[SCM] sonic-pi/master: Imported Upstream version 2.10.0

hanno-guest at users.alioth.debian.org hanno-guest at users.alioth.debian.org
Fri Apr 15 12:24:14 UTC 2016


The following commit has been merged in the master branch:
commit 829b6f750154001d30118c5a609d6e2a6fbe9081
Author: Hanno Zulla <hanno.zulla at epublica.de>
Date:   Fri Apr 15 11:58:30 2016 +0200

    Imported Upstream version 2.10.0

diff --git a/.gitignore b/.gitignore
index 129e792..c2dcc54 100644
--- a/.gitignore
+++ b/.gitignore
@@ -93,3 +93,7 @@ app/server/vendor/atomic/ext/Makefile
 ## Book
 
 book/
+
+## IntelliJ IDEA
+
+*.iml
diff --git a/.travis.yml b/.travis.yml
index 0351223..051f6ba 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,82 @@
 language: ruby
-rvm:
-  - "1.9.3"
-  - "2.1.2"
-# uncomment this line if your project needs to run something other than `rake`:
-script: cd app/server/sonicpi && rake test
+
+os: linux
+sudo: required
+dist: trusty
+compiler: gcc
+cache:
+ - apt
+ - ccache
+
+# in addition to the default settings (above),
+# add test runs using the Travis rvm ruby binaries.
+matrix:
+  include:
+    - env: USE_QT4=1
+    - rvm: 1.9.3
+      env: USE_RVM=1
+    - rvm: 2.1.2
+      env: USE_RVM=1
+    - rvm: 2.2.3
+      env: USE_RVM=1
+
+before_install:
+ - sudo apt-get update
+ - sudo apt-get --yes install ruby-all-dev rake cmake pkg-config g++ libfftw3-dev libffi-dev
+ - |
+   if [[ $USE_QT4 ]]
+   then
+      sudo apt-get --yes install libqscintilla2-dev qt4-dev-tools qt4-default
+   else
+      sudo apt-get --yes install libqt5scintilla2-dev qtbase5-dev qttools5-dev qttools5-dev-tools qt5-default
+   fi
+
+script:
+ - set -e
+# the | starts a multiline YAML entry
+ - |
+   if [[ $USE_RVM ]]
+   then
+     # this compiles the gems and runs the Sonic Pi test suite with the ruby installed through Travis's rvm
+     echo ""
+     echo "***********************************"
+     echo "* Compiling the vendor/ ruby gems *"
+     echo "***********************************"
+     cd $TRAVIS_BUILD_DIR/app/server/bin
+     ruby ./compile-extensions.rb
+     echo ""
+     echo "***********************************"
+     echo "* Running the Sonic Pi test suite *"
+     echo "***********************************"
+     cd $TRAVIS_BUILD_DIR/app/server/sonicpi/test
+     rake test
+   else
+     # this compiles the gems and runs the Sonic Pi test suite for all ruby versions in Ubuntu Trusty (1.9.1 and 2.0.0)
+     echo ""
+     echo "***********************************"
+     echo "* Compiling the vendor/ ruby gems *"
+     echo "***********************************"
+     cd $TRAVIS_BUILD_DIR/app/server/bin
+     /usr/bin/ruby -e 'require "ruby_debian_dev"; include RubyDebianDev; SUPPORTED_RUBY_VERSIONS.each { |v, b| system(b + " ./compile-extensions.rb") or raise ("ruby gem compile failed for " + v) }'
+     echo ""
+     echo "***********************************"
+     echo "* Running the Sonic Pi test suite *"
+     echo "***********************************"
+     cd $TRAVIS_BUILD_DIR/app/server/sonicpi/test
+     /usr/bin/ruby -e 'require "ruby_debian_dev"; include RubyDebianDev; SUPPORTED_RUBY_VERSIONS.each { |v, b| system(b + " /usr/bin/rake test") or raise ("test failed for " + v) }'
+     # the following are the same steps as in ./app/gui/qt/rp-build-app
+     echo ""
+     echo "***********************************"
+     if [[ $USE_QT4 ]]
+     then
+       echo "* Compiling Sonic Pi GUI with Qt4 *"
+     else
+       echo "* Compiling Sonic Pi GUI with Qt5 *"
+     fi
+     echo "***********************************"
+     cd $TRAVIS_BUILD_DIR/app/gui/qt
+     cp -f ruby_help.tmpl ruby_help.h ; /usr/bin/ruby ../../server/bin/qt-doc.rb -o ruby_help.h
+     lrelease SonicPi.pro
+     qmake -o Makefile SonicPi.pro
+     make
+   fi
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 78af5e6..a7c4de5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,5 @@
 # History
+* [v2.10 'Cowbell'](#v2.10), 15th April, 2016
 * [v2.9 'Venster'](#v2.9), 31st Dec, 2015
 * [v2.8 'Karlsruhe'](#v2.8), 20th Nov, 2015
 * [v2.7 'Rerezzed'](#v2.7), 10th Sept, 2015
@@ -10,10 +11,186 @@
 * [v2.1 'Core'](#v2.1), 21st Nov, 2014
 * [v2.0 'Phoenix'](#v2.0), 2nd Sept, 2014
 
+<a name="v2.10"></a>
+
+## Version 2.10 - 'Cowbell'
+*Friday 15th April, 2016*
+[(view commits)](https://github.com/samaaron/sonic-pi/commits/v2.10.0)
+
+_"I gotta have more cowbell!"_ - The Bruce Dickinson
+
+The main feature in this release is the completely new sample system for
+working with large folders of samples. You can now easily index into and
+filter over whole folders of samples with a simple yet powerful filter
+system. This system has been in development for over a year now and has
+been tuned and tweaked over many performances and practice sessions. See
+the documentation and examples for `sample` as well as the new tutorial
+section 3.7 for details.
+
+We also have a number of exciting new sounds to play with including some
+beautifully sounding chiptune synths, fun retro FX and new drum samples
+including a full tabla set and a cowbell.
+
+Finally, even more boot issues on both OS X and Windows that have been
+fixed making this the most polished and stable release to date.
+
+Now go and get your live code on!
+
+
+### Breaking Changes
+
+* `use_sample_pack_as` and `with_sample_pack_as` have been removed.
+* A synth opt value of `nil` now no longer resolves to 0.0. Instead it
+  masks any defaults and ensures the downstream default (for the actual
+  synthdef itself) is honoured. This allows you to override any existing
+  synth defaults specified via `use_synth_defaults` for a given synth
+  trigger.
+* Default schedule ahead time is now 0.5s on all platforms for
+  consistency (except for Raspberry Pi 1 which remains at 1s).
+
+
+### New Fns
+
+* `current_random_seed` - Get the current seed value of the random generator.
+* `set_cent_tuning!` - global tuning.
+* `on` - similar to `if` but behaves the same as the `on:` opt for
+  synths and samples.
+* `halves` - create a ring of successive halves.
+* `doubles` - create a ring of successive doubles.
+* `pick` - similar to shuffle but allows duplicates. You may also
+  specify how many items to pick.
+* `fx_names` - create a ring of all available FX.
+
+### Synths & FX
+
+* New synth `:dtri` - detuned triangle waves.
+* New synth `:pluck` - a lovely synthesised plucked string.
+* New synth `:chiplead` - retro NES style lead synth.
+* New synth `:chipbass` - retro NES style bass synth.
+* New synth `:chipnoise` - retro NES style noise synth.
+* New FX `:whammy` - low-tech transposition effect similar to the
+  Digitech Whammy guitar pedal.
+* New FX `:octaver` - low-tech octave effect similar to early guitar
+  pedals.
+* New FX `:vowel` - modifies incoming signal to match human vowel
+  sounds.
+* New FX `:mono` - mono effect for summing stereo channels.
+* `:tanh` FX is now more crunchy by default.
+* `:compressor` and `:krush` FX now correctly honour the `mix:` opt.
+
+
+### Samples
+
+* Samples in FLAC format (Free Lossless Audio Codec) are now supported!
+* The `sample` fn gained source and filter pre-opts. You may now specify
+  a number of parameters directly before the opts which describe both
+  folders containing samples and filters over those folders to allow you
+  to easily and quickly work with large sample sets. See Section 3.7 of
+  the tutorial for more information.
+* Samplers now have `hpf:` and `lpf:` opts. Any `cutoff:` opts are
+  automatically switched to `lpf:` and any errors will be reported with
+  an `lpf:` prefix.
+* The sampler synth gained a compressor enabled via the `compress:`
+  opt. This means you can now compress any triggered sample directly
+  without the need to reach for an FX.
+* Samplers gained the `pre_amp:` opt which applies the amp at the
+  beginning of its internal signal chain. You can use this to overload
+  the new compressor.
+* Samplers now have both high pass and low pass filter envelopes which
+  behave similarly to the amplitude envelope but control internal hpf
+  and lpf FX. These are available via new opts which mirror the standard
+  envelope opts but with a `hpf_` and `lpf_` prefix (such as
+  `hpf_attack`, `lpf_decay_level` and friends).
+* Passing a directory path to `load_samples` will now load all the
+  samples within that directory.
+* Passing a directory path to `free_samples` will now free all the
+  loaded samples within that directory.
+* Samples are now loaded asynchronously in a separate thread. This
+  therefore doesn't block the current thread and cause any subsequent
+  synth/sample triggers to be late.
+* Sample trigger logging now includes the directory of the contained
+  sample.
+* Samples are now reloaded asynchronously after a server reboot (and
+  therefore no longer block execution).
+* Add new `:tabla_` sample group with a range of tabla drum sounds.
+* Add new `:vinyl_` sample group with a range of vinyl scratches and
+  hisses.
+* Add new samples: `:drum_cowbell`, `:drum_roll`, `:misc_cros`,
+  `:misc_cineboom`, `:perc_swash`, `:perc_till`, `:loop_safari`,
+  `:loop_tabla`.
+
+### GUI
+
+* Add new preference to enforce strict synth/FX timing. When enabled
+  synths and samples no longer trigger if it is too late - instead they
+  are silent and print a warning message. This behaviour ensures samples
+  or synths are never triggered out of time.
+* New load button which will load the contents of a file into the
+  current buffer.
+* The vertical bars which help visualise nesting now render in a
+  contiguous fashion over blank lines.
+* `C-k` now nukes over trailing whitespace.
+* `load_sample` now has sample autocompletion.
+* GUI now correctly reports if the host is a Raspberry Pi 3.
+* New editor preference - Log Auto Scroll. When enabled will always
+  scroll log to the bottom after printing every new message.
+* Whitespace at top and bottom of buffer is no longer trimmed.
+* Hitting `RETURN` now auto-indents the buffer - ensuring that the
+  cursor is moved to the correct indentation on the following line.
+* Added Chinese Simplified GUI translation.
+* Log visibility now correctly matches GUI preference.
+
+
+### Documentation
+
+* New tutorial section 3.7 on Sample Pack Filters.
+* New appendix sections.
+* Examples for `sample` fn have been completely rewritten and extended.
+
+
+### Improvements
+
+* `scale` and `chord` can now handle being passed no tonic such as:
+  `(chord :minor)` which will return a ring of offsets from 0.
+* `chord` learned new variants: `add2`, `add4`, `add9`, `add11`,
+  `add13`, `madd2`, `madd4`, `madd9`, `madd11`, `madd13`
+* The ring's `.take` method can now take more elements than the original
+  ring by wrapping around: 
+  `(ring 1, 2, 3).take(5) #=> (ring 1, 2, 3, 1, 2)`
+* Rings may now be added or subtracted from each other e.g. 
+  `(ring 1, 2,  3) + (ring 4) #=> (ring 1, 2, 3, 4)`
+* Adding or subtracting a number from a ring will create a new ring with
+  the number added or subtracted from each of the original ring's
+  elements: `(ring 1, 2, 3) - 1 #=> (ring 0.0, 1.0, 2.0)`
+* Calling `(ring 1, 2, 3).take(0)` will now return an empty ring.
+* `density` now complains if it isn't passed a do/end block.
+* Improve error messages for `use/with_synth` when accidentally passed opts.
+
+
+
+### Bugfixes
+
+* On OS X only raise an error on boot if it's clear the sound card's in
+  and out rates are different.
+* Improve robustness of boot process on Windows.
+* Rest notes are no longer printed if synth logging is disabled.
+* No longer apply synth defaults to FX.
+* You may now control opts that have no associated info (previously it
+  would raise a 'not modulatable' error).
+* Fix index lookup of Vectors.
+* Fix `C-i` doc lookup shortcut to work with `:tb303` synth docs.
+* `C-i` now always displays docs where available (previously it was
+  possible for docs not to be displayed).
+* Sliding between chords now works correctly  
+* Windows version will now boot mutiple networked machines logged in
+  with the same account.
+
+
 <a name="v2.9"></a>
 
 ## Version 2.9 - 'Venster'
 *Thursday 31st December, 2015*
+[(view commits)](https://github.com/samaaron/sonic-pi/commits/v2.9.0)
 
 Hot on the heels of the previous release comes `v2.9` codenamed
 `Venster` (Dutch for window). This release has a specific focus on
@@ -135,6 +312,7 @@ Happy Live Coding!
 
 ## Version 2.8 - 'Karlsruhe'
 *Friday 20th November, 2015*
+[(view commits)](https://github.com/samaaron/sonic-pi/commits/v2.8.0)
 
 This release, named after Karlsruhe, one of the home cities of live
 coding, is mainly a maintenance release with a strong focus on both
@@ -229,6 +407,7 @@ cutoff envelopes on the sampler.
 
 ## Version 2.7 - 'Rerezzed'
 *Thursday 10th September, 2015*
+[(view commits)](https://github.com/samaaron/sonic-pi/commits/v2.7.0)
 
 This release brings a substantial change to the random number
 generator. This has the unfortunate side effect of breaking backwards
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index e00a1c2..cd11600 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -12,6 +12,8 @@ technical and otherwise) with time, advice, and wisdom:
 * [Rachel Drury](https://twitter.com/Rachel_Drury)
 * [Juneau Projects](http://www.juneauprojects.co.uk)
 * Stephan Lachowsky
+* [Paul Winstanley](https://twitter.com/SCCMentor)
+* [Robin Newman](https://twitter.com/rbnman)
 
 ## Organisations
 
@@ -24,60 +26,78 @@ The following organisations have kindly contributed to Sonic Pi:
 
 ## Developer Contributions
 
-In addition to the Sonic Pi Core Team, I'd like to give my thanks to
-the following developers who have donated their time and effort to help
-grow and improve the Sonic Pi code base:
+In addition to the Sonic Pi Core Team, I'd like to give my thanks to the
+following developers who have donated their time and effort to help grow
+and improve the Sonic Pi code base:
 
-* [Hanno Zulla](https://github.com/hzulla)
 * [Ethan Crawford](https://github.com/ethancrawford)
 * [Łukasz Siwiński](https://github.com/hopbit)
 * [Martin Keegan](https://github.com/mk270)
+* [Kenichi Kanai](https://github.com/kn1kn1)
 * [Nicolas Dermine](https://github.com/nicoder)
 * [Ricardo Pozo](https://github.com/thraex41)
-* [Kenichi Kanai](https://github.com/kn1kn1)
 * [Robin Newman](https://github.com/rbnpi)
 * [Wolfgang Werner](https://github.com/wwerner)
 * [Clare Macrae](https://github.com/claremacrae)
+* [Jeroen Castelein](https://github.com/JeroennC)
+* [G. Martin Butz](https://github.com/mbutz)
 * [Hannes Fritz](https://github.com/hztirf)
 * [Petter Reinholdtsen](https://github.com/petterreinholdtsen)
-* [G. Martin Butz](https://github.com/mbutz)
 * [Marco Giordano](https://github.com/marco-giordano)
 * [Keiko Machiya](https://github.com/keikomachiya)
+* [Franz Laügt](https://github.com/znarf94)
+* [Sébastien Rannou](https://github.com/aimxhaisse)
+* [Frobby](https://github.com/frobby)
 * [Martin Zeilinger](https://github.com/st01c)
 * [Steve Traylen](https://github.com/traylenator)
-* [Chris Ford](https://github.com/ctford)
-* [Mistral Contrastin](https://github.com/madgen)
 * [Christoph B. Wurzinger](https://github.com/chbw)
-* [Ben Nuttall](https://github.com/bennuttall)
 * [Jose Añasco](https://github.com/merongivian)
-* [Will Stephenson](https://github.com/wstephenson)
-* [Frobby](https://github.com/frobby)
 * [Michel Echevres](https://github.com/echevresm)
-* [Katie Miller](https://github.com/codemiller)
+* [Mistral Contrastin](https://github.com/madgen)
+* [Chris Ford](https://github.com/ctford)
 * [Bruce Adams](https://github.com/bruceadams)
+* [Ben Nuttall](https://github.com/bennuttall)
 * [Daniel Canelhas](https://github.com/dcanelhas)
-* [James Smith](https://github.com/Nanomancer)
-* [Ryan Bigg](https://github.com/radar)
+* [Katie Miller](https://github.com/codemiller)
+* [Michael Henry](https://github.com/neoCrimeLabs)
+* [Will Stephenson](https://github.com/wstephenson)
+* [Eugene Kovalev](https://github.com/wl8dr3)
+* [Serge Stinckwich](https://github.com/SergeStinckwich)
+* [Sebastian Stahn](https://github.com/stahnirockt)
 * [Joseph Haig](https://github.com/jrmhaig)
 * [Graham Taylor](https://github.com/vinnievg)
-* [Morgan Owens](https://github.com/equiamos)
-* [Cosmin Stroe](https://github.com/cstroe)
-* [Aspasia Beneti](https://github.com/aspasia)
 * [Ivan Zarea](https://github.com/minivan)
+* [Siim Põder](https://github.com/windo)
+* [Cosmin Stroe](https://github.com/cstroe)
+* [Tomek Rabczak](https://github.com/tomekr)
+* [Brujo Rojas](https://github.com/brujo696)
+* [Mateusz Bielec](https://github.com/mbie)
+* [Tom den Braber](https://github.com/tomdenbraber)
 * [Karl Hiner](https://github.com/khiner)
-* [Serge Stinckwich](https://github.com/SergeStinckwich)
-* [András Németh](https://github.com/nemethandras)
-* [Nigel Michki](https://github.com/nigeil)
-* [Christian Perfect](https://github.com/christianp)
+* [Pierre De Wilde](https://github.com/pierredewilde)
+* [Ryan Bigg](https://github.com/radar)
+* [James Smith](https://github.com/Nanomancer)
+* [Tom Holford](https://github.com/tomholford)
+* [Russell Jones](https://github.com/Russell-Jones)
+* [Marko Peltola](https://github.com/markopeltola)
 * [Hrafnkell Eiríksson](https://github.com/hrafnkelle)
-* [Ruzsa Balázs](https://github.com/cellux)
+* [Michel Kraaijeveld](https://github.com/LandDragoon)
 * [Enrike Hurtado](https://github.com/enrike)
-* [Alex McLean](https://github.com/yaxu)
-* [Russell Jones](https://github.com/Russell-Jones)
-* [Michael Fulton](https://github.com/emu4hire)
+* [John Lawrence Aspden](https://github.com/johnlawrenceaspden)
+* [Sandy Maguire](https://github.com/isovector)
 * [Tomasz Nurkiewicz](https://github.com/nurkiewicz)
+* [Morgan Owens](https://github.com/equiamos)
+* [Christian Perfect](https://github.com/christianp)
+* [Matthias Cavigelli](https://github.com/mcavigelli)
+* [Ruzsa Balázs](https://github.com/cellux)
 * [Emlyn Corrin](https://github.com/emlyn)
-* [John Lawrence Aspden](https://github.com/johnlawrenceaspden)
+* [Alex McLean](https://github.com/yaxu)
+* [Aspasia Beneti](https://github.com/aspasia)
+* [Nigel Michki](https://github.com/nigeil)
+* [Michael Fulton](https://github.com/fultonms)
+* [Scott Kitterman](https://github.com/kitterma)
+* [András Németh](https://github.com/nemethandras)
+
 
 
 
diff --git a/CORETEAM.html b/CORETEAM.html
index 23c84d0..07e457e 100644
--- a/CORETEAM.html
+++ b/CORETEAM.html
@@ -17,7 +17,7 @@
           <td>
             <font size="5" ><span style="color:white; background-color:dodgerblue;">Sam Aaron</span></font>
             <p>
-              University of Cambridge Computer Labs researcher . Performing as <a href="http://facebook.com/livecodersamaaron"> Sam Aaron </a>| <a href="http://twitter.com/poly_core">Poly Core</a> | <a href="http://twitter.com/fib_crisis">Fib Crisis</a></p>
+              University of Cambridge Computer Labs researcher. Performing as <a href="http://facebook.com/livecodersamaaron"> Sam Aaron </a>| <a href="http://twitter.com/poly_core">Poly Core</a> | <a href="http://twitter.com/fib_crisis">Fib Crisis</a></p>
 
             <p><a href="https://twitter.com/samaaron">Twitter</a> | <a href="https://github.com/samaaron">GitHub</a> </p>
 
@@ -94,4 +94,25 @@
 
     </td>
   </tr>
+  <tr>
+    <td>
+
+      <table>
+        <tr>
+          <td> <a href="http://www.hanno.de"><img height="100" width="100" src="../images/coreteam/hannozulla.png"> </a></td>
+          <td>
+            <font size="5" ><span style="color:white; background-color:dodgerblue;">Hanno Zulla</span></font>
+
+            <p>
+              Linux whizz and friend of i18n. Helping to bring Sonic Pi to your native tongue and to your Debian desktop.
+            </p>
+
+            <p> <a href="https://twitter.com/hzulla">Twitter</a> | <a href="https://github.com/hzulla">GitHub</a></p>
+
+          </td>
+        </tr>
+      </table>
+
+    </td>
+  </tr>
 </table>
diff --git a/FAQ.md b/FAQ.md
index 6c370c9..aa57a92 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -22,6 +22,13 @@ scsynth.exe
 You can also check in Task Manger that there is no application entry sonic-pi.exe  
 and quit it if there is.
 
+## Linux: There is no sound with use_synth :piano
+
+You probably didn't install the SC3 plugins
+package for SuperCollider on your system. If there
+is no binary package provided by your distribution, you can
+[install it from source](https://github.com/samaaron/sonic-pi/blob/master/INSTALL-LINUX.md#supercollider-sc3-plugins).
+
 ## Linux: Trouble with JACK
 
 If the GUI complains that _"The Sonic Pi server could not be started!"_
diff --git a/HOW-TO-CONTRIBUTE.md b/HOW-TO-CONTRIBUTE.md
index a780500..ebcfa98 100644
--- a/HOW-TO-CONTRIBUTE.md
+++ b/HOW-TO-CONTRIBUTE.md
@@ -47,25 +47,20 @@ where help is appreciated.
 
 ### Medium Projects
 
+- Get us in touch with blind or visually impaired users
+
+  We think that Sonic Pi would be a pretty awesome tool for blind or
+  visually impaired users wanting to learn programming. If you can
+  help us get in touch with one of these users or are one of them,
+  please let us know. We don't know if the Sonic Pi GUI is useful
+  and accessible enough for you, so we don't know where to improve it
+  for your needs. Your input is highly appreciated.
+
 - Save/Load function for buffers
   
   Sonic Pi can save to a file, but it still doesn't have a user-friendly
   way to load existing code.
 
-- Packaging for Linux
-
-  Currently, there are binaries available for OS X, Windows and
-  Raspberry Pi Raspbian. For other Linux distributions, users have to
-  build it on their own. We'd love to find Linux enthusiasts who'd
-  volunteer to maintain packaging for their Linux distros.
-
-- Translation Server Integration
-
-  Sonic Pi translation has been a good start, but it's now turning into
-  a hassle to keep up with the changes. A translation service such as
-  Transifex etc. would be beneficial. The difficult part is how to
-  integrate this with GitHub.
-
 - Optimisation: Identify & fix bottlenecks that waste CPU or RAM
 
   Several different parts work together in Sonic Pi, there's
diff --git a/INSTALL-LINUX.md b/INSTALL-LINUX.md
new file mode 100644
index 0000000..6dfbd40
--- /dev/null
+++ b/INSTALL-LINUX.md
@@ -0,0 +1,118 @@
+## Generic Linux
+
+### Dependencies
+
+Debian package dependency names (Jessie):
+
+`apt-get install supercollider ruby2.1 libqscintilla2-dev ruby-dev cmake pkg-config g++ libfftw3-dev`
+
+For Ubuntu 14.04.3 (Trusty Tahr):
+`apt-get install supercollider ruby2.0 libqscintilla2-dev ruby-dev cmake pkg-config g++ libfftw3-dev`
+
+In addition, under Ubuntu 14.04 based distributions try these:
+
+* `libqscintilla2-l10n`
+* `qt4-qmake`
+* `libqt4-dev`
+* `libffi-dev`
+
+If you are using a newer version of QT, you need the according version of scintilla. For QT5 they are:
+
+* `libqt5scintilla2-dev` instead of `libqscintilla2-dev`
+* `libqt5scintilla2-l10n` instead of `libqscintilla2-l10n`
+
+Fedora package dependency names:
+
+* `supercollider` (via [Planet CCRMA](http://ccrma.stanford.edu/planetccrma/software/installplanettwenty.html))
+* `ruby` (or use [RVM](http://rvm.io/) to manage specific versions)
+* `qscintilla-devel` (will install `qscintilla` and `qt-devel`)
+* `cmake`
+
+### SuperCollider SC3 Plugins
+
+After installing SuperCollider, you will also need to compile and
+install the [SuperCollider SC3 UGen Plugins](https://github.com/supercollider/sc3-plugins)
+from source, if your distribution does not provide a binary package of them.
+
+You will need your distribution's `supercollider-dev` package for this step.
+
+```
+git clone https://github.com/supercollider/sc3-plugins.git
+cd sc3-plugins
+git submodule init
+git submodule update
+git checkout efba3baaea873f4e4d44aec3bb7468dd0938b4a6
+cp -r external_libraries/nova-simd/* source/VBAPUGens
+mkdir build
+cd build
+cmake -DSC_PATH=/usr/include/SuperCollider -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release ..
+make
+sudo make install
+```
+
+### Server extensions
+
+Compile the server extensions by `cd`ing into the directory `app/server/bin` and running the script `compile-extensions.rb`. This will take some time.
+
+### Qt GUI
+
+You must compile the server extensions prior to this step.
+
+`cd` into the directory `app/gui/qt/` and run the script `rp-build-app`. This will also take some time.
+
+### Running
+
+Start the jack sound server daemon `jackd`. This is easily done through [qjackctl](http://qjackctl.sourceforge.net/), available as `qjackctl` in Debian.
+
+that didn't work for me, but typing this, after randomly googling and trying various things, did:
+`jackd -R -d alsa -d hw:1`
+
+On systems like Ubuntu that run pulseaudio, use
+`pasuspender -- jackd -R -d alsa`
+
+Then run the script `sonic-pi` in the directory `app/gui/qt`.
+
+----
+
+## Arch Linux
+
+### AUR Package
+
+Arch Linux users are strongly recommended to install the [sonic-pi-git](https://aur.archlinux.org/packages/sonic-pi-git/) package from the AUR; see the wiki article on the [Arch User Repository](https://wiki.archlinux.org/index.php/Arch_User_Repository) if you are unfamiliar with how to install such a package. The PKGBUILD found in this package will:
+* Clone the latest sonic-pi source from GitHub
+* Apply a patch to fix a library naming issue
+* Build sonic-pi from source, according to the instructions found in [Generic Linux](#generic-linux)
+* Install the built software components to `/opt/sonic-pi-git`
+* Install the launcher to `/usr/bin/sonic-pi`
+
+After installing, users need to follow the instructions in the [Generic Linux](#generic-linux) section to start the `jackd` server, and then run `sonic-pi` at a command prompt.
+
+### Building from source
+
+Users can opt to build from source as well if they would like. Instructions and dependencies can be found within the PKGBUILD file in the AUR package previously mentioned, as well as the required patch file.
+
+----
+
+## Linux Mint (beta)
+
+### PPA
+
+Tested on Linux Mint 17.2, inspired by [this issue](https://github.com/samaaron/sonic-pi/issues/827).
+
+First, install the binary:
+
+```
+sudo add-apt-repository ppa:sonic-pi/ppa
+sudo apt-get update
+sudo apt-get install sonic-pi
+```
+
+Next, install qjackctl:
+
+`sudo apt-get install qjackctl`
+
+Then, launch qjackctl from the command line (while suspending PulseAudio):
+
+`pasuspender -- qjackctl`
+
+Click the 'Start' button in qjackctl, then launch Sonic Pi :)
diff --git a/INSTALL-MAC.md b/INSTALL-MAC.md
new file mode 100644
index 0000000..8d171eb
--- /dev/null
+++ b/INSTALL-MAC.md
@@ -0,0 +1,113 @@
+# Mac OS X
+
+## Dependencies
+
+* Download Qt 5.4+ http://qt-project.org/downloads
+* Run the setup wizard and install to a known location which we'll call `/path/to/qt`
+* Grab a copy of the QScintilla libs http://www.riverbankcomputing.co.uk/software/qscintilla/download and untar into a known location which we'll call `/path/to/qscintilla`
+  (current version is QScintilla-gpl-2.9)
+* Install SuperCollider 3.6 from http://supercollider.github.io/download.html
+* Download SuperCollider extensions from http://sourceforge.net/projects/sc3-plugins/files/OSX_3.6/SC3ExtPlugins-universal.dmg/download and install as per the included README.txt file
+* Grab a copy of Sonic Pi's source to a known location (which we'll call `/path/to/sonic-pi/root/`)
+  - `cd /path/to/sonic-pi/root/`
+  - `git clone git://github.com/samaaron/sonic-pi.git`
+
+
+## Create Symlinks for Ruby and SuperCollider's scsynth
+
+* Provide a Ruby version for Sonic Pi to use
+  - The Qt app expects Ruby to exist at a certain path. We can use a symlink to provide an appropriate Ruby Version
+  - `cd /path/to/sonic-pi/root/`
+  - `mkdir -p app/server/native/osx/ruby/bin`
+  - link the ruby version into place:
+  - ``ln -s `which ruby` app/server/native/osx/ruby/bin/ruby``
+* Provide a SuperCollider scsynth for Sonic Pi to use  
+ - The Qt app expects scsynth to exist at a certain path. We can also use a symlink here.
+ - `cd /path/to/sonic-pi/root/`
+ - `cd app/server/native/osx/`
+ - `ln -s /Applications/SuperCollider/SuperCollider.app/Contents/Resources/scsynth .`
+
+## Compile Ruby Server extensions
+### Prerequisites
+In order to compile the ruby libraries successfully, make sure you have
+the following programs installed:
+
+* [cmake](https://cmake.org)
+* [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/)
+
+If you want to check whether you have them installed already, you can do
+so by typing the following commands in your terminal:
+
+* `cmake` - If installed, it will show the usage of the program
+* `pkg-config` - If installed, it will show a message indicating that a 
+package name should be specified.
+
+Installation of both the programs can be done through Homebrew or MacPorts
+
+### Compiling
+Sonic Pi uses some ruby libraries which have native extensions. We need
+to compile these with the provided script:
+
+* `cd /path/to/sonic-pi/root/`
+* `cd app/server/bin`
+* `../native/osx/ruby/bin/ruby compile-extensions.rb`
+
+This will take some time. Ignore the warnings.
+
+## Qt GUI
+
+### Xcode 6 and lower
+
+* Build QScintilla:
+  - `cd /path/to/qscintilla/Qt4Qt5`
+  - generate makefile: `/path/to/qt/5.4/clang_64/bin/qmake qscintilla.pro`
+  - `make`
+* Add the following to SonicPi.pro:
+```
+    LIBS += -L /path/to/qscintilla/Qt4Qt5/ -lqscintilla2
+    INCLUDEPATH += /path/to/qscintilla/Qt4Qt5/
+    DEPENDPATH += /path/to/qscintilla/Qt4Qt5/
+```
+* Modify top of mac-build-app appropriately i.e.
+```
+    QSCINTILLA=/path/to/qscintilla/Qt4Qt5
+    QTBIN=/path/to/qt/5.4/clang_64/bin    
+```
+### Xcode 7+
+
+* Build QScintilla:
+  - `cd /path/to/qscintilla/Qt4Qt5`
+  - Add the following to `qscintilla.pro`
+      QMAKE_MAC_SDK = macosx10.11
+  - generate makefile: `/path/to/qt/5.4/clang_64/bin/qmake qscintilla.pro`
+  - `make`
+  - update the dylib inner path part 1: `install_name_tool -id "/path/to/qscintilla/Qt4Qt5/libqscintilla2.12.dylib" /path/to/qscintilla/Qt4Qt5/libqscintilla2.12.dylib`
+  - update the dylib inner path part 2: `install_name_tool -change "libqscintilla2.12.dylib" "/path/to/qscintilla/Qt4Qt5/libqscintilla2.12.dylib" /path/to/qscintilla/Qt4Qt5/libqscintilla2.12.dylib` 
+* Add the following to SonicPi.pro
+```
+    LIBS += -L /path/to/qscintilla/Qt4Qt5/ -lqscintilla2
+    INCLUDEPATH += /path/to/qscintilla/Qt4Qt5/
+    DEPENDPATH += /path/to/qscintilla/Qt4Qt5/
+```    
+* Add the following to SonicPi.pro
+```
+    QMAKE_MAC_SDK = macosx10.11
+```    
+* Modify top of mac-build-app appropriately i.e.
+```    
+    QSCINTILLA=/path/to/qscintilla/Qt4Qt5
+    QTBIN=/path/to/qt/5.4/clang_64/bin
+```    
+
+
+## Building the App
+
+Finally, we need to build the OS X App
+
+* `cd /path/to/sonic-pi/root/`
+* `cd app/gui/qt`
+* `./mac-build-app`
+* App should be in `build` dir which you can either launch via Finder or via the following from the `qt` dir:
+* `./build/Sonic\ Pi.app/Contents/MacOS/Sonic\ Pi`
+
+Sonic Pi should now boot successfully.
diff --git a/INSTALL-RASPBERRY-PI.md b/INSTALL-RASPBERRY-PI.md
new file mode 100644
index 0000000..08d2f3e
--- /dev/null
+++ b/INSTALL-RASPBERRY-PI.md
@@ -0,0 +1,34 @@
+
+## Raspberry Pi
+
+The Raspberry Pi will happily compile all the required aspects of Sonic
+Pi. However, be warned that it will take quite some time to complete.
+
+First grab the dependencies, compile the server extensions, then the GUI then start the app.
+
+### Dependencies
+
+The dependencies for building and running this are:
+
+* `supercollider`
+* `ruby1.9.3`
+* `libqscintilla2-8`
+* `libqscintilla2-dev`
+* `qt4-dev-tools`
+* `cmake`
+* `ruby-dev`
+* `libffi-dev`
+
+Use `sudo apt-get install` to ensure each of these are on your system.
+
+### Server extensions
+
+Compile the server extensions by `cd`ing into the directory `app/server/bin` and running the script `compile-extensions.rb`. This will take some time.
+
+### Qt GUI
+
+`cd` into the directory `app/gui/qt/` and run the script `rp-build-app`. This will also take some time.
+
+### Running
+
+Run the script `rp-app-bin` in the directory `app/gui/qt`.
diff --git a/INSTALL-WINDOWS.md b/INSTALL-WINDOWS.md
new file mode 100644
index 0000000..d9df5ba
--- /dev/null
+++ b/INSTALL-WINDOWS.md
@@ -0,0 +1,269 @@
+# SONIC PI DETAILED BUILD YOUR OWN INSTRUCTIONS FOR WINDOWS 10 BASED ON LATEST SP 2.9dev after e7fde3a
+
+Last revision 29th December 2015 @ 7:32PM AWST   (minor grammar improvement)
+
+Tested on Windows 10 64bit (running under vmware fusion on a Mac) and Windows 7 64bit.
+
+This document details the process from beginning to end to build Sonic Pi 2.9dev and I hope it will be useful to others, and encourage them to have a go themselves.
+
+First there is quite a bit of software to install to facilitate the build, not least the source files for Sonic Pi.
+
+First install **git** from https://msysgit.github.io/ click **download** then run `Git-2.6.3-64-bit.exe` I selected options **Use git from Windows Command Prompt**, **Checkout Windows-style**, **commit Unix-style line endings**, **Use Windows default console window**, and **Enable file system caching**
+
+Now install the **Sonic Pi source files**. I put mine at the top level of the c: drive
+Start a command window by typing **cmd** in the search field
+```
+cd c:/
+git clone https://github.com/samaaron/sonic-pi.git
+```
+
+Now download **Visual Studio Express 2013 for Windows Desktop with Update 5** from
+https://www.visualstudio.com/downloads/download-visual-studio-vs
+scroll down the page and find **Visual Studio 2013**, and then **Express 2013 for Desktop**.
+You can either choose **Web Installer** or **ISO** depending upon whether you want to install over the web or download a complete 3.3Gb and install from that. I did the full download, mounted the iso disk image and installed from that.
+
+Download **Qt**. use **version 5.5.1** as version 5.4.x is NOT qualified for Windows 10
+I went to http://www.qt.io/download-open-source/#section-2
+And selected **Qt 5.5.1 for Windows 32-bit (VS 2013, 804 MB)** 
+
+http://download.qt.io/official_releases/qt/5.5/5.5.1/qt-opensource-windows-x86-msvc2013-5.5.1.exe
+After download, I ran the installer, accepting the default settings, which installs Qt at
+```C:\Qt\Qt5.5.1``` (I skipped setting up an account!)
+
+Install **cmake** from the link http://www.cmake.org/download
+Scroll down and select ```cmake-3.4.1-win32-x86.exe``` and download.
+Run the installer, selecting the option **Add to the System PATH for all (or current) users**
+
+
+Install **Ruby** from http://rubyinstaller.org/downloads/
+I choose **Ruby 2.2.3** although the install works with 2.1.7 with minor alterations which are detailed below.
+Choose the **32 bit version**
+Run the installer when downloaded. Choose the default install ```c:\Ruby22``` (C:\Ruby21 if you use Ruby2.1.7)
+Select **add Ruby Executables to your path** and **associate .rb and .rbw files with this installation**.
+
+Scroll further down the page of http://rubyinstaller.org/downloads/ and select
+```DevKit-mingw64-32-4.7.2-20130224-1151-sfx.exe``` and download that as well
+Make sure you use the **32 bit version for Ruby 2.0 and higher**.
+When downloaded, run this and set the extract location to ```c:\RubyDev```
+
+Now you have to complete the installation as follows:
+In a command window
+```
+cd c:\RubyDev
+ruby dk.rb init
+```
+
+This will create a file ```config.yml``` inside the ```RubyDev``` folder
+Check its contents by typing;
+```Notepad config.yml```
+You should see a line ``` - C:\Ruby22```
+at the end of the file. ( - C:\Ruby21 if you use Ruby2.1.7)
+Close notepad
+Now type
+```ruby dk.rb install```
+
+Now you add two files from **pkgconfiglite**
+Open the link
+http://sourceforge.net/projects/pkgconfiglite/files
+and select
+**Looking for the latest version? Download pkg-config-lite-0.28-1_bin-win32.zip (47.7 kB)**
+When the file has downloaded, extract and then copy the file ```pkg-config``` from the ```bin``` folder to ```c:\RubyDev\bin```
+and the file ```pkg.m4``` from the ```share\aclocal``` folder to ```c:\RubyDev\share\aclocal```
+
+That completes the setup for RubyDev
+
+### Preparing the Ruby section
+This section of the Sonic Pi install.md file should be completed next BEFORE attempting the section **Qt GUI** (unlike in the original install.md document) as the final build in this section requires one of the gems to be installed before it is run.
+
+Copy ```c:\ruby22\*``` into ```c:\sonic-pi\apps\server\native\windows\ruby```
+(amend to c:\Ruby21\* if you use Ruby2.1.7)
+You will need to create the last two folders windows\ruby before doing this, which is best done from a File Explorer window. The copying is also best done using **two** File Explorer windows, one set to ```c:\Ruby22``` (or C:Ruby21  if you use Ruby2.1.7) and the other to ```c:\sonic-pi\app\server\native\windows\ruby```
+You can leave out the **Doc** folder and the two **unins000** files.
+Now open a cmd window and navigate to c:\sonic-pi\app\server\native\windows\ruby
+From there we will install gem files required by Sonic Pi
+
+```.\bin\gem install did_you_mean```
+
+(allow access if you are asked). The install may take a little time. Eventually it will say two gems installed (did_you_mean and interception)
+
+```.\bin\gem install ffi```
+
+
+Another gem recently added, that is needed specifically for the windows install is ```win32-process```
+
+```.\bin\gem install win32-process```
+
+The fourth gem file is problematical, and needs a patch to install. It goes like this:
+
+```.\bin\gem fetch rugged```
+
+This will fetch the latest version which is rugged-0.23.3
+
+```
+.\bin\gem unpack rugged-0.23.3.gem
+.\bin\gem spec rugged-0.23.3.gem --ruby > rugged-0.23.3\rugged.gemspec
+```
+
+Now we have to apply a patch to one of the files.
+
+```
+cd rugged-0.23.3\ext\rugged
+notepad extconf.rb
+```
+In the notepad window select **Find** from the Edit Menu (**ctrl+F**) and search for
+
+```Unix Makefiles\””)```
+
+and change it to read
+
+```Unix Makefiles\" -DCMAKE_INSTALL_PREFIX=C:/ -DWINHTTP=OFF")```
+
+NB: this may no longer be needed with current versions of rugged
+
+Then resave the file and quit notepad.
+Go back to the cmd window
+
+```cd ..\..\```
+ 
+you should be back in the folder ```c:\sonic-pi\app\server\native\windows\ruby\rugged-0.23.3```
+
+Now build the patched rugged
+
+```
+..\bin\gem build rugged.gemspec
+..\bin\gem install rugged-0.23.3.gem
+```
+
+NB: rb-native is not being used for Windows packages, the gems can happily live where they were installed by the "local" Ruby.  You MAY need to delete the vendor/rugged directory so it uses the right version.
+
+That completes the ruby preparation work. Close the cmd and FileExplorer windows.
+
+
+### Preparing the Qt GUI
+From the **Start Button** select **All apps** and scroll down to **Visual Studio 2013**, and then to **Visual Studio Tools**. From the Window that opens **right click**  **VS2013 x86 Native Tools Command Prompt** and **Pin it to the Taskbar**. **Double click it** there to open a window which should be titled **VS2013 x86 Native Tools Command Prompt**.
+
+Type **path** in that window after the prompt and press the enter key.
+
+You will see a long string of folder locations which comprise the path associated with the window, which it will automatically search. It includes links to the various elements of visual studio. However, we have to add one more item, which is the path of the Qt bin directory.
+
+Since the Visual Studio prompt path is rebuilt each time a window is opened, I have found the convenient way to do this is to create a **batch file** which can be run each time to add the additional entry. Since I want to store this at the C:\ top level, we have to run the cmd window with administrative privileges to create it.
+Close the open Visual Studio Command Prompt window, then reopen it, holding down **Shift** and **Ctrl** when you do so. Say **Yes** to the popup window, and you will then have a cmd window with admin privileges. 
+
+```
+cd c:\
+notepad
+```
+
+In the open notepad window type
+```
+PATH=%PATH%;C:\Qt\Qt5.5.1\5.5\msvc2013\bin
+```
+
+Then select **save** and save the file as ```pathupdate.bat```, at the top level of ```c:\``` Make sure you select **All Files** for the type so the extension can be set to **.bat** and NOT **.txt**
+
+Close notepad and type ```dir``` (and press return) You should see the file ```pathupdate.bat``` listed.
+
+Close the cmd window and double click the icon on the taskbar to reopen it with "normal" privileges.
+
+```
+cd c:\
+pathupdate.bat
+```
+
+You should see the long path as before, but now with an additional entry ```C:\Qt\Qt5.5.1\5.5\msvc2013\bin``` at the end
+Leave this window open.
+
+Download **Qscintilla** from https://www.riverbankcomputing.com/software/qscintilla/download
+
+Select the ```Qscintilla-gpl-2.9.1.zip``` file to download
+When downloaded extract the ```Qscintilla-gpl-2.9.1``` folder to ```c:\```
+
+Return to the visual studio command window. 
+```
+cd c:\QScintilla-gpl-2.9.1\Qt4Qt5
+qmake qscintilla.pro
+nmake
+```
+(it will now be compiled)
+```
+nmake install
+```
+keep the cmd window open
+
+copy ```Qt4Qt5\release\moc_qsciscintilla.cpp``` and ```moc_qsciscintillabase.cpp``` to 
+```c:\sonic-pi\app\gui\qt\platform\win``` (There may be two files there already, but overwrite them)
+Best done using two FileExplorer windows as before.
+
+Now we do the main build of Sonic-Pi gui, using the open cmd window.
+```
+cd c:\sonic-pi
+.\app\gui\qt\win-build-app.bat
+```
+This should carry out the build. Don’t worry about various warnings en route.
+We now add some files from visual studio which will be needed at run time.
+Open two FileExplorer windows. In the first navigate to:
+
+```Local Disk (C:)> Program Files (x86) > Microsoft Visual Studio 12.0 > VC > redist > x86 > Microsoft.VC120.CRT```
+
+In the second to
+
+```Local Disk (C:)> sonic-pi> app > gui > qt > release```
+
+Copy msvcp120.dll and msvcr120.dll from the former to the latter.
+
+In the second window navigate to **sonic-pi.exe** and **right-click** it to create a shortcut. Drag the shortcut to the desktop. Do NOT attempt to run it yet.
+
+###  The final stage deals with SuperCollider
+Install SuperCollider from http://supercollider.github.io/download.html
+Select the **Win32 3.6.6** installer and download it
+
+Run the installer
+
+Download additional SuperCollider plugins from
+
+http://sourceforge.net/projects/sc3-plugins/files/sc3-plugins%20Windows/
+
+Select the latest version link at the top of the page and download
+```Looking for the latest version? Download sc3-plugins-3.6.0-win32.zip (10.3 MB)```
+Extract them in the download folder.
+
+NB: The current Sonic Pi 2.9 is packaged with sc3-plugins 3.7.0-beta (f978dc2), which can be compiled in an MSYS environment as follows:
+* install FFTW3 binaries from ftp://ftp.fftw.org/pub/fftw/fftw-3.3.4-dll32.zip to `/home/sc/fftw3.3.4-dll32` for example
+* `git clone https://github.com/supercollider/sc3-plugins.git`
+* `cd sc3-plugins && git submodule init && git submodule update`
+* `mkdir build && cd build`
+* `cmake -DSC_PATH=/home/sc/sources/supercollider/ -DFFTW3F_LIBRARY=/home/sc/fft w-3.3.4-dll32/libfftw3f-3.dll -DFFTW3F_INCLUDE_DIR=/home/sc/fftw3.3.4-dll32 -G "Unix Makefiles" ..`
+* manually add `-IC:/msys/home/sc/fftw-3.3.4-dll32/` to `build/source/CMakeFiles/PitchDetection.dir/includes_CXX.rsp` (no idea why)
+* make install
+* copy SCX files from `c:\program files (x86)\sc3-plugins` or wherever it installs them
+
+We now copy files to the sonic-pi installation.
+
+With two FileExplorer windows navigate the first to ```Local Disk (C:) >Program Files (x86) > SuperCollider```
+
+And the second (destination) to ```Local Disk (C:)> sonic-pi > app > server > native > windows```
+
+Copy the ```plugins``` folder from the former to the latter.
+
+Copy all dll files **EXCEPT those starting with QT** from the former to the latter.
+
+Copy ```scsynth.exe``` from the former to the latter.
+
+Keep these windows open for the moment.
+
+Open the ```sc3-plugins-3.6.0-win32``` folder in the Downloads folder and navigate to ```SC3-plugins```.
+Copy all the *.scx files that folder into the ```plugins``` folder copied to destination folder in the previous step.
+
+Close the open FileExplorer windows.
+
+There is one final patch to install. The Ugen file associated with the Piano synth was updated in the summer, to eliminate a problem with the tuning. Unfortunately the current Ugen has NOT yet been updated for windows, and consequently we have to use a modified version of the MdaUgen. This can be downloaded from https://goo.gl/K316fw
+Extract the contents and follow the instructions in the readme file. Basically you replace the file ```sonic-pi-piano.scsyndef``` in ```c:\sonic-pi\etc\synthdefs\compiled``` with the one downloaded in the patch.
+
+(You may like to retain a copy of the original before overwriting it, or perhaps rename it to ```sonic-pi-piano.scsyndef.original```)
+
+### Finished!
+That should complete the installation of Sonic Pi.
+Try running it by double clicking the Sonic Pi shortcut on the desktop.
+
+
+Robin Newman, 17th December 2015
diff --git a/INSTALL.md b/INSTALL.md
index b8f0fe9..87b38f5 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -1,189 +1,22 @@
 # Installing Sonic Pi from Source
 
 If you want to use the very latest development version of Sonic Pi, then
-you'll need to compile from source. Here are instructions for the
-following platforms:
-
-* [Raspberry Pi](#raspberry-pi)
-* [Generic Linux](#generic-linux)
-* [Arch Linux](#arch-linux)
-* [Mac OS X](#mac-os-x)
-* [Windows](#windows)
-
-----
-
-## Raspberry Pi
-
-The Raspberry Pi will happily compile all the required aspects of Sonic
-Pi. However, be warned that it will take quite some time to complete.
-
-First grab the dependencies, compile the server extensions, then the GUI then start the app.
-
-### Dependencies
-
-The dependencies for building and running this are:
-
-* `supercollider`
-* `ruby1.9.3`
-* `libqscintilla2-8`
-* `libqscintilla2-dev`
-* `qt4-dev-tools`
-* `cmake`
-* `ruby-dev`
-* `libffi-dev`
-
-Use `sudo apt-get install` to ensure each of these are on your system.
-
-### Server extensions
-
-Compile the server extensions by `cd`ing into the directory `app/server/bin` and running the script `compile-extensions.rb`. This will take some time.
-
-### Qt GUI
-
-`cd` into the directory `app/gui/qt/` and run the script `rp-build-app`. This will also take some time.
-
-### Running
-
-Run the script `rp-app-bin` in the directory `app/gui/qt`.
-
------
-
-## Generic Linux
-
-### Dependencies
-
-Debian package dependency names (Jessie):
-
-`apt-get install supercollider ruby2.1 libqscintilla2-dev ruby-dev cmake pkg-config g++`
-
-For Ubuntu 14.04.3 (Trusty Tahr):
-`apt-get install supercollider ruby2.0 libqscintilla2-dev ruby-dev cmake pkg-config g++`
-
-In addition, under Ubuntu 14.04 based distributions try these:
-
-* `libqscintilla2-l10n`
-* `qt4-qmake`
-* `libqt4-dev`
-* `libffi-dev`
-
-If you are using a newer version of QT, you need the according version of scintilla. For QT5 they are: 
-
-* `libqt5scintilla2-dev` instead of `libqscintilla2-dev`
-* `libqt5scintilla2-l10n` instead of `libqscintilla2-l10n`
-
-In addition, you need to tell sonic-pi to use these. In order to do so, navigate to `app/gui/qt/`
-and open `SonicPi.pro`with your text editor of choice.
-Replace `lqscintilla2`with `lqt5scintilla2` everywhere it is written.
-
-Fedora package dependency names:
-
-* `supercollider` (via [Planet CCRMA](http://ccrma.stanford.edu/planetccrma/software/installplanettwenty.html))
-* `ruby` (or use [RVM](http://rvm.io/) to manage specific versions)
-* `qscintilla-devel` (will install `qscintilla` and `qt-devel`)
-* `cmake`
-
-### Server extensions
-
-Compile the server extensions by `cd`ing into the directory `app/server/bin` and running the script `compile-extensions.rb`. This will take some time.
-
-### Qt GUI
-
-`cd` into the directory `app/gui/qt/` and run the script `rp-build-app`. This will also take some time.
-
-### Running
-
-Start the jack sound server daemon `jackd`. This is easily done through [qjackctl](http://qjackctl.sourceforge.net/), available as `qjackctl` in Debian.
-
-that didn't work for me, but typing this, after randomly googling and trying various things, did:
-`jackd -R -d alsa -d hw:1`
-
-On systems like Ubuntu that run pulseaudio, use
-`pasuspender -- jackd -R -d alsa` 
-
-Then run the script `sonic-pi` in the directory `app/gui/qt`.
-
-----
-
-## Arch Linux
-
-### AUR Package
-
-Arch Linux users are strongly recommended to install the [sonic-pi-git](https://aur.archlinux.org/packages/sonic-pi-git/) package from the AUR; see the wiki article on the [Arch User Repository](https://wiki.archlinux.org/index.php/Arch_User_Repository) if you are unfamiliar with how to install such a package. The PKGBUILD found in this package will:
-* Clone the latest sonic-pi source from GitHub
-* Apply a patch to fix a library naming issue
-* Build sonic-pi from source, according to the instructions found in [Generic Linux](#generic-linux)
-* Install the built software components to `/opt/sonic-pi-git`
-* Install the launcher to `/usr/bin/sonic-pi`
-
-After installing, users need to follow the instructions in the [Generic Linux](#generic-linux) section to start the `jackd` server, and then run `sonic-pi` at a command prompt. 
-
-### Building from source
-
-Users can opt to build from source as well if they would like. Instructions and dependencies can be found within the PKGBUILD file in the AUR package previously mentioned, as well as the required patch file. 
-
-----
-
-## Mac OS X
-
-### Dependencies
-
-* Download Qt 5.4+ http://qt-project.org/downloads
-* Run the setup wizard and install to a known location which we'll call /path/to/qt
-* Grab a copy of the QScintilla libs http://www.riverbankcomputing.co.uk/software/qscintilla/download and untar into a known location which we'll call /path/to/qscintilla
-  (current version is QScintilla-gpl-2.9)
-* Install SuperCollider 3.6 from http://supercollider.github.io/download.html
-* Download SuperCollider extensions from http://sourceforge.net/projects/sc3-plugins/files/OSX_3.6/ and install as per the included README.txt file
-
-### Server extensions
-
-Compile the server extensions by `cd`ing into the directory `app/server/bin` and running the script `compile-extensions.rb`. This will take some time.
-
-### Qt GUI
-
-* Build QScintilla:
-  - `cd /path/to/qscintilla/Qt4Qt5`
-  - generate makefile: `/path/to/qt/5.4/clang_64/bin/qmake qscintilla.pro`
-  - `make`
-  - (OSX only) update the dylib inner path part 1: `install_name_tool -id "/path/to/qscintilla/Qt4Qt5/libqscintilla2.12.dylib" /path/to/qscintilla/Qt4Qt5/libqscintilla2.12.dylib`
-  - (OSX only) update the dylib inner path part 2: `install_name_tool -change "libqscintilla2.12.dylib" "/path/to/qscintilla/Qt4Qt5/libqscintilla2.12.dylib" /path/to/qscintilla/Qt4Qt5/libqscintilla2.12.dylib` 
-* Add the following to SonicPi.pro
-    LIBS += -L /path/to/qscintilla/Qt4Qt5/ -lqscintilla2
-    INCLUDEPATH += /path/to/qscintilla/Qt4Qt5/
-    DEPENDPATH += /path/to/qscintilla/Qt4Qt5/
-* Modify top of mac-build-app appropriately i.e.
-    QSCINTILLA=/path/to/qscintilla/Qt4Qt5
-    QTBIN=/path/to/qt/5.4/clang_64/bin
-* Provide a Ruby version for Sonic Pi to use
-  - The Qt app expects Ruby to exist at a certain path. We can use a symlink to provide an appropriate Ruby Version
-  - `$ cd /root/path/to/sonic-pi`
-  - `$ mkdir -p app/server/native/osx/ruby/bin`
-  - check your current ruby version: 
-```
-# This should be 2.1.2 although anything 1.9.3+ _should_ work
-$ ruby --version
-```
-  - link the ruby version into place:
-```
-ln -s `which ruby` app/server/native/osx/ruby/bin/ruby
-```
-* Compile any native extensions: `$ app/server/bin/compile-extensions.rb`
-* Run `./mac-build-app`
-* App should be in `build` dir
-
-----
-
-## Windows
-
-### Building
-
-Follow the instructions in [WindowsInstall.md](WindowsInstall.md)
-
-### Packaging
-* TODO: there should be a "make distclean" target to clean up the tree for MSI packaging
-  - or else a script to build a release tree by copying things out of the working tree
-* There is a WiX project file in `sonic-pi.wxs` -- work in progress
-  - download [WiX Toolset](http://wixtoolset.org/)
-  - see comments at top of sonic-pi.wxs for packaging
+you'll need to compile from source. Due to the complex nature of Sonic
+Pi's architecture this should only be considered by those happy playing
+around with the Terminal and are happy working with bleeding edge
+software. 
+
+For all other users, downloading the latest pre-built app for your
+platform is highly recommended: http://sonic-pi.net
+ 
+
+There are instructions for the following platforms in their own separate
+files:
+
+* Raspberry Pi - `INSTALL-RASPBERRY-PI.md`
+* Windows - `INSTALL-WINDOWS.md`
+* Mac - `INSTALL-MAC.md`
+* Linux - `INSTALL-LINUX.md`
 
 ----
 
diff --git a/LICENSE.md b/LICENSE.md
index 4abccc9..b741e41 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -5,7 +5,7 @@
 
 The MIT License (MIT)
 
-Copyright (c) 2013, 2014, 2015 Samuel Aaron ([http://sam.aaron.name](http://sam.aaron.name))
+Copyright (c) 2013, 2014, 2015, 2016 Samuel Aaron ([http://sam.aaron.name](http://sam.aaron.name))
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
@@ -25,6 +25,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 
+## GUI
+As the Sonic Pi GUI links with the GPLv3-licensed QScintilla2,
+distributors of Sonic Pi GUI binaries must comply with the terms of the
+GPL
 
 ## Docs, Tutorial and Examples 
 (contents of [etc/doc/](https://github.com/samaaron/sonic-pi/tree/master/etc/doc) and [etc/examples](https://github.com/samaaron/sonic-pi/tree/master/etc/examples) directories)
@@ -84,13 +88,10 @@ relevant licenses:
 * [Blankslate](https://github.com/masover/blankslate) - [MIT License](http://opensource.org/licenses/MIT)
 * [Did You Mean](https://github.com/yuki24/did_you_mean) - [MIT License](http://opensource.org/licenses/MIT)
 * [FFI](https://github.com/ffi/ffi) - [BSD 3-Clause License](http://opensource.org/licenses/BSD-3-Clause)
-* [FFI Core MIDI](https://github.com/arirusso/ffi-coremidi) - [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html)
 * [Hamster](https://github.com/hamstergem/hamster) - [MIT License](http://opensource.org/licenses/MIT)
 * [i81n](https://github.com/svenfuchs/i18n) - [MIT License](http://opensource.org/licenses/MIT)
 * [Interception](https://github.com/ConradIrwin/interception) - [MIT License](http://opensource.org/licenses/MIT)
 * [Kramdown](http://kramdown.gettalong.org) - [MIT License](http://opensource.org/licenses/MIT)
-* [MIDI Winmm](https://github.com/arirusso/midi-winmm) - [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html)
-* [MIDILib](https://github.com/jimm/midilib) - [Ruby License](https://www.ruby-lang.org/en/about/license.txt)
 * [Multi JSON](https://github.com/intridea/multi_json) - [MIT License](http://opensource.org/licenses/MIT)
 * [Parslet](http://kschiess.github.io/parslet/) - [MIT License](http://opensource.org/licenses/MIT)
 * [Rouge](https://github.com/jneen/rouge) - [MIT License](http://opensource.org/licenses/MIT)
@@ -99,7 +100,6 @@ relevant licenses:
 * [Ruby Prof](https://github.com/ruby-prof/ruby-prof) - [BSD 2-Clause License](http://opensource.org/licenses/BSD-2-Clause) - [MIT License](http://opensource.org/licenses/MIT)
 * [Rugged](https://github.com/libgit2/rugged) - [MIT License](http://opensource.org/licenses/MIT)
 * [Thread Safe](https://github.com/ruby-concurrency/thread_safe) - [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html)
-* [UniMIDI](https://github.com/arirusso/unimidi) - [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html)
 * [Websocket](https://github.com/imanel/websocket-ruby) - [MIT License](http://opensource.org/licenses/MIT)
 * [NArray](https://github.com/masa16/narray) - [Ruby License](https://www.ruby-lang.org/en/about/license.txt)
 * [Ruby CoreAudio](https://github.com/nagachika/ruby-coreaudio) - [MIT License](http://opensource.org/licenses/MIT)
diff --git a/README.md b/README.md
index 11f6db3..120dd7f 100644
--- a/README.md
+++ b/README.md
@@ -95,4 +95,5 @@ Sonic Pi is under active development, and welcomes new contributors:
 
 [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/samaaron/sonic-pi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 <br/>
-<img src="https://travis-ci.org/samaaron/sonic-pi.svg?branch=master"/>
+[![Travis CI](https://travis-ci.org/samaaron/sonic-pi.svg?branch=master)](https://travis-ci.org/samaaron/sonic-pi)
+
diff --git a/WindowsInstall.md b/WindowsInstall.md
deleted file mode 100644
index fd18013..0000000
--- a/WindowsInstall.md
+++ /dev/null
@@ -1,288 +0,0 @@
-# SONIC PI DETAILED BUILD YOUR OWN INSTRUCTIONS FOR WINDOWS 10 BASED ON LATEST SP 2.9dev after e7fde3a
-
-Last revision 29th December 2015 @ 7:32PM AWST   (minor grammar improvement)
-
-Test bed was a Windows 10 64bit install (running under vmware fusion on a Mac)
-
-This document details the process from beginning to end to build Sonic Pi 2.9dev and I hope it will be useful to others, and encourage them to have a go themselves.
-
-Prerequisite. A windows 10 computer with internet connection and working soundcard.
-
-First there is quite a bit of software to install to facilitate the build, not least the source files for Sonic Pi.
-
-First install **git** from https://msysgit.github.io/ click **download** then run `Git-2.6.3-64-bit.exe` I selected options **Use git from Windows Command Prompt**, **Checkout Windows-style**, **commit Unix-style line endings**, **Use Windows default console window**, and **Enable file system caching**
-
-Now install the **Sonic Pi source files**. I put mine at the top level of the c: drive
-Start a command window by typing **cmd** in the search field
-```
-cd c:/
-git clone https://github.com/samaaron/sonic-pi.git
-```
-
-Now download **Visual Studio Express 2013 for Windows Desktop with Update 5** from
-https://www.visualstudio.com/downloads/download-visual-studio-vs
-scroll down the page and find **Visual Studio 2013**, and then **Express 2013 for Desktop**.
-You can either choose **Web Installer** or **ISO** depending upon whether you want to install over the web or download a complete 3.3Gb and install from that. I did the full download, mounted the iso disk image and installed from that.
-
-Download **Qt**. use **version 5.5.1** as version 5.4.x is NOT qualified for Windows 10
-I went to http://www.qt.io/download-open-source/#section-2
-And selected **Qt 5.5.1 for Windows 32-bit (VS 2013, 804 MB)** 
-
-http://download.qt.io/official_releases/qt/5.5/5.5.1/qt-opensource-windows-x86-msvc2013-5.5.1.exe
-After download, I ran the installer, accepting the default settings, which installs Qt at
-```C:\Qt\Qt5.5.1``` (I skipped setting up an account!)
-
-Install **cmake** from the link http://www.cmake.org/download
-Scroll down and select ```cmake-3.4.1-win32-x86.exe``` and download.
-Run the installer, selecting the option **Add to the System PATH for all (or current) users**
-
-
-Install **Ruby** from http://rubyinstaller.org/downloads/
-I choose **Ruby 2.2.3** although the install works with 2.1.7 with minor alterations which are detailed below.
-Choose the **32 bit version**
-Run the installer when downloaded. Choose the default install ```c:\Ruby22``` (C:\Ruby21 if you use Ruby2.1.7)
-Select **add Ruby Executables to your path** and **associate .rb and .rbw files with this installation**.
-
-Scroll further down the page of http://rubyinstaller.org/downloads/ and select
-```DevKit-mingw64-32-4.7.2-20130224-1151-sfx.exe``` and download that as well
-Make sure you use the **32 bit version for Ruby 2.0 and higher**.
-When downloaded, run this and set the extract location to ```c:\RubyDev```
-
-Now you have to complete the installation as follows:
-In a command window
-```
-cd c:\RubyDev
-ruby dk.rb init
-```
-
-This will create a file ```config.yml``` inside the ```RubyDev``` folder
-Check its contents by typing;
-```Notepad config.yml```
-You should see a line ``` - C:\Ruby22```
-at the end of the file. ( - C:\Ruby21 if you use Ruby2.1.7)
-Close notepad
-Now type
-```ruby dk.rb install```
-
-Now you add two files from **pkgconfiglite**
-Open the link
-http://sourceforge.net/projects/pkgconfiglite/files
-and select
-**Looking for the latest version? Download pkg-config-lite-0.28-1_bin-win32.zip (47.7 kB)**
-When the file has downloaded, extract and then copy the file ```pkg-config``` from the ```bin``` folder to ```c:\RubyDev\bin```
-and the file ```pkg.m4``` from the ```share\aclocal``` folder to ```c:\RubyDev\share\aclocal```
-
-That completes the setup for RubyDev
-
-### Preparing the Ruby section
-This section of the Sonic Pi install.md file should be completed next BEFORE attempting the section **Qt GUI** (unlike in the original install.md document) as the final build in this section requires one of the gems to be installed before it is run.
-
-Copy ```c:\ruby22\*``` into ```c:\sonic-pi\apps\server\native\windows\ruby```
-(amend to c:\Ruby21\* if you use Ruby2.1.7)
-You will need to create the last two folders windows\ruby before doing this, which is best done from a File Explorer window. The copying is also best done using **two** File Explorer windows, one set to ```c:\Ruby22``` (or C:Ruby21  if you use Ruby2.1.7) and the other to ```c:\sonic-pi\app\server\native\windows\ruby```
-You can leave out the **Doc** folder and the two **unins000** files.
-Now open a cmd window and navigate to c:\sonic-pi\app\server\native\windows\ruby
-From there we will install gem files required by Sonic Pi
-
-```.\bin\gem install did_you_mean```
-
-(allow access if you are asked). The install may take a little time. Eventually it will say two gems installed (did_you_mean and interception)
-
-```.\bin\gem install ffi```
-
-
-Another gem recently added, that is needed specifically for the windows install is ```win32-process```
-
-```.\bin\gem install win32-process```
-
-The fourth gem file is problematical, and needs a patch to install. It goes like this:
-
-```.\bin\gem fetch rugged```
-
-This will fetch the latest version which is rugged-0.23.3
-
-```
-.\bin\gem unpack rugged-0.23.3.gem
-.\bin\gem spec rugged-0.23.3.gem --ruby > rugged-0.23.3\rugged.gemspec
-```
-
-Now we have to apply a patch to one of the files.
-
-```
-cd rugged-0.23.3\ext\rugged
-notepad extconf.rb
-```
-In the notepad window select **Find** from the Edit Menu (**ctrl+F**) and search for
-
-```Unix Makefiles\””)```
-
-and change it to read
-
-```Unix Makefiles\" -DCMAKE_INSTALL_PREFIX=C:/ -DWINHTTP=OFF")```
-
-Then resave the file and quit notepad.
-Go back to the cmd window
-
-```cd ..\..\```
- 
-you should be back in the folder ```c:\sonic-pi\app\server\native\windows\ruby\rugged-0.23.3```
-
-Now build the patched rugged
-
-```
-..\bin\gem build rugged.gemspec
-..\bin\gem install rugged-0.23.3.gem
-
-
-```
-create the directory path ```c:\sonic-pi\app\server\rb-native\windows\2.2.0```
-
-You will have to create the last two folders windows\2.2.0 in this path. Easiest to do this with  FileExplorer Window NB if you are using Ruby 2.1.x you will substitute the folder 2.1.0 instead of 2.2.0 here. The compiled shared libraries for the gems will be copied to this folder. Keep this window (hereafter referred to as the ```gem .so folder```) open for the purpose.
-
-Different versions of Ruby appear to store the compiled libraries in different places, so it is probably easiest to search for them using a new FileExplorer Window. Open such a window, and navigate to
-```
-c:\ > sonic-pi > app > server > native > windows > ruby > lib > ruby > gems
-```
-You will use this window three times to search for the three .so files which need to be copied.
-
-A) ***did_you_mean gem*** The shared object file in this case is called ```method_receiver.so``` It will be copied to a folder ```did_you_mean``` which you have to create in the ```gem .so folder``` referred to above.
-To find it, type ```method*.so``` in the search field (top right) 
-Select one of the hits, right click and select open file location. This should reveal a file ```method_receiver.so``` which is the shared object file to support the did_you_mean gem. This needs to be copied to the folder ```did_you_mean``` which you created in the  ```gem .so folder```
-
-B) ***ffi gem*** The shared object file in this case is called ```ffi_c.so``` It is copied to the ```gem .so folder```
-use the left arrow in the window where the ```method_receiver.so``` file was found to return to the search screen, and amend the search. Search for ```ffi*.so```
-IF you are using Ruby 2.2.* you will see several matches. Note that they are NOT all the same size. This is because this gem unfortunately builds with several versions of the file for different versions of Ruby. IT IS VERY IMPORTANT TO SELECT THE RIGHT ONE, which will be in a folder ```2.2``` Other versions which you DON'T want are in folders 1.8,1.9,2.0 and 2.1. Copy the correct version to 
-the ```gem .so folder``` If you are using Ruby 2.1.* the problem does not seem to arise, and although there are several matches to the search, they are all identical.
-
-C) ***rugged gem*** The shared object file in this case is ```rugged.so``` It is copied to the ```gem .so folder```
-use the left arrow in the window where the ```ffi_c.so``` file was found to return to the search screen, and amend the search. Search for ```rugged.so``` Select one of the matches and copy the file to the ```gem .so folder```
-
-At the end of this copying process the ```gem .so folder ``` which is 
-```
-c:\app\server\rb-native\windows\2.2.0\
-```
-(assuming you are using Ruby 2.2.*, or a path ending in 2.1.0 if using Ruby 2.1.*) will contain: ```ffi_c.so```, ```rugged.so``` and a folder named ```did_you_mean``` containing ```method_receiver.so```
-
-(Note nothing needs to be copied with the win32-process gem)
-
-That completes the ruby preparation work. Close the cmd and FileExplorer windows.
-
-
-### Preparing the Qt GUI
-From the **Start Button** select **All apps** and scroll down to **Visual Studio 2013**, and then to **Visual Studio Tools**. From the Window that opens **right click**  **VS2013 x86 Native Tools Command Prompt** and **Pin it to the Taskbar**. **Double click it** there to open a window which should be titled **VS2013 x86 Native Tools Command Prompt**.
-
-Type **path** in that window after the prompt and press the enter key.
-
-You will see a long string of folder locations which comprise the path associated with the window, which it will automatically search. It includes links to the various elements of visual studio. However, we have to add one more item, which is the path of the Qt bin directory.
-
-Since the Visual Studio prompt path is rebuilt each time a window is opened, I have found the convenient way to do this is to create a **batch file** which can be run each time to add the additional entry. Since I want to store this at the C:\ top level, we have to run the cmd window with administrative privileges to create it.
-Close the open Visual Studio Command Prompt window, then reopen it, holding down **Shift** and **Ctrl** when you do so. Say **Yes** to the popup window, and you will then have a cmd window with admin privileges. 
-
-```
-cd c:\
-notepad
-```
-
-In the open notepad window type
-```
-PATH=%PATH%;C:\Qt\Qt5.5.1\5.5\msvc2013\bin
-```
-
-Then select **save** and save the file as ```pathupdate.bat```, at the top level of ```c:\``` Make sure you select **All Files** for the type so the extension can be set to **.bat** and NOT **.txt**
-
-Close notepad and type ```dir``` (and press return) You should see the file ```pathupdate.bat``` listed.
-
-Close the cmd window and double click the icon on the taskbar to reopen it with "normal" privileges.
-
-```
-cd c:\
-pathupdate.bat
-```
-
-You should see the long path as before, but now with an additional entry ```C:\Qt\Qt5.5.1\5.5\msvc2013\bin``` at the end
-Leave this window open.
-
-Download **Qscintilla** from https://www.riverbankcomputing.com/software/qscintilla/download
-
-Select the ```Qscintilla-gpl-2.9.1.zip``` file to download
-When downloaded extract the ```Qscintilla-gpl-2.9.1``` folder to ```c:\```
-
-Return to the visual studio command window. 
-```
-cd c:\QScintilla-gpl-2.9.1\Qt4Qt5
-qmake qscintilla.pro
-nmake
-```
-(it will now be compiled)
-```
-nmake install
-```
-keep the cmd window open
-
-copy ```Qt4Qt5\release\moc_qsciscintilla.cpp``` and ```moc_qsciscintillabase.cpp``` to 
-```c:\sonic-pi\app\gui\qt\platform\win``` (There may be two files there already, but overwrite them)
-Best done using two FileExplorer windows as before.
-
-Now we do the main build of Sonic-Pi gui, using the open cmd window.
-```
-cd c:\sonic-pi
-.\app\gui\qt\win-build-app.bat
-```
-This should carry out the build. Don’t worry about various warnings en route.
-We now add some files from visual studio which will be needed at run time.
-Open two FileExplorer windows. In the first navigate to:
-
-```Local Disk (C:)> Program Files (x86) > Microsoft Visual Studio 12.0 > VC > redist > x86 > Microsoft.VC120.CRT```
-
-In the second to
-
-```Local Disk (C:)> sonic-pi> app > gui > qt > release```
-
-Copy msvcp120.dll and msvcr120.dll from the former to the latter.
-
-In the second window navigate to **sonic-pi.exe** and **right-click** it to create a shortcut. Drag the shortcut to the desktop. Do NOT attempt to run it yet.
-
-###  The final stage deals with SuperCollider
-Install SuperCollider from http://supercollider.github.io/download.html
-Select the **Win32 3.6.6** installer and download it
-
-Run the installer
-
-Download additional SuperCollider plugins from
-
-http://sourceforge.net/projects/sc3-plugins/files/sc3-plugins%20Windows/
-
-Select the latest version link at the top of the page and download
-```Looking for the latest version? Download sc3-plugins-3.6.0-win32.zip (10.3 MB)```
-Extract them in the download folder.
-
-We now copy files to the sonic-pi installation.
-
-With two FileExplorer windows navigate the first to ```Local Disk (C:) >Program Files (x86) > SuperCollider```
-
-And the second (destination) to ```Local Disk (C:)> sonic-pi > app > server > native > windows```
-
-Copy the ```plugins``` folder from the former to the latter.
-
-Copy all dll files **EXCEPT those starting with QT** from the former to the latter.
-
-Copy ```scsynth.exe``` from the former to the latter.
-
-Keep these windows open for the moment.
-
-Open the ```sc3-plugins-3.6.0-win32``` folder in the Downloads folder and navigate to ```SC3-plugins```.
-Copy all the *.scx files that folder into the ```plugins``` folder copied to destination folder in the previous step.
-
-Close the open FileExplorer windows.
-
-There is one final patch to install. The Ugen file associated with the Piano synth was updated in the summer, to eliminate a problem with the tuning. Unfortunately the current Ugen has NOT yet been updated for windows, and consequently we have to use a modified version of the MdaUgen. This can be downloaded from https://goo.gl/K316fw
-Extract the contents and follow the instructions in the readme file. Basically you replace the file ```sonic-pi-piano.scsyndef``` in ```c:\sonic-pi\etc\synthdefs\compiled``` with the one downloaded in the patch.
-
-(You may like to retain a copy of the original before overwriting it, or perhaps rename it to ```sonic-pi-piano.scsyndef.original```)
-
-### Finished!
-That should complete the installation of Sonic Pi.
-Try running it by double clicking the Sonic Pi shortcut on the desktop.
-
-
-Robin Newman, 17th December 2015
diff --git a/app/gui/html/cljs/defpi/keyboard.cljs b/app/gui/html/cljs/defpi/keyboard.cljs
new file mode 100644
index 0000000..0d52d43
--- /dev/null
+++ b/app/gui/html/cljs/defpi/keyboard.cljs
@@ -0,0 +1,36 @@
+;;#--
+;;# This file is part of Sonic Pi: http://sonic-pi.net
+;;# Full project source: https://github.com/samaaron/sonic-pi
+;;# License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+;;#
+;;# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+;;# All rights reserved.
+;;#
+;;# Permission is granted for use, copying, modification, and
+;;# distribution of modified versions of this work as long as this
+;;# notice is included.
+;;#++
+
+(ns defpi.keyboard
+  (:require
+   [goog.events :as events]
+   [goog.events.EventType]))
+
+
+(def keyword->event-type
+  {:keyup goog.events.EventType.KEYUP
+   :keydown goog.events.EventType.KEYDOWN
+   :keypress goog.events.EventType.KEYPRESS
+   :click goog.events.EventType.CLICK
+   :dblclick goog.events.EventType.DBLCLICK
+   :mousedown goog.events.EventType.MOUSEDOWN
+   :mouseup goog.events.EventType.MOUSEUP
+   :mouseover goog.events.EventType.MOUSEOVER
+   :mouseout goog.events.EventType.MOUSEOUT
+   :mousemove goog.events.EventType.MOUSEMOVE
+   :focus goog.events.EventType.FOCUS
+   :blur goog.events.EventType.BLUR})
+
+(defn charcode->char
+  [code]
+  (js/String.fromCharCode code))
diff --git a/app/gui/html/cljs/defpi/onload.cljs b/app/gui/html/cljs/defpi/onload.cljs
new file mode 100644
index 0000000..98d188d
--- /dev/null
+++ b/app/gui/html/cljs/defpi/onload.cljs
@@ -0,0 +1,21 @@
+;;#--
+;;# This file is part of Sonic Pi: http://sonic-pi.net
+;;# Full project source: https://github.com/samaaron/sonic-pi
+;;# License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+;;#
+;;# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+;;# All rights reserved.
+;;#
+;;# Permission is granted for use, copying, modification, and
+;;# distribution of modified versions of this work as long as this
+;;# notice is included.
+;;#++
+
+(ns defpi.onload
+  (:require [defpi.ws :refer [add-ws-handlers mk-ws]]))
+
+(set! (.-onload js/window)
+      (fn []
+        (mk-ws)
+        (add-ws-handlers)
+        ))
diff --git a/app/gui/html/cljs/defpi/ringbuffer.cljs b/app/gui/html/cljs/defpi/ringbuffer.cljs
new file mode 100644
index 0000000..2036970
--- /dev/null
+++ b/app/gui/html/cljs/defpi/ringbuffer.cljs
@@ -0,0 +1,46 @@
+;;#--
+;;# This file is part of Sonic Pi: http://sonic-pi.net
+;;# Full project source: https://github.com/samaaron/sonic-pi
+;;# License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+;;#
+;;# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+;;# All rights reserved.
+;;#
+;;# Permission is granted for use, copying, modification, and
+;;# distribution of modified versions of this work as long as this
+;;# notice is included.
+;;#++
+
+(ns defpi.ringbuffer)
+
+(declare rb-seq)
+
+(deftype RingBuffer [size idx content]
+  ISeqable
+  (-seq [this] (rb-seq this)))
+
+(defn mk-ringbuffer [size]
+  (RingBuffer. size 0 {}))
+
+(defn add [rb el]
+  (let [idx  (.-idx rb)
+        size (.-size rb)]
+    (RingBuffer. size
+                 (mod (inc idx) size)
+                 (assoc (.-content rb)
+                   idx el))))
+
+(defn rb-rseq
+  ([rb] (rb-seq rb (.-idx rb) (.-size rb)))
+  ([rb idx left]
+     (lazy-seq
+      (when (> left 0)
+        (cons (get (.-content rb) idx) (rb-seq rb (mod (inc idx) (.-size rb)) (dec left)))))))
+
+(defn rb-seq
+  ([rb] (rb-seq rb (.-idx rb) (.-size rb)))
+  ([rb idx left]
+     (let [idx (mod (dec idx) (.-size rb)) ]
+       (lazy-seq
+        (when (> left 0)
+          (cons (get (.-content rb) idx) (rb-seq rb idx (dec left))))))))
diff --git a/app/gui/html/cljs/defpi/ws.cljs b/app/gui/html/cljs/defpi/ws.cljs
new file mode 100644
index 0000000..1042e32
--- /dev/null
+++ b/app/gui/html/cljs/defpi/ws.cljs
@@ -0,0 +1,183 @@
+;;#--
+;;# This file is part of Sonic Pi: http://sonic-pi.net
+;;# Full project source: https://github.com/samaaron/sonic-pi
+;;# License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+;;#
+;;# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+;;# All rights reserved.
+;;#
+;;# Permission is granted for use, copying, modification, and
+;;# distribution of modified versions of this work as long as this
+;;# notice is included.
+;;#++
+
+(ns defpi.ws
+  (:require-macros [cljs.core.async.macros :refer [go]])
+  (:require
+   [cljs.core.async :as async :refer [>! <! put! chan]]
+   [clojure.string :as str]
+   [om.core :as om :include-macros true]
+   [om.dom :as dom :include-macros true]
+   [goog.events :as events]
+   [cljs.reader :as reader]
+   [defpi.ringbuffer :as rb]
+   [defpi.keyboard :as kb]))
+
+(enable-console-print!)
+
+(declare stop-job)
+
+(def ws (atom nil))
+(def err-cnt (atom 0))
+(def app-state (atom {:messages (rb/mk-ringbuffer 100)
+                      :jobs #{}}))
+
+(defn jobs-comp [data owner]
+  (om/component
+   (apply dom/div nil
+          (map (fn [j-id]
+                 (dom/div #js{:className "animated rotateIn"
+                              :onClick #(stop-job j-id)
+                              :style #js{:float "right"
+                                         :height "35px"
+                                         :width "35px"
+                                         :color "white"
+                                         :font-size "15px"
+                                         ;; :border-width "5px"
+                                         ;; :border-style "solid"
+                                         ;; :border-color "#5e5e5e"
+                                         :background "deeppink"}} j-id))
+               (:jobs data)))))
+
+(defn message-comp [data owner]
+  (om/component
+   (apply dom/div nil
+          (map (fn [m]
+                 (dom/div nil (get m "val")
+                          (when (get m "backtrace")
+                            (dom/div nil
+                                     (dom/pre nil
+                                              (str/join "\n" (get m "backtrace")))))))
+               (:messages data)))))
+
+(def hostname
+  (let [hn (.-host (.-location js/window))]
+    (if (= "" hn)
+      "localhost"
+      (re-find #"[^\:]+" hn))))
+
+(defn show-msg
+  [msg]
+  (swap! app-state update-in [:messages] rb/add msg)
+  )
+
+(defn show-multi-msg
+  [msg]
+  (swap! app-state update-in [:messages] rb/add msg)
+  )
+
+(defn reply-sync
+  [msg res]
+  (when-let [id (:sync msg)]
+    (.send @ws {:cmd    "sync"
+               :val    id
+               :result (cond
+                        (number? res)  res
+                        (keyword? res) res
+                        :else          (str res))})))
+
+(defmulti handle-message #(get % "type"))
+
+(defmethod handle-message "message"
+  [msg]
+  (show-msg msg))
+
+(defmethod handle-message "multimessage"
+  [msgs]
+  (show-multi-msg msgs))
+
+(defmethod handle-message "error"
+  [msg]
+  (show-msg msg))
+
+(defmethod handle-message "debug_message"
+  [msg]
+  (println "debug=> " msg))
+
+(defmethod handle-message "replace-buffer"
+  [msg]
+  (.setValue js/editor (get msg "val")))
+
+(defmethod handle-message "job"
+  [msg]
+  (cond
+   (= "start" (get msg "action"))
+   (swap! app-state update-in [:jobs] conj (get msg "jobid"))
+
+   (= "completed" (get msg "action"))
+   (swap! app-state update-in [:jobs] disj (get msg "jobid" ))
+
+   :else
+   (js/alert (str "Unknown job action: " (:action msg)))
+
+    ))
+
+(defmethod handle-message js/Object
+  [m]
+  (js/console.log "can't handle: " (:type m)))
+
+(defn replace-buffer [buf-id]
+  (.send @ws (JSON/stringify #js {:cmd  "load-buffer"
+                                  :id   (str buf-id)})))
+
+(defn add-ws-handlers
+  []
+  (set! (.-onopen @ws) (fn []
+                        (om/root message-comp app-state {:target (.getElementById js/document "app-messages")})
+
+                        (om/root jobs-comp app-state {:target (.getElementById js/document "app-jobs")})
+                        (replace-buffer "main")))
+
+  (set! (.-onclose @ws) #(show-msg "Websocket Closed"))
+  (set! (.-onmessage @ws) (fn [m]
+                           (let [msg (js->clj (JSON/parse (.-data m)))
+                                 res (handle-message msg)]
+                             (reply-sync msg res))))
+  (events/listen js/document (kb/keyword->event-type :keypress)
+               (fn [e]
+                 (let [code (.-charCode e)]
+                   (cond
+                    (= 18 code)
+                    (.send @ws (JSON/stringify #js{"cmd" "save-and-run-buffer"
+                                                   "val" (.getValue js/editor)
+                                                   "buffer_id" "main"}))
+
+                    (= 19 code)
+                    (.send @ws (JSON/stringify #js{"cmd" "stop-jobs"
+                                                   "val" (.getValue js/editor)}))))))
+
+)
+
+(defn ^:export sendCode
+  []
+  (.send @ws (JSON/stringify #js {:cmd "save-and-run-buffer"
+                                  :val (.getValue js/editor)
+                                  :buffer_id "main"})))
+
+
+(defn ^:export stopCode
+  []
+  (.send @ws (JSON/stringify #js {:cmd "stop-jobs"
+                                :val (.getValue js/editor)})))
+
+(defn ^:export reloadCode
+  []
+  (.send @ws (JSON/stringify #js {:cmd "reload"
+                                :val (.getValue js/editor)})))
+
+(defn stop-job [j-id]
+  (.send @ws (JSON/stringify #js {:cmd "stop-job"
+                                 :val j-id})))
+
+(defn mk-ws []
+  (reset! ws (js/WebSocket. (str "ws://" hostname  ":8001"))))
diff --git a/app/gui/html/index.html b/app/gui/html/index.html
new file mode 100644
index 0000000..6d5c006
--- /dev/null
+++ b/app/gui/html/index.html
@@ -0,0 +1,56 @@
+<!-- This file is part of Sonic Pi: http://sonic-pi.net -->
+<!-- Full project source: https://github.com/samaaron/sonic-pi -->
+<!-- License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md -->
+
+<!-- Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name). -->
+<!-- All rights reserved. -->
+
+<!-- Permission is granted for use, copying, modification, and -->
+<!-- distribution of modified versions of this work as long as this -->
+<!-- notice is included. -->
+
+
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf-8"/>
+    <title>Sonic Pi</title>
+
+    <script src="vendor/codemirror/lib/codemirror.js"></script>
+    <script src="vendor/codemirror/addon/edit/matchbrackets.js"></script>
+    <script src="vendor/codemirror/mode/ruby/ruby.js"></script>
+    <script src="vendor/react-0.9.0.js"></script>
+
+
+    <link rel="stylesheet" href="vendor/animate.css">
+    <link rel="stylesheet" href="vendor/codemirror/lib/codemirror.css">
+    <link rel="stylesheet" href="vendor/bootstrap/css/bootstrap.css">
+    <link rel="stylesheet" href="style//main.css">
+  </head>
+
+  <body>
+   <center> <img src="public/sonic-pi-web-logo.png" height="148" width="233"></center>
+    <div id="my-stage"></div>
+    <img src="public/run.png" id="run" class=" animated bounceInLeft" onClick="defpi.ws.sendCode()" height="37" width="90">
+    <img src="public/stop.png" id="stop" class="animated bounceInLeft" onClick="defpi.ws.stopCode()" height="37" width="90">
+    <!-- <button id="reload" class="btn btn-success animated bounceInLeft" onClick="defpi.ws.reloadCode()">Reload</button> -->
+    <div id="app-jobs" style="float: right;"></div>
+    <div  class="animated fadeIn">
+
+      <textarea id="code">## Loading Buffer...
+</textarea>
+      </div>
+
+    <div id="app-messages"></div>
+
+    <script src="js/init_editor.js"></script>
+    <script src="js/generated/goog/base.js" type="text/javascript"></script>
+    <script src="js/cljs-main.js" type="text/javascript"></script>
+    <script type="text/javascript">goog.require("defpi.onload");</script>
+
+  </body>
+
+
+
+
+</html>
diff --git a/app/gui/html/js/init_editor.js b/app/gui/html/js/init_editor.js
new file mode 100644
index 0000000..edba9fe
--- /dev/null
+++ b/app/gui/html/js/init_editor.js
@@ -0,0 +1,21 @@
+// --
+//  This file is part of Sonic Pi: http://sonic-pi.net
+//  Full project source: https://github.com/samaaron/sonic-pi
+//  License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+//
+//  Copyright 2013, 2014 by Sam Aaron (http://sam.aaron.name).
+//  All rights reserved.
+//
+//  Permission is granted for use, copying, modification, distribution,
+//  and distribution of modified versions of this work as long as this
+//  notice is included.
+// ++
+
+var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+    mode: "text/x-ruby",
+    tabMode: "indent",
+    matchBrackets: true,
+    indentUnit: 2,
+    lineNumbers: true,
+    value: "#foo"
+});
diff --git a/app/gui/html/project.clj b/app/gui/html/project.clj
new file mode 100644
index 0000000..071e909
--- /dev/null
+++ b/app/gui/html/project.clj
@@ -0,0 +1,37 @@
+;;#--
+;;# This file is part of Sonic Pi: http://sonic-pi.net
+;;# Full project source: https://github.com/samaaron/sonic-pi
+;;# License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+;;#
+;;# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+;;# All rights reserved.
+;;#
+;;# Permission is granted for use, copying, modification, and
+;;# distribution of modified versions of this work as long as this
+;;# notice is included.
+;;#++
+
+(defproject defining-pi "0.0.0-SNAPSHOT"
+  :description "Sonic Pi HTML Interface"
+  :dependencies [[org.clojure/clojure "1.5.1"]
+                 [org.clojure/clojurescript "0.0-2173" :scope "provided"]
+                 [org.clojure/core.async "0.1.267.0-0d7780-alpha" :scope "provided"]
+                 [com.facebook/react "0.9.0"]
+                 [om "0.5.0"]]
+  :plugins [[lein-cljsbuild "1.0.2"]]
+  :source-paths ["src-cljs"]
+  :profiles {:dev {:plugins [[com.cemerick/austin "0.1.3"]]}}
+  :cljsbuild {
+              :builds [{:id "dev"
+                        :source-paths ["cljs"]
+                        :compiler {
+                                   :output-dir "js/generated"
+                                   :output-to "js/cljs-main.js"
+                                   :source-map true
+                                   :optimizations :none}}
+                       {:id "release"
+                        :source-paths ["cljs"]
+                        :compiler {
+                                   :output-to "js/cljs-main.js"
+                                   :optimizations :advanced
+                                   :pretty-print false}}]})
diff --git a/app/gui/qt/images/run.png b/app/gui/html/public/run.png
similarity index 100%
copy from app/gui/qt/images/run.png
copy to app/gui/html/public/run.png
diff --git a/app/gui/html/public/sonic-pi-web-logo.png b/app/gui/html/public/sonic-pi-web-logo.png
new file mode 100644
index 0000000..a0e17fa
Binary files /dev/null and b/app/gui/html/public/sonic-pi-web-logo.png differ
diff --git a/app/gui/qt/images/stop.png b/app/gui/html/public/stop.png
similarity index 100%
copy from app/gui/qt/images/stop.png
copy to app/gui/html/public/stop.png
diff --git a/app/gui/html/style/main.css b/app/gui/html/style/main.css
new file mode 100644
index 0000000..ba59e4c
--- /dev/null
+++ b/app/gui/html/style/main.css
@@ -0,0 +1,17 @@
+/*
+
+ This file is part of Sonic Pi: http://sonic-pi.net
+ Full project source: https://github.com/samaaron/sonic-pi
+ License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+
+ Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+ All rights reserved.
+
+ Permission is granted for use, copying, modification, and
+ distribution of modified versions of this work as long as this
+ notice is included.
+
+*/
+
+.CodeMirror {border-top: 10px solid black; border-bottom: 10px solid black;}
+.cm-s-default span.cm-arrow { color: red; }
diff --git a/app/gui/html/vendor/animate.css b/app/gui/html/vendor/animate.css
new file mode 100644
index 0000000..d71da17
--- /dev/null
+++ b/app/gui/html/vendor/animate.css
@@ -0,0 +1,2744 @@
+ at charset "UTF-8";
+
+
+/*!
+Animate.css - http://daneden.me/animate
+Licensed under the MIT license
+
+Copyright (c) 2013 Daniel Eden
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+.animated {
+  -webkit-animation-duration: 1s;
+  animation-duration: 1s;
+  -webkit-animation-fill-mode: both;
+  animation-fill-mode: both;
+}
+
+.animated.hinge {
+  -webkit-animation-duration: 2s;
+  animation-duration: 2s;
+}
+
+ at -webkit-keyframes bounce {
+  0%, 20%, 50%, 80%, 100% {
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  40% {
+    -webkit-transform: translateY(-30px);
+    transform: translateY(-30px);
+  }
+
+  60% {
+    -webkit-transform: translateY(-15px);
+    transform: translateY(-15px);
+  }
+}
+
+ at keyframes bounce {
+  0%, 20%, 50%, 80%, 100% {
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  40% {
+    -webkit-transform: translateY(-30px);
+    -ms-transform: translateY(-30px);
+    transform: translateY(-30px);
+  }
+
+  60% {
+    -webkit-transform: translateY(-15px);
+    -ms-transform: translateY(-15px);
+    transform: translateY(-15px);
+  }
+}
+
+.bounce {
+  -webkit-animation-name: bounce;
+  animation-name: bounce;
+}
+
+ at -webkit-keyframes flash {
+  0%, 50%, 100% {
+    opacity: 1;
+  }
+
+  25%, 75% {
+    opacity: 0;
+  }
+}
+
+ at keyframes flash {
+  0%, 50%, 100% {
+    opacity: 1;
+  }
+
+  25%, 75% {
+    opacity: 0;
+  }
+}
+
+.flash {
+  -webkit-animation-name: flash;
+  animation-name: flash;
+}
+
+/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
+
+ at -webkit-keyframes pulse {
+  0% {
+    -webkit-transform: scale(1);
+    transform: scale(1);
+  }
+
+  50% {
+    -webkit-transform: scale(1.1);
+    transform: scale(1.1);
+  }
+
+  100% {
+    -webkit-transform: scale(1);
+    transform: scale(1);
+  }
+}
+
+ at keyframes pulse {
+  0% {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+  }
+
+  50% {
+    -webkit-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    transform: scale(1.1);
+  }
+
+  100% {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+  }
+}
+
+.pulse {
+  -webkit-animation-name: pulse;
+  animation-name: pulse;
+}
+
+ at -webkit-keyframes shake {
+  0%, 100% {
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  10%, 30%, 50%, 70%, 90% {
+    -webkit-transform: translateX(-10px);
+    transform: translateX(-10px);
+  }
+
+  20%, 40%, 60%, 80% {
+    -webkit-transform: translateX(10px);
+    transform: translateX(10px);
+  }
+}
+
+ at keyframes shake {
+  0%, 100% {
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  10%, 30%, 50%, 70%, 90% {
+    -webkit-transform: translateX(-10px);
+    -ms-transform: translateX(-10px);
+    transform: translateX(-10px);
+  }
+
+  20%, 40%, 60%, 80% {
+    -webkit-transform: translateX(10px);
+    -ms-transform: translateX(10px);
+    transform: translateX(10px);
+  }
+}
+
+.shake {
+  -webkit-animation-name: shake;
+  animation-name: shake;
+}
+
+ at -webkit-keyframes swing {
+  20% {
+    -webkit-transform: rotate(15deg);
+    transform: rotate(15deg);
+  }
+
+  40% {
+    -webkit-transform: rotate(-10deg);
+    transform: rotate(-10deg);
+  }
+
+  60% {
+    -webkit-transform: rotate(5deg);
+    transform: rotate(5deg);
+  }
+
+  80% {
+    -webkit-transform: rotate(-5deg);
+    transform: rotate(-5deg);
+  }
+
+  100% {
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+}
+
+ at keyframes swing {
+  20% {
+    -webkit-transform: rotate(15deg);
+    -ms-transform: rotate(15deg);
+    transform: rotate(15deg);
+  }
+
+  40% {
+    -webkit-transform: rotate(-10deg);
+    -ms-transform: rotate(-10deg);
+    transform: rotate(-10deg);
+  }
+
+  60% {
+    -webkit-transform: rotate(5deg);
+    -ms-transform: rotate(5deg);
+    transform: rotate(5deg);
+  }
+
+  80% {
+    -webkit-transform: rotate(-5deg);
+    -ms-transform: rotate(-5deg);
+    transform: rotate(-5deg);
+  }
+
+  100% {
+    -webkit-transform: rotate(0deg);
+    -ms-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+}
+
+.swing {
+  -webkit-transform-origin: top center;
+  -ms-transform-origin: top center;
+  transform-origin: top center;
+  -webkit-animation-name: swing;
+  animation-name: swing;
+}
+
+ at -webkit-keyframes tada {
+  0% {
+    -webkit-transform: scale(1);
+    transform: scale(1);
+  }
+
+  10%, 20% {
+    -webkit-transform: scale(0.9) rotate(-3deg);
+    transform: scale(0.9) rotate(-3deg);
+  }
+
+  30%, 50%, 70%, 90% {
+    -webkit-transform: scale(1.1) rotate(3deg);
+    transform: scale(1.1) rotate(3deg);
+  }
+
+  40%, 60%, 80% {
+    -webkit-transform: scale(1.1) rotate(-3deg);
+    transform: scale(1.1) rotate(-3deg);
+  }
+
+  100% {
+    -webkit-transform: scale(1) rotate(0);
+    transform: scale(1) rotate(0);
+  }
+}
+
+ at keyframes tada {
+  0% {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+  }
+
+  10%, 20% {
+    -webkit-transform: scale(0.9) rotate(-3deg);
+    -ms-transform: scale(0.9) rotate(-3deg);
+    transform: scale(0.9) rotate(-3deg);
+  }
+
+  30%, 50%, 70%, 90% {
+    -webkit-transform: scale(1.1) rotate(3deg);
+    -ms-transform: scale(1.1) rotate(3deg);
+    transform: scale(1.1) rotate(3deg);
+  }
+
+  40%, 60%, 80% {
+    -webkit-transform: scale(1.1) rotate(-3deg);
+    -ms-transform: scale(1.1) rotate(-3deg);
+    transform: scale(1.1) rotate(-3deg);
+  }
+
+  100% {
+    -webkit-transform: scale(1) rotate(0);
+    -ms-transform: scale(1) rotate(0);
+    transform: scale(1) rotate(0);
+  }
+}
+
+.tada {
+  -webkit-animation-name: tada;
+  animation-name: tada;
+}
+
+/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
+
+ at -webkit-keyframes wobble {
+  0% {
+    -webkit-transform: translateX(0%);
+    transform: translateX(0%);
+  }
+
+  15% {
+    -webkit-transform: translateX(-25%) rotate(-5deg);
+    transform: translateX(-25%) rotate(-5deg);
+  }
+
+  30% {
+    -webkit-transform: translateX(20%) rotate(3deg);
+    transform: translateX(20%) rotate(3deg);
+  }
+
+  45% {
+    -webkit-transform: translateX(-15%) rotate(-3deg);
+    transform: translateX(-15%) rotate(-3deg);
+  }
+
+  60% {
+    -webkit-transform: translateX(10%) rotate(2deg);
+    transform: translateX(10%) rotate(2deg);
+  }
+
+  75% {
+    -webkit-transform: translateX(-5%) rotate(-1deg);
+    transform: translateX(-5%) rotate(-1deg);
+  }
+
+  100% {
+    -webkit-transform: translateX(0%);
+    transform: translateX(0%);
+  }
+}
+
+ at keyframes wobble {
+  0% {
+    -webkit-transform: translateX(0%);
+    -ms-transform: translateX(0%);
+    transform: translateX(0%);
+  }
+
+  15% {
+    -webkit-transform: translateX(-25%) rotate(-5deg);
+    -ms-transform: translateX(-25%) rotate(-5deg);
+    transform: translateX(-25%) rotate(-5deg);
+  }
+
+  30% {
+    -webkit-transform: translateX(20%) rotate(3deg);
+    -ms-transform: translateX(20%) rotate(3deg);
+    transform: translateX(20%) rotate(3deg);
+  }
+
+  45% {
+    -webkit-transform: translateX(-15%) rotate(-3deg);
+    -ms-transform: translateX(-15%) rotate(-3deg);
+    transform: translateX(-15%) rotate(-3deg);
+  }
+
+  60% {
+    -webkit-transform: translateX(10%) rotate(2deg);
+    -ms-transform: translateX(10%) rotate(2deg);
+    transform: translateX(10%) rotate(2deg);
+  }
+
+  75% {
+    -webkit-transform: translateX(-5%) rotate(-1deg);
+    -ms-transform: translateX(-5%) rotate(-1deg);
+    transform: translateX(-5%) rotate(-1deg);
+  }
+
+  100% {
+    -webkit-transform: translateX(0%);
+    -ms-transform: translateX(0%);
+    transform: translateX(0%);
+  }
+}
+
+.wobble {
+  -webkit-animation-name: wobble;
+  animation-name: wobble;
+}
+
+ at -webkit-keyframes bounceIn {
+  0% {
+    opacity: 0;
+    -webkit-transform: scale(.3);
+    transform: scale(.3);
+  }
+
+  50% {
+    opacity: 1;
+    -webkit-transform: scale(1.05);
+    transform: scale(1.05);
+  }
+
+  70% {
+    -webkit-transform: scale(.9);
+    transform: scale(.9);
+  }
+
+  100% {
+    -webkit-transform: scale(1);
+    transform: scale(1);
+  }
+}
+
+ at keyframes bounceIn {
+  0% {
+    opacity: 0;
+    -webkit-transform: scale(.3);
+    -ms-transform: scale(.3);
+    transform: scale(.3);
+  }
+
+  50% {
+    opacity: 1;
+    -webkit-transform: scale(1.05);
+    -ms-transform: scale(1.05);
+    transform: scale(1.05);
+  }
+
+  70% {
+    -webkit-transform: scale(.9);
+    -ms-transform: scale(.9);
+    transform: scale(.9);
+  }
+
+  100% {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+  }
+}
+
+.bounceIn {
+  -webkit-animation-name: bounceIn;
+  animation-name: bounceIn;
+}
+
+ at -webkit-keyframes bounceInDown {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(-2000px);
+    transform: translateY(-2000px);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translateY(30px);
+    transform: translateY(30px);
+  }
+
+  80% {
+    -webkit-transform: translateY(-10px);
+    transform: translateY(-10px);
+  }
+
+  100% {
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+  }
+}
+
+ at keyframes bounceInDown {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(-2000px);
+    -ms-transform: translateY(-2000px);
+    transform: translateY(-2000px);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translateY(30px);
+    -ms-transform: translateY(30px);
+    transform: translateY(30px);
+  }
+
+  80% {
+    -webkit-transform: translateY(-10px);
+    -ms-transform: translateY(-10px);
+    transform: translateY(-10px);
+  }
+
+  100% {
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0);
+  }
+}
+
+.bounceInDown {
+  -webkit-animation-name: bounceInDown;
+  animation-name: bounceInDown;
+}
+
+ at -webkit-keyframes bounceInLeft {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(-2000px);
+    transform: translateX(-2000px);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translateX(30px);
+    transform: translateX(30px);
+  }
+
+  80% {
+    -webkit-transform: translateX(-10px);
+    transform: translateX(-10px);
+  }
+
+  100% {
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+ at keyframes bounceInLeft {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(-2000px);
+    -ms-transform: translateX(-2000px);
+    transform: translateX(-2000px);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translateX(30px);
+    -ms-transform: translateX(30px);
+    transform: translateX(30px);
+  }
+
+  80% {
+    -webkit-transform: translateX(-10px);
+    -ms-transform: translateX(-10px);
+    transform: translateX(-10px);
+  }
+
+  100% {
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+.bounceInLeft {
+  -webkit-animation-name: bounceInLeft;
+  animation-name: bounceInLeft;
+}
+
+ at -webkit-keyframes bounceInRight {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(2000px);
+    transform: translateX(2000px);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translateX(-30px);
+    transform: translateX(-30px);
+  }
+
+  80% {
+    -webkit-transform: translateX(10px);
+    transform: translateX(10px);
+  }
+
+  100% {
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+ at keyframes bounceInRight {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(2000px);
+    -ms-transform: translateX(2000px);
+    transform: translateX(2000px);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translateX(-30px);
+    -ms-transform: translateX(-30px);
+    transform: translateX(-30px);
+  }
+
+  80% {
+    -webkit-transform: translateX(10px);
+    -ms-transform: translateX(10px);
+    transform: translateX(10px);
+  }
+
+  100% {
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+.bounceInRight {
+  -webkit-animation-name: bounceInRight;
+  animation-name: bounceInRight;
+}
+
+ at -webkit-keyframes bounceInUp {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(2000px);
+    transform: translateY(2000px);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translateY(-30px);
+    transform: translateY(-30px);
+  }
+
+  80% {
+    -webkit-transform: translateY(10px);
+    transform: translateY(10px);
+  }
+
+  100% {
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+  }
+}
+
+ at keyframes bounceInUp {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(2000px);
+    -ms-transform: translateY(2000px);
+    transform: translateY(2000px);
+  }
+
+  60% {
+    opacity: 1;
+    -webkit-transform: translateY(-30px);
+    -ms-transform: translateY(-30px);
+    transform: translateY(-30px);
+  }
+
+  80% {
+    -webkit-transform: translateY(10px);
+    -ms-transform: translateY(10px);
+    transform: translateY(10px);
+  }
+
+  100% {
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0);
+  }
+}
+
+.bounceInUp {
+  -webkit-animation-name: bounceInUp;
+  animation-name: bounceInUp;
+}
+
+ at -webkit-keyframes bounceOut {
+  0% {
+    -webkit-transform: scale(1);
+    transform: scale(1);
+  }
+
+  25% {
+    -webkit-transform: scale(.95);
+    transform: scale(.95);
+  }
+
+  50% {
+    opacity: 1;
+    -webkit-transform: scale(1.1);
+    transform: scale(1.1);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: scale(.3);
+    transform: scale(.3);
+  }
+}
+
+ at keyframes bounceOut {
+  0% {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+  }
+
+  25% {
+    -webkit-transform: scale(.95);
+    -ms-transform: scale(.95);
+    transform: scale(.95);
+  }
+
+  50% {
+    opacity: 1;
+    -webkit-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    transform: scale(1.1);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: scale(.3);
+    -ms-transform: scale(.3);
+    transform: scale(.3);
+  }
+}
+
+.bounceOut {
+  -webkit-animation-name: bounceOut;
+  animation-name: bounceOut;
+}
+
+ at -webkit-keyframes bounceOutDown {
+  0% {
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  20% {
+    opacity: 1;
+    -webkit-transform: translateY(-20px);
+    transform: translateY(-20px);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(2000px);
+    transform: translateY(2000px);
+  }
+}
+
+ at keyframes bounceOutDown {
+  0% {
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  20% {
+    opacity: 1;
+    -webkit-transform: translateY(-20px);
+    -ms-transform: translateY(-20px);
+    transform: translateY(-20px);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(2000px);
+    -ms-transform: translateY(2000px);
+    transform: translateY(2000px);
+  }
+}
+
+.bounceOutDown {
+  -webkit-animation-name: bounceOutDown;
+  animation-name: bounceOutDown;
+}
+
+ at -webkit-keyframes bounceOutLeft {
+  0% {
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  20% {
+    opacity: 1;
+    -webkit-transform: translateX(20px);
+    transform: translateX(20px);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(-2000px);
+    transform: translateX(-2000px);
+  }
+}
+
+ at keyframes bounceOutLeft {
+  0% {
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  20% {
+    opacity: 1;
+    -webkit-transform: translateX(20px);
+    -ms-transform: translateX(20px);
+    transform: translateX(20px);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(-2000px);
+    -ms-transform: translateX(-2000px);
+    transform: translateX(-2000px);
+  }
+}
+
+.bounceOutLeft {
+  -webkit-animation-name: bounceOutLeft;
+  animation-name: bounceOutLeft;
+}
+
+ at -webkit-keyframes bounceOutRight {
+  0% {
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  20% {
+    opacity: 1;
+    -webkit-transform: translateX(-20px);
+    transform: translateX(-20px);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(2000px);
+    transform: translateX(2000px);
+  }
+}
+
+ at keyframes bounceOutRight {
+  0% {
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  20% {
+    opacity: 1;
+    -webkit-transform: translateX(-20px);
+    -ms-transform: translateX(-20px);
+    transform: translateX(-20px);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(2000px);
+    -ms-transform: translateX(2000px);
+    transform: translateX(2000px);
+  }
+}
+
+.bounceOutRight {
+  -webkit-animation-name: bounceOutRight;
+  animation-name: bounceOutRight;
+}
+
+ at -webkit-keyframes bounceOutUp {
+  0% {
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  20% {
+    opacity: 1;
+    -webkit-transform: translateY(20px);
+    transform: translateY(20px);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(-2000px);
+    transform: translateY(-2000px);
+  }
+}
+
+ at keyframes bounceOutUp {
+  0% {
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  20% {
+    opacity: 1;
+    -webkit-transform: translateY(20px);
+    -ms-transform: translateY(20px);
+    transform: translateY(20px);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(-2000px);
+    -ms-transform: translateY(-2000px);
+    transform: translateY(-2000px);
+  }
+}
+
+.bounceOutUp {
+  -webkit-animation-name: bounceOutUp;
+  animation-name: bounceOutUp;
+}
+
+ at -webkit-keyframes fadeIn {
+  0% {
+    opacity: 0;
+  }
+
+  100% {
+    opacity: 1;
+  }
+}
+
+ at keyframes fadeIn {
+  0% {
+    opacity: 0;
+  }
+
+  100% {
+    opacity: 1;
+  }
+}
+
+.fadeIn {
+  -webkit-animation-name: fadeIn;
+  animation-name: fadeIn;
+}
+
+ at -webkit-keyframes fadeInDown {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(-20px);
+    transform: translateY(-20px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+  }
+}
+
+ at keyframes fadeInDown {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(-20px);
+    -ms-transform: translateY(-20px);
+    transform: translateY(-20px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0);
+  }
+}
+
+.fadeInDown {
+  -webkit-animation-name: fadeInDown;
+  animation-name: fadeInDown;
+}
+
+ at -webkit-keyframes fadeInDownBig {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(-2000px);
+    transform: translateY(-2000px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+  }
+}
+
+ at keyframes fadeInDownBig {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(-2000px);
+    -ms-transform: translateY(-2000px);
+    transform: translateY(-2000px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0);
+  }
+}
+
+.fadeInDownBig {
+  -webkit-animation-name: fadeInDownBig;
+  animation-name: fadeInDownBig;
+}
+
+ at -webkit-keyframes fadeInLeft {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(-20px);
+    transform: translateX(-20px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+ at keyframes fadeInLeft {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(-20px);
+    -ms-transform: translateX(-20px);
+    transform: translateX(-20px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+.fadeInLeft {
+  -webkit-animation-name: fadeInLeft;
+  animation-name: fadeInLeft;
+}
+
+ at -webkit-keyframes fadeInLeftBig {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(-2000px);
+    transform: translateX(-2000px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+ at keyframes fadeInLeftBig {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(-2000px);
+    -ms-transform: translateX(-2000px);
+    transform: translateX(-2000px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+.fadeInLeftBig {
+  -webkit-animation-name: fadeInLeftBig;
+  animation-name: fadeInLeftBig;
+}
+
+ at -webkit-keyframes fadeInRight {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(20px);
+    transform: translateX(20px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+ at keyframes fadeInRight {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(20px);
+    -ms-transform: translateX(20px);
+    transform: translateX(20px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+.fadeInRight {
+  -webkit-animation-name: fadeInRight;
+  animation-name: fadeInRight;
+}
+
+ at -webkit-keyframes fadeInRightBig {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(2000px);
+    transform: translateX(2000px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+ at keyframes fadeInRightBig {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(2000px);
+    -ms-transform: translateX(2000px);
+    transform: translateX(2000px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+.fadeInRightBig {
+  -webkit-animation-name: fadeInRightBig;
+  animation-name: fadeInRightBig;
+}
+
+ at -webkit-keyframes fadeInUp {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(20px);
+    transform: translateY(20px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+  }
+}
+
+ at keyframes fadeInUp {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(20px);
+    -ms-transform: translateY(20px);
+    transform: translateY(20px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0);
+  }
+}
+
+.fadeInUp {
+  -webkit-animation-name: fadeInUp;
+  animation-name: fadeInUp;
+}
+
+ at -webkit-keyframes fadeInUpBig {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(2000px);
+    transform: translateY(2000px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+  }
+}
+
+ at keyframes fadeInUpBig {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(2000px);
+    -ms-transform: translateY(2000px);
+    transform: translateY(2000px);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0);
+  }
+}
+
+.fadeInUpBig {
+  -webkit-animation-name: fadeInUpBig;
+  animation-name: fadeInUpBig;
+}
+
+ at -webkit-keyframes fadeOut {
+  0% {
+    opacity: 1;
+  }
+
+  100% {
+    opacity: 0;
+  }
+}
+
+ at keyframes fadeOut {
+  0% {
+    opacity: 1;
+  }
+
+  100% {
+    opacity: 0;
+  }
+}
+
+.fadeOut {
+  -webkit-animation-name: fadeOut;
+  animation-name: fadeOut;
+}
+
+ at -webkit-keyframes fadeOutDown {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(20px);
+    transform: translateY(20px);
+  }
+}
+
+ at keyframes fadeOutDown {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(20px);
+    -ms-transform: translateY(20px);
+    transform: translateY(20px);
+  }
+}
+
+.fadeOutDown {
+  -webkit-animation-name: fadeOutDown;
+  animation-name: fadeOutDown;
+}
+
+ at -webkit-keyframes fadeOutDownBig {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(2000px);
+    transform: translateY(2000px);
+  }
+}
+
+ at keyframes fadeOutDownBig {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(2000px);
+    -ms-transform: translateY(2000px);
+    transform: translateY(2000px);
+  }
+}
+
+.fadeOutDownBig {
+  -webkit-animation-name: fadeOutDownBig;
+  animation-name: fadeOutDownBig;
+}
+
+ at -webkit-keyframes fadeOutLeft {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(-20px);
+    transform: translateX(-20px);
+  }
+}
+
+ at keyframes fadeOutLeft {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(-20px);
+    -ms-transform: translateX(-20px);
+    transform: translateX(-20px);
+  }
+}
+
+.fadeOutLeft {
+  -webkit-animation-name: fadeOutLeft;
+  animation-name: fadeOutLeft;
+}
+
+ at -webkit-keyframes fadeOutLeftBig {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(-2000px);
+    transform: translateX(-2000px);
+  }
+}
+
+ at keyframes fadeOutLeftBig {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(-2000px);
+    -ms-transform: translateX(-2000px);
+    transform: translateX(-2000px);
+  }
+}
+
+.fadeOutLeftBig {
+  -webkit-animation-name: fadeOutLeftBig;
+  animation-name: fadeOutLeftBig;
+}
+
+ at -webkit-keyframes fadeOutRight {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(20px);
+    transform: translateX(20px);
+  }
+}
+
+ at keyframes fadeOutRight {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(20px);
+    -ms-transform: translateX(20px);
+    transform: translateX(20px);
+  }
+}
+
+.fadeOutRight {
+  -webkit-animation-name: fadeOutRight;
+  animation-name: fadeOutRight;
+}
+
+ at -webkit-keyframes fadeOutRightBig {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(2000px);
+    transform: translateX(2000px);
+  }
+}
+
+ at keyframes fadeOutRightBig {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(2000px);
+    -ms-transform: translateX(2000px);
+    transform: translateX(2000px);
+  }
+}
+
+.fadeOutRightBig {
+  -webkit-animation-name: fadeOutRightBig;
+  animation-name: fadeOutRightBig;
+}
+
+ at -webkit-keyframes fadeOutUp {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(-20px);
+    transform: translateY(-20px);
+  }
+}
+
+ at keyframes fadeOutUp {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(-20px);
+    -ms-transform: translateY(-20px);
+    transform: translateY(-20px);
+  }
+}
+
+.fadeOutUp {
+  -webkit-animation-name: fadeOutUp;
+  animation-name: fadeOutUp;
+}
+
+ at -webkit-keyframes fadeOutUpBig {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(-2000px);
+    transform: translateY(-2000px);
+  }
+}
+
+ at keyframes fadeOutUpBig {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(-2000px);
+    -ms-transform: translateY(-2000px);
+    transform: translateY(-2000px);
+  }
+}
+
+.fadeOutUpBig {
+  -webkit-animation-name: fadeOutUpBig;
+  animation-name: fadeOutUpBig;
+}
+
+ at -webkit-keyframes flip {
+  0% {
+    -webkit-transform: perspective(400px) translateZ(0) rotateY(0) scale(1);
+    transform: perspective(400px) translateZ(0) rotateY(0) scale(1);
+    -webkit-animation-timing-function: ease-out;
+    animation-timing-function: ease-out;
+  }
+
+  40% {
+    -webkit-transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1);
+    transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1);
+    -webkit-animation-timing-function: ease-out;
+    animation-timing-function: ease-out;
+  }
+
+  50% {
+    -webkit-transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1);
+    transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+
+  80% {
+    -webkit-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95);
+    transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+
+  100% {
+    -webkit-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1);
+    transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+}
+
+ at keyframes flip {
+  0% {
+    -webkit-transform: perspective(400px) translateZ(0) rotateY(0) scale(1);
+    -ms-transform: perspective(400px) translateZ(0) rotateY(0) scale(1);
+    transform: perspective(400px) translateZ(0) rotateY(0) scale(1);
+    -webkit-animation-timing-function: ease-out;
+    animation-timing-function: ease-out;
+  }
+
+  40% {
+    -webkit-transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1);
+    -ms-transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1);
+    transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1);
+    -webkit-animation-timing-function: ease-out;
+    animation-timing-function: ease-out;
+  }
+
+  50% {
+    -webkit-transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1);
+    -ms-transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1);
+    transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+
+  80% {
+    -webkit-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95);
+    -ms-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95);
+    transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+
+  100% {
+    -webkit-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1);
+    -ms-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1);
+    transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1);
+    -webkit-animation-timing-function: ease-in;
+    animation-timing-function: ease-in;
+  }
+}
+
+.animated.flip {
+  -webkit-backface-visibility: visible;
+  -ms-backface-visibility: visible;
+  backface-visibility: visible;
+  -webkit-animation-name: flip;
+  animation-name: flip;
+}
+
+ at -webkit-keyframes flipInX {
+  0% {
+    -webkit-transform: perspective(400px) rotateX(90deg);
+    transform: perspective(400px) rotateX(90deg);
+    opacity: 0;
+  }
+
+  40% {
+    -webkit-transform: perspective(400px) rotateX(-10deg);
+    transform: perspective(400px) rotateX(-10deg);
+  }
+
+  70% {
+    -webkit-transform: perspective(400px) rotateX(10deg);
+    transform: perspective(400px) rotateX(10deg);
+  }
+
+  100% {
+    -webkit-transform: perspective(400px) rotateX(0deg);
+    transform: perspective(400px) rotateX(0deg);
+    opacity: 1;
+  }
+}
+
+ at keyframes flipInX {
+  0% {
+    -webkit-transform: perspective(400px) rotateX(90deg);
+    -ms-transform: perspective(400px) rotateX(90deg);
+    transform: perspective(400px) rotateX(90deg);
+    opacity: 0;
+  }
+
+  40% {
+    -webkit-transform: perspective(400px) rotateX(-10deg);
+    -ms-transform: perspective(400px) rotateX(-10deg);
+    transform: perspective(400px) rotateX(-10deg);
+  }
+
+  70% {
+    -webkit-transform: perspective(400px) rotateX(10deg);
+    -ms-transform: perspective(400px) rotateX(10deg);
+    transform: perspective(400px) rotateX(10deg);
+  }
+
+  100% {
+    -webkit-transform: perspective(400px) rotateX(0deg);
+    -ms-transform: perspective(400px) rotateX(0deg);
+    transform: perspective(400px) rotateX(0deg);
+    opacity: 1;
+  }
+}
+
+.flipInX {
+  -webkit-backface-visibility: visible !important;
+  -ms-backface-visibility: visible !important;
+  backface-visibility: visible !important;
+  -webkit-animation-name: flipInX;
+  animation-name: flipInX;
+}
+
+ at -webkit-keyframes flipInY {
+  0% {
+    -webkit-transform: perspective(400px) rotateY(90deg);
+    transform: perspective(400px) rotateY(90deg);
+    opacity: 0;
+  }
+
+  40% {
+    -webkit-transform: perspective(400px) rotateY(-10deg);
+    transform: perspective(400px) rotateY(-10deg);
+  }
+
+  70% {
+    -webkit-transform: perspective(400px) rotateY(10deg);
+    transform: perspective(400px) rotateY(10deg);
+  }
+
+  100% {
+    -webkit-transform: perspective(400px) rotateY(0deg);
+    transform: perspective(400px) rotateY(0deg);
+    opacity: 1;
+  }
+}
+
+ at keyframes flipInY {
+  0% {
+    -webkit-transform: perspective(400px) rotateY(90deg);
+    -ms-transform: perspective(400px) rotateY(90deg);
+    transform: perspective(400px) rotateY(90deg);
+    opacity: 0;
+  }
+
+  40% {
+    -webkit-transform: perspective(400px) rotateY(-10deg);
+    -ms-transform: perspective(400px) rotateY(-10deg);
+    transform: perspective(400px) rotateY(-10deg);
+  }
+
+  70% {
+    -webkit-transform: perspective(400px) rotateY(10deg);
+    -ms-transform: perspective(400px) rotateY(10deg);
+    transform: perspective(400px) rotateY(10deg);
+  }
+
+  100% {
+    -webkit-transform: perspective(400px) rotateY(0deg);
+    -ms-transform: perspective(400px) rotateY(0deg);
+    transform: perspective(400px) rotateY(0deg);
+    opacity: 1;
+  }
+}
+
+.flipInY {
+  -webkit-backface-visibility: visible !important;
+  -ms-backface-visibility: visible !important;
+  backface-visibility: visible !important;
+  -webkit-animation-name: flipInY;
+  animation-name: flipInY;
+}
+
+ at -webkit-keyframes flipOutX {
+  0% {
+    -webkit-transform: perspective(400px) rotateX(0deg);
+    transform: perspective(400px) rotateX(0deg);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform: perspective(400px) rotateX(90deg);
+    transform: perspective(400px) rotateX(90deg);
+    opacity: 0;
+  }
+}
+
+ at keyframes flipOutX {
+  0% {
+    -webkit-transform: perspective(400px) rotateX(0deg);
+    -ms-transform: perspective(400px) rotateX(0deg);
+    transform: perspective(400px) rotateX(0deg);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform: perspective(400px) rotateX(90deg);
+    -ms-transform: perspective(400px) rotateX(90deg);
+    transform: perspective(400px) rotateX(90deg);
+    opacity: 0;
+  }
+}
+
+.flipOutX {
+  -webkit-animation-name: flipOutX;
+  animation-name: flipOutX;
+  -webkit-backface-visibility: visible !important;
+  -ms-backface-visibility: visible !important;
+  backface-visibility: visible !important;
+}
+
+ at -webkit-keyframes flipOutY {
+  0% {
+    -webkit-transform: perspective(400px) rotateY(0deg);
+    transform: perspective(400px) rotateY(0deg);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform: perspective(400px) rotateY(90deg);
+    transform: perspective(400px) rotateY(90deg);
+    opacity: 0;
+  }
+}
+
+ at keyframes flipOutY {
+  0% {
+    -webkit-transform: perspective(400px) rotateY(0deg);
+    -ms-transform: perspective(400px) rotateY(0deg);
+    transform: perspective(400px) rotateY(0deg);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform: perspective(400px) rotateY(90deg);
+    -ms-transform: perspective(400px) rotateY(90deg);
+    transform: perspective(400px) rotateY(90deg);
+    opacity: 0;
+  }
+}
+
+.flipOutY {
+  -webkit-backface-visibility: visible !important;
+  -ms-backface-visibility: visible !important;
+  backface-visibility: visible !important;
+  -webkit-animation-name: flipOutY;
+  animation-name: flipOutY;
+}
+
+ at -webkit-keyframes lightSpeedIn {
+  0% {
+    -webkit-transform: translateX(100%) skewX(-30deg);
+    transform: translateX(100%) skewX(-30deg);
+    opacity: 0;
+  }
+
+  60% {
+    -webkit-transform: translateX(-20%) skewX(30deg);
+    transform: translateX(-20%) skewX(30deg);
+    opacity: 1;
+  }
+
+  80% {
+    -webkit-transform: translateX(0%) skewX(-15deg);
+    transform: translateX(0%) skewX(-15deg);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform: translateX(0%) skewX(0deg);
+    transform: translateX(0%) skewX(0deg);
+    opacity: 1;
+  }
+}
+
+ at keyframes lightSpeedIn {
+  0% {
+    -webkit-transform: translateX(100%) skewX(-30deg);
+    -ms-transform: translateX(100%) skewX(-30deg);
+    transform: translateX(100%) skewX(-30deg);
+    opacity: 0;
+  }
+
+  60% {
+    -webkit-transform: translateX(-20%) skewX(30deg);
+    -ms-transform: translateX(-20%) skewX(30deg);
+    transform: translateX(-20%) skewX(30deg);
+    opacity: 1;
+  }
+
+  80% {
+    -webkit-transform: translateX(0%) skewX(-15deg);
+    -ms-transform: translateX(0%) skewX(-15deg);
+    transform: translateX(0%) skewX(-15deg);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform: translateX(0%) skewX(0deg);
+    -ms-transform: translateX(0%) skewX(0deg);
+    transform: translateX(0%) skewX(0deg);
+    opacity: 1;
+  }
+}
+
+.lightSpeedIn {
+  -webkit-animation-name: lightSpeedIn;
+  animation-name: lightSpeedIn;
+  -webkit-animation-timing-function: ease-out;
+  animation-timing-function: ease-out;
+}
+
+ at -webkit-keyframes lightSpeedOut {
+  0% {
+    -webkit-transform: translateX(0%) skewX(0deg);
+    transform: translateX(0%) skewX(0deg);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform: translateX(100%) skewX(-30deg);
+    transform: translateX(100%) skewX(-30deg);
+    opacity: 0;
+  }
+}
+
+ at keyframes lightSpeedOut {
+  0% {
+    -webkit-transform: translateX(0%) skewX(0deg);
+    -ms-transform: translateX(0%) skewX(0deg);
+    transform: translateX(0%) skewX(0deg);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform: translateX(100%) skewX(-30deg);
+    -ms-transform: translateX(100%) skewX(-30deg);
+    transform: translateX(100%) skewX(-30deg);
+    opacity: 0;
+  }
+}
+
+.lightSpeedOut {
+  -webkit-animation-name: lightSpeedOut;
+  animation-name: lightSpeedOut;
+  -webkit-animation-timing-function: ease-in;
+  animation-timing-function: ease-in;
+}
+
+ at -webkit-keyframes rotateIn {
+  0% {
+    -webkit-transform-origin: center center;
+    transform-origin: center center;
+    -webkit-transform: rotate(-200deg);
+    transform: rotate(-200deg);
+    opacity: 0;
+  }
+
+  100% {
+    -webkit-transform-origin: center center;
+    transform-origin: center center;
+    -webkit-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+}
+
+ at keyframes rotateIn {
+  0% {
+    -webkit-transform-origin: center center;
+    -ms-transform-origin: center center;
+    transform-origin: center center;
+    -webkit-transform: rotate(-200deg);
+    -ms-transform: rotate(-200deg);
+    transform: rotate(-200deg);
+    opacity: 0;
+  }
+
+  100% {
+    -webkit-transform-origin: center center;
+    -ms-transform-origin: center center;
+    transform-origin: center center;
+    -webkit-transform: rotate(0);
+    -ms-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+}
+
+.rotateIn {
+  -webkit-animation-name: rotateIn;
+  animation-name: rotateIn;
+}
+
+ at -webkit-keyframes rotateInDownLeft {
+  0% {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(-90deg);
+    transform: rotate(-90deg);
+    opacity: 0;
+  }
+
+  100% {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+}
+
+ at keyframes rotateInDownLeft {
+  0% {
+    -webkit-transform-origin: left bottom;
+    -ms-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(-90deg);
+    -ms-transform: rotate(-90deg);
+    transform: rotate(-90deg);
+    opacity: 0;
+  }
+
+  100% {
+    -webkit-transform-origin: left bottom;
+    -ms-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(0);
+    -ms-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+}
+
+.rotateInDownLeft {
+  -webkit-animation-name: rotateInDownLeft;
+  animation-name: rotateInDownLeft;
+}
+
+ at -webkit-keyframes rotateInDownRight {
+  0% {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(90deg);
+    transform: rotate(90deg);
+    opacity: 0;
+  }
+
+  100% {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+}
+
+ at keyframes rotateInDownRight {
+  0% {
+    -webkit-transform-origin: right bottom;
+    -ms-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(90deg);
+    -ms-transform: rotate(90deg);
+    transform: rotate(90deg);
+    opacity: 0;
+  }
+
+  100% {
+    -webkit-transform-origin: right bottom;
+    -ms-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(0);
+    -ms-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+}
+
+.rotateInDownRight {
+  -webkit-animation-name: rotateInDownRight;
+  animation-name: rotateInDownRight;
+}
+
+ at -webkit-keyframes rotateInUpLeft {
+  0% {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(90deg);
+    transform: rotate(90deg);
+    opacity: 0;
+  }
+
+  100% {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+}
+
+ at keyframes rotateInUpLeft {
+  0% {
+    -webkit-transform-origin: left bottom;
+    -ms-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(90deg);
+    -ms-transform: rotate(90deg);
+    transform: rotate(90deg);
+    opacity: 0;
+  }
+
+  100% {
+    -webkit-transform-origin: left bottom;
+    -ms-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(0);
+    -ms-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+}
+
+.rotateInUpLeft {
+  -webkit-animation-name: rotateInUpLeft;
+  animation-name: rotateInUpLeft;
+}
+
+ at -webkit-keyframes rotateInUpRight {
+  0% {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(-90deg);
+    transform: rotate(-90deg);
+    opacity: 0;
+  }
+
+  100% {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+}
+
+ at keyframes rotateInUpRight {
+  0% {
+    -webkit-transform-origin: right bottom;
+    -ms-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(-90deg);
+    -ms-transform: rotate(-90deg);
+    transform: rotate(-90deg);
+    opacity: 0;
+  }
+
+  100% {
+    -webkit-transform-origin: right bottom;
+    -ms-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(0);
+    -ms-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+}
+
+.rotateInUpRight {
+  -webkit-animation-name: rotateInUpRight;
+  animation-name: rotateInUpRight;
+}
+
+ at -webkit-keyframes rotateOut {
+  0% {
+    -webkit-transform-origin: center center;
+    transform-origin: center center;
+    -webkit-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform-origin: center center;
+    transform-origin: center center;
+    -webkit-transform: rotate(200deg);
+    transform: rotate(200deg);
+    opacity: 0;
+  }
+}
+
+ at keyframes rotateOut {
+  0% {
+    -webkit-transform-origin: center center;
+    -ms-transform-origin: center center;
+    transform-origin: center center;
+    -webkit-transform: rotate(0);
+    -ms-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform-origin: center center;
+    -ms-transform-origin: center center;
+    transform-origin: center center;
+    -webkit-transform: rotate(200deg);
+    -ms-transform: rotate(200deg);
+    transform: rotate(200deg);
+    opacity: 0;
+  }
+}
+
+.rotateOut {
+  -webkit-animation-name: rotateOut;
+  animation-name: rotateOut;
+}
+
+ at -webkit-keyframes rotateOutDownLeft {
+  0% {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(90deg);
+    transform: rotate(90deg);
+    opacity: 0;
+  }
+}
+
+ at keyframes rotateOutDownLeft {
+  0% {
+    -webkit-transform-origin: left bottom;
+    -ms-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(0);
+    -ms-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform-origin: left bottom;
+    -ms-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(90deg);
+    -ms-transform: rotate(90deg);
+    transform: rotate(90deg);
+    opacity: 0;
+  }
+}
+
+.rotateOutDownLeft {
+  -webkit-animation-name: rotateOutDownLeft;
+  animation-name: rotateOutDownLeft;
+}
+
+ at -webkit-keyframes rotateOutDownRight {
+  0% {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(-90deg);
+    transform: rotate(-90deg);
+    opacity: 0;
+  }
+}
+
+ at keyframes rotateOutDownRight {
+  0% {
+    -webkit-transform-origin: right bottom;
+    -ms-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(0);
+    -ms-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform-origin: right bottom;
+    -ms-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(-90deg);
+    -ms-transform: rotate(-90deg);
+    transform: rotate(-90deg);
+    opacity: 0;
+  }
+}
+
+.rotateOutDownRight {
+  -webkit-animation-name: rotateOutDownRight;
+  animation-name: rotateOutDownRight;
+}
+
+ at -webkit-keyframes rotateOutUpLeft {
+  0% {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(-90deg);
+    transform: rotate(-90deg);
+    opacity: 0;
+  }
+}
+
+ at keyframes rotateOutUpLeft {
+  0% {
+    -webkit-transform-origin: left bottom;
+    -ms-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(0);
+    -ms-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform-origin: left bottom;
+    -ms-transform-origin: left bottom;
+    transform-origin: left bottom;
+    -webkit-transform: rotate(-90deg);
+    -ms-transform: rotate(-90deg);
+    transform: rotate(-90deg);
+    opacity: 0;
+  }
+}
+
+.rotateOutUpLeft {
+  -webkit-animation-name: rotateOutUpLeft;
+  animation-name: rotateOutUpLeft;
+}
+
+ at -webkit-keyframes rotateOutUpRight {
+  0% {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(90deg);
+    transform: rotate(90deg);
+    opacity: 0;
+  }
+}
+
+ at keyframes rotateOutUpRight {
+  0% {
+    -webkit-transform-origin: right bottom;
+    -ms-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(0);
+    -ms-transform: rotate(0);
+    transform: rotate(0);
+    opacity: 1;
+  }
+
+  100% {
+    -webkit-transform-origin: right bottom;
+    -ms-transform-origin: right bottom;
+    transform-origin: right bottom;
+    -webkit-transform: rotate(90deg);
+    -ms-transform: rotate(90deg);
+    transform: rotate(90deg);
+    opacity: 0;
+  }
+}
+
+.rotateOutUpRight {
+  -webkit-animation-name: rotateOutUpRight;
+  animation-name: rotateOutUpRight;
+}
+
+ at -webkit-keyframes slideInDown {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(-2000px);
+    transform: translateY(-2000px);
+  }
+
+  100% {
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+  }
+}
+
+ at keyframes slideInDown {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateY(-2000px);
+    -ms-transform: translateY(-2000px);
+    transform: translateY(-2000px);
+  }
+
+  100% {
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0);
+  }
+}
+
+.slideInDown {
+  -webkit-animation-name: slideInDown;
+  animation-name: slideInDown;
+}
+
+ at -webkit-keyframes slideInLeft {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(-2000px);
+    transform: translateX(-2000px);
+  }
+
+  100% {
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+ at keyframes slideInLeft {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(-2000px);
+    -ms-transform: translateX(-2000px);
+    transform: translateX(-2000px);
+  }
+
+  100% {
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+.slideInLeft {
+  -webkit-animation-name: slideInLeft;
+  animation-name: slideInLeft;
+}
+
+ at -webkit-keyframes slideInRight {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(2000px);
+    transform: translateX(2000px);
+  }
+
+  100% {
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+ at keyframes slideInRight {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(2000px);
+    -ms-transform: translateX(2000px);
+    transform: translateX(2000px);
+  }
+
+  100% {
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+}
+
+.slideInRight {
+  -webkit-animation-name: slideInRight;
+  animation-name: slideInRight;
+}
+
+ at -webkit-keyframes slideOutLeft {
+  0% {
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(-2000px);
+    transform: translateX(-2000px);
+  }
+}
+
+ at keyframes slideOutLeft {
+  0% {
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(-2000px);
+    -ms-transform: translateX(-2000px);
+    transform: translateX(-2000px);
+  }
+}
+
+.slideOutLeft {
+  -webkit-animation-name: slideOutLeft;
+  animation-name: slideOutLeft;
+}
+
+ at -webkit-keyframes slideOutRight {
+  0% {
+    -webkit-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(2000px);
+    transform: translateX(2000px);
+  }
+}
+
+ at keyframes slideOutRight {
+  0% {
+    -webkit-transform: translateX(0);
+    -ms-transform: translateX(0);
+    transform: translateX(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(2000px);
+    -ms-transform: translateX(2000px);
+    transform: translateX(2000px);
+  }
+}
+
+.slideOutRight {
+  -webkit-animation-name: slideOutRight;
+  animation-name: slideOutRight;
+}
+
+ at -webkit-keyframes slideOutUp {
+  0% {
+    -webkit-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(-2000px);
+    transform: translateY(-2000px);
+  }
+}
+
+ at keyframes slideOutUp {
+  0% {
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateY(-2000px);
+    -ms-transform: translateY(-2000px);
+    transform: translateY(-2000px);
+  }
+}
+
+.slideOutUp {
+  -webkit-animation-name: slideOutUp;
+  animation-name: slideOutUp;
+}
+
+ at -webkit-keyframes hinge {
+  0% {
+    -webkit-transform: rotate(0);
+    transform: rotate(0);
+    -webkit-transform-origin: top left;
+    transform-origin: top left;
+    -webkit-animation-timing-function: ease-in-out;
+    animation-timing-function: ease-in-out;
+  }
+
+  20%, 60% {
+    -webkit-transform: rotate(80deg);
+    transform: rotate(80deg);
+    -webkit-transform-origin: top left;
+    transform-origin: top left;
+    -webkit-animation-timing-function: ease-in-out;
+    animation-timing-function: ease-in-out;
+  }
+
+  40% {
+    -webkit-transform: rotate(60deg);
+    transform: rotate(60deg);
+    -webkit-transform-origin: top left;
+    transform-origin: top left;
+    -webkit-animation-timing-function: ease-in-out;
+    animation-timing-function: ease-in-out;
+  }
+
+  80% {
+    -webkit-transform: rotate(60deg) translateY(0);
+    transform: rotate(60deg) translateY(0);
+    opacity: 1;
+    -webkit-transform-origin: top left;
+    transform-origin: top left;
+    -webkit-animation-timing-function: ease-in-out;
+    animation-timing-function: ease-in-out;
+  }
+
+  100% {
+    -webkit-transform: translateY(700px);
+    transform: translateY(700px);
+    opacity: 0;
+  }
+}
+
+ at keyframes hinge {
+  0% {
+    -webkit-transform: rotate(0);
+    -ms-transform: rotate(0);
+    transform: rotate(0);
+    -webkit-transform-origin: top left;
+    -ms-transform-origin: top left;
+    transform-origin: top left;
+    -webkit-animation-timing-function: ease-in-out;
+    animation-timing-function: ease-in-out;
+  }
+
+  20%, 60% {
+    -webkit-transform: rotate(80deg);
+    -ms-transform: rotate(80deg);
+    transform: rotate(80deg);
+    -webkit-transform-origin: top left;
+    -ms-transform-origin: top left;
+    transform-origin: top left;
+    -webkit-animation-timing-function: ease-in-out;
+    animation-timing-function: ease-in-out;
+  }
+
+  40% {
+    -webkit-transform: rotate(60deg);
+    -ms-transform: rotate(60deg);
+    transform: rotate(60deg);
+    -webkit-transform-origin: top left;
+    -ms-transform-origin: top left;
+    transform-origin: top left;
+    -webkit-animation-timing-function: ease-in-out;
+    animation-timing-function: ease-in-out;
+  }
+
+  80% {
+    -webkit-transform: rotate(60deg) translateY(0);
+    -ms-transform: rotate(60deg) translateY(0);
+    transform: rotate(60deg) translateY(0);
+    opacity: 1;
+    -webkit-transform-origin: top left;
+    -ms-transform-origin: top left;
+    transform-origin: top left;
+    -webkit-animation-timing-function: ease-in-out;
+    animation-timing-function: ease-in-out;
+  }
+
+  100% {
+    -webkit-transform: translateY(700px);
+    -ms-transform: translateY(700px);
+    transform: translateY(700px);
+    opacity: 0;
+  }
+}
+
+.hinge {
+  -webkit-animation-name: hinge;
+  animation-name: hinge;
+}
+
+/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
+
+ at -webkit-keyframes rollIn {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(-100%) rotate(-120deg);
+    transform: translateX(-100%) rotate(-120deg);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateX(0px) rotate(0deg);
+    transform: translateX(0px) rotate(0deg);
+  }
+}
+
+ at keyframes rollIn {
+  0% {
+    opacity: 0;
+    -webkit-transform: translateX(-100%) rotate(-120deg);
+    -ms-transform: translateX(-100%) rotate(-120deg);
+    transform: translateX(-100%) rotate(-120deg);
+  }
+
+  100% {
+    opacity: 1;
+    -webkit-transform: translateX(0px) rotate(0deg);
+    -ms-transform: translateX(0px) rotate(0deg);
+    transform: translateX(0px) rotate(0deg);
+  }
+}
+
+.rollIn {
+  -webkit-animation-name: rollIn;
+  animation-name: rollIn;
+}
+
+/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
+
+ at -webkit-keyframes rollOut {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateX(0px) rotate(0deg);
+    transform: translateX(0px) rotate(0deg);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(100%) rotate(120deg);
+    transform: translateX(100%) rotate(120deg);
+  }
+}
+
+ at keyframes rollOut {
+  0% {
+    opacity: 1;
+    -webkit-transform: translateX(0px) rotate(0deg);
+    -ms-transform: translateX(0px) rotate(0deg);
+    transform: translateX(0px) rotate(0deg);
+  }
+
+  100% {
+    opacity: 0;
+    -webkit-transform: translateX(100%) rotate(120deg);
+    -ms-transform: translateX(100%) rotate(120deg);
+    transform: translateX(100%) rotate(120deg);
+  }
+}
+
+.rollOut {
+  -webkit-animation-name: rollOut;
+  animation-name: rollOut;
+}
\ No newline at end of file
diff --git a/app/gui/html/vendor/bootstrap/css/bootstrap-theme.css b/app/gui/html/vendor/bootstrap/css/bootstrap-theme.css
new file mode 100644
index 0000000..11fcc9b
--- /dev/null
+++ b/app/gui/html/vendor/bootstrap/css/bootstrap-theme.css
@@ -0,0 +1,347 @@
+/*!
+ * Bootstrap v3.1.0 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+.btn-default,
+.btn-primary,
+.btn-success,
+.btn-info,
+.btn-warning,
+.btn-danger {
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
+          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
+}
+.btn-default:active,
+.btn-primary:active,
+.btn-success:active,
+.btn-info:active,
+.btn-warning:active,
+.btn-danger:active,
+.btn-default.active,
+.btn-primary.active,
+.btn-success.active,
+.btn-info.active,
+.btn-warning.active,
+.btn-danger.active {
+  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+.btn:active,
+.btn.active {
+  background-image: none;
+}
+.btn-default {
+  text-shadow: 0 1px 0 #fff;
+  background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
+  background-image:         linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #dbdbdb;
+  border-color: #ccc;
+}
+.btn-default:hover,
+.btn-default:focus {
+  background-color: #e0e0e0;
+  background-position: 0 -15px;
+}
+.btn-default:active,
+.btn-default.active {
+  background-color: #e0e0e0;
+  border-color: #dbdbdb;
+}
+.btn-primary {
+  background-image: -webkit-linear-gradient(top, #428bca 0%, #2d6ca2 100%);
+  background-image:         linear-gradient(to bottom, #428bca 0%, #2d6ca2 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #2b669a;
+}
+.btn-primary:hover,
+.btn-primary:focus {
+  background-color: #2d6ca2;
+  background-position: 0 -15px;
+}
+.btn-primary:active,
+.btn-primary.active {
+  background-color: #2d6ca2;
+  border-color: #2b669a;
+}
+.btn-success {
+  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
+  background-image:         linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #3e8f3e;
+}
+.btn-success:hover,
+.btn-success:focus {
+  background-color: #419641;
+  background-position: 0 -15px;
+}
+.btn-success:active,
+.btn-success.active {
+  background-color: #419641;
+  border-color: #3e8f3e;
+}
+.btn-info {
+  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
+  background-image:         linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #28a4c9;
+}
+.btn-info:hover,
+.btn-info:focus {
+  background-color: #2aabd2;
+  background-position: 0 -15px;
+}
+.btn-info:active,
+.btn-info.active {
+  background-color: #2aabd2;
+  border-color: #28a4c9;
+}
+.btn-warning {
+  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
+  background-image:         linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #e38d13;
+}
+.btn-warning:hover,
+.btn-warning:focus {
+  background-color: #eb9316;
+  background-position: 0 -15px;
+}
+.btn-warning:active,
+.btn-warning.active {
+  background-color: #eb9316;
+  border-color: #e38d13;
+}
+.btn-danger {
+  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
+  background-image:         linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #b92c28;
+}
+.btn-danger:hover,
+.btn-danger:focus {
+  background-color: #c12e2a;
+  background-position: 0 -15px;
+}
+.btn-danger:active,
+.btn-danger.active {
+  background-color: #c12e2a;
+  border-color: #b92c28;
+}
+.thumbnail,
+.img-thumbnail {
+  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
+          box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
+}
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+  background-color: #e8e8e8;
+  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
+  background-image:         linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
+  background-repeat: repeat-x;
+}
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+  background-color: #357ebd;
+  background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);
+  background-image:         linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
+  background-repeat: repeat-x;
+}
+.navbar-default {
+  background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
+  background-image:         linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
+          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
+}
+.navbar-default .navbar-nav > .active > a {
+  background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%);
+  background-image:         linear-gradient(to bottom, #ebebeb 0%, #f3f3f3 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);
+  background-repeat: repeat-x;
+  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
+          box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
+}
+.navbar-brand,
+.navbar-nav > li > a {
+  text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
+}
+.navbar-inverse {
+  background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
+  background-image:         linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+}
+.navbar-inverse .navbar-nav > .active > a {
+  background-image: -webkit-linear-gradient(top, #222 0%, #282828 100%);
+  background-image:         linear-gradient(to bottom, #222 0%, #282828 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);
+  background-repeat: repeat-x;
+  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
+          box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
+}
+.navbar-inverse .navbar-brand,
+.navbar-inverse .navbar-nav > li > a {
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
+}
+.navbar-static-top,
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+  border-radius: 0;
+}
+.alert {
+  text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
+          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
+}
+.alert-success {
+  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
+  background-image:         linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #b2dba1;
+}
+.alert-info {
+  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
+  background-image:         linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #9acfea;
+}
+.alert-warning {
+  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
+  background-image:         linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #f5e79e;
+}
+.alert-danger {
+  background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
+  background-image:         linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #dca7a7;
+}
+.progress {
+  background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
+  background-image:         linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar {
+  background-image: -webkit-linear-gradient(top, #428bca 0%, #3071a9 100%);
+  background-image:         linear-gradient(to bottom, #428bca 0%, #3071a9 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar-success {
+  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
+  background-image:         linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar-info {
+  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
+  background-image:         linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar-warning {
+  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
+  background-image:         linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar-danger {
+  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
+  background-image:         linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
+  background-repeat: repeat-x;
+}
+.list-group {
+  border-radius: 4px;
+  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
+          box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
+}
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+  text-shadow: 0 -1px 0 #3071a9;
+  background-image: -webkit-linear-gradient(top, #428bca 0%, #3278b3 100%);
+  background-image:         linear-gradient(to bottom, #428bca 0%, #3278b3 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #3278b3;
+}
+.panel {
+  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
+          box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
+}
+.panel-default > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
+  background-image:         linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
+  background-repeat: repeat-x;
+}
+.panel-primary > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);
+  background-image:         linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
+  background-repeat: repeat-x;
+}
+.panel-success > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
+  background-image:         linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
+  background-repeat: repeat-x;
+}
+.panel-info > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
+  background-image:         linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
+  background-repeat: repeat-x;
+}
+.panel-warning > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
+  background-image:         linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
+  background-repeat: repeat-x;
+}
+.panel-danger > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
+  background-image:         linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
+  background-repeat: repeat-x;
+}
+.well {
+  background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
+  background-image:         linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #dcdcdc;
+  -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
+          box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
+}
+/*# sourceMappingURL=bootstrap-theme.css.map */
diff --git a/app/gui/html/vendor/bootstrap/css/bootstrap-theme.css.map b/app/gui/html/vendor/bootstrap/css/bootstrap-theme.css.map
new file mode 100644
index 0000000..29c1319
--- /dev/null
+++ b/app/gui/html/vendor/bootstrap/css/bootstrap-theme.css.map
@@ -0,0 +1 @@
+{"version":3,"sources":["less/theme.less","less/mixins.less"],"names":[],"mappings":"AAeA;AACA;AACA;AACA;AACA;AACA;EACE,wCAAA;ECqGA,2FAAA;EACQ,mFAAA;;ADjGR,YAAC;AAAD,YAAC;AAAD,YAAC;AAAD,SAAC;AAAD,YAAC;AAAD,WAAC;AACD,YAAC;AAAD,YAAC;AAAD,YAAC;AAAD,SAAC;AAAD,YAAC;AAAD,WAAC;EC+FD,wDAAA;EACQ,gDAAA;;ADpER,IAAC;AACD,IAAC;EACC,sBAAA;;AAKJ;EC8PI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EAEA,sHAAA;EAoCF,mEAAA;ED/TA,2BAAA;EACA,qBAAA;EAyB2C,yBAAA;EAA2B,kBAAA;;AAvBtE,YAAC;AACD,YAAC;EACC,yBAAA;EACA,4BAAA;;AAGF,YAAC;AACD,YAAC;EACC,yBAAA;EACA,qBAAA;;AAeJ;EC6PI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EAEA,sHAAA;EAoCF,mEAAA;ED/TA,2BAAA;EACA,qBAAA;;AAEA,YAAC;AACD,YAAC;EACC,yBAAA;EACA,4BAAA;;AAGF,YAAC;AACD,YAAC;EACC,yBAAA;EACA,qBAAA;;AAgBJ;EC4PI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EAEA,sHAAA;EAoCF,mEAAA;ED/TA,2BAAA;EACA,qBAAA;;AAEA,YAAC;AACD,YAAC;EACC,yBAAA;EACA,4BAAA;;AAGF,YAAC;AACD,YAAC;EACC,yBAAA;EACA,qBAAA;;AAiBJ;EC2PI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EAEA,sHAAA;EAoCF,mEAAA;ED/TA,2BAAA;EACA,qBAAA;;AAEA,SAAC;AACD,SAAC;EACC,yBAAA;EACA,4BAAA;;AAGF,SAAC;AACD,SAAC;EACC,yBAAA;EACA,qBAAA;;AAkBJ;EC0PI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EAEA,sHAAA;EAoCF,mEAAA;ED/TA,2BAAA;EACA,qBAAA;;AAEA,YAAC;AACD,YAAC;EACC,yBAAA;EACA,4BAAA;;AAGF,YAAC;AACD,YAAC;EACC,yBAAA;EACA,qBAAA;;AAmBJ;ECyPI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EAEA,sHAAA;EAoCF,mEAAA;ED/TA,2BAAA;EACA,qBAAA;;AAEA,WAAC;AACD,WAAC;EACC,yBAAA;EACA,4BAAA;;AAGF,WAAC;AACD,WAAC;EACC,yBAAA;EACA,qBAAA;;AA2BJ;AACA;EC8CE,kDAAA;EACQ,0CAAA;;ADrCV,cAAe,KAAK,IAAG;AACvB,cAAe,KAAK,IAAG;ECqOnB,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;EDtOF,yBAAA;;AAEF,cAAe,UAAU;AACzB,cAAe,UAAU,IAAG;AAC5B,cAAe,UAAU,IAAG;EC+NxB,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;EDhOF,yBAAA;;AAUF;ECmNI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;EAoCF,mEAAA;EDvPA,kBAAA;ECcA,2FAAA;EACQ,mFAAA;;ADlBV,eAOE,YAAY,UAAU;EC4MpB,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;EArMF,wDAAA;EACQ,gDAAA;;ADNV;AACA,WAAY,KAAK;EACf,8CAAA;;AAIF;ECiMI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;EAoCF,mEAAA;;ADxOF,eAIE,YAAY,UAAU;EC6LpB,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;EArMF,uDAAA;EACQ,+CAAA;;ADAV,eASE;AATF,eAUE,YAAY,KAAK;EACf,yCAAA;;AAKJ;AACA;AACA;EACE,gBAAA;;AAUF;EACE,6CAAA;EC/BA,0FAAA;EACQ,kFAAA;;AD0CV;ECuJI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;ED9JF,qBAAA;;AAKF;ECsJI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;ED9JF,qBAAA;;AAMF;ECqJI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;ED9JF,qBAAA;;AAOF;ECoJI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;ED9JF,qBAAA;;AAgBF;EC2II,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADpIJ;ECiII,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADnIJ;ECgII,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADlIJ;EC+HI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADjIJ;EC8HI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADhIJ;EC6HI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADxHJ;EACE,kBAAA;EC9EA,kDAAA;EACQ,0CAAA;;ADgFV,gBAAgB;AAChB,gBAAgB,OAAO;AACvB,gBAAgB,OAAO;EACrB,6BAAA;EC8GE,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;ED/GF,qBAAA;;AAUF;EChGE,iDAAA;EACQ,yCAAA;;ADyGV,cAAe;ECwFX,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;AD1FJ,cAAe;ECuFX,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADzFJ,cAAe;ECsFX,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADxFJ,WAAY;ECqFR,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADvFJ,cAAe;ECoFX,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADtFJ,aAAc;ECmFV,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;AD9EJ;EC2EI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;ED5EF,qBAAA;ECzHA,yFAAA;EACQ,iFAAA","sourcesContent":["\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n at import \"variables.less\";\n at import \"mixins.less\";\n\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n  text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n  @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n  .box-shadow(@shadow);\n\n  // Reset the shadow\n  &:active,\n  &.active {\n    .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n  }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n  #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n  .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners\n  background-repeat: repeat-x;\n  border-color: darken(@btn-color, 14%);\n\n  &:hover,\n  &:focus  {\n    background-color: darken(@btn-color, 12%);\n    background-position: 0 -15px;\n  }\n\n  &:active,\n  &.active {\n    background-color: darken(@btn-color, 12%);\n    border-color: darken(@btn-color, 14%);\n  }\n}\n\n// Common styles\n.btn {\n  // Remove the gradient for the pressed/active state\n  &:active,\n  &.active {\n    background-image: none;\n  }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info    { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger  { .btn-styles(@btn-danger-bg); }\n\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n  .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n  background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n  background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n  #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n  .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n  border-radius: @navbar-border-radius;\n  @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n  .box-shadow(@shadow);\n\n  .navbar-nav > .active > a {\n    #gradient > .vertical(@start-color: darken(@navbar-default-bg, 5%); @end-color: darken(@navbar-default-bg, 2%));\n    .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n  }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n  text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n  #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n  .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n\n  .navbar-nav > .active > a {\n    #gradient > .vertical(@start-color: @navbar-inverse-bg; @end-color: lighten(@navbar-inverse-bg, 2.5%));\n    .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n  }\n\n  .navbar-brand,\n  .navbar-nav > li > a {\n    text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n  }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  border-radius: 0;\n}\n\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n  text-shadow: 0 1px 0 rgba(255,255,255,.2);\n  @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n  .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n  border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success    { .alert-styles(@alert-success-bg); }\n.alert-info       { .alert-styles(@alert-info-bg); }\n.alert-warning    { .alert-styles(@alert-warning-bg); }\n.alert-danger     { .alert-styles(@alert-danger-bg); }\n\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n  #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar            { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success    { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info       { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning    { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger     { .progress-bar-styles(@progress-bar-danger-bg); }\n\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n  border-radius: @border-radius-base;\n  .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n  #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n  border-color: darken(@list-group-active-border, 7.5%);\n}\n\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n  .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading   { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading   { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading   { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading      { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading   { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading    { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n  #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n  border-color: darken(@well-bg, 10%);\n  @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n  .box-shadow(@shadow);\n}\n","//\n// Mixins\n// --------------------------------------------------\n\n\n// Utilities\n// -------------------------\n\n// Clearfix\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n//    contenteditable attribute is included anywhere else in the document.\n//    Otherwise it causes space to appear at the top and bottom of elements\n//    that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n//    `:before` to contain the top-margins of child elements.\n.clearfix() {\n  &:before,\n  &:after {\n    content: \" \"; // 1\n    display: table; // 2\n  }\n  &:after {\n    clear: both;\n  }\n}\n\n// WebKit-style focus\n.tab-focus() {\n  // Default\n  outline: thin dotted;\n  // WebKit\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n\n// Center-align a block level element\n.center-block() {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n\n// Sizing shortcuts\n.size(@width; @height) {\n  width: @width;\n  height: @height;\n}\n.square(@size) {\n  .size(@size; @size);\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n  &:-moz-placeholder            { color: @color; } // Firefox 4-18\n  &::-moz-placeholder           { color: @color;   // Firefox 19+\n                                  opacity: 1; } // See https://github.com/twbs/bootstrap/pull/11526\n  &:-ms-input-placeholder       { color: @color; } // Internet Explorer 10+\n  &::-webkit-input-placeholder  { color: @color; } // Safari and Chrome\n}\n\n// Text overflow\n// Requires inline-block or block for proper styling\n.text-overflow() {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n// CSS image replacement\n//\n// Heads up! v3 launched with with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`. Note\n// that we cannot chain the mixins together in Less, so they are repeated.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (will be removed in v4)\n.hide-text() {\n  font: ~\"0/0\" a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n// New mixin to use as of v3.0.1\n.text-hide() {\n  .hide-text();\n}\n\n\n\n// CSS3 PROPERTIES\n// --------------------------------------------------\n\n// Single side border-radius\n.border-top-radius(@radius) {\n  border-top-right-radius: @radius;\n   border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n  border-bottom-right-radius: @radius;\n     border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n  border-bottom-right-radius: @radius;\n   border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n  border-bottom-left-radius: @radius;\n     border-top-left-radius: @radius;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n//   supported browsers that have box shadow capabilities now support the\n//   standard `box-shadow` property.\n.box-shadow(@shadow) {\n  -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n          box-shadow: @shadow;\n}\n\n// Transitions\n.transition(@transition) {\n  -webkit-transition: @transition;\n          transition: @transition;\n}\n.transition-property(@transition-property) {\n  -webkit-transition-property: @transition-property;\n          transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n  -webkit-transition-delay: @transition-delay;\n          transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n  -webkit-transition-duration: @transition-duration;\n          transition-duration: @transition-duration;\n}\n.transition-transform(@transition) {\n  -webkit-transition: -webkit-transform @transition;\n     -moz-transition: -moz-transform @transition;\n       -o-transition: -o-transform @transition;\n          transition: transform @transition;\n}\n\n// Transformations\n.rotate(@degrees) {\n  -webkit-transform: rotate(@degrees);\n      -ms-transform: rotate(@degrees); // IE9 only\n          transform: rotate(@degrees);\n}\n.scale(@ratio; @ratio-y...) {\n  -webkit-transform: scale(@ratio, @ratio-y);\n      -ms-transform: scale(@ratio, @ratio-y); // IE9 only\n          transform: scale(@ratio, @ratio-y);\n}\n.translate(@x; @y) {\n  -webkit-transform: translate(@x, @y);\n      -ms-transform: translate(@x, @y); // IE9 only\n          transform: translate(@x, @y);\n}\n.skew(@x; @y) {\n  -webkit-transform: skew(@x, @y);\n      -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n          transform: skew(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n  -webkit-transform: translate3d(@x, @y, @z);\n          transform: translate3d(@x, @y, @z);\n}\n\n.rotateX(@degrees) {\n  -webkit-transform: rotateX(@degrees);\n      -ms-transform: rotateX(@degrees); // IE9 only\n          transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n  -webkit-transform: rotateY(@degrees);\n      -ms-transform: rotateY(@degrees); // IE9 only\n          transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n  -webkit-perspective: @perspective;\n     -moz-perspective: @perspective;\n          perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n  -webkit-perspective-origin: @perspective;\n     -moz-perspective-origin: @perspective;\n          perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n  -webkit-transform-origin: @origin;\n     -moz-transform-origin: @origin;\n      -ms-transform-origin: @origin; // IE9 only\n          transform-origin: @origin;\n}\n\n// Animations\n.animation(@animation) {\n  -webkit-animation: @animation;\n          animation: @animation;\n}\n.animation-name(@name) {\n  -webkit-animation-name: @name;\n          animation-name: @name;\n}\n.animation-duration(@duration) {\n  -webkit-animation-duration: @duration;\n          animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n  -webkit-animation-timing-function: @timing-function;\n          animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n  -webkit-animation-delay: @delay;\n          animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n  -webkit-animation-iteration-count: @iteration-count;\n          animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n  -webkit-animation-direction: @direction;\n          animation-direction: @direction;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n.backface-visibility(@visibility){\n  -webkit-backface-visibility: @visibility;\n     -moz-backface-visibility: @visibility;\n          backface-visibility: @visibility;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n  -webkit-box-sizing: @boxmodel;\n     -moz-box-sizing: @boxmodel;\n          box-sizing: @boxmodel;\n}\n\n// User select\n// For selecting text on the page\n.user-select(@select) {\n  -webkit-user-select: @select;\n     -moz-user-select: @select;\n      -ms-user-select: @select; // IE10+\n       -o-user-select: @select;\n          user-select: @select;\n}\n\n// Resize anything\n.resizable(@direction) {\n  resize: @direction; // Options: horizontal, vertical, both\n  overflow: auto; // Safari fix\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n  -webkit-column-count: @column-count;\n     -moz-column-count: @column-count;\n          column-count: @column-count;\n  -webkit-column-gap: @column-gap;\n     -moz-column-gap: @column-gap;\n          column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n  word-wrap: break-word;\n  -webkit-hyphens: @mode;\n     -moz-hyphens: @mode;\n      -ms-hyphens: @mode; // IE10+\n       -o-hyphens: @mode;\n          hyphens: @mode;\n}\n\n// Opacity\n.opacity(@opacity) {\n  opacity: @opacity;\n  // IE8 filter\n  @opacity-ie: (@opacity * 100);\n  filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n\n\n\n// GRADIENTS\n// --------------------------------------------------\n\n#gradient {\n\n  // Horizontal gradient, from left to right\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(left, color-stop(@start-color @start-percent), color-stop(@end-color @end-percent)); // Safari 5.1-6, Chrome 10+\n    background-image:  linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  // Vertical gradient, from top to bottom\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Safari 5.1-6, Chrome 10+\n    background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n    background-repeat: repeat-x;\n    background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n    background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n  }\n  .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .radial(@inner-color: #555; @outer-color: #333) {\n    background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n    background-image: radial-gradient(circle, @inner-color, @outer-color);\n    background-repeat: no-repeat;\n  }\n  .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n    background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n  }\n}\n\n// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n.reset-filter() {\n  filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n\n\n\n// Retina images\n//\n// Short retina mixin for setting background-image and -size\n\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n  background-image: url(\"@{file-1x}\");\n\n  @media\n  only screen and (-webkit-min-device-pixel-ratio: 2),\n  only screen and (   min--moz-device-pixel-ratio: 2),\n  only screen and (     -o-min-device-pixel-ratio: 2/1),\n  only screen and (        min-device-pixel-ratio: 2),\n  only screen and (                min-resolution: 192dpi),\n  only screen and (                min-resolution: 2dppx) {\n    background-image: url(\"@{file-2x}\");\n    background-size: @width-1x @height-1x;\n  }\n}\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n.img-responsive(@display: block) {\n  display: @display;\n  max-width: 100%; // Part 1: Set a maximum relative to the parent\n  height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// COMPONENT MIXINS\n// --------------------------------------------------\n\n// Horizontal dividers\n// -------------------------\n// Dividers (basically an hr) within dropdowns and nav lists\n.nav-divider(@color: #e5e5e5) {\n  height: 1px;\n  margin: ((@line-height-computed / 2) - 1) 0;\n  overflow: hidden;\n  background-color: @color;\n}\n\n// Panels\n// -------------------------\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n  border-color: @border;\n\n  & > .panel-heading {\n    color: @heading-text-color;\n    background-color: @heading-bg-color;\n    border-color: @heading-border;\n\n    + .panel-collapse .panel-body {\n      border-top-color: @border;\n    }\n  }\n  & > .panel-footer {\n    + .panel-collapse .panel-body {\n      border-bottom-color: @border;\n    }\n  }\n}\n\n// Alerts\n// -------------------------\n.alert-variant(@background; @border; @text-color) {\n  background-color: @background;\n  border-color: @border;\n  color: @text-color;\n\n  hr {\n    border-top-color: darken(@border, 5%);\n  }\n  .alert-link {\n    color: darken(@text-color, 10%);\n  }\n}\n\n// Tables\n// -------------------------\n.table-row-variant(@state; @background) {\n  // Exact selectors below required to override `.table-striped` and prevent\n  // inheritance to nested tables.\n  .table > thead > tr,\n  .table > tbody > tr,\n  .table > tfoot > tr {\n    > td.@{state},\n    > th.@{state},\n    &.@{state} > td,\n    &.@{state} > th {\n      background-color: @background;\n    }\n  }\n\n  // Hover states for `.table-hover`\n  // Note: this is not available for cells or rows within `thead` or `tfoot`.\n  .table-hover > tbody > tr {\n    > td.@{state}:hover,\n    > th.@{state}:hover,\n    &.@{state}:hover > td,\n    &.@{state}:hover > th {\n      background-color: darken(@background, 5%);\n    }\n  }\n}\n\n// List Groups\n// -------------------------\n.list-group-item-variant(@state; @background; @color) {\n  .list-group-item-@{state} {\n    color: @color;\n    background-color: @background;\n\n    a& {\n      color: @color;\n\n      .list-group-item-heading { color: inherit; }\n\n      &:hover,\n      &:focus {\n        color: @color;\n        background-color: darken(@background, 5%);\n      }\n      &.active,\n      &.active:hover,\n      &.active:focus {\n        color: #fff;\n        background-color: @color;\n        border-color: @color;\n      }\n    }\n  }\n}\n\n// Button variants\n// -------------------------\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n.button-variant(@color; @background; @border) {\n  color: @color;\n  background-color: @background;\n  border-color: @border;\n\n  &:hover,\n  &:focus,\n  &:active,\n  &.active,\n  .open .dropdown-toggle& {\n    color: @color;\n    background-color: darken(@background, 8%);\n        border-color: darken(@border, 12%);\n  }\n  &:active,\n  &.active,\n  .open .dropdown-toggle& {\n    background-image: none;\n  }\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    &,\n    &:hover,\n    &:focus,\n    &:active,\n    &.active {\n      background-color: @background;\n          border-color: @border;\n    }\n  }\n\n  .badge {\n    color: @background;\n    background-color: @color;\n  }\n}\n\n// Button sizes\n// -------------------------\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n  padding: @padding-vertical @padding-horizontal;\n  font-size: @font-size;\n  line-height: @line-height;\n  border-radius: @border-radius;\n}\n\n// Pagination\n// -------------------------\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @border-radius) {\n  > li {\n    > a,\n    > span {\n      padding: @padding-vertical @padding-horizontal;\n      font-size: @font-size;\n    }\n    &:first-child {\n      > a,\n      > span {\n        .border-left-radius(@border-radius);\n      }\n    }\n    &:last-child {\n      > a,\n      > span {\n        .border-right-radius(@border-radius);\n      }\n    }\n  }\n}\n\n// Labels\n// -------------------------\n.label-variant(@color) {\n  background-color: @color;\n  &[href] {\n    &:hover,\n    &:focus {\n      background-color: darken(@color, 10%);\n    }\n  }\n}\n\n// Contextual backgrounds\n// -------------------------\n.bg-variant(@color) {\n  background-color: @color;\n  a&:hover {\n    background-color: darken(@color, 10%);\n  }\n}\n\n// Typography\n// -------------------------\n.text-emphasis-variant(@color) {\n  color: @color;\n  a&:hover {\n    color: darken(@color, 10%);\n  }\n}\n\n// Navbar vertical align\n// -------------------------\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n.navbar-vertical-align(@element-height) {\n  margin-top: ((@navbar-height - @element-height) / 2);\n  margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n\n// Progress bars\n// -------------------------\n.progress-bar-variant(@color) {\n  background-color: @color;\n  .progress-striped & {\n    #gradient > .striped();\n  }\n}\n\n// Responsive utilities\n// -------------------------\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n  display: block !important;\n  table&  { display: table; }\n  tr&     { display: table-row !important; }\n  th&,\n  td&     { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n    &,\n  tr&,\n  th&,\n  td& { display: none !important; }\n}\n\n\n// Grid System\n// -----------\n\n// Centered container element\n.container-fixed() {\n  margin-right: auto;\n  margin-left: auto;\n  padding-left:  (@grid-gutter-width / 2);\n  padding-right: (@grid-gutter-width / 2);\n  &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n  margin-left:  (@gutter / -2);\n  margin-right: (@gutter / -2);\n  &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  float: left;\n  width: percentage((@columns / @grid-columns));\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n  @media (min-width: @screen-xs-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-xs-column-push(@columns) {\n  @media (min-width: @screen-xs-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-xs-column-pull(@columns) {\n  @media (min-width: @screen-xs-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  @media (min-width: @screen-sm-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-offset(@columns) {\n  @media (min-width: @screen-sm-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-push(@columns) {\n  @media (min-width: @screen-sm-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-pull(@columns) {\n  @media (min-width: @screen-sm-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  @media (min-width: @screen-md-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-offset(@columns) {\n  @media (min-width: @screen-md-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-push(@columns) {\n  @media (min-width: @screen-md-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-pull(@columns) {\n  @media (min-width: @screen-md-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  @media (min-width: @screen-lg-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-offset(@columns) {\n  @media (min-width: @screen-lg-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-push(@columns) {\n  @media (min-width: @screen-lg-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-pull(@columns) {\n  @media (min-width: @screen-lg-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n\n// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n  // Common styles for all sizes of grid columns, widths 1-12\n  .col(@index) when (@index = 1) { // initial\n    @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n    .col((@index + 1), @item);\n  }\n  .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n    @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n    .col((@index + 1), ~\"@{list}, @{item}\");\n  }\n  .col(@index, @list) when (@index > @grid-columns) { // terminal\n    @{list} {\n      position: relative;\n      // Prevent columns from collapsing when empty\n      min-height: 1px;\n      // Inner gutter via padding\n      padding-left:  (@grid-gutter-width / 2);\n      padding-right: (@grid-gutter-width / 2);\n    }\n  }\n  .col(1); // kickstart it\n}\n\n.make-grid-columns-float(@class) {\n  .col(@index) when (@index = 1) { // initial\n    @item: ~\".col-@{class}-@{index}\";\n    .col((@index + 1), @item);\n  }\n  .col(@index, @list) when (@index =< @grid-columns) { // general\n    @item: ~\".col-@{class}-@{index}\";\n    .col((@index + 1), ~\"@{list}, @{item}\");\n  }\n  .col(@index, @list) when (@index > @grid-columns) { // terminal\n    @{list} {\n      float: left;\n    }\n  }\n  .col(1); // kickstart it\n}\n\n.calc-grid(@index, @class, @type) when (@type = width) and (@index > 0) {\n  .col-@{class}-@{index} {\n    width: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid(@index, @class, @type) when (@type = push) {\n  .col-@{class}-push-@{index} {\n    left: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid(@index, @class, @type) when (@type = pull) {\n  .col-@{class}-pull-@{index} {\n    right: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid(@index, @class, @type) when (@type = offset) {\n  .col-@{class}-offset-@{index} {\n    margin-left: percentage((@index / @grid-columns));\n  }\n}\n\n// Basic looping in LESS\n.make-grid(@index, @class, @type) when (@index >= 0) {\n  .calc-grid(@index, @class, @type);\n  // next iteration\n  .make-grid((@index - 1), @class, @type);\n}\n\n\n// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and successes.\n\n.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {\n  // Color the label and help text\n  .help-block,\n  .control-label,\n  .radio,\n  .checkbox,\n  .radio-inline,\n  .checkbox-inline  {\n    color: @text-color;\n  }\n  // Set the border and box shadow on specific inputs to match\n  .form-control {\n    border-color: @border-color;\n    .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work\n    &:focus {\n      border-color: darken(@border-color, 10%);\n      @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);\n      .box-shadow(@shadow);\n    }\n  }\n  // Set validation states also for addons\n  .input-group-addon {\n    color: @text-color;\n    border-color: @border-color;\n    background-color: @background-color;\n  }\n  // Optional feedback icon\n  .form-control-feedback {\n    color: @text-color;\n  }\n}\n\n// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `@input-focus-border` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n\n.form-control-focus(@color: @input-border-focus) {\n  @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n  &:focus {\n    border-color: @color;\n    outline: 0;\n    .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n  }\n}\n\n// Form control sizing\n//\n// Relative text size, padding, and border-radii changes for form controls. For\n// horizontal sizing, wrap controls in the predefined grid classes. `<select>`\n// element gets special love because it's special, and that's a fact!\n\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n  height: @input-height;\n  padding: @padding-vertical @padding-horizontal;\n  font-size: @font-size;\n  line-height: @line-height;\n  border-radius: @border-radius;\n\n  select& {\n    height: @input-height;\n    line-height: @input-height;\n  }\n\n  textarea&,\n  select[multiple]& {\n    height: auto;\n  }\n}\n"]}
\ No newline at end of file
diff --git a/app/gui/html/vendor/bootstrap/css/bootstrap-theme.min.css b/app/gui/html/vendor/bootstrap/css/bootstrap-theme.min.css
new file mode 100644
index 0000000..cff38df
--- /dev/null
+++ b/app/gui/html/vendor/bootstrap/css/bootstrap-theme.min.css
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v3.1.0 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn:active,.btn.active{background-image:none}.btn-default{background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;text-shadow:0 1px 0 #fff;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-primary{background-image:-webkit-linear-gradient(top,#428bca 0,#2d6ca2 100%);background-image:linear-gradient(to bottom,#428bca 0,#2d6ca2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#2b669a}.btn-primary:hover,.btn-primary:focus{background-color:#2d6ca2;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#2d6ca2;border-color:#2b669a}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-color:#e8e8e8}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);background-color:#357ebd}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f3f3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#222 0,#282828 100%);background-image:linear-gradient(to bottom,#222 0,#282828 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0)}.progress-bar{background-image:-webkit-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0)}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0)}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0)}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0)}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);border-color:#3278b3}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0)}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0)}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0)}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0)}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)}
\ No newline at end of file
diff --git a/app/gui/html/vendor/bootstrap/css/bootstrap.css b/app/gui/html/vendor/bootstrap/css/bootstrap.css
new file mode 100644
index 0000000..14cc1f4
--- /dev/null
+++ b/app/gui/html/vendor/bootstrap/css/bootstrap.css
@@ -0,0 +1,5831 @@
+/*!
+ * Bootstrap v3.1.0 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
+html {
+  font-family: sans-serif;
+  -webkit-text-size-adjust: 100%;
+      -ms-text-size-adjust: 100%;
+}
+body {
+  margin: 0;
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+nav,
+section,
+summary {
+  display: block;
+}
+audio,
+canvas,
+progress,
+video {
+  display: inline-block;
+  vertical-align: baseline;
+}
+audio:not([controls]) {
+  display: none;
+  height: 0;
+}
+[hidden],
+template {
+  display: none;
+}
+a {
+  background: transparent;
+}
+a:active,
+a:hover {
+  outline: 0;
+}
+abbr[title] {
+  border-bottom: 1px dotted;
+}
+b,
+strong {
+  font-weight: bold;
+}
+dfn {
+  font-style: italic;
+}
+h1 {
+  margin: .67em 0;
+  font-size: 2em;
+}
+mark {
+  color: #000;
+  background: #ff0;
+}
+small {
+  font-size: 80%;
+}
+sub,
+sup {
+  position: relative;
+  font-size: 75%;
+  line-height: 0;
+  vertical-align: baseline;
+}
+sup {
+  top: -.5em;
+}
+sub {
+  bottom: -.25em;
+}
+img {
+  border: 0;
+}
+svg:not(:root) {
+  overflow: hidden;
+}
+figure {
+  margin: 1em 40px;
+}
+hr {
+  height: 0;
+  -moz-box-sizing: content-box;
+       box-sizing: content-box;
+}
+pre {
+  overflow: auto;
+}
+code,
+kbd,
+pre,
+samp {
+  font-family: monospace, monospace;
+  font-size: 1em;
+}
+button,
+input,
+optgroup,
+select,
+textarea {
+  margin: 0;
+  font: inherit;
+  color: inherit;
+}
+button {
+  overflow: visible;
+}
+button,
+select {
+  text-transform: none;
+}
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+  -webkit-appearance: button;
+  cursor: pointer;
+}
+button[disabled],
+html input[disabled] {
+  cursor: default;
+}
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+  padding: 0;
+  border: 0;
+}
+input {
+  line-height: normal;
+}
+input[type="checkbox"],
+input[type="radio"] {
+  box-sizing: border-box;
+  padding: 0;
+}
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+  height: auto;
+}
+input[type="search"] {
+  -webkit-box-sizing: content-box;
+     -moz-box-sizing: content-box;
+          box-sizing: content-box;
+  -webkit-appearance: textfield;
+}
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+fieldset {
+  padding: .35em .625em .75em;
+  margin: 0 2px;
+  border: 1px solid #c0c0c0;
+}
+legend {
+  padding: 0;
+  border: 0;
+}
+textarea {
+  overflow: auto;
+}
+optgroup {
+  font-weight: bold;
+}
+table {
+  border-spacing: 0;
+  border-collapse: collapse;
+}
+td,
+th {
+  padding: 0;
+}
+ at media print {
+  * {
+    color: #000 !important;
+    text-shadow: none !important;
+    background: transparent !important;
+    box-shadow: none !important;
+  }
+  a,
+  a:visited {
+    text-decoration: underline;
+  }
+  a[href]:after {
+    content: " (" attr(href) ")";
+  }
+  abbr[title]:after {
+    content: " (" attr(title) ")";
+  }
+  a[href^="javascript:"]:after,
+  a[href^="#"]:after {
+    content: "";
+  }
+  pre,
+  blockquote {
+    border: 1px solid #999;
+
+    page-break-inside: avoid;
+  }
+  thead {
+    display: table-header-group;
+  }
+  tr,
+  img {
+    page-break-inside: avoid;
+  }
+  img {
+    max-width: 100% !important;
+  }
+  p,
+  h2,
+  h3 {
+    orphans: 3;
+    widows: 3;
+  }
+  h2,
+  h3 {
+    page-break-after: avoid;
+  }
+  select {
+    background: #fff !important;
+  }
+  .navbar {
+    display: none;
+  }
+  .table td,
+  .table th {
+    background-color: #fff !important;
+  }
+  .btn > .caret,
+  .dropup > .btn > .caret {
+    border-top-color: #000 !important;
+  }
+  .label {
+    border: 1px solid #000;
+  }
+  .table {
+    border-collapse: collapse !important;
+  }
+  .table-bordered th,
+  .table-bordered td {
+    border: 1px solid #ddd !important;
+  }
+}
+* {
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+}
+*:before,
+*:after {
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+}
+html {
+  font-size: 62.5%;
+
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+body {
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+  font-size: 14px;
+  line-height: 1.428571429;
+  color: #333;
+  background-color: #fff;
+}
+input,
+button,
+select,
+textarea {
+  font-family: inherit;
+  font-size: inherit;
+  line-height: inherit;
+}
+a {
+  color: #428bca;
+  text-decoration: none;
+}
+a:hover,
+a:focus {
+  color: #2a6496;
+  text-decoration: underline;
+}
+a:focus {
+  outline: thin dotted;
+  outline: 5px auto -webkit-focus-ring-color;
+  outline-offset: -2px;
+}
+figure {
+  margin: 0;
+}
+img {
+  vertical-align: middle;
+}
+.img-responsive {
+  display: block;
+  max-width: 100%;
+  height: auto;
+}
+.img-rounded {
+  border-radius: 6px;
+}
+.img-thumbnail {
+  display: inline-block;
+  max-width: 100%;
+  height: auto;
+  padding: 4px;
+  line-height: 1.428571429;
+  background-color: #fff;
+  border: 1px solid #ddd;
+  border-radius: 4px;
+  -webkit-transition: all .2s ease-in-out;
+          transition: all .2s ease-in-out;
+}
+.img-circle {
+  border-radius: 50%;
+}
+hr {
+  margin-top: 20px;
+  margin-bottom: 20px;
+  border: 0;
+  border-top: 1px solid #eee;
+}
+.sr-only {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip: rect(0, 0, 0, 0);
+  border: 0;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+  font-family: inherit;
+  font-weight: 500;
+  line-height: 1.1;
+  color: inherit;
+}
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small,
+.h1 small,
+.h2 small,
+.h3 small,
+.h4 small,
+.h5 small,
+.h6 small,
+h1 .small,
+h2 .small,
+h3 .small,
+h4 .small,
+h5 .small,
+h6 .small,
+.h1 .small,
+.h2 .small,
+.h3 .small,
+.h4 .small,
+.h5 .small,
+.h6 .small {
+  font-weight: normal;
+  line-height: 1;
+  color: #999;
+}
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3 {
+  margin-top: 20px;
+  margin-bottom: 10px;
+}
+h1 small,
+.h1 small,
+h2 small,
+.h2 small,
+h3 small,
+.h3 small,
+h1 .small,
+.h1 .small,
+h2 .small,
+.h2 .small,
+h3 .small,
+.h3 .small {
+  font-size: 65%;
+}
+h4,
+.h4,
+h5,
+.h5,
+h6,
+.h6 {
+  margin-top: 10px;
+  margin-bottom: 10px;
+}
+h4 small,
+.h4 small,
+h5 small,
+.h5 small,
+h6 small,
+.h6 small,
+h4 .small,
+.h4 .small,
+h5 .small,
+.h5 .small,
+h6 .small,
+.h6 .small {
+  font-size: 75%;
+}
+h1,
+.h1 {
+  font-size: 36px;
+}
+h2,
+.h2 {
+  font-size: 30px;
+}
+h3,
+.h3 {
+  font-size: 24px;
+}
+h4,
+.h4 {
+  font-size: 18px;
+}
+h5,
+.h5 {
+  font-size: 14px;
+}
+h6,
+.h6 {
+  font-size: 12px;
+}
+p {
+  margin: 0 0 10px;
+}
+.lead {
+  margin-bottom: 20px;
+  font-size: 16px;
+  font-weight: 200;
+  line-height: 1.4;
+}
+ at media (min-width: 768px) {
+  .lead {
+    font-size: 21px;
+  }
+}
+small,
+.small {
+  font-size: 85%;
+}
+cite {
+  font-style: normal;
+}
+.text-left {
+  text-align: left;
+}
+.text-right {
+  text-align: right;
+}
+.text-center {
+  text-align: center;
+}
+.text-justify {
+  text-align: justify;
+}
+.text-muted {
+  color: #999;
+}
+.text-primary {
+  color: #428bca;
+}
+a.text-primary:hover {
+  color: #3071a9;
+}
+.text-success {
+  color: #3c763d;
+}
+a.text-success:hover {
+  color: #2b542c;
+}
+.text-info {
+  color: #31708f;
+}
+a.text-info:hover {
+  color: #245269;
+}
+.text-warning {
+  color: #8a6d3b;
+}
+a.text-warning:hover {
+  color: #66512c;
+}
+.text-danger {
+  color: #a94442;
+}
+a.text-danger:hover {
+  color: #843534;
+}
+.bg-primary {
+  color: #fff;
+  background-color: #428bca;
+}
+a.bg-primary:hover {
+  background-color: #3071a9;
+}
+.bg-success {
+  background-color: #dff0d8;
+}
+a.bg-success:hover {
+  background-color: #c1e2b3;
+}
+.bg-info {
+  background-color: #d9edf7;
+}
+a.bg-info:hover {
+  background-color: #afd9ee;
+}
+.bg-warning {
+  background-color: #fcf8e3;
+}
+a.bg-warning:hover {
+  background-color: #f7ecb5;
+}
+.bg-danger {
+  background-color: #f2dede;
+}
+a.bg-danger:hover {
+  background-color: #e4b9b9;
+}
+.page-header {
+  padding-bottom: 9px;
+  margin: 40px 0 20px;
+  border-bottom: 1px solid #eee;
+}
+ul,
+ol {
+  margin-top: 0;
+  margin-bottom: 10px;
+}
+ul ul,
+ol ul,
+ul ol,
+ol ol {
+  margin-bottom: 0;
+}
+.list-unstyled {
+  padding-left: 0;
+  list-style: none;
+}
+.list-inline {
+  padding-left: 0;
+  list-style: none;
+}
+.list-inline > li {
+  display: inline-block;
+  padding-right: 5px;
+  padding-left: 5px;
+}
+.list-inline > li:first-child {
+  padding-left: 0;
+}
+dl {
+  margin-top: 0;
+  margin-bottom: 20px;
+}
+dt,
+dd {
+  line-height: 1.428571429;
+}
+dt {
+  font-weight: bold;
+}
+dd {
+  margin-left: 0;
+}
+ at media (min-width: 768px) {
+  .dl-horizontal dt {
+    float: left;
+    width: 160px;
+    overflow: hidden;
+    clear: left;
+    text-align: right;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+  .dl-horizontal dd {
+    margin-left: 180px;
+  }
+}
+abbr[title],
+abbr[data-original-title] {
+  cursor: help;
+  border-bottom: 1px dotted #999;
+}
+.initialism {
+  font-size: 90%;
+  text-transform: uppercase;
+}
+blockquote {
+  padding: 10px 20px;
+  margin: 0 0 20px;
+  font-size: 17.5px;
+  border-left: 5px solid #eee;
+}
+blockquote p:last-child,
+blockquote ul:last-child,
+blockquote ol:last-child {
+  margin-bottom: 0;
+}
+blockquote footer,
+blockquote small,
+blockquote .small {
+  display: block;
+  font-size: 80%;
+  line-height: 1.428571429;
+  color: #999;
+}
+blockquote footer:before,
+blockquote small:before,
+blockquote .small:before {
+  content: '\2014 \00A0';
+}
+.blockquote-reverse,
+blockquote.pull-right {
+  padding-right: 15px;
+  padding-left: 0;
+  text-align: right;
+  border-right: 5px solid #eee;
+  border-left: 0;
+}
+.blockquote-reverse footer:before,
+blockquote.pull-right footer:before,
+.blockquote-reverse small:before,
+blockquote.pull-right small:before,
+.blockquote-reverse .small:before,
+blockquote.pull-right .small:before {
+  content: '';
+}
+.blockquote-reverse footer:after,
+blockquote.pull-right footer:after,
+.blockquote-reverse small:after,
+blockquote.pull-right small:after,
+.blockquote-reverse .small:after,
+blockquote.pull-right .small:after {
+  content: '\00A0 \2014';
+}
+blockquote:before,
+blockquote:after {
+  content: "";
+}
+address {
+  margin-bottom: 20px;
+  font-style: normal;
+  line-height: 1.428571429;
+}
+code,
+kbd,
+pre,
+samp {
+  font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+}
+code {
+  padding: 2px 4px;
+  font-size: 90%;
+  color: #c7254e;
+  white-space: nowrap;
+  background-color: #f9f2f4;
+  border-radius: 4px;
+}
+kbd {
+  padding: 2px 4px;
+  font-size: 90%;
+  color: #fff;
+  background-color: #333;
+  border-radius: 3px;
+  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+}
+pre {
+  display: block;
+  padding: 9.5px;
+  margin: 0 0 10px;
+  font-size: 13px;
+  line-height: 1.428571429;
+  color: #333;
+  word-break: break-all;
+  word-wrap: break-word;
+  background-color: #f5f5f5;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+}
+pre code {
+  padding: 0;
+  font-size: inherit;
+  color: inherit;
+  white-space: pre-wrap;
+  background-color: transparent;
+  border-radius: 0;
+}
+.pre-scrollable {
+  max-height: 340px;
+  overflow-y: scroll;
+}
+.container {
+  padding-right: 15px;
+  padding-left: 15px;
+  margin-right: auto;
+  margin-left: auto;
+}
+ at media (min-width: 768px) {
+  .container {
+    width: 750px;
+  }
+}
+ at media (min-width: 992px) {
+  .container {
+    width: 970px;
+  }
+}
+ at media (min-width: 1200px) {
+  .container {
+    width: 1170px;
+  }
+}
+.container-fluid {
+  padding-right: 15px;
+  padding-left: 15px;
+  margin-right: auto;
+  margin-left: auto;
+}
+.row {
+  margin-right: -15px;
+  margin-left: -15px;
+}
+.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
+  position: relative;
+  min-height: 1px;
+  padding-right: 15px;
+  padding-left: 15px;
+}
+.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
+  float: left;
+}
+.col-xs-12 {
+  width: 100%;
+}
+.col-xs-11 {
+  width: 91.66666666666666%;
+}
+.col-xs-10 {
+  width: 83.33333333333334%;
+}
+.col-xs-9 {
+  width: 75%;
+}
+.col-xs-8 {
+  width: 66.66666666666666%;
+}
+.col-xs-7 {
+  width: 58.333333333333336%;
+}
+.col-xs-6 {
+  width: 50%;
+}
+.col-xs-5 {
+  width: 41.66666666666667%;
+}
+.col-xs-4 {
+  width: 33.33333333333333%;
+}
+.col-xs-3 {
+  width: 25%;
+}
+.col-xs-2 {
+  width: 16.666666666666664%;
+}
+.col-xs-1 {
+  width: 8.333333333333332%;
+}
+.col-xs-pull-12 {
+  right: 100%;
+}
+.col-xs-pull-11 {
+  right: 91.66666666666666%;
+}
+.col-xs-pull-10 {
+  right: 83.33333333333334%;
+}
+.col-xs-pull-9 {
+  right: 75%;
+}
+.col-xs-pull-8 {
+  right: 66.66666666666666%;
+}
+.col-xs-pull-7 {
+  right: 58.333333333333336%;
+}
+.col-xs-pull-6 {
+  right: 50%;
+}
+.col-xs-pull-5 {
+  right: 41.66666666666667%;
+}
+.col-xs-pull-4 {
+  right: 33.33333333333333%;
+}
+.col-xs-pull-3 {
+  right: 25%;
+}
+.col-xs-pull-2 {
+  right: 16.666666666666664%;
+}
+.col-xs-pull-1 {
+  right: 8.333333333333332%;
+}
+.col-xs-pull-0 {
+  right: 0;
+}
+.col-xs-push-12 {
+  left: 100%;
+}
+.col-xs-push-11 {
+  left: 91.66666666666666%;
+}
+.col-xs-push-10 {
+  left: 83.33333333333334%;
+}
+.col-xs-push-9 {
+  left: 75%;
+}
+.col-xs-push-8 {
+  left: 66.66666666666666%;
+}
+.col-xs-push-7 {
+  left: 58.333333333333336%;
+}
+.col-xs-push-6 {
+  left: 50%;
+}
+.col-xs-push-5 {
+  left: 41.66666666666667%;
+}
+.col-xs-push-4 {
+  left: 33.33333333333333%;
+}
+.col-xs-push-3 {
+  left: 25%;
+}
+.col-xs-push-2 {
+  left: 16.666666666666664%;
+}
+.col-xs-push-1 {
+  left: 8.333333333333332%;
+}
+.col-xs-push-0 {
+  left: 0;
+}
+.col-xs-offset-12 {
+  margin-left: 100%;
+}
+.col-xs-offset-11 {
+  margin-left: 91.66666666666666%;
+}
+.col-xs-offset-10 {
+  margin-left: 83.33333333333334%;
+}
+.col-xs-offset-9 {
+  margin-left: 75%;
+}
+.col-xs-offset-8 {
+  margin-left: 66.66666666666666%;
+}
+.col-xs-offset-7 {
+  margin-left: 58.333333333333336%;
+}
+.col-xs-offset-6 {
+  margin-left: 50%;
+}
+.col-xs-offset-5 {
+  margin-left: 41.66666666666667%;
+}
+.col-xs-offset-4 {
+  margin-left: 33.33333333333333%;
+}
+.col-xs-offset-3 {
+  margin-left: 25%;
+}
+.col-xs-offset-2 {
+  margin-left: 16.666666666666664%;
+}
+.col-xs-offset-1 {
+  margin-left: 8.333333333333332%;
+}
+.col-xs-offset-0 {
+  margin-left: 0;
+}
+ at media (min-width: 768px) {
+  .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
+    float: left;
+  }
+  .col-sm-12 {
+    width: 100%;
+  }
+  .col-sm-11 {
+    width: 91.66666666666666%;
+  }
+  .col-sm-10 {
+    width: 83.33333333333334%;
+  }
+  .col-sm-9 {
+    width: 75%;
+  }
+  .col-sm-8 {
+    width: 66.66666666666666%;
+  }
+  .col-sm-7 {
+    width: 58.333333333333336%;
+  }
+  .col-sm-6 {
+    width: 50%;
+  }
+  .col-sm-5 {
+    width: 41.66666666666667%;
+  }
+  .col-sm-4 {
+    width: 33.33333333333333%;
+  }
+  .col-sm-3 {
+    width: 25%;
+  }
+  .col-sm-2 {
+    width: 16.666666666666664%;
+  }
+  .col-sm-1 {
+    width: 8.333333333333332%;
+  }
+  .col-sm-pull-12 {
+    right: 100%;
+  }
+  .col-sm-pull-11 {
+    right: 91.66666666666666%;
+  }
+  .col-sm-pull-10 {
+    right: 83.33333333333334%;
+  }
+  .col-sm-pull-9 {
+    right: 75%;
+  }
+  .col-sm-pull-8 {
+    right: 66.66666666666666%;
+  }
+  .col-sm-pull-7 {
+    right: 58.333333333333336%;
+  }
+  .col-sm-pull-6 {
+    right: 50%;
+  }
+  .col-sm-pull-5 {
+    right: 41.66666666666667%;
+  }
+  .col-sm-pull-4 {
+    right: 33.33333333333333%;
+  }
+  .col-sm-pull-3 {
+    right: 25%;
+  }
+  .col-sm-pull-2 {
+    right: 16.666666666666664%;
+  }
+  .col-sm-pull-1 {
+    right: 8.333333333333332%;
+  }
+  .col-sm-pull-0 {
+    right: 0;
+  }
+  .col-sm-push-12 {
+    left: 100%;
+  }
+  .col-sm-push-11 {
+    left: 91.66666666666666%;
+  }
+  .col-sm-push-10 {
+    left: 83.33333333333334%;
+  }
+  .col-sm-push-9 {
+    left: 75%;
+  }
+  .col-sm-push-8 {
+    left: 66.66666666666666%;
+  }
+  .col-sm-push-7 {
+    left: 58.333333333333336%;
+  }
+  .col-sm-push-6 {
+    left: 50%;
+  }
+  .col-sm-push-5 {
+    left: 41.66666666666667%;
+  }
+  .col-sm-push-4 {
+    left: 33.33333333333333%;
+  }
+  .col-sm-push-3 {
+    left: 25%;
+  }
+  .col-sm-push-2 {
+    left: 16.666666666666664%;
+  }
+  .col-sm-push-1 {
+    left: 8.333333333333332%;
+  }
+  .col-sm-push-0 {
+    left: 0;
+  }
+  .col-sm-offset-12 {
+    margin-left: 100%;
+  }
+  .col-sm-offset-11 {
+    margin-left: 91.66666666666666%;
+  }
+  .col-sm-offset-10 {
+    margin-left: 83.33333333333334%;
+  }
+  .col-sm-offset-9 {
+    margin-left: 75%;
+  }
+  .col-sm-offset-8 {
+    margin-left: 66.66666666666666%;
+  }
+  .col-sm-offset-7 {
+    margin-left: 58.333333333333336%;
+  }
+  .col-sm-offset-6 {
+    margin-left: 50%;
+  }
+  .col-sm-offset-5 {
+    margin-left: 41.66666666666667%;
+  }
+  .col-sm-offset-4 {
+    margin-left: 33.33333333333333%;
+  }
+  .col-sm-offset-3 {
+    margin-left: 25%;
+  }
+  .col-sm-offset-2 {
+    margin-left: 16.666666666666664%;
+  }
+  .col-sm-offset-1 {
+    margin-left: 8.333333333333332%;
+  }
+  .col-sm-offset-0 {
+    margin-left: 0;
+  }
+}
+ at media (min-width: 992px) {
+  .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+    float: left;
+  }
+  .col-md-12 {
+    width: 100%;
+  }
+  .col-md-11 {
+    width: 91.66666666666666%;
+  }
+  .col-md-10 {
+    width: 83.33333333333334%;
+  }
+  .col-md-9 {
+    width: 75%;
+  }
+  .col-md-8 {
+    width: 66.66666666666666%;
+  }
+  .col-md-7 {
+    width: 58.333333333333336%;
+  }
+  .col-md-6 {
+    width: 50%;
+  }
+  .col-md-5 {
+    width: 41.66666666666667%;
+  }
+  .col-md-4 {
+    width: 33.33333333333333%;
+  }
+  .col-md-3 {
+    width: 25%;
+  }
+  .col-md-2 {
+    width: 16.666666666666664%;
+  }
+  .col-md-1 {
+    width: 8.333333333333332%;
+  }
+  .col-md-pull-12 {
+    right: 100%;
+  }
+  .col-md-pull-11 {
+    right: 91.66666666666666%;
+  }
+  .col-md-pull-10 {
+    right: 83.33333333333334%;
+  }
+  .col-md-pull-9 {
+    right: 75%;
+  }
+  .col-md-pull-8 {
+    right: 66.66666666666666%;
+  }
+  .col-md-pull-7 {
+    right: 58.333333333333336%;
+  }
+  .col-md-pull-6 {
+    right: 50%;
+  }
+  .col-md-pull-5 {
+    right: 41.66666666666667%;
+  }
+  .col-md-pull-4 {
+    right: 33.33333333333333%;
+  }
+  .col-md-pull-3 {
+    right: 25%;
+  }
+  .col-md-pull-2 {
+    right: 16.666666666666664%;
+  }
+  .col-md-pull-1 {
+    right: 8.333333333333332%;
+  }
+  .col-md-pull-0 {
+    right: 0;
+  }
+  .col-md-push-12 {
+    left: 100%;
+  }
+  .col-md-push-11 {
+    left: 91.66666666666666%;
+  }
+  .col-md-push-10 {
+    left: 83.33333333333334%;
+  }
+  .col-md-push-9 {
+    left: 75%;
+  }
+  .col-md-push-8 {
+    left: 66.66666666666666%;
+  }
+  .col-md-push-7 {
+    left: 58.333333333333336%;
+  }
+  .col-md-push-6 {
+    left: 50%;
+  }
+  .col-md-push-5 {
+    left: 41.66666666666667%;
+  }
+  .col-md-push-4 {
+    left: 33.33333333333333%;
+  }
+  .col-md-push-3 {
+    left: 25%;
+  }
+  .col-md-push-2 {
+    left: 16.666666666666664%;
+  }
+  .col-md-push-1 {
+    left: 8.333333333333332%;
+  }
+  .col-md-push-0 {
+    left: 0;
+  }
+  .col-md-offset-12 {
+    margin-left: 100%;
+  }
+  .col-md-offset-11 {
+    margin-left: 91.66666666666666%;
+  }
+  .col-md-offset-10 {
+    margin-left: 83.33333333333334%;
+  }
+  .col-md-offset-9 {
+    margin-left: 75%;
+  }
+  .col-md-offset-8 {
+    margin-left: 66.66666666666666%;
+  }
+  .col-md-offset-7 {
+    margin-left: 58.333333333333336%;
+  }
+  .col-md-offset-6 {
+    margin-left: 50%;
+  }
+  .col-md-offset-5 {
+    margin-left: 41.66666666666667%;
+  }
+  .col-md-offset-4 {
+    margin-left: 33.33333333333333%;
+  }
+  .col-md-offset-3 {
+    margin-left: 25%;
+  }
+  .col-md-offset-2 {
+    margin-left: 16.666666666666664%;
+  }
+  .col-md-offset-1 {
+    margin-left: 8.333333333333332%;
+  }
+  .col-md-offset-0 {
+    margin-left: 0;
+  }
+}
+ at media (min-width: 1200px) {
+  .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
+    float: left;
+  }
+  .col-lg-12 {
+    width: 100%;
+  }
+  .col-lg-11 {
+    width: 91.66666666666666%;
+  }
+  .col-lg-10 {
+    width: 83.33333333333334%;
+  }
+  .col-lg-9 {
+    width: 75%;
+  }
+  .col-lg-8 {
+    width: 66.66666666666666%;
+  }
+  .col-lg-7 {
+    width: 58.333333333333336%;
+  }
+  .col-lg-6 {
+    width: 50%;
+  }
+  .col-lg-5 {
+    width: 41.66666666666667%;
+  }
+  .col-lg-4 {
+    width: 33.33333333333333%;
+  }
+  .col-lg-3 {
+    width: 25%;
+  }
+  .col-lg-2 {
+    width: 16.666666666666664%;
+  }
+  .col-lg-1 {
+    width: 8.333333333333332%;
+  }
+  .col-lg-pull-12 {
+    right: 100%;
+  }
+  .col-lg-pull-11 {
+    right: 91.66666666666666%;
+  }
+  .col-lg-pull-10 {
+    right: 83.33333333333334%;
+  }
+  .col-lg-pull-9 {
+    right: 75%;
+  }
+  .col-lg-pull-8 {
+    right: 66.66666666666666%;
+  }
+  .col-lg-pull-7 {
+    right: 58.333333333333336%;
+  }
+  .col-lg-pull-6 {
+    right: 50%;
+  }
+  .col-lg-pull-5 {
+    right: 41.66666666666667%;
+  }
+  .col-lg-pull-4 {
+    right: 33.33333333333333%;
+  }
+  .col-lg-pull-3 {
+    right: 25%;
+  }
+  .col-lg-pull-2 {
+    right: 16.666666666666664%;
+  }
+  .col-lg-pull-1 {
+    right: 8.333333333333332%;
+  }
+  .col-lg-pull-0 {
+    right: 0;
+  }
+  .col-lg-push-12 {
+    left: 100%;
+  }
+  .col-lg-push-11 {
+    left: 91.66666666666666%;
+  }
+  .col-lg-push-10 {
+    left: 83.33333333333334%;
+  }
+  .col-lg-push-9 {
+    left: 75%;
+  }
+  .col-lg-push-8 {
+    left: 66.66666666666666%;
+  }
+  .col-lg-push-7 {
+    left: 58.333333333333336%;
+  }
+  .col-lg-push-6 {
+    left: 50%;
+  }
+  .col-lg-push-5 {
+    left: 41.66666666666667%;
+  }
+  .col-lg-push-4 {
+    left: 33.33333333333333%;
+  }
+  .col-lg-push-3 {
+    left: 25%;
+  }
+  .col-lg-push-2 {
+    left: 16.666666666666664%;
+  }
+  .col-lg-push-1 {
+    left: 8.333333333333332%;
+  }
+  .col-lg-push-0 {
+    left: 0;
+  }
+  .col-lg-offset-12 {
+    margin-left: 100%;
+  }
+  .col-lg-offset-11 {
+    margin-left: 91.66666666666666%;
+  }
+  .col-lg-offset-10 {
+    margin-left: 83.33333333333334%;
+  }
+  .col-lg-offset-9 {
+    margin-left: 75%;
+  }
+  .col-lg-offset-8 {
+    margin-left: 66.66666666666666%;
+  }
+  .col-lg-offset-7 {
+    margin-left: 58.333333333333336%;
+  }
+  .col-lg-offset-6 {
+    margin-left: 50%;
+  }
+  .col-lg-offset-5 {
+    margin-left: 41.66666666666667%;
+  }
+  .col-lg-offset-4 {
+    margin-left: 33.33333333333333%;
+  }
+  .col-lg-offset-3 {
+    margin-left: 25%;
+  }
+  .col-lg-offset-2 {
+    margin-left: 16.666666666666664%;
+  }
+  .col-lg-offset-1 {
+    margin-left: 8.333333333333332%;
+  }
+  .col-lg-offset-0 {
+    margin-left: 0;
+  }
+}
+table {
+  max-width: 100%;
+  background-color: transparent;
+}
+th {
+  text-align: left;
+}
+.table {
+  width: 100%;
+  margin-bottom: 20px;
+}
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+  padding: 8px;
+  line-height: 1.428571429;
+  vertical-align: top;
+  border-top: 1px solid #ddd;
+}
+.table > thead > tr > th {
+  vertical-align: bottom;
+  border-bottom: 2px solid #ddd;
+}
+.table > caption + thead > tr:first-child > th,
+.table > colgroup + thead > tr:first-child > th,
+.table > thead:first-child > tr:first-child > th,
+.table > caption + thead > tr:first-child > td,
+.table > colgroup + thead > tr:first-child > td,
+.table > thead:first-child > tr:first-child > td {
+  border-top: 0;
+}
+.table > tbody + tbody {
+  border-top: 2px solid #ddd;
+}
+.table .table {
+  background-color: #fff;
+}
+.table-condensed > thead > tr > th,
+.table-condensed > tbody > tr > th,
+.table-condensed > tfoot > tr > th,
+.table-condensed > thead > tr > td,
+.table-condensed > tbody > tr > td,
+.table-condensed > tfoot > tr > td {
+  padding: 5px;
+}
+.table-bordered {
+  border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+  border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+  border-bottom-width: 2px;
+}
+.table-striped > tbody > tr:nth-child(odd) > td,
+.table-striped > tbody > tr:nth-child(odd) > th {
+  background-color: #f9f9f9;
+}
+.table-hover > tbody > tr:hover > td,
+.table-hover > tbody > tr:hover > th {
+  background-color: #f5f5f5;
+}
+table col[class*="col-"] {
+  position: static;
+  display: table-column;
+  float: none;
+}
+table td[class*="col-"],
+table th[class*="col-"] {
+  position: static;
+  display: table-cell;
+  float: none;
+}
+.table > thead > tr > td.active,
+.table > tbody > tr > td.active,
+.table > tfoot > tr > td.active,
+.table > thead > tr > th.active,
+.table > tbody > tr > th.active,
+.table > tfoot > tr > th.active,
+.table > thead > tr.active > td,
+.table > tbody > tr.active > td,
+.table > tfoot > tr.active > td,
+.table > thead > tr.active > th,
+.table > tbody > tr.active > th,
+.table > tfoot > tr.active > th {
+  background-color: #f5f5f5;
+}
+.table-hover > tbody > tr > td.active:hover,
+.table-hover > tbody > tr > th.active:hover,
+.table-hover > tbody > tr.active:hover > td,
+.table-hover > tbody > tr.active:hover > th {
+  background-color: #e8e8e8;
+}
+.table > thead > tr > td.success,
+.table > tbody > tr > td.success,
+.table > tfoot > tr > td.success,
+.table > thead > tr > th.success,
+.table > tbody > tr > th.success,
+.table > tfoot > tr > th.success,
+.table > thead > tr.success > td,
+.table > tbody > tr.success > td,
+.table > tfoot > tr.success > td,
+.table > thead > tr.success > th,
+.table > tbody > tr.success > th,
+.table > tfoot > tr.success > th {
+  background-color: #dff0d8;
+}
+.table-hover > tbody > tr > td.success:hover,
+.table-hover > tbody > tr > th.success:hover,
+.table-hover > tbody > tr.success:hover > td,
+.table-hover > tbody > tr.success:hover > th {
+  background-color: #d0e9c6;
+}
+.table > thead > tr > td.info,
+.table > tbody > tr > td.info,
+.table > tfoot > tr > td.info,
+.table > thead > tr > th.info,
+.table > tbody > tr > th.info,
+.table > tfoot > tr > th.info,
+.table > thead > tr.info > td,
+.table > tbody > tr.info > td,
+.table > tfoot > tr.info > td,
+.table > thead > tr.info > th,
+.table > tbody > tr.info > th,
+.table > tfoot > tr.info > th {
+  background-color: #d9edf7;
+}
+.table-hover > tbody > tr > td.info:hover,
+.table-hover > tbody > tr > th.info:hover,
+.table-hover > tbody > tr.info:hover > td,
+.table-hover > tbody > tr.info:hover > th {
+  background-color: #c4e3f3;
+}
+.table > thead > tr > td.warning,
+.table > tbody > tr > td.warning,
+.table > tfoot > tr > td.warning,
+.table > thead > tr > th.warning,
+.table > tbody > tr > th.warning,
+.table > tfoot > tr > th.warning,
+.table > thead > tr.warning > td,
+.table > tbody > tr.warning > td,
+.table > tfoot > tr.warning > td,
+.table > thead > tr.warning > th,
+.table > tbody > tr.warning > th,
+.table > tfoot > tr.warning > th {
+  background-color: #fcf8e3;
+}
+.table-hover > tbody > tr > td.warning:hover,
+.table-hover > tbody > tr > th.warning:hover,
+.table-hover > tbody > tr.warning:hover > td,
+.table-hover > tbody > tr.warning:hover > th {
+  background-color: #faf2cc;
+}
+.table > thead > tr > td.danger,
+.table > tbody > tr > td.danger,
+.table > tfoot > tr > td.danger,
+.table > thead > tr > th.danger,
+.table > tbody > tr > th.danger,
+.table > tfoot > tr > th.danger,
+.table > thead > tr.danger > td,
+.table > tbody > tr.danger > td,
+.table > tfoot > tr.danger > td,
+.table > thead > tr.danger > th,
+.table > tbody > tr.danger > th,
+.table > tfoot > tr.danger > th {
+  background-color: #f2dede;
+}
+.table-hover > tbody > tr > td.danger:hover,
+.table-hover > tbody > tr > th.danger:hover,
+.table-hover > tbody > tr.danger:hover > td,
+.table-hover > tbody > tr.danger:hover > th {
+  background-color: #ebcccc;
+}
+ at media (max-width: 767px) {
+  .table-responsive {
+    width: 100%;
+    margin-bottom: 15px;
+    overflow-x: scroll;
+    overflow-y: hidden;
+    -webkit-overflow-scrolling: touch;
+    -ms-overflow-style: -ms-autohiding-scrollbar;
+    border: 1px solid #ddd;
+  }
+  .table-responsive > .table {
+    margin-bottom: 0;
+  }
+  .table-responsive > .table > thead > tr > th,
+  .table-responsive > .table > tbody > tr > th,
+  .table-responsive > .table > tfoot > tr > th,
+  .table-responsive > .table > thead > tr > td,
+  .table-responsive > .table > tbody > tr > td,
+  .table-responsive > .table > tfoot > tr > td {
+    white-space: nowrap;
+  }
+  .table-responsive > .table-bordered {
+    border: 0;
+  }
+  .table-responsive > .table-bordered > thead > tr > th:first-child,
+  .table-responsive > .table-bordered > tbody > tr > th:first-child,
+  .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+  .table-responsive > .table-bordered > thead > tr > td:first-child,
+  .table-responsive > .table-bordered > tbody > tr > td:first-child,
+  .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+    border-left: 0;
+  }
+  .table-responsive > .table-bordered > thead > tr > th:last-child,
+  .table-responsive > .table-bordered > tbody > tr > th:last-child,
+  .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+  .table-responsive > .table-bordered > thead > tr > td:last-child,
+  .table-responsive > .table-bordered > tbody > tr > td:last-child,
+  .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+    border-right: 0;
+  }
+  .table-responsive > .table-bordered > tbody > tr:last-child > th,
+  .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+  .table-responsive > .table-bordered > tbody > tr:last-child > td,
+  .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+    border-bottom: 0;
+  }
+}
+fieldset {
+  min-width: 0;
+  padding: 0;
+  margin: 0;
+  border: 0;
+}
+legend {
+  display: block;
+  width: 100%;
+  padding: 0;
+  margin-bottom: 20px;
+  font-size: 21px;
+  line-height: inherit;
+  color: #333;
+  border: 0;
+  border-bottom: 1px solid #e5e5e5;
+}
+label {
+  display: inline-block;
+  margin-bottom: 5px;
+  font-weight: bold;
+}
+input[type="search"] {
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+}
+input[type="radio"],
+input[type="checkbox"] {
+  margin: 4px 0 0;
+  margin-top: 1px \9;
+  /* IE8-9 */
+  line-height: normal;
+}
+input[type="file"] {
+  display: block;
+}
+input[type="range"] {
+  display: block;
+  width: 100%;
+}
+select[multiple],
+select[size] {
+  height: auto;
+}
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+  outline: thin dotted;
+  outline: 5px auto -webkit-focus-ring-color;
+  outline-offset: -2px;
+}
+output {
+  display: block;
+  padding-top: 7px;
+  font-size: 14px;
+  line-height: 1.428571429;
+  color: #555;
+}
+.form-control {
+  display: block;
+  width: 100%;
+  height: 34px;
+  padding: 6px 12px;
+  font-size: 14px;
+  line-height: 1.428571429;
+  color: #555;
+  background-color: #fff;
+  background-image: none;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+  -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+          transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+.form-control:focus {
+  border-color: #66afe9;
+  outline: 0;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
+          box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
+}
+.form-control:-moz-placeholder {
+  color: #999;
+}
+.form-control::-moz-placeholder {
+  color: #999;
+  opacity: 1;
+}
+.form-control:-ms-input-placeholder {
+  color: #999;
+}
+.form-control::-webkit-input-placeholder {
+  color: #999;
+}
+.form-control[disabled],
+.form-control[readonly],
+fieldset[disabled] .form-control {
+  cursor: not-allowed;
+  background-color: #eee;
+  opacity: 1;
+}
+textarea.form-control {
+  height: auto;
+}
+input[type="date"] {
+  line-height: 34px;
+}
+.form-group {
+  margin-bottom: 15px;
+}
+.radio,
+.checkbox {
+  display: block;
+  min-height: 20px;
+  padding-left: 20px;
+  margin-top: 10px;
+  margin-bottom: 10px;
+}
+.radio label,
+.checkbox label {
+  display: inline;
+  font-weight: normal;
+  cursor: pointer;
+}
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
+  float: left;
+  margin-left: -20px;
+}
+.radio + .radio,
+.checkbox + .checkbox {
+  margin-top: -5px;
+}
+.radio-inline,
+.checkbox-inline {
+  display: inline-block;
+  padding-left: 20px;
+  margin-bottom: 0;
+  font-weight: normal;
+  vertical-align: middle;
+  cursor: pointer;
+}
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
+  margin-top: 0;
+  margin-left: 10px;
+}
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+.radio[disabled],
+.radio-inline[disabled],
+.checkbox[disabled],
+.checkbox-inline[disabled],
+fieldset[disabled] input[type="radio"],
+fieldset[disabled] input[type="checkbox"],
+fieldset[disabled] .radio,
+fieldset[disabled] .radio-inline,
+fieldset[disabled] .checkbox,
+fieldset[disabled] .checkbox-inline {
+  cursor: not-allowed;
+}
+.input-sm {
+  height: 30px;
+  padding: 5px 10px;
+  font-size: 12px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+select.input-sm {
+  height: 30px;
+  line-height: 30px;
+}
+textarea.input-sm,
+select[multiple].input-sm {
+  height: auto;
+}
+.input-lg {
+  height: 46px;
+  padding: 10px 16px;
+  font-size: 18px;
+  line-height: 1.33;
+  border-radius: 6px;
+}
+select.input-lg {
+  height: 46px;
+  line-height: 46px;
+}
+textarea.input-lg,
+select[multiple].input-lg {
+  height: auto;
+}
+.has-feedback {
+  position: relative;
+}
+.has-feedback .form-control {
+  padding-right: 42.5px;
+}
+.has-feedback .form-control-feedback {
+  position: absolute;
+  top: 25px;
+  right: 0;
+  display: block;
+  width: 34px;
+  height: 34px;
+  line-height: 34px;
+  text-align: center;
+}
+.has-success .help-block,
+.has-success .control-label,
+.has-success .radio,
+.has-success .checkbox,
+.has-success .radio-inline,
+.has-success .checkbox-inline {
+  color: #3c763d;
+}
+.has-success .form-control {
+  border-color: #3c763d;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-success .form-control:focus {
+  border-color: #2b542c;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+}
+.has-success .input-group-addon {
+  color: #3c763d;
+  background-color: #dff0d8;
+  border-color: #3c763d;
+}
+.has-success .form-control-feedback {
+  color: #3c763d;
+}
+.has-warning .help-block,
+.has-warning .control-label,
+.has-warning .radio,
+.has-warning .checkbox,
+.has-warning .radio-inline,
+.has-warning .checkbox-inline {
+  color: #8a6d3b;
+}
+.has-warning .form-control {
+  border-color: #8a6d3b;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-warning .form-control:focus {
+  border-color: #66512c;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+}
+.has-warning .input-group-addon {
+  color: #8a6d3b;
+  background-color: #fcf8e3;
+  border-color: #8a6d3b;
+}
+.has-warning .form-control-feedback {
+  color: #8a6d3b;
+}
+.has-error .help-block,
+.has-error .control-label,
+.has-error .radio,
+.has-error .checkbox,
+.has-error .radio-inline,
+.has-error .checkbox-inline {
+  color: #a94442;
+}
+.has-error .form-control {
+  border-color: #a94442;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-error .form-control:focus {
+  border-color: #843534;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+}
+.has-error .input-group-addon {
+  color: #a94442;
+  background-color: #f2dede;
+  border-color: #a94442;
+}
+.has-error .form-control-feedback {
+  color: #a94442;
+}
+.form-control-static {
+  margin-bottom: 0;
+}
+.help-block {
+  display: block;
+  margin-top: 5px;
+  margin-bottom: 10px;
+  color: #737373;
+}
+ at media (min-width: 768px) {
+  .form-inline .form-group {
+    display: inline-block;
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .form-inline .form-control {
+    display: inline-block;
+    width: auto;
+    vertical-align: middle;
+  }
+  .form-inline .control-label {
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .form-inline .radio,
+  .form-inline .checkbox {
+    display: inline-block;
+    padding-left: 0;
+    margin-top: 0;
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .form-inline .radio input[type="radio"],
+  .form-inline .checkbox input[type="checkbox"] {
+    float: none;
+    margin-left: 0;
+  }
+  .form-inline .has-feedback .form-control-feedback {
+    top: 0;
+  }
+}
+.form-horizontal .control-label,
+.form-horizontal .radio,
+.form-horizontal .checkbox,
+.form-horizontal .radio-inline,
+.form-horizontal .checkbox-inline {
+  padding-top: 7px;
+  margin-top: 0;
+  margin-bottom: 0;
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox {
+  min-height: 27px;
+}
+.form-horizontal .form-group {
+  margin-right: -15px;
+  margin-left: -15px;
+}
+.form-horizontal .form-control-static {
+  padding-top: 7px;
+}
+ at media (min-width: 768px) {
+  .form-horizontal .control-label {
+    text-align: right;
+  }
+}
+.form-horizontal .has-feedback .form-control-feedback {
+  top: 0;
+  right: 15px;
+}
+.btn {
+  display: inline-block;
+  padding: 6px 12px;
+  margin-bottom: 0;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 1.428571429;
+  text-align: center;
+  white-space: nowrap;
+  vertical-align: middle;
+  cursor: pointer;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+       -o-user-select: none;
+          user-select: none;
+  background-image: none;
+  border: 1px solid transparent;
+  border-radius: 4px;
+}
+.btn:focus {
+  outline: thin dotted;
+  outline: 5px auto -webkit-focus-ring-color;
+  outline-offset: -2px;
+}
+.btn:hover,
+.btn:focus {
+  color: #333;
+  text-decoration: none;
+}
+.btn:active,
+.btn.active {
+  background-image: none;
+  outline: 0;
+  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+  pointer-events: none;
+  cursor: not-allowed;
+  filter: alpha(opacity=65);
+  -webkit-box-shadow: none;
+          box-shadow: none;
+  opacity: .65;
+}
+.btn-default {
+  color: #333;
+  background-color: #fff;
+  border-color: #ccc;
+}
+.btn-default:hover,
+.btn-default:focus,
+.btn-default:active,
+.btn-default.active,
+.open .dropdown-toggle.btn-default {
+  color: #333;
+  background-color: #ebebeb;
+  border-color: #adadad;
+}
+.btn-default:active,
+.btn-default.active,
+.open .dropdown-toggle.btn-default {
+  background-image: none;
+}
+.btn-default.disabled,
+.btn-default[disabled],
+fieldset[disabled] .btn-default,
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled:active,
+.btn-default[disabled]:active,
+fieldset[disabled] .btn-default:active,
+.btn-default.disabled.active,
+.btn-default[disabled].active,
+fieldset[disabled] .btn-default.active {
+  background-color: #fff;
+  border-color: #ccc;
+}
+.btn-default .badge {
+  color: #fff;
+  background-color: #333;
+}
+.btn-primary {
+  color: #fff;
+  background-color: #428bca;
+  border-color: #357ebd;
+}
+.btn-primary:hover,
+.btn-primary:focus,
+.btn-primary:active,
+.btn-primary.active,
+.open .dropdown-toggle.btn-primary {
+  color: #fff;
+  background-color: #3276b1;
+  border-color: #285e8e;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open .dropdown-toggle.btn-primary {
+  background-image: none;
+}
+.btn-primary.disabled,
+.btn-primary[disabled],
+fieldset[disabled] .btn-primary,
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled:active,
+.btn-primary[disabled]:active,
+fieldset[disabled] .btn-primary:active,
+.btn-primary.disabled.active,
+.btn-primary[disabled].active,
+fieldset[disabled] .btn-primary.active {
+  background-color: #428bca;
+  border-color: #357ebd;
+}
+.btn-primary .badge {
+  color: #428bca;
+  background-color: #fff;
+}
+.btn-success {
+  color: #fff;
+  background-color: #5cb85c;
+  border-color: #4cae4c;
+}
+.btn-success:hover,
+.btn-success:focus,
+.btn-success:active,
+.btn-success.active,
+.open .dropdown-toggle.btn-success {
+  color: #fff;
+  background-color: #47a447;
+  border-color: #398439;
+}
+.btn-success:active,
+.btn-success.active,
+.open .dropdown-toggle.btn-success {
+  background-image: none;
+}
+.btn-success.disabled,
+.btn-success[disabled],
+fieldset[disabled] .btn-success,
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled:active,
+.btn-success[disabled]:active,
+fieldset[disabled] .btn-success:active,
+.btn-success.disabled.active,
+.btn-success[disabled].active,
+fieldset[disabled] .btn-success.active {
+  background-color: #5cb85c;
+  border-color: #4cae4c;
+}
+.btn-success .badge {
+  color: #5cb85c;
+  background-color: #fff;
+}
+.btn-info {
+  color: #fff;
+  background-color: #5bc0de;
+  border-color: #46b8da;
+}
+.btn-info:hover,
+.btn-info:focus,
+.btn-info:active,
+.btn-info.active,
+.open .dropdown-toggle.btn-info {
+  color: #fff;
+  background-color: #39b3d7;
+  border-color: #269abc;
+}
+.btn-info:active,
+.btn-info.active,
+.open .dropdown-toggle.btn-info {
+  background-image: none;
+}
+.btn-info.disabled,
+.btn-info[disabled],
+fieldset[disabled] .btn-info,
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled:active,
+.btn-info[disabled]:active,
+fieldset[disabled] .btn-info:active,
+.btn-info.disabled.active,
+.btn-info[disabled].active,
+fieldset[disabled] .btn-info.active {
+  background-color: #5bc0de;
+  border-color: #46b8da;
+}
+.btn-info .badge {
+  color: #5bc0de;
+  background-color: #fff;
+}
+.btn-warning {
+  color: #fff;
+  background-color: #f0ad4e;
+  border-color: #eea236;
+}
+.btn-warning:hover,
+.btn-warning:focus,
+.btn-warning:active,
+.btn-warning.active,
+.open .dropdown-toggle.btn-warning {
+  color: #fff;
+  background-color: #ed9c28;
+  border-color: #d58512;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open .dropdown-toggle.btn-warning {
+  background-image: none;
+}
+.btn-warning.disabled,
+.btn-warning[disabled],
+fieldset[disabled] .btn-warning,
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled:active,
+.btn-warning[disabled]:active,
+fieldset[disabled] .btn-warning:active,
+.btn-warning.disabled.active,
+.btn-warning[disabled].active,
+fieldset[disabled] .btn-warning.active {
+  background-color: #f0ad4e;
+  border-color: #eea236;
+}
+.btn-warning .badge {
+  color: #f0ad4e;
+  background-color: #fff;
+}
+.btn-danger {
+  color: #fff;
+  background-color: #d9534f;
+  border-color: #d43f3a;
+}
+.btn-danger:hover,
+.btn-danger:focus,
+.btn-danger:active,
+.btn-danger.active,
+.open .dropdown-toggle.btn-danger {
+  color: #fff;
+  background-color: #d2322d;
+  border-color: #ac2925;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open .dropdown-toggle.btn-danger {
+  background-image: none;
+}
+.btn-danger.disabled,
+.btn-danger[disabled],
+fieldset[disabled] .btn-danger,
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled:active,
+.btn-danger[disabled]:active,
+fieldset[disabled] .btn-danger:active,
+.btn-danger.disabled.active,
+.btn-danger[disabled].active,
+fieldset[disabled] .btn-danger.active {
+  background-color: #d9534f;
+  border-color: #d43f3a;
+}
+.btn-danger .badge {
+  color: #d9534f;
+  background-color: #fff;
+}
+.btn-link {
+  font-weight: normal;
+  color: #428bca;
+  cursor: pointer;
+  border-radius: 0;
+}
+.btn-link,
+.btn-link:active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+  background-color: transparent;
+  -webkit-box-shadow: none;
+          box-shadow: none;
+}
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+  border-color: transparent;
+}
+.btn-link:hover,
+.btn-link:focus {
+  color: #2a6496;
+  text-decoration: underline;
+  background-color: transparent;
+}
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+  color: #999;
+  text-decoration: none;
+}
+.btn-lg {
+  padding: 10px 16px;
+  font-size: 18px;
+  line-height: 1.33;
+  border-radius: 6px;
+}
+.btn-sm {
+  padding: 5px 10px;
+  font-size: 12px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+.btn-xs {
+  padding: 1px 5px;
+  font-size: 12px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+.btn-block {
+  display: block;
+  width: 100%;
+  padding-right: 0;
+  padding-left: 0;
+}
+.btn-block + .btn-block {
+  margin-top: 5px;
+}
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+  width: 100%;
+}
+.fade {
+  opacity: 0;
+  -webkit-transition: opacity .15s linear;
+          transition: opacity .15s linear;
+}
+.fade.in {
+  opacity: 1;
+}
+.collapse {
+  display: none;
+}
+.collapse.in {
+  display: block;
+}
+.collapsing {
+  position: relative;
+  height: 0;
+  overflow: hidden;
+  -webkit-transition: height .35s ease;
+          transition: height .35s ease;
+}
+ at font-face {
+  font-family: 'Glyphicons Halflings';
+
+  src: url('../fonts/glyphicons-halflings-regular.eot');
+  src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+}
+.glyphicon {
+  position: relative;
+  top: 1px;
+  display: inline-block;
+  font-family: 'Glyphicons Halflings';
+  font-style: normal;
+  font-weight: normal;
+  line-height: 1;
+
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+.glyphicon-asterisk:before {
+  content: "\2a";
+}
+.glyphicon-plus:before {
+  content: "\2b";
+}
+.glyphicon-euro:before {
+  content: "\20ac";
+}
+.glyphicon-minus:before {
+  content: "\2212";
+}
+.glyphicon-cloud:before {
+  content: "\2601";
+}
+.glyphicon-envelope:before {
+  content: "\2709";
+}
+.glyphicon-pencil:before {
+  content: "\270f";
+}
+.glyphicon-glass:before {
+  content: "\e001";
+}
+.glyphicon-music:before {
+  content: "\e002";
+}
+.glyphicon-search:before {
+  content: "\e003";
+}
+.glyphicon-heart:before {
+  content: "\e005";
+}
+.glyphicon-star:before {
+  content: "\e006";
+}
+.glyphicon-star-empty:before {
+  content: "\e007";
+}
+.glyphicon-user:before {
+  content: "\e008";
+}
+.glyphicon-film:before {
+  content: "\e009";
+}
+.glyphicon-th-large:before {
+  content: "\e010";
+}
+.glyphicon-th:before {
+  content: "\e011";
+}
+.glyphicon-th-list:before {
+  content: "\e012";
+}
+.glyphicon-ok:before {
+  content: "\e013";
+}
+.glyphicon-remove:before {
+  content: "\e014";
+}
+.glyphicon-zoom-in:before {
+  content: "\e015";
+}
+.glyphicon-zoom-out:before {
+  content: "\e016";
+}
+.glyphicon-off:before {
+  content: "\e017";
+}
+.glyphicon-signal:before {
+  content: "\e018";
+}
+.glyphicon-cog:before {
+  content: "\e019";
+}
+.glyphicon-trash:before {
+  content: "\e020";
+}
+.glyphicon-home:before {
+  content: "\e021";
+}
+.glyphicon-file:before {
+  content: "\e022";
+}
+.glyphicon-time:before {
+  content: "\e023";
+}
+.glyphicon-road:before {
+  content: "\e024";
+}
+.glyphicon-download-alt:before {
+  content: "\e025";
+}
+.glyphicon-download:before {
+  content: "\e026";
+}
+.glyphicon-upload:before {
+  content: "\e027";
+}
+.glyphicon-inbox:before {
+  content: "\e028";
+}
+.glyphicon-play-circle:before {
+  content: "\e029";
+}
+.glyphicon-repeat:before {
+  content: "\e030";
+}
+.glyphicon-refresh:before {
+  content: "\e031";
+}
+.glyphicon-list-alt:before {
+  content: "\e032";
+}
+.glyphicon-lock:before {
+  content: "\e033";
+}
+.glyphicon-flag:before {
+  content: "\e034";
+}
+.glyphicon-headphones:before {
+  content: "\e035";
+}
+.glyphicon-volume-off:before {
+  content: "\e036";
+}
+.glyphicon-volume-down:before {
+  content: "\e037";
+}
+.glyphicon-volume-up:before {
+  content: "\e038";
+}
+.glyphicon-qrcode:before {
+  content: "\e039";
+}
+.glyphicon-barcode:before {
+  content: "\e040";
+}
+.glyphicon-tag:before {
+  content: "\e041";
+}
+.glyphicon-tags:before {
+  content: "\e042";
+}
+.glyphicon-book:before {
+  content: "\e043";
+}
+.glyphicon-bookmark:before {
+  content: "\e044";
+}
+.glyphicon-print:before {
+  content: "\e045";
+}
+.glyphicon-camera:before {
+  content: "\e046";
+}
+.glyphicon-font:before {
+  content: "\e047";
+}
+.glyphicon-bold:before {
+  content: "\e048";
+}
+.glyphicon-italic:before {
+  content: "\e049";
+}
+.glyphicon-text-height:before {
+  content: "\e050";
+}
+.glyphicon-text-width:before {
+  content: "\e051";
+}
+.glyphicon-align-left:before {
+  content: "\e052";
+}
+.glyphicon-align-center:before {
+  content: "\e053";
+}
+.glyphicon-align-right:before {
+  content: "\e054";
+}
+.glyphicon-align-justify:before {
+  content: "\e055";
+}
+.glyphicon-list:before {
+  content: "\e056";
+}
+.glyphicon-indent-left:before {
+  content: "\e057";
+}
+.glyphicon-indent-right:before {
+  content: "\e058";
+}
+.glyphicon-facetime-video:before {
+  content: "\e059";
+}
+.glyphicon-picture:before {
+  content: "\e060";
+}
+.glyphicon-map-marker:before {
+  content: "\e062";
+}
+.glyphicon-adjust:before {
+  content: "\e063";
+}
+.glyphicon-tint:before {
+  content: "\e064";
+}
+.glyphicon-edit:before {
+  content: "\e065";
+}
+.glyphicon-share:before {
+  content: "\e066";
+}
+.glyphicon-check:before {
+  content: "\e067";
+}
+.glyphicon-move:before {
+  content: "\e068";
+}
+.glyphicon-step-backward:before {
+  content: "\e069";
+}
+.glyphicon-fast-backward:before {
+  content: "\e070";
+}
+.glyphicon-backward:before {
+  content: "\e071";
+}
+.glyphicon-play:before {
+  content: "\e072";
+}
+.glyphicon-pause:before {
+  content: "\e073";
+}
+.glyphicon-stop:before {
+  content: "\e074";
+}
+.glyphicon-forward:before {
+  content: "\e075";
+}
+.glyphicon-fast-forward:before {
+  content: "\e076";
+}
+.glyphicon-step-forward:before {
+  content: "\e077";
+}
+.glyphicon-eject:before {
+  content: "\e078";
+}
+.glyphicon-chevron-left:before {
+  content: "\e079";
+}
+.glyphicon-chevron-right:before {
+  content: "\e080";
+}
+.glyphicon-plus-sign:before {
+  content: "\e081";
+}
+.glyphicon-minus-sign:before {
+  content: "\e082";
+}
+.glyphicon-remove-sign:before {
+  content: "\e083";
+}
+.glyphicon-ok-sign:before {
+  content: "\e084";
+}
+.glyphicon-question-sign:before {
+  content: "\e085";
+}
+.glyphicon-info-sign:before {
+  content: "\e086";
+}
+.glyphicon-screenshot:before {
+  content: "\e087";
+}
+.glyphicon-remove-circle:before {
+  content: "\e088";
+}
+.glyphicon-ok-circle:before {
+  content: "\e089";
+}
+.glyphicon-ban-circle:before {
+  content: "\e090";
+}
+.glyphicon-arrow-left:before {
+  content: "\e091";
+}
+.glyphicon-arrow-right:before {
+  content: "\e092";
+}
+.glyphicon-arrow-up:before {
+  content: "\e093";
+}
+.glyphicon-arrow-down:before {
+  content: "\e094";
+}
+.glyphicon-share-alt:before {
+  content: "\e095";
+}
+.glyphicon-resize-full:before {
+  content: "\e096";
+}
+.glyphicon-resize-small:before {
+  content: "\e097";
+}
+.glyphicon-exclamation-sign:before {
+  content: "\e101";
+}
+.glyphicon-gift:before {
+  content: "\e102";
+}
+.glyphicon-leaf:before {
+  content: "\e103";
+}
+.glyphicon-fire:before {
+  content: "\e104";
+}
+.glyphicon-eye-open:before {
+  content: "\e105";
+}
+.glyphicon-eye-close:before {
+  content: "\e106";
+}
+.glyphicon-warning-sign:before {
+  content: "\e107";
+}
+.glyphicon-plane:before {
+  content: "\e108";
+}
+.glyphicon-calendar:before {
+  content: "\e109";
+}
+.glyphicon-random:before {
+  content: "\e110";
+}
+.glyphicon-comment:before {
+  content: "\e111";
+}
+.glyphicon-magnet:before {
+  content: "\e112";
+}
+.glyphicon-chevron-up:before {
+  content: "\e113";
+}
+.glyphicon-chevron-down:before {
+  content: "\e114";
+}
+.glyphicon-retweet:before {
+  content: "\e115";
+}
+.glyphicon-shopping-cart:before {
+  content: "\e116";
+}
+.glyphicon-folder-close:before {
+  content: "\e117";
+}
+.glyphicon-folder-open:before {
+  content: "\e118";
+}
+.glyphicon-resize-vertical:before {
+  content: "\e119";
+}
+.glyphicon-resize-horizontal:before {
+  content: "\e120";
+}
+.glyphicon-hdd:before {
+  content: "\e121";
+}
+.glyphicon-bullhorn:before {
+  content: "\e122";
+}
+.glyphicon-bell:before {
+  content: "\e123";
+}
+.glyphicon-certificate:before {
+  content: "\e124";
+}
+.glyphicon-thumbs-up:before {
+  content: "\e125";
+}
+.glyphicon-thumbs-down:before {
+  content: "\e126";
+}
+.glyphicon-hand-right:before {
+  content: "\e127";
+}
+.glyphicon-hand-left:before {
+  content: "\e128";
+}
+.glyphicon-hand-up:before {
+  content: "\e129";
+}
+.glyphicon-hand-down:before {
+  content: "\e130";
+}
+.glyphicon-circle-arrow-right:before {
+  content: "\e131";
+}
+.glyphicon-circle-arrow-left:before {
+  content: "\e132";
+}
+.glyphicon-circle-arrow-up:before {
+  content: "\e133";
+}
+.glyphicon-circle-arrow-down:before {
+  content: "\e134";
+}
+.glyphicon-globe:before {
+  content: "\e135";
+}
+.glyphicon-wrench:before {
+  content: "\e136";
+}
+.glyphicon-tasks:before {
+  content: "\e137";
+}
+.glyphicon-filter:before {
+  content: "\e138";
+}
+.glyphicon-briefcase:before {
+  content: "\e139";
+}
+.glyphicon-fullscreen:before {
+  content: "\e140";
+}
+.glyphicon-dashboard:before {
+  content: "\e141";
+}
+.glyphicon-paperclip:before {
+  content: "\e142";
+}
+.glyphicon-heart-empty:before {
+  content: "\e143";
+}
+.glyphicon-link:before {
+  content: "\e144";
+}
+.glyphicon-phone:before {
+  content: "\e145";
+}
+.glyphicon-pushpin:before {
+  content: "\e146";
+}
+.glyphicon-usd:before {
+  content: "\e148";
+}
+.glyphicon-gbp:before {
+  content: "\e149";
+}
+.glyphicon-sort:before {
+  content: "\e150";
+}
+.glyphicon-sort-by-alphabet:before {
+  content: "\e151";
+}
+.glyphicon-sort-by-alphabet-alt:before {
+  content: "\e152";
+}
+.glyphicon-sort-by-order:before {
+  content: "\e153";
+}
+.glyphicon-sort-by-order-alt:before {
+  content: "\e154";
+}
+.glyphicon-sort-by-attributes:before {
+  content: "\e155";
+}
+.glyphicon-sort-by-attributes-alt:before {
+  content: "\e156";
+}
+.glyphicon-unchecked:before {
+  content: "\e157";
+}
+.glyphicon-expand:before {
+  content: "\e158";
+}
+.glyphicon-collapse-down:before {
+  content: "\e159";
+}
+.glyphicon-collapse-up:before {
+  content: "\e160";
+}
+.glyphicon-log-in:before {
+  content: "\e161";
+}
+.glyphicon-flash:before {
+  content: "\e162";
+}
+.glyphicon-log-out:before {
+  content: "\e163";
+}
+.glyphicon-new-window:before {
+  content: "\e164";
+}
+.glyphicon-record:before {
+  content: "\e165";
+}
+.glyphicon-save:before {
+  content: "\e166";
+}
+.glyphicon-open:before {
+  content: "\e167";
+}
+.glyphicon-saved:before {
+  content: "\e168";
+}
+.glyphicon-import:before {
+  content: "\e169";
+}
+.glyphicon-export:before {
+  content: "\e170";
+}
+.glyphicon-send:before {
+  content: "\e171";
+}
+.glyphicon-floppy-disk:before {
+  content: "\e172";
+}
+.glyphicon-floppy-saved:before {
+  content: "\e173";
+}
+.glyphicon-floppy-remove:before {
+  content: "\e174";
+}
+.glyphicon-floppy-save:before {
+  content: "\e175";
+}
+.glyphicon-floppy-open:before {
+  content: "\e176";
+}
+.glyphicon-credit-card:before {
+  content: "\e177";
+}
+.glyphicon-transfer:before {
+  content: "\e178";
+}
+.glyphicon-cutlery:before {
+  content: "\e179";
+}
+.glyphicon-header:before {
+  content: "\e180";
+}
+.glyphicon-compressed:before {
+  content: "\e181";
+}
+.glyphicon-earphone:before {
+  content: "\e182";
+}
+.glyphicon-phone-alt:before {
+  content: "\e183";
+}
+.glyphicon-tower:before {
+  content: "\e184";
+}
+.glyphicon-stats:before {
+  content: "\e185";
+}
+.glyphicon-sd-video:before {
+  content: "\e186";
+}
+.glyphicon-hd-video:before {
+  content: "\e187";
+}
+.glyphicon-subtitles:before {
+  content: "\e188";
+}
+.glyphicon-sound-stereo:before {
+  content: "\e189";
+}
+.glyphicon-sound-dolby:before {
+  content: "\e190";
+}
+.glyphicon-sound-5-1:before {
+  content: "\e191";
+}
+.glyphicon-sound-6-1:before {
+  content: "\e192";
+}
+.glyphicon-sound-7-1:before {
+  content: "\e193";
+}
+.glyphicon-copyright-mark:before {
+  content: "\e194";
+}
+.glyphicon-registration-mark:before {
+  content: "\e195";
+}
+.glyphicon-cloud-download:before {
+  content: "\e197";
+}
+.glyphicon-cloud-upload:before {
+  content: "\e198";
+}
+.glyphicon-tree-conifer:before {
+  content: "\e199";
+}
+.glyphicon-tree-deciduous:before {
+  content: "\e200";
+}
+.caret {
+  display: inline-block;
+  width: 0;
+  height: 0;
+  margin-left: 2px;
+  vertical-align: middle;
+  border-top: 4px solid;
+  border-right: 4px solid transparent;
+  border-left: 4px solid transparent;
+}
+.dropdown {
+  position: relative;
+}
+.dropdown-toggle:focus {
+  outline: 0;
+}
+.dropdown-menu {
+  position: absolute;
+  top: 100%;
+  left: 0;
+  z-index: 1000;
+  display: none;
+  float: left;
+  min-width: 160px;
+  padding: 5px 0;
+  margin: 2px 0 0;
+  font-size: 14px;
+  list-style: none;
+  background-color: #fff;
+  background-clip: padding-box;
+  border: 1px solid #ccc;
+  border: 1px solid rgba(0, 0, 0, .15);
+  border-radius: 4px;
+  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+          box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+}
+.dropdown-menu.pull-right {
+  right: 0;
+  left: auto;
+}
+.dropdown-menu .divider {
+  height: 1px;
+  margin: 9px 0;
+  overflow: hidden;
+  background-color: #e5e5e5;
+}
+.dropdown-menu > li > a {
+  display: block;
+  padding: 3px 20px;
+  clear: both;
+  font-weight: normal;
+  line-height: 1.428571429;
+  color: #333;
+  white-space: nowrap;
+}
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+  color: #262626;
+  text-decoration: none;
+  background-color: #f5f5f5;
+}
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+  color: #fff;
+  text-decoration: none;
+  background-color: #428bca;
+  outline: 0;
+}
+.dropdown-menu > .disabled > a,
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+  color: #999;
+}
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+  text-decoration: none;
+  cursor: not-allowed;
+  background-color: transparent;
+  background-image: none;
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+}
+.open > .dropdown-menu {
+  display: block;
+}
+.open > a {
+  outline: 0;
+}
+.dropdown-menu-right {
+  right: 0;
+  left: auto;
+}
+.dropdown-menu-left {
+  right: auto;
+  left: 0;
+}
+.dropdown-header {
+  display: block;
+  padding: 3px 20px;
+  font-size: 12px;
+  line-height: 1.428571429;
+  color: #999;
+}
+.dropdown-backdrop {
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 990;
+}
+.pull-right > .dropdown-menu {
+  right: 0;
+  left: auto;
+}
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
+  content: "";
+  border-top: 0;
+  border-bottom: 4px solid;
+}
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
+  top: auto;
+  bottom: 100%;
+  margin-bottom: 1px;
+}
+ at media (min-width: 768px) {
+  .navbar-right .dropdown-menu {
+    right: 0;
+    left: auto;
+  }
+  .navbar-right .dropdown-menu-left {
+    right: auto;
+    left: 0;
+  }
+}
+.btn-group,
+.btn-group-vertical {
+  position: relative;
+  display: inline-block;
+  vertical-align: middle;
+}
+.btn-group > .btn,
+.btn-group-vertical > .btn {
+  position: relative;
+  float: left;
+}
+.btn-group > .btn:hover,
+.btn-group-vertical > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group-vertical > .btn:focus,
+.btn-group > .btn:active,
+.btn-group-vertical > .btn:active,
+.btn-group > .btn.active,
+.btn-group-vertical > .btn.active {
+  z-index: 2;
+}
+.btn-group > .btn:focus,
+.btn-group-vertical > .btn:focus {
+  outline: none;
+}
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group {
+  margin-left: -1px;
+}
+.btn-toolbar {
+  margin-left: -5px;
+}
+.btn-toolbar .btn-group,
+.btn-toolbar .input-group {
+  float: left;
+}
+.btn-toolbar > .btn,
+.btn-toolbar > .btn-group,
+.btn-toolbar > .input-group {
+  margin-left: 5px;
+}
+.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
+  border-radius: 0;
+}
+.btn-group > .btn:first-child {
+  margin-left: 0;
+}
+.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.btn-group > .btn-group {
+  float: left;
+}
+.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
+  border-radius: 0;
+}
+.btn-group > .btn-group:first-child > .btn:last-child,
+.btn-group > .btn-group:first-child > .dropdown-toggle {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.btn-group > .btn-group:last-child > .btn:first-child {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+  outline: 0;
+}
+.btn-group-xs > .btn {
+  padding: 1px 5px;
+  font-size: 12px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+.btn-group-sm > .btn {
+  padding: 5px 10px;
+  font-size: 12px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+.btn-group-lg > .btn {
+  padding: 10px 16px;
+  font-size: 18px;
+  line-height: 1.33;
+  border-radius: 6px;
+}
+.btn-group > .btn + .dropdown-toggle {
+  padding-right: 8px;
+  padding-left: 8px;
+}
+.btn-group > .btn-lg + .dropdown-toggle {
+  padding-right: 12px;
+  padding-left: 12px;
+}
+.btn-group.open .dropdown-toggle {
+  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+.btn-group.open .dropdown-toggle.btn-link {
+  -webkit-box-shadow: none;
+          box-shadow: none;
+}
+.btn .caret {
+  margin-left: 0;
+}
+.btn-lg .caret {
+  border-width: 5px 5px 0;
+  border-bottom-width: 0;
+}
+.dropup .btn-lg .caret {
+  border-width: 0 5px 5px;
+}
+.btn-group-vertical > .btn,
+.btn-group-vertical > .btn-group,
+.btn-group-vertical > .btn-group > .btn {
+  display: block;
+  float: none;
+  width: 100%;
+  max-width: 100%;
+}
+.btn-group-vertical > .btn-group > .btn {
+  float: none;
+}
+.btn-group-vertical > .btn + .btn,
+.btn-group-vertical > .btn + .btn-group,
+.btn-group-vertical > .btn-group + .btn,
+.btn-group-vertical > .btn-group + .btn-group {
+  margin-top: -1px;
+  margin-left: 0;
+}
+.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
+  border-radius: 0;
+}
+.btn-group-vertical > .btn:first-child:not(:last-child) {
+  border-top-right-radius: 4px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn:last-child:not(:first-child) {
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+  border-bottom-left-radius: 4px;
+}
+.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
+  border-radius: 0;
+}
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+}
+.btn-group-justified {
+  display: table;
+  width: 100%;
+  table-layout: fixed;
+  border-collapse: separate;
+}
+.btn-group-justified > .btn,
+.btn-group-justified > .btn-group {
+  display: table-cell;
+  float: none;
+  width: 1%;
+}
+.btn-group-justified > .btn-group .btn {
+  width: 100%;
+}
+[data-toggle="buttons"] > .btn > input[type="radio"],
+[data-toggle="buttons"] > .btn > input[type="checkbox"] {
+  display: none;
+}
+.input-group {
+  position: relative;
+  display: table;
+  border-collapse: separate;
+}
+.input-group[class*="col-"] {
+  float: none;
+  padding-right: 0;
+  padding-left: 0;
+}
+.input-group .form-control {
+  float: left;
+  width: 100%;
+  margin-bottom: 0;
+}
+.input-group-lg > .form-control,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
+  height: 46px;
+  padding: 10px 16px;
+  font-size: 18px;
+  line-height: 1.33;
+  border-radius: 6px;
+}
+select.input-group-lg > .form-control,
+select.input-group-lg > .input-group-addon,
+select.input-group-lg > .input-group-btn > .btn {
+  height: 46px;
+  line-height: 46px;
+}
+textarea.input-group-lg > .form-control,
+textarea.input-group-lg > .input-group-addon,
+textarea.input-group-lg > .input-group-btn > .btn,
+select[multiple].input-group-lg > .form-control,
+select[multiple].input-group-lg > .input-group-addon,
+select[multiple].input-group-lg > .input-group-btn > .btn {
+  height: auto;
+}
+.input-group-sm > .form-control,
+.input-group-sm > .input-group-addon,
+.input-group-sm > .input-group-btn > .btn {
+  height: 30px;
+  padding: 5px 10px;
+  font-size: 12px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+select.input-group-sm > .form-control,
+select.input-group-sm > .input-group-addon,
+select.input-group-sm > .input-group-btn > .btn {
+  height: 30px;
+  line-height: 30px;
+}
+textarea.input-group-sm > .form-control,
+textarea.input-group-sm > .input-group-addon,
+textarea.input-group-sm > .input-group-btn > .btn,
+select[multiple].input-group-sm > .form-control,
+select[multiple].input-group-sm > .input-group-addon,
+select[multiple].input-group-sm > .input-group-btn > .btn {
+  height: auto;
+}
+.input-group-addon,
+.input-group-btn,
+.input-group .form-control {
+  display: table-cell;
+}
+.input-group-addon:not(:first-child):not(:last-child),
+.input-group-btn:not(:first-child):not(:last-child),
+.input-group .form-control:not(:first-child):not(:last-child) {
+  border-radius: 0;
+}
+.input-group-addon,
+.input-group-btn {
+  width: 1%;
+  white-space: nowrap;
+  vertical-align: middle;
+}
+.input-group-addon {
+  padding: 6px 12px;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 1;
+  color: #555;
+  text-align: center;
+  background-color: #eee;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+}
+.input-group-addon.input-sm {
+  padding: 5px 10px;
+  font-size: 12px;
+  border-radius: 3px;
+}
+.input-group-addon.input-lg {
+  padding: 10px 16px;
+  font-size: 18px;
+  border-radius: 6px;
+}
+.input-group-addon input[type="radio"],
+.input-group-addon input[type="checkbox"] {
+  margin-top: 0;
+}
+.input-group .form-control:first-child,
+.input-group-addon:first-child,
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group > .btn,
+.input-group-btn:first-child > .dropdown-toggle,
+.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.input-group-addon:first-child {
+  border-right: 0;
+}
+.input-group .form-control:last-child,
+.input-group-addon:last-child,
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group > .btn,
+.input-group-btn:last-child > .dropdown-toggle,
+.input-group-btn:first-child > .btn:not(:first-child),
+.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.input-group-addon:last-child {
+  border-left: 0;
+}
+.input-group-btn {
+  position: relative;
+  font-size: 0;
+  white-space: nowrap;
+}
+.input-group-btn > .btn {
+  position: relative;
+}
+.input-group-btn > .btn + .btn {
+  margin-left: -1px;
+}
+.input-group-btn > .btn:hover,
+.input-group-btn > .btn:focus,
+.input-group-btn > .btn:active {
+  z-index: 2;
+}
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group {
+  margin-right: -1px;
+}
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group {
+  margin-left: -1px;
+}
+.nav {
+  padding-left: 0;
+  margin-bottom: 0;
+  list-style: none;
+}
+.nav > li {
+  position: relative;
+  display: block;
+}
+.nav > li > a {
+  position: relative;
+  display: block;
+  padding: 10px 15px;
+}
+.nav > li > a:hover,
+.nav > li > a:focus {
+  text-decoration: none;
+  background-color: #eee;
+}
+.nav > li.disabled > a {
+  color: #999;
+}
+.nav > li.disabled > a:hover,
+.nav > li.disabled > a:focus {
+  color: #999;
+  text-decoration: none;
+  cursor: not-allowed;
+  background-color: transparent;
+}
+.nav .open > a,
+.nav .open > a:hover,
+.nav .open > a:focus {
+  background-color: #eee;
+  border-color: #428bca;
+}
+.nav .nav-divider {
+  height: 1px;
+  margin: 9px 0;
+  overflow: hidden;
+  background-color: #e5e5e5;
+}
+.nav > li > a > img {
+  max-width: none;
+}
+.nav-tabs {
+  border-bottom: 1px solid #ddd;
+}
+.nav-tabs > li {
+  float: left;
+  margin-bottom: -1px;
+}
+.nav-tabs > li > a {
+  margin-right: 2px;
+  line-height: 1.428571429;
+  border: 1px solid transparent;
+  border-radius: 4px 4px 0 0;
+}
+.nav-tabs > li > a:hover {
+  border-color: #eee #eee #ddd;
+}
+.nav-tabs > li.active > a,
+.nav-tabs > li.active > a:hover,
+.nav-tabs > li.active > a:focus {
+  color: #555;
+  cursor: default;
+  background-color: #fff;
+  border: 1px solid #ddd;
+  border-bottom-color: transparent;
+}
+.nav-tabs.nav-justified {
+  width: 100%;
+  border-bottom: 0;
+}
+.nav-tabs.nav-justified > li {
+  float: none;
+}
+.nav-tabs.nav-justified > li > a {
+  margin-bottom: 5px;
+  text-align: center;
+}
+.nav-tabs.nav-justified > .dropdown .dropdown-menu {
+  top: auto;
+  left: auto;
+}
+ at media (min-width: 768px) {
+  .nav-tabs.nav-justified > li {
+    display: table-cell;
+    width: 1%;
+  }
+  .nav-tabs.nav-justified > li > a {
+    margin-bottom: 0;
+  }
+}
+.nav-tabs.nav-justified > li > a {
+  margin-right: 0;
+  border-radius: 4px;
+}
+.nav-tabs.nav-justified > .active > a,
+.nav-tabs.nav-justified > .active > a:hover,
+.nav-tabs.nav-justified > .active > a:focus {
+  border: 1px solid #ddd;
+}
+ at media (min-width: 768px) {
+  .nav-tabs.nav-justified > li > a {
+    border-bottom: 1px solid #ddd;
+    border-radius: 4px 4px 0 0;
+  }
+  .nav-tabs.nav-justified > .active > a,
+  .nav-tabs.nav-justified > .active > a:hover,
+  .nav-tabs.nav-justified > .active > a:focus {
+    border-bottom-color: #fff;
+  }
+}
+.nav-pills > li {
+  float: left;
+}
+.nav-pills > li > a {
+  border-radius: 4px;
+}
+.nav-pills > li + li {
+  margin-left: 2px;
+}
+.nav-pills > li.active > a,
+.nav-pills > li.active > a:hover,
+.nav-pills > li.active > a:focus {
+  color: #fff;
+  background-color: #428bca;
+}
+.nav-stacked > li {
+  float: none;
+}
+.nav-stacked > li + li {
+  margin-top: 2px;
+  margin-left: 0;
+}
+.nav-justified {
+  width: 100%;
+}
+.nav-justified > li {
+  float: none;
+}
+.nav-justified > li > a {
+  margin-bottom: 5px;
+  text-align: center;
+}
+.nav-justified > .dropdown .dropdown-menu {
+  top: auto;
+  left: auto;
+}
+ at media (min-width: 768px) {
+  .nav-justified > li {
+    display: table-cell;
+    width: 1%;
+  }
+  .nav-justified > li > a {
+    margin-bottom: 0;
+  }
+}
+.nav-tabs-justified {
+  border-bottom: 0;
+}
+.nav-tabs-justified > li > a {
+  margin-right: 0;
+  border-radius: 4px;
+}
+.nav-tabs-justified > .active > a,
+.nav-tabs-justified > .active > a:hover,
+.nav-tabs-justified > .active > a:focus {
+  border: 1px solid #ddd;
+}
+ at media (min-width: 768px) {
+  .nav-tabs-justified > li > a {
+    border-bottom: 1px solid #ddd;
+    border-radius: 4px 4px 0 0;
+  }
+  .nav-tabs-justified > .active > a,
+  .nav-tabs-justified > .active > a:hover,
+  .nav-tabs-justified > .active > a:focus {
+    border-bottom-color: #fff;
+  }
+}
+.tab-content > .tab-pane {
+  display: none;
+}
+.tab-content > .active {
+  display: block;
+}
+.nav-tabs .dropdown-menu {
+  margin-top: -1px;
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+}
+.navbar {
+  position: relative;
+  min-height: 50px;
+  margin-bottom: 20px;
+  border: 1px solid transparent;
+}
+ at media (min-width: 768px) {
+  .navbar {
+    border-radius: 4px;
+  }
+}
+ at media (min-width: 768px) {
+  .navbar-header {
+    float: left;
+  }
+}
+.navbar-collapse {
+  max-height: 340px;
+  padding-right: 15px;
+  padding-left: 15px;
+  overflow-x: visible;
+  -webkit-overflow-scrolling: touch;
+  border-top: 1px solid transparent;
+  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+}
+.navbar-collapse.in {
+  overflow-y: auto;
+}
+ at media (min-width: 768px) {
+  .navbar-collapse {
+    width: auto;
+    border-top: 0;
+    box-shadow: none;
+  }
+  .navbar-collapse.collapse {
+    display: block !important;
+    height: auto !important;
+    padding-bottom: 0;
+    overflow: visible !important;
+  }
+  .navbar-collapse.in {
+    overflow-y: visible;
+  }
+  .navbar-fixed-top .navbar-collapse,
+  .navbar-static-top .navbar-collapse,
+  .navbar-fixed-bottom .navbar-collapse {
+    padding-right: 0;
+    padding-left: 0;
+  }
+}
+.container > .navbar-header,
+.container-fluid > .navbar-header,
+.container > .navbar-collapse,
+.container-fluid > .navbar-collapse {
+  margin-right: -15px;
+  margin-left: -15px;
+}
+ at media (min-width: 768px) {
+  .container > .navbar-header,
+  .container-fluid > .navbar-header,
+  .container > .navbar-collapse,
+  .container-fluid > .navbar-collapse {
+    margin-right: 0;
+    margin-left: 0;
+  }
+}
+.navbar-static-top {
+  z-index: 1000;
+  border-width: 0 0 1px;
+}
+ at media (min-width: 768px) {
+  .navbar-static-top {
+    border-radius: 0;
+  }
+}
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+  position: fixed;
+  right: 0;
+  left: 0;
+  z-index: 1030;
+}
+ at media (min-width: 768px) {
+  .navbar-fixed-top,
+  .navbar-fixed-bottom {
+    border-radius: 0;
+  }
+}
+.navbar-fixed-top {
+  top: 0;
+  border-width: 0 0 1px;
+}
+.navbar-fixed-bottom {
+  bottom: 0;
+  margin-bottom: 0;
+  border-width: 1px 0 0;
+}
+.navbar-brand {
+  float: left;
+  height: 20px;
+  padding: 15px 15px;
+  font-size: 18px;
+  line-height: 20px;
+}
+.navbar-brand:hover,
+.navbar-brand:focus {
+  text-decoration: none;
+}
+ at media (min-width: 768px) {
+  .navbar > .container .navbar-brand,
+  .navbar > .container-fluid .navbar-brand {
+    margin-left: -15px;
+  }
+}
+.navbar-toggle {
+  position: relative;
+  float: right;
+  padding: 9px 10px;
+  margin-top: 8px;
+  margin-right: 15px;
+  margin-bottom: 8px;
+  background-color: transparent;
+  background-image: none;
+  border: 1px solid transparent;
+  border-radius: 4px;
+}
+.navbar-toggle:focus {
+  outline: none;
+}
+.navbar-toggle .icon-bar {
+  display: block;
+  width: 22px;
+  height: 2px;
+  border-radius: 1px;
+}
+.navbar-toggle .icon-bar + .icon-bar {
+  margin-top: 4px;
+}
+ at media (min-width: 768px) {
+  .navbar-toggle {
+    display: none;
+  }
+}
+.navbar-nav {
+  margin: 7.5px -15px;
+}
+.navbar-nav > li > a {
+  padding-top: 10px;
+  padding-bottom: 10px;
+  line-height: 20px;
+}
+ at media (max-width: 767px) {
+  .navbar-nav .open .dropdown-menu {
+    position: static;
+    float: none;
+    width: auto;
+    margin-top: 0;
+    background-color: transparent;
+    border: 0;
+    box-shadow: none;
+  }
+  .navbar-nav .open .dropdown-menu > li > a,
+  .navbar-nav .open .dropdown-menu .dropdown-header {
+    padding: 5px 15px 5px 25px;
+  }
+  .navbar-nav .open .dropdown-menu > li > a {
+    line-height: 20px;
+  }
+  .navbar-nav .open .dropdown-menu > li > a:hover,
+  .navbar-nav .open .dropdown-menu > li > a:focus {
+    background-image: none;
+  }
+}
+ at media (min-width: 768px) {
+  .navbar-nav {
+    float: left;
+    margin: 0;
+  }
+  .navbar-nav > li {
+    float: left;
+  }
+  .navbar-nav > li > a {
+    padding-top: 15px;
+    padding-bottom: 15px;
+  }
+  .navbar-nav.navbar-right:last-child {
+    margin-right: -15px;
+  }
+}
+ at media (min-width: 768px) {
+  .navbar-left {
+    float: left !important;
+  }
+  .navbar-right {
+    float: right !important;
+  }
+}
+.navbar-form {
+  padding: 10px 15px;
+  margin-top: 8px;
+  margin-right: -15px;
+  margin-bottom: 8px;
+  margin-left: -15px;
+  border-top: 1px solid transparent;
+  border-bottom: 1px solid transparent;
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
+          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
+}
+ at media (min-width: 768px) {
+  .navbar-form .form-group {
+    display: inline-block;
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .navbar-form .form-control {
+    display: inline-block;
+    width: auto;
+    vertical-align: middle;
+  }
+  .navbar-form .control-label {
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .navbar-form .radio,
+  .navbar-form .checkbox {
+    display: inline-block;
+    padding-left: 0;
+    margin-top: 0;
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .navbar-form .radio input[type="radio"],
+  .navbar-form .checkbox input[type="checkbox"] {
+    float: none;
+    margin-left: 0;
+  }
+  .navbar-form .has-feedback .form-control-feedback {
+    top: 0;
+  }
+}
+ at media (max-width: 767px) {
+  .navbar-form .form-group {
+    margin-bottom: 5px;
+  }
+}
+ at media (min-width: 768px) {
+  .navbar-form {
+    width: auto;
+    padding-top: 0;
+    padding-bottom: 0;
+    margin-right: 0;
+    margin-left: 0;
+    border: 0;
+    -webkit-box-shadow: none;
+            box-shadow: none;
+  }
+  .navbar-form.navbar-right:last-child {
+    margin-right: -15px;
+  }
+}
+.navbar-nav > li > .dropdown-menu {
+  margin-top: 0;
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+}
+.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.navbar-btn {
+  margin-top: 8px;
+  margin-bottom: 8px;
+}
+.navbar-btn.btn-sm {
+  margin-top: 10px;
+  margin-bottom: 10px;
+}
+.navbar-btn.btn-xs {
+  margin-top: 14px;
+  margin-bottom: 14px;
+}
+.navbar-text {
+  margin-top: 15px;
+  margin-bottom: 15px;
+}
+ at media (min-width: 768px) {
+  .navbar-text {
+    float: left;
+    margin-right: 15px;
+    margin-left: 15px;
+  }
+  .navbar-text.navbar-right:last-child {
+    margin-right: 0;
+  }
+}
+.navbar-default {
+  background-color: #f8f8f8;
+  border-color: #e7e7e7;
+}
+.navbar-default .navbar-brand {
+  color: #777;
+}
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus {
+  color: #5e5e5e;
+  background-color: transparent;
+}
+.navbar-default .navbar-text {
+  color: #777;
+}
+.navbar-default .navbar-nav > li > a {
+  color: #777;
+}
+.navbar-default .navbar-nav > li > a:hover,
+.navbar-default .navbar-nav > li > a:focus {
+  color: #333;
+  background-color: transparent;
+}
+.navbar-default .navbar-nav > .active > a,
+.navbar-default .navbar-nav > .active > a:hover,
+.navbar-default .navbar-nav > .active > a:focus {
+  color: #555;
+  background-color: #e7e7e7;
+}
+.navbar-default .navbar-nav > .disabled > a,
+.navbar-default .navbar-nav > .disabled > a:hover,
+.navbar-default .navbar-nav > .disabled > a:focus {
+  color: #ccc;
+  background-color: transparent;
+}
+.navbar-default .navbar-toggle {
+  border-color: #ddd;
+}
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+  background-color: #ddd;
+}
+.navbar-default .navbar-toggle .icon-bar {
+  background-color: #888;
+}
+.navbar-default .navbar-collapse,
+.navbar-default .navbar-form {
+  border-color: #e7e7e7;
+}
+.navbar-default .navbar-nav > .open > a,
+.navbar-default .navbar-nav > .open > a:hover,
+.navbar-default .navbar-nav > .open > a:focus {
+  color: #555;
+  background-color: #e7e7e7;
+}
+ at media (max-width: 767px) {
+  .navbar-default .navbar-nav .open .dropdown-menu > li > a {
+    color: #777;
+  }
+  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
+  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
+    color: #333;
+    background-color: transparent;
+  }
+  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
+  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
+  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
+    color: #555;
+    background-color: #e7e7e7;
+  }
+  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
+  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+    color: #ccc;
+    background-color: transparent;
+  }
+}
+.navbar-default .navbar-link {
+  color: #777;
+}
+.navbar-default .navbar-link:hover {
+  color: #333;
+}
+.navbar-inverse {
+  background-color: #222;
+  border-color: #080808;
+}
+.navbar-inverse .navbar-brand {
+  color: #999;
+}
+.navbar-inverse .navbar-brand:hover,
+.navbar-inverse .navbar-brand:focus {
+  color: #fff;
+  background-color: transparent;
+}
+.navbar-inverse .navbar-text {
+  color: #999;
+}
+.navbar-inverse .navbar-nav > li > a {
+  color: #999;
+}
+.navbar-inverse .navbar-nav > li > a:hover,
+.navbar-inverse .navbar-nav > li > a:focus {
+  color: #fff;
+  background-color: transparent;
+}
+.navbar-inverse .navbar-nav > .active > a,
+.navbar-inverse .navbar-nav > .active > a:hover,
+.navbar-inverse .navbar-nav > .active > a:focus {
+  color: #fff;
+  background-color: #080808;
+}
+.navbar-inverse .navbar-nav > .disabled > a,
+.navbar-inverse .navbar-nav > .disabled > a:hover,
+.navbar-inverse .navbar-nav > .disabled > a:focus {
+  color: #444;
+  background-color: transparent;
+}
+.navbar-inverse .navbar-toggle {
+  border-color: #333;
+}
+.navbar-inverse .navbar-toggle:hover,
+.navbar-inverse .navbar-toggle:focus {
+  background-color: #333;
+}
+.navbar-inverse .navbar-toggle .icon-bar {
+  background-color: #fff;
+}
+.navbar-inverse .navbar-collapse,
+.navbar-inverse .navbar-form {
+  border-color: #101010;
+}
+.navbar-inverse .navbar-nav > .open > a,
+.navbar-inverse .navbar-nav > .open > a:hover,
+.navbar-inverse .navbar-nav > .open > a:focus {
+  color: #fff;
+  background-color: #080808;
+}
+ at media (max-width: 767px) {
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
+    border-color: #080808;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
+    background-color: #080808;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
+    color: #999;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
+    color: #fff;
+    background-color: transparent;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
+    color: #fff;
+    background-color: #080808;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+    color: #444;
+    background-color: transparent;
+  }
+}
+.navbar-inverse .navbar-link {
+  color: #999;
+}
+.navbar-inverse .navbar-link:hover {
+  color: #fff;
+}
+.breadcrumb {
+  padding: 8px 15px;
+  margin-bottom: 20px;
+  list-style: none;
+  background-color: #f5f5f5;
+  border-radius: 4px;
+}
+.breadcrumb > li {
+  display: inline-block;
+}
+.breadcrumb > li + li:before {
+  padding: 0 5px;
+  color: #ccc;
+  content: "/\00a0";
+}
+.breadcrumb > .active {
+  color: #999;
+}
+.pagination {
+  display: inline-block;
+  padding-left: 0;
+  margin: 20px 0;
+  border-radius: 4px;
+}
+.pagination > li {
+  display: inline;
+}
+.pagination > li > a,
+.pagination > li > span {
+  position: relative;
+  float: left;
+  padding: 6px 12px;
+  margin-left: -1px;
+  line-height: 1.428571429;
+  color: #428bca;
+  text-decoration: none;
+  background-color: #fff;
+  border: 1px solid #ddd;
+}
+.pagination > li:first-child > a,
+.pagination > li:first-child > span {
+  margin-left: 0;
+  border-top-left-radius: 4px;
+  border-bottom-left-radius: 4px;
+}
+.pagination > li:last-child > a,
+.pagination > li:last-child > span {
+  border-top-right-radius: 4px;
+  border-bottom-right-radius: 4px;
+}
+.pagination > li > a:hover,
+.pagination > li > span:hover,
+.pagination > li > a:focus,
+.pagination > li > span:focus {
+  color: #2a6496;
+  background-color: #eee;
+  border-color: #ddd;
+}
+.pagination > .active > a,
+.pagination > .active > span,
+.pagination > .active > a:hover,
+.pagination > .active > span:hover,
+.pagination > .active > a:focus,
+.pagination > .active > span:focus {
+  z-index: 2;
+  color: #fff;
+  cursor: default;
+  background-color: #428bca;
+  border-color: #428bca;
+}
+.pagination > .disabled > span,
+.pagination > .disabled > span:hover,
+.pagination > .disabled > span:focus,
+.pagination > .disabled > a,
+.pagination > .disabled > a:hover,
+.pagination > .disabled > a:focus {
+  color: #999;
+  cursor: not-allowed;
+  background-color: #fff;
+  border-color: #ddd;
+}
+.pagination-lg > li > a,
+.pagination-lg > li > span {
+  padding: 10px 16px;
+  font-size: 18px;
+}
+.pagination-lg > li:first-child > a,
+.pagination-lg > li:first-child > span {
+  border-top-left-radius: 6px;
+  border-bottom-left-radius: 6px;
+}
+.pagination-lg > li:last-child > a,
+.pagination-lg > li:last-child > span {
+  border-top-right-radius: 6px;
+  border-bottom-right-radius: 6px;
+}
+.pagination-sm > li > a,
+.pagination-sm > li > span {
+  padding: 5px 10px;
+  font-size: 12px;
+}
+.pagination-sm > li:first-child > a,
+.pagination-sm > li:first-child > span {
+  border-top-left-radius: 3px;
+  border-bottom-left-radius: 3px;
+}
+.pagination-sm > li:last-child > a,
+.pagination-sm > li:last-child > span {
+  border-top-right-radius: 3px;
+  border-bottom-right-radius: 3px;
+}
+.pager {
+  padding-left: 0;
+  margin: 20px 0;
+  text-align: center;
+  list-style: none;
+}
+.pager li {
+  display: inline;
+}
+.pager li > a,
+.pager li > span {
+  display: inline-block;
+  padding: 5px 14px;
+  background-color: #fff;
+  border: 1px solid #ddd;
+  border-radius: 15px;
+}
+.pager li > a:hover,
+.pager li > a:focus {
+  text-decoration: none;
+  background-color: #eee;
+}
+.pager .next > a,
+.pager .next > span {
+  float: right;
+}
+.pager .previous > a,
+.pager .previous > span {
+  float: left;
+}
+.pager .disabled > a,
+.pager .disabled > a:hover,
+.pager .disabled > a:focus,
+.pager .disabled > span {
+  color: #999;
+  cursor: not-allowed;
+  background-color: #fff;
+}
+.label {
+  display: inline;
+  padding: .2em .6em .3em;
+  font-size: 75%;
+  font-weight: bold;
+  line-height: 1;
+  color: #fff;
+  text-align: center;
+  white-space: nowrap;
+  vertical-align: baseline;
+  border-radius: .25em;
+}
+.label[href]:hover,
+.label[href]:focus {
+  color: #fff;
+  text-decoration: none;
+  cursor: pointer;
+}
+.label:empty {
+  display: none;
+}
+.btn .label {
+  position: relative;
+  top: -1px;
+}
+.label-default {
+  background-color: #999;
+}
+.label-default[href]:hover,
+.label-default[href]:focus {
+  background-color: #808080;
+}
+.label-primary {
+  background-color: #428bca;
+}
+.label-primary[href]:hover,
+.label-primary[href]:focus {
+  background-color: #3071a9;
+}
+.label-success {
+  background-color: #5cb85c;
+}
+.label-success[href]:hover,
+.label-success[href]:focus {
+  background-color: #449d44;
+}
+.label-info {
+  background-color: #5bc0de;
+}
+.label-info[href]:hover,
+.label-info[href]:focus {
+  background-color: #31b0d5;
+}
+.label-warning {
+  background-color: #f0ad4e;
+}
+.label-warning[href]:hover,
+.label-warning[href]:focus {
+  background-color: #ec971f;
+}
+.label-danger {
+  background-color: #d9534f;
+}
+.label-danger[href]:hover,
+.label-danger[href]:focus {
+  background-color: #c9302c;
+}
+.badge {
+  display: inline-block;
+  min-width: 10px;
+  padding: 3px 7px;
+  font-size: 12px;
+  font-weight: bold;
+  line-height: 1;
+  color: #fff;
+  text-align: center;
+  white-space: nowrap;
+  vertical-align: baseline;
+  background-color: #999;
+  border-radius: 10px;
+}
+.badge:empty {
+  display: none;
+}
+.btn .badge {
+  position: relative;
+  top: -1px;
+}
+.btn-xs .badge {
+  top: 0;
+  padding: 1px 5px;
+}
+a.badge:hover,
+a.badge:focus {
+  color: #fff;
+  text-decoration: none;
+  cursor: pointer;
+}
+a.list-group-item.active > .badge,
+.nav-pills > .active > a > .badge {
+  color: #428bca;
+  background-color: #fff;
+}
+.nav-pills > li > a > .badge {
+  margin-left: 3px;
+}
+.jumbotron {
+  padding: 30px;
+  margin-bottom: 30px;
+  color: inherit;
+  background-color: #eee;
+}
+.jumbotron h1,
+.jumbotron .h1 {
+  color: inherit;
+}
+.jumbotron p {
+  margin-bottom: 15px;
+  font-size: 21px;
+  font-weight: 200;
+}
+.container .jumbotron {
+  border-radius: 6px;
+}
+.jumbotron .container {
+  max-width: 100%;
+}
+ at media screen and (min-width: 768px) {
+  .jumbotron {
+    padding-top: 48px;
+    padding-bottom: 48px;
+  }
+  .container .jumbotron {
+    padding-right: 60px;
+    padding-left: 60px;
+  }
+  .jumbotron h1,
+  .jumbotron .h1 {
+    font-size: 63px;
+  }
+}
+.thumbnail {
+  display: block;
+  padding: 4px;
+  margin-bottom: 20px;
+  line-height: 1.428571429;
+  background-color: #fff;
+  border: 1px solid #ddd;
+  border-radius: 4px;
+  -webkit-transition: all .2s ease-in-out;
+          transition: all .2s ease-in-out;
+}
+.thumbnail > img,
+.thumbnail a > img {
+  display: block;
+  max-width: 100%;
+  height: auto;
+  margin-right: auto;
+  margin-left: auto;
+}
+a.thumbnail:hover,
+a.thumbnail:focus,
+a.thumbnail.active {
+  border-color: #428bca;
+}
+.thumbnail .caption {
+  padding: 9px;
+  color: #333;
+}
+.alert {
+  padding: 15px;
+  margin-bottom: 20px;
+  border: 1px solid transparent;
+  border-radius: 4px;
+}
+.alert h4 {
+  margin-top: 0;
+  color: inherit;
+}
+.alert .alert-link {
+  font-weight: bold;
+}
+.alert > p,
+.alert > ul {
+  margin-bottom: 0;
+}
+.alert > p + p {
+  margin-top: 5px;
+}
+.alert-dismissable {
+  padding-right: 35px;
+}
+.alert-dismissable .close {
+  position: relative;
+  top: -2px;
+  right: -21px;
+  color: inherit;
+}
+.alert-success {
+  color: #3c763d;
+  background-color: #dff0d8;
+  border-color: #d6e9c6;
+}
+.alert-success hr {
+  border-top-color: #c9e2b3;
+}
+.alert-success .alert-link {
+  color: #2b542c;
+}
+.alert-info {
+  color: #31708f;
+  background-color: #d9edf7;
+  border-color: #bce8f1;
+}
+.alert-info hr {
+  border-top-color: #a6e1ec;
+}
+.alert-info .alert-link {
+  color: #245269;
+}
+.alert-warning {
+  color: #8a6d3b;
+  background-color: #fcf8e3;
+  border-color: #faebcc;
+}
+.alert-warning hr {
+  border-top-color: #f7e1b5;
+}
+.alert-warning .alert-link {
+  color: #66512c;
+}
+.alert-danger {
+  color: #a94442;
+  background-color: #f2dede;
+  border-color: #ebccd1;
+}
+.alert-danger hr {
+  border-top-color: #e4b9c0;
+}
+.alert-danger .alert-link {
+  color: #843534;
+}
+ at -webkit-keyframes progress-bar-stripes {
+  from {
+    background-position: 40px 0;
+  }
+  to {
+    background-position: 0 0;
+  }
+}
+ at keyframes progress-bar-stripes {
+  from {
+    background-position: 40px 0;
+  }
+  to {
+    background-position: 0 0;
+  }
+}
+.progress {
+  height: 20px;
+  margin-bottom: 20px;
+  overflow: hidden;
+  background-color: #f5f5f5;
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+          box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+}
+.progress-bar {
+  float: left;
+  width: 0;
+  height: 100%;
+  font-size: 12px;
+  line-height: 20px;
+  color: #fff;
+  text-align: center;
+  background-color: #428bca;
+  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+  -webkit-transition: width .6s ease;
+          transition: width .6s ease;
+}
+.progress-striped .progress-bar {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+  background-size: 40px 40px;
+}
+.progress.active .progress-bar {
+  -webkit-animation: progress-bar-stripes 2s linear infinite;
+          animation: progress-bar-stripes 2s linear infinite;
+}
+.progress-bar-success {
+  background-color: #5cb85c;
+}
+.progress-striped .progress-bar-success {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-info {
+  background-color: #5bc0de;
+}
+.progress-striped .progress-bar-info {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-warning {
+  background-color: #f0ad4e;
+}
+.progress-striped .progress-bar-warning {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-danger {
+  background-color: #d9534f;
+}
+.progress-striped .progress-bar-danger {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.media,
+.media-body {
+  overflow: hidden;
+  zoom: 1;
+}
+.media,
+.media .media {
+  margin-top: 15px;
+}
+.media:first-child {
+  margin-top: 0;
+}
+.media-object {
+  display: block;
+}
+.media-heading {
+  margin: 0 0 5px;
+}
+.media > .pull-left {
+  margin-right: 10px;
+}
+.media > .pull-right {
+  margin-left: 10px;
+}
+.media-list {
+  padding-left: 0;
+  list-style: none;
+}
+.list-group {
+  padding-left: 0;
+  margin-bottom: 20px;
+}
+.list-group-item {
+  position: relative;
+  display: block;
+  padding: 10px 15px;
+  margin-bottom: -1px;
+  background-color: #fff;
+  border: 1px solid #ddd;
+}
+.list-group-item:first-child {
+  border-top-left-radius: 4px;
+  border-top-right-radius: 4px;
+}
+.list-group-item:last-child {
+  margin-bottom: 0;
+  border-bottom-right-radius: 4px;
+  border-bottom-left-radius: 4px;
+}
+.list-group-item > .badge {
+  float: right;
+}
+.list-group-item > .badge + .badge {
+  margin-right: 5px;
+}
+a.list-group-item {
+  color: #555;
+}
+a.list-group-item .list-group-item-heading {
+  color: #333;
+}
+a.list-group-item:hover,
+a.list-group-item:focus {
+  text-decoration: none;
+  background-color: #f5f5f5;
+}
+a.list-group-item.active,
+a.list-group-item.active:hover,
+a.list-group-item.active:focus {
+  z-index: 2;
+  color: #fff;
+  background-color: #428bca;
+  border-color: #428bca;
+}
+a.list-group-item.active .list-group-item-heading,
+a.list-group-item.active:hover .list-group-item-heading,
+a.list-group-item.active:focus .list-group-item-heading {
+  color: inherit;
+}
+a.list-group-item.active .list-group-item-text,
+a.list-group-item.active:hover .list-group-item-text,
+a.list-group-item.active:focus .list-group-item-text {
+  color: #e1edf7;
+}
+.list-group-item-success {
+  color: #3c763d;
+  background-color: #dff0d8;
+}
+a.list-group-item-success {
+  color: #3c763d;
+}
+a.list-group-item-success .list-group-item-heading {
+  color: inherit;
+}
+a.list-group-item-success:hover,
+a.list-group-item-success:focus {
+  color: #3c763d;
+  background-color: #d0e9c6;
+}
+a.list-group-item-success.active,
+a.list-group-item-success.active:hover,
+a.list-group-item-success.active:focus {
+  color: #fff;
+  background-color: #3c763d;
+  border-color: #3c763d;
+}
+.list-group-item-info {
+  color: #31708f;
+  background-color: #d9edf7;
+}
+a.list-group-item-info {
+  color: #31708f;
+}
+a.list-group-item-info .list-group-item-heading {
+  color: inherit;
+}
+a.list-group-item-info:hover,
+a.list-group-item-info:focus {
+  color: #31708f;
+  background-color: #c4e3f3;
+}
+a.list-group-item-info.active,
+a.list-group-item-info.active:hover,
+a.list-group-item-info.active:focus {
+  color: #fff;
+  background-color: #31708f;
+  border-color: #31708f;
+}
+.list-group-item-warning {
+  color: #8a6d3b;
+  background-color: #fcf8e3;
+}
+a.list-group-item-warning {
+  color: #8a6d3b;
+}
+a.list-group-item-warning .list-group-item-heading {
+  color: inherit;
+}
+a.list-group-item-warning:hover,
+a.list-group-item-warning:focus {
+  color: #8a6d3b;
+  background-color: #faf2cc;
+}
+a.list-group-item-warning.active,
+a.list-group-item-warning.active:hover,
+a.list-group-item-warning.active:focus {
+  color: #fff;
+  background-color: #8a6d3b;
+  border-color: #8a6d3b;
+}
+.list-group-item-danger {
+  color: #a94442;
+  background-color: #f2dede;
+}
+a.list-group-item-danger {
+  color: #a94442;
+}
+a.list-group-item-danger .list-group-item-heading {
+  color: inherit;
+}
+a.list-group-item-danger:hover,
+a.list-group-item-danger:focus {
+  color: #a94442;
+  background-color: #ebcccc;
+}
+a.list-group-item-danger.active,
+a.list-group-item-danger.active:hover,
+a.list-group-item-danger.active:focus {
+  color: #fff;
+  background-color: #a94442;
+  border-color: #a94442;
+}
+.list-group-item-heading {
+  margin-top: 0;
+  margin-bottom: 5px;
+}
+.list-group-item-text {
+  margin-bottom: 0;
+  line-height: 1.3;
+}
+.panel {
+  margin-bottom: 20px;
+  background-color: #fff;
+  border: 1px solid transparent;
+  border-radius: 4px;
+  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+          box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+}
+.panel-body {
+  padding: 15px;
+}
+.panel > .list-group {
+  margin-bottom: 0;
+}
+.panel > .list-group .list-group-item {
+  border-width: 1px 0;
+  border-radius: 0;
+}
+.panel > .list-group .list-group-item:first-child {
+  border-top: 0;
+}
+.panel > .list-group .list-group-item:last-child {
+  border-bottom: 0;
+}
+.panel > .list-group:first-child .list-group-item:first-child {
+  border-top-left-radius: 3px;
+  border-top-right-radius: 3px;
+}
+.panel > .list-group:last-child .list-group-item:last-child {
+  border-bottom-right-radius: 3px;
+  border-bottom-left-radius: 3px;
+}
+.panel-heading + .list-group .list-group-item:first-child {
+  border-top-width: 0;
+}
+.panel > .table,
+.panel > .table-responsive > .table {
+  margin-bottom: 0;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
+  border-top-left-radius: 3px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
+  border-top-right-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
+  border-bottom-left-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
+  border-bottom-right-radius: 3px;
+}
+.panel > .panel-body + .table,
+.panel > .panel-body + .table-responsive {
+  border-top: 1px solid #ddd;
+}
+.panel > .table > tbody:first-child > tr:first-child th,
+.panel > .table > tbody:first-child > tr:first-child td {
+  border-top: 0;
+}
+.panel > .table-bordered,
+.panel > .table-responsive > .table-bordered {
+  border: 0;
+}
+.panel > .table-bordered > thead > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
+.panel > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-bordered > thead > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
+.panel > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-bordered > tfoot > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+  border-left: 0;
+}
+.panel > .table-bordered > thead > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
+.panel > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-bordered > thead > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
+.panel > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-bordered > tfoot > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+  border-right: 0;
+}
+.panel > .table-bordered > thead > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
+.panel > .table-bordered > tbody > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th,
+.panel > .table-bordered > tfoot > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > tfoot > tr:first-child > th,
+.panel > .table-bordered > thead > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
+.panel > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-bordered > tfoot > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > tfoot > tr:first-child > td {
+  border-top: 0;
+}
+.panel > .table-bordered > thead > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > thead > tr:last-child > th,
+.panel > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-bordered > tfoot > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+.panel > .table-bordered > thead > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > thead > tr:last-child > td,
+.panel > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+  border-bottom: 0;
+}
+.panel > .table-responsive {
+  margin-bottom: 0;
+  border: 0;
+}
+.panel-heading {
+  padding: 10px 15px;
+  border-bottom: 1px solid transparent;
+  border-top-left-radius: 3px;
+  border-top-right-radius: 3px;
+}
+.panel-heading > .dropdown .dropdown-toggle {
+  color: inherit;
+}
+.panel-title {
+  margin-top: 0;
+  margin-bottom: 0;
+  font-size: 16px;
+  color: inherit;
+}
+.panel-title > a {
+  color: inherit;
+}
+.panel-footer {
+  padding: 10px 15px;
+  background-color: #f5f5f5;
+  border-top: 1px solid #ddd;
+  border-bottom-right-radius: 3px;
+  border-bottom-left-radius: 3px;
+}
+.panel-group {
+  margin-bottom: 20px;
+}
+.panel-group .panel {
+  margin-bottom: 0;
+  overflow: hidden;
+  border-radius: 4px;
+}
+.panel-group .panel + .panel {
+  margin-top: 5px;
+}
+.panel-group .panel-heading {
+  border-bottom: 0;
+}
+.panel-group .panel-heading + .panel-collapse .panel-body {
+  border-top: 1px solid #ddd;
+}
+.panel-group .panel-footer {
+  border-top: 0;
+}
+.panel-group .panel-footer + .panel-collapse .panel-body {
+  border-bottom: 1px solid #ddd;
+}
+.panel-default {
+  border-color: #ddd;
+}
+.panel-default > .panel-heading {
+  color: #333;
+  background-color: #f5f5f5;
+  border-color: #ddd;
+}
+.panel-default > .panel-heading + .panel-collapse .panel-body {
+  border-top-color: #ddd;
+}
+.panel-default > .panel-footer + .panel-collapse .panel-body {
+  border-bottom-color: #ddd;
+}
+.panel-primary {
+  border-color: #428bca;
+}
+.panel-primary > .panel-heading {
+  color: #fff;
+  background-color: #428bca;
+  border-color: #428bca;
+}
+.panel-primary > .panel-heading + .panel-collapse .panel-body {
+  border-top-color: #428bca;
+}
+.panel-primary > .panel-footer + .panel-collapse .panel-body {
+  border-bottom-color: #428bca;
+}
+.panel-success {
+  border-color: #d6e9c6;
+}
+.panel-success > .panel-heading {
+  color: #3c763d;
+  background-color: #dff0d8;
+  border-color: #d6e9c6;
+}
+.panel-success > .panel-heading + .panel-collapse .panel-body {
+  border-top-color: #d6e9c6;
+}
+.panel-success > .panel-footer + .panel-collapse .panel-body {
+  border-bottom-color: #d6e9c6;
+}
+.panel-info {
+  border-color: #bce8f1;
+}
+.panel-info > .panel-heading {
+  color: #31708f;
+  background-color: #d9edf7;
+  border-color: #bce8f1;
+}
+.panel-info > .panel-heading + .panel-collapse .panel-body {
+  border-top-color: #bce8f1;
+}
+.panel-info > .panel-footer + .panel-collapse .panel-body {
+  border-bottom-color: #bce8f1;
+}
+.panel-warning {
+  border-color: #faebcc;
+}
+.panel-warning > .panel-heading {
+  color: #8a6d3b;
+  background-color: #fcf8e3;
+  border-color: #faebcc;
+}
+.panel-warning > .panel-heading + .panel-collapse .panel-body {
+  border-top-color: #faebcc;
+}
+.panel-warning > .panel-footer + .panel-collapse .panel-body {
+  border-bottom-color: #faebcc;
+}
+.panel-danger {
+  border-color: #ebccd1;
+}
+.panel-danger > .panel-heading {
+  color: #a94442;
+  background-color: #f2dede;
+  border-color: #ebccd1;
+}
+.panel-danger > .panel-heading + .panel-collapse .panel-body {
+  border-top-color: #ebccd1;
+}
+.panel-danger > .panel-footer + .panel-collapse .panel-body {
+  border-bottom-color: #ebccd1;
+}
+.well {
+  min-height: 20px;
+  padding: 19px;
+  margin-bottom: 20px;
+  background-color: #f5f5f5;
+  border: 1px solid #e3e3e3;
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+}
+.well blockquote {
+  border-color: #ddd;
+  border-color: rgba(0, 0, 0, .15);
+}
+.well-lg {
+  padding: 24px;
+  border-radius: 6px;
+}
+.well-sm {
+  padding: 9px;
+  border-radius: 3px;
+}
+.close {
+  float: right;
+  font-size: 21px;
+  font-weight: bold;
+  line-height: 1;
+  color: #000;
+  text-shadow: 0 1px 0 #fff;
+  filter: alpha(opacity=20);
+  opacity: .2;
+}
+.close:hover,
+.close:focus {
+  color: #000;
+  text-decoration: none;
+  cursor: pointer;
+  filter: alpha(opacity=50);
+  opacity: .5;
+}
+button.close {
+  -webkit-appearance: none;
+  padding: 0;
+  cursor: pointer;
+  background: transparent;
+  border: 0;
+}
+.modal-open {
+  overflow: hidden;
+}
+.modal {
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 1050;
+  display: none;
+  overflow: auto;
+  overflow-y: scroll;
+  -webkit-overflow-scrolling: touch;
+  outline: 0;
+}
+.modal.fade .modal-dialog {
+  -webkit-transition: -webkit-transform .3s ease-out;
+     -moz-transition:    -moz-transform .3s ease-out;
+       -o-transition:      -o-transform .3s ease-out;
+          transition:         transform .3s ease-out;
+  -webkit-transform: translate(0, -25%);
+      -ms-transform: translate(0, -25%);
+          transform: translate(0, -25%);
+}
+.modal.in .modal-dialog {
+  -webkit-transform: translate(0, 0);
+      -ms-transform: translate(0, 0);
+          transform: translate(0, 0);
+}
+.modal-dialog {
+  position: relative;
+  width: auto;
+  margin: 10px;
+}
+.modal-content {
+  position: relative;
+  background-color: #fff;
+  background-clip: padding-box;
+  border: 1px solid #999;
+  border: 1px solid rgba(0, 0, 0, .2);
+  border-radius: 6px;
+  outline: none;
+  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+          box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+}
+.modal-backdrop {
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 1040;
+  background-color: #000;
+}
+.modal-backdrop.fade {
+  filter: alpha(opacity=0);
+  opacity: 0;
+}
+.modal-backdrop.in {
+  filter: alpha(opacity=50);
+  opacity: .5;
+}
+.modal-header {
+  min-height: 16.428571429px;
+  padding: 15px;
+  border-bottom: 1px solid #e5e5e5;
+}
+.modal-header .close {
+  margin-top: -2px;
+}
+.modal-title {
+  margin: 0;
+  line-height: 1.428571429;
+}
+.modal-body {
+  position: relative;
+  padding: 20px;
+}
+.modal-footer {
+  padding: 19px 20px 20px;
+  margin-top: 15px;
+  text-align: right;
+  border-top: 1px solid #e5e5e5;
+}
+.modal-footer .btn + .btn {
+  margin-bottom: 0;
+  margin-left: 5px;
+}
+.modal-footer .btn-group .btn + .btn {
+  margin-left: -1px;
+}
+.modal-footer .btn-block + .btn-block {
+  margin-left: 0;
+}
+ at media (min-width: 768px) {
+  .modal-dialog {
+    width: 600px;
+    margin: 30px auto;
+  }
+  .modal-content {
+    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+            box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+  }
+  .modal-sm {
+    width: 300px;
+  }
+  .modal-lg {
+    width: 900px;
+  }
+}
+.tooltip {
+  position: absolute;
+  z-index: 1030;
+  display: block;
+  font-size: 12px;
+  line-height: 1.4;
+  visibility: visible;
+  filter: alpha(opacity=0);
+  opacity: 0;
+}
+.tooltip.in {
+  filter: alpha(opacity=90);
+  opacity: .9;
+}
+.tooltip.top {
+  padding: 5px 0;
+  margin-top: -3px;
+}
+.tooltip.right {
+  padding: 0 5px;
+  margin-left: 3px;
+}
+.tooltip.bottom {
+  padding: 5px 0;
+  margin-top: 3px;
+}
+.tooltip.left {
+  padding: 0 5px;
+  margin-left: -3px;
+}
+.tooltip-inner {
+  max-width: 200px;
+  padding: 3px 8px;
+  color: #fff;
+  text-align: center;
+  text-decoration: none;
+  background-color: #000;
+  border-radius: 4px;
+}
+.tooltip-arrow {
+  position: absolute;
+  width: 0;
+  height: 0;
+  border-color: transparent;
+  border-style: solid;
+}
+.tooltip.top .tooltip-arrow {
+  bottom: 0;
+  left: 50%;
+  margin-left: -5px;
+  border-width: 5px 5px 0;
+  border-top-color: #000;
+}
+.tooltip.top-left .tooltip-arrow {
+  bottom: 0;
+  left: 5px;
+  border-width: 5px 5px 0;
+  border-top-color: #000;
+}
+.tooltip.top-right .tooltip-arrow {
+  right: 5px;
+  bottom: 0;
+  border-width: 5px 5px 0;
+  border-top-color: #000;
+}
+.tooltip.right .tooltip-arrow {
+  top: 50%;
+  left: 0;
+  margin-top: -5px;
+  border-width: 5px 5px 5px 0;
+  border-right-color: #000;
+}
+.tooltip.left .tooltip-arrow {
+  top: 50%;
+  right: 0;
+  margin-top: -5px;
+  border-width: 5px 0 5px 5px;
+  border-left-color: #000;
+}
+.tooltip.bottom .tooltip-arrow {
+  top: 0;
+  left: 50%;
+  margin-left: -5px;
+  border-width: 0 5px 5px;
+  border-bottom-color: #000;
+}
+.tooltip.bottom-left .tooltip-arrow {
+  top: 0;
+  left: 5px;
+  border-width: 0 5px 5px;
+  border-bottom-color: #000;
+}
+.tooltip.bottom-right .tooltip-arrow {
+  top: 0;
+  right: 5px;
+  border-width: 0 5px 5px;
+  border-bottom-color: #000;
+}
+.popover {
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 1010;
+  display: none;
+  max-width: 276px;
+  padding: 1px;
+  text-align: left;
+  white-space: normal;
+  background-color: #fff;
+  background-clip: padding-box;
+  border: 1px solid #ccc;
+  border: 1px solid rgba(0, 0, 0, .2);
+  border-radius: 6px;
+  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+          box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+}
+.popover.top {
+  margin-top: -10px;
+}
+.popover.right {
+  margin-left: 10px;
+}
+.popover.bottom {
+  margin-top: 10px;
+}
+.popover.left {
+  margin-left: -10px;
+}
+.popover-title {
+  padding: 8px 14px;
+  margin: 0;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 18px;
+  background-color: #f7f7f7;
+  border-bottom: 1px solid #ebebeb;
+  border-radius: 5px 5px 0 0;
+}
+.popover-content {
+  padding: 9px 14px;
+}
+.popover .arrow,
+.popover .arrow:after {
+  position: absolute;
+  display: block;
+  width: 0;
+  height: 0;
+  border-color: transparent;
+  border-style: solid;
+}
+.popover .arrow {
+  border-width: 11px;
+}
+.popover .arrow:after {
+  content: "";
+  border-width: 10px;
+}
+.popover.top .arrow {
+  bottom: -11px;
+  left: 50%;
+  margin-left: -11px;
+  border-top-color: #999;
+  border-top-color: rgba(0, 0, 0, .25);
+  border-bottom-width: 0;
+}
+.popover.top .arrow:after {
+  bottom: 1px;
+  margin-left: -10px;
+  content: " ";
+  border-top-color: #fff;
+  border-bottom-width: 0;
+}
+.popover.right .arrow {
+  top: 50%;
+  left: -11px;
+  margin-top: -11px;
+  border-right-color: #999;
+  border-right-color: rgba(0, 0, 0, .25);
+  border-left-width: 0;
+}
+.popover.right .arrow:after {
+  bottom: -10px;
+  left: 1px;
+  content: " ";
+  border-right-color: #fff;
+  border-left-width: 0;
+}
+.popover.bottom .arrow {
+  top: -11px;
+  left: 50%;
+  margin-left: -11px;
+  border-top-width: 0;
+  border-bottom-color: #999;
+  border-bottom-color: rgba(0, 0, 0, .25);
+}
+.popover.bottom .arrow:after {
+  top: 1px;
+  margin-left: -10px;
+  content: " ";
+  border-top-width: 0;
+  border-bottom-color: #fff;
+}
+.popover.left .arrow {
+  top: 50%;
+  right: -11px;
+  margin-top: -11px;
+  border-right-width: 0;
+  border-left-color: #999;
+  border-left-color: rgba(0, 0, 0, .25);
+}
+.popover.left .arrow:after {
+  right: 1px;
+  bottom: -10px;
+  content: " ";
+  border-right-width: 0;
+  border-left-color: #fff;
+}
+.carousel {
+  position: relative;
+}
+.carousel-inner {
+  position: relative;
+  width: 100%;
+  overflow: hidden;
+}
+.carousel-inner > .item {
+  position: relative;
+  display: none;
+  -webkit-transition: .6s ease-in-out left;
+          transition: .6s ease-in-out left;
+}
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+  display: block;
+  max-width: 100%;
+  height: auto;
+  line-height: 1;
+}
+.carousel-inner > .active,
+.carousel-inner > .next,
+.carousel-inner > .prev {
+  display: block;
+}
+.carousel-inner > .active {
+  left: 0;
+}
+.carousel-inner > .next,
+.carousel-inner > .prev {
+  position: absolute;
+  top: 0;
+  width: 100%;
+}
+.carousel-inner > .next {
+  left: 100%;
+}
+.carousel-inner > .prev {
+  left: -100%;
+}
+.carousel-inner > .next.left,
+.carousel-inner > .prev.right {
+  left: 0;
+}
+.carousel-inner > .active.left {
+  left: -100%;
+}
+.carousel-inner > .active.right {
+  left: 100%;
+}
+.carousel-control {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  width: 15%;
+  font-size: 20px;
+  color: #fff;
+  text-align: center;
+  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
+  filter: alpha(opacity=50);
+  opacity: .5;
+}
+.carousel-control.left {
+  background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, .5) 0%), color-stop(rgba(0, 0, 0, .0001) 100%));
+  background-image:         linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
+  background-repeat: repeat-x;
+}
+.carousel-control.right {
+  right: 0;
+  left: auto;
+  background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, .0001) 0%), color-stop(rgba(0, 0, 0, .5) 100%));
+  background-image:         linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
+  background-repeat: repeat-x;
+}
+.carousel-control:hover,
+.carousel-control:focus {
+  color: #fff;
+  text-decoration: none;
+  filter: alpha(opacity=90);
+  outline: none;
+  opacity: .9;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-left,
+.carousel-control .glyphicon-chevron-right {
+  position: absolute;
+  top: 50%;
+  z-index: 5;
+  display: inline-block;
+}
+.carousel-control .icon-prev,
+.carousel-control .glyphicon-chevron-left {
+  left: 50%;
+}
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-right {
+  right: 50%;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next {
+  width: 20px;
+  height: 20px;
+  margin-top: -10px;
+  margin-left: -10px;
+  font-family: serif;
+}
+.carousel-control .icon-prev:before {
+  content: '\2039';
+}
+.carousel-control .icon-next:before {
+  content: '\203a';
+}
+.carousel-indicators {
+  position: absolute;
+  bottom: 10px;
+  left: 50%;
+  z-index: 15;
+  width: 60%;
+  padding-left: 0;
+  margin-left: -30%;
+  text-align: center;
+  list-style: none;
+}
+.carousel-indicators li {
+  display: inline-block;
+  width: 10px;
+  height: 10px;
+  margin: 1px;
+  text-indent: -999px;
+  cursor: pointer;
+  background-color: #000 \9;
+  background-color: rgba(0, 0, 0, 0);
+  border: 1px solid #fff;
+  border-radius: 10px;
+}
+.carousel-indicators .active {
+  width: 12px;
+  height: 12px;
+  margin: 0;
+  background-color: #fff;
+}
+.carousel-caption {
+  position: absolute;
+  right: 15%;
+  bottom: 20px;
+  left: 15%;
+  z-index: 10;
+  padding-top: 20px;
+  padding-bottom: 20px;
+  color: #fff;
+  text-align: center;
+  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
+}
+.carousel-caption .btn {
+  text-shadow: none;
+}
+ at media screen and (min-width: 768px) {
+  .carousel-control .glyphicons-chevron-left,
+  .carousel-control .glyphicons-chevron-right,
+  .carousel-control .icon-prev,
+  .carousel-control .icon-next {
+    width: 30px;
+    height: 30px;
+    margin-top: -15px;
+    margin-left: -15px;
+    font-size: 30px;
+  }
+  .carousel-caption {
+    right: 20%;
+    left: 20%;
+    padding-bottom: 30px;
+  }
+  .carousel-indicators {
+    bottom: 20px;
+  }
+}
+.clearfix:before,
+.clearfix:after,
+.container:before,
+.container:after,
+.container-fluid:before,
+.container-fluid:after,
+.row:before,
+.row:after,
+.form-horizontal .form-group:before,
+.form-horizontal .form-group:after,
+.btn-toolbar:before,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:before,
+.btn-group-vertical > .btn-group:after,
+.nav:before,
+.nav:after,
+.navbar:before,
+.navbar:after,
+.navbar-header:before,
+.navbar-header:after,
+.navbar-collapse:before,
+.navbar-collapse:after,
+.pager:before,
+.pager:after,
+.panel-body:before,
+.panel-body:after,
+.modal-footer:before,
+.modal-footer:after {
+  display: table;
+  content: " ";
+}
+.clearfix:after,
+.container:after,
+.container-fluid:after,
+.row:after,
+.form-horizontal .form-group:after,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:after,
+.nav:after,
+.navbar:after,
+.navbar-header:after,
+.navbar-collapse:after,
+.pager:after,
+.panel-body:after,
+.modal-footer:after {
+  clear: both;
+}
+.center-block {
+  display: block;
+  margin-right: auto;
+  margin-left: auto;
+}
+.pull-right {
+  float: right !important;
+}
+.pull-left {
+  float: left !important;
+}
+.hide {
+  display: none !important;
+}
+.show {
+  display: block !important;
+}
+.invisible {
+  visibility: hidden;
+}
+.text-hide {
+  font: 0/0 a;
+  color: transparent;
+  text-shadow: none;
+  background-color: transparent;
+  border: 0;
+}
+.hidden {
+  display: none !important;
+  visibility: hidden !important;
+}
+.affix {
+  position: fixed;
+}
+ at -ms-viewport {
+  width: device-width;
+}
+.visible-xs,
+tr.visible-xs,
+th.visible-xs,
+td.visible-xs {
+  display: none !important;
+}
+ at media (max-width: 767px) {
+  .visible-xs {
+    display: block !important;
+  }
+  table.visible-xs {
+    display: table;
+  }
+  tr.visible-xs {
+    display: table-row !important;
+  }
+  th.visible-xs,
+  td.visible-xs {
+    display: table-cell !important;
+  }
+}
+.visible-sm,
+tr.visible-sm,
+th.visible-sm,
+td.visible-sm {
+  display: none !important;
+}
+ at media (min-width: 768px) and (max-width: 991px) {
+  .visible-sm {
+    display: block !important;
+  }
+  table.visible-sm {
+    display: table;
+  }
+  tr.visible-sm {
+    display: table-row !important;
+  }
+  th.visible-sm,
+  td.visible-sm {
+    display: table-cell !important;
+  }
+}
+.visible-md,
+tr.visible-md,
+th.visible-md,
+td.visible-md {
+  display: none !important;
+}
+ at media (min-width: 992px) and (max-width: 1199px) {
+  .visible-md {
+    display: block !important;
+  }
+  table.visible-md {
+    display: table;
+  }
+  tr.visible-md {
+    display: table-row !important;
+  }
+  th.visible-md,
+  td.visible-md {
+    display: table-cell !important;
+  }
+}
+.visible-lg,
+tr.visible-lg,
+th.visible-lg,
+td.visible-lg {
+  display: none !important;
+}
+ at media (min-width: 1200px) {
+  .visible-lg {
+    display: block !important;
+  }
+  table.visible-lg {
+    display: table;
+  }
+  tr.visible-lg {
+    display: table-row !important;
+  }
+  th.visible-lg,
+  td.visible-lg {
+    display: table-cell !important;
+  }
+}
+ at media (max-width: 767px) {
+  .hidden-xs,
+  tr.hidden-xs,
+  th.hidden-xs,
+  td.hidden-xs {
+    display: none !important;
+  }
+}
+ at media (min-width: 768px) and (max-width: 991px) {
+  .hidden-sm,
+  tr.hidden-sm,
+  th.hidden-sm,
+  td.hidden-sm {
+    display: none !important;
+  }
+}
+ at media (min-width: 992px) and (max-width: 1199px) {
+  .hidden-md,
+  tr.hidden-md,
+  th.hidden-md,
+  td.hidden-md {
+    display: none !important;
+  }
+}
+ at media (min-width: 1200px) {
+  .hidden-lg,
+  tr.hidden-lg,
+  th.hidden-lg,
+  td.hidden-lg {
+    display: none !important;
+  }
+}
+.visible-print,
+tr.visible-print,
+th.visible-print,
+td.visible-print {
+  display: none !important;
+}
+ at media print {
+  .visible-print {
+    display: block !important;
+  }
+  table.visible-print {
+    display: table;
+  }
+  tr.visible-print {
+    display: table-row !important;
+  }
+  th.visible-print,
+  td.visible-print {
+    display: table-cell !important;
+  }
+}
+ at media print {
+  .hidden-print,
+  tr.hidden-print,
+  th.hidden-print,
+  td.hidden-print {
+    display: none !important;
+  }
+}
+/*# sourceMappingURL=bootstrap.css.map */
diff --git a/app/gui/html/vendor/bootstrap/css/bootstrap.css.map b/app/gui/html/vendor/bootstrap/css/bootstrap.css.map
new file mode 100644
index 0000000..e1836ba
--- /dev/null
+++ b/app/gui/html/vendor/bootstrap/css/bootstrap.css.map
@@ -0,0 +1 @@
+{"version":3,"sources":["less/normalize.less","less/print.less","less/scaffolding.less","less/mixins.less","less/variables.less","less/type.less","less/code.less","less/grid.less","less/tables.less","less/forms.less","less/buttons.less","less/component-animations.less","less/glyphicons.less","less/dropdowns.less","less/button-groups.less","less/input-groups.less","less/navs.less","less/navbar.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/pager.less","less/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/progress-bars.less","less/media.less","less/list-group.less","less/panels.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/popovers.less","less/carousel.less","less/responsive-utilities.less"],"names":[],"mappings":";AAQA;EACE,uBAAA;EACA,0BAAA;EACA,8BAAA;;AAOF;EACE,SAAA;;AAUF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACE,cAAA;;AAQF;AACA;AACA;AACA;EACE,qBAAA;EACA,wBAAA;;AAQF,KAAK,IAAI;EACP,aAAA;EACA,SAAA;;AAQF;AACA;EACE,aAAA;;AAUF;EACE,uBAAA;;AAOF,CAAC;AACD,CAAC;EACC,UAAA;;AAUF,IAAI;EACF,yBAAA;;AAOF;AACA;EACE,iBAAA;;AAOF;EACE,kBAAA;;AAQF;EACE,cAAA;EACA,gBAAA;;AAOF;EACE,gBAAA;EACA,WAAA;;AAOF;EACE,cAAA;;AAOF;AACA;EACE,cAAA;EACA,cAAA;EACA,kBAAA;EACA,wBAAA;;AAGF;EACE,WAAA;;AAGF;EACE,eAAA;;AAUF;EACE,SAAA;;AAOF,GAAG,IAAI;EACL,gBAAA;;AAUF;EACE,gBAAA;;AAOF;EACE,4BAAA;EACA,uBAAA;EACA,SAAA;;AAOF;EACE,cAAA;;AAOF;AACA;AACA;AACA;EACE,iCAAA;EACA,cAAA;;AAkBF;AACA;AACA;AACA;AACA;EACE,cAAA;EACA,aAAA;EACA,SAAA;;AAOF;EACE,iBAAA;;AAUF;AACA;EACE,oBAAA;;AAWF;AACA,IAAK,MAAK;AACV,KAAK;AACL,KAAK;EACH,0BAAA;EACA,eAAA;;AAOF,MAAM;AACN,IAAK,MAAK;EACR,eAAA;;AAOF,MAAM;AACN,KAAK;EACH,SAAA;EACA,UAAA;;AAQF;EACE,mBAAA;;AAWF,KAAK;AACL,KAAK;EACH,sBAAA;EACA,UAAA;;AASF,KAAK,eAAe;AACpB,KAAK,eAAe;EAClB,YAAA;;AASF,KAAK;EACH,6BAAA;EACA,4BAAA;EACA,+BAAA;EACA,uBAAA;;AASF,KAAK,eAAe;AACpB,KAAK,eAAe;EAClB,wBAAA;;AAOF;EACE,yBAAA;EACA,aAAA;EACA,8BAAA;;AAQF;EACE,SAAA;EACA,UAAA;;AAOF;EACE,cAAA;;AAQF;EACE,iBAAA;;AAUF;EACE,yBAAA;EACA,iBAAA;;AAGF;AACA;EACE,UAAA;;AChUF;EA9FE;IACE,4BAAA;IACA,sBAAA;IACA,kCAAA;IACA,2BAAA;;EAGF;EACA,CAAC;IACC,0BAAA;;EAGF,CAAC,MAAM;IACL,SAAS,KAAK,WAAW,GAAzB;;EAGF,IAAI,OAAO;IACT,SAAS,KAAK,YAAY,GAA1B;;EAIF,CAAC,qBAAqB;EACtB,CAAC,WAAW;IACV,SAAS,EAAT;;EAGF;EACA;IACE,sBAAA;IACA,wBAAA;;EAGF;IACE,2BAAA;;EAGF;EACA;IACE,wBAAA;;EAGF;IACE,0BAAA;;EAGF;EACA;EACA;IACE,UAAA;IACA,SAAA;;EAGF;EACA;IACE,uBAAA;;EAKF;IACE,2BAAA;;EAIF;IACE,aAAA;;EAEF,MACE;EADF,MAEE;IACE,iCAAA;;EAGJ,IAEE;EADF,OAAQ,OACN;IACE,iCAAA;;EAGJ;IACE,sBAAA;;EAGF;IACE,oCAAA;;EAEF,eACE;EADF,eAEE;IACE,iCAAA;;;ACtFN;EC0OE,8BAAA;EACG,2BAAA;EACK,sBAAA;;ADzOV,CAAC;AACD,CAAC;ECsOC,8BAAA;EACG,2BAAA;EACK,sBAAA;;ADjOV;EACE,gBAAA;EACA,6CAAA;;AAGF;EACE,aEcwB,8CFdxB;EACA,eAAA;EACA,wBAAA;EACA,cAAA;EACA,yBAAA;;AAIF;AACA;AACA;AACA;EACE,oBAAA;EACA,kBAAA;EACA,oBAAA;;AAMF;EACE,cAAA;EACA,qBAAA;;AAEA,CAAC;AACD,CAAC;EACC,cAAA;EACA,0BAAA;;AAGF,CAAC;ECzBD,oBAAA;EAEA,0CAAA;EACA,oBAAA;;ADiCF;EACE,SAAA;;AAMF;EACE,sBAAA;;AAIF;ECiTE,cAAA;EACA,eAAA;EACA,YAAA;;AD9SF;EACE,kBAAA;;AAMF;EACE,YAAA;EACA,wBAAA;EACA,yBAAA;EACA,yBAAA;EACA,kBAAA;EC+BA,wCAAA;EACQ,gCAAA;EAgQR,qBAAA;EACA,eAAA;EACA,YAAA;;AD1RF;EACE,kBAAA;;AAMF;EACE,gBAAA;EACA,mBAAA;EACA,SAAA;EACA,6BAAA;;AAQF;EACE,kBAAA;EACA,UAAA;EACA,WAAA;EACA,YAAA;EACA,UAAA;EACA,gBAAA;EACA,MAAM,gBAAN;EACA,SAAA;;AG5HF;AAAI;AAAI;AAAI;AAAI;AAAI;AACpB;AAAK;AAAK;AAAK;AAAK;AAAK;EACvB,oBAAA;EACA,gBAAA;EACA,gBAAA;EACA,cAAA;;AALF,EAOE;AAPE,EAOF;AAPM,EAON;AAPU,EAOV;AAPc,EAOd;AAPkB,EAOlB;AANF,GAME;AANG,GAMH;AANQ,GAMR;AANa,GAMb;AANkB,GAMlB;AANuB,GAMvB;AAPF,EAQE;AARE,EAQF;AARM,EAQN;AARU,EAQV;AARc,EAQd;AARkB,EAQlB;AAPF,GAOE;AAPG,GAOH;AAPQ,GAOR;AAPa,GAOb;AAPkB,GAOlB;AAPuB,GAOvB;EACE,mBAAA;EACA,cAAA;EACA,cAAA;;AAIJ;AAAI;AACJ;AAAI;AACJ;AAAI;EACF,gBAAA;EACA,mBAAA;;AAJF,EAME;AANE,GAMF;AALF,EAKE;AALE,GAKF;AAJF,EAIE;AAJE,GAIF;AANF,EAOE;AAPE,GAOF;AANF,EAME;AANE,GAMF;AALF,EAKE;AALE,GAKF;EACE,cAAA;;AAGJ;AAAI;AACJ;AAAI;AACJ;AAAI;EACF,gBAAA;EACA,mBAAA;;AAJF,EAME;AANE,GAMF;AALF,EAKE;AALE,GAKF;AAJF,EAIE;AAJE,GAIF;AANF,EAOE;AAPE,GAOF;AANF,EAME;AANE,GAMF;AALF,EAKE;AALE,GAKF;EACE,cAAA;;AAIJ;AAAI;EAAM,eAAA;;AACV;AAAI;EAAM,eAAA;;AACV;AAAI;EAAM,eAAA;;AACV;AAAI;EAAM,eAAA;;AACV;AAAI;EAAM,eAAA;;AACV;AAAI;EAAM,eAAA;;AAMV;EACE,gBAAA;;AAGF;EACE,mBAAA;EACA,eAAA;EACA,gBAAA;EACA,gBAAA;;AAKF,QAHqC;EAGrC;IAFI,eAAA;;;AASJ;AACA;EAAU,cAAA;;AAGV;EAAU,kBAAA;;AAGV;EAAuB,gBAAA;;AACvB;EAAuB,iBAAA;;AACvB;EAAuB,kBAAA;;AACvB;EAAuB,mBAAA;;AAGvB;EACE,cAAA;;AAEF;EFsfE,cAAA;;AACA,CAAC,aAAC;EACA,cAAA;;AErfJ;EFmfE,cAAA;;AACA,CAAC,aAAC;EACA,cAAA;;AElfJ;EFgfE,cAAA;;AACA,CAAC,UAAC;EACA,cAAA;;AE/eJ;EF6eE,cAAA;;AACA,CAAC,aAAC;EACA,cAAA;;AE5eJ;EF0eE,cAAA;;AACA,CAAC,YAAC;EACA,cAAA;;AEreJ;EAGE,WAAA;EFudA,yBAAA;;AACA,CAAC,WAAC;EACA,yBAAA;;AEtdJ;EFodE,yBAAA;;AACA,CAAC,WAAC;EACA,yBAAA;;AEndJ;EFidE,yBAAA;;AACA,CAAC,QAAC;EACA,yBAAA;;AEhdJ;EF8cE,yBAAA;;AACA,CAAC,WAAC;EACA,yBAAA;;AE7cJ;EF2cE,yBAAA;;AACA,CAAC,UAAC;EACA,yBAAA;;AErcJ;EACE,mBAAA;EACA,mBAAA;EACA,gCAAA;;AAQF;AACA;EACE,aAAA;EACA,mBAAA;;AAHF,EAIE;AAHF,EAGE;AAJF,EAKE;AAJF,EAIE;EACE,gBAAA;;AAOJ;EACE,eAAA;EACA,gBAAA;;AAIF;EALE,eAAA;EACA,gBAAA;;AAIF,YAGE;EACE,qBAAA;EACA,iBAAA;EACA,kBAAA;;AAEA,YALF,KAKG;EACC,eAAA;;AAMN;EACE,aAAA;EACA,mBAAA;;AAEF;AACA;EACE,wBAAA;;AAEF;EACE,iBAAA;;AAEF;EACE,cAAA;;AAwBF,QAhB2C;EACzC,cACE;IACE,WAAA;IACA,YAAA;IACA,WAAA;IACA,iBAAA;IF5IJ,gBAAA;IACA,uBAAA;IACA,mBAAA;;EEqIA,cAQE;IACE,kBAAA;;;AAUN,IAAI;AAEJ,IAAI;EACF,YAAA;EACA,iCAAA;;AAEF;EACE,cAAA;EACA,yBAAA;;AAIF;EACE,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,8BAAA;;AAKE,UAHF,EAGG;AAAD,UAFF,GAEG;AAAD,UADF,GACG;EACC,gBAAA;;AAVN,UAgBE;AAhBF,UAiBE;AAjBF,UAkBE;EACE,cAAA;EACA,cAAA;EACA,wBAAA;EACA,cAAA;;AAEA,UARF,OAQG;AAAD,UAPF,MAOG;AAAD,UANF,OAMG;EACC,SAAS,aAAT;;AAQN;AACA,UAAU;EACR,mBAAA;EACA,eAAA;EACA,+BAAA;EACA,cAAA;EACA,iBAAA;;AAME,mBAHF,OAGG;AAAD,UAXM,WAQR,OAGG;AAAD,mBAFF,MAEG;AAAD,UAXM,WASR,MAEG;AAAD,mBADF,OACG;AAAD,UAXM,WAUR,OACG;EAAU,SAAS,EAAT;;AACX,mBAJF,OAIG;AAAD,UAZM,WAQR,OAIG;AAAD,mBAHF,MAGG;AAAD,UAZM,WASR,MAGG;AAAD,mBAFF,OAEG;AAAD,UAZM,WAUR,OAEG;EACC,SAAS,aAAT;;AAMN,UAAU;AACV,UAAU;EACR,SAAS,EAAT;;AAIF;EACE,mBAAA;EACA,kBAAA;EACA,wBAAA;;AChSF;AACA;AACA;AACA;EACE,sCFkCiD,wBElCjD;;AAIF;EACE,gBAAA;EACA,cAAA;EACA,cAAA;EACA,yBAAA;EACA,mBAAA;EACA,kBAAA;;AAIF;EACE,gBAAA;EACA,cAAA;EACA,cAAA;EACA,yBAAA;EACA,kBAAA;EACA,8CAAA;;AAIF;EACE,cAAA;EACA,cAAA;EACA,gBAAA;EACA,eAAA;EACA,wBAAA;EACA,qBAAA;EACA,qBAAA;EACA,cAAA;EACA,yBAAA;EACA,yBAAA;EACA,kBAAA;;AAXF,GAcE;EACE,UAAA;EACA,kBAAA;EACA,cAAA;EACA,qBAAA;EACA,6BAAA;EACA,gBAAA;;AAKJ;EACE,iBAAA;EACA,kBAAA;;ACpDF;EJ0nBE,kBAAA;EACA,iBAAA;EACA,kBAAA;EACA,mBAAA;;AIvnBA,QAHmC;EAGnC;IAFE,YAAA;;;AAKF,QAHmC;EAGnC;IAFE,YAAA;;;AAKJ,QAHqC;EAGrC;IAFI,aAAA;;;AAUJ;EJsmBE,kBAAA;EACA,iBAAA;EACA,kBAAA;EACA,mBAAA;;AIhmBF;EJsmBE,kBAAA;EACA,mBAAA;;AAqIE;EACE,kBAAA;EAEA,eAAA;EAEA,kBAAA;EACA,mBAAA;;AAgBF;EACE,WAAA;;AAOJ,KAAK,EAAQ,CAAC;EACZ,WAAA;;AADF,KAAK,EAAQ,CAAC;EACZ,yBAAA;;AADF,KAAK,EAAQ,CAAC;EACZ,yBAAA;;AADF,KAAK,EAAQ,CAAC;EACZ,UAAA;;AADF,KAAK,EAAQ,CAAC;EACZ,yBAAA;;AADF,KAAK,EAAQ,CAAC;EACZ,0BAAA;;AADF,KAAK,EAAQ,CAAC;EACZ,UAAA;;AADF,KAAK,EAAQ,CAAC;EACZ,yBAAA;;AADF,KAAK,EAAQ,CAAC;EACZ,yBAAA;;AADF,KAAK,EAAQ,CAAC;EACZ,UAAA;;AADF,KAAK,EAAQ,CAAC;EACZ,0BAAA;;AADF,KAAK,EAAQ,CAAC;EACZ,yBAAA;;AASF,KAAK,EAAQ,MAAM;EACjB,WAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,yBAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,yBAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,UAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,yBAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,0BAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,UAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,yBAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,yBAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,UAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,0BAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,yBAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,SAAA;;AANF,KAAK,EAAQ,MAAM;EACjB,UAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,wBAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,wBAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,SAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,wBAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,yBAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,SAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,wBAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,wBAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,SAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,yBAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,wBAAA;;AADF,KAAK,EAAQ,MAAM;EACjB,QAAA;;AASF,KAAK,EAAQ,QAAQ;EACnB,iBAAA;;AADF,KAAK,EAAQ,QAAQ;EACnB,+BAAA;;AADF,KAAK,EAAQ,QAAQ;EACnB,+BAAA;;AADF,KAAK,EAAQ,QAAQ;EACnB,gBAAA;;AADF,KAAK,EAAQ,QAAQ;EACnB,+BAAA;;AADF,KAAK,EAAQ,QAAQ;EACnB,gCAAA;;AADF,KAAK,EAAQ,QAAQ;EACnB,gBAAA;;AADF,KAAK,EAAQ,QAAQ;EACnB,+BAAA;;AADF,KAAK,EAAQ,QAAQ;EACnB,+BAAA;;AADF,KAAK,EAAQ,QAAQ;EACnB,gBAAA;;AADF,KAAK,EAAQ,QAAQ;EACnB,gCAAA;;AADF,KAAK,EAAQ,QAAQ;EACnB,+BAAA;;AADF,KAAK,EAAQ,QAAQ;EACnB,eAAA;;AIpvBJ,QATmC;EJquB/B;IACE,WAAA;;EAOJ,KAAK,EAAQ,CAAC;IACZ,WAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,UAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,0BAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,UAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,UAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,0BAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EASF,KAAK,EAAQ,MAAM;IACjB,WAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,UAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,0BAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,UAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,UAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,0BAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,SAAA;;EANF,KAAK,EAAQ,MAAM;IACjB,UAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,SAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,SAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,SAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,QAAA;;EASF,KAAK,EAAQ,QAAQ;IACnB,iBAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,gBAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,gCAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,gBAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,gBAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,gCAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,eAAA;;;AIvuBJ,QATmC;EJwtB/B;IACE,WAAA;;EAOJ,KAAK,EAAQ,CAAC;IACZ,WAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,UAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,0BAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,UAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,UAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,0BAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EASF,KAAK,EAAQ,MAAM;IACjB,WAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,UAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,0BAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,UAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,UAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,0BAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,SAAA;;EANF,KAAK,EAAQ,MAAM;IACjB,UAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,SAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,SAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,SAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,QAAA;;EASF,KAAK,EAAQ,QAAQ;IACnB,iBAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,gBAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,gCAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,gBAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,gBAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,gCAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,eAAA;;;AI5tBJ,QAPmC;EJ2sB/B;IACE,WAAA;;EAOJ,KAAK,EAAQ,CAAC;IACZ,WAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,UAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,0BAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,UAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,UAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,0BAAA;;EADF,KAAK,EAAQ,CAAC;IACZ,yBAAA;;EASF,KAAK,EAAQ,MAAM;IACjB,WAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,UAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,0BAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,UAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,UAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,0BAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,SAAA;;EANF,KAAK,EAAQ,MAAM;IACjB,UAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,SAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,SAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,SAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,yBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,wBAAA;;EADF,KAAK,EAAQ,MAAM;IACjB,QAAA;;EASF,KAAK,EAAQ,QAAQ;IACnB,iBAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,gBAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,gCAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,gBAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,gBAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,gCAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,+BAAA;;EADF,KAAK,EAAQ,QAAQ;IACnB,eAAA;;;AK3zBJ;EACE,eAAA;EACA,6BAAA;;AAEF;EACE,gBAAA;;AAMF;EACE,WAAA;EACA,mBAAA;;AAFF,MAIE,QAGE,KACE;AARN,MAKE,QAEE,KACE;AARN,MAME,QACE,KACE;AARN,MAIE,QAGE,KAEE;AATN,MAKE,QAEE,KAEE;AATN,MAME,QACE,KAEE;EACE,YAAA;EACA,wBAAA;EACA,mBAAA;EACA,6BAAA;;AAbR,MAkBE,QAAQ,KAAK;EACX,sBAAA;EACA,gCAAA;;AApBJ,MAuBE,UAAU,QAGR,KAAI,YACF;AA3BN,MAwBE,WAAW,QAET,KAAI,YACF;AA3BN,MAyBE,QAAO,YACL,KAAI,YACF;AA3BN,MAuBE,UAAU,QAGR,KAAI,YAEF;AA5BN,MAwBE,WAAW,QAET,KAAI,YAEF;AA5BN,MAyBE,QAAO,YACL,KAAI,YAEF;EACE,aAAA;;AA7BR,MAkCE,QAAQ;EACN,6BAAA;;AAnCJ,MAuCE;EACE,yBAAA;;AAOJ,gBACE,QAGE,KACE;AALN,gBAEE,QAEE,KACE;AALN,gBAGE,QACE,KACE;AALN,gBACE,QAGE,KAEE;AANN,gBAEE,QAEE,KAEE;AANN,gBAGE,QACE,KAEE;EACE,YAAA;;AAWR;EACE,yBAAA;;AADF,eAEE,QAGE,KACE;AANN,eAGE,QAEE,KACE;AANN,eAIE,QACE,KACE;AANN,eAEE,QAGE,KAEE;AAPN,eAGE,QAEE,KAEE;AAPN,eAIE,QACE,KAEE;EACE,yBAAA;;AARR,eAYE,QAAQ,KACN;AAbJ,eAYE,QAAQ,KAEN;EACE,wBAAA;;AAUN,cACE,QAAQ,KAAI,UAAU,KACpB;AAFJ,cACE,QAAQ,KAAI,UAAU,KAEpB;EACE,yBAAA;;AAUN,YACE,QAAQ,KAAI,MACV;AAFJ,YACE,QAAQ,KAAI,MAEV;EACE,yBAAA;;AAUN,KAAM,IAAG;EACP,gBAAA;EACA,WAAA;EACA,qBAAA;;AAKE,KAFF,GAEG;AAAD,KADF,GACG;EACC,gBAAA;EACA,WAAA;EACA,mBAAA;;AL4SJ,MAAO,QAAQ,KAGb,KAAI,CAAC;AAFP,MAAO,QAAQ,KAEb,KAAI,CAAC;AADP,MAAO,QAAQ,KACb,KAAI,CAAC;AAHP,MAAO,QAAQ,KAIb,KAAI,CAAC;AAHP,MAAO,QAAQ,KAGb,KAAI,CAAC;AAFP,MAAO,QAAQ,KAEb,KAAI,CAAC;AACL,MALK,QAAQ,KAKZ,CAAC,MAAS;AAAX,MAJK,QAAQ,KAIZ,CAAC,MAAS;AAAX,MAHK,QAAQ,KAGZ,CAAC,MAAS;AACX,MANK,QAAQ,KAMZ,CAAC,MAAS;AAAX,MALK,QAAQ,KAKZ,CAAC,MAAS;AAAX,MAJK,QAAQ,KAIZ,CAAC,MAAS;EACT,yBAAA;;AAMJ,YAAa,QAAQ,KACnB,KAAI,CAAC,MAAQ;AADf,YAAa,QAAQ,KAEnB,KAAI,CAAC,MAAQ;AACb,YAHW,QAAQ,KAGlB,CAAC,MAAQ,MAAO;AACjB,YAJW,QAAQ,KAIlB,CAAC,MAAQ,MAAO;EACf,yBAAA;;AAlBJ,MAAO,QAAQ,KAGb,KAAI,CAAC;AAFP,MAAO,QAAQ,KAEb,KAAI,CAAC;AADP,MAAO,QAAQ,KACb,KAAI,CAAC;AAHP,MAAO,QAAQ,KAIb,KAAI,CAAC;AAHP,MAAO,QAAQ,KAGb,KAAI,CAAC;AAFP,MAAO,QAAQ,KAEb,KAAI,CAAC;AACL,MALK,QAAQ,KAKZ,CAAC,OAAS;AAAX,MAJK,QAAQ,KAIZ,CAAC,OAAS;AAAX,MAHK,QAAQ,KAGZ,CAAC,OAAS;AACX,MANK,QAAQ,KAMZ,CAAC,OAAS;AAAX,MALK,QAAQ,KAKZ,CAAC,OAAS;AAAX,MAJK,QAAQ,KAIZ,CAAC,OAAS;EACT,yBAAA;;AAMJ,YAAa,QAAQ,KACnB,KAAI,CAAC,OAAQ;AADf,YAAa,QAAQ,KAEnB,KAAI,CAAC,OAAQ;AACb,YAHW,QAAQ,KAGlB,CAAC,OAAQ,MAAO;AACjB,YAJW,QAAQ,KAIlB,CAAC,OAAQ,MAAO;EACf,yBAAA;;AAlBJ,MAAO,QAAQ,KAGb,KAAI,CAAC;AAFP,MAAO,QAAQ,KAEb,KAAI,CAAC;AADP,MAAO,QAAQ,KACb,KAAI,CAAC;AAHP,MAAO,QAAQ,KAIb,KAAI,CAAC;AAHP,MAAO,QAAQ,KAGb,KAAI,CAAC;AAFP,MAAO,QAAQ,KAEb,KAAI,CAAC;AACL,MALK,QAAQ,KAKZ,CAAC,IAAS;AAAX,MAJK,QAAQ,KAIZ,CAAC,IAAS;AAAX,MAHK,QAAQ,KAGZ,CAAC,IAAS;AACX,MANK,QAAQ,KAMZ,CAAC,IAAS;AAAX,MALK,QAAQ,KAKZ,CAAC,IAAS;AAAX,MAJK,QAAQ,KAIZ,CAAC,IAAS;EACT,yBAAA;;AAMJ,YAAa,QAAQ,KACnB,KAAI,CAAC,IAAQ;AADf,YAAa,QAAQ,KAEnB,KAAI,CAAC,IAAQ;AACb,YAHW,QAAQ,KAGlB,CAAC,IAAQ,MAAO;AACjB,YAJW,QAAQ,KAIlB,CAAC,IAAQ,MAAO;EACf,yBAAA;;AAlBJ,MAAO,QAAQ,KAGb,KAAI,CAAC;AAFP,MAAO,QAAQ,KAEb,KAAI,CAAC;AADP,MAAO,QAAQ,KACb,KAAI,CAAC;AAHP,MAAO,QAAQ,KAIb,KAAI,CAAC;AAHP,MAAO,QAAQ,KAGb,KAAI,CAAC;AAFP,MAAO,QAAQ,KAEb,KAAI,CAAC;AACL,MALK,QAAQ,KAKZ,CAAC,OAAS;AAAX,MAJK,QAAQ,KAIZ,CAAC,OAAS;AAAX,MAHK,QAAQ,KAGZ,CAAC,OAAS;AACX,MANK,QAAQ,KAMZ,CAAC,OAAS;AAAX,MALK,QAAQ,KAKZ,CAAC,OAAS;AAAX,MAJK,QAAQ,KAIZ,CAAC,OAAS;EACT,yBAAA;;AAMJ,YAAa,QAAQ,KACnB,KAAI,CAAC,OAAQ;AADf,YAAa,QAAQ,KAEnB,KAAI,CAAC,OAAQ;AACb,YAHW,QAAQ,KAGlB,CAAC,OAAQ,MAAO;AACjB,YAJW,QAAQ,KAIlB,CAAC,OAAQ,MAAO;EACf,yBAAA;;AAlBJ,MAAO,QAAQ,KAGb,KAAI,CAAC;AAFP,MAAO,QAAQ,KAEb,KAAI,CAAC;AADP,MAAO,QAAQ,KACb,KAAI,CAAC;AAHP,MAAO,QAAQ,KAIb,KAAI,CAAC;AAHP,MAAO,QAAQ,KAGb,KAAI,CAAC;AAFP,MAAO,QAAQ,KAEb,KAAI,CAAC;AACL,MALK,QAAQ,KAKZ,CAAC,MAAS;AAAX,MAJK,QAAQ,KAIZ,CAAC,MAAS;AAAX,MAHK,QAAQ,KAGZ,CAAC,MAAS;AACX,MANK,QAAQ,KAMZ,CAAC,MAAS;AAAX,MALK,QAAQ,KAKZ,CAAC,MAAS;AAAX,MAJK,QAAQ,KAIZ,CAAC,MAAS;EACT,yBAAA;;AAMJ,YAAa,QAAQ,KACnB,KAAI,CAAC,MAAQ;AADf,YAAa,QAAQ,KAEnB,KAAI,CAAC,MAAQ;AACb,YAHW,QAAQ,KAGlB,CAAC,MAAQ,MAAO;AACjB,YAJW,QAAQ,KAIlB,CAAC,MAAQ,MAAO;EACf,yBAAA;;AKtON,QA/DmC;EACjC;IACE,WAAA;IACA,mBAAA;IACA,kBAAA;IACA,kBAAA;IACA,4CAAA;IACA,yBAAA;IACA,iCAAA;;EAPF,iBAUE;IACE,gBAAA;;EAXJ,iBAUE,SAIE,QAGE,KACE;EAlBR,iBAUE,SAKE,QAEE,KACE;EAlBR,iBAUE,SAME,QACE,KACE;EAlBR,iBAUE,SAIE,QAGE,KAEE;EAnBR,iBAUE,SAKE,QAEE,KAEE;EAnBR,iBAUE,SAME,QACE,KAEE;IACE,mBAAA;;EApBV,iBA2BE;IACE,SAAA;;EA5BJ,iBA2BE,kBAIE,QAGE,KACE,KAAI;EAnCZ,iBA2BE,kBAKE,QAEE,KACE,KAAI;EAnCZ,iBA2BE,kBAME,QACE,KACE,KAAI;EAnCZ,iBA2BE,kBAIE,QAGE,KAEE,KAAI;EApCZ,iBA2BE,kBAKE,QAEE,KAEE,KAAI;EApCZ,iBA2BE,kBAME,QACE,KAEE,KAAI;IACF,cAAA;;EArCV,iBA2BE,kBAIE,QAGE,KAKE,KAAI;EAvCZ,iBA2BE,kBAKE,QAEE,KAKE,KAAI;EAvCZ,iBA2BE,kBAME,QACE,KAKE,KAAI;EAvCZ,iBA2BE,kBAIE,QAGE,KAME,KAAI;EAxCZ,iBA2BE,kBAKE,QAEE,KAME,KAAI;EAxCZ,iBA2BE,kBAME,QACE,KAME,KAAI;IACF,eAAA;;EAzCV,iBA2BE,kBAsBE,QAEE,KAAI,WACF;EApDR,iBA2BE,kBAuBE,QACE,KAAI,WACF;EApDR,iBA2BE,kBAsBE,QAEE,KAAI,WAEF;EArDR,iBA2BE,kBAuBE,QACE,KAAI,WAEF;IACE,gBAAA;;;ACxNZ;EACE,UAAA;EACA,SAAA;EACA,SAAA;EAIA,YAAA;;AAGF;EACE,cAAA;EACA,WAAA;EACA,UAAA;EACA,mBAAA;EACA,eAAA;EACA,oBAAA;EACA,cAAA;EACA,SAAA;EACA,gCAAA;;AAGF;EACE,qBAAA;EACA,kBAAA;EACA,iBAAA;;AAWF,KAAK;ENuMH,8BAAA;EACG,2BAAA;EACK,sBAAA;;AMpMV,KAAK;AACL,KAAK;EACH,eAAA;EACA,kBAAA;;EACA,mBAAA;;AAIF,KAAK;EACH,cAAA;;AAIF,KAAK;EACH,cAAA;EACA,WAAA;;AAIF,MAAM;AACN,MAAM;EACJ,YAAA;;AAIF,KAAK,aAAa;AAClB,KAAK,cAAc;AACnB,KAAK,iBAAiB;EN7CpB,oBAAA;EAEA,0CAAA;EACA,oBAAA;;AM+CF;EACE,cAAA;EACA,gBAAA;EACA,eAAA;EACA,wBAAA;EACA,cAAA;;AA0BF;EACE,cAAA;EACA,WAAA;EACA,YAAA;EACA,iBAAA;EACA,eAAA;EACA,wBAAA;EACA,cAAA;EACA,yBAAA;EACA,sBAAA;EACA,yBAAA;EACA,kBAAA;ENFA,wDAAA;EACQ,gDAAA;EAKR,8EAAA;EACQ,sEAAA;;AA+vBR,aAAC;EACC,qBAAA;EACA,UAAA;EAxwBF,sFAAA;EACQ,8EAAA;;AAnER,aAAC;EAA+B,cAAA;;AAChC,aAAC;EAA+B,cAAA;EACA,UAAA;;AAChC,aAAC;EAA+B,cAAA;;AAChC,aAAC;EAA+B,cAAA;;AM8EhC,aAAC;AACD,aAAC;AACD,QAAQ,UAAW;EACjB,mBAAA;EACA,yBAAA;EACA,UAAA;;AAIF,QAAQ;EACN,YAAA;;AAQJ,KAAK;EACH,iBAAA;;AASF;EACE,mBAAA;;AAQF;AACA;EACE,cAAA;EACA,gBAAA;EACA,gBAAA;EACA,mBAAA;EACA,kBAAA;;AANF,MAOE;AANF,SAME;EACE,eAAA;EACA,mBAAA;EACA,eAAA;;AAGJ,MAAO,MAAK;AACZ,aAAc,MAAK;AACnB,SAAU,MAAK;AACf,gBAAiB,MAAK;EACpB,WAAA;EACA,kBAAA;;AAEF,MAAO;AACP,SAAU;EACR,gBAAA;;AAIF;AACA;EACE,qBAAA;EACA,kBAAA;EACA,gBAAA;EACA,sBAAA;EACA,mBAAA;EACA,eAAA;;AAEF,aAAc;AACd,gBAAiB;EACf,aAAA;EACA,iBAAA;;AAYA,KANG,cAMF;AAAD,KALG,iBAKF;AAAD,MAAC;AAAD,aAAC;AAAD,SAAC;AAAD,gBAAC;AACD,QAAQ,UAAW,MAPhB;AAOH,QAAQ,UAAW,MANhB;AAMH,QAAQ,UAAW;AAAnB,QAAQ,UAAW;AAAnB,QAAQ,UAAW;AAAnB,QAAQ,UAAW;EACjB,mBAAA;;AAUJ;ENiqBE,YAAA;EACA,iBAAA;EACA,eAAA;EACA,gBAAA;EACA,kBAAA;;AAEA,MAAM;EACJ,YAAA;EACA,iBAAA;;AAGF,QAAQ;AACR,MAAM,UAAU;EACd,YAAA;;AM1qBJ;EN6pBE,YAAA;EACA,kBAAA;EACA,eAAA;EACA,iBAAA;EACA,kBAAA;;AAEA,MAAM;EACJ,YAAA;EACA,iBAAA;;AAGF,QAAQ;AACR,MAAM,UAAU;EACd,YAAA;;AMjqBJ;EAEE,kBAAA;;AAFF,aAKE;EACE,qBAAA;;AANJ,aAUE;EACE,kBAAA;EACA,SAAA;EACA,QAAA;EACA,cAAA;EACA,WAAA;EACA,YAAA;EACA,iBAAA;EACA,kBAAA;;AAKJ,YNkkBE;AMlkBF,YNmkBE;AMnkBF,YNokBE;AMpkBF,YNqkBE;AMrkBF,YNskBE;AMtkBF,YNukBE;EACE,cAAA;;AMxkBJ,YN2kBE;EACE,qBAAA;EAnuBF,wDAAA;EACQ,gDAAA;;AAouBN,YAHF,cAGG;EACC,qBAAA;EAtuBJ,yEAAA;EACQ,iEAAA;;AMsJV,YNqlBE;EACE,cAAA;EACA,qBAAA;EACA,yBAAA;;AMxlBJ,YN2lBE;EACE,cAAA;;AMzlBJ,YN+jBE;AM/jBF,YNgkBE;AMhkBF,YNikBE;AMjkBF,YNkkBE;AMlkBF,YNmkBE;AMnkBF,YNokBE;EACE,cAAA;;AMrkBJ,YNwkBE;EACE,qBAAA;EAnuBF,wDAAA;EACQ,gDAAA;;AAouBN,YAHF,cAGG;EACC,qBAAA;EAtuBJ,yEAAA;EACQ,iEAAA;;AMyJV,YNklBE;EACE,cAAA;EACA,qBAAA;EACA,yBAAA;;AMrlBJ,YNwlBE;EACE,cAAA;;AMtlBJ,UN4jBE;AM5jBF,UN6jBE;AM7jBF,UN8jBE;AM9jBF,UN+jBE;AM/jBF,UNgkBE;AMhkBF,UNikBE;EACE,cAAA;;AMlkBJ,UNqkBE;EACE,qBAAA;EAnuBF,wDAAA;EACQ,gDAAA;;AAouBN,UAHF,cAGG;EACC,qBAAA;EAtuBJ,yEAAA;EACQ,iEAAA;;AM4JV,UN+kBE;EACE,cAAA;EACA,qBAAA;EACA,yBAAA;;AMllBJ,UNqlBE;EACE,cAAA;;AM5kBJ;EACE,gBAAA;;AASF;EACE,cAAA;EACA,eAAA;EACA,mBAAA;EACA,cAAA;;AAgEF,QA7CqC;EA6CrC,YA3CI;IACE,qBAAA;IACA,gBAAA;IACA,sBAAA;;EAwCN,YApCI;IACE,qBAAA;IACA,WAAA;IACA,sBAAA;;EAiCN,YA9BI;IACE,gBAAA;IACA,sBAAA;;EA4BN,YAtBI;EAsBJ,YArBI;IACE,qBAAA;IACA,aAAA;IACA,gBAAA;IACA,eAAA;IACA,sBAAA;;EAgBN,YAdI,OAAO,MAAK;EAchB,YAbI,UAAU,MAAK;IACb,WAAA;IACA,cAAA;;EAWN,YAJI,cAAc;IACZ,MAAA;;;AAWN,gBAGE;AAHF,gBAIE;AAJF,gBAKE;AALF,gBAME;AANF,gBAOE;EACE,aAAA;EACA,gBAAA;EACA,gBAAA;;AAVJ,gBAcE;AAdF,gBAeE;EACE,gBAAA;;AAhBJ,gBAoBE;ENiQA,kBAAA;EACA,mBAAA;;AMtRF,gBAwBE;EACE,gBAAA;;AAUF,QANmC;EAMnC,gBALE;IACE,iBAAA;;;AA/BN,gBAuCE,cAAc;EACZ,MAAA;EACA,WAAA;;ACxZJ;EACE,qBAAA;EACA,gBAAA;EACA,mBAAA;EACA,kBAAA;EACA,sBAAA;EACA,eAAA;EACA,sBAAA;EACA,6BAAA;EACA,mBAAA;EP4gBA,iBAAA;EACA,eAAA;EACA,wBAAA;EACA,kBAAA;EApSA,yBAAA;EACG,sBAAA;EACC,qBAAA;EACC,oBAAA;EACG,iBAAA;;AO3OR,IAAC;EPWD,oBAAA;EAEA,0CAAA;EACA,oBAAA;;AOVA,IAAC;AACD,IAAC;EACC,cAAA;EACA,qBAAA;;AAGF,IAAC;AACD,IAAC;EACC,UAAA;EACA,sBAAA;EPwFF,wDAAA;EACQ,gDAAA;;AOrFR,IAAC;AACD,IAAC;AACD,QAAQ,UAAW;EACjB,mBAAA;EACA,oBAAA;EPqPF,aAAA;EAGA,yBAAA;EAxKA,wBAAA;EACQ,gBAAA;;AOvEV;EPicE,cAAA;EACA,yBAAA;EACA,qBAAA;;AAEA,YAAC;AACD,YAAC;AACD,YAAC;AACD,YAAC;AACD,KAAM,iBAAgB;EACpB,cAAA;EACA,yBAAA;EACI,qBAAA;;AAEN,YAAC;AACD,YAAC;AACD,KAAM,iBAAgB;EACpB,sBAAA;;AAKA,YAHD;AAGC,YAFD;AAEC,QADM,UAAW;AAEjB,YAJD,SAIE;AAAD,YAHD,UAGE;AAAD,QAFM,UAAW,aAEhB;AACD,YALD,SAKE;AAAD,YAJD,UAIE;AAAD,QAHM,UAAW,aAGhB;AACD,YAND,SAME;AAAD,YALD,UAKE;AAAD,QAJM,UAAW,aAIhB;AACD,YAPD,SAOE;AAAD,YAND,UAME;AAAD,QALM,UAAW,aAKhB;EACC,yBAAA;EACI,qBAAA;;AO5dV,YPgeE;EACE,cAAA;EACA,yBAAA;;AO/dJ;EP8bE,cAAA;EACA,yBAAA;EACA,qBAAA;;AAEA,YAAC;AACD,YAAC;AACD,YAAC;AACD,YAAC;AACD,KAAM,iBAAgB;EACpB,cAAA;EACA,yBAAA;EACI,qBAAA;;AAEN,YAAC;AACD,YAAC;AACD,KAAM,iBAAgB;EACpB,sBAAA;;AAKA,YAHD;AAGC,YAFD;AAEC,QADM,UAAW;AAEjB,YAJD,SAIE;AAAD,YAHD,UAGE;AAAD,QAFM,UAAW,aAEhB;AACD,YALD,SAKE;AAAD,YAJD,UAIE;AAAD,QAHM,UAAW,aAGhB;AACD,YAND,SAME;AAAD,YALD,UAKE;AAAD,QAJM,UAAW,aAIhB;AACD,YAPD,SAOE;AAAD,YAND,UAME;AAAD,QALM,UAAW,aAKhB;EACC,yBAAA;EACI,qBAAA;;AOzdV,YP6dE;EACE,cAAA;EACA,yBAAA;;AO3dJ;EP0bE,cAAA;EACA,yBAAA;EACA,qBAAA;;AAEA,YAAC;AACD,YAAC;AACD,YAAC;AACD,YAAC;AACD,KAAM,iBAAgB;EACpB,cAAA;EACA,yBAAA;EACI,qBAAA;;AAEN,YAAC;AACD,YAAC;AACD,KAAM,iBAAgB;EACpB,sBAAA;;AAKA,YAHD;AAGC,YAFD;AAEC,QADM,UAAW;AAEjB,YAJD,SAIE;AAAD,YAHD,UAGE;AAAD,QAFM,UAAW,aAEhB;AACD,YALD,SAKE;AAAD,YAJD,UAIE;AAAD,QAHM,UAAW,aAGhB;AACD,YAND,SAME;AAAD,YALD,UAKE;AAAD,QAJM,UAAW,aAIhB;AACD,YAPD,SAOE;AAAD,YAND,UAME;AAAD,QALM,UAAW,aAKhB;EACC,yBAAA;EACI,qBAAA;;AOrdV,YPydE;EACE,cAAA;EACA,yBAAA;;AOvdJ;EPsbE,cAAA;EACA,yBAAA;EACA,qBAAA;;AAEA,SAAC;AACD,SAAC;AACD,SAAC;AACD,SAAC;AACD,KAAM,iBAAgB;EACpB,cAAA;EACA,yBAAA;EACI,qBAAA;;AAEN,SAAC;AACD,SAAC;AACD,KAAM,iBAAgB;EACpB,sBAAA;;AAKA,SAHD;AAGC,SAFD;AAEC,QADM,UAAW;AAEjB,SAJD,SAIE;AAAD,SAHD,UAGE;AAAD,QAFM,UAAW,UAEhB;AACD,SALD,SAKE;AAAD,SAJD,UAIE;AAAD,QAHM,UAAW,UAGhB;AACD,SAND,SAME;AAAD,SALD,UAKE;AAAD,QAJM,UAAW,UAIhB;AACD,SAPD,SAOE;AAAD,SAND,UAME;AAAD,QALM,UAAW,UAKhB;EACC,yBAAA;EACI,qBAAA;;AOjdV,SPqdE;EACE,cAAA;EACA,yBAAA;;AOndJ;EPkbE,cAAA;EACA,yBAAA;EACA,qBAAA;;AAEA,YAAC;AACD,YAAC;AACD,YAAC;AACD,YAAC;AACD,KAAM,iBAAgB;EACpB,cAAA;EACA,yBAAA;EACI,qBAAA;;AAEN,YAAC;AACD,YAAC;AACD,KAAM,iBAAgB;EACpB,sBAAA;;AAKA,YAHD;AAGC,YAFD;AAEC,QADM,UAAW;AAEjB,YAJD,SAIE;AAAD,YAHD,UAGE;AAAD,QAFM,UAAW,aAEhB;AACD,YALD,SAKE;AAAD,YAJD,UAIE;AAAD,QAHM,UAAW,aAGhB;AACD,YAND,SAME;AAAD,YALD,UAKE;AAAD,QAJM,UAAW,aAIhB;AACD,YAPD,SAOE;AAAD,YAND,UAME;AAAD,QALM,UAAW,aAKhB;EACC,yBAAA;EACI,qBAAA;;AO7cV,YPidE;EACE,cAAA;EACA,yBAAA;;AO/cJ;EP8aE,cAAA;EACA,yBAAA;EACA,qBAAA;;AAEA,WAAC;AACD,WAAC;AACD,WAAC;AACD,WAAC;AACD,KAAM,iBAAgB;EACpB,cAAA;EACA,yBAAA;EACI,qBAAA;;AAEN,WAAC;AACD,WAAC;AACD,KAAM,iBAAgB;EACpB,sBAAA;;AAKA,WAHD;AAGC,WAFD;AAEC,QADM,UAAW;AAEjB,WAJD,SAIE;AAAD,WAHD,UAGE;AAAD,QAFM,UAAW,YAEhB;AACD,WALD,SAKE;AAAD,WAJD,UAIE;AAAD,QAHM,UAAW,YAGhB;AACD,WAND,SAME;AAAD,WALD,UAKE;AAAD,QAJM,UAAW,YAIhB;AACD,WAPD,SAOE;AAAD,WAND,UAME;AAAD,QALM,UAAW,YAKhB;EACC,yBAAA;EACI,qBAAA;;AOzcV,WP6cE;EACE,cAAA;EACA,yBAAA;;AOtcJ;EACE,cAAA;EACA,mBAAA;EACA,eAAA;EACA,gBAAA;;AAEA;AACA,SAAC;AACD,SAAC;AACD,QAAQ,UAAW;EACjB,6BAAA;EPgCF,wBAAA;EACQ,gBAAA;;AO9BR;AACA,SAAC;AACD,SAAC;AACD,SAAC;EACC,yBAAA;;AAEF,SAAC;AACD,SAAC;EACC,cAAA;EACA,0BAAA;EACA,6BAAA;;AAIA,SAFD,UAEE;AAAD,QADM,UAAW,UAChB;AACD,SAHD,UAGE;AAAD,QAFM,UAAW,UAEhB;EACC,cAAA;EACA,qBAAA;;AASN;EPsaE,kBAAA;EACA,eAAA;EACA,iBAAA;EACA,kBAAA;;AOraF;EPkaE,iBAAA;EACA,eAAA;EACA,gBAAA;EACA,kBAAA;;AOjaF;EP8ZE,gBAAA;EACA,eAAA;EACA,gBAAA;EACA,kBAAA;;AOzZF;EACE,cAAA;EACA,WAAA;EACA,eAAA;EACA,gBAAA;;AAIF,UAAW;EACT,eAAA;;AAOA,KAHG,eAGF;AAAD,KAFG,cAEF;AAAD,KADG,eACF;EACC,WAAA;;AC/IJ;EACE,UAAA;ERsHA,wCAAA;EACQ,gCAAA;;AQrHR,KAAC;EACC,UAAA;;AAIJ;EACE,aAAA;;AACA,SAAC;EACC,cAAA;;AAGJ;EACE,kBAAA;EACA,SAAA;EACA,gBAAA;ERsGA,qCAAA;EACQ,6BAAA;;ASvHV;EACE,aAAa,sBAAb;EACA,qDAAA;EACA,2TAAA;;AAOF;EACE,kBAAA;EACA,QAAA;EACA,qBAAA;EACA,aAAa,sBAAb;EACA,kBAAA;EACA,mBAAA;EACA,cAAA;EACA,mCAAA;EACA,kCAAA;;AAIkC,mBAAC;EAAU,SAAS,KAAT;;AACX,eAAC;EAAU,SAAS,KAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,mBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,mBAAC;EAAU,SAAS,OAAT;;AACX,aAAC;EAAU,SAAS,OAAT;;AACX,kBAAC;EAAU,SAAS,OAAT;;AACX,aAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,kBAAC;EAAU,SAAS,OAAT;;AACX,mBAAC;EAAU,SAAS,OAAT;;AACX,cAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,cAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,uBAAC;EAAU,SAAS,OAAT;;AACX,mBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,kBAAC;EAAU,SAAS,OAAT;;AACX,mBAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,kBAAC;EAAU,SAAS,OAAT;;AACX,cAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,mBAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,uBAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,wBAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,uBAAC;EAAU,SAAS,OAAT;;AACX,yBAAC;EAAU,SAAS,OAAT;;AACX,kBAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,wBAAC;EAAU,SAAS,OAAT;;AACX,wBAAC;EAAU,SAAS,OAAT;;AACX,mBAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,kBAAC;EAAU,SAAS,OAAT;;AACX,uBAAC;EAAU,SAAS,OAAT;;AACX,uBAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,uBAAC;EAAU,SAAS,OAAT;;AACX,wBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,kBAAC;EAAU,SAAS,OAAT;;AACX,wBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,wBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,mBAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,uBAAC;EAAU,SAAS,OAAT;;AACX,2BAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,mBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,uBAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,mBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,kBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,uBAAC;EAAU,SAAS,OAAT;;AACX,kBAAC;EAAU,SAAS,OAAT;;AACX,wBAAC;EAAU,SAAS,OAAT;;AACX,uBAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,0BAAC;EAAU,SAAS,OAAT;;AACX,4BAAC;EAAU,SAAS,OAAT;;AACX,cAAC;EAAU,SAAS,OAAT;;AACX,mBAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,kBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,6BAAC;EAAU,SAAS,OAAT;;AACX,4BAAC;EAAU,SAAS,OAAT;;AACX,0BAAC;EAAU,SAAS,OAAT;;AACX,4BAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,kBAAC;EAAU,SAAS,OAAT;;AACX,cAAC;EAAU,SAAS,OAAT;;AACX,cAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,2BAAC;EAAU,SAAS,OAAT;;AACX,+BAAC;EAAU,SAAS,OAAT;;AACX,wBAAC;EAAU,SAAS,OAAT;;AACX,4BAAC;EAAU,SAAS,OAAT;;AACX,6BAAC;EAAU,SAAS,OAAT;;AACX,iCAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,wBAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,kBAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,eAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,uBAAC;EAAU,SAAS,OAAT;;AACX,wBAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,mBAAC;EAAU,SAAS,OAAT;;AACX,kBAAC;EAAU,SAAS,OAAT;;AACX,iBAAC;EAAU,SAAS,OAAT;;AACX,qBAAC;EAAU,SAAS,OAAT;;AACX,mBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,gBAAC;EAAU,SAAS,OAAT;;AACX,mBAAC;EAAU,SAAS,OAAT;;AACX,mBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,uBAAC;EAAU,SAAS,OAAT;;AACX,sBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,oBAAC;EAAU,SAAS,OAAT;;AACX,yBAAC;EAAU,SAAS,OAAT;;AACX,4BAAC;EAAU,SAAS,OAAT;;AACX,yBAAC;EAAU,SAAS,OAAT;;AACX,uBAAC;EAAU,SAAS,OAAT;;AACX,uBAAC;EAAU,SAAS,OAAT;;AACX,yBAAC;EAAU,SAAS,OAAT;;AClO/C;EACE,qBAAA;EACA,QAAA;EACA,SAAA;EACA,gBAAA;EACA,sBAAA;EACA,qBAAA;EACA,mCAAA;EACA,kCAAA;;AAIF;EACE,kBAAA;;AAIF,gBAAgB;EACd,UAAA;;AAIF;EACE,kBAAA;EACA,SAAA;EACA,OAAA;EACA,aAAA;EACA,aAAA;EACA,WAAA;EACA,gBAAA;EACA,cAAA;EACA,eAAA;EACA,gBAAA;EACA,eAAA;EACA,yBAAA;EACA,yBAAA;EACA,qCAAA;EACA,kBAAA;EV+EA,mDAAA;EACQ,2CAAA;EU9ER,4BAAA;;AAKA,cAAC;EACC,QAAA;EACA,UAAA;;AAxBJ,cA4BE;EVsVA,WAAA;EACA,aAAA;EACA,gBAAA;EACA,yBAAA;;AUrXF,cAiCE,KAAK;EACH,cAAA;EACA,iBAAA;EACA,WAAA;EACA,mBAAA;EACA,wBAAA;EACA,cAAA;EACA,mBAAA;;AAMF,cADa,KAAK,IACjB;AACD,cAFa,KAAK,IAEjB;EACC,qBAAA;EACA,cAAA;EACA,yBAAA;;AAMF,cADa,UAAU;AAEvB,cAFa,UAAU,IAEtB;AACD,cAHa,UAAU,IAGtB;EACC,cAAA;EACA,qBAAA;EACA,UAAA;EACA,yBAAA;;AASF,cADa,YAAY;AAEzB,cAFa,YAAY,IAExB;AACD,cAHa,YAAY,IAGxB;EACC,cAAA;;AAKF,cADa,YAAY,IACxB;AACD,cAFa,YAAY,IAExB;EACC,qBAAA;EACA,6BAAA;EACA,sBAAA;EVoPF,mEAAA;EUlPE,mBAAA;;AAKJ,KAEE;EACE,cAAA;;AAHJ,KAOE;EACE,UAAA;;AAQJ;EACE,UAAA;EACA,QAAA;;AAQF;EACE,OAAA;EACA,WAAA;;AAIF;EACE,cAAA;EACA,iBAAA;EACA,eAAA;EACA,wBAAA;EACA,cAAA;;AAIF;EACE,eAAA;EACA,OAAA;EACA,QAAA;EACA,SAAA;EACA,MAAA;EACA,YAAA;;AAIF,WAAY;EACV,QAAA;EACA,UAAA;;AAQF,OAGE;AAFF,oBAAqB,UAEnB;EACE,aAAA;EACA,wBAAA;EACA,SAAS,EAAT;;AANJ,OASE;AARF,oBAAqB,UAQnB;EACE,SAAA;EACA,YAAA;EACA,kBAAA;;AAsBJ,QAb2C;EACzC,aACE;IAnEF,UAAA;IACA,QAAA;;EAiEA,aAME;IA9DF,OAAA;IACA,WAAA;;;AC7IF;AACA;EACE,kBAAA;EACA,qBAAA;EACA,sBAAA;;AAJF,UAKE;AAJF,mBAIE;EACE,kBAAA;EACA,WAAA;;AAEA,UAJF,OAIG;AAAD,mBAJF,OAIG;AACD,UALF,OAKG;AAAD,mBALF,OAKG;AACD,UANF,OAMG;AAAD,mBANF,OAMG;AACD,UAPF,OAOG;AAAD,mBAPF,OAOG;EACC,UAAA;;AAEF,UAVF,OAUG;AAAD,mBAVF,OAUG;EAEC,aAAA;;AAMN,UACE,KAAK;AADP,UAEE,KAAK;AAFP,UAGE,WAAW;AAHb,UAIE,WAAW;EACT,iBAAA;;AAKJ;EACE,iBAAA;;AADF,YAIE;AAJF,YAKE;EACE,WAAA;;AANJ,YAQE;AARF,YASE;AATF,YAUE;EACE,gBAAA;;AAIJ,UAAW,OAAM,IAAI,cAAc,IAAI,aAAa,IAAI;EACtD,gBAAA;;AAIF,UAAW,OAAM;EACf,cAAA;;AACA,UAFS,OAAM,YAEd,IAAI,aAAa,IAAI;EX4CtB,6BAAA;EACG,0BAAA;;AWxCL,UAAW,OAAM,WAAW,IAAI;AAChC,UAAW,mBAAkB,IAAI;EX8C/B,4BAAA;EACG,yBAAA;;AW1CL,UAAW;EACT,WAAA;;AAEF,UAAW,aAAY,IAAI,cAAc,IAAI,aAAc;EACzD,gBAAA;;AAEF,UAAW,aAAY,YACrB,OAAM;AADR,UAAW,aAAY,YAErB;EXyBA,6BAAA;EACG,0BAAA;;AWtBL,UAAW,aAAY,WAAY,OAAM;EX6BvC,4BAAA;EACG,yBAAA;;AWzBL,UAAW,iBAAgB;AAC3B,UAAU,KAAM;EACd,UAAA;;AAQF,aAAc;EX2bZ,gBAAA;EACA,eAAA;EACA,gBAAA;EACA,kBAAA;;AW7bF,aAAc;EX0bZ,iBAAA;EACA,eAAA;EACA,gBAAA;EACA,kBAAA;;AW5bF,aAAc;EXybZ,kBAAA;EACA,eAAA;EACA,iBAAA;EACA,kBAAA;;AWrbF,UAAW,OAAO;EAChB,iBAAA;EACA,kBAAA;;AAEF,UAAW,UAAU;EACnB,kBAAA;EACA,mBAAA;;AAKF,UAAU,KAAM;EXId,wDAAA;EACQ,gDAAA;;AWDR,UAJQ,KAAM,iBAIb;EXAD,wBAAA;EACQ,gBAAA;;AWMV,IAAK;EACH,cAAA;;AAGF,OAAQ;EACN,uBAAA;EACA,sBAAA;;AAGF,OAAQ,QAAQ;EACd,uBAAA;;AAOF,mBACE;AADF,mBAEE;AAFF,mBAGE,aAAa;EACX,cAAA;EACA,WAAA;EACA,WAAA;EACA,eAAA;;AAPJ,mBAWE,aAEE;EACE,WAAA;;AAdN,mBAkBE,OAAO;AAlBT,mBAmBE,OAAO;AAnBT,mBAoBE,aAAa;AApBf,mBAqBE,aAAa;EACX,gBAAA;EACA,cAAA;;AAKF,mBADkB,OACjB,IAAI,cAAc,IAAI;EACrB,gBAAA;;AAEF,mBAJkB,OAIjB,YAAY,IAAI;EACf,4BAAA;EXtEF,6BAAA;EACC,4BAAA;;AWwED,mBARkB,OAQjB,WAAW,IAAI;EACd,8BAAA;EXlFF,0BAAA;EACC,yBAAA;;AWqFH,mBAAoB,aAAY,IAAI,cAAc,IAAI,aAAc;EAClE,gBAAA;;AAEF,mBAAoB,aAAY,YAAY,IAAI,aAC9C,OAAM;AADR,mBAAoB,aAAY,YAAY,IAAI,aAE9C;EXnFA,6BAAA;EACC,4BAAA;;AWsFH,mBAAoB,aAAY,WAAW,IAAI,cAAe,OAAM;EX/FlE,0BAAA;EACC,yBAAA;;AWuGH;EACE,cAAA;EACA,WAAA;EACA,mBAAA;EACA,yBAAA;;AAJF,oBAKE;AALF,oBAME;EACE,WAAA;EACA,mBAAA;EACA,SAAA;;AATJ,oBAWE,aAAa;EACX,WAAA;;AAMJ,uBAAwB,OAAO,QAAO;AACtC,uBAAwB,OAAO,QAAO;EACpC,aAAA;;AC1NF;EACE,kBAAA;EACA,cAAA;EACA,yBAAA;;AAGA,YAAC;EACC,WAAA;EACA,eAAA;EACA,gBAAA;;AATJ,YAYE;EAIE,WAAA;EAEA,WAAA;EACA,gBAAA;;AASJ,eAAgB;AAChB,eAAgB;AAChB,eAAgB,mBAAmB;EZ02BjC,YAAA;EACA,kBAAA;EACA,eAAA;EACA,iBAAA;EACA,kBAAA;;AAEA,MAAM,eYl3BQ;AZk3Bd,MAAM,eYj3BQ;AZi3Bd,MAAM,eYh3BQ,mBAAmB;EZi3B/B,YAAA;EACA,iBAAA;;AAGF,QAAQ,eYv3BM;AZu3Bd,QAAQ,eYt3BM;AZs3Bd,QAAQ,eYr3BM,mBAAmB;AZs3BjC,MAAM,UAAU,eYx3BF;AZw3Bd,MAAM,UAAU,eYv3BF;AZu3Bd,MAAM,UAAU,eYt3BF,mBAAmB;EZu3B/B,YAAA;;AYt3BJ,eAAgB;AAChB,eAAgB;AAChB,eAAgB,mBAAmB;EZu2BjC,YAAA;EACA,iBAAA;EACA,eAAA;EACA,gBAAA;EACA,kBAAA;;AAEA,MAAM,eY/2BQ;AZ+2Bd,MAAM,eY92BQ;AZ82Bd,MAAM,eY72BQ,mBAAmB;EZ82B/B,YAAA;EACA,iBAAA;;AAGF,QAAQ,eYp3BM;AZo3Bd,QAAQ,eYn3BM;AZm3Bd,QAAQ,eYl3BM,mBAAmB;AZm3BjC,MAAM,UAAU,eYr3BF;AZq3Bd,MAAM,UAAU,eYp3BF;AZo3Bd,MAAM,UAAU,eYn3BF,mBAAmB;EZo3B/B,YAAA;;AY/2BJ;AACA;AACA,YAAa;EACX,mBAAA;;AAEA,kBAAC,IAAI,cAAc,IAAI;AAAvB,gBAAC,IAAI,cAAc,IAAI;AAAvB,YAHW,cAGV,IAAI,cAAc,IAAI;EACrB,gBAAA;;AAIJ;AACA;EACE,SAAA;EACA,mBAAA;EACA,sBAAA;;AAKF;EACE,iBAAA;EACA,eAAA;EACA,mBAAA;EACA,cAAA;EACA,cAAA;EACA,kBAAA;EACA,yBAAA;EACA,yBAAA;EACA,kBAAA;;AAGA,kBAAC;EACC,iBAAA;EACA,eAAA;EACA,kBAAA;;AAEF,kBAAC;EACC,kBAAA;EACA,eAAA;EACA,kBAAA;;AApBJ,kBAwBE,MAAK;AAxBP,kBAyBE,MAAK;EACH,aAAA;;AAKJ,YAAa,cAAa;AAC1B,kBAAkB;AAClB,gBAAgB,YAAa;AAC7B,gBAAgB,YAAa,aAAa;AAC1C,gBAAgB,YAAa;AAC7B,gBAAgB,WAAY,OAAM,IAAI,aAAa,IAAI;AACvD,gBAAgB,WAAY,aAAY,IAAI,aAAc;EZIxD,6BAAA;EACG,0BAAA;;AYFL,kBAAkB;EAChB,eAAA;;AAEF,YAAa,cAAa;AAC1B,kBAAkB;AAClB,gBAAgB,WAAY;AAC5B,gBAAgB,WAAY,aAAa;AACzC,gBAAgB,WAAY;AAC5B,gBAAgB,YAAa,OAAM,IAAI;AACvC,gBAAgB,YAAa,aAAY,IAAI,cAAe;EZA1D,4BAAA;EACG,yBAAA;;AYEL,kBAAkB;EAChB,cAAA;;AAKF;EACE,kBAAA;EAGA,YAAA;EACA,mBAAA;;AALF,gBASE;EACE,kBAAA;;AAVJ,gBASE,OAEE;EACE,iBAAA;;AAGF,gBANF,OAMG;AACD,gBAPF,OAOG;AACD,gBARF,OAQG;EACC,UAAA;;AAKJ,gBAAC,YACC;AADF,gBAAC,YAEC;EACE,kBAAA;;AAGJ,gBAAC,WACC;AADF,gBAAC,WAEC;EACE,iBAAA;;ACjJN;EACE,gBAAA;EACA,eAAA;EACA,gBAAA;;AAHF,IAME;EACE,kBAAA;EACA,cAAA;;AARJ,IAME,KAIE;EACE,kBAAA;EACA,cAAA;EACA,kBAAA;;AACA,IARJ,KAIE,IAIG;AACD,IATJ,KAIE,IAKG;EACC,qBAAA;EACA,yBAAA;;AAKJ,IAhBF,KAgBG,SAAU;EACT,cAAA;;AAEA,IAnBJ,KAgBG,SAAU,IAGR;AACD,IApBJ,KAgBG,SAAU,IAIR;EACC,cAAA;EACA,qBAAA;EACA,6BAAA;EACA,mBAAA;;AAOJ,IADF,MAAM;AAEJ,IAFF,MAAM,IAEH;AACD,IAHF,MAAM,IAGH;EACC,yBAAA;EACA,qBAAA;;AAzCN,IAkDE;EboVA,WAAA;EACA,aAAA;EACA,gBAAA;EACA,yBAAA;;AazYF,IAyDE,KAAK,IAAI;EACP,eAAA;;AASJ;EACE,gCAAA;;AADF,SAEE;EACE,WAAA;EAEA,mBAAA;;AALJ,SAEE,KAME;EACE,iBAAA;EACA,wBAAA;EACA,6BAAA;EACA,0BAAA;;AACA,SAXJ,KAME,IAKG;EACC,qCAAA;;AAMF,SAlBJ,KAiBG,OAAQ;AAEP,SAnBJ,KAiBG,OAAQ,IAEN;AACD,SApBJ,KAiBG,OAAQ,IAGN;EACC,cAAA;EACA,yBAAA;EACA,yBAAA;EACA,gCAAA;EACA,eAAA;;AAKN,SAAC;EAqDD,WAAA;EA8BA,gBAAA;;AAnFA,SAAC,cAuDD;EACE,WAAA;;AAxDF,SAAC,cAuDD,KAEG;EACC,kBAAA;EACA,kBAAA;;AA3DJ,SAAC,cA+DD,YAAY;EACV,SAAA;EACA,UAAA;;AAYJ,QATqC;EASrC,SA7EG,cAqEC;IACE,mBAAA;IACA,SAAA;;EAMN,SA7EG,cAqEC,KAGE;IACE,gBAAA;;;AAzEN,SAAC,cAqFD,KAAK;EAEH,eAAA;EACA,kBAAA;;AAxFF,SAAC,cA2FD,UAAU;AA3FV,SAAC,cA4FD,UAAU,IAAG;AA5Fb,SAAC,cA6FD,UAAU,IAAG;EACX,yBAAA;;AAcJ,QAXqC;EAWrC,SA5GG,cAkGC,KAAK;IACH,gCAAA;IACA,0BAAA;;EAQN,SA5GG,cAsGC,UAAU;EAMd,SA5GG,cAuGC,UAAU,IAAG;EAKjB,SA5GG,cAwGC,UAAU,IAAG;IACX,4BAAA;;;AAhGN,UACE;EACE,WAAA;;AAFJ,UACE,KAIE;EACE,kBAAA;;AANN,UACE,KAOE;EACE,gBAAA;;AAKA,UAbJ,KAYG,OAAQ;AAEP,UAdJ,KAYG,OAAQ,IAEN;AACD,UAfJ,KAYG,OAAQ,IAGN;EACC,cAAA;EACA,yBAAA;;AAQR,YACE;EACE,WAAA;;AAFJ,YACE,KAEE;EACE,eAAA;EACA,cAAA;;AAYN;EACE,WAAA;;AADF,cAGE;EACE,WAAA;;AAJJ,cAGE,KAEG;EACC,kBAAA;EACA,kBAAA;;AAPN,cAWE,YAAY;EACV,SAAA;EACA,UAAA;;AAYJ,QATqC;EASrC,cARI;IACE,mBAAA;IACA,SAAA;;EAMN,cARI,KAGE;IACE,gBAAA;;;AASR;EACE,gBAAA;;AADF,mBAGE,KAAK;EAEH,eAAA;EACA,kBAAA;;AANJ,mBASE,UAAU;AATZ,mBAUE,UAAU,IAAG;AAVf,mBAWE,UAAU,IAAG;EACX,yBAAA;;AAcJ,QAXqC;EAWrC,mBAVI,KAAK;IACH,gCAAA;IACA,0BAAA;;EAQN,mBANI,UAAU;EAMd,mBALI,UAAU,IAAG;EAKjB,mBAJI,UAAU,IAAG;IACX,4BAAA;;;AAUN,YACE;EACE,aAAA;;AAFJ,YAIE;EACE,cAAA;;AASJ,SAAU;EAER,gBAAA;Eb1IA,0BAAA;EACC,yBAAA;;Ac3FH;EACE,kBAAA;EACA,gBAAA;EACA,mBAAA;EACA,6BAAA;;AAQF,QAH6C;EAG7C;IAFI,kBAAA;;;AAgBJ,QAH6C;EAG7C;IAFI,WAAA;;;AAeJ;EACE,iBAAA;EACA,mBAAA;EACA,mBAAA;EACA,kBAAA;EACA,iCAAA;EACA,kDAAA;EAEA,iCAAA;;AAEA,gBAAC;EACC,gBAAA;;AA4BJ,QAzB6C;EAyB7C;IAxBI,WAAA;IACA,aAAA;IACA,gBAAA;;EAEA,gBAAC;IACC,yBAAA;IACA,uBAAA;IACA,iBAAA;IACA,4BAAA;;EAGF,gBAAC;IACC,mBAAA;;EAKF,iBAAkB;EAClB,kBAAmB;EACnB,oBAAqB;IACnB,eAAA;IACA,gBAAA;;;AAUN,UAEE;AADF,gBACE;AAFF,UAGE;AAFF,gBAEE;EACE,mBAAA;EACA,kBAAA;;AAMF,QAJ6C;EAI7C,UATA;EASA,gBATA;EASA,UARA;EAQA,gBARA;IAKI,eAAA;IACA,cAAA;;;AAaN;EACE,aAAA;EACA,qBAAA;;AAKF,QAH6C;EAG7C;IAFI,gBAAA;;;AAKJ;AACA;EACE,eAAA;EACA,QAAA;EACA,OAAA;EACA,aAAA;;AAMF,QAH6C;EAG7C;EAAA;IAFI,gBAAA;;;AAGJ;EACE,MAAA;EACA,qBAAA;;AAEF;EACE,SAAA;EACA,gBAAA;EACA,qBAAA;;AAMF;EACE,WAAA;EACA,kBAAA;EACA,eAAA;EACA,iBAAA;EACA,YAAA;;AAEA,aAAC;AACD,aAAC;EACC,qBAAA;;AASJ,QAN6C;EACzC,OAAQ,aAAa;EACrB,OAAQ,mBAAmB;IACzB,kBAAA;;;AAWN;EACE,kBAAA;EACA,YAAA;EACA,kBAAA;EACA,iBAAA;EdwaA,eAAA;EACA,kBAAA;EcvaA,6BAAA;EACA,sBAAA;EACA,6BAAA;EACA,kBAAA;;AAIA,cAAC;EACC,aAAA;;AAdJ,cAkBE;EACE,cAAA;EACA,WAAA;EACA,WAAA;EACA,kBAAA;;AAtBJ,cAwBE,UAAU;EACR,eAAA;;AAMJ,QAH6C;EAG7C;IAFI,aAAA;;;AAUJ;EACE,mBAAA;;AADF,WAGE,KAAK;EACH,iBAAA;EACA,oBAAA;EACA,iBAAA;;AA2BF,QAxB+C;EAwB/C,WAtBE,MAAM;IACJ,gBAAA;IACA,WAAA;IACA,WAAA;IACA,aAAA;IACA,6BAAA;IACA,SAAA;IACA,gBAAA;;EAeJ,WAtBE,MAAM,eAQJ,KAAK;EAcT,WAtBE,MAAM,eASJ;IACE,0BAAA;;EAYN,WAtBE,MAAM,eAYJ,KAAK;IACH,iBAAA;;EACA,WAdJ,MAAM,eAYJ,KAAK,IAEF;EACD,WAfJ,MAAM,eAYJ,KAAK,IAGF;IACC,sBAAA;;;AAuBV,QAhB6C;EAgB7C;IAfI,WAAA;IACA,SAAA;;EAcJ,WAZI;IACE,WAAA;;EAWN,WAZI,KAEE;IACE,iBAAA;IACA,oBAAA;;EAIJ,WAAC,aAAa;IACZ,mBAAA;;;AAkBN,QAN2C;EACzC;ICnQA,sBAAA;;EDoQA;ICvQA,uBAAA;;;ADgRF;EACE,kBAAA;EACA,mBAAA;EACA,kBAAA;EACA,iCAAA;EACA,oCAAA;Ed1KA,4FAAA;EACQ,oFAAA;EAmeR,eAAA;EACA,kBAAA;;AMhPF,QA7CqC;EA6CrC,YA3CI;IACE,qBAAA;IACA,gBAAA;IACA,sBAAA;;EAwCN,YApCI;IACE,qBAAA;IACA,WAAA;IACA,sBAAA;;EAiCN,YA9BI;IACE,gBAAA;IACA,sBAAA;;EA4BN,YAtBI;EAsBJ,YArBI;IACE,qBAAA;IACA,aAAA;IACA,gBAAA;IACA,eAAA;IACA,sBAAA;;EAgBN,YAdI,OAAO,MAAK;EAchB,YAbI,UAAU,MAAK;IACb,WAAA;IACA,cAAA;;EAWN,YAJI,cAAc;IACZ,MAAA;;;AQ7DJ,QAHiD;EAGjD,YAJA;IAEI,kBAAA;;;AAsBN,QAd6C;EAc7C;IAbI,WAAA;IACA,SAAA;IACA,cAAA;IACA,eAAA;IACA,cAAA;IACA,iBAAA;IdjMF,wBAAA;IACQ,gBAAA;;EcoMN,YAAC,aAAa;IACZ,mBAAA;;;AASN,WAAY,KAAK;EACf,aAAA;EdtOA,0BAAA;EACC,yBAAA;;AcyOH,oBAAqB,YAAY,KAAK;EdlOpC,6BAAA;EACC,4BAAA;;Ac0OH;EduQE,eAAA;EACA,kBAAA;;AcrQA,WAAC;EdoQD,gBAAA;EACA,mBAAA;;AclQA,WAAC;EdiQD,gBAAA;EACA,mBAAA;;AcxPF;EduPE,gBAAA;EACA,mBAAA;;Ac3OF,QAV6C;EAU7C;IATI,WAAA;IACA,iBAAA;IACA,kBAAA;;EAGA,YAAC,aAAa;IACZ,eAAA;;;AASN;EACE,yBAAA;EACA,qBAAA;;AAFF,eAIE;EACE,cAAA;;AACA,eAFF,cAEG;AACD,eAHF,cAGG;EACC,cAAA;EACA,6BAAA;;AATN,eAaE;EACE,cAAA;;AAdJ,eAiBE,YACE,KAAK;EACH,cAAA;;AAEA,eAJJ,YACE,KAAK,IAGF;AACD,eALJ,YACE,KAAK,IAIF;EACC,cAAA;EACA,6BAAA;;AAIF,eAXJ,YAUE,UAAU;AAER,eAZJ,YAUE,UAAU,IAEP;AACD,eAbJ,YAUE,UAAU,IAGP;EACC,cAAA;EACA,yBAAA;;AAIF,eAnBJ,YAkBE,YAAY;AAEV,eApBJ,YAkBE,YAAY,IAET;AACD,eArBJ,YAkBE,YAAY,IAGT;EACC,cAAA;EACA,6BAAA;;AAxCR,eA6CE;EACE,qBAAA;;AACA,eAFF,eAEG;AACD,eAHF,eAGG;EACC,yBAAA;;AAjDN,eA6CE,eAME;EACE,yBAAA;;AApDN,eAwDE;AAxDF,eAyDE;EACE,qBAAA;;AAOE,eAHJ,YAEE,QAAQ;AAEN,eAJJ,YAEE,QAAQ,IAEL;AACD,eALJ,YAEE,QAAQ,IAGL;EACC,yBAAA;EACA,cAAA;;AAiCN,QA7BiD;EA6BjD,eAxCA,YAaI,MAAM,eACJ,KAAK;IACH,cAAA;;EACA,eAhBR,YAaI,MAAM,eACJ,KAAK,IAEF;EACD,eAjBR,YAaI,MAAM,eACJ,KAAK,IAGF;IACC,cAAA;IACA,6BAAA;;EAIF,eAvBR,YAaI,MAAM,eASJ,UAAU;EAER,eAxBR,YAaI,MAAM,eASJ,UAAU,IAEP;EACD,eAzBR,YAaI,MAAM,eASJ,UAAU,IAGP;IACC,cAAA;IACA,yBAAA;;EAIF,eA/BR,YAaI,MAAM,eAiBJ,YAAY;EAEV,eAhCR,YAaI,MAAM,eAiBJ,YAAY,IAET;EACD,eAjCR,YAaI,MAAM,eAiBJ,YAAY,IAGT;IACC,cAAA;IACA,6BAAA;;;AAjGZ,eA6GE;EACE,cAAA;;AACA,eAFF,aAEG;EACC,cAAA;;AAQN;EACE,yBAAA;EACA,qBAAA;;AAFF,eAIE;EACE,cAAA;;AACA,eAFF,cAEG;AACD,eAHF,cAGG;EACC,cAAA;EACA,6BAAA;;AATN,eAaE;EACE,cAAA;;AAdJ,eAiBE,YACE,KAAK;EACH,cAAA;;AAEA,eAJJ,YACE,KAAK,IAGF;AACD,eALJ,YACE,KAAK,IAIF;EACC,cAAA;EACA,6BAAA;;AAIF,eAXJ,YAUE,UAAU;AAER,eAZJ,YAUE,UAAU,IAEP;AACD,eAbJ,YAUE,UAAU,IAGP;EACC,cAAA;EACA,yBAAA;;AAIF,eAnBJ,YAkBE,YAAY;AAEV,eApBJ,YAkBE,YAAY,IAET;AACD,eArBJ,YAkBE,YAAY,IAGT;EACC,cAAA;EACA,6BAAA;;AAxCR,eA8CE;EACE,qBAAA;;AACA,eAFF,eAEG;AACD,eAHF,eAGG;EACC,yBAAA;;AAlDN,eA8CE,eAME;EACE,yBAAA;;AArDN,eAyDE;AAzDF,eA0DE;EACE,qBAAA;;AAME,eAFJ,YACE,QAAQ;AAEN,eAHJ,YACE,QAAQ,IAEL;AACD,eAJJ,YACE,QAAQ,IAGL;EACC,yBAAA;EACA,cAAA;;AAuCN,QAnCiD;EAmCjD,eA7CA,YAYI,MAAM,eACJ;IACE,qBAAA;;EA+BR,eA7CA,YAYI,MAAM,eAIJ;IACE,yBAAA;;EA4BR,eA7CA,YAYI,MAAM,eAOJ,KAAK;IACH,cAAA;;EACA,eArBR,YAYI,MAAM,eAOJ,KAAK,IAEF;EACD,eAtBR,YAYI,MAAM,eAOJ,KAAK,IAGF;IACC,cAAA;IACA,6BAAA;;EAIF,eA5BR,YAYI,MAAM,eAeJ,UAAU;EAER,eA7BR,YAYI,MAAM,eAeJ,UAAU,IAEP;EACD,eA9BR,YAYI,MAAM,eAeJ,UAAU,IAGP;IACC,cAAA;IACA,yBAAA;;EAIF,eApCR,YAYI,MAAM,eAuBJ,YAAY;EAEV,eArCR,YAYI,MAAM,eAuBJ,YAAY,IAET;EACD,eAtCR,YAYI,MAAM,eAuBJ,YAAY,IAGT;IACC,cAAA;IACA,6BAAA;;;AAvGZ,eA8GE;EACE,cAAA;;AACA,eAFF,aAEG;EACC,cAAA;;AE9lBN;EACE,iBAAA;EACA,mBAAA;EACA,gBAAA;EACA,yBAAA;EACA,kBAAA;;AALF,WAOE;EACE,qBAAA;;AARJ,WAOE,KAGE,KAAI;EACF,SAAS,QAAT;EACA,cAAA;EACA,cAAA;;AAbN,WAiBE;EACE,cAAA;;ACpBJ;EACE,qBAAA;EACA,eAAA;EACA,cAAA;EACA,kBAAA;;AAJF,WAME;EACE,eAAA;;AAPJ,WAME,KAEE;AARJ,WAME,KAGE;EACE,kBAAA;EACA,WAAA;EACA,iBAAA;EACA,wBAAA;EACA,qBAAA;EACA,cAAA;EACA,yBAAA;EACA,yBAAA;EACA,iBAAA;;AAEF,WAdF,KAcG,YACC;AADF,WAdF,KAcG,YAEC;EACE,cAAA;EjBsFN,8BAAA;EACG,2BAAA;;AiBnFD,WArBF,KAqBG,WACC;AADF,WArBF,KAqBG,WAEC;EjBwEJ,+BAAA;EACG,4BAAA;;AiBjED,WAFF,KAAK,IAEF;AAAD,WADF,KAAK,OACF;AACD,WAHF,KAAK,IAGF;AAAD,WAFF,KAAK,OAEF;EACC,cAAA;EACA,yBAAA;EACA,qBAAA;;AAMF,WAFF,UAAU;AAER,WADF,UAAU;AAER,WAHF,UAAU,IAGP;AAAD,WAFF,UAAU,OAEP;AACD,WAJF,UAAU,IAIP;AAAD,WAHF,UAAU,OAGP;EACC,UAAA;EACA,cAAA;EACA,yBAAA;EACA,qBAAA;EACA,eAAA;;AAtDN,WA0DE,YACE;AA3DJ,WA0DE,YAEE,OAAM;AA5DV,WA0DE,YAGE,OAAM;AA7DV,WA0DE,YAIE;AA9DJ,WA0DE,YAKE,IAAG;AA/DP,WA0DE,YAME,IAAG;EACD,cAAA;EACA,yBAAA;EACA,qBAAA;EACA,mBAAA;;AASN,cjBsdE,KACE;AiBvdJ,cjBsdE,KAEE;EACE,kBAAA;EACA,eAAA;;AAEF,cANF,KAMG,YACC;AADF,cANF,KAMG,YAEC;EA9bJ,8BAAA;EACG,2BAAA;;AAicD,cAZF,KAYG,WACC;AADF,cAZF,KAYG,WAEC;EA5cJ,+BAAA;EACG,4BAAA;;AiBpBL,cjBidE,KACE;AiBldJ,cjBidE,KAEE;EACE,iBAAA;EACA,eAAA;;AAEF,cANF,KAMG,YACC;AADF,cANF,KAMG,YAEC;EA9bJ,8BAAA;EACG,2BAAA;;AAicD,cAZF,KAYG,WACC;AADF,cAZF,KAYG,WAEC;EA5cJ,+BAAA;EACG,4BAAA;;AkBpGL;EACE,eAAA;EACA,cAAA;EACA,gBAAA;EACA,kBAAA;;AAJF,MAME;EACE,eAAA;;AAPJ,MAME,GAEE;AARJ,MAME,GAGE;EACE,qBAAA;EACA,iBAAA;EACA,yBAAA;EACA,yBAAA;EACA,mBAAA;;AAdN,MAME,GAWE,IAAG;AAjBP,MAME,GAYE,IAAG;EACD,qBAAA;EACA,yBAAA;;AApBN,MAwBE,MACE;AAzBJ,MAwBE,MAEE;EACE,YAAA;;AA3BN,MA+BE,UACE;AAhCJ,MA+BE,UAEE;EACE,WAAA;;AAlCN,MAsCE,UACE;AAvCJ,MAsCE,UAEE,IAAG;AAxCP,MAsCE,UAGE,IAAG;AAzCP,MAsCE,UAIE;EACE,cAAA;EACA,yBAAA;EACA,mBAAA;;AC9CN;EACE,eAAA;EACA,uBAAA;EACA,cAAA;EACA,iBAAA;EACA,cAAA;EACA,cAAA;EACA,kBAAA;EACA,mBAAA;EACA,wBAAA;EACA,oBAAA;;AAIE,MADD,MACE;AACD,MAFD,MAEE;EACC,cAAA;EACA,qBAAA;EACA,eAAA;;AAKJ,MAAC;EACC,aAAA;;AAIF,IAAK;EACH,kBAAA;EACA,SAAA;;AAOJ;EnBqhBE,yBAAA;;AAEE,cADD,MACE;AACD,cAFD,MAEE;EACC,yBAAA;;AmBrhBN;EnBihBE,yBAAA;;AAEE,cADD,MACE;AACD,cAFD,MAEE;EACC,yBAAA;;AmBjhBN;EnB6gBE,yBAAA;;AAEE,cADD,MACE;AACD,cAFD,MAEE;EACC,yBAAA;;AmB7gBN;EnBygBE,yBAAA;;AAEE,WADD,MACE;AACD,WAFD,MAEE;EACC,yBAAA;;AmBzgBN;EnBqgBE,yBAAA;;AAEE,cADD,MACE;AACD,cAFD,MAEE;EACC,yBAAA;;AmBrgBN;EnBigBE,yBAAA;;AAEE,aADD,MACE;AACD,aAFD,MAEE;EACC,yBAAA;;AoB5jBN;EACE,qBAAA;EACA,eAAA;EACA,gBAAA;EACA,eAAA;EACA,iBAAA;EACA,cAAA;EACA,cAAA;EACA,wBAAA;EACA,mBAAA;EACA,kBAAA;EACA,yBAAA;EACA,mBAAA;;AAGA,MAAC;EACC,aAAA;;AAIF,IAAK;EACH,kBAAA;EACA,SAAA;;AAEF,OAAQ;EACN,MAAA;EACA,gBAAA;;AAMF,CADD,MACE;AACD,CAFD,MAEE;EACC,cAAA;EACA,qBAAA;EACA,eAAA;;AAKJ,CAAC,gBAAgB,OAAQ;AACzB,UAAW,UAAU,IAAI;EACvB,cAAA;EACA,yBAAA;;AAEF,UAAW,KAAK,IAAI;EAClB,gBAAA;;AChDF;EACE,aAAA;EACA,mBAAA;EACA,cAAA;EACA,yBAAA;;AAJF,UAME;AANF,UAOE;EACE,cAAA;;AARJ,UAUE;EACE,mBAAA;EACA,eAAA;EACA,gBAAA;;AAGF,UAAW;EACT,kBAAA;;AAjBJ,UAoBE;EACE,eAAA;;AAiBJ,mBAdgD;EAchD;IAbI,iBAAA;IACA,oBAAA;;EAEA,UAAW;IACT,kBAAA;IACA,mBAAA;;EAQN,UALI;EAKJ,UAJI;IACE,eAAA;;;AClCN;EACE,cAAA;EACA,YAAA;EACA,mBAAA;EACA,wBAAA;EACA,yBAAA;EACA,yBAAA;EACA,kBAAA;EtBmHA,wCAAA;EACQ,gCAAA;;AsB3HV,UAUE;AAVF,UAWE,EAAE;EtBgXF,cAAA;EACA,eAAA;EACA,YAAA;EsBhXE,iBAAA;EACA,kBAAA;;AAIF,CAAC,UAAC;AACF,CAAC,UAAC;AACF,CAAC,UAAC;EACA,qBAAA;;AArBJ,UAyBE;EACE,YAAA;EACA,cAAA;;ACzBJ;EACE,aAAA;EACA,mBAAA;EACA,6BAAA;EACA,kBAAA;;AAJF,MAOE;EACE,aAAA;EAEA,cAAA;;AAVJ,MAaE;EACE,iBAAA;;AAdJ,MAkBE;AAlBF,MAmBE;EACE,gBAAA;;AApBJ,MAsBE,IAAI;EACF,eAAA;;AAQJ;EACC,mBAAA;;AADD,kBAIE;EACE,kBAAA;EACA,SAAA;EACA,YAAA;EACA,cAAA;;AAQJ;EvBqXE,yBAAA;EACA,qBAAA;EACA,cAAA;;AuBvXF,cvByXE;EACE,yBAAA;;AuB1XJ,cvB4XE;EACE,cAAA;;AuB1XJ;EvBkXE,yBAAA;EACA,qBAAA;EACA,cAAA;;AuBpXF,WvBsXE;EACE,yBAAA;;AuBvXJ,WvByXE;EACE,cAAA;;AuBvXJ;EvB+WE,yBAAA;EACA,qBAAA;EACA,cAAA;;AuBjXF,cvBmXE;EACE,yBAAA;;AuBpXJ,cvBsXE;EACE,cAAA;;AuBpXJ;EvB4WE,yBAAA;EACA,qBAAA;EACA,cAAA;;AuB9WF,avBgXE;EACE,yBAAA;;AuBjXJ,avBmXE;EACE,cAAA;;AwB3aJ;EACE;IAAQ,2BAAA;;EACR;IAAQ,wBAAA;;;AAIV;EACE;IAAQ,2BAAA;;EACR;IAAQ,wBAAA;;;AASV;EACE,gBAAA;EACA,YAAA;EACA,mBAAA;EACA,yBAAA;EACA,kBAAA;ExB2FA,sDAAA;EACQ,8CAAA;;AwBvFV;EACE,WAAA;EACA,SAAA;EACA,YAAA;EACA,eAAA;EACA,iBAAA;EACA,cAAA;EACA,kBAAA;EACA,yBAAA;ExB8EA,sDAAA;EACQ,8CAAA;EAKR,mCAAA;EACQ,2BAAA;;AwB/EV,iBAAkB;ExBuSd,kBAAkB,2LAAlB;EACA,kBAAkB,mLAAlB;EwBtSF,0BAAA;;AAIF,SAAS,OAAQ;ExBqJf,0DAAA;EACQ,kDAAA;;AwB7IV;ExBoiBE,yBAAA;;AACA,iBAAkB;EA7QhB,kBAAkB,2LAAlB;EACA,kBAAkB,mLAAlB;;AwBrRJ;ExBgiBE,yBAAA;;AACA,iBAAkB;EA7QhB,kBAAkB,2LAAlB;EACA,kBAAkB,mLAAlB;;AwBjRJ;ExB4hBE,yBAAA;;AACA,iBAAkB;EA7QhB,kBAAkB,2LAAlB;EACA,kBAAkB,mLAAlB;;AwB7QJ;ExBwhBE,yBAAA;;AACA,iBAAkB;EA7QhB,kBAAkB,2LAAlB;EACA,kBAAkB,mLAAlB;;AyBjVJ;AACA;EACE,gBAAA;EACA,OAAA;;AAIF;AACA,MAAO;EACL,gBAAA;;AAEF,MAAM;EACJ,aAAA;;AAIF;EACE,cAAA;;AAIF;EACE,eAAA;;AAOF,MACE;EACE,kBAAA;;AAFJ,MAIE;EACE,iBAAA;;AASJ;EACE,eAAA;EACA,gBAAA;;AC7CF;EAEE,mBAAA;EACA,eAAA;;AAQF;EACE,kBAAA;EACA,cAAA;EACA,kBAAA;EAEA,mBAAA;EACA,yBAAA;EACA,yBAAA;;AAGA,gBAAC;E1BsED,4BAAA;EACC,2BAAA;;A0BpED,gBAAC;EACC,gBAAA;E1B0EF,+BAAA;EACC,8BAAA;;A0BzFH,gBAmBE;EACE,YAAA;;AApBJ,gBAsBE,SAAS;EACP,iBAAA;;AAUJ,CAAC;EACC,cAAA;;AADF,CAAC,gBAGC;EACE,cAAA;;AAIF,CARD,gBAQE;AACD,CATD,gBASE;EACC,qBAAA;EACA,yBAAA;;AAIF,CAfD,gBAeE;AACD,CAhBD,gBAgBE,OAAO;AACR,CAjBD,gBAiBE,OAAO;EACN,UAAA;EACA,cAAA;EACA,yBAAA;EACA,qBAAA;;AANF,CAfD,gBAeE,OASC;AARF,CAhBD,gBAgBE,OAAO,MAQN;AAPF,CAjBD,gBAiBE,OAAO,MAON;EACE,cAAA;;AAVJ,CAfD,gBAeE,OAYC;AAXF,CAhBD,gBAgBE,OAAO,MAWN;AAVF,CAjBD,gBAiBE,OAAO,MAUN;EACE,cAAA;;A1BsYJ,iBAAiB;EACf,cAAA;EACA,yBAAA;;AAEA,CAAC,iBAJc;EAKb,cAAA;;AADF,CAAC,iBAJc,OAOb;EAA2B,cAAA;;AAE3B,CALD,iBAJc,OASZ;AACD,CAND,iBAJc,OAUZ;EACC,cAAA;EACA,yBAAA;;AAEF,CAVD,iBAJc,OAcZ;AACD,CAXD,iBAJc,OAeZ,OAAO;AACR,CAZD,iBAJc,OAgBZ,OAAO;EACN,WAAA;EACA,yBAAA;EACA,qBAAA;;AAnBN,iBAAiB;EACf,cAAA;EACA,yBAAA;;AAEA,CAAC,iBAJc;EAKb,cAAA;;AADF,CAAC,iBAJc,IAOb;EAA2B,cAAA;;AAE3B,CALD,iBAJc,IASZ;AACD,CAND,iBAJc,IAUZ;EACC,cAAA;EACA,yBAAA;;AAEF,CAVD,iBAJc,IAcZ;AACD,CAXD,iBAJc,IAeZ,OAAO;AACR,CAZD,iBAJc,IAgBZ,OAAO;EACN,WAAA;EACA,yBAAA;EACA,qBAAA;;AAnBN,iBAAiB;EACf,cAAA;EACA,yBAAA;;AAEA,CAAC,iBAJc;EAKb,cAAA;;AADF,CAAC,iBAJc,OAOb;EAA2B,cAAA;;AAE3B,CALD,iBAJc,OASZ;AACD,CAND,iBAJc,OAUZ;EACC,cAAA;EACA,yBAAA;;AAEF,CAVD,iBAJc,OAcZ;AACD,CAXD,iBAJc,OAeZ,OAAO;AACR,CAZD,iBAJc,OAgBZ,OAAO;EACN,WAAA;EACA,yBAAA;EACA,qBAAA;;AAnBN,iBAAiB;EACf,cAAA;EACA,yBAAA;;AAEA,CAAC,iBAJc;EAKb,cAAA;;AADF,CAAC,iBAJc,MAOb;EAA2B,cAAA;;AAE3B,CALD,iBAJc,MASZ;AACD,CAND,iBAJc,MAUZ;EACC,cAAA;EACA,yBAAA;;AAEF,CAVD,iBAJc,MAcZ;AACD,CAXD,iBAJc,MAeZ,OAAO;AACR,CAZD,iBAJc,MAgBZ,OAAO;EACN,WAAA;EACA,yBAAA;EACA,qBAAA;;A0BpYR;EACE,aAAA;EACA,kBAAA;;AAEF;EACE,gBAAA;EACA,gBAAA;;ACtGF;EACE,mBAAA;EACA,yBAAA;EACA,6BAAA;EACA,kBAAA;E3BgHA,iDAAA;EACQ,yCAAA;;A2B5GV;EACE,aAAA;;AAUF,MACE;EACE,gBAAA;;AAFJ,MACE,cAEE;EACE,mBAAA;EACA,gBAAA;;AACA,MALJ,cAEE,iBAGG;EACC,aAAA;;AAEF,MARJ,cAEE,iBAMG;EACC,gBAAA;;AAIJ,MAbF,cAaG,YACC,iBAAgB;E3B2DpB,4BAAA;EACC,2BAAA;;A2BvDC,MAnBF,cAmBG,WACC,iBAAgB;E3B6DpB,+BAAA;EACC,8BAAA;;A2BvDH,cAAe,cACb,iBAAgB;EACd,mBAAA;;AAUJ,MACE;AADF,MAEE,oBAAoB;EAClB,gBAAA;;AAHJ,MAME,SAAQ,YAEN,QAAO,YAEL,KAAI,YACF,GAAE;AAXV,MAOE,oBAAmB,YAAa,SAAQ,YACtC,QAAO,YAEL,KAAI,YACF,GAAE;AAXV,MAME,SAAQ,YAGN,QAAO,YACL,KAAI,YACF,GAAE;AAXV,MAOE,oBAAmB,YAAa,SAAQ,YAEtC,QAAO,YACL,KAAI,YACF,GAAE;AAXV,MAME,SAAQ,YAEN,QAAO,YAEL,KAAI,YAEF,GAAE;AAZV,MAOE,oBAAmB,YAAa,SAAQ,YACtC,QAAO,YAEL,KAAI,YAEF,GAAE;AAZV,MAME,SAAQ,YAGN,QAAO,YACL,KAAI,YAEF,GAAE;AAZV,MAOE,oBAAmB,YAAa,SAAQ,YAEtC,QAAO,YACL,KAAI,YAEF,GAAE;EACA,2BAAA;;AAbV,MAME,SAAQ,YAEN,QAAO,YAEL,KAAI,YAKF,GAAE;AAfV,MAOE,oBAAmB,YAAa,SAAQ,YACtC,QAAO,YAEL,KAAI,YAKF,GAAE;AAfV,MAME,SAAQ,YAGN,QAAO,YACL,KAAI,YAKF,GAAE;AAfV,MAOE,oBAAmB,YAAa,SAAQ,YAEtC,QAAO,YACL,KAAI,YAKF,GAAE;AAfV,MAME,SAAQ,YAEN,QAAO,YAEL,KAAI,YAMF,GAAE;AAhBV,MAOE,oBAAmB,YAAa,SAAQ,YACtC,QAAO,YAEL,KAAI,YAMF,GAAE;AAhBV,MAME,SAAQ,YAGN,QAAO,YACL,KAAI,YAMF,GAAE;AAhBV,MAOE,oBAAmB,YAAa,SAAQ,YAEtC,QAAO,YACL,KAAI,YAMF,GAAE;EACA,4BAAA;;AAjBV,MAuBE,SAAQ,WAEN,QAAO,WAEL,KAAI,WACF,GAAE;AA5BV,MAwBE,oBAAmB,WAAY,SAAQ,WACrC,QAAO,WAEL,KAAI,WACF,GAAE;AA5BV,MAuBE,SAAQ,WAGN,QAAO,WACL,KAAI,WACF,GAAE;AA5BV,MAwBE,oBAAmB,WAAY,SAAQ,WAErC,QAAO,WACL,KAAI,WACF,GAAE;AA5BV,MAuBE,SAAQ,WAEN,QAAO,WAEL,KAAI,WAEF,GAAE;AA7BV,MAwBE,oBAAmB,WAAY,SAAQ,WACrC,QAAO,WAEL,KAAI,WAEF,GAAE;AA7BV,MAuBE,SAAQ,WAGN,QAAO,WACL,KAAI,WAEF,GAAE;AA7BV,MAwBE,oBAAmB,WAAY,SAAQ,WAErC,QAAO,WACL,KAAI,WAEF,GAAE;EACA,8BAAA;;AA9BV,MAuBE,SAAQ,WAEN,QAAO,WAEL,KAAI,WAKF,GAAE;AAhCV,MAwBE,oBAAmB,WAAY,SAAQ,WACrC,QAAO,WAEL,KAAI,WAKF,GAAE;AAhCV,MAuBE,SAAQ,WAGN,QAAO,WACL,KAAI,WAKF,GAAE;AAhCV,MAwBE,oBAAmB,WAAY,SAAQ,WAErC,QAAO,WACL,KAAI,WAKF,GAAE;AAhCV,MAuBE,SAAQ,WAEN,QAAO,WAEL,KAAI,WAMF,GAAE;AAjCV,MAwBE,oBAAmB,WAAY,SAAQ,WACrC,QAAO,WAEL,KAAI,WAMF,GAAE;AAjCV,MAuBE,SAAQ,WAGN,QAAO,WACL,KAAI,WAMF,GAAE;AAjCV,MAwBE,oBAAmB,WAAY,SAAQ,WAErC,QAAO,WACL,KAAI,WAMF,GAAE;EACA,+BAAA;;AAlCV,MAuCE,cAAc;AAvChB,MAwCE,cAAc;EACZ,6BAAA;;AAzCJ,MA2CE,SAAS,QAAO,YAAa,KAAI,YAAa;AA3ChD,MA4CE,SAAS,QAAO,YAAa,KAAI,YAAa;EAC5C,aAAA;;AA7CJ,MA+CE;AA/CF,MAgDE,oBAAoB;EAClB,SAAA;;AAjDJ,MA+CE,kBAGE,QAGE,KACE,KAAI;AAtDZ,MAgDE,oBAAoB,kBAElB,QAGE,KACE,KAAI;AAtDZ,MA+CE,kBAIE,QAEE,KACE,KAAI;AAtDZ,MAgDE,oBAAoB,kBAGlB,QAEE,KACE,KAAI;AAtDZ,MA+CE,kBAKE,QACE,KACE,KAAI;AAtDZ,MAgDE,oBAAoB,kBAIlB,QACE,KACE,KAAI;AAtDZ,MA+CE,kBAGE,QAGE,KAEE,KAAI;AAvDZ,MAgDE,oBAAoB,kBAElB,QAGE,KAEE,KAAI;AAvDZ,MA+CE,kBAIE,QAEE,KAEE,KAAI;AAvDZ,MAgDE,oBAAoB,kBAGlB,QAEE,KAEE,KAAI;AAvDZ,MA+CE,kBAKE,QACE,KAEE,KAAI;AAvDZ,MAgDE,oBAAoB,kBAIlB,QACE,KAEE,KAAI;EACF,cAAA;;AAxDV,MA+CE,kBAGE,QAGE,KAKE,KAAI;AA1DZ,MAgDE,oBAAoB,kBAElB,QAGE,KAKE,KAAI;AA1DZ,MA+CE,kBAIE,QAEE,KAKE,KAAI;AA1DZ,MAgDE,oBAAoB,kBAGlB,QAEE,KAKE,KAAI;AA1DZ,MA+CE,kBAKE,QACE,KAKE,KAAI;AA1DZ,MAgDE,oBAAoB,kBAIlB,QACE,KAKE,KAAI;AA1DZ,MA+CE,kBAGE,QAGE,KAME,KAAI;AA3DZ,MAgDE,oBAAoB,kBAElB,QAGE,KAME,KAAI;AA3DZ,MA+CE,kBAIE,QAEE,KAME,KAAI;AA3DZ,MAgDE,oBAAoB,kBAGlB,QAEE,KAME,KAAI;AA3DZ,MA+CE,kBAKE,QACE,KAME,KAAI;AA3DZ,MAgDE,oBAAoB,kBAIlB,QACE,KAME,KAAI;EACF,eAAA;;AAEF,MAfN,kBAGE,QAGE,KASG,YAAa;AAAd,MAdN,oBAAoB,kBAElB,QAGE,KASG,YAAa;AAAd,MAfN,kBAIE,QAEE,KASG,YAAa;AAAd,MAdN,oBAAoB,kBAGlB,QAEE,KASG,YAAa;AAAd,MAfN,kBAKE,QACE,KASG,YAAa;AAAd,MAdN,oBAAoB,kBAIlB,QACE,KASG,YAAa;AACd,MAhBN,kBAGE,QAGE,KAUG,YAAa;AAAd,MAfN,oBAAoB,kBAElB,QAGE,KAUG,YAAa;AAAd,MAhBN,kBAIE,QAEE,KAUG,YAAa;AAAd,MAfN,oBAAoB,kBAGlB,QAEE,KAUG,YAAa;AAAd,MAhBN,kBAKE,QACE,KAUG,YAAa;AAAd,MAfN,oBAAoB,kBAIlB,QACE,KAUG,YAAa;EACZ,aAAA;;AAEF,MAnBN,kBAGE,QAGE,KAaG,WAAY;AAAb,MAlBN,oBAAoB,kBAElB,QAGE,KAaG,WAAY;AAAb,MAnBN,kBAIE,QAEE,KAaG,WAAY;AAAb,MAlBN,oBAAoB,kBAGlB,QAEE,KAaG,WAAY;AAAb,MAnBN,kBAKE,QACE,KAaG,WAAY;AAAb,MAlBN,oBAAoB,kBAIlB,QACE,KAaG,WAAY;AACb,MApBN,kBAGE,QAGE,KAcG,WAAY;AAAb,MAnBN,oBAAoB,kBAElB,QAGE,KAcG,WAAY;AAAb,MApBN,kBAIE,QAEE,KAcG,WAAY;AAAb,MAnBN,oBAAoB,kBAGlB,QAEE,KAcG,WAAY;AAAb,MApBN,kBAKE,QACE,KAcG,WAAY;AAAb,MAnBN,oBAAoB,kBAIlB,QACE,KAcG,WAAY;EACX,gBAAA;;AApEV,MAyEE;EACE,SAAA;EACA,gBAAA;;AAMJ;EACE,kBAAA;EACA,oCAAA;E3BjDA,4BAAA;EACC,2BAAA;;A2B8CH,cAKE,YAAY;EACV,cAAA;;AAKJ;EACE,aAAA;EACA,gBAAA;EACA,eAAA;EACA,cAAA;;AAJF,YAME;EACE,cAAA;;AAKJ;EACE,kBAAA;EACA,yBAAA;EACA,6BAAA;E3BjEA,+BAAA;EACC,8BAAA;;A2B0EH;EACE,mBAAA;;AADF,YAIE;EACE,gBAAA;EACA,kBAAA;EACA,gBAAA;;AAPJ,YAIE,OAIE;EACE,eAAA;;AATN,YAaE;EACE,gBAAA;;AAdJ,YAaE,eAEE,kBAAkB;EAChB,6BAAA;;AAhBN,YAmBE;EACE,aAAA;;AApBJ,YAmBE,cAEE,kBAAkB;EAChB,gCAAA;;AAON;E3BmME,qBAAA;;AAEA,cAAE;EACA,cAAA;EACA,yBAAA;EACA,qBAAA;;AAHF,cAAE,iBAKA,kBAAkB;EAChB,yBAAA;;AAGJ,cAAE,gBACA,kBAAkB;EAChB,4BAAA;;A2B7MN;E3BgME,qBAAA;;AAEA,cAAE;EACA,cAAA;EACA,yBAAA;EACA,qBAAA;;AAHF,cAAE,iBAKA,kBAAkB;EAChB,yBAAA;;AAGJ,cAAE,gBACA,kBAAkB;EAChB,4BAAA;;A2B1MN;E3B6LE,qBAAA;;AAEA,cAAE;EACA,cAAA;EACA,yBAAA;EACA,qBAAA;;AAHF,cAAE,iBAKA,kBAAkB;EAChB,yBAAA;;AAGJ,cAAE,gBACA,kBAAkB;EAChB,4BAAA;;A2BvMN;E3B0LE,qBAAA;;AAEA,WAAE;EACA,cAAA;EACA,yBAAA;EACA,qBAAA;;AAHF,WAAE,iBAKA,kBAAkB;EAChB,yBAAA;;AAGJ,WAAE,gBACA,kBAAkB;EAChB,4BAAA;;A2BpMN;E3BuLE,qBAAA;;AAEA,cAAE;EACA,cAAA;EACA,yBAAA;EACA,qBAAA;;AAHF,cAAE,iBAKA,kBAAkB;EAChB,yBAAA;;AAGJ,cAAE,gBACA,kBAAkB;EAChB,4BAAA;;A2BjMN;E3BoLE,qBAAA;;AAEA,aAAE;EACA,cAAA;EACA,yBAAA;EACA,qBAAA;;AAHF,aAAE,iBAKA,kBAAkB;EAChB,yBAAA;;AAGJ,aAAE,gBACA,kBAAkB;EAChB,4BAAA;;A4B9ZN;EACE,gBAAA;EACA,aAAA;EACA,mBAAA;EACA,yBAAA;EACA,yBAAA;EACA,kBAAA;E5B8GA,uDAAA;EACQ,+CAAA;;A4BrHV,KAQE;EACE,kBAAA;EACA,iCAAA;;AAKJ;EACE,aAAA;EACA,kBAAA;;AAEF;EACE,YAAA;EACA,kBAAA;;ACtBF;EACE,YAAA;EACA,eAAA;EACA,iBAAA;EACA,cAAA;EACA,cAAA;EACA,4BAAA;E7BoRA,YAAA;EAGA,yBAAA;;A6BpRA,MAAC;AACD,MAAC;EACC,cAAA;EACA,qBAAA;EACA,eAAA;E7B6QF,YAAA;EAGA,yBAAA;;A6BzQA,MAAM;EACJ,UAAA;EACA,eAAA;EACA,uBAAA;EACA,SAAA;EACA,wBAAA;;ACpBJ;EACE,gBAAA;;AAIF;EACE,aAAA;EACA,cAAA;EACA,kBAAA;EACA,eAAA;EACA,MAAA;EACA,QAAA;EACA,SAAA;EACA,OAAA;EACA,aAAA;EACA,iCAAA;EAIA,UAAA;;AAGA,MAAC,KAAM;E9BkIP,mBAAmB,kBAAnB;EACI,eAAe,kBAAf;EACI,WAAW,kBAAX;EApBR,mDAAA;EACG,6CAAA;EACE,yCAAA;EACG,mCAAA;;A8B/GR,MAAC,GAAI;E9B8HL,mBAAmB,eAAnB;EACI,eAAe,eAAf;EACI,WAAW,eAAX;;A8B5HV;EACE,kBAAA;EACA,WAAA;EACA,YAAA;;AAIF;EACE,kBAAA;EACA,yBAAA;EACA,yBAAA;EACA,oCAAA;EACA,kBAAA;E9BsEA,gDAAA;EACQ,wCAAA;E8BrER,4BAAA;EAEA,aAAA;;AAIF;EACE,eAAA;EACA,MAAA;EACA,QAAA;EACA,SAAA;EACA,OAAA;EACA,aAAA;EACA,yBAAA;;AAEA,eAAC;E9B0ND,UAAA;EAGA,wBAAA;;A8B5NA,eAAC;E9ByND,YAAA;EAGA,yBAAA;;A8BvNF;EACE,aAAA;EACA,gCAAA;EACA,0BAAA;;AAGF,aAAc;EACZ,gBAAA;;AAIF;EACE,SAAA;EACA,wBAAA;;AAKF;EACE,kBAAA;EACA,aAAA;;AAIF;EACE,gBAAA;EACA,uBAAA;EACA,iBAAA;EACA,6BAAA;;AAJF,aAQE,KAAK;EACH,gBAAA;EACA,gBAAA;;AAVJ,aAaE,WAAW,KAAK;EACd,iBAAA;;AAdJ,aAiBE,WAAW;EACT,cAAA;;AAqBJ,QAhBmC;EAGjC;IACE,YAAA;IACA,iBAAA;;EAEF;I9BPA,iDAAA;IACQ,yCAAA;;E8BWR;IAAY,YAAA;;EACZ;IAAY,YAAA;;;ACjId;EACE,kBAAA;EACA,aAAA;EACA,cAAA;EACA,mBAAA;EACA,eAAA;EACA,gBAAA;E/BmRA,UAAA;EAGA,wBAAA;;A+BnRA,QAAC;E/BgRD,YAAA;EAGA,yBAAA;;A+BlRA,QAAC;EAAU,gBAAA;EAAmB,cAAA;;AAC9B,QAAC;EAAU,gBAAA;EAAmB,cAAA;;AAC9B,QAAC;EAAU,eAAA;EAAmB,cAAA;;AAC9B,QAAC;EAAU,iBAAA;EAAmB,cAAA;;AAIhC;EACE,gBAAA;EACA,gBAAA;EACA,cAAA;EACA,kBAAA;EACA,qBAAA;EACA,yBAAA;EACA,kBAAA;;AAIF;EACE,kBAAA;EACA,QAAA;EACA,SAAA;EACA,yBAAA;EACA,mBAAA;;AAGA,QAAC,IAAK;EACJ,SAAA;EACA,SAAA;EACA,iBAAA;EACA,uBAAA;EACA,yBAAA;;AAEF,QAAC,SAAU;EACT,SAAA;EACA,SAAA;EACA,uBAAA;EACA,yBAAA;;AAEF,QAAC,UAAW;EACV,SAAA;EACA,UAAA;EACA,uBAAA;EACA,yBAAA;;AAEF,QAAC,MAAO;EACN,QAAA;EACA,OAAA;EACA,gBAAA;EACA,2BAAA;EACA,2BAAA;;AAEF,QAAC,KAAM;EACL,QAAA;EACA,QAAA;EACA,gBAAA;EACA,2BAAA;EACA,0BAAA;;AAEF,QAAC,OAAQ;EACP,MAAA;EACA,SAAA;EACA,iBAAA;EACA,uBAAA;EACA,4BAAA;;AAEF,QAAC,YAAa;EACZ,MAAA;EACA,SAAA;EACA,uBAAA;EACA,4BAAA;;AAEF,QAAC,aAAc;EACb,MAAA;EACA,UAAA;EACA,uBAAA;EACA,4BAAA;;ACvFJ;EACE,kBAAA;EACA,MAAA;EACA,OAAA;EACA,aAAA;EACA,aAAA;EACA,gBAAA;EACA,YAAA;EACA,gBAAA;EACA,yBAAA;EACA,4BAAA;EACA,yBAAA;EACA,oCAAA;EACA,kBAAA;EhCwGA,iDAAA;EACQ,yCAAA;EgCrGR,mBAAA;;AAGA,QAAC;EAAW,iBAAA;;AACZ,QAAC;EAAW,iBAAA;;AACZ,QAAC;EAAW,gBAAA;;AACZ,QAAC;EAAW,kBAAA;;AAGd;EACE,SAAA;EACA,iBAAA;EACA,eAAA;EACA,mBAAA;EACA,iBAAA;EACA,yBAAA;EACA,gCAAA;EACA,0BAAA;;AAGF;EACE,iBAAA;;AAQA,QADO;AAEP,QAFO,OAEN;EACC,kBAAA;EACA,cAAA;EACA,QAAA;EACA,SAAA;EACA,yBAAA;EACA,mBAAA;;AAGJ,QAAS;EACP,kBAAA;;AAEF,QAAS,OAAM;EACb,kBAAA;EACA,SAAS,EAAT;;AAIA,QAAC,IAAK;EACJ,SAAA;EACA,kBAAA;EACA,sBAAA;EACA,yBAAA;EACA,qCAAA;EACA,aAAA;;AACA,QAPD,IAAK,OAOH;EACC,SAAS,GAAT;EACA,WAAA;EACA,kBAAA;EACA,sBAAA;EACA,yBAAA;;AAGJ,QAAC,MAAO;EACN,QAAA;EACA,WAAA;EACA,iBAAA;EACA,oBAAA;EACA,2BAAA;EACA,uCAAA;;AACA,QAPD,MAAO,OAOL;EACC,SAAS,GAAT;EACA,SAAA;EACA,aAAA;EACA,oBAAA;EACA,2BAAA;;AAGJ,QAAC,OAAQ;EACP,SAAA;EACA,kBAAA;EACA,mBAAA;EACA,4BAAA;EACA,wCAAA;EACA,UAAA;;AACA,QAPD,OAAQ,OAON;EACC,SAAS,GAAT;EACA,QAAA;EACA,kBAAA;EACA,mBAAA;EACA,4BAAA;;AAIJ,QAAC,KAAM;EACL,QAAA;EACA,YAAA;EACA,iBAAA;EACA,qBAAA;EACA,0BAAA;EACA,sCAAA;;AACA,QAPD,KAAM,OAOJ;EACC,SAAS,GAAT;EACA,UAAA;EACA,qBAAA;EACA,0BAAA;EACA,aAAA;;AC1HN;EACE,kBAAA;;AAGF;EACE,kBAAA;EACA,gBAAA;EACA,WAAA;;AAHF,eAKE;EACE,aAAA;EACA,kBAAA;EjC+GF,yCAAA;EACQ,iCAAA;;AiCvHV,eAKE,QAME;AAXJ,eAKE,QAOE,IAAI;EjC2WN,cAAA;EACA,eAAA;EACA,YAAA;EiC3WI,cAAA;;AAdN,eAkBE;AAlBF,eAmBE;AAnBF,eAoBE;EAAU,cAAA;;AApBZ,eAsBE;EACE,OAAA;;AAvBJ,eA0BE;AA1BF,eA2BE;EACE,kBAAA;EACA,MAAA;EACA,WAAA;;AA9BJ,eAiCE;EACE,UAAA;;AAlCJ,eAoCE;EACE,WAAA;;AArCJ,eAuCE,QAAO;AAvCT,eAwCE,QAAO;EACL,OAAA;;AAzCJ,eA4CE,UAAS;EACP,WAAA;;AA7CJ,eA+CE,UAAS;EACP,UAAA;;AAQJ;EACE,kBAAA;EACA,MAAA;EACA,OAAA;EACA,SAAA;EACA,UAAA;EjCwNA,YAAA;EAGA,yBAAA;EiCzNA,eAAA;EACA,cAAA;EACA,kBAAA;EACA,yCAAA;;AAKA,iBAAC;EjCgOC,kBAAkB,8BAA8B,mCAAyC,uCAAzF;EACA,kBAAmB,4EAAnB;EACA,2BAAA;EACA,sHAAA;;AiChOF,iBAAC;EACC,UAAA;EACA,QAAA;EjC2NA,kBAAkB,8BAA8B,sCAAyC,oCAAzF;EACA,kBAAmB,4EAAnB;EACA,2BAAA;EACA,sHAAA;;AiCzNF,iBAAC;AACD,iBAAC;EACC,aAAA;EACA,cAAA;EACA,qBAAA;EjCgMF,YAAA;EAGA,yBAAA;;AiChOF,iBAkCE;AAlCF,iBAmCE;AAnCF,iBAoCE;AApCF,iBAqCE;EACE,kBAAA;EACA,QAAA;EACA,UAAA;EACA,qBAAA;;AAzCJ,iBA2CE;AA3CF,iBA4CE;EACE,SAAA;;AA7CJ,iBA+CE;AA/CF,iBAgDE;EACE,UAAA;;AAjDJ,iBAmDE;AAnDF,iBAoDE;EACE,WAAA;EACA,YAAA;EACA,iBAAA;EACA,kBAAA;EACA,kBAAA;;AAIA,iBADF,WACG;EACC,SAAS,OAAT;;AAIF,iBADF,WACG;EACC,SAAS,OAAT;;AAUN;EACE,kBAAA;EACA,YAAA;EACA,SAAA;EACA,WAAA;EACA,UAAA;EACA,iBAAA;EACA,eAAA;EACA,gBAAA;EACA,kBAAA;;AATF,oBAWE;EACE,qBAAA;EACA,WAAA;EACA,YAAA;EACA,WAAA;EACA,mBAAA;EACA,yBAAA;EACA,mBAAA;EACA,eAAA;EAUA,yBAAA;EACA,kCAAA;;AA9BJ,oBAgCE;EACE,SAAA;EACA,WAAA;EACA,YAAA;EACA,yBAAA;;AAOJ;EACE,kBAAA;EACA,SAAA;EACA,UAAA;EACA,YAAA;EACA,WAAA;EACA,iBAAA;EACA,oBAAA;EACA,cAAA;EACA,kBAAA;EACA,yCAAA;;AACA,iBAAE;EACA,iBAAA;;AAkCJ,mBA5B8C;EAG5C,iBACE;EADF,iBAEE;EAFF,iBAGE;EAHF,iBAIE;IACE,WAAA;IACA,YAAA;IACA,iBAAA;IACA,kBAAA;IACA,eAAA;;EAKJ;IACE,SAAA;IACA,UAAA;IACA,oBAAA;;EAIF;IACE,YAAA;;;AjClNF,SAAC;AACD,SAAC;AIXH,UJUG;AIVH,UJWG;AISH,gBJVG;AIUH,gBJTG;AIkBH,IJnBG;AImBH,IJlBG;AMmWH,gBAoBE,YNxXC;AMoWH,gBAoBE,YNvXC;AWkBH,YXnBG;AWmBH,YXlBG;AW8HH,mBAWE,aX1IC;AW+HH,mBAWE,aXzIC;AaZH,IbWG;AaXH,IbYG;AcVH,OdSG;AcTH,OdUG;AcUH,cdXG;AcWH,cdVG;Ac6BH,gBd9BG;Ac8BH,gBd7BG;AkBfH,MlBcG;AkBdH,MlBeG;A2BLH,W3BIG;A2BJH,W3BKG;A8B+EH,a9BhFG;A8BgFH,a9B/EG;EACC,SAAS,GAAT;EACA,cAAA;;AAEF,SAAC;AIfH,UJeG;AIKH,gBJLG;AIcH,IJdG;AM+VH,gBAoBE,YNnXC;AWcH,YXdG;AW0HH,mBAWE,aXrIC;AahBH,IbgBG;AcdH,OdcG;AcMH,cdNG;AcyBH,gBdzBG;AkBnBH,MlBmBG;A2BTH,W3BSG;A8B2EH,a9B3EG;EACC,WAAA;;AedJ;Ef6BE,cAAA;EACA,iBAAA;EACA,kBAAA;;Ae5BF;EACE,uBAAA;;AAEF;EACE,sBAAA;;AAQF;EACE,wBAAA;;AAEF;EACE,yBAAA;;AAEF;EACE,kBAAA;;AAEF;Ef+CE,WAAA;EACA,kBAAA;EACA,iBAAA;EACA,6BAAA;EACA,SAAA;;Ae1CF;EACE,wBAAA;EACA,6BAAA;;AAOF;EACE,eAAA;;AmBnCF;EACE,mBAAA;;AlCmmBE;AACF,EAAE;AACF,EAAE;AACF,EAAE;EAAI,wBAAA;;AkC3lBR,QAHqC;EAGrC;IlCglBE,yBAAA;;EACA,KAAK;IAAK,cAAA;;EACV,EAAE;IAAQ,kBAAA;;EACV,EAAE;EACF,EAAE;IAAQ,mBAAA;;;AAIR;AACF,EAAE;AACF,EAAE;AACF,EAAE;EAAI,wBAAA;;AkCplBR,QAHqC,uBAAgC;EAGrE;IlCykBE,yBAAA;;EACA,KAAK;IAAK,cAAA;;EACV,EAAE;IAAQ,kBAAA;;EACV,EAAE;EACF,EAAE;IAAQ,mBAAA;;;AAIR;AACF,EAAE;AACF,EAAE;AACF,EAAE;EAAI,wBAAA;;AkC7kBR,QAHqC,uBAAgC;EAGrE;IlCkkBE,yBAAA;;EACA,KAAK;IAAK,cAAA;;EACV,EAAE;IAAQ,kBAAA;;EACV,EAAE;EACF,EAAE;IAAQ,mBAAA;;;AAIR;AACF,EAAE;AACF,EAAE;AACF,EAAE;EAAI,wBAAA;;AkCtkBR,QAHqC;EAGrC;IlC2jBE,yBAAA;;EACA,KAAK;IAAK,cAAA;;EACV,EAAE;IAAQ,kBAAA;;EACV,EAAE;EACF,EAAE;IAAQ,mBAAA;;;AkCzjBZ,QAHqC;ElCgkBjC;EACF,EAAE;EACF,EAAE;EACF,EAAE;IAAI,wBAAA;;;AkC3jBR,QAHqC,uBAAgC;ElC2jBjE;EACF,EAAE;EACF,EAAE;EACF,EAAE;IAAI,wBAAA;;;AkCtjBR,QAHqC,uBAAgC;ElCsjBjE;EACF,EAAE;EACF,EAAE;EACF,EAAE;IAAI,wBAAA;;;AkCjjBR,QAHqC;ElCijBjC;EACF,EAAE;EACF,EAAE;EACF,EAAE;IAAI,wBAAA;;;AAHJ;AACF,EAAE;AACF,EAAE;AACF,EAAE;EAAI,wBAAA;;AkCpiBR;EAAA;IlCyhBE,yBAAA;;EACA,KAAK;IAAK,cAAA;;EACV,EAAE;IAAQ,kBAAA;;EACV,EAAE;EACF,EAAE;IAAQ,mBAAA;;;AkCvhBZ;ElC2hBI;EACF,EAAE;EACF,EAAE;EACF,EAAE;IAAI,wBAAA","sourcesContent":["/*! normalize.css v3.0.0 | MIT License | git.io/normalize */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS text size adjust after orientation change, without disabling\n//    user zoom.\n//\n\nhtml {\n  font-family: sans-serif; // 1\n  -ms-text-size-adjust: 100%; // 2\n  -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n  margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined in IE 8/9.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block; // 1\n  vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9.\n// Hide the `template` element in IE, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n  display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n  background: transparent;\n}\n\n//\n// Improve readability when focused and also mouse hovered in all browsers.\n//\n\na:active,\na:hover {\n  outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9, Safari 5, and Chrome.\n//\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.\n//\n\nb,\nstrong {\n  font-weight: bold;\n}\n\n//\n// Address styling not present in Safari 5 and Chrome.\n//\n\ndfn {\n  font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari 5, and Chrome.\n//\n\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n  background: #ff0;\n  color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n  font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9.\n//\n\nimg {\n  border: 0;\n}\n\n//\n// Correct overflow displayed oddly in IE 9.\n//\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari 5.\n//\n\nfigure {\n  margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n  overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n//    Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit; // 1\n  font: inherit; // 2\n  margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10.\n//\n\nbutton {\n  overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8+, and Opera\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n//    and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n//    `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button; // 2\n  cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n  line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box; // 1\n  padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome\n//    (include `-moz` to future-proof).\n//\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield; // 1\n  -moz-box-sizing: content-box;\n  -webkit-box-sizing: content-box; // 2\n  box-sizing: content-box;\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n  border: 0; // 1\n  padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9.\n//\n\ntextarea {\n  overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n  font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd,\nth {\n  padding: 0;\n}","//\n// Basic print styles\n// --------------------------------------------------\n// Source: https://github.com/h5bp/html5-boilerplate/blob/master/css/main.css\n\n@media print {\n\n  * {\n    text-shadow: none !important;\n    color: #000 !important; // Black prints faster: h5bp.com/s\n    background: transparent !important;\n    box-shadow: none !important;\n  }\n\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n\n  // Don't show links for images, or javascript/internal links\n  a[href^=\"javascript:\"]:after,\n  a[href^=\"#\"]:after {\n    content: \"\";\n  }\n\n  pre,\n  blockquote {\n    border: 1px solid #999;\n    page-break-inside: avoid;\n  }\n\n  thead {\n    display: table-header-group; // h5bp.com/t\n  }\n\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n\n  img {\n    max-width: 100% !important;\n  }\n\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n\n  // Chrome (OSX) fix for https://github.com/twbs/bootstrap/issues/11245\n  // Once fixed, we can just straight up remove this.\n  select {\n    background: #fff !important;\n  }\n\n  // Bootstrap components\n  .navbar {\n    display: none;\n  }\n  .table {\n    td,\n    th {\n      background-color: #fff !important;\n    }\n  }\n  .btn,\n  .dropup > .btn {\n    > .caret {\n      border-top-color: #000 !important;\n    }\n  }\n  .label {\n    border: 1px solid #000;\n  }\n\n  .table {\n    border-collapse: collapse !important;\n  }\n  .table-bordered {\n    th,\n    td {\n      border: 1px solid #ddd !important;\n    }\n  }\n\n}\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n  .box-sizing(border-box);\n}\n*:before,\n*:after {\n  .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n  font-size: 62.5%;\n  -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n  font-family: @font-family-base;\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @text-color;\n  background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n\n\n// Links\n\na {\n  color: @link-color;\n  text-decoration: none;\n\n  &:hover,\n  &:focus {\n    color: @link-hover-color;\n    text-decoration: underline;\n  }\n\n  &:focus {\n    .tab-focus();\n  }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n  margin: 0;\n}\n\n\n// Images\n\nimg {\n  vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n  .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n  border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n  padding: @thumbnail-padding;\n  line-height: @line-height-base;\n  background-color: @thumbnail-bg;\n  border: 1px solid @thumbnail-border;\n  border-radius: @thumbnail-border-radius;\n  .transition(all .2s ease-in-out);\n\n  // Keep them at most 100% wide\n  .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n  border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n  margin-top:    @line-height-computed;\n  margin-bottom: @line-height-computed;\n  border: 0;\n  border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  margin: -1px;\n  padding: 0;\n  overflow: hidden;\n  clip: rect(0,0,0,0);\n  border: 0;\n}\n","//\n// Mixins\n// --------------------------------------------------\n\n\n// Utilities\n// -------------------------\n\n// Clearfix\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n//    contenteditable attribute is included anywhere else in the document.\n//    Otherwise it causes space to appear at the top and bottom of elements\n//    that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n//    `:before` to contain the top-margins of child elements.\n.clearfix() {\n  &:before,\n  &:after {\n    content: \" \"; // 1\n    display: table; // 2\n  }\n  &:after {\n    clear: both;\n  }\n}\n\n// WebKit-style focus\n.tab-focus() {\n  // Default\n  outline: thin dotted;\n  // WebKit\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n\n// Center-align a block level element\n.center-block() {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n\n// Sizing shortcuts\n.size(@width; @height) {\n  width: @width;\n  height: @height;\n}\n.square(@size) {\n  .size(@size; @size);\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n  &:-moz-placeholder            { color: @color; } // Firefox 4-18\n  &::-moz-placeholder           { color: @color;   // Firefox 19+\n                                  opacity: 1; } // See https://github.com/twbs/bootstrap/pull/11526\n  &:-ms-input-placeholder       { color: @color; } // Internet Explorer 10+\n  &::-webkit-input-placeholder  { color: @color; } // Safari and Chrome\n}\n\n// Text overflow\n// Requires inline-block or block for proper styling\n.text-overflow() {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n// CSS image replacement\n//\n// Heads up! v3 launched with with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`. Note\n// that we cannot chain the mixins together in Less, so they are repeated.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (will be removed in v4)\n.hide-text() {\n  font: ~\"0/0\" a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n// New mixin to use as of v3.0.1\n.text-hide() {\n  .hide-text();\n}\n\n\n\n// CSS3 PROPERTIES\n// --------------------------------------------------\n\n// Single side border-radius\n.border-top-radius(@radius) {\n  border-top-right-radius: @radius;\n   border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n  border-bottom-right-radius: @radius;\n     border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n  border-bottom-right-radius: @radius;\n   border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n  border-bottom-left-radius: @radius;\n     border-top-left-radius: @radius;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n//   supported browsers that have box shadow capabilities now support the\n//   standard `box-shadow` property.\n.box-shadow(@shadow) {\n  -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n          box-shadow: @shadow;\n}\n\n// Transitions\n.transition(@transition) {\n  -webkit-transition: @transition;\n          transition: @transition;\n}\n.transition-property(@transition-property) {\n  -webkit-transition-property: @transition-property;\n          transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n  -webkit-transition-delay: @transition-delay;\n          transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n  -webkit-transition-duration: @transition-duration;\n          transition-duration: @transition-duration;\n}\n.transition-transform(@transition) {\n  -webkit-transition: -webkit-transform @transition;\n     -moz-transition: -moz-transform @transition;\n       -o-transition: -o-transform @transition;\n          transition: transform @transition;\n}\n\n// Transformations\n.rotate(@degrees) {\n  -webkit-transform: rotate(@degrees);\n      -ms-transform: rotate(@degrees); // IE9 only\n          transform: rotate(@degrees);\n}\n.scale(@ratio; @ratio-y...) {\n  -webkit-transform: scale(@ratio, @ratio-y);\n      -ms-transform: scale(@ratio, @ratio-y); // IE9 only\n          transform: scale(@ratio, @ratio-y);\n}\n.translate(@x; @y) {\n  -webkit-transform: translate(@x, @y);\n      -ms-transform: translate(@x, @y); // IE9 only\n          transform: translate(@x, @y);\n}\n.skew(@x; @y) {\n  -webkit-transform: skew(@x, @y);\n      -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n          transform: skew(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n  -webkit-transform: translate3d(@x, @y, @z);\n          transform: translate3d(@x, @y, @z);\n}\n\n.rotateX(@degrees) {\n  -webkit-transform: rotateX(@degrees);\n      -ms-transform: rotateX(@degrees); // IE9 only\n          transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n  -webkit-transform: rotateY(@degrees);\n      -ms-transform: rotateY(@degrees); // IE9 only\n          transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n  -webkit-perspective: @perspective;\n     -moz-perspective: @perspective;\n          perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n  -webkit-perspective-origin: @perspective;\n     -moz-perspective-origin: @perspective;\n          perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n  -webkit-transform-origin: @origin;\n     -moz-transform-origin: @origin;\n      -ms-transform-origin: @origin; // IE9 only\n          transform-origin: @origin;\n}\n\n// Animations\n.animation(@animation) {\n  -webkit-animation: @animation;\n          animation: @animation;\n}\n.animation-name(@name) {\n  -webkit-animation-name: @name;\n          animation-name: @name;\n}\n.animation-duration(@duration) {\n  -webkit-animation-duration: @duration;\n          animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n  -webkit-animation-timing-function: @timing-function;\n          animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n  -webkit-animation-delay: @delay;\n          animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n  -webkit-animation-iteration-count: @iteration-count;\n          animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n  -webkit-animation-direction: @direction;\n          animation-direction: @direction;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n.backface-visibility(@visibility){\n  -webkit-backface-visibility: @visibility;\n     -moz-backface-visibility: @visibility;\n          backface-visibility: @visibility;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n  -webkit-box-sizing: @boxmodel;\n     -moz-box-sizing: @boxmodel;\n          box-sizing: @boxmodel;\n}\n\n// User select\n// For selecting text on the page\n.user-select(@select) {\n  -webkit-user-select: @select;\n     -moz-user-select: @select;\n      -ms-user-select: @select; // IE10+\n       -o-user-select: @select;\n          user-select: @select;\n}\n\n// Resize anything\n.resizable(@direction) {\n  resize: @direction; // Options: horizontal, vertical, both\n  overflow: auto; // Safari fix\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n  -webkit-column-count: @column-count;\n     -moz-column-count: @column-count;\n          column-count: @column-count;\n  -webkit-column-gap: @column-gap;\n     -moz-column-gap: @column-gap;\n          column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n  word-wrap: break-word;\n  -webkit-hyphens: @mode;\n     -moz-hyphens: @mode;\n      -ms-hyphens: @mode; // IE10+\n       -o-hyphens: @mode;\n          hyphens: @mode;\n}\n\n// Opacity\n.opacity(@opacity) {\n  opacity: @opacity;\n  // IE8 filter\n  @opacity-ie: (@opacity * 100);\n  filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n\n\n\n// GRADIENTS\n// --------------------------------------------------\n\n#gradient {\n\n  // Horizontal gradient, from left to right\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(left, color-stop(@start-color @start-percent), color-stop(@end-color @end-percent)); // Safari 5.1-6, Chrome 10+\n    background-image:  linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  // Vertical gradient, from top to bottom\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Safari 5.1-6, Chrome 10+\n    background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n    background-repeat: repeat-x;\n    background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n    background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n  }\n  .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .radial(@inner-color: #555; @outer-color: #333) {\n    background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n    background-image: radial-gradient(circle, @inner-color, @outer-color);\n    background-repeat: no-repeat;\n  }\n  .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n    background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n  }\n}\n\n// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n.reset-filter() {\n  filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n\n\n\n// Retina images\n//\n// Short retina mixin for setting background-image and -size\n\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n  background-image: url(\"@{file-1x}\");\n\n  @media\n  only screen and (-webkit-min-device-pixel-ratio: 2),\n  only screen and (   min--moz-device-pixel-ratio: 2),\n  only screen and (     -o-min-device-pixel-ratio: 2/1),\n  only screen and (        min-device-pixel-ratio: 2),\n  only screen and (                min-resolution: 192dpi),\n  only screen and (                min-resolution: 2dppx) {\n    background-image: url(\"@{file-2x}\");\n    background-size: @width-1x @height-1x;\n  }\n}\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n.img-responsive(@display: block) {\n  display: @display;\n  max-width: 100%; // Part 1: Set a maximum relative to the parent\n  height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// COMPONENT MIXINS\n// --------------------------------------------------\n\n// Horizontal dividers\n// -------------------------\n// Dividers (basically an hr) within dropdowns and nav lists\n.nav-divider(@color: #e5e5e5) {\n  height: 1px;\n  margin: ((@line-height-computed / 2) - 1) 0;\n  overflow: hidden;\n  background-color: @color;\n}\n\n// Panels\n// -------------------------\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n  border-color: @border;\n\n  & > .panel-heading {\n    color: @heading-text-color;\n    background-color: @heading-bg-color;\n    border-color: @heading-border;\n\n    + .panel-collapse .panel-body {\n      border-top-color: @border;\n    }\n  }\n  & > .panel-footer {\n    + .panel-collapse .panel-body {\n      border-bottom-color: @border;\n    }\n  }\n}\n\n// Alerts\n// -------------------------\n.alert-variant(@background; @border; @text-color) {\n  background-color: @background;\n  border-color: @border;\n  color: @text-color;\n\n  hr {\n    border-top-color: darken(@border, 5%);\n  }\n  .alert-link {\n    color: darken(@text-color, 10%);\n  }\n}\n\n// Tables\n// -------------------------\n.table-row-variant(@state; @background) {\n  // Exact selectors below required to override `.table-striped` and prevent\n  // inheritance to nested tables.\n  .table > thead > tr,\n  .table > tbody > tr,\n  .table > tfoot > tr {\n    > td.@{state},\n    > th.@{state},\n    &.@{state} > td,\n    &.@{state} > th {\n      background-color: @background;\n    }\n  }\n\n  // Hover states for `.table-hover`\n  // Note: this is not available for cells or rows within `thead` or `tfoot`.\n  .table-hover > tbody > tr {\n    > td.@{state}:hover,\n    > th.@{state}:hover,\n    &.@{state}:hover > td,\n    &.@{state}:hover > th {\n      background-color: darken(@background, 5%);\n    }\n  }\n}\n\n// List Groups\n// -------------------------\n.list-group-item-variant(@state; @background; @color) {\n  .list-group-item-@{state} {\n    color: @color;\n    background-color: @background;\n\n    a& {\n      color: @color;\n\n      .list-group-item-heading { color: inherit; }\n\n      &:hover,\n      &:focus {\n        color: @color;\n        background-color: darken(@background, 5%);\n      }\n      &.active,\n      &.active:hover,\n      &.active:focus {\n        color: #fff;\n        background-color: @color;\n        border-color: @color;\n      }\n    }\n  }\n}\n\n// Button variants\n// -------------------------\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n.button-variant(@color; @background; @border) {\n  color: @color;\n  background-color: @background;\n  border-color: @border;\n\n  &:hover,\n  &:focus,\n  &:active,\n  &.active,\n  .open .dropdown-toggle& {\n    color: @color;\n    background-color: darken(@background, 8%);\n        border-color: darken(@border, 12%);\n  }\n  &:active,\n  &.active,\n  .open .dropdown-toggle& {\n    background-image: none;\n  }\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    &,\n    &:hover,\n    &:focus,\n    &:active,\n    &.active {\n      background-color: @background;\n          border-color: @border;\n    }\n  }\n\n  .badge {\n    color: @background;\n    background-color: @color;\n  }\n}\n\n// Button sizes\n// -------------------------\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n  padding: @padding-vertical @padding-horizontal;\n  font-size: @font-size;\n  line-height: @line-height;\n  border-radius: @border-radius;\n}\n\n// Pagination\n// -------------------------\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @border-radius) {\n  > li {\n    > a,\n    > span {\n      padding: @padding-vertical @padding-horizontal;\n      font-size: @font-size;\n    }\n    &:first-child {\n      > a,\n      > span {\n        .border-left-radius(@border-radius);\n      }\n    }\n    &:last-child {\n      > a,\n      > span {\n        .border-right-radius(@border-radius);\n      }\n    }\n  }\n}\n\n// Labels\n// -------------------------\n.label-variant(@color) {\n  background-color: @color;\n  &[href] {\n    &:hover,\n    &:focus {\n      background-color: darken(@color, 10%);\n    }\n  }\n}\n\n// Contextual backgrounds\n// -------------------------\n.bg-variant(@color) {\n  background-color: @color;\n  a&:hover {\n    background-color: darken(@color, 10%);\n  }\n}\n\n// Typography\n// -------------------------\n.text-emphasis-variant(@color) {\n  color: @color;\n  a&:hover {\n    color: darken(@color, 10%);\n  }\n}\n\n// Navbar vertical align\n// -------------------------\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n.navbar-vertical-align(@element-height) {\n  margin-top: ((@navbar-height - @element-height) / 2);\n  margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n\n// Progress bars\n// -------------------------\n.progress-bar-variant(@color) {\n  background-color: @color;\n  .progress-striped & {\n    #gradient > .striped();\n  }\n}\n\n// Responsive utilities\n// -------------------------\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n  display: block !important;\n  table&  { display: table; }\n  tr&     { display: table-row !important; }\n  th&,\n  td&     { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n    &,\n  tr&,\n  th&,\n  td& { display: none !important; }\n}\n\n\n// Grid System\n// -----------\n\n// Centered container element\n.container-fixed() {\n  margin-right: auto;\n  margin-left: auto;\n  padding-left:  (@grid-gutter-width / 2);\n  padding-right: (@grid-gutter-width / 2);\n  &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n  margin-left:  (@gutter / -2);\n  margin-right: (@gutter / -2);\n  &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  float: left;\n  width: percentage((@columns / @grid-columns));\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n  @media (min-width: @screen-xs-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-xs-column-push(@columns) {\n  @media (min-width: @screen-xs-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-xs-column-pull(@columns) {\n  @media (min-width: @screen-xs-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  @media (min-width: @screen-sm-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-offset(@columns) {\n  @media (min-width: @screen-sm-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-push(@columns) {\n  @media (min-width: @screen-sm-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-pull(@columns) {\n  @media (min-width: @screen-sm-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  @media (min-width: @screen-md-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-offset(@columns) {\n  @media (min-width: @screen-md-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-push(@columns) {\n  @media (min-width: @screen-md-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-pull(@columns) {\n  @media (min-width: @screen-md-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  @media (min-width: @screen-lg-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-offset(@columns) {\n  @media (min-width: @screen-lg-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-push(@columns) {\n  @media (min-width: @screen-lg-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-pull(@columns) {\n  @media (min-width: @screen-lg-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n\n// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n  // Common styles for all sizes of grid columns, widths 1-12\n  .col(@index) when (@index = 1) { // initial\n    @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n    .col((@index + 1), @item);\n  }\n  .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n    @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n    .col((@index + 1), ~\"@{list}, @{item}\");\n  }\n  .col(@index, @list) when (@index > @grid-columns) { // terminal\n    @{list} {\n      position: relative;\n      // Prevent columns from collapsing when empty\n      min-height: 1px;\n      // Inner gutter via padding\n      padding-left:  (@grid-gutter-width / 2);\n      padding-right: (@grid-gutter-width / 2);\n    }\n  }\n  .col(1); // kickstart it\n}\n\n.make-grid-columns-float(@class) {\n  .col(@index) when (@index = 1) { // initial\n    @item: ~\".col-@{class}-@{index}\";\n    .col((@index + 1), @item);\n  }\n  .col(@index, @list) when (@index =< @grid-columns) { // general\n    @item: ~\".col-@{class}-@{index}\";\n    .col((@index + 1), ~\"@{list}, @{item}\");\n  }\n  .col(@index, @list) when (@index > @grid-columns) { // terminal\n    @{list} {\n      float: left;\n    }\n  }\n  .col(1); // kickstart it\n}\n\n.calc-grid(@index, @class, @type) when (@type = width) and (@index > 0) {\n  .col-@{class}-@{index} {\n    width: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid(@index, @class, @type) when (@type = push) {\n  .col-@{class}-push-@{index} {\n    left: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid(@index, @class, @type) when (@type = pull) {\n  .col-@{class}-pull-@{index} {\n    right: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid(@index, @class, @type) when (@type = offset) {\n  .col-@{class}-offset-@{index} {\n    margin-left: percentage((@index / @grid-columns));\n  }\n}\n\n// Basic looping in LESS\n.make-grid(@index, @class, @type) when (@index >= 0) {\n  .calc-grid(@index, @class, @type);\n  // next iteration\n  .make-grid((@index - 1), @class, @type);\n}\n\n\n// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and successes.\n\n.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {\n  // Color the label and help text\n  .help-block,\n  .control-label,\n  .radio,\n  .checkbox,\n  .radio-inline,\n  .checkbox-inline  {\n    color: @text-color;\n  }\n  // Set the border and box shadow on specific inputs to match\n  .form-control {\n    border-color: @border-color;\n    .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work\n    &:focus {\n      border-color: darken(@border-color, 10%);\n      @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);\n      .box-shadow(@shadow);\n    }\n  }\n  // Set validation states also for addons\n  .input-group-addon {\n    color: @text-color;\n    border-color: @border-color;\n    background-color: @background-color;\n  }\n  // Optional feedback icon\n  .form-control-feedback {\n    color: @text-color;\n  }\n}\n\n// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `@input-focus-border` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n\n.form-control-focus(@color: @input-border-focus) {\n  @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n  &:focus {\n    border-color: @color;\n    outline: 0;\n    .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n  }\n}\n\n// Form control sizing\n//\n// Relative text size, padding, and border-radii changes for form controls. For\n// horizontal sizing, wrap controls in the predefined grid classes. `<select>`\n// element gets special love because it's special, and that's a fact!\n\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n  height: @input-height;\n  padding: @padding-vertical @padding-horizontal;\n  font-size: @font-size;\n  line-height: @line-height;\n  border-radius: @border-radius;\n\n  select& {\n    height: @input-height;\n    line-height: @input-height;\n  }\n\n  textarea&,\n  select[multiple]& {\n    height: auto;\n  }\n}\n","//\n// Variables\n// --------------------------------------------------\n\n\n//== Colors\n//\n//## Gray and brand colors for use across Bootstrap.\n\n at gray-darker:            lighten(#000, 13.5%); // #222\n at gray-dark:              lighten(#000, 20%);   // #333\n at gray:                   lighten(#000, 33.5%); // #555\n at gray-light:             lighten(#000, 60%);   // #999\n at gray-lighter:           lighten(#000, 93.5%); // #eee\n\n at brand-primary:         #428bca;\n at brand-success:         #5cb85c;\n at brand-info:            #5bc0de;\n at brand-warning:         #f0ad4e;\n at brand-danger:          #d9534f;\n\n\n//== Scaffolding\n//\n// ## Settings for some of the most global styles.\n\n//** Background color for `<body>`.\n at body-bg:               #fff;\n//** Global text color on `<body>`.\n at text-color:            @gray-dark;\n\n//** Global textual link color.\n at link-color:            @brand-primary;\n//** Link hover color set via `darken()` function.\n at link-hover-color:      darken(@link-color, 15%);\n\n\n//== Typography\n//\n//## Font, line-height, and color for body text, headings, and more.\n\n at font-family-sans-serif:  \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n at font-family-serif:       Georgia, \"Times New Roman\", Times, serif;\n//** Default monospace fonts for `<code>`, `<kbd>`, and `<pre>`.\n at font-family-monospace:   Menlo, Monaco, Consolas, \"Courier New\", monospace;\n at font-family-base:        @font-family-sans-serif;\n\n at font-size-base:          14px;\n at font-size-large:         ceil((@font-size-base * 1.25)); // ~18px\n at font-size-small:         ceil((@font-size-base * 0.85)); // ~12px\n\n at font-size-h1:            floor((@font-size-base * 2.6)); // ~36px\n at font-size-h2:            floor((@font-size-base * 2.15)); // ~30px\n at font-size-h3:            ceil((@font-size-base * 1.7)); // ~24px\n at font-size-h4:            ceil((@font-size-base * 1.25)); // ~18px\n at font-size-h5:            @font-size-base;\n at font-size-h6:            ceil((@font-size-base * 0.85)); // ~12px\n\n//** Unit-less `line-height` for use in components like buttons.\n at line-height-base:        1.428571429; // 20/14\n//** Computed \"line-height\" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.\n at line-height-computed:    floor((@font-size-base * @line-height-base)); // ~20px\n\n//** By default, this inherits from the `<body>`.\n at headings-font-family:    inherit;\n at headings-font-weight:    500;\n at headings-line-height:    1.1;\n at headings-color:          inherit;\n\n\n//-- Iconography\n//\n//## Specify custom locations of the include Glyphicons icon font. Useful for those including Bootstrap via Bower.\n\n at icon-font-path:          \"../fonts/\";\n at icon-font-name:          \"glyphicons-halflings-regular\";\n at icon-font-svg-id:\t\t\t\t\"glyphicons_halflingsregular\";\n\n//== Components\n//\n//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).\n\n at padding-base-vertical:     6px;\n at padding-base-horizontal:   12px;\n\n at padding-large-vertical:    10px;\n at padding-large-horizontal:  16px;\n\n at padding-small-vertical:    5px;\n at padding-small-horizontal:  10px;\n\n at padding-xs-vertical:       1px;\n at padding-xs-horizontal:     5px;\n\n at line-height-large:         1.33;\n at line-height-small:         1.5;\n\n at border-radius-base:        4px;\n at border-radius-large:       6px;\n at border-radius-small:       3px;\n\n//** Global color for active items (e.g., navs or dropdowns).\n at component-active-color:    #fff;\n//** Global background color for active items (e.g., navs or dropdowns).\n at component-active-bg:       @brand-primary;\n\n//** Width of the `border` for generating carets that indicator dropdowns.\n at caret-width-base:          4px;\n//** Carets increase slightly in size for larger components.\n at caret-width-large:         5px;\n\n\n//== Tables\n//\n//## Customizes the `.table` component with basic values, each used across all table variations.\n\n//** Padding for `<th>`s and `<td>`s.\n at table-cell-padding:            8px;\n//** Padding for cells in `.table-condensed`.\n at table-condensed-cell-padding:  5px;\n\n//** Default background color used for all tables.\n at table-bg:                      transparent;\n//** Background color used for `.table-striped`.\n at table-bg-accent:               #f9f9f9;\n//** Background color used for `.table-hover`.\n at table-bg-hover:                #f5f5f5;\n at table-bg-active:               @table-bg-hover;\n\n//** Border color for table and cell borders.\n at table-border-color:            #ddd;\n\n\n//== Buttons\n//\n//## For each of Bootstrap's buttons, define text, background and border color.\n\n at btn-font-weight:                normal;\n\n at btn-default-color:              #333;\n at btn-default-bg:                 #fff;\n at btn-default-border:             #ccc;\n\n at btn-primary-color:              #fff;\n at btn-primary-bg:                 @brand-primary;\n at btn-primary-border:             darken(@btn-primary-bg, 5%);\n\n at btn-success-color:              #fff;\n at btn-success-bg:                 @brand-success;\n at btn-success-border:             darken(@btn-success-bg, 5%);\n\n at btn-info-color:                 #fff;\n at btn-info-bg:                    @brand-info;\n at btn-info-border:                darken(@btn-info-bg, 5%);\n\n at btn-warning-color:              #fff;\n at btn-warning-bg:                 @brand-warning;\n at btn-warning-border:             darken(@btn-warning-bg, 5%);\n\n at btn-danger-color:               #fff;\n at btn-danger-bg:                  @brand-danger;\n at btn-danger-border:              darken(@btn-danger-bg, 5%);\n\n at btn-link-disabled-color:        @gray-light;\n\n\n//== Forms\n//\n//##\n\n//** `<input>` background color\n at input-bg:                       #fff;\n//** `<input disabled>` background color\n at input-bg-disabled:              @gray-lighter;\n\n//** Text color for `<input>`s\n at input-color:                    @gray;\n//** `<input>` border color\n at input-border:                   #ccc;\n//** `<input>` border radius\n at input-border-radius:            @border-radius-base;\n//** Border color for inputs on focus\n at input-border-focus:             #66afe9;\n\n//** Placeholder text color\n at input-color-placeholder:        @gray-light;\n\n//** Default `.form-control` height\n at input-height-base:              (@line-height-computed + (@padding-base-vertical * 2) + 2);\n//** Large `.form-control` height\n at input-height-large:             (ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2);\n//** Small `.form-control` height\n at input-height-small:             (floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2);\n\n at legend-color:                   @gray-dark;\n at legend-border-color:            #e5e5e5;\n\n//** Background color for textual input addons\n at input-group-addon-bg:           @gray-lighter;\n//** Border color for textual input addons\n at input-group-addon-border-color: @input-border;\n\n\n//== Dropdowns\n//\n//## Dropdown menu container and contents.\n\n//** Background for the dropdown menu.\n at dropdown-bg:                    #fff;\n//** Dropdown menu `border-color`.\n at dropdown-border:                rgba(0,0,0,.15);\n//** Dropdown menu `border-color` **for IE8**.\n at dropdown-fallback-border:       #ccc;\n//** Divider color for between dropdown items.\n at dropdown-divider-bg:            #e5e5e5;\n\n//** Dropdown link text color.\n at dropdown-link-color:            @gray-dark;\n//** Hover color for dropdown links.\n at dropdown-link-hover-color:      darken(@gray-dark, 5%);\n//** Hover background for dropdown links.\n at dropdown-link-hover-bg:         #f5f5f5;\n\n//** Active dropdown menu item text color.\n at dropdown-link-active-color:     @component-active-color;\n//** Active dropdown menu item background color.\n at dropdown-link-active-bg:        @component-active-bg;\n\n//** Disabled dropdown menu item background color.\n at dropdown-link-disabled-color:   @gray-light;\n\n//** Text color for headers within dropdown menus.\n at dropdown-header-color:          @gray-light;\n\n// Note: Deprecated @dropdown-caret-color as of v3.1.0\n at dropdown-caret-color:           #000;\n\n\n//-- Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n//\n// Note: These variables are not generated into the Customizer.\n\n at zindex-navbar:            1000;\n at zindex-dropdown:          1000;\n at zindex-popover:           1010;\n at zindex-tooltip:           1030;\n at zindex-navbar-fixed:      1030;\n at zindex-modal-background:  1040;\n at zindex-modal:             1050;\n\n\n//== Media queries breakpoints\n//\n//## Define the breakpoints at which your layout will change, adapting to different screen sizes.\n\n// Extra small screen / phone\n// Note: Deprecated @screen-xs and @screen-phone as of v3.0.1\n at screen-xs:                  480px;\n at screen-xs-min:              @screen-xs;\n at screen-phone:               @screen-xs-min;\n\n// Small screen / tablet\n// Note: Deprecated @screen-sm and @screen-tablet as of v3.0.1\n at screen-sm:                  768px;\n at screen-sm-min:              @screen-sm;\n at screen-tablet:              @screen-sm-min;\n\n// Medium screen / desktop\n// Note: Deprecated @screen-md and @screen-desktop as of v3.0.1\n at screen-md:                  992px;\n at screen-md-min:              @screen-md;\n at screen-desktop:             @screen-md-min;\n\n// Large screen / wide desktop\n// Note: Deprecated @screen-lg and @screen-lg-desktop as of v3.0.1\n at screen-lg:                  1200px;\n at screen-lg-min:              @screen-lg;\n at screen-lg-desktop:          @screen-lg-min;\n\n// So media queries don't overlap when required, provide a maximum\n at screen-xs-max:              (@screen-sm-min - 1);\n at screen-sm-max:              (@screen-md-min - 1);\n at screen-md-max:              (@screen-lg-min - 1);\n\n\n//== Grid system\n//\n//## Define your custom responsive grid.\n\n//** Number of columns in the grid.\n at grid-columns:              12;\n//** Padding between columns. Gets divided in half for the left and right.\n at grid-gutter-width:         30px;\n// Navbar collapse\n//** Point at which the navbar becomes uncollapsed.\n at grid-float-breakpoint:     @screen-sm-min;\n//** Point at which the navbar begins collapsing.\n at grid-float-breakpoint-max: (@grid-float-breakpoint - 1);\n\n\n//== Navbar\n//\n//##\n\n// Basics of a navbar\n at navbar-height:                    50px;\n at navbar-margin-bottom:             @line-height-computed;\n at navbar-border-radius:             @border-radius-base;\n at navbar-padding-horizontal:        floor((@grid-gutter-width / 2));\n at navbar-padding-vertical:          ((@navbar-height - @line-height-computed) / 2);\n at navbar-collapse-max-height:       340px;\n\n at navbar-default-color:             #777;\n at navbar-default-bg:                #f8f8f8;\n at navbar-default-border:            darken(@navbar-default-bg, 6.5%);\n\n// Navbar links\n at navbar-default-link-color:                #777;\n at navbar-default-link-hover-color:          #333;\n at navbar-default-link-hover-bg:             transparent;\n at navbar-default-link-active-color:         #555;\n at navbar-default-link-active-bg:            darken(@navbar-default-bg, 6.5%);\n at navbar-default-link-disabled-color:       #ccc;\n at navbar-default-link-disabled-bg:          transparent;\n\n// Navbar brand label\n at navbar-default-brand-color:               @navbar-default-link-color;\n at navbar-default-brand-hover-color:         darken(@navbar-default-brand-color, 10%);\n at navbar-default-brand-hover-bg:            transparent;\n\n// Navbar toggle\n at navbar-default-toggle-hover-bg:           #ddd;\n at navbar-default-toggle-icon-bar-bg:        #888;\n at navbar-default-toggle-border-color:       #ddd;\n\n\n// Inverted navbar\n// Reset inverted navbar basics\n at navbar-inverse-color:                      @gray-light;\n at navbar-inverse-bg:                         #222;\n at navbar-inverse-border:                     darken(@navbar-inverse-bg, 10%);\n\n// Inverted navbar links\n at navbar-inverse-link-color:                 @gray-light;\n at navbar-inverse-link-hover-color:           #fff;\n at navbar-inverse-link-hover-bg:              transparent;\n at navbar-inverse-link-active-color:          @navbar-inverse-link-hover-color;\n at navbar-inverse-link-active-bg:             darken(@navbar-inverse-bg, 10%);\n at navbar-inverse-link-disabled-color:        #444;\n at navbar-inverse-link-disabled-bg:           transparent;\n\n// Inverted navbar brand label\n at navbar-inverse-brand-color:                @navbar-inverse-link-color;\n at navbar-inverse-brand-hover-color:          #fff;\n at navbar-inverse-brand-hover-bg:             transparent;\n\n// Inverted navbar toggle\n at navbar-inverse-toggle-hover-bg:            #333;\n at navbar-inverse-toggle-icon-bar-bg:         #fff;\n at navbar-inverse-toggle-border-color:        #333;\n\n\n//== Navs\n//\n//##\n\n//=== Shared nav styles\n at nav-link-padding:                          10px 15px;\n at nav-link-hover-bg:                         @gray-lighter;\n\n at nav-disabled-link-color:                   @gray-light;\n at nav-disabled-link-hover-color:             @gray-light;\n\n at nav-open-link-hover-color:                 #fff;\n\n//== Tabs\n at nav-tabs-border-color:                     #ddd;\n\n at nav-tabs-link-hover-border-color:          @gray-lighter;\n\n at nav-tabs-active-link-hover-bg:             @body-bg;\n at nav-tabs-active-link-hover-color:          @gray;\n at nav-tabs-active-link-hover-border-color:   #ddd;\n\n at nav-tabs-justified-link-border-color:            #ddd;\n at nav-tabs-justified-active-link-border-color:     @body-bg;\n\n//== Pills\n at nav-pills-border-radius:                   @border-radius-base;\n at nav-pills-active-link-hover-bg:            @component-active-bg;\n at nav-pills-active-link-hover-color:         @component-active-color;\n\n\n//== Pagination\n//\n//##\n\n at pagination-color:                     @link-color;\n at pagination-bg:                        #fff;\n at pagination-border:                    #ddd;\n\n at pagination-hover-color:               @link-hover-color;\n at pagination-hover-bg:                  @gray-lighter;\n at pagination-hover-border:              #ddd;\n\n at pagination-active-color:              #fff;\n at pagination-active-bg:                 @brand-primary;\n at pagination-active-border:             @brand-primary;\n\n at pagination-disabled-color:            @gray-light;\n at pagination-disabled-bg:               #fff;\n at pagination-disabled-border:           #ddd;\n\n\n//== Pager\n//\n//##\n\n at pager-bg:                             @pagination-bg;\n at pager-border:                         @pagination-border;\n at pager-border-radius:                  15px;\n\n at pager-hover-bg:                       @pagination-hover-bg;\n\n at pager-active-bg:                      @pagination-active-bg;\n at pager-active-color:                   @pagination-active-color;\n\n at pager-disabled-color:                 @pagination-disabled-color;\n\n\n//== Jumbotron\n//\n//##\n\n at jumbotron-padding:              30px;\n at jumbotron-color:                inherit;\n at jumbotron-bg:                   @gray-lighter;\n at jumbotron-heading-color:        inherit;\n at jumbotron-font-size:            ceil((@font-size-base * 1.5));\n\n\n//== Form states and alerts\n//\n//## Define colors for form feedback states and, by default, alerts.\n\n at state-success-text:             #3c763d;\n at state-success-bg:               #dff0d8;\n at state-success-border:           darken(spin(@state-success-bg, -10), 5%);\n\n at state-info-text:                #31708f;\n at state-info-bg:                  #d9edf7;\n at state-info-border:              darken(spin(@state-info-bg, -10), 7%);\n\n at state-warning-text:             #8a6d3b;\n at state-warning-bg:               #fcf8e3;\n at state-warning-border:           darken(spin(@state-warning-bg, -10), 5%);\n\n at state-danger-text:              #a94442;\n at state-danger-bg:                #f2dede;\n at state-danger-border:            darken(spin(@state-danger-bg, -10), 5%);\n\n\n//== Tooltips\n//\n//##\n\n//** Tooltip max width\n at tooltip-max-width:           200px;\n//** Tooltip text color\n at tooltip-color:               #fff;\n//** Tooltip background color\n at tooltip-bg:                  #000;\n at tooltip-opacity:             .9;\n\n//** Tooltip arrow width\n at tooltip-arrow-width:         5px;\n//** Tooltip arrow color\n at tooltip-arrow-color:         @tooltip-bg;\n\n\n//== Popovers\n//\n//##\n\n//** Popover body background color\n at popover-bg:                          #fff;\n//** Popover maximum width\n at popover-max-width:                   276px;\n//** Popover border color\n at popover-border-color:                rgba(0,0,0,.2);\n//** Popover fallback border color\n at popover-fallback-border-color:       #ccc;\n\n//** Popover title background color\n at popover-title-bg:                    darken(@popover-bg, 3%);\n\n//** Popover arrow width\n at popover-arrow-width:                 10px;\n//** Popover arrow color\n at popover-arrow-color:                 #fff;\n\n//** Popover outer arrow width\n at popover-arrow-outer-width:           (@popover-arrow-width + 1);\n//** Popover outer arrow color\n at popover-arrow-outer-color:           rgba(0,0,0,.25);\n//** Popover outer arrow fallback color\n at popover-arrow-outer-fallback-color:  #999;\n\n\n//== Labels\n//\n//##\n\n//** Default label background color\n at label-default-bg:            @gray-light;\n//** Primary label background color\n at label-primary-bg:            @brand-primary;\n//** Success label background color\n at label-success-bg:            @brand-success;\n//** Info label background color\n at label-info-bg:               @brand-info;\n//** Warning label background color\n at label-warning-bg:            @brand-warning;\n//** Danger label background color\n at label-danger-bg:             @brand-danger;\n\n//** Default label text color\n at label-color:                 #fff;\n//** Default text color of a linked label\n at label-link-hover-color:      #fff;\n\n\n//== Modals\n//\n//##\n\n//** Padding applied to the modal body\n at modal-inner-padding:         20px;\n\n//** Padding applied to the modal title\n at modal-title-padding:         15px;\n//** Modal title line-height\n at modal-title-line-height:     @line-height-base;\n\n//** Background color of modal content area\n at modal-content-bg:                             #fff;\n//** Modal content border color\n at modal-content-border-color:                   rgba(0,0,0,.2);\n//** Modal content border color **for IE8**\n at modal-content-fallback-border-color:          #999;\n\n//** Modal backdrop background color\n at modal-backdrop-bg:           #000;\n//** Modal backdrop opacity\n at modal-backdrop-opacity:      .5;\n//** Modal header border color\n at modal-header-border-color:   #e5e5e5;\n//** Modal footer border color\n at modal-footer-border-color:   @modal-header-border-color;\n\n at modal-lg:                    900px;\n at modal-md:                    600px;\n at modal-sm:                    300px;\n\n\n//== Alerts\n//\n//## Define alert colors, border radius, and padding.\n\n at alert-padding:               15px;\n at alert-border-radius:         @border-radius-base;\n at alert-link-font-weight:      bold;\n\n at alert-success-bg:            @state-success-bg;\n at alert-success-text:          @state-success-text;\n at alert-success-border:        @state-success-border;\n\n at alert-info-bg:               @state-info-bg;\n at alert-info-text:             @state-info-text;\n at alert-info-border:           @state-info-border;\n\n at alert-warning-bg:            @state-warning-bg;\n at alert-warning-text:          @state-warning-text;\n at alert-warning-border:        @state-warning-border;\n\n at alert-danger-bg:             @state-danger-bg;\n at alert-danger-text:           @state-danger-text;\n at alert-danger-border:         @state-danger-border;\n\n\n//== Progress bars\n//\n//##\n\n//** Background color of the whole progress component\n at progress-bg:                 #f5f5f5;\n//** Progress bar text color\n at progress-bar-color:          #fff;\n\n//** Default progress bar color\n at progress-bar-bg:             @brand-primary;\n//** Success progress bar color\n at progress-bar-success-bg:     @brand-success;\n//** Warning progress bar color\n at progress-bar-warning-bg:     @brand-warning;\n//** Danger progress bar color\n at progress-bar-danger-bg:      @brand-danger;\n//** Info progress bar color\n at progress-bar-info-bg:        @brand-info;\n\n\n//== List group\n//\n//##\n\n//** Background color on `.list-group-item`\n at list-group-bg:                 #fff;\n//** `.list-group-item` border color\n at list-group-border:             #ddd;\n//** List group border radius\n at list-group-border-radius:      @border-radius-base;\n\n//** Background color of single list elements on hover\n at list-group-hover-bg:           #f5f5f5;\n//** Text color of active list elements\n at list-group-active-color:       @component-active-color;\n//** Background color of active list elements\n at list-group-active-bg:          @component-active-bg;\n//** Border color of active list elements\n at list-group-active-border:      @list-group-active-bg;\n at list-group-active-text-color:  lighten(@list-group-active-bg, 40%);\n\n at list-group-link-color:         #555;\n at list-group-link-heading-color: #333;\n\n\n//== Panels\n//\n//##\n\n at panel-bg:                    #fff;\n at panel-body-padding:          15px;\n at panel-border-radius:         @border-radius-base;\n\n//** Border color for elements within panels\n at panel-inner-border:          #ddd;\n at panel-footer-bg:             #f5f5f5;\n\n at panel-default-text:          @gray-dark;\n at panel-default-border:        #ddd;\n at panel-default-heading-bg:    #f5f5f5;\n\n at panel-primary-text:          #fff;\n at panel-primary-border:        @brand-primary;\n at panel-primary-heading-bg:    @brand-primary;\n\n at panel-success-text:          @state-success-text;\n at panel-success-border:        @state-success-border;\n at panel-success-heading-bg:    @state-success-bg;\n\n at panel-info-text:             @state-info-text;\n at panel-info-border:           @state-info-border;\n at panel-info-heading-bg:       @state-info-bg;\n\n at panel-warning-text:          @state-warning-text;\n at panel-warning-border:        @state-warning-border;\n at panel-warning-heading-bg:    @state-warning-bg;\n\n at panel-danger-text:           @state-danger-text;\n at panel-danger-border:         @state-danger-border;\n at panel-danger-heading-bg:     @state-danger-bg;\n\n\n//== Thumbnails\n//\n//##\n\n//** Padding around the thumbnail image\n at thumbnail-padding:           4px;\n//** Thumbnail background color\n at thumbnail-bg:                @body-bg;\n//** Thumbnail border color\n at thumbnail-border:            #ddd;\n//** Thumbnail border radius\n at thumbnail-border-radius:     @border-radius-base;\n\n//** Custom text color for thumbnail captions\n at thumbnail-caption-color:     @text-color;\n//** Padding around the thumbnail caption\n at thumbnail-caption-padding:   9px;\n\n\n//== Wells\n//\n//##\n\n at well-bg:                     #f5f5f5;\n at well-border:                 darken(@well-bg, 7%);\n\n\n//== Badges\n//\n//##\n\n at badge-color:                 #fff;\n//** Linked badge text color on hover\n at badge-link-hover-color:      #fff;\n at badge-bg:                    @gray-light;\n\n//** Badge text color in active nav link\n at badge-active-color:          @link-color;\n//** Badge background color in active nav link\n at badge-active-bg:             #fff;\n\n at badge-font-weight:           bold;\n at badge-line-height:           1;\n at badge-border-radius:         10px;\n\n\n//== Breadcrumbs\n//\n//##\n\n at breadcrumb-padding-vertical:   8px;\n at breadcrumb-padding-horizontal: 15px;\n//** Breadcrumb background color\n at breadcrumb-bg:                 #f5f5f5;\n//** Breadcrumb text color\n at breadcrumb-color:              #ccc;\n//** Text color of current page in the breadcrumb\n at breadcrumb-active-color:       @gray-light;\n//** Textual separator for between breadcrumb elements\n at breadcrumb-separator:          \"/\";\n\n\n//== Carousel\n//\n//##\n\n at carousel-text-shadow:                        0 1px 2px rgba(0,0,0,.6);\n\n at carousel-control-color:                      #fff;\n at carousel-control-width:                      15%;\n at carousel-control-opacity:                    .5;\n at carousel-control-font-size:                  20px;\n\n at carousel-indicator-active-bg:                #fff;\n at carousel-indicator-border-color:             #fff;\n\n at carousel-caption-color:                      #fff;\n\n\n//== Close\n//\n//##\n\n at close-font-weight:           bold;\n at close-color:                 #000;\n at close-text-shadow:           0 1px 0 #fff;\n\n\n//== Code\n//\n//##\n\n at code-color:                  #c7254e;\n at code-bg:                     #f9f2f4;\n\n at kbd-color:                   #fff;\n at kbd-bg:                      #333;\n\n at pre-bg:                      #f5f5f5;\n at pre-color:                   @gray-dark;\n at pre-border-color:            #ccc;\n at pre-scrollable-max-height:   340px;\n\n\n//== Type\n//\n//##\n\n//** Text muted color\n at text-muted:                  @gray-light;\n//** Abbreviations and acronyms border color\n at abbr-border-color:           @gray-light;\n//** Headings small color\n at headings-small-color:        @gray-light;\n//** Blockquote small color\n at blockquote-small-color:      @gray-light;\n//** Blockquote border color\n at blockquote-border-color:     @gray-lighter;\n//** Page header border color\n at page-header-border-color:    @gray-lighter;\n\n\n//== Miscellaneous\n//\n//##\n\n//** Horizontal line color.\n at hr-border:                   @gray-lighter;\n\n//** Horizontal offset for forms and lists.\n at component-offset-horizontal: 180px;\n\n\n//== Container sizes\n//\n//## Define the maximum width of `.container` for different screen sizes.\n\n// Small screen / tablet\n at container-tablet:             ((720px + @grid-gutter-width));\n//** For `@screen-sm-min` and up.\n at container-sm:                 @container-tablet;\n\n// Medium screen / desktop\n at container-desktop:            ((940px + @grid-gutter-width));\n//** For `@screen-md-min` and up.\n at container-md:                 @container-desktop;\n\n// Large screen / wide desktop\n at container-large-desktop:      ((1140px + @grid-gutter-width));\n//** For `@screen-lg-min` and up.\n at container-lg:                 @container-large-desktop;\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n  font-family: @headings-font-family;\n  font-weight: @headings-font-weight;\n  line-height: @headings-line-height;\n  color: @headings-color;\n\n  small,\n  .small {\n    font-weight: normal;\n    line-height: 1;\n    color: @headings-small-color;\n  }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n  margin-top: @line-height-computed;\n  margin-bottom: (@line-height-computed / 2);\n\n  small,\n  .small {\n    font-size: 65%;\n  }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n  margin-top: (@line-height-computed / 2);\n  margin-bottom: (@line-height-computed / 2);\n\n  small,\n  .small {\n    font-size: 75%;\n  }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n  margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n  margin-bottom: @line-height-computed;\n  font-size: floor((@font-size-base * 1.15));\n  font-weight: 200;\n  line-height: 1.4;\n\n  @media (min-width: @screen-sm-min) {\n    font-size: (@font-size-base * 1.5);\n  }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: 14px base font * 85% = about 12px\nsmall,\n.small  { font-size: 85%; }\n\n// Undo browser default styling\ncite    { font-style: normal; }\n\n// Alignment\n.text-left           { text-align: left; }\n.text-right          { text-align: right; }\n.text-center         { text-align: center; }\n.text-justify        { text-align: justify; }\n\n// Contextual colors\n.text-muted {\n  color: @text-muted;\n}\n.text-primary {\n  .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n  .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n  .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n  .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n  .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n  // Given the contrast here, this is the only class to have its color inverted\n  // automatically.\n  color: #fff;\n  .bg-variant(@brand-primary);\n}\n.bg-success {\n  .bg-variant(@state-success-bg);\n}\n.bg-info {\n  .bg-variant(@state-info-bg);\n}\n.bg-warning {\n  .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n  .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n  padding-bottom: ((@line-height-computed / 2) - 1);\n  margin: (@line-height-computed * 2) 0 @line-height-computed;\n  border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// --------------------------------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n  margin-top: 0;\n  margin-bottom: (@line-height-computed / 2);\n  ul,\n  ol {\n    margin-bottom: 0;\n  }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n  .list-unstyled();\n\n  > li {\n    display: inline-block;\n    padding-left: 5px;\n    padding-right: 5px;\n\n    &:first-child {\n      padding-left: 0;\n    }\n  }\n}\n\n// Description Lists\ndl {\n  margin-top: 0; // Remove browser default\n  margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n  line-height: @line-height-base;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n at media (min-width: @grid-float-breakpoint) {\n  .dl-horizontal {\n    dt {\n      float: left;\n      width: (@component-offset-horizontal - 20);\n      clear: left;\n      text-align: right;\n      .text-overflow();\n    }\n    dd {\n      margin-left: @component-offset-horizontal;\n      &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n    }\n  }\n}\n\n// MISC\n// ----\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\n\n// Blockquotes\nblockquote {\n  padding: (@line-height-computed / 2) @line-height-computed;\n  margin: 0 0 @line-height-computed;\n  font-size: (@font-size-base * 1.25);\n  border-left: 5px solid @blockquote-border-color;\n\n  p,\n  ul,\n  ol {\n    &:last-child {\n      margin-bottom: 0;\n    }\n  }\n\n  // Note: Deprecated small and .small as of v3.1.0\n  // Context: https://github.com/twbs/bootstrap/issues/11660\n  footer,\n  small,\n  .small {\n    display: block;\n    font-size: 80%; // back to default font-size\n    line-height: @line-height-base;\n    color: @blockquote-small-color;\n\n    &:before {\n      content: '\\2014 \\00A0'; // em dash, nbsp\n    }\n  }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  border-right: 5px solid @blockquote-border-color;\n  border-left: 0;\n  text-align: right;\n\n  // Account for citation\n  footer,\n  small,\n  .small {\n    &:before { content: ''; }\n    &:after {\n      content: '\\00A0 \\2014'; // nbsp, em dash\n    }\n  }\n}\n\n// Quotes\nblockquote:before,\nblockquote:after {\n  content: \"\";\n}\n\n// Addresses\naddress {\n  margin-bottom: @line-height-computed;\n  font-style: normal;\n  line-height: @line-height-base;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n  font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: @code-color;\n  background-color: @code-bg;\n  white-space: nowrap;\n  border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: @kbd-color;\n  background-color: @kbd-bg;\n  border-radius: @border-radius-small;\n  box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n}\n\n// Blocks of code\npre {\n  display: block;\n  padding: ((@line-height-computed - 1) / 2);\n  margin: 0 0 (@line-height-computed / 2);\n  font-size: (@font-size-base - 1); // 14px to 13px\n  line-height: @line-height-base;\n  word-break: break-all;\n  word-wrap: break-word;\n  color: @pre-color;\n  background-color: @pre-bg;\n  border: 1px solid @pre-border-color;\n  border-radius: @border-radius-base;\n\n  // Account for some code outputs that place code tags in pre tags\n  code {\n    padding: 0;\n    font-size: inherit;\n    color: inherit;\n    white-space: pre-wrap;\n    background-color: transparent;\n    border-radius: 0;\n  }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n  max-height: @pre-scrollable-max-height;\n  overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n  .container-fixed();\n\n  @media (min-width: @screen-sm-min) {\n    width: @container-sm;\n  }\n  @media (min-width: @screen-md-min) {\n    width: @container-md;\n  }\n  @media (min-width: @screen-lg-min) {\n    width: @container-lg;\n  }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n  .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n  .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid-columns-float(xs);\n.make-grid(@grid-columns, xs, width);\n.make-grid(@grid-columns, xs, pull);\n.make-grid(@grid-columns, xs, push);\n.make-grid(@grid-columns, xs, offset);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n at media (min-width: @screen-sm-min) {\n  .make-grid-columns-float(sm);\n  .make-grid(@grid-columns, sm, width);\n  .make-grid(@grid-columns, sm, pull);\n  .make-grid(@grid-columns, sm, push);\n  .make-grid(@grid-columns, sm, offset);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n at media (min-width: @screen-md-min) {\n  .make-grid-columns-float(md);\n  .make-grid(@grid-columns, md, width);\n  .make-grid(@grid-columns, md, pull);\n  .make-grid(@grid-columns, md, push);\n  .make-grid(@grid-columns, md, offset);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n at media (min-width: @screen-lg-min) {\n  .make-grid-columns-float(lg);\n  .make-grid(@grid-columns, lg, width);\n  .make-grid(@grid-columns, lg, pull);\n  .make-grid(@grid-columns, lg, push);\n  .make-grid(@grid-columns, lg, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n  max-width: 100%;\n  background-color: @table-bg;\n}\nth {\n  text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n  width: 100%;\n  margin-bottom: @line-height-computed;\n  // Cells\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        padding: @table-cell-padding;\n        line-height: @line-height-base;\n        vertical-align: top;\n        border-top: 1px solid @table-border-color;\n      }\n    }\n  }\n  // Bottom align for column headings\n  > thead > tr > th {\n    vertical-align: bottom;\n    border-bottom: 2px solid @table-border-color;\n  }\n  // Remove top border from thead by default\n  > caption + thead,\n  > colgroup + thead,\n  > thead:first-child {\n    > tr:first-child {\n      > th,\n      > td {\n        border-top: 0;\n      }\n    }\n  }\n  // Account for multiple tbody instances\n  > tbody + tbody {\n    border-top: 2px solid @table-border-color;\n  }\n\n  // Nesting\n  .table {\n    background-color: @body-bg;\n  }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        padding: @table-condensed-cell-padding;\n      }\n    }\n  }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n  border: 1px solid @table-border-color;\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        border: 1px solid @table-border-color;\n      }\n    }\n  }\n  > thead > tr {\n    > th,\n    > td {\n      border-bottom-width: 2px;\n    }\n  }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n  > tbody > tr:nth-child(odd) {\n    > td,\n    > th {\n      background-color: @table-bg-accent;\n    }\n  }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n  > tbody > tr:hover {\n    > td,\n    > th {\n      background-color: @table-bg-hover;\n    }\n  }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n  position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n  float: none;\n  display: table-column;\n}\ntable {\n  td,\n  th {\n    &[class*=\"col-\"] {\n      position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n      float: none;\n      display: table-cell;\n    }\n  }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n at media (max-width: @screen-xs-max) {\n  .table-responsive {\n    width: 100%;\n    margin-bottom: (@line-height-computed * 0.75);\n    overflow-y: hidden;\n    overflow-x: scroll;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid @table-border-color;\n    -webkit-overflow-scrolling: touch;\n\n    // Tighten up spacing\n    > .table {\n      margin-bottom: 0;\n\n      // Ensure the content doesn't wrap\n      > thead,\n      > tbody,\n      > tfoot {\n        > tr {\n          > th,\n          > td {\n            white-space: nowrap;\n          }\n        }\n      }\n    }\n\n    // Special overrides for the bordered tables\n    > .table-bordered {\n      border: 0;\n\n      // Nuke the appropriate borders so that the parent can handle them\n      > thead,\n      > tbody,\n      > tfoot {\n        > tr {\n          > th:first-child,\n          > td:first-child {\n            border-left: 0;\n          }\n          > th:last-child,\n          > td:last-child {\n            border-right: 0;\n          }\n        }\n      }\n\n      // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n      // chances are there will be only one `tr` in a `thead` and that would\n      // remove the border altogether.\n      > tbody,\n      > tfoot {\n        > tr:last-child {\n          > th,\n          > td {\n            border-bottom: 0;\n          }\n        }\n      }\n\n    }\n  }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n  padding: 0;\n  margin: 0;\n  border: 0;\n  // Chrome and Firefox set a `min-width: -webkit-min-content;` on fieldsets,\n  // so we reset that to ensure it behaves more like a standard block element.\n  // See https://github.com/twbs/bootstrap/issues/12359.\n  min-width: 0;\n}\n\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: @line-height-computed;\n  font-size: (@font-size-base * 1.5);\n  line-height: inherit;\n  color: @legend-color;\n  border: 0;\n  border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n  display: inline-block;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n  .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9; /* IE8-9 */\n  line-height: normal;\n}\n\n// Set the height of file controls to match text inputs\ninput[type=\"file\"] {\n  display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n  display: block;\n  width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n  height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  .tab-focus();\n}\n\n// Adjust output element\noutput {\n  display: block;\n  padding-top: (@padding-base-vertical + 1);\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n  display: block;\n  width: 100%;\n  height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n  padding: @padding-base-vertical @padding-base-horizontal;\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @input-color;\n  background-color: @input-bg;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid @input-border;\n  border-radius: @input-border-radius;\n  .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n  .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n  // Customize the `:focus` state to imitate native WebKit styles.\n  .form-control-focus();\n\n  // Placeholder\n  .placeholder();\n\n  // Disabled and read-only inputs\n  // Note: HTML5 says that controls under a fieldset > legend:first-child won't\n  // be disabled if the fieldset is disabled. Due to implementation difficulty,\n  // we don't honor that edge case; we style them as disabled anyway.\n  &[disabled],\n  &[readonly],\n  fieldset[disabled] & {\n    cursor: not-allowed;\n    background-color: @input-bg-disabled;\n    opacity: 1; // iOS fix for unreadable disabled content\n  }\n\n  // Reset height for `textarea`s\n  textarea& {\n    height: auto;\n  }\n}\n\n// Special styles for iOS date input\n//\n// In Mobile Safari, date inputs require a pixel line-height that matches the\n// given height of the input.\ninput[type=\"date\"] {\n  line-height: @input-height-base;\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n  margin-bottom: 15px;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n  display: block;\n  min-height: @line-height-computed; // clear the floating input if there is no label text\n  margin-top: 10px;\n  margin-bottom: 10px;\n  padding-left: 20px;\n  label {\n    display: inline;\n    font-weight: normal;\n    cursor: pointer;\n  }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  float: left;\n  margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  vertical-align: middle;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n//\n// Note: Neither radios nor checkboxes can be readonly.\ninput[type=\"radio\"],\ninput[type=\"checkbox\"],\n.radio,\n.radio-inline,\n.checkbox,\n.checkbox-inline {\n  &[disabled],\n  fieldset[disabled] & {\n    cursor: not-allowed;\n  }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n\n.input-sm {\n  .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n\n.input-lg {\n  .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n\n// Form control feedback states\n//\n// Apply contextual and semantic states to individual form controls.\n\n.has-feedback {\n  // Enable absolute positioning\n  position: relative;\n\n  // Ensure icons don't overlap text\n  .form-control {\n    padding-right: (@input-height-base * 1.25);\n  }\n\n  // Feedback icon (requires .glyphicon classes)\n  .form-control-feedback {\n    position: absolute;\n    top: (@line-height-computed + 5); // Height of the `label` and its margin\n    right: 0;\n    display: block;\n    width: @input-height-base;\n    height: @input-height-base;\n    line-height: @input-height-base;\n    text-align: center;\n  }\n}\n\n// Feedback states\n.has-success {\n  .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);\n}\n.has-warning {\n  .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);\n}\n.has-error {\n  .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);\n}\n\n\n// Static form control text\n//\n// Apply class to a `p` element to make any string of text align with labels in\n// a horizontal form layout.\n\n.form-control-static {\n  margin-bottom: 0; // Remove default margin from `p`\n}\n\n\n// Help text\n//\n// Apply to any element you wish to create light text for placement immediately\n// below a form control. Use for general help, formatting, or instructional text.\n\n.help-block {\n  display: block; // account for any element using help-block\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: lighten(@text-color, 25%); // lighten the text some for contrast\n}\n\n\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n//\n// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.\n\n.form-inline {\n\n  // Kick in the inline\n  @media (min-width: @screen-sm-min) {\n    // Inline-block all the things for \"inline\"\n    .form-group {\n      display: inline-block;\n      margin-bottom: 0;\n      vertical-align: middle;\n    }\n\n    // In navbar-form, allow folks to *not* use `.form-group`\n    .form-control {\n      display: inline-block;\n      width: auto; // Prevent labels from stacking above inputs in `.form-group`\n      vertical-align: middle;\n    }\n\n    .control-label {\n      margin-bottom: 0;\n      vertical-align: middle;\n    }\n\n    // Remove default margin on radios/checkboxes that were used for stacking, and\n    // then undo the floating of radios and checkboxes to match (which also avoids\n    // a bug in WebKit: https://github.com/twbs/bootstrap/issues/1969).\n    .radio,\n    .checkbox {\n      display: inline-block;\n      margin-top: 0;\n      margin-bottom: 0;\n      padding-left: 0;\n      vertical-align: middle;\n    }\n    .radio input[type=\"radio\"],\n    .checkbox input[type=\"checkbox\"] {\n      float: none;\n      margin-left: 0;\n    }\n\n    // Validation states\n    //\n    // Reposition the icon because it's now within a grid column and columns have\n    // `position: relative;` on them. Also accounts for the grid gutter padding.\n    .has-feedback .form-control-feedback {\n      top: 0;\n    }\n  }\n}\n\n\n// Horizontal forms\n//\n// Horizontal forms are built on grid classes and allow you to create forms with\n// labels on the left and inputs on the right.\n\n.form-horizontal {\n\n  // Consistent vertical alignment of labels, radios, and checkboxes\n  .control-label,\n  .radio,\n  .checkbox,\n  .radio-inline,\n  .checkbox-inline {\n    margin-top: 0;\n    margin-bottom: 0;\n    padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n  }\n  // Account for padding we're adding to ensure the alignment and of help text\n  // and other content below items\n  .radio,\n  .checkbox {\n    min-height: (@line-height-computed + (@padding-base-vertical + 1));\n  }\n\n  // Make form groups behave like rows\n  .form-group {\n    .make-row();\n  }\n\n  .form-control-static {\n    padding-top: (@padding-base-vertical + 1);\n  }\n\n  // Only right align form labels here when the columns stop stacking\n  @media (min-width: @screen-sm-min) {\n    .control-label {\n      text-align: right;\n    }\n  }\n\n  // Validation states\n  //\n  // Reposition the icon because it's now within a grid column and columns have\n  // `position: relative;` on them. Also accounts for the grid gutter padding.\n  .has-feedback .form-control-feedback {\n    top: 0;\n    right: (@grid-gutter-width / 2);\n  }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n  display: inline-block;\n  margin-bottom: 0; // For input.btn\n  font-weight: @btn-font-weight;\n  text-align: center;\n  vertical-align: middle;\n  cursor: pointer;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid transparent;\n  white-space: nowrap;\n  .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base);\n  .user-select(none);\n\n  &:focus {\n    .tab-focus();\n  }\n\n  &:hover,\n  &:focus {\n    color: @btn-default-color;\n    text-decoration: none;\n  }\n\n  &:active,\n  &.active {\n    outline: 0;\n    background-image: none;\n    .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n  }\n\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    cursor: not-allowed;\n    pointer-events: none; // Future-proof disabling of clicks\n    .opacity(.65);\n    .box-shadow(none);\n  }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n  .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n  .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n  .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n  .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n  .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n  .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n  color: @link-color;\n  font-weight: normal;\n  cursor: pointer;\n  border-radius: 0;\n\n  &,\n  &:active,\n  &[disabled],\n  fieldset[disabled] & {\n    background-color: transparent;\n    .box-shadow(none);\n  }\n  &,\n  &:hover,\n  &:focus,\n  &:active {\n    border-color: transparent;\n  }\n  &:hover,\n  &:focus {\n    color: @link-hover-color;\n    text-decoration: underline;\n    background-color: transparent;\n  }\n  &[disabled],\n  fieldset[disabled] & {\n    &:hover,\n    &:focus {\n      color: @btn-link-disabled-color;\n      text-decoration: none;\n    }\n  }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n  // line-height: ensure even-numbered height of button next to large input\n  .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n.btn-sm {\n  // line-height: ensure proper height of button next to small input\n  .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n.btn-xs {\n  .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n  display: block;\n  width: 100%;\n  padding-left: 0;\n  padding-right: 0;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n  &.btn-block {\n    width: 100%;\n  }\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twitter/bootstrap/pull/3552.\n\n.fade {\n  opacity: 0;\n  .transition(opacity .15s linear);\n  &.in {\n    opacity: 1;\n  }\n}\n\n.collapse {\n  display: none;\n  &.in {\n    display: block;\n  }\n}\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  .transition(height .35s ease);\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// <a href=\"#\"><span class=\"glyphicon glyphicon-star\"></span> Star</a>\n\n// Import the fonts\n at font-face {\n  font-family: 'Glyphicons Halflings';\n  src: ~\"url('@{icon-font-path}@{icon-font-name}.eot')\";\n  src: ~\"url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype')\",\n       ~\"url('@{icon-font-path}@{icon-font-name}.woff') format('woff')\",\n       ~\"url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype')\",\n       ~\"url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg')\";\n}\n\n// Catchall baseclass\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk               { &:before { content: \"\\2a\"; } }\n.glyphicon-plus                   { &:before { content: \"\\2b\"; } }\n.glyphicon-euro                   { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus                  { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud                  { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope               { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil                 { &:before { content: \"\\270f\"; } }\n.glyphicon-glass                  { &:before { content: \"\\e001\"; } }\n.glyphicon-music                  { &:before { content: \"\\e002\"; } }\n.glyphicon-search                 { &:before { content: \"\\e003\"; } }\n.glyphicon-heart                  { &:before { content: \"\\e005\"; } }\n.glyphicon-star                   { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty             { &:before { content: \"\\e007\"; } }\n.glyphicon-user                   { &:before { content: \"\\e008\"; } }\n.glyphicon-film                   { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large               { &:before { content: \"\\e010\"; } }\n.glyphicon-th                     { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list                { &:before { content: \"\\e012\"; } }\n.glyphicon-ok                     { &:before { content: \"\\e013\"; } }\n.glyphicon-remove                 { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in                { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out               { &:before { content: \"\\e016\"; } }\n.glyphicon-off                    { &:before { content: \"\\e017\"; } }\n.glyphicon-signal                 { &:before { content: \"\\e018\"; } }\n.glyphicon-cog                    { &:before { content: \"\\e019\"; } }\n.glyphicon-trash                  { &:before { content: \"\\e020\"; } }\n.glyphicon-home                   { &:before { content: \"\\e021\"; } }\n.glyphicon-file                   { &:before { content: \"\\e022\"; } }\n.glyphicon-time                   { &:before { content: \"\\e023\"; } }\n.glyphicon-road                   { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt           { &:before { content: \"\\e025\"; } }\n.glyphicon-download               { &:before { content: \"\\e026\"; } }\n.glyphicon-upload                 { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox                  { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle            { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat                 { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh                { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt               { &:before { content: \"\\e032\"; } }\n.glyphicon-lock                   { &:before { content: \"\\e033\"; } }\n.glyphicon-flag                   { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones             { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off             { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down            { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up              { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode                 { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode                { &:before { content: \"\\e040\"; } }\n.glyphicon-tag                    { &:before { content: \"\\e041\"; } }\n.glyphicon-tags                   { &:before { content: \"\\e042\"; } }\n.glyphicon-book                   { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark               { &:before { content: \"\\e044\"; } }\n.glyphicon-print                  { &:before { content: \"\\e045\"; } }\n.glyphicon-camera                 { &:before { content: \"\\e046\"; } }\n.glyphicon-font                   { &:before { content: \"\\e047\"; } }\n.glyphicon-bold                   { &:before { content: \"\\e048\"; } }\n.glyphicon-italic                 { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height            { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width             { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left             { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center           { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right            { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify          { &:before { content: \"\\e055\"; } }\n.glyphicon-list                   { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left            { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right           { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video         { &:before { content: \"\\e059\"; } }\n.glyphicon-picture                { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker             { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust                 { &:before { content: \"\\e063\"; } }\n.glyphicon-tint                   { &:before { content: \"\\e064\"; } }\n.glyphicon-edit                   { &:before { content: \"\\e065\"; } }\n.glyphicon-share                  { &:before { content: \"\\e066\"; } }\n.glyphicon-check                  { &:before { content: \"\\e067\"; } }\n.glyphicon-move                   { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward          { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward          { &:before { content: \"\\e070\"; } }\n.glyphicon-backward               { &:before { content: \"\\e071\"; } }\n.glyphicon-play                   { &:before { content: \"\\e072\"; } }\n.glyphicon-pause                  { &:before { content: \"\\e073\"; } }\n.glyphicon-stop                   { &:before { content: \"\\e074\"; } }\n.glyphicon-forward                { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward           { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward           { &:before { content: \"\\e077\"; } }\n.glyphicon-eject                  { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left           { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right          { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign              { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign             { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign            { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign                { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign          { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign              { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot             { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle          { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle              { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle             { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left             { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right            { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up               { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down             { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt              { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full            { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small           { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign       { &:before { content: \"\\e101\"; } }\n.glyphicon-gift                   { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf                   { &:before { content: \"\\e103\"; } }\n.glyphicon-fire                   { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open               { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close              { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign           { &:before { content: \"\\e107\"; } }\n.glyphicon-plane                  { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar               { &:before { content: \"\\e109\"; } }\n.glyphicon-random                 { &:before { content: \"\\e110\"; } }\n.glyphicon-comment                { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet                 { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up             { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down           { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet                { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart          { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close           { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open            { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical        { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal      { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd                    { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn               { &:before { content: \"\\e122\"; } }\n.glyphicon-bell                   { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate            { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up              { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down            { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right             { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left              { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up                { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down              { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right     { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left      { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up        { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down      { &:before { content: \"\\e134\"; } }\n.glyphicon-globe                  { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench                 { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks                  { &:before { content: \"\\e137\"; } }\n.glyphicon-filter                 { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase              { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen             { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard              { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip              { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty            { &:before { content: \"\\e143\"; } }\n.glyphicon-link                   { &:before { content: \"\\e144\"; } }\n.glyphicon-phone                  { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin                { &:before { content: \"\\e146\"; } }\n.glyphicon-usd                    { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp                    { &:before { content: \"\\e149\"; } }\n.glyphicon-sort                   { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet       { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt   { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order          { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt      { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes     { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked              { &:before { content: \"\\e157\"; } }\n.glyphicon-expand                 { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down          { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up            { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in                 { &:before { content: \"\\e161\"; } }\n.glyphicon-flash                  { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out                { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window             { &:before { content: \"\\e164\"; } }\n.glyphicon-record                 { &:before { content: \"\\e165\"; } }\n.glyphicon-save                   { &:before { content: \"\\e166\"; } }\n.glyphicon-open                   { &:before { content: \"\\e167\"; } }\n.glyphicon-saved                  { &:before { content: \"\\e168\"; } }\n.glyphicon-import                 { &:before { content: \"\\e169\"; } }\n.glyphicon-export                 { &:before { content: \"\\e170\"; } }\n.glyphicon-send                   { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk            { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved           { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove          { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save            { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open            { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card            { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer               { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery                { &:before { content: \"\\e179\"; } }\n.glyphicon-header                 { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed             { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone               { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt              { &:before { content: \"\\e183\"; } }\n.glyphicon-tower                  { &:before { content: \"\\e184\"; } }\n.glyphicon-stats                  { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video               { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video               { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles              { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo           { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby            { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1              { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1              { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1              { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark         { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark      { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download         { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload           { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer           { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous         { &:before { content: \"\\e200\"; } }\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top:   @caret-width-base solid;\n  border-right: @caret-width-base solid transparent;\n  border-left:  @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropdown {\n  position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n  outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: @zindex-dropdown;\n  display: none; // none by default, but block on \"open\" of the menu\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0; // override default ul\n  list-style: none;\n  font-size: @font-size-base;\n  background-color: @dropdown-bg;\n  border: 1px solid @dropdown-fallback-border; // IE8 fallback\n  border: 1px solid @dropdown-border;\n  border-radius: @border-radius-base;\n  .box-shadow(0 6px 12px rgba(0,0,0,.175));\n  background-clip: padding-box;\n\n  // Aligns the dropdown menu to right\n  //\n  // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n  &.pull-right {\n    right: 0;\n    left: auto;\n  }\n\n  // Dividers (basically an hr) within the dropdown\n  .divider {\n    .nav-divider(@dropdown-divider-bg);\n  }\n\n  // Links within the dropdown menu\n  > li > a {\n    display: block;\n    padding: 3px 20px;\n    clear: both;\n    font-weight: normal;\n    line-height: @line-height-base;\n    color: @dropdown-link-color;\n    white-space: nowrap; // prevent links from randomly breaking onto new lines\n  }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    color: @dropdown-link-hover-color;\n    background-color: @dropdown-link-hover-bg;\n  }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n  &,\n  &:hover,\n  &:focus {\n    color: @dropdown-link-active-color;\n    text-decoration: none;\n    outline: 0;\n    background-color: @dropdown-link-active-bg;\n  }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n  &,\n  &:hover,\n  &:focus {\n    color: @dropdown-link-disabled-color;\n  }\n}\n// Nuke hover/focus effects\n.dropdown-menu > .disabled > a {\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    background-color: transparent;\n    background-image: none; // Remove CSS gradient\n    .reset-filter();\n    cursor: not-allowed;\n  }\n}\n\n// Open state for the dropdown\n.open {\n  // Show the menu\n  > .dropdown-menu {\n    display: block;\n  }\n\n  // Remove the outline when :focus is triggered\n  > a {\n    outline: 0;\n  }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n  left: auto; // Reset the default from `.dropdown-menu`\n  right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n  left: 0;\n  right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: @font-size-small;\n  line-height: @line-height-base;\n  color: @dropdown-header-color;\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n  position: fixed;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  top: 0;\n  z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n  // Reverse the caret\n  .caret {\n    border-top: 0;\n    border-bottom: @caret-width-base solid;\n    content: \"\";\n  }\n  // Different positioning for bottom up menu\n  .dropdown-menu {\n    top: auto;\n    bottom: 100%;\n    margin-bottom: 1px;\n  }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n at media (min-width: @grid-float-breakpoint) {\n  .navbar-right {\n    .dropdown-menu {\n      .dropdown-menu-right();\n    }\n    // Necessary for overrides of the default right aligned menu.\n    // Will remove come v4 in all likelihood.\n    .dropdown-menu-left {\n      .dropdown-menu-left();\n    }\n  }\n}\n\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle; // match .btn alignment given font-size hack above\n  > .btn {\n    position: relative;\n    float: left;\n    // Bring the \"active\" button to the front\n    &:hover,\n    &:focus,\n    &:active,\n    &.active {\n      z-index: 2;\n    }\n    &:focus {\n      // Remove focus outline when dropdown JS adds it after closing the menu\n      outline: none;\n    }\n  }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n  .btn + .btn,\n  .btn + .btn-group,\n  .btn-group + .btn,\n  .btn-group + .btn-group {\n    margin-left: -1px;\n  }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n  margin-left: -5px; // Offset the first child's margin\n  &:extend(.clearfix all);\n\n  .btn-group,\n  .input-group {\n    float: left;\n  }\n  > .btn,\n  > .btn-group,\n  > .input-group {\n    margin-left: 5px;\n  }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n  margin-left: 0;\n  &:not(:last-child):not(.dropdown-toggle) {\n    .border-right-radius(0);\n  }\n}\n// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child {\n  > .btn:last-child,\n  > .dropdown-toggle {\n    .border-right-radius(0);\n  }\n}\n.btn-group > .btn-group:last-child > .btn:first-child {\n  .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { .btn-xs(); }\n.btn-group-sm > .btn { .btn-sm(); }\n.btn-group-lg > .btn { .btn-lg(); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n  padding-left: 8px;\n  padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-left: 12px;\n  padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n  .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n  // Show no shadow for `.btn-link` since it has no other button styles.\n  &.btn-link {\n    .box-shadow(none);\n  }\n}\n\n\n// Reposition the caret\n.btn .caret {\n  margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n  border-width: @caret-width-large @caret-width-large 0;\n  border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n  border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n  > .btn,\n  > .btn-group,\n  > .btn-group > .btn {\n    display: block;\n    float: none;\n    width: 100%;\n    max-width: 100%;\n  }\n\n  // Clear floats so dropdown menus can be properly placed\n  > .btn-group {\n    &:extend(.clearfix all);\n    > .btn {\n      float: none;\n    }\n  }\n\n  > .btn + .btn,\n  > .btn + .btn-group,\n  > .btn-group + .btn,\n  > .btn-group + .btn-group {\n    margin-top: -1px;\n    margin-left: 0;\n  }\n}\n\n.btn-group-vertical > .btn {\n  &:not(:first-child):not(:last-child) {\n    border-radius: 0;\n  }\n  &:first-child:not(:last-child) {\n    border-top-right-radius: @border-radius-base;\n    .border-bottom-radius(0);\n  }\n  &:last-child:not(:first-child) {\n    border-bottom-left-radius: @border-radius-base;\n    .border-top-radius(0);\n  }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n  > .btn:last-child,\n  > .dropdown-toggle {\n    .border-bottom-radius(0);\n  }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  .border-top-radius(0);\n}\n\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n  > .btn,\n  > .btn-group {\n    float: none;\n    display: table-cell;\n    width: 1%;\n  }\n  > .btn-group .btn {\n    width: 100%;\n  }\n}\n\n\n// Checkbox and radio options\n[data-toggle=\"buttons\"] > .btn > input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn > input[type=\"checkbox\"] {\n  display: none;\n}\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n  position: relative; // For dropdowns\n  display: table;\n  border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n  // Undo padding and float of grid classes\n  &[class*=\"col-\"] {\n    float: none;\n    padding-left: 0;\n    padding-right: 0;\n  }\n\n  .form-control {\n    // IE9 fubars the placeholder attribute in text inputs and the arrows on\n    // select elements in input groups. To fix it, we float the input. Details:\n    // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n    float: left;\n\n    width: 100%;\n    margin-bottom: 0;\n  }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn { .input-lg(); }\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn { .input-sm(); }\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n\n  &:not(:first-child):not(:last-child) {\n    border-radius: 0;\n  }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n  padding: @padding-base-vertical @padding-base-horizontal;\n  font-size: @font-size-base;\n  font-weight: normal;\n  line-height: 1;\n  color: @input-color;\n  text-align: center;\n  background-color: @input-group-addon-bg;\n  border: 1px solid @input-group-addon-border-color;\n  border-radius: @border-radius-base;\n\n  // Sizing\n  &.input-sm {\n    padding: @padding-small-vertical @padding-small-horizontal;\n    font-size: @font-size-small;\n    border-radius: @border-radius-small;\n  }\n  &.input-lg {\n    padding: @padding-large-vertical @padding-large-horizontal;\n    font-size: @font-size-large;\n    border-radius: @border-radius-large;\n  }\n\n  // Nuke default margins from checkboxes and radios to vertically center within.\n  input[type=\"radio\"],\n  input[type=\"checkbox\"] {\n    margin-top: 0;\n  }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n  .border-right-radius(0);\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n  .border-left-radius(0);\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n  position: relative;\n  // Jankily prevent input button groups from wrapping with `white-space` and\n  // `font-size` in combination with `inline-block` on buttons.\n  font-size: 0;\n  white-space: nowrap;\n\n  // Negative margin for spacing, position for bringing hovered/focused/actived\n  // element above the siblings.\n  > .btn {\n    position: relative;\n    + .btn {\n      margin-left: -1px;\n    }\n    // Bring the \"active\" button to the front\n    &:hover,\n    &:focus,\n    &:active {\n      z-index: 2;\n    }\n  }\n\n  // Negative margin to only have a 1px border between the two\n  &:first-child {\n    > .btn,\n    > .btn-group {\n      margin-right: -1px;\n    }\n  }\n  &:last-child {\n    > .btn,\n    > .btn-group {\n      margin-left: -1px;\n    }\n  }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n  margin-bottom: 0;\n  padding-left: 0; // Override default ul/ol\n  list-style: none;\n  &:extend(.clearfix all);\n\n  > li {\n    position: relative;\n    display: block;\n\n    > a {\n      position: relative;\n      display: block;\n      padding: @nav-link-padding;\n      &:hover,\n      &:focus {\n        text-decoration: none;\n        background-color: @nav-link-hover-bg;\n      }\n    }\n\n    // Disabled state sets text to gray and nukes hover/tab effects\n    &.disabled > a {\n      color: @nav-disabled-link-color;\n\n      &:hover,\n      &:focus {\n        color: @nav-disabled-link-hover-color;\n        text-decoration: none;\n        background-color: transparent;\n        cursor: not-allowed;\n      }\n    }\n  }\n\n  // Open dropdowns\n  .open > a {\n    &,\n    &:hover,\n    &:focus {\n      background-color: @nav-link-hover-bg;\n      border-color: @link-color;\n    }\n  }\n\n  // Nav dividers (deprecated with v3.0.1)\n  //\n  // This should have been removed in v3 with the dropping of `.nav-list`, but\n  // we missed it. We don't currently support this anywhere, but in the interest\n  // of maintaining backward compatibility in case you use it, it's deprecated.\n  .nav-divider {\n    .nav-divider();\n  }\n\n  // Prevent IE8 from misplacing imgs\n  //\n  // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n  > li > a > img {\n    max-width: none;\n  }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n  border-bottom: 1px solid @nav-tabs-border-color;\n  > li {\n    float: left;\n    // Make the list-items overlay the bottom border\n    margin-bottom: -1px;\n\n    // Actual tabs (as links)\n    > a {\n      margin-right: 2px;\n      line-height: @line-height-base;\n      border: 1px solid transparent;\n      border-radius: @border-radius-base @border-radius-base 0 0;\n      &:hover {\n        border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n      }\n    }\n\n    // Active state, and its :hover to override normal :hover\n    &.active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @nav-tabs-active-link-hover-color;\n        background-color: @nav-tabs-active-link-hover-bg;\n        border: 1px solid @nav-tabs-active-link-hover-border-color;\n        border-bottom-color: transparent;\n        cursor: default;\n      }\n    }\n  }\n  // pulling this in mainly for less shorthand\n  &.nav-justified {\n    .nav-justified();\n    .nav-tabs-justified();\n  }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n  > li {\n    float: left;\n\n    // Links rendered as pills\n    > a {\n      border-radius: @nav-pills-border-radius;\n    }\n    + li {\n      margin-left: 2px;\n    }\n\n    // Active state\n    &.active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @nav-pills-active-link-hover-color;\n        background-color: @nav-pills-active-link-hover-bg;\n      }\n    }\n  }\n}\n\n\n// Stacked pills\n.nav-stacked {\n  > li {\n    float: none;\n    + li {\n      margin-top: 2px;\n      margin-left: 0; // no need for this gap between nav items\n    }\n  }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n  width: 100%;\n\n  > li {\n    float: none;\n     > a {\n      text-align: center;\n      margin-bottom: 5px;\n    }\n  }\n\n  > .dropdown .dropdown-menu {\n    top: auto;\n    left: auto;\n  }\n\n  @media (min-width: @screen-sm-min) {\n    > li {\n      display: table-cell;\n      width: 1%;\n      > a {\n        margin-bottom: 0;\n      }\n    }\n  }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n  border-bottom: 0;\n\n  > li > a {\n    // Override margin from .nav-tabs\n    margin-right: 0;\n    border-radius: @border-radius-base;\n  }\n\n  > .active > a,\n  > .active > a:hover,\n  > .active > a:focus {\n    border: 1px solid @nav-tabs-justified-link-border-color;\n  }\n\n  @media (min-width: @screen-sm-min) {\n    > li > a {\n      border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n      border-radius: @border-radius-base @border-radius-base 0 0;\n    }\n    > .active > a,\n    > .active > a:hover,\n    > .active > a:focus {\n      border-bottom-color: @nav-tabs-justified-active-link-border-color;\n    }\n  }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n  > .tab-pane {\n    display: none;\n  }\n  > .active {\n    display: block;\n  }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n  // make dropdown border overlap tab border\n  margin-top: -1px;\n  // Remove the top rounded corners here since there is a hard edge above the menu\n  .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n  position: relative;\n  min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n  margin-bottom: @navbar-margin-bottom;\n  border: 1px solid transparent;\n\n  // Prevent floats from breaking the navbar\n  &:extend(.clearfix all);\n\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: @navbar-border-radius;\n  }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n  &:extend(.clearfix all);\n\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n  }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n  max-height: @navbar-collapse-max-height;\n  overflow-x: visible;\n  padding-right: @navbar-padding-horizontal;\n  padding-left:  @navbar-padding-horizontal;\n  border-top: 1px solid transparent;\n  box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n  &:extend(.clearfix all);\n  -webkit-overflow-scrolling: touch;\n\n  &.in {\n    overflow-y: auto;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    width: auto;\n    border-top: 0;\n    box-shadow: none;\n\n    &.collapse {\n      display: block !important;\n      height: auto !important;\n      padding-bottom: 0; // Override default setting\n      overflow: visible !important;\n    }\n\n    &.in {\n      overflow-y: visible;\n    }\n\n    // Undo the collapse side padding for navbars with containers to ensure\n    // alignment of right-aligned contents.\n    .navbar-fixed-top &,\n    .navbar-static-top &,\n    .navbar-fixed-bottom & {\n      padding-left: 0;\n      padding-right: 0;\n    }\n  }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n  > .navbar-header,\n  > .navbar-collapse {\n    margin-right: - at navbar-padding-horizontal;\n    margin-left:  - at navbar-padding-horizontal;\n\n    @media (min-width: @grid-float-breakpoint) {\n      margin-right: 0;\n      margin-left:  0;\n    }\n  }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n  z-index: @zindex-navbar;\n  border-width: 0 0 1px;\n\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: 0;\n  }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: @zindex-navbar-fixed;\n\n  // Undo the rounded corners\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0; // override .navbar defaults\n  border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n  float: left;\n  padding: @navbar-padding-vertical @navbar-padding-horizontal;\n  font-size: @font-size-large;\n  line-height: @line-height-computed;\n  height: @line-height-computed;\n\n  &:hover,\n  &:focus {\n    text-decoration: none;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    .navbar > .container &,\n    .navbar > .container-fluid & {\n      margin-left: - at navbar-padding-horizontal;\n    }\n  }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n  position: relative;\n  float: right;\n  margin-right: @navbar-padding-horizontal;\n  padding: 9px 10px;\n  .navbar-vertical-align(34px);\n  background-color: transparent;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid transparent;\n  border-radius: @border-radius-base;\n\n  // We remove the `outline` here, but later compensate by attaching `:hover`\n  // styles to `:focus`.\n  &:focus {\n    outline: none;\n  }\n\n  // Bars\n  .icon-bar {\n    display: block;\n    width: 22px;\n    height: 2px;\n    border-radius: 1px;\n  }\n  .icon-bar + .icon-bar {\n    margin-top: 4px;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    display: none;\n  }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n  margin: (@navbar-padding-vertical / 2) - at navbar-padding-horizontal;\n\n  > li > a {\n    padding-top:    10px;\n    padding-bottom: 10px;\n    line-height: @line-height-computed;\n  }\n\n  @media (max-width: @grid-float-breakpoint-max) {\n    // Dropdowns get custom display when collapsed\n    .open .dropdown-menu {\n      position: static;\n      float: none;\n      width: auto;\n      margin-top: 0;\n      background-color: transparent;\n      border: 0;\n      box-shadow: none;\n      > li > a,\n      .dropdown-header {\n        padding: 5px 15px 5px 25px;\n      }\n      > li > a {\n        line-height: @line-height-computed;\n        &:hover,\n        &:focus {\n          background-image: none;\n        }\n      }\n    }\n  }\n\n  // Uncollapse the nav\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n    margin: 0;\n\n    > li {\n      float: left;\n      > a {\n        padding-top:    @navbar-padding-vertical;\n        padding-bottom: @navbar-padding-vertical;\n      }\n    }\n\n    &.navbar-right:last-child {\n      margin-right: - at navbar-padding-horizontal;\n    }\n  }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n\n at media (min-width: @grid-float-breakpoint) {\n  .navbar-left  { .pull-left(); }\n  .navbar-right { .pull-right(); }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n  margin-left: - at navbar-padding-horizontal;\n  margin-right: - at navbar-padding-horizontal;\n  padding: 10px @navbar-padding-horizontal;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n  .box-shadow(@shadow);\n\n  // Mixin behavior for optimum display\n  .form-inline();\n\n  .form-group {\n    @media (max-width: @grid-float-breakpoint-max) {\n      margin-bottom: 5px;\n    }\n  }\n\n  // Vertically center in expanded, horizontal navbar\n  .navbar-vertical-align(@input-height-base);\n\n  // Undo 100% width for pull classes\n  @media (min-width: @grid-float-breakpoint) {\n    width: auto;\n    border: 0;\n    margin-left: 0;\n    margin-right: 0;\n    padding-top: 0;\n    padding-bottom: 0;\n    .box-shadow(none);\n\n    // Outdent the form if last child to line up with content down the page\n    &.navbar-right:last-child {\n      margin-right: - at navbar-padding-horizontal;\n    }\n  }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n  .navbar-vertical-align(@input-height-base);\n\n  &.btn-sm {\n    .navbar-vertical-align(@input-height-small);\n  }\n  &.btn-xs {\n    .navbar-vertical-align(22);\n  }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n  .navbar-vertical-align(@line-height-computed);\n\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n    margin-left: @navbar-padding-horizontal;\n    margin-right: @navbar-padding-horizontal;\n\n    // Outdent the form if last child to line up with content down the page\n    &.navbar-right:last-child {\n      margin-right: 0;\n    }\n  }\n}\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n  background-color: @navbar-default-bg;\n  border-color: @navbar-default-border;\n\n  .navbar-brand {\n    color: @navbar-default-brand-color;\n    &:hover,\n    &:focus {\n      color: @navbar-default-brand-hover-color;\n      background-color: @navbar-default-brand-hover-bg;\n    }\n  }\n\n  .navbar-text {\n    color: @navbar-default-color;\n  }\n\n  .navbar-nav {\n    > li > a {\n      color: @navbar-default-link-color;\n\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-hover-color;\n        background-color: @navbar-default-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-active-color;\n        background-color: @navbar-default-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-disabled-color;\n        background-color: @navbar-default-link-disabled-bg;\n      }\n    }\n  }\n\n  .navbar-toggle {\n    border-color: @navbar-default-toggle-border-color;\n    &:hover,\n    &:focus {\n      background-color: @navbar-default-toggle-hover-bg;\n    }\n    .icon-bar {\n      background-color: @navbar-default-toggle-icon-bar-bg;\n    }\n  }\n\n  .navbar-collapse,\n  .navbar-form {\n    border-color: @navbar-default-border;\n  }\n\n  // Dropdown menu items\n  .navbar-nav {\n    // Remove background color from open dropdown\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navbar-default-link-active-bg;\n        color: @navbar-default-link-active-color;\n      }\n    }\n\n    @media (max-width: @grid-float-breakpoint-max) {\n      // Dropdowns get custom display when collapsed\n      .open .dropdown-menu {\n        > li > a {\n          color: @navbar-default-link-color;\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-hover-color;\n            background-color: @navbar-default-link-hover-bg;\n          }\n        }\n        > .active > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-active-color;\n            background-color: @navbar-default-link-active-bg;\n          }\n        }\n        > .disabled > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-disabled-color;\n            background-color: @navbar-default-link-disabled-bg;\n          }\n        }\n      }\n    }\n  }\n\n\n  // Links in navbars\n  //\n  // Add a class to ensure links outside the navbar nav are colored correctly.\n\n  .navbar-link {\n    color: @navbar-default-link-color;\n    &:hover {\n      color: @navbar-default-link-hover-color;\n    }\n  }\n\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n  background-color: @navbar-inverse-bg;\n  border-color: @navbar-inverse-border;\n\n  .navbar-brand {\n    color: @navbar-inverse-brand-color;\n    &:hover,\n    &:focus {\n      color: @navbar-inverse-brand-hover-color;\n      background-color: @navbar-inverse-brand-hover-bg;\n    }\n  }\n\n  .navbar-text {\n    color: @navbar-inverse-color;\n  }\n\n  .navbar-nav {\n    > li > a {\n      color: @navbar-inverse-link-color;\n\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-hover-color;\n        background-color: @navbar-inverse-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-active-color;\n        background-color: @navbar-inverse-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-disabled-color;\n        background-color: @navbar-inverse-link-disabled-bg;\n      }\n    }\n  }\n\n  // Darken the responsive nav toggle\n  .navbar-toggle {\n    border-color: @navbar-inverse-toggle-border-color;\n    &:hover,\n    &:focus {\n      background-color: @navbar-inverse-toggle-hover-bg;\n    }\n    .icon-bar {\n      background-color: @navbar-inverse-toggle-icon-bar-bg;\n    }\n  }\n\n  .navbar-collapse,\n  .navbar-form {\n    border-color: darken(@navbar-inverse-bg, 7%);\n  }\n\n  // Dropdowns\n  .navbar-nav {\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navbar-inverse-link-active-bg;\n        color: @navbar-inverse-link-active-color;\n      }\n    }\n\n    @media (max-width: @grid-float-breakpoint-max) {\n      // Dropdowns get custom display\n      .open .dropdown-menu {\n        > .dropdown-header {\n          border-color: @navbar-inverse-border;\n        }\n        .divider {\n          background-color: @navbar-inverse-border;\n        }\n        > li > a {\n          color: @navbar-inverse-link-color;\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-hover-color;\n            background-color: @navbar-inverse-link-hover-bg;\n          }\n        }\n        > .active > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-active-color;\n            background-color: @navbar-inverse-link-active-bg;\n          }\n        }\n        > .disabled > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-disabled-color;\n            background-color: @navbar-inverse-link-disabled-bg;\n          }\n        }\n      }\n    }\n  }\n\n  .navbar-link {\n    color: @navbar-inverse-link-color;\n    &:hover {\n      color: @navbar-inverse-link-hover-color;\n    }\n  }\n\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n  .clearfix();\n}\n.center-block {\n  .center-block();\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n  display: none !important;\n  visibility: hidden !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n  position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n  padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n  margin-bottom: @line-height-computed;\n  list-style: none;\n  background-color: @breadcrumb-bg;\n  border-radius: @border-radius-base;\n\n  > li {\n    display: inline-block;\n\n    + li:before {\n      content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n      padding: 0 5px;\n      color: @breadcrumb-color;\n    }\n  }\n\n  > .active {\n    color: @breadcrumb-active-color;\n  }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: @line-height-computed 0;\n  border-radius: @border-radius-base;\n\n  > li {\n    display: inline; // Remove list-style and block-level defaults\n    > a,\n    > span {\n      position: relative;\n      float: left; // Collapse white-space\n      padding: @padding-base-vertical @padding-base-horizontal;\n      line-height: @line-height-base;\n      text-decoration: none;\n      color: @pagination-color;\n      background-color: @pagination-bg;\n      border: 1px solid @pagination-border;\n      margin-left: -1px;\n    }\n    &:first-child {\n      > a,\n      > span {\n        margin-left: 0;\n        .border-left-radius(@border-radius-base);\n      }\n    }\n    &:last-child {\n      > a,\n      > span {\n        .border-right-radius(@border-radius-base);\n      }\n    }\n  }\n\n  > li > a,\n  > li > span {\n    &:hover,\n    &:focus {\n      color: @pagination-hover-color;\n      background-color: @pagination-hover-bg;\n      border-color: @pagination-hover-border;\n    }\n  }\n\n  > .active > a,\n  > .active > span {\n    &,\n    &:hover,\n    &:focus {\n      z-index: 2;\n      color: @pagination-active-color;\n      background-color: @pagination-active-bg;\n      border-color: @pagination-active-border;\n      cursor: default;\n    }\n  }\n\n  > .disabled {\n    > span,\n    > span:hover,\n    > span:focus,\n    > a,\n    > a:hover,\n    > a:focus {\n      color: @pagination-disabled-color;\n      background-color: @pagination-disabled-bg;\n      border-color: @pagination-disabled-border;\n      cursor: not-allowed;\n    }\n  }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n  .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n  .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @border-radius-small);\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n  padding-left: 0;\n  margin: @line-height-computed 0;\n  list-style: none;\n  text-align: center;\n  &:extend(.clearfix all);\n  li {\n    display: inline;\n    > a,\n    > span {\n      display: inline-block;\n      padding: 5px 14px;\n      background-color: @pager-bg;\n      border: 1px solid @pager-border;\n      border-radius: @pager-border-radius;\n    }\n\n    > a:hover,\n    > a:focus {\n      text-decoration: none;\n      background-color: @pager-hover-bg;\n    }\n  }\n\n  .next {\n    > a,\n    > span {\n      float: right;\n    }\n  }\n\n  .previous {\n    > a,\n    > span {\n      float: left;\n    }\n  }\n\n  .disabled {\n    > a,\n    > a:hover,\n    > a:focus,\n    > span {\n      color: @pager-disabled-color;\n      background-color: @pager-bg;\n      cursor: not-allowed;\n    }\n  }\n\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: @label-color;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n\n  // Add hover effects, but only for links\n  &[href] {\n    &:hover,\n    &:focus {\n      color: @label-link-hover-color;\n      text-decoration: none;\n      cursor: pointer;\n    }\n  }\n\n  // Empty labels collapse automatically (not available in IE8)\n  &:empty {\n    display: none;\n  }\n\n  // Quick fix for labels in buttons\n  .btn & {\n    position: relative;\n    top: -1px;\n  }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n  .label-variant(@label-default-bg);\n}\n\n.label-primary {\n  .label-variant(@label-primary-bg);\n}\n\n.label-success {\n  .label-variant(@label-success-bg);\n}\n\n.label-info {\n  .label-variant(@label-info-bg);\n}\n\n.label-warning {\n  .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n  .label-variant(@label-danger-bg);\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base classes\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: @font-size-small;\n  font-weight: @badge-font-weight;\n  color: @badge-color;\n  line-height: @badge-line-height;\n  vertical-align: baseline;\n  white-space: nowrap;\n  text-align: center;\n  background-color: @badge-bg;\n  border-radius: @badge-border-radius;\n\n  // Empty badges collapse automatically (not available in IE8)\n  &:empty {\n    display: none;\n  }\n\n  // Quick fix for badges in buttons\n  .btn & {\n    position: relative;\n    top: -1px;\n  }\n  .btn-xs & {\n    top: 0;\n    padding: 1px 5px;\n  }\n}\n\n// Hover state, but only for links\na.badge {\n  &:hover,\n  &:focus {\n    color: @badge-link-hover-color;\n    text-decoration: none;\n    cursor: pointer;\n  }\n}\n\n// Account for counters in navs\na.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: @badge-active-color;\n  background-color: @badge-active-bg;\n}\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n  padding: @jumbotron-padding;\n  margin-bottom: @jumbotron-padding;\n  color: @jumbotron-color;\n  background-color: @jumbotron-bg;\n\n  h1,\n  .h1 {\n    color: @jumbotron-heading-color;\n  }\n  p {\n    margin-bottom: (@jumbotron-padding / 2);\n    font-size: @jumbotron-font-size;\n    font-weight: 200;\n  }\n\n  .container & {\n    border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n  }\n\n  .container {\n    max-width: 100%;\n  }\n\n  @media screen and (min-width: @screen-sm-min) {\n    padding-top:    (@jumbotron-padding * 1.6);\n    padding-bottom: (@jumbotron-padding * 1.6);\n\n    .container & {\n      padding-left:  (@jumbotron-padding * 2);\n      padding-right: (@jumbotron-padding * 2);\n    }\n\n    h1,\n    .h1 {\n      font-size: (@font-size-base * 4.5);\n    }\n  }\n}\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n  display: block;\n  padding: @thumbnail-padding;\n  margin-bottom: @line-height-computed;\n  line-height: @line-height-base;\n  background-color: @thumbnail-bg;\n  border: 1px solid @thumbnail-border;\n  border-radius: @thumbnail-border-radius;\n  .transition(all .2s ease-in-out);\n\n  > img,\n  a > img {\n    .img-responsive();\n    margin-left: auto;\n    margin-right: auto;\n  }\n\n  // Add a hover state for linked versions only\n  a&:hover,\n  a&:focus,\n  a&.active {\n    border-color: @link-color;\n  }\n\n  // Image captions\n  .caption {\n    padding: @thumbnail-caption-padding;\n    color: @thumbnail-caption-color;\n  }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n  padding: @alert-padding;\n  margin-bottom: @line-height-computed;\n  border: 1px solid transparent;\n  border-radius: @alert-border-radius;\n\n  // Headings for larger alerts\n  h4 {\n    margin-top: 0;\n    // Specified for the h4 to prevent conflicts of changing @headings-color\n    color: inherit;\n  }\n  // Provide class for links that match alerts\n  .alert-link {\n    font-weight: @alert-link-font-weight;\n  }\n\n  // Improve alignment and spacing of inner content\n  > p,\n  > ul {\n    margin-bottom: 0;\n  }\n  > p + p {\n    margin-top: 5px;\n  }\n}\n\n// Dismissable alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable {\n padding-right: (@alert-padding + 20);\n\n  // Adjust close link position\n  .close {\n    position: relative;\n    top: -2px;\n    right: -21px;\n    color: inherit;\n  }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n  .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n.alert-info {\n  .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n.alert-warning {\n  .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n.alert-danger {\n  .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n at -webkit-keyframes progress-bar-stripes {\n  from  { background-position: 40px 0; }\n  to    { background-position: 0 0; }\n}\n\n// Spec and IE10+\n at keyframes progress-bar-stripes {\n  from  { background-position: 40px 0; }\n  to    { background-position: 0 0; }\n}\n\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n  overflow: hidden;\n  height: @line-height-computed;\n  margin-bottom: @line-height-computed;\n  background-color: @progress-bg;\n  border-radius: @border-radius-base;\n  .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n  float: left;\n  width: 0%;\n  height: 100%;\n  font-size: @font-size-small;\n  line-height: @line-height-computed;\n  color: @progress-bar-color;\n  text-align: center;\n  background-color: @progress-bar-bg;\n  .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n  .transition(width .6s ease);\n}\n\n// Striped bars\n.progress-striped .progress-bar {\n  #gradient > .striped();\n  background-size: 40px 40px;\n}\n\n// Call animation for the active one\n.progress.active .progress-bar {\n  .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n  .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n  .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n  .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n  .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Media objects\n// Source: http://stubbornella.org/content/?p=497\n// --------------------------------------------------\n\n\n// Common styles\n// -------------------------\n\n// Clear the floats\n.media,\n.media-body {\n  overflow: hidden;\n  zoom: 1;\n}\n\n// Proper spacing between instances of .media\n.media,\n.media .media {\n  margin-top: 15px;\n}\n.media:first-child {\n  margin-top: 0;\n}\n\n// For images and videos, set to block\n.media-object {\n  display: block;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n  margin: 0 0 5px;\n}\n\n\n// Media image alignment\n// -------------------------\n\n.media {\n  > .pull-left {\n    margin-right: 10px;\n  }\n  > .pull-right {\n    margin-left: 10px;\n  }\n}\n\n\n// Media list variation\n// -------------------------\n\n// Undo default ul/ol styles\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n  // No need to set list-style: none; since .list-group-item is block level\n  margin-bottom: 20px;\n  padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  // Place the border on the list items and negative margin up for better styling\n  margin-bottom: -1px;\n  background-color: @list-group-bg;\n  border: 1px solid @list-group-border;\n\n  // Round the first and last items\n  &:first-child {\n    .border-top-radius(@list-group-border-radius);\n  }\n  &:last-child {\n    margin-bottom: 0;\n    .border-bottom-radius(@list-group-border-radius);\n  }\n\n  // Align badges within list items\n  > .badge {\n    float: right;\n  }\n  > .badge + .badge {\n    margin-right: 5px;\n  }\n}\n\n\n// Linked list items\n//\n// Use anchor elements instead of `li`s or `div`s to create linked list items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item {\n  color: @list-group-link-color;\n\n  .list-group-item-heading {\n    color: @list-group-link-heading-color;\n  }\n\n  // Hover state\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    background-color: @list-group-hover-bg;\n  }\n\n  // Active class on item itself, not parent\n  &.active,\n  &.active:hover,\n  &.active:focus {\n    z-index: 2; // Place active items above their siblings for proper border styling\n    color: @list-group-active-color;\n    background-color: @list-group-active-bg;\n    border-color: @list-group-active-border;\n\n    // Force color to inherit for custom content\n    .list-group-item-heading {\n      color: inherit;\n    }\n    .list-group-item-text {\n      color: @list-group-active-text-color;\n    }\n  }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n","//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n  margin-bottom: @line-height-computed;\n  background-color: @panel-bg;\n  border: 1px solid transparent;\n  border-radius: @panel-border-radius;\n  .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n  padding: @panel-body-padding;\n  &:extend(.clearfix all);\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n  > .list-group {\n    margin-bottom: 0;\n    .list-group-item {\n      border-width: 1px 0;\n      border-radius: 0;\n      &:first-child {\n        border-top: 0;\n      }\n      &:last-child {\n        border-bottom: 0;\n      }\n    }\n    // Add border top radius for first one\n    &:first-child {\n      .list-group-item:first-child {\n        .border-top-radius((@panel-border-radius - 1));\n      }\n    }\n    // Add border bottom radius for last one\n    &:last-child {\n      .list-group-item:last-child {\n        .border-bottom-radius((@panel-border-radius - 1));\n      }\n    }\n  }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n  .list-group-item:first-child {\n    border-top-width: 0;\n  }\n}\n\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n  > .table,\n  > .table-responsive > .table {\n    margin-bottom: 0;\n  }\n  // Add border top radius for first one\n  > .table:first-child,\n  > .table-responsive:first-child > .table:first-child {\n    > thead:first-child,\n    > tbody:first-child {\n      > tr:first-child {\n        td:first-child,\n        th:first-child {\n          border-top-left-radius: (@panel-border-radius - 1);\n        }\n        td:last-child,\n        th:last-child {\n          border-top-right-radius: (@panel-border-radius - 1);\n        }\n      }\n    }\n  }\n  // Add border bottom radius for last one\n  > .table:last-child,\n  > .table-responsive:last-child > .table:last-child {\n    > tbody:last-child,\n    > tfoot:last-child {\n      > tr:last-child {\n        td:first-child,\n        th:first-child {\n          border-bottom-left-radius: (@panel-border-radius - 1);\n        }\n        td:last-child,\n        th:last-child {\n          border-bottom-right-radius: (@panel-border-radius - 1);\n        }\n      }\n    }\n  }\n  > .panel-body + .table,\n  > .panel-body + .table-responsive {\n    border-top: 1px solid @table-border-color;\n  }\n  > .table > tbody:first-child > tr:first-child th,\n  > .table > tbody:first-child > tr:first-child td {\n    border-top: 0;\n  }\n  > .table-bordered,\n  > .table-responsive > .table-bordered {\n    border: 0;\n    > thead,\n    > tbody,\n    > tfoot {\n      > tr {\n        > th:first-child,\n        > td:first-child {\n          border-left: 0;\n        }\n        > th:last-child,\n        > td:last-child {\n          border-right: 0;\n        }\n        &:first-child > th,\n        &:first-child > td {\n          border-top: 0;\n        }\n        &:last-child > th,\n        &:last-child > td {\n          border-bottom: 0;\n        }\n      }\n    }\n  }\n  > .table-responsive {\n    border: 0;\n    margin-bottom: 0;\n  }\n}\n\n\n// Optional heading\n.panel-heading {\n  padding: 10px 15px;\n  border-bottom: 1px solid transparent;\n  .border-top-radius((@panel-border-radius - 1));\n\n  > .dropdown .dropdown-toggle {\n    color: inherit;\n  }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: ceil((@font-size-base * 1.125));\n  color: inherit;\n\n  > a {\n    color: inherit;\n  }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n  padding: 10px 15px;\n  background-color: @panel-footer-bg;\n  border-top: 1px solid @panel-inner-border;\n  .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// Collapsable panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n  margin-bottom: @line-height-computed;\n\n  // Tighten up margin so it's only between panels\n  .panel {\n    margin-bottom: 0;\n    border-radius: @panel-border-radius;\n    overflow: hidden; // crop contents when collapsed\n    + .panel {\n      margin-top: 5px;\n    }\n  }\n\n  .panel-heading {\n    border-bottom: 0;\n    + .panel-collapse .panel-body {\n      border-top: 1px solid @panel-inner-border;\n    }\n  }\n  .panel-footer {\n    border-top: 0;\n    + .panel-collapse .panel-body {\n      border-bottom: 1px solid @panel-inner-border;\n    }\n  }\n}\n\n\n// Contextual variations\n.panel-default {\n  .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n  .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n  .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n  .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n  .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n  .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n","//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: @well-bg;\n  border: 1px solid @well-border;\n  border-radius: @border-radius-base;\n  .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n  blockquote {\n    border-color: #ddd;\n    border-color: rgba(0,0,0,.15);\n  }\n}\n\n// Sizes\n.well-lg {\n  padding: 24px;\n  border-radius: @border-radius-large;\n}\n.well-sm {\n  padding: 9px;\n  border-radius: @border-radius-small;\n}\n","//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n  float: right;\n  font-size: (@font-size-base * 1.5);\n  font-weight: @close-font-weight;\n  line-height: 1;\n  color: @close-color;\n  text-shadow: @close-text-shadow;\n  .opacity(.2);\n\n  &:hover,\n  &:focus {\n    color: @close-color;\n    text-decoration: none;\n    cursor: pointer;\n    .opacity(.5);\n  }\n\n  // Additional properties for button version\n  // iOS requires the button element instead of an anchor tag.\n  // If you want the anchor version, it requires `href=\"#\"`.\n  button& {\n    padding: 0;\n    cursor: pointer;\n    background: transparent;\n    border: 0;\n    -webkit-appearance: none;\n  }\n}\n","//\n// Modals\n// --------------------------------------------------\n\n// .modal-open      - body class for killing the scroll\n// .modal           - container to scroll within\n// .modal-dialog    - positioning shell for the actual modal\n// .modal-content   - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n  overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n  display: none;\n  overflow: auto;\n  overflow-y: scroll;\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: @zindex-modal;\n  -webkit-overflow-scrolling: touch;\n\n  // Prevent Chrome on Windows from adding a focus outline. For details, see\n  // https://github.com/twbs/bootstrap/pull/10951.\n  outline: 0;\n\n  // When fading in the modal, animate it to slide down\n  &.fade .modal-dialog {\n    .translate(0, -25%);\n    .transition-transform(~\"0.3s ease-out\");\n  }\n  &.in .modal-dialog { .translate(0, 0)}\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n  position: relative;\n  background-color: @modal-content-bg;\n  border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n  border: 1px solid @modal-content-border-color;\n  border-radius: @border-radius-large;\n  .box-shadow(0 3px 9px rgba(0,0,0,.5));\n  background-clip: padding-box;\n  // Remove focus outline from opened modal\n  outline: none;\n}\n\n// Modal background\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: @zindex-modal-background;\n  background-color: @modal-backdrop-bg;\n  // Fade for backdrop\n  &.fade { .opacity(0); }\n  &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n  padding: @modal-title-padding;\n  border-bottom: 1px solid @modal-header-border-color;\n  min-height: (@modal-title-padding + @modal-title-line-height);\n}\n// Close icon\n.modal-header .close {\n  margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n  margin: 0;\n  line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n  position: relative;\n  padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n  margin-top: 15px;\n  padding: (@modal-inner-padding - 1) @modal-inner-padding @modal-inner-padding;\n  text-align: right; // right align buttons\n  border-top: 1px solid @modal-footer-border-color;\n  &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n  // Properly space out buttons\n  .btn + .btn {\n    margin-left: 5px;\n    margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n  }\n  // but override that for button groups\n  .btn-group .btn + .btn {\n    margin-left: -1px;\n  }\n  // and override it for block buttons as well\n  .btn-block + .btn-block {\n    margin-left: 0;\n  }\n}\n\n// Scale up the modal\n at media (min-width: @screen-sm-min) {\n\n  // Automatically set modal's width for larger viewports\n  .modal-dialog {\n    width: @modal-md;\n    margin: 30px auto;\n  }\n  .modal-content {\n    .box-shadow(0 5px 15px rgba(0,0,0,.5));\n  }\n\n  // Modal sizes\n  .modal-sm { width: @modal-sm; }\n  .modal-lg { width: @modal-lg; }\n\n}\n","//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n  position: absolute;\n  z-index: @zindex-tooltip;\n  display: block;\n  visibility: visible;\n  font-size: @font-size-small;\n  line-height: 1.4;\n  .opacity(0);\n\n  &.in     { .opacity(@tooltip-opacity); }\n  &.top    { margin-top:  -3px; padding: @tooltip-arrow-width 0; }\n  &.right  { margin-left:  3px; padding: 0 @tooltip-arrow-width; }\n  &.bottom { margin-top:   3px; padding: @tooltip-arrow-width 0; }\n  &.left   { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n  max-width: @tooltip-max-width;\n  padding: 3px 8px;\n  color: @tooltip-color;\n  text-align: center;\n  text-decoration: none;\n  background-color: @tooltip-bg;\n  border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.tooltip {\n  &.top .tooltip-arrow {\n    bottom: 0;\n    left: 50%;\n    margin-left: - at tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-top-color: @tooltip-arrow-color;\n  }\n  &.top-left .tooltip-arrow {\n    bottom: 0;\n    left: @tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-top-color: @tooltip-arrow-color;\n  }\n  &.top-right .tooltip-arrow {\n    bottom: 0;\n    right: @tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-top-color: @tooltip-arrow-color;\n  }\n  &.right .tooltip-arrow {\n    top: 50%;\n    left: 0;\n    margin-top: - at tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-right-color: @tooltip-arrow-color;\n  }\n  &.left .tooltip-arrow {\n    top: 50%;\n    right: 0;\n    margin-top: - at tooltip-arrow-width;\n    border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-left-color: @tooltip-arrow-color;\n  }\n  &.bottom .tooltip-arrow {\n    top: 0;\n    left: 50%;\n    margin-left: - at tooltip-arrow-width;\n    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-bottom-color: @tooltip-arrow-color;\n  }\n  &.bottom-left .tooltip-arrow {\n    top: 0;\n    left: @tooltip-arrow-width;\n    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-bottom-color: @tooltip-arrow-color;\n  }\n  &.bottom-right .tooltip-arrow {\n    top: 0;\n    right: @tooltip-arrow-width;\n    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-bottom-color: @tooltip-arrow-color;\n  }\n}\n","//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: @zindex-popover;\n  display: none;\n  max-width: @popover-max-width;\n  padding: 1px;\n  text-align: left; // Reset given new insertion method\n  background-color: @popover-bg;\n  background-clip: padding-box;\n  border: 1px solid @popover-fallback-border-color;\n  border: 1px solid @popover-border-color;\n  border-radius: @border-radius-large;\n  .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n  // Overrides for proper insertion\n  white-space: normal;\n\n  // Offset the popover to account for the popover arrow\n  &.top     { margin-top: -10px; }\n  &.right   { margin-left: 10px; }\n  &.bottom  { margin-top: 10px; }\n  &.left    { margin-left: -10px; }\n}\n\n.popover-title {\n  margin: 0; // reset heading margin\n  padding: 8px 14px;\n  font-size: @font-size-base;\n  font-weight: normal;\n  line-height: 18px;\n  background-color: @popover-title-bg;\n  border-bottom: 1px solid darken(@popover-title-bg, 5%);\n  border-radius: 5px 5px 0 0;\n}\n\n.popover-content {\n  padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover .arrow {\n  &,\n  &:after {\n    position: absolute;\n    display: block;\n    width: 0;\n    height: 0;\n    border-color: transparent;\n    border-style: solid;\n  }\n}\n.popover .arrow {\n  border-width: @popover-arrow-outer-width;\n}\n.popover .arrow:after {\n  border-width: @popover-arrow-width;\n  content: \"\";\n}\n\n.popover {\n  &.top .arrow {\n    left: 50%;\n    margin-left: - at popover-arrow-outer-width;\n    border-bottom-width: 0;\n    border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-top-color: @popover-arrow-outer-color;\n    bottom: - at popover-arrow-outer-width;\n    &:after {\n      content: \" \";\n      bottom: 1px;\n      margin-left: - at popover-arrow-width;\n      border-bottom-width: 0;\n      border-top-color: @popover-arrow-color;\n    }\n  }\n  &.right .arrow {\n    top: 50%;\n    left: - at popover-arrow-outer-width;\n    margin-top: - at popover-arrow-outer-width;\n    border-left-width: 0;\n    border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-right-color: @popover-arrow-outer-color;\n    &:after {\n      content: \" \";\n      left: 1px;\n      bottom: - at popover-arrow-width;\n      border-left-width: 0;\n      border-right-color: @popover-arrow-color;\n    }\n  }\n  &.bottom .arrow {\n    left: 50%;\n    margin-left: - at popover-arrow-outer-width;\n    border-top-width: 0;\n    border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-bottom-color: @popover-arrow-outer-color;\n    top: - at popover-arrow-outer-width;\n    &:after {\n      content: \" \";\n      top: 1px;\n      margin-left: - at popover-arrow-width;\n      border-top-width: 0;\n      border-bottom-color: @popover-arrow-color;\n    }\n  }\n\n  &.left .arrow {\n    top: 50%;\n    right: - at popover-arrow-outer-width;\n    margin-top: - at popover-arrow-outer-width;\n    border-right-width: 0;\n    border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-left-color: @popover-arrow-outer-color;\n    &:after {\n      content: \" \";\n      right: 1px;\n      border-right-width: 0;\n      border-left-color: @popover-arrow-color;\n      bottom: - at popover-arrow-width;\n    }\n  }\n\n}\n","//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n  position: relative;\n}\n\n.carousel-inner {\n  position: relative;\n  overflow: hidden;\n  width: 100%;\n\n  > .item {\n    display: none;\n    position: relative;\n    .transition(.6s ease-in-out left);\n\n    // Account for jankitude on images\n    > img,\n    > a > img {\n      .img-responsive();\n      line-height: 1;\n    }\n  }\n\n  > .active,\n  > .next,\n  > .prev { display: block; }\n\n  > .active {\n    left: 0;\n  }\n\n  > .next,\n  > .prev {\n    position: absolute;\n    top: 0;\n    width: 100%;\n  }\n\n  > .next {\n    left: 100%;\n  }\n  > .prev {\n    left: -100%;\n  }\n  > .next.left,\n  > .prev.right {\n    left: 0;\n  }\n\n  > .active.left {\n    left: -100%;\n  }\n  > .active.right {\n    left: 100%;\n  }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  width: @carousel-control-width;\n  .opacity(@carousel-control-opacity);\n  font-size: @carousel-control-font-size;\n  color: @carousel-control-color;\n  text-align: center;\n  text-shadow: @carousel-text-shadow;\n  // We can't have this transition here because WebKit cancels the carousel\n  // animation if you trip this while in the middle of another animation.\n\n  // Set gradients for backgrounds\n  &.left {\n    #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n  }\n  &.right {\n    left: auto;\n    right: 0;\n    #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n  }\n\n  // Hover/focus state\n  &:hover,\n  &:focus {\n    outline: none;\n    color: @carousel-control-color;\n    text-decoration: none;\n    .opacity(.9);\n  }\n\n  // Toggles\n  .icon-prev,\n  .icon-next,\n  .glyphicon-chevron-left,\n  .glyphicon-chevron-right {\n    position: absolute;\n    top: 50%;\n    z-index: 5;\n    display: inline-block;\n  }\n  .icon-prev,\n  .glyphicon-chevron-left {\n    left: 50%;\n  }\n  .icon-next,\n  .glyphicon-chevron-right {\n    right: 50%;\n  }\n  .icon-prev,\n  .icon-next {\n    width:  20px;\n    height: 20px;\n    margin-top: -10px;\n    margin-left: -10px;\n    font-family: serif;\n  }\n\n  .icon-prev {\n    &:before {\n      content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n    }\n  }\n  .icon-next {\n    &:before {\n      content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n    }\n  }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  margin-left: -30%;\n  padding-left: 0;\n  list-style: none;\n  text-align: center;\n\n  li {\n    display: inline-block;\n    width:  10px;\n    height: 10px;\n    margin: 1px;\n    text-indent: -999px;\n    border: 1px solid @carousel-indicator-border-color;\n    border-radius: 10px;\n    cursor: pointer;\n\n    // IE8-9 hack for event handling\n    //\n    // Internet Explorer 8-9 does not support clicks on elements without a set\n    // `background-color`. We cannot use `filter` since that's not viewed as a\n    // background color by the browser. Thus, a hack is needed.\n    //\n    // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n    // set alpha transparency for the best results possible.\n    background-color: #000 \\9; // IE8\n    background-color: rgba(0,0,0,0); // IE9\n  }\n  .active {\n    margin: 0;\n    width:  12px;\n    height: 12px;\n    background-color: @carousel-indicator-active-bg;\n  }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n  position: absolute;\n  left: 15%;\n  right: 15%;\n  bottom: 20px;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: @carousel-caption-color;\n  text-align: center;\n  text-shadow: @carousel-text-shadow;\n  & .btn {\n    text-shadow: none; // No shadow for button elements in carousel-caption\n  }\n}\n\n\n// Scale up controls for tablets and up\n at media screen and (min-width: @screen-sm-min) {\n\n  // Scale up the controls a smidge\n  .carousel-control {\n    .glyphicons-chevron-left,\n    .glyphicons-chevron-right,\n    .icon-prev,\n    .icon-next {\n      width: 30px;\n      height: 30px;\n      margin-top: -15px;\n      margin-left: -15px;\n      font-size: 30px;\n    }\n  }\n\n  // Show and left align the captions\n  .carousel-caption {\n    left: 20%;\n    right: 20%;\n    padding-bottom: 30px;\n  }\n\n  // Move up the indicators\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n","//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#browsers\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n  width: device-width;\n}\n\n\n// Visibility utilities\n.visible-xs {\n  .responsive-invisibility();\n\n  @media (max-width: @screen-xs-max) {\n    .responsive-visibility();\n  }\n}\n.visible-sm {\n  .responsive-invisibility();\n\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    .responsive-visibility();\n  }\n}\n.visible-md {\n  .responsive-invisibility();\n\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    .responsive-visibility();\n  }\n}\n.visible-lg {\n  .responsive-invisibility();\n\n  @media (min-width: @screen-lg-min) {\n    .responsive-visibility();\n  }\n}\n\n.hidden-xs {\n  @media (max-width: @screen-xs-max) {\n    .responsive-invisibility();\n  }\n}\n.hidden-sm {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    .responsive-invisibility();\n  }\n}\n.hidden-md {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    .responsive-invisibility();\n  }\n}\n.hidden-lg {\n  @media (min-width: @screen-lg-min) {\n    .responsive-invisibility();\n  }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n.visible-print {\n  .responsive-invisibility();\n\n  @media print {\n    .responsive-visibility();\n  }\n}\n\n.hidden-print {\n  @media print {\n    .responsive-invisibility();\n  }\n}\n"]}
\ No newline at end of file
diff --git a/app/gui/html/vendor/bootstrap/css/bootstrap.min.css b/app/gui/html/vendor/bootstrap/css/bootstrap.min.css
new file mode 100644
index 0000000..381834e
--- /dev/null
+++ b/app/gui/html/vendor/bootstrap/css/bootstrap.min.css
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v3.1.0 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+/*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@media print{*{text-shadow:none!important;color:#000!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#999}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}cite{font-style:normal}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-muted{color:#999}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}.list-inline>li:first-child{padding-left:0}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.428571429}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.428571429;color:#999}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}blockquote:before,blockquote:after{content:""}address{margin-bottom:20px;font-style:normal;line-height:1.428571429}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;white-space:nowrap;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.428571429;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666666666666%}.col-xs-10{width:83.33333333333334%}.col-xs-9{width:75%}.col-xs-8{width:66.66666666666666%}.col-xs-7{width:58.333333333333336%}.col-xs-6{width:50%}.col-xs-5{width:41.66666666666667%}.col-xs-4{width:33.33333333333333%}.col-xs-3{width:25%}.col-xs-2{width:16.666666666666664%}.col-xs-1{width:8.333333333333332%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666666666666%}.col-xs-pull-10{right:83.33333333333334%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666666666666%}.col-xs-pull-7{right:58.333333333333336%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666666666667%}.col-xs-pull-4{right:33.33333333333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.666666666666664%}.col-xs-pull-1{right:8.333333333333332%}.col-xs-pull-0{right:0}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666666666666%}.col-xs-push-10{left:83.33333333333334%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666666666666%}.col-xs-push-7{left:58.333333333333336%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666666666667%}.col-xs-push-4{left:33.33333333333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.666666666666664%}.col-xs-push-1{left:8.333333333333332%}.col-xs-push-0{left:0}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666666666666%}.col-xs-offset-10{margin-left:83.33333333333334%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666666666666%}.col-xs-offset-7{margin-left:58.333333333333336%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666666666667%}.col-xs-offset-4{margin-left:33.33333333333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.666666666666664%}.col-xs-offset-1{margin-left:8.333333333333332%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666666666666%}.col-sm-10{width:83.33333333333334%}.col-sm-9{width:75%}.col-sm-8{width:66.66666666666666%}.col-sm-7{width:58.333333333333336%}.col-sm-6{width:50%}.col-sm-5{width:41.66666666666667%}.col-sm-4{width:33.33333333333333%}.col-sm-3{width:25%}.col-sm-2{width:16.666666666666664%}.col-sm-1{width:8.333333333333332%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-0{right:0}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666666666666%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-0{left:0}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666666666666%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666666666666%}.col-md-10{width:83.33333333333334%}.col-md-9{width:75%}.col-md-8{width:66.66666666666666%}.col-md-7{width:58.333333333333336%}.col-md-6{width:50%}.col-md-5{width:41.66666666666667%}.col-md-4{width:33.33333333333333%}.col-md-3{width:25%}.col-md-2{width:16.666666666666664%}.col-md-1{width:8.333333333333332%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666666666666%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-0{right:0}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666666666666%}.col-md-push-10{left:83.33333333333334%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666666666666%}.col-md-push-7{left:58.333333333333336%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666666666667%}.col-md-push-4{left:33.33333333333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.666666666666664%}.col-md-push-1{left:8.333333333333332%}.col-md-push-0{left:0}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666666666666%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666666666666%}.col-lg-10{width:83.33333333333334%}.col-lg-9{width:75%}.col-lg-8{width:66.66666666666666%}.col-lg-7{width:58.333333333333336%}.col-lg-6{width:50%}.col-lg-5{width:41.66666666666667%}.col-lg-4{width:33.33333333333333%}.col-lg-3{width:25%}.col-lg-2{width:16.666666666666664%}.col-lg-1{width:8.333333333333332%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-0{right:0}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666666666666%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-0{left:0}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666666666666%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-0{margin-left:0}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.428571429;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*=col-]{position:static;float:none;display:table-column}table td[class*=col-],table th[class*=col-]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}@media (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;overflow-x:scroll;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.428571429;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.428571429;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control:-moz-placeholder{color:#999}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=date]{line-height:34px}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:20px;margin-top:10px;margin-bottom:10px;padding-left:20px}.radio label,.checkbox label{display:inline;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:400;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.has-feedback .form-control-feedback{position:absolute;top:25px;right:0;display:block;width:34px;height:34px;line-height:34px;text-align:center}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.form-control-static{margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{float:none;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}.form-horizontal .form-control-static{padding-top:7px}@media (min-width:768px){.form-horizontal .control-label{text-align:right}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:15px}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.428571429;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#428bca;font-weight:400;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%;padding-left:0;padding-right:0}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.428571429;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#428bca}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:4px;border-top-right-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}[data-toggle=buttons]>.btn>input[type=radio],[data-toggle=buttons]>.btn>input[type=checkbox]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-left:0;padding-right:0}.input-group .form-control{float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.428571429;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:15px;font-size:18px;line-height:20px;height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);margin-top:8px;margin-bottom:8px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{float:none;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#e7e7e7;color:#555}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#999}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .navbar-nav>li>a{color:#999}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#080808;color:#fff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.428571429;text-decoration:none;color:#428bca;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;background-color:#fff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:gray}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;color:#fff;line-height:1;vertical-align:baseline;white-space:nowrap;text-align:center;background-color:#999;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.container .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img,.thumbnail a>img{display:block;max-width:100%;height:auto;margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}a.list-group-item.active .list-group-item-heading,a.list-group-item.active:hover .list-group-item-heading,a.list-group-item.active:focus .list-group-item-heading{color:inherit}a.list-group-item.active .list-group-item-text,a.list-group-item.active:hover .list-group-item-text,a.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group .list-group-item:first-child{border-top:0}.panel>.list-group .list-group-item:last-child{border-bottom:0}.panel>.list-group:first-child .list-group-item:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.panel>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>tfoot>tr:first-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tfoot>tr:first-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:first-child>td{border-top:0}.panel>.table-bordered>thead>tr:last-child>th,.panel>.table-responsive>.table-bordered>thead>tr:last-child>th,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th,.panel>.table-bordered>thead>tr:last-child>td,.panel>.table-responsive>.table-bordered>thead>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px;overflow:hidden}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#faebcc}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#ebccd1}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ebccd1}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:auto;overflow-y:scroll;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5;min-height:16.428571429px}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.428571429}.modal-body{position:relative;padding:20px}.modal-footer{margin-top:15px;padding:19px 20px 20px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;right:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);white-space:normal}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,.25);bottom:-11px}.popover.top .arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,.25)}.popover.right .arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.popover.bottom .arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25);top:-11px}.popover.bottom .arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left .arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:.5;filter:alpha(opacity=50);font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-control.left{background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.5) 0),color-stop(rgba(0,0,0,.0001) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.0001) 0),color-stop(rgba(0,0,0,.5) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #fff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#fff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicons-chevron-left,.carousel-control .glyphicons-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,tr.visible-xs,th.visible-xs,td.visible-xs{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}.visible-sm,tr.visible-sm,th.visible-sm,td.visible-sm{display:none!important}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}.visible-md,tr.visible-md,th.visible-md,td.visible-md{display:none!important}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}.visible-lg,tr.visible-lg,th.visible-lg,td.visible-lg{display:none!important}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (max-width:767px){.hidden-xs,tr.hidden-xs,th.hidden-xs,td.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm,tr.hidden-sm,th.hidden-sm,td.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md,tr.hidden-md,th.hidden-md,td.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg,tr.hidden-lg,th.hidden-lg,td.hidden-lg{display:none!important}}.visible-print,tr.visible-print,th.visible-print,td.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}@media print{.hidden-print,tr.hidden-print,th.hidden-print,td.hidden-print{display:none!important}}
\ No newline at end of file
diff --git a/app/gui/html/vendor/bootstrap/fonts/glyphicons-halflings-regular.eot b/app/gui/html/vendor/bootstrap/fonts/glyphicons-halflings-regular.eot
new file mode 100644
index 0000000..423bd5d
Binary files /dev/null and b/app/gui/html/vendor/bootstrap/fonts/glyphicons-halflings-regular.eot differ
diff --git a/app/gui/html/vendor/bootstrap/fonts/glyphicons-halflings-regular.svg b/app/gui/html/vendor/bootstrap/fonts/glyphicons-halflings-regular.svg
new file mode 100644
index 0000000..4469488
--- /dev/null
+++ b/app/gui/html/vendor/bootstrap/fonts/glyphicons-halflings-regular.svg
@@ -0,0 +1,229 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
+<font-face units-per-em="1200" ascent="960" descent="-240" />
+<missing-glyph horiz-adv-x="500" />
+<glyph />
+<glyph />
+<glyph unicode="&#xd;" />
+<glyph unicode=" " />
+<glyph unicode="*" d="M100 500v200h259l-183 183l141 141l183 -183v259h200v-259l183 183l141 -141l-183 -183h259v-200h-259l183 -183l-141 -141l-183 183v-259h-200v259l-183 -183l-141 141l183 183h-259z" />
+<glyph unicode="+" d="M0 400v300h400v400h300v-400h400v-300h-400v-400h-300v400h-400z" />
+<glyph unicode="&#xa0;" />
+<glyph unicode="&#x2000;" horiz-adv-x="652" />
+<glyph unicode="&#x2001;" horiz-adv-x="1304" />
+<glyph unicode="&#x2002;" horiz-adv-x="652" />
+<glyph unicode="&#x2003;" horiz-adv-x="1304" />
+<glyph unicode="&#x2004;" horiz-adv-x="434" />
+<glyph unicode="&#x2005;" horiz-adv-x="326" />
+<glyph unicode="&#x2006;" horiz-adv-x="217" />
+<glyph unicode="&#x2007;" horiz-adv-x="217" />
+<glyph unicode="&#x2008;" horiz-adv-x="163" />
+<glyph unicode="&#x2009;" horiz-adv-x="260" />
+<glyph unicode="&#x200a;" horiz-adv-x="72" />
+<glyph unicode="&#x202f;" horiz-adv-x="260" />
+<glyph unicode="&#x205f;" horiz-adv-x="326" />
+<glyph unicode="&#x20ac;" d="M100 500l100 100h113q0 47 5 100h-218l100 100h135q37 167 112 257q117 141 297 141q242 0 354 -189q60 -103 66 -209h-181q0 55 -25.5 99t-63.5 68t-75 36.5t-67 12.5q-24 0 -52.5 -10t-62.5 -32t-65.5 -67t-50.5 -107h379l-100 -100h-300q-6 -46 -6 -100h406l-100 -100 h-300q9 -74 33 -132t52.5 -91t62 -54.5t59 -29t46.5 -7.5q29 0 66 13t75 37t63.5 67.5t25.5 96.5h174q-31 -172 -128 -278q-107 -117 -274 -117q-205 0 -324 158q-36 46 -69 131.5t-45 205.5h-217z" />
+<glyph unicode="&#x2212;" d="M200 400h900v300h-900v-300z" />
+<glyph unicode="&#x2601;" d="M-14 494q0 -80 56.5 -137t135.5 -57h750q120 0 205 86t85 208q0 120 -85 206.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5z" />
+<glyph unicode="&#x2709;" d="M0 100l400 400l200 -200l200 200l400 -400h-1200zM0 300v600l300 -300zM0 1100l600 -603l600 603h-1200zM900 600l300 300v-600z" />
+<glyph unicode="&#x270f;" d="M-13 -13l333 112l-223 223zM187 403l214 -214l614 614l-214 214zM887 1103l214 -214l99 92q13 13 13 32.5t-13 33.5l-153 153q-15 13 -33 13t-33 -13z" />
+<glyph unicode="&#xe000;" horiz-adv-x="500" d="M0 0z" />
+<glyph unicode="&#xe001;" d="M0 1200h1200l-500 -550v-550h300v-100h-800v100h300v550z" />
+<glyph unicode="&#xe002;" d="M14 84q18 -55 86 -75.5t147 5.5q65 21 109 69t44 90v606l600 155v-521q-64 16 -138 -7q-79 -26 -122.5 -83t-25.5 -111q17 -55 85.5 -75.5t147.5 4.5q70 23 111.5 63.5t41.5 95.5v881q0 10 -7 15.5t-17 2.5l-752 -193q-10 -3 -17 -12.5t-7 -19.5v-689q-64 17 -138 -7 q-79 -25 -122.5 -82t-25.5 -112z" />
+<glyph unicode="&#xe003;" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233z" />
+<glyph unicode="&#xe005;" d="M100 784q0 64 28 123t73 100.5t104.5 64t119 20.5t120 -38.5t104.5 -104.5q48 69 109.5 105t121.5 38t118.5 -20.5t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-149.5 152.5t-126.5 127.5 t-94 124.5t-33.5 117.5z" />
+<glyph unicode="&#xe006;" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1z" />
+<glyph unicode="&#xe007;" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1zM237 700l196 -142l-73 -226l192 140l195 -141l-74 229l193 140h-235l-77 211l-78 -211h-239z" />
+<glyph unicode="&#xe008;" d="M0 0v143l400 257v100q-37 0 -68.5 74.5t-31.5 125.5v200q0 124 88 212t212 88t212 -88t88 -212v-200q0 -51 -31.5 -125.5t-68.5 -74.5v-100l400 -257v-143h-1200z" />
+<glyph unicode="&#xe009;" d="M0 0v1100h1200v-1100h-1200zM100 100h100v100h-100v-100zM100 300h100v100h-100v-100zM100 500h100v100h-100v-100zM100 700h100v100h-100v-100zM100 900h100v100h-100v-100zM300 100h600v400h-600v-400zM300 600h600v400h-600v-400zM1000 100h100v100h-100v-100z M1000 300h100v100h-100v-100zM1000 500h100v100h-100v-100zM1000 700h100v100h-100v-100zM1000 900h100v100h-100v-100z" />
+<glyph unicode="&#xe010;" d="M0 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM0 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5zM600 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM600 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe011;" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 450v200q0 21 14.5 35.5t35.5 14.5h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe012;" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v200q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5 t-14.5 -35.5v-200zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe013;" d="M29 454l419 -420l818 820l-212 212l-607 -607l-206 207z" />
+<glyph unicode="&#xe014;" d="M106 318l282 282l-282 282l212 212l282 -282l282 282l212 -212l-282 -282l282 -282l-212 -212l-282 282l-282 -282z" />
+<glyph unicode="&#xe015;" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233zM300 600v200h100v100h200v-100h100v-200h-100v-100h-200v100h-100z" />
+<glyph unicode="&#xe016;" d="M23 694q0 200 142 342t342 142t342 -142t142 -342q0 -141 -78 -262l300 -299q7 -7 7 -18t-7 -18l-109 -109q-8 -8 -18 -8t-18 8l-300 299q-120 -77 -261 -77q-200 0 -342 142t-142 342zM176 694q0 -136 97 -233t234 -97t233.5 97t96.5 233t-96.5 233t-233.5 97t-234 -97 t-97 -233zM300 601h400v200h-400v-200z" />
+<glyph unicode="&#xe017;" d="M23 600q0 183 105 331t272 210v-166q-103 -55 -165 -155t-62 -220q0 -177 125 -302t302 -125t302 125t125 302q0 120 -62 220t-165 155v166q167 -62 272 -210t105 -331q0 -118 -45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5 zM500 750q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v400q0 21 -14.5 35.5t-35.5 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-400z" />
+<glyph unicode="&#xe018;" d="M100 1h200v300h-200v-300zM400 1v500h200v-500h-200zM700 1v800h200v-800h-200zM1000 1v1200h200v-1200h-200z" />
+<glyph unicode="&#xe019;" d="M26 601q0 -33 6 -74l151 -38l2 -6q14 -49 38 -93l3 -5l-80 -134q45 -59 105 -105l133 81l5 -3q45 -26 94 -39l5 -2l38 -151q40 -5 74 -5q27 0 74 5l38 151l6 2q46 13 93 39l5 3l134 -81q56 44 104 105l-80 134l3 5q24 44 39 93l1 6l152 38q5 40 5 74q0 28 -5 73l-152 38 l-1 6q-16 51 -39 93l-3 5l80 134q-44 58 -104 105l-134 -81l-5 3q-45 25 -93 39l-6 1l-38 152q-40 5 -74 5q-27 0 -74 -5l-38 -152l-5 -1q-50 -14 -94 -39l-5 -3l-133 81q-59 -47 -105 -105l80 -134l-3 -5q-25 -47 -38 -93l-2 -6l-151 -38q-6 -48 -6 -73zM385 601 q0 88 63 151t152 63t152 -63t63 -151q0 -89 -63 -152t-152 -63t-152 63t-63 152z" />
+<glyph unicode="&#xe020;" d="M100 1025v50q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-50q0 -11 -7 -18t-18 -7h-1050q-11 0 -18 7t-7 18zM200 100v800h900v-800q0 -41 -29.5 -71t-70.5 -30h-700q-41 0 -70.5 30 t-29.5 71zM300 100h100v700h-100v-700zM500 100h100v700h-100v-700zM500 1100h300v100h-300v-100zM700 100h100v700h-100v-700zM900 100h100v700h-100v-700z" />
+<glyph unicode="&#xe021;" d="M1 601l656 644l644 -644h-200v-600h-300v400h-300v-400h-300v600h-200z" />
+<glyph unicode="&#xe022;" d="M100 25v1150q0 11 7 18t18 7h475v-500h400v-675q0 -11 -7 -18t-18 -7h-850q-11 0 -18 7t-7 18zM700 800v300l300 -300h-300z" />
+<glyph unicode="&#xe023;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 500v400h100 v-300h200v-100h-300z" />
+<glyph unicode="&#xe024;" d="M-100 0l431 1200h209l-21 -300h162l-20 300h208l431 -1200h-538l-41 400h-242l-40 -400h-539zM488 500h224l-27 300h-170z" />
+<glyph unicode="&#xe025;" d="M0 0v400h490l-290 300h200v500h300v-500h200l-290 -300h490v-400h-1100zM813 200h175v100h-175v-100z" />
+<glyph unicode="&#xe026;" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM188 600q0 -170 121 -291t291 -121t291 121t121 291t-121 291t-291 121 t-291 -121t-121 -291zM350 600h150v300h200v-300h150l-250 -300z" />
+<glyph unicode="&#xe027;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM350 600l250 300 l250 -300h-150v-300h-200v300h-150z" />
+<glyph unicode="&#xe028;" d="M0 25v475l200 700h800q199 -700 200 -700v-475q0 -11 -7 -18t-18 -7h-1150q-11 0 -18 7t-7 18zM200 500h200l50 -200h300l50 200h200l-97 500h-606z" />
+<glyph unicode="&#xe029;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 397v401 l297 -200z" />
+<glyph unicode="&#xe030;" d="M23 600q0 -118 45.5 -224.5t123 -184t184 -123t224.5 -45.5t224.5 45.5t184 123t123 184t45.5 224.5h-150q0 -177 -125 -302t-302 -125t-302 125t-125 302t125 302t302 125q136 0 246 -81l-146 -146h400v400l-145 -145q-157 122 -355 122q-118 0 -224.5 -45.5t-184 -123 t-123 -184t-45.5 -224.5z" />
+<glyph unicode="&#xe031;" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5q198 0 355 -122l145 145v-400h-400l147 147q-112 80 -247 80q-177 0 -302 -125t-125 -302h-150zM100 0v400h400l-147 -147q112 -80 247 -80q177 0 302 125t125 302h150q0 -118 -45.5 -224.5t-123 -184t-184 -123 t-224.5 -45.5q-198 0 -355 122z" />
+<glyph unicode="&#xe032;" d="M100 0h1100v1200h-1100v-1200zM200 100v900h900v-900h-900zM300 200v100h100v-100h-100zM300 400v100h100v-100h-100zM300 600v100h100v-100h-100zM300 800v100h100v-100h-100zM500 200h500v100h-500v-100zM500 400v100h500v-100h-500zM500 600v100h500v-100h-500z M500 800v100h500v-100h-500z" />
+<glyph unicode="&#xe033;" d="M0 100v600q0 41 29.5 70.5t70.5 29.5h100v200q0 82 59 141t141 59h300q82 0 141 -59t59 -141v-200h100q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-900q-41 0 -70.5 29.5t-29.5 70.5zM400 800h300v150q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-150z" />
+<glyph unicode="&#xe034;" d="M100 0v1100h100v-1100h-100zM300 400q60 60 127.5 84t127.5 17.5t122 -23t119 -30t110 -11t103 42t91 120.5v500q-40 -81 -101.5 -115.5t-127.5 -29.5t-138 25t-139.5 40t-125.5 25t-103 -29.5t-65 -115.5v-500z" />
+<glyph unicode="&#xe035;" d="M0 275q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 127 70.5 231.5t184.5 161.5t245 57t245 -57t184.5 -161.5t70.5 -231.5v-300q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 116 -49.5 227t-131 192.5t-192.5 131t-227 49.5t-227 -49.5t-192.5 -131t-131 -192.5 t-49.5 -227v-300zM200 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14zM800 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14z" />
+<glyph unicode="&#xe036;" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM688 459l141 141l-141 141l71 71l141 -141l141 141l71 -71l-141 -141l141 -141l-71 -71l-141 141l-141 -141z" />
+<glyph unicode="&#xe037;" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM700 857l69 53q111 -135 111 -310q0 -169 -106 -302l-67 54q86 110 86 248q0 146 -93 257z" />
+<glyph unicode="&#xe038;" d="M0 401v400h300l300 200v-800l-300 200h-300zM702 858l69 53q111 -135 111 -310q0 -170 -106 -303l-67 55q86 110 86 248q0 145 -93 257zM889 951l7 -8q123 -151 123 -344q0 -189 -119 -339l-7 -8l81 -66l6 8q142 178 142 405q0 230 -144 408l-6 8z" />
+<glyph unicode="&#xe039;" d="M0 0h500v500h-200v100h-100v-100h-200v-500zM0 600h100v100h400v100h100v100h-100v300h-500v-600zM100 100v300h300v-300h-300zM100 800v300h300v-300h-300zM200 200v100h100v-100h-100zM200 900h100v100h-100v-100zM500 500v100h300v-300h200v-100h-100v-100h-200v100 h-100v100h100v200h-200zM600 0v100h100v-100h-100zM600 1000h100v-300h200v-300h300v200h-200v100h200v500h-600v-200zM800 800v300h300v-300h-300zM900 0v100h300v-100h-300zM900 900v100h100v-100h-100zM1100 200v100h100v-100h-100z" />
+<glyph unicode="&#xe040;" d="M0 200h100v1000h-100v-1000zM100 0v100h300v-100h-300zM200 200v1000h100v-1000h-100zM500 0v91h100v-91h-100zM500 200v1000h200v-1000h-200zM700 0v91h100v-91h-100zM800 200v1000h100v-1000h-100zM900 0v91h200v-91h-200zM1000 200v1000h200v-1000h-200z" />
+<glyph unicode="&#xe041;" d="M1 700v475q0 10 7.5 17.5t17.5 7.5h474l700 -700l-500 -500zM148 953q0 -42 29 -71q30 -30 71.5 -30t71.5 30q29 29 29 71t-29 71q-30 30 -71.5 30t-71.5 -30q-29 -29 -29 -71z" />
+<glyph unicode="&#xe042;" d="M2 700v475q0 11 7 18t18 7h474l700 -700l-500 -500zM148 953q0 -42 30 -71q29 -30 71 -30t71 30q30 29 30 71t-30 71q-29 30 -71 30t-71 -30q-30 -29 -30 -71zM701 1200h100l700 -700l-500 -500l-50 50l450 450z" />
+<glyph unicode="&#xe043;" d="M100 0v1025l175 175h925v-1000l-100 -100v1000h-750l-100 -100h750v-1000h-900z" />
+<glyph unicode="&#xe044;" d="M200 0l450 444l450 -443v1150q0 20 -14.5 35t-35.5 15h-800q-21 0 -35.5 -15t-14.5 -35v-1151z" />
+<glyph unicode="&#xe045;" d="M0 100v700h200l100 -200h600l100 200h200v-700h-200v200h-800v-200h-200zM253 829l40 -124h592l62 124l-94 346q-2 11 -10 18t-18 7h-450q-10 0 -18 -7t-10 -18zM281 24l38 152q2 10 11.5 17t19.5 7h500q10 0 19.5 -7t11.5 -17l38 -152q2 -10 -3.5 -17t-15.5 -7h-600 q-10 0 -15.5 7t-3.5 17z" />
+<glyph unicode="&#xe046;" d="M0 200q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-150q-4 8 -11.5 21.5t-33 48t-53 61t-69 48t-83.5 21.5h-200q-41 0 -82 -20.5t-70 -50t-52 -59t-34 -50.5l-12 -20h-150q-41 0 -70.5 -29.5t-29.5 -70.5v-600z M356 500q0 100 72 172t172 72t172 -72t72 -172t-72 -172t-172 -72t-172 72t-72 172zM494 500q0 -44 31 -75t75 -31t75 31t31 75t-31 75t-75 31t-75 -31t-31 -75zM900 700v100h100v-100h-100z" />
+<glyph unicode="&#xe047;" d="M53 0h365v66q-41 0 -72 11t-49 38t1 71l92 234h391l82 -222q16 -45 -5.5 -88.5t-74.5 -43.5v-66h417v66q-34 1 -74 43q-18 19 -33 42t-21 37l-6 13l-385 998h-93l-399 -1006q-24 -48 -52 -75q-12 -12 -33 -25t-36 -20l-15 -7v-66zM416 521l178 457l46 -140l116 -317h-340 z" />
+<glyph unicode="&#xe048;" d="M100 0v89q41 7 70.5 32.5t29.5 65.5v827q0 28 -1 39.5t-5.5 26t-15.5 21t-29 14t-49 14.5v70h471q120 0 213 -88t93 -228q0 -55 -11.5 -101.5t-28 -74t-33.5 -47.5t-28 -28l-12 -7q8 -3 21.5 -9t48 -31.5t60.5 -58t47.5 -91.5t21.5 -129q0 -84 -59 -156.5t-142 -111 t-162 -38.5h-500zM400 200h161q89 0 153 48.5t64 132.5q0 90 -62.5 154.5t-156.5 64.5h-159v-400zM400 700h139q76 0 130 61.5t54 138.5q0 82 -84 130.5t-239 48.5v-379z" />
+<glyph unicode="&#xe049;" d="M200 0v57q77 7 134.5 40.5t65.5 80.5l173 849q10 56 -10 74t-91 37q-6 1 -10.5 2.5t-9.5 2.5v57h425l2 -57q-33 -8 -62 -25.5t-46 -37t-29.5 -38t-17.5 -30.5l-5 -12l-128 -825q-10 -52 14 -82t95 -36v-57h-500z" />
+<glyph unicode="&#xe050;" d="M-75 200h75v800h-75l125 167l125 -167h-75v-800h75l-125 -167zM300 900v300h150h700h150v-300h-50q0 29 -8 48.5t-18.5 30t-33.5 15t-39.5 5.5t-50.5 1h-200v-850l100 -50v-100h-400v100l100 50v850h-200q-34 0 -50.5 -1t-40 -5.5t-33.5 -15t-18.5 -30t-8.5 -48.5h-49z " />
+<glyph unicode="&#xe051;" d="M33 51l167 125v-75h800v75l167 -125l-167 -125v75h-800v-75zM100 901v300h150h700h150v-300h-50q0 29 -8 48.5t-18 30t-33.5 15t-40 5.5t-50.5 1h-200v-650l100 -50v-100h-400v100l100 50v650h-200q-34 0 -50.5 -1t-39.5 -5.5t-33.5 -15t-18.5 -30t-8 -48.5h-50z" />
+<glyph unicode="&#xe052;" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 350q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM0 650q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1000q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 950q0 -20 14.5 -35t35.5 -15h600q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-600q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
+<glyph unicode="&#xe053;" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 650q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM200 350q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM200 950q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
+<glyph unicode="&#xe054;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1000q-21 0 -35.5 15 t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-600 q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe055;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100 q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe056;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM300 50v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800 q-21 0 -35.5 15t-14.5 35zM300 650v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 950v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15 h-800q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe057;" d="M-101 500v100h201v75l166 -125l-166 -125v75h-201zM300 0h100v1100h-100v-1100zM500 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35 v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 650q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100 q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100z" />
+<glyph unicode="&#xe058;" d="M1 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 650 q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM801 0v1100h100v-1100 h-100zM934 550l167 -125v75h200v100h-200v75z" />
+<glyph unicode="&#xe059;" d="M0 275v650q0 31 22 53t53 22h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53zM900 600l300 300v-600z" />
+<glyph unicode="&#xe060;" d="M0 44v1012q0 18 13 31t31 13h1112q19 0 31.5 -13t12.5 -31v-1012q0 -18 -12.5 -31t-31.5 -13h-1112q-18 0 -31 13t-13 31zM100 263l247 182l298 -131l-74 156l293 318l236 -288v500h-1000v-737zM208 750q0 56 39 95t95 39t95 -39t39 -95t-39 -95t-95 -39t-95 39t-39 95z " />
+<glyph unicode="&#xe062;" d="M148 745q0 124 60.5 231.5t165 172t226.5 64.5q123 0 227 -63t164.5 -169.5t60.5 -229.5t-73 -272q-73 -114 -166.5 -237t-150.5 -189l-57 -66q-10 9 -27 26t-66.5 70.5t-96 109t-104 135.5t-100.5 155q-63 139 -63 262zM342 772q0 -107 75.5 -182.5t181.5 -75.5 q107 0 182.5 75.5t75.5 182.5t-75.5 182t-182.5 75t-182 -75.5t-75 -181.5z" />
+<glyph unicode="&#xe063;" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM173 600q0 -177 125.5 -302t301.5 -125v854q-176 0 -301.5 -125 t-125.5 -302z" />
+<glyph unicode="&#xe064;" d="M117 406q0 94 34 186t88.5 172.5t112 159t115 177t87.5 194.5q21 -71 57.5 -142.5t76 -130.5t83 -118.5t82 -117t70 -116t50 -125.5t18.5 -136q0 -89 -39 -165.5t-102 -126.5t-140 -79.5t-156 -33.5q-114 6 -211.5 53t-161.5 138.5t-64 210.5zM243 414q14 -82 59.5 -136 t136.5 -80l16 98q-7 6 -18 17t-34 48t-33 77q-15 73 -14 143.5t10 122.5l9 51q-92 -110 -119.5 -185t-12.5 -156z" />
+<glyph unicode="&#xe065;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5q366 -6 397 -14l-186 -186h-311q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v125l200 200v-225q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM436 341l161 50l412 412l-114 113l-405 -405zM995 1015l113 -113l113 113l-21 85l-92 28z" />
+<glyph unicode="&#xe066;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h261l2 -80q-133 -32 -218 -120h-145q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-53q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5 zM423 524q30 38 81.5 64t103 35.5t99 14t77.5 3.5l29 -1v-209l360 324l-359 318v-216q-7 0 -19 -1t-48 -8t-69.5 -18.5t-76.5 -37t-76.5 -59t-62 -88t-39.5 -121.5z" />
+<glyph unicode="&#xe067;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-169q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM342 632l283 -284l566 567l-136 137l-430 -431l-147 147z" />
+<glyph unicode="&#xe068;" d="M0 603l300 296v-198h200v200h-200l300 300l295 -300h-195v-200h200v198l300 -296l-300 -300v198h-200v-200h195l-295 -300l-300 300h200v200h-200v-198z" />
+<glyph unicode="&#xe069;" d="M200 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-1100l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe070;" d="M0 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-487l500 487v-1100l-500 488v-488l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe071;" d="M136 550l564 550v-487l500 487v-1100l-500 488v-488z" />
+<glyph unicode="&#xe072;" d="M200 0l900 550l-900 550v-1100z" />
+<glyph unicode="&#xe073;" d="M200 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5t-14.5 -35.5v-800zM600 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
+<glyph unicode="&#xe074;" d="M200 150q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v800q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
+<glyph unicode="&#xe075;" d="M0 0v1100l500 -487v487l564 -550l-564 -550v488z" />
+<glyph unicode="&#xe076;" d="M0 0v1100l500 -487v487l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-500 -488v488z" />
+<glyph unicode="&#xe077;" d="M300 0v1100l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438z" />
+<glyph unicode="&#xe078;" d="M100 250v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5zM100 500h1100l-550 564z" />
+<glyph unicode="&#xe079;" d="M185 599l592 -592l240 240l-353 353l353 353l-240 240z" />
+<glyph unicode="&#xe080;" d="M272 194l353 353l-353 353l241 240l572 -571l21 -22l-1 -1v-1l-592 -591z" />
+<glyph unicode="&#xe081;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM300 500h200v-200h200v200h200v200h-200v200h-200v-200h-200v-200z" />
+<glyph unicode="&#xe082;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM300 500h600v200h-600v-200z" />
+<glyph unicode="&#xe083;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM246 459l213 -213l141 142l141 -142l213 213l-142 141l142 141l-213 212l-141 -141l-141 142l-212 -213l141 -141z" />
+<glyph unicode="&#xe084;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM270 551l276 -277l411 411l-175 174l-236 -236l-102 102z" />
+<glyph unicode="&#xe085;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM363 700h144q4 0 11.5 -1t11 -1t6.5 3t3 9t1 11t3.5 8.5t3.5 6t5.5 4t6.5 2.5t9 1.5t9 0.5h11.5h12.5q19 0 30 -10t11 -26 q0 -22 -4 -28t-27 -22q-5 -1 -12.5 -3t-27 -13.5t-34 -27t-26.5 -46t-11 -68.5h200q5 3 14 8t31.5 25.5t39.5 45.5t31 69t14 94q0 51 -17.5 89t-42 58t-58.5 32t-58.5 15t-51.5 3q-105 0 -172 -56t-67 -183zM500 300h200v100h-200v-100z" />
+<glyph unicode="&#xe086;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM400 300h400v100h-100v300h-300v-100h100v-200h-100v-100zM500 800h200v100h-200v-100z" />
+<glyph unicode="&#xe087;" d="M0 500v200h194q15 60 36 104.5t55.5 86t88 69t126.5 40.5v200h200v-200q54 -20 113 -60t112.5 -105.5t71.5 -134.5h203v-200h-203q-25 -102 -116.5 -186t-180.5 -117v-197h-200v197q-140 27 -208 102.5t-98 200.5h-194zM290 500q24 -73 79.5 -127.5t130.5 -78.5v206h200 v-206q149 48 201 206h-201v200h200q-25 74 -76 127.5t-124 76.5v-204h-200v203q-75 -24 -130 -77.5t-79 -125.5h209v-200h-210z" />
+<glyph unicode="&#xe088;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM356 465l135 135 l-135 135l109 109l135 -135l135 135l109 -109l-135 -135l135 -135l-109 -109l-135 135l-135 -135z" />
+<glyph unicode="&#xe089;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM322 537l141 141 l87 -87l204 205l142 -142l-346 -345z" />
+<glyph unicode="&#xe090;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -115 62 -215l568 567q-100 62 -216 62q-171 0 -292.5 -121.5t-121.5 -292.5zM391 245q97 -59 209 -59q171 0 292.5 121.5t121.5 292.5 q0 112 -59 209z" />
+<glyph unicode="&#xe091;" d="M0 547l600 453v-300h600v-300h-600v-301z" />
+<glyph unicode="&#xe092;" d="M0 400v300h600v300l600 -453l-600 -448v301h-600z" />
+<glyph unicode="&#xe093;" d="M204 600l450 600l444 -600h-298v-600h-300v600h-296z" />
+<glyph unicode="&#xe094;" d="M104 600h296v600h300v-600h298l-449 -600z" />
+<glyph unicode="&#xe095;" d="M0 200q6 132 41 238.5t103.5 193t184 138t271.5 59.5v271l600 -453l-600 -448v301q-95 -2 -183 -20t-170 -52t-147 -92.5t-100 -135.5z" />
+<glyph unicode="&#xe096;" d="M0 0v400l129 -129l294 294l142 -142l-294 -294l129 -129h-400zM635 777l142 -142l294 294l129 -129v400h-400l129 -129z" />
+<glyph unicode="&#xe097;" d="M34 176l295 295l-129 129h400v-400l-129 130l-295 -295zM600 600v400l129 -129l295 295l142 -141l-295 -295l129 -130h-400z" />
+<glyph unicode="&#xe101;" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5t224.5 -45.5t184 -123t123 -184t45.5 -224.5t-45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5zM456 851l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5 t21.5 34.5l58 302q4 20 -8 34.5t-33 14.5h-207q-20 0 -32 -14.5t-8 -34.5zM500 300h200v100h-200v-100z" />
+<glyph unicode="&#xe102;" d="M0 800h100v-200h400v300h200v-300h400v200h100v100h-111v6t-1 15t-3 18l-34 172q-11 39 -41.5 63t-69.5 24q-32 0 -61 -17l-239 -144q-22 -13 -40 -35q-19 24 -40 36l-238 144q-33 18 -62 18q-39 0 -69.5 -23t-40.5 -61l-35 -177q-2 -8 -3 -18t-1 -15v-6h-111v-100z M100 0h400v400h-400v-400zM200 900q-3 0 14 48t35 96l18 47l214 -191h-281zM700 0v400h400v-400h-400zM731 900l202 197q5 -12 12 -32.5t23 -64t25 -72t7 -28.5h-269z" />
+<glyph unicode="&#xe103;" d="M0 -22v143l216 193q-9 53 -13 83t-5.5 94t9 113t38.5 114t74 124q47 60 99.5 102.5t103 68t127.5 48t145.5 37.5t184.5 43.5t220 58.5q0 -189 -22 -343t-59 -258t-89 -181.5t-108.5 -120t-122 -68t-125.5 -30t-121.5 -1.5t-107.5 12.5t-87.5 17t-56.5 7.5l-99 -55z M238.5 300.5q19.5 -6.5 86.5 76.5q55 66 367 234q70 38 118.5 69.5t102 79t99 111.5t86.5 148q22 50 24 60t-6 19q-7 5 -17 5t-26.5 -14.5t-33.5 -39.5q-35 -51 -113.5 -108.5t-139.5 -89.5l-61 -32q-369 -197 -458 -401q-48 -111 -28.5 -117.5z" />
+<glyph unicode="&#xe104;" d="M111 408q0 -33 5 -63q9 -56 44 -119.5t105 -108.5q31 -21 64 -16t62 23.5t57 49.5t48 61.5t35 60.5q32 66 39 184.5t-13 157.5q79 -80 122 -164t26 -184q-5 -33 -20.5 -69.5t-37.5 -80.5q-10 -19 -14.5 -29t-12 -26t-9 -23.5t-3 -19t2.5 -15.5t11 -9.5t19.5 -5t30.5 2.5 t42 8q57 20 91 34t87.5 44.5t87 64t65.5 88.5t47 122q38 172 -44.5 341.5t-246.5 278.5q22 -44 43 -129q39 -159 -32 -154q-15 2 -33 9q-79 33 -120.5 100t-44 175.5t48.5 257.5q-13 -8 -34 -23.5t-72.5 -66.5t-88.5 -105.5t-60 -138t-8 -166.5q2 -12 8 -41.5t8 -43t6 -39.5 t3.5 -39.5t-1 -33.5t-6 -31.5t-13.5 -24t-21 -20.5t-31 -12q-38 -10 -67 13t-40.5 61.5t-15 81.5t10.5 75q-52 -46 -83.5 -101t-39 -107t-7.5 -85z" />
+<glyph unicode="&#xe105;" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5t145.5 -23.5t132.5 -59t116.5 -83.5t97 -90t74.5 -85.5t49 -63.5t20 -30l26 -40l-26 -40q-6 -10 -20 -30t-49 -63.5t-74.5 -85.5t-97 -90t-116.5 -83.5t-132.5 -59t-145.5 -23.5 t-145.5 23.5t-132.5 59t-116.5 83.5t-97 90t-74.5 85.5t-49 63.5t-20 30zM120 600q7 -10 40.5 -58t56 -78.5t68 -77.5t87.5 -75t103 -49.5t125 -21.5t123.5 20t100.5 45.5t85.5 71.5t66.5 75.5t58 81.5t47 66q-1 1 -28.5 37.5t-42 55t-43.5 53t-57.5 63.5t-58.5 54 q49 -74 49 -163q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l105 105q-37 24 -75 72t-57 84l-20 36z" />
+<glyph unicode="&#xe106;" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5q61 0 121 -17l37 142h148l-314 -1200h-148l37 143q-82 21 -165 71.5t-140 102t-109.5 112t-72 88.5t-29.5 43zM120 600q210 -282 393 -336l37 141q-107 18 -178.5 101.5t-71.5 193.5 q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l47 47l23 87q-30 28 -59 69t-44 68l-14 26zM780 161l38 145q22 15 44.5 34t46 44t40.5 44t41 50.5t33.5 43.5t33 44t24.5 34q-97 127 -140 175l39 146q67 -54 131.5 -125.5t87.5 -103.5t36 -52l26 -40l-26 -40 q-7 -12 -25.5 -38t-63.5 -79.5t-95.5 -102.5t-124 -100t-146.5 -79z" />
+<glyph unicode="&#xe107;" d="M-97.5 34q13.5 -34 50.5 -34h1294q37 0 50.5 35.5t-7.5 67.5l-642 1056q-20 33 -48 36t-48 -29l-642 -1066q-21 -32 -7.5 -66zM155 200l445 723l445 -723h-345v100h-200v-100h-345zM500 600l100 -300l100 300v100h-200v-100z" />
+<glyph unicode="&#xe108;" d="M100 262v41q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44t106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -91 100 -113v-64q0 -21 -13 -29t-32 1l-94 78h-222l-94 -78q-19 -9 -32 -1t-13 29v64 q0 22 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5z" />
+<glyph unicode="&#xe109;" d="M0 50q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v750h-1100v-750zM0 900h1100v150q0 21 -14.5 35.5t-35.5 14.5h-150v100h-100v-100h-500v100h-100v-100h-150q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 100v100h100v-100h-100zM100 300v100h100v-100h-100z M100 500v100h100v-100h-100zM300 100v100h100v-100h-100zM300 300v100h100v-100h-100zM300 500v100h100v-100h-100zM500 100v100h100v-100h-100zM500 300v100h100v-100h-100zM500 500v100h100v-100h-100zM700 100v100h100v-100h-100zM700 300v100h100v-100h-100zM700 500 v100h100v-100h-100zM900 100v100h100v-100h-100zM900 300v100h100v-100h-100zM900 500v100h100v-100h-100z" />
+<glyph unicode="&#xe110;" d="M0 200v200h259l600 600h241v198l300 -295l-300 -300v197h-159l-600 -600h-341zM0 800h259l122 -122l141 142l-181 180h-341v-200zM678 381l141 142l122 -123h159v198l300 -295l-300 -300v197h-241z" />
+<glyph unicode="&#xe111;" d="M0 400v600q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5z" />
+<glyph unicode="&#xe112;" d="M100 600v200h300v-250q0 -113 6 -145q17 -92 102 -117q39 -11 92 -11q37 0 66.5 5.5t50 15.5t36 24t24 31.5t14 37.5t7 42t2.5 45t0 47v25v250h300v-200q0 -42 -3 -83t-15 -104t-31.5 -116t-58 -109.5t-89 -96.5t-129 -65.5t-174.5 -25.5t-174.5 25.5t-129 65.5t-89 96.5 t-58 109.5t-31.5 116t-15 104t-3 83zM100 900v300h300v-300h-300zM800 900v300h300v-300h-300z" />
+<glyph unicode="&#xe113;" d="M-30 411l227 -227l352 353l353 -353l226 227l-578 579z" />
+<glyph unicode="&#xe114;" d="M70 797l580 -579l578 579l-226 227l-353 -353l-352 353z" />
+<glyph unicode="&#xe115;" d="M-198 700l299 283l300 -283h-203v-400h385l215 -200h-800v600h-196zM402 1000l215 -200h381v-400h-198l299 -283l299 283h-200v600h-796z" />
+<glyph unicode="&#xe116;" d="M18 939q-5 24 10 42q14 19 39 19h896l38 162q5 17 18.5 27.5t30.5 10.5h94q20 0 35 -14.5t15 -35.5t-15 -35.5t-35 -14.5h-54l-201 -961q-2 -4 -6 -10.5t-19 -17.5t-33 -11h-31v-50q0 -20 -14.5 -35t-35.5 -15t-35.5 15t-14.5 35v50h-300v-50q0 -20 -14.5 -35t-35.5 -15 t-35.5 15t-14.5 35v50h-50q-21 0 -35.5 15t-14.5 35q0 21 14.5 35.5t35.5 14.5h535l48 200h-633q-32 0 -54.5 21t-27.5 43z" />
+<glyph unicode="&#xe117;" d="M0 0v800h1200v-800h-1200zM0 900v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-100h-1200z" />
+<glyph unicode="&#xe118;" d="M1 0l300 700h1200l-300 -700h-1200zM1 400v600h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-200h-1000z" />
+<glyph unicode="&#xe119;" d="M302 300h198v600h-198l298 300l298 -300h-198v-600h198l-298 -300z" />
+<glyph unicode="&#xe120;" d="M0 600l300 298v-198h600v198l300 -298l-300 -297v197h-600v-197z" />
+<glyph unicode="&#xe121;" d="M0 100v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM31 400l172 739q5 22 23 41.5t38 19.5h672q19 0 37.5 -22.5t23.5 -45.5l172 -732h-1138zM800 100h100v100h-100v-100z M1000 100h100v100h-100v-100z" />
+<glyph unicode="&#xe122;" d="M-101 600v50q0 24 25 49t50 38l25 13v-250l-11 5.5t-24 14t-30 21.5t-24 27.5t-11 31.5zM99 500v250v5q0 13 0.5 18.5t2.5 13t8 10.5t15 3h200l675 250v-850l-675 200h-38l47 -276q2 -12 -3 -17.5t-11 -6t-21 -0.5h-8h-83q-20 0 -34.5 14t-18.5 35q-56 337 -56 351z M1100 200v850q0 21 14.5 35.5t35.5 14.5q20 0 35 -14.5t15 -35.5v-850q0 -20 -15 -35t-35 -15q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe123;" d="M74 350q0 21 13.5 35.5t33.5 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3 32t29 13h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q20 0 33.5 -14.5t13.5 -35.5q0 -20 -13 -40t-31 -27q-22 -9 -63 -23t-167.5 -37 t-251.5 -23t-245.5 20.5t-178.5 41.5l-58 20q-18 7 -31 27.5t-13 40.5zM497 110q12 -49 40 -79.5t63 -30.5t63 30.5t39 79.5q-48 -6 -102 -6t-103 6z" />
+<glyph unicode="&#xe124;" d="M21 445l233 -45l-78 -224l224 78l45 -233l155 179l155 -179l45 233l224 -78l-78 224l234 45l-180 155l180 156l-234 44l78 225l-224 -78l-45 233l-155 -180l-155 180l-45 -233l-224 78l78 -225l-233 -44l179 -156z" />
+<glyph unicode="&#xe125;" d="M0 200h200v600h-200v-600zM300 275q0 -75 100 -75h61q123 -100 139 -100h250q46 0 83 57l238 344q29 31 29 74v100q0 44 -30.5 84.5t-69.5 40.5h-328q28 118 28 125v150q0 44 -30.5 84.5t-69.5 40.5h-50q-27 0 -51 -20t-38 -48l-96 -198l-145 -196q-20 -26 -20 -63v-400z M400 300v375l150 212l100 213h50v-175l-50 -225h450v-125l-250 -375h-214l-136 100h-100z" />
+<glyph unicode="&#xe126;" d="M0 400v600h200v-600h-200zM300 525v400q0 75 100 75h61q123 100 139 100h250q46 0 83 -57l238 -344q29 -31 29 -74v-100q0 -44 -30.5 -84.5t-69.5 -40.5h-328q28 -118 28 -125v-150q0 -44 -30.5 -84.5t-69.5 -40.5h-50q-27 0 -51 20t-38 48l-96 198l-145 196 q-20 26 -20 63zM400 525l150 -212l100 -213h50v175l-50 225h450v125l-250 375h-214l-136 -100h-100v-375z" />
+<glyph unicode="&#xe127;" d="M8 200v600h200v-600h-200zM308 275v525q0 17 14 35.5t28 28.5l14 9l362 230q14 6 25 6q17 0 29 -12l109 -112q14 -14 14 -34q0 -18 -11 -32l-85 -121h302q85 0 138.5 -38t53.5 -110t-54.5 -111t-138.5 -39h-107l-130 -339q-7 -22 -20.5 -41.5t-28.5 -19.5h-341 q-7 0 -90 81t-83 94zM408 289l100 -89h293l131 339q6 21 19.5 41t28.5 20h203q16 0 25 15t9 36q0 20 -9 34.5t-25 14.5h-457h-6.5h-7.5t-6.5 0.5t-6 1t-5 1.5t-5.5 2.5t-4 4t-4 5.5q-5 12 -5 20q0 14 10 27l147 183l-86 83l-339 -236v-503z" />
+<glyph unicode="&#xe128;" d="M-101 651q0 72 54 110t139 37h302l-85 121q-11 16 -11 32q0 21 14 34l109 113q13 12 29 12q11 0 25 -6l365 -230q7 -4 16.5 -10.5t26 -26t16.5 -36.5v-526q0 -13 -85.5 -93.5t-93.5 -80.5h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-84 0 -139 39t-55 111zM-1 601h222 q15 0 28.5 -20.5t19.5 -40.5l131 -339h293l106 89v502l-342 237l-87 -83l145 -184q10 -11 10 -26q0 -11 -5 -20q-1 -3 -3.5 -5.5l-4 -4t-5 -2.5t-5.5 -1.5t-6.5 -1t-6.5 -0.5h-7.5h-6.5h-476v-100zM999 201v600h200v-600h-200z" />
+<glyph unicode="&#xe129;" d="M97 719l230 -363q4 -6 10.5 -15.5t26 -25t36.5 -15.5h525q13 0 94 83t81 90v342q0 15 -20 28.5t-41 19.5l-339 131v106q0 84 -39 139t-111 55t-110 -53.5t-38 -138.5v-302l-121 84q-15 12 -33.5 11.5t-32.5 -13.5l-112 -110q-22 -22 -6 -53zM172 739l83 86l183 -146 q22 -18 47 -5q3 1 5.5 3.5l4 4t2.5 5t1.5 5.5t1 6.5t0.5 6v7.5v7v456q0 22 25 31t50 -0.5t25 -30.5v-202q0 -16 20 -29.5t41 -19.5l339 -130v-294l-89 -100h-503zM400 0v200h600v-200h-600z" />
+<glyph unicode="&#xe130;" d="M1 585q-15 -31 7 -53l112 -110q13 -13 32 -13.5t34 10.5l121 85l-1 -302q0 -84 38.5 -138t110.5 -54t111 55t39 139v106l339 131q20 6 40.5 19.5t20.5 28.5v342q0 7 -81 90t-94 83h-525q-17 0 -35.5 -14t-28.5 -28l-10 -15zM76 565l237 339h503l89 -100v-294l-340 -130 q-20 -6 -40 -20t-20 -29v-202q0 -22 -25 -31t-50 0t-25 31v456v14.5t-1.5 11.5t-5 12t-9.5 7q-24 13 -46 -5l-184 -146zM305 1104v200h600v-200h-600z" />
+<glyph unicode="&#xe131;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 500h300l-2 -194l402 294l-402 298v-197h-298v-201z" />
+<glyph unicode="&#xe132;" d="M0 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t231.5 47.5q122 0 232.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-218 -217.5t-300 -80t-299.5 80t-217.5 217.5t-80 299.5zM200 600l400 -294v194h302v201h-300v197z" />
+<glyph unicode="&#xe133;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600h200v-300h200v300h200l-300 400z" />
+<glyph unicode="&#xe134;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600l300 -400l300 400h-200v300h-200v-300h-200z" />
+<glyph unicode="&#xe135;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM254 780q-8 -34 5.5 -93t7.5 -87q0 -9 17 -44t16 -60q12 0 23 -5.5 t23 -15t20 -13.5q20 -10 108 -42q22 -8 53 -31.5t59.5 -38.5t57.5 -11q8 -18 -15 -55.5t-20 -57.5q12 -21 22.5 -34.5t28 -27t36.5 -17.5q0 -6 -3 -15.5t-3.5 -14.5t4.5 -17q101 -2 221 111q31 30 47 48t34 49t21 62q-14 9 -37.5 9.5t-35.5 7.5q-14 7 -49 15t-52 19 q-9 0 -39.5 -0.5t-46.5 -1.5t-39 -6.5t-39 -16.5q-50 -35 -66 -12q-4 2 -3.5 25.5t0.5 25.5q-6 13 -26.5 17t-24.5 7q2 22 -2 41t-16.5 28t-38.5 -20q-23 -25 -42 4q-19 28 -8 58q8 16 22 22q6 -1 26 -1.5t33.5 -4.5t19.5 -13q12 -19 32 -37.5t34 -27.5l14 -8q0 3 9.5 39.5 t5.5 57.5q-4 23 14.5 44.5t22.5 31.5q5 14 10 35t8.5 31t15.5 22.5t34 21.5q-6 18 10 37q8 0 23.5 -1.5t24.5 -1.5t20.5 4.5t20.5 15.5q-10 23 -30.5 42.5t-38 30t-49 26.5t-43.5 23q11 41 1 44q31 -13 58.5 -14.5t39.5 3.5l11 4q6 36 -17 53.5t-64 28.5t-56 23 q-19 -3 -37 0q-15 -12 -36.5 -21t-34.5 -12t-44 -8t-39 -6q-15 -3 -46 0t-45 -3q-20 -6 -51.5 -25.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79zM518 915q3 12 16 30.5t16 25.5q10 -10 18.5 -10t14 6t14.5 14.5t16 12.5q0 -18 8 -42.5t16.5 -44 t9.5 -23.5q-6 1 -39 5t-53.5 10t-36.5 16z" />
+<glyph unicode="&#xe136;" d="M0 164.5q0 21.5 15 37.5l600 599q-33 101 6 201.5t135 154.5q164 92 306 -9l-259 -138l145 -232l251 126q13 -175 -151 -267q-123 -70 -253 -23l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5z" />
+<glyph unicode="&#xe137;" horiz-adv-x="1220" d="M0 196v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 596v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5zM0 996v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM600 596h500v100h-500v-100zM800 196h300v100h-300v-100zM900 996h200v100h-200v-100z" />
+<glyph unicode="&#xe138;" d="M100 1100v100h1000v-100h-1000zM150 1000h900l-350 -500v-300l-200 -200v500z" />
+<glyph unicode="&#xe139;" d="M0 200v200h1200v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500z M500 1000h200v100h-200v-100z" />
+<glyph unicode="&#xe140;" d="M0 0v400l129 -129l200 200l142 -142l-200 -200l129 -129h-400zM0 800l129 129l200 -200l142 142l-200 200l129 129h-400v-400zM729 329l142 142l200 -200l129 129v-400h-400l129 129zM729 871l200 200l-129 129h400v-400l-129 129l-200 -200z" />
+<glyph unicode="&#xe141;" d="M0 596q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 596q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM291 655 q0 23 15.5 38.5t38.5 15.5t39 -16t16 -38q0 -23 -16 -39t-39 -16q-22 0 -38 16t-16 39zM400 850q0 22 16 38.5t39 16.5q22 0 38 -16t16 -39t-16 -39t-38 -16q-23 0 -39 16.5t-16 38.5zM513 609q0 32 21 56.5t52 29.5l122 126l1 1q-9 14 -9 28q0 22 16 38.5t39 16.5 q22 0 38 -16t16 -39t-16 -39t-38 -16q-16 0 -29 10l-55 -145q17 -22 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5q-37 0 -62.5 25.5t-25.5 61.5zM800 655q0 22 16 38t39 16t38.5 -15.5t15.5 -38.5t-16 -39t-38 -16q-23 0 -39 16t-16 39z" />
+<glyph unicode="&#xe142;" d="M-40 375q-13 -95 35 -173q35 -57 94 -89t129 -32q63 0 119 28q33 16 65 40.5t52.5 45.5t59.5 64q40 44 57 61l394 394q35 35 47 84t-3 96q-27 87 -117 104q-20 2 -29 2q-46 0 -79.5 -17t-67.5 -51l-388 -396l-7 -7l69 -67l377 373q20 22 39 38q23 23 50 23q38 0 53 -36 q16 -39 -20 -75l-547 -547q-52 -52 -125 -52q-55 0 -100 33t-54 96q-5 35 2.5 66t31.5 63t42 50t56 54q24 21 44 41l348 348q52 52 82.5 79.5t84 54t107.5 26.5q25 0 48 -4q95 -17 154 -94.5t51 -175.5q-7 -101 -98 -192l-252 -249l-253 -256l7 -7l69 -60l517 511 q67 67 95 157t11 183q-16 87 -67 154t-130 103q-69 33 -152 33q-107 0 -197 -55q-40 -24 -111 -95l-512 -512q-68 -68 -81 -163z" />
+<glyph unicode="&#xe143;" d="M79 784q0 131 99 229.5t230 98.5q144 0 242 -129q103 129 245 129q130 0 227 -98.5t97 -229.5q0 -46 -17.5 -91t-61 -99t-77 -89.5t-104.5 -105.5q-197 -191 -293 -322l-17 -23l-16 23q-43 58 -100 122.5t-92 99.5t-101 100l-84.5 84.5t-68 74t-60 78t-33.5 70.5t-15 78z M250 784q0 -27 30.5 -70t61.5 -75.5t95 -94.5l22 -22q93 -90 190 -201q82 92 195 203l12 12q64 62 97.5 97t64.5 79t31 72q0 71 -48 119.5t-106 48.5q-73 0 -131 -83l-118 -171l-114 174q-51 80 -124 80q-59 0 -108.5 -49.5t-49.5 -118.5z" />
+<glyph unicode="&#xe144;" d="M57 353q0 -94 66 -160l141 -141q66 -66 159 -66q95 0 159 66l283 283q66 66 66 159t-66 159l-141 141q-12 12 -19 17l-105 -105l212 -212l-389 -389l-247 248l95 95l-18 18q-46 45 -75 101l-55 -55q-66 -66 -66 -159zM269 706q0 -93 66 -159l141 -141l19 -17l105 105 l-212 212l389 389l247 -247l-95 -96l18 -18q46 -46 77 -99l29 29q35 35 62.5 88t27.5 96q0 93 -66 159l-141 141q-66 66 -159 66q-95 0 -159 -66l-283 -283q-66 -64 -66 -159z" />
+<glyph unicode="&#xe145;" d="M200 100v953q0 21 30 46t81 48t129 38t163 15t162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5zM300 300h600v700h-600v-700zM496 150q0 -43 30.5 -73.5t73.5 -30.5t73.5 30.5t30.5 73.5t-30.5 73.5t-73.5 30.5 t-73.5 -30.5t-30.5 -73.5z" />
+<glyph unicode="&#xe146;" d="M0 0l303 380l207 208l-210 212h300l267 279l-35 36q-15 14 -15 35t15 35q14 15 35 15t35 -15l283 -282q15 -15 15 -36t-15 -35q-14 -15 -35 -15t-35 15l-36 35l-279 -267v-300l-212 210l-208 -207z" />
+<glyph unicode="&#xe148;" d="M295 433h139q5 -77 48.5 -126.5t117.5 -64.5v335l-27 7q-46 14 -79 26.5t-72 36t-62.5 52t-40 72.5t-16.5 99q0 92 44 159.5t109 101t144 40.5v78h100v-79q38 -4 72.5 -13.5t75.5 -31.5t71 -53.5t51.5 -84t24.5 -118.5h-159q-8 72 -35 109.5t-101 50.5v-307l64 -14 q34 -7 64 -16.5t70 -31.5t67.5 -52t47.5 -80.5t20 -112.5q0 -139 -89 -224t-244 -96v-77h-100v78q-152 17 -237 104q-40 40 -52.5 93.5t-15.5 139.5zM466 889q0 -29 8 -51t16.5 -34t29.5 -22.5t31 -13.5t38 -10q7 -2 11 -3v274q-61 -8 -97.5 -37.5t-36.5 -102.5zM700 237 q170 18 170 151q0 64 -44 99.5t-126 60.5v-311z" />
+<glyph unicode="&#xe149;" d="M100 600v100h166q-24 49 -44 104q-10 26 -14.5 55.5t-3 72.5t25 90t68.5 87q97 88 263 88q129 0 230 -89t101 -208h-153q0 52 -34 89.5t-74 51.5t-76 14q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -11 2.5 -24.5t5.5 -24t9.5 -26.5t10.5 -25t14 -27.5t14 -25.5 t15.5 -27t13.5 -24h242v-100h-197q8 -50 -2.5 -115t-31.5 -94q-41 -59 -99 -113q35 11 84 18t70 7q32 1 102 -16t104 -17q76 0 136 30l50 -147q-41 -25 -80.5 -36.5t-59 -13t-61.5 -1.5q-23 0 -128 33t-155 29q-39 -4 -82 -17t-66 -25l-24 -11l-55 145l16.5 11t15.5 10 t13.5 9.5t14.5 12t14.5 14t17.5 18.5q48 55 54 126.5t-30 142.5h-221z" />
+<glyph unicode="&#xe150;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM602 900l298 300l298 -300h-198v-900h-200v900h-198z" />
+<glyph unicode="&#xe151;" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v200h100v-100h200v-100h-300zM700 400v100h300v-200h-99v-100h-100v100h99v100h-200zM700 700v500h300v-500h-100v100h-100v-100h-100zM801 900h100v200h-100v-200z" />
+<glyph unicode="&#xe152;" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v500h300v-500h-100v100h-100v-100h-100zM700 700v200h100v-100h200v-100h-300zM700 1100v100h300v-200h-99v-100h-100v100h99v100h-200zM801 200h100v200h-100v-200z" />
+<glyph unicode="&#xe153;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 100v400h300v-500h-100v100h-200zM800 1100v100h200v-500h-100v400h-100zM901 200h100v200h-100v-200z" />
+<glyph unicode="&#xe154;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 400v100h200v-500h-100v400h-100zM800 800v400h300v-500h-100v100h-200zM901 900h100v200h-100v-200z" />
+<glyph unicode="&#xe155;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h500v-200h-500zM700 400v200h400v-200h-400zM700 700v200h300v-200h-300zM700 1000v200h200v-200h-200z" />
+<glyph unicode="&#xe156;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h200v-200h-200zM700 400v200h300v-200h-300zM700 700v200h400v-200h-400zM700 1000v200h500v-200h-500z" />
+<glyph unicode="&#xe157;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q162 0 281 -118.5t119 -281.5v-300q0 -165 -118.5 -282.5t-281.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500z" />
+<glyph unicode="&#xe158;" d="M0 400v300q0 163 119 281.5t281 118.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-163 0 -281.5 117.5t-118.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM400 300l333 250l-333 250v-500z" />
+<glyph unicode="&#xe159;" d="M0 400v300q0 163 117.5 281.5t282.5 118.5h300q163 0 281.5 -119t118.5 -281v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 700l250 -333l250 333h-500z" />
+<glyph unicode="&#xe160;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -162 -118.5 -281t-281.5 -119h-300q-165 0 -282.5 118.5t-117.5 281.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 400h500l-250 333z" />
+<glyph unicode="&#xe161;" d="M0 400v300h300v200l400 -350l-400 -350v200h-300zM500 0v200h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-500v200h400q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-400z" />
+<glyph unicode="&#xe162;" d="M216 519q10 -19 32 -19h302q-155 -438 -160 -458q-5 -21 4 -32l9 -8l9 -1q13 0 26 16l538 630q15 19 6 36q-8 18 -32 16h-300q1 4 78 219.5t79 227.5q2 17 -6 27l-8 8h-9q-16 0 -25 -15q-4 -5 -98.5 -111.5t-228 -257t-209.5 -238.5q-17 -19 -7 -40z" />
+<glyph unicode="&#xe163;" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q47 0 100 15v185h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h500v185q-14 4 -114 7.5t-193 5.5l-93 2q-165 0 -282.5 -117.5t-117.5 -282.5v-300zM600 400v300h300v200l400 -350l-400 -350v200h-300z " />
+<glyph unicode="&#xe164;" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q163 0 281.5 117.5t118.5 282.5v98l-78 73l-122 -123v-148q0 -41 -29.5 -70.5t-70.5 -29.5h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h156l118 122l-74 78h-100q-165 0 -282.5 -117.5t-117.5 -282.5 v-300zM496 709l353 342l-149 149h500v-500l-149 149l-342 -353z" />
+<glyph unicode="&#xe165;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM406 600 q0 80 57 137t137 57t137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137z" />
+<glyph unicode="&#xe166;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 800l445 -500l450 500h-295v400h-300v-400h-300zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe167;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 700h300v-300h300v300h295l-445 500zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe168;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 705l305 -305l596 596l-154 155l-442 -442l-150 151zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe169;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 988l97 -98l212 213l-97 97zM200 401h700v699l-250 -239l-149 149l-212 -212l149 -149zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe170;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM200 612l212 -212l98 97l-213 212zM300 1200l239 -250l-149 -149l212 -212l149 148l248 -237v700h-699zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe171;" d="M23 415l1177 784v-1079l-475 272l-310 -393v416h-392zM494 210l672 938l-672 -712v-226z" />
+<glyph unicode="&#xe172;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-850q0 -21 -15 -35.5t-35 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200z" />
+<glyph unicode="&#xe173;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-218l-276 -275l-120 120l-126 -127h-378v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM581 306l123 123l120 -120l353 352l123 -123l-475 -476zM600 1000h100v200h-100v-200z" />
+<glyph unicode="&#xe174;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-269l-103 -103l-170 170l-298 -298h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200zM700 133l170 170l-170 170l127 127l170 -170l170 170l127 -128l-170 -169l170 -170 l-127 -127l-170 170l-170 -170z" />
+<glyph unicode="&#xe175;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-300h-400v-200h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300l300 -300l300 300h-200v300h-200v-300h-200zM600 1000v200h100v-200h-100z" />
+<glyph unicode="&#xe176;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-402l-200 200l-298 -298h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300h200v-300h200v300h200l-300 300zM600 1000v200h100v-200h-100z" />
+<glyph unicode="&#xe177;" d="M0 250q0 -21 14.5 -35.5t35.5 -14.5h1100q21 0 35.5 14.5t14.5 35.5v550h-1200v-550zM0 900h1200v150q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 300v200h400v-200h-400z" />
+<glyph unicode="&#xe178;" d="M0 400l300 298v-198h400v-200h-400v-198zM100 800v200h100v-200h-100zM300 800v200h100v-200h-100zM500 800v200h400v198l300 -298l-300 -298v198h-400zM800 300v200h100v-200h-100zM1000 300h100v200h-100v-200z" />
+<glyph unicode="&#xe179;" d="M100 700v400l50 100l50 -100v-300h100v300l50 100l50 -100v-300h100v300l50 100l50 -100v-400l-100 -203v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447zM800 597q0 -29 10.5 -55.5t25 -43t29 -28.5t25.5 -18l10 -5v-397q0 -21 14.5 -35.5 t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v1106q0 31 -18 40.5t-44 -7.5l-276 -117q-25 -16 -43.5 -50.5t-18.5 -65.5v-359z" />
+<glyph unicode="&#xe180;" d="M100 0h400v56q-75 0 -87.5 6t-12.5 44v394h500v-394q0 -38 -12.5 -44t-87.5 -6v-56h400v56q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v888q0 22 25 34.5t50 13.5l25 2v56h-400v-56q75 0 87.5 -6t12.5 -44v-394h-500v394q0 38 12.5 44t87.5 6v56h-400v-56q4 0 11 -0.5 t24 -3t30 -7t24 -15t11 -24.5v-888q0 -22 -25 -34.5t-50 -13.5l-25 -2v-56z" />
+<glyph unicode="&#xe181;" d="M0 300q0 -41 29.5 -70.5t70.5 -29.5h300q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-300q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM100 100h400l200 200h105l295 98v-298h-425l-100 -100h-375zM100 300v200h300v-200h-300zM100 600v200h300v-200h-300z M100 1000h400l200 -200v-98l295 98h105v200h-425l-100 100h-375zM700 402v163l400 133v-163z" />
+<glyph unicode="&#xe182;" d="M16.5 974.5q0.5 -21.5 16 -90t46.5 -140t104 -177.5t175 -208q103 -103 207.5 -176t180 -103.5t137 -47t92.5 -16.5l31 1l163 162q16 17 13 40.5t-22 37.5l-192 136q-19 14 -45 12t-42 -19l-119 -118q-143 103 -267 227q-126 126 -227 268l118 118q17 17 20 41.5 t-11 44.5l-139 194q-14 19 -36.5 22t-40.5 -14l-162 -162q-1 -11 -0.5 -32.5z" />
+<glyph unicode="&#xe183;" d="M0 50v212q0 20 10.5 45.5t24.5 39.5l365 303v50q0 4 1 10.5t12 22.5t30 28.5t60 23t97 10.5t97 -10t60 -23.5t30 -27.5t12 -24l1 -10v-50l365 -303q14 -14 24.5 -39.5t10.5 -45.5v-212q0 -21 -15 -35.5t-35 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5zM0 712 q0 -21 14.5 -33.5t34.5 -8.5l202 33q20 4 34.5 21t14.5 38v146q141 24 300 24t300 -24v-146q0 -21 14.5 -38t34.5 -21l202 -33q20 -4 34.5 8.5t14.5 33.5v200q-6 8 -19 20.5t-63 45t-112 57t-171 45t-235 20.5q-92 0 -175 -10.5t-141.5 -27t-108.5 -36.5t-81.5 -40 t-53.5 -36.5t-31 -27.5l-9 -10v-200z" />
+<glyph unicode="&#xe184;" d="M100 0v100h1100v-100h-1100zM175 200h950l-125 150v250l100 100v400h-100v-200h-100v200h-200v-200h-100v200h-200v-200h-100v200h-100v-400l100 -100v-250z" />
+<glyph unicode="&#xe185;" d="M100 0h300v400q0 41 -29.5 70.5t-70.5 29.5h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-400zM500 0v1000q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-1000h-300zM900 0v700q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-700h-300z" />
+<glyph unicode="&#xe186;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
+<glyph unicode="&#xe187;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h100v200h100v-200h100v500h-100v-200h-100v200h-100v-500zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
+<glyph unicode="&#xe188;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v100h-200v300h200v100h-300v-500zM600 300h300v100h-200v300h200v100h-300v-500z" />
+<glyph unicode="&#xe189;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 550l300 -150v300zM600 400l300 150l-300 150v-300z" />
+<glyph unicode="&#xe190;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300v500h700v-500h-700zM300 400h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130v-300zM575 549 q0 -65 27 -107t68 -42h130v300h-130q-38 0 -66.5 -43t-28.5 -108z" />
+<glyph unicode="&#xe191;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
+<glyph unicode="&#xe192;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v400h-200v100h-100v-500zM301 400v200h100v-200h-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
+<glyph unicode="&#xe193;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 700v100h300v-300h-99v-100h-100v100h99v200h-200zM201 300v100h100v-100h-100zM601 300v100h100v-100h-100z M700 700v100h200v-500h-100v400h-100z" />
+<glyph unicode="&#xe194;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 500v200 l100 100h300v-100h-300v-200h300v-100h-300z" />
+<glyph unicode="&#xe195;" d="M0 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 400v400h300 l100 -100v-100h-100v100h-200v-100h200v-100h-200v-100h-100zM700 400v100h100v-100h-100z" />
+<glyph unicode="&#xe197;" d="M-14 494q0 -80 56.5 -137t135.5 -57h222v300h400v-300h128q120 0 205 86t85 208q0 120 -85 206.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200h200v300h200v-300 h200l-300 -300z" />
+<glyph unicode="&#xe198;" d="M-14 494q0 -80 56.5 -137t135.5 -57h8l414 414l403 -403q94 26 154.5 104t60.5 178q0 121 -85 207.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200l300 300 l300 -300h-200v-300h-200v300h-200z" />
+<glyph unicode="&#xe199;" d="M100 200h400v-155l-75 -45h350l-75 45v155h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170z" />
+<glyph unicode="&#xe200;" d="M121 700q0 -53 28.5 -97t75.5 -65q-4 -16 -4 -38q0 -74 52.5 -126.5t126.5 -52.5q56 0 100 30v-306l-75 -45h350l-75 45v306q46 -30 100 -30q74 0 126.5 52.5t52.5 126.5q0 24 -9 55q50 32 79.5 83t29.5 112q0 90 -61.5 155.5t-150.5 71.5q-26 89 -99.5 145.5 t-167.5 56.5q-116 0 -197.5 -81.5t-81.5 -197.5q0 -4 1 -12t1 -11q-14 2 -23 2q-74 0 -126.5 -52.5t-52.5 -126.5z" />
+</font>
+</defs></svg> 
\ No newline at end of file
diff --git a/app/gui/html/vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf b/app/gui/html/vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf
new file mode 100644
index 0000000..a498ef4
Binary files /dev/null and b/app/gui/html/vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf differ
diff --git a/app/gui/html/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff b/app/gui/html/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff
new file mode 100644
index 0000000..d83c539
Binary files /dev/null and b/app/gui/html/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff differ
diff --git a/app/gui/html/vendor/bootstrap/js/bootstrap.js b/app/gui/html/vendor/bootstrap/js/bootstrap.js
new file mode 100644
index 0000000..39ec471
--- /dev/null
+++ b/app/gui/html/vendor/bootstrap/js/bootstrap.js
@@ -0,0 +1,1951 @@
+/*!
+ * Bootstrap v3.1.0 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+if (typeof jQuery === 'undefined') { throw new Error('Bootstrap requires jQuery') }
+
+/* ========================================================================
+ * Bootstrap: transition.js v3.1.0
+ * http://getbootstrap.com/javascript/#transitions
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+  'use strict';
+
+  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
+  // ============================================================
+
+  function transitionEnd() {
+    var el = document.createElement('bootstrap')
+
+    var transEndEventNames = {
+      'WebkitTransition' : 'webkitTransitionEnd',
+      'MozTransition'    : 'transitionend',
+      'OTransition'      : 'oTransitionEnd otransitionend',
+      'transition'       : 'transitionend'
+    }
+
+    for (var name in transEndEventNames) {
+      if (el.style[name] !== undefined) {
+        return { end: transEndEventNames[name] }
+      }
+    }
+
+    return false // explicit for ie8 (  ._.)
+  }
+
+  // http://blog.alexmaccaw.com/css-transitions
+  $.fn.emulateTransitionEnd = function (duration) {
+    var called = false, $el = this
+    $(this).one($.support.transition.end, function () { called = true })
+    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
+    setTimeout(callback, duration)
+    return this
+  }
+
+  $(function () {
+    $.support.transition = transitionEnd()
+  })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: alert.js v3.1.0
+ * http://getbootstrap.com/javascript/#alerts
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+  'use strict';
+
+  // ALERT CLASS DEFINITION
+  // ======================
+
+  var dismiss = '[data-dismiss="alert"]'
+  var Alert   = function (el) {
+    $(el).on('click', dismiss, this.close)
+  }
+
+  Alert.prototype.close = function (e) {
+    var $this    = $(this)
+    var selector = $this.attr('data-target')
+
+    if (!selector) {
+      selector = $this.attr('href')
+      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+    }
+
+    var $parent = $(selector)
+
+    if (e) e.preventDefault()
+
+    if (!$parent.length) {
+      $parent = $this.hasClass('alert') ? $this : $this.parent()
+    }
+
+    $parent.trigger(e = $.Event('close.bs.alert'))
+
+    if (e.isDefaultPrevented()) return
+
+    $parent.removeClass('in')
+
+    function removeElement() {
+      $parent.trigger('closed.bs.alert').remove()
+    }
+
+    $.support.transition && $parent.hasClass('fade') ?
+      $parent
+        .one($.support.transition.end, removeElement)
+        .emulateTransitionEnd(150) :
+      removeElement()
+  }
+
+
+  // ALERT PLUGIN DEFINITION
+  // =======================
+
+  var old = $.fn.alert
+
+  $.fn.alert = function (option) {
+    return this.each(function () {
+      var $this = $(this)
+      var data  = $this.data('bs.alert')
+
+      if (!data) $this.data('bs.alert', (data = new Alert(this)))
+      if (typeof option == 'string') data[option].call($this)
+    })
+  }
+
+  $.fn.alert.Constructor = Alert
+
+
+  // ALERT NO CONFLICT
+  // =================
+
+  $.fn.alert.noConflict = function () {
+    $.fn.alert = old
+    return this
+  }
+
+
+  // ALERT DATA-API
+  // ==============
+
+  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: button.js v3.1.0
+ * http://getbootstrap.com/javascript/#buttons
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+  'use strict';
+
+  // BUTTON PUBLIC CLASS DEFINITION
+  // ==============================
+
+  var Button = function (element, options) {
+    this.$element  = $(element)
+    this.options   = $.extend({}, Button.DEFAULTS, options)
+    this.isLoading = false
+  }
+
+  Button.DEFAULTS = {
+    loadingText: 'loading...'
+  }
+
+  Button.prototype.setState = function (state) {
+    var d    = 'disabled'
+    var $el  = this.$element
+    var val  = $el.is('input') ? 'val' : 'html'
+    var data = $el.data()
+
+    state = state + 'Text'
+
+    if (!data.resetText) $el.data('resetText', $el[val]())
+
+    $el[val](data[state] || this.options[state])
+
+    // push to event loop to allow forms to submit
+    setTimeout($.proxy(function () {
+      if (state == 'loadingText') {
+        this.isLoading = true
+        $el.addClass(d).attr(d, d)
+      } else if (this.isLoading) {
+        this.isLoading = false
+        $el.removeClass(d).removeAttr(d)
+      }
+    }, this), 0)
+  }
+
+  Button.prototype.toggle = function () {
+    var changed = true
+    var $parent = this.$element.closest('[data-toggle="buttons"]')
+
+    if ($parent.length) {
+      var $input = this.$element.find('input')
+      if ($input.prop('type') == 'radio') {
+        if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
+        else $parent.find('.active').removeClass('active')
+      }
+      if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
+    }
+
+    if (changed) this.$element.toggleClass('active')
+  }
+
+
+  // BUTTON PLUGIN DEFINITION
+  // ========================
+
+  var old = $.fn.button
+
+  $.fn.button = function (option) {
+    return this.each(function () {
+      var $this   = $(this)
+      var data    = $this.data('bs.button')
+      var options = typeof option == 'object' && option
+
+      if (!data) $this.data('bs.button', (data = new Button(this, options)))
+
+      if (option == 'toggle') data.toggle()
+      else if (option) data.setState(option)
+    })
+  }
+
+  $.fn.button.Constructor = Button
+
+
+  // BUTTON NO CONFLICT
+  // ==================
+
+  $.fn.button.noConflict = function () {
+    $.fn.button = old
+    return this
+  }
+
+
+  // BUTTON DATA-API
+  // ===============
+
+  $(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) {
+    var $btn = $(e.target)
+    if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
+    $btn.button('toggle')
+    e.preventDefault()
+  })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: carousel.js v3.1.0
+ * http://getbootstrap.com/javascript/#carousel
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+  'use strict';
+
+  // CAROUSEL CLASS DEFINITION
+  // =========================
+
+  var Carousel = function (element, options) {
+    this.$element    = $(element)
+    this.$indicators = this.$element.find('.carousel-indicators')
+    this.options     = options
+    this.paused      =
+    this.sliding     =
+    this.interval    =
+    this.$active     =
+    this.$items      = null
+
+    this.options.pause == 'hover' && this.$element
+      .on('mouseenter', $.proxy(this.pause, this))
+      .on('mouseleave', $.proxy(this.cycle, this))
+  }
+
+  Carousel.DEFAULTS = {
+    interval: 5000,
+    pause: 'hover',
+    wrap: true
+  }
+
+  Carousel.prototype.cycle =  function (e) {
+    e || (this.paused = false)
+
+    this.interval && clearInterval(this.interval)
+
+    this.options.interval
+      && !this.paused
+      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
+
+    return this
+  }
+
+  Carousel.prototype.getActiveIndex = function () {
+    this.$active = this.$element.find('.item.active')
+    this.$items  = this.$active.parent().children()
+
+    return this.$items.index(this.$active)
+  }
+
+  Carousel.prototype.to = function (pos) {
+    var that        = this
+    var activeIndex = this.getActiveIndex()
+
+    if (pos > (this.$items.length - 1) || pos < 0) return
+
+    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) })
+    if (activeIndex == pos) return this.pause().cycle()
+
+    return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
+  }
+
+  Carousel.prototype.pause = function (e) {
+    e || (this.paused = true)
+
+    if (this.$element.find('.next, .prev').length && $.support.transition) {
+      this.$element.trigger($.support.transition.end)
+      this.cycle(true)
+    }
+
+    this.interval = clearInterval(this.interval)
+
+    return this
+  }
+
+  Carousel.prototype.next = function () {
+    if (this.sliding) return
+    return this.slide('next')
+  }
+
+  Carousel.prototype.prev = function () {
+    if (this.sliding) return
+    return this.slide('prev')
+  }
+
+  Carousel.prototype.slide = function (type, next) {
+    var $active   = this.$element.find('.item.active')
+    var $next     = next || $active[type]()
+    var isCycling = this.interval
+    var direction = type == 'next' ? 'left' : 'right'
+    var fallback  = type == 'next' ? 'first' : 'last'
+    var that      = this
+
+    if (!$next.length) {
+      if (!this.options.wrap) return
+      $next = this.$element.find('.item')[fallback]()
+    }
+
+    if ($next.hasClass('active')) return this.sliding = false
+
+    var e = $.Event('slide.bs.carousel', { relatedTarget: $next[0], direction: direction })
+    this.$element.trigger(e)
+    if (e.isDefaultPrevented()) return
+
+    this.sliding = true
+
+    isCycling && this.pause()
+
+    if (this.$indicators.length) {
+      this.$indicators.find('.active').removeClass('active')
+      this.$element.one('slid.bs.carousel', function () {
+        var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
+        $nextIndicator && $nextIndicator.addClass('active')
+      })
+    }
+
+    if ($.support.transition && this.$element.hasClass('slide')) {
+      $next.addClass(type)
+      $next[0].offsetWidth // force reflow
+      $active.addClass(direction)
+      $next.addClass(direction)
+      $active
+        .one($.support.transition.end, function () {
+          $next.removeClass([type, direction].join(' ')).addClass('active')
+          $active.removeClass(['active', direction].join(' '))
+          that.sliding = false
+          setTimeout(function () { that.$element.trigger('slid.bs.carousel') }, 0)
+        })
+        .emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000)
+    } else {
+      $active.removeClass('active')
+      $next.addClass('active')
+      this.sliding = false
+      this.$element.trigger('slid.bs.carousel')
+    }
+
+    isCycling && this.cycle()
+
+    return this
+  }
+
+
+  // CAROUSEL PLUGIN DEFINITION
+  // ==========================
+
+  var old = $.fn.carousel
+
+  $.fn.carousel = function (option) {
+    return this.each(function () {
+      var $this   = $(this)
+      var data    = $this.data('bs.carousel')
+      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
+      var action  = typeof option == 'string' ? option : options.slide
+
+      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
+      if (typeof option == 'number') data.to(option)
+      else if (action) data[action]()
+      else if (options.interval) data.pause().cycle()
+    })
+  }
+
+  $.fn.carousel.Constructor = Carousel
+
+
+  // CAROUSEL NO CONFLICT
+  // ====================
+
+  $.fn.carousel.noConflict = function () {
+    $.fn.carousel = old
+    return this
+  }
+
+
+  // CAROUSEL DATA-API
+  // =================
+
+  $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
+    var $this   = $(this), href
+    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
+    var options = $.extend({}, $target.data(), $this.data())
+    var slideIndex = $this.attr('data-slide-to')
+    if (slideIndex) options.interval = false
+
+    $target.carousel(options)
+
+    if (slideIndex = $this.attr('data-slide-to')) {
+      $target.data('bs.carousel').to(slideIndex)
+    }
+
+    e.preventDefault()
+  })
+
+  $(window).on('load', function () {
+    $('[data-ride="carousel"]').each(function () {
+      var $carousel = $(this)
+      $carousel.carousel($carousel.data())
+    })
+  })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: collapse.js v3.1.0
+ * http://getbootstrap.com/javascript/#collapse
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+  'use strict';
+
+  // COLLAPSE PUBLIC CLASS DEFINITION
+  // ================================
+
+  var Collapse = function (element, options) {
+    this.$element      = $(element)
+    this.options       = $.extend({}, Collapse.DEFAULTS, options)
+    this.transitioning = null
+
+    if (this.options.parent) this.$parent = $(this.options.parent)
+    if (this.options.toggle) this.toggle()
+  }
+
+  Collapse.DEFAULTS = {
+    toggle: true
+  }
+
+  Collapse.prototype.dimension = function () {
+    var hasWidth = this.$element.hasClass('width')
+    return hasWidth ? 'width' : 'height'
+  }
+
+  Collapse.prototype.show = function () {
+    if (this.transitioning || this.$element.hasClass('in')) return
+
+    var startEvent = $.Event('show.bs.collapse')
+    this.$element.trigger(startEvent)
+    if (startEvent.isDefaultPrevented()) return
+
+    var actives = this.$parent && this.$parent.find('> .panel > .in')
+
+    if (actives && actives.length) {
+      var hasData = actives.data('bs.collapse')
+      if (hasData && hasData.transitioning) return
+      actives.collapse('hide')
+      hasData || actives.data('bs.collapse', null)
+    }
+
+    var dimension = this.dimension()
+
+    this.$element
+      .removeClass('collapse')
+      .addClass('collapsing')
+      [dimension](0)
+
+    this.transitioning = 1
+
+    var complete = function () {
+      this.$element
+        .removeClass('collapsing')
+        .addClass('collapse in')
+        [dimension]('auto')
+      this.transitioning = 0
+      this.$element.trigger('shown.bs.collapse')
+    }
+
+    if (!$.support.transition) return complete.call(this)
+
+    var scrollSize = $.camelCase(['scroll', dimension].join('-'))
+
+    this.$element
+      .one($.support.transition.end, $.proxy(complete, this))
+      .emulateTransitionEnd(350)
+      [dimension](this.$element[0][scrollSize])
+  }
+
+  Collapse.prototype.hide = function () {
+    if (this.transitioning || !this.$element.hasClass('in')) return
+
+    var startEvent = $.Event('hide.bs.collapse')
+    this.$element.trigger(startEvent)
+    if (startEvent.isDefaultPrevented()) return
+
+    var dimension = this.dimension()
+
+    this.$element
+      [dimension](this.$element[dimension]())
+      [0].offsetHeight
+
+    this.$element
+      .addClass('collapsing')
+      .removeClass('collapse')
+      .removeClass('in')
+
+    this.transitioning = 1
+
+    var complete = function () {
+      this.transitioning = 0
+      this.$element
+        .trigger('hidden.bs.collapse')
+        .removeClass('collapsing')
+        .addClass('collapse')
+    }
+
+    if (!$.support.transition) return complete.call(this)
+
+    this.$element
+      [dimension](0)
+      .one($.support.transition.end, $.proxy(complete, this))
+      .emulateTransitionEnd(350)
+  }
+
+  Collapse.prototype.toggle = function () {
+    this[this.$element.hasClass('in') ? 'hide' : 'show']()
+  }
+
+
+  // COLLAPSE PLUGIN DEFINITION
+  // ==========================
+
+  var old = $.fn.collapse
+
+  $.fn.collapse = function (option) {
+    return this.each(function () {
+      var $this   = $(this)
+      var data    = $this.data('bs.collapse')
+      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
+
+      if (!data && options.toggle && option == 'show') option = !option
+      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
+      if (typeof option == 'string') data[option]()
+    })
+  }
+
+  $.fn.collapse.Constructor = Collapse
+
+
+  // COLLAPSE NO CONFLICT
+  // ====================
+
+  $.fn.collapse.noConflict = function () {
+    $.fn.collapse = old
+    return this
+  }
+
+
+  // COLLAPSE DATA-API
+  // =================
+
+  $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {
+    var $this   = $(this), href
+    var target  = $this.attr('data-target')
+        || e.preventDefault()
+        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
+    var $target = $(target)
+    var data    = $target.data('bs.collapse')
+    var option  = data ? 'toggle' : $this.data()
+    var parent  = $this.attr('data-parent')
+    var $parent = parent && $(parent)
+
+    if (!data || !data.transitioning) {
+      if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed')
+      $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
+    }
+
+    $target.collapse(option)
+  })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: dropdown.js v3.1.0
+ * http://getbootstrap.com/javascript/#dropdowns
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+  'use strict';
+
+  // DROPDOWN CLASS DEFINITION
+  // =========================
+
+  var backdrop = '.dropdown-backdrop'
+  var toggle   = '[data-toggle=dropdown]'
+  var Dropdown = function (element) {
+    $(element).on('click.bs.dropdown', this.toggle)
+  }
+
+  Dropdown.prototype.toggle = function (e) {
+    var $this = $(this)
+
+    if ($this.is('.disabled, :disabled')) return
+
+    var $parent  = getParent($this)
+    var isActive = $parent.hasClass('open')
+
+    clearMenus()
+
+    if (!isActive) {
+      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
+        // if mobile we use a backdrop because click events don't delegate
+        $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
+      }
+
+      var relatedTarget = { relatedTarget: this }
+      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
+
+      if (e.isDefaultPrevented()) return
+
+      $parent
+        .toggleClass('open')
+        .trigger('shown.bs.dropdown', relatedTarget)
+
+      $this.focus()
+    }
+
+    return false
+  }
+
+  Dropdown.prototype.keydown = function (e) {
+    if (!/(38|40|27)/.test(e.keyCode)) return
+
+    var $this = $(this)
+
+    e.preventDefault()
+    e.stopPropagation()
+
+    if ($this.is('.disabled, :disabled')) return
+
+    var $parent  = getParent($this)
+    var isActive = $parent.hasClass('open')
+
+    if (!isActive || (isActive && e.keyCode == 27)) {
+      if (e.which == 27) $parent.find(toggle).focus()
+      return $this.click()
+    }
+
+    var desc = ' li:not(.divider):visible a'
+    var $items = $parent.find('[role=menu]' + desc + ', [role=listbox]' + desc)
+
+    if (!$items.length) return
+
+    var index = $items.index($items.filter(':focus'))
+
+    if (e.keyCode == 38 && index > 0)                 index--                        // up
+    if (e.keyCode == 40 && index < $items.length - 1) index++                        // down
+    if (!~index)                                      index = 0
+
+    $items.eq(index).focus()
+  }
+
+  function clearMenus(e) {
+    $(backdrop).remove()
+    $(toggle).each(function () {
+      var $parent = getParent($(this))
+      var relatedTarget = { relatedTarget: this }
+      if (!$parent.hasClass('open')) return
+      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
+      if (e.isDefaultPrevented()) return
+      $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
+    })
+  }
+
+  function getParent($this) {
+    var selector = $this.attr('data-target')
+
+    if (!selector) {
+      selector = $this.attr('href')
+      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
+    }
+
+    var $parent = selector && $(selector)
+
+    return $parent && $parent.length ? $parent : $this.parent()
+  }
+
+
+  // DROPDOWN PLUGIN DEFINITION
+  // ==========================
+
+  var old = $.fn.dropdown
+
+  $.fn.dropdown = function (option) {
+    return this.each(function () {
+      var $this = $(this)
+      var data  = $this.data('bs.dropdown')
+
+      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
+      if (typeof option == 'string') data[option].call($this)
+    })
+  }
+
+  $.fn.dropdown.Constructor = Dropdown
+
+
+  // DROPDOWN NO CONFLICT
+  // ====================
+
+  $.fn.dropdown.noConflict = function () {
+    $.fn.dropdown = old
+    return this
+  }
+
+
+  // APPLY TO STANDARD DROPDOWN ELEMENTS
+  // ===================================
+
+  $(document)
+    .on('click.bs.dropdown.data-api', clearMenus)
+    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
+    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
+    .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu], [role=listbox]', Dropdown.prototype.keydown)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: modal.js v3.1.0
+ * http://getbootstrap.com/javascript/#modals
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+  'use strict';
+
+  // MODAL CLASS DEFINITION
+  // ======================
+
+  var Modal = function (element, options) {
+    this.options   = options
+    this.$element  = $(element)
+    this.$backdrop =
+    this.isShown   = null
+
+    if (this.options.remote) {
+      this.$element
+        .find('.modal-content')
+        .load(this.options.remote, $.proxy(function () {
+          this.$element.trigger('loaded.bs.modal')
+        }, this))
+    }
+  }
+
+  Modal.DEFAULTS = {
+    backdrop: true,
+    keyboard: true,
+    show: true
+  }
+
+  Modal.prototype.toggle = function (_relatedTarget) {
+    return this[!this.isShown ? 'show' : 'hide'](_relatedTarget)
+  }
+
+  Modal.prototype.show = function (_relatedTarget) {
+    var that = this
+    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
+
+    this.$element.trigger(e)
+
+    if (this.isShown || e.isDefaultPrevented()) return
+
+    this.isShown = true
+
+    this.escape()
+
+    this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
+
+    this.backdrop(function () {
+      var transition = $.support.transition && that.$element.hasClass('fade')
+
+      if (!that.$element.parent().length) {
+        that.$element.appendTo(document.body) // don't move modals dom position
+      }
+
+      that.$element
+        .show()
+        .scrollTop(0)
+
+      if (transition) {
+        that.$element[0].offsetWidth // force reflow
+      }
+
+      that.$element
+        .addClass('in')
+        .attr('aria-hidden', false)
+
+      that.enforceFocus()
+
+      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
+
+      transition ?
+        that.$element.find('.modal-dialog') // wait for modal to slide in
+          .one($.support.transition.end, function () {
+            that.$element.focus().trigger(e)
+          })
+          .emulateTransitionEnd(300) :
+        that.$element.focus().trigger(e)
+    })
+  }
+
+  Modal.prototype.hide = function (e) {
+    if (e) e.preventDefault()
+
+    e = $.Event('hide.bs.modal')
+
+    this.$element.trigger(e)
+
+    if (!this.isShown || e.isDefaultPrevented()) return
+
+    this.isShown = false
+
+    this.escape()
+
+    $(document).off('focusin.bs.modal')
+
+    this.$element
+      .removeClass('in')
+      .attr('aria-hidden', true)
+      .off('click.dismiss.bs.modal')
+
+    $.support.transition && this.$element.hasClass('fade') ?
+      this.$element
+        .one($.support.transition.end, $.proxy(this.hideModal, this))
+        .emulateTransitionEnd(300) :
+      this.hideModal()
+  }
+
+  Modal.prototype.enforceFocus = function () {
+    $(document)
+      .off('focusin.bs.modal') // guard against infinite focus loop
+      .on('focusin.bs.modal', $.proxy(function (e) {
+        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
+          this.$element.focus()
+        }
+      }, this))
+  }
+
+  Modal.prototype.escape = function () {
+    if (this.isShown && this.options.keyboard) {
+      this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
+        e.which == 27 && this.hide()
+      }, this))
+    } else if (!this.isShown) {
+      this.$element.off('keyup.dismiss.bs.modal')
+    }
+  }
+
+  Modal.prototype.hideModal = function () {
+    var that = this
+    this.$element.hide()
+    this.backdrop(function () {
+      that.removeBackdrop()
+      that.$element.trigger('hidden.bs.modal')
+    })
+  }
+
+  Modal.prototype.removeBackdrop = function () {
+    this.$backdrop && this.$backdrop.remove()
+    this.$backdrop = null
+  }
+
+  Modal.prototype.backdrop = function (callback) {
+    var animate = this.$element.hasClass('fade') ? 'fade' : ''
+
+    if (this.isShown && this.options.backdrop) {
+      var doAnimate = $.support.transition && animate
+
+      this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
+        .appendTo(document.body)
+
+      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
+        if (e.target !== e.currentTarget) return
+        this.options.backdrop == 'static'
+          ? this.$element[0].focus.call(this.$element[0])
+          : this.hide.call(this)
+      }, this))
+
+      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
+
+      this.$backdrop.addClass('in')
+
+      if (!callback) return
+
+      doAnimate ?
+        this.$backdrop
+          .one($.support.transition.end, callback)
+          .emulateTransitionEnd(150) :
+        callback()
+
+    } else if (!this.isShown && this.$backdrop) {
+      this.$backdrop.removeClass('in')
+
+      $.support.transition && this.$element.hasClass('fade') ?
+        this.$backdrop
+          .one($.support.transition.end, callback)
+          .emulateTransitionEnd(150) :
+        callback()
+
+    } else if (callback) {
+      callback()
+    }
+  }
+
+
+  // MODAL PLUGIN DEFINITION
+  // =======================
+
+  var old = $.fn.modal
+
+  $.fn.modal = function (option, _relatedTarget) {
+    return this.each(function () {
+      var $this   = $(this)
+      var data    = $this.data('bs.modal')
+      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
+
+      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
+      if (typeof option == 'string') data[option](_relatedTarget)
+      else if (options.show) data.show(_relatedTarget)
+    })
+  }
+
+  $.fn.modal.Constructor = Modal
+
+
+  // MODAL NO CONFLICT
+  // =================
+
+  $.fn.modal.noConflict = function () {
+    $.fn.modal = old
+    return this
+  }
+
+
+  // MODAL DATA-API
+  // ==============
+
+  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
+    var $this   = $(this)
+    var href    = $this.attr('href')
+    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
+    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
+
+    if ($this.is('a')) e.preventDefault()
+
+    $target
+      .modal(option, this)
+      .one('hide', function () {
+        $this.is(':visible') && $this.focus()
+      })
+  })
+
+  $(document)
+    .on('show.bs.modal', '.modal', function () { $(document.body).addClass('modal-open') })
+    .on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open') })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: tooltip.js v3.1.0
+ * http://getbootstrap.com/javascript/#tooltip
+ * Inspired by the original jQuery.tipsy by Jason Frame
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+  'use strict';
+
+  // TOOLTIP PUBLIC CLASS DEFINITION
+  // ===============================
+
+  var Tooltip = function (element, options) {
+    this.type       =
+    this.options    =
+    this.enabled    =
+    this.timeout    =
+    this.hoverState =
+    this.$element   = null
+
+    this.init('tooltip', element, options)
+  }
+
+  Tooltip.DEFAULTS = {
+    animation: true,
+    placement: 'top',
+    selector: false,
+    template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
+    trigger: 'hover focus',
+    title: '',
+    delay: 0,
+    html: false,
+    container: false
+  }
+
+  Tooltip.prototype.init = function (type, element, options) {
+    this.enabled  = true
+    this.type     = type
+    this.$element = $(element)
+    this.options  = this.getOptions(options)
+
+    var triggers = this.options.trigger.split(' ')
+
+    for (var i = triggers.length; i--;) {
+      var trigger = triggers[i]
+
+      if (trigger == 'click') {
+        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
+      } else if (trigger != 'manual') {
+        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
+        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
+
+        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
+        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
+      }
+    }
+
+    this.options.selector ?
+      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
+      this.fixTitle()
+  }
+
+  Tooltip.prototype.getDefaults = function () {
+    return Tooltip.DEFAULTS
+  }
+
+  Tooltip.prototype.getOptions = function (options) {
+    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
+
+    if (options.delay && typeof options.delay == 'number') {
+      options.delay = {
+        show: options.delay,
+        hide: options.delay
+      }
+    }
+
+    return options
+  }
+
+  Tooltip.prototype.getDelegateOptions = function () {
+    var options  = {}
+    var defaults = this.getDefaults()
+
+    this._options && $.each(this._options, function (key, value) {
+      if (defaults[key] != value) options[key] = value
+    })
+
+    return options
+  }
+
+  Tooltip.prototype.enter = function (obj) {
+    var self = obj instanceof this.constructor ?
+      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
+
+    clearTimeout(self.timeout)
+
+    self.hoverState = 'in'
+
+    if (!self.options.delay || !self.options.delay.show) return self.show()
+
+    self.timeout = setTimeout(function () {
+      if (self.hoverState == 'in') self.show()
+    }, self.options.delay.show)
+  }
+
+  Tooltip.prototype.leave = function (obj) {
+    var self = obj instanceof this.constructor ?
+      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
+
+    clearTimeout(self.timeout)
+
+    self.hoverState = 'out'
+
+    if (!self.options.delay || !self.options.delay.hide) return self.hide()
+
+    self.timeout = setTimeout(function () {
+      if (self.hoverState == 'out') self.hide()
+    }, self.options.delay.hide)
+  }
+
+  Tooltip.prototype.show = function () {
+    var e = $.Event('show.bs.' + this.type)
+
+    if (this.hasContent() && this.enabled) {
+      this.$element.trigger(e)
+
+      if (e.isDefaultPrevented()) return
+      var that = this;
+
+      var $tip = this.tip()
+
+      this.setContent()
+
+      if (this.options.animation) $tip.addClass('fade')
+
+      var placement = typeof this.options.placement == 'function' ?
+        this.options.placement.call(this, $tip[0], this.$element[0]) :
+        this.options.placement
+
+      var autoToken = /\s?auto?\s?/i
+      var autoPlace = autoToken.test(placement)
+      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
+
+      $tip
+        .detach()
+        .css({ top: 0, left: 0, display: 'block' })
+        .addClass(placement)
+
+      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
+
+      var pos          = this.getPosition()
+      var actualWidth  = $tip[0].offsetWidth
+      var actualHeight = $tip[0].offsetHeight
+
+      if (autoPlace) {
+        var $parent = this.$element.parent()
+
+        var orgPlacement = placement
+        var docScroll    = document.documentElement.scrollTop || document.body.scrollTop
+        var parentWidth  = this.options.container == 'body' ? window.innerWidth  : $parent.outerWidth()
+        var parentHeight = this.options.container == 'body' ? window.innerHeight : $parent.outerHeight()
+        var parentLeft   = this.options.container == 'body' ? 0 : $parent.offset().left
+
+        placement = placement == 'bottom' && pos.top   + pos.height  + actualHeight - docScroll > parentHeight  ? 'top'    :
+                    placement == 'top'    && pos.top   - docScroll   - actualHeight < 0                         ? 'bottom' :
+                    placement == 'right'  && pos.right + actualWidth > parentWidth                              ? 'left'   :
+                    placement == 'left'   && pos.left  - actualWidth < parentLeft                               ? 'right'  :
+                    placement
+
+        $tip
+          .removeClass(orgPlacement)
+          .addClass(placement)
+      }
+
+      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
+
+      this.applyPlacement(calculatedOffset, placement)
+      this.hoverState = null
+
+      var complete = function() {
+        that.$element.trigger('shown.bs.' + that.type)
+      }
+
+      $.support.transition && this.$tip.hasClass('fade') ?
+        $tip
+          .one($.support.transition.end, complete)
+          .emulateTransitionEnd(150) :
+        complete()
+    }
+  }
+
+  Tooltip.prototype.applyPlacement = function (offset, placement) {
+    var replace
+    var $tip   = this.tip()
+    var width  = $tip[0].offsetWidth
+    var height = $tip[0].offsetHeight
+
+    // manually read margins because getBoundingClientRect includes difference
+    var marginTop = parseInt($tip.css('margin-top'), 10)
+    var marginLeft = parseInt($tip.css('margin-left'), 10)
+
+    // we must check for NaN for ie 8/9
+    if (isNaN(marginTop))  marginTop  = 0
+    if (isNaN(marginLeft)) marginLeft = 0
+
+    offset.top  = offset.top  + marginTop
+    offset.left = offset.left + marginLeft
+
+    // $.fn.offset doesn't round pixel values
+    // so we use setOffset directly with our own function B-0
+    $.offset.setOffset($tip[0], $.extend({
+      using: function (props) {
+        $tip.css({
+          top: Math.round(props.top),
+          left: Math.round(props.left)
+        })
+      }
+    }, offset), 0)
+
+    $tip.addClass('in')
+
+    // check to see if placing tip in new offset caused the tip to resize itself
+    var actualWidth  = $tip[0].offsetWidth
+    var actualHeight = $tip[0].offsetHeight
+
+    if (placement == 'top' && actualHeight != height) {
+      replace = true
+      offset.top = offset.top + height - actualHeight
+    }
+
+    if (/bottom|top/.test(placement)) {
+      var delta = 0
+
+      if (offset.left < 0) {
+        delta       = offset.left * -2
+        offset.left = 0
+
+        $tip.offset(offset)
+
+        actualWidth  = $tip[0].offsetWidth
+        actualHeight = $tip[0].offsetHeight
+      }
+
+      this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
+    } else {
+      this.replaceArrow(actualHeight - height, actualHeight, 'top')
+    }
+
+    if (replace) $tip.offset(offset)
+  }
+
+  Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
+    this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '')
+  }
+
+  Tooltip.prototype.setContent = function () {
+    var $tip  = this.tip()
+    var title = this.getTitle()
+
+    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
+    $tip.removeClass('fade in top bottom left right')
+  }
+
+  Tooltip.prototype.hide = function () {
+    var that = this
+    var $tip = this.tip()
+    var e    = $.Event('hide.bs.' + this.type)
+
+    function complete() {
+      if (that.hoverState != 'in') $tip.detach()
+      that.$element.trigger('hidden.bs.' + that.type)
+    }
+
+    this.$element.trigger(e)
+
+    if (e.isDefaultPrevented()) return
+
+    $tip.removeClass('in')
+
+    $.support.transition && this.$tip.hasClass('fade') ?
+      $tip
+        .one($.support.transition.end, complete)
+        .emulateTransitionEnd(150) :
+      complete()
+
+    this.hoverState = null
+
+    return this
+  }
+
+  Tooltip.prototype.fixTitle = function () {
+    var $e = this.$element
+    if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
+      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
+    }
+  }
+
+  Tooltip.prototype.hasContent = function () {
+    return this.getTitle()
+  }
+
+  Tooltip.prototype.getPosition = function () {
+    var el = this.$element[0]
+    return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
+      width: el.offsetWidth,
+      height: el.offsetHeight
+    }, this.$element.offset())
+  }
+
+  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
+    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2  } :
+           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2  } :
+           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
+        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width   }
+  }
+
+  Tooltip.prototype.getTitle = function () {
+    var title
+    var $e = this.$element
+    var o  = this.options
+
+    title = $e.attr('data-original-title')
+      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
+
+    return title
+  }
+
+  Tooltip.prototype.tip = function () {
+    return this.$tip = this.$tip || $(this.options.template)
+  }
+
+  Tooltip.prototype.arrow = function () {
+    return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')
+  }
+
+  Tooltip.prototype.validate = function () {
+    if (!this.$element[0].parentNode) {
+      this.hide()
+      this.$element = null
+      this.options  = null
+    }
+  }
+
+  Tooltip.prototype.enable = function () {
+    this.enabled = true
+  }
+
+  Tooltip.prototype.disable = function () {
+    this.enabled = false
+  }
+
+  Tooltip.prototype.toggleEnabled = function () {
+    this.enabled = !this.enabled
+  }
+
+  Tooltip.prototype.toggle = function (e) {
+    var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this
+    self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
+  }
+
+  Tooltip.prototype.destroy = function () {
+    clearTimeout(this.timeout)
+    this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
+  }
+
+
+  // TOOLTIP PLUGIN DEFINITION
+  // =========================
+
+  var old = $.fn.tooltip
+
+  $.fn.tooltip = function (option) {
+    return this.each(function () {
+      var $this   = $(this)
+      var data    = $this.data('bs.tooltip')
+      var options = typeof option == 'object' && option
+
+      if (!data && option == 'destroy') return
+      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
+      if (typeof option == 'string') data[option]()
+    })
+  }
+
+  $.fn.tooltip.Constructor = Tooltip
+
+
+  // TOOLTIP NO CONFLICT
+  // ===================
+
+  $.fn.tooltip.noConflict = function () {
+    $.fn.tooltip = old
+    return this
+  }
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: popover.js v3.1.0
+ * http://getbootstrap.com/javascript/#popovers
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+  'use strict';
+
+  // POPOVER PUBLIC CLASS DEFINITION
+  // ===============================
+
+  var Popover = function (element, options) {
+    this.init('popover', element, options)
+  }
+
+  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
+
+  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
+    placement: 'right',
+    trigger: 'click',
+    content: '',
+    template: '<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
+  })
+
+
+  // NOTE: POPOVER EXTENDS tooltip.js
+  // ================================
+
+  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
+
+  Popover.prototype.constructor = Popover
+
+  Popover.prototype.getDefaults = function () {
+    return Popover.DEFAULTS
+  }
+
+  Popover.prototype.setContent = function () {
+    var $tip    = this.tip()
+    var title   = this.getTitle()
+    var content = this.getContent()
+
+    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
+    $tip.find('.popover-content')[ // we use append for html objects to maintain js events
+      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
+    ](content)
+
+    $tip.removeClass('fade top bottom left right in')
+
+    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
+    // this manually by checking the contents.
+    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
+  }
+
+  Popover.prototype.hasContent = function () {
+    return this.getTitle() || this.getContent()
+  }
+
+  Popover.prototype.getContent = function () {
+    var $e = this.$element
+    var o  = this.options
+
+    return $e.attr('data-content')
+      || (typeof o.content == 'function' ?
+            o.content.call($e[0]) :
+            o.content)
+  }
+
+  Popover.prototype.arrow = function () {
+    return this.$arrow = this.$arrow || this.tip().find('.arrow')
+  }
+
+  Popover.prototype.tip = function () {
+    if (!this.$tip) this.$tip = $(this.options.template)
+    return this.$tip
+  }
+
+
+  // POPOVER PLUGIN DEFINITION
+  // =========================
+
+  var old = $.fn.popover
+
+  $.fn.popover = function (option) {
+    return this.each(function () {
+      var $this   = $(this)
+      var data    = $this.data('bs.popover')
+      var options = typeof option == 'object' && option
+
+      if (!data && option == 'destroy') return
+      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
+      if (typeof option == 'string') data[option]()
+    })
+  }
+
+  $.fn.popover.Constructor = Popover
+
+
+  // POPOVER NO CONFLICT
+  // ===================
+
+  $.fn.popover.noConflict = function () {
+    $.fn.popover = old
+    return this
+  }
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: scrollspy.js v3.1.0
+ * http://getbootstrap.com/javascript/#scrollspy
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+  'use strict';
+
+  // SCROLLSPY CLASS DEFINITION
+  // ==========================
+
+  function ScrollSpy(element, options) {
+    var href
+    var process  = $.proxy(this.process, this)
+
+    this.$element       = $(element).is('body') ? $(window) : $(element)
+    this.$body          = $('body')
+    this.$scrollElement = this.$element.on('scroll.bs.scroll-spy.data-api', process)
+    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
+    this.selector       = (this.options.target
+      || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
+      || '') + ' .nav li > a'
+    this.offsets        = $([])
+    this.targets        = $([])
+    this.activeTarget   = null
+
+    this.refresh()
+    this.process()
+  }
+
+  ScrollSpy.DEFAULTS = {
+    offset: 10
+  }
+
+  ScrollSpy.prototype.refresh = function () {
+    var offsetMethod = this.$element[0] == window ? 'offset' : 'position'
+
+    this.offsets = $([])
+    this.targets = $([])
+
+    var self     = this
+    var $targets = this.$body
+      .find(this.selector)
+      .map(function () {
+        var $el   = $(this)
+        var href  = $el.data('target') || $el.attr('href')
+        var $href = /^#./.test(href) && $(href)
+
+        return ($href
+          && $href.length
+          && $href.is(':visible')
+          && [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
+      })
+      .sort(function (a, b) { return a[0] - b[0] })
+      .each(function () {
+        self.offsets.push(this[0])
+        self.targets.push(this[1])
+      })
+  }
+
+  ScrollSpy.prototype.process = function () {
+    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
+    var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
+    var maxScroll    = scrollHeight - this.$scrollElement.height()
+    var offsets      = this.offsets
+    var targets      = this.targets
+    var activeTarget = this.activeTarget
+    var i
+
+    if (scrollTop >= maxScroll) {
+      return activeTarget != (i = targets.last()[0]) && this.activate(i)
+    }
+
+    if (activeTarget && scrollTop <= offsets[0]) {
+      return activeTarget != (i = targets[0]) && this.activate(i)
+    }
+
+    for (i = offsets.length; i--;) {
+      activeTarget != targets[i]
+        && scrollTop >= offsets[i]
+        && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
+        && this.activate( targets[i] )
+    }
+  }
+
+  ScrollSpy.prototype.activate = function (target) {
+    this.activeTarget = target
+
+    $(this.selector)
+      .parentsUntil(this.options.target, '.active')
+      .removeClass('active')
+
+    var selector = this.selector +
+        '[data-target="' + target + '"],' +
+        this.selector + '[href="' + target + '"]'
+
+    var active = $(selector)
+      .parents('li')
+      .addClass('active')
+
+    if (active.parent('.dropdown-menu').length) {
+      active = active
+        .closest('li.dropdown')
+        .addClass('active')
+    }
+
+    active.trigger('activate.bs.scrollspy')
+  }
+
+
+  // SCROLLSPY PLUGIN DEFINITION
+  // ===========================
+
+  var old = $.fn.scrollspy
+
+  $.fn.scrollspy = function (option) {
+    return this.each(function () {
+      var $this   = $(this)
+      var data    = $this.data('bs.scrollspy')
+      var options = typeof option == 'object' && option
+
+      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
+      if (typeof option == 'string') data[option]()
+    })
+  }
+
+  $.fn.scrollspy.Constructor = ScrollSpy
+
+
+  // SCROLLSPY NO CONFLICT
+  // =====================
+
+  $.fn.scrollspy.noConflict = function () {
+    $.fn.scrollspy = old
+    return this
+  }
+
+
+  // SCROLLSPY DATA-API
+  // ==================
+
+  $(window).on('load', function () {
+    $('[data-spy="scroll"]').each(function () {
+      var $spy = $(this)
+      $spy.scrollspy($spy.data())
+    })
+  })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: tab.js v3.1.0
+ * http://getbootstrap.com/javascript/#tabs
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+  'use strict';
+
+  // TAB CLASS DEFINITION
+  // ====================
+
+  var Tab = function (element) {
+    this.element = $(element)
+  }
+
+  Tab.prototype.show = function () {
+    var $this    = this.element
+    var $ul      = $this.closest('ul:not(.dropdown-menu)')
+    var selector = $this.data('target')
+
+    if (!selector) {
+      selector = $this.attr('href')
+      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
+    }
+
+    if ($this.parent('li').hasClass('active')) return
+
+    var previous = $ul.find('.active:last a')[0]
+    var e        = $.Event('show.bs.tab', {
+      relatedTarget: previous
+    })
+
+    $this.trigger(e)
+
+    if (e.isDefaultPrevented()) return
+
+    var $target = $(selector)
+
+    this.activate($this.parent('li'), $ul)
+    this.activate($target, $target.parent(), function () {
+      $this.trigger({
+        type: 'shown.bs.tab',
+        relatedTarget: previous
+      })
+    })
+  }
+
+  Tab.prototype.activate = function (element, container, callback) {
+    var $active    = container.find('> .active')
+    var transition = callback
+      && $.support.transition
+      && $active.hasClass('fade')
+
+    function next() {
+      $active
+        .removeClass('active')
+        .find('> .dropdown-menu > .active')
+        .removeClass('active')
+
+      element.addClass('active')
+
+      if (transition) {
+        element[0].offsetWidth // reflow for transition
+        element.addClass('in')
+      } else {
+        element.removeClass('fade')
+      }
+
+      if (element.parent('.dropdown-menu')) {
+        element.closest('li.dropdown').addClass('active')
+      }
+
+      callback && callback()
+    }
+
+    transition ?
+      $active
+        .one($.support.transition.end, next)
+        .emulateTransitionEnd(150) :
+      next()
+
+    $active.removeClass('in')
+  }
+
+
+  // TAB PLUGIN DEFINITION
+  // =====================
+
+  var old = $.fn.tab
+
+  $.fn.tab = function ( option ) {
+    return this.each(function () {
+      var $this = $(this)
+      var data  = $this.data('bs.tab')
+
+      if (!data) $this.data('bs.tab', (data = new Tab(this)))
+      if (typeof option == 'string') data[option]()
+    })
+  }
+
+  $.fn.tab.Constructor = Tab
+
+
+  // TAB NO CONFLICT
+  // ===============
+
+  $.fn.tab.noConflict = function () {
+    $.fn.tab = old
+    return this
+  }
+
+
+  // TAB DATA-API
+  // ============
+
+  $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
+    e.preventDefault()
+    $(this).tab('show')
+  })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: affix.js v3.1.0
+ * http://getbootstrap.com/javascript/#affix
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+  'use strict';
+
+  // AFFIX CLASS DEFINITION
+  // ======================
+
+  var Affix = function (element, options) {
+    this.options = $.extend({}, Affix.DEFAULTS, options)
+    this.$window = $(window)
+      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
+      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))
+
+    this.$element     = $(element)
+    this.affixed      =
+    this.unpin        =
+    this.pinnedOffset = null
+
+    this.checkPosition()
+  }
+
+  Affix.RESET = 'affix affix-top affix-bottom'
+
+  Affix.DEFAULTS = {
+    offset: 0
+  }
+
+  Affix.prototype.getPinnedOffset = function () {
+    if (this.pinnedOffset) return this.pinnedOffset
+    this.$element.removeClass(Affix.RESET).addClass('affix')
+    var scrollTop = this.$window.scrollTop()
+    var position  = this.$element.offset()
+    return (this.pinnedOffset = position.top - scrollTop)
+  }
+
+  Affix.prototype.checkPositionWithEventLoop = function () {
+    setTimeout($.proxy(this.checkPosition, this), 1)
+  }
+
+  Affix.prototype.checkPosition = function () {
+    if (!this.$element.is(':visible')) return
+
+    var scrollHeight = $(document).height()
+    var scrollTop    = this.$window.scrollTop()
+    var position     = this.$element.offset()
+    var offset       = this.options.offset
+    var offsetTop    = offset.top
+    var offsetBottom = offset.bottom
+
+    if (this.affixed == 'top') position.top += scrollTop
+
+    if (typeof offset != 'object')         offsetBottom = offsetTop = offset
+    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)
+    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
+
+    var affix = this.unpin   != null && (scrollTop + this.unpin <= position.top) ? false :
+                offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
+                offsetTop    != null && (scrollTop <= offsetTop) ? 'top' : false
+
+    if (this.affixed === affix) return
+    if (this.unpin) this.$element.css('top', '')
+
+    var affixType = 'affix' + (affix ? '-' + affix : '')
+    var e         = $.Event(affixType + '.bs.affix')
+
+    this.$element.trigger(e)
+
+    if (e.isDefaultPrevented()) return
+
+    this.affixed = affix
+    this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
+
+    this.$element
+      .removeClass(Affix.RESET)
+      .addClass(affixType)
+      .trigger($.Event(affixType.replace('affix', 'affixed')))
+
+    if (affix == 'bottom') {
+      this.$element.offset({ top: scrollHeight - offsetBottom - this.$element.height() })
+    }
+  }
+
+
+  // AFFIX PLUGIN DEFINITION
+  // =======================
+
+  var old = $.fn.affix
+
+  $.fn.affix = function (option) {
+    return this.each(function () {
+      var $this   = $(this)
+      var data    = $this.data('bs.affix')
+      var options = typeof option == 'object' && option
+
+      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
+      if (typeof option == 'string') data[option]()
+    })
+  }
+
+  $.fn.affix.Constructor = Affix
+
+
+  // AFFIX NO CONFLICT
+  // =================
+
+  $.fn.affix.noConflict = function () {
+    $.fn.affix = old
+    return this
+  }
+
+
+  // AFFIX DATA-API
+  // ==============
+
+  $(window).on('load', function () {
+    $('[data-spy="affix"]').each(function () {
+      var $spy = $(this)
+      var data = $spy.data()
+
+      data.offset = data.offset || {}
+
+      if (data.offsetBottom) data.offset.bottom = data.offsetBottom
+      if (data.offsetTop)    data.offset.top    = data.offsetTop
+
+      $spy.affix(data)
+    })
+  })
+
+}(jQuery);
diff --git a/app/gui/html/vendor/bootstrap/js/bootstrap.min.js b/app/gui/html/vendor/bootstrap/js/bootstrap.min.js
new file mode 100644
index 0000000..1d4a4ed
--- /dev/null
+++ b/app/gui/html/vendor/bootstrap/js/bootstrap.min.js
@@ -0,0 +1,6 @@
+/*!
+ * Bootstrap v3.1.0 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+if("undefined"==typeof jQuery)throw new Error("Bootstrap requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(jQuery),+function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function c(){f.trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one(a.support.transition.end,c).emulateTransitionEnd(150):c())};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),"string"==typeof b&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.isLoading=!1};b.DEFAULTS={loadingText:"loading..."},b.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",f.resetText||d.data("resetText",d[e]()),d[e](f[b]||this.options[b]),setTimeout(a.proxy(function(){"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},b.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}a&&this.$element.toggleClass("active")};var c=a.fn.button;a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof c&&c;e||d.data("bs.button",e=new b(this,f)),"toggle"==c?e.toggle():c&&e.setState(c)})},a.fn.button.Constructor=b,a.fn.button.noConflict=function(){return a.fn.button=c,this},a(document).on("click.bs.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle"),b.preventDefault()})}(jQuery),+function(a){"use strict";var b=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},b.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},b.prototype.getActiveIndex=function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},b.prototype.to=function(b){var c=this,d=this.getActiveIndex();return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},b.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},b.prototype.next=function(){return this.sliding?void 0:this.slide("next")},b.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},b.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}if(e.hasClass("active"))return this.sliding=!1;var j=a.Event("slide.bs.carousel",{relatedTarget:e[0],direction:g});return this.$element.trigger(j),j.isDefaultPrevented()?void 0:(this.sliding=!0,f&&this.pause(),this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid.bs.carousel",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")})),a.support.transition&&this.$element.hasClass("slide")?(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid.bs.carousel")},0)}).emulateTransitionEnd(1e3*d.css("transition-duration").slice(0,-1))):(d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid.bs.carousel")),f&&this.cycle(),this)};var c=a.fn.carousel;a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c),g="string"==typeof c?c:f.slide;e||d.data("bs.carousel",e=new b(this,f)),"number"==typeof c?e.to(c):g?e[g]():f.interval&&e.pause().cycle()})},a.fn.carousel.Constructor=b,a.fn.carousel.noConflict=function(){return a.fn.carousel=c,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(b){var c,d=a(this),e=a(d.attr("data-target")||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"")),f=a.extend({},e.data(),d.data()),g=d.attr("data-slide-to");g&&(f.interval=!1),e.carousel(f),(g=d.attr("data-slide-to"))&&e.data("bs.carousel").to(g),b.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var b=a(this);b.carousel(b.data())})})}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.DEFAULTS={toggle:!0},b.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},b.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b=a.Event("show.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.$parent&&this.$parent.find("> .panel > .in");if(c&&c.length){var d=c.data("bs.collapse");if(d&&d.transitioning)return;c.collapse("hide"),d||c.data("bs.collapse",null)}var e=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[e](0),this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("collapse in")[e]("auto"),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return f.call(this);var g=a.camelCase(["scroll",e].join("-"));this.$element.one(a.support.transition.end,a.proxy(f,this)).emulateTransitionEnd(350)[e](this.$element[0][g])}}},b.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?void this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350):d.call(this)}}},b.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var c=a.fn.collapse;a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);!e&&f.toggle&&"show"==c&&(c=!c),e||d.data("bs.collapse",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.collapse.Constructor=b,a.fn.collapse.noConflict=function(){return a.fn.collapse=c,this},a(document).on("click.bs.collapse.data-api","[data-toggle=collapse]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.collapse"),h=g?"toggle":d.data(),i=d.attr("data-parent"),j=i&&a(i);g&&g.transitioning||(j&&j.find('[data-toggle=collapse][data-parent="'+i+'"]').not(d).addClass("collapsed"),d[f.hasClass("in")?"addClass":"removeClass"]("collapsed")),f.collapse(h)})}(jQuery),+function(a){"use strict";function b(b){a(d).remove(),a(e).each(function(){var d=c(a(this)),e={relatedTarget:this};d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown",e)),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown",e))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;f.toggleClass("open").trigger("shown.bs.dropdown",h),e.focus()}return!1}},f.prototype.keydown=function(b){if(/(38|40|27)/.test(b.keyCode)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var f=c(d),g=f.hasClass("open");if(!g||g&&27==b.keyCode)return 27==b.which&&f.find(e).focus(),d.click();var h=" li:not(.divider):visible a",i=f.find("[role=menu]"+h+", [role=listbox]"+h);if(i.length){var j=i.index(i.filter(":focus"));38==b.keyCode&&j>0&&j--,40==b.keyCode&&j<i.length-1&&j++,~j||(j=0),i.eq(j).focus()}}}};var g=a.fn.dropdown;a.fn.dropdown=function(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new f(this)),"string"==typeof b&&d[b].call(c)})},a.fn.dropdown.Constructor=f,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=g,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",e,f.prototype.toggle).on("keydown.bs.dropdown.data-api",e+", [role=menu], [role=listbox]",f.prototype.keydown)}(jQuery),+function(a){"use strict";var b=function(b,c){this.options=c,this.$element=a(b),this.$backdrop=this.isShown=null,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};b.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},b.prototype.toggle=function(a){return this[this.isShown?"hide":"show"](a)},b.prototype.show=function(b){var c=this,d=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(d),this.isShown||d.isDefaultPrevented()||(this.isShown=!0,this.escape(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.backdrop(function(){var d=a.support.transition&&c.$element.hasClass("fade");c.$element.parent().length||c.$element.appendTo(document.body),c.$element.show().scrollTop(0),d&&c.$element[0].offsetWidth,c.$element.addClass("in").attr("aria-hidden",!1),c.enforceFocus();var e=a.Event("shown.bs.modal",{relatedTarget:b});d?c.$element.find(".modal-dialog").one(a.support.transition.end,function(){c.$element.focus().trigger(e)}).emulateTransitionEnd(300):c.$element.focus().trigger(e)}))},b.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one(a.support.transition.end,a.proxy(this.hideModal,this)).emulateTransitionEnd(300):this.hideModal())},b.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.focus()},this))},b.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keyup.dismiss.bs.modal")},b.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.removeBackdrop(),a.$element.trigger("hidden.bs.modal")})},b.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},b.prototype.backdrop=function(b){var c=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var d=a.support.transition&&c;if(this.$backdrop=a('<div class="modal-backdrop '+c+'" />').appendTo(document.body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),d&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;d?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()):b&&b()};var c=a.fn.modal;a.fn.modal=function(c,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},b.DEFAULTS,e.data(),"object"==typeof c&&c);f||e.data("bs.modal",f=new b(this,g)),"string"==typeof c?f[c](d):g.show&&f.show(d)})},a.fn.modal.Constructor=b,a.fn.modal.noConflict=function(){return a.fn.modal=c,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(b){var c=a(this),d=c.attr("href"),e=a(c.attr("data-target")||d&&d.replace(/.*(?=#[^\s]+$)/,"")),f=e.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(d)&&d},e.data(),c.data());c.is("a")&&b.preventDefault(),e.modal(f,this).one("hide",function(){c.is(":visible")&&c.focus()})}),a(document).on("show.bs.modal",".modal",function(){a(document.body).addClass("modal-open")}).on("hidden.bs.modal",".modal",function(){a(document.body).removeClass("modal-open")})}(jQuery),+function(a){"use strict";var b=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};b.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1},b.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},b.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},b.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);return clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show()},b.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},b.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){if(this.$element.trigger(b),b.isDefaultPrevented())return;var c=this,d=this.tip();this.setContent(),this.options.animation&&d.addClass("fade");var e="function"==typeof this.options.placement?this.options.placement.call(this,d[0],this.$element[0]):this.options.placement,f=/\s?auto?\s?/i,g=f.test(e);g&&(e=e.replace(f,"")||"top"),d.detach().css({top:0,left:0,display:"block"}).addClass(e),this.options.container?d.appendTo(this.options.container):d.insertAfter(this.$element);var h=this.getPosition(),i=d[0].offsetWidth,j=d[0].offsetHeight;if(g){var k=this.$element.parent(),l=e,m=document.documentElement.scrollTop||document.body.scrollTop,n="body"==this.options.container?window.innerWidth:k.outerWidth(),o="body"==this.options.container?window.innerHeight:k.outerHeight(),p="body"==this.options.container?0:k.offset().left;e="bottom"==e&&h.top+h.height+j-m>o?"top":"top"==e&&h.top-m-j<0?"bottom":"right"==e&&h.right+i>n?"left":"left"==e&&h.left-i<p?"right":e,d.removeClass(l).addClass(e)}var q=this.getCalculatedOffset(e,h,i,j);this.applyPlacement(q,e),this.hoverState=null;var r=function(){c.$element.trigger("shown.bs."+c.type)};a.support.transition&&this.$tip.hasClass("fade")?d.one(a.support.transition.end,r).emulateTransitionEnd(150):r()}},b.prototype.applyPlacement=function(b,c){var d,e=this.tip(),f=e[0].offsetWidth,g=e[0].offsetHeight,h=parseInt(e.css("margin-top"),10),i=parseInt(e.css("margin-left"),10);isNaN(h)&&(h=0),isNaN(i)&&(i=0),b.top=b.top+h,b.left=b.left+i,a.offset.setOffset(e[0],a.extend({using:function(a){e.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),e.addClass("in");var j=e[0].offsetWidth,k=e[0].offsetHeight;if("top"==c&&k!=g&&(d=!0,b.top=b.top+g-k),/bottom|top/.test(c)){var l=0;b.left<0&&(l=-2*b.left,b.left=0,e.offset(b),j=e[0].offsetWidth,k=e[0].offsetHeight),this.replaceArrow(l-f+j,j,"left")}else this.replaceArrow(k-g,k,"top");d&&e.offset(b)},b.prototype.replaceArrow=function(a,b,c){this.arrow().css(c,a?50*(1-a/b)+"%":"")},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},b.prototype.hide=function(){function b(){"in"!=c.hoverState&&d.detach(),c.$element.trigger("hidden.bs."+c.type)}var c=this,d=this.tip(),e=a.Event("hide.bs."+this.type);return this.$element.trigger(e),e.isDefaultPrevented()?void 0:(d.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?d.one(a.support.transition.end,b).emulateTransitionEnd(150):b(),this.hoverState=null,this)},b.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},b.prototype.hasContent=function(){return this.getTitle()},b.prototype.getPosition=function(){var b=this.$element[0];return a.extend({},"function"==typeof b.getBoundingClientRect?b.getBoundingClientRect():{width:b.offsetWidth,height:b.offsetHeight},this.$element.offset())},b.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},b.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},b.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},b.prototype.validate=function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},b.prototype.enable=function(){this.enabled=!0},b.prototype.disable=function(){this.enabled=!1},b.prototype.toggleEnabled=function(){this.enabled=!this.enabled},b.prototype.toggle=function(b){var c=b?a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type):this;c.tip().hasClass("in")?c.leave(c):c.enter(c)},b.prototype.destroy=function(){clearTimeout(this.timeout),this.hide().$element.off("."+this.type).removeData("bs."+this.type)};var c=a.fn.tooltip;a.fn.tooltip=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof c&&c;(e||"destroy"!=c)&&(e||d.data("bs.tooltip",e=new b(this,f)),"string"==typeof c&&e[c]())})},a.fn.tooltip.Constructor=b,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=c,this}}(jQuery),+function(a){"use strict";var b=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");b.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof c&&c;(e||"destroy"!=c)&&(e||d.data("bs.popover",e=new b(this,f)),"string"==typeof c&&e[c]())})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(jQuery),+function(a){"use strict";function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(a(c).is("body")?window:c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scroll-spy.data-api",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);{var c=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})}},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,d=c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(b>=d)return g!=(a=f.last()[0])&&this.activate(a);if(g&&b<=e[0])return g!=(a=f[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parentsUntil(this.options.target,".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")};var c=a.fn.scrollspy;a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=c,this},a(window).on("load",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},b.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),f.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),"string"==typeof c&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(jQuery),+function(a){"use strict";var b=function(c,d){this.options=a.extend({},b.DEFAULTS,d),this.$window=a(window).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(c),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};b.RESET="affix affix-top affix-bottom",b.DEFAULTS={offset:0},b.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(b.RESET).addClass("affix");var a=this.$window.scrollTop(),c=this.$element.offset();return this.pinnedOffset=c.top-a},b.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},b.prototype.checkPosition=function(){if(this.$element.is(":visible")){var c=a(document).height(),d=this.$window.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"top"==this.affixed&&(e.top+=d),"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top(this.$element)),"function"==typeof h&&(h=f.bottom(this.$element));var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=c-h?"bottom":null!=g&&g>=d?"top":!1;if(this.affixed!==i){this.unpin&&this.$element.css("top","");var j="affix"+(i?"-"+i:""),k=a.Event(j+".bs.affix");this.$element.trigger(k),k.isDefaultPrevented()||(this.affixed=i,this.unpin="bottom"==i?this.getPinnedOffset():null,this.$element.removeClass(b.RESET).addClass(j).trigger(a.Event(j.replace("affix","affixed"))),"bottom"==i&&this.$element.offset({top:c-h-this.$element.height()}))}}};var c=a.fn.affix;a.fn.affix=function(c){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof c&&c;e||d.data("bs.affix",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.affix.Constructor=b,a.fn.affix.noConflict=function(){return a.fn.affix=c,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var b=a(this),c=b.data();c.offset=c.offset||{},c.offsetBottom&&(c.offset.bottom=c.offsetBottom),c.offsetTop&&(c.offset.top=c.offsetTop),b.affix(c)})})}(jQuery);
\ No newline at end of file
diff --git a/app/gui/html/vendor/codemirror/.gitattributes b/app/gui/html/vendor/codemirror/.gitattributes
new file mode 100644
index 0000000..f8bdd60
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/.gitattributes
@@ -0,0 +1,8 @@
+*.txt   text
+*.js    text
+*.html  text
+*.md    text
+*.json  text
+*.yml   text
+*.css   text
+*.svg   text
diff --git a/app/gui/html/vendor/codemirror/.gitignore b/app/gui/html/vendor/codemirror/.gitignore
new file mode 100644
index 0000000..b471fe6
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/.gitignore
@@ -0,0 +1,6 @@
+/node_modules
+/npm-debug.log
+test.html
+.tern-*
+*~
+*.swp
diff --git a/app/gui/html/vendor/codemirror/.travis.yml b/app/gui/html/vendor/codemirror/.travis.yml
new file mode 100644
index 0000000..baa0031
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/.travis.yml
@@ -0,0 +1,3 @@
+language: node_js
+node_js:
+  - 0.8
diff --git a/app/gui/html/vendor/codemirror/AUTHORS b/app/gui/html/vendor/codemirror/AUTHORS
new file mode 100644
index 0000000..a7e3335
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/AUTHORS
@@ -0,0 +1,335 @@
+List of CodeMirror contributors. Updated before every release.
+
+4r2r
+Aaron Brooks
+Abe Fettig
+Adam Ahmed
+Adam King
+adanlobato
+Adán Lobato
+Adrian Aichner
+aeroson
+Ahmad Amireh
+Ahmad M. Zawawi
+ahoward
+Akeksandr Motsjonov
+Alberto González Palomo
+Alberto Pose
+Albert Xing
+Alexander Pavlov
+Alexander Schepanovski
+Alexander Solovyov
+alexey-k
+Alex Piggott
+Amsul
+Amy
+Ananya Sen
+anaran
+AndersMad
+Anderson Mesquita
+Andre von Houck
+Andrey Lushnikov
+Andy Joslin
+Andy Kimball
+Andy Li
+angelozerr
+angelo.zerr at gmail.com
+Ankit Ahuja
+Ansel Santosa
+Anthony Grimes
+Anton Kovalyov
+areos
+AtomicPages LLC
+Atul Bhouraskar
+Aurelian Oancea
+Bastian Müller
+benbro
+Beni Cherniavsky-Paskin
+Benjamin DeCoste
+Ben Keen
+Bernhard Sirlinger
+Billy Moon
+binny
+B Krishna Chaitanya
+Blaine G
+boomyjee
+borawjm
+Brandon Frohs
+Brandon Wamboldt
+Brett Zamir
+Brian Sletten
+Bruce Mitchener
+Chandra Sekhar Pydi
+Charles Skelton
+Chris Coyier
+Chris Granger
+Chris Houseknecht
+Chris Morgan
+Christopher Brown
+ciaranj
+CodeAnimal
+ComFreek
+Curtis Gagliardi
+dagsta
+Dan Heberden
+Daniel, Dao Quang Minh
+Daniel Faust
+Daniel Huigens
+Daniel KJ
+Daniel Neel
+Daniel Parnell
+Danny Yoo
+Darius Roberts
+David Mignot
+David Pathakjee
+deebugger
+Deep Thought
+dignifiedquire
+domagoj412
+Dominator008
+Domizio Demichelis
+Drew Bratcher
+Drew Hintz
+Drew Khoury
+Dror BG
+duralog
+eborden
+edsharp
+ekhaled
+Enam Mijbah Noor
+Eric Allam
+eustas
+Fabien O'Carroll
+Fabio Zendhi Nagao
+Fauntleroy
+fbuchinger
+feizhang365
+Felipe Lalanne
+Felix Raab
+Filip Noetzel
+flack
+ForbesLindesay
+Forbes Lindesay
+Ford_Lawnmower
+Frank Wiegand
+Gabriel Horner
+Gabriel Nahmias
+galambalazs
+Gautam Mehta
+Glenn Jorde
+Glenn Ruehle
+Golevka
+Gordon Smith
+Grant Skinner
+greengiant
+Guillaume Massé
+Guillaume Massé
+Hans Engel
+Hardest
+Hasan Karahan
+hitsthings
+Hocdoc
+Ian Beck
+Ian Dickinson
+Ian Wehrman
+Ian Wetherbee
+Ice White
+ICHIKAWA, Yuji
+ilvalle
+Ingo Richter
+Irakli Gozalishvili
+Ivan Kurnosov
+Jacob Lee
+Jakob Miland
+Jakub Vrana
+James Campos
+James Thorne
+Jamie Hill
+Jan Jongboom
+jankeromnes
+Jan Keromnes
+Jan Odvarko
+Jan T. Sott
+Jason
+Jason Grout
+Jason Johnston
+Jason San Jose
+Jason Siefken
+Jean Boussier
+jeffkenton
+Jeff Pickhardt
+jem (graphite)
+Jochen Berger
+Johan Ask
+John Connor
+John Lees-Miller
+John Snelson
+John Van Der Loo
+Jonathan Malmaud
+jongalloway
+Jon Malmaud
+Joost-Wim Boekesteijn
+Joseph Pecoraro
+Joshua Newman
+jots
+jsoojeon
+Juan Benavides Romero
+Jucovschi Constantin
+Juho Vuori
+jwallers at gmail.com
+kaniga
+Ken Newman
+Ken Rockot
+Kevin Sawicki
+Klaus Silveira
+Koh Zi Han, Cliff
+komakino
+Konstantin Lopuhin
+koops
+ks-ifware
+kubelsmieci
+Lanny
+Laszlo Vidacs
+leaf corcoran
+Leonya Khachaturov
+Liam Newman
+LM
+Lorenzo Stoakes
+Luciano Longo
+lynschinzer
+Maksim Lin
+Maksym Taran
+Malay Majithia
+Manuel Rego Casasnovas
+Marat Dreizin
+Marco Aurélio
+Marco Munizaga
+Marijn Haverbeke
+Mario Pietsch
+Mark Lentczner
+Marko Bonaci
+Martin Balek
+Martín Gaitán
+Martin Hasoň
+Mason Malone
+Mateusz Paprocki
+mats cronqvist
+Matthew Beale
+Matthias BUSSONNIER
+Matt McDonald
+Matt Pass
+Matt Sacks
+Maximilian Hils
+Maxim Kraev
+Max Kirsch
+mbarkhau
+Metatheos
+Micah Dubinko
+Michael Lehenbauer
+Michael Zhou
+Mighty Guava
+Miguel Castillo
+Mike
+Mike Brevoort
+Mike Diaz
+Mike Ivanov
+Mike Kadin
+MinRK
+Miraculix87
+misfo
+mloginov
+mps
+mtaran-google
+Narciso Jaramillo
+Nathan Williams
+ndr
+nerbert
+nextrevision
+nguillaumin
+Ng Zhi An
+Nicholas Bollweg
+Niels van Groningen
+Nikita Beloglazov
+Nikita Vasilyev
+Nikolay Kostov
+nlwillia
+pablo
+Page
+Patil Arpith
+Patrick Strawderman
+Paul Garvin
+Paul Ivanov
+Pavel Feldman
+Pavel Strashkin
+Paweł Bartkiewicz
+peteguhl
+peterkroon
+Peter Kroon
+prasanthj
+Prasanth J
+Rahul
+Randy Edmunds
+Rasmus Erik Voel Jensen
+Richard Z.H. Wang
+robertop23
+Robert Plummer
+Ruslan Osmanov
+Ryan Prior
+sabaca
+Samuel Ainsworth
+sandeepshetty
+santec
+Sascha Peilicke
+satchmorun
+sathyamoorthi
+SCLINIC\jdecker
+Sebastian Zaha
+shaund
+shaun gilchrist
+Shawn A
+sheopory
+Shiv Deepak
+Shmuel Englard
+soliton4
+sonson
+spastorelli
+srajanpaliwal
+Stanislav Oaserele
+Stas Kobzar
+Stefan Borsje
+Steffen Beyer
+Steve O'Hara
+stoskov
+Taha Jahangir
+Tarmil
+tfjgeorge
+Thaddee Tyl
+think
+Thomas Dvornik
+Thomas Schmid
+Tim Baumann
+Timothy Farrell
+Timothy Hatcher
+TobiasBg
+Tomas-A
+Tomas Varaneckas
+Tom Erik Støwer
+Tom MacWright
+Tony Jian
+Travis Heppe
+Triangle717
+twifkak
+Vestimir Markov
+vf
+Volker Mische
+wenli
+Wesley Wiser
+William Jamieson
+Wojtek Ptak
+Xavier Mendez
+YNH Webdev
+Yunchi Luo
+Yuvi Panda
+Zachary Dremann
+zziuni
+魏鹏刚
diff --git a/app/gui/html/vendor/codemirror/CONTRIBUTING.md b/app/gui/html/vendor/codemirror/CONTRIBUTING.md
new file mode 100644
index 0000000..8938f62
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/CONTRIBUTING.md
@@ -0,0 +1,72 @@
+# How to contribute
+
+- [Getting help](#getting-help-)
+- [Submitting bug reports](#submitting-bug-reports-)
+- [Contributing code](#contributing-code-)
+
+## Getting help
+
+Community discussion, questions, and informal bug reporting is done on the
+[CodeMirror Google group](http://groups.google.com/group/codemirror).
+
+## Submitting bug reports
+
+The preferred way to report bugs is to use the
+[GitHub issue tracker](http://github.com/marijnh/CodeMirror/issues). Before
+reporting a bug, read these pointers.
+
+**Note:** The issue tracker is for *bugs*, not requests for help. Questions
+should be asked on the
+[CodeMirror Google group](http://groups.google.com/group/codemirror) instead.
+
+### Reporting bugs effectively
+
+- CodeMirror is maintained by volunteers. They don't owe you anything, so be
+  polite. Reports with an indignant or belligerent tone tend to be moved to the
+  bottom of the pile.
+
+- Include information about **the browser in which the problem occurred**. Even
+  if you tested several browsers, and the problem occurred in all of them,
+  mention this fact in the bug report. Also include browser version numbers and
+  the operating system that you're on.
+
+- Mention which release of CodeMirror you're using. Preferably, try also with
+  the current development snapshot, to ensure the problem has not already been
+  fixed.
+
+- Mention very precisely what went wrong. "X is broken" is not a good bug
+  report. What did you expect to happen? What happened instead? Describe the
+  exact steps a maintainer has to take to make the problem occur. We can not
+  fix something that we can not observe.
+
+- If the problem can not be reproduced in any of the demos included in the
+  CodeMirror distribution, please provide an HTML document that demonstrates
+  the problem. The best way to do this is to go to
+  [jsbin.com](http://jsbin.com/ihunin/edit), enter it there, press save, and
+  include the resulting link in your bug report.
+
+## Contributing code
+
+- Make sure you have a [GitHub Account](https://github.com/signup/free)
+- Fork [CodeMirror](https://github.com/marijnh/CodeMirror/)
+  ([how to fork a repo](https://help.github.com/articles/fork-a-repo))
+- Make your changes
+- If your changes are easy to test or likely to regress, add tests.
+  Tests for the core go into `test/test.js`, some modes have their own
+  test suite under `mode/XXX/test.js`. Feel free to add new test
+  suites to modes that don't have one yet (be sure to link the new
+  tests into `test/index.html`).
+- Follow the general code style of the rest of the project (see
+  below). Run `bin/lint` to verify that the linter is happy.
+- Make sure all tests pass. Visit `test/index.html` in your browser to
+  run them.
+- Submit a pull request
+([how to create a pull request](https://help.github.com/articles/fork-a-repo))
+
+### Coding standards
+
+- 2 spaces per indentation level, no tabs.
+- Include semicolons after statements.
+- Note that the linter (`bin/lint`) which is run after each commit
+  complains about unused variables and functions. Prefix their names
+  with an underscore to muffle it.
diff --git a/app/gui/html/vendor/codemirror/LICENSE b/app/gui/html/vendor/codemirror/LICENSE
new file mode 100644
index 0000000..442d11c
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2013 by Marijn Haverbeke <marijnh at gmail.com> and others
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/app/gui/html/vendor/codemirror/README.md b/app/gui/html/vendor/codemirror/README.md
new file mode 100644
index 0000000..61f6b64
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/README.md
@@ -0,0 +1,11 @@
+# CodeMirror
+[![Build Status](https://secure.travis-ci.org/marijnh/CodeMirror.png?branch=master)](http://travis-ci.org/marijnh/CodeMirror)
+[![NPM version](https://badge.fury.io/js/codemirror.png)](http://badge.fury.io/js/codemirror)
+
+CodeMirror is a JavaScript component that provides a code editor in
+the browser. When a mode is available for the language you are coding
+in, it will color your code, and optionally help with indentation.
+
+The project page is http://codemirror.net  
+The manual is at http://codemirror.net/doc/manual.html  
+The contributing guidelines are in [CONTRIBUTING.md](https://github.com/marijnh/CodeMirror/blob/master/CONTRIBUTING.md)
diff --git a/app/gui/html/vendor/codemirror/addon/comment/comment.js b/app/gui/html/vendor/codemirror/addon/comment/comment.js
new file mode 100644
index 0000000..1eb9a05
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/comment/comment.js
@@ -0,0 +1,169 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var noOptions = {};
+  var nonWS = /[^\s\u00a0]/;
+  var Pos = CodeMirror.Pos;
+
+  function firstNonWS(str) {
+    var found = str.search(nonWS);
+    return found == -1 ? 0 : found;
+  }
+
+  CodeMirror.commands.toggleComment = function(cm) {
+    var minLine = Infinity, ranges = cm.listSelections(), mode = null;
+    for (var i = ranges.length - 1; i >= 0; i--) {
+      var from = ranges[i].from(), to = ranges[i].to();
+      if (from.line >= minLine) continue;
+      if (to.line >= minLine) to = Pos(minLine, 0);
+      minLine = from.line;
+      if (mode == null) {
+        if (cm.uncomment(from, to)) mode = "un";
+        else { cm.lineComment(from, to); mode = "line"; }
+      } else if (mode == "un") {
+        cm.uncomment(from, to);
+      } else {
+        cm.lineComment(from, to);
+      }
+    }
+  };
+
+  CodeMirror.defineExtension("lineComment", function(from, to, options) {
+    if (!options) options = noOptions;
+    var self = this, mode = self.getModeAt(from);
+    var commentString = options.lineComment || mode.lineComment;
+    if (!commentString) {
+      if (options.blockCommentStart || mode.blockCommentStart) {
+        options.fullLines = true;
+        self.blockComment(from, to, options);
+      }
+      return;
+    }
+    var firstLine = self.getLine(from.line);
+    if (firstLine == null) return;
+    var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1);
+    var pad = options.padding == null ? " " : options.padding;
+    var blankLines = options.commentBlankLines || from.line == to.line;
+
+    self.operation(function() {
+      if (options.indent) {
+        var baseString = firstLine.slice(0, firstNonWS(firstLine));
+        for (var i = from.line; i < end; ++i) {
+          var line = self.getLine(i), cut = baseString.length;
+          if (!blankLines && !nonWS.test(line)) continue;
+          if (line.slice(0, cut) != baseString) cut = firstNonWS(line);
+          self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut));
+        }
+      } else {
+        for (var i = from.line; i < end; ++i) {
+          if (blankLines || nonWS.test(self.getLine(i)))
+            self.replaceRange(commentString + pad, Pos(i, 0));
+        }
+      }
+    });
+  });
+
+  CodeMirror.defineExtension("blockComment", function(from, to, options) {
+    if (!options) options = noOptions;
+    var self = this, mode = self.getModeAt(from);
+    var startString = options.blockCommentStart || mode.blockCommentStart;
+    var endString = options.blockCommentEnd || mode.blockCommentEnd;
+    if (!startString || !endString) {
+      if ((options.lineComment || mode.lineComment) && options.fullLines != false)
+        self.lineComment(from, to, options);
+      return;
+    }
+
+    var end = Math.min(to.line, self.lastLine());
+    if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end;
+
+    var pad = options.padding == null ? " " : options.padding;
+    if (from.line > end) return;
+
+    self.operation(function() {
+      if (options.fullLines != false) {
+        var lastLineHasText = nonWS.test(self.getLine(end));
+        self.replaceRange(pad + endString, Pos(end));
+        self.replaceRange(startString + pad, Pos(from.line, 0));
+        var lead = options.blockCommentLead || mode.blockCommentLead;
+        if (lead != null) for (var i = from.line + 1; i <= end; ++i)
+          if (i != end || lastLineHasText)
+            self.replaceRange(lead + pad, Pos(i, 0));
+      } else {
+        self.replaceRange(endString, to);
+        self.replaceRange(startString, from);
+      }
+    });
+  });
+
+  CodeMirror.defineExtension("uncomment", function(from, to, options) {
+    if (!options) options = noOptions;
+    var self = this, mode = self.getModeAt(from);
+    var end = Math.min(to.line, self.lastLine()), start = Math.min(from.line, end);
+
+    // Try finding line comments
+    var lineString = options.lineComment || mode.lineComment, lines = [];
+    var pad = options.padding == null ? " " : options.padding, didSomething;
+    lineComment: {
+      if (!lineString) break lineComment;
+      for (var i = start; i <= end; ++i) {
+        var line = self.getLine(i);
+        var found = line.indexOf(lineString);
+        if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1;
+        if (found == -1 && (i != end || i == start) && nonWS.test(line)) break lineComment;
+        if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment;
+        lines.push(line);
+      }
+      self.operation(function() {
+        for (var i = start; i <= end; ++i) {
+          var line = lines[i - start];
+          var pos = line.indexOf(lineString), endPos = pos + lineString.length;
+          if (pos < 0) continue;
+          if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length;
+          didSomething = true;
+          self.replaceRange("", Pos(i, pos), Pos(i, endPos));
+        }
+      });
+      if (didSomething) return true;
+    }
+
+    // Try block comments
+    var startString = options.blockCommentStart || mode.blockCommentStart;
+    var endString = options.blockCommentEnd || mode.blockCommentEnd;
+    if (!startString || !endString) return false;
+    var lead = options.blockCommentLead || mode.blockCommentLead;
+    var startLine = self.getLine(start), endLine = end == start ? startLine : self.getLine(end);
+    var open = startLine.indexOf(startString), close = endLine.lastIndexOf(endString);
+    if (close == -1 && start != end) {
+      endLine = self.getLine(--end);
+      close = endLine.lastIndexOf(endString);
+    }
+    if (open == -1 || close == -1 ||
+        !/comment/.test(self.getTokenTypeAt(Pos(start, open + 1))) ||
+        !/comment/.test(self.getTokenTypeAt(Pos(end, close + 1))))
+      return false;
+
+    self.operation(function() {
+      self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)),
+                        Pos(end, close + endString.length));
+      var openEnd = open + startString.length;
+      if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length;
+      self.replaceRange("", Pos(start, open), Pos(start, openEnd));
+      if (lead) for (var i = start + 1; i <= end; ++i) {
+        var line = self.getLine(i), found = line.indexOf(lead);
+        if (found == -1 || nonWS.test(line.slice(0, found))) continue;
+        var foundEnd = found + lead.length;
+        if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length;
+        self.replaceRange("", Pos(i, found), Pos(i, foundEnd));
+      }
+    });
+    return true;
+  });
+});
diff --git a/app/gui/html/vendor/codemirror/addon/comment/continuecomment.js b/app/gui/html/vendor/codemirror/addon/comment/continuecomment.js
new file mode 100644
index 0000000..4227726
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/comment/continuecomment.js
@@ -0,0 +1,82 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  var modes = ["clike", "css", "javascript"];
+
+  for (var i = 0; i < modes.length; ++i)
+    CodeMirror.extendMode(modes[i], {blockCommentContinue: " * "});
+
+  function continueComment(cm) {
+    if (cm.getOption("disableInput")) return CodeMirror.Pass;
+    var ranges = cm.listSelections(), mode, inserts = [];
+    for (var i = 0; i < ranges.length; i++) {
+      var pos = ranges[i].head, token = cm.getTokenAt(pos);
+      if (token.type != "comment") return CodeMirror.Pass;
+      var modeHere = CodeMirror.innerMode(cm.getMode(), token.state).mode;
+      if (!mode) mode = modeHere;
+      else if (mode != modeHere) return CodeMirror.Pass;
+
+      var insert = null;
+      if (mode.blockCommentStart && mode.blockCommentContinue) {
+        var end = token.string.indexOf(mode.blockCommentEnd);
+        var full = cm.getRange(CodeMirror.Pos(pos.line, 0), CodeMirror.Pos(pos.line, token.end)), found;
+        if (end != -1 && end == token.string.length - mode.blockCommentEnd.length && pos.ch >= end) {
+          // Comment ended, don't continue it
+        } else if (token.string.indexOf(mode.blockCommentStart) == 0) {
+          insert = full.slice(0, token.start);
+          if (!/^\s*$/.test(insert)) {
+            insert = "";
+            for (var j = 0; j < token.start; ++j) insert += " ";
+          }
+        } else if ((found = full.indexOf(mode.blockCommentContinue)) != -1 &&
+                   found + mode.blockCommentContinue.length > token.start &&
+                   /^\s*$/.test(full.slice(0, found))) {
+          insert = full.slice(0, found);
+        }
+        if (insert != null) insert += mode.blockCommentContinue;
+      }
+      if (insert == null && mode.lineComment && continueLineCommentEnabled(cm)) {
+        var line = cm.getLine(pos.line), found = line.indexOf(mode.lineComment);
+        if (found > -1) {
+          insert = line.slice(0, found);
+          if (/\S/.test(insert)) insert = null;
+          else insert += mode.lineComment + line.slice(found + mode.lineComment.length).match(/^\s*/)[0];
+        }
+      }
+      if (insert == null) return CodeMirror.Pass;
+      inserts[i] = "\n" + insert;
+    }
+
+    cm.operation(function() {
+      for (var i = ranges.length - 1; i >= 0; i--)
+        cm.replaceRange(inserts[i], ranges[i].from(), ranges[i].to(), "+insert");
+    });
+  }
+
+  function continueLineCommentEnabled(cm) {
+    var opt = cm.getOption("continueComments");
+    if (opt && typeof opt == "object")
+      return opt.continueLineComment !== false;
+    return true;
+  }
+
+  CodeMirror.defineOption("continueComments", null, function(cm, val, prev) {
+    if (prev && prev != CodeMirror.Init)
+      cm.removeKeyMap("continueComment");
+    if (val) {
+      var key = "Enter";
+      if (typeof val == "string")
+        key = val;
+      else if (typeof val == "object" && val.key)
+        key = val.key;
+      var map = {name: "continueComment"};
+      map[key] = continueComment;
+      cm.addKeyMap(map);
+    }
+  });
+});
diff --git a/app/gui/html/vendor/codemirror/addon/dialog/dialog.css b/app/gui/html/vendor/codemirror/addon/dialog/dialog.css
new file mode 100644
index 0000000..2e7c0fc
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/dialog/dialog.css
@@ -0,0 +1,32 @@
+.CodeMirror-dialog {
+  position: absolute;
+  left: 0; right: 0;
+  background: white;
+  z-index: 15;
+  padding: .1em .8em;
+  overflow: hidden;
+  color: #333;
+}
+
+.CodeMirror-dialog-top {
+  border-bottom: 1px solid #eee;
+  top: 0;
+}
+
+.CodeMirror-dialog-bottom {
+  border-top: 1px solid #eee;
+  bottom: 0;
+}
+
+.CodeMirror-dialog input {
+  border: none;
+  outline: none;
+  background: transparent;
+  width: 20em;
+  color: inherit;
+  font-family: monospace;
+}
+
+.CodeMirror-dialog button {
+  font-size: 70%;
+}
diff --git a/app/gui/html/vendor/codemirror/addon/dialog/dialog.js b/app/gui/html/vendor/codemirror/addon/dialog/dialog.js
new file mode 100644
index 0000000..586b737
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/dialog/dialog.js
@@ -0,0 +1,130 @@
+// Open simple dialogs on top of an editor. Relies on dialog.css.
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  function dialogDiv(cm, template, bottom) {
+    var wrap = cm.getWrapperElement();
+    var dialog;
+    dialog = wrap.appendChild(document.createElement("div"));
+    if (bottom) {
+      dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
+    } else {
+      dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
+    }
+    if (typeof template == "string") {
+      dialog.innerHTML = template;
+    } else { // Assuming it's a detached DOM element.
+      dialog.appendChild(template);
+    }
+    return dialog;
+  }
+
+  function closeNotification(cm, newVal) {
+    if (cm.state.currentNotificationClose)
+      cm.state.currentNotificationClose();
+    cm.state.currentNotificationClose = newVal;
+  }
+
+  CodeMirror.defineExtension("openDialog", function(template, callback, options) {
+    closeNotification(this, null);
+    var dialog = dialogDiv(this, template, options && options.bottom);
+    var closed = false, me = this;
+    function close() {
+      if (closed) return;
+      closed = true;
+      dialog.parentNode.removeChild(dialog);
+    }
+    var inp = dialog.getElementsByTagName("input")[0], button;
+    if (inp) {
+      if (options && options.value) inp.value = options.value;
+      CodeMirror.on(inp, "keydown", function(e) {
+        if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
+        if (e.keyCode == 13 || e.keyCode == 27) {
+          inp.blur();
+          CodeMirror.e_stop(e);
+          close();
+          me.focus();
+          if (e.keyCode == 13) callback(inp.value);
+        }
+      });
+      if (options && options.onKeyUp) {
+        CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
+      }
+      if (options && options.value) inp.value = options.value;
+      inp.focus();
+      CodeMirror.on(inp, "blur", close);
+    } else if (button = dialog.getElementsByTagName("button")[0]) {
+      CodeMirror.on(button, "click", function() {
+        close();
+        me.focus();
+      });
+      button.focus();
+      CodeMirror.on(button, "blur", close);
+    }
+    return close;
+  });
+
+  CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) {
+    closeNotification(this, null);
+    var dialog = dialogDiv(this, template, options && options.bottom);
+    var buttons = dialog.getElementsByTagName("button");
+    var closed = false, me = this, blurring = 1;
+    function close() {
+      if (closed) return;
+      closed = true;
+      dialog.parentNode.removeChild(dialog);
+      me.focus();
+    }
+    buttons[0].focus();
+    for (var i = 0; i < buttons.length; ++i) {
+      var b = buttons[i];
+      (function(callback) {
+        CodeMirror.on(b, "click", function(e) {
+          CodeMirror.e_preventDefault(e);
+          close();
+          if (callback) callback(me);
+        });
+      })(callbacks[i]);
+      CodeMirror.on(b, "blur", function() {
+        --blurring;
+        setTimeout(function() { if (blurring <= 0) close(); }, 200);
+      });
+      CodeMirror.on(b, "focus", function() { ++blurring; });
+    }
+  });
+
+  /*
+   * openNotification
+   * Opens a notification, that can be closed with an optional timer
+   * (default 5000ms timer) and always closes on click.
+   *
+   * If a notification is opened while another is opened, it will close the
+   * currently opened one and open the new one immediately.
+   */
+  CodeMirror.defineExtension("openNotification", function(template, options) {
+    closeNotification(this, close);
+    var dialog = dialogDiv(this, template, options && options.bottom);
+    var duration = options && (options.duration === undefined ? 5000 : options.duration);
+    var closed = false, doneTimer;
+
+    function close() {
+      if (closed) return;
+      closed = true;
+      clearTimeout(doneTimer);
+      dialog.parentNode.removeChild(dialog);
+    }
+
+    CodeMirror.on(dialog, 'click', function(e) {
+      CodeMirror.e_preventDefault(e);
+      close();
+    });
+    if (duration)
+      doneTimer = setTimeout(close, options.duration);
+  });
+});
diff --git a/app/gui/html/vendor/codemirror/addon/display/fullscreen.css b/app/gui/html/vendor/codemirror/addon/display/fullscreen.css
new file mode 100644
index 0000000..437acd8
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/display/fullscreen.css
@@ -0,0 +1,6 @@
+.CodeMirror-fullscreen {
+  position: fixed;
+  top: 0; left: 0; right: 0; bottom: 0;
+  height: auto;
+  z-index: 9;
+}
diff --git a/app/gui/html/vendor/codemirror/addon/display/fullscreen.js b/app/gui/html/vendor/codemirror/addon/display/fullscreen.js
new file mode 100644
index 0000000..e39c6e1
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/display/fullscreen.js
@@ -0,0 +1,38 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  CodeMirror.defineOption("fullScreen", false, function(cm, val, old) {
+    if (old == CodeMirror.Init) old = false;
+    if (!old == !val) return;
+    if (val) setFullscreen(cm);
+    else setNormal(cm);
+  });
+
+  function setFullscreen(cm) {
+    var wrap = cm.getWrapperElement();
+    cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset,
+                                  width: wrap.style.width, height: wrap.style.height};
+    wrap.style.width = "";
+    wrap.style.height = "auto";
+    wrap.className += " CodeMirror-fullscreen";
+    document.documentElement.style.overflow = "hidden";
+    cm.refresh();
+  }
+
+  function setNormal(cm) {
+    var wrap = cm.getWrapperElement();
+    wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, "");
+    document.documentElement.style.overflow = "";
+    var info = cm.state.fullScreenRestore;
+    wrap.style.width = info.width; wrap.style.height = info.height;
+    window.scrollTo(info.scrollLeft, info.scrollTop);
+    cm.refresh();
+  }
+});
diff --git a/app/gui/html/vendor/codemirror/addon/display/placeholder.js b/app/gui/html/vendor/codemirror/addon/display/placeholder.js
new file mode 100644
index 0000000..0fdc9b0
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/display/placeholder.js
@@ -0,0 +1,55 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  CodeMirror.defineOption("placeholder", "", function(cm, val, old) {
+    var prev = old && old != CodeMirror.Init;
+    if (val && !prev) {
+      cm.on("blur", onBlur);
+      cm.on("change", onChange);
+      onChange(cm);
+    } else if (!val && prev) {
+      cm.off("blur", onBlur);
+      cm.off("change", onChange);
+      clearPlaceholder(cm);
+      var wrapper = cm.getWrapperElement();
+      wrapper.className = wrapper.className.replace(" CodeMirror-empty", "");
+    }
+
+    if (val && !cm.hasFocus()) onBlur(cm);
+  });
+
+  function clearPlaceholder(cm) {
+    if (cm.state.placeholder) {
+      cm.state.placeholder.parentNode.removeChild(cm.state.placeholder);
+      cm.state.placeholder = null;
+    }
+  }
+  function setPlaceholder(cm) {
+    clearPlaceholder(cm);
+    var elt = cm.state.placeholder = document.createElement("pre");
+    elt.style.cssText = "height: 0; overflow: visible";
+    elt.className = "CodeMirror-placeholder";
+    elt.appendChild(document.createTextNode(cm.getOption("placeholder")));
+    cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild);
+  }
+
+  function onBlur(cm) {
+    if (isEmpty(cm)) setPlaceholder(cm);
+  }
+  function onChange(cm) {
+    var wrapper = cm.getWrapperElement(), empty = isEmpty(cm);
+    wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : "");
+
+    if (empty) setPlaceholder(cm);
+    else clearPlaceholder(cm);
+  }
+
+  function isEmpty(cm) {
+    return (cm.lineCount() === 1) && (cm.getLine(0) === "");
+  }
+});
diff --git a/app/gui/html/vendor/codemirror/addon/display/rulers.js b/app/gui/html/vendor/codemirror/addon/display/rulers.js
new file mode 100644
index 0000000..eb0ff06
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/display/rulers.js
@@ -0,0 +1,54 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  CodeMirror.defineOption("rulers", false, function(cm, val, old) {
+    if (old && old != CodeMirror.Init) {
+      clearRulers(cm);
+      cm.off("refresh", refreshRulers);
+    }
+    if (val && val.length) {
+      setRulers(cm);
+      cm.on("refresh", refreshRulers);
+    }
+  });
+
+  function clearRulers(cm) {
+    for (var i = cm.display.lineSpace.childNodes.length - 1; i >= 0; i--) {
+      var node = cm.display.lineSpace.childNodes[i];
+      if (/(^|\s)CodeMirror-ruler($|\s)/.test(node.className))
+        node.parentNode.removeChild(node);
+    }
+  }
+
+  function setRulers(cm) {
+    var val = cm.getOption("rulers");
+    var cw = cm.defaultCharWidth();
+    var left = cm.charCoords(CodeMirror.Pos(cm.firstLine(), 0), "div").left;
+    var bot = -cm.display.scroller.offsetHeight;
+    for (var i = 0; i < val.length; i++) {
+      var elt = document.createElement("div");
+      var col, cls = null;
+      if (typeof val[i] == "number") {
+        col = val[i];
+      } else {
+        col = val[i].column;
+        cls = val[i].className;
+      }
+      elt.className = "CodeMirror-ruler" + (cls ? " " + cls : "");
+      elt.style.cssText = "left: " + (left + col * cw) + "px; top: -50px; bottom: " + bot + "px";
+      cm.display.lineSpace.insertBefore(elt, cm.display.cursorDiv);
+    }
+  }
+
+  function refreshRulers(cm) {
+    clearRulers(cm);
+    setRulers(cm);
+  }
+});
diff --git a/app/gui/html/vendor/codemirror/addon/edit/closebrackets.js b/app/gui/html/vendor/codemirror/addon/edit/closebrackets.js
new file mode 100644
index 0000000..f48ad88
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/edit/closebrackets.js
@@ -0,0 +1,123 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  var DEFAULT_BRACKETS = "()[]{}''\"\"";
+  var DEFAULT_EXPLODE_ON_ENTER = "[]{}";
+  var SPACE_CHAR_REGEX = /\s/;
+
+  CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
+    if (old != CodeMirror.Init && old)
+      cm.removeKeyMap("autoCloseBrackets");
+    if (!val) return;
+    var pairs = DEFAULT_BRACKETS, explode = DEFAULT_EXPLODE_ON_ENTER;
+    if (typeof val == "string") pairs = val;
+    else if (typeof val == "object") {
+      if (val.pairs != null) pairs = val.pairs;
+      if (val.explode != null) explode = val.explode;
+    }
+    var map = buildKeymap(pairs);
+    if (explode) map.Enter = buildExplodeHandler(explode);
+    cm.addKeyMap(map);
+  });
+
+  function charsAround(cm, pos) {
+    var str = cm.getRange(CodeMirror.Pos(pos.line, pos.ch - 1),
+                          CodeMirror.Pos(pos.line, pos.ch + 1));
+    return str.length == 2 ? str : null;
+  }
+
+  function buildKeymap(pairs) {
+    var map = {
+      name : "autoCloseBrackets",
+      Backspace: function(cm) {
+        if (cm.getOption("disableInput")) return CodeMirror.Pass;
+        var ranges = cm.listSelections();
+        for (var i = 0; i < ranges.length; i++) {
+          if (!ranges[i].empty()) return CodeMirror.Pass;
+          var around = charsAround(cm, ranges[i].head);
+          if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
+        }
+        for (var i = ranges.length - 1; i >= 0; i--) {
+          var cur = ranges[i].head;
+          cm.replaceRange("", CodeMirror.Pos(cur.line, cur.ch - 1), CodeMirror.Pos(cur.line, cur.ch + 1));
+        }
+      }
+    };
+    var closingBrackets = "";
+    for (var i = 0; i < pairs.length; i += 2) (function(left, right) {
+      if (left != right) closingBrackets += right;
+      map["'" + left + "'"] = function(cm) {
+        if (cm.getOption("disableInput")) return CodeMirror.Pass;
+        var ranges = cm.listSelections(), type, next;
+        for (var i = 0; i < ranges.length; i++) {
+          var range = ranges[i], cur = range.head, curType;
+          if (left == "'" && cm.getTokenTypeAt(cur) == "comment")
+            return CodeMirror.Pass;
+          var next = cm.getRange(cur, CodeMirror.Pos(cur.line, cur.ch + 1));
+          if (!range.empty())
+            curType = "surround";
+          else if (left == right && next == right)
+            curType = "skip";
+          else if (left == right && CodeMirror.isWordChar(next))
+            return CodeMirror.Pass;
+          else if (cm.getLine(cur.line).length == cur.ch || closingBrackets.indexOf(next) >= 0 || SPACE_CHAR_REGEX.test(next))
+            curType = "both";
+          else
+            return CodeMirror.Pass;
+          if (!type) type = curType;
+          else if (type != curType) return CodeMirror.Pass;
+        }
+
+        if (type == "skip") {
+          cm.execCommand("goCharRight");
+        } else if (type == "surround") {
+          var sels = cm.getSelections();
+          for (var i = 0; i < sels.length; i++)
+            sels[i] = left + sels[i] + right;
+          cm.replaceSelections(sels, "around");
+        } else if (type == "both") {
+          cm.replaceSelection(left + right, null);
+          cm.execCommand("goCharLeft");
+        }
+      };
+      if (left != right) map["'" + right + "'"] = function(cm) {
+        var ranges = cm.listSelections();
+        for (var i = 0; i < ranges.length; i++) {
+          var range = ranges[i];
+          if (!range.empty() ||
+              cm.getRange(range.head, CodeMirror.Pos(range.head.line, range.head.ch + 1)) != right)
+            return CodeMirror.Pass;
+        }
+        cm.execCommand("goCharRight");
+      };
+    })(pairs.charAt(i), pairs.charAt(i + 1));
+    return map;
+  }
+
+  function buildExplodeHandler(pairs) {
+    return function(cm) {
+      if (cm.getOption("disableInput")) return CodeMirror.Pass;
+      var ranges = cm.listSelections();
+      for (var i = 0; i < ranges.length; i++) {
+        if (!ranges[i].empty()) return CodeMirror.Pass;
+        var around = charsAround(cm, ranges[i].head);
+        if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
+      }
+      cm.operation(function() {
+        cm.replaceSelection("\n\n", null);
+        cm.execCommand("goCharLeft");
+        ranges = cm.listSelections();
+        for (var i = 0; i < ranges.length; i++) {
+          var line = ranges[i].head.line;
+          cm.indentLine(line, null, true);
+          cm.indentLine(line + 1, null, true);
+        }
+      });
+    };
+  }
+});
diff --git a/app/gui/html/vendor/codemirror/addon/edit/closetag.js b/app/gui/html/vendor/codemirror/addon/edit/closetag.js
new file mode 100644
index 0000000..c7c0701
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/edit/closetag.js
@@ -0,0 +1,116 @@
+/**
+ * Tag-closer extension for CodeMirror.
+ *
+ * This extension adds an "autoCloseTags" option that can be set to
+ * either true to get the default behavior, or an object to further
+ * configure its behavior.
+ *
+ * These are supported options:
+ *
+ * `whenClosing` (default true)
+ *   Whether to autoclose when the '/' of a closing tag is typed.
+ * `whenOpening` (default true)
+ *   Whether to autoclose the tag when the final '>' of an opening
+ *   tag is typed.
+ * `dontCloseTags` (default is empty tags for HTML, none for XML)
+ *   An array of tag names that should not be autoclosed.
+ * `indentTags` (default is block tags for HTML, none for XML)
+ *   An array of tag names that should, when opened, cause a
+ *   blank line to be added inside the tag, and the blank line and
+ *   closing line to be indented.
+ *
+ * See demos/closetag.html for a usage example.
+ */
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("../fold/xml-fold"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "../fold/xml-fold"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) {
+    if (old != CodeMirror.Init && old)
+      cm.removeKeyMap("autoCloseTags");
+    if (!val) return;
+    var map = {name: "autoCloseTags"};
+    if (typeof val != "object" || val.whenClosing)
+      map["'/'"] = function(cm) { return autoCloseSlash(cm); };
+    if (typeof val != "object" || val.whenOpening)
+      map["'>'"] = function(cm) { return autoCloseGT(cm); };
+    cm.addKeyMap(map);
+  });
+
+  var htmlDontClose = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param",
+                       "source", "track", "wbr"];
+  var htmlIndent = ["applet", "blockquote", "body", "button", "div", "dl", "fieldset", "form", "frameset", "h1", "h2", "h3", "h4",
+                    "h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"];
+
+  function autoCloseGT(cm) {
+    if (cm.getOption("disableInput")) return CodeMirror.Pass;
+    var ranges = cm.listSelections(), replacements = [];
+    for (var i = 0; i < ranges.length; i++) {
+      if (!ranges[i].empty()) return CodeMirror.Pass;
+      var pos = ranges[i].head, tok = cm.getTokenAt(pos);
+      var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
+      if (inner.mode.name != "xml" || !state.tagName) return CodeMirror.Pass;
+      var opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html";
+      var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose);
+      var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent);
+
+      var tagName = state.tagName;
+      if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
+      var lowerTagName = tagName.toLowerCase();
+      // Don't process the '>' at the end of an end-tag or self-closing tag
+      if (!tagName ||
+          tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) ||
+          tok.type == "tag" && state.type == "closeTag" ||
+          tok.string.indexOf("/") == (tok.string.length - 1) || // match something like <someTagName />
+          dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1 ||
+          CodeMirror.scanForClosingTag && CodeMirror.scanForClosingTag(cm, pos, tagName,
+                                                                       Math.min(cm.lastLine() + 1, pos.line + 50)))
+        return CodeMirror.Pass;
+
+      var indent = indentTags && indexOf(indentTags, lowerTagName) > -1;
+      replacements[i] = {indent: indent,
+                         text: ">" + (indent ? "\n\n" : "") + "</" + tagName + ">",
+                         newPos: indent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1)};
+    }
+
+    for (var i = ranges.length - 1; i >= 0; i--) {
+      var info = replacements[i];
+      cm.replaceRange(info.text, ranges[i].head, ranges[i].anchor, "+insert");
+      var sel = cm.listSelections().slice(0);
+      sel[i] = {head: info.newPos, anchor: info.newPos};
+      cm.setSelections(sel);
+      if (info.indent) {
+        cm.indentLine(info.newPos.line, null, true);
+        cm.indentLine(info.newPos.line + 1, null, true);
+      }
+    }
+  }
+
+  function autoCloseSlash(cm) {
+    if (cm.getOption("disableInput")) return CodeMirror.Pass;
+    var ranges = cm.listSelections(), replacements = [];
+    for (var i = 0; i < ranges.length; i++) {
+      if (!ranges[i].empty()) return CodeMirror.Pass;
+      var pos = ranges[i].head, tok = cm.getTokenAt(pos);
+      var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
+      if (tok.type == "string" || tok.string.charAt(0) != "<" ||
+          tok.start != pos.ch - 1 || inner.mode.name != "xml" ||
+          !state.context || !state.context.tagName)
+        return CodeMirror.Pass;
+      replacements[i] = "/" + state.context.tagName + ">";
+    }
+    cm.replaceSelections(replacements);
+  }
+
+  function indexOf(collection, elt) {
+    if (collection.indexOf) return collection.indexOf(elt);
+    for (var i = 0, e = collection.length; i < e; ++i)
+      if (collection[i] == elt) return i;
+    return -1;
+  }
+});
diff --git a/app/gui/html/vendor/codemirror/addon/edit/continuelist.js b/app/gui/html/vendor/codemirror/addon/edit/continuelist.js
new file mode 100644
index 0000000..2946aa6
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/edit/continuelist.js
@@ -0,0 +1,35 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var listRE = /^(\s*)([*+-]|(\d+)\.)(\s*)/,
+      unorderedBullets = "*+-";
+
+  CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) {
+    if (cm.getOption("disableInput")) return CodeMirror.Pass;
+    var ranges = cm.listSelections(), replacements = [];
+    for (var i = 0; i < ranges.length; i++) {
+      var pos = ranges[i].head, match;
+      var inList = cm.getStateAfter(pos.line).list !== false;
+
+      if (!ranges[i].empty() || !inList || !(match = cm.getLine(pos.line).match(listRE))) {
+        cm.execCommand("newlineAndIndent");
+        return;
+      }
+      var indent = match[1], after = match[4];
+      var bullet = unorderedBullets.indexOf(match[2]) >= 0
+        ? match[2]
+        : (parseInt(match[3], 10) + 1) + ".";
+
+      replacements[i] = "\n" + indent + bullet + after;
+    }
+
+    cm.replaceSelections(replacements);
+  };
+});
diff --git a/app/gui/html/vendor/codemirror/addon/edit/matchbrackets.js b/app/gui/html/vendor/codemirror/addon/edit/matchbrackets.js
new file mode 100644
index 0000000..576ec14
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/edit/matchbrackets.js
@@ -0,0 +1,108 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
+    (document.documentMode == null || document.documentMode < 8);
+
+  var Pos = CodeMirror.Pos;
+
+  var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
+
+  function findMatchingBracket(cm, where, strict, config) {
+    var line = cm.getLineHandle(where.line), pos = where.ch - 1;
+    var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
+    if (!match) return null;
+    var dir = match.charAt(1) == ">" ? 1 : -1;
+    if (strict && (dir > 0) != (pos == where.ch)) return null;
+    var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
+
+    var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
+    return {from: Pos(where.line, pos), to: found && found.pos,
+            match: found && found.ch == match.charAt(0), forward: dir > 0};
+  }
+
+  function scanForBracket(cm, where, dir, style, config) {
+    var maxScanLen = (config && config.maxScanLineLength) || 10000;
+    var maxScanLines = (config && config.maxScanLines) || 500;
+
+    var stack = [], re = /[(){}[\]]/;
+    var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
+                          : Math.max(cm.firstLine() - 1, where.line - maxScanLines);
+    for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
+      var line = cm.getLine(lineNo);
+      if (!line) continue;
+      var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;
+      if (line.length > maxScanLen) continue;
+      if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
+      for (; pos != end; pos += dir) {
+        var ch = line.charAt(pos);
+        if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
+          var match = matching[ch];
+          if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
+          else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
+          else stack.pop();
+        }
+      }
+    }
+  }
+
+  function matchBrackets(cm, autoclear, config) {
+    // Disable brace matching in long lines, since it'll cause hugely slow updates
+    var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
+    var marks = [], ranges = cm.listSelections();
+    for (var i = 0; i < ranges.length; i++) {
+      var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config);
+      if (match && cm.getLine(match.from.line).length <= maxHighlightLen &&
+          match.to && cm.getLine(match.to.line).length <= maxHighlightLen) {
+        var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
+        marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
+        if (match.to)
+          marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
+      }
+    }
+
+    if (marks.length) {
+      // Kludge to work around the IE bug from issue #1193, where text
+      // input stops going to the textare whever this fires.
+      if (ie_lt8 && cm.state.focused) cm.display.input.focus();
+
+      var clear = function() {
+        cm.operation(function() {
+          for (var i = 0; i < marks.length; i++) marks[i].clear();
+        });
+      };
+      if (autoclear) setTimeout(clear, 800);
+      else return clear;
+    }
+  }
+
+  var currentlyHighlighted = null;
+  function doMatchBrackets(cm) {
+    cm.operation(function() {
+      if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
+      currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
+    });
+  }
+
+  CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
+    if (old && old != CodeMirror.Init)
+      cm.off("cursorActivity", doMatchBrackets);
+    if (val) {
+      cm.state.matchBrackets = typeof val == "object" ? val : {};
+      cm.on("cursorActivity", doMatchBrackets);
+    }
+  });
+
+  CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
+  CodeMirror.defineExtension("findMatchingBracket", function(pos, strict){
+    return findMatchingBracket(this, pos, strict);
+  });
+  CodeMirror.defineExtension("scanForBracket", function(pos, dir, style){
+    return scanForBracket(this, pos, dir, style);
+  });
+});
diff --git a/app/gui/html/vendor/codemirror/addon/edit/matchtags.js b/app/gui/html/vendor/codemirror/addon/edit/matchtags.js
new file mode 100644
index 0000000..76a7b87
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/edit/matchtags.js
@@ -0,0 +1,63 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("../fold/xml-fold"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "../fold/xml-fold"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  CodeMirror.defineOption("matchTags", false, function(cm, val, old) {
+    if (old && old != CodeMirror.Init) {
+      cm.off("cursorActivity", doMatchTags);
+      cm.off("viewportChange", maybeUpdateMatch);
+      clear(cm);
+    }
+    if (val) {
+      cm.state.matchBothTags = typeof val == "object" && val.bothTags;
+      cm.on("cursorActivity", doMatchTags);
+      cm.on("viewportChange", maybeUpdateMatch);
+      doMatchTags(cm);
+    }
+  });
+
+  function clear(cm) {
+    if (cm.state.tagHit) cm.state.tagHit.clear();
+    if (cm.state.tagOther) cm.state.tagOther.clear();
+    cm.state.tagHit = cm.state.tagOther = null;
+  }
+
+  function doMatchTags(cm) {
+    cm.state.failedTagMatch = false;
+    cm.operation(function() {
+      clear(cm);
+      if (cm.somethingSelected()) return;
+      var cur = cm.getCursor(), range = cm.getViewport();
+      range.from = Math.min(range.from, cur.line); range.to = Math.max(cur.line + 1, range.to);
+      var match = CodeMirror.findMatchingTag(cm, cur, range);
+      if (!match) return;
+      if (cm.state.matchBothTags) {
+        var hit = match.at == "open" ? match.open : match.close;
+        if (hit) cm.state.tagHit = cm.markText(hit.from, hit.to, {className: "CodeMirror-matchingtag"});
+      }
+      var other = match.at == "close" ? match.open : match.close;
+      if (other)
+        cm.state.tagOther = cm.markText(other.from, other.to, {className: "CodeMirror-matchingtag"});
+      else
+        cm.state.failedTagMatch = true;
+    });
+  }
+
+  function maybeUpdateMatch(cm) {
+    if (cm.state.failedTagMatch) doMatchTags(cm);
+  }
+
+  CodeMirror.commands.toMatchingTag = function(cm) {
+    var found = CodeMirror.findMatchingTag(cm, cm.getCursor());
+    if (found) {
+      var other = found.at == "close" ? found.open : found.close;
+      if (other) cm.extendSelection(other.to, other.from);
+    }
+  };
+});
diff --git a/app/gui/html/vendor/codemirror/addon/edit/trailingspace.js b/app/gui/html/vendor/codemirror/addon/edit/trailingspace.js
new file mode 100644
index 0000000..ec07221
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/edit/trailingspace.js
@@ -0,0 +1,24 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) {
+    if (prev == CodeMirror.Init) prev = false;
+    if (prev && !val)
+      cm.removeOverlay("trailingspace");
+    else if (!prev && val)
+      cm.addOverlay({
+        token: function(stream) {
+          for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {}
+          if (i > stream.pos) { stream.pos = i; return null; }
+          stream.pos = l;
+          return "trailingspace";
+        },
+        name: "trailingspace"
+      });
+  });
+});
diff --git a/app/gui/html/vendor/codemirror/addon/fold/brace-fold.js b/app/gui/html/vendor/codemirror/addon/fold/brace-fold.js
new file mode 100644
index 0000000..f0ee620
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/fold/brace-fold.js
@@ -0,0 +1,102 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.registerHelper("fold", "brace", function(cm, start) {
+  var line = start.line, lineText = cm.getLine(line);
+  var startCh, tokenType;
+
+  function findOpening(openCh) {
+    for (var at = start.ch, pass = 0;;) {
+      var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1);
+      if (found == -1) {
+        if (pass == 1) break;
+        pass = 1;
+        at = lineText.length;
+        continue;
+      }
+      if (pass == 1 && found < start.ch) break;
+      tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));
+      if (!/^(comment|string)/.test(tokenType)) return found + 1;
+      at = found - 1;
+    }
+  }
+
+  var startToken = "{", endToken = "}", startCh = findOpening("{");
+  if (startCh == null) {
+    startToken = "[", endToken = "]";
+    startCh = findOpening("[");
+  }
+
+  if (startCh == null) return;
+  var count = 1, lastLine = cm.lastLine(), end, endCh;
+  outer: for (var i = line; i <= lastLine; ++i) {
+    var text = cm.getLine(i), pos = i == line ? startCh : 0;
+    for (;;) {
+      var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);
+      if (nextOpen < 0) nextOpen = text.length;
+      if (nextClose < 0) nextClose = text.length;
+      pos = Math.min(nextOpen, nextClose);
+      if (pos == text.length) break;
+      if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) {
+        if (pos == nextOpen) ++count;
+        else if (!--count) { end = i; endCh = pos; break outer; }
+      }
+      ++pos;
+    }
+  }
+  if (end == null || line == end && endCh == startCh) return;
+  return {from: CodeMirror.Pos(line, startCh),
+          to: CodeMirror.Pos(end, endCh)};
+});
+
+CodeMirror.registerHelper("fold", "import", function(cm, start) {
+  function hasImport(line) {
+    if (line < cm.firstLine() || line > cm.lastLine()) return null;
+    var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
+    if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
+    if (start.type != "keyword" || start.string != "import") return null;
+    // Now find closing semicolon, return its position
+    for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) {
+      var text = cm.getLine(i), semi = text.indexOf(";");
+      if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)};
+    }
+  }
+
+  var start = start.line, has = hasImport(start), prev;
+  if (!has || hasImport(start - 1) || ((prev = hasImport(start - 2)) && prev.end.line == start - 1))
+    return null;
+  for (var end = has.end;;) {
+    var next = hasImport(end.line + 1);
+    if (next == null) break;
+    end = next.end;
+  }
+  return {from: cm.clipPos(CodeMirror.Pos(start, has.startCh + 1)), to: end};
+});
+
+CodeMirror.registerHelper("fold", "include", function(cm, start) {
+  function hasInclude(line) {
+    if (line < cm.firstLine() || line > cm.lastLine()) return null;
+    var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
+    if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
+    if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8;
+  }
+
+  var start = start.line, has = hasInclude(start);
+  if (has == null || hasInclude(start - 1) != null) return null;
+  for (var end = start;;) {
+    var next = hasInclude(end + 1);
+    if (next == null) break;
+    ++end;
+  }
+  return {from: CodeMirror.Pos(start, has + 1),
+          to: cm.clipPos(CodeMirror.Pos(end))};
+});
+
+});
diff --git a/app/gui/html/vendor/codemirror/addon/fold/comment-fold.js b/app/gui/html/vendor/codemirror/addon/fold/comment-fold.js
new file mode 100644
index 0000000..d72c547
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/fold/comment-fold.js
@@ -0,0 +1,54 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.registerGlobalHelper("fold", "comment", function(mode) {
+  return mode.blockCommentStart && mode.blockCommentEnd;
+}, function(cm, start) {
+  var mode = cm.getModeAt(start), startToken = mode.blockCommentStart, endToken = mode.blockCommentEnd;
+  if (!startToken || !endToken) return;
+  var line = start.line, lineText = cm.getLine(line);
+
+  var startCh;
+  for (var at = start.ch, pass = 0;;) {
+    var found = at <= 0 ? -1 : lineText.lastIndexOf(startToken, at - 1);
+    if (found == -1) {
+      if (pass == 1) return;
+      pass = 1;
+      at = lineText.length;
+      continue;
+    }
+    if (pass == 1 && found < start.ch) return;
+    if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)))) {
+      startCh = found + startToken.length;
+      break;
+    }
+    at = found - 1;
+  }
+
+  var depth = 1, lastLine = cm.lastLine(), end, endCh;
+  outer: for (var i = line; i <= lastLine; ++i) {
+    var text = cm.getLine(i), pos = i == line ? startCh : 0;
+    for (;;) {
+      var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);
+      if (nextOpen < 0) nextOpen = text.length;
+      if (nextClose < 0) nextClose = text.length;
+      pos = Math.min(nextOpen, nextClose);
+      if (pos == text.length) break;
+      if (pos == nextOpen) ++depth;
+      else if (!--depth) { end = i; endCh = pos; break outer; }
+      ++pos;
+    }
+  }
+  if (end == null || line == end && endCh == startCh) return;
+  return {from: CodeMirror.Pos(line, startCh),
+          to: CodeMirror.Pos(end, endCh)};
+});
+
+});
diff --git a/app/gui/html/vendor/codemirror/addon/fold/foldcode.js b/app/gui/html/vendor/codemirror/addon/fold/foldcode.js
new file mode 100644
index 0000000..d7a0bb5
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/fold/foldcode.js
@@ -0,0 +1,117 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  function doFold(cm, pos, options, force) {
+    var finder = options && (options.call ? options : options.rangeFinder);
+    if (!finder) finder = CodeMirror.fold.auto;
+    if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0);
+    var minSize = options && options.minFoldSize || 0;
+
+    function getRange(allowFolded) {
+      var range = finder(cm, pos);
+      if (!range || range.to.line - range.from.line < minSize) return null;
+      var marks = cm.findMarksAt(range.from);
+      for (var i = 0; i < marks.length; ++i) {
+        if (marks[i].__isFold && force !== "fold") {
+          if (!allowFolded) return null;
+          range.cleared = true;
+          marks[i].clear();
+        }
+      }
+      return range;
+    }
+
+    var range = getRange(true);
+    if (options && options.scanUp) while (!range && pos.line > cm.firstLine()) {
+      pos = CodeMirror.Pos(pos.line - 1, 0);
+      range = getRange(false);
+    }
+    if (!range || range.cleared || force === "unfold") return;
+
+    var myWidget = makeWidget(options);
+    CodeMirror.on(myWidget, "mousedown", function() { myRange.clear(); });
+    var myRange = cm.markText(range.from, range.to, {
+      replacedWith: myWidget,
+      clearOnEnter: true,
+      __isFold: true
+    });
+    myRange.on("clear", function(from, to) {
+      CodeMirror.signal(cm, "unfold", cm, from, to);
+    });
+    CodeMirror.signal(cm, "fold", cm, range.from, range.to);
+  }
+
+  function makeWidget(options) {
+    var widget = (options && options.widget) || "\u2194";
+    if (typeof widget == "string") {
+      var text = document.createTextNode(widget);
+      widget = document.createElement("span");
+      widget.appendChild(text);
+      widget.className = "CodeMirror-foldmarker";
+    }
+    return widget;
+  }
+
+  // Clumsy backwards-compatible interface
+  CodeMirror.newFoldFunction = function(rangeFinder, widget) {
+    return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); };
+  };
+
+  // New-style interface
+  CodeMirror.defineExtension("foldCode", function(pos, options, force) {
+    doFold(this, pos, options, force);
+  });
+
+  CodeMirror.defineExtension("isFolded", function(pos) {
+    var marks = this.findMarksAt(pos);
+    for (var i = 0; i < marks.length; ++i)
+      if (marks[i].__isFold) return true;
+  });
+
+  CodeMirror.commands.toggleFold = function(cm) {
+    cm.foldCode(cm.getCursor());
+  };
+  CodeMirror.commands.fold = function(cm) {
+    cm.foldCode(cm.getCursor(), null, "fold");
+  };
+  CodeMirror.commands.unfold = function(cm) {
+    cm.foldCode(cm.getCursor(), null, "unfold");
+  };
+  CodeMirror.commands.foldAll = function(cm) {
+    cm.operation(function() {
+      for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
+        cm.foldCode(CodeMirror.Pos(i, 0), null, "fold");
+    });
+  };
+  CodeMirror.commands.unfoldAll = function(cm) {
+    cm.operation(function() {
+      for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
+        cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold");
+    });
+  };
+
+  CodeMirror.registerHelper("fold", "combine", function() {
+    var funcs = Array.prototype.slice.call(arguments, 0);
+    return function(cm, start) {
+      for (var i = 0; i < funcs.length; ++i) {
+        var found = funcs[i](cm, start);
+        if (found) return found;
+      }
+    };
+  });
+
+  CodeMirror.registerHelper("fold", "auto", function(cm, start) {
+    var helpers = cm.getHelpers(start, "fold");
+    for (var i = 0; i < helpers.length; i++) {
+      var cur = helpers[i](cm, start);
+      if (cur) return cur;
+    }
+  });
+});
diff --git a/app/gui/html/vendor/codemirror/addon/fold/foldgutter.css b/app/gui/html/vendor/codemirror/addon/fold/foldgutter.css
new file mode 100644
index 0000000..4980539
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/fold/foldgutter.css
@@ -0,0 +1,21 @@
+.CodeMirror-foldmarker {
+  color: blue;
+  text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px;
+  font-family: arial;
+  line-height: .3;
+  cursor: pointer;
+}
+.CodeMirror-foldgutter {
+  width: .7em;
+}
+.CodeMirror-foldgutter-open,
+.CodeMirror-foldgutter-folded {
+  color: #555;
+  cursor: pointer;
+}
+.CodeMirror-foldgutter-open:after {
+  content: "\25BE";
+}
+.CodeMirror-foldgutter-folded:after {
+  content: "\25B8";
+}
diff --git a/app/gui/html/vendor/codemirror/addon/fold/foldgutter.js b/app/gui/html/vendor/codemirror/addon/fold/foldgutter.js
new file mode 100644
index 0000000..9caba59
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/fold/foldgutter.js
@@ -0,0 +1,131 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("./foldcode"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "./foldcode"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  CodeMirror.defineOption("foldGutter", false, function(cm, val, old) {
+    if (old && old != CodeMirror.Init) {
+      cm.clearGutter(cm.state.foldGutter.options.gutter);
+      cm.state.foldGutter = null;
+      cm.off("gutterClick", onGutterClick);
+      cm.off("change", onChange);
+      cm.off("viewportChange", onViewportChange);
+      cm.off("fold", onFold);
+      cm.off("unfold", onFold);
+      cm.off("swapDoc", updateInViewport);
+    }
+    if (val) {
+      cm.state.foldGutter = new State(parseOptions(val));
+      updateInViewport(cm);
+      cm.on("gutterClick", onGutterClick);
+      cm.on("change", onChange);
+      cm.on("viewportChange", onViewportChange);
+      cm.on("fold", onFold);
+      cm.on("unfold", onFold);
+      cm.on("swapDoc", updateInViewport);
+    }
+  });
+
+  var Pos = CodeMirror.Pos;
+
+  function State(options) {
+    this.options = options;
+    this.from = this.to = 0;
+  }
+
+  function parseOptions(opts) {
+    if (opts === true) opts = {};
+    if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter";
+    if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open";
+    if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded";
+    return opts;
+  }
+
+  function isFolded(cm, line) {
+    var marks = cm.findMarksAt(Pos(line));
+    for (var i = 0; i < marks.length; ++i)
+      if (marks[i].__isFold && marks[i].find().from.line == line) return true;
+  }
+
+  function marker(spec) {
+    if (typeof spec == "string") {
+      var elt = document.createElement("div");
+      elt.className = spec;
+      return elt;
+    } else {
+      return spec.cloneNode(true);
+    }
+  }
+
+  function updateFoldInfo(cm, from, to) {
+    var opts = cm.state.foldGutter.options, cur = from;
+    cm.eachLine(from, to, function(line) {
+      var mark = null;
+      if (isFolded(cm, cur)) {
+        mark = marker(opts.indicatorFolded);
+      } else {
+        var pos = Pos(cur, 0), func = opts.rangeFinder || CodeMirror.fold.auto;
+        var range = func && func(cm, pos);
+        if (range && range.from.line + 1 < range.to.line)
+          mark = marker(opts.indicatorOpen);
+      }
+      cm.setGutterMarker(line, opts.gutter, mark);
+      ++cur;
+    });
+  }
+
+  function updateInViewport(cm) {
+    var vp = cm.getViewport(), state = cm.state.foldGutter;
+    if (!state) return;
+    cm.operation(function() {
+      updateFoldInfo(cm, vp.from, vp.to);
+    });
+    state.from = vp.from; state.to = vp.to;
+  }
+
+  function onGutterClick(cm, line, gutter) {
+    var opts = cm.state.foldGutter.options;
+    if (gutter != opts.gutter) return;
+    cm.foldCode(Pos(line, 0), opts.rangeFinder);
+  }
+
+  function onChange(cm) {
+    var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
+    state.from = state.to = 0;
+    clearTimeout(state.changeUpdate);
+    state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
+  }
+
+  function onViewportChange(cm) {
+    var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
+    clearTimeout(state.changeUpdate);
+    state.changeUpdate = setTimeout(function() {
+      var vp = cm.getViewport();
+      if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {
+        updateInViewport(cm);
+      } else {
+        cm.operation(function() {
+          if (vp.from < state.from) {
+            updateFoldInfo(cm, vp.from, state.from);
+            state.from = vp.from;
+          }
+          if (vp.to > state.to) {
+            updateFoldInfo(cm, state.to, vp.to);
+            state.to = vp.to;
+          }
+        });
+      }
+    }, opts.updateViewportTimeSpan || 400);
+  }
+
+  function onFold(cm, from) {
+    var state = cm.state.foldGutter, line = from.line;
+    if (line >= state.from && line < state.to)
+      updateFoldInfo(cm, line, line + 1);
+  }
+});
diff --git a/app/gui/html/vendor/codemirror/addon/fold/indent-fold.js b/app/gui/html/vendor/codemirror/addon/fold/indent-fold.js
new file mode 100644
index 0000000..d013083
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/fold/indent-fold.js
@@ -0,0 +1,41 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.registerHelper("fold", "indent", function(cm, start) {
+  var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line);
+  if (!/\S/.test(firstLine)) return;
+  var getIndent = function(line) {
+    return CodeMirror.countColumn(line, null, tabSize);
+  };
+  var myIndent = getIndent(firstLine);
+  var lastLineInFold = null;
+  // Go through lines until we find a line that definitely doesn't belong in
+  // the block we're folding, or to the end.
+  for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) {
+    var curLine = cm.getLine(i);
+    var curIndent = getIndent(curLine);
+    if (curIndent > myIndent) {
+      // Lines with a greater indent are considered part of the block.
+      lastLineInFold = i;
+    } else if (!/\S/.test(curLine)) {
+      // Empty lines might be breaks within the block we're trying to fold.
+    } else {
+      // A non-empty line at an indent equal to or less than ours marks the
+      // start of another block.
+      break;
+    }
+  }
+  if (lastLineInFold) return {
+    from: CodeMirror.Pos(start.line, firstLine.length),
+    to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length)
+  };
+});
+
+});
diff --git a/app/gui/html/vendor/codemirror/addon/fold/markdown-fold.js b/app/gui/html/vendor/codemirror/addon/fold/markdown-fold.js
new file mode 100644
index 0000000..3bbf5b6
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/fold/markdown-fold.js
@@ -0,0 +1,46 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.registerHelper("fold", "markdown", function(cm, start) {
+  var maxDepth = 100;
+
+  function isHeader(lineNo) {
+    var tokentype = cm.getTokenTypeAt(CodeMirror.Pos(lineNo, 0));
+    return tokentype && /\bheader\b/.test(tokentype);
+  }
+
+  function headerLevel(lineNo, line, nextLine) {
+    var match = line && line.match(/^#+/);
+    if (match && isHeader(lineNo)) return match[0].length;
+    match = nextLine && nextLine.match(/^[=\-]+\s*$/);
+    if (match && isHeader(lineNo + 1)) return nextLine[0] == "=" ? 1 : 2;
+    return maxDepth;
+  }
+
+  var firstLine = cm.getLine(start.line), nextLine = cm.getLine(start.line + 1);
+  var level = headerLevel(start.line, firstLine, nextLine);
+  if (level === maxDepth) return undefined;
+
+  var lastLineNo = cm.lastLine();
+  var end = start.line, nextNextLine = cm.getLine(end + 2);
+  while (end < lastLineNo) {
+    if (headerLevel(end + 1, nextLine, nextNextLine) <= level) break;
+    ++end;
+    nextLine = nextNextLine;
+    nextNextLine = cm.getLine(end + 2);
+  }
+
+  return {
+    from: CodeMirror.Pos(start.line, firstLine.length),
+    to: CodeMirror.Pos(end, cm.getLine(end).length)
+  };
+});
+
+});
diff --git a/app/gui/html/vendor/codemirror/addon/fold/xml-fold.js b/app/gui/html/vendor/codemirror/addon/fold/xml-fold.js
new file mode 100644
index 0000000..d554e2f
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/fold/xml-fold.js
@@ -0,0 +1,178 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var Pos = CodeMirror.Pos;
+  function cmp(a, b) { return a.line - b.line || a.ch - b.ch; }
+
+  var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
+  var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
+  var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g");
+
+  function Iter(cm, line, ch, range) {
+    this.line = line; this.ch = ch;
+    this.cm = cm; this.text = cm.getLine(line);
+    this.min = range ? range.from : cm.firstLine();
+    this.max = range ? range.to - 1 : cm.lastLine();
+  }
+
+  function tagAt(iter, ch) {
+    var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch));
+    return type && /\btag\b/.test(type);
+  }
+
+  function nextLine(iter) {
+    if (iter.line >= iter.max) return;
+    iter.ch = 0;
+    iter.text = iter.cm.getLine(++iter.line);
+    return true;
+  }
+  function prevLine(iter) {
+    if (iter.line <= iter.min) return;
+    iter.text = iter.cm.getLine(--iter.line);
+    iter.ch = iter.text.length;
+    return true;
+  }
+
+  function toTagEnd(iter) {
+    for (;;) {
+      var gt = iter.text.indexOf(">", iter.ch);
+      if (gt == -1) { if (nextLine(iter)) continue; else return; }
+      if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; }
+      var lastSlash = iter.text.lastIndexOf("/", gt);
+      var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt));
+      iter.ch = gt + 1;
+      return selfClose ? "selfClose" : "regular";
+    }
+  }
+  function toTagStart(iter) {
+    for (;;) {
+      var lt = iter.ch ? iter.text.lastIndexOf("<", iter.ch - 1) : -1;
+      if (lt == -1) { if (prevLine(iter)) continue; else return; }
+      if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; }
+      xmlTagStart.lastIndex = lt;
+      iter.ch = lt;
+      var match = xmlTagStart.exec(iter.text);
+      if (match && match.index == lt) return match;
+    }
+  }
+
+  function toNextTag(iter) {
+    for (;;) {
+      xmlTagStart.lastIndex = iter.ch;
+      var found = xmlTagStart.exec(iter.text);
+      if (!found) { if (nextLine(iter)) continue; else return; }
+      if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; }
+      iter.ch = found.index + found[0].length;
+      return found;
+    }
+  }
+  function toPrevTag(iter) {
+    for (;;) {
+      var gt = iter.ch ? iter.text.lastIndexOf(">", iter.ch - 1) : -1;
+      if (gt == -1) { if (prevLine(iter)) continue; else return; }
+      if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; }
+      var lastSlash = iter.text.lastIndexOf("/", gt);
+      var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt));
+      iter.ch = gt + 1;
+      return selfClose ? "selfClose" : "regular";
+    }
+  }
+
+  function findMatchingClose(iter, tag) {
+    var stack = [];
+    for (;;) {
+      var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0);
+      if (!next || !(end = toTagEnd(iter))) return;
+      if (end == "selfClose") continue;
+      if (next[1]) { // closing tag
+        for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) {
+          stack.length = i;
+          break;
+        }
+        if (i < 0 && (!tag || tag == next[2])) return {
+          tag: next[2],
+          from: Pos(startLine, startCh),
+          to: Pos(iter.line, iter.ch)
+        };
+      } else { // opening tag
+        stack.push(next[2]);
+      }
+    }
+  }
+  function findMatchingOpen(iter, tag) {
+    var stack = [];
+    for (;;) {
+      var prev = toPrevTag(iter);
+      if (!prev) return;
+      if (prev == "selfClose") { toTagStart(iter); continue; }
+      var endLine = iter.line, endCh = iter.ch;
+      var start = toTagStart(iter);
+      if (!start) return;
+      if (start[1]) { // closing tag
+        stack.push(start[2]);
+      } else { // opening tag
+        for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) {
+          stack.length = i;
+          break;
+        }
+        if (i < 0 && (!tag || tag == start[2])) return {
+          tag: start[2],
+          from: Pos(iter.line, iter.ch),
+          to: Pos(endLine, endCh)
+        };
+      }
+    }
+  }
+
+  CodeMirror.registerHelper("fold", "xml", function(cm, start) {
+    var iter = new Iter(cm, start.line, 0);
+    for (;;) {
+      var openTag = toNextTag(iter), end;
+      if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return;
+      if (!openTag[1] && end != "selfClose") {
+        var start = Pos(iter.line, iter.ch);
+        var close = findMatchingClose(iter, openTag[2]);
+        return close && {from: start, to: close.from};
+      }
+    }
+  });
+  CodeMirror.findMatchingTag = function(cm, pos, range) {
+    var iter = new Iter(cm, pos.line, pos.ch, range);
+    if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return;
+    var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch);
+    var start = end && toTagStart(iter);
+    if (!end || end == "selfClose" || !start || cmp(iter, pos) > 0) return;
+    var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]};
+
+    if (start[1]) { // closing tag
+      return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"};
+    } else { // opening tag
+      iter = new Iter(cm, to.line, to.ch, range);
+      return {open: here, close: findMatchingClose(iter, start[2]), at: "open"};
+    }
+  };
+
+  CodeMirror.findEnclosingTag = function(cm, pos, range) {
+    var iter = new Iter(cm, pos.line, pos.ch, range);
+    for (;;) {
+      var open = findMatchingOpen(iter);
+      if (!open) break;
+      var forward = new Iter(cm, pos.line, pos.ch, range);
+      var close = findMatchingClose(forward, open.tag);
+      if (close) return {open: open, close: close};
+    }
+  };
+
+  // Used by addon/edit/closetag.js
+  CodeMirror.scanForClosingTag = function(cm, pos, name, end) {
+    var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null);
+    return !!findMatchingClose(iter, name);
+  };
+});
diff --git a/app/gui/html/vendor/codemirror/addon/hint/anyword-hint.js b/app/gui/html/vendor/codemirror/addon/hint/anyword-hint.js
new file mode 100644
index 0000000..3ef979b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/hint/anyword-hint.js
@@ -0,0 +1,39 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var WORD = /[\w$]+/, RANGE = 500;
+
+  CodeMirror.registerHelper("hint", "anyword", function(editor, options) {
+    var word = options && options.word || WORD;
+    var range = options && options.range || RANGE;
+    var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
+    var start = cur.ch, end = start;
+    while (end < curLine.length && word.test(curLine.charAt(end))) ++end;
+    while (start && word.test(curLine.charAt(start - 1))) --start;
+    var curWord = start != end && curLine.slice(start, end);
+
+    var list = [], seen = {};
+    var re = new RegExp(word.source, "g");
+    for (var dir = -1; dir <= 1; dir += 2) {
+      var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
+      for (; line != endLine; line += dir) {
+        var text = editor.getLine(line), m;
+        while (m = re.exec(text)) {
+          if (line == cur.line && m[0] === curWord) continue;
+          if ((!curWord || m[0].lastIndexOf(curWord, 0) == 0) && !Object.prototype.hasOwnProperty.call(seen, m[0])) {
+            seen[m[0]] = true;
+            list.push(m[0]);
+          }
+        }
+      }
+    }
+    return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
+  });
+});
diff --git a/app/gui/html/vendor/codemirror/addon/hint/css-hint.js b/app/gui/html/vendor/codemirror/addon/hint/css-hint.js
new file mode 100644
index 0000000..9e5b1e1
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/hint/css-hint.js
@@ -0,0 +1,53 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("../../mode/css/css"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "../../mode/css/css"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1,
+                       "first-letter": 1, "first-line": 1, "first-child": 1,
+                       before: 1, after: 1, lang: 1};
+
+  CodeMirror.registerHelper("hint", "css", function(cm) {
+    var cur = cm.getCursor(), token = cm.getTokenAt(cur);
+    var inner = CodeMirror.innerMode(cm.getMode(), token.state);
+    if (inner.mode.name != "css") return;
+
+    var word = token.string, start = token.start, end = token.end;
+    if (/[^\w$_-]/.test(word)) {
+      word = ""; start = end = cur.ch;
+    }
+
+    var spec = CodeMirror.resolveMode("text/css");
+
+    var result = [];
+    function add(keywords) {
+      for (var name in keywords)
+        if (!word || name.lastIndexOf(word, 0) == 0)
+          result.push(name);
+    }
+
+    var st = token.state.state;
+    if (st == "pseudo" || token.type == "variable-3") {
+      add(pseudoClasses);
+    } else if (st == "block" || st == "maybeprop") {
+      add(spec.propertyKeywords);
+    } else if (st == "prop" || st == "parens" || st == "at" || st == "params") {
+      add(spec.valueKeywords);
+      add(spec.colorKeywords);
+    } else if (st == "media" || st == "media_parens") {
+      add(spec.mediaTypes);
+      add(spec.mediaFeatures);
+    }
+
+    if (result.length) return {
+      list: result,
+      from: CodeMirror.Pos(cur.line, start),
+      to: CodeMirror.Pos(cur.line, end)
+    };
+  });
+});
diff --git a/app/gui/html/vendor/codemirror/addon/hint/html-hint.js b/app/gui/html/vendor/codemirror/addon/hint/html-hint.js
new file mode 100755
index 0000000..cbe7c61
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/hint/html-hint.js
@@ -0,0 +1,345 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var langs = "ab aa af ak sq am ar an hy as av ae ay az bm ba eu be bn bh bi bs br bg my ca ch ce ny zh cv kw co cr hr cs da dv nl dz en eo et ee fo fj fi fr ff gl ka de el gn gu ht ha he hz hi ho hu ia id ie ga ig ik io is it iu ja jv kl kn kr ks kk km ki rw ky kv kg ko ku kj la lb lg li ln lo lt lu lv gv mk mg ms ml mt mi mr mh mn na nv nb nd ne ng nn no ii nr oc oj cu om or os pa pi fa pl ps pt qu rm rn ro ru sa sc sd se sm sg sr gd sn si sk sl so st es su sw ss sv ta te tg th ti bo tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa cy wo fy xh yi yo za zu".split(" ");
+  var targets = ["_blank", "_self", "_top", "_parent"];
+  var charsets = ["ascii", "utf-8", "utf-16", "latin1", "latin1"];
+  var methods = ["get", "post", "put", "delete"];
+  var encs = ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"];
+  var media = ["all", "screen", "print", "embossed", "braille", "handheld", "print", "projection", "screen", "tty", "tv", "speech",
+               "3d-glasses", "resolution [>][<][=] [X]", "device-aspect-ratio: X/Y", "orientation:portrait",
+               "orientation:landscape", "device-height: [X]", "device-width: [X]"];
+  var s = { attrs: {} }; // Simple tag, reused for a whole lot of tags
+
+  var data = {
+    a: {
+      attrs: {
+        href: null, ping: null, type: null,
+        media: media,
+        target: targets,
+        hreflang: langs
+      }
+    },
+    abbr: s,
+    acronym: s,
+    address: s,
+    applet: s,
+    area: {
+      attrs: {
+        alt: null, coords: null, href: null, target: null, ping: null,
+        media: media, hreflang: langs, type: null,
+        shape: ["default", "rect", "circle", "poly"]
+      }
+    },
+    article: s,
+    aside: s,
+    audio: {
+      attrs: {
+        src: null, mediagroup: null,
+        crossorigin: ["anonymous", "use-credentials"],
+        preload: ["none", "metadata", "auto"],
+        autoplay: ["", "autoplay"],
+        loop: ["", "loop"],
+        controls: ["", "controls"]
+      }
+    },
+    b: s,
+    base: { attrs: { href: null, target: targets } },
+    basefont: s,
+    bdi: s,
+    bdo: s,
+    big: s,
+    blockquote: { attrs: { cite: null } },
+    body: s,
+    br: s,
+    button: {
+      attrs: {
+        form: null, formaction: null, name: null, value: null,
+        autofocus: ["", "autofocus"],
+        disabled: ["", "autofocus"],
+        formenctype: encs,
+        formmethod: methods,
+        formnovalidate: ["", "novalidate"],
+        formtarget: targets,
+        type: ["submit", "reset", "button"]
+      }
+    },
+    canvas: { attrs: { width: null, height: null } },
+    caption: s,
+    center: s,
+    cite: s,
+    code: s,
+    col: { attrs: { span: null } },
+    colgroup: { attrs: { span: null } },
+    command: {
+      attrs: {
+        type: ["command", "checkbox", "radio"],
+        label: null, icon: null, radiogroup: null, command: null, title: null,
+        disabled: ["", "disabled"],
+        checked: ["", "checked"]
+      }
+    },
+    data: { attrs: { value: null } },
+    datagrid: { attrs: { disabled: ["", "disabled"], multiple: ["", "multiple"] } },
+    datalist: { attrs: { data: null } },
+    dd: s,
+    del: { attrs: { cite: null, datetime: null } },
+    details: { attrs: { open: ["", "open"] } },
+    dfn: s,
+    dir: s,
+    div: s,
+    dl: s,
+    dt: s,
+    em: s,
+    embed: { attrs: { src: null, type: null, width: null, height: null } },
+    eventsource: { attrs: { src: null } },
+    fieldset: { attrs: { disabled: ["", "disabled"], form: null, name: null } },
+    figcaption: s,
+    figure: s,
+    font: s,
+    footer: s,
+    form: {
+      attrs: {
+        action: null, name: null,
+        "accept-charset": charsets,
+        autocomplete: ["on", "off"],
+        enctype: encs,
+        method: methods,
+        novalidate: ["", "novalidate"],
+        target: targets
+      }
+    },
+    frame: s,
+    frameset: s,
+    h1: s, h2: s, h3: s, h4: s, h5: s, h6: s,
+    head: {
+      attrs: {},
+      children: ["title", "base", "link", "style", "meta", "script", "noscript", "command"]
+    },
+    header: s,
+    hgroup: s,
+    hr: s,
+    html: {
+      attrs: { manifest: null },
+      children: ["head", "body"]
+    },
+    i: s,
+    iframe: {
+      attrs: {
+        src: null, srcdoc: null, name: null, width: null, height: null,
+        sandbox: ["allow-top-navigation", "allow-same-origin", "allow-forms", "allow-scripts"],
+        seamless: ["", "seamless"]
+      }
+    },
+    img: {
+      attrs: {
+        alt: null, src: null, ismap: null, usemap: null, width: null, height: null,
+        crossorigin: ["anonymous", "use-credentials"]
+      }
+    },
+    input: {
+      attrs: {
+        alt: null, dirname: null, form: null, formaction: null,
+        height: null, list: null, max: null, maxlength: null, min: null,
+        name: null, pattern: null, placeholder: null, size: null, src: null,
+        step: null, value: null, width: null,
+        accept: ["audio/*", "video/*", "image/*"],
+        autocomplete: ["on", "off"],
+        autofocus: ["", "autofocus"],
+        checked: ["", "checked"],
+        disabled: ["", "disabled"],
+        formenctype: encs,
+        formmethod: methods,
+        formnovalidate: ["", "novalidate"],
+        formtarget: targets,
+        multiple: ["", "multiple"],
+        readonly: ["", "readonly"],
+        required: ["", "required"],
+        type: ["hidden", "text", "search", "tel", "url", "email", "password", "datetime", "date", "month",
+               "week", "time", "datetime-local", "number", "range", "color", "checkbox", "radio",
+               "file", "submit", "image", "reset", "button"]
+      }
+    },
+    ins: { attrs: { cite: null, datetime: null } },
+    kbd: s,
+    keygen: {
+      attrs: {
+        challenge: null, form: null, name: null,
+        autofocus: ["", "autofocus"],
+        disabled: ["", "disabled"],
+        keytype: ["RSA"]
+      }
+    },
+    label: { attrs: { "for": null, form: null } },
+    legend: s,
+    li: { attrs: { value: null } },
+    link: {
+      attrs: {
+        href: null, type: null,
+        hreflang: langs,
+        media: media,
+        sizes: ["all", "16x16", "16x16 32x32", "16x16 32x32 64x64"]
+      }
+    },
+    map: { attrs: { name: null } },
+    mark: s,
+    menu: { attrs: { label: null, type: ["list", "context", "toolbar"] } },
+    meta: {
+      attrs: {
+        content: null,
+        charset: charsets,
+        name: ["viewport", "application-name", "author", "description", "generator", "keywords"],
+        "http-equiv": ["content-language", "content-type", "default-style", "refresh"]
+      }
+    },
+    meter: { attrs: { value: null, min: null, low: null, high: null, max: null, optimum: null } },
+    nav: s,
+    noframes: s,
+    noscript: s,
+    object: {
+      attrs: {
+        data: null, type: null, name: null, usemap: null, form: null, width: null, height: null,
+        typemustmatch: ["", "typemustmatch"]
+      }
+    },
+    ol: { attrs: { reversed: ["", "reversed"], start: null, type: ["1", "a", "A", "i", "I"] } },
+    optgroup: { attrs: { disabled: ["", "disabled"], label: null } },
+    option: { attrs: { disabled: ["", "disabled"], label: null, selected: ["", "selected"], value: null } },
+    output: { attrs: { "for": null, form: null, name: null } },
+    p: s,
+    param: { attrs: { name: null, value: null } },
+    pre: s,
+    progress: { attrs: { value: null, max: null } },
+    q: { attrs: { cite: null } },
+    rp: s,
+    rt: s,
+    ruby: s,
+    s: s,
+    samp: s,
+    script: {
+      attrs: {
+        type: ["text/javascript"],
+        src: null,
+        async: ["", "async"],
+        defer: ["", "defer"],
+        charset: charsets
+      }
+    },
+    section: s,
+    select: {
+      attrs: {
+        form: null, name: null, size: null,
+        autofocus: ["", "autofocus"],
+        disabled: ["", "disabled"],
+        multiple: ["", "multiple"]
+      }
+    },
+    small: s,
+    source: { attrs: { src: null, type: null, media: null } },
+    span: s,
+    strike: s,
+    strong: s,
+    style: {
+      attrs: {
+        type: ["text/css"],
+        media: media,
+        scoped: null
+      }
+    },
+    sub: s,
+    summary: s,
+    sup: s,
+    table: s,
+    tbody: s,
+    td: { attrs: { colspan: null, rowspan: null, headers: null } },
+    textarea: {
+      attrs: {
+        dirname: null, form: null, maxlength: null, name: null, placeholder: null,
+        rows: null, cols: null,
+        autofocus: ["", "autofocus"],
+        disabled: ["", "disabled"],
+        readonly: ["", "readonly"],
+        required: ["", "required"],
+        wrap: ["soft", "hard"]
+      }
+    },
+    tfoot: s,
+    th: { attrs: { colspan: null, rowspan: null, headers: null, scope: ["row", "col", "rowgroup", "colgroup"] } },
+    thead: s,
+    time: { attrs: { datetime: null } },
+    title: s,
+    tr: s,
+    track: {
+      attrs: {
+        src: null, label: null, "default": null,
+        kind: ["subtitles", "captions", "descriptions", "chapters", "metadata"],
+        srclang: langs
+      }
+    },
+    tt: s,
+    u: s,
+    ul: s,
+    "var": s,
+    video: {
+      attrs: {
+        src: null, poster: null, width: null, height: null,
+        crossorigin: ["anonymous", "use-credentials"],
+        preload: ["auto", "metadata", "none"],
+        autoplay: ["", "autoplay"],
+        mediagroup: ["movie"],
+        muted: ["", "muted"],
+        controls: ["", "controls"]
+      }
+    },
+    wbr: s
+  };
+
+  var globalAttrs = {
+    accesskey: ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
+    "class": null,
+    contenteditable: ["true", "false"],
+    contextmenu: null,
+    dir: ["ltr", "rtl", "auto"],
+    draggable: ["true", "false", "auto"],
+    dropzone: ["copy", "move", "link", "string:", "file:"],
+    hidden: ["hidden"],
+    id: null,
+    inert: ["inert"],
+    itemid: null,
+    itemprop: null,
+    itemref: null,
+    itemscope: ["itemscope"],
+    itemtype: null,
+    lang: ["en", "es"],
+    spellcheck: ["true", "false"],
+    style: null,
+    tabindex: ["1", "2", "3", "4", "5", "6", "7", "8", "9"],
+    title: null,
+    translate: ["yes", "no"],
+    onclick: null,
+    rel: ["stylesheet", "alternate", "author", "bookmark", "help", "license", "next", "nofollow", "noreferrer", "prefetch", "prev", "search", "tag"]
+  };
+  function populate(obj) {
+    for (var attr in globalAttrs) if (globalAttrs.hasOwnProperty(attr))
+      obj.attrs[attr] = globalAttrs[attr];
+  }
+
+  populate(s);
+  for (var tag in data) if (data.hasOwnProperty(tag) && data[tag] != s)
+    populate(data[tag]);
+
+  CodeMirror.htmlSchema = data;
+  function htmlHint(cm, options) {
+    var local = {schemaInfo: data};
+    if (options) for (var opt in options) local[opt] = options[opt];
+    return CodeMirror.hint.xml(cm, local);
+  }
+  CodeMirror.registerHelper("hint", "html", htmlHint);
+});
diff --git a/app/gui/html/vendor/codemirror/addon/hint/javascript-hint.js b/app/gui/html/vendor/codemirror/addon/hint/javascript-hint.js
new file mode 100644
index 0000000..305bb85
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/hint/javascript-hint.js
@@ -0,0 +1,136 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  var Pos = CodeMirror.Pos;
+
+  function forEach(arr, f) {
+    for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
+  }
+
+  function arrayContains(arr, item) {
+    if (!Array.prototype.indexOf) {
+      var i = arr.length;
+      while (i--) {
+        if (arr[i] === item) {
+          return true;
+        }
+      }
+      return false;
+    }
+    return arr.indexOf(item) != -1;
+  }
+
+  function scriptHint(editor, keywords, getToken, options) {
+    // Find the token at the cursor
+    var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
+    if (/\b(?:string|comment)\b/.test(token.type)) return;
+    token.state = CodeMirror.innerMode(editor.getMode(), token.state).state;
+
+    // If it's not a 'word-style' token, ignore the token.
+    if (!/^[\w$_]*$/.test(token.string)) {
+      token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
+                       type: token.string == "." ? "property" : null};
+    }
+    // If it is a property, find out what it is a property of.
+    while (tprop.type == "property") {
+      tprop = getToken(editor, Pos(cur.line, tprop.start));
+      if (tprop.string != ".") return;
+      tprop = getToken(editor, Pos(cur.line, tprop.start));
+      if (!context) var context = [];
+      context.push(tprop);
+    }
+    return {list: getCompletions(token, context, keywords, options),
+            from: Pos(cur.line, token.start),
+            to: Pos(cur.line, token.end)};
+  }
+
+  function javascriptHint(editor, options) {
+    return scriptHint(editor, javascriptKeywords,
+                      function (e, cur) {return e.getTokenAt(cur);},
+                      options);
+  };
+  CodeMirror.registerHelper("hint", "javascript", javascriptHint);
+
+  function getCoffeeScriptToken(editor, cur) {
+  // This getToken, it is for coffeescript, imitates the behavior of
+  // getTokenAt method in javascript.js, that is, returning "property"
+  // type and treat "." as indepenent token.
+    var token = editor.getTokenAt(cur);
+    if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
+      token.end = token.start;
+      token.string = '.';
+      token.type = "property";
+    }
+    else if (/^\.[\w$_]*$/.test(token.string)) {
+      token.type = "property";
+      token.start++;
+      token.string = token.string.replace(/\./, '');
+    }
+    return token;
+  }
+
+  function coffeescriptHint(editor, options) {
+    return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options);
+  }
+  CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint);
+
+  var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
+                     "toUpperCase toLowerCase split concat match replace search").split(" ");
+  var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " +
+                    "lastIndexOf every some filter forEach map reduce reduceRight ").split(" ");
+  var funcProps = "prototype apply call bind".split(" ");
+  var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " +
+                  "if in instanceof new null return switch throw true try typeof var void while with").split(" ");
+  var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
+                  "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
+
+  function getCompletions(token, context, keywords, options) {
+    var found = [], start = token.string;
+    function maybeAdd(str) {
+      if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
+    }
+    function gatherCompletions(obj) {
+      if (typeof obj == "string") forEach(stringProps, maybeAdd);
+      else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
+      else if (obj instanceof Function) forEach(funcProps, maybeAdd);
+      for (var name in obj) maybeAdd(name);
+    }
+
+    if (context && context.length) {
+      // If this is a property, see if it belongs to some object we can
+      // find in the current environment.
+      var obj = context.pop(), base;
+      if (obj.type && obj.type.indexOf("variable") === 0) {
+        if (options && options.additionalContext)
+          base = options.additionalContext[obj.string];
+        base = base || window[obj.string];
+      } else if (obj.type == "string") {
+        base = "";
+      } else if (obj.type == "atom") {
+        base = 1;
+      } else if (obj.type == "function") {
+        if (window.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
+            (typeof window.jQuery == 'function'))
+          base = window.jQuery();
+        else if (window._ != null && (obj.string == '_') && (typeof window._ == 'function'))
+          base = window._();
+      }
+      while (base != null && context.length)
+        base = base[context.pop().string];
+      if (base != null) gatherCompletions(base);
+    } else {
+      // If not, just look in the window object and any local scope
+      // (reading into JS mode internals to get at the local and global variables)
+      for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
+      for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name);
+      gatherCompletions(window);
+      forEach(keywords, maybeAdd);
+    }
+    return found;
+  }
+});
diff --git a/app/gui/html/vendor/codemirror/addon/hint/python-hint.js b/app/gui/html/vendor/codemirror/addon/hint/python-hint.js
new file mode 100644
index 0000000..eebfcc7
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/hint/python-hint.js
@@ -0,0 +1,99 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  function forEach(arr, f) {
+    for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
+  }
+
+  function arrayContains(arr, item) {
+    if (!Array.prototype.indexOf) {
+      var i = arr.length;
+      while (i--) {
+        if (arr[i] === item) {
+          return true;
+        }
+      }
+      return false;
+    }
+    return arr.indexOf(item) != -1;
+  }
+
+  function scriptHint(editor, _keywords, getToken) {
+    // Find the token at the cursor
+    var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
+    // If it's not a 'word-style' token, ignore the token.
+
+    if (!/^[\w$_]*$/.test(token.string)) {
+        token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
+                         className: token.string == ":" ? "python-type" : null};
+    }
+
+    if (!context) var context = [];
+    context.push(tprop);
+
+    var completionList = getCompletions(token, context);
+    completionList = completionList.sort();
+
+    return {list: completionList,
+            from: CodeMirror.Pos(cur.line, token.start),
+            to: CodeMirror.Pos(cur.line, token.end)};
+  }
+
+  function pythonHint(editor) {
+    return scriptHint(editor, pythonKeywordsU, function (e, cur) {return e.getTokenAt(cur);});
+  }
+  CodeMirror.registerHelper("hint", "python", pythonHint);
+
+  var pythonKeywords = "and del from not while as elif global or with assert else if pass yield"
++ "break except import print class exec in raise continue finally is return def for lambda try";
+  var pythonKeywordsL = pythonKeywords.split(" ");
+  var pythonKeywordsU = pythonKeywords.toUpperCase().split(" ");
+
+  var pythonBuiltins = "abs divmod input open staticmethod all enumerate int ord str "
++ "any eval isinstance pow sum basestring execfile issubclass print super"
++ "bin file iter property tuple bool filter len range type"
++ "bytearray float list raw_input unichr callable format locals reduce unicode"
++ "chr frozenset long reload vars classmethod getattr map repr xrange"
++ "cmp globals max reversed zip compile hasattr memoryview round __import__"
++ "complex hash min set apply delattr help next setattr buffer"
++ "dict hex object slice coerce dir id oct sorted intern ";
+  var pythonBuiltinsL = pythonBuiltins.split(" ").join("() ").split(" ");
+  var pythonBuiltinsU = pythonBuiltins.toUpperCase().split(" ").join("() ").split(" ");
+
+  function getCompletions(token, context) {
+    var found = [], start = token.string;
+    function maybeAdd(str) {
+      if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
+    }
+
+    function gatherCompletions(_obj) {
+        forEach(pythonBuiltinsL, maybeAdd);
+        forEach(pythonBuiltinsU, maybeAdd);
+        forEach(pythonKeywordsL, maybeAdd);
+        forEach(pythonKeywordsU, maybeAdd);
+    }
+
+    if (context) {
+      // If this is a property, see if it belongs to some object we can
+      // find in the current environment.
+      var obj = context.pop(), base;
+
+      if (obj.type == "variable")
+          base = obj.string;
+      else if(obj.type == "variable-3")
+          base = ":" + obj.string;
+
+      while (base != null && context.length)
+        base = base[context.pop().string];
+      if (base != null) gatherCompletions(base);
+    }
+    return found;
+  }
+});
diff --git a/app/gui/html/vendor/codemirror/addon/hint/show-hint.css b/app/gui/html/vendor/codemirror/addon/hint/show-hint.css
new file mode 100644
index 0000000..8a4ff05
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/hint/show-hint.css
@@ -0,0 +1,38 @@
+.CodeMirror-hints {
+  position: absolute;
+  z-index: 10;
+  overflow: hidden;
+  list-style: none;
+
+  margin: 0;
+  padding: 2px;
+
+  -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
+  -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
+  box-shadow: 2px 3px 5px rgba(0,0,0,.2);
+  border-radius: 3px;
+  border: 1px solid silver;
+
+  background: white;
+  font-size: 90%;
+  font-family: monospace;
+
+  max-height: 20em;
+  overflow-y: auto;
+}
+
+.CodeMirror-hint {
+  margin: 0;
+  padding: 0 4px;
+  border-radius: 2px;
+  max-width: 19em;
+  overflow: hidden;
+  white-space: pre;
+  color: black;
+  cursor: pointer;
+}
+
+.CodeMirror-hint-active {
+  background: #08f;
+  color: white;
+}
diff --git a/app/gui/html/vendor/codemirror/addon/hint/show-hint.js b/app/gui/html/vendor/codemirror/addon/hint/show-hint.js
new file mode 100644
index 0000000..6f04c56
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/hint/show-hint.js
@@ -0,0 +1,349 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var HINT_ELEMENT_CLASS        = "CodeMirror-hint";
+  var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
+
+  CodeMirror.showHint = function(cm, getHints, options) {
+    // We want a single cursor position.
+    if (cm.listSelections().length > 1 || cm.somethingSelected()) return;
+    if (getHints == null) {
+      if (options && options.async) return;
+      else getHints = CodeMirror.hint.auto;
+    }
+
+    if (cm.state.completionActive) cm.state.completionActive.close();
+
+    var completion = cm.state.completionActive = new Completion(cm, getHints, options || {});
+    CodeMirror.signal(cm, "startCompletion", cm);
+    if (completion.options.async)
+      getHints(cm, function(hints) { completion.showHints(hints); }, completion.options);
+    else
+      return completion.showHints(getHints(cm, completion.options));
+  };
+
+  function Completion(cm, getHints, options) {
+    this.cm = cm;
+    this.getHints = getHints;
+    this.options = options;
+    this.widget = this.onClose = null;
+  }
+
+  Completion.prototype = {
+    close: function() {
+      if (!this.active()) return;
+      this.cm.state.completionActive = null;
+
+      if (this.widget) this.widget.close();
+      if (this.onClose) this.onClose();
+      CodeMirror.signal(this.cm, "endCompletion", this.cm);
+    },
+
+    active: function() {
+      return this.cm.state.completionActive == this;
+    },
+
+    pick: function(data, i) {
+      var completion = data.list[i];
+      if (completion.hint) completion.hint(this.cm, data, completion);
+      else this.cm.replaceRange(getText(completion), completion.from||data.from, completion.to||data.to);
+      CodeMirror.signal(data, "pick", completion);
+      this.close();
+    },
+
+    showHints: function(data) {
+      if (!data || !data.list.length || !this.active()) return this.close();
+
+      if (this.options.completeSingle != false && data.list.length == 1)
+        this.pick(data, 0);
+      else
+        this.showWidget(data);
+    },
+
+    showWidget: function(data) {
+      this.widget = new Widget(this, data);
+      CodeMirror.signal(data, "shown");
+
+      var debounce = 0, completion = this, finished;
+      var closeOn = this.options.closeCharacters || /[\s()\[\]{};:>,]/;
+      var startPos = this.cm.getCursor(), startLen = this.cm.getLine(startPos.line).length;
+
+      var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
+        return setTimeout(fn, 1000/60);
+      };
+      var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
+
+      function done() {
+        if (finished) return;
+        finished = true;
+        completion.close();
+        completion.cm.off("cursorActivity", activity);
+        if (data) CodeMirror.signal(data, "close");
+      }
+
+      function update() {
+        if (finished) return;
+        CodeMirror.signal(data, "update");
+        if (completion.options.async)
+          completion.getHints(completion.cm, finishUpdate, completion.options);
+        else
+          finishUpdate(completion.getHints(completion.cm, completion.options));
+      }
+      function finishUpdate(data_) {
+        data = data_;
+        if (finished) return;
+        if (!data || !data.list.length) return done();
+        completion.widget = new Widget(completion, data);
+      }
+
+      function clearDebounce() {
+        if (debounce) {
+          cancelAnimationFrame(debounce);
+          debounce = 0;
+        }
+      }
+
+      function activity() {
+        clearDebounce();
+        var pos = completion.cm.getCursor(), line = completion.cm.getLine(pos.line);
+        if (pos.line != startPos.line || line.length - pos.ch != startLen - startPos.ch ||
+            pos.ch < startPos.ch || completion.cm.somethingSelected() ||
+            (pos.ch && closeOn.test(line.charAt(pos.ch - 1)))) {
+          completion.close();
+        } else {
+          debounce = requestAnimationFrame(update);
+          if (completion.widget) completion.widget.close();
+        }
+      }
+      this.cm.on("cursorActivity", activity);
+      this.onClose = done;
+    }
+  };
+
+  function getText(completion) {
+    if (typeof completion == "string") return completion;
+    else return completion.text;
+  }
+
+  function buildKeyMap(options, handle) {
+    var baseMap = {
+      Up: function() {handle.moveFocus(-1);},
+      Down: function() {handle.moveFocus(1);},
+      PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
+      PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
+      Home: function() {handle.setFocus(0);},
+      End: function() {handle.setFocus(handle.length - 1);},
+      Enter: handle.pick,
+      Tab: handle.pick,
+      Esc: handle.close
+    };
+    var ourMap = options.customKeys ? {} : baseMap;
+    function addBinding(key, val) {
+      var bound;
+      if (typeof val != "string")
+        bound = function(cm) { return val(cm, handle); };
+      // This mechanism is deprecated
+      else if (baseMap.hasOwnProperty(val))
+        bound = baseMap[val];
+      else
+        bound = val;
+      ourMap[key] = bound;
+    }
+    if (options.customKeys)
+      for (var key in options.customKeys) if (options.customKeys.hasOwnProperty(key))
+        addBinding(key, options.customKeys[key]);
+    if (options.extraKeys)
+      for (var key in options.extraKeys) if (options.extraKeys.hasOwnProperty(key))
+        addBinding(key, options.extraKeys[key]);
+    return ourMap;
+  }
+
+  function getHintElement(hintsElement, el) {
+    while (el && el != hintsElement) {
+      if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
+      el = el.parentNode;
+    }
+  }
+
+  function Widget(completion, data) {
+    this.completion = completion;
+    this.data = data;
+    var widget = this, cm = completion.cm, options = completion.options;
+
+    var hints = this.hints = document.createElement("ul");
+    hints.className = "CodeMirror-hints";
+    this.selectedHint = options.getDefaultSelection ? options.getDefaultSelection(cm,options,data) : 0;
+
+    var completions = data.list;
+    for (var i = 0; i < completions.length; ++i) {
+      var elt = hints.appendChild(document.createElement("li")), cur = completions[i];
+      var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
+      if (cur.className != null) className = cur.className + " " + className;
+      elt.className = className;
+      if (cur.render) cur.render(elt, data, cur);
+      else elt.appendChild(document.createTextNode(cur.displayText || getText(cur)));
+      elt.hintId = i;
+    }
+
+    var pos = cm.cursorCoords(options.alignWithWord !== false ? data.from : null);
+    var left = pos.left, top = pos.bottom, below = true;
+    hints.style.left = left + "px";
+    hints.style.top = top + "px";
+    // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
+    var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
+    var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
+    (options.container || document.body).appendChild(hints);
+    var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
+    if (overlapY > 0) {
+      var height = box.bottom - box.top, curTop = box.top - (pos.bottom - pos.top);
+      if (curTop - height > 0) { // Fits above cursor
+        hints.style.top = (top = curTop - height) + "px";
+        below = false;
+      } else if (height > winH) {
+        hints.style.height = (winH - 5) + "px";
+        hints.style.top = (top = pos.bottom - box.top) + "px";
+        var cursor = cm.getCursor();
+        if (data.from.ch != cursor.ch) {
+          pos = cm.cursorCoords(cursor);
+          hints.style.left = (left = pos.left) + "px";
+          box = hints.getBoundingClientRect();
+        }
+      }
+    }
+    var overlapX = box.left - winW;
+    if (overlapX > 0) {
+      if (box.right - box.left > winW) {
+        hints.style.width = (winW - 5) + "px";
+        overlapX -= (box.right - box.left) - winW;
+      }
+      hints.style.left = (left = pos.left - overlapX) + "px";
+    }
+
+    cm.addKeyMap(this.keyMap = buildKeyMap(options, {
+      moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
+      setFocus: function(n) { widget.changeActive(n); },
+      menuSize: function() { return widget.screenAmount(); },
+      length: completions.length,
+      close: function() { completion.close(); },
+      pick: function() { widget.pick(); },
+      data: data
+    }));
+
+    if (options.closeOnUnfocus !== false) {
+      var closingOnBlur;
+      cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
+      cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
+    }
+
+    var startScroll = cm.getScrollInfo();
+    cm.on("scroll", this.onScroll = function() {
+      var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
+      var newTop = top + startScroll.top - curScroll.top;
+      var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop);
+      if (!below) point += hints.offsetHeight;
+      if (point <= editor.top || point >= editor.bottom) return completion.close();
+      hints.style.top = newTop + "px";
+      hints.style.left = (left + startScroll.left - curScroll.left) + "px";
+    });
+
+    CodeMirror.on(hints, "dblclick", function(e) {
+      var t = getHintElement(hints, e.target || e.srcElement);
+      if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
+    });
+
+    CodeMirror.on(hints, "click", function(e) {
+      var t = getHintElement(hints, e.target || e.srcElement);
+      if (t && t.hintId != null) {
+        widget.changeActive(t.hintId);
+        if (options.completeOnSingleClick) widget.pick();
+      }
+    });
+
+    CodeMirror.on(hints, "mousedown", function() {
+      setTimeout(function(){cm.focus();}, 20);
+    });
+
+    CodeMirror.signal(data, "select", completions[0], hints.firstChild);
+    return true;
+  }
+
+  Widget.prototype = {
+    close: function() {
+      if (this.completion.widget != this) return;
+      this.completion.widget = null;
+      this.hints.parentNode.removeChild(this.hints);
+      this.completion.cm.removeKeyMap(this.keyMap);
+
+      var cm = this.completion.cm;
+      if (this.completion.options.closeOnUnfocus !== false) {
+        cm.off("blur", this.onBlur);
+        cm.off("focus", this.onFocus);
+      }
+      cm.off("scroll", this.onScroll);
+    },
+
+    pick: function() {
+      this.completion.pick(this.data, this.selectedHint);
+    },
+
+    changeActive: function(i, avoidWrap) {
+      if (i >= this.data.list.length)
+        i = avoidWrap ? this.data.list.length - 1 : 0;
+      else if (i < 0)
+        i = avoidWrap ? 0  : this.data.list.length - 1;
+      if (this.selectedHint == i) return;
+      var node = this.hints.childNodes[this.selectedHint];
+      node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
+      node = this.hints.childNodes[this.selectedHint = i];
+      node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
+      if (node.offsetTop < this.hints.scrollTop)
+        this.hints.scrollTop = node.offsetTop - 3;
+      else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
+        this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
+      CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
+    },
+
+    screenAmount: function() {
+      return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
+    }
+  };
+
+  CodeMirror.registerHelper("hint", "auto", function(cm, options) {
+    var helpers = cm.getHelpers(cm.getCursor(), "hint"), words;
+    if (helpers.length) {
+      for (var i = 0; i < helpers.length; i++) {
+        var cur = helpers[i](cm, options);
+        if (cur && cur.list.length) return cur;
+      }
+    } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
+      if (words) return CodeMirror.hint.fromList(cm, {words: words});
+    } else if (CodeMirror.hint.anyword) {
+      return CodeMirror.hint.anyword(cm, options);
+    }
+  });
+
+  CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
+    var cur = cm.getCursor(), token = cm.getTokenAt(cur);
+    var found = [];
+    for (var i = 0; i < options.words.length; i++) {
+      var word = options.words[i];
+      if (word.slice(0, token.string.length) == token.string)
+        found.push(word);
+    }
+
+    if (found.length) return {
+      list: found,
+      from: CodeMirror.Pos(cur.line, token.start),
+            to: CodeMirror.Pos(cur.line, token.end)
+    };
+  });
+
+  CodeMirror.commands.autocomplete = CodeMirror.showHint;
+});
diff --git a/app/gui/html/vendor/codemirror/addon/hint/sql-hint.js b/app/gui/html/vendor/codemirror/addon/hint/sql-hint.js
new file mode 100644
index 0000000..a48d2b3
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/hint/sql-hint.js
@@ -0,0 +1,161 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("../../mode/sql/sql"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "../../mode/sql/sql"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var tables;
+  var keywords;
+  var CONS = {
+    QUERY_DIV: ";",
+    ALIAS_KEYWORD: "AS"
+  };
+  var Pos = CodeMirror.Pos;
+
+  function getKeywords(editor) {
+    var mode = editor.doc.modeOption;
+    if(mode === "sql") mode = "text/x-sql";
+    return CodeMirror.resolveMode(mode).keywords;
+  }
+
+  function match(string, word) {
+    var len = string.length;
+    var sub = word.substr(0, len);
+    return string.toUpperCase() === sub.toUpperCase();
+  }
+
+  function addMatches(result, search, wordlist, formatter) {
+    for(var word in wordlist) {
+      if(!wordlist.hasOwnProperty(word)) continue;
+      if(Array.isArray(wordlist)) {
+        word = wordlist[word];
+      }
+      if(match(search, word)) {
+        result.push(formatter(word));
+      }
+    }
+  }
+
+  function columnCompletion(result, editor) {
+    var cur = editor.getCursor();
+    var token = editor.getTokenAt(cur);
+    var string = token.string.substr(1);
+    var prevCur = Pos(cur.line, token.start);
+    var table = editor.getTokenAt(prevCur).string;
+    if( !tables.hasOwnProperty( table ) ){
+      table = findTableByAlias(table, editor);
+    }
+    var columns = tables[table];
+    if(!columns) {
+      return;
+    }
+    addMatches(result, string, columns,
+        function(w) {return "." + w;});
+  }
+
+  function eachWord(lineText, f) {
+    if( !lineText ){return;}
+    var excepted = /[,;]/g;
+    var words = lineText.split( " " );
+    for( var i = 0; i < words.length; i++ ){
+      f( words[i]?words[i].replace( excepted, '' ) : '' );
+    }
+  }
+
+  function convertCurToNumber( cur ){
+    // max characters of a line is 999,999.
+    return cur.line + cur.ch / Math.pow( 10, 6 );
+  }
+
+  function convertNumberToCur( num ){
+    return Pos(Math.floor( num ), +num.toString().split( '.' ).pop());
+  }
+
+  function findTableByAlias(alias, editor) {
+    var doc = editor.doc;
+    var fullQuery = doc.getValue();
+    var aliasUpperCase = alias.toUpperCase();
+    var previousWord = "";
+    var table = "";
+    var separator = [];
+    var validRange = {
+      start: Pos( 0, 0 ),
+      end: Pos( editor.lastLine(), editor.getLineHandle( editor.lastLine() ).length )
+    };
+
+    //add separator
+    var indexOfSeparator = fullQuery.indexOf( CONS.QUERY_DIV );
+    while( indexOfSeparator != -1 ){
+      separator.push( doc.posFromIndex(indexOfSeparator));
+      indexOfSeparator = fullQuery.indexOf( CONS.QUERY_DIV, indexOfSeparator+1);
+    }
+    separator.unshift( Pos( 0, 0 ) );
+    separator.push( Pos( editor.lastLine(), editor.getLineHandle( editor.lastLine() ).text.length ) );
+
+    //find valieRange
+    var prevItem = 0;
+    var current = convertCurToNumber( editor.getCursor() );
+    for( var i=0; i< separator.length; i++){
+      var _v = convertCurToNumber( separator[i] );
+      if( current > prevItem && current <= _v ){
+        validRange = { start: convertNumberToCur( prevItem ), end: convertNumberToCur( _v ) };
+        break;
+      }
+      prevItem = _v;
+    }
+
+    var query = doc.getRange(validRange.start, validRange.end, false);
+
+    for(var i=0; i < query.length; i++){
+      var lineText = query[i];
+      eachWord( lineText, function( word ){
+        var wordUpperCase = word.toUpperCase();
+        if( wordUpperCase === aliasUpperCase && tables.hasOwnProperty( previousWord ) ){
+            table = previousWord;
+        }
+        if( wordUpperCase !== CONS.ALIAS_KEYWORD ){
+          previousWord = word;
+        }
+      });
+      if( table ){ break; }
+    }
+    return table;
+  }
+
+  function sqlHint(editor, options) {
+    tables = (options && options.tables) || {};
+    keywords = keywords || getKeywords(editor);
+    var cur = editor.getCursor();
+    var token = editor.getTokenAt(cur), end = token.end;
+    var result = [];
+    var search = token.string.trim();
+
+    if (search.charAt(0) == ".") {
+      columnCompletion(result, editor);
+      if (!result.length) {
+        while (token.start && search.charAt(0) == ".") {
+          token = editor.getTokenAt(Pos(cur.line, token.start - 1));
+          search = token.string + search;
+        }
+        addMatches(result, search, tables,
+                   function(w) {return w;});
+      }
+    } else {
+      addMatches(result, search, keywords,
+                 function(w) {return w.toUpperCase();});
+      addMatches(result, search, tables,
+                 function(w) {return w;});
+    }
+
+    return {
+      list: result,
+        from: Pos(cur.line, token.start),
+        to: Pos(cur.line, end)
+    };
+  }
+  CodeMirror.registerHelper("hint", "sql", sqlHint);
+});
diff --git a/app/gui/html/vendor/codemirror/addon/hint/xml-hint.js b/app/gui/html/vendor/codemirror/addon/hint/xml-hint.js
new file mode 100644
index 0000000..8575649
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/hint/xml-hint.js
@@ -0,0 +1,75 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var Pos = CodeMirror.Pos;
+
+  function getHints(cm, options) {
+    var tags = options && options.schemaInfo;
+    var quote = (options && options.quoteChar) || '"';
+    if (!tags) return;
+    var cur = cm.getCursor(), token = cm.getTokenAt(cur);
+    var inner = CodeMirror.innerMode(cm.getMode(), token.state);
+    if (inner.mode.name != "xml") return;
+    var result = [], replaceToken = false, prefix;
+    var isTag = token.string.charAt(0) == "<";
+    if (!inner.state.tagName || isTag) { // Tag completion
+      if (isTag) {
+        prefix = token.string.slice(1);
+        replaceToken = true;
+      }
+      var cx = inner.state.context, curTag = cx && tags[cx.tagName];
+      var childList = cx ? curTag && curTag.children : tags["!top"];
+      if (childList) {
+        for (var i = 0; i < childList.length; ++i) if (!prefix || childList[i].lastIndexOf(prefix, 0) == 0)
+          result.push("<" + childList[i]);
+      } else {
+        for (var name in tags) if (tags.hasOwnProperty(name) && name != "!top" && (!prefix || name.lastIndexOf(prefix, 0) == 0))
+          result.push("<" + name);
+      }
+      if (cx && (!prefix || ("/" + cx.tagName).lastIndexOf(prefix, 0) == 0))
+        result.push("</" + cx.tagName + ">");
+    } else {
+      // Attribute completion
+      var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs;
+      if (!attrs) return;
+      if (token.type == "string" || token.string == "=") { // A value
+        var before = cm.getRange(Pos(cur.line, Math.max(0, cur.ch - 60)),
+                                 Pos(cur.line, token.type == "string" ? token.start : token.end));
+        var atName = before.match(/([^\s\u00a0=<>\"\']+)=$/), atValues;
+        if (!atName || !attrs.hasOwnProperty(atName[1]) || !(atValues = attrs[atName[1]])) return;
+        if (typeof atValues == 'function') atValues = atValues.call(this, cm); // Functions can be used to supply values for autocomplete widget
+        if (token.type == "string") {
+          prefix = token.string;
+          if (/['"]/.test(token.string.charAt(0))) {
+            quote = token.string.charAt(0);
+            prefix = token.string.slice(1);
+          }
+          replaceToken = true;
+        }
+        for (var i = 0; i < atValues.length; ++i) if (!prefix || atValues[i].lastIndexOf(prefix, 0) == 0)
+          result.push(quote + atValues[i] + quote);
+      } else { // An attribute name
+        if (token.type == "attribute") {
+          prefix = token.string;
+          replaceToken = true;
+        }
+        for (var attr in attrs) if (attrs.hasOwnProperty(attr) && (!prefix || attr.lastIndexOf(prefix, 0) == 0))
+          result.push(attr);
+      }
+    }
+    return {
+      list: result,
+      from: replaceToken ? Pos(cur.line, token.start) : cur,
+      to: replaceToken ? Pos(cur.line, token.end) : cur
+    };
+  }
+
+  CodeMirror.registerHelper("hint", "xml", getHints);
+});
diff --git a/app/gui/html/vendor/codemirror/addon/lint/coffeescript-lint.js b/app/gui/html/vendor/codemirror/addon/lint/coffeescript-lint.js
new file mode 100644
index 0000000..6df17f8
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/lint/coffeescript-lint.js
@@ -0,0 +1,38 @@
+// Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js
+
+// declare global: coffeelint
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.registerHelper("lint", "coffeescript", function(text) {
+  var found = [];
+  var parseError = function(err) {
+    var loc = err.lineNumber;
+    found.push({from: CodeMirror.Pos(loc-1, 0),
+                to: CodeMirror.Pos(loc, 0),
+                severity: err.level,
+                message: err.message});
+  };
+  try {
+    var res = coffeelint.lint(text);
+    for(var i = 0; i < res.length; i++) {
+      parseError(res[i]);
+    }
+  } catch(e) {
+    found.push({from: CodeMirror.Pos(e.location.first_line, 0),
+                to: CodeMirror.Pos(e.location.last_line, e.location.last_column),
+                severity: 'error',
+                message: e.message});
+  }
+  return found;
+});
+
+});
diff --git a/app/gui/html/vendor/codemirror/addon/lint/css-lint.js b/app/gui/html/vendor/codemirror/addon/lint/css-lint.js
new file mode 100644
index 0000000..2a799dd
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/lint/css-lint.js
@@ -0,0 +1,31 @@
+// Depends on csslint.js from https://github.com/stubbornella/csslint
+
+// declare global: CSSLint
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.registerHelper("lint", "css", function(text) {
+  var found = [];
+  var results = CSSLint.verify(text), messages = results.messages, message = null;
+  for ( var i = 0; i < messages.length; i++) {
+    message = messages[i];
+    var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col;
+    found.push({
+      from: CodeMirror.Pos(startLine, startCol),
+      to: CodeMirror.Pos(endLine, endCol),
+      message: message.message,
+      severity : message.type
+    });
+  }
+  return found;
+});
+
+});
diff --git a/app/gui/html/vendor/codemirror/addon/lint/javascript-lint.js b/app/gui/html/vendor/codemirror/addon/lint/javascript-lint.js
new file mode 100644
index 0000000..bbb5108
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/lint/javascript-lint.js
@@ -0,0 +1,132 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+  // declare global: JSHINT
+
+  var bogus = [ "Dangerous comment" ];
+
+  var warnings = [ [ "Expected '{'",
+                     "Statement body should be inside '{ }' braces." ] ];
+
+  var errors = [ "Missing semicolon", "Extra comma", "Missing property name",
+                 "Unmatched ", " and instead saw", " is not defined",
+                 "Unclosed string", "Stopping, unable to continue" ];
+
+  function validator(text, options) {
+    JSHINT(text, options);
+    var errors = JSHINT.data().errors, result = [];
+    if (errors) parseErrors(errors, result);
+    return result;
+  }
+
+  CodeMirror.registerHelper("lint", "javascript", validator);
+
+  function cleanup(error) {
+    // All problems are warnings by default
+    fixWith(error, warnings, "warning", true);
+    fixWith(error, errors, "error");
+
+    return isBogus(error) ? null : error;
+  }
+
+  function fixWith(error, fixes, severity, force) {
+    var description, fix, find, replace, found;
+
+    description = error.description;
+
+    for ( var i = 0; i < fixes.length; i++) {
+      fix = fixes[i];
+      find = (typeof fix === "string" ? fix : fix[0]);
+      replace = (typeof fix === "string" ? null : fix[1]);
+      found = description.indexOf(find) !== -1;
+
+      if (force || found) {
+        error.severity = severity;
+      }
+      if (found && replace) {
+        error.description = replace;
+      }
+    }
+  }
+
+  function isBogus(error) {
+    var description = error.description;
+    for ( var i = 0; i < bogus.length; i++) {
+      if (description.indexOf(bogus[i]) !== -1) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  function parseErrors(errors, output) {
+    for ( var i = 0; i < errors.length; i++) {
+      var error = errors[i];
+      if (error) {
+        var linetabpositions, index;
+
+        linetabpositions = [];
+
+        // This next block is to fix a problem in jshint. Jshint
+        // replaces
+        // all tabs with spaces then performs some checks. The error
+        // positions (character/space) are then reported incorrectly,
+        // not taking the replacement step into account. Here we look
+        // at the evidence line and try to adjust the character position
+        // to the correct value.
+        if (error.evidence) {
+          // Tab positions are computed once per line and cached
+          var tabpositions = linetabpositions[error.line];
+          if (!tabpositions) {
+            var evidence = error.evidence;
+            tabpositions = [];
+            // ugggh phantomjs does not like this
+            // forEachChar(evidence, function(item, index) {
+            Array.prototype.forEach.call(evidence, function(item,
+                                                            index) {
+              if (item === '\t') {
+                // First col is 1 (not 0) to match error
+                // positions
+                tabpositions.push(index + 1);
+              }
+            });
+            linetabpositions[error.line] = tabpositions;
+          }
+          if (tabpositions.length > 0) {
+            var pos = error.character;
+            tabpositions.forEach(function(tabposition) {
+              if (pos > tabposition) pos -= 1;
+            });
+            error.character = pos;
+          }
+        }
+
+        var start = error.character - 1, end = start + 1;
+        if (error.evidence) {
+          index = error.evidence.substring(start).search(/.\b/);
+          if (index > -1) {
+            end += index;
+          }
+        }
+
+        // Convert to format expected by validation service
+        error.description = error.reason;// + "(jshint)";
+        error.start = error.character;
+        error.end = end;
+        error = cleanup(error);
+
+        if (error)
+          output.push({message: error.description,
+                       severity: error.severity,
+                       from: CodeMirror.Pos(error.line - 1, start),
+                       to: CodeMirror.Pos(error.line - 1, end)});
+      }
+    }
+  }
+});
diff --git a/app/gui/html/vendor/codemirror/addon/lint/json-lint.js b/app/gui/html/vendor/codemirror/addon/lint/json-lint.js
new file mode 100644
index 0000000..1f5f82d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/lint/json-lint.js
@@ -0,0 +1,28 @@
+// Depends on jsonlint.js from https://github.com/zaach/jsonlint
+
+// declare global: jsonlint
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.registerHelper("lint", "json", function(text) {
+  var found = [];
+  jsonlint.parseError = function(str, hash) {
+    var loc = hash.loc;
+    found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column),
+                to: CodeMirror.Pos(loc.last_line - 1, loc.last_column),
+                message: str});
+  };
+  try { jsonlint.parse(text); }
+  catch(e) {}
+  return found;
+});
+
+});
diff --git a/app/gui/html/vendor/codemirror/addon/lint/lint.css b/app/gui/html/vendor/codemirror/addon/lint/lint.css
new file mode 100644
index 0000000..414a9a0
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/lint/lint.css
@@ -0,0 +1,73 @@
+/* The lint marker gutter */
+.CodeMirror-lint-markers {
+  width: 16px;
+}
+
+.CodeMirror-lint-tooltip {
+  background-color: infobackground;
+  border: 1px solid black;
+  border-radius: 4px 4px 4px 4px;
+  color: infotext;
+  font-family: monospace;
+  font-size: 10pt;
+  overflow: hidden;
+  padding: 2px 5px;
+  position: fixed;
+  white-space: pre;
+  white-space: pre-wrap;
+  z-index: 100;
+  max-width: 600px;
+  opacity: 0;
+  transition: opacity .4s;
+  -moz-transition: opacity .4s;
+  -webkit-transition: opacity .4s;
+  -o-transition: opacity .4s;
+  -ms-transition: opacity .4s;
+}
+
+.CodeMirror-lint-mark-error, .CodeMirror-lint-mark-warning {
+  background-position: left bottom;
+  background-repeat: repeat-x;
+}
+
+.CodeMirror-lint-mark-error {
+  background-image:
+  url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==")
+  ;
+}
+
+.CodeMirror-lint-mark-warning {
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII=");
+}
+
+.CodeMirror-lint-marker-error, .CodeMirror-lint-marker-warning {
+  background-position: center center;
+  background-repeat: no-repeat;
+  cursor: pointer;
+  display: inline-block;
+  height: 16px;
+  width: 16px;
+  vertical-align: middle;
+  position: relative;
+}
+
+.CodeMirror-lint-message-error, .CodeMirror-lint-message-warning {
+  padding-left: 18px;
+  background-position: top left;
+  background-repeat: no-repeat;
+}
+
+.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error {
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=");
+}
+
+.CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning {
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII=");
+}
+
+.CodeMirror-lint-marker-multiple {
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC");
+  background-repeat: no-repeat;
+  background-position: right bottom;
+  width: 100%; height: 100%;
+}
diff --git a/app/gui/html/vendor/codemirror/addon/lint/lint.js b/app/gui/html/vendor/codemirror/addon/lint/lint.js
new file mode 100644
index 0000000..393a689
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/lint/lint.js
@@ -0,0 +1,207 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+  var GUTTER_ID = "CodeMirror-lint-markers";
+  var SEVERITIES = /^(?:error|warning)$/;
+
+  function showTooltip(e, content) {
+    var tt = document.createElement("div");
+    tt.className = "CodeMirror-lint-tooltip";
+    tt.appendChild(content.cloneNode(true));
+    document.body.appendChild(tt);
+
+    function position(e) {
+      if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position);
+      tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + "px";
+      tt.style.left = (e.clientX + 5) + "px";
+    }
+    CodeMirror.on(document, "mousemove", position);
+    position(e);
+    if (tt.style.opacity != null) tt.style.opacity = 1;
+    return tt;
+  }
+  function rm(elt) {
+    if (elt.parentNode) elt.parentNode.removeChild(elt);
+  }
+  function hideTooltip(tt) {
+    if (!tt.parentNode) return;
+    if (tt.style.opacity == null) rm(tt);
+    tt.style.opacity = 0;
+    setTimeout(function() { rm(tt); }, 600);
+  }
+
+  function showTooltipFor(e, content, node) {
+    var tooltip = showTooltip(e, content);
+    function hide() {
+      CodeMirror.off(node, "mouseout", hide);
+      if (tooltip) { hideTooltip(tooltip); tooltip = null; }
+    }
+    var poll = setInterval(function() {
+      if (tooltip) for (var n = node;; n = n.parentNode) {
+        if (n == document.body) return;
+        if (!n) { hide(); break; }
+      }
+      if (!tooltip) return clearInterval(poll);
+    }, 400);
+    CodeMirror.on(node, "mouseout", hide);
+  }
+
+  function LintState(cm, options, hasGutter) {
+    this.marked = [];
+    this.options = options;
+    this.timeout = null;
+    this.hasGutter = hasGutter;
+    this.onMouseOver = function(e) { onMouseOver(cm, e); };
+  }
+
+  function parseOptions(cm, options) {
+    if (options instanceof Function) return {getAnnotations: options};
+    if (!options || options === true) options = {};
+    if (!options.getAnnotations) options.getAnnotations = cm.getHelper(CodeMirror.Pos(0, 0), "lint");
+    if (!options.getAnnotations) throw new Error("Required option 'getAnnotations' missing (lint addon)");
+    return options;
+  }
+
+  function clearMarks(cm) {
+    var state = cm.state.lint;
+    if (state.hasGutter) cm.clearGutter(GUTTER_ID);
+    for (var i = 0; i < state.marked.length; ++i)
+      state.marked[i].clear();
+    state.marked.length = 0;
+  }
+
+  function makeMarker(labels, severity, multiple, tooltips) {
+    var marker = document.createElement("div"), inner = marker;
+    marker.className = "CodeMirror-lint-marker-" + severity;
+    if (multiple) {
+      inner = marker.appendChild(document.createElement("div"));
+      inner.className = "CodeMirror-lint-marker-multiple";
+    }
+
+    if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) {
+      showTooltipFor(e, labels, inner);
+    });
+
+    return marker;
+  }
+
+  function getMaxSeverity(a, b) {
+    if (a == "error") return a;
+    else return b;
+  }
+
+  function groupByLine(annotations) {
+    var lines = [];
+    for (var i = 0; i < annotations.length; ++i) {
+      var ann = annotations[i], line = ann.from.line;
+      (lines[line] || (lines[line] = [])).push(ann);
+    }
+    return lines;
+  }
+
+  function annotationTooltip(ann) {
+    var severity = ann.severity;
+    if (!SEVERITIES.test(severity)) severity = "error";
+    var tip = document.createElement("div");
+    tip.className = "CodeMirror-lint-message-" + severity;
+    tip.appendChild(document.createTextNode(ann.message));
+    return tip;
+  }
+
+  function startLinting(cm) {
+    var state = cm.state.lint, options = state.options;
+    if (options.async)
+      options.getAnnotations(cm, updateLinting, options);
+    else
+      updateLinting(cm, options.getAnnotations(cm.getValue(), options.options));
+  }
+
+  function updateLinting(cm, annotationsNotSorted) {
+    clearMarks(cm);
+    var state = cm.state.lint, options = state.options;
+
+    var annotations = groupByLine(annotationsNotSorted);
+
+    for (var line = 0; line < annotations.length; ++line) {
+      var anns = annotations[line];
+      if (!anns) continue;
+
+      var maxSeverity = null;
+      var tipLabel = state.hasGutter && document.createDocumentFragment();
+
+      for (var i = 0; i < anns.length; ++i) {
+        var ann = anns[i];
+        var severity = ann.severity;
+        if (!SEVERITIES.test(severity)) severity = "error";
+        maxSeverity = getMaxSeverity(maxSeverity, severity);
+
+        if (options.formatAnnotation) ann = options.formatAnnotation(ann);
+        if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann));
+
+        if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, {
+          className: "CodeMirror-lint-mark-" + severity,
+          __annotation: ann
+        }));
+      }
+
+      if (state.hasGutter)
+        cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1,
+                                                       state.options.tooltips));
+    }
+    if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
+  }
+
+  function onChange(cm) {
+    var state = cm.state.lint;
+    clearTimeout(state.timeout);
+    state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
+  }
+
+  function popupSpanTooltip(ann, e) {
+    var target = e.target || e.srcElement;
+    showTooltipFor(e, annotationTooltip(ann), target);
+  }
+
+  // When the mouseover fires, the cursor might not actually be over
+  // the character itself yet. These pairs of x,y offsets are used to
+  // probe a few nearby points when no suitable marked range is found.
+  var nearby = [0, 0, 0, 5, 0, -5, 5, 0, -5, 0];
+
+  function onMouseOver(cm, e) {
+    if (!/\bCodeMirror-lint-mark-/.test((e.target || e.srcElement).className)) return;
+    for (var i = 0; i < nearby.length; i += 2) {
+      var spans = cm.findMarksAt(cm.coordsChar({left: e.clientX + nearby[i],
+                                                top: e.clientY + nearby[i + 1]}, "client"));
+      for (var j = 0; j < spans.length; ++j) {
+        var span = spans[j], ann = span.__annotation;
+        if (ann) return popupSpanTooltip(ann, e);
+      }
+    }
+  }
+
+  CodeMirror.defineOption("lint", false, function(cm, val, old) {
+    if (old && old != CodeMirror.Init) {
+      clearMarks(cm);
+      cm.off("change", onChange);
+      CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
+      delete cm.state.lint;
+    }
+
+    if (val) {
+      var gutters = cm.getOption("gutters"), hasLintGutter = false;
+      for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
+      var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
+      cm.on("change", onChange);
+      if (state.options.tooltips != false)
+        CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);
+
+      startLinting(cm);
+    }
+  });
+});
diff --git a/app/gui/html/vendor/codemirror/addon/lint/yaml-lint.js b/app/gui/html/vendor/codemirror/addon/lint/yaml-lint.js
new file mode 100644
index 0000000..b53673a
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/lint/yaml-lint.js
@@ -0,0 +1,25 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+// Depends on js-yaml.js from https://github.com/nodeca/js-yaml
+
+// declare global: jsyaml
+
+CodeMirror.registerHelper("lint", "yaml", function(text) {
+  var found = [];
+  try { jsyaml.load(text); }
+  catch(e) {
+      var loc = e.mark;
+      found.push({ from: CodeMirror.Pos(loc.line, loc.column), to: CodeMirror.Pos(loc.line, loc.column), message: e.message });
+  }
+  return found;
+});
+
+});
diff --git a/app/gui/html/vendor/codemirror/addon/merge/dep/diff_match_patch.js b/app/gui/html/vendor/codemirror/addon/merge/dep/diff_match_patch.js
new file mode 100644
index 0000000..9d615dc
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/merge/dep/diff_match_patch.js
@@ -0,0 +1,50 @@
+// From https://code.google.com/p/google-diff-match-patch/ , licensed under the Apache License 2.0
+(function(){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=0.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=0.5;this.Patch_Margin=4;this.Match_MaxBits=32}
+diff_match_patch.prototype.diff_main=function(a,b,c,d){"undefined"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error("Null input. (diff_main)");if(a==b)return a?[[0,a]]:[];"undefined"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);var f=this.diff_commonSuffix(a,b),g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a,
+b,e,d);c&&a.unshift([0,c]);g&&a.push([0,g]);this.diff_cleanupMerge(a);return a};
+diff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[1,b]];if(!b)return[[-1,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[1,e.substring(0,g)],[0,f],[1,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=-1),c):1==f.length?[[-1,a],[1,b]]:(e=this.diff_halfMatch_(a,b))?(f=e[0],a=e[1],g=e[2],b=e[3],e=e[4],f=this.diff_main(f,g,c,d),c=this.diff_main(a,b,c,d),f.concat([[0,e]],c)):c&&100<a.length&&100<b.length?this.diff_lineMode_(a,b,
+d):this.diff_bisect_(a,b,d)};
+diff_match_patch.prototype.diff_lineMode_=function(a,b,c){var d=this.diff_linesToChars_(a,b);a=d.chars1;b=d.chars2;d=d.lineArray;a=this.diff_main(a,b,!1,c);this.diff_charsToLines_(a,d);this.diff_cleanupSemantic(a);a.push([0,""]);for(var e=d=b=0,f="",g="";b<a.length;){switch(a[b][0]){case 1:e++;g+=a[b][1];break;case -1:d++;f+=a[b][1];break;case 0:if(1<=d&&1<=e){a.splice(b-d-e,d+e);b=b-d-e;d=this.diff_main(f,g,!1,c);for(e=d.length-1;0<=e;e--)a.splice(b,0,d[e]);b+=d.length}d=e=0;g=f=""}b++}a.pop();return a};
+diff_match_patch.prototype.diff_bisect_=function(a,b,c){for(var d=a.length,e=b.length,f=Math.ceil((d+e)/2),g=f,h=2*f,j=Array(h),i=Array(h),k=0;k<h;k++)j[k]=-1,i[k]=-1;j[g+1]=0;i[g+1]=0;for(var k=d-e,q=0!=k%2,r=0,t=0,p=0,w=0,v=0;v<f&&!((new Date).getTime()>c);v++){for(var n=-v+r;n<=v-t;n+=2){var l=g+n,m;m=n==-v||n!=v&&j[l-1]<j[l+1]?j[l+1]:j[l-1]+1;for(var s=m-n;m<d&&s<e&&a.charAt(m)==b.charAt(s);)m++,s++;j[l]=m;if(m>d)t+=2;else if(s>e)r+=2;else if(q&&(l=g+k-n,0<=l&&l<h&&-1!=i[l])){var u=d-i[l];if(m>=
+u)return this.diff_bisectSplit_(a,b,m,s,c)}}for(n=-v+p;n<=v-w;n+=2){l=g+n;u=n==-v||n!=v&&i[l-1]<i[l+1]?i[l+1]:i[l-1]+1;for(m=u-n;u<d&&m<e&&a.charAt(d-u-1)==b.charAt(e-m-1);)u++,m++;i[l]=u;if(u>d)w+=2;else if(m>e)p+=2;else if(!q&&(l=g+k-n,0<=l&&(l<h&&-1!=j[l])&&(m=j[l],s=g+m-l,u=d-u,m>=u)))return this.diff_bisectSplit_(a,b,m,s,c)}}return[[-1,a],[1,b]]};
+diff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)};
+diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b="",c=0,f=-1,g=d.length;f<a.length-1;){f=a.indexOf("\n",c);-1==f&&(f=a.length-1);var r=a.substring(c,f+1),c=f+1;(e.hasOwnProperty?e.hasOwnProperty(r):void 0!==e[r])?b+=String.fromCharCode(e[r]):(b+=String.fromCharCode(g),e[r]=g,d[g++]=r)}return b}var d=[],e={};d[0]="";var f=c(a),g=c(b);return{chars1:f,chars2:g,lineArray:d}};
+diff_match_patch.prototype.diff_charsToLines_=function(a,b){for(var c=0;c<a.length;c++){for(var d=a[c][1],e=[],f=0;f<d.length;f++)e[f]=b[d.charCodeAt(f)];a[c][1]=e.join("")}};diff_match_patch.prototype.diff_commonPrefix=function(a,b){if(!a||!b||a.charAt(0)!=b.charAt(0))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(f,e)==b.substring(f,e)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
+diff_match_patch.prototype.diff_commonSuffix=function(a,b){if(!a||!b||a.charAt(a.length-1)!=b.charAt(b.length-1))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(a.length-e,a.length-f)==b.substring(b.length-e,b.length-f)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
+diff_match_patch.prototype.diff_commonOverlap_=function(a,b){var c=a.length,d=b.length;if(0==c||0==d)return 0;c>d?a=a.substring(c-d):c<d&&(b=b.substring(0,c));c=Math.min(c,d);if(a==b)return c;for(var d=0,e=1;;){var f=a.substring(c-e),f=b.indexOf(f);if(-1==f)return d;e+=f;if(0==f||a.substring(c-e)==b.substring(0,e))d=e,e++}};
+diff_match_patch.prototype.diff_halfMatch_=function(a,b){function c(a,b,c){for(var d=a.substring(c,c+Math.floor(a.length/4)),e=-1,g="",h,j,n,l;-1!=(e=b.indexOf(d,e+1));){var m=f.diff_commonPrefix(a.substring(c),b.substring(e)),s=f.diff_commonSuffix(a.substring(0,c),b.substring(0,e));g.length<s+m&&(g=b.substring(e-s,e)+b.substring(e,e+m),h=a.substring(0,c-s),j=a.substring(c+m),n=b.substring(0,e-s),l=b.substring(e+m))}return 2*g.length>=a.length?[h,j,n,l,g]:null}if(0>=this.Diff_Timeout)return null;
+var d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.length<d.length)return null;var f=this,g=c(d,e,Math.ceil(d.length/4)),d=c(d,e,Math.ceil(d.length/2)),h;if(!g&&!d)return null;h=d?g?g[4].length>d[4].length?g:d:d:g;var j;a.length>b.length?(g=h[0],d=h[1],e=h[2],j=h[3]):(e=h[0],j=h[1],g=h[2],d=h[3]);h=h[4];return[g,d,e,j,h]};
+diff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,j=0,i=0;f<a.length;)0==a[f][0]?(c[d++]=f,g=j,h=i,i=j=0,e=a[f][1]):(1==a[f][0]?j+=a[f][1].length:i+=a[f][1].length,e&&(e.length<=Math.max(g,h)&&e.length<=Math.max(j,i))&&(a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,d--,f=0<d?c[d-1]:-1,i=j=h=g=0,e=null,b=!0)),f++;b&&this.diff_cleanupMerge(a);this.diff_cleanupSemanticLossless(a);for(f=1;f<a.length;){if(-1==a[f-1][0]&&1==a[f][0]){b=a[f-1][1];c=a[f][1];
+d=this.diff_commonOverlap_(b,c);e=this.diff_commonOverlap_(c,b);if(d>=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[0,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[0,b.substring(0,e)]),a[f-1][0]=1,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=-1,a[f+1][1]=b.substring(e),f++;f++}f++}};
+diff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_),c=g&&c.match(diff_match_patch.linebreakRegex_),d=h&&d.match(diff_match_patch.linebreakRegex_),i=c&&a.match(diff_match_patch.blanklineEndRegex_),j=d&&b.match(diff_match_patch.blanklineStartRegex_);
+return i||j?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c<a.length-1;){if(0==a[c-1][0]&&0==a[c+1][0]){var d=a[c-1][1],e=a[c][1],f=a[c+1][1],g=this.diff_commonSuffix(d,e);if(g)var h=e.substring(e.length-g),d=d.substring(0,d.length-g),e=h+e.substring(0,e.length-g),f=h+f;for(var g=d,h=e,j=f,i=b(d,e)+b(e,f);e.charAt(0)===f.charAt(0);){var d=d+e.charAt(0),e=e.substring(1)+f.charAt(0),f=f.substring(1),k=b(d,e)+b(e,f);k>=i&&(i=k,g=d,h=e,j=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-1,1),c--),a[c][1]=
+h,j?a[c+1][1]=j:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/;
+diff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,j=!1,i=!1;f<a.length;){if(0==a[f][0])a[f][1].length<this.Diff_EditCost&&(j||i)?(c[d++]=f,g=j,h=i,e=a[f][1]):(d=0,e=null),j=i=!1;else if(-1==a[f][0]?i=!0:j=!0,e&&(g&&h&&j&&i||e.length<this.Diff_EditCost/2&&3==g+h+j+i))a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,e=null,g&&h?(j=i=!0,d=0):(d--,f=0<d?c[d-1]:-1,j=i=!1),b=!0;f++}b&&this.diff_cleanupMerge(a)};
+diff_match_patch.prototype.diff_cleanupMerge=function(a){a.push([0,""]);for(var b=0,c=0,d=0,e="",f="",g;b<a.length;)switch(a[b][0]){case 1:d++;f+=a[b][1];b++;break;case -1:c++;e+=a[b][1];b++;break;case 0:1<c+d?(0!==c&&0!==d&&(g=this.diff_commonPrefix(f,e),0!==g&&(0<b-c-d&&0==a[b-c-d-1][0]?a[b-c-d-1][1]+=f.substring(0,g):(a.splice(0,0,[0,f.substring(0,g)]),b++),f=f.substring(g),e=e.substring(g)),g=this.diff_commonSuffix(f,e),0!==g&&(a[b][1]=f.substring(f.length-g)+a[b][1],f=f.substring(0,f.length-
+g),e=e.substring(0,e.length-g))),0===c?a.splice(b-d,c+d,[1,f]):0===d?a.splice(b-c,c+d,[-1,e]):a.splice(b-c-d,c+d,[-1,e],[1,f]),b=b-c-d+(c?1:0)+(d?1:0)+1):0!==b&&0==a[b-1][0]?(a[b-1][1]+=a[b][1],a.splice(b,1)):b++,c=d=0,f=e=""}""===a[a.length-1][1]&&a.pop();c=!1;for(b=1;b<a.length-1;)0==a[b-1][0]&&0==a[b+1][0]&&(a[b][1].substring(a[b][1].length-a[b-1][1].length)==a[b-1][1]?(a[b][1]=a[b-1][1]+a[b][1].substring(0,a[b][1].length-a[b-1][1].length),a[b+1][1]=a[b-1][1]+a[b+1][1],a.splice(b-1,1),c=!0):a[b][1].substring(0,
+a[b+1][1].length)==a[b+1][1]&&(a[b-1][1]+=a[b+1][1],a[b][1]=a[b][1].substring(a[b+1][1].length)+a[b+1][1],a.splice(b+1,1),c=!0)),b++;c&&this.diff_cleanupMerge(a)};diff_match_patch.prototype.diff_xIndex=function(a,b){var c=0,d=0,e=0,f=0,g;for(g=0;g<a.length;g++){1!==a[g][0]&&(c+=a[g][1].length);-1!==a[g][0]&&(d+=a[g][1].length);if(c>b)break;e=c;f=d}return a.length!=g&&-1===a[g][0]?f:f+(b-e)};
+diff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=/</g,e=/>/g,f=/\n/g,g=0;g<a.length;g++){var h=a[g][0],j=a[g][1],j=j.replace(c,"&").replace(d,"<").replace(e,">").replace(f,"¶<br>");switch(h){case 1:b[g]='<ins style="background:#e6ffe6;">'+j+"</ins>";break;case -1:b[g]='<del style="background:#ffe6e6;">'+j+"</del>";break;case 0:b[g]="<span>"+j+"</span>"}}return b.join("")};
+diff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;c<a.length;c++)1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_text2=function(a){for(var b=[],c=0;c<a.length;c++)-1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_levenshtein=function(a){for(var b=0,c=0,d=0,e=0;e<a.length;e++){var f=a[e][0],g=a[e][1];switch(f){case 1:c+=g.length;break;case -1:d+=g.length;break;case 0:b+=Math.max(c,d),d=c=0}}return b+=Math.max(c,d)};
+diff_match_patch.prototype.diff_toDelta=function(a){for(var b=[],c=0;c<a.length;c++)switch(a[c][0]){case 1:b[c]="+"+encodeURI(a[c][1]);break;case -1:b[c]="-"+a[c][1].length;break;case 0:b[c]="="+a[c][1].length}return b.join("\t").replace(/%20/g," ")};
+diff_match_patch.prototype.diff_fromDelta=function(a,b){for(var c=[],d=0,e=0,f=b.split(/\t/g),g=0;g<f.length;g++){var h=f[g].substring(1);switch(f[g].charAt(0)){case "+":try{c[d++]=[1,decodeURI(h)]}catch(j){throw Error("Illegal escape in diff_fromDelta: "+h);}break;case "-":case "=":var i=parseInt(h,10);if(isNaN(i)||0>i)throw Error("Invalid number in diff_fromDelta: "+h);h=a.substring(e,e+=i);"="==f[g].charAt(0)?c[d++]=[0,h]:c[d++]=[-1,h];break;default:if(f[g])throw Error("Invalid diff operation in diff_fromDelta: "+
+f[g]);}}if(e!=a.length)throw Error("Delta length ("+e+") does not equal source text length ("+a.length+").");return c};diff_match_patch.prototype.match_main=function(a,b,c){if(null==a||null==b||null==c)throw Error("Null input. (match_main)");c=Math.max(0,Math.min(c,a.length));return a==b?0:a.length?a.substring(c,c+b.length)==b?c:this.match_bitap_(a,b,c):-1};
+diff_match_patch.prototype.match_bitap_=function(a,b,c){function d(a,d){var e=a/b.length,g=Math.abs(c-d);return!f.Match_Distance?g?1:e:e+g/f.Match_Distance}if(b.length>this.Match_MaxBits)throw Error("Pattern too long for this browser.");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));for(var j=1<<b.length-1,h=-1,i,k,q=b.length+a.length,r,t=0;t<b.length;t++){i=0;for(k=q;i<k;)d(t,c+
+k)<=g?i=k:q=k,k=Math.floor((q-i)/2+i);q=k;i=Math.max(1,c-k+1);var p=Math.min(c+k,a.length)+b.length;k=Array(p+2);for(k[p+1]=(1<<t)-1;p>=i;p--){var w=e[a.charAt(p-1)];k[p]=0===t?(k[p+1]<<1|1)&w:(k[p+1]<<1|1)&w|((r[p+1]|r[p])<<1|1)|r[p+1];if(k[p]&j&&(w=d(t,p-1),w<=g))if(g=w,h=p-1,h>c)i=Math.max(1,2*c-h);else break}if(d(t+1,c)>g)break;r=k}return h};
+diff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c<a.length;c++)b[a.charAt(c)]=0;for(c=0;c<a.length;c++)b[a.charAt(c)]|=1<<a.length-c-1;return b};
+diff_match_patch.prototype.patch_addContext_=function(a,b){if(0!=b.length){for(var c=b.substring(a.start2,a.start2+a.length1),d=0;b.indexOf(c)!=b.lastIndexOf(c)&&c.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;)d+=this.Patch_Margin,c=b.substring(a.start2-d,a.start2+a.length1+d);d+=this.Patch_Margin;(c=b.substring(a.start2-d,a.start2))&&a.diffs.unshift([0,c]);(d=b.substring(a.start2+a.length1,a.start2+a.length1+d))&&a.diffs.push([0,d]);a.start1-=c.length;a.start2-=c.length;a.length1+=
+c.length+d.length;a.length2+=c.length+d.length}};
+diff_match_patch.prototype.patch_make=function(a,b,c){var d;if("string"==typeof a&&"string"==typeof b&&"undefined"==typeof c)d=a,b=this.diff_main(d,b,!0),2<b.length&&(this.diff_cleanupSemantic(b),this.diff_cleanupEfficiency(b));else if(a&&"object"==typeof a&&"undefined"==typeof b&&"undefined"==typeof c)b=a,d=this.diff_text1(b);else if("string"==typeof a&&b&&"object"==typeof b&&"undefined"==typeof c)d=a;else if("string"==typeof a&&"string"==typeof b&&c&&"object"==typeof c)d=a,b=c;else throw Error("Unknown call format to patch_make.");
+if(0===b.length)return[];c=[];a=new diff_match_patch.patch_obj;for(var e=0,f=0,g=0,h=d,j=0;j<b.length;j++){var i=b[j][0],k=b[j][1];!e&&0!==i&&(a.start1=f,a.start2=g);switch(i){case 1:a.diffs[e++]=b[j];a.length2+=k.length;d=d.substring(0,g)+k+d.substring(g);break;case -1:a.length1+=k.length;a.diffs[e++]=b[j];d=d.substring(0,g)+d.substring(g+k.length);break;case 0:k.length<=2*this.Patch_Margin&&e&&b.length!=j+1?(a.diffs[e++]=b[j],a.length1+=k.length,a.length2+=k.length):k.length>=2*this.Patch_Margin&&
+e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}1!==i&&(f+=k.length);-1!==i&&(g+=k.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};diff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c],e=new diff_match_patch.patch_obj;e.diffs=[];for(var f=0;f<d.diffs.length;f++)e.diffs[f]=d.diffs[f].slice();e.start1=d.start1;e.start2=d.start2;e.length1=d.length1;e.length2=d.length2;b[c]=e}return b};
+diff_match_patch.prototype.patch_apply=function(a,b){if(0==a.length)return[b,[]];a=this.patch_deepCopy(a);var c=this.patch_addPadding(a);b=c+b+c;this.patch_splitMax(a);for(var d=0,e=[],f=0;f<a.length;f++){var g=a[f].start2+d,h=this.diff_text1(a[f].diffs),j,i=-1;if(h.length>this.Match_MaxBits){if(j=this.match_main(b,h.substring(0,this.Match_MaxBits),g),-1!=j&&(i=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==i||j>=i))j=-1}else j=this.match_main(b,h,g);
+if(-1==j)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=j-g,g=-1==i?b.substring(j,j+h.length):b.substring(j,i+this.Match_MaxBits),h==g)b=b.substring(0,j)+this.diff_text2(a[f].diffs)+b.substring(j+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);for(var h=0,k,i=0;i<a[f].diffs.length;i++){var q=a[f].diffs[i];0!==q[0]&&(k=this.diff_xIndex(g,h));1===q[0]?b=b.substring(0,
+j+k)+q[1]+b.substring(j+k):-1===q[0]&&(b=b.substring(0,j+k)+b.substring(j+this.diff_xIndex(g,h+q[1].length)));-1!==q[0]&&(h+=q[1].length)}}}b=b.substring(c.length,b.length-c.length);return[b,e]};
+diff_match_patch.prototype.patch_addPadding=function(a){for(var b=this.Patch_Margin,c="",d=1;d<=b;d++)c+=String.fromCharCode(d);for(d=0;d<a.length;d++)a[d].start1+=b,a[d].start2+=b;var d=a[0],e=d.diffs;if(0==e.length||0!=e[0][0])e.unshift([0,c]),d.start1-=b,d.start2-=b,d.length1+=b,d.length2+=b;else if(b>e[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||0!=e[e.length-1][0]?(e.push([0,
+c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c};
+diff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c<a.length;c++)if(!(a[c].length1<=b)){var d=a[c];a.splice(c--,1);for(var e=d.start1,f=d.start2,g="";0!==d.diffs.length;){var h=new diff_match_patch.patch_obj,j=!0;h.start1=e-g.length;h.start2=f-g.length;""!==g&&(h.length1=h.length2=g.length,h.diffs.push([0,g]));for(;0!==d.diffs.length&&h.length1<b-this.Patch_Margin;){var g=d.diffs[0][0],i=d.diffs[0][1];1===g?(h.length2+=i.length,f+=i.length,h.diffs.push(d.diffs.shift()),
+j=!1):-1===g&&1==h.diffs.length&&0==h.diffs[0][0]&&i.length>2*b?(h.length1+=i.length,e+=i.length,j=!1,h.diffs.push([g,i]),d.diffs.shift()):(i=i.substring(0,b-h.length1-this.Patch_Margin),h.length1+=i.length,e+=i.length,0===g?(h.length2+=i.length,f+=i.length):j=!1,h.diffs.push([g,i]),i==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(i.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);i=this.diff_text1(d.diffs).substring(0,this.Patch_Margin);""!==i&&
+(h.length1+=i.length,h.length2+=i.length,0!==h.diffs.length&&0===h.diffs[h.diffs.length-1][0]?h.diffs[h.diffs.length-1][1]+=i:h.diffs.push([0,i]));j||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b.join("")};
+diff_match_patch.prototype.patch_fromText=function(a){var b=[];if(!a)return b;a=a.split("\n");for(var c=0,d=/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;c<a.length;){var e=a[c].match(d);if(!e)throw Error("Invalid patch string: "+a[c]);var f=new diff_match_patch.patch_obj;b.push(f);f.start1=parseInt(e[1],10);""===e[2]?(f.start1--,f.length1=1):"0"==e[2]?f.length1=0:(f.start1--,f.length1=parseInt(e[2],10));f.start2=parseInt(e[3],10);""===e[4]?(f.start2--,f.length2=1):"0"==e[4]?f.length2=0:(f.start2--,f.length2=
+parseInt(e[4],10));for(c++;c<a.length;){e=a[c].charAt(0);try{var g=decodeURI(a[c].substring(1))}catch(h){throw Error("Illegal escape in patch_fromText: "+g);}if("-"==e)f.diffs.push([-1,g]);else if("+"==e)f.diffs.push([1,g]);else if(" "==e)f.diffs.push([0,g]);else if("@"==e)break;else if(""!==e)throw Error('Invalid patch mode "'+e+'" in: '+g);c++}}return b};diff_match_patch.patch_obj=function(){this.diffs=[];this.start2=this.start1=null;this.length2=this.length1=0};
+diff_match_patch.patch_obj.prototype.toString=function(){var a,b;a=0===this.length1?this.start1+",0":1==this.length1?this.start1+1:this.start1+1+","+this.length1;b=0===this.length2?this.start2+",0":1==this.length2?this.start2+1:this.start2+1+","+this.length2;a=["@@ -"+a+" +"+b+" @@\n"];var c;for(b=0;b<this.diffs.length;b++){switch(this.diffs[b][0]){case 1:c="+";break;case -1:c="-";break;case 0:c=" "}a[b+1]=c+encodeURI(this.diffs[b][1])+"\n"}return a.join("").replace(/%20/g," ")};
+this.diff_match_patch=diff_match_patch;this.DIFF_DELETE=-1;this.DIFF_INSERT=1;this.DIFF_EQUAL=0;})();
diff --git a/app/gui/html/vendor/codemirror/addon/merge/merge.css b/app/gui/html/vendor/codemirror/addon/merge/merge.css
new file mode 100644
index 0000000..63237fc
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/merge/merge.css
@@ -0,0 +1,92 @@
+.CodeMirror-merge {
+  position: relative;
+  border: 1px solid #ddd;
+  white-space: pre;
+}
+
+.CodeMirror-merge, .CodeMirror-merge .CodeMirror {
+  height: 350px;
+}
+
+.CodeMirror-merge-2pane .CodeMirror-merge-pane { width: 47%; }
+.CodeMirror-merge-2pane .CodeMirror-merge-gap { width: 6%; }
+.CodeMirror-merge-3pane .CodeMirror-merge-pane { width: 31%; }
+.CodeMirror-merge-3pane .CodeMirror-merge-gap { width: 3.5%; }
+
+.CodeMirror-merge-pane {
+  display: inline-block;
+  white-space: normal;
+  vertical-align: top;
+}
+.CodeMirror-merge-pane-rightmost {
+  position: absolute;
+  right: 0px;
+  z-index: 1;
+}
+
+.CodeMirror-merge-gap {
+  z-index: 2;
+  display: inline-block;
+  height: 100%;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  overflow: hidden;
+  border-left: 1px solid #ddd;
+  border-right: 1px solid #ddd;
+  position: relative;
+  background: #f8f8f8;
+}
+
+.CodeMirror-merge-scrolllock-wrap {
+  position: absolute;
+  bottom: 0; left: 50%;
+}
+.CodeMirror-merge-scrolllock {
+  position: relative;
+  left: -50%;
+  cursor: pointer;
+  color: #555;
+  line-height: 1;
+}
+
+.CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right {
+  position: absolute;
+  left: 0; top: 0;
+  right: 0; bottom: 0;
+  line-height: 1;
+}
+
+.CodeMirror-merge-copy {
+  position: absolute;
+  cursor: pointer;
+  color: #44c;
+}
+
+.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; }
+.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy { right: 2px; }
+
+.CodeMirror-merge-r-inserted, .CodeMirror-merge-l-inserted {
+  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==);
+  background-position: bottom left;
+  background-repeat: repeat-x;
+}
+
+.CodeMirror-merge-r-deleted, .CodeMirror-merge-l-deleted {
+  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==);
+  background-position: bottom left;
+  background-repeat: repeat-x;
+}
+
+.CodeMirror-merge-r-chunk { background: #ffffe0; }
+.CodeMirror-merge-r-chunk-start { border-top: 1px solid #ee8; }
+.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #ee8; }
+.CodeMirror-merge-r-connect { fill: #ffffe0; stroke: #ee8; stroke-width: 1px; }
+
+.CodeMirror-merge-l-chunk { background: #eef; }
+.CodeMirror-merge-l-chunk-start { border-top: 1px solid #88e; }
+.CodeMirror-merge-l-chunk-end { border-bottom: 1px solid #88e; }
+.CodeMirror-merge-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; }
+
+.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; }
+.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; }
+.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; }
diff --git a/app/gui/html/vendor/codemirror/addon/merge/merge.js b/app/gui/html/vendor/codemirror/addon/merge/merge.js
new file mode 100644
index 0000000..fc1cb2f
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/merge/merge.js
@@ -0,0 +1,505 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+  // declare global: diff_match_patch, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL
+
+  var Pos = CodeMirror.Pos;
+  var svgNS = "http://www.w3.org/2000/svg";
+
+  function DiffView(mv, type) {
+    this.mv = mv;
+    this.type = type;
+    this.classes = type == "left"
+      ? {chunk: "CodeMirror-merge-l-chunk",
+         start: "CodeMirror-merge-l-chunk-start",
+         end: "CodeMirror-merge-l-chunk-end",
+         insert: "CodeMirror-merge-l-inserted",
+         del: "CodeMirror-merge-l-deleted",
+         connect: "CodeMirror-merge-l-connect"}
+      : {chunk: "CodeMirror-merge-r-chunk",
+         start: "CodeMirror-merge-r-chunk-start",
+         end: "CodeMirror-merge-r-chunk-end",
+         insert: "CodeMirror-merge-r-inserted",
+         del: "CodeMirror-merge-r-deleted",
+         connect: "CodeMirror-merge-r-connect"};
+  }
+
+  DiffView.prototype = {
+    constructor: DiffView,
+    init: function(pane, orig, options) {
+      this.edit = this.mv.edit;
+      this.orig = CodeMirror(pane, copyObj({value: orig, readOnly: true}, copyObj(options)));
+
+      this.diff = getDiff(asString(orig), asString(options.value));
+      this.diffOutOfDate = false;
+
+      this.showDifferences = options.showDifferences !== false;
+      this.forceUpdate = registerUpdate(this);
+      setScrollLock(this, true, false);
+      registerScroll(this);
+    },
+    setShowDifferences: function(val) {
+      val = val !== false;
+      if (val != this.showDifferences) {
+        this.showDifferences = val;
+        this.forceUpdate("full");
+      }
+    }
+  };
+
+  function registerUpdate(dv) {
+    var edit = {from: 0, to: 0, marked: []};
+    var orig = {from: 0, to: 0, marked: []};
+    var debounceChange;
+    function update(mode) {
+      if (mode == "full") {
+        if (dv.svg) clear(dv.svg);
+        clear(dv.copyButtons);
+        clearMarks(dv.edit, edit.marked, dv.classes);
+        clearMarks(dv.orig, orig.marked, dv.classes);
+        edit.from = edit.to = orig.from = orig.to = 0;
+      }
+      if (dv.diffOutOfDate) {
+        dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue());
+        dv.diffOutOfDate = false;
+        CodeMirror.signal(dv.edit, "updateDiff", dv.diff);
+      }
+      if (dv.showDifferences) {
+        updateMarks(dv.edit, dv.diff, edit, DIFF_INSERT, dv.classes);
+        updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes);
+      }
+      drawConnectors(dv);
+    }
+    function set(slow) {
+      clearTimeout(debounceChange);
+      debounceChange = setTimeout(update, slow == true ? 250 : 100);
+    }
+    function change() {
+      if (!dv.diffOutOfDate) {
+        dv.diffOutOfDate = true;
+        edit.from = edit.to = orig.from = orig.to = 0;
+      }
+      set(true);
+    }
+    dv.edit.on("change", change);
+    dv.orig.on("change", change);
+    dv.edit.on("markerAdded", set);
+    dv.edit.on("markerCleared", set);
+    dv.orig.on("markerAdded", set);
+    dv.orig.on("markerCleared", set);
+    dv.edit.on("viewportChange", set);
+    dv.orig.on("viewportChange", set);
+    update();
+    return update;
+  }
+
+  function registerScroll(dv) {
+    dv.edit.on("scroll", function() {
+      syncScroll(dv, DIFF_INSERT) && drawConnectors(dv);
+    });
+    dv.orig.on("scroll", function() {
+      syncScroll(dv, DIFF_DELETE) && drawConnectors(dv);
+    });
+  }
+
+  function syncScroll(dv, type) {
+    // Change handler will do a refresh after a timeout when diff is out of date
+    if (dv.diffOutOfDate) return false;
+    if (!dv.lockScroll) return true;
+    var editor, other, now = +new Date;
+    if (type == DIFF_INSERT) { editor = dv.edit; other = dv.orig; }
+    else { editor = dv.orig; other = dv.edit; }
+    // Don't take action if the position of this editor was recently set
+    // (to prevent feedback loops)
+    if (editor.state.scrollSetBy == dv && (editor.state.scrollSetAt || 0) + 50 > now) return false;
+
+    var sInfo = editor.getScrollInfo(), halfScreen = .5 * sInfo.clientHeight, midY = sInfo.top + halfScreen;
+    var mid = editor.lineAtHeight(midY, "local");
+    var around = chunkBoundariesAround(dv.diff, mid, type == DIFF_INSERT);
+    var off = getOffsets(editor, type == DIFF_INSERT ? around.edit : around.orig);
+    var offOther = getOffsets(other, type == DIFF_INSERT ? around.orig : around.edit);
+    var ratio = (midY - off.top) / (off.bot - off.top);
+    var targetPos = (offOther.top - halfScreen) + ratio * (offOther.bot - offOther.top);
+
+    var botDist, mix;
+    // Some careful tweaking to make sure no space is left out of view
+    // when scrolling to top or bottom.
+    if (targetPos > sInfo.top && (mix = sInfo.top / halfScreen) < 1) {
+      targetPos = targetPos * mix + sInfo.top * (1 - mix);
+    } else if ((botDist = sInfo.height - sInfo.clientHeight - sInfo.top) < halfScreen) {
+      var otherInfo = other.getScrollInfo();
+      var botDistOther = otherInfo.height - otherInfo.clientHeight - targetPos;
+      if (botDistOther > botDist && (mix = botDist / halfScreen) < 1)
+        targetPos = targetPos * mix + (otherInfo.height - otherInfo.clientHeight - botDist) * (1 - mix);
+    }
+
+    other.scrollTo(sInfo.left, targetPos);
+    other.state.scrollSetAt = now;
+    other.state.scrollSetBy = dv;
+    return true;
+  }
+
+  function getOffsets(editor, around) {
+    var bot = around.after;
+    if (bot == null) bot = editor.lastLine() + 1;
+    return {top: editor.heightAtLine(around.before || 0, "local"),
+            bot: editor.heightAtLine(bot, "local")};
+  }
+
+  function setScrollLock(dv, val, action) {
+    dv.lockScroll = val;
+    if (val && action != false) syncScroll(dv, DIFF_INSERT) && drawConnectors(dv);
+    dv.lockButton.innerHTML = val ? "\u21db\u21da" : "\u21db  \u21da";
+  }
+
+  // Updating the marks for editor content
+
+  function clearMarks(editor, arr, classes) {
+    for (var i = 0; i < arr.length; ++i) {
+      var mark = arr[i];
+      if (mark instanceof CodeMirror.TextMarker) {
+        mark.clear();
+      } else {
+        editor.removeLineClass(mark, "background", classes.chunk);
+        editor.removeLineClass(mark, "background", classes.start);
+        editor.removeLineClass(mark, "background", classes.end);
+      }
+    }
+    arr.length = 0;
+  }
+
+  // FIXME maybe add a margin around viewport to prevent too many updates
+  function updateMarks(editor, diff, state, type, classes) {
+    var vp = editor.getViewport();
+    editor.operation(function() {
+      if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {
+        clearMarks(editor, state.marked, classes);
+        markChanges(editor, diff, type, state.marked, vp.from, vp.to, classes);
+        state.from = vp.from; state.to = vp.to;
+      } else {
+        if (vp.from < state.from) {
+          markChanges(editor, diff, type, state.marked, vp.from, state.from, classes);
+          state.from = vp.from;
+        }
+        if (vp.to > state.to) {
+          markChanges(editor, diff, type, state.marked, state.to, vp.to, classes);
+          state.to = vp.to;
+        }
+      }
+    });
+  }
+
+  function markChanges(editor, diff, type, marks, from, to, classes) {
+    var pos = Pos(0, 0);
+    var top = Pos(from, 0), bot = editor.clipPos(Pos(to - 1));
+    var cls = type == DIFF_DELETE ? classes.del : classes.insert;
+    function markChunk(start, end) {
+      var bfrom = Math.max(from, start), bto = Math.min(to, end);
+      for (var i = bfrom; i < bto; ++i) {
+        var line = editor.addLineClass(i, "background", classes.chunk);
+        if (i == start) editor.addLineClass(line, "background", classes.start);
+        if (i == end - 1) editor.addLineClass(line, "background", classes.end);
+        marks.push(line);
+      }
+      // When the chunk is empty, make sure a horizontal line shows up
+      if (start == end && bfrom == end && bto == end) {
+        if (bfrom)
+          marks.push(editor.addLineClass(bfrom - 1, "background", classes.end));
+        else
+          marks.push(editor.addLineClass(bfrom, "background", classes.start));
+      }
+    }
+
+    var chunkStart = 0;
+    for (var i = 0; i < diff.length; ++i) {
+      var part = diff[i], tp = part[0], str = part[1];
+      if (tp == DIFF_EQUAL) {
+        var cleanFrom = pos.line + (startOfLineClean(diff, i) ? 0 : 1);
+        moveOver(pos, str);
+        var cleanTo = pos.line + (endOfLineClean(diff, i) ? 1 : 0);
+        if (cleanTo > cleanFrom) {
+          if (i) markChunk(chunkStart, cleanFrom);
+          chunkStart = cleanTo;
+        }
+      } else {
+        if (tp == type) {
+          var end = moveOver(pos, str, true);
+          var a = posMax(top, pos), b = posMin(bot, end);
+          if (!posEq(a, b))
+            marks.push(editor.markText(a, b, {className: cls}));
+          pos = end;
+        }
+      }
+    }
+    if (chunkStart <= pos.line) markChunk(chunkStart, pos.line + 1);
+  }
+
+  // Updating the gap between editor and original
+
+  function drawConnectors(dv) {
+    if (!dv.showDifferences) return;
+
+    if (dv.svg) {
+      clear(dv.svg);
+      var w = dv.gap.offsetWidth;
+      attrs(dv.svg, "width", w, "height", dv.gap.offsetHeight);
+    }
+    clear(dv.copyButtons);
+
+    var flip = dv.type == "left";
+    var vpEdit = dv.edit.getViewport(), vpOrig = dv.orig.getViewport();
+    var sTopEdit = dv.edit.getScrollInfo().top, sTopOrig = dv.orig.getScrollInfo().top;
+    iterateChunks(dv.diff, function(topOrig, botOrig, topEdit, botEdit) {
+      if (topEdit > vpEdit.to || botEdit < vpEdit.from ||
+          topOrig > vpOrig.to || botOrig < vpOrig.from)
+        return;
+      var topLpx = dv.orig.heightAtLine(topOrig, "local") - sTopOrig, top = topLpx;
+      if (dv.svg) {
+        var topRpx = dv.edit.heightAtLine(topEdit, "local") - sTopEdit;
+        if (flip) { var tmp = topLpx; topLpx = topRpx; topRpx = tmp; }
+        var botLpx = dv.orig.heightAtLine(botOrig, "local") - sTopOrig;
+        var botRpx = dv.edit.heightAtLine(botEdit, "local") - sTopEdit;
+        if (flip) { var tmp = botLpx; botLpx = botRpx; botRpx = tmp; }
+        var curveTop = " C " + w/2 + " " + topRpx + " " + w/2 + " " + topLpx + " " + (w + 2) + " " + topLpx;
+        var curveBot = " C " + w/2 + " " + botLpx + " " + w/2 + " " + botRpx + " -1 " + botRpx;
+        attrs(dv.svg.appendChild(document.createElementNS(svgNS, "path")),
+              "d", "M -1 " + topRpx + curveTop + " L " + (w + 2) + " " + botLpx + curveBot + " z",
+              "class", dv.classes.connect);
+      }
+      var copy = dv.copyButtons.appendChild(elt("div", dv.type == "left" ? "\u21dd" : "\u21dc",
+                                                "CodeMirror-merge-copy"));
+      copy.title = "Revert chunk";
+      copy.chunk = {topEdit: topEdit, botEdit: botEdit, topOrig: topOrig, botOrig: botOrig};
+      copy.style.top = top + "px";
+    });
+  }
+
+  function copyChunk(dv, chunk) {
+    if (dv.diffOutOfDate) return;
+    dv.edit.replaceRange(dv.orig.getRange(Pos(chunk.topOrig, 0), Pos(chunk.botOrig, 0)),
+                         Pos(chunk.topEdit, 0), Pos(chunk.botEdit, 0));
+  }
+
+  // Merge view, containing 0, 1, or 2 diff views.
+
+  var MergeView = CodeMirror.MergeView = function(node, options) {
+    if (!(this instanceof MergeView)) return new MergeView(node, options);
+
+    var origLeft = options.origLeft, origRight = options.origRight == null ? options.orig : options.origRight;
+    var hasLeft = origLeft != null, hasRight = origRight != null;
+    var panes = 1 + (hasLeft ? 1 : 0) + (hasRight ? 1 : 0);
+    var wrap = [], left = this.left = null, right = this.right = null;
+
+    if (hasLeft) {
+      left = this.left = new DiffView(this, "left");
+      var leftPane = elt("div", null, "CodeMirror-merge-pane");
+      wrap.push(leftPane);
+      wrap.push(buildGap(left));
+    }
+
+    var editPane = elt("div", null, "CodeMirror-merge-pane");
+    wrap.push(editPane);
+
+    if (hasRight) {
+      right = this.right = new DiffView(this, "right");
+      wrap.push(buildGap(right));
+      var rightPane = elt("div", null, "CodeMirror-merge-pane");
+      wrap.push(rightPane);
+    }
+
+    (hasRight ? rightPane : editPane).className += " CodeMirror-merge-pane-rightmost";
+
+    wrap.push(elt("div", null, null, "height: 0; clear: both;"));
+    var wrapElt = this.wrap = node.appendChild(elt("div", wrap, "CodeMirror-merge CodeMirror-merge-" + panes + "pane"));
+    this.edit = CodeMirror(editPane, copyObj(options));
+
+    if (left) left.init(leftPane, origLeft, options);
+    if (right) right.init(rightPane, origRight, options);
+
+    var onResize = function() {
+      if (left) drawConnectors(left);
+      if (right) drawConnectors(right);
+    };
+    CodeMirror.on(window, "resize", onResize);
+    var resizeInterval = setInterval(function() {
+      for (var p = wrapElt.parentNode; p && p != document.body; p = p.parentNode) {}
+      if (!p) { clearInterval(resizeInterval); CodeMirror.off(window, "resize", onResize); }
+    }, 5000);
+  };
+
+  function buildGap(dv) {
+    var lock = dv.lockButton = elt("div", null, "CodeMirror-merge-scrolllock");
+    lock.title = "Toggle locked scrolling";
+    var lockWrap = elt("div", [lock], "CodeMirror-merge-scrolllock-wrap");
+    CodeMirror.on(lock, "click", function() { setScrollLock(dv, !dv.lockScroll); });
+    dv.copyButtons = elt("div", null, "CodeMirror-merge-copybuttons-" + dv.type);
+    CodeMirror.on(dv.copyButtons, "click", function(e) {
+      var node = e.target || e.srcElement;
+      if (node.chunk) copyChunk(dv, node.chunk);
+    });
+    var gapElts = [dv.copyButtons, lockWrap];
+    var svg = document.createElementNS && document.createElementNS(svgNS, "svg");
+    if (svg && !svg.createSVGRect) svg = null;
+    dv.svg = svg;
+    if (svg) gapElts.push(svg);
+
+    return dv.gap = elt("div", gapElts, "CodeMirror-merge-gap");
+  }
+
+  MergeView.prototype = {
+    constuctor: MergeView,
+    editor: function() { return this.edit; },
+    rightOriginal: function() { return this.right && this.right.orig; },
+    leftOriginal: function() { return this.left && this.left.orig; },
+    setShowDifferences: function(val) {
+      if (this.right) this.right.setShowDifferences(val);
+      if (this.left) this.left.setShowDifferences(val);
+    },
+    rightChunks: function() {
+      return this.right && getChunks(this.right.diff);
+    },
+    leftChunks: function() {
+      return this.left && getChunks(this.left.diff);
+    }
+  };
+
+  function asString(obj) {
+    if (typeof obj == "string") return obj;
+    else return obj.getValue();
+  }
+
+  // Operations on diffs
+
+  var dmp = new diff_match_patch();
+  function getDiff(a, b) {
+    var diff = dmp.diff_main(a, b);
+    dmp.diff_cleanupSemantic(diff);
+    // The library sometimes leaves in empty parts, which confuse the algorithm
+    for (var i = 0; i < diff.length; ++i) {
+      var part = diff[i];
+      if (!part[1]) {
+        diff.splice(i--, 1);
+      } else if (i && diff[i - 1][0] == part[0]) {
+        diff.splice(i--, 1);
+        diff[i][1] += part[1];
+      }
+    }
+    return diff;
+  }
+
+  function iterateChunks(diff, f) {
+    var startEdit = 0, startOrig = 0;
+    var edit = Pos(0, 0), orig = Pos(0, 0);
+    for (var i = 0; i < diff.length; ++i) {
+      var part = diff[i], tp = part[0];
+      if (tp == DIFF_EQUAL) {
+        var startOff = startOfLineClean(diff, i) ? 0 : 1;
+        var cleanFromEdit = edit.line + startOff, cleanFromOrig = orig.line + startOff;
+        moveOver(edit, part[1], null, orig);
+        var endOff = endOfLineClean(diff, i) ? 1 : 0;
+        var cleanToEdit = edit.line + endOff, cleanToOrig = orig.line + endOff;
+        if (cleanToEdit > cleanFromEdit) {
+          if (i) f(startOrig, cleanFromOrig, startEdit, cleanFromEdit);
+          startEdit = cleanToEdit; startOrig = cleanToOrig;
+        }
+      } else {
+        moveOver(tp == DIFF_INSERT ? edit : orig, part[1]);
+      }
+    }
+    if (startEdit <= edit.line || startOrig <= orig.line)
+      f(startOrig, orig.line + 1, startEdit, edit.line + 1);
+  }
+
+  function getChunks(diff) {
+    var collect = [];
+    iterateChunks(diff, function(topOrig, botOrig, topEdit, botEdit) {
+      collect.push({origFrom: topOrig, origTo: botOrig,
+                    editFrom: topEdit, editTo: botEdit});
+    });
+    return collect;
+  }
+
+  function endOfLineClean(diff, i) {
+    if (i == diff.length - 1) return true;
+    var next = diff[i + 1][1];
+    if (next.length == 1 || next.charCodeAt(0) != 10) return false;
+    if (i == diff.length - 2) return true;
+    next = diff[i + 2][1];
+    return next.length > 1 && next.charCodeAt(0) == 10;
+  }
+
+  function startOfLineClean(diff, i) {
+    if (i == 0) return true;
+    var last = diff[i - 1][1];
+    if (last.charCodeAt(last.length - 1) != 10) return false;
+    if (i == 1) return true;
+    last = diff[i - 2][1];
+    return last.charCodeAt(last.length - 1) == 10;
+  }
+
+  function chunkBoundariesAround(diff, n, nInEdit) {
+    var beforeE, afterE, beforeO, afterO;
+    iterateChunks(diff, function(fromOrig, toOrig, fromEdit, toEdit) {
+      var fromLocal = nInEdit ? fromEdit : fromOrig;
+      var toLocal = nInEdit ? toEdit : toOrig;
+      if (afterE == null) {
+        if (fromLocal > n) { afterE = fromEdit; afterO = fromOrig; }
+        else if (toLocal > n) { afterE = toEdit; afterO = toOrig; }
+      }
+      if (toLocal <= n) { beforeE = toEdit; beforeO = toOrig; }
+      else if (fromLocal <= n) { beforeE = fromEdit; beforeO = fromOrig; }
+    });
+    return {edit: {before: beforeE, after: afterE}, orig: {before: beforeO, after: afterO}};
+  }
+
+  // General utilities
+
+  function elt(tag, content, className, style) {
+    var e = document.createElement(tag);
+    if (className) e.className = className;
+    if (style) e.style.cssText = style;
+    if (typeof content == "string") e.appendChild(document.createTextNode(content));
+    else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
+    return e;
+  }
+
+  function clear(node) {
+    for (var count = node.childNodes.length; count > 0; --count)
+      node.removeChild(node.firstChild);
+  }
+
+  function attrs(elt) {
+    for (var i = 1; i < arguments.length; i += 2)
+      elt.setAttribute(arguments[i], arguments[i+1]);
+  }
+
+  function copyObj(obj, target) {
+    if (!target) target = {};
+    for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop];
+    return target;
+  }
+
+  function moveOver(pos, str, copy, other) {
+    var out = copy ? Pos(pos.line, pos.ch) : pos, at = 0;
+    for (;;) {
+      var nl = str.indexOf("\n", at);
+      if (nl == -1) break;
+      ++out.line;
+      if (other) ++other.line;
+      at = nl + 1;
+    }
+    out.ch = (at ? 0 : out.ch) + (str.length - at);
+    if (other) other.ch = (at ? 0 : other.ch) + (str.length - at);
+    return out;
+  }
+
+  function posMin(a, b) { return (a.line - b.line || a.ch - b.ch) < 0 ? a : b; }
+  function posMax(a, b) { return (a.line - b.line || a.ch - b.ch) > 0 ? a : b; }
+  function posEq(a, b) { return a.line == b.line && a.ch == b.ch; }
+});
diff --git a/app/gui/html/vendor/codemirror/addon/mode/loadmode.js b/app/gui/html/vendor/codemirror/addon/mode/loadmode.js
new file mode 100644
index 0000000..e08c281
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/mode/loadmode.js
@@ -0,0 +1,58 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  if (!CodeMirror.modeURL) CodeMirror.modeURL = "../mode/%N/%N.js";
+
+  var loading = {};
+  function splitCallback(cont, n) {
+    var countDown = n;
+    return function() { if (--countDown == 0) cont(); };
+  }
+  function ensureDeps(mode, cont) {
+    var deps = CodeMirror.modes[mode].dependencies;
+    if (!deps) return cont();
+    var missing = [];
+    for (var i = 0; i < deps.length; ++i) {
+      if (!CodeMirror.modes.hasOwnProperty(deps[i]))
+        missing.push(deps[i]);
+    }
+    if (!missing.length) return cont();
+    var split = splitCallback(cont, missing.length);
+    for (var i = 0; i < missing.length; ++i)
+      CodeMirror.requireMode(missing[i], split);
+  }
+
+  CodeMirror.requireMode = function(mode, cont) {
+    if (typeof mode != "string") mode = mode.name;
+    if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont);
+    if (loading.hasOwnProperty(mode)) return loading[mode].push(cont);
+
+    var script = document.createElement("script");
+    script.src = CodeMirror.modeURL.replace(/%N/g, mode);
+    var others = document.getElementsByTagName("script")[0];
+    others.parentNode.insertBefore(script, others);
+    var list = loading[mode] = [cont];
+    var count = 0, poll = setInterval(function() {
+      if (++count > 100) return clearInterval(poll);
+      if (CodeMirror.modes.hasOwnProperty(mode)) {
+        clearInterval(poll);
+        loading[mode] = null;
+        ensureDeps(mode, function() {
+          for (var i = 0; i < list.length; ++i) list[i]();
+        });
+      }
+    }, 200);
+  };
+
+  CodeMirror.autoLoadMode = function(instance, mode) {
+    if (!CodeMirror.modes.hasOwnProperty(mode))
+      CodeMirror.requireMode(mode, function() {
+        instance.setOption("mode", instance.getOption("mode"));
+      });
+  };
+});
diff --git a/app/gui/html/vendor/codemirror/addon/mode/multiplex.js b/app/gui/html/vendor/codemirror/addon/mode/multiplex.js
new file mode 100644
index 0000000..07385c3
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/mode/multiplex.js
@@ -0,0 +1,115 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.multiplexingMode = function(outer /*, others */) {
+  // Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects
+  var others = Array.prototype.slice.call(arguments, 1);
+  var n_others = others.length;
+
+  function indexOf(string, pattern, from) {
+    if (typeof pattern == "string") return string.indexOf(pattern, from);
+    var m = pattern.exec(from ? string.slice(from) : string);
+    return m ? m.index + from : -1;
+  }
+
+  return {
+    startState: function() {
+      return {
+        outer: CodeMirror.startState(outer),
+        innerActive: null,
+        inner: null
+      };
+    },
+
+    copyState: function(state) {
+      return {
+        outer: CodeMirror.copyState(outer, state.outer),
+        innerActive: state.innerActive,
+        inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner)
+      };
+    },
+
+    token: function(stream, state) {
+      if (!state.innerActive) {
+        var cutOff = Infinity, oldContent = stream.string;
+        for (var i = 0; i < n_others; ++i) {
+          var other = others[i];
+          var found = indexOf(oldContent, other.open, stream.pos);
+          if (found == stream.pos) {
+            stream.match(other.open);
+            state.innerActive = other;
+            state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0);
+            return other.delimStyle;
+          } else if (found != -1 && found < cutOff) {
+            cutOff = found;
+          }
+        }
+        if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff);
+        var outerToken = outer.token(stream, state.outer);
+        if (cutOff != Infinity) stream.string = oldContent;
+        return outerToken;
+      } else {
+        var curInner = state.innerActive, oldContent = stream.string;
+        if (!curInner.close && stream.sol()) {
+          state.innerActive = state.inner = null;
+          return this.token(stream, state);
+        }
+        var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos) : -1;
+        if (found == stream.pos) {
+          stream.match(curInner.close);
+          state.innerActive = state.inner = null;
+          return curInner.delimStyle;
+        }
+        if (found > -1) stream.string = oldContent.slice(0, found);
+        var innerToken = curInner.mode.token(stream, state.inner);
+        if (found > -1) stream.string = oldContent;
+
+        if (curInner.innerStyle) {
+          if (innerToken) innerToken = innerToken + ' ' + curInner.innerStyle;
+          else innerToken = curInner.innerStyle;
+        }
+
+        return innerToken;
+      }
+    },
+
+    indent: function(state, textAfter) {
+      var mode = state.innerActive ? state.innerActive.mode : outer;
+      if (!mode.indent) return CodeMirror.Pass;
+      return mode.indent(state.innerActive ? state.inner : state.outer, textAfter);
+    },
+
+    blankLine: function(state) {
+      var mode = state.innerActive ? state.innerActive.mode : outer;
+      if (mode.blankLine) {
+        mode.blankLine(state.innerActive ? state.inner : state.outer);
+      }
+      if (!state.innerActive) {
+        for (var i = 0; i < n_others; ++i) {
+          var other = others[i];
+          if (other.open === "\n") {
+            state.innerActive = other;
+            state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "") : 0);
+          }
+        }
+      } else if (state.innerActive.close === "\n") {
+        state.innerActive = state.inner = null;
+      }
+    },
+
+    electricChars: outer.electricChars,
+
+    innerMode: function(state) {
+      return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer};
+    }
+  };
+};
+
+});
diff --git a/app/gui/html/vendor/codemirror/addon/mode/multiplex_test.js b/app/gui/html/vendor/codemirror/addon/mode/multiplex_test.js
new file mode 100644
index 0000000..c065635
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/mode/multiplex_test.js
@@ -0,0 +1,30 @@
+(function() {
+  CodeMirror.defineMode("markdown_with_stex", function(){
+    var inner = CodeMirror.getMode({}, "stex");
+    var outer = CodeMirror.getMode({}, "markdown");
+
+    var innerOptions = {
+      open: '$',
+      close: '$',
+      mode: inner,
+      delimStyle: 'delim',
+      innerStyle: 'inner'
+    };
+
+    return CodeMirror.multiplexingMode(outer, innerOptions);
+  });
+
+  var mode = CodeMirror.getMode({}, "markdown_with_stex");
+
+  function MT(name) {
+    test.mode(
+      name,
+      mode,
+      Array.prototype.slice.call(arguments, 1),
+      'multiplexing');
+  }
+
+  MT(
+    "stexInsideMarkdown",
+    "[strong **Equation:**] [delim $][inner&tag \\pi][delim $]");
+})();
diff --git a/app/gui/html/vendor/codemirror/addon/mode/overlay.js b/app/gui/html/vendor/codemirror/addon/mode/overlay.js
new file mode 100644
index 0000000..6f556a1
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/mode/overlay.js
@@ -0,0 +1,70 @@
+// Utility function that allows modes to be combined. The mode given
+// as the base argument takes care of most of the normal mode
+// functionality, but a second (typically simple) mode is used, which
+// can override the style of text. Both modes get to parse all of the
+// text, but when both assign a non-null style to a piece of code, the
+// overlay wins, unless the combine argument was true, in which case
+// the styles are combined.
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.overlayMode = function(base, overlay, combine) {
+  return {
+    startState: function() {
+      return {
+        base: CodeMirror.startState(base),
+        overlay: CodeMirror.startState(overlay),
+        basePos: 0, baseCur: null,
+        overlayPos: 0, overlayCur: null
+      };
+    },
+    copyState: function(state) {
+      return {
+        base: CodeMirror.copyState(base, state.base),
+        overlay: CodeMirror.copyState(overlay, state.overlay),
+        basePos: state.basePos, baseCur: null,
+        overlayPos: state.overlayPos, overlayCur: null
+      };
+    },
+
+    token: function(stream, state) {
+      if (stream.start == state.basePos) {
+        state.baseCur = base.token(stream, state.base);
+        state.basePos = stream.pos;
+      }
+      if (stream.start == state.overlayPos) {
+        stream.pos = stream.start;
+        state.overlayCur = overlay.token(stream, state.overlay);
+        state.overlayPos = stream.pos;
+      }
+      stream.pos = Math.min(state.basePos, state.overlayPos);
+      if (stream.eol()) state.basePos = state.overlayPos = 0;
+
+      if (state.overlayCur == null) return state.baseCur;
+      if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur;
+      else return state.overlayCur;
+    },
+
+    indent: base.indent && function(state, textAfter) {
+      return base.indent(state.base, textAfter);
+    },
+    electricChars: base.electricChars,
+
+    innerMode: function(state) { return {state: state.base, mode: base}; },
+
+    blankLine: function(state) {
+      if (base.blankLine) base.blankLine(state.base);
+      if (overlay.blankLine) overlay.blankLine(state.overlay);
+    }
+  };
+};
+
+});
diff --git a/app/gui/html/vendor/codemirror/addon/runmode/colorize.js b/app/gui/html/vendor/codemirror/addon/runmode/colorize.js
new file mode 100644
index 0000000..0f9530b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/runmode/colorize.js
@@ -0,0 +1,37 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("./runmode"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "./runmode"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var isBlock = /^(p|li|div|h\\d|pre|blockquote|td)$/;
+
+  function textContent(node, out) {
+    if (node.nodeType == 3) return out.push(node.nodeValue);
+    for (var ch = node.firstChild; ch; ch = ch.nextSibling) {
+      textContent(ch, out);
+      if (isBlock.test(node.nodeType)) out.push("\n");
+    }
+  }
+
+  CodeMirror.colorize = function(collection, defaultMode) {
+    if (!collection) collection = document.body.getElementsByTagName("pre");
+
+    for (var i = 0; i < collection.length; ++i) {
+      var node = collection[i];
+      var mode = node.getAttribute("data-lang") || defaultMode;
+      if (!mode) continue;
+
+      var text = [];
+      textContent(node, text);
+      node.innerHTML = "";
+      CodeMirror.runMode(text.join(""), mode, node);
+
+      node.className += " cm-s-default";
+    }
+  };
+});
diff --git a/app/gui/html/vendor/codemirror/addon/runmode/runmode-standalone.js b/app/gui/html/vendor/codemirror/addon/runmode/runmode-standalone.js
new file mode 100644
index 0000000..eaa2b8f
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/runmode/runmode-standalone.js
@@ -0,0 +1,149 @@
+window.CodeMirror = {};
+
+(function() {
+"use strict";
+
+function splitLines(string){ return string.split(/\r?\n|\r/); };
+
+function StringStream(string) {
+  this.pos = this.start = 0;
+  this.string = string;
+  this.lineStart = 0;
+}
+StringStream.prototype = {
+  eol: function() {return this.pos >= this.string.length;},
+  sol: function() {return this.pos == 0;},
+  peek: function() {return this.string.charAt(this.pos) || null;},
+  next: function() {
+    if (this.pos < this.string.length)
+      return this.string.charAt(this.pos++);
+  },
+  eat: function(match) {
+    var ch = this.string.charAt(this.pos);
+    if (typeof match == "string") var ok = ch == match;
+    else var ok = ch && (match.test ? match.test(ch) : match(ch));
+    if (ok) {++this.pos; return ch;}
+  },
+  eatWhile: function(match) {
+    var start = this.pos;
+    while (this.eat(match)){}
+    return this.pos > start;
+  },
+  eatSpace: function() {
+    var start = this.pos;
+    while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
+    return this.pos > start;
+  },
+  skipToEnd: function() {this.pos = this.string.length;},
+  skipTo: function(ch) {
+    var found = this.string.indexOf(ch, this.pos);
+    if (found > -1) {this.pos = found; return true;}
+  },
+  backUp: function(n) {this.pos -= n;},
+  column: function() {return this.start - this.lineStart;},
+  indentation: function() {return 0;},
+  match: function(pattern, consume, caseInsensitive) {
+    if (typeof pattern == "string") {
+      var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
+      var substr = this.string.substr(this.pos, pattern.length);
+      if (cased(substr) == cased(pattern)) {
+        if (consume !== false) this.pos += pattern.length;
+        return true;
+      }
+    } else {
+      var match = this.string.slice(this.pos).match(pattern);
+      if (match && match.index > 0) return null;
+      if (match && consume !== false) this.pos += match[0].length;
+      return match;
+    }
+  },
+  current: function(){return this.string.slice(this.start, this.pos);},
+  hideFirstChars: function(n, inner) {
+    this.lineStart += n;
+    try { return inner(); }
+    finally { this.lineStart -= n; }
+  }
+};
+CodeMirror.StringStream = StringStream;
+
+CodeMirror.startState = function (mode, a1, a2) {
+  return mode.startState ? mode.startState(a1, a2) : true;
+};
+
+var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
+CodeMirror.defineMode = function (name, mode) { modes[name] = mode; };
+CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; };
+CodeMirror.resolveMode = function(spec) {
+  if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
+    spec = mimeModes[spec];
+  } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
+    spec = mimeModes[spec.name];
+  }
+  if (typeof spec == "string") return {name: spec};
+  else return spec || {name: "null"};
+};
+CodeMirror.getMode = function (options, spec) {
+  spec = CodeMirror.resolveMode(spec);
+  var mfactory = modes[spec.name];
+  if (!mfactory) throw new Error("Unknown mode: " + spec);
+  return mfactory(options, spec);
+};
+CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min;
+CodeMirror.defineMode("null", function() {
+  return {token: function(stream) {stream.skipToEnd();}};
+});
+CodeMirror.defineMIME("text/plain", "null");
+
+CodeMirror.runMode = function (string, modespec, callback, options) {
+  var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec);
+
+  if (callback.nodeType == 1) {
+    var tabSize = (options && options.tabSize) || 4;
+    var node = callback, col = 0;
+    node.innerHTML = "";
+    callback = function (text, style) {
+      if (text == "\n") {
+        node.appendChild(document.createElement("br"));
+        col = 0;
+        return;
+      }
+      var content = "";
+      // replace tabs
+      for (var pos = 0; ;) {
+        var idx = text.indexOf("\t", pos);
+        if (idx == -1) {
+          content += text.slice(pos);
+          col += text.length - pos;
+          break;
+        } else {
+          col += idx - pos;
+          content += text.slice(pos, idx);
+          var size = tabSize - col % tabSize;
+          col += size;
+          for (var i = 0; i < size; ++i) content += " ";
+          pos = idx + 1;
+        }
+      }
+
+      if (style) {
+        var sp = node.appendChild(document.createElement("span"));
+        sp.className = "cm-" + style.replace(/ +/g, " cm-");
+        sp.appendChild(document.createTextNode(content));
+      } else {
+        node.appendChild(document.createTextNode(content));
+      }
+    };
+  }
+
+  var lines = splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
+  for (var i = 0, e = lines.length; i < e; ++i) {
+    if (i) callback("\n");
+    var stream = new CodeMirror.StringStream(lines[i]);
+    while (!stream.eol()) {
+      var style = mode.token(stream, state);
+      callback(stream.current(), style, i, stream.start, state);
+      stream.start = stream.pos;
+    }
+  }
+};
+})();
diff --git a/app/gui/html/vendor/codemirror/addon/runmode/runmode.js b/app/gui/html/vendor/codemirror/addon/runmode/runmode.js
new file mode 100644
index 0000000..351840e
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/runmode/runmode.js
@@ -0,0 +1,68 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.runMode = function(string, modespec, callback, options) {
+  var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
+  var ie = /MSIE \d/.test(navigator.userAgent);
+  var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
+
+  if (callback.nodeType == 1) {
+    var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
+    var node = callback, col = 0;
+    node.innerHTML = "";
+    callback = function(text, style) {
+      if (text == "\n") {
+        // Emitting LF or CRLF on IE8 or earlier results in an incorrect display.
+        // Emitting a carriage return makes everything ok.
+        node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text));
+        col = 0;
+        return;
+      }
+      var content = "";
+      // replace tabs
+      for (var pos = 0;;) {
+        var idx = text.indexOf("\t", pos);
+        if (idx == -1) {
+          content += text.slice(pos);
+          col += text.length - pos;
+          break;
+        } else {
+          col += idx - pos;
+          content += text.slice(pos, idx);
+          var size = tabSize - col % tabSize;
+          col += size;
+          for (var i = 0; i < size; ++i) content += " ";
+          pos = idx + 1;
+        }
+      }
+
+      if (style) {
+        var sp = node.appendChild(document.createElement("span"));
+        sp.className = "cm-" + style.replace(/ +/g, " cm-");
+        sp.appendChild(document.createTextNode(content));
+      } else {
+        node.appendChild(document.createTextNode(content));
+      }
+    };
+  }
+
+  var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
+  for (var i = 0, e = lines.length; i < e; ++i) {
+    if (i) callback("\n");
+    var stream = new CodeMirror.StringStream(lines[i]);
+    while (!stream.eol()) {
+      var style = mode.token(stream, state);
+      callback(stream.current(), style, i, stream.start, state);
+      stream.start = stream.pos;
+    }
+  }
+};
+
+});
diff --git a/app/gui/html/vendor/codemirror/addon/runmode/runmode.node.js b/app/gui/html/vendor/codemirror/addon/runmode/runmode.node.js
new file mode 100644
index 0000000..74c39be
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/runmode/runmode.node.js
@@ -0,0 +1,118 @@
+/* Just enough of CodeMirror to run runMode under node.js */
+
+// declare global: StringStream
+
+function splitLines(string){ return string.split(/\r?\n|\r/); };
+
+function StringStream(string) {
+  this.pos = this.start = 0;
+  this.string = string;
+  this.lineStart = 0;
+}
+StringStream.prototype = {
+  eol: function() {return this.pos >= this.string.length;},
+  sol: function() {return this.pos == 0;},
+  peek: function() {return this.string.charAt(this.pos) || null;},
+  next: function() {
+    if (this.pos < this.string.length)
+      return this.string.charAt(this.pos++);
+  },
+  eat: function(match) {
+    var ch = this.string.charAt(this.pos);
+    if (typeof match == "string") var ok = ch == match;
+    else var ok = ch && (match.test ? match.test(ch) : match(ch));
+    if (ok) {++this.pos; return ch;}
+  },
+  eatWhile: function(match) {
+    var start = this.pos;
+    while (this.eat(match)){}
+    return this.pos > start;
+  },
+  eatSpace: function() {
+    var start = this.pos;
+    while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
+    return this.pos > start;
+  },
+  skipToEnd: function() {this.pos = this.string.length;},
+  skipTo: function(ch) {
+    var found = this.string.indexOf(ch, this.pos);
+    if (found > -1) {this.pos = found; return true;}
+  },
+  backUp: function(n) {this.pos -= n;},
+  column: function() {return this.start - this.lineStart;},
+  indentation: function() {return 0;},
+  match: function(pattern, consume, caseInsensitive) {
+    if (typeof pattern == "string") {
+      var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
+      var substr = this.string.substr(this.pos, pattern.length);
+      if (cased(substr) == cased(pattern)) {
+        if (consume !== false) this.pos += pattern.length;
+        return true;
+      }
+    } else {
+      var match = this.string.slice(this.pos).match(pattern);
+      if (match && match.index > 0) return null;
+      if (match && consume !== false) this.pos += match[0].length;
+      return match;
+    }
+  },
+  current: function(){return this.string.slice(this.start, this.pos);},
+  hideFirstChars: function(n, inner) {
+    this.lineStart += n;
+    try { return inner(); }
+    finally { this.lineStart -= n; }
+  }
+};
+exports.StringStream = StringStream;
+
+exports.startState = function(mode, a1, a2) {
+  return mode.startState ? mode.startState(a1, a2) : true;
+};
+
+var modes = exports.modes = {}, mimeModes = exports.mimeModes = {};
+exports.defineMode = function(name, mode) {
+  if (arguments.length > 2) {
+    mode.dependencies = [];
+    for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
+  }
+  modes[name] = mode;
+};
+exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; };
+
+exports.defineMode("null", function() {
+  return {token: function(stream) {stream.skipToEnd();}};
+});
+exports.defineMIME("text/plain", "null");
+
+exports.resolveMode = function(spec) {
+  if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
+    spec = mimeModes[spec];
+  } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
+    spec = mimeModes[spec.name];
+  }
+  if (typeof spec == "string") return {name: spec};
+  else return spec || {name: "null"};
+};
+exports.getMode = function(options, spec) {
+  spec = exports.resolveMode(spec);
+  var mfactory = modes[spec.name];
+  if (!mfactory) throw new Error("Unknown mode: " + spec);
+  return mfactory(options, spec);
+};
+exports.registerHelper = exports.registerGlobalHelper = Math.min;
+
+exports.runMode = function(string, modespec, callback, options) {
+  var mode = exports.getMode({indentUnit: 2}, modespec);
+  var lines = splitLines(string), state = (options && options.state) || exports.startState(mode);
+  for (var i = 0, e = lines.length; i < e; ++i) {
+    if (i) callback("\n");
+    var stream = new exports.StringStream(lines[i]);
+    while (!stream.eol()) {
+      var style = mode.token(stream, state);
+      callback(stream.current(), style, i, stream.start, state);
+      stream.start = stream.pos;
+    }
+  }
+};
+
+require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")];
diff --git a/app/gui/html/vendor/codemirror/addon/scroll/scrollpastend.js b/app/gui/html/vendor/codemirror/addon/scroll/scrollpastend.js
new file mode 100644
index 0000000..467b7aa
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/scroll/scrollpastend.js
@@ -0,0 +1,43 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) {
+    if (old && old != CodeMirror.Init) {
+      cm.off("change", onChange);
+      cm.off("refresh", updateBottomMargin);
+      cm.display.lineSpace.parentNode.style.paddingBottom = "";
+      cm.state.scrollPastEndPadding = null;
+    }
+    if (val) {
+      cm.on("change", onChange);
+      cm.on("refresh", updateBottomMargin);
+      updateBottomMargin(cm);
+    }
+  });
+
+  function onChange(cm, change) {
+    if (CodeMirror.changeEnd(change).line == cm.lastLine())
+      updateBottomMargin(cm);
+  }
+
+  function updateBottomMargin(cm) {
+    var padding = "";
+    if (cm.lineCount() > 1) {
+      var totalH = cm.display.scroller.clientHeight - 30,
+          lastLineH = cm.getLineHandle(cm.lastLine()).height;
+      padding = (totalH - lastLineH) + "px";
+    }
+    if (cm.state.scrollPastEndPadding != padding) {
+      cm.state.scrollPastEndPadding = padding;
+      cm.display.lineSpace.parentNode.style.paddingBottom = padding;
+      cm.setSize();
+    }
+  }
+});
diff --git a/app/gui/html/vendor/codemirror/addon/search/match-highlighter.js b/app/gui/html/vendor/codemirror/addon/search/match-highlighter.js
new file mode 100644
index 0000000..d9c818b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/search/match-highlighter.js
@@ -0,0 +1,100 @@
+// Highlighting text that matches the selection
+//
+// Defines an option highlightSelectionMatches, which, when enabled,
+// will style strings that match the selection throughout the
+// document.
+//
+// The option can be set to true to simply enable it, or to a
+// {minChars, style, showToken} object to explicitly configure it.
+// minChars is the minimum amount of characters that should be
+// selected for the behavior to occur, and style is the token style to
+// apply to the matches. This will be prefixed by "cm-" to create an
+// actual CSS class name. showToken, when enabled, will cause the
+// current token to be highlighted when nothing is selected.
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var DEFAULT_MIN_CHARS = 2;
+  var DEFAULT_TOKEN_STYLE = "matchhighlight";
+  var DEFAULT_DELAY = 100;
+
+  function State(options) {
+    if (typeof options == "object") {
+      this.minChars = options.minChars;
+      this.style = options.style;
+      this.showToken = options.showToken;
+      this.delay = options.delay;
+    }
+    if (this.style == null) this.style = DEFAULT_TOKEN_STYLE;
+    if (this.minChars == null) this.minChars = DEFAULT_MIN_CHARS;
+    if (this.delay == null) this.delay = DEFAULT_DELAY;
+    this.overlay = this.timeout = null;
+  }
+
+  CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) {
+    if (old && old != CodeMirror.Init) {
+      var over = cm.state.matchHighlighter.overlay;
+      if (over) cm.removeOverlay(over);
+      clearTimeout(cm.state.matchHighlighter.timeout);
+      cm.state.matchHighlighter = null;
+      cm.off("cursorActivity", cursorActivity);
+    }
+    if (val) {
+      cm.state.matchHighlighter = new State(val);
+      highlightMatches(cm);
+      cm.on("cursorActivity", cursorActivity);
+    }
+  });
+
+  function cursorActivity(cm) {
+    var state = cm.state.matchHighlighter;
+    clearTimeout(state.timeout);
+    state.timeout = setTimeout(function() {highlightMatches(cm);}, state.delay);
+  }
+
+  function highlightMatches(cm) {
+    cm.operation(function() {
+      var state = cm.state.matchHighlighter;
+      if (state.overlay) {
+        cm.removeOverlay(state.overlay);
+        state.overlay = null;
+      }
+      if (!cm.somethingSelected() && state.showToken) {
+        var re = state.showToken === true ? /[\w$]/ : state.showToken;
+        var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start;
+        while (start && re.test(line.charAt(start - 1))) --start;
+        while (end < line.length && re.test(line.charAt(end))) ++end;
+        if (start < end)
+          cm.addOverlay(state.overlay = makeOverlay(line.slice(start, end), re, state.style));
+        return;
+      }
+      if (cm.getCursor("head").line != cm.getCursor("anchor").line) return;
+      var selection = cm.getSelections()[0].replace(/^\s+|\s+$/g, "");
+      if (selection.length >= state.minChars)
+        cm.addOverlay(state.overlay = makeOverlay(selection, false, state.style));
+    });
+  }
+
+  function boundariesAround(stream, re) {
+    return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) &&
+      (stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos)));
+  }
+
+  function makeOverlay(query, hasBoundary, style) {
+    return {token: function(stream) {
+      if (stream.match(query) &&
+          (!hasBoundary || boundariesAround(stream, hasBoundary)))
+        return style;
+      stream.next();
+      stream.skipTo(query.charAt(0)) || stream.skipToEnd();
+    }};
+  }
+});
diff --git a/app/gui/html/vendor/codemirror/addon/search/search.js b/app/gui/html/vendor/codemirror/addon/search/search.js
new file mode 100644
index 0000000..19f51f1
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/search/search.js
@@ -0,0 +1,155 @@
+// Define search commands. Depends on dialog.js or another
+// implementation of the openDialog method.
+
+// Replace works a little oddly -- it will do the replace on the next
+// Ctrl-G (or whatever is bound to findNext) press. You prevent a
+// replace by making sure the match is no longer selected when hitting
+// Ctrl-G.
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("./searchcursor"), require("../dialog/dialog"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "./searchcursor", "../dialog/dialog"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+  function searchOverlay(query, caseInsensitive) {
+    var startChar;
+    if (typeof query == "string") {
+      startChar = query.charAt(0);
+      query = new RegExp("^" + query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"),
+                         caseInsensitive ? "i" : "");
+    } else {
+      query = new RegExp("^(?:" + query.source + ")", query.ignoreCase ? "i" : "");
+    }
+    return {token: function(stream) {
+      if (stream.match(query)) return "searching";
+      while (!stream.eol()) {
+        stream.next();
+        if (startChar && !caseInsensitive)
+          stream.skipTo(startChar) || stream.skipToEnd();
+        if (stream.match(query, false)) break;
+      }
+    }};
+  }
+
+  function SearchState() {
+    this.posFrom = this.posTo = this.query = null;
+    this.overlay = null;
+  }
+  function getSearchState(cm) {
+    return cm.state.search || (cm.state.search = new SearchState());
+  }
+  function queryCaseInsensitive(query) {
+    return typeof query == "string" && query == query.toLowerCase();
+  }
+  function getSearchCursor(cm, query, pos) {
+    // Heuristic: if the query string is all lowercase, do a case insensitive search.
+    return cm.getSearchCursor(query, pos, queryCaseInsensitive(query));
+  }
+  function dialog(cm, text, shortText, deflt, f) {
+    if (cm.openDialog) cm.openDialog(text, f, {value: deflt});
+    else f(prompt(shortText, deflt));
+  }
+  function confirmDialog(cm, text, shortText, fs) {
+    if (cm.openConfirm) cm.openConfirm(text, fs);
+    else if (confirm(shortText)) fs[0]();
+  }
+  function parseQuery(query) {
+    var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
+    if (isRE) {
+      query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i");
+      if (query.test("")) query = /x^/;
+    } else if (query == "") {
+      query = /x^/;
+    }
+    return query;
+  }
+  var queryDialog =
+    'Search: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
+  function doSearch(cm, rev) {
+    var state = getSearchState(cm);
+    if (state.query) return findNext(cm, rev);
+    dialog(cm, queryDialog, "Search for:", cm.getSelection(), function(query) {
+      cm.operation(function() {
+        if (!query || state.query) return;
+        state.query = parseQuery(query);
+        cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
+        state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
+        cm.addOverlay(state.overlay);
+        state.posFrom = state.posTo = cm.getCursor();
+        findNext(cm, rev);
+      });
+    });
+  }
+  function findNext(cm, rev) {cm.operation(function() {
+    var state = getSearchState(cm);
+    var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
+    if (!cursor.find(rev)) {
+      cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0));
+      if (!cursor.find(rev)) return;
+    }
+    cm.setSelection(cursor.from(), cursor.to());
+    cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
+    state.posFrom = cursor.from(); state.posTo = cursor.to();
+  });}
+  function clearSearch(cm) {cm.operation(function() {
+    var state = getSearchState(cm);
+    if (!state.query) return;
+    state.query = null;
+    cm.removeOverlay(state.overlay);
+  });}
+
+  var replaceQueryDialog =
+    'Replace: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
+  var replacementQueryDialog = 'With: <input type="text" style="width: 10em"/>';
+  var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
+  function replace(cm, all) {
+    dialog(cm, replaceQueryDialog, "Replace:", cm.getSelection(), function(query) {
+      if (!query) return;
+      query = parseQuery(query);
+      dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) {
+        if (all) {
+          cm.operation(function() {
+            for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
+              if (typeof query != "string") {
+                var match = cm.getRange(cursor.from(), cursor.to()).match(query);
+                cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
+              } else cursor.replace(text);
+            }
+          });
+        } else {
+          clearSearch(cm);
+          var cursor = getSearchCursor(cm, query, cm.getCursor());
+          var advance = function() {
+            var start = cursor.from(), match;
+            if (!(match = cursor.findNext())) {
+              cursor = getSearchCursor(cm, query);
+              if (!(match = cursor.findNext()) ||
+                  (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
+            }
+            cm.setSelection(cursor.from(), cursor.to());
+            cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
+            confirmDialog(cm, doReplaceConfirm, "Replace?",
+                          [function() {doReplace(match);}, advance]);
+          };
+          var doReplace = function(match) {
+            cursor.replace(typeof query == "string" ? text :
+                           text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
+            advance();
+          };
+          advance();
+        }
+      });
+    });
+  }
+
+  CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
+  CodeMirror.commands.findNext = doSearch;
+  CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
+  CodeMirror.commands.clearSearch = clearSearch;
+  CodeMirror.commands.replace = replace;
+  CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
+});
diff --git a/app/gui/html/vendor/codemirror/addon/search/searchcursor.js b/app/gui/html/vendor/codemirror/addon/search/searchcursor.js
new file mode 100644
index 0000000..899f44c
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/search/searchcursor.js
@@ -0,0 +1,186 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+  var Pos = CodeMirror.Pos;
+
+  function SearchCursor(doc, query, pos, caseFold) {
+    this.atOccurrence = false; this.doc = doc;
+    if (caseFold == null && typeof query == "string") caseFold = false;
+
+    pos = pos ? doc.clipPos(pos) : Pos(0, 0);
+    this.pos = {from: pos, to: pos};
+
+    // The matches method is filled in based on the type of query.
+    // It takes a position and a direction, and returns an object
+    // describing the next occurrence of the query, or null if no
+    // more matches were found.
+    if (typeof query != "string") { // Regexp match
+      if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g");
+      this.matches = function(reverse, pos) {
+        if (reverse) {
+          query.lastIndex = 0;
+          var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start;
+          for (;;) {
+            query.lastIndex = cutOff;
+            var newMatch = query.exec(line);
+            if (!newMatch) break;
+            match = newMatch;
+            start = match.index;
+            cutOff = match.index + (match[0].length || 1);
+            if (cutOff == line.length) break;
+          }
+          var matchLen = (match && match[0].length) || 0;
+          if (!matchLen) {
+            if (start == 0 && line.length == 0) {match = undefined;}
+            else if (start != doc.getLine(pos.line).length) {
+              matchLen++;
+            }
+          }
+        } else {
+          query.lastIndex = pos.ch;
+          var line = doc.getLine(pos.line), match = query.exec(line);
+          var matchLen = (match && match[0].length) || 0;
+          var start = match && match.index;
+          if (start + matchLen != line.length && !matchLen) matchLen = 1;
+        }
+        if (match && matchLen)
+          return {from: Pos(pos.line, start),
+                  to: Pos(pos.line, start + matchLen),
+                  match: match};
+      };
+    } else { // String query
+      var origQuery = query;
+      if (caseFold) query = query.toLowerCase();
+      var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;};
+      var target = query.split("\n");
+      // Different methods for single-line and multi-line queries
+      if (target.length == 1) {
+        if (!query.length) {
+          // Empty string would match anything and never progress, so
+          // we define it to match nothing instead.
+          this.matches = function() {};
+        } else {
+          this.matches = function(reverse, pos) {
+            if (reverse) {
+              var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig);
+              var match = line.lastIndexOf(query);
+              if (match > -1) {
+                match = adjustPos(orig, line, match);
+                return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};
+              }
+             } else {
+               var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig);
+               var match = line.indexOf(query);
+               if (match > -1) {
+                 match = adjustPos(orig, line, match) + pos.ch;
+                 return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};
+               }
+            }
+          };
+        }
+      } else {
+        var origTarget = origQuery.split("\n");
+        this.matches = function(reverse, pos) {
+          var last = target.length - 1;
+          if (reverse) {
+            if (pos.line - (target.length - 1) < doc.firstLine()) return;
+            if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return;
+            var to = Pos(pos.line, origTarget[last].length);
+            for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln)
+              if (target[i] != fold(doc.getLine(ln))) return;
+            var line = doc.getLine(ln), cut = line.length - origTarget[0].length;
+            if (fold(line.slice(cut)) != target[0]) return;
+            return {from: Pos(ln, cut), to: to};
+          } else {
+            if (pos.line + (target.length - 1) > doc.lastLine()) return;
+            var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length;
+            if (fold(line.slice(cut)) != target[0]) return;
+            var from = Pos(pos.line, cut);
+            for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln)
+              if (target[i] != fold(doc.getLine(ln))) return;
+            if (doc.getLine(ln).slice(0, origTarget[last].length) != target[last]) return;
+            return {from: from, to: Pos(ln, origTarget[last].length)};
+          }
+        };
+      }
+    }
+  }
+
+  SearchCursor.prototype = {
+    findNext: function() {return this.find(false);},
+    findPrevious: function() {return this.find(true);},
+
+    find: function(reverse) {
+      var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to);
+      function savePosAndFail(line) {
+        var pos = Pos(line, 0);
+        self.pos = {from: pos, to: pos};
+        self.atOccurrence = false;
+        return false;
+      }
+
+      for (;;) {
+        if (this.pos = this.matches(reverse, pos)) {
+          this.atOccurrence = true;
+          return this.pos.match || true;
+        }
+        if (reverse) {
+          if (!pos.line) return savePosAndFail(0);
+          pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length);
+        }
+        else {
+          var maxLine = this.doc.lineCount();
+          if (pos.line == maxLine - 1) return savePosAndFail(maxLine);
+          pos = Pos(pos.line + 1, 0);
+        }
+      }
+    },
+
+    from: function() {if (this.atOccurrence) return this.pos.from;},
+    to: function() {if (this.atOccurrence) return this.pos.to;},
+
+    replace: function(newText) {
+      if (!this.atOccurrence) return;
+      var lines = CodeMirror.splitLines(newText);
+      this.doc.replaceRange(lines, this.pos.from, this.pos.to);
+      this.pos.to = Pos(this.pos.from.line + lines.length - 1,
+                        lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0));
+    }
+  };
+
+  // Maps a position in a case-folded line back to a position in the original line
+  // (compensating for codepoints increasing in number during folding)
+  function adjustPos(orig, folded, pos) {
+    if (orig.length == folded.length) return pos;
+    for (var pos1 = Math.min(pos, orig.length);;) {
+      var len1 = orig.slice(0, pos1).toLowerCase().length;
+      if (len1 < pos) ++pos1;
+      else if (len1 > pos) --pos1;
+      else return pos1;
+    }
+  }
+
+  CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
+    return new SearchCursor(this.doc, query, pos, caseFold);
+  });
+  CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) {
+    return new SearchCursor(this, query, pos, caseFold);
+  });
+
+  CodeMirror.defineExtension("selectMatches", function(query, caseFold) {
+    var ranges = [], next;
+    var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold);
+    while (next = cur.findNext()) {
+      if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break;
+      ranges.push({anchor: cur.from(), head: cur.to()});
+    }
+    if (ranges.length)
+      this.setSelections(ranges, 0);
+  });
+});
diff --git a/app/gui/html/vendor/codemirror/addon/selection/active-line.js b/app/gui/html/vendor/codemirror/addon/selection/active-line.js
new file mode 100644
index 0000000..a818f10
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/selection/active-line.js
@@ -0,0 +1,66 @@
+// Because sometimes you need to style the cursor's line.
+//
+// Adds an option 'styleActiveLine' which, when enabled, gives the
+// active line's wrapping <div> the CSS class "CodeMirror-activeline",
+// and gives its background <div> the class "CodeMirror-activeline-background".
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+  var WRAP_CLASS = "CodeMirror-activeline";
+  var BACK_CLASS = "CodeMirror-activeline-background";
+
+  CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
+    var prev = old && old != CodeMirror.Init;
+    if (val && !prev) {
+      cm.state.activeLines = [];
+      updateActiveLines(cm, cm.listSelections());
+      cm.on("beforeSelectionChange", selectionChange);
+    } else if (!val && prev) {
+      cm.off("beforeSelectionChange", selectionChange);
+      clearActiveLines(cm);
+      delete cm.state.activeLines;
+    }
+  });
+
+  function clearActiveLines(cm) {
+    for (var i = 0; i < cm.state.activeLines.length; i++) {
+      cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS);
+      cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS);
+    }
+  }
+
+  function sameArray(a, b) {
+    if (a.length != b.length) return false;
+    for (var i = 0; i < a.length; i++)
+      if (a[i] != b[i]) return false;
+    return true;
+  }
+
+  function updateActiveLines(cm, ranges) {
+    var active = [];
+    for (var i = 0; i < ranges.length; i++) {
+      var line = cm.getLineHandleVisualStart(ranges[i].head.line);
+      if (active[active.length - 1] != line) active.push(line);
+    }
+    if (sameArray(cm.state.activeLines, active)) return;
+    cm.operation(function() {
+      clearActiveLines(cm);
+      for (var i = 0; i < active.length; i++) {
+        cm.addLineClass(active[i], "wrap", WRAP_CLASS);
+        cm.addLineClass(active[i], "background", BACK_CLASS);
+      }
+      cm.state.activeLines = active;
+    });
+  }
+
+  function selectionChange(cm, sel) {
+    updateActiveLines(cm, sel.ranges);
+  }
+});
diff --git a/app/gui/html/vendor/codemirror/addon/selection/mark-selection.js b/app/gui/html/vendor/codemirror/addon/selection/mark-selection.js
new file mode 100644
index 0000000..ae0d393
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/selection/mark-selection.js
@@ -0,0 +1,115 @@
+// Because sometimes you need to mark the selected *text*.
+//
+// Adds an option 'styleSelectedText' which, when enabled, gives
+// selected text the CSS class given as option value, or
+// "CodeMirror-selectedtext" when the value is not a string.
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) {
+    var prev = old && old != CodeMirror.Init;
+    if (val && !prev) {
+      cm.state.markedSelection = [];
+      cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext";
+      reset(cm);
+      cm.on("cursorActivity", onCursorActivity);
+      cm.on("change", onChange);
+    } else if (!val && prev) {
+      cm.off("cursorActivity", onCursorActivity);
+      cm.off("change", onChange);
+      clear(cm);
+      cm.state.markedSelection = cm.state.markedSelectionStyle = null;
+    }
+  });
+
+  function onCursorActivity(cm) {
+    cm.operation(function() { update(cm); });
+  }
+
+  function onChange(cm) {
+    if (cm.state.markedSelection.length)
+      cm.operation(function() { clear(cm); });
+  }
+
+  var CHUNK_SIZE = 8;
+  var Pos = CodeMirror.Pos;
+  var cmp = CodeMirror.cmpPos;
+
+  function coverRange(cm, from, to, addAt) {
+    if (cmp(from, to) == 0) return;
+    var array = cm.state.markedSelection;
+    var cls = cm.state.markedSelectionStyle;
+    for (var line = from.line;;) {
+      var start = line == from.line ? from : Pos(line, 0);
+      var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line;
+      var end = atEnd ? to : Pos(endLine, 0);
+      var mark = cm.markText(start, end, {className: cls});
+      if (addAt == null) array.push(mark);
+      else array.splice(addAt++, 0, mark);
+      if (atEnd) break;
+      line = endLine;
+    }
+  }
+
+  function clear(cm) {
+    var array = cm.state.markedSelection;
+    for (var i = 0; i < array.length; ++i) array[i].clear();
+    array.length = 0;
+  }
+
+  function reset(cm) {
+    clear(cm);
+    var ranges = cm.listSelections();
+    for (var i = 0; i < ranges.length; i++)
+      coverRange(cm, ranges[i].from(), ranges[i].to());
+  }
+
+  function update(cm) {
+    if (!cm.somethingSelected()) return clear(cm);
+    if (cm.listSelections().length > 1) return reset(cm);
+
+    var from = cm.getCursor("start"), to = cm.getCursor("end");
+
+    var array = cm.state.markedSelection;
+    if (!array.length) return coverRange(cm, from, to);
+
+    var coverStart = array[0].find(), coverEnd = array[array.length - 1].find();
+    if (!coverStart || !coverEnd || to.line - from.line < CHUNK_SIZE ||
+        cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0)
+      return reset(cm);
+
+    while (cmp(from, coverStart.from) > 0) {
+      array.shift().clear();
+      coverStart = array[0].find();
+    }
+    if (cmp(from, coverStart.from) < 0) {
+      if (coverStart.to.line - from.line < CHUNK_SIZE) {
+        array.shift().clear();
+        coverRange(cm, from, coverStart.to, 0);
+      } else {
+        coverRange(cm, from, coverStart.from, 0);
+      }
+    }
+
+    while (cmp(to, coverEnd.to) < 0) {
+      array.pop().clear();
+      coverEnd = array[array.length - 1].find();
+    }
+    if (cmp(to, coverEnd.to) > 0) {
+      if (to.line - coverEnd.from.line < CHUNK_SIZE) {
+        array.pop().clear();
+        coverRange(cm, coverEnd.from, to);
+      } else {
+        coverRange(cm, coverEnd.to, to);
+      }
+    }
+  }
+});
diff --git a/app/gui/html/vendor/codemirror/addon/tern/tern.css b/app/gui/html/vendor/codemirror/addon/tern/tern.css
new file mode 100644
index 0000000..eacc2f0
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/tern/tern.css
@@ -0,0 +1,85 @@
+.CodeMirror-Tern-completion {
+  padding-left: 22px;
+  position: relative;
+}
+.CodeMirror-Tern-completion:before {
+  position: absolute;
+  left: 2px;
+  bottom: 2px;
+  border-radius: 50%;
+  font-size: 12px;
+  font-weight: bold;
+  height: 15px;
+  width: 15px;
+  line-height: 16px;
+  text-align: center;
+  color: white;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.CodeMirror-Tern-completion-unknown:before {
+  content: "?";
+  background: #4bb;
+}
+.CodeMirror-Tern-completion-object:before {
+  content: "O";
+  background: #77c;
+}
+.CodeMirror-Tern-completion-fn:before {
+  content: "F";
+  background: #7c7;
+}
+.CodeMirror-Tern-completion-array:before {
+  content: "A";
+  background: #c66;
+}
+.CodeMirror-Tern-completion-number:before {
+  content: "1";
+  background: #999;
+}
+.CodeMirror-Tern-completion-string:before {
+  content: "S";
+  background: #999;
+}
+.CodeMirror-Tern-completion-bool:before {
+  content: "B";
+  background: #999;
+}
+
+.CodeMirror-Tern-completion-guess {
+  color: #999;
+}
+
+.CodeMirror-Tern-tooltip {
+  border: 1px solid silver;
+  border-radius: 3px;
+  color: #444;
+  padding: 2px 5px;
+  font-size: 90%;
+  font-family: monospace;
+  background-color: white;
+  white-space: pre-wrap;
+
+  max-width: 40em;
+  position: absolute;
+  z-index: 10;
+  -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
+  -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
+  box-shadow: 2px 3px 5px rgba(0,0,0,.2);
+
+  transition: opacity 1s;
+  -moz-transition: opacity 1s;
+  -webkit-transition: opacity 1s;
+  -o-transition: opacity 1s;
+  -ms-transition: opacity 1s;
+}
+
+.CodeMirror-Tern-hint-doc {
+  max-width: 25em;
+}
+
+.CodeMirror-Tern-fname { color: black; }
+.CodeMirror-Tern-farg { color: #70a; }
+.CodeMirror-Tern-farg-current { text-decoration: underline; }
+.CodeMirror-Tern-type { color: #07c; }
+.CodeMirror-Tern-fhint-guess { opacity: .7; }
diff --git a/app/gui/html/vendor/codemirror/addon/tern/tern.js b/app/gui/html/vendor/codemirror/addon/tern/tern.js
new file mode 100644
index 0000000..6fbd10c
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/tern/tern.js
@@ -0,0 +1,660 @@
+// Glue code between CodeMirror and Tern.
+//
+// Create a CodeMirror.TernServer to wrap an actual Tern server,
+// register open documents (CodeMirror.Doc instances) with it, and
+// call its methods to activate the assisting functions that Tern
+// provides.
+//
+// Options supported (all optional):
+// * defs: An array of JSON definition data structures.
+// * plugins: An object mapping plugin names to configuration
+//   options.
+// * getFile: A function(name, c) that can be used to access files in
+//   the project that haven't been loaded yet. Simply do c(null) to
+//   indicate that a file is not available.
+// * fileFilter: A function(value, docName, doc) that will be applied
+//   to documents before passing them on to Tern.
+// * switchToDoc: A function(name) that should, when providing a
+//   multi-file view, switch the view or focus to the named file.
+// * showError: A function(editor, message) that can be used to
+//   override the way errors are displayed.
+// * completionTip: Customize the content in tooltips for completions.
+//   Is passed a single argument—the completion's data as returned by
+//   Tern—and may return a string, DOM node, or null to indicate that
+//   no tip should be shown. By default the docstring is shown.
+// * typeTip: Like completionTip, but for the tooltips shown for type
+//   queries.
+// * responseFilter: A function(doc, query, request, error, data) that
+//   will be applied to the Tern responses before treating them
+//
+//
+// It is possible to run the Tern server in a web worker by specifying
+// these additional options:
+// * useWorker: Set to true to enable web worker mode. You'll probably
+//   want to feature detect the actual value you use here, for example
+//   !!window.Worker.
+// * workerScript: The main script of the worker. Point this to
+//   wherever you are hosting worker.js from this directory.
+// * workerDeps: An array of paths pointing (relative to workerScript)
+//   to the Acorn and Tern libraries and any Tern plugins you want to
+//   load. Or, if you minified those into a single script and included
+//   them in the workerScript, simply leave this undefined.
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+  // declare global: tern
+
+  CodeMirror.TernServer = function(options) {
+    var self = this;
+    this.options = options || {};
+    var plugins = this.options.plugins || (this.options.plugins = {});
+    if (!plugins.doc_comment) plugins.doc_comment = true;
+    if (this.options.useWorker) {
+      this.server = new WorkerServer(this);
+    } else {
+      this.server = new tern.Server({
+        getFile: function(name, c) { return getFile(self, name, c); },
+        async: true,
+        defs: this.options.defs || [],
+        plugins: plugins
+      });
+    }
+    this.docs = Object.create(null);
+    this.trackChange = function(doc, change) { trackChange(self, doc, change); };
+
+    this.cachedArgHints = null;
+    this.activeArgHints = null;
+    this.jumpStack = [];
+  };
+
+  CodeMirror.TernServer.prototype = {
+    addDoc: function(name, doc) {
+      var data = {doc: doc, name: name, changed: null};
+      this.server.addFile(name, docValue(this, data));
+      CodeMirror.on(doc, "change", this.trackChange);
+      return this.docs[name] = data;
+    },
+
+    delDoc: function(name) {
+      var found = this.docs[name];
+      if (!found) return;
+      CodeMirror.off(found.doc, "change", this.trackChange);
+      delete this.docs[name];
+      this.server.delFile(name);
+    },
+
+    hideDoc: function(name) {
+      closeArgHints(this);
+      var found = this.docs[name];
+      if (found && found.changed) sendDoc(this, found);
+    },
+
+    complete: function(cm) {
+      var self = this;
+      CodeMirror.showHint(cm, function(cm, c) { return hint(self, cm, c); }, {async: true});
+    },
+
+    getHint: function(cm, c) { return hint(this, cm, c); },
+
+    showType: function(cm, pos) { showType(this, cm, pos); },
+
+    updateArgHints: function(cm) { updateArgHints(this, cm); },
+
+    jumpToDef: function(cm) { jumpToDef(this, cm); },
+
+    jumpBack: function(cm) { jumpBack(this, cm); },
+
+    rename: function(cm) { rename(this, cm); },
+
+    selectName: function(cm) { selectName(this, cm); },
+
+    request: function (cm, query, c, pos) {
+      var self = this;
+      var doc = findDoc(this, cm.getDoc());
+      var request = buildRequest(this, doc, query, pos);
+
+      this.server.request(request, function (error, data) {
+        if (!error && self.options.responseFilter)
+          data = self.options.responseFilter(doc, query, request, error, data);
+        c(error, data);
+      });
+    }
+  };
+
+  var Pos = CodeMirror.Pos;
+  var cls = "CodeMirror-Tern-";
+  var bigDoc = 250;
+
+  function getFile(ts, name, c) {
+    var buf = ts.docs[name];
+    if (buf)
+      c(docValue(ts, buf));
+    else if (ts.options.getFile)
+      ts.options.getFile(name, c);
+    else
+      c(null);
+  }
+
+  function findDoc(ts, doc, name) {
+    for (var n in ts.docs) {
+      var cur = ts.docs[n];
+      if (cur.doc == doc) return cur;
+    }
+    if (!name) for (var i = 0;; ++i) {
+      n = "[doc" + (i || "") + "]";
+      if (!ts.docs[n]) { name = n; break; }
+    }
+    return ts.addDoc(name, doc);
+  }
+
+  function trackChange(ts, doc, change) {
+    var data = findDoc(ts, doc);
+
+    var argHints = ts.cachedArgHints;
+    if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) <= 0)
+      ts.cachedArgHints = null;
+
+    var changed = data.changed;
+    if (changed == null)
+      data.changed = changed = {from: change.from.line, to: change.from.line};
+    var end = change.from.line + (change.text.length - 1);
+    if (change.from.line < changed.to) changed.to = changed.to - (change.to.line - end);
+    if (end >= changed.to) changed.to = end + 1;
+    if (changed.from > change.from.line) changed.from = change.from.line;
+
+    if (doc.lineCount() > bigDoc && change.to - changed.from > 100) setTimeout(function() {
+      if (data.changed && data.changed.to - data.changed.from > 100) sendDoc(ts, data);
+    }, 200);
+  }
+
+  function sendDoc(ts, doc) {
+    ts.server.request({files: [{type: "full", name: doc.name, text: docValue(ts, doc)}]}, function(error) {
+      if (error) window.console.error(error);
+      else doc.changed = null;
+    });
+  }
+
+  // Completion
+
+  function hint(ts, cm, c) {
+    ts.request(cm, {type: "completions", types: true, docs: true, urls: true}, function(error, data) {
+      if (error) return showError(ts, cm, error);
+      var completions = [], after = "";
+      var from = data.start, to = data.end;
+      if (cm.getRange(Pos(from.line, from.ch - 2), from) == "[\"" &&
+          cm.getRange(to, Pos(to.line, to.ch + 2)) != "\"]")
+        after = "\"]";
+
+      for (var i = 0; i < data.completions.length; ++i) {
+        var completion = data.completions[i], className = typeToIcon(completion.type);
+        if (data.guess) className += " " + cls + "guess";
+        completions.push({text: completion.name + after,
+                          displayText: completion.name,
+                          className: className,
+                          data: completion});
+      }
+
+      var obj = {from: from, to: to, list: completions};
+      var tooltip = null;
+      CodeMirror.on(obj, "close", function() { remove(tooltip); });
+      CodeMirror.on(obj, "update", function() { remove(tooltip); });
+      CodeMirror.on(obj, "select", function(cur, node) {
+        remove(tooltip);
+        var content = ts.options.completionTip ? ts.options.completionTip(cur.data) : cur.data.doc;
+        if (content) {
+          tooltip = makeTooltip(node.parentNode.getBoundingClientRect().right + window.pageXOffset,
+                                node.getBoundingClientRect().top + window.pageYOffset, content);
+          tooltip.className += " " + cls + "hint-doc";
+        }
+      });
+      c(obj);
+    });
+  }
+
+  function typeToIcon(type) {
+    var suffix;
+    if (type == "?") suffix = "unknown";
+    else if (type == "number" || type == "string" || type == "bool") suffix = type;
+    else if (/^fn\(/.test(type)) suffix = "fn";
+    else if (/^\[/.test(type)) suffix = "array";
+    else suffix = "object";
+    return cls + "completion " + cls + "completion-" + suffix;
+  }
+
+  // Type queries
+
+  function showType(ts, cm, pos) {
+    ts.request(cm, "type", function(error, data) {
+      if (error) return showError(ts, cm, error);
+      if (ts.options.typeTip) {
+        var tip = ts.options.typeTip(data);
+      } else {
+        var tip = elt("span", null, elt("strong", null, data.type || "not found"));
+        if (data.doc)
+          tip.appendChild(document.createTextNode(" — " + data.doc));
+        if (data.url) {
+          tip.appendChild(document.createTextNode(" "));
+          tip.appendChild(elt("a", null, "[docs]")).href = data.url;
+        }
+      }
+      tempTooltip(cm, tip);
+    }, pos);
+  }
+
+  // Maintaining argument hints
+
+  function updateArgHints(ts, cm) {
+    closeArgHints(ts);
+
+    if (cm.somethingSelected()) return;
+    var state = cm.getTokenAt(cm.getCursor()).state;
+    var inner = CodeMirror.innerMode(cm.getMode(), state);
+    if (inner.mode.name != "javascript") return;
+    var lex = inner.state.lexical;
+    if (lex.info != "call") return;
+
+    var ch, argPos = lex.pos || 0, tabSize = cm.getOption("tabSize");
+    for (var line = cm.getCursor().line, e = Math.max(0, line - 9), found = false; line >= e; --line) {
+      var str = cm.getLine(line), extra = 0;
+      for (var pos = 0;;) {
+        var tab = str.indexOf("\t", pos);
+        if (tab == -1) break;
+        extra += tabSize - (tab + extra) % tabSize - 1;
+        pos = tab + 1;
+      }
+      ch = lex.column - extra;
+      if (str.charAt(ch) == "(") {found = true; break;}
+    }
+    if (!found) return;
+
+    var start = Pos(line, ch);
+    var cache = ts.cachedArgHints;
+    if (cache && cache.doc == cm.getDoc() && cmpPos(start, cache.start) == 0)
+      return showArgHints(ts, cm, argPos);
+
+    ts.request(cm, {type: "type", preferFunction: true, end: start}, function(error, data) {
+      if (error || !data.type || !(/^fn\(/).test(data.type)) return;
+      ts.cachedArgHints = {
+        start: pos,
+        type: parseFnType(data.type),
+        name: data.exprName || data.name || "fn",
+        guess: data.guess,
+        doc: cm.getDoc()
+      };
+      showArgHints(ts, cm, argPos);
+    });
+  }
+
+  function showArgHints(ts, cm, pos) {
+    closeArgHints(ts);
+
+    var cache = ts.cachedArgHints, tp = cache.type;
+    var tip = elt("span", cache.guess ? cls + "fhint-guess" : null,
+                  elt("span", cls + "fname", cache.name), "(");
+    for (var i = 0; i < tp.args.length; ++i) {
+      if (i) tip.appendChild(document.createTextNode(", "));
+      var arg = tp.args[i];
+      tip.appendChild(elt("span", cls + "farg" + (i == pos ? " " + cls + "farg-current" : ""), arg.name || "?"));
+      if (arg.type != "?") {
+        tip.appendChild(document.createTextNode(":\u00a0"));
+        tip.appendChild(elt("span", cls + "type", arg.type));
+      }
+    }
+    tip.appendChild(document.createTextNode(tp.rettype ? ") ->\u00a0" : ")"));
+    if (tp.rettype) tip.appendChild(elt("span", cls + "type", tp.rettype));
+    var place = cm.cursorCoords(null, "page");
+    ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip);
+  }
+
+  function parseFnType(text) {
+    var args = [], pos = 3;
+
+    function skipMatching(upto) {
+      var depth = 0, start = pos;
+      for (;;) {
+        var next = text.charAt(pos);
+        if (upto.test(next) && !depth) return text.slice(start, pos);
+        if (/[{\[\(]/.test(next)) ++depth;
+        else if (/[}\]\)]/.test(next)) --depth;
+        ++pos;
+      }
+    }
+
+    // Parse arguments
+    if (text.charAt(pos) != ")") for (;;) {
+      var name = text.slice(pos).match(/^([^, \(\[\{]+): /);
+      if (name) {
+        pos += name[0].length;
+        name = name[1];
+      }
+      args.push({name: name, type: skipMatching(/[\),]/)});
+      if (text.charAt(pos) == ")") break;
+      pos += 2;
+    }
+
+    var rettype = text.slice(pos).match(/^\) -> (.*)$/);
+
+    return {args: args, rettype: rettype && rettype[1]};
+  }
+
+  // Moving to the definition of something
+
+  function jumpToDef(ts, cm) {
+    function inner(varName) {
+      var req = {type: "definition", variable: varName || null};
+      var doc = findDoc(ts, cm.getDoc());
+      ts.server.request(buildRequest(ts, doc, req), function(error, data) {
+        if (error) return showError(ts, cm, error);
+        if (!data.file && data.url) { window.open(data.url); return; }
+
+        if (data.file) {
+          var localDoc = ts.docs[data.file], found;
+          if (localDoc && (found = findContext(localDoc.doc, data))) {
+            ts.jumpStack.push({file: doc.name,
+                               start: cm.getCursor("from"),
+                               end: cm.getCursor("to")});
+            moveTo(ts, doc, localDoc, found.start, found.end);
+            return;
+          }
+        }
+        showError(ts, cm, "Could not find a definition.");
+      });
+    }
+
+    if (!atInterestingExpression(cm))
+      dialog(cm, "Jump to variable", function(name) { if (name) inner(name); });
+    else
+      inner();
+  }
+
+  function jumpBack(ts, cm) {
+    var pos = ts.jumpStack.pop(), doc = pos && ts.docs[pos.file];
+    if (!doc) return;
+    moveTo(ts, findDoc(ts, cm.getDoc()), doc, pos.start, pos.end);
+  }
+
+  function moveTo(ts, curDoc, doc, start, end) {
+    doc.doc.setSelection(end, start);
+    if (curDoc != doc && ts.options.switchToDoc) {
+      closeArgHints(ts);
+      ts.options.switchToDoc(doc.name);
+    }
+  }
+
+  // The {line,ch} representation of positions makes this rather awkward.
+  function findContext(doc, data) {
+    var before = data.context.slice(0, data.contextOffset).split("\n");
+    var startLine = data.start.line - (before.length - 1);
+    var start = Pos(startLine, (before.length == 1 ? data.start.ch : doc.getLine(startLine).length) - before[0].length);
+
+    var text = doc.getLine(startLine).slice(start.ch);
+    for (var cur = startLine + 1; cur < doc.lineCount() && text.length < data.context.length; ++cur)
+      text += "\n" + doc.getLine(cur);
+    if (text.slice(0, data.context.length) == data.context) return data;
+
+    var cursor = doc.getSearchCursor(data.context, 0, false);
+    var nearest, nearestDist = Infinity;
+    while (cursor.findNext()) {
+      var from = cursor.from(), dist = Math.abs(from.line - start.line) * 10000;
+      if (!dist) dist = Math.abs(from.ch - start.ch);
+      if (dist < nearestDist) { nearest = from; nearestDist = dist; }
+    }
+    if (!nearest) return null;
+
+    if (before.length == 1)
+      nearest.ch += before[0].length;
+    else
+      nearest = Pos(nearest.line + (before.length - 1), before[before.length - 1].length);
+    if (data.start.line == data.end.line)
+      var end = Pos(nearest.line, nearest.ch + (data.end.ch - data.start.ch));
+    else
+      var end = Pos(nearest.line + (data.end.line - data.start.line), data.end.ch);
+    return {start: nearest, end: end};
+  }
+
+  function atInterestingExpression(cm) {
+    var pos = cm.getCursor("end"), tok = cm.getTokenAt(pos);
+    if (tok.start < pos.ch && (tok.type == "comment" || tok.type == "string")) return false;
+    return /\w/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1));
+  }
+
+  // Variable renaming
+
+  function rename(ts, cm) {
+    var token = cm.getTokenAt(cm.getCursor());
+    if (!/\w/.test(token.string)) showError(ts, cm, "Not at a variable");
+    dialog(cm, "New name for " + token.string, function(newName) {
+      ts.request(cm, {type: "rename", newName: newName, fullDocs: true}, function(error, data) {
+        if (error) return showError(ts, cm, error);
+        applyChanges(ts, data.changes);
+      });
+    });
+  }
+
+  function selectName(ts, cm) {
+    var cur = cm.getCursor(), token = cm.getTokenAt(cur);
+    if (!/\w/.test(token.string)) showError(ts, cm, "Not at a variable");
+    var name = findDoc(ts, cm.doc).name;
+    ts.request(cm, {type: "refs"}, function(error, data) {
+      if (error) return showError(ts, cm, error);
+      var ranges = [], cur = 0;
+      for (var i = 0; i < data.refs.length; i++) {
+        var ref = data.refs[i];
+        if (ref.file == name) {
+          ranges.push({anchor: ref.start, head: ref.end});
+          if (cmpPos(cur, ref.start) >= 0 && cmpPos(cur, ref.end) <= 0)
+            cur = ranges.length - 1;
+        }
+      }
+      cm.setSelections(ranges, cur);
+    });
+  }
+
+  var nextChangeOrig = 0;
+  function applyChanges(ts, changes) {
+    var perFile = Object.create(null);
+    for (var i = 0; i < changes.length; ++i) {
+      var ch = changes[i];
+      (perFile[ch.file] || (perFile[ch.file] = [])).push(ch);
+    }
+    for (var file in perFile) {
+      var known = ts.docs[file], chs = perFile[file];;
+      if (!known) continue;
+      chs.sort(function(a, b) { return cmpPos(b.start, a.start); });
+      var origin = "*rename" + (++nextChangeOrig);
+      for (var i = 0; i < chs.length; ++i) {
+        var ch = chs[i];
+        known.doc.replaceRange(ch.text, ch.start, ch.end, origin);
+      }
+    }
+  }
+
+  // Generic request-building helper
+
+  function buildRequest(ts, doc, query, pos) {
+    var files = [], offsetLines = 0, allowFragments = !query.fullDocs;
+    if (!allowFragments) delete query.fullDocs;
+    if (typeof query == "string") query = {type: query};
+    query.lineCharPositions = true;
+    if (query.end == null) {
+      query.end = pos || doc.doc.getCursor("end");
+      if (doc.doc.somethingSelected())
+        query.start = doc.doc.getCursor("start");
+    }
+    var startPos = query.start || query.end;
+
+    if (doc.changed) {
+      if (doc.doc.lineCount() > bigDoc && allowFragments !== false &&
+          doc.changed.to - doc.changed.from < 100 &&
+          doc.changed.from <= startPos.line && doc.changed.to > query.end.line) {
+        files.push(getFragmentAround(doc, startPos, query.end));
+        query.file = "#0";
+        var offsetLines = files[0].offsetLines;
+        if (query.start != null) query.start = Pos(query.start.line - -offsetLines, query.start.ch);
+        query.end = Pos(query.end.line - offsetLines, query.end.ch);
+      } else {
+        files.push({type: "full",
+                    name: doc.name,
+                    text: docValue(ts, doc)});
+        query.file = doc.name;
+        doc.changed = null;
+      }
+    } else {
+      query.file = doc.name;
+    }
+    for (var name in ts.docs) {
+      var cur = ts.docs[name];
+      if (cur.changed && cur != doc) {
+        files.push({type: "full", name: cur.name, text: docValue(ts, cur)});
+        cur.changed = null;
+      }
+    }
+
+    return {query: query, files: files};
+  }
+
+  function getFragmentAround(data, start, end) {
+    var doc = data.doc;
+    var minIndent = null, minLine = null, endLine, tabSize = 4;
+    for (var p = start.line - 1, min = Math.max(0, p - 50); p >= min; --p) {
+      var line = doc.getLine(p), fn = line.search(/\bfunction\b/);
+      if (fn < 0) continue;
+      var indent = CodeMirror.countColumn(line, null, tabSize);
+      if (minIndent != null && minIndent <= indent) continue;
+      minIndent = indent;
+      minLine = p;
+    }
+    if (minLine == null) minLine = min;
+    var max = Math.min(doc.lastLine(), end.line + 20);
+    if (minIndent == null || minIndent == CodeMirror.countColumn(doc.getLine(start.line), null, tabSize))
+      endLine = max;
+    else for (endLine = end.line + 1; endLine < max; ++endLine) {
+      var indent = CodeMirror.countColumn(doc.getLine(endLine), null, tabSize);
+      if (indent <= minIndent) break;
+    }
+    var from = Pos(minLine, 0);
+
+    return {type: "part",
+            name: data.name,
+            offsetLines: from.line,
+            text: doc.getRange(from, Pos(endLine, 0))};
+  }
+
+  // Generic utilities
+
+  var cmpPos = CodeMirror.cmpPos;
+
+  function elt(tagname, cls /*, ... elts*/) {
+    var e = document.createElement(tagname);
+    if (cls) e.className = cls;
+    for (var i = 2; i < arguments.length; ++i) {
+      var elt = arguments[i];
+      if (typeof elt == "string") elt = document.createTextNode(elt);
+      e.appendChild(elt);
+    }
+    return e;
+  }
+
+  function dialog(cm, text, f) {
+    if (cm.openDialog)
+      cm.openDialog(text + ": <input type=text>", f);
+    else
+      f(prompt(text, ""));
+  }
+
+  // Tooltips
+
+  function tempTooltip(cm, content) {
+    var where = cm.cursorCoords();
+    var tip = makeTooltip(where.right + 1, where.bottom, content);
+    function clear() {
+      if (!tip.parentNode) return;
+      cm.off("cursorActivity", clear);
+      fadeOut(tip);
+    }
+    setTimeout(clear, 1700);
+    cm.on("cursorActivity", clear);
+  }
+
+  function makeTooltip(x, y, content) {
+    var node = elt("div", cls + "tooltip", content);
+    node.style.left = x + "px";
+    node.style.top = y + "px";
+    document.body.appendChild(node);
+    return node;
+  }
+
+  function remove(node) {
+    var p = node && node.parentNode;
+    if (p) p.removeChild(node);
+  }
+
+  function fadeOut(tooltip) {
+    tooltip.style.opacity = "0";
+    setTimeout(function() { remove(tooltip); }, 1100);
+  }
+
+  function showError(ts, cm, msg) {
+    if (ts.options.showError)
+      ts.options.showError(cm, msg);
+    else
+      tempTooltip(cm, String(msg));
+  }
+
+  function closeArgHints(ts) {
+    if (ts.activeArgHints) { remove(ts.activeArgHints); ts.activeArgHints = null; }
+  }
+
+  function docValue(ts, doc) {
+    var val = doc.doc.getValue();
+    if (ts.options.fileFilter) val = ts.options.fileFilter(val, doc.name, doc.doc);
+    return val;
+  }
+
+  // Worker wrapper
+
+  function WorkerServer(ts) {
+    var worker = new Worker(ts.options.workerScript);
+    worker.postMessage({type: "init",
+                        defs: ts.options.defs,
+                        plugins: ts.options.plugins,
+                        scripts: ts.options.workerDeps});
+    var msgId = 0, pending = {};
+
+    function send(data, c) {
+      if (c) {
+        data.id = ++msgId;
+        pending[msgId] = c;
+      }
+      worker.postMessage(data);
+    }
+    worker.onmessage = function(e) {
+      var data = e.data;
+      if (data.type == "getFile") {
+        getFile(ts, data.name, function(err, text) {
+          send({type: "getFile", err: String(err), text: text, id: data.id});
+        });
+      } else if (data.type == "debug") {
+        window.console.log(data.message);
+      } else if (data.id && pending[data.id]) {
+        pending[data.id](data.err, data.body);
+        delete pending[data.id];
+      }
+    };
+    worker.onerror = function(e) {
+      for (var id in pending) pending[id](e);
+      pending = {};
+    };
+
+    this.addFile = function(name, text) { send({type: "add", name: name, text: text}); };
+    this.delFile = function(name) { send({type: "del", name: name}); };
+    this.request = function(body, c) { send({type: "req", body: body}, c); };
+  }
+});
diff --git a/app/gui/html/vendor/codemirror/addon/tern/worker.js b/app/gui/html/vendor/codemirror/addon/tern/worker.js
new file mode 100644
index 0000000..1ff63de
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/tern/worker.js
@@ -0,0 +1,41 @@
+// declare global: tern, server
+
+var server;
+
+this.onmessage = function(e) {
+  var data = e.data;
+  switch (data.type) {
+  case "init": return startServer(data.defs, data.plugins, data.scripts);
+  case "add": return server.addFile(data.name, data.text);
+  case "del": return server.delFile(data.name);
+  case "req": return server.request(data.body, function(err, reqData) {
+    postMessage({id: data.id, body: reqData, err: err && String(err)});
+  });
+  case "getFile":
+    var c = pending[data.id];
+    delete pending[data.id];
+    return c(data.err, data.text);
+  default: throw new Error("Unknown message type: " + data.type);
+  }
+};
+
+var nextId = 0, pending = {};
+function getFile(file, c) {
+  postMessage({type: "getFile", name: file, id: ++nextId});
+  pending[nextId] = c;
+}
+
+function startServer(defs, plugins, scripts) {
+  if (scripts) importScripts.apply(null, scripts);
+
+  server = new tern.Server({
+    getFile: getFile,
+    async: true,
+    defs: defs,
+    plugins: plugins
+  });
+}
+
+var console = {
+  log: function(v) { postMessage({type: "debug", message: v}); }
+};
diff --git a/app/gui/html/vendor/codemirror/addon/wrap/hardwrap.js b/app/gui/html/vendor/codemirror/addon/wrap/hardwrap.js
new file mode 100644
index 0000000..87aab1b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/addon/wrap/hardwrap.js
@@ -0,0 +1,136 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var Pos = CodeMirror.Pos;
+
+  function findParagraph(cm, pos, options) {
+    var startRE = options.paragraphStart || cm.getHelper(pos, "paragraphStart");
+    for (var start = pos.line, first = cm.firstLine(); start > first; --start) {
+      var line = cm.getLine(start);
+      if (startRE && startRE.test(line)) break;
+      if (!/\S/.test(line)) { ++start; break; }
+    }
+    var endRE = options.paragraphEnd || cm.getHelper(pos, "paragraphEnd");
+    for (var end = pos.line + 1, last = cm.lastLine(); end <= last; ++end) {
+      var line = cm.getLine(end);
+      if (endRE && endRE.test(line)) { ++end; break; }
+      if (!/\S/.test(line)) break;
+    }
+    return {from: start, to: end};
+  }
+
+  function findBreakPoint(text, column, wrapOn, killTrailingSpace) {
+    for (var at = column; at > 0; --at)
+      if (wrapOn.test(text.slice(at - 1, at + 1))) break;
+    if (at == 0) at = column;
+    var endOfText = at;
+    if (killTrailingSpace)
+      while (text.charAt(endOfText - 1) == " ") --endOfText;
+    return {from: endOfText, to: at};
+  }
+
+  function wrapRange(cm, from, to, options) {
+    from = cm.clipPos(from); to = cm.clipPos(to);
+    var column = options.column || 80;
+    var wrapOn = options.wrapOn || /\s\S|-[^\.\d]/;
+    var killTrailing = options.killTrailingSpace !== false;
+    var changes = [], curLine = "", curNo = from.line;
+    var lines = cm.getRange(from, to, false);
+    if (!lines.length) return null;
+    var leadingSpace = lines[0].match(/^[ \t]*/)[0];
+
+    for (var i = 0; i < lines.length; ++i) {
+      var text = lines[i], oldLen = curLine.length, spaceInserted = 0;
+      if (curLine && text && !wrapOn.test(curLine.charAt(curLine.length - 1) + text.charAt(0))) {
+        curLine += " ";
+        spaceInserted = 1;
+      }
+      var spaceTrimmed = "";
+      if (i) {
+        spaceTrimmed = text.match(/^\s*/)[0];
+        text = text.slice(spaceTrimmed.length);
+      }
+      curLine += text;
+      if (i) {
+        var firstBreak = curLine.length > column && leadingSpace == spaceTrimmed &&
+          findBreakPoint(curLine, column, wrapOn, killTrailing);
+        // If this isn't broken, or is broken at a different point, remove old break
+        if (!firstBreak || firstBreak.from != oldLen || firstBreak.to != oldLen + spaceInserted) {
+          changes.push({text: [spaceInserted ? " " : ""],
+                        from: Pos(curNo, oldLen),
+                        to: Pos(curNo + 1, spaceTrimmed.length)});
+        } else {
+          curLine = leadingSpace + text;
+          ++curNo;
+        }
+      }
+      while (curLine.length > column) {
+        var bp = findBreakPoint(curLine, column, wrapOn, killTrailing);
+        changes.push({text: ["", leadingSpace],
+                      from: Pos(curNo, bp.from),
+                      to: Pos(curNo, bp.to)});
+        curLine = leadingSpace + curLine.slice(bp.to);
+        ++curNo;
+      }
+    }
+    if (changes.length) cm.operation(function() {
+      for (var i = 0; i < changes.length; ++i) {
+        var change = changes[i];
+        cm.replaceRange(change.text, change.from, change.to);
+      }
+    });
+    return changes.length ? {from: changes[0].from, to: CodeMirror.changeEnd(changes[changes.length - 1])} : null;
+  }
+
+  CodeMirror.defineExtension("wrapParagraph", function(pos, options) {
+    options = options || {};
+    if (!pos) pos = this.getCursor();
+    var para = findParagraph(this, pos, options);
+    return wrapRange(this, Pos(para.from, 0), Pos(para.to - 1), options);
+  });
+
+  CodeMirror.commands.wrapLines = function(cm) {
+    cm.operation(function() {
+      var ranges = cm.listSelections(), at = cm.lastLine() + 1;
+      for (var i = ranges.length - 1; i >= 0; i--) {
+        var range = ranges[i], span;
+        if (range.empty()) {
+          var para = findParagraph(cm, range.head, {});
+          span = {from: Pos(para.from, 0), to: Pos(para.to - 1)};
+        } else {
+          span = {from: range.from(), to: range.to()};
+        }
+        if (span.to.line >= at) continue;
+        at = span.from.line;
+        wrapRange(cm, span.from, span.to, {});
+      }
+    });
+  };
+
+  CodeMirror.defineExtension("wrapRange", function(from, to, options) {
+    return wrapRange(this, from, to, options || {});
+  });
+
+  CodeMirror.defineExtension("wrapParagraphsInRange", function(from, to, options) {
+    options = options || {};
+    var cm = this, paras = [];
+    for (var line = from.line; line <= to.line;) {
+      var para = findParagraph(cm, Pos(line, 0), options);
+      paras.push(para);
+      line = para.to;
+    }
+    var madeChange = false;
+    if (paras.length) cm.operation(function() {
+      for (var i = paras.length - 1; i >= 0; --i)
+        madeChange = madeChange || wrapRange(cm, Pos(paras[i].from, 0), Pos(paras[i].to - 1), options);
+    });
+    return madeChange;
+  });
+});
diff --git a/app/gui/html/vendor/codemirror/bin/authors.sh b/app/gui/html/vendor/codemirror/bin/authors.sh
new file mode 100755
index 0000000..b3ee99c
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/bin/authors.sh
@@ -0,0 +1,6 @@
+# Combine existing list of authors with everyone known in git, sort, add header.
+tail --lines=+3 AUTHORS > AUTHORS.tmp
+git log --format='%aN' >> AUTHORS.tmp
+echo -e "List of CodeMirror contributors. Updated before every release.\n" > AUTHORS
+sort -u AUTHORS.tmp >> AUTHORS
+rm -f AUTHORS.tmp
diff --git a/app/gui/html/vendor/codemirror/bin/compress b/app/gui/html/vendor/codemirror/bin/compress
new file mode 100755
index 0000000..809fbe8
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/bin/compress
@@ -0,0 +1,92 @@
+#!/usr/bin/env node
+
+// Compression helper for CodeMirror
+//
+// Example:
+//
+//   bin/compress codemirror runmode javascript xml
+//
+// Will take lib/codemirror.js, addon/runmode/runmode.js,
+// mode/javascript/javascript.js, and mode/xml/xml.js, run them though
+// the online minifier at http://marijnhaverbeke.nl/uglifyjs, and spit
+// out the result.
+//
+//   bin/compress codemirror --local /path/to/bin/UglifyJS
+//
+// Will use a local minifier instead of the online default one.
+//
+// Script files are specified without .js ending. Prefixing them with
+// their full (local) path is optional. So you may say lib/codemirror
+// or mode/xml/xml to be more precise. In fact, even the .js suffix
+// may be speficied, if wanted.
+
+"use strict";
+
+var fs = require("fs");
+
+function help(ok) {
+  console.log("usage: " + process.argv[1] + " [--local /path/to/uglifyjs] files...");
+  process.exit(ok ? 0 : 1);
+}
+
+var local = null, args = [], extraArgs = null, files = [], blob = "";
+
+for (var i = 2; i < process.argv.length; ++i) {
+  var arg = process.argv[i];
+  if (arg == "--local" && i + 1 < process.argv.length) {
+    var parts = process.argv[++i].split(/\s+/);
+    local = parts[0];
+    extraArgs = parts.slice(1);
+    if (!extraArgs.length) extraArgs = ["-c", "-m"];
+  } else if (arg == "--help") {
+    help(true);
+  } else if (arg[0] != "-") {
+    files.push({name: arg, re: new RegExp("(?:\\/|^)" + arg + (/\.js$/.test(arg) ? "$" : "\\.js$"))});
+  } else help(false);
+}
+
+function walk(dir) {
+  fs.readdirSync(dir).forEach(function(fname) {
+    if (/^[_\.]/.test(fname)) return;
+    var file = dir + fname;
+    if (fs.statSync(file).isDirectory()) return walk(file + "/");
+    if (files.some(function(spec, i) {
+      var match = spec.re.test(file);
+      if (match) files.splice(i, 1);
+      return match;
+    })) {
+      if (local) args.push(file);
+      else blob += fs.readFileSync(file, "utf8");
+    }
+  });
+}
+
+walk("lib/");
+walk("addon/");
+walk("mode/");
+
+if (!local && !blob) help(false);
+
+if (files.length) {
+  console.log("Some speficied files were not found: " +
+              files.map(function(a){return a.name;}).join(", "));
+  process.exit(1);
+}
+  
+if (local) {
+  require("child_process").spawn(local, args.concat(extraArgs), {stdio: ["ignore", process.stdout, process.stderr]});
+} else {
+  var data = new Buffer("js_code=" + require("querystring").escape(blob), "utf8");
+  var req = require("http").request({
+    host: "marijnhaverbeke.nl",
+    port: 80,
+    method: "POST",
+    path: "/uglifyjs",
+    headers: {"content-type": "application/x-www-form-urlencoded",
+              "content-length": data.length}
+  });
+  req.on("response", function(resp) {
+    resp.on("data", function (chunk) { process.stdout.write(chunk); });
+  });
+  req.end(data);
+}
diff --git a/app/gui/html/vendor/codemirror/bin/lint b/app/gui/html/vendor/codemirror/bin/lint
new file mode 100755
index 0000000..4f70994
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/bin/lint
@@ -0,0 +1,16 @@
+#!/usr/bin/env node
+
+var lint = require("../test/lint/lint"),
+    path = require("path");
+
+if (process.argv.length > 2) {
+  lint.checkDir(process.argv[2]);
+} else {
+  process.chdir(path.resolve(__dirname, ".."));
+  lint.checkDir("lib");
+  lint.checkDir("mode");
+  lint.checkDir("addon");
+  lint.checkDir("keymap");
+}
+
+process.exit(lint.success() ? 0 : 1);
diff --git a/app/gui/html/vendor/codemirror/bin/release b/app/gui/html/vendor/codemirror/bin/release
new file mode 100755
index 0000000..3c33290
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/bin/release
@@ -0,0 +1,44 @@
+#!/usr/bin/env node
+
+var fs = require("fs"), child = require("child_process");
+
+var number, bumpOnly;
+
+for (var i = 2; i < process.argv.length; i++) {
+  if (process.argv[i] == "-bump") bumpOnly = true;
+  else if (/^\d+\.\d+\.\d+$/.test(process.argv[i])) number = process.argv[i];
+  else { console.log("Bogus command line arg: " + process.argv[i]); process.exit(1); }
+}
+
+if (!number) { console.log("Must give a version"); process.exit(1); }
+
+function rewrite(file, f) {
+  fs.writeFileSync(file, f(fs.readFileSync(file, "utf8")), "utf8");
+}
+
+rewrite("lib/codemirror.js", function(lib) {
+  return lib.replace(/CodeMirror\.version = "\d+\.\d+\.\d+"/,
+                     "CodeMirror.version = \"" + number + "\"");
+});
+rewrite("package.json", function(pack) {
+  return pack.replace(/"version":"\d+\.\d+\.\d+"/, "\"version\":\"" + number + "\"");
+});
+rewrite("doc/manual.html", function(manual) {
+  return manual.replace(/>version \d+\.\d+\.\d+<\/span>/, ">version " + number + "</span>");
+});
+
+if (bumpOnly) process.exit(0);
+
+child.exec("bash bin/authors.sh", function(){});
+
+var simple = number.slice(0, number.lastIndexOf("."));
+
+rewrite("doc/compress.html", function(cmp) {
+  return cmp.replace(/<option value="http:\/\/codemirror.net\/">HEAD<\/option>/,
+                     "<option value=\"http://codemirror.net/\">HEAD</option>\n        <option value=\"http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=" + number + ";f=\">" + simple + "</option>");
+});
+
+rewrite("index.html", function(index) {
+  return index.replace(/<strong>version \d+\.\d+<\/strong>/,
+                       "<strong>version " + simple + "</strong>");
+});
diff --git a/app/gui/html/vendor/codemirror/bin/source-highlight b/app/gui/html/vendor/codemirror/bin/source-highlight
new file mode 100755
index 0000000..6d15f1a
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/bin/source-highlight
@@ -0,0 +1,51 @@
+#!/usr/bin/env node
+
+// Simple command-line code highlighting tool. Reads code from stdin,
+// spits html to stdout. For example:
+//
+//   echo 'function foo(a) { return a; }' | bin/source-highlight -s javascript
+//   bin/source-highlight -s 
+
+var fs = require("fs");
+
+var CodeMirror = require("../addon/runmode/runmode.node.js");
+require("../mode/meta.js");
+
+var sPos = process.argv.indexOf("-s");
+if (sPos == -1 || sPos == process.argv.length - 1) {
+   console.error("Usage: source-highlight -s language");
+   process.exit(1);
+}
+var lang = process.argv[sPos + 1].toLowerCase(), modeName = lang;
+CodeMirror.modeInfo.forEach(function(info) {
+  if (info.mime == lang) {
+    modeName = info.mode;
+  } else if (info.name.toLowerCase() == lang) {
+    modeName = info.mode;
+    lang = info.mime;
+  }
+});
+
+if (!CodeMirror.modes[modeName])
+  require("../mode/" + modeName + "/" + modeName + ".js");
+
+function esc(str) {
+  return str.replace(/[<&]/g, function(ch) { return ch == "&" ? "&" : "<"; });
+}
+
+var code = fs.readFileSync("/dev/stdin", "utf8");
+var curStyle = null, accum = "";
+function flush() {
+  if (curStyle) process.stdout.write("<span class=\"" + curStyle.replace(/(^|\s+)/g, "$1cm-") + "\">" + esc(accum) + "</span>");
+  else process.stdout.write(esc(accum));
+}
+
+CodeMirror.runMode(code, lang, function(text, style) {
+  if (style != curStyle) {
+    flush();
+    curStyle = style; accum = text;
+  } else {
+    accum += text;
+  }
+});
+flush();
diff --git a/app/gui/html/vendor/codemirror/bower.json b/app/gui/html/vendor/codemirror/bower.json
new file mode 100644
index 0000000..66e049d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/bower.json
@@ -0,0 +1,15 @@
+{
+  "name": "CodeMirror",
+  "main": ["lib/codemirror.js", "lib/codemirror.css"],
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "components",
+    "bin",
+    "demo",
+    "doc",
+    "test",
+    "index.html",
+    "package.json"
+  ]
+}
diff --git a/app/gui/html/vendor/codemirror/demo/activeline.html b/app/gui/html/vendor/codemirror/demo/activeline.html
new file mode 100644
index 0000000..14851c3
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/activeline.html
@@ -0,0 +1,78 @@
+<!doctype html>
+
+<title>CodeMirror: Active Line Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<script src="../addon/selection/active-line.js"></script>
+<style type="text/css">
+      .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Active Line</a>
+  </ul>
+</div>
+
+<article>
+<h2>Active Line Demo</h2>
+<form><textarea id="code" name="code">
+<?xml version="1.0" encoding="UTF-8"?>
+<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"
+     xmlns:georss="http://www.georss.org/georss"
+     xmlns:twitter="http://api.twitter.com">
+  <channel>
+    <title>Twitter / codemirror</title>
+    <link>http://twitter.com/codemirror</link>
+    <atom:link type="application/rss+xml"
+               href="http://twitter.com/statuses/user_timeline/242283288.rss" rel="self"/>
+    <description>Twitter updates from CodeMirror / codemirror.</description>
+    <language>en-us</language>
+    <ttl>40</ttl>
+  <item>
+    <title>codemirror: http://cloud-ide.com — they're springing up like mushrooms. This one
+      uses CodeMirror as its editor.</title>
+    <description>codemirror: http://cloud-ide.com — they're springing up like mushrooms. This
+      one uses CodeMirror as its editor.</description>
+    <pubDate>Thu, 17 Mar 2011 23:34:47 +0000</pubDate>
+    <guid>http://twitter.com/codemirror/statuses/48527733722058752</guid>
+    <link>http://twitter.com/codemirror/statuses/48527733722058752</link>
+    <twitter:source>web</twitter:source>
+    <twitter:place/>
+  </item>
+  <item>
+    <title>codemirror: Posted a description of the CodeMirror 2 internals at
+      http://codemirror.net/2/internals.html</title>
+    <description>codemirror: Posted a description of the CodeMirror 2 internals at
+      http://codemirror.net/2/internals.html</description>
+    <pubDate>Wed, 02 Mar 2011 12:15:09 +0000</pubDate>
+    <guid>http://twitter.com/codemirror/statuses/42920879788789760</guid>
+    <link>http://twitter.com/codemirror/statuses/42920879788789760</link>
+    <twitter:source>web</twitter:source>
+    <twitter:place/>
+  </item>
+  </channel>
+</rss></textarea></form>
+
+    <script>
+var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+  mode: "application/xml",
+  styleActiveLine: true,
+  lineNumbers: true,
+  lineWrapping: true
+});
+</script>
+
+    <p>Styling the current cursor line.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/anywordhint.html b/app/gui/html/vendor/codemirror/demo/anywordhint.html
new file mode 100644
index 0000000..851f430
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/anywordhint.html
@@ -0,0 +1,79 @@
+<!doctype html>
+
+<title>CodeMirror: Any Word Completion Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<link rel="stylesheet" href="../addon/hint/show-hint.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/hint/show-hint.js"></script>
+<script src="../addon/hint/anyword-hint.js"></script>
+<script src="../mode/javascript/javascript.js"></script>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Any Word Completion</a>
+  </ul>
+</div>
+
+<article>
+<h2>Any Word Completion Demo</h2>
+<form><textarea id="code" name="code">
+(function() {
+  "use strict";
+
+  var WORD = /[\w$]+/g, RANGE = 500;
+
+  CodeMirror.registerHelper("hint", "anyword", function(editor, options) {
+    var word = options && options.word || WORD;
+    var range = options && options.range || RANGE;
+    var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
+    var start = cur.ch, end = start;
+    while (end < curLine.length && word.test(curLine.charAt(end))) ++end;
+    while (start && word.test(curLine.charAt(start - 1))) --start;
+    var curWord = start != end && curLine.slice(start, end);
+
+    var list = [], seen = {};
+    function scan(dir) {
+      var line = cur.line, end = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
+      for (; line != end; line += dir) {
+        var text = editor.getLine(line), m;
+        word.lastIndex = 0;
+        while (m = word.exec(text)) {
+          if ((!curWord || m[0].indexOf(curWord) == 0) && !seen.hasOwnProperty(m[0])) {
+            seen[m[0]] = true;
+            list.push(m[0]);
+          }
+        }
+      }
+    }
+    scan(-1);
+    scan(1);
+    return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
+  });
+})();
+</textarea></form>
+
+<p>Press <strong>ctrl-space</strong> to activate autocompletion. The
+completion uses
+the <a href="../doc/manual.html#addon_anyword-hint">anyword-hint.js</a>
+module, which simply looks at nearby words in the buffer and completes
+to those.</p>
+
+    <script>
+      CodeMirror.commands.autocomplete = function(cm) {
+        CodeMirror.showHint(cm, CodeMirror.hint.anyword);
+      }
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        extraKeys: {"Ctrl-Space": "autocomplete"}
+      });
+    </script>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/bidi.html b/app/gui/html/vendor/codemirror/demo/bidi.html
new file mode 100644
index 0000000..4f1f8f3
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/bidi.html
@@ -0,0 +1,74 @@
+<!doctype html>
+
+<title>CodeMirror: Bi-directional Text Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<style type="text/css">
+      .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Bi-directional Text</a>
+  </ul>
+</div>
+
+<article>
+<h2>Bi-directional Text Demo</h2>
+<form><textarea id="code" name="code"><!-- Piece of the CodeMirror manual, 'translated' into Arabic by
+     Google Translate -->
+
+<dl>
+  <dt id=option_value><code>value (string or Doc)</code></dt>
+  <dd>قيمة البداية المحرر. يمكن أن تكون سلسلة، أو. كائن مستند.</dd>
+  <dt id=option_mode><code>mode (string or object)</code></dt>
+  <dd>وضع الاستخدام. عندما لا تعطى، وهذا الافتراضي إلى الطريقة الاولى
+  التي تم تحميلها. قد يكون من سلسلة، والتي إما أسماء أو ببساطة هو وضع
+  MIME نوع المرتبطة اسطة. بدلا من ذلك، قد يكون من كائن يحتوي على
+  خيارات التكوين لواسطة، مع <code>name</code> الخاصية التي وضع أسماء
+  (على سبيل المثال <code>{name: "javascript", json: true}</code>).
+  صفحات التجريبي لكل وضع تحتوي على معلومات حول ما معلمات تكوين وضع
+  يدعمها. يمكنك أن تطلب CodeMirror التي تم تعريفها طرق وأنواع MIME
+  الكشف على <code>CodeMirror.modes</code>
+  و <code>CodeMirror.mimeModes</code> الكائنات. وضع خرائط الأسماء
+  الأولى لمنشئات الخاصة بهم، وخرائط لأنواع MIME 2 المواصفات
+  واسطة.</dd>
+  <dt id=option_theme><code>theme (string)</code></dt>
+  <dd>موضوع لنمط المحرر مع. يجب عليك التأكد من الملف CSS تحديد
+  المقابلة <code>.cm-s-[name]</code> يتم تحميل أنماط (انظر
+  <a href=../theme/><code>theme</code></a> الدليل في التوزيع).
+  الافتراضي هو <code>"default"</code> ، والتي تم تضمينها في
+  الألوان <code>codemirror.css</code>. فمن الممكن استخدام فئات متعددة
+  في تطبيق السمات مرة واحدة على سبيل المثال <code>"foo bar"</code>
+  سيتم تعيين كل من <code>cm-s-foo</code> و <code>cm-s-bar</code>
+  الطبقات إلى المحرر.</dd>
+</dl>
+</textarea></form>
+
+    <script>
+var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+  mode: "text/html",
+  lineNumbers: true
+});
+</script>
+
+  <p>Demonstration of bi-directional text support. See
+  the <a href="http://marijnhaverbeke.nl/blog/cursor-in-bidi-text.html">related
+  blog post</a> for more background.</p>
+
+  <p><strong>Note:</strong> There is
+  a <a href="https://github.com/marijnh/CodeMirror/issues/1757">known
+  bug</a> with cursor motion and mouse clicks in bi-directional lines
+  that are line wrapped.</p>
+
+</article>
diff --git a/app/gui/html/vendor/codemirror/demo/btree.html b/app/gui/html/vendor/codemirror/demo/btree.html
new file mode 100644
index 0000000..b7bd390
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/btree.html
@@ -0,0 +1,85 @@
+<!doctype html>
+
+<title>CodeMirror: B-Tree visualization</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<style type="text/css">
+      .lineblock { display: inline-block; margin: 1px; height: 5px; }
+      .CodeMirror {border: 1px solid #aaa; height: 400px}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">B-Tree visualization</a>
+  </ul>
+</div>
+
+<article>
+<h2>B-Tree visualization</h2>
+<form><textarea id="code" name="code">type here, see a summary of the document b-tree below</textarea></form>
+      </div>
+      <div style="display: inline-block; height: 402px; overflow-y: auto" id="output"></div>
+    </div>
+
+    <script id="me">
+var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+  lineNumbers: true,
+  lineWrapping: true
+});
+var updateTimeout;
+editor.on("change", function(cm) {
+  clearTimeout(updateTimeout);
+  updateTimeout = setTimeout(updateVisual, 200);
+});
+updateVisual();
+
+function updateVisual() {
+  var out = document.getElementById("output");
+  out.innerHTML = "";
+
+  function drawTree(out, node) {
+    if (node.lines) {
+      out.appendChild(document.createElement("div")).innerHTML =
+        "<b>leaf</b>: " + node.lines.length + " lines, " + Math.round(node.height) + " px";
+      var lines = out.appendChild(document.createElement("div"));
+      lines.style.lineHeight = "6px"; lines.style.marginLeft = "10px";
+      for (var i = 0; i < node.lines.length; ++i) {
+        var line = node.lines[i], lineElt = lines.appendChild(document.createElement("div"));
+        lineElt.className = "lineblock";
+        var gray = Math.min(line.text.length * 3, 230), col = gray.toString(16);
+        if (col.length == 1) col = "0" + col;
+        lineElt.style.background = "#" + col + col + col;
+        lineElt.style.width = Math.max(Math.round(line.height / 3), 1) + "px";
+      }
+    } else {
+      out.appendChild(document.createElement("div")).innerHTML =
+        "<b>node</b>: " + node.size + " lines, " + Math.round(node.height) + " px";
+      var sub = out.appendChild(document.createElement("div"));
+      sub.style.paddingLeft = "20px";
+      for (var i = 0; i < node.children.length; ++i)
+        drawTree(sub, node.children[i]);
+    }
+  }
+  drawTree(out, editor.getDoc());
+}
+
+function fillEditor() {
+  var sc = document.getElementById("me");
+  var doc = (sc.textContent || sc.innerText || sc.innerHTML).replace(/^\s*/, "") + "\n";
+  doc += doc; doc += doc; doc += doc; doc += doc; doc += doc; doc += doc;
+  editor.setValue(doc);
+}
+    </script>
+
+<p><button onclick="fillEditor()">Add a lot of content</button></p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/buffers.html b/app/gui/html/vendor/codemirror/demo/buffers.html
new file mode 100644
index 0000000..951209c
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/buffers.html
@@ -0,0 +1,109 @@
+<!doctype html>
+
+<title>CodeMirror: Multiple Buffer & Split View Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/javascript/javascript.js"></script>
+<script src="../mode/css/css.js"></script>
+<style type="text/css" id=style>
+      .CodeMirror {border: 1px solid black; height: 250px;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Multiple Buffer & Split View</a>
+  </ul>
+</div>
+
+<article>
+<h2>Multiple Buffer & Split View Demo</h2>
+
+
+    <div id=code_top></div>
+    <div>
+      Select buffer: <select id=buffers_top></select>
+          <button onclick="newBuf('top')">New buffer</button>
+    </div>
+    <div id=code_bot></div>
+    <div>
+      Select buffer: <select id=buffers_bot></select>
+          <button onclick="newBuf('bot')">New buffer</button>
+    </div>
+
+    <script id=script>
+var sel_top = document.getElementById("buffers_top");
+CodeMirror.on(sel_top, "change", function() {
+  selectBuffer(ed_top, sel_top.options[sel_top.selectedIndex].value);
+});
+
+var sel_bot = document.getElementById("buffers_bot");
+CodeMirror.on(sel_bot, "change", function() {
+  selectBuffer(ed_bot, sel_bot.options[sel_bot.selectedIndex].value);
+});
+
+var buffers = {};
+
+function openBuffer(name, text, mode) {
+  buffers[name] = CodeMirror.Doc(text, mode);
+  var opt = document.createElement("option");
+  opt.appendChild(document.createTextNode(name));
+  sel_top.appendChild(opt);
+  sel_bot.appendChild(opt.cloneNode(true));
+}
+
+function newBuf(where) {
+  var name = prompt("Name for the buffer", "*scratch*");
+  if (name == null) return;
+  if (buffers.hasOwnProperty(name)) {
+    alert("There's already a buffer by that name.");
+    return;
+  }
+  openBuffer(name, "", "javascript");
+  selectBuffer(where == "top" ? ed_top : ed_bot, name);
+  var sel = where == "top" ? sel_top : sel_bot;
+  sel.value = name;
+}
+
+function selectBuffer(editor, name) {
+  var buf = buffers[name];
+  if (buf.getEditor()) buf = buf.linkedDoc({sharedHist: true});
+  var old = editor.swapDoc(buf);
+  var linked = old.iterLinkedDocs(function(doc) {linked = doc;});
+  if (linked) {
+    // Make sure the document in buffers is the one the other view is looking at
+    for (var name in buffers) if (buffers[name] == old) buffers[name] = linked;
+    old.unlinkDoc(linked);
+  }
+  editor.focus();
+}
+
+function nodeContent(id) {
+  var node = document.getElementById(id), val = node.textContent || node.innerText;
+  val = val.slice(val.match(/^\s*/)[0].length, val.length - val.match(/\s*$/)[0].length) + "\n";
+  return val;
+}
+openBuffer("js", nodeContent("script"), "javascript");
+openBuffer("css", nodeContent("style"), "css");
+
+var ed_top = CodeMirror(document.getElementById("code_top"), {lineNumbers: true});
+selectBuffer(ed_top, "js");
+var ed_bot = CodeMirror(document.getElementById("code_bot"), {lineNumbers: true});
+selectBuffer(ed_bot, "js");
+</script>
+
+    <p>Demonstration of
+    using <a href="../doc/manual.html#linkedDoc">linked documents</a>
+    to provide a split view on a document, and
+    using <a href="../doc/manual.html#swapDoc"><code>swapDoc</code></a>
+    to use a single editor to display multiple documents.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/changemode.html b/app/gui/html/vendor/codemirror/demo/changemode.html
new file mode 100644
index 0000000..ad4c9d1
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/changemode.html
@@ -0,0 +1,58 @@
+<!doctype html>
+
+<title>CodeMirror: Mode-Changing Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/javascript/javascript.js"></script>
+<script src="../mode/scheme/scheme.js"></script>
+<style type="text/css">
+      .CodeMirror {border: 1px solid black;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Mode-Changing</a>
+  </ul>
+</div>
+
+<article>
+<h2>Mode-Changing Demo</h2>
+<form><textarea id="code" name="code">
+;; If there is Scheme code in here, the editor will be in Scheme mode.
+;; If you put in JS instead, it'll switch to JS mode.
+
+(define (double x)
+  (* x x))
+</textarea></form>
+
+<p>On changes to the content of the above editor, a (crude) script
+tries to auto-detect the language used, and switches the editor to
+either JavaScript or Scheme mode based on that.</p>
+
+<script>
+  var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+    mode: "scheme",
+    lineNumbers: true
+  });
+  var pending;
+  editor.on("change", function() {
+    clearTimeout(pending);
+    pending = setTimeout(update, 400);
+  });
+  function looksLikeScheme(code) {
+    return !/^\s*\(\s*function\b/.test(code) && /^\s*[;\(]/.test(code);
+  }
+  function update() {
+    editor.setOption("mode", looksLikeScheme(editor.getValue()) ? "scheme" : "javascript");
+  }
+</script>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/closebrackets.html b/app/gui/html/vendor/codemirror/demo/closebrackets.html
new file mode 100644
index 0000000..f7d5afb
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/closebrackets.html
@@ -0,0 +1,52 @@
+<!doctype html>
+
+<title>CodeMirror: Closebrackets Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/edit/closebrackets.js"></script>
+<script src="../mode/javascript/javascript.js"></script>
+<style type="text/css">
+      .CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Closebrackets</a>
+  </ul>
+</div>
+
+<article>
+<h2>Closebrackets Demo</h2>
+<form><textarea id="code" name="code">function Grid(width, height) {
+  this.width = width;
+  this.height = height;
+  this.cells = new Array(width * height);
+}
+Grid.prototype.valueAt = function(point) {
+  return this.cells[point.y * this.width + point.x];
+};
+Grid.prototype.setValueAt = function(point, value) {
+  this.cells[point.y * this.width + point.x] = value;
+};
+Grid.prototype.isInside = function(point) {
+  return point.x >= 0 && point.y >= 0 &&
+         point.x < this.width && point.y < this.height;
+};
+Grid.prototype.moveValue = function(from, to) {
+  this.setValueAt(to, this.valueAt(from));
+  this.setValueAt(from, undefined);
+};</textarea></form>
+
+    <script type="text/javascript">
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {autoCloseBrackets: true});
+    </script>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/closetag.html b/app/gui/html/vendor/codemirror/demo/closetag.html
new file mode 100644
index 0000000..39ca8b3
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/closetag.html
@@ -0,0 +1,41 @@
+<!doctype html>
+
+<title>CodeMirror: Close-Tag Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/edit/closetag.js"></script>
+<script src="../addon/fold/xml-fold.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<script src="../mode/javascript/javascript.js"></script>
+<script src="../mode/css/css.js"></script>
+<script src="../mode/htmlmixed/htmlmixed.js"></script>
+<style type="text/css">
+      .CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Close-Tag</a>
+  </ul>
+</div>
+
+<article>
+<h2>Close-Tag Demo</h2>
+<form><textarea id="code" name="code"><html</textarea></form>
+
+    <script type="text/javascript">
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: 'text/html',
+        autoCloseTags: true
+      });
+    </script>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/complete.html b/app/gui/html/vendor/codemirror/demo/complete.html
new file mode 100644
index 0000000..047a7ec
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/complete.html
@@ -0,0 +1,79 @@
+<!doctype html>
+
+<title>CodeMirror: Autocomplete Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<link rel="stylesheet" href="../addon/hint/show-hint.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/hint/show-hint.js"></script>
+<script src="../addon/hint/javascript-hint.js"></script>
+<script src="../mode/javascript/javascript.js"></script>
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Autocomplete</a>
+  </ul>
+</div>
+
+<article>
+<h2>Autocomplete Demo</h2>
+<form><textarea id="code" name="code">
+function getCompletions(token, context) {
+  var found = [], start = token.string;
+  function maybeAdd(str) {
+    if (str.indexOf(start) == 0) found.push(str);
+  }
+  function gatherCompletions(obj) {
+    if (typeof obj == "string") forEach(stringProps, maybeAdd);
+    else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
+    else if (obj instanceof Function) forEach(funcProps, maybeAdd);
+    for (var name in obj) maybeAdd(name);
+  }
+
+  if (context) {
+    // If this is a property, see if it belongs to some object we can
+    // find in the current environment.
+    var obj = context.pop(), base;
+    if (obj.className == "js-variable")
+      base = window[obj.string];
+    else if (obj.className == "js-string")
+      base = "";
+    else if (obj.className == "js-atom")
+      base = 1;
+    while (base != null && context.length)
+      base = base[context.pop().string];
+    if (base != null) gatherCompletions(base);
+  }
+  else {
+    // If not, just look in the window object and any local scope
+    // (reading into JS mode internals to get at the local variables)
+    for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
+    gatherCompletions(window);
+    forEach(keywords, maybeAdd);
+  }
+  return found;
+}
+</textarea></form>
+
+<p>Press <strong>ctrl-space</strong> to activate autocompletion. Built
+on top of the <a href="../doc/manual.html#addon_show-hint"><code>show-hint</code></a>
+and <a href="../doc/manual.html#addon_javascript-hint"><code>javascript-hint</code></a>
+addons.</p>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        extraKeys: {"Ctrl-Space": "autocomplete"},
+        mode: {name: "javascript", globalVars: true}
+      });
+    </script>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/emacs.html b/app/gui/html/vendor/codemirror/demo/emacs.html
new file mode 100644
index 0000000..5b622a9
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/emacs.html
@@ -0,0 +1,75 @@
+<!doctype html>
+
+<title>CodeMirror: Emacs bindings demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<link rel="stylesheet" href="../addon/dialog/dialog.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/clike/clike.js"></script>
+<script src="../keymap/emacs.js"></script>
+<script src="../addon/edit/matchbrackets.js"></script>
+<script src="../addon/comment/comment.js"></script>
+<script src="../addon/dialog/dialog.js"></script>
+<script src="../addon/search/searchcursor.js"></script>
+<script src="../addon/search/search.js"></script>
+<style type="text/css">
+      .CodeMirror {border-top: 1px solid #eee; border-bottom: 1px solid #eee;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Emacs bindings</a>
+  </ul>
+</div>
+
+<article>
+<h2>Emacs bindings demo</h2>
+<form><textarea id="code" name="code">
+#include "syscalls.h"
+/* getchar:  simple buffered version */
+int getchar(void)
+{
+  static char buf[BUFSIZ];
+  static char *bufp = buf;
+  static int n = 0;
+  if (n == 0) {  /* buffer is empty */
+    n = read(0, buf, sizeof buf);
+    bufp = buf;
+  }
+  return (--n >= 0) ? (unsigned char) *bufp++ : EOF;
+}
+</textarea></form>
+
+<p>The emacs keybindings are enabled by
+including <a href="../keymap/emacs.js">keymap/emacs.js</a> and setting
+the <code>keyMap</code> option to <code>"emacs"</code>. Because
+CodeMirror's internal API is quite different from Emacs, they are only
+a loose approximation of actual emacs bindings, though.</p>
+
+<p>Also note that a lot of browsers disallow certain keys from being
+captured. For example, Chrome blocks both Ctrl-W and Ctrl-N, with the
+result that idiomatic use of Emacs keys will constantly close your tab
+or open a new window.</p>
+
+    <script>
+      CodeMirror.commands.save = function() {
+        var elt = editor.getWrapperElement();
+        elt.style.background = "#def";
+        setTimeout(function() { elt.style.background = ""; }, 300);
+      };
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        mode: "text/x-csrc",
+        keyMap: "emacs"
+      });
+    </script>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/folding.html b/app/gui/html/vendor/codemirror/demo/folding.html
new file mode 100644
index 0000000..84ef510
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/folding.html
@@ -0,0 +1,95 @@
+<!doctype html>
+
+<head>
+  <title>CodeMirror: Code Folding Demo</title>
+  <meta charset="utf-8"/>
+  <link rel=stylesheet href="../doc/docs.css">
+
+  <link rel="stylesheet" href="../lib/codemirror.css">
+  <link rel="stylesheet" href="../addon/fold/foldgutter.css" />
+  <script src="../lib/codemirror.js"></script>
+  <script src="../addon/fold/foldcode.js"></script>
+  <script src="../addon/fold/foldgutter.js"></script>
+  <script src="../addon/fold/brace-fold.js"></script>
+  <script src="../addon/fold/xml-fold.js"></script>
+  <script src="../addon/fold/markdown-fold.js"></script>
+  <script src="../addon/fold/comment-fold.js"></script>
+  <script src="../mode/javascript/javascript.js"></script>
+  <script src="../mode/xml/xml.js"></script>
+  <script src="../mode/markdown/markdown.js"></script>
+  <style type="text/css">
+    .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+  </style>
+</head>
+
+<body>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Code Folding</a>
+  </ul>
+</div>
+
+<article>
+  <h2>Code Folding Demo</h2>
+  <form>
+    <div style="max-width: 50em; margin-bottom: 1em">JavaScript:<br>
+    <textarea id="code" name="code"></textarea></div>
+    <div style="max-width: 50em; margin-bottom: 1em">HTML:<br>
+    <textarea id="code-html" name="code-html"></textarea></div>
+    <div style="max-width: 50em">Markdown:<br>
+    <textarea id="code-markdown" name="code"></textarea></div>
+  </form>
+  <script id="script">
+/*
+ * Demonstration of code folding
+ */
+window.onload = function() {
+  var te = document.getElementById("code");
+  var sc = document.getElementById("script");
+  te.value = (sc.textContent || sc.innerText || sc.innerHTML).replace(/^\s*/, "");
+  sc.innerHTML = "";
+  var te_html = document.getElementById("code-html");
+  te_html.value = document.documentElement.innerHTML;
+  var te_markdown = document.getElementById("code-markdown");
+  te_markdown.value = "# Foo\n## Bar\n\nblah blah\n\n## Baz\n\nblah blah\n\n# Quux\n\nblah blah\n"
+
+  window.editor = CodeMirror.fromTextArea(te, {
+    mode: "javascript",
+    lineNumbers: true,
+    lineWrapping: true,
+    extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
+    foldGutter: true,
+    gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
+  });
+  editor.foldCode(CodeMirror.Pos(11, 0));
+
+  window.editor_html = CodeMirror.fromTextArea(te_html, {
+    mode: "text/html",
+    lineNumbers: true,
+    lineWrapping: true,
+    extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
+    foldGutter: true,
+    gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
+  });
+  editor_html.foldCode(CodeMirror.Pos(0, 0));
+  editor_html.foldCode(CodeMirror.Pos(21, 0));
+
+  window.editor_markdown = CodeMirror.fromTextArea(te_markdown, {
+    mode: "markdown",
+    lineNumbers: true,
+    lineWrapping: true,
+    extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
+    foldGutter: true,
+    gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
+  });
+};
+  </script>
+</article>
+</body>
diff --git a/app/gui/html/vendor/codemirror/demo/fullscreen.html b/app/gui/html/vendor/codemirror/demo/fullscreen.html
new file mode 100644
index 0000000..0a11f31
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/fullscreen.html
@@ -0,0 +1,83 @@
+<!doctype html>
+
+<title>CodeMirror: Full Screen Editing</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<link rel="stylesheet" href="../addon/display/fullscreen.css">
+<link rel="stylesheet" href="../theme/night.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<script src="../addon/display/fullscreen.js"></script>
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Full Screen Editing</a>
+  </ul>
+</div>
+
+<article>
+<h2>Full Screen Editing</h2>
+<form><textarea id="code" name="code" rows="5">
+<dl>
+  <dt id="option_indentWithTabs"><code><strong>indentWithTabs</strong>: boolean</code></dt>
+  <dd>Whether, when indenting, the first N*<code>tabSize</code>
+  spaces should be replaced by N tabs. Default is false.</dd>
+
+  <dt id="option_electricChars"><code><strong>electricChars</strong>: boolean</code></dt>
+  <dd>Configures whether the editor should re-indent the current
+  line when a character is typed that might change its proper
+  indentation (only works if the mode supports indentation).
+  Default is true.</dd>
+
+  <dt id="option_specialChars"><code><strong>specialChars</strong>: RegExp</code></dt>
+  <dd>A regular expression used to determine which characters
+  should be replaced by a
+  special <a href="#option_specialCharPlaceholder">placeholder</a>.
+  Mostly useful for non-printing special characters. The default
+  is <code>/[\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/</code>.</dd>
+  <dt id="option_specialCharPlaceholder"><code><strong>specialCharPlaceholder</strong>: function(char) → Element</code></dt>
+  <dd>A function that, given a special character identified by
+  the <a href="#option_specialChars"><code>specialChars</code></a>
+  option, produces a DOM node that is used to represent the
+  character. By default, a red dot (<span style="color: red">•</span>)
+  is shown, with a title tooltip to indicate the character code.</dd>
+
+  <dt id="option_rtlMoveVisually"><code><strong>rtlMoveVisually</strong>: boolean</code></dt>
+  <dd>Determines whether horizontal cursor movement through
+  right-to-left (Arabic, Hebrew) text is visual (pressing the left
+  arrow moves the cursor left) or logical (pressing the left arrow
+  moves to the next lower index in the string, which is visually
+  right in right-to-left text). The default is <code>false</code>
+  on Windows, and <code>true</code> on other platforms.</dd>
+</dl>
+</textarea></form>
+  <script>
+    var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+      lineNumbers: true,
+      theme: "night",
+      extraKeys: {
+        "F11": function(cm) {
+          cm.setOption("fullScreen", !cm.getOption("fullScreen"));
+        },
+        "Esc": function(cm) {
+          if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
+        }
+      }
+    });
+  </script>
+
+    <p>Demonstration of
+    the <a href="../doc/manual.html#addon_fullscreen">fullscreen</a>
+    addon. Press <strong>F11</strong> when cursor is in the editor to
+    toggle full screen editing. <strong>Esc</strong> can also be used
+    to <i>exit</i> full screen editing.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/hardwrap.html b/app/gui/html/vendor/codemirror/demo/hardwrap.html
new file mode 100644
index 0000000..598bf95
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/hardwrap.html
@@ -0,0 +1,72 @@
+<!doctype html>
+
+<title>CodeMirror: Hard-wrapping Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/markdown/markdown.js"></script>
+<script src="../addon/wrap/hardwrap.js"></script>
+<style type="text/css">
+  .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Hard-wrapping</a>
+  </ul>
+</div>
+
+<article>
+<h2>Hard-wrapping Demo</h2>
+<form><textarea id="code" name="code">Lorem ipsum dolor sit amet, vim augue dictas constituto ex,
+sit falli simul viderer te. Graeco scaevola maluisset sit
+ut, in idque viris praesent sea. Ea sea eirmod indoctum
+repudiare. Vel noluisse suscipit pericula ut. In ius nulla
+alienum molestie. Mei essent discere democritum id.
+
+Equidem ponderum expetendis ius in, mea an erroribus
+constituto, congue timeam perfecto ad est. Ius ut primis
+timeam, per in ullum mediocrem. An case vero labitur pri,
+vel dicit laoreet et. An qui prompta conclusionemque, eam
+timeam sapientem in, cum dictas epicurei eu.
+
+Usu cu vide dictas deseruisse, eum choro graece adipiscing
+ut. Cibo qualisque ius ad, et dicat scripta mea, eam nihil
+mentitum aliquando cu. Debet aperiam splendide at quo, ad
+paulo nostro commodo duo. Sea adhuc utinam conclusionemque
+id, quas doming malorum nec ad. Tollit eruditi vivendum ad
+ius, eos soleat ignota ad.
+</textarea></form>
+
+<p>Demonstration of
+the <a href="../doc/manual.html#addon_hardwrap">hardwrap</a> addon.
+The above editor has its change event hooked up to
+the <code>wrapParagraphsInRange</code> method, so that the paragraphs
+are reflown as you are typing.</p>
+
+<script>
+var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+  mode: "markdown",
+  lineNumbers: true,
+  extraKeys: {
+    "Ctrl-Q": function(cm) { cm.wrapParagraph(cm.getCursor(), options); }
+  }
+});
+var wait, options = {column: 60};
+editor.on("change", function(cm, change) {
+  clearTimeout(wait);
+  wait = setTimeout(function() {
+    console.log(cm.wrapParagraphsInRange(change.from, CodeMirror.changeEnd(change), options));
+  }, 200);
+});
+</script>
+
+</article>
diff --git a/app/gui/html/vendor/codemirror/demo/html5complete.html b/app/gui/html/vendor/codemirror/demo/html5complete.html
new file mode 100644
index 0000000..94ced52
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/html5complete.html
@@ -0,0 +1,56 @@
+<!doctype html>
+
+<head>
+  <title>CodeMirror: HTML completion demo</title>
+  <meta charset="utf-8"/>
+  <link rel=stylesheet href="../doc/docs.css">
+
+  <link rel="stylesheet" href="../lib/codemirror.css">
+  <link rel="stylesheet" href="../addon/hint/show-hint.css">
+  <script src="../lib/codemirror.js"></script>
+  <script src="../addon/hint/show-hint.js"></script>
+  <script src="../addon/hint/xml-hint.js"></script>
+  <script src="../addon/hint/html-hint.js"></script>
+  <script src="../mode/xml/xml.js"></script>
+  <script src="../mode/javascript/javascript.js"></script>
+  <script src="../mode/css/css.js"></script>
+  <script src="../mode/htmlmixed/htmlmixed.js"></script>
+  <style type="text/css">
+    .CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;}
+  </style>
+</head>
+
+<body>
+  <div id=nav>
+    <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+    <ul>
+      <li><a href="../index.html">Home</a>
+      <li><a href="../doc/manual.html">Manual</a>
+      <li><a href="https://github.com/marijnh/codemirror">Code</a>
+    </ul>
+    <ul>
+      <li><a class=active href="#">HTML completion</a>
+    </ul>
+  </div>
+
+  <article>
+    <h2>HTML completion demo</h2>
+
+    <p>Shows the <a href="xmlcomplete.html">XML completer</a>
+    parameterized with information about the tags in HTML.
+    Press <strong>ctrl-space</strong> to activate completion.</p>
+
+    <div id="code"></div>
+
+    <script type="text/javascript">
+      window.onload = function() {
+        editor = CodeMirror(document.getElementById("code"), {
+          mode: "text/html",
+          extraKeys: {"Ctrl-Space": "autocomplete"},
+          value: document.documentElement.innerHTML
+        });
+      };
+    </script>
+  </article>
+</body>
diff --git a/app/gui/html/vendor/codemirror/demo/indentwrap.html b/app/gui/html/vendor/codemirror/demo/indentwrap.html
new file mode 100644
index 0000000..efdba5d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/indentwrap.html
@@ -0,0 +1,59 @@
+<!doctype html>
+
+<title>CodeMirror: Indented wrapped line demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<style type="text/css">
+      .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+      .CodeMirror pre > * { text-indent: 0px; }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Indented wrapped line</a>
+  </ul>
+</div>
+
+<article>
+<h2>Indented wrapped line demo</h2>
+<form><textarea id="code" name="code">
+<!doctype html>
+<body>
+  <h2 id="overview">Overview</h2>
+
+  <p>CodeMirror is a code-editor component that can be embedded in Web pages. The core library provides <em>only</em> the editor component, no accompanying buttons, auto-completion, or other IDE functionality. It does provide a rich API on top of which such functionality can be straightforwardly implemented. See the <a href="#addons">add-ons</a> included in the distribution, and the <a href="https://github.com/jagthedrummer/codemirror-ui">CodeMirror UI</a> project, for reusable implementations of extra features.</p>
+
+  <p>CodeMirror works with language-specific modes. Modes are JavaScript programs that help color (and optionally indent) text written in a given language. The distribution comes with a number of modes (see the <a href="../mode/"><code>mode/</code></a> directory), and it isn't hard to <a href="#modeapi">write new ones</a> for other languages.</p>
+</body>
+</textarea></form>
+
+    <p>This page uses a hack on top of the <code>"renderLine"</code>
+    event to make wrapped text line up with the base indentation of
+    the line.</p>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        lineWrapping: true,
+        mode: "text/html"
+      });
+      var charWidth = editor.defaultCharWidth(), basePadding = 4;
+      editor.on("renderLine", function(cm, line, elt) {
+        var off = CodeMirror.countColumn(line.text, null, cm.getOption("tabSize")) * charWidth;
+        elt.style.textIndent = "-" + off + "px";
+        elt.style.paddingLeft = (basePadding + off) + "px";
+      });
+      editor.refresh();
+    </script>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/lint.html b/app/gui/html/vendor/codemirror/demo/lint.html
new file mode 100644
index 0000000..8372c52
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/lint.html
@@ -0,0 +1,171 @@
+<!doctype html>
+
+<title>CodeMirror: Linter Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<link rel="stylesheet" href="../addon/lint/lint.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/javascript/javascript.js"></script>
+<script src="../mode/css/css.js"></script>
+<script src="http://ajax.aspnetcdn.com/ajax/jshint/r07/jshint.js"></script>
+<script src="https://rawgithub.com/zaach/jsonlint/79b553fb65c192add9066da64043458981b3972b/lib/jsonlint.js"></script>
+<script src="https://rawgithub.com/stubbornella/csslint/master/release/csslint.js"></script>
+<script src="../addon/lint/lint.js"></script>
+<script src="../addon/lint/javascript-lint.js"></script>
+<script src="../addon/lint/json-lint.js"></script>
+<script src="../addon/lint/css-lint.js"></script>
+<style type="text/css">
+      .CodeMirror {border: 1px solid black;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Linter</a>
+  </ul>
+</div>
+
+<article>
+<h2>Linter Demo</h2>
+
+
+    <p><textarea id="code-js">var widgets = []
+function updateHints() {
+  editor.operation(function(){
+    for (var i = 0; i < widgets.length; ++i)
+      editor.removeLineWidget(widgets[i]);
+    widgets.length = 0;
+
+    JSHINT(editor.getValue());
+    for (var i = 0; i < JSHINT.errors.length; ++i) {
+      var err = JSHINT.errors[i];
+      if (!err) continue;
+      var msg = document.createElement("div");
+      var icon = msg.appendChild(document.createElement("span"));
+      icon.innerHTML = "!!";
+      icon.className = "lint-error-icon";
+      msg.appendChild(document.createTextNode(err.reason));
+      msg.className = "lint-error";
+      widgets.push(editor.addLineWidget(err.line - 1, msg, {coverGutter: false, noHScroll: true}));
+    }
+  });
+  var info = editor.getScrollInfo();
+  var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top;
+  if (info.top + info.clientHeight < after)
+    editor.scrollTo(null, after - info.clientHeight + 3);
+}
+</textarea></p>
+
+    <p><textarea id="code-json">[
+ {
+  _id: "post 1",
+  "author": "Bob",
+  "content": "...",
+  "page_views": 5
+ },
+ {
+  "_id": "post 2",
+  "author": "Bob",
+  "content": "...",
+  "page_views": 9
+ },
+ {
+  "_id": "post 3",
+  "author": "Bob",
+  "content": "...",
+  "page_views": 8
+ }
+]
+</textarea></p>
+
+    <p><textarea id="code-css">@charset "UTF-8";
+
+ at import url("booya.css") print, screen;
+ at import "whatup.css" screen;
+ at import "wicked.css";
+
+/*Error*/
+ at charset "UTF-8";
+
+
+ at namespace "http://www.w3.org/1999/xhtml";
+ at namespace svg "http://www.w3.org/2000/svg";
+
+/*Warning: empty ruleset */
+.foo {
+}
+
+h1 {
+    font-weight: bold;
+}
+
+/*Warning: qualified heading */
+.foo h1 {
+    font-weight: bold;
+}
+
+/*Warning: adjoining classes */
+.foo.bar {
+    zoom: 1;
+}
+
+li.inline {
+    width: 100%;  /*Warning: 100% can be problematic*/
+}
+
+li.last {
+  display: inline;
+  padding-left: 3px !important;
+  padding-right: 3px;
+  border-right: 0px;
+}
+
+ at media print {
+    li.inline {
+      color: black;
+    }
+}
+
+ at page {
+  margin: 10%;
+  counter-increment: page;
+
+  @top-center {
+    font-family: sans-serif;
+    font-weight: bold;
+    font-size: 2em;
+    content: counter(page);
+  }
+}
+</textarea></p>
+<script>
+  var editor = CodeMirror.fromTextArea(document.getElementById("code-js"), {
+    lineNumbers: true,
+    mode: "javascript",
+    gutters: ["CodeMirror-lint-markers"],
+    lint: true
+  });
+
+  var editor_json = CodeMirror.fromTextArea(document.getElementById("code-json"), {
+    lineNumbers: true,
+    mode: "application/json",
+    gutters: ["CodeMirror-lint-markers"],
+    lint: true
+  });
+  
+  var editor_css = CodeMirror.fromTextArea(document.getElementById("code-css"), {
+    lineNumbers: true,
+    mode: "css",
+    gutters: ["CodeMirror-lint-markers"],
+    lint: true
+  });
+</script>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/loadmode.html b/app/gui/html/vendor/codemirror/demo/loadmode.html
new file mode 100644
index 0000000..be28c7a
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/loadmode.html
@@ -0,0 +1,49 @@
+<!doctype html>
+
+<title>CodeMirror: Lazy Mode Loading Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/mode/loadmode.js"></script>
+<style type="text/css">
+      .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Lazy Mode Loading</a>
+  </ul>
+</div>
+
+<article>
+<h2>Lazy Mode Loading Demo</h2>
+<form><textarea id="code" name="code">This is the editor.
+// It starts out in plain text mode,
+#  use the control below to load and apply a mode
+  "you'll see the highlighting of" this text /*change*/.
+</textarea></form>
+<p><input type=text value=javascript id=mode> <button type=button onclick="change()">change mode</button></p>
+
+    <script>
+CodeMirror.modeURL = "../mode/%N/%N.js";
+var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+  lineNumbers: true
+});
+var modeInput = document.getElementById("mode");
+CodeMirror.on(modeInput, "keypress", function(e) {
+  if (e.keyCode == 13) change();
+});
+function change() {
+   editor.setOption("mode", modeInput.value);
+   CodeMirror.autoLoadMode(editor, modeInput.value);
+}
+</script>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/marker.html b/app/gui/html/vendor/codemirror/demo/marker.html
new file mode 100644
index 0000000..ac4dfda
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/marker.html
@@ -0,0 +1,52 @@
+<!doctype html>
+
+<title>CodeMirror: Breakpoint Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/javascript/javascript.js"></script>
+<style type="text/css">
+      .breakpoints {width: .8em;}
+      .breakpoint { color: #822; }
+      .CodeMirror {border: 1px solid #aaa;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Breakpoint</a>
+  </ul>
+</div>
+
+<article>
+<h2>Breakpoint Demo</h2>
+<form><textarea id="code" name="code">
+var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+  lineNumbers: true,
+  gutters: ["CodeMirror-linenumbers", "breakpoints"]
+});
+editor.on("gutterClick", function(cm, n) {
+  var info = cm.lineInfo(n);
+  cm.setGutterMarker(n, "breakpoints", info.gutterMarkers ? null : makeMarker());
+});
+
+function makeMarker() {
+  var marker = document.createElement("div");
+  marker.style.color = "#822";
+  marker.innerHTML = "●";
+  return marker;
+}
+</textarea></form>
+
+<p>Click the line-number gutter to add or remove 'breakpoints'.</p>
+
+    <script>eval(document.getElementById("code").value);</script>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/markselection.html b/app/gui/html/vendor/codemirror/demo/markselection.html
new file mode 100644
index 0000000..4549332
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/markselection.html
@@ -0,0 +1,45 @@
+<!doctype html>
+
+<title>CodeMirror: Match Selection Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/search/searchcursor.js"></script>
+<script src="../addon/selection/mark-selection.js"></script>
+<style type="text/css">
+      .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+      .CodeMirror-selected  { background-color: blue !important; }
+      .CodeMirror-selectedtext { color: white; }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Match Selection</a>
+  </ul>
+</div>
+
+<article>
+<h2>Match Selection Demo</h2>
+<form><textarea id="code" name="code">Select something from here.
+You'll see that the selection's foreground color changes to white!
+Since, by default, CodeMirror only puts an independent "marker" layer
+behind the text, you'll need something like this to change its colour.</textarea></form>
+
+    <script>
+var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+  lineNumbers: true,
+  styleSelectedText: true
+});
+</script>
+
+    <p>Simple addon to easily mark (and style) selected text.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/matchhighlighter.html b/app/gui/html/vendor/codemirror/demo/matchhighlighter.html
new file mode 100644
index 0000000..170213b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/matchhighlighter.html
@@ -0,0 +1,47 @@
+<!doctype html>
+
+<title>CodeMirror: Match Highlighter Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/search/searchcursor.js"></script>
+<script src="../addon/search/match-highlighter.js"></script>
+<style type="text/css">
+      .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+      .CodeMirror-focused .cm-matchhighlight {
+        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==);
+        background-position: bottom;
+        background-repeat: repeat-x;
+      }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Match Highlighter</a>
+  </ul>
+</div>
+
+<article>
+<h2>Match Highlighter Demo</h2>
+<form><textarea id="code" name="code">Select this text: hardToSpotVar
+	And everywhere else in your code where hardToSpotVar appears will automatically illuminate.
+Give it a try!  No more hardToSpotVars.</textarea></form>
+
+    <script>
+var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+  lineNumbers: true,
+  highlightSelectionMatches: {showToken: /\w/}
+});
+</script>
+
+    <p>Search and highlight occurences of the selected text.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/matchtags.html b/app/gui/html/vendor/codemirror/demo/matchtags.html
new file mode 100644
index 0000000..9a3797e
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/matchtags.html
@@ -0,0 +1,49 @@
+<!doctype html>
+
+<title>CodeMirror: Tag Matcher Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/fold/xml-fold.js"></script>
+<script src="../addon/edit/matchtags.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<style type="text/css">
+      .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+      .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Tag Matcher</a>
+  </ul>
+</div>
+
+<article>
+<h2>Tag Matcher Demo</h2>
+
+
+    <div id="editor"></div>
+
+    <script>
+window.onload = function() {
+  editor = CodeMirror(document.getElementById("editor"), {
+    value: "<html>\n  " + document.documentElement.innerHTML + "\n</html>",
+    mode: "text/html",
+    matchTags: {bothTags: true},
+    extraKeys: {"Ctrl-J": "toMatchingTag"}
+  });
+};
+    </script>
+
+    <p>Put the cursor on or inside a pair of tags to highlight them.
+    Press Ctrl-J to jump to the tag that matches the one under the
+    cursor.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/merge.html b/app/gui/html/vendor/codemirror/demo/merge.html
new file mode 100644
index 0000000..fc272f0
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/merge.html
@@ -0,0 +1,81 @@
+<!doctype html>
+
+<title>CodeMirror: merge view demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel=stylesheet href="../lib/codemirror.css">
+<link rel=stylesheet href="../addon/merge/merge.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<script src="../addon/merge/dep/diff_match_patch.js"></script>
+<script src="../addon/merge/merge.js"></script>
+<style>
+    .CodeMirror { line-height: 1.2; }
+    span.clicky {
+      cursor: pointer;
+      background: #d70;
+      color: white;
+      padding: 0 3px;
+      border-radius: 3px;
+    }
+  </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">merge view</a>
+  </ul>
+</div>
+
+<article>
+<h2>merge view demo</h2>
+
+
+<div id=view></div>
+
+<p>The <a href="../doc/manual.html#addon_merge"><code>merge</code></a>
+addon provides an interface for displaying and merging diffs,
+either <span class=clicky onclick="initUI(2)">two-way</span>
+or <span class=clicky onclick="initUI(3)">three-way</span>. The left
+(or center) pane is editable, and the differences with the other
+pane(s) are <span class=clicky onclick="toggleDifferences()">optionally</span> shown live as you edit it.</p>
+
+<p>This addon depends on
+the <a href="https://code.google.com/p/google-diff-match-patch/">google-diff-match-patch</a>
+library to compute the diffs.</p>
+
+<script>
+var value, orig1, orig2, dv, hilight= true;
+function initUI(panes) {
+  if (value == null) return;
+  var target = document.getElementById("view");
+  target.innerHTML = "";
+  dv = CodeMirror.MergeView(target, {
+    value: value,
+    origLeft: panes == 3 ? orig1 : null,
+    orig: orig2,
+    lineNumbers: true,
+    mode: "text/html",
+    highlightDifferences: hilight
+  });
+}
+
+function toggleDifferences() {
+  dv.setShowDifferences(hilight = !hilight);
+}
+
+window.onload = function() {
+  value = document.documentElement.innerHTML;
+  orig1 = value.replace(/\.\.\//g, "codemirror/").replace("yellow", "orange");
+  orig2 = value.replace(/\u003cscript/g, "\u003cscript type=text/javascript ")
+    .replace("white", "purple;\n      font: comic sans;\n      text-decoration: underline;\n      height: 15em");
+  initUI(2);
+};
+</script>
+</article>
diff --git a/app/gui/html/vendor/codemirror/demo/multiplex.html b/app/gui/html/vendor/codemirror/demo/multiplex.html
new file mode 100644
index 0000000..2ad9608
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/multiplex.html
@@ -0,0 +1,75 @@
+<!doctype html>
+
+<title>CodeMirror: Multiplexing Parser Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/mode/multiplex.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<style type="text/css">
+      .CodeMirror {border: 1px solid black;}
+      .cm-delimit {color: #fa4;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Multiplexing Parser</a>
+  </ul>
+</div>
+
+<article>
+<h2>Multiplexing Parser Demo</h2>
+<form><textarea id="code" name="code">
+<html>
+  <body style="<<magic>>">
+    <h1><< this is not <html >></h1>
+    <<
+        multiline
+        not html
+        at all : &amp; <link/>
+    >>
+    <p>this is html again</p>
+  </body>
+</html>
+</textarea></form>
+
+    <script>
+CodeMirror.defineMode("demo", function(config) {
+  return CodeMirror.multiplexingMode(
+    CodeMirror.getMode(config, "text/html"),
+    {open: "<<", close: ">>",
+     mode: CodeMirror.getMode(config, "text/plain"),
+     delimStyle: "delimit"}
+    // .. more multiplexed styles can follow here
+  );
+});
+var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+  mode: "demo",
+  lineNumbers: true,
+  lineWrapping: true
+});
+</script>
+
+    <p>Demonstration of a multiplexing mode, which, at certain
+    boundary strings, switches to one or more inner modes. The out
+    (HTML) mode does not get fed the content of the <code><<
+    >></code> blocks. See
+    the <a href="../doc/manual.html#addon_multiplex">manual</a> and
+    the <a href="../addon/mode/multiplex.js">source</a> for more
+    information.</p>
+
+    <p>
+      <strong>Parsing/Highlighting Tests:</strong>
+      <a href="../test/index.html#multiplexing_*">normal</a>,
+      <a href="../test/index.html#verbose,multiplexing_*">verbose</a>.
+    </p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/mustache.html b/app/gui/html/vendor/codemirror/demo/mustache.html
new file mode 100644
index 0000000..cb02915
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/mustache.html
@@ -0,0 +1,68 @@
+<!doctype html>
+
+<title>CodeMirror: Overlay Parser Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/mode/overlay.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<style type="text/css">
+      .CodeMirror {border: 1px solid black;}
+      .cm-mustache {color: #0ca;}
+</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Overlay Parser</a>
+  </ul>
+</div>
+
+<article>
+<h2>Overlay Parser Demo</h2>
+<form><textarea id="code" name="code">
+<html>
+  <body>
+    <h1>{{title}}</h1>
+    <p>These are links to {{things}}:</p>
+    <ul>{{#links}}
+      <li><a href="{{url}}">{{text}}</a></li>
+    {{/links}}</ul>
+  </body>
+</html>
+</textarea></form>
+
+    <script>
+CodeMirror.defineMode("mustache", function(config, parserConfig) {
+  var mustacheOverlay = {
+    token: function(stream, state) {
+      var ch;
+      if (stream.match("{{")) {
+        while ((ch = stream.next()) != null)
+          if (ch == "}" && stream.next() == "}") break;
+        stream.eat("}");
+        return "mustache";
+      }
+      while (stream.next() != null && !stream.match("{{", false)) {}
+      return null;
+    }
+  };
+  return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || "text/html"), mustacheOverlay);
+});
+var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: "mustache"});
+</script>
+
+    <p>Demonstration of a mode that parses HTML, highlighting
+    the <a href="http://mustache.github.com/">Mustache</a> templating
+    directives inside of it by using the code
+    in <a href="../addon/mode/overlay.js"><code>overlay.js</code></a>. View
+    source to see the 15 lines of code needed to accomplish this.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/placeholder.html b/app/gui/html/vendor/codemirror/demo/placeholder.html
new file mode 100644
index 0000000..6cf098b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/placeholder.html
@@ -0,0 +1,45 @@
+<!doctype html>
+
+<title>CodeMirror: Placeholder demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/display/placeholder.js"></script>
+<style type="text/css">
+      .CodeMirror { border: 1px solid silver; }
+      .CodeMirror-empty { outline: 1px solid #c22; }
+      .CodeMirror-empty.CodeMirror-focused { outline: none; }
+      .CodeMirror pre.CodeMirror-placeholder { color: #999; }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Placeholder</a>
+  </ul>
+</div>
+
+<article>
+<h2>Placeholder demo</h2>
+<form><textarea id="code" name="code" placeholder="Code goes here..."></textarea></form>
+
+    <p>The <a href="../doc/manual.html#addon_placeholder">placeholder</a>
+    plug-in adds an option <code>placeholder</code> that can be set to
+    make text appear in the editor when it is empty and not focused.
+    If the source textarea has a <code>placeholder</code> attribute,
+    it will automatically be inherited.</p>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true
+      });
+    </script>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/preview.html b/app/gui/html/vendor/codemirror/demo/preview.html
new file mode 100644
index 0000000..d2aada3
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/preview.html
@@ -0,0 +1,87 @@
+<!doctype html>
+
+<title>CodeMirror: HTML5 preview</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel=stylesheet href=../lib/codemirror.css>
+<script src=../lib/codemirror.js></script>
+<script src=../mode/xml/xml.js></script>
+<script src=../mode/javascript/javascript.js></script>
+<script src=../mode/css/css.js></script>
+<script src=../mode/htmlmixed/htmlmixed.js></script>
+<style type=text/css>
+      .CodeMirror {
+        float: left;
+        width: 50%;
+        border: 1px solid black;
+      }
+      iframe {
+        width: 49%;
+        float: left;
+        height: 300px;
+        border: 1px solid black;
+        border-left: 0px;
+      }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">HTML5 preview</a>
+  </ul>
+</div>
+
+<article>
+<h2>HTML5 preview</h2>
+
+    <textarea id=code name=code>
+<!doctype html>
+<html>
+  <head>
+    <meta charset=utf-8>
+    <title>HTML5 canvas demo</title>
+    <style>p {font-family: monospace;}</style>
+  </head>
+  <body>
+    <p>Canvas pane goes here:</p>
+    <canvas id=pane width=300 height=200></canvas>
+    <script>
+      var canvas = document.getElementById('pane');
+      var context = canvas.getContext('2d');
+
+      context.fillStyle = 'rgb(250,0,0)';
+      context.fillRect(10, 10, 55, 50);
+
+      context.fillStyle = 'rgba(0, 0, 250, 0.5)';
+      context.fillRect(30, 30, 55, 50);
+    </script>
+  </body>
+</html></textarea>
+    <iframe id=preview></iframe>
+    <script>
+      var delay;
+      // Initialize CodeMirror editor with a nice html5 canvas demo.
+      var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
+        mode: 'text/html'
+      });
+      editor.on("change", function() {
+        clearTimeout(delay);
+        delay = setTimeout(updatePreview, 300);
+      });
+      
+      function updatePreview() {
+        var previewFrame = document.getElementById('preview');
+        var preview =  previewFrame.contentDocument ||  previewFrame.contentWindow.document;
+        preview.open();
+        preview.write(editor.getValue());
+        preview.close();
+      }
+      setTimeout(updatePreview, 300);
+    </script>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/resize.html b/app/gui/html/vendor/codemirror/demo/resize.html
new file mode 100644
index 0000000..10326ef
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/resize.html
@@ -0,0 +1,58 @@
+<!doctype html>
+
+<title>CodeMirror: Autoresize Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/css/css.js"></script>
+<style type="text/css">
+      .CodeMirror {
+        border: 1px solid #eee;
+        height: auto;
+      }
+      .CodeMirror-scroll {
+        overflow-y: hidden;
+        overflow-x: auto;
+      }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Autoresize</a>
+  </ul>
+</div>
+
+<article>
+<h2>Autoresize Demo</h2>
+<form><textarea id="code" name="code">
+.CodeMirror {
+  border: 1px solid #eee;
+  height: auto;
+}
+.CodeMirror-scroll {
+  overflow-y: hidden;
+  overflow-x: auto;
+}
+</textarea></form>
+
+<p>By setting a few CSS properties, and giving
+the <a href="../doc/manual.html#option_viewportMargin"><code>viewportMargin</code></a>
+a value of <code>Infinity</code>, CodeMirror can be made to
+automatically resize to fit its content.</p>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        viewportMargin: Infinity
+      });
+    </script>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/rulers.html b/app/gui/html/vendor/codemirror/demo/rulers.html
new file mode 100644
index 0000000..d75fd08
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/rulers.html
@@ -0,0 +1,54 @@
+<!doctype html>
+
+<title>CodeMirror: Ruler Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/display/rulers.js"></script>
+<style type="text/css">
+  .CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;}
+  .ruler1 { border-left: 1px solid #fcc; }
+  .ruler2 { border-left: 1px solid #f5f577; }
+  .ruler3 { border-left: 1px solid #cfc; }
+  .ruler4 { border-left: 1px solid #aff; }
+  .ruler5 { border-left: 1px solid #ccf; }
+  .ruler6 { border-left: 1px solid #fcf; }
+</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Ruler demo</a>
+  </ul>
+</div>
+
+<article>
+<h2>Ruler Demo</h2>
+
+<script type="text/javascript">
+  var nums = "0123456789", space = "          ";
+  var rulers = [], value = "";
+  for (var i = 1; i <= 6; i++) {
+    rulers.push({className: "ruler" + i, column: i * 10});
+    for (var j = 1; j < i; j++) value += space;
+    value += nums + "\n";
+  }
+  var editor = CodeMirror(document.body.lastChild, {
+    rulers: rulers,
+    value: value + value + value,
+    lineNumbers: true
+});
+</script>
+
+<p>Demonstration of
+the <a href="../doc/manual.html#addon_rulers">rulers</a> addon, which
+displays vertical lines at given column offsets.</p>
+
+</article>
diff --git a/app/gui/html/vendor/codemirror/demo/runmode.html b/app/gui/html/vendor/codemirror/demo/runmode.html
new file mode 100644
index 0000000..144783d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/runmode.html
@@ -0,0 +1,62 @@
+<!doctype html>
+
+<title>CodeMirror: Mode Runner Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/runmode/runmode.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Mode Runner</a>
+  </ul>
+</div>
+
+<article>
+<h2>Mode Runner Demo</h2>
+
+
+    <textarea id="code" style="width: 90%; height: 7em; border: 1px solid black; padding: .2em .4em;">
+<foobar>
+  <blah>Enter your xml here and press the button below to display
+    it as highlighted by the CodeMirror XML mode</blah>
+  <tag2 foo="2" bar="&quot;bar&quot;"/>
+</foobar></textarea><br>
+    <button onclick="doHighlight();">Highlight!</button>
+    <pre id="output" class="cm-s-default"></pre>
+
+    <script>
+function doHighlight() {
+  CodeMirror.runMode(document.getElementById("code").value, "application/xml",
+                     document.getElementById("output"));
+}
+</script>
+
+    <p>Running a CodeMirror mode outside of the editor.
+    The <code>CodeMirror.runMode</code> function, defined
+    in <code><a href="../addon/runmode/runmode.js">lib/runmode.js</a></code> takes the following arguments:</p>
+
+    <dl>
+      <dt><code>text (string)</code></dt>
+      <dd>The document to run through the highlighter.</dd>
+      <dt><code>mode (<a href="../doc/manual.html#option_mode">mode spec</a>)</code></dt>
+      <dd>The mode to use (must be loaded as normal).</dd>
+      <dt><code>output (function or DOM node)</code></dt>
+      <dd>If this is a function, it will be called for each token with
+      two arguments, the token's text and the token's style class (may
+      be <code>null</code> for unstyled tokens). If it is a DOM node,
+      the tokens will be converted to <code>span</code> elements as in
+      an editor, and inserted into the node
+      (through <code>innerHTML</code>).</dd>
+    </dl>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/search.html b/app/gui/html/vendor/codemirror/demo/search.html
new file mode 100644
index 0000000..21c9b27
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/search.html
@@ -0,0 +1,87 @@
+<!doctype html>
+
+<title>CodeMirror: Search/Replace Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<link rel="stylesheet" href="../addon/dialog/dialog.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<script src="../addon/dialog/dialog.js"></script>
+<script src="../addon/search/searchcursor.js"></script>
+<script src="../addon/search/search.js"></script>
+<style type="text/css">
+      .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+      dt {font-family: monospace; color: #666;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Search/Replace</a>
+  </ul>
+</div>
+
+<article>
+<h2>Search/Replace Demo</h2>
+<form><textarea id="code" name="code">
+<dl>
+  <dt id="option_indentWithTabs"><code><strong>indentWithTabs</strong>: boolean</code></dt>
+  <dd>Whether, when indenting, the first N*<code>tabSize</code>
+  spaces should be replaced by N tabs. Default is false.</dd>
+
+  <dt id="option_electricChars"><code><strong>electricChars</strong>: boolean</code></dt>
+  <dd>Configures whether the editor should re-indent the current
+  line when a character is typed that might change its proper
+  indentation (only works if the mode supports indentation).
+  Default is true.</dd>
+
+  <dt id="option_specialChars"><code><strong>specialChars</strong>: RegExp</code></dt>
+  <dd>A regular expression used to determine which characters
+  should be replaced by a
+  special <a href="#option_specialCharPlaceholder">placeholder</a>.
+  Mostly useful for non-printing special characters. The default
+  is <code>/[\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/</code>.</dd>
+  <dt id="option_specialCharPlaceholder"><code><strong>specialCharPlaceholder</strong>: function(char) → Element</code></dt>
+  <dd>A function that, given a special character identified by
+  the <a href="#option_specialChars"><code>specialChars</code></a>
+  option, produces a DOM node that is used to represent the
+  character. By default, a red dot (<span style="color: red">•</span>)
+  is shown, with a title tooltip to indicate the character code.</dd>
+
+  <dt id="option_rtlMoveVisually"><code><strong>rtlMoveVisually</strong>: boolean</code></dt>
+  <dd>Determines whether horizontal cursor movement through
+  right-to-left (Arabic, Hebrew) text is visual (pressing the left
+  arrow moves the cursor left) or logical (pressing the left arrow
+  moves to the next lower index in the string, which is visually
+  right in right-to-left text). The default is <code>false</code>
+  on Windows, and <code>true</code> on other platforms.</dd>
+</dl>
+</textarea></form>
+
+    <script>
+var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: "text/html", lineNumbers: true});
+</script>
+
+    <p>Demonstration of primitive search/replace functionality. The
+    keybindings (which can be overridden by custom keymaps) are:</p>
+    <dl>
+      <dt>Ctrl-F / Cmd-F</dt><dd>Start searching</dd>
+      <dt>Ctrl-G / Cmd-G</dt><dd>Find next</dd>
+      <dt>Shift-Ctrl-G / Shift-Cmd-G</dt><dd>Find previous</dd>
+      <dt>Shift-Ctrl-F / Cmd-Option-F</dt><dd>Replace</dd>
+      <dt>Shift-Ctrl-R / Shift-Cmd-Option-F</dt><dd>Replace all</dd>
+    </dl>
+    <p>Searching is enabled by
+    including <a href="../addon/search/search.js">addon/search/search.js</a>
+    and <a href="../addon/search/searchcursor.js">addon/search/searchcursor.js</a>.
+    For good-looking input dialogs, you also want to include
+    <a href="../addon/dialog/dialog.js">addon/dialog/dialog.js</a>
+    and <a href="../addon/dialog/dialog.css">addon/dialog/dialog.css</a>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/spanaffectswrapping_shim.html b/app/gui/html/vendor/codemirror/demo/spanaffectswrapping_shim.html
new file mode 100644
index 0000000..e598221
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/spanaffectswrapping_shim.html
@@ -0,0 +1,85 @@
+<!doctype html>
+
+<title>CodeMirror: Automatically derive odd wrapping behavior for your browser</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Automatically derive odd wrapping behavior for your browser</a>
+  </ul>
+</div>
+
+<article>
+<h2>Automatically derive odd wrapping behavior for your browser</h2>
+
+
+    <p>This is a hack to automatically derive
+    a <code>spanAffectsWrapping</code> regexp for a browser. See the
+    comments above that variable
+    in <a href="../lib/codemirror.js"><code>lib/codemirror.js</code></a>
+    for some more details.</p>
+
+    <div style="white-space: pre-wrap; width: 50px;" id="area"></div>
+    <pre id="output"></pre>
+
+    <script id="script">
+      var a = document.getElementById("area"), bad = Object.create(null);
+      var chars = "a~`!@#$%^&*()-_=+}{[]\\|'\"/?.>,<:;", l = chars.length;
+      for (var x = 0; x < l; ++x) for (var y = 0; y < l; ++y) {
+        var s1 = "foooo" + chars.charAt(x), s2 = chars.charAt(y) + "br";
+        a.appendChild(document.createTextNode(s1 + s2));
+        var h1 = a.offsetHeight;
+        a.innerHTML = "";
+        a.appendChild(document.createElement("span")).appendChild(document.createTextNode(s1));
+        a.appendChild(document.createElement("span")).appendChild(document.createTextNode(s2));
+        if (a.offsetHeight != h1)
+          bad[chars.charAt(x)] = (bad[chars.charAt(x)] || "") + chars.charAt(y);
+        a.innerHTML = "";
+      }
+
+      var re = "";
+      function toREElt(str) {
+        if (str.length > 1) {
+          var invert = false;
+          if (str.length > chars.length * .6) {
+            invert = true;
+            var newStr = "";
+            for (var i = 0; i < l; ++i) if (str.indexOf(chars.charAt(i)) == -1) newStr += chars.charAt(i);
+            str = newStr;
+          }
+          str = str.replace(/[\-\.\]\"\'\\\/\^a]/g, function(orig) { return orig == "a" ? "\\w" : "\\" + orig; });
+          return "[" + (invert ? "^" : "") + str + "]";
+        } else if (str == "a") {
+          return "\\w";
+        } else if (/[?$*()+{}[\]\.|/\'\"]/.test(str)) {
+          return "\\" + str;
+        } else {
+          return str;
+        }
+      }
+
+      var newRE = "";
+      for (;;) {
+        var left = null;
+        for (var left in bad) break;
+        if (left == null) break;
+        var right = bad[left];
+        delete bad[left];
+        for (var other in bad) if (bad[other] == right) {
+          left += other;
+          delete bad[other];
+        }
+        newRE += (newRE ? "|" : "") + toREElt(left) + toREElt(right);
+      }
+
+      document.getElementById("output").appendChild(document.createTextNode("Your regexp is: " + (newRE || "^$")));
+    </script>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/sublime.html b/app/gui/html/vendor/codemirror/demo/sublime.html
new file mode 100644
index 0000000..f9115f5
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/sublime.html
@@ -0,0 +1,79 @@
+<!doctype html>
+
+<title>CodeMirror: Sublime Text bindings demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<link rel="stylesheet" href="../addon/fold/foldgutter.css">
+<link rel="stylesheet" href="../addon/dialog/dialog.css">
+<link rel="stylesheet" href="../theme/monokai.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/search/searchcursor.js"></script>
+<script src="../addon/search/search.js"></script>
+<script src="../addon/dialog/dialog.js"></script>
+<script src="../addon/edit/matchbrackets.js"></script>
+<script src="../addon/edit/closebrackets.js"></script>
+<script src="../addon/comment/comment.js"></script>
+<script src="../addon/wrap/hardwrap.js"></script>
+<script src="../addon/fold/foldcode.js"></script>
+<script src="../addon/fold/brace-fold.js"></script>
+<script src="../mode/javascript/javascript.js"></script>
+<script src="../keymap/sublime.js"></script>
+<style type="text/css">
+  .CodeMirror {border-top: 1px solid #eee; border-bottom: 1px solid #eee; line-height: 1.3; height: 500px}
+  .CodeMirror-linenumbers { padding: 0 8px; }
+</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Sublime bindings</a>
+  </ul>
+</div>
+
+<article>
+<h2>Sublime Text bindings demo</h2>
+
+<p>The <code>sublime</code> keymap defines many Sublime Text-specific
+bindings for CodeMirror. See the code below for an overview.</p>
+
+<p>Enable the keymap by
+loading <a href="../keymap/sublime.js"><code>keymap/sublime.js</code></a>
+and setting
+the <a href="../doc/manual.html#option_keyMap"><code>keyMap</code></a>
+option to <code>"sublime"</code>.</p>
+
+<p>(A lot of the search functionality is still missing.)
+
+<script>
+  var value = "// The bindings defined specifically in the Sublime Text mode\nvar bindings = {\n";
+  var map = CodeMirror.keyMap.sublime, mapK = CodeMirror.keyMap["sublime-Ctrl-K"];
+  for (var key in map) {
+    if (key != "Ctrl-K" && key != "fallthrough" && (!/find/.test(map[key]) || /findUnder/.test(map[key])))
+      value += "  \"" + key + "\": \"" + map[key] + "\",\n";
+  }
+  for (var key in mapK) {
+    if (key != "auto" && key != "nofallthrough")
+      value += "  \"Ctrl-K " + key + "\": \"" + mapK[key] + "\",\n";
+  }
+  value += "}\n\n// The implementation of joinLines\n";
+  value += CodeMirror.commands.joinLines.toString().replace(/^function\s*\(/, "function joinLines(").replace(/\n  /g, "\n") + "\n";
+  var editor = CodeMirror(document.body.getElementsByTagName("article")[0], {
+    value: value,
+    lineNumbers: true,
+    mode: "javascript",
+    keyMap: "sublime",
+    autoCloseBrackets: true,
+    matchBrackets: true,
+    showCursorWhenSelecting: true,
+    theme: "monokai"
+  });
+</script>
+
+</article>
diff --git a/app/gui/html/vendor/codemirror/demo/tern.html b/app/gui/html/vendor/codemirror/demo/tern.html
new file mode 100644
index 0000000..57027f7
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/tern.html
@@ -0,0 +1,131 @@
+<!doctype html>
+
+<title>CodeMirror: Tern Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<link rel="stylesheet" href="../addon/dialog/dialog.css">
+<link rel="stylesheet" href="../addon/hint/show-hint.css">
+<link rel="stylesheet" href="../addon/tern/tern.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/javascript/javascript.js"></script>
+<script src="../addon/dialog/dialog.js"></script>
+<script src="../addon/hint/show-hint.js"></script>
+<script src="../addon/tern/tern.js"></script>
+<script src="http://marijnhaverbeke.nl/acorn/acorn.js"></script>
+<script src="http://marijnhaverbeke.nl/acorn/acorn_loose.js"></script>
+<script src="http://marijnhaverbeke.nl/acorn/util/walk.js"></script>
+<script src="http://ternjs.net/doc/demo/polyfill.js"></script>
+<script src="http://ternjs.net/lib/signal.js"></script>
+<script src="http://ternjs.net/lib/tern.js"></script>
+<script src="http://ternjs.net/lib/def.js"></script>
+<script src="http://ternjs.net/lib/comment.js"></script>
+<script src="http://ternjs.net/lib/infer.js"></script>
+<script src="http://ternjs.net/plugin/doc_comment.js"></script>
+<style>
+      .CodeMirror {border: 1px solid #ddd;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Tern</a>
+  </ul>
+</div>
+
+<article>
+<h2>Tern Demo</h2>
+<form><textarea id="code" name="code">// Use ctrl-space to complete something
+// Put the cursor in or after an expression, press ctrl-i to
+// find its type
+
+var foo = ["array", "of", "strings"];
+var bar = foo.slice(0, 2).join("").split("a")[0];
+
+// Works for locally defined types too.
+
+function CTor() { this.size = 10; }
+CTor.prototype.hallo = "hallo";
+
+var baz = new CTor;
+baz.
+
+// You can press ctrl-q when the cursor is on a variable name to
+// rename it. Try it with CTor...
+
+// When the cursor is in an argument list, the arguments are
+// shown below the editor.
+
+[1].reduce(  );
+
+// And a little more advanced code...
+
+(function(exports) {
+  exports.randomElt = function(arr) {
+    return arr[Math.floor(arr.length * Math.random())];
+  };
+  exports.strList = "foo".split("");
+  exports.intList = exports.strList.map(function(s) { return s.charCodeAt(0); });
+})(window.myMod = {});
+
+var randomStr = myMod.randomElt(myMod.strList);
+var randomInt = myMod.randomElt(myMod.intList);
+</textarea></p>
+
+<p>Demonstrates integration of <a href="http://ternjs.net/">Tern</a>
+and CodeMirror. The following keys are bound:</p>
+
+<dl>
+  <dt>Ctrl-Space</dt><dd>Autocomplete</dd>
+  <dt>Ctrl-I</dt><dd>Find type at cursor</dd>
+  <dt>Alt-.</dt><dd>Jump to definition (Alt-, to jump back)</dd>
+  <dt>Ctrl-Q</dt><dd>Rename variable</dd>
+  <dt>Ctrl-.</dt><dd>Select all occurrences of a variable</dd>
+</dl>
+
+<p>Documentation is sparse for now. See the top of
+the <a href="../addon/tern/tern.js">script</a> for a rough API
+overview.</p>
+
+<script>
+  function getURL(url, c) {
+    var xhr = new XMLHttpRequest();
+    xhr.open("get", url, true);
+    xhr.send();
+    xhr.onreadystatechange = function() {
+      if (xhr.readyState != 4) return;
+      if (xhr.status < 400) return c(null, xhr.responseText);
+      var e = new Error(xhr.responseText || "No response");
+      e.status = xhr.status;
+      c(e);
+    };
+  }
+
+  var server;
+  getURL("http://ternjs.net/defs/ecma5.json", function(err, code) {
+    if (err) throw new Error("Request for ecma5.json: " + err);
+    server = new CodeMirror.TernServer({defs: [JSON.parse(code)]});
+    editor.setOption("extraKeys", {
+      "Ctrl-Space": function(cm) { server.complete(cm); },
+      "Ctrl-I": function(cm) { server.showType(cm); },
+      "Alt-.": function(cm) { server.jumpToDef(cm); },
+      "Alt-,": function(cm) { server.jumpBack(cm); },
+      "Ctrl-Q": function(cm) { server.rename(cm); },
+      "Ctrl-.": function(cm) { server.selectName(cm); }
+    })
+    editor.on("cursorActivity", function(cm) { server.updateArgHints(cm); });
+  });
+
+  var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+    lineNumbers: true,
+    mode: "javascript"
+  });
+</script>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/theme.html b/app/gui/html/vendor/codemirror/demo/theme.html
new file mode 100644
index 0000000..20e273c
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/theme.html
@@ -0,0 +1,124 @@
+<!doctype html>
+
+<title>CodeMirror: Theme Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<link rel="stylesheet" href="../theme/3024-day.css">
+<link rel="stylesheet" href="../theme/3024-night.css">
+<link rel="stylesheet" href="../theme/ambiance.css">
+<link rel="stylesheet" href="../theme/base16-dark.css">
+<link rel="stylesheet" href="../theme/base16-light.css">
+<link rel="stylesheet" href="../theme/blackboard.css">
+<link rel="stylesheet" href="../theme/cobalt.css">
+<link rel="stylesheet" href="../theme/eclipse.css">
+<link rel="stylesheet" href="../theme/elegant.css">
+<link rel="stylesheet" href="../theme/erlang-dark.css">
+<link rel="stylesheet" href="../theme/lesser-dark.css">
+<link rel="stylesheet" href="../theme/mbo.css">
+<link rel="stylesheet" href="../theme/mdn-like.css">
+<link rel="stylesheet" href="../theme/midnight.css">
+<link rel="stylesheet" href="../theme/monokai.css">
+<link rel="stylesheet" href="../theme/neat.css">
+<link rel="stylesheet" href="../theme/night.css">
+<link rel="stylesheet" href="../theme/paraiso-dark.css">
+<link rel="stylesheet" href="../theme/paraiso-light.css">
+<link rel="stylesheet" href="../theme/pastel-on-dark.css">
+<link rel="stylesheet" href="../theme/rubyblue.css">
+<link rel="stylesheet" href="../theme/solarized.css">
+<link rel="stylesheet" href="../theme/the-matrix.css">
+<link rel="stylesheet" href="../theme/tomorrow-night-eighties.css">
+<link rel="stylesheet" href="../theme/twilight.css">
+<link rel="stylesheet" href="../theme/vibrant-ink.css">
+<link rel="stylesheet" href="../theme/xq-dark.css">
+<link rel="stylesheet" href="../theme/xq-light.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/javascript/javascript.js"></script>
+<script src="../addon/selection/active-line.js"></script>
+<script src="../addon/edit/matchbrackets.js"></script>
+<style type="text/css">
+      .CodeMirror {border: 1px solid black; font-size:13px}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Theme</a>
+  </ul>
+</div>
+
+<article>
+<h2>Theme Demo</h2>
+<form><textarea id="code" name="code">
+function findSequence(goal) {
+  function find(start, history) {
+    if (start == goal)
+      return history;
+    else if (start > goal)
+      return null;
+    else
+      return find(start + 5, "(" + history + " + 5)") ||
+             find(start * 3, "(" + history + " * 3)");
+  }
+  return find(1, "1");
+}</textarea></form>
+
+<p>Select a theme: <select onchange="selectTheme()" id=select>
+    <option selected>default</option>
+    <option>3024-day</option>
+    <option>3024-night</option>
+    <option>ambiance</option>
+    <option>base16-dark</option>
+    <option>base16-light</option>
+    <option>blackboard</option>
+    <option>cobalt</option>
+    <option>eclipse</option>
+    <option>elegant</option>
+    <option>erlang-dark</option>
+    <option>lesser-dark</option>
+    <option>mbo</option>
+    <option>mdn-like</option>
+    <option>midnight</option>
+    <option>monokai</option>
+    <option>neat</option>
+    <option>night</option>
+    <option>paraiso-dark</option>
+    <option>paraiso-light</option>
+    <option>pastel-on-dark</option>
+    <option>rubyblue</option>
+    <option>solarized dark</option>
+    <option>solarized light</option>
+    <option>the-matrix</option>
+    <option>tomorrow-night-eighties</option>
+    <option>twilight</option>
+    <option>vibrant-ink</option>
+    <option>xq-dark</option>
+    <option>xq-light</option>
+</select>
+</p>
+
+<script>
+  var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+    lineNumbers: true,
+    styleActiveLine: true,
+    matchBrackets: true
+  });
+  var input = document.getElementById("select");
+  function selectTheme() {
+    var theme = input.options[input.selectedIndex].innerHTML;
+    editor.setOption("theme", theme);
+  }
+  var choice = document.location.search &&
+               decodeURIComponent(document.location.search.slice(1));
+  if (choice) {
+    input.value = choice;
+    editor.setOption("theme", choice);
+  }
+</script>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/trailingspace.html b/app/gui/html/vendor/codemirror/demo/trailingspace.html
new file mode 100644
index 0000000..c3e9c37
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/trailingspace.html
@@ -0,0 +1,48 @@
+<!doctype html>
+
+<title>CodeMirror: Trailing Whitespace Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/edit/trailingspace.js"></script>
+<style type="text/css">
+      .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+      .cm-trailingspace {
+        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAACCAYAAAB/qH1jAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QUXCToH00Y1UgAAACFJREFUCNdjPMDBUc/AwNDAAAFMTAwMDA0OP34wQgX/AQBYgwYEx4f9lQAAAABJRU5ErkJggg==);
+        background-position: bottom left;
+        background-repeat: repeat-x;
+      }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Trailing Whitespace</a>
+  </ul>
+</div>
+
+<article>
+<h2>Trailing Whitespace Demo</h2>
+<form><textarea id="code" name="code">This text  
+ has some	 
+trailing whitespace!</textarea></form>
+
+    <script>
+var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+  lineNumbers: true,
+  showTrailingSpace: true
+});
+</script>
+
+<p>Uses
+the <a href="../doc/manual.html#addon_trailingspace">trailingspace</a>
+addon to highlight trailing whitespace.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/variableheight.html b/app/gui/html/vendor/codemirror/demo/variableheight.html
new file mode 100644
index 0000000..98f2fd2
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/variableheight.html
@@ -0,0 +1,67 @@
+<!doctype html>
+
+<title>CodeMirror: Variable Height Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/markdown/markdown.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<style type="text/css">
+      .CodeMirror {border: 1px solid silver; border-width: 1px 2px; }
+      .cm-header { font-family: arial; }
+      .cm-header-1 { font-size: 150%; }
+      .cm-header-2 { font-size: 130%; }
+      .cm-header-3 { font-size: 120%; }
+      .cm-header-4 { font-size: 110%; }
+      .cm-header-5 { font-size: 100%; }
+      .cm-header-6 { font-size: 90%; }
+      .cm-strong { font-size: 140%; }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Variable Height</a>
+  </ul>
+</div>
+
+<article>
+<h2>Variable Height Demo</h2>
+<form><textarea id="code" name="code"># A First Level Header
+
+**Bold** text in a normal-size paragraph.
+
+And a very long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long, wrapped line with a piece of **big** text inside of it.
+
+## A Second Level Header
+
+Now is the time for all good men to come to
+the aid of their country. This is just a
+regular paragraph.
+
+The quick brown fox jumped over the lazy
+dog's back.
+
+### Header 3
+
+> This is a blockquote.
+> 
+> This is the second paragraph in the blockquote.
+>
+> ## This is an H2 in a blockquote       
+</textarea></form>
+    <script id="script">
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        lineWrapping: true,
+        mode: "markdown"
+      });
+    </script>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/vim.html b/app/gui/html/vendor/codemirror/demo/vim.html
new file mode 100644
index 0000000..379fac1
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/vim.html
@@ -0,0 +1,74 @@
+<!doctype html>
+
+<title>CodeMirror: Vim bindings demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<link rel="stylesheet" href="../addon/dialog/dialog.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/dialog/dialog.js"></script>
+<script src="../addon/search/searchcursor.js"></script>
+<script src="../mode/clike/clike.js"></script>
+<script src="../keymap/vim.js"></script>
+<style type="text/css">
+      .CodeMirror {border-top: 1px solid #eee; border-bottom: 1px solid #eee;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Vim bindings</a>
+  </ul>
+</div>
+
+<article>
+<h2>Vim bindings demo</h2>
+<form><textarea id="code" name="code">
+#include "syscalls.h"
+/* getchar:  simple buffered version */
+int getchar(void)
+{
+  static char buf[BUFSIZ];
+  static char *bufp = buf;
+  static int n = 0;
+  if (n == 0) {  /* buffer is empty */
+    n = read(0, buf, sizeof buf);
+    bufp = buf;
+  }
+  return (--n >= 0) ? (unsigned char) *bufp++ : EOF;
+}
+</textarea></form>
+
+    <form><textarea id="code2" name="code2">
+        I am another file! You can yank from my neighbor and paste here.
+</textarea></form>
+
+<p>The vim keybindings are enabled by
+including <a href="../keymap/vim.js">keymap/vim.js</a> and setting
+the <code>keyMap</code> option to <code>"vim"</code>. Because
+CodeMirror's internal API is quite different from Vim, they are only
+a loose approximation of actual vim bindings, though.</p>
+
+    <script>
+      CodeMirror.commands.save = function(){ alert("Saving"); };
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        mode: "text/x-csrc",
+        vimMode: true,
+        showCursorWhenSelecting: true
+      });
+      var editor2 = CodeMirror.fromTextArea(document.getElementById("code2"), {
+        lineNumbers: true,
+        mode: "text/x-csrc",
+        vimMode: true,
+        showCursorWhenSelecting: true
+      });
+    </script>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/visibletabs.html b/app/gui/html/vendor/codemirror/demo/visibletabs.html
new file mode 100644
index 0000000..5a5a19a
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/visibletabs.html
@@ -0,0 +1,62 @@
+<!doctype html>
+
+<title>CodeMirror: Visible tabs demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/clike/clike.js"></script>
+<style type="text/css">
+      .CodeMirror {border-top: 1px solid #eee; border-bottom: 1px solid #eee;}
+      .cm-tab {
+         background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);
+         background-position: right;
+         background-repeat: no-repeat;
+      }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Visible tabs</a>
+  </ul>
+</div>
+
+<article>
+<h2>Visible tabs demo</h2>
+<form><textarea id="code" name="code">
+#include "syscalls.h"
+/* getchar:  simple buffered version */
+int getchar(void)
+{
+	static char buf[BUFSIZ];
+	static char *bufp = buf;
+	static int n = 0;
+	if (n == 0) {  /* buffer is empty */
+		n = read(0, buf, sizeof buf);
+		bufp = buf;
+	}
+	return (--n >= 0) ? (unsigned char) *bufp++ : EOF;
+}
+</textarea></form>
+
+<p>Tabs inside the editor are spans with the
+class <code>cm-tab</code>, and can be styled.</p>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        tabSize: 4,
+        indentUnit: 4,
+        indentWithTabs: true,
+        mode: "text/x-csrc"
+      });
+    </script>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/widget.html b/app/gui/html/vendor/codemirror/demo/widget.html
new file mode 100644
index 0000000..6c46853
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/widget.html
@@ -0,0 +1,85 @@
+<!doctype html>
+
+<title>CodeMirror: Inline Widget Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../mode/javascript/javascript.js"></script>
+<script src="http://ajax.aspnetcdn.com/ajax/jshint/r07/jshint.js"></script>
+<style type="text/css">
+      .CodeMirror {border: 1px solid black;}
+      .lint-error {font-family: arial; font-size: 70%; background: #ffa; color: #a00; padding: 2px 5px 3px; }
+      .lint-error-icon {color: white; background-color: red; font-weight: bold; border-radius: 50%; padding: 0 3px; margin-right: 7px;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Inline Widget</a>
+  </ul>
+</div>
+
+<article>
+<h2>Inline Widget Demo</h2>
+
+
+    <div id=code></div>
+    <script id="script">var widgets = []
+function updateHints() {
+  editor.operation(function(){
+    for (var i = 0; i < widgets.length; ++i)
+      editor.removeLineWidget(widgets[i]);
+    widgets.length = 0;
+
+    JSHINT(editor.getValue());
+    for (var i = 0; i < JSHINT.errors.length; ++i) {
+      var err = JSHINT.errors[i];
+      if (!err) continue;
+      var msg = document.createElement("div");
+      var icon = msg.appendChild(document.createElement("span"));
+      icon.innerHTML = "!!";
+      icon.className = "lint-error-icon";
+      msg.appendChild(document.createTextNode(err.reason));
+      msg.className = "lint-error";
+      widgets.push(editor.addLineWidget(err.line - 1, msg, {coverGutter: false, noHScroll: true}));
+    }
+  });
+  var info = editor.getScrollInfo();
+  var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top;
+  if (info.top + info.clientHeight < after)
+    editor.scrollTo(null, after - info.clientHeight + 3);
+}
+
+window.onload = function() {
+  var sc = document.getElementById("script");
+  var content = sc.textContent || sc.innerText || sc.innerHTML;
+
+  window.editor = CodeMirror(document.getElementById("code"), {
+    lineNumbers: true,
+    mode: "javascript",
+    value: content
+  });
+
+  var waiting;
+  editor.on("change", function() {
+    clearTimeout(waiting);
+    waiting = setTimeout(updateHints, 500);
+  });
+
+  setTimeout(updateHints, 100);
+};
+
+"long line to create a horizontal scrollbar, in order to test whether the (non-inline) widgets stay in place when scrolling to the right";
+</script>
+<p>This demo runs <a href="http://jshint.com">JSHint</a> over the code
+in the editor (which is the script used on this page), and
+inserts <a href="../doc/manual.html#addLineWidget">line widgets</a> to
+display the warnings that JSHint comes up with.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/demo/xmlcomplete.html b/app/gui/html/vendor/codemirror/demo/xmlcomplete.html
new file mode 100644
index 0000000..2f81c54
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/demo/xmlcomplete.html
@@ -0,0 +1,116 @@
+<!doctype html>
+
+<title>CodeMirror: XML Autocomplete Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<link rel="stylesheet" href="../addon/hint/show-hint.css">
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/hint/show-hint.js"></script>
+<script src="../addon/hint/xml-hint.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<style type="text/css">
+      .CodeMirror { border: 1px solid #eee; }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">XML Autocomplete</a>
+  </ul>
+</div>
+
+<article>
+<h2>XML Autocomplete Demo</h2>
+<form><textarea id="code" name="code"><!-- write some xml below -->
+</textarea></form>
+
+    <p>Press <strong>ctrl-space</strong>, or type a '<' character to
+    activate autocompletion. This demo defines a simple schema that
+    guides completion. The schema can be customized—see
+    the <a href="../doc/manual.html#addon_xml-hint">manual</a>.</p>
+
+    <p>Development of the <code>xml-hint</code> addon was kindly
+    sponsored
+    by <a href="http://www.xperiment.mobi">www.xperiment.mobi</a>.</p>
+
+    <script>
+      var dummy = {
+        attrs: {
+          color: ["red", "green", "blue", "purple", "white", "black", "yellow"],
+          size: ["large", "medium", "small"],
+          description: null
+        },
+        children: []
+      };
+
+      var tags = {
+        "!top": ["top"],
+        top: {
+          attrs: {
+            lang: ["en", "de", "fr", "nl"],
+            freeform: null
+          },
+          children: ["animal", "plant"]
+        },
+        animal: {
+          attrs: {
+            name: null,
+            isduck: ["yes", "no"]
+          },
+          children: ["wings", "feet", "body", "head", "tail"]
+        },
+        plant: {
+          attrs: {name: null},
+          children: ["leaves", "stem", "flowers"]
+        },
+        wings: dummy, feet: dummy, body: dummy, head: dummy, tail: dummy,
+        leaves: dummy, stem: dummy, flowers: dummy
+      };
+
+      function completeAfter(cm, pred) {
+        var cur = cm.getCursor();
+        if (!pred || pred()) setTimeout(function() {
+          if (!cm.state.completionActive)
+            CodeMirror.showHint(cm, CodeMirror.hint.xml, {schemaInfo: tags, completeSingle: false});
+        }, 100);
+        return CodeMirror.Pass;
+      }
+
+      function completeIfAfterLt(cm) {
+        return completeAfter(cm, function() {
+          var cur = cm.getCursor();
+          return cm.getRange(CodeMirror.Pos(cur.line, cur.ch - 1), cur) == "<";
+        });
+      }
+
+      function completeIfInTag(cm) {
+        return completeAfter(cm, function() {
+          var tok = cm.getTokenAt(cm.getCursor());
+          if (tok.type == "string" && (!/['"]/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1)) return false;
+          var inner = CodeMirror.innerMode(cm.getMode(), tok.state).state;
+          return inner.tagName;
+        });
+      }
+
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: "xml",
+        lineNumbers: true,
+        extraKeys: {
+          "'<'": completeAfter,
+          "'/'": completeIfAfterLt,
+          "' '": completeIfInTag,
+          "'='": completeIfInTag,
+          "Ctrl-Space": function(cm) {
+            CodeMirror.showHint(cm, CodeMirror.hint.xml, {schemaInfo: tags});
+          }
+        }
+      });
+    </script>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/doc/activebookmark.js b/app/gui/html/vendor/codemirror/doc/activebookmark.js
new file mode 100644
index 0000000..407282d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/doc/activebookmark.js
@@ -0,0 +1,57 @@
+// Kludge in HTML5 tag recognition in IE8
+document.createElement("section");
+document.createElement("article");
+
+(function() {
+  if (!window.addEventListener) return;
+  var pending = false, prevVal = null;
+
+  function updateSoon() {
+    if (!pending) {
+      pending = true;
+      setTimeout(update, 250);
+    }
+  }
+
+  function update() {
+    pending = false;
+    var marks = document.getElementById("nav").getElementsByTagName("a"), found;
+    for (var i = 0; i < marks.length; ++i) {
+      var mark = marks[i], m;
+      if (mark.getAttribute("data-default")) {
+        if (found == null) found = i;
+      } else if (m = mark.href.match(/#(.*)/)) {
+        var ref = document.getElementById(m[1]);
+        if (ref && ref.getBoundingClientRect().top < 50)
+          found = i;
+      }
+    }
+    if (found != null && found != prevVal) {
+      prevVal = found;
+      var lis = document.getElementById("nav").getElementsByTagName("li");
+      for (var i = 0; i < lis.length; ++i) lis[i].className = "";
+      for (var i = 0; i < marks.length; ++i) {
+        if (found == i) {
+          marks[i].className = "active";
+          for (var n = marks[i]; n; n = n.parentNode)
+            if (n.nodeName == "LI") n.className = "active";
+        } else {
+          marks[i].className = "";
+        }
+      }
+    }
+  }
+
+  window.addEventListener("scroll", updateSoon);
+  window.addEventListener("load", updateSoon);
+  window.addEventListener("hashchange", function() {
+    setTimeout(function() {
+      var hash = document.location.hash, found = null, m;
+      var marks = document.getElementById("nav").getElementsByTagName("a");
+      for (var i = 0; i < marks.length; i++)
+        if ((m = marks[i].href.match(/(#.*)/)) && m[1] == hash) { found = i; break; }
+      if (found != null) for (var i = 0; i < marks.length; i++)
+        marks[i].className = i == found ? "active" : "";
+    }, 300);
+  });
+})();
diff --git a/app/gui/html/vendor/codemirror/doc/compress.html b/app/gui/html/vendor/codemirror/doc/compress.html
new file mode 100644
index 0000000..ebe8172
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/doc/compress.html
@@ -0,0 +1,240 @@
+<!doctype html>
+
+<title>CodeMirror: Compression Helper</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="docs.css">
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Compression helper</a>
+  </ul>
+</div>
+
+<article>
+
+<h2>Script compression helper</h2>
+
+    <p>To optimize loading CodeMirror, especially when including a
+    bunch of different modes, it is recommended that you combine and
+    minify (and preferably also gzip) the scripts. This page makes
+    those first two steps very easy. Simply select the version and
+    scripts you need in the form below, and
+    click <strong>Compress</strong> to download the minified script
+    file.</p>
+
+    <form id="form" action="http://marijnhaverbeke.nl/uglifyjs" method="post">
+      <input type="hidden" id="download" name="download" value="codemirror-compressed.js"/>
+      <p>Version: <select id="version" onchange="setVersion(this);" style="padding: 1px;">
+        <option value="http://codemirror.net/">HEAD</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.0.3;f=">4.0</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.22.0;f=">3.22</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.21.0;f=">3.21</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.20.0;f=">3.20</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.19.0;f=">3.19</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.18.0;f=">3.18</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.16.0;f=">3.16</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.15.0;f=">3.15</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.14.0;f=">3.14</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.13.0;f=">3.13</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.12;f=">3.12</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.11;f=">3.11</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.1;f=">3.1</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.02;f=">3.02</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.01;f=">3.01</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.0;f=">3.0</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.38;f=">2.38</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.37;f=">2.37</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.36;f=">2.36</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.35;f=">2.35</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.34;f=">2.34</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.33;f=">2.33</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.32;f=">2.32</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.31;f=">2.31</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.3;f=">2.3</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.25;f=">2.25</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.24;f=">2.24</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.23;f=">2.23</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.22;f=">2.22</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.21;f=">2.21</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.2;f=">2.2</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.18;f=">2.18</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.16;f=">2.16</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.15;f=">2.15</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.13;f=">2.13</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.12;f=">2.12</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.11;f=">2.11</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.1;f=">2.1</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.02;f=">2.02</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.01;f=">2.01</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.0;f=">2.0</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=beta2;f=">beta2</option>
+        <option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=beta1;f=">beta1</option>
+      </select></p>
+
+      <select multiple="multiple" size="20" name="code_url" style="width: 40em;" class="field" id="files">
+        <optgroup label="CodeMirror Library">
+          <option value="http://codemirror.net/lib/codemirror.js" selected>codemirror.js</option>
+        </optgroup>
+        <optgroup label="Modes">
+          <option value="http://codemirror.net/mode/apl/apl.js">apl.js</option>
+          <option value="http://codemirror.net/mode/clike/clike.js">clike.js</option>
+          <option value="http://codemirror.net/mode/clojure/clojure.js">clojure.js</option>
+          <option value="http://codemirror.net/mode/cobol/cobol.js">cobol.js</option>
+          <option value="http://codemirror.net/mode/coffeescript/coffeescript.js">coffeescript.js</option>
+          <option value="http://codemirror.net/mode/commonlisp/commonlisp.js">commonlisp.js</option>
+          <option value="http://codemirror.net/mode/css/css.js">css.js</option>
+          <option value="http://codemirror.net/mode/d/d.js">d.js</option>
+          <option value="http://codemirror.net/mode/diff/diff.js">diff.js</option>
+          <option value="http://codemirror.net/mode/dtd/dtd.js">dtd.js</option>
+          <option value="http://codemirror.net/mode/ecl/ecl.js">ecl.js</option>
+          <option value="http://codemirror.net/mode/eiffel/eiffel.js">eiffel.js</option>
+          <option value="http://codemirror.net/mode/erlang/erlang.js">erlang.js</option>
+          <option value="http://codemirror.net/mode/fortran/fortran.js">fortran.js</option>
+          <option value="http://codemirror.net/mode/gfm/gfm.js">gfm.js</option>
+          <option value="http://codemirror.net/mode/gas/gas.js">gas.js</option>
+          <option value="http://codemirror.net/mode/gherkin/gherkin.js">gherkin.js</option>
+          <option value="http://codemirror.net/mode/go/go.js">go.js</option>
+          <option value="http://codemirror.net/mode/groovy/groovy.js">groovy.js</option>
+          <option value="http://codemirror.net/mode/haml/haml.js">haml.js</option>
+          <option value="http://codemirror.net/mode/haskell/haskell.js">haskell.js</option>
+          <option value="http://codemirror.net/mode/haxe/haxe.js">haxe.js</option>
+          <option value="http://codemirror.net/mode/htmlembedded/htmlembedded.js">htmlembedded.js</option>
+          <option value="http://codemirror.net/mode/htmlmixed/htmlmixed.js">htmlmixed.js</option>
+          <option value="http://codemirror.net/mode/http/http.js">http.js</option>
+          <option value="http://codemirror.net/mode/jade/jade.js">jade.js</option>
+          <option value="http://codemirror.net/mode/javascript/javascript.js">javascript.js</option>
+          <option value="http://codemirror.net/mode/jinja2/jinja2.js">jinja2.js</option>
+          <option value="http://codemirror.net/mode/julia/julia.js">julia.js</option>
+          <option value="http://codemirror.net/mode/livescript/livescript.js">livescript.js</option>
+          <option value="http://codemirror.net/mode/lua/lua.js">lua.js</option>
+          <option value="http://codemirror.net/mode/markdown/markdown.js">markdown.js</option>
+          <option value="http://codemirror.net/mode/mirc/mirc.js">mirc.js</option>
+          <option value="http://codemirror.net/mode/mllike/mllike.js">mllike.js</option>
+          <option value="http://codemirror.net/mode/nginx/nginx.js">nginx.js</option>
+          <option value="http://codemirror.net/mode/ntriples/ntriples.js">ntriples.js</option>
+          <option value="http://codemirror.net/mode/octave/octave.js">octave.js</option>
+          <option value="http://codemirror.net/mode/pascal/pascal.js">pascal.js</option>
+          <option value="http://codemirror.net/mode/pegjs/pegjs.js">pegjs.js</option>
+          <option value="http://codemirror.net/mode/perl/perl.js">perl.js</option>
+          <option value="http://codemirror.net/mode/php/php.js">php.js</option>
+          <option value="http://codemirror.net/mode/pig/pig.js">pig.js</option>
+          <option value="http://codemirror.net/mode/properties/properties.js">properties.js</option>
+          <option value="http://codemirror.net/mode/python/python.js">python.js</option>
+          <option value="http://codemirror.net/mode/puppet/puppet.js">puppet.js</option>
+          <option value="http://codemirror.net/mode/q/q.js">q.js</option>
+          <option value="http://codemirror.net/mode/r/r.js">r.js</option>
+          <option value="http://codemirror.net/mode/rpm/rpm.js">rpm.js</option>
+          <option value="http://codemirror.net/mode/rst/rst.js">rst.js</option>
+          <option value="http://codemirror.net/mode/ruby/ruby.js">ruby.js</option>
+          <option value="http://codemirror.net/mode/rust/rust.js">rust.js</option>
+          <option value="http://codemirror.net/mode/sass/sass.js">sass.js</option>
+          <option value="http://codemirror.net/mode/scala/scala.js">scala.js</option>
+          <option value="http://codemirror.net/mode/scheme/scheme.js">scheme.js</option>
+          <option value="http://codemirror.net/mode/shell/shell.js">shell.js</option>
+          <option value="http://codemirror.net/mode/sieve/sieve.js">sieve.js</option>
+          <option value="http://codemirror.net/mode/smalltalk/smalltalk.js">smalltalk.js</option>
+          <option value="http://codemirror.net/mode/smarty/smarty.js">smarty.js</option>
+          <option value="http://codemirror.net/mode/smartymixed/smartymixed.js">smartymixed.js</option>
+          <option value="http://codemirror.net/mode/sql/sql.js">sql.js</option>
+          <option value="http://codemirror.net/mode/sparql/sparql.js">sparql.js</option>
+          <option value="http://codemirror.net/mode/stex/stex.js">stex.js</option>
+          <option value="http://codemirror.net/mode/tcl/tcl.js">tcl.js</option>
+          <option value="http://codemirror.net/mode/tiddlywiki/tiddlywiki.js">tiddlywiki.js</option>
+          <option value="http://codemirror.net/mode/tiki/tiki.js">tiki.js</option>
+          <option value="http://codemirror.net/mode/toml/toml.js">toml.js</option>
+          <option value="http://codemirror.net/mode/turtle/turtle.js">turtle.js</option>
+          <option value="http://codemirror.net/mode/vb/vb.js">vb.js</option>
+          <option value="http://codemirror.net/mode/vbscript/vbscript.js">vbscript.js</option>
+          <option value="http://codemirror.net/mode/velocity/velocity.js">velocity.js</option>
+          <option value="http://codemirror.net/mode/verilog/verilog.js">verilog.js</option>
+          <option value="http://codemirror.net/mode/xml/xml.js">xml.js</option>
+          <option value="http://codemirror.net/mode/xquery/xquery.js">xquery.js</option>
+          <option value="http://codemirror.net/mode/yaml/yaml.js">yaml.js</option>
+          <option value="http://codemirror.net/mode/z80/z80.js">z80.js</option>
+        </optgroup>
+        <optgroup label="Add-ons">
+          <option value="http://codemirror.net/addon/selection/active-line.js">active-line.js</option>
+          <option value="http://codemirror.net/addon/hint/anyword-hint.js">anyword-hint.js</option>
+          <option value="http://codemirror.net/addon/fold/brace-fold.js">brace-fold.js</option>
+          <option value="http://codemirror.net/addon/edit/closebrackets.js">closebrackets.js</option>
+          <option value="http://codemirror.net/addon/edit/closetag.js">closetag.js</option>
+          <option value="http://codemirror.net/addon/runmode/colorize.js">colorize.js</option>
+          <option value="http://codemirror.net/addon/comment/comment.js">comment.js</option>
+          <option value="http://codemirror.net/addon/fold/comment-fold.js">comment-fold.js</option>
+          <option value="http://codemirror.net/addon/comment/continuecomment.js">continuecomment.js</option>
+          <option value="http://codemirror.net/addon/edit/continuelist.js">continuelist.js</option>
+          <option value="http://codemirror.net/addon/hint/css-hint.js">css-hint.js</option>
+          <option value="http://codemirror.net/addon/dialog/dialog.js">dialog.js</option>
+          <option value="http://codemirror.net/addon/fold/foldcode.js">foldcode.js</option>
+          <option value="http://codemirror.net/addon/fold/foldgutter.js">foldgutter.js</option>
+          <option value="http://codemirror.net/addon/display/fullscreen.js">fullscreen.js</option>
+          <option value="http://codemirror.net/addon/wrap/hardwrap.js">hardwrap.js</option>
+          <option value="http://codemirror.net/addon/hint/html-hint.js">html-hint.js</option>
+          <option value="http://codemirror.net/addon/fold/indent-fold.js">indent-fold.js</option>
+          <option value="http://codemirror.net/addon/hint/javascript-hint.js">javascript-hint.js</option>
+          <option value="http://codemirror.net/addon/lint/javascript-lint.js">javascript-lint.js</option>
+          <option value="http://codemirror.net/addon/lint/json-lint.js">json-lint.js</option>
+          <option value="http://codemirror.net/addon/lint/lint.js">lint.js</option>
+          <option value="http://codemirror.net/addon/mode/loadmode.js">loadmode.js</option>
+          <option value="http://codemirror.net/addon/fold/markdown-fold.js">markdown-fold.js</option>
+          <option value="http://codemirror.net/addon/selection/mark-selection.js">mark-selection.js</option>
+          <option value="http://codemirror.net/addon/search/match-highlighter.js">match-highlighter.js</option>
+          <option value="http://codemirror.net/addon/edit/matchbrackets.js">matchbrackets.js</option>
+          <option value="http://codemirror.net/addon/edit/matchtags.js">matchtags.js</option>
+          <option value="http://codemirror.net/addon/merge/merge.js">merge.js</option>
+          <option value="http://codemirror.net/addon/mode/multiplex.js">multiplex.js</option>
+          <option value="http://codemirror.net/addon/mode/overlay.js">overlay.js</option>
+          <option value="http://codemirror.net/addon/display/placeholder.js">placeholder.js</option>
+          <option value="http://codemirror.net/addon/hint/python-hint.js">python-hint.js</option>
+          <option value="http://codemirror.net/addon/display/rulers.js">rulers.js</option>
+          <option value="http://codemirror.net/addon/runmode/runmode.js">runmode.js</option>
+          <option value="http://codemirror.net/addon/runmode/runmode.node.js">runmode.node.js</option>
+          <option value="http://codemirror.net/addon/runmode/runmode-standalone.js">runmode-standalone.js</option>
+          <option value="http://codemirror.net/addon/search/search.js">search.js</option>
+          <option value="http://codemirror.net/addon/search/searchcursor.js">searchcursor.js</option>
+          <option value="http://codemirror.net/addon/hint/show-hint.js">show-hint.js</option>
+          <option value="http://codemirror.net/addon/hint/sql-hint.js">sql-hint.js</option>
+          <option value="http://codemirror.net/addon/edit/trailingspace.js">trailingspace.js</option>
+          <option value="http://codemirror.net/addon/tern/tern.js">tern.js</option>
+          <option value="http://codemirror.net/addon/fold/xml-fold.js">xml-fold.js</option>
+          <option value="http://codemirror.net/addon/hint/xml-hint.js">xml-hint.js</option>
+          <option value="http://codemirror.net/addon/hint/yaml-lint.js">yaml-lint.js</option>
+        </optgroup>
+        <optgroup label="Keymaps">
+          <option value="http://codemirror.net/keymap/emacs.js">emacs.js</option>
+          <option value="http://codemirror.net/keymap/sublime.js">sublime.js</option>
+          <option value="http://codemirror.net/keymap/vim.js">vim.js</option>
+        </optgroup>
+      </select>
+
+      <p>
+        <button type="submit">Compress</button> with <a href="http://github.com/mishoo/UglifyJS/">UglifyJS</a>
+      </p>
+
+      <p>Custom code to add to the compressed file:<textarea name="js_code" style="width: 100%; height: 15em;" class="field"></textarea></p>
+    </form>
+
+    <script type="text/javascript">
+      function setVersion(ver) {
+        var urlprefix = ver.options[ver.selectedIndex].value;
+        var select = document.getElementById("files"), m;
+        for (var optgr = select.firstChild; optgr; optgr = optgr.nextSibling)
+          for (var opt = optgr.firstChild; opt; opt = opt.nextSibling) {
+            if (opt.nodeName != "OPTION")
+              continue;
+            else if (m = opt.value.match(/^http:\/\/codemirror.net\/(.*)$/))
+              opt.value = urlprefix + m[1];
+            else if (m = opt.value.match(/http:\/\/marijnhaverbeke.nl\/git\/codemirror\?a=blob_plain;hb=[^;]+;f=(.*)$/))
+              opt.value = urlprefix + m[1];
+          }
+       }
+    </script>
+
+</article>
diff --git a/app/gui/html/vendor/codemirror/doc/docs.css b/app/gui/html/vendor/codemirror/doc/docs.css
new file mode 100644
index 0000000..01ece71
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/doc/docs.css
@@ -0,0 +1,232 @@
+ at font-face {
+  font-family: 'Source Sans Pro';
+  font-style: normal;
+  font-weight: 400;
+  src: local('Source Sans Pro'), local('SourceSansPro-Regular'), url(http://themes.googleusercontent.com/static/fonts/sourcesanspro/v5/ODelI1aHBYDBqgeIAH2zlBM0YzuT7MdOe03otPbuUS0.woff) format('woff');
+}
+
+body, html { margin: 0; padding: 0; height: 100%; }
+section, article { display: block; padding: 0; }
+
+body {
+  background: #f8f8f8;
+  font-family: 'Source Sans Pro', Helvetica, Arial, sans-serif;
+  line-height: 1.5;
+}
+
+p { margin-top: 0; }
+
+h2, h3 {
+  font-weight: normal;
+  margin-bottom: .7em;
+}
+h2 { font-size: 120%; }
+h3 { font-size: 110%; }
+article > h2:first-child, section:first-child > h2 { margin-top: 0; }
+
+a, a:visited, a:link, .quasilink {
+  color: #A21313;
+  text-decoration: none;
+}
+
+em {
+  padding-right: 2px;
+}
+
+.quasilink {
+  cursor: pointer;
+}
+
+article {
+  max-width: 700px;
+  margin: 0 0 0 160px;
+  border-left: 2px solid #E30808;
+  border-right: 1px solid #ddd;
+  padding: 30px 50px 100px 50px;
+  background: white;
+  z-index: 2;
+  position: relative;
+  min-height: 100%;
+  box-sizing: border-box;
+  -moz-box-sizing: border-box;
+}
+
+#nav {
+  position: fixed;
+  padding-top: 30px;
+  max-height: 100%;
+  box-sizing: -moz-border-box;
+  box-sizing: border-box;
+  overflow-y: auto;
+  left: 0; right: none;
+  width: 160px;
+  text-align: right;
+  z-index: 1;
+}
+
+ at media screen and (min-width: 1000px) {
+  article {
+    margin: 0 auto;
+  }
+  #nav {
+    right: 50%;
+    width: auto;
+    border-right: 349px solid transparent;
+  }
+}
+
+#nav ul {
+  display: block;
+  margin: 0; padding: 0;
+  margin-bottom: 32px;
+}
+
+#nav li {
+  display: block;
+  margin-bottom: 4px;
+}
+
+#nav li ul {
+  font-size: 80%;
+  margin-bottom: 0;
+  display: none;
+}
+
+#nav li.active ul {
+  display: block;
+}
+
+#nav li li a {
+  padding-right: 20px;
+  display: inline-block;
+}
+
+#nav ul a {
+  color: black;
+  padding: 0 7px 1px 11px;
+}
+
+#nav ul a.active, #nav ul a:hover {
+  border-bottom: 1px solid #E30808;
+  margin-bottom: -1px;
+  color: #E30808;
+}
+
+#logo {
+  border: 0;
+  margin-right: 7px;
+  margin-bottom: 25px;
+}
+
+section {
+  border-top: 1px solid #E30808;
+  margin: 1.5em 0;
+}
+
+section.first {
+  border: none;
+  margin-top: 0;
+}
+
+#demo {
+  position: relative;
+}
+
+#demolist {
+  position: absolute;
+  right: 5px;
+  top: 5px;
+  z-index: 25;
+}
+
+#bankinfo {
+  text-align: left;
+  display: none;
+  padding: 0 .5em;
+  position: absolute;
+  border: 2px solid #aaa;
+  border-radius: 5px;
+  background: #eee;
+  top: 10px;
+  left: 30px;
+}
+
+#bankinfo_close {
+  position: absolute;
+  top: 0; right: 6px;
+  font-weight: bold;
+  cursor: pointer;
+}
+
+.bigbutton {
+  cursor: pointer;
+  text-align: center;
+  padding: 0 1em;
+  display: inline-block;
+  color: white;
+  position: relative;
+  line-height: 1.9;
+  color: white !important;
+  background: #A21313;
+}
+
+.bigbutton.right {
+  border-bottom-left-radius: 100px;
+  border-top-left-radius: 100px;
+}
+
+.bigbutton.left {
+  border-bottom-right-radius: 100px;
+  border-top-right-radius: 100px;
+}
+
+.bigbutton:hover {
+  background: #E30808;
+}
+
+th {
+  text-decoration: underline;
+  font-weight: normal;
+  text-align: left;
+}
+
+#features ul {
+  list-style: none;
+  margin: 0 0 1em;
+  padding: 0 0 0 1.2em;
+}
+
+#features li:before {
+  content: "-";
+  width: 1em;
+  display: inline-block;
+  padding: 0;
+  margin: 0;
+  margin-left: -1em;
+}
+
+.rel {
+  margin-bottom: 0;
+}
+.rel-note {
+  margin-top: 0;
+  color: #555;
+}
+
+pre {
+  padding-left: 15px;
+  border-left: 2px solid #ddd;
+}
+
+code {
+  padding: 0 2px;
+}
+
+strong {
+  text-decoration: underline;
+  font-weight: normal;
+}
+
+.field {
+  border: 1px solid #A21313;
+}
diff --git a/app/gui/html/vendor/codemirror/doc/internals.html b/app/gui/html/vendor/codemirror/doc/internals.html
new file mode 100644
index 0000000..3f1b7de
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/doc/internals.html
@@ -0,0 +1,503 @@
+<!doctype html>
+
+<title>CodeMirror: Internals</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="docs.css">
+<style>dl dl {margin: 0;} .update {color: #d40 !important}</style>
+<script src="activebookmark.js"></script>
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="#top">Introduction</a></li>
+    <li><a href="#approach">General Approach</a></li>
+    <li><a href="#input">Input</a></li>
+    <li><a href="#selection">Selection</a></li>
+    <li><a href="#update">Intelligent Updating</a></li>
+    <li><a href="#parse">Parsing</a></li>
+    <li><a href="#summary">What Gives?</a></li>
+    <li><a href="#btree">Content Representation</a></li>
+    <li><a href="#keymap">Key Maps</a></li>
+  </ul>
+</div>
+
+<article>
+
+<h2 id=top>(Re-) Implementing A Syntax-Highlighting Editor in JavaScript</h2>
+
+<p style="font-size: 85%" id="intro">
+  <strong>Topic:</strong> JavaScript, code editor implementation<br>
+  <strong>Author:</strong> Marijn Haverbeke<br>
+  <strong>Date:</strong> March 2nd 2011 (updated November 13th 2011)
+</p>
+
+<p style="padding: 0 3em 0 2em"><strong>Caution</strong>: this text was written briefly after
+version 2 was initially written. It no longer (even including the
+update at the bottom) fully represents the current implementation. I'm
+leaving it here as a historic document. For more up-to-date
+information, look at the entries
+tagged <a href="http://marijnhaverbeke.nl/blog/#cm-internals">cm-internals</a>
+on my blog.</p>
+
+<p>This is a followup to
+my <a href="http://codemirror.net/story.html">Brutal Odyssey to the
+Dark Side of the DOM Tree</a> story. That one describes the
+mind-bending process of implementing (what would become) CodeMirror 1.
+This one describes the internals of CodeMirror 2, a complete rewrite
+and rethink of the old code base. I wanted to give this piece another
+Hunter Thompson copycat subtitle, but somehow that would be out of
+place—the process this time around was one of straightforward
+engineering, requiring no serious mind-bending whatsoever.</p>
+
+<p>So, what is wrong with CodeMirror 1? I'd estimate, by mailing list
+activity and general search-engine presence, that it has been
+integrated into about a thousand systems by now. The most prominent
+one, since a few weeks,
+being <a href="http://googlecode.blogspot.com/2011/01/make-quick-fixes-quicker-on-google.html">Google
+code's project hosting</a>. It works, and it's being used widely.</p>
+
+<p>Still, I did not start replacing it because I was bored. CodeMirror
+1 was heavily reliant on <code>designMode</code>
+or <code>contentEditable</code> (depending on the browser). Neither of
+these are well specified (HTML5 tries
+to <a href="http://www.w3.org/TR/html5/editing.html#contenteditable">specify</a>
+their basics), and, more importantly, they tend to be one of the more
+obscure and buggy areas of browser functionality—CodeMirror, by using
+this functionality in a non-typical way, was constantly running up
+against browser bugs. WebKit wouldn't show an empty line at the end of
+the document, and in some releases would suddenly get unbearably slow.
+Firefox would show the cursor in the wrong place. Internet Explorer
+would insist on linkifying everything that looked like a URL or email
+address, a behaviour that can't be turned off. Some bugs I managed to
+work around (which was often a frustrating, painful process), others,
+such as the Firefox cursor placement, I gave up on, and had to tell
+user after user that they were known problems, but not something I
+could help.</p>
+
+<p>Also, there is the fact that <code>designMode</code> (which seemed
+to be less buggy than <code>contentEditable</code> in Webkit and
+Firefox, and was thus used by CodeMirror 1 in those browsers) requires
+a frame. Frames are another tricky area. It takes some effort to
+prevent getting tripped up by domain restrictions, they don't
+initialize synchronously, behave strangely in response to the back
+button, and, on several browsers, can't be moved around the DOM
+without having them re-initialize. They did provide a very nice way to
+namespace the library, though—CodeMirror 1 could freely pollute the
+namespace inside the frame.</p>
+
+<p>Finally, working with an editable document means working with
+selection in arbitrary DOM structures. Internet Explorer (8 and
+before) has an utterly different (and awkward) selection API than all
+of the other browsers, and even among the different implementations of
+<code>document.selection</code>, details about how exactly a selection
+is represented vary quite a bit. Add to that the fact that Opera's
+selection support tended to be very buggy until recently, and you can
+imagine why CodeMirror 1 contains 700 lines of selection-handling
+code.</p>
+
+<p>And that brings us to the main issue with the CodeMirror 1
+code base: The proportion of browser-bug-workarounds to real
+application code was getting dangerously high. By building on top of a
+few dodgy features, I put the system in a vulnerable position—any
+incompatibility and bugginess in these features, I had to paper over
+with my own code. Not only did I have to do some serious stunt-work to
+get it to work on older browsers (as detailed in the
+previous <a href="http://codemirror.net/story.html">story</a>), things
+also kept breaking in newly released versions, requiring me to come up
+with <em>new</em> scary hacks in order to keep up. This was starting
+to lose its appeal.</p>
+
+<section id=approach>
+  <h2>General Approach</h2>
+
+<p>What CodeMirror 2 does is try to sidestep most of the hairy hacks
+that came up in version 1. I owe a lot to the
+<a href="http://ace.ajax.org">ACE</a> editor for inspiration on how to
+approach this.</p>
+
+<p>I absolutely did not want to be completely reliant on key events to
+generate my input. Every JavaScript programmer knows that key event
+information is horrible and incomplete. Some people (most awesomely
+Mihai Bazon with <a href="http://ymacs.org">Ymacs</a>) have been able
+to build more or less functioning editors by directly reading key
+events, but it takes a lot of work (the kind of never-ending, fragile
+work I described earlier), and will never be able to properly support
+things like multi-keystoke international character
+input. <a href="#keymap" class="update">[see below for caveat]</a></p>
+
+<p>So what I do is focus a hidden textarea, and let the browser
+believe that the user is typing into that. What we show to the user is
+a DOM structure we built to represent his document. If this is updated
+quickly enough, and shows some kind of believable cursor, it feels
+like a real text-input control.</p>
+
+<p>Another big win is that this DOM representation does not have to
+span the whole document. Some CodeMirror 1 users insisted that they
+needed to put a 30 thousand line XML document into CodeMirror. Putting
+all that into the DOM takes a while, especially since, for some
+reason, an editable DOM tree is slower than a normal one on most
+browsers. If we have full control over what we show, we must only
+ensure that the visible part of the document has been added, and can
+do the rest only when needed. (Fortunately, the <code>onscroll</code>
+event works almost the same on all browsers, and lends itself well to
+displaying things only as they are scrolled into view.)</p>
+</section>
+<section id="input">
+  <h2>Input</h2>
+
+<p>ACE uses its hidden textarea only as a text input shim, and does
+all cursor movement and things like text deletion itself by directly
+handling key events. CodeMirror's way is to let the browser do its
+thing as much as possible, and not, for example, define its own set of
+key bindings. One way to do this would have been to have the whole
+document inside the hidden textarea, and after each key event update
+the display DOM to reflect what's in that textarea.</p>
+
+<p>That'd be simple, but it is not realistic. For even medium-sized
+document the editor would be constantly munging huge strings, and get
+terribly slow. What CodeMirror 2 does is put the current selection,
+along with an extra line on the top and on the bottom, into the
+textarea.</p>
+
+<p>This means that the arrow keys (and their ctrl-variations), home,
+end, etcetera, do not have to be handled specially. We just read the
+cursor position in the textarea, and update our cursor to match it.
+Also, copy and paste work pretty much for free, and people get their
+native key bindings, without any special work on my part. For example,
+I have emacs key bindings configured for Chrome and Firefox. There is
+no way for a script to detect this. <a class="update"
+href="#keymap">[no longer the case]</a></p>
+
+<p>Of course, since only a small part of the document sits in the
+textarea, keys like page up and ctrl-end won't do the right thing.
+CodeMirror is catching those events and handling them itself.</p>
+</section>
+<section id="selection">
+  <h2>Selection</h2>
+
+<p>Getting and setting the selection range of a textarea in modern
+browsers is trivial—you just use the <code>selectionStart</code>
+and <code>selectionEnd</code> properties. On IE you have to do some
+insane stuff with temporary ranges and compensating for the fact that
+moving the selection by a 'character' will treat \r\n as a single
+character, but even there it is possible to build functions that
+reliably set and get the selection range.</p>
+
+<p>But consider this typical case: When I'm somewhere in my document,
+press shift, and press the up arrow, something gets selected. Then, if
+I, still holding shift, press the up arrow again, the top of my
+selection is adjusted. The selection remembers where its <em>head</em>
+and its <em>anchor</em> are, and moves the head when we shift-move.
+This is a generally accepted property of selections, and done right by
+every editing component built in the past twenty years.</p>
+
+<p>But not something that the browser selection APIs expose.</p>
+
+<p>Great. So when someone creates an 'upside-down' selection, the next
+time CodeMirror has to update the textarea, it'll re-create the
+selection as an 'upside-up' selection, with the anchor at the top, and
+the next cursor motion will behave in an unexpected way—our second
+up-arrow press in the example above will not do anything, since it is
+interpreted in exactly the same way as the first.</p>
+
+<p>No problem. We'll just, ehm, detect that the selection is
+upside-down (you can tell by the way it was created), and then, when
+an upside-down selection is present, and a cursor-moving key is
+pressed in combination with shift, we quickly collapse the selection
+in the textarea to its start, allow the key to take effect, and then
+combine its new head with its old anchor to get the <em>real</em>
+selection.</p>
+
+<p>In short, scary hacks could not be avoided entirely in CodeMirror
+2.</p>
+
+<p>And, the observant reader might ask, how do you even know that a
+key combo is a cursor-moving combo, if you claim you support any
+native key bindings? Well, we don't, but we can learn. The editor
+keeps a set known cursor-movement combos (initialized to the
+predictable defaults), and updates this set when it observes that
+pressing a certain key had (only) the effect of moving the cursor.
+This, of course, doesn't work if the first time the key is used was
+for extending an inverted selection, but it works most of the
+time.</p>
+</section>
+<section id="update">
+  <h2>Intelligent Updating</h2>
+
+<p>One thing that always comes up when you have a complicated internal
+state that's reflected in some user-visible external representation
+(in this case, the displayed code and the textarea's content) is
+keeping the two in sync. The naive way is to just update the display
+every time you change your state, but this is not only error prone
+(you'll forget), it also easily leads to duplicate work on big,
+composite operations. Then you start passing around flags indicating
+whether the display should be updated in an attempt to be efficient
+again and, well, at that point you might as well give up completely.</p>
+
+<p>I did go down that road, but then switched to a much simpler model:
+simply keep track of all the things that have been changed during an
+action, and then, only at the end, use this information to update the
+user-visible display.</p>
+
+<p>CodeMirror uses a concept of <em>operations</em>, which start by
+calling a specific set-up function that clears the state and end by
+calling another function that reads this state and does the required
+updating. Most event handlers, and all the user-visible methods that
+change state are wrapped like this. There's a method
+called <code>operation</code> that accepts a function, and returns
+another function that wraps the given function as an operation.</p>
+
+<p>It's trivial to extend this (as CodeMirror does) to detect nesting,
+and, when an operation is started inside an operation, simply
+increment the nesting count, and only do the updating when this count
+reaches zero again.</p>
+
+<p>If we have a set of changed ranges and know the currently shown
+range, we can (with some awkward code to deal with the fact that
+changes can add and remove lines, so we're dealing with a changing
+coordinate system) construct a map of the ranges that were left
+intact. We can then compare this map with the part of the document
+that's currently visible (based on scroll offset and editor height) to
+determine whether something needs to be updated.</p>
+
+<p>CodeMirror uses two update algorithms—a full refresh, where it just
+discards the whole part of the DOM that contains the edited text and
+rebuilds it, and a patch algorithm, where it uses the information
+about changed and intact ranges to update only the out-of-date parts
+of the DOM. When more than 30 percent (which is the current heuristic,
+might change) of the lines need to be updated, the full refresh is
+chosen (since it's faster to do than painstakingly finding and
+updating all the changed lines), in the other case it does the
+patching (so that, if you scroll a line or select another character,
+the whole screen doesn't have to be
+re-rendered). <span class="update">[the full-refresh
+algorithm was dropped, it wasn't really faster than the patching
+one]</span></p>
+
+<p>All updating uses <code>innerHTML</code> rather than direct DOM
+manipulation, since that still seems to be by far the fastest way to
+build documents. There's a per-line function that combines the
+highlighting, <a href="manual.html#markText">marking</a>, and
+selection info for that line into a snippet of HTML. The patch updater
+uses this to reset individual lines, the refresh updater builds an
+HTML chunk for the whole visible document at once, and then uses a
+single <code>innerHTML</code> update to do the refresh.</p>
+</section>
+<section id="parse">
+  <h2>Parsers can be Simple</h2>
+
+<p>When I wrote CodeMirror 1, I
+thought <a href="http://codemirror.net/story.html#parser">interruptable
+parsers</a> were a hugely scary and complicated thing, and I used a
+bunch of heavyweight abstractions to keep this supposed complexity
+under control: parsers
+were <a href="http://bob.pythonmac.org/archives/2005/07/06/iteration-in-javascript/">iterators</a>
+that consumed input from another iterator, and used funny
+closure-resetting tricks to copy and resume themselves.</p>
+
+<p>This made for a rather nice system, in that parsers formed strictly
+separate modules, and could be composed in predictable ways.
+Unfortunately, it was quite slow (stacking three or four iterators on
+top of each other), and extremely intimidating to people not used to a
+functional programming style.</p>
+
+<p>With a few small changes, however, we can keep all those
+advantages, but simplify the API and make the whole thing less
+indirect and inefficient. CodeMirror
+2's <a href="manual.html#modeapi">mode API</a> uses explicit state
+objects, and makes the parser/tokenizer a function that simply takes a
+state and a character stream abstraction, advances the stream one
+token, and returns the way the token should be styled. This state may
+be copied, optionally in a mode-defined way, in order to be able to
+continue a parse at a given point. Even someone who's never touched a
+lambda in his life can understand this approach. Additionally, far
+fewer objects are allocated in the course of parsing now.</p>
+
+<p>The biggest speedup comes from the fact that the parsing no longer
+has to touch the DOM though. In CodeMirror 1, on an older browser, you
+could <em>see</em> the parser work its way through the document,
+managing some twenty lines in each 50-millisecond time slice it got. It
+was reading its input from the DOM, and updating the DOM as it went
+along, which any experienced JavaScript programmer will immediately
+spot as a recipe for slowness. In CodeMirror 2, the parser usually
+finishes the whole document in a single 100-millisecond time slice—it
+manages some 1500 lines during that time on Chrome. All it has to do
+is munge strings, so there is no real reason for it to be slow
+anymore.</p>
+</section>
+<section id="summary">
+  <h2>What Gives?</h2>
+
+<p>Given all this, what can you expect from CodeMirror 2?</p>
+
+<ul>
+
+<li><strong>Small.</strong> the base library is
+some <span class="update">45k</span> when minified
+now, <span class="update">17k</span> when gzipped. It's smaller than
+its own logo.</li>
+
+<li><strong>Lightweight.</strong> CodeMirror 2 initializes very
+quickly, and does almost no work when it is not focused. This means
+you can treat it almost like a textarea, have multiple instances on a
+page without trouble.</li>
+
+<li><strong>Huge document support.</strong> Since highlighting is
+really fast, and no DOM structure is being built for non-visible
+content, you don't have to worry about locking up your browser when a
+user enters a megabyte-sized document.</li>
+
+<li><strong>Extended API.</strong> Some things kept coming up in the
+mailing list, such as marking pieces of text or lines, which were
+extremely hard to do with CodeMirror 1. The new version has proper
+support for these built in.</li>
+
+<li><strong>Tab support.</strong> Tabs inside editable documents were,
+for some reason, a no-go. At least six different people announced they
+were going to add tab support to CodeMirror 1, none survived (I mean,
+none delivered a working version). CodeMirror 2 no longer removes tabs
+from your document.</li>
+
+<li><strong>Sane styling.</strong> <code>iframe</code> nodes aren't
+really known for respecting document flow. Now that an editor instance
+is a plain <code>div</code> element, it is much easier to size it to
+fit the surrounding elements. You don't even have to make it scroll if
+you do not <a href="../demo/resize.html">want to</a>.</li>
+
+</ul>
+
+<p>On the downside, a CodeMirror 2 instance is <em>not</em> a native
+editable component. Though it does its best to emulate such a
+component as much as possible, there is functionality that browsers
+just do not allow us to hook into. Doing select-all from the context
+menu, for example, is not currently detected by CodeMirror.</p>
+
+<p id="changes" style="margin-top: 2em;"><span style="font-weight:
+bold">[Updates from November 13th 2011]</span> Recently, I've made
+some changes to the codebase that cause some of the text above to no
+longer be current. I've left the text intact, but added markers at the
+passages that are now inaccurate. The new situation is described
+below.</p>
+</section>
+<section id="btree">
+  <h2>Content Representation</h2>
+
+<p>The original implementation of CodeMirror 2 represented the
+document as a flat array of line objects. This worked well—splicing
+arrays will require the part of the array after the splice to be
+moved, but this is basically just a simple <code>memmove</code> of a
+bunch of pointers, so it is cheap even for huge documents.</p>
+
+<p>However, I recently added line wrapping and code folding (line
+collapsing, basically). Once lines start taking up a non-constant
+amount of vertical space, looking up a line by vertical position
+(which is needed when someone clicks the document, and to determine
+the visible part of the document during scrolling) can only be done
+with a linear scan through the whole array, summing up line heights as
+you go. Seeing how I've been going out of my way to make big documents
+fast, this is not acceptable.</p>
+
+<p>The new representation is based on a B-tree. The leaves of the tree
+contain arrays of line objects, with a fixed minimum and maximum size,
+and the non-leaf nodes simply hold arrays of child nodes. Each node
+stores both the amount of lines that live below them and the vertical
+space taken up by these lines. This allows the tree to be indexed both
+by line number and by vertical position, and all access has
+logarithmic complexity in relation to the document size.</p>
+
+<p>I gave line objects and tree nodes parent pointers, to the node
+above them. When a line has to update its height, it can simply walk
+these pointers to the top of the tree, adding or subtracting the
+difference in height from each node it encounters. The parent pointers
+also make it cheaper (in complexity terms, the difference is probably
+tiny in normal-sized documents) to find the current line number when
+given a line object. In the old approach, the whole document array had
+to be searched. Now, we can just walk up the tree and count the sizes
+of the nodes coming before us at each level.</p>
+
+<p>I chose B-trees, not regular binary trees, mostly because they
+allow for very fast bulk insertions and deletions. When there is a big
+change to a document, it typically involves adding, deleting, or
+replacing a chunk of subsequent lines. In a regular balanced tree, all
+these inserts or deletes would have to be done separately, which could
+be really expensive. In a B-tree, to insert a chunk, you just walk
+down the tree once to find where it should go, insert them all in one
+shot, and then break up the node if needed. This breaking up might
+involve breaking up nodes further up, but only requires a single pass
+back up the tree. For deletion, I'm somewhat lax in keeping things
+balanced—I just collapse nodes into a leaf when their child count goes
+below a given number. This means that there are some weird editing
+patterns that may result in a seriously unbalanced tree, but even such
+an unbalanced tree will perform well, unless you spend a day making
+strangely repeating edits to a really big document.</p>
+</section>
+<section id="keymap">
+  <h2>Keymaps</h2>
+
+<p><a href="#approach">Above</a>, I claimed that directly catching key
+events for things like cursor movement is impractical because it
+requires some browser-specific kludges. I then proceeded to explain
+some awful <a href="#selection">hacks</a> that were needed to make it
+possible for the selection changes to be detected through the
+textarea. In fact, the second hack is about as bad as the first.</p>
+
+<p>On top of that, in the presence of user-configurable tab sizes and
+collapsed and wrapped lines, lining up cursor movement in the textarea
+with what's visible on the screen becomes a nightmare. Thus, I've
+decided to move to a model where the textarea's selection is no longer
+depended on.</p>
+
+<p>So I moved to a model where all cursor movement is handled by my
+own code. This adds support for a goal column, proper interaction of
+cursor movement with collapsed lines, and makes it possible for
+vertical movement to move through wrapped lines properly, instead of
+just treating them like non-wrapped lines.</p>
+
+<p>The key event handlers now translate the key event into a string,
+something like <code>Ctrl-Home</code> or <code>Shift-Cmd-R</code>, and
+use that string to look up an action to perform. To make keybinding
+customizable, this lookup goes through
+a <a href="manual.html#option_keyMap">table</a>, using a scheme that
+allows such tables to be chained together (for example, the default
+Mac bindings fall through to a table named 'emacsy', which defines
+basic Emacs-style bindings like <code>Ctrl-F</code>, and which is also
+used by the custom Emacs bindings).</p>
+
+<p>A new
+option <a href="manual.html#option_extraKeys"><code>extraKeys</code></a>
+allows ad-hoc keybindings to be defined in a much nicer way than what
+was possible with the
+old <a href="manual.html#option_onKeyEvent"><code>onKeyEvent</code></a>
+callback. You simply provide an object mapping key identifiers to
+functions, instead of painstakingly looking at raw key events.</p>
+
+<p>Built-in commands map to strings, rather than functions, for
+example <code>"goLineUp"</code> is the default action bound to the up
+arrow key. This allows new keymaps to refer to them without
+duplicating any code. New commands can be defined by assigning to
+the <code>CodeMirror.commands</code> object, which maps such commands
+to functions.</p>
+
+<p>The hidden textarea now only holds the current selection, with no
+extra characters around it. This has a nice advantage: polling for
+input becomes much, much faster. If there's a big selection, this text
+does not have to be read from the textarea every time—when we poll,
+just noticing that something is still selected is enough to tell us
+that no new text was typed.</p>
+
+<p>The reason that cheap polling is important is that many browsers do
+not fire useful events on IME (input method engine) input, which is
+the thing where people inputting a language like Japanese or Chinese
+use multiple keystrokes to create a character or sequence of
+characters. Most modern browsers fire <code>input</code> when the
+composing is finished, but many don't fire anything when the character
+is updated <em>during</em> composition. So we poll, whenever the
+editor is focused, to provide immediate updates of the display.</p>
+
+</article>
diff --git a/app/gui/html/vendor/codemirror/doc/logo.png b/app/gui/html/vendor/codemirror/doc/logo.png
new file mode 100644
index 0000000..2334f5e
Binary files /dev/null and b/app/gui/html/vendor/codemirror/doc/logo.png differ
diff --git a/app/gui/html/vendor/codemirror/doc/logo.svg b/app/gui/html/vendor/codemirror/doc/logo.svg
new file mode 100644
index 0000000..9783869
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/doc/logo.svg
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   inkscape:export-filename="/home/marijn/src/js/codemirror/doc/logo.png"
+   inkscape:export-xdpi="27.450405"
+   inkscape:export-ydpi="27.450405"
+   sodipodi:docname="logo.svg">
+  <defs
+     id="defs4">
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath4138">
+      <path
+         transform="matrix(1.05,0,0,1,-290.76164,27.927128)"
+         d="m 705.08647,231.61324 a 70.710678,104.55079 0 1 1 -141.42135,0 70.710678,104.55079 0 1 1 141.42135,0 z"
+         sodipodi:ry="104.55079"
+         sodipodi:rx="70.710678"
+         sodipodi:cy="231.61324"
+         sodipodi:cx="634.37579"
+         id="path4140"
+         style="fill:#ffffff;fill-opacity:1;stroke:none"
+         sodipodi:type="arc" />
+    </clipPath>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="291.72812"
+     inkscape:cy="789.2497"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1600"
+     inkscape:window-height="875"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <text
+       xml:space="preserve"
+       style="font-size:15px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#a21313;fill-opacity:1;stroke:none;font-family:Ubuntu Mono;-inkscape-font-specification:Ubuntu Mono"
+       x="247.48738"
+       y="163.42795"
+       id="text4006"
+       sodipodi:linespacing="125%"
+       clip-path="url(#clipPath4138)"
+       transform="translate(0.50507287,0.50507595)"><tspan
+         sodipodi:role="line"
+         id="tspan4008"
+         x="247.48738"
+         y="163.42795">    if (unit == "char") moveOnce();</tspan><tspan
+         sodipodi:role="line"
+         x="247.48738"
+         y="182.17795"
+         id="tspan4010">    else if (unit == "column") moveOnce(true);</tspan><tspan
+         sodipodi:role="line"
+         x="247.48738"
+         y="200.92795"
+         id="tspan4012">    else if (unit == "word" || unit == "group") {</tspan><tspan
+         sodipodi:role="line"
+         x="247.48738"
+         y="219.67795"
+         id="tspan4014">      var sawType = null, group = unit == "group";</tspan><tspan
+         sodipodi:role="line"
+         x="247.48738"
+         y="238.42795"
+         id="tspan4016">      for (var first = true;; first = false) {</tspan><tspan
+         sodipodi:role="line"
+         x="247.48738"
+         y="257.17795"
+         id="tspan4018">        if (dir < 0 && !moveOnce(!first)) break;</tspan><tspan
+         sodipodi:role="line"
+         x="247.48738"
+         y="275.92795"
+         id="tspan4020">        var cur = lineObj.text.charAt(ch) || "\n";</tspan><tspan
+         sodipodi:role="line"
+         x="247.48738"
+         y="294.67795"
+         id="tspan4022">        var type = isWordChar(cur) ? "w"</tspan><tspan
+         sodipodi:role="line"
+         x="247.48738"
+         y="313.42795"
+         id="tspan4024">          : !group ? null</tspan><tspan
+         sodipodi:role="line"
+         x="247.48738"
+         y="332.17795"
+         id="tspan4026">          : /\s/.test(cur) ? null</tspan><tspan
+         sodipodi:role="line"
+         x="247.48738"
+         y="350.92795"
+         id="tspan4028">          : "p"; // punctuation</tspan><tspan
+         sodipodi:role="line"
+         x="247.48738"
+         y="369.67795"
+         id="tspan4046">        if (sawType && sawType</tspan></text>
+    <path
+       style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none"
+       d="M 374.84375 136.8125 C 371.96854 136.71001 368.64305 137.97919 365.15625 142.03125 C 361.97051 140.84608 359.22347 140.35622 356.84375 140.375 C 346.53162 140.4564 343.3125 149.71875 343.3125 149.71875 C 326.2234 146.67934 325.625 162.59375 325.625 162.59375 C 309.43195 163.37101 312.4375 177.375 312.4375 177.375 C 295.67899 180.15651 301.1875 194 301.1875 194 C 284.10838 199.04575 293.4375 212.46875 293.4375 212.46875 C 293.4375 212.46875 277.68174 220.31271 288.1875 232.25 C 288.1875 232.25 273.81776 243.63282 285.90625 253.34375 C 285.90625 253.34375 271.57897 263.97487 286.40625 275.03125 C 286.40625 275.03125 273.84147 285.48036 289.96875 295.3125 C 289.96875 295.3125 278.92374 306.07108 295.59375 314.65625 C 295.59375 314.65625 287.70844 329.01862 305.96875 335.125 C 305.96875 335.125 300.47495 348.88874 319.09375 351.46875 C 319.09375 351.46875 315.90162 357.19564 321.59375 361.15625 C 321.59375 361.15625 310.04416 364.78661 312.5625 374.40625 C 313.83361 379.26171 316.82684 380.49158 323.53125 380.1875 C 323.53125 380.1875 329.096 395.54812 350.46875 398.96875 L 353.125 402.59375 C 353.125 402.59375 342.80592 409.64088 359.125 421.5 C 359.125 421.5 354.16126 425.74314 363.28125 433.34375 C 363.28125 433.34375 357.54117 438.3362 365.75 442.625 C 365.75 442.625 361.35822 445.96166 366.09375 448.125 C 366.09375 448.125 370.88293 490.18262 355.40625 534.4375 C 355.40625 534.4375 341.28721 542.04782 350.1875 556.96875 C 350.1875 556.96875 331.59675 562.24093 345.09375 575.53125 C 345.09375 575.53125 342.0547 585.56155 349.375 585.78125 C 349.375 585.78125 346.16048 592.54552 354.4375 594.5625 C 354.4375 594.5625 353.17883 603.88113 364.09375 602.1875 C 369.44813 608.40994 378.92733 608.70518 385.21875 602.34375 C 396.13361 604.03738 394.875 594.71875 394.875 594.71875 C 403.15197 592.70177 399.9375 585.9375 399.9375 585.9375 C 407.25781 585.7178 404.21875 575.6875 404.21875 575.6875 C 417.71573 562.39718 399.125 557.09375 399.125 557.09375 C 408.0253 542.17282 393.90625 534.5625 393.90625 534.5625 C 378.42953 490.30762 383.21875 448.28125 383.21875 448.28125 C 387.95421 446.11791 383.5625 442.78125 383.5625 442.78125 C 391.77129 438.49245 386.03125 433.5 386.03125 433.5 C 395.15125 425.89939 390.1875 421.65625 390.1875 421.65625 C 406.5066 409.79713 396.1875 402.75 396.1875 402.75 L 398.84375 399.125 C 420.21649 395.70437 425.78125 380.34375 425.78125 380.34375 C 432.48566 380.64783 435.47889 379.41796 436.75 374.5625 C 439.26834 364.94286 427.75 361.3125 427.75 361.3125 C 433.44213 357.35188 430.21875 351.59375 430.21875 351.59375 C 448.83755 349.01373 443.34375 335.28125 443.34375 335.28125 C 461.60406 329.17487 453.71875 314.78125 453.71875 314.78125 C 470.38876 306.19608 459.34375 295.46875 459.34375 295.46875 C 475.47103 285.63661 462.90625 275.1875 462.90625 275.1875 C 477.73353 264.13112 463.40625 253.5 463.40625 253.5 C 475.49474 243.78907 461.15625 232.375 461.15625 232.375 C 471.66201 220.43771 455.875 212.625 455.875 212.625 C 455.875 212.625 465.20411 199.202 448.125 194.15625 C 448.125 194.15625 453.66476 180.31276 436.90625 177.53125 C 436.90625 177.53125 439.88054 163.52726 423.6875 162.75 C 423.6875 162.75 423.0891 146.8356 406 149.875 C 406 149.875 401.14687 135.83532 384.15625 142.15625 C 384.15625 142.15625 380.33279 137.00815 374.84375 136.8125 z M 375.34375 155 C 416.3488 155 449.59375 201.78944 449.59375 259.53125 C 449.59375 317.27306 416.3488 364.09375 375.34375 364.09375 C 334.3387 364.09375 301.09375 317.27306 301.09375 259.53125 C 301.09375 201.78944 334.3387 155 375.34375 155 z "
+       id="rect3058" />
+    <text
+       sodipodi:linespacing="125%"
+       id="text4207"
+       y="491.91403"
+       x="149.69542"
+       style="font-size:95px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#a21313;fill-opacity:1;stroke:none;font-family:Source Sans;-inkscape-font-specification:Source Sans"
+       xml:space="preserve"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90"><tspan
+         y="491.91403"
+         x="149.69542"
+         id="tspan4209"
+         sodipodi:role="line">Code  Mirror</tspan></text>
+  </g>
+</svg>
diff --git a/app/gui/html/vendor/codemirror/doc/manual.html b/app/gui/html/vendor/codemirror/doc/manual.html
new file mode 100644
index 0000000..09a7362
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/doc/manual.html
@@ -0,0 +1,2879 @@
+<!doctype html>
+
+<title>CodeMirror: User Manual</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="docs.css">
+<script src="activebookmark.js"></script>
+
+<script src="../lib/codemirror.js"></script>
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../addon/runmode/runmode.js"></script>
+<script src="../addon/runmode/colorize.js"></script>
+<script src="../mode/javascript/javascript.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<script src="../mode/css/css.js"></script>
+<script src="../mode/htmlmixed/htmlmixed.js"></script>
+<style>
+  dt { text-indent: -2em; padding-left: 2em; margin-top: 1em; }
+  dd { margin-left: 1.5em; margin-bottom: 1em; }
+  dt {margin-top: 1em;}
+  dd dl, dd dt, dd dd, dd ul { margin-top: 0; margin-bottom: 0; }
+  dt + dt { margin-top: 0; }
+  dt.command { position: relative; }
+  span.keybinding { position: absolute; right: 0; font-size: 80%; color: #555; text-indent: 0; }
+</style>
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="logo.png"></a>
+  <ul>
+    <li><a href="../index.html">Home</a></li>
+    <li><a href="#overview" class=active data-default="true">Manual</a></li>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a></li>
+  </ul>
+  <ul>
+    <li><a href="#usage">Basic Usage</a></li>
+    <li><a href="#config">Configuration</a></li>
+    <li><a href="#events">Events</a></li>
+    <li><a href="#keymaps">Key maps</a></li>
+    <li><a href="#commands">Commands</a></li>
+    <li><a href="#styling">Customized Styling</a></li>
+    <li><a href="#api">Programming API</a>
+      <ul>
+        <li><a href="#api_constructor">Constructor</a></li>
+        <li><a href="#api_content">Content manipulation</a></li>
+        <li><a href="#api_selection">Selection</a></li>
+        <li><a href="#api_configuration">Configuration</a></li>
+        <li><a href="#api_doc">Document management</a></li>
+        <li><a href="#api_history">History</a></li>
+        <li><a href="#api_marker">Text-marking</a></li>
+        <li><a href="#api_decoration">Widget, gutter, and decoration</a></li>
+        <li><a href="#api_sizing">Sizing, scrolling, and positioning</a></li>
+        <li><a href="#api_mode">Mode, state, and tokens</a></li>
+        <li><a href="#api_misc">Miscellaneous methods</a></li>
+        <li><a href="#api_static">Static properties</a></li>
+      </ul>
+    </li>
+    <li><a href="#addons">Addons</a></li>
+    <li><a href="#modeapi">Writing CodeMirror Modes</a></li>
+  </ul>
+</div>
+
+<article>
+
+<section class=first id=overview>
+    <h2 style="position: relative">
+      User manual and reference guide
+      <span style="color: #888; font-size: 1rem; position: absolute; right: 0; bottom: 0">version 4.0.3</span>
+    </h2>
+
+    <p>CodeMirror is a code-editor component that can be embedded in
+    Web pages. The core library provides <em>only</em> the editor
+    component, no accompanying buttons, auto-completion, or other IDE
+    functionality. It does provide a rich API on top of which such
+    functionality can be straightforwardly implemented. See
+    the <a href="#addons">addons</a> included in the distribution,
+    and the <a href="https://github.com/marijnh/CodeMirror/wiki/CodeMirror-addons">list
+    of externally hosted addons</a>, for reusable
+    implementations of extra features.</p>
+
+    <p>CodeMirror works with language-specific modes. Modes are
+    JavaScript programs that help color (and optionally indent) text
+    written in a given language. The distribution comes with a number
+    of modes (see the <a href="../mode/"><code>mode/</code></a>
+    directory), and it isn't hard to <a href="#modeapi">write new
+    ones</a> for other languages.</p>
+</section>
+
+<section id=usage>
+    <h2>Basic Usage</h2>
+
+    <p>The easiest way to use CodeMirror is to simply load the script
+    and style sheet found under <code>lib/</code> in the distribution,
+    plus a mode script from one of the <code>mode/</code> directories.
+    (See <a href="compress.html">the compression helper</a> for an
+    easy way to combine scripts.) For example:</p>
+
+    <pre data-lang="text/html"><script src="lib/codemirror.js"></script>
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="mode/javascript/javascript.js"></script></pre>
+
+    <p>(Alternatively, use a module loader. <a href="#modloader">More
+    about that later.</a>)</p>
+
+    <p>Having done this, an editor instance can be created like
+    this:</p>
+
+    <pre data-lang="javascript">var myCodeMirror = CodeMirror(document.body);</pre>
+
+    <p>The editor will be appended to the document body, will start
+    empty, and will use the mode that we loaded. To have more control
+    over the new editor, a configuration object can be passed
+    to <a href="#CodeMirror"><code>CodeMirror</code></a> as a second
+    argument:</p>
+
+    <pre data-lang="javascript">var myCodeMirror = CodeMirror(document.body, {
+  value: "function myScript(){return 100;}\n",
+  mode:  "javascript"
+});</pre>
+
+    <p>This will initialize the editor with a piece of code already in
+    it, and explicitly tell it to use the JavaScript mode (which is
+    useful when multiple modes are loaded).
+    See <a href="#config">below</a> for a full discussion of the
+    configuration options that CodeMirror accepts.</p>
+
+    <p>In cases where you don't want to append the editor to an
+    element, and need more control over the way it is inserted, the
+    first argument to the <code>CodeMirror</code> function can also
+    be a function that, when given a DOM element, inserts it into the
+    document somewhere. This could be used to, for example, replace a
+    textarea with a real editor:</p>
+
+    <pre data-lang="javascript">var myCodeMirror = CodeMirror(function(elt) {
+  myTextArea.parentNode.replaceChild(elt, myTextArea);
+}, {value: myTextArea.value});</pre>
+
+    <p>However, for this use case, which is a common way to use
+    CodeMirror, the library provides a much more powerful
+    shortcut:</p>
+
+    <pre data-lang="javascript">var myCodeMirror = CodeMirror.fromTextArea(myTextArea);</pre>
+
+    <p>This will, among other things, ensure that the textarea's value
+    is updated with the editor's contents when the form (if it is part
+    of a form) is submitted. See the <a href="#fromTextArea">API
+    reference</a> for a full description of this method.</p>
+
+    <h3 id=modloader>Module loaders</h3>
+
+    <p>The files in the CodeMirror distribution contain shims for
+    loading them (and their dependencies) in AMD or CommonJS
+    environments. If the variables <code>exports</code>
+    and <code>module</code> exist and have type object, CommonJS-style
+    require will be used. If not, but there is a
+    function <code>define</code> with an <code>amd</code> property
+    present, AMD-style (RequireJS) will be used.</p>
+
+    <p>It is possible to
+    use <a href="http://browserify.org/">Browserify</a> or similar
+    tools to statically build modules using CodeMirror. Alternatively,
+    use <a href="http://requirejs.org/">RequireJS</a> to dynamically
+    load dependencies at runtime. Both of these approaches have the
+    advantage that they don't use the global namespace and can, thus,
+    do things like load multiple versions of CodeMirror alongside each
+    other.</p>
+
+    <p>Here's a simple example of using RequireJS to load CodeMirror:</p>
+
+    <pre data-lang="javascript">require([
+  "cm/lib/codemirror", "cm/mode/htmlmixed/htmlmixed"
+], function(CodeMirror) {
+  CodeMirror.fromTextArea(document.getElementById("code"), {
+    lineNumbers: true,
+    mode: "htmlmixed"
+  });
+});</pre>
+
+    <p>It will automatically load the modes that the mixed HTML mode
+    depends on (XML, JavaScript, and CSS).</p>
+
+</section>
+
+<section id=config>
+    <h2>Configuration</h2>
+
+    <p>Both the <a href="#CodeMirror"><code>CodeMirror</code></a>
+    function and its <code>fromTextArea</code> method take as second
+    (optional) argument an object containing configuration options.
+    Any option not supplied like this will be taken
+    from <a href="#defaults"><code>CodeMirror.defaults</code></a>, an
+    object containing the default options. You can update this object
+    to change the defaults on your page.</p>
+
+    <p>Options are not checked in any way, so setting bogus option
+    values is bound to lead to odd errors.</p>
+
+    <p>These are the supported options:</p>
+
+    <dl>
+      <dt id="option_value"><code><strong>value</strong>: string|CodeMirror.Doc</code></dt>
+      <dd>The starting value of the editor. Can be a string, or
+      a <a href="#api_doc">document object</a>.</dd>
+
+      <dt id="option_mode"><code><strong>mode</strong>: string|object</code></dt>
+      <dd>The mode to use. When not given, this will default to the
+      first mode that was loaded. It may be a string, which either
+      simply names the mode or is
+      a <a href="http://en.wikipedia.org/wiki/MIME">MIME</a> type
+      associated with the mode. Alternatively, it may be an object
+      containing configuration options for the mode, with
+      a <code>name</code> property that names the mode (for
+      example <code>{name: "javascript", json: true}</code>). The demo
+      pages for each mode contain information about what configuration
+      parameters the mode supports. You can ask CodeMirror which modes
+      and MIME types have been defined by inspecting
+      the <code>CodeMirror.modes</code>
+      and <code>CodeMirror.mimeModes</code> objects. The first maps
+      mode names to their constructors, and the second maps MIME types
+      to mode specs.</dd>
+
+      <dt id="option_theme"><code><strong>theme</strong>: string</code></dt>
+      <dd>The theme to style the editor with. You must make sure the
+      CSS file defining the corresponding <code>.cm-s-[name]</code>
+      styles is loaded (see
+      the <a href="../theme/"><code>theme</code></a> directory in the
+      distribution). The default is <code>"default"</code>, for which
+      colors are included in <code>codemirror.css</code>. It is
+      possible to use multiple theming classes at once—for
+      example <code>"foo bar"</code> will assign both
+      the <code>cm-s-foo</code> and the <code>cm-s-bar</code> classes
+      to the editor.</dd>
+
+      <dt id="option_indentUnit"><code><strong>indentUnit</strong>: integer</code></dt>
+      <dd>How many spaces a block (whatever that means in the edited
+      language) should be indented. The default is 2.</dd>
+
+      <dt id="option_smartIndent"><code><strong>smartIndent</strong>: boolean</code></dt>
+      <dd>Whether to use the context-sensitive indentation that the
+      mode provides (or just indent the same as the line before).
+      Defaults to true.</dd>
+
+      <dt id="option_tabSize"><code><strong>tabSize</strong>: integer</code></dt>
+      <dd>The width of a tab character. Defaults to 4.</dd>
+
+      <dt id="option_indentWithTabs"><code><strong>indentWithTabs</strong>: boolean</code></dt>
+      <dd>Whether, when indenting, the first N*<code>tabSize</code>
+      spaces should be replaced by N tabs. Default is false.</dd>
+
+      <dt id="option_electricChars"><code><strong>electricChars</strong>: boolean</code></dt>
+      <dd>Configures whether the editor should re-indent the current
+      line when a character is typed that might change its proper
+      indentation (only works if the mode supports indentation).
+      Default is true.</dd>
+
+      <dt id="option_specialChars"><code><strong>specialChars</strong>: RegExp</code></dt>
+      <dd>A regular expression used to determine which characters
+      should be replaced by a
+      special <a href="#option_specialCharPlaceholder">placeholder</a>.
+      Mostly useful for non-printing special characters. The default
+      is <code>/[\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/</code>.</dd>
+      <dt id="option_specialCharPlaceholder"><code><strong>specialCharPlaceholder</strong>: function(char) → Element</code></dt>
+      <dd>A function that, given a special character identified by
+      the <a href="#option_specialChars"><code>specialChars</code></a>
+      option, produces a DOM node that is used to represent the
+      character. By default, a red dot (<span style="color: red">•</span>)
+      is shown, with a title tooltip to indicate the character code.</dd>
+
+      <dt id="option_rtlMoveVisually"><code><strong>rtlMoveVisually</strong>: boolean</code></dt>
+      <dd>Determines whether horizontal cursor movement through
+      right-to-left (Arabic, Hebrew) text is visual (pressing the left
+      arrow moves the cursor left) or logical (pressing the left arrow
+      moves to the next lower index in the string, which is visually
+      right in right-to-left text). The default is <code>false</code>
+      on Windows, and <code>true</code> on other platforms.</dd>
+
+      <dt id="option_keyMap"><code><strong>keyMap</strong>: string</code></dt>
+      <dd>Configures the key map to use. The default
+      is <code>"default"</code>, which is the only key map defined
+      in <code>codemirror.js</code> itself. Extra key maps are found in
+      the <a href="../keymap/"><code>key map</code></a> directory. See
+      the <a href="#keymaps">section on key maps</a> for more
+      information.</dd>
+
+      <dt id="option_extraKeys"><code><strong>extraKeys</strong>: object</code></dt>
+      <dd>Can be used to specify extra key bindings for the editor,
+      alongside the ones defined
+      by <a href="#option_keyMap"><code>keyMap</code></a>. Should be
+      either null, or a valid <a href="#keymaps">key map</a> value.</dd>
+
+      <dt id="option_lineWrapping"><code><strong>lineWrapping</strong>: boolean</code></dt>
+      <dd>Whether CodeMirror should scroll or wrap for long lines.
+      Defaults to <code>false</code> (scroll).</dd>
+
+      <dt id="option_lineNumbers"><code><strong>lineNumbers</strong>: boolean</code></dt>
+      <dd>Whether to show line numbers to the left of the editor.</dd>
+
+      <dt id="option_firstLineNumber"><code><strong>firstLineNumber</strong>: integer</code></dt>
+      <dd>At which number to start counting lines. Default is 1.</dd>
+
+      <dt id="option_lineNumberFormatter"><code><strong>lineNumberFormatter</strong>: function(line: integer) → string</code></dt>
+      <dd>A function used to format line numbers. The function is
+      passed the line number, and should return a string that will be
+      shown in the gutter.</dd>
+
+      <dt id="option_gutters"><code><strong>gutters</strong>: array<string></code></dt>
+      <dd>Can be used to add extra gutters (beyond or instead of the
+      line number gutter). Should be an array of CSS class names, each
+      of which defines a <code>width</code> (and optionally a
+      background), and which will be used to draw the background of
+      the gutters. <em>May</em> include
+      the <code>CodeMirror-linenumbers</code> class, in order to
+      explicitly set the position of the line number gutter (it will
+      default to be to the right of all other gutters). These class
+      names are the keys passed
+      to <a href="#setGutterMarker"><code>setGutterMarker</code></a>.</dd>
+
+      <dt id="option_fixedGutter"><code><strong>fixedGutter</strong>: boolean</code></dt>
+      <dd>Determines whether the gutter scrolls along with the content
+      horizontally (false) or whether it stays fixed during horizontal
+      scrolling (true, the default).</dd>
+
+      <dt id="option_coverGutterNextToScrollbar"><code><strong>coverGutterNextToScrollbar</strong>: boolean</code></dt>
+      <dd>When <a href="#option_fixedGutter"><code>fixedGutter</code></a>
+      is on, and there is a horizontal scrollbar, by default the
+      gutter will be visible to the left of this scrollbar. If this
+      option is set to true, it will be covered by an element with
+      class <code>CodeMirror-gutter-filler</code>.</dd>
+
+      <dt id="option_readOnly"><code><strong>readOnly</strong>: boolean|string</code></dt>
+      <dd>This disables editing of the editor content by the user. If
+      the special value <code>"nocursor"</code> is given (instead of
+      simply <code>true</code>), focusing of the editor is also
+      disallowed.</dd>
+
+      <dt id="option_showCursorWhenSelecting"><code><strong>showCursorWhenSelecting</strong>: boolean</code></dt>
+      <dd>Whether the cursor should be drawn when a selection is
+      active. Defaults to false.</dd>
+
+      <dt id="option_undoDepth"><code><strong>undoDepth</strong>: integer</code></dt>
+      <dd>The maximum number of undo levels that the editor stores.
+      Note that this includes selection change events. Defaults to
+      200.</dd>
+
+      <dt id="option_historyEventDelay"><code><strong>historyEventDelay</strong>: integer</code></dt>
+      <dd>The period of inactivity (in milliseconds) that will cause a
+      new history event to be started when typing or deleting.
+      Defaults to 1250.</dd>
+
+      <dt id="option_tabindex"><code><strong>tabindex</strong>: integer</code></dt>
+      <dd>The <a href="http://www.w3.org/TR/html401/interact/forms.html#adef-tabindex">tab
+      index</a> to assign to the editor. If not given, no tab index
+      will be assigned.</dd>
+
+      <dt id="option_autofocus"><code><strong>autofocus</strong>: boolean</code></dt>
+      <dd>Can be used to make CodeMirror focus itself on
+      initialization. Defaults to off.
+      When <a href="#fromTextArea"><code>fromTextArea</code></a> is
+      used, and no explicit value is given for this option, it will be
+      set to true when either the source textarea is focused, or it
+      has an <code>autofocus</code> attribute and no other element is
+      focused.</dd>
+    </dl>
+
+    <p>Below this a few more specialized, low-level options are
+    listed. These are only useful in very specific situations, you
+    might want to skip them the first time you read this manual.</p>
+
+    <dl>
+      <dt id="option_dragDrop"><code><strong>dragDrop</strong>: boolean</code></dt>
+      <dd>Controls whether drag-and-drop is enabled. On by default.</dd>
+
+      <dt id="option_cursorBlinkRate"><code><strong>cursorBlinkRate</strong>: number</code></dt>
+      <dd>Half-period in milliseconds used for cursor blinking. The default blink
+      rate is 530ms. By setting this to zero, blinking can be disabled.</dd>
+
+      <dt id="option_cursorScrollMargin"><code><strong>cursorScrollMargin</strong>: number</code></dt>
+      <dd>How much extra space to always keep above and below the
+      cursor when approaching the top or bottom of the visible view in
+      a scrollable document. Default is 0.</dd>
+
+      <dt id="option_cursorHeight"><code><strong>cursorHeight</strong>: number</code></dt>
+      <dd>Determines the height of the cursor. Default is 1, meaning
+      it spans the whole height of the line. For some fonts (and by
+      some tastes) a smaller height (for example <code>0.85</code>),
+      which causes the cursor to not reach all the way to the bottom
+      of the line, looks better</dd>
+
+      <dt id="option_resetSelectionOnContextMenu"><code><strong>resetSelectionOnContextMenu</strong>: boolean</code></dt>
+      <dd>Controls whether, when the context menu is opened with a
+      click outside of the current selection, the cursor is moved to
+      the point of the click. Defaults to <code>true</code>.</dd>
+
+      <dt id="option_workTime"><code id="option_wordkDelay"><strong>workTime</strong>, <strong>workDelay</strong>: number</code></dt>
+      <dd>Highlighting is done by a pseudo background-thread that will
+      work for <code>workTime</code> milliseconds, and then use
+      timeout to sleep for <code>workDelay</code> milliseconds. The
+      defaults are 200 and 300, you can change these options to make
+      the highlighting more or less aggressive.</dd>
+
+      <dt id="option_pollInterval"><code><strong>pollInterval</strong>: number</code></dt>
+      <dd>Indicates how quickly CodeMirror should poll its input
+      textarea for changes (when focused). Most input is captured by
+      events, but some things, like IME input on some browsers, don't
+      generate events that allow CodeMirror to properly detect it.
+      Thus, it polls. Default is 100 milliseconds.</dd>
+
+      <dt id="option_flattenSpans"><code><strong>flattenSpans</strong>: boolean</code></dt>
+      <dd>By default, CodeMirror will combine adjacent tokens into a
+      single span if they have the same class. This will result in a
+      simpler DOM tree, and thus perform better. With some kinds of
+      styling (such as rounded corners), this will change the way the
+      document looks. You can set this option to false to disable this
+      behavior.</dd>
+
+      <dt id="option_addModeClass"><code><strong>addModeClass</strong>: boolean</code></dt>
+      <dd>When enabled (off by default), an extra CSS class will be
+      added to each token, indicating the
+      (<a href="#innerMode">inner</a>) mode that produced it, prefixed
+      with <code>"cm-m-"</code>. For example, tokens from the XML mode
+      will get the <code>cm-m-xml</code> class.</dd>
+
+      <dt id="option_maxHighlightLength"><code><strong>maxHighlightLength</strong>: number</code></dt>
+      <dd>When highlighting long lines, in order to stay responsive,
+      the editor will give up and simply style the rest of the line as
+      plain text when it reaches a certain position. The default is
+      10 000. You can set this to <code>Infinity</code> to turn off
+      this behavior.</dd>
+
+      <dt id="option_crudeMeasuringFrom"><code><strong>crudeMeasuringFrom</strong>: number</code></dt>
+      <dd>When measuring the character positions in long lines, any
+      line longer than this number (default is 10 000),
+      when <a href="#option_lineWrapping">line wrapping</a>
+      is <strong>off</strong>, will simply be assumed to consist of
+      same-sized characters. This means that, on the one hand,
+      measuring will be inaccurate when characters of varying size,
+      right-to-left text, markers, or other irregular elements are
+      present. On the other hand, it means that having such a line
+      won't freeze the user interface because of the expensiveness of
+      the measurements.</dd>
+
+      <dt id="option_viewportMargin"><code><strong>viewportMargin</strong>: integer</code></dt>
+      <dd>Specifies the amount of lines that are rendered above and
+      below the part of the document that's currently scrolled into
+      view. This affects the amount of updates needed when scrolling,
+      and the amount of work that such an update does. You should
+      usually leave it at its default, 10. Can be set
+      to <code>Infinity</code> to make sure the whole document is
+      always rendered, and thus the browser's text search works on it.
+      This <em>will</em> have bad effects on performance of big
+      documents.</dd>
+    </dl>
+</section>
+
+<section id=events>
+    <h2>Events</h2>
+
+    <p>Various CodeMirror-related objects emit events, which allow
+    client code to react to various situations. Handlers for such
+    events can be registered with the <a href="#on"><code>on</code></a>
+    and <a href="#off"><code>off</code></a> methods on the objects
+    that the event fires on. To fire your own events,
+    use <code>CodeMirror.signal(target, name, args...)</code>,
+    where <code>target</code> is a non-DOM-node object.</p>
+
+    <p>An editor instance fires the following events.
+    The <code>instance</code> argument always refers to the editor
+    itself.</p>
+
+    <dl>
+      <dt id="event_change"><code><strong>"change"</strong> (instance: CodeMirror, changeObj: object)</code></dt>
+      <dd>Fires every time the content of the editor is changed.
+      The <code>changeObj</code> is a <code>{from, to, text, removed,
+      origin}</code> object containing information about the changes
+      that occurred as second argument. <code>from</code>
+      and <code>to</code> are the positions (in the pre-change
+      coordinate system) where the change started and ended (for
+      example, it might be <code>{ch:0, line:18}</code> if the
+      position is at the beginning of line #19). <code>text</code> is
+      an array of strings representing the text that replaced the
+      changed range (split by line). <code>removed</code> is the text
+      that used to be between <code>from</code> and <code>to</code>,
+      which is overwritten by this change.</dd>
+
+      <dt id="event_changes"><code><strong>"changes"</strong> (instance: CodeMirror, changes: array<object<)</code></dt>
+      <dd>Like the <a href="#event_change"><code>"change"</code></a>
+      event, but batched per <a href="#operation">operation</a>,
+      passing an array containing all the changes that happened in the
+      operation.</dd>
+
+      <dt id="event_beforeChange"><code><strong>"beforeChange"</strong> (instance: CodeMirror, changeObj: object)</code></dt>
+      <dd>This event is fired before a change is applied, and its
+      handler may choose to modify or cancel the change.
+      The <code>changeObj</code> object
+      has <code>from</code>, <code>to</code>, and <code>text</code>
+      properties, as with
+      the <a href="#event_change"><code>"change"</code></a> event. It
+      also has a <code>cancel()</code> method, which can be called to
+      cancel the change, and, <strong>if</strong> the change isn't
+      coming from an undo or redo event, an <code>update(from, to,
+      text)</code> method, which may be used to modify the change.
+      Undo or redo changes can't be modified, because they hold some
+      metainformation for restoring old marked ranges that is only
+      valid for that specific change. All three arguments
+      to <code>update</code> are optional, and can be left off to
+      leave the existing value for that field
+      intact. <strong>Note:</strong> you may not do anything from
+      a <code>"beforeChange"</code> handler that would cause changes
+      to the document or its visualization. Doing so will, since this
+      handler is called directly from the bowels of the CodeMirror
+      implementation, probably cause the editor to become
+      corrupted.</dd>
+
+      <dt id="event_cursorActivity"><code><strong>"cursorActivity"</strong> (instance: CodeMirror)</code></dt>
+      <dd>Will be fired when the cursor or selection moves, or any
+      change is made to the editor content.</dd>
+
+      <dt id="event_keyHandled"><code><strong>"keyHandled"</strong> (instance: CodeMirror, name: string, event: Event)</code></dt>
+      <dd>Fired after a key is handled through a
+      key map. <code>name</code> is the name of the handled key (for
+      example <code>"Ctrl-X"</code> or <code>"'q'"</code>),
+      and <code>event</code> is the DOM <code>keydown</code>
+      or <code>keypress</code> event.</dd>
+
+      <dt id="event_inputRead"><code><strong>"inputRead"</strong> (instance: CodeMirror, changeObj: object)</code></dt>
+      <dd>Fired whenever new input is read from the hidden textarea
+      (typed or pasted by the user).</dd>
+
+      <dt id="event_beforeSelectionChange"><code><strong>"beforeSelectionChange"</strong> (instance: CodeMirror, obj: {ranges, update})</code></dt>
+      <dd>This event is fired before the selection is moved. Its
+      handler may inspect the set of selection ranges, present as an
+      array of <code>{anchor, head}</code> objects in
+      the <code>ranges</code> property of the <code>obj</code>
+      argument, and optionally change them by calling
+      the <code>update</code> method on this object, passing an array
+      of ranges in the same format. Handlers for this event have the
+      same restriction
+      as <a href="#event_beforeChange"><code>"beforeChange"</code></a>
+      handlers — they should not do anything to directly update the
+      state of the editor.</dd>
+
+      <dt id="event_viewportChange"><code><strong>"viewportChange"</strong> (instance: CodeMirror, from: number, to: number)</code></dt>
+      <dd>Fires whenever the <a href="#getViewport">view port</a> of
+      the editor changes (due to scrolling, editing, or any other
+      factor). The <code>from</code> and <code>to</code> arguments
+      give the new start and end of the viewport.</dd>
+
+      <dt id="event_swapDoc"><code><strong>"swapDoc"</strong> (instance: CodeMirror, oldDoc: Doc)</code></dt>
+      <dd>This is signalled when the editor's document is replaced
+      using the <a href="#swapDoc"><code>swapDoc</code></a>
+      method.</dd>
+
+      <dt id="event_gutterClick"><code><strong>"gutterClick"</strong> (instance: CodeMirror, line: integer, gutter: string, clickEvent: Event)</code></dt>
+      <dd>Fires when the editor gutter (the line-number area) is
+      clicked. Will pass the editor instance as first argument, the
+      (zero-based) number of the line that was clicked as second
+      argument, the CSS class of the gutter that was clicked as third
+      argument, and the raw <code>mousedown</code> event object as
+      fourth argument.</dd>
+
+      <dt id="event_gutterContextMenu"><code><strong>"gutterContextMenu"</strong> (instance: CodeMirror, line: integer, gutter: string, contextMenu: Event: Event)</code></dt>
+      <dd>Fires when the editor gutter (the line-number area)
+      receives a <code>contextmenu</code> event. Will pass the editor
+      instance as first argument, the (zero-based) number of the line
+      that was clicked as second argument, the CSS class of the
+      gutter that was clicked as third argument, and the raw
+      <code>contextmenu</code> mouse event object as fourth argument.
+      You can <code>preventDefault</code> the event, to signal that
+      CodeMirror should do no further handling.</dd>
+
+      <dt id="event_focus"><code><strong>"focus"</strong> (instance: CodeMirror)</code></dt>
+      <dd>Fires whenever the editor is focused.</dd>
+
+      <dt id="event_blur"><code><strong>"blur"</strong> (instance: CodeMirror)</code></dt>
+      <dd>Fires whenever the editor is unfocused.</dd>
+
+      <dt id="event_scroll"><code><strong>"scroll"</strong> (instance: CodeMirror)</code></dt>
+      <dd>Fires when the editor is scrolled.</dd>
+
+      <dt id="event_update"><code><strong>"update"</strong> (instance: CodeMirror)</code></dt>
+      <dd>Will be fired whenever CodeMirror updates its DOM display.</dd>
+
+      <dt id="event_renderLine"><code><strong>"renderLine"</strong> (instance: CodeMirror, line: LineHandle, element: Element)</code></dt>
+      <dd>Fired whenever a line is (re-)rendered to the DOM. Fired
+      right after the DOM element is built, <em>before</em> it is
+      added to the document. The handler may mess with the style of
+      the resulting element, or add event handlers, but
+      should <em>not</em> try to change the state of the editor.</dd>
+
+      <dt id="event_dom"><code><strong>"mousedown"</strong>,
+      <strong>"dblclick"</strong>, <strong>"contextmenu"</strong>, <strong>"keydown"</strong>, <strong>"keypress"</strong>,
+      <strong>"keyup"</strong>, <strong>"dragstart"</strong>, <strong>"dragenter"</strong>,
+      <strong>"dragover"</strong>, <strong>"drop"</strong>
+      (instance: CodeMirror, event: Event)</code></dt>
+      <dd>Fired when CodeMirror is handling a DOM event of this type.
+      You can <code>preventDefault</code> the event, or give it a
+      truthy <code>codemirrorIgnore</code> property, to signal that
+      CodeMirror should do no further handling.</dd>
+    </dl>
+
+    <p>Document objects (instances
+    of <a href="#Doc"><code>CodeMirror.Doc</code></a>) emit the
+    following events:</p>
+
+    <dl>
+      <dt id="event_doc_change"><code><strong>"change"</strong> (doc: CodeMirror.Doc, changeObj: object)</code></dt>
+      <dd>Fired whenever a change occurs to the
+      document. <code>changeObj</code> has a similar type as the
+      object passed to the
+      editor's <a href="#event_change"><code>"change"</code></a>
+      event.</dd>
+
+      <dt id="event_doc_beforeChange"><code><strong>"beforeChange"</strong> (doc: CodeMirror.Doc, change: object)</code></dt>
+      <dd>See the <a href="#event_beforeChange">description of the
+      same event</a> on editor instances.</dd>
+
+      <dt id="event_doc_cursorActivity"><code><strong>"cursorActivity"</strong> (doc: CodeMirror.Doc)</code></dt>
+      <dd>Fired whenever the cursor or selection in this document
+      changes.</dd>
+
+      <dt id="event_doc_beforeSelectionChange"><code><strong>"beforeSelectionChange"</strong> (doc: CodeMirror.Doc, selection: {head, anchor})</code></dt>
+      <dd>Equivalent to
+      the <a href="#event_beforeSelectionChange">event by the same
+      name</a> as fired on editor instances.</dd>
+    </dl>
+
+    <p>Line handles (as returned by, for
+    example, <a href="#getLineHandle"><code>getLineHandle</code></a>)
+    support these events:</p>
+
+    <dl>
+      <dt id="event_delete"><code><strong>"delete"</strong> ()</code></dt>
+      <dd>Will be fired when the line object is deleted. A line object
+      is associated with the <em>start</em> of the line. Mostly useful
+      when you need to find out when your <a href="#setGutterMarker">gutter
+      markers</a> on a given line are removed.</dd>
+      <dt id="event_line_change"><code><strong>"change"</strong> (line: LineHandle, changeObj: object)</code></dt>
+      <dd>Fires when the line's text content is changed in any way
+      (but the line is not deleted outright). The <code>change</code>
+      object is similar to the one passed
+      to <a href="#event_change">change event</a> on the editor
+      object.</dd>
+    </dl>
+
+    <p>Marked range handles (<code>CodeMirror.TextMarker</code>), as returned
+    by <a href="#markText"><code>markText</code></a>
+    and <a href="#setBookmark"><code>setBookmark</code></a>, emit the
+    following events:</p>
+
+    <dl>
+      <dt id="event_beforeCursorEnter"><code><strong>"beforeCursorEnter"</strong> ()</code></dt>
+      <dd>Fired when the cursor enters the marked range. From this
+      event handler, the editor state may be inspected
+      but <em>not</em> modified, with the exception that the range on
+      which the event fires may be cleared.</dd>
+      <dt id="event_clear"><code><strong>"clear"</strong> (from: {line, ch}, to: {line, ch})</code></dt>
+      <dd>Fired when the range is cleared, either through cursor
+      movement in combination
+      with <a href="#mark_clearOnEnter"><code>clearOnEnter</code></a>
+      or through a call to its <code>clear()</code> method. Will only
+      be fired once per handle. Note that deleting the range through
+      text editing does not fire this event, because an undo action
+      might bring the range back into existence. <code>from</code>
+      and <code>to</code> give the part of the document that the range
+      spanned when it was cleared.</dd>
+      <dt id="event_hide"><code><strong>"hide"</strong> ()</code></dt>
+      <dd>Fired when the last part of the marker is removed from the
+      document by editing operations.</dd>
+      <dt id="event_unhide"><code><strong>"unhide"</strong> ()</code></dt>
+      <dd>Fired when, after the marker was removed by editing, a undo
+      operation brought the marker back.</dd>
+    </dl>
+
+    <p>Line widgets (<code>CodeMirror.LineWidget</code>), returned
+    by <a href="#addLineWidget"><code>addLineWidget</code></a>, fire
+    these events:</p>
+
+    <dl>
+      <dt id="event_redraw"><code><strong>"redraw"</strong> ()</code></dt>
+      <dd>Fired whenever the editor re-adds the widget to the DOM.
+      This will happen once right after the widget is added (if it is
+      scrolled into view), and then again whenever it is scrolled out
+      of view and back in again, or when changes to the editor options
+      or the line the widget is on require the widget to be
+      redrawn.</dd>
+    </dl>
+</section>
+
+<section id=keymaps>
+    <h2>Key Maps</h2>
+
+    <p>Key maps are ways to associate keys with functionality. A key map
+    is an object mapping strings that identify the keys to functions
+    that implement their functionality.</p>
+
+    <p>The CodeMirror distributions comes
+    with <a href="../demo/emacs.html">Emacs</a>, <a href="../demo/vim.html">Vim</a>,
+    and <a href="../demo/sublime.html">Sublime Text</a>-style keymaps.</p>
+
+    <p>Keys are identified either by name or by character.
+    The <code>CodeMirror.keyNames</code> object defines names for
+    common keys and associates them with their key codes. Examples of
+    names defined here are <code>Enter</code>, <code>F5</code>,
+    and <code>Q</code>. These can be prefixed
+    with <code>Shift-</code>, <code>Cmd-</code>, <code>Ctrl-</code>,
+    and <code>Alt-</code> (in that order!) to specify a modifier. So
+    for example, <code>Shift-Ctrl-Space</code> would be a valid key
+    identifier.</p>
+
+    <p>Common example: map the Tab key to insert spaces instead of a tab
+    character.</p>
+
+    <pre data-lang="javascript">
+{
+  Tab: function(cm) {
+    var spaces = Array(cm.getOption("indentUnit") + 1).join(" ");
+    cm.replaceSelection(spaces);
+  }
+}</pre>
+
+    <p>Alternatively, a character can be specified directly by
+    surrounding it in single quotes, for example <code>'$'</code>
+    or <code>'q'</code>. Due to limitations in the way browsers fire
+    key events, these may not be prefixed with modifiers.</p>
+
+    <p>The <code>CodeMirror.keyMap</code> object associates key maps
+    with names. User code and key map definitions can assign extra
+    properties to this object. Anywhere where a key map is expected, a
+    string can be given, which will be looked up in this object. It
+    also contains the <code>"default"</code> key map holding the
+    default bindings.</p>
+
+    <p>The values of properties in key maps can be either functions of
+    a single argument (the CodeMirror instance), strings, or
+    <code>false</code>. Strings refer
+    to <a href="#commands">commands</a>, which are described below. If
+    the property is set to <code>false</code>, CodeMirror leaves
+    handling of the key up to the browser. A key handler function may
+    return <code>CodeMirror.Pass</code> to indicate that it has
+    decided not to handle the key, and other handlers (or the default
+    behavior) should be given a turn.</p>
+
+    <p>Keys mapped to command names that start with the
+    characters <code>"go"</code> (which should be used for
+    cursor-movement actions) will be fired even when an
+    extra <code>Shift</code> modifier is present (i.e. <code>"Up":
+    "goLineUp"</code> matches both up and shift-up). This is used to
+    easily implement shift-selection.</p>
+
+    <p>Key maps can defer to each other by defining
+    a <code>fallthrough</code> property. This indicates that when a
+    key is not found in the map itself, one or more other maps should
+    be searched. It can hold either a single key map or an array of
+    key maps.</p>
+
+    <p>When a key map contains a <code>nofallthrough</code> property
+    set to <code>true</code>, keys matched against that map will be
+    ignored if they don't match any of the bindings in the map (no
+    further child maps will be tried). When
+    the <code>disableInput</code> property is set
+    to <code>true</code>, the default effect of inserting a character
+    will be suppressed when the key map is active as the top-level
+    map.</p>
+</section>
+
+<section id=commands>
+    <h2>Commands</h2>
+
+    <p>Commands are parameter-less actions that can be performed on an
+    editor. Their main use is for key bindings. Commands are defined by
+    adding properties to the <code>CodeMirror.commands</code> object.
+    A number of common commands are defined by the library itself,
+    most of them used by the default key bindings. The value of a
+    command property must be a function of one argument (an editor
+    instance).</p>
+
+    <p>Some of the commands below are referenced in the default
+    key map, but not defined by the core library. These are intended to
+    be defined by user code or addons.</p>
+
+    <p>Commands can also be run with
+    the <a href="#execCommand"><code>execCommand</code></a>
+    method.</p>
+
+    <dl>
+      <dt class=command id=command_selectAll><code><strong>selectAll</strong></code><span class=keybinding>Ctrl-A (PC), Cmd-A (Mac)</span></dt>
+      <dd>Select the whole content of the editor.</dd>
+
+      <dt class=command id=command_singleSelection><code><strong>singleSelection</strong></code><span class=keybinding>Esc</span></dt>
+      <dd>When multiple selections are present, this deselects all but
+      the primary selection.</dd>
+
+      <dt class=command id=command_killLine><code><strong>killLine</strong></code><span class=keybinding>Ctrl-K (Mac)</span></dt>
+      <dd>Emacs-style line killing. Deletes the part of the line after
+      the cursor. If that consists only of whitespace, the newline at
+      the end of the line is also deleted.</dd>
+
+      <dt class=command id=command_deleteLine><code><strong>deleteLine</strong></code><span class=keybinding>Ctrl-D (PC), Cmd-D (Mac)</span></dt>
+      <dd>Deletes the whole line under the cursor, including newline at the end.</dd>
+
+      <dt class=command id=command_delLineLeft><code><strong>delLineLeft</strong></code><span class=keybinding>Cmd-Backspace (Mac)</span></dt>
+      <dd>Delete the part of the line before the cursor.</dd>
+
+      <dt class=command id=command_undo><code><strong>undo</strong></code><span class=keybinding>Ctrl-Z (PC), Cmd-Z (Mac)</span></dt>
+      <dd>Undo the last change.</dd>
+
+      <dt class=command id=command_redo><code><strong>redo</strong></code><span class=keybinding>Ctrl-Y (PC), Shift-Cmd-Z (Mac), Cmd-Y (Mac)</span></dt>
+      <dd>Redo the last undone change.</dd>
+
+      <dt class=command id=command_undoSelection><code><strong>undoSelection</strong></code><span class=keybinding>Ctrl-U (PC), Cmd-U (Mac)</span></dt>
+      <dd>Undo the last change to the selection, or if there are no
+      selection-only changes at the top of the history, undo the last
+      change.</dd>
+
+      <dt class=command id=command_redoSelection><code><strong>redoSelection</strong></code><span class=keybinding>Alt-U (PC), Shift-Cmd-U (Mac)</span></dt>
+      <dd>Redo the last change to the selection, or the last text change if
+      no selection changes remain.</dd>
+
+      <dt class=command id=command_goDocStart><code><strong>goDocStart</strong></code><span class=keybinding>Ctrl-Up (PC), Cmd-Up (Mac)</span></dt>
+      <dd>Move the cursor to the start of the document.</dd>
+
+      <dt class=command id=command_goDocEnd><code><strong>goDocEnd</strong></code><span class=keybinding>Ctrl-Down (PC), Cmd-End (Mac), Cmd-Down (Mac)</span></dt>
+      <dd>Move the cursor to the end of the document.</dd>
+
+      <dt class=command id=command_goLineStart><code><strong>goLineStart</strong></code><span class=keybinding>Alt-Left (PC), Cmd-Left (Mac), Ctrl-A (Mac)</span></dt>
+      <dd>Move the cursor to the start of the line.</dd>
+
+      <dt class=command id=command_goLineStartSmart><code><strong>goLineStartSmart</strong></code><span class=keybinding>Home</span></dt>
+      <dd>Move to the start of the text on the line, or if we are
+      already there, to the actual start of the line (including
+      whitespace).</dd>
+
+      <dt class=command id=command_goLineEnd><code><strong>goLineEnd</strong></code><span class=keybinding>Alt-Right (PC), Cmd-Right (Mac), Ctrl-E (Mac)</span></dt>
+      <dd>Move the cursor to the end of the line.</dd>
+
+      <dt class=command id=command_goLineLeft><code><strong>goLineLeft</strong></code></dt>
+      <dd>Move the cursor to the left side of the visual line it is on. If
+      this line is wrapped, that may not be the start of the line.</dd>
+
+      <dt class=command id=command_goLineRight><code><strong>goLineRight</strong></code></dt>
+      <dd>Move the cursor to the right side of the visual line it is on.</dd>
+
+      <dt class=command id=command_goLineUp><code><strong>goLineUp</strong></code><span class=keybinding>Up, Ctrl-P (Mac)</span></dt>
+      <dd>Move the cursor up one line.</dd>
+
+      <dt class=command id=command_goLineDown><code><strong>goLineDown</strong></code><span class=keybinding>Down, Ctrl-N (Mac)</span></dt>
+      <dd>Move down one line.</dd>
+
+      <dt class=command id=command_goPageUp><code><strong>goPageUp</strong></code><span class=keybinding>PageUp, Shift-Ctrl-V (Mac)</span></dt>
+      <dd>Move the cursor up one screen, and scroll up by the same distance.</dd>
+
+      <dt class=command id=command_goPageDown><code><strong>goPageDown</strong></code><span class=keybinding>PageDown, Ctrl-V (Mac)</span></dt>
+      <dd>Move the cursor down one screen, and scroll down by the same distance.</dd>
+
+      <dt class=command id=command_goCharLeft><code><strong>goCharLeft</strong></code><span class=keybinding>Left, Ctrl-B (Mac)</span></dt>
+      <dd>Move the cursor one character left, going to the previous line
+      when hitting the start of line.</dd>
+
+      <dt class=command id=command_goCharRight><code><strong>goCharRight</strong></code><span class=keybinding>Right, Ctrl-F (Mac)</span></dt>
+      <dd>Move the cursor one character right, going to the next line
+      when hitting the end of line.</dd>
+
+      <dt class=command id=command_goColumnLeft><code><strong>goColumnLeft</strong></code></dt>
+      <dd>Move the cursor one character left, but don't cross line boundaries.</dd>
+
+      <dt class=command id=command_goColumnRight><code><strong>goColumnRight</strong></code></dt>
+      <dd>Move the cursor one character right, don't cross line boundaries.</dd>
+
+      <dt class=command id=command_goWordLeft><code><strong>goWordLeft</strong></code><span class=keybinding>Alt-B (Mac)</span></dt>
+      <dd>Move the cursor to the start of the previous word.</dd>
+
+      <dt class=command id=command_goWordRight><code><strong>goWordRight</strong></code><span class=keybinding>Alt-F (Mac)</span></dt>
+      <dd>Move the cursor to the end of the next word.</dd>
+
+      <dt class=command id=command_goGroupLeft><code><strong>goGroupLeft</strong></code><span class=keybinding>Ctrl-Left (PC), Alt-Left (Mac)</span></dt>
+      <dd>Move to the left of the group before the cursor. A group is
+      a stretch of word characters, a stretch of punctuation
+      characters, a newline, or a stretch of <em>more than one</em>
+      whitespace character.</dd>
+
+      <dt class=command id=command_goGroupRight><code><strong>goGroupRight</strong></code><span class=keybinding>Ctrl-Right (PC), Alt-Right (Mac)</span></dt>
+      <dd>Move to the right of the group after the cursor
+      (see <a href="#command_goGroupLeft">above</a>).</dd>
+
+      <dt class=command id=command_delCharBefore><code><strong>delCharBefore</strong></code><span class=keybinding>Shift-Backspace, Ctrl-H (Mac)</span></dt>
+      <dd>Delete the character before the cursor.</dd>
+
+      <dt class=command id=command_delCharAfter><code><strong>delCharAfter</strong></code><span class=keybinding>Delete, Ctrl-D (Mac)</span></dt>
+      <dd>Delete the character after the cursor.</dd>
+
+      <dt class=command id=command_delWordBefore><code><strong>delWordBefore</strong></code><span class=keybinding>Alt-Backspace (Mac)</span></dt>
+      <dd>Delete up to the start of the word before the cursor.</dd>
+
+      <dt class=command id=command_delWordAfter><code><strong>delWordAfter</strong></code><span class=keybinding>Alt-D (Mac)</span></dt>
+      <dd>Delete up to the end of the word after the cursor.</dd>
+
+      <dt class=command id=command_delGroupBefore><code><strong>delGroupBefore</strong></code><span class=keybinding>Ctrl-Backspace (PC), Alt-Backspace (Mac)</span></dt>
+      <dd>Delete to the left of the <a href="#command_goGroupLeft">group</a> before the cursor.</dd>
+
+      <dt class=command id=command_delGroupAfter><code><strong>delGroupAfter</strong></code><span class=keybinding>Ctrl-Delete (PC), Ctrl-Alt-Backspace (Mac), Alt-Delete (Mac)</span></dt>
+      <dd>Delete to the start of the <a href="#command_goGroupLeft">group</a> after the cursor.</dd>
+
+      <dt class=command id=command_indentAuto><code><strong>indentAuto</strong></code><span class=keybinding>Shift-Tab</span></dt>
+      <dd>Auto-indent the current line or selection.</dd>
+
+      <dt class=command id=command_indentMore><code><strong>indentMore</strong></code><span class=keybinding>Ctrl-] (PC), Cmd-] (Mac)</span></dt>
+      <dd>Indent the current line or selection by one <a href="#option_indentUnit">indent unit</a>.</dd>
+
+      <dt class=command id=command_indentLess><code><strong>indentLess</strong></code><span class=keybinding>Ctrl-[ (PC), Cmd-[ (Mac)</span></dt>
+      <dd>Dedent the current line or selection by one <a href="#option_indentUnit">indent unit</a>.</dd>
+
+      <dt class=command id=command_insertTab><code><strong>insertTab</strong></code></dt>
+      <dd>Insert a tab character at the cursor.</dd>
+
+      <dt class=command id=command_defaultTab><code><strong>defaultTab</strong></code><span class=keybinding>Tab</span></dt>
+      <dd>If something is selected, indent it by
+      one <a href="#option_indentUnit">indent unit</a>. If nothing is
+      selected, insert a tab character.</dd>
+
+      <dt class=command id=command_transposeChars><code><strong>transposeChars</strong></code><span class=keybinding>Ctrl-T (Mac)</span></dt>
+      <dd>Swap the characters before and after the cursor.</dd>
+
+      <dt class=command id=command_newlineAndIndent><code><strong>newlineAndIndent</strong></code><span class=keybinding>Enter</span></dt>
+      <dd>Insert a newline and auto-indent the new line.</dd>
+
+      <dt class=command id=command_toggleOverwrite><code><strong>toggleOverwrite</strong></code><span class=keybinding>Insert</span></dt>
+      <dd>Flip the <a href="#toggleOverwrite">overwrite</a> flag.</dd>
+
+      <dt class=command id=command_save><code><strong>save</strong></code><span class=keybinding>Ctrl-S (PC), Cmd-S (Mac)</span></dt>
+      <dd>Not defined by the core library, only referred to in
+      key maps. Intended to provide an easy way for user code to define
+      a save command.</dd>
+
+      <dt class=command id=command_find><code><strong>find</strong></code><span class=keybinding>Ctrl-F (PC), Cmd-F (Mac)</span></dt>
+      <dt class=command id=command_findNext><code><strong>findNext</strong></code><span class=keybinding>Ctrl-G (PC), Cmd-G (Mac)</span></dt>
+      <dt class=command id=command_findPrev><code><strong>findPrev</strong></code><span class=keybinding>Shift-Ctrl-G (PC), Shift-Cmd-G (Mac)</span></dt>
+      <dt class=command id=command_replace><code><strong>replace</strong></code><span class=keybinding>Shift-Ctrl-F (PC), Cmd-Alt-F (Mac)</span></dt>
+      <dt class=command id=command_replaceAll><code><strong>replaceAll</strong></code><span class=keybinding>Shift-Ctrl-R (PC), Shift-Cmd-Alt-F (Mac)</span></dt>
+      <dd>Not defined by the core library, but defined in
+      the <a href="#addon_search">search addon</a> (or custom client
+      addons).</dd>
+
+    </dl>
+
+</section>
+
+<section id=styling>
+    <h2>Customized Styling</h2>
+
+    <p>Up to a certain extent, CodeMirror's look can be changed by
+    modifying style sheet files. The style sheets supplied by modes
+    simply provide the colors for that mode, and can be adapted in a
+    very straightforward way. To style the editor itself, it is
+    possible to alter or override the styles defined
+    in <a href="../lib/codemirror.css"><code>codemirror.css</code></a>.</p>
+
+    <p>Some care must be taken there, since a lot of the rules in this
+    file are necessary to have CodeMirror function properly. Adjusting
+    colors should be safe, of course, and with some care a lot of
+    other things can be changed as well. The CSS classes defined in
+    this file serve the following roles:</p>
+
+    <dl>
+      <dt id="class_CodeMirror"><code><strong>CodeMirror</strong></code></dt>
+      <dd>The outer element of the editor. This should be used for the
+      editor width, height, borders and positioning. Can also be used
+      to set styles that should hold for everything inside the editor
+      (such as font and font size), or to set a background.</dd>
+
+      <dt id="class_CodeMirror_scroll"><code><strong>CodeMirror-scroll</strong></code></dt>
+      <dd>Whether the editor scrolls (<code>overflow: auto</code> +
+      fixed height). By default, it does. Setting
+      the <code>CodeMirror</code> class to have <code>height:
+      auto</code> and giving this class <code>overflow-x: auto;
+      overflow-y: hidden;</code> will cause the editor
+      to <a href="../demo/resize.html">resize to fit its
+      content</a>.</dd>
+
+      <dt id="class_CodeMirror_focused"><code><strong>CodeMirror-focused</strong></code></dt>
+      <dd>Whenever the editor is focused, the top element gets this
+      class. This is used to hide the cursor and give the selection a
+      different color when the editor is not focused.</dd>
+
+      <dt id="class_CodeMirror_gutters"><code><strong>CodeMirror-gutters</strong></code></dt>
+      <dd>This is the backdrop for all gutters. Use it to set the
+      default gutter background color, and optionally add a border on
+      the right of the gutters.</dd>
+
+      <dt id="class_CodeMirror_linenumbers"><code><strong>CodeMirror-linenumbers</strong></code></dt>
+      <dd>Use this for giving a background or width to the line number
+      gutter.</dd>
+
+      <dt id="class_CodeMirror_linenumber"><code><strong>CodeMirror-linenumber</strong></code></dt>
+      <dd>Used to style the actual individual line numbers. These
+      won't be children of the <code>CodeMirror-linenumbers</code>
+      (plural) element, but rather will be absolutely positioned to
+      overlay it. Use this to set alignment and text properties for
+      the line numbers.</dd>
+
+      <dt id="class_CodeMirror_lines"><code><strong>CodeMirror-lines</strong></code></dt>
+      <dd>The visible lines. This is where you specify vertical
+      padding for the editor content.</dd>
+
+      <dt id="class_CodeMirror_cursor"><code><strong>CodeMirror-cursor</strong></code></dt>
+      <dd>The cursor is a block element that is absolutely positioned.
+      You can make it look whichever way you want.</dd>
+
+      <dt id="class_CodeMirror_selected"><code><strong>CodeMirror-selected</strong></code></dt>
+      <dd>The selection is represented by <code>span</code> elements
+      with this class.</dd>
+
+      <dt id="class_CodeMirror_matchingbracket"><code><strong>CodeMirror-matchingbracket</strong></code>,
+        <code><strong>CodeMirror-nonmatchingbracket</strong></code></dt>
+      <dd>These are used to style matched (or unmatched) brackets.</dd>
+    </dl>
+
+    <p>If your page's style sheets do funky things to
+    all <code>div</code> or <code>pre</code> elements (you probably
+    shouldn't do that), you'll have to define rules to cancel these
+    effects out again for elements under the <code>CodeMirror</code>
+    class.</p>
+
+    <p>Themes are also simply CSS files, which define colors for
+    various syntactic elements. See the files in
+    the <a href="../theme/"><code>theme</code></a> directory.</p>
+</section>
+
+<section id=api>
+    <h2>Programming API</h2>
+
+    <p>A lot of CodeMirror features are only available through its
+    API. Thus, you need to write code (or
+    use <a href="#addons">addons</a>) if you want to expose them to
+    your users.</p>
+
+    <p>Whenever points in the document are represented, the API uses
+    objects with <code>line</code> and <code>ch</code> properties.
+    Both are zero-based. CodeMirror makes sure to 'clip' any positions
+    passed by client code so that they fit inside the document, so you
+    shouldn't worry too much about sanitizing your coordinates. If you
+    give <code>ch</code> a value of <code>null</code>, or don't
+    specify it, it will be replaced with the length of the specified
+    line.</p>
+
+    <p>Methods prefixed with <code>doc.</code> can, unless otherwise
+    specified, be called both on <code>CodeMirror</code> (editor)
+    instances and <code>CodeMirror.Doc</code> instances. Methods
+    prefixed with <code>cm.</code> are <em>only</em> available
+    on <code>CodeMirror</code> instances.</p>
+
+    <h3 id="api_constructor">Constructor</h3>
+
+    <p id="CodeMirror">Constructing an editor instance is done with
+    the <code><strong>CodeMirror</strong>(place: Element|fn(Element),
+    ?option: object)</code> constructor. If the <code>place</code>
+    argument is a DOM element, the editor will be appended to it. If
+    it is a function, it will be called, and is expected to place the
+    editor into the document. <code>options</code> may be an element
+    mapping <a href="#config">option names</a> to values. The options
+    that it doesn't explicitly specify (or all options, if it is not
+    passed) will be taken
+    from <a href="#defaults"><code>CodeMirror.defaults</code></a>.</p>
+
+    <p>Note that the options object passed to the constructor will be
+    mutated when the instance's options
+    are <a href="#setOption">changed</a>, so you shouldn't share such
+    objects between instances.</p>
+
+    <p>See <a href="#fromTextArea"><code>CodeMirror.fromTextArea</code></a>
+    for another way to construct an editor instance.</p>
+
+    <h3 id="api_content">Content manipulation methods</h3>
+
+    <dl>
+      <dt id="getValue"><code><strong>doc.getValue</strong>(?separator: string) → string</code></dt>
+      <dd>Get the current editor content. You can pass it an optional
+      argument to specify the string to be used to separate lines
+      (defaults to <code>"\n"</code>).</dd>
+      <dt id="setValue"><code><strong>doc.setValue</strong>(content: string)</code></dt>
+      <dd>Set the editor content.</dd>
+
+      <dt id="getRange"><code><strong>doc.getRange</strong>(from: {line, ch}, to: {line, ch}, ?separator: string) → string</code></dt>
+      <dd>Get the text between the given points in the editor, which
+      should be <code>{line, ch}</code> objects. An optional third
+      argument can be given to indicate the line separator string to
+      use (defaults to <code>"\n"</code>).</dd>
+      <dt id="replaceRange"><code><strong>doc.replaceRange</strong>(replacement: string, from: {line, ch}, to: {line, ch}, ?origin: string)</code></dt>
+      <dd>Replace the part of the document between <code>from</code>
+      and <code>to</code> with the given string. <code>from</code>
+      and <code>to</code> must be <code>{line, ch}</code>
+      objects. <code>to</code> can be left off to simply insert the
+      string at position <code>from</code>. When <code>origin</code>
+      is given, it will be passed on
+      to <a href="#event_change"><code>"change"</code> events</a>, and
+      its first letter will be used to determine whether this change
+      can be merged with previous history events, in the way described
+      for <a href="#selection_origin">selection origins</a>.</dd>
+
+      <dt id="getLine"><code><strong>doc.getLine</strong>(n: integer) → string</code></dt>
+      <dd>Get the content of line <code>n</code>.</dd>
+
+      <dt id="lineCount"><code><strong>doc.lineCount</strong>() → integer</code></dt>
+      <dd>Get the number of lines in the editor.</dd>
+      <dt id="firstLine"><code><strong>doc.firstLine</strong>() → integer</code></dt>
+      <dd>Get the first line of the editor. This will
+      usually be zero but for <a href="#linkedDoc_from">linked sub-views</a>,
+      or <a href="#api_doc">documents</a> instantiated with a non-zero
+      first line, it might return other values.</dd>
+      <dt id="lastLine"><code><strong>doc.lastLine</strong>() → integer</code></dt>
+      <dd>Get the last line of the editor. This will
+      usually be <code>doc.lineCount() - 1</code>,
+      but for <a href="#linkedDoc_from">linked sub-views</a>,
+      it might return other values.</dd>
+
+      <dt id="getLineHandle"><code><strong>doc.getLineHandle</strong>(num: integer) → LineHandle</code></dt>
+      <dd>Fetches the line handle for the given line number.</dd>
+      <dt id="getLineNumber"><code><strong>doc.getLineNumber</strong>(handle: LineHandle) → integer</code></dt>
+      <dd>Given a line handle, returns the current position of that
+      line (or <code>null</code> when it is no longer in the
+      document).</dd>
+      <dt id="eachLine"><code><strong>doc.eachLine</strong>(f: (line: LineHandle))</code></dt>
+      <dt><code><strong>doc.eachLine</strong>(start: integer, end: integer, f: (line: LineHandle))</code></dt>
+      <dd>Iterate over the whole document, or if <code>start</code>
+      and <code>end</code> line numbers are given, the range
+      from <code>start</code> up to (not including) <code>end</code>,
+      and call <code>f</code> for each line, passing the line handle.
+      This is a faster way to visit a range of line handlers than
+      calling <a href="#getLineHandle"><code>getLineHandle</code></a>
+      for each of them. Note that line handles have
+      a <code>text</code> property containing the line's content (as a
+      string).</dd>
+
+      <dt id="markClean"><code><strong>doc.markClean</strong>()</code></dt>
+      <dd>Set the editor content as 'clean', a flag that it will
+      retain until it is edited, and which will be set again when such
+      an edit is undone again. Useful to track whether the content
+      needs to be saved. This function is deprecated in favor
+      of <a href="#changeGeneration"><code>changeGeneration</code></a>,
+      which allows multiple subsystems to track different notions of
+      cleanness without interfering.</dd>
+      <dt id="changeGeneration"><code><strong>doc.changeGeneration</strong>(?closeEvent: boolean) → integer</code></dt>
+      <dd>Returns a number that can later be passed
+      to <a href="#isClean"><code>isClean</code></a> to test whether
+      any edits were made (and not undone) in the meantime.
+      If <code>closeEvent</code> is true, the current history event
+      will be ‘closed’, meaning it can't be combined with further
+      changes (rapid typing or deleting events are typically
+      combined).</dd>
+      <dt id="isClean"><code><strong>doc.isClean</strong>(?generation: integer) → boolean</code></dt>
+      <dd>Returns whether the document is currently clean — not
+      modified since initialization or the last call
+      to <a href="#markClean"><code>markClean</code></a> if no
+      argument is passed, or since the matching call
+      to <a href="#changeGeneration"><code>changeGeneration</code></a>
+      if a generation value is given.</dd>
+    </dl>
+
+    <h3 id="api_selection">Cursor and selection methods</h3>
+
+    <dl>
+      <dt id="getSelection"><code><strong>doc.getSelection</strong>(?lineSep: string) → string</code></dt>
+      <dd>Get the currently selected code. Optionally pass a line
+      separator to put between the lines in the output. When multiple
+      selections are present, they are concatenated with instances
+      of <code>lineSep</code> in between.</dd>
+      <dt id="getSelections"><code><strong>doc.getSelections</strong>(?lineSep: string) → string</code></dt>
+      <dd>Returns an array containing a string for each selection,
+      representing the content of the selections.</dd>
+
+      <dt id="replaceSelection"><code><strong>doc.replaceSelection</strong>(replacement: string, ?select: string)</code></dt>
+      <dd>Replace the selection(s) with the given string. By default,
+      the new selection ends up after the inserted text. The
+      optional <code>select</code> argument can be used to change
+      this—passing <code>"around"</code> will cause the new text to be
+      selected, passing <code>"start"</code> will collapse the
+      selection to the start of the inserted text.</dd>
+      <dt id="replaceSelections"><code><strong>doc.replaceSelections</strong>(replacements: array<string>, ?select: string)</code></dt>
+      <dd>The length of the given array should be the same as the
+      number of active selections. Replaces the content of the
+      selections with the strings in the array.
+      The <code>select</code> argument works the same as
+      in <a href="#replaceSelection"><code>replaceSelection</code></a>.</dd>
+
+      <dt id="getCursor"><code><strong>doc.getCursor</strong>(?start: string) → {line, ch}</code></dt>
+      <dd>Retrieve one end of the <em>primary</em>
+      selection. <code>start</code> is a an optional string indicating
+      which end of the selection to return. It may
+      be <code>"from"</code>, <code>"to"</code>, <code>"head"</code>
+      (the side of the selection that moves when you press
+      shift+arrow), or <code>"anchor"</code> (the fixed side of the
+      selection). Omitting the argument is the same as
+      passing <code>"head"</code>. A <code>{line, ch}</code> object
+      will be returned.</dd>
+      <dt id="listSelections"><code><strong>doc.listSelections</strong>() → array<{anchor, head}<</code></dt>
+      <dd>Retrieves a list of all current selections. These will
+      always be sorted, and never overlap (overlapping selections are
+      merged). Each object in the array contains <code>anchor</code>
+      and <code>head</code> properties referring to <code>{line,
+      ch}</code> objects.</dd>
+      
+      <dt id="somethingSelected"><code><strong>doc.somethingSelected</strong>() → boolean</code></dt>
+      <dd>Return true if any text is selected.</dd>
+      <dt id="setCursor"><code><strong>doc.setCursor</strong>(pos: {line, ch}|number, ?ch: number, ?options: object)</code></dt>
+      <dd>Set the cursor position. You can either pass a
+      single <code>{line, ch}</code> object, or the line and the
+      character as two separate parameters. Will replace all
+      selections with a single, empty selection at the given position.
+      The supported options are the same as for <a href="#setSelection"><code>setSelection</code></a>.</dd>
+
+      <dt id="setSelection"><code><strong>doc.setSelection</strong>(anchor: {line, ch}, ?head: {line, ch}, ?options: object)</code></dt>
+      <dd>Set a single selection range. <code>anchor</code>
+      and <code>head</code> should be <code>{line, ch}</code>
+      objects. <code>head</code> defaults to <code>anchor</code> when
+      not given. These options are supported:
+      <dl>
+        <dt id="selection_scroll"><code><strong>scroll</strong>: boolean</code></dt>
+        <dd>Determines whether the selection head should be scrolled
+        into view. Defaults to true.</dd>
+        <dt id="selection_origin"><code><strong>origin</strong>: string</code></dt>
+        <dd>Detemines whether the selection history event may be
+        merged with the previous one. When an origin starts with the
+        character <code>+</code>, and the last recorded selection had
+        the same origin and was similar (close
+        in <a href="#option_historyEventDelay">time</a>, both
+        collapsed or both non-collapsed), the new one will replace the
+        old one. When it starts with <code>*</code>, it will always
+        replace the previous event (if that had the same origin).
+        Built-in motion uses the <code>"+move"</code> origin.</dd>
+      </dl></dd>
+
+      <dt id="setSelections"><code><strong>doc.setSelections</strong>(ranges: array<{anchor, head}>, ?primary: integer, ?options: object)</code></dt>
+      <dd>Sets a new set of selections. There must be at least one
+      selection in the given array. When <code>primary</code> is a
+      number, it determines which selection is the primary one. When
+      it is not given, the primary index is taken from the previous
+      selection, or set to the last range if the previous selection
+      had less ranges than the new one. Supports the same options
+      as <a href="#setSelection"><code>setSelection</code></a>.</dd>
+      <dt id="addSelection"><code><strong>doc.addSelection</strong>(anchor: {line, ch}, ?head: {line, ch})</code></dt>
+      <dd>Adds a new selection to the existing set of selections, and
+      makes it the primary selection.</dd>
+
+      <dt id="extendSelection"><code><strong>doc.extendSelection</strong>(from: {line, ch}, ?to: {line, ch}, ?options: object)</code></dt>
+      <dd>Similar
+      to <a href="#setSelection"><code>setSelection</code></a>, but
+      will, if shift is held or
+      the <a href="#setExtending">extending</a> flag is set, move the
+      head of the selection while leaving the anchor at its current
+      place. <code>to</code> is optional, and can be passed to ensure
+      a region (for example a word or paragraph) will end up selected
+      (in addition to whatever lies between that region and the
+      current anchor). When multiple selections are present, all but
+      the primary selection will be dropped by this method.
+      Supports the same options as <a href="#setSelection"><code>setSelection</code></a>.</dd>
+      <dt id="extendSelections"><code><strong>doc.extendSelections</strong>(heads: array<{line, ch}>, ?options: object)</code></dt>
+      <dd>An equivalent
+      of <a href="#extendSelection"><code>extendSelection</code></a>
+      that acts on all selections at once.</dd>
+      <dt id="extendSelectionsBy"><code><strong>doc.extendSelectionsBy</strong>(f: function(range: {anchor, head}) → {anchor, head}), ?options: object)</code></dt>
+      <dd>Applies the given function to all existing selections, and
+      calls <a href="#extendSelections"><code>extendSelections</code></a>
+      on the result.</dd>
+      <dt id="setExtending"><code><strong>doc.setExtending</strong>(value: boolean)</code></dt>
+      <dd>Sets or clears the 'extending' flag, which acts similar to
+      the shift key, in that it will cause cursor movement and calls
+      to <a href="#extendSelection"><code>extendSelection</code></a>
+      to leave the selection anchor in place.</dd>
+      <dt id="getExtending"><code><strong>doc.getExtending</strong>() → boolean</code></dt>
+      <dd>Get the value of the 'extending' flag.</dd>
+
+      <dt id="hasFocus"><code><strong>cm.hasFocus</strong>() → boolean</code></dt>
+      <dd>Tells you whether the editor currently has focus.</dd>
+
+      <dt id="findPosH"><code><strong>cm.findPosH</strong>(start: {line, ch}, amount: integer, unit: string, visually: boolean) → {line, ch, ?hitSide: boolean}</code></dt>
+      <dd>Used to find the target position for horizontal cursor
+      motion. <code>start</code> is a <code>{line, ch}</code>
+      object, <code>amount</code> an integer (may be negative),
+      and <code>unit</code> one of the
+      string <code>"char"</code>, <code>"column"</code>,
+      or <code>"word"</code>. Will return a position that is produced
+      by moving <code>amount</code> times the distance specified
+      by <code>unit</code>. When <code>visually</code> is true, motion
+      in right-to-left text will be visual rather than logical. When
+      the motion was clipped by hitting the end or start of the
+      document, the returned value will have a <code>hitSide</code>
+      property set to true.</dd>
+      <dt id="findPosV"><code><strong>cm.findPosV</strong>(start: {line, ch}, amount: integer, unit: string) → {line, ch, ?hitSide: boolean}</code></dt>
+      <dd>Similar to <a href="#findPosH"><code>findPosH</code></a>,
+      but used for vertical motion. <code>unit</code> may
+      be <code>"line"</code> or <code>"page"</code>. The other
+      arguments and the returned value have the same interpretation as
+      they have in <code>findPosH</code>.</dd>
+    </dl>
+
+    <h3 id="api_configuration">Configuration methods</h3>
+
+    <dl>
+      <dt id="setOption"><code><strong>cm.setOption</strong>(option: string, value: any)</code></dt>
+      <dd>Change the configuration of the editor. <code>option</code>
+      should the name of an <a href="#config">option</a>,
+      and <code>value</code> should be a valid value for that
+      option.</dd>
+      <dt id="getOption"><code><strong>cm.getOption</strong>(option: string) → any</code></dt>
+      <dd>Retrieves the current value of the given option for this
+      editor instance.</dd>
+
+      <dt id="addKeyMap"><code><strong>cm.addKeyMap</strong>(map: object, bottom: boolean)</code></dt>
+      <dd>Attach an additional <a href="#keymaps">key map</a> to the
+      editor. This is mostly useful for addons that need to register
+      some key handlers without trampling on
+      the <a href="#option_extraKeys"><code>extraKeys</code></a>
+      option. Maps added in this way have a higher precedence than
+      the <code>extraKeys</code>
+      and <a href="#option_keyMap"><code>keyMap</code></a> options,
+      and between them, the maps added earlier have a lower precedence
+      than those added later, unless the <code>bottom</code> argument
+      was passed, in which case they end up below other key maps added
+      with this method.</dd>
+      <dt id="removeKeyMap"><code><strong>cm.removeKeyMap</strong>(map: object)</code></dt>
+      <dd>Disable a keymap added
+      with <a href="#addKeyMap"><code>addKeyMap</code></a>. Either
+      pass in the key map object itself, or a string, which will be
+      compared against the <code>name</code> property of the active
+      key maps.</dd>
+
+      <dt id="addOverlay"><code><strong>cm.addOverlay</strong>(mode: string|object, ?options: object)</code></dt>
+      <dd>Enable a highlighting overlay. This is a stateless mini-mode
+      that can be used to add extra highlighting. For example,
+      the <a href="../demo/search.html">search addon</a> uses it to
+      highlight the term that's currently being
+      searched. <code>mode</code> can be a <a href="#option_mode">mode
+      spec</a> or a mode object (an object with
+      a <a href="#token"><code>token</code></a> method).
+      The <code>options</code> parameter is optional. If given, it
+      should be an object. Currently, only the <code>opaque</code>
+      option is recognized. This defaults to off, but can be given to
+      allow the overlay styling, when not <code>null</code>, to
+      override the styling of the base mode entirely, instead of the
+      two being applied together.</dd>
+      <dt id="removeOverlay"><code><strong>cm.removeOverlay</strong>(mode: string|object)</code></dt>
+      <dd>Pass this the exact value passed for the <code>mode</code>
+      parameter to <a href="#addOverlay"><code>addOverlay</code></a>,
+      or a string that corresponds to the <code>name</code> propery of
+      that value, to remove an overlay again.</dd>
+
+      <dt id="on"><code><strong>cm.on</strong>(type: string, func: (...args))</code></dt>
+      <dd>Register an event handler for the given event type (a
+      string) on the editor instance. There is also
+      a <code>CodeMirror.on(object, type, func)</code> version
+      that allows registering of events on any object.</dd>
+      <dt id="off"><code><strong>cm.off</strong>(type: string, func: (...args))</code></dt>
+      <dd>Remove an event handler on the editor instance. An
+      equivalent <code>CodeMirror.off(object, type,
+      func)</code> also exists.</dd>
+    </dl>
+
+    <h3 id="api_doc">Document management methods</h3>
+
+    <p id="Doc">Each editor is associated with an instance
+    of <code>CodeMirror.Doc</code>, its document. A document
+    represents the editor content, plus a selection, an undo history,
+    and a <a href="#option_mode">mode</a>. A document can only be
+    associated with a single editor at a time. You can create new
+    documents by calling the <code>CodeMirror.Doc(text, mode,
+    firstLineNumber)</code> constructor. The last two arguments are
+    optional and can be used to set a mode for the document and make
+    it start at a line number other than 0, respectively.</p>
+
+    <dl>
+      <dt id="getDoc"><code><strong>cm.getDoc</strong>() → Doc</code></dt>
+      <dd>Retrieve the currently active document from an editor.</dd>
+      <dt id="getEditor"><code><strong>doc.getEditor</strong>() → CodeMirror</code></dt>
+      <dd>Retrieve the editor associated with a document. May
+      return <code>null</code>.</dd>
+
+      <dt id="swapDoc"><code><strong>cm.swapDoc</strong>(doc: CodeMirror.Doc) → Doc</code></dt>
+      <dd>Attach a new document to the editor. Returns the old
+      document, which is now no longer associated with an editor.</dd>
+
+      <dt id="copy"><code><strong>doc.copy</strong>(copyHistory: boolean) → Doc</code></dt>
+      <dd>Create an identical copy of the given doc.
+      When <code>copyHistory</code> is true, the history will also be
+      copied. Can not be called directly on an editor.</dd>
+
+      <dt id="linkedDoc"><code><strong>doc.linkedDoc</strong>(options: object) → Doc</code></dt>
+      <dd>Create a new document that's linked to the target document.
+      Linked documents will stay in sync (changes to one are also
+      applied to the other) until <a href="#unlinkDoc">unlinked</a>.
+      These are the options that are supported:
+        <dl>
+          <dt id="linkedDoc_sharedHist"><code><strong>sharedHist</strong>: boolean</code></dt>
+          <dd>When turned on, the linked copy will share an undo
+          history with the original. Thus, something done in one of
+          the two can be undone in the other, and vice versa.</dd>
+          <dt id="linkedDoc_from"><code><strong>from</strong>: integer</code></dt>
+          <dt id="linkedDoc_to"><code><strong>to</strong>: integer</code></dt>
+          <dd>Can be given to make the new document a subview of the
+          original. Subviews only show a given range of lines. Note
+          that line coordinates inside the subview will be consistent
+          with those of the parent, so that for example a subview
+          starting at line 10 will refer to its first line as line 10,
+          not 0.</dd>
+          <dt id="linkedDoc_mode"><code><strong>mode</strong>: string|object</code></dt>
+          <dd>By default, the new document inherits the mode of the
+          parent. This option can be set to
+          a <a href="#option_mode">mode spec</a> to give it a
+          different mode.</dd>
+        </dl></dd>
+      <dt id="unlinkDoc"><code><strong>doc.unlinkDoc</strong>(doc: CodeMirror.Doc)</code></dt>
+      <dd>Break the link between two documents. After calling this,
+      changes will no longer propagate between the documents, and, if
+      they had a shared history, the history will become
+      separate.</dd>
+      <dt id="iterLinkedDocs"><code><strong>doc.iterLinkedDocs</strong>(function: (doc: CodeMirror.Doc, sharedHist: boolean))</code></dt>
+      <dd>Will call the given function for all documents linked to the
+      target document. It will be passed two arguments, the linked document
+      and a boolean indicating whether that document shares history
+      with the target.</dd>
+    </dl>
+
+    <h3 id="api_history">History-related methods</h3>
+
+    <dl>
+      <dt id="undo"><code><strong>doc.undo</strong>()</code></dt>
+      <dd>Undo one edit (if any undo events are stored).</dd>
+      <dt id="redo"><code><strong>doc.redo</strong>()</code></dt>
+      <dd>Redo one undone edit.</dd>
+
+      <dt id="undoSelection"><code><strong>doc.undoSelection</strong>()</code></dt>
+      <dd>Undo one edit or selection change.</dd>
+      <dt id="redoSelection"><code><strong>doc.redoSelection</strong>()</code></dt>
+      <dd>Redo one undone edit or selection change.</dd>
+
+      <dt id="historySize"><code><strong>doc.historySize</strong>() → {undo: integer, redo: integer}</code></dt>
+      <dd>Returns an object with <code>{undo, redo}</code> properties,
+      both of which hold integers, indicating the amount of stored
+      undo and redo operations.</dd>
+      <dt id="clearHistory"><code><strong>doc.clearHistory</strong>()</code></dt>
+      <dd>Clears the editor's undo history.</dd>
+      <dt id="getHistory"><code><strong>doc.getHistory</strong>() → object</code></dt>
+      <dd>Get a (JSON-serializeable) representation of the undo history.</dd>
+      <dt id="setHistory"><code><strong>doc.setHistory</strong>(history: object)</code></dt>
+      <dd>Replace the editor's undo history with the one provided,
+      which must be a value as returned
+      by <a href="#getHistory"><code>getHistory</code></a>. Note that
+      this will have entirely undefined results if the editor content
+      isn't also the same as it was when <code>getHistory</code> was
+      called.</dd>
+    </dl>
+
+    <h3 id="api_marker">Text-marking methods</h3>
+
+    <dl>
+      <dt id="markText"><code><strong>doc.markText</strong>(from: {line, ch}, to: {line, ch}, ?options: object) → TextMarker</code></dt>
+      <dd>Can be used to mark a range of text with a specific CSS
+      class name. <code>from</code> and <code>to</code> should
+      be <code>{line, ch}</code> objects. The <code>options</code>
+      parameter is optional. When given, it should be an object that
+      may contain the following configuration options:
+      <dl>
+        <dt id="mark_className"><code><strong>className</strong>: string</code></dt>
+        <dd>Assigns a CSS class to the marked stretch of text.</dd>
+        <dt id="mark_inclusiveLeft"><code><strong>inclusiveLeft</strong>: boolean</code></dt>
+        <dd>Determines whether
+        text inserted on the left of the marker will end up inside
+        or outside of it.</dd>
+        <dt id="mark_inclusiveRight"><code><strong>inclusiveRight</strong>: boolean</code></dt>
+        <dd>Like <code>inclusiveLeft</code>,
+        but for the right side.</dd>
+        <dt id="mark_atomic"><code><strong>atomic</strong>: boolean</code></dt>
+        <dd>Atomic ranges act as a single unit when cursor movement is
+        concerned—i.e. it is impossible to place the cursor inside of
+        them. In atomic ranges, <code>inclusiveLeft</code>
+        and <code>inclusiveRight</code> have a different meaning—they
+        will prevent the cursor from being placed respectively
+        directly before and directly after the range.</dd>
+        <dt id="mark_collapsed"><code><strong>collapsed</strong>: boolean</code></dt>
+        <dd>Collapsed ranges do not show up in the display. Setting a
+        range to be collapsed will automatically make it atomic.</dd>
+        <dt id="mark_clearOnEnter"><code><strong>clearOnEnter</strong>: boolean</code></dt>
+        <dd>When enabled, will cause the mark to clear itself whenever
+        the cursor enters its range. This is mostly useful for
+        text-replacement widgets that need to 'snap open' when the
+        user tries to edit them. The
+        <a href="#event_clear"><code>"clear"</code></a> event
+        fired on the range handle can be used to be notified when this
+        happens.</dd>
+        <dt id="mark_clearWhenEmpty"><code><strong>clearWhenEmpty</strong>: boolean</code></dt>
+        <dd>Determines whether the mark is automatically cleared when
+        it becomes empty. Default is true.</dd>
+        <dt id="mark_replacedWith"><code><strong>replacedWith</strong>: Element</code></dt>
+        <dd>Use a given node to display this range. Implies both
+        collapsed and atomic. The given DOM node <em>must</em> be an
+        inline element (as opposed to a block element).</dd>
+        <dt><code><strong>handleMouseEvents</strong>: boolean</code></dt>
+        <dd>When <code>replacedWith</code> is given, this determines
+        whether the editor will capture mouse and drag events
+        occurring in this widget. Default is false—the events will be
+        left alone for the default browser handler, or specific
+        handlers on the widget, to capture.</dd>
+        <dt id="mark_readOnly"><code><strong>readOnly</strong>: boolean</code></dt>
+        <dd>A read-only span can, as long as it is not cleared, not be
+        modified except by
+        calling <a href="#setValue"><code>setValue</code></a> to reset
+        the whole document. <em>Note:</em> adding a read-only span
+        currently clears the undo history of the editor, because
+        existing undo events being partially nullified by read-only
+        spans would corrupt the history (in the current
+        implementation).</dd>
+        <dt id="mark_addToHistory"><code><strong>addToHistory</strong>: boolean</code></dt>
+        <dd>When set to true (default is false), adding this marker
+        will create an event in the undo history that can be
+        individually undone (clearing the marker).</dd>
+        <dt id="mark_startStyle"><code><strong>startStyle</strong>: string</code></dt><dd>Can be used to specify
+        an extra CSS class to be applied to the leftmost span that
+        is part of the marker.</dd>
+        <dt id="mark_endStyle"><code><strong>endStyle</strong>: string</code></dt><dd>Equivalent
+        to <code>startStyle</code>, but for the rightmost span.</dd>
+        <dt id="mark_title"><code><strong>title</strong>:
+        string</code></dt><dd>When given, will give the nodes created
+        for this span a HTML <code>title</code> attribute with the
+        given value.</dd>
+        <dt id="mark_shared"><code><strong>shared</strong>: boolean</code></dt><dd>When the
+        target document is <a href="#linkedDoc">linked</a> to other
+        documents, you can set <code>shared</code> to true to make the
+        marker appear in all documents. By default, a marker appears
+        only in its target document.</dd>
+      </dl>
+      The method will return an object that represents the marker
+      (with constructor <code>CodeMirror.TextMarker</code>), which
+      exposes three methods:
+      <code><strong>clear</strong>()</code>, to remove the mark,
+      <code><strong>find</strong>()</code>, which returns
+      a <code>{from, to}</code> object (both holding document
+      positions), indicating the current position of the marked range,
+      or <code>undefined</code> if the marker is no longer in the
+      document, and finally <code><strong>changed</strong>()</code>,
+      which you can call if you've done something that might change
+      the size of the marker (for example changing the content of
+      a <a href="#mark_replacedWith"><code>replacedWith</code></a>
+      node), and want to cheaply update the display.</dd>
+
+      <dt id="setBookmark"><code><strong>doc.setBookmark</strong>(pos: {line, ch}, ?options: object) → TextMarker</code></dt>
+      <dd>Inserts a bookmark, a handle that follows the text around it
+      as it is being edited, at the given position. A bookmark has two
+      methods <code>find()</code> and <code>clear()</code>. The first
+      returns the current position of the bookmark, if it is still in
+      the document, and the second explicitly removes the bookmark.
+      The options argument is optional. If given, the following
+      properties are recognized:
+      <dl>
+        <dt><code><strong>widget</strong>: Element</code></dt><dd>Can be used to display a DOM
+        node at the current location of the bookmark (analogous to
+        the <a href="#mark_replacedWith"><code>replacedWith</code></a>
+        option to <a href="#markText"><code>markText</code></a>).</dd>
+        <dt><code><strong>insertLeft</strong>: boolean</code></dt><dd>By default, text typed
+        when the cursor is on top of the bookmark will end up to the
+        right of the bookmark. Set this option to true to make it go
+        to the left instead.</dd>
+        <dt><code><strong>shared</strong>: boolean</code></dt><dd>See
+        the corresponding <a href="#mark_shared">option</a>
+        to <code>markText</code>.</dd>
+      </dl></dd>
+
+      <dt id="findMarks"><code><strong>doc.findMarks</strong>(from: {line, ch}, to: {line, ch}) → array<TextMarker></code></dt>
+      <dd>Returns an array of all the bookmarks and marked ranges
+      found between the given positions.</dd>
+      <dt id="findMarksAt"><code><strong>doc.findMarksAt</strong>(pos: {line, ch}) → array<TextMarker></code></dt>
+      <dd>Returns an array of all the bookmarks and marked ranges
+      present at the given position.</dd>
+      <dt id="getAllMarks"><code><strong>doc.getAllMarks</strong>() → array<TextMarker></code></dt>
+      <dd>Returns an array containing all marked ranges in the document.</dd>
+    </dl>
+
+    <h3 id="api_decoration">Widget, gutter, and decoration methods</h3>
+
+    <dl>
+      <dt id="setGutterMarker"><code><strong>cm.setGutterMarker</strong>(line: integer|LineHandle, gutterID: string, value: Element) → LineHandle</code></dt>
+      <dd>Sets the gutter marker for the given gutter (identified by
+      its CSS class, see
+      the <a href="#option_gutters"><code>gutters</code></a> option)
+      to the given value. Value can be either <code>null</code>, to
+      clear the marker, or a DOM element, to set it. The DOM element
+      will be shown in the specified gutter next to the specified
+      line.</dd>
+
+      <dt id="clearGutter"><code><strong>cm.clearGutter</strong>(gutterID: string)</code></dt>
+      <dd>Remove all gutter markers in
+      the <a href="#option_gutters">gutter</a> with the given ID.</dd>
+
+      <dt id="addLineClass"><code><strong>cm.addLineClass</strong>(line: integer|LineHandle, where: string, class: string) → LineHandle</code></dt>
+      <dd>Set a CSS class name for the given line. <code>line</code>
+      can be a number or a line handle. <code>where</code> determines
+      to which element this class should be applied, can can be one
+      of <code>"text"</code> (the text element, which lies in front of
+      the selection), <code>"background"</code> (a background element
+      that will be behind the selection), or <code>"wrap"</code> (the
+      wrapper node that wraps all of the line's elements, including
+      gutter elements). <code>class</code> should be the name of the
+      class to apply.</dd>
+
+      <dt id="removeLineClass"><code><strong>cm.removeLineClass</strong>(line: integer|LineHandle, where: string, class: string) → LineHandle</code></dt>
+      <dd>Remove a CSS class from a line. <code>line</code> can be a
+      line handle or number. <code>where</code> should be one
+      of <code>"text"</code>, <code>"background"</code>,
+      or <code>"wrap"</code>
+      (see <a href="#addLineClass"><code>addLineClass</code></a>). <code>class</code>
+      can be left off to remove all classes for the specified node, or
+      be a string to remove only a specific class.</dd>
+
+      <dt id="lineInfo"><code><strong>cm.lineInfo</strong>(line: integer|LineHandle) → object</code></dt>
+      <dd>Returns the line number, text content, and marker status of
+      the given line, which can be either a number or a line handle.
+      The returned object has the structure <code>{line, handle, text,
+      gutterMarkers, textClass, bgClass, wrapClass, widgets}</code>,
+      where <code>gutterMarkers</code> is an object mapping gutter IDs
+      to marker elements, and <code>widgets</code> is an array
+      of <a href="#addLineWidget">line widgets</a> attached to this
+      line, and the various class properties refer to classes added
+      with <a href="#addLineClass"><code>addLineClass</code></a>.</dd>
+
+      <dt id="addWidget"><code><strong>cm.addWidget</strong>(pos: {line, ch}, node: Element, scrollIntoView: boolean)</code></dt>
+      <dd>Puts <code>node</code>, which should be an absolutely
+      positioned DOM node, into the editor, positioned right below the
+      given <code>{line, ch}</code> position.
+      When <code>scrollIntoView</code> is true, the editor will ensure
+      that the entire node is visible (if possible). To remove the
+      widget again, simply use DOM methods (move it somewhere else, or
+      call <code>removeChild</code> on its parent).</dd>
+
+      <dt id="addLineWidget"><code><strong>cm.addLineWidget</strong>(line: integer|LineHandle, node: Element, ?options: object) → LineWidget</code></dt>
+      <dd>Adds a line widget, an element shown below a line, spanning
+      the whole of the editor's width, and moving the lines below it
+      downwards. <code>line</code> should be either an integer or a
+      line handle, and <code>node</code> should be a DOM node, which
+      will be displayed below the given line. <code>options</code>,
+      when given, should be an object that configures the behavior of
+      the widget. The following options are supported (all default to
+      false):
+        <dl>
+          <dt><code><strong>coverGutter</strong>: boolean</code></dt>
+          <dd>Whether the widget should cover the gutter.</dd>
+          <dt><code><strong>noHScroll</strong>: boolean</code></dt>
+          <dd>Whether the widget should stay fixed in the face of
+          horizontal scrolling.</dd>
+          <dt><code><strong>above</strong>: boolean</code></dt>
+          <dd>Causes the widget to be placed above instead of below
+          the text of the line.</dd>
+          <dt><code><strong>handleMouseEvents</strong>: boolean</code></dt>
+          <dd>Determines whether the editor will capture mouse and
+          drag events occurring in this widget. Default is false—the
+          events will be left alone for the default browser handler,
+          or specific handlers on the widget, to capture.</dd>
+          <dt><code><strong>insertAt</strong>: integer</code></dt>
+          <dd>By default, the widget is added below other widgets for
+          the line. This option can be used to place it at a different
+          position (zero for the top, N to put it after the Nth other
+          widget). Note that this only has effect once, when the
+          widget is created.
+        </dl>
+      Note that the widget node will become a descendant of nodes with
+      CodeMirror-specific CSS classes, and those classes might in some
+      cases affect it. This method returns an object that represents
+      the widget placement. It'll have a <code>line</code> property
+      pointing at the line handle that it is associated with, and the following methods:
+        <dl>
+          <dt id="widget_clear"><code><strong>clear</strong>()</code></dt><dd>Removes the widget.</dd>
+          <dt id="widget_changed"><code><strong>changed</strong>()</code></dt><dd>Call
+          this if you made some change to the widget's DOM node that
+          might affect its height. It'll force CodeMirror to update
+          the height of the line that contains the widget.</dd>
+        </dl>
+      </dd>
+    </dl>
+
+    <h3 id="api_sizing">Sizing, scrolling and positioning methods</h3>
+
+    <dl>
+      <dt id="setSize"><code><strong>cm.setSize</strong>(width: number|string, height: number|string)</code></dt>
+      <dd>Programatically set the size of the editor (overriding the
+      applicable <a href="#css-resize">CSS
+      rules</a>). <code>width</code> and <code>height</code>
+      can be either numbers (interpreted as pixels) or CSS units
+      (<code>"100%"</code>, for example). You can
+      pass <code>null</code> for either of them to indicate that that
+      dimension should not be changed.</dd>
+
+      <dt id="scrollTo"><code><strong>cm.scrollTo</strong>(x: number, y: number)</code></dt>
+      <dd>Scroll the editor to a given (pixel) position. Both
+      arguments may be left as <code>null</code>
+      or <code>undefined</code> to have no effect.</dd>
+      <dt id="getScrollInfo"><code><strong>cm.getScrollInfo</strong>() → {left, top, width, height, clientWidth, clientHeight}</code></dt>
+      <dd>Get an <code>{left, top, width, height, clientWidth,
+      clientHeight}</code> object that represents the current scroll
+      position, the size of the scrollable area, and the size of the
+      visible area (minus scrollbars).</dd>
+      <dt id="scrollIntoView"><code><strong>cm.scrollIntoView</strong>(what: {line, ch}|{left, top, right, bottom}|{from, to}|null, ?margin: number)</code></dt>
+      <dd>Scrolls the given position into view. <code>what</code> may
+      be <code>null</code> to scroll the cursor into view,
+      a <code>{line, ch}</code> position to scroll a character into
+      view, a <code>{left, top, right, bottom}</code> pixel range (in
+      editor-local coordinates), or a range <code>{from, to}</code>
+      containing either two character positions or two pixel squares.
+      The <code>margin</code> parameter is optional. When given, it
+      indicates the amount of vertical pixels around the given area
+      that should be made visible as well.</dd>
+
+      <dt id="cursorCoords"><code><strong>cm.cursorCoords</strong>(where: boolean|{line, ch}, mode: string) → {left, top, bottom}</code></dt>
+      <dd>Returns an <code>{left, top, bottom}</code> object
+      containing the coordinates of the cursor position.
+      If <code>mode</code> is <code>"local"</code>, they will be
+      relative to the top-left corner of the editable document. If it
+      is <code>"page"</code> or not given, they are relative to the
+      top-left corner of the page. <code>where</code> can be a boolean
+      indicating whether you want the start (<code>true</code>) or the
+      end (<code>false</code>) of the selection, or, if a <code>{line,
+      ch}</code> object is given, it specifies the precise position at
+      which you want to measure.</dd>
+      <dt id="charCoords"><code><strong>cm.charCoords</strong>(pos: {line, ch}, ?mode: string) → {left, right, top, bottom}</code></dt>
+      <dd>Returns the position and dimensions of an arbitrary
+      character. <code>pos</code> should be a <code>{line, ch}</code>
+      object. This differs from <code>cursorCoords</code> in that
+      it'll give the size of the whole character, rather than just the
+      position that the cursor would have when it would sit at that
+      position.</dd>
+      <dt id="coordsChar"><code><strong>cm.coordsChar</strong>(object: {left, top}, ?mode: string) → {line, ch}</code></dt>
+      <dd>Given an <code>{left, top}</code> object, returns
+      the <code>{line, ch}</code> position that corresponds to it. The
+      optional <code>mode</code> parameter determines relative to what
+      the coordinates are interpreted. It may
+      be <code>"window"</code>, <code>"page"</code> (the default),
+      or <code>"local"</code>.</dd>
+      <dt id="lineAtHeight"><code><strong>cm.lineAtHeight</strong>(height: number, ?mode: string) → number</code></dt>
+      <dd>Computes the line at the given pixel
+      height. <code>mode</code> can be one of the same strings
+      that <a href="#coordsChar"><code>coordsChar</code></a>
+      accepts.</dd>
+      <dt id="heightAtLine"><code><strong>cm.heightAtLine</strong>(line: number, ?mode: string) → number</code></dt>
+      <dd>Computes the height of the top of a line, in the coordinate
+      system specified by <code>mode</code>
+      (see <a href="#coordsChar"><code>coordsChar</code></a>), which
+      defaults to <code>"page"</code>. When a line below the bottom of
+      the document is specified, the returned value is the bottom of
+      the last line in the document.</dd>
+      <dt id="defaultTextHeight"><code><strong>cm.defaultTextHeight</strong>() → number</code></dt>
+      <dd>Returns the line height of the default font for the editor.</dd>
+      <dt id="defaultCharWidth"><code><strong>cm.defaultCharWidth</strong>() → number</code></dt>
+      <dd>Returns the pixel width of an 'x' in the default font for
+      the editor. (Note that for non-monospace fonts, this is mostly
+      useless, and even for monospace fonts, non-ascii characters
+      might have a different width).</dd>
+
+      <dt id="getViewport"><code><strong>cm.getViewport</strong>() → {from: number, to: number}</code></dt>
+      <dd>Returns a <code>{from, to}</code> object indicating the
+      start (inclusive) and end (exclusive) of the currently rendered
+      part of the document. In big documents, when most content is
+      scrolled out of view, CodeMirror will only render the visible
+      part, and a margin around it. See also
+      the <a href="#event_viewportChange"><code>viewportChange</code></a>
+      event.</dd>
+
+      <dt id="refresh"><code><strong>cm.refresh</strong>()</code></dt>
+      <dd>If your code does something to change the size of the editor
+      element (window resizes are already listened for), or unhides
+      it, you should probably follow up by calling this method to
+      ensure CodeMirror is still looking as intended.</dd>
+    </dl>
+
+    <h3 id="api_mode">Mode, state, and token-related methods</h3>
+
+    <p>When writing language-aware functionality, it can often be
+    useful to hook into the knowledge that the CodeMirror language
+    mode has. See <a href="#modeapi">the section on modes</a> for a
+    more detailed description of how these work.</p>
+
+    <dl>
+      <dt id="getMode"><code><strong>doc.getMode</strong>() → object</code></dt>
+      <dd>Gets the (outer) mode object for the editor. Note that this
+      is distinct from <code>getOption("mode")</code>, which gives you
+      the mode specification, rather than the resolved, instantiated
+      <a href="#defineMode">mode object</a>.</dd>
+
+      <dt id="getModeAt"><code><strong>doc.getModeAt</strong>(pos: {line, ch}) → object</code></dt>
+      <dd>Gets the inner mode at a given position. This will return
+      the same as <a href="#getMode"><code>getMode</code></a> for
+      simple modes, but will return an inner mode for nesting modes
+      (such as <code>htmlmixed</code>).</dd>
+
+      <dt id="getTokenAt"><code><strong>cm.getTokenAt</strong>(pos: {line, ch}, ?precise: boolean) → object</code></dt>
+      <dd>Retrieves information about the token the current mode found
+      before the given position (a <code>{line, ch}</code> object). The
+      returned object has the following properties:
+      <dl>
+        <dt><code><strong>start</strong></code></dt><dd>The character (on the given line) at which the token starts.</dd>
+        <dt><code><strong>end</strong></code></dt><dd>The character at which the token ends.</dd>
+        <dt><code><strong>string</strong></code></dt><dd>The token's string.</dd>
+        <dt><code><strong>type</strong></code></dt><dd>The token type the mode assigned
+        to the token, such as <code>"keyword"</code>
+        or <code>"comment"</code> (may also be null).</dd>
+        <dt><code><strong>state</strong></code></dt><dd>The mode's state at the end of this token.</dd>
+      </dl>
+      If <code>precise</code> is true, the token will be guaranteed to be accurate based on recent edits. If false or
+      not specified, the token will use cached state information, which will be faster but might not be accurate if
+      edits were recently made and highlighting has not yet completed.
+      </dd>
+
+      <dt id="getTokenTypeAt"><code><strong>cm.getTokenTypeAt</strong>(pos: {line, ch}) → string</code></dt>
+      <dd>This is a (much) cheaper version
+      of <a href="#getTokenAt"><code>getTokenAt</code></a> useful for
+      when you just need the type of the token at a given position,
+      and no other information. Will return <code>null</code> for
+      unstyled tokens, and a string, potentially containing multiple
+      space-separated style names, otherwise.</dd>
+
+      <dt id="getHelpers"><code><strong>cm.getHelpers</strong>(pos: {line, ch}, type: string) → array<helper></code></dt>
+      <dd>Fetch the set of applicable helper values for the given
+      position. Helpers provide a way to look up functionality
+      appropriate for a mode. The <code>type</code> argument provides
+      the helper namespace (see
+      <a href="#registerHelper"><code>registerHelper</code></a>), in
+      which the values will be looked up. When the mode itself has a
+      property that corresponds to the <code>type</code>, that
+      directly determines the keys that are used to look up the helper
+      values (it may be either a single string, or an array of
+      strings). Failing that, the mode's <code>helperType</code>
+      property and finally the mode's name are used.</dd>
+      <dd>For example, the JavaScript mode has a
+      property <code>fold</code> containing <code>"brace"</code>. When
+      the <code>brace-fold</code> addon is loaded, that defines a
+      helper named <code>brace</code> in the <code>fold</code>
+      namespace. This is then used by
+      the <a href="#addon_foldcode"><code>foldcode</code></a> addon to
+      figure out that it can use that folding function to fold
+      JavaScript code.</dd>
+      <dd>When any <a href="#registerGlobalHelper">'global'</a>
+      helpers are defined for the given namespace, their predicates
+      are called on the current mode and editor, and all those that
+      declare they are applicable will also be added to the array that
+      is returned.</dd>
+
+      <dt id="getHelper"><code><strong>cm.getHelper</strong>(pos: {line, ch}, type: string) → helper</code></dt>
+      <dd>Returns the first applicable helper value.
+      See <a href="#getHelpers"><code>getHelpers</code></a>.</dd>
+
+      <dt id="getStateAfter"><code><strong>cm.getStateAfter</strong>(?line: integer, ?precise: boolean) → object</code></dt>
+      <dd>Returns the mode's parser state, if any, at the end of the
+      given line number. If no line number is given, the state at the
+      end of the document is returned. This can be useful for storing
+      parsing errors in the state, or getting other kinds of
+      contextual information for a line. <code>precise</code> is defined
+      as in <code>getTokenAt()</code>.</dd>
+    </dl>
+
+    <h3 id="api_misc">Miscellaneous methods</h3>
+
+    <dl>
+      <dt id="operation"><code><strong>cm.operation</strong>(func: () → any) → any</code></dt>
+      <dd>CodeMirror internally buffers changes and only updates its
+      DOM structure after it has finished performing some operation.
+      If you need to perform a lot of operations on a CodeMirror
+      instance, you can call this method with a function argument. It
+      will call the function, buffering up all changes, and only doing
+      the expensive update after the function returns. This can be a
+      lot faster. The return value from this method will be the return
+      value of your function.</dd>
+
+      <dt id="indentLine"><code><strong>cm.indentLine</strong>(line: integer, ?dir: string|integer)</code></dt>
+      <dd>Adjust the indentation of the given line. The second
+      argument (which defaults to <code>"smart"</code>) may be one of:
+        <dl>
+          <dt><code><strong>"prev"</strong></code></dt>
+          <dd>Base indentation on the indentation of the previous line.</dd>
+          <dt><code><strong>"smart"</strong></code></dt>
+          <dd>Use the mode's smart indentation if available, behave
+          like <code>"prev"</code> otherwise.</dd>
+          <dt><code><strong>"add"</strong></code></dt>
+          <dd>Increase the indentation of the line by
+          one <a href="#option_indentUnit">indent unit</a>.</dd>
+          <dt><code><strong>"subtract"</strong></code></dt>
+          <dd>Reduce the indentation of the line.</dd>
+          <dt><code><strong><integer></strong></code></dt>
+          <dd>Add (positive number) or reduce (negative number) the
+          indentation by the given amount of spaces.</dd>
+        </dl></dd>
+
+      <dt id="toggleOverwrite"><code><strong>cm.toggleOverwrite</strong>(?value: bool)</code></dt>
+      <dd>Switches between overwrite and normal insert mode (when not
+      given an argument), or sets the overwrite mode to a specific
+      state (when given an argument).</dd>
+
+      <dt id="execCommand"><code><strong>cm.execCommand</strong>(name: string)</code></dt>
+      <dd>Runs the <a href="#commands">command</a> with the given name on the editor.</dd>
+
+      <dt id="posFromIndex"><code><strong>doc.posFromIndex</strong>(index: integer) → {line, ch}</code></dt>
+      <dd>Calculates and returns a <code>{line, ch}</code> object for a
+      zero-based <code>index</code> who's value is relative to the start of the
+      editor's text. If the <code>index</code> is out of range of the text then
+      the returned object is clipped to start or end of the text
+      respectively.</dd>
+      <dt id="indexFromPos"><code><strong>doc.indexFromPos</strong>(object: {line, ch}) → integer</code></dt>
+      <dd>The reverse of <a href="#posFromIndex"><code>posFromIndex</code></a>.</dd>
+
+      <dt id="focus"><code><strong>cm.focus</strong>()</code></dt>
+      <dd>Give the editor focus.</dd>
+
+      <dt id="getInputField"><code><strong>cm.getInputField</strong>() → TextAreaElement</code></dt>
+      <dd>Returns the hidden textarea used to read input.</dd>
+      <dt id="getWrapperElement"><code><strong>cm.getWrapperElement</strong>() → Element</code></dt>
+      <dd>Returns the DOM node that represents the editor, and
+      controls its size. Remove this from your tree to delete an
+      editor instance.</dd>
+      <dt id="getScrollerElement"><code><strong>cm.getScrollerElement</strong>() → Element</code></dt>
+      <dd>Returns the DOM node that is responsible for the scrolling
+      of the editor.</dd>
+      <dt id="getGutterElement"><code><strong>cm.getGutterElement</strong>() → Element</code></dt>
+      <dd>Fetches the DOM node that contains the editor gutters.</dd>
+    </dl>
+
+    <h3 id="api_static">Static properties</h3>
+    <p>The <code>CodeMirror</code> object itself provides
+    several useful properties.</p>
+
+    <dl>
+      <dt id="version"><code><strong>CodeMirror.version</strong>: string</code></dt>
+      <dd>It contains a string that indicates the version of the
+      library. This is a triple of
+      integers <code>"major.minor.patch"</code>,
+      where <code>patch</code> is zero for releases, and something
+      else (usually one) for dev snapshots.</dd>
+
+      <dt id="fromTextArea"><code><strong>CodeMirror.fromTextArea</strong>(textArea: TextAreaElement, ?config: object)</code></dt>
+      <dd>
+        The method provides another way to initialize an editor. It
+        takes a textarea DOM node as first argument and an optional
+        configuration object as second. It will replace the textarea
+        with a CodeMirror instance, and wire up the form of that
+        textarea (if any) to make sure the editor contents are put
+        into the textarea when the form is submitted. The text in the
+        textarea will provide the content for the editor. A CodeMirror
+        instance created this way has three additional methods:
+        <dl>
+          <dt id="save"><code><strong>cm.save</strong>()</code></dt>
+          <dd>Copy the content of the editor into the textarea.</dd>
+
+          <dt id="toTextArea"><code><strong>cm.toTextArea</strong>()</code></dt>
+          <dd>Remove the editor, and restore the original textarea (with
+          the editor's current content).</dd>
+
+          <dt id="getTextArea"><code><strong>cm.getTextArea</strong>() → TextAreaElement</code></dt>
+          <dd>Returns the textarea that the instance was based on.</dd>
+        </dl>
+      </dd>
+
+      <dt id="defaults"><code><strong>CodeMirror.defaults</strong>: object</code></dt>
+      <dd>An object containing default values for
+      all <a href="#config">options</a>. You can assign to its
+      properties to modify defaults (though this won't affect editors
+      that have already been created).</dd>
+
+      <dt id="defineExtension"><code><strong>CodeMirror.defineExtension</strong>(name: string, value: any)</code></dt>
+      <dd>If you want to define extra methods in terms of the
+      CodeMirror API, it is possible to
+      use <code>defineExtension</code>. This will cause the given
+      value (usually a method) to be added to all CodeMirror instances
+      created from then on.</dd>
+
+      <dt id="defineDocExtension"><code><strong>CodeMirror.defineDocExtension</strong>(name: string, value: any)</code></dt>
+      <dd>Like <a href="#defineExtenstion"><code>defineExtension</code></a>,
+      but the method will be added to the interface
+      for <a href="#Doc"><code>Doc</code></a> objects instead.</dd>
+
+      <dt id="defineOption"><code><strong>CodeMirror.defineOption</strong>(name: string,
+      default: any, updateFunc: function)</code></dt>
+      <dd>Similarly, <code>defineOption</code> can be used to define new options for
+      CodeMirror. The <code>updateFunc</code> will be called with the
+      editor instance and the new value when an editor is initialized,
+      and whenever the option is modified
+      through <a href="#setOption"><code>setOption</code></a>.</dd>
+
+      <dt id="defineInitHook"><code><strong>CodeMirror.defineInitHook</strong>(func: function)</code></dt>
+      <dd>If your extention just needs to run some
+      code whenever a CodeMirror instance is initialized,
+      use <code>CodeMirror.defineInitHook</code>. Give it a function as
+      its only argument, and from then on, that function will be called
+      (with the instance as argument) whenever a new CodeMirror instance
+      is initialized.</dd>
+
+      <dt id="registerHelper"><code><strong>CodeMirror.registerHelper</strong>(type: string, name: string, value: helper)</code></dt>
+      <dd>Registers a helper value with the given <code>name</code> in
+      the given namespace (<code>type</code>). This is used to define
+      functionality that may be looked up by mode. Will create (if it
+      doesn't already exist) a property on the <code>CodeMirror</code>
+      object for the given <code>type</code>, pointing to an object
+      that maps names to values. I.e. after
+      doing <code>CodeMirror.registerHelper("hint", "foo",
+      myFoo)</code>, the value <code>CodeMirror.hint.foo</code> will
+      point to <code>myFoo</code>.</dd>
+
+      <dt id="registerGlobalHelper"><code><strong>CodeMirror.registerGlobalHelper</strong>(type: string, name: string, predicate: fn(mode, CodeMirror), value: helper)</code></dt>
+      <dd>Acts
+      like <a href="#registerHelper"><code>registerHelper</code></a>,
+      but also registers this helper as 'global', meaning that it will
+      be included by <a href="#getHelpers"><code>getHelpers</code></a>
+      whenever the given <code>predicate</code> returns true when
+      called with the local mode and editor.</dd>
+
+      <dt id="Pos"><code><strong>CodeMirror.Pos</strong>(line: integer, ?ch: integer)</code></dt>
+      <dd>A constructor for the <code>{line, ch}</code> objects that
+      are used to represent positions in editor documents.</dd>
+
+      <dt id="changeEnd"><code><strong>CodeMirror.changeEnd</strong>(change: object) → {line, ch}</code></dt>
+      <dd>Utility function that computes an end position from a change
+      (an object with <code>from</code>, <code>to</code>,
+      and <code>text</code> properties, as passed to
+      various <a href="#event_change">event handlers</a>). The
+      returned position will be the end of the changed
+      range, <em>after</em> the change is applied.</dd>
+    </dl>
+</section>
+
+<section id=addons>
+    <h2>Addons</h2>
+
+    <p>The <code>addon</code> directory in the distribution contains a
+    number of reusable components that implement extra editor
+    functionality (on top of extension functions
+    like <a href="#defineOption"><code>defineOption</code></a>, <a href="#defineExtension"><code>defineExtension</code></a>,
+    and <a href="#registerHelper"><code>registerHelper</code></a>). In
+    brief, they are:</p>
+
+    <dl>
+      <dt id="addon_dialog"><a href="../addon/dialog/dialog.js"><code>dialog/dialog.js</code></a></dt>
+      <dd>Provides a very simple way to query users for text input.
+      Adds an <strong><code>openDialog</code></strong> method to
+      CodeMirror instances, which can be called with an HTML fragment
+      or a detached DOM node that provides the prompt (should include
+      an <code>input</code> tag), and a callback function that is called
+      when text has been entered. Also adds
+      an <strong><code>openNotification</code></strong> function that
+      simply shows an HTML fragment as a notification. Depends
+      on <code>addon/dialog/dialog.css</code>.</dd>
+
+      <dt id="addon_searchcursor"><a href="../addon/search/searchcursor.js"><code>search/searchcursor.js</code></a></dt>
+      <dd>Adds the <code>getSearchCursor(query, start, caseFold) →
+      cursor</code> method to CodeMirror instances, which can be used
+      to implement search/replace functionality. <code>query</code>
+      can be a regular expression or a string (only strings will match
+      across lines—if they contain newlines). <code>start</code>
+      provides the starting position of the search. It can be
+      a <code>{line, ch}</code> object, or can be left off to default
+      to the start of the document. <code>caseFold</code> is only
+      relevant when matching a string. It will cause the search to be
+      case-insensitive. A search cursor has the following methods:
+        <dl>
+          <dt><code><strong>findNext</strong>() → boolean</code></dt>
+          <dt><code><strong>findPrevious</strong>() → boolean</code></dt>
+          <dd>Search forward or backward from the current position.
+          The return value indicates whether a match was found. If
+          matching a regular expression, the return value will be the
+          array returned by the <code>match</code> method, in case you
+          want to extract matched groups.</dd>
+          <dt><code><strong>from</strong>() → {line, ch}</code></dt>
+          <dt><code><strong>to</strong>() → {line, ch}</code></dt>
+          <dd>These are only valid when the last call
+          to <code>findNext</code> or <code>findPrevious</code> did
+          not return false. They will return <code>{line, ch}</code>
+          objects pointing at the start and end of the match.</dd>
+          <dt><code><strong>replace</strong>(text: string)</code></dt>
+          <dd>Replaces the currently found match with the given text
+          and adjusts the cursor position to reflect the
+          replacement.</dd>
+        </dl></dd>
+
+      <dt id="addon_search"><a href="../addon/search/search.js"><code>search/search.js</code></a></dt>
+      <dd>Implements the search commands. CodeMirror has keys bound to
+      these by default, but will not do anything with them unless an
+      implementation is provided. Depends
+      on <code>searchcursor.js</code>, and will make use
+      of <a href="#addon_dialog"><code>openDialog</code></a> when
+      available to make prompting for search queries less ugly.</dd>
+
+      <dt id="addon_matchbrackets"><a href="../addon/edit/matchbrackets.js"><code>edit/matchbrackets.js</code></a></dt>
+      <dd>Defines an option <code>matchBrackets</code> which, when set
+      to true, causes matching brackets to be highlighted whenever the
+      cursor is next to them. It also adds a
+      method <code>matchBrackets</code> that forces this to happen
+      once, and a method <code>findMatchingBracket</code> that can be
+      used to run the bracket-finding algorithm that this uses
+      internally.</dd>
+
+      <dt id="addon_closebrackets"><a href="../addon/edit/closebrackets.js"><code>edit/closebrackets.js</code></a></dt>
+      <dd>Defines an option <code>autoCloseBrackets</code> that will
+      auto-close brackets and quotes when typed. By default, it'll
+      auto-close <code>()[]{}''""</code>, but you can pass it a string
+      similar to that (containing pairs of matching characters), or an
+      object with <code>pairs</code> and
+      optionally <code>explode</code> properties to customize
+      it. <code>explode</code> should be a similar string that gives
+      the pairs of characters that, when enter is pressed between
+      them, should have the second character also moved to its own
+      line. <a href="../demo/closebrackets.html">Demo here</a>.</dd>
+
+      <dt id="addon_matchtags"><a href="../addon/edit/matchtags.js"><code>edit/matchtags.js</code></a></dt>
+      <dd>Defines an option <code>matchTags</code> that, when enabled,
+      will cause the tags around the cursor to be highlighted (using
+      the <code>CodeMirror-matchingtag</code> class). Also
+      defines
+      a <a href="#commands">command</a> <code>toMatchingTag</code>,
+      which you can bind a key to in order to jump to the tag mathing
+      the one under the cursor. Depends on
+      the <code>addon/fold/xml-fold.js</code>
+      addon. <a href="../demo/matchtags.html">Demo here.</a></dd>
+
+      <dt id="addon_trailingspace"><a href="../addon/edit/trailingspace.js"><code>edit/trailingspace.js</code></a></dt>
+      <dd>Adds an option <code>showTrailingSpace</code> which, when
+      enabled, adds the CSS class <code>cm-trailingspace</code> to
+      stretches of whitespace at the end of lines.
+      The <a href="../demo/trailingspace.html">demo</a> has a nice
+      squiggly underline style for this class.</dd>
+
+      <dt id="addon_closetag"><a href="../addon/edit/closetag.js"><code>edit/closetag.js</code></a></dt>
+      <dd>Provides utility functions for adding automatic tag closing
+      to XML modes. See
+      the <a href="../demo/closetag.html">demo</a>.</dd>
+
+      <dt id="addon_continuelist"><a href="../addon/edit/continuelist.js"><code>edit/continuelist.js</code></a></dt>
+      <dd>Markdown specific. Defines
+      a <code>"newlineAndIndentContinueMarkdownList"</code> <a href="#commands">command</a>
+      command that can be bound to <code>enter</code> to automatically
+      insert the leading characters for continuing a list. See
+      the <a href="../mode/markdown/index.html">Markdown mode
+      demo</a>.</dd>
+
+      <dt id="addon_comment"><a href="../addon/comment/comment.js"><code>comment/comment.js</code></a></dt>
+      <dd>Addon for commenting and uncommenting code. Adds three
+      methods to CodeMirror instances:
+      <dl>
+        <dt id="lineComment"><code><strong>lineComment</strong>(from: {line, ch}, to: {line, ch}, ?options: object)</code></dt>
+        <dd>Set the lines in the given range to be line comments. Will
+        fall back to <code>blockComment</code> when no line comment
+        style is defined for the mode.</dd>
+        <dt id="blockComment"><code><strong>blockComment</strong>(from: {line, ch}, to: {line, ch}, ?options: object)</code></dt>
+        <dd>Wrap the code in the given range in a block comment. Will
+        fall back to <code>lineComment</code> when no block comment
+        style is defined for the mode.</dd>
+        <dt id="uncomment"><code><strong>uncomment</strong>(from: {line, ch}, to: {line, ch}, ?options: object) → boolean</code></dt>
+        <dd>Try to uncomment the given range.
+          Returns <code>true</code> if a comment range was found and
+          removed, <code>false</code> otherwise.</dd>
+      </dl>
+      The <code>options</code> object accepted by these methods may
+      have the following properties:
+      <dl>
+        <dt><code>blockCommentStart, blockCommentEnd, blockCommentLead, lineComment: string</code></dt>
+        <dd>Override the <a href="#mode_comment">comment string
+        properties</a> of the mode with custom comment strings.</dd>
+        <dt><code><strong>padding</strong>: string</code></dt>
+        <dd>A string that will be inserted after opening and before
+        closing comment markers. Defaults to a single space.</dd>
+        <dt><code><strong>commentBlankLines</strong>: boolean</code></dt>
+        <dd>Whether, when adding line comments, to also comment lines
+        that contain only whitespace.</dd>
+        <dt><code><strong>indent</strong>: boolean</code></dt>
+        <dd>When adding line comments and this is turned on, it will
+        align the comment block to the current indentation of the
+        first line of the block.</dd>
+        <dt><code><strong>fullLines</strong>: boolean</code></dt>
+        <dd>When block commenting, this controls whether the whole
+        lines are indented, or only the precise range that is given.
+        Defaults to <code>true</code>.</dd>
+      </dl>
+      The addon also defines
+      a <code>toggleComment</code> <a href="#commands">command</a>,
+      which will try to uncomment the current selection, and if that
+      fails, line-comments it.</dd>
+
+      <dt id="addon_foldcode"><a href="../addon/fold/foldcode.js"><code>fold/foldcode.js</code></a></dt>
+      <dd>Helps with code folding. Adds a <code>foldCode</code> method
+      to editor instances, which will try to do a code fold starting
+      at the given line, or unfold the fold that is already present.
+      The method takes as first argument the position that should be
+      folded (may be a line number or
+      a <a href="#Pos"><code>Pos</code></a>), and as second optional
+      argument either a range-finder function, or an options object,
+      supporting the following properties:
+      <dl>
+        <dt><code><strong>rangeFinder</strong>: fn(CodeMirror, Pos)</code></dt>
+        <dd id="helper_fold_auto">The function that is used to find
+        foldable ranges. If this is not directly passed, it will
+        default to <code>CodeMirror.fold.auto</code>, which
+        uses <a href="#getHelpers"><code>getHelpers</code></a> with
+        a <code>"fold"</code> type to find folding functions
+        appropriate for the local mode. There are files in
+        the <a href="../addon/fold/"><code>addon/fold/</code></a>
+        directory providing <code>CodeMirror.fold.brace</code>, which
+        finds blocks in brace languages (JavaScript, C, Java,
+        etc), <code>CodeMirror.fold.indent</code>, for languages where
+        indentation determines block structure (Python, Haskell),
+        and <code>CodeMirror.fold.xml</code>, for XML-style languages,
+        and <code>CodeMirror.fold.comment</code>, for folding comment
+        blocks.</dd>
+        <dt><code><strong>widget</strong>: string|Element</code></dt>
+        <dd>The widget to show for folded ranges. Can be either a
+        string, in which case it'll become a span with
+        class <code>CodeMirror-foldmarker</code>, or a DOM node.</dd>
+        <dt><code><strong>scanUp</strong>: boolean</code></dt>
+        <dd>When true (default is false), the addon will try to find
+        foldable ranges on the lines above the current one if there
+        isn't an eligible one on the given line.</dd>
+        <dt><code><strong>minFoldSize</strong>: integer</code></dt>
+        <dd>The minimum amount of lines that a fold should span to be
+        accepted. Defaults to 0, which also allows single-line
+        folds.</dd>
+      </dl>
+      See <a href="../demo/folding.html">the demo</a> for an
+      example.</dd>
+
+      <dt id="addon_foldgutter"><a href="../addon/fold/foldgutter.js"><code>fold/foldgutter.js</code></a></dt>
+      <dd>Provides an option <code>foldGutter</code>, which can be
+      used to create a gutter with markers indicating the blocks that
+      can be folded. Create a gutter using
+      the <a href="#option_gutters"><code>gutters</code></a> option,
+      giving it the class <code>CodeMirror-foldgutter</code> or
+      something else if you configure the addon to use a different
+      class, and this addon will show markers next to folded and
+      foldable blocks, and handle clicks in this gutter. Note that
+      CSS styles should be applied to make the gutter, and the fold
+      markers within it, visible. A default set of CSS styles are
+      available in:
+      <a href="../addon/fold/foldgutter.css">
+        <code>addon/fold/foldgutter.css</code>
+      </a>.
+      The option
+      can be either set to <code>true</code>, or an object containing
+      the following optional option fields:
+      <dl>
+        <dt><code><strong>gutter</strong>: string</code></dt>
+        <dd>The CSS class of the gutter. Defaults
+        to <code>"CodeMirror-foldgutter"</code>. You will have to
+        style this yourself to give it a width (and possibly a
+        background). See the default gutter style rules above.</dd>
+        <dt><code><strong>indicatorOpen</strong>: string | Element</code></dt>
+        <dd>A CSS class or DOM element to be used as the marker for
+        open, foldable blocks. Defaults
+        to <code>"CodeMirror-foldgutter-open"</code>.</dd>
+        <dt><code><strong>indicatorFolded</strong>: string | Element</code></dt>
+        <dd>A CSS class or DOM element to be used as the marker for
+        folded blocks. Defaults to <code>"CodeMirror-foldgutter-folded"</code>.</dd>
+        <dt><code><strong>rangeFinder</strong>: fn(CodeMirror, Pos)</code></dt>
+        <dd>The range-finder function to use when determining whether
+        something can be folded. When not
+        given, <a href="#helper_fold_auto"><code>CodeMirror.fold.auto</code></a>
+        will be used as default.</dd>
+      </dl>
+      Demo <a href="../demo/folding.html">here</a>.</dd>
+
+      <dt id="addon_runmode"><a href="../addon/runmode/runmode.js"><code>runmode/runmode.js</code></a></dt>
+      <dd>Can be used to run a CodeMirror mode over text without
+      actually opening an editor instance.
+      See <a href="../demo/runmode.html">the demo</a> for an example.
+      There are alternate versions of the file avaible for
+      running <a href="../addon/runmode/runmode-standalone.js">stand-alone</a>
+      (without including all of CodeMirror) and
+      for <a href="../addon/runmode/runmode.node.js">running under
+      node.js</a>.</dd>
+
+      <dt id="addon_colorize"><a href="../addon/runmode/colorize.js"><code>runmode/colorize.js</code></a></dt>
+      <dd>Provides a convenient way to syntax-highlight code snippets
+      in a webpage. Depends on
+      the <a href="#addon_runmode"><code>runmode</code></a> addon (or
+      its standalone variant). Provides
+      a <code>CodeMirror.colorize</code> function that can be called
+      with an array (or other array-ish collection) of DOM nodes that
+      represent the code snippets. By default, it'll get
+      all <code>pre</code> tags. Will read the <code>data-lang</code>
+      attribute of these nodes to figure out their language, and
+      syntax-color their content using the relevant CodeMirror mode
+      (you'll have to load the scripts for the relevant modes
+      yourself). A second argument may be provided to give a default
+      mode, used when no language attribute is found for a node. Used
+      in this manual to highlight example code.</dd>
+
+      <dt id="addon_overlay"><a href="../addon/mode/overlay.js"><code>mode/overlay.js</code></a></dt>
+      <dd>Mode combinator that can be used to extend a mode with an
+      'overlay' — a secondary mode is run over the stream, along with
+      the base mode, and can color specific pieces of text without
+      interfering with the base mode.
+      Defines <code>CodeMirror.overlayMode</code>, which is used to
+      create such a mode. See <a href="../demo/mustache.html">this
+      demo</a> for a detailed example.</dd>
+
+      <dt id="addon_multiplex"><a href="../addon/mode/multiplex.js"><code>mode/multiplex.js</code></a></dt>
+      <dd>Mode combinator that can be used to easily 'multiplex'
+      between several modes.
+      Defines <code>CodeMirror.multiplexingMode</code> which, when
+      given as first argument a mode object, and as other arguments
+      any number of <code>{open, close, mode [, delimStyle, innerStyle]}</code>
+      objects, will return a mode object that starts parsing using the
+      mode passed as first argument, but will switch to another mode
+      as soon as it encounters a string that occurs in one of
+      the <code>open</code> fields of the passed objects. When in a
+      sub-mode, it will go back to the top mode again when
+      the <code>close</code> string is encountered.
+      Pass <code>"\n"</code> for <code>open</code> or <code>close</code>
+      if you want to switch on a blank line.
+      <ul><li>When <code>delimStyle</code> is specified, it will be the token
+      style returned for the delimiter tokens.</li>
+      <li>When <code>innerStyle</code> is specified, it will be the token
+      style added for each inner mode token.</li></ul>
+      The outer mode will not see the content between the delimiters.
+      See <a href="../demo/multiplex.html">this demo</a> for an
+      example.</dd>
+
+      <dt id="addon_show-hint"><a href="../addon/hint/show-hint.js"><code>hint/show-hint.js</code></a></dt>
+      <dd>Provides a framework for showing autocompletion hints.
+      Defines <code>CodeMirror.showHint</code>, which takes a
+      CodeMirror instance, a hinting function, and optionally an
+      options object, and pops up a widget that allows the user to
+      select a completion. Hinting functions are function that take an
+      editor instance and an optional options object, and return
+      a <code>{list, from, to}</code> object, where <code>list</code>
+      is an array of strings or objects (the completions),
+      and <code>from</code> and <code>to</code> give the start and end
+      of the token that is being completed as <code>{line, ch}</code>
+      objects.</dd>
+      <dd>If no hinting function is given, the addon will
+      use <code>CodeMirror.hint.auto</code>, with
+      calls <a href="#getHelpers"><code>getHelpers</code></a> with
+      the <code>"hint"</code> type to find applicable hinting
+      functions, and tries them one by one. If that fails, it looks
+      for a <code>"hintWords"</code> helper to fetch a list of
+      completable words for the mode, and
+      uses <code>CodeMirror.hint.fromList</code> to complete from
+      those.</dd>
+      <dd>When completions
+      aren't simple strings, they should be objects with the following
+      properties:
+      <dl>
+        <dt><code><strong>text</strong>: string</code></dt>
+        <dd>The completion text. This is the only required
+        property.</dd>
+        <dt><code><strong>displayText</strong>: string</code></dt>
+        <dd>The text that should be displayed in the menu.</dd>
+        <dt><code><strong>className</strong>: string</code></dt>
+        <dd>A CSS class name to apply to the completion's line in the
+        menu.</dd>
+        <dt><code><strong>render</strong>: fn(Element, self, data)</code></dt>
+        <dd>A method used to create the DOM structure for showing the
+        completion by appending it to its first argument.</dd>
+        <dt><code><strong>hint</strong>: fn(CodeMirror, self, data)</code></dt>
+        <dd>A method used to actually apply the completion, instead of
+        the default behavior.</dd>
+        <dt><code><strong>from</strong>: {line, ch}</code></dt>
+        <dd>Optional <code>from</code> position that will be used by <code>pick()</code> instead
+        of the global one passed with the full list of completions.</dd>
+        <dt><code><strong>to</strong>: {line, ch}</code></dt>
+        <dd>Optional <code>to</code> position that will be used by <code>pick()</code> instead
+        of the global one passed with the full list of completions.</dd>
+      </dl>
+      The plugin understands the following options (the options object
+      will also be passed along to the hinting function, which may
+      understand additional options):
+      <dl>
+        <dt><code><strong>async</strong>: boolean</code></dt>
+        <dd>When set to true, the hinting function's signature should
+        be <code>(cm, callback, ?options)</code>, and the completion
+        interface will only be popped up when the hinting function
+        calls the callback, passing it the object holding the
+        completions.</dd>
+        <dt><code><strong>completeSingle</strong>: boolean</code></dt>
+        <dd>Determines whether, when only a single completion is
+        available, it is completed without showing the dialog.
+        Defaults to true.</dd>
+        <dt><code><strong>alignWithWord</strong>: boolean</code></dt>
+        <dd>Whether the pop-up should be horizontally aligned with the
+        start of the word (true, default), or with the cursor (false).</dd>
+        <dt><code><strong>closeOnUnfocus</strong>: boolean</code></dt>
+        <dd>When enabled (which is the default), the pop-up will close
+        when the editor is unfocused.</dd>
+        <dt><code><strong>customKeys</strong>: keymap</code></dt>
+        <dd>Allows you to provide a custom key map of keys to be active
+        when the pop-up is active. The handlers will be called with an
+        extra argument, a handle to the completion menu, which
+        has <code>moveFocus(n)</code>, <code>setFocus(n)</code>, <code>pick()</code>,
+        and <code>close()</code> methods (see the source for details),
+        that can be used to change the focused element, pick the
+        current element or close the menu. Additionnaly <code>menuSize()</code>
+        can give you access to the size of the current dropdown menu,
+        <code>length</code> give you the number of availlable completions, and
+        <code>data</code> give you full access to the completion returned by the
+        hinting function.</dd>
+        <dt><code><strong>extraKeys</strong>: keymap</code></dt>
+        <dd>Like <code>customKeys</code> above, but the bindings will
+        be added to the set of default bindings, instead of replacing
+        them.</dd>
+      </dl>
+      The following events will be fired on the completions object
+      during completion:
+      <dl>
+        <dt><code><strong>"shown"</strong> ()</code></dt>
+        <dd>Fired when the pop-up is shown.</dd>
+        <dt><code><strong>"select"</strong> (completion, Element)</code></dt>
+        <dd>Fired when a completion is selected. Passed the completion
+        value (string or object) and the DOM node that represents it
+        in the menu.</dd>
+        <dt><code><strong>"pick"</strong> (completion)</code></dt>
+        <dd>Fired when a completion is picked. Passed the completion value
+        (string or object).</dd>
+        <dt><code><strong>"close"</strong> ()</code></dt>
+        <dd>Fired when the completion is finished.</dd>
+      </dl>
+      This addon depends on styles
+      from <code>addon/hint/show-hint.css</code>. Check
+      out <a href="../demo/complete.html">the demo</a> for an
+      example.</dd>
+
+      <dt id="addon_javascript-hint"><a href="../addon/hint/javascript-hint.js"><code>hint/javascript-hint.js</code></a></dt>
+      <dd>Defines a simple hinting function for JavaScript
+      (<code>CodeMirror.hint.javascript</code>) and CoffeeScript
+      (<code>CodeMirror.hint.coffeescript</code>) code. This will
+      simply use the JavaScript environment that the editor runs in as
+      a source of information about objects and their properties.</dd>
+
+      <dt id="addon_xml-hint"><a href="../addon/hint/xml-hint.js"><code>hint/xml-hint.js</code></a></dt>
+      <dd>Defines <code>CodeMirror.hint.xml</code>, which produces
+      hints for XML tagnames, attribute names, and attribute values,
+      guided by a <code>schemaInfo</code> option (a property of the
+      second argument passed to the hinting function, or the third
+      argument passed to <code>CodeMirror.showHint</code>).<br>The
+      schema info should be an object mapping tag names to information
+      about these tags, with optionally a <code>"!top"</code> property
+      containing a list of the names of valid top-level tags. The
+      values of the properties should be objects with optional
+      properties <code>children</code> (an array of valid child
+      element names, omit to simply allow all tags to appear)
+      and <code>attrs</code> (an object mapping attribute names
+      to <code>null</code> for free-form attributes, and an array of
+      valid values for restricted
+      attributes). <a href="../demo/xmlcomplete.html">Demo
+      here.</a></dd>
+
+      <dt id="addon_html-hint"><a href="../addon/hint/html-hint.js"><code>hint/html-hint.js</code></a></dt>
+      <dd>Provides schema info to
+      the <a href="#addon_xml-hint">xml-hint</a> addon for HTML
+      documents. Defines a schema
+      object <code>CodeMirror.htmlSchema</code> that you can pass to
+      as a <code>schemaInfo</code> option, and
+      a <code>CodeMirror.hint.html</code> hinting function that
+      automatically calls <code>CodeMirror.hint.xml</code> with this
+      schema data. See
+      the <a href="../demo/html5complete.html">demo</a>.</dd>
+
+      <dt id="addon_css-hint"><a href="../addon/hint/css-hint.js"><code>hint/css-hint.js</code></a></dt>
+      <dd>A hinting function for CSS, SCSS, or LESS code.
+      Defines <code>CodeMirror.hint.css</code>.</dd>
+
+      <dt id="addon_python-hint"><a href="../addon/hint/python-hint.js"><code>hint/python-hint.js</code></a></dt>
+      <dd>A very simple hinting function for Python code.
+      Defines <code>CodeMirror.hint.python</code>.</dd>
+
+      <dt id="addon_anyword-hint"><a href="../addon/hint/anyword-hint.js"><code>hint/anyword-hint.js</code></a></dt>
+      <dd>A very simple hinting function
+      (<code>CodeMirror.hint.anyword</code>) that simply looks for
+      words in the nearby code and completes to those. Takes two
+      optional options, <code>word</code>, a regular expression that
+      matches words (sequences of one or more character),
+      and <code>range</code>, which defines how many lines the addon
+      should scan when completing (defaults to 500).</dd>
+
+      <dt id="addon_sql-hint"><a href="../addon/hint/sql-hint.js"><code>hint/sql-hint.js</code></a></dt>
+      <dd>A simple SQL hinter. Defines <code>CodeMirror.hint.sql</code>.</dd>
+
+      <dt id="addon_match-highlighter"><a href="../addon/search/match-highlighter.js"><code>search/match-highlighter.js</code></a></dt>
+      <dd>Adds a <code>highlightSelectionMatches</code> option that
+      can be enabled to highlight all instances of a currently
+      selected word. Can be set either to true or to an object
+      containing the following options: <code>minChars</code>, for the
+      minimum amount of selected characters that triggers a highlight
+      (default 2), <code>style</code>, for the style to be used to
+      highlight the matches (default <code>"matchhighlight"</code>,
+      which will correspond to CSS
+      class <code>cm-matchhighlight</code>),
+      and <code>showToken</code> which can be set to <code>true</code>
+      or to a regexp matching the characters that make up a word. When
+      enabled, it causes the current word to be highlighted when
+      nothing is selected (defaults to off).
+      Demo <a href="../demo/matchhighlighter.html">here</a>.</dd>
+
+      <dt id="addon_lint"><a href="../addon/lint/lint.js"><code>lint/lint.js</code></a></dt>
+      <dd>Defines an interface component for showing linting warnings,
+      with pluggable warning sources
+      (see <a href="../addon/lint/json-lint.js"><code>json-lint.js</code></a>,
+      <a href="../addon/lint/javascript-lint.js"><code>javascript-lint.js</code></a>,
+      and <a href="../addon/lint/css-lint.js"><code>css-lint.js</code></a>
+      in the same directory). Defines a <code>lint</code> option that
+      can be set to a warning source (for
+      example <code>CodeMirror.lint.javascript</code>), or
+      to <code>true</code>, in which
+      case <a href="#getHelper"><code>getHelper</code></a> with
+      type <code>"lint"</code> is used to determined a validator
+      function. Depends on <code>addon/lint/lint.css</code>. A demo
+      can be found <a href="../demo/lint.html">here</a>.</dd>
+
+      <dt id="addon_mark-selection"><a href="../addon/selection/mark-selection.js"><code>selection/mark-selection.js</code></a></dt>
+      <dd>Causes the selected text to be marked with the CSS class
+      <code>CodeMirror-selectedtext</code> when the <code>styleSelectedText</code> option
+      is enabled. Useful to change the colour of the selection (in addition to the background),
+      like in <a href="../demo/markselection.html">this demo</a>.</dd>
+
+      <dt id="addon_active-line"><a href="../addon/selection/active-line.js"><code>selection/active-line.js</code></a></dt>
+      <dd>Defines a <code>styleActiveLine</code> option that, when enabled,
+      gives the wrapper of the active line the class <code>CodeMirror-activeline</code>,
+      and adds a background with the class <code>CodeMirror-activeline-background</code>.
+      is enabled. See the <a href="../demo/activeline.html">demo</a>.</dd>
+
+      <dt id="addon_loadmode"><a href="../addon/mode/loadmode.js"><code>mode/loadmode.js</code></a></dt>
+      <dd>Defines a <code>CodeMirror.requireMode(modename,
+      callback)</code> function that will try to load a given mode and
+      call the callback when it succeeded. You'll have to
+      set <code>CodeMirror.modeURL</code> to a string that mode paths
+      can be constructed from, for
+      example <code>"mode/%N/%N.js"</code>—the <code>%N</code>'s will
+      be replaced with the mode name. Also
+      defines <code>CodeMirror.autoLoadMode(instance, mode)</code>,
+      which will ensure the given mode is loaded and cause the given
+      editor instance to refresh its mode when the loading
+      succeeded. See the <a href="../demo/loadmode.html">demo</a>.</dd>
+
+      <dt id="addon_continuecomment"><a href="../addon/comment/continuecomment.js"><code>comment/continuecomment.js</code></a></dt>
+      <dd>Adds a <code>continueComments</code> option, which sets whether the
+      editor will make the next line continue a comment when you press Enter
+      inside a comment block. Can be set to a boolean to enable/disable this
+      functionality. Set to a string, it will continue comments using a custom
+      shortcut. Set to an object, it will use the <code>key</code> property for
+      a custom shortcut and the boolean <code>continueLineComment</code>
+      property to determine whether single-line comments should be continued
+      (defaulting to <code>true</code>).</dd>
+
+      <dt id="addon_placeholder"><a href="../addon/display/placeholder.js"><code>display/placeholder.js</code></a></dt>
+      <dd>Adds a <code>placeholder</code> option that can be used to
+      make text appear in the editor when it is empty and not focused.
+      Also gives the editor a <code>CodeMirror-empty</code> CSS class
+      whenever it doesn't contain any text.
+      See <a href="../demo/placeholder.html">the demo</a>.</dd>
+
+      <dt id="addon_fullscreen"><a href="../addon/display/fullscreen.js"><code>display/fullscreen.js</code></a></dt>
+      <dd>Defines an option <code>fullScreen</code> that, when set
+      to <code>true</code>, will make the editor full-screen (as in,
+      taking up the whole browser window). Depends
+      on <a href="../addon/display/fullscreen.css"><code>fullscreen.css</code></a>. <a href="../demo/fullscreen.html">Demo
+      here</a>.</dd>
+
+      <dt id="addon_rulers"><a href="../addon/display/rulers.js"><code>display/rulers.js</code></a></dt>
+      <dd>Adds a <code>rulers</code> option, which can be used to show
+      one or more vertical rulers in the editor. The option, if
+      defined, should be given an array of <code>{column,
+      className}</code> objects or numbers. The ruler will be
+      displayed at the column indicated by the number or
+      the <code>column</code> property. The <code>className</code>
+      property can be used to assign a custom style to a
+      ruler. <a href="../demo/rulers.html">Demo here</a>.</dd>
+
+      <dt id="addon_hardwrap"><a href="../addon/wrap/hardwrap.js"><code>wrap/hardwrap.js</code></a></dt>
+      <dd>Addon to perform hard line wrapping/breaking for paragraphs
+      of text. Adds these methods to editor instances:
+        <dl>
+          <dt><code><strong>wrapParagraph</strong>(?pos: {line, ch}, ?options: object)</code></dt>
+          <dd>Wraps the paragraph at the given position.
+          If <code>pos</code> is not given, it defaults to the cursor
+          position.</dd>
+          <dt><code><strong>wrapRange</strong>(from: {line, ch}, to: {line, ch}, ?options: object)</code></dt>
+          <dd>Wraps the given range as one big paragraph.</dd>
+          <dt><code><strong>wrapParagraphsInRange</strong>(from: {line, ch}, to: {line, ch}, ?options: object)</code></dt>
+          <dd>Wrapps the paragraphs in (and overlapping with) the
+          given range individually.</dd>
+        </dl>
+        The following options are recognized:
+        <dl>
+          <dt><code><strong>paragraphStart</strong>, <strong>paragraphEnd</strong>: RegExp</code></dt>
+          <dd>Blank lines are always considered paragraph boundaries.
+          These options can be used to specify a pattern that causes
+          lines to be considered the start or end of a paragraph.</dd>
+          <dt><code><strong>column</strong>: number</code></dt>
+          <dd>The column to wrap at. Defaults to 80.</dd>
+          <dt><code><strong>wrapOn</strong>: RegExp</code></dt>
+          <dd>A regular expression that matches only those
+          two-character strings that allow wrapping. By default, the
+          addon wraps on whitespace and after dash characters.</dd>
+          <dt><code><strong>killTrailingSpace</strong>: boolean</code></dt>
+          <dd>Whether trailing space caused by wrapping should be
+          preserved, or deleted. Defaults to true.</dd>
+        </dl>
+        A demo of the addon is available <a href="../demo/hardwrap.html">here</a>.
+      </dd>
+
+      <dt id="addon_merge"><a href="../addon/merge/merge.js"><code>merge/merge.js</code></a></dt>
+      <dd>Implements an interface for merging changes, using either a
+      2-way or a 3-way view. The <code>CodeMirror.MergeView</code>
+      constructor takes arguments similar to
+      the <a href="#CodeMirror"><code>CodeMirror</code></a>
+      constructor, first a node to append the interface to, and then
+      an options object. Two extra optional options are
+      recognized, <code>origLeft</code> and <code>origRight</code>,
+      which may be strings that provide original versions of the
+      document, which will be shown to the left and right of the
+      editor in non-editable CodeMirror instances. The merge interface
+      will highlight changes between the editable document and the
+      original(s) (<a href="../demo/merge.html">demo</a>).</dd>
+
+      <dt id="addon_tern"><a href="../addon/tern/tern.js"><code>tern/tern.js</code></a></dt>
+      <dd>Provides integration with
+      the <a href="http://ternjs.net">Tern</a> JavaScript analysis
+      engine, for completion, definition finding, and minor
+      refactoring help. See the <a href="../demo/tern.html">demo</a>
+      for a very simple integration. For more involved scenarios, see
+      the comments at the top of
+      the <a href="../addon/tern/tern.js">addon</a> and the
+      implementation of the
+      (multi-file) <a href="http://ternjs.net/doc/demo.html">demonstration
+      on the Tern website</a>.</dd>
+    </dl>
+</section>
+
+<section id=modeapi>
+    <h2>Writing CodeMirror Modes</h2>
+
+    <p>Modes typically consist of a single JavaScript file. This file
+    defines, in the simplest case, a lexer (tokenizer) for your
+    language—a function that takes a character stream as input,
+    advances it past a token, and returns a style for that token. More
+    advanced modes can also handle indentation for the language.</p>
+
+    <p id="defineMode">The mode script should
+    call <code><strong>CodeMirror.defineMode</strong></code> to
+    register itself with CodeMirror. This function takes two
+    arguments. The first should be the name of the mode, for which you
+    should use a lowercase string, preferably one that is also the
+    name of the files that define the mode (i.e. <code>"xml"</code> is
+    defined in <code>xml.js</code>). The second argument should be a
+    function that, given a CodeMirror configuration object (the thing
+    passed to the <code>CodeMirror</code> function) and an optional
+    mode configuration object (as in
+    the <a href="#option_mode"><code>mode</code></a> option), returns
+    a mode object.</p>
+
+    <p>Typically, you should use this second argument
+    to <code>defineMode</code> as your module scope function (modes
+    should not leak anything into the global scope!), i.e. write your
+    whole mode inside this function.</p>
+
+    <p>The main responsibility of a mode script is <em>parsing</em>
+    the content of the editor. Depending on the language and the
+    amount of functionality desired, this can be done in really easy
+    or extremely complicated ways. Some parsers can be stateless,
+    meaning that they look at one element (<em>token</em>) of the code
+    at a time, with no memory of what came before. Most, however, will
+    need to remember something. This is done by using a <em>state
+    object</em>, which is an object that is always passed when
+    reading a token, and which can be mutated by the tokenizer.</p>
+
+    <p id="startState">Modes that use a state must define
+    a <code><strong>startState</strong></code> method on their mode
+    object. This is a function of no arguments that produces a state
+    object to be used at the start of a document.</p>
+
+    <p id="token">The most important part of a mode object is
+    its <code><strong>token</strong>(stream, state)</code> method. All
+    modes must define this method. It should read one token from the
+    stream it is given as an argument, optionally update its state,
+    and return a style string, or <code>null</code> for tokens that do
+    not have to be styled. For your styles, you are encouraged to use
+    the 'standard' names defined in the themes (without
+    the <code>cm-</code> prefix). If that fails, it is also possible
+    to come up with your own and write your own CSS theme file.<p>
+
+    <p id="token_style_line">A typical token string would
+    be <code>"variable"</code> or <code>"comment"</code>. Multiple
+    styles can be returned (separated by spaces), for
+    example <code>"string error"</code> for a thing that looks like a
+    string but is invalid somehow (say, missing its closing quote).
+    When a style is prefixed by <code>"line-"</code>
+    or <code>"line-background-"</code>, the style will be applied to
+    the whole line, analogous to what
+    the <a href="#addLineClass"><code>addLineClass</code></a> method
+    does—styling the <code>"text"</code> in the simple case, and
+    the <code>"background"</code> element
+    when <code>"line-background-"</code> is prefixed.</p>
+
+    <p id="StringStream">The stream object that's passed
+    to <code>token</code> encapsulates a line of code (tokens may
+    never span lines) and our current position in that line. It has
+    the following API:</p>
+
+    <dl>
+      <dt><code><strong>eol</strong>() → boolean</code></dt>
+      <dd>Returns true only if the stream is at the end of the
+      line.</dd>
+      <dt><code><strong>sol</strong>() → boolean</code></dt>
+      <dd>Returns true only if the stream is at the start of the
+      line.</dd>
+
+      <dt><code><strong>peek</strong>() → string</code></dt>
+      <dd>Returns the next character in the stream without advancing
+      it. Will return an <code>null</code> at the end of the
+      line.</dd>
+      <dt><code><strong>next</strong>() → string</code></dt>
+      <dd>Returns the next character in the stream and advances it.
+      Also returns <code>null</code> when no more characters are
+      available.</dd>
+
+      <dt><code><strong>eat</strong>(match: string|regexp|function(char: string) → boolean) → string</code></dt>
+      <dd><code>match</code> can be a character, a regular expression,
+      or a function that takes a character and returns a boolean. If
+      the next character in the stream 'matches' the given argument,
+      it is consumed and returned. Otherwise, <code>undefined</code>
+      is returned.</dd>
+      <dt><code><strong>eatWhile</strong>(match: string|regexp|function(char: string) → boolean) → boolean</code></dt>
+      <dd>Repeatedly calls <code>eat</code> with the given argument,
+      until it fails. Returns true if any characters were eaten.</dd>
+      <dt><code><strong>eatSpace</strong>() → boolean</code></dt>
+      <dd>Shortcut for <code>eatWhile</code> when matching
+      white-space.</dd>
+      <dt><code><strong>skipToEnd</strong>()</code></dt>
+      <dd>Moves the position to the end of the line.</dd>
+      <dt><code><strong>skipTo</strong>(ch: string) → boolean</code></dt>
+      <dd>Skips to the next occurrence of the given character, if
+      found on the current line (doesn't advance the stream if the
+      character does not occur on the line). Returns true if the
+      character was found.</dd>
+      <dt><code><strong>match</strong>(pattern: string, ?consume: boolean, ?caseFold: boolean) → boolean</code></dt>
+      <dt><code><strong>match</strong>(pattern: regexp, ?consume: boolean) → array<string></code></dt>
+      <dd>Act like a
+      multi-character <code>eat</code>—if <code>consume</code> is true
+      or not given—or a look-ahead that doesn't update the stream
+      position—if it is false. <code>pattern</code> can be either a
+      string or a regular expression starting with <code>^</code>.
+      When it is a string, <code>caseFold</code> can be set to true to
+      make the match case-insensitive. When successfully matching a
+      regular expression, the returned value will be the array
+      returned by <code>match</code>, in case you need to extract
+      matched groups.</dd>
+
+      <dt><code><strong>backUp</strong>(n: integer)</code></dt>
+      <dd>Backs up the stream <code>n</code> characters. Backing it up
+      further than the start of the current token will cause things to
+      break, so be careful.</dd>
+      <dt><code><strong>column</strong>() → integer</code></dt>
+      <dd>Returns the column (taking into account tabs) at which the
+      current token starts.</dd>
+      <dt><code><strong>indentation</strong>() → integer</code></dt>
+      <dd>Tells you how far the current line has been indented, in
+      spaces. Corrects for tab characters.</dd>
+
+      <dt><code><strong>current</strong>() → string</code></dt>
+      <dd>Get the string between the start of the current token and
+      the current stream position.</dd>
+    </dl>
+
+    <p id="blankLine">By default, blank lines are simply skipped when
+    tokenizing a document. For languages that have significant blank
+    lines, you can define
+    a <code><strong>blankLine</strong>(state)</code> method on your
+    mode that will get called whenever a blank line is passed over, so
+    that it can update the parser state.</p>
+
+    <p id="copyState">Because state object are mutated, and CodeMirror
+    needs to keep valid versions of a state around so that it can
+    restart a parse at any line, copies must be made of state objects.
+    The default algorithm used is that a new state object is created,
+    which gets all the properties of the old object. Any properties
+    which hold arrays get a copy of these arrays (since arrays tend to
+    be used as mutable stacks). When this is not correct, for example
+    because a mode mutates non-array properties of its state object, a
+    mode object should define
+    a <code><strong>copyState</strong></code> method, which is given a
+    state and should return a safe copy of that state.</p>
+
+    <p id="indent">If you want your mode to provide smart indentation
+    (through the <a href="#indentLine"><code>indentLine</code></a>
+    method and the <code>indentAuto</code>
+    and <code>newlineAndIndent</code> commands, to which keys can be
+    <a href="#option_extraKeys">bound</a>), you must define
+    an <code><strong>indent</strong>(state, textAfter)</code> method
+    on your mode object.</p>
+
+    <p>The indentation method should inspect the given state object,
+    and optionally the <code>textAfter</code> string, which contains
+    the text on the line that is being indented, and return an
+    integer, the amount of spaces to indent. It should usually take
+    the <a href="#option_indentUnit"><code>indentUnit</code></a>
+    option into account. An indentation method may
+    return <code>CodeMirror.Pass</code> to indicate that it
+    could not come up with a precise indentation.</p>
+
+    <p id="mode_comment">To work well with
+    the <a href="#addon_comment">commenting addon</a>, a mode may
+    define <code><strong>lineComment</strong></code> (string that
+    starts a line
+    comment), <code><strong>blockCommentStart</strong></code>, <code><strong>blockCommentEnd</strong></code>
+    (strings that start and end block comments),
+    and <code>blockCommentLead</code> (a string to put at the start of
+    continued lines in a block comment). All of these are
+    optional.</p>
+
+    <p id="electricChars">Finally, a mode may define
+    an <code>electricChars</code> property, which should hold a string
+    containing all the characters that should trigger the behaviour
+    described for
+    the <a href="#option_electricChars"><code>electricChars</code></a>
+    option.</p>
+
+    <p>So, to summarize, a mode <em>must</em> provide
+    a <code>token</code> method, and it <em>may</em>
+    provide <code>startState</code>, <code>copyState</code>,
+    and <code>indent</code> methods. For an example of a trivial mode,
+    see the <a href="../mode/diff/diff.js">diff mode</a>, for a more
+    involved example, see the <a href="../mode/clike/clike.js">C-like
+    mode</a>.</p>
+
+    <p>Sometimes, it is useful for modes to <em>nest</em>—to have one
+    mode delegate work to another mode. An example of this kind of
+    mode is the <a href="../mode/htmlmixed/htmlmixed.js">mixed-mode HTML
+    mode</a>. To implement such nesting, it is usually necessary to
+    create mode objects and copy states yourself. To create a mode
+    object, there are <code>CodeMirror.getMode(options,
+    parserConfig)</code>, where the first argument is a configuration
+    object as passed to the mode constructor function, and the second
+    argument is a mode specification as in
+    the <a href="#option_mode"><code>mode</code></a> option. To copy a
+    state object, call <code>CodeMirror.copyState(mode, state)</code>,
+    where <code>mode</code> is the mode that created the given
+    state.</p>
+
+    <p id="innerMode">In a nested mode, it is recommended to add an
+    extra method, <code><strong>innerMode</strong></code> which, given
+    a state object, returns a <code>{state, mode}</code> object with
+    the inner mode and its state for the current position. These are
+    used by utility scripts such as the <a href="#addon_closetag">tag
+    closer</a> to get context information. Use
+    the <code>CodeMirror.innerMode</code> helper function to, starting
+    from a mode and a state, recursively walk down to the innermost
+    mode and state.</p>
+
+    <p>To make indentation work properly in a nested parser, it is
+    advisable to give the <code>startState</code> method of modes that
+    are intended to be nested an optional argument that provides the
+    base indentation for the block of code. The JavaScript and CSS
+    parser do this, for example, to allow JavaScript and CSS code
+    inside the mixed-mode HTML mode to be properly indented.</p>
+
+    <p id="defineMIME">It is possible, and encouraged, to associate
+    your mode, or a certain configuration of your mode, with
+    a <a href="http://en.wikipedia.org/wiki/MIME">MIME</a> type. For
+    example, the JavaScript mode associates itself
+    with <code>text/javascript</code>, and its JSON variant
+    with <code>application/json</code>. To do this,
+    call <code><strong>CodeMirror.defineMIME</strong>(mime,
+    modeSpec)</code>, where <code>modeSpec</code> can be a string or
+    object specifying a mode, as in
+    the <a href="#option_mode"><code>mode</code></a> option.</p>
+
+    <p>If a mode specification wants to add some properties to the
+    resulting mode object, typically for use
+    with <a href="#getHelpers"><code>getHelpers</code></a>, it may
+    contain a <code>modeProps</code> property, which holds an object.
+    This object's properties will be copied to the actual mode
+    object.</p>
+
+    <p id="extendMode">Sometimes, it is useful to add or override mode
+    object properties from external code.
+    The <code><strong>CodeMirror.extendMode</strong></code> function
+    can be used to add properties to mode objects produced for a
+    specific mode. Its first argument is the name of the mode, its
+    second an object that specifies the properties that should be
+    added. This is mostly useful to add utilities that can later be
+    looked up through <a href="#getMode"><code>getMode</code></a>.</p>
+</section>
+
+</article>
+
+<script>setTimeout(function(){CodeMirror.colorize();}, 20);</script>
diff --git a/app/gui/html/vendor/codemirror/doc/realworld.html b/app/gui/html/vendor/codemirror/doc/realworld.html
new file mode 100644
index 0000000..661c556
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/doc/realworld.html
@@ -0,0 +1,144 @@
+<!doctype html>
+
+<title>CodeMirror: Real-world Uses</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="docs.css">
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Real-world uses</a>
+  </ul>
+</div>
+
+<article>
+
+<h2>CodeMirror real-world uses</h2>
+
+    <p><a href="mailto:marijnh at gmail.com">Contact me</a> if you'd like
+    your project to be added to this list.</p>
+
+    <ul>
+      <li><a href="http://brackets.io">Adobe Brackets</a> (code editor)</li>
+      <li><a href="http://amber-lang.net/">Amber</a> (JavaScript-based Smalltalk system)</li>
+      <li><a href="http://apeye.org/">APEye</a> (tool for testing & documenting APIs)</li>
+      <li><a href="http://blog.bitbucket.org/2013/05/14/edit-your-code-in-the-cloud-with-bitbucket/">Bitbucket</a> (code hosting)</li>
+      <li><a href="http://buzz.blogger.com/2013/04/improvements-to-blogger-template-html.html">Blogger's template editor</a></li>
+      <li><a href="http://bluegriffon.org/">BlueGriffon</a> (HTML editor)</li>
+      <li><a href="http://cargocollective.com/">Cargo Collective</a> (creative publishing platform)</li>
+      <li><a href="https://developers.google.com/chrome-developer-tools/">Chrome DevTools</a></li>
+      <li><a href="http://clickhelp.co/">ClickHelp</a> (technical writing tool)</li>
+      <li><a href="http://complete-ly.appspot.com/playground/code.playground.html">Complete.ly playground</a></li>
+      <li><a href="http://rsnous.com/cruncher/">Cruncher</a> (notepad with calculation features)</li>
+      <li><a href="http://drupal.org/project/cpn">Code per Node</a> (Drupal module)</li>
+      <li><a href="http://www.codebugapp.com/">Codebug</a> (PHP Xdebug front-end)</li>
+      <li><a href="https://github.com/angelozerr/CodeMirror-Eclipse">CodeMirror Eclipse</a> (embed CM in Eclipse)</li>
+      <li><a href="http://emmet.io/blog/codemirror-movie/">CodeMirror movie</a> (scripted editing demos)</li>
+      <li><a href="http://code.google.com/p/codemirror2-gwt/">CodeMirror2-GWT</a> (Google Web Toolkit wrapper)</li>
+      <li><a href="http://www.crunchzilla.com/code-monster">Code Monster</a> & <a href="http://www.crunchzilla.com/code-maven">Code Maven</a> (learning environment)</li>
+      <li><a href="http://codepen.io">Codepen</a> (gallery of animations)</li>
+      <li><a href="http://sasstwo.codeschool.com/levels/1/challenges/1">Code School</a> (online tech learning environment)</li>
+      <li><a href="http://code-snippets.bungeshea.com/">Code Snippets</a> (WordPress snippet management plugin)</li>
+      <li><a href="http://antonmi.github.io/code_together/">Code together</a> (collaborative editing)</li>
+      <li><a href="http://codev.it/">Codev</a> (collaborative IDE)</li>
+      <li><a href="http://www.codezample.com">CodeZample</a> (code snippet sharing)</li>
+      <li><a href="http://codio.com">Codio</a> (Web IDE)</li>
+      <li><a href="http://ot.substance.io/demo/">Collaborative CodeMirror demo</a> (CodeMirror + operational transforms)</li>
+      <li><a href="http://www.communitycodecamp.com/">Community Code Camp</a> (code snippet sharing)</li>
+      <li><a href="http://www.compilejava.net/">compilejava.net</a> (online Java sandbox)</li>
+      <li><a href="http://www.ckwnc.com/">CKWNC</a> (UML editor)</li>
+      <li><a href="http://www.crudzilla.com/">Crudzilla</a> (self-hosted web IDE)</li>
+      <li><a href="http://cssdeck.com/">CSSDeck</a> (CSS showcase)</li>
+      <li><a href="http://ireneros.com/deck/deck.js-codemirror/introduction/#textarea-code">Deck.js integration</a> (slides with editors)</li>
+      <li><a href="http://www.dbninja.com">DbNinja</a> (MySQL access interface)</li>
+      <li><a href="https://chat.echoplex.us/">Echoplexus</a> (chat and collaborative coding)</li>
+      <li><a href="http://elm-lang.org/Examples.elm">Elm language examples</a></li>
+      <li><a href="http://eloquentjavascript.net/chapter1.html">Eloquent JavaScript</a> (book)</li>
+      <li><a href="http://emmet.io">Emmet</a> (fast XML editing)</li>
+      <li><a href="http://www.fastfig.com/">Fastfig</a> (online computation/math tool)</li>
+      <li><a href="https://metacpan.org/module/Farabi">Farabi</a> (modern Perl IDE)</li>
+      <li><a href="http://blog.pamelafox.org/2012/02/interactive-html5-slides-with-fathomjs.html">FathomJS integration</a> (slides with editors, again)</li>
+      <li><a href="http://fiddlesalad.com/">Fiddle Salad</a> (web development environment)</li>
+      <li><a href="https://hacks.mozilla.org/2013/11/firefox-developer-tools-episode-27-edit-as-html-codemirror-more/">Firefox Developer Tools</a></li>
+      <li><a href="http://www.firepad.io">Firepad</a> (collaborative text editor)</li>
+      <li><a href="https://code.google.com/p/gerrit/">Gerrit</a>'s diff view</a></li>
+      <li><a href="http://tour.golang.org">Go language tour</a></li>
+      <li><a href="https://github.com/github/android">GitHub's Android app</a></li>
+      <li><a href="https://script.google.com/">Google Apps Script</a></li>
+      <li><a href="http://web.uvic.ca/~siefkenj/graphit/graphit.html">Graphit</a> (function graphing)</li>
+      <li><a href="http://www.handcraft.com/">Handcraft</a> (HTML prototyping)</li>
+      <li><a href="http://try.haxe.org">Haxe</a> (Haxe Playground) </li>
+      <li><a href="http://haxpad.com/">HaxPad</a> (editor for Win RT)</li>
+      <li><a href="http://megafonweblab.github.com/histone-javascript/">Histone template engine playground</a></li>
+      <li><a href="http://icecoder.net">ICEcoder</a> (web IDE)</li>
+      <li><a href="http://i-mos.org/imos/">i-MOS</a> (modeling and simulation platform)</li>
+      <li><a href="http://www.janvas.com/">Janvas</a> (vector graphics editor)</li>
+      <li><a href="http://extensions.joomla.org/extensions/edition/editors/8723">Joomla plugin</a></li>
+      <li><a href="http://jqfundamentals.com/">jQuery fundamentals</a> (interactive tutorial)</li>
+      <li><a href="http://jsbin.com">jsbin.com</a> (JS playground)</li>
+      <li><a href="https://github.com/kucherenko/jscpd">jscpd</a> (code duplication detector)</li>
+      <li><a href="http://jsfiddle.com">jsfiddle.com</a> (another JS playground)</li>
+      <li><a href="http://www.jshint.com/">JSHint</a> (JS linter)</li>
+      <li><a href="http://jumpseller.com/">Jumpseller</a> (online store builder)</li>
+      <li><a href="http://kl1p.com/cmtest/1">kl1p</a> (paste service)</li>
+      <li><a href="http://kodtest.com/">Kodtest</a> (HTML/JS/CSS playground)</li>
+      <li><a href="https://laborate.io/">Laborate</a> (collaborative coding)</li>
+      <li><a href="http://lighttable.com/">Light Table</a> (experimental IDE)</li>
+      <li><a href="http://liveweave.com/">Liveweave</a> (HTML/CSS/JS scratchpad)</li>
+      <li><a href="http://marklighteditor.com/">Marklight editor</a> (lightweight markup editor)</li>
+      <li><a href="http://www.mergely.com/">Mergely</a> (interactive diffing)</li>
+      <li><a href="http://www.iunbug.com/mihtool">MIHTool</a> (iOS web-app debugging tool)</li>
+      <li><a href="http://mongo-mapreduce-webbrowser.opensagres.cloudbees.net/">Mongo MapReduce WebBrowser</a></li>
+      <li><a href="http://mvcplayground.apphb.com/">MVC Playground</a></li>
+      <li><a href="https://www.my2ndgeneration.com/">My2ndGeneration</a> (social coding)</li>
+      <li><a href="http://www.navigatecms.com">Navigate CMS</a></li>
+      <li><a href="https://github.com/soliton4/nodeMirror">nodeMirror</a> (IDE project)</li>
+      <li><a href="https://notex.ch">NoTex</a> (rST authoring)</li>
+      <li><a href="http://oakoutliner.com">Oak</a> (online outliner)</li>
+      <li><a href="http://clrhome.org/asm/">ORG</a> (z80 assembly IDE)</li>
+      <li><a href="https://github.com/mamacdon/orion-codemirror">Orion-CodeMirror integration</a> (running CodeMirror modes in Orion)</li>
+      <li><a href="http://paperjs.org/">Paper.js</a> (graphics scripting)</li>
+      <li><a href="http://prinbit.com/">PrinBit</a> (collaborative coding tool)</li>
+      <li><a href="http://prose.io/">Prose.io</a> (github content editor)</li>
+      <li><a href="http://www.puzzlescript.net/">Puzzlescript</a> (puzzle game engine)</li>
+      <li><a href="http://ql.io/">ql.io</a> (http API query helper)</li>
+      <li><a href="http://qyapp.com">QiYun web app platform</a></li>
+      <li><a href="http://ariya.ofilabs.com/2011/09/hybrid-webnative-desktop-codemirror.html">Qt+Webkit integration</a> (building a desktop CodeMirror app)</li>
+      <li><a href="http://www.quivive-file-manager.com">Quivive File Manager</a></li>
+      <li><a href="http://rascalmicro.com/docs/basic-tutorial-getting-started.html">Rascal</a> (tiny computer)</li>
+      <li><a href="https://www.realtime.io/">RealTime.io</a> (Internet-of-Things infrastructure)</li>
+      <li><a href="https://www.shadertoy.com/">Shadertoy</a> (shader sharing)</li>
+      <li><a href="http://www.sketchpatch.net/labs/livecodelabIntro.html">sketchPatch Livecodelab</a></li>
+      <li><a href="http://www.skulpt.org/">Skulpt</a> (in-browser Python environment)</li>
+      <li><a href="http://snippets.pro/">Snippets.pro</a> (code snippet sharing)</li>
+      <li><a href="http://www.solidshops.com/">SolidShops</a> (hosted e-commerce platform)</li>
+      <li><a href="http://sqlfiddle.com">SQLFiddle</a> (SQL playground)</li>
+      <li><a href="https://thefiletree.com">The File Tree</a> (collab editor)</li>
+      <li><a href="http://www.mapbox.com/tilemill/">TileMill</a> (map design tool)</li>
+      <li><a href="http://www.toolsverse.com/products/data-explorer/">Toolsverse Data Explorer</a> (database management)</li>
+      <li><a href="http://enjalot.com/tributary/2636296/sinwaves.js">Tributary</a> (augmented editing)</li>
+      <li><a href="http://blog.englard.net/post/39608000629/codeintumblr">Tumblr code highlighting shim</a></li>
+      <li><a href="http://turbopy.com/">TurboPY</a> (web publishing framework)</li>
+      <li><a href="http://uicod.com/">uiCod</a> (animation demo gallery and sharing)</li>
+      <li><a href="http://cruise.eecs.uottawa.ca/umpleonline/">UmpleOnline</a> (model-oriented programming tool)</li>
+      <li><a href="https://upsource.jetbrains.com/#idea/view/923f30395f2603cd9f42a32bcafd13b6c28de0ff/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java">Upsource</a> (code viewer)</li>
+      <li><a href="https://github.com/brettz9/webappfind">webappfind</a> (windows file bindings for webapps)</li>
+      <li><a href="http://www.webglacademy.com/">WebGL academy</a> (learning WebGL)</li>
+      <li><a href="http://webglplayground.net/">WebGL playground</a></li>
+      <li><a href="https://www.webkit.org/blog/2518/state-of-web-inspector/#source-code">WebKit Web inspector</a></li>
+      <li><a href="http://www.wescheme.org/">WeScheme</a> (learning tool)</li>
+      <li><a href="http://wordpress.org/extend/plugins/codemirror-for-codeeditor/">WordPress plugin</a></li>
+      <li><a href="https://www.writelatex.com">writeLaTeX</a> (Collaborative LaTeX Editor)</li>
+      <li><a href="http://www.xosystem.org/home/applications_websites/xosystem_website/xoside_EN.php">XOSide</a> (online editor)</li>
+      <li><a href="http://videlibri.sourceforge.net/cgi-bin/xidelcgi">XQuery tester</a></li>
+      <li><a href="http://q42jaap.github.io/xsd2codemirror/">xsd2codemirror</a> (convert XSD to CM XML completion info)</li>
+    </ul>
+
+</article>
+
diff --git a/app/gui/html/vendor/codemirror/doc/releases.html b/app/gui/html/vendor/codemirror/doc/releases.html
new file mode 100644
index 0000000..16958c6
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/doc/releases.html
@@ -0,0 +1,832 @@
+<!doctype html>
+
+<title>CodeMirror: Release History</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="docs.css">
+<script src="activebookmark.js"></script>
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active data-default="true" href="#v3">Version 3.x</a>
+    <li><a href="#v2">Version 2.x</a>
+    <li><a href="#v1">Version 0.x</a>
+  </ul>
+</div>
+
+<article>
+
+<h2>Release notes and version history</h2>
+
+<section id=v3 class=first>
+
+  <h2>Version 4.x</h2>
+
+  <p class="rel">20-03-2014: <a href="http://codemirror.net/codemirror-4.0.zip">Version 4.0</a>:</p>
+
+  <p class="rel-note">This is a new major version of CodeMirror. There
+  are a few <strong>incompatible</strong> changes in the API. Upgrade
+  with care, and read the <a href="upgrade_v4.html">upgrading
+  guide</a>.</p>
+
+  <ul class="rel-note">
+    <li>Multiple selections (ctrl-click, alt-drag, <a href="manual.html#setSelections">API</a>).</li>
+    <li>Sublime Text <a href="../demo/sublime.html">bindings</a>.</li>
+    <li><a href="manual.html#modloader">Module loader shims</a> wrapped around all modules.</li>
+    <li>Selection <a href="manual.html#command_undoSelection">undo</a>/<a href="manual.html#command_redoSelection">redo</a>.</li>
+    <li>Improved character measuring (faster, handles wrapped lines more robustly).</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.23.0...4.0.3">list of patches</a>.</li>
+  </ul>
+
+  <h2>Version 3.x</h2>
+
+  <p class="rel">21-02-2014: <a href="http://codemirror.net/codemirror-3.22.zip">Version 3.22</a>:</p>
+
+  <ul class="rel-note">
+    <li>Adds the <a href="manual.html#findMarks"><code>findMarks</code></a> method.</li>
+    <li>New addons: <a href="manual.html#addon_rulers">rulers</a>, markdown-fold, yaml-lint.</li>
+    <li>New theme: <a href="../demo/theme.html?mdn-like">mdn-like</a>.</li>
+    <li>New mode: <a href="../mode/solr/index.html">Solr</a>.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.21.0...3.22.0">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">16-01-2014: <a href="http://codemirror.net/codemirror-3.21.zip">Version 3.21</a>:</p>
+
+  <ul class="rel-note">
+    <li>Auto-indenting a block will no longer add trailing whitespace to blank lines.</a>
+    <li>Marking text has a new option <a href="manual.html#markText"><code>clearWhenEmpty</code></a> to control auto-removal.</li>
+    <li>Several bugfixes in the handling of bidirectional text.</li>
+    <li>The <a href="../mode/xml/index.html">XML</a> and <a href="../mode/css/index.html">CSS</a> modes were largely rewritten. <a href="../mode/css/less.html">LESS</a> support was added to the CSS mode.</li>
+    <li>The OCaml mode was moved to an <a href="../mode/mllike/index.html">mllike</a> mode, F# support added.</li>
+    <li>Make it possible to fetch multiple applicable helper values with <a href="manual.html#getHelpers"><code>getHelpers</code></a>, and to register helpers matched on predicates with <a href="manual.html#registerGlobalHelper"><code>registerGlobalHelper</code></a>.</li>
+    <li>New theme <a href="../demo/theme.html?pastel-on-dark">pastel-on-dark</a>.</li>
+    <li>Better ECMAScript 6 support in <a href="../mode/javascript/index.html">JavaScript</a> mode.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.20.0...3.21.0">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">21-11-2013: <a href="http://codemirror.net/codemirror-3.20.zip">Version 3.20</a>:</p>
+
+  <ul class="rel-note">
+    <li>New modes: <a href="../mode/julia/index.html">Julia</a> and <a href="../mode/pegjs/index.html">PEG.js</a>.</li>
+    <li>Support ECMAScript 6 in the <a href="../mode/javascript/index.html">JavaScript mode</a>.</li>
+    <li>Improved indentation for the <a href="../mode/coffeescript/index.html">CoffeeScript mode</a>.</li>
+    <li>Make non-printable-character representation <a href="manual.html#option_specialChars">configurable</a>.</li>
+    <li>Add ‘notification’ functionality to <a href="manual.html#addon_dialog">dialog</a> addon.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.19.0...3.20.0">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">21-10-2013: <a href="http://codemirror.net/codemirror-3.19.zip">Version 3.19</a>:</p>
+
+  <ul class="rel-note">
+    <li>New modes: <a href="../mode/eiffel/index.html">Eiffel</a>, <a href="../mode/gherkin/index.html">Gherkin</a>, <a href="../mode/sql/?mime=text/x-mssql">MSSQL dialect</a>.</li>
+    <li>New addons: <a href="manual.html#addon_hardwrap">hardwrap</a>, <a href="manual.html#addon_sql-hint">sql-hint</a>.</li>
+    <li>New theme: <a href="../demo/theme.html?mbo">MBO</a>.</li>
+    <li>Add <a href="manual.html#token_style_line">support</a> for line-level styling from mode tokenizers.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.18.0...3.19.0">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">23-09-2013: <a href="http://codemirror.net/codemirror-3.18.zip">Version 3.18</a>:</p>
+
+  <p class="rel-note">Emergency release to fix a problem in 3.17
+  where <code>.setOption("lineNumbers", false)</code> would raise an
+  error.</p>
+
+  <p class="rel">23-09-2013: <a href="http://codemirror.net/codemirror-3.17.zip">Version 3.17</a>:</p>
+
+  <ul class="rel-note">
+    <li>New modes: <a href="../mode/fortran/index.html">Fortran</a>, <a href="../mode/octave/index.html">Octave</a> (Matlab), <a href="../mode/toml/index.html">TOML</a>, and <a href="../mode/dtd/index.html">DTD</a>.</li>
+    <li>New addons: <a href="../addon/lint/css-lint.js"><code>css-lint</code></a>, <a href="manual.html#addon_css-hint"><code>css-hint</code></a>.</li>
+    <li>Improve resilience to CSS 'frameworks' that globally mess up <code>box-sizing</code>.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.16.0...3.17.0">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">21-08-2013: <a href="http://codemirror.net/codemirror-3.16.zip">Version 3.16</a>:</p>
+
+  <ul class="rel-note">
+    <li>The whole codebase is now under a single <a href="../LICENSE">license</a> file.</li>
+    <li>The project page was overhauled and redesigned.</li>
+    <li>New themes: <a href="../demo/theme.html?paraiso-dark">Paraiso</a> (<a href="../demo/theme.html?paraiso-light">light</a>), <a href="../demo/theme.html?the-matrix">The Matrix</a>.</li>
+    <li>Improved interaction between themes and <a href="manual.html#addon_active-line">active-line</a>/<a href="manual.html#addon_matchbrackets">matchbrackets</a> addons.</li>
+    <li>New <a href="manual.html#addon_foldcode">folding</a> function <code>CodeMirror.fold.comment</code>.</li>
+    <li>Added <a href="manual.html#addon_fullscreen">fullscreen</a> addon.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.15.0...3.16.0">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">29-07-2013: <a href="http://codemirror.net/codemirror-3.15.zip">Version 3.15</a>:</p>
+
+  <ul class="rel-note">
+    <li>New modes: <a href="../mode/jade/index.html">Jade</a>, <a href="../mode/nginx/index.html">Nginx</a>.</li>
+    <li>New addons: <a href="../demo/tern.html">Tern</a>, <a href="manual.html#addon_matchtags">matchtags</a>, and <a href="manual.html#addon_foldgutter">foldgutter</a>.</li>
+    <li>Introduced <a href="manual.html#getHelper"><em>helper</em></a> concept (<a href="https://groups.google.com/forum/#!msg/codemirror/cOc0xvUUEUU/nLrX1-qnidgJ">context</a>).</li>
+    <li>New method: <a href="manual.html#getModeAt"><code>getModeAt</code></a>.</li>
+    <li>New themes: base16 <a href="../demo/theme.html?base16-dark">dark</a>/<a href="../demo/theme.html?base16-light">light</a>, 3024 <a href="../demo/theme.html?3024-night">dark</a>/<a href="../demo/theme.html?3024-day">light</a>, <a href="../demo/theme.html?tomorrow-night-eighties">tomorrow-night</a>.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.14.0...3.15.0">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">20-06-2013: <a href="http://codemirror.net/codemirror-3.14.zip">Version 3.14</a>:</p>
+
+  <ul class="rel-note">
+    <li>New
+    addons: <a href="manual.html#addon_trailingspace">trailing
+    space highlight</a>, <a href="manual.html#addon_xml-hint">XML
+    completion</a> (rewritten),
+    and <a href="manual.html#addon_merge">diff merging</a>.</li>
+    <li><a href="manual.html#markText"><code>markText</code></a>
+    and <a href="manual.html#addLineWidget"><code>addLineWidget</code></a>
+    now take a <code>handleMouseEvents</code> option.</li>
+    <li>New methods: <a href="manual.html#lineAtHeight"><code>lineAtHeight</code></a>,
+    <a href="manual.html#getTokenTypeAt"><code>getTokenTypeAt</code></a>.</li>
+    <li>More precise cleanness-tracking
+    using <a href="manual.html#changeGeneration"><code>changeGeneration</code></a>
+    and <a href="manual.html#isClean"><code>isClean</code></a>.</li>
+    <li>Many extensions to <a href="../demo/emacs.html">Emacs</a> mode
+    (prefixes, more navigation units, and more).</li>
+    <li>New
+    events <a href="manual.html#event_keyHandled"><code>"keyHandled"</code></a>
+    and <a href="manual.html#event_inputRead"><code>"inputRead"</code></a>.</li>
+    <li>Various improvements to <a href="../mode/ruby/index.html">Ruby</a>,
+    <a href="../mode/smarty/index.html">Smarty</a>, <a href="../mode/sql/index.html">SQL</a>,
+    and <a href="../demo/vim.html">Vim</a> modes.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.13.0...3.14.0">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">20-05-2013: <a href="http://codemirror.net/codemirror-3.13.zip">Version 3.13</a>:</p>
+
+  <ul class="rel-note">
+    <li>New modes: <a href="../mode/cobol/index.html">COBOL</a> and <a href="../mode/haml/index.html">HAML</a>.</li>
+    <li>New options: <a href="manual.html#option_cursorScrollMargin"><code>cursorScrollMargin</code></a> and <a href="manual.html#option_coverGutterNextToScrollbar"><code>coverGutterNextToScrollbar</code></a>.</li>
+    <li>New addon: <a href="manual.html#addon_comment">commenting</a>.</li>
+    <li>More features added to the <a href="../demo/vim.html">Vim keymap</a>.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.12...3.13.0">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">19-04-2013: <a href="http://codemirror.net/codemirror-3.12.zip">Version 3.12</a>:</p>
+
+  <ul class="rel-note">
+    <li>New mode: <a href="../mode/gas/index.html">GNU assembler</a>.</li>
+    <li>New
+    options: <a href="manual.html#option_maxHighlightLength"><code>maxHighlightLength</code></a>
+    and <a href="manual.html#option_historyEventDelay"><code>historyEventDelay</code></a>.</li>
+    <li>Added <a href="manual.html#mark_addToHistory"><code>addToHistory</code></a>
+    option for <code>markText</code>.</li>
+    <li>Various fixes to JavaScript tokenization and indentation corner cases.</li>
+    <li>Further improvements to the vim mode.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.11...v3.12">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">20-03-2013: <a href="http://codemirror.net/codemirror-3.11.zip">Version 3.11</a>:</p>
+
+  <ul class="rel-note">
+    <li><strong>Removed code:</strong> <code>collapserange</code>,
+    <code>formatting</code>, and <code>simple-hint</code>
+    addons. <code>plsql</code> and <code>mysql</code> modes
+    (use <a href="../mode/sql/index.html"><code>sql</code></a> mode).</li>
+    <li><strong>Moved code:</strong> the range-finding functions for folding now have <a href="../addon/fold/">their own files</a>.</li>
+    <li><strong>Changed interface:</strong>
+    the <a href="manual.html#addon_continuecomment"><code>continuecomment</code></a>
+    addon now exposes an option, rather than a command.</li>
+    <li>New
+    modes: <a href="../mode/css/scss.html">SCSS</a>, <a href="../mode/tcl/index.html">Tcl</a>, <a href="../mode/livescript/index.html">LiveScript</a>,
+    and <a href="../mode/mirc/index.html">mIRC</a>.</li>
+    <li>New addons: <a href="../demo/placeholder.html"><code>placeholder</code></a>, <a href="../demo/html5complete.html">HTML completion</a>.</li>
+    <li>New
+    methods: <a href="manual.html#hasFocus"><code>hasFocus</code></a>, <a href="manual.html#defaultCharWidth"><code>defaultCharWidth</code></a>.</li>
+    <li>New events: <a href="manual.html#event_beforeCursorEnter"><code>beforeCursorEnter</code></a>, <a href="manual.html#event_renderLine"><code>renderLine</code></a>.</li>
+    <li>Many improvements to the <a href="manual.html#addon_show-hint"><code>show-hint</code></a> completion
+    dialog addon.</li>
+    <li>Tweak behavior of by-word cursor motion.</li>
+    <li>Further improvements to the <a href="../demo/vim.html">vim mode</a>.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.1...v3.11">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">21-02-2013: <a href="http://codemirror.net/codemirror-3.1.zip">Version 3.1</a>:</p>
+
+  <ul class="rel-note">
+    <li><strong>Incompatible:</strong> key handlers may
+    now <em>return</em>, rather
+    than <em>throw</em> <code>CodeMirror.Pass</code> to signal they
+    didn't handle the key.</li>
+    <li>Make documents a <a href="manual.html#api_doc">first-class
+    construct</a>, support split views and subviews.</li>
+    <li>Add a <a href="manual.html#addon_show-hint">new module</a>
+    for showing completion hints.
+    Deprecate <code>simple-hint.js</code>.</li>
+    <li>Extend <a href="../mode/htmlmixed/index.html">htmlmixed mode</a>
+    to allow custom handling of script types.</li>
+    <li>Support an <code>insertLeft</code> option
+    to <a href="manual.html#setBookmark"><code>setBookmark</code></a>.</li>
+    <li>Add an <a href="manual.html#eachLine"><code>eachLine</code></a>
+    method to iterate over a document.</li>
+    <li>New addon modules: <a href="../demo/markselection.html">selection
+    marking</a>, <a href="../demo/lint.html">linting</a>,
+    and <a href="../demo/closebrackets.html">automatic bracket
+    closing</a>.</li>
+    <li>Add <a href="manual.html#event_beforeChange"><code>"beforeChange"</code></a>
+    and <a href="manual.html#event_beforeSelectionChange"><code>"beforeSelectionChange"</code></a>
+    events.</li>
+    <li>Add <a href="manual.html#event_hide"><code>"hide"</code></a>
+    and <a href="manual.html#event_unhide"><code>"unhide"</code></a>
+    events to marked ranges.</li>
+    <li>Fix <a href="manual.html#coordsChar"><code>coordsChar</code></a>'s
+    interpretation of its argument to match the documentation.</li>
+    <li>New modes: <a href="../mode/turtle/index.html">Turtle</a>
+    and <a href="../mode/q/index.html">Q</a>.</li>
+    <li>Further improvements to the <a href="../demo/vim.html">vim mode</a>.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.01...v3.1">list of patches</a>.</li>
+  </ul>
+  
+
+  <p class="rel">25-01-2013: <a href="http://codemirror.net/codemirror-3.02.zip">Version 3.02</a>:</p>
+
+  <p class="rel-note">Single-bugfix release. Fixes a problem that
+  prevents CodeMirror instances from being garbage-collected after
+  they become unused.</p>
+
+  <p class="rel">21-01-2013: <a href="http://codemirror.net/codemirror-3.01.zip">Version 3.01</a>:</p>
+
+  <ul class="rel-note">
+    <li>Move all add-ons into an organized directory structure
+    under <a href="../addon/"><code>/addon</code></a>. <strong>You might have to adjust your
+    paths.</strong></li>
+    <li>New
+    modes: <a href="../mode/d/index.html">D</a>, <a href="../mode/sass/index.html">Sass</a>, <a href="../mode/apl/index.html">APL</a>, <a href="../mode/sql/index.html">SQL</a>
+    (configurable), and <a href="../mode/asterisk/index.html">Asterisk</a>.</li>
+    <li>Several bugfixes in right-to-left text support.</li>
+    <li>Add <a href="manual.html#option_rtlMoveVisually"><code>rtlMoveVisually</code></a> option.</li>
+    <li>Improvements to vim keymap.</li>
+    <li>Add built-in (lightweight) <a href="manual.html#addOverlay">overlay mode</a> support.</li>
+    <li>Support <code>showIfHidden</code> option for <a href="manual.html#addLineWidget">line widgets</a>.</li>
+    <li>Add simple <a href="manual.html#addon_python-hint">Python hinter</a>.</li>
+    <li>Bring back the <a href="manual.html#option_fixedGutter"><code>fixedGutter</code></a> option.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.0...v3.01">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">10-12-2012: <a href="http://codemirror.net/codemirror-3.0.zip">Version 3.0</a>:</p>
+
+  <p class="rel-note"><strong>New major version</strong>. Only
+  partially backwards-compatible. See
+  the <a href="upgrade_v3.html">upgrading guide</a> for more
+  information. Changes since release candidate 2:</p>
+
+  <ul class="rel-note">
+    <li>Rewritten VIM mode.</li>
+    <li>Fix a few minor scrolling and sizing issues.</li>
+    <li>Work around Safari segfault when dragging.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.0rc2...v3.0">list of patches</a>.</li>
+  </ul>
+  
+  <p class="rel">20-11-2012: <a href="http://codemirror.net/codemirror-3.0rc2.zip">Version 3.0, release candidate 2</a>:</p>
+
+  <ul class="rel-note">
+    <li>New mode: <a href="../mode/http/index.html">HTTP</a>.</li>
+    <li>Improved handling of selection anchor position.</li>
+    <li>Improve IE performance on longer lines.</li>
+    <li>Reduce gutter glitches during horiz. scrolling.</li>
+    <li>Add <a href="manual.html#addKeyMap"><code>addKeyMap</code></a> and <a href="manual.html#removeKeyMap"><code>removeKeyMap</code></a> methods.</li>
+    <li>Rewrite <code>formatting</code> and <code>closetag</code> add-ons.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.0rc1...v3.0rc2">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">20-11-2012: <a href="http://codemirror.net/codemirror-3.0rc1.zip">Version 3.0, release candidate 1</a>:</p>
+
+  <ul class="rel-note">
+    <li>New theme: <a href="../demo/theme.html?solarized%20light">Solarized</a>.</li>
+    <li>Introduce <a href="manual.html#addLineClass"><code>addLineClass</code></a>
+    and <a href="manual.html#removeLineClass"><code>removeLineClass</code></a>,
+    drop <code>setLineClass</code>.</li>
+    <li>Add a <em>lot</em> of
+    new <a href="manual.html#markText">options for marked text</a>
+    (read-only, atomic, collapsed, widget replacement).</li>
+    <li>Remove the old code folding interface in favour of these new ranges.</li>
+    <li>Add <a href="manual.html#isClean"><code>isClean</code></a>/<a href="manual.html#markClean"><code>markClean</code></a> methods.</li>
+    <li>Remove <code>compoundChange</code> method, use better undo-event-combining heuristic.</li>
+    <li>Improve scrolling performance smoothness.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.0beta2...v3.0rc1">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">22-10-2012: <a href="http://codemirror.net/codemirror-3.0beta2.zip">Version 3.0, beta 2</a>:</p>
+
+  <ul class="rel-note">
+    <li>Fix page-based coordinate computation.</li>
+    <li>Fix firing of <a href="manual.html#event_gutterClick"><code>gutterClick</code></a> event.</li>
+    <li>Add <a href="manual.html#option_cursorHeight"><code>cursorHeight</code></a> option.</li>
+    <li>Fix bi-directional text regression.</li>
+    <li>Add <a href="manual.html#option_viewportMargin"><code>viewportMargin</code></a> option.</li>
+    <li>Directly handle mousewheel events (again, hopefully better).</li>
+    <li>Make vertical cursor movement more robust (through widgets, big line gaps).</li>
+    <li>Add <a href="manual.html#option_flattenSpans"><code>flattenSpans</code></a> option.</li>
+    <li>Many optimizations. Poor responsiveness should be fixed.</li>
+    <li>Initialization in hidden state works again.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.0beta1...v3.0beta2">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">19-09-2012: <a href="http://codemirror.net/codemirror-3.0beta1.zip">Version 3.0, beta 1</a>:</p>
+
+  <ul class="rel-note">
+    <li>Bi-directional text support.</li>
+    <li>More powerful gutter model.</li>
+    <li>Support for arbitrary text/widget height.</li>
+    <li>In-line widgets.</li>
+    <li>Generalized event handling.</li>
+  </ul>
+
+</section>
+
+<section id=v2>
+
+  <h2>Version 2.x</h2>
+
+  <p class="rel">21-01-2013: <a href="http://codemirror.net/codemirror-2.38.zip">Version 2.38</a>:</p>
+
+  <p class="rel-note">Integrate some bugfixes, enhancements to the vim keymap, and new
+  modes
+  (<a href="../mode/d/index.html">D</a>, <a href="../mode/sass/index.html">Sass</a>, <a href="../mode/apl/index.html">APL</a>)
+  from the v3 branch.</p>
+
+  <p class="rel">20-12-2012: <a href="http://codemirror.net/codemirror-2.37.zip">Version 2.37</a>:</p>
+
+  <ul class="rel-note">
+    <li>New mode: <a href="../mode/sql/index.html">SQL</a> (will replace <a href="../mode/plsql/index.html">plsql</a> and <a href="../mode/mysql/index.html">mysql</a> modes).</li>
+    <li>Further work on the new VIM mode.</li>
+    <li>Fix Cmd/Ctrl keys on recent Operas on OS X.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v2.36...v2.37">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">20-11-2012: <a href="http://codemirror.net/codemirror-2.36.zip">Version 2.36</a>:</p>
+
+  <ul class="rel-note">
+    <li>New mode: <a href="../mode/z80/index.html">Z80 assembly</a>.</li>
+    <li>New theme: <a href="../demo/theme.html?twilight">Twilight</a>.</li>
+    <li>Add command-line compression helper.</li>
+    <li>Make <a href="manual.html#scrollIntoView"><code>scrollIntoView</code></a> public.</li>
+    <li>Add <a href="manual.html#defaultTextHeight"><code>defaultTextHeight</code></a> method.</li>
+    <li>Various extensions to the vim keymap.</li>
+    <li>Make <a href="../mode/php/index.html">PHP mode</a> build on <a href="../mode/htmlmixed/index.html">mixed HTML mode</a>.</li>
+    <li>Add <a href="manual.html#addon_continuecomment">comment-continuing</a> add-on.</li>
+    <li>Full <a href="../https://github.com/marijnh/CodeMirror/compare/v2.35...v2.36">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">22-10-2012: <a href="http://codemirror.net/codemirror-2.35.zip">Version 2.35</a>:</p>
+
+  <ul class="rel-note">
+    <li>New (sub) mode: <a href="../mode/javascript/typescript.html">TypeScript</a>.</li>
+    <li>Don't overwrite (insert key) when pasting.</li>
+    <li>Fix several bugs in <a href="manual.html#markText"><code>markText</code></a>/undo interaction.</li>
+    <li>Better indentation of JavaScript code without semicolons.</li>
+    <li>Add <a href="manual.html#defineInitHook"><code>defineInitHook</code></a> function.</li>
+    <li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v2.34...v2.35">list of patches</a>.</li>
+  </ul>
+
+  <p class="rel">19-09-2012: <a href="http://codemirror.net/codemirror-2.34.zip">Version 2.34</a>:</p>
+
+  <ul class="rel-note">
+    <li>New mode: <a href="../mode/commonlisp/index.html">Common Lisp</a>.</li>
+    <li>Fix right-click select-all on most browsers.</li>
+    <li>Change the way highlighting happens:<br>  Saves memory and CPU cycles.<br>  <code>compareStates</code> is no longer needed.<br>  <code>onHighlightComplete</code> no longer works.</li>
+    <li>Integrate mode (Markdown, XQuery, CSS, sTex) tests in central testsuite.</li>
+    <li>Add a <a href="manual.html#version"><code>CodeMirror.version</code></a> property.</li>
+    <li>More robust handling of nested modes in <a href="../demo/formatting.html">formatting</a> and <a href="../demo/closetag.html">closetag</a> plug-ins.</li>
+    <li>Un/redo now preserves <a href="manual.html#markText">marked text</a> and bookmarks.</li>
+    <li><a href="https://github.com/marijnh/CodeMirror/compare/v2.33...v2.34">Full list</a> of patches.</li>
+  </ul>
+
+  <p class="rel">23-08-2012: <a href="http://codemirror.net/codemirror-2.33.zip">Version 2.33</a>:</p>
+
+  <ul class="rel-note">
+    <li>New mode: <a href="../mode/sieve/index.html">Sieve</a>.</li>
+    <li>New <a href="manual.html#getViewport"><code>getViewPort</code></a> and <a href="manual.html#option_onViewportChange"><code>onViewportChange</code></a> API.</li>
+    <li><a href="manual.html#option_cursorBlinkRate">Configurable</a> cursor blink rate.</li>
+    <li>Make binding a key to <code>false</code> disabling handling (again).</li>
+    <li>Show non-printing characters as red dots.</li>
+    <li>More tweaks to the scrolling model.</li>
+    <li>Expanded testsuite. Basic linter added.</li>
+    <li>Remove most uses of <code>innerHTML</code>. Remove <code>CodeMirror.htmlEscape</code>.</li>
+    <li><a href="https://github.com/marijnh/CodeMirror/compare/v2.32...v2.33">Full list</a> of patches.</li>
+  </ul>
+
+  <p class="rel">23-07-2012: <a href="http://codemirror.net/codemirror-2.32.zip">Version 2.32</a>:</p>
+
+  <p class="rel-note">Emergency fix for a bug where an editor with
+  line wrapping on IE will break when there is <em>no</em>
+  scrollbar.</p>
+
+  <p class="rel">20-07-2012: <a href="http://codemirror.net/codemirror-2.31.zip">Version 2.31</a>:</p>
+
+  <ul class="rel-note">
+    <li>New modes: <a href="../mode/ocaml/index.html">OCaml</a>, <a href="../mode/haxe/index.html">Haxe</a>, and <a href="../mode/vb/index.html">VB.NET</a>.</li>
+    <li>Several fixes to the new scrolling model.</li>
+    <li>Add a <a href="manual.html#setSize"><code>setSize</code></a> method for programmatic resizing.</li>
+    <li>Add <a href="manual.html#getHistory"><code>getHistory</code></a> and <a href="manual.html#setHistory"><code>setHistory</code></a> methods.</li>
+    <li>Allow custom line separator string in <a href="manual.html#getValue"><code>getValue</code></a> and <a href="manual.html#getRange"><code>getRange</code></a>.</li>
+    <li>Support double- and triple-click drag, double-clicking whitespace.</li>
+    <li>And more... <a href="https://github.com/marijnh/CodeMirror/compare/v2.3...v2.31">(all patches)</a></li>
+  </ul>
+
+  <p class="rel">22-06-2012: <a href="http://codemirror.net/codemirror-2.3.zip">Version 2.3</a>:</p>
+
+  <ul class="rel-note">
+    <li><strong>New scrollbar implementation</strong>. Should flicker less. Changes DOM structure of the editor.</li>
+    <li>New theme: <a href="../demo/theme.html?vibrant-ink">vibrant-ink</a>.</li>
+    <li>Many extensions to the VIM keymap (including text objects).</li>
+    <li>Add <a href="../demo/multiplex.html">mode-multiplexing</a> utility script.</li>
+    <li>Fix bug where right-click paste works in read-only mode.</li>
+    <li>Add a <a href="manual.html#getScrollInfo"><code>getScrollInfo</code></a> method.</li>
+    <li>Lots of other <a href="https://github.com/marijnh/CodeMirror/compare/v2.25...v2.3">fixes</a>.</li>
+  </ul>
+
+  <p class="rel">23-05-2012: <a href="http://codemirror.net/codemirror-2.25.zip">Version 2.25</a>:</p>
+
+  <ul class="rel-note">
+    <li>New mode: <a href="../mode/erlang/index.html">Erlang</a>.</li>
+    <li><strong>Remove xmlpure mode</strong> (use <a href="../mode/xml/index.html">xml.js</a>).</li>
+    <li>Fix line-wrapping in Opera.</li>
+    <li>Fix X Windows middle-click paste in Chrome.</li>
+    <li>Fix bug that broke pasting of huge documents.</li>
+    <li>Fix backspace and tab key repeat in Opera.</li>
+  </ul>
+
+  <p class="rel">23-04-2012: <a href="http://codemirror.net/codemirror-2.24.zip">Version 2.24</a>:</p>
+
+  <ul class="rel-note">
+    <li><strong>Drop support for Internet Explorer 6</strong>.</li>
+    <li>New
+    modes: <a href="../mode/shell/index.html">Shell</a>, <a href="../mode/tiki/index.html">Tiki
+    wiki</a>, <a href="../mode/pig/index.html">Pig Latin</a>.</li>
+    <li>New themes: <a href="../demo/theme.html?ambiance">Ambiance</a>, <a href="../demo/theme.html?blackboard">Blackboard</a>.</li>
+    <li>More control over drag/drop
+    with <a href="manual.html#option_dragDrop"><code>dragDrop</code></a>
+    and <a href="manual.html#option_onDragEvent"><code>onDragEvent</code></a>
+    options.</li>
+    <li>Make HTML mode a bit less pedantic.</li>
+    <li>Add <a href="manual.html#compoundChange"><code>compoundChange</code></a> API method.</li>
+    <li>Several fixes in undo history and line hiding.</li>
+    <li>Remove (broken) support for <code>catchall</code> in key maps,
+    add <code>nofallthrough</code> boolean field instead.</li>
+  </ul>
+
+  <p class="rel">26-03-2012: <a href="http://codemirror.net/codemirror-2.23.zip">Version 2.23</a>:</p>
+
+  <ul class="rel-note">
+    <li>Change <strong>default binding for tab</strong> <a href="javascript:void(document.getElementById('tabbinding').style.display='')">[more]</a>
+      <div style="display: none" id=tabbinding>
+        Starting in 2.23, these bindings are default:
+        <ul><li>Tab: Insert tab character</li>
+          <li>Shift-tab: Reset line indentation to default</li>
+          <li>Ctrl/Cmd-[: Reduce line indentation (old tab behaviour)</li>
+          <li>Ctrl/Cmd-]: Increase line indentation (old shift-tab behaviour)</li>
+        </ul>
+      </div>
+    </li>
+    <li>New modes: <a href="../mode/xquery/index.html">XQuery</a> and <a href="../mode/vbscript/index.html">VBScript</a>.</li>
+    <li>Two new themes: <a href="../mode/less/index.html">lesser-dark</a> and <a href="../mode/xquery/index.html">xq-dark</a>.</li>
+    <li>Differentiate between background and text styles in <a href="manual.html#setLineClass"><code>setLineClass</code></a>.</li>
+    <li>Fix drag-and-drop in IE9+.</li>
+    <li>Extend <a href="manual.html#charCoords"><code>charCoords</code></a>
+    and <a href="manual.html#cursorCoords"><code>cursorCoords</code></a> with a <code>mode</code> argument.</li>
+    <li>Add <a href="manual.html#option_autofocus"><code>autofocus</code></a> option.</li>
+    <li>Add <a href="manual.html#findMarksAt"><code>findMarksAt</code></a> method.</li>
+  </ul>
+
+  <p class="rel">27-02-2012: <a href="http://codemirror.net/codemirror-2.22.zip">Version 2.22</a>:</p>
+
+  <ul class="rel-note">
+    <li>Allow <a href="manual.html#keymaps">key handlers</a> to pass up events, allow binding characters.</li>
+    <li>Add <a href="manual.html#option_autoClearEmptyLines"><code>autoClearEmptyLines</code></a> option.</li>
+    <li>Properly use tab stops when rendering tabs.</li>
+    <li>Make PHP mode more robust.</li>
+    <li>Support indentation blocks in <a href="manual.html#addon_foldcode">code folder</a>.</li>
+    <li>Add a script for <a href="manual.html#addon_match-highlighter">highlighting instances of the selection</a>.</li>
+    <li>New <a href="../mode/properties/index.html">.properties</a> mode.</li>
+    <li>Fix many bugs.</li>
+  </ul>
+
+  <p class="rel">27-01-2012: <a href="http://codemirror.net/codemirror-2.21.zip">Version 2.21</a>:</p>
+
+  <ul class="rel-note">
+    <li>Added <a href="../mode/less/index.html">LESS</a>, <a href="../mode/mysql/index.html">MySQL</a>,
+    <a href="../mode/go/index.html">Go</a>, and <a href="../mode/verilog/index.html">Verilog</a> modes.</li>
+    <li>Add <a href="manual.html#option_smartIndent"><code>smartIndent</code></a>
+    option.</li>
+    <li>Support a cursor in <a href="manual.html#option_readOnly"><code>readOnly</code></a>-mode.</li>
+    <li>Support assigning multiple styles to a token.</li>
+    <li>Use a new approach to drawing the selection.</li>
+    <li>Add <a href="manual.html#scrollTo"><code>scrollTo</code></a> method.</li>
+    <li>Allow undo/redo events to span non-adjacent lines.</li>
+    <li>Lots and lots of bugfixes.</li>
+  </ul>
+
+  <p class="rel">20-12-2011: <a href="http://codemirror.net/codemirror-2.2.zip">Version 2.2</a>:</p>
+
+  <ul class="rel-note">
+    <li>Slightly incompatible API changes. Read <a href="upgrade_v2.2.html">this</a>.</li>
+    <li>New approach
+    to <a href="manual.html#option_extraKeys">binding</a> keys,
+    support for <a href="manual.html#option_keyMap">custom
+    bindings</a>.</li>
+    <li>Support for overwrite (insert).</li>
+    <li><a href="manual.html#option_tabSize">Custom-width</a>
+    and <a href="../demo/visibletabs.html">stylable</a> tabs.</li>
+    <li>Moved more code into <a href="manual.html#addons">add-on scripts</a>.</li>
+    <li>Support for sane vertical cursor movement in wrapped lines.</li>
+    <li>More reliable handling of
+    editing <a href="manual.html#markText">marked text</a>.</li>
+    <li>Add minimal <a href="../demo/emacs.html">emacs</a>
+    and <a href="../demo/vim.html">vim</a> bindings.</li>
+    <li>Rename <code>coordsFromIndex</code>
+    to <a href="manual.html#posFromIndex"><code>posFromIndex</code></a>,
+    add <a href="manual.html#indexFromPos"><code>indexFromPos</code></a>
+    method.</li>
+  </ul>
+
+  <p class="rel">21-11-2011: <a href="http://codemirror.net/codemirror-2.18.zip">Version 2.18</a>:</p>
+  <p class="rel-note">Fixes <code>TextMarker.clear</code>, which is broken in 2.17.</p>
+
+  <p class="rel">21-11-2011: <a href="http://codemirror.net/codemirror-2.17.zip">Version 2.17</a>:</p>
+  <ul class="rel-note">
+    <li>Add support for <a href="manual.html#option_lineWrapping">line
+    wrapping</a> and <a href="manual.html#hideLine">code
+    folding</a>.</li>
+    <li>Add <a href="../mode/gfm/index.html">Github-style Markdown</a> mode.</li>
+    <li>Add <a href="../theme/monokai.css">Monokai</a>
+    and <a href="../theme/rubyblue.css">Rubyblue</a> themes.</li>
+    <li>Add <a href="manual.html#setBookmark"><code>setBookmark</code></a> method.</li>
+    <li>Move some of the demo code into reusable components
+    under <a href="../addon/"><code>lib/util</code></a>.</li>
+    <li>Make screen-coord-finding code faster and more reliable.</li>
+    <li>Fix drag-and-drop in Firefox.</li>
+    <li>Improve support for IME.</li>
+    <li>Speed up content rendering.</li>
+    <li>Fix browser's built-in search in Webkit.</li>
+    <li>Make double- and triple-click work in IE.</li>
+    <li>Various fixes to modes.</li>
+  </ul>
+
+  <p class="rel">27-10-2011: <a href="http://codemirror.net/codemirror-2.16.zip">Version 2.16</a>:</p>
+  <ul class="rel-note">
+    <li>Add <a href="../mode/perl/index.html">Perl</a>, <a href="../mode/rust/index.html">Rust</a>, <a href="../mode/tiddlywiki/index.html">TiddlyWiki</a>, and <a href="../mode/groovy/index.html">Groovy</a> modes.</li>
+    <li>Dragging text inside the editor now moves, rather than copies.</li>
+    <li>Add a <a href="manual.html#coordsFromIndex"><code>coordsFromIndex</code></a> method.</li>
+    <li><strong>API change</strong>: <code>setValue</code> now no longer clears history. Use <a href="manual.html#clearHistory"><code>clearHistory</code></a> for that.</li>
+    <li><strong>API change</strong>: <a href="manual.html#markText"><code>markText</code></a> now
+    returns an object with <code>clear</code> and <code>find</code>
+    methods. Marked text is now more robust when edited.</li>
+    <li>Fix editing code with tabs in Internet Explorer.</li>
+  </ul>
+
+  <p class="rel">26-09-2011: <a href="http://codemirror.net/codemirror-2.15.zip">Version 2.15</a>:</p>
+  <p class="rel-note">Fix bug that snuck into 2.14: Clicking the
+  character that currently has the cursor didn't re-focus the
+  editor.</p>
+
+  <p class="rel">26-09-2011: <a href="http://codemirror.net/codemirror-2.14.zip">Version 2.14</a>:</p>
+  <ul class="rel-note">
+    <li>Add <a href="../mode/clojure/index.html">Clojure</a>, <a href="../mode/pascal/index.html">Pascal</a>, <a href="../mode/ntriples/index.html">NTriples</a>, <a href="../mode/jinja2/index.html">Jinja2</a>, and <a href="../mode/markdown/index.html">Markdown</a> modes.</li>
+    <li>Add <a href="../theme/cobalt.css">Cobalt</a> and <a href="../theme/eclipse.css">Eclipse</a> themes.</li>
+    <li>Add a <a href="manual.html#option_fixedGutter"><code>fixedGutter</code></a> option.</li>
+    <li>Fix bug with <code>setValue</code> breaking cursor movement.</li>
+    <li>Make gutter updates much more efficient.</li>
+    <li>Allow dragging of text out of the editor (on modern browsers).</li>
+  </ul>
+
+
+  <p class="rel">23-08-2011: <a href="http://codemirror.net/codemirror-2.13.zip">Version 2.13</a>:</p>
+  <ul class="rel-note">
+    <li>Add <a href="../mode/ruby/index.html">Ruby</a>, <a href="../mode/r/index.html">R</a>, <a href="../mode/coffeescript/index.html">CoffeeScript</a>, and <a href="../mode/velocity/index.html">Velocity</a> modes.</li>
+    <li>Add <a href="manual.html#getGutterElement"><code>getGutterElement</code></a> to API.</li>
+    <li>Several fixes to scrolling and positioning.</li>
+    <li>Add <a href="manual.html#option_smartHome"><code>smartHome</code></a> option.</li>
+    <li>Add an experimental <a href="../mode/xmlpure/index.html">pure XML</a> mode.</li>
+  </ul>
+
+  <p class="rel">25-07-2011: <a href="http://codemirror.net/codemirror-2.12.zip">Version 2.12</a>:</p>
+  <ul class="rel-note">
+    <li>Add a <a href="../mode/sparql/index.html">SPARQL</a> mode.</li>
+    <li>Fix bug with cursor jumping around in an unfocused editor in IE.</li>
+    <li>Allow key and mouse events to bubble out of the editor. Ignore widget clicks.</li>
+    <li>Solve cursor flakiness after undo/redo.</li>
+    <li>Fix block-reindent ignoring the last few lines.</li>
+    <li>Fix parsing of multi-line attrs in XML mode.</li>
+    <li>Use <code>innerHTML</code> for HTML-escaping.</li>
+    <li>Some fixes to indentation in C-like mode.</li>
+    <li>Shrink horiz scrollbars when long lines removed.</li>
+    <li>Fix width feedback loop bug that caused the width of an inner DIV to shrink.</li>
+  </ul>
+
+  <p class="rel">04-07-2011: <a href="http://codemirror.net/codemirror-2.11.zip">Version 2.11</a>:</p>
+  <ul class="rel-note">
+    <li>Add a <a href="../mode/scheme/index.html">Scheme mode</a>.</li>
+    <li>Add a <code>replace</code> method to search cursors, for cursor-preserving replacements.</li>
+    <li>Make the <a href="../mode/clike/index.html">C-like mode</a> mode more customizable.</li>
+    <li>Update XML mode to spot mismatched tags.</li>
+    <li>Add <code>getStateAfter</code> API and <code>compareState</code> mode API methods for finer-grained mode magic.</li>
+    <li>Add a <code>getScrollerElement</code> API method to manipulate the scrolling DIV.</li>
+    <li>Fix drag-and-drop for Firefox.</li>
+    <li>Add a C# configuration for the <a href="../mode/clike/index.html">C-like mode</a>.</li>
+    <li>Add <a href="../demo/fullscreen.html">full-screen editing</a> and <a href="../demo/changemode.html">mode-changing</a> demos.</li>
+  </ul>
+
+  <p class="rel">07-06-2011: <a href="http://codemirror.net/codemirror-2.1.zip">Version 2.1</a>:</p>
+  <p class="rel-note">Add
+  a <a href="manual.html#option_theme">theme</a> system
+  (<a href="../demo/theme.html">demo</a>). Note that this is not
+  backwards-compatible—you'll have to update your styles and
+  modes!</p>
+
+  <p class="rel">07-06-2011: <a href="http://codemirror.net/codemirror-2.02.zip">Version 2.02</a>:</p>
+  <ul class="rel-note">
+    <li>Add a <a href="../mode/lua/index.html">Lua mode</a>.</li>
+    <li>Fix reverse-searching for a regexp.</li>
+    <li>Empty lines can no longer break highlighting.</li>
+    <li>Rework scrolling model (the outer wrapper no longer does the scrolling).</li>
+    <li>Solve horizontal jittering on long lines.</li>
+    <li>Add <a href="../demo/runmode.html">runmode.js</a>.</li>
+    <li>Immediately re-highlight text when typing.</li>
+    <li>Fix problem with 'sticking' horizontal scrollbar.</li>
+  </ul>
+
+  <p class="rel">26-05-2011: <a href="http://codemirror.net/codemirror-2.01.zip">Version 2.01</a>:</p>
+  <ul class="rel-note">
+    <li>Add a <a href="../mode/smalltalk/index.html">Smalltalk mode</a>.</li>
+    <li>Add a <a href="../mode/rst/index.html">reStructuredText mode</a>.</li>
+    <li>Add a <a href="../mode/python/index.html">Python mode</a>.</li>
+    <li>Add a <a href="../mode/plsql/index.html">PL/SQL mode</a>.</li>
+    <li><code>coordsChar</code> now works</li>
+    <li>Fix a problem where <code>onCursorActivity</code> interfered with <code>onChange</code>.</li>
+    <li>Fix a number of scrolling and mouse-click-position glitches.</li>
+    <li>Pass information about the changed lines to <code>onChange</code>.</li>
+    <li>Support cmd-up/down on OS X.</li>
+    <li>Add triple-click line selection.</li>
+    <li>Don't handle shift when changing the selection through the API.</li>
+    <li>Support <code>"nocursor"</code> mode for <code>readOnly</code> option.</li>
+    <li>Add an <code>onHighlightComplete</code> option.</li>
+    <li>Fix the context menu for Firefox.</li>
+  </ul>
+
+  <p class="rel">28-03-2011: <a href="http://codemirror.net/codemirror-2.0.zip">Version 2.0</a>:</p>
+  <p class="rel-note">CodeMirror 2 is a complete rewrite that's
+  faster, smaller, simpler to use, and less dependent on browser
+  quirks. See <a href="internals.html">this</a>
+  and <a href="http://groups.google.com/group/codemirror/browse_thread/thread/5a8e894024a9f580">this</a>
+  for more information.</p>
+
+  <p class="rel">22-02-2011: <a href="https://github.com/marijnh/codemirror/tree/beta2">Version 2.0 beta 2</a>:</p>
+  <p class="rel-note">Somewhat more mature API, lots of bugs shaken out.</p>
+
+  <p class="rel">17-02-2011: <a href="http://codemirror.net/codemirror-0.94.zip">Version 0.94</a>:</p>
+  <ul class="rel-note">
+    <li><code>tabMode: "spaces"</code> was modified slightly (now indents when something is selected).</li>
+    <li>Fixes a bug that would cause the selection code to break on some IE versions.</li>
+    <li>Disabling spell-check on WebKit browsers now works.</li>
+  </ul>
+
+  <p class="rel">08-02-2011: <a href="http://codemirror.net/">Version 2.0 beta 1</a>:</p>
+  <p class="rel-note">CodeMirror 2 is a complete rewrite of
+  CodeMirror, no longer depending on an editable frame.</p>
+
+  <p class="rel">19-01-2011: <a href="http://codemirror.net/codemirror-0.93.zip">Version 0.93</a>:</p>
+  <ul class="rel-note">
+    <li>Added a <a href="contrib/regex/index.html">Regular Expression</a> parser.</li>
+    <li>Fixes to the PHP parser.</li>
+    <li>Support for regular expression in search/replace.</li>
+    <li>Add <code>save</code> method to instances created with <code>fromTextArea</code>.</li>
+    <li>Add support for MS T-SQL in the SQL parser.</li>
+    <li>Support use of CSS classes for highlighting brackets.</li>
+    <li>Fix yet another hang with line-numbering in hidden editors.</li>
+  </ul>
+</section>
+
+<section id=v1>
+
+  <h2>Version 0.x</h2>
+
+  <p class="rel">28-03-2011: <a href="http://codemirror.net/codemirror-1.0.zip">Version 1.0</a>:</p>
+  <ul class="rel-note">
+    <li>Fix error when debug history overflows.</li>
+    <li>Refine handling of C# verbatim strings.</li>
+    <li>Fix some issues with JavaScript indentation.</li>
+  </ul>
+
+  <p class="rel">17-12-2010: <a href="http://codemirror.net/codemirror-0.92.zip">Version 0.92</a>:</p>
+  <ul class="rel-note">
+    <li>Make CodeMirror work in XHTML documents.</li>
+    <li>Fix bug in handling of backslashes in Python strings.</li>
+    <li>The <code>styleNumbers</code> option is now officially
+    supported and documented.</li>
+    <li><code>onLineNumberClick</code> option added.</li>
+    <li>More consistent names <code>onLoad</code> and
+    <code>onCursorActivity</code> callbacks. Old names still work, but
+    are deprecated.</li>
+    <li>Add a <a href="contrib/freemarker/index.html">Freemarker</a> mode.</li>
+  </ul>
+
+  <p class="rel">11-11-2010: <a
+  href="http://codemirror.net/codemirror-0.91.zip">Version 0.91</a>:</p>
+  <ul class="rel-note">
+    <li>Adds support for <a href="contrib/java">Java</a>.</li>
+    <li>Small additions to the <a href="contrib/php">PHP</a> and <a href="contrib/sql">SQL</a> parsers.</li>
+    <li>Work around various <a href="https://bugs.webkit.org/show_bug.cgi?id=47806">Webkit</a> <a href="https://bugs.webkit.org/show_bug.cgi?id=23474">issues</a>.</li>
+    <li>Fix <code>toTextArea</code> to update the code in the textarea.</li>
+    <li>Add a <code>noScriptCaching</code> option (hack to ease development).</li>
+    <li>Make sub-modes of <a href="mixedtest.html">HTML mixed</a> mode configurable.</li>
+  </ul>
+
+  <p class="rel">02-10-2010: <a
+  href="http://codemirror.net/codemirror-0.9.zip">Version 0.9</a>:</p>
+  <ul class="rel-note">
+    <li>Add support for searching backwards.</li>
+    <li>There are now parsers for <a href="contrib/scheme/index.html">Scheme</a>, <a href="contrib/xquery/index.html">XQuery</a>, and <a href="contrib/ometa/index.html">OmetaJS</a>.</li>
+    <li>Makes <code>height: "dynamic"</code> more robust.</li>
+    <li>Fixes bug where paste did not work on OS X.</li>
+    <li>Add a <code>enterMode</code> and <code>electricChars</code> options to make indentation even more customizable.</li>
+    <li>Add <code>firstLineNumber</code> option.</li>
+    <li>Fix bad handling of <code>@media</code> rules by the CSS parser.</li>
+    <li>Take a new, more robust approach to working around the invisible-last-line bug in WebKit.</li>
+  </ul>
+
+  <p class="rel">22-07-2010: <a
+  href="http://codemirror.net/codemirror-0.8.zip">Version 0.8</a>:</p>
+  <ul class="rel-note">
+    <li>Add a <code>cursorCoords</code> method to find the screen
+    coordinates of the cursor.</li>
+    <li>A number of fixes and support for more syntax in the PHP parser.</li>
+    <li>Fix indentation problem with JSON-mode JS parser in Webkit.</li>
+    <li>Add a <a href="compress.html">minification</a> UI.</li>
+    <li>Support a <code>height: dynamic</code> mode, where the editor's
+    height will adjust to the size of its content.</li>
+    <li>Better support for IME input mode.</li>
+    <li>Fix JavaScript parser getting confused when seeing a no-argument
+    function call.</li>
+    <li>Have CSS parser see the difference between selectors and other
+    identifiers.</li>
+    <li>Fix scrolling bug when pasting in a horizontally-scrolled
+    editor.</li>
+    <li>Support <code>toTextArea</code> method in instances created with
+    <code>fromTextArea</code>.</li>
+    <li>Work around new Opera cursor bug that causes the cursor to jump
+    when pressing backspace at the end of a line.</li>
+  </ul>
+
+  <p class="rel">27-04-2010: <a
+  href="http://codemirror.net/codemirror-0.67.zip">Version
+  0.67</a>:</p>
+  <p class="rel-note">More consistent page-up/page-down behaviour
+  across browsers. Fix some issues with hidden editors looping forever
+  when line-numbers were enabled. Make PHP parser parse
+  <code>"\\"</code> correctly. Have <code>jumpToLine</code> work on
+  line handles, and add <code>cursorLine</code> function to fetch the
+  line handle where the cursor currently is. Add new
+  <code>setStylesheet</code> function to switch style-sheets in a
+  running editor.</p>
+
+  <p class="rel">01-03-2010: <a
+  href="http://codemirror.net/codemirror-0.66.zip">Version
+  0.66</a>:</p>
+  <p class="rel-note">Adds <code>removeLine</code> method to API.
+  Introduces the <a href="contrib/plsql/index.html">PLSQL parser</a>.
+  Marks XML errors by adding (rather than replacing) a CSS class, so
+  that they can be disabled by modifying their style. Fixes several
+  selection bugs, and a number of small glitches.</p>
+
+  <p class="rel">12-11-2009: <a
+  href="http://codemirror.net/codemirror-0.65.zip">Version
+  0.65</a>:</p>
+  <p class="rel-note">Add support for having both line-wrapping and
+  line-numbers turned on, make paren-highlighting style customisable
+  (<code>markParen</code> and <code>unmarkParen</code> config
+  options), work around a selection bug that Opera
+  <em>re</em>introduced in version 10.</p>
+
+  <p class="rel">23-10-2009: <a
+  href="http://codemirror.net/codemirror-0.64.zip">Version
+  0.64</a>:</p>
+  <p class="rel-note">Solves some issues introduced by the
+  paste-handling changes from the previous release. Adds
+  <code>setSpellcheck</code>, <code>setTextWrapping</code>,
+  <code>setIndentUnit</code>, <code>setUndoDepth</code>,
+  <code>setTabMode</code>, and <code>setLineNumbers</code> to
+  customise a running editor. Introduces an <a
+  href="contrib/sql/index.html">SQL</a> parser. Fixes a few small
+  problems in the <a href="contrib/python/index.html">Python</a>
+  parser. And, as usual, add workarounds for various newly discovered
+  browser incompatibilities.</p>
+
+  <p class="rel"><em>31-08-2009</em>: <a href="http://codemirror.net/codemirror-0.63.zip">Version 0.63</a>:</p>
+  <p class="rel-note"> Overhaul of paste-handling (less fragile), fixes for several
+  serious IE8 issues (cursor jumping, end-of-document bugs) and a number
+  of small problems.</p>
+
+  <p class="rel"><em>30-05-2009</em>: <a href="http://codemirror.net/codemirror-0.62.zip">Version 0.62</a>:</p>
+  <p class="rel-note">Introduces <a href="contrib/python/index.html">Python</a>
+  and <a href="contrib/lua/index.html">Lua</a> parsers. Add
+  <code>setParser</code> (on-the-fly mode changing) and
+  <code>clearHistory</code> methods. Make parsing passes time-based
+  instead of lines-based (see the <code>passTime</code> option).</p>
+
+</section>
+</article>
diff --git a/app/gui/html/vendor/codemirror/doc/reporting.html b/app/gui/html/vendor/codemirror/doc/reporting.html
new file mode 100644
index 0000000..47e37a5
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/doc/reporting.html
@@ -0,0 +1,61 @@
+<!doctype html>
+
+<title>CodeMirror: Reporting Bugs</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="docs.css">
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Reporting bugs</a>
+  </ul>
+</div>
+
+<article>
+
+<h2>Reporting bugs effectively</h2>
+
+<div class="left">
+
+<p>So you found a problem in CodeMirror. By all means, report it! Bug
+reports from users are the main drive behind improvements to
+CodeMirror. But first, please read over these points:</p>
+
+<ol>
+  <li>CodeMirror is maintained by volunteers. They don't owe you
+  anything, so be polite. Reports with an indignant or belligerent
+  tone tend to be moved to the bottom of the pile.</li>
+
+  <li>Include information about <strong>the browser in which the
+  problem occurred</strong>. Even if you tested several browsers, and
+  the problem occurred in all of them, mention this fact in the bug
+  report. Also include browser version numbers and the operating
+  system that you're on.</li>
+
+  <li>Mention which release of CodeMirror you're using. Preferably,
+  try also with the current development snapshot, to ensure the
+  problem has not already been fixed.</li>
+
+  <li>Mention very precisely what went wrong. "X is broken" is not a
+  good bug report. What did you expect to happen? What happened
+  instead? Describe the exact steps a maintainer has to take to make
+  the problem occur. We can not fix something that we can not
+  observe.</li>
+
+  <li>If the problem can not be reproduced in any of the demos
+  included in the CodeMirror distribution, please provide an HTML
+  document that demonstrates the problem. The best way to do this is
+  to go to <a href="http://jsbin.com/ihunin/edit">jsbin.com</a>, enter
+  it there, press save, and include the resulting link in your bug
+  report.</li>
+</ol>
+
+</div>
+
+</article>
diff --git a/app/gui/html/vendor/codemirror/doc/upgrade_v2.2.html b/app/gui/html/vendor/codemirror/doc/upgrade_v2.2.html
new file mode 100644
index 0000000..a2dddef
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/doc/upgrade_v2.2.html
@@ -0,0 +1,96 @@
+<!doctype html>
+
+<title>CodeMirror: Version 2.2 upgrade guide</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="docs.css">
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">2.2 upgrade guide</a>
+  </ul>
+</div>
+
+<article>
+
+<h2>Upgrading to v2.2</h2>
+
+<p>There are a few things in the 2.2 release that require some care
+when upgrading.</p>
+
+<h3>No more default.css</h3>
+
+<p>The default theme is now included
+in <a href="../lib/codemirror.css"><code>codemirror.css</code></a>, so
+you do not have to included it separately anymore. (It was tiny, so
+even if you're not using it, the extra data overhead is negligible.)
+
+<h3>Different key customization</h3>
+
+<p>CodeMirror has moved to a system
+where <a href="manual.html#option_keyMap">keymaps</a> are used to
+bind behavior to keys. This means <a href="../demo/emacs.html">custom
+bindings</a> are now possible.</p>
+
+<p>Three options that influenced key
+behavior, <code>tabMode</code>, <code>enterMode</code>,
+and <code>smartHome</code>, are no longer supported. Instead, you can
+provide custom bindings to influence the way these keys act. This is
+done through the
+new <a href="manual.html#option_extraKeys"><code>extraKeys</code></a>
+option, which can hold an object mapping key names to functionality. A
+simple example would be:</p>
+
+<pre>  extraKeys: {
+    "Ctrl-S": function(instance) { saveText(instance.getValue()); },
+    "Ctrl-/": "undo"
+  }</pre>
+
+<p>Keys can be mapped either to functions, which will be given the
+editor instance as argument, or to strings, which are mapped through
+functions through the <code>CodeMirror.commands</code> table, which
+contains all the built-in editing commands, and can be inspected and
+extended by external code.</p>
+
+<p>By default, the <code>Home</code> key is bound to
+the <code>"goLineStartSmart"</code> command, which moves the cursor to
+the first non-whitespace character on the line. You can set do this to
+make it always go to the very start instead:</p>
+
+<pre>  extraKeys: {"Home": "goLineStart"}</pre>
+
+<p>Similarly, <code>Enter</code> is bound
+to <code>"newlineAndIndent"</code> by default. You can bind it to
+something else to get different behavior. To disable special handling
+completely and only get a newline character inserted, you can bind it
+to <code>false</code>:</p>
+
+<pre>  extraKeys: {"Enter": false}</pre>
+
+<p>The same works for <code>Tab</code>. If you don't want CodeMirror
+to handle it, bind it to <code>false</code>. The default behaviour is
+to indent the current line more (<code>"indentMore"</code> command),
+and indent it less when shift is held (<code>"indentLess"</code>).
+There are also <code>"indentAuto"</code> (smart indent)
+and <code>"insertTab"</code> commands provided for alternate
+behaviors. Or you can write your own handler function to do something
+different altogether.</p>
+
+<h3>Tabs</h3>
+
+<p>Handling of tabs changed completely. The display width of tabs can
+now be set with the <code>tabSize</code> option, and tabs can
+be <a href="../demo/visibletabs.html">styled</a> by setting CSS rules
+for the <code>cm-tab</code> class.</p>
+
+<p>The default width for tabs is now 4, as opposed to the 8 that is
+hard-wired into browsers. If you are relying on 8-space tabs, make
+sure you explicitly set <code>tabSize: 8</code> in your options.</p>
+
+</article>
diff --git a/app/gui/html/vendor/codemirror/doc/upgrade_v3.html b/app/gui/html/vendor/codemirror/doc/upgrade_v3.html
new file mode 100644
index 0000000..1975792
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/doc/upgrade_v3.html
@@ -0,0 +1,230 @@
+<!doctype html>
+
+<title>CodeMirror: Version 3 upgrade guide</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="docs.css">
+<script src="../lib/codemirror.js"></script>
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../addon/runmode/runmode.js"></script>
+<script src="../addon/runmode/colorize.js"></script>
+<script src="../mode/javascript/javascript.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<script src="../mode/css/css.js"></script>
+<script src="../mode/htmlmixed/htmlmixed.js"></script>
+<script src="activebookmark.js"></script>
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#upgrade">Upgrade guide</a>
+    <li><a href="#dom">DOM structure</a></li>
+    <li><a href="#gutters">Gutter model</a></li>
+    <li><a href="#events">Event handling</a></li>
+    <li><a href="#marktext">markText method arguments</a></li>
+    <li><a href="#folding">Line folding</a></li>
+    <li><a href="#lineclass">Line CSS classes</a></li>
+    <li><a href="#positions">Position properties</a></li>
+    <li><a href="#matchbrackets">Bracket matching</a></li>
+    <li><a href="#modes">Mode management</a></li>
+    <li><a href="#new">New features</a></li>
+  </ul>
+</div>
+
+<article>
+
+<h2 id=upgrade>Upgrading to version 3</h2>
+
+<p>Version 3 does not depart too much from 2.x API, and sites that use
+CodeMirror in a very simple way might be able to upgrade without
+trouble. But it does introduce a number of incompatibilities. Please
+at least skim this text before upgrading.</p>
+
+<p>Note that <strong>version 3 drops full support for Internet
+Explorer 7</strong>. The editor will mostly work on that browser, but
+it'll be significantly glitchy.</p>
+
+<section id=dom>
+  <h2>DOM structure</h2>
+
+<p>This one is the most likely to cause problems. The internal
+structure of the editor has changed quite a lot, mostly to implement a
+new scrolling model.</p>
+
+<p>Editor height is now set on the outer wrapper element (CSS
+class <code>CodeMirror</code>), not on the scroller element
+(<code>CodeMirror-scroll</code>).</p>
+
+<p>Other nodes were moved, dropped, and added. If you have any code
+that makes assumptions about the internal DOM structure of the editor,
+you'll have to re-test it and probably update it to work with v3.</p>
+
+<p>See the <a href="manual.html#styling">styling section</a> of the
+manual for more information.</p>
+</section>
+<section id=gutters>
+  <h2>Gutter model</h2>
+
+<p>In CodeMirror 2.x, there was a single gutter, and line markers
+created with <code>setMarker</code> would have to somehow coexist with
+the line numbers (if present). Version 3 allows you to specify an
+array of gutters, <a href="manual.html#option_gutters">by class
+name</a>,
+use <a href="manual.html#setGutterMarker"><code>setGutterMarker</code></a>
+to add or remove markers in individual gutters, and clear whole
+gutters
+with <a href="manual.html#clearGutter"><code>clearGutter</code></a>.
+Gutter markers are now specified as DOM nodes, rather than HTML
+snippets.</p>
+
+<p>The gutters no longer horizontally scrolls along with the content.
+The <code>fixedGutter</code> option was removed (since it is now the
+only behavior).</p>
+
+<pre data-lang="text/html">
+<style>
+  /* Define a gutter style */
+  .note-gutter { width: 3em; background: cyan; }
+</style>
+<script>
+  // Create an instance with two gutters -- line numbers and notes
+  var cm = new CodeMirror(document.body, {
+    gutters: ["note-gutter", "CodeMirror-linenumbers"],
+    lineNumbers: true
+  });
+  // Add a note to line 0
+  cm.setGutterMarker(0, "note-gutter", document.createTextNode("hi"));
+</script>
+</pre>
+</section>
+<section id=events>
+  <h2>Event handling</h2>
+
+<p>Most of the <code>onXYZ</code> options have been removed. The same
+effect is now obtained by calling
+the <a href="manual.html#on"><code>on</code></a> method with a string
+identifying the event type. Multiple handlers can now be registered
+(and individually unregistered) for an event, and objects such as line
+handlers now also expose events. See <a href="manual.html#events">the
+full list here</a>.</p>
+
+<p>(The <code>onKeyEvent</code> and <code>onDragEvent</code> options,
+which act more as hooks than as event handlers, are still there in
+their old form.)</p>
+
+<pre data-lang="javascript">
+cm.on("change", function(cm, change) {
+  console.log("something changed! (" + change.origin + ")");
+});
+</pre>
+</section>
+<section id=marktext>
+  <h2>markText method arguments</h2>
+
+<p>The <a href="manual.html#markText"><code>markText</code></a> method
+(which has gained some interesting new features, such as creating
+atomic and read-only spans, or replacing spans with widgets) no longer
+takes the CSS class name as a separate argument, but makes it an
+optional field in the options object instead.</p>
+
+<pre data-lang="javascript">
+// Style first ten lines, and forbid the cursor from entering them
+cm.markText({line: 0, ch: 0}, {line: 10, ch: 0}, {
+  className: "magic-text",
+  inclusiveLeft: true,
+  atomic: true
+});
+</pre>
+</section>
+<section id=folding>
+  <h2>Line folding</h2>
+
+<p>The interface for hiding lines has been
+removed. <a href="manual.html#markText"><code>markText</code></a> can
+now be used to do the same in a more flexible and powerful way.</p>
+
+<p>The <a href="../demo/folding.html">folding script</a> has been
+updated to use the new interface, and should now be more robust.</p>
+
+<pre data-lang="javascript">
+// Fold a range, replacing it with the text "??"
+var range = cm.markText({line: 4, ch: 2}, {line: 8, ch: 1}, {
+  replacedWith: document.createTextNode("??"),
+  // Auto-unfold when cursor moves into the range
+  clearOnEnter: true
+});
+// Get notified when auto-unfolding
+CodeMirror.on(range, "clear", function() {
+  console.log("boom");
+});
+</pre>
+</section>
+<section id=lineclass>
+  <h2>Line CSS classes</h2>
+
+<p>The <code>setLineClass</code> method has been replaced
+by <a href="manual.html#addLineClass"><code>addLineClass</code></a>
+and <a href="manual.html#removeLineClass"><code>removeLineClass</code></a>,
+which allow more modular control over the classes attached to a line.</p>
+
+<pre data-lang="javascript">
+var marked = cm.addLineClass(10, "background", "highlighted-line");
+setTimeout(function() {
+  cm.removeLineClass(marked, "background", "highlighted-line");
+});
+</pre>
+</section>
+<section id=positions>
+  <h2>Position properties</h2>
+
+<p>All methods that take or return objects that represent screen
+positions now use <code>{left, top, bottom, right}</code> properties
+(not always all of them) instead of the <code>{x, y, yBot}</code> used
+by some methods in v2.x.</p>
+
+<p>Affected methods
+are <a href="manual.html#cursorCoords"><code>cursorCoords</code></a>, <a href="manual.html#charCoords"><code>charCoords</code></a>, <a href="manual.html#coordsChar"><code>coordsChar</code></a>,
+and <a href="manual.html#getScrollInfo"><code>getScrollInfo</code></a>.</p>
+</section>
+<section id=matchbrackets>
+  <h2>Bracket matching no longer in core</h2>
+
+<p>The <a href="manual.html#addon_matchbrackets"><code>matchBrackets</code></a>
+option is no longer defined in the core editor.
+Load <code>addon/edit/matchbrackets.js</code> to enable it.</p>
+</section>
+<section id=modes>
+  <h2>Mode management</h2>
+
+<p>The <code>CodeMirror.listModes</code>
+and <code>CodeMirror.listMIMEs</code> functions, used for listing
+defined modes, are gone. You are now encouraged to simply
+inspect <code>CodeMirror.modes</code> (mapping mode names to mode
+constructors) and <code>CodeMirror.mimeModes</code> (mapping MIME
+strings to mode specs).</p>
+</section>
+<section id=new>
+  <h2>New features</h2>
+
+<p>Some more reasons to upgrade to version 3.</p>
+
+<ul>
+  <li>Bi-directional text support. CodeMirror will now mostly do the
+  right thing when editing Arabic or Hebrew text.</li>
+  <li>Arbitrary line heights. Using fonts with different heights
+  inside the editor (whether off by one pixel or fifty) is now
+  supported and handled gracefully.</li>
+  <li>In-line widgets. See <a href="../demo/widget.html">the demo</a>
+  and <a href="manual.html#addLineWidget">the docs</a>.</li>
+  <li>Defining custom options
+  with <a href="manual.html#defineOption"><code>CodeMirror.defineOption</code></a>.</li>
+</ul>
+</section>
+</article>
+
+<script>setTimeout(function(){CodeMirror.colorize();}, 20);</script>
diff --git a/app/gui/html/vendor/codemirror/doc/upgrade_v4.html b/app/gui/html/vendor/codemirror/doc/upgrade_v4.html
new file mode 100644
index 0000000..9680151
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/doc/upgrade_v4.html
@@ -0,0 +1,147 @@
+<!doctype html>
+
+<title>CodeMirror: Version 4 upgrade guide</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="docs.css">
+<script src="activebookmark.js"></script>
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#upgrade">Upgrade guide</a>
+    <li><a href="#multisel">Multiple selections</a>
+    <li><a href="#beforeSelectionChange">The beforeSelectionChange event</a>
+    <li><a href="#replaceSelection">replaceSelection and collapsing</a>
+    <li><a href="#changeEvent">change event data</a>
+    <li><a href="#showIfHidden">showIfHidden option to line widgets</a>
+    <li><a href="#module">Module loaders</a>
+    <li><a href="#shareddata">Mutating shared data structures</a></li>
+    <li><a href="#deprecated">Deprecated interfaces dropped</a>
+  </ul>
+</div>
+
+<article>
+
+<h2 id=upgrade>Upgrading to version 4</h2>
+
+<p><strong>Note:</strong> Version 4 hasn't been released yet. The
+information here is provisional and might still change.</p>
+
+<p>CodeMirror 4's interface is <em>very</em> close version 3, but it
+does fix a few awkward details in a backwards-incompatible ways. At
+least skim the text below before upgrading.</p>
+
+<section id=multisel><h2>Multiple selections</h2>
+
+<p>The main new feature in version 4 is multiple selections. The
+single-selection variants of methods are still there, but now
+typically act only on the <em>primary</em> selection (usually the last
+one added).</p>
+
+<p>The exception to this
+is <a href="manual.html#getSelection"><strong><code>getSelection</code></strong></a>,
+which will now return the content of <em>all</em> selections
+(separated by newlines, or whatever <code>lineSep</code> parameter you passed
+it).</p>
+
+</section>
+
+<section id=beforeSelectionChange><h2>The beforeSelectionChange event</h2>
+
+<p>This event still exists, but the object it is passed has
+a <a href="manual.html#event_beforeSelectionChange">completely new
+interface</a>, because such changes now concern multiple
+selections.</p>
+
+</section>
+
+<section id=replaceSelection><h2>replaceSelection's collapsing behavior</h2>
+
+<p>By
+default, <a href="manual.html#replaceSelection"><code>replaceSelection</code></a>
+would leave the newly inserted text selected. This is only rarely what
+you want, and also (slightly) more expensive in the new model, so the
+default was changed to <code>"end"</code>, meaning the old behavior
+must be explicitly specified by passing a second argument
+of <code>"around"</code>.</p>
+
+</section>
+
+<section id=changeEvent><h2>change event data</h2>
+
+<p>Rather than forcing client code to follow <code>next</code>
+pointers from one change object to the next, the library will now
+simply fire
+multiple <a href="manual.html#event_change"><code>"change"</code></a>
+events. Existing code will probably continue to work unmodified.</p>
+
+</section>
+
+<section id=showIfHidden><h2>showIfHidden option to line widgets</h2>
+
+<p>This option, which conceptually caused line widgets to be visible
+even if their line was hidden, was never really well-defined, and was
+buggy from the start. It would be a rather expensive feature, both in
+code complexity and run-time performance, to implement properly. It
+has been dropped entirely in 4.0.</p>
+
+</section>
+
+<section id=module><h2>Module loaders</h2>
+
+<p>All modules in the CodeMirror distribution are now wrapped in a
+shim function to make them compatible with both AMD
+(<a href="http://requirejs.org">requirejs</a>) and CommonJS (as used
+by <a href="http://nodejs.org/">node</a>
+and <a href="http://browserify.org/">browserify</a>) module loaders.
+When neither of these is present, they fall back to simply using the
+global <code>CodeMirror</code> variable.</p>
+
+<p>If you have a module loader present in your environment, CodeMirror
+will attempt to use it, and you might need to change the way you load
+CodeMirror modules.</p>
+
+</section>
+
+<section id=shareddata><h2>Mutating shared data structures</h2>
+
+<p>Data structures produced by the library should not be mutated
+unless explicitly allowed, in general. This is slightly more strict in
+4.0 than it was in earlier versions, which copied the position objects
+returned by <a href="manual.html#getCursor"><code>getCursor</code></a>
+for nebulous, historic reasons. In 4.0, mutating these
+objects <em>will</em> corrupt your editor's selection.</p>
+
+</section>
+
+<section id=deprecated><h2>Deprecated interfaces dropped</h2>
+
+<p>A few properties and methods that have been deprecated for a while
+are now gone. Most notably, the <code>onKeyEvent</code>
+and <code>onDragEvent</code> options (use the
+corresponding <a href="manual.html#event_dom">events</a> instead).</p>
+
+<p>Two silly methods, which were mostly there to stay close to the 0.x
+API, <code>setLine</code> and <code>removeLine</code> are now gone.
+Use the more
+flexible <a href="manual.html#replaceRange"><code>replaceRange</code></a>
+method instead.</p>
+
+<p>The long names for folding and completing functions
+(<code>CodeMirror.braceRangeFinder</code>, <code>CodeMirror.javascriptHint</code>,
+etc) are also gone
+(use <code>CodeMirror.fold.brace</code>, <code>CodeMirror.hint.javascript</code>).</p>
+
+<p>The <code>className</code> property in the return value
+of <a href="manual.html#getTokenAt"><code>getTokenAt</code></a>, which
+has been superseded by the <code>type</code> property, is also no
+longer present.</p>
+
+</section>
+</article>
diff --git a/app/gui/html/vendor/codemirror/index.html b/app/gui/html/vendor/codemirror/index.html
new file mode 100644
index 0000000..911382b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/index.html
@@ -0,0 +1,194 @@
+<!doctype html>
+
+<title>CodeMirror</title>
+<meta charset="utf-8"/>
+
+<link rel=stylesheet href="lib/codemirror.css">
+<link rel=stylesheet href="doc/docs.css">
+<script src="lib/codemirror.js"></script>
+<script src="mode/xml/xml.js"></script>
+<script src="mode/javascript/javascript.js"></script>
+<script src="mode/css/css.js"></script>
+<script src="mode/htmlmixed/htmlmixed.js"></script>
+<script src="addon/edit/matchbrackets.js"></script>
+
+<script src="doc/activebookmark.js"></script>
+
+<style>
+  .CodeMirror { height: auto; border: 1px solid #ddd; }
+  .CodeMirror-scroll { max-height: 200px; }
+  .CodeMirror pre { padding-left: 7px; line-height: 1.25; }
+</style>
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="doc/logo.png"></a>
+
+  <ul>
+    <li><a class=active data-default="true" href="#description">Home</a>
+    <li><a href="doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="#features">Features</a>
+    <li><a href="#community">Community</a>
+    <li><a href="#browsersupport">Browser support</a>
+  </ul>
+</div>
+
+<article>
+
+<section id=description class=first>
+  <p><strong>CodeMirror</strong> is a versatile text editor
+  implemented in JavaScript for the browser. It is specialized for
+  editing code, and comes with a number of language modes and addons
+  that implement more advanced editing functionality.</p>
+
+  <p>A rich <a href="doc/manual.html#api">programming API</a> and a
+  CSS <a href="doc/manual.html#styling">theming</a> system are
+  available for customizing CodeMirror to fit your application, and
+  extending it with new functionality.</p>
+</section>
+
+<section id=demo>
+  <h2>This is CodeMirror</h2>
+  <form style="position: relative; margin-top: .5em;"><textarea id=demotext>
+<!-- Create a simple CodeMirror instance -->
+<link rel="stylesheet" href="lib/codemirror.css">
+<script src="lib/codemirror.js"></script>
+<script>
+  var editor = CodeMirror.fromTextArea(myTextarea, {
+    mode: "text/html"
+  });
+</script></textarea>
+  <select id="demolist" onchange="document.location = this.options[this.selectedIndex].value;">
+    <option value="#">Other demos...</option>
+    <option value="demo/complete.html">Autocompletion</option>
+    <option value="demo/folding.html">Code folding</option>
+    <option value="demo/theme.html">Themes</option>
+    <option value="mode/htmlmixed/index.html">Mixed language modes</option>
+    <option value="demo/bidi.html">Bi-directional text</option>
+    <option value="demo/variableheight.html">Variable font sizes</option>
+    <option value="demo/search.html">Search interface</option>
+    <option value="demo/vim.html">Vim bindings</option>
+    <option value="demo/emacs.html">Emacs bindings</option>
+    <option value="demo/sublime.html">Sublime Text bindings</option>
+    <option value="demo/tern.html">Tern integration</option>
+    <option value="demo/merge.html">Merge/diff interface</option>
+    <option value="demo/fullscreen.html">Full-screen editor</option>
+  </select></form>
+  <script>
+    var editor = CodeMirror.fromTextArea(document.getElementById("demotext"), {
+      lineNumbers: true,
+      mode: "text/html",
+      matchBrackets: true
+    });
+  </script>
+  <div style="position: relative; margin: 1em 0;">
+    <a class="bigbutton left" href="http://codemirror.net/codemirror.zip">DOWNLOAD LATEST RELEASE</a>
+    <div><strong>version 4.0</strong> (<a href="doc/releases.html">Release notes</a>)</div>
+    <div>or use the <a href="doc/compress.html">minification helper</a></div>
+    <div style="position: absolute; top: 0; right: 0; text-align: right">
+      <span class="bigbutton right" onclick="document.getElementById('paypal').submit();">DONATE WITH PAYPAL</span>
+      <div style="position: relative">
+        or <span onclick="document.getElementById('bankinfo').style.display = 'block';" class=quasilink>Bank</span>,
+        <a href="https://www.gittip.com/marijnh">Gittip</a>,
+        <a href="https://flattr.com/profile/marijnh">Flattr</a><br>
+        <div id=bankinfo>
+          <span id=bankinfo_close onclick="document.getElementById('bankinfo').style.display = '';">×</span>
+          Bank: <i>Rabobank</i><br/>
+          Country: <i>Netherlands</i><br/>
+          SWIFT: <i>RABONL2U</i><br/>
+          Account: <i>147850770</i><br/>
+          Name: <i>Marijn Haverbeke</i><br/>
+          IBAN: <i>NL26 RABO 0147 8507 70</i>
+        </div>
+        <form action="https://www.paypal.com/cgi-bin/webscr" method="post" id="paypal">
+          <input type="hidden" name="cmd" value="_s-xclick"/>
+          <input type="hidden" name="hosted_button_id" value="3FVHS5FGUY7CC"/>
+        </form>
+      </div>
+      <div>
+        Purchase <a href="http://codemirror.com">commercial support</a>
+      </div>
+    </div>
+  </div>
+</section>
+
+<section id=features>
+  <h2>Features</h2>
+  <ul>
+    <li>Support for <a href="mode/index.html">over 60 languages</a> out of the box
+    <li>A powerful, <a href="mode/htmlmixed/index.html">composable</a> language mode <a href="doc/manual.html#modeapi">system</a>
+    <li><a href="doc/manual.html#addon_show-hint">Autocompletion</a> (<a href="demo/xmlcomplete.html">XML</a>)
+    <li><a href="doc/manual.html#addon_foldcode">Code folding</a>
+    <li><a href="doc/manual.html#option_extraKeys">Configurable</a> keybindings
+    <li><a href="demo/vim.html">Vim</a>, <a href="demo/emacs.html">Emacs</a>, and <a href="demo/sublime.html">Sublime Text</a> bindings
+    <li><a href="doc/manual.html#addon_search">Search and replace</a> interface
+    <li><a href="doc/manual.html#addon_matchbrackets">Bracket</a> and <a href="doc/manual.html#addon_matchtags">tag</a> matching
+    <li>Support for <a href="demo/buffers.html">split views</a>
+    <li><a href="doc/manual.html#addon_lint">Linter integration</a>
+    <li><a href="demo/variableheight.html">Mixing font sizes and styles</a>
+    <li><a href="demo/theme.html">Various themes</a>
+    <li>Able to <a href="demo/resize.html">resize to fit content</a>
+    <li><a href="doc/manual.html#mark_replacedWith">Inline</a> and <a href="doc/manual.html#addLineWidget">block</a> widgets
+    <li>Programmable <a href="demo/marker.html">gutters</a>
+    <li>Making ranges of text <a href="doc/manual.html#markText">styled, read-only, or atomic</a>
+    <li><a href="demo/bidi.html">Bi-directional text</a> support
+    <li>Many other <a href="doc/manual.html#api">methods</a> and <a href="doc/manual.html#addons">addons</a>...
+  </ul>
+</section>
+
+<section id=community>
+  <h2>Community</h2>
+
+  <p>CodeMirror is an open-source project shared under
+  an <a href="LICENSE">MIT license</a>. It is the editor used in the
+  dev tools for
+  both <a href="https://hacks.mozilla.org/2013/11/firefox-developer-tools-episode-27-edit-as-html-codemirror-more/">Firefox</a>
+  and <a href="https://developers.google.com/chrome-developer-tools/">Chrome</a>, <a href="http://www.lighttable.com/">Light
+  Table</a>, <a href="http://brackets.io/">Adobe
+  Brackets</a>, <a href="http://blog.bitbucket.org/2013/05/14/edit-your-code-in-the-cloud-with-bitbucket/">Bitbucket</a>,
+  and <a href="doc/realworld.html">many other projects</a>.</p>
+
+  <p>Development and bug tracking happens
+  on <a href="https://github.com/marijnh/CodeMirror/">github</a>
+  (<a href="http://marijnhaverbeke.nl/git/codemirror">alternate git
+  repository</a>).
+  Please <a href="http://codemirror.net/doc/reporting.html">read these
+  pointers</a> before submitting a bug. Use pull requests to submit
+  patches. All contributions must be released under the same MIT
+  license that CodeMirror uses.</p>
+
+  <p>Discussion around the project is done on
+  a <a href="http://groups.google.com/group/codemirror">mailing list</a>.
+  There is also
+  the <a href="http://groups.google.com/group/codemirror-announce">codemirror-announce</a>
+  list, which is only used for major announcements (such as new
+  versions). If needed, you can
+  contact <a href="mailto:marijnh at gmail.com">the maintainer</a>
+  directly.</p>
+
+  <p>A list of CodeMirror-related software that is not part of the
+  main distribution is maintained
+  on <a href="https://github.com/marijnh/CodeMirror/wiki/CodeMirror-addons">our
+  wiki</a>. Feel free to add your project.</p>
+</section>
+
+<section id=browsersupport>
+  <h2>Browser support</h2>
+  <p>The <em>desktop</em> versions of the following browsers,
+  in <em>standards mode</em> (HTML5 <code><!doctype html></code>
+  recommended) are supported:</p>
+  <table style="margin-bottom: 1em">
+    <tr><th>Firefox</th><td>version 3 and up</td></tr>
+    <tr><th>Chrome</th><td>any version</td></tr>
+    <tr><th>Safari</th><td>version 5.2 and up</td></tr>
+    <tr><th style="padding-right: 1em;">Internet Explorer</th><td>version 8 and up</td></tr>
+    <tr><th>Opera</th><td>version 9 and up</td></tr>
+  </table>
+  <p>Modern mobile browsers tend to partly work. Bug reports and
+  patches for mobile support are welcome, but the maintainer does not
+  have the time or budget to actually work on it himself.</p>
+</section>
+
+</article>
diff --git a/app/gui/html/vendor/codemirror/keymap/emacs.js b/app/gui/html/vendor/codemirror/keymap/emacs.js
new file mode 100644
index 0000000..8d3ab62
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/keymap/emacs.js
@@ -0,0 +1,405 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var Pos = CodeMirror.Pos;
+  function posEq(a, b) { return a.line == b.line && a.ch == b.ch; }
+
+  // Kill 'ring'
+
+  var killRing = [];
+  function addToRing(str) {
+    killRing.push(str);
+    if (killRing.length > 50) killRing.shift();
+  }
+  function growRingTop(str) {
+    if (!killRing.length) return addToRing(str);
+    killRing[killRing.length - 1] += str;
+  }
+  function getFromRing(n) { return killRing[killRing.length - (n ? Math.min(n, 1) : 1)] || ""; }
+  function popFromRing() { if (killRing.length > 1) killRing.pop(); return getFromRing(); }
+
+  var lastKill = null;
+
+  function kill(cm, from, to, mayGrow, text) {
+    if (text == null) text = cm.getRange(from, to);
+
+    if (mayGrow && lastKill && lastKill.cm == cm && posEq(from, lastKill.pos) && cm.isClean(lastKill.gen))
+      growRingTop(text);
+    else
+      addToRing(text);
+    cm.replaceRange("", from, to, "+delete");
+
+    if (mayGrow) lastKill = {cm: cm, pos: from, gen: cm.changeGeneration()};
+    else lastKill = null;
+  }
+
+  // Boundaries of various units
+
+  function byChar(cm, pos, dir) {
+    return cm.findPosH(pos, dir, "char", true);
+  }
+
+  function byWord(cm, pos, dir) {
+    return cm.findPosH(pos, dir, "word", true);
+  }
+
+  function byLine(cm, pos, dir) {
+    return cm.findPosV(pos, dir, "line", cm.doc.sel.goalColumn);
+  }
+
+  function byPage(cm, pos, dir) {
+    return cm.findPosV(pos, dir, "page", cm.doc.sel.goalColumn);
+  }
+
+  function byParagraph(cm, pos, dir) {
+    var no = pos.line, line = cm.getLine(no);
+    var sawText = /\S/.test(dir < 0 ? line.slice(0, pos.ch) : line.slice(pos.ch));
+    var fst = cm.firstLine(), lst = cm.lastLine();
+    for (;;) {
+      no += dir;
+      if (no < fst || no > lst)
+        return cm.clipPos(Pos(no - dir, dir < 0 ? 0 : null));
+      line = cm.getLine(no);
+      var hasText = /\S/.test(line);
+      if (hasText) sawText = true;
+      else if (sawText) return Pos(no, 0);
+    }
+  }
+
+  function bySentence(cm, pos, dir) {
+    var line = pos.line, ch = pos.ch;
+    var text = cm.getLine(pos.line), sawWord = false;
+    for (;;) {
+      var next = text.charAt(ch + (dir < 0 ? -1 : 0));
+      if (!next) { // End/beginning of line reached
+        if (line == (dir < 0 ? cm.firstLine() : cm.lastLine())) return Pos(line, ch);
+        text = cm.getLine(line + dir);
+        if (!/\S/.test(text)) return Pos(line, ch);
+        line += dir;
+        ch = dir < 0 ? text.length : 0;
+        continue;
+      }
+      if (sawWord && /[!?.]/.test(next)) return Pos(line, ch + (dir > 0 ? 1 : 0));
+      if (!sawWord) sawWord = /\w/.test(next);
+      ch += dir;
+    }
+  }
+
+  function byExpr(cm, pos, dir) {
+    var wrap;
+    if (cm.findMatchingBracket && (wrap = cm.findMatchingBracket(pos, true))
+        && wrap.match && (wrap.forward ? 1 : -1) == dir)
+      return dir > 0 ? Pos(wrap.to.line, wrap.to.ch + 1) : wrap.to;
+
+    for (var first = true;; first = false) {
+      var token = cm.getTokenAt(pos);
+      var after = Pos(pos.line, dir < 0 ? token.start : token.end);
+      if (first && dir > 0 && token.end == pos.ch || !/\w/.test(token.string)) {
+        var newPos = cm.findPosH(after, dir, "char");
+        if (posEq(after, newPos)) return pos;
+        else pos = newPos;
+      } else {
+        return after;
+      }
+    }
+  }
+
+  // Prefixes (only crudely supported)
+
+  function getPrefix(cm, precise) {
+    var digits = cm.state.emacsPrefix;
+    if (!digits) return precise ? null : 1;
+    clearPrefix(cm);
+    return digits == "-" ? -1 : Number(digits);
+  }
+
+  function repeated(cmd) {
+    var f = typeof cmd == "string" ? function(cm) { cm.execCommand(cmd); } : cmd;
+    return function(cm) {
+      var prefix = getPrefix(cm);
+      f(cm);
+      for (var i = 1; i < prefix; ++i) f(cm);
+    };
+  }
+
+  function findEnd(cm, by, dir) {
+    var pos = cm.getCursor(), prefix = getPrefix(cm);
+    if (prefix < 0) { dir = -dir; prefix = -prefix; }
+    for (var i = 0; i < prefix; ++i) {
+      var newPos = by(cm, pos, dir);
+      if (posEq(newPos, pos)) break;
+      pos = newPos;
+    }
+    return pos;
+  }
+
+  function move(by, dir) {
+    var f = function(cm) {
+      cm.extendSelection(findEnd(cm, by, dir));
+    };
+    f.motion = true;
+    return f;
+  }
+
+  function killTo(cm, by, dir) {
+    kill(cm, cm.getCursor(), findEnd(cm, by, dir), true);
+  }
+
+  function addPrefix(cm, digit) {
+    if (cm.state.emacsPrefix) {
+      if (digit != "-") cm.state.emacsPrefix += digit;
+      return;
+    }
+    // Not active yet
+    cm.state.emacsPrefix = digit;
+    cm.on("keyHandled", maybeClearPrefix);
+    cm.on("inputRead", maybeDuplicateInput);
+  }
+
+  var prefixPreservingKeys = {"Alt-G": true, "Ctrl-X": true, "Ctrl-Q": true, "Ctrl-U": true};
+
+  function maybeClearPrefix(cm, arg) {
+    if (!cm.state.emacsPrefixMap && !prefixPreservingKeys.hasOwnProperty(arg))
+      clearPrefix(cm);
+  }
+
+  function clearPrefix(cm) {
+    cm.state.emacsPrefix = null;
+    cm.off("keyHandled", maybeClearPrefix);
+    cm.off("inputRead", maybeDuplicateInput);
+  }
+
+  function maybeDuplicateInput(cm, event) {
+    var dup = getPrefix(cm);
+    if (dup > 1 && event.origin == "+input") {
+      var one = event.text.join("\n"), txt = "";
+      for (var i = 1; i < dup; ++i) txt += one;
+      cm.replaceSelection(txt);
+    }
+  }
+
+  function addPrefixMap(cm) {
+    cm.state.emacsPrefixMap = true;
+    cm.addKeyMap(prefixMap);
+    cm.on("keyHandled", maybeRemovePrefixMap);
+    cm.on("inputRead", maybeRemovePrefixMap);
+  }
+
+  function maybeRemovePrefixMap(cm, arg) {
+    if (typeof arg == "string" && (/^\d$/.test(arg) || arg == "Ctrl-U")) return;
+    cm.removeKeyMap(prefixMap);
+    cm.state.emacsPrefixMap = false;
+    cm.off("keyHandled", maybeRemovePrefixMap);
+    cm.off("inputRead", maybeRemovePrefixMap);
+  }
+
+  // Utilities
+
+  function setMark(cm) {
+    cm.setCursor(cm.getCursor());
+    cm.setExtending(!cm.getExtending());
+    cm.on("change", function() { cm.setExtending(false); });
+  }
+
+  function clearMark(cm) {
+    cm.setExtending(false);
+    cm.setCursor(cm.getCursor());
+  }
+
+  function getInput(cm, msg, f) {
+    if (cm.openDialog)
+      cm.openDialog(msg + ": <input type=\"text\" style=\"width: 10em\"/>", f, {bottom: true});
+    else
+      f(prompt(msg, ""));
+  }
+
+  function operateOnWord(cm, op) {
+    var start = cm.getCursor(), end = cm.findPosH(start, 1, "word");
+    cm.replaceRange(op(cm.getRange(start, end)), start, end);
+    cm.setCursor(end);
+  }
+
+  function toEnclosingExpr(cm) {
+    var pos = cm.getCursor(), line = pos.line, ch = pos.ch;
+    var stack = [];
+    while (line >= cm.firstLine()) {
+      var text = cm.getLine(line);
+      for (var i = ch == null ? text.length : ch; i > 0;) {
+        var ch = text.charAt(--i);
+        if (ch == ")")
+          stack.push("(");
+        else if (ch == "]")
+          stack.push("[");
+        else if (ch == "}")
+          stack.push("{");
+        else if (/[\(\{\[]/.test(ch) && (!stack.length || stack.pop() != ch))
+          return cm.extendSelection(Pos(line, i));
+      }
+      --line; ch = null;
+    }
+  }
+
+  function quit(cm) {
+    cm.execCommand("clearSearch");
+    clearMark(cm);
+  }
+
+  // Actual keymap
+
+  var keyMap = CodeMirror.keyMap.emacs = {
+    "Ctrl-W": function(cm) {kill(cm, cm.getCursor("start"), cm.getCursor("end"));},
+    "Ctrl-K": repeated(function(cm) {
+      var start = cm.getCursor(), end = cm.clipPos(Pos(start.line));
+      var text = cm.getRange(start, end);
+      if (!/\S/.test(text)) {
+        text += "\n";
+        end = Pos(start.line + 1, 0);
+      }
+      kill(cm, start, end, true, text);
+    }),
+    "Alt-W": function(cm) {
+      addToRing(cm.getSelection());
+      clearMark(cm);
+    },
+    "Ctrl-Y": function(cm) {
+      var start = cm.getCursor();
+      cm.replaceRange(getFromRing(getPrefix(cm)), start, start, "paste");
+      cm.setSelection(start, cm.getCursor());
+    },
+    "Alt-Y": function(cm) {cm.replaceSelection(popFromRing(), "around", "paste");},
+
+    "Ctrl-Space": setMark, "Ctrl-Shift-2": setMark,
+
+    "Ctrl-F": move(byChar, 1), "Ctrl-B": move(byChar, -1),
+    "Right": move(byChar, 1), "Left": move(byChar, -1),
+    "Ctrl-D": function(cm) { killTo(cm, byChar, 1); },
+    "Delete": function(cm) { killTo(cm, byChar, 1); },
+    "Ctrl-H": function(cm) { killTo(cm, byChar, -1); },
+    "Backspace": function(cm) { killTo(cm, byChar, -1); },
+
+    "Alt-F": move(byWord, 1), "Alt-B": move(byWord, -1),
+    "Alt-D": function(cm) { killTo(cm, byWord, 1); },
+    "Alt-Backspace": function(cm) { killTo(cm, byWord, -1); },
+
+    "Ctrl-N": move(byLine, 1), "Ctrl-P": move(byLine, -1),
+    "Down": move(byLine, 1), "Up": move(byLine, -1),
+    "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
+    "End": "goLineEnd", "Home": "goLineStart",
+
+    "Alt-V": move(byPage, -1), "Ctrl-V": move(byPage, 1),
+    "PageUp": move(byPage, -1), "PageDown": move(byPage, 1),
+
+    "Ctrl-Up": move(byParagraph, -1), "Ctrl-Down": move(byParagraph, 1),
+
+    "Alt-A": move(bySentence, -1), "Alt-E": move(bySentence, 1),
+    "Alt-K": function(cm) { killTo(cm, bySentence, 1); },
+
+    "Ctrl-Alt-K": function(cm) { killTo(cm, byExpr, 1); },
+    "Ctrl-Alt-Backspace": function(cm) { killTo(cm, byExpr, -1); },
+    "Ctrl-Alt-F": move(byExpr, 1), "Ctrl-Alt-B": move(byExpr, -1),
+
+    "Shift-Ctrl-Alt-2": function(cm) {
+      cm.setSelection(findEnd(cm, byExpr, 1), cm.getCursor());
+    },
+    "Ctrl-Alt-T": function(cm) {
+      var leftStart = byExpr(cm, cm.getCursor(), -1), leftEnd = byExpr(cm, leftStart, 1);
+      var rightEnd = byExpr(cm, leftEnd, 1), rightStart = byExpr(cm, rightEnd, -1);
+      cm.replaceRange(cm.getRange(rightStart, rightEnd) + cm.getRange(leftEnd, rightStart) +
+                      cm.getRange(leftStart, leftEnd), leftStart, rightEnd);
+    },
+    "Ctrl-Alt-U": repeated(toEnclosingExpr),
+
+    "Alt-Space": function(cm) {
+      var pos = cm.getCursor(), from = pos.ch, to = pos.ch, text = cm.getLine(pos.line);
+      while (from && /\s/.test(text.charAt(from - 1))) --from;
+      while (to < text.length && /\s/.test(text.charAt(to))) ++to;
+      cm.replaceRange(" ", Pos(pos.line, from), Pos(pos.line, to));
+    },
+    "Ctrl-O": repeated(function(cm) { cm.replaceSelection("\n", "start"); }),
+    "Ctrl-T": repeated(function(cm) {
+      var pos = cm.getCursor();
+      if (pos.ch < cm.getLine(pos.line).length) pos = Pos(pos.line, pos.ch + 1);
+      var from = cm.findPosH(pos, -2, "char");
+      var range = cm.getRange(from, pos);
+      if (range.length != 2) return;
+      cm.setSelection(from, pos);
+      cm.replaceSelection(range.charAt(1) + range.charAt(0), null, "+transpose");
+    }),
+
+    "Alt-C": repeated(function(cm) {
+      operateOnWord(cm, function(w) {
+        var letter = w.search(/\w/);
+        if (letter == -1) return w;
+        return w.slice(0, letter) + w.charAt(letter).toUpperCase() + w.slice(letter + 1).toLowerCase();
+      });
+    }),
+    "Alt-U": repeated(function(cm) {
+      operateOnWord(cm, function(w) { return w.toUpperCase(); });
+    }),
+    "Alt-L": repeated(function(cm) {
+      operateOnWord(cm, function(w) { return w.toLowerCase(); });
+    }),
+
+    "Alt-;": "toggleComment",
+
+    "Ctrl-/": repeated("undo"), "Shift-Ctrl--": repeated("undo"),
+    "Ctrl-Z": repeated("undo"), "Cmd-Z": repeated("undo"),
+    "Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
+    "Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": quit, "Shift-Alt-5": "replace",
+    "Alt-/": "autocomplete",
+    "Ctrl-J": "newlineAndIndent", "Enter": false, "Tab": "indentAuto",
+
+    "Alt-G": function(cm) {cm.setOption("keyMap", "emacs-Alt-G");},
+    "Ctrl-X": function(cm) {cm.setOption("keyMap", "emacs-Ctrl-X");},
+    "Ctrl-Q": function(cm) {cm.setOption("keyMap", "emacs-Ctrl-Q");},
+    "Ctrl-U": addPrefixMap
+  };
+
+  CodeMirror.keyMap["emacs-Ctrl-X"] = {
+    "Tab": function(cm) {
+      cm.indentSelection(getPrefix(cm, true) || cm.getOption("indentUnit"));
+    },
+    "Ctrl-X": function(cm) {
+      cm.setSelection(cm.getCursor("head"), cm.getCursor("anchor"));
+    },
+
+    "Ctrl-S": "save", "Ctrl-W": "save", "S": "saveAll", "F": "open", "U": repeated("undo"), "K": "close",
+    "Delete": function(cm) { kill(cm, cm.getCursor(), bySentence(cm, cm.getCursor(), 1), true); },
+    auto: "emacs", nofallthrough: true, disableInput: true
+  };
+
+  CodeMirror.keyMap["emacs-Alt-G"] = {
+    "G": function(cm) {
+      var prefix = getPrefix(cm, true);
+      if (prefix != null && prefix > 0) return cm.setCursor(prefix - 1);
+
+      getInput(cm, "Goto line", function(str) {
+        var num;
+        if (str && !isNaN(num = Number(str)) && num == num|0 && num > 0)
+          cm.setCursor(num - 1);
+      });
+    },
+    auto: "emacs", nofallthrough: true, disableInput: true
+  };
+
+  CodeMirror.keyMap["emacs-Ctrl-Q"] = {
+    "Tab": repeated("insertTab"),
+    auto: "emacs", nofallthrough: true
+  };
+
+  var prefixMap = {"Ctrl-G": clearPrefix};
+  function regPrefix(d) {
+    prefixMap[d] = function(cm) { addPrefix(cm, d); };
+    keyMap["Ctrl-" + d] = function(cm) { addPrefix(cm, d); };
+    prefixPreservingKeys["Ctrl-" + d] = true;
+  }
+  for (var i = 0; i < 10; ++i) regPrefix(String(i));
+  regPrefix("-");
+});
diff --git a/app/gui/html/vendor/codemirror/keymap/sublime.js b/app/gui/html/vendor/codemirror/keymap/sublime.js
new file mode 100644
index 0000000..4d92115
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/keymap/sublime.js
@@ -0,0 +1,505 @@
+// A rough approximation of Sublime Text's keybindings
+// Depends on addon/search/searchcursor.js and optionally addon/dialog/dialogs.js
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../lib/codemirror"), require("../addon/search/searchcursor"), require("../addon/edit/matchbrackets"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../lib/codemirror", "../addon/search/searchcursor", "../addon/edit/matchbrackets"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var map = CodeMirror.keyMap.sublime = {fallthrough: "default"};
+  var cmds = CodeMirror.commands;
+  var Pos = CodeMirror.Pos;
+  var ctrl = CodeMirror.keyMap["default"] == CodeMirror.keyMap.pcDefault ? "Ctrl-" : "Cmd-";
+
+  // This is not exactly Sublime's algorithm. I couldn't make heads or tails of that.
+  function findPosSubword(doc, start, dir) {
+    if (dir < 0 && start.ch == 0) return doc.clipPos(Pos(start.line - 1));
+    var line = doc.getLine(start.line);
+    if (dir > 0 && start.ch >= line.length) return doc.clipPos(Pos(start.line + 1, 0));
+    var state = "start", type;
+    for (var pos = start.ch, e = dir < 0 ? 0 : line.length, i = 0; pos != e; pos += dir, i++) {
+      var next = line.charAt(dir < 0 ? pos - 1 : pos);
+      var cat = next != "_" && CodeMirror.isWordChar(next) ? "w" : "o";
+      if (cat == "w" && next.toUpperCase() == next) cat = "W";
+      if (state == "start") {
+        if (cat != "o") { state = "in"; type = cat; }
+      } else if (state == "in") {
+        if (type != cat) {
+          if (type == "w" && cat == "W" && dir < 0) pos--;
+          if (type == "W" && cat == "w" && dir > 0) { type = "w"; continue; }
+          break;
+        }
+      }
+    }
+    return Pos(start.line, pos);
+  }
+
+  function moveSubword(cm, dir) {
+    cm.extendSelectionsBy(function(range) {
+      if (cm.display.shift || cm.doc.extend || range.empty())
+        return findPosSubword(cm.doc, range.head, dir);
+      else
+        return dir < 0 ? range.from() : range.to();
+    });
+  }
+
+  cmds[map["Alt-Left"] = "goSubwordLeft"] = function(cm) { moveSubword(cm, -1); };
+  cmds[map["Alt-Right"] = "goSubwordRight"] = function(cm) { moveSubword(cm, 1); };
+
+  cmds[map[ctrl + "Up"] = "scrollLineUp"] = function(cm) {
+    cm.scrollTo(null, cm.getScrollInfo().top - cm.defaultTextHeight());
+  };
+  cmds[map[ctrl + "Down"] = "scrollLineDown"] = function(cm) {
+    cm.scrollTo(null, cm.getScrollInfo().top + cm.defaultTextHeight());
+  };
+
+  cmds[map["Shift-" + ctrl + "L"] = "splitSelectionByLine"] = function(cm) {
+    var ranges = cm.listSelections(), lineRanges = [];
+    for (var i = 0; i < ranges.length; i++) {
+      var from = ranges[i].from(), to = ranges[i].to();
+      for (var line = from.line; line <= to.line; ++line)
+        if (!(to.line > from.line && line == to.line && to.ch == 0))
+          lineRanges.push({anchor: line == from.line ? from : Pos(line, 0),
+                           head: line == to.line ? to : Pos(line)});
+    }
+    cm.setSelections(lineRanges, 0);
+  };
+
+  map["Shift-Tab"] = "indentLess";
+
+  cmds[map["Esc"] = "singleSelectionTop"] = function(cm) {
+    var range = cm.listSelections()[0];
+    cm.setSelection(range.anchor, range.head, {scroll: false});
+  };
+
+  cmds[map[ctrl + "L"] = "selectLine"] = function(cm) {
+    var ranges = cm.listSelections(), extended = [];
+    for (var i = 0; i < ranges.length; i++) {
+      var range = ranges[i];
+      extended.push({anchor: Pos(range.from().line, 0),
+                     head: Pos(range.to().line + 1, 0)});
+    }
+    cm.setSelections(extended);
+  };
+
+  map["Shift-" + ctrl + "K"] = "deleteLine";
+
+  function insertLine(cm, above) {
+    cm.operation(function() {
+      var len = cm.listSelections().length, newSelection = [], last = -1;
+      for (var i = 0; i < len; i++) {
+        var head = cm.listSelections()[i].head;
+        if (head.line <= last) continue;
+        var at = Pos(head.line + (above ? 0 : 1), 0);
+        cm.replaceRange("\n", at, null, "+insertLine");
+        cm.indentLine(at.line, null, true);
+        newSelection.push({head: at, anchor: at});
+        last = head.line + 1;
+      }
+      cm.setSelections(newSelection);
+    });
+  }
+
+  cmds[map[ctrl + "Enter"] = "insertLineAfter"] = function(cm) { insertLine(cm, false); };
+
+  cmds[map["Shift-" + ctrl + "Enter"] = "insertLineBefore"] = function(cm) { insertLine(cm, true); };
+
+  function wordAt(cm, pos) {
+    var start = pos.ch, end = start, line = cm.getLine(pos.line);
+    while (start && CodeMirror.isWordChar(line.charAt(start - 1))) --start;
+    while (end < line.length && CodeMirror.isWordChar(line.charAt(end))) ++end;
+    return {from: Pos(pos.line, start), to: Pos(pos.line, end), word: line.slice(start, end)};
+  }
+
+  cmds[map[ctrl + "D"] = "selectNextOccurrence"] = function(cm) {
+    var from = cm.getCursor("from"), to = cm.getCursor("to");
+    var fullWord = cm.state.sublimeFindFullWord == cm.doc.sel;
+    if (CodeMirror.cmpPos(from, to) == 0) {
+      var word = wordAt(cm, from);
+      if (!word.word) return;
+      cm.setSelection(word.from, word.to);
+      fullWord = true;
+    } else {
+      var text = cm.getRange(from, to);
+      var query = fullWord ? new RegExp("\\b" + text + "\\b") : text;
+      var cur = cm.getSearchCursor(query, to);
+      if (cur.findNext()) {
+        cm.addSelection(cur.from(), cur.to());
+      } else {
+        cur = cm.getSearchCursor(query, Pos(cm.firstLine(), 0));
+        if (cur.findNext())
+          cm.addSelection(cur.from(), cur.to());
+      }
+    }
+    if (fullWord)
+      cm.state.sublimeFindFullWord = cm.doc.sel;
+  };
+
+  var mirror = "(){}[]";
+  function selectBetweenBrackets(cm) {
+    var pos = cm.getCursor(), opening = cm.scanForBracket(pos, -1);
+    if (!opening) return;
+    for (;;) {
+      var closing = cm.scanForBracket(pos, 1);
+      if (!closing) return;
+      if (closing.ch == mirror.charAt(mirror.indexOf(opening.ch) + 1)) {
+        cm.setSelection(Pos(opening.pos.line, opening.pos.ch + 1), closing.pos, false);
+        return true;
+      }
+      pos = Pos(closing.pos.line, closing.pos.ch + 1);
+    }
+  }
+
+  cmds[map["Shift-" + ctrl + "Space"] = "selectScope"] = function(cm) {
+    selectBetweenBrackets(cm) || cm.execCommand("selectAll");
+  };
+  cmds[map["Shift-" + ctrl + "M"] = "selectBetweenBrackets"] = function(cm) {
+    if (!selectBetweenBrackets(cm)) return CodeMirror.Pass;
+  };
+
+  cmds[map[ctrl + "M"] = "goToBracket"] = function(cm) {
+    cm.extendSelectionsBy(function(range) {
+      var next = cm.scanForBracket(range.head, 1);
+      if (next && CodeMirror.cmpPos(next.pos, range.head) != 0) return next.pos;
+      var prev = cm.scanForBracket(range.head, -1);
+      return prev && Pos(prev.pos.line, prev.pos.ch + 1) || range.head;
+    });
+  };
+
+  cmds[map["Shift-" + ctrl + "Up"] = "swapLineUp"] = function(cm) {
+    var ranges = cm.listSelections(), linesToMove = [], at = cm.firstLine() - 1;
+    for (var i = 0; i < ranges.length; i++) {
+      var range = ranges[i], from = range.from().line - 1, to = range.to().line;
+      if (from > at) linesToMove.push(from, to);
+      else if (linesToMove.length) linesToMove[linesToMove.length - 1] = to;
+      at = to;
+    }
+    cm.operation(function() {
+      for (var i = 0; i < linesToMove.length; i += 2) {
+        var from = linesToMove[i], to = linesToMove[i + 1];
+        var line = cm.getLine(from);
+        cm.replaceRange("", Pos(from, 0), Pos(from + 1, 0), "+swapLine");
+        if (to > cm.lastLine()) {
+          cm.replaceRange("\n" + line, Pos(cm.lastLine()), null, "+swapLine");
+          var sels = cm.listSelections(), last = sels[sels.length - 1];
+          var head = last.head.line == to ? Pos(to - 1) : last.head;
+          var anchor = last.anchor.line == to ? Pos(to - 1) : last.anchor;
+          cm.setSelections(sels.slice(0, sels.length - 1).concat([{head: head, anchor: anchor}]));
+        } else {
+          cm.replaceRange(line + "\n", Pos(to, 0), null, "+swapLine");
+        }
+      }
+      cm.scrollIntoView();
+    });
+  };
+
+  cmds[map["Shift-" + ctrl + "Down"] = "swapLineDown"] = function(cm) {
+    var ranges = cm.listSelections(), linesToMove = [], at = cm.lastLine() + 1;
+    for (var i = ranges.length - 1; i >= 0; i--) {
+      var range = ranges[i], from = range.to().line + 1, to = range.from().line;
+      if (from < at) linesToMove.push(from, to);
+      else if (linesToMove.length) linesToMove[linesToMove.length - 1] = to;
+      at = to;
+    }
+    cm.operation(function() {
+      for (var i = linesToMove.length - 2; i >= 0; i -= 2) {
+        var from = linesToMove[i], to = linesToMove[i + 1];
+        var line = cm.getLine(from);
+        if (from == cm.lastLine())
+          cm.replaceRange("", Pos(from - 1), Pos(from), "+swapLine");
+        else
+          cm.replaceRange("", Pos(from, 0), Pos(from + 1, 0), "+swapLine");
+        cm.replaceRange(line + "\n", Pos(to, 0), null, "+swapLine");
+      }
+      cm.scrollIntoView();
+    });
+  };
+
+  map[ctrl + "/"] = "toggleComment";
+
+  cmds[map[ctrl + "J"] = "joinLines"] = function(cm) {
+    var ranges = cm.listSelections(), joined = [];
+    for (var i = 0; i < ranges.length; i++) {
+      var range = ranges[i], from = range.from();
+      var start = from.line, end = range.to().line;
+      while (i < ranges.length - 1 && ranges[i + 1].from().line == end)
+        end = ranges[++i].to().line;
+      joined.push({start: start, end: end, anchor: !range.empty() && from});
+    }
+    cm.operation(function() {
+      var offset = 0, ranges = [];
+      for (var i = 0; i < joined.length; i++) {
+        var obj = joined[i];
+        var anchor = obj.anchor && Pos(obj.anchor.line - offset, obj.anchor.ch), head;
+        for (var line = obj.start; line <= obj.end; line++) {
+          var actual = line - offset;
+          if (line == obj.end) head = Pos(actual, cm.getLine(actual).length + 1);
+          if (actual < cm.lastLine()) {
+            cm.replaceRange(" ", Pos(actual), Pos(actual + 1, /^\s*/.exec(cm.getLine(actual + 1))[0].length));
+            ++offset;
+          }
+        }
+        ranges.push({anchor: anchor || head, head: head});
+      }
+      cm.setSelections(ranges, 0);
+    });
+  };
+
+  cmds[map["Shift-" + ctrl + "D"] = "duplicateLine"] = function(cm) {
+    cm.operation(function() {
+      var rangeCount = cm.listSelections().length;
+      for (var i = 0; i < rangeCount; i++) {
+        var range = cm.listSelections()[i];
+        if (range.empty())
+          cm.replaceRange(cm.getLine(range.head.line) + "\n", Pos(range.head.line, 0));
+        else
+          cm.replaceRange(cm.getRange(range.from(), range.to()), range.from());
+      }
+      cm.scrollIntoView();
+    });
+  };
+
+  map[ctrl + "T"] = "transposeChars";
+
+  function sortLines(cm, caseSensitive) {
+    var ranges = cm.listSelections(), toSort = [], selected;
+    for (var i = 0; i < ranges.length; i++) {
+      var range = ranges[i];
+      if (range.empty()) continue;
+      var from = range.from().line, to = range.to().line;
+      while (i < ranges.length - 1 && ranges[i + 1].from().line == to)
+        to = range[++i].to().line;
+      toSort.push(from, to);
+    }
+    if (toSort.length) selected = true;
+    else toSort.push(cm.firstLine(), cm.lastLine());
+
+    cm.operation(function() {
+      var ranges = [];
+      for (var i = 0; i < toSort.length; i += 2) {
+        var from = toSort[i], to = toSort[i + 1];
+        var start = Pos(from, 0), end = Pos(to);
+        var lines = cm.getRange(start, end, false);
+        if (caseSensitive)
+          lines.sort();
+        else
+          lines.sort(function(a, b) {
+            var au = a.toUpperCase(), bu = b.toUpperCase();
+            if (au != bu) { a = au; b = bu; }
+            return a < b ? -1 : a == b ? 0 : 1;
+          });
+        cm.replaceRange(lines, start, end);
+        if (selected) ranges.push({anchor: start, head: end});
+      }
+      if (selected) cm.setSelections(ranges, 0);
+    });
+  }
+
+  cmds[map["F9"] = "sortLines"] = function(cm) { sortLines(cm, true); };
+  cmds[map[ctrl + "F9"] = "sortLinesInsensitive"] = function(cm) { sortLines(cm, false); };
+
+  cmds[map["F2"] = "nextBookmark"] = function(cm) {
+    var marks = cm.state.sublimeBookmarks;
+    if (marks) while (marks.length) {
+      var current = marks.shift();
+      var found = current.find();
+      if (found) {
+        marks.push(current);
+        return cm.setSelection(found.from, found.to);
+      }
+    }
+  };
+
+  cmds[map["Shift-F2"] = "prevBookmark"] = function(cm) {
+    var marks = cm.state.sublimeBookmarks;
+    if (marks) while (marks.length) {
+      marks.unshift(marks.pop());
+      var found = marks[marks.length - 1].find();
+      if (!found)
+        marks.pop();
+      else
+        return cm.setSelection(found.from, found.to);
+    }
+  };
+
+  cmds[map[ctrl + "F2"] = "toggleBookmark"] = function(cm) {
+    var ranges = cm.listSelections();
+    var marks = cm.state.sublimeBookmarks || (cm.state.sublimeBookmarks = []);
+    for (var i = 0; i < ranges.length; i++) {
+      var from = ranges[i].from(), to = ranges[i].to();
+      var found = cm.findMarks(from, to);
+      for (var j = 0; j < found.length; j++) {
+        if (found[j].sublimeBookmark) {
+          found[j].clear();
+          for (var k = 0; k < marks.length; k++)
+            if (marks[k] == found[j])
+              marks.splice(k--, 1);
+          break;
+        }
+      }
+      if (j == found.length)
+        marks.push(cm.markText(from, to, {sublimeBookmark: true, clearWhenEmpty: false}));
+    }
+  };
+
+  cmds[map["Shift-" + ctrl + "F2"] = "clearBookmarks"] = function(cm) {
+    var marks = cm.state.sublimeBookmarks;
+    if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear();
+    marks.length = 0;
+  };
+
+  cmds[map["Alt-F2"] = "selectBookmarks"] = function(cm) {
+    var marks = cm.state.sublimeBookmarks, ranges = [];
+    if (marks) for (var i = 0; i < marks.length; i++) {
+      var found = marks[i].find();
+      if (!found)
+        marks.splice(i--, 0);
+      else
+        ranges.push({anchor: found.from, head: found.to});
+    }
+    if (ranges.length)
+      cm.setSelections(ranges, 0);
+  };
+
+  map["Alt-Q"] = "wrapLines";
+
+  var mapK = CodeMirror.keyMap["sublime-Ctrl-K"] = {auto: "sublime", nofallthrough: true};
+
+  map[ctrl + "K"] = function(cm) {cm.setOption("keyMap", "sublime-Ctrl-K");};
+
+  function modifyWordOrSelection(cm, mod) {
+    cm.operation(function() {
+      var ranges = cm.listSelections(), indices = [], replacements = [];
+      for (var i = 0; i < ranges.length; i++) {
+        var range = ranges[i];
+        if (range.empty()) { indices.push(i); replacements.push(""); }
+        else replacements.push(mod(cm.getRange(range.from(), range.to())));
+      }
+      cm.replaceSelections(replacements, "around", "case");
+      for (var i = indices.length - 1, at; i >= 0; i--) {
+        var range = ranges[indices[i]];
+        if (at && CodeMirror.cmpPos(range.head, at) > 0) continue;
+        var word = wordAt(cm, range.head);
+        at = word.from;
+        cm.replaceRange(mod(word.word), word.from, word.to);
+      }
+    });
+  }
+
+  mapK[ctrl + "Backspace"] = "delLineLeft";
+
+  cmds[mapK[ctrl + "K"] = "delLineRight"] = function(cm) {
+    cm.operation(function() {
+      var ranges = cm.listSelections();
+      for (var i = ranges.length - 1; i >= 0; i--)
+        cm.replaceRange("", ranges[i].anchor, Pos(ranges[i].to().line), "+delete");
+      cm.scrollIntoView();
+    });
+  };
+
+  cmds[mapK[ctrl + "U"] = "upcaseAtCursor"] = function(cm) {
+    modifyWordOrSelection(cm, function(str) { return str.toUpperCase(); });
+  };
+  cmds[mapK[ctrl + "L"] = "downcaseAtCursor"] = function(cm) {
+    modifyWordOrSelection(cm, function(str) { return str.toLowerCase(); });
+  };
+
+  cmds[mapK[ctrl + "Space"] = "setSublimeMark"] = function(cm) {
+    if (cm.state.sublimeMark) cm.state.sublimeMark.clear();
+    cm.state.sublimeMark = cm.setBookmark(cm.getCursor());
+  };
+  cmds[mapK[ctrl + "A"] = "selectToSublimeMark"] = function(cm) {
+    var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
+    if (found) cm.setSelection(cm.getCursor(), found);
+  };
+  cmds[mapK[ctrl + "W"] = "deleteToSublimeMark"] = function(cm) {
+    var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
+    if (found) {
+      var from = cm.getCursor(), to = found;
+      if (CodeMirror.cmpPos(from, to) > 0) { var tmp = to; to = from; from = tmp; }
+      cm.state.sublimeKilled = cm.getRange(from, to);
+      cm.replaceRange("", from, to);
+    }
+  };
+  cmds[mapK[ctrl + "X"] = "swapWithSublimeMark"] = function(cm) {
+    var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
+    if (found) {
+      cm.state.sublimeMark.clear();
+      cm.state.sublimeMark = cm.setBookmark(cm.getCursor());
+      cm.setCursor(found);
+    }
+  };
+  cmds[mapK[ctrl + "Y"] = "sublimeYank"] = function(cm) {
+    if (cm.state.sublimeKilled != null)
+      cm.replaceSelection(cm.state.sublimeKilled, null, "paste");
+  };
+
+  mapK[ctrl + "G"] = "clearBookmarks";
+  cmds[mapK[ctrl + "C"] = "showInCenter"] = function(cm) {
+    var pos = cm.cursorCoords(null, "local");
+    cm.scrollTo(null, (pos.top + pos.bottom) / 2 - cm.getScrollInfo().clientHeight / 2);
+  };
+
+  cmds[map["Shift-Alt-Up"] = "selectLinesUpward"] = function(cm) {
+    cm.operation(function() {
+      var ranges = cm.listSelections();
+      for (var i = 0; i < ranges.length; i++) {
+        var range = ranges[i];
+        if (range.head.line > cm.firstLine())
+          cm.addSelection(Pos(range.head.line - 1, range.head.ch));
+      }
+    });
+  };
+  cmds[map["Shift-Alt-Down"] = "selectLinesDownward"] = function(cm) {
+    cm.operation(function() {
+      var ranges = cm.listSelections();
+      for (var i = 0; i < ranges.length; i++) {
+        var range = ranges[i];
+        if (range.head.line < cm.lastLine())
+          cm.addSelection(Pos(range.head.line + 1, range.head.ch));
+      }
+    });
+  };
+
+  function findAndGoTo(cm, forward) {
+    var from = cm.getCursor("from"), to = cm.getCursor("to");
+    if (CodeMirror.cmpPos(from, to) == 0) {
+      var word = wordAt(cm, from);
+      if (!word.word) return;
+      from = word.from;
+      to = word.to;
+    }
+
+    var query = cm.getRange(from, to);
+    var cur = cm.getSearchCursor(query, forward ? to : from);
+
+    if (forward ? cur.findNext() : cur.findPrevious()) {
+      cm.setSelection(cur.from(), cur.to());
+    } else {
+      cur = cm.getSearchCursor(query, forward ? Pos(cm.firstLine(), 0)
+                                              : cm.clipPos(Pos(cm.lastLine())));
+      if (forward ? cur.findNext() : cur.findPrevious())
+        cm.setSelection(cur.from(), cur.to());
+      else if (word)
+        cm.setSelection(from, to);
+    }
+  };
+  cmds[map[ctrl + "F3"] = "findUnder"] = function(cm) { findAndGoTo(cm, true); };
+  cmds[map["Shift-" + ctrl + "F3"] = "findUnderPrevious"] = function(cm) { findAndGoTo(cm,false); };
+
+  map["Shift-" + ctrl + "["] = "fold";
+  map["Shift-" + ctrl + "]"] = "unfold";
+  mapK[ctrl + "0"] = mapK[ctrl + "j"] = "unfoldAll";
+
+  map[ctrl + "I"] = "findIncremental";
+  map["Shift-" + ctrl + "I"] = "findIncrementalReverse";
+  map[ctrl + "H"] = "replace";
+  map["F3"] = "findNext";
+  map["Shift-F3"] = "findPrev";
+
+});
diff --git a/app/gui/html/vendor/codemirror/keymap/vim.js b/app/gui/html/vendor/codemirror/keymap/vim.js
new file mode 100644
index 0000000..f9cdfd5
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/keymap/vim.js
@@ -0,0 +1,4123 @@
+/**
+ * Supported keybindings:
+ *
+ *   Motion:
+ *   h, j, k, l
+ *   gj, gk
+ *   e, E, w, W, b, B, ge, gE
+ *   f<character>, F<character>, t<character>, T<character>
+ *   $, ^, 0, -, +, _
+ *   gg, G
+ *   %
+ *   '<character>, `<character>
+ *
+ *   Operator:
+ *   d, y, c
+ *   dd, yy, cc
+ *   g~, g~g~
+ *   >, <, >>, <<
+ *
+ *   Operator-Motion:
+ *   x, X, D, Y, C, ~
+ *
+ *   Action:
+ *   a, i, s, A, I, S, o, O
+ *   zz, z., z<CR>, zt, zb, z-
+ *   J
+ *   u, Ctrl-r
+ *   m<character>
+ *   r<character>
+ *
+ *   Modes:
+ *   ESC - leave insert mode, visual mode, and clear input state.
+ *   Ctrl-[, Ctrl-c - same as ESC.
+ *
+ * Registers: unnamed, -, a-z, A-Z, 0-9
+ *   (Does not respect the special case for number registers when delete
+ *    operator is made with these commands: %, (, ),  , /, ?, n, N, {, } )
+ *   TODO: Implement the remaining registers.
+ * Marks: a-z, A-Z, and 0-9
+ *   TODO: Implement the remaining special marks. They have more complex
+ *       behavior.
+ *
+ * Events:
+ *  'vim-mode-change' - raised on the editor anytime the current mode changes,
+ *                      Event object: {mode: "visual", subMode: "linewise"}
+ *
+ * Code structure:
+ *  1. Default keymap
+ *  2. Variable declarations and short basic helpers
+ *  3. Instance (External API) implementation
+ *  4. Internal state tracking objects (input state, counter) implementation
+ *     and instanstiation
+ *  5. Key handler (the main command dispatcher) implementation
+ *  6. Motion, operator, and action implementations
+ *  7. Helper functions for the key handler, motions, operators, and actions
+ *  8. Set up Vim to work as a keymap for CodeMirror.
+ */
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../lib/codemirror"), require("../addon/search/searchcursor"), require("../addon/dialog/dialog"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../lib/codemirror", "../addon/search/searchcursor", "../addon/dialog/dialog"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  'use strict';
+
+  var defaultKeymap = [
+    // Key to key mapping. This goes first to make it possible to override
+    // existing mappings.
+    { keys: ['<Left>'], type: 'keyToKey', toKeys: ['h'] },
+    { keys: ['<Right>'], type: 'keyToKey', toKeys: ['l'] },
+    { keys: ['<Up>'], type: 'keyToKey', toKeys: ['k'] },
+    { keys: ['<Down>'], type: 'keyToKey', toKeys: ['j'] },
+    { keys: ['<Space>'], type: 'keyToKey', toKeys: ['l'] },
+    { keys: ['<BS>'], type: 'keyToKey', toKeys: ['h'] },
+    { keys: ['<C-Space>'], type: 'keyToKey', toKeys: ['W'] },
+    { keys: ['<C-BS>'], type: 'keyToKey', toKeys: ['B'] },
+    { keys: ['<S-Space>'], type: 'keyToKey', toKeys: ['w'] },
+    { keys: ['<S-BS>'], type: 'keyToKey', toKeys: ['b'] },
+    { keys: ['<C-n>'], type: 'keyToKey', toKeys: ['j'] },
+    { keys: ['<C-p>'], type: 'keyToKey', toKeys: ['k'] },
+    { keys: ['<C-[>'], type: 'keyToKey', toKeys: ['<Esc>'] },
+    { keys: ['<C-c>'], type: 'keyToKey', toKeys: ['<Esc>'] },
+    { keys: ['s'], type: 'keyToKey', toKeys: ['c', 'l'], context: 'normal' },
+    { keys: ['s'], type: 'keyToKey', toKeys: ['x', 'i'], context: 'visual'},
+    { keys: ['S'], type: 'keyToKey', toKeys: ['c', 'c'], context: 'normal' },
+    { keys: ['S'], type: 'keyToKey', toKeys: ['d', 'c', 'c'], context: 'visual' },
+    { keys: ['<Home>'], type: 'keyToKey', toKeys: ['0'] },
+    { keys: ['<End>'], type: 'keyToKey', toKeys: ['$'] },
+    { keys: ['<PageUp>'], type: 'keyToKey', toKeys: ['<C-b>'] },
+    { keys: ['<PageDown>'], type: 'keyToKey', toKeys: ['<C-f>'] },
+    { keys: ['<CR>'], type: 'keyToKey', toKeys: ['j', '^'], context: 'normal' },
+    // Motions
+    { keys: ['H'], type: 'motion',
+        motion: 'moveToTopLine',
+        motionArgs: { linewise: true, toJumplist: true }},
+    { keys: ['M'], type: 'motion',
+        motion: 'moveToMiddleLine',
+        motionArgs: { linewise: true, toJumplist: true }},
+    { keys: ['L'], type: 'motion',
+        motion: 'moveToBottomLine',
+        motionArgs: { linewise: true, toJumplist: true }},
+    { keys: ['h'], type: 'motion',
+        motion: 'moveByCharacters',
+        motionArgs: { forward: false }},
+    { keys: ['l'], type: 'motion',
+        motion: 'moveByCharacters',
+        motionArgs: { forward: true }},
+    { keys: ['j'], type: 'motion',
+        motion: 'moveByLines',
+        motionArgs: { forward: true, linewise: true }},
+    { keys: ['k'], type: 'motion',
+        motion: 'moveByLines',
+        motionArgs: { forward: false, linewise: true }},
+    { keys: ['g','j'], type: 'motion',
+        motion: 'moveByDisplayLines',
+        motionArgs: { forward: true }},
+    { keys: ['g','k'], type: 'motion',
+        motion: 'moveByDisplayLines',
+        motionArgs: { forward: false }},
+    { keys: ['w'], type: 'motion',
+        motion: 'moveByWords',
+        motionArgs: { forward: true, wordEnd: false }},
+    { keys: ['W'], type: 'motion',
+        motion: 'moveByWords',
+        motionArgs: { forward: true, wordEnd: false, bigWord: true }},
+    { keys: ['e'], type: 'motion',
+        motion: 'moveByWords',
+        motionArgs: { forward: true, wordEnd: true, inclusive: true }},
+    { keys: ['E'], type: 'motion',
+        motion: 'moveByWords',
+        motionArgs: { forward: true, wordEnd: true, bigWord: true,
+            inclusive: true }},
+    { keys: ['b'], type: 'motion',
+        motion: 'moveByWords',
+        motionArgs: { forward: false, wordEnd: false }},
+    { keys: ['B'], type: 'motion',
+        motion: 'moveByWords',
+        motionArgs: { forward: false, wordEnd: false, bigWord: true }},
+    { keys: ['g', 'e'], type: 'motion',
+        motion: 'moveByWords',
+        motionArgs: { forward: false, wordEnd: true, inclusive: true }},
+    { keys: ['g', 'E'], type: 'motion',
+        motion: 'moveByWords',
+        motionArgs: { forward: false, wordEnd: true, bigWord: true,
+            inclusive: true }},
+    { keys: ['{'], type: 'motion', motion: 'moveByParagraph',
+        motionArgs: { forward: false, toJumplist: true }},
+    { keys: ['}'], type: 'motion', motion: 'moveByParagraph',
+        motionArgs: { forward: true, toJumplist: true }},
+    { keys: ['<C-f>'], type: 'motion',
+        motion: 'moveByPage', motionArgs: { forward: true }},
+    { keys: ['<C-b>'], type: 'motion',
+        motion: 'moveByPage', motionArgs: { forward: false }},
+    { keys: ['<C-d>'], type: 'motion',
+        motion: 'moveByScroll',
+        motionArgs: { forward: true, explicitRepeat: true }},
+    { keys: ['<C-u>'], type: 'motion',
+        motion: 'moveByScroll',
+        motionArgs: { forward: false, explicitRepeat: true }},
+    { keys: ['g', 'g'], type: 'motion',
+        motion: 'moveToLineOrEdgeOfDocument',
+        motionArgs: { forward: false, explicitRepeat: true, linewise: true, toJumplist: true }},
+    { keys: ['G'], type: 'motion',
+        motion: 'moveToLineOrEdgeOfDocument',
+        motionArgs: { forward: true, explicitRepeat: true, linewise: true, toJumplist: true }},
+    { keys: ['0'], type: 'motion', motion: 'moveToStartOfLine' },
+    { keys: ['^'], type: 'motion',
+        motion: 'moveToFirstNonWhiteSpaceCharacter' },
+    { keys: ['+'], type: 'motion',
+        motion: 'moveByLines',
+        motionArgs: { forward: true, toFirstChar:true }},
+    { keys: ['-'], type: 'motion',
+        motion: 'moveByLines',
+        motionArgs: { forward: false, toFirstChar:true }},
+    { keys: ['_'], type: 'motion',
+        motion: 'moveByLines',
+        motionArgs: { forward: true, toFirstChar:true, repeatOffset:-1 }},
+    { keys: ['$'], type: 'motion',
+        motion: 'moveToEol',
+        motionArgs: { inclusive: true }},
+    { keys: ['%'], type: 'motion',
+        motion: 'moveToMatchedSymbol',
+        motionArgs: { inclusive: true, toJumplist: true }},
+    { keys: ['f', 'character'], type: 'motion',
+        motion: 'moveToCharacter',
+        motionArgs: { forward: true , inclusive: true }},
+    { keys: ['F', 'character'], type: 'motion',
+        motion: 'moveToCharacter',
+        motionArgs: { forward: false }},
+    { keys: ['t', 'character'], type: 'motion',
+        motion: 'moveTillCharacter',
+        motionArgs: { forward: true, inclusive: true }},
+    { keys: ['T', 'character'], type: 'motion',
+        motion: 'moveTillCharacter',
+        motionArgs: { forward: false }},
+    { keys: [';'], type: 'motion', motion: 'repeatLastCharacterSearch',
+        motionArgs: { forward: true }},
+    { keys: [','], type: 'motion', motion: 'repeatLastCharacterSearch',
+        motionArgs: { forward: false }},
+    { keys: ['\'', 'character'], type: 'motion', motion: 'goToMark',
+        motionArgs: {toJumplist: true}},
+    { keys: ['`', 'character'], type: 'motion', motion: 'goToMark',
+        motionArgs: {toJumplist: true}},
+    { keys: [']', '`'], type: 'motion', motion: 'jumpToMark', motionArgs: { forward: true } },
+    { keys: ['[', '`'], type: 'motion', motion: 'jumpToMark', motionArgs: { forward: false } },
+    { keys: [']', '\''], type: 'motion', motion: 'jumpToMark', motionArgs: { forward: true, linewise: true } },
+    { keys: ['[', '\''], type: 'motion', motion: 'jumpToMark', motionArgs: { forward: false, linewise: true } },
+    { keys: [']', 'character'], type: 'motion',
+        motion: 'moveToSymbol',
+        motionArgs: { forward: true, toJumplist: true}},
+    { keys: ['[', 'character'], type: 'motion',
+        motion: 'moveToSymbol',
+        motionArgs: { forward: false, toJumplist: true}},
+    { keys: ['|'], type: 'motion',
+        motion: 'moveToColumn',
+        motionArgs: { }},
+    { keys: ['o'], type: 'motion', motion: 'moveToOtherHighlightedEnd', motionArgs: { },context:'visual'},
+    // Operators
+    { keys: ['d'], type: 'operator', operator: 'delete' },
+    { keys: ['y'], type: 'operator', operator: 'yank' },
+    { keys: ['c'], type: 'operator', operator: 'change' },
+    { keys: ['>'], type: 'operator', operator: 'indent',
+        operatorArgs: { indentRight: true }},
+    { keys: ['<'], type: 'operator', operator: 'indent',
+        operatorArgs: { indentRight: false }},
+    { keys: ['g', '~'], type: 'operator', operator: 'swapcase' },
+    { keys: ['n'], type: 'motion', motion: 'findNext',
+        motionArgs: { forward: true, toJumplist: true }},
+    { keys: ['N'], type: 'motion', motion: 'findNext',
+        motionArgs: { forward: false, toJumplist: true }},
+    // Operator-Motion dual commands
+    { keys: ['x'], type: 'operatorMotion', operator: 'delete',
+        motion: 'moveByCharacters', motionArgs: { forward: true },
+        operatorMotionArgs: { visualLine: false }},
+    { keys: ['X'], type: 'operatorMotion', operator: 'delete',
+        motion: 'moveByCharacters', motionArgs: { forward: false },
+        operatorMotionArgs: { visualLine: true }},
+    { keys: ['D'], type: 'operatorMotion', operator: 'delete',
+      motion: 'moveToEol', motionArgs: { inclusive: true },
+        operatorMotionArgs: { visualLine: true }},
+    { keys: ['Y'], type: 'operatorMotion', operator: 'yank',
+        motion: 'moveToEol', motionArgs: { inclusive: true },
+        operatorMotionArgs: { visualLine: true }},
+    { keys: ['C'], type: 'operatorMotion',
+        operator: 'change',
+        motion: 'moveToEol', motionArgs: { inclusive: true },
+        operatorMotionArgs: { visualLine: true }},
+    { keys: ['~'], type: 'operatorMotion',
+        operator: 'swapcase', operatorArgs: { shouldMoveCursor: true },
+        motion: 'moveByCharacters', motionArgs: { forward: true }},
+    // Actions
+    { keys: ['<C-i>'], type: 'action', action: 'jumpListWalk',
+        actionArgs: { forward: true }},
+    { keys: ['<C-o>'], type: 'action', action: 'jumpListWalk',
+        actionArgs: { forward: false }},
+    { keys: ['<C-e>'], type: 'action',
+        action: 'scroll',
+        actionArgs: { forward: true, linewise: true }},
+    { keys: ['<C-y>'], type: 'action',
+        action: 'scroll',
+        actionArgs: { forward: false, linewise: true }},
+    { keys: ['a'], type: 'action', action: 'enterInsertMode', isEdit: true,
+        actionArgs: { insertAt: 'charAfter' }},
+    { keys: ['A'], type: 'action', action: 'enterInsertMode', isEdit: true,
+        actionArgs: { insertAt: 'eol' }},
+    { keys: ['i'], type: 'action', action: 'enterInsertMode', isEdit: true,
+        actionArgs: { insertAt: 'inplace' }},
+    { keys: ['I'], type: 'action', action: 'enterInsertMode', isEdit: true,
+        actionArgs: { insertAt: 'firstNonBlank' }},
+    { keys: ['o'], type: 'action', action: 'newLineAndEnterInsertMode',
+        isEdit: true, interlaceInsertRepeat: true,
+        actionArgs: { after: true }},
+    { keys: ['O'], type: 'action', action: 'newLineAndEnterInsertMode',
+        isEdit: true, interlaceInsertRepeat: true,
+        actionArgs: { after: false }},
+    { keys: ['v'], type: 'action', action: 'toggleVisualMode' },
+    { keys: ['V'], type: 'action', action: 'toggleVisualMode',
+        actionArgs: { linewise: true }},
+    { keys: ['g', 'v'], type: 'action', action: 'reselectLastSelection' },
+    { keys: ['J'], type: 'action', action: 'joinLines', isEdit: true },
+    { keys: ['p'], type: 'action', action: 'paste', isEdit: true,
+        actionArgs: { after: true, isEdit: true }},
+    { keys: ['P'], type: 'action', action: 'paste', isEdit: true,
+        actionArgs: { after: false, isEdit: true }},
+    { keys: ['r', 'character'], type: 'action', action: 'replace', isEdit: true },
+    { keys: ['@', 'character'], type: 'action', action: 'replayMacro' },
+    { keys: ['q', 'character'], type: 'action', action: 'enterMacroRecordMode' },
+    // Handle Replace-mode as a special case of insert mode.
+    { keys: ['R'], type: 'action', action: 'enterInsertMode', isEdit: true,
+        actionArgs: { replace: true }},
+    { keys: ['u'], type: 'action', action: 'undo' },
+    { keys: ['<C-r>'], type: 'action', action: 'redo' },
+    { keys: ['m', 'character'], type: 'action', action: 'setMark' },
+    { keys: ['"', 'character'], type: 'action', action: 'setRegister' },
+    { keys: ['z', 'z'], type: 'action', action: 'scrollToCursor',
+        actionArgs: { position: 'center' }},
+    { keys: ['z', '.'], type: 'action', action: 'scrollToCursor',
+        actionArgs: { position: 'center' },
+        motion: 'moveToFirstNonWhiteSpaceCharacter' },
+    { keys: ['z', 't'], type: 'action', action: 'scrollToCursor',
+        actionArgs: { position: 'top' }},
+    { keys: ['z', '<CR>'], type: 'action', action: 'scrollToCursor',
+        actionArgs: { position: 'top' },
+        motion: 'moveToFirstNonWhiteSpaceCharacter' },
+    { keys: ['z', '-'], type: 'action', action: 'scrollToCursor',
+        actionArgs: { position: 'bottom' }},
+    { keys: ['z', 'b'], type: 'action', action: 'scrollToCursor',
+        actionArgs: { position: 'bottom' },
+        motion: 'moveToFirstNonWhiteSpaceCharacter' },
+    { keys: ['.'], type: 'action', action: 'repeatLastEdit' },
+    { keys: ['<C-a>'], type: 'action', action: 'incrementNumberToken',
+        isEdit: true,
+        actionArgs: {increase: true, backtrack: false}},
+    { keys: ['<C-x>'], type: 'action', action: 'incrementNumberToken',
+        isEdit: true,
+        actionArgs: {increase: false, backtrack: false}},
+    // Text object motions
+    { keys: ['a', 'character'], type: 'motion',
+        motion: 'textObjectManipulation' },
+    { keys: ['i', 'character'], type: 'motion',
+        motion: 'textObjectManipulation',
+        motionArgs: { textObjectInner: true }},
+    // Search
+    { keys: ['/'], type: 'search',
+        searchArgs: { forward: true, querySrc: 'prompt', toJumplist: true }},
+    { keys: ['?'], type: 'search',
+        searchArgs: { forward: false, querySrc: 'prompt', toJumplist: true }},
+    { keys: ['*'], type: 'search',
+        searchArgs: { forward: true, querySrc: 'wordUnderCursor', toJumplist: true }},
+    { keys: ['#'], type: 'search',
+        searchArgs: { forward: false, querySrc: 'wordUnderCursor', toJumplist: true }},
+    // Ex command
+    { keys: [':'], type: 'ex' }
+  ];
+
+  var Pos = CodeMirror.Pos;
+
+  var Vim = function() {
+    CodeMirror.defineOption('vimMode', false, function(cm, val) {
+      if (val) {
+        cm.setOption('keyMap', 'vim');
+        cm.setOption('disableInput', true);
+        CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
+        cm.on('beforeSelectionChange', beforeSelectionChange);
+        maybeInitVimState(cm);
+        CodeMirror.on(cm.getInputField(), 'paste', getOnPasteFn(cm));
+      } else if (cm.state.vim) {
+        cm.setOption('keyMap', 'default');
+        cm.setOption('disableInput', false);
+        cm.off('beforeSelectionChange', beforeSelectionChange);
+        CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm));
+        cm.state.vim = null;
+      }
+    });
+    function beforeSelectionChange(cm, obj) {
+      var vim = cm.state.vim;
+      if (vim.insertMode || vim.exMode) return;
+
+      var head = obj.ranges[0].head;
+      var anchor = obj.ranges[0].anchor;
+      if (head.ch && head.ch == cm.doc.getLine(head.line).length) {
+        var pos = Pos(head.line, head.ch - 1);
+        obj.update([{anchor: cursorEqual(head, anchor) ? pos : anchor,
+                     head: pos}]);
+      }
+    }
+    function getOnPasteFn(cm) {
+      var vim = cm.state.vim;
+      if (!vim.onPasteFn) {
+        vim.onPasteFn = function() {
+          if (!vim.insertMode) {
+            cm.setCursor(offsetCursor(cm.getCursor(), 0, 1));
+            actions.enterInsertMode(cm, {}, vim);
+          }
+        };
+      }
+      return vim.onPasteFn;
+    }
+
+    var numberRegex = /[\d]/;
+    var wordRegexp = [(/\w/), (/[^\w\s]/)], bigWordRegexp = [(/\S/)];
+    function makeKeyRange(start, size) {
+      var keys = [];
+      for (var i = start; i < start + size; i++) {
+        keys.push(String.fromCharCode(i));
+      }
+      return keys;
+    }
+    var upperCaseAlphabet = makeKeyRange(65, 26);
+    var lowerCaseAlphabet = makeKeyRange(97, 26);
+    var numbers = makeKeyRange(48, 10);
+    var specialSymbols = '~`!@#$%^&*()_-+=[{}]\\|/?.,<>:;"\''.split('');
+    var specialKeys = ['Left', 'Right', 'Up', 'Down', 'Space', 'Backspace',
+        'Esc', 'Home', 'End', 'PageUp', 'PageDown', 'Enter'];
+    var validMarks = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['<', '>']);
+    var validRegisters = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['-', '"']);
+
+    function isLine(cm, line) {
+      return line >= cm.firstLine() && line <= cm.lastLine();
+    }
+    function isLowerCase(k) {
+      return (/^[a-z]$/).test(k);
+    }
+    function isMatchableSymbol(k) {
+      return '()[]{}'.indexOf(k) != -1;
+    }
+    function isNumber(k) {
+      return numberRegex.test(k);
+    }
+    function isUpperCase(k) {
+      return (/^[A-Z]$/).test(k);
+    }
+    function isWhiteSpaceString(k) {
+      return (/^\s*$/).test(k);
+    }
+    function inArray(val, arr) {
+      for (var i = 0; i < arr.length; i++) {
+        if (arr[i] == val) {
+          return true;
+        }
+      }
+      return false;
+    }
+
+    var options = {};
+    function defineOption(name, defaultValue, type) {
+      if (defaultValue === undefined) { throw Error('defaultValue is required'); }
+      if (!type) { type = 'string'; }
+      options[name] = {
+        type: type,
+        defaultValue: defaultValue
+      };
+      setOption(name, defaultValue);
+    }
+
+    function setOption(name, value) {
+      var option = options[name];
+      if (!option) {
+        throw Error('Unknown option: ' + name);
+      }
+      if (option.type == 'boolean') {
+        if (value && value !== true) {
+          throw Error('Invalid argument: ' + name + '=' + value);
+        } else if (value !== false) {
+          // Boolean options are set to true if value is not defined.
+          value = true;
+        }
+      }
+      option.value = option.type == 'boolean' ? !!value : value;
+    }
+
+    function getOption(name) {
+      var option = options[name];
+      if (!option) {
+        throw Error('Unknown option: ' + name);
+      }
+      return option.value;
+    }
+
+    var createCircularJumpList = function() {
+      var size = 100;
+      var pointer = -1;
+      var head = 0;
+      var tail = 0;
+      var buffer = new Array(size);
+      function add(cm, oldCur, newCur) {
+        var current = pointer % size;
+        var curMark = buffer[current];
+        function useNextSlot(cursor) {
+          var next = ++pointer % size;
+          var trashMark = buffer[next];
+          if (trashMark) {
+            trashMark.clear();
+          }
+          buffer[next] = cm.setBookmark(cursor);
+        }
+        if (curMark) {
+          var markPos = curMark.find();
+          // avoid recording redundant cursor position
+          if (markPos && !cursorEqual(markPos, oldCur)) {
+            useNextSlot(oldCur);
+          }
+        } else {
+          useNextSlot(oldCur);
+        }
+        useNextSlot(newCur);
+        head = pointer;
+        tail = pointer - size + 1;
+        if (tail < 0) {
+          tail = 0;
+        }
+      }
+      function move(cm, offset) {
+        pointer += offset;
+        if (pointer > head) {
+          pointer = head;
+        } else if (pointer < tail) {
+          pointer = tail;
+        }
+        var mark = buffer[(size + pointer) % size];
+        // skip marks that are temporarily removed from text buffer
+        if (mark && !mark.find()) {
+          var inc = offset > 0 ? 1 : -1;
+          var newCur;
+          var oldCur = cm.getCursor();
+          do {
+            pointer += inc;
+            mark = buffer[(size + pointer) % size];
+            // skip marks that are the same as current position
+            if (mark &&
+                (newCur = mark.find()) &&
+                !cursorEqual(oldCur, newCur)) {
+              break;
+            }
+          } while (pointer < head && pointer > tail);
+        }
+        return mark;
+      }
+      return {
+        cachedCursor: undefined, //used for # and * jumps
+        add: add,
+        move: move
+      };
+    };
+
+    // Returns an object to track the changes associated insert mode.  It
+    // clones the object that is passed in, or creates an empty object one if
+    // none is provided.
+    var createInsertModeChanges = function(c) {
+      if (c) {
+        // Copy construction
+        return {
+          changes: c.changes,
+          expectCursorActivityForChange: c.expectCursorActivityForChange
+        };
+      }
+      return {
+        // Change list
+        changes: [],
+        // Set to true on change, false on cursorActivity.
+        expectCursorActivityForChange: false
+      };
+    };
+
+    function MacroModeState() {
+      this.latestRegister = undefined;
+      this.isPlaying = false;
+      this.isRecording = false;
+      this.onRecordingDone = undefined;
+      this.lastInsertModeChanges = createInsertModeChanges();
+    }
+    MacroModeState.prototype = {
+      exitMacroRecordMode: function() {
+        var macroModeState = vimGlobalState.macroModeState;
+        macroModeState.onRecordingDone(); // close dialog
+        macroModeState.onRecordingDone = undefined;
+        macroModeState.isRecording = false;
+      },
+      enterMacroRecordMode: function(cm, registerName) {
+        var register =
+            vimGlobalState.registerController.getRegister(registerName);
+        if (register) {
+          register.clear();
+          this.latestRegister = registerName;
+          this.onRecordingDone = cm.openDialog(
+              '(recording)['+registerName+']', null, {bottom:true});
+          this.isRecording = true;
+        }
+      }
+    };
+
+    function maybeInitVimState(cm) {
+      if (!cm.state.vim) {
+        // Store instance state in the CodeMirror object.
+        cm.state.vim = {
+          inputState: new InputState(),
+          // Vim's input state that triggered the last edit, used to repeat
+          // motions and operators with '.'.
+          lastEditInputState: undefined,
+          // Vim's action command before the last edit, used to repeat actions
+          // with '.' and insert mode repeat.
+          lastEditActionCommand: undefined,
+          // When using jk for navigation, if you move from a longer line to a
+          // shorter line, the cursor may clip to the end of the shorter line.
+          // If j is pressed again and cursor goes to the next line, the
+          // cursor should go back to its horizontal position on the longer
+          // line if it can. This is to keep track of the horizontal position.
+          lastHPos: -1,
+          // Doing the same with screen-position for gj/gk
+          lastHSPos: -1,
+          // The last motion command run. Cleared if a non-motion command gets
+          // executed in between.
+          lastMotion: null,
+          marks: {},
+          insertMode: false,
+          // Repeat count for changes made in insert mode, triggered by key
+          // sequences like 3,i. Only exists when insertMode is true.
+          insertModeRepeat: undefined,
+          visualMode: false,
+          // If we are in visual line mode. No effect if visualMode is false.
+          visualLine: false,
+          lastSelection: null
+        };
+      }
+      return cm.state.vim;
+    }
+    var vimGlobalState;
+    function resetVimGlobalState() {
+      vimGlobalState = {
+        // The current search query.
+        searchQuery: null,
+        // Whether we are searching backwards.
+        searchIsReversed: false,
+        jumpList: createCircularJumpList(),
+        macroModeState: new MacroModeState,
+        // Recording latest f, t, F or T motion command.
+        lastChararacterSearch: {increment:0, forward:true, selectedCharacter:''},
+        registerController: new RegisterController({})
+      };
+      for (var optionName in options) {
+        var option = options[optionName];
+        option.value = option.defaultValue;
+      }
+    }
+
+    var vimApi= {
+      buildKeyMap: function() {
+        // TODO: Convert keymap into dictionary format for fast lookup.
+      },
+      // Testing hook, though it might be useful to expose the register
+      // controller anyways.
+      getRegisterController: function() {
+        return vimGlobalState.registerController;
+      },
+      // Testing hook.
+      resetVimGlobalState_: resetVimGlobalState,
+
+      // Testing hook.
+      getVimGlobalState_: function() {
+        return vimGlobalState;
+      },
+
+      // Testing hook.
+      maybeInitVimState_: maybeInitVimState,
+
+      InsertModeKey: InsertModeKey,
+      map: function(lhs, rhs, ctx) {
+        // Add user defined key bindings.
+        exCommandDispatcher.map(lhs, rhs, ctx);
+      },
+      setOption: setOption,
+      getOption: getOption,
+      defineOption: defineOption,
+      defineEx: function(name, prefix, func){
+        if (name.indexOf(prefix) !== 0) {
+          throw new Error('(Vim.defineEx) "'+prefix+'" is not a prefix of "'+name+'", command not registered');
+        }
+        exCommands[name]=func;
+        exCommandDispatcher.commandMap_[prefix]={name:name, shortName:prefix, type:'api'};
+      },
+      // This is the outermost function called by CodeMirror, after keys have
+      // been mapped to their Vim equivalents.
+      handleKey: function(cm, key) {
+        var command;
+        var vim = maybeInitVimState(cm);
+        var macroModeState = vimGlobalState.macroModeState;
+        if (macroModeState.isRecording) {
+          if (key == 'q') {
+            macroModeState.exitMacroRecordMode();
+            vim.inputState = new InputState();
+            return;
+          }
+        }
+        if (key == '<Esc>') {
+          // Clear input state and get back to normal mode.
+          vim.inputState = new InputState();
+          if (vim.visualMode) {
+            exitVisualMode(cm);
+          }
+          return;
+        }
+        // Enter visual mode when the mouse selects text.
+        if (!vim.visualMode &&
+            !cursorEqual(cm.getCursor('head'), cm.getCursor('anchor'))) {
+          vim.visualMode = true;
+          vim.visualLine = false;
+          CodeMirror.signal(cm, "vim-mode-change", {mode: "visual"});
+          cm.on('mousedown', exitVisualMode);
+        }
+        if (key != '0' || (key == '0' && vim.inputState.getRepeat() === 0)) {
+          // Have to special case 0 since it's both a motion and a number.
+          command = commandDispatcher.matchCommand(key, defaultKeymap, vim);
+        }
+        if (!command) {
+          if (isNumber(key)) {
+            // Increment count unless count is 0 and key is 0.
+            vim.inputState.pushRepeatDigit(key);
+          }
+          if (macroModeState.isRecording) {
+            logKey(macroModeState, key);
+          }
+          return;
+        }
+        if (command.type == 'keyToKey') {
+          // TODO: prevent infinite recursion.
+          for (var i = 0; i < command.toKeys.length; i++) {
+            this.handleKey(cm, command.toKeys[i]);
+          }
+        } else {
+          if (macroModeState.isRecording) {
+            logKey(macroModeState, key);
+          }
+          commandDispatcher.processCommand(cm, vim, command);
+        }
+      },
+      handleEx: function(cm, input) {
+        exCommandDispatcher.processCommand(cm, input);
+      }
+    };
+
+    // Represents the current input state.
+    function InputState() {
+      this.prefixRepeat = [];
+      this.motionRepeat = [];
+
+      this.operator = null;
+      this.operatorArgs = null;
+      this.motion = null;
+      this.motionArgs = null;
+      this.keyBuffer = []; // For matching multi-key commands.
+      this.registerName = null; // Defaults to the unnamed register.
+    }
+    InputState.prototype.pushRepeatDigit = function(n) {
+      if (!this.operator) {
+        this.prefixRepeat = this.prefixRepeat.concat(n);
+      } else {
+        this.motionRepeat = this.motionRepeat.concat(n);
+      }
+    };
+    InputState.prototype.getRepeat = function() {
+      var repeat = 0;
+      if (this.prefixRepeat.length > 0 || this.motionRepeat.length > 0) {
+        repeat = 1;
+        if (this.prefixRepeat.length > 0) {
+          repeat *= parseInt(this.prefixRepeat.join(''), 10);
+        }
+        if (this.motionRepeat.length > 0) {
+          repeat *= parseInt(this.motionRepeat.join(''), 10);
+        }
+      }
+      return repeat;
+    };
+
+    /*
+     * Register stores information about copy and paste registers.  Besides
+     * text, a register must store whether it is linewise (i.e., when it is
+     * pasted, should it insert itself into a new line, or should the text be
+     * inserted at the cursor position.)
+     */
+    function Register(text, linewise) {
+      this.clear();
+      this.keyBuffer = [text || ''];
+      this.insertModeChanges = [];
+      this.linewise = !!linewise;
+    }
+    Register.prototype = {
+      setText: function(text, linewise) {
+        this.keyBuffer = [text || ''];
+        this.linewise = !!linewise;
+      },
+      pushText: function(text, linewise) {
+        // if this register has ever been set to linewise, use linewise.
+        if (linewise || this.linewise) {
+          this.keyBuffer.push('\n');
+          this.linewise = true;
+        }
+        this.keyBuffer.push(text);
+      },
+      pushInsertModeChanges: function(changes) {
+        this.insertModeChanges.push(createInsertModeChanges(changes));
+      },
+      clear: function() {
+        this.keyBuffer = [];
+        this.insertModeChanges = [];
+        this.linewise = false;
+      },
+      toString: function() {
+        return this.keyBuffer.join('');
+      }
+    };
+
+    /*
+     * vim registers allow you to keep many independent copy and paste buffers.
+     * See http://usevim.com/2012/04/13/registers/ for an introduction.
+     *
+     * RegisterController keeps the state of all the registers.  An initial
+     * state may be passed in.  The unnamed register '"' will always be
+     * overridden.
+     */
+    function RegisterController(registers) {
+      this.registers = registers;
+      this.unnamedRegister = registers['"'] = new Register();
+    }
+    RegisterController.prototype = {
+      pushText: function(registerName, operator, text, linewise) {
+        if (linewise && text.charAt(0) == '\n') {
+          text = text.slice(1) + '\n';
+        }
+        if (linewise && text.charAt(text.length - 1) !== '\n'){
+          text += '\n';
+        }
+        // Lowercase and uppercase registers refer to the same register.
+        // Uppercase just means append.
+        var register = this.isValidRegister(registerName) ?
+            this.getRegister(registerName) : null;
+        // if no register/an invalid register was specified, things go to the
+        // default registers
+        if (!register) {
+          switch (operator) {
+            case 'yank':
+              // The 0 register contains the text from the most recent yank.
+              this.registers['0'] = new Register(text, linewise);
+              break;
+            case 'delete':
+            case 'change':
+              if (text.indexOf('\n') == -1) {
+                // Delete less than 1 line. Update the small delete register.
+                this.registers['-'] = new Register(text, linewise);
+              } else {
+                // Shift down the contents of the numbered registers and put the
+                // deleted text into register 1.
+                this.shiftNumericRegisters_();
+                this.registers['1'] = new Register(text, linewise);
+              }
+              break;
+          }
+          // Make sure the unnamed register is set to what just happened
+          this.unnamedRegister.setText(text, linewise);
+          return;
+        }
+
+        // If we've gotten to this point, we've actually specified a register
+        var append = isUpperCase(registerName);
+        if (append) {
+          register.append(text, linewise);
+          // The unnamed register always has the same value as the last used
+          // register.
+          this.unnamedRegister.append(text, linewise);
+        } else {
+          register.setText(text, linewise);
+          this.unnamedRegister.setText(text, linewise);
+        }
+      },
+      // Gets the register named @name.  If one of @name doesn't already exist,
+      // create it.  If @name is invalid, return the unnamedRegister.
+      getRegister: function(name) {
+        if (!this.isValidRegister(name)) {
+          return this.unnamedRegister;
+        }
+        name = name.toLowerCase();
+        if (!this.registers[name]) {
+          this.registers[name] = new Register();
+        }
+        return this.registers[name];
+      },
+      isValidRegister: function(name) {
+        return name && inArray(name, validRegisters);
+      },
+      shiftNumericRegisters_: function() {
+        for (var i = 9; i >= 2; i--) {
+          this.registers[i] = this.getRegister('' + (i - 1));
+        }
+      }
+    };
+
+    var commandDispatcher = {
+      matchCommand: function(key, keyMap, vim) {
+        var inputState = vim.inputState;
+        var keys = inputState.keyBuffer.concat(key);
+        var matchedCommands = [];
+        var selectedCharacter;
+        for (var i = 0; i < keyMap.length; i++) {
+          var command = keyMap[i];
+          if (matchKeysPartial(keys, command.keys)) {
+            if (inputState.operator && command.type == 'action') {
+              // Ignore matched action commands after an operator. Operators
+              // only operate on motions. This check is really for text
+              // objects since aW, a[ etcs conflicts with a.
+              continue;
+            }
+            // Match commands that take <character> as an argument.
+            if (command.keys[keys.length - 1] == 'character') {
+              selectedCharacter = keys[keys.length - 1];
+              if (selectedCharacter.length>1){
+                switch(selectedCharacter){
+                  case '<CR>':
+                    selectedCharacter='\n';
+                    break;
+                  case '<Space>':
+                    selectedCharacter=' ';
+                    break;
+                  default:
+                    continue;
+                }
+              }
+            }
+            // Add the command to the list of matched commands. Choose the best
+            // command later.
+            matchedCommands.push(command);
+          }
+        }
+
+        // Returns the command if it is a full match, or null if not.
+        function getFullyMatchedCommandOrNull(command) {
+          if (keys.length < command.keys.length) {
+            // Matches part of a multi-key command. Buffer and wait for next
+            // stroke.
+            inputState.keyBuffer.push(key);
+            return null;
+          } else {
+            if (command.keys[keys.length - 1] == 'character') {
+              inputState.selectedCharacter = selectedCharacter;
+            }
+            // Clear the buffer since a full match was found.
+            inputState.keyBuffer = [];
+            return command;
+          }
+        }
+
+        if (!matchedCommands.length) {
+          // Clear the buffer since there were no matches.
+          inputState.keyBuffer = [];
+          return null;
+        } else if (matchedCommands.length == 1) {
+          return getFullyMatchedCommandOrNull(matchedCommands[0]);
+        } else {
+          // Find the best match in the list of matchedCommands.
+          var context = vim.visualMode ? 'visual' : 'normal';
+          var bestMatch; // Default to first in the list.
+          for (var i = 0; i < matchedCommands.length; i++) {
+            var current = matchedCommands[i];
+            if (current.context == context) {
+              bestMatch = current;
+              break;
+            } else if (!bestMatch && !current.context) {
+              // Only set an imperfect match to best match if no best match is
+              // set and the imperfect match is not restricted to another
+              // context.
+              bestMatch = current;
+            }
+          }
+          return getFullyMatchedCommandOrNull(bestMatch);
+        }
+      },
+      processCommand: function(cm, vim, command) {
+        vim.inputState.repeatOverride = command.repeatOverride;
+        switch (command.type) {
+          case 'motion':
+            this.processMotion(cm, vim, command);
+            break;
+          case 'operator':
+            this.processOperator(cm, vim, command);
+            break;
+          case 'operatorMotion':
+            this.processOperatorMotion(cm, vim, command);
+            break;
+          case 'action':
+            this.processAction(cm, vim, command);
+            break;
+          case 'search':
+            this.processSearch(cm, vim, command);
+            break;
+          case 'ex':
+          case 'keyToEx':
+            this.processEx(cm, vim, command);
+            break;
+          default:
+            break;
+        }
+      },
+      processMotion: function(cm, vim, command) {
+        vim.inputState.motion = command.motion;
+        vim.inputState.motionArgs = copyArgs(command.motionArgs);
+        this.evalInput(cm, vim);
+      },
+      processOperator: function(cm, vim, command) {
+        var inputState = vim.inputState;
+        if (inputState.operator) {
+          if (inputState.operator == command.operator) {
+            // Typing an operator twice like 'dd' makes the operator operate
+            // linewise
+            inputState.motion = 'expandToLine';
+            inputState.motionArgs = { linewise: true };
+            this.evalInput(cm, vim);
+            return;
+          } else {
+            // 2 different operators in a row doesn't make sense.
+            vim.inputState = new InputState();
+          }
+        }
+        inputState.operator = command.operator;
+        inputState.operatorArgs = copyArgs(command.operatorArgs);
+        if (vim.visualMode) {
+          // Operating on a selection in visual mode. We don't need a motion.
+          this.evalInput(cm, vim);
+        }
+      },
+      processOperatorMotion: function(cm, vim, command) {
+        var visualMode = vim.visualMode;
+        var operatorMotionArgs = copyArgs(command.operatorMotionArgs);
+        if (operatorMotionArgs) {
+          // Operator motions may have special behavior in visual mode.
+          if (visualMode && operatorMotionArgs.visualLine) {
+            vim.visualLine = true;
+          }
+        }
+        this.processOperator(cm, vim, command);
+        if (!visualMode) {
+          this.processMotion(cm, vim, command);
+        }
+      },
+      processAction: function(cm, vim, command) {
+        var inputState = vim.inputState;
+        var repeat = inputState.getRepeat();
+        var repeatIsExplicit = !!repeat;
+        var actionArgs = copyArgs(command.actionArgs) || {};
+        if (inputState.selectedCharacter) {
+          actionArgs.selectedCharacter = inputState.selectedCharacter;
+        }
+        // Actions may or may not have motions and operators. Do these first.
+        if (command.operator) {
+          this.processOperator(cm, vim, command);
+        }
+        if (command.motion) {
+          this.processMotion(cm, vim, command);
+        }
+        if (command.motion || command.operator) {
+          this.evalInput(cm, vim);
+        }
+        actionArgs.repeat = repeat || 1;
+        actionArgs.repeatIsExplicit = repeatIsExplicit;
+        actionArgs.registerName = inputState.registerName;
+        vim.inputState = new InputState();
+        vim.lastMotion = null;
+        if (command.isEdit) {
+          this.recordLastEdit(vim, inputState, command);
+        }
+        actions[command.action](cm, actionArgs, vim);
+      },
+      processSearch: function(cm, vim, command) {
+        if (!cm.getSearchCursor) {
+          // Search depends on SearchCursor.
+          return;
+        }
+        var forward = command.searchArgs.forward;
+        getSearchState(cm).setReversed(!forward);
+        var promptPrefix = (forward) ? '/' : '?';
+        var originalQuery = getSearchState(cm).getQuery();
+        var originalScrollPos = cm.getScrollInfo();
+        function handleQuery(query, ignoreCase, smartCase) {
+          try {
+            updateSearchQuery(cm, query, ignoreCase, smartCase);
+          } catch (e) {
+            showConfirm(cm, 'Invalid regex: ' + query);
+            return;
+          }
+          commandDispatcher.processMotion(cm, vim, {
+            type: 'motion',
+            motion: 'findNext',
+            motionArgs: { forward: true, toJumplist: command.searchArgs.toJumplist }
+          });
+        }
+        function onPromptClose(query) {
+          cm.scrollTo(originalScrollPos.left, originalScrollPos.top);
+          handleQuery(query, true /** ignoreCase */, true /** smartCase */);
+        }
+        function onPromptKeyUp(_e, query) {
+          var parsedQuery;
+          try {
+            parsedQuery = updateSearchQuery(cm, query,
+                true /** ignoreCase */, true /** smartCase */);
+          } catch (e) {
+            // Swallow bad regexes for incremental search.
+          }
+          if (parsedQuery) {
+            cm.scrollIntoView(findNext(cm, !forward, parsedQuery), 30);
+          } else {
+            clearSearchHighlight(cm);
+            cm.scrollTo(originalScrollPos.left, originalScrollPos.top);
+          }
+        }
+        function onPromptKeyDown(e, _query, close) {
+          var keyName = CodeMirror.keyName(e);
+          if (keyName == 'Esc' || keyName == 'Ctrl-C' || keyName == 'Ctrl-[') {
+            updateSearchQuery(cm, originalQuery);
+            clearSearchHighlight(cm);
+            cm.scrollTo(originalScrollPos.left, originalScrollPos.top);
+
+            CodeMirror.e_stop(e);
+            close();
+            cm.focus();
+          }
+        }
+        switch (command.searchArgs.querySrc) {
+          case 'prompt':
+            showPrompt(cm, {
+                onClose: onPromptClose,
+                prefix: promptPrefix,
+                desc: searchPromptDesc,
+                onKeyUp: onPromptKeyUp,
+                onKeyDown: onPromptKeyDown
+            });
+            break;
+          case 'wordUnderCursor':
+            var word = expandWordUnderCursor(cm, false /** inclusive */,
+                true /** forward */, false /** bigWord */,
+                true /** noSymbol */);
+            var isKeyword = true;
+            if (!word) {
+              word = expandWordUnderCursor(cm, false /** inclusive */,
+                  true /** forward */, false /** bigWord */,
+                  false /** noSymbol */);
+              isKeyword = false;
+            }
+            if (!word) {
+              return;
+            }
+            var query = cm.getLine(word.start.line).substring(word.start.ch,
+                word.end.ch);
+            if (isKeyword) {
+              query = '\\b' + query + '\\b';
+            } else {
+              query = escapeRegex(query);
+            }
+
+            // cachedCursor is used to save the old position of the cursor
+            // when * or # causes vim to seek for the nearest word and shift
+            // the cursor before entering the motion.
+            vimGlobalState.jumpList.cachedCursor = cm.getCursor();
+            cm.setCursor(word.start);
+
+            handleQuery(query, true /** ignoreCase */, false /** smartCase */);
+            break;
+        }
+      },
+      processEx: function(cm, vim, command) {
+        function onPromptClose(input) {
+          // Give the prompt some time to close so that if processCommand shows
+          // an error, the elements don't overlap.
+          exCommandDispatcher.processCommand(cm, input);
+        }
+        function onPromptKeyDown(e, _input, close) {
+          var keyName = CodeMirror.keyName(e);
+          if (keyName == 'Esc' || keyName == 'Ctrl-C' || keyName == 'Ctrl-[') {
+            CodeMirror.e_stop(e);
+            close();
+            cm.focus();
+          }
+        }
+        if (command.type == 'keyToEx') {
+          // Handle user defined Ex to Ex mappings
+          exCommandDispatcher.processCommand(cm, command.exArgs.input);
+        } else {
+          if (vim.visualMode) {
+            showPrompt(cm, { onClose: onPromptClose, prefix: ':', value: '\'<,\'>',
+                onKeyDown: onPromptKeyDown});
+          } else {
+            showPrompt(cm, { onClose: onPromptClose, prefix: ':',
+                onKeyDown: onPromptKeyDown});
+          }
+        }
+      },
+      evalInput: function(cm, vim) {
+        // If the motion comand is set, execute both the operator and motion.
+        // Otherwise return.
+        var inputState = vim.inputState;
+        var motion = inputState.motion;
+        var motionArgs = inputState.motionArgs || {};
+        var operator = inputState.operator;
+        var operatorArgs = inputState.operatorArgs || {};
+        var registerName = inputState.registerName;
+        var selectionEnd = copyCursor(cm.getCursor('head'));
+        var selectionStart = copyCursor(cm.getCursor('anchor'));
+        // The difference between cur and selection cursors are that cur is
+        // being operated on and ignores that there is a selection.
+        var curStart = copyCursor(selectionEnd);
+        var curOriginal = copyCursor(curStart);
+        var curEnd;
+        var repeat;
+        if (operator) {
+          this.recordLastEdit(vim, inputState);
+        }
+        if (inputState.repeatOverride !== undefined) {
+          // If repeatOverride is specified, that takes precedence over the
+          // input state's repeat. Used by Ex mode and can be user defined.
+          repeat = inputState.repeatOverride;
+        } else {
+          repeat = inputState.getRepeat();
+        }
+        if (repeat > 0 && motionArgs.explicitRepeat) {
+          motionArgs.repeatIsExplicit = true;
+        } else if (motionArgs.noRepeat ||
+            (!motionArgs.explicitRepeat && repeat === 0)) {
+          repeat = 1;
+          motionArgs.repeatIsExplicit = false;
+        }
+        if (inputState.selectedCharacter) {
+          // If there is a character input, stick it in all of the arg arrays.
+          motionArgs.selectedCharacter = operatorArgs.selectedCharacter =
+              inputState.selectedCharacter;
+        }
+        motionArgs.repeat = repeat;
+        vim.inputState = new InputState();
+        if (motion) {
+          var motionResult = motions[motion](cm, motionArgs, vim);
+          vim.lastMotion = motions[motion];
+          if (!motionResult) {
+            return;
+          }
+          if (motionArgs.toJumplist) {
+            var jumpList = vimGlobalState.jumpList;
+            // if the current motion is # or *, use cachedCursor
+            var cachedCursor = jumpList.cachedCursor;
+            if (cachedCursor) {
+              recordJumpPosition(cm, cachedCursor, motionResult);
+              delete jumpList.cachedCursor;
+            } else {
+              recordJumpPosition(cm, curOriginal, motionResult);
+            }
+          }
+          if (motionResult instanceof Array) {
+            curStart = motionResult[0];
+            curEnd = motionResult[1];
+          } else {
+            curEnd = motionResult;
+          }
+          // TODO: Handle null returns from motion commands better.
+          if (!curEnd) {
+            curEnd = Pos(curStart.line, curStart.ch);
+          }
+          if (vim.visualMode) {
+            // Check if the selection crossed over itself. Will need to shift
+            // the start point if that happened.
+            if (cursorIsBefore(selectionStart, selectionEnd) &&
+                (cursorEqual(selectionStart, curEnd) ||
+                    cursorIsBefore(curEnd, selectionStart))) {
+              // The end of the selection has moved from after the start to
+              // before the start. We will shift the start right by 1.
+              selectionStart.ch += 1;
+            } else if (cursorIsBefore(selectionEnd, selectionStart) &&
+                (cursorEqual(selectionStart, curEnd) ||
+                    cursorIsBefore(selectionStart, curEnd))) {
+              // The opposite happened. We will shift the start left by 1.
+              selectionStart.ch -= 1;
+            }
+            selectionEnd = curEnd;
+            selectionStart = (motionResult instanceof Array) ? curStart : selectionStart;
+            if (vim.visualLine) {
+              if (cursorIsBefore(selectionStart, selectionEnd)) {
+                selectionStart.ch = 0;
+
+                var lastLine = cm.lastLine();
+                if (selectionEnd.line > lastLine) {
+                  selectionEnd.line = lastLine;
+                }
+                selectionEnd.ch = lineLength(cm, selectionEnd.line);
+              } else {
+                selectionEnd.ch = 0;
+                selectionStart.ch = lineLength(cm, selectionStart.line);
+              }
+            }
+            cm.setSelection(selectionStart, selectionEnd);
+            updateMark(cm, vim, '<',
+                cursorIsBefore(selectionStart, selectionEnd) ? selectionStart
+                    : selectionEnd);
+            updateMark(cm, vim, '>',
+                cursorIsBefore(selectionStart, selectionEnd) ? selectionEnd
+                    : selectionStart);
+          } else if (!operator) {
+            curEnd = clipCursorToContent(cm, curEnd);
+            cm.setCursor(curEnd.line, curEnd.ch);
+          }
+        }
+
+        if (operator) {
+          var inverted = false;
+          vim.lastMotion = null;
+          operatorArgs.repeat = repeat; // Indent in visual mode needs this.
+          if (vim.visualMode) {
+            curStart = selectionStart;
+            curEnd = selectionEnd;
+            motionArgs.inclusive = true;
+          }
+          // Swap start and end if motion was backward.
+          if (cursorIsBefore(curEnd, curStart)) {
+            var tmp = curStart;
+            curStart = curEnd;
+            curEnd = tmp;
+            inverted = true;
+          }
+          if (motionArgs.inclusive && !(vim.visualMode && inverted)) {
+            // Move the selection end one to the right to include the last
+            // character.
+            curEnd.ch++;
+          }
+          var linewise = motionArgs.linewise ||
+              (vim.visualMode && vim.visualLine);
+          if (linewise) {
+            // Expand selection to entire line.
+            expandSelectionToLine(cm, curStart, curEnd);
+          } else if (motionArgs.forward) {
+            // Clip to trailing newlines only if the motion goes forward.
+            clipToLine(cm, curStart, curEnd);
+          }
+          operatorArgs.registerName = registerName;
+          // Keep track of linewise as it affects how paste and change behave.
+          operatorArgs.linewise = linewise;
+          operators[operator](cm, operatorArgs, vim, curStart,
+              curEnd, curOriginal);
+          if (vim.visualMode) {
+            exitVisualMode(cm);
+          }
+        }
+      },
+      recordLastEdit: function(vim, inputState, actionCommand) {
+        var macroModeState = vimGlobalState.macroModeState;
+        if (macroModeState.isPlaying) { return; }
+        vim.lastEditInputState = inputState;
+        vim.lastEditActionCommand = actionCommand;
+        macroModeState.lastInsertModeChanges.changes = [];
+        macroModeState.lastInsertModeChanges.expectCursorActivityForChange = false;
+      }
+    };
+
+    /**
+     * typedef {Object{line:number,ch:number}} Cursor An object containing the
+     *     position of the cursor.
+     */
+    // All of the functions below return Cursor objects.
+    var motions = {
+      moveToTopLine: function(cm, motionArgs) {
+        var line = getUserVisibleLines(cm).top + motionArgs.repeat -1;
+        return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));
+      },
+      moveToMiddleLine: function(cm) {
+        var range = getUserVisibleLines(cm);
+        var line = Math.floor((range.top + range.bottom) * 0.5);
+        return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));
+      },
+      moveToBottomLine: function(cm, motionArgs) {
+        var line = getUserVisibleLines(cm).bottom - motionArgs.repeat +1;
+        return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));
+      },
+      expandToLine: function(cm, motionArgs) {
+        // Expands forward to end of line, and then to next line if repeat is
+        // >1. Does not handle backward motion!
+        var cur = cm.getCursor();
+        return Pos(cur.line + motionArgs.repeat - 1, Infinity);
+      },
+      findNext: function(cm, motionArgs) {
+        var state = getSearchState(cm);
+        var query = state.getQuery();
+        if (!query) {
+          return;
+        }
+        var prev = !motionArgs.forward;
+        // If search is initiated with ? instead of /, negate direction.
+        prev = (state.isReversed()) ? !prev : prev;
+        highlightSearchMatches(cm, query);
+        return findNext(cm, prev/** prev */, query, motionArgs.repeat);
+      },
+      goToMark: function(_cm, motionArgs, vim) {
+        var mark = vim.marks[motionArgs.selectedCharacter];
+        if (mark) {
+          return mark.find();
+        }
+        return null;
+      },
+      moveToOtherHighlightedEnd: function(cm) {
+        var curEnd = copyCursor(cm.getCursor('head'));
+        var curStart = copyCursor(cm.getCursor('anchor'));
+        if (cursorIsBefore(curStart, curEnd)) {
+           curEnd.ch += 1;
+        } else if (cursorIsBefore(curEnd, curStart)) {
+           curStart.ch -= 1;
+        }
+        return ([curEnd,curStart]);
+      },
+      jumpToMark: function(cm, motionArgs, vim) {
+        var best = cm.getCursor();
+        for (var i = 0; i < motionArgs.repeat; i++) {
+          var cursor = best;
+          for (var key in vim.marks) {
+            if (!isLowerCase(key)) {
+              continue;
+            }
+            var mark = vim.marks[key].find();
+            var isWrongDirection = (motionArgs.forward) ?
+              cursorIsBefore(mark, cursor) : cursorIsBefore(cursor, mark);
+
+            if (isWrongDirection) {
+              continue;
+            }
+            if (motionArgs.linewise && (mark.line == cursor.line)) {
+              continue;
+            }
+
+            var equal = cursorEqual(cursor, best);
+            var between = (motionArgs.forward) ?
+              cusrorIsBetween(cursor, mark, best) :
+              cusrorIsBetween(best, mark, cursor);
+
+            if (equal || between) {
+              best = mark;
+            }
+          }
+        }
+
+        if (motionArgs.linewise) {
+          // Vim places the cursor on the first non-whitespace character of
+          // the line if there is one, else it places the cursor at the end
+          // of the line, regardless of whether a mark was found.
+          best = Pos(best.line, findFirstNonWhiteSpaceCharacter(cm.getLine(best.line)));
+        }
+        return best;
+      },
+      moveByCharacters: function(cm, motionArgs) {
+        var cur = cm.getCursor();
+        var repeat = motionArgs.repeat;
+        var ch = motionArgs.forward ? cur.ch + repeat : cur.ch - repeat;
+        return Pos(cur.line, ch);
+      },
+      moveByLines: function(cm, motionArgs, vim) {
+        var cur = cm.getCursor();
+        var endCh = cur.ch;
+        // Depending what our last motion was, we may want to do different
+        // things. If our last motion was moving vertically, we want to
+        // preserve the HPos from our last horizontal move.  If our last motion
+        // was going to the end of a line, moving vertically we should go to
+        // the end of the line, etc.
+        switch (vim.lastMotion) {
+          case this.moveByLines:
+          case this.moveByDisplayLines:
+          case this.moveByScroll:
+          case this.moveToColumn:
+          case this.moveToEol:
+            endCh = vim.lastHPos;
+            break;
+          default:
+            vim.lastHPos = endCh;
+        }
+        var repeat = motionArgs.repeat+(motionArgs.repeatOffset||0);
+        var line = motionArgs.forward ? cur.line + repeat : cur.line - repeat;
+        var first = cm.firstLine();
+        var last = cm.lastLine();
+        // Vim cancels linewise motions that start on an edge and move beyond
+        // that edge. It does not cancel motions that do not start on an edge.
+        if ((line < first && cur.line == first) ||
+            (line > last && cur.line == last)) {
+          return;
+        }
+        if (motionArgs.toFirstChar){
+          endCh=findFirstNonWhiteSpaceCharacter(cm.getLine(line));
+          vim.lastHPos = endCh;
+        }
+        vim.lastHSPos = cm.charCoords(Pos(line, endCh),'div').left;
+        return Pos(line, endCh);
+      },
+      moveByDisplayLines: function(cm, motionArgs, vim) {
+        var cur = cm.getCursor();
+        switch (vim.lastMotion) {
+          case this.moveByDisplayLines:
+          case this.moveByScroll:
+          case this.moveByLines:
+          case this.moveToColumn:
+          case this.moveToEol:
+            break;
+          default:
+            vim.lastHSPos = cm.charCoords(cur,'div').left;
+        }
+        var repeat = motionArgs.repeat;
+        var res=cm.findPosV(cur,(motionArgs.forward ? repeat : -repeat),'line',vim.lastHSPos);
+        if (res.hitSide) {
+          if (motionArgs.forward) {
+            var lastCharCoords = cm.charCoords(res, 'div');
+            var goalCoords = { top: lastCharCoords.top + 8, left: vim.lastHSPos };
+            var res = cm.coordsChar(goalCoords, 'div');
+          } else {
+            var resCoords = cm.charCoords(Pos(cm.firstLine(), 0), 'div');
+            resCoords.left = vim.lastHSPos;
+            res = cm.coordsChar(resCoords, 'div');
+          }
+        }
+        vim.lastHPos = res.ch;
+        return res;
+      },
+      moveByPage: function(cm, motionArgs) {
+        // CodeMirror only exposes functions that move the cursor page down, so
+        // doing this bad hack to move the cursor and move it back. evalInput
+        // will move the cursor to where it should be in the end.
+        var curStart = cm.getCursor();
+        var repeat = motionArgs.repeat;
+        cm.moveV((motionArgs.forward ? repeat : -repeat), 'page');
+        var curEnd = cm.getCursor();
+        cm.setCursor(curStart);
+        return curEnd;
+      },
+      moveByParagraph: function(cm, motionArgs) {
+        var line = cm.getCursor().line;
+        var repeat = motionArgs.repeat;
+        var inc = motionArgs.forward ? 1 : -1;
+        for (var i = 0; i < repeat; i++) {
+          if ((!motionArgs.forward && line === cm.firstLine() ) ||
+              (motionArgs.forward && line == cm.lastLine())) {
+            break;
+          }
+          line += inc;
+          while (line !== cm.firstLine() && line != cm.lastLine() && cm.getLine(line)) {
+            line += inc;
+          }
+        }
+        return Pos(line, 0);
+      },
+      moveByScroll: function(cm, motionArgs, vim) {
+        var scrollbox = cm.getScrollInfo();
+        var curEnd = null;
+        var repeat = motionArgs.repeat;
+        if (!repeat) {
+          repeat = scrollbox.clientHeight / (2 * cm.defaultTextHeight());
+        }
+        var orig = cm.charCoords(cm.getCursor(), 'local');
+        motionArgs.repeat = repeat;
+        var curEnd = motions.moveByDisplayLines(cm, motionArgs, vim);
+        if (!curEnd) {
+          return null;
+        }
+        var dest = cm.charCoords(curEnd, 'local');
+        cm.scrollTo(null, scrollbox.top + dest.top - orig.top);
+        return curEnd;
+      },
+      moveByWords: function(cm, motionArgs) {
+        return moveToWord(cm, motionArgs.repeat, !!motionArgs.forward,
+            !!motionArgs.wordEnd, !!motionArgs.bigWord);
+      },
+      moveTillCharacter: function(cm, motionArgs) {
+        var repeat = motionArgs.repeat;
+        var curEnd = moveToCharacter(cm, repeat, motionArgs.forward,
+            motionArgs.selectedCharacter);
+        var increment = motionArgs.forward ? -1 : 1;
+        recordLastCharacterSearch(increment, motionArgs);
+        if (!curEnd) return null;
+        curEnd.ch += increment;
+        return curEnd;
+      },
+      moveToCharacter: function(cm, motionArgs) {
+        var repeat = motionArgs.repeat;
+        recordLastCharacterSearch(0, motionArgs);
+        return moveToCharacter(cm, repeat, motionArgs.forward,
+            motionArgs.selectedCharacter) || cm.getCursor();
+      },
+      moveToSymbol: function(cm, motionArgs) {
+        var repeat = motionArgs.repeat;
+        return findSymbol(cm, repeat, motionArgs.forward,
+            motionArgs.selectedCharacter) || cm.getCursor();
+      },
+      moveToColumn: function(cm, motionArgs, vim) {
+        var repeat = motionArgs.repeat;
+        // repeat is equivalent to which column we want to move to!
+        vim.lastHPos = repeat - 1;
+        vim.lastHSPos = cm.charCoords(cm.getCursor(),'div').left;
+        return moveToColumn(cm, repeat);
+      },
+      moveToEol: function(cm, motionArgs, vim) {
+        var cur = cm.getCursor();
+        vim.lastHPos = Infinity;
+        var retval= Pos(cur.line + motionArgs.repeat - 1, Infinity);
+        var end=cm.clipPos(retval);
+        end.ch--;
+        vim.lastHSPos = cm.charCoords(end,'div').left;
+        return retval;
+      },
+      moveToFirstNonWhiteSpaceCharacter: function(cm) {
+        // Go to the start of the line where the text begins, or the end for
+        // whitespace-only lines
+        var cursor = cm.getCursor();
+        return Pos(cursor.line,
+                   findFirstNonWhiteSpaceCharacter(cm.getLine(cursor.line)));
+      },
+      moveToMatchedSymbol: function(cm) {
+        var cursor = cm.getCursor();
+        var line = cursor.line;
+        var ch = cursor.ch;
+        var lineText = cm.getLine(line);
+        var symbol;
+        var startContext = cm.getTokenAt(cursor).type;
+        var startCtxLevel = getContextLevel(startContext);
+        do {
+          symbol = lineText.charAt(ch++);
+          if (symbol && isMatchableSymbol(symbol)) {
+            var endContext = cm.getTokenAt(Pos(line, ch)).type;
+            var endCtxLevel = getContextLevel(endContext);
+            if (startCtxLevel >= endCtxLevel) {
+              break;
+            }
+          }
+        } while (symbol);
+        if (symbol) {
+          return findMatchedSymbol(cm, Pos(line, ch-1), symbol);
+        } else {
+          return cursor;
+        }
+      },
+      moveToStartOfLine: function(cm) {
+        var cursor = cm.getCursor();
+        return Pos(cursor.line, 0);
+      },
+      moveToLineOrEdgeOfDocument: function(cm, motionArgs) {
+        var lineNum = motionArgs.forward ? cm.lastLine() : cm.firstLine();
+        if (motionArgs.repeatIsExplicit) {
+          lineNum = motionArgs.repeat - cm.getOption('firstLineNumber');
+        }
+        return Pos(lineNum,
+                   findFirstNonWhiteSpaceCharacter(cm.getLine(lineNum)));
+      },
+      textObjectManipulation: function(cm, motionArgs) {
+        // TODO: lots of possible exceptions that can be thrown here. Try da(
+        //     outside of a () block.
+
+        // TODO: adding <> >< to this map doesn't work, presumably because
+        // they're operators
+        var mirroredPairs = {'(': ')', ')': '(',
+                             '{': '}', '}': '{',
+                             '[': ']', ']': '['};
+        var selfPaired = {'\'': true, '"': true};
+
+        var character = motionArgs.selectedCharacter;
+
+        // Inclusive is the difference between a and i
+        // TODO: Instead of using the additional text object map to perform text
+        //     object operations, merge the map into the defaultKeyMap and use
+        //     motionArgs to define behavior. Define separate entries for 'aw',
+        //     'iw', 'a[', 'i[', etc.
+        var inclusive = !motionArgs.textObjectInner;
+
+        var tmp;
+        if (mirroredPairs[character]) {
+          tmp = selectCompanionObject(cm, mirroredPairs[character], inclusive);
+        } else if (selfPaired[character]) {
+          tmp = findBeginningAndEnd(cm, character, inclusive);
+        } else if (character === 'W') {
+          tmp = expandWordUnderCursor(cm, inclusive, true /** forward */,
+                                                     true /** bigWord */);
+        } else if (character === 'w') {
+          tmp = expandWordUnderCursor(cm, inclusive, true /** forward */,
+                                                     false /** bigWord */);
+        } else {
+          // No text object defined for this, don't move.
+          return null;
+        }
+
+        return [tmp.start, tmp.end];
+      },
+
+      repeatLastCharacterSearch: function(cm, motionArgs) {
+        var lastSearch = vimGlobalState.lastChararacterSearch;
+        var repeat = motionArgs.repeat;
+        var forward = motionArgs.forward === lastSearch.forward;
+        var increment = (lastSearch.increment ? 1 : 0) * (forward ? -1 : 1);
+        cm.moveH(-increment, 'char');
+        motionArgs.inclusive = forward ? true : false;
+        var curEnd = moveToCharacter(cm, repeat, forward, lastSearch.selectedCharacter);
+        if (!curEnd) {
+          cm.moveH(increment, 'char');
+          return cm.getCursor();
+        }
+        curEnd.ch += increment;
+        return curEnd;
+      }
+    };
+
+    var operators = {
+      change: function(cm, operatorArgs, _vim, curStart, curEnd) {
+        vimGlobalState.registerController.pushText(
+            operatorArgs.registerName, 'change', cm.getRange(curStart, curEnd),
+            operatorArgs.linewise);
+        if (operatorArgs.linewise) {
+          // Push the next line back down, if there is a next line.
+          var replacement = curEnd.line > cm.lastLine() ? '' : '\n';
+          cm.replaceRange(replacement, curStart, curEnd);
+          cm.indentLine(curStart.line, 'smart');
+          // null ch so setCursor moves to end of line.
+          curStart.ch = null;
+        } else {
+          // Exclude trailing whitespace if the range is not all whitespace.
+          var text = cm.getRange(curStart, curEnd);
+          if (!isWhiteSpaceString(text)) {
+            var match = (/\s+$/).exec(text);
+            if (match) {
+              curEnd = offsetCursor(curEnd, 0, - match[0].length);
+            }
+          }
+          cm.replaceRange('', curStart, curEnd);
+        }
+        actions.enterInsertMode(cm, {}, cm.state.vim);
+        cm.setCursor(curStart);
+      },
+      // delete is a javascript keyword.
+      'delete': function(cm, operatorArgs, _vim, curStart, curEnd) {
+        // If the ending line is past the last line, inclusive, instead of
+        // including the trailing \n, include the \n before the starting line
+        if (operatorArgs.linewise &&
+            curEnd.line > cm.lastLine() && curStart.line > cm.firstLine()) {
+          curStart.line--;
+          curStart.ch = lineLength(cm, curStart.line);
+        }
+        vimGlobalState.registerController.pushText(
+            operatorArgs.registerName, 'delete', cm.getRange(curStart, curEnd),
+            operatorArgs.linewise);
+        cm.replaceRange('', curStart, curEnd);
+        if (operatorArgs.linewise) {
+          cm.setCursor(motions.moveToFirstNonWhiteSpaceCharacter(cm));
+        } else {
+          cm.setCursor(curStart);
+        }
+      },
+      indent: function(cm, operatorArgs, vim, curStart, curEnd) {
+        var startLine = curStart.line;
+        var endLine = curEnd.line;
+        // In visual mode, n> shifts the selection right n times, instead of
+        // shifting n lines right once.
+        var repeat = (vim.visualMode) ? operatorArgs.repeat : 1;
+        if (operatorArgs.linewise) {
+          // The only way to delete a newline is to delete until the start of
+          // the next line, so in linewise mode evalInput will include the next
+          // line. We don't want this in indent, so we go back a line.
+          endLine--;
+        }
+        for (var i = startLine; i <= endLine; i++) {
+          for (var j = 0; j < repeat; j++) {
+            cm.indentLine(i, operatorArgs.indentRight);
+          }
+        }
+        cm.setCursor(curStart);
+        cm.setCursor(motions.moveToFirstNonWhiteSpaceCharacter(cm));
+      },
+      swapcase: function(cm, operatorArgs, _vim, curStart, curEnd, curOriginal) {
+        var toSwap = cm.getRange(curStart, curEnd);
+        var swapped = '';
+        for (var i = 0; i < toSwap.length; i++) {
+          var character = toSwap.charAt(i);
+          swapped += isUpperCase(character) ? character.toLowerCase() :
+              character.toUpperCase();
+        }
+        cm.replaceRange(swapped, curStart, curEnd);
+        if (!operatorArgs.shouldMoveCursor) {
+          cm.setCursor(curOriginal);
+        }
+      },
+      yank: function(cm, operatorArgs, _vim, curStart, curEnd, curOriginal) {
+        vimGlobalState.registerController.pushText(
+            operatorArgs.registerName, 'yank',
+            cm.getRange(curStart, curEnd), operatorArgs.linewise);
+        cm.setCursor(curOriginal);
+      }
+    };
+
+    var actions = {
+      jumpListWalk: function(cm, actionArgs, vim) {
+        if (vim.visualMode) {
+          return;
+        }
+        var repeat = actionArgs.repeat;
+        var forward = actionArgs.forward;
+        var jumpList = vimGlobalState.jumpList;
+
+        var mark = jumpList.move(cm, forward ? repeat : -repeat);
+        var markPos = mark ? mark.find() : undefined;
+        markPos = markPos ? markPos : cm.getCursor();
+        cm.setCursor(markPos);
+      },
+      scroll: function(cm, actionArgs, vim) {
+        if (vim.visualMode) {
+          return;
+        }
+        var repeat = actionArgs.repeat || 1;
+        var lineHeight = cm.defaultTextHeight();
+        var top = cm.getScrollInfo().top;
+        var delta = lineHeight * repeat;
+        var newPos = actionArgs.forward ? top + delta : top - delta;
+        var cursor = copyCursor(cm.getCursor());
+        var cursorCoords = cm.charCoords(cursor, 'local');
+        if (actionArgs.forward) {
+          if (newPos > cursorCoords.top) {
+             cursor.line += (newPos - cursorCoords.top) / lineHeight;
+             cursor.line = Math.ceil(cursor.line);
+             cm.setCursor(cursor);
+             cursorCoords = cm.charCoords(cursor, 'local');
+             cm.scrollTo(null, cursorCoords.top);
+          } else {
+             // Cursor stays within bounds.  Just reposition the scroll window.
+             cm.scrollTo(null, newPos);
+          }
+        } else {
+          var newBottom = newPos + cm.getScrollInfo().clientHeight;
+          if (newBottom < cursorCoords.bottom) {
+             cursor.line -= (cursorCoords.bottom - newBottom) / lineHeight;
+             cursor.line = Math.floor(cursor.line);
+             cm.setCursor(cursor);
+             cursorCoords = cm.charCoords(cursor, 'local');
+             cm.scrollTo(
+                 null, cursorCoords.bottom - cm.getScrollInfo().clientHeight);
+          } else {
+             // Cursor stays within bounds.  Just reposition the scroll window.
+             cm.scrollTo(null, newPos);
+          }
+        }
+      },
+      scrollToCursor: function(cm, actionArgs) {
+        var lineNum = cm.getCursor().line;
+        var charCoords = cm.charCoords(Pos(lineNum, 0), 'local');
+        var height = cm.getScrollInfo().clientHeight;
+        var y = charCoords.top;
+        var lineHeight = charCoords.bottom - y;
+        switch (actionArgs.position) {
+          case 'center': y = y - (height / 2) + lineHeight;
+            break;
+          case 'bottom': y = y - height + lineHeight*1.4;
+            break;
+          case 'top': y = y + lineHeight*0.4;
+            break;
+        }
+        cm.scrollTo(null, y);
+      },
+      replayMacro: function(cm, actionArgs, vim) {
+        var registerName = actionArgs.selectedCharacter;
+        var repeat = actionArgs.repeat;
+        var macroModeState = vimGlobalState.macroModeState;
+        if (registerName == '@') {
+          registerName = macroModeState.latestRegister;
+        }
+        while(repeat--){
+          executeMacroRegister(cm, vim, macroModeState, registerName);
+        }
+      },
+      enterMacroRecordMode: function(cm, actionArgs) {
+        var macroModeState = vimGlobalState.macroModeState;
+        var registerName = actionArgs.selectedCharacter;
+        macroModeState.enterMacroRecordMode(cm, registerName);
+      },
+      enterInsertMode: function(cm, actionArgs, vim) {
+        if (cm.getOption('readOnly')) { return; }
+        vim.insertMode = true;
+        vim.insertModeRepeat = actionArgs && actionArgs.repeat || 1;
+        var insertAt = (actionArgs) ? actionArgs.insertAt : null;
+        if (insertAt == 'eol') {
+          var cursor = cm.getCursor();
+          cursor = Pos(cursor.line, lineLength(cm, cursor.line));
+          cm.setCursor(cursor);
+        } else if (insertAt == 'charAfter') {
+          cm.setCursor(offsetCursor(cm.getCursor(), 0, 1));
+        } else if (insertAt == 'firstNonBlank') {
+          cm.setCursor(motions.moveToFirstNonWhiteSpaceCharacter(cm));
+        }
+        cm.setOption('keyMap', 'vim-insert');
+        cm.setOption('disableInput', false);
+        if (actionArgs && actionArgs.replace) {
+          // Handle Replace-mode as a special case of insert mode.
+          cm.toggleOverwrite(true);
+          cm.setOption('keyMap', 'vim-replace');
+          CodeMirror.signal(cm, "vim-mode-change", {mode: "replace"});
+        } else {
+          cm.setOption('keyMap', 'vim-insert');
+          CodeMirror.signal(cm, "vim-mode-change", {mode: "insert"});
+        }
+        if (!vimGlobalState.macroModeState.isPlaying) {
+          // Only record if not replaying.
+          cm.on('change', onChange);
+          cm.on('cursorActivity', onCursorActivity);
+          CodeMirror.on(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown);
+        }
+      },
+      toggleVisualMode: function(cm, actionArgs, vim) {
+        var repeat = actionArgs.repeat;
+        var curStart = cm.getCursor();
+        var curEnd;
+        // TODO: The repeat should actually select number of characters/lines
+        //     equal to the repeat times the size of the previous visual
+        //     operation.
+        if (!vim.visualMode) {
+          cm.on('mousedown', exitVisualMode);
+          vim.visualMode = true;
+          vim.visualLine = !!actionArgs.linewise;
+          if (vim.visualLine) {
+            curStart.ch = 0;
+            curEnd = clipCursorToContent(
+              cm, Pos(curStart.line + repeat - 1, lineLength(cm, curStart.line)),
+              true /** includeLineBreak */);
+          } else {
+            curEnd = clipCursorToContent(
+              cm, Pos(curStart.line, curStart.ch + repeat),
+              true /** includeLineBreak */);
+          }
+          // Make the initial selection.
+          if (!actionArgs.repeatIsExplicit && !vim.visualLine) {
+            // This is a strange case. Here the implicit repeat is 1. The
+            // following commands lets the cursor hover over the 1 character
+            // selection.
+            cm.setCursor(curEnd);
+            cm.setSelection(curEnd, curStart);
+          } else {
+            cm.setSelection(curStart, curEnd);
+          }
+          CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: vim.visualLine ? "linewise" : ""});
+        } else {
+          curStart = cm.getCursor('anchor');
+          curEnd = cm.getCursor('head');
+          if (!vim.visualLine && actionArgs.linewise) {
+            // Shift-V pressed in characterwise visual mode. Switch to linewise
+            // visual mode instead of exiting visual mode.
+            vim.visualLine = true;
+            curStart.ch = cursorIsBefore(curStart, curEnd) ? 0 :
+                lineLength(cm, curStart.line);
+            curEnd.ch = cursorIsBefore(curStart, curEnd) ?
+                lineLength(cm, curEnd.line) : 0;
+            cm.setSelection(curStart, curEnd);
+            CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: "linewise"});
+          } else if (vim.visualLine && !actionArgs.linewise) {
+            // v pressed in linewise visual mode. Switch to characterwise visual
+            // mode instead of exiting visual mode.
+            vim.visualLine = false;
+            CodeMirror.signal(cm, "vim-mode-change", {mode: "visual"});
+          } else {
+            exitVisualMode(cm);
+          }
+        }
+        updateMark(cm, vim, '<', cursorIsBefore(curStart, curEnd) ? curStart
+            : curEnd);
+        updateMark(cm, vim, '>', cursorIsBefore(curStart, curEnd) ? curEnd
+            : curStart);
+      },
+      reselectLastSelection: function(cm, _actionArgs, vim) {
+        if (vim.lastSelection) {
+          var lastSelection = vim.lastSelection;
+          cm.setSelection(lastSelection.curStart, lastSelection.curEnd);
+          if (lastSelection.visualLine) {
+            vim.visualMode = true;
+            vim.visualLine = true;
+          }
+          else {
+            vim.visualMode = true;
+            vim.visualLine = false;
+          }
+          CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: vim.visualLine ? "linewise" : ""});
+        }
+      },
+      joinLines: function(cm, actionArgs, vim) {
+        var curStart, curEnd;
+        if (vim.visualMode) {
+          curStart = cm.getCursor('anchor');
+          curEnd = cm.getCursor('head');
+          curEnd.ch = lineLength(cm, curEnd.line) - 1;
+        } else {
+          // Repeat is the number of lines to join. Minimum 2 lines.
+          var repeat = Math.max(actionArgs.repeat, 2);
+          curStart = cm.getCursor();
+          curEnd = clipCursorToContent(cm, Pos(curStart.line + repeat - 1,
+                                               Infinity));
+        }
+        var finalCh = 0;
+        cm.operation(function() {
+          for (var i = curStart.line; i < curEnd.line; i++) {
+            finalCh = lineLength(cm, curStart.line);
+            var tmp = Pos(curStart.line + 1,
+                          lineLength(cm, curStart.line + 1));
+            var text = cm.getRange(curStart, tmp);
+            text = text.replace(/\n\s*/g, ' ');
+            cm.replaceRange(text, curStart, tmp);
+          }
+          var curFinalPos = Pos(curStart.line, finalCh);
+          cm.setCursor(curFinalPos);
+        });
+      },
+      newLineAndEnterInsertMode: function(cm, actionArgs, vim) {
+        vim.insertMode = true;
+        var insertAt = copyCursor(cm.getCursor());
+        if (insertAt.line === cm.firstLine() && !actionArgs.after) {
+          // Special case for inserting newline before start of document.
+          cm.replaceRange('\n', Pos(cm.firstLine(), 0));
+          cm.setCursor(cm.firstLine(), 0);
+        } else {
+          insertAt.line = (actionArgs.after) ? insertAt.line :
+              insertAt.line - 1;
+          insertAt.ch = lineLength(cm, insertAt.line);
+          cm.setCursor(insertAt);
+          var newlineFn = CodeMirror.commands.newlineAndIndentContinueComment ||
+              CodeMirror.commands.newlineAndIndent;
+          newlineFn(cm);
+        }
+        this.enterInsertMode(cm, { repeat: actionArgs.repeat }, vim);
+      },
+      paste: function(cm, actionArgs) {
+        var cur = copyCursor(cm.getCursor());
+        var register = vimGlobalState.registerController.getRegister(
+            actionArgs.registerName);
+        var text = register.toString();
+        if (!text) {
+          return;
+        }
+        if (actionArgs.repeat > 1) {
+          var text = Array(actionArgs.repeat + 1).join(text);
+        }
+        var linewise = register.linewise;
+        if (linewise) {
+          if (actionArgs.after) {
+            // Move the newline at the end to the start instead, and paste just
+            // before the newline character of the line we are on right now.
+            text = '\n' + text.slice(0, text.length - 1);
+            cur.ch = lineLength(cm, cur.line);
+          } else {
+            cur.ch = 0;
+          }
+        } else {
+          cur.ch += actionArgs.after ? 1 : 0;
+        }
+        cm.replaceRange(text, cur);
+        // Now fine tune the cursor to where we want it.
+        var curPosFinal;
+        var idx;
+        if (linewise && actionArgs.after) {
+          curPosFinal = Pos(
+            cur.line + 1,
+            findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line + 1)));
+        } else if (linewise && !actionArgs.after) {
+          curPosFinal = Pos(
+            cur.line,
+            findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line)));
+        } else if (!linewise && actionArgs.after) {
+          idx = cm.indexFromPos(cur);
+          curPosFinal = cm.posFromIndex(idx + text.length - 1);
+        } else {
+          idx = cm.indexFromPos(cur);
+          curPosFinal = cm.posFromIndex(idx + text.length);
+        }
+        cm.setCursor(curPosFinal);
+      },
+      undo: function(cm, actionArgs) {
+        cm.operation(function() {
+          repeatFn(cm, CodeMirror.commands.undo, actionArgs.repeat)();
+          cm.setCursor(cm.getCursor('anchor'));
+        });
+      },
+      redo: function(cm, actionArgs) {
+        repeatFn(cm, CodeMirror.commands.redo, actionArgs.repeat)();
+      },
+      setRegister: function(_cm, actionArgs, vim) {
+        vim.inputState.registerName = actionArgs.selectedCharacter;
+      },
+      setMark: function(cm, actionArgs, vim) {
+        var markName = actionArgs.selectedCharacter;
+        updateMark(cm, vim, markName, cm.getCursor());
+      },
+      replace: function(cm, actionArgs, vim) {
+        var replaceWith = actionArgs.selectedCharacter;
+        var curStart = cm.getCursor();
+        var replaceTo;
+        var curEnd;
+        if (vim.visualMode){
+          curStart=cm.getCursor('start');
+          curEnd=cm.getCursor('end');
+          // workaround to catch the character under the cursor
+          //  existing workaround doesn't cover actions
+          curEnd=cm.clipPos(Pos(curEnd.line, curEnd.ch+1));
+        }else{
+          var line = cm.getLine(curStart.line);
+          replaceTo = curStart.ch + actionArgs.repeat;
+          if (replaceTo > line.length) {
+            replaceTo=line.length;
+          }
+          curEnd = Pos(curStart.line, replaceTo);
+        }
+        if (replaceWith=='\n'){
+          if (!vim.visualMode) cm.replaceRange('', curStart, curEnd);
+          // special case, where vim help says to replace by just one line-break
+          (CodeMirror.commands.newlineAndIndentContinueComment || CodeMirror.commands.newlineAndIndent)(cm);
+        }else {
+          var replaceWithStr=cm.getRange(curStart, curEnd);
+          //replace all characters in range by selected, but keep linebreaks
+          replaceWithStr=replaceWithStr.replace(/[^\n]/g,replaceWith);
+          cm.replaceRange(replaceWithStr, curStart, curEnd);
+          if (vim.visualMode){
+            cm.setCursor(curStart);
+            exitVisualMode(cm);
+          }else{
+            cm.setCursor(offsetCursor(curEnd, 0, -1));
+          }
+        }
+      },
+      incrementNumberToken: function(cm, actionArgs) {
+        var cur = cm.getCursor();
+        var lineStr = cm.getLine(cur.line);
+        var re = /-?\d+/g;
+        var match;
+        var start;
+        var end;
+        var numberStr;
+        var token;
+        while ((match = re.exec(lineStr)) !== null) {
+          token = match[0];
+          start = match.index;
+          end = start + token.length;
+          if (cur.ch < end)break;
+        }
+        if (!actionArgs.backtrack && (end <= cur.ch))return;
+        if (token) {
+          var increment = actionArgs.increase ? 1 : -1;
+          var number = parseInt(token) + (increment * actionArgs.repeat);
+          var from = Pos(cur.line, start);
+          var to = Pos(cur.line, end);
+          numberStr = number.toString();
+          cm.replaceRange(numberStr, from, to);
+        } else {
+          return;
+        }
+        cm.setCursor(Pos(cur.line, start + numberStr.length - 1));
+      },
+      repeatLastEdit: function(cm, actionArgs, vim) {
+        var lastEditInputState = vim.lastEditInputState;
+        if (!lastEditInputState) { return; }
+        var repeat = actionArgs.repeat;
+        if (repeat && actionArgs.repeatIsExplicit) {
+          vim.lastEditInputState.repeatOverride = repeat;
+        } else {
+          repeat = vim.lastEditInputState.repeatOverride || repeat;
+        }
+        repeatLastEdit(cm, vim, repeat, false /** repeatForInsert */);
+      }
+    };
+
+    /*
+     * Below are miscellaneous utility functions used by vim.js
+     */
+
+    /**
+     * Clips cursor to ensure that line is within the buffer's range
+     * If includeLineBreak is true, then allow cur.ch == lineLength.
+     */
+    function clipCursorToContent(cm, cur, includeLineBreak) {
+      var line = Math.min(Math.max(cm.firstLine(), cur.line), cm.lastLine() );
+      var maxCh = lineLength(cm, line) - 1;
+      maxCh = (includeLineBreak) ? maxCh + 1 : maxCh;
+      var ch = Math.min(Math.max(0, cur.ch), maxCh);
+      return Pos(line, ch);
+    }
+    function copyArgs(args) {
+      var ret = {};
+      for (var prop in args) {
+        if (args.hasOwnProperty(prop)) {
+          ret[prop] = args[prop];
+        }
+      }
+      return ret;
+    }
+    function offsetCursor(cur, offsetLine, offsetCh) {
+      return Pos(cur.line + offsetLine, cur.ch + offsetCh);
+    }
+    function matchKeysPartial(pressed, mapped) {
+      for (var i = 0; i < pressed.length; i++) {
+        // 'character' means any character. For mark, register commads, etc.
+        if (pressed[i] != mapped[i] && mapped[i] != 'character') {
+          return false;
+        }
+      }
+      return true;
+    }
+    function repeatFn(cm, fn, repeat) {
+      return function() {
+        for (var i = 0; i < repeat; i++) {
+          fn(cm);
+        }
+      };
+    }
+    function copyCursor(cur) {
+      return Pos(cur.line, cur.ch);
+    }
+    function cursorEqual(cur1, cur2) {
+      return cur1.ch == cur2.ch && cur1.line == cur2.line;
+    }
+    function cursorIsBefore(cur1, cur2) {
+      if (cur1.line < cur2.line) {
+        return true;
+      }
+      if (cur1.line == cur2.line && cur1.ch < cur2.ch) {
+        return true;
+      }
+      return false;
+    }
+    function cusrorIsBetween(cur1, cur2, cur3) {
+      // returns true if cur2 is between cur1 and cur3.
+      var cur1before2 = cursorIsBefore(cur1, cur2);
+      var cur2before3 = cursorIsBefore(cur2, cur3);
+      return cur1before2 && cur2before3;
+    }
+    function lineLength(cm, lineNum) {
+      return cm.getLine(lineNum).length;
+    }
+    function reverse(s){
+      return s.split('').reverse().join('');
+    }
+    function trim(s) {
+      if (s.trim) {
+        return s.trim();
+      }
+      return s.replace(/^\s+|\s+$/g, '');
+    }
+    function escapeRegex(s) {
+      return s.replace(/([.?*+$\[\]\/\\(){}|\-])/g, '\\$1');
+    }
+
+    function exitVisualMode(cm) {
+      cm.off('mousedown', exitVisualMode);
+      var vim = cm.state.vim;
+      // can't use selection state here because yank has already reset its cursor
+      vim.lastSelection = {'curStart': vim.marks['<'].find(),
+        'curEnd': vim.marks['>'].find(), 'visualMode': vim.visualMode,
+        'visualLine': vim.visualLine};
+      vim.visualMode = false;
+      vim.visualLine = false;
+      var selectionStart = cm.getCursor('anchor');
+      var selectionEnd = cm.getCursor('head');
+      if (!cursorEqual(selectionStart, selectionEnd)) {
+        // Clear the selection and set the cursor only if the selection has not
+        // already been cleared. Otherwise we risk moving the cursor somewhere
+        // it's not supposed to be.
+        cm.setCursor(clipCursorToContent(cm, selectionEnd));
+      }
+      CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
+    }
+
+    // Remove any trailing newlines from the selection. For
+    // example, with the caret at the start of the last word on the line,
+    // 'dw' should word, but not the newline, while 'w' should advance the
+    // caret to the first character of the next line.
+    function clipToLine(cm, curStart, curEnd) {
+      var selection = cm.getRange(curStart, curEnd);
+      // Only clip if the selection ends with trailing newline + whitespace
+      if (/\n\s*$/.test(selection)) {
+        var lines = selection.split('\n');
+        // We know this is all whitepsace.
+        lines.pop();
+
+        // Cases:
+        // 1. Last word is an empty line - do not clip the trailing '\n'
+        // 2. Last word is not an empty line - clip the trailing '\n'
+        var line;
+        // Find the line containing the last word, and clip all whitespace up
+        // to it.
+        for (var line = lines.pop(); lines.length > 0 && line && isWhiteSpaceString(line); line = lines.pop()) {
+          curEnd.line--;
+          curEnd.ch = 0;
+        }
+        // If the last word is not an empty line, clip an additional newline
+        if (line) {
+          curEnd.line--;
+          curEnd.ch = lineLength(cm, curEnd.line);
+        } else {
+          curEnd.ch = 0;
+        }
+      }
+    }
+
+    // Expand the selection to line ends.
+    function expandSelectionToLine(_cm, curStart, curEnd) {
+      curStart.ch = 0;
+      curEnd.ch = 0;
+      curEnd.line++;
+    }
+
+    function findFirstNonWhiteSpaceCharacter(text) {
+      if (!text) {
+        return 0;
+      }
+      var firstNonWS = text.search(/\S/);
+      return firstNonWS == -1 ? text.length : firstNonWS;
+    }
+
+    function expandWordUnderCursor(cm, inclusive, _forward, bigWord, noSymbol) {
+      var cur = cm.getCursor();
+      var line = cm.getLine(cur.line);
+      var idx = cur.ch;
+
+      // Seek to first word or non-whitespace character, depending on if
+      // noSymbol is true.
+      var textAfterIdx = line.substring(idx);
+      var firstMatchedChar;
+      if (noSymbol) {
+        firstMatchedChar = textAfterIdx.search(/\w/);
+      } else {
+        firstMatchedChar = textAfterIdx.search(/\S/);
+      }
+      if (firstMatchedChar == -1) {
+        return null;
+      }
+      idx += firstMatchedChar;
+      textAfterIdx = line.substring(idx);
+      var textBeforeIdx = line.substring(0, idx);
+
+      var matchRegex;
+      // Greedy matchers for the "word" we are trying to expand.
+      if (bigWord) {
+        matchRegex = /^\S+/;
+      } else {
+        if ((/\w/).test(line.charAt(idx))) {
+          matchRegex = /^\w+/;
+        } else {
+          matchRegex = /^[^\w\s]+/;
+        }
+      }
+
+      var wordAfterRegex = matchRegex.exec(textAfterIdx);
+      var wordStart = idx;
+      var wordEnd = idx + wordAfterRegex[0].length;
+      // TODO: Find a better way to do this. It will be slow on very long lines.
+      var revTextBeforeIdx = reverse(textBeforeIdx);
+      var wordBeforeRegex = matchRegex.exec(revTextBeforeIdx);
+      if (wordBeforeRegex) {
+        wordStart -= wordBeforeRegex[0].length;
+      }
+
+      if (inclusive) {
+        // If present, trim all whitespace after word.
+        // Otherwise, trim all whitespace before word.
+        var textAfterWordEnd = line.substring(wordEnd);
+        var whitespacesAfterWord = textAfterWordEnd.match(/^\s*/)[0].length;
+        if (whitespacesAfterWord > 0) {
+          wordEnd += whitespacesAfterWord;
+        } else {
+          var revTrim = revTextBeforeIdx.length - wordStart;
+          var textBeforeWordStart = revTextBeforeIdx.substring(revTrim);
+          var whitespacesBeforeWord = textBeforeWordStart.match(/^\s*/)[0].length;
+          wordStart -= whitespacesBeforeWord;
+        }
+      }
+
+      return { start: Pos(cur.line, wordStart),
+               end: Pos(cur.line, wordEnd) };
+    }
+
+    function recordJumpPosition(cm, oldCur, newCur) {
+      if (!cursorEqual(oldCur, newCur)) {
+        vimGlobalState.jumpList.add(cm, oldCur, newCur);
+      }
+    }
+
+    function recordLastCharacterSearch(increment, args) {
+        vimGlobalState.lastChararacterSearch.increment = increment;
+        vimGlobalState.lastChararacterSearch.forward = args.forward;
+        vimGlobalState.lastChararacterSearch.selectedCharacter = args.selectedCharacter;
+    }
+
+    var symbolToMode = {
+        '(': 'bracket', ')': 'bracket', '{': 'bracket', '}': 'bracket',
+        '[': 'section', ']': 'section',
+        '*': 'comment', '/': 'comment',
+        'm': 'method', 'M': 'method',
+        '#': 'preprocess'
+    };
+    var findSymbolModes = {
+      bracket: {
+        isComplete: function(state) {
+          if (state.nextCh === state.symb) {
+            state.depth++;
+            if (state.depth >= 1)return true;
+          } else if (state.nextCh === state.reverseSymb) {
+            state.depth--;
+          }
+          return false;
+        }
+      },
+      section: {
+        init: function(state) {
+          state.curMoveThrough = true;
+          state.symb = (state.forward ? ']' : '[') === state.symb ? '{' : '}';
+        },
+        isComplete: function(state) {
+          return state.index === 0 && state.nextCh === state.symb;
+        }
+      },
+      comment: {
+        isComplete: function(state) {
+          var found = state.lastCh === '*' && state.nextCh === '/';
+          state.lastCh = state.nextCh;
+          return found;
+        }
+      },
+      // TODO: The original Vim implementation only operates on level 1 and 2.
+      // The current implementation doesn't check for code block level and
+      // therefore it operates on any levels.
+      method: {
+        init: function(state) {
+          state.symb = (state.symb === 'm' ? '{' : '}');
+          state.reverseSymb = state.symb === '{' ? '}' : '{';
+        },
+        isComplete: function(state) {
+          if (state.nextCh === state.symb)return true;
+          return false;
+        }
+      },
+      preprocess: {
+        init: function(state) {
+          state.index = 0;
+        },
+        isComplete: function(state) {
+          if (state.nextCh === '#') {
+            var token = state.lineText.match(/#(\w+)/)[1];
+            if (token === 'endif') {
+              if (state.forward && state.depth === 0) {
+                return true;
+              }
+              state.depth++;
+            } else if (token === 'if') {
+              if (!state.forward && state.depth === 0) {
+                return true;
+              }
+              state.depth--;
+            }
+            if (token === 'else' && state.depth === 0)return true;
+          }
+          return false;
+        }
+      }
+    };
+    function findSymbol(cm, repeat, forward, symb) {
+      var cur = copyCursor(cm.getCursor());
+      var increment = forward ? 1 : -1;
+      var endLine = forward ? cm.lineCount() : -1;
+      var curCh = cur.ch;
+      var line = cur.line;
+      var lineText = cm.getLine(line);
+      var state = {
+        lineText: lineText,
+        nextCh: lineText.charAt(curCh),
+        lastCh: null,
+        index: curCh,
+        symb: symb,
+        reverseSymb: (forward ?  { ')': '(', '}': '{' } : { '(': ')', '{': '}' })[symb],
+        forward: forward,
+        depth: 0,
+        curMoveThrough: false
+      };
+      var mode = symbolToMode[symb];
+      if (!mode)return cur;
+      var init = findSymbolModes[mode].init;
+      var isComplete = findSymbolModes[mode].isComplete;
+      if (init) { init(state); }
+      while (line !== endLine && repeat) {
+        state.index += increment;
+        state.nextCh = state.lineText.charAt(state.index);
+        if (!state.nextCh) {
+          line += increment;
+          state.lineText = cm.getLine(line) || '';
+          if (increment > 0) {
+            state.index = 0;
+          } else {
+            var lineLen = state.lineText.length;
+            state.index = (lineLen > 0) ? (lineLen-1) : 0;
+          }
+          state.nextCh = state.lineText.charAt(state.index);
+        }
+        if (isComplete(state)) {
+          cur.line = line;
+          cur.ch = state.index;
+          repeat--;
+        }
+      }
+      if (state.nextCh || state.curMoveThrough) {
+        return Pos(line, state.index);
+      }
+      return cur;
+    }
+
+    /*
+     * Returns the boundaries of the next word. If the cursor in the middle of
+     * the word, then returns the boundaries of the current word, starting at
+     * the cursor. If the cursor is at the start/end of a word, and we are going
+     * forward/backward, respectively, find the boundaries of the next word.
+     *
+     * @param {CodeMirror} cm CodeMirror object.
+     * @param {Cursor} cur The cursor position.
+     * @param {boolean} forward True to search forward. False to search
+     *     backward.
+     * @param {boolean} bigWord True if punctuation count as part of the word.
+     *     False if only [a-zA-Z0-9] characters count as part of the word.
+     * @param {boolean} emptyLineIsWord True if empty lines should be treated
+     *     as words.
+     * @return {Object{from:number, to:number, line: number}} The boundaries of
+     *     the word, or null if there are no more words.
+     */
+    function findWord(cm, cur, forward, bigWord, emptyLineIsWord) {
+      var lineNum = cur.line;
+      var pos = cur.ch;
+      var line = cm.getLine(lineNum);
+      var dir = forward ? 1 : -1;
+      var regexps = bigWord ? bigWordRegexp : wordRegexp;
+
+      if (emptyLineIsWord && line == '') {
+        lineNum += dir;
+        line = cm.getLine(lineNum);
+        if (!isLine(cm, lineNum)) {
+          return null;
+        }
+        pos = (forward) ? 0 : line.length;
+      }
+
+      while (true) {
+        if (emptyLineIsWord && line == '') {
+          return { from: 0, to: 0, line: lineNum };
+        }
+        var stop = (dir > 0) ? line.length : -1;
+        var wordStart = stop, wordEnd = stop;
+        // Find bounds of next word.
+        while (pos != stop) {
+          var foundWord = false;
+          for (var i = 0; i < regexps.length && !foundWord; ++i) {
+            if (regexps[i].test(line.charAt(pos))) {
+              wordStart = pos;
+              // Advance to end of word.
+              while (pos != stop && regexps[i].test(line.charAt(pos))) {
+                pos += dir;
+              }
+              wordEnd = pos;
+              foundWord = wordStart != wordEnd;
+              if (wordStart == cur.ch && lineNum == cur.line &&
+                  wordEnd == wordStart + dir) {
+                // We started at the end of a word. Find the next one.
+                continue;
+              } else {
+                return {
+                  from: Math.min(wordStart, wordEnd + 1),
+                  to: Math.max(wordStart, wordEnd),
+                  line: lineNum };
+              }
+            }
+          }
+          if (!foundWord) {
+            pos += dir;
+          }
+        }
+        // Advance to next/prev line.
+        lineNum += dir;
+        if (!isLine(cm, lineNum)) {
+          return null;
+        }
+        line = cm.getLine(lineNum);
+        pos = (dir > 0) ? 0 : line.length;
+      }
+      // Should never get here.
+      throw new Error('The impossible happened.');
+    }
+
+    /**
+     * @param {CodeMirror} cm CodeMirror object.
+     * @param {int} repeat Number of words to move past.
+     * @param {boolean} forward True to search forward. False to search
+     *     backward.
+     * @param {boolean} wordEnd True to move to end of word. False to move to
+     *     beginning of word.
+     * @param {boolean} bigWord True if punctuation count as part of the word.
+     *     False if only alphabet characters count as part of the word.
+     * @return {Cursor} The position the cursor should move to.
+     */
+    function moveToWord(cm, repeat, forward, wordEnd, bigWord) {
+      var cur = cm.getCursor();
+      var curStart = copyCursor(cur);
+      var words = [];
+      if (forward && !wordEnd || !forward && wordEnd) {
+        repeat++;
+      }
+      // For 'e', empty lines are not considered words, go figure.
+      var emptyLineIsWord = !(forward && wordEnd);
+      for (var i = 0; i < repeat; i++) {
+        var word = findWord(cm, cur, forward, bigWord, emptyLineIsWord);
+        if (!word) {
+          var eodCh = lineLength(cm, cm.lastLine());
+          words.push(forward
+              ? {line: cm.lastLine(), from: eodCh, to: eodCh}
+              : {line: 0, from: 0, to: 0});
+          break;
+        }
+        words.push(word);
+        cur = Pos(word.line, forward ? (word.to - 1) : word.from);
+      }
+      var shortCircuit = words.length != repeat;
+      var firstWord = words[0];
+      var lastWord = words.pop();
+      if (forward && !wordEnd) {
+        // w
+        if (!shortCircuit && (firstWord.from != curStart.ch || firstWord.line != curStart.line)) {
+          // We did not start in the middle of a word. Discard the extra word at the end.
+          lastWord = words.pop();
+        }
+        return Pos(lastWord.line, lastWord.from);
+      } else if (forward && wordEnd) {
+        return Pos(lastWord.line, lastWord.to - 1);
+      } else if (!forward && wordEnd) {
+        // ge
+        if (!shortCircuit && (firstWord.to != curStart.ch || firstWord.line != curStart.line)) {
+          // We did not start in the middle of a word. Discard the extra word at the end.
+          lastWord = words.pop();
+        }
+        return Pos(lastWord.line, lastWord.to);
+      } else {
+        // b
+        return Pos(lastWord.line, lastWord.from);
+      }
+    }
+
+    function moveToCharacter(cm, repeat, forward, character) {
+      var cur = cm.getCursor();
+      var start = cur.ch;
+      var idx;
+      for (var i = 0; i < repeat; i ++) {
+        var line = cm.getLine(cur.line);
+        idx = charIdxInLine(start, line, character, forward, true);
+        if (idx == -1) {
+          return null;
+        }
+        start = idx;
+      }
+      return Pos(cm.getCursor().line, idx);
+    }
+
+    function moveToColumn(cm, repeat) {
+      // repeat is always >= 1, so repeat - 1 always corresponds
+      // to the column we want to go to.
+      var line = cm.getCursor().line;
+      return clipCursorToContent(cm, Pos(line, repeat - 1));
+    }
+
+    function updateMark(cm, vim, markName, pos) {
+      if (!inArray(markName, validMarks)) {
+        return;
+      }
+      if (vim.marks[markName]) {
+        vim.marks[markName].clear();
+      }
+      vim.marks[markName] = cm.setBookmark(pos);
+    }
+
+    function charIdxInLine(start, line, character, forward, includeChar) {
+      // Search for char in line.
+      // motion_options: {forward, includeChar}
+      // If includeChar = true, include it too.
+      // If forward = true, search forward, else search backwards.
+      // If char is not found on this line, do nothing
+      var idx;
+      if (forward) {
+        idx = line.indexOf(character, start + 1);
+        if (idx != -1 && !includeChar) {
+          idx -= 1;
+        }
+      } else {
+        idx = line.lastIndexOf(character, start - 1);
+        if (idx != -1 && !includeChar) {
+          idx += 1;
+        }
+      }
+      return idx;
+    }
+
+    function getContextLevel(ctx) {
+      return (ctx === 'string' || ctx === 'comment') ? 1 : 0;
+    }
+
+    function findMatchedSymbol(cm, cur, symb) {
+      var line = cur.line;
+      var ch = cur.ch;
+      symb = symb ? symb : cm.getLine(line).charAt(ch);
+
+      var symbContext = cm.getTokenAt(Pos(line, ch + 1)).type;
+      var symbCtxLevel = getContextLevel(symbContext);
+
+      var reverseSymb = ({
+        '(': ')', ')': '(',
+        '[': ']', ']': '[',
+        '{': '}', '}': '{'})[symb];
+
+      // Couldn't find a matching symbol, abort
+      if (!reverseSymb) {
+        return cur;
+      }
+
+      // set our increment to move forward (+1) or backwards (-1)
+      // depending on which bracket we're matching
+      var increment = ({'(': 1, '{': 1, '[': 1})[symb] || -1;
+      var endLine = increment === 1 ? cm.lineCount() : -1;
+      var depth = 1, nextCh = symb, index = ch, lineText = cm.getLine(line);
+      // Simple search for closing paren--just count openings and closings till
+      // we find our match
+      // TODO: use info from CodeMirror to ignore closing brackets in comments
+      // and quotes, etc.
+      while (line !== endLine && depth > 0) {
+        index += increment;
+        nextCh = lineText.charAt(index);
+        if (!nextCh) {
+          line += increment;
+          lineText = cm.getLine(line) || '';
+          if (increment > 0) {
+            index = 0;
+          } else {
+            var lineLen = lineText.length;
+            index = (lineLen > 0) ? (lineLen-1) : 0;
+          }
+          nextCh = lineText.charAt(index);
+        }
+        var revSymbContext = cm.getTokenAt(Pos(line, index + 1)).type;
+        var revSymbCtxLevel = getContextLevel(revSymbContext);
+        if (symbCtxLevel >= revSymbCtxLevel) {
+          if (nextCh === symb) {
+            depth++;
+          } else if (nextCh === reverseSymb) {
+            depth--;
+          }
+        }
+      }
+
+      if (nextCh) {
+        return Pos(line, index);
+      }
+      return cur;
+    }
+
+    // TODO: perhaps this finagling of start and end positions belonds
+    // in codmirror/replaceRange?
+    function selectCompanionObject(cm, revSymb, inclusive) {
+      var cur = copyCursor(cm.getCursor());
+      var end = findMatchedSymbol(cm, cur, revSymb);
+      var start = findMatchedSymbol(cm, end);
+
+      if ((start.line == end.line && start.ch > end.ch)
+          || (start.line > end.line)) {
+        var tmp = start;
+        start = end;
+        end = tmp;
+      }
+
+      if (inclusive) {
+        end.ch += 1;
+      } else {
+        start.ch += 1;
+      }
+
+      return { start: start, end: end };
+    }
+
+    // Takes in a symbol and a cursor and tries to simulate text objects that
+    // have identical opening and closing symbols
+    // TODO support across multiple lines
+    function findBeginningAndEnd(cm, symb, inclusive) {
+      var cur = copyCursor(cm.getCursor());
+      var line = cm.getLine(cur.line);
+      var chars = line.split('');
+      var start, end, i, len;
+      var firstIndex = chars.indexOf(symb);
+
+      // the decision tree is to always look backwards for the beginning first,
+      // but if the cursor is in front of the first instance of the symb,
+      // then move the cursor forward
+      if (cur.ch < firstIndex) {
+        cur.ch = firstIndex;
+        // Why is this line even here???
+        // cm.setCursor(cur.line, firstIndex+1);
+      }
+      // otherwise if the cursor is currently on the closing symbol
+      else if (firstIndex < cur.ch && chars[cur.ch] == symb) {
+        end = cur.ch; // assign end to the current cursor
+        --cur.ch; // make sure to look backwards
+      }
+
+      // if we're currently on the symbol, we've got a start
+      if (chars[cur.ch] == symb && !end) {
+        start = cur.ch + 1; // assign start to ahead of the cursor
+      } else {
+        // go backwards to find the start
+        for (i = cur.ch; i > -1 && !start; i--) {
+          if (chars[i] == symb) {
+            start = i + 1;
+          }
+        }
+      }
+
+      // look forwards for the end symbol
+      if (start && !end) {
+        for (i = start, len = chars.length; i < len && !end; i++) {
+          if (chars[i] == symb) {
+            end = i;
+          }
+        }
+      }
+
+      // nothing found
+      if (!start || !end) {
+        return { start: cur, end: cur };
+      }
+
+      // include the symbols
+      if (inclusive) {
+        --start; ++end;
+      }
+
+      return {
+        start: Pos(cur.line, start),
+        end: Pos(cur.line, end)
+      };
+    }
+
+    // Search functions
+    defineOption('pcre', true, 'boolean');
+    function SearchState() {}
+    SearchState.prototype = {
+      getQuery: function() {
+        return vimGlobalState.query;
+      },
+      setQuery: function(query) {
+        vimGlobalState.query = query;
+      },
+      getOverlay: function() {
+        return this.searchOverlay;
+      },
+      setOverlay: function(overlay) {
+        this.searchOverlay = overlay;
+      },
+      isReversed: function() {
+        return vimGlobalState.isReversed;
+      },
+      setReversed: function(reversed) {
+        vimGlobalState.isReversed = reversed;
+      }
+    };
+    function getSearchState(cm) {
+      var vim = cm.state.vim;
+      return vim.searchState_ || (vim.searchState_ = new SearchState());
+    }
+    function dialog(cm, template, shortText, onClose, options) {
+      if (cm.openDialog) {
+        cm.openDialog(template, onClose, { bottom: true, value: options.value,
+            onKeyDown: options.onKeyDown, onKeyUp: options.onKeyUp });
+      }
+      else {
+        onClose(prompt(shortText, ''));
+      }
+    }
+
+    function findUnescapedSlashes(str) {
+      var escapeNextChar = false;
+      var slashes = [];
+      for (var i = 0; i < str.length; i++) {
+        var c = str.charAt(i);
+        if (!escapeNextChar && c == '/') {
+          slashes.push(i);
+        }
+        escapeNextChar = !escapeNextChar && (c == '\\');
+      }
+      return slashes;
+    }
+
+    // Translates a search string from ex (vim) syntax into javascript form.
+    function translateRegex(str) {
+      // When these match, add a '\' if unescaped or remove one if escaped.
+      var specials = ['|', '(', ')', '{'];
+      // Remove, but never add, a '\' for these.
+      var unescape = ['}'];
+      var escapeNextChar = false;
+      var out = [];
+      for (var i = -1; i < str.length; i++) {
+        var c = str.charAt(i) || '';
+        var n = str.charAt(i+1) || '';
+        var specialComesNext = (specials.indexOf(n) != -1);
+        if (escapeNextChar) {
+          if (c !== '\\' || !specialComesNext) {
+            out.push(c);
+          }
+          escapeNextChar = false;
+        } else {
+          if (c === '\\') {
+            escapeNextChar = true;
+            // Treat the unescape list as special for removing, but not adding '\'.
+            if (unescape.indexOf(n) != -1) {
+              specialComesNext = true;
+            }
+            // Not passing this test means removing a '\'.
+            if (!specialComesNext || n === '\\') {
+              out.push(c);
+            }
+          } else {
+            out.push(c);
+            if (specialComesNext && n !== '\\') {
+              out.push('\\');
+            }
+          }
+        }
+      }
+      return out.join('');
+    }
+
+    // Translates the replace part of a search and replace from ex (vim) syntax into
+    // javascript form.  Similar to translateRegex, but additionally fixes back references
+    // (translates '\[0..9]' to '$[0..9]') and follows different rules for escaping '$'.
+    function translateRegexReplace(str) {
+      var escapeNextChar = false;
+      var out = [];
+      for (var i = -1; i < str.length; i++) {
+        var c = str.charAt(i) || '';
+        var n = str.charAt(i+1) || '';
+        if (escapeNextChar) {
+          // At any point in the loop, escapeNextChar is true if the previous
+          // character was a '\' and was not escaped.
+          out.push(c);
+          escapeNextChar = false;
+        } else {
+          if (c === '\\') {
+            escapeNextChar = true;
+            if ((isNumber(n) || n === '$')) {
+              out.push('$');
+            } else if (n !== '/' && n !== '\\') {
+              out.push('\\');
+            }
+          } else {
+            if (c === '$') {
+              out.push('$');
+            }
+            out.push(c);
+            if (n === '/') {
+              out.push('\\');
+            }
+          }
+        }
+      }
+      return out.join('');
+    }
+
+    // Unescape \ and / in the replace part, for PCRE mode.
+    function unescapeRegexReplace(str) {
+      var stream = new CodeMirror.StringStream(str);
+      var output = [];
+      while (!stream.eol()) {
+        // Search for \.
+        while (stream.peek() && stream.peek() != '\\') {
+          output.push(stream.next());
+        }
+        if (stream.match('\\/', true)) {
+          // \/ => /
+          output.push('/');
+        } else if (stream.match('\\\\', true)) {
+          // \\ => \
+          output.push('\\');
+        } else {
+          // Don't change anything
+          output.push(stream.next());
+        }
+      }
+      return output.join('');
+    }
+
+    /**
+     * Extract the regular expression from the query and return a Regexp object.
+     * Returns null if the query is blank.
+     * If ignoreCase is passed in, the Regexp object will have the 'i' flag set.
+     * If smartCase is passed in, and the query contains upper case letters,
+     *   then ignoreCase is overridden, and the 'i' flag will not be set.
+     * If the query contains the /i in the flag part of the regular expression,
+     *   then both ignoreCase and smartCase are ignored, and 'i' will be passed
+     *   through to the Regex object.
+     */
+    function parseQuery(query, ignoreCase, smartCase) {
+      // Check if the query is already a regex.
+      if (query instanceof RegExp) { return query; }
+      // First try to extract regex + flags from the input. If no flags found,
+      // extract just the regex. IE does not accept flags directly defined in
+      // the regex string in the form /regex/flags
+      var slashes = findUnescapedSlashes(query);
+      var regexPart;
+      var forceIgnoreCase;
+      if (!slashes.length) {
+        // Query looks like 'regexp'
+        regexPart = query;
+      } else {
+        // Query looks like 'regexp/...'
+        regexPart = query.substring(0, slashes[0]);
+        var flagsPart = query.substring(slashes[0]);
+        forceIgnoreCase = (flagsPart.indexOf('i') != -1);
+      }
+      if (!regexPart) {
+        return null;
+      }
+      if (!getOption('pcre')) {
+        regexPart = translateRegex(regexPart);
+      }
+      if (smartCase) {
+        ignoreCase = (/^[^A-Z]*$/).test(regexPart);
+      }
+      var regexp = new RegExp(regexPart,
+          (ignoreCase || forceIgnoreCase) ? 'i' : undefined);
+      return regexp;
+    }
+    function showConfirm(cm, text) {
+      if (cm.openNotification) {
+        cm.openNotification('<span style="color: red">' + text + '</span>',
+                            {bottom: true, duration: 5000});
+      } else {
+        alert(text);
+      }
+    }
+    function makePrompt(prefix, desc) {
+      var raw = '';
+      if (prefix) {
+        raw += '<span style="font-family: monospace">' + prefix + '</span>';
+      }
+      raw += '<input type="text"/> ' +
+          '<span style="color: #888">';
+      if (desc) {
+        raw += '<span style="color: #888">';
+        raw += desc;
+        raw += '</span>';
+      }
+      return raw;
+    }
+    var searchPromptDesc = '(Javascript regexp)';
+    function showPrompt(cm, options) {
+      var shortText = (options.prefix || '') + ' ' + (options.desc || '');
+      var prompt = makePrompt(options.prefix, options.desc);
+      dialog(cm, prompt, shortText, options.onClose, options);
+    }
+    function regexEqual(r1, r2) {
+      if (r1 instanceof RegExp && r2 instanceof RegExp) {
+          var props = ['global', 'multiline', 'ignoreCase', 'source'];
+          for (var i = 0; i < props.length; i++) {
+              var prop = props[i];
+              if (r1[prop] !== r2[prop]) {
+                  return false;
+              }
+          }
+          return true;
+      }
+      return false;
+    }
+    // Returns true if the query is valid.
+    function updateSearchQuery(cm, rawQuery, ignoreCase, smartCase) {
+      if (!rawQuery) {
+        return;
+      }
+      var state = getSearchState(cm);
+      var query = parseQuery(rawQuery, !!ignoreCase, !!smartCase);
+      if (!query) {
+        return;
+      }
+      highlightSearchMatches(cm, query);
+      if (regexEqual(query, state.getQuery())) {
+        return query;
+      }
+      state.setQuery(query);
+      return query;
+    }
+    function searchOverlay(query) {
+      if (query.source.charAt(0) == '^') {
+        var matchSol = true;
+      }
+      return {
+        token: function(stream) {
+          if (matchSol && !stream.sol()) {
+            stream.skipToEnd();
+            return;
+          }
+          var match = stream.match(query, false);
+          if (match) {
+            if (match[0].length == 0) {
+              // Matched empty string, skip to next.
+              stream.next();
+              return 'searching';
+            }
+            if (!stream.sol()) {
+              // Backtrack 1 to match \b
+              stream.backUp(1);
+              if (!query.exec(stream.next() + match[0])) {
+                stream.next();
+                return null;
+              }
+            }
+            stream.match(query);
+            return 'searching';
+          }
+          while (!stream.eol()) {
+            stream.next();
+            if (stream.match(query, false)) break;
+          }
+        },
+        query: query
+      };
+    }
+    function highlightSearchMatches(cm, query) {
+      var overlay = getSearchState(cm).getOverlay();
+      if (!overlay || query != overlay.query) {
+        if (overlay) {
+          cm.removeOverlay(overlay);
+        }
+        overlay = searchOverlay(query);
+        cm.addOverlay(overlay);
+        getSearchState(cm).setOverlay(overlay);
+      }
+    }
+    function findNext(cm, prev, query, repeat) {
+      if (repeat === undefined) { repeat = 1; }
+      return cm.operation(function() {
+        var pos = cm.getCursor();
+        var cursor = cm.getSearchCursor(query, pos);
+        for (var i = 0; i < repeat; i++) {
+          var found = cursor.find(prev);
+          if (i == 0 && found && cursorEqual(cursor.from(), pos)) { found = cursor.find(prev); }
+          if (!found) {
+            // SearchCursor may have returned null because it hit EOF, wrap
+            // around and try again.
+            cursor = cm.getSearchCursor(query,
+                (prev) ? Pos(cm.lastLine()) : Pos(cm.firstLine(), 0) );
+            if (!cursor.find(prev)) {
+              return;
+            }
+          }
+        }
+        return cursor.from();
+      });
+    }
+    function clearSearchHighlight(cm) {
+      cm.removeOverlay(getSearchState(cm).getOverlay());
+      getSearchState(cm).setOverlay(null);
+    }
+    /**
+     * Check if pos is in the specified range, INCLUSIVE.
+     * Range can be specified with 1 or 2 arguments.
+     * If the first range argument is an array, treat it as an array of line
+     * numbers. Match pos against any of the lines.
+     * If the first range argument is a number,
+     *   if there is only 1 range argument, check if pos has the same line
+     *       number
+     *   if there are 2 range arguments, then check if pos is in between the two
+     *       range arguments.
+     */
+    function isInRange(pos, start, end) {
+      if (typeof pos != 'number') {
+        // Assume it is a cursor position. Get the line number.
+        pos = pos.line;
+      }
+      if (start instanceof Array) {
+        return inArray(pos, start);
+      } else {
+        if (end) {
+          return (pos >= start && pos <= end);
+        } else {
+          return pos == start;
+        }
+      }
+    }
+    function getUserVisibleLines(cm) {
+      var scrollInfo = cm.getScrollInfo();
+      var occludeToleranceTop = 6;
+      var occludeToleranceBottom = 10;
+      var from = cm.coordsChar({left:0, top: occludeToleranceTop + scrollInfo.top}, 'local');
+      var bottomY = scrollInfo.clientHeight - occludeToleranceBottom + scrollInfo.top;
+      var to = cm.coordsChar({left:0, top: bottomY}, 'local');
+      return {top: from.line, bottom: to.line};
+    }
+
+    // Ex command handling
+    // Care must be taken when adding to the default Ex command map. For any
+    // pair of commands that have a shared prefix, at least one of their
+    // shortNames must not match the prefix of the other command.
+    var defaultExCommandMap = [
+      { name: 'map' },
+      { name: 'nmap', shortName: 'nm' },
+      { name: 'vmap', shortName: 'vm' },
+      { name: 'unmap' },
+      { name: 'write', shortName: 'w' },
+      { name: 'undo', shortName: 'u' },
+      { name: 'redo', shortName: 'red' },
+      { name: 'set', shortName: 'set' },
+      { name: 'sort', shortName: 'sor' },
+      { name: 'substitute', shortName: 's' },
+      { name: 'nohlsearch', shortName: 'noh' },
+      { name: 'delmarks', shortName: 'delm' },
+      { name: 'registers', shortName: 'reg' }
+    ];
+    Vim.ExCommandDispatcher = function() {
+      this.buildCommandMap_();
+    };
+    Vim.ExCommandDispatcher.prototype = {
+      processCommand: function(cm, input) {
+        var vim = cm.state.vim;
+        if (vim.visualMode) {
+          exitVisualMode(cm);
+        }
+        var inputStream = new CodeMirror.StringStream(input);
+        var params = {};
+        params.input = input;
+        try {
+          this.parseInput_(cm, inputStream, params);
+        } catch(e) {
+          showConfirm(cm, e);
+          throw e;
+        }
+        var commandName;
+        if (!params.commandName) {
+          // If only a line range is defined, move to the line.
+          if (params.line !== undefined) {
+            commandName = 'move';
+          }
+        } else {
+          var command = this.matchCommand_(params.commandName);
+          if (command) {
+            commandName = command.name;
+            this.parseCommandArgs_(inputStream, params, command);
+            if (command.type == 'exToKey') {
+              // Handle Ex to Key mapping.
+              for (var i = 0; i < command.toKeys.length; i++) {
+                CodeMirror.Vim.handleKey(cm, command.toKeys[i]);
+              }
+              return;
+            } else if (command.type == 'exToEx') {
+              // Handle Ex to Ex mapping.
+              this.processCommand(cm, command.toInput);
+              return;
+            }
+          }
+        }
+        if (!commandName) {
+          showConfirm(cm, 'Not an editor command ":' + input + '"');
+          return;
+        }
+        try {
+          exCommands[commandName](cm, params);
+        } catch(e) {
+          showConfirm(cm, e);
+          throw e;
+        }
+      },
+      parseInput_: function(cm, inputStream, result) {
+        inputStream.eatWhile(':');
+        // Parse range.
+        if (inputStream.eat('%')) {
+          result.line = cm.firstLine();
+          result.lineEnd = cm.lastLine();
+        } else {
+          result.line = this.parseLineSpec_(cm, inputStream);
+          if (result.line !== undefined && inputStream.eat(',')) {
+            result.lineEnd = this.parseLineSpec_(cm, inputStream);
+          }
+        }
+
+        // Parse command name.
+        var commandMatch = inputStream.match(/^(\w+)/);
+        if (commandMatch) {
+          result.commandName = commandMatch[1];
+        } else {
+          result.commandName = inputStream.match(/.*/)[0];
+        }
+
+        return result;
+      },
+      parseLineSpec_: function(cm, inputStream) {
+        var numberMatch = inputStream.match(/^(\d+)/);
+        if (numberMatch) {
+          return parseInt(numberMatch[1], 10) - 1;
+        }
+        switch (inputStream.next()) {
+          case '.':
+            return cm.getCursor().line;
+          case '$':
+            return cm.lastLine();
+          case '\'':
+            var mark = cm.state.vim.marks[inputStream.next()];
+            if (mark && mark.find()) {
+              return mark.find().line;
+            }
+            throw new Error('Mark not set');
+          default:
+            inputStream.backUp(1);
+            return undefined;
+        }
+      },
+      parseCommandArgs_: function(inputStream, params, command) {
+        if (inputStream.eol()) {
+          return;
+        }
+        params.argString = inputStream.match(/.*/)[0];
+        // Parse command-line arguments
+        var delim = command.argDelimiter || /\s+/;
+        var args = trim(params.argString).split(delim);
+        if (args.length && args[0]) {
+          params.args = args;
+        }
+      },
+      matchCommand_: function(commandName) {
+        // Return the command in the command map that matches the shortest
+        // prefix of the passed in command name. The match is guaranteed to be
+        // unambiguous if the defaultExCommandMap's shortNames are set up
+        // correctly. (see @code{defaultExCommandMap}).
+        for (var i = commandName.length; i > 0; i--) {
+          var prefix = commandName.substring(0, i);
+          if (this.commandMap_[prefix]) {
+            var command = this.commandMap_[prefix];
+            if (command.name.indexOf(commandName) === 0) {
+              return command;
+            }
+          }
+        }
+        return null;
+      },
+      buildCommandMap_: function() {
+        this.commandMap_ = {};
+        for (var i = 0; i < defaultExCommandMap.length; i++) {
+          var command = defaultExCommandMap[i];
+          var key = command.shortName || command.name;
+          this.commandMap_[key] = command;
+        }
+      },
+      map: function(lhs, rhs, ctx) {
+        if (lhs != ':' && lhs.charAt(0) == ':') {
+          if (ctx) { throw Error('Mode not supported for ex mappings'); }
+          var commandName = lhs.substring(1);
+          if (rhs != ':' && rhs.charAt(0) == ':') {
+            // Ex to Ex mapping
+            this.commandMap_[commandName] = {
+              name: commandName,
+              type: 'exToEx',
+              toInput: rhs.substring(1),
+              user: true
+            };
+          } else {
+            // Ex to key mapping
+            this.commandMap_[commandName] = {
+              name: commandName,
+              type: 'exToKey',
+              toKeys: parseKeyString(rhs),
+              user: true
+            };
+          }
+        } else {
+          if (rhs != ':' && rhs.charAt(0) == ':') {
+            // Key to Ex mapping.
+            var mapping = {
+              keys: parseKeyString(lhs),
+              type: 'keyToEx',
+              exArgs: { input: rhs.substring(1) },
+              user: true};
+            if (ctx) { mapping.context = ctx; }
+            defaultKeymap.unshift(mapping);
+          } else {
+            // Key to key mapping
+            var mapping = {
+              keys: parseKeyString(lhs),
+              type: 'keyToKey',
+              toKeys: parseKeyString(rhs),
+              user: true
+            };
+            if (ctx) { mapping.context = ctx; }
+            defaultKeymap.unshift(mapping);
+          }
+        }
+      },
+      unmap: function(lhs, ctx) {
+        var arrayEquals = function(a, b) {
+          if (a === b) return true;
+          if (a == null || b == null) return true;
+          if (a.length != b.length) return false;
+          for (var i = 0; i < a.length; i++) {
+            if (a[i] !== b[i]) return false;
+          }
+          return true;
+        };
+        if (lhs != ':' && lhs.charAt(0) == ':') {
+          // Ex to Ex or Ex to key mapping
+          if (ctx) { throw Error('Mode not supported for ex mappings'); }
+          var commandName = lhs.substring(1);
+          if (this.commandMap_[commandName] && this.commandMap_[commandName].user) {
+            delete this.commandMap_[commandName];
+            return;
+          }
+        } else {
+          // Key to Ex or key to key mapping
+          var keys = parseKeyString(lhs);
+          for (var i = 0; i < defaultKeymap.length; i++) {
+            if (arrayEquals(keys, defaultKeymap[i].keys)
+                && defaultKeymap[i].context === ctx
+                && defaultKeymap[i].user) {
+              defaultKeymap.splice(i, 1);
+              return;
+            }
+          }
+        }
+        throw Error('No such mapping.');
+      }
+    };
+
+    // Converts a key string sequence of the form a<C-w>bd<Left> into Vim's
+    // keymap representation.
+    function parseKeyString(str) {
+      var key, match;
+      var keys = [];
+      while (str) {
+        match = (/<\w+-.+?>|<\w+>|./).exec(str);
+        if (match === null)break;
+        key = match[0];
+        str = str.substring(match.index + key.length);
+        keys.push(key);
+      }
+      return keys;
+    }
+
+    var exCommands = {
+      map: function(cm, params, ctx) {
+        var mapArgs = params.args;
+        if (!mapArgs || mapArgs.length < 2) {
+          if (cm) {
+            showConfirm(cm, 'Invalid mapping: ' + params.input);
+          }
+          return;
+        }
+        exCommandDispatcher.map(mapArgs[0], mapArgs[1], ctx);
+      },
+      nmap: function(cm, params) { this.map(cm, params, 'normal'); },
+      vmap: function(cm, params) { this.map(cm, params, 'visual'); },
+      unmap: function(cm, params, ctx) {
+        var mapArgs = params.args;
+        if (!mapArgs || mapArgs.length < 1) {
+          if (cm) {
+            showConfirm(cm, 'No such mapping: ' + params.input);
+          }
+          return;
+        }
+        exCommandDispatcher.unmap(mapArgs[0], ctx);
+      },
+      move: function(cm, params) {
+        commandDispatcher.processCommand(cm, cm.state.vim, {
+            type: 'motion',
+            motion: 'moveToLineOrEdgeOfDocument',
+            motionArgs: { forward: false, explicitRepeat: true,
+              linewise: true },
+            repeatOverride: params.line+1});
+      },
+      set: function(cm, params) {
+        var setArgs = params.args;
+        if (!setArgs || setArgs.length < 1) {
+          if (cm) {
+            showConfirm(cm, 'Invalid mapping: ' + params.input);
+          }
+          return;
+        }
+        var expr = setArgs[0].split('=');
+        var optionName = expr[0];
+        var value = expr[1];
+        var forceGet = false;
+
+        if (optionName.charAt(optionName.length - 1) == '?') {
+          // If post-fixed with ?, then the set is actually a get.
+          if (value) { throw Error('Trailing characters: ' + params.argString); }
+          optionName = optionName.substring(0, optionName.length - 1);
+          forceGet = true;
+        }
+        if (value === undefined && optionName.substring(0, 2) == 'no') {
+          // To set boolean options to false, the option name is prefixed with
+          // 'no'.
+          optionName = optionName.substring(2);
+          value = false;
+        }
+        var optionIsBoolean = options[optionName] && options[optionName].type == 'boolean';
+        if (optionIsBoolean && value == undefined) {
+          // Calling set with a boolean option sets it to true.
+          value = true;
+        }
+        if (!optionIsBoolean && !value || forceGet) {
+          var oldValue = getOption(optionName);
+          // If no value is provided, then we assume this is a get.
+          if (oldValue === true || oldValue === false) {
+            showConfirm(cm, ' ' + (oldValue ? '' : 'no') + optionName);
+          } else {
+            showConfirm(cm, '  ' + optionName + '=' + oldValue);
+          }
+        } else {
+          setOption(optionName, value);
+        }
+      },
+      registers: function(cm,params) {
+        var regArgs = params.args;
+        var registers = vimGlobalState.registerController.registers;
+        var regInfo = '----------Registers----------<br><br>';
+        if (!regArgs) {
+          for (var registerName in registers) {
+            var text = registers[registerName].toString();
+            if (text.length) {
+              regInfo += '"' + registerName + '    ' + text + '<br>';
+            }
+          }
+        } else {
+          var registerName;
+          regArgs = regArgs.join('');
+          for (var i = 0; i < regArgs.length; i++) {
+            registerName = regArgs.charAt(i);
+            if (!vimGlobalState.registerController.isValidRegister(registerName)) {
+              continue;
+            }
+            var register = registers[registerName] || new Register();
+            regInfo += '"' + registerName + '    ' + register.text + '<br>';
+          }
+        }
+        showConfirm(cm, regInfo);
+      },
+      sort: function(cm, params) {
+        var reverse, ignoreCase, unique, number;
+        function parseArgs() {
+          if (params.argString) {
+            var args = new CodeMirror.StringStream(params.argString);
+            if (args.eat('!')) { reverse = true; }
+            if (args.eol()) { return; }
+            if (!args.eatSpace()) { return 'Invalid arguments'; }
+            var opts = args.match(/[a-z]+/);
+            if (opts) {
+              opts = opts[0];
+              ignoreCase = opts.indexOf('i') != -1;
+              unique = opts.indexOf('u') != -1;
+              var decimal = opts.indexOf('d') != -1 && 1;
+              var hex = opts.indexOf('x') != -1 && 1;
+              var octal = opts.indexOf('o') != -1 && 1;
+              if (decimal + hex + octal > 1) { return 'Invalid arguments'; }
+              number = decimal && 'decimal' || hex && 'hex' || octal && 'octal';
+            }
+            if (args.eatSpace() && args.match(/\/.*\//)) { 'patterns not supported'; }
+          }
+        }
+        var err = parseArgs();
+        if (err) {
+          showConfirm(cm, err + ': ' + params.argString);
+          return;
+        }
+        var lineStart = params.line || cm.firstLine();
+        var lineEnd = params.lineEnd || params.line || cm.lastLine();
+        if (lineStart == lineEnd) { return; }
+        var curStart = Pos(lineStart, 0);
+        var curEnd = Pos(lineEnd, lineLength(cm, lineEnd));
+        var text = cm.getRange(curStart, curEnd).split('\n');
+        var numberRegex = (number == 'decimal') ? /(-?)([\d]+)/ :
+           (number == 'hex') ? /(-?)(?:0x)?([0-9a-f]+)/i :
+           (number == 'octal') ? /([0-7]+)/ : null;
+        var radix = (number == 'decimal') ? 10 : (number == 'hex') ? 16 : (number == 'octal') ? 8 : null;
+        var numPart = [], textPart = [];
+        if (number) {
+          for (var i = 0; i < text.length; i++) {
+            if (numberRegex.exec(text[i])) {
+              numPart.push(text[i]);
+            } else {
+              textPart.push(text[i]);
+            }
+          }
+        } else {
+          textPart = text;
+        }
+        function compareFn(a, b) {
+          if (reverse) { var tmp; tmp = a; a = b; b = tmp; }
+          if (ignoreCase) { a = a.toLowerCase(); b = b.toLowerCase(); }
+          var anum = number && numberRegex.exec(a);
+          var bnum = number && numberRegex.exec(b);
+          if (!anum) { return a < b ? -1 : 1; }
+          anum = parseInt((anum[1] + anum[2]).toLowerCase(), radix);
+          bnum = parseInt((bnum[1] + bnum[2]).toLowerCase(), radix);
+          return anum - bnum;
+        }
+        numPart.sort(compareFn);
+        textPart.sort(compareFn);
+        text = (!reverse) ? textPart.concat(numPart) : numPart.concat(textPart);
+        if (unique) { // Remove duplicate lines
+          var textOld = text;
+          var lastLine;
+          text = [];
+          for (var i = 0; i < textOld.length; i++) {
+            if (textOld[i] != lastLine) {
+              text.push(textOld[i]);
+            }
+            lastLine = textOld[i];
+          }
+        }
+        cm.replaceRange(text.join('\n'), curStart, curEnd);
+      },
+      substitute: function(cm, params) {
+        if (!cm.getSearchCursor) {
+          throw new Error('Search feature not available. Requires searchcursor.js or ' +
+              'any other getSearchCursor implementation.');
+        }
+        var argString = params.argString;
+        var slashes = findUnescapedSlashes(argString);
+        if (slashes[0] !== 0) {
+          showConfirm(cm, 'Substitutions should be of the form ' +
+              ':s/pattern/replace/');
+          return;
+        }
+        var regexPart = argString.substring(slashes[0] + 1, slashes[1]);
+        var replacePart = '';
+        var flagsPart;
+        var count;
+        var confirm = false; // Whether to confirm each replace.
+        if (slashes[1]) {
+          replacePart = argString.substring(slashes[1] + 1, slashes[2]);
+          if (getOption('pcre')) {
+            replacePart = unescapeRegexReplace(replacePart);
+          } else {
+            replacePart = translateRegexReplace(replacePart);
+          }
+        }
+        if (slashes[2]) {
+          // After the 3rd slash, we can have flags followed by a space followed
+          // by count.
+          var trailing = argString.substring(slashes[2] + 1).split(' ');
+          flagsPart = trailing[0];
+          count = parseInt(trailing[1]);
+        }
+        if (flagsPart) {
+          if (flagsPart.indexOf('c') != -1) {
+            confirm = true;
+            flagsPart.replace('c', '');
+          }
+          regexPart = regexPart + '/' + flagsPart;
+        }
+        if (regexPart) {
+          // If regex part is empty, then use the previous query. Otherwise use
+          // the regex part as the new query.
+          try {
+            updateSearchQuery(cm, regexPart, true /** ignoreCase */,
+              true /** smartCase */);
+          } catch (e) {
+            showConfirm(cm, 'Invalid regex: ' + regexPart);
+            return;
+          }
+        }
+        var state = getSearchState(cm);
+        var query = state.getQuery();
+        var lineStart = (params.line !== undefined) ? params.line : cm.getCursor().line;
+        var lineEnd = params.lineEnd || lineStart;
+        if (count) {
+          lineStart = lineEnd;
+          lineEnd = lineStart + count - 1;
+        }
+        var startPos = clipCursorToContent(cm, Pos(lineStart, 0));
+        var cursor = cm.getSearchCursor(query, startPos);
+        doReplace(cm, confirm, lineStart, lineEnd, cursor, query, replacePart);
+      },
+      redo: CodeMirror.commands.redo,
+      undo: CodeMirror.commands.undo,
+      write: function(cm) {
+        if (CodeMirror.commands.save) {
+          // If a save command is defined, call it.
+          CodeMirror.commands.save(cm);
+        } else {
+          // Saves to text area if no save command is defined.
+          cm.save();
+        }
+      },
+      nohlsearch: function(cm) {
+        clearSearchHighlight(cm);
+      },
+      delmarks: function(cm, params) {
+        if (!params.argString || !trim(params.argString)) {
+          showConfirm(cm, 'Argument required');
+          return;
+        }
+
+        var state = cm.state.vim;
+        var stream = new CodeMirror.StringStream(trim(params.argString));
+        while (!stream.eol()) {
+          stream.eatSpace();
+
+          // Record the streams position at the beginning of the loop for use
+          // in error messages.
+          var count = stream.pos;
+
+          if (!stream.match(/[a-zA-Z]/, false)) {
+            showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count));
+            return;
+          }
+
+          var sym = stream.next();
+          // Check if this symbol is part of a range
+          if (stream.match('-', true)) {
+            // This symbol is part of a range.
+
+            // The range must terminate at an alphabetic character.
+            if (!stream.match(/[a-zA-Z]/, false)) {
+              showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count));
+              return;
+            }
+
+            var startMark = sym;
+            var finishMark = stream.next();
+            // The range must terminate at an alphabetic character which
+            // shares the same case as the start of the range.
+            if (isLowerCase(startMark) && isLowerCase(finishMark) ||
+                isUpperCase(startMark) && isUpperCase(finishMark)) {
+              var start = startMark.charCodeAt(0);
+              var finish = finishMark.charCodeAt(0);
+              if (start >= finish) {
+                showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count));
+                return;
+              }
+
+              // Because marks are always ASCII values, and we have
+              // determined that they are the same case, we can use
+              // their char codes to iterate through the defined range.
+              for (var j = 0; j <= finish - start; j++) {
+                var mark = String.fromCharCode(start + j);
+                delete state.marks[mark];
+              }
+            } else {
+              showConfirm(cm, 'Invalid argument: ' + startMark + '-');
+              return;
+            }
+          } else {
+            // This symbol is a valid mark, and is not part of a range.
+            delete state.marks[sym];
+          }
+        }
+      }
+    };
+
+    var exCommandDispatcher = new Vim.ExCommandDispatcher();
+
+    /**
+    * @param {CodeMirror} cm CodeMirror instance we are in.
+    * @param {boolean} confirm Whether to confirm each replace.
+    * @param {Cursor} lineStart Line to start replacing from.
+    * @param {Cursor} lineEnd Line to stop replacing at.
+    * @param {RegExp} query Query for performing matches with.
+    * @param {string} replaceWith Text to replace matches with. May contain $1,
+    *     $2, etc for replacing captured groups using Javascript replace.
+    */
+    function doReplace(cm, confirm, lineStart, lineEnd, searchCursor, query,
+        replaceWith) {
+      // Set up all the functions.
+      cm.state.vim.exMode = true;
+      var done = false;
+      var lastPos = searchCursor.from();
+      function replaceAll() {
+        cm.operation(function() {
+          while (!done) {
+            replace();
+            next();
+          }
+          stop();
+        });
+      }
+      function replace() {
+        var text = cm.getRange(searchCursor.from(), searchCursor.to());
+        var newText = text.replace(query, replaceWith);
+        searchCursor.replace(newText);
+      }
+      function next() {
+        var found = searchCursor.findNext();
+        if (!found) {
+          done = true;
+        } else if (isInRange(searchCursor.from(), lineStart, lineEnd)) {
+          cm.scrollIntoView(searchCursor.from(), 30);
+          cm.setSelection(searchCursor.from(), searchCursor.to());
+          lastPos = searchCursor.from();
+          done = false;
+        } else {
+          done = true;
+        }
+      }
+      function stop(close) {
+        if (close) { close(); }
+        cm.focus();
+        if (lastPos) {
+          cm.setCursor(lastPos);
+          var vim = cm.state.vim;
+          vim.exMode = false;
+          vim.lastHPos = vim.lastHSPos = lastPos.ch;
+        }
+      }
+      function onPromptKeyDown(e, _value, close) {
+        // Swallow all keys.
+        CodeMirror.e_stop(e);
+        var keyName = CodeMirror.keyName(e);
+        switch (keyName) {
+          case 'Y':
+            replace(); next(); break;
+          case 'N':
+            next(); break;
+          case 'A':
+            cm.operation(replaceAll); break;
+          case 'L':
+            replace();
+            // fall through and exit.
+          case 'Q':
+          case 'Esc':
+          case 'Ctrl-C':
+          case 'Ctrl-[':
+            stop(close);
+            break;
+        }
+        if (done) { stop(close); }
+      }
+
+      // Actually do replace.
+      next();
+      if (done) {
+        showConfirm(cm, 'No matches for ' + query.source);
+        return;
+      }
+      if (!confirm) {
+        replaceAll();
+        return;
+      }
+      showPrompt(cm, {
+        prefix: 'replace with <strong>' + replaceWith + '</strong> (y/n/a/q/l)',
+        onKeyDown: onPromptKeyDown
+      });
+    }
+
+    // Register Vim with CodeMirror
+    function buildVimKeyMap() {
+      /**
+       * Handle the raw key event from CodeMirror. Translate the
+       * Shift + key modifier to the resulting letter, while preserving other
+       * modifers.
+       */
+      function cmKeyToVimKey(key, modifier) {
+        var vimKey = key;
+        if (isUpperCase(vimKey) && modifier == 'Ctrl') {
+            vimKey = vimKey.toLowerCase();
+        }
+        if (modifier) {
+          // Vim will parse modifier+key combination as a single key.
+          vimKey = modifier.charAt(0) + '-' + vimKey;
+        }
+        var specialKey = ({Enter:'CR',Backspace:'BS',Delete:'Del'})[vimKey];
+        vimKey = specialKey ? specialKey : vimKey;
+        vimKey = vimKey.length > 1 ? '<'+ vimKey + '>' : vimKey;
+        return vimKey;
+      }
+
+      // Closure to bind CodeMirror, key, modifier.
+      function keyMapper(vimKey) {
+        return function(cm) {
+          CodeMirror.Vim.handleKey(cm, vimKey);
+        };
+      }
+
+      var cmToVimKeymap = {
+        'nofallthrough': true,
+        'style': 'fat-cursor'
+      };
+      function bindKeys(keys, modifier) {
+        for (var i = 0; i < keys.length; i++) {
+          var key = keys[i];
+          if (!modifier && key.length == 1) {
+            // Wrap all keys without modifiers with '' to identify them by their
+            // key characters instead of key identifiers.
+            key = "'" + key + "'";
+          }
+          var vimKey = cmKeyToVimKey(keys[i], modifier);
+          var cmKey = modifier ? modifier + '-' + key : key;
+          cmToVimKeymap[cmKey] = keyMapper(vimKey);
+        }
+      }
+      bindKeys(upperCaseAlphabet);
+      bindKeys(lowerCaseAlphabet);
+      bindKeys(upperCaseAlphabet, 'Ctrl');
+      bindKeys(specialSymbols);
+      bindKeys(specialSymbols, 'Ctrl');
+      bindKeys(numbers);
+      bindKeys(numbers, 'Ctrl');
+      bindKeys(specialKeys);
+      bindKeys(specialKeys, 'Ctrl');
+      return cmToVimKeymap;
+    }
+    CodeMirror.keyMap.vim = buildVimKeyMap();
+
+    function exitInsertMode(cm) {
+      var vim = cm.state.vim;
+      var macroModeState = vimGlobalState.macroModeState;
+      var isPlaying = macroModeState.isPlaying;
+      if (!isPlaying) {
+        cm.off('change', onChange);
+        cm.off('cursorActivity', onCursorActivity);
+        CodeMirror.off(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown);
+      }
+      if (!isPlaying && vim.insertModeRepeat > 1) {
+        // Perform insert mode repeat for commands like 3,a and 3,o.
+        repeatLastEdit(cm, vim, vim.insertModeRepeat - 1,
+            true /** repeatForInsert */);
+        vim.lastEditInputState.repeatOverride = vim.insertModeRepeat;
+      }
+      delete vim.insertModeRepeat;
+      cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1);
+      vim.insertMode = false;
+      cm.setOption('keyMap', 'vim');
+      cm.setOption('disableInput', true);
+      cm.toggleOverwrite(false); // exit replace mode if we were in it.
+      CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
+      if (macroModeState.isRecording) {
+        logInsertModeChange(macroModeState);
+      }
+    }
+
+    CodeMirror.keyMap['vim-insert'] = {
+      // TODO: override navigation keys so that Esc will cancel automatic
+      // indentation from o, O, i_<CR>
+      'Esc': exitInsertMode,
+      'Ctrl-[': exitInsertMode,
+      'Ctrl-C': exitInsertMode,
+      'Ctrl-N': 'autocomplete',
+      'Ctrl-P': 'autocomplete',
+      'Enter': function(cm) {
+        var fn = CodeMirror.commands.newlineAndIndentContinueComment ||
+            CodeMirror.commands.newlineAndIndent;
+        fn(cm);
+      },
+      fallthrough: ['default']
+    };
+
+    CodeMirror.keyMap['vim-replace'] = {
+      'Backspace': 'goCharLeft',
+      fallthrough: ['vim-insert']
+    };
+
+    function executeMacroRegister(cm, vim, macroModeState, registerName) {
+      var register = vimGlobalState.registerController.getRegister(registerName);
+      var keyBuffer = register.keyBuffer;
+      var imc = 0;
+      macroModeState.isPlaying = true;
+      for (var i = 0; i < keyBuffer.length; i++) {
+        var text = keyBuffer[i];
+        var match, key;
+        while (text) {
+          // Pull off one command key, which is either a single character
+          // or a special sequence wrapped in '<' and '>', e.g. '<Space>'.
+          match = (/<\w+-.+?>|<\w+>|./).exec(text);
+          key = match[0];
+          text = text.substring(match.index + key.length);
+          CodeMirror.Vim.handleKey(cm, key);
+          if (vim.insertMode) {
+            repeatInsertModeChanges(
+                cm, register.insertModeChanges[imc++].changes, 1);
+            exitInsertMode(cm);
+          }
+        }
+      };
+      macroModeState.isPlaying = false;
+    }
+
+    function logKey(macroModeState, key) {
+      if (macroModeState.isPlaying) { return; }
+      var registerName = macroModeState.latestRegister;
+      var register = vimGlobalState.registerController.getRegister(registerName);
+      if (register) {
+        register.pushText(key);
+      }
+    }
+
+    function logInsertModeChange(macroModeState) {
+      if (macroModeState.isPlaying) { return; }
+      var registerName = macroModeState.latestRegister;
+      var register = vimGlobalState.registerController.getRegister(registerName);
+      if (register) {
+        register.pushInsertModeChanges(macroModeState.lastInsertModeChanges);
+      }
+    }
+
+    /**
+     * Listens for changes made in insert mode.
+     * Should only be active in insert mode.
+     */
+    function onChange(_cm, changeObj) {
+      var macroModeState = vimGlobalState.macroModeState;
+      var lastChange = macroModeState.lastInsertModeChanges;
+      if (!macroModeState.isPlaying) {
+        while(changeObj) {
+          lastChange.expectCursorActivityForChange = true;
+          if (changeObj.origin == '+input' || changeObj.origin == 'paste'
+              || changeObj.origin === undefined /* only in testing */) {
+            var text = changeObj.text.join('\n');
+            lastChange.changes.push(text);
+          }
+          // Change objects may be chained with next.
+          changeObj = changeObj.next;
+        }
+      }
+    }
+
+    /**
+    * Listens for any kind of cursor activity on CodeMirror.
+    * - For tracking cursor activity in insert mode.
+    * - Should only be active in insert mode.
+    */
+    function onCursorActivity() {
+      var macroModeState = vimGlobalState.macroModeState;
+      if (macroModeState.isPlaying) { return; }
+      var lastChange = macroModeState.lastInsertModeChanges;
+      if (lastChange.expectCursorActivityForChange) {
+        lastChange.expectCursorActivityForChange = false;
+      } else {
+        // Cursor moved outside the context of an edit. Reset the change.
+        lastChange.changes = [];
+      }
+    }
+
+    /** Wrapper for special keys pressed in insert mode */
+    function InsertModeKey(keyName) {
+      this.keyName = keyName;
+    }
+
+    /**
+    * Handles raw key down events from the text area.
+    * - Should only be active in insert mode.
+    * - For recording deletes in insert mode.
+    */
+    function onKeyEventTargetKeyDown(e) {
+      var macroModeState = vimGlobalState.macroModeState;
+      var lastChange = macroModeState.lastInsertModeChanges;
+      var keyName = CodeMirror.keyName(e);
+      function onKeyFound() {
+        lastChange.changes.push(new InsertModeKey(keyName));
+        return true;
+      }
+      if (keyName.indexOf('Delete') != -1 || keyName.indexOf('Backspace') != -1) {
+        CodeMirror.lookupKey(keyName, ['vim-insert'], onKeyFound);
+      }
+    }
+
+    /**
+     * Repeats the last edit, which includes exactly 1 command and at most 1
+     * insert. Operator and motion commands are read from lastEditInputState,
+     * while action commands are read from lastEditActionCommand.
+     *
+     * If repeatForInsert is true, then the function was called by
+     * exitInsertMode to repeat the insert mode changes the user just made. The
+     * corresponding enterInsertMode call was made with a count.
+     */
+    function repeatLastEdit(cm, vim, repeat, repeatForInsert) {
+      var macroModeState = vimGlobalState.macroModeState;
+      macroModeState.isPlaying = true;
+      var isAction = !!vim.lastEditActionCommand;
+      var cachedInputState = vim.inputState;
+      function repeatCommand() {
+        if (isAction) {
+          commandDispatcher.processAction(cm, vim, vim.lastEditActionCommand);
+        } else {
+          commandDispatcher.evalInput(cm, vim);
+        }
+      }
+      function repeatInsert(repeat) {
+        if (macroModeState.lastInsertModeChanges.changes.length > 0) {
+          // For some reason, repeat cw in desktop VIM does not repeat
+          // insert mode changes. Will conform to that behavior.
+          repeat = !vim.lastEditActionCommand ? 1 : repeat;
+          var changeObject = macroModeState.lastInsertModeChanges;
+          // This isn't strictly necessary, but since lastInsertModeChanges is
+          // supposed to be immutable during replay, this helps catch bugs.
+          macroModeState.lastInsertModeChanges = {};
+          repeatInsertModeChanges(cm, changeObject.changes, repeat);
+          macroModeState.lastInsertModeChanges = changeObject;
+        }
+      }
+      vim.inputState = vim.lastEditInputState;
+      if (isAction && vim.lastEditActionCommand.interlaceInsertRepeat) {
+        // o and O repeat have to be interlaced with insert repeats so that the
+        // insertions appear on separate lines instead of the last line.
+        for (var i = 0; i < repeat; i++) {
+          repeatCommand();
+          repeatInsert(1);
+        }
+      } else {
+        if (!repeatForInsert) {
+          // Hack to get the cursor to end up at the right place. If I is
+          // repeated in insert mode repeat, cursor will be 1 insert
+          // change set left of where it should be.
+          repeatCommand();
+        }
+        repeatInsert(repeat);
+      }
+      vim.inputState = cachedInputState;
+      if (vim.insertMode && !repeatForInsert) {
+        // Don't exit insert mode twice. If repeatForInsert is set, then we
+        // were called by an exitInsertMode call lower on the stack.
+        exitInsertMode(cm);
+      }
+      macroModeState.isPlaying = false;
+    };
+
+    function repeatInsertModeChanges(cm, changes, repeat) {
+      function keyHandler(binding) {
+        if (typeof binding == 'string') {
+          CodeMirror.commands[binding](cm);
+        } else {
+          binding(cm);
+        }
+        return true;
+      }
+      for (var i = 0; i < repeat; i++) {
+        for (var j = 0; j < changes.length; j++) {
+          var change = changes[j];
+          if (change instanceof InsertModeKey) {
+            CodeMirror.lookupKey(change.keyName, ['vim-insert'], keyHandler);
+          } else {
+            var cur = cm.getCursor();
+            cm.replaceRange(change, cur, cur);
+          }
+        }
+      }
+    }
+
+    resetVimGlobalState();
+    return vimApi;
+  };
+  // Initialize Vim and make it available as an API.
+  CodeMirror.Vim = Vim();
+});
diff --git a/app/gui/html/vendor/codemirror/lib/codemirror.css b/app/gui/html/vendor/codemirror/lib/codemirror.css
new file mode 100644
index 0000000..d263e44
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/lib/codemirror.css
@@ -0,0 +1,270 @@
+/* BASICS */
+
+.CodeMirror {
+  /* Set height, width, borders, and global font properties here */
+  font-family: monospace;
+  height: 300px;
+}
+.CodeMirror-scroll {
+  /* Set scrolling behaviour here */
+  overflow: auto;
+}
+
+/* PADDING */
+
+.CodeMirror-lines {
+  padding: 4px 0; /* Vertical padding around content */
+}
+.CodeMirror pre {
+  padding: 0 4px; /* Horizontal padding of content */
+}
+
+.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
+  background-color: white; /* The little square between H and V scrollbars */
+}
+
+/* GUTTER */
+
+.CodeMirror-gutters {
+  border-right: 1px solid #ddd;
+  background-color: #f7f7f7;
+  white-space: nowrap;
+}
+.CodeMirror-linenumbers {}
+.CodeMirror-linenumber {
+  padding: 0 3px 0 5px;
+  min-width: 20px;
+  text-align: right;
+  color: #999;
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
+}
+
+/* CURSOR */
+
+.CodeMirror div.CodeMirror-cursor {
+  border-left: 1px solid black;
+}
+/* Shown when moving in bi-directional text */
+.CodeMirror div.CodeMirror-secondarycursor {
+  border-left: 1px solid silver;
+}
+.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
+  width: auto;
+  border: 0;
+  background: #7e7;
+}
+/* Can style cursor different in overwrite (non-insert) mode */
+div.CodeMirror-overwrite div.CodeMirror-cursor {}
+
+.cm-tab { display: inline-block; }
+
+.CodeMirror-ruler {
+  border-left: 1px solid #ccc;
+  position: absolute;
+}
+
+/* DEFAULT THEME */
+
+.cm-s-default .cm-keyword {color: #708;}
+.cm-s-default .cm-atom {color: #219;}
+.cm-s-default .cm-number {color: #164;}
+.cm-s-default .cm-def {color: #00f;}
+.cm-s-default .cm-variable {color: black;}
+.cm-s-default .cm-variable-2 {color: #05a;}
+.cm-s-default .cm-variable-3 {color: #085;}
+.cm-s-default .cm-property {color: black;}
+.cm-s-default .cm-operator {color: black;}
+.cm-s-default .cm-comment {color: #a50;}
+.cm-s-default .cm-string {color: #a11;}
+.cm-s-default .cm-string-2 {color: #f50;}
+.cm-s-default .cm-meta {color: #555;}
+.cm-s-default .cm-qualifier {color: #555;}
+.cm-s-default .cm-builtin {color: #30a;}
+.cm-s-default .cm-bracket {color: #997;}
+.cm-s-default .cm-tag {color: #170;}
+.cm-s-default .cm-attribute {color: #00c;}
+.cm-s-default .cm-header {color: blue;}
+.cm-s-default .cm-quote {color: #090;}
+.cm-s-default .cm-hr {color: #999;}
+.cm-s-default .cm-link {color: #00c;}
+
+.cm-negative {color: #d44;}
+.cm-positive {color: #292;}
+.cm-header, .cm-strong {font-weight: bold;}
+.cm-em {font-style: italic;}
+.cm-link {text-decoration: underline;}
+
+.cm-s-default .cm-error {color: #f00;}
+.cm-invalidchar {color: #f00;}
+
+div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
+div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
+.CodeMirror-activeline-background {background: #e8f2ff;}
+
+/* STOP */
+
+/* The rest of this file contains styles related to the mechanics of
+   the editor. You probably shouldn't touch them. */
+
+.CodeMirror {
+  line-height: 1;
+  position: relative;
+  overflow: hidden;
+  background: white;
+  color: black;
+}
+
+.CodeMirror-scroll {
+  /* 30px is the magic margin used to hide the element's real scrollbars */
+  /* See overflow: hidden in .CodeMirror */
+  margin-bottom: -30px; margin-right: -30px;
+  padding-bottom: 30px;
+  height: 100%;
+  outline: none; /* Prevent dragging from highlighting the element */
+  position: relative;
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
+}
+.CodeMirror-sizer {
+  position: relative;
+  border-right: 30px solid transparent;
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
+}
+
+/* The fake, visible scrollbars. Used to force redraw during scrolling
+   before actuall scrolling happens, thus preventing shaking and
+   flickering artifacts. */
+.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
+  position: absolute;
+  z-index: 6;
+  display: none;
+}
+.CodeMirror-vscrollbar {
+  right: 0; top: 0;
+  overflow-x: hidden;
+  overflow-y: scroll;
+}
+.CodeMirror-hscrollbar {
+  bottom: 0; left: 0;
+  overflow-y: hidden;
+  overflow-x: scroll;
+}
+.CodeMirror-scrollbar-filler {
+  right: 0; bottom: 0;
+}
+.CodeMirror-gutter-filler {
+  left: 0; bottom: 0;
+}
+
+.CodeMirror-gutters {
+  position: absolute; left: 0; top: 0;
+  padding-bottom: 30px;
+  z-index: 3;
+}
+.CodeMirror-gutter {
+  white-space: normal;
+  height: 100%;
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
+  padding-bottom: 30px;
+  margin-bottom: -32px;
+  display: inline-block;
+  /* Hack to make IE7 behave */
+  *zoom:1;
+  *display:inline;
+}
+.CodeMirror-gutter-elt {
+  position: absolute;
+  cursor: default;
+  z-index: 4;
+}
+
+.CodeMirror-lines {
+  cursor: text;
+}
+.CodeMirror pre {
+  /* Reset some styles that the rest of the page might have set */
+  -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
+  border-width: 0;
+  background: transparent;
+  font-family: inherit;
+  font-size: inherit;
+  margin: 0;
+  white-space: pre;
+  word-wrap: normal;
+  line-height: inherit;
+  color: inherit;
+  z-index: 2;
+  position: relative;
+  overflow: visible;
+}
+.CodeMirror-wrap pre {
+  word-wrap: break-word;
+  white-space: pre-wrap;
+  word-break: normal;
+}
+
+.CodeMirror-linebackground {
+  position: absolute;
+  left: 0; right: 0; top: 0; bottom: 0;
+  z-index: 0;
+}
+
+.CodeMirror-linewidget {
+  position: relative;
+  z-index: 2;
+  overflow: auto;
+}
+
+.CodeMirror-widget {}
+
+.CodeMirror-wrap .CodeMirror-scroll {
+  overflow-x: hidden;
+}
+
+.CodeMirror-measure {
+  position: absolute;
+  width: 100%;
+  height: 0;
+  overflow: hidden;
+  visibility: hidden;
+}
+.CodeMirror-measure pre { position: static; }
+
+.CodeMirror div.CodeMirror-cursor {
+  position: absolute;
+  border-right: none;
+  width: 0;
+}
+
+div.CodeMirror-cursors {
+  visibility: hidden;
+  position: relative;
+  z-index: 1;
+}
+.CodeMirror-focused div.CodeMirror-cursors {
+  visibility: visible;
+}
+
+.CodeMirror-selected { background: #d9d9d9; }
+.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
+
+.cm-searching {
+  background: #ffa;
+  background: rgba(255, 255, 0, .4);
+}
+
+/* IE7 hack to prevent it from returning funny offsetTops on the spans */
+.CodeMirror span { *vertical-align: text-bottom; }
+
+/* Used to force a border model for a node */
+.cm-force-border { padding-right: .1px; }
+
+ at media print {
+  /* Hide the cursor when printing */
+  .CodeMirror div.CodeMirror-cursors {
+    visibility: hidden;
+  }
+}
diff --git a/app/gui/html/vendor/codemirror/lib/codemirror.js b/app/gui/html/vendor/codemirror/lib/codemirror.js
new file mode 100644
index 0000000..c3205cc
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/lib/codemirror.js
@@ -0,0 +1,7339 @@
+// This is CodeMirror (http://codemirror.net), a code editor
+// implemented in JavaScript on top of the browser's DOM.
+//
+// You can find some technical background for some of the code below
+// at http://marijnhaverbeke.nl/blog/#cm-internals .
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    module.exports = mod();
+  else if (typeof define == "function" && define.amd) // AMD
+    return define([], mod);
+  else // Plain browser env
+    this.CodeMirror = mod();
+})(function() {
+  "use strict";
+
+  // BROWSER SNIFFING
+
+  // Kludges for bugs and behavior differences that can't be feature
+  // detected are enabled based on userAgent etc sniffing.
+
+  var gecko = /gecko\/\d/i.test(navigator.userAgent);
+  // ie_uptoN means Internet Explorer version N or lower
+  var ie_upto10 = /MSIE \d/.test(navigator.userAgent);
+  var ie_upto7 = ie_upto10 && (document.documentMode == null || document.documentMode < 8);
+  var ie_upto8 = ie_upto10 && (document.documentMode == null || document.documentMode < 9);
+  var ie_upto9 = ie_upto10 && (document.documentMode == null || document.documentMode < 10);
+  var ie_11up = /Trident\/([7-9]|\d{2,})\./.test(navigator.userAgent);
+  var ie = ie_upto10 || ie_11up;
+  var webkit = /WebKit\//.test(navigator.userAgent);
+  var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
+  var chrome = /Chrome\//.test(navigator.userAgent);
+  var presto = /Opera\//.test(navigator.userAgent);
+  var safari = /Apple Computer/.test(navigator.vendor);
+  var khtml = /KHTML\//.test(navigator.userAgent);
+  var mac_geLion = /Mac OS X 1\d\D([7-9]|\d\d)\D/.test(navigator.userAgent);
+  var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
+  var phantom = /PhantomJS/.test(navigator.userAgent);
+
+  var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
+  // This is woefully incomplete. Suggestions for alternative methods welcome.
+  var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
+  var mac = ios || /Mac/.test(navigator.platform);
+  var windows = /win/i.test(navigator.platform);
+
+  var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
+  if (presto_version) presto_version = Number(presto_version[1]);
+  if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
+  // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
+  var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));
+  var captureRightClick = gecko || (ie && !ie_upto8);
+
+  // Optimize some code when these features are not used.
+  var sawReadOnlySpans = false, sawCollapsedSpans = false;
+
+  // EDITOR CONSTRUCTOR
+
+  // A CodeMirror instance represents an editor. This is the object
+  // that user code is usually dealing with.
+
+  function CodeMirror(place, options) {
+    if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
+
+    this.options = options = options || {};
+    // Determine effective options based on given values and defaults.
+    for (var opt in defaults) if (!options.hasOwnProperty(opt))
+      options[opt] = defaults[opt];
+    setGuttersForLineNumbers(options);
+
+    var doc = options.value;
+    if (typeof doc == "string") doc = new Doc(doc, options.mode);
+    this.doc = doc;
+
+    var display = this.display = new Display(place, doc);
+    display.wrapper.CodeMirror = this;
+    updateGutters(this);
+    themeChanged(this);
+    if (options.lineWrapping)
+      this.display.wrapper.className += " CodeMirror-wrap";
+    if (options.autofocus && !mobile) focusInput(this);
+
+    this.state = {
+      keyMaps: [],  // stores maps added by addKeyMap
+      overlays: [], // highlighting overlays, as added by addOverlay
+      modeGen: 0,   // bumped when mode/overlay changes, used to invalidate highlighting info
+      overwrite: false, focused: false,
+      suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
+      pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in readInput
+      draggingText: false,
+      highlight: new Delayed() // stores highlight worker timeout
+    };
+
+    // Override magic textarea content restore that IE sometimes does
+    // on our hidden textarea on reload
+    if (ie_upto10) setTimeout(bind(resetInput, this, true), 20);
+
+    registerEventHandlers(this);
+
+    var cm = this;
+    runInOp(this, function() {
+      cm.curOp.forceUpdate = true;
+      attachDoc(cm, doc);
+
+      if ((options.autofocus && !mobile) || activeElt() == display.input)
+        setTimeout(bind(onFocus, cm), 20);
+      else
+        onBlur(cm);
+
+      for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))
+        optionHandlers[opt](cm, options[opt], Init);
+      for (var i = 0; i < initHooks.length; ++i) initHooks[i](cm);
+    });
+  }
+
+  // DISPLAY CONSTRUCTOR
+
+  // The display handles the DOM integration, both for input reading
+  // and content drawing. It holds references to DOM nodes and
+  // display-related state.
+
+  function Display(place, doc) {
+    var d = this;
+
+    // The semihidden textarea that is focused when the editor is
+    // focused, and receives input.
+    var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none");
+    // The textarea is kept positioned near the cursor to prevent the
+    // fact that it'll be scrolled into view on input from scrolling
+    // our fake cursor out of view. On webkit, when wrap=off, paste is
+    // very slow. So make the area wide instead.
+    if (webkit) input.style.width = "1000px";
+    else input.setAttribute("wrap", "off");
+    // If border: 0; -- iOS fails to open keyboard (issue #1287)
+    if (ios) input.style.border = "1px solid black";
+    input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false");
+
+    // Wraps and hides input textarea
+    d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
+    // The fake scrollbar elements.
+    d.scrollbarH = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
+    d.scrollbarV = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
+    // Covers bottom-right square when both scrollbars are present.
+    d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
+    // Covers bottom of gutter when coverGutterNextToScrollbar is on
+    // and h scrollbar is present.
+    d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
+    // Will contain the actual code, positioned to cover the viewport.
+    d.lineDiv = elt("div", null, "CodeMirror-code");
+    // Elements are added to these to represent selection and cursors.
+    d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
+    d.cursorDiv = elt("div", null, "CodeMirror-cursors");
+    // A visibility: hidden element used to find the size of things.
+    d.measure = elt("div", null, "CodeMirror-measure");
+    // When lines outside of the viewport are measured, they are drawn in this.
+    d.lineMeasure = elt("div", null, "CodeMirror-measure");
+    // Wraps everything that needs to exist inside the vertically-padded coordinate system
+    d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
+                      null, "position: relative; outline: none");
+    // Moved around its parent to cover visible view.
+    d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
+    // Set to the height of the document, allowing scrolling.
+    d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
+    // Behavior of elts with overflow: auto and padding is
+    // inconsistent across browsers. This is used to ensure the
+    // scrollable area is big enough.
+    d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;");
+    // Will contain the gutters, if any.
+    d.gutters = elt("div", null, "CodeMirror-gutters");
+    d.lineGutter = null;
+    // Actual scrollable element.
+    d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
+    d.scroller.setAttribute("tabIndex", "-1");
+    // The element in which the editor lives.
+    d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV,
+                            d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
+
+    // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
+    if (ie_upto7) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
+    // Needed to hide big blue blinking cursor on Mobile Safari
+    if (ios) input.style.width = "0px";
+    if (!webkit) d.scroller.draggable = true;
+    // Needed to handle Tab key in KHTML
+    if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
+    // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
+    if (ie_upto7) d.scrollbarH.style.minHeight = d.scrollbarV.style.minWidth = "18px";
+
+    if (place.appendChild) place.appendChild(d.wrapper);
+    else place(d.wrapper);
+
+    // Current rendered range (may be bigger than the view window).
+    d.viewFrom = d.viewTo = doc.first;
+    // Information about the rendered lines.
+    d.view = [];
+    // Holds info about a single rendered line when it was rendered
+    // for measurement, while not in view.
+    d.externalMeasured = null;
+    // Empty space (in pixels) above the view
+    d.viewOffset = 0;
+    d.lastSizeC = 0;
+    d.updateLineNumbers = null;
+
+    // Used to only resize the line number gutter when necessary (when
+    // the amount of lines crosses a boundary that makes its width change)
+    d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
+    // See readInput and resetInput
+    d.prevInput = "";
+    // Set to true when a non-horizontal-scrolling line widget is
+    // added. As an optimization, line widget aligning is skipped when
+    // this is false.
+    d.alignWidgets = false;
+    // Flag that indicates whether we expect input to appear real soon
+    // now (after some event like 'keypress' or 'input') and are
+    // polling intensively.
+    d.pollingFast = false;
+    // Self-resetting timeout for the poller
+    d.poll = new Delayed();
+
+    d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
+
+    // Tracks when resetInput has punted to just putting a short
+    // string into the textarea instead of the full selection.
+    d.inaccurateSelection = false;
+
+    // Tracks the maximum line length so that the horizontal scrollbar
+    // can be kept static when scrolling.
+    d.maxLine = null;
+    d.maxLineLength = 0;
+    d.maxLineChanged = false;
+
+    // Used for measuring wheel scrolling granularity
+    d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
+
+    // True when shift is held down.
+    d.shift = false;
+  }
+
+  // STATE UPDATES
+
+  // Used to get the editor into a consistent state again when options change.
+
+  function loadMode(cm) {
+    cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
+    resetModeState(cm);
+  }
+
+  function resetModeState(cm) {
+    cm.doc.iter(function(line) {
+      if (line.stateAfter) line.stateAfter = null;
+      if (line.styles) line.styles = null;
+    });
+    cm.doc.frontier = cm.doc.first;
+    startWorker(cm, 100);
+    cm.state.modeGen++;
+    if (cm.curOp) regChange(cm);
+  }
+
+  function wrappingChanged(cm) {
+    if (cm.options.lineWrapping) {
+      cm.display.wrapper.className += " CodeMirror-wrap";
+      cm.display.sizer.style.minWidth = "";
+    } else {
+      cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-wrap", "");
+      findMaxLine(cm);
+    }
+    estimateLineHeights(cm);
+    regChange(cm);
+    clearCaches(cm);
+    setTimeout(function(){updateScrollbars(cm);}, 100);
+  }
+
+  // Returns a function that estimates the height of a line, to use as
+  // first approximation until the line becomes visible (and is thus
+  // properly measurable).
+  function estimateHeight(cm) {
+    var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
+    var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
+    return function(line) {
+      if (lineIsHidden(cm.doc, line)) return 0;
+
+      var widgetsHeight = 0;
+      if (line.widgets) for (var i = 0; i < line.widgets.length; i++) {
+        if (line.widgets[i].height) widgetsHeight += line.widgets[i].height;
+      }
+
+      if (wrapping)
+        return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th;
+      else
+        return widgetsHeight + th;
+    };
+  }
+
+  function estimateLineHeights(cm) {
+    var doc = cm.doc, est = estimateHeight(cm);
+    doc.iter(function(line) {
+      var estHeight = est(line);
+      if (estHeight != line.height) updateLineHeight(line, estHeight);
+    });
+  }
+
+  function keyMapChanged(cm) {
+    var map = keyMap[cm.options.keyMap], style = map.style;
+    cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
+      (style ? " cm-keymap-" + style : "");
+  }
+
+  function themeChanged(cm) {
+    cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
+      cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
+    clearCaches(cm);
+  }
+
+  function guttersChanged(cm) {
+    updateGutters(cm);
+    regChange(cm);
+    setTimeout(function(){alignHorizontally(cm);}, 20);
+  }
+
+  // Rebuild the gutter elements, ensure the margin to the left of the
+  // code matches their width.
+  function updateGutters(cm) {
+    var gutters = cm.display.gutters, specs = cm.options.gutters;
+    removeChildren(gutters);
+    for (var i = 0; i < specs.length; ++i) {
+      var gutterClass = specs[i];
+      var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
+      if (gutterClass == "CodeMirror-linenumbers") {
+        cm.display.lineGutter = gElt;
+        gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
+      }
+    }
+    gutters.style.display = i ? "" : "none";
+    var width = gutters.offsetWidth;
+    cm.display.sizer.style.marginLeft = width + "px";
+    if (i) cm.display.scrollbarH.style.left = cm.options.fixedGutter ? width + "px" : 0;
+  }
+
+  // Compute the character length of a line, taking into account
+  // collapsed ranges (see markText) that might hide parts, and join
+  // other lines onto it.
+  function lineLength(line) {
+    if (line.height == 0) return 0;
+    var len = line.text.length, merged, cur = line;
+    while (merged = collapsedSpanAtStart(cur)) {
+      var found = merged.find(0, true);
+      cur = found.from.line;
+      len += found.from.ch - found.to.ch;
+    }
+    cur = line;
+    while (merged = collapsedSpanAtEnd(cur)) {
+      var found = merged.find(0, true);
+      len -= cur.text.length - found.from.ch;
+      cur = found.to.line;
+      len += cur.text.length - found.to.ch;
+    }
+    return len;
+  }
+
+  // Find the longest line in the document.
+  function findMaxLine(cm) {
+    var d = cm.display, doc = cm.doc;
+    d.maxLine = getLine(doc, doc.first);
+    d.maxLineLength = lineLength(d.maxLine);
+    d.maxLineChanged = true;
+    doc.iter(function(line) {
+      var len = lineLength(line);
+      if (len > d.maxLineLength) {
+        d.maxLineLength = len;
+        d.maxLine = line;
+      }
+    });
+  }
+
+  // Make sure the gutters options contains the element
+  // "CodeMirror-linenumbers" when the lineNumbers option is true.
+  function setGuttersForLineNumbers(options) {
+    var found = indexOf(options.gutters, "CodeMirror-linenumbers");
+    if (found == -1 && options.lineNumbers) {
+      options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
+    } else if (found > -1 && !options.lineNumbers) {
+      options.gutters = options.gutters.slice(0);
+      options.gutters.splice(found, 1);
+    }
+  }
+
+  // SCROLLBARS
+
+  // Prepare DOM reads needed to update the scrollbars. Done in one
+  // shot to minimize update/measure roundtrips.
+  function measureForScrollbars(cm) {
+    var scroll = cm.display.scroller;
+    return {
+      clientHeight: scroll.clientHeight,
+      barHeight: cm.display.scrollbarV.clientHeight,
+      scrollWidth: scroll.scrollWidth, clientWidth: scroll.clientWidth,
+      barWidth: cm.display.scrollbarH.clientWidth,
+      docHeight: Math.round(cm.doc.height + paddingVert(cm.display))
+    };
+  }
+
+  // Re-synchronize the fake scrollbars with the actual size of the
+  // content.
+  function updateScrollbars(cm, measure) {
+    if (!measure) measure = measureForScrollbars(cm);
+    var d = cm.display;
+    var scrollHeight = measure.docHeight + scrollerCutOff;
+    var needsH = measure.scrollWidth > measure.clientWidth;
+    var needsV = scrollHeight > measure.clientHeight;
+    if (needsV) {
+      d.scrollbarV.style.display = "block";
+      d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0";
+      // A bug in IE8 can cause this value to be negative, so guard it.
+      d.scrollbarV.firstChild.style.height =
+        Math.max(0, scrollHeight - measure.clientHeight + (measure.barHeight || d.scrollbarV.clientHeight)) + "px";
+    } else {
+      d.scrollbarV.style.display = "";
+      d.scrollbarV.firstChild.style.height = "0";
+    }
+    if (needsH) {
+      d.scrollbarH.style.display = "block";
+      d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0";
+      d.scrollbarH.firstChild.style.width =
+        (measure.scrollWidth - measure.clientWidth + (measure.barWidth || d.scrollbarH.clientWidth)) + "px";
+    } else {
+      d.scrollbarH.style.display = "";
+      d.scrollbarH.firstChild.style.width = "0";
+    }
+    if (needsH && needsV) {
+      d.scrollbarFiller.style.display = "block";
+      d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px";
+    } else d.scrollbarFiller.style.display = "";
+    if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
+      d.gutterFiller.style.display = "block";
+      d.gutterFiller.style.height = scrollbarWidth(d.measure) + "px";
+      d.gutterFiller.style.width = d.gutters.offsetWidth + "px";
+    } else d.gutterFiller.style.display = "";
+
+    if (mac_geLion && scrollbarWidth(d.measure) === 0) {
+      d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px";
+      var barMouseDown = function(e) {
+        if (e_target(e) != d.scrollbarV && e_target(e) != d.scrollbarH)
+          operation(cm, onMouseDown)(e);
+      };
+      on(d.scrollbarV, "mousedown", barMouseDown);
+      on(d.scrollbarH, "mousedown", barMouseDown);
+    }
+  }
+
+  // Compute the lines that are visible in a given viewport (defaults
+  // the the current scroll position). viewPort may contain top,
+  // height, and ensure (see op.scrollToPos) properties.
+  function visibleLines(display, doc, viewPort) {
+    var top = viewPort && viewPort.top != null ? viewPort.top : display.scroller.scrollTop;
+    top = Math.floor(top - paddingTop(display));
+    var bottom = viewPort && viewPort.bottom != null ? viewPort.bottom : top + display.wrapper.clientHeight;
+
+    var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);
+    // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
+    // forces those lines into the viewport (if possible).
+    if (viewPort && viewPort.ensure) {
+      var ensureFrom = viewPort.ensure.from.line, ensureTo = viewPort.ensure.to.line;
+      if (ensureFrom < from)
+        return {from: ensureFrom,
+                to: lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight)};
+      if (Math.min(ensureTo, doc.lastLine()) >= to)
+        return {from: lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight),
+                to: ensureTo};
+    }
+    return {from: from, to: to};
+  }
+
+  // LINE NUMBERS
+
+  // Re-align line numbers and gutter marks to compensate for
+  // horizontal scrolling.
+  function alignHorizontally(cm) {
+    var display = cm.display, view = display.view;
+    if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
+    var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
+    var gutterW = display.gutters.offsetWidth, left = comp + "px";
+    for (var i = 0; i < view.length; i++) if (!view[i].hidden) {
+      if (cm.options.fixedGutter && view[i].gutter)
+        view[i].gutter.style.left = left;
+      var align = view[i].alignable;
+      if (align) for (var j = 0; j < align.length; j++)
+        align[j].style.left = left;
+    }
+    if (cm.options.fixedGutter)
+      display.gutters.style.left = (comp + gutterW) + "px";
+  }
+
+  // Used to ensure that the line number gutter is still the right
+  // size for the current document size. Returns true when an update
+  // is needed.
+  function maybeUpdateLineNumberWidth(cm) {
+    if (!cm.options.lineNumbers) return false;
+    var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
+    if (last.length != display.lineNumChars) {
+      var test = display.measure.appendChild(elt("div", [elt("div", last)],
+                                                 "CodeMirror-linenumber CodeMirror-gutter-elt"));
+      var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
+      display.lineGutter.style.width = "";
+      display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding);
+      display.lineNumWidth = display.lineNumInnerWidth + padding;
+      display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
+      display.lineGutter.style.width = display.lineNumWidth + "px";
+      var width = display.gutters.offsetWidth;
+      display.scrollbarH.style.left = cm.options.fixedGutter ? width + "px" : 0;
+      display.sizer.style.marginLeft = width + "px";
+      return true;
+    }
+    return false;
+  }
+
+  function lineNumberFor(options, i) {
+    return String(options.lineNumberFormatter(i + options.firstLineNumber));
+  }
+
+  // Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
+  // but using getBoundingClientRect to get a sub-pixel-accurate
+  // result.
+  function compensateForHScroll(display) {
+    return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left;
+  }
+
+  // DISPLAY DRAWING
+
+  // Updates the display, selection, and scrollbars, using the
+  // information in display.view to find out which nodes are no longer
+  // up-to-date. Tries to bail out early when no changes are needed,
+  // unless forced is true.
+  // Returns true if an actual update happened, false otherwise.
+  function updateDisplay(cm, viewPort, forced) {
+    var oldFrom = cm.display.viewFrom, oldTo = cm.display.viewTo, updated;
+    var visible = visibleLines(cm.display, cm.doc, viewPort);
+    for (var first = true;; first = false) {
+      var oldWidth = cm.display.scroller.clientWidth;
+      if (!updateDisplayInner(cm, visible, forced)) break;
+      updated = true;
+
+      // If the max line changed since it was last measured, measure it,
+      // and ensure the document's width matches it.
+      if (cm.display.maxLineChanged && !cm.options.lineWrapping)
+        adjustContentWidth(cm);
+
+      var barMeasure = measureForScrollbars(cm);
+      updateSelection(cm);
+      setDocumentHeight(cm, barMeasure);
+      updateScrollbars(cm, barMeasure);
+      if (first && cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) {
+        forced = true;
+        continue;
+      }
+      forced = false;
+
+      // Clip forced viewport to actual scrollable area.
+      if (viewPort && viewPort.top != null)
+        viewPort = {top: Math.min(barMeasure.docHeight - scrollerCutOff - barMeasure.clientHeight, viewPort.top)};
+      // Updated line heights might result in the drawn area not
+      // actually covering the viewport. Keep looping until it does.
+      visible = visibleLines(cm.display, cm.doc, viewPort);
+      if (visible.from >= cm.display.viewFrom && visible.to <= cm.display.viewTo)
+        break;
+    }
+
+    cm.display.updateLineNumbers = null;
+    if (updated) {
+      signalLater(cm, "update", cm);
+      if (cm.display.viewFrom != oldFrom || cm.display.viewTo != oldTo)
+        signalLater(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
+    }
+    return updated;
+  }
+
+  // Does the actual updating of the line display. Bails out
+  // (returning false) when there is nothing to be done and forced is
+  // false.
+  function updateDisplayInner(cm, visible, forced) {
+    var display = cm.display, doc = cm.doc;
+    if (!display.wrapper.offsetWidth) {
+      resetView(cm);
+      return;
+    }
+
+    // Bail out if the visible area is already rendered and nothing changed.
+    if (!forced && visible.from >= display.viewFrom && visible.to <= display.viewTo &&
+        countDirtyView(cm) == 0)
+      return;
+
+    if (maybeUpdateLineNumberWidth(cm))
+      resetView(cm);
+    var dims = getDimensions(cm);
+
+    // Compute a suitable new viewport (from & to)
+    var end = doc.first + doc.size;
+    var from = Math.max(visible.from - cm.options.viewportMargin, doc.first);
+    var to = Math.min(end, visible.to + cm.options.viewportMargin);
+    if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom);
+    if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo);
+    if (sawCollapsedSpans) {
+      from = visualLineNo(cm.doc, from);
+      to = visualLineEndNo(cm.doc, to);
+    }
+
+    var different = from != display.viewFrom || to != display.viewTo ||
+      display.lastSizeC != display.wrapper.clientHeight;
+    adjustView(cm, from, to);
+
+    display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
+    // Position the mover div to align with the current scroll position
+    cm.display.mover.style.top = display.viewOffset + "px";
+
+    var toUpdate = countDirtyView(cm);
+    if (!different && toUpdate == 0 && !forced) return;
+
+    // For big changes, we hide the enclosing element during the
+    // update, since that speeds up the operations on most browsers.
+    var focused = activeElt();
+    if (toUpdate > 4) display.lineDiv.style.display = "none";
+    patchDisplay(cm, display.updateLineNumbers, dims);
+    if (toUpdate > 4) display.lineDiv.style.display = "";
+    // There might have been a widget with a focused element that got
+    // hidden or updated, if so re-focus it.
+    if (focused && activeElt() != focused && focused.offsetHeight) focused.focus();
+
+    // Prevent selection and cursors from interfering with the scroll
+    // width.
+    removeChildren(display.cursorDiv);
+    removeChildren(display.selectionDiv);
+
+    if (different) {
+      display.lastSizeC = display.wrapper.clientHeight;
+      startWorker(cm, 400);
+    }
+
+    updateHeightsInViewport(cm);
+
+    return true;
+  }
+
+  function adjustContentWidth(cm) {
+    var display = cm.display;
+    var width = measureChar(cm, display.maxLine, display.maxLine.text.length).left;
+    display.maxLineChanged = false;
+    var minWidth = Math.max(0, width + 3);
+    var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + minWidth + scrollerCutOff - display.scroller.clientWidth);
+    display.sizer.style.minWidth = minWidth + "px";
+    if (maxScrollLeft < cm.doc.scrollLeft)
+      setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true);
+  }
+
+  function setDocumentHeight(cm, measure) {
+    cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = measure.docHeight + "px";
+    cm.display.gutters.style.height = Math.max(measure.docHeight, measure.clientHeight - scrollerCutOff) + "px";
+  }
+
+  // Read the actual heights of the rendered lines, and update their
+  // stored heights to match.
+  function updateHeightsInViewport(cm) {
+    var display = cm.display;
+    var prevBottom = display.lineDiv.offsetTop;
+    for (var i = 0; i < display.view.length; i++) {
+      var cur = display.view[i], height;
+      if (cur.hidden) continue;
+      if (ie_upto7) {
+        var bot = cur.node.offsetTop + cur.node.offsetHeight;
+        height = bot - prevBottom;
+        prevBottom = bot;
+      } else {
+        var box = cur.node.getBoundingClientRect();
+        height = box.bottom - box.top;
+      }
+      var diff = cur.line.height - height;
+      if (height < 2) height = textHeight(display);
+      if (diff > .001 || diff < -.001) {
+        updateLineHeight(cur.line, height);
+        updateWidgetHeight(cur.line);
+        if (cur.rest) for (var j = 0; j < cur.rest.length; j++)
+          updateWidgetHeight(cur.rest[j]);
+      }
+    }
+  }
+
+  // Read and store the height of line widgets associated with the
+  // given line.
+  function updateWidgetHeight(line) {
+    if (line.widgets) for (var i = 0; i < line.widgets.length; ++i)
+      line.widgets[i].height = line.widgets[i].node.offsetHeight;
+  }
+
+  // Do a bulk-read of the DOM positions and sizes needed to draw the
+  // view, so that we don't interleave reading and writing to the DOM.
+  function getDimensions(cm) {
+    var d = cm.display, left = {}, width = {};
+    for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
+      left[cm.options.gutters[i]] = n.offsetLeft;
+      width[cm.options.gutters[i]] = n.offsetWidth;
+    }
+    return {fixedPos: compensateForHScroll(d),
+            gutterTotalWidth: d.gutters.offsetWidth,
+            gutterLeft: left,
+            gutterWidth: width,
+            wrapperWidth: d.wrapper.clientWidth};
+  }
+
+  // Sync the actual display DOM structure with display.view, removing
+  // nodes for lines that are no longer in view, and creating the ones
+  // that are not there yet, and updating the ones that are out of
+  // date.
+  function patchDisplay(cm, updateNumbersFrom, dims) {
+    var display = cm.display, lineNumbers = cm.options.lineNumbers;
+    var container = display.lineDiv, cur = container.firstChild;
+
+    function rm(node) {
+      var next = node.nextSibling;
+      // Works around a throw-scroll bug in OS X Webkit
+      if (webkit && mac && cm.display.currentWheelTarget == node)
+        node.style.display = "none";
+      else
+        node.parentNode.removeChild(node);
+      return next;
+    }
+
+    var view = display.view, lineN = display.viewFrom;
+    // Loop over the elements in the view, syncing cur (the DOM nodes
+    // in display.lineDiv) with the view as we go.
+    for (var i = 0; i < view.length; i++) {
+      var lineView = view[i];
+      if (lineView.hidden) {
+      } else if (!lineView.node) { // Not drawn yet
+        var node = buildLineElement(cm, lineView, lineN, dims);
+        container.insertBefore(node, cur);
+      } else { // Already drawn
+        while (cur != lineView.node) cur = rm(cur);
+        var updateNumber = lineNumbers && updateNumbersFrom != null &&
+          updateNumbersFrom <= lineN && lineView.lineNumber;
+        if (lineView.changes) {
+          if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false;
+          updateLineForChanges(cm, lineView, lineN, dims);
+        }
+        if (updateNumber) {
+          removeChildren(lineView.lineNumber);
+          lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));
+        }
+        cur = lineView.node.nextSibling;
+      }
+      lineN += lineView.size;
+    }
+    while (cur) cur = rm(cur);
+  }
+
+  // When an aspect of a line changes, a string is added to
+  // lineView.changes. This updates the relevant part of the line's
+  // DOM structure.
+  function updateLineForChanges(cm, lineView, lineN, dims) {
+    for (var j = 0; j < lineView.changes.length; j++) {
+      var type = lineView.changes[j];
+      if (type == "text") updateLineText(cm, lineView);
+      else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims);
+      else if (type == "class") updateLineClasses(lineView);
+      else if (type == "widget") updateLineWidgets(lineView, dims);
+    }
+    lineView.changes = null;
+  }
+
+  // Lines with gutter elements, widgets or a background class need to
+  // be wrapped, and have the extra elements added to the wrapper div
+  function ensureLineWrapped(lineView) {
+    if (lineView.node == lineView.text) {
+      lineView.node = elt("div", null, null, "position: relative");
+      if (lineView.text.parentNode)
+        lineView.text.parentNode.replaceChild(lineView.node, lineView.text);
+      lineView.node.appendChild(lineView.text);
+      if (ie_upto7) lineView.node.style.zIndex = 2;
+    }
+    return lineView.node;
+  }
+
+  function updateLineBackground(lineView) {
+    var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass;
+    if (cls) cls += " CodeMirror-linebackground";
+    if (lineView.background) {
+      if (cls) lineView.background.className = cls;
+      else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }
+    } else if (cls) {
+      var wrap = ensureLineWrapped(lineView);
+      lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild);
+    }
+  }
+
+  // Wrapper around buildLineContent which will reuse the structure
+  // in display.externalMeasured when possible.
+  function getLineContent(cm, lineView) {
+    var ext = cm.display.externalMeasured;
+    if (ext && ext.line == lineView.line) {
+      cm.display.externalMeasured = null;
+      lineView.measure = ext.measure;
+      return ext.built;
+    }
+    return buildLineContent(cm, lineView);
+  }
+
+  // Redraw the line's text. Interacts with the background and text
+  // classes because the mode may output tokens that influence these
+  // classes.
+  function updateLineText(cm, lineView) {
+    var cls = lineView.text.className;
+    var built = getLineContent(cm, lineView);
+    if (lineView.text == lineView.node) lineView.node = built.pre;
+    lineView.text.parentNode.replaceChild(built.pre, lineView.text);
+    lineView.text = built.pre;
+    if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {
+      lineView.bgClass = built.bgClass;
+      lineView.textClass = built.textClass;
+      updateLineClasses(lineView);
+    } else if (cls) {
+      lineView.text.className = cls;
+    }
+  }
+
+  function updateLineClasses(lineView) {
+    updateLineBackground(lineView);
+    if (lineView.line.wrapClass)
+      ensureLineWrapped(lineView).className = lineView.line.wrapClass;
+    else if (lineView.node != lineView.text)
+      lineView.node.className = "";
+    var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass;
+    lineView.text.className = textClass || "";
+  }
+
+  function updateLineGutter(cm, lineView, lineN, dims) {
+    if (lineView.gutter) {
+      lineView.node.removeChild(lineView.gutter);
+      lineView.gutter = null;
+    }
+    var markers = lineView.line.gutterMarkers;
+    if (cm.options.lineNumbers || markers) {
+      var wrap = ensureLineWrapped(lineView);
+      var gutterWrap = lineView.gutter =
+        wrap.insertBefore(elt("div", null, "CodeMirror-gutter-wrapper", "position: absolute; left: " +
+                              (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"),
+                          lineView.text);
+      if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
+        lineView.lineNumber = gutterWrap.appendChild(
+          elt("div", lineNumberFor(cm.options, lineN),
+              "CodeMirror-linenumber CodeMirror-gutter-elt",
+              "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
+              + cm.display.lineNumInnerWidth + "px"));
+      if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) {
+        var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
+        if (found)
+          gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
+                                     dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
+      }
+    }
+  }
+
+  function updateLineWidgets(lineView, dims) {
+    if (lineView.alignable) lineView.alignable = null;
+    for (var node = lineView.node.firstChild, next; node; node = next) {
+      var next = node.nextSibling;
+      if (node.className == "CodeMirror-linewidget")
+        lineView.node.removeChild(node);
+    }
+    insertLineWidgets(lineView, dims);
+  }
+
+  // Build a line's DOM representation from scratch
+  function buildLineElement(cm, lineView, lineN, dims) {
+    var built = getLineContent(cm, lineView);
+    lineView.text = lineView.node = built.pre;
+    if (built.bgClass) lineView.bgClass = built.bgClass;
+    if (built.textClass) lineView.textClass = built.textClass;
+
+    updateLineClasses(lineView);
+    updateLineGutter(cm, lineView, lineN, dims);
+    insertLineWidgets(lineView, dims);
+    return lineView.node;
+  }
+
+  // A lineView may contain multiple logical lines (when merged by
+  // collapsed spans). The widgets for all of them need to be drawn.
+  function insertLineWidgets(lineView, dims) {
+    insertLineWidgetsFor(lineView.line, lineView, dims, true);
+    if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
+      insertLineWidgetsFor(lineView.rest[i], lineView, dims, false);
+  }
+
+  function insertLineWidgetsFor(line, lineView, dims, allowAbove) {
+    if (!line.widgets) return;
+    var wrap = ensureLineWrapped(lineView);
+    for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
+      var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
+      if (!widget.handleMouseEvents) node.ignoreEvents = true;
+      positionLineWidget(widget, node, lineView, dims);
+      if (allowAbove && widget.above)
+        wrap.insertBefore(node, lineView.gutter || lineView.text);
+      else
+        wrap.appendChild(node);
+      signalLater(widget, "redraw");
+    }
+  }
+
+  function positionLineWidget(widget, node, lineView, dims) {
+    if (widget.noHScroll) {
+      (lineView.alignable || (lineView.alignable = [])).push(node);
+      var width = dims.wrapperWidth;
+      node.style.left = dims.fixedPos + "px";
+      if (!widget.coverGutter) {
+        width -= dims.gutterTotalWidth;
+        node.style.paddingLeft = dims.gutterTotalWidth + "px";
+      }
+      node.style.width = width + "px";
+    }
+    if (widget.coverGutter) {
+      node.style.zIndex = 5;
+      node.style.position = "relative";
+      if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
+    }
+  }
+
+  // POSITION OBJECT
+
+  // A Pos instance represents a position within the text.
+  var Pos = CodeMirror.Pos = function(line, ch) {
+    if (!(this instanceof Pos)) return new Pos(line, ch);
+    this.line = line; this.ch = ch;
+  };
+
+  // Compare two positions, return 0 if they are the same, a negative
+  // number when a is less, and a positive number otherwise.
+  var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; };
+
+  function copyPos(x) {return Pos(x.line, x.ch);}
+  function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; }
+  function minPos(a, b) { return cmp(a, b) < 0 ? a : b; }
+
+  // SELECTION / CURSOR
+
+  // Selection objects are immutable. A new one is created every time
+  // the selection changes. A selection is one or more non-overlapping
+  // (and non-touching) ranges, sorted, and an integer that indicates
+  // which one is the primary selection (the one that's scrolled into
+  // view, that getCursor returns, etc).
+  function Selection(ranges, primIndex) {
+    this.ranges = ranges;
+    this.primIndex = primIndex;
+  }
+
+  Selection.prototype = {
+    primary: function() { return this.ranges[this.primIndex]; },
+    equals: function(other) {
+      if (other == this) return true;
+      if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false;
+      for (var i = 0; i < this.ranges.length; i++) {
+        var here = this.ranges[i], there = other.ranges[i];
+        if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false;
+      }
+      return true;
+    },
+    deepCopy: function() {
+      for (var out = [], i = 0; i < this.ranges.length; i++)
+        out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head));
+      return new Selection(out, this.primIndex);
+    },
+    somethingSelected: function() {
+      for (var i = 0; i < this.ranges.length; i++)
+        if (!this.ranges[i].empty()) return true;
+      return false;
+    },
+    contains: function(pos, end) {
+      if (!end) end = pos;
+      for (var i = 0; i < this.ranges.length; i++) {
+        var range = this.ranges[i];
+        if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
+          return i;
+      }
+      return -1;
+    }
+  };
+
+  function Range(anchor, head) {
+    this.anchor = anchor; this.head = head;
+  }
+
+  Range.prototype = {
+    from: function() { return minPos(this.anchor, this.head); },
+    to: function() { return maxPos(this.anchor, this.head); },
+    empty: function() {
+      return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch;
+    }
+  };
+
+  // Take an unsorted, potentially overlapping set of ranges, and
+  // build a selection out of it. 'Consumes' ranges array (modifying
+  // it).
+  function normalizeSelection(ranges, primIndex) {
+    var prim = ranges[primIndex];
+    ranges.sort(function(a, b) { return cmp(a.from(), b.from()); });
+    primIndex = indexOf(ranges, prim);
+    for (var i = 1; i < ranges.length; i++) {
+      var cur = ranges[i], prev = ranges[i - 1];
+      if (cmp(prev.to(), cur.from()) >= 0) {
+        var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());
+        var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;
+        if (i <= primIndex) --primIndex;
+        ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));
+      }
+    }
+    return new Selection(ranges, primIndex);
+  }
+
+  function simpleSelection(anchor, head) {
+    return new Selection([new Range(anchor, head || anchor)], 0);
+  }
+
+  // Most of the external API clips given positions to make sure they
+  // actually exist within the document.
+  function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
+  function clipPos(doc, pos) {
+    if (pos.line < doc.first) return Pos(doc.first, 0);
+    var last = doc.first + doc.size - 1;
+    if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
+    return clipToLen(pos, getLine(doc, pos.line).text.length);
+  }
+  function clipToLen(pos, linelen) {
+    var ch = pos.ch;
+    if (ch == null || ch > linelen) return Pos(pos.line, linelen);
+    else if (ch < 0) return Pos(pos.line, 0);
+    else return pos;
+  }
+  function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
+  function clipPosArray(doc, array) {
+    for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]);
+    return out;
+  }
+
+  // SELECTION UPDATES
+
+  // The 'scroll' parameter given to many of these indicated whether
+  // the new cursor position should be scrolled into view after
+  // modifying the selection.
+
+  // If shift is held or the extend flag is set, extends a range to
+  // include a given position (and optionally a second position).
+  // Otherwise, simply returns the range between the given positions.
+  // Used for cursor motion and such.
+  function extendRange(doc, range, head, other) {
+    if (doc.cm && doc.cm.display.shift || doc.extend) {
+      var anchor = range.anchor;
+      if (other) {
+        var posBefore = cmp(head, anchor) < 0;
+        if (posBefore != (cmp(other, anchor) < 0)) {
+          anchor = head;
+          head = other;
+        } else if (posBefore != (cmp(head, other) < 0)) {
+          head = other;
+        }
+      }
+      return new Range(anchor, head);
+    } else {
+      return new Range(other || head, head);
+    }
+  }
+
+  // Extend the primary selection range, discard the rest.
+  function extendSelection(doc, head, other, options) {
+    setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options);
+  }
+
+  // Extend all selections (pos is an array of selections with length
+  // equal the number of selections)
+  function extendSelections(doc, heads, options) {
+    for (var out = [], i = 0; i < doc.sel.ranges.length; i++)
+      out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null);
+    var newSel = normalizeSelection(out, doc.sel.primIndex);
+    setSelection(doc, newSel, options);
+  }
+
+  // Updates a single range in the selection.
+  function replaceOneSelection(doc, i, range, options) {
+    var ranges = doc.sel.ranges.slice(0);
+    ranges[i] = range;
+    setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options);
+  }
+
+  // Reset the selection to a single range.
+  function setSimpleSelection(doc, anchor, head, options) {
+    setSelection(doc, simpleSelection(anchor, head), options);
+  }
+
+  // Give beforeSelectionChange handlers a change to influence a
+  // selection update.
+  function filterSelectionChange(doc, sel) {
+    var obj = {
+      ranges: sel.ranges,
+      update: function(ranges) {
+        this.ranges = [];
+        for (var i = 0; i < ranges.length; i++)
+          this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
+                                     clipPos(doc, ranges[i].head));
+      }
+    };
+    signal(doc, "beforeSelectionChange", doc, obj);
+    if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
+    if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1);
+    else return sel;
+  }
+
+  function setSelectionReplaceHistory(doc, sel, options) {
+    var done = doc.history.done, last = lst(done);
+    if (last && last.ranges) {
+      done[done.length - 1] = sel;
+      setSelectionNoUndo(doc, sel, options);
+    } else {
+      setSelection(doc, sel, options);
+    }
+  }
+
+  // Set a new selection.
+  function setSelection(doc, sel, options) {
+    setSelectionNoUndo(doc, sel, options);
+    addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);
+  }
+
+  function setSelectionNoUndo(doc, sel, options) {
+    if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
+      sel = filterSelectionChange(doc, sel);
+
+    var bias = cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1;
+    setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
+
+    if (!(options && options.scroll === false) && doc.cm)
+      ensureCursorVisible(doc.cm);
+  }
+
+  function setSelectionInner(doc, sel) {
+    if (sel.equals(doc.sel)) return;
+
+    doc.sel = sel;
+
+    if (doc.cm)
+      doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged =
+        doc.cm.curOp.cursorActivity = true;
+    signalLater(doc, "cursorActivity", doc);
+  }
+
+  // Verify that the selection does not partially select any atomic
+  // marked ranges.
+  function reCheckSelection(doc) {
+    setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll);
+  }
+
+  // Return a selection that does not partially select any atomic
+  // ranges.
+  function skipAtomicInSelection(doc, sel, bias, mayClear) {
+    var out;
+    for (var i = 0; i < sel.ranges.length; i++) {
+      var range = sel.ranges[i];
+      var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear);
+      var newHead = skipAtomic(doc, range.head, bias, mayClear);
+      if (out || newAnchor != range.anchor || newHead != range.head) {
+        if (!out) out = sel.ranges.slice(0, i);
+        out[i] = new Range(newAnchor, newHead);
+      }
+    }
+    return out ? normalizeSelection(out, sel.primIndex) : sel;
+  }
+
+  // Ensure a given position is not inside an atomic range.
+  function skipAtomic(doc, pos, bias, mayClear) {
+    var flipped = false, curPos = pos;
+    var dir = bias || 1;
+    doc.cantEdit = false;
+    search: for (;;) {
+      var line = getLine(doc, curPos.line);
+      if (line.markedSpans) {
+        for (var i = 0; i < line.markedSpans.length; ++i) {
+          var sp = line.markedSpans[i], m = sp.marker;
+          if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
+              (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
+            if (mayClear) {
+              signal(m, "beforeCursorEnter");
+              if (m.explicitlyCleared) {
+                if (!line.markedSpans) break;
+                else {--i; continue;}
+              }
+            }
+            if (!m.atomic) continue;
+            var newPos = m.find(dir < 0 ? -1 : 1);
+            if (cmp(newPos, curPos) == 0) {
+              newPos.ch += dir;
+              if (newPos.ch < 0) {
+                if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
+                else newPos = null;
+              } else if (newPos.ch > line.text.length) {
+                if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
+                else newPos = null;
+              }
+              if (!newPos) {
+                if (flipped) {
+                  // Driven in a corner -- no valid cursor position found at all
+                  // -- try again *with* clearing, if we didn't already
+                  if (!mayClear) return skipAtomic(doc, pos, bias, true);
+                  // Otherwise, turn off editing until further notice, and return the start of the doc
+                  doc.cantEdit = true;
+                  return Pos(doc.first, 0);
+                }
+                flipped = true; newPos = pos; dir = -dir;
+              }
+            }
+            curPos = newPos;
+            continue search;
+          }
+        }
+      }
+      return curPos;
+    }
+  }
+
+  // SELECTION DRAWING
+
+  // Redraw the selection and/or cursor
+  function updateSelection(cm) {
+    var display = cm.display, doc = cm.doc;
+    var curFragment = document.createDocumentFragment();
+    var selFragment = document.createDocumentFragment();
+
+    for (var i = 0; i < doc.sel.ranges.length; i++) {
+      var range = doc.sel.ranges[i];
+      var collapsed = range.empty();
+      if (collapsed || cm.options.showCursorWhenSelecting)
+        updateSelectionCursor(cm, range, curFragment);
+      if (!collapsed)
+        updateSelectionRange(cm, range, selFragment);
+    }
+
+    // Move the hidden textarea near the cursor to prevent scrolling artifacts
+    if (cm.options.moveInputWithCursor) {
+      var headPos = cursorCoords(cm, doc.sel.primary().head, "div");
+      var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
+      var top = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
+                                     headPos.top + lineOff.top - wrapOff.top));
+      var left = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
+                                      headPos.left + lineOff.left - wrapOff.left));
+      display.inputDiv.style.top = top + "px";
+      display.inputDiv.style.left = left + "px";
+    }
+
+    removeChildrenAndAdd(display.cursorDiv, curFragment);
+    removeChildrenAndAdd(display.selectionDiv, selFragment);
+  }
+
+  // Draws a cursor for the given range
+  function updateSelectionCursor(cm, range, output) {
+    var pos = cursorCoords(cm, range.head, "div");
+
+    var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"));
+    cursor.style.left = pos.left + "px";
+    cursor.style.top = pos.top + "px";
+    cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
+
+    if (pos.other) {
+      // Secondary cursor, shown when on a 'jump' in bi-directional text
+      var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"));
+      otherCursor.style.display = "";
+      otherCursor.style.left = pos.other.left + "px";
+      otherCursor.style.top = pos.other.top + "px";
+      otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
+    }
+  }
+
+  // Draws the given range as a highlighted selection
+  function updateSelectionRange(cm, range, output) {
+    var display = cm.display, doc = cm.doc;
+    var fragment = document.createDocumentFragment();
+    var padding = paddingH(cm.display), leftSide = padding.left, rightSide = display.lineSpace.offsetWidth - padding.right;
+
+    function add(left, top, width, bottom) {
+      if (top < 0) top = 0;
+      fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
+                               "px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) +
+                               "px; height: " + (bottom - top) + "px"));
+    }
+
+    function drawForLine(line, fromArg, toArg) {
+      var lineObj = getLine(doc, line);
+      var lineLen = lineObj.text.length;
+      var start, end;
+      function coords(ch, bias) {
+        return charCoords(cm, Pos(line, ch), "div", lineObj, bias);
+      }
+
+      iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {
+        var leftPos = coords(from, "left"), rightPos, left, right;
+        if (from == to) {
+          rightPos = leftPos;
+          left = right = leftPos.left;
+        } else {
+          rightPos = coords(to - 1, "right");
+          if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }
+          left = leftPos.left;
+          right = rightPos.right;
+        }
+        if (fromArg == null && from == 0) left = leftSide;
+        if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
+          add(left, leftPos.top, null, leftPos.bottom);
+          left = leftSide;
+          if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
+        }
+        if (toArg == null && to == lineLen) right = rightSide;
+        if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
+          start = leftPos;
+        if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
+          end = rightPos;
+        if (left < leftSide + 1) left = leftSide;
+        add(left, rightPos.top, right - left, rightPos.bottom);
+      });
+      return {start: start, end: end};
+    }
+
+    var sFrom = range.from(), sTo = range.to();
+    if (sFrom.line == sTo.line) {
+      drawForLine(sFrom.line, sFrom.ch, sTo.ch);
+    } else {
+      var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line);
+      var singleVLine = visualLine(fromLine) == visualLine(toLine);
+      var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end;
+      var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start;
+      if (singleVLine) {
+        if (leftEnd.top < rightStart.top - 2) {
+          add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
+          add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);
+        } else {
+          add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
+        }
+      }
+      if (leftEnd.bottom < rightStart.top)
+        add(leftSide, leftEnd.bottom, null, rightStart.top);
+    }
+
+    output.appendChild(fragment);
+  }
+
+  // Cursor-blinking
+  function restartBlink(cm) {
+    if (!cm.state.focused) return;
+    var display = cm.display;
+    clearInterval(display.blinker);
+    var on = true;
+    display.cursorDiv.style.visibility = "";
+    if (cm.options.cursorBlinkRate > 0)
+      display.blinker = setInterval(function() {
+        display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden";
+      }, cm.options.cursorBlinkRate);
+  }
+
+  // HIGHLIGHT WORKER
+
+  function startWorker(cm, time) {
+    if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo)
+      cm.state.highlight.set(time, bind(highlightWorker, cm));
+  }
+
+  function highlightWorker(cm) {
+    var doc = cm.doc;
+    if (doc.frontier < doc.first) doc.frontier = doc.first;
+    if (doc.frontier >= cm.display.viewTo) return;
+    var end = +new Date + cm.options.workTime;
+    var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
+
+    runInOp(cm, function() {
+    doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) {
+      if (doc.frontier >= cm.display.viewFrom) { // Visible
+        var oldStyles = line.styles;
+        line.styles = highlightLine(cm, line, state, true);
+        var ischange = !oldStyles || oldStyles.length != line.styles.length;
+        for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
+        if (ischange) regLineChange(cm, doc.frontier, "text");
+        line.stateAfter = copyState(doc.mode, state);
+      } else {
+        processLine(cm, line.text, state);
+        line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
+      }
+      ++doc.frontier;
+      if (+new Date > end) {
+        startWorker(cm, cm.options.workDelay);
+        return true;
+      }
+    });
+    });
+  }
+
+  // Finds the line to start with when starting a parse. Tries to
+  // find a line with a stateAfter, so that it can start with a
+  // valid state. If that fails, it returns the line with the
+  // smallest indentation, which tends to need the least context to
+  // parse correctly.
+  function findStartLine(cm, n, precise) {
+    var minindent, minline, doc = cm.doc;
+    var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);
+    for (var search = n; search > lim; --search) {
+      if (search <= doc.first) return doc.first;
+      var line = getLine(doc, search - 1);
+      if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
+      var indented = countColumn(line.text, null, cm.options.tabSize);
+      if (minline == null || minindent > indented) {
+        minline = search - 1;
+        minindent = indented;
+      }
+    }
+    return minline;
+  }
+
+  function getStateBefore(cm, n, precise) {
+    var doc = cm.doc, display = cm.display;
+    if (!doc.mode.startState) return true;
+    var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
+    if (!state) state = startState(doc.mode);
+    else state = copyState(doc.mode, state);
+    doc.iter(pos, n, function(line) {
+      processLine(cm, line.text, state);
+      var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo;
+      line.stateAfter = save ? copyState(doc.mode, state) : null;
+      ++pos;
+    });
+    if (precise) doc.frontier = pos;
+    return state;
+  }
+
+  // POSITION MEASUREMENT
+
+  function paddingTop(display) {return display.lineSpace.offsetTop;}
+  function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}
+  function paddingH(display) {
+    if (display.cachedPaddingH) return display.cachedPaddingH;
+    var e = removeChildrenAndAdd(display.measure, elt("pre", "x"));
+    var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;
+    return display.cachedPaddingH = {left: parseInt(style.paddingLeft),
+                                     right: parseInt(style.paddingRight)};
+  }
+
+  // Ensure the lineView.wrapping.heights array is populated. This is
+  // an array of bottom offsets for the lines that make up a drawn
+  // line. When lineWrapping is on, there might be more than one
+  // height.
+  function ensureLineHeights(cm, lineView, rect) {
+    var wrapping = cm.options.lineWrapping;
+    var curWidth = wrapping && cm.display.scroller.clientWidth;
+    if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
+      var heights = lineView.measure.heights = [];
+      if (wrapping) {
+        lineView.measure.width = curWidth;
+        var rects = lineView.text.firstChild.getClientRects();
+        for (var i = 0; i < rects.length - 1; i++) {
+          var cur = rects[i], next = rects[i + 1];
+          if (Math.abs(cur.bottom - next.bottom) > 2)
+            heights.push((cur.bottom + next.top) / 2 - rect.top);
+        }
+      }
+      heights.push(rect.bottom - rect.top);
+    }
+  }
+
+  // Find a line map (mapping character offsets to text nodes) and a
+  // measurement cache for the given line number. (A line view might
+  // contain multiple lines when collapsed ranges are present.)
+  function mapFromLineView(lineView, line, lineN) {
+    if (lineView.line == line)
+      return {map: lineView.measure.map, cache: lineView.measure.cache};
+    for (var i = 0; i < lineView.rest.length; i++)
+      if (lineView.rest[i] == line)
+        return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]};
+    for (var i = 0; i < lineView.rest.length; i++)
+      if (lineNo(lineView.rest[i]) > lineN)
+        return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true};
+  }
+
+  // Render a line into the hidden node display.externalMeasured. Used
+  // when measurement is needed for a line that's not in the viewport.
+  function updateExternalMeasurement(cm, line) {
+    line = visualLine(line);
+    var lineN = lineNo(line);
+    var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN);
+    view.lineN = lineN;
+    var built = view.built = buildLineContent(cm, view);
+    view.text = built.pre;
+    removeChildrenAndAdd(cm.display.lineMeasure, built.pre);
+    return view;
+  }
+
+  // Get a {top, bottom, left, right} box (in line-local coordinates)
+  // for a given character.
+  function measureChar(cm, line, ch, bias) {
+    return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias);
+  }
+
+  // Find a line view that corresponds to the given line number.
+  function findViewForLine(cm, lineN) {
+    if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)
+      return cm.display.view[findViewIndex(cm, lineN)];
+    var ext = cm.display.externalMeasured;
+    if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)
+      return ext;
+  }
+
+  // Measurement can be split in two steps, the set-up work that
+  // applies to the whole line, and the measurement of the actual
+  // character. Functions like coordsChar, that need to do a lot of
+  // measurements in a row, can thus ensure that the set-up work is
+  // only done once.
+  function prepareMeasureForLine(cm, line) {
+    var lineN = lineNo(line);
+    var view = findViewForLine(cm, lineN);
+    if (view && !view.text)
+      view = null;
+    else if (view && view.changes)
+      updateLineForChanges(cm, view, lineN, getDimensions(cm));
+    if (!view)
+      view = updateExternalMeasurement(cm, line);
+
+    var info = mapFromLineView(view, line, lineN);
+    return {
+      line: line, view: view, rect: null,
+      map: info.map, cache: info.cache, before: info.before,
+      hasHeights: false
+    };
+  }
+
+  // Given a prepared measurement object, measures the position of an
+  // actual character (or fetches it from the cache).
+  function measureCharPrepared(cm, prepared, ch, bias) {
+    if (prepared.before) ch = -1;
+    var key = ch + (bias || ""), found;
+    if (prepared.cache.hasOwnProperty(key)) {
+      found = prepared.cache[key];
+    } else {
+      if (!prepared.rect)
+        prepared.rect = prepared.view.text.getBoundingClientRect();
+      if (!prepared.hasHeights) {
+        ensureLineHeights(cm, prepared.view, prepared.rect);
+        prepared.hasHeights = true;
+      }
+      found = measureCharInner(cm, prepared, ch, bias);
+      if (!found.bogus) prepared.cache[key] = found;
+    }
+    return {left: found.left, right: found.right, top: found.top, bottom: found.bottom};
+  }
+
+  var nullRect = {left: 0, right: 0, top: 0, bottom: 0};
+
+  function measureCharInner(cm, prepared, ch, bias) {
+    var map = prepared.map;
+
+    var node, start, end, collapse;
+    // First, search the line map for the text node corresponding to,
+    // or closest to, the target character.
+    for (var i = 0; i < map.length; i += 3) {
+      var mStart = map[i], mEnd = map[i + 1];
+      if (ch < mStart) {
+        start = 0; end = 1;
+        collapse = "left";
+      } else if (ch < mEnd) {
+        start = ch - mStart;
+        end = start + 1;
+      } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) {
+        end = mEnd - mStart;
+        start = end - 1;
+        if (ch >= mEnd) collapse = "right";
+      }
+      if (start != null) {
+        node = map[i + 2];
+        if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
+          collapse = bias;
+        if (bias == "left" && start == 0)
+          while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) {
+            node = map[(i -= 3) + 2];
+            collapse = "left";
+          }
+        if (bias == "right" && start == mEnd - mStart)
+          while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) {
+            node = map[(i += 3) + 2];
+            collapse = "right";
+          }
+        break;
+      }
+    }
+
+    var rect;
+    if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
+      while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start;
+      while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end;
+      if (ie_upto8 && start == 0 && end == mEnd - mStart) {
+        rect = node.parentNode.getBoundingClientRect();
+      } else if (ie && cm.options.lineWrapping) {
+        var rects = range(node, start, end).getClientRects();
+        if (rects.length)
+          rect = rects[bias == "right" ? rects.length - 1 : 0];
+        else
+          rect = nullRect;
+      } else {
+        rect = range(node, start, end).getBoundingClientRect();
+      }
+    } else { // If it is a widget, simply get the box for the whole widget.
+      if (start > 0) collapse = bias = "right";
+      var rects;
+      if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)
+        rect = rects[bias == "right" ? rects.length - 1 : 0];
+      else
+        rect = node.getBoundingClientRect();
+    }
+    if (ie_upto8 && !start && (!rect || !rect.left && !rect.right)) {
+      var rSpan = node.parentNode.getClientRects()[0];
+      if (rSpan)
+        rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom};
+      else
+        rect = nullRect;
+    }
+
+    var top, bot = (rect.bottom + rect.top) / 2 - prepared.rect.top;
+    var heights = prepared.view.measure.heights;
+    for (var i = 0; i < heights.length - 1; i++)
+      if (bot < heights[i]) break;
+    top = i ? heights[i - 1] : 0; bot = heights[i];
+    var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left,
+                  right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left,
+                  top: top, bottom: bot};
+    if (!rect.left && !rect.right) result.bogus = true;
+    return result;
+  }
+
+  function clearLineMeasurementCacheFor(lineView) {
+    if (lineView.measure) {
+      lineView.measure.cache = {};
+      lineView.measure.heights = null;
+      if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
+        lineView.measure.caches[i] = {};
+    }
+  }
+
+  function clearLineMeasurementCache(cm) {
+    cm.display.externalMeasure = null;
+    removeChildren(cm.display.lineMeasure);
+    for (var i = 0; i < cm.display.view.length; i++)
+      clearLineMeasurementCacheFor(cm.display.view[i]);
+  }
+
+  function clearCaches(cm) {
+    clearLineMeasurementCache(cm);
+    cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;
+    if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;
+    cm.display.lineNumChars = null;
+  }
+
+  function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
+  function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }
+
+  // Converts a {top, bottom, left, right} box from line-local
+  // coordinates into another coordinate system. Context may be one of
+  // "line", "div" (display.lineDiv), "local"/null (editor), or "page".
+  function intoCoordSystem(cm, lineObj, rect, context) {
+    if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
+      var size = widgetHeight(lineObj.widgets[i]);
+      rect.top += size; rect.bottom += size;
+    }
+    if (context == "line") return rect;
+    if (!context) context = "local";
+    var yOff = heightAtLine(lineObj);
+    if (context == "local") yOff += paddingTop(cm.display);
+    else yOff -= cm.display.viewOffset;
+    if (context == "page" || context == "window") {
+      var lOff = cm.display.lineSpace.getBoundingClientRect();
+      yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
+      var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
+      rect.left += xOff; rect.right += xOff;
+    }
+    rect.top += yOff; rect.bottom += yOff;
+    return rect;
+  }
+
+  // Coverts a box from "div" coords to another coordinate system.
+  // Context may be "window", "page", "div", or "local"/null.
+  function fromCoordSystem(cm, coords, context) {
+    if (context == "div") return coords;
+    var left = coords.left, top = coords.top;
+    // First move into "page" coordinate system
+    if (context == "page") {
+      left -= pageScrollX();
+      top -= pageScrollY();
+    } else if (context == "local" || !context) {
+      var localBox = cm.display.sizer.getBoundingClientRect();
+      left += localBox.left;
+      top += localBox.top;
+    }
+
+    var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect();
+    return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};
+  }
+
+  function charCoords(cm, pos, context, lineObj, bias) {
+    if (!lineObj) lineObj = getLine(cm.doc, pos.line);
+    return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context);
+  }
+
+  // Returns a box for a given cursor position, which may have an
+  // 'other' property containing the position of the secondary cursor
+  // on a bidi boundary.
+  function cursorCoords(cm, pos, context, lineObj, preparedMeasure) {
+    lineObj = lineObj || getLine(cm.doc, pos.line);
+    if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj);
+    function get(ch, right) {
+      var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left");
+      if (right) m.left = m.right; else m.right = m.left;
+      return intoCoordSystem(cm, lineObj, m, context);
+    }
+    function getBidi(ch, partPos) {
+      var part = order[partPos], right = part.level % 2;
+      if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {
+        part = order[--partPos];
+        ch = bidiRight(part) - (part.level % 2 ? 0 : 1);
+        right = true;
+      } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {
+        part = order[++partPos];
+        ch = bidiLeft(part) - part.level % 2;
+        right = false;
+      }
+      if (right && ch == part.to && ch > part.from) return get(ch - 1);
+      return get(ch, right);
+    }
+    var order = getOrder(lineObj), ch = pos.ch;
+    if (!order) return get(ch);
+    var partPos = getBidiPartAt(order, ch);
+    var val = getBidi(ch, partPos);
+    if (bidiOther != null) val.other = getBidi(ch, bidiOther);
+    return val;
+  }
+
+  // Used to cheaply estimate the coordinates for a position. Used for
+  // intermediate scroll updates.
+  function estimateCoords(cm, pos) {
+    var left = 0, pos = clipPos(cm.doc, pos);
+    if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch;
+    var lineObj = getLine(cm.doc, pos.line);
+    var top = heightAtLine(lineObj) + paddingTop(cm.display);
+    return {left: left, right: left, top: top, bottom: top + lineObj.height};
+  }
+
+  // Positions returned by coordsChar contain some extra information.
+  // xRel is the relative x position of the input coordinates compared
+  // to the found position (so xRel > 0 means the coordinates are to
+  // the right of the character position, for example). When outside
+  // is true, that means the coordinates lie outside the line's
+  // vertical range.
+  function PosWithInfo(line, ch, outside, xRel) {
+    var pos = Pos(line, ch);
+    pos.xRel = xRel;
+    if (outside) pos.outside = true;
+    return pos;
+  }
+
+  // Compute the character position closest to the given coordinates.
+  // Input must be lineSpace-local ("div" coordinate system).
+  function coordsChar(cm, x, y) {
+    var doc = cm.doc;
+    y += cm.display.viewOffset;
+    if (y < 0) return PosWithInfo(doc.first, 0, true, -1);
+    var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
+    if (lineN > last)
+      return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);
+    if (x < 0) x = 0;
+
+    var lineObj = getLine(doc, lineN);
+    for (;;) {
+      var found = coordsCharInner(cm, lineObj, lineN, x, y);
+      var merged = collapsedSpanAtEnd(lineObj);
+      var mergedPos = merged && merged.find(0, true);
+      if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
+        lineN = lineNo(lineObj = mergedPos.to.line);
+      else
+        return found;
+    }
+  }
+
+  function coordsCharInner(cm, lineObj, lineNo, x, y) {
+    var innerOff = y - heightAtLine(lineObj);
+    var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;
+    var preparedMeasure = prepareMeasureForLine(cm, lineObj);
+
+    function getX(ch) {
+      var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure);
+      wrongLine = true;
+      if (innerOff > sp.bottom) return sp.left - adjust;
+      else if (innerOff < sp.top) return sp.left + adjust;
+      else wrongLine = false;
+      return sp.left;
+    }
+
+    var bidi = getOrder(lineObj), dist = lineObj.text.length;
+    var from = lineLeft(lineObj), to = lineRight(lineObj);
+    var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;
+
+    if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);
+    // Do a binary search between these bounds.
+    for (;;) {
+      if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
+        var ch = x < fromX || x - fromX <= toX - x ? from : to;
+        var xDiff = x - (ch == from ? fromX : toX);
+        while (isExtendingChar(lineObj.text.charAt(ch))) ++ch;
+        var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
+                              xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0);
+        return pos;
+      }
+      var step = Math.ceil(dist / 2), middle = from + step;
+      if (bidi) {
+        middle = from;
+        for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);
+      }
+      var middleX = getX(middle);
+      if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}
+      else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}
+    }
+  }
+
+  var measureText;
+  // Compute the default text height.
+  function textHeight(display) {
+    if (display.cachedTextHeight != null) return display.cachedTextHeight;
+    if (measureText == null) {
+      measureText = elt("pre");
+      // Measure a bunch of lines, for browsers that compute
+      // fractional heights.
+      for (var i = 0; i < 49; ++i) {
+        measureText.appendChild(document.createTextNode("x"));
+        measureText.appendChild(elt("br"));
+      }
+      measureText.appendChild(document.createTextNode("x"));
+    }
+    removeChildrenAndAdd(display.measure, measureText);
+    var height = measureText.offsetHeight / 50;
+    if (height > 3) display.cachedTextHeight = height;
+    removeChildren(display.measure);
+    return height || 1;
+  }
+
+  // Compute the default character width.
+  function charWidth(display) {
+    if (display.cachedCharWidth != null) return display.cachedCharWidth;
+    var anchor = elt("span", "xxxxxxxxxx");
+    var pre = elt("pre", [anchor]);
+    removeChildrenAndAdd(display.measure, pre);
+    var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10;
+    if (width > 2) display.cachedCharWidth = width;
+    return width || 10;
+  }
+
+  // OPERATIONS
+
+  // Operations are used to wrap a series of changes to the editor
+  // state in such a way that each change won't have to update the
+  // cursor and display (which would be awkward, slow, and
+  // error-prone). Instead, display updates are batched and then all
+  // combined and executed at once.
+
+  var nextOpId = 0;
+  // Start a new operation.
+  function startOperation(cm) {
+    cm.curOp = {
+      viewChanged: false,      // Flag that indicates that lines might need to be redrawn
+      startHeight: cm.doc.height, // Used to detect need to update scrollbar
+      forceUpdate: false,      // Used to force a redraw
+      updateInput: null,       // Whether to reset the input textarea
+      typing: false,           // Whether this reset should be careful to leave existing text (for compositing)
+      changeObjs: null,        // Accumulated changes, for firing change events
+      cursorActivity: false,   // Whether to fire a cursorActivity event
+      selectionChanged: false, // Whether the selection needs to be redrawn
+      updateMaxLine: false,    // Set when the widest line needs to be determined anew
+      scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
+      scrollToPos: null,       // Used to scroll to a specific position
+      id: ++nextOpId           // Unique ID
+    };
+    if (!delayedCallbackDepth++) delayedCallbacks = [];
+  }
+
+  // Finish an operation, updating the display and signalling delayed events
+  function endOperation(cm) {
+    var op = cm.curOp, doc = cm.doc, display = cm.display;
+    cm.curOp = null;
+
+    if (op.updateMaxLine) findMaxLine(cm);
+
+    // If it looks like an update might be needed, call updateDisplay
+    if (op.viewChanged || op.forceUpdate || op.scrollTop != null ||
+        op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||
+                           op.scrollToPos.to.line >= display.viewTo) ||
+        display.maxLineChanged && cm.options.lineWrapping) {
+      var updated = updateDisplay(cm, {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate);
+      if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop;
+    }
+    // If no update was run, but the selection changed, redraw that.
+    if (!updated && op.selectionChanged) updateSelection(cm);
+    if (!updated && op.startHeight != cm.doc.height) updateScrollbars(cm);
+
+    // Propagate the scroll position to the actual DOM scroller
+    if (op.scrollTop != null && display.scroller.scrollTop != op.scrollTop) {
+      var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));
+      display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = top;
+    }
+    if (op.scrollLeft != null && display.scroller.scrollLeft != op.scrollLeft) {
+      var left = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, op.scrollLeft));
+      display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = left;
+      alignHorizontally(cm);
+    }
+    // If we need to scroll a specific position into view, do so.
+    if (op.scrollToPos) {
+      var coords = scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos.from),
+                                     clipPos(cm.doc, op.scrollToPos.to), op.scrollToPos.margin);
+      if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords);
+    }
+
+    if (op.selectionChanged) restartBlink(cm);
+
+    if (cm.state.focused && op.updateInput)
+      resetInput(cm, op.typing);
+
+    // Fire events for markers that are hidden/unidden by editing or
+    // undoing
+    var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
+    if (hidden) for (var i = 0; i < hidden.length; ++i)
+      if (!hidden[i].lines.length) signal(hidden[i], "hide");
+    if (unhidden) for (var i = 0; i < unhidden.length; ++i)
+      if (unhidden[i].lines.length) signal(unhidden[i], "unhide");
+
+    var delayed;
+    if (!--delayedCallbackDepth) {
+      delayed = delayedCallbacks;
+      delayedCallbacks = null;
+    }
+    // Fire change events, and delayed event handlers
+    if (op.changeObjs) {
+      for (var i = 0; i < op.changeObjs.length; i++)
+        signal(cm, "change", cm, op.changeObjs[i]);
+      signal(cm, "changes", cm, op.changeObjs);
+    }
+    if (op.cursorActivity) signal(cm, "cursorActivity", cm);
+    if (delayed) for (var i = 0; i < delayed.length; ++i) delayed[i]();
+  }
+
+  // Run the given function in an operation
+  function runInOp(cm, f) {
+    if (cm.curOp) return f();
+    startOperation(cm);
+    try { return f(); }
+    finally { endOperation(cm); }
+  }
+  // Wraps a function in an operation. Returns the wrapped function.
+  function operation(cm, f) {
+    return function() {
+      if (cm.curOp) return f.apply(cm, arguments);
+      startOperation(cm);
+      try { return f.apply(cm, arguments); }
+      finally { endOperation(cm); }
+    };
+  }
+  // Used to add methods to editor and doc instances, wrapping them in
+  // operations.
+  function methodOp(f) {
+    return function() {
+      if (this.curOp) return f.apply(this, arguments);
+      startOperation(this);
+      try { return f.apply(this, arguments); }
+      finally { endOperation(this); }
+    };
+  }
+  function docMethodOp(f) {
+    return function() {
+      var cm = this.cm;
+      if (!cm || cm.curOp) return f.apply(this, arguments);
+      startOperation(cm);
+      try { return f.apply(this, arguments); }
+      finally { endOperation(cm); }
+    };
+  }
+
+  // VIEW TRACKING
+
+  // These objects are used to represent the visible (currently drawn)
+  // part of the document. A LineView may correspond to multiple
+  // logical lines, if those are connected by collapsed ranges.
+  function LineView(doc, line, lineN) {
+    // The starting line
+    this.line = line;
+    // Continuing lines, if any
+    this.rest = visualLineContinued(line);
+    // Number of logical lines in this visual line
+    this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1;
+    this.node = this.text = null;
+    this.hidden = lineIsHidden(doc, line);
+  }
+
+  // Create a range of LineView objects for the given lines.
+  function buildViewArray(cm, from, to) {
+    var array = [], nextPos;
+    for (var pos = from; pos < to; pos = nextPos) {
+      var view = new LineView(cm.doc, getLine(cm.doc, pos), pos);
+      nextPos = pos + view.size;
+      array.push(view);
+    }
+    return array;
+  }
+
+  // Updates the display.view data structure for a given change to the
+  // document. From and to are in pre-change coordinates. Lendiff is
+  // the amount of lines added or subtracted by the change. This is
+  // used for changes that span multiple lines, or change the way
+  // lines are divided into visual lines. regLineChange (below)
+  // registers single-line changes.
+  function regChange(cm, from, to, lendiff) {
+    if (from == null) from = cm.doc.first;
+    if (to == null) to = cm.doc.first + cm.doc.size;
+    if (!lendiff) lendiff = 0;
+
+    var display = cm.display;
+    if (lendiff && to < display.viewTo &&
+        (display.updateLineNumbers == null || display.updateLineNumbers > from))
+      display.updateLineNumbers = from;
+
+    cm.curOp.viewChanged = true;
+
+    if (from >= display.viewTo) { // Change after
+      if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)
+        resetView(cm);
+    } else if (to <= display.viewFrom) { // Change before
+      if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {
+        resetView(cm);
+      } else {
+        display.viewFrom += lendiff;
+        display.viewTo += lendiff;
+      }
+    } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap
+      resetView(cm);
+    } else if (from <= display.viewFrom) { // Top overlap
+      var cut = viewCuttingPoint(cm, to, to + lendiff, 1);
+      if (cut) {
+        display.view = display.view.slice(cut.index);
+        display.viewFrom = cut.lineN;
+        display.viewTo += lendiff;
+      } else {
+        resetView(cm);
+      }
+    } else if (to >= display.viewTo) { // Bottom overlap
+      var cut = viewCuttingPoint(cm, from, from, -1);
+      if (cut) {
+        display.view = display.view.slice(0, cut.index);
+        display.viewTo = cut.lineN;
+      } else {
+        resetView(cm);
+      }
+    } else { // Gap in the middle
+      var cutTop = viewCuttingPoint(cm, from, from, -1);
+      var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1);
+      if (cutTop && cutBot) {
+        display.view = display.view.slice(0, cutTop.index)
+          .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))
+          .concat(display.view.slice(cutBot.index));
+        display.viewTo += lendiff;
+      } else {
+        resetView(cm);
+      }
+    }
+
+    var ext = display.externalMeasured;
+    if (ext) {
+      if (to < ext.lineN)
+        ext.lineN += lendiff;
+      else if (from < ext.lineN + ext.size)
+        display.externalMeasured = null;
+    }
+  }
+
+  // Register a change to a single line. Type must be one of "text",
+  // "gutter", "class", "widget"
+  function regLineChange(cm, line, type) {
+    cm.curOp.viewChanged = true;
+    var display = cm.display, ext = cm.display.externalMeasured;
+    if (ext && line >= ext.lineN && line < ext.lineN + ext.size)
+      display.externalMeasured = null;
+
+    if (line < display.viewFrom || line >= display.viewTo) return;
+    var lineView = display.view[findViewIndex(cm, line)];
+    if (lineView.node == null) return;
+    var arr = lineView.changes || (lineView.changes = []);
+    if (indexOf(arr, type) == -1) arr.push(type);
+  }
+
+  // Clear the view.
+  function resetView(cm) {
+    cm.display.viewFrom = cm.display.viewTo = cm.doc.first;
+    cm.display.view = [];
+    cm.display.viewOffset = 0;
+  }
+
+  // Find the view element corresponding to a given line. Return null
+  // when the line isn't visible.
+  function findViewIndex(cm, n) {
+    if (n >= cm.display.viewTo) return null;
+    n -= cm.display.viewFrom;
+    if (n < 0) return null;
+    var view = cm.display.view;
+    for (var i = 0; i < view.length; i++) {
+      n -= view[i].size;
+      if (n < 0) return i;
+    }
+  }
+
+  function viewCuttingPoint(cm, oldN, newN, dir) {
+    var index = findViewIndex(cm, oldN), diff, view = cm.display.view;
+    if (!sawCollapsedSpans) return {index: index, lineN: newN};
+    for (var i = 0, n = cm.display.viewFrom; i < index; i++)
+      n += view[i].size;
+    if (n != oldN) {
+      if (dir > 0) {
+        if (index == view.length - 1) return null;
+        diff = (n + view[index].size) - oldN;
+        index++;
+      } else {
+        diff = n - oldN;
+      }
+      oldN += diff; newN += diff;
+    }
+    while (visualLineNo(cm.doc, newN) != newN) {
+      if (index == (dir < 0 ? 0 : view.length - 1)) return null;
+      newN += dir * view[index - (dir < 0 ? 1 : 0)].size;
+      index += dir;
+    }
+    return {index: index, lineN: newN};
+  }
+
+  // Force the view to cover a given range, adding empty view element
+  // or clipping off existing ones as needed.
+  function adjustView(cm, from, to) {
+    var display = cm.display, view = display.view;
+    if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {
+      display.view = buildViewArray(cm, from, to);
+      display.viewFrom = from;
+    } else {
+      if (display.viewFrom > from)
+        display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view);
+      else if (display.viewFrom < from)
+        display.view = display.view.slice(findViewIndex(cm, from));
+      display.viewFrom = from;
+      if (display.viewTo < to)
+        display.view = display.view.concat(buildViewArray(cm, display.viewTo, to));
+      else if (display.viewTo > to)
+        display.view = display.view.slice(0, findViewIndex(cm, to));
+    }
+    display.viewTo = to;
+  }
+
+  // Count the number of lines in the view whose DOM representation is
+  // out of date (or nonexistent).
+  function countDirtyView(cm) {
+    var view = cm.display.view, dirty = 0;
+    for (var i = 0; i < view.length; i++) {
+      var lineView = view[i];
+      if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty;
+    }
+    return dirty;
+  }
+
+  // INPUT HANDLING
+
+  // Poll for input changes, using the normal rate of polling. This
+  // runs as long as the editor is focused.
+  function slowPoll(cm) {
+    if (cm.display.pollingFast) return;
+    cm.display.poll.set(cm.options.pollInterval, function() {
+      readInput(cm);
+      if (cm.state.focused) slowPoll(cm);
+    });
+  }
+
+  // When an event has just come in that is likely to add or change
+  // something in the input textarea, we poll faster, to ensure that
+  // the change appears on the screen quickly.
+  function fastPoll(cm) {
+    var missed = false;
+    cm.display.pollingFast = true;
+    function p() {
+      var changed = readInput(cm);
+      if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);}
+      else {cm.display.pollingFast = false; slowPoll(cm);}
+    }
+    cm.display.poll.set(20, p);
+  }
+
+  // Read input from the textarea, and update the document to match.
+  // When something is selected, it is present in the textarea, and
+  // selected (unless it is huge, in which case a placeholder is
+  // used). When nothing is selected, the cursor sits after previously
+  // seen text (can be empty), which is stored in prevInput (we must
+  // not reset the textarea when typing, because that breaks IME).
+  function readInput(cm) {
+    var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc;
+    // Since this is called a *lot*, try to bail out as cheaply as
+    // possible when it is clear that nothing happened. hasSelection
+    // will be the case when there is a lot of text in the textarea,
+    // in which case reading its value would be expensive.
+    if (!cm.state.focused || hasSelection(input) || isReadOnly(cm) || cm.options.disableInput) return false;
+    var text = input.value;
+    // If nothing changed, bail.
+    if (text == prevInput && !cm.somethingSelected()) return false;
+    // Work around nonsensical selection resetting in IE9/10
+    if (ie && !ie_upto8 && cm.display.inputHasSelection === text) {
+      resetInput(cm);
+      return false;
+    }
+
+    var withOp = !cm.curOp;
+    if (withOp) startOperation(cm);
+    cm.display.shift = false;
+
+    // Find the part of the input that is actually new
+    var same = 0, l = Math.min(prevInput.length, text.length);
+    while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
+    var inserted = text.slice(same), textLines = splitLines(inserted);
+
+    // When pasing N lines into N selections, insert one line per selection
+    var multiPaste = cm.state.pasteIncoming && textLines.length > 1 && doc.sel.ranges.length == textLines.length;
+
+    // Normal behavior is to insert the new text into every selection
+    for (var i = doc.sel.ranges.length - 1; i >= 0; i--) {
+      var range = doc.sel.ranges[i];
+      var from = range.from(), to = range.to();
+      // Handle deletion
+      if (same < prevInput.length)
+        from = Pos(from.line, from.ch - (prevInput.length - same));
+      // Handle overwrite
+      else if (cm.state.overwrite && range.empty() && !cm.state.pasteIncoming)
+        to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length));
+      var updateInput = cm.curOp.updateInput;
+      var changeEvent = {from: from, to: to, text: multiPaste ? [textLines[i]] : textLines,
+                         origin: cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input"};
+      makeChange(cm.doc, changeEvent);
+      signalLater(cm, "inputRead", cm, changeEvent);
+      // When an 'electric' character is inserted, immediately trigger a reindent
+      if (inserted && !cm.state.pasteIncoming && cm.options.electricChars &&
+          cm.options.smartIndent && range.head.ch < 100 &&
+          (!i || doc.sel.ranges[i - 1].head.line != range.head.line)) {
+        var electric = cm.getModeAt(range.head).electricChars;
+        if (electric) for (var j = 0; j < electric.length; j++)
+          if (inserted.indexOf(electric.charAt(j)) > -1) {
+            indentLine(cm, range.head.line, "smart");
+            break;
+          }
+      }
+    }
+    ensureCursorVisible(cm);
+    cm.curOp.updateInput = updateInput;
+    cm.curOp.typing = true;
+
+    // Don't leave long text in the textarea, since it makes further polling slow
+    if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = "";
+    else cm.display.prevInput = text;
+    if (withOp) endOperation(cm);
+    cm.state.pasteIncoming = cm.state.cutIncoming = false;
+    return true;
+  }
+
+  // Reset the input to correspond to the selection (or to be empty,
+  // when not typing and nothing is selected)
+  function resetInput(cm, typing) {
+    var minimal, selected, doc = cm.doc;
+    if (cm.somethingSelected()) {
+      cm.display.prevInput = "";
+      var range = doc.sel.primary();
+      minimal = hasCopyEvent &&
+        (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000);
+      var content = minimal ? "-" : selected || cm.getSelection();
+      cm.display.input.value = content;
+      if (cm.state.focused) selectInput(cm.display.input);
+      if (ie && !ie_upto8) cm.display.inputHasSelection = content;
+    } else if (!typing) {
+      cm.display.prevInput = cm.display.input.value = "";
+      if (ie && !ie_upto8) cm.display.inputHasSelection = null;
+    }
+    cm.display.inaccurateSelection = minimal;
+  }
+
+  function focusInput(cm) {
+    if (cm.options.readOnly != "nocursor" && (!mobile || activeElt() != cm.display.input))
+      cm.display.input.focus();
+  }
+
+  function ensureFocus(cm) {
+    if (!cm.state.focused) { focusInput(cm); onFocus(cm); }
+  }
+
+  function isReadOnly(cm) {
+    return cm.options.readOnly || cm.doc.cantEdit;
+  }
+
+  // EVENT HANDLERS
+
+  // Attach the necessary event handlers when initializing the editor
+  function registerEventHandlers(cm) {
+    var d = cm.display;
+    on(d.scroller, "mousedown", operation(cm, onMouseDown));
+    // Older IE's will not fire a second mousedown for a double click
+    if (ie_upto10)
+      on(d.scroller, "dblclick", operation(cm, function(e) {
+        if (signalDOMEvent(cm, e)) return;
+        var pos = posFromMouse(cm, e);
+        if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
+        e_preventDefault(e);
+        var word = findWordAt(cm.doc, pos);
+        extendSelection(cm.doc, word.anchor, word.head);
+      }));
+    else
+      on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });
+    // Prevent normal selection in the editor (we handle our own)
+    on(d.lineSpace, "selectstart", function(e) {
+      if (!eventInWidget(d, e)) e_preventDefault(e);
+    });
+    // Some browsers fire contextmenu *after* opening the menu, at
+    // which point we can't mess with it anymore. Context menu is
+    // handled in onMouseDown for these browsers.
+    if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
+
+    // Sync scrolling between fake scrollbars and real scrollable
+    // area, ensure viewport is updated when scrolling.
+    on(d.scroller, "scroll", function() {
+      if (d.scroller.clientHeight) {
+        setScrollTop(cm, d.scroller.scrollTop);
+        setScrollLeft(cm, d.scroller.scrollLeft, true);
+        signal(cm, "scroll", cm);
+      }
+    });
+    on(d.scrollbarV, "scroll", function() {
+      if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop);
+    });
+    on(d.scrollbarH, "scroll", function() {
+      if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft);
+    });
+
+    // Listen to wheel events in order to try and update the viewport on time.
+    on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
+    on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
+
+    // Prevent clicks in the scrollbars from killing focus
+    function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); }
+    on(d.scrollbarH, "mousedown", reFocus);
+    on(d.scrollbarV, "mousedown", reFocus);
+    // Prevent wrapper from ever scrolling
+    on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
+
+    // When the window resizes, we need to refresh active editors.
+    var resizeTimer;
+    function onResize() {
+      if (resizeTimer == null) resizeTimer = setTimeout(function() {
+        resizeTimer = null;
+        // Might be a text scaling operation, clear size caches.
+        d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = knownScrollbarWidth = null;
+        cm.setSize();
+      }, 100);
+    }
+    on(window, "resize", onResize);
+    // The above handler holds on to the editor and its data
+    // structures. Here we poll to unregister it when the editor is no
+    // longer in the document, so that it can be garbage-collected.
+    function unregister() {
+      if (contains(document.body, d.wrapper)) setTimeout(unregister, 5000);
+      else off(window, "resize", onResize);
+    }
+    setTimeout(unregister, 5000);
+
+    on(d.input, "keyup", operation(cm, onKeyUp));
+    on(d.input, "input", function() {
+      if (ie && !ie_upto8 && cm.display.inputHasSelection) cm.display.inputHasSelection = null;
+      fastPoll(cm);
+    });
+    on(d.input, "keydown", operation(cm, onKeyDown));
+    on(d.input, "keypress", operation(cm, onKeyPress));
+    on(d.input, "focus", bind(onFocus, cm));
+    on(d.input, "blur", bind(onBlur, cm));
+
+    function drag_(e) {
+      if (!signalDOMEvent(cm, e)) e_stop(e);
+    }
+    if (cm.options.dragDrop) {
+      on(d.scroller, "dragstart", function(e){onDragStart(cm, e);});
+      on(d.scroller, "dragenter", drag_);
+      on(d.scroller, "dragover", drag_);
+      on(d.scroller, "drop", operation(cm, onDrop));
+    }
+    on(d.scroller, "paste", function(e) {
+      if (eventInWidget(d, e)) return;
+      cm.state.pasteIncoming = true;
+      focusInput(cm);
+      fastPoll(cm);
+    });
+    on(d.input, "paste", function() {
+      cm.state.pasteIncoming = true;
+      fastPoll(cm);
+    });
+
+    function prepareCopy(e) {
+      if (d.inaccurateSelection) {
+        d.prevInput = "";
+        d.inaccurateSelection = false;
+        d.input.value = cm.getSelection();
+        selectInput(d.input);
+      }
+      if (e.type == "cut") cm.state.cutIncoming = true;
+    }
+    on(d.input, "cut", prepareCopy);
+    on(d.input, "copy", prepareCopy);
+
+    // Needed to handle Tab key in KHTML
+    if (khtml) on(d.sizer, "mouseup", function() {
+      if (activeElt() == d.input) d.input.blur();
+      focusInput(cm);
+    });
+  }
+
+  // MOUSE EVENTS
+
+  // Return true when the given mouse event happened in a widget
+  function eventInWidget(display, e) {
+    for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
+      if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true;
+    }
+  }
+
+  // Given a mouse event, find the corresponding position. If liberal
+  // is false, it checks whether a gutter or scrollbar was clicked,
+  // and returns null if it was. forRect is used by rectangular
+  // selections, and tries to estimate a character position even for
+  // coordinates beyond the right of the text.
+  function posFromMouse(cm, e, liberal, forRect) {
+    var display = cm.display;
+    if (!liberal) {
+      var target = e_target(e);
+      if (target == display.scrollbarH || target == display.scrollbarV ||
+          target == display.scrollbarFiller || target == display.gutterFiller) return null;
+    }
+    var x, y, space = display.lineSpace.getBoundingClientRect();
+    // Fails unpredictably on IE[67] when mouse is dragged around quickly.
+    try { x = e.clientX - space.left; y = e.clientY - space.top; }
+    catch (e) { return null; }
+    var coords = coordsChar(cm, x, y), line;
+    if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
+      var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
+      coords = Pos(coords.line, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff);
+    }
+    return coords;
+  }
+
+  // A mouse down can be a single click, double click, triple click,
+  // start of selection drag, start of text drag, new cursor
+  // (ctrl-click), rectangle drag (alt-drag), or xwin
+  // middle-click-paste. Or it might be a click on something we should
+  // not interfere with, such as a scrollbar or widget.
+  function onMouseDown(e) {
+    if (signalDOMEvent(this, e)) return;
+    var cm = this, display = cm.display;
+    display.shift = e.shiftKey;
+
+    if (eventInWidget(display, e)) {
+      if (!webkit) {
+        // Briefly turn off draggability, to allow widgets to do
+        // normal dragging things.
+        display.scroller.draggable = false;
+        setTimeout(function(){display.scroller.draggable = true;}, 100);
+      }
+      return;
+    }
+    if (clickInGutter(cm, e)) return;
+    var start = posFromMouse(cm, e);
+    window.focus();
+
+    switch (e_button(e)) {
+    case 1:
+      if (start)
+        leftButtonDown(cm, e, start);
+      else if (e_target(e) == display.scroller)
+        e_preventDefault(e);
+      break;
+    case 2:
+      if (webkit) cm.state.lastMiddleDown = +new Date;
+      if (start) extendSelection(cm.doc, start);
+      setTimeout(bind(focusInput, cm), 20);
+      e_preventDefault(e);
+      break;
+    case 3:
+      if (captureRightClick) onContextMenu(cm, e);
+      break;
+    }
+  }
+
+  var lastClick, lastDoubleClick;
+  function leftButtonDown(cm, e, start) {
+    setTimeout(bind(ensureFocus, cm), 0);
+
+    var now = +new Date, type;
+    if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) {
+      type = "triple";
+    } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) {
+      type = "double";
+      lastDoubleClick = {time: now, pos: start};
+    } else {
+      type = "single";
+      lastClick = {time: now, pos: start};
+    }
+
+    var sel = cm.doc.sel, addNew = mac ? e.metaKey : e.ctrlKey;
+    if (cm.options.dragDrop && dragAndDrop && !addNew && !isReadOnly(cm) &&
+        type == "single" && sel.contains(start) > -1 && sel.somethingSelected())
+      leftButtonStartDrag(cm, e, start);
+    else
+      leftButtonSelect(cm, e, start, type, addNew);
+  }
+
+  // Start a text drag. When it ends, see if any dragging actually
+  // happen, and treat as a click if it didn't.
+  function leftButtonStartDrag(cm, e, start) {
+    var display = cm.display;
+    var dragEnd = operation(cm, function(e2) {
+      if (webkit) display.scroller.draggable = false;
+      cm.state.draggingText = false;
+      off(document, "mouseup", dragEnd);
+      off(display.scroller, "drop", dragEnd);
+      if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
+        e_preventDefault(e2);
+        extendSelection(cm.doc, start);
+        focusInput(cm);
+        // Work around unexplainable focus problem in IE9 (#2127)
+        if (ie_upto10 && !ie_upto8)
+          setTimeout(function() {document.body.focus(); focusInput(cm);}, 20);
+      }
+    });
+    // Let the drag handler handle this.
+    if (webkit) display.scroller.draggable = true;
+    cm.state.draggingText = dragEnd;
+    // IE's approach to draggable
+    if (display.scroller.dragDrop) display.scroller.dragDrop();
+    on(document, "mouseup", dragEnd);
+    on(display.scroller, "drop", dragEnd);
+  }
+
+  // Normal selection, as opposed to text dragging.
+  function leftButtonSelect(cm, e, start, type, addNew) {
+    var display = cm.display, doc = cm.doc;
+    e_preventDefault(e);
+
+    var ourRange, ourIndex, startSel = doc.sel;
+    if (addNew) {
+      ourIndex = doc.sel.contains(start);
+      if (ourIndex > -1)
+        ourRange = doc.sel.ranges[ourIndex];
+      else
+        ourRange = new Range(start, start);
+    } else {
+      ourRange = doc.sel.primary();
+    }
+
+    if (e.altKey) {
+      type = "rect";
+      if (!addNew) ourRange = new Range(start, start);
+      start = posFromMouse(cm, e, true, true);
+      ourIndex = -1;
+    } else if (type == "double") {
+      var word = findWordAt(doc, start);
+      if (cm.display.shift || doc.extend)
+        ourRange = extendRange(doc, ourRange, word.anchor, word.head);
+      else
+        ourRange = word;
+    } else if (type == "triple") {
+      var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0)));
+      if (cm.display.shift || doc.extend)
+        ourRange = extendRange(doc, ourRange, line.anchor, line.head);
+      else
+        ourRange = line;
+    } else {
+      ourRange = extendRange(doc, ourRange, start);
+    }
+
+    if (!addNew) {
+      ourIndex = 0;
+      setSelection(doc, new Selection([ourRange], 0), sel_mouse);
+    } else if (ourIndex > -1) {
+      replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
+    } else {
+      ourIndex = doc.sel.ranges.length;
+      setSelection(doc, normalizeSelection(doc.sel.ranges.concat([ourRange]), ourIndex),
+                   {scroll: false, origin: "*mouse"});
+    }
+
+    var lastPos = start;
+    function extendTo(pos) {
+      if (cmp(lastPos, pos) == 0) return;
+      lastPos = pos;
+
+      if (type == "rect") {
+        var ranges = [], tabSize = cm.options.tabSize;
+        var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize);
+        var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize);
+        var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol);
+        for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));
+             line <= end; line++) {
+          var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize);
+          if (left == right)
+            ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos)));
+          else if (text.length > leftPos)
+            ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize))));
+        }
+        if (!ranges.length) ranges.push(new Range(start, start));
+        setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), sel_mouse);
+      } else {
+        var oldRange = ourRange;
+        var anchor = oldRange.anchor, head = pos;
+        if (type != "single") {
+          if (type == "double")
+            var range = findWordAt(doc, pos);
+          else
+            var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0)));
+          if (cmp(range.anchor, anchor) > 0) {
+            head = range.head;
+            anchor = minPos(oldRange.from(), range.anchor);
+          } else {
+            head = range.anchor;
+            anchor = maxPos(oldRange.to(), range.head);
+          }
+        }
+        var ranges = startSel.ranges.slice(0);
+        ranges[ourIndex] = new Range(clipPos(doc, anchor), head);
+        setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse);
+      }
+    }
+
+    var editorSize = display.wrapper.getBoundingClientRect();
+    // Used to ensure timeout re-tries don't fire when another extend
+    // happened in the meantime (clearTimeout isn't reliable -- at
+    // least on Chrome, the timeouts still happen even when cleared,
+    // if the clear happens after their scheduled firing time).
+    var counter = 0;
+
+    function extend(e) {
+      var curCount = ++counter;
+      var cur = posFromMouse(cm, e, true, type == "rect");
+      if (!cur) return;
+      if (cmp(cur, lastPos) != 0) {
+        ensureFocus(cm);
+        extendTo(cur);
+        var visible = visibleLines(display, doc);
+        if (cur.line >= visible.to || cur.line < visible.from)
+          setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
+      } else {
+        var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
+        if (outside) setTimeout(operation(cm, function() {
+          if (counter != curCount) return;
+          display.scroller.scrollTop += outside;
+          extend(e);
+        }), 50);
+      }
+    }
+
+    function done(e) {
+      counter = Infinity;
+      e_preventDefault(e);
+      focusInput(cm);
+      off(document, "mousemove", move);
+      off(document, "mouseup", up);
+      doc.history.lastSelOrigin = null;
+    }
+
+    var move = operation(cm, function(e) {
+      if ((ie && !ie_upto9) ?  !e.buttons : !e_button(e)) done(e);
+      else extend(e);
+    });
+    var up = operation(cm, done);
+    on(document, "mousemove", move);
+    on(document, "mouseup", up);
+  }
+
+  // Determines whether an event happened in the gutter, and fires the
+  // handlers for the corresponding event.
+  function gutterEvent(cm, e, type, prevent, signalfn) {
+    try { var mX = e.clientX, mY = e.clientY; }
+    catch(e) { return false; }
+    if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false;
+    if (prevent) e_preventDefault(e);
+
+    var display = cm.display;
+    var lineBox = display.lineDiv.getBoundingClientRect();
+
+    if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e);
+    mY -= lineBox.top - display.viewOffset;
+
+    for (var i = 0; i < cm.options.gutters.length; ++i) {
+      var g = display.gutters.childNodes[i];
+      if (g && g.getBoundingClientRect().right >= mX) {
+        var line = lineAtHeight(cm.doc, mY);
+        var gutter = cm.options.gutters[i];
+        signalfn(cm, type, cm, line, gutter, e);
+        return e_defaultPrevented(e);
+      }
+    }
+  }
+
+  function clickInGutter(cm, e) {
+    return gutterEvent(cm, e, "gutterClick", true, signalLater);
+  }
+
+  // Kludge to work around strange IE behavior where it'll sometimes
+  // re-fire a series of drag-related events right after the drop (#1551)
+  var lastDrop = 0;
+
+  function onDrop(e) {
+    var cm = this;
+    if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
+      return;
+    e_preventDefault(e);
+    if (ie_upto10) lastDrop = +new Date;
+    var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
+    if (!pos || isReadOnly(cm)) return;
+    // Might be a file drop, in which case we simply extract the text
+    // and insert it.
+    if (files && files.length && window.FileReader && window.File) {
+      var n = files.length, text = Array(n), read = 0;
+      var loadFile = function(file, i) {
+        var reader = new FileReader;
+        reader.onload = function() {
+          text[i] = reader.result;
+          if (++read == n) {
+            pos = clipPos(cm.doc, pos);
+            var change = {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"};
+            makeChange(cm.doc, change);
+            setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
+          }
+        };
+        reader.readAsText(file);
+      };
+      for (var i = 0; i < n; ++i) loadFile(files[i], i);
+    } else { // Normal drop
+      // Don't do a replace if the drop happened inside of the selected text.
+      if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
+        cm.state.draggingText(e);
+        // Ensure the editor is re-focused
+        setTimeout(bind(focusInput, cm), 20);
+        return;
+      }
+      try {
+        var text = e.dataTransfer.getData("Text");
+        if (text) {
+          var selected = cm.state.draggingText && cm.listSelections();
+          setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
+          if (selected) for (var i = 0; i < selected.length; ++i)
+            replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag");
+          cm.replaceSelection(text, "around", "paste");
+          focusInput(cm);
+        }
+      }
+      catch(e){}
+    }
+  }
+
+  function onDragStart(cm, e) {
+    if (ie_upto10 && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }
+    if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;
+
+    e.dataTransfer.setData("Text", cm.getSelection());
+
+    // Use dummy image instead of default browsers image.
+    // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
+    if (e.dataTransfer.setDragImage && !safari) {
+      var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
+      img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
+      if (presto) {
+        img.width = img.height = 1;
+        cm.display.wrapper.appendChild(img);
+        // Force a relayout, or Opera won't use our image for some obscure reason
+        img._top = img.offsetTop;
+      }
+      e.dataTransfer.setDragImage(img, 0, 0);
+      if (presto) img.parentNode.removeChild(img);
+    }
+  }
+
+  // SCROLL EVENTS
+
+  // Sync the scrollable area and scrollbars, ensure the viewport
+  // covers the visible area.
+  function setScrollTop(cm, val) {
+    if (Math.abs(cm.doc.scrollTop - val) < 2) return;
+    cm.doc.scrollTop = val;
+    if (!gecko) updateDisplay(cm, {top: val});
+    if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
+    if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val;
+    if (gecko) updateDisplay(cm);
+    startWorker(cm, 100);
+  }
+  // Sync scroller and scrollbar, ensure the gutter elements are
+  // aligned.
+  function setScrollLeft(cm, val, isScroller) {
+    if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;
+    val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
+    cm.doc.scrollLeft = val;
+    alignHorizontally(cm);
+    if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
+    if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val;
+  }
+
+  // Since the delta values reported on mouse wheel events are
+  // unstandardized between browsers and even browser versions, and
+  // generally horribly unpredictable, this code starts by measuring
+  // the scroll effect that the first few mouse wheel events have,
+  // and, from that, detects the way it can convert deltas to pixel
+  // offsets afterwards.
+  //
+  // The reason we want to know the amount a wheel event will scroll
+  // is that it gives us a chance to update the display before the
+  // actual scrolling happens, reducing flickering.
+
+  var wheelSamples = 0, wheelPixelsPerUnit = null;
+  // Fill in a browser-detected starting value on browsers where we
+  // know one. These don't have to be accurate -- the result of them
+  // being wrong would just be a slight flicker on the first wheel
+  // scroll (if it is large enough).
+  if (ie) wheelPixelsPerUnit = -.53;
+  else if (gecko) wheelPixelsPerUnit = 15;
+  else if (chrome) wheelPixelsPerUnit = -.7;
+  else if (safari) wheelPixelsPerUnit = -1/3;
+
+  function onScrollWheel(cm, e) {
+    var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
+    if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
+    if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
+    else if (dy == null) dy = e.wheelDelta;
+
+    var display = cm.display, scroll = display.scroller;
+    // Quit if there's nothing to scroll here
+    if (!(dx && scroll.scrollWidth > scroll.clientWidth ||
+          dy && scroll.scrollHeight > scroll.clientHeight)) return;
+
+    // Webkit browsers on OS X abort momentum scrolls when the target
+    // of the scroll event is removed from the scrollable element.
+    // This hack (see related code in patchDisplay) makes sure the
+    // element is kept around.
+    if (dy && mac && webkit) {
+      outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
+        for (var i = 0; i < view.length; i++) {
+          if (view[i].node == cur) {
+            cm.display.currentWheelTarget = cur;
+            break outer;
+          }
+        }
+      }
+    }
+
+    // On some browsers, horizontal scrolling will cause redraws to
+    // happen before the gutter has been realigned, causing it to
+    // wriggle around in a most unseemly way. When we have an
+    // estimated pixels/delta value, we just handle horizontal
+    // scrolling entirely here. It'll be slightly off from native, but
+    // better than glitching out.
+    if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
+      if (dy)
+        setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
+      setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
+      e_preventDefault(e);
+      display.wheelStartX = null; // Abort measurement, if in progress
+      return;
+    }
+
+    // 'Project' the visible viewport to cover the area that is being
+    // scrolled into view (if we know enough to estimate it).
+    if (dy && wheelPixelsPerUnit != null) {
+      var pixels = dy * wheelPixelsPerUnit;
+      var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
+      if (pixels < 0) top = Math.max(0, top + pixels - 50);
+      else bot = Math.min(cm.doc.height, bot + pixels + 50);
+      updateDisplay(cm, {top: top, bottom: bot});
+    }
+
+    if (wheelSamples < 20) {
+      if (display.wheelStartX == null) {
+        display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
+        display.wheelDX = dx; display.wheelDY = dy;
+        setTimeout(function() {
+          if (display.wheelStartX == null) return;
+          var movedX = scroll.scrollLeft - display.wheelStartX;
+          var movedY = scroll.scrollTop - display.wheelStartY;
+          var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
+            (movedX && display.wheelDX && movedX / display.wheelDX);
+          display.wheelStartX = display.wheelStartY = null;
+          if (!sample) return;
+          wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
+          ++wheelSamples;
+        }, 200);
+      } else {
+        display.wheelDX += dx; display.wheelDY += dy;
+      }
+    }
+  }
+
+  // KEY EVENTS
+
+  // Run a handler that was bound to a key.
+  function doHandleBinding(cm, bound, dropShift) {
+    if (typeof bound == "string") {
+      bound = commands[bound];
+      if (!bound) return false;
+    }
+    // Ensure previous input has been read, so that the handler sees a
+    // consistent view of the document
+    if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;
+    var prevShift = cm.display.shift, done = false;
+    try {
+      if (isReadOnly(cm)) cm.state.suppressEdits = true;
+      if (dropShift) cm.display.shift = false;
+      done = bound(cm) != Pass;
+    } finally {
+      cm.display.shift = prevShift;
+      cm.state.suppressEdits = false;
+    }
+    return done;
+  }
+
+  // Collect the currently active keymaps.
+  function allKeyMaps(cm) {
+    var maps = cm.state.keyMaps.slice(0);
+    if (cm.options.extraKeys) maps.push(cm.options.extraKeys);
+    maps.push(cm.options.keyMap);
+    return maps;
+  }
+
+  var maybeTransition;
+  // Handle a key from the keydown event.
+  function handleKeyBinding(cm, e) {
+    // Handle automatic keymap transitions
+    var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto;
+    clearTimeout(maybeTransition);
+    if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
+      if (getKeyMap(cm.options.keyMap) == startMap) {
+        cm.options.keyMap = (next.call ? next.call(null, cm) : next);
+        keyMapChanged(cm);
+      }
+    }, 50);
+
+    var name = keyName(e, true), handled = false;
+    if (!name) return false;
+    var keymaps = allKeyMaps(cm);
+
+    if (e.shiftKey) {
+      // First try to resolve full name (including 'Shift-'). Failing
+      // that, see if there is a cursor-motion command (starting with
+      // 'go') bound to the keyname without 'Shift-'.
+      handled = lookupKey("Shift-" + name, keymaps, function(b) {return doHandleBinding(cm, b, true);})
+             || lookupKey(name, keymaps, function(b) {
+                  if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
+                    return doHandleBinding(cm, b);
+                });
+    } else {
+      handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); });
+    }
+
+    if (handled) {
+      e_preventDefault(e);
+      restartBlink(cm);
+      signalLater(cm, "keyHandled", cm, name, e);
+    }
+    return handled;
+  }
+
+  // Handle a key from the keypress event
+  function handleCharBinding(cm, e, ch) {
+    var handled = lookupKey("'" + ch + "'", allKeyMaps(cm),
+                            function(b) { return doHandleBinding(cm, b, true); });
+    if (handled) {
+      e_preventDefault(e);
+      restartBlink(cm);
+      signalLater(cm, "keyHandled", cm, "'" + ch + "'", e);
+    }
+    return handled;
+  }
+
+  var lastStoppedKey = null;
+  function onKeyDown(e) {
+    var cm = this;
+    ensureFocus(cm);
+    if (signalDOMEvent(cm, e)) return;
+    // IE does strange things with escape.
+    if (ie_upto10 && e.keyCode == 27) e.returnValue = false;
+    var code = e.keyCode;
+    cm.display.shift = code == 16 || e.shiftKey;
+    var handled = handleKeyBinding(cm, e);
+    if (presto) {
+      lastStoppedKey = handled ? code : null;
+      // Opera has no cut event... we try to at least catch the key combo
+      if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
+        cm.replaceSelection("", null, "cut");
+    }
+  }
+
+  function onKeyUp(e) {
+    if (signalDOMEvent(this, e)) return;
+    if (e.keyCode == 16) this.doc.sel.shift = false;
+  }
+
+  function onKeyPress(e) {
+    var cm = this;
+    if (signalDOMEvent(cm, e)) return;
+    var keyCode = e.keyCode, charCode = e.charCode;
+    if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
+    if (((presto && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
+    var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
+    if (handleCharBinding(cm, e, ch)) return;
+    if (ie && !ie_upto8) cm.display.inputHasSelection = null;
+    fastPoll(cm);
+  }
+
+  // FOCUS/BLUR EVENTS
+
+  function onFocus(cm) {
+    if (cm.options.readOnly == "nocursor") return;
+    if (!cm.state.focused) {
+      signal(cm, "focus", cm);
+      cm.state.focused = true;
+      if (cm.display.wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
+        cm.display.wrapper.className += " CodeMirror-focused";
+      if (!cm.curOp) {
+        resetInput(cm);
+        if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730
+      }
+    }
+    slowPoll(cm);
+    restartBlink(cm);
+  }
+  function onBlur(cm) {
+    if (cm.state.focused) {
+      signal(cm, "blur", cm);
+      cm.state.focused = false;
+      cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-focused", "");
+    }
+    clearInterval(cm.display.blinker);
+    setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150);
+  }
+
+  // CONTEXT MENU HANDLING
+
+  var detectingSelectAll;
+  // To make the context menu work, we need to briefly unhide the
+  // textarea (making it as unobtrusive as possible) to let the
+  // right-click take effect on it.
+  function onContextMenu(cm, e) {
+    if (signalDOMEvent(cm, e, "contextmenu")) return;
+    var display = cm.display;
+    if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return;
+
+    var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
+    if (!pos || presto) return; // Opera is difficult.
+
+    // Reset the current text selection only if the click is done outside of the selection
+    // and 'resetSelectionOnContextMenu' option is true.
+    var reset = cm.options.resetSelectionOnContextMenu;
+    if (reset && cm.doc.sel.contains(pos) == -1)
+      operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll);
+
+    var oldCSS = display.input.style.cssText;
+    display.inputDiv.style.position = "absolute";
+    display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
+      "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " +
+      (ie ? "rgba(255, 255, 255, .05)" : "transparent") +
+      "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
+    focusInput(cm);
+    resetInput(cm);
+    // Adds "Select all" to context menu in FF
+    if (!cm.somethingSelected()) display.input.value = display.prevInput = " ";
+
+    // Select-all will be greyed out if there's nothing to select, so
+    // this adds a zero-width space so that we can later check whether
+    // it got selected.
+    function prepareSelectAllHack() {
+      if (display.input.selectionStart != null) {
+        var extval = display.input.value = "\u200b" + (cm.somethingSelected() ? display.input.value : "");
+        display.prevInput = "\u200b";
+        display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
+      }
+    }
+    function rehide() {
+      display.inputDiv.style.position = "relative";
+      display.input.style.cssText = oldCSS;
+      if (ie_upto8) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos;
+      slowPoll(cm);
+
+      // Try to detect the user choosing select-all
+      if (display.input.selectionStart != null) {
+        if (!ie || ie_upto8) prepareSelectAllHack();
+        clearTimeout(detectingSelectAll);
+        var i = 0, poll = function(){
+          if (display.prevInput == "\u200b" && display.input.selectionStart == 0)
+            operation(cm, commands.selectAll)(cm);
+          else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500);
+          else resetInput(cm);
+        };
+        detectingSelectAll = setTimeout(poll, 200);
+      }
+    }
+
+    if (ie && !ie_upto8) prepareSelectAllHack();
+    if (captureRightClick) {
+      e_stop(e);
+      var mouseup = function() {
+        off(window, "mouseup", mouseup);
+        setTimeout(rehide, 20);
+      };
+      on(window, "mouseup", mouseup);
+    } else {
+      setTimeout(rehide, 50);
+    }
+  }
+
+  function contextMenuInGutter(cm, e) {
+    if (!hasHandler(cm, "gutterContextMenu")) return false;
+    return gutterEvent(cm, e, "gutterContextMenu", false, signal);
+  }
+
+  // UPDATING
+
+  // Compute the position of the end of a change (its 'to' property
+  // refers to the pre-change end).
+  var changeEnd = CodeMirror.changeEnd = function(change) {
+    if (!change.text) return change.to;
+    return Pos(change.from.line + change.text.length - 1,
+               lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));
+  };
+
+  // Adjust a position to refer to the post-change position of the
+  // same text, or the end of the change if the change covers it.
+  function adjustForChange(pos, change) {
+    if (cmp(pos, change.from) < 0) return pos;
+    if (cmp(pos, change.to) <= 0) return changeEnd(change);
+
+    var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
+    if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch;
+    return Pos(line, ch);
+  }
+
+  function computeSelAfterChange(doc, change) {
+    var out = [];
+    for (var i = 0; i < doc.sel.ranges.length; i++) {
+      var range = doc.sel.ranges[i];
+      out.push(new Range(adjustForChange(range.anchor, change),
+                         adjustForChange(range.head, change)));
+    }
+    return normalizeSelection(out, doc.sel.primIndex);
+  }
+
+  function offsetPos(pos, old, nw) {
+    if (pos.line == old.line)
+      return Pos(nw.line, pos.ch - old.ch + nw.ch);
+    else
+      return Pos(nw.line + (pos.line - old.line), pos.ch);
+  }
+
+  // Used by replaceSelections to allow moving the selection to the
+  // start or around the replaced test. Hint may be "start" or "around".
+  function computeReplacedSel(doc, changes, hint) {
+    var out = [];
+    var oldPrev = Pos(doc.first, 0), newPrev = oldPrev;
+    for (var i = 0; i < changes.length; i++) {
+      var change = changes[i];
+      var from = offsetPos(change.from, oldPrev, newPrev);
+      var to = offsetPos(changeEnd(change), oldPrev, newPrev);
+      oldPrev = change.to;
+      newPrev = to;
+      if (hint == "around") {
+        var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0;
+        out[i] = new Range(inv ? to : from, inv ? from : to);
+      } else {
+        out[i] = new Range(from, from);
+      }
+    }
+    return new Selection(out, doc.sel.primIndex);
+  }
+
+  // Allow "beforeChange" event handlers to influence a change
+  function filterChange(doc, change, update) {
+    var obj = {
+      canceled: false,
+      from: change.from,
+      to: change.to,
+      text: change.text,
+      origin: change.origin,
+      cancel: function() { this.canceled = true; }
+    };
+    if (update) obj.update = function(from, to, text, origin) {
+      if (from) this.from = clipPos(doc, from);
+      if (to) this.to = clipPos(doc, to);
+      if (text) this.text = text;
+      if (origin !== undefined) this.origin = origin;
+    };
+    signal(doc, "beforeChange", doc, obj);
+    if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj);
+
+    if (obj.canceled) return null;
+    return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};
+  }
+
+  // Apply a change to a document, and add it to the document's
+  // history, and propagating it to all linked documents.
+  function makeChange(doc, change, ignoreReadOnly) {
+    if (doc.cm) {
+      if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly);
+      if (doc.cm.state.suppressEdits) return;
+    }
+
+    if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
+      change = filterChange(doc, change, true);
+      if (!change) return;
+    }
+
+    // Possibly split or suppress the update based on the presence
+    // of read-only spans in its range.
+    var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
+    if (split) {
+      for (var i = split.length - 1; i >= 0; --i)
+        makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text});
+    } else {
+      makeChangeInner(doc, change);
+    }
+  }
+
+  function makeChangeInner(doc, change) {
+    if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return;
+    var selAfter = computeSelAfterChange(doc, change);
+    addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
+
+    makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
+    var rebased = [];
+
+    linkedDocs(doc, function(doc, sharedHist) {
+      if (!sharedHist && indexOf(rebased, doc.history) == -1) {
+        rebaseHist(doc.history, change);
+        rebased.push(doc.history);
+      }
+      makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
+    });
+  }
+
+  // Revert a change stored in a document's history.
+  function makeChangeFromHistory(doc, type, allowSelectionOnly) {
+    if (doc.cm && doc.cm.state.suppressEdits) return;
+
+    var hist = doc.history, event, selAfter = doc.sel;
+    var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done;
+
+    // Verify that there is a useable event (so that ctrl-z won't
+    // needlessly clear selection events)
+    for (var i = 0; i < source.length; i++) {
+      event = source[i];
+      if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)
+        break;
+    }
+    if (i == source.length) return;
+    hist.lastOrigin = hist.lastSelOrigin = null;
+
+    for (;;) {
+      event = source.pop();
+      if (event.ranges) {
+        pushSelectionToHistory(event, dest);
+        if (allowSelectionOnly && !event.equals(doc.sel)) {
+          setSelection(doc, event, {clearRedo: false});
+          return;
+        }
+        selAfter = event;
+      }
+      else break;
+    }
+
+    // Build up a reverse change object to add to the opposite history
+    // stack (redo when undoing, and vice versa).
+    var antiChanges = [];
+    pushSelectionToHistory(selAfter, dest);
+    dest.push({changes: antiChanges, generation: hist.generation});
+    hist.generation = event.generation || ++hist.maxGeneration;
+
+    var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
+
+    for (var i = event.changes.length - 1; i >= 0; --i) {
+      var change = event.changes[i];
+      change.origin = type;
+      if (filter && !filterChange(doc, change, false)) {
+        source.length = 0;
+        return;
+      }
+
+      antiChanges.push(historyChangeFromChange(doc, change));
+
+      var after = i ? computeSelAfterChange(doc, change, null) : lst(source);
+      makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
+      if (doc.cm) ensureCursorVisible(doc.cm);
+      var rebased = [];
+
+      // Propagate to the linked documents
+      linkedDocs(doc, function(doc, sharedHist) {
+        if (!sharedHist && indexOf(rebased, doc.history) == -1) {
+          rebaseHist(doc.history, change);
+          rebased.push(doc.history);
+        }
+        makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
+      });
+    }
+  }
+
+  // Sub-views need their line numbers shifted when text is added
+  // above or below them in the parent document.
+  function shiftDoc(doc, distance) {
+    doc.first += distance;
+    doc.sel = new Selection(map(doc.sel.ranges, function(range) {
+      return new Range(Pos(range.anchor.line + distance, range.anchor.ch),
+                       Pos(range.head.line + distance, range.head.ch));
+    }), doc.sel.primIndex);
+    if (doc.cm) regChange(doc.cm, doc.first, doc.first - distance, distance);
+  }
+
+  // More lower-level change function, handling only a single document
+  // (not linked ones).
+  function makeChangeSingleDoc(doc, change, selAfter, spans) {
+    if (doc.cm && !doc.cm.curOp)
+      return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);
+
+    if (change.to.line < doc.first) {
+      shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
+      return;
+    }
+    if (change.from.line > doc.lastLine()) return;
+
+    // Clip the change to the size of this doc
+    if (change.from.line < doc.first) {
+      var shift = change.text.length - 1 - (doc.first - change.from.line);
+      shiftDoc(doc, shift);
+      change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
+                text: [lst(change.text)], origin: change.origin};
+    }
+    var last = doc.lastLine();
+    if (change.to.line > last) {
+      change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
+                text: [change.text[0]], origin: change.origin};
+    }
+
+    change.removed = getBetween(doc, change.from, change.to);
+
+    if (!selAfter) selAfter = computeSelAfterChange(doc, change, null);
+    if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans);
+    else updateDoc(doc, change, spans);
+    setSelectionNoUndo(doc, selAfter, sel_dontScroll);
+  }
+
+  // Handle the interaction of a change to a document with the editor
+  // that this document is part of.
+  function makeChangeSingleDocInEditor(cm, change, spans) {
+    var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
+
+    var recomputeMaxLength = false, checkWidthStart = from.line;
+    if (!cm.options.lineWrapping) {
+      checkWidthStart = lineNo(visualLine(getLine(doc, from.line)));
+      doc.iter(checkWidthStart, to.line + 1, function(line) {
+        if (line == display.maxLine) {
+          recomputeMaxLength = true;
+          return true;
+        }
+      });
+    }
+
+    if (doc.sel.contains(change.from, change.to) > -1)
+      cm.curOp.cursorActivity = true;
+
+    updateDoc(doc, change, spans, estimateHeight(cm));
+
+    if (!cm.options.lineWrapping) {
+      doc.iter(checkWidthStart, from.line + change.text.length, function(line) {
+        var len = lineLength(line);
+        if (len > display.maxLineLength) {
+          display.maxLine = line;
+          display.maxLineLength = len;
+          display.maxLineChanged = true;
+          recomputeMaxLength = false;
+        }
+      });
+      if (recomputeMaxLength) cm.curOp.updateMaxLine = true;
+    }
+
+    // Adjust frontier, schedule worker
+    doc.frontier = Math.min(doc.frontier, from.line);
+    startWorker(cm, 400);
+
+    var lendiff = change.text.length - (to.line - from.line) - 1;
+    // Remember that these lines changed, for updating the display
+    if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
+      regLineChange(cm, from.line, "text");
+    else
+      regChange(cm, from.line, to.line + 1, lendiff);
+
+    if (hasHandler(cm, "change") || hasHandler(cm, "changes"))
+      (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push({
+        from: from, to: to,
+        text: change.text,
+        removed: change.removed,
+        origin: change.origin
+      });
+  }
+
+  function replaceRange(doc, code, from, to, origin) {
+    if (!to) to = from;
+    if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; }
+    if (typeof code == "string") code = splitLines(code);
+    makeChange(doc, {from: from, to: to, text: code, origin: origin});
+  }
+
+  // SCROLLING THINGS INTO VIEW
+
+  // If an editor sits on the top or bottom of the window, partially
+  // scrolled out of view, this ensures that the cursor is visible.
+  function maybeScrollWindow(cm, coords) {
+    var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
+    if (coords.top + box.top < 0) doScroll = true;
+    else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
+    if (doScroll != null && !phantom) {
+      var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " +
+                           (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " +
+                           (coords.bottom - coords.top + scrollerCutOff) + "px; left: " +
+                           coords.left + "px; width: 2px;");
+      cm.display.lineSpace.appendChild(scrollNode);
+      scrollNode.scrollIntoView(doScroll);
+      cm.display.lineSpace.removeChild(scrollNode);
+    }
+  }
+
+  // Scroll a given position into view (immediately), verifying that
+  // it actually became visible (as line heights are accurately
+  // measured, the position of something may 'drift' during drawing).
+  function scrollPosIntoView(cm, pos, end, margin) {
+    if (margin == null) margin = 0;
+    for (;;) {
+      var changed = false, coords = cursorCoords(cm, pos);
+      var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
+      var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left),
+                                         Math.min(coords.top, endCoords.top) - margin,
+                                         Math.max(coords.left, endCoords.left),
+                                         Math.max(coords.bottom, endCoords.bottom) + margin);
+      var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
+      if (scrollPos.scrollTop != null) {
+        setScrollTop(cm, scrollPos.scrollTop);
+        if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;
+      }
+      if (scrollPos.scrollLeft != null) {
+        setScrollLeft(cm, scrollPos.scrollLeft);
+        if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
+      }
+      if (!changed) return coords;
+    }
+  }
+
+  // Scroll a given set of coordinates into view (immediately).
+  function scrollIntoView(cm, x1, y1, x2, y2) {
+    var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
+    if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
+    if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);
+  }
+
+  // Calculate a new scroll position needed to scroll the given
+  // rectangle into view. Returns an object with scrollTop and
+  // scrollLeft properties. When these are undefined, the
+  // vertical/horizontal position does not need to be adjusted.
+  function calculateScrollPos(cm, x1, y1, x2, y2) {
+    var display = cm.display, snapMargin = textHeight(cm.display);
+    if (y1 < 0) y1 = 0;
+    var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
+    var screen = display.scroller.clientHeight - scrollerCutOff, result = {};
+    var docBottom = cm.doc.height + paddingVert(display);
+    var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
+    if (y1 < screentop) {
+      result.scrollTop = atTop ? 0 : y1;
+    } else if (y2 > screentop + screen) {
+      var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen);
+      if (newTop != screentop) result.scrollTop = newTop;
+    }
+
+    var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;
+    var screenw = display.scroller.clientWidth - scrollerCutOff;
+    x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth;
+    var gutterw = display.gutters.offsetWidth;
+    var atLeft = x1 < gutterw + 10;
+    if (x1 < screenleft + gutterw || atLeft) {
+      if (atLeft) x1 = 0;
+      result.scrollLeft = Math.max(0, x1 - 10 - gutterw);
+    } else if (x2 > screenw + screenleft - 3) {
+      result.scrollLeft = x2 + 10 - screenw;
+    }
+    return result;
+  }
+
+  // Store a relative adjustment to the scroll position in the current
+  // operation (to be applied when the operation finishes).
+  function addToScrollPos(cm, left, top) {
+    if (left != null || top != null) resolveScrollToPos(cm);
+    if (left != null)
+      cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left;
+    if (top != null)
+      cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top;
+  }
+
+  // Make sure that at the end of the operation the current cursor is
+  // shown.
+  function ensureCursorVisible(cm) {
+    resolveScrollToPos(cm);
+    var cur = cm.getCursor(), from = cur, to = cur;
+    if (!cm.options.lineWrapping) {
+      from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur;
+      to = Pos(cur.line, cur.ch + 1);
+    }
+    cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true};
+  }
+
+  // When an operation has its scrollToPos property set, and another
+  // scroll action is applied before the end of the operation, this
+  // 'simulates' scrolling that position into view in a cheap way, so
+  // that the effect of intermediate scroll commands is not ignored.
+  function resolveScrollToPos(cm) {
+    var range = cm.curOp.scrollToPos;
+    if (range) {
+      cm.curOp.scrollToPos = null;
+      var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to);
+      var sPos = calculateScrollPos(cm, Math.min(from.left, to.left),
+                                    Math.min(from.top, to.top) - range.margin,
+                                    Math.max(from.right, to.right),
+                                    Math.max(from.bottom, to.bottom) + range.margin);
+      cm.scrollTo(sPos.scrollLeft, sPos.scrollTop);
+    }
+  }
+
+  // API UTILITIES
+
+  // Indent the given line. The how parameter can be "smart",
+  // "add"/null, "subtract", or "prev". When aggressive is false
+  // (typically set to true for forced single-line indents), empty
+  // lines are not indented, and places where the mode returns Pass
+  // are left alone.
+  function indentLine(cm, n, how, aggressive) {
+    var doc = cm.doc, state;
+    if (how == null) how = "add";
+    if (how == "smart") {
+      // Fall back to "prev" when the mode doesn't have an indentation
+      // method.
+      if (!cm.doc.mode.indent) how = "prev";
+      else state = getStateBefore(cm, n);
+    }
+
+    var tabSize = cm.options.tabSize;
+    var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
+    if (line.stateAfter) line.stateAfter = null;
+    var curSpaceString = line.text.match(/^\s*/)[0], indentation;
+    if (!aggressive && !/\S/.test(line.text)) {
+      indentation = 0;
+      how = "not";
+    } else if (how == "smart") {
+      indentation = cm.doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
+      if (indentation == Pass) {
+        if (!aggressive) return;
+        how = "prev";
+      }
+    }
+    if (how == "prev") {
+      if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);
+      else indentation = 0;
+    } else if (how == "add") {
+      indentation = curSpace + cm.options.indentUnit;
+    } else if (how == "subtract") {
+      indentation = curSpace - cm.options.indentUnit;
+    } else if (typeof how == "number") {
+      indentation = curSpace + how;
+    }
+    indentation = Math.max(0, indentation);
+
+    var indentString = "", pos = 0;
+    if (cm.options.indentWithTabs)
+      for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
+    if (pos < indentation) indentString += spaceStr(indentation - pos);
+
+    if (indentString != curSpaceString) {
+      replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
+    } else {
+      // Ensure that, if the cursor was in the whitespace at the start
+      // of the line, it is moved to the end of that space.
+      for (var i = 0; i < doc.sel.ranges.length; i++) {
+        var range = doc.sel.ranges[i];
+        if (range.head.line == n && range.head.ch < curSpaceString.length) {
+          var pos = Pos(n, curSpaceString.length);
+          replaceOneSelection(doc, i, new Range(pos, pos));
+          break;
+        }
+      }
+    }
+    line.stateAfter = null;
+  }
+
+  // Utility for applying a change to a line by handle or number,
+  // returning the number and optionally registering the line as
+  // changed.
+  function changeLine(cm, handle, changeType, op) {
+    var no = handle, line = handle, doc = cm.doc;
+    if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle));
+    else no = lineNo(handle);
+    if (no == null) return null;
+    if (op(line, no)) regLineChange(cm, no, changeType);
+    else return null;
+    return line;
+  }
+
+  // Helper for deleting text near the selection(s), used to implement
+  // backspace, delete, and similar functionality.
+  function deleteNearSelection(cm, compute) {
+    var ranges = cm.doc.sel.ranges, kill = [];
+    // Build up a set of ranges to kill first, merging overlapping
+    // ranges.
+    for (var i = 0; i < ranges.length; i++) {
+      var toKill = compute(ranges[i]);
+      while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {
+        var replaced = kill.pop();
+        if (cmp(replaced.from, toKill.from) < 0) {
+          toKill.from = replaced.from;
+          break;
+        }
+      }
+      kill.push(toKill);
+    }
+    // Next, remove those actual ranges.
+    runInOp(cm, function() {
+      for (var i = kill.length - 1; i >= 0; i--)
+        replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete");
+      ensureCursorVisible(cm);
+    });
+  }
+
+  // Used for horizontal relative motion. Dir is -1 or 1 (left or
+  // right), unit can be "char", "column" (like char, but doesn't
+  // cross line boundaries), "word" (across next word), or "group" (to
+  // the start of next group of word or non-word-non-whitespace
+  // chars). The visually param controls whether, in right-to-left
+  // text, direction 1 means to move towards the next index in the
+  // string, or towards the character to the right of the current
+  // position. The resulting position will have a hitSide=true
+  // property if it reached the end of the document.
+  function findPosH(doc, pos, dir, unit, visually) {
+    var line = pos.line, ch = pos.ch, origDir = dir;
+    var lineObj = getLine(doc, line);
+    var possible = true;
+    function findNextLine() {
+      var l = line + dir;
+      if (l < doc.first || l >= doc.first + doc.size) return (possible = false);
+      line = l;
+      return lineObj = getLine(doc, l);
+    }
+    function moveOnce(boundToLine) {
+      var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);
+      if (next == null) {
+        if (!boundToLine && findNextLine()) {
+          if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
+          else ch = dir < 0 ? lineObj.text.length : 0;
+        } else return (possible = false);
+      } else ch = next;
+      return true;
+    }
+
+    if (unit == "char") moveOnce();
+    else if (unit == "column") moveOnce(true);
+    else if (unit == "word" || unit == "group") {
+      var sawType = null, group = unit == "group";
+      for (var first = true;; first = false) {
+        if (dir < 0 && !moveOnce(!first)) break;
+        var cur = lineObj.text.charAt(ch) || "\n";
+        var type = isWordChar(cur) ? "w"
+          : group && cur == "\n" ? "n"
+          : !group || /\s/.test(cur) ? null
+          : "p";
+        if (group && !first && !type) type = "s";
+        if (sawType && sawType != type) {
+          if (dir < 0) {dir = 1; moveOnce();}
+          break;
+        }
+
+        if (type) sawType = type;
+        if (dir > 0 && !moveOnce(!first)) break;
+      }
+    }
+    var result = skipAtomic(doc, Pos(line, ch), origDir, true);
+    if (!possible) result.hitSide = true;
+    return result;
+  }
+
+  // For relative vertical movement. Dir may be -1 or 1. Unit can be
+  // "page" or "line". The resulting position will have a hitSide=true
+  // property if it reached the end of the document.
+  function findPosV(cm, pos, dir, unit) {
+    var doc = cm.doc, x = pos.left, y;
+    if (unit == "page") {
+      var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
+      y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));
+    } else if (unit == "line") {
+      y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
+    }
+    for (;;) {
+      var target = coordsChar(cm, x, y);
+      if (!target.outside) break;
+      if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; }
+      y += dir * 5;
+    }
+    return target;
+  }
+
+  // Find the word at the given position (as returned by coordsChar).
+  function findWordAt(doc, pos) {
+    var line = getLine(doc, pos.line).text;
+    var start = pos.ch, end = pos.ch;
+    if (line) {
+      if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
+      var startChar = line.charAt(start);
+      var check = isWordChar(startChar) ? isWordChar
+        : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
+        : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
+      while (start > 0 && check(line.charAt(start - 1))) --start;
+      while (end < line.length && check(line.charAt(end))) ++end;
+    }
+    return new Range(Pos(pos.line, start), Pos(pos.line, end));
+  }
+
+  // EDITOR METHODS
+
+  // The publicly visible API. Note that methodOp(f) means
+  // 'wrap f in an operation, performed on its `this` parameter'.
+
+  // This is not the complete set of editor methods. Most of the
+  // methods defined on the Doc type are also injected into
+  // CodeMirror.prototype, for backwards compatibility and
+  // convenience.
+
+  CodeMirror.prototype = {
+    constructor: CodeMirror,
+    focus: function(){window.focus(); focusInput(this); fastPoll(this);},
+
+    setOption: function(option, value) {
+      var options = this.options, old = options[option];
+      if (options[option] == value && option != "mode") return;
+      options[option] = value;
+      if (optionHandlers.hasOwnProperty(option))
+        operation(this, optionHandlers[option])(this, value, old);
+    },
+
+    getOption: function(option) {return this.options[option];},
+    getDoc: function() {return this.doc;},
+
+    addKeyMap: function(map, bottom) {
+      this.state.keyMaps[bottom ? "push" : "unshift"](map);
+    },
+    removeKeyMap: function(map) {
+      var maps = this.state.keyMaps;
+      for (var i = 0; i < maps.length; ++i)
+        if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) {
+          maps.splice(i, 1);
+          return true;
+        }
+    },
+
+    addOverlay: methodOp(function(spec, options) {
+      var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
+      if (mode.startState) throw new Error("Overlays may not be stateful.");
+      this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
+      this.state.modeGen++;
+      regChange(this);
+    }),
+    removeOverlay: methodOp(function(spec) {
+      var overlays = this.state.overlays;
+      for (var i = 0; i < overlays.length; ++i) {
+        var cur = overlays[i].modeSpec;
+        if (cur == spec || typeof spec == "string" && cur.name == spec) {
+          overlays.splice(i, 1);
+          this.state.modeGen++;
+          regChange(this);
+          return;
+        }
+      }
+    }),
+
+    indentLine: methodOp(function(n, dir, aggressive) {
+      if (typeof dir != "string" && typeof dir != "number") {
+        if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
+        else dir = dir ? "add" : "subtract";
+      }
+      if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);
+    }),
+    indentSelection: methodOp(function(how) {
+      var ranges = this.doc.sel.ranges, end = -1;
+      for (var i = 0; i < ranges.length; i++) {
+        var range = ranges[i];
+        if (!range.empty()) {
+          var start = Math.max(end, range.from().line);
+          var to = range.to();
+          end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;
+          for (var j = start; j < end; ++j)
+            indentLine(this, j, how);
+        } else if (range.head.line > end) {
+          indentLine(this, range.head.line, how, true);
+          end = range.head.line;
+          if (i == this.doc.sel.primIndex) ensureCursorVisible(this);
+        }
+      }
+    }),
+
+    // Fetch the parser token for a given character. Useful for hacks
+    // that want to inspect the mode state (say, for completion).
+    getTokenAt: function(pos, precise) {
+      var doc = this.doc;
+      pos = clipPos(doc, pos);
+      var state = getStateBefore(this, pos.line, precise), mode = this.doc.mode;
+      var line = getLine(doc, pos.line);
+      var stream = new StringStream(line.text, this.options.tabSize);
+      while (stream.pos < pos.ch && !stream.eol()) {
+        stream.start = stream.pos;
+        var style = mode.token(stream, state);
+      }
+      return {start: stream.start,
+              end: stream.pos,
+              string: stream.current(),
+              type: style || null,
+              state: state};
+    },
+
+    getTokenTypeAt: function(pos) {
+      pos = clipPos(this.doc, pos);
+      var styles = getLineStyles(this, getLine(this.doc, pos.line));
+      var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
+      if (ch == 0) return styles[2];
+      for (;;) {
+        var mid = (before + after) >> 1;
+        if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
+        else if (styles[mid * 2 + 1] < ch) before = mid + 1;
+        else return styles[mid * 2 + 2];
+      }
+    },
+
+    getModeAt: function(pos) {
+      var mode = this.doc.mode;
+      if (!mode.innerMode) return mode;
+      return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;
+    },
+
+    getHelper: function(pos, type) {
+      return this.getHelpers(pos, type)[0];
+    },
+
+    getHelpers: function(pos, type) {
+      var found = [];
+      if (!helpers.hasOwnProperty(type)) return helpers;
+      var help = helpers[type], mode = this.getModeAt(pos);
+      if (typeof mode[type] == "string") {
+        if (help[mode[type]]) found.push(help[mode[type]]);
+      } else if (mode[type]) {
+        for (var i = 0; i < mode[type].length; i++) {
+          var val = help[mode[type][i]];
+          if (val) found.push(val);
+        }
+      } else if (mode.helperType && help[mode.helperType]) {
+        found.push(help[mode.helperType]);
+      } else if (help[mode.name]) {
+        found.push(help[mode.name]);
+      }
+      for (var i = 0; i < help._global.length; i++) {
+        var cur = help._global[i];
+        if (cur.pred(mode, this) && indexOf(found, cur.val) == -1)
+          found.push(cur.val);
+      }
+      return found;
+    },
+
+    getStateAfter: function(line, precise) {
+      var doc = this.doc;
+      line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
+      return getStateBefore(this, line + 1, precise);
+    },
+
+    cursorCoords: function(start, mode) {
+      var pos, range = this.doc.sel.primary();
+      if (start == null) pos = range.head;
+      else if (typeof start == "object") pos = clipPos(this.doc, start);
+      else pos = start ? range.from() : range.to();
+      return cursorCoords(this, pos, mode || "page");
+    },
+
+    charCoords: function(pos, mode) {
+      return charCoords(this, clipPos(this.doc, pos), mode || "page");
+    },
+
+    coordsChar: function(coords, mode) {
+      coords = fromCoordSystem(this, coords, mode || "page");
+      return coordsChar(this, coords.left, coords.top);
+    },
+
+    lineAtHeight: function(height, mode) {
+      height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
+      return lineAtHeight(this.doc, height + this.display.viewOffset);
+    },
+    heightAtLine: function(line, mode) {
+      var end = false, last = this.doc.first + this.doc.size - 1;
+      if (line < this.doc.first) line = this.doc.first;
+      else if (line > last) { line = last; end = true; }
+      var lineObj = getLine(this.doc, line);
+      return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top +
+        (end ? this.doc.height - heightAtLine(lineObj) : 0);
+    },
+
+    defaultTextHeight: function() { return textHeight(this.display); },
+    defaultCharWidth: function() { return charWidth(this.display); },
+
+    setGutterMarker: methodOp(function(line, gutterID, value) {
+      return changeLine(this, line, "gutter", function(line) {
+        var markers = line.gutterMarkers || (line.gutterMarkers = {});
+        markers[gutterID] = value;
+        if (!value && isEmpty(markers)) line.gutterMarkers = null;
+        return true;
+      });
+    }),
+
+    clearGutter: methodOp(function(gutterID) {
+      var cm = this, doc = cm.doc, i = doc.first;
+      doc.iter(function(line) {
+        if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
+          line.gutterMarkers[gutterID] = null;
+          regLineChange(cm, i, "gutter");
+          if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
+        }
+        ++i;
+      });
+    }),
+
+    addLineClass: methodOp(function(handle, where, cls) {
+      return changeLine(this, handle, "class", function(line) {
+        var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
+        if (!line[prop]) line[prop] = cls;
+        else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false;
+        else line[prop] += " " + cls;
+        return true;
+      });
+    }),
+
+    removeLineClass: methodOp(function(handle, where, cls) {
+      return changeLine(this, handle, "class", function(line) {
+        var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
+        var cur = line[prop];
+        if (!cur) return false;
+        else if (cls == null) line[prop] = null;
+        else {
+          var found = cur.match(new RegExp("(?:^|\\s+)" + cls + "(?:$|\\s+)"));
+          if (!found) return false;
+          var end = found.index + found[0].length;
+          line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
+        }
+        return true;
+      });
+    }),
+
+    addLineWidget: methodOp(function(handle, node, options) {
+      return addLineWidget(this, handle, node, options);
+    }),
+
+    removeLineWidget: function(widget) { widget.clear(); },
+
+    lineInfo: function(line) {
+      if (typeof line == "number") {
+        if (!isLine(this.doc, line)) return null;
+        var n = line;
+        line = getLine(this.doc, line);
+        if (!line) return null;
+      } else {
+        var n = lineNo(line);
+        if (n == null) return null;
+      }
+      return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
+              textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
+              widgets: line.widgets};
+    },
+
+    getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};},
+
+    addWidget: function(pos, node, scroll, vert, horiz) {
+      var display = this.display;
+      pos = cursorCoords(this, clipPos(this.doc, pos));
+      var top = pos.bottom, left = pos.left;
+      node.style.position = "absolute";
+      display.sizer.appendChild(node);
+      if (vert == "over") {
+        top = pos.top;
+      } else if (vert == "above" || vert == "near") {
+        var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
+        hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
+        // Default to positioning above (if specified and possible); otherwise default to positioning below
+        if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
+          top = pos.top - node.offsetHeight;
+        else if (pos.bottom + node.offsetHeight <= vspace)
+          top = pos.bottom;
+        if (left + node.offsetWidth > hspace)
+          left = hspace - node.offsetWidth;
+      }
+      node.style.top = top + "px";
+      node.style.left = node.style.right = "";
+      if (horiz == "right") {
+        left = display.sizer.clientWidth - node.offsetWidth;
+        node.style.right = "0px";
+      } else {
+        if (horiz == "left") left = 0;
+        else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2;
+        node.style.left = left + "px";
+      }
+      if (scroll)
+        scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
+    },
+
+    triggerOnKeyDown: methodOp(onKeyDown),
+    triggerOnKeyPress: methodOp(onKeyPress),
+    triggerOnKeyUp: methodOp(onKeyUp),
+
+    execCommand: function(cmd) {
+      if (commands.hasOwnProperty(cmd))
+        return commands[cmd](this);
+    },
+
+    findPosH: function(from, amount, unit, visually) {
+      var dir = 1;
+      if (amount < 0) { dir = -1; amount = -amount; }
+      for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
+        cur = findPosH(this.doc, cur, dir, unit, visually);
+        if (cur.hitSide) break;
+      }
+      return cur;
+    },
+
+    moveH: methodOp(function(dir, unit) {
+      var cm = this;
+      cm.extendSelectionsBy(function(range) {
+        if (cm.display.shift || cm.doc.extend || range.empty())
+          return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually);
+        else
+          return dir < 0 ? range.from() : range.to();
+      }, sel_move);
+    }),
+
+    deleteH: methodOp(function(dir, unit) {
+      var sel = this.doc.sel, doc = this.doc;
+      if (sel.somethingSelected())
+        doc.replaceSelection("", null, "+delete");
+      else
+        deleteNearSelection(this, function(range) {
+          var other = findPosH(doc, range.head, dir, unit, false);
+          return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other};
+        });
+    }),
+
+    findPosV: function(from, amount, unit, goalColumn) {
+      var dir = 1, x = goalColumn;
+      if (amount < 0) { dir = -1; amount = -amount; }
+      for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
+        var coords = cursorCoords(this, cur, "div");
+        if (x == null) x = coords.left;
+        else coords.left = x;
+        cur = findPosV(this, coords, dir, unit);
+        if (cur.hitSide) break;
+      }
+      return cur;
+    },
+
+    moveV: methodOp(function(dir, unit) {
+      var cm = this, doc = this.doc, goals = [];
+      var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected();
+      doc.extendSelectionsBy(function(range) {
+        if (collapse)
+          return dir < 0 ? range.from() : range.to();
+        var headPos = cursorCoords(cm, range.head, "div");
+        if (range.goalColumn != null) headPos.left = range.goalColumn;
+        goals.push(headPos.left);
+        var pos = findPosV(cm, headPos, dir, unit);
+        if (unit == "page" && range == doc.sel.primary())
+          addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top);
+        return pos;
+      }, sel_move);
+      if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++)
+        doc.sel.ranges[i].goalColumn = goals[i];
+    }),
+
+    toggleOverwrite: function(value) {
+      if (value != null && value == this.state.overwrite) return;
+      if (this.state.overwrite = !this.state.overwrite)
+        this.display.cursorDiv.className += " CodeMirror-overwrite";
+      else
+        this.display.cursorDiv.className = this.display.cursorDiv.className.replace(" CodeMirror-overwrite", "");
+
+      signal(this, "overwriteToggle", this, this.state.overwrite);
+    },
+    hasFocus: function() { return activeElt() == this.display.input; },
+
+    scrollTo: methodOp(function(x, y) {
+      if (x != null || y != null) resolveScrollToPos(this);
+      if (x != null) this.curOp.scrollLeft = x;
+      if (y != null) this.curOp.scrollTop = y;
+    }),
+    getScrollInfo: function() {
+      var scroller = this.display.scroller, co = scrollerCutOff;
+      return {left: scroller.scrollLeft, top: scroller.scrollTop,
+              height: scroller.scrollHeight - co, width: scroller.scrollWidth - co,
+              clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co};
+    },
+
+    scrollIntoView: methodOp(function(range, margin) {
+      if (range == null) {
+        range = {from: this.doc.sel.primary().head, to: null};
+        if (margin == null) margin = this.options.cursorScrollMargin;
+      } else if (typeof range == "number") {
+        range = {from: Pos(range, 0), to: null};
+      } else if (range.from == null) {
+        range = {from: range, to: null};
+      }
+      if (!range.to) range.to = range.from;
+      range.margin = margin || 0;
+
+      if (range.from.line != null) {
+        resolveScrollToPos(this);
+        this.curOp.scrollToPos = range;
+      } else {
+        var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left),
+                                      Math.min(range.from.top, range.to.top) - range.margin,
+                                      Math.max(range.from.right, range.to.right),
+                                      Math.max(range.from.bottom, range.to.bottom) + range.margin);
+        this.scrollTo(sPos.scrollLeft, sPos.scrollTop);
+      }
+    }),
+
+    setSize: methodOp(function(width, height) {
+      function interpret(val) {
+        return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
+      }
+      if (width != null) this.display.wrapper.style.width = interpret(width);
+      if (height != null) this.display.wrapper.style.height = interpret(height);
+      if (this.options.lineWrapping) clearLineMeasurementCache(this);
+      this.curOp.forceUpdate = true;
+      signal(this, "refresh", this);
+    }),
+
+    operation: function(f){return runInOp(this, f);},
+
+    refresh: methodOp(function() {
+      var oldHeight = this.display.cachedTextHeight;
+      regChange(this);
+      clearCaches(this);
+      this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop);
+      if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
+        estimateLineHeights(this);
+      signal(this, "refresh", this);
+    }),
+
+    swapDoc: methodOp(function(doc) {
+      var old = this.doc;
+      old.cm = null;
+      attachDoc(this, doc);
+      clearCaches(this);
+      resetInput(this);
+      this.scrollTo(doc.scrollLeft, doc.scrollTop);
+      signalLater(this, "swapDoc", this, old);
+      return old;
+    }),
+
+    getInputField: function(){return this.display.input;},
+    getWrapperElement: function(){return this.display.wrapper;},
+    getScrollerElement: function(){return this.display.scroller;},
+    getGutterElement: function(){return this.display.gutters;}
+  };
+  eventMixin(CodeMirror);
+
+  // OPTION DEFAULTS
+
+  // The default configuration options.
+  var defaults = CodeMirror.defaults = {};
+  // Functions to run when options are changed.
+  var optionHandlers = CodeMirror.optionHandlers = {};
+
+  function option(name, deflt, handle, notOnInit) {
+    CodeMirror.defaults[name] = deflt;
+    if (handle) optionHandlers[name] =
+      notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;
+  }
+
+  // Passed to option handlers when there is no old value.
+  var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}};
+
+  // These two are, on init, called from the constructor because they
+  // have to be initialized before the editor can start at all.
+  option("value", "", function(cm, val) {
+    cm.setValue(val);
+  }, true);
+  option("mode", null, function(cm, val) {
+    cm.doc.modeOption = val;
+    loadMode(cm);
+  }, true);
+
+  option("indentUnit", 2, loadMode, true);
+  option("indentWithTabs", false);
+  option("smartIndent", true);
+  option("tabSize", 4, function(cm) {
+    resetModeState(cm);
+    clearCaches(cm);
+    regChange(cm);
+  }, true);
+  option("specialChars", /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/g, function(cm, val) {
+    cm.options.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
+    cm.refresh();
+  }, true);
+  option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true);
+  option("electricChars", true);
+  option("rtlMoveVisually", !windows);
+  option("wholeLineUpdateBefore", true);
+
+  option("theme", "default", function(cm) {
+    themeChanged(cm);
+    guttersChanged(cm);
+  }, true);
+  option("keyMap", "default", keyMapChanged);
+  option("extraKeys", null);
+
+  option("lineWrapping", false, wrappingChanged, true);
+  option("gutters", [], function(cm) {
+    setGuttersForLineNumbers(cm.options);
+    guttersChanged(cm);
+  }, true);
+  option("fixedGutter", true, function(cm, val) {
+    cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
+    cm.refresh();
+  }, true);
+  option("coverGutterNextToScrollbar", false, updateScrollbars, true);
+  option("lineNumbers", false, function(cm) {
+    setGuttersForLineNumbers(cm.options);
+    guttersChanged(cm);
+  }, true);
+  option("firstLineNumber", 1, guttersChanged, true);
+  option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
+  option("showCursorWhenSelecting", false, updateSelection, true);
+
+  option("resetSelectionOnContextMenu", true);
+
+  option("readOnly", false, function(cm, val) {
+    if (val == "nocursor") {
+      onBlur(cm);
+      cm.display.input.blur();
+      cm.display.disabled = true;
+    } else {
+      cm.display.disabled = false;
+      if (!val) resetInput(cm);
+    }
+  });
+  option("disableInput", false, function(cm, val) {if (!val) resetInput(cm);}, true);
+  option("dragDrop", true);
+
+  option("cursorBlinkRate", 530);
+  option("cursorScrollMargin", 0);
+  option("cursorHeight", 1);
+  option("workTime", 100);
+  option("workDelay", 100);
+  option("flattenSpans", true, resetModeState, true);
+  option("addModeClass", false, resetModeState, true);
+  option("pollInterval", 100);
+  option("undoDepth", 200, function(cm, val){cm.doc.history.undoDepth = val;});
+  option("historyEventDelay", 1250);
+  option("viewportMargin", 10, function(cm){cm.refresh();}, true);
+  option("maxHighlightLength", 10000, resetModeState, true);
+  option("moveInputWithCursor", true, function(cm, val) {
+    if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
+  });
+
+  option("tabindex", null, function(cm, val) {
+    cm.display.input.tabIndex = val || "";
+  });
+  option("autofocus", null);
+
+  // MODE DEFINITION AND QUERYING
+
+  // Known modes, by name and by MIME
+  var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
+
+  // Extra arguments are stored as the mode's dependencies, which is
+  // used by (legacy) mechanisms like loadmode.js to automatically
+  // load a mode. (Preferred mechanism is the require/define calls.)
+  CodeMirror.defineMode = function(name, mode) {
+    if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
+    if (arguments.length > 2) {
+      mode.dependencies = [];
+      for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
+    }
+    modes[name] = mode;
+  };
+
+  CodeMirror.defineMIME = function(mime, spec) {
+    mimeModes[mime] = spec;
+  };
+
+  // Given a MIME type, a {name, ...options} config object, or a name
+  // string, return a mode config object.
+  CodeMirror.resolveMode = function(spec) {
+    if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
+      spec = mimeModes[spec];
+    } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
+      var found = mimeModes[spec.name];
+      if (typeof found == "string") found = {name: found};
+      spec = createObj(found, spec);
+      spec.name = found.name;
+    } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
+      return CodeMirror.resolveMode("application/xml");
+    }
+    if (typeof spec == "string") return {name: spec};
+    else return spec || {name: "null"};
+  };
+
+  // Given a mode spec (anything that resolveMode accepts), find and
+  // initialize an actual mode object.
+  CodeMirror.getMode = function(options, spec) {
+    var spec = CodeMirror.resolveMode(spec);
+    var mfactory = modes[spec.name];
+    if (!mfactory) return CodeMirror.getMode(options, "text/plain");
+    var modeObj = mfactory(options, spec);
+    if (modeExtensions.hasOwnProperty(spec.name)) {
+      var exts = modeExtensions[spec.name];
+      for (var prop in exts) {
+        if (!exts.hasOwnProperty(prop)) continue;
+        if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
+        modeObj[prop] = exts[prop];
+      }
+    }
+    modeObj.name = spec.name;
+    if (spec.helperType) modeObj.helperType = spec.helperType;
+    if (spec.modeProps) for (var prop in spec.modeProps)
+      modeObj[prop] = spec.modeProps[prop];
+
+    return modeObj;
+  };
+
+  // Minimal default mode.
+  CodeMirror.defineMode("null", function() {
+    return {token: function(stream) {stream.skipToEnd();}};
+  });
+  CodeMirror.defineMIME("text/plain", "null");
+
+  // This can be used to attach properties to mode objects from
+  // outside the actual mode definition.
+  var modeExtensions = CodeMirror.modeExtensions = {};
+  CodeMirror.extendMode = function(mode, properties) {
+    var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
+    copyObj(properties, exts);
+  };
+
+  // EXTENSIONS
+
+  CodeMirror.defineExtension = function(name, func) {
+    CodeMirror.prototype[name] = func;
+  };
+  CodeMirror.defineDocExtension = function(name, func) {
+    Doc.prototype[name] = func;
+  };
+  CodeMirror.defineOption = option;
+
+  var initHooks = [];
+  CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
+
+  var helpers = CodeMirror.helpers = {};
+  CodeMirror.registerHelper = function(type, name, value) {
+    if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []};
+    helpers[type][name] = value;
+  };
+  CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {
+    CodeMirror.registerHelper(type, name, value);
+    helpers[type]._global.push({pred: predicate, val: value});
+  };
+
+  // MODE STATE HANDLING
+
+  // Utility functions for working with state. Exported because nested
+  // modes need to do this for their inner modes.
+
+  var copyState = CodeMirror.copyState = function(mode, state) {
+    if (state === true) return state;
+    if (mode.copyState) return mode.copyState(state);
+    var nstate = {};
+    for (var n in state) {
+      var val = state[n];
+      if (val instanceof Array) val = val.concat([]);
+      nstate[n] = val;
+    }
+    return nstate;
+  };
+
+  var startState = CodeMirror.startState = function(mode, a1, a2) {
+    return mode.startState ? mode.startState(a1, a2) : true;
+  };
+
+  // Given a mode and a state (for that mode), find the inner mode and
+  // state at the position that the state refers to.
+  CodeMirror.innerMode = function(mode, state) {
+    while (mode.innerMode) {
+      var info = mode.innerMode(state);
+      if (!info || info.mode == mode) break;
+      state = info.state;
+      mode = info.mode;
+    }
+    return info || {mode: mode, state: state};
+  };
+
+  // STANDARD COMMANDS
+
+  // Commands are parameter-less actions that can be performed on an
+  // editor, mostly used for keybindings.
+  var commands = CodeMirror.commands = {
+    selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);},
+    singleSelection: function(cm) {
+      cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll);
+    },
+    killLine: function(cm) {
+      deleteNearSelection(cm, function(range) {
+        if (range.empty()) {
+          var len = getLine(cm.doc, range.head.line).text.length;
+          if (range.head.ch == len && range.head.line < cm.lastLine())
+            return {from: range.head, to: Pos(range.head.line + 1, 0)};
+          else
+            return {from: range.head, to: Pos(range.head.line, len)};
+        } else {
+          return {from: range.from(), to: range.to()};
+        }
+      });
+    },
+    deleteLine: function(cm) {
+      deleteNearSelection(cm, function(range) {
+        return {from: Pos(range.from().line, 0),
+                to: clipPos(cm.doc, Pos(range.to().line + 1, 0))};
+      });
+    },
+    delLineLeft: function(cm) {
+      deleteNearSelection(cm, function(range) {
+        return {from: Pos(range.from().line, 0), to: range.from()};
+      });
+    },
+    undo: function(cm) {cm.undo();},
+    redo: function(cm) {cm.redo();},
+    undoSelection: function(cm) {cm.undoSelection();},
+    redoSelection: function(cm) {cm.redoSelection();},
+    goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},
+    goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},
+    goLineStart: function(cm) {
+      cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); }, sel_move);
+    },
+    goLineStartSmart: function(cm) {
+      cm.extendSelectionsBy(function(range) {
+        var start = lineStart(cm, range.head.line);
+        var line = cm.getLineHandle(start.line);
+        var order = getOrder(line);
+        if (!order || order[0].level == 0) {
+          var firstNonWS = Math.max(0, line.text.search(/\S/));
+          var inWS = range.head.line == start.line && range.head.ch <= firstNonWS && range.head.ch;
+          return Pos(start.line, inWS ? 0 : firstNonWS);
+        }
+        return start;
+      }, sel_move);
+    },
+    goLineEnd: function(cm) {
+      cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); }, sel_move);
+    },
+    goLineRight: function(cm) {
+      cm.extendSelectionsBy(function(range) {
+        var top = cm.charCoords(range.head, "div").top + 5;
+        return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
+      }, sel_move);
+    },
+    goLineLeft: function(cm) {
+      cm.extendSelectionsBy(function(range) {
+        var top = cm.charCoords(range.head, "div").top + 5;
+        return cm.coordsChar({left: 0, top: top}, "div");
+      }, sel_move);
+    },
+    goLineUp: function(cm) {cm.moveV(-1, "line");},
+    goLineDown: function(cm) {cm.moveV(1, "line");},
+    goPageUp: function(cm) {cm.moveV(-1, "page");},
+    goPageDown: function(cm) {cm.moveV(1, "page");},
+    goCharLeft: function(cm) {cm.moveH(-1, "char");},
+    goCharRight: function(cm) {cm.moveH(1, "char");},
+    goColumnLeft: function(cm) {cm.moveH(-1, "column");},
+    goColumnRight: function(cm) {cm.moveH(1, "column");},
+    goWordLeft: function(cm) {cm.moveH(-1, "word");},
+    goGroupRight: function(cm) {cm.moveH(1, "group");},
+    goGroupLeft: function(cm) {cm.moveH(-1, "group");},
+    goWordRight: function(cm) {cm.moveH(1, "word");},
+    delCharBefore: function(cm) {cm.deleteH(-1, "char");},
+    delCharAfter: function(cm) {cm.deleteH(1, "char");},
+    delWordBefore: function(cm) {cm.deleteH(-1, "word");},
+    delWordAfter: function(cm) {cm.deleteH(1, "word");},
+    delGroupBefore: function(cm) {cm.deleteH(-1, "group");},
+    delGroupAfter: function(cm) {cm.deleteH(1, "group");},
+    indentAuto: function(cm) {cm.indentSelection("smart");},
+    indentMore: function(cm) {cm.indentSelection("add");},
+    indentLess: function(cm) {cm.indentSelection("subtract");},
+    insertTab: function(cm) {cm.replaceSelection("\t");},
+    defaultTab: function(cm) {
+      if (cm.somethingSelected()) cm.indentSelection("add");
+      else cm.execCommand("insertTab");
+    },
+    transposeChars: function(cm) {
+      runInOp(cm, function() {
+        var ranges = cm.listSelections();
+        for (var i = 0; i < ranges.length; i++) {
+          var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;
+          if (cur.ch > 0 && cur.ch < line.length - 1)
+            cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
+                            Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
+        }
+      });
+    },
+    newlineAndIndent: function(cm) {
+      runInOp(cm, function() {
+        var len = cm.listSelections().length;
+        for (var i = 0; i < len; i++) {
+          var range = cm.listSelections()[i];
+          cm.replaceRange("\n", range.anchor, range.head, "+input");
+          cm.indentLine(range.from().line + 1, null, true);
+          ensureCursorVisible(cm);
+        }
+      });
+    },
+    toggleOverwrite: function(cm) {cm.toggleOverwrite();}
+  };
+
+  // STANDARD KEYMAPS
+
+  var keyMap = CodeMirror.keyMap = {};
+  keyMap.basic = {
+    "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
+    "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
+    "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore",
+    "Tab": "defaultTab", "Shift-Tab": "indentAuto",
+    "Enter": "newlineAndIndent", "Insert": "toggleOverwrite",
+    "Esc": "singleSelection"
+  };
+  // Note that the save and find-related commands aren't defined by
+  // default. User code or addons can define them. Unknown commands
+  // are simply ignored.
+  keyMap.pcDefault = {
+    "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
+    "Ctrl-Home": "goDocStart", "Ctrl-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
+    "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
+    "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
+    "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
+    "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
+    "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
+    fallthrough: "basic"
+  };
+  keyMap.macDefault = {
+    "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
+    "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
+    "Alt-Right": "goGroupRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delGroupBefore",
+    "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
+    "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
+    "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delLineLeft",
+    "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection",
+    fallthrough: ["basic", "emacsy"]
+  };
+  // Very basic readline/emacs-style bindings, which are standard on Mac.
+  keyMap.emacsy = {
+    "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
+    "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
+    "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
+    "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
+  };
+  keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
+
+  // KEYMAP DISPATCH
+
+  function getKeyMap(val) {
+    if (typeof val == "string") return keyMap[val];
+    else return val;
+  }
+
+  // Given an array of keymaps and a key name, call handle on any
+  // bindings found, until that returns a truthy value, at which point
+  // we consider the key handled. Implements things like binding a key
+  // to false stopping further handling and keymap fallthrough.
+  var lookupKey = CodeMirror.lookupKey = function(name, maps, handle) {
+    function lookup(map) {
+      map = getKeyMap(map);
+      var found = map[name];
+      if (found === false) return "stop";
+      if (found != null && handle(found)) return true;
+      if (map.nofallthrough) return "stop";
+
+      var fallthrough = map.fallthrough;
+      if (fallthrough == null) return false;
+      if (Object.prototype.toString.call(fallthrough) != "[object Array]")
+        return lookup(fallthrough);
+      for (var i = 0; i < fallthrough.length; ++i) {
+        var done = lookup(fallthrough[i]);
+        if (done) return done;
+      }
+      return false;
+    }
+
+    for (var i = 0; i < maps.length; ++i) {
+      var done = lookup(maps[i]);
+      if (done) return done != "stop";
+    }
+  };
+
+  // Modifier key presses don't count as 'real' key presses for the
+  // purpose of keymap fallthrough.
+  var isModifierKey = CodeMirror.isModifierKey = function(event) {
+    var name = keyNames[event.keyCode];
+    return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
+  };
+
+  // Look up the name of a key as indicated by an event object.
+  var keyName = CodeMirror.keyName = function(event, noShift) {
+    if (presto && event.keyCode == 34 && event["char"]) return false;
+    var name = keyNames[event.keyCode];
+    if (name == null || event.altGraphKey) return false;
+    if (event.altKey) name = "Alt-" + name;
+    if (flipCtrlCmd ? event.metaKey : event.ctrlKey) name = "Ctrl-" + name;
+    if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name;
+    if (!noShift && event.shiftKey) name = "Shift-" + name;
+    return name;
+  };
+
+  // FROMTEXTAREA
+
+  CodeMirror.fromTextArea = function(textarea, options) {
+    if (!options) options = {};
+    options.value = textarea.value;
+    if (!options.tabindex && textarea.tabindex)
+      options.tabindex = textarea.tabindex;
+    if (!options.placeholder && textarea.placeholder)
+      options.placeholder = textarea.placeholder;
+    // Set autofocus to true if this textarea is focused, or if it has
+    // autofocus and no other element is focused.
+    if (options.autofocus == null) {
+      var hasFocus = activeElt();
+      options.autofocus = hasFocus == textarea ||
+        textarea.getAttribute("autofocus") != null && hasFocus == document.body;
+    }
+
+    function save() {textarea.value = cm.getValue();}
+    if (textarea.form) {
+      on(textarea.form, "submit", save);
+      // Deplorable hack to make the submit method do the right thing.
+      if (!options.leaveSubmitMethodAlone) {
+        var form = textarea.form, realSubmit = form.submit;
+        try {
+          var wrappedSubmit = form.submit = function() {
+            save();
+            form.submit = realSubmit;
+            form.submit();
+            form.submit = wrappedSubmit;
+          };
+        } catch(e) {}
+      }
+    }
+
+    textarea.style.display = "none";
+    var cm = CodeMirror(function(node) {
+      textarea.parentNode.insertBefore(node, textarea.nextSibling);
+    }, options);
+    cm.save = save;
+    cm.getTextArea = function() { return textarea; };
+    cm.toTextArea = function() {
+      save();
+      textarea.parentNode.removeChild(cm.getWrapperElement());
+      textarea.style.display = "";
+      if (textarea.form) {
+        off(textarea.form, "submit", save);
+        if (typeof textarea.form.submit == "function")
+          textarea.form.submit = realSubmit;
+      }
+    };
+    return cm;
+  };
+
+  // STRING STREAM
+
+  // Fed to the mode parsers, provides helper functions to make
+  // parsers more succinct.
+
+  var StringStream = CodeMirror.StringStream = function(string, tabSize) {
+    this.pos = this.start = 0;
+    this.string = string;
+    this.tabSize = tabSize || 8;
+    this.lastColumnPos = this.lastColumnValue = 0;
+    this.lineStart = 0;
+  };
+
+  StringStream.prototype = {
+    eol: function() {return this.pos >= this.string.length;},
+    sol: function() {return this.pos == this.lineStart;},
+    peek: function() {return this.string.charAt(this.pos) || undefined;},
+    next: function() {
+      if (this.pos < this.string.length)
+        return this.string.charAt(this.pos++);
+    },
+    eat: function(match) {
+      var ch = this.string.charAt(this.pos);
+      if (typeof match == "string") var ok = ch == match;
+      else var ok = ch && (match.test ? match.test(ch) : match(ch));
+      if (ok) {++this.pos; return ch;}
+    },
+    eatWhile: function(match) {
+      var start = this.pos;
+      while (this.eat(match)){}
+      return this.pos > start;
+    },
+    eatSpace: function() {
+      var start = this.pos;
+      while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
+      return this.pos > start;
+    },
+    skipToEnd: function() {this.pos = this.string.length;},
+    skipTo: function(ch) {
+      var found = this.string.indexOf(ch, this.pos);
+      if (found > -1) {this.pos = found; return true;}
+    },
+    backUp: function(n) {this.pos -= n;},
+    column: function() {
+      if (this.lastColumnPos < this.start) {
+        this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
+        this.lastColumnPos = this.start;
+      }
+      return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
+    },
+    indentation: function() {
+      return countColumn(this.string, null, this.tabSize) -
+        (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
+    },
+    match: function(pattern, consume, caseInsensitive) {
+      if (typeof pattern == "string") {
+        var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
+        var substr = this.string.substr(this.pos, pattern.length);
+        if (cased(substr) == cased(pattern)) {
+          if (consume !== false) this.pos += pattern.length;
+          return true;
+        }
+      } else {
+        var match = this.string.slice(this.pos).match(pattern);
+        if (match && match.index > 0) return null;
+        if (match && consume !== false) this.pos += match[0].length;
+        return match;
+      }
+    },
+    current: function(){return this.string.slice(this.start, this.pos);},
+    hideFirstChars: function(n, inner) {
+      this.lineStart += n;
+      try { return inner(); }
+      finally { this.lineStart -= n; }
+    }
+  };
+
+  // TEXTMARKERS
+
+  // Created with markText and setBookmark methods. A TextMarker is a
+  // handle that can be used to clear or find a marked position in the
+  // document. Line objects hold arrays (markedSpans) containing
+  // {from, to, marker} object pointing to such marker objects, and
+  // indicating that such a marker is present on that line. Multiple
+  // lines may point to the same marker when it spans across lines.
+  // The spans will have null for their from/to properties when the
+  // marker continues beyond the start/end of the line. Markers have
+  // links back to the lines they currently touch.
+
+  var TextMarker = CodeMirror.TextMarker = function(doc, type) {
+    this.lines = [];
+    this.type = type;
+    this.doc = doc;
+  };
+  eventMixin(TextMarker);
+
+  // Clear the marker.
+  TextMarker.prototype.clear = function() {
+    if (this.explicitlyCleared) return;
+    var cm = this.doc.cm, withOp = cm && !cm.curOp;
+    if (withOp) startOperation(cm);
+    if (hasHandler(this, "clear")) {
+      var found = this.find();
+      if (found) signalLater(this, "clear", found.from, found.to);
+    }
+    var min = null, max = null;
+    for (var i = 0; i < this.lines.length; ++i) {
+      var line = this.lines[i];
+      var span = getMarkedSpanFor(line.markedSpans, this);
+      if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text");
+      else if (cm) {
+        if (span.to != null) max = lineNo(line);
+        if (span.from != null) min = lineNo(line);
+      }
+      line.markedSpans = removeMarkedSpan(line.markedSpans, span);
+      if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm)
+        updateLineHeight(line, textHeight(cm.display));
+    }
+    if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
+      var visual = visualLine(this.lines[i]), len = lineLength(visual);
+      if (len > cm.display.maxLineLength) {
+        cm.display.maxLine = visual;
+        cm.display.maxLineLength = len;
+        cm.display.maxLineChanged = true;
+      }
+    }
+
+    if (min != null && cm && this.collapsed) regChange(cm, min, max + 1);
+    this.lines.length = 0;
+    this.explicitlyCleared = true;
+    if (this.atomic && this.doc.cantEdit) {
+      this.doc.cantEdit = false;
+      if (cm) reCheckSelection(cm.doc);
+    }
+    if (cm) signalLater(cm, "markerCleared", cm, this);
+    if (withOp) endOperation(cm);
+  };
+
+  // Find the position of the marker in the document. Returns a {from,
+  // to} object by default. Side can be passed to get a specific side
+  // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the
+  // Pos objects returned contain a line object, rather than a line
+  // number (used to prevent looking up the same line twice).
+  TextMarker.prototype.find = function(side, lineObj) {
+    if (side == null && this.type == "bookmark") side = 1;
+    var from, to;
+    for (var i = 0; i < this.lines.length; ++i) {
+      var line = this.lines[i];
+      var span = getMarkedSpanFor(line.markedSpans, this);
+      if (span.from != null) {
+        from = Pos(lineObj ? line : lineNo(line), span.from);
+        if (side == -1) return from;
+      }
+      if (span.to != null) {
+        to = Pos(lineObj ? line : lineNo(line), span.to);
+        if (side == 1) return to;
+      }
+    }
+    return from && {from: from, to: to};
+  };
+
+  // Signals that the marker's widget changed, and surrounding layout
+  // should be recomputed.
+  TextMarker.prototype.changed = function() {
+    var pos = this.find(-1, true), widget = this, cm = this.doc.cm;
+    if (!pos || !cm) return;
+    runInOp(cm, function() {
+      var line = pos.line, lineN = lineNo(pos.line);
+      var view = findViewForLine(cm, lineN);
+      if (view) {
+        clearLineMeasurementCacheFor(view);
+        cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;
+      }
+      cm.curOp.updateMaxLine = true;
+      if (!lineIsHidden(widget.doc, line) && widget.height != null) {
+        var oldHeight = widget.height;
+        widget.height = null;
+        var dHeight = widgetHeight(widget) - oldHeight;
+        if (dHeight)
+          updateLineHeight(line, line.height + dHeight);
+      }
+    });
+  };
+
+  TextMarker.prototype.attachLine = function(line) {
+    if (!this.lines.length && this.doc.cm) {
+      var op = this.doc.cm.curOp;
+      if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
+        (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);
+    }
+    this.lines.push(line);
+  };
+  TextMarker.prototype.detachLine = function(line) {
+    this.lines.splice(indexOf(this.lines, line), 1);
+    if (!this.lines.length && this.doc.cm) {
+      var op = this.doc.cm.curOp;
+      (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
+    }
+  };
+
+  // Collapsed markers have unique ids, in order to be able to order
+  // them, which is needed for uniquely determining an outer marker
+  // when they overlap (they may nest, but not partially overlap).
+  var nextMarkerId = 0;
+
+  // Create a marker, wire it up to the right lines, and
+  function markText(doc, from, to, options, type) {
+    // Shared markers (across linked documents) are handled separately
+    // (markTextShared will call out to this again, once per
+    // document).
+    if (options && options.shared) return markTextShared(doc, from, to, options, type);
+    // Ensure we are in an operation.
+    if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
+
+    var marker = new TextMarker(doc, type), diff = cmp(from, to);
+    if (options) copyObj(options, marker);
+    // Don't connect empty markers unless clearWhenEmpty is false
+    if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)
+      return marker;
+    if (marker.replacedWith) {
+      // Showing up as a widget implies collapsed (widget replaces text)
+      marker.collapsed = true;
+      marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget");
+      if (!options.handleMouseEvents) marker.widgetNode.ignoreEvents = true;
+      if (options.insertLeft) marker.widgetNode.insertLeft = true;
+    }
+    if (marker.collapsed) {
+      if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||
+          from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))
+        throw new Error("Inserting collapsed marker partially overlapping an existing one");
+      sawCollapsedSpans = true;
+    }
+
+    if (marker.addToHistory)
+      addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN);
+
+    var curLine = from.line, cm = doc.cm, updateMaxLine;
+    doc.iter(curLine, to.line + 1, function(line) {
+      if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)
+        updateMaxLine = true;
+      if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0);
+      addMarkedSpan(line, new MarkedSpan(marker,
+                                         curLine == from.line ? from.ch : null,
+                                         curLine == to.line ? to.ch : null));
+      ++curLine;
+    });
+    // lineIsHidden depends on the presence of the spans, so needs a second pass
+    if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
+      if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
+    });
+
+    if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); });
+
+    if (marker.readOnly) {
+      sawReadOnlySpans = true;
+      if (doc.history.done.length || doc.history.undone.length)
+        doc.clearHistory();
+    }
+    if (marker.collapsed) {
+      marker.id = ++nextMarkerId;
+      marker.atomic = true;
+    }
+    if (cm) {
+      // Sync editor state
+      if (updateMaxLine) cm.curOp.updateMaxLine = true;
+      if (marker.collapsed)
+        regChange(cm, from.line, to.line + 1);
+      else if (marker.className || marker.title || marker.startStyle || marker.endStyle)
+        for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text");
+      if (marker.atomic) reCheckSelection(cm.doc);
+      signalLater(cm, "markerAdded", cm, marker);
+    }
+    return marker;
+  }
+
+  // SHARED TEXTMARKERS
+
+  // A shared marker spans multiple linked documents. It is
+  // implemented as a meta-marker-object controlling multiple normal
+  // markers.
+  var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) {
+    this.markers = markers;
+    this.primary = primary;
+    for (var i = 0, me = this; i < markers.length; ++i) {
+      markers[i].parent = this;
+      on(markers[i], "clear", function(){me.clear();});
+    }
+  };
+  eventMixin(SharedTextMarker);
+
+  SharedTextMarker.prototype.clear = function() {
+    if (this.explicitlyCleared) return;
+    this.explicitlyCleared = true;
+    for (var i = 0; i < this.markers.length; ++i)
+      this.markers[i].clear();
+    signalLater(this, "clear");
+  };
+  SharedTextMarker.prototype.find = function(side, lineObj) {
+    return this.primary.find(side, lineObj);
+  };
+
+  function markTextShared(doc, from, to, options, type) {
+    options = copyObj(options);
+    options.shared = false;
+    var markers = [markText(doc, from, to, options, type)], primary = markers[0];
+    var widget = options.widgetNode;
+    linkedDocs(doc, function(doc) {
+      if (widget) options.widgetNode = widget.cloneNode(true);
+      markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
+      for (var i = 0; i < doc.linked.length; ++i)
+        if (doc.linked[i].isParent) return;
+      primary = lst(markers);
+    });
+    return new SharedTextMarker(markers, primary);
+  }
+
+  // TEXTMARKER SPANS
+
+  function MarkedSpan(marker, from, to) {
+    this.marker = marker;
+    this.from = from; this.to = to;
+  }
+
+  // Search an array of spans for a span matching the given marker.
+  function getMarkedSpanFor(spans, marker) {
+    if (spans) for (var i = 0; i < spans.length; ++i) {
+      var span = spans[i];
+      if (span.marker == marker) return span;
+    }
+  }
+  // Remove a span from an array, returning undefined if no spans are
+  // left (we don't store arrays for lines without spans).
+  function removeMarkedSpan(spans, span) {
+    for (var r, i = 0; i < spans.length; ++i)
+      if (spans[i] != span) (r || (r = [])).push(spans[i]);
+    return r;
+  }
+  // Add a span to a line.
+  function addMarkedSpan(line, span) {
+    line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
+    span.marker.attachLine(line);
+  }
+
+  // Used for the algorithm that adjusts markers for a change in the
+  // document. These functions cut an array of spans at a given
+  // character position, returning an array of remaining chunks (or
+  // undefined if nothing remains).
+  function markedSpansBefore(old, startCh, isInsert) {
+    if (old) for (var i = 0, nw; i < old.length; ++i) {
+      var span = old[i], marker = span.marker;
+      var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
+      if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
+        var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
+        (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));
+      }
+    }
+    return nw;
+  }
+  function markedSpansAfter(old, endCh, isInsert) {
+    if (old) for (var i = 0, nw; i < old.length; ++i) {
+      var span = old[i], marker = span.marker;
+      var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
+      if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
+        var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
+        (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
+                                              span.to == null ? null : span.to - endCh));
+      }
+    }
+    return nw;
+  }
+
+  // Given a change object, compute the new set of marker spans that
+  // cover the line in which the change took place. Removes spans
+  // entirely within the change, reconnects spans belonging to the
+  // same marker that appear on both sides of the change, and cuts off
+  // spans partially within the change. Returns an array of span
+  // arrays with one element for each line in (after) the change.
+  function stretchSpansOverChange(doc, change) {
+    var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
+    var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
+    if (!oldFirst && !oldLast) return null;
+
+    var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0;
+    // Get the spans that 'stick out' on both sides
+    var first = markedSpansBefore(oldFirst, startCh, isInsert);
+    var last = markedSpansAfter(oldLast, endCh, isInsert);
+
+    // Next, merge those two ends
+    var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
+    if (first) {
+      // Fix up .to properties of first
+      for (var i = 0; i < first.length; ++i) {
+        var span = first[i];
+        if (span.to == null) {
+          var found = getMarkedSpanFor(last, span.marker);
+          if (!found) span.to = startCh;
+          else if (sameLine) span.to = found.to == null ? null : found.to + offset;
+        }
+      }
+    }
+    if (last) {
+      // Fix up .from in last (or move them into first in case of sameLine)
+      for (var i = 0; i < last.length; ++i) {
+        var span = last[i];
+        if (span.to != null) span.to += offset;
+        if (span.from == null) {
+          var found = getMarkedSpanFor(first, span.marker);
+          if (!found) {
+            span.from = offset;
+            if (sameLine) (first || (first = [])).push(span);
+          }
+        } else {
+          span.from += offset;
+          if (sameLine) (first || (first = [])).push(span);
+        }
+      }
+    }
+    // Make sure we didn't create any zero-length spans
+    if (first) first = clearEmptySpans(first);
+    if (last && last != first) last = clearEmptySpans(last);
+
+    var newMarkers = [first];
+    if (!sameLine) {
+      // Fill gap with whole-line-spans
+      var gap = change.text.length - 2, gapMarkers;
+      if (gap > 0 && first)
+        for (var i = 0; i < first.length; ++i)
+          if (first[i].to == null)
+            (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null));
+      for (var i = 0; i < gap; ++i)
+        newMarkers.push(gapMarkers);
+      newMarkers.push(last);
+    }
+    return newMarkers;
+  }
+
+  // Remove spans that are empty and don't have a clearWhenEmpty
+  // option of false.
+  function clearEmptySpans(spans) {
+    for (var i = 0; i < spans.length; ++i) {
+      var span = spans[i];
+      if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
+        spans.splice(i--, 1);
+    }
+    if (!spans.length) return null;
+    return spans;
+  }
+
+  // Used for un/re-doing changes from the history. Combines the
+  // result of computing the existing spans with the set of spans that
+  // existed in the history (so that deleting around a span and then
+  // undoing brings back the span).
+  function mergeOldSpans(doc, change) {
+    var old = getOldSpans(doc, change);
+    var stretched = stretchSpansOverChange(doc, change);
+    if (!old) return stretched;
+    if (!stretched) return old;
+
+    for (var i = 0; i < old.length; ++i) {
+      var oldCur = old[i], stretchCur = stretched[i];
+      if (oldCur && stretchCur) {
+        spans: for (var j = 0; j < stretchCur.length; ++j) {
+          var span = stretchCur[j];
+          for (var k = 0; k < oldCur.length; ++k)
+            if (oldCur[k].marker == span.marker) continue spans;
+          oldCur.push(span);
+        }
+      } else if (stretchCur) {
+        old[i] = stretchCur;
+      }
+    }
+    return old;
+  }
+
+  // Used to 'clip' out readOnly ranges when making a change.
+  function removeReadOnlyRanges(doc, from, to) {
+    var markers = null;
+    doc.iter(from.line, to.line + 1, function(line) {
+      if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
+        var mark = line.markedSpans[i].marker;
+        if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
+          (markers || (markers = [])).push(mark);
+      }
+    });
+    if (!markers) return null;
+    var parts = [{from: from, to: to}];
+    for (var i = 0; i < markers.length; ++i) {
+      var mk = markers[i], m = mk.find(0);
+      for (var j = 0; j < parts.length; ++j) {
+        var p = parts[j];
+        if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue;
+        var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to);
+        if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)
+          newParts.push({from: p.from, to: m.from});
+        if (dto > 0 || !mk.inclusiveRight && !dto)
+          newParts.push({from: m.to, to: p.to});
+        parts.splice.apply(parts, newParts);
+        j += newParts.length - 1;
+      }
+    }
+    return parts;
+  }
+
+  // Connect or disconnect spans from a line.
+  function detachMarkedSpans(line) {
+    var spans = line.markedSpans;
+    if (!spans) return;
+    for (var i = 0; i < spans.length; ++i)
+      spans[i].marker.detachLine(line);
+    line.markedSpans = null;
+  }
+  function attachMarkedSpans(line, spans) {
+    if (!spans) return;
+    for (var i = 0; i < spans.length; ++i)
+      spans[i].marker.attachLine(line);
+    line.markedSpans = spans;
+  }
+
+  // Helpers used when computing which overlapping collapsed span
+  // counts as the larger one.
+  function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; }
+  function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; }
+
+  // Returns a number indicating which of two overlapping collapsed
+  // spans is larger (and thus includes the other). Falls back to
+  // comparing ids when the spans cover exactly the same range.
+  function compareCollapsedMarkers(a, b) {
+    var lenDiff = a.lines.length - b.lines.length;
+    if (lenDiff != 0) return lenDiff;
+    var aPos = a.find(), bPos = b.find();
+    var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);
+    if (fromCmp) return -fromCmp;
+    var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);
+    if (toCmp) return toCmp;
+    return b.id - a.id;
+  }
+
+  // Find out whether a line ends or starts in a collapsed span. If
+  // so, return the marker for that span.
+  function collapsedSpanAtSide(line, start) {
+    var sps = sawCollapsedSpans && line.markedSpans, found;
+    if (sps) for (var sp, i = 0; i < sps.length; ++i) {
+      sp = sps[i];
+      if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&
+          (!found || compareCollapsedMarkers(found, sp.marker) < 0))
+        found = sp.marker;
+    }
+    return found;
+  }
+  function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); }
+  function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); }
+
+  // Test whether there exists a collapsed span that partially
+  // overlaps (covers the start or end, but not both) of a new span.
+  // Such overlap is not allowed.
+  function conflictingCollapsedRange(doc, lineNo, from, to, marker) {
+    var line = getLine(doc, lineNo);
+    var sps = sawCollapsedSpans && line.markedSpans;
+    if (sps) for (var i = 0; i < sps.length; ++i) {
+      var sp = sps[i];
+      if (!sp.marker.collapsed) continue;
+      var found = sp.marker.find(0);
+      var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker);
+      var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);
+      if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue;
+      if (fromCmp <= 0 && (cmp(found.to, from) || extraRight(sp.marker) - extraLeft(marker)) > 0 ||
+          fromCmp >= 0 && (cmp(found.from, to) || extraLeft(sp.marker) - extraRight(marker)) < 0)
+        return true;
+    }
+  }
+
+  // A visual line is a line as drawn on the screen. Folding, for
+  // example, can cause multiple logical lines to appear on the same
+  // visual line. This finds the start of the visual line that the
+  // given line is part of (usually that is the line itself).
+  function visualLine(line) {
+    var merged;
+    while (merged = collapsedSpanAtStart(line))
+      line = merged.find(-1, true).line;
+    return line;
+  }
+
+  // Returns an array of logical lines that continue the visual line
+  // started by the argument, or undefined if there are no such lines.
+  function visualLineContinued(line) {
+    var merged, lines;
+    while (merged = collapsedSpanAtEnd(line)) {
+      line = merged.find(1, true).line;
+      (lines || (lines = [])).push(line);
+    }
+    return lines;
+  }
+
+  // Get the line number of the start of the visual line that the
+  // given line number is part of.
+  function visualLineNo(doc, lineN) {
+    var line = getLine(doc, lineN), vis = visualLine(line);
+    if (line == vis) return lineN;
+    return lineNo(vis);
+  }
+  // Get the line number of the start of the next visual line after
+  // the given line.
+  function visualLineEndNo(doc, lineN) {
+    if (lineN > doc.lastLine()) return lineN;
+    var line = getLine(doc, lineN), merged;
+    if (!lineIsHidden(doc, line)) return lineN;
+    while (merged = collapsedSpanAtEnd(line))
+      line = merged.find(1, true).line;
+    return lineNo(line) + 1;
+  }
+
+  // Compute whether a line is hidden. Lines count as hidden when they
+  // are part of a visual line that starts with another line, or when
+  // they are entirely covered by collapsed, non-widget span.
+  function lineIsHidden(doc, line) {
+    var sps = sawCollapsedSpans && line.markedSpans;
+    if (sps) for (var sp, i = 0; i < sps.length; ++i) {
+      sp = sps[i];
+      if (!sp.marker.collapsed) continue;
+      if (sp.from == null) return true;
+      if (sp.marker.widgetNode) continue;
+      if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
+        return true;
+    }
+  }
+  function lineIsHiddenInner(doc, line, span) {
+    if (span.to == null) {
+      var end = span.marker.find(1, true);
+      return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker));
+    }
+    if (span.marker.inclusiveRight && span.to == line.text.length)
+      return true;
+    for (var sp, i = 0; i < line.markedSpans.length; ++i) {
+      sp = line.markedSpans[i];
+      if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&
+          (sp.to == null || sp.to != span.from) &&
+          (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
+          lineIsHiddenInner(doc, line, sp)) return true;
+    }
+  }
+
+  // LINE WIDGETS
+
+  // Line widgets are block elements displayed above or below a line.
+
+  var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
+    if (options) for (var opt in options) if (options.hasOwnProperty(opt))
+      this[opt] = options[opt];
+    this.cm = cm;
+    this.node = node;
+  };
+  eventMixin(LineWidget);
+
+  function adjustScrollWhenAboveVisible(cm, line, diff) {
+    if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
+      addToScrollPos(cm, null, diff);
+  }
+
+  LineWidget.prototype.clear = function() {
+    var cm = this.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);
+    if (no == null || !ws) return;
+    for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
+    if (!ws.length) line.widgets = null;
+    var height = widgetHeight(this);
+    runInOp(cm, function() {
+      adjustScrollWhenAboveVisible(cm, line, -height);
+      regLineChange(cm, no, "widget");
+      updateLineHeight(line, Math.max(0, line.height - height));
+    });
+  };
+  LineWidget.prototype.changed = function() {
+    var oldH = this.height, cm = this.cm, line = this.line;
+    this.height = null;
+    var diff = widgetHeight(this) - oldH;
+    if (!diff) return;
+    runInOp(cm, function() {
+      cm.curOp.forceUpdate = true;
+      adjustScrollWhenAboveVisible(cm, line, diff);
+      updateLineHeight(line, line.height + diff);
+    });
+  };
+
+  function widgetHeight(widget) {
+    if (widget.height != null) return widget.height;
+    if (!contains(document.body, widget.node))
+      removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, "position: relative"));
+    return widget.height = widget.node.offsetHeight;
+  }
+
+  function addLineWidget(cm, handle, node, options) {
+    var widget = new LineWidget(cm, node, options);
+    if (widget.noHScroll) cm.display.alignWidgets = true;
+    changeLine(cm, handle, "widget", function(line) {
+      var widgets = line.widgets || (line.widgets = []);
+      if (widget.insertAt == null) widgets.push(widget);
+      else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
+      widget.line = line;
+      if (!lineIsHidden(cm.doc, line)) {
+        var aboveVisible = heightAtLine(line) < cm.doc.scrollTop;
+        updateLineHeight(line, line.height + widgetHeight(widget));
+        if (aboveVisible) addToScrollPos(cm, null, widget.height);
+        cm.curOp.forceUpdate = true;
+      }
+      return true;
+    });
+    return widget;
+  }
+
+  // LINE DATA STRUCTURE
+
+  // Line objects. These hold state related to a line, including
+  // highlighting info (the styles array).
+  var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {
+    this.text = text;
+    attachMarkedSpans(this, markedSpans);
+    this.height = estimateHeight ? estimateHeight(this) : 1;
+  };
+  eventMixin(Line);
+  Line.prototype.lineNo = function() { return lineNo(this); };
+
+  // Change the content (text, markers) of a line. Automatically
+  // invalidates cached information and tries to re-estimate the
+  // line's height.
+  function updateLine(line, text, markedSpans, estimateHeight) {
+    line.text = text;
+    if (line.stateAfter) line.stateAfter = null;
+    if (line.styles) line.styles = null;
+    if (line.order != null) line.order = null;
+    detachMarkedSpans(line);
+    attachMarkedSpans(line, markedSpans);
+    var estHeight = estimateHeight ? estimateHeight(line) : 1;
+    if (estHeight != line.height) updateLineHeight(line, estHeight);
+  }
+
+  // Detach a line from the document tree and its markers.
+  function cleanUpLine(line) {
+    line.parent = null;
+    detachMarkedSpans(line);
+  }
+
+  // Run the given mode's parser over a line, calling f for each token.
+  function runMode(cm, text, mode, state, f, forceToEnd) {
+    var flattenSpans = mode.flattenSpans;
+    if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
+    var curStart = 0, curStyle = null;
+    var stream = new StringStream(text, cm.options.tabSize), style;
+    if (text == "" && mode.blankLine) mode.blankLine(state);
+    while (!stream.eol()) {
+      if (stream.pos > cm.options.maxHighlightLength) {
+        flattenSpans = false;
+        if (forceToEnd) processLine(cm, text, state, stream.pos);
+        stream.pos = text.length;
+        style = null;
+      } else {
+        style = mode.token(stream, state);
+      }
+      if (cm.options.addModeClass) {
+        var mName = CodeMirror.innerMode(mode, state).mode.name;
+        if (mName) style = "m-" + (style ? mName + " " + style : mName);
+      }
+      if (!flattenSpans || curStyle != style) {
+        if (curStart < stream.start) f(stream.start, curStyle);
+        curStart = stream.start; curStyle = style;
+      }
+      stream.start = stream.pos;
+    }
+    while (curStart < stream.pos) {
+      // Webkit seems to refuse to render text nodes longer than 57444 characters
+      var pos = Math.min(stream.pos, curStart + 50000);
+      f(pos, curStyle);
+      curStart = pos;
+    }
+  }
+
+  // Compute a style array (an array starting with a mode generation
+  // -- for invalidation -- followed by pairs of end positions and
+  // style strings), which is used to highlight the tokens on the
+  // line.
+  function highlightLine(cm, line, state, forceToEnd) {
+    // A styles array always starts with a number identifying the
+    // mode/overlays that it is based on (for easy invalidation).
+    var st = [cm.state.modeGen];
+    // Compute the base array of styles
+    runMode(cm, line.text, cm.doc.mode, state, function(end, style) {
+      st.push(end, style);
+    }, forceToEnd);
+
+    // Run overlays, adjust style array.
+    for (var o = 0; o < cm.state.overlays.length; ++o) {
+      var overlay = cm.state.overlays[o], i = 1, at = 0;
+      runMode(cm, line.text, overlay.mode, true, function(end, style) {
+        var start = i;
+        // Ensure there's a token end at the current position, and that i points at it
+        while (at < end) {
+          var i_end = st[i];
+          if (i_end > end)
+            st.splice(i, 1, end, st[i+1], i_end);
+          i += 2;
+          at = Math.min(end, i_end);
+        }
+        if (!style) return;
+        if (overlay.opaque) {
+          st.splice(start, i - start, end, style);
+          i = start + 2;
+        } else {
+          for (; start < i; start += 2) {
+            var cur = st[start+1];
+            st[start+1] = cur ? cur + " " + style : style;
+          }
+        }
+      });
+    }
+
+    return st;
+  }
+
+  function getLineStyles(cm, line) {
+    if (!line.styles || line.styles[0] != cm.state.modeGen)
+      line.styles = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
+    return line.styles;
+  }
+
+  // Lightweight form of highlight -- proceed over this line and
+  // update state, but don't save a style array. Used for lines that
+  // aren't currently visible.
+  function processLine(cm, text, state, startAt) {
+    var mode = cm.doc.mode;
+    var stream = new StringStream(text, cm.options.tabSize);
+    stream.start = stream.pos = startAt || 0;
+    if (text == "" && mode.blankLine) mode.blankLine(state);
+    while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
+      mode.token(stream, state);
+      stream.start = stream.pos;
+    }
+  }
+
+  // Convert a style as returned by a mode (either null, or a string
+  // containing one or more styles) to a CSS style. This is cached,
+  // and also looks for line-wide styles.
+  var styleToClassCache = {}, styleToClassCacheWithMode = {};
+  function interpretTokenStyle(style, builder) {
+    if (!style) return null;
+    for (;;) {
+      var lineClass = style.match(/(?:^|\s+)line-(background-)?(\S+)/);
+      if (!lineClass) break;
+      style = style.slice(0, lineClass.index) + style.slice(lineClass.index + lineClass[0].length);
+      var prop = lineClass[1] ? "bgClass" : "textClass";
+      if (builder[prop] == null)
+        builder[prop] = lineClass[2];
+      else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(builder[prop]))
+        builder[prop] += " " + lineClass[2];
+    }
+    if (/^\s*$/.test(style)) return null;
+    var cache = builder.cm.options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;
+    return cache[style] ||
+      (cache[style] = style.replace(/\S+/g, "cm-$&"));
+  }
+
+  // Render the DOM representation of the text of a line. Also builds
+  // up a 'line map', which points at the DOM nodes that represent
+  // specific stretches of text, and is used by the measuring code.
+  // The returned object contains the DOM node, this map, and
+  // information about line-wide styles that were set by the mode.
+  function buildLineContent(cm, lineView) {
+    // The padding-right forces the element to have a 'border', which
+    // is needed on Webkit to be able to get line-level bounding
+    // rectangles for it (in measureChar).
+    var content = elt("span", null, null, webkit ? "padding-right: .1px" : null);
+    var builder = {pre: elt("pre", [content]), content: content, col: 0, pos: 0, cm: cm};
+    lineView.measure = {};
+
+    // Iterate over the logical lines that make up this visual line.
+    for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {
+      var line = i ? lineView.rest[i - 1] : lineView.line, order;
+      builder.pos = 0;
+      builder.addToken = buildToken;
+      // Optionally wire in some hacks into the token-rendering
+      // algorithm, to deal with browser quirks.
+      if ((ie || webkit) && cm.getOption("lineWrapping"))
+        builder.addToken = buildTokenSplitSpaces(builder.addToken);
+      if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line)))
+        builder.addToken = buildTokenBadBidi(builder.addToken, order);
+      builder.map = [];
+      insertLineContent(line, builder, getLineStyles(cm, line));
+
+      // Ensure at least a single node is present, for measuring.
+      if (builder.map.length == 0)
+        builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure)));
+
+      // Store the map and a cache object for the current logical line
+      if (i == 0) {
+        lineView.measure.map = builder.map;
+        lineView.measure.cache = {};
+      } else {
+        (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map);
+        (lineView.measure.caches || (lineView.measure.caches = [])).push({});
+      }
+    }
+
+    signal(cm, "renderLine", cm, lineView.line, builder.pre);
+    return builder;
+  }
+
+  function defaultSpecialCharPlaceholder(ch) {
+    var token = elt("span", "\u2022", "cm-invalidchar");
+    token.title = "\\u" + ch.charCodeAt(0).toString(16);
+    return token;
+  }
+
+  // Build up the DOM representation for a single token, and add it to
+  // the line map. Takes care to render special characters separately.
+  function buildToken(builder, text, style, startStyle, endStyle, title) {
+    if (!text) return;
+    var special = builder.cm.options.specialChars, mustWrap = false;
+    if (!special.test(text)) {
+      builder.col += text.length;
+      var content = document.createTextNode(text);
+      builder.map.push(builder.pos, builder.pos + text.length, content);
+      if (ie_upto8) mustWrap = true;
+      builder.pos += text.length;
+    } else {
+      var content = document.createDocumentFragment(), pos = 0;
+      while (true) {
+        special.lastIndex = pos;
+        var m = special.exec(text);
+        var skipped = m ? m.index - pos : text.length - pos;
+        if (skipped) {
+          var txt = document.createTextNode(text.slice(pos, pos + skipped));
+          if (ie_upto8) content.appendChild(elt("span", [txt]));
+          else content.appendChild(txt);
+          builder.map.push(builder.pos, builder.pos + skipped, txt);
+          builder.col += skipped;
+          builder.pos += skipped;
+        }
+        if (!m) break;
+        pos += skipped + 1;
+        if (m[0] == "\t") {
+          var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
+          var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
+          builder.col += tabWidth;
+        } else {
+          var txt = builder.cm.options.specialCharPlaceholder(m[0]);
+          if (ie_upto8) content.appendChild(elt("span", [txt]));
+          else content.appendChild(txt);
+          builder.col += 1;
+        }
+        builder.map.push(builder.pos, builder.pos + 1, txt);
+        builder.pos++;
+      }
+    }
+    if (style || startStyle || endStyle || mustWrap) {
+      var fullStyle = style || "";
+      if (startStyle) fullStyle += startStyle;
+      if (endStyle) fullStyle += endStyle;
+      var token = elt("span", [content], fullStyle);
+      if (title) token.title = title;
+      return builder.content.appendChild(token);
+    }
+    builder.content.appendChild(content);
+  }
+
+  function buildTokenSplitSpaces(inner) {
+    function split(old) {
+      var out = " ";
+      for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
+      out += " ";
+      return out;
+    }
+    return function(builder, text, style, startStyle, endStyle, title) {
+      inner(builder, text.replace(/ {3,}/g, split), style, startStyle, endStyle, title);
+    };
+  }
+
+  // Work around nonsense dimensions being reported for stretches of
+  // right-to-left text.
+  function buildTokenBadBidi(inner, order) {
+    return function(builder, text, style, startStyle, endStyle, title) {
+      style = style ? style + " cm-force-border" : "cm-force-border";
+      var start = builder.pos, end = start + text.length;
+      for (;;) {
+        // Find the part that overlaps with the start of this text
+        for (var i = 0; i < order.length; i++) {
+          var part = order[i];
+          if (part.to > start && part.from <= start) break;
+        }
+        if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title);
+        inner(builder, text.slice(0, part.to - start), style, startStyle, null, title);
+        startStyle = null;
+        text = text.slice(part.to - start);
+        start = part.to;
+      }
+    };
+  }
+
+  function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
+    var widget = !ignoreWidget && marker.widgetNode;
+    if (widget) {
+      builder.map.push(builder.pos, builder.pos + size, widget);
+      builder.content.appendChild(widget);
+    }
+    builder.pos += size;
+  }
+
+  // Outputs a number of spans to make up a line, taking highlighting
+  // and marked text into account.
+  function insertLineContent(line, builder, styles) {
+    var spans = line.markedSpans, allText = line.text, at = 0;
+    if (!spans) {
+      for (var i = 1; i < styles.length; i+=2)
+        builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder));
+      return;
+    }
+
+    var len = allText.length, pos = 0, i = 1, text = "", style;
+    var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
+    for (;;) {
+      if (nextChange == pos) { // Update current marker set
+        spanStyle = spanEndStyle = spanStartStyle = title = "";
+        collapsed = null; nextChange = Infinity;
+        var foundBookmarks = [];
+        for (var j = 0; j < spans.length; ++j) {
+          var sp = spans[j], m = sp.marker;
+          if (sp.from <= pos && (sp.to == null || sp.to > pos)) {
+            if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; }
+            if (m.className) spanStyle += " " + m.className;
+            if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
+            if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
+            if (m.title && !title) title = m.title;
+            if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
+              collapsed = sp;
+          } else if (sp.from > pos && nextChange > sp.from) {
+            nextChange = sp.from;
+          }
+          if (m.type == "bookmark" && sp.from == pos && m.widgetNode) foundBookmarks.push(m);
+        }
+        if (collapsed && (collapsed.from || 0) == pos) {
+          buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
+                             collapsed.marker, collapsed.from == null);
+          if (collapsed.to == null) return;
+        }
+        if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j)
+          buildCollapsedSpan(builder, 0, foundBookmarks[j]);
+      }
+      if (pos >= len) break;
+
+      var upto = Math.min(len, nextChange);
+      while (true) {
+        if (text) {
+          var end = pos + text.length;
+          if (!collapsed) {
+            var tokenText = end > upto ? text.slice(0, upto - pos) : text;
+            builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
+                             spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title);
+          }
+          if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
+          pos = end;
+          spanStartStyle = "";
+        }
+        text = allText.slice(at, at = styles[i++]);
+        style = interpretTokenStyle(styles[i++], builder);
+      }
+    }
+  }
+
+  // DOCUMENT DATA STRUCTURE
+
+  // By default, updates that start and end at the beginning of a line
+  // are treated specially, in order to make the association of line
+  // widgets and marker elements with the text behave more intuitive.
+  function isWholeLineUpdate(doc, change) {
+    return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" &&
+      (!doc.cm || doc.cm.options.wholeLineUpdateBefore);
+  }
+
+  // Perform a change on the document data structure.
+  function updateDoc(doc, change, markedSpans, estimateHeight) {
+    function spansFor(n) {return markedSpans ? markedSpans[n] : null;}
+    function update(line, text, spans) {
+      updateLine(line, text, spans, estimateHeight);
+      signalLater(line, "change", line, change);
+    }
+
+    var from = change.from, to = change.to, text = change.text;
+    var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
+    var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
+
+    // Adjust the line structure
+    if (isWholeLineUpdate(doc, change)) {
+      // This is a whole-line replace. Treated specially to make
+      // sure line objects move the way they are supposed to.
+      for (var i = 0, added = []; i < text.length - 1; ++i)
+        added.push(new Line(text[i], spansFor(i), estimateHeight));
+      update(lastLine, lastLine.text, lastSpans);
+      if (nlines) doc.remove(from.line, nlines);
+      if (added.length) doc.insert(from.line, added);
+    } else if (firstLine == lastLine) {
+      if (text.length == 1) {
+        update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
+      } else {
+        for (var added = [], i = 1; i < text.length - 1; ++i)
+          added.push(new Line(text[i], spansFor(i), estimateHeight));
+        added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
+        update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
+        doc.insert(from.line + 1, added);
+      }
+    } else if (text.length == 1) {
+      update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
+      doc.remove(from.line + 1, nlines);
+    } else {
+      update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
+      update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
+      for (var i = 1, added = []; i < text.length - 1; ++i)
+        added.push(new Line(text[i], spansFor(i), estimateHeight));
+      if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
+      doc.insert(from.line + 1, added);
+    }
+
+    signalLater(doc, "change", doc, change);
+  }
+
+  // The document is represented as a BTree consisting of leaves, with
+  // chunk of lines in them, and branches, with up to ten leaves or
+  // other branch nodes below them. The top node is always a branch
+  // node, and is the document object itself (meaning it has
+  // additional methods and properties).
+  //
+  // All nodes have parent links. The tree is used both to go from
+  // line numbers to line objects, and to go from objects to numbers.
+  // It also indexes by height, and is used to convert between height
+  // and line object, and to find the total height of the document.
+  //
+  // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html
+
+  function LeafChunk(lines) {
+    this.lines = lines;
+    this.parent = null;
+    for (var i = 0, height = 0; i < lines.length; ++i) {
+      lines[i].parent = this;
+      height += lines[i].height;
+    }
+    this.height = height;
+  }
+
+  LeafChunk.prototype = {
+    chunkSize: function() { return this.lines.length; },
+    // Remove the n lines at offset 'at'.
+    removeInner: function(at, n) {
+      for (var i = at, e = at + n; i < e; ++i) {
+        var line = this.lines[i];
+        this.height -= line.height;
+        cleanUpLine(line);
+        signalLater(line, "delete");
+      }
+      this.lines.splice(at, n);
+    },
+    // Helper used to collapse a small branch into a single leaf.
+    collapse: function(lines) {
+      lines.push.apply(lines, this.lines);
+    },
+    // Insert the given array of lines at offset 'at', count them as
+    // having the given height.
+    insertInner: function(at, lines, height) {
+      this.height += height;
+      this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
+      for (var i = 0; i < lines.length; ++i) lines[i].parent = this;
+    },
+    // Used to iterate over a part of the tree.
+    iterN: function(at, n, op) {
+      for (var e = at + n; at < e; ++at)
+        if (op(this.lines[at])) return true;
+    }
+  };
+
+  function BranchChunk(children) {
+    this.children = children;
+    var size = 0, height = 0;
+    for (var i = 0; i < children.length; ++i) {
+      var ch = children[i];
+      size += ch.chunkSize(); height += ch.height;
+      ch.parent = this;
+    }
+    this.size = size;
+    this.height = height;
+    this.parent = null;
+  }
+
+  BranchChunk.prototype = {
+    chunkSize: function() { return this.size; },
+    removeInner: function(at, n) {
+      this.size -= n;
+      for (var i = 0; i < this.children.length; ++i) {
+        var child = this.children[i], sz = child.chunkSize();
+        if (at < sz) {
+          var rm = Math.min(n, sz - at), oldHeight = child.height;
+          child.removeInner(at, rm);
+          this.height -= oldHeight - child.height;
+          if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
+          if ((n -= rm) == 0) break;
+          at = 0;
+        } else at -= sz;
+      }
+      // If the result is smaller than 25 lines, ensure that it is a
+      // single leaf node.
+      if (this.size - n < 25 &&
+          (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {
+        var lines = [];
+        this.collapse(lines);
+        this.children = [new LeafChunk(lines)];
+        this.children[0].parent = this;
+      }
+    },
+    collapse: function(lines) {
+      for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines);
+    },
+    insertInner: function(at, lines, height) {
+      this.size += lines.length;
+      this.height += height;
+      for (var i = 0; i < this.children.length; ++i) {
+        var child = this.children[i], sz = child.chunkSize();
+        if (at <= sz) {
+          child.insertInner(at, lines, height);
+          if (child.lines && child.lines.length > 50) {
+            while (child.lines.length > 50) {
+              var spilled = child.lines.splice(child.lines.length - 25, 25);
+              var newleaf = new LeafChunk(spilled);
+              child.height -= newleaf.height;
+              this.children.splice(i + 1, 0, newleaf);
+              newleaf.parent = this;
+            }
+            this.maybeSpill();
+          }
+          break;
+        }
+        at -= sz;
+      }
+    },
+    // When a node has grown, check whether it should be split.
+    maybeSpill: function() {
+      if (this.children.length <= 10) return;
+      var me = this;
+      do {
+        var spilled = me.children.splice(me.children.length - 5, 5);
+        var sibling = new BranchChunk(spilled);
+        if (!me.parent) { // Become the parent node
+          var copy = new BranchChunk(me.children);
+          copy.parent = me;
+          me.children = [copy, sibling];
+          me = copy;
+        } else {
+          me.size -= sibling.size;
+          me.height -= sibling.height;
+          var myIndex = indexOf(me.parent.children, me);
+          me.parent.children.splice(myIndex + 1, 0, sibling);
+        }
+        sibling.parent = me.parent;
+      } while (me.children.length > 10);
+      me.parent.maybeSpill();
+    },
+    iterN: function(at, n, op) {
+      for (var i = 0; i < this.children.length; ++i) {
+        var child = this.children[i], sz = child.chunkSize();
+        if (at < sz) {
+          var used = Math.min(n, sz - at);
+          if (child.iterN(at, used, op)) return true;
+          if ((n -= used) == 0) break;
+          at = 0;
+        } else at -= sz;
+      }
+    }
+  };
+
+  var nextDocId = 0;
+  var Doc = CodeMirror.Doc = function(text, mode, firstLine) {
+    if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
+    if (firstLine == null) firstLine = 0;
+
+    BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
+    this.first = firstLine;
+    this.scrollTop = this.scrollLeft = 0;
+    this.cantEdit = false;
+    this.cleanGeneration = 1;
+    this.frontier = firstLine;
+    var start = Pos(firstLine, 0);
+    this.sel = simpleSelection(start);
+    this.history = new History(null);
+    this.id = ++nextDocId;
+    this.modeOption = mode;
+
+    if (typeof text == "string") text = splitLines(text);
+    updateDoc(this, {from: start, to: start, text: text});
+    setSelection(this, simpleSelection(start), sel_dontScroll);
+  };
+
+  Doc.prototype = createObj(BranchChunk.prototype, {
+    constructor: Doc,
+    // Iterate over the document. Supports two forms -- with only one
+    // argument, it calls that for each line in the document. With
+    // three, it iterates over the range given by the first two (with
+    // the second being non-inclusive).
+    iter: function(from, to, op) {
+      if (op) this.iterN(from - this.first, to - from, op);
+      else this.iterN(this.first, this.first + this.size, from);
+    },
+
+    // Non-public interface for adding and removing lines.
+    insert: function(at, lines) {
+      var height = 0;
+      for (var i = 0; i < lines.length; ++i) height += lines[i].height;
+      this.insertInner(at - this.first, lines, height);
+    },
+    remove: function(at, n) { this.removeInner(at - this.first, n); },
+
+    // From here, the methods are part of the public interface. Most
+    // are also available from CodeMirror (editor) instances.
+
+    getValue: function(lineSep) {
+      var lines = getLines(this, this.first, this.first + this.size);
+      if (lineSep === false) return lines;
+      return lines.join(lineSep || "\n");
+    },
+    setValue: docMethodOp(function(code) {
+      var top = Pos(this.first, 0), last = this.first + this.size - 1;
+      makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
+                        text: splitLines(code), origin: "setValue"}, true);
+      setSelection(this, simpleSelection(top));
+    }),
+    replaceRange: function(code, from, to, origin) {
+      from = clipPos(this, from);
+      to = to ? clipPos(this, to) : from;
+      replaceRange(this, code, from, to, origin);
+    },
+    getRange: function(from, to, lineSep) {
+      var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
+      if (lineSep === false) return lines;
+      return lines.join(lineSep || "\n");
+    },
+
+    getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
+
+    getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
+    getLineNumber: function(line) {return lineNo(line);},
+
+    getLineHandleVisualStart: function(line) {
+      if (typeof line == "number") line = getLine(this, line);
+      return visualLine(line);
+    },
+
+    lineCount: function() {return this.size;},
+    firstLine: function() {return this.first;},
+    lastLine: function() {return this.first + this.size - 1;},
+
+    clipPos: function(pos) {return clipPos(this, pos);},
+
+    getCursor: function(start) {
+      var range = this.sel.primary(), pos;
+      if (start == null || start == "head") pos = range.head;
+      else if (start == "anchor") pos = range.anchor;
+      else if (start == "end" || start == "to" || start === false) pos = range.to();
+      else pos = range.from();
+      return pos;
+    },
+    listSelections: function() { return this.sel.ranges; },
+    somethingSelected: function() {return this.sel.somethingSelected();},
+
+    setCursor: docMethodOp(function(line, ch, options) {
+      setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options);
+    }),
+    setSelection: docMethodOp(function(anchor, head, options) {
+      setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options);
+    }),
+    extendSelection: docMethodOp(function(head, other, options) {
+      extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);
+    }),
+    extendSelections: docMethodOp(function(heads, options) {
+      extendSelections(this, clipPosArray(this, heads, options));
+    }),
+    extendSelectionsBy: docMethodOp(function(f, options) {
+      extendSelections(this, map(this.sel.ranges, f), options);
+    }),
+    setSelections: docMethodOp(function(ranges, primary, options) {
+      if (!ranges.length) return;
+      for (var i = 0, out = []; i < ranges.length; i++)
+        out[i] = new Range(clipPos(this, ranges[i].anchor),
+                           clipPos(this, ranges[i].head));
+      if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex);
+      setSelection(this, normalizeSelection(out, primary), options);
+    }),
+    addSelection: docMethodOp(function(anchor, head, options) {
+      var ranges = this.sel.ranges.slice(0);
+      ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)));
+      setSelection(this, normalizeSelection(ranges, ranges.length - 1), options);
+    }),
+
+    getSelection: function(lineSep) {
+      var ranges = this.sel.ranges, lines;
+      for (var i = 0; i < ranges.length; i++) {
+        var sel = getBetween(this, ranges[i].from(), ranges[i].to());
+        lines = lines ? lines.concat(sel) : sel;
+      }
+      if (lineSep === false) return lines;
+      else return lines.join(lineSep || "\n");
+    },
+    getSelections: function(lineSep) {
+      var parts = [], ranges = this.sel.ranges;
+      for (var i = 0; i < ranges.length; i++) {
+        var sel = getBetween(this, ranges[i].from(), ranges[i].to());
+        if (lineSep !== false) sel = sel.join(lineSep || "\n");
+        parts[i] = sel;
+      }
+      return parts;
+    },
+    replaceSelection: docMethodOp(function(code, collapse, origin) {
+      var dup = [];
+      for (var i = 0; i < this.sel.ranges.length; i++)
+        dup[i] = code;
+      this.replaceSelections(dup, collapse, origin || "+input");
+    }),
+    replaceSelections: function(code, collapse, origin) {
+      var changes = [], sel = this.sel;
+      for (var i = 0; i < sel.ranges.length; i++) {
+        var range = sel.ranges[i];
+        changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin};
+      }
+      var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
+      for (var i = changes.length - 1; i >= 0; i--)
+        makeChange(this, changes[i]);
+      if (newSel) setSelectionReplaceHistory(this, newSel);
+      else if (this.cm) ensureCursorVisible(this.cm);
+    },
+    undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}),
+    redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}),
+    undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}),
+    redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}),
+
+    setExtending: function(val) {this.extend = val;},
+    getExtending: function() {return this.extend;},
+
+    historySize: function() {
+      var hist = this.history, done = 0, undone = 0;
+      for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done;
+      for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone;
+      return {undo: done, redo: undone};
+    },
+    clearHistory: function() {this.history = new History(this.history.maxGeneration);},
+
+    markClean: function() {
+      this.cleanGeneration = this.changeGeneration(true);
+    },
+    changeGeneration: function(forceSplit) {
+      if (forceSplit)
+        this.history.lastOp = this.history.lastOrigin = null;
+      return this.history.generation;
+    },
+    isClean: function (gen) {
+      return this.history.generation == (gen || this.cleanGeneration);
+    },
+
+    getHistory: function() {
+      return {done: copyHistoryArray(this.history.done),
+              undone: copyHistoryArray(this.history.undone)};
+    },
+    setHistory: function(histData) {
+      var hist = this.history = new History(this.history.maxGeneration);
+      hist.done = copyHistoryArray(histData.done.slice(0), null, true);
+      hist.undone = copyHistoryArray(histData.undone.slice(0), null, true);
+    },
+
+    markText: function(from, to, options) {
+      return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
+    },
+    setBookmark: function(pos, options) {
+      var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
+                      insertLeft: options && options.insertLeft,
+                      clearWhenEmpty: false, shared: options && options.shared};
+      pos = clipPos(this, pos);
+      return markText(this, pos, pos, realOpts, "bookmark");
+    },
+    findMarksAt: function(pos) {
+      pos = clipPos(this, pos);
+      var markers = [], spans = getLine(this, pos.line).markedSpans;
+      if (spans) for (var i = 0; i < spans.length; ++i) {
+        var span = spans[i];
+        if ((span.from == null || span.from <= pos.ch) &&
+            (span.to == null || span.to >= pos.ch))
+          markers.push(span.marker.parent || span.marker);
+      }
+      return markers;
+    },
+    findMarks: function(from, to) {
+      from = clipPos(this, from); to = clipPos(this, to);
+      var found = [], lineNo = from.line;
+      this.iter(from.line, to.line + 1, function(line) {
+        var spans = line.markedSpans;
+        if (spans) for (var i = 0; i < spans.length; i++) {
+          var span = spans[i];
+          if (!(lineNo == from.line && from.ch > span.to ||
+                span.from == null && lineNo != from.line||
+                lineNo == to.line && span.from > to.ch))
+            found.push(span.marker.parent || span.marker);
+        }
+        ++lineNo;
+      });
+      return found;
+    },
+    getAllMarks: function() {
+      var markers = [];
+      this.iter(function(line) {
+        var sps = line.markedSpans;
+        if (sps) for (var i = 0; i < sps.length; ++i)
+          if (sps[i].from != null) markers.push(sps[i].marker);
+      });
+      return markers;
+    },
+
+    posFromIndex: function(off) {
+      var ch, lineNo = this.first;
+      this.iter(function(line) {
+        var sz = line.text.length + 1;
+        if (sz > off) { ch = off; return true; }
+        off -= sz;
+        ++lineNo;
+      });
+      return clipPos(this, Pos(lineNo, ch));
+    },
+    indexFromPos: function (coords) {
+      coords = clipPos(this, coords);
+      var index = coords.ch;
+      if (coords.line < this.first || coords.ch < 0) return 0;
+      this.iter(this.first, coords.line, function (line) {
+        index += line.text.length + 1;
+      });
+      return index;
+    },
+
+    copy: function(copyHistory) {
+      var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
+      doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
+      doc.sel = this.sel;
+      doc.extend = false;
+      if (copyHistory) {
+        doc.history.undoDepth = this.history.undoDepth;
+        doc.setHistory(this.getHistory());
+      }
+      return doc;
+    },
+
+    linkedDoc: function(options) {
+      if (!options) options = {};
+      var from = this.first, to = this.first + this.size;
+      if (options.from != null && options.from > from) from = options.from;
+      if (options.to != null && options.to < to) to = options.to;
+      var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);
+      if (options.sharedHist) copy.history = this.history;
+      (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
+      copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
+      return copy;
+    },
+    unlinkDoc: function(other) {
+      if (other instanceof CodeMirror) other = other.doc;
+      if (this.linked) for (var i = 0; i < this.linked.length; ++i) {
+        var link = this.linked[i];
+        if (link.doc != other) continue;
+        this.linked.splice(i, 1);
+        other.unlinkDoc(this);
+        break;
+      }
+      // If the histories were shared, split them again
+      if (other.history == this.history) {
+        var splitIds = [other.id];
+        linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);
+        other.history = new History(null);
+        other.history.done = copyHistoryArray(this.history.done, splitIds);
+        other.history.undone = copyHistoryArray(this.history.undone, splitIds);
+      }
+    },
+    iterLinkedDocs: function(f) {linkedDocs(this, f);},
+
+    getMode: function() {return this.mode;},
+    getEditor: function() {return this.cm;}
+  });
+
+  // Public alias.
+  Doc.prototype.eachLine = Doc.prototype.iter;
+
+  // Set up methods on CodeMirror's prototype to redirect to the editor's document.
+  var dontDelegate = "iter insert remove copy getEditor".split(" ");
+  for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
+    CodeMirror.prototype[prop] = (function(method) {
+      return function() {return method.apply(this.doc, arguments);};
+    })(Doc.prototype[prop]);
+
+  eventMixin(Doc);
+
+  // Call f for all linked documents.
+  function linkedDocs(doc, f, sharedHistOnly) {
+    function propagate(doc, skip, sharedHist) {
+      if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
+        var rel = doc.linked[i];
+        if (rel.doc == skip) continue;
+        var shared = sharedHist && rel.sharedHist;
+        if (sharedHistOnly && !shared) continue;
+        f(rel.doc, shared);
+        propagate(rel.doc, doc, shared);
+      }
+    }
+    propagate(doc, null, true);
+  }
+
+  // Attach a document to an editor.
+  function attachDoc(cm, doc) {
+    if (doc.cm) throw new Error("This document is already in use.");
+    cm.doc = doc;
+    doc.cm = cm;
+    estimateLineHeights(cm);
+    loadMode(cm);
+    if (!cm.options.lineWrapping) findMaxLine(cm);
+    cm.options.mode = doc.modeOption;
+    regChange(cm);
+  }
+
+  // LINE UTILITIES
+
+  // Find the line object corresponding to the given line number.
+  function getLine(doc, n) {
+    n -= doc.first;
+    if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document.");
+    for (var chunk = doc; !chunk.lines;) {
+      for (var i = 0;; ++i) {
+        var child = chunk.children[i], sz = child.chunkSize();
+        if (n < sz) { chunk = child; break; }
+        n -= sz;
+      }
+    }
+    return chunk.lines[n];
+  }
+
+  // Get the part of a document between two positions, as an array of
+  // strings.
+  function getBetween(doc, start, end) {
+    var out = [], n = start.line;
+    doc.iter(start.line, end.line + 1, function(line) {
+      var text = line.text;
+      if (n == end.line) text = text.slice(0, end.ch);
+      if (n == start.line) text = text.slice(start.ch);
+      out.push(text);
+      ++n;
+    });
+    return out;
+  }
+  // Get the lines between from and to, as array of strings.
+  function getLines(doc, from, to) {
+    var out = [];
+    doc.iter(from, to, function(line) { out.push(line.text); });
+    return out;
+  }
+
+  // Update the height of a line, propagating the height change
+  // upwards to parent nodes.
+  function updateLineHeight(line, height) {
+    var diff = height - line.height;
+    if (diff) for (var n = line; n; n = n.parent) n.height += diff;
+  }
+
+  // Given a line object, find its line number by walking up through
+  // its parent links.
+  function lineNo(line) {
+    if (line.parent == null) return null;
+    var cur = line.parent, no = indexOf(cur.lines, line);
+    for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
+      for (var i = 0;; ++i) {
+        if (chunk.children[i] == cur) break;
+        no += chunk.children[i].chunkSize();
+      }
+    }
+    return no + cur.first;
+  }
+
+  // Find the line at the given vertical position, using the height
+  // information in the document tree.
+  function lineAtHeight(chunk, h) {
+    var n = chunk.first;
+    outer: do {
+      for (var i = 0; i < chunk.children.length; ++i) {
+        var child = chunk.children[i], ch = child.height;
+        if (h < ch) { chunk = child; continue outer; }
+        h -= ch;
+        n += child.chunkSize();
+      }
+      return n;
+    } while (!chunk.lines);
+    for (var i = 0; i < chunk.lines.length; ++i) {
+      var line = chunk.lines[i], lh = line.height;
+      if (h < lh) break;
+      h -= lh;
+    }
+    return n + i;
+  }
+
+
+  // Find the height above the given line.
+  function heightAtLine(lineObj) {
+    lineObj = visualLine(lineObj);
+
+    var h = 0, chunk = lineObj.parent;
+    for (var i = 0; i < chunk.lines.length; ++i) {
+      var line = chunk.lines[i];
+      if (line == lineObj) break;
+      else h += line.height;
+    }
+    for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
+      for (var i = 0; i < p.children.length; ++i) {
+        var cur = p.children[i];
+        if (cur == chunk) break;
+        else h += cur.height;
+      }
+    }
+    return h;
+  }
+
+  // Get the bidi ordering for the given line (and cache it). Returns
+  // false for lines that are fully left-to-right, and an array of
+  // BidiSpan objects otherwise.
+  function getOrder(line) {
+    var order = line.order;
+    if (order == null) order = line.order = bidiOrdering(line.text);
+    return order;
+  }
+
+  // HISTORY
+
+  function History(startGen) {
+    // Arrays of change events and selections. Doing something adds an
+    // event to done and clears undo. Undoing moves events from done
+    // to undone, redoing moves them in the other direction.
+    this.done = []; this.undone = [];
+    this.undoDepth = Infinity;
+    // Used to track when changes can be merged into a single undo
+    // event
+    this.lastModTime = this.lastSelTime = 0;
+    this.lastOp = null;
+    this.lastOrigin = this.lastSelOrigin = null;
+    // Used by the isClean() method
+    this.generation = this.maxGeneration = startGen || 1;
+  }
+
+  // Create a history change event from an updateDoc-style change
+  // object.
+  function historyChangeFromChange(doc, change) {
+    var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
+    attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
+    linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
+    return histChange;
+  }
+
+  // Pop all selection events off the end of a history array. Stop at
+  // a change event.
+  function clearSelectionEvents(array) {
+    while (array.length) {
+      var last = lst(array);
+      if (last.ranges) array.pop();
+      else break;
+    }
+  }
+
+  // Find the top change event in the history. Pop off selection
+  // events that are in the way.
+  function lastChangeEvent(hist, force) {
+    if (force) {
+      clearSelectionEvents(hist.done);
+      return lst(hist.done);
+    } else if (hist.done.length && !lst(hist.done).ranges) {
+      return lst(hist.done);
+    } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {
+      hist.done.pop();
+      return lst(hist.done);
+    }
+  }
+
+  // Register a change in the history. Merges changes that are within
+  // a single operation, ore are close together with an origin that
+  // allows merging (starting with "+") into a single event.
+  function addChangeToHistory(doc, change, selAfter, opId) {
+    var hist = doc.history;
+    hist.undone.length = 0;
+    var time = +new Date, cur;
+
+    if ((hist.lastOp == opId ||
+         hist.lastOrigin == change.origin && change.origin &&
+         ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) ||
+          change.origin.charAt(0) == "*")) &&
+        (cur = lastChangeEvent(hist, hist.lastOp == opId))) {
+      // Merge this change into the last event
+      var last = lst(cur.changes);
+      if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {
+        // Optimized case for simple insertion -- don't want to add
+        // new changesets for every character typed
+        last.to = changeEnd(change);
+      } else {
+        // Add new sub-event
+        cur.changes.push(historyChangeFromChange(doc, change));
+      }
+    } else {
+      // Can not be merged, start a new event.
+      var before = lst(hist.done);
+      if (!before || !before.ranges)
+        pushSelectionToHistory(doc.sel, hist.done);
+      cur = {changes: [historyChangeFromChange(doc, change)],
+             generation: hist.generation};
+      hist.done.push(cur);
+      while (hist.done.length > hist.undoDepth) {
+        hist.done.shift();
+        if (!hist.done[0].ranges) hist.done.shift();
+      }
+    }
+    hist.done.push(selAfter);
+    hist.generation = ++hist.maxGeneration;
+    hist.lastModTime = hist.lastSelTime = time;
+    hist.lastOp = opId;
+    hist.lastOrigin = hist.lastSelOrigin = change.origin;
+
+    if (!last) signal(doc, "historyAdded");
+  }
+
+  function selectionEventCanBeMerged(doc, origin, prev, sel) {
+    var ch = origin.charAt(0);
+    return ch == "*" ||
+      ch == "+" &&
+      prev.ranges.length == sel.ranges.length &&
+      prev.somethingSelected() == sel.somethingSelected() &&
+      new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500);
+  }
+
+  // Called whenever the selection changes, sets the new selection as
+  // the pending selection in the history, and pushes the old pending
+  // selection into the 'done' array when it was significantly
+  // different (in number of selected ranges, emptiness, or time).
+  function addSelectionToHistory(doc, sel, opId, options) {
+    var hist = doc.history, origin = options && options.origin;
+
+    // A new event is started when the previous origin does not match
+    // the current, or the origins don't allow matching. Origins
+    // starting with * are always merged, those starting with + are
+    // merged when similar and close together in time.
+    if (opId == hist.lastOp ||
+        (origin && hist.lastSelOrigin == origin &&
+         (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||
+          selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))
+      hist.done[hist.done.length - 1] = sel;
+    else
+      pushSelectionToHistory(sel, hist.done);
+
+    hist.lastSelTime = +new Date;
+    hist.lastSelOrigin = origin;
+    hist.lastOp = opId;
+    if (options && options.clearRedo !== false)
+      clearSelectionEvents(hist.undone);
+  }
+
+  function pushSelectionToHistory(sel, dest) {
+    var top = lst(dest);
+    if (!(top && top.ranges && top.equals(sel)))
+      dest.push(sel);
+  }
+
+  // Used to store marked span information in the history.
+  function attachLocalSpans(doc, change, from, to) {
+    var existing = change["spans_" + doc.id], n = 0;
+    doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {
+      if (line.markedSpans)
+        (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans;
+      ++n;
+    });
+  }
+
+  // When un/re-doing restores text containing marked spans, those
+  // that have been explicitly cleared should not be restored.
+  function removeClearedSpans(spans) {
+    if (!spans) return null;
+    for (var i = 0, out; i < spans.length; ++i) {
+      if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
+      else if (out) out.push(spans[i]);
+    }
+    return !out ? spans : out.length ? out : null;
+  }
+
+  // Retrieve and filter the old marked spans stored in a change event.
+  function getOldSpans(doc, change) {
+    var found = change["spans_" + doc.id];
+    if (!found) return null;
+    for (var i = 0, nw = []; i < change.text.length; ++i)
+      nw.push(removeClearedSpans(found[i]));
+    return nw;
+  }
+
+  // Used both to provide a JSON-safe object in .getHistory, and, when
+  // detaching a document, to split the history in two
+  function copyHistoryArray(events, newGroup, instantiateSel) {
+    for (var i = 0, copy = []; i < events.length; ++i) {
+      var event = events[i];
+      if (event.ranges) {
+        copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event);
+        continue;
+      }
+      var changes = event.changes, newChanges = [];
+      copy.push({changes: newChanges});
+      for (var j = 0; j < changes.length; ++j) {
+        var change = changes[j], m;
+        newChanges.push({from: change.from, to: change.to, text: change.text});
+        if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) {
+          if (indexOf(newGroup, Number(m[1])) > -1) {
+            lst(newChanges)[prop] = change[prop];
+            delete change[prop];
+          }
+        }
+      }
+    }
+    return copy;
+  }
+
+  // Rebasing/resetting history to deal with externally-sourced changes
+
+  function rebaseHistSelSingle(pos, from, to, diff) {
+    if (to < pos.line) {
+      pos.line += diff;
+    } else if (from < pos.line) {
+      pos.line = from;
+      pos.ch = 0;
+    }
+  }
+
+  // Tries to rebase an array of history events given a change in the
+  // document. If the change touches the same lines as the event, the
+  // event, and everything 'behind' it, is discarded. If the change is
+  // before the event, the event's positions are updated. Uses a
+  // copy-on-write scheme for the positions, to avoid having to
+  // reallocate them all on every rebase, but also avoid problems with
+  // shared position objects being unsafely updated.
+  function rebaseHistArray(array, from, to, diff) {
+    for (var i = 0; i < array.length; ++i) {
+      var sub = array[i], ok = true;
+      if (sub.ranges) {
+        if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; }
+        for (var j = 0; j < sub.ranges.length; j++) {
+          rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff);
+          rebaseHistSelSingle(sub.ranges[j].head, from, to, diff);
+        }
+        continue;
+      }
+      for (var j = 0; j < sub.changes.length; ++j) {
+        var cur = sub.changes[j];
+        if (to < cur.from.line) {
+          cur.from = Pos(cur.from.line + diff, cur.from.ch);
+          cur.to = Pos(cur.to.line + diff, cur.to.ch);
+        } else if (from <= cur.to.line) {
+          ok = false;
+          break;
+        }
+      }
+      if (!ok) {
+        array.splice(0, i + 1);
+        i = 0;
+      }
+    }
+  }
+
+  function rebaseHist(hist, change) {
+    var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
+    rebaseHistArray(hist.done, from, to, diff);
+    rebaseHistArray(hist.undone, from, to, diff);
+  }
+
+  // EVENT UTILITIES
+
+  // Due to the fact that we still support jurassic IE versions, some
+  // compatibility wrappers are needed.
+
+  var e_preventDefault = CodeMirror.e_preventDefault = function(e) {
+    if (e.preventDefault) e.preventDefault();
+    else e.returnValue = false;
+  };
+  var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) {
+    if (e.stopPropagation) e.stopPropagation();
+    else e.cancelBubble = true;
+  };
+  function e_defaultPrevented(e) {
+    return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;
+  }
+  var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);};
+
+  function e_target(e) {return e.target || e.srcElement;}
+  function e_button(e) {
+    var b = e.which;
+    if (b == null) {
+      if (e.button & 1) b = 1;
+      else if (e.button & 2) b = 3;
+      else if (e.button & 4) b = 2;
+    }
+    if (mac && e.ctrlKey && b == 1) b = 3;
+    return b;
+  }
+
+  // EVENT HANDLING
+
+  // Lightweight event framework. on/off also work on DOM nodes,
+  // registering native DOM handlers.
+
+  var on = CodeMirror.on = function(emitter, type, f) {
+    if (emitter.addEventListener)
+      emitter.addEventListener(type, f, false);
+    else if (emitter.attachEvent)
+      emitter.attachEvent("on" + type, f);
+    else {
+      var map = emitter._handlers || (emitter._handlers = {});
+      var arr = map[type] || (map[type] = []);
+      arr.push(f);
+    }
+  };
+
+  var off = CodeMirror.off = function(emitter, type, f) {
+    if (emitter.removeEventListener)
+      emitter.removeEventListener(type, f, false);
+    else if (emitter.detachEvent)
+      emitter.detachEvent("on" + type, f);
+    else {
+      var arr = emitter._handlers && emitter._handlers[type];
+      if (!arr) return;
+      for (var i = 0; i < arr.length; ++i)
+        if (arr[i] == f) { arr.splice(i, 1); break; }
+    }
+  };
+
+  var signal = CodeMirror.signal = function(emitter, type /*, values...*/) {
+    var arr = emitter._handlers && emitter._handlers[type];
+    if (!arr) return;
+    var args = Array.prototype.slice.call(arguments, 2);
+    for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
+  };
+
+  // Often, we want to signal events at a point where we are in the
+  // middle of some work, but don't want the handler to start calling
+  // other methods on the editor, which might be in an inconsistent
+  // state or simply not expect any other events to happen.
+  // signalLater looks whether there are any handlers, and schedules
+  // them to be executed when the last operation ends, or, if no
+  // operation is active, when a timeout fires.
+  var delayedCallbacks, delayedCallbackDepth = 0;
+  function signalLater(emitter, type /*, values...*/) {
+    var arr = emitter._handlers && emitter._handlers[type];
+    if (!arr) return;
+    var args = Array.prototype.slice.call(arguments, 2);
+    if (!delayedCallbacks) {
+      ++delayedCallbackDepth;
+      delayedCallbacks = [];
+      setTimeout(fireDelayed, 0);
+    }
+    function bnd(f) {return function(){f.apply(null, args);};};
+    for (var i = 0; i < arr.length; ++i)
+      delayedCallbacks.push(bnd(arr[i]));
+  }
+
+  function fireDelayed() {
+    --delayedCallbackDepth;
+    var delayed = delayedCallbacks;
+    delayedCallbacks = null;
+    for (var i = 0; i < delayed.length; ++i) delayed[i]();
+  }
+
+  // The DOM events that CodeMirror handles can be overridden by
+  // registering a (non-DOM) handler on the editor for the event name,
+  // and preventDefault-ing the event in that handler.
+  function signalDOMEvent(cm, e, override) {
+    signal(cm, override || e.type, cm, e);
+    return e_defaultPrevented(e) || e.codemirrorIgnore;
+  }
+
+  function hasHandler(emitter, type) {
+    var arr = emitter._handlers && emitter._handlers[type];
+    return arr && arr.length > 0;
+  }
+
+  // Add on and off methods to a constructor's prototype, to make
+  // registering events on such objects more convenient.
+  function eventMixin(ctor) {
+    ctor.prototype.on = function(type, f) {on(this, type, f);};
+    ctor.prototype.off = function(type, f) {off(this, type, f);};
+  }
+
+  // MISC UTILITIES
+
+  // Number of pixels added to scroller and sizer to hide scrollbar
+  var scrollerCutOff = 30;
+
+  // Returned or thrown by various protocols to signal 'I'm not
+  // handling this'.
+  var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
+
+  // Reused option objects for setSelection & friends
+  var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"};
+
+  function Delayed() {this.id = null;}
+  Delayed.prototype.set = function(ms, f) {
+    clearTimeout(this.id);
+    this.id = setTimeout(f, ms);
+  };
+
+  // Counts the column offset in a string, taking tabs into account.
+  // Used mostly to find indentation.
+  var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) {
+    if (end == null) {
+      end = string.search(/[^\s\u00a0]/);
+      if (end == -1) end = string.length;
+    }
+    for (var i = startIndex || 0, n = startValue || 0;;) {
+      var nextTab = string.indexOf("\t", i);
+      if (nextTab < 0 || nextTab >= end)
+        return n + (end - i);
+      n += nextTab - i;
+      n += tabSize - (n % tabSize);
+      i = nextTab + 1;
+    }
+  };
+
+  // The inverse of countColumn -- find the offset that corresponds to
+  // a particular column.
+  function findColumn(string, goal, tabSize) {
+    for (var pos = 0, col = 0;;) {
+      var nextTab = string.indexOf("\t", pos);
+      if (nextTab == -1) nextTab = string.length;
+      var skipped = nextTab - pos;
+      if (nextTab == string.length || col + skipped >= goal)
+        return pos + Math.min(skipped, goal - col);
+      col += nextTab - pos;
+      col += tabSize - (col % tabSize);
+      pos = nextTab + 1;
+      if (col >= goal) return pos;
+    }
+  }
+
+  var spaceStrs = [""];
+  function spaceStr(n) {
+    while (spaceStrs.length <= n)
+      spaceStrs.push(lst(spaceStrs) + " ");
+    return spaceStrs[n];
+  }
+
+  function lst(arr) { return arr[arr.length-1]; }
+
+  var selectInput = function(node) { node.select(); };
+  if (ios) // Mobile Safari apparently has a bug where select() is broken.
+    selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; };
+  else if (ie) // Suppress mysterious IE10 errors
+    selectInput = function(node) { try { node.select(); } catch(_e) {} };
+
+  function indexOf(array, elt) {
+    for (var i = 0; i < array.length; ++i)
+      if (array[i] == elt) return i;
+    return -1;
+  }
+  if ([].indexOf) indexOf = function(array, elt) { return array.indexOf(elt); };
+  function map(array, f) {
+    var out = [];
+    for (var i = 0; i < array.length; i++) out[i] = f(array[i], i);
+    return out;
+  }
+  if ([].map) map = function(array, f) { return array.map(f); };
+
+  function createObj(base, props) {
+    var inst;
+    if (Object.create) {
+      inst = Object.create(base);
+    } else {
+      var ctor = function() {};
+      ctor.prototype = base;
+      inst = new ctor();
+    }
+    if (props) copyObj(props, inst);
+    return inst;
+  };
+
+  function copyObj(obj, target) {
+    if (!target) target = {};
+    for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop];
+    return target;
+  }
+
+  function bind(f) {
+    var args = Array.prototype.slice.call(arguments, 1);
+    return function(){return f.apply(null, args);};
+  }
+
+  var nonASCIISingleCaseWordChar = /[\u00df\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
+  var isWordChar = CodeMirror.isWordChar = function(ch) {
+    return /\w/.test(ch) || ch > "\x80" &&
+      (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
+  };
+
+  function isEmpty(obj) {
+    for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
+    return true;
+  }
+
+  // Extending unicode characters. A series of a non-extending char +
+  // any number of extending chars is treated as a single unit as far
+  // as editing and measuring is concerned. This is not fully correct,
+  // since some scripts/fonts/browsers also treat other configurations
+  // of code points as a group.
+  var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;
+  function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); }
+
+  // DOM UTILITIES
+
+  function elt(tag, content, className, style) {
+    var e = document.createElement(tag);
+    if (className) e.className = className;
+    if (style) e.style.cssText = style;
+    if (typeof content == "string") e.appendChild(document.createTextNode(content));
+    else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
+    return e;
+  }
+
+  var range;
+  if (document.createRange) range = function(node, start, end) {
+    var r = document.createRange();
+    r.setEnd(node, end);
+    r.setStart(node, start);
+    return r;
+  };
+  else range = function(node, start, end) {
+    var r = document.body.createTextRange();
+    r.moveToElementText(node.parentNode);
+    r.collapse(true);
+    r.moveEnd("character", end);
+    r.moveStart("character", start);
+    return r;
+  };
+
+  function removeChildren(e) {
+    for (var count = e.childNodes.length; count > 0; --count)
+      e.removeChild(e.firstChild);
+    return e;
+  }
+
+  function removeChildrenAndAdd(parent, e) {
+    return removeChildren(parent).appendChild(e);
+  }
+
+  function contains(parent, child) {
+    if (parent.contains)
+      return parent.contains(child);
+    while (child = child.parentNode)
+      if (child == parent) return true;
+  }
+
+  function activeElt() { return document.activeElement; }
+  // Older versions of IE throws unspecified error when touching
+  // document.activeElement in some cases (during loading, in iframe)
+  if (ie_upto10) activeElt = function() {
+    try { return document.activeElement; }
+    catch(e) { return document.body; }
+  };
+
+  // FEATURE DETECTION
+
+  // Detect drag-and-drop
+  var dragAndDrop = function() {
+    // There is *some* kind of drag-and-drop support in IE6-8, but I
+    // couldn't get it to work yet.
+    if (ie_upto8) return false;
+    var div = elt('div');
+    return "draggable" in div || "dragDrop" in div;
+  }();
+
+  var knownScrollbarWidth;
+  function scrollbarWidth(measure) {
+    if (knownScrollbarWidth != null) return knownScrollbarWidth;
+    var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll");
+    removeChildrenAndAdd(measure, test);
+    if (test.offsetWidth)
+      knownScrollbarWidth = test.offsetHeight - test.clientHeight;
+    return knownScrollbarWidth || 0;
+  }
+
+  var zwspSupported;
+  function zeroWidthElement(measure) {
+    if (zwspSupported == null) {
+      var test = elt("span", "\u200b");
+      removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
+      if (measure.firstChild.offsetHeight != 0)
+        zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !ie_upto7;
+    }
+    if (zwspSupported) return elt("span", "\u200b");
+    else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
+  }
+
+  // Feature-detect IE's crummy client rect reporting for bidi text
+  var badBidiRects;
+  function hasBadBidiRects(measure) {
+    if (badBidiRects != null) return badBidiRects;
+    var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA"));
+    var r0 = range(txt, 0, 1).getBoundingClientRect();
+    if (r0.left == r0.right) return false;
+    var r1 = range(txt, 1, 2).getBoundingClientRect();
+    return badBidiRects = (r1.right - r0.right < 3);
+  }
+
+  // See if "".split is the broken IE version, if so, provide an
+  // alternative way to split lines.
+  var splitLines = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
+    var pos = 0, result = [], l = string.length;
+    while (pos <= l) {
+      var nl = string.indexOf("\n", pos);
+      if (nl == -1) nl = string.length;
+      var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
+      var rt = line.indexOf("\r");
+      if (rt != -1) {
+        result.push(line.slice(0, rt));
+        pos += rt + 1;
+      } else {
+        result.push(line);
+        pos = nl + 1;
+      }
+    }
+    return result;
+  } : function(string){return string.split(/\r\n?|\n/);};
+
+  var hasSelection = window.getSelection ? function(te) {
+    try { return te.selectionStart != te.selectionEnd; }
+    catch(e) { return false; }
+  } : function(te) {
+    try {var range = te.ownerDocument.selection.createRange();}
+    catch(e) {}
+    if (!range || range.parentElement() != te) return false;
+    return range.compareEndPoints("StartToEnd", range) != 0;
+  };
+
+  var hasCopyEvent = (function() {
+    var e = elt("div");
+    if ("oncopy" in e) return true;
+    e.setAttribute("oncopy", "return;");
+    return typeof e.oncopy == "function";
+  })();
+
+  // KEY NAMES
+
+  var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
+                  19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
+                  36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
+                  46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", 107: "=", 109: "-", 127: "Delete",
+                  173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
+                  221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
+                  63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"};
+  CodeMirror.keyNames = keyNames;
+  (function() {
+    // Number keys
+    for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i);
+    // Alphabetic keys
+    for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
+    // Function keys
+    for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
+  })();
+
+  // BIDI HELPERS
+
+  function iterateBidiSections(order, from, to, f) {
+    if (!order) return f(from, to, "ltr");
+    var found = false;
+    for (var i = 0; i < order.length; ++i) {
+      var part = order[i];
+      if (part.from < to && part.to > from || from == to && part.to == from) {
+        f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
+        found = true;
+      }
+    }
+    if (!found) f(from, to, "ltr");
+  }
+
+  function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
+  function bidiRight(part) { return part.level % 2 ? part.from : part.to; }
+
+  function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }
+  function lineRight(line) {
+    var order = getOrder(line);
+    if (!order) return line.text.length;
+    return bidiRight(lst(order));
+  }
+
+  function lineStart(cm, lineN) {
+    var line = getLine(cm.doc, lineN);
+    var visual = visualLine(line);
+    if (visual != line) lineN = lineNo(visual);
+    var order = getOrder(visual);
+    var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);
+    return Pos(lineN, ch);
+  }
+  function lineEnd(cm, lineN) {
+    var merged, line = getLine(cm.doc, lineN);
+    while (merged = collapsedSpanAtEnd(line)) {
+      line = merged.find(1, true).line;
+      lineN = null;
+    }
+    var order = getOrder(line);
+    var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
+    return Pos(lineN == null ? lineNo(line) : lineN, ch);
+  }
+
+  function compareBidiLevel(order, a, b) {
+    var linedir = order[0].level;
+    if (a == linedir) return true;
+    if (b == linedir) return false;
+    return a < b;
+  }
+  var bidiOther;
+  function getBidiPartAt(order, pos) {
+    bidiOther = null;
+    for (var i = 0, found; i < order.length; ++i) {
+      var cur = order[i];
+      if (cur.from < pos && cur.to > pos) return i;
+      if ((cur.from == pos || cur.to == pos)) {
+        if (found == null) {
+          found = i;
+        } else if (compareBidiLevel(order, cur.level, order[found].level)) {
+          if (cur.from != cur.to) bidiOther = found;
+          return i;
+        } else {
+          if (cur.from != cur.to) bidiOther = i;
+          return found;
+        }
+      }
+    }
+    return found;
+  }
+
+  function moveInLine(line, pos, dir, byUnit) {
+    if (!byUnit) return pos + dir;
+    do pos += dir;
+    while (pos > 0 && isExtendingChar(line.text.charAt(pos)));
+    return pos;
+  }
+
+  // This is needed in order to move 'visually' through bi-directional
+  // text -- i.e., pressing left should make the cursor go left, even
+  // when in RTL text. The tricky part is the 'jumps', where RTL and
+  // LTR text touch each other. This often requires the cursor offset
+  // to move more than one unit, in order to visually move one unit.
+  function moveVisually(line, start, dir, byUnit) {
+    var bidi = getOrder(line);
+    if (!bidi) return moveLogically(line, start, dir, byUnit);
+    var pos = getBidiPartAt(bidi, start), part = bidi[pos];
+    var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit);
+
+    for (;;) {
+      if (target > part.from && target < part.to) return target;
+      if (target == part.from || target == part.to) {
+        if (getBidiPartAt(bidi, target) == pos) return target;
+        part = bidi[pos += dir];
+        return (dir > 0) == part.level % 2 ? part.to : part.from;
+      } else {
+        part = bidi[pos += dir];
+        if (!part) return null;
+        if ((dir > 0) == part.level % 2)
+          target = moveInLine(line, part.to, -1, byUnit);
+        else
+          target = moveInLine(line, part.from, 1, byUnit);
+      }
+    }
+  }
+
+  function moveLogically(line, start, dir, byUnit) {
+    var target = start + dir;
+    if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir;
+    return target < 0 || target > line.text.length ? null : target;
+  }
+
+  // Bidirectional ordering algorithm
+  // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
+  // that this (partially) implements.
+
+  // One-char codes used for character types:
+  // L (L):   Left-to-Right
+  // R (R):   Right-to-Left
+  // r (AL):  Right-to-Left Arabic
+  // 1 (EN):  European Number
+  // + (ES):  European Number Separator
+  // % (ET):  European Number Terminator
+  // n (AN):  Arabic Number
+  // , (CS):  Common Number Separator
+  // m (NSM): Non-Spacing Mark
+  // b (BN):  Boundary Neutral
+  // s (B):   Paragraph Separator
+  // t (S):   Segment Separator
+  // w (WS):  Whitespace
+  // N (ON):  Other Neutrals
+
+  // Returns null if characters are ordered as they appear
+  // (left-to-right), or an array of sections ({from, to, level}
+  // objects) in the order in which they occur visually.
+  var bidiOrdering = (function() {
+    // Character types for codepoints 0 to 0xff
+    var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN";
+    // Character types for codepoints 0x600 to 0x6ff
+    var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm";
+    function charType(code) {
+      if (code <= 0xf7) return lowTypes.charAt(code);
+      else if (0x590 <= code && code <= 0x5f4) return "R";
+      else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600);
+      else if (0x6ee <= code && code <= 0x8ac) return "r";
+      else if (0x2000 <= code && code <= 0x200b) return "w";
+      else if (code == 0x200c) return "b";
+      else return "L";
+    }
+
+    var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
+    var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
+    // Browsers seem to always treat the boundaries of block elements as being L.
+    var outerType = "L";
+
+    function BidiSpan(level, from, to) {
+      this.level = level;
+      this.from = from; this.to = to;
+    }
+
+    return function(str) {
+      if (!bidiRE.test(str)) return false;
+      var len = str.length, types = [];
+      for (var i = 0, type; i < len; ++i)
+        types.push(type = charType(str.charCodeAt(i)));
+
+      // W1. Examine each non-spacing mark (NSM) in the level run, and
+      // change the type of the NSM to the type of the previous
+      // character. If the NSM is at the start of the level run, it will
+      // get the type of sor.
+      for (var i = 0, prev = outerType; i < len; ++i) {
+        var type = types[i];
+        if (type == "m") types[i] = prev;
+        else prev = type;
+      }
+
+      // W2. Search backwards from each instance of a European number
+      // until the first strong type (R, L, AL, or sor) is found. If an
+      // AL is found, change the type of the European number to Arabic
+      // number.
+      // W3. Change all ALs to R.
+      for (var i = 0, cur = outerType; i < len; ++i) {
+        var type = types[i];
+        if (type == "1" && cur == "r") types[i] = "n";
+        else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; }
+      }
+
+      // W4. A single European separator between two European numbers
+      // changes to a European number. A single common separator between
+      // two numbers of the same type changes to that type.
+      for (var i = 1, prev = types[0]; i < len - 1; ++i) {
+        var type = types[i];
+        if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1";
+        else if (type == "," && prev == types[i+1] &&
+                 (prev == "1" || prev == "n")) types[i] = prev;
+        prev = type;
+      }
+
+      // W5. A sequence of European terminators adjacent to European
+      // numbers changes to all European numbers.
+      // W6. Otherwise, separators and terminators change to Other
+      // Neutral.
+      for (var i = 0; i < len; ++i) {
+        var type = types[i];
+        if (type == ",") types[i] = "N";
+        else if (type == "%") {
+          for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
+          var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N";
+          for (var j = i; j < end; ++j) types[j] = replace;
+          i = end - 1;
+        }
+      }
+
+      // W7. Search backwards from each instance of a European number
+      // until the first strong type (R, L, or sor) is found. If an L is
+      // found, then change the type of the European number to L.
+      for (var i = 0, cur = outerType; i < len; ++i) {
+        var type = types[i];
+        if (cur == "L" && type == "1") types[i] = "L";
+        else if (isStrong.test(type)) cur = type;
+      }
+
+      // N1. A sequence of neutrals takes the direction of the
+      // surrounding strong text if the text on both sides has the same
+      // direction. European and Arabic numbers act as if they were R in
+      // terms of their influence on neutrals. Start-of-level-run (sor)
+      // and end-of-level-run (eor) are used at level run boundaries.
+      // N2. Any remaining neutrals take the embedding direction.
+      for (var i = 0; i < len; ++i) {
+        if (isNeutral.test(types[i])) {
+          for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
+          var before = (i ? types[i-1] : outerType) == "L";
+          var after = (end < len ? types[end] : outerType) == "L";
+          var replace = before || after ? "L" : "R";
+          for (var j = i; j < end; ++j) types[j] = replace;
+          i = end - 1;
+        }
+      }
+
+      // Here we depart from the documented algorithm, in order to avoid
+      // building up an actual levels array. Since there are only three
+      // levels (0, 1, 2) in an implementation that doesn't take
+      // explicit embedding into account, we can build up the order on
+      // the fly, without following the level-based algorithm.
+      var order = [], m;
+      for (var i = 0; i < len;) {
+        if (countsAsLeft.test(types[i])) {
+          var start = i;
+          for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
+          order.push(new BidiSpan(0, start, i));
+        } else {
+          var pos = i, at = order.length;
+          for (++i; i < len && types[i] != "L"; ++i) {}
+          for (var j = pos; j < i;) {
+            if (countsAsNum.test(types[j])) {
+              if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j));
+              var nstart = j;
+              for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
+              order.splice(at, 0, new BidiSpan(2, nstart, j));
+              pos = j;
+            } else ++j;
+          }
+          if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i));
+        }
+      }
+      if (order[0].level == 1 && (m = str.match(/^\s+/))) {
+        order[0].from = m[0].length;
+        order.unshift(new BidiSpan(0, 0, m[0].length));
+      }
+      if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
+        lst(order).to -= m[0].length;
+        order.push(new BidiSpan(0, len - m[0].length, len));
+      }
+      if (order[0].level != lst(order).level)
+        order.push(new BidiSpan(order[0].level, len, len));
+
+      return order;
+    };
+  })();
+
+  // THE END
+
+  CodeMirror.version = "4.0.3";
+
+  return CodeMirror;
+});
diff --git a/app/gui/html/vendor/codemirror/mode/apl/apl.js b/app/gui/html/vendor/codemirror/mode/apl/apl.js
new file mode 100644
index 0000000..2ba74c1
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/apl/apl.js
@@ -0,0 +1,172 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("apl", function() {
+  var builtInOps = {
+    ".": "innerProduct",
+    "\\": "scan",
+    "/": "reduce",
+    "⌿": "reduce1Axis",
+    "⍀": "scan1Axis",
+    "¨": "each",
+    "⍣": "power"
+  };
+  var builtInFuncs = {
+    "+": ["conjugate", "add"],
+    "−": ["negate", "subtract"],
+    "×": ["signOf", "multiply"],
+    "÷": ["reciprocal", "divide"],
+    "⌈": ["ceiling", "greaterOf"],
+    "⌊": ["floor", "lesserOf"],
+    "∣": ["absolute", "residue"],
+    "⍳": ["indexGenerate", "indexOf"],
+    "?": ["roll", "deal"],
+    "⋆": ["exponentiate", "toThePowerOf"],
+    "⍟": ["naturalLog", "logToTheBase"],
+    "â—‹": ["piTimes", "circularFuncs"],
+    "!": ["factorial", "binomial"],
+    "⌹": ["matrixInverse", "matrixDivide"],
+    "<": [null, "lessThan"],
+    "≤": [null, "lessThanOrEqual"],
+    "=": [null, "equals"],
+    ">": [null, "greaterThan"],
+    "≥": [null, "greaterThanOrEqual"],
+    "≠": [null, "notEqual"],
+    "≡": ["depth", "match"],
+    "≢": [null, "notMatch"],
+    "∈": ["enlist", "membership"],
+    "⍷": [null, "find"],
+    "∪": ["unique", "union"],
+    "∩": [null, "intersection"],
+    "∼": ["not", "without"],
+    "∨": [null, "or"],
+    "∧": [null, "and"],
+    "⍱": [null, "nor"],
+    "⍲": [null, "nand"],
+    "⍴": ["shapeOf", "reshape"],
+    ",": ["ravel", "catenate"],
+    "⍪": [null, "firstAxisCatenate"],
+    "⌽": ["reverse", "rotate"],
+    "⊖": ["axis1Reverse", "axis1Rotate"],
+    "⍉": ["transpose", null],
+    "↑": ["first", "take"],
+    "↓": [null, "drop"],
+    "⊂": ["enclose", "partitionWithAxis"],
+    "⊃": ["diclose", "pick"],
+    "⌷": [null, "index"],
+    "⍋": ["gradeUp", null],
+    "⍒": ["gradeDown", null],
+    "⊤": ["encode", null],
+    "⊥": ["decode", null],
+    "⍕": ["format", "formatByExample"],
+    "⍎": ["execute", null],
+    "⊣": ["stop", "left"],
+    "⊢": ["pass", "right"]
+  };
+
+  var isOperator = /[\.\/⌿⍀¨⍣]/;
+  var isNiladic = /⍬/;
+  var isFunction = /[\+−×÷⌈⌊∣⍳\?⋆⍟○!⌹<≤=>≥≠≡≢∈⍷∪∩∼∨∧⍱⍲⍴,⍪⌽⊖⍉↑↓⊂⊃⌷⍋⍒⊤⊥⍕⍎⊣⊢]/;
+  var isArrow = /←/;
+  var isComment = /[⍝#].*$/;
+
+  var stringEater = function(type) {
+    var prev;
+    prev = false;
+    return function(c) {
+      prev = c;
+      if (c === type) {
+        return prev === "\\";
+      }
+      return true;
+    };
+  };
+  return {
+    startState: function() {
+      return {
+        prev: false,
+        func: false,
+        op: false,
+        string: false,
+        escape: false
+      };
+    },
+    token: function(stream, state) {
+      var ch, funcName, word;
+      if (stream.eatSpace()) {
+        return null;
+      }
+      ch = stream.next();
+      if (ch === '"' || ch === "'") {
+        stream.eatWhile(stringEater(ch));
+        stream.next();
+        state.prev = true;
+        return "string";
+      }
+      if (/[\[{\(]/.test(ch)) {
+        state.prev = false;
+        return null;
+      }
+      if (/[\]}\)]/.test(ch)) {
+        state.prev = true;
+        return null;
+      }
+      if (isNiladic.test(ch)) {
+        state.prev = false;
+        return "niladic";
+      }
+      if (/[¯\d]/.test(ch)) {
+        if (state.func) {
+          state.func = false;
+          state.prev = false;
+        } else {
+          state.prev = true;
+        }
+        stream.eatWhile(/[\w\.]/);
+        return "number";
+      }
+      if (isOperator.test(ch)) {
+        return "operator apl-" + builtInOps[ch];
+      }
+      if (isArrow.test(ch)) {
+        return "apl-arrow";
+      }
+      if (isFunction.test(ch)) {
+        funcName = "apl-";
+        if (builtInFuncs[ch] != null) {
+          if (state.prev) {
+            funcName += builtInFuncs[ch][1];
+          } else {
+            funcName += builtInFuncs[ch][0];
+          }
+        }
+        state.func = true;
+        state.prev = false;
+        return "function " + funcName;
+      }
+      if (isComment.test(ch)) {
+        stream.skipToEnd();
+        return "comment";
+      }
+      if (ch === "∘" && stream.peek() === ".") {
+        stream.next();
+        return "function jot-dot";
+      }
+      stream.eatWhile(/[\w\$_]/);
+      word = stream.current();
+      state.prev = true;
+      return "keyword";
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/apl", "apl");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/apl/index.html b/app/gui/html/vendor/codemirror/mode/apl/index.html
new file mode 100644
index 0000000..f8282ac
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/apl/index.html
@@ -0,0 +1,72 @@
+<!doctype html>
+
+<title>CodeMirror: APL mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="./apl.js"></script>
+<style>
+	.CodeMirror { border: 2px inset #dee; }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">APL</a>
+  </ul>
+</div>
+
+<article>
+<h2>APL mode</h2>
+<form><textarea id="code" name="code">
+⍝ Conway's game of life
+
+⍝ This example was inspired by the impressive demo at
+⍝ http://www.youtube.com/watch?v=a9xAKttWgP4
+
+⍝ Create a matrix:
+⍝     0 1 1
+⍝     1 1 0
+⍝     0 1 0
+creature ← (3 3 ⍴ ⍳ 9) ∈ 1 2 3 4 7   ⍝ Original creature from demo
+creature ← (3 3 ⍴ ⍳ 9) ∈ 1 3 6 7 8   ⍝ Glider
+
+⍝ Place the creature on a larger board, near the centre
+board ← ¯1 ⊖ ¯2 ⌽ 5 7 ↑ creature
+
+⍝ A function to move from one generation to the next
+life ← {∨/ 1 ⍵ ∧ 3 4 = ⊂+/ +⌿ 1 0 ¯1 ∘.⊖ 1 0 ¯1 ⌽¨ ⊂⍵}
+
+⍝ Compute n-th generation and format it as a
+⍝ character matrix
+gen ← {' #'[(life ⍣ ⍵) board]}
+
+⍝ Show first three generations
+(gen 1) (gen 2) (gen 3)
+</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        mode: "text/apl"
+      });
+    </script>
+
+    <p>Simple mode that tries to handle APL as well as it can.</p>
+    <p>It attempts to label functions/operators based upon
+    monadic/dyadic usage (but this is far from fully fleshed out).
+    This means there are meaningful classnames so hover states can
+    have popups etc.</p>
+
+    <p><strong>MIME types defined:</strong> <code>text/apl</code> (APL code)</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/asterisk/asterisk.js b/app/gui/html/vendor/codemirror/mode/asterisk/asterisk.js
new file mode 100644
index 0000000..c56fc0b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/asterisk/asterisk.js
@@ -0,0 +1,195 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  mode/asterisk/asterisk.js
+ *
+ *    Description:  CodeMirror mode for Asterisk dialplan
+ *
+ *        Created:  05/17/2012 09:20:25 PM
+ *       Revision:  none
+ *
+ *         Author:  Stas Kobzar (stas at modulis.ca),
+ *        Company:  Modulis.ca Inc.
+ *
+ * =====================================================================================
+ */
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("asterisk", function() {
+  var atoms    = ["exten", "same", "include","ignorepat","switch"],
+      dpcmd    = ["#include","#exec"],
+      apps     = [
+                  "addqueuemember","adsiprog","aelsub","agentlogin","agentmonitoroutgoing","agi",
+                  "alarmreceiver","amd","answer","authenticate","background","backgrounddetect",
+                  "bridge","busy","callcompletioncancel","callcompletionrequest","celgenuserevent",
+                  "changemonitor","chanisavail","channelredirect","chanspy","clearhash","confbridge",
+                  "congestion","continuewhile","controlplayback","dahdiacceptr2call","dahdibarge",
+                  "dahdiras","dahdiscan","dahdisendcallreroutingfacility","dahdisendkeypadfacility",
+                  "datetime","dbdel","dbdeltree","deadagi","dial","dictate","directory","disa",
+                  "dumpchan","eagi","echo","endwhile","exec","execif","execiftime","exitwhile","extenspy",
+                  "externalivr","festival","flash","followme","forkcdr","getcpeid","gosub","gosubif",
+                  "goto","gotoif","gotoiftime","hangup","iax2provision","ices","importvar","incomplete",
+                  "ivrdemo","jabberjoin","jabberleave","jabbersend","jabbersendgroup","jabberstatus",
+                  "jack","log","macro","macroexclusive","macroexit","macroif","mailboxexists","meetme",
+                  "meetmeadmin","meetmechanneladmin","meetmecount","milliwatt","minivmaccmess","minivmdelete",
+                  "minivmgreet","minivmmwi","minivmnotify","minivmrecord","mixmonitor","monitor","morsecode",
+                  "mp3player","mset","musiconhold","nbscat","nocdr","noop","odbc","odbc","odbcfinish",
+                  "originate","ospauth","ospfinish","osplookup","ospnext","page","park","parkandannounce",
+                  "parkedcall","pausemonitor","pausequeuemember","pickup","pickupchan","playback","playtones",
+                  "privacymanager","proceeding","progress","queue","queuelog","raiseexception","read","readexten",
+                  "readfile","receivefax","receivefax","receivefax","record","removequeuemember",
+                  "resetcdr","retrydial","return","ringing","sayalpha","saycountedadj","saycountednoun",
+                  "saycountpl","saydigits","saynumber","sayphonetic","sayunixtime","senddtmf","sendfax",
+                  "sendfax","sendfax","sendimage","sendtext","sendurl","set","setamaflags",
+                  "setcallerpres","setmusiconhold","sipaddheader","sipdtmfmode","sipremoveheader","skel",
+                  "slastation","slatrunk","sms","softhangup","speechactivategrammar","speechbackground",
+                  "speechcreate","speechdeactivategrammar","speechdestroy","speechloadgrammar","speechprocessingsound",
+                  "speechstart","speechunloadgrammar","stackpop","startmusiconhold","stopmixmonitor","stopmonitor",
+                  "stopmusiconhold","stopplaytones","system","testclient","testserver","transfer","tryexec",
+                  "trysystem","unpausemonitor","unpausequeuemember","userevent","verbose","vmauthenticate",
+                  "vmsayname","voicemail","voicemailmain","wait","waitexten","waitfornoise","waitforring",
+                  "waitforsilence","waitmusiconhold","waituntil","while","zapateller"
+                 ];
+
+  function basicToken(stream,state){
+    var cur = '';
+    var ch  = '';
+    ch = stream.next();
+    // comment
+    if(ch == ";") {
+      stream.skipToEnd();
+      return "comment";
+    }
+    // context
+    if(ch == '[') {
+      stream.skipTo(']');
+      stream.eat(']');
+      return "header";
+    }
+    // string
+    if(ch == '"') {
+      stream.skipTo('"');
+      return "string";
+    }
+    if(ch == "'") {
+      stream.skipTo("'");
+      return "string-2";
+    }
+    // dialplan commands
+    if(ch == '#') {
+      stream.eatWhile(/\w/);
+      cur = stream.current();
+      if(dpcmd.indexOf(cur) !== -1) {
+        stream.skipToEnd();
+        return "strong";
+      }
+    }
+    // application args
+    if(ch == '$'){
+      var ch1 = stream.peek();
+      if(ch1 == '{'){
+        stream.skipTo('}');
+        stream.eat('}');
+        return "variable-3";
+      }
+    }
+    // extension
+    stream.eatWhile(/\w/);
+    cur = stream.current();
+    if(atoms.indexOf(cur) !== -1) {
+      state.extenStart = true;
+      switch(cur) {
+        case 'same': state.extenSame = true; break;
+        case 'include':
+        case 'switch':
+        case 'ignorepat':
+          state.extenInclude = true;break;
+        default:break;
+      }
+      return "atom";
+    }
+  }
+
+  return {
+    startState: function() {
+      return {
+        extenStart: false,
+        extenSame:  false,
+        extenInclude: false,
+        extenExten: false,
+        extenPriority: false,
+        extenApplication: false
+      };
+    },
+    token: function(stream, state) {
+
+      var cur = '';
+      var ch  = '';
+      if(stream.eatSpace()) return null;
+      // extension started
+      if(state.extenStart){
+        stream.eatWhile(/[^\s]/);
+        cur = stream.current();
+        if(/^=>?$/.test(cur)){
+          state.extenExten = true;
+          state.extenStart = false;
+          return "strong";
+        } else {
+          state.extenStart = false;
+          stream.skipToEnd();
+          return "error";
+        }
+      } else if(state.extenExten) {
+        // set exten and priority
+        state.extenExten = false;
+        state.extenPriority = true;
+        stream.eatWhile(/[^,]/);
+        if(state.extenInclude) {
+          stream.skipToEnd();
+          state.extenPriority = false;
+          state.extenInclude = false;
+        }
+        if(state.extenSame) {
+          state.extenPriority = false;
+          state.extenSame = false;
+          state.extenApplication = true;
+        }
+        return "tag";
+      } else if(state.extenPriority) {
+        state.extenPriority = false;
+        state.extenApplication = true;
+        ch = stream.next(); // get comma
+        if(state.extenSame) return null;
+        stream.eatWhile(/[^,]/);
+        return "number";
+      } else if(state.extenApplication) {
+        stream.eatWhile(/,/);
+        cur = stream.current();
+        if(cur === ',') return null;
+        stream.eatWhile(/\w/);
+        cur = stream.current().toLowerCase();
+        state.extenApplication = false;
+        if(apps.indexOf(cur) !== -1){
+          return "def strong";
+        }
+      } else{
+        return basicToken(stream,state);
+      }
+
+      return null;
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/x-asterisk", "asterisk");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/asterisk/index.html b/app/gui/html/vendor/codemirror/mode/asterisk/index.html
new file mode 100644
index 0000000..6abdecb
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/asterisk/index.html
@@ -0,0 +1,154 @@
+<!doctype html>
+
+<title>CodeMirror: Asterisk dialplan mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="asterisk.js"></script>
+<style>
+      .CodeMirror {border: 1px solid #999;}
+      .cm-s-default span.cm-arrow { color: red; }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Asterisk dialplan</a>
+  </ul>
+</div>
+
+<article>
+<h2>Asterisk dialplan mode</h2>
+<form><textarea id="code" name="code">
+; extensions.conf - the Asterisk dial plan
+;
+
+[general]
+;
+; If static is set to no, or omitted, then the pbx_config will rewrite
+; this file when extensions are modified.  Remember that all comments
+; made in the file will be lost when that happens.
+static=yes
+
+#include "/etc/asterisk/additional_general.conf
+
+[iaxprovider]
+switch => IAX2/user:[key]@myserver/mycontext
+
+[dynamic]
+#exec /usr/bin/dynamic-peers.pl
+
+[trunkint]
+;
+; International long distance through trunk
+;
+exten => _9011.,1,Macro(dundi-e164,${EXTEN:4})
+exten => _9011.,n,Dial(${GLOBAL(TRUNK)}/${FILTER(0-9,${EXTEN:${GLOBAL(TRUNKMSD)}})})
+
+[local]
+;
+; Master context for local, toll-free, and iaxtel calls only
+;
+ignorepat => 9
+include => default
+
+[demo]
+include => stdexten
+;
+; We start with what to do when a call first comes in.
+;
+exten => s,1,Wait(1)			; Wait a second, just for fun
+same  => n,Answer			; Answer the line
+same  => n,Set(TIMEOUT(digit)=5)	; Set Digit Timeout to 5 seconds
+same  => n,Set(TIMEOUT(response)=10)	; Set Response Timeout to 10 seconds
+same  => n(restart),BackGround(demo-congrats)	; Play a congratulatory message
+same  => n(instruct),BackGround(demo-instruct)	; Play some instructions
+same  => n,WaitExten			; Wait for an extension to be dialed.
+
+exten => 2,1,BackGround(demo-moreinfo)	; Give some more information.
+exten => 2,n,Goto(s,instruct)
+
+exten => 3,1,Set(LANGUAGE()=fr)		; Set language to french
+exten => 3,n,Goto(s,restart)		; Start with the congratulations
+
+exten => 1000,1,Goto(default,s,1)
+;
+; We also create an example user, 1234, who is on the console and has
+; voicemail, etc.
+;
+exten => 1234,1,Playback(transfer,skip)		; "Please hold while..."
+					; (but skip if channel is not up)
+exten => 1234,n,Gosub(${EXTEN},stdexten(${GLOBAL(CONSOLE)}))
+exten => 1234,n,Goto(default,s,1)		; exited Voicemail
+
+exten => 1235,1,Voicemail(1234,u)		; Right to voicemail
+
+exten => 1236,1,Dial(Console/dsp)		; Ring forever
+exten => 1236,n,Voicemail(1234,b)		; Unless busy
+
+;
+; # for when they're done with the demo
+;
+exten => #,1,Playback(demo-thanks)	; "Thanks for trying the demo"
+exten => #,n,Hangup			; Hang them up.
+
+;
+; A timeout and "invalid extension rule"
+;
+exten => t,1,Goto(#,1)			; If they take too long, give up
+exten => i,1,Playback(invalid)		; "That's not valid, try again"
+
+;
+; Create an extension, 500, for dialing the
+; Asterisk demo.
+;
+exten => 500,1,Playback(demo-abouttotry); Let them know what's going on
+exten => 500,n,Dial(IAX2/guest at pbx.digium.com/s at default)	; Call the Asterisk demo
+exten => 500,n,Playback(demo-nogo)	; Couldn't connect to the demo site
+exten => 500,n,Goto(s,6)		; Return to the start over message.
+
+;
+; Create an extension, 600, for evaluating echo latency.
+;
+exten => 600,1,Playback(demo-echotest)	; Let them know what's going on
+exten => 600,n,Echo			; Do the echo test
+exten => 600,n,Playback(demo-echodone)	; Let them know it's over
+exten => 600,n,Goto(s,6)		; Start over
+
+;
+;	You can use the Macro Page to intercom a individual user
+exten => 76245,1,Macro(page,SIP/Grandstream1)
+; or if your peernames are the same as extensions
+exten => _7XXX,1,Macro(page,SIP/${EXTEN})
+;
+;
+; System Wide Page at extension 7999
+;
+exten => 7999,1,Set(TIMEOUT(absolute)=60)
+exten => 7999,2,Page(Local/Grandstream1 at page&Local/Xlite1 at page&Local/1234 at page/n,d)
+
+; Give voicemail at extension 8500
+;
+exten => 8500,1,VoicemailMain
+exten => 8500,n,Goto(s,6)
+
+    </textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: "text/x-asterisk",
+        matchBrackets: true,
+        lineNumber: true
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-asterisk</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/clike/clike.js b/app/gui/html/vendor/codemirror/mode/clike/clike.js
new file mode 100644
index 0000000..0e61020
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/clike/clike.js
@@ -0,0 +1,437 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("clike", function(config, parserConfig) {
+  var indentUnit = config.indentUnit,
+      statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
+      dontAlignCalls = parserConfig.dontAlignCalls,
+      keywords = parserConfig.keywords || {},
+      builtin = parserConfig.builtin || {},
+      blockKeywords = parserConfig.blockKeywords || {},
+      atoms = parserConfig.atoms || {},
+      hooks = parserConfig.hooks || {},
+      multiLineStrings = parserConfig.multiLineStrings;
+  var isOperatorChar = /[+\-*&%=<>!?|\/]/;
+
+  var curPunc;
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+    if (hooks[ch]) {
+      var result = hooks[ch](stream, state);
+      if (result !== false) return result;
+    }
+    if (ch == '"' || ch == "'") {
+      state.tokenize = tokenString(ch);
+      return state.tokenize(stream, state);
+    }
+    if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
+      curPunc = ch;
+      return null;
+    }
+    if (/\d/.test(ch)) {
+      stream.eatWhile(/[\w\.]/);
+      return "number";
+    }
+    if (ch == "/") {
+      if (stream.eat("*")) {
+        state.tokenize = tokenComment;
+        return tokenComment(stream, state);
+      }
+      if (stream.eat("/")) {
+        stream.skipToEnd();
+        return "comment";
+      }
+    }
+    if (isOperatorChar.test(ch)) {
+      stream.eatWhile(isOperatorChar);
+      return "operator";
+    }
+    stream.eatWhile(/[\w\$_]/);
+    var cur = stream.current();
+    if (keywords.propertyIsEnumerable(cur)) {
+      if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+      return "keyword";
+    }
+    if (builtin.propertyIsEnumerable(cur)) {
+      if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+      return "builtin";
+    }
+    if (atoms.propertyIsEnumerable(cur)) return "atom";
+    return "variable";
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, next, end = false;
+      while ((next = stream.next()) != null) {
+        if (next == quote && !escaped) {end = true; break;}
+        escaped = !escaped && next == "\\";
+      }
+      if (end || !(escaped || multiLineStrings))
+        state.tokenize = null;
+      return "string";
+    };
+  }
+
+  function tokenComment(stream, state) {
+    var maybeEnd = false, ch;
+    while (ch = stream.next()) {
+      if (ch == "/" && maybeEnd) {
+        state.tokenize = null;
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return "comment";
+  }
+
+  function Context(indented, column, type, align, prev) {
+    this.indented = indented;
+    this.column = column;
+    this.type = type;
+    this.align = align;
+    this.prev = prev;
+  }
+  function pushContext(state, col, type) {
+    var indent = state.indented;
+    if (state.context && state.context.type == "statement")
+      indent = state.context.indented;
+    return state.context = new Context(indent, col, type, null, state.context);
+  }
+  function popContext(state) {
+    var t = state.context.type;
+    if (t == ")" || t == "]" || t == "}")
+      state.indented = state.context.indented;
+    return state.context = state.context.prev;
+  }
+
+  // Interface
+
+  return {
+    startState: function(basecolumn) {
+      return {
+        tokenize: null,
+        context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
+        indented: 0,
+        startOfLine: true
+      };
+    },
+
+    token: function(stream, state) {
+      var ctx = state.context;
+      if (stream.sol()) {
+        if (ctx.align == null) ctx.align = false;
+        state.indented = stream.indentation();
+        state.startOfLine = true;
+      }
+      if (stream.eatSpace()) return null;
+      curPunc = null;
+      var style = (state.tokenize || tokenBase)(stream, state);
+      if (style == "comment" || style == "meta") return style;
+      if (ctx.align == null) ctx.align = true;
+
+      if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
+      else if (curPunc == "{") pushContext(state, stream.column(), "}");
+      else if (curPunc == "[") pushContext(state, stream.column(), "]");
+      else if (curPunc == "(") pushContext(state, stream.column(), ")");
+      else if (curPunc == "}") {
+        while (ctx.type == "statement") ctx = popContext(state);
+        if (ctx.type == "}") ctx = popContext(state);
+        while (ctx.type == "statement") ctx = popContext(state);
+      }
+      else if (curPunc == ctx.type) popContext(state);
+      else if (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') || (ctx.type == "statement" && curPunc == "newstatement"))
+        pushContext(state, stream.column(), "statement");
+      state.startOfLine = false;
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
+      var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
+      if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
+      var closing = firstChar == ctx.type;
+      if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
+      else if (ctx.align && (!dontAlignCalls || ctx.type != ")")) return ctx.column + (closing ? 0 : 1);
+      else if (ctx.type == ")" && !closing) return ctx.indented + statementIndentUnit;
+      else return ctx.indented + (closing ? 0 : indentUnit);
+    },
+
+    electricChars: "{}",
+    blockCommentStart: "/*",
+    blockCommentEnd: "*/",
+    lineComment: "//",
+    fold: "brace"
+  };
+});
+
+(function() {
+  function words(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+  var cKeywords = "auto if break int case long char register continue return default short do sizeof " +
+    "double static else struct entry switch extern typedef float union for unsigned " +
+    "goto while enum void const signed volatile";
+
+  function cppHook(stream, state) {
+    if (!state.startOfLine) return false;
+    for (;;) {
+      if (stream.skipTo("\\")) {
+        stream.next();
+        if (stream.eol()) {
+          state.tokenize = cppHook;
+          break;
+        }
+      } else {
+        stream.skipToEnd();
+        state.tokenize = null;
+        break;
+      }
+    }
+    return "meta";
+  }
+
+  function cpp11StringHook(stream, state) {
+    stream.backUp(1);
+    // Raw strings.
+    if (stream.match(/(R|u8R|uR|UR|LR)/)) {
+      var match = stream.match(/"(.{0,16})\(/);
+      if (!match) {
+        return false;
+      }
+      state.cpp11RawStringDelim = match[1];
+      state.tokenize = tokenRawString;
+      return tokenRawString(stream, state);
+    }
+    // Unicode strings/chars.
+    if (stream.match(/(u8|u|U|L)/)) {
+      if (stream.match(/["']/, /* eat */ false)) {
+        return "string";
+      }
+      return false;
+    }
+    // Ignore this hook.
+    stream.next();
+    return false;
+  }
+
+  // C#-style strings where "" escapes a quote.
+  function tokenAtString(stream, state) {
+    var next;
+    while ((next = stream.next()) != null) {
+      if (next == '"' && !stream.eat('"')) {
+        state.tokenize = null;
+        break;
+      }
+    }
+    return "string";
+  }
+
+  // C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where
+  // <delim> can be a string up to 16 characters long.
+  function tokenRawString(stream, state) {
+    var closingSequence = new RegExp(".*?\\)" + state.cpp11RawStringDelim + '"');
+    var match = stream.match(closingSequence);
+    if (match) {
+      state.tokenize = null;
+    } else {
+      stream.skipToEnd();
+    }
+    return "string";
+  }
+
+  function def(mimes, mode) {
+    var words = [];
+    function add(obj) {
+      if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
+        words.push(prop);
+    }
+    add(mode.keywords);
+    add(mode.builtin);
+    add(mode.atoms);
+    if (words.length) {
+      mode.helperType = mimes[0];
+      CodeMirror.registerHelper("hintWords", mimes[0], words);
+    }
+
+    for (var i = 0; i < mimes.length; ++i)
+      CodeMirror.defineMIME(mimes[i], mode);
+  }
+
+  def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
+    name: "clike",
+    keywords: words(cKeywords),
+    blockKeywords: words("case do else for if switch while struct"),
+    atoms: words("null"),
+    hooks: {"#": cppHook},
+    modeProps: {fold: ["brace", "include"]}
+  });
+
+  def(["text/x-c++src", "text/x-c++hdr"], {
+    name: "clike",
+    keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try bool explicit new " +
+                    "static_cast typeid catch operator template typename class friend private " +
+                    "this using const_cast inline public throw virtual delete mutable protected " +
+                    "wchar_t alignas alignof constexpr decltype nullptr noexcept thread_local final " +
+                    "static_assert override"),
+    blockKeywords: words("catch class do else finally for if struct switch try while"),
+    atoms: words("true false null"),
+    hooks: {
+      "#": cppHook,
+      "u": cpp11StringHook,
+      "U": cpp11StringHook,
+      "L": cpp11StringHook,
+      "R": cpp11StringHook
+    },
+    modeProps: {fold: ["brace", "include"]}
+  });
+  CodeMirror.defineMIME("text/x-java", {
+    name: "clike",
+    keywords: words("abstract assert boolean break byte case catch char class const continue default " +
+                    "do double else enum extends final finally float for goto if implements import " +
+                    "instanceof int interface long native new package private protected public " +
+                    "return short static strictfp super switch synchronized this throw throws transient " +
+                    "try void volatile while"),
+    blockKeywords: words("catch class do else finally for if switch try while"),
+    atoms: words("true false null"),
+    hooks: {
+      "@": function(stream) {
+        stream.eatWhile(/[\w\$_]/);
+        return "meta";
+      }
+    },
+    modeProps: {fold: ["brace", "import"]}
+  });
+  CodeMirror.defineMIME("text/x-csharp", {
+    name: "clike",
+    keywords: words("abstract as base break case catch checked class const continue" +
+                    " default delegate do else enum event explicit extern finally fixed for" +
+                    " foreach goto if implicit in interface internal is lock namespace new" +
+                    " operator out override params private protected public readonly ref return sealed" +
+                    " sizeof stackalloc static struct switch this throw try typeof unchecked" +
+                    " unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
+                    " global group into join let orderby partial remove select set value var yield"),
+    blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
+    builtin: words("Boolean Byte Char DateTime DateTimeOffset Decimal Double" +
+                    " Guid Int16 Int32 Int64 Object SByte Single String TimeSpan UInt16 UInt32" +
+                    " UInt64 bool byte char decimal double short int long object"  +
+                    " sbyte float string ushort uint ulong"),
+    atoms: words("true false null"),
+    hooks: {
+      "@": function(stream, state) {
+        if (stream.eat('"')) {
+          state.tokenize = tokenAtString;
+          return tokenAtString(stream, state);
+        }
+        stream.eatWhile(/[\w\$_]/);
+        return "meta";
+      }
+    }
+  });
+  CodeMirror.defineMIME("text/x-scala", {
+    name: "clike",
+    keywords: words(
+
+      /* scala */
+      "abstract case catch class def do else extends false final finally for forSome if " +
+      "implicit import lazy match new null object override package private protected return " +
+      "sealed super this throw trait try trye type val var while with yield _ : = => <- <: " +
+      "<% >: # @ " +
+
+      /* package scala */
+      "assert assume require print println printf readLine readBoolean readByte readShort " +
+      "readChar readInt readLong readFloat readDouble " +
+
+      "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
+      "Enumeration Equiv Error Exception Fractional Function IndexedSeq Integral Iterable " +
+      "Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " +
+      "Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " +
+      "StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector :: #:: " +
+
+      /* package java.lang */
+      "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
+      "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
+      "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
+      "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
+
+
+    ),
+    blockKeywords: words("catch class do else finally for forSome if match switch try while"),
+    atoms: words("true false null"),
+    hooks: {
+      "@": function(stream) {
+        stream.eatWhile(/[\w\$_]/);
+        return "meta";
+      }
+    }
+  });
+  def(["x-shader/x-vertex", "x-shader/x-fragment"], {
+    name: "clike",
+    keywords: words("float int bool void " +
+                    "vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
+                    "mat2 mat3 mat4 " +
+                    "sampler1D sampler2D sampler3D samplerCube " +
+                    "sampler1DShadow sampler2DShadow" +
+                    "const attribute uniform varying " +
+                    "break continue discard return " +
+                    "for while do if else struct " +
+                    "in out inout"),
+    blockKeywords: words("for while do if else struct"),
+    builtin: words("radians degrees sin cos tan asin acos atan " +
+                    "pow exp log exp2 sqrt inversesqrt " +
+                    "abs sign floor ceil fract mod min max clamp mix step smootstep " +
+                    "length distance dot cross normalize ftransform faceforward " +
+                    "reflect refract matrixCompMult " +
+                    "lessThan lessThanEqual greaterThan greaterThanEqual " +
+                    "equal notEqual any all not " +
+                    "texture1D texture1DProj texture1DLod texture1DProjLod " +
+                    "texture2D texture2DProj texture2DLod texture2DProjLod " +
+                    "texture3D texture3DProj texture3DLod texture3DProjLod " +
+                    "textureCube textureCubeLod " +
+                    "shadow1D shadow2D shadow1DProj shadow2DProj " +
+                    "shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " +
+                    "dFdx dFdy fwidth " +
+                    "noise1 noise2 noise3 noise4"),
+    atoms: words("true false " +
+                "gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
+                "gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
+                "gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
+                "gl_FogCoord " +
+                "gl_Position gl_PointSize gl_ClipVertex " +
+                "gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
+                "gl_TexCoord gl_FogFragCoord " +
+                "gl_FragCoord gl_FrontFacing " +
+                "gl_FragColor gl_FragData gl_FragDepth " +
+                "gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
+                "gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
+                "gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
+                "gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
+                "gl_ProjectionMatrixInverseTranspose " +
+                "gl_ModelViewProjectionMatrixInverseTranspose " +
+                "gl_TextureMatrixInverseTranspose " +
+                "gl_NormalScale gl_DepthRange gl_ClipPlane " +
+                "gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " +
+                "gl_FrontLightModelProduct gl_BackLightModelProduct " +
+                "gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " +
+                "gl_FogParameters " +
+                "gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " +
+                "gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " +
+                "gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
+                "gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
+                "gl_MaxDrawBuffers"),
+    hooks: {"#": cppHook},
+    modeProps: {fold: ["brace", "include"]}
+  });
+}());
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/clike/index.html b/app/gui/html/vendor/codemirror/mode/clike/index.html
new file mode 100644
index 0000000..d892fdd
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/clike/index.html
@@ -0,0 +1,200 @@
+<!doctype html>
+
+<title>CodeMirror: C-like mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="clike.js"></script>
+<style>.CodeMirror {border: 2px inset #dee;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">C-like</a>
+  </ul>
+</div>
+
+<article>
+<h2>C-like mode</h2>
+
+<div><textarea id="c-code">
+/* C demo code */
+
+#include <zmq.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <time.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <malloc.h>
+
+typedef struct {
+  void* arg_socket;
+  zmq_msg_t* arg_msg;
+  char* arg_string;
+  unsigned long arg_len;
+  int arg_int, arg_command;
+
+  int signal_fd;
+  int pad;
+  void* context;
+  sem_t sem;
+} acl_zmq_context;
+
+#define p(X) (context->arg_##X)
+
+void* zmq_thread(void* context_pointer) {
+  acl_zmq_context* context = (acl_zmq_context*)context_pointer;
+  char ok = 'K', err = 'X';
+  int res;
+
+  while (1) {
+    while ((res = sem_wait(&context->sem)) == EINTR);
+    if (res) {write(context->signal_fd, &err, 1); goto cleanup;}
+    switch(p(command)) {
+    case 0: goto cleanup;
+    case 1: p(socket) = zmq_socket(context->context, p(int)); break;
+    case 2: p(int) = zmq_close(p(socket)); break;
+    case 3: p(int) = zmq_bind(p(socket), p(string)); break;
+    case 4: p(int) = zmq_connect(p(socket), p(string)); break;
+    case 5: p(int) = zmq_getsockopt(p(socket), p(int), (void*)p(string), &p(len)); break;
+    case 6: p(int) = zmq_setsockopt(p(socket), p(int), (void*)p(string), p(len)); break;
+    case 7: p(int) = zmq_send(p(socket), p(msg), p(int)); break;
+    case 8: p(int) = zmq_recv(p(socket), p(msg), p(int)); break;
+    case 9: p(int) = zmq_poll(p(socket), p(int), p(len)); break;
+    }
+    p(command) = errno;
+    write(context->signal_fd, &ok, 1);
+  }
+ cleanup:
+  close(context->signal_fd);
+  free(context_pointer);
+  return 0;
+}
+
+void* zmq_thread_init(void* zmq_context, int signal_fd) {
+  acl_zmq_context* context = malloc(sizeof(acl_zmq_context));
+  pthread_t thread;
+
+  context->context = zmq_context;
+  context->signal_fd = signal_fd;
+  sem_init(&context->sem, 1, 0);
+  pthread_create(&thread, 0, &zmq_thread, context);
+  pthread_detach(thread);
+  return context;
+}
+</textarea></div>
+
+<h2>C++ example</h2>
+
+<div><textarea id="cpp-code">
+#include <iostream>
+#include "mystuff/util.h"
+
+namespace {
+enum Enum {
+  VAL1, VAL2, VAL3
+};
+
+char32_t unicode_string = U"\U0010FFFF";
+string raw_string = R"delim(anything
+you
+want)delim";
+
+int Helper(const MyType& param) {
+  return 0;
+}
+} // namespace
+
+class ForwardDec;
+
+template <class T, class V>
+class Class : public BaseClass {
+  const MyType<T, V> member_;
+
+ public:
+  const MyType<T, V>& Method() const {
+    return member_;
+  }
+
+  void Method2(MyType<T, V>* value);
+}
+
+template <class T, class V>
+void Class::Method2(MyType<T, V>* value) {
+  std::out << 1 >> method();
+  value->Method3(member_);
+  member_ = value;
+}
+</textarea></div>
+
+<h2>Java example</h2>
+
+<div><textarea id="java-code">
+import com.demo.util.MyType;
+import com.demo.util.MyInterface;
+
+public enum Enum {
+  VAL1, VAL2, VAL3
+}
+
+public class Class<T, V> implements MyInterface {
+  public static final MyType<T, V> member;
+  
+  private class InnerClass {
+    public int zero() {
+      return 0;
+    }
+  }
+
+  @Override
+  public MyType method() {
+    return member;
+  }
+
+  public void method2(MyType<T, V> value) {
+    method();
+    value.method3();
+    member = value;
+  }
+}
+</textarea></div>
+
+    <script>
+      var cEditor = CodeMirror.fromTextArea(document.getElementById("c-code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        mode: "text/x-csrc"
+      });
+      var cppEditor = CodeMirror.fromTextArea(document.getElementById("cpp-code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        mode: "text/x-c++src"
+      });
+      var javaEditor = CodeMirror.fromTextArea(document.getElementById("java-code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        mode: "text/x-java"
+      });
+    </script>
+
+    <p>Simple mode that tries to handle C-like languages as well as it
+    can. Takes two configuration parameters: <code>keywords</code>, an
+    object whose property names are the keywords in the language,
+    and <code>useCPP</code>, which determines whether C preprocessor
+    directives are recognized.</p>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-csrc</code>
+    (C code), <code>text/x-c++src</code> (C++
+    code), <code>text/x-java</code> (Java
+    code), <code>text/x-csharp</code> (C#).</p>
+</article>
diff --git a/app/gui/html/vendor/codemirror/mode/clike/scala.html b/app/gui/html/vendor/codemirror/mode/clike/scala.html
new file mode 100644
index 0000000..e9acc04
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/clike/scala.html
@@ -0,0 +1,767 @@
+<!doctype html>
+
+<title>CodeMirror: Scala mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link rel="stylesheet" href="../../theme/ambiance.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="clike.js"></script>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Scala</a>
+  </ul>
+</div>
+
+<article>
+<h2>Scala mode</h2>
+<form>
+<textarea id="code" name="code">
+
+  /*                     __                                               *\
+  **     ________ ___   / /  ___     Scala API                            **
+  **    / __/ __// _ | / /  / _ |    (c) 2003-2011, LAMP/EPFL             **
+  **  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
+  ** /____/\___/_/ |_/____/_/ | |                                         **
+  **                          |/                                          **
+  \*                                                                      */
+
+  package scala.collection
+
+  import generic._
+  import mutable.{ Builder, ListBuffer }
+  import annotation.{tailrec, migration, bridge}
+  import annotation.unchecked.{ uncheckedVariance => uV }
+  import parallel.ParIterable
+
+  /** A template trait for traversable collections of type `Traversable[A]`.
+   *  
+   *  $traversableInfo
+   *  @define mutability
+   *  @define traversableInfo
+   *  This is a base trait of all kinds of $mutability Scala collections. It
+   *  implements the behavior common to all collections, in terms of a method
+   *  `foreach` with signature:
+   * {{{
+   *     def foreach[U](f: Elem => U): Unit
+   * }}}
+   *  Collection classes mixing in this trait provide a concrete 
+   *  `foreach` method which traverses all the
+   *  elements contained in the collection, applying a given function to each.
+   *  They also need to provide a method `newBuilder`
+   *  which creates a builder for collections of the same kind.
+   *  
+   *  A traversable class might or might not have two properties: strictness
+   *  and orderedness. Neither is represented as a type.
+   *  
+   *  The instances of a strict collection class have all their elements
+   *  computed before they can be used as values. By contrast, instances of
+   *  a non-strict collection class may defer computation of some of their
+   *  elements until after the instance is available as a value.
+   *  A typical example of a non-strict collection class is a
+   *  <a href="../immutable/Stream.html" target="ContentFrame">
+   *  `scala.collection.immutable.Stream`</a>.
+   *  A more general class of examples are `TraversableViews`.
+   *  
+   *  If a collection is an instance of an ordered collection class, traversing
+   *  its elements with `foreach` will always visit elements in the
+   *  same order, even for different runs of the program. If the class is not
+   *  ordered, `foreach` can visit elements in different orders for
+   *  different runs (but it will keep the same order in the same run).'
+   * 
+   *  A typical example of a collection class which is not ordered is a
+   *  `HashMap` of objects. The traversal order for hash maps will
+   *  depend on the hash codes of its elements, and these hash codes might
+   *  differ from one run to the next. By contrast, a `LinkedHashMap`
+   *  is ordered because it's `foreach` method visits elements in the
+   *  order they were inserted into the `HashMap`.
+   *
+   *  @author Martin Odersky
+   *  @version 2.8
+   *  @since   2.8
+   *  @tparam A    the element type of the collection
+   *  @tparam Repr the type of the actual collection containing the elements.
+   *
+   *  @define Coll Traversable
+   *  @define coll traversable collection
+   */
+  trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr] 
+                                      with FilterMonadic[A, Repr]
+                                      with TraversableOnce[A]
+                                      with GenTraversableLike[A, Repr]
+                                      with Parallelizable[A, ParIterable[A]]
+  {
+    self =>
+
+    import Traversable.breaks._
+
+    /** The type implementing this traversable */
+    protected type Self = Repr
+
+    /** The collection of type $coll underlying this `TraversableLike` object.
+     *  By default this is implemented as the `TraversableLike` object itself,
+     *  but this can be overridden.
+     */
+    def repr: Repr = this.asInstanceOf[Repr]
+
+    /** The underlying collection seen as an instance of `$Coll`.
+     *  By default this is implemented as the current collection object itself,
+     *  but this can be overridden.
+     */
+    protected[this] def thisCollection: Traversable[A] = this.asInstanceOf[Traversable[A]]
+
+    /** A conversion from collections of type `Repr` to `$Coll` objects.
+     *  By default this is implemented as just a cast, but this can be overridden.
+     */
+    protected[this] def toCollection(repr: Repr): Traversable[A] = repr.asInstanceOf[Traversable[A]]
+
+    /** Creates a new builder for this collection type.
+     */
+    protected[this] def newBuilder: Builder[A, Repr]
+
+    protected[this] def parCombiner = ParIterable.newCombiner[A]
+
+    /** Applies a function `f` to all elements of this $coll.
+     *  
+     *    Note: this method underlies the implementation of most other bulk operations.
+     *    It's important to implement this method in an efficient way.
+     *  
+     *
+     *  @param  f   the function that is applied for its side-effect to every element.
+     *              The result of function `f` is discarded.
+     *              
+     *  @tparam  U  the type parameter describing the result of function `f`. 
+     *              This result will always be ignored. Typically `U` is `Unit`,
+     *              but this is not necessary.
+     *
+     *  @usecase def foreach(f: A => Unit): Unit
+     */
+    def foreach[U](f: A => U): Unit
+
+    /** Tests whether this $coll is empty.
+     *
+     *  @return    `true` if the $coll contain no elements, `false` otherwise.
+     */
+    def isEmpty: Boolean = {
+      var result = true
+      breakable {
+        for (x <- this) {
+          result = false
+          break
+        }
+      }
+      result
+    }
+
+    /** Tests whether this $coll is known to have a finite size.
+     *  All strict collections are known to have finite size. For a non-strict collection
+     *  such as `Stream`, the predicate returns `true` if all elements have been computed.
+     *  It returns `false` if the stream is not yet evaluated to the end.
+     *
+     *  Note: many collection methods will not work on collections of infinite sizes. 
+     *
+     *  @return  `true` if this collection is known to have finite size, `false` otherwise.
+     */
+    def hasDefiniteSize = true
+
+    def ++[B >: A, That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+      val b = bf(repr)
+      if (that.isInstanceOf[IndexedSeqLike[_, _]]) b.sizeHint(this, that.seq.size)
+      b ++= thisCollection
+      b ++= that.seq
+      b.result
+    }
+
+    @bridge
+    def ++[B >: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That =
+      ++(that: GenTraversableOnce[B])(bf)
+
+    /** Concatenates this $coll with the elements of a traversable collection.
+     *  It differs from ++ in that the right operand determines the type of the
+     *  resulting collection rather than the left one.
+     * 
+     *  @param that   the traversable to append.
+     *  @tparam B     the element type of the returned collection. 
+     *  @tparam That  $thatinfo
+     *  @param bf     $bfinfo
+     *  @return       a new collection of type `That` which contains all elements
+     *                of this $coll followed by all elements of `that`.
+     * 
+     *  @usecase def ++:[B](that: TraversableOnce[B]): $Coll[B]
+     *  
+     *  @return       a new $coll which contains all elements of this $coll
+     *                followed by all elements of `that`.
+     */
+    def ++:[B >: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+      val b = bf(repr)
+      if (that.isInstanceOf[IndexedSeqLike[_, _]]) b.sizeHint(this, that.size)
+      b ++= that
+      b ++= thisCollection
+      b.result
+    }
+
+    /** This overload exists because: for the implementation of ++: we should reuse
+     *  that of ++ because many collections override it with more efficient versions.
+     *  Since TraversableOnce has no '++' method, we have to implement that directly,
+     *  but Traversable and down can use the overload.
+     */
+    def ++:[B >: A, That](that: Traversable[B])(implicit bf: CanBuildFrom[Repr, B, That]): That =
+      (that ++ seq)(breakOut)
+
+    def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+      val b = bf(repr)
+      b.sizeHint(this) 
+      for (x <- this) b += f(x)
+      b.result
+    }
+
+    def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+      val b = bf(repr)
+      for (x <- this) b ++= f(x).seq
+      b.result
+    }
+
+    /** Selects all elements of this $coll which satisfy a predicate.
+     *
+     *  @param p     the predicate used to test elements.
+     *  @return      a new $coll consisting of all elements of this $coll that satisfy the given
+     *               predicate `p`. The order of the elements is preserved.
+     */
+    def filter(p: A => Boolean): Repr = {
+      val b = newBuilder
+      for (x <- this) 
+        if (p(x)) b += x
+      b.result
+    }
+
+    /** Selects all elements of this $coll which do not satisfy a predicate.
+     *
+     *  @param p     the predicate used to test elements.
+     *  @return      a new $coll consisting of all elements of this $coll that do not satisfy the given
+     *               predicate `p`. The order of the elements is preserved.
+     */
+    def filterNot(p: A => Boolean): Repr = filter(!p(_))
+
+    def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+      val b = bf(repr)
+      for (x <- this) if (pf.isDefinedAt(x)) b += pf(x)
+      b.result
+    }
+
+    /** Builds a new collection by applying an option-valued function to all
+     *  elements of this $coll on which the function is defined.
+     *
+     *  @param f      the option-valued function which filters and maps the $coll.
+     *  @tparam B     the element type of the returned collection.
+     *  @tparam That  $thatinfo
+     *  @param bf     $bfinfo
+     *  @return       a new collection of type `That` resulting from applying the option-valued function
+     *                `f` to each element and collecting all defined results.
+     *                The order of the elements is preserved.
+     *
+     *  @usecase def filterMap[B](f: A => Option[B]): $Coll[B]
+     *  
+     *  @param pf     the partial function which filters and maps the $coll.
+     *  @return       a new $coll resulting from applying the given option-valued function
+     *                `f` to each element and collecting all defined results.
+     *                The order of the elements is preserved.
+    def filterMap[B, That](f: A => Option[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+      val b = bf(repr)
+      for (x <- this) 
+        f(x) match {
+          case Some(y) => b += y
+          case _ =>
+        }
+      b.result
+    }
+     */
+
+    /** Partitions this $coll in two ${coll}s according to a predicate.
+     *
+     *  @param p the predicate on which to partition.
+     *  @return  a pair of ${coll}s: the first $coll consists of all elements that 
+     *           satisfy the predicate `p` and the second $coll consists of all elements
+     *           that don't. The relative order of the elements in the resulting ${coll}s
+     *           is the same as in the original $coll.
+     */
+    def partition(p: A => Boolean): (Repr, Repr) = {
+      val l, r = newBuilder
+      for (x <- this) (if (p(x)) l else r) += x
+      (l.result, r.result)
+    }
+
+    def groupBy[K](f: A => K): immutable.Map[K, Repr] = {
+      val m = mutable.Map.empty[K, Builder[A, Repr]]
+      for (elem <- this) {
+        val key = f(elem)
+        val bldr = m.getOrElseUpdate(key, newBuilder)
+        bldr += elem
+      }
+      val b = immutable.Map.newBuilder[K, Repr]
+      for ((k, v) <- m)
+        b += ((k, v.result))
+
+      b.result
+    }
+
+    /** Tests whether a predicate holds for all elements of this $coll.
+     *
+     *  $mayNotTerminateInf
+     *
+     *  @param   p     the predicate used to test elements.
+     *  @return        `true` if the given predicate `p` holds for all elements
+     *                 of this $coll, otherwise `false`.
+     */
+    def forall(p: A => Boolean): Boolean = {
+      var result = true
+      breakable {
+        for (x <- this)
+          if (!p(x)) { result = false; break }
+      }
+      result
+    }
+
+    /** Tests whether a predicate holds for some of the elements of this $coll.
+     *
+     *  $mayNotTerminateInf
+     *
+     *  @param   p     the predicate used to test elements.
+     *  @return        `true` if the given predicate `p` holds for some of the
+     *                 elements of this $coll, otherwise `false`.
+     */
+    def exists(p: A => Boolean): Boolean = {
+      var result = false
+      breakable {
+        for (x <- this)
+          if (p(x)) { result = true; break }
+      }
+      result
+    }
+
+    /** Finds the first element of the $coll satisfying a predicate, if any.
+     * 
+     *  $mayNotTerminateInf
+     *  $orderDependent
+     *
+     *  @param p    the predicate used to test elements.
+     *  @return     an option value containing the first element in the $coll
+     *              that satisfies `p`, or `None` if none exists.
+     */
+    def find(p: A => Boolean): Option[A] = {
+      var result: Option[A] = None
+      breakable {
+        for (x <- this)
+          if (p(x)) { result = Some(x); break }
+      }
+      result
+    }
+
+    def scan[B >: A, That](z: B)(op: (B, B) => B)(implicit cbf: CanBuildFrom[Repr, B, That]): That = scanLeft(z)(op)
+
+    def scanLeft[B, That](z: B)(op: (B, A) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+      val b = bf(repr)
+      b.sizeHint(this, 1)
+      var acc = z
+      b += acc
+      for (x <- this) { acc = op(acc, x); b += acc }
+      b.result
+    }
+
+    @migration(2, 9,
+      "This scanRight definition has changed in 2.9.\n" +
+      "The previous behavior can be reproduced with scanRight.reverse."
+    )
+    def scanRight[B, That](z: B)(op: (A, B) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+      var scanned = List(z)
+      var acc = z
+      for (x <- reversed) {
+        acc = op(x, acc)
+        scanned ::= acc
+      }
+      val b = bf(repr)
+      for (elem <- scanned) b += elem
+      b.result
+    }
+
+    /** Selects the first element of this $coll.
+     *  $orderDependent
+     *  @return  the first element of this $coll.
+     *  @throws `NoSuchElementException` if the $coll is empty.
+     */
+    def head: A = {
+      var result: () => A = () => throw new NoSuchElementException
+      breakable {
+        for (x <- this) {
+          result = () => x
+          break
+        }
+      }
+      result()
+    }
+
+    /** Optionally selects the first element.
+     *  $orderDependent
+     *  @return  the first element of this $coll if it is nonempty, `None` if it is empty.
+     */
+    def headOption: Option[A] = if (isEmpty) None else Some(head)
+
+    /** Selects all elements except the first.
+     *  $orderDependent
+     *  @return  a $coll consisting of all elements of this $coll
+     *           except the first one.
+     *  @throws `UnsupportedOperationException` if the $coll is empty.
+     */ 
+    override def tail: Repr = {
+      if (isEmpty) throw new UnsupportedOperationException("empty.tail")
+      drop(1)
+    }
+
+    /** Selects the last element.
+      * $orderDependent
+      * @return The last element of this $coll.
+      * @throws NoSuchElementException If the $coll is empty.
+      */
+    def last: A = {
+      var lst = head
+      for (x <- this)
+        lst = x
+      lst
+    }
+
+    /** Optionally selects the last element.
+     *  $orderDependent
+     *  @return  the last element of this $coll$ if it is nonempty, `None` if it is empty.
+     */
+    def lastOption: Option[A] = if (isEmpty) None else Some(last)
+
+    /** Selects all elements except the last.
+     *  $orderDependent
+     *  @return  a $coll consisting of all elements of this $coll
+     *           except the last one.
+     *  @throws `UnsupportedOperationException` if the $coll is empty.
+     */
+    def init: Repr = {
+      if (isEmpty) throw new UnsupportedOperationException("empty.init")
+      var lst = head
+      var follow = false
+      val b = newBuilder
+      b.sizeHint(this, -1)
+      for (x <- this.seq) {
+        if (follow) b += lst
+        else follow = true
+        lst = x
+      }
+      b.result
+    }
+
+    def take(n: Int): Repr = slice(0, n)
+
+    def drop(n: Int): Repr = 
+      if (n <= 0) {
+        val b = newBuilder
+        b.sizeHint(this)
+        b ++= thisCollection result
+      }
+      else sliceWithKnownDelta(n, Int.MaxValue, -n)
+
+    def slice(from: Int, until: Int): Repr = sliceWithKnownBound(math.max(from, 0), until)
+
+    // Precondition: from >= 0, until > 0, builder already configured for building.
+    private[this] def sliceInternal(from: Int, until: Int, b: Builder[A, Repr]): Repr = {
+      var i = 0
+      breakable {
+        for (x <- this.seq) {
+          if (i >= from) b += x
+          i += 1
+          if (i >= until) break
+        }
+      }
+      b.result
+    }
+    // Precondition: from >= 0
+    private[scala] def sliceWithKnownDelta(from: Int, until: Int, delta: Int): Repr = {
+      val b = newBuilder
+      if (until <= from) b.result
+      else {
+        b.sizeHint(this, delta)
+        sliceInternal(from, until, b)
+      }
+    }
+    // Precondition: from >= 0
+    private[scala] def sliceWithKnownBound(from: Int, until: Int): Repr = {
+      val b = newBuilder
+      if (until <= from) b.result
+      else {
+        b.sizeHintBounded(until - from, this)      
+        sliceInternal(from, until, b)
+      }
+    }
+
+    def takeWhile(p: A => Boolean): Repr = {
+      val b = newBuilder
+      breakable {
+        for (x <- this) {
+          if (!p(x)) break
+          b += x
+        }
+      }
+      b.result
+    }
+
+    def dropWhile(p: A => Boolean): Repr = {
+      val b = newBuilder
+      var go = false
+      for (x <- this) {
+        if (!p(x)) go = true
+        if (go) b += x
+      }
+      b.result
+    }
+
+    def span(p: A => Boolean): (Repr, Repr) = {
+      val l, r = newBuilder
+      var toLeft = true
+      for (x <- this) {
+        toLeft = toLeft && p(x)
+        (if (toLeft) l else r) += x
+      }
+      (l.result, r.result)
+    }
+
+    def splitAt(n: Int): (Repr, Repr) = {
+      val l, r = newBuilder
+      l.sizeHintBounded(n, this)
+      if (n >= 0) r.sizeHint(this, -n)
+      var i = 0
+      for (x <- this) {
+        (if (i < n) l else r) += x
+        i += 1
+      }
+      (l.result, r.result)
+    }
+
+    /** Iterates over the tails of this $coll. The first value will be this
+     *  $coll and the final one will be an empty $coll, with the intervening
+     *  values the results of successive applications of `tail`.
+     *
+     *  @return   an iterator over all the tails of this $coll
+     *  @example  `List(1,2,3).tails = Iterator(List(1,2,3), List(2,3), List(3), Nil)`
+     */  
+    def tails: Iterator[Repr] = iterateUntilEmpty(_.tail)
+
+    /** Iterates over the inits of this $coll. The first value will be this
+     *  $coll and the final one will be an empty $coll, with the intervening
+     *  values the results of successive applications of `init`.
+     *
+     *  @return  an iterator over all the inits of this $coll
+     *  @example  `List(1,2,3).inits = Iterator(List(1,2,3), List(1,2), List(1), Nil)`
+     */
+    def inits: Iterator[Repr] = iterateUntilEmpty(_.init)
+
+    /** Copies elements of this $coll to an array.
+     *  Fills the given array `xs` with at most `len` elements of
+     *  this $coll, starting at position `start`.
+     *  Copying will stop once either the end of the current $coll is reached,
+     *  or the end of the array is reached, or `len` elements have been copied.
+     *
+     *  $willNotTerminateInf
+     * 
+     *  @param  xs     the array to fill.
+     *  @param  start  the starting index.
+     *  @param  len    the maximal number of elements to copy.
+     *  @tparam B      the type of the elements of the array. 
+     * 
+     *
+     *  @usecase def copyToArray(xs: Array[A], start: Int, len: Int): Unit
+     */
+    def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) {
+      var i = start
+      val end = (start + len) min xs.length
+      breakable {
+        for (x <- this) {
+          if (i >= end) break
+          xs(i) = x
+          i += 1
+        }
+      }
+    }
+
+    def toTraversable: Traversable[A] = thisCollection
+    def toIterator: Iterator[A] = toStream.iterator
+    def toStream: Stream[A] = toBuffer.toStream
+
+    /** Converts this $coll to a string.
+     *
+     *  @return   a string representation of this collection. By default this
+     *            string consists of the `stringPrefix` of this $coll,
+     *            followed by all elements separated by commas and enclosed in parentheses.
+     */
+    override def toString = mkString(stringPrefix + "(", ", ", ")")
+
+    /** Defines the prefix of this object's `toString` representation.
+     *
+     *  @return  a string representation which starts the result of `toString`
+     *           applied to this $coll. By default the string prefix is the
+     *           simple name of the collection class $coll.
+     */
+    def stringPrefix : String = {
+      var string = repr.asInstanceOf[AnyRef].getClass.getName
+      val idx1 = string.lastIndexOf('.' : Int)
+      if (idx1 != -1) string = string.substring(idx1 + 1)
+      val idx2 = string.indexOf('$')
+      if (idx2 != -1) string = string.substring(0, idx2)
+      string
+    }
+
+    /** Creates a non-strict view of this $coll.
+     * 
+     *  @return a non-strict view of this $coll.
+     */
+    def view = new TraversableView[A, Repr] {
+      protected lazy val underlying = self.repr
+      override def foreach[U](f: A => U) = self foreach f
+    }
+
+    /** Creates a non-strict view of a slice of this $coll.
+     *
+     *  Note: the difference between `view` and `slice` is that `view` produces
+     *        a view of the current $coll, whereas `slice` produces a new $coll.
+     * 
+     *  Note: `view(from, to)` is equivalent to `view.slice(from, to)`
+     *  $orderDependent
+     * 
+     *  @param from   the index of the first element of the view
+     *  @param until  the index of the element following the view
+     *  @return a non-strict view of a slice of this $coll, starting at index `from`
+     *  and extending up to (but not including) index `until`.
+     */
+    def view(from: Int, until: Int): TraversableView[A, Repr] = view.slice(from, until)
+
+    /** Creates a non-strict filter of this $coll.
+     *
+     *  Note: the difference between `c filter p` and `c withFilter p` is that
+     *        the former creates a new collection, whereas the latter only
+     *        restricts the domain of subsequent `map`, `flatMap`, `foreach`,
+     *        and `withFilter` operations.
+     *  $orderDependent
+     * 
+     *  @param p   the predicate used to test elements.
+     *  @return    an object of class `WithFilter`, which supports
+     *             `map`, `flatMap`, `foreach`, and `withFilter` operations.
+     *             All these operations apply to those elements of this $coll which
+     *             satisfy the predicate `p`.
+     */
+    def withFilter(p: A => Boolean): FilterMonadic[A, Repr] = new WithFilter(p)
+
+    /** A class supporting filtered operations. Instances of this class are
+     *  returned by method `withFilter`.
+     */
+    class WithFilter(p: A => Boolean) extends FilterMonadic[A, Repr] {
+
+      /** Builds a new collection by applying a function to all elements of the
+       *  outer $coll containing this `WithFilter` instance that satisfy predicate `p`.
+       *
+       *  @param f      the function to apply to each element.
+       *  @tparam B     the element type of the returned collection.
+       *  @tparam That  $thatinfo
+       *  @param bf     $bfinfo
+       *  @return       a new collection of type `That` resulting from applying
+       *                the given function `f` to each element of the outer $coll
+       *                that satisfies predicate `p` and collecting the results.
+       *
+       *  @usecase def map[B](f: A => B): $Coll[B] 
+       *  
+       *  @return       a new $coll resulting from applying the given function
+       *                `f` to each element of the outer $coll that satisfies
+       *                predicate `p` and collecting the results.
+       */
+      def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+        val b = bf(repr)
+        for (x <- self) 
+          if (p(x)) b += f(x)
+        b.result
+      }
+
+      /** Builds a new collection by applying a function to all elements of the
+       *  outer $coll containing this `WithFilter` instance that satisfy
+       *  predicate `p` and concatenating the results. 
+       *
+       *  @param f      the function to apply to each element.
+       *  @tparam B     the element type of the returned collection.
+       *  @tparam That  $thatinfo
+       *  @param bf     $bfinfo
+       *  @return       a new collection of type `That` resulting from applying
+       *                the given collection-valued function `f` to each element
+       *                of the outer $coll that satisfies predicate `p` and
+       *                concatenating the results.
+       *
+       *  @usecase def flatMap[B](f: A => TraversableOnce[B]): $Coll[B]
+       * 
+       *  @return       a new $coll resulting from applying the given collection-valued function
+       *                `f` to each element of the outer $coll that satisfies predicate `p` and concatenating the results.
+       */
+      def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+        val b = bf(repr)
+        for (x <- self) 
+          if (p(x)) b ++= f(x).seq
+        b.result
+      }
+
+      /** Applies a function `f` to all elements of the outer $coll containing
+       *  this `WithFilter` instance that satisfy predicate `p`.
+       *
+       *  @param  f   the function that is applied for its side-effect to every element.
+       *              The result of function `f` is discarded.
+       *              
+       *  @tparam  U  the type parameter describing the result of function `f`. 
+       *              This result will always be ignored. Typically `U` is `Unit`,
+       *              but this is not necessary.
+       *
+       *  @usecase def foreach(f: A => Unit): Unit
+       */   
+      def foreach[U](f: A => U): Unit = 
+        for (x <- self) 
+          if (p(x)) f(x)
+
+      /** Further refines the filter for this $coll.
+       *
+       *  @param q   the predicate used to test elements.
+       *  @return    an object of class `WithFilter`, which supports
+       *             `map`, `flatMap`, `foreach`, and `withFilter` operations.
+       *             All these operations apply to those elements of this $coll which
+       *             satisfy the predicate `q` in addition to the predicate `p`.
+       */
+      def withFilter(q: A => Boolean): WithFilter = 
+        new WithFilter(x => p(x) && q(x))
+    }
+
+    // A helper for tails and inits.
+    private def iterateUntilEmpty(f: Traversable[A @uV] => Traversable[A @uV]): Iterator[Repr] = {
+      val it = Iterator.iterate(thisCollection)(f) takeWhile (x => !x.isEmpty)
+      it ++ Iterator(Nil) map (newBuilder ++= _ result)
+    }
+  }
+
+
+</textarea>
+</form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        theme: "ambiance",
+        mode: "text/x-scala"
+      });
+    </script>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/clojure/clojure.js b/app/gui/html/vendor/codemirror/mode/clojure/clojure.js
new file mode 100644
index 0000000..3b596ad
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/clojure/clojure.js
@@ -0,0 +1,238 @@
+/**
+ * Author: Hans Engel
+ * Branched from CodeMirror's Scheme mode (by Koh Zi Han, based on implementation by Koh Zi Chun)
+ */
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("clojure", function (options) {
+    var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", CHARACTER = "string-2",
+        ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD = "keyword";
+    var INDENT_WORD_SKIP = options.indentUnit || 2;
+    var NORMAL_INDENT_UNIT = options.indentUnit || 2;
+
+    function makeKeywords(str) {
+        var obj = {}, words = str.split(" ");
+        for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+        return obj;
+    }
+
+    var atoms = makeKeywords("true false nil");
+
+    var keywords = makeKeywords(
+      "defn defn- def def- defonce defmulti defmethod defmacro defstruct deftype defprotocol defrecord defproject deftest slice defalias defhinted defmacro- defn-memo defnk defnk defonce- defunbound defunbound- defvar defvar- let letfn do case cond condp for loop recur when when-not when-let when-first if if-let if-not . .. -> ->> doto and or dosync doseq dotimes dorun doall load import unimport ns in-ns refer try catch finally throw with-open with-local-vars binding gen-class gen-and-load-class gen-and-save-class handler-case handle");
+
+    var builtins = makeKeywords(
+        "* *' *1 *2 *3 *agent* *allow-unresolved-vars* *assert* *clojure-version* *command-line-args* *compile-files* *compile-path* *compiler-options* *data-readers* *e *err* *file* *flush-on-newline* *fn-loader* *in* *math-context* *ns* *out* *print-dup* *print-length* *print-level* *print-meta* *print-readably* *read-eval* *source-path* *unchecked-math* *use-context-classloader* *verbose-defrecords* *warn-on-reflection* + +' - -' -> ->> ->ArrayChunk ->Vec ->VecNode ->VecSeq -cache-protocol-fn -reset-methods .. / < <= = == > >= EMPTY-NODE accessor aclone add-classpath add-watch agent agent-error agent-errors aget alength alias all-ns alter alter-meta! alter-var-root amap ancestors and apply areduce array-map aset aset-boolean aset-byte aset-char aset-double aset-float aset-int aset-long aset-short assert assoc assoc! assoc-in associative? atom await await-for await1 bases bean bigdec bigint biginteger binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array booleans bound-fn bound-fn* bound? butlast byte byte-array bytes case cast char char-array char-escape-string char-name-string char? chars chunk chunk-append chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? class class? clear-agent-errors clojure-version coll? comment commute comp comparator compare compare-and-set! compile complement concat cond condp conj conj! cons constantly construct-proxy contains? count counted? create-ns create-struct cycle dec dec' decimal? declare default-data-readers definline definterface defmacro defmethod defmulti defn defn- defonce defprotocol defrecord defstruct deftype delay delay? deliver denominator deref derive descendants destructure disj disj! dissoc dissoc! distinct distinct? doall dorun doseq dosync dotimes doto double double-array doubles drop drop-last drop-while empty empty? ensure enumeration-seq error-handler error-mode eval even? every-pred every? ex-data ex-info extend extend-protocol extend-type extenders extends? false? ffirst file-seq filter filterv find find-keyword find-ns find-protocol-impl find-protocol-method find-var first flatten float float-array float? floats flush fn fn? fnext fnil for force format frequencies future future-call future-cancel future-cancelled? future-done? future? gen-class gen-interface gensym get get-in get-method get-proxy-class get-thread-bindings get-validator group-by hash hash-combine hash-map hash-set identical? identity if-let if-not ifn? import in-ns inc inc' init-proxy instance? int int-array integer? interleave intern interpose into into-array ints io! isa? iterate iterator-seq juxt keep keep-indexed key keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list list* list? load load-file load-reader load-string loaded-libs locking long long-array longs loop macroexpand macroexpand-1 make-array make-hierarchy map map-indexed map? mapcat mapv max max-key memfn memoize merge merge-with meta method-sig methods min min-key mod munge name namespace namespace-munge neg? newline next nfirst nil? nnext not not-any? not-empty not-every? not= ns ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers ns-resolve ns-unalias ns-unmap nth nthnext nthrest num number? numerator object-array odd? or parents partial partition partition-all partition-by pcalls peek persistent! pmap pop pop! pop-thread-bindings pos? pr pr-str prefer-method prefers primitives-classnames print print-ctor print-dup print-method print-simple print-str printf println println-str prn prn-str promise proxy proxy-call-with-super proxy-mappings proxy-name proxy-super push-thread-bindings pvalues quot rand rand-int rand-nth range ratio? rational? rationalize re-find re-groups re-matcher re-matches re-pattern re-seq read read-line read-string realized? reduce reduce-kv reductions ref ref-history-count ref-max-history ref-min-history ref-set refer refer-clojure reify release-pending-sends rem remove remove-all-methods remove-method remove-ns remove-watch repeat repeatedly replace replicate require reset! reset-meta! resolve rest restart-agent resultset-seq reverse reversible? rseq rsubseq satisfies? second select-keys send send-off seq seq? seque sequence sequential? set set-error-handler! set-error-mode! set-validator! set? short short-array shorts shuffle shutdown-agents slurp some some-fn sort sort-by sorted-map sorted-map-by sorted-set sorted-set-by sorted? special-symbol? spit split-at split-with str string? struct struct-map subs subseq subvec supers swap! symbol symbol? sync take take-last take-nth take-while test the-ns thread-bound? time to-array to-array-2d trampoline transient tree-seq true? type unchecked-add unchecked-add-int unchecked-byte unchecked-char unchecked-dec unchecked-dec-int unchecked-divide-int unchecked-double unchecked-float unchecked-inc unchecked-inc-int unchecked-int unchecked-long unchecked-multiply unchecked-multiply-int unchecked-negate unchecked-negate-int unchecked-remainder-int unchecked-short unchecked-subtract unchecked-subtract-int underive unquote unquote-splicing update-in update-proxy use val vals var-get var-set var? vary-meta vec vector vector-of vector? when when-first when-let when-not while with-bindings with-bindings* with-in-str with-loading-context with-local-vars with-meta with-open with-out-str with-precision with-redefs with-redefs-fn xml-seq zero? zipmap *default-data-reader-fn* as-> cond-> cond->> reduced reduced? send-via set-agent-send-executor! set-agent-send-off-executor! some-> some->>");
+
+    var indentKeys = makeKeywords(
+        // Built-ins
+        "ns fn def defn defmethod bound-fn if if-not case condp when while when-not when-first do future comment doto locking proxy with-open with-precision reify deftype defrecord defprotocol extend extend-protocol extend-type try catch " +
+
+        // Binding forms
+        "let letfn binding loop for doseq dotimes when-let if-let " +
+
+        // Data structures
+        "defstruct struct-map assoc " +
+
+        // clojure.test
+        "testing deftest " +
+
+        // contrib
+        "handler-case handle dotrace deftrace");
+
+    var tests = {
+        digit: /\d/,
+        digit_or_colon: /[\d:]/,
+        hex: /[0-9a-f]/i,
+        sign: /[+-]/,
+        exponent: /e/i,
+        keyword_char: /[^\s\(\[\;\)\]]/,
+        symbol: /[\w*+!\-\._?:<>\/]/
+    };
+
+    function stateStack(indent, type, prev) { // represents a state stack object
+        this.indent = indent;
+        this.type = type;
+        this.prev = prev;
+    }
+
+    function pushStack(state, indent, type) {
+        state.indentStack = new stateStack(indent, type, state.indentStack);
+    }
+
+    function popStack(state) {
+        state.indentStack = state.indentStack.prev;
+    }
+
+    function isNumber(ch, stream){
+        // hex
+        if ( ch === '0' && stream.eat(/x/i) ) {
+            stream.eatWhile(tests.hex);
+            return true;
+        }
+
+        // leading sign
+        if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) {
+          stream.eat(tests.sign);
+          ch = stream.next();
+        }
+
+        if ( tests.digit.test(ch) ) {
+            stream.eat(ch);
+            stream.eatWhile(tests.digit);
+
+            if ( '.' == stream.peek() ) {
+                stream.eat('.');
+                stream.eatWhile(tests.digit);
+            }
+
+            if ( stream.eat(tests.exponent) ) {
+                stream.eat(tests.sign);
+                stream.eatWhile(tests.digit);
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    // Eat character that starts after backslash \
+    function eatCharacter(stream) {
+        var first = stream.next();
+        // Read special literals: backspace, newline, space, return.
+        // Just read all lowercase letters.
+        if (first.match(/[a-z]/) && stream.match(/[a-z]+/, true)) {
+            return;
+        }
+        // Read unicode character: \u1000 \uA0a1
+        if (first === "u") {
+            stream.match(/[0-9a-z]{4}/i, true);
+        }
+    }
+
+    return {
+        startState: function () {
+            return {
+                indentStack: null,
+                indentation: 0,
+                mode: false
+            };
+        },
+
+        token: function (stream, state) {
+            if (state.indentStack == null && stream.sol()) {
+                // update indentation, but only if indentStack is empty
+                state.indentation = stream.indentation();
+            }
+
+            // skip spaces
+            if (stream.eatSpace()) {
+                return null;
+            }
+            var returnType = null;
+
+            switch(state.mode){
+                case "string": // multi-line string parsing mode
+                    var next, escaped = false;
+                    while ((next = stream.next()) != null) {
+                        if (next == "\"" && !escaped) {
+
+                            state.mode = false;
+                            break;
+                        }
+                        escaped = !escaped && next == "\\";
+                    }
+                    returnType = STRING; // continue on in string mode
+                    break;
+                default: // default parsing mode
+                    var ch = stream.next();
+
+                    if (ch == "\"") {
+                        state.mode = "string";
+                        returnType = STRING;
+                    } else if (ch == "\\") {
+                        eatCharacter(stream);
+                        returnType = CHARACTER;
+                    } else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) {
+                        returnType = ATOM;
+                    } else if (ch == ";") { // comment
+                        stream.skipToEnd(); // rest of the line is a comment
+                        returnType = COMMENT;
+                    } else if (isNumber(ch,stream)){
+                        returnType = NUMBER;
+                    } else if (ch == "(" || ch == "[" || ch == "{" ) {
+                        var keyWord = '', indentTemp = stream.column(), letter;
+                        /**
+                        Either
+                        (indent-word ..
+                        (non-indent-word ..
+                        (;something else, bracket, etc.
+                        */
+
+                        if (ch == "(") while ((letter = stream.eat(tests.keyword_char)) != null) {
+                            keyWord += letter;
+                        }
+
+                        if (keyWord.length > 0 && (indentKeys.propertyIsEnumerable(keyWord) ||
+                                                   /^(?:def|with)/.test(keyWord))) { // indent-word
+                            pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);
+                        } else { // non-indent word
+                            // we continue eating the spaces
+                            stream.eatSpace();
+                            if (stream.eol() || stream.peek() == ";") {
+                                // nothing significant after
+                                // we restart indentation the user defined spaces after
+                                pushStack(state, indentTemp + NORMAL_INDENT_UNIT, ch);
+                            } else {
+                                pushStack(state, indentTemp + stream.current().length, ch); // else we match
+                            }
+                        }
+                        stream.backUp(stream.current().length - 1); // undo all the eating
+
+                        returnType = BRACKET;
+                    } else if (ch == ")" || ch == "]" || ch == "}") {
+                        returnType = BRACKET;
+                        if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : (ch == "]" ? "[" :"{"))) {
+                            popStack(state);
+                        }
+                    } else if ( ch == ":" ) {
+                        stream.eatWhile(tests.symbol);
+                        return ATOM;
+                    } else {
+                        stream.eatWhile(tests.symbol);
+
+                        if (keywords && keywords.propertyIsEnumerable(stream.current())) {
+                            returnType = KEYWORD;
+                        } else if (builtins && builtins.propertyIsEnumerable(stream.current())) {
+                            returnType = BUILTIN;
+                        } else if (atoms && atoms.propertyIsEnumerable(stream.current())) {
+                            returnType = ATOM;
+                        } else returnType = null;
+                    }
+            }
+
+            return returnType;
+        },
+
+        indent: function (state) {
+            if (state.indentStack == null) return state.indentation;
+            return state.indentStack.indent;
+        },
+
+        lineComment: ";;"
+    };
+});
+
+CodeMirror.defineMIME("text/x-clojure", "clojure");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/clojure/index.html b/app/gui/html/vendor/codemirror/mode/clojure/index.html
new file mode 100644
index 0000000..5a50c56
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/clojure/index.html
@@ -0,0 +1,88 @@
+<!doctype html>
+
+<title>CodeMirror: Clojure mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="clojure.js"></script>
+<style>.CodeMirror {background: #f8f8f8;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Clojure</a>
+  </ul>
+</div>
+
+<article>
+<h2>Clojure mode</h2>
+<form><textarea id="code" name="code">
+; Conway's Game of Life, based on the work of:
+;; Laurent Petit https://gist.github.com/1200343
+;; Christophe Grand http://clj-me.cgrand.net/2011/08/19/conways-game-of-life
+
+(ns ^{:doc "Conway's Game of Life."}
+ game-of-life)
+
+;; Core game of life's algorithm functions
+
+(defn neighbours
+  "Given a cell's coordinates, returns the coordinates of its neighbours."
+  [[x y]]
+  (for [dx [-1 0 1] dy (if (zero? dx) [-1 1] [-1 0 1])]
+    [(+ dx x) (+ dy y)]))
+
+(defn step
+  "Given a set of living cells, computes the new set of living cells."
+  [cells]
+  (set (for [[cell n] (frequencies (mapcat neighbours cells))
+             :when (or (= n 3) (and (= n 2) (cells cell)))]
+         cell)))
+
+;; Utility methods for displaying game on a text terminal
+
+(defn print-board
+  "Prints a board on *out*, representing a step in the game."
+  [board w h]
+  (doseq [x (range (inc w)) y (range (inc h))]
+    (if (= y 0) (print "\n"))
+    (print (if (board [x y]) "[X]" " . "))))
+
+(defn display-grids
+  "Prints a squence of boards on *out*, representing several steps."
+  [grids w h]
+  (doseq [board grids]
+    (print-board board w h)
+    (print "\n")))
+
+;; Launches an example board
+
+(def
+  ^{:doc "board represents the initial set of living cells"}
+   board #{[2 1] [2 2] [2 3]})
+
+(display-grids (take 3 (iterate step board)) 5 5)
+
+;; Let's play with characters
+(println \1 \a \# \\
+         \" \( \newline
+         \} \" \space
+         \tab \return \backspace
+         \u1000 \uAaAa \u9F9F)
+
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-clojure</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/cobol/cobol.js b/app/gui/html/vendor/codemirror/mode/cobol/cobol.js
new file mode 100644
index 0000000..e66e42a
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/cobol/cobol.js
@@ -0,0 +1,252 @@
+/**
+ * Author: Gautam Mehta
+ * Branched from CodeMirror's Scheme mode
+ */
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("cobol", function () {
+  var BUILTIN = "builtin", COMMENT = "comment", STRING = "string",
+      ATOM = "atom", NUMBER = "number", KEYWORD = "keyword", MODTAG = "header",
+      COBOLLINENUM = "def", PERIOD = "link";
+  function makeKeywords(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+  var atoms = makeKeywords("TRUE FALSE ZEROES ZEROS ZERO SPACES SPACE LOW-VALUE LOW-VALUES ");
+  var keywords = makeKeywords(
+      "ACCEPT ACCESS ACQUIRE ADD ADDRESS " +
+      "ADVANCING AFTER ALIAS ALL ALPHABET " +
+      "ALPHABETIC ALPHABETIC-LOWER ALPHABETIC-UPPER ALPHANUMERIC ALPHANUMERIC-EDITED " +
+      "ALSO ALTER ALTERNATE AND ANY " +
+      "ARE AREA AREAS ARITHMETIC ASCENDING " +
+      "ASSIGN AT ATTRIBUTE AUTHOR AUTO " +
+      "AUTO-SKIP AUTOMATIC B-AND B-EXOR B-LESS " +
+      "B-NOT B-OR BACKGROUND-COLOR BACKGROUND-COLOUR BEEP " +
+      "BEFORE BELL BINARY BIT BITS " +
+      "BLANK BLINK BLOCK BOOLEAN BOTTOM " +
+      "BY CALL CANCEL CD CF " +
+      "CH CHARACTER CHARACTERS CLASS CLOCK-UNITS " +
+      "CLOSE COBOL CODE CODE-SET COL " +
+      "COLLATING COLUMN COMMA COMMIT COMMITMENT " +
+      "COMMON COMMUNICATION COMP COMP-0 COMP-1 " +
+      "COMP-2 COMP-3 COMP-4 COMP-5 COMP-6 " +
+      "COMP-7 COMP-8 COMP-9 COMPUTATIONAL COMPUTATIONAL-0 " +
+      "COMPUTATIONAL-1 COMPUTATIONAL-2 COMPUTATIONAL-3 COMPUTATIONAL-4 COMPUTATIONAL-5 " +
+      "COMPUTATIONAL-6 COMPUTATIONAL-7 COMPUTATIONAL-8 COMPUTATIONAL-9 COMPUTE " +
+      "CONFIGURATION CONNECT CONSOLE CONTAINED CONTAINS " +
+      "CONTENT CONTINUE CONTROL CONTROL-AREA CONTROLS " +
+      "CONVERTING COPY CORR CORRESPONDING COUNT " +
+      "CRT CRT-UNDER CURRENCY CURRENT CURSOR " +
+      "DATA DATE DATE-COMPILED DATE-WRITTEN DAY " +
+      "DAY-OF-WEEK DB DB-ACCESS-CONTROL-KEY DB-DATA-NAME DB-EXCEPTION " +
+      "DB-FORMAT-NAME DB-RECORD-NAME DB-SET-NAME DB-STATUS DBCS " +
+      "DBCS-EDITED DE DEBUG-CONTENTS DEBUG-ITEM DEBUG-LINE " +
+      "DEBUG-NAME DEBUG-SUB-1 DEBUG-SUB-2 DEBUG-SUB-3 DEBUGGING " +
+      "DECIMAL-POINT DECLARATIVES DEFAULT DELETE DELIMITED " +
+      "DELIMITER DEPENDING DESCENDING DESCRIBED DESTINATION " +
+      "DETAIL DISABLE DISCONNECT DISPLAY DISPLAY-1 " +
+      "DISPLAY-2 DISPLAY-3 DISPLAY-4 DISPLAY-5 DISPLAY-6 " +
+      "DISPLAY-7 DISPLAY-8 DISPLAY-9 DIVIDE DIVISION " +
+      "DOWN DROP DUPLICATE DUPLICATES DYNAMIC " +
+      "EBCDIC EGI EJECT ELSE EMI " +
+      "EMPTY EMPTY-CHECK ENABLE END END. END-ACCEPT END-ACCEPT. " +
+      "END-ADD END-CALL END-COMPUTE END-DELETE END-DISPLAY " +
+      "END-DIVIDE END-EVALUATE END-IF END-INVOKE END-MULTIPLY " +
+      "END-OF-PAGE END-PERFORM END-READ END-RECEIVE END-RETURN " +
+      "END-REWRITE END-SEARCH END-START END-STRING END-SUBTRACT " +
+      "END-UNSTRING END-WRITE END-XML ENTER ENTRY " +
+      "ENVIRONMENT EOP EQUAL EQUALS ERASE " +
+      "ERROR ESI EVALUATE EVERY EXCEEDS " +
+      "EXCEPTION EXCLUSIVE EXIT EXTEND EXTERNAL " +
+      "EXTERNALLY-DESCRIBED-KEY FD FETCH FILE FILE-CONTROL " +
+      "FILE-STREAM FILES FILLER FINAL FIND " +
+      "FINISH FIRST FOOTING FOR FOREGROUND-COLOR " +
+      "FOREGROUND-COLOUR FORMAT FREE FROM FULL " +
+      "FUNCTION GENERATE GET GIVING GLOBAL " +
+      "GO GOBACK GREATER GROUP HEADING " +
+      "HIGH-VALUE HIGH-VALUES HIGHLIGHT I-O I-O-CONTROL " +
+      "ID IDENTIFICATION IF IN INDEX " +
+      "INDEX-1 INDEX-2 INDEX-3 INDEX-4 INDEX-5 " +
+      "INDEX-6 INDEX-7 INDEX-8 INDEX-9 INDEXED " +
+      "INDIC INDICATE INDICATOR INDICATORS INITIAL " +
+      "INITIALIZE INITIATE INPUT INPUT-OUTPUT INSPECT " +
+      "INSTALLATION INTO INVALID INVOKE IS " +
+      "JUST JUSTIFIED KANJI KEEP KEY " +
+      "LABEL LAST LD LEADING LEFT " +
+      "LEFT-JUSTIFY LENGTH LENGTH-CHECK LESS LIBRARY " +
+      "LIKE LIMIT LIMITS LINAGE LINAGE-COUNTER " +
+      "LINE LINE-COUNTER LINES LINKAGE LOCAL-STORAGE " +
+      "LOCALE LOCALLY LOCK " +
+      "MEMBER MEMORY MERGE MESSAGE METACLASS " +
+      "MODE MODIFIED MODIFY MODULES MOVE " +
+      "MULTIPLE MULTIPLY NATIONAL NATIVE NEGATIVE " +
+      "NEXT NO NO-ECHO NONE NOT " +
+      "NULL NULL-KEY-MAP NULL-MAP NULLS NUMBER " +
+      "NUMERIC NUMERIC-EDITED OBJECT OBJECT-COMPUTER OCCURS " +
+      "OF OFF OMITTED ON ONLY " +
+      "OPEN OPTIONAL OR ORDER ORGANIZATION " +
+      "OTHER OUTPUT OVERFLOW OWNER PACKED-DECIMAL " +
+      "PADDING PAGE PAGE-COUNTER PARSE PERFORM " +
+      "PF PH PIC PICTURE PLUS " +
+      "POINTER POSITION POSITIVE PREFIX PRESENT " +
+      "PRINTING PRIOR PROCEDURE PROCEDURE-POINTER PROCEDURES " +
+      "PROCEED PROCESS PROCESSING PROGRAM PROGRAM-ID " +
+      "PROMPT PROTECTED PURGE QUEUE QUOTE " +
+      "QUOTES RANDOM RD READ READY " +
+      "REALM RECEIVE RECONNECT RECORD RECORD-NAME " +
+      "RECORDS RECURSIVE REDEFINES REEL REFERENCE " +
+      "REFERENCE-MONITOR REFERENCES RELATION RELATIVE RELEASE " +
+      "REMAINDER REMOVAL RENAMES REPEATED REPLACE " +
+      "REPLACING REPORT REPORTING REPORTS REPOSITORY " +
+      "REQUIRED RERUN RESERVE RESET RETAINING " +
+      "RETRIEVAL RETURN RETURN-CODE RETURNING REVERSE-VIDEO " +
+      "REVERSED REWIND REWRITE RF RH " +
+      "RIGHT RIGHT-JUSTIFY ROLLBACK ROLLING ROUNDED " +
+      "RUN SAME SCREEN SD SEARCH " +
+      "SECTION SECURE SECURITY SEGMENT SEGMENT-LIMIT " +
+      "SELECT SEND SENTENCE SEPARATE SEQUENCE " +
+      "SEQUENTIAL SET SHARED SIGN SIZE " +
+      "SKIP1 SKIP2 SKIP3 SORT SORT-MERGE " +
+      "SORT-RETURN SOURCE SOURCE-COMPUTER SPACE-FILL " +
+      "SPECIAL-NAMES STANDARD STANDARD-1 STANDARD-2 " +
+      "START STARTING STATUS STOP STORE " +
+      "STRING SUB-QUEUE-1 SUB-QUEUE-2 SUB-QUEUE-3 SUB-SCHEMA " +
+      "SUBFILE SUBSTITUTE SUBTRACT SUM SUPPRESS " +
+      "SYMBOLIC SYNC SYNCHRONIZED SYSIN SYSOUT " +
+      "TABLE TALLYING TAPE TENANT TERMINAL " +
+      "TERMINATE TEST TEXT THAN THEN " +
+      "THROUGH THRU TIME TIMES TITLE " +
+      "TO TOP TRAILING TRAILING-SIGN TRANSACTION " +
+      "TYPE TYPEDEF UNDERLINE UNEQUAL UNIT " +
+      "UNSTRING UNTIL UP UPDATE UPON " +
+      "USAGE USAGE-MODE USE USING VALID " +
+      "VALIDATE VALUE VALUES VARYING VLR " +
+      "WAIT WHEN WHEN-COMPILED WITH WITHIN " +
+      "WORDS WORKING-STORAGE WRITE XML XML-CODE " +
+      "XML-EVENT XML-NTEXT XML-TEXT ZERO ZERO-FILL " );
+
+  var builtins = makeKeywords("- * ** / + < <= = > >= ");
+  var tests = {
+    digit: /\d/,
+    digit_or_colon: /[\d:]/,
+    hex: /[0-9a-f]/i,
+    sign: /[+-]/,
+    exponent: /e/i,
+    keyword_char: /[^\s\(\[\;\)\]]/,
+    symbol: /[\w*+\-]/
+  };
+  function isNumber(ch, stream){
+    // hex
+    if ( ch === '0' && stream.eat(/x/i) ) {
+      stream.eatWhile(tests.hex);
+      return true;
+    }
+    // leading sign
+    if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) {
+      stream.eat(tests.sign);
+      ch = stream.next();
+    }
+    if ( tests.digit.test(ch) ) {
+      stream.eat(ch);
+      stream.eatWhile(tests.digit);
+      if ( '.' == stream.peek()) {
+        stream.eat('.');
+        stream.eatWhile(tests.digit);
+      }
+      if ( stream.eat(tests.exponent) ) {
+        stream.eat(tests.sign);
+        stream.eatWhile(tests.digit);
+      }
+      return true;
+    }
+    return false;
+  }
+  return {
+    startState: function () {
+      return {
+        indentStack: null,
+        indentation: 0,
+        mode: false
+      };
+    },
+    token: function (stream, state) {
+      if (state.indentStack == null && stream.sol()) {
+        // update indentation, but only if indentStack is empty
+        state.indentation = 6 ; //stream.indentation();
+      }
+      // skip spaces
+      if (stream.eatSpace()) {
+        return null;
+      }
+      var returnType = null;
+      switch(state.mode){
+      case "string": // multi-line string parsing mode
+        var next = false;
+        while ((next = stream.next()) != null) {
+          if (next == "\"" || next == "\'") {
+            state.mode = false;
+            break;
+          }
+        }
+        returnType = STRING; // continue on in string mode
+        break;
+      default: // default parsing mode
+        var ch = stream.next();
+        var col = stream.column();
+        if (col >= 0 && col <= 5) {
+          returnType = COBOLLINENUM;
+        } else if (col >= 72 && col <= 79) {
+          stream.skipToEnd();
+          returnType = MODTAG;
+        } else if (ch == "*" && col == 6) { // comment
+          stream.skipToEnd(); // rest of the line is a comment
+          returnType = COMMENT;
+        } else if (ch == "\"" || ch == "\'") {
+          state.mode = "string";
+          returnType = STRING;
+        } else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) {
+          returnType = ATOM;
+        } else if (ch == ".") {
+          returnType = PERIOD;
+        } else if (isNumber(ch,stream)){
+          returnType = NUMBER;
+        } else {
+          if (stream.current().match(tests.symbol)) {
+            while (col < 71) {
+              if (stream.eat(tests.symbol) === undefined) {
+                break;
+              } else {
+                col++;
+              }
+            }
+          }
+          if (keywords && keywords.propertyIsEnumerable(stream.current().toUpperCase())) {
+            returnType = KEYWORD;
+          } else if (builtins && builtins.propertyIsEnumerable(stream.current().toUpperCase())) {
+            returnType = BUILTIN;
+          } else if (atoms && atoms.propertyIsEnumerable(stream.current().toUpperCase())) {
+            returnType = ATOM;
+          } else returnType = null;
+        }
+      }
+      return returnType;
+    },
+    indent: function (state) {
+      if (state.indentStack == null) return state.indentation;
+      return state.indentStack.indent;
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/x-cobol", "cobol");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/cobol/index.html b/app/gui/html/vendor/codemirror/mode/cobol/index.html
new file mode 100644
index 0000000..326e398
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/cobol/index.html
@@ -0,0 +1,210 @@
+<!doctype html>
+
+<title>CodeMirror: COBOL mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link rel="stylesheet" href="../../theme/neat.css">
+<link rel="stylesheet" href="../../theme/elegant.css">
+<link rel="stylesheet" href="../../theme/erlang-dark.css">
+<link rel="stylesheet" href="../../theme/night.css">
+<link rel="stylesheet" href="../../theme/monokai.css">
+<link rel="stylesheet" href="../../theme/cobalt.css">
+<link rel="stylesheet" href="../../theme/eclipse.css">
+<link rel="stylesheet" href="../../theme/rubyblue.css">
+<link rel="stylesheet" href="../../theme/lesser-dark.css">
+<link rel="stylesheet" href="../../theme/xq-dark.css">
+<link rel="stylesheet" href="../../theme/xq-light.css">
+<link rel="stylesheet" href="../../theme/ambiance.css">
+<link rel="stylesheet" href="../../theme/blackboard.css">
+<link rel="stylesheet" href="../../theme/vibrant-ink.css">
+<link rel="stylesheet" href="../../theme/solarized.css">
+<link rel="stylesheet" href="../../theme/twilight.css">
+<link rel="stylesheet" href="../../theme/midnight.css">
+<link rel="stylesheet" href="../../addon/dialog/dialog.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="cobol.js"></script>
+<script src="../../addon/selection/active-line.js"></script>
+<script src="../../addon/search/search.js"></script>
+<script src="../../addon/dialog/dialog.js"></script>
+<script src="../../addon/search/searchcursor.js"></script>
+<style>
+        .CodeMirror {
+          border: 1px solid #eee;
+          font-size : 20px;
+          height : auto !important;
+        }
+        .CodeMirror-activeline-background {background: #555555 !important;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">COBOL</a>
+  </ul>
+</div>
+
+<article>
+<h2>COBOL mode</h2>
+
+    <p> Select Theme <select onchange="selectTheme()" id="selectTheme">
+        <option>default</option>
+        <option>ambiance</option>
+        <option>blackboard</option>
+        <option>cobalt</option>
+        <option>eclipse</option>
+        <option>elegant</option>
+        <option>erlang-dark</option>
+        <option>lesser-dark</option>
+        <option>midnight</option>
+        <option>monokai</option>
+        <option>neat</option>
+        <option>night</option>
+        <option>rubyblue</option>
+        <option>solarized dark</option>
+        <option>solarized light</option>
+        <option selected>twilight</option>
+        <option>vibrant-ink</option>
+        <option>xq-dark</option>
+        <option>xq-light</option>
+    </select>    Select Font Size <select onchange="selectFontsize()" id="selectFontSize">
+          <option value="13px">13px</option>
+          <option value="14px">14px</option>
+          <option value="16px">16px</option>
+          <option value="18px">18px</option>
+          <option value="20px" selected="selected">20px</option>
+          <option value="24px">24px</option>
+          <option value="26px">26px</option>
+          <option value="28px">28px</option>
+          <option value="30px">30px</option>
+          <option value="32px">32px</option>
+          <option value="34px">34px</option>
+          <option value="36px">36px</option>
+        </select>
+<label for="checkBoxReadOnly">Read-only</label>
+<input type="checkbox" id="checkBoxReadOnly" onchange="selectReadOnly()">
+<label for="id_tabToIndentSpace">Insert Spaces on Tab</label>
+<input type="checkbox" id="id_tabToIndentSpace" onchange="tabToIndentSpace()">
+</p>
+<textarea id="code" name="code">
+---------1---------2---------3---------4---------5---------6---------7---------8
+12345678911234567892123456789312345678941234567895123456789612345678971234567898
+000010 IDENTIFICATION DIVISION.                                        MODTGHERE
+000020 PROGRAM-ID.       SAMPLE.
+000030 AUTHOR.           TEST SAM. 
+000040 DATE-WRITTEN.     5 February 2013
+000041
+000042* A sample program just to show the form.
+000043* The program copies its input to the output,
+000044* and counts the number of records.
+000045* At the end this number is printed.
+000046
+000050 ENVIRONMENT DIVISION.
+000060 INPUT-OUTPUT SECTION.
+000070 FILE-CONTROL.
+000080     SELECT STUDENT-FILE     ASSIGN TO SYSIN
+000090         ORGANIZATION IS LINE SEQUENTIAL.
+000100     SELECT PRINT-FILE       ASSIGN TO SYSOUT
+000110         ORGANIZATION IS LINE SEQUENTIAL.
+000120
+000130 DATA DIVISION.
+000140 FILE SECTION.
+000150 FD  STUDENT-FILE
+000160     RECORD CONTAINS 43 CHARACTERS
+000170     DATA RECORD IS STUDENT-IN.
+000180 01  STUDENT-IN              PIC X(43).
+000190
+000200 FD  PRINT-FILE
+000210     RECORD CONTAINS 80 CHARACTERS
+000220     DATA RECORD IS PRINT-LINE.
+000230 01  PRINT-LINE              PIC X(80).
+000240
+000250 WORKING-STORAGE SECTION.
+000260 01  DATA-REMAINS-SWITCH     PIC X(2)      VALUE SPACES.
+000261 01  RECORDS-WRITTEN         PIC 99.
+000270
+000280 01  DETAIL-LINE.
+000290     05  FILLER              PIC X(7)      VALUE SPACES.
+000300     05  RECORD-IMAGE        PIC X(43).
+000310     05  FILLER              PIC X(30)     VALUE SPACES.
+000311 
+000312 01  SUMMARY-LINE.
+000313     05  FILLER              PIC X(7)      VALUE SPACES.
+000314     05  TOTAL-READ          PIC 99.
+000315     05  FILLER              PIC X         VALUE SPACE.
+000316     05  FILLER              PIC X(17)     
+000317                 VALUE  'Records were read'.
+000318     05  FILLER              PIC X(53)     VALUE SPACES.
+000319
+000320 PROCEDURE DIVISION.
+000321
+000330 PREPARE-SENIOR-REPORT.
+000340     OPEN INPUT  STUDENT-FILE
+000350          OUTPUT PRINT-FILE.
+000351     MOVE ZERO TO RECORDS-WRITTEN.
+000360     READ STUDENT-FILE
+000370         AT END MOVE 'NO' TO DATA-REMAINS-SWITCH
+000380     END-READ.
+000390     PERFORM PROCESS-RECORDS
+000410         UNTIL DATA-REMAINS-SWITCH = 'NO'.
+000411     PERFORM PRINT-SUMMARY.
+000420     CLOSE STUDENT-FILE
+000430           PRINT-FILE.
+000440     STOP RUN.
+000450
+000460 PROCESS-RECORDS.
+000470     MOVE STUDENT-IN TO RECORD-IMAGE.
+000480     MOVE DETAIL-LINE TO PRINT-LINE.
+000490     WRITE PRINT-LINE.
+000500     ADD 1 TO RECORDS-WRITTEN.
+000510     READ STUDENT-FILE
+000520         AT END MOVE 'NO' TO DATA-REMAINS-SWITCH
+000530     END-READ. 
+000540
+000550 PRINT-SUMMARY.
+000560     MOVE RECORDS-WRITTEN TO TOTAL-READ.
+000570     MOVE SUMMARY-LINE TO PRINT-LINE.
+000571     WRITE PRINT-LINE. 
+000572
+000580
+</textarea>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        mode: "text/x-cobol",
+        theme : "twilight",
+        styleActiveLine: true,
+        showCursorWhenSelecting : true,  
+      });
+      function selectTheme() {
+        var themeInput = document.getElementById("selectTheme");
+        var theme = themeInput.options[themeInput.selectedIndex].innerHTML;
+        editor.setOption("theme", theme);
+      }
+      function selectFontsize() {
+        var fontSizeInput = document.getElementById("selectFontSize");
+        var fontSize = fontSizeInput.options[fontSizeInput.selectedIndex].innerHTML;
+        editor.getWrapperElement().style["font-size"] = fontSize;
+        editor.refresh();
+      }
+      function selectReadOnly() {
+        editor.setOption("readOnly", document.getElementById("checkBoxReadOnly").checked);
+      }
+      function tabToIndentSpace() {
+        if (document.getElementById("id_tabToIndentSpace").checked) {
+            editor.setOption("extraKeys", {Tab: function(cm) { cm.replaceSelection("    ", "end"); }});
+        } else {
+            editor.setOption("extraKeys", {Tab: function(cm) { cm.replaceSelection("    ", "end"); }});
+        }
+      }
+    </script>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/coffeescript/coffeescript.js b/app/gui/html/vendor/codemirror/mode/coffeescript/coffeescript.js
new file mode 100644
index 0000000..c6da8f2
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/coffeescript/coffeescript.js
@@ -0,0 +1,365 @@
+/**
+ * Link to the project's GitHub page:
+ * https://github.com/pickhardt/coffeescript-codemirror-mode
+ */
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("coffeescript", function(conf) {
+  var ERRORCLASS = "error";
+
+  function wordRegexp(words) {
+    return new RegExp("^((" + words.join(")|(") + "))\\b");
+  }
+
+  var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?)/;
+  var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
+  var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
+  var properties = /^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*/;
+
+  var wordOperators = wordRegexp(["and", "or", "not",
+                                  "is", "isnt", "in",
+                                  "instanceof", "typeof"]);
+  var indentKeywords = ["for", "while", "loop", "if", "unless", "else",
+                        "switch", "try", "catch", "finally", "class"];
+  var commonKeywords = ["break", "by", "continue", "debugger", "delete",
+                        "do", "in", "of", "new", "return", "then",
+                        "this", "throw", "when", "until"];
+
+  var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
+
+  indentKeywords = wordRegexp(indentKeywords);
+
+
+  var stringPrefixes = /^('{3}|\"{3}|['\"])/;
+  var regexPrefixes = /^(\/{3}|\/)/;
+  var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"];
+  var constants = wordRegexp(commonConstants);
+
+  // Tokenizers
+  function tokenBase(stream, state) {
+    // Handle scope changes
+    if (stream.sol()) {
+      if (state.scope.align === null) state.scope.align = false;
+      var scopeOffset = state.scope.offset;
+      if (stream.eatSpace()) {
+        var lineOffset = stream.indentation();
+        if (lineOffset > scopeOffset && state.scope.type == "coffee") {
+          return "indent";
+        } else if (lineOffset < scopeOffset) {
+          return "dedent";
+        }
+        return null;
+      } else {
+        if (scopeOffset > 0) {
+          dedent(stream, state);
+        }
+      }
+    }
+    if (stream.eatSpace()) {
+      return null;
+    }
+
+    var ch = stream.peek();
+
+    // Handle docco title comment (single line)
+    if (stream.match("####")) {
+      stream.skipToEnd();
+      return "comment";
+    }
+
+    // Handle multi line comments
+    if (stream.match("###")) {
+      state.tokenize = longComment;
+      return state.tokenize(stream, state);
+    }
+
+    // Single line comment
+    if (ch === "#") {
+      stream.skipToEnd();
+      return "comment";
+    }
+
+    // Handle number literals
+    if (stream.match(/^-?[0-9\.]/, false)) {
+      var floatLiteral = false;
+      // Floats
+      if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
+        floatLiteral = true;
+      }
+      if (stream.match(/^-?\d+\.\d*/)) {
+        floatLiteral = true;
+      }
+      if (stream.match(/^-?\.\d+/)) {
+        floatLiteral = true;
+      }
+
+      if (floatLiteral) {
+        // prevent from getting extra . on 1..
+        if (stream.peek() == "."){
+          stream.backUp(1);
+        }
+        return "number";
+      }
+      // Integers
+      var intLiteral = false;
+      // Hex
+      if (stream.match(/^-?0x[0-9a-f]+/i)) {
+        intLiteral = true;
+      }
+      // Decimal
+      if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
+        intLiteral = true;
+      }
+      // Zero by itself with no other piece of number.
+      if (stream.match(/^-?0(?![\dx])/i)) {
+        intLiteral = true;
+      }
+      if (intLiteral) {
+        return "number";
+      }
+    }
+
+    // Handle strings
+    if (stream.match(stringPrefixes)) {
+      state.tokenize = tokenFactory(stream.current(), false, "string");
+      return state.tokenize(stream, state);
+    }
+    // Handle regex literals
+    if (stream.match(regexPrefixes)) {
+      if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division
+        state.tokenize = tokenFactory(stream.current(), true, "string-2");
+        return state.tokenize(stream, state);
+      } else {
+        stream.backUp(1);
+      }
+    }
+
+    // Handle operators and delimiters
+    if (stream.match(operators) || stream.match(wordOperators)) {
+      return "operator";
+    }
+    if (stream.match(delimiters)) {
+      return "punctuation";
+    }
+
+    if (stream.match(constants)) {
+      return "atom";
+    }
+
+    if (stream.match(keywords)) {
+      return "keyword";
+    }
+
+    if (stream.match(identifiers)) {
+      return "variable";
+    }
+
+    if (stream.match(properties)) {
+      return "property";
+    }
+
+    // Handle non-detected items
+    stream.next();
+    return ERRORCLASS;
+  }
+
+  function tokenFactory(delimiter, singleline, outclass) {
+    return function(stream, state) {
+      while (!stream.eol()) {
+        stream.eatWhile(/[^'"\/\\]/);
+        if (stream.eat("\\")) {
+          stream.next();
+          if (singleline && stream.eol()) {
+            return outclass;
+          }
+        } else if (stream.match(delimiter)) {
+          state.tokenize = tokenBase;
+          return outclass;
+        } else {
+          stream.eat(/['"\/]/);
+        }
+      }
+      if (singleline) {
+        if (conf.mode.singleLineStringErrors) {
+          outclass = ERRORCLASS;
+        } else {
+          state.tokenize = tokenBase;
+        }
+      }
+      return outclass;
+    };
+  }
+
+  function longComment(stream, state) {
+    while (!stream.eol()) {
+      stream.eatWhile(/[^#]/);
+      if (stream.match("###")) {
+        state.tokenize = tokenBase;
+        break;
+      }
+      stream.eatWhile("#");
+    }
+    return "comment";
+  }
+
+  function indent(stream, state, type) {
+    type = type || "coffee";
+    var offset = 0, align = false, alignOffset = null;
+    for (var scope = state.scope; scope; scope = scope.prev) {
+      if (scope.type === "coffee") {
+        offset = scope.offset + conf.indentUnit;
+        break;
+      }
+    }
+    if (type !== "coffee") {
+      align = null;
+      alignOffset = stream.column() + stream.current().length;
+    } else if (state.scope.align) {
+      state.scope.align = false;
+    }
+    state.scope = {
+      offset: offset,
+      type: type,
+      prev: state.scope,
+      align: align,
+      alignOffset: alignOffset
+    };
+  }
+
+  function dedent(stream, state) {
+    if (!state.scope.prev) return;
+    if (state.scope.type === "coffee") {
+      var _indent = stream.indentation();
+      var matched = false;
+      for (var scope = state.scope; scope; scope = scope.prev) {
+        if (_indent === scope.offset) {
+          matched = true;
+          break;
+        }
+      }
+      if (!matched) {
+        return true;
+      }
+      while (state.scope.prev && state.scope.offset !== _indent) {
+        state.scope = state.scope.prev;
+      }
+      return false;
+    } else {
+      state.scope = state.scope.prev;
+      return false;
+    }
+  }
+
+  function tokenLexer(stream, state) {
+    var style = state.tokenize(stream, state);
+    var current = stream.current();
+
+    // Handle "." connected identifiers
+    if (current === ".") {
+      style = state.tokenize(stream, state);
+      current = stream.current();
+      if (/^\.[\w$]+$/.test(current)) {
+        return "variable";
+      } else {
+        return ERRORCLASS;
+      }
+    }
+
+    // Handle scope changes.
+    if (current === "return") {
+      state.dedent += 1;
+    }
+    if (((current === "->" || current === "=>") &&
+         !state.lambda &&
+         !stream.peek())
+        || style === "indent") {
+      indent(stream, state);
+    }
+    var delimiter_index = "[({".indexOf(current);
+    if (delimiter_index !== -1) {
+      indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
+    }
+    if (indentKeywords.exec(current)){
+      indent(stream, state);
+    }
+    if (current == "then"){
+      dedent(stream, state);
+    }
+
+
+    if (style === "dedent") {
+      if (dedent(stream, state)) {
+        return ERRORCLASS;
+      }
+    }
+    delimiter_index = "])}".indexOf(current);
+    if (delimiter_index !== -1) {
+      while (state.scope.type == "coffee" && state.scope.prev)
+        state.scope = state.scope.prev;
+      if (state.scope.type == current)
+        state.scope = state.scope.prev;
+    }
+    if (state.dedent > 0 && stream.eol() && state.scope.type == "coffee") {
+      if (state.scope.prev) state.scope = state.scope.prev;
+      state.dedent -= 1;
+    }
+
+    return style;
+  }
+
+  var external = {
+    startState: function(basecolumn) {
+      return {
+        tokenize: tokenBase,
+        scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
+        lastToken: null,
+        lambda: false,
+        dedent: 0
+      };
+    },
+
+    token: function(stream, state) {
+      var fillAlign = state.scope.align === null && state.scope;
+      if (fillAlign && stream.sol()) fillAlign.align = false;
+
+      var style = tokenLexer(stream, state);
+      if (fillAlign && style && style != "comment") fillAlign.align = true;
+
+      state.lastToken = {style:style, content: stream.current()};
+
+      if (stream.eol() && stream.lambda) {
+        state.lambda = false;
+      }
+
+      return style;
+    },
+
+    indent: function(state, text) {
+      if (state.tokenize != tokenBase) return 0;
+      var scope = state.scope;
+      var closer = text && "])}".indexOf(text.charAt(0)) > -1;
+      if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev;
+      var closes = closer && scope.type === text.charAt(0);
+      if (scope.align)
+        return scope.alignOffset - (closes ? 1 : 0);
+      else
+        return (closes ? scope.prev : scope).offset;
+    },
+
+    lineComment: "#",
+    fold: "indent"
+  };
+  return external;
+});
+
+CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/coffeescript/index.html b/app/gui/html/vendor/codemirror/mode/coffeescript/index.html
new file mode 100644
index 0000000..6e6fde5
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/coffeescript/index.html
@@ -0,0 +1,740 @@
+<!doctype html>
+
+<title>CodeMirror: CoffeeScript mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="coffeescript.js"></script>
+<style>.CodeMirror {border-top: 1px solid silver; border-bottom: 1px solid silver;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">CoffeeScript</a>
+  </ul>
+</div>
+
+<article>
+<h2>CoffeeScript mode</h2>
+<form><textarea id="code" name="code">
+# CoffeeScript mode for CodeMirror
+# Copyright (c) 2011 Jeff Pickhardt, released under
+# the MIT License.
+#
+# Modified from the Python CodeMirror mode, which also is 
+# under the MIT License Copyright (c) 2010 Timothy Farrell.
+#
+# The following script, Underscore.coffee, is used to 
+# demonstrate CoffeeScript mode for CodeMirror.
+#
+# To download CoffeeScript mode for CodeMirror, go to:
+# https://github.com/pickhardt/coffeescript-codemirror-mode
+
+# **Underscore.coffee
+# (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.**
+# Underscore is freely distributable under the terms of the
+# [MIT license](http://en.wikipedia.org/wiki/MIT_License).
+# Portions of Underscore are inspired by or borrowed from
+# [Prototype.js](http://prototypejs.org/api), Oliver Steele's
+# [Functional](http://osteele.com), and John Resig's
+# [Micro-Templating](http://ejohn.org).
+# For all details and documentation:
+# http://documentcloud.github.com/underscore/
+
+
+# Baseline setup
+# --------------
+
+# Establish the root object, `window` in the browser, or `global` on the server.
+root = this
+
+
+# Save the previous value of the `_` variable.
+previousUnderscore = root._
+
+### Multiline
+    comment
+###
+
+# Establish the object that gets thrown to break out of a loop iteration.
+# `StopIteration` is SOP on Mozilla.
+breaker = if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration
+
+
+#### Docco style single line comment (title)
+
+
+# Helper function to escape **RegExp** contents, because JS doesn't have one.
+escapeRegExp = (string) -> string.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1')
+
+
+# Save bytes in the minified (but not gzipped) version:
+ArrayProto = Array.prototype
+ObjProto = Object.prototype
+
+
+# Create quick reference variables for speed access to core prototypes.
+slice = ArrayProto.slice
+unshift = ArrayProto.unshift
+toString = ObjProto.toString
+hasOwnProperty = ObjProto.hasOwnProperty
+propertyIsEnumerable = ObjProto.propertyIsEnumerable
+
+
+# All **ECMA5** native implementations we hope to use are declared here.
+nativeForEach = ArrayProto.forEach
+nativeMap = ArrayProto.map
+nativeReduce = ArrayProto.reduce
+nativeReduceRight = ArrayProto.reduceRight
+nativeFilter = ArrayProto.filter
+nativeEvery = ArrayProto.every
+nativeSome = ArrayProto.some
+nativeIndexOf = ArrayProto.indexOf
+nativeLastIndexOf = ArrayProto.lastIndexOf
+nativeIsArray = Array.isArray
+nativeKeys = Object.keys
+
+
+# Create a safe reference to the Underscore object for use below.
+_ = (obj) -> new wrapper(obj)
+
+
+# Export the Underscore object for **CommonJS**.
+if typeof(exports) != 'undefined' then exports._ = _
+
+
+# Export Underscore to global scope.
+root._ = _
+
+
+# Current version.
+_.VERSION = '1.1.0'
+
+
+# Collection Functions
+# --------------------
+
+# The cornerstone, an **each** implementation.
+# Handles objects implementing **forEach**, arrays, and raw objects.
+_.each = (obj, iterator, context) ->
+  try
+    if nativeForEach and obj.forEach is nativeForEach
+      obj.forEach iterator, context
+    else if _.isNumber obj.length
+      iterator.call context, obj[i], i, obj for i in [0...obj.length]
+    else
+      iterator.call context, val, key, obj for own key, val of obj
+  catch e
+    throw e if e isnt breaker
+  obj
+
+
+# Return the results of applying the iterator to each element. Use JavaScript
+# 1.6's version of **map**, if possible.
+_.map = (obj, iterator, context) ->
+  return obj.map(iterator, context) if nativeMap and obj.map is nativeMap
+  results = []
+  _.each obj, (value, index, list) ->
+    results.push iterator.call context, value, index, list
+  results
+
+
+# **Reduce** builds up a single result from a list of values. Also known as
+# **inject**, or **foldl**. Uses JavaScript 1.8's version of **reduce**, if possible.
+_.reduce = (obj, iterator, memo, context) ->
+  if nativeReduce and obj.reduce is nativeReduce
+    iterator = _.bind iterator, context if context
+    return obj.reduce iterator, memo
+  _.each obj, (value, index, list) ->
+    memo = iterator.call context, memo, value, index, list
+  memo
+
+
+# The right-associative version of **reduce**, also known as **foldr**. Uses
+# JavaScript 1.8's version of **reduceRight**, if available.
+_.reduceRight = (obj, iterator, memo, context) ->
+  if nativeReduceRight and obj.reduceRight is nativeReduceRight
+    iterator = _.bind iterator, context if context
+    return obj.reduceRight iterator, memo
+  reversed = _.clone(_.toArray(obj)).reverse()
+  _.reduce reversed, iterator, memo, context
+
+
+# Return the first value which passes a truth test.
+_.detect = (obj, iterator, context) ->
+  result = null
+  _.each obj, (value, index, list) ->
+    if iterator.call context, value, index, list
+      result = value
+      _.breakLoop()
+  result
+
+
+# Return all the elements that pass a truth test. Use JavaScript 1.6's
+# **filter**, if it exists.
+_.filter = (obj, iterator, context) ->
+  return obj.filter iterator, context if nativeFilter and obj.filter is nativeFilter
+  results = []
+  _.each obj, (value, index, list) ->
+    results.push value if iterator.call context, value, index, list
+  results
+
+
+# Return all the elements for which a truth test fails.
+_.reject = (obj, iterator, context) ->
+  results = []
+  _.each obj, (value, index, list) ->
+    results.push value if not iterator.call context, value, index, list
+  results
+
+
+# Determine whether all of the elements match a truth test. Delegate to
+# JavaScript 1.6's **every**, if it is present.
+_.every = (obj, iterator, context) ->
+  iterator ||= _.identity
+  return obj.every iterator, context if nativeEvery and obj.every is nativeEvery
+  result = true
+  _.each obj, (value, index, list) ->
+    _.breakLoop() unless (result = result and iterator.call(context, value, index, list))
+  result
+
+
+# Determine if at least one element in the object matches a truth test. Use
+# JavaScript 1.6's **some**, if it exists.
+_.some = (obj, iterator, context) ->
+  iterator ||= _.identity
+  return obj.some iterator, context if nativeSome and obj.some is nativeSome
+  result = false
+  _.each obj, (value, index, list) ->
+    _.breakLoop() if (result = iterator.call(context, value, index, list))
+  result
+
+
+# Determine if a given value is included in the array or object,
+# based on `===`.
+_.include = (obj, target) ->
+  return _.indexOf(obj, target) isnt -1 if nativeIndexOf and obj.indexOf is nativeIndexOf
+  return true for own key, val of obj when val is target
+  false
+
+
+# Invoke a method with arguments on every item in a collection.
+_.invoke = (obj, method) ->
+  args = _.rest arguments, 2
+  (if method then val[method] else val).apply(val, args) for val in obj
+
+
+# Convenience version of a common use case of **map**: fetching a property.
+_.pluck = (obj, key) ->
+  _.map(obj, (val) -> val[key])
+
+
+# Return the maximum item or (item-based computation).
+_.max = (obj, iterator, context) ->
+  return Math.max.apply(Math, obj) if not iterator and _.isArray(obj)
+  result = computed: -Infinity
+  _.each obj, (value, index, list) ->
+    computed = if iterator then iterator.call(context, value, index, list) else value
+    computed >= result.computed and (result = {value: value, computed: computed})
+  result.value
+
+
+# Return the minimum element (or element-based computation).
+_.min = (obj, iterator, context) ->
+  return Math.min.apply(Math, obj) if not iterator and _.isArray(obj)
+  result = computed: Infinity
+  _.each obj, (value, index, list) ->
+    computed = if iterator then iterator.call(context, value, index, list) else value
+    computed < result.computed and (result = {value: value, computed: computed})
+  result.value
+
+
+# Sort the object's values by a criterion produced by an iterator.
+_.sortBy = (obj, iterator, context) ->
+  _.pluck(((_.map obj, (value, index, list) ->
+    {value: value, criteria: iterator.call(context, value, index, list)}
+  ).sort((left, right) ->
+    a = left.criteria; b = right.criteria
+    if a < b then -1 else if a > b then 1 else 0
+  )), 'value')
+
+
+# Use a comparator function to figure out at what index an object should
+# be inserted so as to maintain order. Uses binary search.
+_.sortedIndex = (array, obj, iterator) ->
+  iterator ||= _.identity
+  low = 0
+  high = array.length
+  while low < high
+    mid = (low + high) >> 1
+    if iterator(array[mid]) < iterator(obj) then low = mid + 1 else high = mid
+  low
+
+
+# Convert anything iterable into a real, live array.
+_.toArray = (iterable) ->
+  return [] if (!iterable)
+  return iterable.toArray() if (iterable.toArray)
+  return iterable if (_.isArray(iterable))
+  return slice.call(iterable) if (_.isArguments(iterable))
+  _.values(iterable)
+
+
+# Return the number of elements in an object.
+_.size = (obj) -> _.toArray(obj).length
+
+
+# Array Functions
+# ---------------
+
+# Get the first element of an array. Passing `n` will return the first N
+# values in the array. Aliased as **head**. The `guard` check allows it to work
+# with **map**.
+_.first = (array, n, guard) ->
+  if n and not guard then slice.call(array, 0, n) else array[0]
+
+
+# Returns everything but the first entry of the array. Aliased as **tail**.
+# Especially useful on the arguments object. Passing an `index` will return
+# the rest of the values in the array from that index onward. The `guard`
+# check allows it to work with **map**.
+_.rest = (array, index, guard) ->
+  slice.call(array, if _.isUndefined(index) or guard then 1 else index)
+
+
+# Get the last element of an array.
+_.last = (array) -> array[array.length - 1]
+
+
+# Trim out all falsy values from an array.
+_.compact = (array) -> item for item in array when item
+
+
+# Return a completely flattened version of an array.
+_.flatten = (array) ->
+  _.reduce array, (memo, value) ->
+    return memo.concat(_.flatten(value)) if _.isArray value
+    memo.push value
+    memo
+  , []
+
+
+# Return a version of the array that does not contain the specified value(s).
+_.without = (array) ->
+  values = _.rest arguments
+  val for val in _.toArray(array) when not _.include values, val
+
+
+# Produce a duplicate-free version of the array. If the array has already
+# been sorted, you have the option of using a faster algorithm.
+_.uniq = (array, isSorted) ->
+  memo = []
+  for el, i in _.toArray array
+    memo.push el if i is 0 || (if isSorted is true then _.last(memo) isnt el else not _.include(memo, el))
+  memo
+
+
+# Produce an array that contains every item shared between all the
+# passed-in arrays.
+_.intersect = (array) ->
+  rest = _.rest arguments
+  _.select _.uniq(array), (item) ->
+    _.all rest, (other) ->
+      _.indexOf(other, item) >= 0
+
+
+# Zip together multiple lists into a single array -- elements that share
+# an index go together.
+_.zip = ->
+  length = _.max _.pluck arguments, 'length'
+  results = new Array length
+  for i in [0...length]
+    results[i] = _.pluck arguments, String i
+  results
+
+
+# If the browser doesn't supply us with **indexOf** (I'm looking at you, MSIE),
+# we need this function. Return the position of the first occurrence of an
+# item in an array, or -1 if the item is not included in the array.
+_.indexOf = (array, item) ->
+  return array.indexOf item if nativeIndexOf and array.indexOf is nativeIndexOf
+  i = 0; l = array.length
+  while l - i
+    if array[i] is item then return i else i++
+  -1
+
+
+# Provide JavaScript 1.6's **lastIndexOf**, delegating to the native function,
+# if possible.
+_.lastIndexOf = (array, item) ->
+  return array.lastIndexOf(item) if nativeLastIndexOf and array.lastIndexOf is nativeLastIndexOf
+  i = array.length
+  while i
+    if array[i] is item then return i else i--
+  -1
+
+
+# Generate an integer Array containing an arithmetic progression. A port of
+# [the native Python **range** function](http://docs.python.org/library/functions.html#range).
+_.range = (start, stop, step) ->
+  a = arguments
+  solo = a.length <= 1
+  i = start = if solo then 0 else a[0]
+  stop = if solo then a[0] else a[1]
+  step = a[2] or 1
+  len = Math.ceil((stop - start) / step)
+  return [] if len <= 0
+  range = new Array len
+  idx = 0
+  loop
+    return range if (if step > 0 then i - stop else stop - i) >= 0
+    range[idx] = i
+    idx++
+    i+= step
+
+
+# Function Functions
+# ------------------
+
+# Create a function bound to a given object (assigning `this`, and arguments,
+# optionally). Binding with arguments is also known as **curry**.
+_.bind = (func, obj) ->
+  args = _.rest arguments, 2
+  -> func.apply obj or root, args.concat arguments
+
+
+# Bind all of an object's methods to that object. Useful for ensuring that
+# all callbacks defined on an object belong to it.
+_.bindAll = (obj) ->
+  funcs = if arguments.length > 1 then _.rest(arguments) else _.functions(obj)
+  _.each funcs, (f) -> obj[f] = _.bind obj[f], obj
+  obj
+
+
+# Delays a function for the given number of milliseconds, and then calls
+# it with the arguments supplied.
+_.delay = (func, wait) ->
+  args = _.rest arguments, 2
+  setTimeout((-> func.apply(func, args)), wait)
+
+
+# Memoize an expensive function by storing its results.
+_.memoize = (func, hasher) ->
+  memo = {}
+  hasher or= _.identity
+  ->
+    key = hasher.apply this, arguments
+    return memo[key] if key of memo
+    memo[key] = func.apply this, arguments
+
+
+# Defers a function, scheduling it to run after the current call stack has
+# cleared.
+_.defer = (func) ->
+  _.delay.apply _, [func, 1].concat _.rest arguments
+
+
+# Returns the first function passed as an argument to the second,
+# allowing you to adjust arguments, run code before and after, and
+# conditionally execute the original function.
+_.wrap = (func, wrapper) ->
+  -> wrapper.apply wrapper, [func].concat arguments
+
+
+# Returns a function that is the composition of a list of functions, each
+# consuming the return value of the function that follows.
+_.compose = ->
+  funcs = arguments
+  ->
+    args = arguments
+    for i in [funcs.length - 1..0] by -1
+      args = [funcs[i].apply(this, args)]
+    args[0]
+
+
+# Object Functions
+# ----------------
+
+# Retrieve the names of an object's properties.
+_.keys = nativeKeys or (obj) ->
+  return _.range 0, obj.length if _.isArray(obj)
+  key for key, val of obj
+
+
+# Retrieve the values of an object's properties.
+_.values = (obj) ->
+  _.map obj, _.identity
+
+
+# Return a sorted list of the function names available in Underscore.
+_.functions = (obj) ->
+  _.filter(_.keys(obj), (key) -> _.isFunction(obj[key])).sort()
+
+
+# Extend a given object with all of the properties in a source object.
+_.extend = (obj) ->
+  for source in _.rest(arguments)
+    obj[key] = val for key, val of source
+  obj
+
+
+# Create a (shallow-cloned) duplicate of an object.
+_.clone = (obj) ->
+  return obj.slice 0 if _.isArray obj
+  _.extend {}, obj
+
+
+# Invokes interceptor with the obj, and then returns obj.
+# The primary purpose of this method is to "tap into" a method chain,
+# in order to perform operations on intermediate results within
+ the chain.
+_.tap = (obj, interceptor) ->
+  interceptor obj
+  obj
+
+
+# Perform a deep comparison to check if two objects are equal.
+_.isEqual = (a, b) ->
+  # Check object identity.
+  return true if a is b
+  # Different types?
+  atype = typeof(a); btype = typeof(b)
+  return false if atype isnt btype
+  # Basic equality test (watch out for coercions).
+  return true if `a == b`
+  # One is falsy and the other truthy.
+  return false if (!a and b) or (a and !b)
+  # One of them implements an `isEqual()`?
+  return a.isEqual(b) if a.isEqual
+  # Check dates' integer values.
+  return a.getTime() is b.getTime() if _.isDate(a) and _.isDate(b)
+  # Both are NaN?
+  return false if _.isNaN(a) and _.isNaN(b)
+  # Compare regular expressions.
+  if _.isRegExp(a) and _.isRegExp(b)
+    return a.source is b.source and
+           a.global is b.global and
+           a.ignoreCase is b.ignoreCase and
+           a.multiline is b.multiline
+  # If a is not an object by this point, we can't handle it.
+  return false if atype isnt 'object'
+  # Check for different array lengths before comparing contents.
+  return false if a.length and (a.length isnt b.length)
+  # Nothing else worked, deep compare the contents.
+  aKeys = _.keys(a); bKeys = _.keys(b)
+  # Different object sizes?
+  return false if aKeys.length isnt bKeys.length
+  # Recursive comparison of contents.
+  return false for key, val of a when !(key of b) or !_.isEqual(val, b[key])
+  true
+
+
+# Is a given array or object empty?
+_.isEmpty = (obj) ->
+  return obj.length is 0 if _.isArray(obj) or _.isString(obj)
+  return false for own key of obj
+  true
+
+
+# Is a given value a DOM element?
+_.isElement = (obj) -> obj and obj.nodeType is 1
+
+
+# Is a given value an array?
+_.isArray = nativeIsArray or (obj) -> !!(obj and obj.concat and obj.unshift and not obj.callee)
+
+
+# Is a given variable an arguments object?
+_.isArguments = (obj) -> obj and obj.callee
+
+
+# Is the given value a function?
+_.isFunction = (obj) -> !!(obj and obj.constructor and obj.call and obj.apply)
+
+
+# Is the given value a string?
+_.isString = (obj) -> !!(obj is '' or (obj and obj.charCodeAt and obj.substr))
+
+
+# Is a given value a number?
+_.isNumber = (obj) -> (obj is +obj) or toString.call(obj) is '[object Number]'
+
+
+# Is a given value a boolean?
+_.isBoolean = (obj) -> obj is true or obj is false
+
+
+# Is a given value a Date?
+_.isDate = (obj) -> !!(obj and obj.getTimezoneOffset and obj.setUTCFullYear)
+
+
+# Is the given value a regular expression?
+_.isRegExp = (obj) -> !!(obj and obj.exec and (obj.ignoreCase or obj.ignoreCase is false))
+
+
+# Is the given value NaN -- this one is interesting. `NaN != NaN`, and
+# `isNaN(undefined) == true`, so we make sure it's a number first.
+_.isNaN = (obj) -> _.isNumber(obj) and window.isNaN(obj)
+
+
+# Is a given value equal to null?
+_.isNull = (obj) -> obj is null
+
+
+# Is a given variable undefined?
+_.isUndefined = (obj) -> typeof obj is 'undefined'
+
+
+# Utility Functions
+# -----------------
+
+# Run Underscore.js in noConflict mode, returning the `_` variable to its
+# previous owner. Returns a reference to the Underscore object.
+_.noConflict = ->
+  root._ = previousUnderscore
+  this
+
+
+# Keep the identity function around for default iterators.
+_.identity = (value) -> value
+
+
+# Run a function `n` times.
+_.times = (n, iterator, context) ->
+  iterator.call context, i for i in [0...n]
+
+
+# Break out of the middle of an iteration.
+_.breakLoop = -> throw breaker
+
+
+# Add your own custom functions to the Underscore object, ensuring that
+# they're correctly added to the OOP wrapper as well.
+_.mixin = (obj) ->
+  for name in _.functions(obj)
+    addToWrapper name, _[name] = obj[name]
+
+
+# Generate a unique integer id (unique within the entire client session).
+# Useful for temporary DOM ids.
+idCounter = 0
+_.uniqueId = (prefix) ->
+  (prefix or '') + idCounter++
+
+
+# By default, Underscore uses **ERB**-style template delimiters, change the
+# following template settings to use alternative delimiters.
+_.templateSettings = {
+  start: '<%'
+  end: '%>'
+  interpolate: /<%=(.+?)%>/g
+}
+
+
+# JavaScript templating a-la **ERB**, pilfered from John Resig's
+# *Secrets of the JavaScript Ninja*, page 83.
+# Single-quote fix from Rick Strahl.
+# With alterations for arbitrary delimiters, and to preserve whitespace.
+_.template = (str, data) ->
+  c = _.templateSettings
+  endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g")
+  fn = new Function 'obj',
+    'var p=[],print=function(){p.push.apply(p,arguments);};' +
+    'with(obj||{}){p.push(\'' +
+    str.replace(/\r/g, '\\r')
+       .replace(/\n/g, '\\n')
+       .replace(/\t/g, '\\t')
+       .replace(endMatch,"���")
+       .split("'").join("\\'")
+       .split("���").join("'")
+       .replace(c.interpolate, "',$1,'")
+       .split(c.start).join("');")
+       .split(c.end).join("p.push('") +
+       "');}return p.join('');"
+  if data then fn(data) else fn
+
+
+# Aliases
+# -------
+
+_.forEach = _.each
+_.foldl = _.inject = _.reduce
+_.foldr = _.reduceRight
+_.select = _.filter
+_.all = _.every
+_.any = _.some
+_.contains = _.include
+_.head = _.first
+_.tail = _.rest
+_.methods = _.functions
+
+
+# Setup the OOP Wrapper
+# ---------------------
+
+# If Underscore is called as a function, it returns a wrapped object that
+# can be used OO-style. This wrapper holds altered versions of all the
+# underscore functions. Wrapped objects may be chained.
+wrapper = (obj) ->
+  this._wrapped = obj
+  this
+
+
+# Helper function to continue chaining intermediate results.
+result = (obj, chain) ->
+  if chain then _(obj).chain() else obj
+
+
+# A method to easily add functions to the OOP wrapper.
+addToWrapper = (name, func) ->
+  wrapper.prototype[name] = ->
+    args = _.toArray arguments
+    unshift.call args, this._wrapped
+    result func.apply(_, args), this._chain
+
+
+# Add all ofthe Underscore functions to the wrapper object.
+_.mixin _
+
+
+# Add all mutator Array functions to the wrapper.
+_.each ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], (name) ->
+  method = Array.prototype[name]
+  wrapper.prototype[name] = ->
+    method.apply(this._wrapped, arguments)
+    result(this._wrapped, this._chain)
+
+
+# Add all accessor Array functions to the wrapper.
+_.each ['concat', 'join', 'slice'], (name) ->
+  method = Array.prototype[name]
+  wrapper.prototype[name] = ->
+    result(method.apply(this._wrapped, arguments), this._chain)
+
+
+# Start chaining a wrapped Underscore object.
+wrapper::chain = ->
+  this._chain = true
+  this
+
+
+# Extracts the result from a wrapped and chained object.
+wrapper::value = -> this._wrapped
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-coffeescript</code>.</p>
+
+    <p>The CoffeeScript mode was written by Jeff Pickhardt (<a href="LICENSE">license</a>).</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/commonlisp/commonlisp.js b/app/gui/html/vendor/codemirror/mode/commonlisp/commonlisp.js
new file mode 100644
index 0000000..a0f0732
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/commonlisp/commonlisp.js
@@ -0,0 +1,117 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("commonlisp", function (config) {
+  var assumeBody = /^with|^def|^do|^prog|case$|^cond$|bind$|when$|unless$/;
+  var numLiteral = /^(?:[+\-]?(?:\d+|\d*\.\d+)(?:[efd][+\-]?\d+)?|[+\-]?\d+(?:\/[+\-]?\d+)?|#b[+\-]?[01]+|#o[+\-]?[0-7]+|#x[+\-]?[\da-f]+)/;
+  var symbol = /[^\s'`,@()\[\]";]/;
+  var type;
+
+  function readSym(stream) {
+    var ch;
+    while (ch = stream.next()) {
+      if (ch == "\\") stream.next();
+      else if (!symbol.test(ch)) { stream.backUp(1); break; }
+    }
+    return stream.current();
+  }
+
+  function base(stream, state) {
+    if (stream.eatSpace()) {type = "ws"; return null;}
+    if (stream.match(numLiteral)) return "number";
+    var ch = stream.next();
+    if (ch == "\\") ch = stream.next();
+
+    if (ch == '"') return (state.tokenize = inString)(stream, state);
+    else if (ch == "(") { type = "open"; return "bracket"; }
+    else if (ch == ")" || ch == "]") { type = "close"; return "bracket"; }
+    else if (ch == ";") { stream.skipToEnd(); type = "ws"; return "comment"; }
+    else if (/['`,@]/.test(ch)) return null;
+    else if (ch == "|") {
+      if (stream.skipTo("|")) { stream.next(); return "symbol"; }
+      else { stream.skipToEnd(); return "error"; }
+    } else if (ch == "#") {
+      var ch = stream.next();
+      if (ch == "[") { type = "open"; return "bracket"; }
+      else if (/[+\-=\.']/.test(ch)) return null;
+      else if (/\d/.test(ch) && stream.match(/^\d*#/)) return null;
+      else if (ch == "|") return (state.tokenize = inComment)(stream, state);
+      else if (ch == ":") { readSym(stream); return "meta"; }
+      else return "error";
+    } else {
+      var name = readSym(stream);
+      if (name == ".") return null;
+      type = "symbol";
+      if (name == "nil" || name == "t") return "atom";
+      if (name.charAt(0) == ":") return "keyword";
+      if (name.charAt(0) == "&") return "variable-2";
+      return "variable";
+    }
+  }
+
+  function inString(stream, state) {
+    var escaped = false, next;
+    while (next = stream.next()) {
+      if (next == '"' && !escaped) { state.tokenize = base; break; }
+      escaped = !escaped && next == "\\";
+    }
+    return "string";
+  }
+
+  function inComment(stream, state) {
+    var next, last;
+    while (next = stream.next()) {
+      if (next == "#" && last == "|") { state.tokenize = base; break; }
+      last = next;
+    }
+    type = "ws";
+    return "comment";
+  }
+
+  return {
+    startState: function () {
+      return {ctx: {prev: null, start: 0, indentTo: 0}, tokenize: base};
+    },
+
+    token: function (stream, state) {
+      if (stream.sol() && typeof state.ctx.indentTo != "number")
+        state.ctx.indentTo = state.ctx.start + 1;
+
+      type = null;
+      var style = state.tokenize(stream, state);
+      if (type != "ws") {
+        if (state.ctx.indentTo == null) {
+          if (type == "symbol" && assumeBody.test(stream.current()))
+            state.ctx.indentTo = state.ctx.start + config.indentUnit;
+          else
+            state.ctx.indentTo = "next";
+        } else if (state.ctx.indentTo == "next") {
+          state.ctx.indentTo = stream.column();
+        }
+      }
+      if (type == "open") state.ctx = {prev: state.ctx, start: stream.column(), indentTo: null};
+      else if (type == "close") state.ctx = state.ctx.prev || state.ctx;
+      return style;
+    },
+
+    indent: function (state, _textAfter) {
+      var i = state.ctx.indentTo;
+      return typeof i == "number" ? i : state.ctx.start + 1;
+    },
+
+    lineComment: ";;",
+    blockCommentStart: "#|",
+    blockCommentEnd: "|#"
+  };
+});
+
+CodeMirror.defineMIME("text/x-common-lisp", "commonlisp");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/commonlisp/index.html b/app/gui/html/vendor/codemirror/mode/commonlisp/index.html
new file mode 100644
index 0000000..d48be8d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/commonlisp/index.html
@@ -0,0 +1,177 @@
+<!doctype html>
+
+<title>CodeMirror: Common Lisp mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="commonlisp.js"></script>
+<style>.CodeMirror {background: #f8f8f8;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Common Lisp</a>
+  </ul>
+</div>
+
+<article>
+<h2>Common Lisp mode</h2>
+<form><textarea id="code" name="code">(in-package :cl-postgres)
+
+;; These are used to synthesize reader and writer names for integer
+;; reading/writing functions when the amount of bytes and the
+;; signedness is known. Both the macro that creates the functions and
+;; some macros that use them create names this way.
+(eval-when (:compile-toplevel :load-toplevel :execute)
+  (defun integer-reader-name (bytes signed)
+    (intern (with-standard-io-syntax
+              (format nil "~a~a~a~a" '#:read- (if signed "" '#:u) '#:int bytes))))
+  (defun integer-writer-name (bytes signed)
+    (intern (with-standard-io-syntax
+              (format nil "~a~a~a~a" '#:write- (if signed "" '#:u) '#:int bytes)))))
+
+(defmacro integer-reader (bytes)
+  "Create a function to read integers from a binary stream."
+  (let ((bits (* bytes 8)))
+    (labels ((return-form (signed)
+               (if signed
+                   `(if (logbitp ,(1- bits) result)
+                        (dpb result (byte ,(1- bits) 0) -1)
+                        result)
+                   `result))
+             (generate-reader (signed)
+               `(defun ,(integer-reader-name bytes signed) (socket)
+                  (declare (type stream socket)
+                           #.*optimize*)
+                  ,(if (= bytes 1)
+                       `(let ((result (the (unsigned-byte 8) (read-byte socket))))
+                          (declare (type (unsigned-byte 8) result))
+                          ,(return-form signed))
+                       `(let ((result 0))
+                          (declare (type (unsigned-byte ,bits) result))
+                          ,@(loop :for byte :from (1- bytes) :downto 0
+                                   :collect `(setf (ldb (byte 8 ,(* 8 byte)) result)
+                                                   (the (unsigned-byte 8) (read-byte socket))))
+                          ,(return-form signed))))))
+      `(progn
+;; This causes weird errors on SBCL in some circumstances. Disabled for now.
+;;         (declaim (inline ,(integer-reader-name bytes t)
+;;                          ,(integer-reader-name bytes nil)))
+         (declaim (ftype (function (t) (signed-byte ,bits))
+                         ,(integer-reader-name bytes t)))
+         ,(generate-reader t)
+         (declaim (ftype (function (t) (unsigned-byte ,bits))
+                         ,(integer-reader-name bytes nil)))
+         ,(generate-reader nil)))))
+
+(defmacro integer-writer (bytes)
+  "Create a function to write integers to a binary stream."
+  (let ((bits (* 8 bytes)))
+    `(progn
+      (declaim (inline ,(integer-writer-name bytes t)
+                       ,(integer-writer-name bytes nil)))
+      (defun ,(integer-writer-name bytes nil) (socket value)
+        (declare (type stream socket)
+                 (type (unsigned-byte ,bits) value)
+                 #.*optimize*)
+        ,@(if (= bytes 1)
+              `((write-byte value socket))
+              (loop :for byte :from (1- bytes) :downto 0
+                    :collect `(write-byte (ldb (byte 8 ,(* byte 8)) value)
+                               socket)))
+        (values))
+      (defun ,(integer-writer-name bytes t) (socket value)
+        (declare (type stream socket)
+                 (type (signed-byte ,bits) value)
+                 #.*optimize*)
+        ,@(if (= bytes 1)
+              `((write-byte (ldb (byte 8 0) value) socket))
+              (loop :for byte :from (1- bytes) :downto 0
+                    :collect `(write-byte (ldb (byte 8 ,(* byte 8)) value)
+                               socket)))
+        (values)))))
+
+;; All the instances of the above that we need.
+
+(integer-reader 1)
+(integer-reader 2)
+(integer-reader 4)
+(integer-reader 8)
+
+(integer-writer 1)
+(integer-writer 2)
+(integer-writer 4)
+
+(defun write-bytes (socket bytes)
+  "Write a byte-array to a stream."
+  (declare (type stream socket)
+           (type (simple-array (unsigned-byte 8)) bytes)
+           #.*optimize*)
+  (write-sequence bytes socket))
+
+(defun write-str (socket string)
+  "Write a null-terminated string to a stream \(encoding it when UTF-8
+support is enabled.)."
+  (declare (type stream socket)
+           (type string string)
+           #.*optimize*)
+  (enc-write-string string socket)
+  (write-uint1 socket 0))
+
+(declaim (ftype (function (t unsigned-byte)
+                          (simple-array (unsigned-byte 8) (*)))
+                read-bytes))
+(defun read-bytes (socket length)
+  "Read a byte array of the given length from a stream."
+  (declare (type stream socket)
+           (type fixnum length)
+           #.*optimize*)
+  (let ((result (make-array length :element-type '(unsigned-byte 8))))
+    (read-sequence result socket)
+    result))
+
+(declaim (ftype (function (t) string) read-str))
+(defun read-str (socket)
+  "Read a null-terminated string from a stream. Takes care of encoding
+when UTF-8 support is enabled."
+  (declare (type stream socket)
+           #.*optimize*)
+  (enc-read-string socket :null-terminated t))
+
+(defun skip-bytes (socket length)
+  "Skip a given number of bytes in a binary stream."
+  (declare (type stream socket)
+           (type (unsigned-byte 32) length)
+           #.*optimize*)
+  (dotimes (i length)
+    (read-byte socket)))
+
+(defun skip-str (socket)
+  "Skip a null-terminated string."
+  (declare (type stream socket)
+           #.*optimize*)
+  (loop :for char :of-type fixnum = (read-byte socket)
+        :until (zerop char)))
+
+(defun ensure-socket-is-closed (socket &key abort)
+  (when (open-stream-p socket)
+    (handler-case
+        (close socket :abort abort)
+      (error (error)
+        (warn "Ignoring the error which happened while trying to close PostgreSQL socket: ~A" error)))))
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {lineNumbers: true});
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-common-lisp</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/css/css.js b/app/gui/html/vendor/codemirror/mode/css/css.js
new file mode 100644
index 0000000..f8fc5ce
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/css/css.js
@@ -0,0 +1,701 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("css", function(config, parserConfig) {
+  if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
+
+  var indentUnit = config.indentUnit,
+      tokenHooks = parserConfig.tokenHooks,
+      mediaTypes = parserConfig.mediaTypes || {},
+      mediaFeatures = parserConfig.mediaFeatures || {},
+      propertyKeywords = parserConfig.propertyKeywords || {},
+      colorKeywords = parserConfig.colorKeywords || {},
+      valueKeywords = parserConfig.valueKeywords || {},
+      fontProperties = parserConfig.fontProperties || {},
+      allowNested = parserConfig.allowNested;
+
+  var type, override;
+  function ret(style, tp) { type = tp; return style; }
+
+  // Tokenizers
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+    if (tokenHooks[ch]) {
+      var result = tokenHooks[ch](stream, state);
+      if (result !== false) return result;
+    }
+    if (ch == "@") {
+      stream.eatWhile(/[\w\\\-]/);
+      return ret("def", stream.current());
+    } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
+      return ret(null, "compare");
+    } else if (ch == "\"" || ch == "'") {
+      state.tokenize = tokenString(ch);
+      return state.tokenize(stream, state);
+    } else if (ch == "#") {
+      stream.eatWhile(/[\w\\\-]/);
+      return ret("atom", "hash");
+    } else if (ch == "!") {
+      stream.match(/^\s*\w*/);
+      return ret("keyword", "important");
+    } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
+      stream.eatWhile(/[\w.%]/);
+      return ret("number", "unit");
+    } else if (ch === "-") {
+      if (/[\d.]/.test(stream.peek())) {
+        stream.eatWhile(/[\w.%]/);
+        return ret("number", "unit");
+      } else if (stream.match(/^[^-]+-/)) {
+        return ret("meta", "meta");
+      }
+    } else if (/[,+>*\/]/.test(ch)) {
+      return ret(null, "select-op");
+    } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
+      return ret("qualifier", "qualifier");
+    } else if (/[:;{}\[\]\(\)]/.test(ch)) {
+      return ret(null, ch);
+    } else if (ch == "u" && stream.match("rl(")) {
+      stream.backUp(1);
+      state.tokenize = tokenParenthesized;
+      return ret("property", "word");
+    } else if (/[\w\\\-]/.test(ch)) {
+      stream.eatWhile(/[\w\\\-]/);
+      return ret("property", "word");
+    } else {
+      return ret(null, null);
+    }
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, ch;
+      while ((ch = stream.next()) != null) {
+        if (ch == quote && !escaped) {
+          if (quote == ")") stream.backUp(1);
+          break;
+        }
+        escaped = !escaped && ch == "\\";
+      }
+      if (ch == quote || !escaped && quote != ")") state.tokenize = null;
+      return ret("string", "string");
+    };
+  }
+
+  function tokenParenthesized(stream, state) {
+    stream.next(); // Must be '('
+    if (!stream.match(/\s*[\"\']/, false))
+      state.tokenize = tokenString(")");
+    else
+      state.tokenize = null;
+    return ret(null, "(");
+  }
+
+  // Context management
+
+  function Context(type, indent, prev) {
+    this.type = type;
+    this.indent = indent;
+    this.prev = prev;
+  }
+
+  function pushContext(state, stream, type) {
+    state.context = new Context(type, stream.indentation() + indentUnit, state.context);
+    return type;
+  }
+
+  function popContext(state) {
+    state.context = state.context.prev;
+    return state.context.type;
+  }
+
+  function pass(type, stream, state) {
+    return states[state.context.type](type, stream, state);
+  }
+  function popAndPass(type, stream, state, n) {
+    for (var i = n || 1; i > 0; i--)
+      state.context = state.context.prev;
+    return pass(type, stream, state);
+  }
+
+  // Parser
+
+  function wordAsValue(stream) {
+    var word = stream.current().toLowerCase();
+    if (valueKeywords.hasOwnProperty(word))
+      override = "atom";
+    else if (colorKeywords.hasOwnProperty(word))
+      override = "keyword";
+    else
+      override = "variable";
+  }
+
+  var states = {};
+
+  states.top = function(type, stream, state) {
+    if (type == "{") {
+      return pushContext(state, stream, "block");
+    } else if (type == "}" && state.context.prev) {
+      return popContext(state);
+    } else if (type == "@media") {
+      return pushContext(state, stream, "media");
+    } else if (type == "@font-face") {
+      return "font_face_before";
+    } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
+      return "keyframes";
+    } else if (type && type.charAt(0) == "@") {
+      return pushContext(state, stream, "at");
+    } else if (type == "hash") {
+      override = "builtin";
+    } else if (type == "word") {
+      override = "tag";
+    } else if (type == "variable-definition") {
+      return "maybeprop";
+    } else if (type == "interpolation") {
+      return pushContext(state, stream, "interpolation");
+    } else if (type == ":") {
+      return "pseudo";
+    } else if (allowNested && type == "(") {
+      return pushContext(state, stream, "params");
+    }
+    return state.context.type;
+  };
+
+  states.block = function(type, stream, state) {
+    if (type == "word") {
+      if (propertyKeywords.hasOwnProperty(stream.current().toLowerCase())) {
+        override = "property";
+        return "maybeprop";
+      } else if (allowNested) {
+        override = stream.match(/^\s*:/, false) ? "property" : "tag";
+        return "block";
+      } else {
+        override += " error";
+        return "maybeprop";
+      }
+    } else if (type == "meta") {
+      return "block";
+    } else if (!allowNested && (type == "hash" || type == "qualifier")) {
+      override = "error";
+      return "block";
+    } else {
+      return states.top(type, stream, state);
+    }
+  };
+
+  states.maybeprop = function(type, stream, state) {
+    if (type == ":") return pushContext(state, stream, "prop");
+    return pass(type, stream, state);
+  };
+
+  states.prop = function(type, stream, state) {
+    if (type == ";") return popContext(state);
+    if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
+    if (type == "}" || type == "{") return popAndPass(type, stream, state);
+    if (type == "(") return pushContext(state, stream, "parens");
+
+    if (type == "hash" && !/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
+      override += " error";
+    } else if (type == "word") {
+      wordAsValue(stream);
+    } else if (type == "interpolation") {
+      return pushContext(state, stream, "interpolation");
+    }
+    return "prop";
+  };
+
+  states.propBlock = function(type, _stream, state) {
+    if (type == "}") return popContext(state);
+    if (type == "word") { override = "property"; return "maybeprop"; }
+    return state.context.type;
+  };
+
+  states.parens = function(type, stream, state) {
+    if (type == "{" || type == "}") return popAndPass(type, stream, state);
+    if (type == ")") return popContext(state);
+    return "parens";
+  };
+
+  states.pseudo = function(type, stream, state) {
+    if (type == "word") {
+      override = "variable-3";
+      return state.context.type;
+    }
+    return pass(type, stream, state);
+  };
+
+  states.media = function(type, stream, state) {
+    if (type == "(") return pushContext(state, stream, "media_parens");
+    if (type == "}") return popAndPass(type, stream, state);
+    if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
+
+    if (type == "word") {
+      var word = stream.current().toLowerCase();
+      if (word == "only" || word == "not" || word == "and")
+        override = "keyword";
+      else if (mediaTypes.hasOwnProperty(word))
+        override = "attribute";
+      else if (mediaFeatures.hasOwnProperty(word))
+        override = "property";
+      else
+        override = "error";
+    }
+    return state.context.type;
+  };
+
+  states.media_parens = function(type, stream, state) {
+    if (type == ")") return popContext(state);
+    if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
+    return states.media(type, stream, state);
+  };
+
+  states.font_face_before = function(type, stream, state) {
+    if (type == "{")
+      return pushContext(state, stream, "font_face");
+    return pass(type, stream, state);
+  };
+
+  states.font_face = function(type, stream, state) {
+    if (type == "}") return popContext(state);
+    if (type == "word") {
+      if (!fontProperties.hasOwnProperty(stream.current().toLowerCase()))
+        override = "error";
+      else
+        override = "property";
+      return "maybeprop";
+    }
+    return "font_face";
+  };
+
+  states.keyframes = function(type, stream, state) {
+    if (type == "word") { override = "variable"; return "keyframes"; }
+    if (type == "{") return pushContext(state, stream, "top");
+    return pass(type, stream, state);
+  };
+
+  states.at = function(type, stream, state) {
+    if (type == ";") return popContext(state);
+    if (type == "{" || type == "}") return popAndPass(type, stream, state);
+    if (type == "word") override = "tag";
+    else if (type == "hash") override = "builtin";
+    return "at";
+  };
+
+  states.interpolation = function(type, stream, state) {
+    if (type == "}") return popContext(state);
+    if (type == "{" || type == ";") return popAndPass(type, stream, state);
+    if (type != "variable") override = "error";
+    return "interpolation";
+  };
+
+  states.params = function(type, stream, state) {
+    if (type == ")") return popContext(state);
+    if (type == "{" || type == "}") return popAndPass(type, stream, state);
+    if (type == "word") wordAsValue(stream);
+    return "params";
+  };
+
+  return {
+    startState: function(base) {
+      return {tokenize: null,
+              state: "top",
+              context: new Context("top", base || 0, null)};
+    },
+
+    token: function(stream, state) {
+      if (!state.tokenize && stream.eatSpace()) return null;
+      var style = (state.tokenize || tokenBase)(stream, state);
+      if (style && typeof style == "object") {
+        type = style[1];
+        style = style[0];
+      }
+      override = style;
+      state.state = states[state.state](type, stream, state);
+      return override;
+    },
+
+    indent: function(state, textAfter) {
+      var cx = state.context, ch = textAfter && textAfter.charAt(0);
+      var indent = cx.indent;
+      if (cx.type == "prop" && ch == "}") cx = cx.prev;
+      if (cx.prev &&
+          (ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "font_face") ||
+           ch == ")" && (cx.type == "parens" || cx.type == "params" || cx.type == "media_parens") ||
+           ch == "{" && (cx.type == "at" || cx.type == "media"))) {
+        indent = cx.indent - indentUnit;
+        cx = cx.prev;
+      }
+      return indent;
+    },
+
+    electricChars: "}",
+    blockCommentStart: "/*",
+    blockCommentEnd: "*/",
+    fold: "brace"
+  };
+});
+
+  function keySet(array) {
+    var keys = {};
+    for (var i = 0; i < array.length; ++i) {
+      keys[array[i]] = true;
+    }
+    return keys;
+  }
+
+  var mediaTypes_ = [
+    "all", "aural", "braille", "handheld", "print", "projection", "screen",
+    "tty", "tv", "embossed"
+  ], mediaTypes = keySet(mediaTypes_);
+
+  var mediaFeatures_ = [
+    "width", "min-width", "max-width", "height", "min-height", "max-height",
+    "device-width", "min-device-width", "max-device-width", "device-height",
+    "min-device-height", "max-device-height", "aspect-ratio",
+    "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
+    "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
+    "max-color", "color-index", "min-color-index", "max-color-index",
+    "monochrome", "min-monochrome", "max-monochrome", "resolution",
+    "min-resolution", "max-resolution", "scan", "grid"
+  ], mediaFeatures = keySet(mediaFeatures_);
+
+  var propertyKeywords_ = [
+    "align-content", "align-items", "align-self", "alignment-adjust",
+    "alignment-baseline", "anchor-point", "animation", "animation-delay",
+    "animation-direction", "animation-duration", "animation-fill-mode",
+    "animation-iteration-count", "animation-name", "animation-play-state",
+    "animation-timing-function", "appearance", "azimuth", "backface-visibility",
+    "background", "background-attachment", "background-clip", "background-color",
+    "background-image", "background-origin", "background-position",
+    "background-repeat", "background-size", "baseline-shift", "binding",
+    "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
+    "bookmark-target", "border", "border-bottom", "border-bottom-color",
+    "border-bottom-left-radius", "border-bottom-right-radius",
+    "border-bottom-style", "border-bottom-width", "border-collapse",
+    "border-color", "border-image", "border-image-outset",
+    "border-image-repeat", "border-image-slice", "border-image-source",
+    "border-image-width", "border-left", "border-left-color",
+    "border-left-style", "border-left-width", "border-radius", "border-right",
+    "border-right-color", "border-right-style", "border-right-width",
+    "border-spacing", "border-style", "border-top", "border-top-color",
+    "border-top-left-radius", "border-top-right-radius", "border-top-style",
+    "border-top-width", "border-width", "bottom", "box-decoration-break",
+    "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
+    "caption-side", "clear", "clip", "color", "color-profile", "column-count",
+    "column-fill", "column-gap", "column-rule", "column-rule-color",
+    "column-rule-style", "column-rule-width", "column-span", "column-width",
+    "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
+    "cue-after", "cue-before", "cursor", "direction", "display",
+    "dominant-baseline", "drop-initial-after-adjust",
+    "drop-initial-after-align", "drop-initial-before-adjust",
+    "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
+    "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
+    "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
+    "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
+    "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
+    "font-stretch", "font-style", "font-synthesis", "font-variant",
+    "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
+    "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
+    "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
+    "grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end",
+    "grid-column-start", "grid-row", "grid-row-end", "grid-row-start",
+    "grid-template", "grid-template-areas", "grid-template-columns",
+    "grid-template-rows", "hanging-punctuation", "height", "hyphens",
+    "icon", "image-orientation", "image-rendering", "image-resolution",
+    "inline-box-align", "justify-content", "left", "letter-spacing",
+    "line-break", "line-height", "line-stacking", "line-stacking-ruby",
+    "line-stacking-shift", "line-stacking-strategy", "list-style",
+    "list-style-image", "list-style-position", "list-style-type", "margin",
+    "margin-bottom", "margin-left", "margin-right", "margin-top",
+    "marker-offset", "marks", "marquee-direction", "marquee-loop",
+    "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
+    "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
+    "nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline",
+    "outline-color", "outline-offset", "outline-style", "outline-width",
+    "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
+    "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
+    "page", "page-break-after", "page-break-before", "page-break-inside",
+    "page-policy", "pause", "pause-after", "pause-before", "perspective",
+    "perspective-origin", "pitch", "pitch-range", "play-during", "position",
+    "presentation-level", "punctuation-trim", "quotes", "region-break-after",
+    "region-break-before", "region-break-inside", "region-fragment",
+    "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
+    "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
+    "ruby-position", "ruby-span", "shape-inside", "shape-outside", "size",
+    "speak", "speak-as", "speak-header",
+    "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
+    "tab-size", "table-layout", "target", "target-name", "target-new",
+    "target-position", "text-align", "text-align-last", "text-decoration",
+    "text-decoration-color", "text-decoration-line", "text-decoration-skip",
+    "text-decoration-style", "text-emphasis", "text-emphasis-color",
+    "text-emphasis-position", "text-emphasis-style", "text-height",
+    "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
+    "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
+    "text-wrap", "top", "transform", "transform-origin", "transform-style",
+    "transition", "transition-delay", "transition-duration",
+    "transition-property", "transition-timing-function", "unicode-bidi",
+    "vertical-align", "visibility", "voice-balance", "voice-duration",
+    "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
+    "voice-volume", "volume", "white-space", "widows", "width", "word-break",
+    "word-spacing", "word-wrap", "z-index", "zoom",
+    // SVG-specific
+    "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
+    "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
+    "color-interpolation", "color-interpolation-filters", "color-profile",
+    "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
+    "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
+    "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
+    "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
+    "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
+    "glyph-orientation-vertical", "kerning", "text-anchor", "writing-mode"
+  ], propertyKeywords = keySet(propertyKeywords_);
+
+  var colorKeywords_ = [
+    "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
+    "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
+    "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
+    "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
+    "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
+    "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
+    "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
+    "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
+    "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
+    "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
+    "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
+    "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
+    "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
+    "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
+    "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
+    "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
+    "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
+    "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
+    "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
+    "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
+    "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
+    "purple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon",
+    "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
+    "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
+    "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
+    "whitesmoke", "yellow", "yellowgreen"
+  ], colorKeywords = keySet(colorKeywords_);
+
+  var valueKeywords_ = [
+    "above", "absolute", "activeborder", "activecaption", "afar",
+    "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
+    "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
+    "arabic-indic", "armenian", "asterisks", "auto", "avoid", "avoid-column", "avoid-page",
+    "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
+    "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
+    "both", "bottom", "break", "break-all", "break-word", "button", "button-bevel",
+    "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
+    "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
+    "cell", "center", "checkbox", "circle", "cjk-earthly-branch",
+    "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
+    "col-resize", "collapse", "column", "compact", "condensed", "contain", "content",
+    "content-box", "context-menu", "continuous", "copy", "cover", "crop",
+    "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
+    "decimal-leading-zero", "default", "default-button", "destination-atop",
+    "destination-in", "destination-out", "destination-over", "devanagari",
+    "disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
+    "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
+    "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
+    "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
+    "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
+    "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
+    "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
+    "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
+    "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et",
+    "ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed",
+    "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes",
+    "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
+    "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
+    "help", "hidden", "hide", "higher", "highlight", "highlighttext",
+    "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
+    "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
+    "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
+    "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
+    "italic", "justify", "kannada", "katakana", "katakana-iroha", "keep-all", "khmer",
+    "landscape", "lao", "large", "larger", "left", "level", "lighter",
+    "line-through", "linear", "lines", "list-item", "listbox", "listitem",
+    "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
+    "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
+    "lower-roman", "lowercase", "ltr", "malayalam", "match",
+    "media-controls-background", "media-current-time-display",
+    "media-fullscreen-button", "media-mute-button", "media-play-button",
+    "media-return-to-realtime-button", "media-rewind-button",
+    "media-seek-back-button", "media-seek-forward-button", "media-slider",
+    "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
+    "media-volume-slider-container", "media-volume-sliderthumb", "medium",
+    "menu", "menulist", "menulist-button", "menulist-text",
+    "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
+    "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
+    "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
+    "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
+    "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
+    "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
+    "outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
+    "painted", "page", "paused", "persian", "plus-darker", "plus-lighter", "pointer",
+    "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
+    "radio", "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region",
+    "relative", "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
+    "ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
+    "s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
+    "searchfield-cancel-button", "searchfield-decoration",
+    "searchfield-results-button", "searchfield-results-decoration",
+    "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
+    "single", "skip-white-space", "slide", "slider-horizontal",
+    "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
+    "small", "small-caps", "small-caption", "smaller", "solid", "somali",
+    "source-atop", "source-in", "source-out", "source-over", "space", "square",
+    "square-button", "start", "static", "status-bar", "stretch", "stroke",
+    "sub", "subpixel-antialiased", "super", "sw-resize", "table",
+    "table-caption", "table-cell", "table-column", "table-column-group",
+    "table-footer-group", "table-header-group", "table-row", "table-row-group",
+    "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
+    "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
+    "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
+    "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
+    "transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
+    "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
+    "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
+    "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
+    "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
+    "window", "windowframe", "windowtext", "x-large", "x-small", "xor",
+    "xx-large", "xx-small"
+  ], valueKeywords = keySet(valueKeywords_);
+
+  var fontProperties_ = [
+    "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
+    "font-stretch", "font-weight", "font-style"
+  ], fontProperties = keySet(fontProperties_);
+
+  var allWords = mediaTypes_.concat(mediaFeatures_).concat(propertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);
+  CodeMirror.registerHelper("hintWords", "css", allWords);
+
+  function tokenCComment(stream, state) {
+    var maybeEnd = false, ch;
+    while ((ch = stream.next()) != null) {
+      if (maybeEnd && ch == "/") {
+        state.tokenize = null;
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return ["comment", "comment"];
+  }
+
+  function tokenSGMLComment(stream, state) {
+    if (stream.skipTo("-->")) {
+      stream.match("-->");
+      state.tokenize = null;
+    } else {
+      stream.skipToEnd();
+    }
+    return ["comment", "comment"];
+  }
+
+  CodeMirror.defineMIME("text/css", {
+    mediaTypes: mediaTypes,
+    mediaFeatures: mediaFeatures,
+    propertyKeywords: propertyKeywords,
+    colorKeywords: colorKeywords,
+    valueKeywords: valueKeywords,
+    fontProperties: fontProperties,
+    tokenHooks: {
+      "<": function(stream, state) {
+        if (!stream.match("!--")) return false;
+        state.tokenize = tokenSGMLComment;
+        return tokenSGMLComment(stream, state);
+      },
+      "/": function(stream, state) {
+        if (!stream.eat("*")) return false;
+        state.tokenize = tokenCComment;
+        return tokenCComment(stream, state);
+      }
+    },
+    name: "css"
+  });
+
+  CodeMirror.defineMIME("text/x-scss", {
+    mediaTypes: mediaTypes,
+    mediaFeatures: mediaFeatures,
+    propertyKeywords: propertyKeywords,
+    colorKeywords: colorKeywords,
+    valueKeywords: valueKeywords,
+    fontProperties: fontProperties,
+    allowNested: true,
+    tokenHooks: {
+      "/": function(stream, state) {
+        if (stream.eat("/")) {
+          stream.skipToEnd();
+          return ["comment", "comment"];
+        } else if (stream.eat("*")) {
+          state.tokenize = tokenCComment;
+          return tokenCComment(stream, state);
+        } else {
+          return ["operator", "operator"];
+        }
+      },
+      ":": function(stream) {
+        if (stream.match(/\s*{/))
+          return [null, "{"];
+        return false;
+      },
+      "$": function(stream) {
+        stream.match(/^[\w-]+/);
+        if (stream.match(/^\s*:/, false))
+          return ["variable-2", "variable-definition"];
+        return ["variable-2", "variable"];
+      },
+      "#": function(stream) {
+        if (!stream.eat("{")) return false;
+        return [null, "interpolation"];
+      }
+    },
+    name: "css",
+    helperType: "scss"
+  });
+
+  CodeMirror.defineMIME("text/x-less", {
+    mediaTypes: mediaTypes,
+    mediaFeatures: mediaFeatures,
+    propertyKeywords: propertyKeywords,
+    colorKeywords: colorKeywords,
+    valueKeywords: valueKeywords,
+    fontProperties: fontProperties,
+    allowNested: true,
+    tokenHooks: {
+      "/": function(stream, state) {
+        if (stream.eat("/")) {
+          stream.skipToEnd();
+          return ["comment", "comment"];
+        } else if (stream.eat("*")) {
+          state.tokenize = tokenCComment;
+          return tokenCComment(stream, state);
+        } else {
+          return ["operator", "operator"];
+        }
+      },
+      "@": function(stream) {
+        if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
+        stream.eatWhile(/[\w\\\-]/);
+        if (stream.match(/^\s*:/, false))
+          return ["variable-2", "variable-definition"];
+        return ["variable-2", "variable"];
+      },
+      "&": function() {
+        return ["atom", "atom"];
+      }
+    },
+    name: "css",
+    helperType: "less"
+  });
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/css/index.html b/app/gui/html/vendor/codemirror/mode/css/index.html
new file mode 100644
index 0000000..80ef518
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/css/index.html
@@ -0,0 +1,70 @@
+<!doctype html>
+
+<title>CodeMirror: CSS mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="css.js"></script>
+<style>.CodeMirror {background: #f8f8f8;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">CSS</a>
+  </ul>
+</div>
+
+<article>
+<h2>CSS mode</h2>
+<form><textarea id="code" name="code">
+/* Some example CSS */
+
+ at import url("something.css");
+
+body {
+  margin: 0;
+  padding: 3em 6em;
+  font-family: tahoma, arial, sans-serif;
+  color: #000;
+}
+
+#navigation a {
+  font-weight: bold;
+  text-decoration: none !important;
+}
+
+h1 {
+  font-size: 2.5em;
+}
+
+h2 {
+  font-size: 1.7em;
+}
+
+h1:before, h2:before {
+  content: "::";
+}
+
+code {
+  font-family: courier, monospace;
+  font-size: 80%;
+  color: #418A8A;
+}
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/css</code>, <code>text/x-scss</code> (<a href="scss.html">demo</a>), <code>text/x-less</code> (<a href="less.html">demo</a>).</p>
+
+    <p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#css_*">normal</a>,  <a href="../../test/index.html#verbose,css_*">verbose</a>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/css/less.html b/app/gui/html/vendor/codemirror/mode/css/less.html
new file mode 100644
index 0000000..1030ca4
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/css/less.html
@@ -0,0 +1,152 @@
+<!doctype html>
+
+<title>CodeMirror: LESS mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="css.js"></script>
+<style>.CodeMirror {border: 1px solid #ddd; line-height: 1.2;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">LESS</a>
+  </ul>
+</div>
+
+<article>
+<h2>LESS mode</h2>
+<form><textarea id="code" name="code">@media screen and (device-aspect-ratio: 16/9) { … }
+ at media screen and (device-aspect-ratio: 1280/720) { … }
+ at media screen and (device-aspect-ratio: 2560/1440) { … }
+
+html:lang(fr-be)
+
+tr:nth-child(2n+1) /* represents every odd row of an HTML table */
+
+img:nth-of-type(2n+1) { float: right; }
+img:nth-of-type(2n) { float: left; }
+
+body > h2:not(:first-of-type):not(:last-of-type)
+
+html|*:not(:link):not(:visited)
+*|*:not(:hover)
+p::first-line { text-transform: uppercase }
+
+ at namespace foo url(http://www.example.com);
+foo|h1 { color: blue }  /* first rule */
+
+span[hello="Ocean"][goodbye="Land"]
+
+E[foo]{
+  padding:65px;
+}
+
+input[type="search"]::-webkit-search-decoration,
+input[type="search"]::-webkit-search-cancel-button {
+  -webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5
+}
+button::-moz-focus-inner,
+input::-moz-focus-inner { // Inner padding and border oddities in FF3/4
+  padding: 0;
+  border: 0;
+}
+.btn {
+  // reset here as of 2.0.3 due to Recess property order
+  border-color: #ccc;
+  border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);
+}
+fieldset span button, fieldset span input[type="file"] {
+  font-size:12px;
+	font-family:Arial, Helvetica, sans-serif;
+}
+
+.rounded-corners (@radius: 5px) {
+  border-radius: @radius;
+  -webkit-border-radius: @radius;
+  -moz-border-radius: @radius;
+}
+
+ at import url("something.css");
+
+ at light-blue:   hsl(190, 50%, 65%);
+
+#menu {
+  position: absolute;
+  width: 100%;
+  z-index: 3;
+  clear: both;
+  display: block;
+  background-color: @blue;
+  height: 42px;
+  border-top: 2px solid lighten(@alpha-blue, 20%);
+  border-bottom: 2px solid darken(@alpha-blue, 25%);
+  .box-shadow(0, 1px, 8px, 0.6);
+  -moz-box-shadow: 0 0 0 #000; // Because firefox sucks.
+
+  &.docked {
+    background-color: hsla(210, 60%, 40%, 0.4);
+  }
+  &:hover {
+    background-color: @blue;
+  }
+
+  #dropdown {
+    margin: 0 0 0 117px;
+    padding: 0;
+    padding-top: 5px;
+    display: none;
+    width: 190px;
+    border-top: 2px solid @medium;
+    color: @highlight;
+    border: 2px solid darken(@medium, 25%);
+    border-left-color: darken(@medium, 15%);
+    border-right-color: darken(@medium, 15%);
+    border-top-width: 0;
+    background-color: darken(@medium, 10%);
+    ul {
+      padding: 0px;  
+    }
+    li {
+      font-size: 14px;
+      display: block;
+      text-align: left;
+      padding: 0;
+      border: 0;
+      a {
+        display: block;
+        padding: 0px 15px;  
+        text-decoration: none;
+        color: white;  
+        &:hover {
+          background-color: darken(@medium, 15%);
+          text-decoration: none;
+        }
+      }
+    }
+    .border-radius(5px, bottom);
+    .box-shadow(0, 6px, 8px, 0.5);
+  }
+}
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers : true,
+        matchBrackets : true,
+        mode: "text/x-less"
+      });
+    </script>
+
+    <p>The LESS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>.</p>
+
+    <p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#less_*">normal</a>,  <a href="../../test/index.html#verbose,less_*">verbose</a>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/css/less_test.js b/app/gui/html/vendor/codemirror/mode/css/less_test.js
new file mode 100644
index 0000000..ea64f91
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/css/less_test.js
@@ -0,0 +1,48 @@
+(function() {
+  "use strict";
+
+  var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-less");
+  function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "less"); }
+
+  MT("variable",
+     "[variable-2 @base]: [atom #f04615];",
+     "[qualifier .class] {",
+     "  [property width]: [variable percentage]([number 0.5]); [comment // returns `50%`]",
+     "  [property color]: [variable saturate]([variable-2 @base], [number 5%]);",
+     "}");
+
+  MT("amp",
+     "[qualifier .child], [qualifier .sibling] {",
+     "  [qualifier .parent] [atom &] {",
+     "    [property color]: [keyword black];",
+     "  }",
+     "  [atom &] + [atom &] {",
+     "    [property color]: [keyword red];",
+     "  }",
+     "}");
+
+  MT("mixin",
+     "[qualifier .mixin] ([variable dark]; [variable-2 @color]) {",
+     "  [property color]: [variable darken]([variable-2 @color], [number 10%]);",
+     "}",
+     "[qualifier .mixin] ([variable light]; [variable-2 @color]) {",
+     "  [property color]: [variable lighten]([variable-2 @color], [number 10%]);",
+     "}",
+     "[qualifier .mixin] ([variable-2 @_]; [variable-2 @color]) {",
+     "  [property display]: [atom block];",
+     "}",
+     "[variable-2 @switch]: [variable light];",
+     "[qualifier .class] {",
+     "  [qualifier .mixin]([variable-2 @switch]; [atom #888]);",
+     "}");
+
+  MT("nest",
+     "[qualifier .one] {",
+     "  [def @media] ([property width]: [number 400px]) {",
+     "    [property font-size]: [number 1.2em];",
+     "    [def @media] [attribute print] [keyword and] [property color] {",
+     "      [property color]: [keyword blue];",
+     "    }",
+     "  }",
+     "}");
+})();
diff --git a/app/gui/html/vendor/codemirror/mode/css/scss.html b/app/gui/html/vendor/codemirror/mode/css/scss.html
new file mode 100644
index 0000000..0677d08
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/css/scss.html
@@ -0,0 +1,157 @@
+<!doctype html>
+
+<title>CodeMirror: SCSS mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="css.js"></script>
+<style>.CodeMirror {background: #f8f8f8;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">SCSS</a>
+  </ul>
+</div>
+
+<article>
+<h2>SCSS mode</h2>
+<form><textarea id="code" name="code">
+/* Some example SCSS */
+
+ at import "compass/css3";
+$variable: #333;
+
+$blue: #3bbfce;
+$margin: 16px;
+
+.content-navigation {
+  #nested {
+    background-color: black;
+  }
+  border-color: $blue;
+  color:
+    darken($blue, 9%);
+}
+
+.border {
+  padding: $margin / 2;
+  margin: $margin / 2;
+  border-color: $blue;
+}
+
+ at mixin table-base {
+  th {
+    text-align: center;
+    font-weight: bold;
+  }
+  td, th {padding: 2px}
+}
+
+table.hl {
+  margin: 2em 0;
+  td.ln {
+    text-align: right;
+  }
+}
+
+li {
+  font: {
+    family: serif;
+    weight: bold;
+    size: 1.2em;
+  }
+}
+
+ at mixin left($dist) {
+  float: left;
+  margin-left: $dist;
+}
+
+#data {
+  @include left(10px);
+  @include table-base;
+}
+
+.source {
+  @include flow-into(target);
+  border: 10px solid green;
+  margin: 20px;
+  width: 200px; }
+
+.new-container {
+  @include flow-from(target);
+  border: 10px solid red;
+  margin: 20px;
+  width: 200px; }
+
+body {
+  margin: 0;
+  padding: 3em 6em;
+  font-family: tahoma, arial, sans-serif;
+  color: #000;
+}
+
+ at mixin yellow() {
+  background: yellow;
+}
+
+.big {
+  font-size: 14px;
+}
+
+.nested {
+  @include border-radius(3px);
+  @extend .big;
+  p {
+    background: whitesmoke;
+    a {
+      color: red;
+    }
+  }
+}
+
+#navigation a {
+  font-weight: bold;
+  text-decoration: none !important;
+}
+
+h1 {
+  font-size: 2.5em;
+}
+
+h2 {
+  font-size: 1.7em;
+}
+
+h1:before, h2:before {
+  content: "::";
+}
+
+code {
+  font-family: courier, monospace;
+  font-size: 80%;
+  color: #418A8A;
+}
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        mode: "text/x-scss"
+      });
+    </script>
+
+    <p>The SCSS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>.</p>
+
+    <p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#scss_*">normal</a>,  <a href="../../test/index.html#verbose,scss_*">verbose</a>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/css/scss_test.js b/app/gui/html/vendor/codemirror/mode/css/scss_test.js
new file mode 100644
index 0000000..c51cb42
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/css/scss_test.js
@@ -0,0 +1,107 @@
+(function() {
+  var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss");
+  function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); }
+
+  MT('url_with_quotation',
+    "[tag foo] { [property background]:[atom url]([string test.jpg]) }");
+
+  MT('url_with_double_quotes',
+    "[tag foo] { [property background]:[atom url]([string \"test.jpg\"]) }");
+
+  MT('url_with_single_quotes',
+    "[tag foo] { [property background]:[atom url]([string \'test.jpg\']) }");
+
+  MT('string',
+    "[def @import] [string \"compass/css3\"]");
+
+  MT('important_keyword',
+    "[tag foo] { [property background]:[atom url]([string \'test.jpg\']) [keyword !important] }");
+
+  MT('variable',
+    "[variable-2 $blue]:[atom #333]");
+
+  MT('variable_as_attribute',
+    "[tag foo] { [property color]:[variable-2 $blue] }");
+
+  MT('numbers',
+    "[tag foo] { [property padding]:[number 10px] [number 10] [number 10em] [number 8in] }");
+
+  MT('number_percentage',
+    "[tag foo] { [property width]:[number 80%] }");
+
+  MT('selector',
+    "[builtin #hello][qualifier .world]{}");
+
+  MT('singleline_comment',
+    "[comment // this is a comment]");
+
+  MT('multiline_comment',
+    "[comment /*foobar*/]");
+
+  MT('attribute_with_hyphen',
+    "[tag foo] { [property font-size]:[number 10px] }");
+
+  MT('string_after_attribute',
+    "[tag foo] { [property content]:[string \"::\"] }");
+
+  MT('directives',
+    "[def @include] [qualifier .mixin]");
+
+  MT('basic_structure',
+    "[tag p] { [property background]:[keyword red]; }");
+
+  MT('nested_structure',
+    "[tag p] { [tag a] { [property color]:[keyword red]; } }");
+
+  MT('mixin',
+    "[def @mixin] [tag table-base] {}");
+
+  MT('number_without_semicolon',
+    "[tag p] {[property width]:[number 12]}",
+    "[tag a] {[property color]:[keyword red];}");
+
+  MT('atom_in_nested_block',
+    "[tag p] { [tag a] { [property color]:[atom #000]; } }");
+
+  MT('interpolation_in_property',
+    "[tag foo] { #{[variable-2 $hello]}:[number 2]; }");
+
+  MT('interpolation_in_selector',
+    "[tag foo]#{[variable-2 $hello]} { [property color]:[atom #000]; }");
+
+  MT('interpolation_error',
+    "[tag foo]#{[error foo]} { [property color]:[atom #000]; }");
+
+  MT("divide_operator",
+    "[tag foo] { [property width]:[number 4] [operator /] [number 2] }");
+
+  MT('nested_structure_with_id_selector',
+    "[tag p] { [builtin #hello] { [property color]:[keyword red]; } }");
+
+  MT('indent_mixin',
+     "[def @mixin] [tag container] (",
+     "  [variable-2 $a]: [number 10],",
+     "  [variable-2 $b]: [number 10])",
+     "{}");
+
+  MT('indent_nested',
+     "[tag foo] {",
+     "  [tag bar] {",
+     "  }",
+     "}");
+
+  MT('indent_parentheses',
+     "[tag foo] {",
+     "  [property color]: [variable darken]([variable-2 $blue],",
+     "    [number 9%]);",
+     "}");
+
+  MT('indent_vardef',
+     "[variable-2 $name]:",
+     "  [string 'val'];",
+     "[tag tag] {",
+     "  [tag inner] {",
+     "    [property margin]: [number 3px];",
+     "  }",
+     "}");
+})();
diff --git a/app/gui/html/vendor/codemirror/mode/css/test.js b/app/gui/html/vendor/codemirror/mode/css/test.js
new file mode 100644
index 0000000..b3f4776
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/css/test.js
@@ -0,0 +1,119 @@
+(function() {
+  var mode = CodeMirror.getMode({indentUnit: 2}, "css");
+  function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
+
+  // Error, because "foobarhello" is neither a known type or property, but
+  // property was expected (after "and"), and it should be in parenthese.
+  MT("atMediaUnknownType",
+     "[def @media] [attribute screen] [keyword and] [error foobarhello] { }");
+
+  // Soft error, because "foobarhello" is not a known property or type.
+  MT("atMediaUnknownProperty",
+     "[def @media] [attribute screen] [keyword and] ([error foobarhello]) { }");
+
+  // Make sure nesting works with media queries
+  MT("atMediaMaxWidthNested",
+     "[def @media] [attribute screen] [keyword and] ([property max-width]: [number 25px]) { [tag foo] { } }");
+
+  MT("tagSelector",
+     "[tag foo] { }");
+
+  MT("classSelector",
+     "[qualifier .foo-bar_hello] { }");
+
+  MT("idSelector",
+     "[builtin #foo] { [error #foo] }");
+
+  MT("tagSelectorUnclosed",
+     "[tag foo] { [property margin]: [number 0] } [tag bar] { }");
+
+  MT("tagStringNoQuotes",
+     "[tag foo] { [property font-family]: [variable hello] [variable world]; }");
+
+  MT("tagStringDouble",
+     "[tag foo] { [property font-family]: [string \"hello world\"]; }");
+
+  MT("tagStringSingle",
+     "[tag foo] { [property font-family]: [string 'hello world']; }");
+
+  MT("tagColorKeyword",
+     "[tag foo] {",
+     "  [property color]: [keyword black];",
+     "  [property color]: [keyword navy];",
+     "  [property color]: [keyword yellow];",
+     "}");
+
+  MT("tagColorHex3",
+     "[tag foo] { [property background]: [atom #fff]; }");
+
+  MT("tagColorHex6",
+     "[tag foo] { [property background]: [atom #ffffff]; }");
+
+  MT("tagColorHex4",
+     "[tag foo] { [property background]: [atom&error #ffff]; }");
+
+  MT("tagColorHexInvalid",
+     "[tag foo] { [property background]: [atom&error #ffg]; }");
+
+  MT("tagNegativeNumber",
+     "[tag foo] { [property margin]: [number -5px]; }");
+
+  MT("tagPositiveNumber",
+     "[tag foo] { [property padding]: [number 5px]; }");
+
+  MT("tagVendor",
+     "[tag foo] { [meta -foo-][property box-sizing]: [meta -foo-][atom border-box]; }");
+
+  MT("tagBogusProperty",
+     "[tag foo] { [property&error barhelloworld]: [number 0]; }");
+
+  MT("tagTwoProperties",
+     "[tag foo] { [property margin]: [number 0]; [property padding]: [number 0]; }");
+
+  MT("tagTwoPropertiesURL",
+     "[tag foo] { [property background]: [atom url]([string //example.com/foo.png]); [property padding]: [number 0]; }");
+
+  MT("commentSGML",
+     "[comment <!--comment-->]");
+
+  MT("commentSGML2",
+     "[comment <!--comment]",
+     "[comment -->] [tag div] {}");
+
+  MT("indent_tagSelector",
+     "[tag strong], [tag em] {",
+     "  [property background]: [atom rgba](",
+     "    [number 255], [number 255], [number 0], [number .2]",
+     "  );",
+     "}");
+
+  MT("indent_atMedia",
+     "[def @media] {",
+     "  [tag foo] {",
+     "    [property color]:",
+     "      [keyword yellow];",
+     "  }",
+     "}");
+
+  MT("indent_comma",
+     "[tag foo] {",
+     "  [property font-family]: [variable verdana],",
+     "    [atom sans-serif];",
+     "}");
+
+  MT("indent_parentheses",
+     "[tag foo]:[variable-3 before] {",
+     "  [property background]: [atom url](",
+     "[string     blahblah]",
+     "[string     etc]",
+     "[string   ]) [keyword !important];",
+     "}");
+
+  MT("font_face",
+     "[def @font-face] {",
+     "  [property font-family]: [string 'myfont'];",
+     "  [error nonsense]: [string 'abc'];",
+     "  [property src]: [atom url]([string http://blah]),",
+     "    [atom url]([string http://foo]);",
+     "}");
+})();
diff --git a/app/gui/html/vendor/codemirror/mode/d/d.js b/app/gui/html/vendor/codemirror/mode/d/d.js
new file mode 100644
index 0000000..3ab8b42
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/d/d.js
@@ -0,0 +1,215 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("d", function(config, parserConfig) {
+  var indentUnit = config.indentUnit,
+      statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
+      keywords = parserConfig.keywords || {},
+      builtin = parserConfig.builtin || {},
+      blockKeywords = parserConfig.blockKeywords || {},
+      atoms = parserConfig.atoms || {},
+      hooks = parserConfig.hooks || {},
+      multiLineStrings = parserConfig.multiLineStrings;
+  var isOperatorChar = /[+\-*&%=<>!?|\/]/;
+
+  var curPunc;
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+    if (hooks[ch]) {
+      var result = hooks[ch](stream, state);
+      if (result !== false) return result;
+    }
+    if (ch == '"' || ch == "'" || ch == "`") {
+      state.tokenize = tokenString(ch);
+      return state.tokenize(stream, state);
+    }
+    if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
+      curPunc = ch;
+      return null;
+    }
+    if (/\d/.test(ch)) {
+      stream.eatWhile(/[\w\.]/);
+      return "number";
+    }
+    if (ch == "/") {
+      if (stream.eat("+")) {
+        state.tokenize = tokenComment;
+        return tokenNestedComment(stream, state);
+      }
+      if (stream.eat("*")) {
+        state.tokenize = tokenComment;
+        return tokenComment(stream, state);
+      }
+      if (stream.eat("/")) {
+        stream.skipToEnd();
+        return "comment";
+      }
+    }
+    if (isOperatorChar.test(ch)) {
+      stream.eatWhile(isOperatorChar);
+      return "operator";
+    }
+    stream.eatWhile(/[\w\$_]/);
+    var cur = stream.current();
+    if (keywords.propertyIsEnumerable(cur)) {
+      if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+      return "keyword";
+    }
+    if (builtin.propertyIsEnumerable(cur)) {
+      if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+      return "builtin";
+    }
+    if (atoms.propertyIsEnumerable(cur)) return "atom";
+    return "variable";
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, next, end = false;
+      while ((next = stream.next()) != null) {
+        if (next == quote && !escaped) {end = true; break;}
+        escaped = !escaped && next == "\\";
+      }
+      if (end || !(escaped || multiLineStrings))
+        state.tokenize = null;
+      return "string";
+    };
+  }
+
+  function tokenComment(stream, state) {
+    var maybeEnd = false, ch;
+    while (ch = stream.next()) {
+      if (ch == "/" && maybeEnd) {
+        state.tokenize = null;
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return "comment";
+  }
+
+  function tokenNestedComment(stream, state) {
+    var maybeEnd = false, ch;
+    while (ch = stream.next()) {
+      if (ch == "/" && maybeEnd) {
+        state.tokenize = null;
+        break;
+      }
+      maybeEnd = (ch == "+");
+    }
+    return "comment";
+  }
+
+  function Context(indented, column, type, align, prev) {
+    this.indented = indented;
+    this.column = column;
+    this.type = type;
+    this.align = align;
+    this.prev = prev;
+  }
+  function pushContext(state, col, type) {
+    var indent = state.indented;
+    if (state.context && state.context.type == "statement")
+      indent = state.context.indented;
+    return state.context = new Context(indent, col, type, null, state.context);
+  }
+  function popContext(state) {
+    var t = state.context.type;
+    if (t == ")" || t == "]" || t == "}")
+      state.indented = state.context.indented;
+    return state.context = state.context.prev;
+  }
+
+  // Interface
+
+  return {
+    startState: function(basecolumn) {
+      return {
+        tokenize: null,
+        context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
+        indented: 0,
+        startOfLine: true
+      };
+    },
+
+    token: function(stream, state) {
+      var ctx = state.context;
+      if (stream.sol()) {
+        if (ctx.align == null) ctx.align = false;
+        state.indented = stream.indentation();
+        state.startOfLine = true;
+      }
+      if (stream.eatSpace()) return null;
+      curPunc = null;
+      var style = (state.tokenize || tokenBase)(stream, state);
+      if (style == "comment" || style == "meta") return style;
+      if (ctx.align == null) ctx.align = true;
+
+      if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
+      else if (curPunc == "{") pushContext(state, stream.column(), "}");
+      else if (curPunc == "[") pushContext(state, stream.column(), "]");
+      else if (curPunc == "(") pushContext(state, stream.column(), ")");
+      else if (curPunc == "}") {
+        while (ctx.type == "statement") ctx = popContext(state);
+        if (ctx.type == "}") ctx = popContext(state);
+        while (ctx.type == "statement") ctx = popContext(state);
+      }
+      else if (curPunc == ctx.type) popContext(state);
+      else if (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') || (ctx.type == "statement" && curPunc == "newstatement"))
+        pushContext(state, stream.column(), "statement");
+      state.startOfLine = false;
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
+      var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
+      if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
+      var closing = firstChar == ctx.type;
+      if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
+      else if (ctx.align) return ctx.column + (closing ? 0 : 1);
+      else return ctx.indented + (closing ? 0 : indentUnit);
+    },
+
+    electricChars: "{}"
+  };
+});
+
+  function words(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+
+  var blockKeywords = "body catch class do else enum for foreach foreach_reverse if in interface mixin " +
+                      "out scope struct switch try union unittest version while with";
+
+  CodeMirror.defineMIME("text/x-d", {
+    name: "d",
+    keywords: words("abstract alias align asm assert auto break case cast cdouble cent cfloat const continue " +
+                    "debug default delegate delete deprecated export extern final finally function goto immutable " +
+                    "import inout invariant is lazy macro module new nothrow override package pragma private " +
+                    "protected public pure ref return shared short static super synchronized template this " +
+                    "throw typedef typeid typeof volatile __FILE__ __LINE__ __gshared __traits __vector __parameters " +
+                    blockKeywords),
+    blockKeywords: words(blockKeywords),
+    builtin: words("bool byte char creal dchar double float idouble ifloat int ireal long real short ubyte " +
+                   "ucent uint ulong ushort wchar wstring void size_t sizediff_t"),
+    atoms: words("exit failure success true false null"),
+    hooks: {
+      "@": function(stream, _state) {
+        stream.eatWhile(/[\w\$_]/);
+        return "meta";
+      }
+    }
+  });
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/d/index.html b/app/gui/html/vendor/codemirror/mode/d/index.html
new file mode 100644
index 0000000..8b25fcc
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/d/index.html
@@ -0,0 +1,273 @@
+<!doctype html>
+
+<title>CodeMirror: D mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="d.js"></script>
+<style>.CodeMirror {border: 2px inset #dee;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">D</a>
+  </ul>
+</div>
+
+<article>
+<h2>D mode</h2>
+<form><textarea id="code" name="code">
+/* D demo code // copied from phobos/sd/metastrings.d */
+// Written in the D programming language.
+
+/**
+Templates with which to do compile-time manipulation of strings.
+
+Macros:
+ WIKI = Phobos/StdMetastrings
+
+Copyright: Copyright Digital Mars 2007 - 2009.
+License:   <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+Authors:   $(WEB digitalmars.com, Walter Bright),
+           Don Clugston
+Source:    $(PHOBOSSRC std/_metastrings.d)
+*/
+/*
+         Copyright Digital Mars 2007 - 2009.
+Distributed under the Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt or copy at
+         http://www.boost.org/LICENSE_1_0.txt)
+ */
+module std.metastrings;
+
+/**
+Formats constants into a string at compile time.  Analogous to $(XREF
+string,format).
+
+Parameters:
+
+A = tuple of constants, which can be strings, characters, or integral
+    values.
+
+Formats:
+ *    The formats supported are %s for strings, and %%
+ *    for the % character.
+Example:
+---
+import std.metastrings;
+import std.stdio;
+
+void main()
+{
+  string s = Format!("Arg %s = %s", "foo", 27);
+  writefln(s); // "Arg foo = 27"
+}
+ * ---
+ */
+
+template Format(A...)
+{
+    static if (A.length == 0)
+        enum Format = "";
+    else static if (is(typeof(A[0]) : const(char)[]))
+        enum Format = FormatString!(A[0], A[1..$]);
+    else
+        enum Format = toStringNow!(A[0]) ~ Format!(A[1..$]);
+}
+
+template FormatString(const(char)[] F, A...)
+{
+    static if (F.length == 0)
+        enum FormatString = Format!(A);
+    else static if (F.length == 1)
+        enum FormatString = F[0] ~ Format!(A);
+    else static if (F[0..2] == "%s")
+        enum FormatString
+            = toStringNow!(A[0]) ~ FormatString!(F[2..$],A[1..$]);
+    else static if (F[0..2] == "%%")
+        enum FormatString = "%" ~ FormatString!(F[2..$],A);
+    else
+    {
+        static assert(F[0] != '%', "unrecognized format %" ~ F[1]);
+        enum FormatString = F[0] ~ FormatString!(F[1..$],A);
+    }
+}
+
+unittest
+{
+    auto s = Format!("hel%slo", "world", -138, 'c', true);
+    assert(s == "helworldlo-138ctrue", "[" ~ s ~ "]");
+}
+
+/**
+ * Convert constant argument to a string.
+ */
+
+template toStringNow(ulong v)
+{
+    static if (v < 10)
+        enum toStringNow = "" ~ cast(char)(v + '0');
+    else
+        enum toStringNow = toStringNow!(v / 10) ~ toStringNow!(v % 10);
+}
+
+unittest
+{
+    static assert(toStringNow!(1uL << 62) == "4611686018427387904");
+}
+
+/// ditto
+template toStringNow(long v)
+{
+    static if (v < 0)
+        enum toStringNow = "-" ~ toStringNow!(cast(ulong) -v);
+    else
+        enum toStringNow = toStringNow!(cast(ulong) v);
+}
+
+unittest
+{
+    static assert(toStringNow!(0x100000000) == "4294967296");
+    static assert(toStringNow!(-138L) == "-138");
+}
+
+/// ditto
+template toStringNow(uint U)
+{
+    enum toStringNow = toStringNow!(cast(ulong)U);
+}
+
+/// ditto
+template toStringNow(int I)
+{
+    enum toStringNow = toStringNow!(cast(long)I);
+}
+
+/// ditto
+template toStringNow(bool B)
+{
+    enum toStringNow = B ? "true" : "false";
+}
+
+/// ditto
+template toStringNow(string S)
+{
+    enum toStringNow = S;
+}
+
+/// ditto
+template toStringNow(char C)
+{
+    enum toStringNow = "" ~ C;
+}
+
+
+/********
+ * Parse unsigned integer literal from the start of string s.
+ * returns:
+ *    .value = the integer literal as a string,
+ *    .rest = the string following the integer literal
+ * Otherwise:
+ *    .value = null,
+ *    .rest = s
+ */
+
+template parseUinteger(const(char)[] s)
+{
+    static if (s.length == 0)
+    {
+        enum value = "";
+        enum rest = "";
+    }
+    else static if (s[0] >= '0' && s[0] <= '9')
+    {
+        enum value = s[0] ~ parseUinteger!(s[1..$]).value;
+        enum rest = parseUinteger!(s[1..$]).rest;
+    }
+    else
+    {
+        enum value = "";
+        enum rest = s;
+    }
+}
+
+/********
+Parse integer literal optionally preceded by $(D '-') from the start
+of string $(D s).
+
+Returns:
+   .value = the integer literal as a string,
+   .rest = the string following the integer literal
+
+Otherwise:
+   .value = null,
+   .rest = s
+*/
+
+template parseInteger(const(char)[] s)
+{
+    static if (s.length == 0)
+    {
+        enum value = "";
+        enum rest = "";
+    }
+    else static if (s[0] >= '0' && s[0] <= '9')
+    {
+        enum value = s[0] ~ parseUinteger!(s[1..$]).value;
+        enum rest = parseUinteger!(s[1..$]).rest;
+    }
+    else static if (s.length >= 2 &&
+            s[0] == '-' && s[1] >= '0' && s[1] <= '9')
+    {
+        enum value = s[0..2] ~ parseUinteger!(s[2..$]).value;
+        enum rest = parseUinteger!(s[2..$]).rest;
+    }
+    else
+    {
+        enum value = "";
+        enum rest = s;
+    }
+}
+
+unittest
+{
+    assert(parseUinteger!("1234abc").value == "1234");
+    assert(parseUinteger!("1234abc").rest == "abc");
+    assert(parseInteger!("-1234abc").value == "-1234");
+    assert(parseInteger!("-1234abc").rest == "abc");
+}
+
+/**
+Deprecated aliases held for backward compatibility.
+*/
+deprecated alias toStringNow ToString;
+/// Ditto
+deprecated alias parseUinteger ParseUinteger;
+/// Ditto
+deprecated alias parseUinteger ParseInteger;
+
+</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        indentUnit: 4,
+        mode: "text/x-d"
+      });
+    </script>
+
+    <p>Simple mode that handle D-Syntax (<a href="http://www.dlang.org">DLang Homepage</a>).</p>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-d</code>
+    .</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/diff/diff.js b/app/gui/html/vendor/codemirror/mode/diff/diff.js
new file mode 100644
index 0000000..d43f15d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/diff/diff.js
@@ -0,0 +1,44 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("diff", function() {
+
+  var TOKEN_NAMES = {
+    '+': 'positive',
+    '-': 'negative',
+    '@': 'meta'
+  };
+
+  return {
+    token: function(stream) {
+      var tw_pos = stream.string.search(/[\t ]+?$/);
+
+      if (!stream.sol() || tw_pos === 0) {
+        stream.skipToEnd();
+        return ("error " + (
+          TOKEN_NAMES[stream.string.charAt(0)] || '')).replace(/ $/, '');
+      }
+
+      var token_name = TOKEN_NAMES[stream.peek()] || stream.skipToEnd();
+
+      if (tw_pos === -1) {
+        stream.skipToEnd();
+      } else {
+        stream.pos = tw_pos;
+      }
+
+      return token_name;
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/x-diff", "diff");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/diff/index.html b/app/gui/html/vendor/codemirror/mode/diff/index.html
new file mode 100644
index 0000000..6ceae8b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/diff/index.html
@@ -0,0 +1,117 @@
+<!doctype html>
+
+<title>CodeMirror: Diff mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="diff.js"></script>
+<style>
+      .CodeMirror {border-top: 1px solid #ddd; border-bottom: 1px solid #ddd;}
+      span.cm-meta {color: #a0b !important;}
+      span.cm-error { background-color: black; opacity: 0.4;}
+      span.cm-error.cm-string { background-color: red; }
+      span.cm-error.cm-tag { background-color: #2b2; }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Diff</a>
+  </ul>
+</div>
+
+<article>
+<h2>Diff mode</h2>
+<form><textarea id="code" name="code">
+diff --git a/index.html b/index.html
+index c1d9156..7764744 100644
+--- a/index.html
++++ b/index.html
+@@ -95,7 +95,8 @@ StringStream.prototype = {
+     <script>
+       var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+         lineNumbers: true,
+-        autoMatchBrackets: true
++        autoMatchBrackets: true,
++      onGutterClick: function(x){console.log(x);}
+       });
+     </script>
+   </body>
+diff --git a/lib/codemirror.js b/lib/codemirror.js
+index 04646a9..9a39cc7 100644
+--- a/lib/codemirror.js
++++ b/lib/codemirror.js
+@@ -399,10 +399,16 @@ var CodeMirror = (function() {
+     }
+ 
+     function onMouseDown(e) {
+-      var start = posFromMouse(e), last = start;    
++      var start = posFromMouse(e), last = start, target = e.target();
+       if (!start) return;
+       setCursor(start.line, start.ch, false);
+       if (e.button() != 1) return;
++      if (target.parentNode == gutter) {    
++        if (options.onGutterClick)
++          options.onGutterClick(indexOf(gutter.childNodes, target) + showingFrom);
++        return;
++      }
++
+       if (!focused) onFocus();
+ 
+       e.stop();
+@@ -808,7 +814,7 @@ var CodeMirror = (function() {
+       for (var i = showingFrom; i < showingTo; ++i) {
+         var marker = lines[i].gutterMarker;
+         if (marker) html.push('<div class="' + marker.style + '">' + htmlEscape(marker.text) + '</div>');
+-        else html.push("<div>" + (options.lineNumbers ? i + 1 : "\u00a0") + "</div>");
++        else html.push("<div>" + (options.lineNumbers ? i + options.firstLineNumber : "\u00a0") + "</div>");
+       }
+       gutter.style.display = "none"; // TODO test whether this actually helps
+       gutter.innerHTML = html.join("");
+@@ -1371,10 +1377,8 @@ var CodeMirror = (function() {
+         if (option == "parser") setParser(value);
+         else if (option === "lineNumbers") setLineNumbers(value);
+         else if (option === "gutter") setGutter(value);
+-        else if (option === "readOnly") options.readOnly = value;
+-        else if (option === "indentUnit") {options.indentUnit = indentUnit = value; setParser(options.parser);}
+-        else if (/^(?:enterMode|tabMode|indentWithTabs|readOnly|autoMatchBrackets|undoDepth)$/.test(option)) options[option] = value;
+-        else throw new Error("Can't set option " + option);
++        else if (option === "indentUnit") {options.indentUnit = value; setParser(options.parser);}
++        else options[option] = value;
+       },
+       cursorCoords: cursorCoords,
+       undo: operation(undo),
+@@ -1402,7 +1406,8 @@ var CodeMirror = (function() {
+       replaceRange: operation(replaceRange),
+ 
+       operation: function(f){return operation(f)();},
+-      refresh: function(){updateDisplay([{from: 0, to: lines.length}]);}
++      refresh: function(){updateDisplay([{from: 0, to: lines.length}]);},
++      getInputField: function(){return input;}
+     };
+     return instance;
+   }
+@@ -1420,6 +1425,7 @@ var CodeMirror = (function() {
+     readOnly: false,
+     onChange: null,
+     onCursorActivity: null,
++    onGutterClick: null,
+     autoMatchBrackets: false,
+     workTime: 200,
+     workDelay: 300,
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-diff</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/dtd/dtd.js b/app/gui/html/vendor/codemirror/mode/dtd/dtd.js
new file mode 100644
index 0000000..b4a6cb3
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/dtd/dtd.js
@@ -0,0 +1,139 @@
+/*
+  DTD mode
+  Ported to CodeMirror by Peter Kroon <plakroon at gmail.com>
+  Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues
+  GitHub: @peterkroon
+*/
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("dtd", function(config) {
+  var indentUnit = config.indentUnit, type;
+  function ret(style, tp) {type = tp; return style;}
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+
+    if (ch == "<" && stream.eat("!") ) {
+      if (stream.eatWhile(/[\-]/)) {
+        state.tokenize = tokenSGMLComment;
+        return tokenSGMLComment(stream, state);
+      } else if (stream.eatWhile(/[\w]/)) return ret("keyword", "doindent");
+    } else if (ch == "<" && stream.eat("?")) { //xml declaration
+      state.tokenize = inBlock("meta", "?>");
+      return ret("meta", ch);
+    } else if (ch == "#" && stream.eatWhile(/[\w]/)) return ret("atom", "tag");
+    else if (ch == "|") return ret("keyword", "seperator");
+    else if (ch.match(/[\(\)\[\]\-\.,\+\?>]/)) return ret(null, ch);//if(ch === ">") return ret(null, "endtag"); else
+    else if (ch.match(/[\[\]]/)) return ret("rule", ch);
+    else if (ch == "\"" || ch == "'") {
+      state.tokenize = tokenString(ch);
+      return state.tokenize(stream, state);
+    } else if (stream.eatWhile(/[a-zA-Z\?\+\d]/)) {
+      var sc = stream.current();
+      if( sc.substr(sc.length-1,sc.length).match(/\?|\+/) !== null )stream.backUp(1);
+      return ret("tag", "tag");
+    } else if (ch == "%" || ch == "*" ) return ret("number", "number");
+    else {
+      stream.eatWhile(/[\w\\\-_%.{,]/);
+      return ret(null, null);
+    }
+  }
+
+  function tokenSGMLComment(stream, state) {
+    var dashes = 0, ch;
+    while ((ch = stream.next()) != null) {
+      if (dashes >= 2 && ch == ">") {
+        state.tokenize = tokenBase;
+        break;
+      }
+      dashes = (ch == "-") ? dashes + 1 : 0;
+    }
+    return ret("comment", "comment");
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, ch;
+      while ((ch = stream.next()) != null) {
+        if (ch == quote && !escaped) {
+          state.tokenize = tokenBase;
+          break;
+        }
+        escaped = !escaped && ch == "\\";
+      }
+      return ret("string", "tag");
+    };
+  }
+
+  function inBlock(style, terminator) {
+    return function(stream, state) {
+      while (!stream.eol()) {
+        if (stream.match(terminator)) {
+          state.tokenize = tokenBase;
+          break;
+        }
+        stream.next();
+      }
+      return style;
+    };
+  }
+
+  return {
+    startState: function(base) {
+      return {tokenize: tokenBase,
+              baseIndent: base || 0,
+              stack: []};
+    },
+
+    token: function(stream, state) {
+      if (stream.eatSpace()) return null;
+      var style = state.tokenize(stream, state);
+
+      var context = state.stack[state.stack.length-1];
+      if (stream.current() == "[" || type === "doindent" || type == "[") state.stack.push("rule");
+      else if (type === "endtag") state.stack[state.stack.length-1] = "endtag";
+      else if (stream.current() == "]" || type == "]" || (type == ">" && context == "rule")) state.stack.pop();
+      else if (type == "[") state.stack.push("[");
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      var n = state.stack.length;
+
+      if( textAfter.match(/\]\s+|\]/) )n=n-1;
+      else if(textAfter.substr(textAfter.length-1, textAfter.length) === ">"){
+        if(textAfter.substr(0,1) === "<")n;
+        else if( type == "doindent" && textAfter.length > 1 )n;
+        else if( type == "doindent")n--;
+        else if( type == ">" && textAfter.length > 1)n;
+        else if( type == "tag" && textAfter !== ">")n;
+        else if( type == "tag" && state.stack[state.stack.length-1] == "rule")n--;
+        else if( type == "tag")n++;
+        else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule" && type === ">")n--;
+        else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule")n;
+        else if( textAfter.substr(0,1) !== "<" && textAfter.substr(0,1) === ">" )n=n-1;
+        else if( textAfter === ">")n;
+        else n=n-1;
+        //over rule them all
+        if(type == null || type == "]")n--;
+      }
+
+      return state.baseIndent + n * indentUnit;
+    },
+
+    electricChars: "]>"
+  };
+});
+
+CodeMirror.defineMIME("application/xml-dtd", "dtd");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/dtd/index.html b/app/gui/html/vendor/codemirror/mode/dtd/index.html
new file mode 100644
index 0000000..076d827
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/dtd/index.html
@@ -0,0 +1,89 @@
+<!doctype html>
+
+<title>CodeMirror: DTD mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="dtd.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">DTD</a>
+  </ul>
+</div>
+
+<article>
+<h2>DTD mode</h2>
+<form><textarea id="code" name="code"><?xml version="1.0" encoding="UTF-8"?>
+
+<!ATTLIST title
+  xmlns	CDATA	#FIXED	"http://docbook.org/ns/docbook"
+  role	CDATA	#IMPLIED
+  %db.common.attributes;
+  %db.common.linking.attributes;
+>
+
+<!--
+  Try: http://docbook.org/xml/5.0/dtd/docbook.dtd
+-->
+
+<!DOCTYPE xsl:stylesheet
+  [
+    <!ENTITY nbsp   "&#160;">
+    <!ENTITY copy   "&#169;">
+    <!ENTITY reg    "&#174;">
+    <!ENTITY trade  "&#8482;">
+    <!ENTITY mdash  "&#8212;">
+    <!ENTITY ldquo  "&#8220;">
+    <!ENTITY rdquo  "&#8221;">
+    <!ENTITY pound  "&#163;">
+    <!ENTITY yen    "&#165;">
+    <!ENTITY euro   "&#8364;">
+    <!ENTITY mathml "http://www.w3.org/1998/Math/MathML">
+  ]
+>
+
+<!ELEMENT title (#PCDATA|inlinemediaobject|remark|superscript|subscript|xref|link|olink|anchor|biblioref|alt|annotation|indexterm|abbrev|acronym|date|emphasis|footnote|footnoteref|foreignphrase|phrase|quote|wordasword|firstterm|glossterm|coref|trademark|productnumber|productname|database|application|hardware|citation|citerefentry|citetitle|citebiblioid|author|person|personname|org|orgname|editor|jobtitle|replaceable|package|parameter|termdef|nonterminal|systemitem|option|optional|property|inlineequation|tag|markup|token|symbol|literal|code|constant|email|uri|guiicon|guibutton|guimenuitem|guimenu|guisubmenu|guilabel|menuchoice|mousebutton|keycombo|keycap|keycode|keysym|shortcut|accel|prompt|envar|filename|command|computeroutput|userinput|function|varname|returnvalue|type|classname|exceptionname|interfacename|methodname|modifier|initializer|ooclass|ooexception|oointerface|errorcode|errortext|errorname|errortype)*>
+
+<!ENTITY % db.common.attributes "
+  xml:id	ID	#IMPLIED
+  version	CDATA	#IMPLIED
+  xml:lang	CDATA	#IMPLIED
+  xml:base	CDATA	#IMPLIED
+  remap	CDATA	#IMPLIED
+  xreflabel	CDATA	#IMPLIED
+  revisionflag	(changed|added|deleted|off)	#IMPLIED
+  dir	(ltr|rtl|lro|rlo)	#IMPLIED
+  arch	CDATA	#IMPLIED
+  audience	CDATA	#IMPLIED
+  condition	CDATA	#IMPLIED
+  conformance	CDATA	#IMPLIED
+  os	CDATA	#IMPLIED
+  revision	CDATA	#IMPLIED
+  security	CDATA	#IMPLIED
+  userlevel	CDATA	#IMPLIED
+  vendor	CDATA	#IMPLIED
+  wordsize	CDATA	#IMPLIED
+  annotations	CDATA	#IMPLIED
+
+"></textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: {name: "dtd", alignCDATA: true},
+        lineNumbers: true,
+        lineWrapping: true
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>application/xml-dtd</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/ecl/ecl.js b/app/gui/html/vendor/codemirror/mode/ecl/ecl.js
new file mode 100644
index 0000000..2b841ff
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/ecl/ecl.js
@@ -0,0 +1,204 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("ecl", function(config) {
+
+  function words(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+
+  function metaHook(stream, state) {
+    if (!state.startOfLine) return false;
+    stream.skipToEnd();
+    return "meta";
+  }
+
+  var indentUnit = config.indentUnit;
+  var keyword = words("abs acos allnodes ascii asin asstring atan atan2 ave case choose choosen choosesets clustersize combine correlation cos cosh count covariance cron dataset dedup define denormalize distribute distributed distribution ebcdic enth error evaluate event eventextra eventname exists exp failcode failmessage fetch fromunicode getisvalid global graph group hash hash32 hash64 hashcrc hashmd5 having if index intformat isvalid iterate join keyunicode length library limit ln local log loop map matched matchlength matchposition matchtext matchunicode max merge mergejoin min nolocal nonempty normalize parse pipe power preload process project pull random range rank ranked realformat recordof regexfind regexreplace regroup rejected rollup round roundup row rowdiff sample set sin sinh sizeof soapcall sort sorted sqrt stepped stored sum table tan tanh thisnode topn tounicode transfer trim truncate typeof ungroup unicodeorder variance which workunit xmldecode xmlencode xmltext xmlunicode");
+  var variable = words("apply assert build buildindex evaluate fail keydiff keypatch loadxml nothor notify output parallel sequential soapcall wait");
+  var variable_2 = words("__compressed__ all and any as atmost before beginc++ best between case const counter csv descend encrypt end endc++ endmacro except exclusive expire export extend false few first flat from full function group header heading hole ifblock import in interface joined keep keyed last left limit load local locale lookup macro many maxcount maxlength min skew module named nocase noroot noscan nosort not of only opt or outer overwrite packed partition penalty physicallength pipe quote record relationship repeat return right scan self separator service shared skew skip sql store terminator thor threshold token transform trim true type unicodeorder unsorted validate virtual whole wild within xml xpath");
+  var variable_3 = words("ascii big_endian boolean data decimal ebcdic integer pattern qstring real record rule set of string token udecimal unicode unsigned varstring varunicode");
+  var builtin = words("checkpoint deprecated failcode failmessage failure global independent onwarning persist priority recovery stored success wait when");
+  var blockKeywords = words("catch class do else finally for if switch try while");
+  var atoms = words("true false null");
+  var hooks = {"#": metaHook};
+  var multiLineStrings;
+  var isOperatorChar = /[+\-*&%=<>!?|\/]/;
+
+  var curPunc;
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+    if (hooks[ch]) {
+      var result = hooks[ch](stream, state);
+      if (result !== false) return result;
+    }
+    if (ch == '"' || ch == "'") {
+      state.tokenize = tokenString(ch);
+      return state.tokenize(stream, state);
+    }
+    if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
+      curPunc = ch;
+      return null;
+    }
+    if (/\d/.test(ch)) {
+      stream.eatWhile(/[\w\.]/);
+      return "number";
+    }
+    if (ch == "/") {
+      if (stream.eat("*")) {
+        state.tokenize = tokenComment;
+        return tokenComment(stream, state);
+      }
+      if (stream.eat("/")) {
+        stream.skipToEnd();
+        return "comment";
+      }
+    }
+    if (isOperatorChar.test(ch)) {
+      stream.eatWhile(isOperatorChar);
+      return "operator";
+    }
+    stream.eatWhile(/[\w\$_]/);
+    var cur = stream.current().toLowerCase();
+    if (keyword.propertyIsEnumerable(cur)) {
+      if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+      return "keyword";
+    } else if (variable.propertyIsEnumerable(cur)) {
+      if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+      return "variable";
+    } else if (variable_2.propertyIsEnumerable(cur)) {
+      if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+      return "variable-2";
+    } else if (variable_3.propertyIsEnumerable(cur)) {
+      if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+      return "variable-3";
+    } else if (builtin.propertyIsEnumerable(cur)) {
+      if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+      return "builtin";
+    } else { //Data types are of from KEYWORD##
+                var i = cur.length - 1;
+                while(i >= 0 && (!isNaN(cur[i]) || cur[i] == '_'))
+                        --i;
+
+                if (i > 0) {
+                        var cur2 = cur.substr(0, i + 1);
+                if (variable_3.propertyIsEnumerable(cur2)) {
+                        if (blockKeywords.propertyIsEnumerable(cur2)) curPunc = "newstatement";
+                        return "variable-3";
+                }
+            }
+    }
+    if (atoms.propertyIsEnumerable(cur)) return "atom";
+    return null;
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, next, end = false;
+      while ((next = stream.next()) != null) {
+        if (next == quote && !escaped) {end = true; break;}
+        escaped = !escaped && next == "\\";
+      }
+      if (end || !(escaped || multiLineStrings))
+        state.tokenize = tokenBase;
+      return "string";
+    };
+  }
+
+  function tokenComment(stream, state) {
+    var maybeEnd = false, ch;
+    while (ch = stream.next()) {
+      if (ch == "/" && maybeEnd) {
+        state.tokenize = tokenBase;
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return "comment";
+  }
+
+  function Context(indented, column, type, align, prev) {
+    this.indented = indented;
+    this.column = column;
+    this.type = type;
+    this.align = align;
+    this.prev = prev;
+  }
+  function pushContext(state, col, type) {
+    return state.context = new Context(state.indented, col, type, null, state.context);
+  }
+  function popContext(state) {
+    var t = state.context.type;
+    if (t == ")" || t == "]" || t == "}")
+      state.indented = state.context.indented;
+    return state.context = state.context.prev;
+  }
+
+  // Interface
+
+  return {
+    startState: function(basecolumn) {
+      return {
+        tokenize: null,
+        context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
+        indented: 0,
+        startOfLine: true
+      };
+    },
+
+    token: function(stream, state) {
+      var ctx = state.context;
+      if (stream.sol()) {
+        if (ctx.align == null) ctx.align = false;
+        state.indented = stream.indentation();
+        state.startOfLine = true;
+      }
+      if (stream.eatSpace()) return null;
+      curPunc = null;
+      var style = (state.tokenize || tokenBase)(stream, state);
+      if (style == "comment" || style == "meta") return style;
+      if (ctx.align == null) ctx.align = true;
+
+      if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
+      else if (curPunc == "{") pushContext(state, stream.column(), "}");
+      else if (curPunc == "[") pushContext(state, stream.column(), "]");
+      else if (curPunc == "(") pushContext(state, stream.column(), ")");
+      else if (curPunc == "}") {
+        while (ctx.type == "statement") ctx = popContext(state);
+        if (ctx.type == "}") ctx = popContext(state);
+        while (ctx.type == "statement") ctx = popContext(state);
+      }
+      else if (curPunc == ctx.type) popContext(state);
+      else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
+        pushContext(state, stream.column(), "statement");
+      state.startOfLine = false;
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      if (state.tokenize != tokenBase && state.tokenize != null) return 0;
+      var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
+      if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
+      var closing = firstChar == ctx.type;
+      if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit);
+      else if (ctx.align) return ctx.column + (closing ? 0 : 1);
+      else return ctx.indented + (closing ? 0 : indentUnit);
+    },
+
+    electricChars: "{}"
+  };
+});
+
+CodeMirror.defineMIME("text/x-ecl", "ecl");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/ecl/index.html b/app/gui/html/vendor/codemirror/mode/ecl/index.html
new file mode 100644
index 0000000..f4b612d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/ecl/index.html
@@ -0,0 +1,52 @@
+<!doctype html>
+
+<title>CodeMirror: ECL mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="ecl.js"></script>
+<style>.CodeMirror {border: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">ECL</a>
+  </ul>
+</div>
+
+<article>
+<h2>ECL mode</h2>
+<form><textarea id="code" name="code">
+/*
+sample useless code to demonstrate ecl syntax highlighting
+this is a multiline comment!
+*/
+
+//  this is a singleline comment!
+
+import ut;
+r := 
+  record
+   string22 s1 := '123';
+   integer4 i1 := 123;
+  end;
+#option('tmp', true);
+d := dataset('tmp::qb', r, thor);
+output(d);
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
+    </script>
+
+    <p>Based on CodeMirror's clike mode.  For more information see <a href="http://hpccsystems.com">HPCC Systems</a> web site.</p>
+    <p><strong>MIME types defined:</strong> <code>text/x-ecl</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/eiffel/eiffel.js b/app/gui/html/vendor/codemirror/mode/eiffel/eiffel.js
new file mode 100644
index 0000000..c6c3c84
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/eiffel/eiffel.js
@@ -0,0 +1,159 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("eiffel", function() {
+  function wordObj(words) {
+    var o = {};
+    for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
+    return o;
+  }
+  var keywords = wordObj([
+    'note',
+    'across',
+    'when',
+    'variant',
+    'until',
+    'unique',
+    'undefine',
+    'then',
+    'strip',
+    'select',
+    'retry',
+    'rescue',
+    'require',
+    'rename',
+    'reference',
+    'redefine',
+    'prefix',
+    'once',
+    'old',
+    'obsolete',
+    'loop',
+    'local',
+    'like',
+    'is',
+    'inspect',
+    'infix',
+    'include',
+    'if',
+    'frozen',
+    'from',
+    'external',
+    'export',
+    'ensure',
+    'end',
+    'elseif',
+    'else',
+    'do',
+    'creation',
+    'create',
+    'check',
+    'alias',
+    'agent',
+    'separate',
+    'invariant',
+    'inherit',
+    'indexing',
+    'feature',
+    'expanded',
+    'deferred',
+    'class',
+    'Void',
+    'True',
+    'Result',
+    'Precursor',
+    'False',
+    'Current',
+    'create',
+    'attached',
+    'detachable',
+    'as',
+    'and',
+    'implies',
+    'not',
+    'or'
+  ]);
+  var operators = wordObj([":=", "and then","and", "or","<<",">>"]);
+  var curPunc;
+
+  function chain(newtok, stream, state) {
+    state.tokenize.push(newtok);
+    return newtok(stream, state);
+  }
+
+  function tokenBase(stream, state) {
+    curPunc = null;
+    if (stream.eatSpace()) return null;
+    var ch = stream.next();
+    if (ch == '"'||ch == "'") {
+      return chain(readQuoted(ch, "string"), stream, state);
+    } else if (ch == "-"&&stream.eat("-")) {
+      stream.skipToEnd();
+      return "comment";
+    } else if (ch == ":"&&stream.eat("=")) {
+      return "operator";
+    } else if (/[0-9]/.test(ch)) {
+      stream.eatWhile(/[xXbBCc0-9\.]/);
+      stream.eat(/[\?\!]/);
+      return "ident";
+    } else if (/[a-zA-Z_0-9]/.test(ch)) {
+      stream.eatWhile(/[a-zA-Z_0-9]/);
+      stream.eat(/[\?\!]/);
+      return "ident";
+    } else if (/[=+\-\/*^%<>~]/.test(ch)) {
+      stream.eatWhile(/[=+\-\/*^%<>~]/);
+      return "operator";
+    } else {
+      return null;
+    }
+  }
+
+  function readQuoted(quote, style,  unescaped) {
+    return function(stream, state) {
+      var escaped = false, ch;
+      while ((ch = stream.next()) != null) {
+        if (ch == quote && (unescaped || !escaped)) {
+          state.tokenize.pop();
+          break;
+        }
+        escaped = !escaped && ch == "%";
+      }
+      return style;
+    };
+  }
+
+  return {
+    startState: function() {
+      return {tokenize: [tokenBase]};
+    },
+
+    token: function(stream, state) {
+      var style = state.tokenize[state.tokenize.length-1](stream, state);
+      if (style == "ident") {
+        var word = stream.current();
+        style = keywords.propertyIsEnumerable(stream.current()) ? "keyword"
+          : operators.propertyIsEnumerable(stream.current()) ? "operator"
+          : /^[A-Z][A-Z_0-9]*$/g.test(word) ? "tag"
+          : /^0[bB][0-1]+$/g.test(word) ? "number"
+          : /^0[cC][0-7]+$/g.test(word) ? "number"
+          : /^0[xX][a-fA-F0-9]+$/g.test(word) ? "number"
+          : /^([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+)$/g.test(word) ? "number"
+          : /^[0-9]+$/g.test(word) ? "number"
+          : "variable";
+      }
+      return style;
+    },
+    lineComment: "--"
+  };
+});
+
+CodeMirror.defineMIME("text/x-eiffel", "eiffel");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/eiffel/index.html b/app/gui/html/vendor/codemirror/mode/eiffel/index.html
new file mode 100644
index 0000000..95c5f88
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/eiffel/index.html
@@ -0,0 +1,429 @@
+<!doctype html>
+
+<title>CodeMirror: Eiffel mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link rel="stylesheet" href="../../theme/neat.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="eiffel.js"></script>
+<style>
+      .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+      .cm-s-default span.cm-arrow { color: red; }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Eiffel</a>
+  </ul>
+</div>
+
+<article>
+<h2>Eiffel mode</h2>
+<form><textarea id="code" name="code">
+note
+    description: "[
+        Project-wide universal properties.
+        This class is an ancestor to all developer-written classes.
+        ANY may be customized for individual projects or teams.
+        ]"
+
+    library: "Free implementation of ELKS library"
+    status: "See notice at end of class."
+    legal: "See notice at end of class."
+    date: "$Date: 2013-01-25 11:49:00 -0800 (Fri, 25 Jan 2013) $"
+    revision: "$Revision: 712 $"
+
+class
+    ANY
+
+feature -- Customization
+
+feature -- Access
+
+    generator: STRING
+            -- Name of current object's generating class
+            -- (base class of the type of which it is a direct instance)
+        external
+            "built_in"
+        ensure
+            generator_not_void: Result /= Void
+            generator_not_empty: not Result.is_empty
+        end
+
+    generating_type: TYPE [detachable like Current]
+            -- Type of current object
+            -- (type of which it is a direct instance)
+        do
+            Result := {detachable like Current}
+        ensure
+            generating_type_not_void: Result /= Void
+        end
+
+feature -- Status report
+
+    conforms_to (other: ANY): BOOLEAN
+            -- Does type of current object conform to type
+            -- of `other' (as per Eiffel: The Language, chapter 13)?
+        require
+            other_not_void: other /= Void
+        external
+            "built_in"
+        end
+
+    same_type (other: ANY): BOOLEAN
+            -- Is type of current object identical to type of `other'?
+        require
+            other_not_void: other /= Void
+        external
+            "built_in"
+        ensure
+            definition: Result = (conforms_to (other) and
+                                        other.conforms_to (Current))
+        end
+
+feature -- Comparison
+
+    is_equal (other: like Current): BOOLEAN
+            -- Is `other' attached to an object considered
+            -- equal to current object?
+        require
+            other_not_void: other /= Void
+        external
+            "built_in"
+        ensure
+            symmetric: Result implies other ~ Current
+            consistent: standard_is_equal (other) implies Result
+        end
+
+    frozen standard_is_equal (other: like Current): BOOLEAN
+            -- Is `other' attached to an object of the same type
+            -- as current object, and field-by-field identical to it?
+        require
+            other_not_void: other /= Void
+        external
+            "built_in"
+        ensure
+            same_type: Result implies same_type (other)
+            symmetric: Result implies other.standard_is_equal (Current)
+        end
+
+    frozen equal (a: detachable ANY; b: like a): BOOLEAN
+            -- Are `a' and `b' either both void or attached
+            -- to objects considered equal?
+        do
+            if a = Void then
+                Result := b = Void
+            else
+                Result := b /= Void and then
+                            a.is_equal (b)
+            end
+        ensure
+            definition: Result = (a = Void and b = Void) or else
+                        ((a /= Void and b /= Void) and then
+                        a.is_equal (b))
+        end
+
+    frozen standard_equal (a: detachable ANY; b: like a): BOOLEAN
+            -- Are `a' and `b' either both void or attached to
+            -- field-by-field identical objects of the same type?
+            -- Always uses default object comparison criterion.
+        do
+            if a = Void then
+                Result := b = Void
+            else
+                Result := b /= Void and then
+                            a.standard_is_equal (b)
+            end
+        ensure
+            definition: Result = (a = Void and b = Void) or else
+                        ((a /= Void and b /= Void) and then
+                        a.standard_is_equal (b))
+        end
+
+    frozen is_deep_equal (other: like Current): BOOLEAN
+            -- Are `Current' and `other' attached to isomorphic object structures?
+        require
+            other_not_void: other /= Void
+        external
+            "built_in"
+        ensure
+            shallow_implies_deep: standard_is_equal (other) implies Result
+            same_type: Result implies same_type (other)
+            symmetric: Result implies other.is_deep_equal (Current)
+        end
+
+    frozen deep_equal (a: detachable ANY; b: like a): BOOLEAN
+            -- Are `a' and `b' either both void
+            -- or attached to isomorphic object structures?
+        do
+            if a = Void then
+                Result := b = Void
+            else
+                Result := b /= Void and then a.is_deep_equal (b)
+            end
+        ensure
+            shallow_implies_deep: standard_equal (a, b) implies Result
+            both_or_none_void: (a = Void) implies (Result = (b = Void))
+            same_type: (Result and (a /= Void)) implies (b /= Void and then a.same_type (b))
+            symmetric: Result implies deep_equal (b, a)
+        end
+
+feature -- Duplication
+
+    frozen twin: like Current
+            -- New object equal to `Current'
+            -- `twin' calls `copy'; to change copying/twinning semantics, redefine `copy'.
+        external
+            "built_in"
+        ensure
+            twin_not_void: Result /= Void
+            is_equal: Result ~ Current
+        end
+
+    copy (other: like Current)
+            -- Update current object using fields of object attached
+            -- to `other', so as to yield equal objects.
+        require
+            other_not_void: other /= Void
+            type_identity: same_type (other)
+        external
+            "built_in"
+        ensure
+            is_equal: Current ~ other
+        end
+
+    frozen standard_copy (other: like Current)
+            -- Copy every field of `other' onto corresponding field
+            -- of current object.
+        require
+            other_not_void: other /= Void
+            type_identity: same_type (other)
+        external
+            "built_in"
+        ensure
+            is_standard_equal: standard_is_equal (other)
+        end
+
+    frozen clone (other: detachable ANY): like other
+            -- Void if `other' is void; otherwise new object
+            -- equal to `other'
+            --
+            -- For non-void `other', `clone' calls `copy';
+            -- to change copying/cloning semantics, redefine `copy'.
+        obsolete
+            "Use `twin' instead."
+        do
+            if other /= Void then
+                Result := other.twin
+            end
+        ensure
+            equal: Result ~ other
+        end
+
+    frozen standard_clone (other: detachable ANY): like other
+            -- Void if `other' is void; otherwise new object
+            -- field-by-field identical to `other'.
+            -- Always uses default copying semantics.
+        obsolete
+            "Use `standard_twin' instead."
+        do
+            if other /= Void then
+                Result := other.standard_twin
+            end
+        ensure
+            equal: standard_equal (Result, other)
+        end
+
+    frozen standard_twin: like Current
+            -- New object field-by-field identical to `other'.
+            -- Always uses default copying semantics.
+        external
+            "built_in"
+        ensure
+            standard_twin_not_void: Result /= Void
+            equal: standard_equal (Result, Current)
+        end
+
+    frozen deep_twin: like Current
+            -- New object structure recursively duplicated from Current.
+        external
+            "built_in"
+        ensure
+            deep_twin_not_void: Result /= Void
+            deep_equal: deep_equal (Current, Result)
+        end
+
+    frozen deep_clone (other: detachable ANY): like other
+            -- Void if `other' is void: otherwise, new object structure
+            -- recursively duplicated from the one attached to `other'
+        obsolete
+            "Use `deep_twin' instead."
+        do
+            if other /= Void then
+                Result := other.deep_twin
+            end
+        ensure
+            deep_equal: deep_equal (other, Result)
+        end
+
+    frozen deep_copy (other: like Current)
+            -- Effect equivalent to that of:
+            --      `copy' (`other' . `deep_twin')
+        require
+            other_not_void: other /= Void
+        do
+            copy (other.deep_twin)
+        ensure
+            deep_equal: deep_equal (Current, other)
+        end
+
+feature {NONE} -- Retrieval
+
+    frozen internal_correct_mismatch
+            -- Called from runtime to perform a proper dynamic dispatch on `correct_mismatch'
+            -- from MISMATCH_CORRECTOR.
+        local
+            l_msg: STRING
+            l_exc: EXCEPTIONS
+        do
+            if attached {MISMATCH_CORRECTOR} Current as l_corrector then
+                l_corrector.correct_mismatch
+            else
+                create l_msg.make_from_string ("Mismatch: ")
+                create l_exc
+                l_msg.append (generating_type.name)
+                l_exc.raise_retrieval_exception (l_msg)
+            end
+        end
+
+feature -- Output
+
+    io: STD_FILES
+            -- Handle to standard file setup
+        once
+            create Result
+            Result.set_output_default
+        ensure
+            io_not_void: Result /= Void
+        end
+
+    out: STRING
+            -- New string containing terse printable representation
+            -- of current object
+        do
+            Result := tagged_out
+        ensure
+            out_not_void: Result /= Void
+        end
+
+    frozen tagged_out: STRING
+            -- New string containing terse printable representation
+            -- of current object
+        external
+            "built_in"
+        ensure
+            tagged_out_not_void: Result /= Void
+        end
+
+    print (o: detachable ANY)
+            -- Write terse external representation of `o'
+            -- on standard output.
+        do
+            if o /= Void then
+                io.put_string (o.out)
+            end
+        end
+
+feature -- Platform
+
+    Operating_environment: OPERATING_ENVIRONMENT
+            -- Objects available from the operating system
+        once
+            create Result
+        ensure
+            operating_environment_not_void: Result /= Void
+        end
+
+feature {NONE} -- Initialization
+
+    default_create
+            -- Process instances of classes with no creation clause.
+            -- (Default: do nothing.)
+        do
+        end
+
+feature -- Basic operations
+
+    default_rescue
+            -- Process exception for routines with no Rescue clause.
+            -- (Default: do nothing.)
+        do
+        end
+
+    frozen do_nothing
+            -- Execute a null action.
+        do
+        end
+
+    frozen default: detachable like Current
+            -- Default value of object's type
+        do
+        end
+
+    frozen default_pointer: POINTER
+            -- Default value of type `POINTER'
+            -- (Avoid the need to write `p'.`default' for
+            -- some `p' of type `POINTER'.)
+        do
+        ensure
+            -- Result = Result.default
+        end
+
+    frozen as_attached: attached like Current
+            -- Attached version of Current
+            -- (Can be used during transitional period to convert
+            -- non-void-safe classes to void-safe ones.)
+        do
+            Result := Current
+        end
+
+invariant
+    reflexive_equality: standard_is_equal (Current)
+    reflexive_conformance: conforms_to (Current)
+
+note
+    copyright: "Copyright (c) 1984-2012, Eiffel Software and others"
+    license:   "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
+    source: "[
+            Eiffel Software
+            5949 Hollister Ave., Goleta, CA 93117 USA
+            Telephone 805-685-1006, Fax 805-685-6869
+            Website http://www.eiffel.com
+            Customer support http://support.eiffel.com
+        ]"
+
+end
+
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: "text/x-eiffel",
+        indentUnit: 4,
+        lineNumbers: true,
+        theme: "neat"
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-eiffel</code>.</p>
+ 
+ <p> Created by <a href="https://github.com/ynh">YNH</a>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/erlang/erlang.js b/app/gui/html/vendor/codemirror/mode/erlang/erlang.js
new file mode 100644
index 0000000..79693fc
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/erlang/erlang.js
@@ -0,0 +1,619 @@
+/*jshint unused:true, eqnull:true, curly:true, bitwise:true */
+/*jshint undef:true, latedef:true, trailing:true */
+/*global CodeMirror:true */
+
+// erlang mode.
+// tokenizer -> token types -> CodeMirror styles
+// tokenizer maintains a parse stack
+// indenter uses the parse stack
+
+// TODO indenter:
+//   bit syntax
+//   old guard/bif/conversion clashes (e.g. "float/1")
+//   type/spec/opaque
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMIME("text/x-erlang", "erlang");
+
+CodeMirror.defineMode("erlang", function(cmCfg) {
+  "use strict";
+
+/////////////////////////////////////////////////////////////////////////////
+// constants
+
+  var typeWords = [
+    "-type", "-spec", "-export_type", "-opaque"];
+
+  var keywordWords = [
+    "after","begin","catch","case","cond","end","fun","if",
+    "let","of","query","receive","try","when"];
+
+  var separatorRE    = /[\->,;]/;
+  var separatorWords = [
+    "->",";",","];
+
+  var operatorAtomWords = [
+    "and","andalso","band","bnot","bor","bsl","bsr","bxor",
+    "div","not","or","orelse","rem","xor"];
+
+  var operatorSymbolRE    = /[\+\-\*\/<>=\|:!]/;
+  var operatorSymbolWords = [
+    "=","+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-","!"];
+
+  var openParenRE    = /[<\(\[\{]/;
+  var openParenWords = [
+    "<<","(","[","{"];
+
+  var closeParenRE    = /[>\)\]\}]/;
+  var closeParenWords = [
+    "}","]",")",">>"];
+
+  var guardWords = [
+    "is_atom","is_binary","is_bitstring","is_boolean","is_float",
+    "is_function","is_integer","is_list","is_number","is_pid",
+    "is_port","is_record","is_reference","is_tuple",
+    "atom","binary","bitstring","boolean","function","integer","list",
+    "number","pid","port","record","reference","tuple"];
+
+  var bifWords = [
+    "abs","adler32","adler32_combine","alive","apply","atom_to_binary",
+    "atom_to_list","binary_to_atom","binary_to_existing_atom",
+    "binary_to_list","binary_to_term","bit_size","bitstring_to_list",
+    "byte_size","check_process_code","contact_binary","crc32",
+    "crc32_combine","date","decode_packet","delete_module",
+    "disconnect_node","element","erase","exit","float","float_to_list",
+    "garbage_collect","get","get_keys","group_leader","halt","hd",
+    "integer_to_list","internal_bif","iolist_size","iolist_to_binary",
+    "is_alive","is_atom","is_binary","is_bitstring","is_boolean",
+    "is_float","is_function","is_integer","is_list","is_number","is_pid",
+    "is_port","is_process_alive","is_record","is_reference","is_tuple",
+    "length","link","list_to_atom","list_to_binary","list_to_bitstring",
+    "list_to_existing_atom","list_to_float","list_to_integer",
+    "list_to_pid","list_to_tuple","load_module","make_ref","module_loaded",
+    "monitor_node","node","node_link","node_unlink","nodes","notalive",
+    "now","open_port","pid_to_list","port_close","port_command",
+    "port_connect","port_control","pre_loaded","process_flag",
+    "process_info","processes","purge_module","put","register",
+    "registered","round","self","setelement","size","spawn","spawn_link",
+    "spawn_monitor","spawn_opt","split_binary","statistics",
+    "term_to_binary","time","throw","tl","trunc","tuple_size",
+    "tuple_to_list","unlink","unregister","whereis"];
+
+// upper case: [A-Z] [Ø-Þ] [À-Ö]
+// lower case: [a-z] [ß-ö] [ø-ÿ]
+  var anumRE       = /[\w@Ø-ÞÀ-Öß-öø-ÿ]/;
+  var escapesRE    =
+    /[0-7]{1,3}|[bdefnrstv\\"']|\^[a-zA-Z]|x[0-9a-zA-Z]{2}|x{[0-9a-zA-Z]+}/;
+
+/////////////////////////////////////////////////////////////////////////////
+// tokenizer
+
+  function tokenizer(stream,state) {
+    // in multi-line string
+    if (state.in_string) {
+      state.in_string = (!doubleQuote(stream));
+      return rval(state,stream,"string");
+    }
+
+    // in multi-line atom
+    if (state.in_atom) {
+      state.in_atom = (!singleQuote(stream));
+      return rval(state,stream,"atom");
+    }
+
+    // whitespace
+    if (stream.eatSpace()) {
+      return rval(state,stream,"whitespace");
+    }
+
+    // attributes and type specs
+    if (!peekToken(state) &&
+        stream.match(/-\s*[a-zß-öø-ÿ][\wØ-ÞÀ-Öß-öø-ÿ]*/)) {
+      if (is_member(stream.current(),typeWords)) {
+        return rval(state,stream,"type");
+      }else{
+        return rval(state,stream,"attribute");
+      }
+    }
+
+    var ch = stream.next();
+
+    // comment
+    if (ch == '%') {
+      stream.skipToEnd();
+      return rval(state,stream,"comment");
+    }
+
+    // colon
+    if (ch == ":") {
+      return rval(state,stream,"colon");
+    }
+
+    // macro
+    if (ch == '?') {
+      stream.eatSpace();
+      stream.eatWhile(anumRE);
+      return rval(state,stream,"macro");
+    }
+
+    // record
+    if (ch == "#") {
+      stream.eatSpace();
+      stream.eatWhile(anumRE);
+      return rval(state,stream,"record");
+    }
+
+    // dollar escape
+    if (ch == "$") {
+      if (stream.next() == "\\" && !stream.match(escapesRE)) {
+        return rval(state,stream,"error");
+      }
+      return rval(state,stream,"number");
+    }
+
+    // dot
+    if (ch == ".") {
+      return rval(state,stream,"dot");
+    }
+
+    // quoted atom
+    if (ch == '\'') {
+      if (!(state.in_atom = (!singleQuote(stream)))) {
+        if (stream.match(/\s*\/\s*[0-9]/,false)) {
+          stream.match(/\s*\/\s*[0-9]/,true);
+          return rval(state,stream,"fun");      // 'f'/0 style fun
+        }
+        if (stream.match(/\s*\(/,false) || stream.match(/\s*:/,false)) {
+          return rval(state,stream,"function");
+        }
+      }
+      return rval(state,stream,"atom");
+    }
+
+    // string
+    if (ch == '"') {
+      state.in_string = (!doubleQuote(stream));
+      return rval(state,stream,"string");
+    }
+
+    // variable
+    if (/[A-Z_Ø-ÞÀ-Ö]/.test(ch)) {
+      stream.eatWhile(anumRE);
+      return rval(state,stream,"variable");
+    }
+
+    // atom/keyword/BIF/function
+    if (/[a-z_ß-öø-ÿ]/.test(ch)) {
+      stream.eatWhile(anumRE);
+
+      if (stream.match(/\s*\/\s*[0-9]/,false)) {
+        stream.match(/\s*\/\s*[0-9]/,true);
+        return rval(state,stream,"fun");      // f/0 style fun
+      }
+
+      var w = stream.current();
+
+      if (is_member(w,keywordWords)) {
+        return rval(state,stream,"keyword");
+      }else if (is_member(w,operatorAtomWords)) {
+        return rval(state,stream,"operator");
+      }else if (stream.match(/\s*\(/,false)) {
+        // 'put' and 'erlang:put' are bifs, 'foo:put' is not
+        if (is_member(w,bifWords) &&
+            ((peekToken(state).token != ":") ||
+             (peekToken(state,2).token == "erlang"))) {
+          return rval(state,stream,"builtin");
+        }else if (is_member(w,guardWords)) {
+          return rval(state,stream,"guard");
+        }else{
+          return rval(state,stream,"function");
+        }
+      }else if (is_member(w,operatorAtomWords)) {
+        return rval(state,stream,"operator");
+      }else if (lookahead(stream) == ":") {
+        if (w == "erlang") {
+          return rval(state,stream,"builtin");
+        } else {
+          return rval(state,stream,"function");
+        }
+      }else if (is_member(w,["true","false"])) {
+        return rval(state,stream,"boolean");
+      }else if (is_member(w,["true","false"])) {
+        return rval(state,stream,"boolean");
+      }else{
+        return rval(state,stream,"atom");
+      }
+    }
+
+    // number
+    var digitRE      = /[0-9]/;
+    var radixRE      = /[0-9a-zA-Z]/;         // 36#zZ style int
+    if (digitRE.test(ch)) {
+      stream.eatWhile(digitRE);
+      if (stream.eat('#')) {                // 36#aZ  style integer
+        if (!stream.eatWhile(radixRE)) {
+          stream.backUp(1);                 //"36#" - syntax error
+        }
+      } else if (stream.eat('.')) {       // float
+        if (!stream.eatWhile(digitRE)) {
+          stream.backUp(1);        // "3." - probably end of function
+        } else {
+          if (stream.eat(/[eE]/)) {        // float with exponent
+            if (stream.eat(/[-+]/)) {
+              if (!stream.eatWhile(digitRE)) {
+                stream.backUp(2);            // "2e-" - syntax error
+              }
+            } else {
+              if (!stream.eatWhile(digitRE)) {
+                stream.backUp(1);            // "2e" - syntax error
+              }
+            }
+          }
+        }
+      }
+      return rval(state,stream,"number");   // normal integer
+    }
+
+    // open parens
+    if (nongreedy(stream,openParenRE,openParenWords)) {
+      return rval(state,stream,"open_paren");
+    }
+
+    // close parens
+    if (nongreedy(stream,closeParenRE,closeParenWords)) {
+      return rval(state,stream,"close_paren");
+    }
+
+    // separators
+    if (greedy(stream,separatorRE,separatorWords)) {
+      return rval(state,stream,"separator");
+    }
+
+    // operators
+    if (greedy(stream,operatorSymbolRE,operatorSymbolWords)) {
+      return rval(state,stream,"operator");
+    }
+
+    return rval(state,stream,null);
+  }
+
+/////////////////////////////////////////////////////////////////////////////
+// utilities
+  function nongreedy(stream,re,words) {
+    if (stream.current().length == 1 && re.test(stream.current())) {
+      stream.backUp(1);
+      while (re.test(stream.peek())) {
+        stream.next();
+        if (is_member(stream.current(),words)) {
+          return true;
+        }
+      }
+      stream.backUp(stream.current().length-1);
+    }
+    return false;
+  }
+
+  function greedy(stream,re,words) {
+    if (stream.current().length == 1 && re.test(stream.current())) {
+      while (re.test(stream.peek())) {
+        stream.next();
+      }
+      while (0 < stream.current().length) {
+        if (is_member(stream.current(),words)) {
+          return true;
+        }else{
+          stream.backUp(1);
+        }
+      }
+      stream.next();
+    }
+    return false;
+  }
+
+  function doubleQuote(stream) {
+    return quote(stream, '"', '\\');
+  }
+
+  function singleQuote(stream) {
+    return quote(stream,'\'','\\');
+  }
+
+  function quote(stream,quoteChar,escapeChar) {
+    while (!stream.eol()) {
+      var ch = stream.next();
+      if (ch == quoteChar) {
+        return true;
+      }else if (ch == escapeChar) {
+        stream.next();
+      }
+    }
+    return false;
+  }
+
+  function lookahead(stream) {
+    var m = stream.match(/([\n\s]+|%[^\n]*\n)*(.)/,false);
+    return m ? m.pop() : "";
+  }
+
+  function is_member(element,list) {
+    return (-1 < list.indexOf(element));
+  }
+
+  function rval(state,stream,type) {
+
+    // parse stack
+    pushToken(state,realToken(type,stream));
+
+    // map erlang token type to CodeMirror style class
+    //     erlang             -> CodeMirror tag
+    switch (type) {
+      case "atom":        return "atom";
+      case "attribute":   return "attribute";
+      case "boolean":     return "special";
+      case "builtin":     return "builtin";
+      case "close_paren": return null;
+      case "colon":       return null;
+      case "comment":     return "comment";
+      case "dot":         return null;
+      case "error":       return "error";
+      case "fun":         return "meta";
+      case "function":    return "tag";
+      case "guard":       return "property";
+      case "keyword":     return "keyword";
+      case "macro":       return "variable-2";
+      case "number":      return "number";
+      case "open_paren":  return null;
+      case "operator":    return "operator";
+      case "record":      return "bracket";
+      case "separator":   return null;
+      case "string":      return "string";
+      case "type":        return "def";
+      case "variable":    return "variable";
+      default:            return null;
+    }
+  }
+
+  function aToken(tok,col,ind,typ) {
+    return {token:  tok,
+            column: col,
+            indent: ind,
+            type:   typ};
+  }
+
+  function realToken(type,stream) {
+    return aToken(stream.current(),
+                 stream.column(),
+                 stream.indentation(),
+                 type);
+  }
+
+  function fakeToken(type) {
+    return aToken(type,0,0,type);
+  }
+
+  function peekToken(state,depth) {
+    var len = state.tokenStack.length;
+    var dep = (depth ? depth : 1);
+
+    if (len < dep) {
+      return false;
+    }else{
+      return state.tokenStack[len-dep];
+    }
+  }
+
+  function pushToken(state,token) {
+
+    if (!(token.type == "comment" || token.type == "whitespace")) {
+      state.tokenStack = maybe_drop_pre(state.tokenStack,token);
+      state.tokenStack = maybe_drop_post(state.tokenStack);
+    }
+  }
+
+  function maybe_drop_pre(s,token) {
+    var last = s.length-1;
+
+    if (0 < last && s[last].type === "record" && token.type === "dot") {
+      s.pop();
+    }else if (0 < last && s[last].type === "group") {
+      s.pop();
+      s.push(token);
+    }else{
+      s.push(token);
+    }
+    return s;
+  }
+
+  function maybe_drop_post(s) {
+    var last = s.length-1;
+
+    if (s[last].type === "dot") {
+      return [];
+    }
+    if (s[last].type === "fun" && s[last-1].token === "fun") {
+      return s.slice(0,last-1);
+    }
+    switch (s[s.length-1].token) {
+      case "}":    return d(s,{g:["{"]});
+      case "]":    return d(s,{i:["["]});
+      case ")":    return d(s,{i:["("]});
+      case ">>":   return d(s,{i:["<<"]});
+      case "end":  return d(s,{i:["begin","case","fun","if","receive","try"]});
+      case ",":    return d(s,{e:["begin","try","when","->",
+                                  ",","(","[","{","<<"]});
+      case "->":   return d(s,{r:["when"],
+                               m:["try","if","case","receive"]});
+      case ";":    return d(s,{E:["case","fun","if","receive","try","when"]});
+      case "catch":return d(s,{e:["try"]});
+      case "of":   return d(s,{e:["case"]});
+      case "after":return d(s,{e:["receive","try"]});
+      default:     return s;
+    }
+  }
+
+  function d(stack,tt) {
+    // stack is a stack of Token objects.
+    // tt is an object; {type:tokens}
+    // type is a char, tokens is a list of token strings.
+    // The function returns (possibly truncated) stack.
+    // It will descend the stack, looking for a Token such that Token.token
+    //  is a member of tokens. If it does not find that, it will normally (but
+    //  see "E" below) return stack. If it does find a match, it will remove
+    //  all the Tokens between the top and the matched Token.
+    // If type is "m", that is all it does.
+    // If type is "i", it will also remove the matched Token and the top Token.
+    // If type is "g", like "i", but add a fake "group" token at the top.
+    // If type is "r", it will remove the matched Token, but not the top Token.
+    // If type is "e", it will keep the matched Token but not the top Token.
+    // If type is "E", it behaves as for type "e", except if there is no match,
+    //  in which case it will return an empty stack.
+
+    for (var type in tt) {
+      var len = stack.length-1;
+      var tokens = tt[type];
+      for (var i = len-1; -1 < i ; i--) {
+        if (is_member(stack[i].token,tokens)) {
+          var ss = stack.slice(0,i);
+          switch (type) {
+              case "m": return ss.concat(stack[i]).concat(stack[len]);
+              case "r": return ss.concat(stack[len]);
+              case "i": return ss;
+              case "g": return ss.concat(fakeToken("group"));
+              case "E": return ss.concat(stack[i]);
+              case "e": return ss.concat(stack[i]);
+          }
+        }
+      }
+    }
+    return (type == "E" ? [] : stack);
+  }
+
+/////////////////////////////////////////////////////////////////////////////
+// indenter
+
+  function indenter(state,textAfter) {
+    var t;
+    var unit = cmCfg.indentUnit;
+    var wordAfter = wordafter(textAfter);
+    var currT = peekToken(state,1);
+    var prevT = peekToken(state,2);
+
+    if (state.in_string || state.in_atom) {
+      return CodeMirror.Pass;
+    }else if (!prevT) {
+      return 0;
+    }else if (currT.token == "when") {
+      return currT.column+unit;
+    }else if (wordAfter === "when" && prevT.type === "function") {
+      return prevT.indent+unit;
+    }else if (wordAfter === "(" && currT.token === "fun") {
+      return  currT.column+3;
+    }else if (wordAfter === "catch" && (t = getToken(state,["try"]))) {
+      return t.column;
+    }else if (is_member(wordAfter,["end","after","of"])) {
+      t = getToken(state,["begin","case","fun","if","receive","try"]);
+      return t ? t.column : CodeMirror.Pass;
+    }else if (is_member(wordAfter,closeParenWords)) {
+      t = getToken(state,openParenWords);
+      return t ? t.column : CodeMirror.Pass;
+    }else if (is_member(currT.token,[",","|","||"]) ||
+              is_member(wordAfter,[",","|","||"])) {
+      t = postcommaToken(state);
+      return t ? t.column+t.token.length : unit;
+    }else if (currT.token == "->") {
+      if (is_member(prevT.token, ["receive","case","if","try"])) {
+        return prevT.column+unit+unit;
+      }else{
+        return prevT.column+unit;
+      }
+    }else if (is_member(currT.token,openParenWords)) {
+      return currT.column+currT.token.length;
+    }else{
+      t = defaultToken(state);
+      return truthy(t) ? t.column+unit : 0;
+    }
+  }
+
+  function wordafter(str) {
+    var m = str.match(/,|[a-z]+|\}|\]|\)|>>|\|+|\(/);
+
+    return truthy(m) && (m.index === 0) ? m[0] : "";
+  }
+
+  function postcommaToken(state) {
+    var objs = state.tokenStack.slice(0,-1);
+    var i = getTokenIndex(objs,"type",["open_paren"]);
+
+    return truthy(objs[i]) ? objs[i] : false;
+  }
+
+  function defaultToken(state) {
+    var objs = state.tokenStack;
+    var stop = getTokenIndex(objs,"type",["open_paren","separator","keyword"]);
+    var oper = getTokenIndex(objs,"type",["operator"]);
+
+    if (truthy(stop) && truthy(oper) && stop < oper) {
+      return objs[stop+1];
+    } else if (truthy(stop)) {
+      return objs[stop];
+    } else {
+      return false;
+    }
+  }
+
+  function getToken(state,tokens) {
+    var objs = state.tokenStack;
+    var i = getTokenIndex(objs,"token",tokens);
+
+    return truthy(objs[i]) ? objs[i] : false;
+  }
+
+  function getTokenIndex(objs,propname,propvals) {
+
+    for (var i = objs.length-1; -1 < i ; i--) {
+      if (is_member(objs[i][propname],propvals)) {
+        return i;
+      }
+    }
+    return false;
+  }
+
+  function truthy(x) {
+    return (x !== false) && (x != null);
+  }
+
+/////////////////////////////////////////////////////////////////////////////
+// this object defines the mode
+
+  return {
+    startState:
+      function() {
+        return {tokenStack: [],
+                in_string:  false,
+                in_atom:    false};
+      },
+
+    token:
+      function(stream, state) {
+        return tokenizer(stream, state);
+      },
+
+    indent:
+      function(state, textAfter) {
+        return indenter(state,textAfter);
+      },
+
+    lineComment: "%"
+  };
+});
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/erlang/index.html b/app/gui/html/vendor/codemirror/mode/erlang/index.html
new file mode 100644
index 0000000..9cacb75
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/erlang/index.html
@@ -0,0 +1,76 @@
+<!doctype html>
+
+<title>CodeMirror: Erlang mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link rel="stylesheet" href="../../theme/erlang-dark.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="erlang.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Erlang</a>
+  </ul>
+</div>
+
+<article>
+<h2>Erlang mode</h2>
+<form><textarea id="code" name="code">
+%% -*- mode: erlang; erlang-indent-level: 2 -*-
+%%% Created :  7 May 2012 by mats cronqvist <masse at klarna.com>
+
+%% @doc
+%% Demonstrates how to print a record.
+%% @end
+
+-module('ex').
+-author('mats cronqvist').
+-export([demo/0,
+         rec_info/1]).
+
+-record(demo,{a="One",b="Two",c="Three",d="Four"}).
+
+rec_info(demo) -> record_info(fields,demo).
+
+demo() -> expand_recs(?MODULE,#demo{a="A",b="BB"}).
+
+expand_recs(M,List) when is_list(List) ->
+  [expand_recs(M,L)||L<-List];
+expand_recs(M,Tup) when is_tuple(Tup) ->
+  case tuple_size(Tup) of
+    L when L < 1 -> Tup;
+    L ->
+      try
+        Fields = M:rec_info(element(1,Tup)),
+        L = length(Fields)+1,
+        lists:zip(Fields,expand_recs(M,tl(tuple_to_list(Tup))))
+      catch
+        _:_ -> list_to_tuple(expand_recs(M,tuple_to_list(Tup)))
+      end
+  end;
+expand_recs(_,Term) ->
+  Term.
+</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        extraKeys: {"Tab":  "indentAuto"},
+        theme: "erlang-dark"
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-erlang</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/fortran/fortran.js b/app/gui/html/vendor/codemirror/mode/fortran/fortran.js
new file mode 100644
index 0000000..58dac12
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/fortran/fortran.js
@@ -0,0 +1,185 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("fortran", function() {
+  function words(array) {
+    var keys = {};
+    for (var i = 0; i < array.length; ++i) {
+      keys[array[i]] = true;
+    }
+    return keys;
+  }
+
+  var keywords = words([
+                  "abstract", "accept", "allocatable", "allocate",
+                  "array", "assign", "asynchronous", "backspace",
+                  "bind", "block", "byte", "call", "case",
+                  "class", "close", "common", "contains",
+                  "continue", "cycle", "data", "deallocate",
+                  "decode", "deferred", "dimension", "do",
+                  "elemental", "else", "encode", "end",
+                  "endif", "entry", "enumerator", "equivalence",
+                  "exit", "external", "extrinsic", "final",
+                  "forall", "format", "function", "generic",
+                  "go", "goto", "if", "implicit", "import", "include",
+                  "inquire", "intent", "interface", "intrinsic",
+                  "module", "namelist", "non_intrinsic",
+                  "non_overridable", "none", "nopass",
+                  "nullify", "open", "optional", "options",
+                  "parameter", "pass", "pause", "pointer",
+                  "print", "private", "program", "protected",
+                  "public", "pure", "read", "recursive", "result",
+                  "return", "rewind", "save", "select", "sequence",
+                  "stop", "subroutine", "target", "then", "to", "type",
+                  "use", "value", "volatile", "where", "while",
+                  "write"]);
+  var builtins = words(["abort", "abs", "access", "achar", "acos",
+                          "adjustl", "adjustr", "aimag", "aint", "alarm",
+                          "all", "allocated", "alog", "amax", "amin",
+                          "amod", "and", "anint", "any", "asin",
+                          "associated", "atan", "besj", "besjn", "besy",
+                          "besyn", "bit_size", "btest", "cabs", "ccos",
+                          "ceiling", "cexp", "char", "chdir", "chmod",
+                          "clog", "cmplx", "command_argument_count",
+                          "complex", "conjg", "cos", "cosh", "count",
+                          "cpu_time", "cshift", "csin", "csqrt", "ctime",
+                          "c_funloc", "c_loc", "c_associated", "c_null_ptr",
+                          "c_null_funptr", "c_f_pointer", "c_null_char",
+                          "c_alert", "c_backspace", "c_form_feed",
+                          "c_new_line", "c_carriage_return",
+                          "c_horizontal_tab", "c_vertical_tab", "dabs",
+                          "dacos", "dasin", "datan", "date_and_time",
+                          "dbesj", "dbesj", "dbesjn", "dbesy", "dbesy",
+                          "dbesyn", "dble", "dcos", "dcosh", "ddim", "derf",
+                          "derfc", "dexp", "digits", "dim", "dint", "dlog",
+                          "dlog", "dmax", "dmin", "dmod", "dnint",
+                          "dot_product", "dprod", "dsign", "dsinh",
+                          "dsin", "dsqrt", "dtanh", "dtan", "dtime",
+                          "eoshift", "epsilon", "erf", "erfc", "etime",
+                          "exit", "exp", "exponent", "extends_type_of",
+                          "fdate", "fget", "fgetc", "float", "floor",
+                          "flush", "fnum", "fputc", "fput", "fraction",
+                          "fseek", "fstat", "ftell", "gerror", "getarg",
+                          "get_command", "get_command_argument",
+                          "get_environment_variable", "getcwd",
+                          "getenv", "getgid", "getlog", "getpid",
+                          "getuid", "gmtime", "hostnm", "huge", "iabs",
+                          "iachar", "iand", "iargc", "ibclr", "ibits",
+                          "ibset", "ichar", "idate", "idim", "idint",
+                          "idnint", "ieor", "ierrno", "ifix", "imag",
+                          "imagpart", "index", "int", "ior", "irand",
+                          "isatty", "ishft", "ishftc", "isign",
+                          "iso_c_binding", "is_iostat_end", "is_iostat_eor",
+                          "itime", "kill", "kind", "lbound", "len", "len_trim",
+                          "lge", "lgt", "link", "lle", "llt", "lnblnk", "loc",
+                          "log", "logical", "long", "lshift", "lstat", "ltime",
+                          "matmul", "max", "maxexponent", "maxloc", "maxval",
+                          "mclock", "merge", "move_alloc", "min", "minexponent",
+                          "minloc", "minval", "mod", "modulo", "mvbits",
+                          "nearest", "new_line", "nint", "not", "or", "pack",
+                          "perror", "precision", "present", "product", "radix",
+                          "rand", "random_number", "random_seed", "range",
+                          "real", "realpart", "rename", "repeat", "reshape",
+                          "rrspacing", "rshift", "same_type_as", "scale",
+                          "scan", "second", "selected_int_kind",
+                          "selected_real_kind", "set_exponent", "shape",
+                          "short", "sign", "signal", "sinh", "sin", "sleep",
+                          "sngl", "spacing", "spread", "sqrt", "srand", "stat",
+                          "sum", "symlnk", "system", "system_clock", "tan",
+                          "tanh", "time", "tiny", "transfer", "transpose",
+                          "trim", "ttynam", "ubound", "umask", "unlink",
+                          "unpack", "verify", "xor", "zabs", "zcos", "zexp",
+                          "zlog", "zsin", "zsqrt"]);
+
+    var dataTypes =  words(["c_bool", "c_char", "c_double", "c_double_complex",
+                     "c_float", "c_float_complex", "c_funptr", "c_int",
+                     "c_int16_t", "c_int32_t", "c_int64_t", "c_int8_t",
+                     "c_int_fast16_t", "c_int_fast32_t", "c_int_fast64_t",
+                     "c_int_fast8_t", "c_int_least16_t", "c_int_least32_t",
+                     "c_int_least64_t", "c_int_least8_t", "c_intmax_t",
+                     "c_intptr_t", "c_long", "c_long_double",
+                     "c_long_double_complex", "c_long_long", "c_ptr",
+                     "c_short", "c_signed_char", "c_size_t", "character",
+                     "complex", "double", "integer", "logical", "real"]);
+  var isOperatorChar = /[+\-*&=<>\/\:]/;
+  var litOperator = new RegExp("(\.and\.|\.or\.|\.eq\.|\.lt\.|\.le\.|\.gt\.|\.ge\.|\.ne\.|\.not\.|\.eqv\.|\.neqv\.)", "i");
+
+  function tokenBase(stream, state) {
+
+    if (stream.match(litOperator)){
+        return 'operator';
+    }
+
+    var ch = stream.next();
+    if (ch == "!") {
+      stream.skipToEnd();
+      return "comment";
+    }
+    if (ch == '"' || ch == "'") {
+      state.tokenize = tokenString(ch);
+      return state.tokenize(stream, state);
+    }
+    if (/[\[\]\(\),]/.test(ch)) {
+      return null;
+    }
+    if (/\d/.test(ch)) {
+      stream.eatWhile(/[\w\.]/);
+      return "number";
+    }
+    if (isOperatorChar.test(ch)) {
+      stream.eatWhile(isOperatorChar);
+      return "operator";
+    }
+    stream.eatWhile(/[\w\$_]/);
+    var word = stream.current().toLowerCase();
+
+    if (keywords.hasOwnProperty(word)){
+            return 'keyword';
+    }
+    if (builtins.hasOwnProperty(word) || dataTypes.hasOwnProperty(word)) {
+            return 'builtin';
+    }
+    return "variable";
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, next, end = false;
+      while ((next = stream.next()) != null) {
+        if (next == quote && !escaped) {
+            end = true;
+            break;
+        }
+        escaped = !escaped && next == "\\";
+      }
+      if (end || !escaped) state.tokenize = null;
+      return "string";
+    };
+  }
+
+  // Interface
+
+  return {
+    startState: function() {
+      return {tokenize: null};
+    },
+
+    token: function(stream, state) {
+      if (stream.eatSpace()) return null;
+      var style = (state.tokenize || tokenBase)(stream, state);
+      if (style == "comment" || style == "meta") return style;
+      return style;
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/x-fortran", "fortran");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/fortran/index.html b/app/gui/html/vendor/codemirror/mode/fortran/index.html
new file mode 100644
index 0000000..efa55ec
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/fortran/index.html
@@ -0,0 +1,81 @@
+<!doctype html>
+
+<title>CodeMirror: Fortran mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="fortran.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Fortran</a>
+  </ul>
+</div>
+
+<article>
+<h2>Fortran mode</h2>
+
+
+<div><textarea id="code" name="code">
+! Example Fortran code
+  program average
+
+  ! Read in some numbers and take the average
+  ! As written, if there are no data points, an average of zero is returned
+  ! While this may not be desired behavior, it keeps this example simple
+
+  implicit none
+
+  real, dimension(:), allocatable :: points
+  integer                         :: number_of_points
+  real                            :: average_points=0., positive_average=0., negative_average=0.
+
+  write (*,*) "Input number of points to average:"
+  read  (*,*) number_of_points
+
+  allocate (points(number_of_points))
+
+  write (*,*) "Enter the points to average:"
+  read  (*,*) points
+
+  ! Take the average by summing points and dividing by number_of_points
+  if (number_of_points > 0) average_points = sum(points) / number_of_points
+
+  ! Now form average over positive and negative points only
+  if (count(points > 0.) > 0) then
+     positive_average = sum(points, points > 0.) / count(points > 0.)
+  end if
+
+  if (count(points < 0.) > 0) then
+     negative_average = sum(points, points < 0.) / count(points < 0.)
+  end if
+
+  deallocate (points)
+
+  ! Print result to terminal
+  write (*,'(a,g12.4)') 'Average = ', average_points
+  write (*,'(a,g12.4)') 'Average of positive points = ', positive_average
+  write (*,'(a,g12.4)') 'Average of negative points = ', negative_average
+
+  end program average
+</textarea></div>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        mode: "text/x-fortran"
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-Fortran</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/gas/gas.js b/app/gui/html/vendor/codemirror/mode/gas/gas.js
new file mode 100644
index 0000000..ba5f195
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/gas/gas.js
@@ -0,0 +1,342 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("gas", function(_config, parserConfig) {
+  'use strict';
+
+  // If an architecture is specified, its initialization function may
+  // populate this array with custom parsing functions which will be
+  // tried in the event that the standard functions do not find a match.
+  var custom = [];
+
+  // The symbol used to start a line comment changes based on the target
+  // architecture.
+  // If no architecture is pased in "parserConfig" then only multiline
+  // comments will have syntax support.
+  var lineCommentStartSymbol = "";
+
+  // These directives are architecture independent.
+  // Machine specific directives should go in their respective
+  // architecture initialization function.
+  // Reference:
+  // http://sourceware.org/binutils/docs/as/Pseudo-Ops.html#Pseudo-Ops
+  var directives = {
+    ".abort" : "builtin",
+    ".align" : "builtin",
+    ".altmacro" : "builtin",
+    ".ascii" : "builtin",
+    ".asciz" : "builtin",
+    ".balign" : "builtin",
+    ".balignw" : "builtin",
+    ".balignl" : "builtin",
+    ".bundle_align_mode" : "builtin",
+    ".bundle_lock" : "builtin",
+    ".bundle_unlock" : "builtin",
+    ".byte" : "builtin",
+    ".cfi_startproc" : "builtin",
+    ".comm" : "builtin",
+    ".data" : "builtin",
+    ".def" : "builtin",
+    ".desc" : "builtin",
+    ".dim" : "builtin",
+    ".double" : "builtin",
+    ".eject" : "builtin",
+    ".else" : "builtin",
+    ".elseif" : "builtin",
+    ".end" : "builtin",
+    ".endef" : "builtin",
+    ".endfunc" : "builtin",
+    ".endif" : "builtin",
+    ".equ" : "builtin",
+    ".equiv" : "builtin",
+    ".eqv" : "builtin",
+    ".err" : "builtin",
+    ".error" : "builtin",
+    ".exitm" : "builtin",
+    ".extern" : "builtin",
+    ".fail" : "builtin",
+    ".file" : "builtin",
+    ".fill" : "builtin",
+    ".float" : "builtin",
+    ".func" : "builtin",
+    ".global" : "builtin",
+    ".gnu_attribute" : "builtin",
+    ".hidden" : "builtin",
+    ".hword" : "builtin",
+    ".ident" : "builtin",
+    ".if" : "builtin",
+    ".incbin" : "builtin",
+    ".include" : "builtin",
+    ".int" : "builtin",
+    ".internal" : "builtin",
+    ".irp" : "builtin",
+    ".irpc" : "builtin",
+    ".lcomm" : "builtin",
+    ".lflags" : "builtin",
+    ".line" : "builtin",
+    ".linkonce" : "builtin",
+    ".list" : "builtin",
+    ".ln" : "builtin",
+    ".loc" : "builtin",
+    ".loc_mark_labels" : "builtin",
+    ".local" : "builtin",
+    ".long" : "builtin",
+    ".macro" : "builtin",
+    ".mri" : "builtin",
+    ".noaltmacro" : "builtin",
+    ".nolist" : "builtin",
+    ".octa" : "builtin",
+    ".offset" : "builtin",
+    ".org" : "builtin",
+    ".p2align" : "builtin",
+    ".popsection" : "builtin",
+    ".previous" : "builtin",
+    ".print" : "builtin",
+    ".protected" : "builtin",
+    ".psize" : "builtin",
+    ".purgem" : "builtin",
+    ".pushsection" : "builtin",
+    ".quad" : "builtin",
+    ".reloc" : "builtin",
+    ".rept" : "builtin",
+    ".sbttl" : "builtin",
+    ".scl" : "builtin",
+    ".section" : "builtin",
+    ".set" : "builtin",
+    ".short" : "builtin",
+    ".single" : "builtin",
+    ".size" : "builtin",
+    ".skip" : "builtin",
+    ".sleb128" : "builtin",
+    ".space" : "builtin",
+    ".stab" : "builtin",
+    ".string" : "builtin",
+    ".struct" : "builtin",
+    ".subsection" : "builtin",
+    ".symver" : "builtin",
+    ".tag" : "builtin",
+    ".text" : "builtin",
+    ".title" : "builtin",
+    ".type" : "builtin",
+    ".uleb128" : "builtin",
+    ".val" : "builtin",
+    ".version" : "builtin",
+    ".vtable_entry" : "builtin",
+    ".vtable_inherit" : "builtin",
+    ".warning" : "builtin",
+    ".weak" : "builtin",
+    ".weakref" : "builtin",
+    ".word" : "builtin"
+  };
+
+  var registers = {};
+
+  function x86(_parserConfig) {
+    lineCommentStartSymbol = "#";
+
+    registers.ax  = "variable";
+    registers.eax = "variable-2";
+    registers.rax = "variable-3";
+
+    registers.bx  = "variable";
+    registers.ebx = "variable-2";
+    registers.rbx = "variable-3";
+
+    registers.cx  = "variable";
+    registers.ecx = "variable-2";
+    registers.rcx = "variable-3";
+
+    registers.dx  = "variable";
+    registers.edx = "variable-2";
+    registers.rdx = "variable-3";
+
+    registers.si  = "variable";
+    registers.esi = "variable-2";
+    registers.rsi = "variable-3";
+
+    registers.di  = "variable";
+    registers.edi = "variable-2";
+    registers.rdi = "variable-3";
+
+    registers.sp  = "variable";
+    registers.esp = "variable-2";
+    registers.rsp = "variable-3";
+
+    registers.bp  = "variable";
+    registers.ebp = "variable-2";
+    registers.rbp = "variable-3";
+
+    registers.ip  = "variable";
+    registers.eip = "variable-2";
+    registers.rip = "variable-3";
+
+    registers.cs  = "keyword";
+    registers.ds  = "keyword";
+    registers.ss  = "keyword";
+    registers.es  = "keyword";
+    registers.fs  = "keyword";
+    registers.gs  = "keyword";
+  }
+
+  function armv6(_parserConfig) {
+    // Reference:
+    // http://infocenter.arm.com/help/topic/com.arm.doc.qrc0001l/QRC0001_UAL.pdf
+    // http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301h/DDI0301H_arm1176jzfs_r0p7_trm.pdf
+    lineCommentStartSymbol = "@";
+    directives.syntax = "builtin";
+
+    registers.r0  = "variable";
+    registers.r1  = "variable";
+    registers.r2  = "variable";
+    registers.r3  = "variable";
+    registers.r4  = "variable";
+    registers.r5  = "variable";
+    registers.r6  = "variable";
+    registers.r7  = "variable";
+    registers.r8  = "variable";
+    registers.r9  = "variable";
+    registers.r10 = "variable";
+    registers.r11 = "variable";
+    registers.r12 = "variable";
+
+    registers.sp  = "variable-2";
+    registers.lr  = "variable-2";
+    registers.pc  = "variable-2";
+    registers.r13 = registers.sp;
+    registers.r14 = registers.lr;
+    registers.r15 = registers.pc;
+
+    custom.push(function(ch, stream) {
+      if (ch === '#') {
+        stream.eatWhile(/\w/);
+        return "number";
+      }
+    });
+  }
+
+  var arch = (parserConfig.architecture || "x86").toLowerCase();
+  if (arch === "x86") {
+    x86(parserConfig);
+  } else if (arch === "arm" || arch === "armv6") {
+    armv6(parserConfig);
+  }
+
+  function nextUntilUnescaped(stream, end) {
+    var escaped = false, next;
+    while ((next = stream.next()) != null) {
+      if (next === end && !escaped) {
+        return false;
+      }
+      escaped = !escaped && next === "\\";
+    }
+    return escaped;
+  }
+
+  function clikeComment(stream, state) {
+    var maybeEnd = false, ch;
+    while ((ch = stream.next()) != null) {
+      if (ch === "/" && maybeEnd) {
+        state.tokenize = null;
+        break;
+      }
+      maybeEnd = (ch === "*");
+    }
+    return "comment";
+  }
+
+  return {
+    startState: function() {
+      return {
+        tokenize: null
+      };
+    },
+
+    token: function(stream, state) {
+      if (state.tokenize) {
+        return state.tokenize(stream, state);
+      }
+
+      if (stream.eatSpace()) {
+        return null;
+      }
+
+      var style, cur, ch = stream.next();
+
+      if (ch === "/") {
+        if (stream.eat("*")) {
+          state.tokenize = clikeComment;
+          return clikeComment(stream, state);
+        }
+      }
+
+      if (ch === lineCommentStartSymbol) {
+        stream.skipToEnd();
+        return "comment";
+      }
+
+      if (ch === '"') {
+        nextUntilUnescaped(stream, '"');
+        return "string";
+      }
+
+      if (ch === '.') {
+        stream.eatWhile(/\w/);
+        cur = stream.current().toLowerCase();
+        style = directives[cur];
+        return style || null;
+      }
+
+      if (ch === '=') {
+        stream.eatWhile(/\w/);
+        return "tag";
+      }
+
+      if (ch === '{') {
+        return "braket";
+      }
+
+      if (ch === '}') {
+        return "braket";
+      }
+
+      if (/\d/.test(ch)) {
+        if (ch === "0" && stream.eat("x")) {
+          stream.eatWhile(/[0-9a-fA-F]/);
+          return "number";
+        }
+        stream.eatWhile(/\d/);
+        return "number";
+      }
+
+      if (/\w/.test(ch)) {
+        stream.eatWhile(/\w/);
+        if (stream.eat(":")) {
+          return 'tag';
+        }
+        cur = stream.current().toLowerCase();
+        style = registers[cur];
+        return style || null;
+      }
+
+      for (var i = 0; i < custom.length; i++) {
+        style = custom[i](ch, stream, state);
+        if (style) {
+          return style;
+        }
+      }
+    },
+
+    lineComment: lineCommentStartSymbol,
+    blockCommentStart: "/*",
+    blockCommentEnd: "*/"
+  };
+});
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/gas/index.html b/app/gui/html/vendor/codemirror/mode/gas/index.html
new file mode 100644
index 0000000..cd8a2ff
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/gas/index.html
@@ -0,0 +1,68 @@
+<!doctype html>
+
+<title>CodeMirror: Gas mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="gas.js"></script>
+<style>.CodeMirror {border: 2px inset #dee;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Gas</a>
+  </ul>
+</div>
+
+<article>
+<h2>Gas mode</h2>
+<form>
+<textarea id="code" name="code">
+.syntax unified
+.global main
+
+/* 
+ *  A
+ *  multi-line
+ *  comment.
+ */
+
+@ A single line comment.
+
+main:
+        push    {sp, lr}
+        ldr     r0, =message
+        bl      puts
+        mov     r0, #0
+        pop     {sp, pc}
+
+message:
+        .asciz "Hello world!<br />"
+</textarea>
+        </form>
+
+        <script>
+            var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+                lineNumbers: true,
+                mode: {name: "gas", architecture: "ARMv6"},
+            });
+        </script>
+
+        <p>Handles AT&T assembler syntax (more specifically this handles
+        the GNU Assembler (gas) syntax.)
+        It takes a single optional configuration parameter:
+        <code>architecture</code>, which can be one of <code>"ARM"</code>,
+        <code>"ARMv6"</code> or <code>"x86"</code>.
+        Including the parameter adds syntax for the registers and special
+        directives for the supplied architecture.
+
+        <p><strong>MIME types defined:</strong> <code>text/x-gas</code></p>
+    </article>
diff --git a/app/gui/html/vendor/codemirror/mode/gfm/gfm.js b/app/gui/html/vendor/codemirror/mode/gfm/gfm.js
new file mode 100644
index 0000000..8fcc9f7
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/gfm/gfm.js
@@ -0,0 +1,114 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("../markdown/markdown"), require("../../addon/mode/overlay"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "../markdown/markdown", "../../addon/mode/overlay"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("gfm", function(config, modeConfig) {
+  var codeDepth = 0;
+  function blankLine(state) {
+    state.code = false;
+    return null;
+  }
+  var gfmOverlay = {
+    startState: function() {
+      return {
+        code: false,
+        codeBlock: false,
+        ateSpace: false
+      };
+    },
+    copyState: function(s) {
+      return {
+        code: s.code,
+        codeBlock: s.codeBlock,
+        ateSpace: s.ateSpace
+      };
+    },
+    token: function(stream, state) {
+      // Hack to prevent formatting override inside code blocks (block and inline)
+      if (state.codeBlock) {
+        if (stream.match(/^```/)) {
+          state.codeBlock = false;
+          return null;
+        }
+        stream.skipToEnd();
+        return null;
+      }
+      if (stream.sol()) {
+        state.code = false;
+      }
+      if (stream.sol() && stream.match(/^```/)) {
+        stream.skipToEnd();
+        state.codeBlock = true;
+        return null;
+      }
+      // If this block is changed, it may need to be updated in Markdown mode
+      if (stream.peek() === '`') {
+        stream.next();
+        var before = stream.pos;
+        stream.eatWhile('`');
+        var difference = 1 + stream.pos - before;
+        if (!state.code) {
+          codeDepth = difference;
+          state.code = true;
+        } else {
+          if (difference === codeDepth) { // Must be exact
+            state.code = false;
+          }
+        }
+        return null;
+      } else if (state.code) {
+        stream.next();
+        return null;
+      }
+      // Check if space. If so, links can be formatted later on
+      if (stream.eatSpace()) {
+        state.ateSpace = true;
+        return null;
+      }
+      if (stream.sol() || state.ateSpace) {
+        state.ateSpace = false;
+        if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?:[a-f0-9]{7,40}\b)/)) {
+          // User/Project at SHA
+          // User at SHA
+          // SHA
+          return "link";
+        } else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) {
+          // User/Project#Num
+          // User#Num
+          // #Num
+          return "link";
+        }
+      }
+      if (stream.match(/^((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/i) &&
+         stream.string.slice(stream.start - 2, stream.start) != "](") {
+        // URLs
+        // Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
+        // And then (issue #1160) simplified to make it not crash the Chrome Regexp engine
+        return "link";
+      }
+      stream.next();
+      return null;
+    },
+    blankLine: blankLine
+  };
+
+  var markdownConfig = {
+    underscoresBreakWords: false,
+    taskLists: true,
+    fencedCodeBlocks: true
+  };
+  for (var attr in modeConfig) {
+    markdownConfig[attr] = modeConfig[attr];
+  }
+  markdownConfig.name = "markdown";
+  CodeMirror.defineMIME("gfmBase", markdownConfig);
+  return CodeMirror.overlayMode(CodeMirror.getMode(config, "gfmBase"), gfmOverlay);
+}, "markdown");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/gfm/index.html b/app/gui/html/vendor/codemirror/mode/gfm/index.html
new file mode 100644
index 0000000..b71cd5c
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/gfm/index.html
@@ -0,0 +1,82 @@
+<!doctype html>
+
+<title>CodeMirror: GFM mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/mode/overlay.js"></script>
+<script src="../xml/xml.js"></script>
+<script src="../markdown/markdown.js"></script>
+<script src="gfm.js"></script>
+<script src="../javascript/javascript.js"></script>
+<script src="../css/css.js"></script>
+<script src="../htmlmixed/htmlmixed.js"></script>
+<script src="../clike/clike.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">GFM</a>
+  </ul>
+</div>
+
+<article>
+<h2>GFM mode</h2>
+<form><textarea id="code" name="code">
+GitHub Flavored Markdown
+========================
+
+Everything from markdown plus GFM features:
+
+## URL autolinking
+
+Underscores_are_allowed_between_words.
+
+## Fenced code blocks (and syntax highlighting)
+
+```javascript
+for (var i = 0; i < items.length; i++) {
+    console.log(items[i], i); // log them
+}
+```
+
+## Task Lists
+
+- [ ] Incomplete task list item
+- [x] **Completed** task list item
+
+## A bit of GitHub spice
+
+* SHA: be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2
+* User at SHA ref: mojombo at be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2
+* User/Project at SHA: mojombo/god at be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2
+* \#Num: #1
+* User/#Num: mojombo#1
+* User/Project#Num: mojombo/god#1
+
+See http://github.github.com/github-flavored-markdown/.
+
+</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: 'gfm',
+        lineNumbers: true,
+        theme: "default"
+      });
+    </script>
+
+    <p>Optionally depends on other modes for properly highlighted code blocks.</p>
+
+    <p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#gfm_*">normal</a>,  <a href="../../test/index.html#verbose,gfm_*">verbose</a>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/gfm/test.js b/app/gui/html/vendor/codemirror/mode/gfm/test.js
new file mode 100644
index 0000000..e5c3486
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/gfm/test.js
@@ -0,0 +1,129 @@
+(function() {
+  var mode = CodeMirror.getMode({tabSize: 4}, "gfm");
+  function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
+  var modeHighlightFormatting = CodeMirror.getMode({tabSize: 4}, {name: "gfm", highlightFormatting: true});
+  function FT(name) { test.mode(name, modeHighlightFormatting, Array.prototype.slice.call(arguments, 1)); }
+
+  FT("codeBackticks",
+     "[comment&formatting&formatting-code `][comment foo][comment&formatting&formatting-code `]");
+
+  FT("doubleBackticks",
+     "[comment&formatting&formatting-code ``][comment foo ` bar][comment&formatting&formatting-code ``]");
+
+  FT("codeBlock",
+     "[comment&formatting&formatting-code-block ```css]",
+     "[tag foo]",
+     "[comment&formatting&formatting-code-block ```]");
+
+  FT("taskList",
+     "[variable-2&formatting&formatting-list&formatting-list-ul - ][meta&formatting&formatting-task [ ]]][variable-2  foo]",
+     "[variable-2&formatting&formatting-list&formatting-list-ul - ][property&formatting&formatting-task [x]]][variable-2  foo]");
+
+  MT("emInWordAsterisk",
+     "foo[em *bar*]hello");
+
+  MT("emInWordUnderscore",
+     "foo_bar_hello");
+
+  MT("emStrongUnderscore",
+     "[strong __][em&strong _foo__][em _] bar");
+
+  MT("fencedCodeBlocks",
+     "[comment ```]",
+     "[comment foo]",
+     "",
+     "[comment ```]",
+     "bar");
+
+  MT("fencedCodeBlockModeSwitching",
+     "[comment ```javascript]",
+     "[variable foo]",
+     "",
+     "[comment ```]",
+     "bar");
+
+  MT("taskListAsterisk",
+     "[variable-2 * []] foo]", // Invalid; must have space or x between []
+     "[variable-2 * [ ]]bar]", // Invalid; must have space after ]
+     "[variable-2 * [x]]hello]", // Invalid; must have space after ]
+     "[variable-2 * ][meta [ ]]][variable-2  [world]]]", // Valid; tests reference style links
+     "    [variable-3 * ][property [x]]][variable-3  foo]"); // Valid; can be nested
+
+  MT("taskListPlus",
+     "[variable-2 + []] foo]", // Invalid; must have space or x between []
+     "[variable-2 + [ ]]bar]", // Invalid; must have space after ]
+     "[variable-2 + [x]]hello]", // Invalid; must have space after ]
+     "[variable-2 + ][meta [ ]]][variable-2  [world]]]", // Valid; tests reference style links
+     "    [variable-3 + ][property [x]]][variable-3  foo]"); // Valid; can be nested
+
+  MT("taskListDash",
+     "[variable-2 - []] foo]", // Invalid; must have space or x between []
+     "[variable-2 - [ ]]bar]", // Invalid; must have space after ]
+     "[variable-2 - [x]]hello]", // Invalid; must have space after ]
+     "[variable-2 - ][meta [ ]]][variable-2  [world]]]", // Valid; tests reference style links
+     "    [variable-3 - ][property [x]]][variable-3  foo]"); // Valid; can be nested
+
+  MT("taskListNumber",
+     "[variable-2 1. []] foo]", // Invalid; must have space or x between []
+     "[variable-2 2. [ ]]bar]", // Invalid; must have space after ]
+     "[variable-2 3. [x]]hello]", // Invalid; must have space after ]
+     "[variable-2 4. ][meta [ ]]][variable-2  [world]]]", // Valid; tests reference style links
+     "    [variable-3 1. ][property [x]]][variable-3  foo]"); // Valid; can be nested
+
+  MT("SHA",
+     "foo [link be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2] bar");
+
+  MT("shortSHA",
+     "foo [link be6a8cc] bar");
+
+  MT("tooShortSHA",
+     "foo be6a8c bar");
+
+  MT("longSHA",
+     "foo be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd22 bar");
+
+  MT("badSHA",
+     "foo be6a8cc1c1ecfe9489fb51e4869af15a13fc2cg2 bar");
+
+  MT("userSHA",
+     "foo [link bar at be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2] hello");
+
+  MT("userProjectSHA",
+     "foo [link bar/hello at be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2] world");
+
+  MT("num",
+     "foo [link #1] bar");
+
+  MT("badNum",
+     "foo #1bar hello");
+
+  MT("userNum",
+     "foo [link bar#1] hello");
+
+  MT("userProjectNum",
+     "foo [link bar/hello#1] world");
+
+  MT("vanillaLink",
+     "foo [link http://www.example.com/] bar");
+
+  MT("vanillaLinkPunctuation",
+     "foo [link http://www.example.com/]. bar");
+
+  MT("vanillaLinkExtension",
+     "foo [link http://www.example.com/index.html] bar");
+
+  MT("notALink",
+     "[comment ```css]",
+     "[tag foo] {[property color]:[keyword black];}",
+     "[comment ```][link http://www.example.com/]");
+
+  MT("notALink",
+     "[comment ``foo `bar` http://www.example.com/``] hello");
+
+  MT("notALink",
+     "[comment `foo]",
+     "[link http://www.example.com/]",
+     "[comment `foo]",
+     "",
+     "[link http://www.example.com/]");
+})();
diff --git a/app/gui/html/vendor/codemirror/mode/gherkin/gherkin.js b/app/gui/html/vendor/codemirror/mode/gherkin/gherkin.js
new file mode 100644
index 0000000..4100364
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/gherkin/gherkin.js
@@ -0,0 +1,175 @@
+/*
+Gherkin mode - http://www.cukes.info/
+Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues
+*/
+
+// Following Objs from Brackets implementation: https://github.com/tregusti/brackets-gherkin/blob/master/main.js
+//var Quotes = {
+//  SINGLE: 1,
+//  DOUBLE: 2
+//};
+
+//var regex = {
+//  keywords: /(Feature| {2}(Scenario|In order to|As|I)| {4}(Given|When|Then|And))/
+//};
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("gherkin", function () {
+  return {
+    startState: function () {
+      return {
+        lineNumber: 0,
+        tableHeaderLine: false,
+        allowFeature: true,
+        allowBackground: false,
+        allowScenario: false,
+        allowSteps: false,
+        allowPlaceholders: false,
+        allowMultilineArgument: false,
+        inMultilineString: false,
+        inMultilineTable: false,
+        inKeywordLine: false
+      };
+    },
+    token: function (stream, state) {
+      if (stream.sol()) {
+        state.lineNumber++;
+        state.inKeywordLine = false;
+        if (state.inMultilineTable) {
+            state.tableHeaderLine = false;
+            if (!stream.match(/\s*\|/, false)) {
+              state.allowMultilineArgument = false;
+              state.inMultilineTable = false;
+            }
+        }
+      }
+
+      stream.eatSpace();
+
+      if (state.allowMultilineArgument) {
+
+        // STRING
+        if (state.inMultilineString) {
+          if (stream.match('"""')) {
+            state.inMultilineString = false;
+            state.allowMultilineArgument = false;
+          } else {
+            stream.match(/.*/);
+          }
+          return "string";
+        }
+
+        // TABLE
+        if (state.inMultilineTable) {
+          if (stream.match(/\|\s*/)) {
+            return "bracket";
+          } else {
+            stream.match(/[^\|]*/);
+            return state.tableHeaderLine ? "header" : "string";
+          }
+        }
+
+        // DETECT START
+        if (stream.match('"""')) {
+          // String
+          state.inMultilineString = true;
+          return "string";
+        } else if (stream.match("|")) {
+          // Table
+          state.inMultilineTable = true;
+          state.tableHeaderLine = true;
+          return "bracket";
+        }
+
+      }
+
+      // LINE COMMENT
+      if (stream.match(/#.*/)) {
+        return "comment";
+
+      // TAG
+      } else if (!state.inKeywordLine && stream.match(/@\S+/)) {
+        return "tag";
+
+      // FEATURE
+      } else if (!state.inKeywordLine && state.allowFeature && stream.match(/(機能|功能|フィーチャ|기능|โครงหลัก|ความสามารถ|ความต้องการทางธุรกิจ|ಹೆಚ್ಚಳ|గుణము|ਮੁਹਾਂਦਰਾ|ਨਕਸ਼ ਨੁਹਾਰ|ਖਾਸੀਅਤ|रूप लेख|وِیژگی|خاصية|תכונה|Функціонал|Функция|Функционалност|Функционал|Үзенчәлеклелек|Свойство|Особина|Мөмкинлек|Могућност|Λειτουργία|Δυνατότητα|Właściwość|Vlastnosť|Trajto|Tính năng|Savybė|Pretty much|Požiadavka|Požadavek|Potrzeba biznesowa|Özellik|Osobina|Ominaisuus|Omadus|OH HAI|Mogućnost|Mogucnost|Jellemző|Hwæt|Hwaet|Funzionalità|Funktionalitéit|Funktionalität|Funkcja|Funkcionalnost|Funkcionalitāte|Funkcia|Fungsi|Functionaliteit|Funcționalitate|Funcţionalitate|Functionalitate|Funcionalitat|Funcionalidade|Fonctionnalité|Fitur|Fīča|Feature|Eiginleiki|Egenskap|Egenskab|Característica|Caracteristica|Business Need|Aspekt|Arwedd|Ahoy matey!|Ability):/)) {
+        state.allowScenario = true;
+        state.allowBackground = true;
+        state.allowPlaceholders = false;
+        state.allowSteps = false;
+        state.allowMultilineArgument = false;
+        state.inKeywordLine = true;
+        return "keyword";
+
+      // BACKGROUND
+      } else if (!state.inKeywordLine && state.allowBackground && stream.match(/(背景|배경|แนวคิด|ಹಿನ್ನೆಲೆ|నేపథ్యం|ਪਿਛੋਕੜ|पृष्ठभूमि|زمینه|الخلفية|רקע|Тарих|Предыстория|Предистория|Позадина|Передумова|Основа|Контекст|Кереш|Υπόβαθρο|Założenia|Yo\-ho\-ho|Tausta|Taust|Situācija|Rerefons|Pozadina|Pozadie|Pozadí|Osnova|Latar Belakang|Kontext|Konteksts|Kontekstas|Kontekst|Háttér|Hannergrond|Grundlage|Geçmiş|Fundo|Fono|First off|Dis is what went down|Dasar|Contexto|Contexte|Context|Contesto|Cenário de Fundo|Cenario de Fundo|Cefndir|Bối cảnh|Bakgrunnur|Bakgrunn|Bakgrund|Baggrund|Background|B4|Antecedents|Antecedentes|Ær|Aer|Achtergrond):/)) {
+        state.allowPlaceholders = false;
+        state.allowSteps = true;
+        state.allowBackground = false;
+        state.allowMultilineArgument = false;
+        state.inKeywordLine = true;
+        return "keyword";
+
+      // SCENARIO OUTLINE
+      } else if (!state.inKeywordLine && state.allowScenario && stream.match(/(場景大綱|场景大纲|劇本大綱|剧本大纲|テンプレ|シナリオテンプレート|シナリオテンプレ|シナリオアウトライン|시나리오 개요|สรุปเหตุการณ์|โครงสร้างของเหตุการณ์|ವಿವರಣೆ|కథనం|ਪਟਕਥਾ ਰੂਪ ਰੇਖਾ|ਪਟਕਥਾ ਢਾਂਚਾ|परिदृश्य रूपरेखा|سيناريو مخطط|الگوی سناریو|תבנית תרחיש|Сценарийның төзелеше|Сценарий структураси|Структура сценарію|Структура сценария|Структура сценарија|Скица|Рамка на сценарий|Концепт|Περιγραφή Σεναρίου|Wharrimean is|Template Situai|Template Senario|Template Keadaan|Tapausaihio|Szenariogrundriss|Szablon scenariusza|Swa hwær swa|Swa hwaer swa|Struktura scenarija|Structură scenariu|Structura scenariu|Skica|Skenario konsep|Shiver me timbers|Senaryo taslağı|Schema dello scenario|Scenariomall|Scenariomal|Scenario Template|Scenario Outline|Scenario Amlinellol|Scenārijs pēc parauga|Scenarijaus šablonas|Reckon it's like|Raamstsenaarium|Plang vum Szenario|Plan du Scénario|Plan du scénario|Osnova scénáře|Osnova Scenára|Náčrt Scenáru|Náčrt Scénáře|Náčrt Scenára|MISHUN SRSLY|Menggariskan Senario|Lýsing Dæma|Lýsing Atburðarásar|Konturo de la scenaro|Koncept|Khung tình huống|Khung kịch bản|Forgatókönyv vázlat|Esquema do Cenário|Esquema do Cenario|Esquema del escenario|Esquema de l'escenari|Esbozo do escenario|Delineação do Cenário|Delineacao do Cenario|All y'all|Abstrakt Scenario|Abstract Scenario):/)) {
+        state.allowPlaceholders = true;
+        state.allowSteps = true;
+        state.allowMultilineArgument = false;
+        state.inKeywordLine = true;
+        return "keyword";
+
+      // EXAMPLES
+      } else if (state.allowScenario && stream.match(/(例子|例|サンプル|예|ชุดของเหตุการณ์|ชุดของตัวอย่าง|ಉದಾಹರಣೆಗಳು|ఉదాహరణలు|ਉਦਾਹਰਨਾਂ|उदाहरण|نمونه ها|امثلة|דוגמאות|Үрнәкләр|Сценарији|Примеры|Примери|Приклади|Мисоллар|Мисаллар|Σενάρια|Παραδείγματα|You'll wanna|Voorbeelden|Variantai|Tapaukset|Se þe|Se the|Se ðe|Scenarios|Scenariji|Scenarijai|Przykłady|Primjeri|Primeri|Příklady|Príklady|Piemēri|Példák|Pavyzdžiai|Paraugs|Örnekler|Juhtumid|Exemplos|Exemples|Exemple|Exempel|EXAMPLZ|Examples|Esempi|Enghreifftiau|Ekzemploj|Eksempler|Ejemplos|Dữ liệu|Dead men tell no tales|Dæmi|Contoh|Cenários|Cenarios|Beispiller|Beispiele|Atburðarásir):/)) {
+        state.allowPlaceholders = false;
+        state.allowSteps = true;
+        state.allowBackground = false;
+        state.allowMultilineArgument = true;
+        return "keyword";
+
+      // SCENARIO
+      } else if (!state.inKeywordLine && state.allowScenario && stream.match(/(場景|场景|劇本|剧本|シナリオ|시나리오|เหตุการณ์|ಕಥಾಸಾರಾಂಶ|సన్నివేశం|ਪਟਕਥਾ|परिदृश्य|سيناريو|سناریو|תרחיש|Сценарій|Сценарио|Сценарий|Пример|Σενάριο|Tình huống|The thing of it is|Tapaus|Szenario|Swa|Stsenaarium|Skenario|Situai|Senaryo|Senario|Scenaro|Scenariusz|Scenariu|Scénario|Scenario|Scenarijus|Scenārijs|Scenarij|Scenarie|Scénář|Scenár|Primer|MISHUN|Kịch bản|Keadaan|Heave to|Forgatókönyv|Escenario|Escenari|Cenário|Cenario|Awww, look mate|Atburðarás):/)) {
+        state.allowPlaceholders = false;
+        state.allowSteps = true;
+        state.allowBackground = false;
+        state.allowMultilineArgument = false;
+        state.inKeywordLine = true;
+        return "keyword";
+
+      // STEPS
+      } else if (!state.inKeywordLine && state.allowSteps && stream.match(/(那麼|那么|而且|當|当|并且|同時|同时|前提|假设|假設|假定|假如|但是|但し|並且|もし|ならば|ただし|しかし|かつ|하지만|조건|먼저|만일|만약|단|그리고|그러면|และ |เมื่อ |แต่ |ดังนั้น |กำหนดให้ |ಸ್ಥಿತಿಯನ್ನು |ಮತ್ತು |ನೀಡಿದ |ನಂತರ |ಆದರೆ |మరియు |చెప్పబడినది |కాని |ఈ పరిస్థితిలో |అప్పుడు |ਪਰ |ਤਦ |ਜੇਕਰ |ਜਿਵੇਂ ਕਿ |ਜਦੋਂ |ਅਤੇ |यदि |परन्तु |पर |तब |तदा |तथा |जब |चूंकि |किन्तु |कदा |और |अगर |و |هنگامی |متى |لكن |عندما |ثم |بفرض |با فرض |اما |اذاً |آنگاه |כאשר |וגם |בהינתן |אזי |אז |אבל |Якщо |Һәм |Унда |Тоді |Тогда |То |Также |Та |Пусть |Припустимо, що |Припустимо |Онда |Но |Нехай |Нәтиҗәдә |Лекин |Ләкин |Коли |Когда |Когато |Када |Кад |К тому же |І |И |Задато |Задати |Задате |Если |Допустим |Дано |Дадено |Вә |Ва |Бирок |Әмма |Әйтик |Әгәр |Аммо |Али |Але |Агар |А також |А |Τότε |Όταν |Και |Δεδομένου |Αλλά |Þurh |Þegar |Þa þe |Þá |Þa |Zatati |Zakładając |Zadato |Zadate |Zadano |Zadani |Zadan |Za předpokladu |Za predpokladu |Youse know when youse got |Youse know like when |Yna |Yeah nah |Y'know |Y |Wun |Wtedy |When y'all |When |Wenn |WEN |wann |Ve |Và |Und |Un |ugeholl |Too right |Thurh |Thì |Then y'all |Then |Tha the |Tha |Tetapi |Tapi |Tak |Tada |Tad |Stel |Soit |Siis |Și |Şi |Si |Sed |Se |Så |Quando |Quand |Quan |Pryd |Potom |Pokud |Pokiaľ |Però |Pero |Pak |Oraz |Onda |Ond |Oletetaan |Og |Och |O zaman |Niin |Nhưng |När |Når |Mutta |Men |Mas |Maka |Majd |Mając |Mais |Maar |mä |Ma |Lorsque |Lorsqu'|Logo |Let go and haul |Kun |Kuid |Kui |Kiedy |Khi |Ketika |Kemudian |Keď |Když |Kaj |Kai |Kada |Kad |Jeżeli |Jeśli |Ja |It's just unbelievable |Ir |I CAN HAZ |I |Ha |Givun |Givet |Given y'all |Given |Gitt |Gegeven |Gegeben seien |Gegeben sei |Gdy |Gangway! |Fakat |Étant donnés |Etant donnés |Étant données |Etant données |Étant donnée |Etant donnée |Étant donné |Etant donné |Et |És |Entonces |Entón |Então |Entao |En |Eğer ki |Ef |Eeldades |E |Ðurh |Duota |Dun |Donitaĵo |Donat |Donada |Do |Diyelim ki |Diberi |Dengan |Den youse gotta |DEN |De |Dato |Dați fiind |Daţi fiind |Dati fiind |Dati |Date fiind |Date |Data |Dat fiind |Dar |Dann |dann |Dan |Dados |Dado |Dadas |Dada |Ða ðe |Ða |Cuando |Cho |Cando |Când |Cand |Cal |But y'all |But at the end of the day I reckon |BUT |But |Buh |Blimey! |Biết |Bet |Bagi |Aye |awer |Avast! |Atunci |Atesa |Atès |Apabila |Anrhegedig a |Angenommen |And y'all |And |AN |An |an |Amikor |Amennyiben |Ama |Als |Alors |Allora |Ali |Aleshores |Ale |Akkor |Ak |Adott |Ac |Aber |A zároveň |A tiež |A taktiež |A také |A |a |7 |\* )/)) {
+        state.inStep = true;
+        state.allowPlaceholders = true;
+        state.allowMultilineArgument = true;
+        state.inKeywordLine = true;
+        return "keyword";
+
+      // INLINE STRING
+      } else if (stream.match(/"[^"]*"?/)) {
+        return "string";
+
+      // PLACEHOLDER
+      } else if (state.allowPlaceholders && stream.match(/<[^>]*>?/)) {
+        return "variable";
+
+      // Fall through
+      } else {
+        stream.next();
+        stream.eatWhile(/[^@"<#]/);
+        return null;
+      }
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/x-feature", "gherkin");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/gherkin/index.html b/app/gui/html/vendor/codemirror/mode/gherkin/index.html
new file mode 100644
index 0000000..b76877a
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/gherkin/index.html
@@ -0,0 +1,48 @@
+<!doctype html>
+
+<title>CodeMirror: Gherkin mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="gherkin.js"></script>
+<style>.CodeMirror { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; }</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Gherkin</a>
+  </ul>
+</div>
+
+<article>
+<h2>Gherkin mode</h2>
+<form><textarea id="code" name="code">
+Feature: Using Google
+  Background: 
+    Something something
+    Something else
+  Scenario: Has a homepage
+    When I navigate to the google home page
+    Then the home page should contain the menu and the search form
+  Scenario: Searching for a term 
+    When I navigate to the google home page
+    When I search for Tofu
+    Then the search results page is displayed
+    Then the search results page contains 10 individual search results
+    Then the search results contain a link to the wikipedia tofu page
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-feature</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/go/go.js b/app/gui/html/vendor/codemirror/mode/go/go.js
new file mode 100644
index 0000000..7ba780e
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/go/go.js
@@ -0,0 +1,180 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("go", function(config) {
+  var indentUnit = config.indentUnit;
+
+  var keywords = {
+    "break":true, "case":true, "chan":true, "const":true, "continue":true,
+    "default":true, "defer":true, "else":true, "fallthrough":true, "for":true,
+    "func":true, "go":true, "goto":true, "if":true, "import":true,
+    "interface":true, "map":true, "package":true, "range":true, "return":true,
+    "select":true, "struct":true, "switch":true, "type":true, "var":true,
+    "bool":true, "byte":true, "complex64":true, "complex128":true,
+    "float32":true, "float64":true, "int8":true, "int16":true, "int32":true,
+    "int64":true, "string":true, "uint8":true, "uint16":true, "uint32":true,
+    "uint64":true, "int":true, "uint":true, "uintptr":true
+  };
+
+  var atoms = {
+    "true":true, "false":true, "iota":true, "nil":true, "append":true,
+    "cap":true, "close":true, "complex":true, "copy":true, "imag":true,
+    "len":true, "make":true, "new":true, "panic":true, "print":true,
+    "println":true, "real":true, "recover":true
+  };
+
+  var isOperatorChar = /[+\-*&^%:=<>!|\/]/;
+
+  var curPunc;
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+    if (ch == '"' || ch == "'" || ch == "`") {
+      state.tokenize = tokenString(ch);
+      return state.tokenize(stream, state);
+    }
+    if (/[\d\.]/.test(ch)) {
+      if (ch == ".") {
+        stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/);
+      } else if (ch == "0") {
+        stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/);
+      } else {
+        stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/);
+      }
+      return "number";
+    }
+    if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
+      curPunc = ch;
+      return null;
+    }
+    if (ch == "/") {
+      if (stream.eat("*")) {
+        state.tokenize = tokenComment;
+        return tokenComment(stream, state);
+      }
+      if (stream.eat("/")) {
+        stream.skipToEnd();
+        return "comment";
+      }
+    }
+    if (isOperatorChar.test(ch)) {
+      stream.eatWhile(isOperatorChar);
+      return "operator";
+    }
+    stream.eatWhile(/[\w\$_]/);
+    var cur = stream.current();
+    if (keywords.propertyIsEnumerable(cur)) {
+      if (cur == "case" || cur == "default") curPunc = "case";
+      return "keyword";
+    }
+    if (atoms.propertyIsEnumerable(cur)) return "atom";
+    return "variable";
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, next, end = false;
+      while ((next = stream.next()) != null) {
+        if (next == quote && !escaped) {end = true; break;}
+        escaped = !escaped && next == "\\";
+      }
+      if (end || !(escaped || quote == "`"))
+        state.tokenize = tokenBase;
+      return "string";
+    };
+  }
+
+  function tokenComment(stream, state) {
+    var maybeEnd = false, ch;
+    while (ch = stream.next()) {
+      if (ch == "/" && maybeEnd) {
+        state.tokenize = tokenBase;
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return "comment";
+  }
+
+  function Context(indented, column, type, align, prev) {
+    this.indented = indented;
+    this.column = column;
+    this.type = type;
+    this.align = align;
+    this.prev = prev;
+  }
+  function pushContext(state, col, type) {
+    return state.context = new Context(state.indented, col, type, null, state.context);
+  }
+  function popContext(state) {
+    var t = state.context.type;
+    if (t == ")" || t == "]" || t == "}")
+      state.indented = state.context.indented;
+    return state.context = state.context.prev;
+  }
+
+  // Interface
+
+  return {
+    startState: function(basecolumn) {
+      return {
+        tokenize: null,
+        context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
+        indented: 0,
+        startOfLine: true
+      };
+    },
+
+    token: function(stream, state) {
+      var ctx = state.context;
+      if (stream.sol()) {
+        if (ctx.align == null) ctx.align = false;
+        state.indented = stream.indentation();
+        state.startOfLine = true;
+        if (ctx.type == "case") ctx.type = "}";
+      }
+      if (stream.eatSpace()) return null;
+      curPunc = null;
+      var style = (state.tokenize || tokenBase)(stream, state);
+      if (style == "comment") return style;
+      if (ctx.align == null) ctx.align = true;
+
+      if (curPunc == "{") pushContext(state, stream.column(), "}");
+      else if (curPunc == "[") pushContext(state, stream.column(), "]");
+      else if (curPunc == "(") pushContext(state, stream.column(), ")");
+      else if (curPunc == "case") ctx.type = "case";
+      else if (curPunc == "}" && ctx.type == "}") ctx = popContext(state);
+      else if (curPunc == ctx.type) popContext(state);
+      state.startOfLine = false;
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      if (state.tokenize != tokenBase && state.tokenize != null) return 0;
+      var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
+      if (ctx.type == "case" && /^(?:case|default)\b/.test(textAfter)) {
+        state.context.type = "}";
+        return ctx.indented;
+      }
+      var closing = firstChar == ctx.type;
+      if (ctx.align) return ctx.column + (closing ? 0 : 1);
+      else return ctx.indented + (closing ? 0 : indentUnit);
+    },
+
+    electricChars: "{}):",
+    blockCommentStart: "/*",
+    blockCommentEnd: "*/",
+    lineComment: "//"
+  };
+});
+
+CodeMirror.defineMIME("text/x-go", "go");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/go/index.html b/app/gui/html/vendor/codemirror/mode/go/index.html
new file mode 100644
index 0000000..3673fa0
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/go/index.html
@@ -0,0 +1,85 @@
+<!doctype html>
+
+<title>CodeMirror: Go mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link rel="stylesheet" href="../../theme/elegant.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="go.js"></script>
+<style>.CodeMirror {border:1px solid #999; background:#ffc}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Go</a>
+  </ul>
+</div>
+
+<article>
+<h2>Go mode</h2>
+<form><textarea id="code" name="code">
+// Prime Sieve in Go.
+// Taken from the Go specification.
+// Copyright © The Go Authors.
+
+package main
+
+import "fmt"
+
+// Send the sequence 2, 3, 4, ... to channel 'ch'.
+func generate(ch chan<- int) {
+	for i := 2; ; i++ {
+		ch <- i  // Send 'i' to channel 'ch'
+	}
+}
+
+// Copy the values from channel 'src' to channel 'dst',
+// removing those divisible by 'prime'.
+func filter(src <-chan int, dst chan<- int, prime int) {
+	for i := range src {    // Loop over values received from 'src'.
+		if i%prime != 0 {
+			dst <- i  // Send 'i' to channel 'dst'.
+		}
+	}
+}
+
+// The prime sieve: Daisy-chain filter processes together.
+func sieve() {
+	ch := make(chan int)  // Create a new channel.
+	go generate(ch)       // Start generate() as a subprocess.
+	for {
+		prime := <-ch
+		fmt.Print(prime, "\n")
+		ch1 := make(chan int)
+		go filter(ch, ch1, prime)
+		ch = ch1
+	}
+}
+
+func main() {
+	sieve()
+}
+</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        theme: "elegant",
+        matchBrackets: true,
+        indentUnit: 8,
+        tabSize: 8,
+        indentWithTabs: true,
+        mode: "text/x-go"
+      });
+    </script>
+
+    <p><strong>MIME type:</strong> <code>text/x-go</code></p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/groovy/groovy.js b/app/gui/html/vendor/codemirror/mode/groovy/groovy.js
new file mode 100644
index 0000000..399452d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/groovy/groovy.js
@@ -0,0 +1,223 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("groovy", function(config) {
+  function words(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+  var keywords = words(
+    "abstract as assert boolean break byte case catch char class const continue def default " +
+    "do double else enum extends final finally float for goto if implements import in " +
+    "instanceof int interface long native new package private protected public return " +
+    "short static strictfp super switch synchronized threadsafe throw throws transient " +
+    "try void volatile while");
+  var blockKeywords = words("catch class do else finally for if switch try while enum interface def");
+  var atoms = words("null true false this");
+
+  var curPunc;
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+    if (ch == '"' || ch == "'") {
+      return startString(ch, stream, state);
+    }
+    if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
+      curPunc = ch;
+      return null;
+    }
+    if (/\d/.test(ch)) {
+      stream.eatWhile(/[\w\.]/);
+      if (stream.eat(/eE/)) { stream.eat(/\+\-/); stream.eatWhile(/\d/); }
+      return "number";
+    }
+    if (ch == "/") {
+      if (stream.eat("*")) {
+        state.tokenize.push(tokenComment);
+        return tokenComment(stream, state);
+      }
+      if (stream.eat("/")) {
+        stream.skipToEnd();
+        return "comment";
+      }
+      if (expectExpression(state.lastToken)) {
+        return startString(ch, stream, state);
+      }
+    }
+    if (ch == "-" && stream.eat(">")) {
+      curPunc = "->";
+      return null;
+    }
+    if (/[+\-*&%=<>!?|\/~]/.test(ch)) {
+      stream.eatWhile(/[+\-*&%=<>|~]/);
+      return "operator";
+    }
+    stream.eatWhile(/[\w\$_]/);
+    if (ch == "@") { stream.eatWhile(/[\w\$_\.]/); return "meta"; }
+    if (state.lastToken == ".") return "property";
+    if (stream.eat(":")) { curPunc = "proplabel"; return "property"; }
+    var cur = stream.current();
+    if (atoms.propertyIsEnumerable(cur)) { return "atom"; }
+    if (keywords.propertyIsEnumerable(cur)) {
+      if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+      return "keyword";
+    }
+    return "variable";
+  }
+  tokenBase.isBase = true;
+
+  function startString(quote, stream, state) {
+    var tripleQuoted = false;
+    if (quote != "/" && stream.eat(quote)) {
+      if (stream.eat(quote)) tripleQuoted = true;
+      else return "string";
+    }
+    function t(stream, state) {
+      var escaped = false, next, end = !tripleQuoted;
+      while ((next = stream.next()) != null) {
+        if (next == quote && !escaped) {
+          if (!tripleQuoted) { break; }
+          if (stream.match(quote + quote)) { end = true; break; }
+        }
+        if (quote == '"' && next == "$" && !escaped && stream.eat("{")) {
+          state.tokenize.push(tokenBaseUntilBrace());
+          return "string";
+        }
+        escaped = !escaped && next == "\\";
+      }
+      if (end) state.tokenize.pop();
+      return "string";
+    }
+    state.tokenize.push(t);
+    return t(stream, state);
+  }
+
+  function tokenBaseUntilBrace() {
+    var depth = 1;
+    function t(stream, state) {
+      if (stream.peek() == "}") {
+        depth--;
+        if (depth == 0) {
+          state.tokenize.pop();
+          return state.tokenize[state.tokenize.length-1](stream, state);
+        }
+      } else if (stream.peek() == "{") {
+        depth++;
+      }
+      return tokenBase(stream, state);
+    }
+    t.isBase = true;
+    return t;
+  }
+
+  function tokenComment(stream, state) {
+    var maybeEnd = false, ch;
+    while (ch = stream.next()) {
+      if (ch == "/" && maybeEnd) {
+        state.tokenize.pop();
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return "comment";
+  }
+
+  function expectExpression(last) {
+    return !last || last == "operator" || last == "->" || /[\.\[\{\(,;:]/.test(last) ||
+      last == "newstatement" || last == "keyword" || last == "proplabel";
+  }
+
+  function Context(indented, column, type, align, prev) {
+    this.indented = indented;
+    this.column = column;
+    this.type = type;
+    this.align = align;
+    this.prev = prev;
+  }
+  function pushContext(state, col, type) {
+    return state.context = new Context(state.indented, col, type, null, state.context);
+  }
+  function popContext(state) {
+    var t = state.context.type;
+    if (t == ")" || t == "]" || t == "}")
+      state.indented = state.context.indented;
+    return state.context = state.context.prev;
+  }
+
+  // Interface
+
+  return {
+    startState: function(basecolumn) {
+      return {
+        tokenize: [tokenBase],
+        context: new Context((basecolumn || 0) - config.indentUnit, 0, "top", false),
+        indented: 0,
+        startOfLine: true,
+        lastToken: null
+      };
+    },
+
+    token: function(stream, state) {
+      var ctx = state.context;
+      if (stream.sol()) {
+        if (ctx.align == null) ctx.align = false;
+        state.indented = stream.indentation();
+        state.startOfLine = true;
+        // Automatic semicolon insertion
+        if (ctx.type == "statement" && !expectExpression(state.lastToken)) {
+          popContext(state); ctx = state.context;
+        }
+      }
+      if (stream.eatSpace()) return null;
+      curPunc = null;
+      var style = state.tokenize[state.tokenize.length-1](stream, state);
+      if (style == "comment") return style;
+      if (ctx.align == null) ctx.align = true;
+
+      if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
+      // Handle indentation for {x -> \n ... }
+      else if (curPunc == "->" && ctx.type == "statement" && ctx.prev.type == "}") {
+        popContext(state);
+        state.context.align = false;
+      }
+      else if (curPunc == "{") pushContext(state, stream.column(), "}");
+      else if (curPunc == "[") pushContext(state, stream.column(), "]");
+      else if (curPunc == "(") pushContext(state, stream.column(), ")");
+      else if (curPunc == "}") {
+        while (ctx.type == "statement") ctx = popContext(state);
+        if (ctx.type == "}") ctx = popContext(state);
+        while (ctx.type == "statement") ctx = popContext(state);
+      }
+      else if (curPunc == ctx.type) popContext(state);
+      else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
+        pushContext(state, stream.column(), "statement");
+      state.startOfLine = false;
+      state.lastToken = curPunc || style;
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      if (!state.tokenize[state.tokenize.length-1].isBase) return 0;
+      var firstChar = textAfter && textAfter.charAt(0), ctx = state.context;
+      if (ctx.type == "statement" && !expectExpression(state.lastToken)) ctx = ctx.prev;
+      var closing = firstChar == ctx.type;
+      if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : config.indentUnit);
+      else if (ctx.align) return ctx.column + (closing ? 0 : 1);
+      else return ctx.indented + (closing ? 0 : config.indentUnit);
+    },
+
+    electricChars: "{}",
+    fold: "brace"
+  };
+});
+
+CodeMirror.defineMIME("text/x-groovy", "groovy");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/groovy/index.html b/app/gui/html/vendor/codemirror/mode/groovy/index.html
new file mode 100644
index 0000000..f5efdf7
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/groovy/index.html
@@ -0,0 +1,84 @@
+<!doctype html>
+
+<title>CodeMirror: Groovy mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="groovy.js"></script>
+<style>.CodeMirror {border-top: 1px solid #500; border-bottom: 1px solid #500;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Groovy</a>
+  </ul>
+</div>
+
+<article>
+<h2>Groovy mode</h2>
+<form><textarea id="code" name="code">
+//Pattern for groovy script
+def p = ~/.*\.groovy/
+new File( 'd:\\scripts' ).eachFileMatch(p) {f ->
+  // imports list
+  def imports = []
+  f.eachLine {
+    // condition to detect an import instruction
+    ln -> if ( ln =~ '^import .*' ) {
+      imports << "${ln - 'import '}"
+    }
+  }
+  // print thmen
+  if ( ! imports.empty ) {
+    println f
+    imports.each{ println "   $it" }
+  }
+}
+
+/* Coin changer demo code from http://groovy.codehaus.org */
+
+enum UsCoin {
+  quarter(25), dime(10), nickel(5), penny(1)
+  UsCoin(v) { value = v }
+  final value
+}
+
+enum OzzieCoin {
+  fifty(50), twenty(20), ten(10), five(5)
+  OzzieCoin(v) { value = v }
+  final value
+}
+
+def plural(word, count) {
+  if (count == 1) return word
+  word[-1] == 'y' ? word[0..-2] + "ies" : word + "s"
+}
+
+def change(currency, amount) {
+  currency.values().inject([]){ list, coin ->
+     int count = amount / coin.value
+     amount = amount % coin.value
+     list += "$count ${plural(coin.toString(), count)}"
+  }
+}
+</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        mode: "text/x-groovy"
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-groovy</code></p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/haml/haml.js b/app/gui/html/vendor/codemirror/mode/haml/haml.js
new file mode 100644
index 0000000..6b205b4
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/haml/haml.js
@@ -0,0 +1,161 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../ruby/ruby"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../ruby/ruby"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+(function() {
+  "use strict";
+
+  // full haml mode. This handled embeded ruby and html fragments too
+  CodeMirror.defineMode("haml", function(config) {
+    var htmlMode = CodeMirror.getMode(config, {name: "htmlmixed"});
+    var rubyMode = CodeMirror.getMode(config, "ruby");
+
+    function rubyInQuote(endQuote) {
+      return function(stream, state) {
+        var ch = stream.peek();
+        if (ch == endQuote && state.rubyState.tokenize.length == 1) {
+          // step out of ruby context as it seems to complete processing all the braces
+          stream.next();
+          state.tokenize = html;
+          return "closeAttributeTag";
+        } else {
+          return ruby(stream, state);
+        }
+      };
+    }
+
+    function ruby(stream, state) {
+      if (stream.match("-#")) {
+        stream.skipToEnd();
+        return "comment";
+      }
+      return rubyMode.token(stream, state.rubyState);
+    }
+
+    function html(stream, state) {
+      var ch = stream.peek();
+
+      // handle haml declarations. All declarations that cant be handled here
+      // will be passed to html mode
+      if (state.previousToken.style == "comment" ) {
+        if (state.indented > state.previousToken.indented) {
+          stream.skipToEnd();
+          return "commentLine";
+        }
+      }
+
+      if (state.startOfLine) {
+        if (ch == "!" && stream.match("!!")) {
+          stream.skipToEnd();
+          return "tag";
+        } else if (stream.match(/^%[\w:#\.]+=/)) {
+          state.tokenize = ruby;
+          return "hamlTag";
+        } else if (stream.match(/^%[\w:]+/)) {
+          return "hamlTag";
+        } else if (ch == "/" ) {
+          stream.skipToEnd();
+          return "comment";
+        }
+      }
+
+      if (state.startOfLine || state.previousToken.style == "hamlTag") {
+        if ( ch == "#" || ch == ".") {
+          stream.match(/[\w-#\.]*/);
+          return "hamlAttribute";
+        }
+      }
+
+      // donot handle --> as valid ruby, make it HTML close comment instead
+      if (state.startOfLine && !stream.match("-->", false) && (ch == "=" || ch == "-" )) {
+        state.tokenize = ruby;
+        return null;
+      }
+
+      if (state.previousToken.style == "hamlTag" ||
+          state.previousToken.style == "closeAttributeTag" ||
+          state.previousToken.style == "hamlAttribute") {
+        if (ch == "(") {
+          state.tokenize = rubyInQuote(")");
+          return null;
+        } else if (ch == "{") {
+          state.tokenize = rubyInQuote("}");
+          return null;
+        }
+      }
+
+      return htmlMode.token(stream, state.htmlState);
+    }
+
+    return {
+      // default to html mode
+      startState: function() {
+        var htmlState = htmlMode.startState();
+        var rubyState = rubyMode.startState();
+        return {
+          htmlState: htmlState,
+          rubyState: rubyState,
+          indented: 0,
+          previousToken: { style: null, indented: 0},
+          tokenize: html
+        };
+      },
+
+      copyState: function(state) {
+        return {
+          htmlState : CodeMirror.copyState(htmlMode, state.htmlState),
+          rubyState: CodeMirror.copyState(rubyMode, state.rubyState),
+          indented: state.indented,
+          previousToken: state.previousToken,
+          tokenize: state.tokenize
+        };
+      },
+
+      token: function(stream, state) {
+        if (stream.sol()) {
+          state.indented = stream.indentation();
+          state.startOfLine = true;
+        }
+        if (stream.eatSpace()) return null;
+        var style = state.tokenize(stream, state);
+        state.startOfLine = false;
+        // dont record comment line as we only want to measure comment line with
+        // the opening comment block
+        if (style && style != "commentLine") {
+          state.previousToken = { style: style, indented: state.indented };
+        }
+        // if current state is ruby and the previous token is not `,` reset the
+        // tokenize to html
+        if (stream.eol() && state.tokenize == ruby) {
+          stream.backUp(1);
+          var ch = stream.peek();
+          stream.next();
+          if (ch && ch != ",") {
+            state.tokenize = html;
+          }
+        }
+        // reprocess some of the specific style tag when finish setting previousToken
+        if (style == "hamlTag") {
+          style = "tag";
+        } else if (style == "commentLine") {
+          style = "comment";
+        } else if (style == "hamlAttribute") {
+          style = "attribute";
+        } else if (style == "closeAttributeTag") {
+          style = null;
+        }
+        return style;
+      }
+    };
+  }, "htmlmixed", "ruby");
+
+  CodeMirror.defineMIME("text/x-haml", "haml");
+})();
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/haml/index.html b/app/gui/html/vendor/codemirror/mode/haml/index.html
new file mode 100644
index 0000000..a737875
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/haml/index.html
@@ -0,0 +1,79 @@
+<!doctype html>
+
+<title>CodeMirror: HAML mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../xml/xml.js"></script>
+<script src="../htmlmixed/htmlmixed.js"></script>
+<script src="../javascript/javascript.js"></script>
+<script src="../ruby/ruby.js"></script>
+<script src="haml.js"></script>
+<style>.CodeMirror {background: #f8f8f8;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">HAML</a>
+  </ul>
+</div>
+
+<article>
+<h2>HAML mode</h2>
+<form><textarea id="code" name="code">
+!!!
+#content
+.left.column(title="title"){:href => "/hello", :test => "#{hello}_#{world}"}
+    <!-- This is a comment -->
+    %h2 Welcome to our site!
+    %p= puts "HAML MODE"
+  .right.column
+    = render :partial => "sidebar"
+
+.container
+  .row
+    .span8
+      %h1.title= @page_title
+%p.title= @page_title
+%p
+  /
+    The same as HTML comment
+    Hello multiline comment
+
+  -# haml comment
+      This wont be displayed
+      nor will this
+  Date/Time:
+  - now = DateTime.now
+  %strong= now
+  - if now > DateTime.parse("December 31, 2006")
+    = "Happy new " + "year!"
+
+%title
+  = @title
+  \= @title
+  <h1>Title</h1>
+  <h1 title="HELLO">
+    Title
+  </h1>
+    </textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        mode: "text/x-haml"
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-haml</code>.</p>
+
+    <p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#haml_*">normal</a>,  <a href="../../test/index.html#verbose,haml_*">verbose</a>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/haml/test.js b/app/gui/html/vendor/codemirror/mode/haml/test.js
new file mode 100644
index 0000000..163b09f
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/haml/test.js
@@ -0,0 +1,94 @@
+(function() {
+  var mode = CodeMirror.getMode({tabSize: 4, indentUnit: 2}, "haml");
+  function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
+
+  // Requires at least one media query
+  MT("elementName",
+     "[tag %h1] Hey There");
+
+  MT("oneElementPerLine",
+     "[tag %h1] Hey There %h2");
+
+  MT("idSelector",
+     "[tag %h1][attribute #test] Hey There");
+
+  MT("classSelector",
+     "[tag %h1][attribute .hello] Hey There");
+
+  MT("docType",
+     "[tag !!! XML]");
+
+  MT("comment",
+     "[comment / Hello WORLD]");
+
+  MT("notComment",
+     "[tag %h1] This is not a / comment ");
+
+  MT("attributes",
+     "[tag %a]([variable title][operator =][string \"test\"]){[atom :title] [operator =>] [string \"test\"]}");
+
+  MT("htmlCode",
+     "[tag <h1>]Title[tag </h1>]");
+
+  MT("rubyBlock",
+     "[operator =][variable-2 @item]");
+
+  MT("selectorRubyBlock",
+     "[tag %a.selector=] [variable-2 @item]");
+
+  MT("nestedRubyBlock",
+      "[tag %a]",
+      "   [operator =][variable puts] [string \"test\"]");
+
+  MT("multilinePlaintext",
+      "[tag %p]",
+      "  Hello,",
+      "  World");
+
+  MT("multilineRuby",
+      "[tag %p]",
+      "  [comment -# this is a comment]",
+      "     [comment and this is a comment too]",
+      "  Date/Time",
+      "  [operator -] [variable now] [operator =] [tag DateTime][operator .][variable now]",
+      "  [tag %strong=] [variable now]",
+      "  [operator -] [keyword if] [variable now] [operator >] [tag DateTime][operator .][variable parse]([string \"December 31, 2006\"])",
+      "     [operator =][string \"Happy\"]",
+      "     [operator =][string \"Belated\"]",
+      "     [operator =][string \"Birthday\"]");
+
+  MT("multilineComment",
+      "[comment /]",
+      "  [comment Multiline]",
+      "  [comment Comment]");
+
+  MT("hamlComment",
+     "[comment -# this is a comment]");
+
+  MT("multilineHamlComment",
+     "[comment -# this is a comment]",
+     "   [comment and this is a comment too]");
+
+  MT("multilineHTMLComment",
+    "[comment <!--]",
+    "  [comment what a comment]",
+    "  [comment -->]");
+
+  MT("hamlAfterRubyTag",
+    "[attribute .block]",
+    "  [tag %strong=] [variable now]",
+    "  [attribute .test]",
+    "     [operator =][variable now]",
+    "  [attribute .right]");
+
+  MT("stretchedRuby",
+     "[operator =] [variable puts] [string \"Hello\"],",
+     "   [string \"World\"]");
+
+  MT("interpolationInHashAttribute",
+     //"[tag %div]{[atom :id] [operator =>] [string \"#{][variable test][string }_#{][variable ting][string }\"]} test");
+     "[tag %div]{[atom :id] [operator =>] [string \"#{][variable test][string }_#{][variable ting][string }\"]} test");
+
+  MT("interpolationInHTMLAttribute",
+     "[tag %div]([variable title][operator =][string \"#{][variable test][string }_#{][variable ting]()[string }\"]) Test");
+})();
diff --git a/app/gui/html/vendor/codemirror/mode/haskell/haskell.js b/app/gui/html/vendor/codemirror/mode/haskell/haskell.js
new file mode 100644
index 0000000..2876172
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/haskell/haskell.js
@@ -0,0 +1,264 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("haskell", function(_config, modeConfig) {
+
+  function switchState(source, setState, f) {
+    setState(f);
+    return f(source, setState);
+  }
+
+  // These should all be Unicode extended, as per the Haskell 2010 report
+  var smallRE = /[a-z_]/;
+  var largeRE = /[A-Z]/;
+  var digitRE = /\d/;
+  var hexitRE = /[0-9A-Fa-f]/;
+  var octitRE = /[0-7]/;
+  var idRE = /[a-z_A-Z0-9']/;
+  var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:]/;
+  var specialRE = /[(),;[\]`{}]/;
+  var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer
+
+  function normal(source, setState) {
+    if (source.eatWhile(whiteCharRE)) {
+      return null;
+    }
+
+    var ch = source.next();
+    if (specialRE.test(ch)) {
+      if (ch == '{' && source.eat('-')) {
+        var t = "comment";
+        if (source.eat('#')) {
+          t = "meta";
+        }
+        return switchState(source, setState, ncomment(t, 1));
+      }
+      return null;
+    }
+
+    if (ch == '\'') {
+      if (source.eat('\\')) {
+        source.next();  // should handle other escapes here
+      }
+      else {
+        source.next();
+      }
+      if (source.eat('\'')) {
+        return "string";
+      }
+      return "error";
+    }
+
+    if (ch == '"') {
+      return switchState(source, setState, stringLiteral);
+    }
+
+    if (largeRE.test(ch)) {
+      source.eatWhile(idRE);
+      if (source.eat('.')) {
+        return "qualifier";
+      }
+      return "variable-2";
+    }
+
+    if (smallRE.test(ch)) {
+      source.eatWhile(idRE);
+      return "variable";
+    }
+
+    if (digitRE.test(ch)) {
+      if (ch == '0') {
+        if (source.eat(/[xX]/)) {
+          source.eatWhile(hexitRE); // should require at least 1
+          return "integer";
+        }
+        if (source.eat(/[oO]/)) {
+          source.eatWhile(octitRE); // should require at least 1
+          return "number";
+        }
+      }
+      source.eatWhile(digitRE);
+      var t = "number";
+      if (source.match(/^\.\d+/)) {
+        t = "number";
+      }
+      if (source.eat(/[eE]/)) {
+        t = "number";
+        source.eat(/[-+]/);
+        source.eatWhile(digitRE); // should require at least 1
+      }
+      return t;
+    }
+
+    if (ch == "." && source.eat("."))
+      return "keyword";
+
+    if (symbolRE.test(ch)) {
+      if (ch == '-' && source.eat(/-/)) {
+        source.eatWhile(/-/);
+        if (!source.eat(symbolRE)) {
+          source.skipToEnd();
+          return "comment";
+        }
+      }
+      var t = "variable";
+      if (ch == ':') {
+        t = "variable-2";
+      }
+      source.eatWhile(symbolRE);
+      return t;
+    }
+
+    return "error";
+  }
+
+  function ncomment(type, nest) {
+    if (nest == 0) {
+      return normal;
+    }
+    return function(source, setState) {
+      var currNest = nest;
+      while (!source.eol()) {
+        var ch = source.next();
+        if (ch == '{' && source.eat('-')) {
+          ++currNest;
+        }
+        else if (ch == '-' && source.eat('}')) {
+          --currNest;
+          if (currNest == 0) {
+            setState(normal);
+            return type;
+          }
+        }
+      }
+      setState(ncomment(type, currNest));
+      return type;
+    };
+  }
+
+  function stringLiteral(source, setState) {
+    while (!source.eol()) {
+      var ch = source.next();
+      if (ch == '"') {
+        setState(normal);
+        return "string";
+      }
+      if (ch == '\\') {
+        if (source.eol() || source.eat(whiteCharRE)) {
+          setState(stringGap);
+          return "string";
+        }
+        if (source.eat('&')) {
+        }
+        else {
+          source.next(); // should handle other escapes here
+        }
+      }
+    }
+    setState(normal);
+    return "error";
+  }
+
+  function stringGap(source, setState) {
+    if (source.eat('\\')) {
+      return switchState(source, setState, stringLiteral);
+    }
+    source.next();
+    setState(normal);
+    return "error";
+  }
+
+
+  var wellKnownWords = (function() {
+    var wkw = {};
+    function setType(t) {
+      return function () {
+        for (var i = 0; i < arguments.length; i++)
+          wkw[arguments[i]] = t;
+      };
+    }
+
+    setType("keyword")(
+      "case", "class", "data", "default", "deriving", "do", "else", "foreign",
+      "if", "import", "in", "infix", "infixl", "infixr", "instance", "let",
+      "module", "newtype", "of", "then", "type", "where", "_");
+
+    setType("keyword")(
+      "\.\.", ":", "::", "=", "\\", "\"", "<-", "->", "@", "~", "=>");
+
+    setType("builtin")(
+      "!!", "$!", "$", "&&", "+", "++", "-", ".", "/", "/=", "<", "<=", "=<<",
+      "==", ">", ">=", ">>", ">>=", "^", "^^", "||", "*", "**");
+
+    setType("builtin")(
+      "Bool", "Bounded", "Char", "Double", "EQ", "Either", "Enum", "Eq",
+      "False", "FilePath", "Float", "Floating", "Fractional", "Functor", "GT",
+      "IO", "IOError", "Int", "Integer", "Integral", "Just", "LT", "Left",
+      "Maybe", "Monad", "Nothing", "Num", "Ord", "Ordering", "Rational", "Read",
+      "ReadS", "Real", "RealFloat", "RealFrac", "Right", "Show", "ShowS",
+      "String", "True");
+
+    setType("builtin")(
+      "abs", "acos", "acosh", "all", "and", "any", "appendFile", "asTypeOf",
+      "asin", "asinh", "atan", "atan2", "atanh", "break", "catch", "ceiling",
+      "compare", "concat", "concatMap", "const", "cos", "cosh", "curry",
+      "cycle", "decodeFloat", "div", "divMod", "drop", "dropWhile", "either",
+      "elem", "encodeFloat", "enumFrom", "enumFromThen", "enumFromThenTo",
+      "enumFromTo", "error", "even", "exp", "exponent", "fail", "filter",
+      "flip", "floatDigits", "floatRadix", "floatRange", "floor", "fmap",
+      "foldl", "foldl1", "foldr", "foldr1", "fromEnum", "fromInteger",
+      "fromIntegral", "fromRational", "fst", "gcd", "getChar", "getContents",
+      "getLine", "head", "id", "init", "interact", "ioError", "isDenormalized",
+      "isIEEE", "isInfinite", "isNaN", "isNegativeZero", "iterate", "last",
+      "lcm", "length", "lex", "lines", "log", "logBase", "lookup", "map",
+      "mapM", "mapM_", "max", "maxBound", "maximum", "maybe", "min", "minBound",
+      "minimum", "mod", "negate", "not", "notElem", "null", "odd", "or",
+      "otherwise", "pi", "pred", "print", "product", "properFraction",
+      "putChar", "putStr", "putStrLn", "quot", "quotRem", "read", "readFile",
+      "readIO", "readList", "readLn", "readParen", "reads", "readsPrec",
+      "realToFrac", "recip", "rem", "repeat", "replicate", "return", "reverse",
+      "round", "scaleFloat", "scanl", "scanl1", "scanr", "scanr1", "seq",
+      "sequence", "sequence_", "show", "showChar", "showList", "showParen",
+      "showString", "shows", "showsPrec", "significand", "signum", "sin",
+      "sinh", "snd", "span", "splitAt", "sqrt", "subtract", "succ", "sum",
+      "tail", "take", "takeWhile", "tan", "tanh", "toEnum", "toInteger",
+      "toRational", "truncate", "uncurry", "undefined", "unlines", "until",
+      "unwords", "unzip", "unzip3", "userError", "words", "writeFile", "zip",
+      "zip3", "zipWith", "zipWith3");
+
+    var override = modeConfig.overrideKeywords;
+    if (override) for (var word in override) if (override.hasOwnProperty(word))
+      wkw[word] = override[word];
+
+    return wkw;
+  })();
+
+
+
+  return {
+    startState: function ()  { return { f: normal }; },
+    copyState:  function (s) { return { f: s.f }; },
+
+    token: function(stream, state) {
+      var t = state.f(stream, function(s) { state.f = s; });
+      var w = stream.current();
+      return wellKnownWords.hasOwnProperty(w) ? wellKnownWords[w] : t;
+    },
+
+    blockCommentStart: "{-",
+    blockCommentEnd: "-}",
+    lineComment: "--"
+  };
+
+});
+
+CodeMirror.defineMIME("text/x-haskell", "haskell");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/haskell/index.html b/app/gui/html/vendor/codemirror/mode/haskell/index.html
new file mode 100644
index 0000000..056b01d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/haskell/index.html
@@ -0,0 +1,73 @@
+<!doctype html>
+
+<title>CodeMirror: Haskell mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link rel="stylesheet" href="../../theme/elegant.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="haskell.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Haskell</a>
+  </ul>
+</div>
+
+<article>
+<h2>Haskell mode</h2>
+<form><textarea id="code" name="code">
+module UniquePerms (
+    uniquePerms
+    )
+where
+
+-- | Find all unique permutations of a list where there might be duplicates.
+uniquePerms :: (Eq a) => [a] -> [[a]]
+uniquePerms = permBag . makeBag
+
+-- | An unordered collection where duplicate values are allowed,
+-- but represented with a single value and a count.
+type Bag a = [(a, Int)]
+
+makeBag :: (Eq a) => [a] -> Bag a
+makeBag [] = []
+makeBag (a:as) = mix a $ makeBag as
+  where
+    mix a []                        = [(a,1)]
+    mix a (bn@(b,n):bs) | a == b    = (b,n+1):bs
+                        | otherwise = bn : mix a bs
+
+permBag :: Bag a -> [[a]]
+permBag [] = [[]]
+permBag bs = concatMap (\(f,cs) -> map (f:) $ permBag cs) . oneOfEach $ bs
+  where
+    oneOfEach [] = []
+    oneOfEach (an@(a,n):bs) =
+        let bs' = if n == 1 then bs else (a,n-1):bs
+        in (a,bs') : mapSnd (an:) (oneOfEach bs)
+    
+    apSnd f (a,b) = (a, f b)
+    mapSnd = map . apSnd
+</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        theme: "elegant"
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-haskell</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/haxe/haxe.js b/app/gui/html/vendor/codemirror/mode/haxe/haxe.js
new file mode 100644
index 0000000..53d7b1d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/haxe/haxe.js
@@ -0,0 +1,442 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("haxe", function(config, parserConfig) {
+  var indentUnit = config.indentUnit;
+
+  // Tokenizer
+
+  var keywords = function(){
+    function kw(type) {return {type: type, style: "keyword"};}
+    var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
+    var operator = kw("operator"), atom = {type: "atom", style: "atom"}, attribute = {type:"attribute", style: "attribute"};
+  var type = kw("typedef");
+    return {
+      "if": A, "while": A, "else": B, "do": B, "try": B,
+      "return": C, "break": C, "continue": C, "new": C, "throw": C,
+      "var": kw("var"), "inline":attribute, "static": attribute, "using":kw("import"),
+    "public": attribute, "private": attribute, "cast": kw("cast"), "import": kw("import"), "macro": kw("macro"),
+      "function": kw("function"), "catch": kw("catch"), "untyped": kw("untyped"), "callback": kw("cb"),
+      "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
+      "in": operator, "never": kw("property_access"), "trace":kw("trace"),
+    "class": type, "enum":type, "interface":type, "typedef":type, "extends":type, "implements":type, "dynamic":type,
+      "true": atom, "false": atom, "null": atom
+    };
+  }();
+
+  var isOperatorChar = /[+\-*&%=<>!?|]/;
+
+  function chain(stream, state, f) {
+    state.tokenize = f;
+    return f(stream, state);
+  }
+
+  function nextUntilUnescaped(stream, end) {
+    var escaped = false, next;
+    while ((next = stream.next()) != null) {
+      if (next == end && !escaped)
+        return false;
+      escaped = !escaped && next == "\\";
+    }
+    return escaped;
+  }
+
+  // Used as scratch variables to communicate multiple values without
+  // consing up tons of objects.
+  var type, content;
+  function ret(tp, style, cont) {
+    type = tp; content = cont;
+    return style;
+  }
+
+  function haxeTokenBase(stream, state) {
+    var ch = stream.next();
+    if (ch == '"' || ch == "'")
+      return chain(stream, state, haxeTokenString(ch));
+    else if (/[\[\]{}\(\),;\:\.]/.test(ch))
+      return ret(ch);
+    else if (ch == "0" && stream.eat(/x/i)) {
+      stream.eatWhile(/[\da-f]/i);
+      return ret("number", "number");
+    }
+    else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
+      stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
+      return ret("number", "number");
+    }
+    else if (state.reAllowed && (ch == "~" && stream.eat(/\//))) {
+      nextUntilUnescaped(stream, "/");
+      stream.eatWhile(/[gimsu]/);
+      return ret("regexp", "string-2");
+    }
+    else if (ch == "/") {
+      if (stream.eat("*")) {
+        return chain(stream, state, haxeTokenComment);
+      }
+      else if (stream.eat("/")) {
+        stream.skipToEnd();
+        return ret("comment", "comment");
+      }
+      else {
+        stream.eatWhile(isOperatorChar);
+        return ret("operator", null, stream.current());
+      }
+    }
+    else if (ch == "#") {
+        stream.skipToEnd();
+        return ret("conditional", "meta");
+    }
+    else if (ch == "@") {
+      stream.eat(/:/);
+      stream.eatWhile(/[\w_]/);
+      return ret ("metadata", "meta");
+    }
+    else if (isOperatorChar.test(ch)) {
+      stream.eatWhile(isOperatorChar);
+      return ret("operator", null, stream.current());
+    }
+    else {
+    var word;
+    if(/[A-Z]/.test(ch))
+    {
+      stream.eatWhile(/[\w_<>]/);
+      word = stream.current();
+      return ret("type", "variable-3", word);
+    }
+    else
+    {
+        stream.eatWhile(/[\w_]/);
+        var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
+        return (known && state.kwAllowed) ? ret(known.type, known.style, word) :
+                       ret("variable", "variable", word);
+    }
+    }
+  }
+
+  function haxeTokenString(quote) {
+    return function(stream, state) {
+      if (!nextUntilUnescaped(stream, quote))
+        state.tokenize = haxeTokenBase;
+      return ret("string", "string");
+    };
+  }
+
+  function haxeTokenComment(stream, state) {
+    var maybeEnd = false, ch;
+    while (ch = stream.next()) {
+      if (ch == "/" && maybeEnd) {
+        state.tokenize = haxeTokenBase;
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return ret("comment", "comment");
+  }
+
+  // Parser
+
+  var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
+
+  function HaxeLexical(indented, column, type, align, prev, info) {
+    this.indented = indented;
+    this.column = column;
+    this.type = type;
+    this.prev = prev;
+    this.info = info;
+    if (align != null) this.align = align;
+  }
+
+  function inScope(state, varname) {
+    for (var v = state.localVars; v; v = v.next)
+      if (v.name == varname) return true;
+  }
+
+  function parseHaxe(state, style, type, content, stream) {
+    var cc = state.cc;
+    // Communicate our context to the combinators.
+    // (Less wasteful than consing up a hundred closures on every call.)
+    cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
+
+    if (!state.lexical.hasOwnProperty("align"))
+      state.lexical.align = true;
+
+    while(true) {
+      var combinator = cc.length ? cc.pop() : statement;
+      if (combinator(type, content)) {
+        while(cc.length && cc[cc.length - 1].lex)
+          cc.pop()();
+        if (cx.marked) return cx.marked;
+        if (type == "variable" && inScope(state, content)) return "variable-2";
+    if (type == "variable" && imported(state, content)) return "variable-3";
+        return style;
+      }
+    }
+  }
+
+  function imported(state, typename)
+  {
+  if (/[a-z]/.test(typename.charAt(0)))
+    return false;
+  var len = state.importedtypes.length;
+  for (var i = 0; i<len; i++)
+    if(state.importedtypes[i]==typename) return true;
+  }
+
+
+  function registerimport(importname) {
+  var state = cx.state;
+  for (var t = state.importedtypes; t; t = t.next)
+    if(t.name == importname) return;
+  state.importedtypes = { name: importname, next: state.importedtypes };
+  }
+  // Combinator utils
+
+  var cx = {state: null, column: null, marked: null, cc: null};
+  function pass() {
+    for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
+  }
+  function cont() {
+    pass.apply(null, arguments);
+    return true;
+  }
+  function register(varname) {
+    var state = cx.state;
+    if (state.context) {
+      cx.marked = "def";
+      for (var v = state.localVars; v; v = v.next)
+        if (v.name == varname) return;
+      state.localVars = {name: varname, next: state.localVars};
+    }
+  }
+
+  // Combinators
+
+  var defaultVars = {name: "this", next: null};
+  function pushcontext() {
+    if (!cx.state.context) cx.state.localVars = defaultVars;
+    cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
+  }
+  function popcontext() {
+    cx.state.localVars = cx.state.context.vars;
+    cx.state.context = cx.state.context.prev;
+  }
+  function pushlex(type, info) {
+    var result = function() {
+      var state = cx.state;
+      state.lexical = new HaxeLexical(state.indented, cx.stream.column(), type, null, state.lexical, info);
+    };
+    result.lex = true;
+    return result;
+  }
+  function poplex() {
+    var state = cx.state;
+    if (state.lexical.prev) {
+      if (state.lexical.type == ")")
+        state.indented = state.lexical.indented;
+      state.lexical = state.lexical.prev;
+    }
+  }
+  poplex.lex = true;
+
+  function expect(wanted) {
+    function f(type) {
+      if (type == wanted) return cont();
+      else if (wanted == ";") return pass();
+      else return cont(f);
+    };
+    return f;
+  }
+
+  function statement(type) {
+    if (type == "@") return cont(metadef);
+    if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
+    if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
+    if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
+    if (type == "{") return cont(pushlex("}"), pushcontext, block, poplex, popcontext);
+    if (type == ";") return cont();
+    if (type == "attribute") return cont(maybeattribute);
+    if (type == "function") return cont(functiondef);
+    if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
+                                      poplex, statement, poplex);
+    if (type == "variable") return cont(pushlex("stat"), maybelabel);
+    if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
+                                         block, poplex, poplex);
+    if (type == "case") return cont(expression, expect(":"));
+    if (type == "default") return cont(expect(":"));
+    if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
+                                        statement, poplex, popcontext);
+    if (type == "import") return cont(importdef, expect(";"));
+    if (type == "typedef") return cont(typedef);
+    return pass(pushlex("stat"), expression, expect(";"), poplex);
+  }
+  function expression(type) {
+    if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
+    if (type == "function") return cont(functiondef);
+    if (type == "keyword c") return cont(maybeexpression);
+    if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator);
+    if (type == "operator") return cont(expression);
+    if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
+    if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
+    return cont();
+  }
+  function maybeexpression(type) {
+    if (type.match(/[;\}\)\],]/)) return pass();
+    return pass(expression);
+  }
+
+  function maybeoperator(type, value) {
+    if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
+    if (type == "operator" || type == ":") return cont(expression);
+    if (type == ";") return;
+    if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
+    if (type == ".") return cont(property, maybeoperator);
+    if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
+  }
+
+  function maybeattribute(type) {
+    if (type == "attribute") return cont(maybeattribute);
+    if (type == "function") return cont(functiondef);
+    if (type == "var") return cont(vardef1);
+  }
+
+  function metadef(type) {
+    if(type == ":") return cont(metadef);
+    if(type == "variable") return cont(metadef);
+    if(type == "(") return cont(pushlex(")"), commasep(metaargs, ")"), poplex, statement);
+  }
+  function metaargs(type) {
+    if(type == "variable") return cont();
+  }
+
+  function importdef (type, value) {
+  if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); }
+  else if(type == "variable" || type == "property" || type == ".") return cont(importdef);
+  }
+
+  function typedef (type, value)
+  {
+  if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); }
+  }
+
+  function maybelabel(type) {
+    if (type == ":") return cont(poplex, statement);
+    return pass(maybeoperator, expect(";"), poplex);
+  }
+  function property(type) {
+    if (type == "variable") {cx.marked = "property"; return cont();}
+  }
+  function objprop(type) {
+    if (type == "variable") cx.marked = "property";
+    if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
+  }
+  function commasep(what, end) {
+    function proceed(type) {
+      if (type == ",") return cont(what, proceed);
+      if (type == end) return cont();
+      return cont(expect(end));
+    }
+    return function(type) {
+      if (type == end) return cont();
+      else return pass(what, proceed);
+    };
+  }
+  function block(type) {
+    if (type == "}") return cont();
+    return pass(statement, block);
+  }
+  function vardef1(type, value) {
+    if (type == "variable"){register(value); return cont(typeuse, vardef2);}
+    return cont();
+  }
+  function vardef2(type, value) {
+    if (value == "=") return cont(expression, vardef2);
+    if (type == ",") return cont(vardef1);
+  }
+  function forspec1(type, value) {
+  if (type == "variable") {
+    register(value);
+  }
+  return cont(pushlex(")"), pushcontext, forin, expression, poplex, statement, popcontext);
+  }
+  function forin(_type, value) {
+    if (value == "in") return cont();
+  }
+  function functiondef(type, value) {
+    if (type == "variable") {register(value); return cont(functiondef);}
+    if (value == "new") return cont(functiondef);
+    if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, typeuse, statement, popcontext);
+  }
+  function typeuse(type) {
+    if(type == ":") return cont(typestring);
+  }
+  function typestring(type) {
+    if(type == "type") return cont();
+    if(type == "variable") return cont();
+    if(type == "{") return cont(pushlex("}"), commasep(typeprop, "}"), poplex);
+  }
+  function typeprop(type) {
+    if(type == "variable") return cont(typeuse);
+  }
+  function funarg(type, value) {
+    if (type == "variable") {register(value); return cont(typeuse);}
+  }
+
+  // Interface
+
+  return {
+    startState: function(basecolumn) {
+    var defaulttypes = ["Int", "Float", "String", "Void", "Std", "Bool", "Dynamic", "Array"];
+      return {
+        tokenize: haxeTokenBase,
+        reAllowed: true,
+        kwAllowed: true,
+        cc: [],
+        lexical: new HaxeLexical((basecolumn || 0) - indentUnit, 0, "block", false),
+        localVars: parserConfig.localVars,
+    importedtypes: defaulttypes,
+        context: parserConfig.localVars && {vars: parserConfig.localVars},
+        indented: 0
+      };
+    },
+
+    token: function(stream, state) {
+      if (stream.sol()) {
+        if (!state.lexical.hasOwnProperty("align"))
+          state.lexical.align = false;
+        state.indented = stream.indentation();
+      }
+      if (stream.eatSpace()) return null;
+      var style = state.tokenize(stream, state);
+      if (type == "comment") return style;
+      state.reAllowed = !!(type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/));
+      state.kwAllowed = type != '.';
+      return parseHaxe(state, style, type, content, stream);
+    },
+
+    indent: function(state, textAfter) {
+      if (state.tokenize != haxeTokenBase) return 0;
+      var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
+      if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
+      var type = lexical.type, closing = firstChar == type;
+      if (type == "vardef") return lexical.indented + 4;
+      else if (type == "form" && firstChar == "{") return lexical.indented;
+      else if (type == "stat" || type == "form") return lexical.indented + indentUnit;
+      else if (lexical.info == "switch" && !closing)
+        return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
+      else if (lexical.align) return lexical.column + (closing ? 0 : 1);
+      else return lexical.indented + (closing ? 0 : indentUnit);
+    },
+
+    electricChars: "{}"
+  };
+});
+
+CodeMirror.defineMIME("text/x-haxe", "haxe");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/haxe/index.html b/app/gui/html/vendor/codemirror/mode/haxe/index.html
new file mode 100644
index 0000000..ec3b8e0
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/haxe/index.html
@@ -0,0 +1,103 @@
+<!doctype html>
+
+<title>CodeMirror: Haxe mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="haxe.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Haxe</a>
+  </ul>
+</div>
+
+<article>
+<h2>Haxe mode</h2>
+
+
+<div><textarea id="code" name="code">
+import one.two.Three;
+
+ at attr("test")
+class Foo<T> extends Three
+{
+	public function new()
+	{
+		noFoo = 12;
+	}
+	
+	public static inline function doFoo(obj:{k:Int, l:Float}):Int
+	{
+		for(i in 0...10)
+		{
+			obj.k++;
+			trace(i);
+			var var1 = new Array();
+			if(var1.length > 1)
+				throw "Error";
+		}
+		// The following line should not be colored, the variable is scoped out
+		var1;
+		/* Multi line
+		 * Comment test
+		 */
+		return obj.k;
+	}
+	private function bar():Void
+	{
+		#if flash
+		var t1:String = "1.21";
+		#end
+		try {
+			doFoo({k:3, l:1.2});
+		}
+		catch (e : String) {
+			trace(e);
+		}
+		var t2:Float = cast(3.2);
+		var t3:haxe.Timer = new haxe.Timer();
+		var t4 = {k:Std.int(t2), l:Std.parseFloat(t1)};
+		var t5 = ~/123+.*$/i;
+		doFoo(t4);
+		untyped t1 = 4;
+		bob = new Foo<Int>
+	}
+	public var okFoo(default, never):Float;
+	var noFoo(getFoo, null):Int;
+	function getFoo():Int {
+		return noFoo;
+	}
+	
+	public var three:Int;
+}
+enum Color
+{
+	red;
+	green;
+	blue;
+	grey( v : Int );
+	rgb (r:Int,g:Int,b:Int);
+}
+</textarea></div>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        indentUnit: 4,
+        indentWithTabs: true
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-haxe</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/htmlembedded/htmlembedded.js b/app/gui/html/vendor/codemirror/mode/htmlembedded/htmlembedded.js
new file mode 100644
index 0000000..3a07c34
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/htmlembedded/htmlembedded.js
@@ -0,0 +1,83 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "../htmlmixed/htmlmixed"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
+
+  //config settings
+  var scriptStartRegex = parserConfig.scriptStartRegex || /^<%/i,
+      scriptEndRegex = parserConfig.scriptEndRegex || /^%>/i;
+
+  //inner modes
+  var scriptingMode, htmlMixedMode;
+
+  //tokenizer when in html mode
+  function htmlDispatch(stream, state) {
+      if (stream.match(scriptStartRegex, false)) {
+          state.token=scriptingDispatch;
+          return scriptingMode.token(stream, state.scriptState);
+          }
+      else
+          return htmlMixedMode.token(stream, state.htmlState);
+    }
+
+  //tokenizer when in scripting mode
+  function scriptingDispatch(stream, state) {
+      if (stream.match(scriptEndRegex, false))  {
+          state.token=htmlDispatch;
+          return htmlMixedMode.token(stream, state.htmlState);
+         }
+      else
+          return scriptingMode.token(stream, state.scriptState);
+         }
+
+
+  return {
+    startState: function() {
+      scriptingMode = scriptingMode || CodeMirror.getMode(config, parserConfig.scriptingModeSpec);
+      htmlMixedMode = htmlMixedMode || CodeMirror.getMode(config, "htmlmixed");
+      return {
+          token :  parserConfig.startOpen ? scriptingDispatch : htmlDispatch,
+          htmlState : CodeMirror.startState(htmlMixedMode),
+          scriptState : CodeMirror.startState(scriptingMode)
+      };
+    },
+
+    token: function(stream, state) {
+      return state.token(stream, state);
+    },
+
+    indent: function(state, textAfter) {
+      if (state.token == htmlDispatch)
+        return htmlMixedMode.indent(state.htmlState, textAfter);
+      else if (scriptingMode.indent)
+        return scriptingMode.indent(state.scriptState, textAfter);
+    },
+
+    copyState: function(state) {
+      return {
+       token : state.token,
+       htmlState : CodeMirror.copyState(htmlMixedMode, state.htmlState),
+       scriptState : CodeMirror.copyState(scriptingMode, state.scriptState)
+      };
+    },
+
+    innerMode: function(state) {
+      if (state.token == scriptingDispatch) return {state: state.scriptState, mode: scriptingMode};
+      else return {state: state.htmlState, mode: htmlMixedMode};
+    }
+  };
+}, "htmlmixed");
+
+CodeMirror.defineMIME("application/x-ejs", { name: "htmlembedded", scriptingModeSpec:"javascript"});
+CodeMirror.defineMIME("application/x-aspx", { name: "htmlembedded", scriptingModeSpec:"text/x-csharp"});
+CodeMirror.defineMIME("application/x-jsp", { name: "htmlembedded", scriptingModeSpec:"text/x-java"});
+CodeMirror.defineMIME("application/x-erb", { name: "htmlembedded", scriptingModeSpec:"ruby"});
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/htmlembedded/index.html b/app/gui/html/vendor/codemirror/mode/htmlembedded/index.html
new file mode 100644
index 0000000..fee1196
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/htmlembedded/index.html
@@ -0,0 +1,58 @@
+<!doctype html>
+
+<title>CodeMirror: Html Embedded Scripts mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../xml/xml.js"></script>
+<script src="../javascript/javascript.js"></script>
+<script src="../css/css.js"></script>
+<script src="../htmlmixed/htmlmixed.js"></script>
+<script src="htmlembedded.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Html Embedded Scripts</a>
+  </ul>
+</div>
+
+<article>
+<h2>Html Embedded Scripts mode</h2>
+<form><textarea id="code" name="code">
+<%
+function hello(who) {
+	return "Hello " + who;
+}
+%>
+This is an example of EJS (embedded javascript)
+<p>The program says <%= hello("world") %>.</p>
+<script>
+	alert("And here is some normal JS code"); // also colored
+</script>
+</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        mode: "application/x-ejs",
+        indentUnit: 4,
+        indentWithTabs: true
+      });
+    </script>
+
+    <p>Mode for html embedded scripts like JSP and ASP.NET. Depends on HtmlMixed which in turn depends on
+    JavaScript, CSS and XML.<br />Other dependancies include those of the scriping language chosen.</p>
+
+    <p><strong>MIME types defined:</strong> <code>application/x-aspx</code> (ASP.NET), 
+    <code>application/x-ejs</code> (Embedded Javascript), <code>application/x-jsp</code> (JavaServer Pages)</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/htmlmixed/htmlmixed.js b/app/gui/html/vendor/codemirror/mode/htmlmixed/htmlmixed.js
new file mode 100644
index 0000000..d80ef9c
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/htmlmixed/htmlmixed.js
@@ -0,0 +1,117 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
+  var htmlMode = CodeMirror.getMode(config, {name: "xml",
+                                             htmlMode: true,
+                                             multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
+                                             multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag});
+  var cssMode = CodeMirror.getMode(config, "css");
+
+  var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes;
+  scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,
+                    mode: CodeMirror.getMode(config, "javascript")});
+  if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) {
+    var conf = scriptTypesConf[i];
+    scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)});
+  }
+  scriptTypes.push({matches: /./,
+                    mode: CodeMirror.getMode(config, "text/plain")});
+
+  function html(stream, state) {
+    var tagName = state.htmlState.tagName;
+    var style = htmlMode.token(stream, state.htmlState);
+    if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") {
+      // Script block: mode to change to depends on type attribute
+      var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);
+      scriptType = scriptType ? scriptType[1] : "";
+      if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1);
+      for (var i = 0; i < scriptTypes.length; ++i) {
+        var tp = scriptTypes[i];
+        if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) {
+          if (tp.mode) {
+            state.token = script;
+            state.localMode = tp.mode;
+            state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, ""));
+          }
+          break;
+        }
+      }
+    } else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") {
+      state.token = css;
+      state.localMode = cssMode;
+      state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
+    }
+    return style;
+  }
+  function maybeBackup(stream, pat, style) {
+    var cur = stream.current();
+    var close = cur.search(pat), m;
+    if (close > -1) stream.backUp(cur.length - close);
+    else if (m = cur.match(/<\/?$/)) {
+      stream.backUp(cur.length);
+      if (!stream.match(pat, false)) stream.match(cur);
+    }
+    return style;
+  }
+  function script(stream, state) {
+    if (stream.match(/^<\/\s*script\s*>/i, false)) {
+      state.token = html;
+      state.localState = state.localMode = null;
+      return html(stream, state);
+    }
+    return maybeBackup(stream, /<\/\s*script\s*>/,
+                       state.localMode.token(stream, state.localState));
+  }
+  function css(stream, state) {
+    if (stream.match(/^<\/\s*style\s*>/i, false)) {
+      state.token = html;
+      state.localState = state.localMode = null;
+      return html(stream, state);
+    }
+    return maybeBackup(stream, /<\/\s*style\s*>/,
+                       cssMode.token(stream, state.localState));
+  }
+
+  return {
+    startState: function() {
+      var state = htmlMode.startState();
+      return {token: html, localMode: null, localState: null, htmlState: state};
+    },
+
+    copyState: function(state) {
+      if (state.localState)
+        var local = CodeMirror.copyState(state.localMode, state.localState);
+      return {token: state.token, localMode: state.localMode, localState: local,
+              htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
+    },
+
+    token: function(stream, state) {
+      return state.token(stream, state);
+    },
+
+    indent: function(state, textAfter) {
+      if (!state.localMode || /^\s*<\//.test(textAfter))
+        return htmlMode.indent(state.htmlState, textAfter);
+      else if (state.localMode.indent)
+        return state.localMode.indent(state.localState, textAfter);
+      else
+        return CodeMirror.Pass;
+    },
+
+    innerMode: function(state) {
+      return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
+    }
+  };
+}, "xml", "javascript", "css");
+
+CodeMirror.defineMIME("text/html", "htmlmixed");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/htmlmixed/index.html b/app/gui/html/vendor/codemirror/mode/htmlmixed/index.html
new file mode 100644
index 0000000..bd06bb5
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/htmlmixed/index.html
@@ -0,0 +1,85 @@
+<!doctype html>
+
+<title>CodeMirror: HTML mixed mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../xml/xml.js"></script>
+<script src="../javascript/javascript.js"></script>
+<script src="../css/css.js"></script>
+<script src="../vbscript/vbscript.js"></script>
+<script src="htmlmixed.js"></script>
+<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">HTML mixed</a>
+  </ul>
+</div>
+
+<article>
+<h2>HTML mixed mode</h2>
+<form><textarea id="code" name="code">
+<html style="color: green">
+  <!-- this is a comment -->
+  <head>
+    <title>Mixed HTML Example</title>
+    <style type="text/css">
+      h1 {font-family: comic sans; color: #f0f;}
+      div {background: yellow !important;}
+      body {
+        max-width: 50em;
+        margin: 1em 2em 1em 5em;
+      }
+    </style>
+  </head>
+  <body>
+    <h1>Mixed HTML Example</h1>
+    <script>
+      function jsFunc(arg1, arg2) {
+        if (arg1 && arg2) document.body.innerHTML = "achoo";
+      }
+    </script>
+  </body>
+</html>
+</textarea></form>
+    <script>
+      // Define an extended mixed-mode that understands vbscript and
+      // leaves mustache/handlebars embedded templates in html mode
+      var mixedMode = {
+        name: "htmlmixed",
+        scriptTypes: [{matches: /\/x-handlebars-template|\/x-mustache/i,
+                       mode: null},
+                      {matches: /(text|application)\/(x-)?vb(a|script)/i,
+                       mode: "vbscript"}]
+      };
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: mixedMode});
+    </script>
+
+    <p>The HTML mixed mode depends on the XML, JavaScript, and CSS modes.</p>
+
+    <p>It takes an optional mode configuration
+    option, <code>scriptTypes</code>, which can be used to add custom
+    behavior for specific <code><script type="..."></code> tags. If
+    given, it should hold an array of <code>{matches, mode}</code>
+    objects, where <code>matches</code> is a string or regexp that
+    matches the script type, and <code>mode</code> is
+    either <code>null</code>, for script types that should stay in
+    HTML mode, or a <a href="../../doc/manual.html#option_mode">mode
+    spec</a> corresponding to the mode that should be used for the
+    script.</p>
+
+    <p><strong>MIME types defined:</strong> <code>text/html</code>
+    (redefined, only takes effect if you load this parser after the
+    XML parser).</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/http/http.js b/app/gui/html/vendor/codemirror/mode/http/http.js
new file mode 100644
index 0000000..d2ad599
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/http/http.js
@@ -0,0 +1,110 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("http", function() {
+  function failFirstLine(stream, state) {
+    stream.skipToEnd();
+    state.cur = header;
+    return "error";
+  }
+
+  function start(stream, state) {
+    if (stream.match(/^HTTP\/\d\.\d/)) {
+      state.cur = responseStatusCode;
+      return "keyword";
+    } else if (stream.match(/^[A-Z]+/) && /[ \t]/.test(stream.peek())) {
+      state.cur = requestPath;
+      return "keyword";
+    } else {
+      return failFirstLine(stream, state);
+    }
+  }
+
+  function responseStatusCode(stream, state) {
+    var code = stream.match(/^\d+/);
+    if (!code) return failFirstLine(stream, state);
+
+    state.cur = responseStatusText;
+    var status = Number(code[0]);
+    if (status >= 100 && status < 200) {
+      return "positive informational";
+    } else if (status >= 200 && status < 300) {
+      return "positive success";
+    } else if (status >= 300 && status < 400) {
+      return "positive redirect";
+    } else if (status >= 400 && status < 500) {
+      return "negative client-error";
+    } else if (status >= 500 && status < 600) {
+      return "negative server-error";
+    } else {
+      return "error";
+    }
+  }
+
+  function responseStatusText(stream, state) {
+    stream.skipToEnd();
+    state.cur = header;
+    return null;
+  }
+
+  function requestPath(stream, state) {
+    stream.eatWhile(/\S/);
+    state.cur = requestProtocol;
+    return "string-2";
+  }
+
+  function requestProtocol(stream, state) {
+    if (stream.match(/^HTTP\/\d\.\d$/)) {
+      state.cur = header;
+      return "keyword";
+    } else {
+      return failFirstLine(stream, state);
+    }
+  }
+
+  function header(stream) {
+    if (stream.sol() && !stream.eat(/[ \t]/)) {
+      if (stream.match(/^.*?:/)) {
+        return "atom";
+      } else {
+        stream.skipToEnd();
+        return "error";
+      }
+    } else {
+      stream.skipToEnd();
+      return "string";
+    }
+  }
+
+  function body(stream) {
+    stream.skipToEnd();
+    return null;
+  }
+
+  return {
+    token: function(stream, state) {
+      var cur = state.cur;
+      if (cur != header && cur != body && stream.eatSpace()) return null;
+      return cur(stream, state);
+    },
+
+    blankLine: function(state) {
+      state.cur = body;
+    },
+
+    startState: function() {
+      return {cur: start};
+    }
+  };
+});
+
+CodeMirror.defineMIME("message/http", "http");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/http/index.html b/app/gui/html/vendor/codemirror/mode/http/index.html
new file mode 100644
index 0000000..705085e
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/http/index.html
@@ -0,0 +1,45 @@
+<!doctype html>
+
+<title>CodeMirror: HTTP mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="http.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">HTTP</a>
+  </ul>
+</div>
+
+<article>
+<h2>HTTP mode</h2>
+
+
+<div><textarea id="code" name="code">
+POST /somewhere HTTP/1.1
+Host: example.com
+If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
+Content-Type: application/x-www-form-urlencoded;
+	charset=utf-8
+User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.11 (KHTML, like Gecko) Ubuntu/12.04 Chromium/20.0.1132.47 Chrome/20.0.1132.47 Safari/536.11
+
+This is the request body!
+</textarea></div>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>message/http</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/index.html b/app/gui/html/vendor/codemirror/mode/index.html
new file mode 100644
index 0000000..8a1a629
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/index.html
@@ -0,0 +1,117 @@
+<!doctype html>
+
+<title>CodeMirror: Language Modes</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Language modes</a>
+  </ul>
+</div>
+
+<article>
+
+<h2>Language modes</h2>
+
+<p>This is a list of every mode in the distribution. Each mode lives
+in a subdirectory of the <code>mode/</code> directory, and typically
+defines a single JavaScript file that implements the mode. Loading
+such file will make the language available to CodeMirror, through
+the <a href="manual.html#option_mode"><code>mode</code></a>
+option.</p>
+
+<div style="-webkit-columns: 100px 2; -moz-columns: 100px 2; columns: 100px 2;">
+    <ul style="margin-top: 0">
+      <li><a href="apl/index.html">APL</a></li>
+      <li><a href="asterisk/index.html">Asterisk dialplan</a></li>
+      <li><a href="clike/index.html">C, C++, C#</a></li>
+      <li><a href="clojure/index.html">Clojure</a></li>
+      <li><a href="cobol/index.html">COBOL</a></li>
+      <li><a href="coffeescript/index.html">CoffeeScript</a></li>
+      <li><a href="commonlisp/index.html">Common Lisp</a></li>
+      <li><a href="css/index.html">CSS</a></li>
+      <li><a href="python/index.html">Cython</a></li>
+      <li><a href="d/index.html">D</a></li>
+      <li><a href="diff/index.html">diff</a></li>
+      <li><a href="dtd/index.html">DTD</a></li>
+      <li><a href="ecl/index.html">ECL</a></li>
+      <li><a href="eiffel/index.html">Eiffel</a></li>
+      <li><a href="erlang/index.html">Erlang</a></li>
+      <li><a href="fortran/index.html">Fortran</a></li>
+      <li><a href="mllike/index.html">F#</a></li>
+      <li><a href="gas/index.html">Gas</a> (AT&T-style assembly)</li>
+      <li><a href="gherkin/index.html">Gherkin</a></li>
+      <li><a href="go/index.html">Go</a></li>
+      <li><a href="groovy/index.html">Groovy</a></li>
+      <li><a href="haml/index.html">HAML</a></li>
+      <li><a href="haskell/index.html">Haskell</a></li>
+      <li><a href="haxe/index.html">Haxe</a></li>
+      <li><a href="htmlembedded/index.html">HTML embedded scripts</a></li>
+      <li><a href="htmlmixed/index.html">HTML mixed-mode</a></li>
+      <li><a href="http/index.html">HTTP</a></li>
+      <li><a href="clike/index.html">Java</a></li>
+      <li><a href="jade/index.html">Jade</a></li>
+      <li><a href="javascript/index.html">JavaScript</a></li>
+      <li><a href="jinja2/index.html">Jinja2</a></li>
+      <li><a href="julia/index.html">Julia</a></li>
+      <li><a href="css/less.html">LESS</a></li>
+      <li><a href="livescript/index.html">LiveScript</a></li>
+      <li><a href="lua/index.html">Lua</a></li>
+      <li><a href="markdown/index.html">Markdown</a> (<a href="gfm/index.html">GitHub-flavour</a>)</li>
+      <li><a href="mirc/index.html">mIRC</a></li>
+      <li><a href="nginx/index.html">Nginx</a></li>
+      <li><a href="ntriples/index.html">NTriples</a></li>
+      <li><a href="mllike/index.html">OCaml</a></li>
+      <li><a href="octave/index.html">Octave</a> (MATLAB)</li>
+      <li><a href="pascal/index.html">Pascal</a></li>
+      <li><a href="pegjs/index.html">PEG.js</a></li>
+      <li><a href="perl/index.html">Perl</a></li>
+      <li><a href="php/index.html">PHP</a></li>
+      <li><a href="pig/index.html">Pig Latin</a></li>
+      <li><a href="properties/index.html">Properties files</a></li>
+      <li><a href="puppet/index.html">Puppet</a></li>
+      <li><a href="python/index.html">Python</a></li>
+      <li><a href="q/index.html">Q</a></li>
+      <li><a href="r/index.html">R</a></li>
+      <li><a href="rpm/index.html">RPM</a></li>
+      <li><a href="rst/index.html">reStructuredText</a></li>
+      <li><a href="ruby/index.html">Ruby</a></li>
+      <li><a href="rust/index.html">Rust</a></li>
+      <li><a href="sass/index.html">Sass</a></li>
+      <li><a href="clike/scala.html">Scala</a></li>
+      <li><a href="scheme/index.html">Scheme</a></li>
+      <li><a href="css/scss.html">SCSS</a></li>
+      <li><a href="shell/index.html">Shell</a></li>
+      <li><a href="sieve/index.html">Sieve</a></li>
+      <li><a href="smalltalk/index.html">Smalltalk</a></li>
+      <li><a href="smarty/index.html">Smarty</a></li>
+      <li><a href="smartymixed/index.html">Smarty/HTML mixed</a></li>
+      <li><a href="solr/index.html">Solr</a></li>
+      <li><a href="sql/index.html">SQL</a> (several dialects)</li>
+      <li><a href="sparql/index.html">SPARQL</a></li>
+      <li><a href="stex/index.html">sTeX, LaTeX</a></li>
+      <li><a href="tcl/index.html">Tcl</a></li>
+      <li><a href="tiddlywiki/index.html">Tiddlywiki</a></li>
+      <li><a href="tiki/index.html">Tiki wiki</a></li>
+      <li><a href="toml/index.html">TOML</a></li>
+      <li><a href="turtle/index.html">Turtle</a></li>
+      <li><a href="vb/index.html">VB.NET</a></li>
+      <li><a href="vbscript/index.html">VBScript</a></li>
+      <li><a href="velocity/index.html">Velocity</a></li>
+      <li><a href="verilog/index.html">Verilog</a></li>
+      <li><a href="xml/index.html">XML/HTML</a></li>
+      <li><a href="xquery/index.html">XQuery</a></li>
+      <li><a href="yaml/index.html">YAML</a></li>
+      <li><a href="z80/index.html">Z80</a></li>
+    </ul>
+  </div>
+
+</article>
diff --git a/app/gui/html/vendor/codemirror/mode/jade/index.html b/app/gui/html/vendor/codemirror/mode/jade/index.html
new file mode 100644
index 0000000..e22b15e
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/jade/index.html
@@ -0,0 +1,66 @@
+<!doctype html>
+
+<title>CodeMirror: Jade Templating Mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="jade.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Jade Templating Mode</a>
+  </ul>
+</div>
+
+<article>
+<h2>Jade Templating Mode</h2>
+<form><textarea id="code" name="code">
+doctype 5
+  html
+    head
+      title= "Jade Templating CodeMirror Mode Example"
+      link(rel='stylesheet', href='/css/bootstrap.min.css')
+      link(rel='stylesheet', href='/css/index.css')
+      script(type='text/javascript', src='/js/jquery-1.9.1.min.js')
+      script(type='text/javascript', src='/js/bootstrap.min.js')
+    body
+      div.header
+        h1 Welcome to this Example
+      div.spots
+        if locals.spots
+          each spot in spots
+            div.spot.well
+         div
+           if spot.logo
+             img.img-rounded.logo(src=spot.logo)
+           else
+             img.img-rounded.logo(src="img/placeholder.png")
+         h3
+           a(href=spot.hash) ##{spot.hash}
+           if spot.title
+             span.title #{spot.title}
+           if spot.desc
+             div #{spot.desc}
+        else
+          h3 There are no spots currently available.
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: {name: "jade", alignCDATA: true},
+        lineNumbers: true
+      });
+    </script>
+    <h3>The Jade Templating Mode</h3>
+      <p> Created by Drew Bratcher. Managed as part of an Adobe Brackets extension at <a href="https://github.com/dbratcher/brackets-jade">https://github.com/dbratcher/brackets-jade</a>.</p>
+    <p><strong>MIME type defined:</strong> <code>text/x-jade</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/jade/jade.js b/app/gui/html/vendor/codemirror/mode/jade/jade.js
new file mode 100644
index 0000000..020b93e
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/jade/jade.js
@@ -0,0 +1,102 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("jade", function () {
+  var symbol_regex1 = /^(?:~|!|%|\^|\*|\+|=|\\|:|;|,|\/|\?|&|<|>|\|)/;
+  var open_paren_regex = /^(\(|\[)/;
+  var close_paren_regex = /^(\)|\])/;
+  var keyword_regex1 = /^(if|else|return|var|function|include|doctype|each)/;
+  var keyword_regex2 = /^(#|{|}|\.)/;
+  var keyword_regex3 = /^(in)/;
+  var html_regex1 = /^(html|head|title|meta|link|script|body|br|div|input|span|a|img)/;
+  var html_regex2 = /^(h1|h2|h3|h4|h5|p|strong|em)/;
+  return {
+    startState: function () {
+      return {
+        inString: false,
+        stringType: "",
+        beforeTag: true,
+        justMatchedKeyword: false,
+        afterParen: false
+      };
+    },
+    token: function (stream, state) {
+      //check for state changes
+      if (!state.inString && ((stream.peek() == '"') || (stream.peek() == "'"))) {
+        state.stringType = stream.peek();
+        stream.next(); // Skip quote
+        state.inString = true; // Update state
+      }
+
+      //return state
+      if (state.inString) {
+        if (stream.skipTo(state.stringType)) { // Quote found on this line
+          stream.next(); // Skip quote
+          state.inString = false; // Clear flag
+        } else {
+          stream.skipToEnd(); // Rest of line is string
+        }
+        state.justMatchedKeyword = false;
+        return "string"; // Token style
+      } else if (stream.sol() && stream.eatSpace()) {
+        if (stream.match(keyword_regex1)) {
+          state.justMatchedKeyword = true;
+          stream.eatSpace();
+          return "keyword";
+        }
+        if (stream.match(html_regex1) || stream.match(html_regex2)) {
+          state.justMatchedKeyword = true;
+          return "variable";
+        }
+      } else if (stream.sol() && stream.match(keyword_regex1)) {
+        state.justMatchedKeyword = true;
+        stream.eatSpace();
+        return "keyword";
+      } else if (stream.sol() && (stream.match(html_regex1) || stream.match(html_regex2))) {
+        state.justMatchedKeyword = true;
+        return "variable";
+      } else if (stream.eatSpace()) {
+        state.justMatchedKeyword = false;
+        if (stream.match(keyword_regex3) && stream.eatSpace()) {
+          state.justMatchedKeyword = true;
+          return "keyword";
+        }
+      } else if (stream.match(symbol_regex1)) {
+        state.justMatchedKeyword = false;
+        return "atom";
+      } else if (stream.match(open_paren_regex)) {
+        state.afterParen = true;
+        state.justMatchedKeyword = true;
+        return "def";
+      } else if (stream.match(close_paren_regex)) {
+        state.afterParen = false;
+        state.justMatchedKeyword = true;
+        return "def";
+      } else if (stream.match(keyword_regex2)) {
+        state.justMatchedKeyword = true;
+        return "keyword";
+      } else if (stream.eatSpace()) {
+        state.justMatchedKeyword = false;
+      } else {
+        stream.next();
+        if (state.justMatchedKeyword) {
+          return "property";
+        } else if (state.afterParen) {
+          return "property";
+        }
+      }
+      return null;
+    }
+  };
+});
+
+CodeMirror.defineMIME('text/x-jade', 'jade');
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/javascript/index.html b/app/gui/html/vendor/codemirror/mode/javascript/index.html
new file mode 100644
index 0000000..faf5036
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/javascript/index.html
@@ -0,0 +1,109 @@
+<!doctype html>
+
+<title>CodeMirror: JavaScript mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="../../addon/comment/continuecomment.js"></script>
+<script src="../../addon/comment/comment.js"></script>
+<script src="javascript.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">JavaScript</a>
+  </ul>
+</div>
+
+<article>
+<h2>JavaScript mode</h2>
+
+
+<div><textarea id="code" name="code">
+// Demo code (the actual new parser character stream implementation)
+
+function StringStream(string) {
+  this.pos = 0;
+  this.string = string;
+}
+
+StringStream.prototype = {
+  done: function() {return this.pos >= this.string.length;},
+  peek: function() {return this.string.charAt(this.pos);},
+  next: function() {
+    if (this.pos < this.string.length)
+      return this.string.charAt(this.pos++);
+  },
+  eat: function(match) {
+    var ch = this.string.charAt(this.pos);
+    if (typeof match == "string") var ok = ch == match;
+    else var ok = ch && match.test ? match.test(ch) : match(ch);
+    if (ok) {this.pos++; return ch;}
+  },
+  eatWhile: function(match) {
+    var start = this.pos;
+    while (this.eat(match));
+    if (this.pos > start) return this.string.slice(start, this.pos);
+  },
+  backUp: function(n) {this.pos -= n;},
+  column: function() {return this.pos;},
+  eatSpace: function() {
+    var start = this.pos;
+    while (/\s/.test(this.string.charAt(this.pos))) this.pos++;
+    return this.pos - start;
+  },
+  match: function(pattern, consume, caseInsensitive) {
+    if (typeof pattern == "string") {
+      function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
+      if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
+        if (consume !== false) this.pos += str.length;
+        return true;
+      }
+    }
+    else {
+      var match = this.string.slice(this.pos).match(pattern);
+      if (match && consume !== false) this.pos += match[0].length;
+      return match;
+    }
+  }
+};
+</textarea></div>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        continueComments: "Enter",
+        extraKeys: {"Ctrl-Q": "toggleComment"}
+      });
+    </script>
+
+    <p>
+      JavaScript mode supports several configuration options:
+      <ul>
+        <li><code>json</code> which will set the mode to expect JSON
+        data rather than a JavaScript program.</li>
+        <li><code>jsonld</code> which will set the mode to expect
+        <a href="http://json-ld.org">JSON-LD</a> linked data rather
+        than a JavaScript program (<a href="json-ld.html">demo</a>).</li>
+        <li><code>typescript</code> which will activate additional
+        syntax highlighting and some other things for TypeScript code
+        (<a href="typescript.html">demo</a>).</li>
+        <li><code>statementIndent</code> which (given a number) will
+        determine the amount of indentation to use for statements
+        continued on a new line.</li>
+      </ul>
+    </p>
+
+    <p><strong>MIME types defined:</strong> <code>text/javascript</code>, <code>application/json</code>, <code>application/ld+json</code>, <code>text/typescript</code>, <code>application/typescript</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/javascript/javascript.js b/app/gui/html/vendor/codemirror/mode/javascript/javascript.js
new file mode 100644
index 0000000..15eccf7
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/javascript/javascript.js
@@ -0,0 +1,652 @@
+// TODO actually recognize syntax of TypeScript constructs
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("javascript", function(config, parserConfig) {
+  var indentUnit = config.indentUnit;
+  var statementIndent = parserConfig.statementIndent;
+  var jsonldMode = parserConfig.jsonld;
+  var jsonMode = parserConfig.json || jsonldMode;
+  var isTS = parserConfig.typescript;
+
+  // Tokenizer
+
+  var keywords = function(){
+    function kw(type) {return {type: type, style: "keyword"};}
+    var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
+    var operator = kw("operator"), atom = {type: "atom", style: "atom"};
+
+    var jsKeywords = {
+      "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
+      "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
+      "var": kw("var"), "const": kw("var"), "let": kw("var"),
+      "function": kw("function"), "catch": kw("catch"),
+      "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
+      "in": operator, "typeof": operator, "instanceof": operator,
+      "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
+      "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
+      "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
+    };
+
+    // Extend the 'normal' keywords with the TypeScript language extensions
+    if (isTS) {
+      var type = {type: "variable", style: "variable-3"};
+      var tsKeywords = {
+        // object-like things
+        "interface": kw("interface"),
+        "extends": kw("extends"),
+        "constructor": kw("constructor"),
+
+        // scope modifiers
+        "public": kw("public"),
+        "private": kw("private"),
+        "protected": kw("protected"),
+        "static": kw("static"),
+
+        // types
+        "string": type, "number": type, "bool": type, "any": type
+      };
+
+      for (var attr in tsKeywords) {
+        jsKeywords[attr] = tsKeywords[attr];
+      }
+    }
+
+    return jsKeywords;
+  }();
+
+  var isOperatorChar = /[+\-*&%=<>!?|~^]/;
+  var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
+
+  function readRegexp(stream) {
+    var escaped = false, next, inSet = false;
+    while ((next = stream.next()) != null) {
+      if (!escaped) {
+        if (next == "/" && !inSet) return;
+        if (next == "[") inSet = true;
+        else if (inSet && next == "]") inSet = false;
+      }
+      escaped = !escaped && next == "\\";
+    }
+  }
+
+  // Used as scratch variables to communicate multiple values without
+  // consing up tons of objects.
+  var type, content;
+  function ret(tp, style, cont) {
+    type = tp; content = cont;
+    return style;
+  }
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+    if (ch == '"' || ch == "'") {
+      state.tokenize = tokenString(ch);
+      return state.tokenize(stream, state);
+    } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
+      return ret("number", "number");
+    } else if (ch == "." && stream.match("..")) {
+      return ret("spread", "meta");
+    } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
+      return ret(ch);
+    } else if (ch == "=" && stream.eat(">")) {
+      return ret("=>", "operator");
+    } else if (ch == "0" && stream.eat(/x/i)) {
+      stream.eatWhile(/[\da-f]/i);
+      return ret("number", "number");
+    } else if (/\d/.test(ch)) {
+      stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
+      return ret("number", "number");
+    } else if (ch == "/") {
+      if (stream.eat("*")) {
+        state.tokenize = tokenComment;
+        return tokenComment(stream, state);
+      } else if (stream.eat("/")) {
+        stream.skipToEnd();
+        return ret("comment", "comment");
+      } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
+               state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
+        readRegexp(stream);
+        stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
+        return ret("regexp", "string-2");
+      } else {
+        stream.eatWhile(isOperatorChar);
+        return ret("operator", "operator", stream.current());
+      }
+    } else if (ch == "`") {
+      state.tokenize = tokenQuasi;
+      return tokenQuasi(stream, state);
+    } else if (ch == "#") {
+      stream.skipToEnd();
+      return ret("error", "error");
+    } else if (isOperatorChar.test(ch)) {
+      stream.eatWhile(isOperatorChar);
+      return ret("operator", "operator", stream.current());
+    } else {
+      stream.eatWhile(/[\w\$_]/);
+      var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
+      return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
+                     ret("variable", "variable", word);
+    }
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, next;
+      if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
+        state.tokenize = tokenBase;
+        return ret("jsonld-keyword", "meta");
+      }
+      while ((next = stream.next()) != null) {
+        if (next == quote && !escaped) break;
+        escaped = !escaped && next == "\\";
+      }
+      if (!escaped) state.tokenize = tokenBase;
+      return ret("string", "string");
+    };
+  }
+
+  function tokenComment(stream, state) {
+    var maybeEnd = false, ch;
+    while (ch = stream.next()) {
+      if (ch == "/" && maybeEnd) {
+        state.tokenize = tokenBase;
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return ret("comment", "comment");
+  }
+
+  function tokenQuasi(stream, state) {
+    var escaped = false, next;
+    while ((next = stream.next()) != null) {
+      if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
+        state.tokenize = tokenBase;
+        break;
+      }
+      escaped = !escaped && next == "\\";
+    }
+    return ret("quasi", "string-2", stream.current());
+  }
+
+  var brackets = "([{}])";
+  // This is a crude lookahead trick to try and notice that we're
+  // parsing the argument patterns for a fat-arrow function before we
+  // actually hit the arrow token. It only works if the arrow is on
+  // the same line as the arguments and there's no strange noise
+  // (comments) in between. Fallback is to only notice when we hit the
+  // arrow, and not declare the arguments as locals for the arrow
+  // body.
+  function findFatArrow(stream, state) {
+    if (state.fatArrowAt) state.fatArrowAt = null;
+    var arrow = stream.string.indexOf("=>", stream.start);
+    if (arrow < 0) return;
+
+    var depth = 0, sawSomething = false;
+    for (var pos = arrow - 1; pos >= 0; --pos) {
+      var ch = stream.string.charAt(pos);
+      var bracket = brackets.indexOf(ch);
+      if (bracket >= 0 && bracket < 3) {
+        if (!depth) { ++pos; break; }
+        if (--depth == 0) break;
+      } else if (bracket >= 3 && bracket < 6) {
+        ++depth;
+      } else if (/[$\w]/.test(ch)) {
+        sawSomething = true;
+      } else if (sawSomething && !depth) {
+        ++pos;
+        break;
+      }
+    }
+    if (sawSomething && !depth) state.fatArrowAt = pos;
+  }
+
+  // Parser
+
+  var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
+
+  function JSLexical(indented, column, type, align, prev, info) {
+    this.indented = indented;
+    this.column = column;
+    this.type = type;
+    this.prev = prev;
+    this.info = info;
+    if (align != null) this.align = align;
+  }
+
+  function inScope(state, varname) {
+    for (var v = state.localVars; v; v = v.next)
+      if (v.name == varname) return true;
+    for (var cx = state.context; cx; cx = cx.prev) {
+      for (var v = cx.vars; v; v = v.next)
+        if (v.name == varname) return true;
+    }
+  }
+
+  function parseJS(state, style, type, content, stream) {
+    var cc = state.cc;
+    // Communicate our context to the combinators.
+    // (Less wasteful than consing up a hundred closures on every call.)
+    cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
+
+    if (!state.lexical.hasOwnProperty("align"))
+      state.lexical.align = true;
+
+    while(true) {
+      var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
+      if (combinator(type, content)) {
+        while(cc.length && cc[cc.length - 1].lex)
+          cc.pop()();
+        if (cx.marked) return cx.marked;
+        if (type == "variable" && inScope(state, content)) return "variable-2";
+        return style;
+      }
+    }
+  }
+
+  // Combinator utils
+
+  var cx = {state: null, column: null, marked: null, cc: null};
+  function pass() {
+    for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
+  }
+  function cont() {
+    pass.apply(null, arguments);
+    return true;
+  }
+  function register(varname) {
+    function inList(list) {
+      for (var v = list; v; v = v.next)
+        if (v.name == varname) return true;
+      return false;
+    }
+    var state = cx.state;
+    if (state.context) {
+      cx.marked = "def";
+      if (inList(state.localVars)) return;
+      state.localVars = {name: varname, next: state.localVars};
+    } else {
+      if (inList(state.globalVars)) return;
+      if (parserConfig.globalVars)
+        state.globalVars = {name: varname, next: state.globalVars};
+    }
+  }
+
+  // Combinators
+
+  var defaultVars = {name: "this", next: {name: "arguments"}};
+  function pushcontext() {
+    cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
+    cx.state.localVars = defaultVars;
+  }
+  function popcontext() {
+    cx.state.localVars = cx.state.context.vars;
+    cx.state.context = cx.state.context.prev;
+  }
+  function pushlex(type, info) {
+    var result = function() {
+      var state = cx.state, indent = state.indented;
+      if (state.lexical.type == "stat") indent = state.lexical.indented;
+      state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
+    };
+    result.lex = true;
+    return result;
+  }
+  function poplex() {
+    var state = cx.state;
+    if (state.lexical.prev) {
+      if (state.lexical.type == ")")
+        state.indented = state.lexical.indented;
+      state.lexical = state.lexical.prev;
+    }
+  }
+  poplex.lex = true;
+
+  function expect(wanted) {
+    function exp(type) {
+      if (type == wanted) return cont();
+      else if (wanted == ";") return pass();
+      else return cont(exp);
+    };
+    return exp;
+  }
+
+  function statement(type, value) {
+    if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
+    if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
+    if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
+    if (type == "{") return cont(pushlex("}"), block, poplex);
+    if (type == ";") return cont();
+    if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse);
+    if (type == "function") return cont(functiondef);
+    if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
+    if (type == "variable") return cont(pushlex("stat"), maybelabel);
+    if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
+                                      block, poplex, poplex);
+    if (type == "case") return cont(expression, expect(":"));
+    if (type == "default") return cont(expect(":"));
+    if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
+                                     statement, poplex, popcontext);
+    if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
+    if (type == "class") return cont(pushlex("form"), className, objlit, poplex);
+    if (type == "export") return cont(pushlex("form"), afterExport, poplex);
+    if (type == "import") return cont(pushlex("form"), afterImport, poplex);
+    return pass(pushlex("stat"), expression, expect(";"), poplex);
+  }
+  function expression(type) {
+    return expressionInner(type, false);
+  }
+  function expressionNoComma(type) {
+    return expressionInner(type, true);
+  }
+  function expressionInner(type, noComma) {
+    if (cx.state.fatArrowAt == cx.stream.start) {
+      var body = noComma ? arrowBodyNoComma : arrowBody;
+      if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
+      else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
+    }
+
+    var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
+    if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
+    if (type == "function") return cont(functiondef);
+    if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
+    if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
+    if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
+    if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
+    if (type == "{") return contCommasep(objprop, "}", null, maybeop);
+    return cont();
+  }
+  function maybeexpression(type) {
+    if (type.match(/[;\}\)\],]/)) return pass();
+    return pass(expression);
+  }
+  function maybeexpressionNoComma(type) {
+    if (type.match(/[;\}\)\],]/)) return pass();
+    return pass(expressionNoComma);
+  }
+
+  function maybeoperatorComma(type, value) {
+    if (type == ",") return cont(expression);
+    return maybeoperatorNoComma(type, value, false);
+  }
+  function maybeoperatorNoComma(type, value, noComma) {
+    var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
+    var expr = noComma == false ? expression : expressionNoComma;
+    if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
+    if (type == "operator") {
+      if (/\+\+|--/.test(value)) return cont(me);
+      if (value == "?") return cont(expression, expect(":"), expr);
+      return cont(expr);
+    }
+    if (type == "quasi") { cx.cc.push(me); return quasi(value); }
+    if (type == ";") return;
+    if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
+    if (type == ".") return cont(property, me);
+    if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
+  }
+  function quasi(value) {
+    if (value.slice(value.length - 2) != "${") return cont();
+    return cont(expression, continueQuasi);
+  }
+  function continueQuasi(type) {
+    if (type == "}") {
+      cx.marked = "string-2";
+      cx.state.tokenize = tokenQuasi;
+      return cont();
+    }
+  }
+  function arrowBody(type) {
+    findFatArrow(cx.stream, cx.state);
+    if (type == "{") return pass(statement);
+    return pass(expression);
+  }
+  function arrowBodyNoComma(type) {
+    findFatArrow(cx.stream, cx.state);
+    if (type == "{") return pass(statement);
+    return pass(expressionNoComma);
+  }
+  function maybelabel(type) {
+    if (type == ":") return cont(poplex, statement);
+    return pass(maybeoperatorComma, expect(";"), poplex);
+  }
+  function property(type) {
+    if (type == "variable") {cx.marked = "property"; return cont();}
+  }
+  function objprop(type, value) {
+    if (type == "variable") {
+      cx.marked = "property";
+      if (value == "get" || value == "set") return cont(getterSetter);
+    } else if (type == "number" || type == "string") {
+      cx.marked = jsonldMode ? "property" : (type + " property");
+    } else if (type == "[") {
+      return cont(expression, expect("]"), afterprop);
+    }
+    if (atomicTypes.hasOwnProperty(type)) return cont(afterprop);
+  }
+  function getterSetter(type) {
+    if (type != "variable") return pass(afterprop);
+    cx.marked = "property";
+    return cont(functiondef);
+  }
+  function afterprop(type) {
+    if (type == ":") return cont(expressionNoComma);
+    if (type == "(") return pass(functiondef);
+  }
+  function commasep(what, end) {
+    function proceed(type) {
+      if (type == ",") {
+        var lex = cx.state.lexical;
+        if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
+        return cont(what, proceed);
+      }
+      if (type == end) return cont();
+      return cont(expect(end));
+    }
+    return function(type) {
+      if (type == end) return cont();
+      return pass(what, proceed);
+    };
+  }
+  function contCommasep(what, end, info) {
+    for (var i = 3; i < arguments.length; i++)
+      cx.cc.push(arguments[i]);
+    return cont(pushlex(end, info), commasep(what, end), poplex);
+  }
+  function block(type) {
+    if (type == "}") return cont();
+    return pass(statement, block);
+  }
+  function maybetype(type) {
+    if (isTS && type == ":") return cont(typedef);
+  }
+  function typedef(type) {
+    if (type == "variable"){cx.marked = "variable-3"; return cont();}
+  }
+  function vardef() {
+    return pass(pattern, maybetype, maybeAssign, vardefCont);
+  }
+  function pattern(type, value) {
+    if (type == "variable") { register(value); return cont(); }
+    if (type == "[") return contCommasep(pattern, "]");
+    if (type == "{") return contCommasep(proppattern, "}");
+  }
+  function proppattern(type, value) {
+    if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
+      register(value);
+      return cont(maybeAssign);
+    }
+    if (type == "variable") cx.marked = "property";
+    return cont(expect(":"), pattern, maybeAssign);
+  }
+  function maybeAssign(_type, value) {
+    if (value == "=") return cont(expressionNoComma);
+  }
+  function vardefCont(type) {
+    if (type == ",") return cont(vardef);
+  }
+  function maybeelse(type, value) {
+    if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex);
+  }
+  function forspec(type) {
+    if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
+  }
+  function forspec1(type) {
+    if (type == "var") return cont(vardef, expect(";"), forspec2);
+    if (type == ";") return cont(forspec2);
+    if (type == "variable") return cont(formaybeinof);
+    return pass(expression, expect(";"), forspec2);
+  }
+  function formaybeinof(_type, value) {
+    if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
+    return cont(maybeoperatorComma, forspec2);
+  }
+  function forspec2(type, value) {
+    if (type == ";") return cont(forspec3);
+    if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
+    return pass(expression, expect(";"), forspec3);
+  }
+  function forspec3(type) {
+    if (type != ")") cont(expression);
+  }
+  function functiondef(type, value) {
+    if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
+    if (type == "variable") {register(value); return cont(functiondef);}
+    if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
+  }
+  function funarg(type) {
+    if (type == "spread") return cont(funarg);
+    return pass(pattern, maybetype);
+  }
+  function className(type, value) {
+    if (type == "variable") {register(value); return cont(classNameAfter);}
+  }
+  function classNameAfter(_type, value) {
+    if (value == "extends") return cont(expression);
+  }
+  function objlit(type) {
+    if (type == "{") return contCommasep(objprop, "}");
+  }
+  function afterModule(type, value) {
+    if (type == "string") return cont(statement);
+    if (type == "variable") { register(value); return cont(maybeFrom); }
+  }
+  function afterExport(_type, value) {
+    if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
+    if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
+    return pass(statement);
+  }
+  function afterImport(type) {
+    if (type == "string") return cont();
+    return pass(importSpec, maybeFrom);
+  }
+  function importSpec(type, value) {
+    if (type == "{") return contCommasep(importSpec, "}");
+    if (type == "variable") register(value);
+    return cont();
+  }
+  function maybeFrom(_type, value) {
+    if (value == "from") { cx.marked = "keyword"; return cont(expression); }
+  }
+  function arrayLiteral(type) {
+    if (type == "]") return cont();
+    return pass(expressionNoComma, maybeArrayComprehension);
+  }
+  function maybeArrayComprehension(type) {
+    if (type == "for") return pass(comprehension, expect("]"));
+    if (type == ",") return cont(commasep(expressionNoComma, "]"));
+    return pass(commasep(expressionNoComma, "]"));
+  }
+  function comprehension(type) {
+    if (type == "for") return cont(forspec, comprehension);
+    if (type == "if") return cont(expression, comprehension);
+  }
+
+  // Interface
+
+  return {
+    startState: function(basecolumn) {
+      var state = {
+        tokenize: tokenBase,
+        lastType: "sof",
+        cc: [],
+        lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
+        localVars: parserConfig.localVars,
+        context: parserConfig.localVars && {vars: parserConfig.localVars},
+        indented: 0
+      };
+      if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
+        state.globalVars = parserConfig.globalVars;
+      return state;
+    },
+
+    token: function(stream, state) {
+      if (stream.sol()) {
+        if (!state.lexical.hasOwnProperty("align"))
+          state.lexical.align = false;
+        state.indented = stream.indentation();
+        findFatArrow(stream, state);
+      }
+      if (state.tokenize != tokenComment && stream.eatSpace()) return null;
+      var style = state.tokenize(stream, state);
+      if (type == "comment") return style;
+      state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
+      return parseJS(state, style, type, content, stream);
+    },
+
+    indent: function(state, textAfter) {
+      if (state.tokenize == tokenComment) return CodeMirror.Pass;
+      if (state.tokenize != tokenBase) return 0;
+      var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
+      // Kludge to prevent 'maybelse' from blocking lexical scope pops
+      for (var i = state.cc.length - 1; i >= 0; --i) {
+        var c = state.cc[i];
+        if (c == poplex) lexical = lexical.prev;
+        else if (c != maybeelse) break;
+      }
+      if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
+      if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
+        lexical = lexical.prev;
+      var type = lexical.type, closing = firstChar == type;
+
+      if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
+      else if (type == "form" && firstChar == "{") return lexical.indented;
+      else if (type == "form") return lexical.indented + indentUnit;
+      else if (type == "stat")
+        return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0);
+      else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
+        return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
+      else if (lexical.align) return lexical.column + (closing ? 0 : 1);
+      else return lexical.indented + (closing ? 0 : indentUnit);
+    },
+
+    electricChars: ":{}",
+    blockCommentStart: jsonMode ? null : "/*",
+    blockCommentEnd: jsonMode ? null : "*/",
+    lineComment: jsonMode ? null : "//",
+    fold: "brace",
+
+    helperType: jsonMode ? "json" : "javascript",
+    jsonldMode: jsonldMode,
+    jsonMode: jsonMode
+  };
+});
+
+CodeMirror.defineMIME("text/javascript", "javascript");
+CodeMirror.defineMIME("text/ecmascript", "javascript");
+CodeMirror.defineMIME("application/javascript", "javascript");
+CodeMirror.defineMIME("application/ecmascript", "javascript");
+CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
+CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
+CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
+CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
+CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/javascript/json-ld.html b/app/gui/html/vendor/codemirror/mode/javascript/json-ld.html
new file mode 100644
index 0000000..256bb0f
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/javascript/json-ld.html
@@ -0,0 +1,72 @@
+<!doctype html>
+
+<title>CodeMirror: JSON-LD mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="../../addon/comment/continuecomment.js"></script>
+<script src="../../addon/comment/comment.js"></script>
+<script src="javascript.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id="nav">
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"/></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">JSON-LD</a>
+  </ul>
+</div>
+
+<article>
+<h2>JSON-LD mode</h2>
+
+
+<div><textarea id="code" name="code">
+{
+  "@context": {
+    "name": "http://schema.org/name",
+    "description": "http://schema.org/description",
+    "image": {
+      "@id": "http://schema.org/image",
+      "@type": "@id"
+    },
+    "geo": "http://schema.org/geo",
+    "latitude": {
+      "@id": "http://schema.org/latitude",
+      "@type": "xsd:float"
+    },
+    "longitude": {
+      "@id": "http://schema.org/longitude",
+      "@type": "xsd:float"
+    },
+    "xsd": "http://www.w3.org/2001/XMLSchema#"
+  },
+  "name": "The Empire State Building",
+  "description": "The Empire State Building is a 102-story landmark in New York City.",
+  "image": "http://www.civil.usherbrooke.ca/cours/gci215a/empire-state-building.jpg",
+  "geo": {
+    "latitude": "40.75",
+    "longitude": "73.98"
+  }
+}
+</textarea></div>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        matchBrackets: true,
+        autoCloseBrackets: true,
+        mode: "application/ld+json",
+        lineWrapping: true
+      });
+    </script>
+    
+    <p>This is a specialization of the <a href="index.html">JavaScript mode</a>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/javascript/test.js b/app/gui/html/vendor/codemirror/mode/javascript/test.js
new file mode 100644
index 0000000..3f73196
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/javascript/test.js
@@ -0,0 +1,151 @@
+(function() {
+  var mode = CodeMirror.getMode({indentUnit: 2}, "javascript");
+  function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
+
+  MT("locals",
+     "[keyword function] [variable foo]([def a], [def b]) { [keyword var] [def c] [operator =] [number 10]; [keyword return] [variable-2 a] [operator +] [variable-2 c] [operator +] [variable d]; }");
+
+  MT("comma-and-binop",
+     "[keyword function](){ [keyword var] [def x] [operator =] [number 1] [operator +] [number 2], [def y]; }");
+
+  MT("destructuring",
+     "([keyword function]([def a], [[[def b], [def c] ]]) {",
+     "  [keyword let] {[def d], [property foo]: [def c][operator =][number 10], [def x]} [operator =] [variable foo]([variable-2 a]);",
+     "  [[[variable-2 c], [variable y] ]] [operator =] [variable-2 c];",
+     "})();");
+
+  MT("class",
+     "[keyword class] [variable Point] [keyword extends] [variable SuperThing] {",
+     "  [[ [string-2 /expr/] ]]: [number 24],",
+     "  [property constructor]([def x], [def y]) {",
+     "    [keyword super]([string 'something']);",
+     "    [keyword this].[property x] [operator =] [variable-2 x];",
+     "  }",
+     "}");
+
+  MT("module",
+     "[keyword module] [string 'foo'] {",
+     "  [keyword export] [keyword let] [def x] [operator =] [number 42];",
+     "  [keyword export] [keyword *] [keyword from] [string 'somewhere'];",
+     "}");
+
+  MT("import",
+     "[keyword function] [variable foo]() {",
+     "  [keyword import] [def $] [keyword from] [string 'jquery'];",
+     "  [keyword module] [def crypto] [keyword from] [string 'crypto'];",
+     "  [keyword import] { [def encrypt], [def decrypt] } [keyword from] [string 'crypto'];",
+     "}");
+
+  MT("const",
+     "[keyword function] [variable f]() {",
+     "  [keyword const] [[ [def a], [def b] ]] [operator =] [[ [number 1], [number 2] ]];",
+     "}");
+
+  MT("for/of",
+     "[keyword for]([keyword let] [variable of] [keyword of] [variable something]) {}");
+
+  MT("generator",
+     "[keyword function*] [variable repeat]([def n]) {",
+     "  [keyword for]([keyword var] [def i] [operator =] [number 0]; [variable-2 i] [operator <] [variable-2 n]; [operator ++][variable-2 i])",
+     "    [keyword yield] [variable-2 i];",
+     "}");
+
+  MT("fatArrow",
+     "[variable array].[property filter]([def a] [operator =>] [variable-2 a] [operator +] [number 1]);",
+     "[variable a];", // No longer in scope
+     "[keyword let] [variable f] [operator =] ([[ [def a], [def b] ]], [def c]) [operator =>] [variable-2 a] [operator +] [variable-2 c];",
+     "[variable c];");
+
+  MT("spread",
+     "[keyword function] [variable f]([def a], [meta ...][def b]) {",
+     "  [variable something]([variable-2 a], [meta ...][variable-2 b]);",
+     "}");
+
+  MT("comprehension",
+     "[keyword function] [variable f]() {",
+     "  [[([variable x] [operator +] [number 1]) [keyword for] ([keyword var] [def x] [keyword in] [variable y]) [keyword if] [variable pred]([variable-2 x]) ]];",
+     "  ([variable u] [keyword for] ([keyword var] [def u] [keyword of] [variable generateValues]()) [keyword if] ([variable-2 u].[property color] [operator ===] [string 'blue']));",
+     "}");
+
+  MT("quasi",
+     "[variable re][string-2 `fofdlakj${][variable x] [operator +] ([variable re][string-2 `foo`]) [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]");
+
+  MT("indent_statement",
+     "[keyword var] [variable x] [operator =] [number 10]",
+     "[variable x] [operator +=] [variable y] [operator +]",
+     "  [atom Infinity]",
+     "[keyword debugger];");
+
+  MT("indent_if",
+     "[keyword if] ([number 1])",
+     "  [keyword break];",
+     "[keyword else] [keyword if] ([number 2])",
+     "  [keyword continue];",
+     "[keyword else]",
+     "  [number 10];",
+     "[keyword if] ([number 1]) {",
+     "  [keyword break];",
+     "} [keyword else] [keyword if] ([number 2]) {",
+     "  [keyword continue];",
+     "} [keyword else] {",
+     "  [number 10];",
+     "}");
+
+  MT("indent_for",
+     "[keyword for] ([keyword var] [variable i] [operator =] [number 0];",
+     "     [variable i] [operator <] [number 100];",
+     "     [variable i][operator ++])",
+     "  [variable doSomething]([variable i]);",
+     "[keyword debugger];");
+
+  MT("indent_c_style",
+     "[keyword function] [variable foo]()",
+     "{",
+     "  [keyword debugger];",
+     "}");
+
+  MT("multilinestring",
+     "[keyword var] [variable x] [operator =] [string 'foo\\]",
+     "[string bar'];");
+
+  MT("scary_regexp",
+     "[string-2 /foo[[/]]bar/];");
+
+  var jsonld_mode = CodeMirror.getMode(
+    {indentUnit: 2},
+    {name: "javascript", jsonld: true}
+  );
+  function LD(name) {
+    test.mode(name, jsonld_mode, Array.prototype.slice.call(arguments, 1));
+  }
+
+  LD("json_ld_keywords",
+    '{',
+    '  [meta "@context"]: {',
+    '    [meta "@base"]: [string "http://example.com"],',
+    '    [meta "@vocab"]: [string "http://xmlns.com/foaf/0.1/"],',
+    '    [property "likesFlavor"]: {',
+    '      [meta "@container"]: [meta "@list"]',
+    '      [meta "@reverse"]: [string "@beFavoriteOf"]',
+    '    },',
+    '    [property "nick"]: { [meta "@container"]: [meta "@set"] },',
+    '    [property "nick"]: { [meta "@container"]: [meta "@index"] }',
+    '  },',
+    '  [meta "@graph"]: [[ {',
+    '    [meta "@id"]: [string "http://dbpedia.org/resource/John_Lennon"],',
+    '    [property "name"]: [string "John Lennon"],',
+    '    [property "modified"]: {',
+    '      [meta "@value"]: [string "2010-05-29T14:17:39+02:00"],',
+    '      [meta "@type"]: [string "http://www.w3.org/2001/XMLSchema#dateTime"]',
+    '    }',
+    '  } ]]',
+    '}');
+
+  LD("json_ld_fake",
+    '{',
+    '  [property "@fake"]: [string "@fake"],',
+    '  [property "@contextual"]: [string "@identifier"],',
+    '  [property "user at domain.com"]: [string "@graphical"],',
+    '  [property "@ID"]: [string "@@ID"]',
+    '}');
+})();
diff --git a/app/gui/html/vendor/codemirror/mode/javascript/typescript.html b/app/gui/html/vendor/codemirror/mode/javascript/typescript.html
new file mode 100644
index 0000000..9cc5f49
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/javascript/typescript.html
@@ -0,0 +1,61 @@
+<!doctype html>
+
+<title>CodeMirror: TypeScript mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="javascript.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">TypeScript</a>
+  </ul>
+</div>
+
+<article>
+<h2>TypeScript mode</h2>
+
+
+<div><textarea id="code" name="code">
+class Greeter {
+	greeting: string;
+	constructor (message: string) {
+		this.greeting = message;
+	}
+	greet() {
+		return "Hello, " + this.greeting;
+	}
+}   
+
+var greeter = new Greeter("world");
+
+var button = document.createElement('button')
+button.innerText = "Say Hello"
+button.onclick = function() {
+	alert(greeter.greet())
+}
+
+document.body.appendChild(button)
+
+</textarea></div>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        mode: "text/typescript"
+      });
+    </script>
+
+    <p>This is a specialization of the <a href="index.html">JavaScript mode</a>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/jinja2/index.html b/app/gui/html/vendor/codemirror/mode/jinja2/index.html
new file mode 100644
index 0000000..66bf2ec
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/jinja2/index.html
@@ -0,0 +1,50 @@
+<!doctype html>
+
+<title>CodeMirror: Jinja2 mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="jinja2.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Jinja2</a>
+  </ul>
+</div>
+
+<article>
+<h2>Jinja2 mode</h2>
+<form><textarea id="code" name="code">
+<html style="color: green">
+  <!-- this is a comment -->
+  <head>
+    <title>Jinja2 Example</title>
+  </head>
+  <body>
+    <ul>
+    {# this is a comment #}
+    {%- for item in li -%}
+      <li>
+        {{ item.label }}
+      </li>
+    {% endfor -%}
+    </ul>
+  </body>
+</html>
+</textarea></form>
+    <script>
+      var editor =
+      CodeMirror.fromTextArea(document.getElementById("code"), {mode:
+        {name: "jinja2", htmlMode: true}});
+    </script>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/jinja2/jinja2.js b/app/gui/html/vendor/codemirror/mode/jinja2/jinja2.js
new file mode 100644
index 0000000..e30ce63
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/jinja2/jinja2.js
@@ -0,0 +1,63 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  CodeMirror.defineMode("jinja2", function() {
+    var keywords = ["and", "as", "block", "endblock", "by", "cycle", "debug", "else", "elif",
+                    "extends", "filter", "endfilter", "firstof", "for",
+                    "endfor", "if", "endif", "ifchanged", "endifchanged",
+                    "ifequal", "endifequal", "ifnotequal",
+                    "endifnotequal", "in", "include", "load", "not", "now", "or",
+                    "parsed", "regroup", "reversed", "spaceless",
+                    "endspaceless", "ssi", "templatetag", "openblock",
+                    "closeblock", "openvariable", "closevariable",
+                    "openbrace", "closebrace", "opencomment",
+                    "closecomment", "widthratio", "url", "with", "endwith",
+                    "get_current_language", "trans", "noop", "blocktrans",
+                    "endblocktrans", "get_available_languages",
+                    "get_current_language_bidi", "plural"];
+    keywords = new RegExp("^((" + keywords.join(")|(") + "))\\b");
+
+    function tokenBase (stream, state) {
+      var ch = stream.next();
+      if (ch == "{") {
+        if (ch = stream.eat(/\{|%|#/)) {
+          stream.eat("-");
+          state.tokenize = inTag(ch);
+          return "tag";
+        }
+      }
+    }
+    function inTag (close) {
+      if (close == "{") {
+        close = "}";
+      }
+      return function (stream, state) {
+        var ch = stream.next();
+        if ((ch == close || (ch == "-" && stream.eat(close)))
+            && stream.eat("}")) {
+          state.tokenize = tokenBase;
+          return "tag";
+        }
+        if (stream.match(keywords)) {
+          return "keyword";
+        }
+        return close == "#" ? "comment" : "string";
+      };
+    }
+    return {
+      startState: function () {
+        return {tokenize: tokenBase};
+      },
+      token: function (stream, state) {
+        return state.tokenize(stream, state);
+      }
+    };
+  });
+});
diff --git a/app/gui/html/vendor/codemirror/mode/julia/index.html b/app/gui/html/vendor/codemirror/mode/julia/index.html
new file mode 100644
index 0000000..945e1a9
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/julia/index.html
@@ -0,0 +1,186 @@
+<!doctype html>
+
+<title>CodeMirror: Julia mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="julia.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Julia</a>
+  </ul>
+</div>
+
+<article>
+<h2>Julia mode</h2>
+
+    <div><textarea id="code" name="code">
+#numbers
+1234
+1234im
+.234
+.234im
+2.23im
+2.3f3
+23e2
+0x234
+
+#strings
+'a'
+"asdf"
+r"regex"
+b"bytestring"
+
+"""
+multiline string
+"""
+
+#identifiers
+a
+as123
+function_name!
+
+#literal identifier multiples
+3x
+4[1, 2, 3]
+
+#dicts and indexing
+x=[1, 2, 3]
+x[end-1]
+x={"julia"=>"language of technical computing"}
+
+#exception handling
+try
+  f()
+catch
+  @printf "Error"
+finally
+  g()
+end
+
+#types
+immutable Color{T<:Number}
+  r::T
+  g::T
+  b::T
+end
+
+#functions
+function change!(x::Vector{Float64})
+  for i = 1:length(x)
+    x[i] *= 2
+  end
+end
+
+#function invocation
+f('b', (2, 3)...)
+
+#operators
+|=
+&=
+^=
+\-
+%=
+*=
++=
+-=
+<=
+>=
+!=
+==
+%
+*
++
+-
+<
+>
+!
+=
+|
+&
+^
+\
+?
+~
+:
+$
+<:
+.<
+.>
+<<
+<<=
+>>
+>>>>
+>>=
+>>>=
+<<=
+<<<=
+.<=
+.>=
+.==
+->
+//
+in
+...
+//
+:=
+.//=
+.*=
+./=
+.^=
+.%=
+.+=
+.-=
+\=
+\\=
+||
+===
+&&
+|=
+.|=
+<:
+>:
+|>
+<|
+::
+x ? y : z
+
+#macros
+ at spawnat 2 1+1
+ at eval(:x)
+
+#keywords and operators
+if else elseif while for
+ begin let end do
+try catch finally return break continue
+global local const 
+export import importall using
+function macro module baremodule 
+type immutable quote
+true false enumerate
+
+
+    </textarea></div>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: {name: "julia",
+               },
+        lineNumbers: true,
+        indentUnit: 4,
+        matchBrackets: true
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-julia</code>.</p>
+</article>
diff --git a/app/gui/html/vendor/codemirror/mode/julia/julia.js b/app/gui/html/vendor/codemirror/mode/julia/julia.js
new file mode 100644
index 0000000..d37ab50
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/julia/julia.js
@@ -0,0 +1,298 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("julia", function(_conf, parserConf) {
+  var ERRORCLASS = 'error';
+
+  function wordRegexp(words) {
+    return new RegExp("^((" + words.join(")|(") + "))\\b");
+  }
+
+  var operators = parserConf.operators || /^\.?[|&^\\%*+\-<>!=\/]=?|\?|~|:|\$|\.[<>]|<<=?|>>>?=?|\.[<>=]=|->?|\/\/|\bin\b/;
+  var delimiters = parserConf.delimiters || /^[;,()[\]{}]/;
+  var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*!*/;
+  var blockOpeners = ["begin", "function", "type", "immutable", "let", "macro", "for", "while", "quote", "if", "else", "elseif", "try", "finally", "catch", "do"];
+  var blockClosers = ["end", "else", "elseif", "catch", "finally"];
+  var keywordList = ['if', 'else', 'elseif', 'while', 'for', 'begin', 'let', 'end', 'do', 'try', 'catch', 'finally', 'return', 'break', 'continue', 'global', 'local', 'const', 'export', 'import', 'importall', 'using', 'function', 'macro', 'module', 'baremodule', 'type', 'immutable', 'quote', 'typealias', 'abstract', 'bitstype', 'ccall'];
+  var builtinList = ['true', 'false', 'enumerate', 'open', 'close', 'nothing', 'NaN', 'Inf', 'print', 'println', 'Int', 'Int8', 'Uint8', 'Int16', 'Uint16', 'Int32', 'Uint32', 'Int64', 'Uint64', 'Int128', 'Uint128', 'Bool', 'Char', 'Float16', 'Float32', 'Float64', 'Array', 'Vector', 'Matrix', 'String', 'UTF8String', 'ASCIIString', 'error', 'warn', 'info', '@printf'];
+
+  //var stringPrefixes = new RegExp("^[br]?('|\")")
+  var stringPrefixes = /^(`|'|"{3}|([br]?"))/;
+  var keywords = wordRegexp(keywordList);
+  var builtins = wordRegexp(builtinList);
+  var openers = wordRegexp(blockOpeners);
+  var closers = wordRegexp(blockClosers);
+  var macro = /^@[_A-Za-z][_A-Za-z0-9]*/;
+  var symbol = /^:[_A-Za-z][_A-Za-z0-9]*/;
+  var indentInfo = null;
+
+  function in_array(state) {
+    var ch = cur_scope(state);
+    if(ch=="[" || ch=="{") {
+      return true;
+    }
+    else {
+      return false;
+    }
+  }
+
+  function cur_scope(state) {
+    if(state.scopes.length==0) {
+      return null;
+    }
+    return state.scopes[state.scopes.length - 1];
+  }
+
+  // tokenizers
+  function tokenBase(stream, state) {
+    // Handle scope changes
+    var leaving_expr = state.leaving_expr;
+    if(stream.sol()) {
+      leaving_expr = false;
+    }
+    state.leaving_expr = false;
+    if(leaving_expr) {
+      if(stream.match(/^'+/)) {
+        return 'operator';
+      }
+
+    }
+
+    if(stream.match(/^\.{2,3}/)) {
+      return 'operator';
+    }
+
+    if (stream.eatSpace()) {
+      return null;
+    }
+
+    var ch = stream.peek();
+    // Handle Comments
+    if (ch === '#') {
+        stream.skipToEnd();
+        return 'comment';
+    }
+    if(ch==='[') {
+      state.scopes.push("[");
+    }
+
+    if(ch==='{') {
+      state.scopes.push("{");
+    }
+
+    var scope=cur_scope(state);
+
+    if(scope==='[' && ch===']') {
+      state.scopes.pop();
+      state.leaving_expr=true;
+    }
+
+    if(scope==='{' && ch==='}') {
+      state.scopes.pop();
+      state.leaving_expr=true;
+    }
+
+    if(ch===')') {
+      state.leaving_expr = true;
+    }
+
+    var match;
+    if(!in_array(state) && (match=stream.match(openers, false))) {
+      state.scopes.push(match);
+    }
+
+    if(!in_array(state) && stream.match(closers, false)) {
+      state.scopes.pop();
+    }
+
+    if(in_array(state)) {
+      if(stream.match(/^end/)) {
+        return 'number';
+      }
+
+    }
+
+    if(stream.match(/^=>/)) {
+      return 'operator';
+    }
+
+
+    // Handle Number Literals
+    if (stream.match(/^[0-9\.]/, false)) {
+      var imMatcher = RegExp(/^im\b/);
+      var floatLiteral = false;
+      // Floats
+      if (stream.match(/^\d*\.(?!\.)\d+([ef][\+\-]?\d+)?/i)) { floatLiteral = true; }
+      if (stream.match(/^\d+\.(?!\.)\d*/)) { floatLiteral = true; }
+      if (stream.match(/^\.\d+/)) { floatLiteral = true; }
+      if (floatLiteral) {
+          // Float literals may be "imaginary"
+          stream.match(imMatcher);
+          state.leaving_expr = true;
+          return 'number';
+      }
+      // Integers
+      var intLiteral = false;
+      // Hex
+      if (stream.match(/^0x[0-9a-f]+/i)) { intLiteral = true; }
+      // Binary
+      if (stream.match(/^0b[01]+/i)) { intLiteral = true; }
+      // Octal
+      if (stream.match(/^0o[0-7]+/i)) { intLiteral = true; }
+      // Decimal
+      if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) {
+          intLiteral = true;
+      }
+      // Zero by itself with no other piece of number.
+      if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; }
+      if (intLiteral) {
+          // Integer literals may be "long"
+          stream.match(imMatcher);
+          state.leaving_expr = true;
+          return 'number';
+      }
+    }
+
+    if(stream.match(/^(::)|(<:)/)) {
+      return 'operator';
+    }
+
+    // Handle symbols
+    if(!leaving_expr && stream.match(symbol)) {
+      return 'string';
+    }
+
+    // Handle operators and Delimiters
+    if (stream.match(operators)) {
+      return 'operator';
+    }
+
+
+    // Handle Strings
+    if (stream.match(stringPrefixes)) {
+      state.tokenize = tokenStringFactory(stream.current());
+      return state.tokenize(stream, state);
+    }
+
+    if (stream.match(macro)) {
+      return 'meta';
+    }
+
+
+    if (stream.match(delimiters)) {
+      return null;
+    }
+
+    if (stream.match(keywords)) {
+      return 'keyword';
+    }
+
+    if (stream.match(builtins)) {
+      return 'builtin';
+    }
+
+
+    if (stream.match(identifiers)) {
+      state.leaving_expr=true;
+      return 'variable';
+    }
+    // Handle non-detected items
+    stream.next();
+    return ERRORCLASS;
+  }
+
+  function tokenStringFactory(delimiter) {
+    while ('rub'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
+      delimiter = delimiter.substr(1);
+    }
+    var singleline = delimiter.length == 1;
+    var OUTCLASS = 'string';
+
+    function tokenString(stream, state) {
+      while (!stream.eol()) {
+        stream.eatWhile(/[^'"\\]/);
+        if (stream.eat('\\')) {
+            stream.next();
+            if (singleline && stream.eol()) {
+              return OUTCLASS;
+            }
+        } else if (stream.match(delimiter)) {
+            state.tokenize = tokenBase;
+            return OUTCLASS;
+        } else {
+            stream.eat(/['"]/);
+        }
+      }
+      if (singleline) {
+        if (parserConf.singleLineStringErrors) {
+            return ERRORCLASS;
+        } else {
+            state.tokenize = tokenBase;
+        }
+      }
+      return OUTCLASS;
+    }
+    tokenString.isString = true;
+    return tokenString;
+  }
+
+  function tokenLexer(stream, state) {
+    indentInfo = null;
+    var style = state.tokenize(stream, state);
+    var current = stream.current();
+
+    // Handle '.' connected identifiers
+    if (current === '.') {
+      style = stream.match(identifiers, false) ? null : ERRORCLASS;
+      if (style === null && state.lastStyle === 'meta') {
+          // Apply 'meta' style to '.' connected identifiers when
+          // appropriate.
+        style = 'meta';
+      }
+      return style;
+    }
+
+    return style;
+  }
+
+  var external = {
+    startState: function() {
+      return {
+        tokenize: tokenBase,
+        scopes: [],
+        leaving_expr: false
+      };
+    },
+
+    token: function(stream, state) {
+      var style = tokenLexer(stream, state);
+      state.lastStyle = style;
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      var delta = 0;
+      if(textAfter=="end" || textAfter=="]" || textAfter=="}" || textAfter=="else" || textAfter=="elseif" || textAfter=="catch" || textAfter=="finally") {
+        delta = -1;
+      }
+      return (state.scopes.length + delta) * 4;
+    },
+
+    lineComment: "#",
+    fold: "indent",
+    electricChars: "edlsifyh]}"
+  };
+  return external;
+});
+
+
+CodeMirror.defineMIME("text/x-julia", "julia");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/livescript/index.html b/app/gui/html/vendor/codemirror/mode/livescript/index.html
new file mode 100644
index 0000000..3ce8974
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/livescript/index.html
@@ -0,0 +1,459 @@
+<!doctype html>
+
+<title>CodeMirror: LiveScript mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link rel="stylesheet" href="../../theme/solarized.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="livescript.js"></script>
+<style>.CodeMirror {font-size: 80%;border-top: 1px solid silver; border-bottom: 1px solid silver;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">LiveScript</a>
+  </ul>
+</div>
+
+<article>
+<h2>LiveScript mode</h2>
+<form><textarea id="code" name="code">
+# LiveScript mode for CodeMirror
+# The following script, prelude.ls, is used to
+# demonstrate LiveScript mode for CodeMirror.
+#   https://github.com/gkz/prelude-ls
+
+export objToFunc = objToFunc = (obj) ->
+  (key) -> obj[key]
+
+export each = (f, xs) -->
+  if typeof! xs is \Object
+    for , x of xs then f x
+  else
+    for x in xs then f x
+  xs
+
+export map = (f, xs) -->
+  f = objToFunc f if typeof! f isnt \Function
+  type = typeof! xs
+  if type is \Object
+    {[key, f x] for key, x of xs}
+  else
+    result = [f x for x in xs]
+    if type is \String then result * '' else result
+
+export filter = (f, xs) -->
+  f = objToFunc f if typeof! f isnt \Function
+  type = typeof! xs
+  if type is \Object
+    {[key, x] for key, x of xs when f x}
+  else
+    result = [x for x in xs when f x]
+    if type is \String then result * '' else result
+
+export reject = (f, xs) -->
+  f = objToFunc f if typeof! f isnt \Function
+  type = typeof! xs
+  if type is \Object
+    {[key, x] for key, x of xs when not f x}
+  else
+    result = [x for x in xs when not f x]
+    if type is \String then result * '' else result
+
+export partition = (f, xs) -->
+  f = objToFunc f if typeof! f isnt \Function
+  type = typeof! xs
+  if type is \Object
+    passed = {}
+    failed = {}
+    for key, x of xs
+      (if f x then passed else failed)[key] = x
+  else
+    passed = []
+    failed = []
+    for x in xs
+      (if f x then passed else failed)push x
+    if type is \String
+      passed *= ''
+      failed *= ''
+  [passed, failed]
+
+export find = (f, xs) -->
+  f = objToFunc f if typeof! f isnt \Function
+  if typeof! xs is \Object
+    for , x of xs when f x then return x
+  else
+    for x in xs when f x then return x
+  void
+
+export head = export first = (xs) ->
+  return void if not xs.length
+  xs.0
+
+export tail = (xs) ->
+  return void if not xs.length
+  xs.slice 1
+
+export last = (xs) ->
+  return void if not xs.length
+  xs[*-1]
+
+export initial = (xs) ->
+  return void if not xs.length
+  xs.slice 0 xs.length - 1
+
+export empty = (xs) ->
+  if typeof! xs is \Object
+    for x of xs then return false
+    return yes
+  not xs.length
+
+export values = (obj) ->
+  [x for , x of obj]
+
+export keys = (obj) ->
+  [x for x of obj]
+
+export len = (xs) ->
+  xs = values xs if typeof! xs is \Object
+  xs.length
+
+export cons = (x, xs) -->
+  if typeof! xs is \String then x + xs else [x] ++ xs
+
+export append = (xs, ys) -->
+  if typeof! ys is \String then xs + ys else xs ++ ys
+
+export join = (sep, xs) -->
+  xs = values xs if typeof! xs is \Object
+  xs.join sep
+
+export reverse = (xs) ->
+  if typeof! xs is \String
+  then (xs / '')reverse! * ''
+  else xs.slice!reverse!
+
+export fold = export foldl = (f, memo, xs) -->
+  if typeof! xs is \Object
+    for , x of xs then memo = f memo, x
+  else
+    for x in xs then memo = f memo, x
+  memo
+
+export fold1 = export foldl1 = (f, xs) --> fold f, xs.0, xs.slice 1
+
+export foldr = (f, memo, xs) --> fold f, memo, xs.slice!reverse!
+
+export foldr1 = (f, xs) -->
+  xs.=slice!reverse!
+  fold f, xs.0, xs.slice 1
+
+export unfoldr = export unfold = (f, b) -->
+  if (f b)?
+    [that.0] ++ unfoldr f, that.1
+  else
+    []
+
+export andList = (xs) ->
+  for x in xs when not x
+    return false
+  true
+
+export orList = (xs) ->
+  for x in xs when x
+    return true
+  false
+
+export any = (f, xs) -->
+  f = objToFunc f if typeof! f isnt \Function
+  for x in xs when f x
+    return yes
+  no
+
+export all = (f, xs) -->
+  f = objToFunc f if typeof! f isnt \Function
+  for x in xs when not f x
+    return no
+  yes
+
+export unique = (xs) ->
+  result = []
+  if typeof! xs is \Object
+    for , x of xs when x not in result then result.push x
+  else
+    for x   in xs when x not in result then result.push x
+  if typeof! xs is \String then result * '' else result
+
+export sort = (xs) ->
+  xs.concat!sort (x, y) ->
+    | x > y =>  1
+    | x < y => -1
+    | _     =>  0
+
+export sortBy = (f, xs) -->
+  return [] unless xs.length
+  xs.concat!sort f
+
+export compare = (f, x, y) -->
+  | (f x) > (f y) =>  1
+  | (f x) < (f y) => -1
+  | otherwise     =>  0
+
+export sum = (xs) ->
+  result = 0
+  if typeof! xs is \Object
+    for , x of xs then result += x
+  else
+    for x   in xs then result += x
+  result
+
+export product = (xs) ->
+  result = 1
+  if typeof! xs is \Object
+    for , x of xs then result *= x
+  else
+    for x   in xs then result *= x
+  result
+
+export mean = export average = (xs) -> (sum xs) / len xs
+
+export concat = (xss) -> fold append, [], xss
+
+export concatMap = (f, xs) --> fold ((memo, x) -> append memo, f x), [], xs
+
+export listToObj = (xs) ->
+  {[x.0, x.1] for x in xs}
+
+export maximum = (xs) -> fold1 (>?), xs
+
+export minimum = (xs) -> fold1 (<?), xs
+
+export scan = export scanl = (f, memo, xs) -->
+  last = memo
+  if typeof! xs is \Object
+  then [memo] ++ [last = f last, x for , x of xs]
+  else [memo] ++ [last = f last, x for x in xs]
+
+export scan1 = export scanl1 = (f, xs) --> scan f, xs.0, xs.slice 1
+
+export scanr = (f, memo, xs) -->
+  xs.=slice!reverse!
+  scan f, memo, xs .reverse!
+
+export scanr1 = (f, xs) -->
+  xs.=slice!reverse!
+  scan f, xs.0, xs.slice 1 .reverse!
+
+export replicate = (n, x) -->
+  result = []
+  i = 0
+  while i < n, ++i then result.push x
+  result
+
+export take = (n, xs) -->
+  | n <= 0
+    if typeof! xs is \String then '' else []
+  | not xs.length => xs
+  | otherwise     => xs.slice 0, n
+
+export drop = (n, xs) -->
+  | n <= 0        => xs
+  | not xs.length => xs
+  | otherwise     => xs.slice n
+
+export splitAt = (n, xs) --> [(take n, xs), (drop n, xs)]
+
+export takeWhile = (p, xs) -->
+  return xs if not xs.length
+  p = objToFunc p if typeof! p isnt \Function
+  result = []
+  for x in xs
+    break if not p x
+    result.push x
+  if typeof! xs is \String then result * '' else result
+
+export dropWhile = (p, xs) -->
+  return xs if not xs.length
+  p = objToFunc p if typeof! p isnt \Function
+  i = 0
+  for x in xs
+    break if not p x
+    ++i
+  drop i, xs
+
+export span = (p, xs) --> [(takeWhile p, xs), (dropWhile p, xs)]
+
+export breakIt = (p, xs) --> span (not) << p, xs
+
+export zip = (xs, ys) -->
+  result = []
+  for zs, i in [xs, ys]
+    for z, j in zs
+      result.push [] if i is 0
+      result[j]?push z
+  result
+
+export zipWith = (f,xs, ys) -->
+  f = objToFunc f if typeof! f isnt \Function
+  if not xs.length or not ys.length
+    []
+  else
+    [f.apply this, zs for zs in zip.call this, xs, ys]
+
+export zipAll = (...xss) ->
+  result = []
+  for xs, i in xss
+    for x, j in xs
+      result.push [] if i is 0
+      result[j]?push x
+  result
+
+export zipAllWith = (f, ...xss) ->
+  f = objToFunc f if typeof! f isnt \Function
+  if not xss.0.length or not xss.1.length
+    []
+  else
+    [f.apply this, xs for xs in zipAll.apply this, xss]
+
+export compose = (...funcs) ->
+  ->
+    args = arguments
+    for f in funcs
+      args = [f.apply this, args]
+    args.0
+
+export curry = (f) ->
+  curry$ f # using util method curry$ from livescript
+
+export id = (x) -> x
+
+export flip = (f, x, y) --> f y, x
+
+export fix = (f) ->
+  ( (g, x) -> -> f(g g) ...arguments ) do
+    (g, x) -> -> f(g g) ...arguments
+
+export lines = (str) ->
+  return [] if not str.length
+  str / \\n
+
+export unlines = (strs) -> strs * \\n
+
+export words = (str) ->
+  return [] if not str.length
+  str / /[ ]+/
+
+export unwords = (strs) -> strs * ' '
+
+export max = (>?)
+
+export min = (<?)
+
+export negate = (x) -> -x
+
+export abs = Math.abs
+
+export signum = (x) ->
+  | x < 0     => -1
+  | x > 0     =>  1
+  | otherwise =>  0
+
+export quot = (x, y) --> ~~(x / y)
+
+export rem = (%)
+
+export div = (x, y) --> Math.floor x / y
+
+export mod = (%%)
+
+export recip = (1 /)
+
+export pi = Math.PI
+
+export tau = pi * 2
+
+export exp = Math.exp
+
+export sqrt = Math.sqrt
+
+# changed from log as log is a
+# common function for logging things
+export ln = Math.log
+
+export pow = (^)
+
+export sin = Math.sin
+
+export tan = Math.tan
+
+export cos = Math.cos
+
+export asin = Math.asin
+
+export acos = Math.acos
+
+export atan = Math.atan
+
+export atan2 = (x, y) --> Math.atan2 x, y
+
+# sinh
+# tanh
+# cosh
+# asinh
+# atanh
+# acosh
+
+export truncate = (x) -> ~~x
+
+export round = Math.round
+
+export ceiling = Math.ceil
+
+export floor = Math.floor
+
+export isItNaN = (x) -> x isnt x
+
+export even = (x) -> x % 2 == 0
+
+export odd = (x) -> x % 2 != 0
+
+export gcd = (x, y) -->
+  x = Math.abs x
+  y = Math.abs y
+  until y is 0
+    z = x % y
+    x = y
+    y = z
+  x
+
+export lcm = (x, y) -->
+  Math.abs Math.floor (x / (gcd x, y) * y)
+
+# meta
+export installPrelude = !(target) ->
+  unless target.prelude?isInstalled
+    target <<< out$ # using out$ generated by livescript
+    target <<< target.prelude.isInstalled = true
+
+export prelude = out$
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        theme: "solarized light",
+        lineNumbers: true
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-livescript</code>.</p>
+
+    <p>The LiveScript mode was written by Kenneth Bentley.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/livescript/livescript.js b/app/gui/html/vendor/codemirror/mode/livescript/livescript.js
new file mode 100644
index 0000000..9322ba8
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/livescript/livescript.js
@@ -0,0 +1,280 @@
+/**
+ * Link to the project's GitHub page:
+ * https://github.com/duralog/CodeMirror
+ */
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+(function() {
+  CodeMirror.defineMode('livescript', function(){
+    var tokenBase, external;
+    tokenBase = function(stream, state){
+      var next_rule, nr, i$, len$, r, m;
+      if (next_rule = state.next || 'start') {
+        state.next = state.next;
+        if (Array.isArray(nr = Rules[next_rule])) {
+          for (i$ = 0, len$ = nr.length; i$ < len$; ++i$) {
+            r = nr[i$];
+            if (r.regex && (m = stream.match(r.regex))) {
+              state.next = r.next;
+              return r.token;
+            }
+          }
+          stream.next();
+          return 'error';
+        }
+        if (stream.match(r = Rules[next_rule])) {
+          if (r.regex && stream.match(r.regex)) {
+            state.next = r.next;
+            return r.token;
+          } else {
+            stream.next();
+            return 'error';
+          }
+        }
+      }
+      stream.next();
+      return 'error';
+    };
+    external = {
+      startState: function(){
+        return {
+          next: 'start',
+          lastToken: null
+        };
+      },
+      token: function(stream, state){
+        var style;
+        style = tokenBase(stream, state);
+        state.lastToken = {
+          style: style,
+          indent: stream.indentation(),
+          content: stream.current()
+        };
+        return style.replace(/\./g, ' ');
+      },
+      indent: function(state){
+        var indentation;
+        indentation = state.lastToken.indent;
+        if (state.lastToken.content.match(indenter)) {
+          indentation += 2;
+        }
+        return indentation;
+      }
+    };
+    return external;
+  });
+
+  var identifier = '(?![\\d\\s])[$\\w\\xAA-\\uFFDC](?:(?!\\s)[$\\w\\xAA-\\uFFDC]|-[A-Za-z])*';
+  var indenter = RegExp('(?:[({[=:]|[-~]>|\\b(?:e(?:lse|xport)|d(?:o|efault)|t(?:ry|hen)|finally|import(?:\\s*all)?|const|var|let|new|catch(?:\\s*' + identifier + ')?))\\s*$');
+  var keywordend = '(?![$\\w]|-[A-Za-z]|\\s*:(?![:=]))';
+  var stringfill = {
+    token: 'string',
+    regex: '.+'
+  };
+  var Rules = {
+    start: [
+      {
+        token: 'comment.doc',
+        regex: '/\\*',
+        next: 'comment'
+      }, {
+        token: 'comment',
+        regex: '#.*'
+      }, {
+        token: 'keyword',
+        regex: '(?:t(?:h(?:is|row|en)|ry|ypeof!?)|c(?:on(?:tinue|st)|a(?:se|tch)|lass)|i(?:n(?:stanceof)?|mp(?:ort(?:\\s+all)?|lements)|[fs])|d(?:e(?:fault|lete|bugger)|o)|f(?:or(?:\\s+own)?|inally|unction)|s(?:uper|witch)|e(?:lse|x(?:tends|port)|val)|a(?:nd|rguments)|n(?:ew|ot)|un(?:less|til)|w(?:hile|ith)|o[fr]|return|break|let|var|loop)' + keywordend
+      }, {
+        token: 'constant.language',
+        regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend
+      }, {
+        token: 'invalid.illegal',
+        regex: '(?:p(?:ackage|r(?:ivate|otected)|ublic)|i(?:mplements|nterface)|enum|static|yield)' + keywordend
+      }, {
+        token: 'language.support.class',
+        regex: '(?:R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|Array|Boolean|Date|Function|Number|Object|TypeError|URIError)' + keywordend
+      }, {
+        token: 'language.support.function',
+        regex: '(?:is(?:NaN|Finite)|parse(?:Int|Float)|Math|JSON|(?:en|de)codeURI(?:Component)?)' + keywordend
+      }, {
+        token: 'variable.language',
+        regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend
+      }, {
+        token: 'identifier',
+        regex: identifier + '\\s*:(?![:=])'
+      }, {
+        token: 'variable',
+        regex: identifier
+      }, {
+        token: 'keyword.operator',
+        regex: '(?:\\.{3}|\\s+\\?)'
+      }, {
+        token: 'keyword.variable',
+        regex: '(?:@+|::|\\.\\.)',
+        next: 'key'
+      }, {
+        token: 'keyword.operator',
+        regex: '\\.\\s*',
+        next: 'key'
+      }, {
+        token: 'string',
+        regex: '\\\\\\S[^\\s,;)}\\]]*'
+      }, {
+        token: 'string.doc',
+        regex: '\'\'\'',
+        next: 'qdoc'
+      }, {
+        token: 'string.doc',
+        regex: '"""',
+        next: 'qqdoc'
+      }, {
+        token: 'string',
+        regex: '\'',
+        next: 'qstring'
+      }, {
+        token: 'string',
+        regex: '"',
+        next: 'qqstring'
+      }, {
+        token: 'string',
+        regex: '`',
+        next: 'js'
+      }, {
+        token: 'string',
+        regex: '<\\[',
+        next: 'words'
+      }, {
+        token: 'string.regex',
+        regex: '//',
+        next: 'heregex'
+      }, {
+        token: 'string.regex',
+        regex: '\\/(?:[^[\\/\\n\\\\]*(?:(?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[\\/\\n\\\\]*)*)\\/[gimy$]{0,4}',
+        next: 'key'
+      }, {
+        token: 'constant.numeric',
+        regex: '(?:0x[\\da-fA-F][\\da-fA-F_]*|(?:[2-9]|[12]\\d|3[0-6])r[\\da-zA-Z][\\da-zA-Z_]*|(?:\\d[\\d_]*(?:\\.\\d[\\d_]*)?|\\.\\d[\\d_]*)(?:e[+-]?\\d[\\d_]*)?[\\w$]*)'
+      }, {
+        token: 'lparen',
+        regex: '[({[]'
+      }, {
+        token: 'rparen',
+        regex: '[)}\\]]',
+        next: 'key'
+      }, {
+        token: 'keyword.operator',
+        regex: '\\S+'
+      }, {
+        token: 'text',
+        regex: '\\s+'
+      }
+    ],
+    heregex: [
+      {
+        token: 'string.regex',
+        regex: '.*?//[gimy$?]{0,4}',
+        next: 'start'
+      }, {
+        token: 'string.regex',
+        regex: '\\s*#{'
+      }, {
+        token: 'comment.regex',
+        regex: '\\s+(?:#.*)?'
+      }, {
+        token: 'string.regex',
+        regex: '\\S+'
+      }
+    ],
+    key: [
+      {
+        token: 'keyword.operator',
+        regex: '[.?@!]+'
+      }, {
+        token: 'identifier',
+        regex: identifier,
+        next: 'start'
+      }, {
+        token: 'text',
+        regex: '.',
+        next: 'start'
+      }
+    ],
+    comment: [
+      {
+        token: 'comment.doc',
+        regex: '.*?\\*/',
+        next: 'start'
+      }, {
+        token: 'comment.doc',
+        regex: '.+'
+      }
+    ],
+    qdoc: [
+      {
+        token: 'string',
+        regex: ".*?'''",
+        next: 'key'
+      }, stringfill
+    ],
+    qqdoc: [
+      {
+        token: 'string',
+        regex: '.*?"""',
+        next: 'key'
+      }, stringfill
+    ],
+    qstring: [
+      {
+        token: 'string',
+        regex: '[^\\\\\']*(?:\\\\.[^\\\\\']*)*\'',
+        next: 'key'
+      }, stringfill
+    ],
+    qqstring: [
+      {
+        token: 'string',
+        regex: '[^\\\\"]*(?:\\\\.[^\\\\"]*)*"',
+        next: 'key'
+      }, stringfill
+    ],
+    js: [
+      {
+        token: 'string',
+        regex: '[^\\\\`]*(?:\\\\.[^\\\\`]*)*`',
+        next: 'key'
+      }, stringfill
+    ],
+    words: [
+      {
+        token: 'string',
+        regex: '.*?\\]>',
+        next: 'key'
+      }, stringfill
+    ]
+  };
+  for (var idx in Rules) {
+    var r = Rules[idx];
+    if (Array.isArray(r)) {
+      for (var i = 0, len = r.length; i < len; ++i) {
+        var rr = r[i];
+        if (rr.regex) {
+          Rules[idx][i].regex = new RegExp('^' + rr.regex);
+        }
+      }
+    } else if (r.regex) {
+      Rules[idx].regex = new RegExp('^' + r.regex);
+    }
+  }
+})();
+
+CodeMirror.defineMIME('text/x-livescript', 'livescript');
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/livescript/livescript.ls b/app/gui/html/vendor/codemirror/mode/livescript/livescript.ls
new file mode 100644
index 0000000..0652423
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/livescript/livescript.ls
@@ -0,0 +1,266 @@
+/**
+ * Link to the project's GitHub page:
+ * https://github.com/duralog/CodeMirror
+ */
+CodeMirror.defineMode 'livescript', (conf) ->
+  tokenBase = (stream, state) ->
+    #indent =
+    if next_rule = state.next or \start
+      state.next = state.next
+      if Array.isArray nr = Rules[next_rule]
+        for r in nr
+          if r.regex and m = stream.match r.regex
+            state.next = r.next
+            return r.token
+        stream.next!
+        return \error
+      if stream.match r = Rules[next_rule]
+        if r.regex and stream.match r.regex
+          state.next = r.next
+          return r.token
+        else
+          stream.next!
+          return \error
+    stream.next!
+    return 'error'
+  external = {
+    startState: (basecolumn) ->
+      {
+        next: \start
+        lastToken: null
+      }
+    token: (stream, state) ->
+      style = tokenBase stream, state #tokenLexer stream, state
+      state.lastToken = {
+        style: style
+        indent: stream.indentation!
+        content: stream.current!
+      }
+      style.replace /\./g, ' '
+    indent: (state, textAfter) ->
+      # XXX this won't work with backcalls
+      indentation = state.lastToken.indent
+      if state.lastToken.content.match indenter then indentation += 2
+      return indentation
+  }
+  external
+
+### Highlight Rules
+# taken from mode-ls.ls
+
+indenter = // (?
+    : [({[=:]
+    | [-~]>
+    | \b (?: e(?:lse|xport) | d(?:o|efault) | t(?:ry|hen) | finally |
+             import (?:\s* all)? | const | var |
+             let | new | catch (?:\s* #identifier)? )
+  ) \s* $ //
+
+identifier = /(?![\d\s])[$\w\xAA-\uFFDC](?:(?!\s)[$\w\xAA-\uFFDC]|-[A-Za-z])*/$
+keywordend = /(?![$\w]|-[A-Za-z]|\s*:(?![:=]))/$
+stringfill = token: \string, regex: '.+'
+
+Rules =
+  start:
+    * token: \comment.doc
+      regex: '/\\*'
+      next : \comment
+
+    * token: \comment
+      regex: '#.*'
+
+    * token: \keyword
+      regex: //(?
+        :t(?:h(?:is|row|en)|ry|ypeof!?)
+        |c(?:on(?:tinue|st)|a(?:se|tch)|lass)
+        |i(?:n(?:stanceof)?|mp(?:ort(?:\s+all)?|lements)|[fs])
+        |d(?:e(?:fault|lete|bugger)|o)
+        |f(?:or(?:\s+own)?|inally|unction)
+        |s(?:uper|witch)
+        |e(?:lse|x(?:tends|port)|val)
+        |a(?:nd|rguments)
+        |n(?:ew|ot)
+        |un(?:less|til)
+        |w(?:hile|ith)
+        |o[fr]|return|break|let|var|loop
+      )//$ + keywordend
+
+    * token: \constant.language
+      regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend
+
+    * token: \invalid.illegal
+      regex: '(?
+        :p(?:ackage|r(?:ivate|otected)|ublic)
+        |i(?:mplements|nterface)
+        |enum|static|yield
+      )' + keywordend
+
+    * token: \language.support.class
+      regex: '(?
+        :R(?:e(?:gExp|ferenceError)|angeError)
+        |S(?:tring|yntaxError)
+        |E(?:rror|valError)
+        |Array|Boolean|Date|Function|Number|Object|TypeError|URIError
+      )' + keywordend
+
+    * token: \language.support.function
+      regex: '(?
+        :is(?:NaN|Finite)
+        |parse(?:Int|Float)
+        |Math|JSON
+        |(?:en|de)codeURI(?:Component)?
+      )' + keywordend
+
+    * token: \variable.language
+      regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend
+
+    * token: \identifier
+      regex: identifier + /\s*:(?![:=])/$
+
+    * token: \variable
+      regex: identifier
+
+    * token: \keyword.operator
+      regex: /(?:\.{3}|\s+\?)/$
+
+    * token: \keyword.variable
+      regex: /(?:@+|::|\.\.)/$
+      next : \key
+
+    * token: \keyword.operator
+      regex: /\.\s*/$
+      next : \key
+
+    * token: \string
+      regex: /\\\S[^\s,;)}\]]*/$
+
+    * token: \string.doc
+      regex: \'''
+      next : \qdoc
+
+    * token: \string.doc
+      regex: \"""
+      next : \qqdoc
+
+    * token: \string
+      regex: \'
+      next : \qstring
+
+    * token: \string
+      regex: \"
+      next : \qqstring
+
+    * token: \string
+      regex: \`
+      next : \js
+
+    * token: \string
+      regex: '<\\['
+      next : \words
+
+    * token: \string.regex
+      regex: \//
+      next : \heregex
+
+    * token: \string.regex
+      regex: //
+        /(?: [^ [ / \n \\ ]*
+          (?: (?: \\.
+                | \[ [^\]\n\\]* (?:\\.[^\]\n\\]*)* \]
+              ) [^ [ / \n \\ ]*
+          )*
+        )/ [gimy$]{0,4}
+      //$
+      next : \key
+
+    * token: \constant.numeric
+      regex: '(?:0x[\\da-fA-F][\\da-fA-F_]*
+                |(?:[2-9]|[12]\\d|3[0-6])r[\\da-zA-Z][\\da-zA-Z_]*
+                |(?:\\d[\\d_]*(?:\\.\\d[\\d_]*)?|\\.\\d[\\d_]*)
+                 (?:e[+-]?\\d[\\d_]*)?[\\w$]*)'
+
+    * token: \lparen
+      regex: '[({[]'
+
+    * token: \rparen
+      regex: '[)}\\]]'
+      next : \key
+
+    * token: \keyword.operator
+      regex: \\\S+
+
+    * token: \text
+      regex: \\\s+
+
+  heregex:
+    * token: \string.regex
+      regex: '.*?//[gimy$?]{0,4}'
+      next : \start
+    * token: \string.regex
+      regex: '\\s*#{'
+    * token: \comment.regex
+      regex: '\\s+(?:#.*)?'
+    * token: \string.regex
+      regex: '\\S+'
+
+  key:
+    * token: \keyword.operator
+      regex: '[.?@!]+'
+    * token: \identifier
+      regex: identifier
+      next : \start
+    * token: \text
+      regex: '.'
+      next : \start
+
+  comment:
+    * token: \comment.doc
+      regex: '.*?\\*/'
+      next : \start
+    * token: \comment.doc
+      regex: '.+'
+
+  qdoc:
+    token: \string
+    regex: ".*?'''"
+    next : \key
+    stringfill
+
+  qqdoc:
+    token: \string
+    regex: '.*?"""'
+    next : \key
+    stringfill
+
+  qstring:
+    token: \string
+    regex: /[^\\']*(?:\\.[^\\']*)*'/$
+    next : \key
+    stringfill
+
+  qqstring:
+    token: \string
+    regex: /[^\\"]*(?:\\.[^\\"]*)*"/$
+    next : \key
+    stringfill
+
+  js:
+    token: \string
+    regex: /[^\\`]*(?:\\.[^\\`]*)*`/$
+    next : \key
+    stringfill
+
+  words:
+    token: \string
+    regex: '.*?\\]>'
+    next : \key
+    stringfill
+
+# for optimization, precompile the regexps
+for idx, r of Rules
+  if Array.isArray r
+    for rr, i in r
+      if rr.regex then Rules[idx][i].regex = new RegExp '^'+rr.regex
+  else if r.regex then Rules[idx].regex = new RegExp '^'+r.regex
+
+CodeMirror.defineMIME 'text/x-livescript', 'livescript'
diff --git a/app/gui/html/vendor/codemirror/mode/lua/index.html b/app/gui/html/vendor/codemirror/mode/lua/index.html
new file mode 100644
index 0000000..7f4eb2c
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/lua/index.html
@@ -0,0 +1,85 @@
+<!doctype html>
+
+<title>CodeMirror: Lua mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link rel="stylesheet" href="../../theme/neat.css">
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="../../lib/codemirror.js"></script>
+<script src="lua.js"></script>
+<style>.CodeMirror {border: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Lua</a>
+  </ul>
+</div>
+
+<article>
+<h2>Lua mode</h2>
+<form><textarea id="code" name="code">
+--[[
+example useless code to show lua syntax highlighting
+this is multiline comment
+]]
+
+function blahblahblah(x)
+
+  local table = {
+    "asd" = 123,
+    "x" = 0.34,  
+  }
+  if x ~= 3 then
+    print( x )
+  elseif x == "string"
+    my_custom_function( 0x34 )
+  else
+    unknown_function( "some string" )
+  end
+
+  --single line comment
+  
+end
+
+function blablabla3()
+
+  for k,v in ipairs( table ) do
+    --abcde..
+    y=[=[
+  x=[[
+      x is a multi line string
+   ]]
+  but its definition is iside a highest level string!
+  ]=]
+    print(" \"\" ")
+
+    s = math.sin( x )
+  end
+
+end
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        matchBrackets: true,
+        theme: "neat"
+      });
+    </script>
+
+    <p>Loosely based on Franciszek
+    Wawrzak's <a href="http://codemirror.net/1/contrib/lua">CodeMirror
+    1 mode</a>. One configuration parameter is
+    supported, <code>specials</code>, to which you can provide an
+    array of strings to have those identifiers highlighted with
+    the <code>lua-special</code> style.</p>
+    <p><strong>MIME types defined:</strong> <code>text/x-lua</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/lua/lua.js b/app/gui/html/vendor/codemirror/mode/lua/lua.js
new file mode 100644
index 0000000..3673557
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/lua/lua.js
@@ -0,0 +1,156 @@
+// LUA mode. Ported to CodeMirror 2 from Franciszek Wawrzak's
+// CodeMirror 1 mode.
+// highlights keywords, strings, comments (no leveling supported! ("[==[")), tokens, basic indenting
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("lua", function(config, parserConfig) {
+  var indentUnit = config.indentUnit;
+
+  function prefixRE(words) {
+    return new RegExp("^(?:" + words.join("|") + ")", "i");
+  }
+  function wordRE(words) {
+    return new RegExp("^(?:" + words.join("|") + ")$", "i");
+  }
+  var specials = wordRE(parserConfig.specials || []);
+
+  // long list of standard functions from lua manual
+  var builtins = wordRE([
+    "_G","_VERSION","assert","collectgarbage","dofile","error","getfenv","getmetatable","ipairs","load",
+    "loadfile","loadstring","module","next","pairs","pcall","print","rawequal","rawget","rawset","require",
+    "select","setfenv","setmetatable","tonumber","tostring","type","unpack","xpcall",
+
+    "coroutine.create","coroutine.resume","coroutine.running","coroutine.status","coroutine.wrap","coroutine.yield",
+
+    "debug.debug","debug.getfenv","debug.gethook","debug.getinfo","debug.getlocal","debug.getmetatable",
+    "debug.getregistry","debug.getupvalue","debug.setfenv","debug.sethook","debug.setlocal","debug.setmetatable",
+    "debug.setupvalue","debug.traceback",
+
+    "close","flush","lines","read","seek","setvbuf","write",
+
+    "io.close","io.flush","io.input","io.lines","io.open","io.output","io.popen","io.read","io.stderr","io.stdin",
+    "io.stdout","io.tmpfile","io.type","io.write",
+
+    "math.abs","math.acos","math.asin","math.atan","math.atan2","math.ceil","math.cos","math.cosh","math.deg",
+    "math.exp","math.floor","math.fmod","math.frexp","math.huge","math.ldexp","math.log","math.log10","math.max",
+    "math.min","math.modf","math.pi","math.pow","math.rad","math.random","math.randomseed","math.sin","math.sinh",
+    "math.sqrt","math.tan","math.tanh",
+
+    "os.clock","os.date","os.difftime","os.execute","os.exit","os.getenv","os.remove","os.rename","os.setlocale",
+    "os.time","os.tmpname",
+
+    "package.cpath","package.loaded","package.loaders","package.loadlib","package.path","package.preload",
+    "package.seeall",
+
+    "string.byte","string.char","string.dump","string.find","string.format","string.gmatch","string.gsub",
+    "string.len","string.lower","string.match","string.rep","string.reverse","string.sub","string.upper",
+
+    "table.concat","table.insert","table.maxn","table.remove","table.sort"
+  ]);
+  var keywords = wordRE(["and","break","elseif","false","nil","not","or","return",
+                         "true","function", "end", "if", "then", "else", "do",
+                         "while", "repeat", "until", "for", "in", "local" ]);
+
+  var indentTokens = wordRE(["function", "if","repeat","do", "\\(", "{"]);
+  var dedentTokens = wordRE(["end", "until", "\\)", "}"]);
+  var dedentPartial = prefixRE(["end", "until", "\\)", "}", "else", "elseif"]);
+
+  function readBracket(stream) {
+    var level = 0;
+    while (stream.eat("=")) ++level;
+    stream.eat("[");
+    return level;
+  }
+
+  function normal(stream, state) {
+    var ch = stream.next();
+    if (ch == "-" && stream.eat("-")) {
+      if (stream.eat("[") && stream.eat("["))
+        return (state.cur = bracketed(readBracket(stream), "comment"))(stream, state);
+      stream.skipToEnd();
+      return "comment";
+    }
+    if (ch == "\"" || ch == "'")
+      return (state.cur = string(ch))(stream, state);
+    if (ch == "[" && /[\[=]/.test(stream.peek()))
+      return (state.cur = bracketed(readBracket(stream), "string"))(stream, state);
+    if (/\d/.test(ch)) {
+      stream.eatWhile(/[\w.%]/);
+      return "number";
+    }
+    if (/[\w_]/.test(ch)) {
+      stream.eatWhile(/[\w\\\-_.]/);
+      return "variable";
+    }
+    return null;
+  }
+
+  function bracketed(level, style) {
+    return function(stream, state) {
+      var curlev = null, ch;
+      while ((ch = stream.next()) != null) {
+        if (curlev == null) {if (ch == "]") curlev = 0;}
+        else if (ch == "=") ++curlev;
+        else if (ch == "]" && curlev == level) { state.cur = normal; break; }
+        else curlev = null;
+      }
+      return style;
+    };
+  }
+
+  function string(quote) {
+    return function(stream, state) {
+      var escaped = false, ch;
+      while ((ch = stream.next()) != null) {
+        if (ch == quote && !escaped) break;
+        escaped = !escaped && ch == "\\";
+      }
+      if (!escaped) state.cur = normal;
+      return "string";
+    };
+  }
+
+  return {
+    startState: function(basecol) {
+      return {basecol: basecol || 0, indentDepth: 0, cur: normal};
+    },
+
+    token: function(stream, state) {
+      if (stream.eatSpace()) return null;
+      var style = state.cur(stream, state);
+      var word = stream.current();
+      if (style == "variable") {
+        if (keywords.test(word)) style = "keyword";
+        else if (builtins.test(word)) style = "builtin";
+        else if (specials.test(word)) style = "variable-2";
+      }
+      if ((style != "comment") && (style != "string")){
+        if (indentTokens.test(word)) ++state.indentDepth;
+        else if (dedentTokens.test(word)) --state.indentDepth;
+      }
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      var closing = dedentPartial.test(textAfter);
+      return state.basecol + indentUnit * (state.indentDepth - (closing ? 1 : 0));
+    },
+
+    lineComment: "--",
+    blockCommentStart: "--[[",
+    blockCommentEnd: "]]"
+  };
+});
+
+CodeMirror.defineMIME("text/x-lua", "lua");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/markdown/index.html b/app/gui/html/vendor/codemirror/mode/markdown/index.html
new file mode 100644
index 0000000..a6b541e
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/markdown/index.html
@@ -0,0 +1,359 @@
+<!doctype html>
+
+<title>CodeMirror: Markdown mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/continuelist.js"></script>
+<script src="../xml/xml.js"></script>
+<script src="markdown.js"></script>
+<style type="text/css">
+      .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+      .cm-s-default .cm-trailing-space-a:before,
+      .cm-s-default .cm-trailing-space-b:before {position: absolute; content: "\00B7"; color: #777;}
+      .cm-s-default .cm-trailing-space-new-line:before {position: absolute; content: "\21B5"; color: #777;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Markdown</a>
+  </ul>
+</div>
+
+<article>
+<h2>Markdown mode</h2>
+<form><textarea id="code" name="code">
+Markdown: Basics
+================
+
+<ul id="ProjectSubmenu">
+    <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
+    <li><a class="selected" title="Markdown Basics">Basics</a></li>
+    <li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li>
+    <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
+    <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
+</ul>
+
+
+Getting the Gist of Markdown's Formatting Syntax
+------------------------------------------------
+
+This page offers a brief overview of what it's like to use Markdown.
+The [syntax page] [s] provides complete, detailed documentation for
+every feature, but Markdown should be very easy to pick up simply by
+looking at a few examples of it in action. The examples on this page
+are written in a before/after style, showing example syntax and the
+HTML output produced by Markdown.
+
+It's also helpful to simply try Markdown out; the [Dingus] [d] is a
+web application that allows you type your own Markdown-formatted text
+and translate it to XHTML.
+
+**Note:** This document is itself written using Markdown; you
+can [see the source for it by adding '.text' to the URL] [src].
+
+  [s]: /projects/markdown/syntax  "Markdown Syntax"
+  [d]: /projects/markdown/dingus  "Markdown Dingus"
+  [src]: /projects/markdown/basics.text
+
+
+## Paragraphs, Headers, Blockquotes ##
+
+A paragraph is simply one or more consecutive lines of text, separated
+by one or more blank lines. (A blank line is any line that looks like
+a blank line -- a line containing nothing but spaces or tabs is
+considered blank.) Normal paragraphs should not be indented with
+spaces or tabs.
+
+Markdown offers two styles of headers: *Setext* and *atx*.
+Setext-style headers for `<h1>` and `<h2>` are created by
+"underlining" with equal signs (`=`) and hyphens (`-`), respectively.
+To create an atx-style header, you put 1-6 hash marks (`#`) at the
+beginning of the line -- the number of hashes equals the resulting
+HTML header level.
+
+Blockquotes are indicated using email-style '`>`' angle brackets.
+
+Markdown:
+
+    A First Level Header
+    ====================
+    
+    A Second Level Header
+    ---------------------
+
+    Now is the time for all good men to come to
+    the aid of their country. This is just a
+    regular paragraph.
+
+    The quick brown fox jumped over the lazy
+    dog's back.
+    
+    ### Header 3
+
+    > This is a blockquote.
+    > 
+    > This is the second paragraph in the blockquote.
+    >
+    > ## This is an H2 in a blockquote
+
+
+Output:
+
+    <h1>A First Level Header</h1>
+    
+    <h2>A Second Level Header</h2>
+    
+    <p>Now is the time for all good men to come to
+    the aid of their country. This is just a
+    regular paragraph.</p>
+    
+    <p>The quick brown fox jumped over the lazy
+    dog's back.</p>
+    
+    <h3>Header 3</h3>
+    
+    <blockquote>
+        <p>This is a blockquote.</p>
+        
+        <p>This is the second paragraph in the blockquote.</p>
+        
+        <h2>This is an H2 in a blockquote</h2>
+    </blockquote>
+
+
+
+### Phrase Emphasis ###
+
+Markdown uses asterisks and underscores to indicate spans of emphasis.
+
+Markdown:
+
+    Some of these words *are emphasized*.
+    Some of these words _are emphasized also_.
+    
+    Use two asterisks for **strong emphasis**.
+    Or, if you prefer, __use two underscores instead__.
+
+Output:
+
+    <p>Some of these words <em>are emphasized</em>.
+    Some of these words <em>are emphasized also</em>.</p>
+    
+    <p>Use two asterisks for <strong>strong emphasis</strong>.
+    Or, if you prefer, <strong>use two underscores instead</strong>.</p>
+   
+
+
+## Lists ##
+
+Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`,
+`+`, and `-`) as list markers. These three markers are
+interchangable; this:
+
+    *   Candy.
+    *   Gum.
+    *   Booze.
+
+this:
+
+    +   Candy.
+    +   Gum.
+    +   Booze.
+
+and this:
+
+    -   Candy.
+    -   Gum.
+    -   Booze.
+
+all produce the same output:
+
+    <ul>
+    <li>Candy.</li>
+    <li>Gum.</li>
+    <li>Booze.</li>
+    </ul>
+
+Ordered (numbered) lists use regular numbers, followed by periods, as
+list markers:
+
+    1.  Red
+    2.  Green
+    3.  Blue
+
+Output:
+
+    <ol>
+    <li>Red</li>
+    <li>Green</li>
+    <li>Blue</li>
+    </ol>
+
+If you put blank lines between items, you'll get `<p>` tags for the
+list item text. You can create multi-paragraph list items by indenting
+the paragraphs by 4 spaces or 1 tab:
+
+    *   A list item.
+    
+        With multiple paragraphs.
+
+    *   Another item in the list.
+
+Output:
+
+    <ul>
+    <li><p>A list item.</p>
+    <p>With multiple paragraphs.</p></li>
+    <li><p>Another item in the list.</p></li>
+    </ul>
+    
+
+
+### Links ###
+
+Markdown supports two styles for creating links: *inline* and
+*reference*. With both styles, you use square brackets to delimit the
+text you want to turn into a link.
+
+Inline-style links use parentheses immediately after the link text.
+For example:
+
+    This is an [example link](http://example.com/).
+
+Output:
+
+    <p>This is an <a href="http://example.com/">
+    example link</a>.</p>
+
+Optionally, you may include a title attribute in the parentheses:
+
+    This is an [example link](http://example.com/ "With a Title").
+
+Output:
+
+    <p>This is an <a href="http://example.com/" title="With a Title">
+    example link</a>.</p>
+
+Reference-style links allow you to refer to your links by names, which
+you define elsewhere in your document:
+
+    I get 10 times more traffic from [Google][1] than from
+    [Yahoo][2] or [MSN][3].
+
+    [1]: http://google.com/        "Google"
+    [2]: http://search.yahoo.com/  "Yahoo Search"
+    [3]: http://search.msn.com/    "MSN Search"
+
+Output:
+
+    <p>I get 10 times more traffic from <a href="http://google.com/"
+    title="Google">Google</a> than from <a href="http://search.yahoo.com/"
+    title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"
+    title="MSN Search">MSN</a>.</p>
+
+The title attribute is optional. Link names may contain letters,
+numbers and spaces, but are *not* case sensitive:
+
+    I start my morning with a cup of coffee and
+    [The New York Times][NY Times].
+
+    [ny times]: http://www.nytimes.com/
+
+Output:
+
+    <p>I start my morning with a cup of coffee and
+    <a href="http://www.nytimes.com/">The New York Times</a>.</p>
+
+
+### Images ###
+
+Image syntax is very much like link syntax.
+
+Inline (titles are optional):
+
+    ![alt text](/path/to/img.jpg "Title")
+
+Reference-style:
+
+    ![alt text][id]
+
+    [id]: /path/to/img.jpg "Title"
+
+Both of the above examples produce the same output:
+
+    <img src="/path/to/img.jpg" alt="alt text" title="Title" />
+
+
+
+### Code ###
+
+In a regular paragraph, you can create code span by wrapping text in
+backtick quotes. Any ampersands (`&`) and angle brackets (`<` or
+`>`) will automatically be translated into HTML entities. This makes
+it easy to use Markdown to write about HTML example code:
+
+    I strongly recommend against using any `<blink>` tags.
+
+    I wish SmartyPants used named entities like `&mdash;`
+    instead of decimal-encoded entites like `&#8212;`.
+
+Output:
+
+    <p>I strongly recommend against using any
+    <code>&lt;blink&gt;</code> tags.</p>
+    
+    <p>I wish SmartyPants used named entities like
+    <code>&amp;mdash;</code> instead of decimal-encoded
+    entites like <code>&amp;#8212;</code>.</p>
+
+
+To specify an entire block of pre-formatted code, indent every line of
+the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`,
+and `>` characters will be escaped automatically.
+
+Markdown:
+
+    If you want your page to validate under XHTML 1.0 Strict,
+    you've got to put paragraph tags in your blockquotes:
+
+        <blockquote>
+            <p>For example.</p>
+        </blockquote>
+
+Output:
+
+    <p>If you want your page to validate under XHTML 1.0 Strict,
+    you've got to put paragraph tags in your blockquotes:</p>
+    
+    <pre><code>&lt;blockquote&gt;
+        &lt;p&gt;For example.&lt;/p&gt;
+    &lt;/blockquote&gt;
+    </code></pre>
+</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: 'markdown',
+        lineNumbers: true,
+        theme: "default",
+        extraKeys: {"Enter": "newlineAndIndentContinueMarkdownList"}
+      });
+    </script>
+
+    <p>Optionally depends on the XML mode for properly highlighted inline XML blocks.</p>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-markdown</code>.</p>
+
+    <p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#markdown_*">normal</a>,  <a href="../../test/index.html#verbose,markdown_*">verbose</a>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/markdown/markdown.js b/app/gui/html/vendor/codemirror/mode/markdown/markdown.js
new file mode 100644
index 0000000..199c7a7
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/markdown/markdown.js
@@ -0,0 +1,760 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror", require("../xml/xml")));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "../xml/xml"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
+
+  var htmlFound = CodeMirror.modes.hasOwnProperty("xml");
+  var htmlMode = CodeMirror.getMode(cmCfg, htmlFound ? {name: "xml", htmlMode: true} : "text/plain");
+  var aliases = {
+    html: "htmlmixed",
+    js: "javascript",
+    json: "application/json",
+    c: "text/x-csrc",
+    "c++": "text/x-c++src",
+    java: "text/x-java",
+    csharp: "text/x-csharp",
+    "c#": "text/x-csharp",
+    scala: "text/x-scala"
+  };
+
+  var getMode = (function () {
+    var i, modes = {}, mimes = {}, mime;
+
+    var list = [];
+    for (var m in CodeMirror.modes)
+      if (CodeMirror.modes.propertyIsEnumerable(m)) list.push(m);
+    for (i = 0; i < list.length; i++) {
+      modes[list[i]] = list[i];
+    }
+    var mimesList = [];
+    for (var m in CodeMirror.mimeModes)
+      if (CodeMirror.mimeModes.propertyIsEnumerable(m))
+        mimesList.push({mime: m, mode: CodeMirror.mimeModes[m]});
+    for (i = 0; i < mimesList.length; i++) {
+      mime = mimesList[i].mime;
+      mimes[mime] = mimesList[i].mime;
+    }
+
+    for (var a in aliases) {
+      if (aliases[a] in modes || aliases[a] in mimes)
+        modes[a] = aliases[a];
+    }
+
+    return function (lang) {
+      return modes[lang] ? CodeMirror.getMode(cmCfg, modes[lang]) : null;
+    };
+  }());
+
+  // Should characters that affect highlighting be highlighted separate?
+  // Does not include characters that will be output (such as `1.` and `-` for lists)
+  if (modeCfg.highlightFormatting === undefined)
+    modeCfg.highlightFormatting = false;
+
+  // Maximum number of nested blockquotes. Set to 0 for infinite nesting.
+  // Excess `>` will emit `error` token.
+  if (modeCfg.maxBlockquoteDepth === undefined)
+    modeCfg.maxBlockquoteDepth = 0;
+
+  // Should underscores in words open/close em/strong?
+  if (modeCfg.underscoresBreakWords === undefined)
+    modeCfg.underscoresBreakWords = true;
+
+  // Turn on fenced code blocks? ("```" to start/end)
+  if (modeCfg.fencedCodeBlocks === undefined) modeCfg.fencedCodeBlocks = false;
+
+  // Turn on task lists? ("- [ ] " and "- [x] ")
+  if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
+
+  var codeDepth = 0;
+
+  var header   = 'header'
+  ,   code     = 'comment'
+  ,   quote    = 'quote'
+  ,   list1    = 'variable-2'
+  ,   list2    = 'variable-3'
+  ,   list3    = 'keyword'
+  ,   hr       = 'hr'
+  ,   image    = 'tag'
+  ,   formatting = 'formatting'
+  ,   linkinline = 'link'
+  ,   linkemail = 'link'
+  ,   linktext = 'link'
+  ,   linkhref = 'string'
+  ,   em       = 'em'
+  ,   strong   = 'strong';
+
+  var hrRE = /^([*\-=_])(?:\s*\1){2,}\s*$/
+  ,   ulRE = /^[*\-+]\s+/
+  ,   olRE = /^[0-9]+\.\s+/
+  ,   taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE
+  ,   atxHeaderRE = /^#+/
+  ,   setextHeaderRE = /^(?:\={1,}|-{1,})$/
+  ,   textRE = /^[^#!\[\]*_\\<>` "'(]+/;
+
+  function switchInline(stream, state, f) {
+    state.f = state.inline = f;
+    return f(stream, state);
+  }
+
+  function switchBlock(stream, state, f) {
+    state.f = state.block = f;
+    return f(stream, state);
+  }
+
+
+  // Blocks
+
+  function blankLine(state) {
+    // Reset linkTitle state
+    state.linkTitle = false;
+    // Reset EM state
+    state.em = false;
+    // Reset STRONG state
+    state.strong = false;
+    // Reset state.quote
+    state.quote = 0;
+    if (!htmlFound && state.f == htmlBlock) {
+      state.f = inlineNormal;
+      state.block = blockNormal;
+    }
+    // Reset state.trailingSpace
+    state.trailingSpace = 0;
+    state.trailingSpaceNewLine = false;
+    // Mark this line as blank
+    state.thisLineHasContent = false;
+    return null;
+  }
+
+  function blockNormal(stream, state) {
+
+    var sol = stream.sol();
+
+    var prevLineIsList = (state.list !== false);
+    if (state.list !== false && state.indentationDiff >= 0) { // Continued list
+      if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
+        state.indentation -= state.indentationDiff;
+      }
+      state.list = null;
+    } else if (state.list !== false && state.indentation > 0) {
+      state.list = null;
+      state.listDepth = Math.floor(state.indentation / 4);
+    } else if (state.list !== false) { // No longer a list
+      state.list = false;
+      state.listDepth = 0;
+    }
+
+    var match = null;
+    if (state.indentationDiff >= 4) {
+      state.indentation -= 4;
+      stream.skipToEnd();
+      return code;
+    } else if (stream.eatSpace()) {
+      return null;
+    } else if (match = stream.match(atxHeaderRE)) {
+      state.header = match[0].length <= 6 ? match[0].length : 6;
+      if (modeCfg.highlightFormatting) state.formatting = "header";
+      state.f = state.inline;
+      return getType(state);
+    } else if (state.prevLineHasContent && (match = stream.match(setextHeaderRE))) {
+      state.header = match[0].charAt(0) == '=' ? 1 : 2;
+      if (modeCfg.highlightFormatting) state.formatting = "header";
+      state.f = state.inline;
+      return getType(state);
+    } else if (stream.eat('>')) {
+      state.indentation++;
+      state.quote = sol ? 1 : state.quote + 1;
+      if (modeCfg.highlightFormatting) state.formatting = "quote";
+      stream.eatSpace();
+      return getType(state);
+    } else if (stream.peek() === '[') {
+      return switchInline(stream, state, footnoteLink);
+    } else if (stream.match(hrRE, true)) {
+      return hr;
+    } else if ((!state.prevLineHasContent || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) {
+      var listType = null;
+      if (stream.match(ulRE, true)) {
+        listType = 'ul';
+      } else {
+        stream.match(olRE, true);
+        listType = 'ol';
+      }
+      state.indentation += 4;
+      state.list = true;
+      state.listDepth++;
+      if (modeCfg.taskLists && stream.match(taskListRE, false)) {
+        state.taskList = true;
+      }
+      state.f = state.inline;
+      if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
+      return getType(state);
+    } else if (modeCfg.fencedCodeBlocks && stream.match(/^```([\w+#]*)/, true)) {
+      // try switching mode
+      state.localMode = getMode(RegExp.$1);
+      if (state.localMode) state.localState = state.localMode.startState();
+      switchBlock(stream, state, local);
+      if (modeCfg.highlightFormatting) state.formatting = "code-block";
+      state.code = true;
+      return getType(state);
+    }
+
+    return switchInline(stream, state, state.inline);
+  }
+
+  function htmlBlock(stream, state) {
+    var style = htmlMode.token(stream, state.htmlState);
+    if ((htmlFound && !state.htmlState.tagName && !state.htmlState.context) ||
+        (state.md_inside && stream.current().indexOf(">") > -1)) {
+      state.f = inlineNormal;
+      state.block = blockNormal;
+      state.htmlState = null;
+    }
+    return style;
+  }
+
+  function local(stream, state) {
+    if (stream.sol() && stream.match(/^```/, true)) {
+      state.localMode = state.localState = null;
+      state.f = inlineNormal;
+      state.block = blockNormal;
+      if (modeCfg.highlightFormatting) state.formatting = "code-block";
+      state.code = true;
+      var returnType = getType(state);
+      state.code = false;
+      return returnType;
+    } else if (state.localMode) {
+      return state.localMode.token(stream, state.localState);
+    } else {
+      stream.skipToEnd();
+      return code;
+    }
+  }
+
+  // Inline
+  function getType(state) {
+    var styles = [];
+
+    if (state.formatting) {
+      styles.push(formatting);
+
+      if (typeof state.formatting === "string") state.formatting = [state.formatting];
+
+      for (var i = 0; i < state.formatting.length; i++) {
+        styles.push(formatting + "-" + state.formatting[i]);
+
+        if (state.formatting[i] === "header") {
+          styles.push(formatting + "-" + state.formatting[i] + "-" + state.header);
+        }
+
+        // Add `formatting-quote` and `formatting-quote-#` for blockquotes
+        // Add `error` instead if the maximum blockquote nesting depth is passed
+        if (state.formatting[i] === "quote") {
+          if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
+            styles.push(formatting + "-" + state.formatting[i] + "-" + state.quote);
+          } else {
+            styles.push("error");
+          }
+        }
+      }
+    }
+
+    if (state.taskOpen) {
+      styles.push("meta");
+      return styles.length ? styles.join(' ') : null;
+    }
+    if (state.taskClosed) {
+      styles.push("property");
+      return styles.length ? styles.join(' ') : null;
+    }
+
+    if (state.linkHref) {
+      styles.push(linkhref);
+      return styles.length ? styles.join(' ') : null;
+    }
+
+    if (state.strong) { styles.push(strong); }
+    if (state.em) { styles.push(em); }
+
+    if (state.linkText) { styles.push(linktext); }
+
+    if (state.code) { styles.push(code); }
+
+    if (state.header) { styles.push(header); styles.push(header + "-" + state.header); }
+
+    if (state.quote) {
+      styles.push(quote);
+
+      // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
+      if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
+        styles.push(quote + "-" + state.quote);
+      } else {
+        styles.push(quote + "-" + modeCfg.maxBlockquoteDepth);
+      }
+    }
+
+    if (state.list !== false) {
+      var listMod = (state.listDepth - 1) % 3;
+      if (!listMod) {
+        styles.push(list1);
+      } else if (listMod === 1) {
+        styles.push(list2);
+      } else {
+        styles.push(list3);
+      }
+    }
+
+    if (state.trailingSpaceNewLine) {
+      styles.push("trailing-space-new-line");
+    } else if (state.trailingSpace) {
+      styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
+    }
+
+    return styles.length ? styles.join(' ') : null;
+  }
+
+  function handleText(stream, state) {
+    if (stream.match(textRE, true)) {
+      return getType(state);
+    }
+    return undefined;
+  }
+
+  function inlineNormal(stream, state) {
+    var style = state.text(stream, state);
+    if (typeof style !== 'undefined')
+      return style;
+
+    if (state.list) { // List marker (*, +, -, 1., etc)
+      state.list = null;
+      return getType(state);
+    }
+
+    if (state.taskList) {
+      var taskOpen = stream.match(taskListRE, true)[1] !== "x";
+      if (taskOpen) state.taskOpen = true;
+      else state.taskClosed = true;
+      if (modeCfg.highlightFormatting) state.formatting = "task";
+      state.taskList = false;
+      return getType(state);
+    }
+
+    state.taskOpen = false;
+    state.taskClosed = false;
+
+    if (state.header && stream.match(/^#+$/, true)) {
+      if (modeCfg.highlightFormatting) state.formatting = "header";
+      return getType(state);
+    }
+
+    // Get sol() value now, before character is consumed
+    var sol = stream.sol();
+
+    var ch = stream.next();
+
+    if (state.escape) {
+      state.escape = false;
+      return getType(state);
+    }
+
+    if (ch === '\\') {
+      if (modeCfg.highlightFormatting) state.formatting = "escape";
+      state.escape = true;
+      return getType(state);
+    }
+
+    // Matches link titles present on next line
+    if (state.linkTitle) {
+      state.linkTitle = false;
+      var matchCh = ch;
+      if (ch === '(') {
+        matchCh = ')';
+      }
+      matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
+      var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
+      if (stream.match(new RegExp(regex), true)) {
+        return linkhref;
+      }
+    }
+
+    // If this block is changed, it may need to be updated in GFM mode
+    if (ch === '`') {
+      var previousFormatting = state.formatting;
+      if (modeCfg.highlightFormatting) state.formatting = "code";
+      var t = getType(state);
+      var before = stream.pos;
+      stream.eatWhile('`');
+      var difference = 1 + stream.pos - before;
+      if (!state.code) {
+        codeDepth = difference;
+        state.code = true;
+        return getType(state);
+      } else {
+        if (difference === codeDepth) { // Must be exact
+          state.code = false;
+          return t;
+        }
+        state.formatting = previousFormatting;
+        return getType(state);
+      }
+    } else if (state.code) {
+      return getType(state);
+    }
+
+    if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
+      stream.match(/\[[^\]]*\]/);
+      state.inline = state.f = linkHref;
+      return image;
+    }
+
+    if (ch === '[' && stream.match(/.*\](\(| ?\[)/, false)) {
+      state.linkText = true;
+      if (modeCfg.highlightFormatting) state.formatting = "link";
+      return getType(state);
+    }
+
+    if (ch === ']' && state.linkText) {
+      if (modeCfg.highlightFormatting) state.formatting = "link";
+      var type = getType(state);
+      state.linkText = false;
+      state.inline = state.f = linkHref;
+      return type;
+    }
+
+    if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) {
+      state.f = state.inline = linkInline;
+      if (modeCfg.highlightFormatting) state.formatting = "link";
+      var type = getType(state);
+      if (type){
+        type += " ";
+      } else {
+        type = "";
+      }
+      return type + linkinline;
+    }
+
+    if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
+      state.f = state.inline = linkInline;
+      if (modeCfg.highlightFormatting) state.formatting = "link";
+      var type = getType(state);
+      if (type){
+        type += " ";
+      } else {
+        type = "";
+      }
+      return type + linkemail;
+    }
+
+    if (ch === '<' && stream.match(/^\w/, false)) {
+      if (stream.string.indexOf(">") != -1) {
+        var atts = stream.string.substring(1,stream.string.indexOf(">"));
+        if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) {
+          state.md_inside = true;
+        }
+      }
+      stream.backUp(1);
+      state.htmlState = CodeMirror.startState(htmlMode);
+      return switchBlock(stream, state, htmlBlock);
+    }
+
+    if (ch === '<' && stream.match(/^\/\w*?>/)) {
+      state.md_inside = false;
+      return "tag";
+    }
+
+    var ignoreUnderscore = false;
+    if (!modeCfg.underscoresBreakWords) {
+      if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {
+        var prevPos = stream.pos - 2;
+        if (prevPos >= 0) {
+          var prevCh = stream.string.charAt(prevPos);
+          if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {
+            ignoreUnderscore = true;
+          }
+        }
+      }
+    }
+    if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {
+      if (sol && stream.peek() === ' ') {
+        // Do nothing, surrounded by newline and space
+      } else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG
+        if (modeCfg.highlightFormatting) state.formatting = "strong";
+        var t = getType(state);
+        state.strong = false;
+        return t;
+      } else if (!state.strong && stream.eat(ch)) { // Add STRONG
+        state.strong = ch;
+        if (modeCfg.highlightFormatting) state.formatting = "strong";
+        return getType(state);
+      } else if (state.em === ch) { // Remove EM
+        if (modeCfg.highlightFormatting) state.formatting = "em";
+        var t = getType(state);
+        state.em = false;
+        return t;
+      } else if (!state.em) { // Add EM
+        state.em = ch;
+        if (modeCfg.highlightFormatting) state.formatting = "em";
+        return getType(state);
+      }
+    } else if (ch === ' ') {
+      if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
+        if (stream.peek() === ' ') { // Surrounded by spaces, ignore
+          return getType(state);
+        } else { // Not surrounded by spaces, back up pointer
+          stream.backUp(1);
+        }
+      }
+    }
+
+    if (ch === ' ') {
+      if (stream.match(/ +$/, false)) {
+        state.trailingSpace++;
+      } else if (state.trailingSpace) {
+        state.trailingSpaceNewLine = true;
+      }
+    }
+
+    return getType(state);
+  }
+
+  function linkInline(stream, state) {
+    var ch = stream.next();
+
+    if (ch === ">") {
+      state.f = state.inline = inlineNormal;
+      if (modeCfg.highlightFormatting) state.formatting = "link";
+      var type = getType(state);
+      if (type){
+        type += " ";
+      } else {
+        type = "";
+      }
+      return type + linkinline;
+    }
+
+    stream.match(/^[^>]+/, true);
+
+    return linkinline;
+  }
+
+  function linkHref(stream, state) {
+    // Check if space, and return NULL if so (to avoid marking the space)
+    if(stream.eatSpace()){
+      return null;
+    }
+    var ch = stream.next();
+    if (ch === '(' || ch === '[') {
+      state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]");
+      if (modeCfg.highlightFormatting) state.formatting = "link-string";
+      state.linkHref = true;
+      return getType(state);
+    }
+    return 'error';
+  }
+
+  function getLinkHrefInside(endChar) {
+    return function(stream, state) {
+      var ch = stream.next();
+
+      if (ch === endChar) {
+        state.f = state.inline = inlineNormal;
+        if (modeCfg.highlightFormatting) state.formatting = "link-string";
+        var returnState = getType(state);
+        state.linkHref = false;
+        return returnState;
+      }
+
+      if (stream.match(inlineRE(endChar), true)) {
+        stream.backUp(1);
+      }
+
+      state.linkHref = true;
+      return getType(state);
+    };
+  }
+
+  function footnoteLink(stream, state) {
+    if (stream.match(/^[^\]]*\]:/, false)) {
+      state.f = footnoteLinkInside;
+      stream.next(); // Consume [
+      if (modeCfg.highlightFormatting) state.formatting = "link";
+      state.linkText = true;
+      return getType(state);
+    }
+    return switchInline(stream, state, inlineNormal);
+  }
+
+  function footnoteLinkInside(stream, state) {
+    if (stream.match(/^\]:/, true)) {
+      state.f = state.inline = footnoteUrl;
+      if (modeCfg.highlightFormatting) state.formatting = "link";
+      var returnType = getType(state);
+      state.linkText = false;
+      return returnType;
+    }
+
+    stream.match(/^[^\]]+/, true);
+
+    return linktext;
+  }
+
+  function footnoteUrl(stream, state) {
+    // Check if space, and return NULL if so (to avoid marking the space)
+    if(stream.eatSpace()){
+      return null;
+    }
+    // Match URL
+    stream.match(/^[^\s]+/, true);
+    // Check for link title
+    if (stream.peek() === undefined) { // End of line, set flag to check next line
+      state.linkTitle = true;
+    } else { // More content on line, check if link title
+      stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
+    }
+    state.f = state.inline = inlineNormal;
+    return linkhref;
+  }
+
+  var savedInlineRE = [];
+  function inlineRE(endChar) {
+    if (!savedInlineRE[endChar]) {
+      // Escape endChar for RegExp (taken from http://stackoverflow.com/a/494122/526741)
+      endChar = (endChar+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
+      // Match any non-endChar, escaped character, as well as the closing
+      // endChar.
+      savedInlineRE[endChar] = new RegExp('^(?:[^\\\\]|\\\\.)*?(' + endChar + ')');
+    }
+    return savedInlineRE[endChar];
+  }
+
+  var mode = {
+    startState: function() {
+      return {
+        f: blockNormal,
+
+        prevLineHasContent: false,
+        thisLineHasContent: false,
+
+        block: blockNormal,
+        htmlState: null,
+        indentation: 0,
+
+        inline: inlineNormal,
+        text: handleText,
+
+        escape: false,
+        formatting: false,
+        linkText: false,
+        linkHref: false,
+        linkTitle: false,
+        em: false,
+        strong: false,
+        header: 0,
+        taskList: false,
+        list: false,
+        listDepth: 0,
+        quote: 0,
+        trailingSpace: 0,
+        trailingSpaceNewLine: false
+      };
+    },
+
+    copyState: function(s) {
+      return {
+        f: s.f,
+
+        prevLineHasContent: s.prevLineHasContent,
+        thisLineHasContent: s.thisLineHasContent,
+
+        block: s.block,
+        htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
+        indentation: s.indentation,
+
+        localMode: s.localMode,
+        localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
+
+        inline: s.inline,
+        text: s.text,
+        escape: false,
+        formatting: false,
+        linkTitle: s.linkTitle,
+        em: s.em,
+        strong: s.strong,
+        header: s.header,
+        taskList: s.taskList,
+        list: s.list,
+        listDepth: s.listDepth,
+        quote: s.quote,
+        trailingSpace: s.trailingSpace,
+        trailingSpaceNewLine: s.trailingSpaceNewLine,
+        md_inside: s.md_inside
+      };
+    },
+
+    token: function(stream, state) {
+
+      // Reset state.formatting
+      state.formatting = false;
+
+      if (stream.sol()) {
+        var forceBlankLine = stream.match(/^\s*$/, true) || state.header;
+
+        // Reset state.header
+        state.header = 0;
+
+        if (forceBlankLine) {
+          state.prevLineHasContent = false;
+          return blankLine(state);
+        } else {
+          state.prevLineHasContent = state.thisLineHasContent;
+          state.thisLineHasContent = true;
+        }
+
+        // Reset state.escape
+        state.escape = false;
+
+        // Reset state.taskList
+        state.taskList = false;
+
+        // Reset state.code
+        state.code = false;
+
+        // Reset state.trailingSpace
+        state.trailingSpace = 0;
+        state.trailingSpaceNewLine = false;
+
+        state.f = state.block;
+        var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, '    ').length;
+        var difference = Math.floor((indentation - state.indentation) / 4) * 4;
+        if (difference > 4) difference = 4;
+        var adjustedIndentation = state.indentation + difference;
+        state.indentationDiff = adjustedIndentation - state.indentation;
+        state.indentation = adjustedIndentation;
+        if (indentation > 0) return null;
+      }
+      return state.f(stream, state);
+    },
+
+    innerMode: function(state) {
+      if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode};
+      if (state.localState) return {state: state.localState, mode: state.localMode};
+      return {state: state, mode: mode};
+    },
+
+    blankLine: blankLine,
+
+    getType: getType,
+
+    fold: "markdown"
+  };
+  return mode;
+}, "xml");
+
+CodeMirror.defineMIME("text/x-markdown", "markdown");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/markdown/test.js b/app/gui/html/vendor/codemirror/mode/markdown/test.js
new file mode 100644
index 0000000..c3016d3
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/markdown/test.js
@@ -0,0 +1,724 @@
+(function() {
+  var mode = CodeMirror.getMode({tabSize: 4}, "markdown");
+  function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
+  var modeHighlightFormatting = CodeMirror.getMode({tabSize: 4}, {name: "markdown", highlightFormatting: true});
+  function FT(name) { test.mode(name, modeHighlightFormatting, Array.prototype.slice.call(arguments, 1)); }
+
+  FT("formatting_emAsterisk",
+     "[em&formatting&formatting-em *][em foo][em&formatting&formatting-em *]");
+
+  FT("formatting_emUnderscore",
+     "[em&formatting&formatting-em _][em foo][em&formatting&formatting-em _]");
+
+  FT("formatting_strongAsterisk",
+     "[strong&formatting&formatting-strong **][strong foo][strong&formatting&formatting-strong **]");
+
+  FT("formatting_strongUnderscore",
+     "[strong&formatting&formatting-strong __][strong foo][strong&formatting&formatting-strong __]");
+
+  FT("formatting_codeBackticks",
+     "[comment&formatting&formatting-code `][comment foo][comment&formatting&formatting-code `]");
+
+  FT("formatting_doubleBackticks",
+     "[comment&formatting&formatting-code ``][comment foo ` bar][comment&formatting&formatting-code ``]");
+
+  FT("formatting_atxHeader",
+     "[header&header-1&formatting&formatting-header&formatting-header-1 #][header&header-1  foo # bar ][header&header-1&formatting&formatting-header&formatting-header-1 #]");
+
+  FT("formatting_setextHeader",
+     "foo",
+     "[header&header-1&formatting&formatting-header&formatting-header-1 =]");
+
+  FT("formatting_blockquote",
+     "[quote&quote-1&formatting&formatting-quote&formatting-quote-1 > ][quote&quote-1 foo]");
+
+  FT("formatting_list",
+     "[variable-2&formatting&formatting-list&formatting-list-ul - ][variable-2 foo]");
+  FT("formatting_list",
+     "[variable-2&formatting&formatting-list&formatting-list-ol 1. ][variable-2 foo]");
+
+  FT("formatting_link",
+     "[link&formatting&formatting-link [][link foo][link&formatting&formatting-link ]]][string&formatting&formatting-link-string (][string http://example.com/][string&formatting&formatting-link-string )]");
+
+  FT("formatting_linkReference",
+     "[link&formatting&formatting-link [][link foo][link&formatting&formatting-link ]]][string&formatting&formatting-link-string [][string bar][string&formatting&formatting-link-string ]]]",
+     "[link&formatting&formatting-link [][link bar][link&formatting&formatting-link ]]:] [string http://example.com/]");
+
+  FT("formatting_linkWeb",
+     "[link&formatting&formatting-link <][link http://example.com/][link&formatting&formatting-link >]");
+
+  FT("formatting_linkEmail",
+     "[link&formatting&formatting-link <][link user at example.com][link&formatting&formatting-link >]");
+
+  FT("formatting_escape",
+     "[formatting&formatting-escape \\]*");
+
+  MT("plainText",
+     "foo");
+
+  // Don't style single trailing space
+  MT("trailingSpace1",
+     "foo ");
+
+  // Two or more trailing spaces should be styled with line break character
+  MT("trailingSpace2",
+     "foo[trailing-space-a  ][trailing-space-new-line  ]");
+
+  MT("trailingSpace3",
+     "foo[trailing-space-a  ][trailing-space-b  ][trailing-space-new-line  ]");
+
+  MT("trailingSpace4",
+     "foo[trailing-space-a  ][trailing-space-b  ][trailing-space-a  ][trailing-space-new-line  ]");
+
+  // Code blocks using 4 spaces (regardless of CodeMirror.tabSize value)
+  MT("codeBlocksUsing4Spaces",
+     "    [comment foo]");
+
+  // Code blocks using 4 spaces with internal indentation
+  MT("codeBlocksUsing4SpacesIndentation",
+     "    [comment bar]",
+     "        [comment hello]",
+     "            [comment world]",
+     "    [comment foo]",
+     "bar");
+
+  // Code blocks using 4 spaces with internal indentation
+  MT("codeBlocksUsing4SpacesIndentation",
+     " foo",
+     "    [comment bar]",
+     "        [comment hello]",
+     "    [comment world]");
+
+  // Code blocks using 1 tab (regardless of CodeMirror.indentWithTabs value)
+  MT("codeBlocksUsing1Tab",
+     "\t[comment foo]");
+
+  // Inline code using backticks
+  MT("inlineCodeUsingBackticks",
+     "foo [comment `bar`]");
+
+  // Block code using single backtick (shouldn't work)
+  MT("blockCodeSingleBacktick",
+     "[comment `]",
+     "foo",
+     "[comment `]");
+
+  // Unclosed backticks
+  // Instead of simply marking as CODE, it would be nice to have an
+  // incomplete flag for CODE, that is styled slightly different.
+  MT("unclosedBackticks",
+     "foo [comment `bar]");
+
+  // Per documentation: "To include a literal backtick character within a
+  // code span, you can use multiple backticks as the opening and closing
+  // delimiters"
+  MT("doubleBackticks",
+     "[comment ``foo ` bar``]");
+
+  // Tests based on Dingus
+  // http://daringfireball.net/projects/markdown/dingus
+  //
+  // Multiple backticks within an inline code block
+  MT("consecutiveBackticks",
+     "[comment `foo```bar`]");
+
+  // Multiple backticks within an inline code block with a second code block
+  MT("consecutiveBackticks",
+     "[comment `foo```bar`] hello [comment `world`]");
+
+  // Unclosed with several different groups of backticks
+  MT("unclosedBackticks",
+     "[comment ``foo ``` bar` hello]");
+
+  // Closed with several different groups of backticks
+  MT("closedBackticks",
+     "[comment ``foo ``` bar` hello``] world");
+
+  // atx headers
+  // http://daringfireball.net/projects/markdown/syntax#header
+
+  MT("atxH1",
+     "[header&header-1 # foo]");
+
+  MT("atxH2",
+     "[header&header-2 ## foo]");
+
+  MT("atxH3",
+     "[header&header-3 ### foo]");
+
+  MT("atxH4",
+     "[header&header-4 #### foo]");
+
+  MT("atxH5",
+     "[header&header-5 ##### foo]");
+
+  MT("atxH6",
+     "[header&header-6 ###### foo]");
+
+  // H6 - 7x '#' should still be H6, per Dingus
+  // http://daringfireball.net/projects/markdown/dingus
+  MT("atxH6NotH7",
+     "[header&header-6 ####### foo]");
+
+  // Inline styles should be parsed inside headers
+  MT("atxH1inline",
+     "[header&header-1 # foo ][header&header-1&em *bar*]");
+
+  // Setext headers - H1, H2
+  // Per documentation, "Any number of underlining =’s or -’s will work."
+  // http://daringfireball.net/projects/markdown/syntax#header
+  // Ideally, the text would be marked as `header` as well, but this is
+  // not really feasible at the moment. So, instead, we're testing against
+  // what works today, to avoid any regressions.
+  //
+  // Check if single underlining = works
+  MT("setextH1",
+     "foo",
+     "[header&header-1 =]");
+
+  // Check if 3+ ='s work
+  MT("setextH1",
+     "foo",
+     "[header&header-1 ===]");
+
+  // Check if single underlining - works
+  MT("setextH2",
+     "foo",
+     "[header&header-2 -]");
+
+  // Check if 3+ -'s work
+  MT("setextH2",
+     "foo",
+     "[header&header-2 ---]");
+
+  // Single-line blockquote with trailing space
+  MT("blockquoteSpace",
+     "[quote&quote-1 > foo]");
+
+  // Single-line blockquote
+  MT("blockquoteNoSpace",
+     "[quote&quote-1 >foo]");
+
+  // No blank line before blockquote
+  MT("blockquoteNoBlankLine",
+     "foo",
+     "[quote&quote-1 > bar]");
+
+  // Nested blockquote
+  MT("blockquoteSpace",
+     "[quote&quote-1 > foo]",
+     "[quote&quote-1 >][quote&quote-2 > foo]",
+     "[quote&quote-1 >][quote&quote-2 >][quote&quote-3 > foo]");
+
+  // Single-line blockquote followed by normal paragraph
+  MT("blockquoteThenParagraph",
+     "[quote&quote-1 >foo]",
+     "",
+     "bar");
+
+  // Multi-line blockquote (lazy mode)
+  MT("multiBlockquoteLazy",
+     "[quote&quote-1 >foo]",
+     "[quote&quote-1 bar]");
+
+  // Multi-line blockquote followed by normal paragraph (lazy mode)
+  MT("multiBlockquoteLazyThenParagraph",
+     "[quote&quote-1 >foo]",
+     "[quote&quote-1 bar]",
+     "",
+     "hello");
+
+  // Multi-line blockquote (non-lazy mode)
+  MT("multiBlockquote",
+     "[quote&quote-1 >foo]",
+     "[quote&quote-1 >bar]");
+
+  // Multi-line blockquote followed by normal paragraph (non-lazy mode)
+  MT("multiBlockquoteThenParagraph",
+     "[quote&quote-1 >foo]",
+     "[quote&quote-1 >bar]",
+     "",
+     "hello");
+
+  // Check list types
+
+  MT("listAsterisk",
+     "foo",
+     "bar",
+     "",
+     "[variable-2 * foo]",
+     "[variable-2 * bar]");
+
+  MT("listPlus",
+     "foo",
+     "bar",
+     "",
+     "[variable-2 + foo]",
+     "[variable-2 + bar]");
+
+  MT("listDash",
+     "foo",
+     "bar",
+     "",
+     "[variable-2 - foo]",
+     "[variable-2 - bar]");
+
+  MT("listNumber",
+     "foo",
+     "bar",
+     "",
+     "[variable-2 1. foo]",
+     "[variable-2 2. bar]");
+
+  // Lists require a preceding blank line (per Dingus)
+  MT("listBogus",
+     "foo",
+     "1. bar",
+     "2. hello");
+
+  // List after header
+  MT("listAfterHeader",
+     "[header&header-1 # foo]",
+     "[variable-2 - bar]");
+
+  // Formatting in lists (*)
+  MT("listAsteriskFormatting",
+     "[variable-2 * ][variable-2&em *foo*][variable-2  bar]",
+     "[variable-2 * ][variable-2&strong **foo**][variable-2  bar]",
+     "[variable-2 * ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2  bar]",
+     "[variable-2 * ][variable-2&comment `foo`][variable-2  bar]");
+
+  // Formatting in lists (+)
+  MT("listPlusFormatting",
+     "[variable-2 + ][variable-2&em *foo*][variable-2  bar]",
+     "[variable-2 + ][variable-2&strong **foo**][variable-2  bar]",
+     "[variable-2 + ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2  bar]",
+     "[variable-2 + ][variable-2&comment `foo`][variable-2  bar]");
+
+  // Formatting in lists (-)
+  MT("listDashFormatting",
+     "[variable-2 - ][variable-2&em *foo*][variable-2  bar]",
+     "[variable-2 - ][variable-2&strong **foo**][variable-2  bar]",
+     "[variable-2 - ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2  bar]",
+     "[variable-2 - ][variable-2&comment `foo`][variable-2  bar]");
+
+  // Formatting in lists (1.)
+  MT("listNumberFormatting",
+     "[variable-2 1. ][variable-2&em *foo*][variable-2  bar]",
+     "[variable-2 2. ][variable-2&strong **foo**][variable-2  bar]",
+     "[variable-2 3. ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2  bar]",
+     "[variable-2 4. ][variable-2&comment `foo`][variable-2  bar]");
+
+  // Paragraph lists
+  MT("listParagraph",
+     "[variable-2 * foo]",
+     "",
+     "[variable-2 * bar]");
+
+  // Multi-paragraph lists
+  //
+  // 4 spaces
+  MT("listMultiParagraph",
+     "[variable-2 * foo]",
+     "",
+     "[variable-2 * bar]",
+     "",
+     "    [variable-2 hello]");
+
+  // 4 spaces, extra blank lines (should still be list, per Dingus)
+  MT("listMultiParagraphExtra",
+     "[variable-2 * foo]",
+     "",
+     "[variable-2 * bar]",
+     "",
+     "",
+     "    [variable-2 hello]");
+
+  // 4 spaces, plus 1 space (should still be list, per Dingus)
+  MT("listMultiParagraphExtraSpace",
+     "[variable-2 * foo]",
+     "",
+     "[variable-2 * bar]",
+     "",
+     "     [variable-2 hello]",
+     "",
+     "    [variable-2 world]");
+
+  // 1 tab
+  MT("listTab",
+     "[variable-2 * foo]",
+     "",
+     "[variable-2 * bar]",
+     "",
+     "\t[variable-2 hello]");
+
+  // No indent
+  MT("listNoIndent",
+     "[variable-2 * foo]",
+     "",
+     "[variable-2 * bar]",
+     "",
+     "hello");
+
+  // Blockquote
+  MT("blockquote",
+     "[variable-2 * foo]",
+     "",
+     "[variable-2 * bar]",
+     "",
+     "    [variable-2&quote&quote-1 > hello]");
+
+  // Code block
+  MT("blockquoteCode",
+     "[variable-2 * foo]",
+     "",
+     "[variable-2 * bar]",
+     "",
+     "        [comment > hello]",
+     "",
+     "    [variable-2 world]");
+
+  // Code block followed by text
+  MT("blockquoteCodeText",
+     "[variable-2 * foo]",
+     "",
+     "    [variable-2 bar]",
+     "",
+     "        [comment hello]",
+     "",
+     "    [variable-2 world]");
+
+  // Nested list
+
+  MT("listAsteriskNested",
+     "[variable-2 * foo]",
+     "",
+     "    [variable-3 * bar]");
+
+  MT("listPlusNested",
+     "[variable-2 + foo]",
+     "",
+     "    [variable-3 + bar]");
+
+  MT("listDashNested",
+     "[variable-2 - foo]",
+     "",
+     "    [variable-3 - bar]");
+
+  MT("listNumberNested",
+     "[variable-2 1. foo]",
+     "",
+     "    [variable-3 2. bar]");
+
+  MT("listMixed",
+     "[variable-2 * foo]",
+     "",
+     "    [variable-3 + bar]",
+     "",
+     "        [keyword - hello]",
+     "",
+     "            [variable-2 1. world]");
+
+  MT("listBlockquote",
+     "[variable-2 * foo]",
+     "",
+     "    [variable-3 + bar]",
+     "",
+     "        [quote&quote-1&variable-3 > hello]");
+
+  MT("listCode",
+     "[variable-2 * foo]",
+     "",
+     "    [variable-3 + bar]",
+     "",
+     "            [comment hello]");
+
+  // Code with internal indentation
+  MT("listCodeIndentation",
+     "[variable-2 * foo]",
+     "",
+     "        [comment bar]",
+     "            [comment hello]",
+     "                [comment world]",
+     "        [comment foo]",
+     "    [variable-2 bar]");
+
+  // List nesting edge cases
+  MT("listNested",
+    "[variable-2 * foo]",
+    "",
+    "    [variable-3 * bar]",
+    "",
+    "       [variable-2 hello]"
+  );
+  MT("listNested",
+    "[variable-2 * foo]",
+    "",
+    "    [variable-3 * bar]",
+    "",
+    "      [variable-3 * foo]"
+  );
+
+  // Code followed by text
+  MT("listCodeText",
+     "[variable-2 * foo]",
+     "",
+     "        [comment bar]",
+     "",
+     "hello");
+
+  // Following tests directly from official Markdown documentation
+  // http://daringfireball.net/projects/markdown/syntax#hr
+
+  MT("hrSpace",
+     "[hr * * *]");
+
+  MT("hr",
+     "[hr ***]");
+
+  MT("hrLong",
+     "[hr *****]");
+
+  MT("hrSpaceDash",
+     "[hr - - -]");
+
+  MT("hrDashLong",
+     "[hr ---------------------------------------]");
+
+  // Inline link with title
+  MT("linkTitle",
+     "[link [[foo]]][string (http://example.com/ \"bar\")] hello");
+
+  // Inline link without title
+  MT("linkNoTitle",
+     "[link [[foo]]][string (http://example.com/)] bar");
+
+  // Inline link with image
+  MT("linkImage",
+     "[link [[][tag ![[foo]]][string (http://example.com/)][link ]]][string (http://example.com/)] bar");
+
+  // Inline link with Em
+  MT("linkEm",
+     "[link [[][link&em *foo*][link ]]][string (http://example.com/)] bar");
+
+  // Inline link with Strong
+  MT("linkStrong",
+     "[link [[][link&strong **foo**][link ]]][string (http://example.com/)] bar");
+
+  // Inline link with EmStrong
+  MT("linkEmStrong",
+     "[link [[][link&strong **][link&em&strong *foo**][link&em *][link ]]][string (http://example.com/)] bar");
+
+  // Image with title
+  MT("imageTitle",
+     "[tag ![[foo]]][string (http://example.com/ \"bar\")] hello");
+
+  // Image without title
+  MT("imageNoTitle",
+     "[tag ![[foo]]][string (http://example.com/)] bar");
+
+  // Image with asterisks
+  MT("imageAsterisks",
+     "[tag ![[*foo*]]][string (http://example.com/)] bar");
+
+  // Not a link. Should be normal text due to square brackets being used
+  // regularly in text, especially in quoted material, and no space is allowed
+  // between square brackets and parentheses (per Dingus).
+  MT("notALink",
+     "[[foo]] (bar)");
+
+  // Reference-style links
+  MT("linkReference",
+     "[link [[foo]]][string [[bar]]] hello");
+
+  // Reference-style links with Em
+  MT("linkReferenceEm",
+     "[link [[][link&em *foo*][link ]]][string [[bar]]] hello");
+
+  // Reference-style links with Strong
+  MT("linkReferenceStrong",
+     "[link [[][link&strong **foo**][link ]]][string [[bar]]] hello");
+
+  // Reference-style links with EmStrong
+  MT("linkReferenceEmStrong",
+     "[link [[][link&strong **][link&em&strong *foo**][link&em *][link ]]][string [[bar]]] hello");
+
+  // Reference-style links with optional space separator (per docuentation)
+  // "You can optionally use a space to separate the sets of brackets"
+  MT("linkReferenceSpace",
+     "[link [[foo]]] [string [[bar]]] hello");
+
+  // Should only allow a single space ("...use *a* space...")
+  MT("linkReferenceDoubleSpace",
+     "[[foo]]  [[bar]] hello");
+
+  // Reference-style links with implicit link name
+  MT("linkImplicit",
+     "[link [[foo]]][string [[]]] hello");
+
+  // @todo It would be nice if, at some point, the document was actually
+  // checked to see if the referenced link exists
+
+  // Link label, for reference-style links (taken from documentation)
+
+  MT("labelNoTitle",
+     "[link [[foo]]:] [string http://example.com/]");
+
+  MT("labelIndented",
+     "   [link [[foo]]:] [string http://example.com/]");
+
+  MT("labelSpaceTitle",
+     "[link [[foo bar]]:] [string http://example.com/ \"hello\"]");
+
+  MT("labelDoubleTitle",
+     "[link [[foo bar]]:] [string http://example.com/ \"hello\"] \"world\"");
+
+  MT("labelTitleDoubleQuotes",
+     "[link [[foo]]:] [string http://example.com/  \"bar\"]");
+
+  MT("labelTitleSingleQuotes",
+     "[link [[foo]]:] [string http://example.com/  'bar']");
+
+  MT("labelTitleParenthese",
+     "[link [[foo]]:] [string http://example.com/  (bar)]");
+
+  MT("labelTitleInvalid",
+     "[link [[foo]]:] [string http://example.com/] bar");
+
+  MT("labelLinkAngleBrackets",
+     "[link [[foo]]:] [string <http://example.com/>  \"bar\"]");
+
+  MT("labelTitleNextDoubleQuotes",
+     "[link [[foo]]:] [string http://example.com/]",
+     "[string \"bar\"] hello");
+
+  MT("labelTitleNextSingleQuotes",
+     "[link [[foo]]:] [string http://example.com/]",
+     "[string 'bar'] hello");
+
+  MT("labelTitleNextParenthese",
+     "[link [[foo]]:] [string http://example.com/]",
+     "[string (bar)] hello");
+
+  MT("labelTitleNextMixed",
+     "[link [[foo]]:] [string http://example.com/]",
+     "(bar\" hello");
+
+  MT("linkWeb",
+     "[link <http://example.com/>] foo");
+
+  MT("linkWebDouble",
+     "[link <http://example.com/>] foo [link <http://example.com/>]");
+
+  MT("linkEmail",
+     "[link <user at example.com>] foo");
+
+  MT("linkEmailDouble",
+     "[link <user at example.com>] foo [link <user at example.com>]");
+
+  MT("emAsterisk",
+     "[em *foo*] bar");
+
+  MT("emUnderscore",
+     "[em _foo_] bar");
+
+  MT("emInWordAsterisk",
+     "foo[em *bar*]hello");
+
+  MT("emInWordUnderscore",
+     "foo[em _bar_]hello");
+
+  // Per documentation: "...surround an * or _ with spaces, it’ll be
+  // treated as a literal asterisk or underscore."
+
+  MT("emEscapedBySpaceIn",
+     "foo [em _bar _ hello_] world");
+
+  MT("emEscapedBySpaceOut",
+     "foo _ bar[em _hello_]world");
+
+  MT("emEscapedByNewline",
+     "foo",
+     "_ bar[em _hello_]world");
+
+  // Unclosed emphasis characters
+  // Instead of simply marking as EM / STRONG, it would be nice to have an
+  // incomplete flag for EM and STRONG, that is styled slightly different.
+  MT("emIncompleteAsterisk",
+     "foo [em *bar]");
+
+  MT("emIncompleteUnderscore",
+     "foo [em _bar]");
+
+  MT("strongAsterisk",
+     "[strong **foo**] bar");
+
+  MT("strongUnderscore",
+     "[strong __foo__] bar");
+
+  MT("emStrongAsterisk",
+     "[em *foo][em&strong **bar*][strong hello**] world");
+
+  MT("emStrongUnderscore",
+     "[em _foo][em&strong __bar_][strong hello__] world");
+
+  // "...same character must be used to open and close an emphasis span.""
+  MT("emStrongMixed",
+     "[em _foo][em&strong **bar*hello__ world]");
+
+  MT("emStrongMixed",
+     "[em *foo][em&strong __bar_hello** world]");
+
+  // These characters should be escaped:
+  // \   backslash
+  // `   backtick
+  // *   asterisk
+  // _   underscore
+  // {}  curly braces
+  // []  square brackets
+  // ()  parentheses
+  // #   hash mark
+  // +   plus sign
+  // -   minus sign (hyphen)
+  // .   dot
+  // !   exclamation mark
+
+  MT("escapeBacktick",
+     "foo \\`bar\\`");
+
+  MT("doubleEscapeBacktick",
+     "foo \\\\[comment `bar\\\\`]");
+
+  MT("escapeAsterisk",
+     "foo \\*bar\\*");
+
+  MT("doubleEscapeAsterisk",
+     "foo \\\\[em *bar\\\\*]");
+
+  MT("escapeUnderscore",
+     "foo \\_bar\\_");
+
+  MT("doubleEscapeUnderscore",
+     "foo \\\\[em _bar\\\\_]");
+
+  MT("escapeHash",
+     "\\# foo");
+
+  MT("doubleEscapeHash",
+     "\\\\# foo");
+
+  MT("escapeNewline",
+     "\\",
+     "[em *foo*]");
+
+
+  // Tests to make sure GFM-specific things aren't getting through
+
+  MT("taskList",
+     "[variable-2 * [ ]] bar]");
+
+  MT("fencedCodeBlocks",
+     "[comment ```]",
+     "foo",
+     "[comment ```]");
+})();
diff --git a/app/gui/html/vendor/codemirror/mode/meta.js b/app/gui/html/vendor/codemirror/mode/meta.js
new file mode 100644
index 0000000..142d959
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/meta.js
@@ -0,0 +1,106 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+CodeMirror.modeInfo = [
+  {name: 'APL', mime: 'text/apl', mode: 'apl'},
+  {name: 'Asterisk', mime: 'text/x-asterisk', mode: 'asterisk'},
+  {name: 'C', mime: 'text/x-csrc', mode: 'clike'},
+  {name: 'C++', mime: 'text/x-c++src', mode: 'clike'},
+  {name: 'Cobol', mime: 'text/x-cobol', mode: 'cobol'},
+  {name: 'Java', mime: 'text/x-java', mode: 'clike'},
+  {name: 'C#', mime: 'text/x-csharp', mode: 'clike'},
+  {name: 'Scala', mime: 'text/x-scala', mode: 'clike'},
+  {name: 'Clojure', mime: 'text/x-clojure', mode: 'clojure'},
+  {name: 'CoffeeScript', mime: 'text/x-coffeescript', mode: 'coffeescript'},
+  {name: 'Common Lisp', mime: 'text/x-common-lisp', mode: 'commonlisp'},
+  {name: 'CSS', mime: 'text/css', mode: 'css'},
+  {name: 'D', mime: 'text/x-d', mode: 'd'},
+  {name: 'diff', mime: 'text/x-diff', mode: 'diff'},
+  {name: 'DTD', mime: 'application/xml-dtd', mode: 'dtd'},
+  {name: 'ECL', mime: 'text/x-ecl', mode: 'ecl'},
+  {name: 'Eiffel', mime: 'text/x-eiffel', mode: 'eiffel'},
+  {name: 'Erlang', mime: 'text/x-erlang', mode: 'erlang'},
+  {name: 'Fortran', mime: 'text/x-fortran', mode: 'fortran'},
+  {name: 'F#', mime: 'text/x-fsharp', mode: 'mllike'},
+  {name: 'Gas', mime: 'text/x-gas', mode: 'gas'},
+  {name: 'Gherkin', mime: 'text/x-feature', mode: 'gherkin'},
+  {name: 'GitHub Flavored Markdown', mime: 'text/x-gfm', mode: 'gfm'},
+  {name: 'Go', mime: 'text/x-go', mode: 'go'},
+  {name: 'Groovy', mime: 'text/x-groovy', mode: 'groovy'},
+  {name: 'HAML', mime: 'text/x-haml', mode: 'haml'},
+  {name: 'Haskell', mime: 'text/x-haskell', mode: 'haskell'},
+  {name: 'Haxe', mime: 'text/x-haxe', mode: 'haxe'},
+  {name: 'ASP.NET', mime: 'application/x-aspx', mode: 'htmlembedded'},
+  {name: 'Embedded Javascript', mime: 'application/x-ejs', mode: 'htmlembedded'},
+  {name: 'JavaServer Pages', mime: 'application/x-jsp', mode: 'htmlembedded'},
+  {name: 'HTML', mime: 'text/html', mode: 'htmlmixed'},
+  {name: 'HTTP', mime: 'message/http', mode: 'http'},
+  {name: 'Jade', mime: 'text/x-jade', mode: 'jade'},
+  {name: 'JavaScript', mime: 'text/javascript', mode: 'javascript'},
+  {name: 'JSON', mime: 'application/x-json', mode: 'javascript'},
+  {name: 'JSON', mime: 'application/json', mode: 'javascript'},
+  {name: 'JSON-LD', mime: 'application/ld+json', mode: 'javascript'},
+  {name: 'TypeScript', mime: 'application/typescript', mode: 'javascript'},
+  {name: 'Jinja2', mime: null, mode: 'jinja2'},
+  {name: 'Julia', mime: 'text/x-julia', mode: 'julia'},
+  {name: 'LESS', mime: 'text/x-less', mode: 'css'},
+  {name: 'LiveScript', mime: 'text/x-livescript', mode: 'livescript'},
+  {name: 'Lua', mime: 'text/x-lua', mode: 'lua'},
+  {name: 'Markdown (GitHub-flavour)', mime: 'text/x-markdown', mode: 'markdown'},
+  {name: 'mIRC', mime: 'text/mirc', mode: 'mirc'},
+  {name: 'Nginx', mime: 'text/x-nginx-conf', mode: 'nginx'},
+  {name: 'NTriples', mime: 'text/n-triples', mode: 'ntriples'},
+  {name: 'OCaml', mime: 'text/x-ocaml', mode: 'mllike'},
+  {name: 'Octave', mime: 'text/x-octave', mode: 'octave'},
+  {name: 'Pascal', mime: 'text/x-pascal', mode: 'pascal'},
+  {name: 'PEG.js', mime: null, mode: 'pegjs'},
+  {name: 'Perl', mime: 'text/x-perl', mode: 'perl'},
+  {name: 'PHP', mime: 'text/x-php', mode: 'php'},
+  {name: 'PHP(HTML)', mime: 'application/x-httpd-php', mode: 'php'},
+  {name: 'Pig', mime: 'text/x-pig', mode: 'pig'},
+  {name: 'Plain Text', mime: 'text/plain', mode: 'null'},
+  {name: 'Properties files', mime: 'text/x-properties', mode: 'properties'},
+  {name: 'Python', mime: 'text/x-python', mode: 'python'},
+  {name: 'Puppet', mime: 'text/x-puppet', mode: 'puppet'},
+  {name: 'Cython', mime: 'text/x-cython', mode: 'python'},
+  {name: 'R', mime: 'text/x-rsrc', mode: 'r'},
+  {name: 'reStructuredText', mime: 'text/x-rst', mode: 'rst'},
+  {name: 'Ruby', mime: 'text/x-ruby', mode: 'ruby'},
+  {name: 'Rust', mime: 'text/x-rustsrc', mode: 'rust'},
+  {name: 'Sass', mime: 'text/x-sass', mode: 'sass'},
+  {name: 'Scheme', mime: 'text/x-scheme', mode: 'scheme'},
+  {name: 'SCSS', mime: 'text/x-scss', mode: 'css'},
+  {name: 'Shell', mime: 'text/x-sh', mode: 'shell'},
+  {name: 'Sieve', mime: 'application/sieve', mode: 'sieve'},
+  {name: 'Smalltalk', mime: 'text/x-stsrc', mode: 'smalltalk'},
+  {name: 'Smarty', mime: 'text/x-smarty', mode: 'smarty'},
+  {name: 'SmartyMixed', mime: 'text/x-smarty', mode: 'smartymixed'},
+  {name: 'Solr', mime: 'text/x-solr', mode: 'solr'},
+  {name: 'SPARQL', mime: 'application/x-sparql-query', mode: 'sparql'},
+  {name: 'SQL', mime: 'text/x-sql', mode: 'sql'},
+  {name: 'MariaDB', mime: 'text/x-mariadb', mode: 'sql'},
+  {name: 'sTeX', mime: 'text/x-stex', mode: 'stex'},
+  {name: 'LaTeX', mime: 'text/x-latex', mode: 'stex'},
+  {name: 'Tcl', mime: 'text/x-tcl', mode: 'tcl'},
+  {name: 'TiddlyWiki ', mime: 'text/x-tiddlywiki', mode: 'tiddlywiki'},
+  {name: 'Tiki wiki', mime: 'text/tiki', mode: 'tiki'},
+  {name: 'TOML', mime: 'text/x-toml', mode: 'toml'},
+  {name: 'Turtle', mime: 'text/turtle', mode: 'turtle'},
+  {name: 'VB.NET', mime: 'text/x-vb', mode: 'vb'},
+  {name: 'VBScript', mime: 'text/vbscript', mode: 'vbscript'},
+  {name: 'Velocity', mime: 'text/velocity', mode: 'velocity'},
+  {name: 'Verilog', mime: 'text/x-verilog', mode: 'verilog'},
+  {name: 'XML', mime: 'application/xml', mode: 'xml'},
+  {name: 'XQuery', mime: 'application/xquery', mode: 'xquery'},
+  {name: 'YAML', mime: 'text/x-yaml', mode: 'yaml'},
+  {name: 'Z80', mime: 'text/x-z80', mode: 'z80'}
+];
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/mirc/index.html b/app/gui/html/vendor/codemirror/mode/mirc/index.html
new file mode 100644
index 0000000..c346f1c
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/mirc/index.html
@@ -0,0 +1,160 @@
+<!doctype html>
+
+<title>CodeMirror: mIRC mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link rel="stylesheet" href="../../theme/twilight.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="mirc.js"></script>
+<style>.CodeMirror {border: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">mIRC</a>
+  </ul>
+</div>
+
+<article>
+<h2>mIRC mode</h2>
+<form><textarea id="code" name="code">
+;AKA Nick Tracker by Ford_Lawnmower irc.GeekShed.net #Script-Help
+;*****************************************************************************;
+;**Start Setup
+;Change JoinDisplay, below, for On Join AKA Display. On = 1 - Off = 0
+alias -l JoinDisplay { return 1 }
+;Change MaxNicks, below, to the number of nicknames you want to store for each hostmask. I wouldn't go over 400 with this ;/
+alias -l MaxNicks { return 20 }
+;Change AKALogo, below, To the text you want displayed before each AKA result.
+alias -l AKALogo { return 06 05A06K07A 06 }
+;**End Setup
+;*****************************************************************************;
+On *:Join:#: {
+  if ($nick == $me) { .timer 1 1 ialupdateCheck $chan }
+  NickNamesAdd $nick $+($network,$wildsite)
+  if ($JoinDisplay) { .timerNickNames $+ $nick 1 2 NickNames.display $nick $chan $network $wildsite }
+}
+on *:Nick: { NickNamesAdd $newnick $+($network,$wildsite) $nick }
+alias -l NickNames.display {
+  if ($gettok($hget(NickNames,$+($3,$4)),0,126) > 1) {
+    echo -g $2 $AKALogo $+(09,$1) $AKALogo 07 $mid($replace($hget(NickNames,$+($3,$4)),$chr(126),$chr(44)),2,-1)
+  }
+}
+alias -l NickNamesAdd {
+  if ($hget(NickNames,$2)) {
+    if (!$regex($hget(NickNames,$2),/~\Q $+ $replacecs($1,\E,\E\\E\Q) $+ \E~/i)) {
+      if ($gettok($hget(NickNames,$2),0,126) <= $MaxNicks) {
+        hadd NickNames $2 $+($hget(NickNames,$2),$1,~)
+      }
+      else {
+        hadd NickNames $2 $+($mid($hget(NickNames,$2),$pos($hget(NickNames,$2),~,2)),$1,~)
+      }
+    }
+  }
+  else {
+    hadd -m NickNames $2 $+(~,$1,~,$iif($3,$+($3,~)))
+  }
+}
+alias -l Fix.All.MindUser {
+  var %Fix.Count = $hfind(NickNames,/[^~]+[0-9]{4}~/,0,r).data
+  while (%Fix.Count) {
+    if ($Fix.MindUser($hget(NickNames,$hfind(NickNames,/[^~]+[0-9]{4}~/,%Fix.Count,r).data))) {
+      echo -ag Record %Fix.Count - $v1 - Was Cleaned
+      hadd NickNames $hfind(NickNames,/[^~]+[0-9]{4}~/,%Fix.Count,r).data $v1
+    }
+    dec %Fix.Count
+  }
+}
+alias -l Fix.MindUser { return $regsubex($1,/[^~]+[0-9]{4}~/g,$null) }
+menu nicklist,query {
+  -
+  .AKA
+  ..Check $$1: {
+    if ($gettok($hget(NickNames,$+($network,$address($1,2))),0,126) > 1) {
+      NickNames.display $1 $active $network $address($1,2)
+    }
+    else { echo -ag $AKALogo $+(09,$1) 07has not been known by any other nicknames while I have been watching. }
+  }
+  ..Cleanup $$1:hadd NickNames $+($network,$address($1,2)) $fix.minduser($hget(NickNames,$+($network,$address($1,2))))
+  ..Clear $$1:hadd NickNames $+($network,$address($1,2)) $+(~,$1,~)
+  ..AKA Search Dialog:dialog $iif($dialog(AKA_Search),-v,-m) AKA_Search AKA_Search
+  -
+}
+menu status,channel {
+  -
+  .AKA
+  ..AKA Search Dialog:dialog $iif($dialog(AKA_Search),-v,-m) AKA_Search AKA_Search
+  ..Clean All Records:Fix.All.Minduser
+  -
+}
+dialog AKA_Search {
+  title "AKA Search Engine"
+  size -1 -1 206 221
+  option dbu
+  edit "", 1, 8 5 149 10, autohs
+  button "Search", 2, 163 4 32 12
+  radio "Search HostMask", 4, 61 22 55 10
+  radio "Search Nicknames", 5, 123 22 56 10
+  list 6, 8 38 190 169, sort extsel vsbar
+  button "Check Selected", 7, 67 206 40 12
+  button "Close", 8, 160 206 38 12, cancel
+  box "Search Type", 3, 11 17 183 18
+  button "Copy to Clipboard", 9, 111 206 46 12
+}
+On *:Dialog:Aka_Search:init:*: { did -c $dname 5 }
+On *:Dialog:Aka_Search:Sclick:2,7,9: {
+  if ($did == 2) && ($did($dname,1)) {
+    did -r $dname 6
+    var %search $+(*,$v1,*), %type $iif($did($dname,5).state,data,item), %matches = $hfind(NickNames,%search,0,w). [ $+ [ %type ] ]
+    while (%matches) {
+      did -a $dname 6 $hfind(NickNames,%search,%matches,w). [ $+ [ %type ] ]
+      dec %matches
+    }
+    did -c $dname 6 1
+  }
+  elseif ($did == 7) && ($did($dname,6).seltext) { echo -ga $AKALogo 07 $mid($replace($hget(NickNames,$v1),$chr(126),$chr(44)),2,-1) }
+  elseif ($did == 9) && ($did($dname,6).seltext) { clipboard $mid($v1,$pos($v1,*,1)) }
+}
+On *:Start:{
+  if (!$hget(NickNames)) { hmake NickNames 10 }
+  if ($isfile(NickNames.hsh)) { hload  NickNames NickNames.hsh }
+}
+On *:Exit: { if ($hget(NickNames)) { hsave NickNames NickNames.hsh } }
+On *:Disconnect: { if ($hget(NickNames)) { hsave NickNames NickNames.hsh } }
+On *:Unload: { hfree NickNames }
+alias -l ialupdateCheck {
+  inc -z $+(%,ialupdateCheck,$network) $calc($nick($1,0) / 4)
+  ;If your ial is already being updated on join .who $1 out.
+  ;If you are using /names to update ial you will still need this line.
+  .who $1
+}
+Raw 352:*: {
+  if ($($+(%,ialupdateCheck,$network),2)) haltdef
+  NickNamesAdd $6 $+($network,$address($6,2))
+}
+Raw 315:*: {
+  if ($($+(%,ialupdateCheck,$network),2)) haltdef
+}
+
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        theme: "twilight",
+        lineNumbers: true,
+        matchBrackets: true,
+        indentUnit: 4,
+        mode: "text/mirc"
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/mirc</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/mirc/mirc.js b/app/gui/html/vendor/codemirror/mode/mirc/mirc.js
new file mode 100644
index 0000000..6b2a23a
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/mirc/mirc.js
@@ -0,0 +1,190 @@
+//mIRC mode by Ford_Lawnmower :: Based on Velocity mode by Steve O'Hara
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMIME("text/mirc", "mirc");
+CodeMirror.defineMode("mirc", function() {
+  function parseWords(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+  var specials = parseWords("$! $$ $& $? $+ $abook $abs $active $activecid " +
+                            "$activewid $address $addtok $agent $agentname $agentstat $agentver " +
+                            "$alias $and $anick $ansi2mirc $aop $appactive $appstate $asc $asctime " +
+                            "$asin $atan $avoice $away $awaymsg $awaytime $banmask $base $bfind " +
+                            "$binoff $biton $bnick $bvar $bytes $calc $cb $cd $ceil $chan $chanmodes " +
+                            "$chantypes $chat $chr $cid $clevel $click $cmdbox $cmdline $cnick $color " +
+                            "$com $comcall $comchan $comerr $compact $compress $comval $cos $count " +
+                            "$cr $crc $creq $crlf $ctime $ctimer $ctrlenter $date $day $daylight " +
+                            "$dbuh $dbuw $dccignore $dccport $dde $ddename $debug $decode $decompress " +
+                            "$deltok $devent $dialog $did $didreg $didtok $didwm $disk $dlevel $dll " +
+                            "$dllcall $dname $dns $duration $ebeeps $editbox $emailaddr $encode $error " +
+                            "$eval $event $exist $feof $ferr $fgetc $file $filename $filtered $finddir " +
+                            "$finddirn $findfile $findfilen $findtok $fline $floor $fopen $fread $fserve " +
+                            "$fulladdress $fulldate $fullname $fullscreen $get $getdir $getdot $gettok $gmt " +
+                            "$group $halted $hash $height $hfind $hget $highlight $hnick $hotline " +
+                            "$hotlinepos $ial $ialchan $ibl $idle $iel $ifmatch $ignore $iif $iil " +
+                            "$inelipse $ini $inmidi $inpaste $inpoly $input $inrect $inroundrect " +
+                            "$insong $instok $int $inwave $ip $isalias $isbit $isdde $isdir $isfile " +
+                            "$isid $islower $istok $isupper $keychar $keyrpt $keyval $knick $lactive " +
+                            "$lactivecid $lactivewid $left $len $level $lf $line $lines $link $lock " +
+                            "$lock $locked $log $logstamp $logstampfmt $longfn $longip $lower $ltimer " +
+                            "$maddress $mask $matchkey $matchtok $md5 $me $menu $menubar $menucontext " +
+                            "$menutype $mid $middir $mircdir $mircexe $mircini $mklogfn $mnick $mode " +
+                            "$modefirst $modelast $modespl $mouse $msfile $network $newnick $nick $nofile " +
+                            "$nopath $noqt $not $notags $notify $null $numeric $numok $oline $onpoly " +
+                            "$opnick $or $ord $os $passivedcc $pic $play $pnick $port $portable $portfree " +
+                            "$pos $prefix $prop $protect $puttok $qt $query $rand $r $rawmsg $read $readomo " +
+                            "$readn $regex $regml $regsub $regsubex $remove $remtok $replace $replacex " +
+                            "$reptok $result $rgb $right $round $scid $scon $script $scriptdir $scriptline " +
+                            "$sdir $send $server $serverip $sfile $sha1 $shortfn $show $signal $sin " +
+                            "$site $sline $snick $snicks $snotify $sock $sockbr $sockerr $sockname " +
+                            "$sorttok $sound $sqrt $ssl $sreq $sslready $status $strip $str $stripped " +
+                            "$syle $submenu $switchbar $tan $target $ticks $time $timer $timestamp " +
+                            "$timestampfmt $timezone $tip $titlebar $toolbar $treebar $trust $ulevel " +
+                            "$ulist $upper $uptime $url $usermode $v1 $v2 $var $vcmd $vcmdstat $vcmdver " +
+                            "$version $vnick $vol $wid $width $wildsite $wildtok $window $wrap $xor");
+  var keywords = parseWords("abook ajinvite alias aline ame amsg anick aop auser autojoin avoice " +
+                            "away background ban bcopy beep bread break breplace bset btrunc bunset bwrite " +
+                            "channel clear clearall cline clipboard close cnick color comclose comopen " +
+                            "comreg continue copy creq ctcpreply ctcps dcc dccserver dde ddeserver " +
+                            "debug dec describe dialog did didtok disable disconnect dlevel dline dll " +
+                            "dns dqwindow drawcopy drawdot drawfill drawline drawpic drawrect drawreplace " +
+                            "drawrot drawsave drawscroll drawtext ebeeps echo editbox emailaddr enable " +
+                            "events exit fclose filter findtext finger firewall flash flist flood flush " +
+                            "flushini font fopen fseek fsend fserve fullname fwrite ghide gload gmove " +
+                            "gopts goto gplay gpoint gqreq groups gshow gsize gstop gtalk gunload hadd " +
+                            "halt haltdef hdec hdel help hfree hinc hload hmake hop hsave ial ialclear " +
+                            "ialmark identd if ignore iline inc invite iuser join kick linesep links list " +
+                            "load loadbuf localinfo log mdi me menubar mkdir mnick mode msg nick noop notice " +
+                            "notify omsg onotice part partall pdcc perform play playctrl pop protect pvoice " +
+                            "qme qmsg query queryn quit raw reload remini remote remove rename renwin " +
+                            "reseterror resetidle return rlevel rline rmdir run ruser save savebuf saveini " +
+                            "say scid scon server set showmirc signam sline sockaccept sockclose socklist " +
+                            "socklisten sockmark sockopen sockpause sockread sockrename sockudp sockwrite " +
+                            "sound speak splay sreq strip switchbar timer timestamp titlebar tnick tokenize " +
+                            "toolbar topic tray treebar ulist unload unset unsetall updatenl url uwho " +
+                            "var vcadd vcmd vcrem vol while whois window winhelp write writeint if isalnum " +
+                            "isalpha isaop isavoice isban ischan ishop isignore isin isincs isletter islower " +
+                            "isnotify isnum ison isop isprotect isreg isupper isvoice iswm iswmcs " +
+                            "elseif else goto menu nicklist status title icon size option text edit " +
+                            "button check radio box scroll list combo link tab item");
+  var functions = parseWords("if elseif else and not or eq ne in ni for foreach while switch");
+  var isOperatorChar = /[+\-*&%=<>!?^\/\|]/;
+  function chain(stream, state, f) {
+    state.tokenize = f;
+    return f(stream, state);
+  }
+  function tokenBase(stream, state) {
+    var beforeParams = state.beforeParams;
+    state.beforeParams = false;
+    var ch = stream.next();
+    if (/[\[\]{}\(\),\.]/.test(ch)) {
+      if (ch == "(" && beforeParams) state.inParams = true;
+      else if (ch == ")") state.inParams = false;
+      return null;
+    }
+    else if (/\d/.test(ch)) {
+      stream.eatWhile(/[\w\.]/);
+      return "number";
+    }
+    else if (ch == "\\") {
+      stream.eat("\\");
+      stream.eat(/./);
+      return "number";
+    }
+    else if (ch == "/" && stream.eat("*")) {
+      return chain(stream, state, tokenComment);
+    }
+    else if (ch == ";" && stream.match(/ *\( *\(/)) {
+      return chain(stream, state, tokenUnparsed);
+    }
+    else if (ch == ";" && !state.inParams) {
+      stream.skipToEnd();
+      return "comment";
+    }
+    else if (ch == '"') {
+      stream.eat(/"/);
+      return "keyword";
+    }
+    else if (ch == "$") {
+      stream.eatWhile(/[$_a-z0-9A-Z\.:]/);
+      if (specials && specials.propertyIsEnumerable(stream.current().toLowerCase())) {
+        return "keyword";
+      }
+      else {
+        state.beforeParams = true;
+        return "builtin";
+      }
+    }
+    else if (ch == "%") {
+      stream.eatWhile(/[^,^\s^\(^\)]/);
+      state.beforeParams = true;
+      return "string";
+    }
+    else if (isOperatorChar.test(ch)) {
+      stream.eatWhile(isOperatorChar);
+      return "operator";
+    }
+    else {
+      stream.eatWhile(/[\w\$_{}]/);
+      var word = stream.current().toLowerCase();
+      if (keywords && keywords.propertyIsEnumerable(word))
+        return "keyword";
+      if (functions && functions.propertyIsEnumerable(word)) {
+        state.beforeParams = true;
+        return "keyword";
+      }
+      return null;
+    }
+  }
+  function tokenComment(stream, state) {
+    var maybeEnd = false, ch;
+    while (ch = stream.next()) {
+      if (ch == "/" && maybeEnd) {
+        state.tokenize = tokenBase;
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return "comment";
+  }
+  function tokenUnparsed(stream, state) {
+    var maybeEnd = 0, ch;
+    while (ch = stream.next()) {
+      if (ch == ";" && maybeEnd == 2) {
+        state.tokenize = tokenBase;
+        break;
+      }
+      if (ch == ")")
+        maybeEnd++;
+      else if (ch != " ")
+        maybeEnd = 0;
+    }
+    return "meta";
+  }
+  return {
+    startState: function() {
+      return {
+        tokenize: tokenBase,
+        beforeParams: false,
+        inParams: false
+      };
+    },
+    token: function(stream, state) {
+      if (stream.eatSpace()) return null;
+      return state.tokenize(stream, state);
+    }
+  };
+});
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/mllike/index.html b/app/gui/html/vendor/codemirror/mode/mllike/index.html
new file mode 100644
index 0000000..67bfef8
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/mllike/index.html
@@ -0,0 +1,179 @@
+<!doctype html>
+
+<title>CodeMirror: ML-like mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel=stylesheet href=../../lib/codemirror.css>
+<script src=../../lib/codemirror.js></script>
+<script src=../../addon/edit/matchbrackets.js></script>
+<script src=mllike.js></script>
+<style type=text/css>
+  .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">ML-like</a>
+  </ul>
+</div>
+
+<article>
+<h2>OCaml mode</h2>
+
+
+<textarea id="ocamlCode">
+(* Summing a list of integers *)
+let rec sum xs =
+  match xs with
+    | []       -> 0
+    | x :: xs' -> x + sum xs'
+
+(* Quicksort *)
+let rec qsort = function
+   | [] -> []
+   | pivot :: rest ->
+       let is_less x = x < pivot in
+       let left, right = List.partition is_less rest in
+       qsort left @ [pivot] @ qsort right
+
+(* Fibonacci Sequence *)
+let rec fib_aux n a b =
+  match n with
+  | 0 -> a
+  | _ -> fib_aux (n - 1) (a + b) a
+let fib n = fib_aux n 0 1
+
+(* Birthday paradox *)
+let year_size = 365.
+
+let rec birthday_paradox prob people =
+    let prob' = (year_size -. float people) /. year_size *. prob  in
+    if prob' < 0.5 then
+        Printf.printf "answer = %d\n" (people+1)
+    else
+        birthday_paradox prob' (people+1) ;;
+
+birthday_paradox 1.0 1
+
+(* Church numerals *)
+let zero f x = x
+let succ n f x = f (n f x)
+let one = succ zero
+let two = succ (succ zero)
+let add n1 n2 f x = n1 f (n2 f x)
+let to_string n = n (fun k -> "S" ^ k) "0"
+let _ = to_string (add (succ two) two)
+
+(* Elementary functions *)
+let square x = x * x;;
+let rec fact x =
+  if x <= 1 then 1 else x * fact (x - 1);;
+
+(* Automatic memory management *)
+let l = 1 :: 2 :: 3 :: [];;
+[1; 2; 3];;
+5 :: l;;
+
+(* Polymorphism: sorting lists *)
+let rec sort = function
+  | [] -> []
+  | x :: l -> insert x (sort l)
+
+and insert elem = function
+  | [] -> [elem]
+  | x :: l ->
+      if elem < x then elem :: x :: l else x :: insert elem l;;
+
+(* Imperative features *)
+let add_polynom p1 p2 =
+  let n1 = Array.length p1
+  and n2 = Array.length p2 in
+  let result = Array.create (max n1 n2) 0 in
+  for i = 0 to n1 - 1 do result.(i) <- p1.(i) done;
+  for i = 0 to n2 - 1 do result.(i) <- result.(i) + p2.(i) done;
+  result;;
+add_polynom [| 1; 2 |] [| 1; 2; 3 |];;
+
+(* We may redefine fact using a reference cell and a for loop *)
+let fact n =
+  let result = ref 1 in
+  for i = 2 to n do
+    result := i * !result
+   done;
+   !result;;
+fact 5;;
+
+(* Triangle (graphics) *)
+let () =
+  ignore( Glut.init Sys.argv );
+  Glut.initDisplayMode ~double_buffer:true ();
+  ignore (Glut.createWindow ~title:"OpenGL Demo");
+  let angle t = 10. *. t *. t in
+  let render () =
+    GlClear.clear [ `color ];
+    GlMat.load_identity ();
+    GlMat.rotate ~angle: (angle (Sys.time ())) ~z:1. ();
+    GlDraw.begins `triangles;
+    List.iter GlDraw.vertex2 [-1., -1.; 0., 1.; 1., -1.];
+    GlDraw.ends ();
+    Glut.swapBuffers () in
+  GlMat.mode `modelview;
+  Glut.displayFunc ~cb:render;
+  Glut.idleFunc ~cb:(Some Glut.postRedisplay);
+  Glut.mainLoop ()
+
+(* A Hundred Lines of Caml - http://caml.inria.fr/about/taste.en.html *)
+(* OCaml page on Wikipedia - http://en.wikipedia.org/wiki/OCaml *)
+</textarea>
+
+<h2>F# mode</h2>
+<textarea id="fsharpCode">
+module CodeMirror.FSharp
+
+let rec fib = function
+    | 0 -> 0
+    | 1 -> 1
+    | n -> fib (n - 1) + fib (n - 2)
+
+type Point =
+    {
+        x : int
+        y : int
+    }
+
+type Color =
+    | Red
+    | Green
+    | Blue
+
+[0 .. 10]
+|> List.map ((+) 2)
+|> List.fold (fun x y -> x + y) 0
+|> printf "%i"
+</textarea>
+
+
+<script>
+  var ocamlEditor = CodeMirror.fromTextArea(document.getElementById('ocamlCode'), {
+    mode: 'text/x-ocaml',
+    lineNumbers: true,
+    matchBrackets: true
+  });
+
+  var fsharpEditor = CodeMirror.fromTextArea(document.getElementById('fsharpCode'), {
+    mode: 'text/x-fsharp',
+    lineNumbers: true,
+    matchBrackets: true
+  });
+</script>
+
+<p><strong>MIME types defined:</strong> <code>text/x-ocaml</code> (OCaml) and <code>text/x-fsharp</code> (F#).</p>
+</article>
diff --git a/app/gui/html/vendor/codemirror/mode/mllike/mllike.js b/app/gui/html/vendor/codemirror/mode/mllike/mllike.js
new file mode 100644
index 0000000..d4d59fc
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/mllike/mllike.js
@@ -0,0 +1,202 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode('mllike', function(_config, parserConfig) {
+  var words = {
+    'let': 'keyword',
+    'rec': 'keyword',
+    'in': 'keyword',
+    'of': 'keyword',
+    'and': 'keyword',
+    'if': 'keyword',
+    'then': 'keyword',
+    'else': 'keyword',
+    'for': 'keyword',
+    'to': 'keyword',
+    'while': 'keyword',
+    'do': 'keyword',
+    'done': 'keyword',
+    'fun': 'keyword',
+    'function': 'keyword',
+    'val': 'keyword',
+    'type': 'keyword',
+    'mutable': 'keyword',
+    'match': 'keyword',
+    'with': 'keyword',
+    'try': 'keyword',
+    'open': 'builtin',
+    'ignore': 'builtin',
+    'begin': 'keyword',
+    'end': 'keyword'
+  };
+
+  var extraWords = parserConfig.extraWords || {};
+  for (var prop in extraWords) {
+    if (extraWords.hasOwnProperty(prop)) {
+      words[prop] = parserConfig.extraWords[prop];
+    }
+  }
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+
+    if (ch === '"') {
+      state.tokenize = tokenString;
+      return state.tokenize(stream, state);
+    }
+    if (ch === '(') {
+      if (stream.eat('*')) {
+        state.commentLevel++;
+        state.tokenize = tokenComment;
+        return state.tokenize(stream, state);
+      }
+    }
+    if (ch === '~') {
+      stream.eatWhile(/\w/);
+      return 'variable-2';
+    }
+    if (ch === '`') {
+      stream.eatWhile(/\w/);
+      return 'quote';
+    }
+    if (ch === '/' && parserConfig.slashComments && stream.eat('/')) {
+      stream.skipToEnd();
+      return 'comment';
+    }
+    if (/\d/.test(ch)) {
+      stream.eatWhile(/[\d]/);
+      if (stream.eat('.')) {
+        stream.eatWhile(/[\d]/);
+      }
+      return 'number';
+    }
+    if ( /[+\-*&%=<>!?|]/.test(ch)) {
+      return 'operator';
+    }
+    stream.eatWhile(/\w/);
+    var cur = stream.current();
+    return words[cur] || 'variable';
+  }
+
+  function tokenString(stream, state) {
+    var next, end = false, escaped = false;
+    while ((next = stream.next()) != null) {
+      if (next === '"' && !escaped) {
+        end = true;
+        break;
+      }
+      escaped = !escaped && next === '\\';
+    }
+    if (end && !escaped) {
+      state.tokenize = tokenBase;
+    }
+    return 'string';
+  };
+
+  function tokenComment(stream, state) {
+    var prev, next;
+    while(state.commentLevel > 0 && (next = stream.next()) != null) {
+      if (prev === '(' && next === '*') state.commentLevel++;
+      if (prev === '*' && next === ')') state.commentLevel--;
+      prev = next;
+    }
+    if (state.commentLevel <= 0) {
+      state.tokenize = tokenBase;
+    }
+    return 'comment';
+  }
+
+  return {
+    startState: function() {return {tokenize: tokenBase, commentLevel: 0};},
+    token: function(stream, state) {
+      if (stream.eatSpace()) return null;
+      return state.tokenize(stream, state);
+    },
+
+    blockCommentStart: "(*",
+    blockCommentEnd: "*)",
+    lineComment: parserConfig.slashComments ? "//" : null
+  };
+});
+
+CodeMirror.defineMIME('text/x-ocaml', {
+  name: 'mllike',
+  extraWords: {
+    'succ': 'keyword',
+    'trace': 'builtin',
+    'exit': 'builtin',
+    'print_string': 'builtin',
+    'print_endline': 'builtin',
+    'true': 'atom',
+    'false': 'atom',
+    'raise': 'keyword'
+  }
+});
+
+CodeMirror.defineMIME('text/x-fsharp', {
+  name: 'mllike',
+  extraWords: {
+    'abstract': 'keyword',
+    'as': 'keyword',
+    'assert': 'keyword',
+    'base': 'keyword',
+    'class': 'keyword',
+    'default': 'keyword',
+    'delegate': 'keyword',
+    'downcast': 'keyword',
+    'downto': 'keyword',
+    'elif': 'keyword',
+    'exception': 'keyword',
+    'extern': 'keyword',
+    'finally': 'keyword',
+    'global': 'keyword',
+    'inherit': 'keyword',
+    'inline': 'keyword',
+    'interface': 'keyword',
+    'internal': 'keyword',
+    'lazy': 'keyword',
+    'let!': 'keyword',
+    'member' : 'keyword',
+    'module': 'keyword',
+    'namespace': 'keyword',
+    'new': 'keyword',
+    'null': 'keyword',
+    'override': 'keyword',
+    'private': 'keyword',
+    'public': 'keyword',
+    'return': 'keyword',
+    'return!': 'keyword',
+    'select': 'keyword',
+    'static': 'keyword',
+    'struct': 'keyword',
+    'upcast': 'keyword',
+    'use': 'keyword',
+    'use!': 'keyword',
+    'val': 'keyword',
+    'when': 'keyword',
+    'yield': 'keyword',
+    'yield!': 'keyword',
+
+    'List': 'builtin',
+    'Seq': 'builtin',
+    'Map': 'builtin',
+    'Set': 'builtin',
+    'int': 'builtin',
+    'string': 'builtin',
+    'raise': 'builtin',
+    'failwith': 'builtin',
+    'not': 'builtin',
+    'true': 'builtin',
+    'false': 'builtin'
+  },
+  slashComments: true
+});
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/nginx/index.html b/app/gui/html/vendor/codemirror/mode/nginx/index.html
new file mode 100644
index 0000000..16be1eb
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/nginx/index.html
@@ -0,0 +1,181 @@
+<!doctype html>
+
+<title>CodeMirror: NGINX mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="nginx.js"></script>
+<style>.CodeMirror {background: #f8f8f8;}</style>
+    <link rel="stylesheet" href="../../doc/docs.css">
+  </head>
+
+  <style>
+    body {
+      margin: 0em auto;
+    }
+
+    .CodeMirror, .CodeMirror-scroll {
+      height: 600px;
+    }
+  </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">NGINX</a>
+  </ul>
+</div>
+
+<article>
+<h2>NGINX mode</h2>
+<form><textarea id="code" name="code" style="height: 800px;">
+server {
+  listen 173.255.219.235:80;
+  server_name website.com.au;
+  rewrite / $scheme://www.$host$request_uri permanent; ## Forcibly prepend a www
+}
+
+server {
+  listen 173.255.219.235:443;
+  server_name website.com.au;
+  rewrite / $scheme://www.$host$request_uri permanent; ## Forcibly prepend a www
+}
+
+server {
+
+  listen      173.255.219.235:80;
+  server_name www.website.com.au;
+
+
+
+  root        /data/www;
+  index       index.html index.php;
+
+  location / {
+    index index.html index.php;     ## Allow a static html file to be shown first
+    try_files $uri $uri/ @handler;  ## If missing pass the URI to Magento's front handler
+    expires 30d;                    ## Assume all files are cachable
+  }
+
+  ## These locations would be hidden by .htaccess normally
+  location /app/                { deny all; }
+  location /includes/           { deny all; }
+  location /lib/                { deny all; }
+  location /media/downloadable/ { deny all; }
+  location /pkginfo/            { deny all; }
+  location /report/config.xml   { deny all; }
+  location /var/                { deny all; }
+
+  location /var/export/ { ## Allow admins only to view export folder
+    auth_basic           "Restricted"; ## Message shown in login window
+    auth_basic_user_file /rs/passwords/testfile; ## See /etc/nginx/htpassword
+    autoindex            on;
+  }
+
+  location  /. { ## Disable .htaccess and other hidden files
+    return 404;
+  }
+
+  location @handler { ## Magento uses a common front handler
+    rewrite / /index.php;
+  }
+
+  location ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
+    rewrite ^/(.*.php)/ /$1 last;
+  }
+
+  location ~ \.php$ {
+    if (!-e $request_filename) { rewrite / /index.php last; } ## Catch 404s that try_files miss
+
+    fastcgi_pass   127.0.0.1:9000;
+    fastcgi_index  index.php;
+    fastcgi_param PATH_INFO $fastcgi_script_name;
+    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
+    include        /rs/confs/nginx/fastcgi_params;
+  }
+
+}
+
+
+server {
+
+  listen              173.255.219.235:443;
+  server_name         website.com.au www.website.com.au;
+
+  root   /data/www;
+  index index.html index.php;
+
+  ssl                 on;
+  ssl_certificate     /rs/ssl/ssl.crt;
+  ssl_certificate_key /rs/ssl/ssl.key;
+
+  ssl_session_timeout  5m;
+
+  ssl_protocols  SSLv2 SSLv3 TLSv1;
+  ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
+  ssl_prefer_server_ciphers   on;
+
+
+
+  location / {
+    index index.html index.php; ## Allow a static html file to be shown first
+    try_files $uri $uri/ @handler; ## If missing pass the URI to Magento's front handler
+    expires 30d; ## Assume all files are cachable
+  }
+
+  ## These locations would be hidden by .htaccess normally
+  location /app/                { deny all; }
+  location /includes/           { deny all; }
+  location /lib/                { deny all; }
+  location /media/downloadable/ { deny all; }
+  location /pkginfo/            { deny all; }
+  location /report/config.xml   { deny all; }
+  location /var/                { deny all; }
+
+  location /var/export/ { ## Allow admins only to view export folder
+    auth_basic           "Restricted"; ## Message shown in login window
+    auth_basic_user_file htpasswd; ## See /etc/nginx/htpassword
+    autoindex            on;
+  }
+
+  location  /. { ## Disable .htaccess and other hidden files
+    return 404;
+  }
+
+  location @handler { ## Magento uses a common front handler
+    rewrite / /index.php;
+  }
+
+  location ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
+    rewrite ^/(.*.php)/ /$1 last;
+  }
+
+  location ~ .php$ { ## Execute PHP scripts
+    if (!-e $request_filename) { rewrite  /index.php last; } ## Catch 404s that try_files miss
+
+    fastcgi_pass 127.0.0.1:9000;
+    fastcgi_index  index.php;
+    fastcgi_param PATH_INFO $fastcgi_script_name;
+    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
+    include        /rs/confs/nginx/fastcgi_params;
+
+    fastcgi_param HTTPS on;
+  }
+
+}
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/nginx</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/nginx/nginx.js b/app/gui/html/vendor/codemirror/mode/nginx/nginx.js
new file mode 100644
index 0000000..4e17cdb
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/nginx/nginx.js
@@ -0,0 +1,175 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("nginx", function(config) {
+
+  function words(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+
+  var keywords = words(
+    /* ngxDirectiveControl */ "break return rewrite set" +
+    /* ngxDirective */ " accept_mutex accept_mutex_delay access_log add_after_body add_before_body add_header addition_types aio alias allow ancient_browser ancient_browser_value auth_basic auth_basic_user_file auth_http auth_http_header auth_http_timeout autoindex autoindex_exact_size autoindex_localtime charset charset_types client_body_buffer_size client_body_in_file_only client_body_in_single_buffer client_body_temp_path client_body_timeout client_header_buffer_size client_header_timeout client_max_body_size connection_pool_size create_full_put_path daemon dav_access dav_methods debug_connection debug_points default_type degradation degrade deny devpoll_changes devpoll_events directio directio_alignment empty_gif env epoll_events error_log eventport_events expires fastcgi_bind fastcgi_buffer_size fastcgi_buffers fastcgi_busy_buffers_size fastcgi_cache fastcgi_cache_key fastcgi_cache_methods fastcgi_cache_min_uses fastcgi_cache_path fastcgi_cache_use_stale fastcgi_cache_valid fastcgi_catch_stderr fastcgi_connect_timeout fastcgi_hide_header fastcgi_ignore_client_abort fastcgi_ignore_headers fastcgi_index fastcgi_intercept_errors fastcgi_max_temp_file_size fastcgi_next_upstream fastcgi_param fastcgi_pass_header fastcgi_pass_request_body fastcgi_pass_request_headers fastcgi_read_timeout fastcgi_send_lowat fastcgi_send_timeout fastcgi_split_path_info fastcgi_store fastcgi_store_access fastcgi_temp_file_write_size fastcgi_temp_path fastcgi_upstream_fail_timeout fastcgi_upstream_max_fails flv geoip_city geoip_country google_perftools_profiles gzip gzip_buffers gzip_comp_level gzip_disable gzip_hash gzip_http_version gzip_min_length gzip_no_buffer gzip_proxied gzip_static gzip_types gzip_vary gzip_window if_modified_since ignore_invalid_headers image_filter image_filter_buffer image_filter_jpeg_quality image_filter_transparency imap_auth imap_capabilities imap_client_buffer index ip_hash keepalive_requests keepalive_timeout kqueue_changes kqueue_events large_client_header_buffers limit_conn limit_conn_log_level limit_rate limit_rate_after limit_req limit_req_log_level limit_req_zone limit_zone lingering_time lingering_timeout lock_file log_format log_not_found log_subrequest map_hash_bucket_size map_hash_max_size master_process memcached_bind memcached_buffer_size memcached_connect_timeout memcached_next_upstream memcached_read_timeout memcached_send_timeout memcached_upstream_fail_timeout memcached_upstream_max_fails merge_slashes min_delete_depth modern_browser modern_browser_value msie_padding msie_refresh multi_accept open_file_cache open_file_cache_errors open_file_cache_events open_file_cache_min_uses open_file_cache_valid open_log_file_cache output_buffers override_charset perl perl_modules perl_require perl_set pid pop3_auth pop3_capabilities port_in_redirect postpone_gzipping postpone_output protocol proxy proxy_bind proxy_buffer proxy_buffer_size proxy_buffering proxy_buffers proxy_busy_buffers_size proxy_cache proxy_cache_key proxy_cache_methods proxy_cache_min_uses proxy_cache_path proxy_cache_use_stale proxy_cache_valid proxy_connect_timeout proxy_headers_hash_bucket_size proxy_headers_hash_max_size proxy_hide_header proxy_ignore_client_abort proxy_ignore_headers proxy_intercept_errors proxy_max_temp_file_size proxy_method proxy_next_upstream proxy_pass_error_message proxy_pass_header proxy_pass_request_body proxy_pass_request_headers proxy_read_timeout proxy_redirect proxy_send_lowat proxy_send_timeout proxy_set_body proxy_set_header proxy_ssl_session_reuse proxy_store proxy_store_access proxy_temp_file_write_size proxy_temp_path proxy_timeout proxy_upstream_fail_timeout proxy_upstream_max_fails random_index read_ahead real_ip_header recursive_error_pages request_pool_size reset_timedout_connection resolver resolver_timeout rewrite_log rtsig_overflow_events rtsig_overflow_test rtsig_overflow_threshold rtsig_signo satisfy secure_link_secret send_lowat send_timeout sendfile sendfile_max_chunk server_name_in_redirect server_names_hash_bucket_size server_names_hash_max_size server_tokens set_real_ip_from smtp_auth smtp_capabilities smtp_client_buffer smtp_greeting_delay so_keepalive source_charset ssi ssi_ignore_recycled_buffers ssi_min_file_chunk ssi_silent_errors ssi_types ssi_value_length ssl ssl_certificate ssl_certificate_key ssl_ciphers ssl_client_certificate ssl_crl ssl_dhparam ssl_engine ssl_prefer_server_ciphers ssl_protocols ssl_session_cache ssl_session_timeout ssl_verify_client ssl_verify_depth starttls stub_status sub_filter sub_filter_once sub_filter_types tcp_nodelay tcp_nopush thread_stack_size timeout timer_resolution types_hash_bucket_size types_hash_max_size underscores_in_headers uninitialized_variable_warn use user userid userid_domain userid_expires userid_mark userid_name userid_p3p userid_path userid_service valid_referers variables_hash_bucket_size variables_hash_max_size worker_connections worker_cpu_affinity worker_priority worker_processes worker_rlimit_core worker_rlimit_nofile worker_rlimit_sigpending worker_threads working_directory xclient xml_entities xslt_stylesheet xslt_typesdrew at li229-23"
+    );
+
+  var keywords_block = words(
+    /* ngxDirectiveBlock */ "http mail events server types location upstream charset_map limit_except if geo map"
+    );
+
+  var keywords_important = words(
+    /* ngxDirectiveImportant */ "include root server server_name listen internal proxy_pass memcached_pass fastcgi_pass try_files"
+    );
+
+  var indentUnit = config.indentUnit, type;
+  function ret(style, tp) {type = tp; return style;}
+
+  function tokenBase(stream, state) {
+
+
+    stream.eatWhile(/[\w\$_]/);
+
+    var cur = stream.current();
+
+
+    if (keywords.propertyIsEnumerable(cur)) {
+      return "keyword";
+    }
+    else if (keywords_block.propertyIsEnumerable(cur)) {
+      return "variable-2";
+    }
+    else if (keywords_important.propertyIsEnumerable(cur)) {
+      return "string-2";
+    }
+    /**/
+
+    var ch = stream.next();
+    if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("meta", stream.current());}
+    else if (ch == "/" && stream.eat("*")) {
+      state.tokenize = tokenCComment;
+      return tokenCComment(stream, state);
+    }
+    else if (ch == "<" && stream.eat("!")) {
+      state.tokenize = tokenSGMLComment;
+      return tokenSGMLComment(stream, state);
+    }
+    else if (ch == "=") ret(null, "compare");
+    else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
+    else if (ch == "\"" || ch == "'") {
+      state.tokenize = tokenString(ch);
+      return state.tokenize(stream, state);
+    }
+    else if (ch == "#") {
+      stream.skipToEnd();
+      return ret("comment", "comment");
+    }
+    else if (ch == "!") {
+      stream.match(/^\s*\w*/);
+      return ret("keyword", "important");
+    }
+    else if (/\d/.test(ch)) {
+      stream.eatWhile(/[\w.%]/);
+      return ret("number", "unit");
+    }
+    else if (/[,.+>*\/]/.test(ch)) {
+      return ret(null, "select-op");
+    }
+    else if (/[;{}:\[\]]/.test(ch)) {
+      return ret(null, ch);
+    }
+    else {
+      stream.eatWhile(/[\w\\\-]/);
+      return ret("variable", "variable");
+    }
+  }
+
+  function tokenCComment(stream, state) {
+    var maybeEnd = false, ch;
+    while ((ch = stream.next()) != null) {
+      if (maybeEnd && ch == "/") {
+        state.tokenize = tokenBase;
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return ret("comment", "comment");
+  }
+
+  function tokenSGMLComment(stream, state) {
+    var dashes = 0, ch;
+    while ((ch = stream.next()) != null) {
+      if (dashes >= 2 && ch == ">") {
+        state.tokenize = tokenBase;
+        break;
+      }
+      dashes = (ch == "-") ? dashes + 1 : 0;
+    }
+    return ret("comment", "comment");
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, ch;
+      while ((ch = stream.next()) != null) {
+        if (ch == quote && !escaped)
+          break;
+        escaped = !escaped && ch == "\\";
+      }
+      if (!escaped) state.tokenize = tokenBase;
+      return ret("string", "string");
+    };
+  }
+
+  return {
+    startState: function(base) {
+      return {tokenize: tokenBase,
+              baseIndent: base || 0,
+              stack: []};
+    },
+
+    token: function(stream, state) {
+      if (stream.eatSpace()) return null;
+      type = null;
+      var style = state.tokenize(stream, state);
+
+      var context = state.stack[state.stack.length-1];
+      if (type == "hash" && context == "rule") style = "atom";
+      else if (style == "variable") {
+        if (context == "rule") style = "number";
+        else if (!context || context == "@media{") style = "tag";
+      }
+
+      if (context == "rule" && /^[\{\};]$/.test(type))
+        state.stack.pop();
+      if (type == "{") {
+        if (context == "@media") state.stack[state.stack.length-1] = "@media{";
+        else state.stack.push("{");
+      }
+      else if (type == "}") state.stack.pop();
+      else if (type == "@media") state.stack.push("@media");
+      else if (context == "{" && type != "comment") state.stack.push("rule");
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      var n = state.stack.length;
+      if (/^\}/.test(textAfter))
+        n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
+      return state.baseIndent + n * indentUnit;
+    },
+
+    electricChars: "}"
+  };
+});
+
+CodeMirror.defineMIME("text/nginx", "text/x-nginx-conf");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/ntriples/index.html b/app/gui/html/vendor/codemirror/mode/ntriples/index.html
new file mode 100644
index 0000000..c8a6791
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/ntriples/index.html
@@ -0,0 +1,45 @@
+<!doctype html>
+
+<title>CodeMirror: NTriples mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="ntriples.js"></script>
+<style type="text/css">
+      .CodeMirror {
+        border: 1px solid #eee;
+      }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">NTriples</a>
+  </ul>
+</div>
+
+<article>
+<h2>NTriples mode</h2>
+<form>
+<textarea id="ntriples" name="ntriples">    
+<http://Sub1>     <http://pred1>     <http://obj> .
+<http://Sub2>     <http://pred2#an2> "literal 1" .
+<http://Sub3#an3> <http://pred3>     _:bnode3 .
+_:bnode4          <http://pred4>     "literal 2"@lang .
+_:bnode5          <http://pred5>     "literal 3"^^<http://type> .
+</textarea>
+</form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("ntriples"), {});
+    </script>
+    <p><strong>MIME types defined:</strong> <code>text/n-triples</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/ntriples/ntriples.js b/app/gui/html/vendor/codemirror/mode/ntriples/ntriples.js
new file mode 100644
index 0000000..cd5eb24
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/ntriples/ntriples.js
@@ -0,0 +1,183 @@
+/**********************************************************
+* This script provides syntax highlighting support for
+* the Ntriples format.
+* Ntriples format specification:
+*     http://www.w3.org/TR/rdf-testcases/#ntriples
+***********************************************************/
+
+/*
+    The following expression defines the defined ASF grammar transitions.
+
+    pre_subject ->
+        {
+        ( writing_subject_uri | writing_bnode_uri )
+            -> pre_predicate
+                -> writing_predicate_uri
+                    -> pre_object
+                        -> writing_object_uri | writing_object_bnode |
+                          (
+                            writing_object_literal
+                                -> writing_literal_lang | writing_literal_type
+                          )
+                            -> post_object
+                                -> BEGIN
+         } otherwise {
+             -> ERROR
+         }
+*/
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("ntriples", function() {
+
+  var Location = {
+    PRE_SUBJECT         : 0,
+    WRITING_SUB_URI     : 1,
+    WRITING_BNODE_URI   : 2,
+    PRE_PRED            : 3,
+    WRITING_PRED_URI    : 4,
+    PRE_OBJ             : 5,
+    WRITING_OBJ_URI     : 6,
+    WRITING_OBJ_BNODE   : 7,
+    WRITING_OBJ_LITERAL : 8,
+    WRITING_LIT_LANG    : 9,
+    WRITING_LIT_TYPE    : 10,
+    POST_OBJ            : 11,
+    ERROR               : 12
+  };
+  function transitState(currState, c) {
+    var currLocation = currState.location;
+    var ret;
+
+    // Opening.
+    if     (currLocation == Location.PRE_SUBJECT && c == '<') ret = Location.WRITING_SUB_URI;
+    else if(currLocation == Location.PRE_SUBJECT && c == '_') ret = Location.WRITING_BNODE_URI;
+    else if(currLocation == Location.PRE_PRED    && c == '<') ret = Location.WRITING_PRED_URI;
+    else if(currLocation == Location.PRE_OBJ     && c == '<') ret = Location.WRITING_OBJ_URI;
+    else if(currLocation == Location.PRE_OBJ     && c == '_') ret = Location.WRITING_OBJ_BNODE;
+    else if(currLocation == Location.PRE_OBJ     && c == '"') ret = Location.WRITING_OBJ_LITERAL;
+
+    // Closing.
+    else if(currLocation == Location.WRITING_SUB_URI     && c == '>') ret = Location.PRE_PRED;
+    else if(currLocation == Location.WRITING_BNODE_URI   && c == ' ') ret = Location.PRE_PRED;
+    else if(currLocation == Location.WRITING_PRED_URI    && c == '>') ret = Location.PRE_OBJ;
+    else if(currLocation == Location.WRITING_OBJ_URI     && c == '>') ret = Location.POST_OBJ;
+    else if(currLocation == Location.WRITING_OBJ_BNODE   && c == ' ') ret = Location.POST_OBJ;
+    else if(currLocation == Location.WRITING_OBJ_LITERAL && c == '"') ret = Location.POST_OBJ;
+    else if(currLocation == Location.WRITING_LIT_LANG && c == ' ') ret = Location.POST_OBJ;
+    else if(currLocation == Location.WRITING_LIT_TYPE && c == '>') ret = Location.POST_OBJ;
+
+    // Closing typed and language literal.
+    else if(currLocation == Location.WRITING_OBJ_LITERAL && c == '@') ret = Location.WRITING_LIT_LANG;
+    else if(currLocation == Location.WRITING_OBJ_LITERAL && c == '^') ret = Location.WRITING_LIT_TYPE;
+
+    // Spaces.
+    else if( c == ' ' &&
+             (
+               currLocation == Location.PRE_SUBJECT ||
+               currLocation == Location.PRE_PRED    ||
+               currLocation == Location.PRE_OBJ     ||
+               currLocation == Location.POST_OBJ
+             )
+           ) ret = currLocation;
+
+    // Reset.
+    else if(currLocation == Location.POST_OBJ && c == '.') ret = Location.PRE_SUBJECT;
+
+    // Error
+    else ret = Location.ERROR;
+
+    currState.location=ret;
+  }
+
+  return {
+    startState: function() {
+       return {
+           location : Location.PRE_SUBJECT,
+           uris     : [],
+           anchors  : [],
+           bnodes   : [],
+           langs    : [],
+           types    : []
+       };
+    },
+    token: function(stream, state) {
+      var ch = stream.next();
+      if(ch == '<') {
+         transitState(state, ch);
+         var parsedURI = '';
+         stream.eatWhile( function(c) { if( c != '#' && c != '>' ) { parsedURI += c; return true; } return false;} );
+         state.uris.push(parsedURI);
+         if( stream.match('#', false) ) return 'variable';
+         stream.next();
+         transitState(state, '>');
+         return 'variable';
+      }
+      if(ch == '#') {
+        var parsedAnchor = '';
+        stream.eatWhile(function(c) { if(c != '>' && c != ' ') { parsedAnchor+= c; return true; } return false;});
+        state.anchors.push(parsedAnchor);
+        return 'variable-2';
+      }
+      if(ch == '>') {
+          transitState(state, '>');
+          return 'variable';
+      }
+      if(ch == '_') {
+          transitState(state, ch);
+          var parsedBNode = '';
+          stream.eatWhile(function(c) { if( c != ' ' ) { parsedBNode += c; return true; } return false;});
+          state.bnodes.push(parsedBNode);
+          stream.next();
+          transitState(state, ' ');
+          return 'builtin';
+      }
+      if(ch == '"') {
+          transitState(state, ch);
+          stream.eatWhile( function(c) { return c != '"'; } );
+          stream.next();
+          if( stream.peek() != '@' && stream.peek() != '^' ) {
+              transitState(state, '"');
+          }
+          return 'string';
+      }
+      if( ch == '@' ) {
+          transitState(state, '@');
+          var parsedLang = '';
+          stream.eatWhile(function(c) { if( c != ' ' ) { parsedLang += c; return true; } return false;});
+          state.langs.push(parsedLang);
+          stream.next();
+          transitState(state, ' ');
+          return 'string-2';
+      }
+      if( ch == '^' ) {
+          stream.next();
+          transitState(state, '^');
+          var parsedType = '';
+          stream.eatWhile(function(c) { if( c != '>' ) { parsedType += c; return true; } return false;} );
+          state.types.push(parsedType);
+          stream.next();
+          transitState(state, '>');
+          return 'variable';
+      }
+      if( ch == ' ' ) {
+          transitState(state, ch);
+      }
+      if( ch == '.' ) {
+          transitState(state, ch);
+      }
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/n-triples", "ntriples");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/octave/index.html b/app/gui/html/vendor/codemirror/mode/octave/index.html
new file mode 100644
index 0000000..573ce42
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/octave/index.html
@@ -0,0 +1,83 @@
+<!doctype html>
+
+<title>CodeMirror: Octave mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="octave.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Octave</a>
+  </ul>
+</div>
+
+<article>
+<h2>Octave mode</h2>
+
+    <div><textarea id="code" name="code">
+%numbers
+[1234 1234i 1234j]
+[.234 .234j 2.23i]
+[23e2 12E1j 123D-4 0x234]
+
+%strings
+'asda''a'
+"asda""a"
+
+%identifiers
+a + as123 - __asd__
+
+%operators
+-
++
+=
+==
+>
+<
+>=
+<=
+&
+~
+...
+break zeros default margin round ones rand
+ceil floor size clear zeros eye mean std cov
+error eval function
+abs acos atan asin cos cosh exp log prod sum
+log10 max min sign sin sinh sqrt tan reshape
+return
+case switch
+else elseif end if otherwise
+do for while
+try catch
+classdef properties events methods
+global persistent
+
+%one line comment
+%{ multi 
+line commment %}
+
+    </textarea></div>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: {name: "octave",
+               version: 2,
+               singleLineStringErrors: false},
+        lineNumbers: true,
+        indentUnit: 4,
+        matchBrackets: true
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-octave</code>.</p>
+</article>
diff --git a/app/gui/html/vendor/codemirror/mode/octave/octave.js b/app/gui/html/vendor/codemirror/mode/octave/octave.js
new file mode 100644
index 0000000..16fe4df
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/octave/octave.js
@@ -0,0 +1,132 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("octave", function() {
+  function wordRegexp(words) {
+    return new RegExp("^((" + words.join(")|(") + "))\\b");
+  }
+
+  var singleOperators = new RegExp("^[\\+\\-\\*/&|\\^~<>!@'\\\\]");
+  var singleDelimiters = new RegExp('^[\\(\\[\\{\\},:=;]');
+  var doubleOperators = new RegExp("^((==)|(~=)|(<=)|(>=)|(<<)|(>>)|(\\.[\\+\\-\\*/\\^\\\\]))");
+  var doubleDelimiters = new RegExp("^((!=)|(\\+=)|(\\-=)|(\\*=)|(/=)|(&=)|(\\|=)|(\\^=))");
+  var tripleDelimiters = new RegExp("^((>>=)|(<<=))");
+  var expressionEnd = new RegExp("^[\\]\\)]");
+  var identifiers = new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
+
+  var builtins = wordRegexp([
+    'error', 'eval', 'function', 'abs', 'acos', 'atan', 'asin', 'cos',
+    'cosh', 'exp', 'log', 'prod', 'sum', 'log10', 'max', 'min', 'sign', 'sin', 'sinh',
+    'sqrt', 'tan', 'reshape', 'break', 'zeros', 'default', 'margin', 'round', 'ones',
+    'rand', 'syn', 'ceil', 'floor', 'size', 'clear', 'zeros', 'eye', 'mean', 'std', 'cov',
+    'det', 'eig', 'inv', 'norm', 'rank', 'trace', 'expm', 'logm', 'sqrtm', 'linspace', 'plot',
+    'title', 'xlabel', 'ylabel', 'legend', 'text', 'grid', 'meshgrid', 'mesh', 'num2str',
+    'fft', 'ifft', 'arrayfun', 'cellfun', 'input', 'fliplr', 'flipud', 'ismember'
+  ]);
+
+  var keywords = wordRegexp([
+    'return', 'case', 'switch', 'else', 'elseif', 'end', 'endif', 'endfunction',
+    'if', 'otherwise', 'do', 'for', 'while', 'try', 'catch', 'classdef', 'properties', 'events',
+    'methods', 'global', 'persistent', 'endfor', 'endwhile', 'printf', 'sprintf', 'disp', 'until',
+    'continue', 'pkg'
+  ]);
+
+
+  // tokenizers
+  function tokenTranspose(stream, state) {
+    if (!stream.sol() && stream.peek() === '\'') {
+      stream.next();
+      state.tokenize = tokenBase;
+      return 'operator';
+    }
+    state.tokenize = tokenBase;
+    return tokenBase(stream, state);
+  }
+
+
+  function tokenComment(stream, state) {
+    if (stream.match(/^.*%}/)) {
+      state.tokenize = tokenBase;
+      return 'comment';
+    };
+    stream.skipToEnd();
+    return 'comment';
+  }
+
+  function tokenBase(stream, state) {
+    // whitespaces
+    if (stream.eatSpace()) return null;
+
+    // Handle one line Comments
+    if (stream.match('%{')){
+      state.tokenize = tokenComment;
+      stream.skipToEnd();
+      return 'comment';
+    }
+
+    if (stream.match(/^[%#]/)){
+      stream.skipToEnd();
+      return 'comment';
+    }
+
+    // Handle Number Literals
+    if (stream.match(/^[0-9\.+-]/, false)) {
+      if (stream.match(/^[+-]?0x[0-9a-fA-F]+[ij]?/)) {
+        stream.tokenize = tokenBase;
+        return 'number'; };
+      if (stream.match(/^[+-]?\d*\.\d+([EeDd][+-]?\d+)?[ij]?/)) { return 'number'; };
+      if (stream.match(/^[+-]?\d+([EeDd][+-]?\d+)?[ij]?/)) { return 'number'; };
+    }
+    if (stream.match(wordRegexp(['nan','NaN','inf','Inf']))) { return 'number'; };
+
+    // Handle Strings
+    if (stream.match(/^"([^"]|(""))*"/)) { return 'string'; } ;
+    if (stream.match(/^'([^']|(''))*'/)) { return 'string'; } ;
+
+    // Handle words
+    if (stream.match(keywords)) { return 'keyword'; } ;
+    if (stream.match(builtins)) { return 'builtin'; } ;
+    if (stream.match(identifiers)) { return 'variable'; } ;
+
+    if (stream.match(singleOperators) || stream.match(doubleOperators)) { return 'operator'; };
+    if (stream.match(singleDelimiters) || stream.match(doubleDelimiters) || stream.match(tripleDelimiters)) { return null; };
+
+    if (stream.match(expressionEnd)) {
+      state.tokenize = tokenTranspose;
+      return null;
+    };
+
+
+    // Handle non-detected items
+    stream.next();
+    return 'error';
+  };
+
+
+  return {
+    startState: function() {
+      return {
+        tokenize: tokenBase
+      };
+    },
+
+    token: function(stream, state) {
+      var style = state.tokenize(stream, state);
+      if (style === 'number' || style === 'variable'){
+        state.tokenize = tokenTranspose;
+      }
+      return style;
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/x-octave", "octave");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/pascal/index.html b/app/gui/html/vendor/codemirror/mode/pascal/index.html
new file mode 100644
index 0000000..bf8ff0d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/pascal/index.html
@@ -0,0 +1,61 @@
+<!doctype html>
+
+<title>CodeMirror: Pascal mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="pascal.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Pascal</a>
+  </ul>
+</div>
+
+<article>
+<h2>Pascal mode</h2>
+
+
+<div><textarea id="code" name="code">
+(* Example Pascal code *)
+
+while a <> b do writeln('Waiting');
+ 
+if a > b then 
+  writeln('Condition met')
+else 
+  writeln('Condition not met');
+ 
+for i := 1 to 10 do 
+  writeln('Iteration: ', i:1);
+ 
+repeat
+  a := a + 1
+until a = 10;
+ 
+case i of
+  0: write('zero');
+  1: write('one');
+  2: write('two')
+end;
+</textarea></div>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        mode: "text/x-pascal"
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-pascal</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/pascal/pascal.js b/app/gui/html/vendor/codemirror/mode/pascal/pascal.js
new file mode 100644
index 0000000..642dd9b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/pascal/pascal.js
@@ -0,0 +1,106 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("pascal", function() {
+  function words(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+  var keywords = words("and array begin case const div do downto else end file for forward integer " +
+                       "boolean char function goto if in label mod nil not of or packed procedure " +
+                       "program record repeat set string then to type until var while with");
+  var atoms = {"null": true};
+
+  var isOperatorChar = /[+\-*&%=<>!?|\/]/;
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+    if (ch == "#" && state.startOfLine) {
+      stream.skipToEnd();
+      return "meta";
+    }
+    if (ch == '"' || ch == "'") {
+      state.tokenize = tokenString(ch);
+      return state.tokenize(stream, state);
+    }
+    if (ch == "(" && stream.eat("*")) {
+      state.tokenize = tokenComment;
+      return tokenComment(stream, state);
+    }
+    if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
+      return null;
+    }
+    if (/\d/.test(ch)) {
+      stream.eatWhile(/[\w\.]/);
+      return "number";
+    }
+    if (ch == "/") {
+      if (stream.eat("/")) {
+        stream.skipToEnd();
+        return "comment";
+      }
+    }
+    if (isOperatorChar.test(ch)) {
+      stream.eatWhile(isOperatorChar);
+      return "operator";
+    }
+    stream.eatWhile(/[\w\$_]/);
+    var cur = stream.current();
+    if (keywords.propertyIsEnumerable(cur)) return "keyword";
+    if (atoms.propertyIsEnumerable(cur)) return "atom";
+    return "variable";
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, next, end = false;
+      while ((next = stream.next()) != null) {
+        if (next == quote && !escaped) {end = true; break;}
+        escaped = !escaped && next == "\\";
+      }
+      if (end || !escaped) state.tokenize = null;
+      return "string";
+    };
+  }
+
+  function tokenComment(stream, state) {
+    var maybeEnd = false, ch;
+    while (ch = stream.next()) {
+      if (ch == ")" && maybeEnd) {
+        state.tokenize = null;
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return "comment";
+  }
+
+  // Interface
+
+  return {
+    startState: function() {
+      return {tokenize: null};
+    },
+
+    token: function(stream, state) {
+      if (stream.eatSpace()) return null;
+      var style = (state.tokenize || tokenBase)(stream, state);
+      if (style == "comment" || style == "meta") return style;
+      return style;
+    },
+
+    electricChars: "{}"
+  };
+});
+
+CodeMirror.defineMIME("text/x-pascal", "pascal");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/pegjs/index.html b/app/gui/html/vendor/codemirror/mode/pegjs/index.html
new file mode 100644
index 0000000..678b714
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/pegjs/index.html
@@ -0,0 +1,66 @@
+<!doctype html>
+<html>
+  <head>
+    <title>CodeMirror: PEG.js Mode</title>
+    <meta charset="utf-8"/>
+    <link rel=stylesheet href="../../doc/docs.css">
+
+    <link rel="stylesheet" href="../../lib/codemirror.css">
+    <script src="../../lib/codemirror.js"></script>
+    <script src="../javascript/javascript.js"></script>
+    <script src="pegjs.js"></script>
+    <style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+  </head>
+  <body>
+    <div id=nav>
+      <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+      <ul>
+        <li><a href="../../index.html">Home</a>
+        <li><a href="../../doc/manual.html">Manual</a>
+        <li><a href="https://github.com/marijnh/codemirror">Code</a>
+      </ul>
+      <ul>
+        <li><a href="../index.html">Language modes</a>
+        <li><a class=active href="#">PEG.js Mode</a>
+      </ul>
+    </div>
+
+    <article>
+      <h2>PEG.js Mode</h2>
+      <form><textarea id="code" name="code">
+/*
+ * Classic example grammar, which recognizes simple arithmetic expressions like
+ * "2*(3+4)". The parser generated from this grammar then computes their value.
+ */
+
+start
+  = additive
+
+additive
+  = left:multiplicative "+" right:additive { return left + right; }
+  / multiplicative
+
+multiplicative
+  = left:primary "*" right:multiplicative { return left * right; }
+  / primary
+
+primary
+  = integer
+  / "(" additive:additive ")" { return additive; }
+
+integer "integer"
+  = digits:[0-9]+ { return parseInt(digits.join(""), 10); }
+
+letter = [a-z]+</textarea></form>
+      <script>
+        var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+          mode: {name: "pegjs"},
+          lineNumbers: true
+        });
+      </script>
+      <h3>The PEG.js Mode</h3>
+      <p> Created by Forbes Lindesay.</p>
+    </article>
+  </body>
+</html>
diff --git a/app/gui/html/vendor/codemirror/mode/pegjs/pegjs.js b/app/gui/html/vendor/codemirror/mode/pegjs/pegjs.js
new file mode 100644
index 0000000..f74f2a4
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/pegjs/pegjs.js
@@ -0,0 +1,111 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("../javascript/javascript"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "../javascript/javascript"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("pegjs", function (config) {
+  var jsMode = CodeMirror.getMode(config, "javascript");
+
+  function identifier(stream) {
+    return stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*/);
+  }
+
+  return {
+    startState: function () {
+      return {
+        inString: false,
+        stringType: null,
+        inComment: false,
+        inChracterClass: false,
+        braced: 0,
+        lhs: true,
+        localState: null
+      };
+    },
+    token: function (stream, state) {
+      if (stream)
+
+      //check for state changes
+      if (!state.inString && !state.inComment && ((stream.peek() == '"') || (stream.peek() == "'"))) {
+        state.stringType = stream.peek();
+        stream.next(); // Skip quote
+        state.inString = true; // Update state
+      }
+      if (!state.inString && !state.inComment && stream.match(/^\/\*/)) {
+        state.inComment = true;
+      }
+
+      //return state
+      if (state.inString) {
+        while (state.inString && !stream.eol()) {
+          if (stream.peek() === state.stringType) {
+            stream.next(); // Skip quote
+            state.inString = false; // Clear flag
+          } else if (stream.peek() === '\\') {
+            stream.next();
+            stream.next();
+          } else {
+            stream.match(/^.[^\\\"\']*/);
+          }
+        }
+        return state.lhs ? "property string" : "string"; // Token style
+      } else if (state.inComment) {
+        while (state.inComment && !stream.eol()) {
+          if (stream.match(/\*\//)) {
+            state.inComment = false; // Clear flag
+          } else {
+            stream.match(/^.[^\*]*/);
+          }
+        }
+        return "comment";
+      } else if (state.inChracterClass) {
+          while (state.inChracterClass && !stream.eol()) {
+            if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./))) {
+              state.inChracterClass = false;
+            }
+          }
+      } else if (stream.peek() === '[') {
+        stream.next();
+        state.inChracterClass = true;
+        return 'bracket';
+      } else if (stream.match(/^\/\//)) {
+        stream.skipToEnd();
+        return "comment";
+      } else if (state.braced || stream.peek() === '{') {
+        if (state.localState === null) {
+          state.localState = jsMode.startState();
+        }
+        var token = jsMode.token(stream, state.localState);
+        var text = stream.current();
+        if (!token) {
+          for (var i = 0; i < text.length; i++) {
+            if (text[i] === '{') {
+              state.braced++;
+            } else if (text[i] === '}') {
+              state.braced--;
+            }
+          };
+        }
+        return token;
+      } else if (identifier(stream)) {
+        if (stream.peek() === ':') {
+          return 'variable';
+        }
+        return 'variable-2';
+      } else if (['[', ']', '(', ')'].indexOf(stream.peek()) != -1) {
+        stream.next();
+        return 'bracket';
+      } else if (!stream.eatSpace()) {
+        stream.next();
+      }
+      return null;
+    }
+  };
+}, "javascript");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/perl/index.html b/app/gui/html/vendor/codemirror/mode/perl/index.html
new file mode 100644
index 0000000..2b7578e
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/perl/index.html
@@ -0,0 +1,75 @@
+<!doctype html>
+
+<title>CodeMirror: Perl mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="perl.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Perl</a>
+  </ul>
+</div>
+
+<article>
+<h2>Perl mode</h2>
+
+
+<div><textarea id="code" name="code">
+#!/usr/bin/perl
+
+use Something qw(func1 func2);
+
+# strings
+my $s1 = qq'single line';
+our $s2 = q(multi-
+              line);
+
+=item Something
+	Example.
+=cut
+
+my $html=<<'HTML'
+<html>
+<title>hi!</title>
+</html>
+HTML
+
+print "first,".join(',', 'second', qq~third~);
+
+if($s1 =~ m[(?<!\s)(l.ne)\z]o) {
+	$h->{$1}=$$.' predefined variables';
+	$s2 =~ s/\-line//ox;
+	$s1 =~ s[
+		  line ]
+		[
+		  block
+		]ox;
+}
+
+1; # numbers and comments
+
+__END__
+something...
+
+</textarea></div>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-perl</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/perl/perl.js b/app/gui/html/vendor/codemirror/mode/perl/perl.js
new file mode 100644
index 0000000..84392e4
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/perl/perl.js
@@ -0,0 +1,827 @@
+// CodeMirror2 mode/perl/perl.js (text/x-perl) beta 0.10 (2011-11-08)
+// This is a part of CodeMirror from https://github.com/sabaca/CodeMirror_mode_perl (mail at sabaca.com)
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("perl",function(){
+        // http://perldoc.perl.org
+        var PERL={                                      //   null - magic touch
+                                                        //   1 - keyword
+                                                        //   2 - def
+                                                        //   3 - atom
+                                                        //   4 - operator
+                                                        //   5 - variable-2 (predefined)
+                                                        //   [x,y] - x=1,2,3; y=must be defined if x{...}
+                                                //      PERL operators
+                '->'                            :   4,
+                '++'                            :   4,
+                '--'                            :   4,
+                '**'                            :   4,
+                                                        //   ! ~ \ and unary + and -
+                '=~'                            :   4,
+                '!~'                            :   4,
+                '*'                             :   4,
+                '/'                             :   4,
+                '%'                             :   4,
+                'x'                             :   4,
+                '+'                             :   4,
+                '-'                             :   4,
+                '.'                             :   4,
+                '<<'                            :   4,
+                '>>'                            :   4,
+                                                        //   named unary operators
+                '<'                             :   4,
+                '>'                             :   4,
+                '<='                            :   4,
+                '>='                            :   4,
+                'lt'                            :   4,
+                'gt'                            :   4,
+                'le'                            :   4,
+                'ge'                            :   4,
+                '=='                            :   4,
+                '!='                            :   4,
+                '<=>'                           :   4,
+                'eq'                            :   4,
+                'ne'                            :   4,
+                'cmp'                           :   4,
+                '~~'                            :   4,
+                '&'                             :   4,
+                '|'                             :   4,
+                '^'                             :   4,
+                '&&'                            :   4,
+                '||'                            :   4,
+                '//'                            :   4,
+                '..'                            :   4,
+                '...'                           :   4,
+                '?'                             :   4,
+                ':'                             :   4,
+                '='                             :   4,
+                '+='                            :   4,
+                '-='                            :   4,
+                '*='                            :   4,  //   etc. ???
+                ','                             :   4,
+                '=>'                            :   4,
+                '::'                            :   4,
+                                                        //   list operators (rightward)
+                'not'                           :   4,
+                'and'                           :   4,
+                'or'                            :   4,
+                'xor'                           :   4,
+                                                //      PERL predefined variables (I know, what this is a paranoid idea, but may be needed for people, who learn PERL, and for me as well, ...and may be for you?;)
+                'BEGIN'                         :   [5,1],
+                'END'                           :   [5,1],
+                'PRINT'                         :   [5,1],
+                'PRINTF'                        :   [5,1],
+                'GETC'                          :   [5,1],
+                'READ'                          :   [5,1],
+                'READLINE'                      :   [5,1],
+                'DESTROY'                       :   [5,1],
+                'TIE'                           :   [5,1],
+                'TIEHANDLE'                     :   [5,1],
+                'UNTIE'                         :   [5,1],
+                'STDIN'                         :    5,
+                'STDIN_TOP'                     :    5,
+                'STDOUT'                        :    5,
+                'STDOUT_TOP'                    :    5,
+                'STDERR'                        :    5,
+                'STDERR_TOP'                    :    5,
+                '$ARG'                          :    5,
+                '$_'                            :    5,
+                '@ARG'                          :    5,
+                '@_'                            :    5,
+                '$LIST_SEPARATOR'               :    5,
+                '$"'                            :    5,
+                '$PROCESS_ID'                   :    5,
+                '$PID'                          :    5,
+                '$$'                            :    5,
+                '$REAL_GROUP_ID'                :    5,
+                '$GID'                          :    5,
+                '$('                            :    5,
+                '$EFFECTIVE_GROUP_ID'           :    5,
+                '$EGID'                         :    5,
+                '$)'                            :    5,
+                '$PROGRAM_NAME'                 :    5,
+                '$0'                            :    5,
+                '$SUBSCRIPT_SEPARATOR'          :    5,
+                '$SUBSEP'                       :    5,
+                '$;'                            :    5,
+                '$REAL_USER_ID'                 :    5,
+                '$UID'                          :    5,
+                '$<'                            :    5,
+                '$EFFECTIVE_USER_ID'            :    5,
+                '$EUID'                         :    5,
+                '$>'                            :    5,
+                '$a'                            :    5,
+                '$b'                            :    5,
+                '$COMPILING'                    :    5,
+                '$^C'                           :    5,
+                '$DEBUGGING'                    :    5,
+                '$^D'                           :    5,
+                '${^ENCODING}'                  :    5,
+                '$ENV'                          :    5,
+                '%ENV'                          :    5,
+                '$SYSTEM_FD_MAX'                :    5,
+                '$^F'                           :    5,
+                '@F'                            :    5,
+                '${^GLOBAL_PHASE}'              :    5,
+                '$^H'                           :    5,
+                '%^H'                           :    5,
+                '@INC'                          :    5,
+                '%INC'                          :    5,
+                '$INPLACE_EDIT'                 :    5,
+                '$^I'                           :    5,
+                '$^M'                           :    5,
+                '$OSNAME'                       :    5,
+                '$^O'                           :    5,
+                '${^OPEN}'                      :    5,
+                '$PERLDB'                       :    5,
+                '$^P'                           :    5,
+                '$SIG'                          :    5,
+                '%SIG'                          :    5,
+                '$BASETIME'                     :    5,
+                '$^T'                           :    5,
+                '${^TAINT}'                     :    5,
+                '${^UNICODE}'                   :    5,
+                '${^UTF8CACHE}'                 :    5,
+                '${^UTF8LOCALE}'                :    5,
+                '$PERL_VERSION'                 :    5,
+                '$^V'                           :    5,
+                '${^WIN32_SLOPPY_STAT}'         :    5,
+                '$EXECUTABLE_NAME'              :    5,
+                '$^X'                           :    5,
+                '$1'                            :    5, // - regexp $1, $2...
+                '$MATCH'                        :    5,
+                '$&'                            :    5,
+                '${^MATCH}'                     :    5,
+                '$PREMATCH'                     :    5,
+                '$`'                            :    5,
+                '${^PREMATCH}'                  :    5,
+                '$POSTMATCH'                    :    5,
+                "$'"                            :    5,
+                '${^POSTMATCH}'                 :    5,
+                '$LAST_PAREN_MATCH'             :    5,
+                '$+'                            :    5,
+                '$LAST_SUBMATCH_RESULT'         :    5,
+                '$^N'                           :    5,
+                '@LAST_MATCH_END'               :    5,
+                '@+'                            :    5,
+                '%LAST_PAREN_MATCH'             :    5,
+                '%+'                            :    5,
+                '@LAST_MATCH_START'             :    5,
+                '@-'                            :    5,
+                '%LAST_MATCH_START'             :    5,
+                '%-'                            :    5,
+                '$LAST_REGEXP_CODE_RESULT'      :    5,
+                '$^R'                           :    5,
+                '${^RE_DEBUG_FLAGS}'            :    5,
+                '${^RE_TRIE_MAXBUF}'            :    5,
+                '$ARGV'                         :    5,
+                '@ARGV'                         :    5,
+                'ARGV'                          :    5,
+                'ARGVOUT'                       :    5,
+                '$OUTPUT_FIELD_SEPARATOR'       :    5,
+                '$OFS'                          :    5,
+                '$,'                            :    5,
+                '$INPUT_LINE_NUMBER'            :    5,
+                '$NR'                           :    5,
+                '$.'                            :    5,
+                '$INPUT_RECORD_SEPARATOR'       :    5,
+                '$RS'                           :    5,
+                '$/'                            :    5,
+                '$OUTPUT_RECORD_SEPARATOR'      :    5,
+                '$ORS'                          :    5,
+                '$\\'                           :    5,
+                '$OUTPUT_AUTOFLUSH'             :    5,
+                '$|'                            :    5,
+                '$ACCUMULATOR'                  :    5,
+                '$^A'                           :    5,
+                '$FORMAT_FORMFEED'              :    5,
+                '$^L'                           :    5,
+                '$FORMAT_PAGE_NUMBER'           :    5,
+                '$%'                            :    5,
+                '$FORMAT_LINES_LEFT'            :    5,
+                '$-'                            :    5,
+                '$FORMAT_LINE_BREAK_CHARACTERS' :    5,
+                '$:'                            :    5,
+                '$FORMAT_LINES_PER_PAGE'        :    5,
+                '$='                            :    5,
+                '$FORMAT_TOP_NAME'              :    5,
+                '$^'                            :    5,
+                '$FORMAT_NAME'                  :    5,
+                '$~'                            :    5,
+                '${^CHILD_ERROR_NATIVE}'        :    5,
+                '$EXTENDED_OS_ERROR'            :    5,
+                '$^E'                           :    5,
+                '$EXCEPTIONS_BEING_CAUGHT'      :    5,
+                '$^S'                           :    5,
+                '$WARNING'                      :    5,
+                '$^W'                           :    5,
+                '${^WARNING_BITS}'              :    5,
+                '$OS_ERROR'                     :    5,
+                '$ERRNO'                        :    5,
+                '$!'                            :    5,
+                '%OS_ERROR'                     :    5,
+                '%ERRNO'                        :    5,
+                '%!'                            :    5,
+                '$CHILD_ERROR'                  :    5,
+                '$?'                            :    5,
+                '$EVAL_ERROR'                   :    5,
+                '$@'                            :    5,
+                '$OFMT'                         :    5,
+                '$#'                            :    5,
+                '$*'                            :    5,
+                '$ARRAY_BASE'                   :    5,
+                '$['                            :    5,
+                '$OLD_PERL_VERSION'             :    5,
+                '$]'                            :    5,
+                                                //      PERL blocks
+                'if'                            :[1,1],
+                elsif                           :[1,1],
+                'else'                          :[1,1],
+                'while'                         :[1,1],
+                unless                          :[1,1],
+                'for'                           :[1,1],
+                foreach                         :[1,1],
+                                                //      PERL functions
+                'abs'                           :1,     // - absolute value function
+                accept                          :1,     // - accept an incoming socket connect
+                alarm                           :1,     // - schedule a SIGALRM
+                'atan2'                         :1,     // - arctangent of Y/X in the range -PI to PI
+                bind                            :1,     // - binds an address to a socket
+                binmode                         :1,     // - prepare binary files for I/O
+                bless                           :1,     // - create an object
+                bootstrap                       :1,     //
+                'break'                         :1,     // - break out of a "given" block
+                caller                          :1,     // - get context of the current subroutine call
+                chdir                           :1,     // - change your current working directory
+                chmod                           :1,     // - changes the permissions on a list of files
+                chomp                           :1,     // - remove a trailing record separator from a string
+                chop                            :1,     // - remove the last character from a string
+                chown                           :1,     // - change the owership on a list of files
+                chr                             :1,     // - get character this number represents
+                chroot                          :1,     // - make directory new root for path lookups
+                close                           :1,     // - close file (or pipe or socket) handle
+                closedir                        :1,     // - close directory handle
+                connect                         :1,     // - connect to a remote socket
+                'continue'                      :[1,1], // - optional trailing block in a while or foreach
+                'cos'                           :1,     // - cosine function
+                crypt                           :1,     // - one-way passwd-style encryption
+                dbmclose                        :1,     // - breaks binding on a tied dbm file
+                dbmopen                         :1,     // - create binding on a tied dbm file
+                'default'                       :1,     //
+                defined                         :1,     // - test whether a value, variable, or function is defined
+                'delete'                        :1,     // - deletes a value from a hash
+                die                             :1,     // - raise an exception or bail out
+                'do'                            :1,     // - turn a BLOCK into a TERM
+                dump                            :1,     // - create an immediate core dump
+                each                            :1,     // - retrieve the next key/value pair from a hash
+                endgrent                        :1,     // - be done using group file
+                endhostent                      :1,     // - be done using hosts file
+                endnetent                       :1,     // - be done using networks file
+                endprotoent                     :1,     // - be done using protocols file
+                endpwent                        :1,     // - be done using passwd file
+                endservent                      :1,     // - be done using services file
+                eof                             :1,     // - test a filehandle for its end
+                'eval'                          :1,     // - catch exceptions or compile and run code
+                'exec'                          :1,     // - abandon this program to run another
+                exists                          :1,     // - test whether a hash key is present
+                exit                            :1,     // - terminate this program
+                'exp'                           :1,     // - raise I to a power
+                fcntl                           :1,     // - file control system call
+                fileno                          :1,     // - return file descriptor from filehandle
+                flock                           :1,     // - lock an entire file with an advisory lock
+                fork                            :1,     // - create a new process just like this one
+                format                          :1,     // - declare a picture format with use by the write() function
+                formline                        :1,     // - internal function used for formats
+                getc                            :1,     // - get the next character from the filehandle
+                getgrent                        :1,     // - get next group record
+                getgrgid                        :1,     // - get group record given group user ID
+                getgrnam                        :1,     // - get group record given group name
+                gethostbyaddr                   :1,     // - get host record given its address
+                gethostbyname                   :1,     // - get host record given name
+                gethostent                      :1,     // - get next hosts record
+                getlogin                        :1,     // - return who logged in at this tty
+                getnetbyaddr                    :1,     // - get network record given its address
+                getnetbyname                    :1,     // - get networks record given name
+                getnetent                       :1,     // - get next networks record
+                getpeername                     :1,     // - find the other end of a socket connection
+                getpgrp                         :1,     // - get process group
+                getppid                         :1,     // - get parent process ID
+                getpriority                     :1,     // - get current nice value
+                getprotobyname                  :1,     // - get protocol record given name
+                getprotobynumber                :1,     // - get protocol record numeric protocol
+                getprotoent                     :1,     // - get next protocols record
+                getpwent                        :1,     // - get next passwd record
+                getpwnam                        :1,     // - get passwd record given user login name
+                getpwuid                        :1,     // - get passwd record given user ID
+                getservbyname                   :1,     // - get services record given its name
+                getservbyport                   :1,     // - get services record given numeric port
+                getservent                      :1,     // - get next services record
+                getsockname                     :1,     // - retrieve the sockaddr for a given socket
+                getsockopt                      :1,     // - get socket options on a given socket
+                given                           :1,     //
+                glob                            :1,     // - expand filenames using wildcards
+                gmtime                          :1,     // - convert UNIX time into record or string using Greenwich time
+                'goto'                          :1,     // - create spaghetti code
+                grep                            :1,     // - locate elements in a list test true against a given criterion
+                hex                             :1,     // - convert a string to a hexadecimal number
+                'import'                        :1,     // - patch a module's namespace into your own
+                index                           :1,     // - find a substring within a string
+                'int'                           :1,     // - get the integer portion of a number
+                ioctl                           :1,     // - system-dependent device control system call
+                'join'                          :1,     // - join a list into a string using a separator
+                keys                            :1,     // - retrieve list of indices from a hash
+                kill                            :1,     // - send a signal to a process or process group
+                last                            :1,     // - exit a block prematurely
+                lc                              :1,     // - return lower-case version of a string
+                lcfirst                         :1,     // - return a string with just the next letter in lower case
+                length                          :1,     // - return the number of bytes in a string
+                'link'                          :1,     // - create a hard link in the filesytem
+                listen                          :1,     // - register your socket as a server
+                local                           : 2,    // - create a temporary value for a global variable (dynamic scoping)
+                localtime                       :1,     // - convert UNIX time into record or string using local time
+                lock                            :1,     // - get a thread lock on a variable, subroutine, or method
+                'log'                           :1,     // - retrieve the natural logarithm for a number
+                lstat                           :1,     // - stat a symbolic link
+                m                               :null,  // - match a string with a regular expression pattern
+                map                             :1,     // - apply a change to a list to get back a new list with the changes
+                mkdir                           :1,     // - create a directory
+                msgctl                          :1,     // - SysV IPC message control operations
+                msgget                          :1,     // - get SysV IPC message queue
+                msgrcv                          :1,     // - receive a SysV IPC message from a message queue
+                msgsnd                          :1,     // - send a SysV IPC message to a message queue
+                my                              : 2,    // - declare and assign a local variable (lexical scoping)
+                'new'                           :1,     //
+                next                            :1,     // - iterate a block prematurely
+                no                              :1,     // - unimport some module symbols or semantics at compile time
+                oct                             :1,     // - convert a string to an octal number
+                open                            :1,     // - open a file, pipe, or descriptor
+                opendir                         :1,     // - open a directory
+                ord                             :1,     // - find a character's numeric representation
+                our                             : 2,    // - declare and assign a package variable (lexical scoping)
+                pack                            :1,     // - convert a list into a binary representation
+                'package'                       :1,     // - declare a separate global namespace
+                pipe                            :1,     // - open a pair of connected filehandles
+                pop                             :1,     // - remove the last element from an array and return it
+                pos                             :1,     // - find or set the offset for the last/next m//g search
+                print                           :1,     // - output a list to a filehandle
+                printf                          :1,     // - output a formatted list to a filehandle
+                prototype                       :1,     // - get the prototype (if any) of a subroutine
+                push                            :1,     // - append one or more elements to an array
+                q                               :null,  // - singly quote a string
+                qq                              :null,  // - doubly quote a string
+                qr                              :null,  // - Compile pattern
+                quotemeta                       :null,  // - quote regular expression magic characters
+                qw                              :null,  // - quote a list of words
+                qx                              :null,  // - backquote quote a string
+                rand                            :1,     // - retrieve the next pseudorandom number
+                read                            :1,     // - fixed-length buffered input from a filehandle
+                readdir                         :1,     // - get a directory from a directory handle
+                readline                        :1,     // - fetch a record from a file
+                readlink                        :1,     // - determine where a symbolic link is pointing
+                readpipe                        :1,     // - execute a system command and collect standard output
+                recv                            :1,     // - receive a message over a Socket
+                redo                            :1,     // - start this loop iteration over again
+                ref                             :1,     // - find out the type of thing being referenced
+                rename                          :1,     // - change a filename
+                require                         :1,     // - load in external functions from a library at runtime
+                reset                           :1,     // - clear all variables of a given name
+                'return'                        :1,     // - get out of a function early
+                reverse                         :1,     // - flip a string or a list
+                rewinddir                       :1,     // - reset directory handle
+                rindex                          :1,     // - right-to-left substring search
+                rmdir                           :1,     // - remove a directory
+                s                               :null,  // - replace a pattern with a string
+                say                             :1,     // - print with newline
+                scalar                          :1,     // - force a scalar context
+                seek                            :1,     // - reposition file pointer for random-access I/O
+                seekdir                         :1,     // - reposition directory pointer
+                select                          :1,     // - reset default output or do I/O multiplexing
+                semctl                          :1,     // - SysV semaphore control operations
+                semget                          :1,     // - get set of SysV semaphores
+                semop                           :1,     // - SysV semaphore operations
+                send                            :1,     // - send a message over a socket
+                setgrent                        :1,     // - prepare group file for use
+                sethostent                      :1,     // - prepare hosts file for use
+                setnetent                       :1,     // - prepare networks file for use
+                setpgrp                         :1,     // - set the process group of a process
+                setpriority                     :1,     // - set a process's nice value
+                setprotoent                     :1,     // - prepare protocols file for use
+                setpwent                        :1,     // - prepare passwd file for use
+                setservent                      :1,     // - prepare services file for use
+                setsockopt                      :1,     // - set some socket options
+                shift                           :1,     // - remove the first element of an array, and return it
+                shmctl                          :1,     // - SysV shared memory operations
+                shmget                          :1,     // - get SysV shared memory segment identifier
+                shmread                         :1,     // - read SysV shared memory
+                shmwrite                        :1,     // - write SysV shared memory
+                shutdown                        :1,     // - close down just half of a socket connection
+                'sin'                           :1,     // - return the sine of a number
+                sleep                           :1,     // - block for some number of seconds
+                socket                          :1,     // - create a socket
+                socketpair                      :1,     // - create a pair of sockets
+                'sort'                          :1,     // - sort a list of values
+                splice                          :1,     // - add or remove elements anywhere in an array
+                'split'                         :1,     // - split up a string using a regexp delimiter
+                sprintf                         :1,     // - formatted print into a string
+                'sqrt'                          :1,     // - square root function
+                srand                           :1,     // - seed the random number generator
+                stat                            :1,     // - get a file's status information
+                state                           :1,     // - declare and assign a state variable (persistent lexical scoping)
+                study                           :1,     // - optimize input data for repeated searches
+                'sub'                           :1,     // - declare a subroutine, possibly anonymously
+                'substr'                        :1,     // - get or alter a portion of a stirng
+                symlink                         :1,     // - create a symbolic link to a file
+                syscall                         :1,     // - execute an arbitrary system call
+                sysopen                         :1,     // - open a file, pipe, or descriptor
+                sysread                         :1,     // - fixed-length unbuffered input from a filehandle
+                sysseek                         :1,     // - position I/O pointer on handle used with sysread and syswrite
+                system                          :1,     // - run a separate program
+                syswrite                        :1,     // - fixed-length unbuffered output to a filehandle
+                tell                            :1,     // - get current seekpointer on a filehandle
+                telldir                         :1,     // - get current seekpointer on a directory handle
+                tie                             :1,     // - bind a variable to an object class
+                tied                            :1,     // - get a reference to the object underlying a tied variable
+                time                            :1,     // - return number of seconds since 1970
+                times                           :1,     // - return elapsed time for self and child processes
+                tr                              :null,  // - transliterate a string
+                truncate                        :1,     // - shorten a file
+                uc                              :1,     // - return upper-case version of a string
+                ucfirst                         :1,     // - return a string with just the next letter in upper case
+                umask                           :1,     // - set file creation mode mask
+                undef                           :1,     // - remove a variable or function definition
+                unlink                          :1,     // - remove one link to a file
+                unpack                          :1,     // - convert binary structure into normal perl variables
+                unshift                         :1,     // - prepend more elements to the beginning of a list
+                untie                           :1,     // - break a tie binding to a variable
+                use                             :1,     // - load in a module at compile time
+                utime                           :1,     // - set a file's last access and modify times
+                values                          :1,     // - return a list of the values in a hash
+                vec                             :1,     // - test or set particular bits in a string
+                wait                            :1,     // - wait for any child process to die
+                waitpid                         :1,     // - wait for a particular child process to die
+                wantarray                       :1,     // - get void vs scalar vs list context of current subroutine call
+                warn                            :1,     // - print debugging info
+                when                            :1,     //
+                write                           :1,     // - print a picture record
+                y                               :null}; // - transliterate a string
+
+        var RXstyle="string-2";
+        var RXmodifiers=/[goseximacplud]/;              // NOTE: "m", "s", "y" and "tr" need to correct real modifiers for each regexp type
+
+        function tokenChain(stream,state,chain,style,tail){     // NOTE: chain.length > 2 is not working now (it's for s[...][...]geos;)
+                state.chain=null;                               //                                                          12   3tail
+                state.style=null;
+                state.tail=null;
+                state.tokenize=function(stream,state){
+                        var e=false,c,i=0;
+                        while(c=stream.next()){
+                                if(c===chain[i]&&!e){
+                                        if(chain[++i]!==undefined){
+                                                state.chain=chain[i];
+                                                state.style=style;
+                                                state.tail=tail;}
+                                        else if(tail)
+                                                stream.eatWhile(tail);
+                                        state.tokenize=tokenPerl;
+                                        return style;}
+                                e=!e&&c=="\\";}
+                        return style;};
+                return state.tokenize(stream,state);}
+
+        function tokenSOMETHING(stream,state,string){
+                state.tokenize=function(stream,state){
+                        if(stream.string==string)
+                                state.tokenize=tokenPerl;
+                        stream.skipToEnd();
+                        return "string";};
+                return state.tokenize(stream,state);}
+
+        function tokenPerl(stream,state){
+                if(stream.eatSpace())
+                        return null;
+                if(state.chain)
+                        return tokenChain(stream,state,state.chain,state.style,state.tail);
+                if(stream.match(/^\-?[\d\.]/,false))
+                        if(stream.match(/^(\-?(\d*\.\d+(e[+-]?\d+)?|\d+\.\d*)|0x[\da-fA-F]+|0b[01]+|\d+(e[+-]?\d+)?)/))
+                                return 'number';
+                if(stream.match(/^<<(?=\w)/)){                  // NOTE: <<SOMETHING\n...\nSOMETHING\n
+                        stream.eatWhile(/\w/);
+                        return tokenSOMETHING(stream,state,stream.current().substr(2));}
+                if(stream.sol()&&stream.match(/^\=item(?!\w)/)){// NOTE: \n=item...\n=cut\n
+                        return tokenSOMETHING(stream,state,'=cut');}
+                var ch=stream.next();
+                if(ch=='"'||ch=="'"){                           // NOTE: ' or " or <<'SOMETHING'\n...\nSOMETHING\n or <<"SOMETHING"\n...\nSOMETHING\n
+                        if(prefix(stream, 3)=="<<"+ch){
+                                var p=stream.pos;
+                                stream.eatWhile(/\w/);
+                                var n=stream.current().substr(1);
+                                if(n&&stream.eat(ch))
+                                        return tokenSOMETHING(stream,state,n);
+                                stream.pos=p;}
+                        return tokenChain(stream,state,[ch],"string");}
+                if(ch=="q"){
+                        var c=look(stream, -2);
+                        if(!(c&&/\w/.test(c))){
+                                c=look(stream, 0);
+                                if(c=="x"){
+                                        c=look(stream, 1);
+                                        if(c=="("){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);}
+                                        if(c=="["){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);}
+                                        if(c=="{"){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);}
+                                        if(c=="<"){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}
+                                        if(/[\^'"!~\/]/.test(c)){
+                                                eatSuffix(stream, 1);
+                                                return tokenChain(stream,state,[stream.eat(c)],RXstyle,RXmodifiers);}}
+                                else if(c=="q"){
+                                        c=look(stream, 1);
+                                        if(c=="("){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,[")"],"string");}
+                                        if(c=="["){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,["]"],"string");}
+                                        if(c=="{"){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,["}"],"string");}
+                                        if(c=="<"){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,[">"],"string");}
+                                        if(/[\^'"!~\/]/.test(c)){
+                                                eatSuffix(stream, 1);
+                                                return tokenChain(stream,state,[stream.eat(c)],"string");}}
+                                else if(c=="w"){
+                                        c=look(stream, 1);
+                                        if(c=="("){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,[")"],"bracket");}
+                                        if(c=="["){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,["]"],"bracket");}
+                                        if(c=="{"){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,["}"],"bracket");}
+                                        if(c=="<"){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,[">"],"bracket");}
+                                        if(/[\^'"!~\/]/.test(c)){
+                                                eatSuffix(stream, 1);
+                                                return tokenChain(stream,state,[stream.eat(c)],"bracket");}}
+                                else if(c=="r"){
+                                        c=look(stream, 1);
+                                        if(c=="("){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);}
+                                        if(c=="["){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);}
+                                        if(c=="{"){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);}
+                                        if(c=="<"){
+                                                eatSuffix(stream, 2);
+                                                return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}
+                                        if(/[\^'"!~\/]/.test(c)){
+                                                eatSuffix(stream, 1);
+                                                return tokenChain(stream,state,[stream.eat(c)],RXstyle,RXmodifiers);}}
+                                else if(/[\^'"!~\/(\[{<]/.test(c)){
+                                        if(c=="("){
+                                                eatSuffix(stream, 1);
+                                                return tokenChain(stream,state,[")"],"string");}
+                                        if(c=="["){
+                                                eatSuffix(stream, 1);
+                                                return tokenChain(stream,state,["]"],"string");}
+                                        if(c=="{"){
+                                                eatSuffix(stream, 1);
+                                                return tokenChain(stream,state,["}"],"string");}
+                                        if(c=="<"){
+                                                eatSuffix(stream, 1);
+                                                return tokenChain(stream,state,[">"],"string");}
+                                        if(/[\^'"!~\/]/.test(c)){
+                                                return tokenChain(stream,state,[stream.eat(c)],"string");}}}}
+                if(ch=="m"){
+                        var c=look(stream, -2);
+                        if(!(c&&/\w/.test(c))){
+                                c=stream.eat(/[(\[{<\^'"!~\/]/);
+                                if(c){
+                                        if(/[\^'"!~\/]/.test(c)){
+                                                return tokenChain(stream,state,[c],RXstyle,RXmodifiers);}
+                                        if(c=="("){
+                                                return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);}
+                                        if(c=="["){
+                                                return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);}
+                                        if(c=="{"){
+                                                return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);}
+                                        if(c=="<"){
+                                                return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}}}}
+                if(ch=="s"){
+                        var c=/[\/>\]})\w]/.test(look(stream, -2));
+                        if(!c){
+                                c=stream.eat(/[(\[{<\^'"!~\/]/);
+                                if(c){
+                                        if(c=="[")
+                                                return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);
+                                        if(c=="{")
+                                                return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);
+                                        if(c=="<")
+                                                return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);
+                                        if(c=="(")
+                                                return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);
+                                        return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}
+                if(ch=="y"){
+                        var c=/[\/>\]})\w]/.test(look(stream, -2));
+                        if(!c){
+                                c=stream.eat(/[(\[{<\^'"!~\/]/);
+                                if(c){
+                                        if(c=="[")
+                                                return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);
+                                        if(c=="{")
+                                                return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);
+                                        if(c=="<")
+                                                return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);
+                                        if(c=="(")
+                                                return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);
+                                        return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}
+                if(ch=="t"){
+                        var c=/[\/>\]})\w]/.test(look(stream, -2));
+                        if(!c){
+                                c=stream.eat("r");if(c){
+                                c=stream.eat(/[(\[{<\^'"!~\/]/);
+                                if(c){
+                                        if(c=="[")
+                                                return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);
+                                        if(c=="{")
+                                                return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);
+                                        if(c=="<")
+                                                return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);
+                                        if(c=="(")
+                                                return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);
+                                        return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}}
+                if(ch=="`"){
+                        return tokenChain(stream,state,[ch],"variable-2");}
+                if(ch=="/"){
+                        if(!/~\s*$/.test(prefix(stream)))
+                                return "operator";
+                        else
+                                return tokenChain(stream,state,[ch],RXstyle,RXmodifiers);}
+                if(ch=="$"){
+                        var p=stream.pos;
+                        if(stream.eatWhile(/\d/)||stream.eat("{")&&stream.eatWhile(/\d/)&&stream.eat("}"))
+                                return "variable-2";
+                        else
+                                stream.pos=p;}
+                if(/[$@%]/.test(ch)){
+                        var p=stream.pos;
+                        if(stream.eat("^")&&stream.eat(/[A-Z]/)||!/[@$%&]/.test(look(stream, -2))&&stream.eat(/[=|\\\-#?@;:&`~\^!\[\]*'"$+.,\/<>()]/)){
+                                var c=stream.current();
+                                if(PERL[c])
+                                        return "variable-2";}
+                        stream.pos=p;}
+                if(/[$@%&]/.test(ch)){
+                        if(stream.eatWhile(/[\w$\[\]]/)||stream.eat("{")&&stream.eatWhile(/[\w$\[\]]/)&&stream.eat("}")){
+                                var c=stream.current();
+                                if(PERL[c])
+                                        return "variable-2";
+                                else
+                                        return "variable";}}
+                if(ch=="#"){
+                        if(look(stream, -2)!="$"){
+                                stream.skipToEnd();
+                                return "comment";}}
+                if(/[:+\-\^*$&%@=<>!?|\/~\.]/.test(ch)){
+                        var p=stream.pos;
+                        stream.eatWhile(/[:+\-\^*$&%@=<>!?|\/~\.]/);
+                        if(PERL[stream.current()])
+                                return "operator";
+                        else
+                                stream.pos=p;}
+                if(ch=="_"){
+                        if(stream.pos==1){
+                                if(suffix(stream, 6)=="_END__"){
+                                        return tokenChain(stream,state,['\0'],"comment");}
+                                else if(suffix(stream, 7)=="_DATA__"){
+                                        return tokenChain(stream,state,['\0'],"variable-2");}
+                                else if(suffix(stream, 7)=="_C__"){
+                                        return tokenChain(stream,state,['\0'],"string");}}}
+                if(/\w/.test(ch)){
+                        var p=stream.pos;
+                        if(look(stream, -2)=="{"&&(look(stream, 0)=="}"||stream.eatWhile(/\w/)&&look(stream, 0)=="}"))
+                                return "string";
+                        else
+                                stream.pos=p;}
+                if(/[A-Z]/.test(ch)){
+                        var l=look(stream, -2);
+                        var p=stream.pos;
+                        stream.eatWhile(/[A-Z_]/);
+                        if(/[\da-z]/.test(look(stream, 0))){
+                                stream.pos=p;}
+                        else{
+                                var c=PERL[stream.current()];
+                                if(!c)
+                                        return "meta";
+                                if(c[1])
+                                        c=c[0];
+                                if(l!=":"){
+                                        if(c==1)
+                                                return "keyword";
+                                        else if(c==2)
+                                                return "def";
+                                        else if(c==3)
+                                                return "atom";
+                                        else if(c==4)
+                                                return "operator";
+                                        else if(c==5)
+                                                return "variable-2";
+                                        else
+                                                return "meta";}
+                                else
+                                        return "meta";}}
+                if(/[a-zA-Z_]/.test(ch)){
+                        var l=look(stream, -2);
+                        stream.eatWhile(/\w/);
+                        var c=PERL[stream.current()];
+                        if(!c)
+                                return "meta";
+                        if(c[1])
+                                c=c[0];
+                        if(l!=":"){
+                                if(c==1)
+                                        return "keyword";
+                                else if(c==2)
+                                        return "def";
+                                else if(c==3)
+                                        return "atom";
+                                else if(c==4)
+                                        return "operator";
+                                else if(c==5)
+                                        return "variable-2";
+                                else
+                                        return "meta";}
+                        else
+                                return "meta";}
+                return null;}
+
+        return{
+                startState:function(){
+                        return{
+                                tokenize:tokenPerl,
+                                chain:null,
+                                style:null,
+                                tail:null};},
+                token:function(stream,state){
+                        return (state.tokenize||tokenPerl)(stream,state);},
+                electricChars:"{}"};});
+
+CodeMirror.defineMIME("text/x-perl", "perl");
+
+// it's like "peek", but need for look-ahead or look-behind if index < 0
+function look(stream, c){
+  return stream.string.charAt(stream.pos+(c||0));
+}
+
+// return a part of prefix of current stream from current position
+function prefix(stream, c){
+  if(c){
+    var x=stream.pos-c;
+    return stream.string.substr((x>=0?x:0),c);}
+  else{
+    return stream.string.substr(0,stream.pos-1);
+  }
+}
+
+// return a part of suffix of current stream from current position
+function suffix(stream, c){
+  var y=stream.string.length;
+  var x=y-stream.pos+1;
+  return stream.string.substr(stream.pos,(c&&c<y?c:x));
+}
+
+// eating and vomiting a part of stream from current position
+function eatSuffix(stream, c){
+  var x=stream.pos+c;
+  var y;
+  if(x<=0)
+    stream.pos=0;
+  else if(x>=(y=stream.string.length-1))
+    stream.pos=y;
+  else
+    stream.pos=x;
+}
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/php/index.html b/app/gui/html/vendor/codemirror/mode/php/index.html
new file mode 100644
index 0000000..1fb7435
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/php/index.html
@@ -0,0 +1,60 @@
+<!doctype html>
+
+<title>CodeMirror: PHP mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="../htmlmixed/htmlmixed.js"></script>
+<script src="../xml/xml.js"></script>
+<script src="../javascript/javascript.js"></script>
+<script src="../css/css.js"></script>
+<script src="../clike/clike.js"></script>
+<script src="php.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">PHP</a>
+  </ul>
+</div>
+
+<article>
+<h2>PHP mode</h2>
+<form><textarea id="code" name="code">
+<?php
+function hello($who) {
+	return "Hello " . $who;
+}
+?>
+<p>The program says <?= hello("World") ?>.</p>
+<script>
+	alert("And here is some JS code"); // also colored
+</script>
+</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        mode: "application/x-httpd-php",
+        indentUnit: 4,
+        indentWithTabs: true
+      });
+    </script>
+
+    <p>Simple HTML/PHP mode based on
+    the <a href="../clike/">C-like</a> mode. Depends on XML,
+    JavaScript, CSS, HTMLMixed, and C-like modes.</p>
+
+    <p><strong>MIME types defined:</strong> <code>application/x-httpd-php</code> (HTML with PHP code), <code>text/x-php</code> (plain, non-wrapped PHP code).</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/php/php.js b/app/gui/html/vendor/codemirror/mode/php/php.js
new file mode 100644
index 0000000..7156dbb
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/php/php.js
@@ -0,0 +1,140 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../clike/clike"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../clike/clike"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  function keywords(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+  function heredoc(delim) {
+    return function(stream, state) {
+      if (stream.match(delim)) state.tokenize = null;
+      else stream.skipToEnd();
+      return "string";
+    };
+  }
+  var phpConfig = {
+    name: "clike",
+    keywords: keywords("abstract and array as break case catch class clone const continue declare default " +
+                       "do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " +
+                       "for foreach function global goto if implements interface instanceof namespace " +
+                       "new or private protected public static switch throw trait try use var while xor " +
+                       "die echo empty exit eval include include_once isset list require require_once return " +
+                       "print unset __halt_compiler self static parent yield insteadof finally"),
+    blockKeywords: keywords("catch do else elseif for foreach if switch try while finally"),
+    atoms: keywords("true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__ __TRAIT__"),
+    builtin: keywords("func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex hex2bin sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport http_response_code get_declared_traits getimagesizefromstring socket_import_stream stream_set_chunk_size trait_exists header_register_callback class_uses session_status session_register_shutdown echo print global static exit array empty eval isset unset die include require include_once require_once"),
+    multiLineStrings: true,
+    hooks: {
+      "$": function(stream) {
+        stream.eatWhile(/[\w\$_]/);
+        return "variable-2";
+      },
+      "<": function(stream, state) {
+        if (stream.match(/<</)) {
+          stream.eatWhile(/[\w\.]/);
+          state.tokenize = heredoc(stream.current().slice(3));
+          return state.tokenize(stream, state);
+        }
+        return false;
+      },
+      "#": function(stream) {
+        while (!stream.eol() && !stream.match("?>", false)) stream.next();
+        return "comment";
+      },
+      "/": function(stream) {
+        if (stream.eat("/")) {
+          while (!stream.eol() && !stream.match("?>", false)) stream.next();
+          return "comment";
+        }
+        return false;
+      }
+    }
+  };
+
+  CodeMirror.defineMode("php", function(config, parserConfig) {
+    var htmlMode = CodeMirror.getMode(config, "text/html");
+    var phpMode = CodeMirror.getMode(config, phpConfig);
+
+    function dispatch(stream, state) {
+      var isPHP = state.curMode == phpMode;
+      if (stream.sol() && state.pending && state.pending != '"' && state.pending != "'") state.pending = null;
+      if (!isPHP) {
+        if (stream.match(/^<\?\w*/)) {
+          state.curMode = phpMode;
+          state.curState = state.php;
+          return "meta";
+        }
+        if (state.pending == '"' || state.pending == "'") {
+          while (!stream.eol() && stream.next() != state.pending) {}
+          var style = "string";
+        } else if (state.pending && stream.pos < state.pending.end) {
+          stream.pos = state.pending.end;
+          var style = state.pending.style;
+        } else {
+          var style = htmlMode.token(stream, state.curState);
+        }
+        if (state.pending) state.pending = null;
+        var cur = stream.current(), openPHP = cur.search(/<\?/), m;
+        if (openPHP != -1) {
+          if (style == "string" && (m = cur.match(/[\'\"]$/)) && !/\?>/.test(cur)) state.pending = m[0];
+          else state.pending = {end: stream.pos, style: style};
+          stream.backUp(cur.length - openPHP);
+        }
+        return style;
+      } else if (isPHP && state.php.tokenize == null && stream.match("?>")) {
+        state.curMode = htmlMode;
+        state.curState = state.html;
+        return "meta";
+      } else {
+        return phpMode.token(stream, state.curState);
+      }
+    }
+
+    return {
+      startState: function() {
+        var html = CodeMirror.startState(htmlMode), php = CodeMirror.startState(phpMode);
+        return {html: html,
+                php: php,
+                curMode: parserConfig.startOpen ? phpMode : htmlMode,
+                curState: parserConfig.startOpen ? php : html,
+                pending: null};
+      },
+
+      copyState: function(state) {
+        var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html),
+            php = state.php, phpNew = CodeMirror.copyState(phpMode, php), cur;
+        if (state.curMode == htmlMode) cur = htmlNew;
+        else cur = phpNew;
+        return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur,
+                pending: state.pending};
+      },
+
+      token: dispatch,
+
+      indent: function(state, textAfter) {
+        if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) ||
+            (state.curMode == phpMode && /^\?>/.test(textAfter)))
+          return htmlMode.indent(state.html, textAfter);
+        return state.curMode.indent(state.curState, textAfter);
+      },
+
+      blockCommentStart: "/*",
+      blockCommentEnd: "*/",
+      lineComment: "//",
+
+      innerMode: function(state) { return {state: state.curState, mode: state.curMode}; }
+    };
+  }, "htmlmixed", "clike");
+
+  CodeMirror.defineMIME("application/x-httpd-php", "php");
+  CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
+  CodeMirror.defineMIME("text/x-php", phpConfig);
+});
diff --git a/app/gui/html/vendor/codemirror/mode/pig/index.html b/app/gui/html/vendor/codemirror/mode/pig/index.html
new file mode 100644
index 0000000..93744ae
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/pig/index.html
@@ -0,0 +1,55 @@
+<!doctype html>
+
+<title>CodeMirror: Pig Latin mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="pig.js"></script>
+<style>.CodeMirror {border: 2px inset #dee;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Pig Latin</a>
+  </ul>
+</div>
+
+<article>
+<h2>Pig Latin mode</h2>
+<form><textarea id="code" name="code">
+-- Apache Pig (Pig Latin Language) Demo
+/* 
+This is a multiline comment.
+*/
+a = LOAD "\path\to\input" USING PigStorage('\t') AS (x:long, y:chararray, z:bytearray);
+b = GROUP a BY (x,y,3+4);
+c = FOREACH b GENERATE flatten(group) as (x,y), SUM(group.$2) as z;
+STORE c INTO "\path\to\output";
+
+--
+</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        indentUnit: 4,
+        mode: "text/x-pig"
+      });
+    </script>
+
+    <p>
+        Simple mode that handles Pig Latin language.
+    </p>
+
+    <p><strong>MIME type defined:</strong> <code>text/x-pig</code>
+    (PIG code)
+</html>
+</article>
diff --git a/app/gui/html/vendor/codemirror/mode/pig/pig.js b/app/gui/html/vendor/codemirror/mode/pig/pig.js
new file mode 100644
index 0000000..64ac506
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/pig/pig.js
@@ -0,0 +1,185 @@
+/*
+ *      Pig Latin Mode for CodeMirror 2
+ *      @author Prasanth Jayachandran
+ *      @link   https://github.com/prasanthj/pig-codemirror-2
+ *  This implementation is adapted from PL/SQL mode in CodeMirror 2.
+ */
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("pig", function(_config, parserConfig) {
+  var keywords = parserConfig.keywords,
+  builtins = parserConfig.builtins,
+  types = parserConfig.types,
+  multiLineStrings = parserConfig.multiLineStrings;
+
+  var isOperatorChar = /[*+\-%<>=&?:\/!|]/;
+
+  function chain(stream, state, f) {
+    state.tokenize = f;
+    return f(stream, state);
+  }
+
+  var type;
+  function ret(tp, style) {
+    type = tp;
+    return style;
+  }
+
+  function tokenComment(stream, state) {
+    var isEnd = false;
+    var ch;
+    while(ch = stream.next()) {
+      if(ch == "/" && isEnd) {
+        state.tokenize = tokenBase;
+        break;
+      }
+      isEnd = (ch == "*");
+    }
+    return ret("comment", "comment");
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, next, end = false;
+      while((next = stream.next()) != null) {
+        if (next == quote && !escaped) {
+          end = true; break;
+        }
+        escaped = !escaped && next == "\\";
+      }
+      if (end || !(escaped || multiLineStrings))
+        state.tokenize = tokenBase;
+      return ret("string", "error");
+    };
+  }
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+
+    // is a start of string?
+    if (ch == '"' || ch == "'")
+      return chain(stream, state, tokenString(ch));
+    // is it one of the special chars
+    else if(/[\[\]{}\(\),;\.]/.test(ch))
+      return ret(ch);
+    // is it a number?
+    else if(/\d/.test(ch)) {
+      stream.eatWhile(/[\w\.]/);
+      return ret("number", "number");
+    }
+    // multi line comment or operator
+    else if (ch == "/") {
+      if (stream.eat("*")) {
+        return chain(stream, state, tokenComment);
+      }
+      else {
+        stream.eatWhile(isOperatorChar);
+        return ret("operator", "operator");
+      }
+    }
+    // single line comment or operator
+    else if (ch=="-") {
+      if(stream.eat("-")){
+        stream.skipToEnd();
+        return ret("comment", "comment");
+      }
+      else {
+        stream.eatWhile(isOperatorChar);
+        return ret("operator", "operator");
+      }
+    }
+    // is it an operator
+    else if (isOperatorChar.test(ch)) {
+      stream.eatWhile(isOperatorChar);
+      return ret("operator", "operator");
+    }
+    else {
+      // get the while word
+      stream.eatWhile(/[\w\$_]/);
+      // is it one of the listed keywords?
+      if (keywords && keywords.propertyIsEnumerable(stream.current().toUpperCase())) {
+        if (stream.eat(")") || stream.eat(".")) {
+          //keywords can be used as variables like flatten(group), group.$0 etc..
+        }
+        else {
+          return ("keyword", "keyword");
+        }
+      }
+      // is it one of the builtin functions?
+      if (builtins && builtins.propertyIsEnumerable(stream.current().toUpperCase()))
+      {
+        return ("keyword", "variable-2");
+      }
+      // is it one of the listed types?
+      if (types && types.propertyIsEnumerable(stream.current().toUpperCase()))
+        return ("keyword", "variable-3");
+      // default is a 'variable'
+      return ret("variable", "pig-word");
+    }
+  }
+
+  // Interface
+  return {
+    startState: function() {
+      return {
+        tokenize: tokenBase,
+        startOfLine: true
+      };
+    },
+
+    token: function(stream, state) {
+      if(stream.eatSpace()) return null;
+      var style = state.tokenize(stream, state);
+      return style;
+    }
+  };
+});
+
+(function() {
+  function keywords(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+
+  // builtin funcs taken from trunk revision 1303237
+  var pBuiltins = "ABS ACOS ARITY ASIN ATAN AVG BAGSIZE BINSTORAGE BLOOM BUILDBLOOM CBRT CEIL "
+    + "CONCAT COR COS COSH COUNT COUNT_STAR COV CONSTANTSIZE CUBEDIMENSIONS DIFF DISTINCT DOUBLEABS "
+    + "DOUBLEAVG DOUBLEBASE DOUBLEMAX DOUBLEMIN DOUBLEROUND DOUBLESUM EXP FLOOR FLOATABS FLOATAVG "
+    + "FLOATMAX FLOATMIN FLOATROUND FLOATSUM GENERICINVOKER INDEXOF INTABS INTAVG INTMAX INTMIN "
+    + "INTSUM INVOKEFORDOUBLE INVOKEFORFLOAT INVOKEFORINT INVOKEFORLONG INVOKEFORSTRING INVOKER "
+    + "ISEMPTY JSONLOADER JSONMETADATA JSONSTORAGE LAST_INDEX_OF LCFIRST LOG LOG10 LOWER LONGABS "
+    + "LONGAVG LONGMAX LONGMIN LONGSUM MAX MIN MAPSIZE MONITOREDUDF NONDETERMINISTIC OUTPUTSCHEMA  "
+    + "PIGSTORAGE PIGSTREAMING RANDOM REGEX_EXTRACT REGEX_EXTRACT_ALL REPLACE ROUND SIN SINH SIZE "
+    + "SQRT STRSPLIT SUBSTRING SUM STRINGCONCAT STRINGMAX STRINGMIN STRINGSIZE TAN TANH TOBAG "
+    + "TOKENIZE TOMAP TOP TOTUPLE TRIM TEXTLOADER TUPLESIZE UCFIRST UPPER UTF8STORAGECONVERTER ";
+
+  // taken from QueryLexer.g
+  var pKeywords = "VOID IMPORT RETURNS DEFINE LOAD FILTER FOREACH ORDER CUBE DISTINCT COGROUP "
+    + "JOIN CROSS UNION SPLIT INTO IF OTHERWISE ALL AS BY USING INNER OUTER ONSCHEMA PARALLEL "
+    + "PARTITION GROUP AND OR NOT GENERATE FLATTEN ASC DESC IS STREAM THROUGH STORE MAPREDUCE "
+    + "SHIP CACHE INPUT OUTPUT STDERROR STDIN STDOUT LIMIT SAMPLE LEFT RIGHT FULL EQ GT LT GTE LTE "
+    + "NEQ MATCHES TRUE FALSE DUMP";
+
+  // data types
+  var pTypes = "BOOLEAN INT LONG FLOAT DOUBLE CHARARRAY BYTEARRAY BAG TUPLE MAP ";
+
+  CodeMirror.defineMIME("text/x-pig", {
+    name: "pig",
+    builtins: keywords(pBuiltins),
+    keywords: keywords(pKeywords),
+    types: keywords(pTypes)
+  });
+
+  CodeMirror.registerHelper("hintWords", "pig", (pBuiltins + pTypes + pKeywords).split(" "));
+}());
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/properties/index.html b/app/gui/html/vendor/codemirror/mode/properties/index.html
new file mode 100644
index 0000000..40ee1a3
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/properties/index.html
@@ -0,0 +1,53 @@
+<!doctype html>
+
+<title>CodeMirror: Properties files mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="properties.js"></script>
+<style>.CodeMirror {border-top: 1px solid #ddd; border-bottom: 1px solid #ddd;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Properties files</a>
+  </ul>
+</div>
+
+<article>
+<h2>Properties files mode</h2>
+<form><textarea id="code" name="code">
+# This is a properties file
+a.key = A value
+another.key = http://example.com
+! Exclamation mark as comment
+but.not=Within ! A value # indeed
+   # Spaces at the beginning of a line
+   spaces.before.key=value
+backslash=Used for multi\
+          line entries,\
+          that's convenient.
+# Unicode sequences
+unicode.key=This is \u0020 Unicode
+no.multiline=here
+# Colons
+colons : can be used too
+# Spaces
+spaces\ in\ keys=Not very common...
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-properties</code>,
+    <code>text/x-ini</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/properties/properties.js b/app/gui/html/vendor/codemirror/mode/properties/properties.js
new file mode 100644
index 0000000..6dfe06f
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/properties/properties.js
@@ -0,0 +1,75 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("properties", function() {
+  return {
+    token: function(stream, state) {
+      var sol = stream.sol() || state.afterSection;
+      var eol = stream.eol();
+
+      state.afterSection = false;
+
+      if (sol) {
+        if (state.nextMultiline) {
+          state.inMultiline = true;
+          state.nextMultiline = false;
+        } else {
+          state.position = "def";
+        }
+      }
+
+      if (eol && ! state.nextMultiline) {
+        state.inMultiline = false;
+        state.position = "def";
+      }
+
+      if (sol) {
+        while(stream.eatSpace());
+      }
+
+      var ch = stream.next();
+
+      if (sol && (ch === "#" || ch === "!" || ch === ";")) {
+        state.position = "comment";
+        stream.skipToEnd();
+        return "comment";
+      } else if (sol && ch === "[") {
+        state.afterSection = true;
+        stream.skipTo("]"); stream.eat("]");
+        return "header";
+      } else if (ch === "=" || ch === ":") {
+        state.position = "quote";
+        return null;
+      } else if (ch === "\\" && state.position === "quote") {
+        if (stream.next() !== "u") {    // u = Unicode sequence \u1234
+          // Multiline value
+          state.nextMultiline = true;
+        }
+      }
+
+      return state.position;
+    },
+
+    startState: function() {
+      return {
+        position : "def",       // Current position, "def", "quote" or "comment"
+        nextMultiline : false,  // Is the next line multiline value
+        inMultiline : false,    // Is the current line a multiline value
+        afterSection : false    // Did we just open a section
+      };
+    }
+
+  };
+});
+
+CodeMirror.defineMIME("text/x-properties", "properties");
+CodeMirror.defineMIME("text/x-ini", "properties");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/puppet/index.html b/app/gui/html/vendor/codemirror/mode/puppet/index.html
new file mode 100644
index 0000000..f307636
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/puppet/index.html
@@ -0,0 +1,121 @@
+<!doctype html>
+
+<title>CodeMirror: Puppet mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="puppet.js"></script>
+<style>
+      .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+      .cm-s-default span.cm-arrow { color: red; }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Puppet</a>
+  </ul>
+</div>
+
+<article>
+<h2>Puppet mode</h2>
+<form><textarea id="code" name="code">
+# == Class: automysqlbackup
+#
+# Puppet module to install AutoMySQLBackup for periodic MySQL backups.
+#
+# class { 'automysqlbackup':
+#   backup_dir => '/mnt/backups',
+# }
+#
+
+class automysqlbackup (
+  $bin_dir = $automysqlbackup::params::bin_dir,
+  $etc_dir = $automysqlbackup::params::etc_dir,
+  $backup_dir = $automysqlbackup::params::backup_dir,
+  $install_multicore = undef,
+  $config = {},
+  $config_defaults = {},
+) inherits automysqlbackup::params {
+
+# Ensure valid paths are assigned
+  validate_absolute_path($bin_dir)
+  validate_absolute_path($etc_dir)
+  validate_absolute_path($backup_dir)
+
+# Create a subdirectory in /etc for config files
+  file { $etc_dir:
+    ensure => directory,
+    owner => 'root',
+    group => 'root',
+    mode => '0750',
+  }
+
+# Create an example backup file, useful for reference
+  file { "${etc_dir}/automysqlbackup.conf.example":
+    ensure => file,
+    owner => 'root',
+    group => 'root',
+    mode => '0660',
+    source => 'puppet:///modules/automysqlbackup/automysqlbackup.conf',
+  }
+
+# Add files from the developer
+  file { "${etc_dir}/AMB_README":
+    ensure => file,
+    source => 'puppet:///modules/automysqlbackup/AMB_README',
+  }
+  file { "${etc_dir}/AMB_LICENSE":
+    ensure => file,
+    source => 'puppet:///modules/automysqlbackup/AMB_LICENSE',
+  }
+
+# Install the actual binary file
+  file { "${bin_dir}/automysqlbackup":
+    ensure => file,
+    owner => 'root',
+    group => 'root',
+    mode => '0755',
+    source => 'puppet:///modules/automysqlbackup/automysqlbackup',
+  }
+
+# Create the base backup directory
+  file { $backup_dir:
+    ensure => directory,
+    owner => 'root',
+    group => 'root',
+    mode => '0755',
+  }
+
+# If you'd like to keep your config in hiera and pass it to this class
+  if !empty($config) {
+    create_resources('automysqlbackup::backup', $config, $config_defaults)
+  }
+
+# If using RedHat family, must have the RPMforge repo's enabled
+  if $install_multicore {
+    package { ['pigz', 'pbzip2']: ensure => installed }
+  }
+
+}
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: "text/x-puppet",
+        matchBrackets: true,
+        indentUnit: 4
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-puppet</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/puppet/puppet.js b/app/gui/html/vendor/codemirror/mode/puppet/puppet.js
new file mode 100644
index 0000000..da8823e
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/puppet/puppet.js
@@ -0,0 +1,217 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("puppet", function () {
+  // Stores the words from the define method
+  var words = {};
+  // Taken, mostly, from the Puppet official variable standards regex
+  var variable_regex = /({)?([a-z][a-z0-9_]*)?((::[a-z][a-z0-9_]*)*::)?[a-zA-Z0-9_]+(})?/;
+
+  // Takes a string of words separated by spaces and adds them as
+  // keys with the value of the first argument 'style'
+  function define(style, string) {
+    var split = string.split(' ');
+    for (var i = 0; i < split.length; i++) {
+      words[split[i]] = style;
+    }
+  }
+
+  // Takes commonly known puppet types/words and classifies them to a style
+  define('keyword', 'class define site node include import inherits');
+  define('keyword', 'case if else in and elsif default or');
+  define('atom', 'false true running present absent file directory undef');
+  define('builtin', 'action augeas burst chain computer cron destination dport exec ' +
+    'file filebucket group host icmp iniface interface jump k5login limit log_level ' +
+    'log_prefix macauthorization mailalias maillist mcx mount nagios_command ' +
+    'nagios_contact nagios_contactgroup nagios_host nagios_hostdependency ' +
+    'nagios_hostescalation nagios_hostextinfo nagios_hostgroup nagios_service ' +
+    'nagios_servicedependency nagios_serviceescalation nagios_serviceextinfo ' +
+    'nagios_servicegroup nagios_timeperiod name notify outiface package proto reject ' +
+    'resources router schedule scheduled_task selboolean selmodule service source ' +
+    'sport ssh_authorized_key sshkey stage state table tidy todest toports tosource ' +
+    'user vlan yumrepo zfs zone zpool');
+
+  // After finding a start of a string ('|") this function attempts to find the end;
+  // If a variable is encountered along the way, we display it differently when it
+  // is encapsulated in a double-quoted string.
+  function tokenString(stream, state) {
+    var current, prev, found_var = false;
+    while (!stream.eol() && (current = stream.next()) != state.pending) {
+      if (current === '$' && prev != '\\' && state.pending == '"') {
+        found_var = true;
+        break;
+      }
+      prev = current;
+    }
+    if (found_var) {
+      stream.backUp(1);
+    }
+    if (current == state.pending) {
+      state.continueString = false;
+    } else {
+      state.continueString = true;
+    }
+    return "string";
+  }
+
+  // Main function
+  function tokenize(stream, state) {
+    // Matches one whole word
+    var word = stream.match(/[\w]+/, false);
+    // Matches attributes (i.e. ensure => present ; 'ensure' would be matched)
+    var attribute = stream.match(/(\s+)?\w+\s+=>.*/, false);
+    // Matches non-builtin resource declarations
+    // (i.e. "apache::vhost {" or "mycustomclasss {" would be matched)
+    var resource = stream.match(/(\s+)?[\w:_]+(\s+)?{/, false);
+    // Matches virtual and exported resources (i.e. @@user { ; and the like)
+    var special_resource = stream.match(/(\s+)?[@]{1,2}[\w:_]+(\s+)?{/, false);
+
+    // Finally advance the stream
+    var ch = stream.next();
+
+    // Have we found a variable?
+    if (ch === '$') {
+      if (stream.match(variable_regex)) {
+        // If so, and its in a string, assign it a different color
+        return state.continueString ? 'variable-2' : 'variable';
+      }
+      // Otherwise return an invalid variable
+      return "error";
+    }
+    // Should we still be looking for the end of a string?
+    if (state.continueString) {
+      // If so, go through the loop again
+      stream.backUp(1);
+      return tokenString(stream, state);
+    }
+    // Are we in a definition (class, node, define)?
+    if (state.inDefinition) {
+      // If so, return def (i.e. for 'class myclass {' ; 'myclass' would be matched)
+      if (stream.match(/(\s+)?[\w:_]+(\s+)?/)) {
+        return 'def';
+      }
+      // Match the rest it the next time around
+      stream.match(/\s+{/);
+      state.inDefinition = false;
+    }
+    // Are we in an 'include' statement?
+    if (state.inInclude) {
+      // Match and return the included class
+      stream.match(/(\s+)?\S+(\s+)?/);
+      state.inInclude = false;
+      return 'def';
+    }
+    // Do we just have a function on our hands?
+    // In 'ensure_resource("myclass")', 'ensure_resource' is matched
+    if (stream.match(/(\s+)?\w+\(/)) {
+      stream.backUp(1);
+      return 'def';
+    }
+    // Have we matched the prior attribute regex?
+    if (attribute) {
+      stream.match(/(\s+)?\w+/);
+      return 'tag';
+    }
+    // Do we have Puppet specific words?
+    if (word && words.hasOwnProperty(word)) {
+      // Negates the initial next()
+      stream.backUp(1);
+      // Acutally move the stream
+      stream.match(/[\w]+/);
+      // We want to process these words differently
+      // do to the importance they have in Puppet
+      if (stream.match(/\s+\S+\s+{/, false)) {
+        state.inDefinition = true;
+      }
+      if (word == 'include') {
+        state.inInclude = true;
+      }
+      // Returns their value as state in the prior define methods
+      return words[word];
+    }
+    // Is there a match on a reference?
+    if (/(\s+)?[A-Z]/.test(word)) {
+      // Negate the next()
+      stream.backUp(1);
+      // Match the full reference
+      stream.match(/(\s+)?[A-Z][\w:_]+/);
+      return 'def';
+    }
+    // Have we matched the prior resource regex?
+    if (resource) {
+      stream.match(/(\s+)?[\w:_]+/);
+      return 'def';
+    }
+    // Have we matched the prior special_resource regex?
+    if (special_resource) {
+      stream.match(/(\s+)?[@]{1,2}/);
+      return 'special';
+    }
+    // Match all the comments. All of them.
+    if (ch == "#") {
+      stream.skipToEnd();
+      return "comment";
+    }
+    // Have we found a string?
+    if (ch == "'" || ch == '"') {
+      // Store the type (single or double)
+      state.pending = ch;
+      // Perform the looping function to find the end
+      return tokenString(stream, state);
+    }
+    // Match all the brackets
+    if (ch == '{' || ch == '}') {
+      return 'bracket';
+    }
+    // Match characters that we are going to assume
+    // are trying to be regex
+    if (ch == '/') {
+      stream.match(/.*\//);
+      return 'variable-3';
+    }
+    // Match all the numbers
+    if (ch.match(/[0-9]/)) {
+      stream.eatWhile(/[0-9]+/);
+      return 'number';
+    }
+    // Match the '=' and '=>' operators
+    if (ch == '=') {
+      if (stream.peek() == '>') {
+          stream.next();
+      }
+      return "operator";
+    }
+    // Keep advancing through all the rest
+    stream.eatWhile(/[\w-]/);
+    // Return a blank line for everything else
+    return null;
+  }
+  // Start it all
+  return {
+    startState: function () {
+      var state = {};
+      state.inDefinition = false;
+      state.inInclude = false;
+      state.continueString = false;
+      state.pending = false;
+      return state;
+    },
+    token: function (stream, state) {
+      // Strip the spaces, but regex will account for them eitherway
+      if (stream.eatSpace()) return null;
+      // Go through the main process
+      return tokenize(stream, state);
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/x-puppet", "puppet");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/python/index.html b/app/gui/html/vendor/codemirror/mode/python/index.html
new file mode 100644
index 0000000..a1d6d2d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/python/index.html
@@ -0,0 +1,186 @@
+<!doctype html>
+
+<title>CodeMirror: Python mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="python.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Python</a>
+  </ul>
+</div>
+
+<article>
+<h2>Python mode</h2>
+
+    <div><textarea id="code" name="code">
+# Literals
+1234
+0.0e101
+.123
+0b01010011100
+0o01234567
+0x0987654321abcdef
+7
+2147483647
+3L
+79228162514264337593543950336L
+0x100000000L
+79228162514264337593543950336
+0xdeadbeef
+3.14j
+10.j
+10j
+.001j
+1e100j
+3.14e-10j
+
+
+# String Literals
+'For\''
+"God\""
+"""so loved
+the world"""
+'''that he gave
+his only begotten\' '''
+'that whosoever believeth \
+in him'
+''
+
+# Identifiers
+__a__
+a.b
+a.b.c
+
+# Operators
++ - * / % & | ^ ~ < >
+== != <= >= <> << >> // **
+and or not in is
+
+# Delimiters
+() [] {} , : ` = ; @ .  # Note that @ and . require the proper context.
++= -= *= /= %= &= |= ^=
+//= >>= <<= **=
+
+# Keywords
+as assert break class continue def del elif else except
+finally for from global if import lambda pass raise
+return try while with yield
+
+# Python 2 Keywords (otherwise Identifiers)
+exec print
+
+# Python 3 Keywords (otherwise Identifiers)
+nonlocal
+
+# Types
+bool classmethod complex dict enumerate float frozenset int list object
+property reversed set slice staticmethod str super tuple type
+
+# Python 2 Types (otherwise Identifiers)
+basestring buffer file long unicode xrange
+
+# Python 3 Types (otherwise Identifiers)
+bytearray bytes filter map memoryview open range zip
+
+# Some Example code
+import os
+from package import ParentClass
+
+ at nonsenseDecorator
+def doesNothing():
+    pass
+
+class ExampleClass(ParentClass):
+    @staticmethod
+    def example(inputStr):
+        a = list(inputStr)
+        a.reverse()
+        return ''.join(a)
+
+    def __init__(self, mixin = 'Hello'):
+        self.mixin = mixin
+
+</textarea></div>
+
+
+<h2>Cython mode</h2>
+
+<div><textarea id="code-cython" name="code-cython">
+
+import numpy as np
+cimport cython
+from libc.math cimport sqrt
+
+ at cython.boundscheck(False)
+ at cython.wraparound(False)
+def pairwise_cython(double[:, ::1] X):
+    cdef int M = X.shape[0]
+    cdef int N = X.shape[1]
+    cdef double tmp, d
+    cdef double[:, ::1] D = np.empty((M, M), dtype=np.float64)
+    for i in range(M):
+        for j in range(M):
+            d = 0.0
+            for k in range(N):
+                tmp = X[i, k] - X[j, k]
+                d += tmp * tmp
+            D[i, j] = sqrt(d)
+    return np.asarray(D)
+
+</textarea></div>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: {name: "python",
+               version: 2,
+               singleLineStringErrors: false},
+        lineNumbers: true,
+        indentUnit: 4,
+        matchBrackets: true
+    });
+
+    CodeMirror.fromTextArea(document.getElementById("code-cython"), {
+        mode: {name: "text/x-cython",
+               version: 2,
+               singleLineStringErrors: false},
+        lineNumbers: true,
+        indentUnit: 4,
+        matchBrackets: true
+      });
+    </script>
+    <h2>Configuration Options for Python mode:</h2>
+    <ul>
+      <li>version - 2/3 - The version of Python to recognize.  Default is 2.</li>
+      <li>singleLineStringErrors - true/false - If you have a single-line string that is not terminated at the end of the line, this will show subsequent lines as errors if true, otherwise it will consider the newline as the end of the string. Default is false.</li>
+      <li>hangingIndent - int - If you want to write long arguments to a function starting on a new line, how much that line should be indented. Defaults to one normal indentation unit.</li>
+    </ul>
+    <h2>Advanced Configuration Options:</h2>
+    <p>Usefull for superset of python syntax like Enthought enaml, IPython magics and  questionmark help</p>
+    <ul>
+      <li>singleOperators - RegEx - Regular Expression for single operator matching,  default : <pre>^[\\+\\-\\*/%&|\\^~<>!]</pre></li>
+      <li>singleDelimiters - RegEx - Regular Expression for single delimiter matching, default :  <pre>^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]</pre></li>
+      <li>doubleOperators - RegEx - Regular Expression for double operators matching, default : <pre>^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))</pre></li>
+      <li>doubleDelimiters - RegEx - Regular Expressoin for double delimiters matching, default : <pre>^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))</pre></li>
+      <li>tripleDelimiters - RegEx - Regular Expression for triple delimiters matching, default : <pre>^((//=)|(>>=)|(<<=)|(\\*\\*=))</pre></li>
+      <li>identifiers - RegEx - Regular Expression for identifier, default : <pre>^[_A-Za-z][_A-Za-z0-9]*</pre></li>
+      <li>extra_keywords - list of string - List of extra words ton consider as keywords</li>
+      <li>extra_builtins - list of string - List of extra words ton consider as builtins</li>
+    </ul>
+
+
+    <p><strong>MIME types defined:</strong> <code>text/x-python</code> and <code>text/x-cython</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/python/python.js b/app/gui/html/vendor/codemirror/mode/python/python.js
new file mode 100644
index 0000000..f5530bc
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/python/python.js
@@ -0,0 +1,388 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+
+CodeMirror.defineMode("python", function(conf, parserConf) {
+    var ERRORCLASS = 'error';
+
+    function wordRegexp(words) {
+        return new RegExp("^((" + words.join(")|(") + "))\\b");
+    }
+
+    var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/%&|\\^~<>!]");
+    var singleDelimiters = parserConf.singleDelimiters || new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]');
+    var doubleOperators = parserConf.doubleOperators || new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
+    var doubleDelimiters = parserConf.doubleDelimiters || new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
+    var tripleDelimiters = parserConf.tripleDelimiters || new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))");
+    var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
+    var hangingIndent = parserConf.hangingIndent || parserConf.indentUnit;
+
+    var wordOperators = wordRegexp(['and', 'or', 'not', 'is', 'in']);
+    var commonkeywords = ['as', 'assert', 'break', 'class', 'continue',
+                          'def', 'del', 'elif', 'else', 'except', 'finally',
+                          'for', 'from', 'global', 'if', 'import',
+                          'lambda', 'pass', 'raise', 'return',
+                          'try', 'while', 'with', 'yield'];
+    var commonBuiltins = ['abs', 'all', 'any', 'bin', 'bool', 'bytearray', 'callable', 'chr',
+                          'classmethod', 'compile', 'complex', 'delattr', 'dict', 'dir', 'divmod',
+                          'enumerate', 'eval', 'filter', 'float', 'format', 'frozenset',
+                          'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id',
+                          'input', 'int', 'isinstance', 'issubclass', 'iter', 'len',
+                          'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next',
+                          'object', 'oct', 'open', 'ord', 'pow', 'property', 'range',
+                          'repr', 'reversed', 'round', 'set', 'setattr', 'slice',
+                          'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple',
+                          'type', 'vars', 'zip', '__import__', 'NotImplemented',
+                          'Ellipsis', '__debug__'];
+    var py2 = {'builtins': ['apply', 'basestring', 'buffer', 'cmp', 'coerce', 'execfile',
+                            'file', 'intern', 'long', 'raw_input', 'reduce', 'reload',
+                            'unichr', 'unicode', 'xrange', 'False', 'True', 'None'],
+               'keywords': ['exec', 'print']};
+    var py3 = {'builtins': ['ascii', 'bytes', 'exec', 'print'],
+               'keywords': ['nonlocal', 'False', 'True', 'None']};
+
+    if(parserConf.extra_keywords != undefined){
+        commonkeywords = commonkeywords.concat(parserConf.extra_keywords);
+    }
+    if(parserConf.extra_builtins != undefined){
+        commonBuiltins = commonBuiltins.concat(parserConf.extra_builtins);
+    }
+    if (!!parserConf.version && parseInt(parserConf.version, 10) === 3) {
+        commonkeywords = commonkeywords.concat(py3.keywords);
+        commonBuiltins = commonBuiltins.concat(py3.builtins);
+        var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i");
+    } else {
+        commonkeywords = commonkeywords.concat(py2.keywords);
+        commonBuiltins = commonBuiltins.concat(py2.builtins);
+        var stringPrefixes = new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i");
+    }
+    var keywords = wordRegexp(commonkeywords);
+    var builtins = wordRegexp(commonBuiltins);
+
+    var indentInfo = null;
+
+    // tokenizers
+    function tokenBase(stream, state) {
+        // Handle scope changes
+        if (stream.sol()) {
+            var scopeOffset = state.scopes[0].offset;
+            if (stream.eatSpace()) {
+                var lineOffset = stream.indentation();
+                if (lineOffset > scopeOffset) {
+                    indentInfo = 'indent';
+                } else if (lineOffset < scopeOffset) {
+                    indentInfo = 'dedent';
+                }
+                return null;
+            } else {
+                if (scopeOffset > 0) {
+                    dedent(stream, state);
+                }
+            }
+        }
+        if (stream.eatSpace()) {
+            return null;
+        }
+
+        var ch = stream.peek();
+
+        // Handle Comments
+        if (ch === '#') {
+            stream.skipToEnd();
+            return 'comment';
+        }
+
+        // Handle Number Literals
+        if (stream.match(/^[0-9\.]/, false)) {
+            var floatLiteral = false;
+            // Floats
+            if (stream.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; }
+            if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; }
+            if (stream.match(/^\.\d+/)) { floatLiteral = true; }
+            if (floatLiteral) {
+                // Float literals may be "imaginary"
+                stream.eat(/J/i);
+                return 'number';
+            }
+            // Integers
+            var intLiteral = false;
+            // Hex
+            if (stream.match(/^0x[0-9a-f]+/i)) { intLiteral = true; }
+            // Binary
+            if (stream.match(/^0b[01]+/i)) { intLiteral = true; }
+            // Octal
+            if (stream.match(/^0o[0-7]+/i)) { intLiteral = true; }
+            // Decimal
+            if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) {
+                // Decimal literals may be "imaginary"
+                stream.eat(/J/i);
+                // TODO - Can you have imaginary longs?
+                intLiteral = true;
+            }
+            // Zero by itself with no other piece of number.
+            if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; }
+            if (intLiteral) {
+                // Integer literals may be "long"
+                stream.eat(/L/i);
+                return 'number';
+            }
+        }
+
+        // Handle Strings
+        if (stream.match(stringPrefixes)) {
+            state.tokenize = tokenStringFactory(stream.current());
+            return state.tokenize(stream, state);
+        }
+
+        // Handle operators and Delimiters
+        if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) {
+            return null;
+        }
+        if (stream.match(doubleOperators)
+            || stream.match(singleOperators)
+            || stream.match(wordOperators)) {
+            return 'operator';
+        }
+        if (stream.match(singleDelimiters)) {
+            return null;
+        }
+
+        if (stream.match(keywords)) {
+            return 'keyword';
+        }
+
+        if (stream.match(builtins)) {
+            return 'builtin';
+        }
+
+        if (stream.match(/^(self|cls)\b/)) {
+            return "variable-2";
+        }
+
+        if (stream.match(identifiers)) {
+            if (state.lastToken == 'def' || state.lastToken == 'class') {
+                return 'def';
+            }
+            return 'variable';
+        }
+
+        // Handle non-detected items
+        stream.next();
+        return ERRORCLASS;
+    }
+
+    function tokenStringFactory(delimiter) {
+        while ('rub'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
+            delimiter = delimiter.substr(1);
+        }
+        var singleline = delimiter.length == 1;
+        var OUTCLASS = 'string';
+
+        function tokenString(stream, state) {
+            while (!stream.eol()) {
+                stream.eatWhile(/[^'"\\]/);
+                if (stream.eat('\\')) {
+                    stream.next();
+                    if (singleline && stream.eol()) {
+                        return OUTCLASS;
+                    }
+                } else if (stream.match(delimiter)) {
+                    state.tokenize = tokenBase;
+                    return OUTCLASS;
+                } else {
+                    stream.eat(/['"]/);
+                }
+            }
+            if (singleline) {
+                if (parserConf.singleLineStringErrors) {
+                    return ERRORCLASS;
+                } else {
+                    state.tokenize = tokenBase;
+                }
+            }
+            return OUTCLASS;
+        }
+        tokenString.isString = true;
+        return tokenString;
+    }
+
+    function indent(stream, state, type) {
+        type = type || 'py';
+        var indentUnit = 0;
+        if (type === 'py') {
+            if (state.scopes[0].type !== 'py') {
+                state.scopes[0].offset = stream.indentation();
+                return;
+            }
+            for (var i = 0; i < state.scopes.length; ++i) {
+                if (state.scopes[i].type === 'py') {
+                    indentUnit = state.scopes[i].offset + conf.indentUnit;
+                    break;
+                }
+            }
+        } else if (stream.match(/\s*($|#)/, false)) {
+            // An open paren/bracket/brace with only space or comments after it
+            // on the line will indent the next line a fixed amount, to make it
+            // easier to put arguments, list items, etc. on their own lines.
+            indentUnit = stream.indentation() + hangingIndent;
+        } else {
+            indentUnit = stream.column() + stream.current().length;
+        }
+        state.scopes.unshift({
+            offset: indentUnit,
+            type: type
+        });
+    }
+
+    function dedent(stream, state, type) {
+        type = type || 'py';
+        if (state.scopes.length == 1) return;
+        if (state.scopes[0].type === 'py') {
+            var _indent = stream.indentation();
+            var _indent_index = -1;
+            for (var i = 0; i < state.scopes.length; ++i) {
+                if (_indent === state.scopes[i].offset) {
+                    _indent_index = i;
+                    break;
+                }
+            }
+            if (_indent_index === -1) {
+                return true;
+            }
+            while (state.scopes[0].offset !== _indent) {
+                state.scopes.shift();
+            }
+            return false;
+        } else {
+            if (type === 'py') {
+                state.scopes[0].offset = stream.indentation();
+                return false;
+            } else {
+                if (state.scopes[0].type != type) {
+                    return true;
+                }
+                state.scopes.shift();
+                return false;
+            }
+        }
+    }
+
+    function tokenLexer(stream, state) {
+        indentInfo = null;
+        var style = state.tokenize(stream, state);
+        var current = stream.current();
+
+        // Handle '.' connected identifiers
+        if (current === '.') {
+            style = stream.match(identifiers, false) ? null : ERRORCLASS;
+            if (style === null && state.lastStyle === 'meta') {
+                // Apply 'meta' style to '.' connected identifiers when
+                // appropriate.
+                style = 'meta';
+            }
+            return style;
+        }
+
+        // Handle decorators
+        if (current === '@') {
+            return stream.match(identifiers, false) ? 'meta' : ERRORCLASS;
+        }
+
+        if ((style === 'variable' || style === 'builtin')
+            && state.lastStyle === 'meta') {
+            style = 'meta';
+        }
+
+        // Handle scope changes.
+        if (current === 'pass' || current === 'return') {
+            state.dedent += 1;
+        }
+        if (current === 'lambda') state.lambda = true;
+        if ((current === ':' && !state.lambda && state.scopes[0].type == 'py')
+            || indentInfo === 'indent') {
+            indent(stream, state);
+        }
+        var delimiter_index = '[({'.indexOf(current);
+        if (delimiter_index !== -1) {
+            indent(stream, state, '])}'.slice(delimiter_index, delimiter_index+1));
+        }
+        if (indentInfo === 'dedent') {
+            if (dedent(stream, state)) {
+                return ERRORCLASS;
+            }
+        }
+        delimiter_index = '])}'.indexOf(current);
+        if (delimiter_index !== -1) {
+            if (dedent(stream, state, current)) {
+                return ERRORCLASS;
+            }
+        }
+        if (state.dedent > 0 && stream.eol() && state.scopes[0].type == 'py') {
+            if (state.scopes.length > 1) state.scopes.shift();
+            state.dedent -= 1;
+        }
+
+        return style;
+    }
+
+    var external = {
+        startState: function(basecolumn) {
+            return {
+              tokenize: tokenBase,
+              scopes: [{offset:basecolumn || 0, type:'py'}],
+              lastStyle: null,
+              lastToken: null,
+              lambda: false,
+              dedent: 0
+          };
+        },
+
+        token: function(stream, state) {
+            var style = tokenLexer(stream, state);
+
+            state.lastStyle = style;
+
+            var current = stream.current();
+            if (current && style) {
+                state.lastToken = current;
+            }
+
+            if (stream.eol() && state.lambda) {
+                state.lambda = false;
+            }
+            return style;
+        },
+
+        indent: function(state) {
+            if (state.tokenize != tokenBase) {
+                return state.tokenize.isString ? CodeMirror.Pass : 0;
+            }
+
+            return state.scopes[0].offset;
+        },
+
+        lineComment: "#",
+        fold: "indent"
+    };
+    return external;
+});
+
+CodeMirror.defineMIME("text/x-python", "python");
+
+var words = function(str){return str.split(' ');};
+
+CodeMirror.defineMIME("text/x-cython", {
+  name: "python",
+  extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+
+                        "extern gil include nogil property public"+
+                        "readonly struct union DEF IF ELIF ELSE")
+});
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/q/index.html b/app/gui/html/vendor/codemirror/mode/q/index.html
new file mode 100644
index 0000000..78ed3d8
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/q/index.html
@@ -0,0 +1,144 @@
+<!doctype html>
+
+<title>CodeMirror: Q mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="q.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Q</a>
+  </ul>
+</div>
+
+<article>
+<h2>Q mode</h2>
+
+
+<div><textarea id="code" name="code">
+/ utilities to quickly load a csv file - for more exhaustive analysis of the csv contents see csvguess.q
+/ 2009.09.20 - updated to match latest csvguess.q 
+
+/ .csv.colhdrs[file] - return a list of colhdrs from file
+/ info:.csv.info[file] - return a table of information about the file
+/ columns are: 
+/	c - column name; ci - column index; t - load type; mw - max width; 
+/	dchar - distinct characters in values; rule - rule that caught the type
+/	maybe - needs checking, _could_ be say a date, but perhaps just a float?
+/ .csv.info0[file;onlycols] - like .csv.info except that it only analyses <onlycols>
+/ example:
+/	info:.csv.info0[file;(.csv.colhdrs file)like"*price"]
+/	info:.csv.infolike[file;"*price"]
+/	show delete from info where t=" "
+/ .csv.data[file;info] - use the info from .csv.info to read the data
+/ .csv.data10[file;info] - like .csv.data but only returns the first 10 rows
+/ bulkload[file;info] - bulk loads file into table DATA (which must be already defined :: DATA:() )
+/ .csv.read[file]/read10[file] - for when you don't care about checking/tweaking the <info> before reading 
+
+\d .csv
+DELIM:","
+ZAPHDRS:0b / lowercase and remove _ from colhdrs (junk characters are always removed)
+WIDTHHDR:25000 / number of characters read to get the header
+READLINES:222 / number of lines read and used to guess the types
+SYMMAXWIDTH:11 / character columns narrower than this are stored as symbols
+SYMMAXGR:10 / max symbol granularity% before we give up and keep as a * string
+FORCECHARWIDTH:30 / every field (of any type) with values this wide or more is forced to character "*"
+DISCARDEMPTY:0b / completely ignore empty columns if true else set them to "C"
+CHUNKSIZE:50000000 / used in fs2 (modified .Q.fs)
+
+k)nameltrim:{$[~@x;.z.s'x;~(*x)in aA:.Q.a,.Q.A;(+/&\~x in aA)_x;x]}
+k)fs2:{[f;s]((-7!s)>){[f;s;x]i:1+last@&0xa=r:1:(s;x;CHUNKSIZE);f@`\:i#r;x+i}[f;s]/0j}
+cleanhdrs:{{$[ZAPHDRS;lower x except"_";x]}x where x in DELIM,.Q.an}
+cancast:{nw:x$"";if[not x in"BXCS";nw:(min 0#;max 0#;::)@\:nw];$[not any nw in x$(11&count y)#y;$[11<count y;not any nw in x$y;1b];0b]}
+
+read:{[file]data[file;info[file]]}  
+read10:{[file]data10[file;info[file]]}  
+
+colhdrs:{[file]
+	`$nameltrim DELIM vs cleanhdrs first read0(file;0;1+first where 0xa=read1(file;0;WIDTHHDR))}
+data:{[file;info]
+	(exec c from info where not t=" ")xcol(exec t from info;enlist DELIM)0:file}
+data10:{[file;info]
+	data[;info](file;0;1+last 11#where 0xa=read1(file;0;15*WIDTHHDR))}
+info0:{[file;onlycols]
+	colhdrs:`$nameltrim DELIM vs cleanhdrs first head:read0(file;0;1+last where 0xa=read1(file;0;WIDTHHDR));
+	loadfmts:(count colhdrs)#"S";if[count onlycols;loadfmts[where not colhdrs in onlycols]:"C"];
+	breaks:where 0xa=read1(file;0;floor(10+READLINES)*WIDTHHDR%count head);
+	nas:count as:colhdrs xcol(loadfmts;enlist DELIM)0:(file;0;1+last((1+READLINES)&count breaks)#breaks);
+	info:([]c:key flip as;v:value flip as);as:();
+	reserved:key`.q;reserved,:.Q.res;reserved,:`i;
+	info:update res:c in reserved from info;
+	info:update ci:i,t:"?",ipa:0b,mdot:0,mw:0,rule:0,gr:0,ndv:0,maybe:0b,empty:0b,j10:0b,j12:0b from info;
+	info:update ci:`s#ci from info;
+	if[count onlycols;info:update t:" ",rule:10 from info where not c in onlycols];
+	info:update sdv:{string(distinct x)except`}peach v from info; 
+	info:update ndv:count each sdv from info;
+	info:update gr:floor 0.5+100*ndv%nas,mw:{max count each x}peach sdv from info where 0<ndv;
+	info:update t:"*",rule:20 from info where mw>.csv.FORCECHARWIDTH; / long values
+	info:update t:"C "[.csv.DISCARDEMPTY],rule:30,empty:1b from info where t="?",mw=0; / empty columns
+	info:update dchar:{asc distinct raze x}peach sdv from info where t="?";
+	info:update mdot:{max sum each"."=x}peach sdv from info where t="?",{"."in x}each dchar;
+	info:update t:"n",rule:40 from info where t="?",{any x in"0123456789"}each dchar; / vaguely numeric..
+	info:update t:"I",rule:50,ipa:1b from info where t="n",mw within 7 15,mdot=3,{all x in".0123456789"}each dchar,.csv.cancast["I"]peach sdv; / ip-address
+	info:update t:"J",rule:60 from info where t="n",mdot=0,{all x in"+-0123456789"}each dchar,.csv.cancast["J"]peach sdv;
+	info:update t:"I",rule:70 from info where t="J",mw<12,.csv.cancast["I"]peach sdv;
+	info:update t:"H",rule:80 from info where t="I",mw<7,.csv.cancast["H"]peach sdv;
+	info:update t:"F",rule:90 from info where t="n",mdot<2,mw>1,.csv.cancast["F"]peach sdv;
+	info:update t:"E",rule:100,maybe:1b from info where t="F",mw<9;
+	info:update t:"M",rule:110,maybe:1b from info where t in"nIHEF",mdot<2,mw within 4 7,.csv.cancast["M"]peach sdv; 
+	info:update t:"D",rule:120,maybe:1b from info where t in"nI",mdot in 0 2,mw within 6 11,.csv.cancast["D"]peach sdv; 
+	info:update t:"V",rule:130,maybe:1b from info where t="I",mw in 5 6,7<count each dchar,{all x like"*[0-9][0-5][0-9][0-5][0-9]"}peach sdv,.csv.cancast["V"]peach sdv; / 235959 12345        
+	info:update t:"U",rule:140,maybe:1b from info where t="H",mw in 3 4,7<count each dchar,{all x like"*[0-9][0-5][0-9]"}peach sdv,.csv.cancast["U"]peach sdv; /2359
+	info:update t:"U",rule:150,maybe:0b from info where t="n",mw in 4 5,mdot=0,{all x like"*[0-9]:[0-5][0-9]"}peach sdv,.csv.cancast["U"]peach sdv;
+	info:update t:"T",rule:160,maybe:0b from info where t="n",mw within 7 12,mdot<2,{all x like"*[0-9]:[0-5][0-9]:[0-5][0-9]*"}peach sdv,.csv.cancast["T"]peach sdv;
+	info:update t:"V",rule:170,maybe:0b from info where t="T",mw in 7 8,mdot=0,.csv.cancast["V"]peach sdv;
+	info:update t:"T",rule:180,maybe:1b from info where t in"EF",mw within 7 10,mdot=1,{all x like"*[0-9][0-5][0-9][0-5][0-9].*"}peach sdv,.csv.cancast["T"]peach sdv;
+	info:update t:"Z",rule:190,maybe:0b from info where t="n",mw within 11 24,mdot<4,.csv.cancast["Z"]peach sdv;
+	info:update t:"P",rule:200,maybe:1b from info where t="n",mw within 12 29,mdot<4,{all x like"[12]*"}peach sdv,.csv.cancast["P"]peach sdv;
+	info:update t:"N",rule:210,maybe:1b from info where t="n",mw within 3 28,mdot=1,.csv.cancast["N"]peach sdv;
+	info:update t:"?",rule:220,maybe:0b from info where t="n"; / reset remaining maybe numeric
+	info:update t:"C",rule:230,maybe:0b from info where t="?",mw=1; / char
+	info:update t:"B",rule:240,maybe:0b from info where t in"HC",mw=1,mdot=0,{$[all x in"01tTfFyYnN";(any"0fFnN"in x)and any"1tTyY"in x;0b]}each dchar; / boolean
+	info:update t:"B",rule:250,maybe:1b from info where t in"HC",mw=1,mdot=0,{all x in"01tTfFyYnN"}each dchar; / boolean
+	info:update t:"X",rule:260,maybe:0b from info where t="?",mw=2,{$[all x in"0123456789abcdefABCDEF";(any .Q.n in x)and any"abcdefABCDEF"in x;0b]}each dchar; /hex
+	info:update t:"S",rule:270,maybe:1b from info where t="?",mw<.csv.SYMMAXWIDTH,mw>1,gr<.csv.SYMMAXGR; / symbols (max width permitting)
+	info:update t:"*",rule:280,maybe:0b from info where t="?"; / the rest as strings
+	/ flag those S/* columns which could be encoded to integers (.Q.j10/x10/j12/x12) to avoid symbols
+	info:update j12:1b from info where t in"S*",mw<13,{all x in .Q.nA}each dchar;
+	info:update j10:1b from info where t in"S*",mw<11,{all x in .Q.b6}each dchar; 
+	select c,ci,t,maybe,empty,res,j10,j12,ipa,mw,mdot,rule,gr,ndv,dchar from info}
+info:info0[;()] / by default don't restrict columns
+infolike:{[file;pattern] info0[file;{x where x like y}[lower colhdrs[file];pattern]]} / .csv.infolike[file;"*time"]
+
+\d .
+/ DATA:()
+bulkload:{[file;info]
+	if[not`DATA in system"v";'`DATA.not.defined];
+	if[count DATA;'`DATA.not.empty];
+	loadhdrs:exec c from info where not t=" ";loadfmts:exec t from info;
+	.csv.fs2[{[file;loadhdrs;loadfmts] `DATA insert $[count DATA;flip loadhdrs!(loadfmts;.csv.DELIM)0:file;loadhdrs xcol(loadfmts;enlist .csv.DELIM)0:file]}[file;loadhdrs;loadfmts]];
+	count DATA}
+@[.:;"\\l csvutil.custom.q";::]; / save your custom settings in csvutil.custom.q to override those set at the beginning of the file 
+</textarea></div>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        matchBrackets: true
+      });
+    </script>
+
+    <p><strong>MIME type defined:</strong> <code>text/x-q</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/q/q.js b/app/gui/html/vendor/codemirror/mode/q/q.js
new file mode 100644
index 0000000..d6e3b66
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/q/q.js
@@ -0,0 +1,136 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("q",function(config){
+  var indentUnit=config.indentUnit,
+      curPunc,
+      keywords=buildRE(["abs","acos","aj","aj0","all","and","any","asc","asin","asof","atan","attr","avg","avgs","bin","by","ceiling","cols","cor","cos","count","cov","cross","csv","cut","delete","deltas","desc","dev","differ","distinct","div","do","each","ej","enlist","eval","except","exec","exit","exp","fby","fills","first","fkeys","flip","floor","from","get","getenv","group","gtime","hclose","hcount","hdel","hopen","hsym","iasc","idesc","if","ij","in","insert","inter","inv","key","keys","last","like","list","lj","load","log","lower","lsq","ltime","ltrim","mavg","max","maxs","mcount","md5","mdev","med","meta","min","mins","mmax","mmin","mmu","mod","msum","neg","next","not","null","or","over","parse","peach","pj","plist","prd","prds","prev","prior","rand","rank","ratios","raze","read0","read1","reciprocal","reverse","rload","rotate","rsave","rtrim","save","scan","select","set","setenv","show","signum","sin","sqrt","ss","ssr","string","sublist","sum","sums","sv","system","tables","tan","til","trim","txf","type","uj","ungroup","union","update","upper","upsert","value","var","view","views","vs","wavg","where","where","while","within","wj","wj1","wsum","xasc","xbar","xcol","xcols","xdesc","xexp","xgroup","xkey","xlog","xprev","xrank"]),
+      E=/[|/&^!+:\\\-*%$=~#;@><,?_\'\"\[\(\]\)\s{}]/;
+  function buildRE(w){return new RegExp("^("+w.join("|")+")$");}
+  function tokenBase(stream,state){
+    var sol=stream.sol(),c=stream.next();
+    curPunc=null;
+    if(sol)
+      if(c=="/")
+        return(state.tokenize=tokenLineComment)(stream,state);
+      else if(c=="\\"){
+        if(stream.eol()||/\s/.test(stream.peek()))
+          return stream.skipToEnd(),/^\\\s*$/.test(stream.current())?(state.tokenize=tokenCommentToEOF)(stream, state):state.tokenize=tokenBase,"comment";
+        else
+          return state.tokenize=tokenBase,"builtin";
+      }
+    if(/\s/.test(c))
+      return stream.peek()=="/"?(stream.skipToEnd(),"comment"):"whitespace";
+    if(c=='"')
+      return(state.tokenize=tokenString)(stream,state);
+    if(c=='`')
+      return stream.eatWhile(/[A-Z|a-z|\d|_|:|\/|\.]/),"symbol";
+    if(("."==c&&/\d/.test(stream.peek()))||/\d/.test(c)){
+      var t=null;
+      stream.backUp(1);
+      if(stream.match(/^\d{4}\.\d{2}(m|\.\d{2}([D|T](\d{2}(:\d{2}(:\d{2}(\.\d{1,9})?)?)?)?)?)/)
+      || stream.match(/^\d+D(\d{2}(:\d{2}(:\d{2}(\.\d{1,9})?)?)?)/)
+      || stream.match(/^\d{2}:\d{2}(:\d{2}(\.\d{1,9})?)?/)
+      || stream.match(/^\d+[ptuv]{1}/))
+        t="temporal";
+      else if(stream.match(/^0[NwW]{1}/)
+      || stream.match(/^0x[\d|a-f|A-F]*/)
+      || stream.match(/^[0|1]+[b]{1}/)
+      || stream.match(/^\d+[chijn]{1}/)
+      || stream.match(/-?\d*(\.\d*)?(e[+\-]?\d+)?(e|f)?/))
+        t="number";
+      return(t&&(!(c=stream.peek())||E.test(c)))?t:(stream.next(),"error");
+    }
+    if(/[A-Z|a-z]|\./.test(c))
+      return stream.eatWhile(/[A-Z|a-z|\.|_|\d]/),keywords.test(stream.current())?"keyword":"variable";
+    if(/[|/&^!+:\\\-*%$=~#;@><\.,?_\']/.test(c))
+      return null;
+    if(/[{}\(\[\]\)]/.test(c))
+      return null;
+    return"error";
+  }
+  function tokenLineComment(stream,state){
+    return stream.skipToEnd(),/\/\s*$/.test(stream.current())?(state.tokenize=tokenBlockComment)(stream,state):(state.tokenize=tokenBase),"comment";
+  }
+  function tokenBlockComment(stream,state){
+    var f=stream.sol()&&stream.peek()=="\\";
+    stream.skipToEnd();
+    if(f&&/^\\\s*$/.test(stream.current()))
+      state.tokenize=tokenBase;
+    return"comment";
+  }
+  function tokenCommentToEOF(stream){return stream.skipToEnd(),"comment";}
+  function tokenString(stream,state){
+    var escaped=false,next,end=false;
+    while((next=stream.next())){
+      if(next=="\""&&!escaped){end=true;break;}
+      escaped=!escaped&&next=="\\";
+    }
+    if(end)state.tokenize=tokenBase;
+    return"string";
+  }
+  function pushContext(state,type,col){state.context={prev:state.context,indent:state.indent,col:col,type:type};}
+  function popContext(state){state.indent=state.context.indent;state.context=state.context.prev;}
+  return{
+    startState:function(){
+      return{tokenize:tokenBase,
+             context:null,
+             indent:0,
+             col:0};
+    },
+    token:function(stream,state){
+      if(stream.sol()){
+        if(state.context&&state.context.align==null)
+          state.context.align=false;
+        state.indent=stream.indentation();
+      }
+      //if (stream.eatSpace()) return null;
+      var style=state.tokenize(stream,state);
+      if(style!="comment"&&state.context&&state.context.align==null&&state.context.type!="pattern"){
+        state.context.align=true;
+      }
+      if(curPunc=="(")pushContext(state,")",stream.column());
+      else if(curPunc=="[")pushContext(state,"]",stream.column());
+      else if(curPunc=="{")pushContext(state,"}",stream.column());
+      else if(/[\]\}\)]/.test(curPunc)){
+        while(state.context&&state.context.type=="pattern")popContext(state);
+        if(state.context&&curPunc==state.context.type)popContext(state);
+      }
+      else if(curPunc=="."&&state.context&&state.context.type=="pattern")popContext(state);
+      else if(/atom|string|variable/.test(style)&&state.context){
+        if(/[\}\]]/.test(state.context.type))
+          pushContext(state,"pattern",stream.column());
+        else if(state.context.type=="pattern"&&!state.context.align){
+          state.context.align=true;
+          state.context.col=stream.column();
+        }
+      }
+      return style;
+    },
+    indent:function(state,textAfter){
+      var firstChar=textAfter&&textAfter.charAt(0);
+      var context=state.context;
+      if(/[\]\}]/.test(firstChar))
+        while (context&&context.type=="pattern")context=context.prev;
+      var closing=context&&firstChar==context.type;
+      if(!context)
+        return 0;
+      else if(context.type=="pattern")
+        return context.col;
+      else if(context.align)
+        return context.col+(closing?0:1);
+      else
+        return context.indent+(closing?0:indentUnit);
+    }
+  };
+});
+CodeMirror.defineMIME("text/x-q","q");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/r/index.html b/app/gui/html/vendor/codemirror/mode/r/index.html
new file mode 100644
index 0000000..f73e13d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/r/index.html
@@ -0,0 +1,86 @@
+<!doctype html>
+
+<title>CodeMirror: R mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="r.js"></script>
+<style>
+      .CodeMirror { border-top: 1px solid silver; border-bottom: 1px solid silver; }
+      .cm-s-default span.cm-semi { color: blue; font-weight: bold; }
+      .cm-s-default span.cm-dollar { color: orange; font-weight: bold; }
+      .cm-s-default span.cm-arrow { color: brown; }
+      .cm-s-default span.cm-arg-is { color: brown; }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">R</a>
+  </ul>
+</div>
+
+<article>
+<h2>R mode</h2>
+<form><textarea id="code" name="code">
+# Code from http://www.mayin.org/ajayshah/KB/R/
+
+# FIRST LEARN ABOUT LISTS --
+X = list(height=5.4, weight=54)
+print("Use default printing --")
+print(X)
+print("Accessing individual elements --")
+cat("Your height is ", X$height, " and your weight is ", X$weight, "\n")
+
+# FUNCTIONS --
+square <- function(x) {
+  return(x*x)
+}
+cat("The square of 3 is ", square(3), "\n")
+
+                 # default value of the arg is set to 5.
+cube <- function(x=5) {
+  return(x*x*x);
+}
+cat("Calling cube with 2 : ", cube(2), "\n")    # will give 2^3
+cat("Calling cube        : ", cube(), "\n")     # will default to 5^3.
+
+# LEARN ABOUT FUNCTIONS THAT RETURN MULTIPLE OBJECTS --
+powers <- function(x) {
+  parcel = list(x2=x*x, x3=x*x*x, x4=x*x*x*x);
+  return(parcel);
+}
+
+X = powers(3);
+print("Showing powers of 3 --"); print(X);
+
+# WRITING THIS COMPACTLY (4 lines instead of 7)
+
+powerful <- function(x) {
+  return(list(x2=x*x, x3=x*x*x, x4=x*x*x*x));
+}
+print("Showing powers of 3 --"); print(powerful(3));
+
+# In R, the last expression in a function is, by default, what is
+# returned. So you could equally just say:
+powerful <- function(x) {list(x2=x*x, x3=x*x*x, x4=x*x*x*x)}
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-rsrc</code>.</p>
+
+    <p>Development of the CodeMirror R mode was kindly sponsored
+    by <a href="http://ubalo.com/">Ubalo</a>, who hold
+    the <a href="LICENSE">license</a>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/r/r.js b/app/gui/html/vendor/codemirror/mode/r/r.js
new file mode 100644
index 0000000..7f4feb2
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/r/r.js
@@ -0,0 +1,157 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("r", function(config) {
+  function wordObj(str) {
+    var words = str.split(" "), res = {};
+    for (var i = 0; i < words.length; ++i) res[words[i]] = true;
+    return res;
+  }
+  var atoms = wordObj("NULL NA Inf NaN NA_integer_ NA_real_ NA_complex_ NA_character_");
+  var builtins = wordObj("list quote bquote eval return call parse deparse");
+  var keywords = wordObj("if else repeat while function for in next break");
+  var blockkeywords = wordObj("if else repeat while function for");
+  var opChars = /[+\-*\/^<>=!&|~$:]/;
+  var curPunc;
+
+  function tokenBase(stream, state) {
+    curPunc = null;
+    var ch = stream.next();
+    if (ch == "#") {
+      stream.skipToEnd();
+      return "comment";
+    } else if (ch == "0" && stream.eat("x")) {
+      stream.eatWhile(/[\da-f]/i);
+      return "number";
+    } else if (ch == "." && stream.eat(/\d/)) {
+      stream.match(/\d*(?:e[+\-]?\d+)?/);
+      return "number";
+    } else if (/\d/.test(ch)) {
+      stream.match(/\d*(?:\.\d+)?(?:e[+\-]\d+)?L?/);
+      return "number";
+    } else if (ch == "'" || ch == '"') {
+      state.tokenize = tokenString(ch);
+      return "string";
+    } else if (ch == "." && stream.match(/.[.\d]+/)) {
+      return "keyword";
+    } else if (/[\w\.]/.test(ch) && ch != "_") {
+      stream.eatWhile(/[\w\.]/);
+      var word = stream.current();
+      if (atoms.propertyIsEnumerable(word)) return "atom";
+      if (keywords.propertyIsEnumerable(word)) {
+        // Block keywords start new blocks, except 'else if', which only starts
+        // one new block for the 'if', no block for the 'else'.
+        if (blockkeywords.propertyIsEnumerable(word) &&
+            !stream.match(/\s*if(\s+|$)/, false))
+          curPunc = "block";
+        return "keyword";
+      }
+      if (builtins.propertyIsEnumerable(word)) return "builtin";
+      return "variable";
+    } else if (ch == "%") {
+      if (stream.skipTo("%")) stream.next();
+      return "variable-2";
+    } else if (ch == "<" && stream.eat("-")) {
+      return "arrow";
+    } else if (ch == "=" && state.ctx.argList) {
+      return "arg-is";
+    } else if (opChars.test(ch)) {
+      if (ch == "$") return "dollar";
+      stream.eatWhile(opChars);
+      return "operator";
+    } else if (/[\(\){}\[\];]/.test(ch)) {
+      curPunc = ch;
+      if (ch == ";") return "semi";
+      return null;
+    } else {
+      return null;
+    }
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      if (stream.eat("\\")) {
+        var ch = stream.next();
+        if (ch == "x") stream.match(/^[a-f0-9]{2}/i);
+        else if ((ch == "u" || ch == "U") && stream.eat("{") && stream.skipTo("}")) stream.next();
+        else if (ch == "u") stream.match(/^[a-f0-9]{4}/i);
+        else if (ch == "U") stream.match(/^[a-f0-9]{8}/i);
+        else if (/[0-7]/.test(ch)) stream.match(/^[0-7]{1,2}/);
+        return "string-2";
+      } else {
+        var next;
+        while ((next = stream.next()) != null) {
+          if (next == quote) { state.tokenize = tokenBase; break; }
+          if (next == "\\") { stream.backUp(1); break; }
+        }
+        return "string";
+      }
+    };
+  }
+
+  function push(state, type, stream) {
+    state.ctx = {type: type,
+                 indent: state.indent,
+                 align: null,
+                 column: stream.column(),
+                 prev: state.ctx};
+  }
+  function pop(state) {
+    state.indent = state.ctx.indent;
+    state.ctx = state.ctx.prev;
+  }
+
+  return {
+    startState: function() {
+      return {tokenize: tokenBase,
+              ctx: {type: "top",
+                    indent: -config.indentUnit,
+                    align: false},
+              indent: 0,
+              afterIdent: false};
+    },
+
+    token: function(stream, state) {
+      if (stream.sol()) {
+        if (state.ctx.align == null) state.ctx.align = false;
+        state.indent = stream.indentation();
+      }
+      if (stream.eatSpace()) return null;
+      var style = state.tokenize(stream, state);
+      if (style != "comment" && state.ctx.align == null) state.ctx.align = true;
+
+      var ctype = state.ctx.type;
+      if ((curPunc == ";" || curPunc == "{" || curPunc == "}") && ctype == "block") pop(state);
+      if (curPunc == "{") push(state, "}", stream);
+      else if (curPunc == "(") {
+        push(state, ")", stream);
+        if (state.afterIdent) state.ctx.argList = true;
+      }
+      else if (curPunc == "[") push(state, "]", stream);
+      else if (curPunc == "block") push(state, "block", stream);
+      else if (curPunc == ctype) pop(state);
+      state.afterIdent = style == "variable" || style == "keyword";
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      if (state.tokenize != tokenBase) return 0;
+      var firstChar = textAfter && textAfter.charAt(0), ctx = state.ctx,
+          closing = firstChar == ctx.type;
+      if (ctx.type == "block") return ctx.indent + (firstChar == "{" ? 0 : config.indentUnit);
+      else if (ctx.align) return ctx.column + (closing ? 0 : 1);
+      else return ctx.indent + (closing ? 0 : config.indentUnit);
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/x-rsrc", "r");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/rpm/changes/index.html b/app/gui/html/vendor/codemirror/mode/rpm/changes/index.html
new file mode 100644
index 0000000..0ade017
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/rpm/changes/index.html
@@ -0,0 +1,66 @@
+<!doctype html>
+
+<title>CodeMirror: RPM changes mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+    <link rel="stylesheet" href="../../../lib/codemirror.css">
+    <script src="../../../lib/codemirror.js"></script>
+    <script src="changes.js"></script>
+    <link rel="stylesheet" href="../../../doc/docs.css">
+    <style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../../index.html">Home</a>
+    <li><a href="../../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../../index.html">Language modes</a>
+    <li><a class=active href="#">RPM changes</a>
+  </ul>
+</div>
+
+<article>
+<h2>RPM changes mode</h2>
+
+    <div><textarea id="code" name="code">
+-------------------------------------------------------------------
+Tue Oct 18 13:58:40 UTC 2011 - misterx at example.com
+
+- Update to r60.3
+- Fixes bug in the reflect package
+  * disallow Interface method on Value obtained via unexported name
+
+-------------------------------------------------------------------
+Thu Oct  6 08:14:24 UTC 2011 - misterx at example.com
+
+- Update to r60.2
+- Fixes memory leak in certain map types
+
+-------------------------------------------------------------------
+Wed Oct  5 14:34:10 UTC 2011 - misterx at example.com
+
+- Tweaks for gdb debugging
+- go.spec changes:
+  - move %go_arch definition to %prep section
+  - pass correct location of go specific gdb pretty printer and
+    functions to cpp as HOST_EXTRA_CFLAGS macro
+  - install go gdb functions & printer
+- gdb-printer.patch
+  - patch linker (src/cmd/ld/dwarf.c) to emit correct location of go
+    gdb functions and pretty printer
+</textarea></div>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: {name: "changes"},
+        lineNumbers: true,
+        indentUnit: 4
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-rpm-changes</code>.</p>
+</article>
diff --git a/app/gui/html/vendor/codemirror/mode/rpm/index.html b/app/gui/html/vendor/codemirror/mode/rpm/index.html
new file mode 100644
index 0000000..e0f501b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/rpm/index.html
@@ -0,0 +1,149 @@
+<!doctype html>
+
+<title>CodeMirror: RPM changes mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+    <link rel="stylesheet" href="../../lib/codemirror.css">
+    <script src="../../lib/codemirror.js"></script>
+    <script src="rpm.js"></script>
+    <link rel="stylesheet" href="../../doc/docs.css">
+    <style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">RPM</a>
+  </ul>
+</div>
+
+<article>
+<h2>RPM changes mode</h2>
+
+    <div><textarea id="code" name="code">
+-------------------------------------------------------------------
+Tue Oct 18 13:58:40 UTC 2011 - misterx at example.com
+
+- Update to r60.3
+- Fixes bug in the reflect package
+  * disallow Interface method on Value obtained via unexported name
+
+-------------------------------------------------------------------
+Thu Oct  6 08:14:24 UTC 2011 - misterx at example.com
+
+- Update to r60.2
+- Fixes memory leak in certain map types
+
+-------------------------------------------------------------------
+Wed Oct  5 14:34:10 UTC 2011 - misterx at example.com
+
+- Tweaks for gdb debugging
+- go.spec changes:
+  - move %go_arch definition to %prep section
+  - pass correct location of go specific gdb pretty printer and
+    functions to cpp as HOST_EXTRA_CFLAGS macro
+  - install go gdb functions & printer
+- gdb-printer.patch
+  - patch linker (src/cmd/ld/dwarf.c) to emit correct location of go
+    gdb functions and pretty printer
+</textarea></div>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: {name: "rpm-changes"},
+        lineNumbers: true,
+        indentUnit: 4
+      });
+    </script>
+
+<h2>RPM spec mode</h2>
+    
+    <div><textarea id="code2" name="code2">
+#
+# spec file for package minidlna
+#
+# Copyright (c) 2011, Sascha Peilicke <saschpe at gmx.de>
+#
+# All modifications and additions to the file contributed by third parties
+# remain the property of their copyright owners, unless otherwise agreed
+# upon. The license for this file, and modifications and additions to the
+# file, is the same license as for the pristine package itself (unless the
+# license for the pristine package is not an Open Source License, in which
+# case the license is the MIT License). An "Open Source License" is a
+# license that conforms to the Open Source Definition (Version 1.9)
+# published by the Open Source Initiative.
+
+
+Name:           libupnp6
+Version:        1.6.13
+Release:        0
+Summary:        Portable Universal Plug and Play (UPnP) SDK
+Group:          System/Libraries
+License:        BSD-3-Clause
+Url:            http://sourceforge.net/projects/pupnp/
+Source0:        http://downloads.sourceforge.net/pupnp/libupnp-%{version}.tar.bz2
+BuildRoot:      %{_tmppath}/%{name}-%{version}-build
+
+%description
+The portable Universal Plug and Play (UPnP) SDK provides support for building
+UPnP-compliant control points, devices, and bridges on several operating
+systems.
+
+%package -n libupnp-devel
+Summary:        Portable Universal Plug and Play (UPnP) SDK
+Group:          Development/Libraries/C and C++
+Provides:       pkgconfig(libupnp)
+Requires:       %{name} = %{version}
+
+%description -n libupnp-devel
+The portable Universal Plug and Play (UPnP) SDK provides support for building
+UPnP-compliant control points, devices, and bridges on several operating
+systems.
+
+%prep
+%setup -n libupnp-%{version}
+
+%build
+%configure --disable-static
+make %{?_smp_mflags}
+
+%install
+%makeinstall
+find %{buildroot} -type f -name '*.la' -exec rm -f {} ';'
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%defattr(-,root,root,-)
+%doc ChangeLog NEWS README TODO
+%{_libdir}/libixml.so.*
+%{_libdir}/libthreadutil.so.*
+%{_libdir}/libupnp.so.*
+
+%files -n libupnp-devel
+%defattr(-,root,root,-)
+%{_libdir}/pkgconfig/libupnp.pc
+%{_libdir}/libixml.so
+%{_libdir}/libthreadutil.so
+%{_libdir}/libupnp.so
+%{_includedir}/upnp/
+
+%changelog</textarea></div>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code2"), {
+        mode: {name: "rpm-spec"},
+        lineNumbers: true,
+        indentUnit: 4
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-rpm-spec</code>, <code>text/x-rpm-changes</code>.</p>
+</article>
diff --git a/app/gui/html/vendor/codemirror/mode/rpm/rpm.js b/app/gui/html/vendor/codemirror/mode/rpm/rpm.js
new file mode 100644
index 0000000..497997c
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/rpm/rpm.js
@@ -0,0 +1,98 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("rpm-changes", function() {
+  var headerSeperator = /^-+$/;
+  var headerLine = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)  ?\d{1,2} \d{2}:\d{2}(:\d{2})? [A-Z]{3,4} \d{4} - /;
+  var simpleEmail = /^[\w+.-]+@[\w.-]+/;
+
+  return {
+    token: function(stream) {
+      if (stream.sol()) {
+        if (stream.match(headerSeperator)) { return 'tag'; }
+        if (stream.match(headerLine)) { return 'tag'; }
+      }
+      if (stream.match(simpleEmail)) { return 'string'; }
+      stream.next();
+      return null;
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/x-rpm-changes", "rpm-changes");
+
+// Quick and dirty spec file highlighting
+
+CodeMirror.defineMode("rpm-spec", function() {
+  var arch = /^(i386|i586|i686|x86_64|ppc64|ppc|ia64|s390x|s390|sparc64|sparcv9|sparc|noarch|alphaev6|alpha|hppa|mipsel)/;
+
+  var preamble = /^(Name|Version|Release|License|Summary|Url|Group|Source|BuildArch|BuildRequires|BuildRoot|AutoReqProv|Provides|Requires(\(\w+\))?|Obsoletes|Conflicts|Recommends|Source\d*|Patch\d*|ExclusiveArch|NoSource|Supplements):/;
+  var section = /^%(debug_package|package|description|prep|build|install|files|clean|changelog|preinstall|preun|postinstall|postun|pre|post|triggerin|triggerun|pretrans|posttrans|verifyscript|check|triggerpostun|triggerprein|trigger)/;
+  var control_flow_complex = /^%(ifnarch|ifarch|if)/; // rpm control flow macros
+  var control_flow_simple = /^%(else|endif)/; // rpm control flow macros
+  var operators = /^(\!|\?|\<\=|\<|\>\=|\>|\=\=|\&\&|\|\|)/; // operators in control flow macros
+
+  return {
+    startState: function () {
+        return {
+          controlFlow: false,
+          macroParameters: false,
+          section: false
+        };
+    },
+    token: function (stream, state) {
+      var ch = stream.peek();
+      if (ch == "#") { stream.skipToEnd(); return "comment"; }
+
+      if (stream.sol()) {
+        if (stream.match(preamble)) { return "preamble"; }
+        if (stream.match(section)) { return "section"; }
+      }
+
+      if (stream.match(/^\$\w+/)) { return "def"; } // Variables like '$RPM_BUILD_ROOT'
+      if (stream.match(/^\$\{\w+\}/)) { return "def"; } // Variables like '${RPM_BUILD_ROOT}'
+
+      if (stream.match(control_flow_simple)) { return "keyword"; }
+      if (stream.match(control_flow_complex)) {
+        state.controlFlow = true;
+        return "keyword";
+      }
+      if (state.controlFlow) {
+        if (stream.match(operators)) { return "operator"; }
+        if (stream.match(/^(\d+)/)) { return "number"; }
+        if (stream.eol()) { state.controlFlow = false; }
+      }
+
+      if (stream.match(arch)) { return "number"; }
+
+      // Macros like '%make_install' or '%attr(0775,root,root)'
+      if (stream.match(/^%[\w]+/)) {
+        if (stream.match(/^\(/)) { state.macroParameters = true; }
+        return "macro";
+      }
+      if (state.macroParameters) {
+        if (stream.match(/^\d+/)) { return "number";}
+        if (stream.match(/^\)/)) {
+          state.macroParameters = false;
+          return "macro";
+        }
+      }
+      if (stream.match(/^%\{\??[\w \-]+\}/)) { return "macro"; } // Macros like '%{defined fedora}'
+
+      //TODO: Include bash script sub-parser (CodeMirror supports that)
+      stream.next();
+      return null;
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/x-rpm-spec", "rpm-spec");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/rst/index.html b/app/gui/html/vendor/codemirror/mode/rst/index.html
new file mode 100644
index 0000000..cb82697
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/rst/index.html
@@ -0,0 +1,535 @@
+<!doctype html>
+
+<title>CodeMirror: reStructuredText mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/mode/overlay.js"></script>
+<script src="rst.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">reStructuredText</a>
+  </ul>
+</div>
+
+<article>
+<h2>reStructuredText mode</h2>
+<form><textarea id="code" name="code">
+.. This is an excerpt from Sphinx documentation: http://sphinx.pocoo.org/_sources/rest.txt
+
+.. highlightlang:: rest
+
+.. _rst-primer:
+
+reStructuredText Primer
+=======================
+
+This section is a brief introduction to reStructuredText (reST) concepts and
+syntax, intended to provide authors with enough information to author documents
+productively.  Since reST was designed to be a simple, unobtrusive markup
+language, this will not take too long.
+
+.. seealso::
+
+   The authoritative `reStructuredText User Documentation
+   <http://docutils.sourceforge.net/rst.html>`_.  The "ref" links in this
+   document link to the description of the individual constructs in the reST
+   reference.
+
+
+Paragraphs
+----------
+
+The paragraph (:duref:`ref <paragraphs>`) is the most basic block in a reST
+document.  Paragraphs are simply chunks of text separated by one or more blank
+lines.  As in Python, indentation is significant in reST, so all lines of the
+same paragraph must be left-aligned to the same level of indentation.
+
+
+.. _inlinemarkup:
+
+Inline markup
+-------------
+
+The standard reST inline markup is quite simple: use
+
+* one asterisk: ``*text*`` for emphasis (italics),
+* two asterisks: ``**text**`` for strong emphasis (boldface), and
+* backquotes: ````text```` for code samples.
+
+If asterisks or backquotes appear in running text and could be confused with
+inline markup delimiters, they have to be escaped with a backslash.
+
+Be aware of some restrictions of this markup:
+
+* it may not be nested,
+* content may not start or end with whitespace: ``* text*`` is wrong,
+* it must be separated from surrounding text by non-word characters.  Use a
+  backslash escaped space to work around that: ``thisis\ *one*\ word``.
+
+These restrictions may be lifted in future versions of the docutils.
+
+reST also allows for custom "interpreted text roles"', which signify that the
+enclosed text should be interpreted in a specific way.  Sphinx uses this to
+provide semantic markup and cross-referencing of identifiers, as described in
+the appropriate section.  The general syntax is ``:rolename:`content```.
+
+Standard reST provides the following roles:
+
+* :durole:`emphasis` -- alternate spelling for ``*emphasis*``
+* :durole:`strong` -- alternate spelling for ``**strong**``
+* :durole:`literal` -- alternate spelling for ````literal````
+* :durole:`subscript` -- subscript text
+* :durole:`superscript` -- superscript text
+* :durole:`title-reference` -- for titles of books, periodicals, and other
+  materials
+
+See :ref:`inline-markup` for roles added by Sphinx.
+
+
+Lists and Quote-like blocks
+---------------------------
+
+List markup (:duref:`ref <bullet-lists>`) is natural: just place an asterisk at
+the start of a paragraph and indent properly.  The same goes for numbered lists;
+they can also be autonumbered using a ``#`` sign::
+
+   * This is a bulleted list.
+   * It has two items, the second
+     item uses two lines.
+
+   1. This is a numbered list.
+   2. It has two items too.
+
+   #. This is a numbered list.
+   #. It has two items too.
+
+
+Nested lists are possible, but be aware that they must be separated from the
+parent list items by blank lines::
+
+   * this is
+   * a list
+
+     * with a nested list
+     * and some subitems
+
+   * and here the parent list continues
+
+Definition lists (:duref:`ref <definition-lists>`) are created as follows::
+
+   term (up to a line of text)
+      Definition of the term, which must be indented
+
+      and can even consist of multiple paragraphs
+
+   next term
+      Description.
+
+Note that the term cannot have more than one line of text.
+
+Quoted paragraphs (:duref:`ref <block-quotes>`) are created by just indenting
+them more than the surrounding paragraphs.
+
+Line blocks (:duref:`ref <line-blocks>`) are a way of preserving line breaks::
+
+   | These lines are
+   | broken exactly like in
+   | the source file.
+
+There are also several more special blocks available:
+
+* field lists (:duref:`ref <field-lists>`)
+* option lists (:duref:`ref <option-lists>`)
+* quoted literal blocks (:duref:`ref <quoted-literal-blocks>`)
+* doctest blocks (:duref:`ref <doctest-blocks>`)
+
+
+Source Code
+-----------
+
+Literal code blocks (:duref:`ref <literal-blocks>`) are introduced by ending a
+paragraph with the special marker ``::``.  The literal block must be indented
+(and, like all paragraphs, separated from the surrounding ones by blank lines)::
+
+   This is a normal text paragraph. The next paragraph is a code sample::
+
+      It is not processed in any way, except
+      that the indentation is removed.
+
+      It can span multiple lines.
+
+   This is a normal text paragraph again.
+
+The handling of the ``::`` marker is smart:
+
+* If it occurs as a paragraph of its own, that paragraph is completely left
+  out of the document.
+* If it is preceded by whitespace, the marker is removed.
+* If it is preceded by non-whitespace, the marker is replaced by a single
+  colon.
+
+That way, the second sentence in the above example's first paragraph would be
+rendered as "The next paragraph is a code sample:".
+
+
+.. _rst-tables:
+
+Tables
+------
+
+Two forms of tables are supported.  For *grid tables* (:duref:`ref
+<grid-tables>`), you have to "paint" the cell grid yourself.  They look like
+this::
+
+   +------------------------+------------+----------+----------+
+   | Header row, column 1   | Header 2   | Header 3 | Header 4 |
+   | (header rows optional) |            |          |          |
+   +========================+============+==========+==========+
+   | body row 1, column 1   | column 2   | column 3 | column 4 |
+   +------------------------+------------+----------+----------+
+   | body row 2             | ...        | ...      |          |
+   +------------------------+------------+----------+----------+
+
+*Simple tables* (:duref:`ref <simple-tables>`) are easier to write, but
+limited: they must contain more than one row, and the first column cannot
+contain multiple lines.  They look like this::
+
+   =====  =====  =======
+   A      B      A and B
+   =====  =====  =======
+   False  False  False
+   True   False  False
+   False  True   False
+   True   True   True
+   =====  =====  =======
+
+
+Hyperlinks
+----------
+
+External links
+^^^^^^^^^^^^^^
+
+Use ```Link text <http://example.com/>`_`` for inline web links.  If the link
+text should be the web address, you don't need special markup at all, the parser
+finds links and mail addresses in ordinary text.
+
+You can also separate the link and the target definition (:duref:`ref
+<hyperlink-targets>`), like this::
+
+   This is a paragraph that contains `a link`_.
+
+   .. _a link: http://example.com/
+
+
+Internal links
+^^^^^^^^^^^^^^
+
+Internal linking is done via a special reST role provided by Sphinx, see the
+section on specific markup, :ref:`ref-role`.
+
+
+Sections
+--------
+
+Section headers (:duref:`ref <sections>`) are created by underlining (and
+optionally overlining) the section title with a punctuation character, at least
+as long as the text::
+
+   =================
+   This is a heading
+   =================
+
+Normally, there are no heading levels assigned to certain characters as the
+structure is determined from the succession of headings.  However, for the
+Python documentation, this convention is used which you may follow:
+
+* ``#`` with overline, for parts
+* ``*`` with overline, for chapters
+* ``=``, for sections
+* ``-``, for subsections
+* ``^``, for subsubsections
+* ``"``, for paragraphs
+
+Of course, you are free to use your own marker characters (see the reST
+documentation), and use a deeper nesting level, but keep in mind that most
+target formats (HTML, LaTeX) have a limited supported nesting depth.
+
+
+Explicit Markup
+---------------
+
+"Explicit markup" (:duref:`ref <explicit-markup-blocks>`) is used in reST for
+most constructs that need special handling, such as footnotes,
+specially-highlighted paragraphs, comments, and generic directives.
+
+An explicit markup block begins with a line starting with ``..`` followed by
+whitespace and is terminated by the next paragraph at the same level of
+indentation.  (There needs to be a blank line between explicit markup and normal
+paragraphs.  This may all sound a bit complicated, but it is intuitive enough
+when you write it.)
+
+
+.. _directives:
+
+Directives
+----------
+
+A directive (:duref:`ref <directives>`) is a generic block of explicit markup.
+Besides roles, it is one of the extension mechanisms of reST, and Sphinx makes
+heavy use of it.
+
+Docutils supports the following directives:
+
+* Admonitions: :dudir:`attention`, :dudir:`caution`, :dudir:`danger`,
+  :dudir:`error`, :dudir:`hint`, :dudir:`important`, :dudir:`note`,
+  :dudir:`tip`, :dudir:`warning` and the generic :dudir:`admonition`.
+  (Most themes style only "note" and "warning" specially.)
+
+* Images:
+
+  - :dudir:`image` (see also Images_ below)
+  - :dudir:`figure` (an image with caption and optional legend)
+
+* Additional body elements:
+
+  - :dudir:`contents` (a local, i.e. for the current file only, table of
+    contents)
+  - :dudir:`container` (a container with a custom class, useful to generate an
+    outer ``<div>`` in HTML)
+  - :dudir:`rubric` (a heading without relation to the document sectioning)
+  - :dudir:`topic`, :dudir:`sidebar` (special highlighted body elements)
+  - :dudir:`parsed-literal` (literal block that supports inline markup)
+  - :dudir:`epigraph` (a block quote with optional attribution line)
+  - :dudir:`highlights`, :dudir:`pull-quote` (block quotes with their own
+    class attribute)
+  - :dudir:`compound` (a compound paragraph)
+
+* Special tables:
+
+  - :dudir:`table` (a table with title)
+  - :dudir:`csv-table` (a table generated from comma-separated values)
+  - :dudir:`list-table` (a table generated from a list of lists)
+
+* Special directives:
+
+  - :dudir:`raw` (include raw target-format markup)
+  - :dudir:`include` (include reStructuredText from another file)
+    -- in Sphinx, when given an absolute include file path, this directive takes
+    it as relative to the source directory
+  - :dudir:`class` (assign a class attribute to the next element) [1]_
+
+* HTML specifics:
+
+  - :dudir:`meta` (generation of HTML ``<meta>`` tags)
+  - :dudir:`title` (override document title)
+
+* Influencing markup:
+
+  - :dudir:`default-role` (set a new default role)
+  - :dudir:`role` (create a new role)
+
+  Since these are only per-file, better use Sphinx' facilities for setting the
+  :confval:`default_role`.
+
+Do *not* use the directives :dudir:`sectnum`, :dudir:`header` and
+:dudir:`footer`.
+
+Directives added by Sphinx are described in :ref:`sphinxmarkup`.
+
+Basically, a directive consists of a name, arguments, options and content. (Keep
+this terminology in mind, it is used in the next chapter describing custom
+directives.)  Looking at this example, ::
+
+   .. function:: foo(x)
+                 foo(y, z)
+      :module: some.module.name
+
+      Return a line of text input from the user.
+
+``function`` is the directive name.  It is given two arguments here, the
+remainder of the first line and the second line, as well as one option
+``module`` (as you can see, options are given in the lines immediately following
+the arguments and indicated by the colons).  Options must be indented to the
+same level as the directive content.
+
+The directive content follows after a blank line and is indented relative to the
+directive start.
+
+
+Images
+------
+
+reST supports an image directive (:dudir:`ref <image>`), used like so::
+
+   .. image:: gnu.png
+      (options)
+
+When used within Sphinx, the file name given (here ``gnu.png``) must either be
+relative to the source file, or absolute which means that they are relative to
+the top source directory.  For example, the file ``sketch/spam.rst`` could refer
+to the image ``images/spam.png`` as ``../images/spam.png`` or
+``/images/spam.png``.
+
+Sphinx will automatically copy image files over to a subdirectory of the output
+directory on building (e.g. the ``_static`` directory for HTML output.)
+
+Interpretation of image size options (``width`` and ``height``) is as follows:
+if the size has no unit or the unit is pixels, the given size will only be
+respected for output channels that support pixels (i.e. not in LaTeX output).
+Other units (like ``pt`` for points) will be used for HTML and LaTeX output.
+
+Sphinx extends the standard docutils behavior by allowing an asterisk for the
+extension::
+
+   .. image:: gnu.*
+
+Sphinx then searches for all images matching the provided pattern and determines
+their type.  Each builder then chooses the best image out of these candidates.
+For instance, if the file name ``gnu.*`` was given and two files :file:`gnu.pdf`
+and :file:`gnu.png` existed in the source tree, the LaTeX builder would choose
+the former, while the HTML builder would prefer the latter.
+
+.. versionchanged:: 0.4
+   Added the support for file names ending in an asterisk.
+
+.. versionchanged:: 0.6
+   Image paths can now be absolute.
+
+
+Footnotes
+---------
+
+For footnotes (:duref:`ref <footnotes>`), use ``[#name]_`` to mark the footnote
+location, and add the footnote body at the bottom of the document after a
+"Footnotes" rubric heading, like so::
+
+   Lorem ipsum [#f1]_ dolor sit amet ... [#f2]_
+
+   .. rubric:: Footnotes
+
+   .. [#f1] Text of the first footnote.
+   .. [#f2] Text of the second footnote.
+
+You can also explicitly number the footnotes (``[1]_``) or use auto-numbered
+footnotes without names (``[#]_``).
+
+
+Citations
+---------
+
+Standard reST citations (:duref:`ref <citations>`) are supported, with the
+additional feature that they are "global", i.e. all citations can be referenced
+from all files.  Use them like so::
+
+   Lorem ipsum [Ref]_ dolor sit amet.
+
+   .. [Ref] Book or article reference, URL or whatever.
+
+Citation usage is similar to footnote usage, but with a label that is not
+numeric or begins with ``#``.
+
+
+Substitutions
+-------------
+
+reST supports "substitutions" (:duref:`ref <substitution-definitions>`), which
+are pieces of text and/or markup referred to in the text by ``|name|``.  They
+are defined like footnotes with explicit markup blocks, like this::
+
+   .. |name| replace:: replacement *text*
+
+or this::
+
+   .. |caution| image:: warning.png
+                :alt: Warning!
+
+See the :duref:`reST reference for substitutions <substitution-definitions>`
+for details.
+
+If you want to use some substitutions for all documents, put them into
+:confval:`rst_prolog` or put them into a separate file and include it into all
+documents you want to use them in, using the :rst:dir:`include` directive.  (Be
+sure to give the include file a file name extension differing from that of other
+source files, to avoid Sphinx finding it as a standalone document.)
+
+Sphinx defines some default substitutions, see :ref:`default-substitutions`.
+
+
+Comments
+--------
+
+Every explicit markup block which isn't a valid markup construct (like the
+footnotes above) is regarded as a comment (:duref:`ref <comments>`).  For
+example::
+
+   .. This is a comment.
+
+You can indent text after a comment start to form multiline comments::
+
+   ..
+      This whole indented block
+      is a comment.
+
+      Still in the comment.
+
+
+Source encoding
+---------------
+
+Since the easiest way to include special characters like em dashes or copyright
+signs in reST is to directly write them as Unicode characters, one has to
+specify an encoding.  Sphinx assumes source files to be encoded in UTF-8 by
+default; you can change this with the :confval:`source_encoding` config value.
+
+
+Gotchas
+-------
+
+There are some problems one commonly runs into while authoring reST documents:
+
+* **Separation of inline markup:** As said above, inline markup spans must be
+  separated from the surrounding text by non-word characters, you have to use a
+  backslash-escaped space to get around that.  See `the reference
+  <http://docutils.sf.net/docs/ref/rst/restructuredtext.html#inline-markup>`_
+  for the details.
+
+* **No nested inline markup:** Something like ``*see :func:`foo`*`` is not
+  possible.
+
+
+.. rubric:: Footnotes
+
+.. [1] When the default domain contains a :rst:dir:`class` directive, this directive
+       will be shadowed.  Therefore, Sphinx re-exports it as :rst:dir:`rst-class`.
+</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+      });
+    </script>
+    <p>
+        The <code>python</code> mode will be used for highlighting blocks
+        containing Python/IPython terminal sessions: blocks starting with
+        <code>>>></code> (for Python) or <code>In [num]:</code> (for
+        IPython).
+
+        Further, the <code>stex</code> mode will be used for highlighting
+        blocks containing LaTex code.
+    </p>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-rst</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/rst/rst.js b/app/gui/html/vendor/codemirror/mode/rst/rst.js
new file mode 100644
index 0000000..0763d4b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/rst/rst.js
@@ -0,0 +1,575 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("../python/python"), require("../stex/stex"), require("../../addon/mode/overlay"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "../python/python", "../stex/stex", "../../addon/mode/overlay"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode('rst', function (config, options) {
+
+  var rx_strong = /^\*\*[^\*\s](?:[^\*]*[^\*\s])?\*\*/;
+  var rx_emphasis = /^\*[^\*\s](?:[^\*]*[^\*\s])?\*/;
+  var rx_literal = /^``[^`\s](?:[^`]*[^`\s])``/;
+
+  var rx_number = /^(?:[\d]+(?:[\.,]\d+)*)/;
+  var rx_positive = /^(?:\s\+[\d]+(?:[\.,]\d+)*)/;
+  var rx_negative = /^(?:\s\-[\d]+(?:[\.,]\d+)*)/;
+
+  var rx_uri_protocol = "[Hh][Tt][Tt][Pp][Ss]?://";
+  var rx_uri_domain = "(?:[\\d\\w.-]+)\\.(?:\\w{2,6})";
+  var rx_uri_path = "(?:/[\\d\\w\\#\\%\\&\\-\\.\\,\\/\\:\\=\\?\\~]+)*";
+  var rx_uri = new RegExp("^" + rx_uri_protocol + rx_uri_domain + rx_uri_path);
+
+  var overlay = {
+    token: function (stream) {
+
+      if (stream.match(rx_strong) && stream.match (/\W+|$/, false))
+        return 'strong';
+      if (stream.match(rx_emphasis) && stream.match (/\W+|$/, false))
+        return 'em';
+      if (stream.match(rx_literal) && stream.match (/\W+|$/, false))
+        return 'string-2';
+      if (stream.match(rx_number))
+        return 'number';
+      if (stream.match(rx_positive))
+        return 'positive';
+      if (stream.match(rx_negative))
+        return 'negative';
+      if (stream.match(rx_uri))
+        return 'link';
+
+      while (stream.next() != null) {
+        if (stream.match(rx_strong, false)) break;
+        if (stream.match(rx_emphasis, false)) break;
+        if (stream.match(rx_literal, false)) break;
+        if (stream.match(rx_number, false)) break;
+        if (stream.match(rx_positive, false)) break;
+        if (stream.match(rx_negative, false)) break;
+        if (stream.match(rx_uri, false)) break;
+      }
+
+      return null;
+    }
+  };
+
+  var mode = CodeMirror.getMode(
+    config, options.backdrop || 'rst-base'
+  );
+
+  return CodeMirror.overlayMode(mode, overlay, true); // combine
+}, 'python', 'stex');
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+CodeMirror.defineMode('rst-base', function (config) {
+
+  ///////////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////////
+
+  function format(string) {
+    var args = Array.prototype.slice.call(arguments, 1);
+    return string.replace(/{(\d+)}/g, function (match, n) {
+      return typeof args[n] != 'undefined' ? args[n] : match;
+    });
+  }
+
+  function AssertException(message) {
+    this.message = message;
+  }
+
+  AssertException.prototype.toString = function () {
+    return 'AssertException: ' + this.message;
+  };
+
+  function assert(expression, message) {
+    if (!expression) throw new AssertException(message);
+    return expression;
+  }
+
+  ///////////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////////
+
+  var mode_python = CodeMirror.getMode(config, 'python');
+  var mode_stex = CodeMirror.getMode(config, 'stex');
+
+  ///////////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////////
+
+  var SEPA = "\\s+";
+  var TAIL = "(?:\\s*|\\W|$)",
+  rx_TAIL = new RegExp(format('^{0}', TAIL));
+
+  var NAME =
+    "(?:[^\\W\\d_](?:[\\w!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)",
+  rx_NAME = new RegExp(format('^{0}', NAME));
+  var NAME_WWS =
+    "(?:[^\\W\\d_](?:[\\w\\s!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)";
+  var REF_NAME = format('(?:{0}|`{1}`)', NAME, NAME_WWS);
+
+  var TEXT1 = "(?:[^\\s\\|](?:[^\\|]*[^\\s\\|])?)";
+  var TEXT2 = "(?:[^\\`]+)",
+  rx_TEXT2 = new RegExp(format('^{0}', TEXT2));
+
+  var rx_section = new RegExp(
+    "^([!'#$%&\"()*+,-./:;<=>?@\\[\\\\\\]^_`{|}~])\\1{3,}\\s*$");
+  var rx_explicit = new RegExp(
+    format('^\\.\\.{0}', SEPA));
+  var rx_link = new RegExp(
+    format('^_{0}:{1}|^__:{1}', REF_NAME, TAIL));
+  var rx_directive = new RegExp(
+    format('^{0}::{1}', REF_NAME, TAIL));
+  var rx_substitution = new RegExp(
+    format('^\\|{0}\\|{1}{2}::{3}', TEXT1, SEPA, REF_NAME, TAIL));
+  var rx_footnote = new RegExp(
+    format('^\\[(?:\\d+|#{0}?|\\*)]{1}', REF_NAME, TAIL));
+  var rx_citation = new RegExp(
+    format('^\\[{0}\\]{1}', REF_NAME, TAIL));
+
+  var rx_substitution_ref = new RegExp(
+    format('^\\|{0}\\|', TEXT1));
+  var rx_footnote_ref = new RegExp(
+    format('^\\[(?:\\d+|#{0}?|\\*)]_', REF_NAME));
+  var rx_citation_ref = new RegExp(
+    format('^\\[{0}\\]_', REF_NAME));
+  var rx_link_ref1 = new RegExp(
+    format('^{0}__?', REF_NAME));
+  var rx_link_ref2 = new RegExp(
+    format('^`{0}`_', TEXT2));
+
+  var rx_role_pre = new RegExp(
+    format('^:{0}:`{1}`{2}', NAME, TEXT2, TAIL));
+  var rx_role_suf = new RegExp(
+    format('^`{1}`:{0}:{2}', NAME, TEXT2, TAIL));
+  var rx_role = new RegExp(
+    format('^:{0}:{1}', NAME, TAIL));
+
+  var rx_directive_name = new RegExp(format('^{0}', REF_NAME));
+  var rx_directive_tail = new RegExp(format('^::{0}', TAIL));
+  var rx_substitution_text = new RegExp(format('^\\|{0}\\|', TEXT1));
+  var rx_substitution_sepa = new RegExp(format('^{0}', SEPA));
+  var rx_substitution_name = new RegExp(format('^{0}', REF_NAME));
+  var rx_substitution_tail = new RegExp(format('^::{0}', TAIL));
+  var rx_link_head = new RegExp("^_");
+  var rx_link_name = new RegExp(format('^{0}|_', REF_NAME));
+  var rx_link_tail = new RegExp(format('^:{0}', TAIL));
+
+  var rx_verbatim = new RegExp('^::\\s*$');
+  var rx_examples = new RegExp('^\\s+(?:>>>|In \\[\\d+\\]:)\\s');
+
+  ///////////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////////
+
+  function to_normal(stream, state) {
+    var token = null;
+
+    if (stream.sol() && stream.match(rx_examples, false)) {
+      change(state, to_mode, {
+        mode: mode_python, local: CodeMirror.startState(mode_python)
+      });
+    } else if (stream.sol() && stream.match(rx_explicit)) {
+      change(state, to_explicit);
+      token = 'meta';
+    } else if (stream.sol() && stream.match(rx_section)) {
+      change(state, to_normal);
+      token = 'header';
+    } else if (phase(state) == rx_role_pre ||
+               stream.match(rx_role_pre, false)) {
+
+      switch (stage(state)) {
+      case 0:
+        change(state, to_normal, context(rx_role_pre, 1));
+        assert(stream.match(/^:/));
+        token = 'meta';
+        break;
+      case 1:
+        change(state, to_normal, context(rx_role_pre, 2));
+        assert(stream.match(rx_NAME));
+        token = 'keyword';
+
+        if (stream.current().match(/^(?:math|latex)/)) {
+          state.tmp_stex = true;
+        }
+        break;
+      case 2:
+        change(state, to_normal, context(rx_role_pre, 3));
+        assert(stream.match(/^:`/));
+        token = 'meta';
+        break;
+      case 3:
+        if (state.tmp_stex) {
+          state.tmp_stex = undefined; state.tmp = {
+            mode: mode_stex, local: CodeMirror.startState(mode_stex)
+          };
+        }
+
+        if (state.tmp) {
+          if (stream.peek() == '`') {
+            change(state, to_normal, context(rx_role_pre, 4));
+            state.tmp = undefined;
+            break;
+          }
+
+          token = state.tmp.mode.token(stream, state.tmp.local);
+          break;
+        }
+
+        change(state, to_normal, context(rx_role_pre, 4));
+        assert(stream.match(rx_TEXT2));
+        token = 'string';
+        break;
+      case 4:
+        change(state, to_normal, context(rx_role_pre, 5));
+        assert(stream.match(/^`/));
+        token = 'meta';
+        break;
+      case 5:
+        change(state, to_normal, context(rx_role_pre, 6));
+        assert(stream.match(rx_TAIL));
+        break;
+      default:
+        change(state, to_normal);
+        assert(stream.current() == '');
+      }
+    } else if (phase(state) == rx_role_suf ||
+               stream.match(rx_role_suf, false)) {
+
+      switch (stage(state)) {
+      case 0:
+        change(state, to_normal, context(rx_role_suf, 1));
+        assert(stream.match(/^`/));
+        token = 'meta';
+        break;
+      case 1:
+        change(state, to_normal, context(rx_role_suf, 2));
+        assert(stream.match(rx_TEXT2));
+        token = 'string';
+        break;
+      case 2:
+        change(state, to_normal, context(rx_role_suf, 3));
+        assert(stream.match(/^`:/));
+        token = 'meta';
+        break;
+      case 3:
+        change(state, to_normal, context(rx_role_suf, 4));
+        assert(stream.match(rx_NAME));
+        token = 'keyword';
+        break;
+      case 4:
+        change(state, to_normal, context(rx_role_suf, 5));
+        assert(stream.match(/^:/));
+        token = 'meta';
+        break;
+      case 5:
+        change(state, to_normal, context(rx_role_suf, 6));
+        assert(stream.match(rx_TAIL));
+        break;
+      default:
+        change(state, to_normal);
+        assert(stream.current() == '');
+      }
+    } else if (phase(state) == rx_role || stream.match(rx_role, false)) {
+
+      switch (stage(state)) {
+      case 0:
+        change(state, to_normal, context(rx_role, 1));
+        assert(stream.match(/^:/));
+        token = 'meta';
+        break;
+      case 1:
+        change(state, to_normal, context(rx_role, 2));
+        assert(stream.match(rx_NAME));
+        token = 'keyword';
+        break;
+      case 2:
+        change(state, to_normal, context(rx_role, 3));
+        assert(stream.match(/^:/));
+        token = 'meta';
+        break;
+      case 3:
+        change(state, to_normal, context(rx_role, 4));
+        assert(stream.match(rx_TAIL));
+        break;
+      default:
+        change(state, to_normal);
+        assert(stream.current() == '');
+      }
+    } else if (phase(state) == rx_substitution_ref ||
+               stream.match(rx_substitution_ref, false)) {
+
+      switch (stage(state)) {
+      case 0:
+        change(state, to_normal, context(rx_substitution_ref, 1));
+        assert(stream.match(rx_substitution_text));
+        token = 'variable-2';
+        break;
+      case 1:
+        change(state, to_normal, context(rx_substitution_ref, 2));
+        if (stream.match(/^_?_?/)) token = 'link';
+        break;
+      default:
+        change(state, to_normal);
+        assert(stream.current() == '');
+      }
+    } else if (stream.match(rx_footnote_ref)) {
+      change(state, to_normal);
+      token = 'quote';
+    } else if (stream.match(rx_citation_ref)) {
+      change(state, to_normal);
+      token = 'quote';
+    } else if (stream.match(rx_link_ref1)) {
+      change(state, to_normal);
+      if (!stream.peek() || stream.peek().match(/^\W$/)) {
+        token = 'link';
+      }
+    } else if (phase(state) == rx_link_ref2 ||
+               stream.match(rx_link_ref2, false)) {
+
+      switch (stage(state)) {
+      case 0:
+        if (!stream.peek() || stream.peek().match(/^\W$/)) {
+          change(state, to_normal, context(rx_link_ref2, 1));
+        } else {
+          stream.match(rx_link_ref2);
+        }
+        break;
+      case 1:
+        change(state, to_normal, context(rx_link_ref2, 2));
+        assert(stream.match(/^`/));
+        token = 'link';
+        break;
+      case 2:
+        change(state, to_normal, context(rx_link_ref2, 3));
+        assert(stream.match(rx_TEXT2));
+        break;
+      case 3:
+        change(state, to_normal, context(rx_link_ref2, 4));
+        assert(stream.match(/^`_/));
+        token = 'link';
+        break;
+      default:
+        change(state, to_normal);
+        assert(stream.current() == '');
+      }
+    } else if (stream.match(rx_verbatim)) {
+      change(state, to_verbatim);
+    }
+
+    else {
+      if (stream.next()) change(state, to_normal);
+    }
+
+    return token;
+  }
+
+  ///////////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////////
+
+  function to_explicit(stream, state) {
+    var token = null;
+
+    if (phase(state) == rx_substitution ||
+        stream.match(rx_substitution, false)) {
+
+      switch (stage(state)) {
+      case 0:
+        change(state, to_explicit, context(rx_substitution, 1));
+        assert(stream.match(rx_substitution_text));
+        token = 'variable-2';
+        break;
+      case 1:
+        change(state, to_explicit, context(rx_substitution, 2));
+        assert(stream.match(rx_substitution_sepa));
+        break;
+      case 2:
+        change(state, to_explicit, context(rx_substitution, 3));
+        assert(stream.match(rx_substitution_name));
+        token = 'keyword';
+        break;
+      case 3:
+        change(state, to_explicit, context(rx_substitution, 4));
+        assert(stream.match(rx_substitution_tail));
+        token = 'meta';
+        break;
+      default:
+        change(state, to_normal);
+        assert(stream.current() == '');
+      }
+    } else if (phase(state) == rx_directive ||
+               stream.match(rx_directive, false)) {
+
+      switch (stage(state)) {
+      case 0:
+        change(state, to_explicit, context(rx_directive, 1));
+        assert(stream.match(rx_directive_name));
+        token = 'keyword';
+
+        if (stream.current().match(/^(?:math|latex)/))
+          state.tmp_stex = true;
+        else if (stream.current().match(/^python/))
+          state.tmp_py = true;
+        break;
+      case 1:
+        change(state, to_explicit, context(rx_directive, 2));
+        assert(stream.match(rx_directive_tail));
+        token = 'meta';
+
+        if (stream.match(/^latex\s*$/) || state.tmp_stex) {
+          state.tmp_stex = undefined; change(state, to_mode, {
+            mode: mode_stex, local: CodeMirror.startState(mode_stex)
+          });
+        }
+        break;
+      case 2:
+        change(state, to_explicit, context(rx_directive, 3));
+        if (stream.match(/^python\s*$/) || state.tmp_py) {
+          state.tmp_py = undefined; change(state, to_mode, {
+            mode: mode_python, local: CodeMirror.startState(mode_python)
+          });
+        }
+        break;
+      default:
+        change(state, to_normal);
+        assert(stream.current() == '');
+      }
+    } else if (phase(state) == rx_link || stream.match(rx_link, false)) {
+
+      switch (stage(state)) {
+      case 0:
+        change(state, to_explicit, context(rx_link, 1));
+        assert(stream.match(rx_link_head));
+        assert(stream.match(rx_link_name));
+        token = 'link';
+        break;
+      case 1:
+        change(state, to_explicit, context(rx_link, 2));
+        assert(stream.match(rx_link_tail));
+        token = 'meta';
+        break;
+      default:
+        change(state, to_normal);
+        assert(stream.current() == '');
+      }
+    } else if (stream.match(rx_footnote)) {
+      change(state, to_normal);
+      token = 'quote';
+    } else if (stream.match(rx_citation)) {
+      change(state, to_normal);
+      token = 'quote';
+    }
+
+    else {
+      stream.eatSpace();
+      if (stream.eol()) {
+        change(state, to_normal);
+      } else {
+        stream.skipToEnd();
+        change(state, to_comment);
+        token = 'comment';
+      }
+    }
+
+    return token;
+  }
+
+  ///////////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////////
+
+  function to_comment(stream, state) {
+    return as_block(stream, state, 'comment');
+  }
+
+  function to_verbatim(stream, state) {
+    return as_block(stream, state, 'meta');
+  }
+
+  function as_block(stream, state, token) {
+    if (stream.eol() || stream.eatSpace()) {
+      stream.skipToEnd();
+      return token;
+    } else {
+      change(state, to_normal);
+      return null;
+    }
+  }
+
+  ///////////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////////
+
+  function to_mode(stream, state) {
+
+    if (state.ctx.mode && state.ctx.local) {
+
+      if (stream.sol()) {
+        if (!stream.eatSpace()) change(state, to_normal);
+        return null;
+      }
+
+      return state.ctx.mode.token(stream, state.ctx.local);
+    }
+
+    change(state, to_normal);
+    return null;
+  }
+
+  ///////////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////////
+
+  function context(phase, stage, mode, local) {
+    return {phase: phase, stage: stage, mode: mode, local: local};
+  }
+
+  function change(state, tok, ctx) {
+    state.tok = tok;
+    state.ctx = ctx || {};
+  }
+
+  function stage(state) {
+    return state.ctx.stage || 0;
+  }
+
+  function phase(state) {
+    return state.ctx.phase;
+  }
+
+  ///////////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////////
+
+  return {
+    startState: function () {
+      return {tok: to_normal, ctx: context(undefined, 0)};
+    },
+
+    copyState: function (state) {
+      var ctx = state.ctx, tmp = state.tmp;
+      if (ctx.local)
+        ctx = {mode: ctx.mode, local: CodeMirror.copyState(ctx.mode, ctx.local)};
+      if (tmp)
+        tmp = {mode: tmp.mode, local: CodeMirror.copyState(tmp.mode, tmp.local)};
+      return {tok: state.tok, ctx: ctx, tmp: tmp};
+    },
+
+    innerMode: function (state) {
+      return state.tmp      ? {state: state.tmp.local, mode: state.tmp.mode}
+      : state.ctx.mode ? {state: state.ctx.local, mode: state.ctx.mode}
+      : null;
+    },
+
+    token: function (stream, state) {
+      return state.tok(stream, state);
+    }
+  };
+}, 'python', 'stex');
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+CodeMirror.defineMIME('text/x-rst', 'rst');
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/ruby/index.html b/app/gui/html/vendor/codemirror/mode/ruby/index.html
new file mode 100644
index 0000000..8f0ebca
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/ruby/index.html
@@ -0,0 +1,184 @@
+<!doctype html>
+
+<title>CodeMirror: Ruby mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="ruby.js"></script>
+<style>
+      .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+      .cm-s-default span.cm-arrow { color: red; }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Ruby</a>
+  </ul>
+</div>
+
+<article>
+<h2>Ruby mode</h2>
+<form><textarea id="code" name="code">
+# Code from http://sandbox.mc.edu/~bennet/ruby/code/poly_rb.html
+#
+# This program evaluates polynomials.  It first asks for the coefficients
+# of a polynomial, which must be entered on one line, highest-order first.
+# It then requests values of x and will compute the value of the poly for
+# each x.  It will repeatly ask for x values, unless you the user enters
+# a blank line.  It that case, it will ask for another polynomial.  If the
+# user types quit for either input, the program immediately exits.
+#
+
+#
+# Function to evaluate a polynomial at x.  The polynomial is given
+# as a list of coefficients, from the greatest to the least.
+def polyval(x, coef)
+    sum = 0
+    coef = coef.clone           # Don't want to destroy the original
+    while true
+        sum += coef.shift       # Add and remove the next coef
+        break if coef.empty?    # If no more, done entirely.
+        sum *= x                # This happens the right number of times.
+    end
+    return sum
+end
+
+#
+# Function to read a line containing a list of integers and return
+# them as an array of integers.  If the string conversion fails, it
+# throws TypeError.  If the input line is the word 'quit', then it
+# converts it to an end-of-file exception
+def readints(prompt)
+    # Read a line
+    print prompt
+    line = readline.chomp
+    raise EOFError.new if line == 'quit' # You can also use a real EOF.
+            
+    # Go through each item on the line, converting each one and adding it
+    # to retval.
+    retval = [ ]
+    for str in line.split(/\s+/)
+        if str =~ /^\-?\d+$/
+            retval.push(str.to_i)
+        else
+            raise TypeError.new
+        end
+    end
+
+    return retval
+end
+
+#
+# Take a coeff and an exponent and return the string representation, ignoring
+# the sign of the coefficient.
+def term_to_str(coef, exp)
+    ret = ""
+
+    # Show coeff, unless it's 1 or at the right
+    coef = coef.abs
+    ret = coef.to_s     unless coef == 1 && exp > 0
+    ret += "x" if exp > 0                               # x if exponent not 0
+    ret += "^" + exp.to_s if exp > 1                    # ^exponent, if > 1.
+
+    return ret
+end
+
+#
+# Create a string of the polynomial in sort-of-readable form.
+def polystr(p)
+    # Get the exponent of first coefficient, plus 1.
+    exp = p.length
+
+    # Assign exponents to each term, making pairs of coeff and exponent,
+    # Then get rid of the zero terms.
+    p = (p.map { |c| exp -= 1; [ c, exp ] }).select { |p| p[0] != 0 }
+
+    # If there's nothing left, it's a zero
+    return "0" if p.empty?
+
+    # *** Now p is a non-empty list of [ coef, exponent ] pairs. ***
+
+    # Convert the first term, preceded by a "-" if it's negative.
+    result = (if p[0][0] < 0 then "-" else "" end) + term_to_str(*p[0])
+
+    # Convert the rest of the terms, in each case adding the appropriate
+    # + or - separating them.  
+    for term in p[1...p.length]
+        # Add the separator then the rep. of the term.
+        result += (if term[0] < 0 then " - " else " + " end) + 
+                term_to_str(*term)
+    end
+
+    return result
+end
+        
+#
+# Run until some kind of endfile.
+begin
+    # Repeat until an exception or quit gets us out.
+    while true
+        # Read a poly until it works.  An EOF will except out of the
+        # program.
+        print "\n"
+        begin
+            poly = readints("Enter a polynomial coefficients: ")
+        rescue TypeError
+            print "Try again.\n"
+            retry
+        end
+        break if poly.empty?
+
+        # Read and evaluate x values until the user types a blank line.
+        # Again, an EOF will except out of the pgm.
+        while true
+            # Request an integer.
+            print "Enter x value or blank line: "
+            x = readline.chomp
+            break if x == ''
+            raise EOFError.new if x == 'quit'
+
+            # If it looks bad, let's try again.
+            if x !~ /^\-?\d+$/
+                print "That doesn't look like an integer.  Please try again.\n"
+                next
+            end
+
+            # Convert to an integer and print the result.
+            x = x.to_i
+            print "p(x) = ", polystr(poly), "\n"
+            print "p(", x, ") = ", polyval(x, poly), "\n"
+        end
+    end
+rescue EOFError
+    print "\n=== EOF ===\n"
+rescue Interrupt, SignalException
+    print "\n=== Interrupted ===\n"
+else
+    print "--- Bye ---\n"
+end
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: "text/x-ruby",
+        matchBrackets: true,
+        indentUnit: 4
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-ruby</code>.</p>
+
+    <p>Development of the CodeMirror Ruby mode was kindly sponsored
+    by <a href="http://ubalo.com/">Ubalo</a>, who hold
+    the <a href="LICENSE">license</a>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/ruby/ruby.js b/app/gui/html/vendor/codemirror/mode/ruby/ruby.js
new file mode 100644
index 0000000..4ef08b1
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/ruby/ruby.js
@@ -0,0 +1,261 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("ruby", function(config) {
+  function wordObj(words) {
+    var o = {};
+    for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
+    return o;
+  }
+  var keywords = wordObj([
+    "alias", "and", "BEGIN", "begin", "break", "case", "class", "def", "defined?", "do", "else",
+    "elsif", "END", "end", "ensure", "false", "for", "if", "in", "module", "next", "not", "or",
+    "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless",
+    "until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc",
+    "caller", "lambda", "proc", "public", "protected", "private", "require", "load",
+    "require_relative", "extend", "autoload", "__END__", "__FILE__", "__LINE__", "__dir__"
+  ]);
+  var indentWords = wordObj(["def", "class", "case", "for", "while", "module", "then",
+                             "catch", "loop", "proc", "begin"]);
+  var dedentWords = wordObj(["end", "until"]);
+  var matching = {"[": "]", "{": "}", "(": ")"};
+  var curPunc;
+
+  function chain(newtok, stream, state) {
+    state.tokenize.push(newtok);
+    return newtok(stream, state);
+  }
+
+  function tokenBase(stream, state) {
+    curPunc = null;
+    if (stream.sol() && stream.match("=begin") && stream.eol()) {
+      state.tokenize.push(readBlockComment);
+      return "comment";
+    }
+    if (stream.eatSpace()) return null;
+    var ch = stream.next(), m;
+    if (ch == "`" || ch == "'" || ch == '"') {
+      return chain(readQuoted(ch, "string", ch == '"' || ch == "`"), stream, state);
+    } else if (ch == "/" && !stream.eol() && stream.peek() != " ") {
+      if (stream.eat("=")) return "operator";
+      return chain(readQuoted(ch, "string-2", true), stream, state);
+    } else if (ch == "%") {
+      var style = "string", embed = true;
+      if (stream.eat("s")) style = "atom";
+      else if (stream.eat(/[WQ]/)) style = "string";
+      else if (stream.eat(/[r]/)) style = "string-2";
+      else if (stream.eat(/[wxq]/)) { style = "string"; embed = false; }
+      var delim = stream.eat(/[^\w\s]/);
+      if (!delim) return "operator";
+      if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
+      return chain(readQuoted(delim, style, embed, true), stream, state);
+    } else if (ch == "#") {
+      stream.skipToEnd();
+      return "comment";
+    } else if (ch == "<" && (m = stream.match(/^<-?[\`\"\']?([a-zA-Z_?]\w*)[\`\"\']?(?:;|$)/))) {
+      return chain(readHereDoc(m[1]), stream, state);
+    } else if (ch == "0") {
+      if (stream.eat("x")) stream.eatWhile(/[\da-fA-F]/);
+      else if (stream.eat("b")) stream.eatWhile(/[01]/);
+      else stream.eatWhile(/[0-7]/);
+      return "number";
+    } else if (/\d/.test(ch)) {
+      stream.match(/^[\d_]*(?:\.[\d_]+)?(?:[eE][+\-]?[\d_]+)?/);
+      return "number";
+    } else if (ch == "?") {
+      while (stream.match(/^\\[CM]-/)) {}
+      if (stream.eat("\\")) stream.eatWhile(/\w/);
+      else stream.next();
+      return "string";
+    } else if (ch == ":") {
+      if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state);
+      if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state);
+
+      // :> :>> :< :<< are valid symbols
+      if (stream.eat(/[\<\>]/)) {
+        stream.eat(/[\<\>]/);
+        return "atom";
+      }
+
+      // :+ :- :/ :* :| :& :! are valid symbols
+      if (stream.eat(/[\+\-\*\/\&\|\:\!]/)) {
+        return "atom";
+      }
+
+      // Symbols can't start by a digit
+      if (stream.eat(/[a-zA-Z$@_]/)) {
+        stream.eatWhile(/[\w]/);
+        // Only one ? ! = is allowed and only as the last character
+        stream.eat(/[\?\!\=]/);
+        return "atom";
+      }
+      return "operator";
+    } else if (ch == "@" && stream.match(/^@?[a-zA-Z_]/)) {
+      stream.eat("@");
+      stream.eatWhile(/[\w]/);
+      return "variable-2";
+    } else if (ch == "$") {
+      if (stream.eat(/[a-zA-Z_]/)) {
+        stream.eatWhile(/[\w]/);
+      } else if (stream.eat(/\d/)) {
+        stream.eat(/\d/);
+      } else {
+        stream.next(); // Must be a special global like $: or $!
+      }
+      return "variable-3";
+    } else if (/[a-zA-Z_]/.test(ch)) {
+      stream.eatWhile(/[\w]/);
+      stream.eat(/[\?\!]/);
+      if (stream.eat(":")) return "atom";
+      return "ident";
+    } else if (ch == "|" && (state.varList || state.lastTok == "{" || state.lastTok == "do")) {
+      curPunc = "|";
+      return null;
+    } else if (/[\(\)\[\]{}\\;]/.test(ch)) {
+      curPunc = ch;
+      return null;
+    } else if (ch == "-" && stream.eat(">")) {
+      return "arrow";
+    } else if (/[=+\-\/*:\.^%<>~|]/.test(ch)) {
+      stream.eatWhile(/[=+\-\/*:\.^%<>~|]/);
+      return "operator";
+    } else {
+      return null;
+    }
+  }
+
+  function tokenBaseUntilBrace() {
+    var depth = 1;
+    return function(stream, state) {
+      if (stream.peek() == "}") {
+        depth--;
+        if (depth == 0) {
+          state.tokenize.pop();
+          return state.tokenize[state.tokenize.length-1](stream, state);
+        }
+      } else if (stream.peek() == "{") {
+        depth++;
+      }
+      return tokenBase(stream, state);
+    };
+  }
+  function tokenBaseOnce() {
+    var alreadyCalled = false;
+    return function(stream, state) {
+      if (alreadyCalled) {
+        state.tokenize.pop();
+        return state.tokenize[state.tokenize.length-1](stream, state);
+      }
+      alreadyCalled = true;
+      return tokenBase(stream, state);
+    };
+  }
+  function readQuoted(quote, style, embed, unescaped) {
+    return function(stream, state) {
+      var escaped = false, ch;
+
+      if (state.context.type === 'read-quoted-paused') {
+        state.context = state.context.prev;
+        stream.eat("}");
+      }
+
+      while ((ch = stream.next()) != null) {
+        if (ch == quote && (unescaped || !escaped)) {
+          state.tokenize.pop();
+          break;
+        }
+        if (embed && ch == "#" && !escaped) {
+          if (stream.eat("{")) {
+            if (quote == "}") {
+              state.context = {prev: state.context, type: 'read-quoted-paused'};
+            }
+            state.tokenize.push(tokenBaseUntilBrace());
+            break;
+          } else if (/[@\$]/.test(stream.peek())) {
+            state.tokenize.push(tokenBaseOnce());
+            break;
+          }
+        }
+        escaped = !escaped && ch == "\\";
+      }
+      return style;
+    };
+  }
+  function readHereDoc(phrase) {
+    return function(stream, state) {
+      if (stream.match(phrase)) state.tokenize.pop();
+      else stream.skipToEnd();
+      return "string";
+    };
+  }
+  function readBlockComment(stream, state) {
+    if (stream.sol() && stream.match("=end") && stream.eol())
+      state.tokenize.pop();
+    stream.skipToEnd();
+    return "comment";
+  }
+
+  return {
+    startState: function() {
+      return {tokenize: [tokenBase],
+              indented: 0,
+              context: {type: "top", indented: -config.indentUnit},
+              continuedLine: false,
+              lastTok: null,
+              varList: false};
+    },
+
+    token: function(stream, state) {
+      if (stream.sol()) state.indented = stream.indentation();
+      var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;
+      if (style == "ident") {
+        var word = stream.current();
+        style = keywords.propertyIsEnumerable(stream.current()) ? "keyword"
+          : /^[A-Z]/.test(word) ? "tag"
+          : (state.lastTok == "def" || state.lastTok == "class" || state.varList) ? "def"
+          : "variable";
+        if (indentWords.propertyIsEnumerable(word)) kwtype = "indent";
+        else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent";
+        else if ((word == "if" || word == "unless") && stream.column() == stream.indentation())
+          kwtype = "indent";
+        else if (word == "do" && state.context.indented < state.indented)
+          kwtype = "indent";
+      }
+      if (curPunc || (style && style != "comment")) state.lastTok = word || curPunc || style;
+      if (curPunc == "|") state.varList = !state.varList;
+
+      if (kwtype == "indent" || /[\(\[\{]/.test(curPunc))
+        state.context = {prev: state.context, type: curPunc || style, indented: state.indented};
+      else if ((kwtype == "dedent" || /[\)\]\}]/.test(curPunc)) && state.context.prev)
+        state.context = state.context.prev;
+
+      if (stream.eol())
+        state.continuedLine = (curPunc == "\\" || style == "operator");
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      if (state.tokenize[state.tokenize.length-1] != tokenBase) return 0;
+      var firstChar = textAfter && textAfter.charAt(0);
+      var ct = state.context;
+      var closing = ct.type == matching[firstChar] ||
+        ct.type == "keyword" && /^(?:end|until|else|elsif|when|rescue)\b/.test(textAfter);
+      return ct.indented + (closing ? 0 : config.indentUnit) +
+        (state.continuedLine ? config.indentUnit : 0);
+    },
+
+    electricChars: "}de", // enD and rescuE
+    lineComment: "#"
+  };
+});
+
+CodeMirror.defineMIME("text/x-ruby", "ruby");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/ruby/test.js b/app/gui/html/vendor/codemirror/mode/ruby/test.js
new file mode 100644
index 0000000..c97d106
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/ruby/test.js
@@ -0,0 +1,11 @@
+(function() {
+  var mode = CodeMirror.getMode({indentUnit: 2}, "ruby");
+  function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
+
+  MT("divide_equal_operator",
+     "[variable bar] [operator /=] [variable foo]");
+
+  MT("divide_equal_operator_no_spacing",
+     "[variable foo][operator /=][number 42]");
+
+})();
diff --git a/app/gui/html/vendor/codemirror/mode/rust/index.html b/app/gui/html/vendor/codemirror/mode/rust/index.html
new file mode 100644
index 0000000..4fc0999
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/rust/index.html
@@ -0,0 +1,60 @@
+<!doctype html>
+
+<title>CodeMirror: Rust mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="rust.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Rust</a>
+  </ul>
+</div>
+
+<article>
+<h2>Rust mode</h2>
+
+
+<div><textarea id="code" name="code">
+// Demo code.
+
+type foo<T> = int;
+enum bar {
+    some(int, foo<float>),
+    none
+}
+
+fn check_crate(x: int) {
+    let v = 10;
+    alt foo {
+      1 to 3 {
+        print_foo();
+        if x {
+            blah() + 10;
+        }
+      }
+      (x, y) { "bye" }
+      _ { "hi" }
+    }
+}
+</textarea></div>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-rustsrc</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/rust/rust.js b/app/gui/html/vendor/codemirror/mode/rust/rust.js
new file mode 100644
index 0000000..2e6e20b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/rust/rust.js
@@ -0,0 +1,448 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("rust", function() {
+  var indentUnit = 4, altIndentUnit = 2;
+  var valKeywords = {
+    "if": "if-style", "while": "if-style", "else": "else-style",
+    "do": "else-style", "ret": "else-style", "fail": "else-style",
+    "break": "atom", "cont": "atom", "const": "let", "resource": "fn",
+    "let": "let", "fn": "fn", "for": "for", "alt": "alt", "iface": "iface",
+    "impl": "impl", "type": "type", "enum": "enum", "mod": "mod",
+    "as": "op", "true": "atom", "false": "atom", "assert": "op", "check": "op",
+    "claim": "op", "native": "ignore", "unsafe": "ignore", "import": "else-style",
+    "export": "else-style", "copy": "op", "log": "op", "log_err": "op",
+    "use": "op", "bind": "op", "self": "atom"
+  };
+  var typeKeywords = function() {
+    var keywords = {"fn": "fn", "block": "fn", "obj": "obj"};
+    var atoms = "bool uint int i8 i16 i32 i64 u8 u16 u32 u64 float f32 f64 str char".split(" ");
+    for (var i = 0, e = atoms.length; i < e; ++i) keywords[atoms[i]] = "atom";
+    return keywords;
+  }();
+  var operatorChar = /[+\-*&%=<>!?|\.@]/;
+
+  // Tokenizer
+
+  // Used as scratch variable to communicate multiple values without
+  // consing up tons of objects.
+  var tcat, content;
+  function r(tc, style) {
+    tcat = tc;
+    return style;
+  }
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+    if (ch == '"') {
+      state.tokenize = tokenString;
+      return state.tokenize(stream, state);
+    }
+    if (ch == "'") {
+      tcat = "atom";
+      if (stream.eat("\\")) {
+        if (stream.skipTo("'")) { stream.next(); return "string"; }
+        else { return "error"; }
+      } else {
+        stream.next();
+        return stream.eat("'") ? "string" : "error";
+      }
+    }
+    if (ch == "/") {
+      if (stream.eat("/")) { stream.skipToEnd(); return "comment"; }
+      if (stream.eat("*")) {
+        state.tokenize = tokenComment(1);
+        return state.tokenize(stream, state);
+      }
+    }
+    if (ch == "#") {
+      if (stream.eat("[")) { tcat = "open-attr"; return null; }
+      stream.eatWhile(/\w/);
+      return r("macro", "meta");
+    }
+    if (ch == ":" && stream.match(":<")) {
+      return r("op", null);
+    }
+    if (ch.match(/\d/) || (ch == "." && stream.eat(/\d/))) {
+      var flp = false;
+      if (!stream.match(/^x[\da-f]+/i) && !stream.match(/^b[01]+/)) {
+        stream.eatWhile(/\d/);
+        if (stream.eat(".")) { flp = true; stream.eatWhile(/\d/); }
+        if (stream.match(/^e[+\-]?\d+/i)) { flp = true; }
+      }
+      if (flp) stream.match(/^f(?:32|64)/);
+      else stream.match(/^[ui](?:8|16|32|64)/);
+      return r("atom", "number");
+    }
+    if (ch.match(/[()\[\]{}:;,]/)) return r(ch, null);
+    if (ch == "-" && stream.eat(">")) return r("->", null);
+    if (ch.match(operatorChar)) {
+      stream.eatWhile(operatorChar);
+      return r("op", null);
+    }
+    stream.eatWhile(/\w/);
+    content = stream.current();
+    if (stream.match(/^::\w/)) {
+      stream.backUp(1);
+      return r("prefix", "variable-2");
+    }
+    if (state.keywords.propertyIsEnumerable(content))
+      return r(state.keywords[content], content.match(/true|false/) ? "atom" : "keyword");
+    return r("name", "variable");
+  }
+
+  function tokenString(stream, state) {
+    var ch, escaped = false;
+    while (ch = stream.next()) {
+      if (ch == '"' && !escaped) {
+        state.tokenize = tokenBase;
+        return r("atom", "string");
+      }
+      escaped = !escaped && ch == "\\";
+    }
+    // Hack to not confuse the parser when a string is split in
+    // pieces.
+    return r("op", "string");
+  }
+
+  function tokenComment(depth) {
+    return function(stream, state) {
+      var lastCh = null, ch;
+      while (ch = stream.next()) {
+        if (ch == "/" && lastCh == "*") {
+          if (depth == 1) {
+            state.tokenize = tokenBase;
+            break;
+          } else {
+            state.tokenize = tokenComment(depth - 1);
+            return state.tokenize(stream, state);
+          }
+        }
+        if (ch == "*" && lastCh == "/") {
+          state.tokenize = tokenComment(depth + 1);
+          return state.tokenize(stream, state);
+        }
+        lastCh = ch;
+      }
+      return "comment";
+    };
+  }
+
+  // Parser
+
+  var cx = {state: null, stream: null, marked: null, cc: null};
+  function pass() {
+    for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
+  }
+  function cont() {
+    pass.apply(null, arguments);
+    return true;
+  }
+
+  function pushlex(type, info) {
+    var result = function() {
+      var state = cx.state;
+      state.lexical = {indented: state.indented, column: cx.stream.column(),
+                       type: type, prev: state.lexical, info: info};
+    };
+    result.lex = true;
+    return result;
+  }
+  function poplex() {
+    var state = cx.state;
+    if (state.lexical.prev) {
+      if (state.lexical.type == ")")
+        state.indented = state.lexical.indented;
+      state.lexical = state.lexical.prev;
+    }
+  }
+  function typecx() { cx.state.keywords = typeKeywords; }
+  function valcx() { cx.state.keywords = valKeywords; }
+  poplex.lex = typecx.lex = valcx.lex = true;
+
+  function commasep(comb, end) {
+    function more(type) {
+      if (type == ",") return cont(comb, more);
+      if (type == end) return cont();
+      return cont(more);
+    }
+    return function(type) {
+      if (type == end) return cont();
+      return pass(comb, more);
+    };
+  }
+
+  function stat_of(comb, tag) {
+    return cont(pushlex("stat", tag), comb, poplex, block);
+  }
+  function block(type) {
+    if (type == "}") return cont();
+    if (type == "let") return stat_of(letdef1, "let");
+    if (type == "fn") return stat_of(fndef);
+    if (type == "type") return cont(pushlex("stat"), tydef, endstatement, poplex, block);
+    if (type == "enum") return stat_of(enumdef);
+    if (type == "mod") return stat_of(mod);
+    if (type == "iface") return stat_of(iface);
+    if (type == "impl") return stat_of(impl);
+    if (type == "open-attr") return cont(pushlex("]"), commasep(expression, "]"), poplex);
+    if (type == "ignore" || type.match(/[\]\);,]/)) return cont(block);
+    return pass(pushlex("stat"), expression, poplex, endstatement, block);
+  }
+  function endstatement(type) {
+    if (type == ";") return cont();
+    return pass();
+  }
+  function expression(type) {
+    if (type == "atom" || type == "name") return cont(maybeop);
+    if (type == "{") return cont(pushlex("}"), exprbrace, poplex);
+    if (type.match(/[\[\(]/)) return matchBrackets(type, expression);
+    if (type.match(/[\]\)\};,]/)) return pass();
+    if (type == "if-style") return cont(expression, expression);
+    if (type == "else-style" || type == "op") return cont(expression);
+    if (type == "for") return cont(pattern, maybetype, inop, expression, expression);
+    if (type == "alt") return cont(expression, altbody);
+    if (type == "fn") return cont(fndef);
+    if (type == "macro") return cont(macro);
+    return cont();
+  }
+  function maybeop(type) {
+    if (content == ".") return cont(maybeprop);
+    if (content == "::<"){return cont(typarams, maybeop);}
+    if (type == "op" || content == ":") return cont(expression);
+    if (type == "(" || type == "[") return matchBrackets(type, expression);
+    return pass();
+  }
+  function maybeprop() {
+    if (content.match(/^\w+$/)) {cx.marked = "variable"; return cont(maybeop);}
+    return pass(expression);
+  }
+  function exprbrace(type) {
+    if (type == "op") {
+      if (content == "|") return cont(blockvars, poplex, pushlex("}", "block"), block);
+      if (content == "||") return cont(poplex, pushlex("}", "block"), block);
+    }
+    if (content == "mutable" || (content.match(/^\w+$/) && cx.stream.peek() == ":"
+                                 && !cx.stream.match("::", false)))
+      return pass(record_of(expression));
+    return pass(block);
+  }
+  function record_of(comb) {
+    function ro(type) {
+      if (content == "mutable" || content == "with") {cx.marked = "keyword"; return cont(ro);}
+      if (content.match(/^\w*$/)) {cx.marked = "variable"; return cont(ro);}
+      if (type == ":") return cont(comb, ro);
+      if (type == "}") return cont();
+      return cont(ro);
+    }
+    return ro;
+  }
+  function blockvars(type) {
+    if (type == "name") {cx.marked = "def"; return cont(blockvars);}
+    if (type == "op" && content == "|") return cont();
+    return cont(blockvars);
+  }
+
+  function letdef1(type) {
+    if (type.match(/[\]\)\};]/)) return cont();
+    if (content == "=") return cont(expression, letdef2);
+    if (type == ",") return cont(letdef1);
+    return pass(pattern, maybetype, letdef1);
+  }
+  function letdef2(type) {
+    if (type.match(/[\]\)\};,]/)) return pass(letdef1);
+    else return pass(expression, letdef2);
+  }
+  function maybetype(type) {
+    if (type == ":") return cont(typecx, rtype, valcx);
+    return pass();
+  }
+  function inop(type) {
+    if (type == "name" && content == "in") {cx.marked = "keyword"; return cont();}
+    return pass();
+  }
+  function fndef(type) {
+    if (content == "@" || content == "~") {cx.marked = "keyword"; return cont(fndef);}
+    if (type == "name") {cx.marked = "def"; return cont(fndef);}
+    if (content == "<") return cont(typarams, fndef);
+    if (type == "{") return pass(expression);
+    if (type == "(") return cont(pushlex(")"), commasep(argdef, ")"), poplex, fndef);
+    if (type == "->") return cont(typecx, rtype, valcx, fndef);
+    if (type == ";") return cont();
+    return cont(fndef);
+  }
+  function tydef(type) {
+    if (type == "name") {cx.marked = "def"; return cont(tydef);}
+    if (content == "<") return cont(typarams, tydef);
+    if (content == "=") return cont(typecx, rtype, valcx);
+    return cont(tydef);
+  }
+  function enumdef(type) {
+    if (type == "name") {cx.marked = "def"; return cont(enumdef);}
+    if (content == "<") return cont(typarams, enumdef);
+    if (content == "=") return cont(typecx, rtype, valcx, endstatement);
+    if (type == "{") return cont(pushlex("}"), typecx, enumblock, valcx, poplex);
+    return cont(enumdef);
+  }
+  function enumblock(type) {
+    if (type == "}") return cont();
+    if (type == "(") return cont(pushlex(")"), commasep(rtype, ")"), poplex, enumblock);
+    if (content.match(/^\w+$/)) cx.marked = "def";
+    return cont(enumblock);
+  }
+  function mod(type) {
+    if (type == "name") {cx.marked = "def"; return cont(mod);}
+    if (type == "{") return cont(pushlex("}"), block, poplex);
+    return pass();
+  }
+  function iface(type) {
+    if (type == "name") {cx.marked = "def"; return cont(iface);}
+    if (content == "<") return cont(typarams, iface);
+    if (type == "{") return cont(pushlex("}"), block, poplex);
+    return pass();
+  }
+  function impl(type) {
+    if (content == "<") return cont(typarams, impl);
+    if (content == "of" || content == "for") {cx.marked = "keyword"; return cont(rtype, impl);}
+    if (type == "name") {cx.marked = "def"; return cont(impl);}
+    if (type == "{") return cont(pushlex("}"), block, poplex);
+    return pass();
+  }
+  function typarams() {
+    if (content == ">") return cont();
+    if (content == ",") return cont(typarams);
+    if (content == ":") return cont(rtype, typarams);
+    return pass(rtype, typarams);
+  }
+  function argdef(type) {
+    if (type == "name") {cx.marked = "def"; return cont(argdef);}
+    if (type == ":") return cont(typecx, rtype, valcx);
+    return pass();
+  }
+  function rtype(type) {
+    if (type == "name") {cx.marked = "variable-3"; return cont(rtypemaybeparam); }
+    if (content == "mutable") {cx.marked = "keyword"; return cont(rtype);}
+    if (type == "atom") return cont(rtypemaybeparam);
+    if (type == "op" || type == "obj") return cont(rtype);
+    if (type == "fn") return cont(fntype);
+    if (type == "{") return cont(pushlex("{"), record_of(rtype), poplex);
+    return matchBrackets(type, rtype);
+  }
+  function rtypemaybeparam() {
+    if (content == "<") return cont(typarams);
+    return pass();
+  }
+  function fntype(type) {
+    if (type == "(") return cont(pushlex("("), commasep(rtype, ")"), poplex, fntype);
+    if (type == "->") return cont(rtype);
+    return pass();
+  }
+  function pattern(type) {
+    if (type == "name") {cx.marked = "def"; return cont(patternmaybeop);}
+    if (type == "atom") return cont(patternmaybeop);
+    if (type == "op") return cont(pattern);
+    if (type.match(/[\]\)\};,]/)) return pass();
+    return matchBrackets(type, pattern);
+  }
+  function patternmaybeop(type) {
+    if (type == "op" && content == ".") return cont();
+    if (content == "to") {cx.marked = "keyword"; return cont(pattern);}
+    else return pass();
+  }
+  function altbody(type) {
+    if (type == "{") return cont(pushlex("}", "alt"), altblock1, poplex);
+    return pass();
+  }
+  function altblock1(type) {
+    if (type == "}") return cont();
+    if (type == "|") return cont(altblock1);
+    if (content == "when") {cx.marked = "keyword"; return cont(expression, altblock2);}
+    if (type.match(/[\]\);,]/)) return cont(altblock1);
+    return pass(pattern, altblock2);
+  }
+  function altblock2(type) {
+    if (type == "{") return cont(pushlex("}", "alt"), block, poplex, altblock1);
+    else return pass(altblock1);
+  }
+
+  function macro(type) {
+    if (type.match(/[\[\(\{]/)) return matchBrackets(type, expression);
+    return pass();
+  }
+  function matchBrackets(type, comb) {
+    if (type == "[") return cont(pushlex("]"), commasep(comb, "]"), poplex);
+    if (type == "(") return cont(pushlex(")"), commasep(comb, ")"), poplex);
+    if (type == "{") return cont(pushlex("}"), commasep(comb, "}"), poplex);
+    return cont();
+  }
+
+  function parse(state, stream, style) {
+    var cc = state.cc;
+    // Communicate our context to the combinators.
+    // (Less wasteful than consing up a hundred closures on every call.)
+    cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
+
+    while (true) {
+      var combinator = cc.length ? cc.pop() : block;
+      if (combinator(tcat)) {
+        while(cc.length && cc[cc.length - 1].lex)
+          cc.pop()();
+        return cx.marked || style;
+      }
+    }
+  }
+
+  return {
+    startState: function() {
+      return {
+        tokenize: tokenBase,
+        cc: [],
+        lexical: {indented: -indentUnit, column: 0, type: "top", align: false},
+        keywords: valKeywords,
+        indented: 0
+      };
+    },
+
+    token: function(stream, state) {
+      if (stream.sol()) {
+        if (!state.lexical.hasOwnProperty("align"))
+          state.lexical.align = false;
+        state.indented = stream.indentation();
+      }
+      if (stream.eatSpace()) return null;
+      tcat = content = null;
+      var style = state.tokenize(stream, state);
+      if (style == "comment") return style;
+      if (!state.lexical.hasOwnProperty("align"))
+        state.lexical.align = true;
+      if (tcat == "prefix") return style;
+      if (!content) content = stream.current();
+      return parse(state, stream, style);
+    },
+
+    indent: function(state, textAfter) {
+      if (state.tokenize != tokenBase) return 0;
+      var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
+          type = lexical.type, closing = firstChar == type;
+      if (type == "stat") return lexical.indented + indentUnit;
+      if (lexical.align) return lexical.column + (closing ? 0 : 1);
+      return lexical.indented + (closing ? 0 : (lexical.info == "alt" ? altIndentUnit : indentUnit));
+    },
+
+    electricChars: "{}",
+    blockCommentStart: "/*",
+    blockCommentEnd: "*/",
+    lineComment: "//",
+    fold: "brace"
+  };
+});
+
+CodeMirror.defineMIME("text/x-rustsrc", "rust");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/sass/index.html b/app/gui/html/vendor/codemirror/mode/sass/index.html
new file mode 100644
index 0000000..66d4677
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/sass/index.html
@@ -0,0 +1,66 @@
+<!doctype html>
+
+<title>CodeMirror: Sass mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="sass.js"></script>
+<style>.CodeMirror {border: 1px solid #ddd; font-size:12px; height: 400px}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Sass</a>
+  </ul>
+</div>
+
+<article>
+<h2>Sass mode</h2>
+<form><textarea id="code" name="code">// Variable Definitions
+
+$page-width:    800px
+$sidebar-width: 200px
+$primary-color: #eeeeee
+
+// Global Attributes
+
+body
+  font:
+    family: sans-serif
+    size: 30em
+    weight: bold
+
+// Scoped Styles
+
+#contents
+  width: $page-width
+  #sidebar
+    float: right
+    width: $sidebar-width
+  #main
+    width: $page-width - $sidebar-width
+    background: $primary-color
+    h2
+      color: blue
+
+#footer
+  height: 200px
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers : true,
+        matchBrackets : true
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-sass</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/sass/sass.js b/app/gui/html/vendor/codemirror/mode/sass/sass.js
new file mode 100644
index 0000000..74ae91d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/sass/sass.js
@@ -0,0 +1,342 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("sass", function(config) {
+  var tokenRegexp = function(words){
+    return new RegExp("^" + words.join("|"));
+  };
+
+  var keywords = ["true", "false", "null", "auto"];
+  var keywordsRegexp = new RegExp("^" + keywords.join("|"));
+
+  var operators = ["\\(", "\\)", "=", ">", "<", "==", ">=", "<=", "\\+", "-", "\\!=", "/", "\\*", "%", "and", "or", "not"];
+  var opRegexp = tokenRegexp(operators);
+
+  var pseudoElementsRegexp = /^::?[\w\-]+/;
+
+  var urlTokens = function(stream, state){
+    var ch = stream.peek();
+
+    if (ch === ")"){
+      stream.next();
+      state.tokenizer = tokenBase;
+      return "operator";
+    }else if (ch === "("){
+      stream.next();
+      stream.eatSpace();
+
+      return "operator";
+    }else if (ch === "'" || ch === '"'){
+      state.tokenizer = buildStringTokenizer(stream.next());
+      return "string";
+    }else{
+      state.tokenizer = buildStringTokenizer(")", false);
+      return "string";
+    }
+  };
+  var multilineComment = function(stream, state) {
+    if (stream.skipTo("*/")){
+      stream.next();
+      stream.next();
+      state.tokenizer = tokenBase;
+    }else {
+      stream.next();
+    }
+
+    return "comment";
+  };
+
+  var buildStringTokenizer = function(quote, greedy){
+    if(greedy == null){ greedy = true; }
+
+    function stringTokenizer(stream, state){
+      var nextChar = stream.next();
+      var peekChar = stream.peek();
+      var previousChar = stream.string.charAt(stream.pos-2);
+
+      var endingString = ((nextChar !== "\\" && peekChar === quote) || (nextChar === quote && previousChar !== "\\"));
+
+      /*
+      console.log("previousChar: " + previousChar);
+      console.log("nextChar: " + nextChar);
+      console.log("peekChar: " + peekChar);
+      console.log("ending: " + endingString);
+      */
+
+      if (endingString){
+        if (nextChar !== quote && greedy) { stream.next(); }
+        state.tokenizer = tokenBase;
+        return "string";
+      }else if (nextChar === "#" && peekChar === "{"){
+        state.tokenizer = buildInterpolationTokenizer(stringTokenizer);
+        stream.next();
+        return "operator";
+      }else {
+        return "string";
+      }
+    }
+
+    return stringTokenizer;
+  };
+
+  var buildInterpolationTokenizer = function(currentTokenizer){
+    return function(stream, state){
+      if (stream.peek() === "}"){
+        stream.next();
+        state.tokenizer = currentTokenizer;
+        return "operator";
+      }else{
+        return tokenBase(stream, state);
+      }
+    };
+  };
+
+  var indent = function(state){
+    if (state.indentCount == 0){
+      state.indentCount++;
+      var lastScopeOffset = state.scopes[0].offset;
+      var currentOffset = lastScopeOffset + config.indentUnit;
+      state.scopes.unshift({ offset:currentOffset });
+    }
+  };
+
+  var dedent = function(state){
+    if (state.scopes.length == 1) { return; }
+
+    state.scopes.shift();
+  };
+
+  var tokenBase = function(stream, state) {
+    var ch = stream.peek();
+
+    // Single line Comment
+    if (stream.match('//')) {
+      stream.skipToEnd();
+      return "comment";
+    }
+
+    // Multiline Comment
+    if (stream.match('/*')){
+      state.tokenizer = multilineComment;
+      return state.tokenizer(stream, state);
+    }
+
+    // Interpolation
+    if (stream.match('#{')){
+    state.tokenizer = buildInterpolationTokenizer(tokenBase);
+      return "operator";
+    }
+
+    if (ch === "."){
+      stream.next();
+
+      // Match class selectors
+      if (stream.match(/^[\w-]+/)){
+        indent(state);
+        return "atom";
+      }else if (stream.peek() === "#"){
+        indent(state);
+        return "atom";
+      }else{
+        return "operator";
+      }
+    }
+
+    if (ch === "#"){
+      stream.next();
+
+      // Hex numbers
+      if (stream.match(/[0-9a-fA-F]{6}|[0-9a-fA-F]{3}/)){
+        return "number";
+      }
+
+      // ID selectors
+      if (stream.match(/^[\w-]+/)){
+        indent(state);
+        return "atom";
+      }
+
+      if (stream.peek() === "#"){
+        indent(state);
+        return "atom";
+      }
+    }
+
+    // Numbers
+    if (stream.match(/^-?[0-9\.]+/)){
+      return "number";
+    }
+
+    // Units
+    if (stream.match(/^(px|em|in)\b/)){
+      return "unit";
+    }
+
+    if (stream.match(keywordsRegexp)){
+      return "keyword";
+    }
+
+    if (stream.match(/^url/) && stream.peek() === "("){
+      state.tokenizer = urlTokens;
+      return "atom";
+    }
+
+    // Variables
+    if (ch === "$"){
+      stream.next();
+      stream.eatWhile(/[\w-]/);
+
+      if (stream.peek() === ":"){
+        stream.next();
+        return "variable-2";
+      }else{
+        return "variable-3";
+      }
+    }
+
+    if (ch === "!"){
+      stream.next();
+
+      if (stream.match(/^[\w]+/)){
+        return "keyword";
+      }
+
+      return "operator";
+    }
+
+    if (ch === "="){
+      stream.next();
+
+      // Match shortcut mixin definition
+      if (stream.match(/^[\w-]+/)){
+        indent(state);
+        return "meta";
+      }else {
+        return "operator";
+      }
+    }
+
+    if (ch === "+"){
+      stream.next();
+
+      // Match shortcut mixin definition
+      if (stream.match(/^[\w-]+/)){
+        return "variable-3";
+      }else {
+        return "operator";
+      }
+    }
+
+    // Indent Directives
+    if (stream.match(/^@(else if|if|media|else|for|each|while|mixin|function)/)){
+      indent(state);
+      return "meta";
+    }
+
+    // Other Directives
+    if (ch === "@"){
+      stream.next();
+      stream.eatWhile(/[\w-]/);
+      return "meta";
+    }
+
+    // Strings
+    if (ch === '"' || ch === "'"){
+      stream.next();
+      state.tokenizer = buildStringTokenizer(ch);
+      return "string";
+    }
+
+    // Pseudo element selectors
+    if (ch == ':' && stream.match(pseudoElementsRegexp)){
+      return "keyword";
+    }
+
+    // atoms
+    if (stream.eatWhile(/[\w-&]/)){
+      // matches a property definition
+      if (stream.peek() === ":" && !stream.match(pseudoElementsRegexp, false))
+        return "property";
+      else
+        return "atom";
+    }
+
+    if (stream.match(opRegexp)){
+      return "operator";
+    }
+
+    // If we haven't returned by now, we move 1 character
+    // and return an error
+    stream.next();
+    return null;
+  };
+
+  var tokenLexer = function(stream, state) {
+    if (stream.sol()){
+      state.indentCount = 0;
+    }
+    var style = state.tokenizer(stream, state);
+    var current = stream.current();
+
+    if (current === "@return"){
+      dedent(state);
+    }
+
+    if (style === "atom"){
+      indent(state);
+    }
+
+    if (style !== null){
+      var startOfToken = stream.pos - current.length;
+      var withCurrentIndent = startOfToken + (config.indentUnit * state.indentCount);
+
+      var newScopes = [];
+
+      for (var i = 0; i < state.scopes.length; i++){
+        var scope = state.scopes[i];
+
+        if (scope.offset <= withCurrentIndent){
+          newScopes.push(scope);
+        }
+      }
+
+      state.scopes = newScopes;
+    }
+
+
+    return style;
+  };
+
+  return {
+    startState: function() {
+      return {
+        tokenizer: tokenBase,
+        scopes: [{offset: 0, type: 'sass'}],
+        definedVars: [],
+        definedMixins: []
+      };
+    },
+    token: function(stream, state) {
+      var style = tokenLexer(stream, state);
+
+      state.lastToken = { style: style, content: stream.current() };
+
+      return style;
+    },
+
+    indent: function(state) {
+      return state.scopes[0].offset;
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/x-sass", "sass");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/scheme/index.html b/app/gui/html/vendor/codemirror/mode/scheme/index.html
new file mode 100644
index 0000000..164d5da
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/scheme/index.html
@@ -0,0 +1,77 @@
+<!doctype html>
+
+<title>CodeMirror: Scheme mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="scheme.js"></script>
+<style>.CodeMirror {background: #f8f8f8;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Scheme</a>
+  </ul>
+</div>
+
+<article>
+<h2>Scheme mode</h2>
+<form><textarea id="code" name="code">
+; See if the input starts with a given symbol.
+(define (match-symbol input pattern)
+  (cond ((null? (remain input)) #f)
+	((eqv? (car (remain input)) pattern) (r-cdr input))
+	(else #f)))
+
+; Allow the input to start with one of a list of patterns.
+(define (match-or input pattern)
+  (cond ((null? pattern) #f)
+	((match-pattern input (car pattern)))
+	(else (match-or input (cdr pattern)))))
+
+; Allow a sequence of patterns.
+(define (match-seq input pattern)
+  (if (null? pattern)
+      input
+      (let ((match (match-pattern input (car pattern))))
+	(if match (match-seq match (cdr pattern)) #f))))
+
+; Match with the pattern but no problem if it does not match.
+(define (match-opt input pattern)
+  (let ((match (match-pattern input (car pattern))))
+    (if match match input)))
+
+; Match anything (other than '()), until pattern is found. The rather
+; clumsy form of requiring an ending pattern is needed to decide where
+; the end of the match is. If none is given, this will match the rest
+; of the sentence.
+(define (match-any input pattern)
+  (cond ((null? (remain input)) #f)
+	((null? pattern) (f-cons (remain input) (clear-remain input)))
+	(else
+	 (let ((accum-any (collector)))
+	   (define (match-pattern-any input pattern)
+	     (cond ((null? (remain input)) #f)
+		   (else (accum-any (car (remain input)))
+			 (cond ((match-pattern (r-cdr input) pattern))
+			       (else (match-pattern-any (r-cdr input) pattern))))))
+	   (let ((retval (match-pattern-any input (car pattern))))
+	     (if retval
+		 (f-cons (accum-any) retval)
+		 #f))))))
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-scheme</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/scheme/scheme.js b/app/gui/html/vendor/codemirror/mode/scheme/scheme.js
new file mode 100644
index 0000000..7124f72
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/scheme/scheme.js
@@ -0,0 +1,245 @@
+/**
+ * Author: Koh Zi Han, based on implementation by Koh Zi Chun
+ */
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("scheme", function () {
+    var BUILTIN = "builtin", COMMENT = "comment", STRING = "string",
+        ATOM = "atom", NUMBER = "number", BRACKET = "bracket";
+    var INDENT_WORD_SKIP = 2;
+
+    function makeKeywords(str) {
+        var obj = {}, words = str.split(" ");
+        for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+        return obj;
+    }
+
+    var keywords = makeKeywords("λ case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci<? char-ci=? char-ci>=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char<? char=? char>=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt #f floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci<? string-ci=? string-ci>=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string<? string=? string>=? string>? string? substring symbol->string symbol? #t tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?");
+    var indentKeys = makeKeywords("define let letrec let* lambda");
+
+    function stateStack(indent, type, prev) { // represents a state stack object
+        this.indent = indent;
+        this.type = type;
+        this.prev = prev;
+    }
+
+    function pushStack(state, indent, type) {
+        state.indentStack = new stateStack(indent, type, state.indentStack);
+    }
+
+    function popStack(state) {
+        state.indentStack = state.indentStack.prev;
+    }
+
+    var binaryMatcher = new RegExp(/^(?:[-+]i|[-+][01]+#*(?:\/[01]+#*)?i|[-+]?[01]+#*(?:\/[01]+#*)?@[-+]?[01]+#*(?:\/[01]+#*)?|[-+]?[01]+#*(?:\/[01]+#*)?[-+](?:[01]+#*(?:\/[01]+#*)?)?i|[-+]?[01]+#*(?:\/[01]+#*)?)(?=[()\s;"]|$)/i);
+    var octalMatcher = new RegExp(/^(?:[-+]i|[-+][0-7]+#*(?:\/[0-7]+#*)?i|[-+]?[0-7]+#*(?:\/[0-7]+#*)?@[-+]?[0-7]+#*(?:\/[0-7]+#*)?|[-+]?[0-7]+#*(?:\/[0-7]+#*)?[-+](?:[0-7]+#*(?:\/[0-7]+#*)?)?i|[-+]?[0-7]+#*(?:\/[0-7]+#*)?)(?=[()\s;"]|$)/i);
+    var hexMatcher = new RegExp(/^(?:[-+]i|[-+][\da-f]+#*(?:\/[\da-f]+#*)?i|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?@[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?[-+](?:[\da-f]+#*(?:\/[\da-f]+#*)?)?i|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?)(?=[()\s;"]|$)/i);
+    var decimalMatcher = new RegExp(/^(?:[-+]i|[-+](?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)i|[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)@[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)|[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)[-+](?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)?i|(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*))(?=[()\s;"]|$)/i);
+
+    function isBinaryNumber (stream) {
+        return stream.match(binaryMatcher);
+    }
+
+    function isOctalNumber (stream) {
+        return stream.match(octalMatcher);
+    }
+
+    function isDecimalNumber (stream, backup) {
+        if (backup === true) {
+            stream.backUp(1);
+        }
+        return stream.match(decimalMatcher);
+    }
+
+    function isHexNumber (stream) {
+        return stream.match(hexMatcher);
+    }
+
+    return {
+        startState: function () {
+            return {
+                indentStack: null,
+                indentation: 0,
+                mode: false,
+                sExprComment: false
+            };
+        },
+
+        token: function (stream, state) {
+            if (state.indentStack == null && stream.sol()) {
+                // update indentation, but only if indentStack is empty
+                state.indentation = stream.indentation();
+            }
+
+            // skip spaces
+            if (stream.eatSpace()) {
+                return null;
+            }
+            var returnType = null;
+
+            switch(state.mode){
+                case "string": // multi-line string parsing mode
+                    var next, escaped = false;
+                    while ((next = stream.next()) != null) {
+                        if (next == "\"" && !escaped) {
+
+                            state.mode = false;
+                            break;
+                        }
+                        escaped = !escaped && next == "\\";
+                    }
+                    returnType = STRING; // continue on in scheme-string mode
+                    break;
+                case "comment": // comment parsing mode
+                    var next, maybeEnd = false;
+                    while ((next = stream.next()) != null) {
+                        if (next == "#" && maybeEnd) {
+
+                            state.mode = false;
+                            break;
+                        }
+                        maybeEnd = (next == "|");
+                    }
+                    returnType = COMMENT;
+                    break;
+                case "s-expr-comment": // s-expr commenting mode
+                    state.mode = false;
+                    if(stream.peek() == "(" || stream.peek() == "["){
+                        // actually start scheme s-expr commenting mode
+                        state.sExprComment = 0;
+                    }else{
+                        // if not we just comment the entire of the next token
+                        stream.eatWhile(/[^/s]/); // eat non spaces
+                        returnType = COMMENT;
+                        break;
+                    }
+                default: // default parsing mode
+                    var ch = stream.next();
+
+                    if (ch == "\"") {
+                        state.mode = "string";
+                        returnType = STRING;
+
+                    } else if (ch == "'") {
+                        returnType = ATOM;
+                    } else if (ch == '#') {
+                        if (stream.eat("|")) {                    // Multi-line comment
+                            state.mode = "comment"; // toggle to comment mode
+                            returnType = COMMENT;
+                        } else if (stream.eat(/[tf]/i)) {            // #t/#f (atom)
+                            returnType = ATOM;
+                        } else if (stream.eat(';')) {                // S-Expr comment
+                            state.mode = "s-expr-comment";
+                            returnType = COMMENT;
+                        } else {
+                            var numTest = null, hasExactness = false, hasRadix = true;
+                            if (stream.eat(/[ei]/i)) {
+                                hasExactness = true;
+                            } else {
+                                stream.backUp(1);       // must be radix specifier
+                            }
+                            if (stream.match(/^#b/i)) {
+                                numTest = isBinaryNumber;
+                            } else if (stream.match(/^#o/i)) {
+                                numTest = isOctalNumber;
+                            } else if (stream.match(/^#x/i)) {
+                                numTest = isHexNumber;
+                            } else if (stream.match(/^#d/i)) {
+                                numTest = isDecimalNumber;
+                            } else if (stream.match(/^[-+0-9.]/, false)) {
+                                hasRadix = false;
+                                numTest = isDecimalNumber;
+                            // re-consume the intial # if all matches failed
+                            } else if (!hasExactness) {
+                                stream.eat('#');
+                            }
+                            if (numTest != null) {
+                                if (hasRadix && !hasExactness) {
+                                    // consume optional exactness after radix
+                                    stream.match(/^#[ei]/i);
+                                }
+                                if (numTest(stream))
+                                    returnType = NUMBER;
+                            }
+                        }
+                    } else if (/^[-+0-9.]/.test(ch) && isDecimalNumber(stream, true)) { // match non-prefixed number, must be decimal
+                        returnType = NUMBER;
+                    } else if (ch == ";") { // comment
+                        stream.skipToEnd(); // rest of the line is a comment
+                        returnType = COMMENT;
+                    } else if (ch == "(" || ch == "[") {
+                      var keyWord = ''; var indentTemp = stream.column(), letter;
+                        /**
+                        Either
+                        (indent-word ..
+                        (non-indent-word ..
+                        (;something else, bracket, etc.
+                        */
+
+                        while ((letter = stream.eat(/[^\s\(\[\;\)\]]/)) != null) {
+                            keyWord += letter;
+                        }
+
+                        if (keyWord.length > 0 && indentKeys.propertyIsEnumerable(keyWord)) { // indent-word
+
+                            pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);
+                        } else { // non-indent word
+                            // we continue eating the spaces
+                            stream.eatSpace();
+                            if (stream.eol() || stream.peek() == ";") {
+                                // nothing significant after
+                                // we restart indentation 1 space after
+                                pushStack(state, indentTemp + 1, ch);
+                            } else {
+                                pushStack(state, indentTemp + stream.current().length, ch); // else we match
+                            }
+                        }
+                        stream.backUp(stream.current().length - 1); // undo all the eating
+
+                        if(typeof state.sExprComment == "number") state.sExprComment++;
+
+                        returnType = BRACKET;
+                    } else if (ch == ")" || ch == "]") {
+                        returnType = BRACKET;
+                        if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : "[")) {
+                            popStack(state);
+
+                            if(typeof state.sExprComment == "number"){
+                                if(--state.sExprComment == 0){
+                                    returnType = COMMENT; // final closing bracket
+                                    state.sExprComment = false; // turn off s-expr commenting mode
+                                }
+                            }
+                        }
+                    } else {
+                        stream.eatWhile(/[\w\$_\-!$%&*+\.\/:<=>?@\^~]/);
+
+                        if (keywords && keywords.propertyIsEnumerable(stream.current())) {
+                            returnType = BUILTIN;
+                        } else returnType = "variable";
+                    }
+            }
+            return (typeof state.sExprComment == "number") ? COMMENT : returnType;
+        },
+
+        indent: function (state) {
+            if (state.indentStack == null) return state.indentation;
+            return state.indentStack.indent;
+        },
+
+        lineComment: ";;"
+    };
+});
+
+CodeMirror.defineMIME("text/x-scheme", "scheme");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/shell/index.html b/app/gui/html/vendor/codemirror/mode/shell/index.html
new file mode 100644
index 0000000..cf415e8
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/shell/index.html
@@ -0,0 +1,66 @@
+<!doctype html>
+
+<title>CodeMirror: Shell mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel=stylesheet href=../../lib/codemirror.css>
+<script src=../../lib/codemirror.js></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src=shell.js></script>
+<style type=text/css>
+  .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Shell</a>
+  </ul>
+</div>
+
+<article>
+<h2>Shell mode</h2>
+
+
+<textarea id=code>
+#!/bin/bash
+
+# clone the repository
+git clone http://github.com/garden/tree
+
+# generate HTTPS credentials
+cd tree
+openssl genrsa -aes256 -out https.key 1024
+openssl req -new -nodes -key https.key -out https.csr
+openssl x509 -req -days 365 -in https.csr -signkey https.key -out https.crt
+cp https.key{,.orig}
+openssl rsa -in https.key.orig -out https.key
+
+# start the server in HTTPS mode
+cd web
+sudo node ../server.js 443 'yes' >> ../node.log &
+
+# here is how to stop the server
+for pid in `ps aux | grep 'node ../server.js' | awk '{print $2}'` ; do
+  sudo kill -9 $pid 2> /dev/null
+done
+
+exit 0</textarea>
+
+<script>
+  var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
+    mode: 'shell',
+    lineNumbers: true,
+    matchBrackets: true
+  });
+</script>
+
+<p><strong>MIME types defined:</strong> <code>text/x-sh</code>.</p>
+</article>
diff --git a/app/gui/html/vendor/codemirror/mode/shell/shell.js b/app/gui/html/vendor/codemirror/mode/shell/shell.js
new file mode 100644
index 0000000..7753411
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/shell/shell.js
@@ -0,0 +1,130 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode('shell', function() {
+
+  var words = {};
+  function define(style, string) {
+    var split = string.split(' ');
+    for(var i = 0; i < split.length; i++) {
+      words[split[i]] = style;
+    }
+  };
+
+  // Atoms
+  define('atom', 'true false');
+
+  // Keywords
+  define('keyword', 'if then do else elif while until for in esac fi fin ' +
+    'fil done exit set unset export function');
+
+  // Commands
+  define('builtin', 'ab awk bash beep cat cc cd chown chmod chroot clear cp ' +
+    'curl cut diff echo find gawk gcc get git grep kill killall ln ls make ' +
+    'mkdir openssl mv nc node npm ping ps restart rm rmdir sed service sh ' +
+    'shopt shred source sort sleep ssh start stop su sudo tee telnet top ' +
+    'touch vi vim wall wc wget who write yes zsh');
+
+  function tokenBase(stream, state) {
+
+    var sol = stream.sol();
+    var ch = stream.next();
+
+    if (ch === '\'' || ch === '"' || ch === '`') {
+      state.tokens.unshift(tokenString(ch));
+      return tokenize(stream, state);
+    }
+    if (ch === '#') {
+      if (sol && stream.eat('!')) {
+        stream.skipToEnd();
+        return 'meta'; // 'comment'?
+      }
+      stream.skipToEnd();
+      return 'comment';
+    }
+    if (ch === '$') {
+      state.tokens.unshift(tokenDollar);
+      return tokenize(stream, state);
+    }
+    if (ch === '+' || ch === '=') {
+      return 'operator';
+    }
+    if (ch === '-') {
+      stream.eat('-');
+      stream.eatWhile(/\w/);
+      return 'attribute';
+    }
+    if (/\d/.test(ch)) {
+      stream.eatWhile(/\d/);
+      if(!/\w/.test(stream.peek())) {
+        return 'number';
+      }
+    }
+    stream.eatWhile(/[\w-]/);
+    var cur = stream.current();
+    if (stream.peek() === '=' && /\w+/.test(cur)) return 'def';
+    return words.hasOwnProperty(cur) ? words[cur] : null;
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var next, end = false, escaped = false;
+      while ((next = stream.next()) != null) {
+        if (next === quote && !escaped) {
+          end = true;
+          break;
+        }
+        if (next === '$' && !escaped && quote !== '\'') {
+          escaped = true;
+          stream.backUp(1);
+          state.tokens.unshift(tokenDollar);
+          break;
+        }
+        escaped = !escaped && next === '\\';
+      }
+      if (end || !escaped) {
+        state.tokens.shift();
+      }
+      return (quote === '`' || quote === ')' ? 'quote' : 'string');
+    };
+  };
+
+  var tokenDollar = function(stream, state) {
+    if (state.tokens.length > 1) stream.eat('$');
+    var ch = stream.next(), hungry = /\w/;
+    if (ch === '{') hungry = /[^}]/;
+    if (ch === '(') {
+      state.tokens[0] = tokenString(')');
+      return tokenize(stream, state);
+    }
+    if (!/\d/.test(ch)) {
+      stream.eatWhile(hungry);
+      stream.eat('}');
+    }
+    state.tokens.shift();
+    return 'def';
+  };
+
+  function tokenize(stream, state) {
+    return (state.tokens[0] || tokenBase) (stream, state);
+  };
+
+  return {
+    startState: function() {return {tokens:[]};},
+    token: function(stream, state) {
+      if (stream.eatSpace()) return null;
+      return tokenize(stream, state);
+    }
+  };
+});
+
+CodeMirror.defineMIME('text/x-sh', 'shell');
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/sieve/index.html b/app/gui/html/vendor/codemirror/mode/sieve/index.html
new file mode 100644
index 0000000..9d814a9
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/sieve/index.html
@@ -0,0 +1,93 @@
+<!doctype html>
+
+<title>CodeMirror: Sieve (RFC5228) mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="sieve.js"></script>
+<style>.CodeMirror {background: #f8f8f8;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Sieve (RFC5228)</a>
+  </ul>
+</div>
+
+<article>
+<h2>Sieve (RFC5228) mode</h2>
+<form><textarea id="code" name="code">
+#
+# Example Sieve Filter
+# Declare any optional features or extension used by the script
+#
+
+require ["fileinto", "reject"];
+
+#
+# Reject any large messages (note that the four leading dots get
+# "stuffed" to three)
+#
+if size :over 1M
+{
+  reject text:
+Please do not send me large attachments.
+Put your file on a server and send me the URL.
+Thank you.
+.... Fred
+.
+;
+  stop;
+}
+
+#
+# Handle messages from known mailing lists
+# Move messages from IETF filter discussion list to filter folder
+#
+if header :is "Sender" "owner-ietf-mta-filters at imc.org"
+{
+  fileinto "filter";  # move to "filter" folder
+}
+#
+# Keep all messages to or from people in my company
+#
+elsif address :domain :is ["From", "To"] "example.com"
+{
+  keep;               # keep in "In" folder
+}
+
+#
+# Try and catch unsolicited email.  If a message is not to me,
+# or it contains a subject known to be spam, file it away.
+#
+elsif anyof (not address :all :contains
+               ["To", "Cc", "Bcc"] "me at example.com",
+             header :matches "subject"
+               ["*make*money*fast*", "*university*dipl*mas*"])
+{
+  # If message header does not contain my address,
+  # it's from a list.
+  fileinto "spam";   # move to "spam" folder
+}
+else
+{
+  # Move all other (non-company) mail to "personal"
+  # folder.
+  fileinto "personal";
+}
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>application/sieve</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/sieve/sieve.js b/app/gui/html/vendor/codemirror/mode/sieve/sieve.js
new file mode 100644
index 0000000..8256dda
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/sieve/sieve.js
@@ -0,0 +1,190 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("sieve", function(config) {
+  function words(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+
+  var keywords = words("if elsif else stop require");
+  var atoms = words("true false not");
+  var indentUnit = config.indentUnit;
+
+  function tokenBase(stream, state) {
+
+    var ch = stream.next();
+    if (ch == "/" && stream.eat("*")) {
+      state.tokenize = tokenCComment;
+      return tokenCComment(stream, state);
+    }
+
+    if (ch === '#') {
+      stream.skipToEnd();
+      return "comment";
+    }
+
+    if (ch == "\"") {
+      state.tokenize = tokenString(ch);
+      return state.tokenize(stream, state);
+    }
+
+    if (ch == "(") {
+      state._indent.push("(");
+      // add virtual angel wings so that editor behaves...
+      // ...more sane incase of broken brackets
+      state._indent.push("{");
+      return null;
+    }
+
+    if (ch === "{") {
+      state._indent.push("{");
+      return null;
+    }
+
+    if (ch == ")")  {
+      state._indent.pop();
+      state._indent.pop();
+    }
+
+    if (ch === "}") {
+      state._indent.pop();
+      return null;
+    }
+
+    if (ch == ",")
+      return null;
+
+    if (ch == ";")
+      return null;
+
+
+    if (/[{}\(\),;]/.test(ch))
+      return null;
+
+    // 1*DIGIT "K" / "M" / "G"
+    if (/\d/.test(ch)) {
+      stream.eatWhile(/[\d]/);
+      stream.eat(/[KkMmGg]/);
+      return "number";
+    }
+
+    // ":" (ALPHA / "_") *(ALPHA / DIGIT / "_")
+    if (ch == ":") {
+      stream.eatWhile(/[a-zA-Z_]/);
+      stream.eatWhile(/[a-zA-Z0-9_]/);
+
+      return "operator";
+    }
+
+    stream.eatWhile(/\w/);
+    var cur = stream.current();
+
+    // "text:" *(SP / HTAB) (hash-comment / CRLF)
+    // *(multiline-literal / multiline-dotstart)
+    // "." CRLF
+    if ((cur == "text") && stream.eat(":"))
+    {
+      state.tokenize = tokenMultiLineString;
+      return "string";
+    }
+
+    if (keywords.propertyIsEnumerable(cur))
+      return "keyword";
+
+    if (atoms.propertyIsEnumerable(cur))
+      return "atom";
+
+    return null;
+  }
+
+  function tokenMultiLineString(stream, state)
+  {
+    state._multiLineString = true;
+    // the first line is special it may contain a comment
+    if (!stream.sol()) {
+      stream.eatSpace();
+
+      if (stream.peek() == "#") {
+        stream.skipToEnd();
+        return "comment";
+      }
+
+      stream.skipToEnd();
+      return "string";
+    }
+
+    if ((stream.next() == ".")  && (stream.eol()))
+    {
+      state._multiLineString = false;
+      state.tokenize = tokenBase;
+    }
+
+    return "string";
+  }
+
+  function tokenCComment(stream, state) {
+    var maybeEnd = false, ch;
+    while ((ch = stream.next()) != null) {
+      if (maybeEnd && ch == "/") {
+        state.tokenize = tokenBase;
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return "comment";
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, ch;
+      while ((ch = stream.next()) != null) {
+        if (ch == quote && !escaped)
+          break;
+        escaped = !escaped && ch == "\\";
+      }
+      if (!escaped) state.tokenize = tokenBase;
+      return "string";
+    };
+  }
+
+  return {
+    startState: function(base) {
+      return {tokenize: tokenBase,
+              baseIndent: base || 0,
+              _indent: []};
+    },
+
+    token: function(stream, state) {
+      if (stream.eatSpace())
+        return null;
+
+      return (state.tokenize || tokenBase)(stream, state);;
+    },
+
+    indent: function(state, _textAfter) {
+      var length = state._indent.length;
+      if (_textAfter && (_textAfter[0] == "}"))
+        length--;
+
+      if (length <0)
+        length = 0;
+
+      return length * indentUnit;
+    },
+
+    electricChars: "}"
+  };
+});
+
+CodeMirror.defineMIME("application/sieve", "sieve");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/smalltalk/index.html b/app/gui/html/vendor/codemirror/mode/smalltalk/index.html
new file mode 100644
index 0000000..0d2b172
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/smalltalk/index.html
@@ -0,0 +1,68 @@
+<!doctype html>
+
+<title>CodeMirror: Smalltalk mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="smalltalk.js"></script>
+<style>
+      .CodeMirror {border: 2px solid #dee; border-right-width: 10px;}
+      .CodeMirror-gutter {border: none; background: #dee;}
+      .CodeMirror-gutter pre {color: white; font-weight: bold;}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Smalltalk</a>
+  </ul>
+</div>
+
+<article>
+<h2>Smalltalk mode</h2>
+<form><textarea id="code" name="code">
+" 
+    This is a test of the Smalltalk code
+"
+Seaside.WAComponent subclass: #MyCounter [
+    | count |
+    MyCounter class >> canBeRoot [ ^true ]
+
+    initialize [
+        super initialize.
+        count := 0.
+    ]
+    states [ ^{ self } ]
+    renderContentOn: html [
+        html heading: count.
+        html anchor callback: [ count := count + 1 ]; with: '++'.
+        html space.
+        html anchor callback: [ count := count - 1 ]; with: '--'.
+    ]
+]
+
+MyCounter registerAsApplication: 'mycounter'
+</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        mode: "text/x-stsrc",
+        indentUnit: 4
+      });
+    </script>
+
+    <p>Simple Smalltalk mode.</p>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-stsrc</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/smalltalk/smalltalk.js b/app/gui/html/vendor/codemirror/mode/smalltalk/smalltalk.js
new file mode 100644
index 0000000..deb78a4
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/smalltalk/smalltalk.js
@@ -0,0 +1,165 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode('smalltalk', function(config) {
+
+  var specialChars = /[+\-\/\\*~<>=@%|&?!.,:;^]/;
+  var keywords = /true|false|nil|self|super|thisContext/;
+
+  var Context = function(tokenizer, parent) {
+    this.next = tokenizer;
+    this.parent = parent;
+  };
+
+  var Token = function(name, context, eos) {
+    this.name = name;
+    this.context = context;
+    this.eos = eos;
+  };
+
+  var State = function() {
+    this.context = new Context(next, null);
+    this.expectVariable = true;
+    this.indentation = 0;
+    this.userIndentationDelta = 0;
+  };
+
+  State.prototype.userIndent = function(indentation) {
+    this.userIndentationDelta = indentation > 0 ? (indentation / config.indentUnit - this.indentation) : 0;
+  };
+
+  var next = function(stream, context, state) {
+    var token = new Token(null, context, false);
+    var aChar = stream.next();
+
+    if (aChar === '"') {
+      token = nextComment(stream, new Context(nextComment, context));
+
+    } else if (aChar === '\'') {
+      token = nextString(stream, new Context(nextString, context));
+
+    } else if (aChar === '#') {
+      if (stream.peek() === '\'') {
+        stream.next();
+        token = nextSymbol(stream, new Context(nextSymbol, context));
+      } else {
+        if (stream.eatWhile(/[^ .{}\[\]()]/))
+          token.name = 'string-2';
+        else
+          token.name = 'meta';
+      }
+
+    } else if (aChar === '$') {
+      if (stream.next() === '<') {
+        stream.eatWhile(/[^ >]/);
+        stream.next();
+      }
+      token.name = 'string-2';
+
+    } else if (aChar === '|' && state.expectVariable) {
+      token.context = new Context(nextTemporaries, context);
+
+    } else if (/[\[\]{}()]/.test(aChar)) {
+      token.name = 'bracket';
+      token.eos = /[\[{(]/.test(aChar);
+
+      if (aChar === '[') {
+        state.indentation++;
+      } else if (aChar === ']') {
+        state.indentation = Math.max(0, state.indentation - 1);
+      }
+
+    } else if (specialChars.test(aChar)) {
+      stream.eatWhile(specialChars);
+      token.name = 'operator';
+      token.eos = aChar !== ';'; // ; cascaded message expression
+
+    } else if (/\d/.test(aChar)) {
+      stream.eatWhile(/[\w\d]/);
+      token.name = 'number';
+
+    } else if (/[\w_]/.test(aChar)) {
+      stream.eatWhile(/[\w\d_]/);
+      token.name = state.expectVariable ? (keywords.test(stream.current()) ? 'keyword' : 'variable') : null;
+
+    } else {
+      token.eos = state.expectVariable;
+    }
+
+    return token;
+  };
+
+  var nextComment = function(stream, context) {
+    stream.eatWhile(/[^"]/);
+    return new Token('comment', stream.eat('"') ? context.parent : context, true);
+  };
+
+  var nextString = function(stream, context) {
+    stream.eatWhile(/[^']/);
+    return new Token('string', stream.eat('\'') ? context.parent : context, false);
+  };
+
+  var nextSymbol = function(stream, context) {
+    stream.eatWhile(/[^']/);
+    return new Token('string-2', stream.eat('\'') ? context.parent : context, false);
+  };
+
+  var nextTemporaries = function(stream, context) {
+    var token = new Token(null, context, false);
+    var aChar = stream.next();
+
+    if (aChar === '|') {
+      token.context = context.parent;
+      token.eos = true;
+
+    } else {
+      stream.eatWhile(/[^|]/);
+      token.name = 'variable';
+    }
+
+    return token;
+  };
+
+  return {
+    startState: function() {
+      return new State;
+    },
+
+    token: function(stream, state) {
+      state.userIndent(stream.indentation());
+
+      if (stream.eatSpace()) {
+        return null;
+      }
+
+      var token = state.context.next(stream, state.context, state);
+      state.context = token.context;
+      state.expectVariable = token.eos;
+
+      return token.name;
+    },
+
+    blankLine: function(state) {
+      state.userIndent(0);
+    },
+
+    indent: function(state, textAfter) {
+      var i = state.context.next === next && textAfter && textAfter.charAt(0) === ']' ? -1 : state.userIndentationDelta;
+      return (state.indentation + i) * config.indentUnit;
+    },
+
+    electricChars: ']'
+  };
+
+});
+
+CodeMirror.defineMIME('text/x-stsrc', {name: 'smalltalk'});
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/smarty/index.html b/app/gui/html/vendor/codemirror/mode/smarty/index.html
new file mode 100644
index 0000000..d458aef
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/smarty/index.html
@@ -0,0 +1,136 @@
+<!doctype html>
+
+<title>CodeMirror: Smarty mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="smarty.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Smarty</a>
+  </ul>
+</div>
+
+<article>
+<h2>Smarty mode</h2>
+<form><textarea id="code" name="code">
+{extends file="parent.tpl"}
+{include file="template.tpl"}
+
+{* some example Smarty content *}
+{if isset($name) && $name == 'Blog'}
+  This is a {$var}.
+  {$integer = 451}, {$array[] = "a"}, {$stringvar = "string"}
+  {assign var='bob' value=$var.prop}
+{elseif $name == $foo}
+  {function name=menu level=0}
+    {foreach $data as $entry}
+      {if is_array($entry)}
+        - {$entry at key}
+        {menu data=$entry level=$level+1}
+      {else}
+        {$entry}
+      {/if}
+    {/foreach}
+  {/function}
+{/if}</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        mode: "smarty"
+      });
+    </script>
+
+    <br />
+
+	<h3>Smarty 2, custom delimiters</h3>
+    <form><textarea id="code2" name="code2">
+{--extends file="parent.tpl"--}
+{--include file="template.tpl"--}
+
+{--* some example Smarty content *--}
+{--if isset($name) && $name == 'Blog'--}
+  This is a {--$var--}.
+  {--$integer = 451--}, {--$array[] = "a"--}, {--$stringvar = "string"--}
+  {--assign var='bob' value=$var.prop--}
+{--elseif $name == $foo--}
+  {--function name=menu level=0--}
+    {--foreach $data as $entry--}
+      {--if is_array($entry)--}
+        - {--$entry at key--}
+        {--menu data=$entry level=$level+1--}
+      {--else--}
+        {--$entry--}
+      {--/if--}
+    {--/foreach--}
+  {--/function--}
+{--/if--}</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code2"), {
+        lineNumbers: true,
+        mode: {
+          name: "smarty",
+          leftDelimiter: "{--",
+          rightDelimiter: "--}"
+        }
+      });
+    </script>
+
+	<br />
+
+	<h3>Smarty 3</h3>
+
+	<textarea id="code3" name="code3">
+Nested tags {$foo={counter one=1 two={inception}}+3} are now valid in Smarty 3.
+
+<script>
+function test() {
+	console.log("Smarty 3 permits single curly braces followed by whitespace to NOT slip into Smarty mode.");
+}
+</script>
+
+{assign var=foo value=[1,2,3]}
+{assign var=foo value=['y'=>'yellow','b'=>'blue']}
+{assign var=foo value=[1,[9,8],3]}
+
+{$foo=$bar+2} {* a comment *}
+{$foo.bar=1}  {* another comment *}
+{$foo = myfunct(($x+$y)*3)}
+{$foo = strlen($bar)}
+{$foo.bar.baz=1}, {$foo[]=1}
+
+Smarty "dot" syntax (note: embedded {} are used to address ambiguities):
+
+{$foo.a.b.c}      => $foo['a']['b']['c']
+{$foo.a.$b.c}     => $foo['a'][$b]['c']
+{$foo.a.{$b+4}.c} => $foo['a'][$b+4]['c']
+{$foo.a.{$b.c}}   => $foo['a'][$b['c']]
+
+{$object->method1($x)->method2($y)}</textarea>
+
+	<script>
+		var editor = CodeMirror.fromTextArea(document.getElementById("code3"), {
+			lineNumbers: true,
+			mode: "smarty",
+			smartyVersion: 3
+		});
+	</script>
+
+
+    <p>A plain text/Smarty version 2 or 3 mode, which allows for custom delimiter tags.</p>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-smarty</code></p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/smarty/smarty.js b/app/gui/html/vendor/codemirror/mode/smarty/smarty.js
new file mode 100644
index 0000000..2a78c6d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/smarty/smarty.js
@@ -0,0 +1,218 @@
+/**
+ * Smarty 2 and 3 mode.
+ */
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("smarty", function(config) {
+  "use strict";
+
+  // our default settings; check to see if they're overridden
+  var settings = {
+    rightDelimiter: '}',
+    leftDelimiter: '{',
+    smartyVersion: 2 // for backward compatibility
+  };
+  if (config.hasOwnProperty("leftDelimiter")) {
+    settings.leftDelimiter = config.leftDelimiter;
+  }
+  if (config.hasOwnProperty("rightDelimiter")) {
+    settings.rightDelimiter = config.rightDelimiter;
+  }
+  if (config.hasOwnProperty("smartyVersion") && config.smartyVersion === 3) {
+    settings.smartyVersion = 3;
+  }
+
+  var keyFunctions = ["debug", "extends", "function", "include", "literal"];
+  var last;
+  var regs = {
+    operatorChars: /[+\-*&%=<>!?]/,
+    validIdentifier: /[a-zA-Z0-9_]/,
+    stringChar: /['"]/
+  };
+
+  var helpers = {
+    cont: function(style, lastType) {
+      last = lastType;
+      return style;
+    },
+    chain: function(stream, state, parser) {
+      state.tokenize = parser;
+      return parser(stream, state);
+    }
+  };
+
+
+  // our various parsers
+  var parsers = {
+
+    // the main tokenizer
+    tokenizer: function(stream, state) {
+      if (stream.match(settings.leftDelimiter, true)) {
+        if (stream.eat("*")) {
+          return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter));
+        } else {
+          // Smarty 3 allows { and } surrounded by whitespace to NOT slip into Smarty mode
+          state.depth++;
+          var isEol = stream.eol();
+          var isFollowedByWhitespace = /\s/.test(stream.peek());
+          if (settings.smartyVersion === 3 && settings.leftDelimiter === "{" && (isEol || isFollowedByWhitespace)) {
+            state.depth--;
+            return null;
+          } else {
+            state.tokenize = parsers.smarty;
+            last = "startTag";
+            return "tag";
+          }
+        }
+      } else {
+        stream.next();
+        return null;
+      }
+    },
+
+    // parsing Smarty content
+    smarty: function(stream, state) {
+      if (stream.match(settings.rightDelimiter, true)) {
+        if (settings.smartyVersion === 3) {
+          state.depth--;
+          if (state.depth <= 0) {
+            state.tokenize = parsers.tokenizer;
+          }
+        } else {
+          state.tokenize = parsers.tokenizer;
+        }
+        return helpers.cont("tag", null);
+      }
+
+      if (stream.match(settings.leftDelimiter, true)) {
+        state.depth++;
+        return helpers.cont("tag", "startTag");
+      }
+
+      var ch = stream.next();
+      if (ch == "$") {
+        stream.eatWhile(regs.validIdentifier);
+        return helpers.cont("variable-2", "variable");
+      } else if (ch == "|") {
+        return helpers.cont("operator", "pipe");
+      } else if (ch == ".") {
+        return helpers.cont("operator", "property");
+      } else if (regs.stringChar.test(ch)) {
+        state.tokenize = parsers.inAttribute(ch);
+        return helpers.cont("string", "string");
+      } else if (regs.operatorChars.test(ch)) {
+        stream.eatWhile(regs.operatorChars);
+        return helpers.cont("operator", "operator");
+      } else if (ch == "[" || ch == "]") {
+        return helpers.cont("bracket", "bracket");
+      } else if (ch == "(" || ch == ")") {
+        return helpers.cont("bracket", "operator");
+      } else if (/\d/.test(ch)) {
+        stream.eatWhile(/\d/);
+        return helpers.cont("number", "number");
+      } else {
+
+        if (state.last == "variable") {
+          if (ch == "@") {
+            stream.eatWhile(regs.validIdentifier);
+            return helpers.cont("property", "property");
+          } else if (ch == "|") {
+            stream.eatWhile(regs.validIdentifier);
+            return helpers.cont("qualifier", "modifier");
+          }
+        } else if (state.last == "pipe") {
+          stream.eatWhile(regs.validIdentifier);
+          return helpers.cont("qualifier", "modifier");
+        } else if (state.last == "whitespace") {
+          stream.eatWhile(regs.validIdentifier);
+          return helpers.cont("attribute", "modifier");
+        } if (state.last == "property") {
+          stream.eatWhile(regs.validIdentifier);
+          return helpers.cont("property", null);
+        } else if (/\s/.test(ch)) {
+          last = "whitespace";
+          return null;
+        }
+
+        var str = "";
+        if (ch != "/") {
+          str += ch;
+        }
+        var c = null;
+        while (c = stream.eat(regs.validIdentifier)) {
+          str += c;
+        }
+        for (var i=0, j=keyFunctions.length; i<j; i++) {
+          if (keyFunctions[i] == str) {
+            return helpers.cont("keyword", "keyword");
+          }
+        }
+        if (/\s/.test(ch)) {
+          return null;
+        }
+        return helpers.cont("tag", "tag");
+      }
+    },
+
+    inAttribute: function(quote) {
+      return function(stream, state) {
+        var prevChar = null;
+        var currChar = null;
+        while (!stream.eol()) {
+          currChar = stream.peek();
+          if (stream.next() == quote && prevChar !== '\\') {
+            state.tokenize = parsers.smarty;
+            break;
+          }
+          prevChar = currChar;
+        }
+        return "string";
+      };
+    },
+
+    inBlock: function(style, terminator) {
+      return function(stream, state) {
+        while (!stream.eol()) {
+          if (stream.match(terminator)) {
+            state.tokenize = parsers.tokenizer;
+            break;
+          }
+          stream.next();
+        }
+        return style;
+      };
+    }
+  };
+
+
+  // the public API for CodeMirror
+  return {
+    startState: function() {
+      return {
+        tokenize: parsers.tokenizer,
+        mode: "smarty",
+        last: null,
+        depth: 0
+      };
+    },
+    token: function(stream, state) {
+      var style = state.tokenize(stream, state);
+      state.last = last;
+      return style;
+    },
+    electricChars: ""
+  };
+});
+
+CodeMirror.defineMIME("text/x-smarty", "smarty");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/smartymixed/index.html b/app/gui/html/vendor/codemirror/mode/smartymixed/index.html
new file mode 100644
index 0000000..47c805f
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/smartymixed/index.html
@@ -0,0 +1,114 @@
+<!doctype html>
+
+<title>CodeMirror: Smarty mixed mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../mode/xml/xml.js"></script>
+<script src="../../mode/javascript/javascript.js"></script>
+<script src="../../mode/css/css.js"></script>
+<script src="../../mode/htmlmixed/htmlmixed.js"></script>
+<script src="../../mode/smarty/smarty.js"></script>
+<script src="../../mode/smartymixed/smartymixed.js"></script>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Smarty mixed</a>
+  </ul>
+</div>
+
+<article>
+<h2>Smarty mixed mode</h2>
+<form><textarea id="code" name="code">
+{**
+* @brief Smarty mixed mode
+* @author Ruslan Osmanov
+* @date 29.06.2013
+*}
+<html>
+<head>
+  <title>{$title|htmlspecialchars|truncate:30}</title>
+</head>
+<body class="{$bodyclass}">
+  {* Multiline smarty
+  * comment, no {$variables} here
+  *}
+  {literal}
+  {literal} is just an HTML text.
+  <script type="text/javascript">//<![CDATA[
+    var a = {$just_a_normal_js_object : "value"};
+    var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("code"), {
+      mode           : "smartymixed",
+      tabSize        : 2,
+      indentUnit     : 2,
+      indentWithTabs : false,
+      lineNumbers    : true,
+      smartyVersion  : 3
+    });
+    // ]]>
+  </script>
+  <style>
+    /* CSS content 
+    {$no_smarty} */
+    .some-class { font-weight: bolder; color: "orange"; }
+  </style>
+  {/literal}
+
+  {extends file="parent.tpl"}
+  {include file="template.tpl"}
+
+  {* some example Smarty content *}
+  {if isset($name) && $name == 'Blog'}
+    This is a {$var}.
+    {$integer = 4511}, {$array[] = "a"}, {$stringvar = "string"}
+    {$integer = 4512} {$array[] = "a"} {$stringvar = "string"}
+    {assign var='bob' value=$var.prop}
+  {elseif $name == $foo}
+    {function name=menu level=0}
+    {foreach $data as $entry}
+      {if is_array($entry)}
+      - {$entry at key}
+      {menu data=$entry level=$level+1}
+      {else}
+      {$entry}
+      {* One
+      * Two
+      * Three
+      *}
+      {/if}
+    {/foreach}
+    {/function}
+  {/if}
+  </body>
+  <!-- R.O. -->
+</html>
+</textarea></form>
+
+    <script type="text/javascript">
+      var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode           : "smartymixed",
+        tabSize        : 2,
+        indentUnit     : 2,
+        indentWithTabs : false,
+        lineNumbers    : true,
+        smartyVersion  : 3,
+        matchBrackets  : true,
+      });
+    </script>
+
+    <p>The Smarty mixed mode depends on the Smarty and HTML mixed modes. HTML
+    mixed mode itself depends on XML, JavaScript, and CSS modes.</p>
+
+    <p>It takes the same options, as Smarty and HTML mixed modes.</p>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-smarty</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/smartymixed/smartymixed.js b/app/gui/html/vendor/codemirror/mode/smartymixed/smartymixed.js
new file mode 100644
index 0000000..7e5e12c
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/smartymixed/smartymixed.js
@@ -0,0 +1,185 @@
+/**
+* @file smartymixed.js
+* @brief Smarty Mixed Codemirror mode (Smarty + Mixed HTML)
+* @author Ruslan Osmanov <rrosmanov at gmail dot com>
+* @version 3.0
+* @date 05.07.2013
+*/
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../smarty/smarty"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../smarty/smarty"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("smartymixed", function(config) {
+  var settings, regs, helpers, parsers,
+  htmlMixedMode = CodeMirror.getMode(config, "htmlmixed"),
+  smartyMode = CodeMirror.getMode(config, "smarty"),
+
+  settings = {
+    rightDelimiter: '}',
+    leftDelimiter: '{'
+  };
+
+  if (config.hasOwnProperty("leftDelimiter")) {
+    settings.leftDelimiter = config.leftDelimiter;
+  }
+  if (config.hasOwnProperty("rightDelimiter")) {
+    settings.rightDelimiter = config.rightDelimiter;
+  }
+
+  regs = {
+    smartyComment: new RegExp("^" + settings.leftDelimiter + "\\*"),
+    literalOpen: new RegExp(settings.leftDelimiter + "literal" + settings.rightDelimiter),
+    literalClose: new RegExp(settings.leftDelimiter + "\/literal" + settings.rightDelimiter),
+    hasLeftDelimeter: new RegExp(".*" + settings.leftDelimiter),
+    htmlHasLeftDelimeter: new RegExp("[^<>]*" + settings.leftDelimiter)
+  };
+
+  helpers = {
+    chain: function(stream, state, parser) {
+      state.tokenize = parser;
+      return parser(stream, state);
+    },
+
+    cleanChain: function(stream, state, parser) {
+      state.tokenize = null;
+      state.localState = null;
+      state.localMode = null;
+      return (typeof parser == "string") ? (parser ? parser : null) : parser(stream, state);
+    },
+
+    maybeBackup: function(stream, pat, style) {
+      var cur = stream.current();
+      var close = cur.search(pat),
+      m;
+      if (close > - 1) stream.backUp(cur.length - close);
+      else if (m = cur.match(/<\/?$/)) {
+        stream.backUp(cur.length);
+        if (!stream.match(pat, false)) stream.match(cur[0]);
+      }
+      return style;
+    }
+  };
+
+  parsers = {
+    html: function(stream, state) {
+      if (!state.inLiteral && stream.match(regs.htmlHasLeftDelimeter, false) && state.htmlMixedState.htmlState.tagName === null) {
+        state.tokenize = parsers.smarty;
+        state.localMode = smartyMode;
+        state.localState = smartyMode.startState(htmlMixedMode.indent(state.htmlMixedState, ""));
+        return helpers.maybeBackup(stream, settings.leftDelimiter, smartyMode.token(stream, state.localState));
+      } else if (!state.inLiteral && stream.match(settings.leftDelimiter, false)) {
+        state.tokenize = parsers.smarty;
+        state.localMode = smartyMode;
+        state.localState = smartyMode.startState(htmlMixedMode.indent(state.htmlMixedState, ""));
+        return helpers.maybeBackup(stream, settings.leftDelimiter, smartyMode.token(stream, state.localState));
+      }
+      return htmlMixedMode.token(stream, state.htmlMixedState);
+    },
+
+    smarty: function(stream, state) {
+      if (stream.match(settings.leftDelimiter, false)) {
+        if (stream.match(regs.smartyComment, false)) {
+          return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter));
+        }
+      } else if (stream.match(settings.rightDelimiter, false)) {
+        stream.eat(settings.rightDelimiter);
+        state.tokenize = parsers.html;
+        state.localMode = htmlMixedMode;
+        state.localState = state.htmlMixedState;
+        return "tag";
+      }
+
+      return helpers.maybeBackup(stream, settings.rightDelimiter, smartyMode.token(stream, state.localState));
+    },
+
+    inBlock: function(style, terminator) {
+      return function(stream, state) {
+        while (!stream.eol()) {
+          if (stream.match(terminator)) {
+            helpers.cleanChain(stream, state, "");
+            break;
+          }
+          stream.next();
+        }
+        return style;
+      };
+    }
+  };
+
+  return {
+    startState: function() {
+      var state = htmlMixedMode.startState();
+      return {
+        token: parsers.html,
+        localMode: null,
+        localState: null,
+        htmlMixedState: state,
+        tokenize: null,
+        inLiteral: false
+      };
+    },
+
+    copyState: function(state) {
+      var local = null, tok = (state.tokenize || state.token);
+      if (state.localState) {
+        local = CodeMirror.copyState((tok != parsers.html ? smartyMode : htmlMixedMode), state.localState);
+      }
+      return {
+        token: state.token,
+        tokenize: state.tokenize,
+        localMode: state.localMode,
+        localState: local,
+        htmlMixedState: CodeMirror.copyState(htmlMixedMode, state.htmlMixedState),
+        inLiteral: state.inLiteral
+      };
+    },
+
+    token: function(stream, state) {
+      if (stream.match(settings.leftDelimiter, false)) {
+        if (!state.inLiteral && stream.match(regs.literalOpen, true)) {
+          state.inLiteral = true;
+          return "keyword";
+        } else if (state.inLiteral && stream.match(regs.literalClose, true)) {
+          state.inLiteral = false;
+          return "keyword";
+        }
+      }
+      if (state.inLiteral && state.localState != state.htmlMixedState) {
+        state.tokenize = parsers.html;
+        state.localMode = htmlMixedMode;
+        state.localState = state.htmlMixedState;
+      }
+
+      var style = (state.tokenize || state.token)(stream, state);
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      if (state.localMode == smartyMode
+          || (state.inLiteral && !state.localMode)
+         || regs.hasLeftDelimeter.test(textAfter)) {
+        return CodeMirror.Pass;
+      }
+      return htmlMixedMode.indent(state.htmlMixedState, textAfter);
+    },
+
+    innerMode: function(state) {
+      return {
+        state: state.localState || state.htmlMixedState,
+        mode: state.localMode || htmlMixedMode
+      };
+    }
+  };
+}, "htmlmixed", "smarty");
+
+CodeMirror.defineMIME("text/x-smarty", "smartymixed");
+// vim: et ts=2 sts=2 sw=2
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/solr/index.html b/app/gui/html/vendor/codemirror/mode/solr/index.html
new file mode 100644
index 0000000..cb88024
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/solr/index.html
@@ -0,0 +1,57 @@
+<!doctype html>
+
+<title>CodeMirror: Solr mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="solr.js"></script>
+<style type="text/css">
+  .CodeMirror {
+    border-top: 1px solid black;
+    border-bottom: 1px solid black;
+  }
+
+  .CodeMirror .cm-operator {
+    color: orange;
+  }
+</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Solr</a>
+  </ul>
+</div>
+
+<article>
+  <h2>Solr mode</h2>
+
+  <div>
+    <textarea id="code" name="code">author:Camus
+
+title:"The Rebel" and author:Camus
+
+philosophy:Existentialism -author:Kierkegaard
+
+hardToSpell:Dostoevsky~
+
+published:[194* TO 1960] and author:(Sartre or "Simone de Beauvoir")</textarea>
+  </div>
+
+  <script>
+    var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+      mode: 'solr',
+      lineNumbers: true
+    });
+  </script>
+
+  <p><strong>MIME types defined:</strong> <code>text/x-solr</code>.</p>
+</article>
diff --git a/app/gui/html/vendor/codemirror/mode/solr/solr.js b/app/gui/html/vendor/codemirror/mode/solr/solr.js
new file mode 100644
index 0000000..25d928e
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/solr/solr.js
@@ -0,0 +1,101 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("solr", function() {
+  "use strict";
+
+  var isStringChar = /[^\s\|\!\+\-\*\?\~\^\&\:\(\)\[\]\{\}\^\"\\]/;
+  var isOperatorChar = /[\|\!\+\-\*\?\~\^\&]/;
+  var isOperatorString = /^(OR|AND|NOT|TO)$/i;
+
+  function isNumber(word) {
+    return parseFloat(word, 10).toString() === word;
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, next;
+      while ((next = stream.next()) != null) {
+        if (next == quote && !escaped) break;
+        escaped = !escaped && next == "\\";
+      }
+
+      if (!escaped) state.tokenize = tokenBase;
+      return "string";
+    };
+  }
+
+  function tokenOperator(operator) {
+    return function(stream, state) {
+      var style = "operator";
+      if (operator == "+")
+        style += " positive";
+      else if (operator == "-")
+        style += " negative";
+      else if (operator == "|")
+        stream.eat(/\|/);
+      else if (operator == "&")
+        stream.eat(/\&/);
+      else if (operator == "^")
+        style += " boost";
+
+      state.tokenize = tokenBase;
+      return style;
+    };
+  }
+
+  function tokenWord(ch) {
+    return function(stream, state) {
+      var word = ch;
+      while ((ch = stream.peek()) && ch.match(isStringChar) != null) {
+        word += stream.next();
+      }
+
+      state.tokenize = tokenBase;
+      if (isOperatorString.test(word))
+        return "operator";
+      else if (isNumber(word))
+        return "number";
+      else if (stream.peek() == ":")
+        return "field";
+      else
+        return "string";
+    };
+  }
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+    if (ch == '"')
+      state.tokenize = tokenString(ch);
+    else if (isOperatorChar.test(ch))
+      state.tokenize = tokenOperator(ch);
+    else if (isStringChar.test(ch))
+      state.tokenize = tokenWord(ch);
+
+    return (state.tokenize != tokenBase) ? state.tokenize(stream, state) : null;
+  }
+
+  return {
+    startState: function() {
+      return {
+        tokenize: tokenBase
+      };
+    },
+
+    token: function(stream, state) {
+      if (stream.eatSpace()) return null;
+      return state.tokenize(stream, state);
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/x-solr", "solr");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/sparql/index.html b/app/gui/html/vendor/codemirror/mode/sparql/index.html
new file mode 100644
index 0000000..5f19d64
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/sparql/index.html
@@ -0,0 +1,53 @@
+<!doctype html>
+
+<title>CodeMirror: SPARQL mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="sparql.js"></script>
+<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">SPARQL</a>
+  </ul>
+</div>
+
+<article>
+<h2>SPARQL mode</h2>
+<form><textarea id="code" name="code">
+PREFIX a: <http://www.w3.org/2000/10/annotation-ns#>
+PREFIX dc: <http://purl.org/dc/elements/1.1/>
+PREFIX foaf: <http://xmlns.com/foaf/0.1/>
+
+# Comment!
+
+SELECT ?given ?family
+WHERE {
+  ?annot a:annotates <http://www.w3.org/TR/rdf-sparql-query/> .
+  ?annot dc:creator ?c .
+  OPTIONAL {?c foaf:given ?given ;
+               foaf:family ?family } .
+  FILTER isBlank(?c)
+}
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: "application/x-sparql-query",
+        matchBrackets: true
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>application/x-sparql-query</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/sparql/sparql.js b/app/gui/html/vendor/codemirror/mode/sparql/sparql.js
new file mode 100644
index 0000000..f228b1d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/sparql/sparql.js
@@ -0,0 +1,157 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("sparql", function(config) {
+  var indentUnit = config.indentUnit;
+  var curPunc;
+
+  function wordRegexp(words) {
+    return new RegExp("^(?:" + words.join("|") + ")$", "i");
+  }
+  var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri",
+                        "isblank", "isliteral", "a"]);
+  var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe",
+                             "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional",
+                             "graph", "by", "asc", "desc", "as", "having", "undef", "values", "group",
+                             "minus", "in", "not", "service", "silent", "using", "insert", "delete", "union",
+                             "data", "copy", "to", "move", "add", "create", "drop", "clear", "load"]);
+  var operatorChars = /[*+\-<>=&|]/;
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+    curPunc = null;
+    if (ch == "$" || ch == "?") {
+      stream.match(/^[\w\d]*/);
+      return "variable-2";
+    }
+    else if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) {
+      stream.match(/^[^\s\u00a0>]*>?/);
+      return "atom";
+    }
+    else if (ch == "\"" || ch == "'") {
+      state.tokenize = tokenLiteral(ch);
+      return state.tokenize(stream, state);
+    }
+    else if (/[{}\(\),\.;\[\]]/.test(ch)) {
+      curPunc = ch;
+      return null;
+    }
+    else if (ch == "#") {
+      stream.skipToEnd();
+      return "comment";
+    }
+    else if (operatorChars.test(ch)) {
+      stream.eatWhile(operatorChars);
+      return null;
+    }
+    else if (ch == ":") {
+      stream.eatWhile(/[\w\d\._\-]/);
+      return "atom";
+    }
+    else {
+      stream.eatWhile(/[_\w\d]/);
+      if (stream.eat(":")) {
+        stream.eatWhile(/[\w\d_\-]/);
+        return "atom";
+      }
+      var word = stream.current();
+      if (ops.test(word))
+        return null;
+      else if (keywords.test(word))
+        return "keyword";
+      else
+        return "variable";
+    }
+  }
+
+  function tokenLiteral(quote) {
+    return function(stream, state) {
+      var escaped = false, ch;
+      while ((ch = stream.next()) != null) {
+        if (ch == quote && !escaped) {
+          state.tokenize = tokenBase;
+          break;
+        }
+        escaped = !escaped && ch == "\\";
+      }
+      return "string";
+    };
+  }
+
+  function pushContext(state, type, col) {
+    state.context = {prev: state.context, indent: state.indent, col: col, type: type};
+  }
+  function popContext(state) {
+    state.indent = state.context.indent;
+    state.context = state.context.prev;
+  }
+
+  return {
+    startState: function() {
+      return {tokenize: tokenBase,
+              context: null,
+              indent: 0,
+              col: 0};
+    },
+
+    token: function(stream, state) {
+      if (stream.sol()) {
+        if (state.context && state.context.align == null) state.context.align = false;
+        state.indent = stream.indentation();
+      }
+      if (stream.eatSpace()) return null;
+      var style = state.tokenize(stream, state);
+
+      if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") {
+        state.context.align = true;
+      }
+
+      if (curPunc == "(") pushContext(state, ")", stream.column());
+      else if (curPunc == "[") pushContext(state, "]", stream.column());
+      else if (curPunc == "{") pushContext(state, "}", stream.column());
+      else if (/[\]\}\)]/.test(curPunc)) {
+        while (state.context && state.context.type == "pattern") popContext(state);
+        if (state.context && curPunc == state.context.type) popContext(state);
+      }
+      else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state);
+      else if (/atom|string|variable/.test(style) && state.context) {
+        if (/[\}\]]/.test(state.context.type))
+          pushContext(state, "pattern", stream.column());
+        else if (state.context.type == "pattern" && !state.context.align) {
+          state.context.align = true;
+          state.context.col = stream.column();
+        }
+      }
+
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      var firstChar = textAfter && textAfter.charAt(0);
+      var context = state.context;
+      if (/[\]\}]/.test(firstChar))
+        while (context && context.type == "pattern") context = context.prev;
+
+      var closing = context && firstChar == context.type;
+      if (!context)
+        return 0;
+      else if (context.type == "pattern")
+        return context.col;
+      else if (context.align)
+        return context.col + (closing ? 0 : 1);
+      else
+        return context.indent + (closing ? 0 : indentUnit);
+    }
+  };
+});
+
+CodeMirror.defineMIME("application/x-sparql-query", "sparql");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/sql/index.html b/app/gui/html/vendor/codemirror/mode/sql/index.html
new file mode 100644
index 0000000..79a2e74
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/sql/index.html
@@ -0,0 +1,76 @@
+<!doctype html>
+
+<title>CodeMirror: SQL Mode for CodeMirror</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css" />
+<script src="../../lib/codemirror.js"></script>
+<script src="sql.js"></script>
+<style>
+.CodeMirror {
+    border-top: 1px solid black;
+    border-bottom: 1px solid black;
+}
+        </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">SQL Mode for CodeMirror</a>
+  </ul>
+</div>
+
+<article>
+<h2>SQL Mode for CodeMirror</h2>
+<form>
+            <textarea id="code" name="code">-- SQL Mode for CodeMirror
+SELECT SQL_NO_CACHE DISTINCT
+		@var1 AS `val1`, @'val2', @global.'sql_mode',
+		1.1 AS `float_val`, .14 AS `another_float`, 0.09e3 AS `int_with_esp`,
+		0xFA5 AS `hex`, x'fa5' AS `hex2`, 0b101 AS `bin`, b'101' AS `bin2`,
+		DATE '1994-01-01' AS `sql_date`, { T "1994-01-01" } AS `odbc_date`,
+		'my string', _utf8'your string', N'her string',
+        TRUE, FALSE, UNKNOWN
+	FROM DUAL
+	-- space needed after '--'
+	# 1 line comment
+	/* multiline
+	comment! */
+	LIMIT 1 OFFSET 0;
+</textarea>
+            </form>
+            <p><strong>MIME types defined:</strong> 
+            <code><a href="?mime=text/x-sql">text/x-sql</a></code>,
+            <code><a href="?mime=text/x-mysql">text/x-mysql</a></code>,
+            <code><a href="?mime=text/x-mariadb">text/x-mariadb</a></code>,
+            <code><a href="?mime=text/x-cassandra">text/x-cassandra</a></code>,
+            <code><a href="?mime=text/x-plsql">text/x-plsql</a></code>,
+            <code><a href="?mime=text/x-mssql">text/x-mssql</a></code>,
+            <code><a href="?mime=text/x-hive">text/x-hive</a></code>.
+        </p>
+<script>
+window.onload = function() {
+  var mime = 'text/x-mariadb';
+  // get mime type
+  if (window.location.href.indexOf('mime=') > -1) {
+    mime = window.location.href.substr(window.location.href.indexOf('mime=') + 5);
+  }
+  window.editor = CodeMirror.fromTextArea(document.getElementById('code'), {
+    mode: mime,
+    indentWithTabs: true,
+    smartIndent: true,
+    lineNumbers: true,
+    matchBrackets : true,
+    autofocus: true
+  });
+};
+</script>
+
+</article>
diff --git a/app/gui/html/vendor/codemirror/mode/sql/sql.js b/app/gui/html/vendor/codemirror/mode/sql/sql.js
new file mode 100644
index 0000000..417db06
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/sql/sql.js
@@ -0,0 +1,389 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("sql", function(config, parserConfig) {
+  "use strict";
+
+  var client         = parserConfig.client || {},
+      atoms          = parserConfig.atoms || {"false": true, "true": true, "null": true},
+      builtin        = parserConfig.builtin || {},
+      keywords       = parserConfig.keywords || {},
+      operatorChars  = parserConfig.operatorChars || /^[*+\-%<>!=&|~^]/,
+      support        = parserConfig.support || {},
+      hooks          = parserConfig.hooks || {},
+      dateSQL        = parserConfig.dateSQL || {"date" : true, "time" : true, "timestamp" : true};
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+
+    // call hooks from the mime type
+    if (hooks[ch]) {
+      var result = hooks[ch](stream, state);
+      if (result !== false) return result;
+    }
+
+    if (support.hexNumber == true &&
+      ((ch == "0" && stream.match(/^[xX][0-9a-fA-F]+/))
+      || (ch == "x" || ch == "X") && stream.match(/^'[0-9a-fA-F]+'/))) {
+      // hex
+      // ref: http://dev.mysql.com/doc/refman/5.5/en/hexadecimal-literals.html
+      return "number";
+    } else if (support.binaryNumber == true &&
+      (((ch == "b" || ch == "B") && stream.match(/^'[01]+'/))
+      || (ch == "0" && stream.match(/^b[01]+/)))) {
+      // bitstring
+      // ref: http://dev.mysql.com/doc/refman/5.5/en/bit-field-literals.html
+      return "number";
+    } else if (ch.charCodeAt(0) > 47 && ch.charCodeAt(0) < 58) {
+      // numbers
+      // ref: http://dev.mysql.com/doc/refman/5.5/en/number-literals.html
+          stream.match(/^[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?/);
+      support.decimallessFloat == true && stream.eat('.');
+      return "number";
+    } else if (ch == "?" && (stream.eatSpace() || stream.eol() || stream.eat(";"))) {
+      // placeholders
+      return "variable-3";
+    } else if (ch == "'" || (ch == '"' && support.doubleQuote)) {
+      // strings
+      // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
+      state.tokenize = tokenLiteral(ch);
+      return state.tokenize(stream, state);
+    } else if ((((support.nCharCast == true && (ch == "n" || ch == "N"))
+        || (support.charsetCast == true && ch == "_" && stream.match(/[a-z][a-z0-9]*/i)))
+        && (stream.peek() == "'" || stream.peek() == '"'))) {
+      // charset casting: _utf8'str', N'str', n'str'
+      // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
+      return "keyword";
+    } else if (/^[\(\),\;\[\]]/.test(ch)) {
+      // no highlightning
+      return null;
+    } else if (support.commentSlashSlash && ch == "/" && stream.eat("/")) {
+      // 1-line comment
+      stream.skipToEnd();
+      return "comment";
+    } else if ((support.commentHash && ch == "#")
+        || (ch == "-" && stream.eat("-") && (!support.commentSpaceRequired || stream.eat(" ")))) {
+      // 1-line comments
+      // ref: https://kb.askmonty.org/en/comment-syntax/
+      stream.skipToEnd();
+      return "comment";
+    } else if (ch == "/" && stream.eat("*")) {
+      // multi-line comments
+      // ref: https://kb.askmonty.org/en/comment-syntax/
+      state.tokenize = tokenComment;
+      return state.tokenize(stream, state);
+    } else if (ch == ".") {
+      // .1 for 0.1
+      if (support.zerolessFloat == true && stream.match(/^(?:\d+(?:e[+-]?\d+)?)/i)) {
+        return "number";
+      }
+      // .table_name (ODBC)
+      // // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
+      if (support.ODBCdotTable == true && stream.match(/^[a-zA-Z_]+/)) {
+        return "variable-2";
+      }
+    } else if (operatorChars.test(ch)) {
+      // operators
+      stream.eatWhile(operatorChars);
+      return null;
+    } else if (ch == '{' &&
+        (stream.match(/^( )*(d|D|t|T|ts|TS)( )*'[^']*'( )*}/) || stream.match(/^( )*(d|D|t|T|ts|TS)( )*"[^"]*"( )*}/))) {
+      // dates (weird ODBC syntax)
+      // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html
+      return "number";
+    } else {
+      stream.eatWhile(/^[_\w\d]/);
+      var word = stream.current().toLowerCase();
+      // dates (standard SQL syntax)
+      // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html
+      if (dateSQL.hasOwnProperty(word) && (stream.match(/^( )+'[^']*'/) || stream.match(/^( )+"[^"]*"/)))
+        return "number";
+      if (atoms.hasOwnProperty(word)) return "atom";
+      if (builtin.hasOwnProperty(word)) return "builtin";
+      if (keywords.hasOwnProperty(word)) return "keyword";
+      if (client.hasOwnProperty(word)) return "string-2";
+      return null;
+    }
+  }
+
+  // 'string', with char specified in quote escaped by '\'
+  function tokenLiteral(quote) {
+    return function(stream, state) {
+      var escaped = false, ch;
+      while ((ch = stream.next()) != null) {
+        if (ch == quote && !escaped) {
+          state.tokenize = tokenBase;
+          break;
+        }
+        escaped = !escaped && ch == "\\";
+      }
+      return "string";
+    };
+  }
+  function tokenComment(stream, state) {
+    while (true) {
+      if (stream.skipTo("*")) {
+        stream.next();
+        if (stream.eat("/")) {
+          state.tokenize = tokenBase;
+          break;
+        }
+      } else {
+        stream.skipToEnd();
+        break;
+      }
+    }
+    return "comment";
+  }
+
+  function pushContext(stream, state, type) {
+    state.context = {
+      prev: state.context,
+      indent: stream.indentation(),
+      col: stream.column(),
+      type: type
+    };
+  }
+
+  function popContext(state) {
+    state.indent = state.context.indent;
+    state.context = state.context.prev;
+  }
+
+  return {
+    startState: function() {
+      return {tokenize: tokenBase, context: null};
+    },
+
+    token: function(stream, state) {
+      if (stream.sol()) {
+        if (state.context && state.context.align == null)
+          state.context.align = false;
+      }
+      if (stream.eatSpace()) return null;
+
+      var style = state.tokenize(stream, state);
+      if (style == "comment") return style;
+
+      if (state.context && state.context.align == null)
+        state.context.align = true;
+
+      var tok = stream.current();
+      if (tok == "(")
+        pushContext(stream, state, ")");
+      else if (tok == "[")
+        pushContext(stream, state, "]");
+      else if (state.context && state.context.type == tok)
+        popContext(state);
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      var cx = state.context;
+      if (!cx) return 0;
+      var closing = textAfter.charAt(0) == cx.type;
+      if (cx.align) return cx.col + (closing ? 0 : 1);
+      else return cx.indent + (closing ? 0 : config.indentUnit);
+    },
+
+    blockCommentStart: "/*",
+    blockCommentEnd: "*/",
+    lineComment: support.commentSlashSlash ? "//" : support.commentHash ? "#" : null
+  };
+});
+
+(function() {
+  "use strict";
+
+  // `identifier`
+  function hookIdentifier(stream) {
+    // MySQL/MariaDB identifiers
+    // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
+    var ch;
+    while ((ch = stream.next()) != null) {
+      if (ch == "`" && !stream.eat("`")) return "variable-2";
+    }
+    return null;
+  }
+
+  // variable token
+  function hookVar(stream) {
+    // variables
+    // @@prefix.varName @varName
+    // varName can be quoted with ` or ' or "
+    // ref: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
+    if (stream.eat("@")) {
+      stream.match(/^session\./);
+      stream.match(/^local\./);
+      stream.match(/^global\./);
+    }
+
+    if (stream.eat("'")) {
+      stream.match(/^.*'/);
+      return "variable-2";
+    } else if (stream.eat('"')) {
+      stream.match(/^.*"/);
+      return "variable-2";
+    } else if (stream.eat("`")) {
+      stream.match(/^.*`/);
+      return "variable-2";
+    } else if (stream.match(/^[0-9a-zA-Z$\.\_]+/)) {
+      return "variable-2";
+    }
+    return null;
+  };
+
+  // short client keyword token
+  function hookClient(stream) {
+    // \N means NULL
+    // ref: http://dev.mysql.com/doc/refman/5.5/en/null-values.html
+    if (stream.eat("N")) {
+        return "atom";
+    }
+    // \g, etc
+    // ref: http://dev.mysql.com/doc/refman/5.5/en/mysql-commands.html
+    return stream.match(/^[a-zA-Z.#!?]/) ? "variable-2" : null;
+  }
+
+  // these keywords are used by all SQL dialects (however, a mode can still overwrite it)
+  var sqlKeywords = "alter and as asc between by count create delete desc distinct drop from having in insert into is join like not on or order select set table union update values where ";
+
+  // turn a space-separated list into an array
+  function set(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+
+  // A generic SQL Mode. It's not a standard, it just try to support what is generally supported
+  CodeMirror.defineMIME("text/x-sql", {
+    name: "sql",
+    keywords: set(sqlKeywords + "begin"),
+    builtin: set("bool boolean bit blob enum long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision real date datetime year unsigned signed decimal numeric"),
+    atoms: set("false true null unknown"),
+    operatorChars: /^[*+\-%<>!=]/,
+    dateSQL: set("date time timestamp"),
+    support: set("ODBCdotTable doubleQuote binaryNumber hexNumber")
+  });
+
+  CodeMirror.defineMIME("text/x-mssql", {
+    name: "sql",
+    client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
+    keywords: set(sqlKeywords + "begin trigger proc view index for add constraint key primary foreign collate clustered nonclustered"),
+    builtin: set("bigint numeric bit smallint decimal smallmoney int tinyint money float real char varchar text nchar nvarchar ntext binary varbinary image cursor timestamp hierarchyid uniqueidentifier sql_variant xml table "),
+    atoms: set("false true null unknown"),
+    operatorChars: /^[*+\-%<>!=]/,
+    dateSQL: set("date datetimeoffset datetime2 smalldatetime datetime time"),
+    hooks: {
+      "@":   hookVar
+    }
+  });
+
+  CodeMirror.defineMIME("text/x-mysql", {
+    name: "sql",
+    client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
+    keywords: set(sqlKeywords + "accessible action add after algorithm all analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general get global grant grants group groupby_concat handler hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show signal slave slow smallint snapshot soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"),
+    builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"),
+    atoms: set("false true null unknown"),
+    operatorChars: /^[*+\-%<>!=&|^]/,
+    dateSQL: set("date time timestamp"),
+    support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"),
+    hooks: {
+      "@":   hookVar,
+      "`":   hookIdentifier,
+      "\\":  hookClient
+    }
+  });
+
+  CodeMirror.defineMIME("text/x-mariadb", {
+    name: "sql",
+    client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
+    keywords: set(sqlKeywords + "accessible action add after algorithm all always analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general generated get global grant grants group groupby_concat handler hard hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password persistent phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show shutdown signal slave slow smallint snapshot soft soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views virtual warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"),
+    builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"),
+    atoms: set("false true null unknown"),
+    operatorChars: /^[*+\-%<>!=&|^]/,
+    dateSQL: set("date time timestamp"),
+    support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"),
+    hooks: {
+      "@":   hookVar,
+      "`":   hookIdentifier,
+      "\\":  hookClient
+    }
+  });
+
+  // the query language used by Apache Cassandra is called CQL, but this mime type
+  // is called Cassandra to avoid confusion with Contextual Query Language
+  CodeMirror.defineMIME("text/x-cassandra", {
+    name: "sql",
+    client: { },
+    keywords: set("use select from using consistency where limit first reversed first and in insert into values using consistency ttl update set delete truncate begin batch apply create keyspace with columnfamily primary key index on drop alter type add any one quorum all local_quorum each_quorum"),
+    builtin: set("ascii bigint blob boolean counter decimal double float int text timestamp uuid varchar varint"),
+    atoms: set("false true"),
+    operatorChars: /^[<>=]/,
+    dateSQL: { },
+    support: set("commentSlashSlash decimallessFloat"),
+    hooks: { }
+  });
+
+  // this is based on Peter Raganitsch's 'plsql' mode
+  CodeMirror.defineMIME("text/x-plsql", {
+    name:       "sql",
+    client:     set("appinfo arraysize autocommit autoprint autorecovery autotrace blockterminator break btitle cmdsep colsep compatibility compute concat copycommit copytypecheck define describe echo editfile embedded escape exec execute feedback flagger flush heading headsep instance linesize lno loboffset logsource long longchunksize markup native newpage numformat numwidth pagesize pause pno recsep recsepchar release repfooter repheader serveroutput shiftinout show showmode size spool sqlblanklines sqlcase sqlcode sqlcontinue sqlnumber sqlpluscompatibility sqlprefix sqlprompt sqlterminator suffix tab term termout time timing trimout trimspool ttitle underline verify version wrap"),
+    keywords:   set("abort accept access add all alter and any array arraylen as asc assert assign at attributes audit authorization avg base_table begin between binary_integer body boolean by case cast char char_base check close cluster clusters colauth column comment commit compress connect connected constant constraint crash create current currval cursor data_base database date dba deallocate debugoff debugon decimal declare default definition delay delete desc digits dispose distinct do drop else elseif elsif enable end entry escape exception exception_init exchange exclusive exists exit external fast fetch file for force form from function generic goto grant group having identified if immediate in increment index indexes indicator initial initrans insert interface intersect into is key level library like limited local lock log logging long loop master maxextents maxtrans member minextents minus mislabel mode modify multiset new next no noaudit nocompress nologging noparallel not nowait number_base object of off offline on online only open option or order out package parallel partition pctfree pctincrease pctused pls_integer positive positiven pragma primary prior private privileges procedure public raise range raw read rebuild record ref references refresh release rename replace resource restrict return returning returns reverse revoke rollback row rowid rowlabel rownum rows run savepoint schema segment select separate session set share snapshot some space split sql start statement storage subtype successful synonym tabauth table tables tablespace task terminate then to trigger truncate type union unique unlimited unrecoverable unusable update use using validate value values variable view views when whenever where while with work"),
+    builtin:    set("abs acos add_months ascii asin atan atan2 average bfile bfilename bigserial bit blob ceil character chartorowid chr clob concat convert cos cosh count dec decode deref dual dump dup_val_on_index empty error exp false float floor found glb greatest hextoraw initcap instr instrb int integer isopen last_day least lenght lenghtb ln lower lpad ltrim lub make_ref max min mlslabel mod months_between natural naturaln nchar nclob new_time next_day nextval nls_charset_decl_len nls_charset_id nls_charset_name nls_initcap nls_lower nls_sort nls_upper nlssort no_data_found notfound null number numeric nvarchar2 nvl others power rawtohex real reftohex round rowcount rowidtochar rowtype rpad rtrim serial sign signtype sin sinh smallint soundex sqlcode sqlerrm sqrt stddev string substr substrb sum sysdate tan tanh to_char text to_date to_label to_multi_byte to_number to_single_byte translate true trunc uid unlogged upper user userenv varchar varchar2 variance varying vsize xml"),
+    operatorChars: /^[*+\-%<>!=~]/,
+    dateSQL:    set("date time timestamp"),
+    support:    set("doubleQuote nCharCast zerolessFloat binaryNumber hexNumber")
+  });
+
+  // Created to support specific hive keywords
+  CodeMirror.defineMIME("text/x-hive", {
+    name: "sql",
+    keywords: set("select alter $elem$ $key$ $value$ add after all analyze and archive as asc before between binary both bucket buckets by cascade case cast change cluster clustered clusterstatus collection column columns comment compute concatenate continue create cross cursor data database databases dbproperties deferred delete delimited desc describe directory disable distinct distribute drop else enable end escaped exclusive exists explain export extended external false fetch fields fileformat first format formatted from full function functions grant group having hold_ddltime idxproperties if import in index indexes inpath inputdriver inputformat insert intersect into is items join keys lateral left like limit lines load local location lock locks mapjoin materialized minus msck no_drop nocompress not of offline on option or order out outer outputdriver outputformat overwrite partition partitioned partitions percent plus preserve procedure purge range rcfile read readonly reads rebuild recordreader recordwriter recover reduce regexp rename repair replace restrict revoke right rlike row schema schemas semi sequencefile serde serdeproperties set shared show show_database sort sorted ssl statistics stored streamtable table tables tablesample tblproperties temporary terminated textfile then tmp to touch transform trigger true unarchive undo union uniquejoin unlock update use using utc utc_tmestamp view when where while with"),
+    builtin: set("bool boolean long timestamp tinyint smallint bigint int float double date datetime unsigned string array struct map uniontype"),
+    atoms: set("false true null unknown"),
+    operatorChars: /^[*+\-%<>!=]/,
+    dateSQL: set("date timestamp"),
+    support: set("ODBCdotTable doubleQuote binaryNumber hexNumber")
+  });
+}());
+
+});
+
+/*
+  How Properties of Mime Types are used by SQL Mode
+  =================================================
+
+  keywords:
+    A list of keywords you want to be highlighted.
+  functions:
+    A list of function names you want to be highlighted.
+  builtin:
+    A list of builtin types you want to be highlighted (if you want types to be of class "builtin" instead of "keyword").
+  operatorChars:
+    All characters that must be handled as operators.
+  client:
+    Commands parsed and executed by the client (not the server).
+  support:
+    A list of supported syntaxes which are not common, but are supported by more than 1 DBMS.
+    * ODBCdotTable: .tableName
+    * zerolessFloat: .1
+    * doubleQuote
+    * nCharCast: N'string'
+    * charsetCast: _utf8'string'
+    * commentHash: use # char for comments
+    * commentSlashSlash: use // for comments
+    * commentSpaceRequired: require a space after -- for comments
+  atoms:
+    Keywords that must be highlighted as atoms,. Some DBMS's support more atoms than others:
+    UNKNOWN, INFINITY, UNDERFLOW, NaN...
+  dateSQL:
+    Used for date/time SQL standard syntax, because not all DBMS's support same temporal types.
+*/
diff --git a/app/gui/html/vendor/codemirror/mode/stex/index.html b/app/gui/html/vendor/codemirror/mode/stex/index.html
new file mode 100644
index 0000000..28b8f64
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/stex/index.html
@@ -0,0 +1,110 @@
+<!doctype html>
+
+<title>CodeMirror: sTeX mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="stex.js"></script>
+<style>.CodeMirror {background: #f8f8f8;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">sTeX</a>
+  </ul>
+</div>
+
+<article>
+<h2>sTeX mode</h2>
+<form><textarea id="code" name="code">
+\begin{module}[id=bbt-size]
+\importmodule[balanced-binary-trees]{balanced-binary-trees}
+\importmodule[\KWARCslides{dmath/en/cardinality}]{cardinality}
+
+\begin{frame}
+  \frametitle{Size Lemma for Balanced Trees}
+  \begin{itemize}
+  \item
+    \begin{assertion}[id=size-lemma,type=lemma] 
+    Let $G=\tup{V,E}$ be a \termref[cd=binary-trees]{balanced binary tree} 
+    of \termref[cd=graph-depth,name=vertex-depth]{depth}$n>i$, then the set
+     $\defeq{\livar{V}i}{\setst{\inset{v}{V}}{\gdepth{v} = i}}$ of
+    \termref[cd=graphs-intro,name=node]{nodes} at 
+    \termref[cd=graph-depth,name=vertex-depth]{depth} $i$ has
+    \termref[cd=cardinality,name=cardinality]{cardinality} $\power2i$.
+   \end{assertion}
+  \item
+    \begin{sproof}[id=size-lemma-pf,proofend=,for=size-lemma]{via induction over the depth $i$.}
+      \begin{spfcases}{We have to consider two cases}
+        \begin{spfcase}{$i=0$}
+          \begin{spfstep}[display=flow]
+            then $\livar{V}i=\set{\livar{v}r}$, where $\livar{v}r$ is the root, so
+            $\eq{\card{\livar{V}0},\card{\set{\livar{v}r}},1,\power20}$.
+          \end{spfstep}
+        \end{spfcase}
+        \begin{spfcase}{$i>0$}
+          \begin{spfstep}[display=flow]
+           then $\livar{V}{i-1}$ contains $\power2{i-1}$ vertexes 
+           \begin{justification}[method=byIH](IH)\end{justification}
+          \end{spfstep}
+          \begin{spfstep}
+           By the \begin{justification}[method=byDef]definition of a binary
+              tree\end{justification}, each $\inset{v}{\livar{V}{i-1}}$ is a leaf or has
+            two children that are at depth $i$.
+          \end{spfstep}
+          \begin{spfstep}
+           As $G$ is \termref[cd=balanced-binary-trees,name=balanced-binary-tree]{balanced} and $\gdepth{G}=n>i$, $\livar{V}{i-1}$ cannot contain
+            leaves.
+          \end{spfstep}
+          \begin{spfstep}[type=conclusion]
+           Thus $\eq{\card{\livar{V}i},{\atimes[cdot]{2,\card{\livar{V}{i-1}}}},{\atimes[cdot]{2,\power2{i-1}}},\power2i}$.
+          \end{spfstep}
+        \end{spfcase}
+      \end{spfcases}
+    \end{sproof}
+  \item 
+    \begin{assertion}[id=fbbt,type=corollary]	
+      A fully balanced tree of depth $d$ has $\power2{d+1}-1$ nodes.
+    \end{assertion}
+  \item
+      \begin{sproof}[for=fbbt,id=fbbt-pf]{}
+        \begin{spfstep}
+          Let $\defeq{G}{\tup{V,E}}$ be a fully balanced tree
+        \end{spfstep}
+        \begin{spfstep}
+          Then $\card{V}=\Sumfromto{i}1d{\power2i}= \power2{d+1}-1$.
+        \end{spfstep}
+      \end{sproof}
+    \end{itemize}
+  \end{frame}
+\begin{note}
+  \begin{omtext}[type=conclusion,for=binary-tree]
+    This shows that balanced binary trees grow in breadth very quickly, a consequence of
+    this is that they are very shallow (and this compute very fast), which is the essence of
+    the next result.
+  \end{omtext}
+\end{note}
+\end{module}
+
+%%% Local Variables: 
+%%% mode: LaTeX
+%%% TeX-master: "all"
+%%% End: \end{document}
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-stex</code>.</p>
+
+    <p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#stex_*">normal</a>,  <a href="../../test/index.html#verbose,stex_*">verbose</a>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/stex/stex.js b/app/gui/html/vendor/codemirror/mode/stex/stex.js
new file mode 100644
index 0000000..59a395a
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/stex/stex.js
@@ -0,0 +1,258 @@
+/*
+ * Author: Constantin Jucovschi (c.jucovschi at jacobs-university.de)
+ * Licence: MIT
+ */
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("stex", function() {
+    "use strict";
+
+    function pushCommand(state, command) {
+        state.cmdState.push(command);
+    }
+
+    function peekCommand(state) {
+        if (state.cmdState.length > 0) {
+            return state.cmdState[state.cmdState.length - 1];
+        } else {
+            return null;
+        }
+    }
+
+    function popCommand(state) {
+        var plug = state.cmdState.pop();
+        if (plug) {
+            plug.closeBracket();
+        }
+    }
+
+    // returns the non-default plugin closest to the end of the list
+    function getMostPowerful(state) {
+        var context = state.cmdState;
+        for (var i = context.length - 1; i >= 0; i--) {
+            var plug = context[i];
+            if (plug.name == "DEFAULT") {
+                continue;
+            }
+            return plug;
+        }
+        return { styleIdentifier: function() { return null; } };
+    }
+
+    function addPluginPattern(pluginName, cmdStyle, styles) {
+        return function () {
+            this.name = pluginName;
+            this.bracketNo = 0;
+            this.style = cmdStyle;
+            this.styles = styles;
+            this.argument = null;   // \begin and \end have arguments that follow. These are stored in the plugin
+
+            this.styleIdentifier = function() {
+                return this.styles[this.bracketNo - 1] || null;
+            };
+            this.openBracket = function() {
+                this.bracketNo++;
+                return "bracket";
+            };
+            this.closeBracket = function() {};
+        };
+    }
+
+    var plugins = {};
+
+    plugins["importmodule"] = addPluginPattern("importmodule", "tag", ["string", "builtin"]);
+    plugins["documentclass"] = addPluginPattern("documentclass", "tag", ["", "atom"]);
+    plugins["usepackage"] = addPluginPattern("usepackage", "tag", ["atom"]);
+    plugins["begin"] = addPluginPattern("begin", "tag", ["atom"]);
+    plugins["end"] = addPluginPattern("end", "tag", ["atom"]);
+
+    plugins["DEFAULT"] = function () {
+        this.name = "DEFAULT";
+        this.style = "tag";
+
+        this.styleIdentifier = this.openBracket = this.closeBracket = function() {};
+    };
+
+    function setState(state, f) {
+        state.f = f;
+    }
+
+    // called when in a normal (no environment) context
+    function normal(source, state) {
+        var plug;
+        // Do we look like '\command' ?  If so, attempt to apply the plugin 'command'
+        if (source.match(/^\\[a-zA-Z@]+/)) {
+            var cmdName = source.current().slice(1);
+            plug = plugins[cmdName] || plugins["DEFAULT"];
+            plug = new plug();
+            pushCommand(state, plug);
+            setState(state, beginParams);
+            return plug.style;
+        }
+
+        // escape characters
+        if (source.match(/^\\[$&%#{}_]/)) {
+          return "tag";
+        }
+
+        // white space control characters
+        if (source.match(/^\\[,;!\/\\]/)) {
+          return "tag";
+        }
+
+        // find if we're starting various math modes
+        if (source.match("\\[")) {
+            setState(state, function(source, state){ return inMathMode(source, state, "\\]"); });
+            return "keyword";
+        }
+        if (source.match("$$")) {
+            setState(state, function(source, state){ return inMathMode(source, state, "$$"); });
+            return "keyword";
+        }
+        if (source.match("$")) {
+            setState(state, function(source, state){ return inMathMode(source, state, "$"); });
+            return "keyword";
+        }
+
+        var ch = source.next();
+        if (ch == "%") {
+            // special case: % at end of its own line; stay in same state
+            if (!source.eol()) {
+              setState(state, inCComment);
+            }
+            return "comment";
+        }
+        else if (ch == '}' || ch == ']') {
+            plug = peekCommand(state);
+            if (plug) {
+                plug.closeBracket(ch);
+                setState(state, beginParams);
+            } else {
+                return "error";
+            }
+            return "bracket";
+        } else if (ch == '{' || ch == '[') {
+            plug = plugins["DEFAULT"];
+            plug = new plug();
+            pushCommand(state, plug);
+            return "bracket";
+        }
+        else if (/\d/.test(ch)) {
+            source.eatWhile(/[\w.%]/);
+            return "atom";
+        }
+        else {
+            source.eatWhile(/[\w\-_]/);
+            plug = getMostPowerful(state);
+            if (plug.name == 'begin') {
+                plug.argument = source.current();
+            }
+            return plug.styleIdentifier();
+        }
+    }
+
+    function inCComment(source, state) {
+        source.skipToEnd();
+        setState(state, normal);
+        return "comment";
+    }
+
+    function inMathMode(source, state, endModeSeq) {
+        if (source.eatSpace()) {
+            return null;
+        }
+        if (source.match(endModeSeq)) {
+            setState(state, normal);
+            return "keyword";
+        }
+        if (source.match(/^\\[a-zA-Z@]+/)) {
+            return "tag";
+        }
+        if (source.match(/^[a-zA-Z]+/)) {
+            return "variable-2";
+        }
+        // escape characters
+        if (source.match(/^\\[$&%#{}_]/)) {
+          return "tag";
+        }
+        // white space control characters
+        if (source.match(/^\\[,;!\/]/)) {
+          return "tag";
+        }
+        // special math-mode characters
+        if (source.match(/^[\^_&]/)) {
+          return "tag";
+        }
+        // non-special characters
+        if (source.match(/^[+\-<>|=,\/@!*:;'"`~#?]/)) {
+            return null;
+        }
+        if (source.match(/^(\d+\.\d*|\d*\.\d+|\d+)/)) {
+          return "number";
+        }
+        var ch = source.next();
+        if (ch == "{" || ch == "}" || ch == "[" || ch == "]" || ch == "(" || ch == ")") {
+            return "bracket";
+        }
+
+        // eat comments here, because inCComment returns us to normal state!
+        if (ch == "%") {
+            if (!source.eol()) {
+                source.skipToEnd();
+            }
+            return "comment";
+        }
+        return "error";
+    }
+
+    function beginParams(source, state) {
+        var ch = source.peek(), lastPlug;
+        if (ch == '{' || ch == '[') {
+            lastPlug = peekCommand(state);
+            lastPlug.openBracket(ch);
+            source.eat(ch);
+            setState(state, normal);
+            return "bracket";
+        }
+        if (/[ \t\r]/.test(ch)) {
+            source.eat(ch);
+            return null;
+        }
+        setState(state, normal);
+        popCommand(state);
+
+        return normal(source, state);
+    }
+
+    return {
+        startState: function() {
+            return {
+                cmdState: [],
+                f: normal
+            };
+        },
+        copyState: function(s) {
+            return {
+                cmdState: s.cmdState.slice(),
+                f: s.f
+            };
+        },
+        token: function(stream, state) {
+            return state.f(stream, state);
+        }
+    };
+});
+
+CodeMirror.defineMIME("text/x-stex", "stex");
+CodeMirror.defineMIME("text/x-latex", "stex");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/stex/test.js b/app/gui/html/vendor/codemirror/mode/stex/test.js
new file mode 100644
index 0000000..ab629e8
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/stex/test.js
@@ -0,0 +1,120 @@
+(function() {
+  var mode = CodeMirror.getMode({tabSize: 4}, "stex");
+  function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
+
+  MT("word",
+     "foo");
+
+  MT("twoWords",
+     "foo bar");
+
+  MT("beginEndDocument",
+     "[tag \\begin][bracket {][atom document][bracket }]",
+     "[tag \\end][bracket {][atom document][bracket }]");
+
+  MT("beginEndEquation",
+     "[tag \\begin][bracket {][atom equation][bracket }]",
+     "  E=mc^2",
+     "[tag \\end][bracket {][atom equation][bracket }]");
+
+  MT("beginModule",
+     "[tag \\begin][bracket {][atom module][bracket }[[]]]");
+
+  MT("beginModuleId",
+     "[tag \\begin][bracket {][atom module][bracket }[[]id=bbt-size[bracket ]]]");
+
+  MT("importModule",
+     "[tag \\importmodule][bracket [[][string b-b-t][bracket ]]{][builtin b-b-t][bracket }]");
+
+  MT("importModulePath",
+     "[tag \\importmodule][bracket [[][tag \\KWARCslides][bracket {][string dmath/en/cardinality][bracket }]]{][builtin card][bracket }]");
+
+  MT("psForPDF",
+     "[tag \\PSforPDF][bracket [[][atom 1][bracket ]]{]#1[bracket }]");
+
+  MT("comment",
+     "[comment % foo]");
+
+  MT("tagComment",
+     "[tag \\item][comment % bar]");
+
+  MT("commentTag",
+     " [comment % \\item]");
+
+  MT("commentLineBreak",
+     "[comment %]",
+     "foo");
+
+  MT("tagErrorCurly",
+     "[tag \\begin][error }][bracket {]");
+
+  MT("tagErrorSquare",
+     "[tag \\item][error ]]][bracket {]");
+
+  MT("commentCurly",
+     "[comment % }]");
+
+  MT("tagHash",
+     "the [tag \\#] key");
+
+  MT("tagNumber",
+     "a [tag \\$][atom 5] stetson");
+
+  MT("tagPercent",
+     "[atom 100][tag \\%] beef");
+
+  MT("tagAmpersand",
+     "L [tag \\&] N");
+
+  MT("tagUnderscore",
+     "foo[tag \\_]bar");
+
+  MT("tagBracketOpen",
+     "[tag \\emph][bracket {][tag \\{][bracket }]");
+
+  MT("tagBracketClose",
+     "[tag \\emph][bracket {][tag \\}][bracket }]");
+
+  MT("tagLetterNumber",
+     "section [tag \\S][atom 1]");
+
+  MT("textTagNumber",
+     "para [tag \\P][atom 2]");
+
+  MT("thinspace",
+     "x[tag \\,]y");
+
+  MT("thickspace",
+     "x[tag \\;]y");
+
+  MT("negativeThinspace",
+     "x[tag \\!]y");
+
+  MT("periodNotSentence",
+     "J.\\ L.\\ is");
+
+  MT("periodSentence",
+     "X[tag \\@]. The");
+
+  MT("italicCorrection",
+     "[bracket {][tag \\em] If[tag \\/][bracket }] I");
+
+  MT("tagBracket",
+     "[tag \\newcommand][bracket {][tag \\pop][bracket }]");
+
+  MT("inlineMathTagFollowedByNumber",
+     "[keyword $][tag \\pi][number 2][keyword $]");
+
+  MT("inlineMath",
+     "[keyword $][number 3][variable-2 x][tag ^][number 2.45]-[tag \\sqrt][bracket {][tag \\$\\alpha][bracket }] = [number 2][keyword $] other text");
+
+  MT("displayMath",
+     "More [keyword $$]\t[variable-2 S][tag ^][variable-2 n][tag \\sum] [variable-2 i][keyword $$] other text");
+
+  MT("mathWithComment",
+     "[keyword $][variable-2 x] [comment % $]",
+     "[variable-2 y][keyword $] other text");
+
+  MT("lineBreakArgument",
+    "[tag \\\\][bracket [[][atom 1cm][bracket ]]]");
+})();
diff --git a/app/gui/html/vendor/codemirror/mode/tcl/index.html b/app/gui/html/vendor/codemirror/mode/tcl/index.html
new file mode 100644
index 0000000..c48e253
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/tcl/index.html
@@ -0,0 +1,142 @@
+<!doctype html>
+
+<title>CodeMirror: Tcl mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link rel="stylesheet" href="../../theme/night.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="tcl.js"></script>
+<script src="../../addon/scroll/scrollpastend.js"></script>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Tcl</a>
+  </ul>
+</div>
+
+<article>
+<h2>Tcl mode</h2>
+<form><textarea id="code" name="code">
+##############################################################################################
+##  ##     whois.tcl for eggdrop by Ford_Lawnmower irc.geekshed.net #Script-Help        ##  ##
+##############################################################################################
+## To use this script you must set channel flag +whois (ie .chanset #chan +whois)           ##
+##############################################################################################
+##      ____                __                 ###########################################  ##
+##     / __/___ _ ___ _ ___/ /____ ___   ___   ###########################################  ##
+##    / _/ / _ `// _ `// _  // __// _ \ / _ \  ###########################################  ##
+##   /___/ \_, / \_, / \_,_//_/   \___// .__/  ###########################################  ##
+##        /___/ /___/                 /_/      ###########################################  ##
+##                                             ###########################################  ##
+##############################################################################################
+##  ##                             Start Setup.                                         ##  ##
+##############################################################################################
+namespace eval whois {
+## change cmdchar to the trigger you want to use                                        ##  ##
+  variable cmdchar "!"
+## change command to the word trigger you would like to use.                            ##  ##
+## Keep in mind, This will also change the .chanset +/-command                          ##  ##
+  variable command "whois"
+## change textf to the colors you want for the text.                                    ##  ##
+  variable textf "\017\00304"
+## change tagf to the colors you want for tags:                                         ##  ##
+  variable tagf "\017\002"
+## Change logo to the logo you want at the start of the line.                           ##  ##
+  variable logo "\017\00304\002\[\00306W\003hois\00304\]\017"
+## Change lineout to the results you want. Valid results are channel users modes topic  ##  ##
+  variable lineout "channel users modes topic"
+##############################################################################################
+##  ##                           End Setup.                                              ## ##
+##############################################################################################
+  variable channel ""
+  setudef flag $whois::command
+  bind pub -|- [string trimleft $whois::cmdchar]${whois::command} whois::list
+  bind raw -|- "311" whois::311
+  bind raw -|- "312" whois::312
+  bind raw -|- "319" whois::319
+  bind raw -|- "317" whois::317
+  bind raw -|- "313" whois::multi
+  bind raw -|- "310" whois::multi
+  bind raw -|- "335" whois::multi
+  bind raw -|- "301" whois::301
+  bind raw -|- "671" whois::multi
+  bind raw -|- "320" whois::multi
+  bind raw -|- "401" whois::multi
+  bind raw -|- "318" whois::318
+  bind raw -|- "307" whois::307
+}
+proc whois::311 {from key text} {
+  if {[regexp -- {^[^\s]+\s(.+?)\s(.+?)\s(.+?)\s\*\s\:(.+)$} $text wholematch nick ident host realname]} {
+    putserv "PRIVMSG $whois::channel :${whois::logo} ${whois::tagf}Host:${whois::textf} \
+        $nick \(${ident}@${host}\) ${whois::tagf}Realname:${whois::textf} $realname"
+  }
+}
+proc whois::multi {from key text} {
+  if {[regexp {\:(.*)$} $text match $key]} {
+    putserv "PRIVMSG $whois::channel :${whois::logo} ${whois::tagf}Note:${whois::textf} [subst $$key]"
+        return 1
+  }
+}
+proc whois::312 {from key text} {
+  regexp {([^\s]+)\s\:} $text match server
+  putserv "PRIVMSG $whois::channel :${whois::logo} ${whois::tagf}Server:${whois::textf} $server"
+}
+proc whois::319 {from key text} {
+  if {[regexp {.+\:(.+)$} $text match channels]} {
+    putserv "PRIVMSG $whois::channel :${whois::logo} ${whois::tagf}Channels:${whois::textf} $channels"
+  }
+}
+proc whois::317 {from key text} {
+  if {[regexp -- {.*\s(\d+)\s(\d+)\s\:} $text wholematch idle signon]} {
+    putserv "PRIVMSG $whois::channel :${whois::logo} ${whois::tagf}Connected:${whois::textf} \
+        [ctime $signon] ${whois::tagf}Idle:${whois::textf} [duration $idle]"
+  }
+}
+proc whois::301 {from key text} {
+  if {[regexp {^.+\s[^\s]+\s\:(.*)$} $text match awaymsg]} {
+    putserv "PRIVMSG $whois::channel :${whois::logo} ${whois::tagf}Away:${whois::textf} $awaymsg"
+  }
+}
+proc whois::318 {from key text} {
+  namespace eval whois {
+        variable channel ""
+  }
+  variable whois::channel ""
+}
+proc whois::307 {from key text} {
+  putserv "PRIVMSG $whois::channel :${whois::logo} ${whois::tagf}Services:${whois::textf} Registered Nick"
+}
+proc whois::list {nick host hand chan text} {
+  if {[lsearch -exact [channel info $chan] "+${whois::command}"] != -1} {
+    namespace eval whois {
+          variable channel ""
+        }
+    variable whois::channel $chan
+    putserv "WHOIS $text"
+  }
+}
+putlog "\002*Loaded* \017\00304\002\[\00306W\003hois\00304\]\017 \002by \
+Ford_Lawnmower irc.GeekShed.net #Script-Help"
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        theme: "night",
+        lineNumbers: true,
+        indentUnit: 2,
+        scrollPastEnd: true,
+        mode: "text/x-tcl"
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-tcl</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/tcl/tcl.js b/app/gui/html/vendor/codemirror/mode/tcl/tcl.js
new file mode 100644
index 0000000..4c29ee7
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/tcl/tcl.js
@@ -0,0 +1,144 @@
+//tcl mode by Ford_Lawnmower :: Based on Velocity mode by Steve O'Hara
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("tcl", function() {
+  function parseWords(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+  var keywords = parseWords("Tcl safe after append array auto_execok auto_import auto_load " +
+        "auto_mkindex auto_mkindex_old auto_qualify auto_reset bgerror " +
+        "binary break catch cd close concat continue dde eof encoding error " +
+        "eval exec exit expr fblocked fconfigure fcopy file fileevent filename " +
+        "filename flush for foreach format gets glob global history http if " +
+        "incr info interp join lappend lindex linsert list llength load lrange " +
+        "lreplace lsearch lset lsort memory msgcat namespace open package parray " +
+        "pid pkg::create pkg_mkIndex proc puts pwd re_syntax read regex regexp " +
+        "registry regsub rename resource return scan seek set socket source split " +
+        "string subst switch tcl_endOfWord tcl_findLibrary tcl_startOfNextWord " +
+        "tcl_wordBreakAfter tcl_startOfPreviousWord tcl_wordBreakBefore tcltest " +
+        "tclvars tell time trace unknown unset update uplevel upvar variable " +
+    "vwait");
+    var functions = parseWords("if elseif else and not or eq ne in ni for foreach while switch");
+    var isOperatorChar = /[+\-*&%=<>!?^\/\|]/;
+    function chain(stream, state, f) {
+      state.tokenize = f;
+      return f(stream, state);
+    }
+    function tokenBase(stream, state) {
+      var beforeParams = state.beforeParams;
+      state.beforeParams = false;
+      var ch = stream.next();
+      if ((ch == '"' || ch == "'") && state.inParams)
+        return chain(stream, state, tokenString(ch));
+      else if (/[\[\]{}\(\),;\.]/.test(ch)) {
+        if (ch == "(" && beforeParams) state.inParams = true;
+        else if (ch == ")") state.inParams = false;
+          return null;
+      }
+      else if (/\d/.test(ch)) {
+        stream.eatWhile(/[\w\.]/);
+        return "number";
+      }
+      else if (ch == "#" && stream.eat("*")) {
+        return chain(stream, state, tokenComment);
+      }
+      else if (ch == "#" && stream.match(/ *\[ *\[/)) {
+        return chain(stream, state, tokenUnparsed);
+      }
+      else if (ch == "#" && stream.eat("#")) {
+        stream.skipToEnd();
+        return "comment";
+      }
+      else if (ch == '"') {
+        stream.skipTo(/"/);
+        return "comment";
+      }
+      else if (ch == "$") {
+        stream.eatWhile(/[$_a-z0-9A-Z\.{:]/);
+        stream.eatWhile(/}/);
+        state.beforeParams = true;
+        return "builtin";
+      }
+      else if (isOperatorChar.test(ch)) {
+        stream.eatWhile(isOperatorChar);
+        return "comment";
+      }
+      else {
+        stream.eatWhile(/[\w\$_{}]/);
+        var word = stream.current().toLowerCase();
+        if (keywords && keywords.propertyIsEnumerable(word))
+          return "keyword";
+        if (functions && functions.propertyIsEnumerable(word)) {
+          state.beforeParams = true;
+          return "keyword";
+        }
+        return null;
+      }
+    }
+    function tokenString(quote) {
+      return function(stream, state) {
+      var escaped = false, next, end = false;
+      while ((next = stream.next()) != null) {
+        if (next == quote && !escaped) {
+          end = true;
+          break;
+        }
+        escaped = !escaped && next == "\\";
+      }
+      if (end) state.tokenize = tokenBase;
+        return "string";
+      };
+    }
+    function tokenComment(stream, state) {
+      var maybeEnd = false, ch;
+      while (ch = stream.next()) {
+        if (ch == "#" && maybeEnd) {
+          state.tokenize = tokenBase;
+          break;
+        }
+        maybeEnd = (ch == "*");
+      }
+      return "comment";
+    }
+    function tokenUnparsed(stream, state) {
+      var maybeEnd = 0, ch;
+      while (ch = stream.next()) {
+        if (ch == "#" && maybeEnd == 2) {
+          state.tokenize = tokenBase;
+          break;
+        }
+        if (ch == "]")
+          maybeEnd++;
+        else if (ch != " ")
+          maybeEnd = 0;
+      }
+      return "meta";
+    }
+    return {
+      startState: function() {
+        return {
+          tokenize: tokenBase,
+          beforeParams: false,
+          inParams: false
+        };
+      },
+      token: function(stream, state) {
+        if (stream.eatSpace()) return null;
+        return state.tokenize(stream, state);
+      }
+    };
+});
+CodeMirror.defineMIME("text/x-tcl", "tcl");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/tiddlywiki/index.html b/app/gui/html/vendor/codemirror/mode/tiddlywiki/index.html
new file mode 100644
index 0000000..6ef64a4
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/tiddlywiki/index.html
@@ -0,0 +1,154 @@
+<!doctype html>
+
+<title>CodeMirror: TiddlyWiki mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link rel="stylesheet" href="tiddlywiki.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/edit/matchbrackets.js"></script>
+<script src="tiddlywiki.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">TiddlyWiki</a>
+  </ul>
+</div>
+
+<article>
+<h2>TiddlyWiki mode</h2>
+
+
+<div><textarea id="code" name="code">
+!TiddlyWiki Formatting
+* Rendered versions can be found at: http://www.tiddlywiki.com/#Reference
+
+|!Option            | !Syntax            |
+|bold font          | ''bold''           |
+|italic type        | //italic//         |
+|underlined text    | __underlined__     |
+|strikethrough text | --strikethrough--  |
+|superscript text   | super^^script^^    |
+|subscript text     | sub~~script~~      |
+|highlighted text   | @@highlighted@@    |
+|preformatted text  | {{{preformatted}}} |
+
+!Block Elements
+<<<
+!Heading 1
+
+!!Heading 2
+
+!!!Heading 3
+
+!!!!Heading 4
+
+!!!!!Heading 5
+<<<
+
+!!Lists
+<<<
+* unordered list, level 1
+** unordered list, level 2
+*** unordered list, level 3
+
+# ordered list, level 1
+## ordered list, level 2
+### unordered list, level 3
+
+; definition list, term
+: definition list, description
+<<<
+
+!!Blockquotes
+<<<
+> blockquote, level 1
+>> blockquote, level 2
+>>> blockquote, level 3
+
+> blockquote
+<<<
+
+!!Preformatted Text
+<<<
+{{{
+preformatted (e.g. code)
+}}}
+<<<
+
+!!Code Sections
+<<<
+{{{
+Text style code
+}}}
+
+//{{{
+JS styled code. TiddlyWiki mixed mode should support highlighter switching in the future.
+//}}}
+
+<!--{{{-->
+XML styled code. TiddlyWiki mixed mode should support highlighter switching in the future.
+<!--}}}-->
+<<<
+
+!!Tables
+<<<
+|CssClass|k
+|!heading column 1|!heading column 2|
+|row 1, column 1|row 1, column 2|
+|row 2, column 1|row 2, column 2|
+|>|COLSPAN|
+|ROWSPAN| ... |
+|~| ... |
+|CssProperty:value;...| ... |
+|caption|c
+
+''Annotation:''
+* The {{{>}}} marker creates a "colspan", causing the current cell to merge with the one to the right.
+* The {{{~}}} marker creates a "rowspan", causing the current cell to merge with the one above.
+<<<
+!!Images /% TODO %/
+cf. [[TiddlyWiki.com|http://www.tiddlywiki.com/#EmbeddedImages]]
+
+!Hyperlinks
+* [[WikiWords|WikiWord]] are automatically transformed to hyperlinks to the respective tiddler
+** the automatic transformation can be suppressed by preceding the respective WikiWord with a tilde ({{{~}}}): {{{~WikiWord}}}
+* [[PrettyLinks]] are enclosed in square brackets and contain the desired tiddler name: {{{[[tiddler name]]}}}
+** optionally, a custom title or description can be added, separated by a pipe character ({{{|}}}): {{{[[title|target]]}}}<br>'''N.B.:''' In this case, the target can also be any website (i.e. URL).
+
+!Custom Styling
+* {{{@@CssProperty:value;CssProperty:value;...@@}}}<br>''N.B.:'' CSS color definitions should use lowercase letters to prevent the inadvertent creation of WikiWords.
+* <html><code>{{customCssClass{...}}}</code></html>
+* raw HTML can be inserted by enclosing the respective code in HTML tags: {{{<html> ... </html>}}}
+
+!Special Markers
+* {{{<br>}}} forces a manual line break
+* {{{----}}} creates a horizontal ruler
+* [[HTML entities|http://www.tiddlywiki.com/#HtmlEntities]]
+* [[HTML entities local|HtmlEntities]]
+* {{{<<macroName>>}}} calls the respective [[macro|Macros]]
+* To hide text within a tiddler so that it is not displayed, it can be wrapped in {{{/%}}} and {{{%/}}}.<br/>This can be a useful trick for hiding drafts or annotating complex markup.
+* To prevent wiki markup from taking effect for a particular section, that section can be enclosed in three double quotes: e.g. {{{"""WikiWord"""}}}.
+</textarea></div>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: 'tiddlywiki',      
+        lineNumbers: true,
+        matchBrackets: true
+      });
+    </script>
+
+    <p>TiddlyWiki mode supports a single configuration.</p>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-tiddlywiki</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/tiddlywiki/tiddlywiki.css b/app/gui/html/vendor/codemirror/mode/tiddlywiki/tiddlywiki.css
new file mode 100644
index 0000000..9a69b63
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/tiddlywiki/tiddlywiki.css
@@ -0,0 +1,14 @@
+span.cm-underlined {
+  text-decoration: underline;
+}
+span.cm-strikethrough {
+  text-decoration: line-through;
+}
+span.cm-brace {
+  color: #170;
+  font-weight: bold;
+}
+span.cm-table {
+  color: blue;
+  font-weight: bold;
+}
diff --git a/app/gui/html/vendor/codemirror/mode/tiddlywiki/tiddlywiki.js b/app/gui/html/vendor/codemirror/mode/tiddlywiki/tiddlywiki.js
new file mode 100644
index 0000000..ecd1d17
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/tiddlywiki/tiddlywiki.js
@@ -0,0 +1,366 @@
+/***
+    |''Name''|tiddlywiki.js|
+    |''Description''|Enables TiddlyWikiy syntax highlighting using CodeMirror|
+    |''Author''|PMario|
+    |''Version''|0.1.7|
+    |''Status''|''stable''|
+    |''Source''|[[GitHub|https://github.com/pmario/CodeMirror2/blob/tw-syntax/mode/tiddlywiki]]|
+    |''Documentation''|http://codemirror.tiddlyspace.com/|
+    |''License''|[[MIT License|http://www.opensource.org/licenses/mit-license.php]]|
+    |''CoreVersion''|2.5.0|
+    |''Requires''|codemirror.js|
+    |''Keywords''|syntax highlighting color code mirror codemirror|
+    ! Info
+    CoreVersion parameter is needed for TiddlyWiki only!
+***/
+//{{{
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("tiddlywiki", function () {
+  // Tokenizer
+  var textwords = {};
+
+  var keywords = function () {
+    function kw(type) {
+      return { type: type, style: "macro"};
+    }
+    return {
+      "allTags": kw('allTags'), "closeAll": kw('closeAll'), "list": kw('list'),
+      "newJournal": kw('newJournal'), "newTiddler": kw('newTiddler'),
+      "permaview": kw('permaview'), "saveChanges": kw('saveChanges'),
+      "search": kw('search'), "slider": kw('slider'),   "tabs": kw('tabs'),
+      "tag": kw('tag'), "tagging": kw('tagging'),       "tags": kw('tags'),
+      "tiddler": kw('tiddler'), "timeline": kw('timeline'),
+      "today": kw('today'), "version": kw('version'),   "option": kw('option'),
+
+      "with": kw('with'),
+      "filter": kw('filter')
+    };
+  }();
+
+  var isSpaceName = /[\w_\-]/i,
+  reHR = /^\-\-\-\-+$/,                                 // <hr>
+  reWikiCommentStart = /^\/\*\*\*$/,            // /***
+  reWikiCommentStop = /^\*\*\*\/$/,             // ***/
+  reBlockQuote = /^<<<$/,
+
+  reJsCodeStart = /^\/\/\{\{\{$/,                       // //{{{ js block start
+  reJsCodeStop = /^\/\/\}\}\}$/,                        // //}}} js stop
+  reXmlCodeStart = /^<!--\{\{\{-->$/,           // xml block start
+  reXmlCodeStop = /^<!--\}\}\}-->$/,            // xml stop
+
+  reCodeBlockStart = /^\{\{\{$/,                        // {{{ TW text div block start
+  reCodeBlockStop = /^\}\}\}$/,                 // }}} TW text stop
+
+  reUntilCodeStop = /.*?\}\}\}/;
+
+  function chain(stream, state, f) {
+    state.tokenize = f;
+    return f(stream, state);
+  }
+
+  // Used as scratch variables to communicate multiple values without
+  // consing up tons of objects.
+  var type, content;
+
+  function ret(tp, style, cont) {
+    type = tp;
+    content = cont;
+    return style;
+  }
+
+  function jsTokenBase(stream, state) {
+    var sol = stream.sol(), ch;
+
+    state.block = false;        // indicates the start of a code block.
+
+    ch = stream.peek();         // don't eat, to make matching simpler
+
+    // check start of  blocks
+    if (sol && /[<\/\*{}\-]/.test(ch)) {
+      if (stream.match(reCodeBlockStart)) {
+        state.block = true;
+        return chain(stream, state, twTokenCode);
+      }
+      if (stream.match(reBlockQuote)) {
+        return ret('quote', 'quote');
+      }
+      if (stream.match(reWikiCommentStart) || stream.match(reWikiCommentStop)) {
+        return ret('code', 'comment');
+      }
+      if (stream.match(reJsCodeStart) || stream.match(reJsCodeStop) || stream.match(reXmlCodeStart) || stream.match(reXmlCodeStop)) {
+        return ret('code', 'comment');
+      }
+      if (stream.match(reHR)) {
+        return ret('hr', 'hr');
+      }
+    } // sol
+    ch = stream.next();
+
+    if (sol && /[\/\*!#;:>|]/.test(ch)) {
+      if (ch == "!") { // tw header
+        stream.skipToEnd();
+        return ret("header", "header");
+      }
+      if (ch == "*") { // tw list
+        stream.eatWhile('*');
+        return ret("list", "comment");
+      }
+      if (ch == "#") { // tw numbered list
+        stream.eatWhile('#');
+        return ret("list", "comment");
+      }
+      if (ch == ";") { // definition list, term
+        stream.eatWhile(';');
+        return ret("list", "comment");
+      }
+      if (ch == ":") { // definition list, description
+        stream.eatWhile(':');
+        return ret("list", "comment");
+      }
+      if (ch == ">") { // single line quote
+        stream.eatWhile(">");
+        return ret("quote", "quote");
+      }
+      if (ch == '|') {
+        return ret('table', 'header');
+      }
+    }
+
+    if (ch == '{' && stream.match(/\{\{/)) {
+      return chain(stream, state, twTokenCode);
+    }
+
+    // rudimentary html:// file:// link matching. TW knows much more ...
+    if (/[hf]/i.test(ch)) {
+      if (/[ti]/i.test(stream.peek()) && stream.match(/\b(ttps?|tp|ile):\/\/[\-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/i)) {
+        return ret("link", "link");
+      }
+    }
+    // just a little string indicator, don't want to have the whole string covered
+    if (ch == '"') {
+      return ret('string', 'string');
+    }
+    if (ch == '~') {    // _no_ CamelCase indicator should be bold
+      return ret('text', 'brace');
+    }
+    if (/[\[\]]/.test(ch)) { // check for [[..]]
+      if (stream.peek() == ch) {
+        stream.next();
+        return ret('brace', 'brace');
+      }
+    }
+    if (ch == "@") {    // check for space link. TODO fix @@...@@ highlighting
+      stream.eatWhile(isSpaceName);
+      return ret("link", "link");
+    }
+    if (/\d/.test(ch)) {        // numbers
+      stream.eatWhile(/\d/);
+      return ret("number", "number");
+    }
+    if (ch == "/") { // tw invisible comment
+      if (stream.eat("%")) {
+        return chain(stream, state, twTokenComment);
+      }
+      else if (stream.eat("/")) { //
+        return chain(stream, state, twTokenEm);
+      }
+    }
+    if (ch == "_") { // tw underline
+      if (stream.eat("_")) {
+        return chain(stream, state, twTokenUnderline);
+      }
+    }
+    // strikethrough and mdash handling
+    if (ch == "-") {
+      if (stream.eat("-")) {
+        // if strikethrough looks ugly, change CSS.
+        if (stream.peek() != ' ')
+          return chain(stream, state, twTokenStrike);
+        // mdash
+        if (stream.peek() == ' ')
+          return ret('text', 'brace');
+      }
+    }
+    if (ch == "'") { // tw bold
+      if (stream.eat("'")) {
+        return chain(stream, state, twTokenStrong);
+      }
+    }
+    if (ch == "<") { // tw macro
+      if (stream.eat("<")) {
+        return chain(stream, state, twTokenMacro);
+      }
+    }
+    else {
+      return ret(ch);
+    }
+
+    // core macro handling
+    stream.eatWhile(/[\w\$_]/);
+    var word = stream.current(),
+    known = textwords.propertyIsEnumerable(word) && textwords[word];
+
+    return known ? ret(known.type, known.style, word) : ret("text", null, word);
+
+  } // jsTokenBase()
+
+  // tw invisible comment
+  function twTokenComment(stream, state) {
+    var maybeEnd = false,
+    ch;
+    while (ch = stream.next()) {
+      if (ch == "/" && maybeEnd) {
+        state.tokenize = jsTokenBase;
+        break;
+      }
+      maybeEnd = (ch == "%");
+    }
+    return ret("comment", "comment");
+  }
+
+  // tw strong / bold
+  function twTokenStrong(stream, state) {
+    var maybeEnd = false,
+    ch;
+    while (ch = stream.next()) {
+      if (ch == "'" && maybeEnd) {
+        state.tokenize = jsTokenBase;
+        break;
+      }
+      maybeEnd = (ch == "'");
+    }
+    return ret("text", "strong");
+  }
+
+  // tw code
+  function twTokenCode(stream, state) {
+    var ch, sb = state.block;
+
+    if (sb && stream.current()) {
+      return ret("code", "comment");
+    }
+
+    if (!sb && stream.match(reUntilCodeStop)) {
+      state.tokenize = jsTokenBase;
+      return ret("code", "comment");
+    }
+
+    if (sb && stream.sol() && stream.match(reCodeBlockStop)) {
+      state.tokenize = jsTokenBase;
+      return ret("code", "comment");
+    }
+
+    ch = stream.next();
+    return (sb) ? ret("code", "comment") : ret("code", "comment");
+  }
+
+  // tw em / italic
+  function twTokenEm(stream, state) {
+    var maybeEnd = false,
+    ch;
+    while (ch = stream.next()) {
+      if (ch == "/" && maybeEnd) {
+        state.tokenize = jsTokenBase;
+        break;
+      }
+      maybeEnd = (ch == "/");
+    }
+    return ret("text", "em");
+  }
+
+  // tw underlined text
+  function twTokenUnderline(stream, state) {
+    var maybeEnd = false,
+    ch;
+    while (ch = stream.next()) {
+      if (ch == "_" && maybeEnd) {
+        state.tokenize = jsTokenBase;
+        break;
+      }
+      maybeEnd = (ch == "_");
+    }
+    return ret("text", "underlined");
+  }
+
+  // tw strike through text looks ugly
+  // change CSS if needed
+  function twTokenStrike(stream, state) {
+    var maybeEnd = false, ch;
+
+    while (ch = stream.next()) {
+      if (ch == "-" && maybeEnd) {
+        state.tokenize = jsTokenBase;
+        break;
+      }
+      maybeEnd = (ch == "-");
+    }
+    return ret("text", "strikethrough");
+  }
+
+  // macro
+  function twTokenMacro(stream, state) {
+    var ch, word, known;
+
+    if (stream.current() == '<<') {
+      return ret('brace', 'macro');
+    }
+
+    ch = stream.next();
+    if (!ch) {
+      state.tokenize = jsTokenBase;
+      return ret(ch);
+    }
+    if (ch == ">") {
+      if (stream.peek() == '>') {
+        stream.next();
+        state.tokenize = jsTokenBase;
+        return ret("brace", "macro");
+      }
+    }
+
+    stream.eatWhile(/[\w\$_]/);
+    word = stream.current();
+    known = keywords.propertyIsEnumerable(word) && keywords[word];
+
+    if (known) {
+      return ret(known.type, known.style, word);
+    }
+    else {
+      return ret("macro", null, word);
+    }
+  }
+
+  // Interface
+  return {
+    startState: function () {
+      return {
+        tokenize: jsTokenBase,
+        indented: 0,
+        level: 0
+      };
+    },
+
+    token: function (stream, state) {
+      if (stream.eatSpace()) return null;
+      var style = state.tokenize(stream, state);
+      return style;
+    },
+
+    electricChars: ""
+  };
+});
+
+CodeMirror.defineMIME("text/x-tiddlywiki", "tiddlywiki");
+});
+
+//}}}
diff --git a/app/gui/html/vendor/codemirror/mode/tiki/index.html b/app/gui/html/vendor/codemirror/mode/tiki/index.html
new file mode 100644
index 0000000..5315dbf
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/tiki/index.html
@@ -0,0 +1,95 @@
+<!doctype html>
+
+<title>CodeMirror: Tiki wiki mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link rel="stylesheet" href="tiki.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="tiki.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Tiki wiki</a>
+  </ul>
+</div>
+
+<article>
+<h2>Tiki wiki mode</h2>
+
+
+<div><textarea id="code" name="code">
+Headings
+!Header 1
+!!Header 2
+!!!Header 3
+!!!!Header 4
+!!!!!Header 5
+!!!!!!Header 6
+
+Styling
+-=titlebar=-
+^^ Box on multi
+lines
+of content^^
+__bold__
+''italic''
+===underline===
+::center::
+--Line Through--
+
+Operators
+~np~No parse~/np~
+
+Link
+[link|desc|nocache]
+
+Wiki
+((Wiki))
+((Wiki|desc))
+((Wiki|desc|timeout))
+
+Table
+||row1 col1|row1 col2|row1 col3
+row2 col1|row2 col2|row2 col3
+row3 col1|row3 col2|row3 col3||
+
+Lists:
+*bla
+**bla-1
+++continue-bla-1
+***bla-2
+++continue-bla-1
+*bla
++continue-bla
+#bla
+** tra-la-la
++continue-bla
+#bla
+
+Plugin (standard):
+{PLUGIN(attr="my attr")}
+Plugin Body
+{PLUGIN}
+
+Plugin (inline):
+{plugin attr="my attr"}
+</textarea></div>
+
+<script type="text/javascript">
+	var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: 'tiki',      
+        lineNumbers: true
+    });
+</script>
+
+</article>
diff --git a/app/gui/html/vendor/codemirror/mode/tiki/tiki.css b/app/gui/html/vendor/codemirror/mode/tiki/tiki.css
new file mode 100644
index 0000000..0dbc3ea
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/tiki/tiki.css
@@ -0,0 +1,26 @@
+.cm-tw-syntaxerror {
+	color: #FFF;
+	background-color: #900;
+}
+
+.cm-tw-deleted {
+	text-decoration: line-through;
+}
+
+.cm-tw-header5 {
+	font-weight: bold;
+}
+.cm-tw-listitem:first-child { /*Added first child to fix duplicate padding when highlighting*/
+	padding-left: 10px;
+}
+
+.cm-tw-box {
+	border-top-width: 0px ! important;
+	border-style: solid;
+	border-width: 1px;
+	border-color: inherit;
+}
+
+.cm-tw-underline {
+	text-decoration: underline;
+}
\ No newline at end of file
diff --git a/app/gui/html/vendor/codemirror/mode/tiki/tiki.js b/app/gui/html/vendor/codemirror/mode/tiki/tiki.js
new file mode 100644
index 0000000..eb9a893
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/tiki/tiki.js
@@ -0,0 +1,320 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode('tiki', function(config) {
+  function inBlock(style, terminator, returnTokenizer) {
+    return function(stream, state) {
+      while (!stream.eol()) {
+        if (stream.match(terminator)) {
+          state.tokenize = inText;
+          break;
+        }
+        stream.next();
+      }
+
+      if (returnTokenizer) state.tokenize = returnTokenizer;
+
+      return style;
+    };
+  }
+
+  function inLine(style) {
+    return function(stream, state) {
+      while(!stream.eol()) {
+        stream.next();
+      }
+      state.tokenize = inText;
+      return style;
+    };
+  }
+
+  function inText(stream, state) {
+    function chain(parser) {
+      state.tokenize = parser;
+      return parser(stream, state);
+    }
+
+    var sol = stream.sol();
+    var ch = stream.next();
+
+    //non start of line
+    switch (ch) { //switch is generally much faster than if, so it is used here
+    case "{": //plugin
+      stream.eat("/");
+      stream.eatSpace();
+      var tagName = "";
+      var c;
+      while ((c = stream.eat(/[^\s\u00a0=\"\'\/?(}]/))) tagName += c;
+      state.tokenize = inPlugin;
+      return "tag";
+      break;
+    case "_": //bold
+      if (stream.eat("_")) {
+        return chain(inBlock("strong", "__", inText));
+      }
+      break;
+    case "'": //italics
+      if (stream.eat("'")) {
+        // Italic text
+        return chain(inBlock("em", "''", inText));
+      }
+      break;
+    case "(":// Wiki Link
+      if (stream.eat("(")) {
+        return chain(inBlock("variable-2", "))", inText));
+      }
+      break;
+    case "[":// Weblink
+      return chain(inBlock("variable-3", "]", inText));
+      break;
+    case "|": //table
+      if (stream.eat("|")) {
+        return chain(inBlock("comment", "||"));
+      }
+      break;
+    case "-":
+      if (stream.eat("=")) {//titleBar
+        return chain(inBlock("header string", "=-", inText));
+      } else if (stream.eat("-")) {//deleted
+        return chain(inBlock("error tw-deleted", "--", inText));
+      }
+      break;
+    case "=": //underline
+      if (stream.match("==")) {
+        return chain(inBlock("tw-underline", "===", inText));
+      }
+      break;
+    case ":":
+      if (stream.eat(":")) {
+        return chain(inBlock("comment", "::"));
+      }
+      break;
+    case "^": //box
+      return chain(inBlock("tw-box", "^"));
+      break;
+    case "~": //np
+      if (stream.match("np~")) {
+        return chain(inBlock("meta", "~/np~"));
+      }
+      break;
+    }
+
+    //start of line types
+    if (sol) {
+      switch (ch) {
+      case "!": //header at start of line
+        if (stream.match('!!!!!')) {
+          return chain(inLine("header string"));
+        } else if (stream.match('!!!!')) {
+          return chain(inLine("header string"));
+        } else if (stream.match('!!!')) {
+          return chain(inLine("header string"));
+        } else if (stream.match('!!')) {
+          return chain(inLine("header string"));
+        } else {
+          return chain(inLine("header string"));
+        }
+        break;
+      case "*": //unordered list line item, or <li /> at start of line
+      case "#": //ordered list line item, or <li /> at start of line
+      case "+": //ordered list line item, or <li /> at start of line
+        return chain(inLine("tw-listitem bracket"));
+        break;
+      }
+    }
+
+    //stream.eatWhile(/[&{]/); was eating up plugins, turned off to act less like html and more like tiki
+    return null;
+  }
+
+  var indentUnit = config.indentUnit;
+
+  // Return variables for tokenizers
+  var pluginName, type;
+  function inPlugin(stream, state) {
+    var ch = stream.next();
+    var peek = stream.peek();
+
+    if (ch == "}") {
+      state.tokenize = inText;
+      //type = ch == ")" ? "endPlugin" : "selfclosePlugin"; inPlugin
+      return "tag";
+    } else if (ch == "(" || ch == ")") {
+      return "bracket";
+    } else if (ch == "=") {
+      type = "equals";
+
+      if (peek == ">") {
+        ch = stream.next();
+        peek = stream.peek();
+      }
+
+      //here we detect values directly after equal character with no quotes
+      if (!/[\'\"]/.test(peek)) {
+        state.tokenize = inAttributeNoQuote();
+      }
+      //end detect values
+
+      return "operator";
+    } else if (/[\'\"]/.test(ch)) {
+      state.tokenize = inAttribute(ch);
+      return state.tokenize(stream, state);
+    } else {
+      stream.eatWhile(/[^\s\u00a0=\"\'\/?]/);
+      return "keyword";
+    }
+  }
+
+  function inAttribute(quote) {
+    return function(stream, state) {
+      while (!stream.eol()) {
+        if (stream.next() == quote) {
+          state.tokenize = inPlugin;
+          break;
+        }
+      }
+      return "string";
+    };
+  }
+
+  function inAttributeNoQuote() {
+    return function(stream, state) {
+      while (!stream.eol()) {
+        var ch = stream.next();
+        var peek = stream.peek();
+        if (ch == " " || ch == "," || /[ )}]/.test(peek)) {
+      state.tokenize = inPlugin;
+      break;
+    }
+  }
+  return "string";
+};
+                     }
+
+var curState, setStyle;
+function pass() {
+  for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
+}
+
+function cont() {
+  pass.apply(null, arguments);
+  return true;
+}
+
+function pushContext(pluginName, startOfLine) {
+  var noIndent = curState.context && curState.context.noIndent;
+  curState.context = {
+    prev: curState.context,
+    pluginName: pluginName,
+    indent: curState.indented,
+    startOfLine: startOfLine,
+    noIndent: noIndent
+  };
+}
+
+function popContext() {
+  if (curState.context) curState.context = curState.context.prev;
+}
+
+function element(type) {
+  if (type == "openPlugin") {curState.pluginName = pluginName; return cont(attributes, endplugin(curState.startOfLine));}
+  else if (type == "closePlugin") {
+    var err = false;
+    if (curState.context) {
+      err = curState.context.pluginName != pluginName;
+      popContext();
+    } else {
+      err = true;
+    }
+    if (err) setStyle = "error";
+    return cont(endcloseplugin(err));
+  }
+  else if (type == "string") {
+    if (!curState.context || curState.context.name != "!cdata") pushContext("!cdata");
+    if (curState.tokenize == inText) popContext();
+    return cont();
+  }
+  else return cont();
+}
+
+function endplugin(startOfLine) {
+  return function(type) {
+    if (
+      type == "selfclosePlugin" ||
+        type == "endPlugin"
+    )
+      return cont();
+    if (type == "endPlugin") {pushContext(curState.pluginName, startOfLine); return cont();}
+    return cont();
+  };
+}
+
+function endcloseplugin(err) {
+  return function(type) {
+    if (err) setStyle = "error";
+    if (type == "endPlugin") return cont();
+    return pass();
+  };
+}
+
+function attributes(type) {
+  if (type == "keyword") {setStyle = "attribute"; return cont(attributes);}
+  if (type == "equals") return cont(attvalue, attributes);
+  return pass();
+}
+function attvalue(type) {
+  if (type == "keyword") {setStyle = "string"; return cont();}
+  if (type == "string") return cont(attvaluemaybe);
+  return pass();
+}
+function attvaluemaybe(type) {
+  if (type == "string") return cont(attvaluemaybe);
+  else return pass();
+}
+return {
+  startState: function() {
+    return {tokenize: inText, cc: [], indented: 0, startOfLine: true, pluginName: null, context: null};
+  },
+  token: function(stream, state) {
+    if (stream.sol()) {
+      state.startOfLine = true;
+      state.indented = stream.indentation();
+    }
+    if (stream.eatSpace()) return null;
+
+    setStyle = type = pluginName = null;
+    var style = state.tokenize(stream, state);
+    if ((style || type) && style != "comment") {
+      curState = state;
+      while (true) {
+        var comb = state.cc.pop() || element;
+        if (comb(type || style)) break;
+      }
+    }
+    state.startOfLine = false;
+    return setStyle || style;
+  },
+  indent: function(state, textAfter) {
+    var context = state.context;
+    if (context && context.noIndent) return 0;
+    if (context && /^{\//.test(textAfter))
+        context = context.prev;
+        while (context && !context.startOfLine)
+          context = context.prev;
+        if (context) return context.indent + indentUnit;
+        else return 0;
+       },
+    electricChars: "/"
+  };
+});
+
+CodeMirror.defineMIME("text/tiki", "tiki");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/toml/index.html b/app/gui/html/vendor/codemirror/mode/toml/index.html
new file mode 100644
index 0000000..c59b4cc
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/toml/index.html
@@ -0,0 +1,73 @@
+<!doctype html>
+
+<title>CodeMirror: TOML Mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="toml.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">TOML Mode</a>
+  </ul>
+</div>
+
+<article>
+<h2>TOML Mode</h2>
+<form><textarea id="code" name="code">
+# This is a TOML document. Boom.
+
+title = "TOML Example"
+
+[owner]
+name = "Tom Preston-Werner"
+organization = "GitHub"
+bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
+dob = 1979-05-27T07:32:00Z # First class dates? Why not?
+
+[database]
+server = "192.168.1.1"
+ports = [ 8001, 8001, 8002 ]
+connection_max = 5000
+enabled = true
+
+[servers]
+
+  # You can indent as you please. Tabs or spaces. TOML don't care.
+  [servers.alpha]
+  ip = "10.0.0.1"
+  dc = "eqdc10"
+  
+  [servers.beta]
+  ip = "10.0.0.2"
+  dc = "eqdc10"
+  
+[clients]
+data = [ ["gamma", "delta"], [1, 2] ]
+
+# Line breaks are OK when inside arrays
+hosts = [
+  "alpha",
+  "omega"
+]
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: {name: "toml"},
+        lineNumbers: true
+      });
+    </script>
+    <h3>The TOML Mode</h3>
+      <p> Created by Forbes Lindesay.</p>
+    <p><strong>MIME type defined:</strong> <code>text/x-toml</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/toml/toml.js b/app/gui/html/vendor/codemirror/mode/toml/toml.js
new file mode 100644
index 0000000..2c722b3
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/toml/toml.js
@@ -0,0 +1,85 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("toml", function () {
+  return {
+    startState: function () {
+      return {
+        inString: false,
+        stringType: "",
+        lhs: true,
+        inArray: 0
+      };
+    },
+    token: function (stream, state) {
+      //check for state changes
+      if (!state.inString && ((stream.peek() == '"') || (stream.peek() == "'"))) {
+        state.stringType = stream.peek();
+        stream.next(); // Skip quote
+        state.inString = true; // Update state
+      }
+      if (stream.sol() && state.inArray === 0) {
+        state.lhs = true;
+      }
+      //return state
+      if (state.inString) {
+        while (state.inString && !stream.eol()) {
+          if (stream.peek() === state.stringType) {
+            stream.next(); // Skip quote
+            state.inString = false; // Clear flag
+          } else if (stream.peek() === '\\') {
+            stream.next();
+            stream.next();
+          } else {
+            stream.match(/^.[^\\\"\']*/);
+          }
+        }
+        return state.lhs ? "property string" : "string"; // Token style
+      } else if (state.inArray && stream.peek() === ']') {
+        stream.next();
+        state.inArray--;
+        return 'bracket';
+      } else if (state.lhs && stream.peek() === '[' && stream.skipTo(']')) {
+        stream.next();//skip closing ]
+        // array of objects has an extra open & close []
+        if (stream.peek() === ']') stream.next();
+        return "atom";
+      } else if (stream.peek() === "#") {
+        stream.skipToEnd();
+        return "comment";
+      } else if (stream.eatSpace()) {
+        return null;
+      } else if (state.lhs && stream.eatWhile(function (c) { return c != '=' && c != ' '; })) {
+        return "property";
+      } else if (state.lhs && stream.peek() === "=") {
+        stream.next();
+        state.lhs = false;
+        return null;
+      } else if (!state.lhs && stream.match(/^\d\d\d\d[\d\-\:\.T]*Z/)) {
+        return 'atom'; //date
+      } else if (!state.lhs && (stream.match('true') || stream.match('false'))) {
+        return 'atom';
+      } else if (!state.lhs && stream.peek() === '[') {
+        state.inArray++;
+        stream.next();
+        return 'bracket';
+      } else if (!state.lhs && stream.match(/^\-?\d+(?:\.\d+)?/)) {
+        return 'number';
+      } else if (!stream.eatSpace()) {
+        stream.next();
+      }
+      return null;
+    }
+  };
+});
+
+CodeMirror.defineMIME('text/x-toml', 'toml');
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/turtle/index.html b/app/gui/html/vendor/codemirror/mode/turtle/index.html
new file mode 100644
index 0000000..27689c3
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/turtle/index.html
@@ -0,0 +1,50 @@
+<!doctype html>
+
+<title>CodeMirror: Turtle mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="turtle.js"></script>
+<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Turtle</a>
+  </ul>
+</div>
+
+<article>
+<h2>Turtle mode</h2>
+<form><textarea id="code" name="code">
+ at prefix foaf: <http://xmlns.com/foaf/0.1/> .
+ at prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> .
+ at prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+
+<http://purl.org/net/bsletten> 
+    a foaf:Person;
+    foaf:interest <http://www.w3.org/2000/01/sw/>;
+    foaf:based_near [
+        geo:lat "34.0736111" ;
+        geo:lon "-118.3994444"
+   ]
+
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: "text/turtle",
+        matchBrackets: true
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/turtle</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/turtle/turtle.js b/app/gui/html/vendor/codemirror/mode/turtle/turtle.js
new file mode 100644
index 0000000..de9fc2b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/turtle/turtle.js
@@ -0,0 +1,157 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("turtle", function(config) {
+  var indentUnit = config.indentUnit;
+  var curPunc;
+
+  function wordRegexp(words) {
+    return new RegExp("^(?:" + words.join("|") + ")$", "i");
+  }
+  var ops = wordRegexp([]);
+  var keywords = wordRegexp(["@prefix", "@base", "a"]);
+  var operatorChars = /[*+\-<>=&|]/;
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+    curPunc = null;
+    if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) {
+      stream.match(/^[^\s\u00a0>]*>?/);
+      return "atom";
+    }
+    else if (ch == "\"" || ch == "'") {
+      state.tokenize = tokenLiteral(ch);
+      return state.tokenize(stream, state);
+    }
+    else if (/[{}\(\),\.;\[\]]/.test(ch)) {
+      curPunc = ch;
+      return null;
+    }
+    else if (ch == "#") {
+      stream.skipToEnd();
+      return "comment";
+    }
+    else if (operatorChars.test(ch)) {
+      stream.eatWhile(operatorChars);
+      return null;
+    }
+    else if (ch == ":") {
+          return "operator";
+        } else {
+      stream.eatWhile(/[_\w\d]/);
+      if(stream.peek() == ":") {
+        return "variable-3";
+      } else {
+             var word = stream.current();
+
+             if(keywords.test(word)) {
+                        return "meta";
+             }
+
+             if(ch >= "A" && ch <= "Z") {
+                    return "comment";
+                 } else {
+                        return "keyword";
+                 }
+      }
+      var word = stream.current();
+      if (ops.test(word))
+        return null;
+      else if (keywords.test(word))
+        return "meta";
+      else
+        return "variable";
+    }
+  }
+
+  function tokenLiteral(quote) {
+    return function(stream, state) {
+      var escaped = false, ch;
+      while ((ch = stream.next()) != null) {
+        if (ch == quote && !escaped) {
+          state.tokenize = tokenBase;
+          break;
+        }
+        escaped = !escaped && ch == "\\";
+      }
+      return "string";
+    };
+  }
+
+  function pushContext(state, type, col) {
+    state.context = {prev: state.context, indent: state.indent, col: col, type: type};
+  }
+  function popContext(state) {
+    state.indent = state.context.indent;
+    state.context = state.context.prev;
+  }
+
+  return {
+    startState: function() {
+      return {tokenize: tokenBase,
+              context: null,
+              indent: 0,
+              col: 0};
+    },
+
+    token: function(stream, state) {
+      if (stream.sol()) {
+        if (state.context && state.context.align == null) state.context.align = false;
+        state.indent = stream.indentation();
+      }
+      if (stream.eatSpace()) return null;
+      var style = state.tokenize(stream, state);
+
+      if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") {
+        state.context.align = true;
+      }
+
+      if (curPunc == "(") pushContext(state, ")", stream.column());
+      else if (curPunc == "[") pushContext(state, "]", stream.column());
+      else if (curPunc == "{") pushContext(state, "}", stream.column());
+      else if (/[\]\}\)]/.test(curPunc)) {
+        while (state.context && state.context.type == "pattern") popContext(state);
+        if (state.context && curPunc == state.context.type) popContext(state);
+      }
+      else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state);
+      else if (/atom|string|variable/.test(style) && state.context) {
+        if (/[\}\]]/.test(state.context.type))
+          pushContext(state, "pattern", stream.column());
+        else if (state.context.type == "pattern" && !state.context.align) {
+          state.context.align = true;
+          state.context.col = stream.column();
+        }
+      }
+
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      var firstChar = textAfter && textAfter.charAt(0);
+      var context = state.context;
+      if (/[\]\}]/.test(firstChar))
+        while (context && context.type == "pattern") context = context.prev;
+
+      var closing = context && firstChar == context.type;
+      if (!context)
+        return 0;
+      else if (context.type == "pattern")
+        return context.col;
+      else if (context.align)
+        return context.col + (closing ? 0 : 1);
+      else
+        return context.indent + (closing ? 0 : indentUnit);
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/turtle", "turtle");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/vb/index.html b/app/gui/html/vendor/codemirror/mode/vb/index.html
new file mode 100644
index 0000000..8b81a88
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/vb/index.html
@@ -0,0 +1,102 @@
+<!doctype html>
+
+<title>CodeMirror: VB.NET mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link href="http://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet" type="text/css">
+<script src="../../lib/codemirror.js"></script>
+<script src="vb.js"></script>
+<script type="text/javascript" src="../../addon/runmode/runmode.js"></script>
+<style>
+      .CodeMirror {border: 1px solid #aaa; height:210px; height: auto;}
+      .CodeMirror-scroll { overflow-x: auto; overflow-y: hidden;}
+      .CodeMirror pre { font-family: Inconsolata; font-size: 14px}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">VB.NET</a>
+  </ul>
+</div>
+
+<article>
+<h2>VB.NET mode</h2>
+
+<script type="text/javascript">
+function test(golden, text) {
+  var ok = true;
+  var i = 0;
+  function callback(token, style, lineNo, pos){
+		//console.log(String(token) + " " + String(style) + " " + String(lineNo) + " " + String(pos));
+    var result = [String(token), String(style)];
+    if (golden[i][0] != result[0] || golden[i][1] != result[1]){
+      return "Error, expected: " + String(golden[i]) + ", got: " + String(result);
+      ok = false;
+    }
+    i++;
+  }
+  CodeMirror.runMode(text, "text/x-vb",callback); 
+
+  if (ok) return "Tests OK";
+}
+function testTypes() {
+  var golden = [['Integer','keyword'],[' ','null'],['Float','keyword']]
+  var text =  "Integer Float";
+  return test(golden,text);
+}
+function testIf(){
+  var golden = [['If','keyword'],[' ','null'],['True','keyword'],[' ','null'],['End','keyword'],[' ','null'],['If','keyword']];
+  var text = 'If True End If';
+  return test(golden, text);
+}
+function testDecl(){
+   var golden = [['Dim','keyword'],[' ','null'],['x','variable'],[' ','null'],['as','keyword'],[' ','null'],['Integer','keyword']];
+   var text = 'Dim x as Integer';
+   return test(golden, text);
+}
+function testAll(){
+  var result = "";
+
+  result += testTypes() + "\n";
+  result += testIf() + "\n";
+  result += testDecl() + "\n";
+  return result;
+
+}
+function initText(editor) {
+  var content = 'Class rocket\nPrivate quality as Double\nPublic Sub launch() as String\nif quality > 0.8\nlaunch = "Successful"\nElse\nlaunch = "Failed"\nEnd If\nEnd sub\nEnd class\n';
+  editor.setValue(content);
+  for (var i =0; i< editor.lineCount(); i++) editor.indentLine(i);
+}
+function init() {
+    editor = CodeMirror.fromTextArea(document.getElementById("solution"), {
+        lineNumbers: true,
+        mode: "text/x-vb",
+        readOnly: false
+    });
+    runTest();
+}
+function runTest() {
+	document.getElementById('testresult').innerHTML = testAll();
+  initText(editor);
+	
+}
+document.body.onload = init;
+</script>
+
+  <div id="edit">
+  <textarea style="width:95%;height:200px;padding:5px;" name="solution" id="solution" ></textarea>
+  </div>
+  <pre id="testresult"></pre>
+  <p>MIME type defined: <code>text/x-vb</code>.</p>
+
+</article>
diff --git a/app/gui/html/vendor/codemirror/mode/vb/vb.js b/app/gui/html/vendor/codemirror/mode/vb/vb.js
new file mode 100644
index 0000000..4fd8021
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/vb/vb.js
@@ -0,0 +1,271 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("vb", function(conf, parserConf) {
+    var ERRORCLASS = 'error';
+
+    function wordRegexp(words) {
+        return new RegExp("^((" + words.join(")|(") + "))\\b", "i");
+    }
+
+    var singleOperators = new RegExp("^[\\+\\-\\*/%&\\\\|\\^~<>!]");
+    var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]');
+    var doubleOperators = new RegExp("^((==)|(<>)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
+    var doubleDelimiters = new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
+    var tripleDelimiters = new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))");
+    var identifiers = new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
+
+    var openingKeywords = ['class','module', 'sub','enum','select','while','if','function',  'get','set','property', 'try'];
+    var middleKeywords = ['else','elseif','case', 'catch'];
+    var endKeywords = ['next','loop'];
+
+    var wordOperators = wordRegexp(['and', 'or', 'not', 'xor', 'in']);
+    var commonkeywords = ['as', 'dim', 'break',  'continue','optional', 'then',  'until',
+                          'goto', 'byval','byref','new','handles','property', 'return',
+                          'const','private', 'protected', 'friend', 'public', 'shared', 'static', 'true','false'];
+    var commontypes = ['integer','string','double','decimal','boolean','short','char', 'float','single'];
+
+    var keywords = wordRegexp(commonkeywords);
+    var types = wordRegexp(commontypes);
+    var stringPrefixes = '"';
+
+    var opening = wordRegexp(openingKeywords);
+    var middle = wordRegexp(middleKeywords);
+    var closing = wordRegexp(endKeywords);
+    var doubleClosing = wordRegexp(['end']);
+    var doOpening = wordRegexp(['do']);
+
+    var indentInfo = null;
+
+
+
+
+    function indent(_stream, state) {
+      state.currentIndent++;
+    }
+
+    function dedent(_stream, state) {
+      state.currentIndent--;
+    }
+    // tokenizers
+    function tokenBase(stream, state) {
+        if (stream.eatSpace()) {
+            return null;
+        }
+
+        var ch = stream.peek();
+
+        // Handle Comments
+        if (ch === "'") {
+            stream.skipToEnd();
+            return 'comment';
+        }
+
+
+        // Handle Number Literals
+        if (stream.match(/^((&H)|(&O))?[0-9\.a-f]/i, false)) {
+            var floatLiteral = false;
+            // Floats
+            if (stream.match(/^\d*\.\d+F?/i)) { floatLiteral = true; }
+            else if (stream.match(/^\d+\.\d*F?/)) { floatLiteral = true; }
+            else if (stream.match(/^\.\d+F?/)) { floatLiteral = true; }
+
+            if (floatLiteral) {
+                // Float literals may be "imaginary"
+                stream.eat(/J/i);
+                return 'number';
+            }
+            // Integers
+            var intLiteral = false;
+            // Hex
+            if (stream.match(/^&H[0-9a-f]+/i)) { intLiteral = true; }
+            // Octal
+            else if (stream.match(/^&O[0-7]+/i)) { intLiteral = true; }
+            // Decimal
+            else if (stream.match(/^[1-9]\d*F?/)) {
+                // Decimal literals may be "imaginary"
+                stream.eat(/J/i);
+                // TODO - Can you have imaginary longs?
+                intLiteral = true;
+            }
+            // Zero by itself with no other piece of number.
+            else if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; }
+            if (intLiteral) {
+                // Integer literals may be "long"
+                stream.eat(/L/i);
+                return 'number';
+            }
+        }
+
+        // Handle Strings
+        if (stream.match(stringPrefixes)) {
+            state.tokenize = tokenStringFactory(stream.current());
+            return state.tokenize(stream, state);
+        }
+
+        // Handle operators and Delimiters
+        if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) {
+            return null;
+        }
+        if (stream.match(doubleOperators)
+            || stream.match(singleOperators)
+            || stream.match(wordOperators)) {
+            return 'operator';
+        }
+        if (stream.match(singleDelimiters)) {
+            return null;
+        }
+        if (stream.match(doOpening)) {
+            indent(stream,state);
+            state.doInCurrentLine = true;
+            return 'keyword';
+        }
+        if (stream.match(opening)) {
+            if (! state.doInCurrentLine)
+              indent(stream,state);
+            else
+              state.doInCurrentLine = false;
+            return 'keyword';
+        }
+        if (stream.match(middle)) {
+            return 'keyword';
+        }
+
+        if (stream.match(doubleClosing)) {
+            dedent(stream,state);
+            dedent(stream,state);
+            return 'keyword';
+        }
+        if (stream.match(closing)) {
+            dedent(stream,state);
+            return 'keyword';
+        }
+
+        if (stream.match(types)) {
+            return 'keyword';
+        }
+
+        if (stream.match(keywords)) {
+            return 'keyword';
+        }
+
+        if (stream.match(identifiers)) {
+            return 'variable';
+        }
+
+        // Handle non-detected items
+        stream.next();
+        return ERRORCLASS;
+    }
+
+    function tokenStringFactory(delimiter) {
+        var singleline = delimiter.length == 1;
+        var OUTCLASS = 'string';
+
+        return function(stream, state) {
+            while (!stream.eol()) {
+                stream.eatWhile(/[^'"]/);
+                if (stream.match(delimiter)) {
+                    state.tokenize = tokenBase;
+                    return OUTCLASS;
+                } else {
+                    stream.eat(/['"]/);
+                }
+            }
+            if (singleline) {
+                if (parserConf.singleLineStringErrors) {
+                    return ERRORCLASS;
+                } else {
+                    state.tokenize = tokenBase;
+                }
+            }
+            return OUTCLASS;
+        };
+    }
+
+
+    function tokenLexer(stream, state) {
+        var style = state.tokenize(stream, state);
+        var current = stream.current();
+
+        // Handle '.' connected identifiers
+        if (current === '.') {
+            style = state.tokenize(stream, state);
+            current = stream.current();
+            if (style === 'variable') {
+                return 'variable';
+            } else {
+                return ERRORCLASS;
+            }
+        }
+
+
+        var delimiter_index = '[({'.indexOf(current);
+        if (delimiter_index !== -1) {
+            indent(stream, state );
+        }
+        if (indentInfo === 'dedent') {
+            if (dedent(stream, state)) {
+                return ERRORCLASS;
+            }
+        }
+        delimiter_index = '])}'.indexOf(current);
+        if (delimiter_index !== -1) {
+            if (dedent(stream, state)) {
+                return ERRORCLASS;
+            }
+        }
+
+        return style;
+    }
+
+    var external = {
+        electricChars:"dDpPtTfFeE ",
+        startState: function() {
+            return {
+              tokenize: tokenBase,
+              lastToken: null,
+              currentIndent: 0,
+              nextLineIndent: 0,
+              doInCurrentLine: false
+
+
+          };
+        },
+
+        token: function(stream, state) {
+            if (stream.sol()) {
+              state.currentIndent += state.nextLineIndent;
+              state.nextLineIndent = 0;
+              state.doInCurrentLine = 0;
+            }
+            var style = tokenLexer(stream, state);
+
+            state.lastToken = {style:style, content: stream.current()};
+
+
+
+            return style;
+        },
+
+        indent: function(state, textAfter) {
+            var trueText = textAfter.replace(/^\s+|\s+$/g, '') ;
+            if (trueText.match(closing) || trueText.match(doubleClosing) || trueText.match(middle)) return conf.indentUnit*(state.currentIndent-1);
+            if(state.currentIndent < 0) return 0;
+            return state.currentIndent * conf.indentUnit;
+        }
+
+    };
+    return external;
+});
+
+CodeMirror.defineMIME("text/x-vb", "vb");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/vbscript/index.html b/app/gui/html/vendor/codemirror/mode/vbscript/index.html
new file mode 100644
index 0000000..9b506b7
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/vbscript/index.html
@@ -0,0 +1,55 @@
+<!doctype html>
+
+<title>CodeMirror: VBScript mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="vbscript.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">VBScript</a>
+  </ul>
+</div>
+
+<article>
+<h2>VBScript mode</h2>
+
+
+<div><textarea id="code" name="code">
+' Pete Guhl
+' 03-04-2012
+'
+' Basic VBScript support for codemirror2
+
+Const ForReading = 1, ForWriting = 2, ForAppending = 8
+
+Call Sub020_PostBroadcastToUrbanAirship(strUserName, strPassword, intTransmitID, strResponse)
+
+If Not IsNull(strResponse) AND Len(strResponse) = 0 Then
+	boolTransmitOkYN = False
+Else
+	' WScript.Echo "Oh Happy Day! Oh Happy DAY!"
+	boolTransmitOkYN = True
+End If
+</textarea></div>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        indentUnit: 4
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/vbscript</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/vbscript/vbscript.js b/app/gui/html/vendor/codemirror/mode/vbscript/vbscript.js
new file mode 100644
index 0000000..4be7c7f
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/vbscript/vbscript.js
@@ -0,0 +1,347 @@
+/*
+For extra ASP classic objects, initialize CodeMirror instance with this option:
+    isASP: true
+
+E.G.:
+    var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        isASP: true
+      });
+*/
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("vbscript", function(conf, parserConf) {
+    var ERRORCLASS = 'error';
+
+    function wordRegexp(words) {
+        return new RegExp("^((" + words.join(")|(") + "))\\b", "i");
+    }
+
+    var singleOperators = new RegExp("^[\\+\\-\\*/&\\\\\\^<>=]");
+    var doubleOperators = new RegExp("^((<>)|(<=)|(>=))");
+    var singleDelimiters = new RegExp('^[\\.,]');
+    var brakets = new RegExp('^[\\(\\)]');
+    var identifiers = new RegExp("^[A-Za-z][_A-Za-z0-9]*");
+
+    var openingKeywords = ['class','sub','select','while','if','function', 'property', 'with', 'for'];
+    var middleKeywords = ['else','elseif','case'];
+    var endKeywords = ['next','loop','wend'];
+
+    var wordOperators = wordRegexp(['and', 'or', 'not', 'xor', 'is', 'mod', 'eqv', 'imp']);
+    var commonkeywords = ['dim', 'redim', 'then',  'until', 'randomize',
+                          'byval','byref','new','property', 'exit', 'in',
+                          'const','private', 'public',
+                          'get','set','let', 'stop', 'on error resume next', 'on error goto 0', 'option explicit', 'call', 'me'];
+
+    //This list was from: http://msdn.microsoft.com/en-us/library/f8tbc79x(v=vs.84).aspx
+    var atomWords = ['true', 'false', 'nothing', 'empty', 'null'];
+    //This list was from: http://msdn.microsoft.com/en-us/library/3ca8tfek(v=vs.84).aspx
+    var builtinFuncsWords = ['abs', 'array', 'asc', 'atn', 'cbool', 'cbyte', 'ccur', 'cdate', 'cdbl', 'chr', 'cint', 'clng', 'cos', 'csng', 'cstr', 'date', 'dateadd', 'datediff', 'datepart',
+                        'dateserial', 'datevalue', 'day', 'escape', 'eval', 'execute', 'exp', 'filter', 'formatcurrency', 'formatdatetime', 'formatnumber', 'formatpercent', 'getlocale', 'getobject',
+                        'getref', 'hex', 'hour', 'inputbox', 'instr', 'instrrev', 'int', 'fix', 'isarray', 'isdate', 'isempty', 'isnull', 'isnumeric', 'isobject', 'join', 'lbound', 'lcase', 'left',
+                        'len', 'loadpicture', 'log', 'ltrim', 'rtrim', 'trim', 'maths', 'mid', 'minute', 'month', 'monthname', 'msgbox', 'now', 'oct', 'replace', 'rgb', 'right', 'rnd', 'round',
+                        'scriptengine', 'scriptenginebuildversion', 'scriptenginemajorversion', 'scriptengineminorversion', 'second', 'setlocale', 'sgn', 'sin', 'space', 'split', 'sqr', 'strcomp',
+                        'string', 'strreverse', 'tan', 'time', 'timer', 'timeserial', 'timevalue', 'typename', 'ubound', 'ucase', 'unescape', 'vartype', 'weekday', 'weekdayname', 'year'];
+
+    //This list was from: http://msdn.microsoft.com/en-us/library/ydz4cfk3(v=vs.84).aspx
+    var builtinConsts = ['vbBlack', 'vbRed', 'vbGreen', 'vbYellow', 'vbBlue', 'vbMagenta', 'vbCyan', 'vbWhite', 'vbBinaryCompare', 'vbTextCompare',
+                         'vbSunday', 'vbMonday', 'vbTuesday', 'vbWednesday', 'vbThursday', 'vbFriday', 'vbSaturday', 'vbUseSystemDayOfWeek', 'vbFirstJan1', 'vbFirstFourDays', 'vbFirstFullWeek',
+                         'vbGeneralDate', 'vbLongDate', 'vbShortDate', 'vbLongTime', 'vbShortTime', 'vbObjectError',
+                         'vbOKOnly', 'vbOKCancel', 'vbAbortRetryIgnore', 'vbYesNoCancel', 'vbYesNo', 'vbRetryCancel', 'vbCritical', 'vbQuestion', 'vbExclamation', 'vbInformation', 'vbDefaultButton1', 'vbDefaultButton2',
+                         'vbDefaultButton3', 'vbDefaultButton4', 'vbApplicationModal', 'vbSystemModal', 'vbOK', 'vbCancel', 'vbAbort', 'vbRetry', 'vbIgnore', 'vbYes', 'vbNo',
+                         'vbCr', 'VbCrLf', 'vbFormFeed', 'vbLf', 'vbNewLine', 'vbNullChar', 'vbNullString', 'vbTab', 'vbVerticalTab', 'vbUseDefault', 'vbTrue', 'vbFalse',
+                         'vbEmpty', 'vbNull', 'vbInteger', 'vbLong', 'vbSingle', 'vbDouble', 'vbCurrency', 'vbDate', 'vbString', 'vbObject', 'vbError', 'vbBoolean', 'vbVariant', 'vbDataObject', 'vbDecimal', 'vbByte', 'vbArray'];
+    //This list was from: http://msdn.microsoft.com/en-us/library/hkc375ea(v=vs.84).aspx
+    var builtinObjsWords = ['WScript', 'err', 'debug', 'RegExp'];
+    var knownProperties = ['description', 'firstindex', 'global', 'helpcontext', 'helpfile', 'ignorecase', 'length', 'number', 'pattern', 'source', 'value', 'count'];
+    var knownMethods = ['clear', 'execute', 'raise', 'replace', 'test', 'write', 'writeline', 'close', 'open', 'state', 'eof', 'update', 'addnew', 'end', 'createobject', 'quit'];
+
+    var aspBuiltinObjsWords = ['server', 'response', 'request', 'session', 'application'];
+    var aspKnownProperties = ['buffer', 'cachecontrol', 'charset', 'contenttype', 'expires', 'expiresabsolute', 'isclientconnected', 'pics', 'status', //response
+                              'clientcertificate', 'cookies', 'form', 'querystring', 'servervariables', 'totalbytes', //request
+                              'contents', 'staticobjects', //application
+                              'codepage', 'lcid', 'sessionid', 'timeout', //session
+                              'scripttimeout']; //server
+    var aspKnownMethods = ['addheader', 'appendtolog', 'binarywrite', 'end', 'flush', 'redirect', //response
+                           'binaryread', //request
+                           'remove', 'removeall', 'lock', 'unlock', //application
+                           'abandon', //session
+                           'getlasterror', 'htmlencode', 'mappath', 'transfer', 'urlencode']; //server
+
+    var knownWords = knownMethods.concat(knownProperties);
+
+    builtinObjsWords = builtinObjsWords.concat(builtinConsts);
+
+    if (conf.isASP){
+        builtinObjsWords = builtinObjsWords.concat(aspBuiltinObjsWords);
+        knownWords = knownWords.concat(aspKnownMethods, aspKnownProperties);
+    };
+
+    var keywords = wordRegexp(commonkeywords);
+    var atoms = wordRegexp(atomWords);
+    var builtinFuncs = wordRegexp(builtinFuncsWords);
+    var builtinObjs = wordRegexp(builtinObjsWords);
+    var known = wordRegexp(knownWords);
+    var stringPrefixes = '"';
+
+    var opening = wordRegexp(openingKeywords);
+    var middle = wordRegexp(middleKeywords);
+    var closing = wordRegexp(endKeywords);
+    var doubleClosing = wordRegexp(['end']);
+    var doOpening = wordRegexp(['do']);
+    var noIndentWords = wordRegexp(['on error resume next', 'exit']);
+    var comment = wordRegexp(['rem']);
+
+
+    function indent(_stream, state) {
+      state.currentIndent++;
+    }
+
+    function dedent(_stream, state) {
+      state.currentIndent--;
+    }
+    // tokenizers
+    function tokenBase(stream, state) {
+        if (stream.eatSpace()) {
+            return 'space';
+            //return null;
+        }
+
+        var ch = stream.peek();
+
+        // Handle Comments
+        if (ch === "'") {
+            stream.skipToEnd();
+            return 'comment';
+        }
+        if (stream.match(comment)){
+            stream.skipToEnd();
+            return 'comment';
+        }
+
+
+        // Handle Number Literals
+        if (stream.match(/^((&H)|(&O))?[0-9\.]/i, false) && !stream.match(/^((&H)|(&O))?[0-9\.]+[a-z_]/i, false)) {
+            var floatLiteral = false;
+            // Floats
+            if (stream.match(/^\d*\.\d+/i)) { floatLiteral = true; }
+            else if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; }
+            else if (stream.match(/^\.\d+/)) { floatLiteral = true; }
+
+            if (floatLiteral) {
+                // Float literals may be "imaginary"
+                stream.eat(/J/i);
+                return 'number';
+            }
+            // Integers
+            var intLiteral = false;
+            // Hex
+            if (stream.match(/^&H[0-9a-f]+/i)) { intLiteral = true; }
+            // Octal
+            else if (stream.match(/^&O[0-7]+/i)) { intLiteral = true; }
+            // Decimal
+            else if (stream.match(/^[1-9]\d*F?/)) {
+                // Decimal literals may be "imaginary"
+                stream.eat(/J/i);
+                // TODO - Can you have imaginary longs?
+                intLiteral = true;
+            }
+            // Zero by itself with no other piece of number.
+            else if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; }
+            if (intLiteral) {
+                // Integer literals may be "long"
+                stream.eat(/L/i);
+                return 'number';
+            }
+        }
+
+        // Handle Strings
+        if (stream.match(stringPrefixes)) {
+            state.tokenize = tokenStringFactory(stream.current());
+            return state.tokenize(stream, state);
+        }
+
+        // Handle operators and Delimiters
+        if (stream.match(doubleOperators)
+            || stream.match(singleOperators)
+            || stream.match(wordOperators)) {
+            return 'operator';
+        }
+        if (stream.match(singleDelimiters)) {
+            return null;
+        }
+
+        if (stream.match(brakets)) {
+            return "bracket";
+        }
+
+        if (stream.match(noIndentWords)) {
+            state.doInCurrentLine = true;
+
+            return 'keyword';
+        }
+
+        if (stream.match(doOpening)) {
+            indent(stream,state);
+            state.doInCurrentLine = true;
+
+            return 'keyword';
+        }
+        if (stream.match(opening)) {
+            if (! state.doInCurrentLine)
+              indent(stream,state);
+            else
+              state.doInCurrentLine = false;
+
+            return 'keyword';
+        }
+        if (stream.match(middle)) {
+            return 'keyword';
+        }
+
+
+        if (stream.match(doubleClosing)) {
+            dedent(stream,state);
+            dedent(stream,state);
+
+            return 'keyword';
+        }
+        if (stream.match(closing)) {
+            if (! state.doInCurrentLine)
+              dedent(stream,state);
+            else
+              state.doInCurrentLine = false;
+
+            return 'keyword';
+        }
+
+        if (stream.match(keywords)) {
+            return 'keyword';
+        }
+
+        if (stream.match(atoms)) {
+            return 'atom';
+        }
+
+        if (stream.match(known)) {
+            return 'variable-2';
+        }
+
+        if (stream.match(builtinFuncs)) {
+            return 'builtin';
+        }
+
+        if (stream.match(builtinObjs)){
+            return 'variable-2';
+        }
+
+        if (stream.match(identifiers)) {
+            return 'variable';
+        }
+
+        // Handle non-detected items
+        stream.next();
+        return ERRORCLASS;
+    }
+
+    function tokenStringFactory(delimiter) {
+        var singleline = delimiter.length == 1;
+        var OUTCLASS = 'string';
+
+        return function(stream, state) {
+            while (!stream.eol()) {
+                stream.eatWhile(/[^'"]/);
+                if (stream.match(delimiter)) {
+                    state.tokenize = tokenBase;
+                    return OUTCLASS;
+                } else {
+                    stream.eat(/['"]/);
+                }
+            }
+            if (singleline) {
+                if (parserConf.singleLineStringErrors) {
+                    return ERRORCLASS;
+                } else {
+                    state.tokenize = tokenBase;
+                }
+            }
+            return OUTCLASS;
+        };
+    }
+
+
+    function tokenLexer(stream, state) {
+        var style = state.tokenize(stream, state);
+        var current = stream.current();
+
+        // Handle '.' connected identifiers
+        if (current === '.') {
+            style = state.tokenize(stream, state);
+
+            current = stream.current();
+            if (style.substr(0, 8) === 'variable' || style==='builtin' || style==='keyword'){//|| knownWords.indexOf(current.substring(1)) > -1) {
+                if (style === 'builtin' || style === 'keyword') style='variable';
+                if (knownWords.indexOf(current.substr(1)) > -1) style='variable-2';
+
+                return style;
+            } else {
+                return ERRORCLASS;
+            }
+        }
+
+        return style;
+    }
+
+    var external = {
+        electricChars:"dDpPtTfFeE ",
+        startState: function() {
+            return {
+              tokenize: tokenBase,
+              lastToken: null,
+              currentIndent: 0,
+              nextLineIndent: 0,
+              doInCurrentLine: false,
+              ignoreKeyword: false
+
+
+          };
+        },
+
+        token: function(stream, state) {
+            if (stream.sol()) {
+              state.currentIndent += state.nextLineIndent;
+              state.nextLineIndent = 0;
+              state.doInCurrentLine = 0;
+            }
+            var style = tokenLexer(stream, state);
+
+            state.lastToken = {style:style, content: stream.current()};
+
+            if (style==='space') style=null;
+
+            return style;
+        },
+
+        indent: function(state, textAfter) {
+            var trueText = textAfter.replace(/^\s+|\s+$/g, '') ;
+            if (trueText.match(closing) || trueText.match(doubleClosing) || trueText.match(middle)) return conf.indentUnit*(state.currentIndent-1);
+            if(state.currentIndent < 0) return 0;
+            return state.currentIndent * conf.indentUnit;
+        }
+
+    };
+    return external;
+});
+
+CodeMirror.defineMIME("text/vbscript", "vbscript");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/velocity/index.html b/app/gui/html/vendor/codemirror/mode/velocity/index.html
new file mode 100644
index 0000000..bd38b88
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/velocity/index.html
@@ -0,0 +1,118 @@
+<!doctype html>
+
+<title>CodeMirror: Velocity mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link rel="stylesheet" href="../../theme/night.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="velocity.js"></script>
+<style>.CodeMirror {border: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Velocity</a>
+  </ul>
+</div>
+
+<article>
+<h2>Velocity mode</h2>
+<form><textarea id="code" name="code">
+## Velocity Code Demo
+#*
+   based on PL/SQL mode by Peter Raganitsch, adapted to Velocity by Steve O'Hara ( http://www.pivotal-solutions.co.uk )
+   August 2011
+*#
+
+#*
+   This is a multiline comment.
+   This is the second line
+*#
+
+#[[ hello steve
+   This has invalid syntax that would normally need "poor man's escaping" like:
+
+   #define()
+
+   ${blah
+]]#
+
+#include( "disclaimer.txt" "opinion.txt" )
+#include( $foo $bar )
+
+#parse( "lecorbusier.vm" )
+#parse( $foo )
+
+#evaluate( 'string with VTL #if(true)will be displayed#end' )
+
+#define( $hello ) Hello $who #end #set( $who = "World!") $hello ## displays Hello World!
+
+#foreach( $customer in $customerList )
+
+    $foreach.count $customer.Name
+
+    #if( $foo == ${bar})
+        it's true!
+        #break
+    #{else}
+        it's not!
+        #stop
+    #end
+
+    #if ($foreach.parent.hasNext)
+        $velocityCount
+    #end
+#end
+
+$someObject.getValues("this is a string split
+        across lines")
+
+$someObject("This plus $something in the middle").method(7567).property
+
+#macro( tablerows $color $somelist )
+    #foreach( $something in $somelist )
+        <tr><td bgcolor=$color>$something</td></tr>
+        <tr><td bgcolor=$color>$bodyContent</td></tr>
+    #end
+#end
+
+#tablerows("red" ["dadsdf","dsa"])
+#@tablerows("red" ["dadsdf","dsa"]) some body content #end
+
+   Variable reference: #set( $monkey = $bill )
+   String literal: #set( $monkey.Friend = 'monica' )
+   Property reference: #set( $monkey.Blame = $whitehouse.Leak )
+   Method reference: #set( $monkey.Plan = $spindoctor.weave($web) )
+   Number literal: #set( $monkey.Number = 123 )
+   Range operator: #set( $monkey.Numbers = [1..3] )
+   Object list: #set( $monkey.Say = ["Not", $my, "fault"] )
+   Object map: #set( $monkey.Map = {"banana" : "good", "roast beef" : "bad"})
+
+The RHS can also be a simple arithmetic expression, such as:
+Addition: #set( $value = $foo + 1 )
+   Subtraction: #set( $value = $bar - 1 )
+   Multiplication: #set( $value = $foo * $bar )
+   Division: #set( $value = $foo / $bar )
+   Remainder: #set( $value = $foo % $bar )
+
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        theme: "night",
+        lineNumbers: true,
+        indentUnit: 4,
+        mode: "text/velocity"
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/velocity</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/velocity/velocity.js b/app/gui/html/vendor/codemirror/mode/velocity/velocity.js
new file mode 100644
index 0000000..b64636b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/velocity/velocity.js
@@ -0,0 +1,198 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("velocity", function() {
+    function parseWords(str) {
+        var obj = {}, words = str.split(" ");
+        for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+        return obj;
+    }
+
+    var keywords = parseWords("#end #else #break #stop #[[ #]] " +
+                              "#{end} #{else} #{break} #{stop}");
+    var functions = parseWords("#if #elseif #foreach #set #include #parse #macro #define #evaluate " +
+                               "#{if} #{elseif} #{foreach} #{set} #{include} #{parse} #{macro} #{define} #{evaluate}");
+    var specials = parseWords("$foreach.count $foreach.hasNext $foreach.first $foreach.last $foreach.topmost $foreach.parent.count $foreach.parent.hasNext $foreach.parent.first $foreach.parent.last $foreach.parent $velocityCount $!bodyContent $bodyContent");
+    var isOperatorChar = /[+\-*&%=<>!?:\/|]/;
+
+    function chain(stream, state, f) {
+        state.tokenize = f;
+        return f(stream, state);
+    }
+    function tokenBase(stream, state) {
+        var beforeParams = state.beforeParams;
+        state.beforeParams = false;
+        var ch = stream.next();
+        // start of unparsed string?
+        if ((ch == "'") && state.inParams) {
+            state.lastTokenWasBuiltin = false;
+            return chain(stream, state, tokenString(ch));
+        }
+        // start of parsed string?
+        else if ((ch == '"')) {
+            state.lastTokenWasBuiltin = false;
+            if (state.inString) {
+                state.inString = false;
+                return "string";
+            }
+            else if (state.inParams)
+                return chain(stream, state, tokenString(ch));
+        }
+        // is it one of the special signs []{}().,;? Seperator?
+        else if (/[\[\]{}\(\),;\.]/.test(ch)) {
+            if (ch == "(" && beforeParams)
+                state.inParams = true;
+            else if (ch == ")") {
+                state.inParams = false;
+                state.lastTokenWasBuiltin = true;
+            }
+            return null;
+        }
+        // start of a number value?
+        else if (/\d/.test(ch)) {
+            state.lastTokenWasBuiltin = false;
+            stream.eatWhile(/[\w\.]/);
+            return "number";
+        }
+        // multi line comment?
+        else if (ch == "#" && stream.eat("*")) {
+            state.lastTokenWasBuiltin = false;
+            return chain(stream, state, tokenComment);
+        }
+        // unparsed content?
+        else if (ch == "#" && stream.match(/ *\[ *\[/)) {
+            state.lastTokenWasBuiltin = false;
+            return chain(stream, state, tokenUnparsed);
+        }
+        // single line comment?
+        else if (ch == "#" && stream.eat("#")) {
+            state.lastTokenWasBuiltin = false;
+            stream.skipToEnd();
+            return "comment";
+        }
+        // variable?
+        else if (ch == "$") {
+            stream.eatWhile(/[\w\d\$_\.{}]/);
+            // is it one of the specials?
+            if (specials && specials.propertyIsEnumerable(stream.current())) {
+                return "keyword";
+            }
+            else {
+                state.lastTokenWasBuiltin = true;
+                state.beforeParams = true;
+                return "builtin";
+            }
+        }
+        // is it a operator?
+        else if (isOperatorChar.test(ch)) {
+            state.lastTokenWasBuiltin = false;
+            stream.eatWhile(isOperatorChar);
+            return "operator";
+        }
+        else {
+            // get the whole word
+            stream.eatWhile(/[\w\$_{}@]/);
+            var word = stream.current();
+            // is it one of the listed keywords?
+            if (keywords && keywords.propertyIsEnumerable(word))
+                return "keyword";
+            // is it one of the listed functions?
+            if (functions && functions.propertyIsEnumerable(word) ||
+                    (stream.current().match(/^#@?[a-z0-9_]+ *$/i) && stream.peek()=="(") &&
+                     !(functions && functions.propertyIsEnumerable(word.toLowerCase()))) {
+                state.beforeParams = true;
+                state.lastTokenWasBuiltin = false;
+                return "keyword";
+            }
+            if (state.inString) {
+                state.lastTokenWasBuiltin = false;
+                return "string";
+            }
+            if (stream.pos > word.length && stream.string.charAt(stream.pos-word.length-1)=="." && state.lastTokenWasBuiltin)
+                return "builtin";
+            // default: just a "word"
+            state.lastTokenWasBuiltin = false;
+            return null;
+        }
+    }
+
+    function tokenString(quote) {
+        return function(stream, state) {
+            var escaped = false, next, end = false;
+            while ((next = stream.next()) != null) {
+                if ((next == quote) && !escaped) {
+                    end = true;
+                    break;
+                }
+                if (quote=='"' && stream.peek() == '$' && !escaped) {
+                    state.inString = true;
+                    end = true;
+                    break;
+                }
+                escaped = !escaped && next == "\\";
+            }
+            if (end) state.tokenize = tokenBase;
+            return "string";
+        };
+    }
+
+    function tokenComment(stream, state) {
+        var maybeEnd = false, ch;
+        while (ch = stream.next()) {
+            if (ch == "#" && maybeEnd) {
+                state.tokenize = tokenBase;
+                break;
+            }
+            maybeEnd = (ch == "*");
+        }
+        return "comment";
+    }
+
+    function tokenUnparsed(stream, state) {
+        var maybeEnd = 0, ch;
+        while (ch = stream.next()) {
+            if (ch == "#" && maybeEnd == 2) {
+                state.tokenize = tokenBase;
+                break;
+            }
+            if (ch == "]")
+                maybeEnd++;
+            else if (ch != " ")
+                maybeEnd = 0;
+        }
+        return "meta";
+    }
+    // Interface
+
+    return {
+        startState: function() {
+            return {
+                tokenize: tokenBase,
+                beforeParams: false,
+                inParams: false,
+                inString: false,
+                lastTokenWasBuiltin: false
+            };
+        },
+
+        token: function(stream, state) {
+            if (stream.eatSpace()) return null;
+            return state.tokenize(stream, state);
+        },
+        blockCommentStart: "#*",
+        blockCommentEnd: "*#",
+        lineComment: "##",
+        fold: "velocity"
+    };
+});
+
+CodeMirror.defineMIME("text/velocity", "velocity");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/verilog/index.html b/app/gui/html/vendor/codemirror/mode/verilog/index.html
new file mode 100644
index 0000000..cc71056
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/verilog/index.html
@@ -0,0 +1,132 @@
+<!doctype html>
+
+<title>CodeMirror: Verilog mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="verilog.js"></script>
+<style>.CodeMirror {border: 2px inset #dee;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Verilog</a>
+  </ul>
+</div>
+
+<article>
+<h2>Verilog mode</h2>
+<form><textarea id="code" name="code">
+/* Verilog demo code */
+
+module butterfly
+  #(
+    parameter WIDTH = 32,
+    parameter MWIDTH = 1
+    )
+   (
+    input wire                     clk,
+    input wire                     rst_n,
+    // m_in contains data that passes through this block with no change.
+    input wire [MWIDTH-1:0]        m_in,
+    // The twiddle factor.
+    input wire signed [WIDTH-1:0]  w,
+    // XA
+    input wire signed [WIDTH-1:0]  xa,
+    // XB
+    input wire signed [WIDTH-1:0]  xb,
+    // Set to 1 when new data is present on inputs.
+    input wire                     x_nd,
+    // delayed version of m_in.
+    output reg [MWIDTH-1:0]        m_out,
+    // YA = XA + W*XB
+    // YB = XA - W*XB
+    output wire signed [WIDTH-1:0] ya,
+    output wire signed [WIDTH-1:0] yb,
+    output reg                     y_nd,
+    output reg                     error
+    );
+
+   // Set wire to the real and imag parts for convenience.
+   wire signed [WIDTH/2-1:0]        xa_re;
+   wire signed [WIDTH/2-1:0]        xa_im;
+   assign xa_re = xa[WIDTH-1:WIDTH/2];
+   assign xa_im = xa[WIDTH/2-1:0];
+   wire signed [WIDTH/2-1: 0]       ya_re;
+   wire signed [WIDTH/2-1: 0]       ya_im;
+   assign ya = {ya_re, ya_im};
+   wire signed [WIDTH/2-1: 0]       yb_re;
+   wire signed [WIDTH/2-1: 0]       yb_im;
+   assign yb = {yb_re, yb_im};
+
+   // Delayed stuff.
+   reg signed [WIDTH/2-1:0]         xa_re_z;
+   reg signed [WIDTH/2-1:0]         xa_im_z;
+   // Output of multiplier
+   wire signed [WIDTH-1:0]          xbw;
+   wire signed [WIDTH/2-1:0]        xbw_re;
+   wire signed [WIDTH/2-1:0]        xbw_im;
+   assign xbw_re = xbw[WIDTH-1:WIDTH/2];
+   assign xbw_im = xbw[WIDTH/2-1:0];
+   // Do summing
+   // I don't think we should get overflow here because of the
+   // size of the twiddle factors.
+   // If we do testing should catch it.
+   assign ya_re = xa_re_z + xbw_re;
+   assign ya_im = xa_im_z + xbw_im;
+   assign yb_re = xa_re_z - xbw_re;
+   assign yb_im = xa_im_z - xbw_im;
+   
+   // Create the multiply module.
+   multiply_complex #(WIDTH) multiply_complex_0
+     (.clk(clk),
+      .rst_n(rst_n),
+      .x(xb),
+      .y(w),
+      .z(xbw)
+      );
+
+  always @ (posedge clk)
+    begin
+       if (!rst_n)
+         begin
+            y_nd <= 1'b0;
+            error <= 1'b0;
+         end
+       else
+         begin
+            // Set delay for x_nd_old and m.
+            y_nd <= x_nd;
+            m_out <= m_in;
+            if (x_nd)
+              begin
+                 xa_re_z <= xa_re/2;
+                 xa_im_z <= xa_im/2;
+              end
+         end
+    end
+   
+endmodule
+</textarea></form>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        mode: "text/x-verilog"
+      });
+    </script>
+
+    <p>Simple mode that tries to handle Verilog-like languages as well as it
+    can. Takes one configuration parameters: <code>keywords</code>, an
+    object whose property names are the keywords in the language.</p>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-verilog</code> (Verilog code).</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/verilog/verilog.js b/app/gui/html/vendor/codemirror/mode/verilog/verilog.js
new file mode 100644
index 0000000..bc4fd4f
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/verilog/verilog.js
@@ -0,0 +1,192 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("verilog", function(config, parserConfig) {
+  var indentUnit = config.indentUnit,
+      keywords = parserConfig.keywords || {},
+      blockKeywords = parserConfig.blockKeywords || {},
+      atoms = parserConfig.atoms || {},
+      hooks = parserConfig.hooks || {},
+      multiLineStrings = parserConfig.multiLineStrings;
+  var isOperatorChar = /[&|~><!\)\(*#%@+\/=?\:;}{,\.\^\-\[\]]/;
+
+  var curPunc;
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+    if (hooks[ch]) {
+      var result = hooks[ch](stream, state);
+      if (result !== false) return result;
+    }
+    if (ch == '"') {
+      state.tokenize = tokenString(ch);
+      return state.tokenize(stream, state);
+    }
+    if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
+      curPunc = ch;
+      return null;
+    }
+    if (/[\d']/.test(ch)) {
+      stream.eatWhile(/[\w\.']/);
+      return "number";
+    }
+    if (ch == "/") {
+      if (stream.eat("*")) {
+        state.tokenize = tokenComment;
+        return tokenComment(stream, state);
+      }
+      if (stream.eat("/")) {
+        stream.skipToEnd();
+        return "comment";
+      }
+    }
+    if (isOperatorChar.test(ch)) {
+      stream.eatWhile(isOperatorChar);
+      return "operator";
+    }
+    stream.eatWhile(/[\w\$_]/);
+    var cur = stream.current();
+    if (keywords.propertyIsEnumerable(cur)) {
+      if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+      return "keyword";
+    }
+    if (atoms.propertyIsEnumerable(cur)) return "atom";
+    return "variable";
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, next, end = false;
+      while ((next = stream.next()) != null) {
+        if (next == quote && !escaped) {end = true; break;}
+        escaped = !escaped && next == "\\";
+      }
+      if (end || !(escaped || multiLineStrings))
+        state.tokenize = tokenBase;
+      return "string";
+    };
+  }
+
+  function tokenComment(stream, state) {
+    var maybeEnd = false, ch;
+    while (ch = stream.next()) {
+      if (ch == "/" && maybeEnd) {
+        state.tokenize = tokenBase;
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return "comment";
+  }
+
+  function Context(indented, column, type, align, prev) {
+    this.indented = indented;
+    this.column = column;
+    this.type = type;
+    this.align = align;
+    this.prev = prev;
+  }
+  function pushContext(state, col, type) {
+    return state.context = new Context(state.indented, col, type, null, state.context);
+  }
+  function popContext(state) {
+    var t = state.context.type;
+    if (t == ")" || t == "]" || t == "}")
+      state.indented = state.context.indented;
+    return state.context = state.context.prev;
+  }
+
+  // Interface
+
+  return {
+    startState: function(basecolumn) {
+      return {
+        tokenize: null,
+        context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
+        indented: 0,
+        startOfLine: true
+      };
+    },
+
+    token: function(stream, state) {
+      var ctx = state.context;
+      if (stream.sol()) {
+        if (ctx.align == null) ctx.align = false;
+        state.indented = stream.indentation();
+        state.startOfLine = true;
+      }
+      if (stream.eatSpace()) return null;
+      curPunc = null;
+      var style = (state.tokenize || tokenBase)(stream, state);
+      if (style == "comment" || style == "meta") return style;
+      if (ctx.align == null) ctx.align = true;
+
+      if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
+      else if (curPunc == "{") pushContext(state, stream.column(), "}");
+      else if (curPunc == "[") pushContext(state, stream.column(), "]");
+      else if (curPunc == "(") pushContext(state, stream.column(), ")");
+      else if (curPunc == "}") {
+        while (ctx.type == "statement") ctx = popContext(state);
+        if (ctx.type == "}") ctx = popContext(state);
+        while (ctx.type == "statement") ctx = popContext(state);
+      }
+      else if (curPunc == ctx.type) popContext(state);
+      else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
+        pushContext(state, stream.column(), "statement");
+      state.startOfLine = false;
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      if (state.tokenize != tokenBase && state.tokenize != null) return 0;
+      var firstChar = textAfter && textAfter.charAt(0), ctx = state.context, closing = firstChar == ctx.type;
+      if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit);
+      else if (ctx.align) return ctx.column + (closing ? 0 : 1);
+      else return ctx.indented + (closing ? 0 : indentUnit);
+    },
+
+    electricChars: "{}"
+  };
+});
+
+  function words(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+
+  var verilogKeywords = "always and assign automatic begin buf bufif0 bufif1 case casex casez cell cmos config " +
+    "deassign default defparam design disable edge else end endcase endconfig endfunction endgenerate endmodule " +
+    "endprimitive endspecify endtable endtask event for force forever fork function generate genvar highz0 " +
+    "highz1 if ifnone incdir include initial inout input instance integer join large liblist library localparam " +
+    "macromodule medium module nand negedge nmos nor noshowcancelled not notif0 notif1 or output parameter pmos " +
+    "posedge primitive pull0 pull1 pulldown pullup pulsestyle_onevent pulsestyle_ondetect rcmos real realtime " +
+    "reg release repeat rnmos rpmos rtran rtranif0 rtranif1 scalared showcancelled signed small specify specparam " +
+    "strong0 strong1 supply0 supply1 table task time tran tranif0 tranif1 tri tri0 tri1 triand trior trireg " +
+    "unsigned use vectored wait wand weak0 weak1 while wire wor xnor xor";
+
+  var verilogBlockKeywords = "begin bufif0 bufif1 case casex casez config else end endcase endconfig endfunction " +
+    "endgenerate endmodule endprimitive endspecify endtable endtask for forever function generate if ifnone " +
+    "macromodule module primitive repeat specify table task while";
+
+  function metaHook(stream) {
+    stream.eatWhile(/[\w\$_]/);
+    return "meta";
+  }
+
+  CodeMirror.defineMIME("text/x-verilog", {
+    name: "verilog",
+    keywords: words(verilogKeywords),
+    blockKeywords: words(verilogBlockKeywords),
+    atoms: words("null"),
+    hooks: {"`": metaHook, "$": metaHook}
+  });
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/xml/index.html b/app/gui/html/vendor/codemirror/mode/xml/index.html
new file mode 100644
index 0000000..60ebd20
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/xml/index.html
@@ -0,0 +1,57 @@
+<!doctype html>
+
+<title>CodeMirror: XML mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="xml.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">XML</a>
+  </ul>
+</div>
+
+<article>
+<h2>XML mode</h2>
+<form><textarea id="code" name="code">
+<html style="color: green">
+  <!-- this is a comment -->
+  <head>
+    <title>HTML Example</title>
+  </head>
+  <body>
+    The indentation tries to be <em>somewhat &quot;do what
+    I mean&quot;</em>... but might not match your style.
+  </body>
+</html>
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: "text/html",
+        lineNumbers: true
+      });
+    </script>
+    <p>The XML mode supports two configuration parameters:</p>
+    <dl>
+      <dt><code>htmlMode (boolean)</code></dt>
+      <dd>This switches the mode to parse HTML instead of XML. This
+      means attributes do not have to be quoted, and some elements
+      (such as <code>br</code>) do not require a closing tag.</dd>
+      <dt><code>alignCDATA (boolean)</code></dt>
+      <dd>Setting this to true will force the opening tag of CDATA
+      blocks to not be indented.</dd>
+    </dl>
+
+    <p><strong>MIME types defined:</strong> <code>application/xml</code>, <code>text/html</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/xml/xml.js b/app/gui/html/vendor/codemirror/mode/xml/xml.js
new file mode 100644
index 0000000..880b74d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/xml/xml.js
@@ -0,0 +1,349 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("xml", function(config, parserConfig) {
+  var indentUnit = config.indentUnit;
+  var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
+  var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag;
+  if (multilineTagIndentPastTag == null) multilineTagIndentPastTag = true;
+
+  var Kludges = parserConfig.htmlMode ? {
+    autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
+                      'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
+                      'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
+                      'track': true, 'wbr': true},
+    implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
+                       'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
+                       'th': true, 'tr': true},
+    contextGrabbers: {
+      'dd': {'dd': true, 'dt': true},
+      'dt': {'dd': true, 'dt': true},
+      'li': {'li': true},
+      'option': {'option': true, 'optgroup': true},
+      'optgroup': {'optgroup': true},
+      'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
+            'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
+            'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
+            'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
+            'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
+      'rp': {'rp': true, 'rt': true},
+      'rt': {'rp': true, 'rt': true},
+      'tbody': {'tbody': true, 'tfoot': true},
+      'td': {'td': true, 'th': true},
+      'tfoot': {'tbody': true},
+      'th': {'td': true, 'th': true},
+      'thead': {'tbody': true, 'tfoot': true},
+      'tr': {'tr': true}
+    },
+    doNotIndent: {"pre": true},
+    allowUnquoted: true,
+    allowMissing: true,
+    caseFold: true
+  } : {
+    autoSelfClosers: {},
+    implicitlyClosed: {},
+    contextGrabbers: {},
+    doNotIndent: {},
+    allowUnquoted: false,
+    allowMissing: false,
+    caseFold: false
+  };
+  var alignCDATA = parserConfig.alignCDATA;
+
+  // Return variables for tokenizers
+  var tagName, type, setStyle;
+
+  function inText(stream, state) {
+    function chain(parser) {
+      state.tokenize = parser;
+      return parser(stream, state);
+    }
+
+    var ch = stream.next();
+    if (ch == "<") {
+      if (stream.eat("!")) {
+        if (stream.eat("[")) {
+          if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
+          else return null;
+        } else if (stream.match("--")) {
+          return chain(inBlock("comment", "-->"));
+        } else if (stream.match("DOCTYPE", true, true)) {
+          stream.eatWhile(/[\w\._\-]/);
+          return chain(doctype(1));
+        } else {
+          return null;
+        }
+      } else if (stream.eat("?")) {
+        stream.eatWhile(/[\w\._\-]/);
+        state.tokenize = inBlock("meta", "?>");
+        return "meta";
+      } else {
+        var isClose = stream.eat("/");
+        tagName = "";
+        var c;
+        while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
+        if (Kludges.caseFold) tagName = tagName.toLowerCase();
+        if (!tagName) return "tag error";
+        type = isClose ? "closeTag" : "openTag";
+        state.tokenize = inTag;
+        return "tag";
+      }
+    } else if (ch == "&") {
+      var ok;
+      if (stream.eat("#")) {
+        if (stream.eat("x")) {
+          ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
+        } else {
+          ok = stream.eatWhile(/[\d]/) && stream.eat(";");
+        }
+      } else {
+        ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
+      }
+      return ok ? "atom" : "error";
+    } else {
+      stream.eatWhile(/[^&<]/);
+      return null;
+    }
+  }
+
+  function inTag(stream, state) {
+    var ch = stream.next();
+    if (ch == ">" || (ch == "/" && stream.eat(">"))) {
+      state.tokenize = inText;
+      type = ch == ">" ? "endTag" : "selfcloseTag";
+      return "tag";
+    } else if (ch == "=") {
+      type = "equals";
+      return null;
+    } else if (ch == "<") {
+      state.tokenize = inText;
+      state.state = baseState;
+      state.tagName = state.tagStart = null;
+      var next = state.tokenize(stream, state);
+      return next ? next + " error" : "error";
+    } else if (/[\'\"]/.test(ch)) {
+      state.tokenize = inAttribute(ch);
+      state.stringStartCol = stream.column();
+      return state.tokenize(stream, state);
+    } else {
+      stream.eatWhile(/[^\s\u00a0=<>\"\']/);
+      return "word";
+    }
+  }
+
+  function inAttribute(quote) {
+    var closure = function(stream, state) {
+      while (!stream.eol()) {
+        if (stream.next() == quote) {
+          state.tokenize = inTag;
+          break;
+        }
+      }
+      return "string";
+    };
+    closure.isInAttribute = true;
+    return closure;
+  }
+
+  function inBlock(style, terminator) {
+    return function(stream, state) {
+      while (!stream.eol()) {
+        if (stream.match(terminator)) {
+          state.tokenize = inText;
+          break;
+        }
+        stream.next();
+      }
+      return style;
+    };
+  }
+  function doctype(depth) {
+    return function(stream, state) {
+      var ch;
+      while ((ch = stream.next()) != null) {
+        if (ch == "<") {
+          state.tokenize = doctype(depth + 1);
+          return state.tokenize(stream, state);
+        } else if (ch == ">") {
+          if (depth == 1) {
+            state.tokenize = inText;
+            break;
+          } else {
+            state.tokenize = doctype(depth - 1);
+            return state.tokenize(stream, state);
+          }
+        }
+      }
+      return "meta";
+    };
+  }
+
+  function Context(state, tagName, startOfLine) {
+    this.prev = state.context;
+    this.tagName = tagName;
+    this.indent = state.indented;
+    this.startOfLine = startOfLine;
+    if (Kludges.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
+      this.noIndent = true;
+  }
+  function popContext(state) {
+    if (state.context) state.context = state.context.prev;
+  }
+  function maybePopContext(state, nextTagName) {
+    var parentTagName;
+    while (true) {
+      if (!state.context) {
+        return;
+      }
+      parentTagName = state.context.tagName;
+      if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
+          !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
+        return;
+      }
+      popContext(state);
+    }
+  }
+
+  function baseState(type, stream, state) {
+    if (type == "openTag") {
+      state.tagName = tagName;
+      state.tagStart = stream.column();
+      return attrState;
+    } else if (type == "closeTag") {
+      var err = false;
+      if (state.context) {
+        if (state.context.tagName != tagName) {
+          if (Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName))
+            popContext(state);
+          err = !state.context || state.context.tagName != tagName;
+        }
+      } else {
+        err = true;
+      }
+      if (err) setStyle = "error";
+      return err ? closeStateErr : closeState;
+    } else {
+      return baseState;
+    }
+  }
+
+  function closeState(type, _stream, state) {
+    if (type != "endTag") {
+      setStyle = "error";
+      return closeState;
+    }
+    popContext(state);
+    return baseState;
+  }
+  function closeStateErr(type, stream, state) {
+    setStyle = "error";
+    return closeState(type, stream, state);
+  }
+
+  function attrState(type, _stream, state) {
+    if (type == "word") {
+      setStyle = "attribute";
+      return attrEqState;
+    } else if (type == "endTag" || type == "selfcloseTag") {
+      var tagName = state.tagName, tagStart = state.tagStart;
+      state.tagName = state.tagStart = null;
+      if (type == "selfcloseTag" ||
+          Kludges.autoSelfClosers.hasOwnProperty(tagName)) {
+        maybePopContext(state, tagName);
+      } else {
+        maybePopContext(state, tagName);
+        state.context = new Context(state, tagName, tagStart == state.indented);
+      }
+      return baseState;
+    }
+    setStyle = "error";
+    return attrState;
+  }
+  function attrEqState(type, stream, state) {
+    if (type == "equals") return attrValueState;
+    if (!Kludges.allowMissing) setStyle = "error";
+    return attrState(type, stream, state);
+  }
+  function attrValueState(type, stream, state) {
+    if (type == "string") return attrContinuedState;
+    if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return attrState;}
+    setStyle = "error";
+    return attrState(type, stream, state);
+  }
+  function attrContinuedState(type, stream, state) {
+    if (type == "string") return attrContinuedState;
+    return attrState(type, stream, state);
+  }
+
+  return {
+    startState: function() {
+      return {tokenize: inText,
+              state: baseState,
+              indented: 0,
+              tagName: null, tagStart: null,
+              context: null};
+    },
+
+    token: function(stream, state) {
+      if (!state.tagName && stream.sol())
+        state.indented = stream.indentation();
+
+      if (stream.eatSpace()) return null;
+      tagName = type = null;
+      var style = state.tokenize(stream, state);
+      if ((style || type) && style != "comment") {
+        setStyle = null;
+        state.state = state.state(type || style, stream, state);
+        if (setStyle)
+          style = setStyle == "error" ? style + " error" : setStyle;
+      }
+      return style;
+    },
+
+    indent: function(state, textAfter, fullLine) {
+      var context = state.context;
+      // Indent multi-line strings (e.g. css).
+      if (state.tokenize.isInAttribute) {
+        return state.stringStartCol + 1;
+      }
+      if (context && context.noIndent) return CodeMirror.Pass;
+      if (state.tokenize != inTag && state.tokenize != inText)
+        return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
+      // Indent the starts of attribute names.
+      if (state.tagName) {
+        if (multilineTagIndentPastTag)
+          return state.tagStart + state.tagName.length + 2;
+        else
+          return state.tagStart + indentUnit * multilineTagIndentFactor;
+      }
+      if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
+      if (context && /^<\//.test(textAfter))
+        context = context.prev;
+      while (context && !context.startOfLine)
+        context = context.prev;
+      if (context) return context.indent + indentUnit;
+      else return 0;
+    },
+
+    electricChars: "/",
+    blockCommentStart: "<!--",
+    blockCommentEnd: "-->",
+
+    configuration: parserConfig.htmlMode ? "html" : "xml",
+    helperType: parserConfig.htmlMode ? "html" : "xml"
+  };
+});
+
+CodeMirror.defineMIME("text/xml", "xml");
+CodeMirror.defineMIME("application/xml", "xml");
+if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
+  CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/xquery/index.html b/app/gui/html/vendor/codemirror/mode/xquery/index.html
new file mode 100644
index 0000000..3baf5e3
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/xquery/index.html
@@ -0,0 +1,210 @@
+<!doctype html>
+
+<title>CodeMirror: XQuery mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link rel="stylesheet" href="../../theme/xq-dark.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="xquery.js"></script>
+<style type="text/css">
+	.CodeMirror {
+	  border-top: 1px solid black; border-bottom: 1px solid black;
+	  height:400px;
+	}
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">XQuery</a>
+  </ul>
+</div>
+
+<article>
+<h2>XQuery mode</h2>
+ 
+ 
+<div class="cm-s-default"> 
+	<textarea id="code" name="code"> 
+xquery version "1.0-ml";
+(: this is
+ : a 
+   "comment" :)
+let $let := <x attr="value">"test"<func>function() $var {function()} {$var}</func></x>
+let $joe:=1
+return element element {
+	attribute attribute { 1 },
+	element test { 'a' }, 
+	attribute foo { "bar" },
+	fn:doc()[ foo/@bar eq $let ],
+	//x }    
+ 
+(: a more 'evil' test :)
+(: Modified Blakeley example (: with nested comment :) ... :)
+declare private function local:declare() {()};
+declare private function local:private() {()};
+declare private function local:function() {()};
+declare private function local:local() {()};
+let $let := <let>let $let := "let"</let>
+return element element {
+	attribute attribute { try { xdmp:version() } catch($e) { xdmp:log($e) } },
+	attribute fn:doc { "bar" castable as xs:string },
+	element text { text { "text" } },
+	fn:doc()[ child::eq/(@bar | attribute::attribute) eq $let ],
+	//fn:doc
+}
+
+
+
+xquery version "1.0-ml";
+
+(: Copyright 2006-2010 Mark Logic Corporation. :)
+
+(:
+ : Licensed under the Apache License, Version 2.0 (the "License");
+ : you may not use this file except in compliance with the License.
+ : You may obtain a copy of the License at
+ :
+ :     http://www.apache.org/licenses/LICENSE-2.0
+ :
+ : Unless required by applicable law or agreed to in writing, software
+ : distributed under the License is distributed on an "AS IS" BASIS,
+ : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ : See the License for the specific language governing permissions and
+ : limitations under the License.
+ :)
+
+module namespace json = "http://marklogic.com/json";
+declare default function namespace "http://www.w3.org/2005/xpath-functions";
+
+(: Need to backslash escape any double quotes, backslashes, and newlines :)
+declare function json:escape($s as xs:string) as xs:string {
+  let $s := replace($s, "\\", "\\\\")
+  let $s := replace($s, """", "\\""")
+  let $s := replace($s, codepoints-to-string((13, 10)), "\\n")
+  let $s := replace($s, codepoints-to-string(13), "\\n")
+  let $s := replace($s, codepoints-to-string(10), "\\n")
+  return $s
+};
+
+declare function json:atomize($x as element()) as xs:string {
+  if (count($x/node()) = 0) then 'null'
+  else if ($x/@type = "number") then
+    let $castable := $x castable as xs:float or
+                     $x castable as xs:double or
+                     $x castable as xs:decimal
+    return
+    if ($castable) then xs:string($x)
+    else error(concat("Not a number: ", xdmp:describe($x)))
+  else if ($x/@type = "boolean") then
+    let $castable := $x castable as xs:boolean
+    return
+    if ($castable) then xs:string(xs:boolean($x))
+    else error(concat("Not a boolean: ", xdmp:describe($x)))
+  else concat('"', json:escape($x), '"')
+};
+
+(: Print the thing that comes after the colon :)
+declare function json:print-value($x as element()) as xs:string {
+  if (count($x/*) = 0) then
+    json:atomize($x)
+  else if ($x/@quote = "true") then
+    concat('"', json:escape(xdmp:quote($x/node())), '"')
+  else
+    string-join(('{',
+      string-join(for $i in $x/* return json:print-name-value($i), ","),
+    '}'), "")
+};
+
+(: Print the name and value both :)
+declare function json:print-name-value($x as element()) as xs:string? {
+  let $name := name($x)
+  let $first-in-array :=
+    count($x/preceding-sibling::*[name(.) = $name]) = 0 and
+    (count($x/following-sibling::*[name(.) = $name]) > 0 or $x/@array = "true")
+  let $later-in-array := count($x/preceding-sibling::*[name(.) = $name]) > 0
+  return
+
+  if ($later-in-array) then
+    ()  (: I was handled previously :)
+  else if ($first-in-array) then
+    string-join(('"', json:escape($name), '":[',
+      string-join((for $i in ($x, $x/following-sibling::*[name(.) = $name]) return json:print-value($i)), ","),
+    ']'), "")
+   else
+     string-join(('"', json:escape($name), '":', json:print-value($x)), "")
+};
+
+(:~
+  Transforms an XML element into a JSON string representation.  See http://json.org.
+  <p/>
+  Sample usage:
+  <pre>
+    xquery version "1.0-ml";
+    import module namespace json="http://marklogic.com/json" at "json.xqy";
+    json:serialize(&lt;foo&gt;&lt;bar&gt;kid&lt;/bar&gt;&lt;/foo&gt;)
+  </pre>
+  Sample transformations:
+  <pre>
+  &lt;e/&gt; becomes {"e":null}
+  &lt;e&gt;text&lt;/e&gt; becomes {"e":"text"}
+  &lt;e&gt;quote " escaping&lt;/e&gt; becomes {"e":"quote \" escaping"}
+  &lt;e&gt;backslash \ escaping&lt;/e&gt; becomes {"e":"backslash \\ escaping"}
+  &lt;e&gt;&lt;a&gt;text1&lt;/a&gt;&lt;b&gt;text2&lt;/b&gt;&lt;/e&gt; becomes {"e":{"a":"text1","b":"text2"}}
+  &lt;e&gt;&lt;a&gt;text1&lt;/a&gt;&lt;a&gt;text2&lt;/a&gt;&lt;/e&gt; becomes {"e":{"a":["text1","text2"]}}
+  &lt;e&gt;&lt;a array="true"&gt;text1&lt;/a&gt;&lt;/e&gt; becomes {"e":{"a":["text1"]}}
+  &lt;e&gt;&lt;a type="boolean"&gt;false&lt;/a&gt;&lt;/e&gt; becomes {"e":{"a":false}}
+  &lt;e&gt;&lt;a type="number"&gt;123.5&lt;/a&gt;&lt;/e&gt; becomes {"e":{"a":123.5}}
+  &lt;e quote="true"&gt;&lt;div attrib="value"/&gt;&lt;/e&gt; becomes {"e":"&lt;div attrib=\"value\"/&gt;"}
+  </pre>
+  <p/>
+  Namespace URIs are ignored.  Namespace prefixes are included in the JSON name.
+  <p/>
+  Attributes are ignored, except for the special attribute @array="true" that
+  indicates the JSON serialization should write the node, even if single, as an
+  array, and the attribute @type that can be set to "boolean" or "number" to
+  dictate the value should be written as that type (unquoted).  There's also
+  an @quote attribute that when set to true writes the inner content as text
+  rather than as structured JSON, useful for sending some XHTML over the
+  wire.
+  <p/>
+  Text nodes within mixed content are ignored.
+
+  @param $x Element node to convert
+  @return String holding JSON serialized representation of $x
+
+  @author Jason Hunter
+  @version 1.0.1
+  
+  Ported to xquery 1.0-ml; double escaped backslashes in json:escape
+:)
+declare function json:serialize($x as element())  as xs:string {
+  string-join(('{', json:print-name-value($x), '}'), "")
+};
+  </textarea> 
+</div> 
+ 
+    <script> 
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true,
+        matchBrackets: true,
+        theme: "xq-dark"
+      });
+    </script> 
+ 
+    <p><strong>MIME types defined:</strong> <code>application/xquery</code>.</p> 
+ 
+    <p>Development of the CodeMirror XQuery mode was sponsored by 
+      <a href="http://marklogic.com">MarkLogic</a> and developed by 
+      <a href="https://twitter.com/mbrevoort">Mike Brevoort</a>.
+    </p>
+ 
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/xquery/test.js b/app/gui/html/vendor/codemirror/mode/xquery/test.js
new file mode 100644
index 0000000..41719dd
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/xquery/test.js
@@ -0,0 +1,64 @@
+// Don't take these too seriously -- the expected results appear to be
+// based on the results of actual runs without any serious manual
+// verification. If a change you made causes them to fail, the test is
+// as likely to wrong as the code.
+
+(function() {
+  var mode = CodeMirror.getMode({tabSize: 4}, "xquery");
+  function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
+
+  MT("eviltest",
+     "[keyword xquery] [keyword version] [variable "1][keyword .][atom 0][keyword -][variable ml"][def&variable ;]      [comment (: this is       : a          \"comment\" :)]",
+     "      [keyword let] [variable $let] [keyword :=] [variable <x] [variable attr][keyword =][variable "value">"test"<func&gt][def&variable ;function]() [variable $var] {[keyword function]()} {[variable $var]}[variable <][keyword /][variable func><][keyword /][variable x>]",
+     "      [keyword let] [variable $joe][keyword :=][atom 1]",
+     "      [keyword return] [keyword element] [variable element] {",
+     "          [keyword attribute] [variable attribute] { [atom 1] },",
+     "          [keyword element] [variable test] { [variable 'a'] },           [keyword attribute] [variable foo] { [variable "bar"] },",
+     "          [def&variable fn:doc]()[[ [variable foo][keyword /][variable @bar] [keyword eq] [variable $let] ]],",
+     "          [keyword //][variable x] }                 [comment (: a more 'evil' test :)]",
+     "      [comment (: Modified Blakeley example (: with nested comment :) ... :)]",
+     "      [keyword declare] [keyword private] [keyword function] [def&variable local:declare]() {()}[variable ;]",
+     "      [keyword declare] [keyword private] [keyword function] [def&variable local:private]() {()}[variable ;]",
+     "      [keyword declare] [keyword private] [keyword function] [def&variable local:function]() {()}[variable ;]",
+     "      [keyword declare] [keyword private] [keyword function] [def&variable local:local]() {()}[variable ;]",
+     "      [keyword let] [variable $let] [keyword :=] [variable <let>let] [variable $let] [keyword :=] [variable "let"<][keyword /let][variable >]",
+     "      [keyword return] [keyword element] [variable element] {",
+     "          [keyword attribute] [variable attribute] { [keyword try] { [def&variable xdmp:version]() } [keyword catch]([variable $e]) { [def&variable xdmp:log]([variable $e]) } },",
+     "          [keyword attribute] [variable fn:doc] { [variable "bar"] [variable castable] [keyword as] [atom xs:string] },",
+     "          [keyword element] [variable text] { [keyword text] { [variable "text"] } },",
+     "          [def&variable fn:doc]()[[ [qualifier child::][variable eq][keyword /]([variable @bar] [keyword |] [qualifier attribute::][variable attribute]) [keyword eq] [variable $let] ]],",
+     "          [keyword //][variable fn:doc]",
+     "      }");
+
+  MT("testEmptySequenceKeyword",
+     "[string \"foo\"] [keyword instance] [keyword of] [keyword empty-sequence]()");
+
+  MT("testMultiAttr",
+     "[tag <p ][attribute a1]=[string \"foo\"] [attribute a2]=[string \"bar\"][tag >][variable hello] [variable world][tag </p>]");
+
+  MT("test namespaced variable",
+     "[keyword declare] [keyword namespace] [variable e] [keyword =] [string \"http://example.com/ANamespace\"][variable ;declare] [keyword variable] [variable $e:exampleComThisVarIsNotRecognized] [keyword as] [keyword element]([keyword *]) [variable external;]");
+
+  MT("test EQName variable",
+     "[keyword declare] [keyword variable] [variable $\"http://www.example.com/ns/my\":var] [keyword :=] [atom 12][variable ;]",
+     "[tag <out>]{[variable $\"http://www.example.com/ns/my\":var]}[tag </out>]");
+
+  MT("test EQName function",
+     "[keyword declare] [keyword function] [def&variable \"http://www.example.com/ns/my\":fn] ([variable $a] [keyword as] [atom xs:integer]) [keyword as] [atom xs:integer] {",
+     "   [variable $a] [keyword +] [atom 2]",
+     "}[variable ;]",
+     "[tag <out>]{[def&variable \"http://www.example.com/ns/my\":fn]([atom 12])}[tag </out>]");
+
+  MT("test EQName function with single quotes",
+     "[keyword declare] [keyword function] [def&variable 'http://www.example.com/ns/my':fn] ([variable $a] [keyword as] [atom xs:integer]) [keyword as] [atom xs:integer] {",
+     "   [variable $a] [keyword +] [atom 2]",
+     "}[variable ;]",
+     "[tag <out>]{[def&variable 'http://www.example.com/ns/my':fn]([atom 12])}[tag </out>]");
+
+  MT("testProcessingInstructions",
+     "[def&variable data]([comment&meta <?target content?>]) [keyword instance] [keyword of] [atom xs:string]");
+
+  MT("testQuoteEscapeDouble",
+     "[keyword let] [variable $rootfolder] [keyword :=] [string \"c:\\builds\\winnt\\HEAD\\qa\\scripts\\\"]",
+     "[keyword let] [variable $keysfolder] [keyword :=] [def&variable concat]([variable $rootfolder], [string \"keys\\\"])");
+})();
diff --git a/app/gui/html/vendor/codemirror/mode/xquery/xquery.js b/app/gui/html/vendor/codemirror/mode/xquery/xquery.js
new file mode 100644
index 0000000..2c7faf4
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/xquery/xquery.js
@@ -0,0 +1,444 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("xquery", function() {
+
+  // The keywords object is set to the result of this self executing
+  // function. Each keyword is a property of the keywords object whose
+  // value is {type: atype, style: astyle}
+  var keywords = function(){
+    // conveinence functions used to build keywords object
+    function kw(type) {return {type: type, style: "keyword"};}
+    var A = kw("keyword a")
+      , B = kw("keyword b")
+      , C = kw("keyword c")
+      , operator = kw("operator")
+      , atom = {type: "atom", style: "atom"}
+      , punctuation = {type: "punctuation", style: null}
+      , qualifier = {type: "axis_specifier", style: "qualifier"};
+
+    // kwObj is what is return from this function at the end
+    var kwObj = {
+      'if': A, 'switch': A, 'while': A, 'for': A,
+      'else': B, 'then': B, 'try': B, 'finally': B, 'catch': B,
+      'element': C, 'attribute': C, 'let': C, 'implements': C, 'import': C, 'module': C, 'namespace': C,
+      'return': C, 'super': C, 'this': C, 'throws': C, 'where': C, 'private': C,
+      ',': punctuation,
+      'null': atom, 'fn:false()': atom, 'fn:true()': atom
+    };
+
+    // a list of 'basic' keywords. For each add a property to kwObj with the value of
+    // {type: basic[i], style: "keyword"} e.g. 'after' --> {type: "after", style: "keyword"}
+    var basic = ['after','ancestor','ancestor-or-self','and','as','ascending','assert','attribute','before',
+    'by','case','cast','child','comment','declare','default','define','descendant','descendant-or-self',
+    'descending','document','document-node','element','else','eq','every','except','external','following',
+    'following-sibling','follows','for','function','if','import','in','instance','intersect','item',
+    'let','module','namespace','node','node','of','only','or','order','parent','precedes','preceding',
+    'preceding-sibling','processing-instruction','ref','return','returns','satisfies','schema','schema-element',
+    'self','some','sortby','stable','text','then','to','treat','typeswitch','union','variable','version','where',
+    'xquery', 'empty-sequence'];
+    for(var i=0, l=basic.length; i < l; i++) { kwObj[basic[i]] = kw(basic[i]);};
+
+    // a list of types. For each add a property to kwObj with the value of
+    // {type: "atom", style: "atom"}
+    var types = ['xs:string', 'xs:float', 'xs:decimal', 'xs:double', 'xs:integer', 'xs:boolean', 'xs:date', 'xs:dateTime',
+    'xs:time', 'xs:duration', 'xs:dayTimeDuration', 'xs:time', 'xs:yearMonthDuration', 'numeric', 'xs:hexBinary',
+    'xs:base64Binary', 'xs:anyURI', 'xs:QName', 'xs:byte','xs:boolean','xs:anyURI','xf:yearMonthDuration'];
+    for(var i=0, l=types.length; i < l; i++) { kwObj[types[i]] = atom;};
+
+    // each operator will add a property to kwObj with value of {type: "operator", style: "keyword"}
+    var operators = ['eq', 'ne', 'lt', 'le', 'gt', 'ge', ':=', '=', '>', '>=', '<', '<=', '.', '|', '?', 'and', 'or', 'div', 'idiv', 'mod', '*', '/', '+', '-'];
+    for(var i=0, l=operators.length; i < l; i++) { kwObj[operators[i]] = operator;};
+
+    // each axis_specifiers will add a property to kwObj with value of {type: "axis_specifier", style: "qualifier"}
+    var axis_specifiers = ["self::", "attribute::", "child::", "descendant::", "descendant-or-self::", "parent::",
+    "ancestor::", "ancestor-or-self::", "following::", "preceding::", "following-sibling::", "preceding-sibling::"];
+    for(var i=0, l=axis_specifiers.length; i < l; i++) { kwObj[axis_specifiers[i]] = qualifier; };
+
+    return kwObj;
+  }();
+
+  // Used as scratch variables to communicate multiple values without
+  // consing up tons of objects.
+  var type, content;
+
+  function ret(tp, style, cont) {
+    type = tp; content = cont;
+    return style;
+  }
+
+  function chain(stream, state, f) {
+    state.tokenize = f;
+    return f(stream, state);
+  }
+
+  // the primary mode tokenizer
+  function tokenBase(stream, state) {
+    var ch = stream.next(),
+        mightBeFunction = false,
+        isEQName = isEQNameAhead(stream);
+
+    // an XML tag (if not in some sub, chained tokenizer)
+    if (ch == "<") {
+      if(stream.match("!--", true))
+        return chain(stream, state, tokenXMLComment);
+
+      if(stream.match("![CDATA", false)) {
+        state.tokenize = tokenCDATA;
+        return ret("tag", "tag");
+      }
+
+      if(stream.match("?", false)) {
+        return chain(stream, state, tokenPreProcessing);
+      }
+
+      var isclose = stream.eat("/");
+      stream.eatSpace();
+      var tagName = "", c;
+      while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
+
+      return chain(stream, state, tokenTag(tagName, isclose));
+    }
+    // start code block
+    else if(ch == "{") {
+      pushStateStack(state,{ type: "codeblock"});
+      return ret("", null);
+    }
+    // end code block
+    else if(ch == "}") {
+      popStateStack(state);
+      return ret("", null);
+    }
+    // if we're in an XML block
+    else if(isInXmlBlock(state)) {
+      if(ch == ">")
+        return ret("tag", "tag");
+      else if(ch == "/" && stream.eat(">")) {
+        popStateStack(state);
+        return ret("tag", "tag");
+      }
+      else
+        return ret("word", "variable");
+    }
+    // if a number
+    else if (/\d/.test(ch)) {
+      stream.match(/^\d*(?:\.\d*)?(?:E[+\-]?\d+)?/);
+      return ret("number", "atom");
+    }
+    // comment start
+    else if (ch === "(" && stream.eat(":")) {
+      pushStateStack(state, { type: "comment"});
+      return chain(stream, state, tokenComment);
+    }
+    // quoted string
+    else if (  !isEQName && (ch === '"' || ch === "'"))
+      return chain(stream, state, tokenString(ch));
+    // variable
+    else if(ch === "$") {
+      return chain(stream, state, tokenVariable);
+    }
+    // assignment
+    else if(ch ===":" && stream.eat("=")) {
+      return ret("operator", "keyword");
+    }
+    // open paren
+    else if(ch === "(") {
+      pushStateStack(state, { type: "paren"});
+      return ret("", null);
+    }
+    // close paren
+    else if(ch === ")") {
+      popStateStack(state);
+      return ret("", null);
+    }
+    // open paren
+    else if(ch === "[") {
+      pushStateStack(state, { type: "bracket"});
+      return ret("", null);
+    }
+    // close paren
+    else if(ch === "]") {
+      popStateStack(state);
+      return ret("", null);
+    }
+    else {
+      var known = keywords.propertyIsEnumerable(ch) && keywords[ch];
+
+      // if there's a EQName ahead, consume the rest of the string portion, it's likely a function
+      if(isEQName && ch === '\"') while(stream.next() !== '"'){}
+      if(isEQName && ch === '\'') while(stream.next() !== '\''){}
+
+      // gobble up a word if the character is not known
+      if(!known) stream.eatWhile(/[\w\$_-]/);
+
+      // gobble a colon in the case that is a lib func type call fn:doc
+      var foundColon = stream.eat(":");
+
+      // if there's not a second colon, gobble another word. Otherwise, it's probably an axis specifier
+      // which should get matched as a keyword
+      if(!stream.eat(":") && foundColon) {
+        stream.eatWhile(/[\w\$_-]/);
+      }
+      // if the next non whitespace character is an open paren, this is probably a function (if not a keyword of other sort)
+      if(stream.match(/^[ \t]*\(/, false)) {
+        mightBeFunction = true;
+      }
+      // is the word a keyword?
+      var word = stream.current();
+      known = keywords.propertyIsEnumerable(word) && keywords[word];
+
+      // if we think it's a function call but not yet known,
+      // set style to variable for now for lack of something better
+      if(mightBeFunction && !known) known = {type: "function_call", style: "variable def"};
+
+      // if the previous word was element, attribute, axis specifier, this word should be the name of that
+      if(isInXmlConstructor(state)) {
+        popStateStack(state);
+        return ret("word", "variable", word);
+      }
+      // as previously checked, if the word is element,attribute, axis specifier, call it an "xmlconstructor" and
+      // push the stack so we know to look for it on the next word
+      if(word == "element" || word == "attribute" || known.type == "axis_specifier") pushStateStack(state, {type: "xmlconstructor"});
+
+      // if the word is known, return the details of that else just call this a generic 'word'
+      return known ? ret(known.type, known.style, word) :
+                     ret("word", "variable", word);
+    }
+  }
+
+  // handle comments, including nested
+  function tokenComment(stream, state) {
+    var maybeEnd = false, maybeNested = false, nestedCount = 0, ch;
+    while (ch = stream.next()) {
+      if (ch == ")" && maybeEnd) {
+        if(nestedCount > 0)
+          nestedCount--;
+        else {
+          popStateStack(state);
+          break;
+        }
+      }
+      else if(ch == ":" && maybeNested) {
+        nestedCount++;
+      }
+      maybeEnd = (ch == ":");
+      maybeNested = (ch == "(");
+    }
+
+    return ret("comment", "comment");
+  }
+
+  // tokenizer for string literals
+  // optionally pass a tokenizer function to set state.tokenize back to when finished
+  function tokenString(quote, f) {
+    return function(stream, state) {
+      var ch;
+
+      if(isInString(state) && stream.current() == quote) {
+        popStateStack(state);
+        if(f) state.tokenize = f;
+        return ret("string", "string");
+      }
+
+      pushStateStack(state, { type: "string", name: quote, tokenize: tokenString(quote, f) });
+
+      // if we're in a string and in an XML block, allow an embedded code block
+      if(stream.match("{", false) && isInXmlAttributeBlock(state)) {
+        state.tokenize = tokenBase;
+        return ret("string", "string");
+      }
+
+
+      while (ch = stream.next()) {
+        if (ch ==  quote) {
+          popStateStack(state);
+          if(f) state.tokenize = f;
+          break;
+        }
+        else {
+          // if we're in a string and in an XML block, allow an embedded code block in an attribute
+          if(stream.match("{", false) && isInXmlAttributeBlock(state)) {
+            state.tokenize = tokenBase;
+            return ret("string", "string");
+          }
+
+        }
+      }
+
+      return ret("string", "string");
+    };
+  }
+
+  // tokenizer for variables
+  function tokenVariable(stream, state) {
+    var isVariableChar = /[\w\$_-]/;
+
+    // a variable may start with a quoted EQName so if the next character is quote, consume to the next quote
+    if(stream.eat("\"")) {
+      while(stream.next() !== '\"'){};
+      stream.eat(":");
+    } else {
+      stream.eatWhile(isVariableChar);
+      if(!stream.match(":=", false)) stream.eat(":");
+    }
+    stream.eatWhile(isVariableChar);
+    state.tokenize = tokenBase;
+    return ret("variable", "variable");
+  }
+
+  // tokenizer for XML tags
+  function tokenTag(name, isclose) {
+    return function(stream, state) {
+      stream.eatSpace();
+      if(isclose && stream.eat(">")) {
+        popStateStack(state);
+        state.tokenize = tokenBase;
+        return ret("tag", "tag");
+      }
+      // self closing tag without attributes?
+      if(!stream.eat("/"))
+        pushStateStack(state, { type: "tag", name: name, tokenize: tokenBase});
+      if(!stream.eat(">")) {
+        state.tokenize = tokenAttribute;
+        return ret("tag", "tag");
+      }
+      else {
+        state.tokenize = tokenBase;
+      }
+      return ret("tag", "tag");
+    };
+  }
+
+  // tokenizer for XML attributes
+  function tokenAttribute(stream, state) {
+    var ch = stream.next();
+
+    if(ch == "/" && stream.eat(">")) {
+      if(isInXmlAttributeBlock(state)) popStateStack(state);
+      if(isInXmlBlock(state)) popStateStack(state);
+      return ret("tag", "tag");
+    }
+    if(ch == ">") {
+      if(isInXmlAttributeBlock(state)) popStateStack(state);
+      return ret("tag", "tag");
+    }
+    if(ch == "=")
+      return ret("", null);
+    // quoted string
+    if (ch == '"' || ch == "'")
+      return chain(stream, state, tokenString(ch, tokenAttribute));
+
+    if(!isInXmlAttributeBlock(state))
+      pushStateStack(state, { type: "attribute", tokenize: tokenAttribute});
+
+    stream.eat(/[a-zA-Z_:]/);
+    stream.eatWhile(/[-a-zA-Z0-9_:.]/);
+    stream.eatSpace();
+
+    // the case where the attribute has not value and the tag was closed
+    if(stream.match(">", false) || stream.match("/", false)) {
+      popStateStack(state);
+      state.tokenize = tokenBase;
+    }
+
+    return ret("attribute", "attribute");
+  }
+
+  // handle comments, including nested
+  function tokenXMLComment(stream, state) {
+    var ch;
+    while (ch = stream.next()) {
+      if (ch == "-" && stream.match("->", true)) {
+        state.tokenize = tokenBase;
+        return ret("comment", "comment");
+      }
+    }
+  }
+
+
+  // handle CDATA
+  function tokenCDATA(stream, state) {
+    var ch;
+    while (ch = stream.next()) {
+      if (ch == "]" && stream.match("]", true)) {
+        state.tokenize = tokenBase;
+        return ret("comment", "comment");
+      }
+    }
+  }
+
+  // handle preprocessing instructions
+  function tokenPreProcessing(stream, state) {
+    var ch;
+    while (ch = stream.next()) {
+      if (ch == "?" && stream.match(">", true)) {
+        state.tokenize = tokenBase;
+        return ret("comment", "comment meta");
+      }
+    }
+  }
+
+
+  // functions to test the current context of the state
+  function isInXmlBlock(state) { return isIn(state, "tag"); }
+  function isInXmlAttributeBlock(state) { return isIn(state, "attribute"); }
+  function isInXmlConstructor(state) { return isIn(state, "xmlconstructor"); }
+  function isInString(state) { return isIn(state, "string"); }
+
+  function isEQNameAhead(stream) {
+    // assume we've already eaten a quote (")
+    if(stream.current() === '"')
+      return stream.match(/^[^\"]+\"\:/, false);
+    else if(stream.current() === '\'')
+      return stream.match(/^[^\"]+\'\:/, false);
+    else
+      return false;
+  }
+
+  function isIn(state, type) {
+    return (state.stack.length && state.stack[state.stack.length - 1].type == type);
+  }
+
+  function pushStateStack(state, newState) {
+    state.stack.push(newState);
+  }
+
+  function popStateStack(state) {
+    state.stack.pop();
+    var reinstateTokenize = state.stack.length && state.stack[state.stack.length-1].tokenize;
+    state.tokenize = reinstateTokenize || tokenBase;
+  }
+
+  // the interface for the mode API
+  return {
+    startState: function() {
+      return {
+        tokenize: tokenBase,
+        cc: [],
+        stack: []
+      };
+    },
+
+    token: function(stream, state) {
+      if (stream.eatSpace()) return null;
+      var style = state.tokenize(stream, state);
+      return style;
+    },
+
+    blockCommentStart: "(:",
+    blockCommentEnd: ":)"
+
+  };
+
+});
+
+CodeMirror.defineMIME("application/xquery", "xquery");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/yaml/index.html b/app/gui/html/vendor/codemirror/mode/yaml/index.html
new file mode 100644
index 0000000..bbb40a3
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/yaml/index.html
@@ -0,0 +1,80 @@
+<!doctype html>
+
+<title>CodeMirror: YAML mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="yaml.js"></script>
+<style>.CodeMirror { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; }</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">YAML</a>
+  </ul>
+</div>
+
+<article>
+<h2>YAML mode</h2>
+<form><textarea id="code" name="code">
+--- # Favorite movies
+- Casablanca
+- North by Northwest
+- The Man Who Wasn't There
+--- # Shopping list
+[milk, pumpkin pie, eggs, juice]
+--- # Indented Blocks, common in YAML data files, use indentation and new lines to separate the key: value pairs
+  name: John Smith
+  age: 33
+--- # Inline Blocks, common in YAML data streams, use commas to separate the key: value pairs between braces
+{name: John Smith, age: 33}
+---
+receipt:     Oz-Ware Purchase Invoice
+date:        2007-08-06
+customer:
+    given:   Dorothy
+    family:  Gale
+
+items:
+    - part_no:   A4786
+      descrip:   Water Bucket (Filled)
+      price:     1.47
+      quantity:  4
+
+    - part_no:   E1628
+      descrip:   High Heeled "Ruby" Slippers
+      size:       8
+      price:     100.27
+      quantity:  1
+
+bill-to:  &id001
+    street: |
+            123 Tornado Alley
+            Suite 16
+    city:   East Centerville
+    state:  KS
+
+ship-to:  *id001
+
+specialDelivery:  >
+    Follow the Yellow Brick
+    Road to the Emerald City.
+    Pay no attention to the
+    man behind the curtain.
+...
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-yaml</code>.</p>
+
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/yaml/yaml.js b/app/gui/html/vendor/codemirror/mode/yaml/yaml.js
new file mode 100644
index 0000000..f7b3a90
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/yaml/yaml.js
@@ -0,0 +1,109 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("yaml", function() {
+
+  var cons = ['true', 'false', 'on', 'off', 'yes', 'no'];
+  var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))$", 'i');
+
+  return {
+    token: function(stream, state) {
+      var ch = stream.peek();
+      var esc = state.escaped;
+      state.escaped = false;
+      /* comments */
+      if (ch == "#" && (stream.pos == 0 || /\s/.test(stream.string.charAt(stream.pos - 1)))) {
+        stream.skipToEnd(); return "comment";
+      }
+      if (state.literal && stream.indentation() > state.keyCol) {
+        stream.skipToEnd(); return "string";
+      } else if (state.literal) { state.literal = false; }
+      if (stream.sol()) {
+        state.keyCol = 0;
+        state.pair = false;
+        state.pairStart = false;
+        /* document start */
+        if(stream.match(/---/)) { return "def"; }
+        /* document end */
+        if (stream.match(/\.\.\./)) { return "def"; }
+        /* array list item */
+        if (stream.match(/\s*-\s+/)) { return 'meta'; }
+      }
+      /* inline pairs/lists */
+      if (stream.match(/^(\{|\}|\[|\])/)) {
+        if (ch == '{')
+          state.inlinePairs++;
+        else if (ch == '}')
+          state.inlinePairs--;
+        else if (ch == '[')
+          state.inlineList++;
+        else
+          state.inlineList--;
+        return 'meta';
+      }
+
+      /* list seperator */
+      if (state.inlineList > 0 && !esc && ch == ',') {
+        stream.next();
+        return 'meta';
+      }
+      /* pairs seperator */
+      if (state.inlinePairs > 0 && !esc && ch == ',') {
+        state.keyCol = 0;
+        state.pair = false;
+        state.pairStart = false;
+        stream.next();
+        return 'meta';
+      }
+
+      /* start of value of a pair */
+      if (state.pairStart) {
+        /* block literals */
+        if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return 'meta'; };
+        /* references */
+        if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return 'variable-2'; }
+        /* numbers */
+        if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return 'number'; }
+        if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return 'number'; }
+        /* keywords */
+        if (stream.match(keywordRegex)) { return 'keyword'; }
+      }
+
+      /* pairs (associative arrays) -> key */
+      if (!state.pair && stream.match(/^\s*\S+(?=\s*:($|\s))/i)) {
+        state.pair = true;
+        state.keyCol = stream.indentation();
+        return "atom";
+      }
+      if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return 'meta'; }
+
+      /* nothing found, continue */
+      state.pairStart = false;
+      state.escaped = (ch == '\\');
+      stream.next();
+      return null;
+    },
+    startState: function() {
+      return {
+        pair: false,
+        pairStart: false,
+        keyCol: 0,
+        inlinePairs: 0,
+        inlineList: 0,
+        literal: false,
+        escaped: false
+      };
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/x-yaml", "yaml");
+
+});
diff --git a/app/gui/html/vendor/codemirror/mode/z80/index.html b/app/gui/html/vendor/codemirror/mode/z80/index.html
new file mode 100644
index 0000000..b63c962
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/z80/index.html
@@ -0,0 +1,52 @@
+<!doctype html>
+
+<title>CodeMirror: Z80 assembly mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="z80.js"></script>
+<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Z80 assembly</a>
+  </ul>
+</div>
+
+<article>
+<h2>Z80 assembly mode</h2>
+
+
+<div><textarea id="code" name="code">
+#include    "ti83plus.inc"
+#define     progStart   $9D95
+.org        progStart-2
+.db         $BB,$6D
+    bcall(_ClrLCDFull)
+    ld  HL, 0
+    ld  (PenCol),   HL
+    ld  HL, Message
+    bcall(_PutS) ; Displays the string
+    bcall(_NewLine)
+    ret
+Message:
+.db         "Hello world!",0
+</textarea></div>
+
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        lineNumbers: true
+      });
+    </script>
+
+    <p><strong>MIME type defined:</strong> <code>text/x-z80</code>.</p>
+  </article>
diff --git a/app/gui/html/vendor/codemirror/mode/z80/z80.js b/app/gui/html/vendor/codemirror/mode/z80/z80.js
new file mode 100644
index 0000000..c778803
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/mode/z80/z80.js
@@ -0,0 +1,97 @@
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode('z80', function() {
+  var keywords1 = /^(exx?|(ld|cp|in)([di]r?)?|pop|push|ad[cd]|cpl|daa|dec|inc|neg|sbc|sub|and|bit|[cs]cf|x?or|res|set|r[lr]c?a?|r[lr]d|s[lr]a|srl|djnz|nop|rst|[de]i|halt|im|ot[di]r|out[di]?)\b/i;
+  var keywords2 = /^(call|j[pr]|ret[in]?)\b/i;
+  var keywords3 = /^b_?(call|jump)\b/i;
+  var variables1 = /^(af?|bc?|c|de?|e|hl?|l|i[xy]?|r|sp)\b/i;
+  var variables2 = /^(n?[zc]|p[oe]?|m)\b/i;
+  var errors = /^([hl][xy]|i[xy][hl]|slia|sll)\b/i;
+  var numbers = /^([\da-f]+h|[0-7]+o|[01]+b|\d+)\b/i;
+
+  return {
+    startState: function() {
+      return {context: 0};
+    },
+    token: function(stream, state) {
+      if (!stream.column())
+        state.context = 0;
+
+      if (stream.eatSpace())
+        return null;
+
+      var w;
+
+      if (stream.eatWhile(/\w/)) {
+        w = stream.current();
+
+        if (stream.indentation()) {
+          if (state.context == 1 && variables1.test(w))
+            return 'variable-2';
+
+          if (state.context == 2 && variables2.test(w))
+            return 'variable-3';
+
+          if (keywords1.test(w)) {
+            state.context = 1;
+            return 'keyword';
+          } else if (keywords2.test(w)) {
+            state.context = 2;
+            return 'keyword';
+          } else if (keywords3.test(w)) {
+            state.context = 3;
+            return 'keyword';
+          }
+
+          if (errors.test(w))
+            return 'error';
+        } else if (numbers.test(w)) {
+          return 'number';
+        } else {
+          return null;
+        }
+      } else if (stream.eat(';')) {
+        stream.skipToEnd();
+        return 'comment';
+      } else if (stream.eat('"')) {
+        while (w = stream.next()) {
+          if (w == '"')
+            break;
+
+          if (w == '\\')
+            stream.next();
+        }
+        return 'string';
+      } else if (stream.eat('\'')) {
+        if (stream.match(/\\?.'/))
+          return 'number';
+      } else if (stream.eat('.') || stream.sol() && stream.eat('#')) {
+        state.context = 4;
+
+        if (stream.eatWhile(/\w/))
+          return 'def';
+      } else if (stream.eat('$')) {
+        if (stream.eatWhile(/[\da-f]/i))
+          return 'number';
+      } else if (stream.eat('%')) {
+        if (stream.eatWhile(/[01]/))
+          return 'number';
+      } else {
+        stream.next();
+      }
+      return null;
+    }
+  };
+});
+
+CodeMirror.defineMIME("text/x-z80", "z80");
+
+});
diff --git a/app/gui/html/vendor/codemirror/package.json b/app/gui/html/vendor/codemirror/package.json
new file mode 100644
index 0000000..496581b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/package.json
@@ -0,0 +1,20 @@
+{
+    "name": "codemirror",
+    "version":"4.0.3",
+    "main": "lib/codemirror.js",
+    "description": "In-browser code editing made bearable",
+    "licenses": [{"type": "MIT",
+                  "url": "http://codemirror.net/LICENSE"}],
+    "directories": {"lib": "./lib"},
+    "scripts": {"test": "node ./test/run.js"},
+    "devDependencies": {"node-static": "0.6.0",
+                        "phantomjs": "1.9.2-5"},
+    "bugs": "http://github.com/marijnh/CodeMirror/issues",
+    "keywords": ["JavaScript", "CodeMirror", "Editor"],
+    "homepage": "http://codemirror.net",
+    "maintainers":[{"name": "Marijn Haverbeke",
+                    "email": "marijnh at gmail.com",
+                    "web": "http://marijnhaverbeke.nl"}],
+    "repository": {"type": "git",
+                   "url": "https://github.com/marijnh/CodeMirror.git"}
+}
diff --git a/app/gui/html/vendor/codemirror/test/comment_test.js b/app/gui/html/vendor/codemirror/test/comment_test.js
new file mode 100644
index 0000000..d8ff2c8
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/comment_test.js
@@ -0,0 +1,63 @@
+namespace = "comment_";
+
+(function() {
+  function test(name, mode, run, before, after) {
+    return testCM(name, function(cm) {
+      run(cm);
+      eq(cm.getValue(), after);
+    }, {value: before, mode: mode});
+  }
+
+  var simpleProg = "function foo() {\n  return bar;\n}";
+
+  test("block", "javascript", function(cm) {
+    cm.blockComment(Pos(0, 3), Pos(3, 0), {blockCommentLead: " *"});
+  }, simpleProg + "\n", "/* function foo() {\n *   return bar;\n * }\n */");
+
+  test("blockToggle", "javascript", function(cm) {
+    cm.blockComment(Pos(0, 3), Pos(2, 0), {blockCommentLead: " *"});
+    cm.uncomment(Pos(0, 3), Pos(2, 0), {blockCommentLead: " *"});
+  }, simpleProg, simpleProg);
+
+  test("line", "javascript", function(cm) {
+    cm.lineComment(Pos(1, 1), Pos(1, 1));
+  }, simpleProg, "function foo() {\n//   return bar;\n}");
+
+  test("lineToggle", "javascript", function(cm) {
+    cm.lineComment(Pos(0, 0), Pos(2, 1));
+    cm.uncomment(Pos(0, 0), Pos(2, 1));
+  }, simpleProg, simpleProg);
+
+  test("fallbackToBlock", "css", function(cm) {
+    cm.lineComment(Pos(0, 0), Pos(2, 1));
+  }, "html {\n  border: none;\n}", "/* html {\n  border: none;\n} */");
+
+  test("fallbackToLine", "ruby", function(cm) {
+    cm.blockComment(Pos(0, 0), Pos(1));
+  }, "def blah()\n  return hah\n", "# def blah()\n#   return hah\n");
+
+  test("commentRange", "javascript", function(cm) {
+    cm.blockComment(Pos(1, 2), Pos(1, 13), {fullLines: false});
+  }, simpleProg, "function foo() {\n  /*return bar;*/\n}");
+
+  test("indented", "javascript", function(cm) {
+    cm.lineComment(Pos(1, 0), Pos(2), {indent: true});
+  }, simpleProg, "function foo() {\n  // return bar;\n  // }");
+
+  test("singleEmptyLine", "javascript", function(cm) {
+    cm.setCursor(1);
+    cm.execCommand("toggleComment");
+  }, "a;\n\nb;", "a;\n// \nb;");
+
+  test("dontMessWithStrings", "javascript", function(cm) {
+    cm.execCommand("toggleComment");
+  }, "console.log(\"/*string*/\");", "// console.log(\"/*string*/\");");
+
+  test("dontMessWithStrings2", "javascript", function(cm) {
+    cm.execCommand("toggleComment");
+  }, "console.log(\"// string\");", "// console.log(\"// string\");");
+
+  test("dontMessWithStrings3", "javascript", function(cm) {
+    cm.execCommand("toggleComment");
+  }, "// console.log(\"// string\");", "console.log(\"// string\");");
+})();
diff --git a/app/gui/html/vendor/codemirror/test/doc_test.js b/app/gui/html/vendor/codemirror/test/doc_test.js
new file mode 100644
index 0000000..ab0350e
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/doc_test.js
@@ -0,0 +1,348 @@
+(function() {
+  // A minilanguage for instantiating linked CodeMirror instances and Docs
+  function instantiateSpec(spec, place, opts) {
+    var names = {}, pos = 0, l = spec.length, editors = [];
+    while (spec) {
+      var m = spec.match(/^(\w+)(\*?)(?:='([^\']*)'|<(~?)(\w+)(?:\/(\d+)-(\d+))?)\s*/);
+      var name = m[1], isDoc = m[2], cur;
+      if (m[3]) {
+        cur = isDoc ? CodeMirror.Doc(m[3]) : CodeMirror(place, clone(opts, {value: m[3]}));
+      } else {
+        var other = m[5];
+        if (!names.hasOwnProperty(other)) {
+          names[other] = editors.length;
+          editors.push(CodeMirror(place, opts));
+        }
+        var doc = editors[names[other]].linkedDoc({
+          sharedHist: !m[4],
+          from: m[6] ? Number(m[6]) : null,
+          to: m[7] ? Number(m[7]) : null
+        });
+        cur = isDoc ? doc : CodeMirror(place, clone(opts, {value: doc}));
+      }
+      names[name] = editors.length;
+      editors.push(cur);
+      spec = spec.slice(m[0].length);
+    }
+    return editors;
+  }
+
+  function clone(obj, props) {
+    if (!obj) return;
+    clone.prototype = obj;
+    var inst = new clone();
+    if (props) for (var n in props) if (props.hasOwnProperty(n))
+      inst[n] = props[n];
+    return inst;
+  }
+
+  function eqAll(val) {
+    var end = arguments.length, msg = null;
+    if (typeof arguments[end-1] == "string")
+      msg = arguments[--end];
+    if (i == end) throw new Error("No editors provided to eqAll");
+    for (var i = 1; i < end; ++i)
+      eq(arguments[i].getValue(), val, msg)
+  }
+
+  function testDoc(name, spec, run, opts, expectFail) {
+    if (!opts) opts = {};
+
+    return test("doc_" + name, function() {
+      var place = document.getElementById("testground");
+      var editors = instantiateSpec(spec, place, opts);
+      var successful = false;
+
+      try {
+        run.apply(null, editors);
+        successful = true;
+      } finally {
+        if (!successful || verbose) {
+          place.style.visibility = "visible";
+        } else {
+          for (var i = 0; i < editors.length; ++i)
+            if (editors[i] instanceof CodeMirror)
+              place.removeChild(editors[i].getWrapperElement());
+        }
+      }
+    }, expectFail);
+  }
+
+  var ie_lt8 = /MSIE [1-7]\b/.test(navigator.userAgent);
+
+  function testBasic(a, b) {
+    eqAll("x", a, b);
+    a.setValue("hey");
+    eqAll("hey", a, b);
+    b.setValue("wow");
+    eqAll("wow", a, b);
+    a.replaceRange("u\nv\nw", Pos(0, 3));
+    b.replaceRange("i", Pos(0, 4));
+    b.replaceRange("j", Pos(2, 1));
+    eqAll("wowui\nv\nwj", a, b);
+  }
+
+  testDoc("basic", "A='x' B<A", testBasic);
+  testDoc("basicSeparate", "A='x' B<~A", testBasic);
+
+  testDoc("sharedHist", "A='ab\ncd\nef' B<A", function(a, b) {
+    a.replaceRange("x", Pos(0));
+    b.replaceRange("y", Pos(1));
+    a.replaceRange("z", Pos(2));
+    eqAll("abx\ncdy\nefz", a, b);
+    a.undo();
+    a.undo();
+    eqAll("abx\ncd\nef", a, b);
+    a.redo();
+    eqAll("abx\ncdy\nef", a, b);
+    b.redo();
+    eqAll("abx\ncdy\nefz", a, b);
+    a.undo(); b.undo(); a.undo(); a.undo();
+    eqAll("ab\ncd\nef", a, b);
+  }, null, ie_lt8);
+
+  testDoc("undoIntact", "A='ab\ncd\nef' B<~A", function(a, b) {
+    a.replaceRange("x", Pos(0));
+    b.replaceRange("y", Pos(1));
+    a.replaceRange("z", Pos(2));
+    a.replaceRange("q", Pos(0));
+    eqAll("abxq\ncdy\nefz", a, b);
+    a.undo();
+    a.undo();
+    eqAll("abx\ncdy\nef", a, b);
+    b.undo();
+    eqAll("abx\ncd\nef", a, b);
+    a.redo();
+    eqAll("abx\ncd\nefz", a, b);
+    a.redo();
+    eqAll("abxq\ncd\nefz", a, b);
+    a.undo(); a.undo(); a.undo(); a.undo();
+    eqAll("ab\ncd\nef", a, b);
+    b.redo();
+    eqAll("ab\ncdy\nef", a, b);
+  });
+
+  testDoc("undoConflict", "A='ab\ncd\nef' B<~A", function(a, b) {
+    a.replaceRange("x", Pos(0));
+    a.replaceRange("z", Pos(2));
+    // This should clear the first undo event in a, but not the second
+    b.replaceRange("y", Pos(0));
+    a.undo(); a.undo();
+    eqAll("abxy\ncd\nef", a, b);
+    a.replaceRange("u", Pos(2));
+    a.replaceRange("v", Pos(0));
+    // This should clear both events in a
+    b.replaceRange("w", Pos(0));
+    a.undo(); a.undo();
+    eqAll("abxyvw\ncd\nefu", a, b);
+  });
+
+  testDoc("doubleRebase", "A='ab\ncd\nef\ng' B<~A C<B", function(a, b, c) {
+    c.replaceRange("u", Pos(3));
+    a.replaceRange("", Pos(0, 0), Pos(1, 0));
+    c.undo();
+    eqAll("cd\nef\ng", a, b, c);
+  });
+
+  testDoc("undoUpdate", "A='ab\ncd\nef' B<~A", function(a, b) {
+    a.replaceRange("x", Pos(2));
+    b.replaceRange("u\nv\nw\n", Pos(0, 0));
+    a.undo();
+    eqAll("u\nv\nw\nab\ncd\nef", a, b);
+    a.redo();
+    eqAll("u\nv\nw\nab\ncd\nefx", a, b);
+    a.undo();
+    eqAll("u\nv\nw\nab\ncd\nef", a, b);
+    b.undo();
+    a.redo();
+    eqAll("ab\ncd\nefx", a, b);
+    a.undo();
+    eqAll("ab\ncd\nef", a, b);
+  });
+
+  testDoc("undoKeepRanges", "A='abcdefg' B<A", function(a, b) {
+    var m = a.markText(Pos(0, 1), Pos(0, 3), {className: "foo"});
+    b.replaceRange("x", Pos(0, 0));
+    eqPos(m.find().from, Pos(0, 2));
+    b.replaceRange("yzzy", Pos(0, 1), Pos(0));
+    eq(m.find(), null);
+    b.undo();
+    eqPos(m.find().from, Pos(0, 2));
+    b.undo();
+    eqPos(m.find().from, Pos(0, 1));
+  });
+
+  testDoc("longChain", "A='uv' B<A C<B D<C", function(a, b, c, d) {
+    a.replaceSelection("X");
+    eqAll("Xuv", a, b, c, d);
+    d.replaceRange("Y", Pos(0));
+    eqAll("XuvY", a, b, c, d);
+  });
+
+  testDoc("broadCast", "B<A C<A D<A E<A", function(a, b, c, d, e) {
+    b.setValue("uu");
+    eqAll("uu", a, b, c, d, e);
+    a.replaceRange("v", Pos(0, 1));
+    eqAll("uvu", a, b, c, d, e);
+  });
+
+  // A and B share a history, C and D share a separate one
+  testDoc("islands", "A='x\ny\nz' B<A C<~A D<C", function(a, b, c, d) {
+    a.replaceRange("u", Pos(0));
+    d.replaceRange("v", Pos(2));
+    b.undo();
+    eqAll("x\ny\nzv", a, b, c, d);
+    c.undo();
+    eqAll("x\ny\nz", a, b, c, d);
+    a.redo();
+    eqAll("xu\ny\nz", a, b, c, d);
+    d.redo();
+    eqAll("xu\ny\nzv", a, b, c, d);
+  });
+
+  testDoc("unlink", "B<A C<A D<B", function(a, b, c, d) {
+    a.setValue("hi");
+    b.unlinkDoc(a);
+    d.setValue("aye");
+    eqAll("hi", a, c);
+    eqAll("aye", b, d);
+    a.setValue("oo");
+    eqAll("oo", a, c);
+    eqAll("aye", b, d);
+  });
+
+  testDoc("bareDoc", "A*='foo' B*<A C<B", function(a, b, c) {
+    is(a instanceof CodeMirror.Doc);
+    is(b instanceof CodeMirror.Doc);
+    is(c instanceof CodeMirror);
+    eqAll("foo", a, b, c);
+    a.replaceRange("hey", Pos(0, 0), Pos(0));
+    c.replaceRange("!", Pos(0));
+    eqAll("hey!", a, b, c);
+    b.unlinkDoc(a);
+    b.setValue("x");
+    eqAll("x", b, c);
+    eqAll("hey!", a);
+  });
+
+  testDoc("swapDoc", "A='a' B*='b' C<A", function(a, b, c) {
+    var d = a.swapDoc(b);
+    d.setValue("x");
+    eqAll("x", c, d);
+    eqAll("b", a, b);
+  });
+
+  testDoc("docKeepsScroll", "A='x' B*='y'", function(a, b) {
+    addDoc(a, 200, 200);
+    a.scrollIntoView(Pos(199, 200));
+    var c = a.swapDoc(b);
+    a.swapDoc(c);
+    var pos = a.getScrollInfo();
+    is(pos.left > 0, "not at left");
+    is(pos.top > 0, "not at top");
+  });
+
+  testDoc("copyDoc", "A='u'", function(a) {
+    var copy = a.getDoc().copy(true);
+    a.setValue("foo");
+    copy.setValue("bar");
+    var old = a.swapDoc(copy);
+    eq(a.getValue(), "bar");
+    a.undo();
+    eq(a.getValue(), "u");
+    a.swapDoc(old);
+    eq(a.getValue(), "foo");
+    eq(old.historySize().undo, 1);
+    eq(old.copy(false).historySize().undo, 0);
+  });
+
+  testDoc("docKeepsMode", "A='1+1'", function(a) {
+    var other = CodeMirror.Doc("hi", "text/x-markdown");
+    a.setOption("mode", "text/javascript");
+    var old = a.swapDoc(other);
+    eq(a.getOption("mode"), "text/x-markdown");
+    eq(a.getMode().name, "markdown");
+    a.swapDoc(old);
+    eq(a.getOption("mode"), "text/javascript");
+    eq(a.getMode().name, "javascript");
+  });
+
+  testDoc("subview", "A='1\n2\n3\n4\n5' B<~A/1-3", function(a, b) {
+    eq(b.getValue(), "2\n3");
+    eq(b.firstLine(), 1);
+    b.setCursor(Pos(4));
+    eqPos(b.getCursor(), Pos(2, 1));
+    a.replaceRange("-1\n0\n", Pos(0, 0));
+    eq(b.firstLine(), 3);
+    eqPos(b.getCursor(), Pos(4, 1));
+    a.undo();
+    eqPos(b.getCursor(), Pos(2, 1));
+    b.replaceRange("oyoy\n", Pos(2, 0));
+    eq(a.getValue(), "1\n2\noyoy\n3\n4\n5");
+    b.undo();
+    eq(a.getValue(), "1\n2\n3\n4\n5");
+  });
+
+  testDoc("subviewEditOnBoundary", "A='11\n22\n33\n44\n55' B<~A/1-4", function(a, b) {
+    a.replaceRange("x\nyy\nz", Pos(0, 1), Pos(2, 1));
+    eq(b.firstLine(), 2);
+    eq(b.lineCount(), 2);
+    eq(b.getValue(), "z3\n44");
+    a.replaceRange("q\nrr\ns", Pos(3, 1), Pos(4, 1));
+    eq(b.firstLine(), 2);
+    eq(b.getValue(), "z3\n4q");
+    eq(a.getValue(), "1x\nyy\nz3\n4q\nrr\ns5");
+    a.execCommand("selectAll");
+    a.replaceSelection("!");
+    eqAll("!", a, b);
+  });
+
+
+  testDoc("sharedMarker", "A='ab\ncd\nef\ngh' B<A C<~A/1-2", function(a, b, c) {
+    var mark = b.markText(Pos(0, 1), Pos(3, 1),
+                          {className: "cm-searching", shared: true});
+    var found = a.findMarksAt(Pos(0, 2));
+    eq(found.length, 1);
+    eq(found[0], mark);
+    eq(c.findMarksAt(Pos(1, 1)).length, 1);
+    eqPos(mark.find().from, Pos(0, 1));
+    eqPos(mark.find().to, Pos(3, 1));
+    b.replaceRange("x\ny\n", Pos(0, 0));
+    eqPos(mark.find().from, Pos(2, 1));
+    eqPos(mark.find().to, Pos(5, 1));
+    var cleared = 0;
+    CodeMirror.on(mark, "clear", function() {++cleared;});
+    b.operation(function(){mark.clear();});
+    eq(a.findMarksAt(Pos(3, 1)).length, 0);
+    eq(b.findMarksAt(Pos(3, 1)).length, 0);
+    eq(c.findMarksAt(Pos(3, 1)).length, 0);
+    eq(mark.find(), null);
+    eq(cleared, 1);
+  });
+
+  testDoc("sharedBookmark", "A='ab\ncd\nef\ngh' B<A C<~A/1-2", function(a, b, c) {
+    var mark = b.setBookmark(Pos(1, 1), {shared: true});
+    var found = a.findMarksAt(Pos(1, 1));
+    eq(found.length, 1);
+    eq(found[0], mark);
+    eq(c.findMarksAt(Pos(1, 1)).length, 1);
+    eqPos(mark.find(), Pos(1, 1));
+    b.replaceRange("x\ny\n", Pos(0, 0));
+    eqPos(mark.find(), Pos(3, 1));
+    var cleared = 0;
+    CodeMirror.on(mark, "clear", function() {++cleared;});
+    b.operation(function() {mark.clear();});
+    eq(a.findMarks(Pos(0, 0), Pos(5)).length, 0);
+    eq(b.findMarks(Pos(0, 0), Pos(5)).length, 0);
+    eq(c.findMarks(Pos(0, 0), Pos(5)).length, 0);
+    eq(mark.find(), null);
+    eq(cleared, 1);
+  });
+
+  testDoc("undoInSubview", "A='line 0\nline 1\nline 2\nline 3\nline 4' B<A/1-4", function(a, b) {
+    b.replaceRange("x", Pos(2, 0));
+    a.undo();
+    eq(a.getValue(), "line 0\nline 1\nline 2\nline 3\nline 4");
+    eq(b.getValue(), "line 1\nline 2\nline 3");
+  });
+})();
diff --git a/app/gui/html/vendor/codemirror/test/driver.js b/app/gui/html/vendor/codemirror/test/driver.js
new file mode 100644
index 0000000..be013a7
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/driver.js
@@ -0,0 +1,138 @@
+var tests = [], filters = [], allNames = [];
+
+function Failure(why) {this.message = why;}
+Failure.prototype.toString = function() { return this.message; };
+
+function indexOf(collection, elt) {
+  if (collection.indexOf) return collection.indexOf(elt);
+  for (var i = 0, e = collection.length; i < e; ++i)
+    if (collection[i] == elt) return i;
+  return -1;
+}
+
+function test(name, run, expectedFail) {
+  // Force unique names
+  var originalName = name;
+  var i = 2; // Second function would be NAME_2
+  while (indexOf(allNames, name) !== -1){
+    name = originalName + "_" + i;
+    i++;
+  }
+  allNames.push(name);
+  // Add test
+  tests.push({name: name, func: run, expectedFail: expectedFail});
+  return name;
+}
+var namespace = "";
+function testCM(name, run, opts, expectedFail) {
+  return test(namespace + name, function() {
+    var place = document.getElementById("testground"), cm = window.cm = CodeMirror(place, opts);
+    var successful = false;
+    try {
+      run(cm);
+      successful = true;
+    } finally {
+      if (!successful || verbose) {
+        place.style.visibility = "visible";
+      } else {
+        place.removeChild(cm.getWrapperElement());
+      }
+    }
+  }, expectedFail);
+}
+
+function runTests(callback) {
+  var totalTime = 0;
+  function step(i) {
+    for (;;) {
+      if (i === tests.length) {
+        running = false;
+        return callback("done");
+      }
+      var test = tests[i], skip = false;
+      if (filters.length) {
+        skip = true;
+        for (var j = 0; j < filters.length; j++)
+          if (test.name.match(filters[j])) skip = false;
+      }
+      if (skip) {
+        callback("skipped", test.name, message);
+        i++;
+      } else {
+        break;
+      }
+    }
+    var expFail = test.expectedFail, startTime = +new Date, threw = false;
+    try {
+      var message = test.func();
+    } catch(e) {
+      threw = true;
+      if (expFail) callback("expected", test.name);
+      else if (e instanceof Failure) callback("fail", test.name, e.message);
+      else {
+        var pos = /(?:\bat |@).*?([^\/:]+):(\d+)/.exec(e.stack);
+        if (pos) console["log"](e.stack);
+        callback("error", test.name, e.toString() + (pos ? " (" + pos[1] + ":" + pos[2] + ")" : ""));
+      }
+    }
+    if (!threw) {
+      if (expFail) callback("fail", test.name, message || "expected failure, but succeeded");
+      else callback("ok", test.name, message);
+    }
+    if (!quit) { // Run next test
+      var delay = 0;
+      totalTime += (+new Date) - startTime;
+      if (totalTime > 500){
+        totalTime = 0;
+        delay = 50;
+      }
+      setTimeout(function(){step(i + 1);}, delay);
+    } else { // Quit tests
+      running = false;
+      return null;
+    }
+  }
+  step(0);
+}
+
+function label(str, msg) {
+  if (msg) return str + " (" + msg + ")";
+  return str;
+}
+function eq(a, b, msg) {
+  if (a != b) throw new Failure(label(a + " != " + b, msg));
+}
+function near(a, b, margin, msg) {
+  if (Math.abs(a - b) > margin)
+    throw new Failure(label(a + " is not close to " + b + " (" + margin + ")", msg));
+}
+function eqPos(a, b, msg) {
+  function str(p) { return "{line:" + p.line + ",ch:" + p.ch + "}"; }
+  if (a == b) return;
+  if (a == null) throw new Failure(label("comparing null to " + str(b), msg));
+  if (b == null) throw new Failure(label("comparing " + str(a) + " to null", msg));
+  if (a.line != b.line || a.ch != b.ch) throw new Failure(label(str(a) + " != " + str(b), msg));
+}
+function is(a, msg) {
+  if (!a) throw new Failure(label("assertion failed", msg));
+}
+
+function countTests() {
+  if (!filters.length) return tests.length;
+  var sum = 0;
+  for (var i = 0; i < tests.length; ++i) {
+    var name = tests[i].name;
+    for (var j = 0; j < filters.length; j++) {
+      if (name.match(filters[j])) {
+        ++sum;
+        break;
+      }
+    }
+  }
+  return sum;
+}
+
+function parseTestFilter(s) {
+  if (/_\*$/.test(s)) return new RegExp("^" + s.slice(0, s.length - 2), "i");
+  else return new RegExp(s, "i");
+}
diff --git a/app/gui/html/vendor/codemirror/test/emacs_test.js b/app/gui/html/vendor/codemirror/test/emacs_test.js
new file mode 100644
index 0000000..f21605b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/emacs_test.js
@@ -0,0 +1,138 @@
+(function() {
+  "use strict";
+
+  var Pos = CodeMirror.Pos;
+  namespace = "emacs_";
+
+  var eventCache = {};
+  function fakeEvent(keyName) {
+    var event = eventCache[key];
+    if (event) return event;
+
+    var ctrl, shift, alt;
+    var key = keyName.replace(/\w+-/g, function(type) {
+      if (type == "Ctrl-") ctrl = true;
+      else if (type == "Alt-") alt = true;
+      else if (type == "Shift-") shift = true;
+      return "";
+    });
+    var code;
+    for (var c in CodeMirror.keyNames)
+      if (CodeMirror.keyNames[c] == key) { code = c; break; }
+    if (c == null) throw new Error("Unknown key: " + key);
+
+    return eventCache[keyName] = {
+      type: "keydown", keyCode: code, ctrlKey: ctrl, shiftKey: shift, altKey: alt,
+      preventDefault: function(){}, stopPropagation: function(){}
+    };
+  }
+
+  function sim(name, start /*, actions... */) {
+    var keys = Array.prototype.slice.call(arguments, 2);
+    testCM(name, function(cm) {
+      for (var i = 0; i < keys.length; ++i) {
+        var cur = keys[i];
+        if (cur instanceof Pos) cm.setCursor(cur);
+        else if (cur.call) cur(cm);
+        else cm.triggerOnKeyDown(fakeEvent(cur));
+      }
+    }, {keyMap: "emacs", value: start, mode: "javascript"});
+  }
+
+  function at(line, ch) { return function(cm) { eqPos(cm.getCursor(), Pos(line, ch)); }; }
+  function txt(str) { return function(cm) { eq(cm.getValue(), str); }; }
+
+  sim("motionHSimple", "abc", "Ctrl-F", "Ctrl-F", "Ctrl-B", at(0, 1));
+  sim("motionHMulti", "abcde",
+      "Ctrl-4", "Ctrl-F", at(0, 4), "Ctrl--", "Ctrl-2", "Ctrl-F", at(0, 2),
+      "Ctrl-5", "Ctrl-B", at(0, 0));
+
+  sim("motionHWord", "abc. def ghi",
+      "Alt-F", at(0, 3), "Alt-F", at(0, 8),
+      "Ctrl-B", "Alt-B", at(0, 5), "Alt-B", at(0, 0));
+  sim("motionHWordMulti", "abc. def ghi ",
+      "Ctrl-3", "Alt-F", at(0, 12), "Ctrl-2", "Alt-B", at(0, 5),
+      "Ctrl--", "Alt-B", at(0, 8));
+
+  sim("motionVSimple", "a\nb\nc\n", "Ctrl-N", "Ctrl-N", "Ctrl-P", at(1, 0));
+  sim("motionVMulti", "a\nb\nc\nd\ne\n",
+      "Ctrl-2", "Ctrl-N", at(2, 0), "Ctrl-F", "Ctrl--", "Ctrl-N", at(1, 1),
+      "Ctrl--", "Ctrl-3", "Ctrl-P", at(4, 1));
+
+  sim("killYank", "abc\ndef\nghi",
+      "Ctrl-F", "Ctrl-Space", "Ctrl-N", "Ctrl-N", "Ctrl-W", "Ctrl-E", "Ctrl-Y",
+      txt("ahibc\ndef\ng"));
+  sim("killRing", "abcdef",
+      "Ctrl-Space", "Ctrl-F", "Ctrl-W", "Ctrl-Space", "Ctrl-F", "Ctrl-W",
+      "Ctrl-Y", "Alt-Y",
+      txt("acdef"));
+  sim("copyYank", "abcd",
+      "Ctrl-Space", "Ctrl-E", "Alt-W", "Ctrl-Y",
+      txt("abcdabcd"));
+
+  sim("killLineSimple", "foo\nbar", "Ctrl-F", "Ctrl-K", txt("f\nbar"));
+  sim("killLineEmptyLine", "foo\n  \nbar", "Ctrl-N", "Ctrl-K", txt("foo\nbar"));
+  sim("killLineMulti", "foo\nbar\nbaz",
+      "Ctrl-F", "Ctrl-F", "Ctrl-K", "Ctrl-K", "Ctrl-K", "Ctrl-A", "Ctrl-Y",
+      txt("o\nbarfo\nbaz"));
+
+  sim("moveByParagraph", "abc\ndef\n\n\nhij\nklm\n\n",
+      "Ctrl-F", "Ctrl-Down", at(2, 0), "Ctrl-Down", at(6, 0),
+      "Ctrl-N", "Ctrl-Up", at(3, 0), "Ctrl-Up", at(0, 0),
+      Pos(1, 2), "Ctrl-Down", at(2, 0), Pos(4, 2), "Ctrl-Up", at(3, 0));
+  sim("moveByParagraphMulti", "abc\n\ndef\n\nhij\n\nklm",
+      "Ctrl-U", "2", "Ctrl-Down", at(3, 0),
+      "Shift-Alt-.", "Ctrl-3", "Ctrl-Up", at(1, 0));
+
+  sim("moveBySentence", "sentence one! sentence\ntwo\n\nparagraph two",
+      "Alt-E", at(0, 13), "Alt-E", at(1, 3), "Ctrl-F", "Alt-A", at(0, 13));
+
+  sim("moveByExpr", "function foo(a, b) {}",
+      "Ctrl-Alt-F", at(0, 8), "Ctrl-Alt-F", at(0, 12), "Ctrl-Alt-F", at(0, 18),
+      "Ctrl-Alt-B", at(0, 12), "Ctrl-Alt-B", at(0, 9));
+  sim("moveByExprMulti", "foo bar baz bug",
+      "Ctrl-2", "Ctrl-Alt-F", at(0, 7),
+      "Ctrl--", "Ctrl-Alt-F", at(0, 4),
+      "Ctrl--", "Ctrl-2", "Ctrl-Alt-B", at(0, 11));
+  sim("delExpr", "var x = [\n  a,\n  b\n  c\n];",
+      Pos(0, 8), "Ctrl-Alt-K", txt("var x = ;"), "Ctrl-/",
+      Pos(4, 1), "Ctrl-Alt-Backspace", txt("var x = ;"));
+  sim("delExprMulti", "foo bar baz",
+      "Ctrl-2", "Ctrl-Alt-K", txt(" baz"),
+      "Ctrl-/", "Ctrl-E", "Ctrl-2", "Ctrl-Alt-Backspace", txt("foo "));
+
+  sim("justOneSpace", "hi      bye  ",
+      Pos(0, 4), "Alt-Space", txt("hi bye  "),
+      Pos(0, 4), "Alt-Space", txt("hi b ye  "),
+      "Ctrl-A", "Alt-Space", "Ctrl-E", "Alt-Space", txt(" hi b ye "));
+
+  sim("openLine", "foo bar", "Alt-F", "Ctrl-O", txt("foo\n bar"))
+
+  sim("transposeChar", "abcd\n\ne",
+      "Ctrl-F", "Ctrl-T", "Ctrl-T", txt("bcad\n\ne"), at(0, 3),
+      "Ctrl-F", "Ctrl-T", "Ctrl-T", "Ctrl-T", txt("bcda\n\ne"), at(0, 4),
+      "Ctrl-F", "Ctrl-T", txt("bcd\na\ne"), at(1, 1));
+
+  sim("manipWordCase", "foo BAR bAZ",
+      "Alt-C", "Alt-L", "Alt-U", txt("Foo bar BAZ"),
+      "Ctrl-A", "Alt-U", "Alt-L", "Alt-C", txt("FOO bar Baz"));
+  sim("manipWordCaseMulti", "foo Bar bAz",
+      "Ctrl-2", "Alt-U", txt("FOO BAR bAz"),
+      "Ctrl-A", "Ctrl-3", "Alt-C", txt("Foo Bar Baz"));
+
+  sim("upExpr", "foo {\n  bar[];\n  baz(blah);\n}",
+      Pos(2, 7), "Ctrl-Alt-U", at(2, 5), "Ctrl-Alt-U", at(0, 4));
+  sim("transposeExpr", "do foo[bar] dah",
+      Pos(0, 6), "Ctrl-Alt-T", txt("do [bar]foo dah"));
+
+  sim("clearMark", "abcde", Pos(0, 2), "Ctrl-Space", "Ctrl-F", "Ctrl-F",
+      "Ctrl-G", "Ctrl-W", txt("abcde"));
+
+  testCM("save", function(cm) {
+    var saved = false;
+    CodeMirror.commands.save = function(cm) { saved = cm.getValue(); };
+    cm.triggerOnKeyDown(fakeEvent("Ctrl-X"));
+    cm.triggerOnKeyDown(fakeEvent("Ctrl-S"));
+    is(saved, "hi");
+  }, {value: "hi", keyMap: "emacs"});
+})();
diff --git a/app/gui/html/vendor/codemirror/test/index.html b/app/gui/html/vendor/codemirror/test/index.html
new file mode 100644
index 0000000..62a9838
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/index.html
@@ -0,0 +1,223 @@
+<!doctype html>
+
+<title>CodeMirror: Test Suite</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<link rel="stylesheet" href="mode_test.css">
+<script src="../doc/activebookmark.js"></script>
+<script src="../lib/codemirror.js"></script>
+<script src="../addon/mode/overlay.js"></script>
+<script src="../addon/mode/multiplex.js"></script>
+<script src="../addon/search/searchcursor.js"></script>
+<script src="../addon/dialog/dialog.js"></script>
+<script src="../addon/edit/matchbrackets.js"></script>
+<script src="../addon/comment/comment.js"></script>
+<script src="../mode/javascript/javascript.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<script src="../keymap/vim.js"></script>
+<script src="../keymap/emacs.js"></script>
+<script src="../keymap/sublime.js"></script>
+
+<style type="text/css">
+  .ok {color: #090;}
+  .fail {color: #e00;}
+  .error {color: #c90;}
+  .done {font-weight: bold;}
+  #progress {
+  background: #45d;
+  color: white;
+  text-shadow: 0 0 1px #45d, 0 0 2px #45d, 0 0 3px #45d;
+  font-weight: bold;
+  white-space: pre;
+  }
+  #testground {
+  visibility: hidden;
+  }
+  #testground.offscreen {
+  visibility: visible;
+  position: absolute;
+  left: -10000px;
+  top: -10000px;
+  }
+  .CodeMirror { border: 1px solid black; }
+</style>
+
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../index.html">Home</a>
+    <li><a href="../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a class=active href="#">Test suite</a>
+  </ul>
+</div>
+
+<article>
+  <h2>Test Suite</h2>
+
+    <p>A limited set of programmatic sanity tests for CodeMirror.</p>
+
+    <div style="border: 1px solid black; padding: 1px; max-width: 700px;">
+      <div style="width: 0px;" id=progress><div style="padding: 3px;">Ran <span id="progress_ran">0</span><span id="progress_total"> of 0</span> tests</div></div>
+    </div>
+    <p id=status>Please enable JavaScript...</p>
+    <div id=output></div>
+
+    <div id=testground></div>
+
+    <script src="driver.js"></script>
+    <script src="test.js"></script>
+    <script src="doc_test.js"></script>
+    <script src="multi_test.js"></script>
+    <script src="comment_test.js"></script>
+    <script src="search_test.js"></script>
+    <script src="mode_test.js"></script>
+    <script src="../mode/javascript/test.js"></script>
+    <script src="../mode/css/css.js"></script>
+    <script src="../mode/css/test.js"></script>
+    <script src="../mode/css/scss_test.js"></script>
+    <script src="../mode/css/less_test.js"></script>
+    <script src="../mode/xml/xml.js"></script>
+    <script src="../mode/htmlmixed/htmlmixed.js"></script>
+    <script src="../mode/ruby/ruby.js"></script>
+    <script src="../mode/ruby/test.js"></script>
+    <script src="../mode/haml/haml.js"></script>
+    <script src="../mode/haml/test.js"></script>
+    <script src="../mode/markdown/markdown.js"></script>
+    <script src="../mode/markdown/test.js"></script>
+    <script src="../mode/gfm/gfm.js"></script>
+    <script src="../mode/gfm/test.js"></script>
+    <script src="../mode/stex/stex.js"></script>
+    <script src="../mode/stex/test.js"></script>
+    <script src="../mode/xquery/xquery.js"></script>
+    <script src="../mode/xquery/test.js"></script>
+    <script src="../addon/mode/multiplex_test.js"></script>
+    <script src="vim_test.js"></script>
+    <script src="emacs_test.js"></script>
+    <script src="sublime_test.js"></script>
+    <script>
+      window.onload = runHarness;
+      CodeMirror.on(window, 'hashchange', runHarness);
+
+      function esc(str) {
+        return str.replace(/[<&]/, function(ch) { return ch == "<" ? "<" : "&"; });
+      }
+
+      var output = document.getElementById("output"),
+          progress = document.getElementById("progress"),
+          progressRan = document.getElementById("progress_ran").childNodes[0],
+          progressTotal = document.getElementById("progress_total").childNodes[0];
+      var count = 0,
+          failed = 0,
+          skipped = 0,
+          bad = "",
+          running = false, // Flag that states tests are running
+          quit = false, // Flag to quit tests ASAP
+          verbose = false; // Adds message for *every* test to output
+
+      function runHarness(){
+        if (running) {
+          quit = true;
+          setStatus("Restarting tests...", '', true);
+          setTimeout(function(){runHarness();}, 500);
+          return;
+        }
+        filters = [];
+        verbose = false;
+        if (window.location.hash.substr(1)){
+          var strings = window.location.hash.substr(1).split(",");
+          while (strings.length) {
+            var s = strings.shift();
+            if (s === "verbose")
+              verbose = true;
+            else
+              filters.push(parseTestFilter(decodeURIComponent(s)));;
+          }
+        }
+        quit = false;
+        running = true;
+        setStatus("Loading tests...");
+        count = 0;
+        failed = 0;
+        skipped = 0;
+        bad = "";
+        totalTests = countTests();
+        progressTotal.nodeValue = " of " + totalTests;
+        progressRan.nodeValue = count;
+        output.innerHTML = '';
+        document.getElementById("testground").innerHTML = "<form>" +
+          "<textarea id=\"code\" name=\"code\"></textarea>" +
+          "<input type=submit value=ok name=submit>" +
+          "</form>";
+        runTests(displayTest);
+      }
+
+      function setStatus(message, className, force){
+        if (quit && !force) return;
+        if (!message) throw("must provide message");
+        var status = document.getElementById("status").childNodes[0];
+        status.nodeValue = message;
+        status.parentNode.className = className;
+      }
+      function addOutput(name, className, code){
+        var newOutput = document.createElement("dl");
+        var newTitle = document.createElement("dt");
+        newTitle.className = className;
+        newTitle.appendChild(document.createTextNode(name));
+        newOutput.appendChild(newTitle);
+        var newMessage = document.createElement("dd");
+        newMessage.innerHTML = code;
+        newOutput.appendChild(newTitle);
+        newOutput.appendChild(newMessage);
+        output.appendChild(newOutput);
+      }
+      function displayTest(type, name, customMessage) {
+        var message = "???";
+        if (type != "done" && type != "skipped") ++count;
+        progress.style.width = (count * (progress.parentNode.clientWidth - 2) / totalTests) + "px";
+        progressRan.nodeValue = count;
+        if (type == "ok") {
+          message = "Test '" + name + "' succeeded";
+          if (!verbose) customMessage = false;
+        } else if (type == "skipped") {
+          message = "Test '" + name + "' skipped";
+          ++skipped;
+          if (!verbose) customMessage = false;
+        } else if (type == "expected") {
+          message = "Test '" + name + "' failed as expected";
+          if (!verbose) customMessage = false;
+        } else if (type == "error" || type == "fail") {
+          ++failed;
+          message = "Test '" + name + "' failed";
+        } else if (type == "done") {
+          if (failed) {
+            type += " fail";
+            message = failed + " failure" + (failed > 1 ? "s" : "");
+          } else if (count < totalTests) {
+            failed = totalTests - count;
+            type += " fail";
+            message = failed + " failure" + (failed > 1 ? "s" : "");
+          } else {
+            type += " ok";
+            message = "All passed";
+            if (skipped) {
+              message += " (" + skipped + " skipped)";
+            }
+          }
+          progressTotal.nodeValue = '';
+          customMessage = true; // Hack to avoid adding to output
+        }
+        if (verbose && !customMessage)  customMessage = message;
+        setStatus(message, type);
+        if (customMessage && customMessage.length > 0) {
+          addOutput(name, type, customMessage);
+        }
+      }
+    </script>
+
+</article>
diff --git a/app/gui/html/vendor/codemirror/test/lint/acorn.js b/app/gui/html/vendor/codemirror/test/lint/acorn.js
new file mode 100644
index 0000000..0f11931
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/lint/acorn.js
@@ -0,0 +1,1782 @@
+// Acorn is a tiny, fast JavaScript parser written in JavaScript.
+//
+// Acorn was written by Marijn Haverbeke and released under an MIT
+// license. The Unicode regexps (for identifiers and whitespace) were
+// taken from [Esprima](http://esprima.org) by Ariya Hidayat.
+//
+// Git repositories for Acorn are available at
+//
+//     http://marijnhaverbeke.nl/git/acorn
+//     https://github.com/marijnh/acorn.git
+//
+// Please use the [github bug tracker][ghbt] to report issues.
+//
+// [ghbt]: https://github.com/marijnh/acorn/issues
+//
+// This file defines the main parser interface. The library also comes
+// with a [error-tolerant parser][dammit] and an
+// [abstract syntax tree walker][walk], defined in other files.
+//
+// [dammit]: acorn_loose.js
+// [walk]: util/walk.js
+
+(function(root, mod) {
+  if (typeof exports == "object" && typeof module == "object") return mod(exports); // CommonJS
+  if (typeof define == "function" && define.amd) return define(["exports"], mod); // AMD
+  mod(root.acorn || (root.acorn = {})); // Plain browser env
+})(this, function(exports) {
+  "use strict";
+
+  exports.version = "0.4.1";
+
+  // The main exported interface (under `self.acorn` when in the
+  // browser) is a `parse` function that takes a code string and
+  // returns an abstract syntax tree as specified by [Mozilla parser
+  // API][api], with the caveat that the SpiderMonkey-specific syntax
+  // (`let`, `yield`, inline XML, etc) is not recognized.
+  //
+  // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
+
+  var options, input, inputLen, sourceFile;
+
+  exports.parse = function(inpt, opts) {
+    input = String(inpt); inputLen = input.length;
+    setOptions(opts);
+    initTokenState();
+    return parseTopLevel(options.program);
+  };
+
+  // A second optional argument can be given to further configure
+  // the parser process. These options are recognized:
+
+  var defaultOptions = exports.defaultOptions = {
+    // `ecmaVersion` indicates the ECMAScript version to parse. Must
+    // be either 3 or 5. This
+    // influences support for strict mode, the set of reserved words, and
+    // support for getters and setter.
+    ecmaVersion: 5,
+    // Turn on `strictSemicolons` to prevent the parser from doing
+    // automatic semicolon insertion.
+    strictSemicolons: false,
+    // When `allowTrailingCommas` is false, the parser will not allow
+    // trailing commas in array and object literals.
+    allowTrailingCommas: true,
+    // By default, reserved words are not enforced. Enable
+    // `forbidReserved` to enforce them. When this option has the
+    // value "everywhere", reserved words and keywords can also not be
+    // used as property names.
+    forbidReserved: false,
+    // When enabled, a return at the top level is not considered an
+    // error.
+    allowReturnOutsideFunction: false,
+    // When `locations` is on, `loc` properties holding objects with
+    // `start` and `end` properties in `{line, column}` form (with
+    // line being 1-based and column 0-based) will be attached to the
+    // nodes.
+    locations: false,
+    // A function can be passed as `onComment` option, which will
+    // cause Acorn to call that function with `(block, text, start,
+    // end)` parameters whenever a comment is skipped. `block` is a
+    // boolean indicating whether this is a block (`/* */`) comment,
+    // `text` is the content of the comment, and `start` and `end` are
+    // character offsets that denote the start and end of the comment.
+    // When the `locations` option is on, two more parameters are
+    // passed, the full `{line, column}` locations of the start and
+    // end of the comments. Note that you are not allowed to call the
+    // parser from the callback—that will corrupt its internal state.
+    onComment: null,
+    // Nodes have their start and end characters offsets recorded in
+    // `start` and `end` properties (directly on the node, rather than
+    // the `loc` object, which holds line/column data. To also add a
+    // [semi-standardized][range] `range` property holding a `[start,
+    // end]` array with the same numbers, set the `ranges` option to
+    // `true`.
+    //
+    // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
+    ranges: false,
+    // It is possible to parse multiple files into a single AST by
+    // passing the tree produced by parsing the first file as
+    // `program` option in subsequent parses. This will add the
+    // toplevel forms of the parsed file to the `Program` (top) node
+    // of an existing parse tree.
+    program: null,
+    // When `locations` is on, you can pass this to record the source
+    // file in every node's `loc` object.
+    sourceFile: null,
+    // This value, if given, is stored in every node, whether
+    // `locations` is on or off.
+    directSourceFile: null
+  };
+
+  function setOptions(opts) {
+    options = opts || {};
+    for (var opt in defaultOptions) if (!Object.prototype.hasOwnProperty.call(options, opt))
+      options[opt] = defaultOptions[opt];
+    sourceFile = options.sourceFile || null;
+  }
+
+  // The `getLineInfo` function is mostly useful when the
+  // `locations` option is off (for performance reasons) and you
+  // want to find the line/column position for a given character
+  // offset. `input` should be the code string that the offset refers
+  // into.
+
+  var getLineInfo = exports.getLineInfo = function(input, offset) {
+    for (var line = 1, cur = 0;;) {
+      lineBreak.lastIndex = cur;
+      var match = lineBreak.exec(input);
+      if (match && match.index < offset) {
+        ++line;
+        cur = match.index + match[0].length;
+      } else break;
+    }
+    return {line: line, column: offset - cur};
+  };
+
+  // Acorn is organized as a tokenizer and a recursive-descent parser.
+  // The `tokenize` export provides an interface to the tokenizer.
+  // Because the tokenizer is optimized for being efficiently used by
+  // the Acorn parser itself, this interface is somewhat crude and not
+  // very modular. Performing another parse or call to `tokenize` will
+  // reset the internal state, and invalidate existing tokenizers.
+
+  exports.tokenize = function(inpt, opts) {
+    input = String(inpt); inputLen = input.length;
+    setOptions(opts);
+    initTokenState();
+
+    var t = {};
+    function getToken(forceRegexp) {
+      lastEnd = tokEnd;
+      readToken(forceRegexp);
+      t.start = tokStart; t.end = tokEnd;
+      t.startLoc = tokStartLoc; t.endLoc = tokEndLoc;
+      t.type = tokType; t.value = tokVal;
+      return t;
+    }
+    getToken.jumpTo = function(pos, reAllowed) {
+      tokPos = pos;
+      if (options.locations) {
+        tokCurLine = 1;
+        tokLineStart = lineBreak.lastIndex = 0;
+        var match;
+        while ((match = lineBreak.exec(input)) && match.index < pos) {
+          ++tokCurLine;
+          tokLineStart = match.index + match[0].length;
+        }
+      }
+      tokRegexpAllowed = reAllowed;
+      skipSpace();
+    };
+    return getToken;
+  };
+
+  // State is kept in (closure-)global variables. We already saw the
+  // `options`, `input`, and `inputLen` variables above.
+
+  // The current position of the tokenizer in the input.
+
+  var tokPos;
+
+  // The start and end offsets of the current token.
+
+  var tokStart, tokEnd;
+
+  // When `options.locations` is true, these hold objects
+  // containing the tokens start and end line/column pairs.
+
+  var tokStartLoc, tokEndLoc;
+
+  // The type and value of the current token. Token types are objects,
+  // named by variables against which they can be compared, and
+  // holding properties that describe them (indicating, for example,
+  // the precedence of an infix operator, and the original name of a
+  // keyword token). The kind of value that's held in `tokVal` depends
+  // on the type of the token. For literals, it is the literal value,
+  // for operators, the operator name, and so on.
+
+  var tokType, tokVal;
+
+  // Interal state for the tokenizer. To distinguish between division
+  // operators and regular expressions, it remembers whether the last
+  // token was one that is allowed to be followed by an expression.
+  // (If it is, a slash is probably a regexp, if it isn't it's a
+  // division operator. See the `parseStatement` function for a
+  // caveat.)
+
+  var tokRegexpAllowed;
+
+  // When `options.locations` is true, these are used to keep
+  // track of the current line, and know when a new line has been
+  // entered.
+
+  var tokCurLine, tokLineStart;
+
+  // These store the position of the previous token, which is useful
+  // when finishing a node and assigning its `end` position.
+
+  var lastStart, lastEnd, lastEndLoc;
+
+  // This is the parser's state. `inFunction` is used to reject
+  // `return` statements outside of functions, `labels` to verify that
+  // `break` and `continue` have somewhere to jump to, and `strict`
+  // indicates whether strict mode is on.
+
+  var inFunction, labels, strict;
+
+  // This function is used to raise exceptions on parse errors. It
+  // takes an offset integer (into the current `input`) to indicate
+  // the location of the error, attaches the position to the end
+  // of the error message, and then raises a `SyntaxError` with that
+  // message.
+
+  function raise(pos, message) {
+    var loc = getLineInfo(input, pos);
+    message += " (" + loc.line + ":" + loc.column + ")";
+    var err = new SyntaxError(message);
+    err.pos = pos; err.loc = loc; err.raisedAt = tokPos;
+    throw err;
+  }
+
+  // Reused empty array added for node fields that are always empty.
+
+  var empty = [];
+
+  // ## Token types
+
+  // The assignment of fine-grained, information-carrying type objects
+  // allows the tokenizer to store the information it has about a
+  // token in a way that is very cheap for the parser to look up.
+
+  // All token type variables start with an underscore, to make them
+  // easy to recognize.
+
+  // These are the general types. The `type` property is only used to
+  // make them recognizeable when debugging.
+
+  var _num = {type: "num"}, _regexp = {type: "regexp"}, _string = {type: "string"};
+  var _name = {type: "name"}, _eof = {type: "eof"};
+
+  // Keyword tokens. The `keyword` property (also used in keyword-like
+  // operators) indicates that the token originated from an
+  // identifier-like word, which is used when parsing property names.
+  //
+  // The `beforeExpr` property is used to disambiguate between regular
+  // expressions and divisions. It is set on all token types that can
+  // be followed by an expression (thus, a slash after them would be a
+  // regular expression).
+  //
+  // `isLoop` marks a keyword as starting a loop, which is important
+  // to know when parsing a label, in order to allow or disallow
+  // continue jumps to that label.
+
+  var _break = {keyword: "break"}, _case = {keyword: "case", beforeExpr: true}, _catch = {keyword: "catch"};
+  var _continue = {keyword: "continue"}, _debugger = {keyword: "debugger"}, _default = {keyword: "default"};
+  var _do = {keyword: "do", isLoop: true}, _else = {keyword: "else", beforeExpr: true};
+  var _finally = {keyword: "finally"}, _for = {keyword: "for", isLoop: true}, _function = {keyword: "function"};
+  var _if = {keyword: "if"}, _return = {keyword: "return", beforeExpr: true}, _switch = {keyword: "switch"};
+  var _throw = {keyword: "throw", beforeExpr: true}, _try = {keyword: "try"}, _var = {keyword: "var"};
+  var _while = {keyword: "while", isLoop: true}, _with = {keyword: "with"}, _new = {keyword: "new", beforeExpr: true};
+  var _this = {keyword: "this"};
+
+  // The keywords that denote values.
+
+  var _null = {keyword: "null", atomValue: null}, _true = {keyword: "true", atomValue: true};
+  var _false = {keyword: "false", atomValue: false};
+
+  // Some keywords are treated as regular operators. `in` sometimes
+  // (when parsing `for`) needs to be tested against specifically, so
+  // we assign a variable name to it for quick comparing.
+
+  var _in = {keyword: "in", binop: 7, beforeExpr: true};
+
+  // Map keyword names to token types.
+
+  var keywordTypes = {"break": _break, "case": _case, "catch": _catch,
+                      "continue": _continue, "debugger": _debugger, "default": _default,
+                      "do": _do, "else": _else, "finally": _finally, "for": _for,
+                      "function": _function, "if": _if, "return": _return, "switch": _switch,
+                      "throw": _throw, "try": _try, "var": _var, "while": _while, "with": _with,
+                      "null": _null, "true": _true, "false": _false, "new": _new, "in": _in,
+                      "instanceof": {keyword: "instanceof", binop: 7, beforeExpr: true}, "this": _this,
+                      "typeof": {keyword: "typeof", prefix: true, beforeExpr: true},
+                      "void": {keyword: "void", prefix: true, beforeExpr: true},
+                      "delete": {keyword: "delete", prefix: true, beforeExpr: true}};
+
+  // Punctuation token types. Again, the `type` property is purely for debugging.
+
+  var _bracketL = {type: "[", beforeExpr: true}, _bracketR = {type: "]"}, _braceL = {type: "{", beforeExpr: true};
+  var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"};
+  var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true};
+  var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _question = {type: "?", beforeExpr: true};
+
+  // Operators. These carry several kinds of properties to help the
+  // parser use them properly (the presence of these properties is
+  // what categorizes them as operators).
+  //
+  // `binop`, when present, specifies that this operator is a binary
+  // operator, and will refer to its precedence.
+  //
+  // `prefix` and `postfix` mark the operator as a prefix or postfix
+  // unary operator. `isUpdate` specifies that the node produced by
+  // the operator should be of type UpdateExpression rather than
+  // simply UnaryExpression (`++` and `--`).
+  //
+  // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
+  // binary operators with a very low precedence, that should result
+  // in AssignmentExpression nodes.
+
+  var _slash = {binop: 10, beforeExpr: true}, _eq = {isAssign: true, beforeExpr: true};
+  var _assign = {isAssign: true, beforeExpr: true};
+  var _incDec = {postfix: true, prefix: true, isUpdate: true}, _prefix = {prefix: true, beforeExpr: true};
+  var _logicalOR = {binop: 1, beforeExpr: true};
+  var _logicalAND = {binop: 2, beforeExpr: true};
+  var _bitwiseOR = {binop: 3, beforeExpr: true};
+  var _bitwiseXOR = {binop: 4, beforeExpr: true};
+  var _bitwiseAND = {binop: 5, beforeExpr: true};
+  var _equality = {binop: 6, beforeExpr: true};
+  var _relational = {binop: 7, beforeExpr: true};
+  var _bitShift = {binop: 8, beforeExpr: true};
+  var _plusMin = {binop: 9, prefix: true, beforeExpr: true};
+  var _multiplyModulo = {binop: 10, beforeExpr: true};
+
+  // Provide access to the token types for external users of the
+  // tokenizer.
+
+  exports.tokTypes = {bracketL: _bracketL, bracketR: _bracketR, braceL: _braceL, braceR: _braceR,
+                      parenL: _parenL, parenR: _parenR, comma: _comma, semi: _semi, colon: _colon,
+                      dot: _dot, question: _question, slash: _slash, eq: _eq, name: _name, eof: _eof,
+                      num: _num, regexp: _regexp, string: _string};
+  for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw];
+
+  // This is a trick taken from Esprima. It turns out that, on
+  // non-Chrome browsers, to check whether a string is in a set, a
+  // predicate containing a big ugly `switch` statement is faster than
+  // a regular expression, and on Chrome the two are about on par.
+  // This function uses `eval` (non-lexical) to produce such a
+  // predicate from a space-separated string of words.
+  //
+  // It starts by sorting the words by length.
+
+  function makePredicate(words) {
+    words = words.split(" ");
+    var f = "", cats = [];
+    out: for (var i = 0; i < words.length; ++i) {
+      for (var j = 0; j < cats.length; ++j)
+        if (cats[j][0].length == words[i].length) {
+          cats[j].push(words[i]);
+          continue out;
+        }
+      cats.push([words[i]]);
+    }
+    function compareTo(arr) {
+      if (arr.length == 1) return f += "return str === " + JSON.stringify(arr[0]) + ";";
+      f += "switch(str){";
+      for (var i = 0; i < arr.length; ++i) f += "case " + JSON.stringify(arr[i]) + ":";
+      f += "return true}return false;";
+    }
+
+    // When there are more than three length categories, an outer
+    // switch first dispatches on the lengths, to save on comparisons.
+
+    if (cats.length > 3) {
+      cats.sort(function(a, b) {return b.length - a.length;});
+      f += "switch(str.length){";
+      for (var i = 0; i < cats.length; ++i) {
+        var cat = cats[i];
+        f += "case " + cat[0].length + ":";
+        compareTo(cat);
+      }
+      f += "}";
+
+    // Otherwise, simply generate a flat `switch` statement.
+
+    } else {
+      compareTo(words);
+    }
+    return new Function("str", f);
+  }
+
+  // The ECMAScript 3 reserved word list.
+
+  var isReservedWord3 = makePredicate("abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile");
+
+  // ECMAScript 5 reserved words.
+
+  var isReservedWord5 = makePredicate("class enum extends super const export import");
+
+  // The additional reserved words in strict mode.
+
+  var isStrictReservedWord = makePredicate("implements interface let package private protected public static yield");
+
+  // The forbidden variable names in strict mode.
+
+  var isStrictBadIdWord = makePredicate("eval arguments");
+
+  // And the keywords.
+
+  var isKeyword = makePredicate("break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this");
+
+  // ## Character categories
+
+  // Big ugly regular expressions that match characters in the
+  // whitespace, identifier, and identifier-start categories. These
+  // are only applied when a character is found to actually have a
+  // code point above 128.
+
+  var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
+  var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
+  var nonASCIIidentifierChars = "\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u0620-\u0649\u0672-\u06d3\u06e7-\u06e8\u06fb-\u06fc\u0730-\u074a\u0800-\u0814\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0840-\u0857\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962-\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09d7\u09df-\u09e0\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5f-\u0b60\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2-\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d46-\u0d48\u0d57\u0d62-\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e34-\u0e3a\u0e40-\u0e45\u0e50-\u0e59\u0eb4-\u0eb9\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f41-\u0f47\u0f71-\u0f84\u0f86-\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1029\u1040-\u1049\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u170e-\u1710\u1720-\u1730\u1740-\u1750\u1772\u1773\u1780-\u17b2\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1920-\u192b\u1930-\u193b\u1951-\u196d\u19b0-\u19c0\u19c8-\u19c9\u19d0-\u19d9\u1a00-\u1a15\u1a20-\u1a53\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b46-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1bb0-\u1bb9\u1be6-\u1bf3\u1c00-\u1c22\u1c40-\u1c49\u1c5b-\u1c7d\u1cd0-\u1cd2\u1d00-\u1dbe\u1e01-\u1f15\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2d81-\u2d96\u2de0-\u2dff\u3021-\u3028\u3099\u309a\ua640-\ua66d\ua674-\ua67d\ua69f\ua6f0-\ua6f1\ua7f8-\ua800\ua806\ua80b\ua823-\ua827\ua880-\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8f3-\ua8f7\ua900-\ua909\ua926-\ua92d\ua930-\ua945\ua980-\ua983\ua9b3-\ua9c0\uaa00-\uaa27\uaa40-\uaa41\uaa4c-\uaa4d\uaa50-\uaa59\uaa7b\uaae0-\uaae9\uaaf2-\uaaf3\uabc0-\uabe1\uabec\uabed\uabf0-\uabf9\ufb20-\ufb28\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f";
+  var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
+  var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
+
+  // Whether a single character denotes a newline.
+
+  var newline = /[\n\r\u2028\u2029]/;
+
+  // Matches a whole line break (where CRLF is considered a single
+  // line break). Used to count lines.
+
+  var lineBreak = /\r\n|[\n\r\u2028\u2029]/g;
+
+  // Test whether a given character code starts an identifier.
+
+  var isIdentifierStart = exports.isIdentifierStart = function(code) {
+    if (code < 65) return code === 36;
+    if (code < 91) return true;
+    if (code < 97) return code === 95;
+    if (code < 123)return true;
+    return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code));
+  };
+
+  // Test whether a given character is part of an identifier.
+
+  var isIdentifierChar = exports.isIdentifierChar = function(code) {
+    if (code < 48) return code === 36;
+    if (code < 58) return true;
+    if (code < 65) return false;
+    if (code < 91) return true;
+    if (code < 97) return code === 95;
+    if (code < 123)return true;
+    return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code));
+  };
+
+  // ## Tokenizer
+
+  // These are used when `options.locations` is on, for the
+  // `tokStartLoc` and `tokEndLoc` properties.
+
+  function line_loc_t() {
+    this.line = tokCurLine;
+    this.column = tokPos - tokLineStart;
+  }
+
+  // Reset the token state. Used at the start of a parse.
+
+  function initTokenState() {
+    tokCurLine = 1;
+    tokPos = tokLineStart = 0;
+    tokRegexpAllowed = true;
+    skipSpace();
+  }
+
+  // Called at the end of every token. Sets `tokEnd`, `tokVal`, and
+  // `tokRegexpAllowed`, and skips the space after the token, so that
+  // the next one's `tokStart` will point at the right position.
+
+  function finishToken(type, val) {
+    tokEnd = tokPos;
+    if (options.locations) tokEndLoc = new line_loc_t;
+    tokType = type;
+    skipSpace();
+    tokVal = val;
+    tokRegexpAllowed = type.beforeExpr;
+  }
+
+  function skipBlockComment() {
+    var startLoc = options.onComment && options.locations && new line_loc_t;
+    var start = tokPos, end = input.indexOf("*/", tokPos += 2);
+    if (end === -1) raise(tokPos - 2, "Unterminated comment");
+    tokPos = end + 2;
+    if (options.locations) {
+      lineBreak.lastIndex = start;
+      var match;
+      while ((match = lineBreak.exec(input)) && match.index < tokPos) {
+        ++tokCurLine;
+        tokLineStart = match.index + match[0].length;
+      }
+    }
+    if (options.onComment)
+      options.onComment(true, input.slice(start + 2, end), start, tokPos,
+                        startLoc, options.locations && new line_loc_t);
+  }
+
+  function skipLineComment() {
+    var start = tokPos;
+    var startLoc = options.onComment && options.locations && new line_loc_t;
+    var ch = input.charCodeAt(tokPos+=2);
+    while (tokPos < inputLen && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {
+      ++tokPos;
+      ch = input.charCodeAt(tokPos);
+    }
+    if (options.onComment)
+      options.onComment(false, input.slice(start + 2, tokPos), start, tokPos,
+                        startLoc, options.locations && new line_loc_t);
+  }
+
+  // Called at the start of the parse and after every token. Skips
+  // whitespace and comments, and.
+
+  function skipSpace() {
+    while (tokPos < inputLen) {
+      var ch = input.charCodeAt(tokPos);
+      if (ch === 32) { // ' '
+        ++tokPos;
+      } else if (ch === 13) {
+        ++tokPos;
+        var next = input.charCodeAt(tokPos);
+        if (next === 10) {
+          ++tokPos;
+        }
+        if (options.locations) {
+          ++tokCurLine;
+          tokLineStart = tokPos;
+        }
+      } else if (ch === 10 || ch === 8232 || ch === 8233) {
+        ++tokPos;
+        if (options.locations) {
+          ++tokCurLine;
+          tokLineStart = tokPos;
+        }
+      } else if (ch > 8 && ch < 14) {
+        ++tokPos;
+      } else if (ch === 47) { // '/'
+        var next = input.charCodeAt(tokPos + 1);
+        if (next === 42) { // '*'
+          skipBlockComment();
+        } else if (next === 47) { // '/'
+          skipLineComment();
+        } else break;
+      } else if (ch === 160) { // '\xa0'
+        ++tokPos;
+      } else if (ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
+        ++tokPos;
+      } else {
+        break;
+      }
+    }
+  }
+
+  // ### Token reading
+
+  // This is the function that is called to fetch the next token. It
+  // is somewhat obscure, because it works in character codes rather
+  // than characters, and because operator parsing has been inlined
+  // into it.
+  //
+  // All in the name of speed.
+  //
+  // The `forceRegexp` parameter is used in the one case where the
+  // `tokRegexpAllowed` trick does not work. See `parseStatement`.
+
+  function readToken_dot() {
+    var next = input.charCodeAt(tokPos + 1);
+    if (next >= 48 && next <= 57) return readNumber(true);
+    ++tokPos;
+    return finishToken(_dot);
+  }
+
+  function readToken_slash() { // '/'
+    var next = input.charCodeAt(tokPos + 1);
+    if (tokRegexpAllowed) {++tokPos; return readRegexp();}
+    if (next === 61) return finishOp(_assign, 2);
+    return finishOp(_slash, 1);
+  }
+
+  function readToken_mult_modulo() { // '%*'
+    var next = input.charCodeAt(tokPos + 1);
+    if (next === 61) return finishOp(_assign, 2);
+    return finishOp(_multiplyModulo, 1);
+  }
+
+  function readToken_pipe_amp(code) { // '|&'
+    var next = input.charCodeAt(tokPos + 1);
+    if (next === code) return finishOp(code === 124 ? _logicalOR : _logicalAND, 2);
+    if (next === 61) return finishOp(_assign, 2);
+    return finishOp(code === 124 ? _bitwiseOR : _bitwiseAND, 1);
+  }
+
+  function readToken_caret() { // '^'
+    var next = input.charCodeAt(tokPos + 1);
+    if (next === 61) return finishOp(_assign, 2);
+    return finishOp(_bitwiseXOR, 1);
+  }
+
+  function readToken_plus_min(code) { // '+-'
+    var next = input.charCodeAt(tokPos + 1);
+    if (next === code) {
+      if (next == 45 && input.charCodeAt(tokPos + 2) == 62 &&
+          newline.test(input.slice(lastEnd, tokPos))) {
+        // A `-->` line comment
+        tokPos += 3;
+        skipLineComment();
+        skipSpace();
+        return readToken();
+      }
+      return finishOp(_incDec, 2);
+    }
+    if (next === 61) return finishOp(_assign, 2);
+    return finishOp(_plusMin, 1);
+  }
+
+  function readToken_lt_gt(code) { // '<>'
+    var next = input.charCodeAt(tokPos + 1);
+    var size = 1;
+    if (next === code) {
+      size = code === 62 && input.charCodeAt(tokPos + 2) === 62 ? 3 : 2;
+      if (input.charCodeAt(tokPos + size) === 61) return finishOp(_assign, size + 1);
+      return finishOp(_bitShift, size);
+    }
+    if (next == 33 && code == 60 && input.charCodeAt(tokPos + 2) == 45 &&
+        input.charCodeAt(tokPos + 3) == 45) {
+      // `<!--`, an XML-style comment that should be interpreted as a line comment
+      tokPos += 4;
+      skipLineComment();
+      skipSpace();
+      return readToken();
+    }
+    if (next === 61)
+      size = input.charCodeAt(tokPos + 2) === 61 ? 3 : 2;
+    return finishOp(_relational, size);
+  }
+
+  function readToken_eq_excl(code) { // '=!'
+    var next = input.charCodeAt(tokPos + 1);
+    if (next === 61) return finishOp(_equality, input.charCodeAt(tokPos + 2) === 61 ? 3 : 2);
+    return finishOp(code === 61 ? _eq : _prefix, 1);
+  }
+
+  function getTokenFromCode(code) {
+    switch(code) {
+      // The interpretation of a dot depends on whether it is followed
+      // by a digit.
+    case 46: // '.'
+      return readToken_dot();
+
+      // Punctuation tokens.
+    case 40: ++tokPos; return finishToken(_parenL);
+    case 41: ++tokPos; return finishToken(_parenR);
+    case 59: ++tokPos; return finishToken(_semi);
+    case 44: ++tokPos; return finishToken(_comma);
+    case 91: ++tokPos; return finishToken(_bracketL);
+    case 93: ++tokPos; return finishToken(_bracketR);
+    case 123: ++tokPos; return finishToken(_braceL);
+    case 125: ++tokPos; return finishToken(_braceR);
+    case 58: ++tokPos; return finishToken(_colon);
+    case 63: ++tokPos; return finishToken(_question);
+
+      // '0x' is a hexadecimal number.
+    case 48: // '0'
+      var next = input.charCodeAt(tokPos + 1);
+      if (next === 120 || next === 88) return readHexNumber();
+      // Anything else beginning with a digit is an integer, octal
+      // number, or float.
+    case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
+      return readNumber(false);
+
+      // Quotes produce strings.
+    case 34: case 39: // '"', "'"
+      return readString(code);
+
+    // Operators are parsed inline in tiny state machines. '=' (61) is
+    // often referred to. `finishOp` simply skips the amount of
+    // characters it is given as second argument, and returns a token
+    // of the type given by its first argument.
+
+    case 47: // '/'
+      return readToken_slash(code);
+
+    case 37: case 42: // '%*'
+      return readToken_mult_modulo();
+
+    case 124: case 38: // '|&'
+      return readToken_pipe_amp(code);
+
+    case 94: // '^'
+      return readToken_caret();
+
+    case 43: case 45: // '+-'
+      return readToken_plus_min(code);
+
+    case 60: case 62: // '<>'
+      return readToken_lt_gt(code);
+
+    case 61: case 33: // '=!'
+      return readToken_eq_excl(code);
+
+    case 126: // '~'
+      return finishOp(_prefix, 1);
+    }
+
+    return false;
+  }
+
+  function readToken(forceRegexp) {
+    if (!forceRegexp) tokStart = tokPos;
+    else tokPos = tokStart + 1;
+    if (options.locations) tokStartLoc = new line_loc_t;
+    if (forceRegexp) return readRegexp();
+    if (tokPos >= inputLen) return finishToken(_eof);
+
+    var code = input.charCodeAt(tokPos);
+    // Identifier or keyword. '\uXXXX' sequences are allowed in
+    // identifiers, so '\' also dispatches to that.
+    if (isIdentifierStart(code) || code === 92 /* '\' */) return readWord();
+
+    var tok = getTokenFromCode(code);
+
+    if (tok === false) {
+      // If we are here, we either found a non-ASCII identifier
+      // character, or something that's entirely disallowed.
+      var ch = String.fromCharCode(code);
+      if (ch === "\\" || nonASCIIidentifierStart.test(ch)) return readWord();
+      raise(tokPos, "Unexpected character '" + ch + "'");
+    }
+    return tok;
+  }
+
+  function finishOp(type, size) {
+    var str = input.slice(tokPos, tokPos + size);
+    tokPos += size;
+    finishToken(type, str);
+  }
+
+  // Parse a regular expression. Some context-awareness is necessary,
+  // since a '/' inside a '[]' set does not end the expression.
+
+  function readRegexp() {
+    var content = "", escaped, inClass, start = tokPos;
+    for (;;) {
+      if (tokPos >= inputLen) raise(start, "Unterminated regular expression");
+      var ch = input.charAt(tokPos);
+      if (newline.test(ch)) raise(start, "Unterminated regular expression");
+      if (!escaped) {
+        if (ch === "[") inClass = true;
+        else if (ch === "]" && inClass) inClass = false;
+        else if (ch === "/" && !inClass) break;
+        escaped = ch === "\\";
+      } else escaped = false;
+      ++tokPos;
+    }
+    var content = input.slice(start, tokPos);
+    ++tokPos;
+    // Need to use `readWord1` because '\uXXXX' sequences are allowed
+    // here (don't ask).
+    var mods = readWord1();
+    if (mods && !/^[gmsiy]*$/.test(mods)) raise(start, "Invalid regexp flag");
+    try {
+      var value = new RegExp(content, mods);
+    } catch (e) {
+      if (e instanceof SyntaxError) raise(start, e.message);
+      raise(e);
+    }
+    return finishToken(_regexp, value);
+  }
+
+  // Read an integer in the given radix. Return null if zero digits
+  // were read, the integer value otherwise. When `len` is given, this
+  // will return `null` unless the integer has exactly `len` digits.
+
+  function readInt(radix, len) {
+    var start = tokPos, total = 0;
+    for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
+      var code = input.charCodeAt(tokPos), val;
+      if (code >= 97) val = code - 97 + 10; // a
+      else if (code >= 65) val = code - 65 + 10; // A
+      else if (code >= 48 && code <= 57) val = code - 48; // 0-9
+      else val = Infinity;
+      if (val >= radix) break;
+      ++tokPos;
+      total = total * radix + val;
+    }
+    if (tokPos === start || len != null && tokPos - start !== len) return null;
+
+    return total;
+  }
+
+  function readHexNumber() {
+    tokPos += 2; // 0x
+    var val = readInt(16);
+    if (val == null) raise(tokStart + 2, "Expected hexadecimal number");
+    if (isIdentifierStart(input.charCodeAt(tokPos))) raise(tokPos, "Identifier directly after number");
+    return finishToken(_num, val);
+  }
+
+  // Read an integer, octal integer, or floating-point number.
+
+  function readNumber(startsWithDot) {
+    var start = tokPos, isFloat = false, octal = input.charCodeAt(tokPos) === 48;
+    if (!startsWithDot && readInt(10) === null) raise(start, "Invalid number");
+    if (input.charCodeAt(tokPos) === 46) {
+      ++tokPos;
+      readInt(10);
+      isFloat = true;
+    }
+    var next = input.charCodeAt(tokPos);
+    if (next === 69 || next === 101) { // 'eE'
+      next = input.charCodeAt(++tokPos);
+      if (next === 43 || next === 45) ++tokPos; // '+-'
+      if (readInt(10) === null) raise(start, "Invalid number");
+      isFloat = true;
+    }
+    if (isIdentifierStart(input.charCodeAt(tokPos))) raise(tokPos, "Identifier directly after number");
+
+    var str = input.slice(start, tokPos), val;
+    if (isFloat) val = parseFloat(str);
+    else if (!octal || str.length === 1) val = parseInt(str, 10);
+    else if (/[89]/.test(str) || strict) raise(start, "Invalid number");
+    else val = parseInt(str, 8);
+    return finishToken(_num, val);
+  }
+
+  // Read a string value, interpreting backslash-escapes.
+
+  function readString(quote) {
+    tokPos++;
+    var out = "";
+    for (;;) {
+      if (tokPos >= inputLen) raise(tokStart, "Unterminated string constant");
+      var ch = input.charCodeAt(tokPos);
+      if (ch === quote) {
+        ++tokPos;
+        return finishToken(_string, out);
+      }
+      if (ch === 92) { // '\'
+        ch = input.charCodeAt(++tokPos);
+        var octal = /^[0-7]+/.exec(input.slice(tokPos, tokPos + 3));
+        if (octal) octal = octal[0];
+        while (octal && parseInt(octal, 8) > 255) octal = octal.slice(0, -1);
+        if (octal === "0") octal = null;
+        ++tokPos;
+        if (octal) {
+          if (strict) raise(tokPos - 2, "Octal literal in strict mode");
+          out += String.fromCharCode(parseInt(octal, 8));
+          tokPos += octal.length - 1;
+        } else {
+          switch (ch) {
+          case 110: out += "\n"; break; // 'n' -> '\n'
+          case 114: out += "\r"; break; // 'r' -> '\r'
+          case 120: out += String.fromCharCode(readHexChar(2)); break; // 'x'
+          case 117: out += String.fromCharCode(readHexChar(4)); break; // 'u'
+          case 85: out += String.fromCharCode(readHexChar(8)); break; // 'U'
+          case 116: out += "\t"; break; // 't' -> '\t'
+          case 98: out += "\b"; break; // 'b' -> '\b'
+          case 118: out += "\u000b"; break; // 'v' -> '\u000b'
+          case 102: out += "\f"; break; // 'f' -> '\f'
+          case 48: out += "\0"; break; // 0 -> '\0'
+          case 13: if (input.charCodeAt(tokPos) === 10) ++tokPos; // '\r\n'
+          case 10: // ' \n'
+            if (options.locations) { tokLineStart = tokPos; ++tokCurLine; }
+            break;
+          default: out += String.fromCharCode(ch); break;
+          }
+        }
+      } else {
+        if (ch === 13 || ch === 10 || ch === 8232 || ch === 8233) raise(tokStart, "Unterminated string constant");
+        out += String.fromCharCode(ch); // '\'
+        ++tokPos;
+      }
+    }
+  }
+
+  // Used to read character escape sequences ('\x', '\u', '\U').
+
+  function readHexChar(len) {
+    var n = readInt(16, len);
+    if (n === null) raise(tokStart, "Bad character escape sequence");
+    return n;
+  }
+
+  // Used to signal to callers of `readWord1` whether the word
+  // contained any escape sequences. This is needed because words with
+  // escape sequences must not be interpreted as keywords.
+
+  var containsEsc;
+
+  // Read an identifier, and return it as a string. Sets `containsEsc`
+  // to whether the word contained a '\u' escape.
+  //
+  // Only builds up the word character-by-character when it actually
+  // containeds an escape, as a micro-optimization.
+
+  function readWord1() {
+    containsEsc = false;
+    var word, first = true, start = tokPos;
+    for (;;) {
+      var ch = input.charCodeAt(tokPos);
+      if (isIdentifierChar(ch)) {
+        if (containsEsc) word += input.charAt(tokPos);
+        ++tokPos;
+      } else if (ch === 92) { // "\"
+        if (!containsEsc) word = input.slice(start, tokPos);
+        containsEsc = true;
+        if (input.charCodeAt(++tokPos) != 117) // "u"
+          raise(tokPos, "Expecting Unicode escape sequence \\uXXXX");
+        ++tokPos;
+        var esc = readHexChar(4);
+        var escStr = String.fromCharCode(esc);
+        if (!escStr) raise(tokPos - 1, "Invalid Unicode escape");
+        if (!(first ? isIdentifierStart(esc) : isIdentifierChar(esc)))
+          raise(tokPos - 4, "Invalid Unicode escape");
+        word += escStr;
+      } else {
+        break;
+      }
+      first = false;
+    }
+    return containsEsc ? word : input.slice(start, tokPos);
+  }
+
+  // Read an identifier or keyword token. Will check for reserved
+  // words when necessary.
+
+  function readWord() {
+    var word = readWord1();
+    var type = _name;
+    if (!containsEsc && isKeyword(word))
+      type = keywordTypes[word];
+    return finishToken(type, word);
+  }
+
+  // ## Parser
+
+  // A recursive descent parser operates by defining functions for all
+  // syntactic elements, and recursively calling those, each function
+  // advancing the input stream and returning an AST node. Precedence
+  // of constructs (for example, the fact that `!x[1]` means `!(x[1])`
+  // instead of `(!x)[1]` is handled by the fact that the parser
+  // function that parses unary prefix operators is called first, and
+  // in turn calls the function that parses `[]` subscripts — that
+  // way, it'll receive the node for `x[1]` already parsed, and wraps
+  // *that* in the unary operator node.
+  //
+  // Acorn uses an [operator precedence parser][opp] to handle binary
+  // operator precedence, because it is much more compact than using
+  // the technique outlined above, which uses different, nesting
+  // functions to specify precedence, for all of the ten binary
+  // precedence levels that JavaScript defines.
+  //
+  // [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
+
+  // ### Parser utilities
+
+  // Continue to the next token.
+
+  function next() {
+    lastStart = tokStart;
+    lastEnd = tokEnd;
+    lastEndLoc = tokEndLoc;
+    readToken();
+  }
+
+  // Enter strict mode. Re-reads the next token to please pedantic
+  // tests ("use strict"; 010; -- should fail).
+
+  function setStrict(strct) {
+    strict = strct;
+    tokPos = tokStart;
+    if (options.locations) {
+      while (tokPos < tokLineStart) {
+        tokLineStart = input.lastIndexOf("\n", tokLineStart - 2) + 1;
+        --tokCurLine;
+      }
+    }
+    skipSpace();
+    readToken();
+  }
+
+  // Start an AST node, attaching a start offset.
+
+  function node_t() {
+    this.type = null;
+    this.start = tokStart;
+    this.end = null;
+  }
+
+  function node_loc_t() {
+    this.start = tokStartLoc;
+    this.end = null;
+    if (sourceFile !== null) this.source = sourceFile;
+  }
+
+  function startNode() {
+    var node = new node_t();
+    if (options.locations)
+      node.loc = new node_loc_t();
+    if (options.directSourceFile)
+      node.sourceFile = options.directSourceFile;
+    if (options.ranges)
+      node.range = [tokStart, 0];
+    return node;
+  }
+
+  // Start a node whose start offset information should be based on
+  // the start of another node. For example, a binary operator node is
+  // only started after its left-hand side has already been parsed.
+
+  function startNodeFrom(other) {
+    var node = new node_t();
+    node.start = other.start;
+    if (options.locations) {
+      node.loc = new node_loc_t();
+      node.loc.start = other.loc.start;
+    }
+    if (options.ranges)
+      node.range = [other.range[0], 0];
+
+    return node;
+  }
+
+  // Finish an AST node, adding `type` and `end` properties.
+
+  function finishNode(node, type) {
+    node.type = type;
+    node.end = lastEnd;
+    if (options.locations)
+      node.loc.end = lastEndLoc;
+    if (options.ranges)
+      node.range[1] = lastEnd;
+    return node;
+  }
+
+  // Test whether a statement node is the string literal `"use strict"`.
+
+  function isUseStrict(stmt) {
+    return options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" &&
+      stmt.expression.type === "Literal" && stmt.expression.value === "use strict";
+  }
+
+  // Predicate that tests whether the next token is of the given
+  // type, and if yes, consumes it as a side effect.
+
+  function eat(type) {
+    if (tokType === type) {
+      next();
+      return true;
+    }
+  }
+
+  // Test whether a semicolon can be inserted at the current position.
+
+  function canInsertSemicolon() {
+    return !options.strictSemicolons &&
+      (tokType === _eof || tokType === _braceR || newline.test(input.slice(lastEnd, tokStart)));
+  }
+
+  // Consume a semicolon, or, failing that, see if we are allowed to
+  // pretend that there is a semicolon at this position.
+
+  function semicolon() {
+    if (!eat(_semi) && !canInsertSemicolon()) unexpected();
+  }
+
+  // Expect a token of a given type. If found, consume it, otherwise,
+  // raise an unexpected token error.
+
+  function expect(type) {
+    if (tokType === type) next();
+    else unexpected();
+  }
+
+  // Raise an unexpected token error.
+
+  function unexpected() {
+    raise(tokStart, "Unexpected token");
+  }
+
+  // Verify that a node is an lval — something that can be assigned
+  // to.
+
+  function checkLVal(expr) {
+    if (expr.type !== "Identifier" && expr.type !== "MemberExpression")
+      raise(expr.start, "Assigning to rvalue");
+    if (strict && expr.type === "Identifier" && isStrictBadIdWord(expr.name))
+      raise(expr.start, "Assigning to " + expr.name + " in strict mode");
+  }
+
+  // ### Statement parsing
+
+  // Parse a program. Initializes the parser, reads any number of
+  // statements, and wraps them in a Program node.  Optionally takes a
+  // `program` argument.  If present, the statements will be appended
+  // to its body instead of creating a new node.
+
+  function parseTopLevel(program) {
+    lastStart = lastEnd = tokPos;
+    if (options.locations) lastEndLoc = new line_loc_t;
+    inFunction = strict = null;
+    labels = [];
+    readToken();
+
+    var node = program || startNode(), first = true;
+    if (!program) node.body = [];
+    while (tokType !== _eof) {
+      var stmt = parseStatement();
+      node.body.push(stmt);
+      if (first && isUseStrict(stmt)) setStrict(true);
+      first = false;
+    }
+    return finishNode(node, "Program");
+  }
+
+  var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"};
+
+  // Parse a single statement.
+  //
+  // If expecting a statement and finding a slash operator, parse a
+  // regular expression literal. This is to handle cases like
+  // `if (foo) /blah/.exec(foo);`, where looking at the previous token
+  // does not help.
+
+  function parseStatement() {
+    if (tokType === _slash || tokType === _assign && tokVal == "/=")
+      readToken(true);
+
+    var starttype = tokType, node = startNode();
+
+    // Most types of statements are recognized by the keyword they
+    // start with. Many are trivial to parse, some require a bit of
+    // complexity.
+
+    switch (starttype) {
+    case _break: case _continue:
+      next();
+      var isBreak = starttype === _break;
+      if (eat(_semi) || canInsertSemicolon()) node.label = null;
+      else if (tokType !== _name) unexpected();
+      else {
+        node.label = parseIdent();
+        semicolon();
+      }
+
+      // Verify that there is an actual destination to break or
+      // continue to.
+      for (var i = 0; i < labels.length; ++i) {
+        var lab = labels[i];
+        if (node.label == null || lab.name === node.label.name) {
+          if (lab.kind != null && (isBreak || lab.kind === "loop")) break;
+          if (node.label && isBreak) break;
+        }
+      }
+      if (i === labels.length) raise(node.start, "Unsyntactic " + starttype.keyword);
+      return finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
+
+    case _debugger:
+      next();
+      semicolon();
+      return finishNode(node, "DebuggerStatement");
+
+    case _do:
+      next();
+      labels.push(loopLabel);
+      node.body = parseStatement();
+      labels.pop();
+      expect(_while);
+      node.test = parseParenExpression();
+      semicolon();
+      return finishNode(node, "DoWhileStatement");
+
+      // Disambiguating between a `for` and a `for`/`in` loop is
+      // non-trivial. Basically, we have to parse the init `var`
+      // statement or expression, disallowing the `in` operator (see
+      // the second parameter to `parseExpression`), and then check
+      // whether the next token is `in`. When there is no init part
+      // (semicolon immediately after the opening parenthesis), it is
+      // a regular `for` loop.
+
+    case _for:
+      next();
+      labels.push(loopLabel);
+      expect(_parenL);
+      if (tokType === _semi) return parseFor(node, null);
+      if (tokType === _var) {
+        var init = startNode();
+        next();
+        parseVar(init, true);
+        finishNode(init, "VariableDeclaration");
+        if (init.declarations.length === 1 && eat(_in))
+          return parseForIn(node, init);
+        return parseFor(node, init);
+      }
+      var init = parseExpression(false, true);
+      if (eat(_in)) {checkLVal(init); return parseForIn(node, init);}
+      return parseFor(node, init);
+
+    case _function:
+      next();
+      return parseFunction(node, true);
+
+    case _if:
+      next();
+      node.test = parseParenExpression();
+      node.consequent = parseStatement();
+      node.alternate = eat(_else) ? parseStatement() : null;
+      return finishNode(node, "IfStatement");
+
+    case _return:
+      if (!inFunction && !options.allowReturnOutsideFunction)
+        raise(tokStart, "'return' outside of function");
+      next();
+
+      // In `return` (and `break`/`continue`), the keywords with
+      // optional arguments, we eagerly look for a semicolon or the
+      // possibility to insert one.
+
+      if (eat(_semi) || canInsertSemicolon()) node.argument = null;
+      else { node.argument = parseExpression(); semicolon(); }
+      return finishNode(node, "ReturnStatement");
+
+    case _switch:
+      next();
+      node.discriminant = parseParenExpression();
+      node.cases = [];
+      expect(_braceL);
+      labels.push(switchLabel);
+
+      // Statements under must be grouped (by label) in SwitchCase
+      // nodes. `cur` is used to keep the node that we are currently
+      // adding statements to.
+
+      for (var cur, sawDefault; tokType != _braceR;) {
+        if (tokType === _case || tokType === _default) {
+          var isCase = tokType === _case;
+          if (cur) finishNode(cur, "SwitchCase");
+          node.cases.push(cur = startNode());
+          cur.consequent = [];
+          next();
+          if (isCase) cur.test = parseExpression();
+          else {
+            if (sawDefault) raise(lastStart, "Multiple default clauses"); sawDefault = true;
+            cur.test = null;
+          }
+          expect(_colon);
+        } else {
+          if (!cur) unexpected();
+          cur.consequent.push(parseStatement());
+        }
+      }
+      if (cur) finishNode(cur, "SwitchCase");
+      next(); // Closing brace
+      labels.pop();
+      return finishNode(node, "SwitchStatement");
+
+    case _throw:
+      next();
+      if (newline.test(input.slice(lastEnd, tokStart)))
+        raise(lastEnd, "Illegal newline after throw");
+      node.argument = parseExpression();
+      semicolon();
+      return finishNode(node, "ThrowStatement");
+
+    case _try:
+      next();
+      node.block = parseBlock();
+      node.handler = null;
+      if (tokType === _catch) {
+        var clause = startNode();
+        next();
+        expect(_parenL);
+        clause.param = parseIdent();
+        if (strict && isStrictBadIdWord(clause.param.name))
+          raise(clause.param.start, "Binding " + clause.param.name + " in strict mode");
+        expect(_parenR);
+        clause.guard = null;
+        clause.body = parseBlock();
+        node.handler = finishNode(clause, "CatchClause");
+      }
+      node.guardedHandlers = empty;
+      node.finalizer = eat(_finally) ? parseBlock() : null;
+      if (!node.handler && !node.finalizer)
+        raise(node.start, "Missing catch or finally clause");
+      return finishNode(node, "TryStatement");
+
+    case _var:
+      next();
+      parseVar(node);
+      semicolon();
+      return finishNode(node, "VariableDeclaration");
+
+    case _while:
+      next();
+      node.test = parseParenExpression();
+      labels.push(loopLabel);
+      node.body = parseStatement();
+      labels.pop();
+      return finishNode(node, "WhileStatement");
+
+    case _with:
+      if (strict) raise(tokStart, "'with' in strict mode");
+      next();
+      node.object = parseParenExpression();
+      node.body = parseStatement();
+      return finishNode(node, "WithStatement");
+
+    case _braceL:
+      return parseBlock();
+
+    case _semi:
+      next();
+      return finishNode(node, "EmptyStatement");
+
+      // If the statement does not start with a statement keyword or a
+      // brace, it's an ExpressionStatement or LabeledStatement. We
+      // simply start parsing an expression, and afterwards, if the
+      // next token is a colon and the expression was a simple
+      // Identifier node, we switch to interpreting it as a label.
+
+    default:
+      var maybeName = tokVal, expr = parseExpression();
+      if (starttype === _name && expr.type === "Identifier" && eat(_colon)) {
+        for (var i = 0; i < labels.length; ++i)
+          if (labels[i].name === maybeName) raise(expr.start, "Label '" + maybeName + "' is already declared");
+        var kind = tokType.isLoop ? "loop" : tokType === _switch ? "switch" : null;
+        labels.push({name: maybeName, kind: kind});
+        node.body = parseStatement();
+        labels.pop();
+        node.label = expr;
+        return finishNode(node, "LabeledStatement");
+      } else {
+        node.expression = expr;
+        semicolon();
+        return finishNode(node, "ExpressionStatement");
+      }
+    }
+  }
+
+  // Used for constructs like `switch` and `if` that insist on
+  // parentheses around their expression.
+
+  function parseParenExpression() {
+    expect(_parenL);
+    var val = parseExpression();
+    expect(_parenR);
+    return val;
+  }
+
+  // Parse a semicolon-enclosed block of statements, handling `"use
+  // strict"` declarations when `allowStrict` is true (used for
+  // function bodies).
+
+  function parseBlock(allowStrict) {
+    var node = startNode(), first = true, strict = false, oldStrict;
+    node.body = [];
+    expect(_braceL);
+    while (!eat(_braceR)) {
+      var stmt = parseStatement();
+      node.body.push(stmt);
+      if (first && allowStrict && isUseStrict(stmt)) {
+        oldStrict = strict;
+        setStrict(strict = true);
+      }
+      first = false;
+    }
+    if (strict && !oldStrict) setStrict(false);
+    return finishNode(node, "BlockStatement");
+  }
+
+  // Parse a regular `for` loop. The disambiguation code in
+  // `parseStatement` will already have parsed the init statement or
+  // expression.
+
+  function parseFor(node, init) {
+    node.init = init;
+    expect(_semi);
+    node.test = tokType === _semi ? null : parseExpression();
+    expect(_semi);
+    node.update = tokType === _parenR ? null : parseExpression();
+    expect(_parenR);
+    node.body = parseStatement();
+    labels.pop();
+    return finishNode(node, "ForStatement");
+  }
+
+  // Parse a `for`/`in` loop.
+
+  function parseForIn(node, init) {
+    node.left = init;
+    node.right = parseExpression();
+    expect(_parenR);
+    node.body = parseStatement();
+    labels.pop();
+    return finishNode(node, "ForInStatement");
+  }
+
+  // Parse a list of variable declarations.
+
+  function parseVar(node, noIn) {
+    node.declarations = [];
+    node.kind = "var";
+    for (;;) {
+      var decl = startNode();
+      decl.id = parseIdent();
+      if (strict && isStrictBadIdWord(decl.id.name))
+        raise(decl.id.start, "Binding " + decl.id.name + " in strict mode");
+      decl.init = eat(_eq) ? parseExpression(true, noIn) : null;
+      node.declarations.push(finishNode(decl, "VariableDeclarator"));
+      if (!eat(_comma)) break;
+    }
+    return node;
+  }
+
+  // ### Expression parsing
+
+  // These nest, from the most general expression type at the top to
+  // 'atomic', nondivisible expression types at the bottom. Most of
+  // the functions will simply let the function(s) below them parse,
+  // and, *if* the syntactic construct they handle is present, wrap
+  // the AST node that the inner parser gave them in another node.
+
+  // Parse a full expression. The arguments are used to forbid comma
+  // sequences (in argument lists, array literals, or object literals)
+  // or the `in` operator (in for loops initalization expressions).
+
+  function parseExpression(noComma, noIn) {
+    var expr = parseMaybeAssign(noIn);
+    if (!noComma && tokType === _comma) {
+      var node = startNodeFrom(expr);
+      node.expressions = [expr];
+      while (eat(_comma)) node.expressions.push(parseMaybeAssign(noIn));
+      return finishNode(node, "SequenceExpression");
+    }
+    return expr;
+  }
+
+  // Parse an assignment expression. This includes applications of
+  // operators like `+=`.
+
+  function parseMaybeAssign(noIn) {
+    var left = parseMaybeConditional(noIn);
+    if (tokType.isAssign) {
+      var node = startNodeFrom(left);
+      node.operator = tokVal;
+      node.left = left;
+      next();
+      node.right = parseMaybeAssign(noIn);
+      checkLVal(left);
+      return finishNode(node, "AssignmentExpression");
+    }
+    return left;
+  }
+
+  // Parse a ternary conditional (`?:`) operator.
+
+  function parseMaybeConditional(noIn) {
+    var expr = parseExprOps(noIn);
+    if (eat(_question)) {
+      var node = startNodeFrom(expr);
+      node.test = expr;
+      node.consequent = parseExpression(true);
+      expect(_colon);
+      node.alternate = parseExpression(true, noIn);
+      return finishNode(node, "ConditionalExpression");
+    }
+    return expr;
+  }
+
+  // Start the precedence parser.
+
+  function parseExprOps(noIn) {
+    return parseExprOp(parseMaybeUnary(), -1, noIn);
+  }
+
+  // Parse binary operators with the operator precedence parsing
+  // algorithm. `left` is the left-hand side of the operator.
+  // `minPrec` provides context that allows the function to stop and
+  // defer further parser to one of its callers when it encounters an
+  // operator that has a lower precedence than the set it is parsing.
+
+  function parseExprOp(left, minPrec, noIn) {
+    var prec = tokType.binop;
+    if (prec != null && (!noIn || tokType !== _in)) {
+      if (prec > minPrec) {
+        var node = startNodeFrom(left);
+        node.left = left;
+        node.operator = tokVal;
+        var op = tokType;
+        next();
+        node.right = parseExprOp(parseMaybeUnary(), prec, noIn);
+        var exprNode = finishNode(node, (op === _logicalOR || op === _logicalAND) ? "LogicalExpression" : "BinaryExpression");
+        return parseExprOp(exprNode, minPrec, noIn);
+      }
+    }
+    return left;
+  }
+
+  // Parse unary operators, both prefix and postfix.
+
+  function parseMaybeUnary() {
+    if (tokType.prefix) {
+      var node = startNode(), update = tokType.isUpdate;
+      node.operator = tokVal;
+      node.prefix = true;
+      tokRegexpAllowed = true;
+      next();
+      node.argument = parseMaybeUnary();
+      if (update) checkLVal(node.argument);
+      else if (strict && node.operator === "delete" &&
+               node.argument.type === "Identifier")
+        raise(node.start, "Deleting local variable in strict mode");
+      return finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
+    }
+    var expr = parseExprSubscripts();
+    while (tokType.postfix && !canInsertSemicolon()) {
+      var node = startNodeFrom(expr);
+      node.operator = tokVal;
+      node.prefix = false;
+      node.argument = expr;
+      checkLVal(expr);
+      next();
+      expr = finishNode(node, "UpdateExpression");
+    }
+    return expr;
+  }
+
+  // Parse call, dot, and `[]`-subscript expressions.
+
+  function parseExprSubscripts() {
+    return parseSubscripts(parseExprAtom());
+  }
+
+  function parseSubscripts(base, noCalls) {
+    if (eat(_dot)) {
+      var node = startNodeFrom(base);
+      node.object = base;
+      node.property = parseIdent(true);
+      node.computed = false;
+      return parseSubscripts(finishNode(node, "MemberExpression"), noCalls);
+    } else if (eat(_bracketL)) {
+      var node = startNodeFrom(base);
+      node.object = base;
+      node.property = parseExpression();
+      node.computed = true;
+      expect(_bracketR);
+      return parseSubscripts(finishNode(node, "MemberExpression"), noCalls);
+    } else if (!noCalls && eat(_parenL)) {
+      var node = startNodeFrom(base);
+      node.callee = base;
+      node.arguments = parseExprList(_parenR, false);
+      return parseSubscripts(finishNode(node, "CallExpression"), noCalls);
+    } else return base;
+  }
+
+  // Parse an atomic expression — either a single token that is an
+  // expression, an expression started by a keyword like `function` or
+  // `new`, or an expression wrapped in punctuation like `()`, `[]`,
+  // or `{}`.
+
+  function parseExprAtom() {
+    switch (tokType) {
+    case _this:
+      var node = startNode();
+      next();
+      return finishNode(node, "ThisExpression");
+    case _name:
+      return parseIdent();
+    case _num: case _string: case _regexp:
+      var node = startNode();
+      node.value = tokVal;
+      node.raw = input.slice(tokStart, tokEnd);
+      next();
+      return finishNode(node, "Literal");
+
+    case _null: case _true: case _false:
+      var node = startNode();
+      node.value = tokType.atomValue;
+      node.raw = tokType.keyword;
+      next();
+      return finishNode(node, "Literal");
+
+    case _parenL:
+      var tokStartLoc1 = tokStartLoc, tokStart1 = tokStart;
+      next();
+      var val = parseExpression();
+      val.start = tokStart1;
+      val.end = tokEnd;
+      if (options.locations) {
+        val.loc.start = tokStartLoc1;
+        val.loc.end = tokEndLoc;
+      }
+      if (options.ranges)
+        val.range = [tokStart1, tokEnd];
+      expect(_parenR);
+      return val;
+
+    case _bracketL:
+      var node = startNode();
+      next();
+      node.elements = parseExprList(_bracketR, true, true);
+      return finishNode(node, "ArrayExpression");
+
+    case _braceL:
+      return parseObj();
+
+    case _function:
+      var node = startNode();
+      next();
+      return parseFunction(node, false);
+
+    case _new:
+      return parseNew();
+
+    default:
+      unexpected();
+    }
+  }
+
+  // New's precedence is slightly tricky. It must allow its argument
+  // to be a `[]` or dot subscript expression, but not a call — at
+  // least, not without wrapping it in parentheses. Thus, it uses the
+
+  function parseNew() {
+    var node = startNode();
+    next();
+    node.callee = parseSubscripts(parseExprAtom(), true);
+    if (eat(_parenL)) node.arguments = parseExprList(_parenR, false);
+    else node.arguments = empty;
+    return finishNode(node, "NewExpression");
+  }
+
+  // Parse an object literal.
+
+  function parseObj() {
+    var node = startNode(), first = true, sawGetSet = false;
+    node.properties = [];
+    next();
+    while (!eat(_braceR)) {
+      if (!first) {
+        expect(_comma);
+        if (options.allowTrailingCommas && eat(_braceR)) break;
+      } else first = false;
+
+      var prop = {key: parsePropertyName()}, isGetSet = false, kind;
+      if (eat(_colon)) {
+        prop.value = parseExpression(true);
+        kind = prop.kind = "init";
+      } else if (options.ecmaVersion >= 5 && prop.key.type === "Identifier" &&
+                 (prop.key.name === "get" || prop.key.name === "set")) {
+        isGetSet = sawGetSet = true;
+        kind = prop.kind = prop.key.name;
+        prop.key = parsePropertyName();
+        if (tokType !== _parenL) unexpected();
+        prop.value = parseFunction(startNode(), false);
+      } else unexpected();
+
+      // getters and setters are not allowed to clash — either with
+      // each other or with an init property — and in strict mode,
+      // init properties are also not allowed to be repeated.
+
+      if (prop.key.type === "Identifier" && (strict || sawGetSet)) {
+        for (var i = 0; i < node.properties.length; ++i) {
+          var other = node.properties[i];
+          if (other.key.name === prop.key.name) {
+            var conflict = kind == other.kind || isGetSet && other.kind === "init" ||
+              kind === "init" && (other.kind === "get" || other.kind === "set");
+            if (conflict && !strict && kind === "init" && other.kind === "init") conflict = false;
+            if (conflict) raise(prop.key.start, "Redefinition of property");
+          }
+        }
+      }
+      node.properties.push(prop);
+    }
+    return finishNode(node, "ObjectExpression");
+  }
+
+  function parsePropertyName() {
+    if (tokType === _num || tokType === _string) return parseExprAtom();
+    return parseIdent(true);
+  }
+
+  // Parse a function declaration or literal (depending on the
+  // `isStatement` parameter).
+
+  function parseFunction(node, isStatement) {
+    if (tokType === _name) node.id = parseIdent();
+    else if (isStatement) unexpected();
+    else node.id = null;
+    node.params = [];
+    var first = true;
+    expect(_parenL);
+    while (!eat(_parenR)) {
+      if (!first) expect(_comma); else first = false;
+      node.params.push(parseIdent());
+    }
+
+    // Start a new scope with regard to labels and the `inFunction`
+    // flag (restore them to their old value afterwards).
+    var oldInFunc = inFunction, oldLabels = labels;
+    inFunction = true; labels = [];
+    node.body = parseBlock(true);
+    inFunction = oldInFunc; labels = oldLabels;
+
+    // If this is a strict mode function, verify that argument names
+    // are not repeated, and it does not try to bind the words `eval`
+    // or `arguments`.
+    if (strict || node.body.body.length && isUseStrict(node.body.body[0])) {
+      for (var i = node.id ? -1 : 0; i < node.params.length; ++i) {
+        var id = i < 0 ? node.id : node.params[i];
+        if (isStrictReservedWord(id.name) || isStrictBadIdWord(id.name))
+          raise(id.start, "Defining '" + id.name + "' in strict mode");
+        if (i >= 0) for (var j = 0; j < i; ++j) if (id.name === node.params[j].name)
+          raise(id.start, "Argument name clash in strict mode");
+      }
+    }
+
+    return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
+  }
+
+  // Parses a comma-separated list of expressions, and returns them as
+  // an array. `close` is the token type that ends the list, and
+  // `allowEmpty` can be turned on to allow subsequent commas with
+  // nothing in between them to be parsed as `null` (which is needed
+  // for array literals).
+
+  function parseExprList(close, allowTrailingComma, allowEmpty) {
+    var elts = [], first = true;
+    while (!eat(close)) {
+      if (!first) {
+        expect(_comma);
+        if (allowTrailingComma && options.allowTrailingCommas && eat(close)) break;
+      } else first = false;
+
+      if (allowEmpty && tokType === _comma) elts.push(null);
+      else elts.push(parseExpression(true));
+    }
+    return elts;
+  }
+
+  // Parse the next token as an identifier. If `liberal` is true (used
+  // when parsing properties), it will also convert keywords into
+  // identifiers.
+
+  function parseIdent(liberal) {
+    var node = startNode();
+    if (liberal && options.forbidReserved == "everywhere") liberal = false;
+    if (tokType === _name) {
+      if (!liberal &&
+          (options.forbidReserved &&
+           (options.ecmaVersion === 3 ? isReservedWord3 : isReservedWord5)(tokVal) ||
+           strict && isStrictReservedWord(tokVal)) &&
+          input.slice(tokStart, tokEnd).indexOf("\\") == -1)
+        raise(tokStart, "The keyword '" + tokVal + "' is reserved");
+      node.name = tokVal;
+    } else if (liberal && tokType.keyword) {
+      node.name = tokType.keyword;
+    } else {
+      unexpected();
+    }
+    tokRegexpAllowed = false;
+    next();
+    return finishNode(node, "Identifier");
+  }
+
+});
diff --git a/app/gui/html/vendor/codemirror/test/lint/lint.js b/app/gui/html/vendor/codemirror/test/lint/lint.js
new file mode 100644
index 0000000..a65deb6
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/lint/lint.js
@@ -0,0 +1,161 @@
+/*
+ Simple linter, based on the Acorn [1] parser module
+
+ All of the existing linters either cramp my style or have huge
+ dependencies (Closure). So here's a very simple, non-invasive one
+ that only spots
+
+  - missing semicolons and trailing commas
+  - variables or properties that are reserved words
+  - assigning to a variable you didn't declare
+  - access to non-whitelisted globals
+    (use a '// declare global: foo, bar' comment to declare extra
+    globals in a file)
+
+ [1]: https://github.com/marijnh/acorn/
+*/
+
+var topAllowedGlobals = Object.create(null);
+("Error RegExp Number String Array Function Object Math Date undefined " +
+ "parseInt parseFloat Infinity NaN isNaN " +
+ "window document navigator prompt alert confirm console " +
+ "FileReader Worker postMessage importScripts " +
+ "setInterval clearInterval setTimeout clearTimeout " +
+ "CodeMirror " +
+ "test exports require module define")
+  .split(" ").forEach(function(n) { topAllowedGlobals[n] = true; });
+
+var fs = require("fs"), acorn = require("./acorn.js"), walk = require("./walk.js");
+
+var scopePasser = walk.make({
+  ScopeBody: function(node, prev, c) { c(node, node.scope); }
+});
+
+function checkFile(fileName) {
+  var file = fs.readFileSync(fileName, "utf8"), notAllowed;
+  if (notAllowed = file.match(/[\x00-\x08\x0b\x0c\x0e-\x19\uFEFF\t]|[ \t]\n/)) {
+    var msg;
+    if (notAllowed[0] == "\t") msg = "Found tab character";
+    else if (notAllowed[0].indexOf("\n") > -1) msg = "Trailing whitespace";
+    else msg = "Undesirable character " + notAllowed[0].charCodeAt(0);
+    var info = acorn.getLineInfo(file, notAllowed.index);
+    fail(msg + " at line " + info.line + ", column " + info.column, {source: fileName});
+  }
+  
+  var globalsSeen = Object.create(null);
+
+  try {
+    var parsed = acorn.parse(file, {
+      locations: true,
+      ecmaVersion: 3,
+      strictSemicolons: true,
+      allowTrailingCommas: false,
+      forbidReserved: "everywhere",
+      sourceFile: fileName
+    });
+  } catch (e) {
+    fail(e.message, {source: fileName});
+    return;
+  }
+
+  var scopes = [];
+
+  walk.simple(parsed, {
+    ScopeBody: function(node, scope) {
+      node.scope = scope;
+      scopes.push(scope);
+    }
+  }, walk.scopeVisitor, {vars: Object.create(null)});
+
+  var ignoredGlobals = Object.create(null);
+
+  function inScope(name, scope) {
+    for (var cur = scope; cur; cur = cur.prev)
+      if (name in cur.vars) return true;
+  }
+  function checkLHS(node, scope) {
+    if (node.type == "Identifier" && !(node.name in ignoredGlobals) &&
+        !inScope(node.name, scope)) {
+      ignoredGlobals[node.name] = true;
+      fail("Assignment to global variable", node.loc);
+    }
+  }
+
+  walk.simple(parsed, {
+    UpdateExpression: function(node, scope) {checkLHS(node.argument, scope);},
+    AssignmentExpression: function(node, scope) {checkLHS(node.left, scope);},
+    Identifier: function(node, scope) {
+      if (node.name == "arguments") return;
+      // Mark used identifiers
+      for (var cur = scope; cur; cur = cur.prev)
+        if (node.name in cur.vars) {
+          cur.vars[node.name].used = true;
+          return;
+        }
+      globalsSeen[node.name] = node.loc;
+    },
+    FunctionExpression: function(node) {
+      if (node.id) fail("Named function expression", node.loc);
+    },
+    ForStatement: function(node) {
+      checkReusedIndex(node);
+    },
+    MemberExpression: function(node) {
+      if (node.object.type == "Identifier" && node.object.name == "console" && !node.computed)
+        fail("Found console." + node.property.name, node.loc);
+    },
+    DebuggerStatement: function(node) {
+      fail("Found debugger statement", node.loc);
+    }
+  }, scopePasser);
+
+  function checkReusedIndex(node) {
+    if (!node.init || node.init.type != "VariableDeclaration") return;
+    var name = node.init.declarations[0].id.name;
+    walk.recursive(node.body, null, {
+      Function: function() {},
+      VariableDeclaration: function(node, st, c) {
+        for (var i = 0; i < node.declarations.length; i++)
+          if (node.declarations[i].id.name == name)
+            fail("redefined loop variable", node.declarations[i].id.loc);
+        walk.base.VariableDeclaration(node, st, c);
+      }
+    });
+  }
+
+  var allowedGlobals = Object.create(topAllowedGlobals), m;
+  if (m = file.match(/\/\/ declare global:\s+(.*)/))
+    m[1].split(/,\s*/g).forEach(function(n) { allowedGlobals[n] = true; });
+  for (var glob in globalsSeen)
+    if (!(glob in allowedGlobals))
+      fail("Access to global variable " + glob + ". Add a '// declare global: " + glob +
+           "' comment or add this variable in test/lint/lint.js.", globalsSeen[glob]);
+
+  for (var i = 0; i < scopes.length; ++i) {
+    var scope = scopes[i];
+    for (var name in scope.vars) {
+      var info = scope.vars[name];
+      if (!info.used && info.type != "catch clause" && info.type != "function name" && name.charAt(0) != "_")
+        fail("Unused " + info.type + " " + name, info.node.loc);
+    }
+  }
+}
+
+var failed = false;
+function fail(msg, pos) {
+  if (pos.start) msg += " (" + pos.start.line + ":" + pos.start.column + ")";
+  console.log(pos.source + ": " + msg);
+  failed = true;
+}
+
+function checkDir(dir) {
+  fs.readdirSync(dir).forEach(function(file) {
+    var fname = dir + "/" + file;
+    if (/\.js$/.test(file)) checkFile(fname);
+    else if (file != "dep" && fs.lstatSync(fname).isDirectory()) checkDir(fname);
+  });
+}
+
+exports.checkDir = checkDir;
+exports.checkFile = checkFile;
+exports.success = function() { return !failed; };
diff --git a/app/gui/html/vendor/codemirror/test/lint/walk.js b/app/gui/html/vendor/codemirror/test/lint/walk.js
new file mode 100644
index 0000000..4c0d9a7
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/lint/walk.js
@@ -0,0 +1,313 @@
+// AST walker module for Mozilla Parser API compatible trees
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") return mod(exports); // CommonJS
+  if (typeof define == "function" && define.amd) return define(["exports"], mod); // AMD
+  mod((this.acorn || (this.acorn = {})).walk = {}); // Plain browser env
+})(function(exports) {
+  "use strict";
+
+  // A simple walk is one where you simply specify callbacks to be
+  // called on specific nodes. The last two arguments are optional. A
+  // simple use would be
+  //
+  //     walk.simple(myTree, {
+  //         Expression: function(node) { ... }
+  //     });
+  //
+  // to do something with all expressions. All Parser API node types
+  // can be used to identify node types, as well as Expression,
+  // Statement, and ScopeBody, which denote categories of nodes.
+  //
+  // The base argument can be used to pass a custom (recursive)
+  // walker, and state can be used to give this walked an initial
+  // state.
+  exports.simple = function(node, visitors, base, state) {
+    if (!base) base = exports.base;
+    function c(node, st, override) {
+      var type = override || node.type, found = visitors[type];
+      base[type](node, st, c);
+      if (found) found(node, st);
+    }
+    c(node, state);
+  };
+
+  // A recursive walk is one where your functions override the default
+  // walkers. They can modify and replace the state parameter that's
+  // threaded through the walk, and can opt how and whether to walk
+  // their child nodes (by calling their third argument on these
+  // nodes).
+  exports.recursive = function(node, state, funcs, base) {
+    var visitor = funcs ? exports.make(funcs, base) : base;
+    function c(node, st, override) {
+      visitor[override || node.type](node, st, c);
+    }
+    c(node, state);
+  };
+
+  function makeTest(test) {
+    if (typeof test == "string")
+      return function(type) { return type == test; };
+    else if (!test)
+      return function() { return true; };
+    else
+      return test;
+  }
+
+  function Found(node, state) { this.node = node; this.state = state; }
+
+  // Find a node with a given start, end, and type (all are optional,
+  // null can be used as wildcard). Returns a {node, state} object, or
+  // undefined when it doesn't find a matching node.
+  exports.findNodeAt = function(node, start, end, test, base, state) {
+    test = makeTest(test);
+    try {
+      if (!base) base = exports.base;
+      var c = function(node, st, override) {
+        var type = override || node.type;
+        if ((start == null || node.start <= start) &&
+            (end == null || node.end >= end))
+          base[type](node, st, c);
+        if (test(type, node) &&
+            (start == null || node.start == start) &&
+            (end == null || node.end == end))
+          throw new Found(node, st);
+      };
+      c(node, state);
+    } catch (e) {
+      if (e instanceof Found) return e;
+      throw e;
+    }
+  };
+
+  // Find the innermost node of a given type that contains the given
+  // position. Interface similar to findNodeAt.
+  exports.findNodeAround = function(node, pos, test, base, state) {
+    test = makeTest(test);
+    try {
+      if (!base) base = exports.base;
+      var c = function(node, st, override) {
+        var type = override || node.type;
+        if (node.start > pos || node.end < pos) return;
+        base[type](node, st, c);
+        if (test(type, node)) throw new Found(node, st);
+      };
+      c(node, state);
+    } catch (e) {
+      if (e instanceof Found) return e;
+      throw e;
+    }
+  };
+
+  // Find the outermost matching node after a given position.
+  exports.findNodeAfter = function(node, pos, test, base, state) {
+    test = makeTest(test);
+    try {
+      if (!base) base = exports.base;
+      var c = function(node, st, override) {
+        if (node.end < pos) return;
+        var type = override || node.type;
+        if (node.start >= pos && test(type, node)) throw new Found(node, st);
+        base[type](node, st, c);
+      };
+      c(node, state);
+    } catch (e) {
+      if (e instanceof Found) return e;
+      throw e;
+    }
+  };
+
+  // Find the outermost matching node before a given position.
+  exports.findNodeBefore = function(node, pos, test, base, state) {
+    test = makeTest(test);
+    if (!base) base = exports.base;
+    var max;
+    var c = function(node, st, override) {
+      if (node.start > pos) return;
+      var type = override || node.type;
+      if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node))
+        max = new Found(node, st);
+      base[type](node, st, c);
+    };
+    c(node, state);
+    return max;
+  };
+
+  // Used to create a custom walker. Will fill in all missing node
+  // type properties with the defaults.
+  exports.make = function(funcs, base) {
+    if (!base) base = exports.base;
+    var visitor = {};
+    for (var type in base) visitor[type] = base[type];
+    for (var type in funcs) visitor[type] = funcs[type];
+    return visitor;
+  };
+
+  function skipThrough(node, st, c) { c(node, st); }
+  function ignore(_node, _st, _c) {}
+
+  // Node walkers.
+
+  var base = exports.base = {};
+  base.Program = base.BlockStatement = function(node, st, c) {
+    for (var i = 0; i < node.body.length; ++i)
+      c(node.body[i], st, "Statement");
+  };
+  base.Statement = skipThrough;
+  base.EmptyStatement = ignore;
+  base.ExpressionStatement = function(node, st, c) {
+    c(node.expression, st, "Expression");
+  };
+  base.IfStatement = function(node, st, c) {
+    c(node.test, st, "Expression");
+    c(node.consequent, st, "Statement");
+    if (node.alternate) c(node.alternate, st, "Statement");
+  };
+  base.LabeledStatement = function(node, st, c) {
+    c(node.body, st, "Statement");
+  };
+  base.BreakStatement = base.ContinueStatement = ignore;
+  base.WithStatement = function(node, st, c) {
+    c(node.object, st, "Expression");
+    c(node.body, st, "Statement");
+  };
+  base.SwitchStatement = function(node, st, c) {
+    c(node.discriminant, st, "Expression");
+    for (var i = 0; i < node.cases.length; ++i) {
+      var cs = node.cases[i];
+      if (cs.test) c(cs.test, st, "Expression");
+      for (var j = 0; j < cs.consequent.length; ++j)
+        c(cs.consequent[j], st, "Statement");
+    }
+  };
+  base.ReturnStatement = function(node, st, c) {
+    if (node.argument) c(node.argument, st, "Expression");
+  };
+  base.ThrowStatement = function(node, st, c) {
+    c(node.argument, st, "Expression");
+  };
+  base.TryStatement = function(node, st, c) {
+    c(node.block, st, "Statement");
+    if (node.handler) c(node.handler.body, st, "ScopeBody");
+    if (node.finalizer) c(node.finalizer, st, "Statement");
+  };
+  base.WhileStatement = function(node, st, c) {
+    c(node.test, st, "Expression");
+    c(node.body, st, "Statement");
+  };
+  base.DoWhileStatement = base.WhileStatement;
+  base.ForStatement = function(node, st, c) {
+    if (node.init) c(node.init, st, "ForInit");
+    if (node.test) c(node.test, st, "Expression");
+    if (node.update) c(node.update, st, "Expression");
+    c(node.body, st, "Statement");
+  };
+  base.ForInStatement = function(node, st, c) {
+    c(node.left, st, "ForInit");
+    c(node.right, st, "Expression");
+    c(node.body, st, "Statement");
+  };
+  base.ForInit = function(node, st, c) {
+    if (node.type == "VariableDeclaration") c(node, st);
+    else c(node, st, "Expression");
+  };
+  base.DebuggerStatement = ignore;
+
+  base.FunctionDeclaration = function(node, st, c) {
+    c(node, st, "Function");
+  };
+  base.VariableDeclaration = function(node, st, c) {
+    for (var i = 0; i < node.declarations.length; ++i) {
+      var decl = node.declarations[i];
+      if (decl.init) c(decl.init, st, "Expression");
+    }
+  };
+
+  base.Function = function(node, st, c) {
+    c(node.body, st, "ScopeBody");
+  };
+  base.ScopeBody = function(node, st, c) {
+    c(node, st, "Statement");
+  };
+
+  base.Expression = skipThrough;
+  base.ThisExpression = ignore;
+  base.ArrayExpression = function(node, st, c) {
+    for (var i = 0; i < node.elements.length; ++i) {
+      var elt = node.elements[i];
+      if (elt) c(elt, st, "Expression");
+    }
+  };
+  base.ObjectExpression = function(node, st, c) {
+    for (var i = 0; i < node.properties.length; ++i)
+      c(node.properties[i].value, st, "Expression");
+  };
+  base.FunctionExpression = base.FunctionDeclaration;
+  base.SequenceExpression = function(node, st, c) {
+    for (var i = 0; i < node.expressions.length; ++i)
+      c(node.expressions[i], st, "Expression");
+  };
+  base.UnaryExpression = base.UpdateExpression = function(node, st, c) {
+    c(node.argument, st, "Expression");
+  };
+  base.BinaryExpression = base.AssignmentExpression = base.LogicalExpression = function(node, st, c) {
+    c(node.left, st, "Expression");
+    c(node.right, st, "Expression");
+  };
+  base.ConditionalExpression = function(node, st, c) {
+    c(node.test, st, "Expression");
+    c(node.consequent, st, "Expression");
+    c(node.alternate, st, "Expression");
+  };
+  base.NewExpression = base.CallExpression = function(node, st, c) {
+    c(node.callee, st, "Expression");
+    if (node.arguments) for (var i = 0; i < node.arguments.length; ++i)
+      c(node.arguments[i], st, "Expression");
+  };
+  base.MemberExpression = function(node, st, c) {
+    c(node.object, st, "Expression");
+    if (node.computed) c(node.property, st, "Expression");
+  };
+  base.Identifier = base.Literal = ignore;
+
+  // A custom walker that keeps track of the scope chain and the
+  // variables defined in it.
+  function makeScope(prev, isCatch) {
+    return {vars: Object.create(null), prev: prev, isCatch: isCatch};
+  }
+  function normalScope(scope) {
+    while (scope.isCatch) scope = scope.prev;
+    return scope;
+  }
+  exports.scopeVisitor = exports.make({
+    Function: function(node, scope, c) {
+      var inner = makeScope(scope);
+      for (var i = 0; i < node.params.length; ++i)
+        inner.vars[node.params[i].name] = {type: "argument", node: node.params[i]};
+      if (node.id) {
+        var decl = node.type == "FunctionDeclaration";
+        (decl ? normalScope(scope) : inner).vars[node.id.name] =
+          {type: decl ? "function" : "function name", node: node.id};
+      }
+      c(node.body, inner, "ScopeBody");
+    },
+    TryStatement: function(node, scope, c) {
+      c(node.block, scope, "Statement");
+      if (node.handler) {
+        var inner = makeScope(scope, true);
+        inner.vars[node.handler.param.name] = {type: "catch clause", node: node.handler.param};
+        c(node.handler.body, inner, "ScopeBody");
+      }
+      if (node.finalizer) c(node.finalizer, scope, "Statement");
+    },
+    VariableDeclaration: function(node, scope, c) {
+      var target = normalScope(scope);
+      for (var i = 0; i < node.declarations.length; ++i) {
+        var decl = node.declarations[i];
+        target.vars[decl.id.name] = {type: "var", node: decl.id};
+        if (decl.init) c(decl.init, scope, "Expression");
+      }
+    }
+  });
+
+});
diff --git a/app/gui/html/vendor/codemirror/test/mode_test.css b/app/gui/html/vendor/codemirror/test/mode_test.css
new file mode 100644
index 0000000..1ac6673
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/mode_test.css
@@ -0,0 +1,10 @@
+.mt-output .mt-token {
+  border: 1px solid #ddd;
+  white-space: pre;
+  font-family: "Consolas", monospace;
+  text-align: center;
+}
+
+.mt-output .mt-style {
+  font-size: x-small;
+}
diff --git a/app/gui/html/vendor/codemirror/test/mode_test.js b/app/gui/html/vendor/codemirror/test/mode_test.js
new file mode 100644
index 0000000..46174e1
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/mode_test.js
@@ -0,0 +1,168 @@
+/**
+ * Helper to test CodeMirror highlighting modes. It pretty prints output of the
+ * highlighter and can check against expected styles.
+ *
+ * Mode tests are registered by calling test.mode(testName, mode,
+ * tokens), where mode is a mode object as returned by
+ * CodeMirror.getMode, and tokens is an array of lines that make up
+ * the test.
+ *
+ * These lines are strings, in which styled stretches of code are
+ * enclosed in brackets `[]`, and prefixed by their style. For
+ * example, `[keyword if]`. Brackets in the code itself must be
+ * duplicated to prevent them from being interpreted as token
+ * boundaries. For example `a[[i]]` for `a[i]`. If a token has
+ * multiple styles, the styles must be separated by ampersands, for
+ * example `[tag&error </hmtl>]`.
+ *
+ * See the test.js files in the css, markdown, gfm, and stex mode
+ * directories for examples.
+ */
+(function() {
+  function findSingle(str, pos, ch) {
+    for (;;) {
+      var found = str.indexOf(ch, pos);
+      if (found == -1) return null;
+      if (str.charAt(found + 1) != ch) return found;
+      pos = found + 2;
+    }
+  }
+
+  var styleName = /[\w&-_]+/g;
+  function parseTokens(strs) {
+    var tokens = [], plain = "";
+    for (var i = 0; i < strs.length; ++i) {
+      if (i) plain += "\n";
+      var str = strs[i], pos = 0;
+      while (pos < str.length) {
+        var style = null, text;
+        if (str.charAt(pos) == "[" && str.charAt(pos+1) != "[") {
+          styleName.lastIndex = pos + 1;
+          var m = styleName.exec(str);
+          style = m[0].replace(/&/g, " ");
+          var textStart = pos + style.length + 2;
+          var end = findSingle(str, textStart, "]");
+          if (end == null) throw new Error("Unterminated token at " + pos + " in '" + str + "'" + style);
+          text = str.slice(textStart, end);
+          pos = end + 1;
+        } else {
+          var end = findSingle(str, pos, "[");
+          if (end == null) end = str.length;
+          text = str.slice(pos, end);
+          pos = end;
+        }
+        text = text.replace(/\[\[|\]\]/g, function(s) {return s.charAt(0);});
+        tokens.push(style, text);
+        plain += text;
+      }
+    }
+    return {tokens: tokens, plain: plain};
+  }
+
+  test.mode = function(name, mode, tokens, modeName) {
+    var data = parseTokens(tokens);
+    return test((modeName || mode.name) + "_" + name, function() {
+      return compare(data.plain, data.tokens, mode);
+    });
+  };
+
+  function esc(str) {
+    return str.replace('&', '&').replace('<', '<');
+  }
+
+  function compare(text, expected, mode) {
+
+    var expectedOutput = [];
+    for (var i = 0; i < expected.length; i += 2) {
+      var sty = expected[i];
+      if (sty && sty.indexOf(" ")) sty = sty.split(' ').sort().join(' ');
+      expectedOutput.push(sty, expected[i + 1]);
+    }
+
+    var observedOutput = highlight(text, mode);
+
+    var s = "";
+    var diff = highlightOutputsDifferent(expectedOutput, observedOutput);
+    if (diff != null) {
+      s += '<div class="mt-test mt-fail">';
+      s +=   '<pre>' + esc(text) + '</pre>';
+      s +=   '<div class="cm-s-default">';
+      s += 'expected:';
+      s +=   prettyPrintOutputTable(expectedOutput, diff);
+      s += 'observed:';
+      s +=   prettyPrintOutputTable(observedOutput, diff);
+      s +=   '</div>';
+      s += '</div>';
+    }
+    if (observedOutput.indentFailures) {
+      for (var i = 0; i < observedOutput.indentFailures.length; i++)
+        s += "<div class='mt-test mt-fail'>" + esc(observedOutput.indentFailures[i]) + "</div>";
+    }
+    if (s) throw new Failure(s);
+  }
+
+  function highlight(string, mode) {
+    var state = mode.startState()
+
+    var lines = string.replace(/\r\n/g,'\n').split('\n');
+    var st = [], pos = 0;
+    for (var i = 0; i < lines.length; ++i) {
+      var line = lines[i], newLine = true;
+      if (mode.indent) {
+        var ws = line.match(/^\s*/)[0];
+        var indent = mode.indent(state, line.slice(ws.length));
+        if (indent != CodeMirror.Pass && indent != ws.length)
+          (st.indentFailures || (st.indentFailures = [])).push(
+            "Indentation of line " + (i + 1) + " is " + indent + " (expected " + ws.length + ")");
+      }
+      var stream = new CodeMirror.StringStream(line);
+      if (line == "" && mode.blankLine) mode.blankLine(state);
+      /* Start copied code from CodeMirror.highlight */
+      while (!stream.eol()) {
+        var compare = mode.token(stream, state), substr = stream.current();
+        if (compare && compare.indexOf(" ") > -1) compare = compare.split(' ').sort().join(' ');
+        stream.start = stream.pos;
+        if (pos && st[pos-2] == compare && !newLine) {
+          st[pos-1] += substr;
+        } else if (substr) {
+          st[pos++] = compare; st[pos++] = substr;
+        }
+        // Give up when line is ridiculously long
+        if (stream.pos > 5000) {
+          st[pos++] = null; st[pos++] = this.text.slice(stream.pos);
+          break;
+        }
+        newLine = false;
+      }
+    }
+
+    return st;
+  }
+
+  function highlightOutputsDifferent(o1, o2) {
+    var minLen = Math.min(o1.length, o2.length);
+    for (var i = 0; i < minLen; ++i)
+      if (o1[i] != o2[i]) return i >> 1;
+    if (o1.length > minLen || o2.length > minLen) return minLen;
+  }
+
+  function prettyPrintOutputTable(output, diffAt) {
+    var s = '<table class="mt-output">';
+    s += '<tr>';
+    for (var i = 0; i < output.length; i += 2) {
+      var style = output[i], val = output[i+1];
+      s +=
+      '<td class="mt-token"' + (i == diffAt * 2 ? " style='background: pink'" : "") + '>' +
+        '<span class="cm-' + esc(String(style)) + '">' +
+        esc(val.replace(/ /g,'\xb7')) +
+        '</span>' +
+        '</td>';
+    }
+    s += '</tr><tr>';
+    for (var i = 0; i < output.length; i += 2) {
+      s += '<td class="mt-style"><span>' + (output[i] || null) + '</span></td>';
+    }
+    s += '</table>';
+    return s;
+  }
+})();
diff --git a/app/gui/html/vendor/codemirror/test/multi_test.js b/app/gui/html/vendor/codemirror/test/multi_test.js
new file mode 100644
index 0000000..a8e760d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/multi_test.js
@@ -0,0 +1,285 @@
+(function() {
+  namespace = "multi_";
+
+  function hasSelections(cm) {
+    var sels = cm.listSelections();
+    var given = (arguments.length - 1) / 4;
+    if (sels.length != given)
+      throw new Failure("expected " + given + " selections, found " + sels.length);
+    for (var i = 0, p = 1; i < given; i++, p += 4) {
+      var anchor = Pos(arguments[p], arguments[p + 1]);
+      var head = Pos(arguments[p + 2], arguments[p + 3]);
+      eqPos(sels[i].anchor, anchor, "anchor of selection " + i);
+      eqPos(sels[i].head, head, "head of selection " + i);
+    }
+  }
+  function hasCursors(cm) {
+    var sels = cm.listSelections();
+    var given = (arguments.length - 1) / 2;
+    if (sels.length != given)
+      throw new Failure("expected " + given + " selections, found " + sels.length);
+    for (var i = 0, p = 1; i < given; i++, p += 2) {
+      eqPos(sels[i].anchor, sels[i].head, "something selected for " + i);
+      var head = Pos(arguments[p], arguments[p + 1]);
+      eqPos(sels[i].head, head, "selection " + i);
+    }
+  }
+
+  testCM("getSelection", function(cm) {
+    select(cm, {anchor: Pos(0, 0), head: Pos(1, 2)}, {anchor: Pos(2, 2), head: Pos(2, 0)});
+    eq(cm.getSelection(), "1234\n56\n90");
+    eq(cm.getSelection(false).join("|"), "1234|56|90");
+    eq(cm.getSelections().join("|"), "1234\n56|90");
+  }, {value: "1234\n5678\n90"});
+
+  testCM("setSelection", function(cm) {
+    select(cm, Pos(3, 0), Pos(0, 0), {anchor: Pos(2, 5), head: Pos(1, 0)});
+    hasSelections(cm, 0, 0, 0, 0,
+                  2, 5, 1, 0,
+                  3, 0, 3, 0);
+    cm.setSelection(Pos(1, 2), Pos(1, 1));
+    hasSelections(cm, 1, 2, 1, 1);
+    select(cm, {anchor: Pos(1, 1), head: Pos(2, 4)},
+           {anchor: Pos(0, 0), head: Pos(1, 3)},
+           Pos(3, 0), Pos(2, 2));
+    hasSelections(cm, 0, 0, 2, 4,
+                  3, 0, 3, 0);
+    cm.setSelections([{anchor: Pos(0, 1), head: Pos(0, 2)},
+                      {anchor: Pos(1, 1), head: Pos(1, 2)},
+                      {anchor: Pos(2, 1), head: Pos(2, 2)}], 1);
+    eqPos(cm.getCursor("head"), Pos(1, 2));
+    eqPos(cm.getCursor("anchor"), Pos(1, 1));
+    eqPos(cm.getCursor("from"), Pos(1, 1));
+    eqPos(cm.getCursor("to"), Pos(1, 2));
+    cm.setCursor(Pos(1, 1));
+    hasCursors(cm, 1, 1);
+  }, {value: "abcde\nabcde\nabcde\n"});
+
+  testCM("somethingSelected", function(cm) {
+    select(cm, Pos(0, 1), {anchor: Pos(0, 3), head: Pos(0, 5)});
+    eq(cm.somethingSelected(), true);
+    select(cm, Pos(0, 1), Pos(0, 3), Pos(0, 5));
+    eq(cm.somethingSelected(), false);
+  }, {value: "123456789"});
+
+  testCM("extendSelection", function(cm) {
+    select(cm, Pos(0, 1), Pos(1, 1), Pos(2, 1));
+    cm.setExtending(true);
+    cm.extendSelections([Pos(0, 2), Pos(1, 0), Pos(2, 3)]);
+    hasSelections(cm, 0, 1, 0, 2,
+                  1, 1, 1, 0,
+                  2, 1, 2, 3);
+    cm.extendSelection(Pos(2, 4), Pos(2, 0));
+    hasSelections(cm, 2, 4, 2, 0);
+  }, {value: "1234\n1234\n1234"});
+
+  testCM("addSelection", function(cm) {
+    select(cm, Pos(0, 1), Pos(1, 1));
+    cm.addSelection(Pos(0, 0), Pos(0, 4));
+    hasSelections(cm, 0, 0, 0, 4,
+                  1, 1, 1, 1);
+    cm.addSelection(Pos(2, 2));
+    hasSelections(cm, 0, 0, 0, 4,
+                  1, 1, 1, 1,
+                  2, 2, 2, 2);
+  }, {value: "1234\n1234\n1234"});
+
+  testCM("replaceSelection", function(cm) {
+    var selections = [{anchor: Pos(0, 0), head: Pos(0, 1)},
+                      {anchor: Pos(0, 2), head: Pos(0, 3)},
+                      {anchor: Pos(0, 4), head: Pos(0, 5)},
+                      {anchor: Pos(2, 1), head: Pos(2, 4)},
+                      {anchor: Pos(2, 5), head: Pos(2, 6)}];
+    var val = "123456\n123456\n123456";
+    cm.setValue(val);
+    cm.setSelections(selections);
+    cm.replaceSelection("ab", "around");
+    eq(cm.getValue(), "ab2ab4ab6\n123456\n1ab5ab");
+    hasSelections(cm, 0, 0, 0, 2,
+                  0, 3, 0, 5,
+                  0, 6, 0, 8,
+                  2, 1, 2, 3,
+                  2, 4, 2, 6);
+    cm.setValue(val);
+    cm.setSelections(selections);
+    cm.replaceSelection("", "around");
+    eq(cm.getValue(), "246\n123456\n15");
+    hasSelections(cm, 0, 0, 0, 0,
+                  0, 1, 0, 1,
+                  0, 2, 0, 2,
+                  2, 1, 2, 1,
+                  2, 2, 2, 2);
+    cm.setValue(val);
+    cm.setSelections(selections);
+    cm.replaceSelection("X\nY\nZ", "around");
+    hasSelections(cm, 0, 0, 2, 1,
+                  2, 2, 4, 1,
+                  4, 2, 6, 1,
+                  8, 1, 10, 1,
+                  10, 2, 12, 1);
+    cm.replaceSelection("a", "around");
+    hasSelections(cm, 0, 0, 0, 1,
+                  0, 2, 0, 3,
+                  0, 4, 0, 5,
+                  2, 1, 2, 2,
+                  2, 3, 2, 4);
+    cm.replaceSelection("xy", "start");
+    hasSelections(cm, 0, 0, 0, 0,
+                  0, 3, 0, 3,
+                  0, 6, 0, 6,
+                  2, 1, 2, 1,
+                  2, 4, 2, 4);
+    cm.replaceSelection("z\nf");
+    hasSelections(cm, 1, 1, 1, 1,
+                  2, 1, 2, 1,
+                  3, 1, 3, 1,
+                  6, 1, 6, 1,
+                  7, 1, 7, 1);
+    eq(cm.getValue(), "z\nfxy2z\nfxy4z\nfxy6\n123456\n1z\nfxy5z\nfxy");
+  });
+
+  function select(cm) {
+    var sels = [];
+    for (var i = 1; i < arguments.length; i++) {
+      var arg = arguments[i];
+      if (arg.head) sels.push(arg);
+      else sels.push({head: arg, anchor: arg});
+    }
+    cm.setSelections(sels, sels.length - 1);
+  }
+
+  testCM("indentSelection", function(cm) {
+    select(cm, Pos(0, 1), Pos(1, 1));
+    cm.indentSelection(4);
+    eq(cm.getValue(), "    foo\n    bar\nbaz");
+
+    select(cm, Pos(0, 2), Pos(0, 3), Pos(0, 4));
+    cm.indentSelection(-2);
+    eq(cm.getValue(), "  foo\n    bar\nbaz");
+
+    select(cm, {anchor: Pos(0, 0), head: Pos(1, 2)},
+           {anchor: Pos(1, 3), head: Pos(2, 0)});
+    cm.indentSelection(-2);
+    eq(cm.getValue(), "foo\n  bar\nbaz");
+  }, {value: "foo\nbar\nbaz"});
+
+  testCM("killLine", function(cm) {
+    select(cm, Pos(0, 1), Pos(0, 2), Pos(1, 1));
+    cm.execCommand("killLine");
+    eq(cm.getValue(), "f\nb\nbaz");
+    cm.execCommand("killLine");
+    eq(cm.getValue(), "fbbaz");
+    cm.setValue("foo\nbar\nbaz");
+    select(cm, Pos(0, 1), {anchor: Pos(0, 2), head: Pos(2, 1)});
+    cm.execCommand("killLine");
+    eq(cm.getValue(), "faz");
+  }, {value: "foo\nbar\nbaz"});
+
+  testCM("deleteLine", function(cm) {
+    select(cm, Pos(0, 0),
+           {head: Pos(0, 1), anchor: Pos(2, 0)},
+           Pos(4, 0));
+    cm.execCommand("deleteLine");
+    eq(cm.getValue(), "4\n6\n7");
+    select(cm, Pos(2, 1));
+    cm.execCommand("deleteLine");
+    eq(cm.getValue(), "4\n6\n");
+  }, {value: "1\n2\n3\n4\n5\n6\n7"});
+
+  testCM("deleteH", function(cm) {
+    select(cm, Pos(0, 4), {anchor: Pos(1, 4), head: Pos(1, 5)});
+    cm.execCommand("delWordAfter");
+    eq(cm.getValue(), "foo bar baz\nabc ef ghi\n");
+    cm.execCommand("delWordAfter");
+    eq(cm.getValue(), "foo  baz\nabc  ghi\n");
+    cm.execCommand("delCharBefore");
+    cm.execCommand("delCharBefore");
+    eq(cm.getValue(), "fo baz\nab ghi\n");
+    select(cm, Pos(0, 3), Pos(0, 4), Pos(0, 5));
+    cm.execCommand("delWordAfter");
+    eq(cm.getValue(), "fo \nab ghi\n");
+  }, {value: "foo bar baz\nabc def ghi\n"});
+
+  testCM("goLineStart", function(cm) {
+    select(cm, Pos(0, 2), Pos(0, 3), Pos(1, 1));
+    cm.execCommand("goLineStart");
+    hasCursors(cm, 0, 0, 1, 0);
+    select(cm, Pos(1, 1), Pos(0, 1));
+    cm.setExtending(true);
+    cm.execCommand("goLineStart");
+    hasSelections(cm, 0, 1, 0, 0,
+                  1, 1, 1, 0);
+  }, {value: "foo\nbar\nbaz"});
+
+  testCM("moveV", function(cm) {
+    select(cm, Pos(0, 2), Pos(1, 2));
+    cm.execCommand("goLineDown");
+    hasCursors(cm, 1, 2, 2, 2);
+    cm.execCommand("goLineUp");
+    hasCursors(cm, 0, 2, 1, 2);
+    cm.execCommand("goLineUp");
+    hasCursors(cm, 0, 0, 0, 2);
+    cm.execCommand("goLineUp");
+    hasCursors(cm, 0, 0);
+    select(cm, Pos(0, 2), Pos(1, 2));
+    cm.setExtending(true);
+    cm.execCommand("goLineDown");
+    hasSelections(cm, 0, 2, 2, 2);
+  }, {value: "12345\n12345\n12345"});
+
+  testCM("moveH", function(cm) {
+    select(cm, Pos(0, 1), Pos(0, 3), Pos(0, 5), Pos(2, 3));
+    cm.execCommand("goCharRight");
+    hasCursors(cm, 0, 2, 0, 4, 1, 0, 2, 4);
+    cm.execCommand("goCharLeft");
+    hasCursors(cm, 0, 1, 0, 3, 0, 5, 2, 3);
+    for (var i = 0; i < 15; i++)
+      cm.execCommand("goCharRight");
+    hasCursors(cm, 2, 4, 2, 5);
+  }, {value: "12345\n12345\n12345"});
+
+  testCM("newlineAndIndent", function(cm) {
+    select(cm, Pos(0, 5), Pos(1, 5));
+    cm.execCommand("newlineAndIndent");
+    hasCursors(cm, 1, 2, 3, 2);
+    eq(cm.getValue(), "x = [\n  1];\ny = [\n  2];");
+    cm.undo();
+    eq(cm.getValue(), "x = [1];\ny = [2];");
+    hasCursors(cm, 0, 5, 1, 5);
+    select(cm, Pos(0, 5), Pos(0, 6));
+    cm.execCommand("newlineAndIndent");
+    hasCursors(cm, 1, 2, 2, 0);
+    eq(cm.getValue(), "x = [\n  1\n];\ny = [2];");
+  }, {value: "x = [1];\ny = [2];", mode: "javascript"});
+
+  testCM("goDocStartEnd", function(cm) {
+    select(cm, Pos(0, 1), Pos(1, 1));
+    cm.execCommand("goDocStart");
+    hasCursors(cm, 0, 0);
+    select(cm, Pos(0, 1), Pos(1, 1));
+    cm.execCommand("goDocEnd");
+    hasCursors(cm, 1, 3);
+    select(cm, Pos(0, 1), Pos(1, 1));
+    cm.setExtending(true);
+    cm.execCommand("goDocEnd");
+    hasSelections(cm, 1, 1, 1, 3);
+  }, {value: "abc\ndef"});
+
+  testCM("selectionHistory", function(cm) {
+    for (var i = 0; i < 3; ++i)
+      cm.addSelection(Pos(0, i * 2), Pos(0, i * 2 + 1));
+    cm.execCommand("undoSelection");
+    eq(cm.getSelection(), "1\n2");
+    cm.execCommand("undoSelection");
+    eq(cm.getSelection(), "1");
+    cm.execCommand("undoSelection");
+    eq(cm.getSelection(), "");
+    eqPos(cm.getCursor(), Pos(0, 0));
+    cm.execCommand("redoSelection");
+    eq(cm.getSelection(), "1");
+    cm.execCommand("redoSelection");
+    eq(cm.getSelection(), "1\n2");
+    cm.execCommand("redoSelection");
+    eq(cm.getSelection(), "1\n2\n3");
+  }, {value: "1 2 3"});
+})();
diff --git a/app/gui/html/vendor/codemirror/test/phantom_driver.js b/app/gui/html/vendor/codemirror/test/phantom_driver.js
new file mode 100644
index 0000000..dbad08d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/phantom_driver.js
@@ -0,0 +1,31 @@
+var page = require('webpage').create();
+
+page.open("http://localhost:3000/test/index.html", function (status) {
+  if (status != "success") {
+    console.log("page couldn't be loaded successfully");
+    phantom.exit(1);
+  }
+  waitFor(function () {
+    return page.evaluate(function () {
+      var output = document.getElementById('status');
+      if (!output) { return false; }
+      return (/^(\d+ failures?|all passed)/i).test(output.innerText);
+    });
+  }, function () {
+    var failed = page.evaluate(function () { return window.failed; });
+    var output = page.evaluate(function () {
+      return document.getElementById('output').innerText + "\n" +
+        document.getElementById('status').innerText;
+    });
+    console.log(output);
+    phantom.exit(failed > 0 ? 1 : 0);
+  });
+});
+
+function waitFor (test, cb) {
+  if (test()) {
+    cb();
+  } else {
+    setTimeout(function () { waitFor(test, cb); }, 250);
+  }
+}
diff --git a/app/gui/html/vendor/codemirror/test/run.js b/app/gui/html/vendor/codemirror/test/run.js
new file mode 100755
index 0000000..140539c
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/run.js
@@ -0,0 +1,38 @@
+#!/usr/bin/env node
+
+var lint = require("./lint/lint");
+
+lint.checkDir("mode");
+lint.checkDir("lib");
+lint.checkDir("addon");
+lint.checkDir("keymap");
+
+var ok = lint.success();
+
+var files = new (require('node-static').Server)();
+
+var server = require('http').createServer(function (req, res) {
+  req.addListener('end', function () {
+    files.serve(req, res, function (err/*, result */) {
+      if (err) {
+        console.error(err);
+        process.exit(1);
+      }
+    });
+  }).resume();
+}).addListener('error', function (err) {
+  throw err;
+}).listen(3000, function () {
+  var childProcess = require('child_process');
+  var phantomjs = require("phantomjs");
+  var childArgs = [
+    require("path").join(__dirname, 'phantom_driver.js')
+  ];
+  childProcess.execFile(phantomjs.path, childArgs, function (err, stdout, stderr) {
+    server.close();
+    console.log(stdout);
+    if (err) console.error(err);
+    if (stderr) console.error(stderr);
+    process.exit(err || stderr || !ok ? 1 : 0);
+  });
+});
diff --git a/app/gui/html/vendor/codemirror/test/search_test.js b/app/gui/html/vendor/codemirror/test/search_test.js
new file mode 100644
index 0000000..04a1e68
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/search_test.js
@@ -0,0 +1,62 @@
+(function() {
+  "use strict";
+
+  function test(name) {
+    var text = Array.prototype.slice.call(arguments, 1, arguments.length - 1).join("\n");
+    var body = arguments[arguments.length - 1];
+    return window.test("search_" + name, function() {
+      body(new CodeMirror.Doc(text));
+    });
+  }
+
+  function run(doc, query, insensitive) {
+    var cursor = doc.getSearchCursor(query, null, insensitive);
+    for (var i = 3; i < arguments.length; i += 4) {
+      var found = cursor.findNext();
+      is(found, "not enough results (forward)");
+      eqPos(Pos(arguments[i], arguments[i + 1]), cursor.from(), "from, forward, " + (i - 3) / 4);
+      eqPos(Pos(arguments[i + 2], arguments[i + 3]), cursor.to(), "to, forward, " + (i - 3) / 4);
+    }
+    is(!cursor.findNext(), "too many matches (forward)");
+    for (var i = arguments.length - 4; i >= 3; i -= 4) {
+      var found = cursor.findPrevious();
+      is(found, "not enough results (backwards)");
+      eqPos(Pos(arguments[i], arguments[i + 1]), cursor.from(), "from, backwards, " + (i - 3) / 4);
+      eqPos(Pos(arguments[i + 2], arguments[i + 3]), cursor.to(), "to, backwards, " + (i - 3) / 4);
+    }
+    is(!cursor.findPrevious(), "too many matches (backwards)");
+  }
+
+  test("simple", "abcdefg", "abcdefg", function(doc) {
+    run(doc, "cde", false, 0, 2, 0, 5, 1, 2, 1, 5);
+  });
+
+  test("multiline", "hallo", "goodbye", function(doc) {
+    run(doc, "llo\ngoo", false, 0, 2, 1, 3);
+    run(doc, "blah\nhall", false);
+    run(doc, "bye\neye", false);
+  });
+
+  test("regexp", "abcde", "abcde", function(doc) {
+    run(doc, /bcd/, false, 0, 1, 0, 4, 1, 1, 1, 4);
+    run(doc, /BCD/, false);
+    run(doc, /BCD/i, false, 0, 1, 0, 4, 1, 1, 1, 4);
+  });
+
+  test("insensitive", "hallo", "HALLO", "oink", "hAllO", function(doc) {
+    run(doc, "All", false, 3, 1, 3, 4);
+    run(doc, "All", true, 0, 1, 0, 4, 1, 1, 1, 4, 3, 1, 3, 4);
+  });
+
+  test("multilineInsensitive", "zie ginds komT", "De Stoomboot", "uit Spanje weer aan", function(doc) {
+    run(doc, "komt\nde stoomboot\nuit", false);
+    run(doc, "komt\nde stoomboot\nuit", true, 0, 10, 2, 3);
+    run(doc, "kOMt\ndE stOOmboot\nuiT", true, 0, 10, 2, 3);
+  });
+
+  test("expandingCaseFold", "<b>Ä°Ä° Ä°Ä°</b>", "<b>uu uu</b>", function(doc) {
+    if (phantom) return; // A Phantom bug makes this hang
+    run(doc, "</b>", true, 0, 8, 0, 12, 1, 8, 1, 12);
+    run(doc, "Ä°Ä°", true, 0, 3, 0, 5, 0, 6, 0, 8);
+  });
+})();
diff --git a/app/gui/html/vendor/codemirror/test/sublime_test.js b/app/gui/html/vendor/codemirror/test/sublime_test.js
new file mode 100644
index 0000000..f09504c
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/sublime_test.js
@@ -0,0 +1,297 @@
+(function() {
+  "use strict";
+  
+  var Pos = CodeMirror.Pos;
+  namespace = "sublime_";
+
+  function stTest(name) {
+    var actions = Array.prototype.slice.call(arguments, 1);
+    testCM(name, function(cm) {
+      for (var i = 0; i < actions.length; i++) {
+        var action = actions[i];
+        if (typeof action == "string" && i == 0)
+          cm.setValue(action);
+        else if (typeof action == "string")
+          cm.execCommand(action);
+        else if (action instanceof Pos)
+          cm.setCursor(action);
+        else
+          action(cm);
+      }
+    });
+  }
+
+  function at(line, ch, msg) {
+    return function(cm) {
+      eq(cm.listSelections().length, 1);
+      eqPos(cm.getCursor("head"), Pos(line, ch), msg);
+      eqPos(cm.getCursor("anchor"), Pos(line, ch), msg);
+    };
+  }
+
+  function val(content, msg) {
+    return function(cm) { eq(cm.getValue(), content, msg); };
+  }
+
+  function argsToRanges(args) {
+    if (args.length % 4) throw new Error("Wrong number of arguments for ranges.");
+    var ranges = [];
+    for (var i = 0; i < args.length; i += 4)
+      ranges.push({anchor: Pos(args[i], args[i + 1]),
+                   head: Pos(args[i + 2], args[i + 3])});
+    return ranges;
+  }
+
+  function setSel() {
+    var ranges = argsToRanges(arguments);
+    return function(cm) { cm.setSelections(ranges, 0); };
+  }
+
+  function hasSel() {
+    var ranges = argsToRanges(arguments);
+    return function(cm) {
+      var sels = cm.listSelections();
+      if (sels.length != ranges.length)
+        throw new Failure("Expected " + ranges.length + " selections, but found " + sels.length);
+      for (var i = 0; i < sels.length; i++) {
+        eqPos(sels[i].anchor, ranges[i].anchor, "anchor " + i);
+        eqPos(sels[i].head, ranges[i].head, "head " + i);
+      }
+    };
+  }
+
+  stTest("bySubword", "the foo_bar DooDahBah \n a",
+         "goSubwordLeft", at(0, 0),
+         "goSubwordRight", at(0, 3),
+         "goSubwordRight", at(0, 7),
+         "goSubwordRight", at(0, 11),
+         "goSubwordRight", at(0, 15),
+         "goSubwordRight", at(0, 18),
+         "goSubwordRight", at(0, 21),
+         "goSubwordRight", at(0, 22),
+         "goSubwordRight", at(1, 0),
+         "goSubwordRight", at(1, 2),
+         "goSubwordRight", at(1, 2),
+         "goSubwordLeft", at(1, 1),
+         "goSubwordLeft", at(1, 0),
+         "goSubwordLeft", at(0, 22),
+         "goSubwordLeft", at(0, 18),
+         "goSubwordLeft", at(0, 15),
+         "goSubwordLeft", at(0, 12),
+         "goSubwordLeft", at(0, 8),
+         "goSubwordLeft", at(0, 4),
+         "goSubwordLeft", at(0, 0));
+
+  stTest("splitSelectionByLine", "abc\ndef\nghi",
+         setSel(0, 1, 2, 2),
+         "splitSelectionByLine",
+         hasSel(0, 1, 0, 3,
+                1, 0, 1, 3,
+                2, 0, 2, 2));
+
+  stTest("splitSelectionByLineMulti", "abc\ndef\nghi\njkl",
+         setSel(0, 1, 1, 1,
+                1, 2, 3, 2,
+                3, 3, 3, 3),
+         "splitSelectionByLine",
+         hasSel(0, 1, 0, 3,
+                1, 0, 1, 1,
+                1, 2, 1, 3,
+                2, 0, 2, 3,
+                3, 0, 3, 2,
+                3, 3, 3, 3));
+
+  stTest("selectLine", "abc\ndef\nghi",
+         setSel(0, 1, 0, 1,
+                2, 0, 2, 1),
+         "selectLine",
+         hasSel(0, 0, 1, 0,
+                2, 0, 2, 3),
+         setSel(0, 1, 1, 0),
+         "selectLine",
+         hasSel(0, 0, 2, 0));
+
+  stTest("insertLineAfter", "abcde\nfghijkl\nmn",
+         setSel(0, 1, 0, 1,
+                0, 3, 0, 3,
+                1, 2, 1, 2,
+                1, 3, 1, 5), "insertLineAfter",
+         hasSel(1, 0, 1, 0,
+                3, 0, 3, 0), val("abcde\n\nfghijkl\n\nmn"));
+
+  stTest("insertLineBefore", "abcde\nfghijkl\nmn",
+         setSel(0, 1, 0, 1,
+                0, 3, 0, 3,
+                1, 2, 1, 2,
+                1, 3, 1, 5), "insertLineBefore",
+         hasSel(0, 0, 0, 0,
+                2, 0, 2, 0), val("\nabcde\n\nfghijkl\nmn"));
+
+  stTest("selectNextOccurrence", "a foo bar\nfoobar foo",
+         setSel(0, 2, 0, 5),
+         "selectNextOccurrence", hasSel(0, 2, 0, 5,
+                                        1, 0, 1, 3),
+         "selectNextOccurrence", hasSel(0, 2, 0, 5,
+                                        1, 0, 1, 3,
+                                        1, 7, 1, 10),
+         "selectNextOccurrence", hasSel(0, 2, 0, 5,
+                                        1, 0, 1, 3,
+                                        1, 7, 1, 10),
+         Pos(0, 3), "selectNextOccurrence", hasSel(0, 2, 0, 5),
+        "selectNextOccurrence", hasSel(0, 2, 0, 5,
+                                       1, 7, 1, 10),
+         setSel(0, 6, 0, 9),
+         "selectNextOccurrence", hasSel(0, 6, 0, 9,
+                                        1, 3, 1, 6));
+
+  stTest("selectScope", "foo(a) {\n  bar[1, 2];\n}",
+         "selectScope", hasSel(0, 0, 2, 1),
+         Pos(0, 4), "selectScope", hasSel(0, 4, 0, 5),
+         Pos(0, 5), "selectScope", hasSel(0, 4, 0, 5),
+         Pos(0, 6), "selectScope", hasSel(0, 0, 2, 1),
+         Pos(0, 8), "selectScope", hasSel(0, 8, 2, 0),
+         Pos(1, 2), "selectScope", hasSel(0, 8, 2, 0),
+         Pos(1, 6), "selectScope", hasSel(1, 6, 1, 10),
+         Pos(1, 9), "selectScope", hasSel(1, 6, 1, 10));
+
+  stTest("goToBracket", "foo(a) {\n  bar[1, 2];\n}",
+         Pos(0, 0), "goToBracket", at(0, 0),
+         Pos(0, 4), "goToBracket", at(0, 5), "goToBracket", at(0, 4),
+         Pos(0, 8), "goToBracket", at(2, 0), "goToBracket", at(0, 8),
+         Pos(1, 2), "goToBracket", at(2, 0),
+         Pos(1, 7), "goToBracket", at(1, 10), "goToBracket", at(1, 6));
+
+  stTest("swapLine", "1\n2\n3---\n4\n5",
+         "swapLineDown", val("2\n1\n3---\n4\n5"),
+         "swapLineUp", val("1\n2\n3---\n4\n5"),
+         "swapLineUp", val("1\n2\n3---\n4\n5"),
+         Pos(4, 1), "swapLineDown", val("1\n2\n3---\n4\n5"),
+         setSel(0, 1, 0, 1,
+                1, 0, 2, 0,
+                2, 2, 2, 2),
+         "swapLineDown", val("4\n1\n2\n3---\n5"),
+         hasSel(1, 1, 1, 1,
+                2, 0, 3, 0,
+                3, 2, 3, 2),
+         "swapLineUp", val("1\n2\n3---\n4\n5"),
+         hasSel(0, 1, 0, 1,
+                1, 0, 2, 0,
+                2, 2, 2, 2));
+
+  stTest("swapLineUpFromEnd", "a\nb\nc",
+         Pos(2, 1), "swapLineUp",
+         hasSel(1, 1, 1, 1), val("a\nc\nb"));
+
+  stTest("joinLines", "abc\ndef\nghi\njkl",
+         "joinLines", val("abc def\nghi\njkl"), at(0, 4),
+         "undo",
+         setSel(0, 2, 1, 1), "joinLines",
+         val("abc def ghi\njkl"), hasSel(0, 2, 0, 8),
+         "undo",
+         setSel(0, 1, 0, 1,
+                1, 1, 1, 1,
+                3, 1, 3, 1), "joinLines",
+         val("abc def ghi\njkl"), hasSel(0, 4, 0, 4,
+                                         0, 8, 0, 8,
+                                         1, 3, 1, 3));
+
+  stTest("duplicateLine", "abc\ndef\nghi",
+         Pos(1, 0), "duplicateLine", val("abc\ndef\ndef\nghi"), at(2, 0),
+         "undo",
+         setSel(0, 1, 0, 1,
+                1, 1, 1, 1,
+                2, 1, 2, 1), "duplicateLine",
+         val("abc\nabc\ndef\ndef\nghi\nghi"), hasSel(1, 1, 1, 1,
+                                                     3, 1, 3, 1,
+                                                     5, 1, 5, 1));
+  stTest("duplicateLineSelection", "abcdef",
+         setSel(0, 1, 0, 1,
+                0, 2, 0, 4,
+                0, 5, 0, 5),
+         "duplicateLine",
+         val("abcdef\nabcdcdef\nabcdcdef"), hasSel(2, 1, 2, 1,
+                                                   2, 4, 2, 6,
+                                                   2, 7, 2, 7));
+
+  stTest("selectLinesUpward", "123\n345\n789\n012",
+         setSel(0, 1, 0, 1,
+                1, 1, 1, 3,
+                2, 0, 2, 0,
+                3, 0, 3, 0),
+         "selectLinesUpward",
+         hasSel(0, 1, 0, 1,
+                0, 3, 0, 3,
+                1, 0, 1, 0,
+                1, 1, 1, 3,
+                2, 0, 2, 0,
+                3, 0, 3, 0));
+
+  stTest("selectLinesDownward", "123\n345\n789\n012",
+         setSel(0, 1, 0, 1,
+                1, 1, 1, 3,
+                2, 0, 2, 0,
+                3, 0, 3, 0),
+         "selectLinesDownward",
+         hasSel(0, 1, 0, 1,
+                1, 1, 1, 3,
+                2, 0, 2, 0,
+                2, 3, 2, 3,
+                3, 0, 3, 0));
+
+  stTest("sortLines", "c\nb\na\nC\nB\nA",
+         "sortLines", val("A\nB\nC\na\nb\nc"),
+         "undo",
+         setSel(0, 0, 2, 0,
+                3, 0, 5, 0),
+         "sortLines", val("a\nb\nc\nA\nB\nC"),
+         hasSel(0, 0, 2, 1,
+                3, 0, 5, 1),
+         "undo",
+         setSel(1, 0, 4, 0), "sortLinesInsensitive", val("c\na\nB\nb\nC\nA"));
+
+  stTest("bookmarks", "abc\ndef\nghi\njkl",
+         Pos(0, 1), "toggleBookmark",
+         setSel(1, 1, 1, 2), "toggleBookmark",
+         setSel(2, 1, 2, 2), "toggleBookmark",
+         "nextBookmark", hasSel(0, 1, 0, 1),
+         "nextBookmark", hasSel(1, 1, 1, 2),
+         "nextBookmark", hasSel(2, 1, 2, 2),
+         "prevBookmark", hasSel(1, 1, 1, 2),
+         "prevBookmark", hasSel(0, 1, 0, 1),
+         "prevBookmark", hasSel(2, 1, 2, 2),
+         "prevBookmark", hasSel(1, 1, 1, 2),
+         "toggleBookmark",
+         "prevBookmark", hasSel(2, 1, 2, 2),
+         "prevBookmark", hasSel(0, 1, 0, 1),
+         "selectBookmarks", hasSel(0, 1, 0, 1,
+                                   2, 1, 2, 2),
+         "clearBookmarks",
+         Pos(0, 0), "selectBookmarks", at(0, 0));
+
+  stTest("upAndDowncaseAtCursor", "abc\ndef  x\nghI",
+         setSel(0, 1, 0, 3,
+                1, 1, 1, 1,
+                1, 4, 1, 4), "upcaseAtCursor",
+         val("aBC\nDEF  x\nghI"), hasSel(0, 1, 0, 3,
+                                         1, 3, 1, 3,
+                                         1, 4, 1, 4),
+         "downcaseAtCursor",
+         val("abc\ndef  x\nghI"), hasSel(0, 1, 0, 3,
+                                         1, 3, 1, 3,
+                                         1, 4, 1, 4));
+
+  stTest("mark", "abc\ndef\nghi",
+         Pos(1, 1), "setSublimeMark",
+         Pos(2, 1), "selectToSublimeMark", hasSel(2, 1, 1, 1),
+         Pos(0, 1), "swapWithSublimeMark", at(1, 1), "swapWithSublimeMark", at(0, 1),
+         "deleteToSublimeMark", val("aef\nghi"),
+         "sublimeYank", val("abc\ndef\nghi"), at(1, 1));
+
+  stTest("findUnder", "foo foobar  a",
+         "findUnder", hasSel(0, 4, 0, 7),
+         "findUnder", hasSel(0, 0, 0, 3),
+         "findUnderPrevious", hasSel(0, 4, 0, 7),
+         "findUnderPrevious", hasSel(0, 0, 0, 3),
+         Pos(0, 4), "findUnder", hasSel(0, 4, 0, 10),
+         Pos(0, 11), "findUnder", hasSel(0, 11, 0, 11));
+})();
diff --git a/app/gui/html/vendor/codemirror/test/test.js b/app/gui/html/vendor/codemirror/test/test.js
new file mode 100644
index 0000000..b1b5594
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/test.js
@@ -0,0 +1,1878 @@
+var Pos = CodeMirror.Pos;
+
+CodeMirror.defaults.rtlMoveVisually = true;
+
+function forEach(arr, f) {
+  for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
+}
+
+function addDoc(cm, width, height) {
+  var content = [], line = "";
+  for (var i = 0; i < width; ++i) line += "x";
+  for (var i = 0; i < height; ++i) content.push(line);
+  cm.setValue(content.join("\n"));
+}
+
+function byClassName(elt, cls) {
+  if (elt.getElementsByClassName) return elt.getElementsByClassName(cls);
+  var found = [], re = new RegExp("\\b" + cls + "\\b");
+  function search(elt) {
+    if (elt.nodeType == 3) return;
+    if (re.test(elt.className)) found.push(elt);
+    for (var i = 0, e = elt.childNodes.length; i < e; ++i)
+      search(elt.childNodes[i]);
+  }
+  search(elt);
+  return found;
+}
+
+var ie_lt8 = /MSIE [1-7]\b/.test(navigator.userAgent);
+var ie_lt9 = /MSIE [1-8]\b/.test(navigator.userAgent);
+var mac = /Mac/.test(navigator.platform);
+var phantom = /PhantomJS/.test(navigator.userAgent);
+var opera = /Opera\/\./.test(navigator.userAgent);
+var opera_version = opera && navigator.userAgent.match(/Version\/(\d+\.\d+)/);
+if (opera_version) opera_version = Number(opera_version);
+var opera_lt10 = opera && (!opera_version || opera_version < 10);
+
+namespace = "core_";
+
+test("core_fromTextArea", function() {
+  var te = document.getElementById("code");
+  te.value = "CONTENT";
+  var cm = CodeMirror.fromTextArea(te);
+  is(!te.offsetHeight);
+  eq(cm.getValue(), "CONTENT");
+  cm.setValue("foo\nbar");
+  eq(cm.getValue(), "foo\nbar");
+  cm.save();
+  is(/^foo\r?\nbar$/.test(te.value));
+  cm.setValue("xxx");
+  cm.toTextArea();
+  is(te.offsetHeight);
+  eq(te.value, "xxx");
+});
+
+testCM("getRange", function(cm) {
+  eq(cm.getLine(0), "1234");
+  eq(cm.getLine(1), "5678");
+  eq(cm.getLine(2), null);
+  eq(cm.getLine(-1), null);
+  eq(cm.getRange(Pos(0, 0), Pos(0, 3)), "123");
+  eq(cm.getRange(Pos(0, -1), Pos(0, 200)), "1234");
+  eq(cm.getRange(Pos(0, 2), Pos(1, 2)), "34\n56");
+  eq(cm.getRange(Pos(1, 2), Pos(100, 0)), "78");
+}, {value: "1234\n5678"});
+
+testCM("replaceRange", function(cm) {
+  eq(cm.getValue(), "");
+  cm.replaceRange("foo\n", Pos(0, 0));
+  eq(cm.getValue(), "foo\n");
+  cm.replaceRange("a\nb", Pos(0, 1));
+  eq(cm.getValue(), "fa\nboo\n");
+  eq(cm.lineCount(), 3);
+  cm.replaceRange("xyzzy", Pos(0, 0), Pos(1, 1));
+  eq(cm.getValue(), "xyzzyoo\n");
+  cm.replaceRange("abc", Pos(0, 0), Pos(10, 0));
+  eq(cm.getValue(), "abc");
+  eq(cm.lineCount(), 1);
+});
+
+testCM("selection", function(cm) {
+  cm.setSelection(Pos(0, 4), Pos(2, 2));
+  is(cm.somethingSelected());
+  eq(cm.getSelection(), "11\n222222\n33");
+  eqPos(cm.getCursor(false), Pos(2, 2));
+  eqPos(cm.getCursor(true), Pos(0, 4));
+  cm.setSelection(Pos(1, 0));
+  is(!cm.somethingSelected());
+  eq(cm.getSelection(), "");
+  eqPos(cm.getCursor(true), Pos(1, 0));
+  cm.replaceSelection("abc", "around");
+  eq(cm.getSelection(), "abc");
+  eq(cm.getValue(), "111111\nabc222222\n333333");
+  cm.replaceSelection("def", "end");
+  eq(cm.getSelection(), "");
+  eqPos(cm.getCursor(true), Pos(1, 3));
+  cm.setCursor(Pos(2, 1));
+  eqPos(cm.getCursor(true), Pos(2, 1));
+  cm.setCursor(1, 2);
+  eqPos(cm.getCursor(true), Pos(1, 2));
+}, {value: "111111\n222222\n333333"});
+
+testCM("extendSelection", function(cm) {
+  cm.setExtending(true);
+  addDoc(cm, 10, 10);
+  cm.setSelection(Pos(3, 5));
+  eqPos(cm.getCursor("head"), Pos(3, 5));
+  eqPos(cm.getCursor("anchor"), Pos(3, 5));
+  cm.setSelection(Pos(2, 5), Pos(5, 5));
+  eqPos(cm.getCursor("head"), Pos(5, 5));
+  eqPos(cm.getCursor("anchor"), Pos(2, 5));
+  eqPos(cm.getCursor("start"), Pos(2, 5));
+  eqPos(cm.getCursor("end"), Pos(5, 5));
+  cm.setSelection(Pos(5, 5), Pos(2, 5));
+  eqPos(cm.getCursor("head"), Pos(2, 5));
+  eqPos(cm.getCursor("anchor"), Pos(5, 5));
+  eqPos(cm.getCursor("start"), Pos(2, 5));
+  eqPos(cm.getCursor("end"), Pos(5, 5));
+  cm.extendSelection(Pos(3, 2));
+  eqPos(cm.getCursor("head"), Pos(3, 2));
+  eqPos(cm.getCursor("anchor"), Pos(5, 5));
+  cm.extendSelection(Pos(6, 2));
+  eqPos(cm.getCursor("head"), Pos(6, 2));
+  eqPos(cm.getCursor("anchor"), Pos(5, 5));
+  cm.extendSelection(Pos(6, 3), Pos(6, 4));
+  eqPos(cm.getCursor("head"), Pos(6, 4));
+  eqPos(cm.getCursor("anchor"), Pos(5, 5));
+  cm.extendSelection(Pos(0, 3), Pos(0, 4));
+  eqPos(cm.getCursor("head"), Pos(0, 3));
+  eqPos(cm.getCursor("anchor"), Pos(5, 5));
+  cm.extendSelection(Pos(4, 5), Pos(6, 5));
+  eqPos(cm.getCursor("head"), Pos(6, 5));
+  eqPos(cm.getCursor("anchor"), Pos(4, 5));
+  cm.setExtending(false);
+  cm.extendSelection(Pos(0, 3), Pos(0, 4));
+  eqPos(cm.getCursor("head"), Pos(0, 3));
+  eqPos(cm.getCursor("anchor"), Pos(0, 4));
+});
+
+testCM("lines", function(cm) {
+  eq(cm.getLine(0), "111111");
+  eq(cm.getLine(1), "222222");
+  eq(cm.getLine(-1), null);
+  cm.replaceRange("", Pos(1, 0), Pos(2, 0))
+  cm.replaceRange("abc", Pos(1, 0), Pos(1));
+  eq(cm.getValue(), "111111\nabc");
+}, {value: "111111\n222222\n333333"});
+
+testCM("indent", function(cm) {
+  cm.indentLine(1);
+  eq(cm.getLine(1), "   blah();");
+  cm.setOption("indentUnit", 8);
+  cm.indentLine(1);
+  eq(cm.getLine(1), "\tblah();");
+  cm.setOption("indentUnit", 10);
+  cm.setOption("tabSize", 4);
+  cm.indentLine(1);
+  eq(cm.getLine(1), "\t\t  blah();");
+}, {value: "if (x) {\nblah();\n}", indentUnit: 3, indentWithTabs: true, tabSize: 8});
+
+testCM("indentByNumber", function(cm) {
+  cm.indentLine(0, 2);
+  eq(cm.getLine(0), "  foo");
+  cm.indentLine(0, -200);
+  eq(cm.getLine(0), "foo");
+  cm.setSelection(Pos(0, 0), Pos(1, 2));
+  cm.indentSelection(3);
+  eq(cm.getValue(), "   foo\n   bar\nbaz");
+}, {value: "foo\nbar\nbaz"});
+
+test("core_defaults", function() {
+  var defsCopy = {}, defs = CodeMirror.defaults;
+  for (var opt in defs) defsCopy[opt] = defs[opt];
+  defs.indentUnit = 5;
+  defs.value = "uu";
+  defs.indentWithTabs = true;
+  defs.tabindex = 55;
+  var place = document.getElementById("testground"), cm = CodeMirror(place);
+  try {
+    eq(cm.getOption("indentUnit"), 5);
+    cm.setOption("indentUnit", 10);
+    eq(defs.indentUnit, 5);
+    eq(cm.getValue(), "uu");
+    eq(cm.getOption("indentWithTabs"), true);
+    eq(cm.getInputField().tabIndex, 55);
+  }
+  finally {
+    for (var opt in defsCopy) defs[opt] = defsCopy[opt];
+    place.removeChild(cm.getWrapperElement());
+  }
+});
+
+testCM("lineInfo", function(cm) {
+  eq(cm.lineInfo(-1), null);
+  var mark = document.createElement("span");
+  var lh = cm.setGutterMarker(1, "FOO", mark);
+  var info = cm.lineInfo(1);
+  eq(info.text, "222222");
+  eq(info.gutterMarkers.FOO, mark);
+  eq(info.line, 1);
+  eq(cm.lineInfo(2).gutterMarkers, null);
+  cm.setGutterMarker(lh, "FOO", null);
+  eq(cm.lineInfo(1).gutterMarkers, null);
+  cm.setGutterMarker(1, "FOO", mark);
+  cm.setGutterMarker(0, "FOO", mark);
+  cm.clearGutter("FOO");
+  eq(cm.lineInfo(0).gutterMarkers, null);
+  eq(cm.lineInfo(1).gutterMarkers, null);
+}, {value: "111111\n222222\n333333"});
+
+testCM("coords", function(cm) {
+  cm.setSize(null, 100);
+  addDoc(cm, 32, 200);
+  var top = cm.charCoords(Pos(0, 0));
+  var bot = cm.charCoords(Pos(200, 30));
+  is(top.left < bot.left);
+  is(top.top < bot.top);
+  is(top.top < top.bottom);
+  cm.scrollTo(null, 100);
+  var top2 = cm.charCoords(Pos(0, 0));
+  is(top.top > top2.top);
+  eq(top.left, top2.left);
+});
+
+testCM("coordsChar", function(cm) {
+  addDoc(cm, 35, 70);
+  for (var i = 0; i < 2; ++i) {
+    var sys = i ? "local" : "page";
+    for (var ch = 0; ch <= 35; ch += 5) {
+      for (var line = 0; line < 70; line += 5) {
+        cm.setCursor(line, ch);
+        var coords = cm.charCoords(Pos(line, ch), sys);
+        var pos = cm.coordsChar({left: coords.left + 1, top: coords.top + 1}, sys);
+        eqPos(pos, Pos(line, ch));
+      }
+    }
+  }
+}, {lineNumbers: true});
+
+testCM("posFromIndex", function(cm) {
+  cm.setValue(
+    "This function should\n" +
+    "convert a zero based index\n" +
+    "to line and ch."
+  );
+
+  var examples = [
+    { index: -1, line: 0, ch: 0  }, // <- Tests clipping
+    { index: 0,  line: 0, ch: 0  },
+    { index: 10, line: 0, ch: 10 },
+    { index: 39, line: 1, ch: 18 },
+    { index: 55, line: 2, ch: 7  },
+    { index: 63, line: 2, ch: 15 },
+    { index: 64, line: 2, ch: 15 }  // <- Tests clipping
+  ];
+
+  for (var i = 0; i < examples.length; i++) {
+    var example = examples[i];
+    var pos = cm.posFromIndex(example.index);
+    eq(pos.line, example.line);
+    eq(pos.ch, example.ch);
+    if (example.index >= 0 && example.index < 64)
+      eq(cm.indexFromPos(pos), example.index);
+  }
+});
+
+testCM("undo", function(cm) {
+  cm.replaceRange("def", Pos(0, 0), Pos(0));
+  eq(cm.historySize().undo, 1);
+  cm.undo();
+  eq(cm.getValue(), "abc");
+  eq(cm.historySize().undo, 0);
+  eq(cm.historySize().redo, 1);
+  cm.redo();
+  eq(cm.getValue(), "def");
+  eq(cm.historySize().undo, 1);
+  eq(cm.historySize().redo, 0);
+  cm.setValue("1\n\n\n2");
+  cm.clearHistory();
+  eq(cm.historySize().undo, 0);
+  for (var i = 0; i < 20; ++i) {
+    cm.replaceRange("a", Pos(0, 0));
+    cm.replaceRange("b", Pos(3, 0));
+  }
+  eq(cm.historySize().undo, 40);
+  for (var i = 0; i < 40; ++i)
+    cm.undo();
+  eq(cm.historySize().redo, 40);
+  eq(cm.getValue(), "1\n\n\n2");
+}, {value: "abc"});
+
+testCM("undoDepth", function(cm) {
+  cm.replaceRange("d", Pos(0));
+  cm.replaceRange("e", Pos(0));
+  cm.replaceRange("f", Pos(0));
+  cm.undo(); cm.undo(); cm.undo();
+  eq(cm.getValue(), "abcd");
+}, {value: "abc", undoDepth: 4});
+
+testCM("undoDoesntClearValue", function(cm) {
+  cm.undo();
+  eq(cm.getValue(), "x");
+}, {value: "x"});
+
+testCM("undoMultiLine", function(cm) {
+  cm.operation(function() {
+    cm.replaceRange("x", Pos(0, 0));
+    cm.replaceRange("y", Pos(1, 0));
+  });
+  cm.undo();
+  eq(cm.getValue(), "abc\ndef\nghi");
+  cm.operation(function() {
+    cm.replaceRange("y", Pos(1, 0));
+    cm.replaceRange("x", Pos(0, 0));
+  });
+  cm.undo();
+  eq(cm.getValue(), "abc\ndef\nghi");
+  cm.operation(function() {
+    cm.replaceRange("y", Pos(2, 0));
+    cm.replaceRange("x", Pos(1, 0));
+    cm.replaceRange("z", Pos(2, 0));
+  });
+  cm.undo();
+  eq(cm.getValue(), "abc\ndef\nghi", 3);
+}, {value: "abc\ndef\nghi"});
+
+testCM("undoComposite", function(cm) {
+  cm.replaceRange("y", Pos(1));
+  cm.operation(function() {
+    cm.replaceRange("x", Pos(0));
+    cm.replaceRange("z", Pos(2));
+  });
+  eq(cm.getValue(), "ax\nby\ncz\n");
+  cm.undo();
+  eq(cm.getValue(), "a\nby\nc\n");
+  cm.undo();
+  eq(cm.getValue(), "a\nb\nc\n");
+  cm.redo(); cm.redo();
+  eq(cm.getValue(), "ax\nby\ncz\n");
+}, {value: "a\nb\nc\n"});
+
+testCM("undoSelection", function(cm) {
+  cm.setSelection(Pos(0, 2), Pos(0, 4));
+  cm.replaceSelection("");
+  cm.setCursor(Pos(1, 0));
+  cm.undo();
+  eqPos(cm.getCursor(true), Pos(0, 2));
+  eqPos(cm.getCursor(false), Pos(0, 4));
+  cm.setCursor(Pos(1, 0));
+  cm.redo();
+  eqPos(cm.getCursor(true), Pos(0, 2));
+  eqPos(cm.getCursor(false), Pos(0, 2));
+}, {value: "abcdefgh\n"});
+
+testCM("undoSelectionAsBefore", function(cm) {
+  cm.replaceSelection("abc", "around");
+  cm.undo();
+  cm.redo();
+  eq(cm.getSelection(), "abc");
+});
+
+testCM("markTextSingleLine", function(cm) {
+  forEach([{a: 0, b: 1, c: "", f: 2, t: 5},
+           {a: 0, b: 4, c: "", f: 0, t: 2},
+           {a: 1, b: 2, c: "x", f: 3, t: 6},
+           {a: 4, b: 5, c: "", f: 3, t: 5},
+           {a: 4, b: 5, c: "xx", f: 3, t: 7},
+           {a: 2, b: 5, c: "", f: 2, t: 3},
+           {a: 2, b: 5, c: "abcd", f: 6, t: 7},
+           {a: 2, b: 6, c: "x", f: null, t: null},
+           {a: 3, b: 6, c: "", f: null, t: null},
+           {a: 0, b: 9, c: "hallo", f: null, t: null},
+           {a: 4, b: 6, c: "x", f: 3, t: 4},
+           {a: 4, b: 8, c: "", f: 3, t: 4},
+           {a: 6, b: 6, c: "a", f: 3, t: 6},
+           {a: 8, b: 9, c: "", f: 3, t: 6}], function(test) {
+    cm.setValue("1234567890");
+    var r = cm.markText(Pos(0, 3), Pos(0, 6), {className: "foo"});
+    cm.replaceRange(test.c, Pos(0, test.a), Pos(0, test.b));
+    var f = r.find();
+    eq(f && f.from.ch, test.f); eq(f && f.to.ch, test.t);
+  });
+});
+
+testCM("markTextMultiLine", function(cm) {
+  function p(v) { return v && Pos(v[0], v[1]); }
+  forEach([{a: [0, 0], b: [0, 5], c: "", f: [0, 0], t: [2, 5]},
+           {a: [0, 0], b: [0, 5], c: "foo\n", f: [1, 0], t: [3, 5]},
+           {a: [0, 1], b: [0, 10], c: "", f: [0, 1], t: [2, 5]},
+           {a: [0, 5], b: [0, 6], c: "x", f: [0, 6], t: [2, 5]},
+           {a: [0, 0], b: [1, 0], c: "", f: [0, 0], t: [1, 5]},
+           {a: [0, 6], b: [2, 4], c: "", f: [0, 5], t: [0, 7]},
+           {a: [0, 6], b: [2, 4], c: "aa", f: [0, 5], t: [0, 9]},
+           {a: [1, 2], b: [1, 8], c: "", f: [0, 5], t: [2, 5]},
+           {a: [0, 5], b: [2, 5], c: "xx", f: null, t: null},
+           {a: [0, 0], b: [2, 10], c: "x", f: null, t: null},
+           {a: [1, 5], b: [2, 5], c: "", f: [0, 5], t: [1, 5]},
+           {a: [2, 0], b: [2, 3], c: "", f: [0, 5], t: [2, 2]},
+           {a: [2, 5], b: [3, 0], c: "a\nb", f: [0, 5], t: [2, 5]},
+           {a: [2, 3], b: [3, 0], c: "x", f: [0, 5], t: [2, 3]},
+           {a: [1, 1], b: [1, 9], c: "1\n2\n3", f: [0, 5], t: [4, 5]}], function(test) {
+    cm.setValue("aaaaaaaaaa\nbbbbbbbbbb\ncccccccccc\ndddddddd\n");
+    var r = cm.markText(Pos(0, 5), Pos(2, 5),
+                        {className: "CodeMirror-matchingbracket"});
+    cm.replaceRange(test.c, p(test.a), p(test.b));
+    var f = r.find();
+    eqPos(f && f.from, p(test.f)); eqPos(f && f.to, p(test.t));
+  });
+});
+
+testCM("markTextUndo", function(cm) {
+  var marker1, marker2, bookmark;
+  marker1 = cm.markText(Pos(0, 1), Pos(0, 3),
+                        {className: "CodeMirror-matchingbracket"});
+  marker2 = cm.markText(Pos(0, 0), Pos(2, 1),
+                        {className: "CodeMirror-matchingbracket"});
+  bookmark = cm.setBookmark(Pos(1, 5));
+  cm.operation(function(){
+    cm.replaceRange("foo", Pos(0, 2));
+    cm.replaceRange("bar\nbaz\nbug\n", Pos(2, 0), Pos(3, 0));
+  });
+  var v1 = cm.getValue();
+  cm.setValue("");
+  eq(marker1.find(), null); eq(marker2.find(), null); eq(bookmark.find(), null);
+  cm.undo();
+  eqPos(bookmark.find(), Pos(1, 5), "still there");
+  cm.undo();
+  var m1Pos = marker1.find(), m2Pos = marker2.find();
+  eqPos(m1Pos.from, Pos(0, 1)); eqPos(m1Pos.to, Pos(0, 3));
+  eqPos(m2Pos.from, Pos(0, 0)); eqPos(m2Pos.to, Pos(2, 1));
+  eqPos(bookmark.find(), Pos(1, 5));
+  cm.redo(); cm.redo();
+  eq(bookmark.find(), null);
+  cm.undo();
+  eqPos(bookmark.find(), Pos(1, 5));
+  eq(cm.getValue(), v1);
+}, {value: "1234\n56789\n00\n"});
+
+testCM("markTextStayGone", function(cm) {
+  var m1 = cm.markText(Pos(0, 0), Pos(0, 1));
+  cm.replaceRange("hi", Pos(0, 2));
+  m1.clear();
+  cm.undo();
+  eq(m1.find(), null);
+}, {value: "hello"});
+
+testCM("markTextAllowEmpty", function(cm) {
+  var m1 = cm.markText(Pos(0, 1), Pos(0, 2), {clearWhenEmpty: false});
+  is(m1.find());
+  cm.replaceRange("x", Pos(0, 0));
+  is(m1.find());
+  cm.replaceRange("y", Pos(0, 2));
+  is(m1.find());
+  cm.replaceRange("z", Pos(0, 3), Pos(0, 4));
+  is(!m1.find());
+  var m2 = cm.markText(Pos(0, 1), Pos(0, 2), {clearWhenEmpty: false,
+                                              inclusiveLeft: true,
+                                              inclusiveRight: true});
+  cm.replaceRange("q", Pos(0, 1), Pos(0, 2));
+  is(m2.find());
+  cm.replaceRange("", Pos(0, 0), Pos(0, 3));
+  is(!m2.find());
+  var m3 = cm.markText(Pos(0, 1), Pos(0, 1), {clearWhenEmpty: false});
+  cm.replaceRange("a", Pos(0, 3));
+  is(m3.find());
+  cm.replaceRange("b", Pos(0, 1));
+  is(!m3.find());
+}, {value: "abcde"});
+
+testCM("markTextStacked", function(cm) {
+  var m1 = cm.markText(Pos(0, 0), Pos(0, 0), {clearWhenEmpty: false});
+  var m2 = cm.markText(Pos(0, 0), Pos(0, 0), {clearWhenEmpty: false});
+  cm.replaceRange("B", Pos(0, 1));
+  is(m1.find() && m2.find());
+}, {value: "A"});
+
+testCM("undoPreservesNewMarks", function(cm) {
+  cm.markText(Pos(0, 3), Pos(0, 4));
+  cm.markText(Pos(1, 1), Pos(1, 3));
+  cm.replaceRange("", Pos(0, 3), Pos(3, 1));
+  var mBefore = cm.markText(Pos(0, 0), Pos(0, 1));
+  var mAfter = cm.markText(Pos(0, 5), Pos(0, 6));
+  var mAround = cm.markText(Pos(0, 2), Pos(0, 4));
+  cm.undo();
+  eqPos(mBefore.find().from, Pos(0, 0));
+  eqPos(mBefore.find().to, Pos(0, 1));
+  eqPos(mAfter.find().from, Pos(3, 3));
+  eqPos(mAfter.find().to, Pos(3, 4));
+  eqPos(mAround.find().from, Pos(0, 2));
+  eqPos(mAround.find().to, Pos(3, 2));
+  var found = cm.findMarksAt(Pos(2, 2));
+  eq(found.length, 1);
+  eq(found[0], mAround);
+}, {value: "aaaa\nbbbb\ncccc\ndddd"});
+
+testCM("markClearBetween", function(cm) {
+  cm.setValue("aaa\nbbb\nccc\nddd\n");
+  cm.markText(Pos(0, 0), Pos(2));
+  cm.replaceRange("aaa\nbbb\nccc", Pos(0, 0), Pos(2));
+  eq(cm.findMarksAt(Pos(1, 1)).length, 0);
+});
+
+testCM("deleteSpanCollapsedInclusiveLeft", function(cm) {
+  var from = Pos(1, 0), to = Pos(1, 1);
+  var m = cm.markText(from, to, {collapsed: true, inclusiveLeft: true});
+  // Delete collapsed span.
+  cm.replaceRange("", from, to);
+}, {value: "abc\nX\ndef"});
+
+testCM("bookmark", function(cm) {
+  function p(v) { return v && Pos(v[0], v[1]); }
+  forEach([{a: [1, 0], b: [1, 1], c: "", d: [1, 4]},
+           {a: [1, 1], b: [1, 1], c: "xx", d: [1, 7]},
+           {a: [1, 4], b: [1, 5], c: "ab", d: [1, 6]},
+           {a: [1, 4], b: [1, 6], c: "", d: null},
+           {a: [1, 5], b: [1, 6], c: "abc", d: [1, 5]},
+           {a: [1, 6], b: [1, 8], c: "", d: [1, 5]},
+           {a: [1, 4], b: [1, 4], c: "\n\n", d: [3, 1]},
+           {bm: [1, 9], a: [1, 1], b: [1, 1], c: "\n", d: [2, 8]}], function(test) {
+    cm.setValue("1234567890\n1234567890\n1234567890");
+    var b = cm.setBookmark(p(test.bm) || Pos(1, 5));
+    cm.replaceRange(test.c, p(test.a), p(test.b));
+    eqPos(b.find(), p(test.d));
+  });
+});
+
+testCM("bookmarkInsertLeft", function(cm) {
+  var br = cm.setBookmark(Pos(0, 2), {insertLeft: false});
+  var bl = cm.setBookmark(Pos(0, 2), {insertLeft: true});
+  cm.setCursor(Pos(0, 2));
+  cm.replaceSelection("hi");
+  eqPos(br.find(), Pos(0, 2));
+  eqPos(bl.find(), Pos(0, 4));
+  cm.replaceRange("", Pos(0, 4), Pos(0, 5));
+  cm.replaceRange("", Pos(0, 2), Pos(0, 4));
+  cm.replaceRange("", Pos(0, 1), Pos(0, 2));
+  // Verify that deleting next to bookmarks doesn't kill them
+  eqPos(br.find(), Pos(0, 1));
+  eqPos(bl.find(), Pos(0, 1));
+}, {value: "abcdef"});
+
+testCM("bookmarkCursor", function(cm) {
+  var pos01 = cm.cursorCoords(Pos(0, 1)), pos11 = cm.cursorCoords(Pos(1, 1)),
+      pos20 = cm.cursorCoords(Pos(2, 0)), pos30 = cm.cursorCoords(Pos(3, 0)),
+      pos41 = cm.cursorCoords(Pos(4, 1));
+  cm.setBookmark(Pos(0, 1), {widget: document.createTextNode("←"), insertLeft: true});
+  cm.setBookmark(Pos(2, 0), {widget: document.createTextNode("←"), insertLeft: true});
+  cm.setBookmark(Pos(1, 1), {widget: document.createTextNode("→")});
+  cm.setBookmark(Pos(3, 0), {widget: document.createTextNode("→")});
+  var new01 = cm.cursorCoords(Pos(0, 1)), new11 = cm.cursorCoords(Pos(1, 1)),
+      new20 = cm.cursorCoords(Pos(2, 0)), new30 = cm.cursorCoords(Pos(3, 0));
+  near(new01.left, pos01.left, 1);
+  near(new01.top, pos01.top, 1);
+  is(new11.left > pos11.left, "at right, middle of line");
+  near(new11.top == pos11.top, 1);
+  near(new20.left, pos20.left, 1);
+  near(new20.top, pos20.top, 1);
+  is(new30.left > pos30.left, "at right, empty line");
+  near(new30.top, pos30, 1);
+  cm.setBookmark(Pos(4, 0), {widget: document.createTextNode("→")});
+  is(cm.cursorCoords(Pos(4, 1)).left > pos41.left, "single-char bug");
+}, {value: "foo\nbar\n\n\nx\ny"});
+
+testCM("multiBookmarkCursor", function(cm) {
+  if (phantom) return;
+  var ms = [], m;
+  function add(insertLeft) {
+    for (var i = 0; i < 3; ++i) {
+      var node = document.createElement("span");
+      node.innerHTML = "X";
+      ms.push(cm.setBookmark(Pos(0, 1), {widget: node, insertLeft: insertLeft}));
+    }
+  }
+  var base1 = cm.cursorCoords(Pos(0, 1)).left, base4 = cm.cursorCoords(Pos(0, 4)).left;
+  add(true);
+  near(base1, cm.cursorCoords(Pos(0, 1)).left, 1);
+  while (m = ms.pop()) m.clear();
+  add(false);
+  near(base4, cm.cursorCoords(Pos(0, 1)).left, 1);
+}, {value: "abcdefg"});
+
+testCM("getAllMarks", function(cm) {
+  addDoc(cm, 10, 10);
+  var m1 = cm.setBookmark(Pos(0, 2));
+  var m2 = cm.markText(Pos(0, 2), Pos(3, 2));
+  var m3 = cm.markText(Pos(1, 2), Pos(1, 8));
+  var m4 = cm.markText(Pos(8, 0), Pos(9, 0));
+  eq(cm.getAllMarks().length, 4);
+  m1.clear();
+  m3.clear();
+  eq(cm.getAllMarks().length, 2);
+});
+
+testCM("bug577", function(cm) {
+  cm.setValue("a\nb");
+  cm.clearHistory();
+  cm.setValue("fooooo");
+  cm.undo();
+});
+
+testCM("scrollSnap", function(cm) {
+  cm.setSize(100, 100);
+  addDoc(cm, 200, 200);
+  cm.setCursor(Pos(100, 180));
+  var info = cm.getScrollInfo();
+  is(info.left > 0 && info.top > 0);
+  cm.setCursor(Pos(0, 0));
+  info = cm.getScrollInfo();
+  is(info.left == 0 && info.top == 0, "scrolled clean to top");
+  cm.setCursor(Pos(100, 180));
+  cm.setCursor(Pos(199, 0));
+  info = cm.getScrollInfo();
+  is(info.left == 0 && info.top + 2 > info.height - cm.getScrollerElement().clientHeight, "scrolled clean to bottom");
+});
+
+testCM("scrollIntoView", function(cm) {
+  if (phantom) return;
+  var outer = cm.getWrapperElement().getBoundingClientRect();
+  function test(line, ch, msg) {
+    var pos = Pos(line, ch);
+    cm.scrollIntoView(pos);
+    var box = cm.charCoords(pos, "window");
+    is(box.left >= outer.left, msg + " (left)");
+    is(box.right <= outer.right, msg + " (right)");
+    is(box.top >= outer.top, msg + " (top)");
+    is(box.bottom <= outer.bottom, msg + " (bottom)");
+  }
+  addDoc(cm, 200, 200);
+  test(199, 199, "bottom right");
+  test(0, 0, "top left");
+  test(100, 100, "center");
+  test(199, 0, "bottom left");
+  test(0, 199, "top right");
+  test(100, 100, "center again");
+});
+
+testCM("scrollBackAndForth", function(cm) {
+  addDoc(cm, 1, 200);
+  cm.operation(function() {
+    cm.scrollIntoView(Pos(199, 0));
+    cm.scrollIntoView(Pos(4, 0));
+  });
+  is(cm.getScrollInfo().top > 0);
+});
+
+testCM("selectAllNoScroll", function(cm) {
+  addDoc(cm, 1, 200);
+  cm.execCommand("selectAll");
+  eq(cm.getScrollInfo().top, 0);
+  cm.setCursor(199);
+  cm.execCommand("selectAll");
+  is(cm.getScrollInfo().top > 0);
+});
+
+testCM("selectionPos", function(cm) {
+  if (phantom) return;
+  cm.setSize(100, 100);
+  addDoc(cm, 200, 100);
+  cm.setSelection(Pos(1, 100), Pos(98, 100));
+  var lineWidth = cm.charCoords(Pos(0, 200), "local").left;
+  var lineHeight = (cm.charCoords(Pos(99)).top - cm.charCoords(Pos(0)).top) / 100;
+  cm.scrollTo(0, 0);
+  var selElt = byClassName(cm.getWrapperElement(), "CodeMirror-selected");
+  var outer = cm.getWrapperElement().getBoundingClientRect();
+  var sawMiddle, sawTop, sawBottom;
+  for (var i = 0, e = selElt.length; i < e; ++i) {
+    var box = selElt[i].getBoundingClientRect();
+    var atLeft = box.left - outer.left < 30;
+    var width = box.right - box.left;
+    var atRight = box.right - outer.left > .8 * lineWidth;
+    if (atLeft && atRight) {
+      sawMiddle = true;
+      is(box.bottom - box.top > 90 * lineHeight, "middle high");
+      is(width > .9 * lineWidth, "middle wide");
+    } else {
+      is(width > .4 * lineWidth, "top/bot wide enough");
+      is(width < .6 * lineWidth, "top/bot slim enough");
+      if (atLeft) {
+        sawBottom = true;
+        is(box.top - outer.top > 96 * lineHeight, "bot below");
+      } else if (atRight) {
+        sawTop = true;
+        is(box.top - outer.top < 2.1 * lineHeight, "top above");
+      }
+    }
+  }
+  is(sawTop && sawBottom && sawMiddle, "all parts");
+}, null);
+
+testCM("restoreHistory", function(cm) {
+  cm.setValue("abc\ndef");
+  cm.replaceRange("hello", Pos(1, 0), Pos(1));
+  cm.replaceRange("goop", Pos(0, 0), Pos(0));
+  cm.undo();
+  var storedVal = cm.getValue(), storedHist = cm.getHistory();
+  if (window.JSON) storedHist = JSON.parse(JSON.stringify(storedHist));
+  eq(storedVal, "abc\nhello");
+  cm.setValue("");
+  cm.clearHistory();
+  eq(cm.historySize().undo, 0);
+  cm.setValue(storedVal);
+  cm.setHistory(storedHist);
+  cm.redo();
+  eq(cm.getValue(), "goop\nhello");
+  cm.undo(); cm.undo();
+  eq(cm.getValue(), "abc\ndef");
+});
+
+testCM("doubleScrollbar", function(cm) {
+  var dummy = document.body.appendChild(document.createElement("p"));
+  dummy.style.cssText = "height: 50px; overflow: scroll; width: 50px";
+  var scrollbarWidth = dummy.offsetWidth + 1 - dummy.clientWidth;
+  document.body.removeChild(dummy);
+  if (scrollbarWidth < 2) return;
+  cm.setSize(null, 100);
+  addDoc(cm, 1, 300);
+  var wrap = cm.getWrapperElement();
+  is(wrap.offsetWidth - byClassName(wrap, "CodeMirror-lines")[0].offsetWidth <= scrollbarWidth * 1.5);
+});
+
+testCM("weirdLinebreaks", function(cm) {
+  cm.setValue("foo\nbar\rbaz\r\nquux\n\rplop");
+  is(cm.getValue(), "foo\nbar\nbaz\nquux\n\nplop");
+  is(cm.lineCount(), 6);
+  cm.setValue("\n\n");
+  is(cm.lineCount(), 3);
+});
+
+testCM("setSize", function(cm) {
+  cm.setSize(100, 100);
+  var wrap = cm.getWrapperElement();
+  is(wrap.offsetWidth, 100);
+  is(wrap.offsetHeight, 100);
+  cm.setSize("100%", "3em");
+  is(wrap.style.width, "100%");
+  is(wrap.style.height, "3em");
+  cm.setSize(null, 40);
+  is(wrap.style.width, "100%");
+  is(wrap.style.height, "40px");
+});
+
+function foldLines(cm, start, end, autoClear) {
+  return cm.markText(Pos(start, 0), Pos(end - 1), {
+    inclusiveLeft: true,
+    inclusiveRight: true,
+    collapsed: true,
+    clearOnEnter: autoClear
+  });
+}
+
+testCM("collapsedLines", function(cm) {
+  addDoc(cm, 4, 10);
+  var range = foldLines(cm, 4, 5), cleared = 0;
+  CodeMirror.on(range, "clear", function() {cleared++;});
+  cm.setCursor(Pos(3, 0));
+  CodeMirror.commands.goLineDown(cm);
+  eqPos(cm.getCursor(), Pos(5, 0));
+  cm.replaceRange("abcdefg", Pos(3, 0), Pos(3));
+  cm.setCursor(Pos(3, 6));
+  CodeMirror.commands.goLineDown(cm);
+  eqPos(cm.getCursor(), Pos(5, 4));
+  cm.replaceRange("ab", Pos(3, 0), Pos(3));
+  cm.setCursor(Pos(3, 2));
+  CodeMirror.commands.goLineDown(cm);
+  eqPos(cm.getCursor(), Pos(5, 2));
+  cm.operation(function() {range.clear(); range.clear();});
+  eq(cleared, 1);
+});
+
+testCM("collapsedRangeCoordsChar", function(cm) {
+  var pos_1_3 = cm.charCoords(Pos(1, 3));
+  pos_1_3.left += 2; pos_1_3.top += 2;
+  var opts = {collapsed: true, inclusiveLeft: true, inclusiveRight: true};
+  var m1 = cm.markText(Pos(0, 0), Pos(2, 0), opts);
+  eqPos(cm.coordsChar(pos_1_3), Pos(3, 3));
+  m1.clear();
+  var m1 = cm.markText(Pos(0, 0), Pos(1, 1), {collapsed: true, inclusiveLeft: true});
+  var m2 = cm.markText(Pos(1, 1), Pos(2, 0), {collapsed: true, inclusiveRight: true});
+  eqPos(cm.coordsChar(pos_1_3), Pos(3, 3));
+  m1.clear(); m2.clear();
+  var m1 = cm.markText(Pos(0, 0), Pos(1, 6), opts);
+  eqPos(cm.coordsChar(pos_1_3), Pos(3, 3));
+}, {value: "123456\nabcdef\nghijkl\nmnopqr\n"});
+
+testCM("collapsedRangeBetweenLinesSelected", function(cm) {
+  var widget = document.createElement("span");
+  widget.textContent = "\u2194";
+  cm.markText(Pos(0, 3), Pos(1, 0), {replacedWith: widget});
+  cm.setSelection(Pos(0, 3), Pos(1, 0));
+  var selElts = byClassName(cm.getWrapperElement(), "CodeMirror-selected");
+  for (var i = 0, w = 0; i < selElts.length; i++)
+    w += selElts[i].offsetWidth;
+  is(w > 0);
+}, {value: "one\ntwo"});
+
+testCM("randomCollapsedRanges", function(cm) {
+  addDoc(cm, 20, 500);
+  cm.operation(function() {
+    for (var i = 0; i < 200; i++) {
+      var start = Pos(Math.floor(Math.random() * 500), Math.floor(Math.random() * 20));
+      if (i % 4)
+        try { cm.markText(start, Pos(start.line + 2, 1), {collapsed: true}); }
+        catch(e) { if (!/overlapping/.test(String(e))) throw e; }
+      else
+        cm.markText(start, Pos(start.line, start.ch + 4), {"className": "foo"});
+    }
+  });
+});
+
+testCM("hiddenLinesAutoUnfold", function(cm) {
+  var range = foldLines(cm, 1, 3, true), cleared = 0;
+  CodeMirror.on(range, "clear", function() {cleared++;});
+  cm.setCursor(Pos(3, 0));
+  eq(cleared, 0);
+  cm.execCommand("goCharLeft");
+  eq(cleared, 1);
+  range = foldLines(cm, 1, 3, true);
+  CodeMirror.on(range, "clear", function() {cleared++;});
+  eqPos(cm.getCursor(), Pos(3, 0));
+  cm.setCursor(Pos(0, 3));
+  cm.execCommand("goCharRight");
+  eq(cleared, 2);
+}, {value: "abc\ndef\nghi\njkl"});
+
+testCM("hiddenLinesSelectAll", function(cm) {  // Issue #484
+  addDoc(cm, 4, 20);
+  foldLines(cm, 0, 10);
+  foldLines(cm, 11, 20);
+  CodeMirror.commands.selectAll(cm);
+  eqPos(cm.getCursor(true), Pos(10, 0));
+  eqPos(cm.getCursor(false), Pos(10, 4));
+});
+
+
+testCM("everythingFolded", function(cm) {
+  addDoc(cm, 2, 2);
+  function enterPress() {
+    cm.triggerOnKeyDown({type: "keydown", keyCode: 13, preventDefault: function(){}, stopPropagation: function(){}});
+  }
+  var fold = foldLines(cm, 0, 2);
+  enterPress();
+  eq(cm.getValue(), "xx\nxx");
+  fold.clear();
+  fold = foldLines(cm, 0, 2, true);
+  eq(fold.find(), null);
+  enterPress();
+  eq(cm.getValue(), "\nxx\nxx");
+});
+
+testCM("structuredFold", function(cm) {
+  if (phantom) return;
+  addDoc(cm, 4, 8);
+  var range = cm.markText(Pos(1, 2), Pos(6, 2), {
+    replacedWith: document.createTextNode("Q")
+  });
+  cm.setCursor(0, 3);
+  CodeMirror.commands.goLineDown(cm);
+  eqPos(cm.getCursor(), Pos(6, 2));
+  CodeMirror.commands.goCharLeft(cm);
+  eqPos(cm.getCursor(), Pos(1, 2));
+  CodeMirror.commands.delCharAfter(cm);
+  eq(cm.getValue(), "xxxx\nxxxx\nxxxx");
+  addDoc(cm, 4, 8);
+  range = cm.markText(Pos(1, 2), Pos(6, 2), {
+    replacedWith: document.createTextNode("M"),
+    clearOnEnter: true
+  });
+  var cleared = 0;
+  CodeMirror.on(range, "clear", function(){++cleared;});
+  cm.setCursor(0, 3);
+  CodeMirror.commands.goLineDown(cm);
+  eqPos(cm.getCursor(), Pos(6, 2));
+  CodeMirror.commands.goCharLeft(cm);
+  eqPos(cm.getCursor(), Pos(6, 1));
+  eq(cleared, 1);
+  range.clear();
+  eq(cleared, 1);
+  range = cm.markText(Pos(1, 2), Pos(6, 2), {
+    replacedWith: document.createTextNode("Q"),
+    clearOnEnter: true
+  });
+  range.clear();
+  cm.setCursor(1, 2);
+  CodeMirror.commands.goCharRight(cm);
+  eqPos(cm.getCursor(), Pos(1, 3));
+  range = cm.markText(Pos(2, 0), Pos(4, 4), {
+    replacedWith: document.createTextNode("M")
+  });
+  cm.setCursor(1, 0);
+  CodeMirror.commands.goLineDown(cm);
+  eqPos(cm.getCursor(), Pos(2, 0));
+}, null);
+
+testCM("nestedFold", function(cm) {
+  addDoc(cm, 10, 3);
+  function fold(ll, cl, lr, cr) {
+    return cm.markText(Pos(ll, cl), Pos(lr, cr), {collapsed: true});
+  }
+  var inner1 = fold(0, 6, 1, 3), inner2 = fold(0, 2, 1, 8), outer = fold(0, 1, 2, 3), inner0 = fold(0, 5, 0, 6);
+  cm.setCursor(0, 1);
+  CodeMirror.commands.goCharRight(cm);
+  eqPos(cm.getCursor(), Pos(2, 3));
+  inner0.clear();
+  CodeMirror.commands.goCharLeft(cm);
+  eqPos(cm.getCursor(), Pos(0, 1));
+  outer.clear();
+  CodeMirror.commands.goCharRight(cm);
+  eqPos(cm.getCursor(), Pos(0, 2));
+  CodeMirror.commands.goCharRight(cm);
+  eqPos(cm.getCursor(), Pos(1, 8));
+  inner2.clear();
+  CodeMirror.commands.goCharLeft(cm);
+  eqPos(cm.getCursor(), Pos(1, 7));
+  cm.setCursor(0, 5);
+  CodeMirror.commands.goCharRight(cm);
+  eqPos(cm.getCursor(), Pos(0, 6));
+  CodeMirror.commands.goCharRight(cm);
+  eqPos(cm.getCursor(), Pos(1, 3));
+});
+
+testCM("badNestedFold", function(cm) {
+  addDoc(cm, 4, 4);
+  cm.markText(Pos(0, 2), Pos(3, 2), {collapsed: true});
+  var caught;
+  try {cm.markText(Pos(0, 1), Pos(0, 3), {collapsed: true});}
+  catch(e) {caught = e;}
+  is(caught instanceof Error, "no error");
+  is(/overlap/i.test(caught.message), "wrong error");
+});
+
+testCM("nestedFoldOnSide", function(cm) {
+  var m1 = cm.markText(Pos(0, 1), Pos(2, 1), {collapsed: true, inclusiveRight: true});
+  var m2 = cm.markText(Pos(0, 1), Pos(0, 2), {collapsed: true});
+  cm.markText(Pos(0, 1), Pos(0, 2), {collapsed: true}).clear();
+  try { cm.markText(Pos(0, 1), Pos(0, 2), {collapsed: true, inclusiveLeft: true}); }
+  catch(e) { var caught = e; }
+  is(caught && /overlap/i.test(caught.message));
+  var m3 = cm.markText(Pos(2, 0), Pos(2, 1), {collapsed: true});
+  var m4 = cm.markText(Pos(2, 0), Pos(2, 1), {collapse: true, inclusiveRight: true});
+  m1.clear(); m4.clear();
+  m1 = cm.markText(Pos(0, 1), Pos(2, 1), {collapsed: true});
+  cm.markText(Pos(2, 0), Pos(2, 1), {collapsed: true}).clear();
+  try { cm.markText(Pos(2, 0), Pos(2, 1), {collapsed: true, inclusiveRight: true}); }
+  catch(e) { var caught = e; }
+  is(caught && /overlap/i.test(caught.message));
+}, {value: "ab\ncd\ef"});
+
+testCM("editInFold", function(cm) {
+  addDoc(cm, 4, 6);
+  var m = cm.markText(Pos(1, 2), Pos(3, 2), {collapsed: true});
+  cm.replaceRange("", Pos(0, 0), Pos(1, 3));
+  cm.replaceRange("", Pos(2, 1), Pos(3, 3));
+  cm.replaceRange("a\nb\nc\nd", Pos(0, 1), Pos(1, 0));
+  cm.cursorCoords(Pos(0, 0));
+});
+
+testCM("wrappingInlineWidget", function(cm) {
+  cm.setSize("11em");
+  var w = document.createElement("span");
+  w.style.color = "red";
+  w.innerHTML = "one two three four";
+  cm.markText(Pos(0, 6), Pos(0, 9), {replacedWith: w});
+  var cur0 = cm.cursorCoords(Pos(0, 0)), cur1 = cm.cursorCoords(Pos(0, 10));
+  is(cur0.top < cur1.top);
+  is(cur0.bottom < cur1.bottom);
+  var curL = cm.cursorCoords(Pos(0, 6)), curR = cm.cursorCoords(Pos(0, 9));
+  eq(curL.top, cur0.top);
+  eq(curL.bottom, cur0.bottom);
+  eq(curR.top, cur1.top);
+  eq(curR.bottom, cur1.bottom);
+  cm.replaceRange("", Pos(0, 9), Pos(0));
+  curR = cm.cursorCoords(Pos(0, 9));
+  if (phantom) return;
+  eq(curR.top, cur1.top);
+  eq(curR.bottom, cur1.bottom);
+}, {value: "1 2 3 xxx 4", lineWrapping: true});
+
+testCM("changedInlineWidget", function(cm) {
+  cm.setSize("10em");
+  var w = document.createElement("span");
+  w.innerHTML = "x";
+  var m = cm.markText(Pos(0, 4), Pos(0, 5), {replacedWith: w});
+  w.innerHTML = "and now the widget is really really long all of a sudden and a scrollbar is needed";
+  m.changed();
+  var hScroll = byClassName(cm.getWrapperElement(), "CodeMirror-hscrollbar")[0];
+  is(hScroll.scrollWidth > hScroll.clientWidth);
+}, {value: "hello there"});
+
+testCM("changedBookmark", function(cm) {
+  cm.setSize("10em");
+  var w = document.createElement("span");
+  w.innerHTML = "x";
+  var m = cm.setBookmark(Pos(0, 4), {widget: w});
+  w.innerHTML = "and now the widget is really really long all of a sudden and a scrollbar is needed";
+  m.changed();
+  var hScroll = byClassName(cm.getWrapperElement(), "CodeMirror-hscrollbar")[0];
+  is(hScroll.scrollWidth > hScroll.clientWidth);
+}, {value: "abcdefg"});
+
+testCM("inlineWidget", function(cm) {
+  var w = cm.setBookmark(Pos(0, 2), {widget: document.createTextNode("uu")});
+  cm.setCursor(0, 2);
+  CodeMirror.commands.goLineDown(cm);
+  eqPos(cm.getCursor(), Pos(1, 4));
+  cm.setCursor(0, 2);
+  cm.replaceSelection("hi");
+  eqPos(w.find(), Pos(0, 2));
+  cm.setCursor(0, 1);
+  cm.replaceSelection("ay");
+  eqPos(w.find(), Pos(0, 4));
+  eq(cm.getLine(0), "uayuhiuu");
+}, {value: "uuuu\nuuuuuu"});
+
+testCM("wrappingAndResizing", function(cm) {
+  cm.setSize(null, "auto");
+  cm.setOption("lineWrapping", true);
+  var wrap = cm.getWrapperElement(), h0 = wrap.offsetHeight;
+  var doc = "xxx xxx xxx xxx xxx";
+  cm.setValue(doc);
+  for (var step = 10, w = cm.charCoords(Pos(0, 18), "div").right;; w += step) {
+    cm.setSize(w);
+    if (wrap.offsetHeight <= h0 * (opera_lt10 ? 1.2 : 1.5)) {
+      if (step == 10) { w -= 10; step = 1; }
+      else break;
+    }
+  }
+  // Ensure that putting the cursor at the end of the maximally long
+  // line doesn't cause wrapping to happen.
+  cm.setCursor(Pos(0, doc.length));
+  eq(wrap.offsetHeight, h0);
+  cm.replaceSelection("x");
+  is(wrap.offsetHeight > h0, "wrapping happens");
+  // Now add a max-height and, in a document consisting of
+  // almost-wrapped lines, go over it so that a scrollbar appears.
+  cm.setValue(doc + "\n" + doc + "\n");
+  cm.getScrollerElement().style.maxHeight = "100px";
+  cm.replaceRange("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n!\n", Pos(2, 0));
+  forEach([Pos(0, doc.length), Pos(0, doc.length - 1),
+           Pos(0, 0), Pos(1, doc.length), Pos(1, doc.length - 1)],
+          function(pos) {
+    var coords = cm.charCoords(pos);
+    eqPos(pos, cm.coordsChar({left: coords.left + 2, top: coords.top + 5}));
+  });
+}, null, ie_lt8);
+
+testCM("measureEndOfLine", function(cm) {
+  cm.setSize(null, "auto");
+  var inner = byClassName(cm.getWrapperElement(), "CodeMirror-lines")[0].firstChild;
+  var lh = inner.offsetHeight;
+  for (var step = 10, w = cm.charCoords(Pos(0, 7), "div").right;; w += step) {
+    cm.setSize(w);
+    if (inner.offsetHeight < 2.5 * lh) {
+      if (step == 10) { w -= 10; step = 1; }
+      else break;
+    }
+  }
+  cm.setValue(cm.getValue() + "\n\n");
+  var endPos = cm.charCoords(Pos(0, 18), "local");
+  is(endPos.top > lh * .8, "not at top");
+  is(endPos.left > w - 20, "not at right");
+  endPos = cm.charCoords(Pos(0, 18));
+  eqPos(cm.coordsChar({left: endPos.left, top: endPos.top + 5}), Pos(0, 18));
+}, {mode: "text/html", value: "<!-- foo barrr -->", lineWrapping: true}, ie_lt8 || opera_lt10);
+
+testCM("scrollVerticallyAndHorizontally", function(cm) {
+  cm.setSize(100, 100);
+  addDoc(cm, 40, 40);
+  cm.setCursor(39);
+  var wrap = cm.getWrapperElement(), bar = byClassName(wrap, "CodeMirror-vscrollbar")[0];
+  is(bar.offsetHeight < wrap.offsetHeight, "vertical scrollbar limited by horizontal one");
+  var cursorBox = byClassName(wrap, "CodeMirror-cursor")[0].getBoundingClientRect();
+  var editorBox = wrap.getBoundingClientRect();
+  is(cursorBox.bottom < editorBox.top + cm.getScrollerElement().clientHeight,
+     "bottom line visible");
+}, {lineNumbers: true});
+
+testCM("moveVstuck", function(cm) {
+  var lines = byClassName(cm.getWrapperElement(), "CodeMirror-lines")[0].firstChild, h0 = lines.offsetHeight;
+  var val = "fooooooooooooooooooooooooo baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar\n";
+  cm.setValue(val);
+  for (var w = cm.charCoords(Pos(0, 26), "div").right * 2.8;; w += 5) {
+    cm.setSize(w);
+    if (lines.offsetHeight <= 3.5 * h0) break;
+  }
+  cm.setCursor(Pos(0, val.length - 1));
+  cm.moveV(-1, "line");
+  eqPos(cm.getCursor(), Pos(0, 26));
+}, {lineWrapping: true}, ie_lt8 || opera_lt10);
+
+testCM("collapseOnMove", function(cm) {
+  cm.setSelection(Pos(0, 1), Pos(2, 4));
+  cm.execCommand("goLineUp");
+  is(!cm.somethingSelected());
+  eqPos(cm.getCursor(), Pos(0, 1));
+  cm.setSelection(Pos(0, 1), Pos(2, 4));
+  cm.execCommand("goPageDown");
+  is(!cm.somethingSelected());
+  eqPos(cm.getCursor(), Pos(2, 4));
+  cm.execCommand("goLineUp");
+  cm.execCommand("goLineUp");
+  eqPos(cm.getCursor(), Pos(0, 4));
+  cm.setSelection(Pos(0, 1), Pos(2, 4));
+  cm.execCommand("goCharLeft");
+  is(!cm.somethingSelected());
+  eqPos(cm.getCursor(), Pos(0, 1));
+}, {value: "aaaaa\nb\nccccc"});
+
+testCM("clickTab", function(cm) {
+  var p0 = cm.charCoords(Pos(0, 0));
+  eqPos(cm.coordsChar({left: p0.left + 5, top: p0.top + 5}), Pos(0, 0));
+  eqPos(cm.coordsChar({left: p0.right - 5, top: p0.top + 5}), Pos(0, 1));
+}, {value: "\t\n\n", lineWrapping: true, tabSize: 8});
+
+testCM("verticalScroll", function(cm) {
+  cm.setSize(100, 200);
+  cm.setValue("foo\nbar\nbaz\n");
+  var sc = cm.getScrollerElement(), baseWidth = sc.scrollWidth;
+  cm.replaceRange("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah", Pos(0, 0), Pos(0));
+  is(sc.scrollWidth > baseWidth, "scrollbar present");
+  cm.replaceRange("foo", Pos(0, 0), Pos(0));
+  if (!phantom) eq(sc.scrollWidth, baseWidth, "scrollbar gone");
+  cm.replaceRange("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah", Pos(0, 0), Pos(0));
+  cm.replaceRange("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbh", Pos(1, 0), Pos(1));
+  is(sc.scrollWidth > baseWidth, "present again");
+  var curWidth = sc.scrollWidth;
+  cm.replaceRange("foo", Pos(0, 0), Pos(0));
+  is(sc.scrollWidth < curWidth, "scrollbar smaller");
+  is(sc.scrollWidth > baseWidth, "but still present");
+});
+
+testCM("extraKeys", function(cm) {
+  var outcome;
+  function fakeKey(expected, code, props) {
+    if (typeof code == "string") code = code.charCodeAt(0);
+    var e = {type: "keydown", keyCode: code, preventDefault: function(){}, stopPropagation: function(){}};
+    if (props) for (var n in props) e[n] = props[n];
+    outcome = null;
+    cm.triggerOnKeyDown(e);
+    eq(outcome, expected);
+  }
+  CodeMirror.commands.testCommand = function() {outcome = "tc";};
+  CodeMirror.commands.goTestCommand = function() {outcome = "gtc";};
+  cm.setOption("extraKeys", {"Shift-X": function() {outcome = "sx";},
+                             "X": function() {outcome = "x";},
+                             "Ctrl-Alt-U": function() {outcome = "cau";},
+                             "End": "testCommand",
+                             "Home": "goTestCommand",
+                             "Tab": false});
+  fakeKey(null, "U");
+  fakeKey("cau", "U", {ctrlKey: true, altKey: true});
+  fakeKey(null, "U", {shiftKey: true, ctrlKey: true, altKey: true});
+  fakeKey("x", "X");
+  fakeKey("sx", "X", {shiftKey: true});
+  fakeKey("tc", 35);
+  fakeKey(null, 35, {shiftKey: true});
+  fakeKey("gtc", 36);
+  fakeKey("gtc", 36, {shiftKey: true});
+  fakeKey(null, 9);
+}, null, window.opera && mac);
+
+testCM("wordMovementCommands", function(cm) {
+  cm.execCommand("goWordLeft");
+  eqPos(cm.getCursor(), Pos(0, 0));
+  cm.execCommand("goWordRight"); cm.execCommand("goWordRight");
+  eqPos(cm.getCursor(), Pos(0, 7));
+  cm.execCommand("goWordLeft");
+  eqPos(cm.getCursor(), Pos(0, 5));
+  cm.execCommand("goWordRight"); cm.execCommand("goWordRight");
+  eqPos(cm.getCursor(), Pos(0, 12));
+  cm.execCommand("goWordLeft");
+  eqPos(cm.getCursor(), Pos(0, 9));
+  cm.execCommand("goWordRight"); cm.execCommand("goWordRight"); cm.execCommand("goWordRight");
+  eqPos(cm.getCursor(), Pos(0, 24));
+  cm.execCommand("goWordRight"); cm.execCommand("goWordRight");
+  eqPos(cm.getCursor(), Pos(1, 9));
+  cm.execCommand("goWordRight");
+  eqPos(cm.getCursor(), Pos(1, 13));
+  cm.execCommand("goWordRight"); cm.execCommand("goWordRight");
+  eqPos(cm.getCursor(), Pos(2, 0));
+}, {value: "this is (the) firstline.\na foo12\u00e9\u00f8\u00d7bar\n"});
+
+testCM("groupMovementCommands", function(cm) {
+  cm.execCommand("goGroupLeft");
+  eqPos(cm.getCursor(), Pos(0, 0));
+  cm.execCommand("goGroupRight");
+  eqPos(cm.getCursor(), Pos(0, 4));
+  cm.execCommand("goGroupRight");
+  eqPos(cm.getCursor(), Pos(0, 7));
+  cm.execCommand("goGroupRight");
+  eqPos(cm.getCursor(), Pos(0, 10));
+  cm.execCommand("goGroupLeft");
+  eqPos(cm.getCursor(), Pos(0, 7));
+  cm.execCommand("goGroupRight"); cm.execCommand("goGroupRight"); cm.execCommand("goGroupRight");
+  eqPos(cm.getCursor(), Pos(0, 15));
+  cm.setCursor(Pos(0, 17));
+  cm.execCommand("goGroupLeft");
+  eqPos(cm.getCursor(), Pos(0, 16));
+  cm.execCommand("goGroupLeft");
+  eqPos(cm.getCursor(), Pos(0, 14));
+  cm.execCommand("goGroupRight"); cm.execCommand("goGroupRight");
+  eqPos(cm.getCursor(), Pos(0, 20));
+  cm.execCommand("goGroupRight");
+  eqPos(cm.getCursor(), Pos(1, 0));
+  cm.execCommand("goGroupRight");
+  eqPos(cm.getCursor(), Pos(1, 2));
+  cm.execCommand("goGroupRight");
+  eqPos(cm.getCursor(), Pos(1, 5));
+  cm.execCommand("goGroupLeft"); cm.execCommand("goGroupLeft");
+  eqPos(cm.getCursor(), Pos(1, 0));
+  cm.execCommand("goGroupLeft");
+  eqPos(cm.getCursor(), Pos(0, 20));
+  cm.execCommand("goGroupLeft");
+  eqPos(cm.getCursor(), Pos(0, 16));
+}, {value: "booo ba---quux. ffff\n  abc d"});
+
+testCM("groupsAndWhitespace", function(cm) {
+  var positions = [Pos(0, 0), Pos(0, 2), Pos(0, 5), Pos(0, 9), Pos(0, 11),
+                   Pos(1, 0), Pos(1, 2), Pos(1, 5)];
+  for (var i = 1; i < positions.length; i++) {
+    cm.execCommand("goGroupRight");
+    eqPos(cm.getCursor(), positions[i]);
+  }
+  for (var i = positions.length - 2; i >= 0; i--) {
+    cm.execCommand("goGroupLeft");
+    eqPos(cm.getCursor(), i == 2 ? Pos(0, 6) : positions[i]);
+  }
+}, {value: "  foo +++  \n  bar"});
+
+testCM("charMovementCommands", function(cm) {
+  cm.execCommand("goCharLeft"); cm.execCommand("goColumnLeft");
+  eqPos(cm.getCursor(), Pos(0, 0));
+  cm.execCommand("goCharRight"); cm.execCommand("goCharRight");
+  eqPos(cm.getCursor(), Pos(0, 2));
+  cm.setCursor(Pos(1, 0));
+  cm.execCommand("goColumnLeft");
+  eqPos(cm.getCursor(), Pos(1, 0));
+  cm.execCommand("goCharLeft");
+  eqPos(cm.getCursor(), Pos(0, 5));
+  cm.execCommand("goColumnRight");
+  eqPos(cm.getCursor(), Pos(0, 5));
+  cm.execCommand("goCharRight");
+  eqPos(cm.getCursor(), Pos(1, 0));
+  cm.execCommand("goLineEnd");
+  eqPos(cm.getCursor(), Pos(1, 5));
+  cm.execCommand("goLineStartSmart");
+  eqPos(cm.getCursor(), Pos(1, 1));
+  cm.execCommand("goLineStartSmart");
+  eqPos(cm.getCursor(), Pos(1, 0));
+  cm.setCursor(Pos(2, 0));
+  cm.execCommand("goCharRight"); cm.execCommand("goColumnRight");
+  eqPos(cm.getCursor(), Pos(2, 0));
+}, {value: "line1\n ine2\n"});
+
+testCM("verticalMovementCommands", function(cm) {
+  cm.execCommand("goLineUp");
+  eqPos(cm.getCursor(), Pos(0, 0));
+  cm.execCommand("goLineDown");
+  if (!phantom) // This fails in PhantomJS, though not in a real Webkit
+    eqPos(cm.getCursor(), Pos(1, 0));
+  cm.setCursor(Pos(1, 12));
+  cm.execCommand("goLineDown");
+  eqPos(cm.getCursor(), Pos(2, 5));
+  cm.execCommand("goLineDown");
+  eqPos(cm.getCursor(), Pos(3, 0));
+  cm.execCommand("goLineUp");
+  eqPos(cm.getCursor(), Pos(2, 5));
+  cm.execCommand("goLineUp");
+  eqPos(cm.getCursor(), Pos(1, 12));
+  cm.execCommand("goPageDown");
+  eqPos(cm.getCursor(), Pos(5, 0));
+  cm.execCommand("goPageDown"); cm.execCommand("goLineDown");
+  eqPos(cm.getCursor(), Pos(5, 0));
+  cm.execCommand("goPageUp");
+  eqPos(cm.getCursor(), Pos(0, 0));
+}, {value: "line1\nlong long line2\nline3\n\nline5\n"});
+
+testCM("verticalMovementCommandsWrapping", function(cm) {
+  cm.setSize(120);
+  cm.setCursor(Pos(0, 5));
+  cm.execCommand("goLineDown");
+  eq(cm.getCursor().line, 0);
+  is(cm.getCursor().ch > 5, "moved beyond wrap");
+  for (var i = 0; ; ++i) {
+    is(i < 20, "no endless loop");
+    cm.execCommand("goLineDown");
+    var cur = cm.getCursor();
+    if (cur.line == 1) eq(cur.ch, 5);
+    if (cur.line == 2) { eq(cur.ch, 1); break; }
+  }
+}, {value: "a very long line that wraps around somehow so that we can test cursor movement\nshortone\nk",
+    lineWrapping: true});
+
+testCM("rtlMovement", function(cm) {
+  forEach(["خحج", "خحabcخحج", "abخحخحجcd", "abخde", "abخح2342خ1حج", "خ1ح2خح3حxج",
+           "خحcd", "1خحcd", "abcdeح1ج", "خمرحبها مها!", "foobarر", "خ ة ق",
+           "<img src=\"/בדיקה3.jpg\">"], function(line) {
+    var inv = line.charAt(0) == "Ø®";
+    cm.setValue(line + "\n"); cm.execCommand(inv ? "goLineEnd" : "goLineStart");
+    var cursors = byClassName(cm.getWrapperElement(), "CodeMirror-cursors")[0];
+    var cursor = cursors.firstChild;
+    var prevX = cursor.offsetLeft, prevY = cursor.offsetTop;
+    for (var i = 0; i <= line.length; ++i) {
+      cm.execCommand("goCharRight");
+      cursor = cursors.firstChild;
+      if (i == line.length) is(cursor.offsetTop > prevY, "next line");
+      else is(cursor.offsetLeft > prevX, "moved right");
+      prevX = cursor.offsetLeft; prevY = cursor.offsetTop;
+    }
+    cm.setCursor(0, 0); cm.execCommand(inv ? "goLineStart" : "goLineEnd");
+    prevX = cursors.firstChild.offsetLeft;
+    for (var i = 0; i < line.length; ++i) {
+      cm.execCommand("goCharLeft");
+      cursor = cursors.firstChild;
+      is(cursor.offsetLeft < prevX, "moved left");
+      prevX = cursor.offsetLeft;
+    }
+  });
+}, null, ie_lt9);
+
+// Verify that updating a line clears its bidi ordering
+testCM("bidiUpdate", function(cm) {
+  cm.setCursor(Pos(0, 2));
+  cm.replaceSelection("خحج", "start");
+  cm.execCommand("goCharRight");
+  eqPos(cm.getCursor(), Pos(0, 4));
+}, {value: "abcd\n"});
+
+testCM("movebyTextUnit", function(cm) {
+  cm.setValue("בְּרֵאשִ\nééé́\n");
+  cm.execCommand("goLineEnd");
+  for (var i = 0; i < 4; ++i) cm.execCommand("goCharRight");
+  eqPos(cm.getCursor(), Pos(0, 0));
+  cm.execCommand("goCharRight");
+  eqPos(cm.getCursor(), Pos(1, 0));
+  cm.execCommand("goCharRight");
+  cm.execCommand("goCharRight");
+  eqPos(cm.getCursor(), Pos(1, 4));
+  cm.execCommand("goCharRight");
+  eqPos(cm.getCursor(), Pos(1, 7));
+});
+
+testCM("lineChangeEvents", function(cm) {
+  addDoc(cm, 3, 5);
+  var log = [], want = ["ch 0", "ch 1", "del 2", "ch 0", "ch 0", "del 1", "del 3", "del 4"];
+  for (var i = 0; i < 5; ++i) {
+    CodeMirror.on(cm.getLineHandle(i), "delete", function(i) {
+      return function() {log.push("del " + i);};
+    }(i));
+    CodeMirror.on(cm.getLineHandle(i), "change", function(i) {
+      return function() {log.push("ch " + i);};
+    }(i));
+  }
+  cm.replaceRange("x", Pos(0, 1));
+  cm.replaceRange("xy", Pos(1, 1), Pos(2));
+  cm.replaceRange("foo\nbar", Pos(0, 1));
+  cm.replaceRange("", Pos(0, 0), Pos(cm.lineCount()));
+  eq(log.length, want.length, "same length");
+  for (var i = 0; i < log.length; ++i)
+    eq(log[i], want[i]);
+});
+
+testCM("scrollEntirelyToRight", function(cm) {
+  if (phantom) return;
+  addDoc(cm, 500, 2);
+  cm.setCursor(Pos(0, 500));
+  var wrap = cm.getWrapperElement(), cur = byClassName(wrap, "CodeMirror-cursor")[0];
+  is(wrap.getBoundingClientRect().right > cur.getBoundingClientRect().left);
+});
+
+testCM("lineWidgets", function(cm) {
+  addDoc(cm, 500, 3);
+  var last = cm.charCoords(Pos(2, 0));
+  var node = document.createElement("div");
+  node.innerHTML = "hi";
+  var widget = cm.addLineWidget(1, node);
+  is(last.top < cm.charCoords(Pos(2, 0)).top, "took up space");
+  cm.setCursor(Pos(1, 1));
+  cm.execCommand("goLineDown");
+  eqPos(cm.getCursor(), Pos(2, 1));
+  cm.execCommand("goLineUp");
+  eqPos(cm.getCursor(), Pos(1, 1));
+});
+
+testCM("lineWidgetFocus", function(cm) {
+  var place = document.getElementById("testground");
+  place.className = "offscreen";
+  try {
+    addDoc(cm, 500, 10);
+    var node = document.createElement("input");
+    var widget = cm.addLineWidget(1, node);
+    node.focus();
+    eq(document.activeElement, node);
+    cm.replaceRange("new stuff", Pos(1, 0));
+    eq(document.activeElement, node);
+  } finally {
+    place.className = "";
+  }
+});
+
+testCM("lineWidgetCautiousRedraw", function(cm) {
+  var node = document.createElement("div");
+  node.innerHTML = "hahah";
+  var w = cm.addLineWidget(0, node);
+  var redrawn = false;
+  w.on("redraw", function() { redrawn = true; });
+  cm.replaceSelection("0");
+  is(!redrawn);
+}, {value: "123\n456"});
+
+testCM("lineWidgetChanged", function(cm) {
+  addDoc(cm, 2, 300);
+  cm.setSize(null, cm.defaultTextHeight() * 50);
+  cm.scrollTo(null, cm.heightAtLine(125, "local"));
+  function w() {
+    var node = document.createElement("div");
+    node.style.cssText = "background: yellow; height: 50px;";
+    return node;
+  }
+  var info0 = cm.getScrollInfo();
+  var w0 = cm.addLineWidget(0, w());
+  var w150 = cm.addLineWidget(150, w());
+  var w300 = cm.addLineWidget(300, w());
+  var info1 = cm.getScrollInfo();
+  eq(info0.height + 150, info1.height);
+  eq(info0.top + 50, info1.top);
+  w0.node.style.height = w150.node.style.height = w300.node.style.height = "10px";
+  w0.changed(); w150.changed(); w300.changed();
+  var info2 = cm.getScrollInfo();
+  eq(info0.height + 30, info2.height);
+  eq(info0.top + 10, info2.top);
+});
+
+testCM("getLineNumber", function(cm) {
+  addDoc(cm, 2, 20);
+  var h1 = cm.getLineHandle(1);
+  eq(cm.getLineNumber(h1), 1);
+  cm.replaceRange("hi\nbye\n", Pos(0, 0));
+  eq(cm.getLineNumber(h1), 3);
+  cm.setValue("");
+  eq(cm.getLineNumber(h1), null);
+});
+
+testCM("jumpTheGap", function(cm) {
+  if (phantom) return;
+  var longLine = "abcdef ghiklmnop qrstuvw xyz ";
+  longLine += longLine; longLine += longLine; longLine += longLine;
+  cm.replaceRange(longLine, Pos(2, 0), Pos(2));
+  cm.setSize("200px", null);
+  cm.getWrapperElement().style.lineHeight = 2;
+  cm.refresh();
+  cm.setCursor(Pos(0, 1));
+  cm.execCommand("goLineDown");
+  eqPos(cm.getCursor(), Pos(1, 1));
+  cm.execCommand("goLineDown");
+  eqPos(cm.getCursor(), Pos(2, 1));
+  cm.execCommand("goLineDown");
+  eq(cm.getCursor().line, 2);
+  is(cm.getCursor().ch > 1);
+  cm.execCommand("goLineUp");
+  eqPos(cm.getCursor(), Pos(2, 1));
+  cm.execCommand("goLineUp");
+  eqPos(cm.getCursor(), Pos(1, 1));
+  var node = document.createElement("div");
+  node.innerHTML = "hi"; node.style.height = "30px";
+  cm.addLineWidget(0, node);
+  cm.addLineWidget(1, node.cloneNode(true), {above: true});
+  cm.setCursor(Pos(0, 2));
+  cm.execCommand("goLineDown");
+  eqPos(cm.getCursor(), Pos(1, 2));
+  cm.execCommand("goLineUp");
+  eqPos(cm.getCursor(), Pos(0, 2));
+}, {lineWrapping: true, value: "abc\ndef\nghi\njkl\n"});
+
+testCM("addLineClass", function(cm) {
+  function cls(line, text, bg, wrap) {
+    var i = cm.lineInfo(line);
+    eq(i.textClass, text);
+    eq(i.bgClass, bg);
+    eq(i.wrapClass, wrap);
+  }
+  cm.addLineClass(0, "text", "foo");
+  cm.addLineClass(0, "text", "bar");
+  cm.addLineClass(1, "background", "baz");
+  cm.addLineClass(1, "wrap", "foo");
+  cls(0, "foo bar", null, null);
+  cls(1, null, "baz", "foo");
+  var lines = cm.display.lineDiv;
+  eq(byClassName(lines, "foo").length, 2);
+  eq(byClassName(lines, "bar").length, 1);
+  eq(byClassName(lines, "baz").length, 1);
+  cm.removeLineClass(0, "text", "foo");
+  cls(0, "bar", null, null);
+  cm.removeLineClass(0, "text", "foo");
+  cls(0, "bar", null, null);
+  cm.removeLineClass(0, "text", "bar");
+  cls(0, null, null, null);
+  cm.addLineClass(1, "wrap", "quux");
+  cls(1, null, "baz", "foo quux");
+  cm.removeLineClass(1, "wrap");
+  cls(1, null, "baz", null);
+}, {value: "hohoho\n"});
+
+testCM("atomicMarker", function(cm) {
+  addDoc(cm, 10, 10);
+  function atom(ll, cl, lr, cr, li, ri) {
+    return cm.markText(Pos(ll, cl), Pos(lr, cr),
+                       {atomic: true, inclusiveLeft: li, inclusiveRight: ri});
+  }
+  var m = atom(0, 1, 0, 5);
+  cm.setCursor(Pos(0, 1));
+  cm.execCommand("goCharRight");
+  eqPos(cm.getCursor(), Pos(0, 5));
+  cm.execCommand("goCharLeft");
+  eqPos(cm.getCursor(), Pos(0, 1));
+  m.clear();
+  m = atom(0, 0, 0, 5, true);
+  eqPos(cm.getCursor(), Pos(0, 5), "pushed out");
+  cm.execCommand("goCharLeft");
+  eqPos(cm.getCursor(), Pos(0, 5));
+  m.clear();
+  m = atom(8, 4, 9, 10, false, true);
+  cm.setCursor(Pos(9, 8));
+  eqPos(cm.getCursor(), Pos(8, 4), "set");
+  cm.execCommand("goCharRight");
+  eqPos(cm.getCursor(), Pos(8, 4), "char right");
+  cm.execCommand("goLineDown");
+  eqPos(cm.getCursor(), Pos(8, 4), "line down");
+  cm.execCommand("goCharLeft");
+  eqPos(cm.getCursor(), Pos(8, 3));
+  m.clear();
+  m = atom(1, 1, 3, 8);
+  cm.setCursor(Pos(0, 0));
+  cm.setCursor(Pos(2, 0));
+  eqPos(cm.getCursor(), Pos(3, 8));
+  cm.execCommand("goCharLeft");
+  eqPos(cm.getCursor(), Pos(1, 1));
+  cm.execCommand("goCharRight");
+  eqPos(cm.getCursor(), Pos(3, 8));
+  cm.execCommand("goLineUp");
+  eqPos(cm.getCursor(), Pos(1, 1));
+  cm.execCommand("goLineDown");
+  eqPos(cm.getCursor(), Pos(3, 8));
+  cm.execCommand("delCharBefore");
+  eq(cm.getValue().length, 80, "del chunk");
+  m = atom(3, 0, 5, 5);
+  cm.setCursor(Pos(3, 0));
+  cm.execCommand("delWordAfter");
+  eq(cm.getValue().length, 53, "del chunk");
+});
+
+testCM("readOnlyMarker", function(cm) {
+  function mark(ll, cl, lr, cr, at) {
+    return cm.markText(Pos(ll, cl), Pos(lr, cr),
+                       {readOnly: true, atomic: at});
+  }
+  var m = mark(0, 1, 0, 4);
+  cm.setCursor(Pos(0, 2));
+  cm.replaceSelection("hi", "end");
+  eqPos(cm.getCursor(), Pos(0, 2));
+  eq(cm.getLine(0), "abcde");
+  cm.execCommand("selectAll");
+  cm.replaceSelection("oops", "around");
+  eq(cm.getValue(), "oopsbcd");
+  cm.undo();
+  eqPos(m.find().from, Pos(0, 1));
+  eqPos(m.find().to, Pos(0, 4));
+  m.clear();
+  cm.setCursor(Pos(0, 2));
+  cm.replaceSelection("hi", "around");
+  eq(cm.getLine(0), "abhicde");
+  eqPos(cm.getCursor(), Pos(0, 4));
+  m = mark(0, 2, 2, 2, true);
+  cm.setSelection(Pos(1, 1), Pos(2, 4));
+  cm.replaceSelection("t", "end");
+  eqPos(cm.getCursor(), Pos(2, 3));
+  eq(cm.getLine(2), "klto");
+  cm.execCommand("goCharLeft");
+  cm.execCommand("goCharLeft");
+  eqPos(cm.getCursor(), Pos(0, 2));
+  cm.setSelection(Pos(0, 1), Pos(0, 3));
+  cm.replaceSelection("xx", "around");
+  eqPos(cm.getCursor(), Pos(0, 3));
+  eq(cm.getLine(0), "axxhicde");
+}, {value: "abcde\nfghij\nklmno\n"});
+
+testCM("dirtyBit", function(cm) {
+  eq(cm.isClean(), true);
+  cm.replaceSelection("boo", null, "test");
+  eq(cm.isClean(), false);
+  cm.undo();
+  eq(cm.isClean(), true);
+  cm.replaceSelection("boo", null, "test");
+  cm.replaceSelection("baz", null, "test");
+  cm.undo();
+  eq(cm.isClean(), false);
+  cm.markClean();
+  eq(cm.isClean(), true);
+  cm.undo();
+  eq(cm.isClean(), false);
+  cm.redo();
+  eq(cm.isClean(), true);
+});
+
+testCM("changeGeneration", function(cm) {
+  cm.replaceSelection("x");
+  var softGen = cm.changeGeneration();
+  cm.replaceSelection("x");
+  cm.undo();
+  eq(cm.getValue(), "");
+  is(!cm.isClean(softGen));
+  cm.replaceSelection("x");
+  var hardGen = cm.changeGeneration(true);
+  cm.replaceSelection("x");
+  cm.undo();
+  eq(cm.getValue(), "x");
+  is(cm.isClean(hardGen));
+});
+
+testCM("addKeyMap", function(cm) {
+  function sendKey(code) {
+    cm.triggerOnKeyDown({type: "keydown", keyCode: code,
+                         preventDefault: function(){}, stopPropagation: function(){}});
+  }
+
+  sendKey(39);
+  eqPos(cm.getCursor(), Pos(0, 1));
+  var test = 0;
+  var map1 = {Right: function() { ++test; }}, map2 = {Right: function() { test += 10; }}
+  cm.addKeyMap(map1);
+  sendKey(39);
+  eqPos(cm.getCursor(), Pos(0, 1));
+  eq(test, 1);
+  cm.addKeyMap(map2, true);
+  sendKey(39);
+  eq(test, 2);
+  cm.removeKeyMap(map1);
+  sendKey(39);
+  eq(test, 12);
+  cm.removeKeyMap(map2);
+  sendKey(39);
+  eq(test, 12);
+  eqPos(cm.getCursor(), Pos(0, 2));
+  cm.addKeyMap({Right: function() { test = 55; }, name: "mymap"});
+  sendKey(39);
+  eq(test, 55);
+  cm.removeKeyMap("mymap");
+  sendKey(39);
+  eqPos(cm.getCursor(), Pos(0, 3));
+}, {value: "abc"});
+
+testCM("findPosH", function(cm) {
+  forEach([{from: Pos(0, 0), to: Pos(0, 1), by: 1},
+           {from: Pos(0, 0), to: Pos(0, 0), by: -1, hitSide: true},
+           {from: Pos(0, 0), to: Pos(0, 4), by: 1, unit: "word"},
+           {from: Pos(0, 0), to: Pos(0, 8), by: 2, unit: "word"},
+           {from: Pos(0, 0), to: Pos(2, 0), by: 20, unit: "word", hitSide: true},
+           {from: Pos(0, 7), to: Pos(0, 5), by: -1, unit: "word"},
+           {from: Pos(0, 4), to: Pos(0, 8), by: 1, unit: "word"},
+           {from: Pos(1, 0), to: Pos(1, 18), by: 3, unit: "word"},
+           {from: Pos(1, 22), to: Pos(1, 5), by: -3, unit: "word"},
+           {from: Pos(1, 15), to: Pos(1, 10), by: -5},
+           {from: Pos(1, 15), to: Pos(1, 10), by: -5, unit: "column"},
+           {from: Pos(1, 15), to: Pos(1, 0), by: -50, unit: "column", hitSide: true},
+           {from: Pos(1, 15), to: Pos(1, 24), by: 50, unit: "column", hitSide: true},
+           {from: Pos(1, 15), to: Pos(2, 0), by: 50, hitSide: true}], function(t) {
+    var r = cm.findPosH(t.from, t.by, t.unit || "char");
+    eqPos(r, t.to);
+    eq(!!r.hitSide, !!t.hitSide);
+  });
+}, {value: "line one\nline two.something.other\n"});
+
+testCM("beforeChange", function(cm) {
+  cm.on("beforeChange", function(cm, change) {
+    var text = [];
+    for (var i = 0; i < change.text.length; ++i)
+      text.push(change.text[i].replace(/\s/g, "_"));
+    change.update(null, null, text);
+  });
+  cm.setValue("hello, i am a\nnew document\n");
+  eq(cm.getValue(), "hello,_i_am_a\nnew_document\n");
+  CodeMirror.on(cm.getDoc(), "beforeChange", function(doc, change) {
+    if (change.from.line == 0) change.cancel();
+  });
+  cm.setValue("oops"); // Canceled
+  eq(cm.getValue(), "hello,_i_am_a\nnew_document\n");
+  cm.replaceRange("hey hey hey", Pos(1, 0), Pos(2, 0));
+  eq(cm.getValue(), "hello,_i_am_a\nhey_hey_hey");
+}, {value: "abcdefghijk"});
+
+testCM("beforeChangeUndo", function(cm) {
+  cm.replaceRange("hi", Pos(0, 0), Pos(0));
+  cm.replaceRange("bye", Pos(0, 0), Pos(0));
+  eq(cm.historySize().undo, 2);
+  cm.on("beforeChange", function(cm, change) {
+    is(!change.update);
+    change.cancel();
+  });
+  cm.undo();
+  eq(cm.historySize().undo, 0);
+  eq(cm.getValue(), "bye\ntwo");
+}, {value: "one\ntwo"});
+
+testCM("beforeSelectionChange", function(cm) {
+  function notAtEnd(cm, pos) {
+    var len = cm.getLine(pos.line).length;
+    if (!len || pos.ch == len) return Pos(pos.line, pos.ch - 1);
+    return pos;
+  }
+  cm.on("beforeSelectionChange", function(cm, obj) {
+    obj.update([{anchor: notAtEnd(cm, obj.ranges[0].anchor),
+                 head: notAtEnd(cm, obj.ranges[0].head)}]);
+  });
+
+  addDoc(cm, 10, 10);
+  cm.execCommand("goLineEnd");
+  eqPos(cm.getCursor(), Pos(0, 9));
+  cm.execCommand("selectAll");
+  eqPos(cm.getCursor("start"), Pos(0, 0));
+  eqPos(cm.getCursor("end"), Pos(9, 9));
+});
+
+testCM("change_removedText", function(cm) {
+  cm.setValue("abc\ndef");
+
+  var removedText = [];
+  cm.on("change", function(cm, change) {
+    removedText.push(change.removed);
+  });
+
+  cm.operation(function() {
+    cm.replaceRange("xyz", Pos(0, 0), Pos(1,1));
+    cm.replaceRange("123", Pos(0,0));
+  });
+
+  eq(removedText.length, 2);
+  eq(removedText[0].join("\n"), "abc\nd");
+  eq(removedText[1].join("\n"), "");
+
+  var removedText = [];
+  cm.undo();
+  eq(removedText.length, 2);
+  eq(removedText[0].join("\n"), "123");
+  eq(removedText[1].join("\n"), "xyz");
+
+  var removedText = [];
+  cm.redo();
+  eq(removedText.length, 2);
+  eq(removedText[0].join("\n"), "abc\nd");
+  eq(removedText[1].join("\n"), "");
+});
+
+testCM("lineStyleFromMode", function(cm) {
+  CodeMirror.defineMode("test_mode", function() {
+    return {token: function(stream) {
+      if (stream.match(/^\[[^\]]*\]/)) return "  line-brackets  ";
+      if (stream.match(/^\([^\)]*\)/)) return "  line-background-parens  ";
+      if (stream.match(/^<[^>]*>/)) return "  span  line-line  line-background-bg  ";
+      stream.match(/^\s+|^\S+/);
+    }};
+  });
+  cm.setOption("mode", "test_mode");
+  var bracketElts = byClassName(cm.getWrapperElement(), "brackets");
+  eq(bracketElts.length, 1, "brackets count");
+  eq(bracketElts[0].nodeName, "PRE");
+  is(!/brackets.*brackets/.test(bracketElts[0].className));
+  var parenElts = byClassName(cm.getWrapperElement(), "parens");
+  eq(parenElts.length, 1, "parens count");
+  eq(parenElts[0].nodeName, "DIV");
+  is(!/parens.*parens/.test(parenElts[0].className));
+  eq(parenElts[0].parentElement.nodeName, "DIV");
+
+  eq(byClassName(cm.getWrapperElement(), "bg").length, 1);
+  eq(byClassName(cm.getWrapperElement(), "line").length, 1);
+  var spanElts = byClassName(cm.getWrapperElement(), "cm-span");
+  eq(spanElts.length, 2);
+  is(/^\s*cm-span\s*$/.test(spanElts[0].className));
+}, {value: "line1: [br] [br]\nline2: (par) (par)\nline3: <tag> <tag>"});
+
+CodeMirror.registerHelper("xxx", "a", "A");
+CodeMirror.registerHelper("xxx", "b", "B");
+CodeMirror.defineMode("yyy", function() {
+  return {
+    token: function(stream) { stream.skipToEnd(); },
+    xxx: ["a", "b", "q"]
+  };
+});
+CodeMirror.registerGlobalHelper("xxx", "c", function(m) { return m.enableC; }, "C");
+
+testCM("helpers", function(cm) {
+  cm.setOption("mode", "yyy");
+  eq(cm.getHelpers(Pos(0, 0), "xxx").join("/"), "A/B");
+  cm.setOption("mode", {name: "yyy", modeProps: {xxx: "b", enableC: true}});
+  eq(cm.getHelpers(Pos(0, 0), "xxx").join("/"), "B/C");
+  cm.setOption("mode", "javascript");
+  eq(cm.getHelpers(Pos(0, 0), "xxx").join("/"), "");
+});
+
+testCM("selectionHistory", function(cm) {
+  for (var i = 0; i < 3; i++) {
+    cm.setExtending(true);
+    cm.execCommand("goCharRight");
+    cm.setExtending(false);
+    cm.execCommand("goCharRight");
+    cm.execCommand("goCharRight");
+  }
+  cm.execCommand("undoSelection");
+  eq(cm.getSelection(), "c");
+  cm.execCommand("undoSelection");
+  eq(cm.getSelection(), "");
+  eqPos(cm.getCursor(), Pos(0, 4));
+  cm.execCommand("undoSelection");
+  eq(cm.getSelection(), "b");
+  cm.execCommand("redoSelection");
+  eq(cm.getSelection(), "");
+  eqPos(cm.getCursor(), Pos(0, 4));
+  cm.execCommand("redoSelection");
+  eq(cm.getSelection(), "c");
+  cm.execCommand("redoSelection");
+  eq(cm.getSelection(), "");
+  eqPos(cm.getCursor(), Pos(0, 6));
+}, {value: "a b c d"});
+
+testCM("selectionChangeReducesRedo", function(cm) {
+  cm.replaceSelection("X");
+  cm.execCommand("goCharRight");
+  cm.undoSelection();
+  cm.execCommand("selectAll");
+  cm.undoSelection();
+  eq(cm.getValue(), "Xabc");
+  eqPos(cm.getCursor(), Pos(0, 1));
+  cm.undoSelection();
+  eq(cm.getValue(), "abc");
+}, {value: "abc"});
+
+testCM("selectionHistoryNonOverlapping", function(cm) {
+  cm.setSelection(Pos(0, 0), Pos(0, 1));
+  cm.setSelection(Pos(0, 2), Pos(0, 3));
+  cm.execCommand("undoSelection");
+  eqPos(cm.getCursor("anchor"), Pos(0, 0));
+  eqPos(cm.getCursor("head"), Pos(0, 1));
+}, {value: "1234"});
+
+testCM("cursorMotionSplitsHistory", function(cm) {
+  cm.replaceSelection("a");
+  cm.execCommand("goCharRight");
+  cm.replaceSelection("b");
+  cm.replaceSelection("c");
+  cm.undo();
+  eq(cm.getValue(), "a1234");
+  eqPos(cm.getCursor(), Pos(0, 2));
+  cm.undo();
+  eq(cm.getValue(), "1234");
+  eqPos(cm.getCursor(), Pos(0, 0));
+}, {value: "1234"});
+
+testCM("selChangeInOperationDoesNotSplit", function(cm) {
+  for (var i = 0; i < 4; i++) {
+    cm.operation(function() {
+      cm.replaceSelection("x");
+      cm.setCursor(Pos(0, cm.getCursor().ch - 1));
+    });
+  }
+  eqPos(cm.getCursor(), Pos(0, 0));
+  eq(cm.getValue(), "xxxxa");
+  cm.undo();
+  eq(cm.getValue(), "a");
+}, {value: "a"});
+
+testCM("alwaysMergeSelEventWithChangeOrigin", function(cm) {
+  cm.replaceSelection("U", null, "foo");
+  cm.setSelection(Pos(0, 0), Pos(0, 1), {origin: "foo"});
+  cm.undoSelection();
+  eq(cm.getValue(), "a");
+  cm.replaceSelection("V", null, "foo");
+  cm.setSelection(Pos(0, 0), Pos(0, 1), {origin: "bar"});
+  cm.undoSelection();
+  eq(cm.getValue(), "Va");
+}, {value: "a"});
diff --git a/app/gui/html/vendor/codemirror/test/vim_test.js b/app/gui/html/vendor/codemirror/test/vim_test.js
new file mode 100644
index 0000000..8522237
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/test/vim_test.js
@@ -0,0 +1,2859 @@
+var code = '' +
+' wOrd1 (#%\n' +
+' word3] \n' +
+'aopop pop 0 1 2 3 4\n' +
+' (a) [b] {c} \n' +
+'int getchar(void) {\n' +
+'  static char buf[BUFSIZ];\n' +
+'  static char *bufp = buf;\n' +
+'  if (n == 0) {  /* buffer is empty */\n' +
+'    n = read(0, buf, sizeof buf);\n' +
+'    bufp = buf;\n' +
+'  }\n' +
+'\n' +
+'  return (--n >= 0) ? (unsigned char) *bufp++ : EOF;\n' +
+' \n' +
+'}\n';
+
+var lines = (function() {
+  lineText = code.split('\n');
+  var ret = [];
+  for (var i = 0; i < lineText.length; i++) {
+    ret[i] = {
+      line: i,
+      length: lineText[i].length,
+      lineText: lineText[i],
+      textStart: /^\s*/.exec(lineText[i])[0].length
+    };
+  }
+  return ret;
+})();
+var endOfDocument = makeCursor(lines.length - 1,
+    lines[lines.length - 1].length);
+var wordLine = lines[0];
+var bigWordLine = lines[1];
+var charLine = lines[2];
+var bracesLine = lines[3];
+var seekBraceLine = lines[4];
+
+var word1 = {
+  start: { line: wordLine.line, ch: 1 },
+  end: { line: wordLine.line, ch: 5 }
+};
+var word2 = {
+  start: { line: wordLine.line, ch: word1.end.ch + 2 },
+  end: { line: wordLine.line, ch: word1.end.ch + 4 }
+};
+var word3 = {
+  start: { line: bigWordLine.line, ch: 1 },
+  end: { line: bigWordLine.line, ch: 5 }
+};
+var bigWord1 = word1;
+var bigWord2 = word2;
+var bigWord3 = {
+  start: { line: bigWordLine.line, ch: 1 },
+  end: { line: bigWordLine.line, ch: 7 }
+};
+var bigWord4 = {
+  start: { line: bigWordLine.line, ch: bigWord1.end.ch + 3 },
+  end: { line: bigWordLine.line, ch: bigWord1.end.ch + 7 }
+};
+
+var oChars = [ { line: charLine.line, ch: 1 },
+    { line: charLine.line, ch: 3 },
+    { line: charLine.line, ch: 7 } ];
+var pChars = [ { line: charLine.line, ch: 2 },
+    { line: charLine.line, ch: 4 },
+    { line: charLine.line, ch: 6 },
+    { line: charLine.line, ch: 8 } ];
+var numChars = [ { line: charLine.line, ch: 10 },
+    { line: charLine.line, ch: 12 },
+    { line: charLine.line, ch: 14 },
+    { line: charLine.line, ch: 16 },
+    { line: charLine.line, ch: 18 }];
+var parens1 = {
+  start: { line: bracesLine.line, ch: 1 },
+  end: { line: bracesLine.line, ch: 3 }
+};
+var squares1 = {
+  start: { line: bracesLine.line, ch: 5 },
+  end: { line: bracesLine.line, ch: 7 }
+};
+var curlys1 = {
+  start: { line: bracesLine.line, ch: 9 },
+  end: { line: bracesLine.line, ch: 11 }
+};
+var seekOutside = {
+  start: { line: seekBraceLine.line, ch: 1 },
+  end: { line: seekBraceLine.line, ch: 16 }
+};
+var seekInside = {
+  start: { line: seekBraceLine.line, ch: 14 },
+  end: { line: seekBraceLine.line, ch: 11 }
+};
+
+function copyCursor(cur) {
+  return { ch: cur.ch, line: cur.line };
+}
+
+function forEach(arr, func) {
+  for (var i = 0; i < arr.length; i++) {
+    func(arr[i]);
+  }
+}
+
+function testVim(name, run, opts, expectedFail) {
+  var vimOpts = {
+    lineNumbers: true,
+    vimMode: true,
+    showCursorWhenSelecting: true,
+    value: code
+  };
+  for (var prop in opts) {
+    if (opts.hasOwnProperty(prop)) {
+      vimOpts[prop] = opts[prop];
+    }
+  }
+  return test('vim_' + name, function() {
+    var place = document.getElementById("testground");
+    var cm = CodeMirror(place, vimOpts);
+    var vim = CodeMirror.Vim.maybeInitVimState_(cm);
+
+    function doKeysFn(cm) {
+      return function(args) {
+        if (args instanceof Array) {
+          arguments = args;
+        }
+        for (var i = 0; i < arguments.length; i++) {
+          CodeMirror.Vim.handleKey(cm, arguments[i]);
+        }
+      }
+    }
+    function doInsertModeKeysFn(cm) {
+      return function(args) {
+        if (args instanceof Array) { arguments = args; }
+        function executeHandler(handler) {
+          if (typeof handler == 'string') {
+            CodeMirror.commands[handler](cm);
+          } else {
+            handler(cm);
+          }
+          return true;
+        }
+        for (var i = 0; i < arguments.length; i++) {
+          var key = arguments[i];
+          // Find key in keymap and handle.
+          var handled = CodeMirror.lookupKey(key, ['vim-insert'], executeHandler);
+          // Record for insert mode.
+          if (handled === true && cm.state.vim.insertMode && arguments[i] != 'Esc') {
+            var lastChange = CodeMirror.Vim.getVimGlobalState_().macroModeState.lastInsertModeChanges;
+            if (lastChange) {
+              lastChange.changes.push(new CodeMirror.Vim.InsertModeKey(key));
+            }
+          }
+        }
+      }
+    }
+    function doExFn(cm) {
+      return function(command) {
+        cm.openDialog = helpers.fakeOpenDialog(command);
+        helpers.doKeys(':');
+      }
+    }
+    function assertCursorAtFn(cm) {
+      return function(line, ch) {
+        var pos;
+        if (ch == null && typeof line.line == 'number') {
+          pos = line;
+        } else {
+          pos = makeCursor(line, ch);
+        }
+        eqPos(pos, cm.getCursor());
+      }
+    }
+    function fakeOpenDialog(result) {
+      return function(text, callback) {
+        return callback(result);
+      }
+    }
+    function fakeOpenNotification(matcher) {
+      return function(text) {
+        matcher(text);
+      }
+    }
+    var helpers = {
+      doKeys: doKeysFn(cm),
+      // Warning: Only emulates keymap events, not character insertions. Use
+      // replaceRange to simulate character insertions.
+      // Keys are in CodeMirror format, NOT vim format.
+      doInsertModeKeys: doInsertModeKeysFn(cm),
+      doEx: doExFn(cm),
+      assertCursorAt: assertCursorAtFn(cm),
+      fakeOpenDialog: fakeOpenDialog,
+      fakeOpenNotification: fakeOpenNotification,
+      getRegisterController: function() {
+        return CodeMirror.Vim.getRegisterController();
+      }
+    }
+    CodeMirror.Vim.resetVimGlobalState_();
+    var successful = false;
+    var savedOpenNotification = cm.openNotification;
+    try {
+      run(cm, vim, helpers);
+      successful = true;
+    } finally {
+      cm.openNotification = savedOpenNotification;
+      if (!successful || verbose) {
+        place.style.visibility = "visible";
+      } else {
+        place.removeChild(cm.getWrapperElement());
+      }
+    }
+  }, expectedFail);
+};
+testVim('qq at q', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('q', 'q', 'l', 'l', 'q');
+  helpers.assertCursorAt(0,2);
+  helpers.doKeys('@', 'q');
+  helpers.assertCursorAt(0,4);
+}, { value: '            '});
+testVim('@@', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('q', 'q', 'l', 'l', 'q');
+  helpers.assertCursorAt(0,2);
+  helpers.doKeys('@', 'q');
+  helpers.assertCursorAt(0,4);
+  helpers.doKeys('@', '@');
+  helpers.assertCursorAt(0,6);
+}, { value: '            '});
+var jumplistScene = ''+
+  'word\n'+
+  '(word)\n'+
+  '{word\n'+
+  'word.\n'+
+  '\n'+
+  'word search\n'+
+  '}word\n'+
+  'word\n'+
+  'word\n';
+function testJumplist(name, keys, endPos, startPos, dialog) {
+  endPos = makeCursor(endPos[0], endPos[1]);
+  startPos = makeCursor(startPos[0], startPos[1]);
+  testVim(name, function(cm, vim, helpers) {
+    CodeMirror.Vim.resetVimGlobalState_();
+    if(dialog)cm.openDialog = helpers.fakeOpenDialog('word');
+    cm.setCursor(startPos);
+    helpers.doKeys.apply(null, keys);
+    helpers.assertCursorAt(endPos);
+  }, {value: jumplistScene});
+};
+testJumplist('jumplist_H', ['H', '<C-o>'], [5,2], [5,2]);
+testJumplist('jumplist_M', ['M', '<C-o>'], [2,2], [2,2]);
+testJumplist('jumplist_L', ['L', '<C-o>'], [2,2], [2,2]);
+testJumplist('jumplist_[[', ['[', '[', '<C-o>'], [5,2], [5,2]);
+testJumplist('jumplist_]]', [']', ']', '<C-o>'], [2,2], [2,2]);
+testJumplist('jumplist_G', ['G', '<C-o>'], [5,2], [5,2]);
+testJumplist('jumplist_gg', ['g', 'g', '<C-o>'], [5,2], [5,2]);
+testJumplist('jumplist_%', ['%', '<C-o>'], [1,5], [1,5]);
+testJumplist('jumplist_{', ['{', '<C-o>'], [1,5], [1,5]);
+testJumplist('jumplist_}', ['}', '<C-o>'], [1,5], [1,5]);
+testJumplist('jumplist_\'', ['m', 'a', 'h', '\'', 'a', 'h', '<C-i>'], [1,5], [1,5]);
+testJumplist('jumplist_`', ['m', 'a', 'h', '`', 'a', 'h', '<C-i>'], [1,5], [1,5]);
+testJumplist('jumplist_*_cachedCursor', ['*', '<C-o>'], [1,3], [1,3]);
+testJumplist('jumplist_#_cachedCursor', ['#', '<C-o>'], [1,3], [1,3]);
+testJumplist('jumplist_n', ['#', 'n', '<C-o>'], [1,1], [2,3]);
+testJumplist('jumplist_N', ['#', 'N', '<C-o>'], [1,1], [2,3]);
+testJumplist('jumplist_repeat_<c-o>', ['*', '*', '*', '3', '<C-o>'], [2,3], [2,3]);
+testJumplist('jumplist_repeat_<c-i>', ['*', '*', '*', '3', '<C-o>', '2', '<C-i>'], [5,0], [2,3]);
+testJumplist('jumplist_repeated_motion', ['3', '*', '<C-o>'], [2,3], [2,3]);
+testJumplist('jumplist_/', ['/', '<C-o>'], [2,3], [2,3], 'dialog');
+testJumplist('jumplist_?', ['?', '<C-o>'], [2,3], [2,3], 'dialog');
+testJumplist('jumplist_skip_delted_mark<c-o>',
+             ['*', 'n', 'n', 'k', 'd', 'k', '<C-o>', '<C-o>', '<C-o>'],
+             [0,2], [0,2]);
+testJumplist('jumplist_skip_delted_mark<c-i>',
+             ['*', 'n', 'n', 'k', 'd', 'k', '<C-o>', '<C-i>', '<C-i>'],
+             [1,0], [0,2]);
+
+/**
+ * @param name Name of the test
+ * @param keys An array of keys or a string with a single key to simulate.
+ * @param endPos The expected end position of the cursor.
+ * @param startPos The position the cursor should start at, defaults to 0, 0.
+ */
+function testMotion(name, keys, endPos, startPos) {
+  testVim(name, function(cm, vim, helpers) {
+    if (!startPos) {
+      startPos = { line: 0, ch: 0 };
+    }
+    cm.setCursor(startPos);
+    helpers.doKeys(keys);
+    helpers.assertCursorAt(endPos);
+  });
+};
+
+function makeCursor(line, ch) {
+  return { line: line, ch: ch };
+};
+
+function offsetCursor(cur, offsetLine, offsetCh) {
+  return { line: cur.line + offsetLine, ch: cur.ch + offsetCh };
+};
+
+// Motion tests
+testMotion('|', '|', makeCursor(0, 0), makeCursor(0,4));
+testMotion('|_repeat', ['3', '|'], makeCursor(0, 2), makeCursor(0,4));
+testMotion('h', 'h', makeCursor(0, 0), word1.start);
+testMotion('h_repeat', ['3', 'h'], offsetCursor(word1.end, 0, -3), word1.end);
+testMotion('l', 'l', makeCursor(0, 1));
+testMotion('l_repeat', ['2', 'l'], makeCursor(0, 2));
+testMotion('j', 'j', offsetCursor(word1.end, 1, 0), word1.end);
+testMotion('j_repeat', ['2', 'j'], offsetCursor(word1.end, 2, 0), word1.end);
+testMotion('j_repeat_clip', ['1000', 'j'], endOfDocument);
+testMotion('k', 'k', offsetCursor(word3.end, -1, 0), word3.end);
+testMotion('k_repeat', ['2', 'k'], makeCursor(0, 4), makeCursor(2, 4));
+testMotion('k_repeat_clip', ['1000', 'k'], makeCursor(0, 4), makeCursor(2, 4));
+testMotion('w', 'w', word1.start);
+testMotion('w_multiple_newlines_no_space', 'w', makeCursor(12, 2), makeCursor(11, 2));
+testMotion('w_multiple_newlines_with_space', 'w', makeCursor(14, 0), makeCursor(12, 51));
+testMotion('w_repeat', ['2', 'w'], word2.start);
+testMotion('w_wrap', ['w'], word3.start, word2.start);
+testMotion('w_endOfDocument', 'w', endOfDocument, endOfDocument);
+testMotion('w_start_to_end', ['1000', 'w'], endOfDocument, makeCursor(0, 0));
+testMotion('W', 'W', bigWord1.start);
+testMotion('W_repeat', ['2', 'W'], bigWord3.start, bigWord1.start);
+testMotion('e', 'e', word1.end);
+testMotion('e_repeat', ['2', 'e'], word2.end);
+testMotion('e_wrap', 'e', word3.end, word2.end);
+testMotion('e_endOfDocument', 'e', endOfDocument, endOfDocument);
+testMotion('e_start_to_end', ['1000', 'e'], endOfDocument, makeCursor(0, 0));
+testMotion('b', 'b', word3.start, word3.end);
+testMotion('b_repeat', ['2', 'b'], word2.start, word3.end);
+testMotion('b_wrap', 'b', word2.start, word3.start);
+testMotion('b_startOfDocument', 'b', makeCursor(0, 0), makeCursor(0, 0));
+testMotion('b_end_to_start', ['1000', 'b'], makeCursor(0, 0), endOfDocument);
+testMotion('ge', ['g', 'e'], word2.end, word3.end);
+testMotion('ge_repeat', ['2', 'g', 'e'], word1.end, word3.start);
+testMotion('ge_wrap', ['g', 'e'], word2.end, word3.start);
+testMotion('ge_startOfDocument', ['g', 'e'], makeCursor(0, 0),
+    makeCursor(0, 0));
+testMotion('ge_end_to_start', ['1000', 'g', 'e'], makeCursor(0, 0), endOfDocument);
+testMotion('gg', ['g', 'g'], makeCursor(lines[0].line, lines[0].textStart),
+    makeCursor(3, 1));
+testMotion('gg_repeat', ['3', 'g', 'g'],
+    makeCursor(lines[2].line, lines[2].textStart));
+testMotion('G', 'G',
+    makeCursor(lines[lines.length - 1].line, lines[lines.length - 1].textStart),
+    makeCursor(3, 1));
+testMotion('G_repeat', ['3', 'G'], makeCursor(lines[2].line,
+    lines[2].textStart));
+// TODO: Make the test code long enough to test Ctrl-F and Ctrl-B.
+testMotion('0', '0', makeCursor(0, 0), makeCursor(0, 8));
+testMotion('^', '^', makeCursor(0, lines[0].textStart), makeCursor(0, 8));
+testMotion('+', '+', makeCursor(1, lines[1].textStart), makeCursor(0, 8));
+testMotion('-', '-', makeCursor(0, lines[0].textStart), makeCursor(1, 4));
+testMotion('_', ['6','_'], makeCursor(5, lines[5].textStart), makeCursor(0, 8));
+testMotion('$', '$', makeCursor(0, lines[0].length - 1), makeCursor(0, 1));
+testMotion('$_repeat', ['2', '$'], makeCursor(1, lines[1].length - 1),
+    makeCursor(0, 3));
+testMotion('f', ['f', 'p'], pChars[0], makeCursor(charLine.line, 0));
+testMotion('f_repeat', ['2', 'f', 'p'], pChars[2], pChars[0]);
+testMotion('f_num', ['f', '2'], numChars[2], makeCursor(charLine.line, 0));
+testMotion('t', ['t','p'], offsetCursor(pChars[0], 0, -1),
+    makeCursor(charLine.line, 0));
+testMotion('t_repeat', ['2', 't', 'p'], offsetCursor(pChars[2], 0, -1),
+    pChars[0]);
+testMotion('F', ['F', 'p'], pChars[0], pChars[1]);
+testMotion('F_repeat', ['2', 'F', 'p'], pChars[0], pChars[2]);
+testMotion('T', ['T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[1]);
+testMotion('T_repeat', ['2', 'T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[2]);
+testMotion('%_parens', ['%'], parens1.end, parens1.start);
+testMotion('%_squares', ['%'], squares1.end, squares1.start);
+testMotion('%_braces', ['%'], curlys1.end, curlys1.start);
+testMotion('%_seek_outside', ['%'], seekOutside.end, seekOutside.start);
+testMotion('%_seek_inside', ['%'], seekInside.end, seekInside.start);
+testVim('%_seek_skip', function(cm, vim, helpers) {
+  cm.setCursor(0,0);
+  helpers.doKeys(['%']);
+  helpers.assertCursorAt(0,9);
+}, {value:'01234"("()'});
+testVim('%_skip_string', function(cm, vim, helpers) {
+  cm.setCursor(0,0);
+  helpers.doKeys(['%']);
+  helpers.assertCursorAt(0,4);
+  cm.setCursor(0,2);
+  helpers.doKeys(['%']);
+  helpers.assertCursorAt(0,0);
+}, {value:'(")")'});
+(')')
+testVim('%_skip_comment', function(cm, vim, helpers) {
+  cm.setCursor(0,0);
+  helpers.doKeys(['%']);
+  helpers.assertCursorAt(0,6);
+  cm.setCursor(0,3);
+  helpers.doKeys(['%']);
+  helpers.assertCursorAt(0,0);
+}, {value:'(/*)*/)'});
+// Make sure that moving down after going to the end of a line always leaves you
+// at the end of a line, but preserves the offset in other cases
+testVim('Changing lines after Eol operation', function(cm, vim, helpers) {
+  cm.setCursor(0,0);
+  helpers.doKeys(['$']);
+  helpers.doKeys(['j']);
+  // After moving to Eol and then down, we should be at Eol of line 2
+  helpers.assertCursorAt({ line: 1, ch: lines[1].length - 1 });
+  helpers.doKeys(['j']);
+  // After moving down, we should be at Eol of line 3
+  helpers.assertCursorAt({ line: 2, ch: lines[2].length - 1 });
+  helpers.doKeys(['h']);
+  helpers.doKeys(['j']);
+  // After moving back one space and then down, since line 4 is shorter than line 2, we should
+  // be at Eol of line 2 - 1
+  helpers.assertCursorAt({ line: 3, ch: lines[3].length - 1 });
+  helpers.doKeys(['j']);
+  helpers.doKeys(['j']);
+  // After moving down again, since line 3 has enough characters, we should be back to the
+  // same place we were at on line 1
+  helpers.assertCursorAt({ line: 5, ch: lines[2].length - 2 });
+});
+//making sure gj and gk recover from clipping
+testVim('gj_gk_clipping', function(cm,vim,helpers){
+  cm.setCursor(0, 1);
+  helpers.doKeys('g','j','g','j');
+  helpers.assertCursorAt(2, 1);
+  helpers.doKeys('g','k','g','k');
+  helpers.assertCursorAt(0, 1);
+},{value: 'line 1\n\nline 2'});
+//testing a mix of j/k and gj/gk
+testVim('j_k_and_gj_gk', function(cm,vim,helpers){
+  cm.setSize(120);
+  cm.setCursor(0, 0);
+  //go to the last character on the first line
+  helpers.doKeys('$');
+  //move up/down on the column within the wrapped line
+  //side-effect: cursor is not locked to eol anymore
+  helpers.doKeys('g','k');
+  var cur=cm.getCursor();
+  eq(cur.line,0);
+  is((cur.ch<176),'gk didn\'t move cursor back (1)');
+  helpers.doKeys('g','j');
+  helpers.assertCursorAt(0, 176);
+  //should move to character 177 on line 2 (j/k preserve character index within line)
+  helpers.doKeys('j');
+  //due to different line wrapping, the cursor can be on a different screen-x now
+  //gj and gk preserve screen-x on movement, much like moveV
+  helpers.doKeys('3','g','k');
+  cur=cm.getCursor();
+  eq(cur.line,1);
+  is((cur.ch<176),'gk didn\'t move cursor back (2)');
+  helpers.doKeys('g','j','2','g','j');
+  //should return to the same character-index
+  helpers.doKeys('k');
+  helpers.assertCursorAt(0, 176);
+},{ lineWrapping:true, value: 'This line is intentially long to test movement of gj and gk over wrapped lines. I will start on the end of this line, then make a step up and back to set the origin for j and k.\nThis line is supposed to be even longer than the previous. I will jump here and make another wiggle with gj and gk, before I jump back to the line above. Both wiggles should not change my cursor\'s target character but both j/k and gj/gk change each other\'s reference position.'});
+testVim('gj_gk', function(cm, vim, helpers) {
+  if (phantom) return;
+  cm.setSize(120);
+  // Test top of document edge case.
+  cm.setCursor(0, 4);
+  helpers.doKeys('g', 'j');
+  helpers.doKeys('10', 'g', 'k');
+  helpers.assertCursorAt(0, 4);
+
+  // Test moving down preserves column position.
+  helpers.doKeys('g', 'j');
+  var pos1 = cm.getCursor();
+  var expectedPos2 = { line: 0, ch: (pos1.ch - 4) * 2 + 4};
+  helpers.doKeys('g', 'j');
+  helpers.assertCursorAt(expectedPos2);
+
+  // Move to the last character
+  cm.setCursor(0, 0);
+  // Move left to reset HSPos
+  helpers.doKeys('h');
+  // Test bottom of document edge case.
+  helpers.doKeys('100', 'g', 'j');
+  var endingPos = cm.getCursor();
+  is(endingPos != 0, 'gj should not be on wrapped line 0');
+  var topLeftCharCoords = cm.charCoords(makeCursor(0, 0));
+  var endingCharCoords = cm.charCoords(endingPos);
+  is(topLeftCharCoords.left == endingCharCoords.left, 'gj should end up on column 0');
+},{ lineNumbers: false, lineWrapping:true, value: 'Thislineisintentiallylongtotestmovementofgjandgkoverwrappedlines.' });
+testVim('}', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('}');
+  helpers.assertCursorAt(1, 0);
+  cm.setCursor(0, 0);
+  helpers.doKeys('2', '}');
+  helpers.assertCursorAt(4, 0);
+  cm.setCursor(0, 0);
+  helpers.doKeys('6', '}');
+  helpers.assertCursorAt(5, 0);
+}, { value: 'a\n\nb\nc\n\nd' });
+testVim('{', function(cm, vim, helpers) {
+  cm.setCursor(5, 0);
+  helpers.doKeys('{');
+  helpers.assertCursorAt(4, 0);
+  cm.setCursor(5, 0);
+  helpers.doKeys('2', '{');
+  helpers.assertCursorAt(1, 0);
+  cm.setCursor(5, 0);
+  helpers.doKeys('6', '{');
+  helpers.assertCursorAt(0, 0);
+}, { value: 'a\n\nb\nc\n\nd' });
+
+// Operator tests
+testVim('dl', function(cm, vim, helpers) {
+  var curStart = makeCursor(0, 0);
+  cm.setCursor(curStart);
+  helpers.doKeys('d', 'l');
+  eq('word1 ', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq(' ', register.toString());
+  is(!register.linewise);
+  eqPos(curStart, cm.getCursor());
+}, { value: ' word1 ' });
+testVim('dl_eol', function(cm, vim, helpers) {
+  cm.setCursor(0, 6);
+  helpers.doKeys('d', 'l');
+  eq(' word1', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq(' ', register.toString());
+  is(!register.linewise);
+  helpers.assertCursorAt(0, 5);
+}, { value: ' word1 ' });
+testVim('dl_repeat', function(cm, vim, helpers) {
+  var curStart = makeCursor(0, 0);
+  cm.setCursor(curStart);
+  helpers.doKeys('2', 'd', 'l');
+  eq('ord1 ', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq(' w', register.toString());
+  is(!register.linewise);
+  eqPos(curStart, cm.getCursor());
+}, { value: ' word1 ' });
+testVim('dh', function(cm, vim, helpers) {
+  var curStart = makeCursor(0, 3);
+  cm.setCursor(curStart);
+  helpers.doKeys('d', 'h');
+  eq(' wrd1 ', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('o', register.toString());
+  is(!register.linewise);
+  eqPos(offsetCursor(curStart, 0 , -1), cm.getCursor());
+}, { value: ' word1 ' });
+testVim('dj', function(cm, vim, helpers) {
+  var curStart = makeCursor(0, 3);
+  cm.setCursor(curStart);
+  helpers.doKeys('d', 'j');
+  eq(' word3', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq(' word1\nword2\n', register.toString());
+  is(register.linewise);
+  helpers.assertCursorAt(0, 1);
+}, { value: ' word1\nword2\n word3' });
+testVim('dj_end_of_document', function(cm, vim, helpers) {
+  var curStart = makeCursor(0, 3);
+  cm.setCursor(curStart);
+  helpers.doKeys('d', 'j');
+  eq(' word1 ', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('', register.toString());
+  is(!register.linewise);
+  helpers.assertCursorAt(0, 3);
+}, { value: ' word1 ' });
+testVim('dk', function(cm, vim, helpers) {
+  var curStart = makeCursor(1, 3);
+  cm.setCursor(curStart);
+  helpers.doKeys('d', 'k');
+  eq(' word3', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq(' word1\nword2\n', register.toString());
+  is(register.linewise);
+  helpers.assertCursorAt(0, 1);
+}, { value: ' word1\nword2\n word3' });
+testVim('dk_start_of_document', function(cm, vim, helpers) {
+  var curStart = makeCursor(0, 3);
+  cm.setCursor(curStart);
+  helpers.doKeys('d', 'k');
+  eq(' word1 ', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('', register.toString());
+  is(!register.linewise);
+  helpers.assertCursorAt(0, 3);
+}, { value: ' word1 ' });
+testVim('dw_space', function(cm, vim, helpers) {
+  var curStart = makeCursor(0, 0);
+  cm.setCursor(curStart);
+  helpers.doKeys('d', 'w');
+  eq('word1 ', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq(' ', register.toString());
+  is(!register.linewise);
+  eqPos(curStart, cm.getCursor());
+}, { value: ' word1 ' });
+testVim('dw_word', function(cm, vim, helpers) {
+  var curStart = makeCursor(0, 1);
+  cm.setCursor(curStart);
+  helpers.doKeys('d', 'w');
+  eq(' word2', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('word1 ', register.toString());
+  is(!register.linewise);
+  eqPos(curStart, cm.getCursor());
+}, { value: ' word1 word2' });
+testVim('dw_only_word', function(cm, vim, helpers) {
+  // Test that if there is only 1 word left, dw deletes till the end of the
+  // line.
+  cm.setCursor(0, 1);
+  helpers.doKeys('d', 'w');
+  eq(' ', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('word1 ', register.toString());
+  is(!register.linewise);
+  helpers.assertCursorAt(0, 0);
+}, { value: ' word1 ' });
+testVim('dw_eol', function(cm, vim, helpers) {
+  // Assert that dw does not delete the newline if last word to delete is at end
+  // of line.
+  cm.setCursor(0, 1);
+  helpers.doKeys('d', 'w');
+  eq(' \nword2', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('word1', register.toString());
+  is(!register.linewise);
+  helpers.assertCursorAt(0, 0);
+}, { value: ' word1\nword2' });
+testVim('dw_eol_with_multiple_newlines', function(cm, vim, helpers) {
+  // Assert that dw does not delete the newline if last word to delete is at end
+  // of line and it is followed by multiple newlines.
+  cm.setCursor(0, 1);
+  helpers.doKeys('d', 'w');
+  eq(' \n\nword2', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('word1', register.toString());
+  is(!register.linewise);
+  helpers.assertCursorAt(0, 0);
+}, { value: ' word1\n\nword2' });
+testVim('dw_empty_line_followed_by_whitespace', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', 'w');
+  eq('  \nword', cm.getValue());
+}, { value: '\n  \nword' });
+testVim('dw_empty_line_followed_by_word', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', 'w');
+  eq('word', cm.getValue());
+}, { value: '\nword' });
+testVim('dw_empty_line_followed_by_empty_line', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', 'w');
+  eq('\n', cm.getValue());
+}, { value: '\n\n' });
+testVim('dw_whitespace_followed_by_whitespace', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', 'w');
+  eq('\n   \n', cm.getValue());
+}, { value: '  \n   \n' });
+testVim('dw_whitespace_followed_by_empty_line', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', 'w');
+  eq('\n\n', cm.getValue());
+}, { value: '  \n\n' });
+testVim('dw_word_whitespace_word', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', 'w');
+  eq('\n   \nword2', cm.getValue());
+}, { value: 'word1\n   \nword2'})
+testVim('dw_end_of_document', function(cm, vim, helpers) {
+  cm.setCursor(1, 2);
+  helpers.doKeys('d', 'w');
+  eq('\nab', cm.getValue());
+}, { value: '\nabc' });
+testVim('dw_repeat', function(cm, vim, helpers) {
+  // Assert that dw does delete newline if it should go to the next line, and
+  // that repeat works properly.
+  cm.setCursor(0, 1);
+  helpers.doKeys('d', '2', 'w');
+  eq(' ', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('word1\nword2', register.toString());
+  is(!register.linewise);
+  helpers.assertCursorAt(0, 0);
+}, { value: ' word1\nword2' });
+testVim('de_word_start_and_empty_lines', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', 'e');
+  eq('\n\n', cm.getValue());
+}, { value: 'word\n\n' });
+testVim('de_word_end_and_empty_lines', function(cm, vim, helpers) {
+  cm.setCursor(0, 3);
+  helpers.doKeys('d', 'e');
+  eq('wor', cm.getValue());
+}, { value: 'word\n\n\n' });
+testVim('de_whitespace_and_empty_lines', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', 'e');
+  eq('', cm.getValue());
+}, { value: '   \n\n\n' });
+testVim('de_end_of_document', function(cm, vim, helpers) {
+  cm.setCursor(1, 2);
+  helpers.doKeys('d', 'e');
+  eq('\nab', cm.getValue());
+}, { value: '\nabc' });
+testVim('db_empty_lines', function(cm, vim, helpers) {
+  cm.setCursor(2, 0);
+  helpers.doKeys('d', 'b');
+  eq('\n\n', cm.getValue());
+}, { value: '\n\n\n' });
+testVim('db_word_start_and_empty_lines', function(cm, vim, helpers) {
+  cm.setCursor(2, 0);
+  helpers.doKeys('d', 'b');
+  eq('\nword', cm.getValue());
+}, { value: '\n\nword' });
+testVim('db_word_end_and_empty_lines', function(cm, vim, helpers) {
+  cm.setCursor(2, 3);
+  helpers.doKeys('d', 'b');
+  eq('\n\nd', cm.getValue());
+}, { value: '\n\nword' });
+testVim('db_whitespace_and_empty_lines', function(cm, vim, helpers) {
+  cm.setCursor(2, 0);
+  helpers.doKeys('d', 'b');
+  eq('', cm.getValue());
+}, { value: '\n   \n' });
+testVim('db_start_of_document', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', 'b');
+  eq('abc\n', cm.getValue());
+}, { value: 'abc\n' });
+testVim('dge_empty_lines', function(cm, vim, helpers) {
+  cm.setCursor(1, 0);
+  helpers.doKeys('d', 'g', 'e');
+  // Note: In real VIM the result should be '', but it's not quite consistent,
+  // since 2 newlines are deleted. But in the similar case of word\n\n, only
+  // 1 newline is deleted. We'll diverge from VIM's behavior since it's much
+  // easier this way.
+  eq('\n', cm.getValue());
+}, { value: '\n\n' });
+testVim('dge_word_and_empty_lines', function(cm, vim, helpers) {
+  cm.setCursor(1, 0);
+  helpers.doKeys('d', 'g', 'e');
+  eq('wor\n', cm.getValue());
+}, { value: 'word\n\n'});
+testVim('dge_whitespace_and_empty_lines', function(cm, vim, helpers) {
+  cm.setCursor(2, 0);
+  helpers.doKeys('d', 'g', 'e');
+  eq('', cm.getValue());
+}, { value: '\n  \n' });
+testVim('dge_start_of_document', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', 'g', 'e');
+  eq('bc\n', cm.getValue());
+}, { value: 'abc\n' });
+testVim('d_inclusive', function(cm, vim, helpers) {
+  // Assert that when inclusive is set, the character the cursor is on gets
+  // deleted too.
+  var curStart = makeCursor(0, 1);
+  cm.setCursor(curStart);
+  helpers.doKeys('d', 'e');
+  eq('  ', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('word1', register.toString());
+  is(!register.linewise);
+  eqPos(curStart, cm.getCursor());
+}, { value: ' word1 ' });
+testVim('d_reverse', function(cm, vim, helpers) {
+  // Test that deleting in reverse works.
+  cm.setCursor(1, 0);
+  helpers.doKeys('d', 'b');
+  eq(' word2 ', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('word1\n', register.toString());
+  is(!register.linewise);
+  helpers.assertCursorAt(0, 1);
+}, { value: ' word1\nword2 ' });
+testVim('dd', function(cm, vim, helpers) {
+  cm.setCursor(0, 3);
+  var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
+    { line: 1, ch: 0 });
+  var expectedLineCount = cm.lineCount() - 1;
+  helpers.doKeys('d', 'd');
+  eq(expectedLineCount, cm.lineCount());
+  var register = helpers.getRegisterController().getRegister();
+  eq(expectedBuffer, register.toString());
+  is(register.linewise);
+  helpers.assertCursorAt(0, lines[1].textStart);
+});
+testVim('dd_prefix_repeat', function(cm, vim, helpers) {
+  cm.setCursor(0, 3);
+  var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
+    { line: 2, ch: 0 });
+  var expectedLineCount = cm.lineCount() - 2;
+  helpers.doKeys('2', 'd', 'd');
+  eq(expectedLineCount, cm.lineCount());
+  var register = helpers.getRegisterController().getRegister();
+  eq(expectedBuffer, register.toString());
+  is(register.linewise);
+  helpers.assertCursorAt(0, lines[2].textStart);
+});
+testVim('dd_motion_repeat', function(cm, vim, helpers) {
+  cm.setCursor(0, 3);
+  var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
+    { line: 2, ch: 0 });
+  var expectedLineCount = cm.lineCount() - 2;
+  helpers.doKeys('d', '2', 'd');
+  eq(expectedLineCount, cm.lineCount());
+  var register = helpers.getRegisterController().getRegister();
+  eq(expectedBuffer, register.toString());
+  is(register.linewise);
+  helpers.assertCursorAt(0, lines[2].textStart);
+});
+testVim('dd_multiply_repeat', function(cm, vim, helpers) {
+  cm.setCursor(0, 3);
+  var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
+    { line: 6, ch: 0 });
+  var expectedLineCount = cm.lineCount() - 6;
+  helpers.doKeys('2', 'd', '3', 'd');
+  eq(expectedLineCount, cm.lineCount());
+  var register = helpers.getRegisterController().getRegister();
+  eq(expectedBuffer, register.toString());
+  is(register.linewise);
+  helpers.assertCursorAt(0, lines[6].textStart);
+});
+testVim('dd_lastline', function(cm, vim, helpers) {
+  cm.setCursor(cm.lineCount(), 0);
+  var expectedLineCount = cm.lineCount() - 1;
+  helpers.doKeys('d', 'd');
+  eq(expectedLineCount, cm.lineCount());
+  helpers.assertCursorAt(cm.lineCount() - 1, 0);
+});
+// Yank commands should behave the exact same as d commands, expect that nothing
+// gets deleted.
+testVim('yw_repeat', function(cm, vim, helpers) {
+  // Assert that yw does yank newline if it should go to the next line, and
+  // that repeat works properly.
+  var curStart = makeCursor(0, 1);
+  cm.setCursor(curStart);
+  helpers.doKeys('y', '2', 'w');
+  eq(' word1\nword2', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('word1\nword2', register.toString());
+  is(!register.linewise);
+  eqPos(curStart, cm.getCursor());
+}, { value: ' word1\nword2' });
+testVim('yy_multiply_repeat', function(cm, vim, helpers) {
+  var curStart = makeCursor(0, 3);
+  cm.setCursor(curStart);
+  var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
+    { line: 6, ch: 0 });
+  var expectedLineCount = cm.lineCount();
+  helpers.doKeys('2', 'y', '3', 'y');
+  eq(expectedLineCount, cm.lineCount());
+  var register = helpers.getRegisterController().getRegister();
+  eq(expectedBuffer, register.toString());
+  is(register.linewise);
+  eqPos(curStart, cm.getCursor());
+});
+// Change commands behave like d commands except that it also enters insert
+// mode. In addition, when the change is linewise, an additional newline is
+// inserted so that insert mode starts on that line.
+testVim('cw', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('c', '2', 'w');
+  eq(' word3', cm.getValue());
+  helpers.assertCursorAt(0, 0);
+}, { value: 'word1 word2 word3'});
+testVim('cw_repeat', function(cm, vim, helpers) {
+  // Assert that cw does delete newline if it should go to the next line, and
+  // that repeat works properly.
+  var curStart = makeCursor(0, 1);
+  cm.setCursor(curStart);
+  helpers.doKeys('c', '2', 'w');
+  eq(' ', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('word1\nword2', register.toString());
+  is(!register.linewise);
+  eqPos(curStart, cm.getCursor());
+  eq('vim-insert', cm.getOption('keyMap'));
+}, { value: ' word1\nword2' });
+testVim('cc_multiply_repeat', function(cm, vim, helpers) {
+  cm.setCursor(0, 3);
+  var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
+    { line: 6, ch: 0 });
+  var expectedLineCount = cm.lineCount() - 5;
+  helpers.doKeys('2', 'c', '3', 'c');
+  eq(expectedLineCount, cm.lineCount());
+  var register = helpers.getRegisterController().getRegister();
+  eq(expectedBuffer, register.toString());
+  is(register.linewise);
+  eq('vim-insert', cm.getOption('keyMap'));
+});
+testVim('cc_append', function(cm, vim, helpers) {
+  var expectedLineCount = cm.lineCount();
+  cm.setCursor(cm.lastLine(), 0);
+  helpers.doKeys('c', 'c');
+  eq(expectedLineCount, cm.lineCount());
+});
+// Swapcase commands edit in place and do not modify registers.
+testVim('g~w_repeat', function(cm, vim, helpers) {
+  // Assert that dw does delete newline if it should go to the next line, and
+  // that repeat works properly.
+  var curStart = makeCursor(0, 1);
+  cm.setCursor(curStart);
+  helpers.doKeys('g', '~', '2', 'w');
+  eq(' WORD1\nWORD2', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('', register.toString());
+  is(!register.linewise);
+  eqPos(curStart, cm.getCursor());
+}, { value: ' word1\nword2' });
+testVim('g~g~', function(cm, vim, helpers) {
+  var curStart = makeCursor(0, 3);
+  cm.setCursor(curStart);
+  var expectedLineCount = cm.lineCount();
+  var expectedValue = cm.getValue().toUpperCase();
+  helpers.doKeys('2', 'g', '~', '3', 'g', '~');
+  eq(expectedValue, cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('', register.toString());
+  is(!register.linewise);
+  eqPos(curStart, cm.getCursor());
+}, { value: ' word1\nword2\nword3\nword4\nword5\nword6' });
+testVim('>{motion}', function(cm, vim, helpers) {
+  cm.setCursor(1, 3);
+  var expectedLineCount = cm.lineCount();
+  var expectedValue = '   word1\n  word2\nword3 ';
+  helpers.doKeys('>', 'k');
+  eq(expectedValue, cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('', register.toString());
+  is(!register.linewise);
+  helpers.assertCursorAt(0, 3);
+}, { value: ' word1\nword2\nword3 ', indentUnit: 2 });
+testVim('>>', function(cm, vim, helpers) {
+  cm.setCursor(0, 3);
+  var expectedLineCount = cm.lineCount();
+  var expectedValue = '   word1\n  word2\nword3 ';
+  helpers.doKeys('2', '>', '>');
+  eq(expectedValue, cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('', register.toString());
+  is(!register.linewise);
+  helpers.assertCursorAt(0, 3);
+}, { value: ' word1\nword2\nword3 ', indentUnit: 2 });
+testVim('<{motion}', function(cm, vim, helpers) {
+  cm.setCursor(1, 3);
+  var expectedLineCount = cm.lineCount();
+  var expectedValue = ' word1\nword2\nword3 ';
+  helpers.doKeys('<', 'k');
+  eq(expectedValue, cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('', register.toString());
+  is(!register.linewise);
+  helpers.assertCursorAt(0, 1);
+}, { value: '   word1\n  word2\nword3 ', indentUnit: 2 });
+testVim('<<', function(cm, vim, helpers) {
+  cm.setCursor(0, 3);
+  var expectedLineCount = cm.lineCount();
+  var expectedValue = ' word1\nword2\nword3 ';
+  helpers.doKeys('2', '<', '<');
+  eq(expectedValue, cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('', register.toString());
+  is(!register.linewise);
+  helpers.assertCursorAt(0, 1);
+}, { value: '   word1\n  word2\nword3 ', indentUnit: 2 });
+
+// Edit tests
+function testEdit(name, before, pos, edit, after) {
+  return testVim(name, function(cm, vim, helpers) {
+             var ch = before.search(pos)
+             var line = before.substring(0, ch).split('\n').length - 1;
+             if (line) {
+               ch = before.substring(0, ch).split('\n').pop().length;
+             }
+             cm.setCursor(line, ch);
+             helpers.doKeys.apply(this, edit.split(''));
+             eq(after, cm.getValue());
+           }, {value: before});
+}
+
+// These Delete tests effectively cover word-wise Change, Visual & Yank.
+// Tabs are used as differentiated whitespace to catch edge cases.
+// Normal word:
+testEdit('diw_mid_spc', 'foo \tbAr\t baz', /A/, 'diw', 'foo \t\t baz');
+testEdit('daw_mid_spc', 'foo \tbAr\t baz', /A/, 'daw', 'foo \tbaz');
+testEdit('diw_mid_punct', 'foo \tbAr.\t baz', /A/, 'diw', 'foo \t.\t baz');
+testEdit('daw_mid_punct', 'foo \tbAr.\t baz', /A/, 'daw', 'foo.\t baz');
+testEdit('diw_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'diw', 'foo \t,.\t baz');
+testEdit('daw_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'daw', 'foo \t,.\t baz');
+testEdit('diw_start_spc', 'bAr \tbaz', /A/, 'diw', ' \tbaz');
+testEdit('daw_start_spc', 'bAr \tbaz', /A/, 'daw', 'baz');
+testEdit('diw_start_punct', 'bAr. \tbaz', /A/, 'diw', '. \tbaz');
+testEdit('daw_start_punct', 'bAr. \tbaz', /A/, 'daw', '. \tbaz');
+testEdit('diw_end_spc', 'foo \tbAr', /A/, 'diw', 'foo \t');
+testEdit('daw_end_spc', 'foo \tbAr', /A/, 'daw', 'foo');
+testEdit('diw_end_punct', 'foo \tbAr.', /A/, 'diw', 'foo \t.');
+testEdit('daw_end_punct', 'foo \tbAr.', /A/, 'daw', 'foo.');
+// Big word:
+testEdit('diW_mid_spc', 'foo \tbAr\t baz', /A/, 'diW', 'foo \t\t baz');
+testEdit('daW_mid_spc', 'foo \tbAr\t baz', /A/, 'daW', 'foo \tbaz');
+testEdit('diW_mid_punct', 'foo \tbAr.\t baz', /A/, 'diW', 'foo \t\t baz');
+testEdit('daW_mid_punct', 'foo \tbAr.\t baz', /A/, 'daW', 'foo \tbaz');
+testEdit('diW_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'diW', 'foo \t\t baz');
+testEdit('daW_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'daW', 'foo \tbaz');
+testEdit('diW_start_spc', 'bAr\t baz', /A/, 'diW', '\t baz');
+testEdit('daW_start_spc', 'bAr\t baz', /A/, 'daW', 'baz');
+testEdit('diW_start_punct', 'bAr.\t baz', /A/, 'diW', '\t baz');
+testEdit('daW_start_punct', 'bAr.\t baz', /A/, 'daW', 'baz');
+testEdit('diW_end_spc', 'foo \tbAr', /A/, 'diW', 'foo \t');
+testEdit('daW_end_spc', 'foo \tbAr', /A/, 'daW', 'foo');
+testEdit('diW_end_punct', 'foo \tbAr.', /A/, 'diW', 'foo \t');
+testEdit('daW_end_punct', 'foo \tbAr.', /A/, 'daW', 'foo');
+// Deleting text objects
+//    Open and close on same line
+testEdit('di(_open_spc', 'foo (bAr) baz', /\(/, 'di(', 'foo () baz');
+testEdit('di)_open_spc', 'foo (bAr) baz', /\(/, 'di)', 'foo () baz');
+testEdit('da(_open_spc', 'foo (bAr) baz', /\(/, 'da(', 'foo  baz');
+testEdit('da)_open_spc', 'foo (bAr) baz', /\(/, 'da)', 'foo  baz');
+
+testEdit('di(_middle_spc', 'foo (bAr) baz', /A/, 'di(', 'foo () baz');
+testEdit('di)_middle_spc', 'foo (bAr) baz', /A/, 'di)', 'foo () baz');
+testEdit('da(_middle_spc', 'foo (bAr) baz', /A/, 'da(', 'foo  baz');
+testEdit('da)_middle_spc', 'foo (bAr) baz', /A/, 'da)', 'foo  baz');
+
+testEdit('di(_close_spc', 'foo (bAr) baz', /\)/, 'di(', 'foo () baz');
+testEdit('di)_close_spc', 'foo (bAr) baz', /\)/, 'di)', 'foo () baz');
+testEdit('da(_close_spc', 'foo (bAr) baz', /\)/, 'da(', 'foo  baz');
+testEdit('da)_close_spc', 'foo (bAr) baz', /\)/, 'da)', 'foo  baz');
+
+//  Open and close on different lines, equally indented
+testEdit('di{_middle_spc', 'a{\n\tbar\n}b', /r/, 'di{', 'a{}b');
+testEdit('di}_middle_spc', 'a{\n\tbar\n}b', /r/, 'di}', 'a{}b');
+testEdit('da{_middle_spc', 'a{\n\tbar\n}b', /r/, 'da{', 'ab');
+testEdit('da}_middle_spc', 'a{\n\tbar\n}b', /r/, 'da}', 'ab');
+
+// open and close on diff lines, open indented less than close
+testEdit('di{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'di{', 'a{}b');
+testEdit('di}_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'di}', 'a{}b');
+testEdit('da{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'da{', 'ab');
+testEdit('da}_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'da}', 'ab');
+
+// open and close on diff lines, open indented more than close
+testEdit('di[_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'di[', 'a\t[]b');
+testEdit('di]_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'di]', 'a\t[]b');
+testEdit('da[_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'da[', 'a\tb');
+testEdit('da]_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'da]', 'a\tb');
+
+// Operator-motion tests
+testVim('D', function(cm, vim, helpers) {
+  cm.setCursor(0, 3);
+  helpers.doKeys('D');
+  eq(' wo\nword2\n word3', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('rd1', register.toString());
+  is(!register.linewise);
+  helpers.assertCursorAt(0, 2);
+}, { value: ' word1\nword2\n word3' });
+testVim('C', function(cm, vim, helpers) {
+  var curStart = makeCursor(0, 3);
+  cm.setCursor(curStart);
+  helpers.doKeys('C');
+  eq(' wo\nword2\n word3', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('rd1', register.toString());
+  is(!register.linewise);
+  eqPos(curStart, cm.getCursor());
+  eq('vim-insert', cm.getOption('keyMap'));
+}, { value: ' word1\nword2\n word3' });
+testVim('Y', function(cm, vim, helpers) {
+  var curStart = makeCursor(0, 3);
+  cm.setCursor(curStart);
+  helpers.doKeys('Y');
+  eq(' word1\nword2\n word3', cm.getValue());
+  var register = helpers.getRegisterController().getRegister();
+  eq('rd1', register.toString());
+  is(!register.linewise);
+  helpers.assertCursorAt(0, 3);
+}, { value: ' word1\nword2\n word3' });
+testVim('~', function(cm, vim, helpers) {
+  helpers.doKeys('3', '~');
+  eq('ABCdefg', cm.getValue());
+  helpers.assertCursorAt(0, 3);
+}, { value: 'abcdefg' });
+
+// Action tests
+testVim('ctrl-a', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('<C-a>');
+  eq('-9', cm.getValue());
+  helpers.assertCursorAt(0, 1);
+  helpers.doKeys('2','<C-a>');
+  eq('-7', cm.getValue());
+}, {value: '-10'});
+testVim('ctrl-x', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('<C-x>');
+  eq('-1', cm.getValue());
+  helpers.assertCursorAt(0, 1);
+  helpers.doKeys('2','<C-x>');
+  eq('-3', cm.getValue());
+}, {value: '0'});
+testVim('<C-x>/<C-a> search forward', function(cm, vim, helpers) {
+  forEach(['<C-x>', '<C-a>'], function(key) {
+    cm.setCursor(0, 0);
+    helpers.doKeys(key);
+    helpers.assertCursorAt(0, 5);
+    helpers.doKeys('l');
+    helpers.doKeys(key);
+    helpers.assertCursorAt(0, 10);
+    cm.setCursor(0, 11);
+    helpers.doKeys(key);
+    helpers.assertCursorAt(0, 11);
+  });
+}, {value: '__jmp1 jmp2 jmp'});
+testVim('a', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.doKeys('a');
+  helpers.assertCursorAt(0, 2);
+  eq('vim-insert', cm.getOption('keyMap'));
+});
+testVim('a_eol', function(cm, vim, helpers) {
+  cm.setCursor(0, lines[0].length - 1);
+  helpers.doKeys('a');
+  helpers.assertCursorAt(0, lines[0].length);
+  eq('vim-insert', cm.getOption('keyMap'));
+});
+testVim('i', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.doKeys('i');
+  helpers.assertCursorAt(0, 1);
+  eq('vim-insert', cm.getOption('keyMap'));
+});
+testVim('i_repeat', function(cm, vim, helpers) {
+  helpers.doKeys('3', 'i');
+  cm.replaceRange('test', cm.getCursor());
+  helpers.doInsertModeKeys('Esc');
+  eq('testtesttest', cm.getValue());
+  helpers.assertCursorAt(0, 11);
+}, { value: '' });
+testVim('i_repeat_delete', function(cm, vim, helpers) {
+  cm.setCursor(0, 4);
+  helpers.doKeys('2', 'i');
+  cm.replaceRange('z', cm.getCursor());
+  helpers.doInsertModeKeys('Backspace', 'Backspace', 'Esc');
+  eq('abe', cm.getValue());
+  helpers.assertCursorAt(0, 1);
+}, { value: 'abcde' });
+testVim('A', function(cm, vim, helpers) {
+  helpers.doKeys('A');
+  helpers.assertCursorAt(0, lines[0].length);
+  eq('vim-insert', cm.getOption('keyMap'));
+});
+testVim('I', function(cm, vim, helpers) {
+  cm.setCursor(0, 4);
+  helpers.doKeys('I');
+  helpers.assertCursorAt(0, lines[0].textStart);
+  eq('vim-insert', cm.getOption('keyMap'));
+});
+testVim('I_repeat', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.doKeys('3', 'I');
+  cm.replaceRange('test', cm.getCursor());
+  helpers.doInsertModeKeys('Esc');
+  eq('testtesttestblah', cm.getValue());
+  helpers.assertCursorAt(0, 11);
+}, { value: 'blah' });
+testVim('o', function(cm, vim, helpers) {
+  cm.setCursor(0, 4);
+  helpers.doKeys('o');
+  eq('word1\n\nword2', cm.getValue());
+  helpers.assertCursorAt(1, 0);
+  eq('vim-insert', cm.getOption('keyMap'));
+}, { value: 'word1\nword2' });
+testVim('o_repeat', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('3', 'o');
+  cm.replaceRange('test', cm.getCursor());
+  helpers.doInsertModeKeys('Esc');
+  eq('\ntest\ntest\ntest', cm.getValue());
+  helpers.assertCursorAt(3, 3);
+}, { value: '' });
+testVim('O', function(cm, vim, helpers) {
+  cm.setCursor(0, 4);
+  helpers.doKeys('O');
+  eq('\nword1\nword2', cm.getValue());
+  helpers.assertCursorAt(0, 0);
+  eq('vim-insert', cm.getOption('keyMap'));
+}, { value: 'word1\nword2' });
+testVim('J', function(cm, vim, helpers) {
+  cm.setCursor(0, 4);
+  helpers.doKeys('J');
+  var expectedValue = 'word1  word2\nword3\n word4';
+  eq(expectedValue, cm.getValue());
+  helpers.assertCursorAt(0, expectedValue.indexOf('word2') - 1);
+}, { value: 'word1 \n    word2\nword3\n word4' });
+testVim('J_repeat', function(cm, vim, helpers) {
+  cm.setCursor(0, 4);
+  helpers.doKeys('3', 'J');
+  var expectedValue = 'word1  word2 word3\n word4';
+  eq(expectedValue, cm.getValue());
+  helpers.assertCursorAt(0, expectedValue.indexOf('word3') - 1);
+}, { value: 'word1 \n    word2\nword3\n word4' });
+testVim('p', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.getRegisterController().pushText('"', 'yank', 'abc\ndef', false);
+  helpers.doKeys('p');
+  eq('__abc\ndef_', cm.getValue());
+  helpers.assertCursorAt(1, 2);
+}, { value: '___' });
+testVim('p_register', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.getRegisterController().getRegister('a').setText('abc\ndef', false);
+  helpers.doKeys('"', 'a', 'p');
+  eq('__abc\ndef_', cm.getValue());
+  helpers.assertCursorAt(1, 2);
+}, { value: '___' });
+testVim('p_wrong_register', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.getRegisterController().getRegister('a').setText('abc\ndef', false);
+  helpers.doKeys('p');
+  eq('___', cm.getValue());
+  helpers.assertCursorAt(0, 1);
+}, { value: '___' });
+testVim('p_line', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.getRegisterController().pushText('"', 'yank', '  a\nd\n', true);
+  helpers.doKeys('2', 'p');
+  eq('___\n  a\nd\n  a\nd', cm.getValue());
+  helpers.assertCursorAt(1, 2);
+}, { value: '___' });
+testVim('p_lastline', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.getRegisterController().pushText('"', 'yank', '  a\nd', true);
+  helpers.doKeys('2', 'p');
+  eq('___\n  a\nd\n  a\nd', cm.getValue());
+  helpers.assertCursorAt(1, 2);
+}, { value: '___' });
+testVim('P', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.getRegisterController().pushText('"', 'yank', 'abc\ndef', false);
+  helpers.doKeys('P');
+  eq('_abc\ndef__', cm.getValue());
+  helpers.assertCursorAt(1, 3);
+}, { value: '___' });
+testVim('P_line', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.getRegisterController().pushText('"', 'yank', '  a\nd\n', true);
+  helpers.doKeys('2', 'P');
+  eq('  a\nd\n  a\nd\n___', cm.getValue());
+  helpers.assertCursorAt(0, 2);
+}, { value: '___' });
+testVim('r', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.doKeys('3', 'r', 'u');
+  eq('wuuuet\nanother', cm.getValue(),'3r failed');
+  helpers.assertCursorAt(0, 3);
+  cm.setCursor(0, 4);
+  helpers.doKeys('v', 'j', 'h', 'r', '<Space>');
+  eq('wuuu  \n    her', cm.getValue(),'Replacing selection by space-characters failed');
+}, { value: 'wordet\nanother' });
+testVim('R', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.doKeys('R');
+  helpers.assertCursorAt(0, 1);
+  eq('vim-replace', cm.getOption('keyMap'));
+  is(cm.state.overwrite, 'Setting overwrite state failed');
+});
+testVim('mark', function(cm, vim, helpers) {
+  cm.setCursor(2, 2);
+  helpers.doKeys('m', 't');
+  cm.setCursor(0, 0);
+  helpers.doKeys('\'', 't');
+  helpers.assertCursorAt(2, 2);
+  cm.setCursor(0, 0);
+  helpers.doKeys('`', 't');
+  helpers.assertCursorAt(2, 2);
+});
+testVim('jumpToMark_next', function(cm, vim, helpers) {
+  cm.setCursor(2, 2);
+  helpers.doKeys('m', 't');
+  cm.setCursor(0, 0);
+  helpers.doKeys(']', '`');
+  helpers.assertCursorAt(2, 2);
+  cm.setCursor(0, 0);
+  helpers.doKeys(']', '\'');
+  helpers.assertCursorAt(2, 0);
+});
+testVim('jumpToMark_next_repeat', function(cm, vim, helpers) {
+  cm.setCursor(2, 2);
+  helpers.doKeys('m', 'a');
+  cm.setCursor(3, 2);
+  helpers.doKeys('m', 'b');
+  cm.setCursor(4, 2);
+  helpers.doKeys('m', 'c');
+  cm.setCursor(0, 0);
+  helpers.doKeys('2', ']', '`');
+  helpers.assertCursorAt(3, 2);
+  cm.setCursor(0, 0);
+  helpers.doKeys('2', ']', '\'');
+  helpers.assertCursorAt(3, 1);
+});
+testVim('jumpToMark_next_sameline', function(cm, vim, helpers) {
+  cm.setCursor(2, 0);
+  helpers.doKeys('m', 'a');
+  cm.setCursor(2, 4);
+  helpers.doKeys('m', 'b');
+  cm.setCursor(2, 2);
+  helpers.doKeys(']', '`');
+  helpers.assertCursorAt(2, 4);
+});
+testVim('jumpToMark_next_onlyprev', function(cm, vim, helpers) {
+  cm.setCursor(2, 0);
+  helpers.doKeys('m', 'a');
+  cm.setCursor(4, 0);
+  helpers.doKeys(']', '`');
+  helpers.assertCursorAt(4, 0);
+});
+testVim('jumpToMark_next_nomark', function(cm, vim, helpers) {
+  cm.setCursor(2, 2);
+  helpers.doKeys(']', '`');
+  helpers.assertCursorAt(2, 2);
+  helpers.doKeys(']', '\'');
+  helpers.assertCursorAt(2, 0);
+});
+testVim('jumpToMark_next_linewise_over', function(cm, vim, helpers) {
+  cm.setCursor(2, 2);
+  helpers.doKeys('m', 'a');
+  cm.setCursor(3, 4);
+  helpers.doKeys('m', 'b');
+  cm.setCursor(2, 1);
+  helpers.doKeys(']', '\'');
+  helpers.assertCursorAt(3, 1);
+});
+testVim('jumpToMark_next_action', function(cm, vim, helpers) {
+  cm.setCursor(2, 2);
+  helpers.doKeys('m', 't');
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', ']', '`');
+  helpers.assertCursorAt(0, 0);
+  var actual = cm.getLine(0);
+  var expected = 'pop pop 0 1 2 3 4';
+  eq(actual, expected, "Deleting while jumping to the next mark failed.");
+});
+testVim('jumpToMark_next_line_action', function(cm, vim, helpers) {
+  cm.setCursor(2, 2);
+  helpers.doKeys('m', 't');
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', ']', '\'');
+  helpers.assertCursorAt(0, 1);
+  var actual = cm.getLine(0);
+  var expected = ' (a) [b] {c} '
+  eq(actual, expected, "Deleting while jumping to the next mark line failed.");
+});
+testVim('jumpToMark_prev', function(cm, vim, helpers) {
+  cm.setCursor(2, 2);
+  helpers.doKeys('m', 't');
+  cm.setCursor(4, 0);
+  helpers.doKeys('[', '`');
+  helpers.assertCursorAt(2, 2);
+  cm.setCursor(4, 0);
+  helpers.doKeys('[', '\'');
+  helpers.assertCursorAt(2, 0);
+});
+testVim('jumpToMark_prev_repeat', function(cm, vim, helpers) {
+  cm.setCursor(2, 2);
+  helpers.doKeys('m', 'a');
+  cm.setCursor(3, 2);
+  helpers.doKeys('m', 'b');
+  cm.setCursor(4, 2);
+  helpers.doKeys('m', 'c');
+  cm.setCursor(5, 0);
+  helpers.doKeys('2', '[', '`');
+  helpers.assertCursorAt(3, 2);
+  cm.setCursor(5, 0);
+  helpers.doKeys('2', '[', '\'');
+  helpers.assertCursorAt(3, 1);
+});
+testVim('jumpToMark_prev_sameline', function(cm, vim, helpers) {
+  cm.setCursor(2, 0);
+  helpers.doKeys('m', 'a');
+  cm.setCursor(2, 4);
+  helpers.doKeys('m', 'b');
+  cm.setCursor(2, 2);
+  helpers.doKeys('[', '`');
+  helpers.assertCursorAt(2, 0);
+});
+testVim('jumpToMark_prev_onlynext', function(cm, vim, helpers) {
+  cm.setCursor(4, 4);
+  helpers.doKeys('m', 'a');
+  cm.setCursor(2, 0);
+  helpers.doKeys('[', '`');
+  helpers.assertCursorAt(2, 0);
+});
+testVim('jumpToMark_prev_nomark', function(cm, vim, helpers) {
+  cm.setCursor(2, 2);
+  helpers.doKeys('[', '`');
+  helpers.assertCursorAt(2, 2);
+  helpers.doKeys('[', '\'');
+  helpers.assertCursorAt(2, 0);
+});
+testVim('jumpToMark_prev_linewise_over', function(cm, vim, helpers) {
+  cm.setCursor(2, 2);
+  helpers.doKeys('m', 'a');
+  cm.setCursor(3, 4);
+  helpers.doKeys('m', 'b');
+  cm.setCursor(3, 6);
+  helpers.doKeys('[', '\'');
+  helpers.assertCursorAt(2, 0);
+});
+testVim('delmark_single', function(cm, vim, helpers) {
+  cm.setCursor(1, 2);
+  helpers.doKeys('m', 't');
+  helpers.doEx('delmarks t');
+  cm.setCursor(0, 0);
+  helpers.doKeys('`', 't');
+  helpers.assertCursorAt(0, 0);
+});
+testVim('delmark_range', function(cm, vim, helpers) {
+  cm.setCursor(1, 2);
+  helpers.doKeys('m', 'a');
+  cm.setCursor(2, 2);
+  helpers.doKeys('m', 'b');
+  cm.setCursor(3, 2);
+  helpers.doKeys('m', 'c');
+  cm.setCursor(4, 2);
+  helpers.doKeys('m', 'd');
+  cm.setCursor(5, 2);
+  helpers.doKeys('m', 'e');
+  helpers.doEx('delmarks b-d');
+  cm.setCursor(0, 0);
+  helpers.doKeys('`', 'a');
+  helpers.assertCursorAt(1, 2);
+  helpers.doKeys('`', 'b');
+  helpers.assertCursorAt(1, 2);
+  helpers.doKeys('`', 'c');
+  helpers.assertCursorAt(1, 2);
+  helpers.doKeys('`', 'd');
+  helpers.assertCursorAt(1, 2);
+  helpers.doKeys('`', 'e');
+  helpers.assertCursorAt(5, 2);
+});
+testVim('delmark_multi', function(cm, vim, helpers) {
+  cm.setCursor(1, 2);
+  helpers.doKeys('m', 'a');
+  cm.setCursor(2, 2);
+  helpers.doKeys('m', 'b');
+  cm.setCursor(3, 2);
+  helpers.doKeys('m', 'c');
+  cm.setCursor(4, 2);
+  helpers.doKeys('m', 'd');
+  cm.setCursor(5, 2);
+  helpers.doKeys('m', 'e');
+  helpers.doEx('delmarks bcd');
+  cm.setCursor(0, 0);
+  helpers.doKeys('`', 'a');
+  helpers.assertCursorAt(1, 2);
+  helpers.doKeys('`', 'b');
+  helpers.assertCursorAt(1, 2);
+  helpers.doKeys('`', 'c');
+  helpers.assertCursorAt(1, 2);
+  helpers.doKeys('`', 'd');
+  helpers.assertCursorAt(1, 2);
+  helpers.doKeys('`', 'e');
+  helpers.assertCursorAt(5, 2);
+});
+testVim('delmark_multi_space', function(cm, vim, helpers) {
+  cm.setCursor(1, 2);
+  helpers.doKeys('m', 'a');
+  cm.setCursor(2, 2);
+  helpers.doKeys('m', 'b');
+  cm.setCursor(3, 2);
+  helpers.doKeys('m', 'c');
+  cm.setCursor(4, 2);
+  helpers.doKeys('m', 'd');
+  cm.setCursor(5, 2);
+  helpers.doKeys('m', 'e');
+  helpers.doEx('delmarks b c d');
+  cm.setCursor(0, 0);
+  helpers.doKeys('`', 'a');
+  helpers.assertCursorAt(1, 2);
+  helpers.doKeys('`', 'b');
+  helpers.assertCursorAt(1, 2);
+  helpers.doKeys('`', 'c');
+  helpers.assertCursorAt(1, 2);
+  helpers.doKeys('`', 'd');
+  helpers.assertCursorAt(1, 2);
+  helpers.doKeys('`', 'e');
+  helpers.assertCursorAt(5, 2);
+});
+testVim('delmark_all', function(cm, vim, helpers) {
+  cm.setCursor(1, 2);
+  helpers.doKeys('m', 'a');
+  cm.setCursor(2, 2);
+  helpers.doKeys('m', 'b');
+  cm.setCursor(3, 2);
+  helpers.doKeys('m', 'c');
+  cm.setCursor(4, 2);
+  helpers.doKeys('m', 'd');
+  cm.setCursor(5, 2);
+  helpers.doKeys('m', 'e');
+  helpers.doEx('delmarks a b-de');
+  cm.setCursor(0, 0);
+  helpers.doKeys('`', 'a');
+  helpers.assertCursorAt(0, 0);
+  helpers.doKeys('`', 'b');
+  helpers.assertCursorAt(0, 0);
+  helpers.doKeys('`', 'c');
+  helpers.assertCursorAt(0, 0);
+  helpers.doKeys('`', 'd');
+  helpers.assertCursorAt(0, 0);
+  helpers.doKeys('`', 'e');
+  helpers.assertCursorAt(0, 0);
+});
+testVim('visual', function(cm, vim, helpers) {
+  helpers.doKeys('l', 'v', 'l', 'l');
+  helpers.assertCursorAt(0, 3);
+  eqPos(makeCursor(0, 1), cm.getCursor('anchor'));
+  helpers.doKeys('d');
+  eq('15', cm.getValue());
+}, { value: '12345' });
+testVim('visual_line', function(cm, vim, helpers) {
+  helpers.doKeys('l', 'V', 'l', 'j', 'j', 'd');
+  eq(' 4\n 5', cm.getValue());
+}, { value: ' 1\n 2\n 3\n 4\n 5' });
+testVim('visual_marks', function(cm, vim, helpers) {
+  helpers.doKeys('l', 'v', 'l', 'l', 'v');
+  // Test visual mode marks
+  cm.setCursor(0, 0);
+  helpers.doKeys('\'', '<');
+  helpers.assertCursorAt(0, 1);
+  helpers.doKeys('\'', '>');
+  helpers.assertCursorAt(0, 3);
+});
+testVim('visual_join', function(cm, vim, helpers) {
+  helpers.doKeys('l', 'V', 'l', 'j', 'j', 'J');
+  eq(' 1 2 3\n 4\n 5', cm.getValue());
+}, { value: ' 1\n 2\n 3\n 4\n 5' });
+testVim('visual_blank', function(cm, vim, helpers) {
+  helpers.doKeys('v', 'k');
+  eq(vim.visualMode, true);
+}, { value: '\n' });
+testVim('reselect_visual', function(cm, vim, helpers) {
+  helpers.doKeys('l', 'v', 'l', 'l', 'y', 'g', 'v');
+  helpers.assertCursorAt(0, 3);
+  eqPos(makeCursor(0, 1), cm.getCursor('anchor'));
+  helpers.doKeys('d');
+  eq('15', cm.getValue());
+}, { value: '12345' });
+testVim('reselect_visual_line', function(cm, vim, helpers) {
+  helpers.doKeys('l', 'V', 'l', 'j', 'j', 'V', 'g', 'v', 'd');
+  eq(' 4\n 5', cm.getValue());
+}, { value: ' 1\n 2\n 3\n 4\n 5' });
+testVim('s_normal', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.doKeys('s');
+  helpers.doInsertModeKeys('Esc');
+  helpers.assertCursorAt(0, 0);
+  eq('ac', cm.getValue());
+}, { value: 'abc'});
+testVim('s_visual', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.doKeys('v', 's');
+  helpers.doInsertModeKeys('Esc');
+  helpers.assertCursorAt(0, 0);
+  eq('ac', cm.getValue());
+}, { value: 'abc'});
+testVim('o_visual', function(cm,vim,helpers) {
+  cm.setCursor(0,0);
+  helpers.doKeys('v','l','l','l','o');
+  helpers.assertCursorAt(0,0);
+  helpers.doKeys('v','v','j','j','j','o');
+  helpers.assertCursorAt(0,0);
+  helpers.doKeys('o');
+  helpers.doKeys('l','l')
+  helpers.assertCursorAt(3,2);
+  helpers.doKeys('d');
+  eq('p',cm.getValue());
+}, { value: 'abcd\nefgh\nijkl\nmnop'});
+
+testVim('S_normal', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.doKeys('j', 'S');
+  helpers.doInsertModeKeys('Esc');
+  helpers.assertCursorAt(1, 0);
+  eq('aa\n\ncc', cm.getValue());
+}, { value: 'aa\nbb\ncc'});
+testVim('S_visual', function(cm, vim, helpers) {
+  cm.setCursor(0, 1);
+  helpers.doKeys('v', 'j', 'S');
+  helpers.doInsertModeKeys('Esc');
+  helpers.assertCursorAt(0, 0);
+  eq('\ncc', cm.getValue());
+}, { value: 'aa\nbb\ncc'});
+
+testVim('/ and n/N', function(cm, vim, helpers) {
+  cm.openDialog = helpers.fakeOpenDialog('match');
+  helpers.doKeys('/');
+  helpers.assertCursorAt(0, 11);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(1, 6);
+  helpers.doKeys('N');
+  helpers.assertCursorAt(0, 11);
+
+  cm.setCursor(0, 0);
+  helpers.doKeys('2', '/');
+  helpers.assertCursorAt(1, 6);
+}, { value: 'match nope match \n nope Match' });
+testVim('/_case', function(cm, vim, helpers) {
+  cm.openDialog = helpers.fakeOpenDialog('Match');
+  helpers.doKeys('/');
+  helpers.assertCursorAt(1, 6);
+}, { value: 'match nope match \n nope Match' });
+testVim('/_2_pcre', function(cm, vim, helpers) {
+  CodeMirror.Vim.setOption('pcre', true);
+  cm.openDialog = helpers.fakeOpenDialog('(word){2}');
+  helpers.doKeys('/');
+  helpers.assertCursorAt(1, 9);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(2, 1);
+}, { value: 'word\n another wordword\n wordwordword\n' });
+testVim('/_2_nopcre', function(cm, vim, helpers) {
+  CodeMirror.Vim.setOption('pcre', false);
+  cm.openDialog = helpers.fakeOpenDialog('\\(word\\)\\{2}');
+  helpers.doKeys('/');
+  helpers.assertCursorAt(1, 9);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(2, 1);
+}, { value: 'word\n another wordword\n wordwordword\n' });
+testVim('/_nongreedy', function(cm, vim, helpers) {
+  cm.openDialog = helpers.fakeOpenDialog('aa');
+  helpers.doKeys('/');
+  helpers.assertCursorAt(0, 4);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(1, 3);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(0, 0);
+}, { value: 'aaa aa \n a aa'});
+testVim('?_nongreedy', function(cm, vim, helpers) {
+  cm.openDialog = helpers.fakeOpenDialog('aa');
+  helpers.doKeys('?');
+  helpers.assertCursorAt(1, 3);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(0, 4);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(0, 0);
+}, { value: 'aaa aa \n a aa'});
+testVim('/_greedy', function(cm, vim, helpers) {
+  cm.openDialog = helpers.fakeOpenDialog('a+');
+  helpers.doKeys('/');
+  helpers.assertCursorAt(0, 4);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(1, 1);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(1, 3);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(0, 0);
+}, { value: 'aaa aa \n a aa'});
+testVim('?_greedy', function(cm, vim, helpers) {
+  cm.openDialog = helpers.fakeOpenDialog('a+');
+  helpers.doKeys('?');
+  helpers.assertCursorAt(1, 3);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(1, 1);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(0, 4);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(0, 0);
+}, { value: 'aaa aa \n a aa'});
+testVim('/_greedy_0_or_more', function(cm, vim, helpers) {
+  cm.openDialog = helpers.fakeOpenDialog('a*');
+  helpers.doKeys('/');
+  helpers.assertCursorAt(0, 3);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(0, 4);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(0, 5);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(1, 0);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(1, 1);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(0, 0);
+}, { value: 'aaa  aa\n aa'});
+testVim('?_greedy_0_or_more', function(cm, vim, helpers) {
+  cm.openDialog = helpers.fakeOpenDialog('a*');
+  helpers.doKeys('?');
+  helpers.assertCursorAt(1, 1);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(1, 0);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(0, 5);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(0, 4);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(0, 3);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(0, 0);
+}, { value: 'aaa  aa\n aa'});
+testVim('? and n/N', function(cm, vim, helpers) {
+  cm.openDialog = helpers.fakeOpenDialog('match');
+  helpers.doKeys('?');
+  helpers.assertCursorAt(1, 6);
+  helpers.doKeys('n');
+  helpers.assertCursorAt(0, 11);
+  helpers.doKeys('N');
+  helpers.assertCursorAt(1, 6);
+
+  cm.setCursor(0, 0);
+  helpers.doKeys('2', '?');
+  helpers.assertCursorAt(0, 11);
+}, { value: 'match nope match \n nope Match' });
+testVim('*', function(cm, vim, helpers) {
+  cm.setCursor(0, 9);
+  helpers.doKeys('*');
+  helpers.assertCursorAt(0, 22);
+
+  cm.setCursor(0, 9);
+  helpers.doKeys('2', '*');
+  helpers.assertCursorAt(1, 8);
+}, { value: 'nomatch match nomatch match \nnomatch Match' });
+testVim('*_no_word', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('*');
+  helpers.assertCursorAt(0, 0);
+}, { value: ' \n match \n' });
+testVim('*_symbol', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('*');
+  helpers.assertCursorAt(1, 0);
+}, { value: ' /}\n/} match \n' });
+testVim('#', function(cm, vim, helpers) {
+  cm.setCursor(0, 9);
+  helpers.doKeys('#');
+  helpers.assertCursorAt(1, 8);
+
+  cm.setCursor(0, 9);
+  helpers.doKeys('2', '#');
+  helpers.assertCursorAt(0, 22);
+}, { value: 'nomatch match nomatch match \nnomatch Match' });
+testVim('*_seek', function(cm, vim, helpers) {
+  // Should skip over space and symbols.
+  cm.setCursor(0, 3);
+  helpers.doKeys('*');
+  helpers.assertCursorAt(0, 22);
+}, { value: '    :=  match nomatch match \nnomatch Match' });
+testVim('#', function(cm, vim, helpers) {
+  // Should skip over space and symbols.
+  cm.setCursor(0, 3);
+  helpers.doKeys('#');
+  helpers.assertCursorAt(1, 8);
+}, { value: '    :=  match nomatch match \nnomatch Match' });
+testVim('macro_insert', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('q', 'a', '0', 'i');
+  cm.replaceRange('foo', cm.getCursor());
+  helpers.doInsertModeKeys('Esc');
+  helpers.doKeys('q', '@', 'a');
+  eq('foofoo', cm.getValue());
+}, { value: ''});
+testVim('macro_space', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('<Space>', '<Space>');
+  helpers.assertCursorAt(0, 2);
+  helpers.doKeys('q', 'a', '<Space>', '<Space>', 'q');
+  helpers.assertCursorAt(0, 4);
+  helpers.doKeys('@', 'a');
+  helpers.assertCursorAt(0, 6);
+  helpers.doKeys('@', 'a');
+  helpers.assertCursorAt(0, 8);
+}, { value: 'one line of text.'});
+testVim('macro_parens', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('q', 'z', 'i');
+  cm.replaceRange('(', cm.getCursor());
+  helpers.doInsertModeKeys('Esc');
+  helpers.doKeys('e', 'a');
+  cm.replaceRange(')', cm.getCursor());
+  helpers.doInsertModeKeys('Esc');
+  helpers.doKeys('q');
+  helpers.doKeys('w', '@', 'z');
+  helpers.doKeys('w', '@', 'z');
+  eq('(see) (spot) (run)', cm.getValue());
+}, { value: 'see spot run'});
+testVim('macro_overwrite', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('q', 'z', '0', 'i');
+  cm.replaceRange('I ', cm.getCursor());
+  helpers.doInsertModeKeys('Esc');
+  helpers.doKeys('q');
+  helpers.doKeys('e');
+  // Now replace the macro with something else.
+  helpers.doKeys('q', 'z', 'a');
+  cm.replaceRange('.', cm.getCursor());
+  helpers.doInsertModeKeys('Esc');
+  helpers.doKeys('q');
+  helpers.doKeys('e', '@', 'z');
+  helpers.doKeys('e', '@', 'z');
+  eq('I see. spot. run.', cm.getValue());
+}, { value: 'see spot run'});
+testVim('macro_search_f', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('q', 'a', 'f', ' ');
+  helpers.assertCursorAt(0,3);
+  helpers.doKeys('q', '0');
+  helpers.assertCursorAt(0,0);
+  helpers.doKeys('@', 'a');
+  helpers.assertCursorAt(0,3);
+}, { value: 'The quick brown fox jumped over the lazy dog.'});
+testVim('macro_search_2f', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('q', 'a', '2', 'f', ' ');
+  helpers.assertCursorAt(0,9);
+  helpers.doKeys('q', '0');
+  helpers.assertCursorAt(0,0);
+  helpers.doKeys('@', 'a');
+  helpers.assertCursorAt(0,9);
+}, { value: 'The quick brown fox jumped over the lazy dog.'});
+testVim('yank_register', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('"', 'a', 'y', 'y');
+  helpers.doKeys('j', '"', 'b', 'y', 'y');
+  cm.openDialog = helpers.fakeOpenDialog('registers');
+  cm.openNotification = helpers.fakeOpenNotification(function(text) {
+    is(/a\s+foo/.test(text));
+    is(/b\s+bar/.test(text));
+  });
+  helpers.doKeys(':');
+}, { value: 'foo\nbar'});
+testVim('macro_register', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('q', 'a', 'i');
+  cm.replaceRange('gangnam', cm.getCursor());
+  helpers.doInsertModeKeys('Esc');
+  helpers.doKeys('q');
+  helpers.doKeys('q', 'b', 'o');
+  cm.replaceRange('style', cm.getCursor());
+  helpers.doInsertModeKeys('Esc');
+  helpers.doKeys('q');
+  cm.openDialog = helpers.fakeOpenDialog('registers');
+  cm.openNotification = helpers.fakeOpenNotification(function(text) {
+    is(/a\s+i/.test(text));
+    is(/b\s+o/.test(text));
+  });
+  helpers.doKeys(':');
+}, { value: ''});
+testVim('.', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('2', 'd', 'w');
+  helpers.doKeys('.');
+  eq('5 6', cm.getValue());
+}, { value: '1 2 3 4 5 6'});
+testVim('._repeat', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('2', 'd', 'w');
+  helpers.doKeys('3', '.');
+  eq('6', cm.getValue());
+}, { value: '1 2 3 4 5 6'});
+testVim('._insert', function(cm, vim, helpers) {
+  helpers.doKeys('i');
+  cm.replaceRange('test', cm.getCursor());
+  helpers.doInsertModeKeys('Esc');
+  helpers.doKeys('.');
+  eq('testestt', cm.getValue());
+  helpers.assertCursorAt(0, 6);
+}, { value: ''});
+testVim('._insert_repeat', function(cm, vim, helpers) {
+  helpers.doKeys('i');
+  cm.replaceRange('test', cm.getCursor());
+  cm.setCursor(0, 4);
+  helpers.doInsertModeKeys('Esc');
+  helpers.doKeys('2', '.');
+  eq('testesttestt', cm.getValue());
+  helpers.assertCursorAt(0, 10);
+}, { value: ''});
+testVim('._repeat_insert', function(cm, vim, helpers) {
+  helpers.doKeys('3', 'i');
+  cm.replaceRange('te', cm.getCursor());
+  cm.setCursor(0, 2);
+  helpers.doInsertModeKeys('Esc');
+  helpers.doKeys('.');
+  eq('tetettetetee', cm.getValue());
+  helpers.assertCursorAt(0, 10);
+}, { value: ''});
+testVim('._insert_o', function(cm, vim, helpers) {
+  helpers.doKeys('o');
+  cm.replaceRange('z', cm.getCursor());
+  cm.setCursor(1, 1);
+  helpers.doInsertModeKeys('Esc');
+  helpers.doKeys('.');
+  eq('\nz\nz', cm.getValue());
+  helpers.assertCursorAt(2, 0);
+}, { value: ''});
+testVim('._insert_o_repeat', function(cm, vim, helpers) {
+  helpers.doKeys('o');
+  cm.replaceRange('z', cm.getCursor());
+  helpers.doInsertModeKeys('Esc');
+  cm.setCursor(1, 0);
+  helpers.doKeys('2', '.');
+  eq('\nz\nz\nz', cm.getValue());
+  helpers.assertCursorAt(3, 0);
+}, { value: ''});
+testVim('._insert_o_indent', function(cm, vim, helpers) {
+  helpers.doKeys('o');
+  cm.replaceRange('z', cm.getCursor());
+  helpers.doInsertModeKeys('Esc');
+  cm.setCursor(1, 2);
+  helpers.doKeys('.');
+  eq('{\n  z\n  z', cm.getValue());
+  helpers.assertCursorAt(2, 2);
+}, { value: '{'});
+testVim('._insert_cw', function(cm, vim, helpers) {
+  helpers.doKeys('c', 'w');
+  cm.replaceRange('test', cm.getCursor());
+  helpers.doInsertModeKeys('Esc');
+  cm.setCursor(0, 3);
+  helpers.doKeys('2', 'l');
+  helpers.doKeys('.');
+  eq('test test word3', cm.getValue());
+  helpers.assertCursorAt(0, 8);
+}, { value: 'word1 word2 word3' });
+testVim('._insert_cw_repeat', function(cm, vim, helpers) {
+  // For some reason, repeat cw in desktop VIM will does not repeat insert mode
+  // changes. Will conform to that behavior.
+  helpers.doKeys('c', 'w');
+  cm.replaceRange('test', cm.getCursor());
+  helpers.doInsertModeKeys('Esc');
+  cm.setCursor(0, 4);
+  helpers.doKeys('l');
+  helpers.doKeys('2', '.');
+  eq('test test', cm.getValue());
+  helpers.assertCursorAt(0, 8);
+}, { value: 'word1 word2 word3' });
+testVim('._delete', function(cm, vim, helpers) {
+  cm.setCursor(0, 5);
+  helpers.doKeys('i');
+  helpers.doInsertModeKeys('Backspace', 'Esc');
+  helpers.doKeys('.');
+  eq('zace', cm.getValue());
+  helpers.assertCursorAt(0, 1);
+}, { value: 'zabcde'});
+testVim('._delete_repeat', function(cm, vim, helpers) {
+  cm.setCursor(0, 6);
+  helpers.doKeys('i');
+  helpers.doInsertModeKeys('Backspace', 'Esc');
+  helpers.doKeys('2', '.');
+  eq('zzce', cm.getValue());
+  helpers.assertCursorAt(0, 1);
+}, { value: 'zzabcde'});
+testVim('f;', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('f', 'x');
+  helpers.doKeys(';');
+  helpers.doKeys('2', ';');
+  eq(9, cm.getCursor().ch);
+}, { value: '01x3xx678x'});
+testVim('F;', function(cm, vim, helpers) {
+  cm.setCursor(0, 8);
+  helpers.doKeys('F', 'x');
+  helpers.doKeys(';');
+  helpers.doKeys('2', ';');
+  eq(2, cm.getCursor().ch);
+}, { value: '01x3xx6x8x'});
+testVim('t;', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('t', 'x');
+  helpers.doKeys(';');
+  helpers.doKeys('2', ';');
+  eq(8, cm.getCursor().ch);
+}, { value: '01x3xx678x'});
+testVim('T;', function(cm, vim, helpers) {
+  cm.setCursor(0, 9);
+  helpers.doKeys('T', 'x');
+  helpers.doKeys(';');
+  helpers.doKeys('2', ';');
+  eq(2, cm.getCursor().ch);
+}, { value: '0xx3xx678x'});
+testVim('f,', function(cm, vim, helpers) {
+  cm.setCursor(0, 6);
+  helpers.doKeys('f', 'x');
+  helpers.doKeys(',');
+  helpers.doKeys('2', ',');
+  eq(2, cm.getCursor().ch);
+}, { value: '01x3xx678x'});
+testVim('F,', function(cm, vim, helpers) {
+  cm.setCursor(0, 3);
+  helpers.doKeys('F', 'x');
+  helpers.doKeys(',');
+  helpers.doKeys('2', ',');
+  eq(9, cm.getCursor().ch);
+}, { value: '01x3xx678x'});
+testVim('t,', function(cm, vim, helpers) {
+  cm.setCursor(0, 6);
+  helpers.doKeys('t', 'x');
+  helpers.doKeys(',');
+  helpers.doKeys('2', ',');
+  eq(3, cm.getCursor().ch);
+}, { value: '01x3xx678x'});
+testVim('T,', function(cm, vim, helpers) {
+  cm.setCursor(0, 4);
+  helpers.doKeys('T', 'x');
+  helpers.doKeys(',');
+  helpers.doKeys('2', ',');
+  eq(8, cm.getCursor().ch);
+}, { value: '01x3xx67xx'});
+testVim('fd,;', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('f', '4');
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', ';');
+  eq('56789', cm.getValue());
+  helpers.doKeys('u');
+  cm.setCursor(0, 9);
+  helpers.doKeys('d', ',');
+  eq('01239', cm.getValue());
+}, { value: '0123456789'});
+testVim('Fd,;', function(cm, vim, helpers) {
+  cm.setCursor(0, 9);
+  helpers.doKeys('F', '4');
+  cm.setCursor(0, 9);
+  helpers.doKeys('d', ';');
+  eq('01239', cm.getValue());
+  helpers.doKeys('u');
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', ',');
+  eq('56789', cm.getValue());
+}, { value: '0123456789'});
+testVim('td,;', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('t', '4');
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', ';');
+  eq('456789', cm.getValue());
+  helpers.doKeys('u');
+  cm.setCursor(0, 9);
+  helpers.doKeys('d', ',');
+  eq('012349', cm.getValue());
+}, { value: '0123456789'});
+testVim('Td,;', function(cm, vim, helpers) {
+  cm.setCursor(0, 9);
+  helpers.doKeys('T', '4');
+  cm.setCursor(0, 9);
+  helpers.doKeys('d', ';');
+  eq('012349', cm.getValue());
+  helpers.doKeys('u');
+  cm.setCursor(0, 0);
+  helpers.doKeys('d', ',');
+  eq('456789', cm.getValue());
+}, { value: '0123456789'});
+testVim('fc,;', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('f', '4');
+  cm.setCursor(0, 0);
+  helpers.doKeys('c', ';', 'Esc');
+  eq('56789', cm.getValue());
+  helpers.doKeys('u');
+  cm.setCursor(0, 9);
+  helpers.doKeys('c', ',');
+  eq('01239', cm.getValue());
+}, { value: '0123456789'});
+testVim('Fc,;', function(cm, vim, helpers) {
+  cm.setCursor(0, 9);
+  helpers.doKeys('F', '4');
+  cm.setCursor(0, 9);
+  helpers.doKeys('c', ';', 'Esc');
+  eq('01239', cm.getValue());
+  helpers.doKeys('u');
+  cm.setCursor(0, 0);
+  helpers.doKeys('c', ',');
+  eq('56789', cm.getValue());
+}, { value: '0123456789'});
+testVim('tc,;', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('t', '4');
+  cm.setCursor(0, 0);
+  helpers.doKeys('c', ';', 'Esc');
+  eq('456789', cm.getValue());
+  helpers.doKeys('u');
+  cm.setCursor(0, 9);
+  helpers.doKeys('c', ',');
+  eq('012349', cm.getValue());
+}, { value: '0123456789'});
+testVim('Tc,;', function(cm, vim, helpers) {
+  cm.setCursor(0, 9);
+  helpers.doKeys('T', '4');
+  cm.setCursor(0, 9);
+  helpers.doKeys('c', ';', 'Esc');
+  eq('012349', cm.getValue());
+  helpers.doKeys('u');
+  cm.setCursor(0, 0);
+  helpers.doKeys('c', ',');
+  eq('456789', cm.getValue());
+}, { value: '0123456789'});
+testVim('fy,;', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('f', '4');
+  cm.setCursor(0, 0);
+  helpers.doKeys('y', ';', 'P');
+  eq('012340123456789', cm.getValue());
+  helpers.doKeys('u');
+  cm.setCursor(0, 9);
+  helpers.doKeys('y', ',', 'P');
+  eq('012345678456789', cm.getValue());
+}, { value: '0123456789'});
+testVim('Fy,;', function(cm, vim, helpers) {
+  cm.setCursor(0, 9);
+  helpers.doKeys('F', '4');
+  cm.setCursor(0, 9);
+  helpers.doKeys('y', ';', 'p');
+  eq('012345678945678', cm.getValue());
+  helpers.doKeys('u');
+  cm.setCursor(0, 0);
+  helpers.doKeys('y', ',', 'P');
+  eq('012340123456789', cm.getValue());
+}, { value: '0123456789'});
+testVim('ty,;', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys('t', '4');
+  cm.setCursor(0, 0);
+  helpers.doKeys('y', ';', 'P');
+  eq('01230123456789', cm.getValue());
+  helpers.doKeys('u');
+  cm.setCursor(0, 9);
+  helpers.doKeys('y', ',', 'p');
+  eq('01234567895678', cm.getValue());
+}, { value: '0123456789'});
+testVim('Ty,;', function(cm, vim, helpers) {
+  cm.setCursor(0, 9);
+  helpers.doKeys('T', '4');
+  cm.setCursor(0, 9);
+  helpers.doKeys('y', ';', 'p');
+  eq('01234567895678', cm.getValue());
+  helpers.doKeys('u');
+  cm.setCursor(0, 0);
+  helpers.doKeys('y', ',', 'P');
+  eq('01230123456789', cm.getValue());
+}, { value: '0123456789'});
+testVim('HML', function(cm, vim, helpers) {
+  var lines = 35;
+  var textHeight = cm.defaultTextHeight();
+  cm.setSize(600, lines*textHeight);
+  cm.setCursor(120, 0);
+  helpers.doKeys('H');
+  helpers.assertCursorAt(86, 2);
+  helpers.doKeys('L');
+  helpers.assertCursorAt(120, 4);
+  helpers.doKeys('M');
+  helpers.assertCursorAt(103,4);
+}, { value: (function(){
+  var lines = new Array(100);
+  var upper = '  xx\n';
+  var lower = '    xx\n';
+  upper = lines.join(upper);
+  lower = lines.join(lower);
+  return upper + lower;
+})()});
+
+var zVals = ['zb','zz','zt','z-','z.','z<CR>'].map(function(e, idx){
+  var lineNum = 250;
+  var lines = 35;
+  testVim(e, function(cm, vim, helpers) {
+    var k1 = e[0];
+    var k2 = e.substring(1);
+    var textHeight = cm.defaultTextHeight();
+    cm.setSize(600, lines*textHeight);
+    cm.setCursor(lineNum, 0);
+    helpers.doKeys(k1, k2);
+    zVals[idx] = cm.getScrollInfo().top;
+  }, { value: (function(){
+    return new Array(500).join('\n');
+  })()});
+});
+testVim('zb<zz', function(cm, vim, helpers){
+  eq(zVals[0]<zVals[1], true);
+});
+testVim('zz<zt', function(cm, vim, helpers){
+  eq(zVals[1]<zVals[2], true);
+});
+testVim('zb==z-', function(cm, vim, helpers){
+  eq(zVals[0], zVals[3]);
+});
+testVim('zz==z.', function(cm, vim, helpers){
+  eq(zVals[1], zVals[4]);
+});
+testVim('zt==z<CR>', function(cm, vim, helpers){
+  eq(zVals[2], zVals[5]);
+});
+
+var moveTillCharacterSandbox =
+  'The quick brown fox \n'
+  'jumped over the lazy dog.'
+testVim('moveTillCharacter', function(cm, vim, helpers){
+  cm.setCursor(0, 0);
+  // Search for the 'q'.
+  cm.openDialog = helpers.fakeOpenDialog('q');
+  helpers.doKeys('/');
+  eq(4, cm.getCursor().ch);
+  // Jump to just before the first o in the list.
+  helpers.doKeys('t');
+  helpers.doKeys('o');
+  eq('The quick brown fox \n', cm.getValue());
+  // Delete that one character.
+  helpers.doKeys('d');
+  helpers.doKeys('t');
+  helpers.doKeys('o');
+  eq('The quick bown fox \n', cm.getValue());
+  // Delete everything until the next 'o'.
+  helpers.doKeys('.');
+  eq('The quick box \n', cm.getValue());
+  // An unmatched character should have no effect.
+  helpers.doKeys('d');
+  helpers.doKeys('t');
+  helpers.doKeys('q');
+  eq('The quick box \n', cm.getValue());
+  // Matches should only be possible on single lines.
+  helpers.doKeys('d');
+  helpers.doKeys('t');
+  helpers.doKeys('z');
+  eq('The quick box \n', cm.getValue());
+  // After all that, the search for 'q' should still be active, so the 'N' command
+  // can run it again in reverse. Use that to delete everything back to the 'q'.
+  helpers.doKeys('d');
+  helpers.doKeys('N');
+  eq('The ox \n', cm.getValue());
+  eq(4, cm.getCursor().ch);
+}, { value: moveTillCharacterSandbox});
+testVim('searchForPipe', function(cm, vim, helpers){
+  CodeMirror.Vim.setOption('pcre', false);
+  cm.setCursor(0, 0);
+  // Search for the '|'.
+  cm.openDialog = helpers.fakeOpenDialog('|');
+  helpers.doKeys('/');
+  eq(4, cm.getCursor().ch);
+}, { value: 'this|that'});
+
+
+var scrollMotionSandbox =
+  '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n'
+  '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n'
+  '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n'
+  '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n';
+testVim('scrollMotion', function(cm, vim, helpers){
+  var prevCursor, prevScrollInfo;
+  cm.setCursor(0, 0);
+  // ctrl-y at the top of the file should have no effect.
+  helpers.doKeys('<C-y>');
+  eq(0, cm.getCursor().line);
+  prevScrollInfo = cm.getScrollInfo();
+  helpers.doKeys('<C-e>');
+  eq(1, cm.getCursor().line);
+  is(prevScrollInfo.top < cm.getScrollInfo().top);
+  // Jump to the end of the sandbox.
+  cm.setCursor(1000, 0);
+  prevCursor = cm.getCursor();
+  // ctrl-e at the bottom of the file should have no effect.
+  helpers.doKeys('<C-e>');
+  eq(prevCursor.line, cm.getCursor().line);
+  prevScrollInfo = cm.getScrollInfo();
+  helpers.doKeys('<C-y>');
+  eq(prevCursor.line - 1, cm.getCursor().line);
+  is(prevScrollInfo.top > cm.getScrollInfo().top);
+}, { value: scrollMotionSandbox});
+
+var squareBracketMotionSandbox = ''+
+  '({\n'+//0
+  '  ({\n'+//11
+  '  /*comment {\n'+//2
+  '            */(\n'+//3
+  '#else                \n'+//4
+  '  /*       )\n'+//5
+  '#if        }\n'+//6
+  '  )}*/\n'+//7
+  ')}\n'+//8
+  '{}\n'+//9
+  '#else {{\n'+//10
+  '{}\n'+//11
+  '}\n'+//12
+  '{\n'+//13
+  '#endif\n'+//14
+  '}\n'+//15
+  '}\n'+//16
+  '#else';//17
+testVim('[[, ]]', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys(']', ']');
+  helpers.assertCursorAt(9,0);
+  helpers.doKeys('2', ']', ']');
+  helpers.assertCursorAt(13,0);
+  helpers.doKeys(']', ']');
+  helpers.assertCursorAt(17,0);
+  helpers.doKeys('[', '[');
+  helpers.assertCursorAt(13,0);
+  helpers.doKeys('2', '[', '[');
+  helpers.assertCursorAt(9,0);
+  helpers.doKeys('[', '[');
+  helpers.assertCursorAt(0,0);
+}, { value: squareBracketMotionSandbox});
+testVim('[], ][', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doKeys(']', '[');
+  helpers.assertCursorAt(12,0);
+  helpers.doKeys('2', ']', '[');
+  helpers.assertCursorAt(16,0);
+  helpers.doKeys(']', '[');
+  helpers.assertCursorAt(17,0);
+  helpers.doKeys('[', ']');
+  helpers.assertCursorAt(16,0);
+  helpers.doKeys('2', '[', ']');
+  helpers.assertCursorAt(12,0);
+  helpers.doKeys('[', ']');
+  helpers.assertCursorAt(0,0);
+}, { value: squareBracketMotionSandbox});
+testVim('[{, ]}', function(cm, vim, helpers) {
+  cm.setCursor(4, 10);
+  helpers.doKeys('[', '{');
+  helpers.assertCursorAt(2,12);
+  helpers.doKeys('2', '[', '{');
+  helpers.assertCursorAt(0,1);
+  cm.setCursor(4, 10);
+  helpers.doKeys(']', '}');
+  helpers.assertCursorAt(6,11);
+  helpers.doKeys('2', ']', '}');
+  helpers.assertCursorAt(8,1);
+  cm.setCursor(0,1);
+  helpers.doKeys(']', '}');
+  helpers.assertCursorAt(8,1);
+  helpers.doKeys('[', '{');
+  helpers.assertCursorAt(0,1);
+}, { value: squareBracketMotionSandbox});
+testVim('[(, ])', function(cm, vim, helpers) {
+  cm.setCursor(4, 10);
+  helpers.doKeys('[', '(');
+  helpers.assertCursorAt(3,14);
+  helpers.doKeys('2', '[', '(');
+  helpers.assertCursorAt(0,0);
+  cm.setCursor(4, 10);
+  helpers.doKeys(']', ')');
+  helpers.assertCursorAt(5,11);
+  helpers.doKeys('2', ']', ')');
+  helpers.assertCursorAt(8,0);
+  helpers.doKeys('[', '(');
+  helpers.assertCursorAt(0,0);
+  helpers.doKeys(']', ')');
+  helpers.assertCursorAt(8,0);
+}, { value: squareBracketMotionSandbox});
+testVim('[*, ]*, [/, ]/', function(cm, vim, helpers) {
+  forEach(['*', '/'], function(key){
+    cm.setCursor(7, 0);
+    helpers.doKeys('2', '[', key);
+    helpers.assertCursorAt(2,2);
+    helpers.doKeys('2', ']', key);
+    helpers.assertCursorAt(7,5);
+  });
+}, { value: squareBracketMotionSandbox});
+testVim('[#, ]#', function(cm, vim, helpers) {
+  cm.setCursor(10, 3);
+  helpers.doKeys('2', '[', '#');
+  helpers.assertCursorAt(4,0);
+  helpers.doKeys('5', ']', '#');
+  helpers.assertCursorAt(17,0);
+  cm.setCursor(10, 3);
+  helpers.doKeys(']', '#');
+  helpers.assertCursorAt(14,0);
+}, { value: squareBracketMotionSandbox});
+testVim('[m, ]m, [M, ]M', function(cm, vim, helpers) {
+  cm.setCursor(11, 0);
+  helpers.doKeys('[', 'm');
+  helpers.assertCursorAt(10,7);
+  helpers.doKeys('4', '[', 'm');
+  helpers.assertCursorAt(1,3);
+  helpers.doKeys('5', ']', 'm');
+  helpers.assertCursorAt(11,0);
+  helpers.doKeys('[', 'M');
+  helpers.assertCursorAt(9,1);
+  helpers.doKeys('3', ']', 'M');
+  helpers.assertCursorAt(15,0);
+  helpers.doKeys('5', '[', 'M');
+  helpers.assertCursorAt(7,3);
+}, { value: squareBracketMotionSandbox});
+
+// Ex mode tests
+testVim('ex_go_to_line', function(cm, vim, helpers) {
+  cm.setCursor(0, 0);
+  helpers.doEx('4');
+  helpers.assertCursorAt(3, 0);
+}, { value: 'a\nb\nc\nd\ne\n'});
+testVim('ex_write', function(cm, vim, helpers) {
+  var tmp = CodeMirror.commands.save;
+  var written;
+  var actualCm;
+  CodeMirror.commands.save = function(cm) {
+    written = true;
+    actualCm = cm;
+  };
+  // Test that w, wr, wri ... write all trigger :write.
+  var command = 'write';
+  for (var i = 1; i < command.length; i++) {
+    written = false;
+    actualCm = null;
+    helpers.doEx(command.substring(0, i));
+    eq(written, true);
+    eq(actualCm, cm);
+  }
+  CodeMirror.commands.save = tmp;
+});
+testVim('ex_sort', function(cm, vim, helpers) {
+  helpers.doEx('sort');
+  eq('Z\na\nb\nc\nd', cm.getValue());
+}, { value: 'b\nZ\nd\nc\na'});
+testVim('ex_sort_reverse', function(cm, vim, helpers) {
+  helpers.doEx('sort!');
+  eq('d\nc\nb\na', cm.getValue());
+}, { value: 'b\nd\nc\na'});
+testVim('ex_sort_range', function(cm, vim, helpers) {
+  helpers.doEx('2,3sort');
+  eq('b\nc\nd\na', cm.getValue());
+}, { value: 'b\nd\nc\na'});
+testVim('ex_sort_oneline', function(cm, vim, helpers) {
+  helpers.doEx('2sort');
+  // Expect no change.
+  eq('b\nd\nc\na', cm.getValue());
+}, { value: 'b\nd\nc\na'});
+testVim('ex_sort_ignoreCase', function(cm, vim, helpers) {
+  helpers.doEx('sort i');
+  eq('a\nb\nc\nd\nZ', cm.getValue());
+}, { value: 'b\nZ\nd\nc\na'});
+testVim('ex_sort_unique', function(cm, vim, helpers) {
+  helpers.doEx('sort u');
+  eq('Z\na\nb\nc\nd', cm.getValue());
+}, { value: 'b\nZ\na\na\nd\na\nc\na'});
+testVim('ex_sort_decimal', function(cm, vim, helpers) {
+  helpers.doEx('sort d');
+  eq('d3\n s5\n6\n.9', cm.getValue());
+}, { value: '6\nd3\n s5\n.9'});
+testVim('ex_sort_decimal_negative', function(cm, vim, helpers) {
+  helpers.doEx('sort d');
+  eq('z-9\nd3\n s5\n6\n.9', cm.getValue());
+}, { value: '6\nd3\n s5\n.9\nz-9'});
+testVim('ex_sort_decimal_reverse', function(cm, vim, helpers) {
+  helpers.doEx('sort! d');
+  eq('.9\n6\n s5\nd3', cm.getValue());
+}, { value: '6\nd3\n s5\n.9'});
+testVim('ex_sort_hex', function(cm, vim, helpers) {
+  helpers.doEx('sort x');
+  eq(' s5\n6\n.9\n&0xB\nd3', cm.getValue());
+}, { value: '6\nd3\n s5\n&0xB\n.9'});
+testVim('ex_sort_octal', function(cm, vim, helpers) {
+  helpers.doEx('sort o');
+  eq('.8\n.9\nd3\n s5\n6', cm.getValue());
+}, { value: '6\nd3\n s5\n.9\n.8'});
+testVim('ex_sort_decimal_mixed', function(cm, vim, helpers) {
+  helpers.doEx('sort d');
+  eq('y\nz\nc1\nb2\na3', cm.getValue());
+}, { value: 'a3\nz\nc1\ny\nb2'});
+testVim('ex_sort_decimal_mixed_reverse', function(cm, vim, helpers) {
+  helpers.doEx('sort! d');
+  eq('a3\nb2\nc1\nz\ny', cm.getValue());
+}, { value: 'a3\nz\nc1\ny\nb2'});
+
+// Basic substitute tests.
+testVim('ex_substitute_same_line', function(cm, vim, helpers) {
+  cm.setCursor(1, 0);
+  helpers.doEx('s/one/two');
+  eq('one one\n two two', cm.getValue());
+}, { value: 'one one\n one one'});
+testVim('ex_substitute_global', function(cm, vim, helpers) {
+  cm.setCursor(1, 0);
+  helpers.doEx('%s/one/two');
+  eq('two two\n two two', cm.getValue());
+}, { value: 'one one\n one one'});
+testVim('ex_substitute_input_range', function(cm, vim, helpers) {
+  cm.setCursor(1, 0);
+  helpers.doEx('1,3s/\\d/0');
+  eq('0\n0\n0\n4', cm.getValue());
+}, { value: '1\n2\n3\n4' });
+testVim('ex_substitute_visual_range', function(cm, vim, helpers) {
+  cm.setCursor(1, 0);
+  // Set last visual mode selection marks '< and '> at lines 2 and 4
+  helpers.doKeys('V', '2', 'j', 'v');
+  helpers.doEx('\'<,\'>s/\\d/0');
+  eq('1\n0\n0\n0\n5', cm.getValue());
+}, { value: '1\n2\n3\n4\n5' });
+testVim('ex_substitute_empty_query', function(cm, vim, helpers) {
+  // If the query is empty, use last query.
+  cm.setCursor(1, 0);
+  cm.openDialog = helpers.fakeOpenDialog('1');
+  helpers.doKeys('/');
+  helpers.doEx('s//b');
+  eq('abb ab2 ab3', cm.getValue());
+}, { value: 'a11 a12 a13' });
+testVim('ex_substitute_javascript', function(cm, vim, helpers) {
+  CodeMirror.Vim.setOption('pcre', false);
+  cm.setCursor(1, 0);
+  // Throw all the things that javascript likes to treat as special values
+  // into the replace part. All should be literal (this is VIM).
+  helpers.doEx('s/\\(\\d+\\)/$$ $\' $` $& \\1/')
+  eq('a $$ $\' $` $& 0 b', cm.getValue());
+}, { value: 'a 0 b' });
+
+// More complex substitute tests that test both pcre and nopcre options.
+function testSubstitute(name, options) {
+  testVim(name + '_pcre', function(cm, vim, helpers) {
+    cm.setCursor(1, 0);
+    CodeMirror.Vim.setOption('pcre', true);
+    helpers.doEx(options.expr);
+    eq(options.expectedValue, cm.getValue());
+  }, options);
+  // If no noPcreExpr is defined, assume that it's the same as the expr.
+  var noPcreExpr = options.noPcreExpr ? options.noPcreExpr : options.expr;
+  testVim(name + '_nopcre', function(cm, vim, helpers) {
+    cm.setCursor(1, 0);
+    CodeMirror.Vim.setOption('pcre', false);
+    helpers.doEx(noPcreExpr);
+    eq(options.expectedValue, cm.getValue());
+  }, options);
+}
+testSubstitute('ex_substitute_capture', {
+  value: 'a11 a12 a13',
+  expectedValue: 'a1111 a1212 a1313',
+  // $n is a backreference
+  expr: 's/(\\d+)/$1$1/',
+  // \n is a backreference.
+  noPcreExpr: 's/\\(\\d+\\)/\\1\\1/'});
+testSubstitute('ex_substitute_capture2', {
+  value: 'a 0 b',
+  expectedValue: 'a $00 b',
+  expr: 's/(\\d+)/$$$1$1/',
+  noPcreExpr: 's/\\(\\d+\\)/$\\1\\1/'});
+testSubstitute('ex_substitute_nocapture', {
+  value: 'a11 a12 a13',
+  expectedValue: 'a$1$1 a$1$1 a$1$1',
+  expr: 's/(\\d+)/$$1$$1',
+  noPcreExpr: 's/\\(\\d+\\)/$1$1/'});
+testSubstitute('ex_substitute_nocapture2', {
+  value: 'a 0 b',
+  expectedValue: 'a $10 b',
+  expr: 's/(\\d+)/$$1$1',
+  noPcreExpr: 's/\\(\\d+\\)/\\$1\\1/'});
+testSubstitute('ex_substitute_nocapture', {
+  value: 'a b c',
+  expectedValue: 'a $ c',
+  expr: 's/b/$$/',
+  noPcreExpr: 's/b/$/'});
+testSubstitute('ex_substitute_slash_regex', {
+  value: 'one/two \n three/four',
+  expectedValue: 'one|two \n three|four',
+  expr: '%s/\\//|'});
+testSubstitute('ex_substitute_pipe_regex', {
+  value: 'one|two \n three|four',
+  expectedValue: 'one,two \n three,four',
+  expr: '%s/\\|/,/',
+  noPcreExpr: '%s/|/,/'});
+testSubstitute('ex_substitute_or_regex', {
+  value: 'one|two \n three|four',
+  expectedValue: 'ana|twa \n thraa|faar',
+  expr: '%s/o|e|u/a',
+  noPcreExpr: '%s/o\\|e\\|u/a'});
+testSubstitute('ex_substitute_or_word_regex', {
+  value: 'one|two \n three|four',
+  expectedValue: 'five|five \n three|four',
+  expr: '%s/(one|two)/five/',
+  noPcreExpr: '%s/\\(one\\|two\\)/five'});
+testSubstitute('ex_substitute_backslashslash_regex', {
+  value: 'one\\two \n three\\four',
+  expectedValue: 'one,two \n three,four',
+  expr: '%s/\\\\/,'});
+testSubstitute('ex_substitute_slash_replacement', {
+  value: 'one,two \n three,four',
+  expectedValue: 'one/two \n three/four',
+  expr: '%s/,/\\/'});
+testSubstitute('ex_substitute_backslash_replacement', {
+  value: 'one,two \n three,four',
+  expectedValue: 'one\\two \n three\\four',
+  expr: '%s/,/\\\\/g'});
+testSubstitute('ex_substitute_multibackslash_replacement', {
+  value: 'one,two \n three,four',
+  expectedValue: 'one\\\\\\\\two \n three\\\\\\\\four', // 2*8 backslashes.
+  expr: '%s/,/\\\\\\\\\\\\\\\\/g'}); // 16 backslashes.
+testSubstitute('ex_substitute_braces_word', {
+  value: 'ababab abb ab{2}',
+  expectedValue: 'ab abb ab{2}',
+  expr: '%s/(ab){2}//g',
+  noPcreExpr: '%s/\\(ab\\)\\{2\\}//g'});
+testSubstitute('ex_substitute_braces_range', {
+  value: 'a aa aaa aaaa',
+  expectedValue: 'a   a',
+  expr: '%s/a{2,3}//g',
+  noPcreExpr: '%s/a\\{2,3\\}//g'});
+testSubstitute('ex_substitute_braces_literal', {
+  value: 'ababab abb ab{2}',
+  expectedValue: 'ababab abb ',
+  expr: '%s/ab\\{2\\}//g',
+  noPcreExpr: '%s/ab{2}//g'});
+testSubstitute('ex_substitute_braces_char', {
+  value: 'ababab abb ab{2}',
+  expectedValue: 'ababab  ab{2}',
+  expr: '%s/ab{2}//g',
+  noPcreExpr: '%s/ab\\{2\\}//g'});
+testSubstitute('ex_substitute_braces_no_escape', {
+  value: 'ababab abb ab{2}',
+  expectedValue: 'ababab  ab{2}',
+  expr: '%s/ab{2}//g',
+  noPcreExpr: '%s/ab\\{2}//g'});
+testSubstitute('ex_substitute_count', {
+  value: '1\n2\n3\n4',
+  expectedValue: '1\n0\n0\n4',
+  expr: 's/\\d/0/i 2'});
+testSubstitute('ex_substitute_count_with_range', {
+  value: '1\n2\n3\n4',
+  expectedValue: '1\n2\n0\n0',
+  expr: '1,3s/\\d/0/ 3'});
+function testSubstituteConfirm(name, command, initialValue, expectedValue, keys, finalPos) {
+  testVim(name, function(cm, vim, helpers) {
+    var savedOpenDialog = cm.openDialog;
+    var savedKeyName = CodeMirror.keyName;
+    var onKeyDown;
+    var recordedCallback;
+    var closed = true; // Start out closed, set false on second openDialog.
+    function close() {
+      closed = true;
+    }
+    // First openDialog should save callback.
+    cm.openDialog = function(template, callback, options) {
+      recordedCallback = callback;
+    }
+    // Do first openDialog.
+    helpers.doKeys(':');
+    // Second openDialog should save keyDown handler.
+    cm.openDialog = function(template, callback, options) {
+      onKeyDown = options.onKeyDown;
+      closed = false;
+    };
+    // Return the command to Vim and trigger second openDialog.
+    recordedCallback(command);
+    // The event should really use keyCode, but here just mock it out and use
+    // key and replace keyName to just return key.
+    CodeMirror.keyName = function (e) { return e.key; }
+    keys = keys.toUpperCase();
+    for (var i = 0; i < keys.length; i++) {
+      is(!closed);
+      onKeyDown({ key: keys.charAt(i) }, '', close);
+    }
+    try {
+      eq(expectedValue, cm.getValue());
+      helpers.assertCursorAt(finalPos);
+      is(closed);
+    } catch(e) {
+      throw e
+    } finally {
+      // Restore overriden functions.
+      CodeMirror.keyName = savedKeyName;
+      cm.openDialog = savedOpenDialog;
+    }
+  }, { value: initialValue });
+};
+testSubstituteConfirm('ex_substitute_confirm_emptydoc',
+    '%s/x/b/c', '', '', '', makeCursor(0, 0));
+testSubstituteConfirm('ex_substitute_confirm_nomatch',
+    '%s/x/b/c', 'ba a\nbab', 'ba a\nbab', '', makeCursor(0, 0));
+testSubstituteConfirm('ex_substitute_confirm_accept',
+    '%s/a/b/c', 'ba a\nbab', 'bb b\nbbb', 'yyy', makeCursor(1, 1));
+testSubstituteConfirm('ex_substitute_confirm_random_keys',
+    '%s/a/b/c', 'ba a\nbab', 'bb b\nbbb', 'ysdkywerty', makeCursor(1, 1));
+testSubstituteConfirm('ex_substitute_confirm_some',
+    '%s/a/b/c', 'ba a\nbab', 'bb a\nbbb', 'yny', makeCursor(1, 1));
+testSubstituteConfirm('ex_substitute_confirm_all',
+    '%s/a/b/c', 'ba a\nbab', 'bb b\nbbb', 'a', makeCursor(1, 1));
+testSubstituteConfirm('ex_substitute_confirm_accept_then_all',
+    '%s/a/b/c', 'ba a\nbab', 'bb b\nbbb', 'ya', makeCursor(1, 1));
+testSubstituteConfirm('ex_substitute_confirm_quit',
+    '%s/a/b/c', 'ba a\nbab', 'bb a\nbab', 'yq', makeCursor(0, 3));
+testSubstituteConfirm('ex_substitute_confirm_last',
+    '%s/a/b/c', 'ba a\nbab', 'bb b\nbab', 'yl', makeCursor(0, 3));
+testSubstituteConfirm('ex_substitute_confirm_oneline',
+    '1s/a/b/c', 'ba a\nbab', 'bb b\nbab', 'yl', makeCursor(0, 3));
+testSubstituteConfirm('ex_substitute_confirm_range_accept',
+    '1,2s/a/b/c', 'aa\na \na\na', 'bb\nb \na\na', 'yyy', makeCursor(1, 0));
+testSubstituteConfirm('ex_substitute_confirm_range_some',
+    '1,3s/a/b/c', 'aa\na \na\na', 'ba\nb \nb\na', 'ynyy', makeCursor(2, 0));
+testSubstituteConfirm('ex_substitute_confirm_range_all',
+    '1,3s/a/b/c', 'aa\na \na\na', 'bb\nb \nb\na', 'a', makeCursor(2, 0));
+testSubstituteConfirm('ex_substitute_confirm_range_last',
+    '1,3s/a/b/c', 'aa\na \na\na', 'bb\nb \na\na', 'yyl', makeCursor(1, 0));
+//:noh should clear highlighting of search-results but allow to resume search through n
+testVim('ex_noh_clearSearchHighlight', function(cm, vim, helpers) {
+  cm.openDialog = helpers.fakeOpenDialog('match');
+  helpers.doKeys('?');
+  helpers.doEx('noh');
+  eq(vim.searchState_.getOverlay(),null,'match-highlighting wasn\'t cleared');
+  helpers.doKeys('n');
+  helpers.assertCursorAt(0, 11,'can\'t resume search after clearing highlighting');
+}, { value: 'match nope match \n nope Match' });
+testVim('set_boolean', function(cm, vim, helpers) {
+  CodeMirror.Vim.defineOption('testoption', true, 'boolean');
+  // Test default value is set.
+  is(CodeMirror.Vim.getOption('testoption'));
+  try {
+    // Test fail to set to non-boolean
+    CodeMirror.Vim.setOption('testoption', '5');
+    fail();
+  } catch (expected) {};
+  // Test setOption
+  CodeMirror.Vim.setOption('testoption', false);
+  is(!CodeMirror.Vim.getOption('testoption'));
+});
+testVim('ex_set_boolean', function(cm, vim, helpers) {
+  CodeMirror.Vim.defineOption('testoption', true, 'boolean');
+  // Test default value is set.
+  is(CodeMirror.Vim.getOption('testoption'));
+  try {
+    // Test fail to set to non-boolean
+    helpers.doEx('set testoption=22');
+    fail();
+  } catch (expected) {};
+  // Test setOption
+  helpers.doEx('set notestoption');
+  is(!CodeMirror.Vim.getOption('testoption'));
+});
+testVim('set_string', function(cm, vim, helpers) {
+  CodeMirror.Vim.defineOption('testoption', 'a', 'string');
+  // Test default value is set.
+  eq('a', CodeMirror.Vim.getOption('testoption'));
+  try {
+    // Test fail to set non-string.
+    CodeMirror.Vim.setOption('testoption', true);
+    fail();
+  } catch (expected) {};
+  try {
+    // Test fail to set 'notestoption'
+    CodeMirror.Vim.setOption('notestoption', 'b');
+    fail();
+  } catch (expected) {};
+  // Test setOption
+  CodeMirror.Vim.setOption('testoption', 'c');
+  eq('c', CodeMirror.Vim.getOption('testoption'));
+});
+testVim('ex_set_string', function(cm, vim, helpers) {
+  CodeMirror.Vim.defineOption('testoption', 'a', 'string');
+  // Test default value is set.
+  eq('a', CodeMirror.Vim.getOption('testoption'));
+  try {
+    // Test fail to set 'notestoption'
+    helpers.doEx('set notestoption=b');
+    fail();
+  } catch (expected) {};
+  // Test setOption
+  helpers.doEx('set testoption=c')
+  eq('c', CodeMirror.Vim.getOption('testoption'));
+});
+// TODO: Reset key maps after each test.
+testVim('ex_map_key2key', function(cm, vim, helpers) {
+  helpers.doEx('map a x');
+  helpers.doKeys('a');
+  helpers.assertCursorAt(0, 0);
+  eq('bc', cm.getValue());
+}, { value: 'abc' });
+testVim('ex_unmap_key2key', function(cm, vim, helpers) {
+  helpers.doEx('unmap a');
+  helpers.doKeys('a');
+  eq('vim-insert', cm.getOption('keyMap'));
+}, { value: 'abc' });
+testVim('ex_unmap_key2key_does_not_remove_default', function(cm, vim, helpers) {
+  try {
+    helpers.doEx('unmap a');
+    fail();
+  } catch (expected) {}
+  helpers.doKeys('a');
+  eq('vim-insert', cm.getOption('keyMap'));
+}, { value: 'abc' });
+testVim('ex_map_key2key_to_colon', function(cm, vim, helpers) {
+  helpers.doEx('map ; :');
+  var dialogOpened = false;
+  cm.openDialog = function() {
+    dialogOpened = true;
+  }
+  helpers.doKeys(';');
+  eq(dialogOpened, true);
+});
+testVim('ex_map_ex2key:', function(cm, vim, helpers) {
+  helpers.doEx('map :del x');
+  helpers.doEx('del');
+  helpers.assertCursorAt(0, 0);
+  eq('bc', cm.getValue());
+}, { value: 'abc' });
+testVim('ex_map_ex2ex', function(cm, vim, helpers) {
+  helpers.doEx('map :del :w');
+  var tmp = CodeMirror.commands.save;
+  var written = false;
+  var actualCm;
+  CodeMirror.commands.save = function(cm) {
+    written = true;
+    actualCm = cm;
+  };
+  helpers.doEx('del');
+  CodeMirror.commands.save = tmp;
+  eq(written, true);
+  eq(actualCm, cm);
+});
+testVim('ex_map_key2ex', function(cm, vim, helpers) {
+  helpers.doEx('map a :w');
+  var tmp = CodeMirror.commands.save;
+  var written = false;
+  var actualCm;
+  CodeMirror.commands.save = function(cm) {
+    written = true;
+    actualCm = cm;
+  };
+  helpers.doKeys('a');
+  CodeMirror.commands.save = tmp;
+  eq(written, true);
+  eq(actualCm, cm);
+});
+testVim('ex_map_key2key_visual_api', function(cm, vim, helpers) {
+  CodeMirror.Vim.map('b', ':w', 'visual');
+  var tmp = CodeMirror.commands.save;
+  var written = false;
+  var actualCm;
+  CodeMirror.commands.save = function(cm) {
+    written = true;
+    actualCm = cm;
+  };
+  // Mapping should not work in normal mode.
+  helpers.doKeys('b');
+  eq(written, false);
+  // Mapping should work in visual mode.
+  helpers.doKeys('v', 'b');
+  eq(written, true);
+  eq(actualCm, cm);
+
+  CodeMirror.commands.save = tmp;
+});
+
+// Testing registration of functions as ex-commands and mapping to <Key>-keys
+testVim('ex_api_test', function(cm, vim, helpers) {
+  var res=false;
+  var val='from';
+  CodeMirror.Vim.defineEx('extest','ext',function(cm,params){
+    if(params.args)val=params.args[0];
+    else res=true;
+  });
+  helpers.doEx(':ext to');
+  eq(val,'to','Defining ex-command failed');
+  CodeMirror.Vim.map('<C-CR><Space>',':ext');
+  helpers.doKeys('<C-CR>','<Space>');
+  is(res,'Mapping to key failed');
+});
+// For now, this test needs to be last because it messes up : for future tests.
+testVim('ex_map_key2key_from_colon', function(cm, vim, helpers) {
+  helpers.doEx('map : x');
+  helpers.doKeys(':');
+  helpers.assertCursorAt(0, 0);
+  eq('bc', cm.getValue());
+}, { value: 'abc' });
+
+// Test event handlers
+testVim('beforeSelectionChange', function(cm, vim, helpers) {
+  cm.setCursor(0, 100);
+  eqPos(cm.getCursor('head'), cm.getCursor('anchor'));
+}, { value: 'abc' });
diff --git a/app/gui/html/vendor/codemirror/theme/3024-day.css b/app/gui/html/vendor/codemirror/theme/3024-day.css
new file mode 100644
index 0000000..cbb9a4f
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/3024-day.css
@@ -0,0 +1,34 @@
+/*
+
+    Name:       3024 day
+    Author:     Jan T. Sott (http://github.com/idleberg)
+
+    CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+    Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-3024-day.CodeMirror {background: #f7f7f7; color: #3a3432;}
+.cm-s-3024-day div.CodeMirror-selected {background: #d6d5d4 !important;}
+.cm-s-3024-day .CodeMirror-gutters {background: #f7f7f7; border-right: 0px;}
+.cm-s-3024-day .CodeMirror-linenumber {color: #807d7c;}
+.cm-s-3024-day .CodeMirror-cursor {border-left: 1px solid #5c5855 !important;}
+
+.cm-s-3024-day span.cm-comment {color: #cdab53;}
+.cm-s-3024-day span.cm-atom {color: #a16a94;}
+.cm-s-3024-day span.cm-number {color: #a16a94;}
+
+.cm-s-3024-day span.cm-property, .cm-s-3024-day span.cm-attribute {color: #01a252;}
+.cm-s-3024-day span.cm-keyword {color: #db2d20;}
+.cm-s-3024-day span.cm-string {color: #fded02;}
+
+.cm-s-3024-day span.cm-variable {color: #01a252;}
+.cm-s-3024-day span.cm-variable-2 {color: #01a0e4;}
+.cm-s-3024-day span.cm-def {color: #e8bbd0;}
+.cm-s-3024-day span.cm-bracket {color: #3a3432;}
+.cm-s-3024-day span.cm-tag {color: #db2d20;}
+.cm-s-3024-day span.cm-link {color: #a16a94;}
+.cm-s-3024-day span.cm-error {background: #db2d20; color: #5c5855;}
+
+.cm-s-3024-day .CodeMirror-activeline-background {background: #e8f2ff !important;}
+.cm-s-3024-day .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/3024-night.css b/app/gui/html/vendor/codemirror/theme/3024-night.css
new file mode 100644
index 0000000..2c62e22
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/3024-night.css
@@ -0,0 +1,34 @@
+/*
+
+    Name:       3024 night
+    Author:     Jan T. Sott (http://github.com/idleberg)
+
+    CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+    Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-3024-night.CodeMirror {background: #090300; color: #d6d5d4;}
+.cm-s-3024-night div.CodeMirror-selected {background: #3a3432 !important;}
+.cm-s-3024-night .CodeMirror-gutters {background: #090300; border-right: 0px;}
+.cm-s-3024-night .CodeMirror-linenumber {color: #5c5855;}
+.cm-s-3024-night .CodeMirror-cursor {border-left: 1px solid #807d7c !important;}
+
+.cm-s-3024-night span.cm-comment {color: #cdab53;}
+.cm-s-3024-night span.cm-atom {color: #a16a94;}
+.cm-s-3024-night span.cm-number {color: #a16a94;}
+
+.cm-s-3024-night span.cm-property, .cm-s-3024-night span.cm-attribute {color: #01a252;}
+.cm-s-3024-night span.cm-keyword {color: #db2d20;}
+.cm-s-3024-night span.cm-string {color: #fded02;}
+
+.cm-s-3024-night span.cm-variable {color: #01a252;}
+.cm-s-3024-night span.cm-variable-2 {color: #01a0e4;}
+.cm-s-3024-night span.cm-def {color: #e8bbd0;}
+.cm-s-3024-night span.cm-bracket {color: #d6d5d4;}
+.cm-s-3024-night span.cm-tag {color: #db2d20;}
+.cm-s-3024-night span.cm-link {color: #a16a94;}
+.cm-s-3024-night span.cm-error {background: #db2d20; color: #807d7c;}
+
+.cm-s-3024-night .CodeMirror-activeline-background {background: #2F2F2F !important;}
+.cm-s-3024-night .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/ambiance-mobile.css b/app/gui/html/vendor/codemirror/theme/ambiance-mobile.css
new file mode 100644
index 0000000..88d332e
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/ambiance-mobile.css
@@ -0,0 +1,5 @@
+.cm-s-ambiance.CodeMirror {
+  -webkit-box-shadow: none;
+  -moz-box-shadow: none;
+  box-shadow: none;
+}
diff --git a/app/gui/html/vendor/codemirror/theme/ambiance.css b/app/gui/html/vendor/codemirror/theme/ambiance.css
new file mode 100644
index 0000000..3a54b2a
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/ambiance.css
@@ -0,0 +1,75 @@
+/* ambiance theme for codemirror */
+
+/* Color scheme */
+
+.cm-s-ambiance .cm-keyword { color: #cda869; }
+.cm-s-ambiance .cm-atom { color: #CF7EA9; }
+.cm-s-ambiance .cm-number { color: #78CF8A; }
+.cm-s-ambiance .cm-def { color: #aac6e3; }
+.cm-s-ambiance .cm-variable { color: #ffb795; }
+.cm-s-ambiance .cm-variable-2 { color: #eed1b3; }
+.cm-s-ambiance .cm-variable-3 { color: #faded3; }
+.cm-s-ambiance .cm-property { color: #eed1b3; }
+.cm-s-ambiance .cm-operator {color: #fa8d6a;}
+.cm-s-ambiance .cm-comment { color: #555; font-style:italic; }
+.cm-s-ambiance .cm-string { color: #8f9d6a; }
+.cm-s-ambiance .cm-string-2 { color: #9d937c; }
+.cm-s-ambiance .cm-meta { color: #D2A8A1; }
+.cm-s-ambiance .cm-qualifier { color: yellow; }
+.cm-s-ambiance .cm-builtin { color: #9999cc; }
+.cm-s-ambiance .cm-bracket { color: #24C2C7; }
+.cm-s-ambiance .cm-tag { color: #fee4ff }
+.cm-s-ambiance .cm-attribute {  color: #9B859D; }
+.cm-s-ambiance .cm-header {color: blue;}
+.cm-s-ambiance .cm-quote { color: #24C2C7; }
+.cm-s-ambiance .cm-hr { color: pink; }
+.cm-s-ambiance .cm-link { color: #F4C20B; }
+.cm-s-ambiance .cm-special { color: #FF9D00; }
+.cm-s-ambiance .cm-error { color: #AF2018; }
+
+.cm-s-ambiance .CodeMirror-matchingbracket { color: #0f0; }
+.cm-s-ambiance .CodeMirror-nonmatchingbracket { color: #f22; }
+
+.cm-s-ambiance .CodeMirror-selected {
+  background: rgba(255, 255, 255, 0.15);
+}
+.cm-s-ambiance.CodeMirror-focused .CodeMirror-selected {
+  background: rgba(255, 255, 255, 0.10);
+}
+
+/* Editor styling */
+
+.cm-s-ambiance.CodeMirror {
+  line-height: 1.40em;
+  font-family: Monaco, Menlo,"Andale Mono","lucida console","Courier New",monospace !important;
+  color: #E6E1DC;
+  background-color: #202020;
+  -webkit-box-shadow: inset 0 0 10px black;
+  -moz-box-shadow: inset 0 0 10px black;
+  box-shadow: inset 0 0 10px black;
+}
+
+.cm-s-ambiance .CodeMirror-gutters {
+  background: #3D3D3D;
+  border-right: 1px solid #4D4D4D;
+  box-shadow: 0 10px 20px black;
+}
+
+.cm-s-ambiance .CodeMirror-linenumber {
+  text-shadow: 0px 1px 1px #4d4d4d;
+  color: #222;
+  padding: 0 5px;
+}
+
+.cm-s-ambiance .CodeMirror-lines .CodeMirror-cursor {
+  border-left: 1px solid #7991E8;
+}
+
+.cm-s-ambiance .CodeMirror-activeline-background {
+  background: none repeat scroll 0% 0% rgba(255, 255, 255, 0.031);
+}
+
+.cm-s-ambiance.CodeMirror,
+.cm-s-ambiance .CodeMirror-gutters {
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAQAAAAHUWYVAABFFUlEQVQYGbzBCeDVU/74/6fj9HIcx/FRHx9JCFmzMyGRURhLZIkUsoeRfUjS2FNDtr6WkMhO9sm+S8maJfu+Jcsg+/o/c+Z4z/t97/vezy3z+z8ekGlnYICG/o7gdk+wmSHZ1z4pJItqapjoKXWahm8NmV6eOTbWUOp6/6a/XIg6GQqmenJ2lDHyvCFZ2cBDbmtHA043VFhHwXxClWmeYAdLhV00Bd85go8VmaFCkbVkzlQENzfBDZ5gtN7HwF0KDrTwJ0dypSOzpaKCMwQHKTIreYIxlmhXTzTWkVm+LTynZhiSBT3RZQ7aGfjGEd3qyXQ1FDymqbKxpspERQN2MiRjNZlFFQXfCNFm9nM1zpAsoYjmtRTc5ajwuaXc5xrWskT97RaKzAGe5ARHhVUsDbjKklziiX5WROcJwSNCNI+9w1Jwv4Zb2r7lCMZ4oq5C0EdTx+2GzNuKpJ+iFf38JEWkHJn9DNF7mmBDITrWEg0VWL3pHU20tSZnuqWu+R3BtYa8XxV1HO7GyD32UkOpL/yDloINFTmvtId+nmAjxRw40VMwVKiwrKLE4bK5UOVntYwhOcSSXKrJHKPJedocpGjVz/ZMIbnYUPB10/eKCrs5apqpgVmWzBYWpmtKHecJPjaUuEgRDDaU0oZghCJ6zNMQ5ZhDYx05r5v2muQdM0EILtXUsaKiQX9WMEUotagQzFbUNN6NUPC2nm5pxEWGCjMc3GdJHjSU2kORLK/JGSrkfGEIjncU/CYUnOipoYemwj8tST9NsJmB7TUVXtbUtXATJVZXBMvYeTXJfobgJUPmGMP/yFaWonaa6BcFO3nqcIqCozSZoZoSr1g4zJOzuyGnxTEX3lUEJ7WcZgme8ddaWvWJo2AJR9DZU3CUIbhCSG6ybSwN6qtJVnCU2svDTP2ZInOw2cBTrqtQahtNZn9NcJ4l2NaSmSkkP1noZWnVwkLmdUPOwLZEwy2Z3S3R+4rIG9hcbpPXHFVWcQdZkn2FOta3cKWQnNRC5g1LsJah4GCzSVsKnCOY5OAFRTBekyyryeyilhFKva75r4Mc0aWanGEaThcy31s439KKxTzJYY5WTHPU1FtIHjQU3Oip4xlNzj/lBw23dYZVliQa7WAXf4shetcQfatI+jWRDBPmyNeW6A1P5kdDgyYJlba0BIM8BZu1JfrFwItyjcAMR3K0BWOIrtMEXyhyrlVEx3ui5dUBjmB/Q3CXW85R4mBD0s7B+4q5tKUjOlb9qqmhi5AZ6GFIC5HXtOobdYGlVdMVbNJ8toNTFcHxnoL+muBagcctjWnbNMuR00uI7nQESwg5q2qqrKWIfrNUmeQocY6HuyxJV02wj36w00yhpmUFenv4p6fUkZYqLyuinx2RGOjhCXYyJF84oiU00YMOOhhquNdfbOB7gU88pY4xJO8LVdp6/q2voeB4R04vIdhSE40xZObx1HGGJ/ja0LBthFInKaLPPFzuCaYaoj8JjPME8yoyxo6zlBqkiUZYgq00OYMswbWO5NGmq+xhipxHLRW29ARjNKXO0wRnear8XSg4XFPLKEPUS1GqvyLwiuBUoa7zpZ0l5xxFwWmWZC1H5h5FwU8eQ7K+g8UcVY6TMQreVQT/8uQ8Z+ALIXnSEa2pYZQneE9RZbSBNYXfWYJzW/h/4j4Dp1tYVcFIC5019Vyi4ThPqSFCzjGWaHQTBU8q6vrVwgxP9Lkm840imWKpcLCjYTtrKuwvsKSnrvHCXGkSMk9p6lhckfRpIeis+N2PiszT+mFLspyGleUhDwcLrZqmyeylxwjBcKHEapqkmyangyLZRVOijwOtCY5SsG5zL0OwlCJ4y5KznF3EUNDDrinwiyLZRzOXtlBbK5ITHFGLp8Q0R6ab6mS7enI2cFrxOyHvOCFaT1HThS1krjCwqWeurCkk+willhCC+RSZnRXBiZaC5RXRIZYKp2lyfrHwiKPKR0JDzrdU2EFgpidawlFDR6FgXUMNa+g1FY3bUQh2cLCwosRdnuQTS/S+JVrGLeWIvtQUvONJxlqSQYYKpwoN2kaocLjdVsis4Mk80ESF2YpSkzwldjHkjFCUutI/r+EHDU8oCs6yzL3PhWiEooZdFMkymlas4AcI3KmoMMNSQ3tHzjGWCrcJJdYyZC7QFGwjRL9p+MrRkAGWzIaWCn9W0F3TsK01c2ZvQw0byvxuQU0r1lM0qJO7wW0kRIMdDTtXEdzi4VIh+EoIHm0mWtAtpCixlabgn83fKTI7anJe9ST7WIK1DMGpQmYeA58ImV6ezOGOzK2Kgq01pd60cKWiUi9Lievb/0vIDPHQ05Kzt4ddPckQBQtoaurjyHnek/nKzpQLrVgKPjIkh2v4uyezpv+Xoo7fPFXaGFp1vaLKxQ4uUpQQS5VuQs7BCq4xRJv7fwpVvvFEB3j+620haOuocqMhWd6TTPAEx+mdFNGHdranFe95WrWmIvlY4F1Dle2ECgc6cto7SryuqGGGha0tFQ5V53migUKmg6XKAo4qS3mik+0OZpAhOLeZKicacgaYcyx5hypYQE02ZA4xi/pNhOQxR4klNKyqacj+mpxnLTnnGSo85++3ZCZq6lrZkXlGEX3o+C9FieccJbZWVFjC0Yo1FZnJhoYMFoI1hEZ9r6hwg75HwzBNhbZCdJEfJwTPGzJvaKImw1yYX1HDAmpXR+ZJQ/SmgqMNVQb5vgamGwLtt7VwvP7Qk1xpiM5x5Cyv93E06MZmgs0Nya2azIKOYKCGBQQW97RmhKNKF02JZqHEJ4o58qp7X5EcZmc56trXEqzjCBZ1MFGR87Ql2tSTs6CGxS05PTzRQorkbw7aKoKXFDXsYW42VJih/q+FP2BdTzDTwVqOYB13liM50vG7wy28qagyuIXMeQI/Oqq8bcn5wJI50xH00CRntyfpL1T4hydYpoXgNiFzoIUTDZnLNRzh4TBHwbYGDvZkxmlyJloyr6tRihpeUG94GnKtIznREF0tzJG/OOr73JBcrSh1k6WuTprgLU+mnSGnv6Zge0NNz+kTDdH8nuAuTdJDCNb21LCiIuqlYbqGzT3RAoZofQfjFazkqeNWdYaGvYTM001EW2oKPvVk1ldUGSgUtHFwjKM1h9jnFcmy5lChoLNaQMGGDsYbKixlaMBmmsx1QjCfflwTfO/gckW0ruZ3jugKR3R5W9hGUWqCgxuFgsuaCHorotGKzGaeZB9DMsaTnKCpMtwTvOzhYk0rdrArKCqcaWmVk1+F372ur1YkKxgatI8Qfe1gIX9wE9FgS8ESmuABIXnRUbCapcKe+nO7slClSZFzpV/LkLncEb1qiO42fS3R855Su2mCLh62t1SYZZYVmKwIHjREF2uihTzB20JOkz7dkxzYQnK0UOU494wh+VWRc6Un2kpTaVgLDFEkJ/uhzRcI0YKGgpGWOlocBU/a4fKoJ/pEaNV6jip3+Es9VXY078rGnmAdf7t9ylPXS34RBSuYPs1UecZTU78WanhBCHpZ5sAoTz0LGZKjPf9TRypqWEiTvOFglL1fCEY3wY/++rbk7C8bWebA6p6om6PgOL2kp44TFJlVNBXae2rqqdZztOJpT87GQsE9jqCPIe9VReZuQ/CIgacsyZdCpIScSYqcZk8r+nsyCzhyfhOqHGOIvrLknC8wTpFcaYiGC/RU1NRbUeUpocQOnkRpGOrIOcNRx+1uA0UrzhSSt+VyS3SJpnFWkzNDqOFGIWcfR86DnmARTQ1HKIL33ExPiemeOhYSSjzlSUZZuE4TveoJLnBUOFof6KiysCbnAEcZgcUNTDOwkqWu3RWtmGpZwlHhJENdZ3miGz0lJlsKnjbwqSHQjpxnFDlTLLwqJPMZMjd7KrzkSG7VsxXBZE+F8YZkb01Oe00yyRK9psh5SYh29ySPKBo2ylNht7ZkZnsKenjKNJu9PNEyZpaCHv4Kt6RQsLvAVp7M9kIimmCUwGeWqLMmGuIotYMmWNpSahkhZw9FqZsVnKJhsjAHvtHMsTM9fCI06Dx/u3vfUXCqfsKRc4oFY2jMsoo/7DJDwZ1CsIKnJu+J9ldkpmiCxQx1rWjI+T9FwcWWzOuaYH0Hj7klNRVWEQpmaqosakiGNTFHdjS/qnUdmf0NJW5xsL0HhimCCZZSRzmSPTXJQ4aaztAwtZnoabebJ+htCaZ7Cm535ByoqXKbX1WRc4Eh2MkRXWzImVc96Cj4VdOKVxR84VdQsIUM8Psoou2byVHyZFuq7O8otbSQ2UAoeEWTudATLGSpZzVLlXVkPU2Jc+27lsw2jmg5T5VhbeE3BT083K9WsTTkFU/Osi0rC5lRlpwRHUiesNS0sOvmqGML1aRbPAxTJD9ZKtxuob+hhl8cwYGWpJ8nub7t5p6coYbMovZ1BTdaKn1jYD6h4GFDNFyT/Kqe1XCXphXHOKLZmuRSRdBPEfVUXQzJm5YGPGGJdvAEr7hHNdGZnuBvrpciGmopOLf5N0uVMy0FfYToJk90uUCbJupaVpO53UJXR2bVpoU00V2KOo4zMFrBd0Jtz2pa0clT5Q5L8IpQ177mWQejPMEJhuQjS10ref6HHjdEhy1P1EYR7GtO0uSsKJQYLiTnG1rVScj5lyazpqWGl5uBbRWl7m6ixGOOnEsMJR7z8J0n6KMnCdxhiNYQCoZ6CmYLnO8omC3MkW3bktlPmEt/VQQHejL3+dOE5FlPdK/Mq8hZxxJtLyRrepLThYKbLZxkSb5W52vYxNOaOxUF0yxMUPwBTYqCzy01XayYK0sJyWBLqX0MwU5CzoymRzV0EjjeUeLgDpTo6ij42ZAzvD01dHUUTPLU96MdLbBME8nFBn7zJCMtJcZokn8YoqU0FS5WFKyniHobguMcmW8N0XkWZjkyN3hqOMtS08r+/xTBwpZSZ3qiVRX8SzMHHjfUNFjgHEPmY9PL3ykEzxkSre/1ZD6z/NuznuB0RcE1TWTm9zRgfUWVJiG6yrzgmWPXC8EAR4Wxhlad0ZbgQyEz3pG5RVEwwDJH2mgKpjcTiCOzn1lfUWANFbZ2BA8balnEweJC9J0iuaeZoI+ippFCztEKVvckR2iice1JvhVytrQwUAZpgsubCPaU7xUe9vWnaOpaSBEspalykhC9bUlOMpT42ZHca6hyrqKmw/wMR8H5ZmdFoBVJb03O4UL0tSNnvIeRmkrLWqrs78gcrEn2tpcboh0UPOW3UUR9PMk4T4nnNKWmCjlrefhCwxRNztfmIQVdDElvS4m1/WuOujoZCs5XVOjtKPGokJzsYCtFYoWonSPT21DheU/wWhM19FcElwqNGOsp9Q8N/cwXaiND1MmeL1Q5XROtYYgGeFq1aTMsoMmcrKjQrOFQTQ1fmBYhmW6o8Jkjc7iDJRTBIo5kgJD5yMEYA3srCg7VFKwiVJkmRCc5ohGOKhsYMn/XBLdo5taZjlb9YAlGWRimqbCsoY7HFAXLa5I1HPRxMMsQDHFkWtRNniqT9UEeNjcE7RUlrCJ4R2CSJuqlKHWvJXjAUNcITYkenuBRB84TbeepcqTj3zZyFJzgYQdHnqfgI0ddUwS6GqWpsKWhjq9cV0vBAEMN2znq+EBfIWT+pClYw5xsTlJU6GeIBsjGmmANTzJZiIYpgrM0Oa8ZMjd7NP87jxhqGOhJlnQtjuQpB+8aEE00wZFznSJPyHxgH3HkPOsJFvYk8zqCHzTs1BYOa4J3PFU+UVRZxlHDM4YavlNUuMoRveiZA2d7grMNc2g+RbSCEKzmgYsUmWmazFJyoiOZ4KnyhKOGRzWJa0+moyV4TVHDzn51Awtqaphfk/lRQ08FX1iiqxTB/kLwd0VynKfEvI6cd4XMV5bMhZ7gZUWVzYQ6Nm2BYzxJbw3bGthEUUMfgbGeorae6DxHtJoZ6alhZ0+ytiVoK1R4z5PTrOECT/SugseEOlb1MMNR4VRNcJy+V1Hg9ONClSZFZjdHlc6W6FBLdJja2MC5hhpu0DBYEY1TFGwiFAxRRCsYkiM9JRb0JNMVkW6CZYT/2EiTGWmo8k+h4FhDNE7BvppoTSFnmCV5xZKzvcCdDo7VVPnIU+I+Rc68juApC90MwcFCsJ5hDqxgScYKreruyQwTqrzoqDCmhWi4IbhB0Yrt3RGa6GfDv52rKXWhh28dyZaWUvcZeMTBaZoSGyiCtRU5J8iviioHaErs7Jkj61syVzTTgOcUOQ8buFBTYWdL5g3T4qlpe0+wvD63heAXRfCCIed9RbCsp2CiI7raUOYOTU13N8PNHvpaGvayo4a3LLT1lDrVEPT2zLUlheB1R+ZTRfKWJ+dcocLJfi11vyJ51lLqJ0WD7tRwryezjiV5W28uJO9qykzX8JDe2lHl/9oyBwa2UMfOngpXCixvKdXTk3wrsKmiVYdZIqsoWEERjbcUNDuiaQomGoIbFdEHmsyWnuR+IeriKDVLnlawlyNHKwKlSU631PKep8J4Q+ayjkSLKYLhalNHlYvttb6fHm0p6OApsZ4l2VfdqZkjuysy6ysKLlckf1KUutCTs39bmCgEyyoasIWlVaMF7mgmWtBT8Kol5xpH9IGllo8cJdopcvZ2sImlDmMIbtDk3KIpeNiS08lQw11NFPTwVFlPP6pJ2gvRfI7gQUfmNAtf6Gs0wQxDsKGlVBdF8rCa3jzdwMaGHOsItrZk7hAyOzpK9VS06j5F49b0VNGOOfKs3lDToMsMBe9ZWtHFEgxTJLs7qrygKZjUnmCYoeAqeU6jqWuLJup4WghOdvCYJnrSkSzoyRkm5M2StQwVltPkfCAk58tET/CSg+8MUecmotMEnhBKfWBIZsg2ihruMJQaoIm+tkTLKEqspMh00w95gvFCQRtDwTT1gVDDSEVdlwqZfxoQRbK0g+tbiBZxzKlpnpypejdDwTaeOvorMk/IJE10h9CqRe28hhLbe0pMsdSwv4ZbhKivo2BjDWfL8UKJgeavwlwb5KlwhyE4u4XkGE2ytZCznKLCDZZq42VzT8HLCrpruFbIfOIINmh/qCdZ1ZBc65kLHR1Bkyf5zn6pN3SvGKIlFNGplhrO9QSXanLOMQTLCa0YJCRrCZm/CZmrLTm7WzCK4GJDiWUdFeYx1LCFg3NMd0XmCuF3Y5rITLDUsYS9zoHVzwnJoYpSTQoObyEzr4cFBNqYTopoaU/wkyLZ2lPhX/5Y95ulxGTV7KjhWrOZgl8MyUUafjYraNjNU1N3IWcjT5WzWqjwtoarHSUObGYO3GCJZpsBlnJGPd6ZYLyl1GdCA2625IwwJDP8GUKymbzuyPlZlvTUsaUh5zFDhRWFzPKKZLAlWdcQbObgF9tOqOsmB1dqcqYJmWstFbZRRI9poolmqiLnU0POvxScpah2iSL5UJNzgScY5+AuIbpO0YD3NCW+dLMszFSdFCWGqG6eVq2uYVNDdICGD6W7EPRWZEY5gpsE9rUkS3mijzzJnm6UpUFXG1hCUeVoS5WfNcFpblELL2qqrCvMvRfd45oalvKU2tiQ6ePJOVMRXase9iTtLJztPxJKLWpo2CRDcJwn2sWSLKIO1WQWNTCvpVUvOZhgSC40JD0dOctaSqzkCRbXsKlb11Oip6PCJ0IwSJM31j3akRxlP7Rwn6aGaUL0qiLnJkvB3xWZ2+Q1TfCwpQH3G0o92UzmX4o/oJNQMMSQc547wVHhdk+VCw01DFYEnTxzZKAm74QmeNNR1w6WzEhNK15VJzuCdxQ53dRUDws5KvwgBMOEgpcVNe0hZI6RXT1Jd0cyj5nsaEAHgVmGaJIlWdsc5Ui2ElrRR6jrRAttNMEAIWrTDFubkZaok7/AkzfIwfuWVq0jHzuCK4QabtLUMVPB3kJ0oyHTSVFlqMALilJf2Rf8k5aaHtMfayocLBS8L89oKoxpJvnAkDPa0qp5DAUTHKWmCcnthlou8iCKaFFLHWcINd1nyIwXqrSxMNmSs6KmoL2QrKuWtlQ5V0120xQ5vRyZS1rgFkWwhiOwiuQbR0OOVhQM9iS3tiXp4RawRPMp5tDletOOBL95MpM01dZTBM9pkn5qF010rIeHFcFZhmSGpYpTsI6nwhqe5C9ynhlpp5ophuRb6WcJFldkVnVEwwxVfrVkvnWUuNLCg5bgboFHPDlDPDmnK7hUrWiIbjadDclujlZcaokOFup4Ri1kacV6jmrrK1hN9bGwpKEBQ4Q6DvIUXOmo6U5LqQM6EPyiKNjVkPnJkDPNEaxhiFay5ExW1NXVUGqcpYYdPcGiCq7z/TSlbhL4pplWXKd7NZO5QQFrefhRQW/NHOsqcIglc4UhWklR8K0QzbAw08CBDnpbgqXdeD/QUsM4RZXDFBW6WJKe/mFPdH0LtBgiq57wFLzlyQzz82qYx5D5WJP5yVJDW01BfyHnS6HKO/reZqId1WGa4Hkh2kWodJ8i6KoIPlAj2hPt76CzXsVR6koPRzWTfKqIentatYpQw2me4AA3y1Kind3SwoOKZDcFXTwl9tWU6mfgRk9d71sKtlNwrjnYw5tC5n5LdKiGry3JKNlHEd3oaMCFHrazBPMp/uNJ+V7IudcSbeOIdjUEdwl0VHCOZo5t6YluEuaC9mQeMgSfOyKnYGFHcIeQ84yQWbuJYJpZw5CzglDH7gKnWqqM9ZTaXcN0TeYhR84eQtJT76JJ1lREe7WnnvsMmRc9FQ7SBBM9mV3lCUdmHk/S2RAMt0QjFNFqQpWjDPQ01DXWUdDBkXziKPjGEP3VP+zIWU2t7im41FOloyWzn/L6dkUy3VLDaZ6appgDLHPjJEsyvJngWEPUyVBiAaHCTEXwrLvSEbV1e1gKJniicWorC1MUrVjB3uDhJE/wgSOzk1DXpk0k73qCM8xw2UvD5kJmDUfOomqMpWCkJRlvKXGmoeBm18USjVIk04SClxTB6YrgLAPLWYK9HLUt5cmc0vYES8GnTeRc6skZbQkWdxRsIcyBRzx1DbTk9FbU0caTPOgJHhJKnOGIVhQqvKmo0llRw9sabrZkDtdg3PqaKi9oatjY8B+G371paMg6+mZFNNtQ04mWBq3rYLOmtWWQp8KJnpy9DdFensyjdqZ+yY40VJlH8wcdLzC8PZnvHMFUTZUrDTkLyQaGus5X5LzpYAf3i+e/ZlhqGqWhh6Ou6xTR9Z6oi5AZZtp7Mj2EEm8oSpxiYZCHU/1fbGdNNNRRoZMhmilEb2gqHOEJDtXkHK/JnG6IrvbPCwV3NhONVdS1thBMs1T4QOBcTWa2IzhMk2nW5Kyn9tXUtpv9RsG2msxk+ZsQzRQacJncpgke0+T8y5Fzj8BiGo7XlJjaTIlpQs7KFjpqGnKuoyEPeIKnFMkZHvopgh81ySxNFWvJWcKRs70j2FOT012IllEEO1n4pD1513Yg2ssQPOThOkvyrqHUdEXOSEsihmBbTbKX1kLBPWqWkLOqJbjB3GBIZmoa8qWl4CG/iZ7oiA72ZL7TJNeZUY7kFQftDcHHluBzRbCegzMtrRjVQpX2lgoPKKLJAkcbMl01XK2p7yhL8pCBbQ3BN2avJgKvttcrWDK3CiUOVxQ8ZP+pqXKyIxnmBymCg5vJjNfkPK4+c8cIfK8ocVt7kmfd/I5SR1hKvCzUtb+lhgc00ZaO6CyhIQP1Uv4yIZjload72PXX0OIJvnFU+0Zf6MhsJwTfW0r0UwQfW4LNLZl5HK261JCZ4qnBaAreVAS3WrjV0LBnNDUNNDToCEeFfwgcb4gOEqLRhirWkexrCEYKVV711DLYEE1XBEsp5tpTGjorkomKYF9FDXv7fR3BGwbettSxnyL53MBPjsxDZjMh+VUW9NRxq1DhVk+FSxQcaGjV9Pawv6eGByw5qzoy7xk4RsOShqjJwWKe/1pEEfzkobeD/dQJmpqedcyBTy2sr4nGNRH0c0SPWTLrqAc0OQcb/gemKgqucQT7ySWKCn2EUotoCvpZct7RO2sy/QW0IWcXd7pQRQyZVwT2USRO87uhjioTLKV2brpMUcMQRbKH/N2T+UlTpaMls6cmc6CCNy3JdYYSUzzJQ4oSD3oKLncULOiJvjBEC2oqnCJkJluCYy2ZQ5so9YYlZ1VLlQU1mXEW1jZERwj/MUSRc24TdexlqLKfQBtDTScJUV8FszXBEY5ktpD5Ur9hYB4Nb1iikw3JoYpkKX+RodRKFt53MMuRnKSpY31PwYaGaILh3wxJGz9TkTPEETxoCWZrgvOlmyMzxFEwVJE5xZKzvyJ4WxEc16Gd4Xe3Weq4XH2jKRikqOkGQ87hQnC7wBmGYLAnesX3M+S87eFATauuN+Qcrh7xIxXJbUIdMw3JGE3ylCWzrieaqCn4zhGM19TQ3z1oH1AX+pWEqIc7wNGAkULBo/ZxRaV9NNyh4Br3rCHZzbzmSfawBL0dNRwpW1kK9mxPXR9povcdrGSZK9c2k0xwFGzjuniCtRSZCZ6ccZ7gaktmgAOtKbG/JnOkJrjcQTdFMsxRQ2cLY3WTIrlCw1eWKn8R6pvt4GFDso3QoL4a3nLk3G6JrtME3dSenpx7PNFTmga0EaJTLQ061sEeQoWXhSo9LTXsaSjoJQRXeZLtDclbCrYzfzHHeaKjHCVOUkQHO3JeEepr56mhiyaYYKjjNU+Fed1wS5VlhWSqI/hYUdDOkaxiKehoyOnrCV5yBHtbWFqTHCCwtpDcYolesVR5yUzTZBb3RNMd0d6WP+SvhuBmRcGxnuQzT95IC285cr41cLGQ6aJJhmi4TMGempxeimBRQw1tFKV+8jd6KuzoSTqqDxzRtpZkurvKEHxlqXKRIjjfUNNXQsNOsRScoWFLT+YeRZVD3GRN0MdQcKqQjHDMrdGGVu3iYJpQx3WGUvfbmxwFfR20WBq0oYY7LMFhhgYtr8jpaEnaOzjawWWaTP8mMr0t/EPDPoqcnxTBI5o58L7uoWnMrpoqPwgVrlAUWE+V+TQl9rawoyP6QGAlQw2TPRX+YSkxyBC8Z6jhHkXBgQL7WII3DVFnRfCrBfxewv9D6xsyjys4VkhWb9pUU627JllV0YDNHMku/ldNMMXDEo4aFnAkk4U6frNEU4XgZUPmEKHUl44KrzmYamjAbh0JFvGnaTLPu1s9jPCwjFpYiN7z1DTOk/nc07CfDFzmCf7i+bfNHXhDtLeBXzTBT5rkMvWOIxpl4EMh2LGJBu2syDnAEx2naEhHDWMMzPZEhygyS1mS5RTJr5ZkoKbEUoYqr2kqdDUE8ztK7OaIntJkFrIECwv8LJTaVx5XJE86go8dFeZ3FN3rjabCAYpoYEeC9zzJVULBbmZhDyd7ko09ydpNZ3nm2Kee4FPPXHnYEF1nqOFEC08LUVcDvYXkJHW8gTaKCk9YGOeIJhqiE4ToPEepdp7IWFjdwnWaufGMwJJCMtUTTBBK9BGCOy2tGGrJTHIwyEOzp6aPzNMOtlZkDvcEWpP5SVNhfkvDxhmSazTJXYrM9U1E0xwFVwqZQwzJxw6+kGGGUj2FglGGmnb1/G51udRSMNlTw6GGnCcUwVcOpmsqTHa06o72sw1RL02p9z0VbnMLOaIX3QKaYKSCFQzBKEUNHTSc48k53RH9wxGMtpQa5KjjW0W0n6XCCCG4yxNNdhQ4R4l1Ff+2sSd6UFHiIEOyqqFgT01mEUMD+joy75jPhOA+oVVLm309FR4yVOlp4RhLiScNmSmaYF5Pw0STrOIoWMSR2UkRXOMp+M4SHW8o8Zoi6OZgjKOaFar8zZDzkWzvKOjkKBjmCXby8JahhjXULY4KlzgKLvAwxVGhvyd4zxB1d9T0piazmKLCVZY5sKiD0y2ZSYrkUEPUbIk+dlQ4SJHTR50k1DPaUWIdTZW9NJwnJMOECgd7ou/MnppMJ02O1VT4Wsh85MnZzcFTngpXGKo84qmwgKbCL/orR/SzJ2crA+t6Mp94KvxJUeIbT3CQu1uIdlQEOzlKfS3UMcrTiFmOuroocrZrT2AcmamOKg8YomeEKm/rlT2sociMaybaUlFhuqHCM2qIJ+rg4EcDFymiDSxzaHdPcpE62pD5kyM5SBMoA1PaUtfIthS85ig1VPiPPYXgYEMNk4Qq7TXBgo7oT57gPUdwgCHzhIVFPFU6OYJzHAX9m5oNrVjeE61miDrqQ4VSa1oiURTsKHC0IfjNwU2WzK6eqK8jWln4g15TVBnqmDteCJ501PGAocJhhqjZdtBEB6lnhLreFJKxmlKbeGrqLiSThVIbCdGzloasa6lpMQXHCME2boLpJgT7yWaemu6wBONbqGNVRS0PKIL7LckbjmQtR7K8I5qtqel+T/ChJTNIKLjdUMNIRyvOEko9YYl2cwQveBikCNawJKcLBbc7+JM92mysNvd/Fqp8a0k6CNEe7cnZrxlW0wQXaXjaktnRwNOGZKYiONwS7a1JVheq3WgJHlQUGKHKmp4KAxXR/ULURcNgoa4zhKSLpZR3kxRRb0NmD0OFn+UCS7CzI1nbP6+o4x47QZE5xRCt3ZagnYcvmpYQktXdk5YKXTzBC57kKEe0VVuiSYqapssMS3C9p2CKkHOg8B8Pa8p5atrIw3qezIWanMGa5HRDNF6RM9wcacl0N+Q8Z8hsIkSnaIIdHRUOEebAPy1zbCkhM062FCJtif7PU+UtoVXzWKqM1PxXO8cfdruhFQ/a6x3JKYagvVDhQEtNiyiiSQ7OsuRsZUku0CRNDs4Sog6KKjsZgk2bYJqijgsEenoKeniinRXBn/U3lgpPdyDZynQx8IiioMnCep5Ky8mjGs6Wty0l1hUQTcNWswS3WRp2kCNZwJG8omG8JphPUaFbC8lEfabwP7VtM9yoaNCAjpR41VNhrD9LkbN722v0CoZMByFzhaW+MyzRYEWFDQwN2M4/JiT76PuljT3VU/A36eaIThb+R9oZGOAJ9tewkgGvqOMNRWYjT/Cwu99Q8LqDE4TgbLWxJ1jaDDAERsFOFrobgjUsBScaguXU8kKm2RL19tRypSHnHNlHiIZqgufs4opgQdVdwxBNNFBR6kVFqb8ogimOzB6a6HTzrlDHEpYaxjiiA4TMQobkDg2vejjfwJGWmnbVFAw3H3hq2NyQfG7hz4aC+w3BbwbesG0swYayvpAs6++Ri1Vfzx93mFChvyN5xVHTS+0p9aqCAxyZ6ZacZyw5+7uuQkFPR9DDk9NOiE7X1PCYJVjVUqq7JlrHwWALF5nfHNGjApdpqgzx5OwilDhCiDYTgnc9waGW4BdLNNUQvOtpzDOWHDH8D7TR/A/85KljEQu3NREc4Pl/6B1Hhc8Umb5CsKMmGC9EPcxoT2amwHNCmeOEnOPbklnMkbOgIvO5UMOpQrS9UGVdt6iH/fURjhI/WOpaW9OKLYRod6HCUEdOX000wpDZQ6hwg6LgZfOqo1RfT/CrJzjekXOGhpc1VW71ZLbXyyp+93ILbC1kPtIEYx0FIx1VDrLoVzXRKRYWk809yYlC9ImcrinxtabKnzRJk3lAU1OLEN1j2zrYzr2myHRXJFf4h4QKT1qSTzTB5+ZNTzTRkAxX8FcLV2uS8eoQQ2aAkFzvCM72sJIcJET3WPjRk5wi32uSS9rfZajpWEvj9hW42F4o5NytSXYy8IKHay10VYdrcl4SkqscrXpMwyGOgtkajheSxdQqmpxP1L3t4R5PqasFnrQEjytq6qgp9Y09Qx9o4S1FzhUCn1kyHSzBWLemoSGvOqLNhZyBjmCaAUYpMgt4Ck7wBBMMwWKWgjsUwTaGVsxWC1mYoKiyqqeGKYqonSIRQ3KIkHO0pmAxTdBHkbOvfllfr+AA+7gnc50huVKYK393FOyg7rbPO/izI7hE4CnHHHnJ0ogNPRUGeUpsrZZTBJcrovUcJe51BPsr6GkJdhCCsZ6aTtMEb2pqWkqeVtDXE/QVggsU/Nl86d9RMF3DxvZTA58agu810RWawCiSzzXBeU3MMW9oyJUedvNEvQyNu1f10BSMddR1vaLCYpYa/mGocLSiYDcLbQz8aMn5iyF4xBNMs1P0QEOV7o5gaWGuzSeLue4tt3ro7y4Tgm4G/mopdZgl6q0o6KzJWE3mMksNr3r+a6CbT8g5wZNzT9O7fi/zpaOmnz3BRoqos+tv9zMbdpxsqDBOEewtJLt7cg5wtKKbvldpSzRRCD43VFheCI7yZLppggMVBS/KMAdHODJvOwq2NQSbKKKPLdFWQs7Fqo+mpl01JXYRgq8dnGLhTiFzqmWsUMdpllZdbKlyvSdYxhI9YghOtxR8LgSLWHK62mGGVoxzBE8LNWzqH9CUesQzFy5RQzTc56mhi6fgXEWwpKfE5Z7M05ZgZUPmo6auiv8YKzDYwWBLMErIbKHJvOwIrvEdhOBcQ9JdU1NHQ7CXn2XIDFBKU2WAgcX9UAUzDXWd5alwuyJ41Z9rjKLCL4aCp4WarhPm2rH+SaHUYE001JDZ2ZAzXPjdMpZWvC9wmqIB2lLhQ01D5jO06hghWMndbM7yRJMsoCj1vYbnFQVrW9jak3OlEJ3s/96+p33dEPRV5GxiqaGjIthUU6FFEZyqCa5qJrpBdzSw95IUnOPIrCUUjRZQFrbw5PR0R1qiYx3cb6nrWUMrBmmiBQxVHtTew5ICP/ip6g4hed/Akob/32wvBHsIOX83cI8hGeNeNPCIkPmXe8fPKx84OMSRM1MTdXSwjCZ4S30jVGhvqTRak/OVhgGazHuOCud5onEO1lJr6ecVyaOK6H7zqlBlIaHE0oroCgfvGJIdPcmfLNGLjpz7hZwZQpUbFME0A1cIJa7VNORkgfsMBatbKgwwJM9bSvQXeNOvbIjelg6WWvo5kvbKaJJNHexkKNHL9xRyFlH8Ti2riB5wVPhUk7nGkJnoCe428LR/wRGdYIlmWebCyxou1rCk4g/ShugBDX0V0ZQWkh0dOVsagkM0yV6OoLd5ye+pRlsCr0n+KiQrGuq5yJDzrTAXHtLUMduTDBVKrSm3eHL+6ijxhFDX9Z5gVU/wliHYTMiMFpKLNMEywu80wd3meoFmt6VbRMPenhrOc6DVe4pgXU8DnnHakLOIIrlF4FZPIw6R+zxBP0dyq6OOZ4Q5sLKCcz084ok+VsMMyQhNZmmBgX5xIXOEJTmi7VsGTvMTNdHHhpzdbE8Du2oKxgvBqQKdDDnTFOylCFaxR1syz2iqrOI/FEpNc3C6f11/7+ASS6l2inq2ciTrCCzgyemrCL5SVPjQkdPZUmGy2c9Sw9FtR1sS30RmsKPCS4rkIC/2U0MduwucYolGaPjKEyhzmiPYXagyWbYz8LWBDdzRimAXzxx4z8K9hpzlhLq+NiQ97HuKorMUfK/OVvC2JfiHUPCQI/q7J2gjK+tTDNxkCc4TMssqCs4TGtLVwQihyoAWgj9bosU80XGW6Ac9TJGziaUh5+hnFcHOnlaM1iRn29NaqGENTTTSUHCH2tWTeV0osUhH6psuVLjRUmGWhm6OZEshGeNowABHcJ2Bpy2ZszRcKkRXd2QuKVEeXnbfaEq825FguqfgfE2whlChSRMdron+LATTPQ2Z369t4B9C5gs/ylzv+CMmepIDPclFQl13W0rspPd1JOcbghGOEutqCv5qacURQl3dDKyvyJlqKXGPgcM9FfawJAMVmdcspcYKOZc4GjDYkFlK05olNMHyHn4zFNykyOxt99RkHlfwmiHo60l2EKI+mhreEKp080Tbug08BVPcgoqC5zWt+NLDTZ7oNSF51N1qie7Va3uCCwyZbkINf/NED6jzOsBdZjFN8oqG3wxVunqCSYYKf3EdhJyf9YWGf7tRU2oH3VHgPr1fe5J9hOgHd7xQ0y7qBwXr23aGErP0cm64JVjZwsOGqL+mhNgZmhJLW2oY4UhedsyBgzrCKrq7BmcpNVhR6jBPq64Vgi+kn6XE68pp8J5/+0wRHGOpsKenQn9DZntPzjRLZpDAdD2fnSgkG9tmIXnUwQ6WVighs7Yi2MxQ0N3CqYaCXkJ0oyOztMDJjmSSpcpvlrk0RMMOjmArQ04PRV1DO1FwhCVaUVPpKUM03JK5SxPsIWRu8/CGHi8UHChiqGFDTbSRJWeYUDDcH6vJWUxR4k1FXbMUwV6e4AJFXS8oMqsZKqzvYQ9DDQdZckY4aGsIhtlubbd2r3j4QBMoTamdPZk7O/Bf62lacZwneNjQoGcdVU7zJOd7ghsUHOkosagic6cnWc8+4gg285R6zZP5s1/LUbCKIznTwK36PkdwlOrl4U1LwfdCCa+IrvFkmgw1PCAUXKWo0sURXWcI2muKJlgyFzhynCY4RBOsqCjoI1R5zREco0n2Vt09BQtYSizgKNHfUmUrQ5UOCh51BFcLmY7umhYqXKQomOop8bUnWNNQcIiBcYaC6xzMNOS8JQQfeqKBmmglB+97ok/lfk3ygaHSyZaCRTzRxQo6GzLfa2jWBPepw+UmT7SQEJyiyRkhBLMVOfcoMjcK0eZChfUNzFAUzCsEN5vP/X1uP/n/aoMX+K+nw/Hjr/9xOo7j7Pju61tLcgvJpTWXNbfN5jLpi6VfCOviTktKlFusQixdEKWmEBUKNaIpjZRSSOXSgzaaKLdabrm1/9nZ+/f+vd/vz/v9+Xy+zZ7PRorYoZqyLrCwQdEAixxVOEXNNnjX2nUSRlkqGmWowk8lxR50JPy9Bo6qJXaXwNvREBvnThPEPrewryLhcAnj5WE15Fqi8W7R1sAuEu86S4ENikItFN4xkv9Af4nXSnUVcLiA9xzesFpivRRVeFKtsMRaKBhuSbjOELnAUtlSQUpXgdfB4Z1oSbnFEetbQ0IrAe+Y+pqnDcEJFj6S8LDZzZHwY4e3XONNlARraomNEt2bkvGsosA3ioyHm+6jCMbI59wqt4eeara28IzEmyPgoRaUOEDhTVdEJhmCoTWfC0p8aNkCp0oYqih2iqGi4yXeMkOsn4LdLLnmKfh/YogjNsPebeFGR4m9BJHLzB61XQ3BtpISfS2FugsK9FAtLWX1dCRcrCnUp44CNzuCowUZmxSRgYaE6Za0W2u/E7CVXCiI/UOR8aAm1+OSyE3mOUcwyc1zBBeoX1kiKy0Zfxck1Gsyulti11i83QTBF5Kg3pDQThFMVHiPSlK+0cSedng/VaS8bOZbtsBcTcZAR8JP5KeqQ1OYKAi20njdNNRpgnsU//K+JnaXJaGTomr7aYIphoRn9aeShJWKEq9LcozSF7QleEfDI5LYm5bgVkFkRwVDBCVu0DDIkGupo8TZBq+/pMQURYErJQmPKGKjNDkWOLx7Jd5QizdUweIaKrlP7SwJDhZvONjLkOsBBX9UpGxnydhXkfBLQ8IxgojQbLFnJf81JytSljclYYyEFyx0kVBvKWOFJmONpshGAcsduQY5giVNCV51eOdJYo/pLhbvM0uDHSevNKRcrKZIqnCtJeEsO95RoqcgGK4ocZcho1tTYtcZvH41pNQ7vA0WrhIfOSraIIntIAi+NXWCErdbkvrWwjRLrt0NKUdL6KSOscTOdMSOUtBHwL6OLA0vNSdynaWQEnCpIvKaIrJJEbvHkmuNhn6OjM8VkSGSqn1uYJCGHnq9I3aLhNME3t6GjIkO7xrNFumpyTNX/NrwX7CrIRiqqWijI9JO4d1iieykyfiposQIQ8YjjsjlBh6oHWbwRjgYJQn2NgSnNycmJAk3NiXhx44Sxykihxm8ybUwT1OVKySc7vi3OXVkdBJ4AyXBeksDXG0IhgtYY0lY5ahCD0ehborIk5aUWRJviMA7Xt5kyRjonrXENkm8yYqgs8VzgrJmClK20uMM3jRJ0FiQICQF9hdETlLQWRIb5ki6WDfWRPobvO6a4GP5mcOrNzDFELtTkONLh9dXE8xypEg7z8A9jkhrQ6Fhjlg/QVktJXxt4WXzT/03Q8IaQWSqIuEvloQ2mqC9Jfi7wRul4RX3pSPlzpoVlmCtI2jvKHCFhjcM3sN6lqF6HxnKelLjXWbwrpR4xzuCrTUZx2qq9oAh8p6ixCUGr78g8oyjRAtB5CZFwi80VerVpI0h+IeBxa6Zg6kWvpDHaioYYuEsRbDC3eOmC2JvGYLeioxGknL2UATNJN6hmtj1DlpLvDVmocYbrGCVJKOrg4X6DgddLA203BKMFngdJJFtFd7vJLm6KEpc5yjQrkk7M80SGe34X24nSex1Ra5Omgb71JKyg8SrU3i/kARKwWpH0kOGhKkObyfd0ZGjvyXlAkVZ4xRbYJ2irFMkFY1SwyWxr2oo4zlNiV+7zmaweFpT4kR3kaDAFW6xpSqzJay05FtYR4HmZhc9UxKbbfF2V8RG1MBmSaE+kmC6JnaRXK9gsiXhJHl/U0qM0WTcbyhwkYIvFGwjSbjfwhiJt8ZSQU+Bd5+marPMOkVkD0muxYLIfEuhh60x/J92itguihJSEMySVPQnTewnEm+620rTQEMsOfo4/kP/0ARvWjitlpSX7GxBgcMEsd3EEeYWvdytd+Saawi6aCIj1CkGb6Aj9rwhx16Cf3vAwFy5pyLhVonXzy51FDpdEblbkdJbUcEPDEFzQ8qNmhzzLTmmKWKbFCXeEuRabp6rxbvAtLF442QjQ+wEA9eL1xSR7Q0JXzlSHjJ4exq89yR0laScJ/FW6z4a73pFMEfDiRZvuvijIt86RaSFOl01riV2mD1UEvxGk/Geg5aWwGki1zgKPG9J2U8PEg8qYvMsZeytiTRXBMslCU8JSlxi8EabjwUldlDNLfzTUmCgxWsjqWCOHavYAqsknKFIO0yQ61VL5AVFxk6WhEaCAkdJgt9aSkzXlKNX2jEa79waYuc7gq0N3GDJGCBhoiTXUEPsdknCUE1CK0fwsiaylSF2uiDyO4XX3pFhNd7R4itFGc0k/ElBZwWvq+GC6szVeEoS/MZ+qylwpKNKv9Z469UOjqCjwlusicyTxG6VpNxcQ8IncoR4RhLbR+NdpGGmJWOcIzJGUuKPGpQg8rrG21dOMqQssJQ4RxH5jaUqnZuQ0F4Q+cjxLwPtpZbIAk3QTJHQWBE5S1BokoVtDd6lhqr9UpHSUxMcIYl9pojsb8h4SBOsMQcqvOWC2E8EVehqiJ1hrrAEbQxeK0NGZ0Gkq+guSRgniM23bIHVkqwx4hiHd7smaOyglyIyQuM978j4VS08J/A2G1KeMBRo4fBaSNhKUEZfQewVQ/C1I+MgfbEleEzCUw7mKXI0M3hd1EESVji8x5uQ41nxs1q4RMJCCXs7Iq9acpxn22oSDnQ/sJTxsCbHIYZiLyhY05TY0ZLIOQrGaSJDDN4t8pVaIrsqqFdEegtizc1iTew5Q4ayBDMUsQMkXocaYkc0hZua412siZ1rSXlR460zRJ5SlHGe5j801RLMlJTxtaOM3Q1pvxJ45zUlWFD7rsAbpfEm1JHxG0eh8w2R7QQVzBUw28FhFp5QZzq8t2rx2joqulYTWSuJdTYfWwqMFMcovFmSyJPNyLhE4E10pHzYjOC3huArRa571ZsGajQpQx38SBP5pyZB6lMU3khDnp0MBV51BE9o2E+TY5Ml2E8S7C0o6w1xvCZjf0HkVEHCzFoyNmqC+9wdcqN+Tp7jSDheE9ws8Y5V0NJCn2bk2tqSY4okdrEhx1iDN8cSudwepWmAGXKcJXK65H9to8jYQRH7SBF01ESUJdd0TayVInaWhLkOjlXE5irKGOnI6GSWGCJa482zBI9rCr0jyTVcEuzriC1vcr6mwFGSiqy5zMwxBH/TJHwjSPhL8+01kaaSUuMFKTcLEvaUePcrSmwn8DZrgikWb7CGPxkSjhQwrRk57tctmxLsb9sZvL9LSlyuSLlWkqOjwduo8b6Uv1DkmudIeFF2dHCgxVtk8dpIvHpBxhEOdhKk7OLIUSdJ+cSRY57B+0DgGUUlNfpthTfGkauzxrvTsUUaCVhlKeteTXCoJDCa2NOKhOmC4G1H8JBd4OBZReSRGkqcb/CO1PyLJTLB4j1q8JYaIutEjSLX8YKM+a6phdMsdLFUoV5RTm9JSkuDN8WcIon0NZMNZWh1q8C7SJEwV5HxrmnnTrf3KoJBlmCYI2ilSLlfEvlE4011NNgjgthzEua0oKK7JLE7HZHlEl60BLMVFewg4EWNt0ThrVNEVkkiTwpKXSWJzdRENgvKGq4IhjsiezgSFtsfCUq8qki5S1LRQeYQQ4nemmCkImWMw3tFUoUBZk4NOeZYEp4XRKTGa6wJjrWNHBVJR4m3FCnbuD6aak2WsMTh3SZImGCIPKNgsDpVwnsa70K31lCFJZYcwwSMFcQulGTsZuEaSdBXkPGZhu0FsdUO73RHjq8MPGGIfaGIbVTk6iuI3GFgucHrIQkmWSJdBd7BBu+uOryWAhY7+Lki9rK5wtEQzWwvtbqGhIMFwWRJsElsY4m9IIg9L6lCX0VklaPAYkfkZEGDnOWowlBJjtMUkcGK4Lg6EtoZInMUBVYLgn0UsdmCyCz7gIGHFfk+k1QwTh5We7A9x+IdJ6CvIkEagms0hR50eH9UnTQJ+2oiKyVlLFUE+8gBGu8MQ3CppUHesnjTHN4QB/UGPhCTHLFPHMFrCqa73gqObUJGa03wgbhHkrCfpEpzNLE7JDS25FMKhlhKKWKfCgqstLCPu1zBXy0J2ztwjtixBu8UTRn9LVtkmCN2iyFhtME70JHRQ1KVZXqKI/KNIKYMCYs1GUMEKbM1bKOI9LDXC7zbHS+bt+1MTWS9odA9DtrYtpbImQJ2VHh/lisEwaHqUk1kjKTAKknkBEXkbkdMGwq0dnhzLJF3NJH3JVwrqOB4Sca2hti75nmJN0WzxS6UxDYoEpxpa4htVlRjkYE7DZGzJVU72uC9IyhQL4i8YfGWSYLLNcHXloyz7QhNifmKSE9JgfGmuyLhc403Xm9vqcp6gXe3xuuv8F6VJNxkyTHEkHG2g0aKXL0MsXc1bGfgas2//dCONXiNLCX+5mB7eZIl1kHh7ajwpikyzlUUWOVOsjSQlsS+M0R+pPje/dzBXRZGO0rMtgQrLLG9VSu9n6CMXS3BhwYmSoIBhsjNBmZbgusE9BCPCP5triU4VhNbJfE+swSP27aayE8tuTpYYjtrYjMVGZdp2NpS1s6aBnKSHDsbKuplKbHM4a0wMFd/5/DmGyKrJSUaW4IBrqUhx0vyfzTBBLPIUcnZdrAkNsKR0sWRspumSns6Ch0v/qqIbBYUWKvPU/CFoyrDJGwSNFhbA/MlzKqjrO80hRbpKx0Jewsi/STftwGSlKc1JZyAzx05dhLEdnfQvhZOqiHWWEAHC7+30FuRcZUgaO5gpaIK+xsiHRUsqaPElTV40xQZQ107Q9BZE1nryDVGU9ZSQ47bmhBpLcYpUt7S+xuK/FiT8qKjwXYw5ypS2iuCv7q1gtgjhuBuB8LCFY5cUuCNtsQOFcT+4Ih9JX+k8Ea6v0iCIRZOtCT0Et00JW5UeC85Cg0ScK0k411HcG1zKtre3SeITBRk7WfwDhEvaYLTHP9le0m8By0JDwn4TlLW/aJOvGHxdjYUes+ScZigCkYQdNdEOhkiezgShqkx8ueKjI8lDfK2oNiOFvrZH1hS+tk7NV7nOmLHicGWEgubkXKdwdtZknCLJXaCpkrjZBtLZFsDP9CdxWsSr05Sxl6CMmoFbCOgryX40uDtamB7SVmXW4Ihlgpmq+00tBKUUa83WbjLUNkzDmY7cow1JDygyPGlhgGKYKz4vcV7QBNbJIgM11TUqZaMdwTeSguH6rOaw1JRKzaaGyxVm2EJ/uCIrVWUcZUkcp2grMsEjK+DMwS59jQk3Kd6SEq1d0S6uVmO4Bc1lDXTUcHjluCXEq+1OlBDj1pi9zgiXxnKuE0SqTXwhqbETW6RggMEnGl/q49UT2iCzgJvRwVXS2K/d6+ZkyUl7jawSVLit46EwxVljDZwoSQ20sDBihztHfk2yA8NVZghiXwrYHQdfKAOtzsayjhY9bY0yE2CWEeJ9xfzO423xhL5syS2TFJofO2pboHob0nY4GiAgRrvGQEDa/FWSsoaaYl0syRsEt3kWoH3B01shCXhTUWe9w3Bt44SC9QCh3eShQctwbaK2ApLroGCMlZrYqvlY3qYhM0aXpFkPOuoqJ3Dm6fxXrGwVF9gCWZagjPqznfkuMKQ8DPTQRO8ZqG1hPGKEm9IgpGW4DZDgTNriTxvFiq+Lz+0cKfp4wj6OCK9JSnzNSn9LFU7UhKZZMnYwcJ8s8yRsECScK4j5UOB95HFO0CzhY4xJxuCix0lDlEUeMdS6EZBkTsUkZ4K74dugyTXS7aNgL8aqjDfkCE0ZbwkCXpaWCKhl8P7VD5jxykivSyxyZrYERbe168LYu9ZYh86IkscgVLE7tWPKmJv11CgoyJltMEbrohtVAQfO4ImltiHEroYEs7RxAarVpY8AwXMcMReFOTYWe5iiLRQxJ5Q8DtJ8LQhWOhIeFESPGsILhbNDRljNbHzNRlTFbk2S3L0NOS6V1KFJYKUbSTcIIhM0wQ/s2TM0SRMNcQmSap3jCH4yhJZKSkwyRHpYYgsFeQ4U7xoCB7VVOExhXepo9ABBsYbvGWKXPME3lyH95YioZ0gssQRWWbI+FaSMkXijZXwgiTlYdPdkNLaETxlyDVIwqeaEus0aTcYcg0RVOkpR3CSJqIddK+90JCxzsDVloyrFd5ZAr4TBKfaWa6boEA7C7s6EpYaeFPjveooY72mjIccLHJ9HUwVlDhKkmutJDJBwnp1rvulJZggKDRfbXAkvC/4l3ozQOG9a8lxjx0i7nV4jSXc7vhe3OwIxjgSHjdEhhsif9YkPGlus3iLFDnWOFhtCZbJg0UbQcIaR67JjthoCyMEZRwhiXWyxO5QxI6w5NhT4U1WsJvDO60J34fW9hwzwlKij6ZAW9ne4L0s8C6XeBMEkd/LQy1VucBRot6QMlbivaBhoBgjqGiCJNhsqVp/S2SsG6DIONCR0dXhvWbJ+MRRZJkkuEjgDXJjFQW6SSL7GXK8Z2CZg7cVsbWGoKmEpzQ5elpiy8Ryg7dMkLLUEauzeO86CuwlSOlgYLojZWeJ9xM3S1PWfEfKl5ISLQ0MEKR8YOB2QfCxJBjrKPCN4f9MkaSsqoVXJBmP7EpFZ9UQfOoOFwSzBN4MQ8LsGrymlipcJQhmy0GaQjPqCHaXRwuCZwRbqK2Fg9wlClZqYicrIgMdZfxTQ0c7TBIbrChxmuzoKG8XRaSrIhhiyNFJkrC7oIAWMEOQa5aBekPCRknCo4IKPrYkvCDI8aYmY7WFtprgekcJZ3oLIqssCSMtFbQTJKwXYy3BY5oCh2iKPCpJOE+zRdpYgi6O2KmOAgvVCYaU4ySRek1sgyFhJ403QFHiVEmJHwtybO1gs8Hr5+BETQX3War0qZngYGgtVZtoqd6vFSk/UwdZElYqyjrF4HXUeFspIi9IGKf4j92pKGAdCYMVsbcV3kRF0N+R8LUd5PCsIGWoxDtBkCI0nKofdJQxT+LtZflvuc8Q3CjwWkq8KwUpHzkK/NmSsclCL0nseQdj5FRH5CNHSgtLiW80Of5HU9Hhlsga9bnBq3fEVltKfO5IaSTmGjjc4J0otcP7QsJUSQM8pEj5/wCuUuC2DWz8AAAAAElFTkSuQmCC");
+}
diff --git a/app/gui/html/vendor/codemirror/theme/base16-dark.css b/app/gui/html/vendor/codemirror/theme/base16-dark.css
new file mode 100644
index 0000000..3b7b21c
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/base16-dark.css
@@ -0,0 +1,34 @@
+/*
+
+    Name:       Base16 Default Dark
+    Author:     Chris Kempson (http://chriskempson.com)
+
+    CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-chrome-devtools)
+    Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-base16-dark.CodeMirror {background: #151515; color: #e0e0e0;}
+.cm-s-base16-dark div.CodeMirror-selected {background: #202020 !important;}
+.cm-s-base16-dark .CodeMirror-gutters {background: #151515; border-right: 0px;}
+.cm-s-base16-dark .CodeMirror-linenumber {color: #505050;}
+.cm-s-base16-dark .CodeMirror-cursor {border-left: 1px solid #b0b0b0 !important;}
+
+.cm-s-base16-dark span.cm-comment {color: #8f5536;}
+.cm-s-base16-dark span.cm-atom {color: #aa759f;}
+.cm-s-base16-dark span.cm-number {color: #aa759f;}
+
+.cm-s-base16-dark span.cm-property, .cm-s-base16-dark span.cm-attribute {color: #90a959;}
+.cm-s-base16-dark span.cm-keyword {color: #ac4142;}
+.cm-s-base16-dark span.cm-string {color: #f4bf75;}
+
+.cm-s-base16-dark span.cm-variable {color: #90a959;}
+.cm-s-base16-dark span.cm-variable-2 {color: #6a9fb5;}
+.cm-s-base16-dark span.cm-def {color: #d28445;}
+.cm-s-base16-dark span.cm-bracket {color: #e0e0e0;}
+.cm-s-base16-dark span.cm-tag {color: #ac4142;}
+.cm-s-base16-dark span.cm-link {color: #aa759f;}
+.cm-s-base16-dark span.cm-error {background: #ac4142; color: #b0b0b0;}
+
+.cm-s-base16-dark .CodeMirror-activeline-background {background: #2F2F2F !important;}
+.cm-s-base16-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/base16-light.css b/app/gui/html/vendor/codemirror/theme/base16-light.css
new file mode 100644
index 0000000..5aa4b53
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/base16-light.css
@@ -0,0 +1,34 @@
+/*
+
+    Name:       Base16 Default Light
+    Author:     Chris Kempson (http://chriskempson.com)
+
+    CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-chrome-devtools)
+    Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-base16-light.CodeMirror {background: #f5f5f5; color: #202020;}
+.cm-s-base16-light div.CodeMirror-selected {background: #e0e0e0 !important;}
+.cm-s-base16-light .CodeMirror-gutters {background: #f5f5f5; border-right: 0px;}
+.cm-s-base16-light .CodeMirror-linenumber {color: #b0b0b0;}
+.cm-s-base16-light .CodeMirror-cursor {border-left: 1px solid #505050 !important;}
+
+.cm-s-base16-light span.cm-comment {color: #8f5536;}
+.cm-s-base16-light span.cm-atom {color: #aa759f;}
+.cm-s-base16-light span.cm-number {color: #aa759f;}
+
+.cm-s-base16-light span.cm-property, .cm-s-base16-light span.cm-attribute {color: #90a959;}
+.cm-s-base16-light span.cm-keyword {color: #ac4142;}
+.cm-s-base16-light span.cm-string {color: #f4bf75;}
+
+.cm-s-base16-light span.cm-variable {color: #90a959;}
+.cm-s-base16-light span.cm-variable-2 {color: #6a9fb5;}
+.cm-s-base16-light span.cm-def {color: #d28445;}
+.cm-s-base16-light span.cm-bracket {color: #202020;}
+.cm-s-base16-light span.cm-tag {color: #ac4142;}
+.cm-s-base16-light span.cm-link {color: #aa759f;}
+.cm-s-base16-light span.cm-error {background: #ac4142; color: #505050;}
+
+.cm-s-base16-light .CodeMirror-activeline-background {background: #DDDCDC !important;}
+.cm-s-base16-light .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/blackboard.css b/app/gui/html/vendor/codemirror/theme/blackboard.css
new file mode 100644
index 0000000..8b76084
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/blackboard.css
@@ -0,0 +1,28 @@
+/* Port of TextMate's Blackboard theme */
+
+.cm-s-blackboard.CodeMirror { background: #0C1021; color: #F8F8F8; }
+.cm-s-blackboard .CodeMirror-selected { background: #253B76 !important; }
+.cm-s-blackboard .CodeMirror-gutters { background: #0C1021; border-right: 0; }
+.cm-s-blackboard .CodeMirror-linenumber { color: #888; }
+.cm-s-blackboard .CodeMirror-cursor { border-left: 1px solid #A7A7A7 !important; }
+
+.cm-s-blackboard .cm-keyword { color: #FBDE2D; }
+.cm-s-blackboard .cm-atom { color: #D8FA3C; }
+.cm-s-blackboard .cm-number { color: #D8FA3C; }
+.cm-s-blackboard .cm-def { color: #8DA6CE; }
+.cm-s-blackboard .cm-variable { color: #FF6400; }
+.cm-s-blackboard .cm-operator { color: #FBDE2D;}
+.cm-s-blackboard .cm-comment { color: #AEAEAE; }
+.cm-s-blackboard .cm-string { color: #61CE3C; }
+.cm-s-blackboard .cm-string-2 { color: #61CE3C; }
+.cm-s-blackboard .cm-meta { color: #D8FA3C; }
+.cm-s-blackboard .cm-builtin { color: #8DA6CE; }
+.cm-s-blackboard .cm-tag { color: #8DA6CE; }
+.cm-s-blackboard .cm-attribute { color: #8DA6CE; }
+.cm-s-blackboard .cm-header { color: #FF6400; }
+.cm-s-blackboard .cm-hr { color: #AEAEAE; }
+.cm-s-blackboard .cm-link { color: #8DA6CE; }
+.cm-s-blackboard .cm-error { background: #9D1E15; color: #F8F8F8; }
+
+.cm-s-blackboard .CodeMirror-activeline-background {background: #3C3636 !important;}
+.cm-s-blackboard .CodeMirror-matchingbracket {outline:1px solid grey;color:white !important}
\ No newline at end of file
diff --git a/app/gui/html/vendor/codemirror/theme/cobalt.css b/app/gui/html/vendor/codemirror/theme/cobalt.css
new file mode 100644
index 0000000..b4a9177
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/cobalt.css
@@ -0,0 +1,21 @@
+.cm-s-cobalt.CodeMirror { background: #002240; color: white; }
+.cm-s-cobalt div.CodeMirror-selected { background: #b36539 !important; }
+.cm-s-cobalt .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; }
+.cm-s-cobalt .CodeMirror-linenumber { color: #d0d0d0; }
+.cm-s-cobalt .CodeMirror-cursor { border-left: 1px solid white !important; }
+
+.cm-s-cobalt span.cm-comment { color: #08f; }
+.cm-s-cobalt span.cm-atom { color: #845dc4; }
+.cm-s-cobalt span.cm-number, .cm-s-cobalt span.cm-attribute { color: #ff80e1; }
+.cm-s-cobalt span.cm-keyword { color: #ffee80; }
+.cm-s-cobalt span.cm-string { color: #3ad900; }
+.cm-s-cobalt span.cm-meta { color: #ff9d00; }
+.cm-s-cobalt span.cm-variable-2, .cm-s-cobalt span.cm-tag { color: #9effff; }
+.cm-s-cobalt span.cm-variable-3, .cm-s-cobalt span.cm-def { color: white; }
+.cm-s-cobalt span.cm-bracket { color: #d8d8d8; }
+.cm-s-cobalt span.cm-builtin, .cm-s-cobalt span.cm-special { color: #ff9e59; }
+.cm-s-cobalt span.cm-link { color: #845dc4; }
+.cm-s-cobalt span.cm-error { color: #9d1e15; }
+
+.cm-s-cobalt .CodeMirror-activeline-background {background: #002D57 !important;}
+.cm-s-cobalt .CodeMirror-matchingbracket {outline:1px solid grey;color:white !important}
diff --git a/app/gui/html/vendor/codemirror/theme/eclipse.css b/app/gui/html/vendor/codemirror/theme/eclipse.css
new file mode 100644
index 0000000..317218e
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/eclipse.css
@@ -0,0 +1,23 @@
+.cm-s-eclipse span.cm-meta {color: #FF1717;}
+.cm-s-eclipse span.cm-keyword { line-height: 1em; font-weight: bold; color: #7F0055; }
+.cm-s-eclipse span.cm-atom {color: #219;}
+.cm-s-eclipse span.cm-number {color: #164;}
+.cm-s-eclipse span.cm-def {color: #00f;}
+.cm-s-eclipse span.cm-variable {color: black;}
+.cm-s-eclipse span.cm-variable-2 {color: #0000C0;}
+.cm-s-eclipse span.cm-variable-3 {color: #0000C0;}
+.cm-s-eclipse span.cm-property {color: black;}
+.cm-s-eclipse span.cm-operator {color: black;}
+.cm-s-eclipse span.cm-comment {color: #3F7F5F;}
+.cm-s-eclipse span.cm-string {color: #2A00FF;}
+.cm-s-eclipse span.cm-string-2 {color: #f50;}
+.cm-s-eclipse span.cm-qualifier {color: #555;}
+.cm-s-eclipse span.cm-builtin {color: #30a;}
+.cm-s-eclipse span.cm-bracket {color: #cc7;}
+.cm-s-eclipse span.cm-tag {color: #170;}
+.cm-s-eclipse span.cm-attribute {color: #00c;}
+.cm-s-eclipse span.cm-link {color: #219;}
+.cm-s-eclipse span.cm-error {color: #f00;}
+
+.cm-s-eclipse .CodeMirror-activeline-background {background: #e8f2ff !important;}
+.cm-s-eclipse .CodeMirror-matchingbracket {outline:1px solid grey; color:black !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/elegant.css b/app/gui/html/vendor/codemirror/theme/elegant.css
new file mode 100644
index 0000000..dd7df7b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/elegant.css
@@ -0,0 +1,13 @@
+.cm-s-elegant span.cm-number, .cm-s-elegant span.cm-string, .cm-s-elegant span.cm-atom {color: #762;}
+.cm-s-elegant span.cm-comment {color: #262; font-style: italic; line-height: 1em;}
+.cm-s-elegant span.cm-meta {color: #555; font-style: italic; line-height: 1em;}
+.cm-s-elegant span.cm-variable {color: black;}
+.cm-s-elegant span.cm-variable-2 {color: #b11;}
+.cm-s-elegant span.cm-qualifier {color: #555;}
+.cm-s-elegant span.cm-keyword {color: #730;}
+.cm-s-elegant span.cm-builtin {color: #30a;}
+.cm-s-elegant span.cm-link {color: #762;}
+.cm-s-elegant span.cm-error {background-color: #fdd;}
+
+.cm-s-elegant .CodeMirror-activeline-background {background: #e8f2ff !important;}
+.cm-s-elegant .CodeMirror-matchingbracket {outline:1px solid grey; color:black !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/erlang-dark.css b/app/gui/html/vendor/codemirror/theme/erlang-dark.css
new file mode 100644
index 0000000..db56b10
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/erlang-dark.css
@@ -0,0 +1,30 @@
+.cm-s-erlang-dark.CodeMirror { background: #002240; color: white; }
+.cm-s-erlang-dark div.CodeMirror-selected { background: #b36539 !important; }
+.cm-s-erlang-dark .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; }
+.cm-s-erlang-dark .CodeMirror-linenumber { color: #d0d0d0; }
+.cm-s-erlang-dark .CodeMirror-cursor { border-left: 1px solid white !important; }
+
+.cm-s-erlang-dark span.cm-atom       { color: #f133f1; }
+.cm-s-erlang-dark span.cm-attribute  { color: #ff80e1; }
+.cm-s-erlang-dark span.cm-bracket    { color: #ff9d00; }
+.cm-s-erlang-dark span.cm-builtin    { color: #eaa; }
+.cm-s-erlang-dark span.cm-comment    { color: #77f; }
+.cm-s-erlang-dark span.cm-def        { color: #e7a; }
+.cm-s-erlang-dark span.cm-keyword    { color: #ffee80; }
+.cm-s-erlang-dark span.cm-meta       { color: #50fefe; }
+.cm-s-erlang-dark span.cm-number     { color: #ffd0d0; }
+.cm-s-erlang-dark span.cm-operator   { color: #d55; }
+.cm-s-erlang-dark span.cm-property   { color: #ccc; }
+.cm-s-erlang-dark span.cm-qualifier  { color: #ccc; }
+.cm-s-erlang-dark span.cm-quote      { color: #ccc; }
+.cm-s-erlang-dark span.cm-special    { color: #ffbbbb; }
+.cm-s-erlang-dark span.cm-string     { color: #3ad900; }
+.cm-s-erlang-dark span.cm-string-2   { color: #ccc; }
+.cm-s-erlang-dark span.cm-tag        { color: #9effff; }
+.cm-s-erlang-dark span.cm-variable   { color: #50fe50; }
+.cm-s-erlang-dark span.cm-variable-2 { color: #e0e; }
+.cm-s-erlang-dark span.cm-variable-3 { color: #ccc; }
+.cm-s-erlang-dark span.cm-error      { color: #9d1e15; }
+
+.cm-s-erlang-dark .CodeMirror-activeline-background {background: #013461 !important;}
+.cm-s-erlang-dark .CodeMirror-matchingbracket {outline:1px solid grey; color:white !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/lesser-dark.css b/app/gui/html/vendor/codemirror/theme/lesser-dark.css
new file mode 100644
index 0000000..c325596
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/lesser-dark.css
@@ -0,0 +1,47 @@
+/*
+http://lesscss.org/ dark theme
+Ported to CodeMirror by Peter Kroon
+*/
+.cm-s-lesser-dark {
+  line-height: 1.3em;
+}
+.cm-s-lesser-dark {
+  font-family: 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', 'Monaco', Courier, monospace !important;
+}
+
+.cm-s-lesser-dark.CodeMirror { background: #262626; color: #EBEFE7; text-shadow: 0 -1px 1px #262626; }
+.cm-s-lesser-dark div.CodeMirror-selected {background: #45443B !important;} /* 33322B*/
+.cm-s-lesser-dark .CodeMirror-cursor { border-left: 1px solid white !important; }
+.cm-s-lesser-dark pre { padding: 0 8px; }/*editable code holder*/
+
+.cm-s-lesser-dark.CodeMirror span.CodeMirror-matchingbracket { color: #7EFC7E; }/*65FC65*/
+
+.cm-s-lesser-dark .CodeMirror-gutters { background: #262626; border-right:1px solid #aaa; }
+.cm-s-lesser-dark .CodeMirror-linenumber { color: #777; }
+
+.cm-s-lesser-dark span.cm-keyword { color: #599eff; }
+.cm-s-lesser-dark span.cm-atom { color: #C2B470; }
+.cm-s-lesser-dark span.cm-number { color: #B35E4D; }
+.cm-s-lesser-dark span.cm-def {color: white;}
+.cm-s-lesser-dark span.cm-variable { color:#D9BF8C; }
+.cm-s-lesser-dark span.cm-variable-2 { color: #669199; }
+.cm-s-lesser-dark span.cm-variable-3 { color: white; }
+.cm-s-lesser-dark span.cm-property {color: #92A75C;}
+.cm-s-lesser-dark span.cm-operator {color: #92A75C;}
+.cm-s-lesser-dark span.cm-comment { color: #666; }
+.cm-s-lesser-dark span.cm-string { color: #BCD279; }
+.cm-s-lesser-dark span.cm-string-2 {color: #f50;}
+.cm-s-lesser-dark span.cm-meta { color: #738C73; }
+.cm-s-lesser-dark span.cm-qualifier {color: #555;}
+.cm-s-lesser-dark span.cm-builtin { color: #ff9e59; }
+.cm-s-lesser-dark span.cm-bracket { color: #EBEFE7; }
+.cm-s-lesser-dark span.cm-tag { color: #669199; }
+.cm-s-lesser-dark span.cm-attribute {color: #00c;}
+.cm-s-lesser-dark span.cm-header {color: #a0a;}
+.cm-s-lesser-dark span.cm-quote {color: #090;}
+.cm-s-lesser-dark span.cm-hr {color: #999;}
+.cm-s-lesser-dark span.cm-link {color: #00c;}
+.cm-s-lesser-dark span.cm-error { color: #9d1e15; }
+
+.cm-s-lesser-dark .CodeMirror-activeline-background {background: #3C3A3A !important;}
+.cm-s-lesser-dark .CodeMirror-matchingbracket {outline:1px solid grey; color:white !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/mbo.css b/app/gui/html/vendor/codemirror/theme/mbo.css
new file mode 100644
index 0000000..bb52e6d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/mbo.css
@@ -0,0 +1,37 @@
+/* Based on mbonaci's Brackets mbo theme */
+
+.cm-s-mbo.CodeMirror {background: #2c2c2c; color: #ffffe9;}
+.cm-s-mbo div.CodeMirror-selected {background: #716C62 !important;}
+.cm-s-mbo .CodeMirror-gutters {background: #4e4e4e; border-right: 0px;}
+.cm-s-mbo .CodeMirror-linenumber {color: #dadada;}
+.cm-s-mbo .CodeMirror-cursor {border-left: 1px solid #ffffec !important;}
+
+.cm-s-mbo span.cm-comment {color: #95958a;}
+.cm-s-mbo span.cm-atom {color: #00a8c6;}
+.cm-s-mbo span.cm-number {color: #00a8c6;}
+
+.cm-s-mbo span.cm-property, .cm-s-mbo span.cm-attribute {color: #9ddfe9;}
+.cm-s-mbo span.cm-keyword {color: #ffb928;}
+.cm-s-mbo span.cm-string {color: #ffcf6c;}
+
+.cm-s-mbo span.cm-variable {color: #ffffec;}
+.cm-s-mbo span.cm-variable-2 {color: #00a8c6;}
+.cm-s-mbo span.cm-def {color: #ffffec;}
+.cm-s-mbo span.cm-bracket {color: #fffffc; font-weight: bold;}
+.cm-s-mbo span.cm-tag {color: #9ddfe9;}
+.cm-s-mbo span.cm-link {color: #f54b07;}
+.cm-s-mbo span.cm-error {background: #636363; color: #ffffec;}
+
+.cm-s-mbo .CodeMirror-activeline-background {background: #494b41 !important;}
+.cm-s-mbo .CodeMirror-matchingbracket {
+  text-decoration: underline;
+  color: #f5e107 !important;
+ }
+ 
+.cm-s-mbo .CodeMirror-matchingtag {background: #4e4e4e;}
+
+.cm-s-mbo span.cm-searching {
+  background-color: none;
+  background: none;
+  box-shadow: 0 0 0 1px #ffffec;
+}
diff --git a/app/gui/html/vendor/codemirror/theme/mdn-like.css b/app/gui/html/vendor/codemirror/theme/mdn-like.css
new file mode 100644
index 0000000..c12cb1f
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/mdn-like.css
@@ -0,0 +1,44 @@
+/*
+  MDN-LIKE Theme - Mozilla
+  Ported to CodeMirror by Peter Kroon <plakroon at gmail.com>
+  Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues
+  GitHub: @peterkroon
+
+  The mdn-like theme is inspired on the displayed code examples at: https://developer.mozilla.org/en-US/docs/Web/CSS/animation
+
+*/
+.cm-s-mdn-like.CodeMirror { color: #999; font-family: monospace; background-color: #fff; }
+.cm-s-mdn-like .CodeMirror-selected { background: #cfc !important; }
+
+.cm-s-mdn-like .CodeMirror-gutters { background: #f8f8f8; border-left: 6px solid rgba(0,83,159,0.65); color: #333; }
+.cm-s-mdn-like .CodeMirror-linenumber { color: #aaa; margin-left: 3px; }
+div.cm-s-mdn-like .CodeMirror-cursor { border-left: 2px solid #222; }
+
+.cm-s-mdn-like .cm-keyword {  color: #6262FF; }
+.cm-s-mdn-like .cm-atom { color: #F90; }
+.cm-s-mdn-like .cm-number { color:  #ca7841; }
+.cm-s-mdn-like .cm-def { color: #8DA6CE; }
+.cm-s-mdn-like span.cm-variable-2, .cm-s-mdn-like span.cm-tag { color: #690; }
+.cm-s-mdn-like span.cm-variable-3, .cm-s-mdn-like span.cm-def { color: #07a; }
+
+.cm-s-mdn-like .cm-variable { color: #07a; }
+.cm-s-mdn-like .cm-property { color: #905; }
+.cm-s-mdn-like .cm-qualifier { color: #690; }
+
+.cm-s-mdn-like .cm-operator { color: #cda869; }
+.cm-s-mdn-like .cm-comment { color:#777; font-weight:normal; }
+.cm-s-mdn-like .cm-string { color:#07a; font-style:italic; }
+.cm-s-mdn-like .cm-string-2 { color:#bd6b18; } /*?*/
+.cm-s-mdn-like .cm-meta { color: #000; } /*?*/
+.cm-s-mdn-like .cm-builtin { color: #9B7536; } /*?*/
+.cm-s-mdn-like .cm-tag { color: #997643; }
+.cm-s-mdn-like .cm-attribute { color: #d6bb6d; } /*?*/
+.cm-s-mdn-like .cm-header { color: #FF6400; }
+.cm-s-mdn-like .cm-hr { color: #AEAEAE; }
+.cm-s-mdn-like .cm-link {   color:#ad9361; font-style:italic; text-decoration:none; }
+.cm-s-mdn-like .cm-error { border-bottom: 1px solid red; }
+
+div.cm-s-mdn-like .CodeMirror-activeline-background {background: #efefff;}
+div.cm-s-mdn-like span.CodeMirror-matchingbracket {outline:1px solid grey; color: inherit;}
+
+.cm-s-mdn-like.CodeMirror { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFcAAAAyCAYAAAAp8UeFAAAHvklEQVR42s2b63bcNgyEQZCSHCdt2vd/0tWF7I+Q6XgMXiTtuvU5Pl57ZQKkKHzEAOtF5KeIJBGJ8uvL599FRFREZhFx8DeXv8trn68RuGaC8TRfo3SNp9dlDDHedyLyTUTeRWStXKPZrjtpZxaRw5hPqozRs1N8/enzIiQRWcCgy4MUA0f+XWliDhyL8Lfyvx7ei/Ae3iQFHyw7U/59pQVIMEEPEz0G7XiwdRjzSfC3UTtz9vchIntxvry5iMgfIhJoEflOz2CQr3F5h/HfeFe+GTdLaKcu9L8LTeQb/R/7GgbsfKedyNdoHsN31uRPWrfZ5wsj/NzzRQHuToIdU3ahwnsKPxXCjJITuOsi7XLc7SG/v5GdALs7wf8JjTFiB5+QvTEfRyGOfX3Lrx8wxyQi3sNq46O7QahQiCsRFgqddjBouVEHOKDgXAQHD9gJCr5sMKkEdjwsarG/ww3BMHBU7OBjXnzdyY7SfCxf5/z6ATccrwlKuwC/jhznnPF4CgVzhhVf4xp2EixcBActO75iZ8/fM9zAs2OMzKdslgXWJ9XG8PQoOAMA5fGcsvORgv0doBXyHrCwfLJAOwo71QLNkb8n2Pl6EWiR7OCibtkPaz4Kc/0NNAze2gju3zOwekALDaCFPI5vjPFmgGY5AZqyGEvH1x7QfIb8YtxMnA/b+QQ0aQDAwc6JMFg8CbQZ4qoYEEHbRwNojuK3EHwd7VALSgq+MNDKzfT58T8qdpADrgW0GmgcAS1lhzztJmkAzcPNOQbsWEALBDSlMKUG0Eq4CLAQWvEVQ9WU57gZJwZtgPO3r9oBTQ9WO8TjqXINx8R0EYpiZEUWOF3FxkbJkgU9B2f41YBrIj5ZfsQa0M5kTgiAAqM3ShXLgu8XMqcrQBvJ0CL5pnTsfMB13oB8athpAq2XOQmcGmoACCLydx7nToa23ATaSIY2ichfOdPTGxlasXMLaL0MLZAOwAKIM+y8CmicobGdCcbbK9DzN+yYGVoNNI5iUKTMyYOjPse4A8SM1MmcXgU0toOq1yO/v8FOxlASyc7TgeYaAMBJHcY1CcCwGI/TK4AmDbDyKYBBtFUkRwto8gygiQEaByFgJ00BH2M8JWwQS1nafDXQCidWyOI8AcjDCSjCLk8ngObuAm3JAHAdubAmOaK06V8MNEsKPJOhobSprwQa6gD7DclRQdqcwL4zxqgBrQcabUiBLclRDKAlWp+etPkBaNMA0AKlrHwTdEByZAA4GM+SNluSY6wAzcMNewxmgig5Ks0nkrSpBvSaQHMdKTBAnLojOdYyGpQ254602ZILPdTD1hdlggdIm74jbTp8vDwF5ZYUeLWGJpWsh6XNyXgcYwVoJQTEhhTYkxzZjiU5npU2TaB979TQehlaAVq4kaGpiPwwwLkYUuBbQwocyQTv1tA0+1UFWoJF3iv1oq+qoSk8EQdJmwHkziIF7oOZk14EGitibAdjLYYK78H5vZOhtWpoI0ATGHs0Q8OMb4Ey+2bU2UYztCtA0wFAs7TplGLRVQCcqaFdGSPCeTI1QNIC52iWNzof6Uib7xjEp07mNNoUYmVosVItHrHzRlLgBn9LFyRHaQCtVUMbtTNhoXWiTOO9k/V8BdAc1Oq0ArSQs6/5SU0hckNy9NnXqQY0PGYo5dWJ7nINaN6o958FWin27aBaWRka1r5myvLOAm0j30eBJqCxHLReVclxhxOEN2JfDWjxBtAC7MIH1fVaGdoOp4qJYDgKtKPSFNID2gSnGldrCqkFZ+5UeQXQBIRrSwocbdZYQT/2LwRahBPBXoHrB8nxaGROST62DKUbQOMMzZIC9abkuELfQzQALWTnDNAm8KHWFOJgJ5+SHIvTPcmx1xQyZRhNL5Qci689aXMEaN/uNIWkEwDAvFpOZmgsBaaGnbs1NPa1Jm32gBZAIh1pCtG7TSH4aE0y1uVY4uqoFPisGlpP2rSA5qTecWn5agK6BzSpgAyD+wFaqhnYoSZ1Vwr8CmlTQbrcO3ZaX0NAEyMbYaAlyquFoLKK3SPby9CeVUPThrSJmkCAE0CrKUQadi4DrdSlWhmah0YL9z9vClH59YGbHx1J8VZTyAjQepJjmXwAKTDQI3omc3p1U4gDUf6RfcdYfrUp5ClAi2J3Ba6UOXGo+K+bQrjjssitG2SJzshaLwMtXgRagUNpYYoVkMSBLM+9GGiJZMvduG6DRZ4qc04DMPtQQxOjEtACmhO7K1AbNbQDEggZyJwscFpAGwENhoBeUwh3bWolhe8BTYVKxQEWrSUn/uhcM5KhvUu/+eQu0Lzhi+VrK0PrZZNDQKs9cpYUuFYgMVpD4/NxenJTiMCNqdUEUf1qZWjppLT5qSkkUZbCwkbZMSuVnu80hfSkzRbQeqCZSAh6huR4VtoM2gHAlLf72smuWgE+VV7XpE25Ab2WFDgyhnSuKbs4GuGzCjR+tIoUuMFg3kgcWKLTwRqanJQ2W00hAsenfaApRC42hbCvK1SlE0HtE9BGgneJO+ELamitD1YjjOYnNYVcraGhtKkW0EqVVeDx733I2NH581k1NNxNLG0i0IJ8/NjVaOZ0tYZ2Vtr0Xv7tPV3hkWp9EFkgS/J0vosngTaSoaG06WHi+xObQkaAdlbanP8B2+2l0f90LmUAAAAASUVORK5CYII=); }
diff --git a/app/gui/html/vendor/codemirror/theme/midnight.css b/app/gui/html/vendor/codemirror/theme/midnight.css
new file mode 100644
index 0000000..468d87d
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/midnight.css
@@ -0,0 +1,43 @@
+/* Based on the theme at http://bonsaiden.github.com/JavaScript-Garden */
+
+/*<!--match-->*/
+.cm-s-midnight span.CodeMirror-matchhighlight { background: #494949; }
+.cm-s-midnight.CodeMirror-focused span.CodeMirror-matchhighlight { background: #314D67 !important; }
+
+/*<!--activeline-->*/
+.cm-s-midnight .CodeMirror-activeline-background {background: #253540 !important;}
+
+.cm-s-midnight.CodeMirror {
+    background: #0F192A;
+    color: #D1EDFF;
+}
+
+.cm-s-midnight.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+
+.cm-s-midnight div.CodeMirror-selected {background: #314D67 !important;}
+.cm-s-midnight .CodeMirror-gutters {background: #0F192A; border-right: 1px solid;}
+.cm-s-midnight .CodeMirror-linenumber {color: #D0D0D0;}
+.cm-s-midnight .CodeMirror-cursor {
+    border-left: 1px solid #F8F8F0 !important;
+}
+
+.cm-s-midnight span.cm-comment {color: #428BDD;}
+.cm-s-midnight span.cm-atom {color: #AE81FF;}
+.cm-s-midnight span.cm-number {color: #D1EDFF;}
+
+.cm-s-midnight span.cm-property, .cm-s-midnight span.cm-attribute {color: #A6E22E;}
+.cm-s-midnight span.cm-keyword {color: #E83737;}
+.cm-s-midnight span.cm-string {color: #1DC116;}
+
+.cm-s-midnight span.cm-variable {color: #FFAA3E;}
+.cm-s-midnight span.cm-variable-2 {color: #FFAA3E;}
+.cm-s-midnight span.cm-def {color: #4DD;}
+.cm-s-midnight span.cm-bracket {color: #D1EDFF;}
+.cm-s-midnight span.cm-tag {color: #449;}
+.cm-s-midnight span.cm-link {color: #AE81FF;}
+.cm-s-midnight span.cm-error {background: #F92672; color: #F8F8F0;}
+
+.cm-s-midnight .CodeMirror-matchingbracket {
+  text-decoration: underline;
+  color: white !important;
+}
diff --git a/app/gui/html/vendor/codemirror/theme/monokai.css b/app/gui/html/vendor/codemirror/theme/monokai.css
new file mode 100644
index 0000000..7ac601a
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/monokai.css
@@ -0,0 +1,29 @@
+/* Based on Sublime Text's Monokai theme */
+
+.cm-s-monokai.CodeMirror {background: #272822; color: #f8f8f2;}
+.cm-s-monokai div.CodeMirror-selected {background: #49483E !important;}
+.cm-s-monokai .CodeMirror-gutters {background: #272822; border-right: 0px;}
+.cm-s-monokai .CodeMirror-linenumber {color: #d0d0d0;}
+.cm-s-monokai .CodeMirror-cursor {border-left: 1px solid #f8f8f0 !important;}
+
+.cm-s-monokai span.cm-comment {color: #75715e;}
+.cm-s-monokai span.cm-atom {color: #ae81ff;}
+.cm-s-monokai span.cm-number {color: #ae81ff;}
+
+.cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute {color: #a6e22e;}
+.cm-s-monokai span.cm-keyword {color: #f92672;}
+.cm-s-monokai span.cm-string {color: #e6db74;}
+
+.cm-s-monokai span.cm-variable {color: #a6e22e;}
+.cm-s-monokai span.cm-variable-2 {color: #9effff;}
+.cm-s-monokai span.cm-def {color: #fd971f;}
+.cm-s-monokai span.cm-bracket {color: #f8f8f2;}
+.cm-s-monokai span.cm-tag {color: #f92672;}
+.cm-s-monokai span.cm-link {color: #ae81ff;}
+.cm-s-monokai span.cm-error {background: #f92672; color: #f8f8f0;}
+
+.cm-s-monokai .CodeMirror-activeline-background {background: #373831 !important;}
+.cm-s-monokai .CodeMirror-matchingbracket {
+  text-decoration: underline;
+  color: white !important;
+}
diff --git a/app/gui/html/vendor/codemirror/theme/neat.css b/app/gui/html/vendor/codemirror/theme/neat.css
new file mode 100644
index 0000000..115083b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/neat.css
@@ -0,0 +1,12 @@
+.cm-s-neat span.cm-comment { color: #a86; }
+.cm-s-neat span.cm-keyword { line-height: 1em; font-weight: bold; color: blue; }
+.cm-s-neat span.cm-string { color: #a22; }
+.cm-s-neat span.cm-builtin { line-height: 1em; font-weight: bold; color: #077; }
+.cm-s-neat span.cm-special { line-height: 1em; font-weight: bold; color: #0aa; }
+.cm-s-neat span.cm-variable { color: black; }
+.cm-s-neat span.cm-number, .cm-s-neat span.cm-atom { color: #3a3; }
+.cm-s-neat span.cm-meta {color: #555;}
+.cm-s-neat span.cm-link { color: #3a3; }
+
+.cm-s-neat .CodeMirror-activeline-background {background: #e8f2ff !important;}
+.cm-s-neat .CodeMirror-matchingbracket {outline:1px solid grey; color:black !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/night.css b/app/gui/html/vendor/codemirror/theme/night.css
new file mode 100644
index 0000000..016e55e
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/night.css
@@ -0,0 +1,24 @@
+/* Loosely based on the Midnight Textmate theme */
+
+.cm-s-night.CodeMirror { background: #0a001f; color: #f8f8f8; }
+.cm-s-night div.CodeMirror-selected { background: #447 !important; }
+.cm-s-night .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; }
+.cm-s-night .CodeMirror-linenumber { color: #f8f8f8; }
+.cm-s-night .CodeMirror-cursor { border-left: 1px solid white !important; }
+
+.cm-s-night span.cm-comment { color: #6900a1; }
+.cm-s-night span.cm-atom { color: #845dc4; }
+.cm-s-night span.cm-number, .cm-s-night span.cm-attribute { color: #ffd500; }
+.cm-s-night span.cm-keyword { color: #599eff; }
+.cm-s-night span.cm-string { color: #37f14a; }
+.cm-s-night span.cm-meta { color: #7678e2; }
+.cm-s-night span.cm-variable-2, .cm-s-night span.cm-tag { color: #99b2ff; }
+.cm-s-night span.cm-variable-3, .cm-s-night span.cm-def { color: white; }
+.cm-s-night span.cm-bracket { color: #8da6ce; }
+.cm-s-night span.cm-comment { color: #6900a1; }
+.cm-s-night span.cm-builtin, .cm-s-night span.cm-special { color: #ff9e59; }
+.cm-s-night span.cm-link { color: #845dc4; }
+.cm-s-night span.cm-error { color: #9d1e15; }
+
+.cm-s-night .CodeMirror-activeline-background {background: #1C005A !important;}
+.cm-s-night .CodeMirror-matchingbracket {outline:1px solid grey; color:white !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/paraiso-dark.css b/app/gui/html/vendor/codemirror/theme/paraiso-dark.css
new file mode 100644
index 0000000..ddefc55
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/paraiso-dark.css
@@ -0,0 +1,34 @@
+/*
+
+    Name:       Paraíso (Dark)
+    Author:     Jan T. Sott
+
+    Color scheme by Jan T. Sott (https://github.com/idleberg/Paraiso-CodeMirror)
+    Inspired by the art of Rubens LP (http://www.rubenslp.com.br)
+
+*/
+
+.cm-s-paraiso-dark.CodeMirror {background: #2f1e2e; color: #b9b6b0;}
+.cm-s-paraiso-dark div.CodeMirror-selected {background: #41323f !important;}
+.cm-s-paraiso-dark .CodeMirror-gutters {background: #2f1e2e; border-right: 0px;}
+.cm-s-paraiso-dark .CodeMirror-linenumber {color: #776e71;}
+.cm-s-paraiso-dark .CodeMirror-cursor {border-left: 1px solid #8d8687 !important;}
+
+.cm-s-paraiso-dark span.cm-comment {color: #e96ba8;}
+.cm-s-paraiso-dark span.cm-atom {color: #815ba4;}
+.cm-s-paraiso-dark span.cm-number {color: #815ba4;}
+
+.cm-s-paraiso-dark span.cm-property, .cm-s-paraiso-dark span.cm-attribute {color: #48b685;}
+.cm-s-paraiso-dark span.cm-keyword {color: #ef6155;}
+.cm-s-paraiso-dark span.cm-string {color: #fec418;}
+
+.cm-s-paraiso-dark span.cm-variable {color: #48b685;}
+.cm-s-paraiso-dark span.cm-variable-2 {color: #06b6ef;}
+.cm-s-paraiso-dark span.cm-def {color: #f99b15;}
+.cm-s-paraiso-dark span.cm-bracket {color: #b9b6b0;}
+.cm-s-paraiso-dark span.cm-tag {color: #ef6155;}
+.cm-s-paraiso-dark span.cm-link {color: #815ba4;}
+.cm-s-paraiso-dark span.cm-error {background: #ef6155; color: #8d8687;}
+
+.cm-s-paraiso-dark .CodeMirror-activeline-background {background: #4D344A !important;}
+.cm-s-paraiso-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/paraiso-light.css b/app/gui/html/vendor/codemirror/theme/paraiso-light.css
new file mode 100644
index 0000000..8afb14b
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/paraiso-light.css
@@ -0,0 +1,34 @@
+/*
+
+    Name:       Paraíso (Light)
+    Author:     Jan T. Sott
+
+    Color scheme by Jan T. Sott (https://github.com/idleberg/Paraiso-CodeMirror)
+    Inspired by the art of Rubens LP (http://www.rubenslp.com.br)
+
+*/
+
+.cm-s-paraiso-light.CodeMirror {background: #e7e9db; color: #41323f;}
+.cm-s-paraiso-light div.CodeMirror-selected {background: #b9b6b0 !important;}
+.cm-s-paraiso-light .CodeMirror-gutters {background: #e7e9db; border-right: 0px;}
+.cm-s-paraiso-light .CodeMirror-linenumber {color: #8d8687;}
+.cm-s-paraiso-light .CodeMirror-cursor {border-left: 1px solid #776e71 !important;}
+
+.cm-s-paraiso-light span.cm-comment {color: #e96ba8;}
+.cm-s-paraiso-light span.cm-atom {color: #815ba4;}
+.cm-s-paraiso-light span.cm-number {color: #815ba4;}
+
+.cm-s-paraiso-light span.cm-property, .cm-s-paraiso-light span.cm-attribute {color: #48b685;}
+.cm-s-paraiso-light span.cm-keyword {color: #ef6155;}
+.cm-s-paraiso-light span.cm-string {color: #fec418;}
+
+.cm-s-paraiso-light span.cm-variable {color: #48b685;}
+.cm-s-paraiso-light span.cm-variable-2 {color: #06b6ef;}
+.cm-s-paraiso-light span.cm-def {color: #f99b15;}
+.cm-s-paraiso-light span.cm-bracket {color: #41323f;}
+.cm-s-paraiso-light span.cm-tag {color: #ef6155;}
+.cm-s-paraiso-light span.cm-link {color: #815ba4;}
+.cm-s-paraiso-light span.cm-error {background: #ef6155; color: #776e71;}
+
+.cm-s-paraiso-light .CodeMirror-activeline-background {background: #CFD1C4 !important;}
+.cm-s-paraiso-light .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/pastel-on-dark.css b/app/gui/html/vendor/codemirror/theme/pastel-on-dark.css
new file mode 100644
index 0000000..df95699
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/pastel-on-dark.css
@@ -0,0 +1,49 @@
+/**
+ * Pastel On Dark theme ported from ACE editor
+ * @license MIT
+ * @copyright AtomicPages LLC 2014
+ * @author Dennis Thompson, AtomicPages LLC
+ * @version 1.1
+ * @source https://github.com/atomicpages/codemirror-pastel-on-dark-theme
+ */
+
+.cm-s-pastel-on-dark.CodeMirror {
+	background: #2c2827;
+	color: #8F938F;
+	line-height: 1.5;
+	font-family: consolas, Courier, monospace;
+	font-size: 14px;
+}
+.cm-s-pastel-on-dark div.CodeMirror-selected { background: rgba(221,240,255,0.2) !important; }
+.cm-s-pastel-on-dark .CodeMirror-gutters {
+	background: #34302f;
+	border-right: 0px;
+	padding: 0 3px;
+}
+.cm-s-pastel-on-dark .CodeMirror-linenumber { color: #8F938F; }
+.cm-s-pastel-on-dark .CodeMirror-cursor { border-left: 1px solid #A7A7A7 !important; }
+.cm-s-pastel-on-dark span.cm-comment { color: #A6C6FF; }
+.cm-s-pastel-on-dark span.cm-atom { color: #DE8E30; }
+.cm-s-pastel-on-dark span.cm-number { color: #CCCCCC; }
+.cm-s-pastel-on-dark span.cm-property { color: #8F938F; }
+.cm-s-pastel-on-dark span.cm-attribute { color: #a6e22e; }
+.cm-s-pastel-on-dark span.cm-keyword { color: #AEB2F8; }
+.cm-s-pastel-on-dark span.cm-string { color: #66A968; }
+.cm-s-pastel-on-dark span.cm-variable { color: #AEB2F8; }
+.cm-s-pastel-on-dark span.cm-variable-2 { color: #BEBF55; }
+.cm-s-pastel-on-dark span.cm-variable-3 { color: #DE8E30; }
+.cm-s-pastel-on-dark span.cm-def { color: #757aD8; }
+.cm-s-pastel-on-dark span.cm-bracket { color: #f8f8f2; }
+.cm-s-pastel-on-dark span.cm-tag { color: #C1C144; }
+.cm-s-pastel-on-dark span.cm-link { color: #ae81ff; }
+.cm-s-pastel-on-dark span.cm-qualifier,.cm-s-pastel-on-dark span.cm-builtin { color: #C1C144; }
+.cm-s-pastel-on-dark span.cm-error {
+	background: #757aD8;
+	color: #f8f8f0;
+}
+.cm-s-pastel-on-dark .CodeMirror-activeline-background { background: rgba(255, 255, 255, 0.031) !important; }
+.cm-s-pastel-on-dark .CodeMirror-matchingbracket {
+	border: 1px solid rgba(255,255,255,0.25);
+	color: #8F938F !important;
+	margin: -1px -1px 0 -1px;
+}
diff --git a/app/gui/html/vendor/codemirror/theme/rubyblue.css b/app/gui/html/vendor/codemirror/theme/rubyblue.css
new file mode 100644
index 0000000..b556139
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/rubyblue.css
@@ -0,0 +1,23 @@
+.cm-s-rubyblue { font-family: Trebuchet, Verdana, sans-serif; }	/* - customized editor font - */
+
+.cm-s-rubyblue.CodeMirror { background: #112435; color: white; }
+.cm-s-rubyblue div.CodeMirror-selected { background: #38566F !important; }
+.cm-s-rubyblue .CodeMirror-gutters { background: #1F4661; border-right: 7px solid #3E7087; }
+.cm-s-rubyblue .CodeMirror-linenumber { color: white; }
+.cm-s-rubyblue .CodeMirror-cursor { border-left: 1px solid white !important; }
+
+.cm-s-rubyblue span.cm-comment { color: #999; font-style:italic; line-height: 1em; }
+.cm-s-rubyblue span.cm-atom { color: #F4C20B; }
+.cm-s-rubyblue span.cm-number, .cm-s-rubyblue span.cm-attribute { color: #82C6E0; }
+.cm-s-rubyblue span.cm-keyword { color: #F0F; }
+.cm-s-rubyblue span.cm-string { color: #F08047; }
+.cm-s-rubyblue span.cm-meta { color: #F0F; }
+.cm-s-rubyblue span.cm-variable-2, .cm-s-rubyblue span.cm-tag { color: #7BD827; }
+.cm-s-rubyblue span.cm-variable-3, .cm-s-rubyblue span.cm-def { color: white; }
+.cm-s-rubyblue span.cm-bracket { color: #F0F; }
+.cm-s-rubyblue span.cm-link { color: #F4C20B; }
+.cm-s-rubyblue span.CodeMirror-matchingbracket { color:#F0F !important; }
+.cm-s-rubyblue span.cm-builtin, .cm-s-rubyblue span.cm-special { color: #FF9D00; }
+.cm-s-rubyblue span.cm-error { color: #AF2018; }
+
+.cm-s-rubyblue .CodeMirror-activeline-background {background: #173047 !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/solarized.css b/app/gui/html/vendor/codemirror/theme/solarized.css
new file mode 100644
index 0000000..9c2e914
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/solarized.css
@@ -0,0 +1,181 @@
+/*
+Solarized theme for code-mirror
+http://ethanschoonover.com/solarized
+*/
+
+/*
+Solarized color pallet
+http://ethanschoonover.com/solarized/img/solarized-palette.png
+*/
+
+.solarized.base03 { color: #002b36; }
+.solarized.base02 { color: #073642; }
+.solarized.base01 { color: #586e75; }
+.solarized.base00 { color: #657b83; }
+.solarized.base0 { color: #839496; }
+.solarized.base1 { color: #93a1a1; }
+.solarized.base2 { color: #eee8d5; }
+.solarized.base3  { color: #fdf6e3; }
+.solarized.solar-yellow  { color: #b58900; }
+.solarized.solar-orange  { color: #cb4b16; }
+.solarized.solar-red { color: #dc322f; }
+.solarized.solar-magenta { color: #d33682; }
+.solarized.solar-violet  { color: #6c71c4; }
+.solarized.solar-blue { color: #268bd2; }
+.solarized.solar-cyan { color: #2aa198; }
+.solarized.solar-green { color: #859900; }
+
+/* Color scheme for code-mirror */
+
+.cm-s-solarized {
+  line-height: 1.45em;
+  font-family: Menlo,Monaco,"Andale Mono","lucida console","Courier New",monospace !important;
+  color-profile: sRGB;
+  rendering-intent: auto;
+}
+.cm-s-solarized.cm-s-dark {
+  color: #839496;
+  background-color:  #002b36;
+  text-shadow: #002b36 0 1px;
+}
+.cm-s-solarized.cm-s-light {
+  background-color: #fdf6e3;
+  color: #657b83;
+  text-shadow: #eee8d5 0 1px;
+}
+
+.cm-s-solarized .CodeMirror-widget {
+  text-shadow: none;
+}
+
+
+.cm-s-solarized .cm-keyword { color: #cb4b16 }
+.cm-s-solarized .cm-atom { color: #d33682; }
+.cm-s-solarized .cm-number { color: #d33682; }
+.cm-s-solarized .cm-def { color: #2aa198; }
+
+.cm-s-solarized .cm-variable { color: #268bd2; }
+.cm-s-solarized .cm-variable-2 { color: #b58900; }
+.cm-s-solarized .cm-variable-3 { color: #6c71c4; }
+
+.cm-s-solarized .cm-property { color: #2aa198; }
+.cm-s-solarized .cm-operator {color: #6c71c4;}
+
+.cm-s-solarized .cm-comment { color: #586e75; font-style:italic; }
+
+.cm-s-solarized .cm-string { color: #859900; }
+.cm-s-solarized .cm-string-2 { color: #b58900; }
+
+.cm-s-solarized .cm-meta { color: #859900; }
+.cm-s-solarized .cm-qualifier { color: #b58900; }
+.cm-s-solarized .cm-builtin { color: #d33682; }
+.cm-s-solarized .cm-bracket { color: #cb4b16; }
+.cm-s-solarized .CodeMirror-matchingbracket { color: #859900; }
+.cm-s-solarized .CodeMirror-nonmatchingbracket { color: #dc322f; }
+.cm-s-solarized .cm-tag { color: #93a1a1 }
+.cm-s-solarized .cm-attribute {  color: #2aa198; }
+.cm-s-solarized .cm-header { color: #586e75; }
+.cm-s-solarized .cm-quote { color: #93a1a1; }
+.cm-s-solarized .cm-hr {
+  color: transparent;
+  border-top: 1px solid #586e75;
+  display: block;
+}
+.cm-s-solarized .cm-link { color: #93a1a1; cursor: pointer; }
+.cm-s-solarized .cm-special { color: #6c71c4; }
+.cm-s-solarized .cm-em {
+  color: #999;
+  text-decoration: underline;
+  text-decoration-style: dotted;
+}
+.cm-s-solarized .cm-strong { color: #eee; }
+.cm-s-solarized .cm-tab:before {
+  content: "➤";   /*visualize tab character*/
+  color: #586e75;
+  position:absolute;
+}
+.cm-s-solarized .cm-error,
+.cm-s-solarized .cm-invalidchar {
+  color: #586e75;
+  border-bottom: 1px dotted #dc322f;
+}
+
+.cm-s-solarized.cm-s-dark .CodeMirror-selected {
+  background: #073642;
+}
+
+.cm-s-solarized.cm-s-light .CodeMirror-selected {
+  background: #eee8d5;
+}
+
+/* Editor styling */
+
+
+
+/* Little shadow on the view-port of the buffer view */
+.cm-s-solarized.CodeMirror {
+  -moz-box-shadow: inset 7px 0 12px -6px #000;
+  -webkit-box-shadow: inset 7px 0 12px -6px #000;
+  box-shadow: inset 7px 0 12px -6px #000;
+}
+
+/* Gutter border and some shadow from it  */
+.cm-s-solarized .CodeMirror-gutters {
+  padding: 0 15px 0 10px;
+  box-shadow: 0 10px 20px black;
+  border-right: 1px solid;
+}
+
+/* Gutter colors and line number styling based of color scheme (dark / light) */
+
+/* Dark */
+.cm-s-solarized.cm-s-dark .CodeMirror-gutters {
+  background-color: #073642;
+  border-color: #00232c;
+}
+
+.cm-s-solarized.cm-s-dark .CodeMirror-linenumber {
+  text-shadow: #021014 0 -1px;
+}
+
+/* Light */
+.cm-s-solarized.cm-s-light .CodeMirror-gutters {
+  background-color: #eee8d5;
+  border-color: #eee8d5;
+}
+
+/* Common */
+.cm-s-solarized .CodeMirror-linenumber {
+  color: #586e75;
+}
+
+.cm-s-solarized .CodeMirror-gutter .CodeMirror-gutter-text {
+  color: #586e75;
+}
+
+.cm-s-solarized .CodeMirror-lines {
+  padding-left: 5px;
+}
+
+.cm-s-solarized .CodeMirror-lines .CodeMirror-cursor {
+  border-left: 1px solid #819090;
+}
+
+/*
+Active line. Negative margin compensates left padding of the text in the
+view-port
+*/
+.cm-s-solarized.cm-s-dark .CodeMirror-activeline-background {
+  background: rgba(255, 255, 255, 0.10);
+}
+.cm-s-solarized.cm-s-light .CodeMirror-activeline-background {
+  background: rgba(0, 0, 0, 0.10);
+}
+
+/*
+View-port and gutter both get little noise background to give it a real feel.
+*/
+.cm-s-solarized.CodeMirror,
+.cm-s-solarized .CodeMirror-gutters {
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAQAAAAHUWYVAABFFUlEQVQYGbzBCeDVU/74/6fj9HIcx/FRHx9JCFmzMyGRURhLZIkUsoeRfUjS2FNDtr6WkMhO9sm+S8maJfu+Jcsg+/o/c+Z4z/t97/vezy3z+z8ekGlnYICG/o7gdk+wmSHZ1z4pJItqapjoKXWahm8NmV6eOTbWUOp6/6a/XIg6GQqmenJ2lDHyvCFZ2cBDbmtHA043VFhHwXxClWmeYAdLhV00Bd85go8VmaFCkbVkzlQENzfBDZ5gtN7HwF0KDrTwJ0dypSOzpaKCMwQHKTIreYIxlmhXTzTWkVm+LTynZhiSBT3RZQ7aGfjGEd3qyXQ1FDymqbKxpspERQN2MiRjNZlFFQXfCNFm9nM1zpAsoYjmtRTc5ajwuaXc5xrWskT97RaKzAGe5ARHhVUsDbjKklziiX5WROcJwSNCNI+9w1Jwv4Zb2r7lCMZ4oq5C0EdTx+2GzNuKpJ+iFf38JEWkHJn9DNF7mmBDITrWEg0VWL3pHU20tSZnuqWu+R3BtYa8XxV1HO7GyD32UkOpL/yDloINFTmvtId+nmAjxRw40VMwVKiwrKLE4bK5UOVntYwhOcSSXKrJHKPJedocpGjVz/ZMIbnYUPB10/eKCrs5apqpgVmWzBYWpmtKHecJPjaUuEgRDDaU0oZghCJ6zNMQ5ZhDYx05r5v2muQdM0EILtXUsaKiQX9WMEUotagQzFbUNN6NUPC2nm5pxEWGCjMc3GdJHjSU2kORLK/JGSrkfGEIjncU/CYUnOipoYemwj8tST9NsJmB7TUVXtbUtXATJVZXBMvYeTXJfobgJUPmGMP/yFaWonaa6BcFO3nqcIqCozSZoZoSr1g4zJOzuyGnxTEX3lUEJ7WcZgme8ddaWvWJo2AJR9DZU3CUIbhCSG6ybSwN6qtJVnCU2svDTP2ZInOw2cBTrqtQahtNZn9NcJ4l2NaSmSkkP1noZWnVwkLmdUPOwLZEwy2Z3S3R+4rIG9hcbpPXHFVWcQdZkn2FOta3cKWQnNRC5g1LsJah4GCzSVsKnCOY5OAFRTBekyyryeyilhFKva75r4Mc0aWanGEaThcy31s439KKxTzJYY5WTHPU1FtIHjQU3Oip4xlNzj/lBw23dYZVliQa7WAXf4shetcQfatI+jWRDBPmyNeW6A1P5kdDgyYJlba0BIM8BZu1JfrFwItyjcAMR3K0BWOIrtMEXyhyrlVEx3ui5dUBjmB/Q3CXW85R4mBD0s7B+4q5tKUjOlb9qqmhi5AZ6GFIC5HXtOobdYGlVdMVbNJ8toNTFcHxnoL+muBagcctjWnbNMuR00uI7nQESwg5q2qqrKWIfrNUmeQocY6HuyxJV02wj36w00yhpmUFenv4p6fUkZYqLyuinx2RGOjhCXYyJF84oiU00YMOOhhquNdfbOB7gU88pY4xJO8LVdp6/q2voeB4R04vIdhSE40xZObx1HGGJ/ja0LBthFInKaLPPFzuCaYaoj8JjPME8yoyxo6zlBqkiUZYgq00OYMswbWO5NGmq+xhipxHLRW29ARjNKXO0wRnear8XSg4XFPLKEPUS1GqvyLwiuBUoa7zpZ0l5xxFwWmWZC1H5h5FwU8eQ7K+g8UcVY6TMQreVQT/8uQ8Z+ALIXnSEa2pYZQneE9RZbSBNYXfWYJzW/h/4j4Dp1tYVcFIC5019Vyi4ThPqSFCzjGWaHQTBU8q6vrVwgxP9Lkm840imWKpcLCjYTtrKuwvsKSnrvHCXGkSMk9p6lhckfRpIeis+N2PiszT+mFLspyGleUhDwcLrZqmyeylxwjBcKHEapqkmyangyLZRVOijwOtCY5SsG5zL0OwlCJ4y5KznF3EUNDDrinwiyLZRzOXtlBbK5ITHFGLp8Q0R6ab6mS7enI2cFrxOyHvOCFaT1HThS1krjCwqWeurCkk+willhCC+RSZnRXBiZaC5RXRIZYKp2lyfrHwiKPKR0JDzrdU2EFgpidawlFDR6FgXUMNa+g1FY3bUQh2cLCwosRdnuQTS/S+JVrGLeWIvtQUvONJxlqSQYYKpwoN2kaocLjdVsis4Mk80ESF2YpSkzwldjHkjFCUutI/r+EHDU8oCs6yzL3PhWiEooZdFMkymlas4AcI3KmoMMNSQ3tHzjGWCrcJJdYyZC7QFGwjRL9p+MrRkAGWzIaWCn9W0F3TsK01c2ZvQw0byvxuQU0r1lM0qJO7wW0kRIMdDTtXEdzi4VIh+EoIHm0mWtAtpCixlabgn83fKTI7anJe9ST7WIK1DMGpQmYeA58ImV6ezOGOzK2Kgq01pd60cKWiUi9Lievb/0vIDPHQ05Kzt4ddPckQBQtoaurjyHnek/nKzpQLrVgKPjIkh2v4uyezpv+Xoo7fPFXaGFp1vaLKxQ4uUpQQS5VuQs7BCq4xRJv7fwpVvvFEB3j+620haOuocqMhWd6TTPAEx+mdFNGHdranFe95WrWmIvlY4F1Dle2ECgc6cto7SryuqGGGha0tFQ5V53migUKmg6XKAo4qS3mik+0OZpAhOLeZKicacgaYcyx5hypYQE02ZA4xi/pNhOQxR4klNKyqacj+mpxnLTnnGSo85++3ZCZq6lrZkXlGEX3o+C9FieccJbZWVFjC0Yo1FZnJhoYMFoI1hEZ9r6hwg75HwzBNhbZCdJEfJwTPGzJvaKImw1yYX1HDAmpXR+ZJQ/SmgqMNVQb5vgamGwLtt7VwvP7Qk1xpiM5x5Cyv93E06MZmgs0Nya2azIKOYKCGBQQW97RmhKNKF02JZqHEJ4o58qp7X5EcZmc56trXEqzjCBZ1MFGR87Ql2tSTs6CGxS05PTzRQorkbw7aKoKXFDXsYW42VJih/q+FP2BdTzDTwVqOYB13liM50vG7wy28qagyuIXMeQI/Oqq8bcn5wJI50xH00CRntyfpL1T4hydYpoXgNiFzoIUTDZnLNRzh4TBHwbYGDvZkxmlyJloyr6tRihpeUG94GnKtIznREF0tzJG/OOr73JBcrSh1k6WuTprgLU+mnSGnv6Zge0NNz+kTDdH8nuAuTdJDCNb21LCiIuqlYbqGzT3RAoZofQfjFazkqeNWdYaGvYTM001EW2oKPvVk1ldUGSgUtHFwjKM1h9jnFcmy5lChoLNaQMGGDsYbKixlaMBmmsx1QjCfflwTfO/gckW0ruZ3jugKR3R5W9hGUWqCgxuFgsuaCHorotGKzGaeZB9DMsaTnKCpMtwTvOzhYk0rdrArKCqcaWmVk1+F372ur1YkKxgatI8Qfe1gIX9wE9FgS8ESmuABIXnRUbCapcKe+nO7slClSZFzpV/LkLncEb1qiO42fS3R855Su2mCLh62t1SYZZYVmKwIHjREF2uihTzB20JOkz7dkxzYQnK0UOU494wh+VWRc6Un2kpTaVgLDFEkJ/uhzRcI0YKGgpGWOlocBU/a4fKoJ/pEaNV6jip3+Es9VXY078rGnmAdf7t9ylPXS34RBSuYPs1UecZTU78WanhBCHpZ5sAoTz0LGZKjPf9TRypqWEiTvOFglL1fCEY3wY/++rbk7C8bWebA6p6om6PgOL2kp44TFJlVNBXae2rqqdZztOJpT87GQsE9jqCPIe9VReZuQ/CIgacsyZdCpIScSYqcZk8r+nsyCzhyfhOqHGOIvrLknC8wTpFcaYiGC/RU1NRbUeUpocQOnkRpGOrIOcNRx+1uA0UrzhSSt+VyS3SJpnFWkzNDqOFGIWcfR86DnmARTQ1HKIL33ExPiemeOhYSSjzlSUZZuE4TveoJLnBUOFof6KiysCbnAEcZgcUNTDOwkqWu3RWtmGpZwlHhJENdZ3miGz0lJlsKnjbwqSHQjpxnFDlTLLwqJPMZMjd7KrzkSG7VsxXBZE+F8YZkb01Oe00yyRK9psh5SYh29ySPKBo2ylNht7ZkZnsKenjKNJu9PNEyZpaCHv4Kt6RQsLvAVp7M9kIimmCUwGeWqLMmGuIotYMmWNpSahkhZw9FqZsVnKJhsjAHvtHMsTM9fCI06Dx/u3vfUXCqfsKRc4oFY2jMsoo/7DJDwZ1CsIKnJu+J9ldkpmiCxQx1rWjI+T9FwcWWzOuaYH0Hj7klNRVWEQpmaqosakiGNTFHdjS/qnUdmf0NJW5xsL0HhimCCZZSRzmSPTXJQ4aaztAwtZnoabebJ+htCaZ7Cm535ByoqXKbX1WRc4Eh2MkRXWzImVc96Cj4VdOKVxR84VdQsIUM8Psoou2byVHyZFuq7O8otbSQ2UAoeEWTudATLGSpZzVLlXVkPU2Jc+27lsw2jmg5T5VhbeE3BT083K9WsTTkFU/Osi0rC5lRlpwRHUiesNS0sOvmqGML1aRbPAxTJD9ZKtxuob+hhl8cwYGWpJ8nub7t5p6coYbMovZ1BTdaKn1jYD6h4GFDNFyT/Kqe1XCXphXHOKLZmuRSRdBPEfVUXQzJm5YGPGGJdvAEr7hHNdGZnuBvrpciGmopOLf5N0uVMy0FfYToJk90uUCbJupaVpO53UJXR2bVpoU00V2KOo4zMFrBd0Jtz2pa0clT5Q5L8IpQ177mWQejPMEJhuQjS10ref6HHjdEhy1P1EYR7GtO0uSsKJQYLiTnG1rVScj5lyazpqWGl5uBbRWl7m6ixGOOnEsMJR7z8J0n6KMnCdxhiNYQCoZ6CmYLnO8omC3MkW3bktlPmEt/VQQHejL3+dOE5FlPdK/Mq8hZxxJtLyRrepLThYKbLZxkSb5W52vYxNOaOxUF0yxMUPwBTYqCzy01XayYK0sJyWBLqX0MwU5CzoymRzV0EjjeUeLgDpTo6ij42ZAzvD01dHUUTPLU96MdLbBME8nFBn7zJCMtJcZokn8YoqU0FS5WFKyniHobguMcmW8N0XkWZjkyN3hqOMtS08r+/xTBwpZSZ3qiVRX8SzMHHjfUNFjgHEPmY9PL3ykEzxkSre/1ZD6z/NuznuB0RcE1TWTm9zRgfUWVJiG6yrzgmWPXC8EAR4Wxhlad0ZbgQyEz3pG5RVEwwDJH2mgKpjcTiCOzn1lfUWANFbZ2BA8balnEweJC9J0iuaeZoI+ippFCztEKVvckR2iice1JvhVytrQwUAZpgsubCPaU7xUe9vWnaOpaSBEspalykhC9bUlOMpT42ZHca6hyrqKmw/wMR8H5ZmdFoBVJb03O4UL0tSNnvIeRmkrLWqrs78gcrEn2tpcboh0UPOW3UUR9PMk4T4nnNKWmCjlrefhCwxRNztfmIQVdDElvS4m1/WuOujoZCs5XVOjtKPGokJzsYCtFYoWonSPT21DheU/wWhM19FcElwqNGOsp9Q8N/cwXaiND1MmeL1Q5XROtYYgGeFq1aTMsoMmcrKjQrOFQTQ1fmBYhmW6o8Jkjc7iDJRTBIo5kgJD5yMEYA3srCg7VFKwiVJkmRCc5ohGOKhsYMn/XBLdo5taZjlb9YAlGWRimqbCsoY7HFAXLa5I1HPRxMMsQDHFkWtRNniqT9UEeNjcE7RUlrCJ4R2CSJuqlKHWvJXjAUNcITYkenuBRB84TbeepcqTj3zZyFJzgYQdHnqfgI0ddUwS6GqWpsKWhjq9cV0vBAEMN2znq+EBfIWT+pClYw5xsTlJU6GeIBsjGmmANTzJZiIYpgrM0Oa8ZMjd7NP87jxhqGOhJlnQtjuQpB+8aEE00wZFznSJPyHxgH3HkPOsJFvYk8zqCHzTs1BYOa4J3PFU+UVRZxlHDM4YavlNUuMoRveiZA2d7grMNc2g+RbSCEKzmgYsUmWmazFJyoiOZ4KnyhKOGRzWJa0+moyV4TVHDzn51Awtqaphfk/lRQ08FX1iiqxTB/kLwd0VynKfEvI6cd4XMV5bMhZ7gZUWVzYQ6Nm2BYzxJbw3bGthEUUMfgbGeorae6DxHtJoZ6alhZ0+ytiVoK1R4z5PTrOECT/SugseEOlb1MMNR4VRNcJy+V1Hg9ONClSZFZjdHlc6W6FBLdJja2MC5hhpu0DBYEY1TFGwiFAxRRCsYkiM9JRb0JNMVkW6CZYT/2EiTGWmo8k+h4FhDNE7BvppoTSFnmCV5xZKzvcCdDo7VVPnIU+I+Rc68juApC90MwcFCsJ5hDqxgScYKreruyQwTqrzoqDCmhWi4IbhB0Yrt3RGa6GfDv52rKXWhh28dyZaWUvcZeMTBaZoSGyiCtRU5J8iviioHaErs7Jkj61syVzTTgOcUOQ8buFBTYWdL5g3T4qlpe0+wvD63heAXRfCCIed9RbCsp2CiI7raUOYOTU13N8PNHvpaGvayo4a3LLT1lDrVEPT2zLUlheB1R+ZTRfKWJ+dcocLJfi11vyJ51lLqJ0WD7tRwryezjiV5W28uJO9qykzX8JDe2lHl/9oyBwa2UMfOngpXCixvKdXTk3wrsKmiVYdZIqsoWEERjbcUNDuiaQomGoIbFdEHmsyWnuR+IeriKDVLnlawlyNHKwKlSU631PKep8J4Q+ayjkSLKYLhalNHlYvttb6fHm0p6OApsZ4l2VfdqZkjuysy6ysKLlckf1KUutCTs39bmCgEyyoasIWlVaMF7mgmWtBT8Kol5xpH9IGllo8cJdopcvZ2sImlDmMIbtDk3KIpeNiS08lQw11NFPTwVFlPP6pJ2gvRfI7gQUfmNAtf6Gs0wQxDsKGlVBdF8rCa3jzdwMaGHOsItrZk7hAyOzpK9VS06j5F49b0VNGOOfKs3lDToMsMBe9ZWtHFEgxTJLs7qrygKZjUnmCYoeAqeU6jqWuLJup4WghOdvCYJnrSkSzoyRkm5M2StQwVltPkfCAk58tET/CSg+8MUecmotMEnhBKfWBIZsg2ihruMJQaoIm+tkTLKEqspMh00w95gvFCQRtDwTT1gVDDSEVdlwqZfxoQRbK0g+tbiBZxzKlpnpypejdDwTaeOvorMk/IJE10h9CqRe28hhLbe0pMsdSwv4ZbhKivo2BjDWfL8UKJgeavwlwb5KlwhyE4u4XkGE2ytZCznKLCDZZq42VzT8HLCrpruFbIfOIINmh/qCdZ1ZBc65kLHR1Bkyf5zn6pN3SvGKIlFNGplhrO9QSXanLOMQTLCa0YJCRrCZm/CZmrLTm7WzCK4GJDiWUdFeYx1LCFg3NMd0XmCuF3Y5rITLDUsYS9zoHVzwnJoYpSTQoObyEzr4cFBNqYTopoaU/wkyLZ2lPhX/5Y95ulxGTV7KjhWrOZgl8MyUUafjYraNjNU1N3IWcjT5WzWqjwtoarHSUObGYO3GCJZpsBlnJGPd6ZYLyl1GdCA2625IwwJDP8GUKymbzuyPlZlvTUsaUh5zFDhRWFzPKKZLAlWdcQbObgF9tOqOsmB1dqcqYJmWstFbZRRI9poolmqiLnU0POvxScpah2iSL5UJNzgScY5+AuIbpO0YD3NCW+dLMszFSdFCWGqG6eVq2uYVNDdICGD6W7EPRWZEY5gpsE9rUkS3mijzzJnm6UpUFXG1hCUeVoS5WfNcFpblELL2qqrCvMvRfd45oalvKU2tiQ6ePJOVMRXase9iTtLJztPxJKLWpo2CRDcJwn2sWSLKIO1WQWNTCvpVUvOZhgSC40JD0dOctaSqzkCRbXsKlb11Oip6PCJ0IwSJM31j3akRxlP7Rwn6aGaUL0qiLnJkvB3xWZ2+Q1TfCwpQH3G0o92UzmX4o/oJNQMMSQc547wVHhdk+VCw01DFYEnTxzZKAm74QmeNNR1w6WzEhNK15VJzuCdxQ53dRUDws5KvwgBMOEgpcVNe0hZI6RXT1Jd0cyj5nsaEAHgVmGaJIlWdsc5Ui2ElrRR6jrRAttNMEAIWrTDFubkZaok7/AkzfIwfuWVq0jHzuCK4QabtLUMVPB3kJ0oyHTSVFlqMALilJf2Rf8k5aaHtMfayocLBS8L89oKoxpJvnAkDPa0qp5DAUTHKWmCcnthlou8iCKaFFLHWcINd1nyIwXqrSxMNmSs6KmoL2QrKuWtlQ5V0120xQ5vRyZS1rgFkWwhiOwiuQbR0OOVhQM9iS3tiXp4RawRPMp5tDletOOBL95MpM01dZTBM9pkn5qF010rIeHFcFZhmSGpYpTsI6nwhqe5C9ynhlpp5ophuRb6WcJFldkVnVEwwxVfrVkvnWUuNLCg5bgboFHPDlDPDmnK7hUrWiIbjadDclujlZcaokOFup4Ri1kacV6jmrrK1hN9bGwpKEBQ4Q6DvIUXOmo6U5LqQM6EPyiKNjVkPnJkDPNEaxhiFay5ExW1NXVUGqcpYYdPcGiCq7z/TSlbhL4pplWXKd7NZO5QQFrefhRQW/NHOsqcIglc4UhWklR8K0QzbAw08CBDnpbgqXdeD/QUsM4RZXDFBW6WJKe/mFPdH0LtBgiq57wFLzlyQzz82qYx5D5WJP5yVJDW01BfyHnS6HKO/reZqId1WGa4Hkh2kWodJ8i6KoIPlAj2hPt76CzXsVR6koPRzWTfKqIentatYpQw2me4AA3y1Kind3SwoOKZDcFXTwl9tWU6mfgRk9d71sKtlNwrjnYw5tC5n5LdKiGry3JKNlHEd3oaMCFHrazBPMp/uNJ+V7IudcSbeOIdjUEdwl0VHCOZo5t6YluEuaC9mQeMgSfOyKnYGFHcIeQ84yQWbuJYJpZw5CzglDH7gKnWqqM9ZTaXcN0TeYhR84eQtJT76JJ1lREe7WnnvsMmRc9FQ7SBBM9mV3lCUdmHk/S2RAMt0QjFNFqQpWjDPQ01DXWUdDBkXziKPjGEP3VP+zIWU2t7im41FOloyWzn/L6dkUy3VLDaZ6appgDLHPjJEsyvJngWEPUyVBiAaHCTEXwrLvSEbV1e1gKJniicWorC1MUrVjB3uDhJE/wgSOzk1DXpk0k73qCM8xw2UvD5kJmDUfOomqMpWCkJRlvKXGmoeBm18USjVIk04SClxTB6YrgLAPLWYK9HLUt5cmc0vYES8GnTeRc6skZbQkWdxRsIcyBRzx1DbTk9FbU0caTPOgJHhJKnOGIVhQqvKmo0llRw9sabrZkDtdg3PqaKi9oatjY8B+G371paMg6+mZFNNtQ04mWBq3rYLOmtWWQp8KJnpy9DdFensyjdqZ+yY40VJlH8wcdLzC8PZnvHMFUTZUrDTkLyQaGus5X5LzpYAf3i+e/ZlhqGqWhh6Ou6xTR9Z6oi5AZZtp7Mj2EEm8oSpxiYZCHU/1fbGdNNNRRoZMhmilEb2gqHOEJDtXkHK/JnG6IrvbPCwV3NhONVdS1thBMs1T4QOBcTWa2IzhMk2nW5Kyn9tXUtpv9RsG2msxk+ZsQzRQacJncpgke0+T8y5Fzj8BiGo7XlJjaTIlpQs7KFjpqGnKuoyEPeIKnFMkZHvopgh81ySxNFWvJWcKRs70j2FOT012IllEEO1n4pD1513Yg2ssQPOThOkvyrqHUdEXOSEsihmBbTbKX1kLBPWqWkLOqJbjB3GBIZmoa8qWl4CG/iZ7oiA72ZL7TJNeZUY7kFQftDcHHluBzRbCegzMtrRjVQpX2lgoPKKLJAkcbMl01XK2p7yhL8pCBbQ3BN2avJgKvttcrWDK3CiUOVxQ8ZP+pqXKyIxnmBymCg5vJjNfkPK4+c8cIfK8ocVt7kmfd/I5SR1hKvCzUtb+lhgc00ZaO6CyhIQP1Uv4yIZjload72PXX0OIJvnFU+0Zf6MhsJwTfW0r0UwQfW4LNLZl5HK261JCZ4qnBaAreVAS3WrjV0LBnNDUNNDToCEeFfwgcb4gOEqLRhirWkexrCEYKVV711DLYEE1XBEsp5tpTGjorkomKYF9FDXv7fR3BGwbettSxnyL53MBPjsxDZjMh+VUW9NRxq1DhVk+FSxQcaGjV9Pawv6eGByw5qzoy7xk4RsOShqjJwWKe/1pEEfzkobeD/dQJmpqedcyBTy2sr4nGNRH0c0SPWTLrqAc0OQcb/gemKgqucQT7ySWKCn2EUotoCvpZct7RO2sy/QW0IWcXd7pQRQyZVwT2USRO87uhjioTLKV2brpMUcMQRbKH/N2T+UlTpaMls6cmc6CCNy3JdYYSUzzJQ4oSD3oKLncULOiJvjBEC2oqnCJkJluCYy2ZQ5so9YYlZ1VLlQU1mXEW1jZERwj/MUSRc24TdexlqLKfQBtDTScJUV8FszXBEY5ktpD5Ur9hYB4Nb1iikw3JoYpkKX+RodRKFt53MMuRnKSpY31PwYaGaILh3wxJGz9TkTPEETxoCWZrgvOlmyMzxFEwVJE5xZKzvyJ4WxEc16Gd4Xe3Weq4XH2jKRikqOkGQ87hQnC7wBmGYLAnesX3M+S87eFATauuN+Qcrh7xIxXJbUIdMw3JGE3ylCWzrieaqCn4zhGM19TQ3z1oH1AX+pWEqIc7wNGAkULBo/ZxRaV9NNyh4Br3rCHZzbzmSfawBL0dNRwpW1kK9mxPXR9povcdrGSZK9c2k0xwFGzjuniCtRSZCZ6ccZ7gaktmgAOtKbG/JnOkJrjcQTdFMsxRQ2cLY3WTIrlCw1eWKn8R6pvt4GFDso3QoL4a3nLk3G6JrtME3dSenpx7PNFTmga0EaJTLQ061sEeQoWXhSo9LTXsaSjoJQRXeZLtDclbCrYzfzHHeaKjHCVOUkQHO3JeEepr56mhiyaYYKjjNU+Fed1wS5VlhWSqI/hYUdDOkaxiKehoyOnrCV5yBHtbWFqTHCCwtpDcYolesVR5yUzTZBb3RNMd0d6WP+SvhuBmRcGxnuQzT95IC285cr41cLGQ6aJJhmi4TMGempxeimBRQw1tFKV+8jd6KuzoSTqqDxzRtpZkurvKEHxlqXKRIjjfUNNXQsNOsRScoWFLT+YeRZVD3GRN0MdQcKqQjHDMrdGGVu3iYJpQx3WGUvfbmxwFfR20WBq0oYY7LMFhhgYtr8jpaEnaOzjawWWaTP8mMr0t/EPDPoqcnxTBI5o58L7uoWnMrpoqPwgVrlAUWE+V+TQl9rawoyP6QGAlQw2TPRX+YSkxyBC8Z6jhHkXBgQL7WII3DVFnRfCrBfxewv9D6xsyjys4VkhWb9pUU627JllV0YDNHMku/ldNMMXDEo4aFnAkk4U6frNEU4XgZUPmEKHUl44KrzmYamjAbh0JFvGnaTLPu1s9jPCwjFpYiN7z1DTOk/nc07CfDFzmCf7i+bfNHXhDtLeBXzTBT5rkMvWOIxpl4EMh2LGJBu2syDnAEx2naEhHDWMMzPZEhygyS1mS5RTJr5ZkoKbEUoYqr2kqdDUE8ztK7OaIntJkFrIECwv8LJTaVx5XJE86go8dFeZ3FN3rjabCAYpoYEeC9zzJVULBbmZhDyd7ko09ydpNZ3nm2Kee4FPPXHnYEF1nqOFEC08LUVcDvYXkJHW8gTaKCk9YGOeIJhqiE4ToPEepdp7IWFjdwnWaufGMwJJCMtUTTBBK9BGCOy2tGGrJTHIwyEOzp6aPzNMOtlZkDvcEWpP5SVNhfkvDxhmSazTJXYrM9U1E0xwFVwqZQwzJxw6+kGGGUj2FglGGmnb1/G51udRSMNlTw6GGnCcUwVcOpmsqTHa06o72sw1RL02p9z0VbnMLOaIX3QKaYKSCFQzBKEUNHTSc48k53RH9wxGMtpQa5KjjW0W0n6XCCCG4yxNNdhQ4R4l1Ff+2sSd6UFHiIEOyqqFgT01mEUMD+joy75jPhOA+oVVLm309FR4yVOlp4RhLiScNmSmaYF5Pw0STrOIoWMSR2UkRXOMp+M4SHW8o8Zoi6OZgjKOaFar8zZDzkWzvKOjkKBjmCXby8JahhjXULY4KlzgKLvAwxVGhvyd4zxB1d9T0piazmKLCVZY5sKiD0y2ZSYrkUEPUbIk+dlQ4SJHTR50k1DPaUWIdTZW9NJwnJMOECgd7ou/MnppMJ02O1VT4Wsh85MnZzcFTngpXGKo84qmwgKbCL/orR/SzJ2crA+t6Mp94KvxJUeIbT3CQu1uIdlQEOzlKfS3UMcrTiFmOuroocrZrT2AcmamOKg8YomeEKm/rlT2sociMaybaUlFhuqHCM2qIJ+rg4EcDFymiDSxzaHdPcpE62pD5kyM5SBMoA1PaUtfIthS85ig1VPiPPYXgYEMNk4Qq7TXBgo7oT57gPUdwgCHzhIVFPFU6OYJzHAX9m5oNrVjeE61miDrqQ4VSa1oiURTsKHC0IfjNwU2WzK6eqK8jWln4g15TVBnqmDteCJ501PGAocJhhqjZdtBEB6lnhLreFJKxmlKbeGrqLiSThVIbCdGzloasa6lpMQXHCME2boLpJgT7yWaemu6wBONbqGNVRS0PKIL7LckbjmQtR7K8I5qtqel+T/ChJTNIKLjdUMNIRyvOEko9YYl2cwQveBikCNawJKcLBbc7+JM92mysNvd/Fqp8a0k6CNEe7cnZrxlW0wQXaXjaktnRwNOGZKYiONwS7a1JVheq3WgJHlQUGKHKmp4KAxXR/ULURcNgoa4zhKSLpZR3kxRRb0NmD0OFn+UCS7CzI1nbP6+o4x47QZE5xRCt3ZagnYcvmpYQktXdk5YKXTzBC57kKEe0VVuiSYqapssMS3C9p2CKkHOg8B8Pa8p5atrIw3qezIWanMGa5HRDNF6RM9wcacl0N+Q8Z8hsIkSnaIIdHRUOEebAPy1zbCkhM062FCJtif7PU+UtoVXzWKqM1PxXO8cfdruhFQ/a6x3JKYagvVDhQEtNiyiiSQ7OsuRsZUku0CRNDs4Sog6KKjsZgk2bYJqijgsEenoKeniinRXBn/U3lgpPdyDZynQx8IiioMnCep5Ky8mjGs6Wty0l1hUQTcNWswS3WRp2kCNZwJG8omG8JphPUaFbC8lEfabwP7VtM9yoaNCAjpR41VNhrD9LkbN722v0CoZMByFzhaW+MyzRYEWFDQwN2M4/JiT76PuljT3VU/A36eaIThb+R9oZGOAJ9tewkgGvqOMNRWYjT/Cwu99Q8LqDE4TgbLWxJ1jaDDAERsFOFrobgjUsBScaguXU8kKm2RL19tRypSHnHNlHiIZqgufs4opgQdVdwxBNNFBR6kVFqb8ogimOzB6a6HTzrlDHEpYaxjiiA4TMQobkDg2vejjfwJGWmnbVFAw3H3hq2NyQfG7hz4aC+w3BbwbesG0swYayvpAs6++Ri1Vfzx93mFChvyN5xVHTS+0p9aqCAxyZ6ZacZyw5+7uuQkFPR9DDk9NOiE7X1PCYJVjVUqq7JlrHwWALF5nfHNGjApdpqgzx5OwilDhCiDYTgnc9waGW4BdLNNUQvOtpzDOWHDH8D7TR/A/85KljEQu3NREc4Pl/6B1Hhc8Umb5CsKMmGC9EPcxoT2amwHNCmeOEnOPbklnMkbOgIvO5UMOpQrS9UGVdt6iH/fURjhI/WOpaW9OKLYRod6HCUEdOX000wpDZQ6hwg6LgZfOqo1RfT/CrJzjekXOGhpc1VW71ZLbXyyp+93ILbC1kPtIEYx0FIx1VDrLoVzXRKRYWk809yYlC9ImcrinxtabKnzRJk3lAU1OLEN1j2zrYzr2myHRXJFf4h4QKT1qSTzTB5+ZNTzTRkAxX8FcLV2uS8eoQQ2aAkFzvCM72sJIcJET3WPjRk5wi32uSS9rfZajpWEvj9hW42F4o5NytSXYy8IKHay10VYdrcl4SkqscrXpMwyGOgtkajheSxdQqmpxP1L3t4R5PqasFnrQEjytq6qgp9Y09Qx9o4S1FzhUCn1kyHSzBWLemoSGvOqLNhZyBjmCaAUYpMgt4Ck7wBBMMwWKWgjsUwTaGVsxWC1mYoKiyqqeGKYqonSIRQ3KIkHO0pmAxTdBHkbOvfllfr+AA+7gnc50huVKYK393FOyg7rbPO/izI7hE4CnHHHnJ0ogNPRUGeUpsrZZTBJcrovUcJe51BPsr6GkJdhCCsZ6aTtMEb2pqWkqeVtDXE/QVggsU/Nl86d9RMF3DxvZTA58agu810RWawCiSzzXBeU3MMW9oyJUedvNEvQyNu1f10BSMddR1vaLCYpYa/mGocLSiYDcLbQz8aMn5iyF4xBNMs1P0QEOV7o5gaWGuzSeLue4tt3ro7y4Tgm4G/mopdZgl6q0o6KzJWE3mMksNr3r+a6CbT8g5wZNzT9O7fi/zpaOmnz3BRoqos+tv9zMbdpxsqDBOEewtJLt7cg5wtKKbvldpSzRRCD43VFheCI7yZLppggMVBS/KMAdHODJvOwq2NQSbKKKPLdFWQs7Fqo+mpl01JXYRgq8dnGLhTiFzqmWsUMdpllZdbKlyvSdYxhI9YghOtxR8LgSLWHK62mGGVoxzBE8LNWzqH9CUesQzFy5RQzTc56mhi6fgXEWwpKfE5Z7M05ZgZUPmo6auiv8YKzDYwWBLMErIbKHJvOwIrvEdhOBcQ9JdU1NHQ7CXn2XIDFBKU2WAgcX9UAUzDXWd5alwuyJ41Z9rjKLCL4aCp4WarhPm2rH+SaHUYE001JDZ2ZAzXPjdMpZWvC9wmqIB2lLhQ01D5jO06hghWMndbM7yRJMsoCj1vYbnFQVrW9jak3OlEJ3s/96+p33dEPRV5GxiqaGjIthUU6FFEZyqCa5qJrpBdzSw95IUnOPIrCUUjRZQFrbw5PR0R1qiYx3cb6nrWUMrBmmiBQxVHtTew5ICP/ip6g4hed/Akob/32wvBHsIOX83cI8hGeNeNPCIkPmXe8fPKx84OMSRM1MTdXSwjCZ4S30jVGhvqTRak/OVhgGazHuOCud5onEO1lJr6ecVyaOK6H7zqlBlIaHE0oroCgfvGJIdPcmfLNGLjpz7hZwZQpUbFME0A1cIJa7VNORkgfsMBatbKgwwJM9bSvQXeNOvbIjelg6WWvo5kvbKaJJNHexkKNHL9xRyFlH8Ti2riB5wVPhUk7nGkJnoCe428LR/wRGdYIlmWebCyxou1rCk4g/ShugBDX0V0ZQWkh0dOVsagkM0yV6OoLd5ye+pRlsCr0n+KiQrGuq5yJDzrTAXHtLUMduTDBVKrSm3eHL+6ijxhFDX9Z5gVU/wliHYTMiMFpKLNMEywu80wd3meoFmt6VbRMPenhrOc6DVe4pgXU8DnnHakLOIIrlF4FZPIw6R+zxBP0dyq6OOZ4Q5sLKCcz084ok+VsMMyQhNZmmBgX5xIXOEJTmi7VsGTvMTNdHHhpzdbE8Du2oKxgvBqQKdDDnTFOylCFaxR1syz2iqrOI/FEpNc3C6f11/7+ASS6l2inq2ciTrCCzgyemrCL5SVPjQkdPZUmGy2c9Sw9FtR1sS30RmsKPCS4rkIC/2U0MduwucYolGaPjKEyhzmiPYXagyWbYz8LWBDdzRimAXzxx4z8K9hpzlhLq+NiQ97HuKorMUfK/OVvC2JfiHUPCQI/q7J2gjK+tTDNxkCc4TMssqCs4TGtLVwQihyoAWgj9bosU80XGW6Ac9TJGziaUh5+hnFcHOnlaM1iRn29NaqGENTTTSUHCH2tWTeV0osUhH6psuVLjRUmGWhm6OZEshGeNowABHcJ2Bpy2ZszRcKkRXd2QuKVEeXnbfaEq825FguqfgfE2whlChSRMdron+LATTPQ2Z369t4B9C5gs/ylzv+CMmepIDPclFQl13W0rspPd1JOcbghGOEutqCv5qacURQl3dDKyvyJlqKXGPgcM9FfawJAMVmdcspcYKOZc4GjDYkFlK05olNMHyHn4zFNykyOxt99RkHlfwmiHo60l2EKI+mhreEKp080Tbug08BVPcgoqC5zWt+NLDTZ7oNSF51N1qie7Va3uCCwyZbkINf/NED6jzOsBdZjFN8oqG3wxVunqCSYYKf3EdhJyf9YWGf7tRU2oH3VHgPr1fe5J9hOgHd7xQ0y7qBwXr23aGErP0cm64JVjZwsOGqL+mhNgZmhJLW2oY4UhedsyBgzrCKrq7BmcpNVhR6jBPq64Vgi+kn6XE68pp8J5/+0wRHGOpsKenQn9DZntPzjRLZpDAdD2fnSgkG9tmIXnUwQ6WVighs7Yi2MxQ0N3CqYaCXkJ0oyOztMDJjmSSpcpvlrk0RMMOjmArQ04PRV1DO1FwhCVaUVPpKUM03JK5SxPsIWRu8/CGHi8UHChiqGFDTbSRJWeYUDDcH6vJWUxR4k1FXbMUwV6e4AJFXS8oMqsZKqzvYQ9DDQdZckY4aGsIhtlubbd2r3j4QBMoTamdPZk7O/Bf62lacZwneNjQoGcdVU7zJOd7ghsUHOkosagic6cnWc8+4gg285R6zZP5s1/LUbCKIznTwK36PkdwlOrl4U1LwfdCCa+IrvFkmgw1PCAUXKWo0sURXWcI2muKJlgyFzhynCY4RBOsqCjoI1R5zREco0n2Vt09BQtYSizgKNHfUmUrQ5UOCh51BFcLmY7umhYqXKQomOop8bUnWNNQcIiBcYaC6xzMNOS8JQQfeqKBmmglB+97ok/lfk3ygaHSyZaCRTzRxQo6GzLfa2jWBPepw+UmT7SQEJyiyRkhBLMVOfcoMjcK0eZChfUNzFAUzCsEN5vP/X1uP/n/aoMX+K+nw/Hjr/9xOo7j7Pju61tLcgvJpTWXNbfN5jLpi6VfCOviTktKlFusQixdEKWmEBUKNaIpjZRSSOXSgzaaKLdabrm1/9nZ+/f+vd/vz/v9+Xy+zZ7PRorYoZqyLrCwQdEAixxVOEXNNnjX2nUSRlkqGmWowk8lxR50JPy9Bo6qJXaXwNvREBvnThPEPrewryLhcAnj5WE15Fqi8W7R1sAuEu86S4ENikItFN4xkv9Af4nXSnUVcLiA9xzesFpivRRVeFKtsMRaKBhuSbjOELnAUtlSQUpXgdfB4Z1oSbnFEetbQ0IrAe+Y+pqnDcEJFj6S8LDZzZHwY4e3XONNlARraomNEt2bkvGsosA3ioyHm+6jCMbI59wqt4eeara28IzEmyPgoRaUOEDhTVdEJhmCoTWfC0p8aNkCp0oYqih2iqGi4yXeMkOsn4LdLLnmKfh/YogjNsPebeFGR4m9BJHLzB61XQ3BtpISfS2FugsK9FAtLWX1dCRcrCnUp44CNzuCowUZmxSRgYaE6Za0W2u/E7CVXCiI/UOR8aAm1+OSyE3mOUcwyc1zBBeoX1kiKy0Zfxck1Gsyulti11i83QTBF5Kg3pDQThFMVHiPSlK+0cSedng/VaS8bOZbtsBcTcZAR8JP5KeqQ1OYKAi20njdNNRpgnsU//K+JnaXJaGTomr7aYIphoRn9aeShJWKEq9LcozSF7QleEfDI5LYm5bgVkFkRwVDBCVu0DDIkGupo8TZBq+/pMQURYErJQmPKGKjNDkWOLx7Jd5QizdUweIaKrlP7SwJDhZvONjLkOsBBX9UpGxnydhXkfBLQ8IxgojQbLFnJf81JytSljclYYyEFyx0kVBvKWOFJmONpshGAcsduQY5giVNCV51eOdJYo/pLhbvM0uDHSevNKRcrKZIqnCtJeEsO95RoqcgGK4ocZcho1tTYtcZvH41pNQ7vA0WrhIfOSraIIntIAi+NXWCErdbkvrWwjRLrt0NKUdL6KSOscTOdMSOUtBHwL6OLA0vNSdynaWQEnCpIvKaIrJJEbvHkmuNhn6OjM8VkSGSqn1uYJCGHnq9I3aLhNME3t6GjIkO7xrNFumpyTNX/NrwX7CrIRiqqWijI9JO4d1iieykyfiposQIQ8YjjsjlBh6oHWbwRjgYJQn2NgSnNycmJAk3NiXhx44Sxykihxm8ybUwT1OVKySc7vi3OXVkdBJ4AyXBeksDXG0IhgtYY0lY5ahCD0ehborIk5aUWRJviMA7Xt5kyRjonrXENkm8yYqgs8VzgrJmClK20uMM3jRJ0FiQICQF9hdETlLQWRIb5ki6WDfWRPobvO6a4GP5mcOrNzDFELtTkONLh9dXE8xypEg7z8A9jkhrQ6Fhjlg/QVktJXxt4WXzT/03Q8IaQWSqIuEvloQ2mqC9Jfi7wRul4RX3pSPlzpoVlmCtI2jvKHCFhjcM3sN6lqF6HxnKelLjXWbwrpR4xzuCrTUZx2qq9oAh8p6ixCUGr78g8oyjRAtB5CZFwi80VerVpI0h+IeBxa6Zg6kWvpDHaioYYuEsRbDC3eOmC2JvGYLeioxGknL2UATNJN6hmtj1DlpLvDVmocYbrGCVJKOrg4X6DgddLA203BKMFngdJJFtFd7vJLm6KEpc5yjQrkk7M80SGe34X24nSex1Ra5Omgb71JKyg8SrU3i/kARKwWpH0kOGhKkObyfd0ZGjvyXlAkVZ4xRbYJ2irFMkFY1SwyWxr2oo4zlNiV+7zmaweFpT4kR3kaDAFW6xpSqzJay05FtYR4HmZhc9UxKbbfF2V8RG1MBmSaE+kmC6JnaRXK9gsiXhJHl/U0qM0WTcbyhwkYIvFGwjSbjfwhiJt8ZSQU+Bd5+marPMOkVkD0muxYLIfEuhh60x/J92itguihJSEMySVPQnTewnEm+620rTQEMsOfo4/kP/0ARvWjitlpSX7GxBgcMEsd3EEeYWvdytd+Saawi6aCIj1CkGb6Aj9rwhx16Cf3vAwFy5pyLhVonXzy51FDpdEblbkdJbUcEPDEFzQ8qNmhzzLTmmKWKbFCXeEuRabp6rxbvAtLF442QjQ+wEA9eL1xSR7Q0JXzlSHjJ4exq89yR0laScJ/FW6z4a73pFMEfDiRZvuvijIt86RaSFOl01riV2mD1UEvxGk/Geg5aWwGki1zgKPG9J2U8PEg8qYvMsZeytiTRXBMslCU8JSlxi8EabjwUldlDNLfzTUmCgxWsjqWCOHavYAqsknKFIO0yQ61VL5AVFxk6WhEaCAkdJgt9aSkzXlKNX2jEa79waYuc7gq0N3GDJGCBhoiTXUEPsdknCUE1CK0fwsiaylSF2uiDyO4XX3pFhNd7R4itFGc0k/ElBZwWvq+GC6szVeEoS/MZ+qylwpKNKv9Z469UOjqCjwlusicyTxG6VpNxcQ8IncoR4RhLbR+NdpGGmJWOcIzJGUuKPGpQg8rrG21dOMqQssJQ4RxH5jaUqnZuQ0F4Q+cjxLwPtpZbIAk3QTJHQWBE5S1BokoVtDd6lhqr9UpHSUxMcIYl9pojsb8h4SBOsMQcqvOWC2E8EVehqiJ1hrrAEbQxeK0NGZ0Gkq+guSRgniM23bIHVkqwx4hiHd7smaOyglyIyQuM978j4VS08J/A2G1KeMBRo4fBaSNhKUEZfQewVQ/C1I+MgfbEleEzCUw7mKXI0M3hd1EESVji8x5uQ41nxs1q4RMJCCXs7Iq9acpxn22oSDnQ/sJTxsCbHIYZiLyhY05TY0ZLIOQrGaSJDDN4t8pVaIrsqqFdEegtizc1iTew5Q4ayBDMUsQMkXocaYkc0hZua412siZ1rSXlR460zRJ5SlHGe5j801RLMlJTxtaOM3Q1pvxJ45zUlWFD7rsAbpfEm1JHxG0eh8w2R7QQVzBUw28FhFp5QZzq8t2rx2joqulYTWSuJdTYfWwqMFMcovFmSyJPNyLhE4E10pHzYjOC3huArRa571ZsGajQpQx38SBP5pyZB6lMU3khDnp0MBV51BE9o2E+TY5Ml2E8S7C0o6w1xvCZjf0HkVEHCzFoyNmqC+9wdcqN+Tp7jSDheE9ws8Y5V0NJCn2bk2tqSY4okdrEhx1iDN8cSudwepWmAGXKcJXK65H9to8jYQRH7SBF01ESUJdd0TayVInaWhLkOjlXE5irKGOnI6GSWGCJa482zBI9rCr0jyTVcEuzriC1vcr6mwFGSiqy5zMwxBH/TJHwjSPhL8+01kaaSUuMFKTcLEvaUePcrSmwn8DZrgikWb7CGPxkSjhQwrRk57tctmxLsb9sZvL9LSlyuSLlWkqOjwduo8b6Uv1DkmudIeFF2dHCgxVtk8dpIvHpBxhEOdhKk7OLIUSdJ+cSRY57B+0DgGUUlNfpthTfGkauzxrvTsUUaCVhlKeteTXCoJDCa2NOKhOmC4G1H8JBd4OBZReSRGkqcb/CO1PyLJTLB4j1q8JYaIutEjSLX8YKM+a6phdMsdLFUoV5RTm9JSkuDN8WcIon0NZMNZWh1q8C7SJEwV5HxrmnnTrf3KoJBlmCYI2ilSLlfEvlE4011NNgjgthzEua0oKK7JLE7HZHlEl60BLMVFewg4EWNt0ThrVNEVkkiTwpKXSWJzdRENgvKGq4IhjsiezgSFtsfCUq8qki5S1LRQeYQQ4nemmCkImWMw3tFUoUBZk4NOeZYEp4XRKTGa6wJjrWNHBVJR4m3FCnbuD6aak2WsMTh3SZImGCIPKNgsDpVwnsa70K31lCFJZYcwwSMFcQulGTsZuEaSdBXkPGZhu0FsdUO73RHjq8MPGGIfaGIbVTk6iuI3GFgucHrIQkmWSJdBd7BBu+uOryWAhY7+Lki9rK5wtEQzWwvtbqGhIMFwWRJsElsY4m9IIg9L6lCX0VklaPAYkfkZEGDnOWowlBJjtMUkcGK4Lg6EtoZInMUBVYLgn0UsdmCyCz7gIGHFfk+k1QwTh5We7A9x+IdJ6CvIkEagms0hR50eH9UnTQJ+2oiKyVlLFUE+8gBGu8MQ3CppUHesnjTHN4QB/UGPhCTHLFPHMFrCqa73gqObUJGa03wgbhHkrCfpEpzNLE7JDS25FMKhlhKKWKfCgqstLCPu1zBXy0J2ztwjtixBu8UTRn9LVtkmCN2iyFhtME70JHRQ1KVZXqKI/KNIKYMCYs1GUMEKbM1bKOI9LDXC7zbHS+bt+1MTWS9odA9DtrYtpbImQJ2VHh/lisEwaHqUk1kjKTAKknkBEXkbkdMGwq0dnhzLJF3NJH3JVwrqOB4Sca2hti75nmJN0WzxS6UxDYoEpxpa4htVlRjkYE7DZGzJVU72uC9IyhQL4i8YfGWSYLLNcHXloyz7QhNifmKSE9JgfGmuyLhc403Xm9vqcp6gXe3xuuv8F6VJNxkyTHEkHG2g0aKXL0MsXc1bGfgas2//dCONXiNLCX+5mB7eZIl1kHh7ajwpikyzlUUWOVOsjSQlsS+M0R+pPje/dzBXRZGO0rMtgQrLLG9VSu9n6CMXS3BhwYmSoIBhsjNBmZbgusE9BCPCP5triU4VhNbJfE+swSP27aayE8tuTpYYjtrYjMVGZdp2NpS1s6aBnKSHDsbKuplKbHM4a0wMFd/5/DmGyKrJSUaW4IBrqUhx0vyfzTBBLPIUcnZdrAkNsKR0sWRspumSns6Ch0v/qqIbBYUWKvPU/CFoyrDJGwSNFhbA/MlzKqjrO80hRbpKx0Jewsi/STftwGSlKc1JZyAzx05dhLEdnfQvhZOqiHWWEAHC7+30FuRcZUgaO5gpaIK+xsiHRUsqaPElTV40xQZQ107Q9BZE1nryDVGU9ZSQ47bmhBpLcYpUt7S+xuK/FiT8qKjwXYw5ypS2iuCv7q1gtgjhuBuB8LCFY5cUuCNtsQOFcT+4Ih9JX+k8Ea6v0iCIRZOtCT0Et00JW5UeC85Cg0ScK0k411HcG1zKtre3SeITBRk7WfwDhEvaYLTHP9le0m8By0JDwn4TlLW/aJOvGHxdjYUes+ScZigCkYQdNdEOhkiezgShqkx8ueKjI8lDfK2oNiOFvrZH1hS+tk7NV7nOmLHicGWEgubkXKdwdtZknCLJXaCpkrjZBtLZFsDP9CdxWsSr05Sxl6CMmoFbCOgryX40uDtamB7SVmXW4Ihlgpmq+00tBKUUa83WbjLUNkzDmY7cow1JDygyPGlhgGKYKz4vcV7QBNbJIgM11TUqZaMdwTeSguH6rOaw1JRKzaaGyxVm2EJ/uCIrVWUcZUkcp2grMsEjK+DMwS59jQk3Kd6SEq1d0S6uVmO4Bc1lDXTUcHjluCXEq+1OlBDj1pi9zgiXxnKuE0SqTXwhqbETW6RggMEnGl/q49UT2iCzgJvRwVXS2K/d6+ZkyUl7jawSVLit46EwxVljDZwoSQ20sDBihztHfk2yA8NVZghiXwrYHQdfKAOtzsayjhY9bY0yE2CWEeJ9xfzO423xhL5syS2TFJofO2pboHob0nY4GiAgRrvGQEDa/FWSsoaaYl0syRsEt3kWoH3B01shCXhTUWe9w3Bt44SC9QCh3eShQctwbaK2ApLroGCMlZrYqvlY3qYhM0aXpFkPOuoqJ3Dm6fxXrGwVF9gCWZagjPqznfkuMKQ8DPTQRO8ZqG1hPGKEm9IgpGW4DZDgTNriTxvFiq+Lz+0cKfp4wj6OCK9JSnzNSn9LFU7UhKZZMnYwcJ8s8yRsECScK4j5UOB95HFO0CzhY4xJxuCix0lDlEUeMdS6EZBkTsUkZ4K74dugyTXS7aNgL8aqjDfkCE0ZbwkCXpaWCKhl8P7VD5jxykivSyxyZrYERbe168LYu9ZYh86IkscgVLE7tWPKmJv11CgoyJltMEbrohtVAQfO4ImltiHEroYEs7RxAarVpY8AwXMcMReFOTYWe5iiLRQxJ5Q8DtJ8LQhWOhIeFESPGsILhbNDRljNbHzNRlTFbk2S3L0NOS6V1KFJYKUbSTcIIhM0wQ/s2TM0SRMNcQmSap3jCH4yhJZKSkwyRHpYYgsFeQ4U7xoCB7VVOExhXepo9ABBsYbvGWKXPME3lyH95YioZ0gssQRWWbI+FaSMkXijZXwgiTlYdPdkNLaETxlyDVIwqeaEus0aTcYcg0RVOkpR3CSJqIddK+90JCxzsDVloyrFd5ZAr4TBKfaWa6boEA7C7s6EpYaeFPjveooY72mjIccLHJ9HUwVlDhKkmutJDJBwnp1rvulJZggKDRfbXAkvC/4l3ozQOG9a8lxjx0i7nV4jSXc7vhe3OwIxjgSHjdEhhsif9YkPGlus3iLFDnWOFhtCZbJg0UbQcIaR67JjthoCyMEZRwhiXWyxO5QxI6w5NhT4U1WsJvDO60J34fW9hwzwlKij6ZAW9ne4L0s8C6XeBMEkd/LQy1VucBRot6QMlbivaBhoBgjqGiCJNhsqVp/S2SsG6DIONCR0dXhvWbJ+MRRZJkkuEjgDXJjFQW6SSL7GXK8Z2CZg7cVsbWGoKmEpzQ5elpiy8Ryg7dMkLLUEauzeO86CuwlSOlgYLojZWeJ9xM3S1PWfEfKl5ISLQ0MEKR8YOB2QfCxJBjrKPCN4f9MkaSsqoVXJBmP7EpFZ9UQfOoOFwSzBN4MQ8LsGrymlipcJQhmy0GaQjPqCHaXRwuCZwRbqK2Fg9wlClZqYicrIgMdZfxTQ0c7TBIbrChxmuzoKG8XRaSrIhhiyNFJkrC7oIAWMEOQa5aBekPCRknCo4IKPrYkvCDI8aYmY7WFtprgekcJZ3oLIqssCSMtFbQTJKwXYy3BY5oCh2iKPCpJOE+zRdpYgi6O2KmOAgvVCYaU4ySRek1sgyFhJ403QFHiVEmJHwtybO1gs8Hr5+BETQX3War0qZngYGgtVZtoqd6vFSk/UwdZElYqyjrF4HXUeFspIi9IGKf4j92pKGAdCYMVsbcV3kRF0N+R8LUd5PCsIGWoxDtBkCI0nKofdJQxT+LtZflvuc8Q3CjwWkq8KwUpHzkK/NmSsclCL0nseQdj5FRH5CNHSgtLiW80Of5HU9Hhlsga9bnBq3fEVltKfO5IaSTmGjjc4J0otcP7QsJUSQM8pEj5/wCuUuC2DWz8AAAAAElFTkSuQmCC");
+}
diff --git a/app/gui/html/vendor/codemirror/theme/the-matrix.css b/app/gui/html/vendor/codemirror/theme/the-matrix.css
new file mode 100644
index 0000000..0c3704a
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/the-matrix.css
@@ -0,0 +1,26 @@
+.cm-s-the-matrix.CodeMirror { background: #000000; color: #00FF00; }
+.cm-s-the-matrix div.CodeMirror-selected { background: #2D2D2D !important; }
+.cm-s-the-matrix .CodeMirror-gutters { background: #060; border-right: 2px solid #00FF00; }
+.cm-s-the-matrix .CodeMirror-linenumber { color: #FFFFFF; }
+.cm-s-the-matrix .CodeMirror-cursor { border-left: 1px solid #00FF00 !important; }
+
+.cm-s-the-matrix span.cm-keyword {color: #008803; font-weight: bold;}
+.cm-s-the-matrix span.cm-atom {color: #3FF;}
+.cm-s-the-matrix span.cm-number {color: #FFB94F;}
+.cm-s-the-matrix span.cm-def {color: #99C;}
+.cm-s-the-matrix span.cm-variable {color: #F6C;}
+.cm-s-the-matrix span.cm-variable-2 {color: #C6F;}
+.cm-s-the-matrix span.cm-variable-3 {color: #96F;}
+.cm-s-the-matrix span.cm-property {color: #62FFA0;}
+.cm-s-the-matrix span.cm-operator {color: #999}
+.cm-s-the-matrix span.cm-comment {color: #CCCCCC;}
+.cm-s-the-matrix span.cm-string {color: #39C;}
+.cm-s-the-matrix span.cm-meta {color: #C9F;}
+.cm-s-the-matrix span.cm-qualifier {color: #FFF700;}
+.cm-s-the-matrix span.cm-builtin {color: #30a;}
+.cm-s-the-matrix span.cm-bracket {color: #cc7;}
+.cm-s-the-matrix span.cm-tag {color: #FFBD40;}
+.cm-s-the-matrix span.cm-attribute {color: #FFF700;}
+.cm-s-the-matrix span.cm-error {color: #FF0000;}
+
+.cm-s-the-matrix .CodeMirror-activeline-background {background: #040;}
diff --git a/app/gui/html/vendor/codemirror/theme/tomorrow-night-eighties.css b/app/gui/html/vendor/codemirror/theme/tomorrow-night-eighties.css
new file mode 100644
index 0000000..85c2a4a
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/tomorrow-night-eighties.css
@@ -0,0 +1,34 @@
+/*
+
+    Name:       Tomorrow Night - Eighties
+    Author:     Chris Kempson
+
+    CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+    Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-tomorrow-night-eighties.CodeMirror {background: #000000; color: #CCCCCC;}
+.cm-s-tomorrow-night-eighties div.CodeMirror-selected {background: #2D2D2D !important;}
+.cm-s-tomorrow-night-eighties .CodeMirror-gutters {background: #000000; border-right: 0px;}
+.cm-s-tomorrow-night-eighties .CodeMirror-linenumber {color: #515151;}
+.cm-s-tomorrow-night-eighties .CodeMirror-cursor {border-left: 1px solid #6A6A6A !important;}
+
+.cm-s-tomorrow-night-eighties span.cm-comment {color: #d27b53;}
+.cm-s-tomorrow-night-eighties span.cm-atom {color: #a16a94;}
+.cm-s-tomorrow-night-eighties span.cm-number {color: #a16a94;}
+
+.cm-s-tomorrow-night-eighties span.cm-property, .cm-s-tomorrow-night-eighties span.cm-attribute {color: #99cc99;}
+.cm-s-tomorrow-night-eighties span.cm-keyword {color: #f2777a;}
+.cm-s-tomorrow-night-eighties span.cm-string {color: #ffcc66;}
+
+.cm-s-tomorrow-night-eighties span.cm-variable {color: #99cc99;}
+.cm-s-tomorrow-night-eighties span.cm-variable-2 {color: #6699cc;}
+.cm-s-tomorrow-night-eighties span.cm-def {color: #f99157;}
+.cm-s-tomorrow-night-eighties span.cm-bracket {color: #CCCCCC;}
+.cm-s-tomorrow-night-eighties span.cm-tag {color: #f2777a;}
+.cm-s-tomorrow-night-eighties span.cm-link {color: #a16a94;}
+.cm-s-tomorrow-night-eighties span.cm-error {background: #f2777a; color: #6A6A6A;}
+
+.cm-s-tomorrow-night-eighties .CodeMirror-activeline-background {background: #343600 !important;}
+.cm-s-tomorrow-night-eighties .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/twilight.css b/app/gui/html/vendor/codemirror/theme/twilight.css
new file mode 100644
index 0000000..19d6aba
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/twilight.css
@@ -0,0 +1,28 @@
+.cm-s-twilight.CodeMirror { background: #141414; color: #f7f7f7; } /**/
+.cm-s-twilight .CodeMirror-selected { background: #323232 !important; } /**/
+
+.cm-s-twilight .CodeMirror-gutters { background: #222; border-right: 1px solid #aaa; }
+.cm-s-twilight .CodeMirror-linenumber { color: #aaa; }
+.cm-s-twilight .CodeMirror-cursor { border-left: 1px solid white !important; }
+
+.cm-s-twilight .cm-keyword {  color: #f9ee98; } /**/
+.cm-s-twilight .cm-atom { color: #FC0; }
+.cm-s-twilight .cm-number { color:  #ca7841; } /**/
+.cm-s-twilight .cm-def { color: #8DA6CE; }
+.cm-s-twilight span.cm-variable-2, .cm-s-twilight span.cm-tag { color: #607392; } /**/
+.cm-s-twilight span.cm-variable-3, .cm-s-twilight span.cm-def { color: #607392; } /**/
+.cm-s-twilight .cm-operator { color: #cda869; } /**/
+.cm-s-twilight .cm-comment { color:#777; font-style:italic; font-weight:normal; } /**/
+.cm-s-twilight .cm-string { color:#8f9d6a; font-style:italic; } /**/
+.cm-s-twilight .cm-string-2 { color:#bd6b18 } /*?*/
+.cm-s-twilight .cm-meta { background-color:#141414; color:#f7f7f7; } /*?*/
+.cm-s-twilight .cm-builtin { color: #cda869; } /*?*/
+.cm-s-twilight .cm-tag { color: #997643; } /**/
+.cm-s-twilight .cm-attribute { color: #d6bb6d; } /*?*/
+.cm-s-twilight .cm-header { color: #FF6400; }
+.cm-s-twilight .cm-hr { color: #AEAEAE; }
+.cm-s-twilight .cm-link {   color:#ad9361; font-style:italic; text-decoration:none; } /**/
+.cm-s-twilight .cm-error { border-bottom: 1px solid red; }
+
+.cm-s-twilight .CodeMirror-activeline-background {background: #27282E !important;}
+.cm-s-twilight .CodeMirror-matchingbracket {outline:1px solid grey; color:white !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/vibrant-ink.css b/app/gui/html/vendor/codemirror/theme/vibrant-ink.css
new file mode 100644
index 0000000..0206225
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/vibrant-ink.css
@@ -0,0 +1,30 @@
+/* Taken from the popular Visual Studio Vibrant Ink Schema */
+
+.cm-s-vibrant-ink.CodeMirror { background: black; color: white; }
+.cm-s-vibrant-ink .CodeMirror-selected { background: #35493c !important; }
+
+.cm-s-vibrant-ink .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; }
+.cm-s-vibrant-ink .CodeMirror-linenumber { color: #d0d0d0; }
+.cm-s-vibrant-ink .CodeMirror-cursor { border-left: 1px solid white !important; }
+
+.cm-s-vibrant-ink .cm-keyword {  color: #CC7832; }
+.cm-s-vibrant-ink .cm-atom { color: #FC0; }
+.cm-s-vibrant-ink .cm-number { color:  #FFEE98; }
+.cm-s-vibrant-ink .cm-def { color: #8DA6CE; }
+.cm-s-vibrant-ink span.cm-variable-2, .cm-s-vibrant span.cm-tag { color: #FFC66D }
+.cm-s-vibrant-ink span.cm-variable-3, .cm-s-vibrant span.cm-def { color: #FFC66D }
+.cm-s-vibrant-ink .cm-operator { color: #888; }
+.cm-s-vibrant-ink .cm-comment { color: gray; font-weight: bold; }
+.cm-s-vibrant-ink .cm-string { color:  #A5C25C }
+.cm-s-vibrant-ink .cm-string-2 { color: red }
+.cm-s-vibrant-ink .cm-meta { color: #D8FA3C; }
+.cm-s-vibrant-ink .cm-builtin { color: #8DA6CE; }
+.cm-s-vibrant-ink .cm-tag { color: #8DA6CE; }
+.cm-s-vibrant-ink .cm-attribute { color: #8DA6CE; }
+.cm-s-vibrant-ink .cm-header { color: #FF6400; }
+.cm-s-vibrant-ink .cm-hr { color: #AEAEAE; }
+.cm-s-vibrant-ink .cm-link { color: blue; }
+.cm-s-vibrant-ink .cm-error { border-bottom: 1px solid red; }
+
+.cm-s-vibrant-ink .CodeMirror-activeline-background {background: #27282E !important;}
+.cm-s-vibrant-ink .CodeMirror-matchingbracket {outline:1px solid grey; color:white !important;}
diff --git a/app/gui/html/vendor/codemirror/theme/xq-dark.css b/app/gui/html/vendor/codemirror/theme/xq-dark.css
new file mode 100644
index 0000000..4a0b213
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/xq-dark.css
@@ -0,0 +1,49 @@
+/*
+Copyright (C) 2011 by MarkLogic Corporation
+Author: Mike Brevoort <mike at brevoort.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+.cm-s-xq-dark.CodeMirror { background: #0a001f; color: #f8f8f8; }
+.cm-s-xq-dark .CodeMirror-selected { background: #27007A !important; }
+.cm-s-xq-dark .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; }
+.cm-s-xq-dark .CodeMirror-linenumber { color: #f8f8f8; }
+.cm-s-xq-dark .CodeMirror-cursor { border-left: 1px solid white !important; }
+
+.cm-s-xq-dark span.cm-keyword {color: #FFBD40;}
+.cm-s-xq-dark span.cm-atom {color: #6C8CD5;}
+.cm-s-xq-dark span.cm-number {color: #164;}
+.cm-s-xq-dark span.cm-def {color: #FFF; text-decoration:underline;}
+.cm-s-xq-dark span.cm-variable {color: #FFF;}
+.cm-s-xq-dark span.cm-variable-2 {color: #EEE;}
+.cm-s-xq-dark span.cm-variable-3 {color: #DDD;}
+.cm-s-xq-dark span.cm-property {}
+.cm-s-xq-dark span.cm-operator {}
+.cm-s-xq-dark span.cm-comment {color: gray;}
+.cm-s-xq-dark span.cm-string {color: #9FEE00;}
+.cm-s-xq-dark span.cm-meta {color: yellow;}
+.cm-s-xq-dark span.cm-qualifier {color: #FFF700;}
+.cm-s-xq-dark span.cm-builtin {color: #30a;}
+.cm-s-xq-dark span.cm-bracket {color: #cc7;}
+.cm-s-xq-dark span.cm-tag {color: #FFBD40;}
+.cm-s-xq-dark span.cm-attribute {color: #FFF700;}
+.cm-s-xq-dark span.cm-error {color: #f00;}
+
+.cm-s-xq-dark .CodeMirror-activeline-background {background: #27282E !important;}
+.cm-s-xq-dark .CodeMirror-matchingbracket {outline:1px solid grey; color:white !important;}
\ No newline at end of file
diff --git a/app/gui/html/vendor/codemirror/theme/xq-light.css b/app/gui/html/vendor/codemirror/theme/xq-light.css
new file mode 100644
index 0000000..20b5c79
--- /dev/null
+++ b/app/gui/html/vendor/codemirror/theme/xq-light.css
@@ -0,0 +1,43 @@
+/*
+Copyright (C) 2011 by MarkLogic Corporation
+Author: Mike Brevoort <mike at brevoort.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+.cm-s-xq-light span.cm-keyword {line-height: 1em; font-weight: bold; color: #5A5CAD; }
+.cm-s-xq-light span.cm-atom {color: #6C8CD5;}
+.cm-s-xq-light span.cm-number {color: #164;}
+.cm-s-xq-light span.cm-def {text-decoration:underline;}
+.cm-s-xq-light span.cm-variable {color: black; }
+.cm-s-xq-light span.cm-variable-2 {color:black;}
+.cm-s-xq-light span.cm-variable-3 {color: black; }
+.cm-s-xq-light span.cm-property {}
+.cm-s-xq-light span.cm-operator {}
+.cm-s-xq-light span.cm-comment {color: #0080FF; font-style: italic;}
+.cm-s-xq-light span.cm-string {color: red;}
+.cm-s-xq-light span.cm-meta {color: yellow;}
+.cm-s-xq-light span.cm-qualifier {color: grey}
+.cm-s-xq-light span.cm-builtin {color: #7EA656;}
+.cm-s-xq-light span.cm-bracket {color: #cc7;}
+.cm-s-xq-light span.cm-tag {color: #3F7F7F;}
+.cm-s-xq-light span.cm-attribute {color: #7F007F;}
+.cm-s-xq-light span.cm-error {color: #f00;}
+
+.cm-s-xq-light .CodeMirror-activeline-background {background: #e8f2ff !important;}
+.cm-s-xq-light .CodeMirror-matchingbracket {outline:1px solid grey;color:black !important;background:yellow;}
\ No newline at end of file
diff --git a/app/gui/html/vendor/kinetic-v4.7.2.min.js b/app/gui/html/vendor/kinetic-v4.7.2.min.js
new file mode 100644
index 0000000..773a1e6
--- /dev/null
+++ b/app/gui/html/vendor/kinetic-v4.7.2.min.js
@@ -0,0 +1,5 @@
+/*! KineticJS v4.7.2 2013-09-29 http://www.kineticjs.com by Eric Rowell @ericdrowell - MIT License https://github.com/ericdrowell/KineticJS/wiki/License*/
+var Kinetic={};!function(){Kinetic={version:"4.7.2",stages:[],idCounter:0,ids:{},names:{},shapes:{},listenClickTap:!1,inDblClickWindow:!1,enableTrace:!1,traceArrMax:100,dblClickWindow:400,pixelRatio:void 0,UA:function(){var a=navigator.userAgent.toLowerCase(),b=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||a.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}}(),Filters:{},Node:function(a){this._init(a)},Shape:function(a){this.__init(a)},Container:function(a){this.__init(a)},Stage:function(a){this.___init(a)},Layer:function(a){this.___init(a)},Group:function(a){this.___init(a)},isDragging:function(){var a=Kinetic.DD;return a?a.isDragging:!1},isDragReady:function(){var a=Kinetic.DD;return a?!!a.node:!1},_addId:function(a,b){void 0!==b&&(this.ids[b]=a)},_removeId:function(a){void 0!==a&&delete this.ids[a]},_addName:function(a,b){void 0!==b&&(void 0===this.names[b]&&(this.names[b]=[]),this.names[b].push(a))},_removeName:function(a,b){if(void 0!==a){var c=this.names[a];if(void 0!==c){for(var d=0;d<c.length;d++){var e=c[d];e._id===b&&c.splice(d,1)}0===c.length&&delete this.names[a]}}}}}(),function(a,b){"object"==typeof exports?module.exports=b():"function"==typeof define&&define.amd?define(b):a.returnExports=b()}(this,function(){return Kinetic}),function(){Kinetic.Collection=function(){var a=[].slice.call(arguments),b=a.length,c=0;for(this.length=b;b>c;c++)this[c]=a[c];return this},Kinetic.Collection.prototype=[],Kinetic.Collection.prototype.each=function(a){for(var b=0;b<this.length;b++)a(this[b],b)},Kinetic.Collection.prototype.toArray=function(){var a,b=[],c=this.length;for(a=0;c>a;a++)b.push(this[a]);return b},Kinetic.Collection.toCollection=function(a){var b,c=new Kinetic.Collection,d=a.length;for(b=0;d>b;b++)c.push(a[b]);return c},Kinetic.Collection.mapMethods=function(a){var b,c=a.length;for(b=0;c>b;b++)!function(b){var c=a[b];Kinetic.Collection.prototype[c]=function(){var a,b=this.length;for(args=[].slice.call(arguments),a=0;b>a;a++)this[a][c].apply(this[a],args)}}(b)},Kinetic.Transform=function(){this.m=[1,0,0,1,0,0]},Kinetic.Transform.prototype={translate:function(a,b){this.m[4]+=this.m[0]*a+this.m[2]*b,this.m[5]+=this.m[1]*a+this.m[3]*b},scale:function(a,b){this.m[0]*=a,this.m[1]*=a,this.m[2]*=b,this.m[3]*=b},rotate:function(a){var b=Math.cos(a),c=Math.sin(a),d=this.m[0]*b+this.m[2]*c,e=this.m[1]*b+this.m[3]*c,f=this.m[0]*-c+this.m[2]*b,g=this.m[1]*-c+this.m[3]*b;this.m[0]=d,this.m[1]=e,this.m[2]=f,this.m[3]=g},getTranslation:function(){return{x:this.m[4],y:this.m[5]}},skew:function(a,b){var c=this.m[0]+this.m[2]*b,d=this.m[1]+this.m[3]*b,e=this.m[2]+this.m[0]*a,f=this.m[3]+this.m[1]*a;this.m[0]=c,this.m[1]=d,this.m[2]=e,this.m[3]=f},multiply:function(a){var b=this.m[0]*a.m[0]+this.m[2]*a.m[1],c=this.m[1]*a.m[0]+this.m[3]*a.m[1],d=this.m[0]*a.m[2]+this.m[2]*a.m[3],e=this.m[1]*a.m[2]+this.m[3]*a.m[3],f=this.m[0]*a.m[4]+this.m[2]*a.m[5]+this.m[4],g=this.m[1]*a.m[4]+this.m[3]*a.m[5]+this.m[5];this.m[0]=b,this.m[1]=c,this.m[2]=d,this.m[3]=e,this.m[4]=f,this.m[5]=g},invert:function(){var a=1/(this.m[0]*this.m[3]-this.m[1]*this.m[2]),b=this.m[3]*a,c=-this.m[1]*a,d=-this.m[2]*a,e=this.m[0]*a,f=a*(this.m[2]*this.m[5]-this.m[3]*this.m[4]),g=a*(this.m[1]*this.m[4]-this.m[0]*this.m[5]);this.m[0]=b,this.m[1]=c,this.m[2]=d,this.m[3]=e,this.m[4]=f,this.m[5]=g},getMatrix:function(){return this.m},setAbsolutePosition:function(a,b){var c=this.m[0],d=this.m[1],e=this.m[2],f=this.m[3],g=this.m[4],h=this.m[5],i=(c*(b-h)-d*(a-g))/(c*f-d*e),j=(a-g-e*i)/c;this.translate(j,i)}};var a="canvas",b="2d",c="[object Array]",d="[object Number]",e="[object String]",f=Math.PI/180,g=180/Math.PI,h="#",i="",j="0",k="Kinetic warning: ",l="Kinetic error: ",m="rgb(",n={aqua:[0,255,255],lime:[0,255,0],silver:[192,192,192],black:[0,0,0],maroon:[128,0,0],teal:[0,128,128],blue:[0,0,255],navy:[0,0,128],white:[255,255,255],fuchsia:[255,0,255],olive:[128,128,0],yellow:[255,255,0],orange:[255,165,0],gray:[128,128,128],purple:[128,0,128],green:[0,128,0],red:[255,0,0],pink:[255,192,203],cyan:[0,255,255],transparent:[255,255,255,0]},o=/rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/;Kinetic.Util={_isElement:function(a){return!(!a||1!=a.nodeType)},_isFunction:function(a){return!!(a&&a.constructor&&a.call&&a.apply)},_isObject:function(a){return!!a&&a.constructor==Object},_isArray:function(a){return Object.prototype.toString.call(a)==c},_isNumber:function(a){return Object.prototype.toString.call(a)==d},_isString:function(a){return Object.prototype.toString.call(a)==e},_hasMethods:function(a){var b,c=[];for(b in a)this._isFunction(a[b])&&c.push(b);return c.length>0},_isInDocument:function(a){for(;a=a.parentNode;)if(a==document)return!0;return!1},_simplifyArray:function(a){var b,c,d=[],e=a.length,f=Kinetic.Util;for(b=0;e>b;b++)c=a[b],f._isNumber(c)?c=Math.round(1e3*c)/1e3:f._isString(c)||(c=c.toString()),d.push(c);return d},_getXY:function(a){if(this._isNumber(a))return{x:a,y:a};if(this._isArray(a)){if(1===a.length){var b=a[0];if(this._isNumber(b))return{x:b,y:b};if(this._isArray(b))return{x:b[0],y:b[1]};if(this._isObject(b))return b}else if(a.length>=2)return{x:a[0],y:a[1]}}else if(this._isObject(a))return a;return null},_getSize:function(a){if(this._isNumber(a))return{width:a,height:a};if(this._isArray(a))if(1===a.length){var b=a[0];if(this._isNumber(b))return{width:b,height:b};if(this._isArray(b)){if(b.length>=4)return{width:b[2],height:b[3]};if(b.length>=2)return{width:b[0],height:b[1]}}else if(this._isObject(b))return b}else{if(a.length>=4)return{width:a[2],height:a[3]};if(a.length>=2)return{width:a[0],height:a[1]}}else if(this._isObject(a))return a;return null},_getPoints:function(a){var b,c,d=[];if(void 0===a)return[];if(c=a.length,this._isArray(a[0])){for(b=0;c>b;b++)d.push({x:a[b][0],y:a[b][1]});return d}if(this._isObject(a[0]))return a;for(b=0;c>b;b+=2)d.push({x:a[b],y:a[b+1]});return d},_getImage:function(c,d){var e,f,g;c?this._isElement(c)?d(c):this._isString(c)?(e=new Image,e.onload=function(){d(e)},e.src=c):c.data?(f=document.createElement(a),f.width=c.width,f.height=c.height,_context=f.getContext(b),_context.putImageData(c,0,0),g=f.toDataURL(),e=new Image,e.onload=function(){d(e)},e.src=g):d(null):d(null)},_rgbToHex:function(a,b,c){return((1<<24)+(a<<16)+(b<<8)+c).toString(16).slice(1)},_hexToRgb:function(a){a=a.replace(h,i);var b=parseInt(a,16);return{r:255&b>>16,g:255&b>>8,b:255&b}},getRandomColor:function(){for(var a=(16777215*Math.random()<<0).toString(16);a.length<6;)a=j+a;return h+a},get:function(a,b){return void 0===a?b:a},getRGB:function(a){var b;return a in n?(b=n[a],{r:b[0],g:b[1],b:b[2]}):a[0]===h?this._hexToRgb(a.substring(1)):a.substr(0,4)===m?(b=o.exec(a.replace(/ /g,"")),{r:parseInt(b[1],10),g:parseInt(b[2],10),b:parseInt(b[3],10)}):{r:0,g:0,b:0}},_merge:function(a,b){var c=this._clone(b);for(var d in a)c[d]=this._isObject(a[d])?this._merge(a[d],c[d]):a[d];return c},_clone:function(a){var b={};for(var c in a)b[c]=this._isObject(a[c])?this._clone(a[c]):a[c];return b},_degToRad:function(a){return a*f},_radToDeg:function(a){return a*g},_capitalize:function(a){return a.charAt(0).toUpperCase()+a.slice(1)},error:function(a){throw new Error(l+a)},warn:function(a){window.console&&console.warn&&console.warn(k+a)},extend:function(a,b){for(var c in b.prototype)c in a.prototype||(a.prototype[c]=b.prototype[c])},addMethods:function(a,b){var c;for(c in b)a.prototype[c]=b[c]},_getControlPoints:function(a,b,c,d){var e=a.x,f=a.y,g=b.x,h=b.y,i=c.x,j=c.y,k=Math.sqrt(Math.pow(g-e,2)+Math.pow(h-f,2)),l=Math.sqrt(Math.pow(i-g,2)+Math.pow(j-h,2)),m=d*k/(k+l),n=d*l/(k+l),o=g-m*(i-e),p=h-m*(j-f),q=g+n*(i-e),r=h+n*(j-f);return[{x:o,y:p},{x:q,y:r}]},_expandPoints:function(a,b){var c,d,e=a.length,f=[];for(c=1;e-1>c;c++)d=Kinetic.Util._getControlPoints(a[c-1],a[c],a[c+1],b),f.push(d[0]),f.push(a[c]),f.push(d[1]);return f},_removeLastLetter:function(a){return a.substring(0,a.length-1)}}}(),function(){var a=document.createElement("canvas"),b=a.getContext("2d"),c=window.devicePixelRatio||1,d=b.webkitBackingStorePixelRatio||b.mozBackingStorePixelRatio||b.msBackingStorePixelRatio||b.oBackingStorePixelRatio||b.backingStorePixelRatio||1,e=c/d;Kinetic.Canvas=function(a){this.init(a)},Kinetic.Canvas.prototype={init:function(a){a=a||{};var b=a.pixelRatio||Kinetic.pixelRatio||e;this.pixelRatio=b,this._canvas=document.createElement("canvas"),this._canvas.style.padding=0,this._canvas.style.margin=0,this._canvas.style.border=0,this._canvas.style.background="transparent",this._canvas.style.position="absolute",this._canvas.style.top=0,this._canvas.style.left=0},getContext:function(){return this.context},getPixelRatio:function(){return this.pixelRatio},setPixelRatio:function(a){this.pixelRatio=a,this.setSize(this.getWidth(),this.getHeight())},setWidth:function(a){this.width=this._canvas.width=a*this.pixelRatio,this._canvas.style.width=a+"px"},setHeight:function(a){this.height=this._canvas.height=a*this.pixelRatio,this._canvas.style.height=a+"px"},getWidth:function(){return this.width},getHeight:function(){return this.height},setSize:function(a,b){this.setWidth(a),this.setHeight(b)},toDataURL:function(a,b){try{return this._canvas.toDataURL(a,b)}catch(c){try{return this._canvas.toDataURL()}catch(d){return Kinetic.Util.warn("Unable to get data URL. "+d.message),""}}}},Kinetic.SceneCanvas=function(a){a=a||{};var b=a.width||0,c=a.height||0;Kinetic.Canvas.call(this,a),this.context=new Kinetic.SceneContext(this),this.setSize(b,c)},Kinetic.SceneCanvas.prototype={setWidth:function(a){var b=this.pixelRatio,c=this.getContext()._context;Kinetic.Canvas.prototype.setWidth.call(this,a),c.scale(b,b)},setHeight:function(a){var b=this.pixelRatio,c=this.getContext()._context;Kinetic.Canvas.prototype.setHeight.call(this,a),c.scale(b,b)}},Kinetic.Util.extend(Kinetic.SceneCanvas,Kinetic.Canvas),Kinetic.HitCanvas=function(a){a=a||{};var b=a.width||0,c=a.height||0;Kinetic.Canvas.call(this,a),this.context=new Kinetic.HitContext(this),this.setSize(b,c)},Kinetic.Util.extend(Kinetic.HitCanvas,Kinetic.Canvas)}(),function(){var a=",",b="(",c=")",d="([",e="])",f=";",g="()",h="=",i=["arc","arcTo","beginPath","bezierCurveTo","clearRect","clip","closePath","createLinearGradient","createPattern","createRadialGradient","drawImage","fill","fillText","getImageData","lineTo","moveTo","putImageData","quadraticCurveTo","rect","restore","rotate","save","scale","setLineDash","setTransform","stroke","strokeText","transform","translate"];Kinetic.Context=function(a){this.init(a)},Kinetic.Context.prototype={init:function(a){this.canvas=a,this._context=a._canvas.getContext("2d"),Kinetic.enableTrace&&(this.traceArr=[],this._enableTrace())},fillShape:function(a){a.getFillEnabled()&&this._fill(a)},strokeShape:function(a){a.getStrokeEnabled()&&this._stroke(a)},fillStrokeShape:function(a){var b=a.getFillEnabled();b&&this._fill(a),a.getStrokeEnabled()&&this._stroke(a)},getTrace:function(i){var j,k,l,m,n=this.traceArr,o=n.length,p="";for(j=0;o>j;j++)k=n[j],l=k.method,l?(m=k.args,p+=l,p+=i?g:Kinetic.Util._isArray(m[0])?d+m.join(a)+e:b+m.join(a)+c):(p+=k.property,i||(p+=h+k.val)),p+=f;return p},clearTrace:function(){this.traceArr=[]},_trace:function(a){var b,c=this.traceArr;c.push(a),b=c.length,b>=Kinetic.traceArrMax&&c.shift()},reset:function(){var a=this.getCanvas().getPixelRatio();this.setTransform(1*a,0,0,1*a,0,0)},getCanvas:function(){return this.canvas},clear:function(){var a,b,c=[].slice.call(arguments),d=this.getCanvas();c.length?(a=Kinetic.Util._getXY(c),b=Kinetic.Util._getSize(c),this.clearRect(a.x||0,a.y||0,b.width,b.height)):this.clearRect(0,0,d.getWidth(),d.getHeight())},_applyLineCap:function(a){var b=a.getLineCap();b&&this.setAttr("lineCap",b)},_applyOpacity:function(a){var b=a.getAbsoluteOpacity();1!==b&&this.setAttr("globalAlpha",b)},_applyLineJoin:function(a){var b=a.getLineJoin();b&&this.setAttr("lineJoin",b)},_applyAncestorTransforms:function(a){var b=a.getAbsoluteTransform().getMatrix();this.transform(b[0],b[1],b[2],b[3],b[4],b[5])},_clip:function(a){var b=a.getClipX()||0,c=a.getClipY()||0,d=a.getClipWidth(),e=a.getClipHeight();this.save(),this._applyAncestorTransforms(a),this.beginPath(),this.rect(b,c,d,e),this.clip(),this.reset(),a._drawChildren(this.getCanvas()),this.restore()},setAttr:function(a,b){this._context[a]=b},arc:function(){var a=arguments;this._context.arc(a[0],a[1],a[2],a[3],a[4],a[5])},beginPath:function(){this._context.beginPath()},bezierCurveTo:function(){var a=arguments;this._context.bezierCurveTo(a[0],a[1],a[2],a[3],a[4],a[5])},clearRect:function(){var a=arguments;this._context.clearRect(a[0],a[1],a[2],a[3])},clip:function(){this._context.clip()},closePath:function(){this._context.closePath()},createLinearGradient:function(){var a=arguments;return this._context.createLinearGradient(a[0],a[1],a[2],a[3])},createPattern:function(){var a=arguments;return this._context.createPattern(a[0],a[1])},createRadialGradient:function(){var a=arguments;return this._context.createRadialGradient(a[0],a[1],a[2],a[3],a[4],a[5])},drawImage:function(){var a=arguments,b=this._context;3===a.length?b.drawImage(a[0],a[1],a[2]):5===a.length?b.drawImage(a[0],a[1],a[2],a[3],a[4]):9===a.length&&b.drawImage(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8])},fill:function(){this._context.fill()},fillText:function(){var a=arguments;this._context.fillText(a[0],a[1],a[2])},getImageData:function(){var a=arguments;return this._context.getImageData(a[0],a[1],a[2],a[3])},lineTo:function(){var a=arguments;this._context.lineTo(a[0],a[1])},moveTo:function(){var a=arguments;this._context.moveTo(a[0],a[1])},rect:function(){var a=arguments;this._context.rect(a[0],a[1],a[2],a[3])},putImageData:function(){var a=arguments;this._context.putImageData(a[0],a[1],a[2])},quadraticCurveTo:function(){var a=arguments;this._context.quadraticCurveTo(a[0],a[1],a[2],a[3])},restore:function(){this._context.restore()},rotate:function(){var a=arguments;this._context.rotate(a[0])},save:function(){this._context.save()},scale:function(){var a=arguments;this._context.scale(a[0],a[1])},setLineDash:function(){var a=arguments,b=this._context;this._context.setLineDash?b.setLineDash(a[0]):"mozDash"in b?b.mozDash=a[0]:"webkitLineDash"in b&&(b.webkitLineDash=a[0])},setTransform:function(){var a=arguments;this._context.setTransform(a[0],a[1],a[2],a[3],a[4],a[5])},stroke:function(){this._context.stroke()},strokeText:function(){var a=arguments;this._context.strokeText(a[0],a[1],a[2])},transform:function(){var a=arguments;this._context.transform(a[0],a[1],a[2],a[3],a[4],a[5])},translate:function(){var a=arguments;this._context.translate(a[0],a[1])},_enableTrace:function(){var a,b,c=this,d=i.length,e=Kinetic.Util._simplifyArray,f=this.setAttr;for(a=0;d>a;a++)!function(a){var d,f=c[a];c[a]=function(){return b=e(Array.prototype.slice.call(arguments,0)),d=f.apply(c,arguments),c._trace({method:a,args:b}),d}}(i[a]);c.setAttr=function(){f.apply(c,arguments),c._trace({property:arguments[0],val:arguments[1]})}}},Kinetic.SceneContext=function(a){Kinetic.Context.call(this,a)},Kinetic.SceneContext.prototype={_fillColor:function(a){var b=a.getFill();this.setAttr("fillStyle",b),a._fillFunc(this)},_fillPattern:function(a){var b=a.getFillPatternImage(),c=a.getFillPatternX(),d=a.getFillPatternY(),e=a.getFillPatternScale(),f=a.getFillPatternRotation(),g=a.getFillPatternOffset(),h=a.getFillPatternRepeat();(c||d)&&this.translate(c||0,d||0),f&&this.rotate(f),e&&this.scale(e.x,e.y),g&&this.translate(-1*g.x,-1*g.y),this.setAttr("fillStyle",this.createPattern(b,h||"repeat")),this.fill()},_fillLinearGradient:function(a){var b=a.getFillLinearGradientStartPoint(),c=a.getFillLinearGradientEndPoint(),d=a.getFillLinearGradientColorStops(),e=this.createLinearGradient(b.x,b.y,c.x,c.y);if(d){for(var f=0;f<d.length;f+=2)e.addColorStop(d[f],d[f+1]);this.setAttr("fillStyle",e),this.fill()}},_fillRadialGradient:function(a){for(var b=a.getFillRadialGradientStartPoint(),c=a.getFillRadialGradientEndPoint(),d=a.getFillRadialGradientStartRadius(),e=a.getFillRadialGradientEndRadius(),f=a.getFillRadialGradientColorStops(),g=this.createRadialGradient(b.x,b.y,d,c.x,c.y,e),h=0;h<f.length;h+=2)g.addColorStop(f[h],f[h+1]);this.setAttr("fillStyle",g),this.fill()},_fill:function(a){var b=a.getFill(),c=a.getFillPatternImage(),d=a.getFillLinearGradientColorStops(),e=a.getFillRadialGradientColorStops(),f=a.getFillPriority();b&&"color"===f?this._fillColor(a):c&&"pattern"===f?this._fillPattern(a):d&&"linear-gradient"===f?this._fillLinearGradient(a):e&&"radial-gradient"===f?this._fillRadialGradient(a):b?this._fillColor(a):c?this._fillPattern(a):d?this._fillLinearGradient(a):e&&this._fillRadialGradient(a)},_stroke:function(a){var b=a.getStroke(),c=a.getStrokeWidth(),d=a.getDashArray(),e=a.getStrokeScaleEnabled();a.hasStroke()&&(e||(this.save(),this.setTransform(1,0,0,1,0,0)),this._applyLineCap(a),d&&a.getDashArrayEnabled()&&this.setLineDash(d),this.setAttr("lineWidth",c||2),this.setAttr("strokeStyle",b||"black"),a._strokeFunc(this),e||this.restore())},_applyShadow:function(a){var b=Kinetic.Util,c=a.getAbsoluteOpacity(),d=b.get(a.getShadowColor(),"black"),e=b.get(a.getShadowBlur(),5),f=b.get(a.getShadowOpacity(),0),g=b.get(a.getShadowOffset(),{x:0,y:0});f&&this.setAttr("globalAlpha",f*c),this.setAttr("shadowColor",d),this.setAttr("shadowBlur",e),this.setAttr("shadowOffsetX",g.x),this.setAttr("shadowOffsetY",g.y)}},Kinetic.Util.extend(Kinetic.SceneContext,Kinetic.Context),Kinetic.HitContext=function(a){Kinetic.Context.call(this,a)},Kinetic.HitContext.prototype={_fill:function(a){this.save(),this.setAttr("fillStyle",a.colorKey),a._fillFuncHit(this),this.restore()},_stroke:function(a){var b=a.getStroke(),c=a.getStrokeWidth();(b||c)&&(this._applyLineCap(a),this.setAttr("lineWidth",c||2),this.setAttr("strokeStyle",a.colorKey),a._strokeFuncHit(this))}},Kinetic.Util.extend(Kinetic.HitContext,Kinetic.Context)}(),function(){var a="add",b="b",c="Deg",d="g",e="get",f="#",g="r",h="RGB",i="set",j="B",k="G",l="Height",m="R",n="Width",o="X",p="Y";Kinetic.Factory={addGetterSetter:function(a,b,c){this.addGetter(a,b,c),this.addSetter(a,b)},addPointGetterSetter:function(a,b,c){this.addPointGetter(a,b,c),this.addPointSetter(a,b),this.addGetter(a,b+o,c),this.addGetter(a,b+p,c),this.addSetter(a,b+o),this.addSetter(a,b+p)},addBoxGetterSetter:function(a,b,c){this.addBoxGetter(a,b,c),this.addBoxSetter(a,b),this.addGetter(a,b+o,c),this.addGetter(a,b+p,c),this.addGetter(a,b+n,c),this.addGetter(a,b+l,c),this.addSetter(a,b+o),this.addSetter(a,b+p),this.addSetter(a,b+n),this.addSetter(a,b+l)},addPointsGetterSetter:function(a,b){this.addPointsGetter(a,b),this.addPointsSetter(a,b),this.addPointAdder(a,b)},addRotationGetterSetter:function(a,b,c){this.addRotationGetter(a,b,c),this.addRotationSetter(a,b)},addColorGetterSetter:function(a,c){this.addGetter(a,c),this.addSetter(a,c),this.addColorRGBGetter(a,c),this.addColorComponentGetter(a,c,g),this.addColorComponentGetter(a,c,d),this.addColorComponentGetter(a,c,b),this.addColorRGBSetter(a,c),this.addColorComponentSetter(a,c,g),this.addColorComponentSetter(a,c,d),this.addColorComponentSetter(a,c,b)},addColorRGBGetter:function(a,b){var c=e+Kinetic.Util._capitalize(b)+h;a.prototype[c]=function(){return Kinetic.Util.getRGB(this.attrs[b])}},addColorComponentGetter:function(a,b,c){var d=e+Kinetic.Util._capitalize(b),f=d+Kinetic.Util._capitalize(c);a.prototype[f]=function(){return this[d+h]()[c]}},addPointsGetter:function(a,b){var c=e+Kinetic.Util._capitalize(b);a.prototype[c]=function(){var a=this.attrs[b];return void 0===a?[]:a}},addGetter:function(a,b,c){var d=e+Kinetic.Util._capitalize(b);a.prototype[d]=function(){var a=this.attrs[b];return void 0===a?c:a}},addPointGetter:function(a,b){var c=e+Kinetic.Util._capitalize(b);a.prototype[c]=function(){var a=this;return{x:a[c+o](),y:a[c+p]()}}},addBoxGetter:function(a,b){var c=e+Kinetic.Util._capitalize(b);a.prototype[c]=function(){var a=this;return{x:a[c+o](),y:a[c+p](),width:a[c+n](),height:a[c+l]()}}},addRotationGetter:function(a,b,d){var f=e+Kinetic.Util._capitalize(b);a.prototype[f]=function(){var a=this.attrs[b];return void 0===a&&(a=d),a},a.prototype[f+c]=function(){var a=this.attrs[b];return void 0===a&&(a=d),Kinetic.Util._radToDeg(a)}},addColorRGBSetter:function(a,b){var c=i+Kinetic.Util._capitalize(b)+h;a.prototype[c]=function(a){var c=a&&void 0!==a.r?0|a.r:this.getAttr(b+m),d=a&&void 0!==a.g?0|a.g:this.getAttr(b+k),e=a&&void 0!==a.b?0|a.b:this.getAttr(b+j);this._setAttr(b,f+Kinetic.Util._rgbToHex(c,d,e))}},addColorComponentSetter:function(a,b,c){var d=i+Kinetic.Util._capitalize(b),e=d+Kinetic.Util._capitalize(c);a.prototype[e]=function(a){var b={};b[c]=a,this[d+h](b)}},addPointsSetter:function(a,b){var c=i+Kinetic.Util._capitalize(b);a.prototype[c]=function(a){var b=Kinetic.Util._getPoints(a);this._setAttr("points",b)}},addSetter:function(a,b){var c=i+Kinetic.Util._capitalize(b);a.prototype[c]=function(a){this._setAttr(b,a)}},addPointSetter:function(a,b){var c=i+Kinetic.Util._capitalize(b);a.prototype[c]=function(){var a=Kinetic.Util._getXY([].slice.call(arguments)),d=this.attrs[b],e=0,f=0;a&&(e=a.x,f=a.y,this._fireBeforeChangeEvent(b,d,a),void 0!==e&&this[c+o](e),void 0!==f&&this[c+p](f),this._fireChangeEvent(b,d,a))}},addBoxSetter:function(a,b){var c=i+Kinetic.Util._capitalize(b);a.prototype[c]=function(){var a,d,e,f,g=[].slice.call(arguments),h=Kinetic.Util._getXY(g),i=Kinetic.Util._getSize(g),j=Kinetic.Util._merge(h,i),k=this.attrs[b];j&&(a=j.x,d=j.y,e=j.width,f=j.height,this._fireBeforeChangeEvent(b,k,j),void 0!==a&&this[c+o](a),void 0!==d&&this[c+p](d),void 0!==e&&this[c+n](e),void 0!==f&&this[c+l](f),this._fireChangeEvent(b,k,j))}},addRotationSetter:function(a,b){var d=i+Kinetic.Util._capitalize(b);a.prototype[d]=function(a){this._setAttr(b,a)},a.prototype[d+c]=function(a){this._setAttr(b,Kinetic.Util._degToRad(a))}},addPointAdder:function(b,c){var d=a+Kinetic.Util._removeLastLetter(Kinetic.Util._capitalize(c));b.prototype[d]=function(){var a=Kinetic.Util._getXY([].slice.call(arguments)),b=this.attrs[c];a&&(this._fireBeforeChangeEvent(c,b,a),this.attrs[c].push(a),this._fireChangeEvent(c,b,a))}}}}(),function(){var a="absoluteOpacity",b="absoluteTransform",c="before",d="Change",e="children",f=".",g="",h="get",i="id",j="kinetic",k="listening",l="mouseenter",m="mouseleave",n="name",o="set",p="Shape",q=" ",r="stage",s="transform",t="Stage",u="visible",v=["xChange.kinetic","yChange.kinetic","scaleXChange.kinetic","scaleYChange.kinetic","skewXChange.kinetic","skewYChange.kinetic","rotationChange.kinetic","offsetXChange.kinetic","offsetYChange.kinetic"].join(q);Kinetic.Util.addMethods(Kinetic.Node,{_init:function(c){var d=this;this._id=Kinetic.idCounter++,this.eventListeners={},this.attrs={},this.cache={},this.setAttrs(c),this.on(v,function(){this._clearCache(s),d._clearSelfAndChildrenCache(b)}),this.on("visibleChange.kinetic",function(){d._clearSelfAndChildrenCache(u)}),this.on("listeningChange.kinetic",function(){d._clearSelfAndChildrenCache(k)}),this.on("opacityChange.kinetic",function(){d._clearSelfAndChildrenCache(a)})},clearCache:function(){this.cache={}},_clearCache:function(a){delete this.cache[a]},_getCache:function(a,b){var c=this.cache[a];return void 0===c&&(this.cache[a]=b.call(this)),this.cache[a]},_clearSelfAndChildrenCache:function(a){this._clearCache(a),this.children&&this.getChildren().each(function(b){b._clearSelfAndChildrenCache(a)})},on:function(a,b){var c,d,e,h,i,j=a.split(q),k=j.length;for(c=0;k>c;c++)d=j[c],e=d.split(f),h=e[0],i=e[1]||g,this.eventListeners[h]||(this.eventListeners[h]=[]),this.eventListeners[h].push({name:i,handler:b});return this},off:function(a){var b,c,d,e,g,h,i=a.split(q),j=i.length;for(b=0;j>b;b++)if(d=i[b],e=d.split(f),g=e[0],h=e[1],g)this.eventListeners[g]&&this._off(g,h);else for(c in this.eventListeners)this._off(c,h);return this},remove:function(){var c=this.getParent();return c&&c.children&&(c.children.splice(this.index,1),c._setChildrenIndices(),delete this.parent),this._clearSelfAndChildrenCache(r),this._clearSelfAndChildrenCache(b),this._clearSelfAndChildrenCache(u),this._clearSelfAndChildrenCache(k),this._clearSelfAndChildrenCache(a),this},destroy:function(){Kinetic._removeId(this.getId()),Kinetic._removeName(this.getName(),this._id),this.remove()},getAttr:function(a){var b=h+Kinetic.Util._capitalize(a);return Kinetic.Util._isFunction(this[b])?this[b]():this.attrs[a]},getAncestors:function(){for(var a=this.getParent(),b=new Kinetic.Collection;a;)b.push(a),a=a.getParent();return b},setAttr:function(){var a=Array.prototype.slice.call(arguments),b=a[0],c=o+Kinetic.Util._capitalize(b),d=this[c];return a.shift(),Kinetic.Util._isFunction(d)?d.apply(this,a):this.attrs[b]=a[0],this},getAttrs:function(){return this.attrs||{}},setAttrs:function(a){var b,c;if(a)for(b in a)b===e||(c=o+Kinetic.Util._capitalize(b),Kinetic.Util._isFunction(this[c])?this[c](a[b]):this._setAttr(b,a[b]));return this},isListening:function(){return this._getCache(k,this._isListening)},_isListening:function(){var a=this.getListening(),b=this.getParent();return a&&b&&!b.isListening()?!1:a},isVisible:function(){return this._getCache(u,this._isVisible)},_isVisible:function(){var a=this.getVisible(),b=this.getParent();return a&&b&&!b.isVisible()?!1:a},show:function(){return this.setVisible(!0),this},hide:function(){return this.setVisible(!1),this},getZIndex:function(){return this.index||0},getAbsoluteZIndex:function(){function a(i){for(b=[],c=i.length,d=0;c>d;d++)e=i[d],h++,e.nodeType!==p&&(b=b.concat(e.getChildren().toArray())),e._id===g._id&&(d=c);b.length>0&&b[0].getLevel()<=f&&a(b)}var b,c,d,e,f=this.getLevel(),g=this,h=0;return g.nodeType!==t&&a(g.getStage().getChildren()),h},getLevel:function(){for(var a=0,b=this.parent;b;)a++,b=b.parent;return a},setPosition:function(){var a=Kinetic.Util._getXY([].slice.call(arguments));return this.setX(a.x),this.setY(a.y),this},getPosition:function(){return{x:this.getX(),y:this.getY()}},getAbsolutePosition:function(){var a=this.getAbsoluteTransform().getMatrix(),b=new Kinetic.Transform,c=this.getOffset();return b.m=a.slice(),b.translate(c.x,c.y),b.getTranslation()},setAbsolutePosition:function(){var a,b=Kinetic.Util._getXY([].slice.call(arguments)),c=this._clearTransform();return this.attrs.x=c.x,this.attrs.y=c.y,delete c.x,delete c.y,a=this.getAbsoluteTransform(),a.invert(),a.translate(b.x,b.y),b={x:this.attrs.x+a.getTranslation().x,y:this.attrs.y+a.getTranslation().y},this.setPosition(b.x,b.y),this._setTransform(c),this},_setTransform:function(a){var c;for(c in a)this.attrs[c]=a[c];this._clearCache(s),this._clearSelfAndChildrenCache(b)},_clearTransform:function(){var a={x:this.getX(),y:this.getY(),rotation:this.getRotation(),scaleX:this.getScaleX(),scaleY:this.getScaleY(),offsetX:this.getOffsetX(),offsetY:this.getOffsetY(),skewX:this.getSkewX(),skewY:this.getSkewY()};return this.attrs.x=0,this.attrs.y=0,this.attrs.rotation=0,this.attrs.scaleX=1,this.attrs.scaleY=1,this.attrs.offsetX=0,this.attrs.offsetY=0,this.attrs.skewX=0,this.attrs.skewY=0,this._clearCache(s),this._clearSelfAndChildrenCache(b),a},move:function(){var a=Kinetic.Util._getXY([].slice.call(arguments)),b=this.getX(),c=this.getY();return void 0!==a.x&&(b+=a.x),void 0!==a.y&&(c+=a.y),this.setPosition(b,c),this},_eachAncestorReverse:function(a,b){var c,d,e=[],f=this.getParent();for(b&&e.unshift(this);f;)e.unshift(f),f=f.parent;for(c=e.length,d=0;c>d;d++)a(e[d])},rotate:function(a){return this.setRotation(this.getRotation()+a),this},rotateDeg:function(a){return this.setRotation(this.getRotation()+Kinetic.Util._degToRad(a)),this},moveToTop:function(){var a=this.index;return this.parent.children.splice(a,1),this.parent.children.push(this),this.parent._setChildrenIndices(),!0},moveUp:function(){var a=this.index,b=this.parent.getChildren().length;return b-1>a?(this.parent.children.splice(a,1),this.parent.children.splice(a+1,0,this),this.parent._setChildrenIndices(),!0):!1},moveDown:function(){var a=this.index;return a>0?(this.parent.children.splice(a,1),this.parent.children.splice(a-1,0,this),this.parent._setChildrenIndices(),!0):!1},moveToBottom:function(){var a=this.index;return a>0?(this.parent.children.splice(a,1),this.parent.children.unshift(this),this.parent._setChildrenIndices(),!0):!1},setZIndex:function(a){var b=this.index;return this.parent.children.splice(b,1),this.parent.children.splice(a,0,this),this.parent._setChildrenIndices(),this},getAbsoluteOpacity:function(){return this._getCache(a,this._getAbsoluteOpacity)},_getAbsoluteOpacity:function(){var a=this.getOpacity();return this.getParent()&&(a*=this.getParent().getAbsoluteOpacity()),a},moveTo:function(a){return Kinetic.Node.prototype.remove.call(this),a.add(this),this},toObject:function(){var a,b,c=Kinetic.Util,d={},e=this.getAttrs();d.attrs={};for(a in e)b=e[a],c._isFunction(b)||c._isElement(b)||c._isObject(b)&&c._hasMethods(b)||(d.attrs[a]=b);return d.className=this.getClassName(),d},toJSON:function(){return JSON.stringify(this.toObject())},getParent:function(){return this.parent},getLayer:function(){return this.getParent().getLayer()},getStage:function(){return this._getCache(r,this._getStage)},_getStage:function(){var a=this.getParent();return a?a.getStage():void 0},fire:function(a,b,c){return c?this._fireAndBubble(a,b||{}):this._fire(a,b||{}),this},getAbsoluteTransform:function(){return this._getCache(b,this._getAbsoluteTransform)},_getAbsoluteTransform:function(){var a,b=new Kinetic.Transform;return this._eachAncestorReverse(function(c){a=c.getTransform(),b.multiply(a)},!0),b},_getTransform:function(){var a=new Kinetic.Transform,b=this.getX(),c=this.getY(),d=this.getRotation(),e=this.getScaleX(),f=this.getScaleY(),g=this.getSkewX(),h=this.getSkewY(),i=this.getOffsetX(),j=this.getOffsetY();return(0!==b||0!==c)&&a.translate(b,c),0!==d&&a.rotate(d),(0!==g||0!==h)&&a.skew(g,h),(1!==e||1!==f)&&a.scale(e,f),(0!==i||0!==j)&&a.translate(-1*i,-1*j),a},clone:function(a){var b,c,d,e,f,g=this.getClassName(),h=new Kinetic[g](this.attrs);for(b in this.eventListeners)for(c=this.eventListeners[b],d=c.length,e=0;d>e;e++)f=c[e],f.name.indexOf(j)<0&&(h.eventListeners[b]||(h.eventListeners[b]=[]),h.eventListeners[b].push(f));return h.setAttrs(a),h},toDataURL:function(a){a=a||{};var b=a.mimeType||null,c=a.quality||null,d=this.getStage(),e=a.x||0,f=a.y||0,g=new Kinetic.SceneCanvas({width:a.width||d.getWidth(),height:a.height||d.getHeight(),pixelRatio:1}),h=g.getContext();return h.save(),(e||f)&&h.translate(-1*e,-1*f),this.drawScene(g),h.restore(),g.toDataURL(b,c)},toImage:function(a){Kinetic.Util._getImage(this.toDataURL(a),function(b){a.callback(b)})},setSize:function(){var a=Kinetic.Util._getSize(Array.prototype.slice.call(arguments));return this.setWidth(a.width),this.setHeight(a.height),this},getSize:function(){return{width:this.getWidth(),height:this.getHeight()}},getWidth:function(){return this.attrs.width||0},getHeight:function(){return this.attrs.height||0},getClassName:function(){return this.className||this.nodeType},getType:function(){return this.nodeType},_get:function(a){return this.nodeType===a?[this]:[]},_off:function(a,b){var c,d,e=this.eventListeners[a];for(c=0;c<e.length;c++)if(d=e[c].name,!("kinetic"===d&&"kinetic"!==b||b&&d!==b)){if(e.splice(c,1),0===e.length){delete this.eventListeners[a];break}c--}},_fireBeforeChangeEvent:function(a,b,e){this._fire(c+Kinetic.Util._capitalize(a)+d,{oldVal:b,newVal:e})},_fireChangeEvent:function(a,b,c){this._fire(a+d,{oldVal:b,newVal:c})},setId:function(a){var b=this.getId();return Kinetic._removeId(b),Kinetic._addId(this,a),this._setAttr(i,a),this},setName:function(a){var b=this.getName();return Kinetic._removeName(b,this._id),Kinetic._addName(this,a),this._setAttr(n,a),this},_setAttr:function(a,b){var c;void 0!==b&&(c=this.attrs[a],this._fireBeforeChangeEvent(a,c,b),this.attrs[a]=b,this._fireChangeEvent(a,c,b))},_fireAndBubble:function(a,b,c){var d=!0;b&&this.nodeType===p&&(b.targetNode=this),a===l&&c&&this._id===c._id?d=!1:a===m&&c&&this._id===c._id&&(d=!1),d&&(this._fire(a,b),b&&!b.cancelBubble&&this.parent&&(c&&c.parent?this._fireAndBubble.call(this.parent,a,b,c.parent):this._fireAndBubble.call(this.parent,a,b)))
+},_fire:function(a,b){var c,d,e=this.eventListeners[a];if(e)for(c=e.length,d=0;c>d;d++)e[d].handler.call(this,b)},draw:function(){return this.drawScene(),this.drawHit(),this},shouldDrawHit:function(){return this.isListening()&&this.isVisible()&&!Kinetic.isDragging()},isDraggable:function(){return!1},getTransform:function(){return this._getCache(s,this._getTransform)}}),Kinetic.Node.create=function(a,b){return this._createNode(JSON.parse(a),b)},Kinetic.Node._createNode=function(a,b){var c,d,e,f=Kinetic.Node.prototype.getClassName.call(a),g=a.children;if(b&&(a.attrs.container=b),c=new Kinetic[f](a.attrs),g)for(d=g.length,e=0;d>e;e++)c.add(this._createNode(g[e]));return c},Kinetic.Factory.addGetterSetter(Kinetic.Node,"x",0),Kinetic.Factory.addGetterSetter(Kinetic.Node,"y",0),Kinetic.Factory.addGetterSetter(Kinetic.Node,"opacity",1),Kinetic.Factory.addGetter(Kinetic.Node,"name"),Kinetic.Factory.addGetter(Kinetic.Node,"id"),Kinetic.Factory.addRotationGetterSetter(Kinetic.Node,"rotation",0),Kinetic.Factory.addPointGetterSetter(Kinetic.Node,"scale",1),Kinetic.Factory.addPointGetterSetter(Kinetic.Node,"skew",0),Kinetic.Factory.addPointGetterSetter(Kinetic.Node,"offset",0),Kinetic.Factory.addSetter(Kinetic.Node,"width"),Kinetic.Factory.addSetter(Kinetic.Node,"height"),Kinetic.Factory.addGetterSetter(Kinetic.Node,"listening",!0),Kinetic.Factory.addGetterSetter(Kinetic.Node,"visible",!0),Kinetic.Collection.mapMethods(["on","off","remove","destroy","show","hide","move","rotate","moveToTop","moveUp","moveDown","moveToBottom","moveTo","fire","draw"])}(),function(){function a(a){window.setTimeout(a,1e3/60)}var b=500;Kinetic.Animation=function(a,b){this.func=a,this.setLayers(b),this.id=Kinetic.Animation.animIdCounter++,this.frame={time:0,timeDiff:0,lastTime:(new Date).getTime()}},Kinetic.Animation.prototype={setLayers:function(a){var b=[];b=a?a.length>0?a:[a]:[],this.layers=b},getLayers:function(){return this.layers},addLayer:function(a){var b,c,d=this.layers;if(d){for(b=d.length,c=0;b>c;c++)if(d[c]._id===a._id)return!1}else this.layers=[];return this.layers.push(a),!0},isRunning:function(){for(var a=Kinetic.Animation,b=a.animations,c=0;c<b.length;c++)if(b[c].id===this.id)return!0;return!1},start:function(){this.stop(),this.frame.timeDiff=0,this.frame.lastTime=(new Date).getTime(),Kinetic.Animation._addAnimation(this)},stop:function(){Kinetic.Animation._removeAnimation(this)},_updateFrameObject:function(a){this.frame.timeDiff=a-this.frame.lastTime,this.frame.lastTime=a,this.frame.time+=this.frame.timeDiff,this.frame.frameRate=1e3/this.frame.timeDiff}},Kinetic.Animation.animations=[],Kinetic.Animation.animIdCounter=0,Kinetic.Animation.animRunning=!1,Kinetic.Animation._addAnimation=function(a){this.animations.push(a),this._handleAnimation()},Kinetic.Animation._removeAnimation=function(a){for(var b=a.id,c=this.animations,d=c.length,e=0;d>e;e++)if(c[e].id===b){this.animations.splice(e,1);break}},Kinetic.Animation._runFrames=function(){var a,b,c,d,e,f,g,h,i={},j=this.animations;for(d=0;d<j.length;d++){for(a=j[d],b=a.layers,c=a.func,a._updateFrameObject((new Date).getTime()),f=b.length,e=0;f>e;e++)g=b[e],void 0!==g._id&&(i[g._id]=g);c&&c.call(a,a.frame)}for(h in i)i[h].draw()},Kinetic.Animation._animationLoop=function(){var a=this;this.animations.length>0?(this._runFrames(),Kinetic.Animation.requestAnimFrame(function(){a._animationLoop()})):this.animRunning=!1},Kinetic.Animation._handleAnimation=function(){var a=this;this.animRunning||(this.animRunning=!0,a._animationLoop())},RAF=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||a}(),Kinetic.Animation.requestAnimFrame=function(b){var c=Kinetic.DD&&Kinetic.DD.isDragging?a:RAF;c(b)};var c=Kinetic.Node.prototype.moveTo;Kinetic.Node.prototype.moveTo=function(a){c.call(this,a)},Kinetic.Layer.prototype.batchDraw=function(){var a=this;this.batchAnim||(this.batchAnim=new Kinetic.Animation(function(){a.lastBatchDrawTime&&(new Date).getTime()-a.lastBatchDrawTime>b&&a.batchAnim.stop()},this)),this.lastBatchDrawTime=(new Date).getTime(),this.batchAnim.isRunning()||(this.draw(),this.batchAnim.start())},Kinetic.Stage.prototype.batchDraw=function(){this.getChildren().each(function(a){a.batchDraw()})}}(),function(){var a={node:1,duration:1,easing:1,onFinish:1,yoyo:1},b=1,c=2,d=3,e=0;Kinetic.Tween=function(b){var c,d=this,g=b.node,h=g._id,i=b.duration||1,j=b.easing||Kinetic.Easings.Linear,k=!!b.yoyo;this.node=g,this._id=e++,this.anim=new Kinetic.Animation(function(){d.tween.onEnterFrame()},g.getLayer()||g.getLayers()),this.tween=new f(c,function(a){d._tweenFunc(a)},j,0,1,1e3*i,k),this._addListeners(),Kinetic.Tween.attrs[h]||(Kinetic.Tween.attrs[h]={}),Kinetic.Tween.attrs[h][this._id]||(Kinetic.Tween.attrs[h][this._id]={}),Kinetic.Tween.tweens[h]||(Kinetic.Tween.tweens[h]={});for(c in b)void 0===a[c]&&this._addAttr(c,b[c]);this.reset(),this.onFinish=b.onFinish,this.onReset=b.onReset},Kinetic.Tween.attrs={},Kinetic.Tween.tweens={},Kinetic.Tween.prototype={_addAttr:function(a,b){var c,d,e,f,g,h,i,j=this.node,k=j._id;if(e=Kinetic.Tween.tweens[k][a],e&&delete Kinetic.Tween.attrs[k][e][a],c=j.getAttr(a),Kinetic.Util._isArray(b))for(b=Kinetic.Util._getPoints(b),d=[],g=b.length,f=0;g>f;f++)h=c[f],i=b[f],d.push({x:i.x-h.x,y:i.y-h.y});else d=b-c;Kinetic.Tween.attrs[k][this._id][a]={start:c,diff:d},Kinetic.Tween.tweens[k][a]=this._id},_tweenFunc:function(a){var b,c,d,e,f,g,h,i,j,k=this.node,l=Kinetic.Tween.attrs[k._id][this._id];for(b in l){if(c=l[b],d=c.start,e=c.diff,Kinetic.Util._isArray(d))for(f=[],h=d.length,g=0;h>g;g++)i=d[g],j=e[g],f.push({x:i.x+j.x*a,y:i.y+j.y*a});else f=d+e*a;k.setAttr(b,f)}},_addListeners:function(){var a=this;this.tween.onPlay=function(){a.anim.start()},this.tween.onReverse=function(){a.anim.start()},this.tween.onPause=function(){a.anim.stop()},this.tween.onFinish=function(){a.onFinish&&a.onFinish()},this.tween.onReset=function(){a.onReset&&a.onReset()}},play:function(){return this.tween.play(),this},reverse:function(){return this.tween.reverse(),this},reset:function(){var a=this.node;return this.tween.reset(),(a.getLayer()||a.getLayers()).draw(),this},seek:function(a){var b=this.node;return this.tween.seek(1e3*a),(b.getLayer()||b.getLayers()).draw(),this},pause:function(){return this.tween.pause(),this},finish:function(){var a=this.node;return this.tween.finish(),(a.getLayer()||a.getLayers()).draw(),this},destroy:function(){var a,b=this.node._id,c=this._id,d=Kinetic.Tween.tweens[b];this.pause();for(a in d)delete Kinetic.Tween.tweens[b][a];delete Kinetic.Tween.attrs[b][c]}};var f=function(a,b,c,d,e,f,g){this.prop=a,this.propFunc=b,this.begin=d,this._pos=d,this.duration=f,this._change=0,this.prevPos=0,this.yoyo=g,this._time=0,this._position=0,this._startTime=0,this._finish=0,this.func=c,this._change=e-this.begin,this.pause()};f.prototype={fire:function(a){var b=this[a];b&&b()},setTime:function(a){a>this.duration?this.yoyo?(this._time=this.duration,this.reverse()):this.finish():0>a?this.yoyo?(this._time=0,this.play()):this.reset():(this._time=a,this.update())},getTime:function(){return this._time},setPosition:function(a){this.prevPos=this._pos,this.propFunc(a),this._pos=a},getPosition:function(a){return void 0===a&&(a=this._time),this.func(a,this.begin,this._change,this.duration)},play:function(){this.state=c,this._startTime=this.getTimer()-this._time,this.onEnterFrame(),this.fire("onPlay")},reverse:function(){this.state=d,this._time=this.duration-this._time,this._startTime=this.getTimer()-this._time,this.onEnterFrame(),this.fire("onReverse")},seek:function(a){this.pause(),this._time=a,this.update(),this.fire("onSeek")},reset:function(){this.pause(),this._time=0,this.update(),this.fire("onReset")},finish:function(){this.pause(),this._time=this.duration,this.update(),this.fire("onFinish")},update:function(){this.setPosition(this.getPosition(this._time))},onEnterFrame:function(){var a=this.getTimer()-this._startTime;this.state===c?this.setTime(a):this.state===d&&this.setTime(this.duration-a)},pause:function(){this.state=b,this.fire("onPause")},getTimer:function(){return(new Date).getTime()}},Kinetic.Easings={BackEaseIn:function(a,b,c,d){var e=1.70158;return c*(a/=d)*a*((e+1)*a-e)+b},BackEaseOut:function(a,b,c,d){var e=1.70158;return c*((a=a/d-1)*a*((e+1)*a+e)+1)+b},BackEaseInOut:function(a,b,c,d){var e=1.70158;return(a/=d/2)<1?c/2*a*a*(((e*=1.525)+1)*a-e)+b:c/2*((a-=2)*a*(((e*=1.525)+1)*a+e)+2)+b},ElasticEaseIn:function(a,b,c,d,e,f){var g=0;return 0===a?b:1==(a/=d)?b+c:(f||(f=.3*d),!e||e<Math.abs(c)?(e=c,g=f/4):g=f/(2*Math.PI)*Math.asin(c/e),-(e*Math.pow(2,10*(a-=1))*Math.sin((a*d-g)*2*Math.PI/f))+b)},ElasticEaseOut:function(a,b,c,d,e,f){var g=0;return 0===a?b:1==(a/=d)?b+c:(f||(f=.3*d),!e||e<Math.abs(c)?(e=c,g=f/4):g=f/(2*Math.PI)*Math.asin(c/e),e*Math.pow(2,-10*a)*Math.sin((a*d-g)*2*Math.PI/f)+c+b)},ElasticEaseInOut:function(a,b,c,d,e,f){var g=0;return 0===a?b:2==(a/=d/2)?b+c:(f||(f=d*.3*1.5),!e||e<Math.abs(c)?(e=c,g=f/4):g=f/(2*Math.PI)*Math.asin(c/e),1>a?-.5*e*Math.pow(2,10*(a-=1))*Math.sin((a*d-g)*2*Math.PI/f)+b:.5*e*Math.pow(2,-10*(a-=1))*Math.sin((a*d-g)*2*Math.PI/f)+c+b)},BounceEaseOut:function(a,b,c,d){return(a/=d)<1/2.75?c*7.5625*a*a+b:2/2.75>a?c*(7.5625*(a-=1.5/2.75)*a+.75)+b:2.5/2.75>a?c*(7.5625*(a-=2.25/2.75)*a+.9375)+b:c*(7.5625*(a-=2.625/2.75)*a+.984375)+b},BounceEaseIn:function(a,b,c,d){return c-Kinetic.Easings.BounceEaseOut(d-a,0,c,d)+b},BounceEaseInOut:function(a,b,c,d){return d/2>a?.5*Kinetic.Easings.BounceEaseIn(2*a,0,c,d)+b:.5*Kinetic.Easings.BounceEaseOut(2*a-d,0,c,d)+.5*c+b},EaseIn:function(a,b,c,d){return c*(a/=d)*a+b},EaseOut:function(a,b,c,d){return-c*(a/=d)*(a-2)+b},EaseInOut:function(a,b,c,d){return(a/=d/2)<1?c/2*a*a+b:-c/2*(--a*(a-2)-1)+b},StrongEaseIn:function(a,b,c,d){return c*(a/=d)*a*a*a*a+b},StrongEaseOut:function(a,b,c,d){return c*((a=a/d-1)*a*a*a*a+1)+b},StrongEaseInOut:function(a,b,c,d){return(a/=d/2)<1?c/2*a*a*a*a*a+b:c/2*((a-=2)*a*a*a*a+2)+b},Linear:function(a,b,c,d){return c*a/d+b}}}(),function(){Kinetic.DD={anim:new Kinetic.Animation,isDragging:!1,offset:{x:0,y:0},node:null,_drag:function(a){var b=Kinetic.DD,c=b.node;c&&(c._setDragPosition(a),b.isDragging||(b.isDragging=!0,c.fire("dragstart",a,!0)),c.fire("dragmove",a,!0))},_endDragBefore:function(a){var b,c,d=Kinetic.DD,e=d.node;e&&(b=e.nodeType,c=e.getLayer(),d.anim.stop(),d.isDragging&&(d.isDragging=!1,Kinetic.listenClickTap=!1,a&&(a.dragEndNode=e)),delete d.node,(c||e).draw())},_endDragAfter:function(a){a=a||{};var b=a.dragEndNode;a&&b&&b.fire("dragend",a,!0)}},Kinetic.Node.prototype.startDrag=function(){var a=Kinetic.DD,b=this.getStage(),c=this.getLayer(),d=b.getPointerPosition(),e=this.getAbsolutePosition();d&&(a.node&&a.node.stopDrag(),a.node=this,a.offset.x=d.x-e.x,a.offset.y=d.y-e.y,a.anim.setLayers(c||this.getLayers()),a.anim.start(),this._setDragPosition())},Kinetic.Node.prototype._setDragPosition=function(a){var b=Kinetic.DD,c=this.getStage().getPointerPosition(),d=this.getDragBoundFunc(),e={x:c.x-b.offset.x,y:c.y-b.offset.y};void 0!==d&&(e=d.call(this,e,a)),this.setAbsolutePosition(e)},Kinetic.Node.prototype.stopDrag=function(){var a=Kinetic.DD,b={};a._endDragBefore(b),a._endDragAfter(b)},Kinetic.Node.prototype.setDraggable=function(a){this._setAttr("draggable",a),this._dragChange()};var a=Kinetic.Node.prototype.destroy;Kinetic.Node.prototype.destroy=function(){var b=Kinetic.DD;b.node&&b.node._id===this._id&&this.stopDrag(),a.call(this)},Kinetic.Node.prototype.isDragging=function(){var a=Kinetic.DD;return a.node&&a.node._id===this._id&&a.isDragging},Kinetic.Node.prototype._listenDrag=function(){var a=this;this._dragCleanup(),"Stage"===this.getClassName()?this.on("contentMousedown.kinetic contentTouchstart.kinetic",function(b){Kinetic.DD.node||a.startDrag(b)}):this.on("mousedown.kinetic touchstart.kinetic",function(b){Kinetic.DD.node||a.startDrag(b)})},Kinetic.Node.prototype._dragChange=function(){if(this.attrs.draggable)this._listenDrag();else{this._dragCleanup();var a=this.getStage(),b=Kinetic.DD;a&&b.node&&b.node._id===this._id&&b.node.stopDrag()}},Kinetic.Node.prototype._dragCleanup=function(){this.off("mousedown.kinetic"),this.off("touchstart.kinetic")},Kinetic.Factory.addGetterSetter(Kinetic.Node,"dragBoundFunc"),Kinetic.Factory.addGetter(Kinetic.Node,"draggable",!1),Kinetic.Node.prototype.isDraggable=Kinetic.Node.prototype.getDraggable;var b=document.getElementsByTagName("html")[0];b.addEventListener("mouseup",Kinetic.DD._endDragBefore,!0),b.addEventListener("touchend",Kinetic.DD._endDragBefore,!0),b.addEventListener("mouseup",Kinetic.DD._endDragAfter,!1),b.addEventListener("touchend",Kinetic.DD._endDragAfter,!1)}(),function(){Kinetic.Util.addMethods(Kinetic.Container,{__init:function(a){this.children=new Kinetic.Collection,Kinetic.Node.call(this,a)},getChildren:function(){return this.children},hasChildren:function(){return this.getChildren().length>0},removeChildren:function(){for(var a,b=this.children;b.length>0;)a=b[0],a.hasChildren()&&a.removeChildren(),a.remove();return this},destroyChildren:function(){for(var a=this.children;a.length>0;)a[0].destroy();return this},add:function(a){var b=this.children;return this._validateAdd(a),a.index=b.length,a.parent=this,b.push(a),this._fire("add",{child:a}),this},destroy:function(){this.hasChildren()&&this.destroyChildren(),Kinetic.Node.prototype.destroy.call(this)},find:function(a){var b,c,d,e,f,g,h,i=[],j=a.replace(/ /g,"").split(","),k=j.length;for(b=0;k>b;b++)if(d=j[b],"#"===d.charAt(0))f=this._getNodeById(d.slice(1)),f&&i.push(f);else if("."===d.charAt(0))e=this._getNodesByName(d.slice(1)),i=i.concat(e);else for(g=this.getChildren(),h=g.length,c=0;h>c;c++)i=i.concat(g[c]._get(d));return Kinetic.Collection.toCollection(i)},_getNodeById:function(a){var b=Kinetic.ids[a];return void 0!==b&&this.isAncestorOf(b)?b:null},_getNodesByName:function(a){var b=Kinetic.names[a]||[];return this._getDescendants(b)},_get:function(a){for(var b=Kinetic.Node.prototype._get.call(this,a),c=this.getChildren(),d=c.length,e=0;d>e;e++)b=b.concat(c[e]._get(a));return b},toObject:function(){var a=Kinetic.Node.prototype.toObject.call(this);a.children=[];for(var b=this.getChildren(),c=b.length,d=0;c>d;d++){var e=b[d];a.children.push(e.toObject())}return a},_getDescendants:function(a){for(var b=[],c=a.length,d=0;c>d;d++){var e=a[d];this.isAncestorOf(e)&&b.push(e)}return b},isAncestorOf:function(a){for(var b=a.getParent();b;){if(b._id===this._id)return!0;b=b.getParent()}return!1},clone:function(a){var b=Kinetic.Node.prototype.clone.call(this,a);return this.getChildren().each(function(a){b.add(a.clone())}),b},getAllIntersections:function(){for(var a=Kinetic.Util._getXY(Array.prototype.slice.call(arguments)),b=[],c=this.find("Shape"),d=c.length,e=0;d>e;e++){var f=c[e];f.isVisible()&&f.intersects(a)&&b.push(f)}return b},_setChildrenIndices:function(){this.children.each(function(a,b){a.index=b})},drawScene:function(a){var b=this.getLayer(),c=this.getClipWidth()&&this.getClipHeight();return!a&&b&&(a=b.getCanvas()),this.isVisible()&&(c?a.getContext()._clip(this):this._drawChildren(a)),this},_drawChildren:function(a){this.children.each(function(b){b.drawScene(a)})},drawHit:function(){var a,b=this.getClipWidth()&&this.getClipHeight()&&"Stage"!==this.nodeType,c=0,d=0,e=[];if(this.shouldDrawHit()){for(b&&(a=this.getLayer().hitCanvas,a.getContext()._clip(this)),e=this.children,d=e.length,c=0;d>c;c++)e[c].drawHit();b&&a.getContext()._context.restore()}return this}}),Kinetic.Util.extend(Kinetic.Container,Kinetic.Node),Kinetic.Container.prototype.get=Kinetic.Container.prototype.find,Kinetic.Factory.addBoxGetterSetter(Kinetic.Container,"clip")}(),function(){function a(a){a.fill()}function b(a){a.stroke()}function c(a){a.fill()}function d(a){a.stroke()}function e(){this._clearCache(f)}var f="hasShadow";Kinetic.Util.addMethods(Kinetic.Shape,{__init:function(f){this.nodeType="Shape",this._fillFunc=a,this._strokeFunc=b,this._fillFuncHit=c,this._strokeFuncHit=d;for(var g,h=Kinetic.shapes;;)if(g=Kinetic.Util.getRandomColor(),g&&!(g in h))break;this.colorKey=g,h[g]=this,Kinetic.Node.call(this,f),this._setDrawFuncs(),this.on("shadowColorChange.kinetic shadowBlurChange.kinetic shadowOffsetChange.kinetic shadowOpacityChange.kinetic",e)},hasChildren:function(){return!1},getChildren:function(){return[]},getContext:function(){return this.getLayer().getContext()},getCanvas:function(){return this.getLayer().getCanvas()},hasShadow:function(){return this._getCache(f,this._hasShadow)},_hasShadow:function(){return this.getShadowEnabled()&&0!==this.getShadowOpacity()&&!!(this.getShadowColor()||this.getShadowBlur()||this.getShadowOffsetX()||this.getShadowOffsetY())},hasFill:function(){return!!(this.getFill()||this.getFillPatternImage()||this.getFillLinearGradientColorStops()||this.getFillRadialGradientColorStops())},hasStroke:function(){return!(!this.getStroke()&&!this.getStrokeWidth())},_get:function(a){return this.className===a||this.nodeType===a?[this]:[]},intersects:function(){var a,b=Kinetic.Util._getXY(Array.prototype.slice.call(arguments)),c=this.getStage(),d=c.bufferHitCanvas;return d.getContext().clear(),this.drawScene(d),a=d.context.getImageData(0|b.x,0|b.y,1,1).data,a[3]>0},enableFill:function(){return this._setAttr("fillEnabled",!0),this},disableFill:function(){return this._setAttr("fillEnabled",!1),this},enableStroke:function(){return this._setAttr("strokeEnabled",!0),this},disableStroke:function(){return this._setAttr("strokeEnabled",!1),this},enableStrokeScale:function(){return this._setAttr("strokeScaleEnabled",!0),this},disableStrokeScale:function(){return this._setAttr("strokeScaleEnabled",!1),this},enableShadow:function(){return this._setAttr("shadowEnabled",!0),this},disableShadow:function(){return this._setAttr("shadowEnabled",!1),this},enableDashArray:function(){return this._setAttr("dashArrayEnabled",!0),this},disableDashArray:function(){return this._setAttr("dashArrayEnabled",!1),this},destroy:function(){return Kinetic.Node.prototype.destroy.call(this),delete Kinetic.shapes[this.colorKey],this},_useBufferCanvas:function(){return(this.hasShadow()||1!==this.getAbsoluteOpacity())&&this.hasFill()&&this.hasStroke()},drawScene:function(a){var b,c,d,e=a||this.getLayer().getCanvas(),f=e.getContext(),g=this.getDrawFunc(),h=this.hasShadow();return g&&this.isVisible()&&(this._useBufferCanvas()?(b=this.getStage(),c=b.bufferCanvas,d=c.getContext(),d.clear(),d.save(),d._applyLineJoin(this),d._applyAncestorTransforms(this),g.call(this,d),d.restore(),f.save(),h&&(f.save(),f._applyShadow(this),f.drawImage(c._canvas,0,0),f.restore()),f._applyOpacity(this),f.drawImage(c._canvas,0,0),f.restore()):(f.save(),f._applyLineJoin(this),f._applyAncestorTransforms(this),h&&(f.save(),f._applyShadow(this),g.call(this,f),f.restore()),f._applyOpacity(this),g.call(this,f),f.restore())),this},drawHit:function(){var a=this.getAttrs(),b=a.drawHitFunc||a.drawFunc,c=this.getLayer().hitCanvas,d=c.getContext();return b&&this.shouldDrawHit()&&(d.save(),d._applyLineJoin(this),d._applyAncestorTransforms(this),b.call(this,d),d.restore()),this},_setDrawFuncs:function(){!this.attrs.drawFunc&&this.drawFunc&&this.setDrawFunc(this.drawFunc),!this.attrs.drawHitFunc&&this.drawHitFunc&&this.setDrawHitFunc(this.drawHitFunc)}}),Kinetic.Util.extend(Kinetic.Shape,Kinetic.Node),Kinetic.Factory.addColorGetterSetter(Kinetic.Shape,"stroke"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"lineJoin"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"lineCap"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"strokeWidth"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"drawFunc"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"drawHitFunc"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"dashArray"),Kinetic.Factory.addColorGetterSetter(Kinetic.Shape,"shadowColor"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"shadowBlur"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"shadowOpacity"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillPatternImage"),Kinetic.Factory.addColorGetterSetter(Kinetic.Shape,"fill"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillPatternX"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillPatternY"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillLinearGradientColorStops"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillRadialGradientStartRadius"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillRadialGradientEndRadius"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillRadialGradientColorStops"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillPatternRepeat"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillEnabled",!0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"strokeEnabled",!0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"shadowEnabled",!0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"dashArrayEnabled",!0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillPriority","color"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"strokeScaleEnabled",!0),Kinetic.Factory.addPointGetterSetter(Kinetic.Shape,"fillPatternOffset",0),Kinetic.Factory.addPointGetterSetter(Kinetic.Shape,"fillPatternScale",1),Kinetic.Factory.addPointGetterSetter(Kinetic.Shape,"fillLinearGradientStartPoint",0),Kinetic.Factory.addPointGetterSetter(Kinetic.Shape,"fillLinearGradientEndPoint",0),Kinetic.Factory.addPointGetterSetter(Kinetic.Shape,"fillRadialGradientStartPoint",0),Kinetic.Factory.addPointGetterSetter(Kinetic.Shape,"fillRadialGradientEndPoint",0),Kinetic.Factory.addPointGetterSetter(Kinetic.Shape,"shadowOffset",0),Kinetic.Factory.addRotationGetterSetter(Kinetic.Shape,"fillPatternRotation",0)}(),function(){function a(a,b){a.content.addEventListener(b,function(c){a[I+b](c)},!1)}var b="Stage",c="string",d="px",e="mouseout",f="mouseleave",g="mouseover",h="mouseenter",i="mousemove",j="mousedown",k="mouseup",l="click",m="dblclick",n="touchstart",o="touchend",p="tap",q="dbltap",r="touchmove",s="contentMouseout",t="contentMouseover",u="contentMousemove",v="contentMousedown",w="contentMouseup",x="contentClick",y="contentDblclick",z="contentTouchstart",A="contentTouchend",B="contentDbltap",C="contentTouchmove",D="div",E="relative",F="inline-block",G="kineticjs-content",H=" ",I="_",J="container",K="",L=[j,i,k,e,n,r,o,g],M=L.length;Kinetic.Util.addMethods(Kinetic.Stage,{___init:function(a){this.nodeType=b,Kinetic.Container.call(this,a),this._id=Kinetic.idCounter++,this._buildDOM(),this._bindContentEvents(),Kinetic.stages.push(this)},_validateAdd:function(a){"Layer"!==a.getType()&&Kinetic.Util.error("You may only add layers to the stage.")},setContainer:function(a){return typeof a===c&&(a=document.getElementById(a)),this._setAttr(J,a),this},draw:function(){return Kinetic.Node.prototype.draw.call(this),this},setHeight:function(a){return Kinetic.Node.prototype.setHeight.call(this,a),this._resizeDOM(),this},setWidth:function(a){return Kinetic.Node.prototype.setWidth.call(this,a),this._resizeDOM(),this},clear:function(){var a,b=this.children,c=b.length;for(a=0;c>a;a++)b[a].clear();return this},destroy:function(){var a=this.content;Kinetic.Container.prototype.destroy.call(this),a&&Kinetic.Util._isInDocument(a)&&this.getContainer().removeChild(a)},getMousePosition:function(){return this.mousePos},getTouchPosition:function(){return this.touchPos},getPointerPosition:function(){return this.getTouchPosition()||this.getMousePosition()},getStage:function(){return this},getContent:function(){return this.content},toDataURL:function(a){function b(e){var f=i[e],j=f.toDataURL(),k=new Image;k.onload=function(){h.drawImage(k,0,0),e<i.length-1?b(e+1):a.callback(g.toDataURL(c,d))},k.src=j}a=a||{};var c=a.mimeType||null,d=a.quality||null,e=a.x||0,f=a.y||0,g=new Kinetic.SceneCanvas({width:a.width||this.getWidth(),height:a.height||this.getHeight(),pixelRatio:1}),h=g.getContext()._context,i=this.children;(e||f)&&h.translate(-1*e,-1*f),b(0)},toImage:function(a){var b=a.callback;a.callback=function(a){Kinetic.Util._getImage(a,function(a){b(a)})},this.toDataURL(a)},getIntersection:function(){var a,b,c=Kinetic.Util._getXY(Array.prototype.slice.call(arguments)),d=this.getChildren(),e=d.length,f=e-1;for(a=f;a>=0;a--)if(b=d[a].getIntersection(c))return b;return null},_resizeDOM:function(){if(this.content){var a,b,c=this.getWidth(),e=this.getHeight(),f=this.getChildren(),g=f.length;for(this.content.style.width=c+d,this.content.style.height=e+d,this.bufferCanvas.setSize(c,e),this.bufferHitCanvas.setSize(c,e),a=0;g>a;a++)b=f[a],b.getCanvas().setSize(c,e),b.hitCanvas.setSize(c,e),b.draw()}},add:function(a){return Kinetic.Container.prototype.add.call(this,a),a.canvas.setSize(this.attrs.width,this.attrs.height),a.hitCanvas.setSize(this.attrs.width,this.attrs.height),a.draw(),this.content.appendChild(a.canvas._canvas),this},getParent:function(){return null},getLayer:function(){return null},getLayers:function(){return this.getChildren()},_setPointerPosition:function(a){a||(a=window.event),this._setMousePosition(a),this._setTouchPosition(a)},_bindContentEvents:function(){var b;for(b=0;M>b;b++)a(this,L[b])},_mouseover:function(a){this._fire(t,a)},_mouseout:function(a){this._setPointerPosition(a);var b=this.targetShape;b&&!Kinetic.isDragging()&&(b._fireAndBubble(e,a),b._fireAndBubble(f,a),this.targetShape=null),this.mousePos=void 0,this._fire(s,a)},_mousemove:function(a){this._setPointerPosition(a);var b=Kinetic.DD,c=this.getIntersection(this.getPointerPosition()),d=c&&c.shape?c.shape:void 0;d?Kinetic.isDragging()||255!==c.pixel[3]||this.targetShape&&this.targetShape._id===d._id?d._fireAndBubble(i,a):(this.targetShape&&(this.targetShape._fireAndBubble(e,a,d),this.targetShape._fireAndBubble(f,a,d)),d._fireAndBubble(g,a,this.targetShape),d._fireAndBubble(h,a,this.targetShape),this.targetShape=d):this.targetShape&&!Kinetic.isDragging()&&(this.targetShape._fireAndBubble(e,a),this.targetShape._fireAndBubble(f,a),this.targetShape=null),this._fire(u,a),b&&b._drag(a),a.preventDefault&&a.preventDefault()},_mousedown:function(a){this._setPointerPosition(a);var b=this.getIntersection(this.getPointerPosition()),c=b&&b.shape?b.shape:void 0;Kinetic.listenClickTap=!0,c&&(this.clickStartShape=c,c._fireAndBubble(j,a)),this._fire(v),a.preventDefault&&a.preventDefault()},_mouseup:function(a){this._setPointerPosition(a);var b=this.getIntersection(this.getPointerPosition()),c=b&&b.shape?b.shape:void 0,d=!1;Kinetic.inDblClickWindow?(d=!0,Kinetic.inDblClickWindow=!1):Kinetic.inDblClickWindow=!0,setTimeout(function(){Kinetic.inDblClickWindow=!1},Kinetic.dblClickWindow),c&&(c._fireAndBubble(k,a),Kinetic.listenClickTap&&c._id===this.clickStartShape._id&&(c._fireAndBubble(l,a),d&&c._fireAndBubble(m,a))),this._fire(w),Kinetic.listenClickTap&&(this._fire(x,a),d&&this._fire(y,a)),Kinetic.listenClickTap=!1,a.preventDefault&&a.preventDefault()},_touchstart:function(a){this._setPointerPosition(a);var b=this.getIntersection(this.getPointerPosition()),c=b&&b.shape?b.shape:void 0;Kinetic.listenClickTap=!0,c&&(this.tapStartShape=c,c._fireAndBubble(n,a),c.isListening()&&a.preventDefault&&a.preventDefault()),this._fire(z,a)},_touchend:function(a){this._setPointerPosition(a);var b=this.getIntersection(this.getPointerPosition()),c=b&&b.shape?b.shape:void 0,d=!1;Kinetic.inDblClickWindow?(d=!0,Kinetic.inDblClickWindow=!1):Kinetic.inDblClickWindow=!0,setTimeout(function(){Kinetic.inDblClickWindow=!1},Kinetic.dblClickWindow),c&&(c._fireAndBubble(o,a),Kinetic.listenClickTap&&c._id===this.tapStartShape._id&&(c._fireAndBubble(p,a),d&&c._fireAndBubble(q,a)),c.isListening()&&a.preventDefault&&a.preventDefault()),Kinetic.listenClickTap&&(this._fire(A,a),d&&this._fire(B,a)),Kinetic.listenClickTap=!1},_touchmove:function(a){this._setPointerPosition(a);var b=Kinetic.DD,c=this.getIntersection(this.getPointerPosition()),d=c&&c.shape?c.shape:void 0;d&&(d._fireAndBubble(r,a),d.isListening()&&a.preventDefault&&a.preventDefault()),this._fire(C,a),b&&b._drag(a)},_setMousePosition:function(a){var b=this._getContentPosition(),c=a.offsetX,d=a.clientX,e=0,f=0;void 0!==c?(e=c,f=a.offsetY):"mozilla"===Kinetic.UA.browser?(e=a.layerX,f=a.layerY):void 0!==d&&b&&(e=d-b.left,f=a.clientY-b.top),this.mousePos={x:e,y:f}},_setTouchPosition:function(a){var b,c,d,e=this._getContentPosition();void 0!==a.touches&&1===a.touches.length&&(b=a.touches[0],c=b.clientX-e.left,d=b.clientY-e.top,this.touchPos={x:c,y:d})},_getContentPosition:function(){var a=this.content.getBoundingClientRect();return{top:a.top,left:a.left}},_buildDOM:function(){var a=this.getContainer();a.innerHTML=K,this.content=document.createElement(D),this.content.style.position=E,this.content.style.display=F,this.content.className=G,a.appendChild(this.content),this.bufferCanvas=new Kinetic.SceneCanvas,this.bufferHitCanvas=new Kinetic.HitCanvas,this._resizeDOM()},_onContent:function(a,b){var c,d,e=a.split(H),f=e.length;for(c=0;f>c;c++)d=e[c],this.content.addEventListener(d,b,!1)}}),Kinetic.Util.extend(Kinetic.Stage,Kinetic.Container),Kinetic.Factory.addGetter(Kinetic.Stage,"container")}(),function(){var a="#",b="beforeDraw",c="draw";Kinetic.Util.addMethods(Kinetic.Layer,{___init:function(a){this.nodeType="Layer",this.canvas=new Kinetic.SceneCanvas,this.hitCanvas=new Kinetic.HitCanvas,Kinetic.Container.call(this,a)},_validateAdd:function(a){var b=a.getType();"Group"!==b&&"Shape"!==b&&Kinetic.Util.error("You may only add groups and shapes to a layer.")},getIntersection:function(){var b,c,d,e=Kinetic.Util._getXY(Array.prototype.slice.call(arguments));if(this.isVisible()&&this.isListening()){if(b=this.hitCanvas.context._context.getImageData(0|e.x,0|e.y,1,1).data,255===b[3])return c=Kinetic.Util._rgbToHex(b[0],b[1],b[2]),d=Kinetic.shapes[a+c],{shape:d,pixel:b};if(b[0]>0||b[1]>0||b[2]>0||b[3]>0)return{pixel:b}}return null},drawScene:function(a){return a=a||this.getCanvas(),this._fire(b,{node:this}),this.getClearBeforeDraw()&&a.getContext().clear(),Kinetic.Container.prototype.drawScene.call(this,a),this._fire(c,{node:this}),this},drawHit:function(){var a=this.getLayer();return a&&a.getClearBeforeDraw()&&a.getHitCanvas().getContext().clear(),Kinetic.Container.prototype.drawHit.call(this),this},getCanvas:function(){return this.canvas},getHitCanvas:function(){return this.hitCanvas},getContext:function(){return this.getCanvas().getContext()},clear:function(){var a=this.getContext(),b=this.getHitCanvas().getContext();return a.clear.apply(a,arguments),b.clear.apply(b,arguments),this},setVisible:function(a){return Kinetic.Node.prototype.setVisible.call(this,a),a?(this.getCanvas()._canvas.style.display="block",this.hitCanvas._canvas.style.display="block"):(this.getCanvas()._canvas.style.display="none",this.hitCanvas._canvas.style.display="none"),this},setZIndex:function(a){Kinetic.Node.prototype.setZIndex.call(this,a);var b=this.getStage();return b&&(b.content.removeChild(this.getCanvas()._canvas),a<b.getChildren().length-1?b.content.insertBefore(this.getCanvas()._canvas,b.getChildren()[a+1].getCanvas()._canvas):b.content.appendChild(this.getCanvas()._canvas)),this},moveToTop:function(){Kinetic.Node.prototype.moveToTop.call(this);var a=this.getStage();a&&(a.content.removeChild(this.getCanvas()._canvas),a.content.appendChild(this.getCanvas()._canvas))},moveUp:function(){if(Kinetic.Node.prototype.moveUp.call(this)){var a=this.getStage();a&&(a.content.removeChild(this.getCanvas()._canvas),this.index<a.getChildren().length-1?a.content.insertBefore(this.getCanvas()._canvas,a.getChildren()[this.index+1].getCanvas()._canvas):a.content.appendChild(this.getCanvas()._canvas))}},moveDown:function(){if(Kinetic.Node.prototype.moveDown.call(this)){var a=this.getStage();if(a){var b=a.getChildren();a.content.removeChild(this.getCanvas()._canvas),a.content.insertBefore(this.getCanvas()._canvas,b[this.index+1].getCanvas()._canvas)}}},moveToBottom:function(){if(Kinetic.Node.prototype.moveToBottom.call(this)){var a=this.getStage();if(a){var b=a.getChildren();a.content.removeChild(this.getCanvas()._canvas),a.content.insertBefore(this.getCanvas()._canvas,b[1].getCanvas()._canvas)
+}}},getLayer:function(){return this},remove:function(){var a=this.getStage(),b=this.getCanvas(),c=b._canvas;return Kinetic.Node.prototype.remove.call(this),a&&c&&Kinetic.Util._isInDocument(c)&&a.content.removeChild(c),this},getStage:function(){return this.parent}}),Kinetic.Util.extend(Kinetic.Layer,Kinetic.Container),Kinetic.Factory.addGetterSetter(Kinetic.Layer,"clearBeforeDraw",!0)}(),function(){Kinetic.Util.addMethods(Kinetic.Group,{___init:function(a){this.nodeType="Group",Kinetic.Container.call(this,a)},_validateAdd:function(a){var b=a.getType();"Group"!==b&&"Shape"!==b&&Kinetic.Util.error("You may only add groups and shapes to groups.")}}),Kinetic.Util.extend(Kinetic.Group,Kinetic.Container)}(),function(){Kinetic.Rect=function(a){this.___init(a)},Kinetic.Rect.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="Rect"},drawFunc:function(a){var b=this.getCornerRadius(),c=this.getWidth(),d=this.getHeight();a.beginPath(),b?(a.moveTo(b,0),a.lineTo(c-b,0),a.arc(c-b,b,b,3*Math.PI/2,0,!1),a.lineTo(c,d-b),a.arc(c-b,d-b,b,0,Math.PI/2,!1),a.lineTo(b,d),a.arc(b,d-b,b,Math.PI/2,Math.PI,!1),a.lineTo(0,b),a.arc(b,b,b,Math.PI,3*Math.PI/2,!1)):a.rect(0,0,c,d),a.closePath(),a.fillStrokeShape(this)}},Kinetic.Util.extend(Kinetic.Rect,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Rect,"cornerRadius",0)}(),function(){var a=2*Math.PI-1e-4,b="Circle";Kinetic.Circle=function(a){this.___init(a)},Kinetic.Circle.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className=b},drawFunc:function(b){b.beginPath(),b.arc(0,0,this.getRadius(),0,a,!1),b.closePath(),b.fillStrokeShape(this)},getWidth:function(){return 2*this.getRadius()},getHeight:function(){return 2*this.getRadius()},setWidth:function(a){Kinetic.Node.prototype.setWidth.call(this,a),this.setRadius(a/2)},setHeight:function(a){Kinetic.Node.prototype.setHeight.call(this,a),this.setRadius(a/2)}},Kinetic.Util.extend(Kinetic.Circle,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Circle,"radius",0)}(),function(){var a=2*Math.PI-1e-4,b="Ellipse";Kinetic.Ellipse=function(a){this.___init(a)},Kinetic.Ellipse.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className=b},drawFunc:function(b){var c=this.getRadius();b.beginPath(),b.save(),c.x!==c.y&&b.scale(1,c.y/c.x),b.arc(0,0,c.x,0,a,!1),b.restore(),b.closePath(),b.fillStrokeShape(this)},getWidth:function(){return 2*this.getRadius().x},getHeight:function(){return 2*this.getRadius().y},setWidth:function(a){Kinetic.Node.prototype.setWidth.call(this,a),this.setRadius({x:a/2})},setHeight:function(a){Kinetic.Node.prototype.setHeight.call(this,a),this.setRadius({y:a/2})}},Kinetic.Util.extend(Kinetic.Ellipse,Kinetic.Shape),Kinetic.Factory.addPointGetterSetter(Kinetic.Ellipse,"radius",0)}(),function(){Kinetic.Wedge=function(a){this.___init(a)},Kinetic.Wedge.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="Wedge"},drawFunc:function(a){a.beginPath(),a.arc(0,0,this.getRadius(),0,this.getAngle(),this.getClockwise()),a.lineTo(0,0),a.closePath(),a.fillStrokeShape(this)}},Kinetic.Util.extend(Kinetic.Wedge,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Wedge,"radius",0),Kinetic.Factory.addRotationGetterSetter(Kinetic.Wedge,"angle",0),Kinetic.Factory.addGetterSetter(Kinetic.Wedge,"clockwise",!1)}(),function(){var a="Image",b="set";Kinetic.Image=function(a){this.___init(a)},Kinetic.Image.prototype={___init:function(b){Kinetic.Shape.call(this,b),this.className=a},_useBufferCanvas:function(){return(this.hasShadow()||1!==this.getAbsoluteOpacity())&&this.hasStroke()},drawFunc:function(a){var b,c,d,e=this.getWidth(),f=this.getHeight();this.getFilter()&&this._applyFilter&&(this.applyFilter(),this._applyFilter=!1),this.filterCanvas?(d=this.filterCanvas._canvas,c=[d,0,0,e,f]):(d=this.getImage(),d&&(b=this.getCrop(),b?(b.x=b.x||0,b.y=b.y||0,b.width=b.width||d.width-b.x,b.height=b.height||d.height-b.y,c=[d,b.x,b.y,b.width,b.height,0,0,e,f]):c=[d,0,0,e,f])),a.beginPath(),a.rect(0,0,e,f),a.closePath(),a.fillStrokeShape(this),d&&a.drawImage.apply(a,c)},drawHitFunc:function(a){var b=this.getWidth(),c=this.getHeight(),d=this.imageHitRegion;d?(a.drawImage(d,0,0,b,c),a.beginPath(),a.rect(0,0,b,c),a.closePath(),a.strokeShape(this)):(a.beginPath(),a.rect(0,0,b,c),a.closePath(),a.fillStrokeShape(this))},applyFilter:function(){var a,b,c,d=this.getImage(),e=(this.getWidth(),this.getHeight(),this.getFilter()),f=this.getCrop()||{};f.x=f.x||0,f.y=f.y||0,f.width=f.width||d.width-f.x,f.height=f.height||d.height-f.y,this.filterCanvas&&this.filterCanvas.getWidth()===f.width&&this.filterCanvas.getHeight()===f.height?(a=this.filterCanvas,a.getContext().clear()):a=this.filterCanvas=new Kinetic.SceneCanvas({width:f.width,height:f.height,pixelRatio:1}),b=a.getContext();try{b.drawImage(d,f.x,f.y,f.width,f.height,0,0,f.width,f.height),c=b.getImageData(0,0,f.width,f.height),e.call(this,c),b.putImageData(c,0,0)}catch(g){this.clearFilter(),Kinetic.Util.warn("Unable to apply filter. "+g.message)}},clearFilter:function(){this.filterCanvas=null,this._applyFilter=!1},createImageHitRegion:function(a){var b,c,d,e,f,g=this,h=this.getWidth(),i=this.getHeight(),j=new Kinetic.SceneCanvas({width:h,height:i}),k=j.getContext()._context,l=this.getImage();k.drawImage(l,0,0);try{for(b=k.getImageData(0,0,h,i),c=b.data,f=c.length,d=Kinetic.Util._hexToRgb(this.colorKey),e=0;f>e;e+=4)c[e+3]>0&&(c[e]=d.r,c[e+1]=d.g,c[e+2]=d.b);Kinetic.Util._getImage(b,function(b){g.imageHitRegion=b,a&&a()})}catch(m){Kinetic.Util.warn("Unable to create image hit region. "+m.message)}},clearImageHitRegion:function(){delete this.imageHitRegion},getWidth:function(){var a=this.getImage();return this.attrs.width||(a?a.width:0)},getHeight:function(){var a=this.getImage();return this.attrs.height||(a?a.height:0)}},Kinetic.Util.extend(Kinetic.Image,Kinetic.Shape),Kinetic.Factory.addFilterGetterSetter=function(a,b,c){this.addGetter(a,b,c),this.addFilterSetter(a,b)},Kinetic.Factory.addFilterSetter=function(a,c){var d=b+Kinetic.Util._capitalize(c);a.prototype[d]=function(a){this._setAttr(c,a),this._applyFilter=!0}},Kinetic.Factory.addGetterSetter(Kinetic.Image,"image"),Kinetic.Factory.addBoxGetterSetter(Kinetic.Image,"crop"),Kinetic.Factory.addFilterGetterSetter(Kinetic.Image,"filter")}(),function(){Kinetic.Polygon=function(a){this.___init(a)},Kinetic.Polygon.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="Polygon"},drawFunc:function(a){var b=this.getPoints(),c=b.length;a.beginPath(),a.moveTo(b[0].x,b[0].y);for(var d=1;c>d;d++)a.lineTo(b[d].x,b[d].y);a.closePath(),a.fillStrokeShape(this)}},Kinetic.Util.extend(Kinetic.Polygon,Kinetic.Shape),Kinetic.Factory.addPointsGetterSetter(Kinetic.Polygon,"points")}(),function(){function a(a){a.fillText(this.partialText,0,0)}function b(a){a.strokeText(this.partialText,0,0)}var c="auto",d="Calibri",e="canvas",f="center",g="Change.kinetic",h="2d",i="-",j="",k="left",l="text",m="Text",n="middle",o="normal",p="px ",q=" ",r="right",s="word",t="char",u="none",v=["fontFamily","fontSize","fontStyle","padding","align","lineHeight","text","width","height","wrap"],w=v.length,x=document.createElement(e).getContext(h);Kinetic.Text=function(a){this.___init(a)},Kinetic.Text.prototype={___init:function(d){var e=this;void 0===d.width&&(d.width=c),void 0===d.height&&(d.height=c),Kinetic.Shape.call(this,d),this._fillFunc=a,this._strokeFunc=b,this.className=m;for(var f=0;w>f;f++)this.on(v[f]+g,e._setTextData);this._setTextData()},drawFunc:function(a){var b=this.getPadding(),c=(this.getFontStyle(),this.getFontSize(),this.getFontFamily(),this.getTextHeight()),d=this.getLineHeight()*c,e=this.textArr,g=e.length,h=this.getWidth();a.setAttr("font",this._getContextFont()),a.setAttr("textBaseline",n),a.setAttr("textAlign",k),a.save(),a.translate(b,0),a.translate(0,b+c/2);for(var i=0;g>i;i++){var j=e[i],l=j.text,m=j.width;a.save(),this.getAlign()===r?a.translate(h-m-2*b,0):this.getAlign()===f&&a.translate((h-m-2*b)/2,0),this.partialText=l,a.fillStrokeShape(this),a.restore(),a.translate(0,d)}a.restore()},drawHitFunc:function(a){var b=this.getWidth(),c=this.getHeight();a.beginPath(),a.rect(0,0,b,c),a.closePath(),a.fillStrokeShape(this)},setText:function(a){var b=Kinetic.Util._isString(a)?a:a.toString();this._setAttr(l,b)},getWidth:function(){return this.attrs.width===c?this.getTextWidth()+2*this.getPadding():this.attrs.width},getHeight:function(){return this.attrs.height===c?this.getTextHeight()*this.textArr.length*this.getLineHeight()+2*this.getPadding():this.attrs.height},getTextWidth:function(){return this.textWidth},getTextHeight:function(){return this.textHeight},_getTextSize:function(a){var b,c=x,d=this.getFontSize();return c.save(),c.font=this._getContextFont(),b=c.measureText(a),c.restore(),{width:b.width,height:parseInt(d,10)}},_getContextFont:function(){return this.getFontStyle()+q+this.getFontSize()+p+this.getFontFamily()},_addTextLine:function(a,b){return this.textArr.push({text:a,width:b})},_getTextWidth:function(a){return x.measureText(a).width},_setTextData:function(){var a=this.getText().split("\n"),b=+this.getFontSize(),d=0,e=this.getLineHeight()*b,f=this.attrs.width,g=this.attrs.height,h=f!==c,j=g!==c,k=this.getPadding(),l=f-2*k,m=g-2*k,n=0,o=this.getWrap(),r=o!==u,s=o!==t&&r;this.textArr=[],x.save(),x.font=this.getFontStyle()+q+b+p+this.getFontFamily();for(var v=0,w=a.length;w>v;++v){var y=a[v],z=this._getTextWidth(y);if(h&&z>l)for(;y.length>0;){for(var A=0,B=y.length,C="",D=0;B>A;){var E=A+B>>>1,F=y.slice(0,E+1),G=this._getTextWidth(F);l>=G?(A=E+1,C=F,D=G):B=E}if(!C)break;if(s){var H=Math.max(C.lastIndexOf(q),C.lastIndexOf(i))+1;H>0&&(A=H,C=C.slice(0,A),D=this._getTextWidth(C))}if(this._addTextLine(C,D),n+=e,!r||j&&n+e>m)break;if(y=y.slice(A),y.length>0&&(z=this._getTextWidth(y),l>=z)){this._addTextLine(y,z),n+=e;break}}else this._addTextLine(y,z),n+=e,d=Math.max(d,z);if(j&&n+e>m)break}x.restore(),this.textHeight=b,this.textWidth=d}},Kinetic.Util.extend(Kinetic.Text,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Text,"fontFamily",d),Kinetic.Factory.addGetterSetter(Kinetic.Text,"fontSize",12),Kinetic.Factory.addGetterSetter(Kinetic.Text,"fontStyle",o),Kinetic.Factory.addGetterSetter(Kinetic.Text,"padding",0),Kinetic.Factory.addGetterSetter(Kinetic.Text,"align",k),Kinetic.Factory.addGetterSetter(Kinetic.Text,"lineHeight",1),Kinetic.Factory.addGetterSetter(Kinetic.Text,"wrap",s),Kinetic.Factory.addGetter(Kinetic.Text,l,j),Kinetic.Factory.addSetter(Kinetic.Text,"width"),Kinetic.Factory.addSetter(Kinetic.Text,"height")}(),function(){Kinetic.Line=function(a){this.___init(a)},Kinetic.Line.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="Line"},drawFunc:function(a){var b,c,d=this.getPoints(),e=d.length;for(a.beginPath(),a.moveTo(d[0].x,d[0].y),b=1;e>b;b++)c=d[b],a.lineTo(c.x,c.y);a.strokeShape(this)}},Kinetic.Util.extend(Kinetic.Line,Kinetic.Shape),Kinetic.Factory.addPointsGetterSetter(Kinetic.Line,"points")}(),function(){Kinetic.Spline=function(a){this.___init(a)},Kinetic.Spline.prototype={___init:function(a){var b=this;Kinetic.Shape.call(this,a),this.className="Spline",this.on("pointsChange.kinetic tensionChange.kinetic",function(){b._setAllPoints()}),this._setAllPoints()},drawFunc:function(a){var b,c,d,e,f=this.getPoints(),g=f.length,h=this.getTension();if(a.beginPath(),a.moveTo(f[0].x,f[0].y),0!==h&&g>2){for(b=this.allPoints,c=b.length,d=2,a.quadraticCurveTo(b[0].x,b[0].y,b[1].x,b[1].y);c-1>d;)a.bezierCurveTo(b[d].x,b[d++].y,b[d].x,b[d++].y,b[d].x,b[d++].y);a.quadraticCurveTo(b[c-1].x,b[c-1].y,f[g-1].x,f[g-1].y)}else for(d=1;g>d;d++)e=f[d],a.lineTo(e.x,e.y);a.strokeShape(this)},_setAllPoints:function(){this.allPoints=Kinetic.Util._expandPoints(this.getPoints(),this.getTension())}},Kinetic.Util.extend(Kinetic.Spline,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Spline,"tension",1),Kinetic.Factory.addPointsGetterSetter(Kinetic.Spline,"points")}(),function(){Kinetic.Blob=function(a){this.___init(a)},Kinetic.Blob.prototype={___init:function(a){var b=this;Kinetic.Shape.call(this,a),this.className="Blob",this.on("pointsChange.kinetic tensionChange.kinetic",function(){b._setAllPoints()}),this._setAllPoints()},drawFunc:function(a){var b,c,d,e,f=this.getPoints(),g=f.length,h=this.getTension();if(a.beginPath(),a.moveTo(f[0].x,f[0].y),0!==h&&g>2)for(b=this.allPoints,c=b.length,d=0;c-1>d;)a.bezierCurveTo(b[d].x,b[d++].y,b[d].x,b[d++].y,b[d].x,b[d++].y);else for(d=1;g>d;d++)e=f[d],a.lineTo(e.x,e.y);a.closePath(),a.fillStrokeShape(this)},_setAllPoints:function(){var a=this.getPoints(),b=a.length,c=this.getTension(),d=Kinetic.Util,e=d._getControlPoints(a[b-1],a[0],a[1],c),f=d._getControlPoints(a[b-2],a[b-1],a[0],c);this.allPoints=Kinetic.Util._expandPoints(this.getPoints(),this.getTension()),this.allPoints.unshift(e[1]),this.allPoints.push(f[0]),this.allPoints.push(a[b-1]),this.allPoints.push(f[1]),this.allPoints.push(e[0]),this.allPoints.push(a[0])}},Kinetic.Util.extend(Kinetic.Blob,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Blob,"tension",1),Kinetic.Factory.addPointsGetterSetter(Kinetic.Blob,"points")}(),function(){Kinetic.Sprite=function(a){this.___init(a)},Kinetic.Sprite.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="Sprite",this.anim=new Kinetic.Animation;var b=this;this.on("animationChange.kinetic",function(){b.setIndex(0)})},drawFunc:function(a){var b=this.getAnimation(),c=this.getIndex(),d=this.getAnimations()[b][c],e=this.getImage();e&&a.drawImage(e,d.x,d.y,d.width,d.height,0,0,d.width,d.height)},drawHitFunc:function(a){var b=this.getAnimation(),c=this.getIndex(),d=this.getAnimations()[b][c];a.beginPath(),a.rect(0,0,d.width,d.height),a.closePath(),a.fillShape(this)},_useBufferCanvas:function(){return(this.hasShadow()||1!==this.getAbsoluteOpacity())&&this.hasStroke()},start:function(){var a=this,b=this.getLayer();this.anim.setLayers(b),this.interval=setInterval(function(){var b=a.getIndex();a._updateIndex(),a.afterFrameFunc&&b===a.afterFrameIndex&&(a.afterFrameFunc(),delete a.afterFrameFunc,delete a.afterFrameIndex)},1e3/this.getFrameRate()),this.anim.start()},stop:function(){this.anim.stop(),clearInterval(this.interval)},afterFrame:function(a,b){this.afterFrameIndex=a,this.afterFrameFunc=b},_updateIndex:function(){var a=this.getIndex(),b=this.getAnimation(),c=this.getAnimations(),d=c[b],e=d.length;e-1>a?this.setIndex(a+1):this.setIndex(0)}},Kinetic.Util.extend(Kinetic.Sprite,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Sprite,"animation"),Kinetic.Factory.addGetterSetter(Kinetic.Sprite,"animations"),Kinetic.Factory.addGetterSetter(Kinetic.Sprite,"image"),Kinetic.Factory.addGetterSetter(Kinetic.Sprite,"index",0),Kinetic.Factory.addGetterSetter(Kinetic.Sprite,"frameRate",17)}(),function(){Kinetic.Path=function(a){this.___init(a)},Kinetic.Path.prototype={___init:function(a){this.dataArray=[];var b=this;Kinetic.Shape.call(this,a),this.className="Path",this.dataArray=Kinetic.Path.parsePathData(this.getData()),this.on("dataChange.kinetic",function(){b.dataArray=Kinetic.Path.parsePathData(this.getData())})},drawFunc:function(a){var b=this.dataArray,c=!1;a.beginPath();for(var d=0;d<b.length;d++){var e=b[d].command,f=b[d].points;switch(e){case"L":a.lineTo(f[0],f[1]);break;case"M":a.moveTo(f[0],f[1]);break;case"C":a.bezierCurveTo(f[0],f[1],f[2],f[3],f[4],f[5]);break;case"Q":a.quadraticCurveTo(f[0],f[1],f[2],f[3]);break;case"A":var g=f[0],h=f[1],i=f[2],j=f[3],k=f[4],l=f[5],m=f[6],n=f[7],o=i>j?i:j,p=i>j?1:i/j,q=i>j?j/i:1;a.translate(g,h),a.rotate(m),a.scale(p,q),a.arc(0,0,o,k,k+l,1-n),a.scale(1/p,1/q),a.rotate(-m),a.translate(-g,-h);break;case"z":a.closePath(),c=!0}}c?a.fillStrokeShape(this):a.strokeShape(this)}},Kinetic.Util.extend(Kinetic.Path,Kinetic.Shape),Kinetic.Path.getLineLength=function(a,b,c,d){return Math.sqrt((c-a)*(c-a)+(d-b)*(d-b))},Kinetic.Path.getPointOnLine=function(a,b,c,d,e,f,g){void 0===f&&(f=b),void 0===g&&(g=c);var h=(e-c)/(d-b+1e-8),i=Math.sqrt(a*a/(1+h*h));b>d&&(i*=-1);var j,k=h*i;if(d===b)j={x:f,y:g+k};else if((g-c)/(f-b+1e-8)===h)j={x:f+i,y:g+k};else{var l,m,n=this.getLineLength(b,c,d,e);if(1e-8>n)return void 0;var o=(f-b)*(d-b)+(g-c)*(e-c);o/=n*n,l=b+o*(d-b),m=c+o*(e-c);var p=this.getLineLength(f,g,l,m),q=Math.sqrt(a*a-p*p);i=Math.sqrt(q*q/(1+h*h)),b>d&&(i*=-1),k=h*i,j={x:l+i,y:m+k}}return j},Kinetic.Path.getPointOnCubicBezier=function(a,b,c,d,e,f,g,h,i){function j(a){return a*a*a}function k(a){return 3*a*a*(1-a)}function l(a){return 3*a*(1-a)*(1-a)}function m(a){return(1-a)*(1-a)*(1-a)}var n=h*j(a)+f*k(a)+d*l(a)+b*m(a),o=i*j(a)+g*k(a)+e*l(a)+c*m(a);return{x:n,y:o}},Kinetic.Path.getPointOnQuadraticBezier=function(a,b,c,d,e,f,g){function h(a){return a*a}function i(a){return 2*a*(1-a)}function j(a){return(1-a)*(1-a)}var k=f*h(a)+d*i(a)+b*j(a),l=g*h(a)+e*i(a)+c*j(a);return{x:k,y:l}},Kinetic.Path.getPointOnEllipticalArc=function(a,b,c,d,e,f){var g=Math.cos(f),h=Math.sin(f),i={x:c*Math.cos(e),y:d*Math.sin(e)};return{x:a+(i.x*g-i.y*h),y:b+(i.x*h+i.y*g)}},Kinetic.Path.parsePathData=function(a){if(!a)return[];var b=a,c=["m","M","l","L","v","V","h","H","z","Z","c","C","q","Q","t","T","s","S","a","A"];b=b.replace(new RegExp(" ","g"),",");for(var d=0;d<c.length;d++)b=b.replace(new RegExp(c[d],"g"),"|"+c[d]);var e=b.split("|"),f=[],g=0,h=0;for(d=1;d<e.length;d++){var i=e[d],j=i.charAt(0);i=i.slice(1),i=i.replace(new RegExp(",-","g"),"-"),i=i.replace(new RegExp("-","g"),",-"),i=i.replace(new RegExp("e,-","g"),"e-");var k=i.split(",");k.length>0&&""===k[0]&&k.shift();for(var l=0;l<k.length;l++)k[l]=parseFloat(k[l]);for(;k.length>0&&!isNaN(k[0]);){var m,n,o,p,q,r,s,t,u,v,w=null,x=[],y=g,z=h;switch(j){case"l":g+=k.shift(),h+=k.shift(),w="L",x.push(g,h);break;case"L":g=k.shift(),h=k.shift(),x.push(g,h);break;case"m":g+=k.shift(),h+=k.shift(),w="M",x.push(g,h),j="l";break;case"M":g=k.shift(),h=k.shift(),w="M",x.push(g,h),j="L";break;case"h":g+=k.shift(),w="L",x.push(g,h);break;case"H":g=k.shift(),w="L",x.push(g,h);break;case"v":h+=k.shift(),w="L",x.push(g,h);break;case"V":h=k.shift(),w="L",x.push(g,h);break;case"C":x.push(k.shift(),k.shift(),k.shift(),k.shift()),g=k.shift(),h=k.shift(),x.push(g,h);break;case"c":x.push(g+k.shift(),h+k.shift(),g+k.shift(),h+k.shift()),g+=k.shift(),h+=k.shift(),w="C",x.push(g,h);break;case"S":n=g,o=h,m=f[f.length-1],"C"===m.command&&(n=g+(g-m.points[2]),o=h+(h-m.points[3])),x.push(n,o,k.shift(),k.shift()),g=k.shift(),h=k.shift(),w="C",x.push(g,h);break;case"s":n=g,o=h,m=f[f.length-1],"C"===m.command&&(n=g+(g-m.points[2]),o=h+(h-m.points[3])),x.push(n,o,g+k.shift(),h+k.shift()),g+=k.shift(),h+=k.shift(),w="C",x.push(g,h);break;case"Q":x.push(k.shift(),k.shift()),g=k.shift(),h=k.shift(),x.push(g,h);break;case"q":x.push(g+k.shift(),h+k.shift()),g+=k.shift(),h+=k.shift(),w="Q",x.push(g,h);break;case"T":n=g,o=h,m=f[f.length-1],"Q"===m.command&&(n=g+(g-m.points[0]),o=h+(h-m.points[1])),g=k.shift(),h=k.shift(),w="Q",x.push(n,o,g,h);break;case"t":n=g,o=h,m=f[f.length-1],"Q"===m.command&&(n=g+(g-m.points[0]),o=h+(h-m.points[1])),g+=k.shift(),h+=k.shift(),w="Q",x.push(n,o,g,h);break;case"A":p=k.shift(),q=k.shift(),r=k.shift(),s=k.shift(),t=k.shift(),u=g,v=h,g=k.shift(),h=k.shift(),w="A",x=this.convertEndpointToCenterParameterization(u,v,g,h,s,t,p,q,r);break;case"a":p=k.shift(),q=k.shift(),r=k.shift(),s=k.shift(),t=k.shift(),u=g,v=h,g+=k.shift(),h+=k.shift(),w="A",x=this.convertEndpointToCenterParameterization(u,v,g,h,s,t,p,q,r)}f.push({command:w||j,points:x,start:{x:y,y:z},pathLength:this.calcLength(y,z,w||j,x)})}("z"===j||"Z"===j)&&f.push({command:"z",points:[],start:void 0,pathLength:0})}return f},Kinetic.Path.calcLength=function(a,b,c,d){var e,f,g,h=Kinetic.Path;switch(c){case"L":return h.getLineLength(a,b,d[0],d[1]);case"C":for(e=0,f=h.getPointOnCubicBezier(0,a,b,d[0],d[1],d[2],d[3],d[4],d[5]),t=.01;1>=t;t+=.01)g=h.getPointOnCubicBezier(t,a,b,d[0],d[1],d[2],d[3],d[4],d[5]),e+=h.getLineLength(f.x,f.y,g.x,g.y),f=g;return e;case"Q":for(e=0,f=h.getPointOnQuadraticBezier(0,a,b,d[0],d[1],d[2],d[3]),t=.01;1>=t;t+=.01)g=h.getPointOnQuadraticBezier(t,a,b,d[0],d[1],d[2],d[3]),e+=h.getLineLength(f.x,f.y,g.x,g.y),f=g;return e;case"A":e=0;var i=d[4],j=d[5],k=d[4]+j,l=Math.PI/180;if(Math.abs(i-k)<l&&(l=Math.abs(i-k)),f=h.getPointOnEllipticalArc(d[0],d[1],d[2],d[3],i,0),0>j)for(t=i-l;t>k;t-=l)g=h.getPointOnEllipticalArc(d[0],d[1],d[2],d[3],t,0),e+=h.getLineLength(f.x,f.y,g.x,g.y),f=g;else for(t=i+l;k>t;t+=l)g=h.getPointOnEllipticalArc(d[0],d[1],d[2],d[3],t,0),e+=h.getLineLength(f.x,f.y,g.x,g.y),f=g;return g=h.getPointOnEllipticalArc(d[0],d[1],d[2],d[3],k,0),e+=h.getLineLength(f.x,f.y,g.x,g.y)}return 0},Kinetic.Path.convertEndpointToCenterParameterization=function(a,b,c,d,e,f,g,h,i){var j=i*(Math.PI/180),k=Math.cos(j)*(a-c)/2+Math.sin(j)*(b-d)/2,l=-1*Math.sin(j)*(a-c)/2+Math.cos(j)*(b-d)/2,m=k*k/(g*g)+l*l/(h*h);m>1&&(g*=Math.sqrt(m),h*=Math.sqrt(m));var n=Math.sqrt((g*g*h*h-g*g*l*l-h*h*k*k)/(g*g*l*l+h*h*k*k));e==f&&(n*=-1),isNaN(n)&&(n=0);var o=n*g*l/h,p=n*-h*k/g,q=(a+c)/2+Math.cos(j)*o-Math.sin(j)*p,r=(b+d)/2+Math.sin(j)*o+Math.cos(j)*p,s=function(a){return Math.sqrt(a[0]*a[0]+a[1]*a[1])},t=function(a,b){return(a[0]*b[0]+a[1]*b[1])/(s(a)*s(b))},u=function(a,b){return(a[0]*b[1]<a[1]*b[0]?-1:1)*Math.acos(t(a,b))},v=u([1,0],[(k-o)/g,(l-p)/h]),w=[(k-o)/g,(l-p)/h],x=[(-1*k-o)/g,(-1*l-p)/h],y=u(w,x);return t(w,x)<=-1&&(y=Math.PI),t(w,x)>=1&&(y=0),0===f&&y>0&&(y-=2*Math.PI),1==f&&0>y&&(y+=2*Math.PI),[q,r,g,h,v,y,j,f]},Kinetic.Factory.addGetterSetter(Kinetic.Path,"data")}(),function(){function a(a){a.fillText(this.partialText,0,0)}function b(a){a.strokeText(this.partialText,0,0)}var c="",d="Calibri",e="normal";Kinetic.TextPath=function(a){this.___init(a)},Kinetic.TextPath.prototype={___init:function(c){var d=this;this.dummyCanvas=document.createElement("canvas"),this.dataArray=[],Kinetic.Shape.call(this,c),this._fillFunc=a,this._strokeFunc=b,this.className="TextPath",this.dataArray=Kinetic.Path.parsePathData(this.attrs.data),this.on("dataChange.kinetic",function(){d.dataArray=Kinetic.Path.parsePathData(this.attrs.data)}),this.on("textChange.kinetic textStroke.kinetic textStrokeWidth.kinetic",d._setTextData),d._setTextData()},drawFunc:function(a){this.charArr,a.setAttr("font",this._getContextFont()),a.setAttr("textBaseline","middle"),a.setAttr("textAlign","left"),a.save();for(var b=this.glyphInfo,c=0;c<b.length;c++){a.save();var d=b[c].p0;b[c].p1,parseFloat(this.attrs.fontSize),a.translate(d.x,d.y),a.rotate(b[c].rotation),this.partialText=b[c].text,a.fillStrokeShape(this),a.restore()}a.restore()},getTextWidth:function(){return this.textWidth},getTextHeight:function(){return this.textHeight},setText:function(a){Kinetic.Text.prototype.setText.call(this,a)},_getTextSize:function(a){var b=this.dummyCanvas,c=b.getContext("2d");c.save(),c.font=this._getContextFont();var d=c.measureText(a);return c.restore(),{width:d.width,height:parseInt(this.attrs.fontSize,10)}},_setTextData:function(){var a=this,b=this._getTextSize(this.attrs.text);this.textWidth=b.width,this.textHeight=b.height,this.glyphInfo=[];for(var c,d,e,f=this.attrs.text.split(""),g=-1,h=0,i=function(){h=0;for(var b=a.dataArray,d=g+1;d<b.length;d++){if(b[d].pathLength>0)return g=d,b[d];"M"==b[d].command&&(c={x:b[d].points[0],y:b[d].points[1]})}return{}},j=function(b){var f=a._getTextSize(b).width,g=0,j=0;for(d=void 0;Math.abs(f-g)/f>.01&&25>j;){j++;for(var k=g;void 0===e;)e=i(),e&&k+e.pathLength<f&&(k+=e.pathLength,e=void 0);if(e==={}||void 0===c)return void 0;var l=!1;switch(e.command){case"L":Kinetic.Path.getLineLength(c.x,c.y,e.points[0],e.points[1])>f?d=Kinetic.Path.getPointOnLine(f,c.x,c.y,e.points[0],e.points[1],c.x,c.y):e=void 0;break;case"A":var m=e.points[4],n=e.points[5],o=e.points[4]+n;0===h?h=m+1e-8:f>g?h+=Math.PI/180*n/Math.abs(n):h-=Math.PI/360*n/Math.abs(n),(0>n&&o>h||n>=0&&h>o)&&(h=o,l=!0),d=Kinetic.Path.getPointOnEllipticalArc(e.points[0],e.points[1],e.points[2],e.points[3],h,e.points[6]);break;case"C":0===h?h=f>e.pathLength?1e-8:f/e.pathLength:f>g?h+=(f-g)/e.pathLength:h-=(g-f)/e.pathLength,h>1&&(h=1,l=!0),d=Kinetic.Path.getPointOnCubicBezier(h,e.start.x,e.start.y,e.points[0],e.points[1],e.points[2],e.points[3],e.points[4],e.points[5]);break;case"Q":0===h?h=f/e.pathLength:f>g?h+=(f-g)/e.pathLength:h-=(g-f)/e.pathLength,h>1&&(h=1,l=!0),d=Kinetic.Path.getPointOnQuadraticBezier(h,e.start.x,e.start.y,e.points[0],e.points[1],e.points[2],e.points[3])}void 0!==d&&(g=Kinetic.Path.getLineLength(c.x,c.y,d.x,d.y)),l&&(l=!1,e=void 0)}},k=0;k<f.length&&(j(f[k]),void 0!==c&&void 0!==d);k++){var l=Kinetic.Path.getLineLength(c.x,c.y,d.x,d.y),m=0,n=Kinetic.Path.getPointOnLine(m+l/2,c.x,c.y,d.x,d.y),o=Math.atan2(d.y-c.y,d.x-c.x);this.glyphInfo.push({transposeX:n.x,transposeY:n.y,text:f[k],rotation:o,p0:c,p1:d}),c=d}}},Kinetic.TextPath.prototype._getContextFont=Kinetic.Text.prototype._getContextFont,Kinetic.Util.extend(Kinetic.TextPath,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.TextPath,"fontFamily",d),Kinetic.Factory.addGetterSetter(Kinetic.TextPath,"fontSize",12),Kinetic.Factory.addGetterSetter(Kinetic.TextPath,"fontStyle",e),Kinetic.Factory.addGetter(Kinetic.TextPath,"text",c)}(),function(){Kinetic.RegularPolygon=function(a){this.___init(a)},Kinetic.RegularPolygon.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="RegularPolygon"},drawFunc:function(a){var b,c,d,e=this.attrs.sides,f=this.attrs.radius;for(a.beginPath(),a.moveTo(0,0-f),b=1;e>b;b++)c=f*Math.sin(2*b*Math.PI/e),d=-1*f*Math.cos(2*b*Math.PI/e),a.lineTo(c,d);a.closePath(),a.fillStrokeShape(this)}},Kinetic.Util.extend(Kinetic.RegularPolygon,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.RegularPolygon,"radius",0),Kinetic.Factory.addGetterSetter(Kinetic.RegularPolygon,"sides",0)}(),function(){Kinetic.Star=function(a){this.___init(a)},Kinetic.Star.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="Star"},drawFunc:function(a){var b=a._context,c=this.attrs.innerRadius,d=this.attrs.outerRadius,e=this.attrs.numPoints;b.beginPath(),b.moveTo(0,0-this.attrs.outerRadius);for(var f=1;2*e>f;f++){var g=0===f%2?d:c,h=g*Math.sin(f*Math.PI/e),i=-1*g*Math.cos(f*Math.PI/e);b.lineTo(h,i)}b.closePath(),a.fillStrokeShape(this)}},Kinetic.Util.extend(Kinetic.Star,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Star,"numPoints",0),Kinetic.Factory.addGetterSetter(Kinetic.Star,"innerRadius",0),Kinetic.Factory.addGetterSetter(Kinetic.Star,"outerRadius",0)}(),function(){var a=["fontFamily","fontSize","fontStyle","padding","lineHeight","text"],b="Change.kinetic",c="none",d="up",e="right",f="down",g="left",h="Label",i=a.length;Kinetic.Label=function(a){this.____init(a)},Kinetic.Label.prototype={____init:function(a){var b=this;this.className=h,Kinetic.Group.call(this,a),this.on("add.kinetic",function(a){b._addListeners(a.child),b._sync()})},getText:function(){return this.find("Text")[0]},getTag:function(){return this.find("Tag")[0]},_addListeners:function(c){var d,e=this,f=function(){e._sync()};for(d=0;i>d;d++)c.on(a[d]+b,f)},getWidth:function(){return this.getText().getWidth()},getHeight:function(){return this.getText().getHeight()},_sync:function(){var a,b,c,h,i,j,k=this.getText(),l=this.getTag();if(k&&l){switch(a=k.getWidth(),b=k.getHeight(),c=l.getPointerDirection(),h=l.getPointerWidth(),pointerHeight=l.getPointerHeight(),i=0,j=0,c){case d:i=a/2,j=-1*pointerHeight;break;case e:i=a+h,j=b/2;break;case f:i=a/2,j=b+pointerHeight;break;case g:i=-1*h,j=b/2}l.setAttrs({x:-1*i,y:-1*j,width:a,height:b}),k.setAttrs({x:-1*i,y:-1*j})}}},Kinetic.Util.extend(Kinetic.Label,Kinetic.Group),Kinetic.Tag=function(a){this.___init(a)},Kinetic.Tag.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="Tag"},drawFunc:function(a){var b=this.getWidth(),c=this.getHeight(),h=this.getPointerDirection(),i=this.getPointerWidth(),j=this.getPointerHeight();this.getCornerRadius(),a.beginPath(),a.moveTo(0,0),h===d&&(a.lineTo((b-i)/2,0),a.lineTo(b/2,-1*j),a.lineTo((b+i)/2,0)),a.lineTo(b,0),h===e&&(a.lineTo(b,(c-j)/2),a.lineTo(b+i,c/2),a.lineTo(b,(c+j)/2)),a.lineTo(b,c),h===f&&(a.lineTo((b+i)/2,c),a.lineTo(b/2,c+j),a.lineTo((b-i)/2,c)),a.lineTo(0,c),h===g&&(a.lineTo(0,(c+j)/2),a.lineTo(-1*i,c/2),a.lineTo(0,(c-j)/2)),a.closePath(),a.fillStrokeShape(this)}},Kinetic.Util.extend(Kinetic.Tag,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Tag,"pointerDirection",c),Kinetic.Factory.addGetterSetter(Kinetic.Tag,"pointerWidth",0),Kinetic.Factory.addGetterSetter(Kinetic.Tag,"pointerHeight",0),Kinetic.Factory.addGetterSetter(Kinetic.Tag,"cornerRadius",0)}(),function(){Kinetic.Filters.Grayscale=function(a){for(var b=a.data,c=0;c<b.length;c+=4){var d=.34*b[c]+.5*b[c+1]+.16*b[c+2];b[c]=d,b[c+1]=d,b[c+2]=d}}}(),function(){Kinetic.Filters.Brighten=function(a){for(var b=this.getFilterBrightness(),c=a.data,d=0;d<c.length;d+=4)c[d]+=b,c[d+1]+=b,c[d+2]+=b},Kinetic.Factory.addFilterGetterSetter(Kinetic.Image,"filterBrightness",0)}(),function(){Kinetic.Filters.Invert=function(a){for(var b=a.data,c=0;c<b.length;c+=4)b[c]=255-b[c],b[c+1]=255-b[c+1],b[c+2]=255-b[c+2]}}(),function(){function a(){this.r=0,this.g=0,this.b=0,this.a=0,this.next=null}function b(b,e){var f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D=b.data,E=b.width,F=b.height,G=e+e+1,H=E-1,I=F-1,J=e+1,K=J*(J+1)/2,L=new a,M=null,N=L,O=null,P=null,Q=c[e],R=d[e];for(h=1;G>h;h++)N=N.next=new a,h==J&&(M=N);for(N.next=L,l=k=0,g=0;F>g;g++){for(u=v=w=x=m=n=o=p=0,q=J*(y=D[k]),r=J*(z=D[k+1]),s=J*(A=D[k+2]),t=J*(B=D[k+3]),m+=K*y,n+=K*z,o+=K*A,p+=K*B,N=L,h=0;J>h;h++)N.r=y,N.g=z,N.b=A,N.a=B,N=N.next;for(h=1;J>h;h++)i=k+((h>H?H:h)<<2),m+=(N.r=y=D[i])*(C=J-h),n+=(N.g=z=D[i+1])*C,o+=(N.b=A=D[i+2])*C,p+=(N.a=B=D[i+3])*C,u+=y,v+=z,w+=A,x+=B,N=N.next;for(O=L,P=M,f=0;E>f;f++)D[k+3]=B=p*Q>>R,0!==B?(B=255/B,D[k]=(m*Q>>R)*B,D[k+1]=(n*Q>>R)*B,D[k+2]=(o*Q>>R)*B):D[k]=D[k+1]=D[k+2]=0,m-=q,n-=r,o-=s,p-=t,q-=O.r,r-=O.g,s-=O.b,t-=O.a,i=l+((i=f+e+1)<H?i:H)<<2,u+=O.r=D[i],v+=O.g=D[i+1],w+=O.b=D[i+2],x+=O.a=D[i+3],m+=u,n+=v,o+=w,p+=x,O=O.next,q+=y=P.r,r+=z=P.g,s+=A=P.b,t+=B=P.a,u-=y,v-=z,w-=A,x-=B,P=P.next,k+=4;l+=E}for(f=0;E>f;f++){for(v=w=x=u=n=o=p=m=0,k=f<<2,q=J*(y=D[k]),r=J*(z=D[k+1]),s=J*(A=D[k+2]),t=J*(B=D[k+3]),m+=K*y,n+=K*z,o+=K*A,p+=K*B,N=L,h=0;J>h;h++)N.r=y,N.g=z,N.b=A,N.a=B,N=N.next;for(j=E,h=1;e>=h;h++)k=j+f<<2,m+=(N.r=y=D[k])*(C=J-h),n+=(N.g=z=D[k+1])*C,o+=(N.b=A=D[k+2])*C,p+=(N.a=B=D[k+3])*C,u+=y,v+=z,w+=A,x+=B,N=N.next,I>h&&(j+=E);for(k=f,O=L,P=M,g=0;F>g;g++)i=k<<2,D[i+3]=B=p*Q>>R,B>0?(B=255/B,D[i]=(m*Q>>R)*B,D[i+1]=(n*Q>>R)*B,D[i+2]=(o*Q>>R)*B):D[i]=D[i+1]=D[i+2]=0,m-=q,n-=r,o-=s,p-=t,q-=O.r,r-=O.g,s-=O.b,t-=O.a,i=f+((i=g+J)<I?i:I)*E<<2,m+=u+=O.r=D[i],n+=v+=O.g=D[i+1],o+=w+=O.b=D[i+2],p+=x+=O.a=D[i+3],O=O.next,q+=y=P.r,r+=z=P.g,s+=A=P.b,t+=B=P.a,u-=y,v-=z,w-=A,x-=B,P=P.next,k+=E}}var c=[512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512,454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512,482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456,437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512,497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328,320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456,446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335,329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512,505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405,399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328,324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271,268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456,451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388,385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335,332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292,289,287,285,282,280,278,275,273,271,269,267,265,263,261,259],d=[9,11,12,13,13,14,14,15,15,15,15,16,16,16,16,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24];
+Kinetic.Filters.Blur=function(a){var c=0|this.getFilterRadius();c>0&&b(a,c)},Kinetic.Factory.addFilterGetterSetter(Kinetic.Image,"filterRadius",0)}(),function(){function a(a,b,c){var d=4*(c*a.width+b),e=[];return e.push(a.data[d++],a.data[d++],a.data[d++],a.data[d++]),e}function b(a,b){return Math.sqrt(Math.pow(a[0]-b[0],2)+Math.pow(a[1]-b[1],2)+Math.pow(a[2]-b[2],2))}function c(a){for(var b=[0,0,0],c=0;c<a.length;c++)b[0]+=a[c][0],b[1]+=a[c][1],b[2]+=a[c][2];return b[0]/=a.length,b[1]/=a.length,b[2]/=a.length,b}function d(d,e){var f=a(d,0,0),g=a(d,d.width-1,0),h=a(d,0,d.height-1),i=a(d,d.width-1,d.height-1),j=e||10;if(b(f,g)<j&&b(g,i)<j&&b(i,h)<j&&b(h,f)<j){for(var k=c([g,f,i,h]),l=[],m=0;m<d.width*d.height;m++){var n=b(k,[d.data[4*m],d.data[4*m+1],d.data[4*m+2]]);l[m]=j>n?0:255}return l}}function e(a,b){for(var c=0;c<a.width*a.height;c++)a.data[4*c+3]=b[c]}function f(a,b,c){for(var d=[1,1,1,1,0,1,1,1,1],e=Math.round(Math.sqrt(d.length)),f=Math.floor(e/2),g=[],h=0;c>h;h++)for(var i=0;b>i;i++){for(var j=h*b+i,k=0,l=0;e>l;l++)for(var m=0;e>m;m++){var n=h+l-f,o=i+m-f;if(n>=0&&c>n&&o>=0&&b>o){var p=n*b+o,q=d[l*e+m];k+=a[p]*q}}g[j]=2040===k?255:0}return g}function g(a,b,c){for(var d=[1,1,1,1,1,1,1,1,1],e=Math.round(Math.sqrt(d.length)),f=Math.floor(e/2),g=[],h=0;c>h;h++)for(var i=0;b>i;i++){for(var j=h*b+i,k=0,l=0;e>l;l++)for(var m=0;e>m;m++){var n=h+l-f,o=i+m-f;if(n>=0&&c>n&&o>=0&&b>o){var p=n*b+o,q=d[l*e+m];k+=a[p]*q}}g[j]=k>=1020?255:0}return g}function h(a,b,c){for(var d=[1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9],e=Math.round(Math.sqrt(d.length)),f=Math.floor(e/2),g=[],h=0;c>h;h++)for(var i=0;b>i;i++){for(var j=h*b+i,k=0,l=0;e>l;l++)for(var m=0;e>m;m++){var n=h+l-f,o=i+m-f;if(n>=0&&c>n&&o>=0&&b>o){var p=n*b+o,q=d[l*e+m];k+=a[p]*q}}g[j]=k}return g}Kinetic.Filters.Mask=function(a){var b=this.getFilterThreshold(),c=d(a,b);return c&&(c=f(c,a.width,a.height),c=g(c,a.width,a.height),c=h(c,a.width,a.height),e(a,c)),a},Kinetic.Factory.addFilterGetterSetter(Kinetic.Image,"filterThreshold",0)}(),function(){var a=function(a,b,c){a/=255,b/=255,c/=255;var d=Math.max(a,b,c),e=Math.min(a,b,c),f=d-e,g=f/2,h=f/(1-Math.abs(2*g-1)),i=0;return d==a?i=(b-c)/f%6:d==b?i=(c-a)/f+2:d==c&&(i=(a-b)/f+4),[(60*i+360)%360,h,g]},b=function(a,b,c,d){a/=255,b/=255,c/=255;var e=Math.max(a,b,c),f=Math.min(a,b,c),g=e-f,h=g/2,i=(g/(1-Math.abs(2*h-1)),0);e==a?i=(b-c)/g%6:e==b?i=(c-a)/g+2:e==c&&(i=(a-b)/g+4),i*=60,i%=360,i+=d,i%=360,i/=60;var j=0,k=0,l=0,m=g*(1-Math.abs(i%2-1)),n=h-g/2;return i>=0&&1>i?(j=g,k=m):i>=1&&2>i?(k=g,j=m):i>=2&&3>i?(k=g,l=m):i>=3&&4>i?(l=g,k=m):i>=4&&5>i?(l=g,j=m):i>=5&&6>i&&(j=g,l=m),j+=n,k+=n,l+=n,j=255*j,k=255*k,l=255*l,[j,k,l]},c=function(a,c){for(var d,e=a.data,f=0;f<e.length;f+=4)d=b(e[f+0],e[f+1],e[f+2],c),e[f+0]=d[0],e[f+1]=d[1],e[f+2]=d[2]};Kinetic.Filters.ShiftHue=function(a){c(a,this.getFilterHueShiftDeg()%360)},Kinetic.Factory.addFilterGetterSetter(Kinetic.Image,"filterHueShiftDeg",0),Kinetic.Filters.Colorize=function(b){for(var d=b.data,e=this.getFilterColorizeColor(),f=a(e[0],e[1],e[2]),g=f[0],h=0;h<d.length;h+=4)d[h+1]=0,d[h+2]=0;c(b,g)},Kinetic.Factory.addFilterGetterSetter(Kinetic.Image,"filterColorizeColor",[255,0,0])}(),function(){var a=function(a,b){var c=a.data,d=a.width,e=a.height,f=d*e,g=[];g.length=4*d*e;var h,i,j,k,l,m,n,o,p,q,r,s=b.length,t=b[0].length,u=Math.floor(b.length/2),v=Math.floor(b[0].length/2);for(m=0;e>m;m+=1)for(l=0;d>l;l+=1){for(h=0,i=0,j=0,k=0,q=0;s>q;q+=1)for(r=0;t>r;r+=1)n=(l+q-u)%d,n=n>0?n:-n,o=(m+q-v)%e,o=o>0?o:-o,p=4*(o*d+n),h+=b[r][q]*c[p+0],i+=b[r][q]*c[p+1],j+=b[r][q]*c[p+2];p=4*(m*d+l),g[p+0]=h,g[p+1]=i,g[p+2]=j}var w=4*f;for(p=0;w>p;p+=4)c[p+0]=g[p+0],c[p+1]=g[p+1],c[p+2]=g[p+2]},b=function(a,b,c){var d=a-b;return Math.pow(Math.E,-d*d/(2*c*c))},c=function(a,c,d){0===a%2&&(a+=1);var e,f,g,h=[];for(e=0;a>e;e+=1){for(g=[],f=0;a>f;f+=1)g.push(c*b(e,a/2,d)*b(f,a/2,d));h.push(g)}return h},d=function(a,b){var d=c(a,b,1),e=Math.floor(a/2);return d[e][e]+=1-b,d},e=function(a,b){var d=c(a,-b,1),e=Math.floor(a/2);return d[e][e]+=1+b,d};Kinetic.Factory.addFilterGetterSetter(Kinetic.Image,"filterAmount",50),Kinetic.Filters.UnsharpMask=function(b){a(b,e(5,this.getFilterAmount()/100))},Kinetic.Filters.SoftBlur=function(b){a(b,d(5,this.getFilterAmount()/100))},Kinetic.Filters.Edge=function(b){var c=this.getFilterAmount()/100;0!==c&&a(b,[[0,-1*c,0],[-1*c,1-c+4*c,-1*c],[0,-1*c,0]])},Kinetic.Filters.Emboss=function(b){var c=this.getFilterAmount()/100;0!==c&&a(b,[[-1*c,-.5*c,0],[-.5*c,1+.5*c,.5*c],[0,.5*c,1*c]])}}();
\ No newline at end of file
diff --git a/app/gui/html/vendor/react-0.9.0.js b/app/gui/html/vendor/react-0.9.0.js
new file mode 100644
index 0000000..3161572
--- /dev/null
+++ b/app/gui/html/vendor/react-0.9.0.js
@@ -0,0 +1,16644 @@
+/**
+ * React v0.9.0
+ */
+!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.React=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule AutoFocusMixin
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var AutoFocusMixin = {
+  componentDidMount: function() {
+    if (this.props.autoFocus) {
+      this.getDOMNode().focus();
+    }
+  }
+};
+
+module.exports = AutoFocusMixin;
+
+},{}],2:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule CSSProperty
+ */
+
+"use strict";
+
+/**
+ * CSS properties which accept numbers but are not in units of "px".
+ */
+var isUnitlessNumber = {
+  columnCount: true,
+  fillOpacity: true,
+  flex: true,
+  flexGrow: true,
+  flexShrink: true,
+  fontWeight: true,
+  lineClamp: true,
+  lineHeight: true,
+  opacity: true,
+  order: true,
+  orphans: true,
+  widows: true,
+  zIndex: true,
+  zoom: true
+};
+
+/**
+ * @param {string} prefix vendor-specific prefix, eg: Webkit
+ * @param {string} key style name, eg: transitionDuration
+ * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
+ * WebkitTransitionDuration
+ */
+function prefixKey(prefix, key) {
+  return prefix + key.charAt(0).toUpperCase() + key.substring(1);
+}
+
+/**
+ * Support style names that may come passed in prefixed by adding permutations
+ * of vendor prefixes.
+ */
+var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
+
+// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
+// infinite loop, because it iterates over the newly added props too.
+Object.keys(isUnitlessNumber).forEach(function(prop) {
+  prefixes.forEach(function(prefix) {
+    isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
+  });
+});
+
+/**
+ * Most style properties can be unset by doing .style[prop] = '' but IE8
+ * doesn't like doing that with shorthand properties so for the properties that
+ * IE8 breaks on, which are listed here, we instead unset each of the
+ * individual properties. See http://bugs.jquery.com/ticket/12385.
+ * The 4-value 'clock' properties like margin, padding, border-width seem to
+ * behave without any problems. Curiously, list-style works too without any
+ * special prodding.
+ */
+var shorthandPropertyExpansions = {
+  background: {
+    backgroundImage: true,
+    backgroundPosition: true,
+    backgroundRepeat: true,
+    backgroundColor: true
+  },
+  border: {
+    borderWidth: true,
+    borderStyle: true,
+    borderColor: true
+  },
+  borderBottom: {
+    borderBottomWidth: true,
+    borderBottomStyle: true,
+    borderBottomColor: true
+  },
+  borderLeft: {
+    borderLeftWidth: true,
+    borderLeftStyle: true,
+    borderLeftColor: true
+  },
+  borderRight: {
+    borderRightWidth: true,
+    borderRightStyle: true,
+    borderRightColor: true
+  },
+  borderTop: {
+    borderTopWidth: true,
+    borderTopStyle: true,
+    borderTopColor: true
+  },
+  font: {
+    fontStyle: true,
+    fontVariant: true,
+    fontWeight: true,
+    fontSize: true,
+    lineHeight: true,
+    fontFamily: true
+  }
+};
+
+var CSSProperty = {
+  isUnitlessNumber: isUnitlessNumber,
+  shorthandPropertyExpansions: shorthandPropertyExpansions
+};
+
+module.exports = CSSProperty;
+
+},{}],3:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule CSSPropertyOperations
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var CSSProperty = require("./CSSProperty");
+
+var dangerousStyleValue = require("./dangerousStyleValue");
+var escapeTextForBrowser = require("./escapeTextForBrowser");
+var hyphenate = require("./hyphenate");
+var memoizeStringOnly = require("./memoizeStringOnly");
+
+var processStyleName = memoizeStringOnly(function(styleName) {
+  return escapeTextForBrowser(hyphenate(styleName));
+});
+
+/**
+ * Operations for dealing with CSS properties.
+ */
+var CSSPropertyOperations = {
+
+  /**
+   * Serializes a mapping of style properties for use as inline styles:
+   *
+   *   > createMarkupForStyles({width: '200px', height: 0})
+   *   "width:200px;height:0;"
+   *
+   * Undefined values are ignored so that declarative programming is easier.
+   *
+   * @param {object} styles
+   * @return {?string}
+   */
+  createMarkupForStyles: function(styles) {
+    var serialized = '';
+    for (var styleName in styles) {
+      if (!styles.hasOwnProperty(styleName)) {
+        continue;
+      }
+      var styleValue = styles[styleName];
+      if (styleValue != null) {
+        serialized += processStyleName(styleName) + ':';
+        serialized += dangerousStyleValue(styleName, styleValue) + ';';
+      }
+    }
+    return serialized || null;
+  },
+
+  /**
+   * Sets the value for multiple styles on a node.  If a value is specified as
+   * '' (empty string), the corresponding style property will be unset.
+   *
+   * @param {DOMElement} node
+   * @param {object} styles
+   */
+  setValueForStyles: function(node, styles) {
+    var style = node.style;
+    for (var styleName in styles) {
+      if (!styles.hasOwnProperty(styleName)) {
+        continue;
+      }
+      var styleValue = dangerousStyleValue(styleName, styles[styleName]);
+      if (styleValue) {
+        style[styleName] = styleValue;
+      } else {
+        var expansion = CSSProperty.shorthandPropertyExpansions[styleName];
+        if (expansion) {
+          // Shorthand property that IE8 won't like unsetting, so unset each
+          // component to placate it
+          for (var individualStyleName in expansion) {
+            style[individualStyleName] = '';
+          }
+        } else {
+          style[styleName] = '';
+        }
+      }
+    }
+  }
+
+};
+
+module.exports = CSSPropertyOperations;
+
+},{"./CSSProperty":2,"./dangerousStyleValue":94,"./escapeTextForBrowser":96,"./hyphenate":107,"./memoizeStringOnly":116}],4:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ChangeEventPlugin
+ */
+
+"use strict";
+
+var EventConstants = require("./EventConstants");
+var EventPluginHub = require("./EventPluginHub");
+var EventPropagators = require("./EventPropagators");
+var ExecutionEnvironment = require("./ExecutionEnvironment");
+var ReactUpdates = require("./ReactUpdates");
+var SyntheticEvent = require("./SyntheticEvent");
+
+var isEventSupported = require("./isEventSupported");
+var isTextInputElement = require("./isTextInputElement");
+var keyOf = require("./keyOf");
+
+var topLevelTypes = EventConstants.topLevelTypes;
+
+var eventTypes = {
+  change: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onChange: null}),
+      captured: keyOf({onChangeCapture: null})
+    },
+    dependencies: [
+      topLevelTypes.topBlur,
+      topLevelTypes.topChange,
+      topLevelTypes.topClick,
+      topLevelTypes.topFocus,
+      topLevelTypes.topInput,
+      topLevelTypes.topKeyDown,
+      topLevelTypes.topKeyUp,
+      topLevelTypes.topSelectionChange
+    ]
+  }
+};
+
+/**
+ * For IE shims
+ */
+var activeElement = null;
+var activeElementID = null;
+var activeElementValue = null;
+var activeElementValueProp = null;
+
+/**
+ * SECTION: handle `change` event
+ */
+function shouldUseChangeEvent(elem) {
+  return (
+    elem.nodeName === 'SELECT' ||
+    (elem.nodeName === 'INPUT' && elem.type === 'file')
+  );
+}
+
+var doesChangeEventBubble = false;
+if (ExecutionEnvironment.canUseDOM) {
+  // See `handleChange` comment below
+  doesChangeEventBubble = isEventSupported('change') && (
+    !('documentMode' in document) || document.documentMode > 8
+  );
+}
+
+function manualDispatchChangeEvent(nativeEvent) {
+  var event = SyntheticEvent.getPooled(
+    eventTypes.change,
+    activeElementID,
+    nativeEvent
+  );
+  EventPropagators.accumulateTwoPhaseDispatches(event);
+
+  // If change and propertychange bubbled, we'd just bind to it like all the
+  // other events and have it go through ReactEventTopLevelCallback. Since it
+  // doesn't, we manually listen for the events and so we have to enqueue and
+  // process the abstract event manually.
+  //
+  // Batching is necessary here in order to ensure that all event handlers run
+  // before the next rerender (including event handlers attached to ancestor
+  // elements instead of directly on the input). Without this, controlled
+  // components don't work properly in conjunction with event bubbling because
+  // the component is rerendered and the value reverted before all the event
+  // handlers can run. See https://github.com/facebook/react/issues/708.
+  ReactUpdates.batchedUpdates(runEventInBatch, event);
+}
+
+function runEventInBatch(event) {
+  EventPluginHub.enqueueEvents(event);
+  EventPluginHub.processEventQueue();
+}
+
+function startWatchingForChangeEventIE8(target, targetID) {
+  activeElement = target;
+  activeElementID = targetID;
+  activeElement.attachEvent('onchange', manualDispatchChangeEvent);
+}
+
+function stopWatchingForChangeEventIE8() {
+  if (!activeElement) {
+    return;
+  }
+  activeElement.detachEvent('onchange', manualDispatchChangeEvent);
+  activeElement = null;
+  activeElementID = null;
+}
+
+function getTargetIDForChangeEvent(
+    topLevelType,
+    topLevelTarget,
+    topLevelTargetID) {
+  if (topLevelType === topLevelTypes.topChange) {
+    return topLevelTargetID;
+  }
+}
+function handleEventsForChangeEventIE8(
+    topLevelType,
+    topLevelTarget,
+    topLevelTargetID) {
+  if (topLevelType === topLevelTypes.topFocus) {
+    // stopWatching() should be a noop here but we call it just in case we
+    // missed a blur event somehow.
+    stopWatchingForChangeEventIE8();
+    startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID);
+  } else if (topLevelType === topLevelTypes.topBlur) {
+    stopWatchingForChangeEventIE8();
+  }
+}
+
+
+/**
+ * SECTION: handle `input` event
+ */
+var isInputEventSupported = false;
+if (ExecutionEnvironment.canUseDOM) {
+  // IE9 claims to support the input event but fails to trigger it when
+  // deleting text, so we ignore its input events
+  isInputEventSupported = isEventSupported('input') && (
+    !('documentMode' in document) || document.documentMode > 9
+  );
+}
+
+/**
+ * (For old IE.) Replacement getter/setter for the `value` property that gets
+ * set on the active element.
+ */
+var newValueProp =  {
+  get: function() {
+    return activeElementValueProp.get.call(this);
+  },
+  set: function(val) {
+    // Cast to a string so we can do equality checks.
+    activeElementValue = '' + val;
+    activeElementValueProp.set.call(this, val);
+  }
+};
+
+/**
+ * (For old IE.) Starts tracking propertychange events on the passed-in element
+ * and override the value property so that we can distinguish user events from
+ * value changes in JS.
+ */
+function startWatchingForValueChange(target, targetID) {
+  activeElement = target;
+  activeElementID = targetID;
+  activeElementValue = target.value;
+  activeElementValueProp = Object.getOwnPropertyDescriptor(
+    target.constructor.prototype,
+    'value'
+  );
+
+  Object.defineProperty(activeElement, 'value', newValueProp);
+  activeElement.attachEvent('onpropertychange', handlePropertyChange);
+}
+
+/**
+ * (For old IE.) Removes the event listeners from the currently-tracked element,
+ * if any exists.
+ */
+function stopWatchingForValueChange() {
+  if (!activeElement) {
+    return;
+  }
+
+  // delete restores the original property definition
+  delete activeElement.value;
+  activeElement.detachEvent('onpropertychange', handlePropertyChange);
+
+  activeElement = null;
+  activeElementID = null;
+  activeElementValue = null;
+  activeElementValueProp = null;
+}
+
+/**
+ * (For old IE.) Handles a propertychange event, sending a `change` event if
+ * the value of the active element has changed.
+ */
+function handlePropertyChange(nativeEvent) {
+  if (nativeEvent.propertyName !== 'value') {
+    return;
+  }
+  var value = nativeEvent.srcElement.value;
+  if (value === activeElementValue) {
+    return;
+  }
+  activeElementValue = value;
+
+  manualDispatchChangeEvent(nativeEvent);
+}
+
+/**
+ * If a `change` event should be fired, returns the target's ID.
+ */
+function getTargetIDForInputEvent(
+    topLevelType,
+    topLevelTarget,
+    topLevelTargetID) {
+  if (topLevelType === topLevelTypes.topInput) {
+    // In modern browsers (i.e., not IE8 or IE9), the input event is exactly
+    // what we want so fall through here and trigger an abstract event
+    return topLevelTargetID;
+  }
+}
+
+// For IE8 and IE9.
+function handleEventsForInputEventIE(
+    topLevelType,
+    topLevelTarget,
+    topLevelTargetID) {
+  if (topLevelType === topLevelTypes.topFocus) {
+    // In IE8, we can capture almost all .value changes by adding a
+    // propertychange handler and looking for events with propertyName
+    // equal to 'value'
+    // In IE9, propertychange fires for most input events but is buggy and
+    // doesn't fire when text is deleted, but conveniently, selectionchange
+    // appears to fire in all of the remaining cases so we catch those and
+    // forward the event if the value has changed
+    // In either case, we don't want to call the event handler if the value
+    // is changed from JS so we redefine a setter for `.value` that updates
+    // our activeElementValue variable, allowing us to ignore those changes
+    //
+    // stopWatching() should be a noop here but we call it just in case we
+    // missed a blur event somehow.
+    stopWatchingForValueChange();
+    startWatchingForValueChange(topLevelTarget, topLevelTargetID);
+  } else if (topLevelType === topLevelTypes.topBlur) {
+    stopWatchingForValueChange();
+  }
+}
+
+// For IE8 and IE9.
+function getTargetIDForInputEventIE(
+    topLevelType,
+    topLevelTarget,
+    topLevelTargetID) {
+  if (topLevelType === topLevelTypes.topSelectionChange ||
+      topLevelType === topLevelTypes.topKeyUp ||
+      topLevelType === topLevelTypes.topKeyDown) {
+    // On the selectionchange event, the target is just document which isn't
+    // helpful for us so just check activeElement instead.
+    //
+    // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
+    // propertychange on the first input event after setting `value` from a
+    // script and fires only keydown, keypress, keyup. Catching keyup usually
+    // gets it and catching keydown lets us fire an event for the first
+    // keystroke if user does a key repeat (it'll be a little delayed: right
+    // before the second keystroke). Other input methods (e.g., paste) seem to
+    // fire selectionchange normally.
+    if (activeElement && activeElement.value !== activeElementValue) {
+      activeElementValue = activeElement.value;
+      return activeElementID;
+    }
+  }
+}
+
+
+/**
+ * SECTION: handle `click` event
+ */
+function shouldUseClickEvent(elem) {
+  // Use the `click` event to detect changes to checkbox and radio inputs.
+  // This approach works across all browsers, whereas `change` does not fire
+  // until `blur` in IE8.
+  return (
+    elem.nodeName === 'INPUT' &&
+    (elem.type === 'checkbox' || elem.type === 'radio')
+  );
+}
+
+function getTargetIDForClickEvent(
+    topLevelType,
+    topLevelTarget,
+    topLevelTargetID) {
+  if (topLevelType === topLevelTypes.topClick) {
+    return topLevelTargetID;
+  }
+}
+
+/**
+ * This plugin creates an `onChange` event that normalizes change events
+ * across form elements. This event fires at a time when it's possible to
+ * change the element's value without seeing a flicker.
+ *
+ * Supported elements are:
+ * - input (see `isTextInputElement`)
+ * - textarea
+ * - select
+ */
+var ChangeEventPlugin = {
+
+  eventTypes: eventTypes,
+
+  /**
+   * @param {string} topLevelType Record from `EventConstants`.
+   * @param {DOMEventTarget} topLevelTarget The listening component root node.
+   * @param {string} topLevelTargetID ID of `topLevelTarget`.
+   * @param {object} nativeEvent Native browser event.
+   * @return {*} An accumulation of synthetic events.
+   * @see {EventPluginHub.extractEvents}
+   */
+  extractEvents: function(
+      topLevelType,
+      topLevelTarget,
+      topLevelTargetID,
+      nativeEvent) {
+
+    var getTargetIDFunc, handleEventFunc;
+    if (shouldUseChangeEvent(topLevelTarget)) {
+      if (doesChangeEventBubble) {
+        getTargetIDFunc = getTargetIDForChangeEvent;
+      } else {
+        handleEventFunc = handleEventsForChangeEventIE8;
+      }
+    } else if (isTextInputElement(topLevelTarget)) {
+      if (isInputEventSupported) {
+        getTargetIDFunc = getTargetIDForInputEvent;
+      } else {
+        getTargetIDFunc = getTargetIDForInputEventIE;
+        handleEventFunc = handleEventsForInputEventIE;
+      }
+    } else if (shouldUseClickEvent(topLevelTarget)) {
+      getTargetIDFunc = getTargetIDForClickEvent;
+    }
+
+    if (getTargetIDFunc) {
+      var targetID = getTargetIDFunc(
+        topLevelType,
+        topLevelTarget,
+        topLevelTargetID
+      );
+      if (targetID) {
+        var event = SyntheticEvent.getPooled(
+          eventTypes.change,
+          targetID,
+          nativeEvent
+        );
+        EventPropagators.accumulateTwoPhaseDispatches(event);
+        return event;
+      }
+    }
+
+    if (handleEventFunc) {
+      handleEventFunc(
+        topLevelType,
+        topLevelTarget,
+        topLevelTargetID
+      );
+    }
+  }
+
+};
+
+module.exports = ChangeEventPlugin;
+
+},{"./EventConstants":14,"./EventPluginHub":16,"./EventPropagators":19,"./ExecutionEnvironment":20,"./ReactUpdates":70,"./SyntheticEvent":77,"./isEventSupported":109,"./isTextInputElement":111,"./keyOf":115}],5:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ClientReactRootIndex
+ * @typechecks
+ */
+
+"use strict";
+
+var nextReactRootIndex = 0;
+
+var ClientReactRootIndex = {
+  createReactRootIndex: function() {
+    return nextReactRootIndex++;
+  }
+};
+
+module.exports = ClientReactRootIndex;
+
+},{}],6:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule CompositionEventPlugin
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var EventConstants = require("./EventConstants");
+var EventPropagators = require("./EventPropagators");
+var ExecutionEnvironment = require("./ExecutionEnvironment");
+var ReactInputSelection = require("./ReactInputSelection");
+var SyntheticCompositionEvent = require("./SyntheticCompositionEvent");
+
+var getTextContentAccessor = require("./getTextContentAccessor");
+var keyOf = require("./keyOf");
+
+var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
+var START_KEYCODE = 229;
+
+var useCompositionEvent = (
+  ExecutionEnvironment.canUseDOM &&
+  'CompositionEvent' in window
+);
+
+// In IE9+, we have access to composition events, but the data supplied
+// by the native compositionend event may be incorrect. In Korean, for example,
+// the compositionend event contains only one character regardless of
+// how many characters have been composed since compositionstart.
+// We therefore use the fallback data while still using the native
+// events as triggers.
+var useFallbackData = (
+  !useCompositionEvent ||
+  'documentMode' in document && document.documentMode > 8
+);
+
+var topLevelTypes = EventConstants.topLevelTypes;
+var currentComposition = null;
+
+// Events and their corresponding property names.
+var eventTypes = {
+  compositionEnd: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onCompositionEnd: null}),
+      captured: keyOf({onCompositionEndCapture: null})
+    },
+    dependencies: [
+      topLevelTypes.topBlur,
+      topLevelTypes.topCompositionEnd,
+      topLevelTypes.topKeyDown,
+      topLevelTypes.topKeyPress,
+      topLevelTypes.topKeyUp,
+      topLevelTypes.topMouseDown
+    ]
+  },
+  compositionStart: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onCompositionStart: null}),
+      captured: keyOf({onCompositionStartCapture: null})
+    },
+    dependencies: [
+      topLevelTypes.topBlur,
+      topLevelTypes.topCompositionStart,
+      topLevelTypes.topKeyDown,
+      topLevelTypes.topKeyPress,
+      topLevelTypes.topKeyUp,
+      topLevelTypes.topMouseDown
+    ]
+  },
+  compositionUpdate: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onCompositionUpdate: null}),
+      captured: keyOf({onCompositionUpdateCapture: null})
+    },
+    dependencies: [
+      topLevelTypes.topBlur,
+      topLevelTypes.topCompositionUpdate,
+      topLevelTypes.topKeyDown,
+      topLevelTypes.topKeyPress,
+      topLevelTypes.topKeyUp,
+      topLevelTypes.topMouseDown
+    ]
+  }
+};
+
+/**
+ * Translate native top level events into event types.
+ *
+ * @param {string} topLevelType
+ * @return {object}
+ */
+function getCompositionEventType(topLevelType) {
+  switch (topLevelType) {
+    case topLevelTypes.topCompositionStart:
+      return eventTypes.compositionStart;
+    case topLevelTypes.topCompositionEnd:
+      return eventTypes.compositionEnd;
+    case topLevelTypes.topCompositionUpdate:
+      return eventTypes.compositionUpdate;
+  }
+}
+
+/**
+ * Does our fallback best-guess model think this event signifies that
+ * composition has begun?
+ *
+ * @param {string} topLevelType
+ * @param {object} nativeEvent
+ * @return {boolean}
+ */
+function isFallbackStart(topLevelType, nativeEvent) {
+  return (
+    topLevelType === topLevelTypes.topKeyDown &&
+    nativeEvent.keyCode === START_KEYCODE
+  );
+}
+
+/**
+ * Does our fallback mode think that this event is the end of composition?
+ *
+ * @param {string} topLevelType
+ * @param {object} nativeEvent
+ * @return {boolean}
+ */
+function isFallbackEnd(topLevelType, nativeEvent) {
+  switch (topLevelType) {
+    case topLevelTypes.topKeyUp:
+      // Command keys insert or clear IME input.
+      return (END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1);
+    case topLevelTypes.topKeyDown:
+      // Expect IME keyCode on each keydown. If we get any other
+      // code we must have exited earlier.
+      return (nativeEvent.keyCode !== START_KEYCODE);
+    case topLevelTypes.topKeyPress:
+    case topLevelTypes.topMouseDown:
+    case topLevelTypes.topBlur:
+      // Events are not possible without cancelling IME.
+      return true;
+    default:
+      return false;
+  }
+}
+
+/**
+ * Helper class stores information about selection and document state
+ * so we can figure out what changed at a later date.
+ *
+ * @param {DOMEventTarget} root
+ */
+function FallbackCompositionState(root) {
+  this.root = root;
+  this.startSelection = ReactInputSelection.getSelection(root);
+  this.startValue = this.getText();
+}
+
+/**
+ * Get current text of input.
+ *
+ * @return {string}
+ */
+FallbackCompositionState.prototype.getText = function() {
+  return this.root.value || this.root[getTextContentAccessor()];
+};
+
+/**
+ * Text that has changed since the start of composition.
+ *
+ * @return {string}
+ */
+FallbackCompositionState.prototype.getData = function() {
+  var endValue = this.getText();
+  var prefixLength = this.startSelection.start;
+  var suffixLength = this.startValue.length - this.startSelection.end;
+
+  return endValue.substr(
+    prefixLength,
+    endValue.length - suffixLength - prefixLength
+  );
+};
+
+/**
+ * This plugin creates `onCompositionStart`, `onCompositionUpdate` and
+ * `onCompositionEnd` events on inputs, textareas and contentEditable
+ * nodes.
+ */
+var CompositionEventPlugin = {
+
+  eventTypes: eventTypes,
+
+  /**
+   * @param {string} topLevelType Record from `EventConstants`.
+   * @param {DOMEventTarget} topLevelTarget The listening component root node.
+   * @param {string} topLevelTargetID ID of `topLevelTarget`.
+   * @param {object} nativeEvent Native browser event.
+   * @return {*} An accumulation of synthetic events.
+   * @see {EventPluginHub.extractEvents}
+   */
+  extractEvents: function(
+      topLevelType,
+      topLevelTarget,
+      topLevelTargetID,
+      nativeEvent) {
+
+    var eventType;
+    var data;
+
+    if (useCompositionEvent) {
+      eventType = getCompositionEventType(topLevelType);
+    } else if (!currentComposition) {
+      if (isFallbackStart(topLevelType, nativeEvent)) {
+        eventType = eventTypes.compositionStart;
+      }
+    } else if (isFallbackEnd(topLevelType, nativeEvent)) {
+      eventType = eventTypes.compositionEnd;
+    }
+
+    if (useFallbackData) {
+      // The current composition is stored statically and must not be
+      // overwritten while composition continues.
+      if (!currentComposition && eventType === eventTypes.compositionStart) {
+        currentComposition = new FallbackCompositionState(topLevelTarget);
+      } else if (eventType === eventTypes.compositionEnd) {
+        if (currentComposition) {
+          data = currentComposition.getData();
+          currentComposition = null;
+        }
+      }
+    }
+
+    if (eventType) {
+      var event = SyntheticCompositionEvent.getPooled(
+        eventType,
+        topLevelTargetID,
+        nativeEvent
+      );
+      if (data) {
+        // Inject data generated from fallback path into the synthetic event.
+        // This matches the property of native CompositionEventInterface.
+        event.data = data;
+      }
+      EventPropagators.accumulateTwoPhaseDispatches(event);
+      return event;
+    }
+  }
+};
+
+module.exports = CompositionEventPlugin;
+
+},{"./EventConstants":14,"./EventPropagators":19,"./ExecutionEnvironment":20,"./ReactInputSelection":52,"./SyntheticCompositionEvent":75,"./getTextContentAccessor":105,"./keyOf":115}],7:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule DOMChildrenOperations
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var Danger = require("./Danger");
+var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes");
+
+var getTextContentAccessor = require("./getTextContentAccessor");
+
+/**
+ * The DOM property to use when setting text content.
+ *
+ * @type {string}
+ * @private
+ */
+var textContentAccessor = getTextContentAccessor();
+
+/**
+ * Inserts `childNode` as a child of `parentNode` at the `index`.
+ *
+ * @param {DOMElement} parentNode Parent node in which to insert.
+ * @param {DOMElement} childNode Child node to insert.
+ * @param {number} index Index at which to insert the child.
+ * @internal
+ */
+function insertChildAt(parentNode, childNode, index) {
+  var childNodes = parentNode.childNodes;
+  if (childNodes[index] === childNode) {
+    return;
+  }
+  // If `childNode` is already a child of `parentNode`, remove it so that
+  // computing `childNodes[index]` takes into account the removal.
+  if (childNode.parentNode === parentNode) {
+    parentNode.removeChild(childNode);
+  }
+  if (index >= childNodes.length) {
+    parentNode.appendChild(childNode);
+  } else {
+    parentNode.insertBefore(childNode, childNodes[index]);
+  }
+}
+
+/**
+ * Sets the text content of `node` to `text`.
+ *
+ * @param {DOMElement} node Node to change
+ * @param {string} text New text content
+ */
+var updateTextContent;
+if (textContentAccessor === 'textContent') {
+  updateTextContent = function(node, text) {
+    node.textContent = text;
+  };
+} else {
+  updateTextContent = function(node, text) {
+    // In order to preserve newlines correctly, we can't use .innerText to set
+    // the contents (see #1080), so we empty the element then append a text node
+    while (node.firstChild) {
+      node.removeChild(node.firstChild);
+    }
+    if (text) {
+      var doc = node.ownerDocument || document;
+      node.appendChild(doc.createTextNode(text));
+    }
+  };
+}
+
+/**
+ * Operations for updating with DOM children.
+ */
+var DOMChildrenOperations = {
+
+  dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup,
+
+  updateTextContent: updateTextContent,
+
+  /**
+   * Updates a component's children by processing a series of updates. The
+   * update configurations are each expected to have a `parentNode` property.
+   *
+   * @param {array<object>} updates List of update configurations.
+   * @param {array<string>} markupList List of markup strings.
+   * @internal
+   */
+  processUpdates: function(updates, markupList) {
+    var update;
+    // Mapping from parent IDs to initial child orderings.
+    var initialChildren = null;
+    // List of children that will be moved or removed.
+    var updatedChildren = null;
+
+    for (var i = 0; update = updates[i]; i++) {
+      if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING ||
+          update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) {
+        var updatedIndex = update.fromIndex;
+        var updatedChild = update.parentNode.childNodes[updatedIndex];
+        var parentID = update.parentID;
+
+        initialChildren = initialChildren || {};
+        initialChildren[parentID] = initialChildren[parentID] || [];
+        initialChildren[parentID][updatedIndex] = updatedChild;
+
+        updatedChildren = updatedChildren || [];
+        updatedChildren.push(updatedChild);
+      }
+    }
+
+    var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList);
+
+    // Remove updated children first so that `toIndex` is consistent.
+    if (updatedChildren) {
+      for (var j = 0; j < updatedChildren.length; j++) {
+        updatedChildren[j].parentNode.removeChild(updatedChildren[j]);
+      }
+    }
+
+    for (var k = 0; update = updates[k]; k++) {
+      switch (update.type) {
+        case ReactMultiChildUpdateTypes.INSERT_MARKUP:
+          insertChildAt(
+            update.parentNode,
+            renderedMarkup[update.markupIndex],
+            update.toIndex
+          );
+          break;
+        case ReactMultiChildUpdateTypes.MOVE_EXISTING:
+          insertChildAt(
+            update.parentNode,
+            initialChildren[update.parentID][update.fromIndex],
+            update.toIndex
+          );
+          break;
+        case ReactMultiChildUpdateTypes.TEXT_CONTENT:
+          updateTextContent(
+            update.parentNode,
+            update.textContent
+          );
+          break;
+        case ReactMultiChildUpdateTypes.REMOVE_NODE:
+          // Already removed by the for-loop above.
+          break;
+      }
+    }
+  }
+
+};
+
+module.exports = DOMChildrenOperations;
+
+},{"./Danger":10,"./ReactMultiChildUpdateTypes":58,"./getTextContentAccessor":105}],8:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule DOMProperty
+ * @typechecks static-only
+ */
+
+/*jslint bitwise: true */
+
+"use strict";
+
+var invariant = require("./invariant");
+
+var DOMPropertyInjection = {
+  /**
+   * Mapping from normalized, camelcased property names to a configuration that
+   * specifies how the associated DOM property should be accessed or rendered.
+   */
+  MUST_USE_ATTRIBUTE: 0x1,
+  MUST_USE_PROPERTY: 0x2,
+  HAS_SIDE_EFFECTS: 0x4,
+  HAS_BOOLEAN_VALUE: 0x8,
+  HAS_POSITIVE_NUMERIC_VALUE: 0x10,
+
+  /**
+   * Inject some specialized knowledge about the DOM. This takes a config object
+   * with the following properties:
+   *
+   * isCustomAttribute: function that given an attribute name will return true
+   * if it can be inserted into the DOM verbatim. Useful for data-* or aria-*
+   * attributes where it's impossible to enumerate all of the possible
+   * attribute names,
+   *
+   * Properties: object mapping DOM property name to one of the
+   * DOMPropertyInjection constants or null. If your attribute isn't in here,
+   * it won't get written to the DOM.
+   *
+   * DOMAttributeNames: object mapping React attribute name to the DOM
+   * attribute name. Attribute names not specified use the **lowercase**
+   * normalized name.
+   *
+   * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties.
+   * Property names not specified use the normalized name.
+   *
+   * DOMMutationMethods: Properties that require special mutation methods. If
+   * `value` is undefined, the mutation method should unset the property.
+   *
+   * @param {object} domPropertyConfig the config as described above.
+   */
+  injectDOMPropertyConfig: function(domPropertyConfig) {
+    var Properties = domPropertyConfig.Properties || {};
+    var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {};
+    var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {};
+    var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {};
+
+    if (domPropertyConfig.isCustomAttribute) {
+      DOMProperty._isCustomAttributeFunctions.push(
+        domPropertyConfig.isCustomAttribute
+      );
+    }
+
+    for (var propName in Properties) {
+      ("production" !== "development" ? invariant(
+        !DOMProperty.isStandardName[propName],
+        'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' +
+        '\'%s\' which has already been injected. You may be accidentally ' +
+        'injecting the same DOM property config twice, or you may be ' +
+        'injecting two configs that have conflicting property names.',
+        propName
+      ) : invariant(!DOMProperty.isStandardName[propName]));
+
+      DOMProperty.isStandardName[propName] = true;
+
+      var lowerCased = propName.toLowerCase();
+      DOMProperty.getPossibleStandardName[lowerCased] = propName;
+
+      var attributeName = DOMAttributeNames[propName];
+      if (attributeName) {
+        DOMProperty.getPossibleStandardName[attributeName] = propName;
+      }
+
+      DOMProperty.getAttributeName[propName] = attributeName || lowerCased;
+
+      DOMProperty.getPropertyName[propName] =
+        DOMPropertyNames[propName] || propName;
+
+      var mutationMethod = DOMMutationMethods[propName];
+      if (mutationMethod) {
+        DOMProperty.getMutationMethod[propName] = mutationMethod;
+      }
+
+      var propConfig = Properties[propName];
+      DOMProperty.mustUseAttribute[propName] =
+        propConfig & DOMPropertyInjection.MUST_USE_ATTRIBUTE;
+      DOMProperty.mustUseProperty[propName] =
+        propConfig & DOMPropertyInjection.MUST_USE_PROPERTY;
+      DOMProperty.hasSideEffects[propName] =
+        propConfig & DOMPropertyInjection.HAS_SIDE_EFFECTS;
+      DOMProperty.hasBooleanValue[propName] =
+        propConfig & DOMPropertyInjection.HAS_BOOLEAN_VALUE;
+      DOMProperty.hasPositiveNumericValue[propName] =
+        propConfig & DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE;
+
+      ("production" !== "development" ? invariant(
+        !DOMProperty.mustUseAttribute[propName] ||
+          !DOMProperty.mustUseProperty[propName],
+        'DOMProperty: Cannot require using both attribute and property: %s',
+        propName
+      ) : invariant(!DOMProperty.mustUseAttribute[propName] ||
+        !DOMProperty.mustUseProperty[propName]));
+      ("production" !== "development" ? invariant(
+        DOMProperty.mustUseProperty[propName] ||
+          !DOMProperty.hasSideEffects[propName],
+        'DOMProperty: Properties that have side effects must use property: %s',
+        propName
+      ) : invariant(DOMProperty.mustUseProperty[propName] ||
+        !DOMProperty.hasSideEffects[propName]));
+      ("production" !== "development" ? invariant(
+        !DOMProperty.hasBooleanValue[propName] ||
+          !DOMProperty.hasPositiveNumericValue[propName],
+        'DOMProperty: Cannot have both boolean and positive numeric value: %s',
+        propName
+      ) : invariant(!DOMProperty.hasBooleanValue[propName] ||
+        !DOMProperty.hasPositiveNumericValue[propName]));
+    }
+  }
+};
+var defaultValueCache = {};
+
+/**
+ * DOMProperty exports lookup objects that can be used like functions:
+ *
+ *   > DOMProperty.isValid['id']
+ *   true
+ *   > DOMProperty.isValid['foobar']
+ *   undefined
+ *
+ * Although this may be confusing, it performs better in general.
+ *
+ * @see http://jsperf.com/key-exists
+ * @see http://jsperf.com/key-missing
+ */
+var DOMProperty = {
+
+  ID_ATTRIBUTE_NAME: 'data-reactid',
+
+  /**
+   * Checks whether a property name is a standard property.
+   * @type {Object}
+   */
+  isStandardName: {},
+
+  /**
+   * Mapping from lowercase property names to the properly cased version, used
+   * to warn in the case of missing properties.
+   * @type {Object}
+   */
+  getPossibleStandardName: {},
+
+  /**
+   * Mapping from normalized names to attribute names that differ. Attribute
+   * names are used when rendering markup or with `*Attribute()`.
+   * @type {Object}
+   */
+  getAttributeName: {},
+
+  /**
+   * Mapping from normalized names to properties on DOM node instances.
+   * (This includes properties that mutate due to external factors.)
+   * @type {Object}
+   */
+  getPropertyName: {},
+
+  /**
+   * Mapping from normalized names to mutation methods. This will only exist if
+   * mutation cannot be set simply by the property or `setAttribute()`.
+   * @type {Object}
+   */
+  getMutationMethod: {},
+
+  /**
+   * Whether the property must be accessed and mutated as an object property.
+   * @type {Object}
+   */
+  mustUseAttribute: {},
+
+  /**
+   * Whether the property must be accessed and mutated using `*Attribute()`.
+   * (This includes anything that fails `<propName> in <element>`.)
+   * @type {Object}
+   */
+  mustUseProperty: {},
+
+  /**
+   * Whether or not setting a value causes side effects such as triggering
+   * resources to be loaded or text selection changes. We must ensure that
+   * the value is only set if it has changed.
+   * @type {Object}
+   */
+  hasSideEffects: {},
+
+  /**
+   * Whether the property should be removed when set to a falsey value.
+   * @type {Object}
+   */
+  hasBooleanValue: {},
+
+  /**
+   * Whether the property must be positive numeric or parse as a positive
+   * numeric and should be removed when set to a falsey value.
+   * @type {Object}
+   */
+  hasPositiveNumericValue: {},
+
+  /**
+   * All of the isCustomAttribute() functions that have been injected.
+   */
+  _isCustomAttributeFunctions: [],
+
+  /**
+   * Checks whether a property name is a custom attribute.
+   * @method
+   */
+  isCustomAttribute: function(attributeName) {
+    return DOMProperty._isCustomAttributeFunctions.some(
+      function(isCustomAttributeFn) {
+        return isCustomAttributeFn.call(null, attributeName);
+      }
+    );
+  },
+
+  /**
+   * Returns the default property value for a DOM property (i.e., not an
+   * attribute). Most default values are '' or false, but not all. Worse yet,
+   * some (in particular, `type`) vary depending on the type of element.
+   *
+   * TODO: Is it better to grab all the possible properties when creating an
+   * element to avoid having to create the same element twice?
+   */
+  getDefaultValueForProperty: function(nodeName, prop) {
+    var nodeDefaults = defaultValueCache[nodeName];
+    var testElement;
+    if (!nodeDefaults) {
+      defaultValueCache[nodeName] = nodeDefaults = {};
+    }
+    if (!(prop in nodeDefaults)) {
+      testElement = document.createElement(nodeName);
+      nodeDefaults[prop] = testElement[prop];
+    }
+    return nodeDefaults[prop];
+  },
+
+  injection: DOMPropertyInjection
+};
+
+module.exports = DOMProperty;
+
+},{"./invariant":108}],9:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule DOMPropertyOperations
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var DOMProperty = require("./DOMProperty");
+
+var escapeTextForBrowser = require("./escapeTextForBrowser");
+var memoizeStringOnly = require("./memoizeStringOnly");
+
+function shouldIgnoreValue(name, value) {
+  return value == null ||
+    DOMProperty.hasBooleanValue[name] && !value ||
+    DOMProperty.hasPositiveNumericValue[name] && (isNaN(value) || value < 1);
+}
+
+var processAttributeNameAndPrefix = memoizeStringOnly(function(name) {
+  return escapeTextForBrowser(name) + '="';
+});
+
+if ("production" !== "development") {
+  var reactProps = {
+    children: true,
+    dangerouslySetInnerHTML: true,
+    key: true,
+    ref: true
+  };
+  var warnedProperties = {};
+
+  var warnUnknownProperty = function(name) {
+    if (reactProps[name] || warnedProperties[name]) {
+      return;
+    }
+
+    warnedProperties[name] = true;
+    var lowerCasedName = name.toLowerCase();
+
+    // data-* attributes should be lowercase; suggest the lowercase version
+    var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ?
+      lowerCasedName : DOMProperty.getPossibleStandardName[lowerCasedName];
+
+    // For now, only warn when we have a suggested correction. This prevents
+    // logging too much when using transferPropsTo.
+    if (standardName != null) {
+      console.warn(
+        'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?'
+      );
+    }
+
+  };
+}
+
+/**
+ * Operations for dealing with DOM properties.
+ */
+var DOMPropertyOperations = {
+
+  /**
+   * Creates markup for the ID property.
+   *
+   * @param {string} id Unescaped ID.
+   * @return {string} Markup string.
+   */
+  createMarkupForID: function(id) {
+    return processAttributeNameAndPrefix(DOMProperty.ID_ATTRIBUTE_NAME) +
+      escapeTextForBrowser(id) + '"';
+  },
+
+  /**
+   * Creates markup for a property.
+   *
+   * @param {string} name
+   * @param {*} value
+   * @return {?string} Markup string, or null if the property was invalid.
+   */
+  createMarkupForProperty: function(name, value) {
+    if (DOMProperty.isStandardName[name]) {
+      if (shouldIgnoreValue(name, value)) {
+        return '';
+      }
+      var attributeName = DOMProperty.getAttributeName[name];
+      if (DOMProperty.hasBooleanValue[name]) {
+        return escapeTextForBrowser(attributeName);
+      }
+      return processAttributeNameAndPrefix(attributeName) +
+        escapeTextForBrowser(value) + '"';
+    } else if (DOMProperty.isCustomAttribute(name)) {
+      if (value == null) {
+        return '';
+      }
+      return processAttributeNameAndPrefix(name) +
+        escapeTextForBrowser(value) + '"';
+    } else if ("production" !== "development") {
+      warnUnknownProperty(name);
+    }
+    return null;
+  },
+
+  /**
+   * Sets the value for a property on a node.
+   *
+   * @param {DOMElement} node
+   * @param {string} name
+   * @param {*} value
+   */
+  setValueForProperty: function(node, name, value) {
+    if (DOMProperty.isStandardName[name]) {
+      var mutationMethod = DOMProperty.getMutationMethod[name];
+      if (mutationMethod) {
+        mutationMethod(node, value);
+      } else if (shouldIgnoreValue(name, value)) {
+        this.deleteValueForProperty(node, name);
+      } else if (DOMProperty.mustUseAttribute[name]) {
+        node.setAttribute(DOMProperty.getAttributeName[name], '' + value);
+      } else {
+        var propName = DOMProperty.getPropertyName[name];
+        if (!DOMProperty.hasSideEffects[name] || node[propName] !== value) {
+          node[propName] = value;
+        }
+      }
+    } else if (DOMProperty.isCustomAttribute(name)) {
+      if (value == null) {
+        node.removeAttribute(DOMProperty.getAttributeName[name]);
+      } else {
+        node.setAttribute(name, '' + value);
+      }
+    } else if ("production" !== "development") {
+      warnUnknownProperty(name);
+    }
+  },
+
+  /**
+   * Deletes the value for a property on a node.
+   *
+   * @param {DOMElement} node
+   * @param {string} name
+   */
+  deleteValueForProperty: function(node, name) {
+    if (DOMProperty.isStandardName[name]) {
+      var mutationMethod = DOMProperty.getMutationMethod[name];
+      if (mutationMethod) {
+        mutationMethod(node, undefined);
+      } else if (DOMProperty.mustUseAttribute[name]) {
+        node.removeAttribute(DOMProperty.getAttributeName[name]);
+      } else {
+        var propName = DOMProperty.getPropertyName[name];
+        var defaultValue = DOMProperty.getDefaultValueForProperty(
+          node.nodeName,
+          name
+        );
+        if (!DOMProperty.hasSideEffects[name] ||
+            node[propName] !== defaultValue) {
+          node[propName] = defaultValue;
+        }
+      }
+    } else if (DOMProperty.isCustomAttribute(name)) {
+      node.removeAttribute(name);
+    } else if ("production" !== "development") {
+      warnUnknownProperty(name);
+    }
+  }
+
+};
+
+module.exports = DOMPropertyOperations;
+
+},{"./DOMProperty":8,"./escapeTextForBrowser":96,"./memoizeStringOnly":116}],10:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule Danger
+ * @typechecks static-only
+ */
+
+/*jslint evil: true, sub: true */
+
+"use strict";
+
+var ExecutionEnvironment = require("./ExecutionEnvironment");
+
+var createNodesFromMarkup = require("./createNodesFromMarkup");
+var emptyFunction = require("./emptyFunction");
+var getMarkupWrap = require("./getMarkupWrap");
+var invariant = require("./invariant");
+
+var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/;
+var RESULT_INDEX_ATTR = 'data-danger-index';
+
+/**
+ * Extracts the `nodeName` from a string of markup.
+ *
+ * NOTE: Extracting the `nodeName` does not require a regular expression match
+ * because we make assumptions about React-generated markup (i.e. there are no
+ * spaces surrounding the opening tag and there is at least one attribute).
+ *
+ * @param {string} markup String of markup.
+ * @return {string} Node name of the supplied markup.
+ * @see http://jsperf.com/extract-nodename
+ */
+function getNodeName(markup) {
+  return markup.substring(1, markup.indexOf(' '));
+}
+
+var Danger = {
+
+  /**
+   * Renders markup into an array of nodes. The markup is expected to render
+   * into a list of root nodes. Also, the length of `resultList` and
+   * `markupList` should be the same.
+   *
+   * @param {array<string>} markupList List of markup strings to render.
+   * @return {array<DOMElement>} List of rendered nodes.
+   * @internal
+   */
+  dangerouslyRenderMarkup: function(markupList) {
+    ("production" !== "development" ? invariant(
+      ExecutionEnvironment.canUseDOM,
+      'dangerouslyRenderMarkup(...): Cannot render markup in a Worker ' +
+      'thread. This is likely a bug in the framework. Please report ' +
+      'immediately.'
+    ) : invariant(ExecutionEnvironment.canUseDOM));
+    var nodeName;
+    var markupByNodeName = {};
+    // Group markup by `nodeName` if a wrap is necessary, else by '*'.
+    for (var i = 0; i < markupList.length; i++) {
+      ("production" !== "development" ? invariant(
+        markupList[i],
+        'dangerouslyRenderMarkup(...): Missing markup.'
+      ) : invariant(markupList[i]));
+      nodeName = getNodeName(markupList[i]);
+      nodeName = getMarkupWrap(nodeName) ? nodeName : '*';
+      markupByNodeName[nodeName] = markupByNodeName[nodeName] || [];
+      markupByNodeName[nodeName][i] = markupList[i];
+    }
+    var resultList = [];
+    var resultListAssignmentCount = 0;
+    for (nodeName in markupByNodeName) {
+      if (!markupByNodeName.hasOwnProperty(nodeName)) {
+        continue;
+      }
+      var markupListByNodeName = markupByNodeName[nodeName];
+
+      // This for-in loop skips the holes of the sparse array. The order of
+      // iteration should follow the order of assignment, which happens to match
+      // numerical index order, but we don't rely on that.
+      for (var resultIndex in markupListByNodeName) {
+        if (markupListByNodeName.hasOwnProperty(resultIndex)) {
+          var markup = markupListByNodeName[resultIndex];
+
+          // Push the requested markup with an additional RESULT_INDEX_ATTR
+          // attribute.  If the markup does not start with a < character, it
+          // will be discarded below (with an appropriate console.error).
+          markupListByNodeName[resultIndex] = markup.replace(
+            OPEN_TAG_NAME_EXP,
+            // This index will be parsed back out below.
+            '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" '
+          );
+        }
+      }
+
+      // Render each group of markup with similar wrapping `nodeName`.
+      var renderNodes = createNodesFromMarkup(
+        markupListByNodeName.join(''),
+        emptyFunction // Do nothing special with <script> tags.
+      );
+
+      for (i = 0; i < renderNodes.length; ++i) {
+        var renderNode = renderNodes[i];
+        if (renderNode.hasAttribute &&
+            renderNode.hasAttribute(RESULT_INDEX_ATTR)) {
+
+          resultIndex = +renderNode.getAttribute(RESULT_INDEX_ATTR);
+          renderNode.removeAttribute(RESULT_INDEX_ATTR);
+
+          ("production" !== "development" ? invariant(
+            !resultList.hasOwnProperty(resultIndex),
+            'Danger: Assigning to an already-occupied result index.'
+          ) : invariant(!resultList.hasOwnProperty(resultIndex)));
+
+          resultList[resultIndex] = renderNode;
+
+          // This should match resultList.length and markupList.length when
+          // we're done.
+          resultListAssignmentCount += 1;
+
+        } else if ("production" !== "development") {
+          console.error(
+            "Danger: Discarding unexpected node:",
+            renderNode
+          );
+        }
+      }
+    }
+
+    // Although resultList was populated out of order, it should now be a dense
+    // array.
+    ("production" !== "development" ? invariant(
+      resultListAssignmentCount === resultList.length,
+      'Danger: Did not assign to every index of resultList.'
+    ) : invariant(resultListAssignmentCount === resultList.length));
+
+    ("production" !== "development" ? invariant(
+      resultList.length === markupList.length,
+      'Danger: Expected markup to render %s nodes, but rendered %s.',
+      markupList.length,
+      resultList.length
+    ) : invariant(resultList.length === markupList.length));
+
+    return resultList;
+  },
+
+  /**
+   * Replaces a node with a string of markup at its current position within its
+   * parent. The markup must render into a single root node.
+   *
+   * @param {DOMElement} oldChild Child node to replace.
+   * @param {string} markup Markup to render in place of the child node.
+   * @internal
+   */
+  dangerouslyReplaceNodeWithMarkup: function(oldChild, markup) {
+    ("production" !== "development" ? invariant(
+      ExecutionEnvironment.canUseDOM,
+      'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a ' +
+      'worker thread. This is likely a bug in the framework. Please report ' +
+      'immediately.'
+    ) : invariant(ExecutionEnvironment.canUseDOM));
+    ("production" !== "development" ? invariant(markup, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : invariant(markup));
+    ("production" !== "development" ? invariant(
+      oldChild.tagName.toLowerCase() !== 'html',
+      'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the ' +
+      '<html> node. This is because browser quirks make this unreliable ' +
+      'and/or slow. If you want to render to the root you must use ' +
+      'server rendering. See renderComponentToString().'
+    ) : invariant(oldChild.tagName.toLowerCase() !== 'html'));
+
+    var newChild = createNodesFromMarkup(markup, emptyFunction)[0];
+    oldChild.parentNode.replaceChild(newChild, oldChild);
+  }
+
+};
+
+module.exports = Danger;
+
+},{"./ExecutionEnvironment":20,"./createNodesFromMarkup":92,"./emptyFunction":95,"./getMarkupWrap":102,"./invariant":108}],11:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule DefaultDOMPropertyConfig
+ */
+
+/*jslint bitwise: true*/
+
+"use strict";
+
+var DOMProperty = require("./DOMProperty");
+
+var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE;
+var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY;
+var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE;
+var HAS_SIDE_EFFECTS = DOMProperty.injection.HAS_SIDE_EFFECTS;
+var HAS_POSITIVE_NUMERIC_VALUE =
+  DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE;
+
+var DefaultDOMPropertyConfig = {
+  isCustomAttribute: RegExp.prototype.test.bind(
+    /^(data|aria)-[a-z_][a-z\d_.\-]*$/
+  ),
+  Properties: {
+    /**
+     * Standard Properties
+     */
+    accept: null,
+    accessKey: null,
+    action: null,
+    allowFullScreen: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
+    allowTransparency: MUST_USE_ATTRIBUTE,
+    alt: null,
+    async: HAS_BOOLEAN_VALUE,
+    autoComplete: null,
+    // autoFocus is polyfilled/normalized by AutoFocusMixin
+    // autoFocus: HAS_BOOLEAN_VALUE,
+    autoPlay: HAS_BOOLEAN_VALUE,
+    cellPadding: null,
+    cellSpacing: null,
+    charSet: MUST_USE_ATTRIBUTE,
+    checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
+    className: MUST_USE_PROPERTY,
+    cols: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE,
+    colSpan: null,
+    content: null,
+    contentEditable: null,
+    contextMenu: MUST_USE_ATTRIBUTE,
+    controls: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
+    crossOrigin: null,
+    data: null, // For `<object />` acts as `src`.
+    dateTime: MUST_USE_ATTRIBUTE,
+    defer: HAS_BOOLEAN_VALUE,
+    dir: null,
+    disabled: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
+    download: null,
+    draggable: null,
+    encType: null,
+    form: MUST_USE_ATTRIBUTE,
+    formNoValidate: HAS_BOOLEAN_VALUE,
+    frameBorder: MUST_USE_ATTRIBUTE,
+    height: MUST_USE_ATTRIBUTE,
+    hidden: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
+    href: null,
+    hrefLang: null,
+    htmlFor: null,
+    httpEquiv: null,
+    icon: null,
+    id: MUST_USE_PROPERTY,
+    label: null,
+    lang: null,
+    list: null,
+    loop: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
+    max: null,
+    maxLength: MUST_USE_ATTRIBUTE,
+    mediaGroup: null,
+    method: null,
+    min: null,
+    multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
+    muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
+    name: null,
+    noValidate: HAS_BOOLEAN_VALUE,
+    pattern: null,
+    placeholder: null,
+    poster: null,
+    preload: null,
+    radioGroup: null,
+    readOnly: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
+    rel: null,
+    required: HAS_BOOLEAN_VALUE,
+    role: MUST_USE_ATTRIBUTE,
+    rows: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE,
+    rowSpan: null,
+    sandbox: null,
+    scope: null,
+    scrollLeft: MUST_USE_PROPERTY,
+    scrollTop: MUST_USE_PROPERTY,
+    seamless: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
+    selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
+    size: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE,
+    span: HAS_POSITIVE_NUMERIC_VALUE,
+    spellCheck: null,
+    src: null,
+    srcDoc: MUST_USE_PROPERTY,
+    step: null,
+    style: null,
+    tabIndex: null,
+    target: null,
+    title: null,
+    type: null,
+    value: MUST_USE_PROPERTY | HAS_SIDE_EFFECTS,
+    width: MUST_USE_ATTRIBUTE,
+    wmode: MUST_USE_ATTRIBUTE,
+
+    /**
+     * Non-standard Properties
+     */
+    autoCapitalize: null, // Supported in Mobile Safari for keyboard hints
+    autoCorrect: null, // Supported in Mobile Safari for keyboard hints
+    property: null, // Supports OG in meta tags
+
+    /**
+     * SVG Properties
+     */
+    cx: MUST_USE_ATTRIBUTE,
+    cy: MUST_USE_ATTRIBUTE,
+    d: MUST_USE_ATTRIBUTE,
+    fill: MUST_USE_ATTRIBUTE,
+    fx: MUST_USE_ATTRIBUTE,
+    fy: MUST_USE_ATTRIBUTE,
+    gradientTransform: MUST_USE_ATTRIBUTE,
+    gradientUnits: MUST_USE_ATTRIBUTE,
+    offset: MUST_USE_ATTRIBUTE,
+    points: MUST_USE_ATTRIBUTE,
+    r: MUST_USE_ATTRIBUTE,
+    rx: MUST_USE_ATTRIBUTE,
+    ry: MUST_USE_ATTRIBUTE,
+    spreadMethod: MUST_USE_ATTRIBUTE,
+    stopColor: MUST_USE_ATTRIBUTE,
+    stopOpacity: MUST_USE_ATTRIBUTE,
+    stroke: MUST_USE_ATTRIBUTE,
+    strokeLinecap: MUST_USE_ATTRIBUTE,
+    strokeWidth: MUST_USE_ATTRIBUTE,
+    transform: MUST_USE_ATTRIBUTE,
+    version: MUST_USE_ATTRIBUTE,
+    viewBox: MUST_USE_ATTRIBUTE,
+    x1: MUST_USE_ATTRIBUTE,
+    x2: MUST_USE_ATTRIBUTE,
+    x: MUST_USE_ATTRIBUTE,
+    y1: MUST_USE_ATTRIBUTE,
+    y2: MUST_USE_ATTRIBUTE,
+    y: MUST_USE_ATTRIBUTE
+  },
+  DOMAttributeNames: {
+    className: 'class',
+    gradientTransform: 'gradientTransform',
+    gradientUnits: 'gradientUnits',
+    htmlFor: 'for',
+    spreadMethod: 'spreadMethod',
+    stopColor: 'stop-color',
+    stopOpacity: 'stop-opacity',
+    strokeLinecap: 'stroke-linecap',
+    strokeWidth: 'stroke-width',
+    viewBox: 'viewBox'
+  },
+  DOMPropertyNames: {
+    autoCapitalize: 'autocapitalize',
+    autoComplete: 'autocomplete',
+    autoCorrect: 'autocorrect',
+    autoFocus: 'autofocus',
+    autoPlay: 'autoplay',
+    encType: 'enctype',
+    hrefLang: 'hreflang',
+    radioGroup: 'radiogroup',
+    spellCheck: 'spellcheck',
+    srcDoc: 'srcdoc'
+  },
+  DOMMutationMethods: {
+    /**
+     * Setting `className` to null may cause it to be set to the string "null".
+     *
+     * @param {DOMElement} node
+     * @param {*} value
+     */
+    className: function(node, value) {
+      node.className = value || '';
+    }
+  }
+};
+
+module.exports = DefaultDOMPropertyConfig;
+
+},{"./DOMProperty":8}],12:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule DefaultEventPluginOrder
+ */
+
+"use strict";
+
+ var keyOf = require("./keyOf");
+
+/**
+ * Module that is injectable into `EventPluginHub`, that specifies a
+ * deterministic ordering of `EventPlugin`s. A convenient way to reason about
+ * plugins, without having to package every one of them. This is better than
+ * having plugins be ordered in the same order that they are injected because
+ * that ordering would be influenced by the packaging order.
+ * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
+ * preventing default on events is convenient in `SimpleEventPlugin` handlers.
+ */
+var DefaultEventPluginOrder = [
+  keyOf({ResponderEventPlugin: null}),
+  keyOf({SimpleEventPlugin: null}),
+  keyOf({TapEventPlugin: null}),
+  keyOf({EnterLeaveEventPlugin: null}),
+  keyOf({ChangeEventPlugin: null}),
+  keyOf({SelectEventPlugin: null}),
+  keyOf({CompositionEventPlugin: null}),
+  keyOf({AnalyticsEventPlugin: null}),
+  keyOf({MobileSafariClickEventPlugin: null})
+];
+
+module.exports = DefaultEventPluginOrder;
+
+},{"./keyOf":115}],13:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule EnterLeaveEventPlugin
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var EventConstants = require("./EventConstants");
+var EventPropagators = require("./EventPropagators");
+var SyntheticMouseEvent = require("./SyntheticMouseEvent");
+
+var ReactMount = require("./ReactMount");
+var keyOf = require("./keyOf");
+
+var topLevelTypes = EventConstants.topLevelTypes;
+var getFirstReactDOM = ReactMount.getFirstReactDOM;
+
+var eventTypes = {
+  mouseEnter: {
+    registrationName: keyOf({onMouseEnter: null}),
+    dependencies: [
+      topLevelTypes.topMouseOut,
+      topLevelTypes.topMouseOver
+    ]
+  },
+  mouseLeave: {
+    registrationName: keyOf({onMouseLeave: null}),
+    dependencies: [
+      topLevelTypes.topMouseOut,
+      topLevelTypes.topMouseOver
+    ]
+  }
+};
+
+var extractedEvents = [null, null];
+
+var EnterLeaveEventPlugin = {
+
+  eventTypes: eventTypes,
+
+  /**
+   * For almost every interaction we care about, there will be both a top-level
+   * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
+   * we do not extract duplicate events. However, moving the mouse into the
+   * browser from outside will not fire a `mouseout` event. In this case, we use
+   * the `mouseover` top-level event.
+   *
+   * @param {string} topLevelType Record from `EventConstants`.
+   * @param {DOMEventTarget} topLevelTarget The listening component root node.
+   * @param {string} topLevelTargetID ID of `topLevelTarget`.
+   * @param {object} nativeEvent Native browser event.
+   * @return {*} An accumulation of synthetic events.
+   * @see {EventPluginHub.extractEvents}
+   */
+  extractEvents: function(
+      topLevelType,
+      topLevelTarget,
+      topLevelTargetID,
+      nativeEvent) {
+    if (topLevelType === topLevelTypes.topMouseOver &&
+        (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
+      return null;
+    }
+    if (topLevelType !== topLevelTypes.topMouseOut &&
+        topLevelType !== topLevelTypes.topMouseOver) {
+      // Must not be a mouse in or mouse out - ignoring.
+      return null;
+    }
+
+    var win;
+    if (topLevelTarget.window === topLevelTarget) {
+      // `topLevelTarget` is probably a window object.
+      win = topLevelTarget;
+    } else {
+      // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
+      var doc = topLevelTarget.ownerDocument;
+      if (doc) {
+        win = doc.defaultView || doc.parentWindow;
+      } else {
+        win = window;
+      }
+    }
+
+    var from, to;
+    if (topLevelType === topLevelTypes.topMouseOut) {
+      from = topLevelTarget;
+      to =
+        getFirstReactDOM(nativeEvent.relatedTarget || nativeEvent.toElement) ||
+        win;
+    } else {
+      from = win;
+      to = topLevelTarget;
+    }
+
+    if (from === to) {
+      // Nothing pertains to our managed components.
+      return null;
+    }
+
+    var fromID = from ? ReactMount.getID(from) : '';
+    var toID = to ? ReactMount.getID(to) : '';
+
+    var leave = SyntheticMouseEvent.getPooled(
+      eventTypes.mouseLeave,
+      fromID,
+      nativeEvent
+    );
+    leave.type = 'mouseleave';
+    leave.target = from;
+    leave.relatedTarget = to;
+
+    var enter = SyntheticMouseEvent.getPooled(
+      eventTypes.mouseEnter,
+      toID,
+      nativeEvent
+    );
+    enter.type = 'mouseenter';
+    enter.target = to;
+    enter.relatedTarget = from;
+
+    EventPropagators.accumulateEnterLeaveDispatches(leave, enter, fromID, toID);
+
+    extractedEvents[0] = leave;
+    extractedEvents[1] = enter;
+
+    return extractedEvents;
+  }
+
+};
+
+module.exports = EnterLeaveEventPlugin;
+
+},{"./EventConstants":14,"./EventPropagators":19,"./ReactMount":55,"./SyntheticMouseEvent":80,"./keyOf":115}],14:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule EventConstants
+ */
+
+"use strict";
+
+var keyMirror = require("./keyMirror");
+
+var PropagationPhases = keyMirror({bubbled: null, captured: null});
+
+/**
+ * Types of raw signals from the browser caught at the top level.
+ */
+var topLevelTypes = keyMirror({
+  topBlur: null,
+  topChange: null,
+  topClick: null,
+  topCompositionEnd: null,
+  topCompositionStart: null,
+  topCompositionUpdate: null,
+  topContextMenu: null,
+  topCopy: null,
+  topCut: null,
+  topDoubleClick: null,
+  topDrag: null,
+  topDragEnd: null,
+  topDragEnter: null,
+  topDragExit: null,
+  topDragLeave: null,
+  topDragOver: null,
+  topDragStart: null,
+  topDrop: null,
+  topError: null,
+  topFocus: null,
+  topInput: null,
+  topKeyDown: null,
+  topKeyPress: null,
+  topKeyUp: null,
+  topLoad: null,
+  topMouseDown: null,
+  topMouseMove: null,
+  topMouseOut: null,
+  topMouseOver: null,
+  topMouseUp: null,
+  topPaste: null,
+  topReset: null,
+  topScroll: null,
+  topSelectionChange: null,
+  topSubmit: null,
+  topTouchCancel: null,
+  topTouchEnd: null,
+  topTouchMove: null,
+  topTouchStart: null,
+  topWheel: null
+});
+
+var EventConstants = {
+  topLevelTypes: topLevelTypes,
+  PropagationPhases: PropagationPhases
+};
+
+module.exports = EventConstants;
+
+},{"./keyMirror":114}],15:[function(require,module,exports){
+/**
+ * @providesModule EventListener
+ */
+
+var emptyFunction = require("./emptyFunction");
+
+/**
+ * Upstream version of event listener. Does not take into account specific
+ * nature of platform.
+ */
+var EventListener = {
+  /**
+   * Listen to DOM events during the bubble phase.
+   *
+   * @param {DOMEventTarget} target DOM element to register listener on.
+   * @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
+   * @param {function} callback Callback function.
+   * @return {object} Object with a `remove` method.
+   */
+  listen: function(target, eventType, callback) {
+    if (target.addEventListener) {
+      target.addEventListener(eventType, callback, false);
+      return {
+        remove: function() {
+          target.removeEventListener(eventType, callback, false);
+        }
+      };
+    } else if (target.attachEvent) {
+      target.attachEvent('on' + eventType, callback);
+      return {
+        remove: function() {
+          target.detachEvent(eventType, callback);
+        }
+      };
+    }
+  },
+
+  /**
+   * Listen to DOM events during the capture phase.
+   *
+   * @param {DOMEventTarget} target DOM element to register listener on.
+   * @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
+   * @param {function} callback Callback function.
+   * @return {object} Object with a `remove` method.
+   */
+  capture: function(target, eventType, callback) {
+    if (!target.addEventListener) {
+      if ("production" !== "development") {
+        console.error(
+          'Attempted to listen to events during the capture phase on a ' +
+          'browser that does not support the capture phase. Your application ' +
+          'will not receive some events.'
+        );
+      }
+      return {
+        remove: emptyFunction
+      };
+    } else {
+      target.addEventListener(eventType, callback, true);
+      return {
+        remove: function() {
+          target.removeEventListener(eventType, callback, true);
+        }
+      };
+    }
+  }
+};
+
+module.exports = EventListener;
+
+},{"./emptyFunction":95}],16:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule EventPluginHub
+ */
+
+"use strict";
+
+var EventPluginRegistry = require("./EventPluginRegistry");
+var EventPluginUtils = require("./EventPluginUtils");
+var ExecutionEnvironment = require("./ExecutionEnvironment");
+
+var accumulate = require("./accumulate");
+var forEachAccumulated = require("./forEachAccumulated");
+var invariant = require("./invariant");
+var isEventSupported = require("./isEventSupported");
+
+/**
+ * Internal store for event listeners
+ */
+var listenerBank = {};
+
+/**
+ * Internal queue of events that have accumulated their dispatches and are
+ * waiting to have their dispatches executed.
+ */
+var eventQueue = null;
+
+/**
+ * Dispatches an event and releases it back into the pool, unless persistent.
+ *
+ * @param {?object} event Synthetic event to be dispatched.
+ * @private
+ */
+var executeDispatchesAndRelease = function(event) {
+  if (event) {
+    var executeDispatch = EventPluginUtils.executeDispatch;
+    // Plugins can provide custom behavior when dispatching events.
+    var PluginModule = EventPluginRegistry.getPluginModuleForEvent(event);
+    if (PluginModule && PluginModule.executeDispatch) {
+      executeDispatch = PluginModule.executeDispatch;
+    }
+    EventPluginUtils.executeDispatchesInOrder(event, executeDispatch);
+
+    if (!event.isPersistent()) {
+      event.constructor.release(event);
+    }
+  }
+};
+
+/**
+ * - `InstanceHandle`: [required] Module that performs logical traversals of DOM
+ *   hierarchy given ids of the logical DOM elements involved.
+ */
+var InstanceHandle = null;
+
+function validateInstanceHandle() {
+  var invalid = !InstanceHandle||
+    !InstanceHandle.traverseTwoPhase ||
+    !InstanceHandle.traverseEnterLeave;
+  if (invalid) {
+    throw new Error('InstanceHandle not injected before use!');
+  }
+}
+
+/**
+ * This is a unified interface for event plugins to be installed and configured.
+ *
+ * Event plugins can implement the following properties:
+ *
+ *   `extractEvents` {function(string, DOMEventTarget, string, object): *}
+ *     Required. When a top-level event is fired, this method is expected to
+ *     extract synthetic events that will in turn be queued and dispatched.
+ *
+ *   `eventTypes` {object}
+ *     Optional, plugins that fire events must publish a mapping of registration
+ *     names that are used to register listeners. Values of this mapping must
+ *     be objects that contain `registrationName` or `phasedRegistrationNames`.
+ *
+ *   `executeDispatch` {function(object, function, string)}
+ *     Optional, allows plugins to override how an event gets dispatched. By
+ *     default, the listener is simply invoked.
+ *
+ * Each plugin that is injected into `EventsPluginHub` is immediately operable.
+ *
+ * @public
+ */
+var EventPluginHub = {
+
+  /**
+   * Methods for injecting dependencies.
+   */
+  injection: {
+
+    /**
+     * @param {object} InjectedMount
+     * @public
+     */
+    injectMount: EventPluginUtils.injection.injectMount,
+
+    /**
+     * @param {object} InjectedInstanceHandle
+     * @public
+     */
+    injectInstanceHandle: function(InjectedInstanceHandle) {
+      InstanceHandle = InjectedInstanceHandle;
+      if ("production" !== "development") {
+        validateInstanceHandle();
+      }
+    },
+
+    getInstanceHandle: function() {
+      if ("production" !== "development") {
+        validateInstanceHandle();
+      }
+      return InstanceHandle;
+    },
+
+    /**
+     * @param {array} InjectedEventPluginOrder
+     * @public
+     */
+    injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder,
+
+    /**
+     * @param {object} injectedNamesToPlugins Map from names to plugin modules.
+     */
+    injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName
+
+  },
+
+  eventNameDispatchConfigs: EventPluginRegistry.eventNameDispatchConfigs,
+
+  registrationNameModules: EventPluginRegistry.registrationNameModules,
+
+  /**
+   * Stores `listener` at `listenerBank[registrationName][id]`. Is idempotent.
+   *
+   * @param {string} id ID of the DOM element.
+   * @param {string} registrationName Name of listener (e.g. `onClick`).
+   * @param {?function} listener The callback to store.
+   */
+  putListener: function(id, registrationName, listener) {
+    ("production" !== "development" ? invariant(
+      ExecutionEnvironment.canUseDOM,
+      'Cannot call putListener() in a non-DOM environment.'
+    ) : invariant(ExecutionEnvironment.canUseDOM));
+    ("production" !== "development" ? invariant(
+      !listener || typeof listener === 'function',
+      'Expected %s listener to be a function, instead got type %s',
+      registrationName, typeof listener
+    ) : invariant(!listener || typeof listener === 'function'));
+
+    if ("production" !== "development") {
+      // IE8 has no API for event capturing and the `onScroll` event doesn't
+      // bubble.
+      if (registrationName === 'onScroll' &&
+          !isEventSupported('scroll', true)) {
+        console.warn('This browser doesn\'t support the `onScroll` event');
+      }
+    }
+    var bankForRegistrationName =
+      listenerBank[registrationName] || (listenerBank[registrationName] = {});
+    bankForRegistrationName[id] = listener;
+  },
+
+  /**
+   * @param {string} id ID of the DOM element.
+   * @param {string} registrationName Name of listener (e.g. `onClick`).
+   * @return {?function} The stored callback.
+   */
+  getListener: function(id, registrationName) {
+    var bankForRegistrationName = listenerBank[registrationName];
+    return bankForRegistrationName && bankForRegistrationName[id];
+  },
+
+  /**
+   * Deletes a listener from the registration bank.
+   *
+   * @param {string} id ID of the DOM element.
+   * @param {string} registrationName Name of listener (e.g. `onClick`).
+   */
+  deleteListener: function(id, registrationName) {
+    var bankForRegistrationName = listenerBank[registrationName];
+    if (bankForRegistrationName) {
+      delete bankForRegistrationName[id];
+    }
+  },
+
+  /**
+   * Deletes all listeners for the DOM element with the supplied ID.
+   *
+   * @param {string} id ID of the DOM element.
+   */
+  deleteAllListeners: function(id) {
+    for (var registrationName in listenerBank) {
+      delete listenerBank[registrationName][id];
+    }
+  },
+
+  /**
+   * Allows registered plugins an opportunity to extract events from top-level
+   * native browser events.
+   *
+   * @param {string} topLevelType Record from `EventConstants`.
+   * @param {DOMEventTarget} topLevelTarget The listening component root node.
+   * @param {string} topLevelTargetID ID of `topLevelTarget`.
+   * @param {object} nativeEvent Native browser event.
+   * @return {*} An accumulation of synthetic events.
+   * @internal
+   */
+  extractEvents: function(
+      topLevelType,
+      topLevelTarget,
+      topLevelTargetID,
+      nativeEvent) {
+    var events;
+    var plugins = EventPluginRegistry.plugins;
+    for (var i = 0, l = plugins.length; i < l; i++) {
+      // Not every plugin in the ordering may be loaded at runtime.
+      var possiblePlugin = plugins[i];
+      if (possiblePlugin) {
+        var extractedEvents = possiblePlugin.extractEvents(
+          topLevelType,
+          topLevelTarget,
+          topLevelTargetID,
+          nativeEvent
+        );
+        if (extractedEvents) {
+          events = accumulate(events, extractedEvents);
+        }
+      }
+    }
+    return events;
+  },
+
+  /**
+   * Enqueues a synthetic event that should be dispatched when
+   * `processEventQueue` is invoked.
+   *
+   * @param {*} events An accumulation of synthetic events.
+   * @internal
+   */
+  enqueueEvents: function(events) {
+    if (events) {
+      eventQueue = accumulate(eventQueue, events);
+    }
+  },
+
+  /**
+   * Dispatches all synthetic events on the event queue.
+   *
+   * @internal
+   */
+  processEventQueue: function() {
+    // Set `eventQueue` to null before processing it so that we can tell if more
+    // events get enqueued while processing.
+    var processingEventQueue = eventQueue;
+    eventQueue = null;
+    forEachAccumulated(processingEventQueue, executeDispatchesAndRelease);
+    ("production" !== "development" ? invariant(
+      !eventQueue,
+      'processEventQueue(): Additional events were enqueued while processing ' +
+      'an event queue. Support for this has not yet been implemented.'
+    ) : invariant(!eventQueue));
+  },
+
+  /**
+   * These are needed for tests only. Do not use!
+   */
+  __purge: function() {
+    listenerBank = {};
+  },
+
+  __getListenerBank: function() {
+    return listenerBank;
+  }
+
+};
+
+module.exports = EventPluginHub;
+
+},{"./EventPluginRegistry":17,"./EventPluginUtils":18,"./ExecutionEnvironment":20,"./accumulate":86,"./forEachAccumulated":98,"./invariant":108,"./isEventSupported":109}],17:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule EventPluginRegistry
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var invariant = require("./invariant");
+
+/**
+ * Injectable ordering of event plugins.
+ */
+var EventPluginOrder = null;
+
+/**
+ * Injectable mapping from names to event plugin modules.
+ */
+var namesToPlugins = {};
+
+/**
+ * Recomputes the plugin list using the injected plugins and plugin ordering.
+ *
+ * @private
+ */
+function recomputePluginOrdering() {
+  if (!EventPluginOrder) {
+    // Wait until an `EventPluginOrder` is injected.
+    return;
+  }
+  for (var pluginName in namesToPlugins) {
+    var PluginModule = namesToPlugins[pluginName];
+    var pluginIndex = EventPluginOrder.indexOf(pluginName);
+    ("production" !== "development" ? invariant(
+      pluginIndex > -1,
+      'EventPluginRegistry: Cannot inject event plugins that do not exist in ' +
+      'the plugin ordering, `%s`.',
+      pluginName
+    ) : invariant(pluginIndex > -1));
+    if (EventPluginRegistry.plugins[pluginIndex]) {
+      continue;
+    }
+    ("production" !== "development" ? invariant(
+      PluginModule.extractEvents,
+      'EventPluginRegistry: Event plugins must implement an `extractEvents` ' +
+      'method, but `%s` does not.',
+      pluginName
+    ) : invariant(PluginModule.extractEvents));
+    EventPluginRegistry.plugins[pluginIndex] = PluginModule;
+    var publishedEvents = PluginModule.eventTypes;
+    for (var eventName in publishedEvents) {
+      ("production" !== "development" ? invariant(
+        publishEventForPlugin(
+          publishedEvents[eventName],
+          PluginModule,
+          eventName
+        ),
+        'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.',
+        eventName,
+        pluginName
+      ) : invariant(publishEventForPlugin(
+        publishedEvents[eventName],
+        PluginModule,
+        eventName
+      )));
+    }
+  }
+}
+
+/**
+ * Publishes an event so that it can be dispatched by the supplied plugin.
+ *
+ * @param {object} dispatchConfig Dispatch configuration for the event.
+ * @param {object} PluginModule Plugin publishing the event.
+ * @return {boolean} True if the event was successfully published.
+ * @private
+ */
+function publishEventForPlugin(dispatchConfig, PluginModule, eventName) {
+  ("production" !== "development" ? invariant(
+    !EventPluginRegistry.eventNameDispatchConfigs[eventName],
+    'EventPluginHub: More than one plugin attempted to publish the same ' +
+    'event name, `%s`.',
+    eventName
+  ) : invariant(!EventPluginRegistry.eventNameDispatchConfigs[eventName]));
+  EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig;
+
+  var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
+  if (phasedRegistrationNames) {
+    for (var phaseName in phasedRegistrationNames) {
+      if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
+        var phasedRegistrationName = phasedRegistrationNames[phaseName];
+        publishRegistrationName(
+          phasedRegistrationName,
+          PluginModule,
+          eventName
+        );
+      }
+    }
+    return true;
+  } else if (dispatchConfig.registrationName) {
+    publishRegistrationName(
+      dispatchConfig.registrationName,
+      PluginModule,
+      eventName
+    );
+    return true;
+  }
+  return false;
+}
+
+/**
+ * Publishes a registration name that is used to identify dispatched events and
+ * can be used with `EventPluginHub.putListener` to register listeners.
+ *
+ * @param {string} registrationName Registration name to add.
+ * @param {object} PluginModule Plugin publishing the event.
+ * @private
+ */
+function publishRegistrationName(registrationName, PluginModule, eventName) {
+  ("production" !== "development" ? invariant(
+    !EventPluginRegistry.registrationNameModules[registrationName],
+    'EventPluginHub: More than one plugin attempted to publish the same ' +
+    'registration name, `%s`.',
+    registrationName
+  ) : invariant(!EventPluginRegistry.registrationNameModules[registrationName]));
+  EventPluginRegistry.registrationNameModules[registrationName] = PluginModule;
+  EventPluginRegistry.registrationNameDependencies[registrationName] =
+    PluginModule.eventTypes[eventName].dependencies;
+}
+
+/**
+ * Registers plugins so that they can extract and dispatch events.
+ *
+ * @see {EventPluginHub}
+ */
+var EventPluginRegistry = {
+
+  /**
+   * Ordered list of injected plugins.
+   */
+  plugins: [],
+
+  /**
+   * Mapping from event name to dispatch config
+   */
+  eventNameDispatchConfigs: {},
+
+  /**
+   * Mapping from registration name to plugin module
+   */
+  registrationNameModules: {},
+
+  /**
+   * Mapping from registration name to event name
+   */
+  registrationNameDependencies: {},
+
+  /**
+   * Injects an ordering of plugins (by plugin name). This allows the ordering
+   * to be decoupled from injection of the actual plugins so that ordering is
+   * always deterministic regardless of packaging, on-the-fly injection, etc.
+   *
+   * @param {array} InjectedEventPluginOrder
+   * @internal
+   * @see {EventPluginHub.injection.injectEventPluginOrder}
+   */
+  injectEventPluginOrder: function(InjectedEventPluginOrder) {
+    ("production" !== "development" ? invariant(
+      !EventPluginOrder,
+      'EventPluginRegistry: Cannot inject event plugin ordering more than once.'
+    ) : invariant(!EventPluginOrder));
+    // Clone the ordering so it cannot be dynamically mutated.
+    EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder);
+    recomputePluginOrdering();
+  },
+
+  /**
+   * Injects plugins to be used by `EventPluginHub`. The plugin names must be
+   * in the ordering injected by `injectEventPluginOrder`.
+   *
+   * Plugins can be injected as part of page initialization or on-the-fly.
+   *
+   * @param {object} injectedNamesToPlugins Map from names to plugin modules.
+   * @internal
+   * @see {EventPluginHub.injection.injectEventPluginsByName}
+   */
+  injectEventPluginsByName: function(injectedNamesToPlugins) {
+    var isOrderingDirty = false;
+    for (var pluginName in injectedNamesToPlugins) {
+      if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
+        continue;
+      }
+      var PluginModule = injectedNamesToPlugins[pluginName];
+      if (namesToPlugins[pluginName] !== PluginModule) {
+        ("production" !== "development" ? invariant(
+          !namesToPlugins[pluginName],
+          'EventPluginRegistry: Cannot inject two different event plugins ' +
+          'using the same name, `%s`.',
+          pluginName
+        ) : invariant(!namesToPlugins[pluginName]));
+        namesToPlugins[pluginName] = PluginModule;
+        isOrderingDirty = true;
+      }
+    }
+    if (isOrderingDirty) {
+      recomputePluginOrdering();
+    }
+  },
+
+  /**
+   * Looks up the plugin for the supplied event.
+   *
+   * @param {object} event A synthetic event.
+   * @return {?object} The plugin that created the supplied event.
+   * @internal
+   */
+  getPluginModuleForEvent: function(event) {
+    var dispatchConfig = event.dispatchConfig;
+    if (dispatchConfig.registrationName) {
+      return EventPluginRegistry.registrationNameModules[
+        dispatchConfig.registrationName
+      ] || null;
+    }
+    for (var phase in dispatchConfig.phasedRegistrationNames) {
+      if (!dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)) {
+        continue;
+      }
+      var PluginModule = EventPluginRegistry.registrationNameModules[
+        dispatchConfig.phasedRegistrationNames[phase]
+      ];
+      if (PluginModule) {
+        return PluginModule;
+      }
+    }
+    return null;
+  },
+
+  /**
+   * Exposed for unit testing.
+   * @private
+   */
+  _resetEventPlugins: function() {
+    EventPluginOrder = null;
+    for (var pluginName in namesToPlugins) {
+      if (namesToPlugins.hasOwnProperty(pluginName)) {
+        delete namesToPlugins[pluginName];
+      }
+    }
+    EventPluginRegistry.plugins.length = 0;
+
+    var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs;
+    for (var eventName in eventNameDispatchConfigs) {
+      if (eventNameDispatchConfigs.hasOwnProperty(eventName)) {
+        delete eventNameDispatchConfigs[eventName];
+      }
+    }
+
+    var registrationNameModules = EventPluginRegistry.registrationNameModules;
+    for (var registrationName in registrationNameModules) {
+      if (registrationNameModules.hasOwnProperty(registrationName)) {
+        delete registrationNameModules[registrationName];
+      }
+    }
+  }
+
+};
+
+module.exports = EventPluginRegistry;
+
+},{"./invariant":108}],18:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule EventPluginUtils
+ */
+
+"use strict";
+
+var EventConstants = require("./EventConstants");
+
+var invariant = require("./invariant");
+
+/**
+ * Injected dependencies:
+ */
+
+/**
+ * - `Mount`: [required] Module that can convert between React dom IDs and
+ *   actual node references.
+ */
+var injection = {
+  Mount: null,
+  injectMount: function(InjectedMount) {
+    injection.Mount = InjectedMount;
+    if ("production" !== "development") {
+      ("production" !== "development" ? invariant(
+        InjectedMount && InjectedMount.getNode,
+        'EventPluginUtils.injection.injectMount(...): Injected Mount module ' +
+        'is missing getNode.'
+      ) : invariant(InjectedMount && InjectedMount.getNode));
+    }
+  }
+};
+
+var topLevelTypes = EventConstants.topLevelTypes;
+
+function isEndish(topLevelType) {
+  return topLevelType === topLevelTypes.topMouseUp ||
+         topLevelType === topLevelTypes.topTouchEnd ||
+         topLevelType === topLevelTypes.topTouchCancel;
+}
+
+function isMoveish(topLevelType) {
+  return topLevelType === topLevelTypes.topMouseMove ||
+         topLevelType === topLevelTypes.topTouchMove;
+}
+function isStartish(topLevelType) {
+  return topLevelType === topLevelTypes.topMouseDown ||
+         topLevelType === topLevelTypes.topTouchStart;
+}
+
+
+var validateEventDispatches;
+if ("production" !== "development") {
+  validateEventDispatches = function(event) {
+    var dispatchListeners = event._dispatchListeners;
+    var dispatchIDs = event._dispatchIDs;
+
+    var listenersIsArr = Array.isArray(dispatchListeners);
+    var idsIsArr = Array.isArray(dispatchIDs);
+    var IDsLen = idsIsArr ? dispatchIDs.length : dispatchIDs ? 1 : 0;
+    var listenersLen = listenersIsArr ?
+      dispatchListeners.length :
+      dispatchListeners ? 1 : 0;
+
+    ("production" !== "development" ? invariant(
+      idsIsArr === listenersIsArr && IDsLen === listenersLen,
+      'EventPluginUtils: Invalid `event`.'
+    ) : invariant(idsIsArr === listenersIsArr && IDsLen === listenersLen));
+  };
+}
+
+/**
+ * Invokes `cb(event, listener, id)`. Avoids using call if no scope is
+ * provided. The `(listener,id)` pair effectively forms the "dispatch" but are
+ * kept separate to conserve memory.
+ */
+function forEachEventDispatch(event, cb) {
+  var dispatchListeners = event._dispatchListeners;
+  var dispatchIDs = event._dispatchIDs;
+  if ("production" !== "development") {
+    validateEventDispatches(event);
+  }
+  if (Array.isArray(dispatchListeners)) {
+    for (var i = 0; i < dispatchListeners.length; i++) {
+      if (event.isPropagationStopped()) {
+        break;
+      }
+      // Listeners and IDs are two parallel arrays that are always in sync.
+      cb(event, dispatchListeners[i], dispatchIDs[i]);
+    }
+  } else if (dispatchListeners) {
+    cb(event, dispatchListeners, dispatchIDs);
+  }
+}
+
+/**
+ * Default implementation of PluginModule.executeDispatch().
+ * @param {SyntheticEvent} SyntheticEvent to handle
+ * @param {function} Application-level callback
+ * @param {string} domID DOM id to pass to the callback.
+ */
+function executeDispatch(event, listener, domID) {
+  event.currentTarget = injection.Mount.getNode(domID);
+  var returnValue = listener(event, domID);
+  event.currentTarget = null;
+  return returnValue;
+}
+
+/**
+ * Standard/simple iteration through an event's collected dispatches.
+ */
+function executeDispatchesInOrder(event, executeDispatch) {
+  forEachEventDispatch(event, executeDispatch);
+  event._dispatchListeners = null;
+  event._dispatchIDs = null;
+}
+
+/**
+ * Standard/simple iteration through an event's collected dispatches, but stops
+ * at the first dispatch execution returning true, and returns that id.
+ *
+ * @return id of the first dispatch execution who's listener returns true, or
+ * null if no listener returned true.
+ */
+function executeDispatchesInOrderStopAtTrue(event) {
+  var dispatchListeners = event._dispatchListeners;
+  var dispatchIDs = event._dispatchIDs;
+  if ("production" !== "development") {
+    validateEventDispatches(event);
+  }
+  if (Array.isArray(dispatchListeners)) {
+    for (var i = 0; i < dispatchListeners.length; i++) {
+      if (event.isPropagationStopped()) {
+        break;
+      }
+      // Listeners and IDs are two parallel arrays that are always in sync.
+      if (dispatchListeners[i](event, dispatchIDs[i])) {
+        return dispatchIDs[i];
+      }
+    }
+  } else if (dispatchListeners) {
+    if (dispatchListeners(event, dispatchIDs)) {
+      return dispatchIDs;
+    }
+  }
+  return null;
+}
+
+/**
+ * Execution of a "direct" dispatch - there must be at most one dispatch
+ * accumulated on the event or it is considered an error. It doesn't really make
+ * sense for an event with multiple dispatches (bubbled) to keep track of the
+ * return values at each dispatch execution, but it does tend to make sense when
+ * dealing with "direct" dispatches.
+ *
+ * @return The return value of executing the single dispatch.
+ */
+function executeDirectDispatch(event) {
+  if ("production" !== "development") {
+    validateEventDispatches(event);
+  }
+  var dispatchListener = event._dispatchListeners;
+  var dispatchID = event._dispatchIDs;
+  ("production" !== "development" ? invariant(
+    !Array.isArray(dispatchListener),
+    'executeDirectDispatch(...): Invalid `event`.'
+  ) : invariant(!Array.isArray(dispatchListener)));
+  var res = dispatchListener ?
+    dispatchListener(event, dispatchID) :
+    null;
+  event._dispatchListeners = null;
+  event._dispatchIDs = null;
+  return res;
+}
+
+/**
+ * @param {SyntheticEvent} event
+ * @return {bool} True iff number of dispatches accumulated is greater than 0.
+ */
+function hasDispatches(event) {
+  return !!event._dispatchListeners;
+}
+
+/**
+ * General utilities that are useful in creating custom Event Plugins.
+ */
+var EventPluginUtils = {
+  isEndish: isEndish,
+  isMoveish: isMoveish,
+  isStartish: isStartish,
+
+  executeDirectDispatch: executeDirectDispatch,
+  executeDispatch: executeDispatch,
+  executeDispatchesInOrder: executeDispatchesInOrder,
+  executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue,
+  hasDispatches: hasDispatches,
+  injection: injection,
+  useTouchEvents: false
+};
+
+module.exports = EventPluginUtils;
+
+},{"./EventConstants":14,"./invariant":108}],19:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule EventPropagators
+ */
+
+"use strict";
+
+var EventConstants = require("./EventConstants");
+var EventPluginHub = require("./EventPluginHub");
+
+var accumulate = require("./accumulate");
+var forEachAccumulated = require("./forEachAccumulated");
+
+var PropagationPhases = EventConstants.PropagationPhases;
+var getListener = EventPluginHub.getListener;
+
+/**
+ * Some event types have a notion of different registration names for different
+ * "phases" of propagation. This finds listeners by a given phase.
+ */
+function listenerAtPhase(id, event, propagationPhase) {
+  var registrationName =
+    event.dispatchConfig.phasedRegistrationNames[propagationPhase];
+  return getListener(id, registrationName);
+}
+
+/**
+ * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
+ * here, allows us to not have to bind or create functions for each event.
+ * Mutating the event's members allows us to not have to create a wrapping
+ * "dispatch" object that pairs the event with the listener.
+ */
+function accumulateDirectionalDispatches(domID, upwards, event) {
+  if ("production" !== "development") {
+    if (!domID) {
+      throw new Error('Dispatching id must not be null');
+    }
+  }
+  var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured;
+  var listener = listenerAtPhase(domID, event, phase);
+  if (listener) {
+    event._dispatchListeners = accumulate(event._dispatchListeners, listener);
+    event._dispatchIDs = accumulate(event._dispatchIDs, domID);
+  }
+}
+
+/**
+ * Collect dispatches (must be entirely collected before dispatching - see unit
+ * tests). Lazily allocate the array to conserve memory.  We must loop through
+ * each event and perform the traversal for each one. We can not perform a
+ * single traversal for the entire collection of events because each event may
+ * have a different target.
+ */
+function accumulateTwoPhaseDispatchesSingle(event) {
+  if (event && event.dispatchConfig.phasedRegistrationNames) {
+    EventPluginHub.injection.getInstanceHandle().traverseTwoPhase(
+      event.dispatchMarker,
+      accumulateDirectionalDispatches,
+      event
+    );
+  }
+}
+
+
+/**
+ * Accumulates without regard to direction, does not look for phased
+ * registration names. Same as `accumulateDirectDispatchesSingle` but without
+ * requiring that the `dispatchMarker` be the same as the dispatched ID.
+ */
+function accumulateDispatches(id, ignoredDirection, event) {
+  if (event && event.dispatchConfig.registrationName) {
+    var registrationName = event.dispatchConfig.registrationName;
+    var listener = getListener(id, registrationName);
+    if (listener) {
+      event._dispatchListeners = accumulate(event._dispatchListeners, listener);
+      event._dispatchIDs = accumulate(event._dispatchIDs, id);
+    }
+  }
+}
+
+/**
+ * Accumulates dispatches on an `SyntheticEvent`, but only for the
+ * `dispatchMarker`.
+ * @param {SyntheticEvent} event
+ */
+function accumulateDirectDispatchesSingle(event) {
+  if (event && event.dispatchConfig.registrationName) {
+    accumulateDispatches(event.dispatchMarker, null, event);
+  }
+}
+
+function accumulateTwoPhaseDispatches(events) {
+  forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
+}
+
+function accumulateEnterLeaveDispatches(leave, enter, fromID, toID) {
+  EventPluginHub.injection.getInstanceHandle().traverseEnterLeave(
+    fromID,
+    toID,
+    accumulateDispatches,
+    leave,
+    enter
+  );
+}
+
+
+function accumulateDirectDispatches(events) {
+  forEachAccumulated(events, accumulateDirectDispatchesSingle);
+}
+
+
+
+/**
+ * A small set of propagation patterns, each of which will accept a small amount
+ * of information, and generate a set of "dispatch ready event objects" - which
+ * are sets of events that have already been annotated with a set of dispatched
+ * listener functions/ids. The API is designed this way to discourage these
+ * propagation strategies from actually executing the dispatches, since we
+ * always want to collect the entire set of dispatches before executing event a
+ * single one.
+ *
+ * @constructor EventPropagators
+ */
+var EventPropagators = {
+  accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches,
+  accumulateDirectDispatches: accumulateDirectDispatches,
+  accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches
+};
+
+module.exports = EventPropagators;
+
+},{"./EventConstants":14,"./EventPluginHub":16,"./accumulate":86,"./forEachAccumulated":98}],20:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ExecutionEnvironment
+ */
+
+/*jslint evil: true */
+
+"use strict";
+
+var canUseDOM = typeof window !== 'undefined';
+
+/**
+ * Simple, lightweight module assisting with the detection and context of
+ * Worker. Helps avoid circular dependencies and allows code to reason about
+ * whether or not they are in a Worker, even if they never include the main
+ * `ReactWorker` dependency.
+ */
+var ExecutionEnvironment = {
+
+  canUseDOM: canUseDOM,
+
+  canUseWorkers: typeof Worker !== 'undefined',
+
+  canUseEventListeners:
+    canUseDOM && (window.addEventListener || window.attachEvent),
+
+  isInWorker: !canUseDOM // For now, this is true - might change in the future.
+
+};
+
+module.exports = ExecutionEnvironment;
+
+},{}],21:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule LinkedValueUtils
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var ReactPropTypes = require("./ReactPropTypes");
+
+var invariant = require("./invariant");
+
+var hasReadOnlyValue = {
+  'button': true,
+  'checkbox': true,
+  'image': true,
+  'hidden': true,
+  'radio': true,
+  'reset': true,
+  'submit': true
+};
+
+function _assertSingleLink(input) {
+  ("production" !== "development" ? invariant(
+      input.props.checkedLink == null || input.props.valueLink == null,
+      'Cannot provide a checkedLink and a valueLink. If you want to use ' +
+      'checkedLink, you probably don\'t want to use valueLink and vice versa.'
+  ) : invariant(input.props.checkedLink == null || input.props.valueLink == null));
+}
+function _assertValueLink(input) {
+  _assertSingleLink(input);
+  ("production" !== "development" ? invariant(
+    input.props.value == null && input.props.onChange == null,
+    'Cannot provide a valueLink and a value or onChange event. If you want ' +
+    'to use value or onChange, you probably don\'t want to use valueLink.'
+  ) : invariant(input.props.value == null && input.props.onChange == null));
+}
+
+function _assertCheckedLink(input) {
+  _assertSingleLink(input);
+  ("production" !== "development" ? invariant(
+    input.props.checked == null && input.props.onChange == null,
+    'Cannot provide a checkedLink and a checked property or onChange event. ' +
+    'If you want to use checked or onChange, you probably don\'t want to ' +
+    'use checkedLink'
+  ) : invariant(input.props.checked == null && input.props.onChange == null));
+}
+
+/**
+ * @param {SyntheticEvent} e change event to handle
+ */
+function _handleLinkedValueChange(e) {
+  /*jshint validthis:true */
+  this.props.valueLink.requestChange(e.target.value);
+}
+
+/**
+  * @param {SyntheticEvent} e change event to handle
+  */
+function _handleLinkedCheckChange(e) {
+  /*jshint validthis:true */
+  this.props.checkedLink.requestChange(e.target.checked);
+}
+
+/**
+ * Provide a linked `value` attribute for controlled forms. You should not use
+ * this outside of the ReactDOM controlled form components.
+ */
+var LinkedValueUtils = {
+  Mixin: {
+    propTypes: {
+      value: function(props, propName, componentName) {
+        if ("production" !== "development") {
+          if (props[propName] &&
+              !hasReadOnlyValue[props.type] &&
+              !props.onChange &&
+              !props.readOnly &&
+              !props.disabled) {
+            console.warn(
+              'You provided a `value` prop to a form field without an ' +
+              '`onChange` handler. This will render a read-only field. If ' +
+              'the field should be mutable use `defaultValue`. Otherwise, ' +
+              'set either `onChange` or `readOnly`.'
+            );
+          }
+        }
+      },
+      checked: function(props, propName, componentName) {
+        if ("production" !== "development") {
+          if (props[propName] &&
+              !props.onChange &&
+              !props.readOnly &&
+              !props.disabled) {
+            console.warn(
+              'You provided a `checked` prop to a form field without an ' +
+              '`onChange` handler. This will render a read-only field. If ' +
+              'the field should be mutable use `defaultChecked`. Otherwise, ' +
+              'set either `onChange` or `readOnly`.'
+            );
+          }
+        }
+      },
+      onChange: ReactPropTypes.func
+    }
+  },
+
+  /**
+   * @param {ReactComponent} input Form component
+   * @return {*} current value of the input either from value prop or link.
+   */
+  getValue: function(input) {
+    if (input.props.valueLink) {
+      _assertValueLink(input);
+      return input.props.valueLink.value;
+    }
+    return input.props.value;
+  },
+
+  /**
+   * @param {ReactComponent} input Form component
+   * @return {*} current checked status of the input either from checked prop
+   *             or link.
+   */
+  getChecked: function(input) {
+    if (input.props.checkedLink) {
+      _assertCheckedLink(input);
+      return input.props.checkedLink.value;
+    }
+    return input.props.checked;
+  },
+
+  /**
+   * @param {ReactComponent} input Form component
+   * @return {function} change callback either from onChange prop or link.
+   */
+  getOnChange: function(input) {
+    if (input.props.valueLink) {
+      _assertValueLink(input);
+      return _handleLinkedValueChange;
+    } else if (input.props.checkedLink) {
+      _assertCheckedLink(input);
+      return _handleLinkedCheckChange;
+    }
+    return input.props.onChange;
+  }
+};
+
+module.exports = LinkedValueUtils;
+
+},{"./ReactPropTypes":64,"./invariant":108}],22:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule MobileSafariClickEventPlugin
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var EventConstants = require("./EventConstants");
+
+var emptyFunction = require("./emptyFunction");
+
+var topLevelTypes = EventConstants.topLevelTypes;
+
+/**
+ * Mobile Safari does not fire properly bubble click events on non-interactive
+ * elements, which means delegated click listeners do not fire. The workaround
+ * for this bug involves attaching an empty click listener on the target node.
+ *
+ * This particular plugin works around the bug by attaching an empty click
+ * listener on `touchstart` (which does fire on every element).
+ */
+var MobileSafariClickEventPlugin = {
+
+  eventTypes: null,
+
+  /**
+   * @param {string} topLevelType Record from `EventConstants`.
+   * @param {DOMEventTarget} topLevelTarget The listening component root node.
+   * @param {string} topLevelTargetID ID of `topLevelTarget`.
+   * @param {object} nativeEvent Native browser event.
+   * @return {*} An accumulation of synthetic events.
+   * @see {EventPluginHub.extractEvents}
+   */
+  extractEvents: function(
+      topLevelType,
+      topLevelTarget,
+      topLevelTargetID,
+      nativeEvent) {
+    if (topLevelType === topLevelTypes.topTouchStart) {
+      var target = nativeEvent.target;
+      if (target && !target.onclick) {
+        target.onclick = emptyFunction;
+      }
+    }
+  }
+
+};
+
+module.exports = MobileSafariClickEventPlugin;
+
+},{"./EventConstants":14,"./emptyFunction":95}],23:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule PooledClass
+ */
+
+"use strict";
+
+var invariant = require("./invariant");
+
+/**
+ * Static poolers. Several custom versions for each potential number of
+ * arguments. A completely generic pooler is easy to implement, but would
+ * require accessing the `arguments` object. In each of these, `this` refers to
+ * the Class itself, not an instance. If any others are needed, simply add them
+ * here, or in their own files.
+ */
+var oneArgumentPooler = function(copyFieldsFrom) {
+  var Klass = this;
+  if (Klass.instancePool.length) {
+    var instance = Klass.instancePool.pop();
+    Klass.call(instance, copyFieldsFrom);
+    return instance;
+  } else {
+    return new Klass(copyFieldsFrom);
+  }
+};
+
+var twoArgumentPooler = function(a1, a2) {
+  var Klass = this;
+  if (Klass.instancePool.length) {
+    var instance = Klass.instancePool.pop();
+    Klass.call(instance, a1, a2);
+    return instance;
+  } else {
+    return new Klass(a1, a2);
+  }
+};
+
+var threeArgumentPooler = function(a1, a2, a3) {
+  var Klass = this;
+  if (Klass.instancePool.length) {
+    var instance = Klass.instancePool.pop();
+    Klass.call(instance, a1, a2, a3);
+    return instance;
+  } else {
+    return new Klass(a1, a2, a3);
+  }
+};
+
+var fiveArgumentPooler = function(a1, a2, a3, a4, a5) {
+  var Klass = this;
+  if (Klass.instancePool.length) {
+    var instance = Klass.instancePool.pop();
+    Klass.call(instance, a1, a2, a3, a4, a5);
+    return instance;
+  } else {
+    return new Klass(a1, a2, a3, a4, a5);
+  }
+};
+
+var standardReleaser = function(instance) {
+  var Klass = this;
+  ("production" !== "development" ? invariant(
+    instance instanceof Klass,
+    'Trying to release an instance into a pool of a different type.'
+  ) : invariant(instance instanceof Klass));
+  if (instance.destructor) {
+    instance.destructor();
+  }
+  if (Klass.instancePool.length < Klass.poolSize) {
+    Klass.instancePool.push(instance);
+  }
+};
+
+var DEFAULT_POOL_SIZE = 10;
+var DEFAULT_POOLER = oneArgumentPooler;
+
+/**
+ * Augments `CopyConstructor` to be a poolable class, augmenting only the class
+ * itself (statically) not adding any prototypical fields. Any CopyConstructor
+ * you give this may have a `poolSize` property, and will look for a
+ * prototypical `destructor` on instances (optional).
+ *
+ * @param {Function} CopyConstructor Constructor that can be used to reset.
+ * @param {Function} pooler Customizable pooler.
+ */
+var addPoolingTo = function(CopyConstructor, pooler) {
+  var NewKlass = CopyConstructor;
+  NewKlass.instancePool = [];
+  NewKlass.getPooled = pooler || DEFAULT_POOLER;
+  if (!NewKlass.poolSize) {
+    NewKlass.poolSize = DEFAULT_POOL_SIZE;
+  }
+  NewKlass.release = standardReleaser;
+  return NewKlass;
+};
+
+var PooledClass = {
+  addPoolingTo: addPoolingTo,
+  oneArgumentPooler: oneArgumentPooler,
+  twoArgumentPooler: twoArgumentPooler,
+  threeArgumentPooler: threeArgumentPooler,
+  fiveArgumentPooler: fiveArgumentPooler
+};
+
+module.exports = PooledClass;
+
+},{"./invariant":108}],24:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule React
+ */
+
+"use strict";
+
+var DOMPropertyOperations = require("./DOMPropertyOperations");
+var EventPluginUtils = require("./EventPluginUtils");
+var ReactChildren = require("./ReactChildren");
+var ReactComponent = require("./ReactComponent");
+var ReactCompositeComponent = require("./ReactCompositeComponent");
+var ReactContext = require("./ReactContext");
+var ReactCurrentOwner = require("./ReactCurrentOwner");
+var ReactDOM = require("./ReactDOM");
+var ReactDOMComponent = require("./ReactDOMComponent");
+var ReactDefaultInjection = require("./ReactDefaultInjection");
+var ReactInstanceHandles = require("./ReactInstanceHandles");
+var ReactMount = require("./ReactMount");
+var ReactMultiChild = require("./ReactMultiChild");
+var ReactPerf = require("./ReactPerf");
+var ReactPropTypes = require("./ReactPropTypes");
+var ReactServerRendering = require("./ReactServerRendering");
+var ReactTextComponent = require("./ReactTextComponent");
+
+var onlyChild = require("./onlyChild");
+
+ReactDefaultInjection.inject();
+
+var React = {
+  Children: {
+    map: ReactChildren.map,
+    forEach: ReactChildren.forEach,
+    only: onlyChild
+  },
+  DOM: ReactDOM,
+  PropTypes: ReactPropTypes,
+  initializeTouchEvents: function(shouldUseTouch) {
+    EventPluginUtils.useTouchEvents = shouldUseTouch;
+  },
+  createClass: ReactCompositeComponent.createClass,
+  constructAndRenderComponent: ReactMount.constructAndRenderComponent,
+  constructAndRenderComponentByID: ReactMount.constructAndRenderComponentByID,
+  renderComponent: ReactPerf.measure(
+    'React',
+    'renderComponent',
+    ReactMount.renderComponent
+  ),
+  renderComponentToString: ReactServerRendering.renderComponentToString,
+  unmountComponentAtNode: ReactMount.unmountComponentAtNode,
+  isValidClass: ReactCompositeComponent.isValidClass,
+  isValidComponent: ReactComponent.isValidComponent,
+  withContext: ReactContext.withContext,
+  __internals: {
+    Component: ReactComponent,
+    CurrentOwner: ReactCurrentOwner,
+    DOMComponent: ReactDOMComponent,
+    DOMPropertyOperations: DOMPropertyOperations,
+    InstanceHandles: ReactInstanceHandles,
+    Mount: ReactMount,
+    MultiChild: ReactMultiChild,
+    TextComponent: ReactTextComponent
+  }
+};
+
+if ("production" !== "development") {
+  var ExecutionEnvironment = require("./ExecutionEnvironment");
+  if (ExecutionEnvironment.canUseDOM &&
+      window.top === window.self &&
+      navigator.userAgent.indexOf('Chrome') > -1) {
+    console.debug(
+      'Download the React DevTools for a better development experience: ' +
+      'http://fb.me/react-devtools'
+    );
+  }
+}
+
+// Version exists only in the open-source version of React, not in Facebook's
+// internal version.
+React.version = '0.9.0';
+
+module.exports = React;
+
+},{"./DOMPropertyOperations":9,"./EventPluginUtils":18,"./ExecutionEnvironment":20,"./ReactChildren":25,"./ReactComponent":26,"./ReactCompositeComponent":29,"./ReactContext":30,"./ReactCurrentOwner":31,"./ReactDOM":32,"./ReactDOMComponent":34,"./ReactDefaultInjection":44,"./ReactInstanceHandles":53,"./ReactMount":55,"./ReactMultiChild":57,"./ReactPerf":60,"./ReactPropTypes":64,"./ReactServerRendering":68,"./ReactTextComponent":69,"./onlyChild":123}],25:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactChildren
+ */
+
+"use strict";
+
+var PooledClass = require("./PooledClass");
+
+var invariant = require("./invariant");
+var traverseAllChildren = require("./traverseAllChildren");
+
+var twoArgumentPooler = PooledClass.twoArgumentPooler;
+var threeArgumentPooler = PooledClass.threeArgumentPooler;
+
+/**
+ * PooledClass representing the bookkeeping associated with performing a child
+ * traversal. Allows avoiding binding callbacks.
+ *
+ * @constructor ForEachBookKeeping
+ * @param {!function} forEachFunction Function to perform traversal with.
+ * @param {?*} forEachContext Context to perform context with.
+ */
+function ForEachBookKeeping(forEachFunction, forEachContext) {
+  this.forEachFunction = forEachFunction;
+  this.forEachContext = forEachContext;
+}
+PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler);
+
+function forEachSingleChild(traverseContext, child, name, i) {
+  var forEachBookKeeping = traverseContext;
+  forEachBookKeeping.forEachFunction.call(
+    forEachBookKeeping.forEachContext, child, i);
+}
+
+/**
+ * Iterates through children that are typically specified as `props.children`.
+ *
+ * The provided forEachFunc(child, index) will be called for each
+ * leaf child.
+ *
+ * @param {?*} children Children tree container.
+ * @param {function(*, int)} forEachFunc.
+ * @param {*} forEachContext Context for forEachContext.
+ */
+function forEachChildren(children, forEachFunc, forEachContext) {
+  if (children == null) {
+    return children;
+  }
+
+  var traverseContext =
+    ForEachBookKeeping.getPooled(forEachFunc, forEachContext);
+  traverseAllChildren(children, forEachSingleChild, traverseContext);
+  ForEachBookKeeping.release(traverseContext);
+}
+
+/**
+ * PooledClass representing the bookkeeping associated with performing a child
+ * mapping. Allows avoiding binding callbacks.
+ *
+ * @constructor MapBookKeeping
+ * @param {!*} mapResult Object containing the ordered map of results.
+ * @param {!function} mapFunction Function to perform mapping with.
+ * @param {?*} mapContext Context to perform mapping with.
+ */
+function MapBookKeeping(mapResult, mapFunction, mapContext) {
+  this.mapResult = mapResult;
+  this.mapFunction = mapFunction;
+  this.mapContext = mapContext;
+}
+PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler);
+
+function mapSingleChildIntoContext(traverseContext, child, name, i) {
+  var mapBookKeeping = traverseContext;
+  var mapResult = mapBookKeeping.mapResult;
+  var mappedChild =
+    mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i);
+  // We found a component instance
+  ("production" !== "development" ? invariant(
+    !mapResult.hasOwnProperty(name),
+    'ReactChildren.map(...): Encountered two children with the same key, ' +
+    '`%s`. Children keys must be unique.',
+    name
+  ) : invariant(!mapResult.hasOwnProperty(name)));
+  mapResult[name] = mappedChild;
+}
+
+/**
+ * Maps children that are typically specified as `props.children`.
+ *
+ * The provided mapFunction(child, key, index) will be called for each
+ * leaf child.
+ *
+ * TODO: This may likely break any calls to `ReactChildren.map` that were
+ * previously relying on the fact that we guarded against null children.
+ *
+ * @param {?*} children Children tree container.
+ * @param {function(*, int)} mapFunction.
+ * @param {*} mapContext Context for mapFunction.
+ * @return {object} Object containing the ordered map of results.
+ */
+function mapChildren(children, func, context) {
+  if (children == null) {
+    return children;
+  }
+
+  var mapResult = {};
+  var traverseContext = MapBookKeeping.getPooled(mapResult, func, context);
+  traverseAllChildren(children, mapSingleChildIntoContext, traverseContext);
+  MapBookKeeping.release(traverseContext);
+  return mapResult;
+}
+
+var ReactChildren = {
+  forEach: forEachChildren,
+  map: mapChildren
+};
+
+module.exports = ReactChildren;
+
+},{"./PooledClass":23,"./invariant":108,"./traverseAllChildren":128}],26:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactComponent
+ */
+
+"use strict";
+
+var ReactComponentEnvironment = require("./ReactComponentEnvironment");
+var ReactCurrentOwner = require("./ReactCurrentOwner");
+var ReactOwner = require("./ReactOwner");
+var ReactUpdates = require("./ReactUpdates");
+
+var invariant = require("./invariant");
+var keyMirror = require("./keyMirror");
+var merge = require("./merge");
+
+/**
+ * Every React component is in one of these life cycles.
+ */
+var ComponentLifeCycle = keyMirror({
+  /**
+   * Mounted components have a DOM node representation and are capable of
+   * receiving new props.
+   */
+  MOUNTED: null,
+  /**
+   * Unmounted components are inactive and cannot receive new props.
+   */
+  UNMOUNTED: null
+});
+
+/**
+ * Warn if there's no key explicitly set on dynamic arrays of children or
+ * object keys are not valid. This allows us to keep track of children between
+ * updates.
+ */
+
+var ownerHasExplicitKeyWarning = {};
+var ownerHasPropertyWarning = {};
+
+var NUMERIC_PROPERTY_REGEX = /^\d+$/;
+
+/**
+ * Warn if the component doesn't have an explicit key assigned to it.
+ * This component is in an array. The array could grow and shrink or be
+ * reordered. All children that haven't already been validated are required to
+ * have a "key" property assigned to it.
+ *
+ * @internal
+ * @param {ReactComponent} component Component that requires a key.
+ */
+function validateExplicitKey(component) {
+  if (component.__keyValidated__ || component.props.key != null) {
+    return;
+  }
+  component.__keyValidated__ = true;
+
+  // We can't provide friendly warnings for top level components.
+  if (!ReactCurrentOwner.current) {
+    return;
+  }
+
+  // Name of the component whose render method tried to pass children.
+  var currentName = ReactCurrentOwner.current.constructor.displayName;
+  if (ownerHasExplicitKeyWarning.hasOwnProperty(currentName)) {
+    return;
+  }
+  ownerHasExplicitKeyWarning[currentName] = true;
+
+  var message = 'Each child in an array should have a unique "key" prop. ' +
+                'Check the render method of ' + currentName + '.';
+  if (!component.isOwnedBy(ReactCurrentOwner.current)) {
+    // Name of the component that originally created this child.
+    var childOwnerName =
+      component._owner &&
+      component._owner.constructor.displayName;
+
+    // Usually the current owner is the offender, but if it accepts
+    // children as a property, it may be the creator of the child that's
+    // responsible for assigning it a key.
+    message += ' It was passed a child from ' + childOwnerName + '.';
+  }
+
+  message += ' See http://fb.me/react-warning-keys for more information.';
+  console.warn(message);
+}
+
+/**
+ * Warn if the key is being defined as an object property but has an incorrect
+ * value.
+ *
+ * @internal
+ * @param {string} name Property name of the key.
+ * @param {ReactComponent} component Component that requires a key.
+ */
+function validatePropertyKey(name) {
+  if (NUMERIC_PROPERTY_REGEX.test(name)) {
+    // Name of the component whose render method tried to pass children.
+    var currentName = ReactCurrentOwner.current.constructor.displayName;
+    if (ownerHasPropertyWarning.hasOwnProperty(currentName)) {
+      return;
+    }
+    ownerHasPropertyWarning[currentName] = true;
+
+    console.warn(
+      'Child objects should have non-numeric keys so ordering is preserved. ' +
+      'Check the render method of ' + currentName + '. ' +
+      'See http://fb.me/react-warning-keys for more information.'
+    );
+  }
+}
+
+/**
+ * Ensure that every component either is passed in a static location, in an
+ * array with an explicit keys property defined, or in an object literal
+ * with valid key property.
+ *
+ * @internal
+ * @param {*} component Statically passed child of any type.
+ * @return {boolean}
+ */
+function validateChildKeys(component) {
+  if (Array.isArray(component)) {
+    for (var i = 0; i < component.length; i++) {
+      var child = component[i];
+      if (ReactComponent.isValidComponent(child)) {
+        validateExplicitKey(child);
+      }
+    }
+  } else if (ReactComponent.isValidComponent(component)) {
+    // This component was passed in a valid location.
+    component.__keyValidated__ = true;
+  } else if (component && typeof component === 'object') {
+    for (var name in component) {
+      validatePropertyKey(name, component);
+    }
+  }
+}
+
+/**
+ * Components are the basic units of composition in React.
+ *
+ * Every component accepts a set of keyed input parameters known as "props" that
+ * are initialized by the constructor. Once a component is mounted, the props
+ * can be mutated using `setProps` or `replaceProps`.
+ *
+ * Every component is capable of the following operations:
+ *
+ *   `mountComponent`
+ *     Initializes the component, renders markup, and registers event listeners.
+ *
+ *   `receiveComponent`
+ *     Updates the rendered DOM nodes to match the given component.
+ *
+ *   `unmountComponent`
+ *     Releases any resources allocated by this component.
+ *
+ * Components can also be "owned" by other components. Being owned by another
+ * component means being constructed by that component. This is different from
+ * being the child of a component, which means having a DOM representation that
+ * is a child of the DOM representation of that component.
+ *
+ * @class ReactComponent
+ */
+var ReactComponent = {
+
+  /**
+   * @param {?object} object
+   * @return {boolean} True if `object` is a valid component.
+   * @final
+   */
+  isValidComponent: function(object) {
+    if (!object || !object.type || !object.type.prototype) {
+      return false;
+    }
+    // This is the safer way of duck checking the type of instance this is.
+    // The object can be a generic descriptor but the type property refers to
+    // the constructor and it's prototype can be used to inspect the type that
+    // will actually get mounted.
+    var prototype = object.type.prototype;
+    return (
+      typeof prototype.mountComponentIntoNode === 'function' &&
+      typeof prototype.receiveComponent === 'function'
+    );
+  },
+
+  /**
+   * @internal
+   */
+  LifeCycle: ComponentLifeCycle,
+
+  /**
+   * Injected module that provides ability to mutate individual properties.
+   * Injected into the base class because many different subclasses need access
+   * to this.
+   *
+   * @internal
+   */
+  BackendIDOperations: ReactComponentEnvironment.BackendIDOperations,
+
+  /**
+   * Optionally injectable environment dependent cleanup hook. (server vs.
+   * browser etc). Example: A browser system caches DOM nodes based on component
+   * ID and must remove that cache entry when this instance is unmounted.
+   *
+   * @private
+   */
+  unmountIDFromEnvironment: ReactComponentEnvironment.unmountIDFromEnvironment,
+
+  /**
+   * The "image" of a component tree, is the platform specific (typically
+   * serialized) data that represents a tree of lower level UI building blocks.
+   * On the web, this "image" is HTML markup which describes a construction of
+   * low level `div` and `span` nodes. Other platforms may have different
+   * encoding of this "image". This must be injected.
+   *
+   * @private
+   */
+  mountImageIntoNode: ReactComponentEnvironment.mountImageIntoNode,
+
+  /**
+   * React references `ReactReconcileTransaction` using this property in order
+   * to allow dependency injection.
+   *
+   * @internal
+   */
+  ReactReconcileTransaction:
+    ReactComponentEnvironment.ReactReconcileTransaction,
+
+  /**
+   * Base functionality for every ReactComponent constructor. Mixed into the
+   * `ReactComponent` prototype, but exposed statically for easy access.
+   *
+   * @lends {ReactComponent.prototype}
+   */
+  Mixin: merge(ReactComponentEnvironment.Mixin, {
+
+    /**
+     * Checks whether or not this component is mounted.
+     *
+     * @return {boolean} True if mounted, false otherwise.
+     * @final
+     * @protected
+     */
+    isMounted: function() {
+      return this._lifeCycleState === ComponentLifeCycle.MOUNTED;
+    },
+
+    /**
+     * Sets a subset of the props.
+     *
+     * @param {object} partialProps Subset of the next props.
+     * @param {?function} callback Called after props are updated.
+     * @final
+     * @public
+     */
+    setProps: function(partialProps, callback) {
+      // Merge with `_pendingProps` if it exists, otherwise with existing props.
+      this.replaceProps(
+        merge(this._pendingProps || this.props, partialProps),
+        callback
+      );
+    },
+
+    /**
+     * Replaces all of the props.
+     *
+     * @param {object} props New props.
+     * @param {?function} callback Called after props are updated.
+     * @final
+     * @public
+     */
+    replaceProps: function(props, callback) {
+      ("production" !== "development" ? invariant(
+        this.isMounted(),
+        'replaceProps(...): Can only update a mounted component.'
+      ) : invariant(this.isMounted()));
+      ("production" !== "development" ? invariant(
+        this._mountDepth === 0,
+        'replaceProps(...): You called `setProps` or `replaceProps` on a ' +
+        'component with a parent. This is an anti-pattern since props will ' +
+        'get reactively updated when rendered. Instead, change the owner\'s ' +
+        '`render` method to pass the correct value as props to the component ' +
+        'where it is created.'
+      ) : invariant(this._mountDepth === 0));
+      this._pendingProps = props;
+      ReactUpdates.enqueueUpdate(this, callback);
+    },
+
+    /**
+     * Base constructor for all React components.
+     *
+     * Subclasses that override this method should make sure to invoke
+     * `ReactComponent.Mixin.construct.call(this, ...)`.
+     *
+     * @param {?object} initialProps
+     * @param {*} children
+     * @internal
+     */
+    construct: function(initialProps, children) {
+      this.props = initialProps || {};
+      // Record the component responsible for creating this component.
+      this._owner = ReactCurrentOwner.current;
+      // All components start unmounted.
+      this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
+
+      this._pendingProps = null;
+      this._pendingCallbacks = null;
+
+      // Unlike _pendingProps and _pendingCallbacks, we won't use null to
+      // indicate that nothing is pending because it's possible for a component
+      // to have a null owner. Instead, an owner change is pending when
+      // this._owner !== this._pendingOwner.
+      this._pendingOwner = this._owner;
+
+      // Children can be more than one argument
+      var childrenLength = arguments.length - 1;
+      if (childrenLength === 1) {
+        if ("production" !== "development") {
+          validateChildKeys(children);
+        }
+        this.props.children = children;
+      } else if (childrenLength > 1) {
+        var childArray = Array(childrenLength);
+        for (var i = 0; i < childrenLength; i++) {
+          if ("production" !== "development") {
+            validateChildKeys(arguments[i + 1]);
+          }
+          childArray[i] = arguments[i + 1];
+        }
+        this.props.children = childArray;
+      }
+    },
+
+    /**
+     * Initializes the component, renders markup, and registers event listeners.
+     *
+     * NOTE: This does not insert any nodes into the DOM.
+     *
+     * Subclasses that override this method should make sure to invoke
+     * `ReactComponent.Mixin.mountComponent.call(this, ...)`.
+     *
+     * @param {string} rootID DOM ID of the root node.
+     * @param {ReactReconcileTransaction} transaction
+     * @param {number} mountDepth number of components in the owner hierarchy.
+     * @return {?string} Rendered markup to be inserted into the DOM.
+     * @internal
+     */
+    mountComponent: function(rootID, transaction, mountDepth) {
+      ("production" !== "development" ? invariant(
+        !this.isMounted(),
+        'mountComponent(%s, ...): Can only mount an unmounted component. ' +
+        'Make sure to avoid storing components between renders or reusing a ' +
+        'single component instance in multiple places.',
+        rootID
+      ) : invariant(!this.isMounted()));
+      var props = this.props;
+      if (props.ref != null) {
+        ReactOwner.addComponentAsRefTo(this, props.ref, this._owner);
+      }
+      this._rootNodeID = rootID;
+      this._lifeCycleState = ComponentLifeCycle.MOUNTED;
+      this._mountDepth = mountDepth;
+      // Effectively: return '';
+    },
+
+    /**
+     * Releases any resources allocated by `mountComponent`.
+     *
+     * NOTE: This does not remove any nodes from the DOM.
+     *
+     * Subclasses that override this method should make sure to invoke
+     * `ReactComponent.Mixin.unmountComponent.call(this)`.
+     *
+     * @internal
+     */
+    unmountComponent: function() {
+      ("production" !== "development" ? invariant(
+        this.isMounted(),
+        'unmountComponent(): Can only unmount a mounted component.'
+      ) : invariant(this.isMounted()));
+      var props = this.props;
+      if (props.ref != null) {
+        ReactOwner.removeComponentAsRefFrom(this, props.ref, this._owner);
+      }
+      ReactComponent.unmountIDFromEnvironment(this._rootNodeID);
+      this._rootNodeID = null;
+      this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
+    },
+
+    /**
+     * Given a new instance of this component, updates the rendered DOM nodes
+     * as if that instance was rendered instead.
+     *
+     * Subclasses that override this method should make sure to invoke
+     * `ReactComponent.Mixin.receiveComponent.call(this, ...)`.
+     *
+     * @param {object} nextComponent Next set of properties.
+     * @param {ReactReconcileTransaction} transaction
+     * @internal
+     */
+    receiveComponent: function(nextComponent, transaction) {
+      ("production" !== "development" ? invariant(
+        this.isMounted(),
+        'receiveComponent(...): Can only update a mounted component.'
+      ) : invariant(this.isMounted()));
+      this._pendingOwner = nextComponent._owner;
+      this._pendingProps = nextComponent.props;
+      this._performUpdateIfNecessary(transaction);
+    },
+
+    /**
+     * Call `_performUpdateIfNecessary` within a new transaction.
+     *
+     * @param {ReactReconcileTransaction} transaction
+     * @internal
+     */
+    performUpdateIfNecessary: function() {
+      var transaction = ReactComponent.ReactReconcileTransaction.getPooled();
+      transaction.perform(this._performUpdateIfNecessary, this, transaction);
+      ReactComponent.ReactReconcileTransaction.release(transaction);
+    },
+
+    /**
+     * If `_pendingProps` is set, update the component.
+     *
+     * @param {ReactReconcileTransaction} transaction
+     * @internal
+     */
+    _performUpdateIfNecessary: function(transaction) {
+      if (this._pendingProps == null) {
+        return;
+      }
+      var prevProps = this.props;
+      var prevOwner = this._owner;
+      this.props = this._pendingProps;
+      this._owner = this._pendingOwner;
+      this._pendingProps = null;
+      this.updateComponent(transaction, prevProps, prevOwner);
+    },
+
+    /**
+     * Updates the component's currently mounted representation.
+     *
+     * @param {ReactReconcileTransaction} transaction
+     * @param {object} prevProps
+     * @internal
+     */
+    updateComponent: function(transaction, prevProps, prevOwner) {
+      var props = this.props;
+      // If either the owner or a `ref` has changed, make sure the newest owner
+      // has stored a reference to `this`, and the previous owner (if different)
+      // has forgotten the reference to `this`.
+      if (this._owner !== prevOwner || props.ref !== prevProps.ref) {
+        if (prevProps.ref != null) {
+          ReactOwner.removeComponentAsRefFrom(
+            this, prevProps.ref, prevOwner
+          );
+        }
+        // Correct, even if the owner is the same, and only the ref has changed.
+        if (props.ref != null) {
+          ReactOwner.addComponentAsRefTo(this, props.ref, this._owner);
+        }
+      }
+    },
+
+    /**
+     * Mounts this component and inserts it into the DOM.
+     *
+     * @param {string} rootID DOM ID of the root node.
+     * @param {DOMElement} container DOM element to mount into.
+     * @param {boolean} shouldReuseMarkup If true, do not insert markup
+     * @final
+     * @internal
+     * @see {ReactMount.renderComponent}
+     */
+    mountComponentIntoNode: function(rootID, container, shouldReuseMarkup) {
+      var transaction = ReactComponent.ReactReconcileTransaction.getPooled();
+      transaction.perform(
+        this._mountComponentIntoNode,
+        this,
+        rootID,
+        container,
+        transaction,
+        shouldReuseMarkup
+      );
+      ReactComponent.ReactReconcileTransaction.release(transaction);
+    },
+
+    /**
+     * @param {string} rootID DOM ID of the root node.
+     * @param {DOMElement} container DOM element to mount into.
+     * @param {ReactReconcileTransaction} transaction
+     * @param {boolean} shouldReuseMarkup If true, do not insert markup
+     * @final
+     * @private
+     */
+    _mountComponentIntoNode: function(
+        rootID,
+        container,
+        transaction,
+        shouldReuseMarkup) {
+      var markup = this.mountComponent(rootID, transaction, 0);
+      ReactComponent.mountImageIntoNode(markup, container, shouldReuseMarkup);
+    },
+
+    /**
+     * Checks if this component is owned by the supplied `owner` component.
+     *
+     * @param {ReactComponent} owner Component to check.
+     * @return {boolean} True if `owners` owns this component.
+     * @final
+     * @internal
+     */
+    isOwnedBy: function(owner) {
+      return this._owner === owner;
+    },
+
+    /**
+     * Gets another component, that shares the same owner as this one, by ref.
+     *
+     * @param {string} ref of a sibling Component.
+     * @return {?ReactComponent} the actual sibling Component.
+     * @final
+     * @internal
+     */
+    getSiblingByRef: function(ref) {
+      var owner = this._owner;
+      if (!owner || !owner.refs) {
+        return null;
+      }
+      return owner.refs[ref];
+    }
+  })
+};
+
+module.exports = ReactComponent;
+
+},{"./ReactComponentEnvironment":28,"./ReactCurrentOwner":31,"./ReactOwner":59,"./ReactUpdates":70,"./invariant":108,"./keyMirror":114,"./merge":117}],27:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactComponentBrowserEnvironment
+ */
+
+/*jslint evil: true */
+
+"use strict";
+
+var ReactDOMIDOperations = require("./ReactDOMIDOperations");
+var ReactMarkupChecksum = require("./ReactMarkupChecksum");
+var ReactMount = require("./ReactMount");
+var ReactPerf = require("./ReactPerf");
+var ReactReconcileTransaction = require("./ReactReconcileTransaction");
+
+var getReactRootElementInContainer = require("./getReactRootElementInContainer");
+var invariant = require("./invariant");
+
+
+var ELEMENT_NODE_TYPE = 1;
+var DOC_NODE_TYPE = 9;
+
+
+/**
+ * Abstracts away all functionality of `ReactComponent` requires knowledge of
+ * the browser context.
+ */
+var ReactComponentBrowserEnvironment = {
+  /**
+   * Mixed into every component instance.
+   */
+  Mixin: {
+    /**
+     * Returns the DOM node rendered by this component.
+     *
+     * @return {DOMElement} The root node of this component.
+     * @final
+     * @protected
+     */
+    getDOMNode: function() {
+      ("production" !== "development" ? invariant(
+        this.isMounted(),
+        'getDOMNode(): A component must be mounted to have a DOM node.'
+      ) : invariant(this.isMounted()));
+      return ReactMount.getNode(this._rootNodeID);
+    }
+  },
+
+  ReactReconcileTransaction: ReactReconcileTransaction,
+
+  BackendIDOperations: ReactDOMIDOperations,
+
+  /**
+   * If a particular environment requires that some resources be cleaned up,
+   * specify this in the injected Mixin. In the DOM, we would likely want to
+   * purge any cached node ID lookups.
+   *
+   * @private
+   */
+  unmountIDFromEnvironment: function(rootNodeID) {
+    ReactMount.purgeID(rootNodeID);
+  },
+
+  /**
+   * @param {string} markup Markup string to place into the DOM Element.
+   * @param {DOMElement} container DOM Element to insert markup into.
+   * @param {boolean} shouldReuseMarkup Should reuse the existing markup in the
+   * container if possible.
+   */
+  mountImageIntoNode: ReactPerf.measure(
+    'ReactComponentBrowserEnvironment',
+    'mountImageIntoNode',
+    function(markup, container, shouldReuseMarkup) {
+      ("production" !== "development" ? invariant(
+        container && (
+          container.nodeType === ELEMENT_NODE_TYPE ||
+            container.nodeType === DOC_NODE_TYPE
+        ),
+        'mountComponentIntoNode(...): Target container is not valid.'
+      ) : invariant(container && (
+        container.nodeType === ELEMENT_NODE_TYPE ||
+          container.nodeType === DOC_NODE_TYPE
+      )));
+
+      if (shouldReuseMarkup) {
+        if (ReactMarkupChecksum.canReuseMarkup(
+          markup,
+          getReactRootElementInContainer(container))) {
+          return;
+        } else {
+          ("production" !== "development" ? invariant(
+            container.nodeType !== DOC_NODE_TYPE,
+            'You\'re trying to render a component to the document using ' +
+            'server rendering but the checksum was invalid. This usually ' +
+            'means you rendered a different component type or props on ' +
+            'the client from the one on the server, or your render() ' +
+            'methods are impure. React cannot handle this case due to ' +
+            'cross-browser quirks by rendering at the document root. You ' +
+            'should look for environment dependent code in your components ' +
+            'and ensure the props are the same client and server side.'
+          ) : invariant(container.nodeType !== DOC_NODE_TYPE));
+
+          if ("production" !== "development") {
+            console.warn(
+              'React attempted to use reuse markup in a container but the ' +
+              'checksum was invalid. This generally means that you are ' +
+              'using server rendering and the markup generated on the ' +
+              'server was not what the client was expecting. React injected' +
+              'new markup to compensate which works but you have lost many ' +
+              'of the benefits of server rendering. Instead, figure out ' +
+              'why the markup being generated is different on the client ' +
+              'or server.'
+            );
+          }
+        }
+      }
+
+      ("production" !== "development" ? invariant(
+        container.nodeType !== DOC_NODE_TYPE,
+        'You\'re trying to render a component to the document but ' +
+          'you didn\'t use server rendering. We can\'t do this ' +
+          'without using server rendering due to cross-browser quirks. ' +
+          'See renderComponentToString() for server rendering.'
+      ) : invariant(container.nodeType !== DOC_NODE_TYPE));
+
+      // Asynchronously inject markup by ensuring that the container is not in
+      // the document when settings its `innerHTML`.
+      var parent = container.parentNode;
+      if (parent) {
+        var next = container.nextSibling;
+        parent.removeChild(container);
+        container.innerHTML = markup;
+        if (next) {
+          parent.insertBefore(container, next);
+        } else {
+          parent.appendChild(container);
+        }
+      } else {
+        container.innerHTML = markup;
+      }
+    }
+  )
+};
+
+module.exports = ReactComponentBrowserEnvironment;
+
+},{"./ReactDOMIDOperations":36,"./ReactMarkupChecksum":54,"./ReactMount":55,"./ReactPerf":60,"./ReactReconcileTransaction":66,"./getReactRootElementInContainer":104,"./invariant":108}],28:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactComponentEnvironment
+ */
+
+"use strict";
+
+var ReactComponentBrowserEnvironment =
+  require("./ReactComponentBrowserEnvironment");
+
+var ReactComponentEnvironment = ReactComponentBrowserEnvironment;
+
+module.exports = ReactComponentEnvironment;
+
+},{"./ReactComponentBrowserEnvironment":27}],29:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactCompositeComponent
+ */
+
+"use strict";
+
+var ReactComponent = require("./ReactComponent");
+var ReactContext = require("./ReactContext");
+var ReactCurrentOwner = require("./ReactCurrentOwner");
+var ReactErrorUtils = require("./ReactErrorUtils");
+var ReactOwner = require("./ReactOwner");
+var ReactPerf = require("./ReactPerf");
+var ReactPropTransferer = require("./ReactPropTransferer");
+var ReactPropTypeLocations = require("./ReactPropTypeLocations");
+var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames");
+var ReactUpdates = require("./ReactUpdates");
+
+var invariant = require("./invariant");
+var keyMirror = require("./keyMirror");
+var merge = require("./merge");
+var mixInto = require("./mixInto");
+var objMap = require("./objMap");
+var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
+
+/**
+ * Policies that describe methods in `ReactCompositeComponentInterface`.
+ */
+var SpecPolicy = keyMirror({
+  /**
+   * These methods may be defined only once by the class specification or mixin.
+   */
+  DEFINE_ONCE: null,
+  /**
+   * These methods may be defined by both the class specification and mixins.
+   * Subsequent definitions will be chained. These methods must return void.
+   */
+  DEFINE_MANY: null,
+  /**
+   * These methods are overriding the base ReactCompositeComponent class.
+   */
+  OVERRIDE_BASE: null,
+  /**
+   * These methods are similar to DEFINE_MANY, except we assume they return
+   * objects. We try to merge the keys of the return values of all the mixed in
+   * functions. If there is a key conflict we throw.
+   */
+  DEFINE_MANY_MERGED: null
+});
+
+/**
+ * Composite components are higher-level components that compose other composite
+ * or native components.
+ *
+ * To create a new type of `ReactCompositeComponent`, pass a specification of
+ * your new class to `React.createClass`. The only requirement of your class
+ * specification is that you implement a `render` method.
+ *
+ *   var MyComponent = React.createClass({
+ *     render: function() {
+ *       return <div>Hello World</div>;
+ *     }
+ *   });
+ *
+ * The class specification supports a specific protocol of methods that have
+ * special meaning (e.g. `render`). See `ReactCompositeComponentInterface` for
+ * more the comprehensive protocol. Any other properties and methods in the
+ * class specification will available on the prototype.
+ *
+ * @interface ReactCompositeComponentInterface
+ * @internal
+ */
+var ReactCompositeComponentInterface = {
+
+  /**
+   * An array of Mixin objects to include when defining your component.
+   *
+   * @type {array}
+   * @optional
+   */
+  mixins: SpecPolicy.DEFINE_MANY,
+
+  /**
+   * An object containing properties and methods that should be defined on
+   * the component's constructor instead of its prototype (static methods).
+   *
+   * @type {object}
+   * @optional
+   */
+  statics: SpecPolicy.DEFINE_MANY,
+
+  /**
+   * Definition of prop types for this component.
+   *
+   * @type {object}
+   * @optional
+   */
+  propTypes: SpecPolicy.DEFINE_MANY,
+
+  /**
+   * Definition of context types for this component.
+   *
+   * @type {object}
+   * @optional
+   */
+  contextTypes: SpecPolicy.DEFINE_MANY,
+
+  /**
+   * Definition of context types this component sets for its children.
+   *
+   * @type {object}
+   * @optional
+   */
+  childContextTypes: SpecPolicy.DEFINE_MANY,
+
+  // ==== Definition methods ====
+
+  /**
+   * Invoked when the component is mounted. Values in the mapping will be set on
+   * `this.props` if that prop is not specified (i.e. using an `in` check).
+   *
+   * This method is invoked before `getInitialState` and therefore cannot rely
+   * on `this.state` or use `this.setState`.
+   *
+   * @return {object}
+   * @optional
+   */
+  getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED,
+
+  /**
+   * Invoked once before the component is mounted. The return value will be used
+   * as the initial value of `this.state`.
+   *
+   *   getInitialState: function() {
+   *     return {
+   *       isOn: false,
+   *       fooBaz: new BazFoo()
+   *     }
+   *   }
+   *
+   * @return {object}
+   * @optional
+   */
+  getInitialState: SpecPolicy.DEFINE_MANY_MERGED,
+
+  /**
+   * @return {object}
+   * @optional
+   */
+  getChildContext: SpecPolicy.DEFINE_MANY_MERGED,
+
+  /**
+   * Uses props from `this.props` and state from `this.state` to render the
+   * structure of the component.
+   *
+   * No guarantees are made about when or how often this method is invoked, so
+   * it must not have side effects.
+   *
+   *   render: function() {
+   *     var name = this.props.name;
+   *     return <div>Hello, {name}!</div>;
+   *   }
+   *
+   * @return {ReactComponent}
+   * @nosideeffects
+   * @required
+   */
+  render: SpecPolicy.DEFINE_ONCE,
+
+
+
+  // ==== Delegate methods ====
+
+  /**
+   * Invoked when the component is initially created and about to be mounted.
+   * This may have side effects, but any external subscriptions or data created
+   * by this method must be cleaned up in `componentWillUnmount`.
+   *
+   * @optional
+   */
+  componentWillMount: SpecPolicy.DEFINE_MANY,
+
+  /**
+   * Invoked when the component has been mounted and has a DOM representation.
+   * However, there is no guarantee that the DOM node is in the document.
+   *
+   * Use this as an opportunity to operate on the DOM when the component has
+   * been mounted (initialized and rendered) for the first time.
+   *
+   * @param {DOMElement} rootNode DOM element representing the component.
+   * @optional
+   */
+  componentDidMount: SpecPolicy.DEFINE_MANY,
+
+  /**
+   * Invoked before the component receives new props.
+   *
+   * Use this as an opportunity to react to a prop transition by updating the
+   * state using `this.setState`. Current props are accessed via `this.props`.
+   *
+   *   componentWillReceiveProps: function(nextProps, nextContext) {
+   *     this.setState({
+   *       likesIncreasing: nextProps.likeCount > this.props.likeCount
+   *     });
+   *   }
+   *
+   * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop
+   * transition may cause a state change, but the opposite is not true. If you
+   * need it, you are probably looking for `componentWillUpdate`.
+   *
+   * @param {object} nextProps
+   * @optional
+   */
+  componentWillReceiveProps: SpecPolicy.DEFINE_MANY,
+
+  /**
+   * Invoked while deciding if the component should be updated as a result of
+   * receiving new props, state and/or context.
+   *
+   * Use this as an opportunity to `return false` when you're certain that the
+   * transition to the new props/state/context will not require a component
+   * update.
+   *
+   *   shouldComponentUpdate: function(nextProps, nextState, nextContext) {
+   *     return !equal(nextProps, this.props) ||
+   *       !equal(nextState, this.state) ||
+   *       !equal(nextContext, this.context);
+   *   }
+   *
+   * @param {object} nextProps
+   * @param {?object} nextState
+   * @param {?object} nextContext
+   * @return {boolean} True if the component should update.
+   * @optional
+   */
+  shouldComponentUpdate: SpecPolicy.DEFINE_ONCE,
+
+  /**
+   * Invoked when the component is about to update due to a transition from
+   * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState`
+   * and `nextContext`.
+   *
+   * Use this as an opportunity to perform preparation before an update occurs.
+   *
+   * NOTE: You **cannot** use `this.setState()` in this method.
+   *
+   * @param {object} nextProps
+   * @param {?object} nextState
+   * @param {?object} nextContext
+   * @param {ReactReconcileTransaction} transaction
+   * @optional
+   */
+  componentWillUpdate: SpecPolicy.DEFINE_MANY,
+
+  /**
+   * Invoked when the component's DOM representation has been updated.
+   *
+   * Use this as an opportunity to operate on the DOM when the component has
+   * been updated.
+   *
+   * @param {object} prevProps
+   * @param {?object} prevState
+   * @param {?object} prevContext
+   * @param {DOMElement} rootNode DOM element representing the component.
+   * @optional
+   */
+  componentDidUpdate: SpecPolicy.DEFINE_MANY,
+
+  /**
+   * Invoked when the component is about to be removed from its parent and have
+   * its DOM representation destroyed.
+   *
+   * Use this as an opportunity to deallocate any external resources.
+   *
+   * NOTE: There is no `componentDidUnmount` since your component will have been
+   * destroyed by that point.
+   *
+   * @optional
+   */
+  componentWillUnmount: SpecPolicy.DEFINE_MANY,
+
+
+
+  // ==== Advanced methods ====
+
+  /**
+   * Updates the component's currently mounted DOM representation.
+   *
+   * By default, this implements React's rendering and reconciliation algorithm.
+   * Sophisticated clients may wish to override this.
+   *
+   * @param {ReactReconcileTransaction} transaction
+   * @internal
+   * @overridable
+   */
+  updateComponent: SpecPolicy.OVERRIDE_BASE
+
+};
+
+/**
+ * Mapping from class specification keys to special processing functions.
+ *
+ * Although these are declared like instance properties in the specification
+ * when defining classes using `React.createClass`, they are actually static
+ * and are accessible on the constructor instead of the prototype. Despite
+ * being static, they must be defined outside of the "statics" key under
+ * which all other static methods are defined.
+ */
+var RESERVED_SPEC_KEYS = {
+  displayName: function(ConvenienceConstructor, displayName) {
+    ConvenienceConstructor.componentConstructor.displayName = displayName;
+  },
+  mixins: function(ConvenienceConstructor, mixins) {
+    if (mixins) {
+      for (var i = 0; i < mixins.length; i++) {
+        mixSpecIntoComponent(ConvenienceConstructor, mixins[i]);
+      }
+    }
+  },
+  childContextTypes: function(ConvenienceConstructor, childContextTypes) {
+    var Constructor = ConvenienceConstructor.componentConstructor;
+    validateTypeDef(
+      Constructor,
+      childContextTypes,
+      ReactPropTypeLocations.childContext
+    );
+    Constructor.childContextTypes = merge(
+      Constructor.childContextTypes,
+      childContextTypes
+    );
+  },
+  contextTypes: function(ConvenienceConstructor, contextTypes) {
+    var Constructor = ConvenienceConstructor.componentConstructor;
+    validateTypeDef(
+      Constructor,
+      contextTypes,
+      ReactPropTypeLocations.context
+    );
+    Constructor.contextTypes = merge(Constructor.contextTypes, contextTypes);
+  },
+  propTypes: function(ConvenienceConstructor, propTypes) {
+    var Constructor = ConvenienceConstructor.componentConstructor;
+    validateTypeDef(
+      Constructor,
+      propTypes,
+      ReactPropTypeLocations.prop
+    );
+    Constructor.propTypes = merge(Constructor.propTypes, propTypes);
+  },
+  statics: function(ConvenienceConstructor, statics) {
+    mixStaticSpecIntoComponent(ConvenienceConstructor, statics);
+  }
+};
+
+function validateTypeDef(Constructor, typeDef, location) {
+  for (var propName in typeDef) {
+    if (typeDef.hasOwnProperty(propName)) {
+      ("production" !== "development" ? invariant(
+        typeof typeDef[propName] == 'function',
+        '%s: %s type `%s` is invalid; it must be a function, usually from ' +
+        'React.PropTypes.',
+        Constructor.displayName || 'ReactCompositeComponent',
+        ReactPropTypeLocationNames[location],
+        propName
+      ) : invariant(typeof typeDef[propName] == 'function'));
+    }
+  }
+}
+
+function validateMethodOverride(proto, name) {
+  var specPolicy = ReactCompositeComponentInterface[name];
+
+  // Disallow overriding of base class methods unless explicitly allowed.
+  if (ReactCompositeComponentMixin.hasOwnProperty(name)) {
+    ("production" !== "development" ? invariant(
+      specPolicy === SpecPolicy.OVERRIDE_BASE,
+      'ReactCompositeComponentInterface: You are attempting to override ' +
+      '`%s` from your class specification. Ensure that your method names ' +
+      'do not overlap with React methods.',
+      name
+    ) : invariant(specPolicy === SpecPolicy.OVERRIDE_BASE));
+  }
+
+  // Disallow defining methods more than once unless explicitly allowed.
+  if (proto.hasOwnProperty(name)) {
+    ("production" !== "development" ? invariant(
+      specPolicy === SpecPolicy.DEFINE_MANY ||
+      specPolicy === SpecPolicy.DEFINE_MANY_MERGED,
+      'ReactCompositeComponentInterface: You are attempting to define ' +
+      '`%s` on your component more than once. This conflict may be due ' +
+      'to a mixin.',
+      name
+    ) : invariant(specPolicy === SpecPolicy.DEFINE_MANY ||
+    specPolicy === SpecPolicy.DEFINE_MANY_MERGED));
+  }
+}
+
+function validateLifeCycleOnReplaceState(instance) {
+  var compositeLifeCycleState = instance._compositeLifeCycleState;
+  ("production" !== "development" ? invariant(
+    instance.isMounted() ||
+      compositeLifeCycleState === CompositeLifeCycle.MOUNTING,
+    'replaceState(...): Can only update a mounted or mounting component.'
+  ) : invariant(instance.isMounted() ||
+    compositeLifeCycleState === CompositeLifeCycle.MOUNTING));
+  ("production" !== "development" ? invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE,
+    'replaceState(...): Cannot update during an existing state transition ' +
+    '(such as within `render`). This could potentially cause an infinite ' +
+    'loop so it is forbidden.'
+  ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE));
+  ("production" !== "development" ? invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,
+    'replaceState(...): Cannot update while unmounting component. This ' +
+    'usually means you called setState() on an unmounted component.'
+  ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING));
+}
+
+/**
+ * Custom version of `mixInto` which handles policy validation and reserved
+ * specification keys when building `ReactCompositeComponent` classses.
+ */
+function mixSpecIntoComponent(ConvenienceConstructor, spec) {
+  ("production" !== "development" ? invariant(
+    !isValidClass(spec),
+    'ReactCompositeComponent: You\'re attempting to ' +
+    'use a component class as a mixin. Instead, just use a regular object.'
+  ) : invariant(!isValidClass(spec)));
+  ("production" !== "development" ? invariant(
+    !ReactComponent.isValidComponent(spec),
+    'ReactCompositeComponent: You\'re attempting to ' +
+    'use a component as a mixin. Instead, just use a regular object.'
+  ) : invariant(!ReactComponent.isValidComponent(spec)));
+
+  var Constructor = ConvenienceConstructor.componentConstructor;
+  var proto = Constructor.prototype;
+  for (var name in spec) {
+    var property = spec[name];
+    if (!spec.hasOwnProperty(name)) {
+      continue;
+    }
+
+    validateMethodOverride(proto, name);
+
+    if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
+      RESERVED_SPEC_KEYS[name](ConvenienceConstructor, property);
+    } else {
+      // Setup methods on prototype:
+      // The following member methods should not be automatically bound:
+      // 1. Expected ReactCompositeComponent methods (in the "interface").
+      // 2. Overridden methods (that were mixed in).
+      var isCompositeComponentMethod = name in ReactCompositeComponentInterface;
+      var isInherited = name in proto;
+      var markedDontBind = property && property.__reactDontBind;
+      var isFunction = typeof property === 'function';
+      var shouldAutoBind =
+        isFunction &&
+        !isCompositeComponentMethod &&
+        !isInherited &&
+        !markedDontBind;
+
+      if (shouldAutoBind) {
+        if (!proto.__reactAutoBindMap) {
+          proto.__reactAutoBindMap = {};
+        }
+        proto.__reactAutoBindMap[name] = property;
+        proto[name] = property;
+      } else {
+        if (isInherited) {
+          // For methods which are defined more than once, call the existing
+          // methods before calling the new property.
+          if (ReactCompositeComponentInterface[name] ===
+              SpecPolicy.DEFINE_MANY_MERGED) {
+            proto[name] = createMergedResultFunction(proto[name], property);
+          } else {
+            proto[name] = createChainedFunction(proto[name], property);
+          }
+        } else {
+          proto[name] = property;
+        }
+      }
+    }
+  }
+}
+
+function mixStaticSpecIntoComponent(ConvenienceConstructor, statics) {
+  if (!statics) {
+    return;
+  }
+  for (var name in statics) {
+    var property = statics[name];
+    if (!statics.hasOwnProperty(name) || !property) {
+      return;
+    }
+
+    var isInherited = name in ConvenienceConstructor;
+    var result = property;
+    if (isInherited) {
+      var existingProperty = ConvenienceConstructor[name];
+      var existingType = typeof existingProperty;
+      var propertyType = typeof property;
+      ("production" !== "development" ? invariant(
+        existingType === 'function' && propertyType === 'function',
+        'ReactCompositeComponent: You are attempting to define ' +
+        '`%s` on your component more than once, but that is only supported ' +
+        'for functions, which are chained together. This conflict may be ' +
+        'due to a mixin.',
+        name
+      ) : invariant(existingType === 'function' && propertyType === 'function'));
+      result = createChainedFunction(existingProperty, property);
+    }
+    ConvenienceConstructor[name] = result;
+    ConvenienceConstructor.componentConstructor[name] = result;
+  }
+}
+
+/**
+ * Merge two objects, but throw if both contain the same key.
+ *
+ * @param {object} one The first object, which is mutated.
+ * @param {object} two The second object
+ * @return {object} one after it has been mutated to contain everything in two.
+ */
+function mergeObjectsWithNoDuplicateKeys(one, two) {
+  ("production" !== "development" ? invariant(
+    one && two && typeof one === 'object' && typeof two === 'object',
+    'mergeObjectsWithNoDuplicateKeys(): Cannot merge non-objects'
+  ) : invariant(one && two && typeof one === 'object' && typeof two === 'object'));
+
+  objMap(two, function(value, key) {
+    ("production" !== "development" ? invariant(
+      one[key] === undefined,
+      'mergeObjectsWithNoDuplicateKeys(): ' +
+      'Tried to merge two objects with the same key: %s',
+      key
+    ) : invariant(one[key] === undefined));
+    one[key] = value;
+  });
+  return one;
+}
+
+/**
+ * Creates a function that invokes two functions and merges their return values.
+ *
+ * @param {function} one Function to invoke first.
+ * @param {function} two Function to invoke second.
+ * @return {function} Function that invokes the two argument functions.
+ * @private
+ */
+function createMergedResultFunction(one, two) {
+  return function mergedResult() {
+    var a = one.apply(this, arguments);
+    var b = two.apply(this, arguments);
+    if (a == null) {
+      return b;
+    } else if (b == null) {
+      return a;
+    }
+    return mergeObjectsWithNoDuplicateKeys(a, b);
+  };
+}
+
+/**
+ * Creates a function that invokes two functions and ignores their return vales.
+ *
+ * @param {function} one Function to invoke first.
+ * @param {function} two Function to invoke second.
+ * @return {function} Function that invokes the two argument functions.
+ * @private
+ */
+function createChainedFunction(one, two) {
+  return function chainedFunction() {
+    one.apply(this, arguments);
+    two.apply(this, arguments);
+  };
+}
+
+if ("production" !== "development") {
+
+  var unmountedPropertyWhitelist = {
+    constructor: true,
+    construct: true,
+    isOwnedBy: true, // should be deprecated but can have code mod (internal)
+    mountComponent: true,
+    mountComponentIntoNode: true,
+    props: true,
+    type: true,
+    _checkPropTypes: true,
+    _mountComponentIntoNode: true,
+    _processContext: true
+  };
+
+  var hasWarnedOnComponentType = {};
+
+  var warnIfUnmounted = function(instance, key) {
+    if (instance.__hasBeenMounted) {
+      return;
+    }
+    var name = instance.constructor.displayName || 'Unknown';
+    var owner = ReactCurrentOwner.current;
+    var ownerName = (owner && owner.constructor.displayName) || 'Unknown';
+    var warningKey = key + '|' + name + '|' + ownerName;
+    if (hasWarnedOnComponentType.hasOwnProperty(warningKey)) {
+      // We have already warned for this combination. Skip it this time.
+      return;
+    }
+    hasWarnedOnComponentType[warningKey] = true;
+
+    var context = owner ? ' in ' + ownerName + '.' : ' at the top level.';
+    var staticMethodExample = '<' + name + ' />.type.' + key + '(...)';
+
+    console.warn(
+      'Invalid access to component property "' + key + '" on ' + name +
+      context + ' See http://fb.me/react-warning-descriptors .' +
+      ' Use a static method instead: ' + staticMethodExample
+    );
+  };
+
+  var defineMembraneProperty = function(membrane, prototype, key) {
+    Object.defineProperty(membrane, key, {
+
+      configurable: false,
+      enumerable: true,
+
+      get: function() {
+        if (this !== membrane) {
+          // When this is accessed through a prototype chain we need to check if
+          // this component was mounted.
+          warnIfUnmounted(this, key);
+        }
+        return prototype[key];
+      },
+
+      set: function(value) {
+        if (this !== membrane) {
+          // When this is accessed through a prototype chain, we first check if
+          // this component was mounted. Then we define a value on "this"
+          // instance, effectively disabling the membrane on that prototype
+          // chain.
+          warnIfUnmounted(this, key);
+          Object.defineProperty(this, key, {
+            enumerable: true,
+            configurable: true,
+            writable: true,
+            value: value
+          });
+        } else {
+          // Otherwise, this should modify the prototype
+          prototype[key] = value;
+        }
+      }
+
+    });
+  };
+
+  /**
+   * Creates a membrane prototype which wraps the original prototype. If any
+   * property is accessed in an unmounted state, a warning is issued.
+   *
+   * @param {object} prototype Original prototype.
+   * @return {object} The membrane prototype.
+   * @private
+   */
+  var createMountWarningMembrane = function(prototype) {
+    try {
+      var membrane = Object.create(prototype);
+      for (var key in prototype) {
+        if (unmountedPropertyWhitelist.hasOwnProperty(key)) {
+          continue;
+        }
+        defineMembraneProperty(membrane, prototype, key);
+      }
+
+      membrane.mountComponent = function() {
+        this.__hasBeenMounted = true;
+        return prototype.mountComponent.apply(this, arguments);
+      };
+
+      return membrane;
+    } catch(x) {
+      // In IE8 define property will fail on non-DOM objects. If anything in
+      // the membrane creation fails, we'll bail out and just use the prototype
+      // without warnings.
+      return prototype;
+    }
+  };
+
+}
+
+/**
+ * `ReactCompositeComponent` maintains an auxiliary life cycle state in
+ * `this._compositeLifeCycleState` (which can be null).
+ *
+ * This is different from the life cycle state maintained by `ReactComponent` in
+ * `this._lifeCycleState`. The following diagram shows how the states overlap in
+ * time. There are times when the CompositeLifeCycle is null - at those times it
+ * is only meaningful to look at ComponentLifeCycle alone.
+ *
+ * Top Row: ReactComponent.ComponentLifeCycle
+ * Low Row: ReactComponent.CompositeLifeCycle
+ *
+ * +-------+------------------------------------------------------+--------+
+ * |  UN   |                    MOUNTED                           |   UN   |
+ * |MOUNTED|                                                      | MOUNTED|
+ * +-------+------------------------------------------------------+--------+
+ * |       ^--------+   +------+   +------+   +------+   +--------^        |
+ * |       |        |   |      |   |      |   |      |   |        |        |
+ * |    0--|MOUNTING|-0-|RECEIV|-0-|RECEIV|-0-|RECEIV|-0-|   UN   |--->0   |
+ * |       |        |   |PROPS |   | PROPS|   | STATE|   |MOUNTING|        |
+ * |       |        |   |      |   |      |   |      |   |        |        |
+ * |       |        |   |      |   |      |   |      |   |        |        |
+ * |       +--------+   +------+   +------+   +------+   +--------+        |
+ * |       |                                                      |        |
+ * +-------+------------------------------------------------------+--------+
+ */
+var CompositeLifeCycle = keyMirror({
+  /**
+   * Components in the process of being mounted respond to state changes
+   * differently.
+   */
+  MOUNTING: null,
+  /**
+   * Components in the process of being unmounted are guarded against state
+   * changes.
+   */
+  UNMOUNTING: null,
+  /**
+   * Components that are mounted and receiving new props respond to state
+   * changes differently.
+   */
+  RECEIVING_PROPS: null,
+  /**
+   * Components that are mounted and receiving new state are guarded against
+   * additional state changes.
+   */
+  RECEIVING_STATE: null
+});
+
+/**
+ * @lends {ReactCompositeComponent.prototype}
+ */
+var ReactCompositeComponentMixin = {
+
+  /**
+   * Base constructor for all composite component.
+   *
+   * @param {?object} initialProps
+   * @param {*} children
+   * @final
+   * @internal
+   */
+  construct: function(initialProps, children) {
+    // Children can be either an array or more than one argument
+    ReactComponent.Mixin.construct.apply(this, arguments);
+
+    this.state = null;
+    this._pendingState = null;
+
+    this.context = this._processContext(ReactContext.current);
+    this._currentContext = ReactContext.current;
+    this._pendingContext = null;
+
+    this._compositeLifeCycleState = null;
+  },
+
+  /**
+   * Checks whether or not this composite component is mounted.
+   * @return {boolean} True if mounted, false otherwise.
+   * @protected
+   * @final
+   */
+  isMounted: function() {
+    return ReactComponent.Mixin.isMounted.call(this) &&
+      this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING;
+  },
+
+  /**
+   * Initializes the component, renders markup, and registers event listeners.
+   *
+   * @param {string} rootID DOM ID of the root node.
+   * @param {ReactReconcileTransaction} transaction
+   * @param {number} mountDepth number of components in the owner hierarchy
+   * @return {?string} Rendered markup to be inserted into the DOM.
+   * @final
+   * @internal
+   */
+  mountComponent: ReactPerf.measure(
+    'ReactCompositeComponent',
+    'mountComponent',
+    function(rootID, transaction, mountDepth) {
+      ReactComponent.Mixin.mountComponent.call(
+        this,
+        rootID,
+        transaction,
+        mountDepth
+      );
+      this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING;
+
+      this._defaultProps = this.getDefaultProps ? this.getDefaultProps() : null;
+      this.props = this._processProps(this.props);
+
+      if (this.__reactAutoBindMap) {
+        this._bindAutoBindMethods();
+      }
+
+      this.state = this.getInitialState ? this.getInitialState() : null;
+      ("production" !== "development" ? invariant(
+        typeof this.state === 'object' && !Array.isArray(this.state),
+        '%s.getInitialState(): must return an object or null',
+        this.constructor.displayName || 'ReactCompositeComponent'
+      ) : invariant(typeof this.state === 'object' && !Array.isArray(this.state)));
+
+      this._pendingState = null;
+      this._pendingForceUpdate = false;
+
+      if (this.componentWillMount) {
+        this.componentWillMount();
+        // When mounting, calls to `setState` by `componentWillMount` will set
+        // `this._pendingState` without triggering a re-render.
+        if (this._pendingState) {
+          this.state = this._pendingState;
+          this._pendingState = null;
+        }
+      }
+
+      this._renderedComponent = this._renderValidatedComponent();
+
+      // Done with mounting, `setState` will now trigger UI changes.
+      this._compositeLifeCycleState = null;
+      var markup = this._renderedComponent.mountComponent(
+        rootID,
+        transaction,
+        mountDepth + 1
+      );
+      if (this.componentDidMount) {
+        transaction.getReactMountReady().enqueue(this, this.componentDidMount);
+      }
+      return markup;
+    }
+  ),
+
+  /**
+   * Releases any resources allocated by `mountComponent`.
+   *
+   * @final
+   * @internal
+   */
+  unmountComponent: function() {
+    this._compositeLifeCycleState = CompositeLifeCycle.UNMOUNTING;
+    if (this.componentWillUnmount) {
+      this.componentWillUnmount();
+    }
+    this._compositeLifeCycleState = null;
+
+    this._defaultProps = null;
+
+    this._renderedComponent.unmountComponent();
+    this._renderedComponent = null;
+
+    ReactComponent.Mixin.unmountComponent.call(this);
+
+    if (this.refs) {
+      this.refs = null;
+    }
+
+    // Some existing components rely on this.props even after they've been
+    // destroyed (in event handlers).
+    // TODO: this.props = null;
+    // TODO: this.state = null;
+  },
+
+  /**
+   * Sets a subset of the state. Always use this or `replaceState` to mutate
+   * state. You should treat `this.state` as immutable.
+   *
+   * There is no guarantee that `this.state` will be immediately updated, so
+   * accessing `this.state` after calling this method may return the old value.
+   *
+   * There is no guarantee that calls to `setState` will run synchronously,
+   * as they may eventually be batched together.  You can provide an optional
+   * callback that will be executed when the call to setState is actually
+   * completed.
+   *
+   * @param {object} partialState Next partial state to be merged with state.
+   * @param {?function} callback Called after state is updated.
+   * @final
+   * @protected
+   */
+  setState: function(partialState, callback) {
+    ("production" !== "development" ? invariant(
+      typeof partialState === 'object' || partialState == null,
+      'setState(...): takes an object of state variables to update.'
+    ) : invariant(typeof partialState === 'object' || partialState == null));
+    if ("production" !== "development") {
+      if (partialState == null) {
+        console.warn(
+          'setState(...): You passed an undefined or null state object; ' +
+          'instead, use forceUpdate().'
+        );
+      }
+    }
+    // Merge with `_pendingState` if it exists, otherwise with existing state.
+    this.replaceState(
+      merge(this._pendingState || this.state, partialState),
+      callback
+    );
+  },
+
+  /**
+   * Replaces all of the state. Always use this or `setState` to mutate state.
+   * You should treat `this.state` as immutable.
+   *
+   * There is no guarantee that `this.state` will be immediately updated, so
+   * accessing `this.state` after calling this method may return the old value.
+   *
+   * @param {object} completeState Next state.
+   * @param {?function} callback Called after state is updated.
+   * @final
+   * @protected
+   */
+  replaceState: function(completeState, callback) {
+    validateLifeCycleOnReplaceState(this);
+    this._pendingState = completeState;
+    ReactUpdates.enqueueUpdate(this, callback);
+  },
+
+  /**
+   * Filters the context object to only contain keys specified in
+   * `contextTypes`, and asserts that they are valid.
+   *
+   * @param {object} context
+   * @return {?object}
+   * @private
+   */
+  _processContext: function(context) {
+    var maskedContext = null;
+    var contextTypes = this.constructor.contextTypes;
+    if (contextTypes) {
+      maskedContext = {};
+      for (var contextName in contextTypes) {
+        maskedContext[contextName] = context[contextName];
+      }
+      if ("production" !== "development") {
+        this._checkPropTypes(
+          contextTypes,
+          maskedContext,
+          ReactPropTypeLocations.context
+        );
+      }
+    }
+    return maskedContext;
+  },
+
+  /**
+   * @param {object} currentContext
+   * @return {object}
+   * @private
+   */
+  _processChildContext: function(currentContext) {
+    var childContext = this.getChildContext && this.getChildContext();
+    var displayName = this.constructor.displayName || 'ReactCompositeComponent';
+    if (childContext) {
+      ("production" !== "development" ? invariant(
+        typeof this.constructor.childContextTypes === 'object',
+        '%s.getChildContext(): childContextTypes must be defined in order to ' +
+        'use getChildContext().',
+        displayName
+      ) : invariant(typeof this.constructor.childContextTypes === 'object'));
+      if ("production" !== "development") {
+        this._checkPropTypes(
+          this.constructor.childContextTypes,
+          childContext,
+          ReactPropTypeLocations.childContext
+        );
+      }
+      for (var name in childContext) {
+        ("production" !== "development" ? invariant(
+          name in this.constructor.childContextTypes,
+          '%s.getChildContext(): key "%s" is not defined in childContextTypes.',
+          displayName,
+          name
+        ) : invariant(name in this.constructor.childContextTypes));
+      }
+      return merge(currentContext, childContext);
+    }
+    return currentContext;
+  },
+
+  /**
+   * Processes props by setting default values for unspecified props and
+   * asserting that the props are valid. Does not mutate its argument; returns
+   * a new props object with defaults merged in.
+   *
+   * @param {object} newProps
+   * @return {object}
+   * @private
+   */
+  _processProps: function(newProps) {
+    var props = merge(newProps);
+    var defaultProps = this._defaultProps;
+    for (var propName in defaultProps) {
+      if (typeof props[propName] === 'undefined') {
+        props[propName] = defaultProps[propName];
+      }
+    }
+    if ("production" !== "development") {
+      var propTypes = this.constructor.propTypes;
+      if (propTypes) {
+        this._checkPropTypes(propTypes, props, ReactPropTypeLocations.prop);
+      }
+    }
+    return props;
+  },
+
+  /**
+   * Assert that the props are valid
+   *
+   * @param {object} propTypes Map of prop name to a ReactPropType
+   * @param {object} props
+   * @param {string} location e.g. "prop", "context", "child context"
+   * @private
+   */
+  _checkPropTypes: function(propTypes, props, location) {
+    var componentName = this.constructor.displayName;
+    for (var propName in propTypes) {
+      if (propTypes.hasOwnProperty(propName)) {
+        propTypes[propName](props, propName, componentName, location);
+      }
+    }
+  },
+
+  performUpdateIfNecessary: function() {
+    var compositeLifeCycleState = this._compositeLifeCycleState;
+    // Do not trigger a state transition if we are in the middle of mounting or
+    // receiving props because both of those will already be doing this.
+    if (compositeLifeCycleState === CompositeLifeCycle.MOUNTING ||
+        compositeLifeCycleState === CompositeLifeCycle.RECEIVING_PROPS) {
+      return;
+    }
+    ReactComponent.Mixin.performUpdateIfNecessary.call(this);
+  },
+
+  /**
+   * If any of `_pendingProps`, `_pendingState`, or `_pendingForceUpdate` is
+   * set, update the component.
+   *
+   * @param {ReactReconcileTransaction} transaction
+   * @internal
+   */
+  _performUpdateIfNecessary: function(transaction) {
+    if (this._pendingProps == null &&
+        this._pendingState == null &&
+        this._pendingContext == null &&
+        !this._pendingForceUpdate) {
+      return;
+    }
+
+    var nextFullContext = this._pendingContext || this._currentContext;
+    var nextContext = this._processContext(nextFullContext);
+    this._pendingContext = null;
+
+    var nextProps = this.props;
+    if (this._pendingProps != null) {
+      nextProps = this._processProps(this._pendingProps);
+      this._pendingProps = null;
+
+      this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_PROPS;
+      if (this.componentWillReceiveProps) {
+        this.componentWillReceiveProps(nextProps, nextContext);
+      }
+    }
+
+    this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_STATE;
+
+    // Unlike props, state, and context, we specifically don't want to set
+    // _pendingOwner to null here because it's possible for a component to have
+    // a null owner, so we instead make `this._owner === this._pendingOwner`
+    // mean that there's no owner change pending.
+    var nextOwner = this._pendingOwner;
+
+    var nextState = this._pendingState || this.state;
+    this._pendingState = null;
+
+    try {
+      if (this._pendingForceUpdate ||
+          !this.shouldComponentUpdate ||
+          this.shouldComponentUpdate(nextProps, nextState, nextContext)) {
+        this._pendingForceUpdate = false;
+        // Will set `this.props`, `this.state` and `this.context`.
+        this._performComponentUpdate(
+          nextProps,
+          nextOwner,
+          nextState,
+          nextFullContext,
+          nextContext,
+          transaction
+        );
+      } else {
+        // If it's determined that a component should not update, we still want
+        // to set props and state.
+        this.props = nextProps;
+        this._owner = nextOwner;
+        this.state = nextState;
+        this._currentContext = nextFullContext;
+        this.context = nextContext;
+      }
+    } finally {
+      this._compositeLifeCycleState = null;
+    }
+  },
+
+  /**
+   * Merges new props and state, notifies delegate methods of update and
+   * performs update.
+   *
+   * @param {object} nextProps Next object to set as properties.
+   * @param {?ReactComponent} nextOwner Next component to set as owner
+   * @param {?object} nextState Next object to set as state.
+   * @param {?object} nextFullContext Next object to set as _currentContext.
+   * @param {?object} nextContext Next object to set as context.
+   * @param {ReactReconcileTransaction} transaction
+   * @private
+   */
+  _performComponentUpdate: function(
+    nextProps,
+    nextOwner,
+    nextState,
+    nextFullContext,
+    nextContext,
+    transaction
+  ) {
+    var prevProps = this.props;
+    var prevOwner = this._owner;
+    var prevState = this.state;
+    var prevContext = this.context;
+
+    if (this.componentWillUpdate) {
+      this.componentWillUpdate(nextProps, nextState, nextContext);
+    }
+
+    this.props = nextProps;
+    this._owner = nextOwner;
+    this.state = nextState;
+    this._currentContext = nextFullContext;
+    this.context = nextContext;
+
+    this.updateComponent(
+      transaction,
+      prevProps,
+      prevOwner,
+      prevState,
+      prevContext
+    );
+
+    if (this.componentDidUpdate) {
+      transaction.getReactMountReady().enqueue(
+        this,
+        this.componentDidUpdate.bind(this, prevProps, prevState, prevContext)
+      );
+    }
+  },
+
+  receiveComponent: function(nextComponent, transaction) {
+    if (nextComponent === this) {
+      // Since props and context are immutable after the component is
+      // mounted, we can do a cheap identity compare here to determine
+      // if this is a superfluous reconcile.
+      return;
+    }
+
+    this._pendingContext = nextComponent._currentContext;
+    ReactComponent.Mixin.receiveComponent.call(
+      this,
+      nextComponent,
+      transaction
+    );
+  },
+
+  /**
+   * Updates the component's currently mounted DOM representation.
+   *
+   * By default, this implements React's rendering and reconciliation algorithm.
+   * Sophisticated clients may wish to override this.
+   *
+   * @param {ReactReconcileTransaction} transaction
+   * @param {object} prevProps
+   * @param {?ReactComponent} prevOwner
+   * @param {?object} prevState
+   * @param {?object} prevContext
+   * @internal
+   * @overridable
+   */
+  updateComponent: ReactPerf.measure(
+    'ReactCompositeComponent',
+    'updateComponent',
+    function(transaction, prevProps, prevOwner, prevState, prevContext) {
+      ReactComponent.Mixin.updateComponent.call(
+        this,
+        transaction,
+        prevProps,
+        prevOwner
+      );
+      var prevComponent = this._renderedComponent;
+      var nextComponent = this._renderValidatedComponent();
+      if (shouldUpdateReactComponent(prevComponent, nextComponent)) {
+        prevComponent.receiveComponent(nextComponent, transaction);
+      } else {
+        // These two IDs are actually the same! But nothing should rely on that.
+        var thisID = this._rootNodeID;
+        var prevComponentID = prevComponent._rootNodeID;
+        prevComponent.unmountComponent();
+        this._renderedComponent = nextComponent;
+        var nextMarkup = nextComponent.mountComponent(
+          thisID,
+          transaction,
+          this._mountDepth + 1
+        );
+        ReactComponent.BackendIDOperations.dangerouslyReplaceNodeWithMarkupByID(
+          prevComponentID,
+          nextMarkup
+        );
+      }
+    }
+  ),
+
+  /**
+   * Forces an update. This should only be invoked when it is known with
+   * certainty that we are **not** in a DOM transaction.
+   *
+   * You may want to call this when you know that some deeper aspect of the
+   * component's state has changed but `setState` was not called.
+   *
+   * This will not invoke `shouldUpdateComponent`, but it will invoke
+   * `componentWillUpdate` and `componentDidUpdate`.
+   *
+   * @param {?function} callback Called after update is complete.
+   * @final
+   * @protected
+   */
+  forceUpdate: function(callback) {
+    var compositeLifeCycleState = this._compositeLifeCycleState;
+    ("production" !== "development" ? invariant(
+      this.isMounted() ||
+        compositeLifeCycleState === CompositeLifeCycle.MOUNTING,
+      'forceUpdate(...): Can only force an update on mounted or mounting ' +
+        'components.'
+    ) : invariant(this.isMounted() ||
+      compositeLifeCycleState === CompositeLifeCycle.MOUNTING));
+    ("production" !== "development" ? invariant(
+      compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&
+      compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,
+      'forceUpdate(...): Cannot force an update while unmounting component ' +
+      'or during an existing state transition (such as within `render`).'
+    ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&
+    compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING));
+    this._pendingForceUpdate = true;
+    ReactUpdates.enqueueUpdate(this, callback);
+  },
+
+  /**
+   * @private
+   */
+  _renderValidatedComponent: ReactPerf.measure(
+    'ReactCompositeComponent',
+    '_renderValidatedComponent',
+    function() {
+      var renderedComponent;
+      var previousContext = ReactContext.current;
+      ReactContext.current = this._processChildContext(this._currentContext);
+      ReactCurrentOwner.current = this;
+      try {
+        renderedComponent = this.render();
+      } finally {
+        ReactContext.current = previousContext;
+        ReactCurrentOwner.current = null;
+      }
+      ("production" !== "development" ? invariant(
+        ReactComponent.isValidComponent(renderedComponent),
+        '%s.render(): A valid ReactComponent must be returned. You may have ' +
+          'returned null, undefined, an array, or some other invalid object.',
+        this.constructor.displayName || 'ReactCompositeComponent'
+      ) : invariant(ReactComponent.isValidComponent(renderedComponent)));
+      return renderedComponent;
+    }
+  ),
+
+  /**
+   * @private
+   */
+  _bindAutoBindMethods: function() {
+    for (var autoBindKey in this.__reactAutoBindMap) {
+      if (!this.__reactAutoBindMap.hasOwnProperty(autoBindKey)) {
+        continue;
+      }
+      var method = this.__reactAutoBindMap[autoBindKey];
+      this[autoBindKey] = this._bindAutoBindMethod(ReactErrorUtils.guard(
+        method,
+        this.constructor.displayName + '.' + autoBindKey
+      ));
+    }
+  },
+
+  /**
+   * Binds a method to the component.
+   *
+   * @param {function} method Method to be bound.
+   * @private
+   */
+  _bindAutoBindMethod: function(method) {
+    var component = this;
+    var boundMethod = function() {
+      return method.apply(component, arguments);
+    };
+    if ("production" !== "development") {
+      boundMethod.__reactBoundContext = component;
+      boundMethod.__reactBoundMethod = method;
+      boundMethod.__reactBoundArguments = null;
+      var componentName = component.constructor.displayName;
+      var _bind = boundMethod.bind;
+      boundMethod.bind = function(newThis ) {var args=Array.prototype.slice.call(arguments,1);
+        // User is trying to bind() an autobound method; we effectively will
+        // ignore the value of "this" that the user is trying to use, so
+        // let's warn.
+        if (newThis !== component && newThis !== null) {
+          console.warn(
+            'bind(): React component methods may only be bound to the ' +
+            'component instance. See ' + componentName
+          );
+        } else if (!args.length) {
+          console.warn(
+            'bind(): You are binding a component method to the component. ' +
+            'React does this for you automatically in a high-performance ' +
+            'way, so you can safely remove this call. See ' + componentName
+          );
+          return boundMethod;
+        }
+        var reboundMethod = _bind.apply(boundMethod, arguments);
+        reboundMethod.__reactBoundContext = component;
+        reboundMethod.__reactBoundMethod = method;
+        reboundMethod.__reactBoundArguments = args;
+        return reboundMethod;
+      };
+    }
+    return boundMethod;
+  }
+};
+
+var ReactCompositeComponentBase = function() {};
+mixInto(ReactCompositeComponentBase, ReactComponent.Mixin);
+mixInto(ReactCompositeComponentBase, ReactOwner.Mixin);
+mixInto(ReactCompositeComponentBase, ReactPropTransferer.Mixin);
+mixInto(ReactCompositeComponentBase, ReactCompositeComponentMixin);
+
+/**
+ * Checks if a value is a valid component constructor.
+ *
+ * @param {*}
+ * @return {boolean}
+ * @public
+ */
+function isValidClass(componentClass) {
+  return componentClass instanceof Function &&
+         'componentConstructor' in componentClass &&
+         componentClass.componentConstructor instanceof Function;
+}
+/**
+ * Module for creating composite components.
+ *
+ * @class ReactCompositeComponent
+ * @extends ReactComponent
+ * @extends ReactOwner
+ * @extends ReactPropTransferer
+ */
+var ReactCompositeComponent = {
+
+  LifeCycle: CompositeLifeCycle,
+
+  Base: ReactCompositeComponentBase,
+
+  /**
+   * Creates a composite component class given a class specification.
+   *
+   * @param {object} spec Class specification (which must define `render`).
+   * @return {function} Component constructor function.
+   * @public
+   */
+  createClass: function(spec) {
+    var Constructor = function() {};
+    Constructor.prototype = new ReactCompositeComponentBase();
+    Constructor.prototype.constructor = Constructor;
+
+    var ConvenienceConstructor = function(props, children) {
+      var instance = new Constructor();
+      instance.construct.apply(instance, arguments);
+      return instance;
+    };
+    ConvenienceConstructor.componentConstructor = Constructor;
+    Constructor.ConvenienceConstructor = ConvenienceConstructor;
+    ConvenienceConstructor.originalSpec = spec;
+
+    mixSpecIntoComponent(ConvenienceConstructor, spec);
+
+    ("production" !== "development" ? invariant(
+      Constructor.prototype.render,
+      'createClass(...): Class specification must implement a `render` method.'
+    ) : invariant(Constructor.prototype.render));
+
+    if ("production" !== "development") {
+      if (Constructor.prototype.componentShouldUpdate) {
+        console.warn(
+          (spec.displayName || 'A component') + ' has a method called ' +
+          'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
+          'The name is phrased as a question because the function is ' +
+          'expected to return a value.'
+         );
+      }
+    }
+
+    // Expose the convience constructor on the prototype so that it can be
+    // easily accessed on descriptors. E.g. <Foo />.type === Foo.type and for
+    // static methods like <Foo />.type.staticMethod();
+    // This should not be named constructor since this may not be the function
+    // that created the descriptor, and it may not even be a constructor.
+    ConvenienceConstructor.type = Constructor;
+    Constructor.prototype.type = Constructor;
+
+    // Reduce time spent doing lookups by setting these on the prototype.
+    for (var methodName in ReactCompositeComponentInterface) {
+      if (!Constructor.prototype[methodName]) {
+        Constructor.prototype[methodName] = null;
+      }
+    }
+
+    if ("production" !== "development") {
+      Constructor.prototype = createMountWarningMembrane(Constructor.prototype);
+    }
+
+    return ConvenienceConstructor;
+  },
+
+  isValidClass: isValidClass
+};
+
+module.exports = ReactCompositeComponent;
+
+},{"./ReactComponent":26,"./ReactContext":30,"./ReactCurrentOwner":31,"./ReactErrorUtils":47,"./ReactOwner":59,"./ReactPerf":60,"./ReactPropTransferer":61,"./ReactPropTypeLocationNames":62,"./ReactPropTypeLocations":63,"./ReactUpdates":70,"./invariant":108,"./keyMirror":114,"./merge":117,"./mixInto":120,"./objMap":121,"./shouldUpdateReactComponent":126}],30:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactContext
+ */
+
+"use strict";
+
+var merge = require("./merge");
+
+/**
+ * Keeps track of the current context.
+ *
+ * The context is automatically passed down the component ownership hierarchy
+ * and is accessible via `this.context` on ReactCompositeComponents.
+ */
+var ReactContext = {
+
+  /**
+   * @internal
+   * @type {object}
+   */
+  current: {},
+
+  /**
+   * Temporarily extends the current context while executing scopedCallback.
+   *
+   * A typical use case might look like
+   *
+   *  render: function() {
+   *    var children = ReactContext.withContext({foo: 'foo'} () => (
+   *
+   *    ));
+   *    return <div>{children}</div>;
+   *  }
+   *
+   * @param {object} newContext New context to merge into the existing context
+   * @param {function} scopedCallback Callback to run with the new context
+   * @return {ReactComponent|array<ReactComponent>}
+   */
+  withContext: function(newContext, scopedCallback) {
+    var result;
+    var previousContext = ReactContext.current;
+    ReactContext.current = merge(previousContext, newContext);
+    try {
+      result = scopedCallback();
+    } finally {
+      ReactContext.current = previousContext;
+    }
+    return result;
+  }
+
+};
+
+module.exports = ReactContext;
+
+},{"./merge":117}],31:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactCurrentOwner
+ */
+
+"use strict";
+
+/**
+ * Keeps track of the current owner.
+ *
+ * The current owner is the component who should own any components that are
+ * currently being constructed.
+ *
+ * The depth indicate how many composite components are above this render level.
+ */
+var ReactCurrentOwner = {
+
+  /**
+   * @internal
+   * @type {ReactComponent}
+   */
+  current: null
+
+};
+
+module.exports = ReactCurrentOwner;
+
+},{}],32:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactDOM
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var ReactDOMComponent = require("./ReactDOMComponent");
+
+var mergeInto = require("./mergeInto");
+var objMapKeyVal = require("./objMapKeyVal");
+
+/**
+ * Creates a new React class that is idempotent and capable of containing other
+ * React components. It accepts event listeners and DOM properties that are
+ * valid according to `DOMProperty`.
+ *
+ *  - Event listeners: `onClick`, `onMouseDown`, etc.
+ *  - DOM properties: `className`, `name`, `title`, etc.
+ *
+ * The `style` property functions differently from the DOM API. It accepts an
+ * object mapping of style properties to values.
+ *
+ * @param {string} tag Tag name (e.g. `div`).
+ * @param {boolean} omitClose True if the close tag should be omitted.
+ * @private
+ */
+function createDOMComponentClass(tag, omitClose) {
+  var Constructor = function() {};
+  Constructor.prototype = new ReactDOMComponent(tag, omitClose);
+  Constructor.prototype.constructor = Constructor;
+  Constructor.displayName = tag;
+
+  var ConvenienceConstructor = function(props, children) {
+    var instance = new Constructor();
+    instance.construct.apply(instance, arguments);
+    return instance;
+  };
+
+  // Expose the constructor on the ConvenienceConstructor and prototype so that
+  // it can be easily easily accessed on descriptors.
+  // E.g. <div />.type === div.type
+  ConvenienceConstructor.type = Constructor;
+  Constructor.prototype.type = Constructor;
+
+  Constructor.ConvenienceConstructor = ConvenienceConstructor;
+  ConvenienceConstructor.componentConstructor = Constructor;
+  return ConvenienceConstructor;
+}
+
+/**
+ * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes.
+ * This is also accessible via `React.DOM`.
+ *
+ * @public
+ */
+var ReactDOM = objMapKeyVal({
+  a: false,
+  abbr: false,
+  address: false,
+  area: false,
+  article: false,
+  aside: false,
+  audio: false,
+  b: false,
+  base: false,
+  bdi: false,
+  bdo: false,
+  big: false,
+  blockquote: false,
+  body: false,
+  br: true,
+  button: false,
+  canvas: false,
+  caption: false,
+  cite: false,
+  code: false,
+  col: true,
+  colgroup: false,
+  data: false,
+  datalist: false,
+  dd: false,
+  del: false,
+  details: false,
+  dfn: false,
+  div: false,
+  dl: false,
+  dt: false,
+  em: false,
+  embed: true,
+  fieldset: false,
+  figcaption: false,
+  figure: false,
+  footer: false,
+  form: false, // NOTE: Injected, see `ReactDOMForm`.
+  h1: false,
+  h2: false,
+  h3: false,
+  h4: false,
+  h5: false,
+  h6: false,
+  head: false,
+  header: false,
+  hr: true,
+  html: false,
+  i: false,
+  iframe: false,
+  img: true,
+  input: true,
+  ins: false,
+  kbd: false,
+  keygen: true,
+  label: false,
+  legend: false,
+  li: false,
+  link: false,
+  main: false,
+  map: false,
+  mark: false,
+  menu: false,
+  menuitem: false, // NOTE: Close tag should be omitted, but causes problems.
+  meta: true,
+  meter: false,
+  nav: false,
+  noscript: false,
+  object: false,
+  ol: false,
+  optgroup: false,
+  option: false,
+  output: false,
+  p: false,
+  param: true,
+  pre: false,
+  progress: false,
+  q: false,
+  rp: false,
+  rt: false,
+  ruby: false,
+  s: false,
+  samp: false,
+  script: false,
+  section: false,
+  select: false,
+  small: false,
+  source: false,
+  span: false,
+  strong: false,
+  style: false,
+  sub: false,
+  summary: false,
+  sup: false,
+  table: false,
+  tbody: false,
+  td: false,
+  textarea: false, // NOTE: Injected, see `ReactDOMTextarea`.
+  tfoot: false,
+  th: false,
+  thead: false,
+  time: false,
+  title: false,
+  tr: false,
+  track: true,
+  u: false,
+  ul: false,
+  'var': false,
+  video: false,
+  wbr: false,
+
+  // SVG
+  circle: false,
+  defs: false,
+  g: false,
+  line: false,
+  linearGradient: false,
+  path: false,
+  polygon: false,
+  polyline: false,
+  radialGradient: false,
+  rect: false,
+  stop: false,
+  svg: false,
+  text: false
+}, createDOMComponentClass);
+
+var injection = {
+  injectComponentClasses: function(componentClasses) {
+    mergeInto(ReactDOM, componentClasses);
+  }
+};
+
+ReactDOM.injection = injection;
+
+module.exports = ReactDOM;
+
+},{"./ReactDOMComponent":34,"./mergeInto":119,"./objMapKeyVal":122}],33:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactDOMButton
+ */
+
+"use strict";
+
+var AutoFocusMixin = require("./AutoFocusMixin");
+var ReactCompositeComponent = require("./ReactCompositeComponent");
+var ReactDOM = require("./ReactDOM");
+
+var keyMirror = require("./keyMirror");
+
+// Store a reference to the <button> `ReactDOMComponent`.
+var button = ReactDOM.button;
+
+var mouseListenerNames = keyMirror({
+  onClick: true,
+  onDoubleClick: true,
+  onMouseDown: true,
+  onMouseMove: true,
+  onMouseUp: true,
+  onClickCapture: true,
+  onDoubleClickCapture: true,
+  onMouseDownCapture: true,
+  onMouseMoveCapture: true,
+  onMouseUpCapture: true
+});
+
+/**
+ * Implements a <button> native component that does not receive mouse events
+ * when `disabled` is set.
+ */
+var ReactDOMButton = ReactCompositeComponent.createClass({
+  displayName: 'ReactDOMButton',
+
+  mixins: [AutoFocusMixin],
+
+  render: function() {
+    var props = {};
+
+    // Copy the props; except the mouse listeners if we're disabled
+    for (var key in this.props) {
+      if (this.props.hasOwnProperty(key) &&
+          (!this.props.disabled || !mouseListenerNames[key])) {
+        props[key] = this.props[key];
+      }
+    }
+
+    return button(props, this.props.children);
+  }
+
+});
+
+module.exports = ReactDOMButton;
+
+},{"./AutoFocusMixin":1,"./ReactCompositeComponent":29,"./ReactDOM":32,"./keyMirror":114}],34:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactDOMComponent
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var CSSPropertyOperations = require("./CSSPropertyOperations");
+var DOMProperty = require("./DOMProperty");
+var DOMPropertyOperations = require("./DOMPropertyOperations");
+var ReactComponent = require("./ReactComponent");
+var ReactEventEmitter = require("./ReactEventEmitter");
+var ReactMount = require("./ReactMount");
+var ReactMultiChild = require("./ReactMultiChild");
+var ReactPerf = require("./ReactPerf");
+
+var escapeTextForBrowser = require("./escapeTextForBrowser");
+var invariant = require("./invariant");
+var keyOf = require("./keyOf");
+var merge = require("./merge");
+var mixInto = require("./mixInto");
+
+var deleteListener = ReactEventEmitter.deleteListener;
+var listenTo = ReactEventEmitter.listenTo;
+var registrationNameModules = ReactEventEmitter.registrationNameModules;
+
+// For quickly matching children type, to test if can be treated as content.
+var CONTENT_TYPES = {'string': true, 'number': true};
+
+var STYLE = keyOf({style: null});
+
+var ELEMENT_NODE_TYPE = 1;
+
+/**
+ * @param {?object} props
+ */
+function assertValidProps(props) {
+  if (!props) {
+    return;
+  }
+  // Note the use of `==` which checks for null or undefined.
+  ("production" !== "development" ? invariant(
+    props.children == null || props.dangerouslySetInnerHTML == null,
+    'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
+  ) : invariant(props.children == null || props.dangerouslySetInnerHTML == null));
+  ("production" !== "development" ? invariant(
+    props.style == null || typeof props.style === 'object',
+    'The `style` prop expects a mapping from style properties to values, ' +
+    'not a string.'
+  ) : invariant(props.style == null || typeof props.style === 'object'));
+}
+
+function putListener(id, registrationName, listener, transaction) {
+  var container = ReactMount.findReactContainerForID(id);
+  if (container) {
+    var doc = container.nodeType === ELEMENT_NODE_TYPE ?
+      container.ownerDocument :
+      container;
+    listenTo(registrationName, doc);
+  }
+  transaction.getPutListenerQueue().enqueuePutListener(
+    id,
+    registrationName,
+    listener
+  );
+}
+
+
+/**
+ * @constructor ReactDOMComponent
+ * @extends ReactComponent
+ * @extends ReactMultiChild
+ */
+function ReactDOMComponent(tag, omitClose) {
+  this._tagOpen = '<' + tag;
+  this._tagClose = omitClose ? '' : '</' + tag + '>';
+  this.tagName = tag.toUpperCase();
+}
+
+ReactDOMComponent.Mixin = {
+
+  /**
+   * Generates root tag markup then recurses. This method has side effects and
+   * is not idempotent.
+   *
+   * @internal
+   * @param {string} rootID The root DOM ID for this node.
+   * @param {ReactReconcileTransaction} transaction
+   * @param {number} mountDepth number of components in the owner hierarchy
+   * @return {string} The computed markup.
+   */
+  mountComponent: ReactPerf.measure(
+    'ReactDOMComponent',
+    'mountComponent',
+    function(rootID, transaction, mountDepth) {
+      ReactComponent.Mixin.mountComponent.call(
+        this,
+        rootID,
+        transaction,
+        mountDepth
+      );
+      assertValidProps(this.props);
+      return (
+        this._createOpenTagMarkupAndPutListeners(transaction) +
+        this._createContentMarkup(transaction) +
+        this._tagClose
+      );
+    }
+  ),
+
+  /**
+   * Creates markup for the open tag and all attributes.
+   *
+   * This method has side effects because events get registered.
+   *
+   * Iterating over object properties is faster than iterating over arrays.
+   * @see http://jsperf.com/obj-vs-arr-iteration
+   *
+   * @private
+   * @param {ReactReconcileTransaction} transaction
+   * @return {string} Markup of opening tag.
+   */
+  _createOpenTagMarkupAndPutListeners: function(transaction) {
+    var props = this.props;
+    var ret = this._tagOpen;
+
+    for (var propKey in props) {
+      if (!props.hasOwnProperty(propKey)) {
+        continue;
+      }
+      var propValue = props[propKey];
+      if (propValue == null) {
+        continue;
+      }
+      if (registrationNameModules[propKey]) {
+        putListener(this._rootNodeID, propKey, propValue, transaction);
+      } else {
+        if (propKey === STYLE) {
+          if (propValue) {
+            propValue = props.style = merge(props.style);
+          }
+          propValue = CSSPropertyOperations.createMarkupForStyles(propValue);
+        }
+        var markup =
+          DOMPropertyOperations.createMarkupForProperty(propKey, propValue);
+        if (markup) {
+          ret += ' ' + markup;
+        }
+      }
+    }
+
+    var idMarkup = DOMPropertyOperations.createMarkupForID(this._rootNodeID);
+    return ret + ' ' + idMarkup + '>';
+  },
+
+  /**
+   * Creates markup for the content between the tags.
+   *
+   * @private
+   * @param {ReactReconcileTransaction} transaction
+   * @return {string} Content markup.
+   */
+  _createContentMarkup: function(transaction) {
+    // Intentional use of != to avoid catching zero/false.
+    var innerHTML = this.props.dangerouslySetInnerHTML;
+    if (innerHTML != null) {
+      if (innerHTML.__html != null) {
+        return innerHTML.__html;
+      }
+    } else {
+      var contentToUse =
+        CONTENT_TYPES[typeof this.props.children] ? this.props.children : null;
+      var childrenToUse = contentToUse != null ? null : this.props.children;
+      if (contentToUse != null) {
+        return escapeTextForBrowser(contentToUse);
+      } else if (childrenToUse != null) {
+        var mountImages = this.mountChildren(
+          childrenToUse,
+          transaction
+        );
+        return mountImages.join('');
+      }
+    }
+    return '';
+  },
+
+  receiveComponent: function(nextComponent, transaction) {
+    assertValidProps(nextComponent.props);
+    ReactComponent.Mixin.receiveComponent.call(
+      this,
+      nextComponent,
+      transaction
+    );
+  },
+
+  /**
+   * Updates a native DOM component after it has already been allocated and
+   * attached to the DOM. Reconciles the root DOM node, then recurses.
+   *
+   * @param {ReactReconcileTransaction} transaction
+   * @param {object} prevProps
+   * @internal
+   * @overridable
+   */
+  updateComponent: ReactPerf.measure(
+    'ReactDOMComponent',
+    'updateComponent',
+    function(transaction, prevProps, prevOwner) {
+      ReactComponent.Mixin.updateComponent.call(
+        this,
+        transaction,
+        prevProps,
+        prevOwner
+      );
+      this._updateDOMProperties(prevProps, transaction);
+      this._updateDOMChildren(prevProps, transaction);
+    }
+  ),
+
+  /**
+   * Reconciles the properties by detecting differences in property values and
+   * updating the DOM as necessary. This function is probably the single most
+   * critical path for performance optimization.
+   *
+   * TODO: Benchmark whether checking for changed values in memory actually
+   *       improves performance (especially statically positioned elements).
+   * TODO: Benchmark the effects of putting this at the top since 99% of props
+   *       do not change for a given reconciliation.
+   * TODO: Benchmark areas that can be improved with caching.
+   *
+   * @private
+   * @param {object} lastProps
+   * @param {ReactReconcileTransaction} transaction
+   */
+  _updateDOMProperties: function(lastProps, transaction) {
+    var nextProps = this.props;
+    var propKey;
+    var styleName;
+    var styleUpdates;
+    for (propKey in lastProps) {
+      if (nextProps.hasOwnProperty(propKey) ||
+         !lastProps.hasOwnProperty(propKey)) {
+        continue;
+      }
+      if (propKey === STYLE) {
+        var lastStyle = lastProps[propKey];
+        for (styleName in lastStyle) {
+          if (lastStyle.hasOwnProperty(styleName)) {
+            styleUpdates = styleUpdates || {};
+            styleUpdates[styleName] = '';
+          }
+        }
+      } else if (registrationNameModules[propKey]) {
+        deleteListener(this._rootNodeID, propKey);
+      } else if (
+          DOMProperty.isStandardName[propKey] ||
+          DOMProperty.isCustomAttribute(propKey)) {
+        ReactComponent.BackendIDOperations.deletePropertyByID(
+          this._rootNodeID,
+          propKey
+        );
+      }
+    }
+    for (propKey in nextProps) {
+      var nextProp = nextProps[propKey];
+      var lastProp = lastProps[propKey];
+      if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) {
+        continue;
+      }
+      if (propKey === STYLE) {
+        if (nextProp) {
+          nextProp = nextProps.style = merge(nextProp);
+        }
+        if (lastProp) {
+          // Unset styles on `lastProp` but not on `nextProp`.
+          for (styleName in lastProp) {
+            if (lastProp.hasOwnProperty(styleName) &&
+                !nextProp.hasOwnProperty(styleName)) {
+              styleUpdates = styleUpdates || {};
+              styleUpdates[styleName] = '';
+            }
+          }
+          // Update styles that changed since `lastProp`.
+          for (styleName in nextProp) {
+            if (nextProp.hasOwnProperty(styleName) &&
+                lastProp[styleName] !== nextProp[styleName]) {
+              styleUpdates = styleUpdates || {};
+              styleUpdates[styleName] = nextProp[styleName];
+            }
+          }
+        } else {
+          // Relies on `updateStylesByID` not mutating `styleUpdates`.
+          styleUpdates = nextProp;
+        }
+      } else if (registrationNameModules[propKey]) {
+        putListener(this._rootNodeID, propKey, nextProp, transaction);
+      } else if (
+          DOMProperty.isStandardName[propKey] ||
+          DOMProperty.isCustomAttribute(propKey)) {
+        ReactComponent.BackendIDOperations.updatePropertyByID(
+          this._rootNodeID,
+          propKey,
+          nextProp
+        );
+      }
+    }
+    if (styleUpdates) {
+      ReactComponent.BackendIDOperations.updateStylesByID(
+        this._rootNodeID,
+        styleUpdates
+      );
+    }
+  },
+
+  /**
+   * Reconciles the children with the various properties that affect the
+   * children content.
+   *
+   * @param {object} lastProps
+   * @param {ReactReconcileTransaction} transaction
+   */
+  _updateDOMChildren: function(lastProps, transaction) {
+    var nextProps = this.props;
+
+    var lastContent =
+      CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;
+    var nextContent =
+      CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;
+
+    var lastHtml =
+      lastProps.dangerouslySetInnerHTML &&
+      lastProps.dangerouslySetInnerHTML.__html;
+    var nextHtml =
+      nextProps.dangerouslySetInnerHTML &&
+      nextProps.dangerouslySetInnerHTML.__html;
+
+    // Note the use of `!=` which checks for null or undefined.
+    var lastChildren = lastContent != null ? null : lastProps.children;
+    var nextChildren = nextContent != null ? null : nextProps.children;
+
+    // If we're switching from children to content/html or vice versa, remove
+    // the old content
+    var lastHasContentOrHtml = lastContent != null || lastHtml != null;
+    var nextHasContentOrHtml = nextContent != null || nextHtml != null;
+    if (lastChildren != null && nextChildren == null) {
+      this.updateChildren(null, transaction);
+    } else if (lastHasContentOrHtml && !nextHasContentOrHtml) {
+      this.updateTextContent('');
+    }
+
+    if (nextContent != null) {
+      if (lastContent !== nextContent) {
+        this.updateTextContent('' + nextContent);
+      }
+    } else if (nextHtml != null) {
+      if (lastHtml !== nextHtml) {
+        ReactComponent.BackendIDOperations.updateInnerHTMLByID(
+          this._rootNodeID,
+          nextHtml
+        );
+      }
+    } else if (nextChildren != null) {
+      this.updateChildren(nextChildren, transaction);
+    }
+  },
+
+  /**
+   * Destroys all event registrations for this instance. Does not remove from
+   * the DOM. That must be done by the parent.
+   *
+   * @internal
+   */
+  unmountComponent: function() {
+    this.unmountChildren();
+    ReactEventEmitter.deleteAllListeners(this._rootNodeID);
+    ReactComponent.Mixin.unmountComponent.call(this);
+  }
+
+};
+
+mixInto(ReactDOMComponent, ReactComponent.Mixin);
+mixInto(ReactDOMComponent, ReactDOMComponent.Mixin);
+mixInto(ReactDOMComponent, ReactMultiChild.Mixin);
+
+module.exports = ReactDOMComponent;
+
+},{"./CSSPropertyOperations":3,"./DOMProperty":8,"./DOMPropertyOperations":9,"./ReactComponent":26,"./ReactEventEmitter":48,"./ReactMount":55,"./ReactMultiChild":57,"./ReactPerf":60,"./escapeTextForBrowser":96,"./invariant":108,"./keyOf":115,"./merge":117,"./mixInto":120}],35:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactDOMForm
+ */
+
+"use strict";
+
+var ReactCompositeComponent = require("./ReactCompositeComponent");
+var ReactDOM = require("./ReactDOM");
+var ReactEventEmitter = require("./ReactEventEmitter");
+var EventConstants = require("./EventConstants");
+
+// Store a reference to the <form> `ReactDOMComponent`.
+var form = ReactDOM.form;
+
+/**
+ * Since onSubmit doesn't bubble OR capture on the top level in IE8, we need
+ * to capture it on the <form> element itself. There are lots of hacks we could
+ * do to accomplish this, but the most reliable is to make <form> a
+ * composite component and use `componentDidMount` to attach the event handlers.
+ */
+var ReactDOMForm = ReactCompositeComponent.createClass({
+  displayName: 'ReactDOMForm',
+
+  render: function() {
+    // TODO: Instead of using `ReactDOM` directly, we should use JSX. However,
+    // `jshint` fails to parse JSX so in order for linting to work in the open
+    // source repo, we need to just use `ReactDOM.form`.
+    return this.transferPropsTo(form(null, this.props.children));
+  },
+
+  componentDidMount: function() {
+    ReactEventEmitter.trapBubbledEvent(
+      EventConstants.topLevelTypes.topReset,
+      'reset',
+      this.getDOMNode()
+    );
+    ReactEventEmitter.trapBubbledEvent(
+      EventConstants.topLevelTypes.topSubmit,
+      'submit',
+      this.getDOMNode()
+    );
+  }
+});
+
+module.exports = ReactDOMForm;
+
+},{"./EventConstants":14,"./ReactCompositeComponent":29,"./ReactDOM":32,"./ReactEventEmitter":48}],36:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactDOMIDOperations
+ * @typechecks static-only
+ */
+
+/*jslint evil: true */
+
+"use strict";
+
+var CSSPropertyOperations = require("./CSSPropertyOperations");
+var DOMChildrenOperations = require("./DOMChildrenOperations");
+var DOMPropertyOperations = require("./DOMPropertyOperations");
+var ReactMount = require("./ReactMount");
+var ReactPerf = require("./ReactPerf");
+
+var invariant = require("./invariant");
+
+/**
+ * Errors for properties that should not be updated with `updatePropertyById()`.
+ *
+ * @type {object}
+ * @private
+ */
+var INVALID_PROPERTY_ERRORS = {
+  dangerouslySetInnerHTML:
+    '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.',
+  style: '`style` must be set using `updateStylesByID()`.'
+};
+
+var useWhitespaceWorkaround;
+
+/**
+ * Operations used to process updates to DOM nodes. This is made injectable via
+ * `ReactComponent.BackendIDOperations`.
+ */
+var ReactDOMIDOperations = {
+
+  /**
+   * Updates a DOM node with new property values. This should only be used to
+   * update DOM properties in `DOMProperty`.
+   *
+   * @param {string} id ID of the node to update.
+   * @param {string} name A valid property name, see `DOMProperty`.
+   * @param {*} value New value of the property.
+   * @internal
+   */
+  updatePropertyByID: ReactPerf.measure(
+    'ReactDOMIDOperations',
+    'updatePropertyByID',
+    function(id, name, value) {
+      var node = ReactMount.getNode(id);
+      ("production" !== "development" ? invariant(
+        !INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
+        'updatePropertyByID(...): %s',
+        INVALID_PROPERTY_ERRORS[name]
+      ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name)));
+
+      // If we're updating to null or undefined, we should remove the property
+      // from the DOM node instead of inadvertantly setting to a string. This
+      // brings us in line with the same behavior we have on initial render.
+      if (value != null) {
+        DOMPropertyOperations.setValueForProperty(node, name, value);
+      } else {
+        DOMPropertyOperations.deleteValueForProperty(node, name);
+      }
+    }
+  ),
+
+  /**
+   * Updates a DOM node to remove a property. This should only be used to remove
+   * DOM properties in `DOMProperty`.
+   *
+   * @param {string} id ID of the node to update.
+   * @param {string} name A property name to remove, see `DOMProperty`.
+   * @internal
+   */
+  deletePropertyByID: ReactPerf.measure(
+    'ReactDOMIDOperations',
+    'deletePropertyByID',
+    function(id, name, value) {
+      var node = ReactMount.getNode(id);
+      ("production" !== "development" ? invariant(
+        !INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
+        'updatePropertyByID(...): %s',
+        INVALID_PROPERTY_ERRORS[name]
+      ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name)));
+      DOMPropertyOperations.deleteValueForProperty(node, name, value);
+    }
+  ),
+
+  /**
+   * Updates a DOM node with new style values. If a value is specified as '',
+   * the corresponding style property will be unset.
+   *
+   * @param {string} id ID of the node to update.
+   * @param {object} styles Mapping from styles to values.
+   * @internal
+   */
+  updateStylesByID: ReactPerf.measure(
+    'ReactDOMIDOperations',
+    'updateStylesByID',
+    function(id, styles) {
+      var node = ReactMount.getNode(id);
+      CSSPropertyOperations.setValueForStyles(node, styles);
+    }
+  ),
+
+  /**
+   * Updates a DOM node's innerHTML.
+   *
+   * @param {string} id ID of the node to update.
+   * @param {string} html An HTML string.
+   * @internal
+   */
+  updateInnerHTMLByID: ReactPerf.measure(
+    'ReactDOMIDOperations',
+    'updateInnerHTMLByID',
+    function(id, html) {
+      var node = ReactMount.getNode(id);
+
+      // IE8: When updating a just created node with innerHTML only leading
+      // whitespace is removed. When updating an existing node with innerHTML
+      // whitespace in root TextNodes is also collapsed.
+      // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
+
+      if (useWhitespaceWorkaround === undefined) {
+        // Feature detection; only IE8 is known to behave improperly like this.
+        var temp = document.createElement('div');
+        temp.innerHTML = ' ';
+        useWhitespaceWorkaround = temp.innerHTML === '';
+      }
+
+      if (useWhitespaceWorkaround) {
+        // Magic theory: IE8 supposedly differentiates between added and updated
+        // nodes when processing innerHTML, innerHTML on updated nodes suffers
+        // from worse whitespace behavior. Re-adding a node like this triggers
+        // the initial and more favorable whitespace behavior.
+        node.parentNode.replaceChild(node, node);
+      }
+
+      if (useWhitespaceWorkaround && html.match(/^[ \r\n\t\f]/)) {
+        // Recover leading whitespace by temporarily prepending any character.
+        // \uFEFF has the potential advantage of being zero-width/invisible.
+        node.innerHTML = '\uFEFF' + html;
+        node.firstChild.deleteData(0, 1);
+      } else {
+        node.innerHTML = html;
+      }
+    }
+  ),
+
+  /**
+   * Updates a DOM node's text content set by `props.content`.
+   *
+   * @param {string} id ID of the node to update.
+   * @param {string} content Text content.
+   * @internal
+   */
+  updateTextContentByID: ReactPerf.measure(
+    'ReactDOMIDOperations',
+    'updateTextContentByID',
+    function(id, content) {
+      var node = ReactMount.getNode(id);
+      DOMChildrenOperations.updateTextContent(node, content);
+    }
+  ),
+
+  /**
+   * Replaces a DOM node that exists in the document with markup.
+   *
+   * @param {string} id ID of child to be replaced.
+   * @param {string} markup Dangerous markup to inject in place of child.
+   * @internal
+   * @see {Danger.dangerouslyReplaceNodeWithMarkup}
+   */
+  dangerouslyReplaceNodeWithMarkupByID: ReactPerf.measure(
+    'ReactDOMIDOperations',
+    'dangerouslyReplaceNodeWithMarkupByID',
+    function(id, markup) {
+      var node = ReactMount.getNode(id);
+      DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);
+    }
+  ),
+
+  /**
+   * Updates a component's children by processing a series of updates.
+   *
+   * @param {array<object>} updates List of update configurations.
+   * @param {array<string>} markup List of markup strings.
+   * @internal
+   */
+  dangerouslyProcessChildrenUpdates: ReactPerf.measure(
+    'ReactDOMIDOperations',
+    'dangerouslyProcessChildrenUpdates',
+    function(updates, markup) {
+      for (var i = 0; i < updates.length; i++) {
+        updates[i].parentNode = ReactMount.getNode(updates[i].parentID);
+      }
+      DOMChildrenOperations.processUpdates(updates, markup);
+    }
+  )
+};
+
+module.exports = ReactDOMIDOperations;
+
+},{"./CSSPropertyOperations":3,"./DOMChildrenOperations":7,"./DOMPropertyOperations":9,"./ReactMount":55,"./ReactPerf":60,"./invariant":108}],37:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactDOMImg
+ */
+
+"use strict";
+
+var ReactCompositeComponent = require("./ReactCompositeComponent");
+var ReactDOM = require("./ReactDOM");
+var ReactEventEmitter = require("./ReactEventEmitter");
+var EventConstants = require("./EventConstants");
+
+// Store a reference to the <img> `ReactDOMComponent`.
+var img = ReactDOM.img;
+
+/**
+ * Since onLoad doesn't bubble OR capture on the top level in IE8, we need to
+ * capture it on the <img> element itself. There are lots of hacks we could do
+ * to accomplish this, but the most reliable is to make <img> a composite
+ * component and use `componentDidMount` to attach the event handlers.
+ */
+var ReactDOMImg = ReactCompositeComponent.createClass({
+  displayName: 'ReactDOMImg',
+  tagName: 'IMG',
+
+  render: function() {
+    return img(this.props);
+  },
+
+  componentDidMount: function() {
+    var node = this.getDOMNode();
+    ReactEventEmitter.trapBubbledEvent(
+      EventConstants.topLevelTypes.topLoad,
+      'load',
+      node
+    );
+    ReactEventEmitter.trapBubbledEvent(
+      EventConstants.topLevelTypes.topError,
+      'error',
+      node
+    );
+  }
+});
+
+module.exports = ReactDOMImg;
+
+},{"./EventConstants":14,"./ReactCompositeComponent":29,"./ReactDOM":32,"./ReactEventEmitter":48}],38:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactDOMInput
+ */
+
+"use strict";
+
+var AutoFocusMixin = require("./AutoFocusMixin");
+var DOMPropertyOperations = require("./DOMPropertyOperations");
+var LinkedValueUtils = require("./LinkedValueUtils");
+var ReactCompositeComponent = require("./ReactCompositeComponent");
+var ReactDOM = require("./ReactDOM");
+var ReactMount = require("./ReactMount");
+
+var invariant = require("./invariant");
+var merge = require("./merge");
+
+// Store a reference to the <input> `ReactDOMComponent`.
+var input = ReactDOM.input;
+
+var instancesByReactID = {};
+
+/**
+ * Implements an <input> native component that allows setting these optional
+ * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
+ *
+ * If `checked` or `value` are not supplied (or null/undefined), user actions
+ * that affect the checked state or value will trigger updates to the element.
+ *
+ * If they are supplied (and not null/undefined), the rendered element will not
+ * trigger updates to the element. Instead, the props must change in order for
+ * the rendered element to be updated.
+ *
+ * The rendered element will be initialized as unchecked (or `defaultChecked`)
+ * with an empty value (or `defaultValue`).
+ *
+ * @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
+ */
+var ReactDOMInput = ReactCompositeComponent.createClass({
+  displayName: 'ReactDOMInput',
+
+  mixins: [AutoFocusMixin, LinkedValueUtils.Mixin],
+
+  getInitialState: function() {
+    var defaultValue = this.props.defaultValue;
+    return {
+      checked: this.props.defaultChecked || false,
+      value: defaultValue != null ? defaultValue : null
+    };
+  },
+
+  shouldComponentUpdate: function() {
+    // Defer any updates to this component during the `onChange` handler.
+    return !this._isChanging;
+  },
+
+  render: function() {
+    // Clone `this.props` so we don't mutate the input.
+    var props = merge(this.props);
+
+    props.defaultChecked = null;
+    props.defaultValue = null;
+
+    var value = LinkedValueUtils.getValue(this);
+    props.value = value != null ? value : this.state.value;
+
+    var checked = LinkedValueUtils.getChecked(this);
+    props.checked = checked != null ? checked : this.state.checked;
+
+    props.onChange = this._handleChange;
+
+    return input(props, this.props.children);
+  },
+
+  componentDidMount: function() {
+    var id = ReactMount.getID(this.getDOMNode());
+    instancesByReactID[id] = this;
+  },
+
+  componentWillUnmount: function() {
+    var rootNode = this.getDOMNode();
+    var id = ReactMount.getID(rootNode);
+    delete instancesByReactID[id];
+  },
+
+  componentDidUpdate: function(prevProps, prevState, prevContext) {
+    var rootNode = this.getDOMNode();
+    if (this.props.checked != null) {
+      DOMPropertyOperations.setValueForProperty(
+        rootNode,
+        'checked',
+        this.props.checked || false
+      );
+    }
+
+    var value = LinkedValueUtils.getValue(this);
+    if (value != null) {
+      // Cast `value` to a string to ensure the value is set correctly. While
+      // browsers typically do this as necessary, jsdom doesn't.
+      DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value);
+    }
+  },
+
+  _handleChange: function(event) {
+    var returnValue;
+    var onChange = LinkedValueUtils.getOnChange(this);
+    if (onChange) {
+      this._isChanging = true;
+      returnValue = onChange.call(this, event);
+      this._isChanging = false;
+    }
+    this.setState({
+      checked: event.target.checked,
+      value: event.target.value
+    });
+
+    var name = this.props.name;
+    if (this.props.type === 'radio' && name != null) {
+      var rootNode = this.getDOMNode();
+      var queryRoot = rootNode;
+
+      while (queryRoot.parentNode) {
+        queryRoot = queryRoot.parentNode;
+      }
+
+      // If `rootNode.form` was non-null, then we could try `form.elements`,
+      // but that sometimes behaves strangely in IE8. We could also try using
+      // `form.getElementsByName`, but that will only return direct children
+      // and won't include inputs that use the HTML5 `form=` attribute. Since
+      // the input might not even be in a form, let's just use the global
+      // `querySelectorAll` to ensure we don't miss anything.
+      var group = queryRoot.querySelectorAll(
+        'input[name=' + JSON.stringify('' + name) + '][type="radio"]');
+
+      for (var i = 0, groupLen = group.length; i < groupLen; i++) {
+        var otherNode = group[i];
+        if (otherNode === rootNode ||
+            otherNode.form !== rootNode.form) {
+          continue;
+        }
+        var otherID = ReactMount.getID(otherNode);
+        ("production" !== "development" ? invariant(
+          otherID,
+          'ReactDOMInput: Mixing React and non-React radio inputs with the ' +
+          'same `name` is not supported.'
+        ) : invariant(otherID));
+        var otherInstance = instancesByReactID[otherID];
+        ("production" !== "development" ? invariant(
+          otherInstance,
+          'ReactDOMInput: Unknown radio button ID %s.',
+          otherID
+        ) : invariant(otherInstance));
+        // In some cases, this will actually change the `checked` state value.
+        // In other cases, there's no change but this forces a reconcile upon
+        // which componentDidUpdate will reset the DOM property to whatever it
+        // should be.
+        otherInstance.setState({
+          checked: false
+        });
+      }
+    }
+
+    return returnValue;
+  }
+
+});
+
+module.exports = ReactDOMInput;
+
+},{"./AutoFocusMixin":1,"./DOMPropertyOperations":9,"./LinkedValueUtils":21,"./ReactCompositeComponent":29,"./ReactDOM":32,"./ReactMount":55,"./invariant":108,"./merge":117}],39:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactDOMOption
+ */
+
+"use strict";
+
+var ReactCompositeComponent = require("./ReactCompositeComponent");
+var ReactDOM = require("./ReactDOM");
+
+// Store a reference to the <option> `ReactDOMComponent`.
+var option = ReactDOM.option;
+
+/**
+ * Implements an <option> native component that warns when `selected` is set.
+ */
+var ReactDOMOption = ReactCompositeComponent.createClass({
+  displayName: 'ReactDOMOption',
+
+  componentWillMount: function() {
+    // TODO (yungsters): Remove support for `selected` in <option>.
+    if (this.props.selected != null) {
+      if ("production" !== "development") {
+        console.warn(
+          'Use the `defaultValue` or `value` props on <select> instead of ' +
+          'setting `selected` on <option>.'
+        );
+      }
+    }
+  },
+
+  render: function() {
+    return option(this.props, this.props.children);
+  }
+
+});
+
+module.exports = ReactDOMOption;
+
+},{"./ReactCompositeComponent":29,"./ReactDOM":32}],40:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactDOMSelect
+ */
+
+"use strict";
+
+var AutoFocusMixin = require("./AutoFocusMixin");
+var LinkedValueUtils = require("./LinkedValueUtils");
+var ReactCompositeComponent = require("./ReactCompositeComponent");
+var ReactDOM = require("./ReactDOM");
+
+var invariant = require("./invariant");
+var merge = require("./merge");
+
+// Store a reference to the <select> `ReactDOMComponent`.
+var select = ReactDOM.select;
+
+/**
+ * Validation function for `value` and `defaultValue`.
+ * @private
+ */
+function selectValueType(props, propName, componentName) {
+  if (props[propName] == null) {
+    return;
+  }
+  if (props.multiple) {
+    ("production" !== "development" ? invariant(
+      Array.isArray(props[propName]),
+      'The `%s` prop supplied to <select> must be an array if `multiple` is ' +
+      'true.',
+      propName
+    ) : invariant(Array.isArray(props[propName])));
+  } else {
+    ("production" !== "development" ? invariant(
+      !Array.isArray(props[propName]),
+      'The `%s` prop supplied to <select> must be a scalar value if ' +
+      '`multiple` is false.',
+      propName
+    ) : invariant(!Array.isArray(props[propName])));
+  }
+}
+
+/**
+ * If `value` is supplied, updates <option> elements on mount and update.
+ * @param {ReactComponent} component Instance of ReactDOMSelect
+ * @param {?*} propValue For uncontrolled components, null/undefined. For
+ * controlled components, a string (or with `multiple`, a list of strings).
+ * @private
+ */
+function updateOptions(component, propValue) {
+  var multiple = component.props.multiple;
+  var value = propValue != null ? propValue : component.state.value;
+  var options = component.getDOMNode().options;
+  var selectedValue, i, l;
+  if (multiple) {
+    selectedValue = {};
+    for (i = 0, l = value.length; i < l; ++i) {
+      selectedValue['' + value[i]] = true;
+    }
+  } else {
+    selectedValue = '' + value;
+  }
+  for (i = 0, l = options.length; i < l; i++) {
+    var selected = multiple ?
+      selectedValue.hasOwnProperty(options[i].value) :
+      options[i].value === selectedValue;
+
+    if (selected !== options[i].selected) {
+      options[i].selected = selected;
+    }
+  }
+}
+
+/**
+ * Implements a <select> native component that allows optionally setting the
+ * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
+ * string. If `multiple` is true, the prop must be an array of strings.
+ *
+ * If `value` is not supplied (or null/undefined), user actions that change the
+ * selected option will trigger updates to the rendered options.
+ *
+ * If it is supplied (and not null/undefined), the rendered options will not
+ * update in response to user actions. Instead, the `value` prop must change in
+ * order for the rendered options to update.
+ *
+ * If `defaultValue` is provided, any options with the supplied values will be
+ * selected.
+ */
+var ReactDOMSelect = ReactCompositeComponent.createClass({
+  displayName: 'ReactDOMSelect',
+
+  mixins: [AutoFocusMixin, LinkedValueUtils.Mixin],
+
+  propTypes: {
+    defaultValue: selectValueType,
+    value: selectValueType
+  },
+
+  getInitialState: function() {
+    return {value: this.props.defaultValue || (this.props.multiple ? [] : '')};
+  },
+
+  componentWillReceiveProps: function(nextProps) {
+    if (!this.props.multiple && nextProps.multiple) {
+      this.setState({value: [this.state.value]});
+    } else if (this.props.multiple && !nextProps.multiple) {
+      this.setState({value: this.state.value[0]});
+    }
+  },
+
+  shouldComponentUpdate: function() {
+    // Defer any updates to this component during the `onChange` handler.
+    return !this._isChanging;
+  },
+
+  render: function() {
+    // Clone `this.props` so we don't mutate the input.
+    var props = merge(this.props);
+
+    props.onChange = this._handleChange;
+    props.value = null;
+
+    return select(props, this.props.children);
+  },
+
+  componentDidMount: function() {
+    updateOptions(this, LinkedValueUtils.getValue(this));
+  },
+
+  componentDidUpdate: function() {
+    var value = LinkedValueUtils.getValue(this);
+    if (value != null) {
+      updateOptions(this, value);
+    }
+  },
+
+  _handleChange: function(event) {
+    var returnValue;
+    var onChange = LinkedValueUtils.getOnChange(this);
+    if (onChange) {
+      this._isChanging = true;
+      returnValue = onChange.call(this, event);
+      this._isChanging = false;
+    }
+
+    var selectedValue;
+    if (this.props.multiple) {
+      selectedValue = [];
+      var options = event.target.options;
+      for (var i = 0, l = options.length; i < l; i++) {
+        if (options[i].selected) {
+          selectedValue.push(options[i].value);
+        }
+      }
+    } else {
+      selectedValue = event.target.value;
+    }
+
+    this.setState({value: selectedValue});
+    return returnValue;
+  }
+
+});
+
+module.exports = ReactDOMSelect;
+
+},{"./AutoFocusMixin":1,"./LinkedValueUtils":21,"./ReactCompositeComponent":29,"./ReactDOM":32,"./invariant":108,"./merge":117}],41:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactDOMSelection
+ */
+
+"use strict";
+
+var getNodeForCharacterOffset = require("./getNodeForCharacterOffset");
+var getTextContentAccessor = require("./getTextContentAccessor");
+
+/**
+ * Get the appropriate anchor and focus node/offset pairs for IE.
+ *
+ * The catch here is that IE's selection API doesn't provide information
+ * about whether the selection is forward or backward, so we have to
+ * behave as though it's always forward.
+ *
+ * IE text differs from modern selection in that it behaves as though
+ * block elements end with a new line. This means character offsets will
+ * differ between the two APIs.
+ *
+ * @param {DOMElement} node
+ * @return {object}
+ */
+function getIEOffsets(node) {
+  var selection = document.selection;
+  var selectedRange = selection.createRange();
+  var selectedLength = selectedRange.text.length;
+
+  // Duplicate selection so we can move range without breaking user selection.
+  var fromStart = selectedRange.duplicate();
+  fromStart.moveToElementText(node);
+  fromStart.setEndPoint('EndToStart', selectedRange);
+
+  var startOffset = fromStart.text.length;
+  var endOffset = startOffset + selectedLength;
+
+  return {
+    start: startOffset,
+    end: endOffset
+  };
+}
+
+/**
+ * @param {DOMElement} node
+ * @return {?object}
+ */
+function getModernOffsets(node) {
+  var selection = window.getSelection();
+
+  if (selection.rangeCount === 0) {
+    return null;
+  }
+
+  var anchorNode = selection.anchorNode;
+  var anchorOffset = selection.anchorOffset;
+  var focusNode = selection.focusNode;
+  var focusOffset = selection.focusOffset;
+
+  var currentRange = selection.getRangeAt(0);
+  var rangeLength = currentRange.toString().length;
+
+  var tempRange = currentRange.cloneRange();
+  tempRange.selectNodeContents(node);
+  tempRange.setEnd(currentRange.startContainer, currentRange.startOffset);
+
+  var start = tempRange.toString().length;
+  var end = start + rangeLength;
+
+  // Detect whether the selection is backward.
+  var detectionRange = document.createRange();
+  detectionRange.setStart(anchorNode, anchorOffset);
+  detectionRange.setEnd(focusNode, focusOffset);
+  var isBackward = detectionRange.collapsed;
+  detectionRange.detach();
+
+  return {
+    start: isBackward ? end : start,
+    end: isBackward ? start : end
+  };
+}
+
+/**
+ * @param {DOMElement|DOMTextNode} node
+ * @param {object} offsets
+ */
+function setIEOffsets(node, offsets) {
+  var range = document.selection.createRange().duplicate();
+  var start, end;
+
+  if (typeof offsets.end === 'undefined') {
+    start = offsets.start;
+    end = start;
+  } else if (offsets.start > offsets.end) {
+    start = offsets.end;
+    end = offsets.start;
+  } else {
+    start = offsets.start;
+    end = offsets.end;
+  }
+
+  range.moveToElementText(node);
+  range.moveStart('character', start);
+  range.setEndPoint('EndToStart', range);
+  range.moveEnd('character', end - start);
+  range.select();
+}
+
+/**
+ * In modern non-IE browsers, we can support both forward and backward
+ * selections.
+ *
+ * Note: IE10+ supports the Selection object, but it does not support
+ * the `extend` method, which means that even in modern IE, it's not possible
+ * to programatically create a backward selection. Thus, for all IE
+ * versions, we use the old IE API to create our selections.
+ *
+ * @param {DOMElement|DOMTextNode} node
+ * @param {object} offsets
+ */
+function setModernOffsets(node, offsets) {
+  var selection = window.getSelection();
+
+  var length = node[getTextContentAccessor()].length;
+  var start = Math.min(offsets.start, length);
+  var end = typeof offsets.end === 'undefined' ?
+            start : Math.min(offsets.end, length);
+
+  // IE 11 uses modern selection, but doesn't support the extend method.
+  // Flip backward selections, so we can set with a single range.
+  if (!selection.extend && start > end) {
+    var temp = end;
+    end = start;
+    start = temp;
+  }
+
+  var startMarker = getNodeForCharacterOffset(node, start);
+  var endMarker = getNodeForCharacterOffset(node, end);
+
+  if (startMarker && endMarker) {
+    var range = document.createRange();
+    range.setStart(startMarker.node, startMarker.offset);
+    selection.removeAllRanges();
+
+    if (start > end) {
+      selection.addRange(range);
+      selection.extend(endMarker.node, endMarker.offset);
+    } else {
+      range.setEnd(endMarker.node, endMarker.offset);
+      selection.addRange(range);
+    }
+
+    range.detach();
+  }
+}
+
+var ReactDOMSelection = {
+  /**
+   * @param {DOMElement} node
+   */
+  getOffsets: function(node) {
+    var getOffsets = document.selection ? getIEOffsets : getModernOffsets;
+    return getOffsets(node);
+  },
+
+  /**
+   * @param {DOMElement|DOMTextNode} node
+   * @param {object} offsets
+   */
+  setOffsets: function(node, offsets) {
+    var setOffsets = document.selection ? setIEOffsets : setModernOffsets;
+    setOffsets(node, offsets);
+  }
+};
+
+module.exports = ReactDOMSelection;
+
+},{"./getNodeForCharacterOffset":103,"./getTextContentAccessor":105}],42:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactDOMTextarea
+ */
+
+"use strict";
+
+var AutoFocusMixin = require("./AutoFocusMixin");
+var DOMPropertyOperations = require("./DOMPropertyOperations");
+var LinkedValueUtils = require("./LinkedValueUtils");
+var ReactCompositeComponent = require("./ReactCompositeComponent");
+var ReactDOM = require("./ReactDOM");
+
+var invariant = require("./invariant");
+var merge = require("./merge");
+
+// Store a reference to the <textarea> `ReactDOMComponent`.
+var textarea = ReactDOM.textarea;
+
+/**
+ * Implements a <textarea> native component that allows setting `value`, and
+ * `defaultValue`. This differs from the traditional DOM API because value is
+ * usually set as PCDATA children.
+ *
+ * If `value` is not supplied (or null/undefined), user actions that affect the
+ * value will trigger updates to the element.
+ *
+ * If `value` is supplied (and not null/undefined), the rendered element will
+ * not trigger updates to the element. Instead, the `value` prop must change in
+ * order for the rendered element to be updated.
+ *
+ * The rendered element will be initialized with an empty value, the prop
+ * `defaultValue` if specified, or the children content (deprecated).
+ */
+var ReactDOMTextarea = ReactCompositeComponent.createClass({
+  displayName: 'ReactDOMTextarea',
+
+  mixins: [AutoFocusMixin, LinkedValueUtils.Mixin],
+
+  getInitialState: function() {
+    var defaultValue = this.props.defaultValue;
+    // TODO (yungsters): Remove support for children content in <textarea>.
+    var children = this.props.children;
+    if (children != null) {
+      if ("production" !== "development") {
+        console.warn(
+          'Use the `defaultValue` or `value` props instead of setting ' +
+          'children on <textarea>.'
+        );
+      }
+      ("production" !== "development" ? invariant(
+        defaultValue == null,
+        'If you supply `defaultValue` on a <textarea>, do not pass children.'
+      ) : invariant(defaultValue == null));
+      if (Array.isArray(children)) {
+        ("production" !== "development" ? invariant(
+          children.length <= 1,
+          '<textarea> can only have at most one child.'
+        ) : invariant(children.length <= 1));
+        children = children[0];
+      }
+
+      defaultValue = '' + children;
+    }
+    if (defaultValue == null) {
+      defaultValue = '';
+    }
+    var value = LinkedValueUtils.getValue(this);
+    return {
+      // We save the initial value so that `ReactDOMComponent` doesn't update
+      // `textContent` (unnecessary since we update value).
+      // The initial value can be a boolean or object so that's why it's
+      // forced to be a string.
+      initialValue: '' + (value != null ? value : defaultValue),
+      value: defaultValue
+    };
+  },
+
+  shouldComponentUpdate: function() {
+    // Defer any updates to this component during the `onChange` handler.
+    return !this._isChanging;
+  },
+
+  render: function() {
+    // Clone `this.props` so we don't mutate the input.
+    var props = merge(this.props);
+    var value = LinkedValueUtils.getValue(this);
+
+    ("production" !== "development" ? invariant(
+      props.dangerouslySetInnerHTML == null,
+      '`dangerouslySetInnerHTML` does not make sense on <textarea>.'
+    ) : invariant(props.dangerouslySetInnerHTML == null));
+
+    props.defaultValue = null;
+    props.value = value != null ? value : this.state.value;
+    props.onChange = this._handleChange;
+
+    // Always set children to the same thing. In IE9, the selection range will
+    // get reset if `textContent` is mutated.
+    return textarea(props, this.state.initialValue);
+  },
+
+  componentDidUpdate: function(prevProps, prevState, prevContext) {
+    var value = LinkedValueUtils.getValue(this);
+    if (value != null) {
+      var rootNode = this.getDOMNode();
+      // Cast `value` to a string to ensure the value is set correctly. While
+      // browsers typically do this as necessary, jsdom doesn't.
+      DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value);
+    }
+  },
+
+  _handleChange: function(event) {
+    var returnValue;
+    var onChange = LinkedValueUtils.getOnChange(this);
+    if (onChange) {
+      this._isChanging = true;
+      returnValue = onChange.call(this, event);
+      this._isChanging = false;
+    }
+    this.setState({value: event.target.value});
+    return returnValue;
+  }
+
+});
+
+module.exports = ReactDOMTextarea;
+
+},{"./AutoFocusMixin":1,"./DOMPropertyOperations":9,"./LinkedValueUtils":21,"./ReactCompositeComponent":29,"./ReactDOM":32,"./invariant":108,"./merge":117}],43:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactDefaultBatchingStrategy
+ */
+
+"use strict";
+
+var ReactUpdates = require("./ReactUpdates");
+var Transaction = require("./Transaction");
+
+var emptyFunction = require("./emptyFunction");
+var mixInto = require("./mixInto");
+
+var RESET_BATCHED_UPDATES = {
+  initialize: emptyFunction,
+  close: function() {
+    ReactDefaultBatchingStrategy.isBatchingUpdates = false;
+  }
+};
+
+var FLUSH_BATCHED_UPDATES = {
+  initialize: emptyFunction,
+  close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates)
+};
+
+var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES];
+
+function ReactDefaultBatchingStrategyTransaction() {
+  this.reinitializeTransaction();
+}
+
+mixInto(ReactDefaultBatchingStrategyTransaction, Transaction.Mixin);
+mixInto(ReactDefaultBatchingStrategyTransaction, {
+  getTransactionWrappers: function() {
+    return TRANSACTION_WRAPPERS;
+  }
+});
+
+var transaction = new ReactDefaultBatchingStrategyTransaction();
+
+var ReactDefaultBatchingStrategy = {
+  isBatchingUpdates: false,
+
+  /**
+   * Call the provided function in a context within which calls to `setState`
+   * and friends are batched such that components aren't updated unnecessarily.
+   */
+  batchedUpdates: function(callback, param) {
+    var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates;
+
+    ReactDefaultBatchingStrategy.isBatchingUpdates = true;
+
+    // The code is written this way to avoid extra allocations
+    if (alreadyBatchingUpdates) {
+      callback(param);
+    } else {
+      transaction.perform(callback, null, param);
+    }
+  }
+};
+
+module.exports = ReactDefaultBatchingStrategy;
+
+},{"./ReactUpdates":70,"./Transaction":84,"./emptyFunction":95,"./mixInto":120}],44:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactDefaultInjection
+ */
+
+"use strict";
+
+var ReactInjection = require("./ReactInjection");
+
+var ExecutionEnvironment = require("./ExecutionEnvironment");
+
+var DefaultDOMPropertyConfig = require("./DefaultDOMPropertyConfig");
+
+var ChangeEventPlugin = require("./ChangeEventPlugin");
+var ClientReactRootIndex = require("./ClientReactRootIndex");
+var CompositionEventPlugin = require("./CompositionEventPlugin");
+var DefaultEventPluginOrder = require("./DefaultEventPluginOrder");
+var EnterLeaveEventPlugin = require("./EnterLeaveEventPlugin");
+var MobileSafariClickEventPlugin = require("./MobileSafariClickEventPlugin");
+var ReactEventTopLevelCallback = require("./ReactEventTopLevelCallback");
+var ReactDOM = require("./ReactDOM");
+var ReactDOMButton = require("./ReactDOMButton");
+var ReactDOMForm = require("./ReactDOMForm");
+var ReactDOMImg = require("./ReactDOMImg");
+var ReactDOMInput = require("./ReactDOMInput");
+var ReactDOMOption = require("./ReactDOMOption");
+var ReactDOMSelect = require("./ReactDOMSelect");
+var ReactDOMTextarea = require("./ReactDOMTextarea");
+var ReactInstanceHandles = require("./ReactInstanceHandles");
+var ReactMount = require("./ReactMount");
+var SelectEventPlugin = require("./SelectEventPlugin");
+var ServerReactRootIndex = require("./ServerReactRootIndex");
+var SimpleEventPlugin = require("./SimpleEventPlugin");
+
+var ReactDefaultBatchingStrategy = require("./ReactDefaultBatchingStrategy");
+
+var createFullPageComponent = require("./createFullPageComponent");
+
+function inject() {
+  ReactInjection.EventEmitter.injectTopLevelCallbackCreator(
+    ReactEventTopLevelCallback
+  );
+
+  /**
+   * Inject modules for resolving DOM hierarchy and plugin ordering.
+   */
+  ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder);
+  ReactInjection.EventPluginHub.injectInstanceHandle(ReactInstanceHandles);
+  ReactInjection.EventPluginHub.injectMount(ReactMount);
+
+  /**
+   * Some important event plugins included by default (without having to require
+   * them).
+   */
+  ReactInjection.EventPluginHub.injectEventPluginsByName({
+    SimpleEventPlugin: SimpleEventPlugin,
+    EnterLeaveEventPlugin: EnterLeaveEventPlugin,
+    ChangeEventPlugin: ChangeEventPlugin,
+    CompositionEventPlugin: CompositionEventPlugin,
+    MobileSafariClickEventPlugin: MobileSafariClickEventPlugin,
+    SelectEventPlugin: SelectEventPlugin
+  });
+
+  ReactInjection.DOM.injectComponentClasses({
+    button: ReactDOMButton,
+    form: ReactDOMForm,
+    img: ReactDOMImg,
+    input: ReactDOMInput,
+    option: ReactDOMOption,
+    select: ReactDOMSelect,
+    textarea: ReactDOMTextarea,
+
+    html: createFullPageComponent(ReactDOM.html),
+    head: createFullPageComponent(ReactDOM.head),
+    title: createFullPageComponent(ReactDOM.title),
+    body: createFullPageComponent(ReactDOM.body)
+  });
+
+  ReactInjection.DOMProperty.injectDOMPropertyConfig(DefaultDOMPropertyConfig);
+
+  ReactInjection.Updates.injectBatchingStrategy(
+    ReactDefaultBatchingStrategy
+  );
+
+  ReactInjection.RootIndex.injectCreateReactRootIndex(
+    ExecutionEnvironment.canUseDOM ?
+      ClientReactRootIndex.createReactRootIndex :
+      ServerReactRootIndex.createReactRootIndex
+  );
+
+  if ("production" !== "development") {
+    var url = (ExecutionEnvironment.canUseDOM && window.location.href) || '';
+    if ((/[?&]react_perf\b/).test(url)) {
+      var ReactDefaultPerf = require("./ReactDefaultPerf");
+      ReactDefaultPerf.start();
+    }
+  }
+}
+
+module.exports = {
+  inject: inject
+};
+
+},{"./ChangeEventPlugin":4,"./ClientReactRootIndex":5,"./CompositionEventPlugin":6,"./DefaultDOMPropertyConfig":11,"./DefaultEventPluginOrder":12,"./EnterLeaveEventPlugin":13,"./ExecutionEnvironment":20,"./MobileSafariClickEventPlugin":22,"./ReactDOM":32,"./ReactDOMButton":33,"./ReactDOMForm":35,"./ReactDOMImg":37,"./ReactDOMInput":38,"./ReactDOMOption":39,"./ReactDOMSelect":40,"./ReactDOMTextarea":42,"./ReactDefaultBatchingStrategy":43,"./ReactDefaultPerf":45,"./ReactEventTopLevelCallback":50,"./ReactInjection":51,"./ReactInstanceHandles":53,"./ReactMount":55,"./SelectEventPlugin":71,"./ServerReactRootIndex":72,"./SimpleEventPlugin":73,"./createFullPageComponent":91}],45:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactDefaultPerf
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var DOMProperty = require("./DOMProperty");
+var ReactDefaultPerfAnalysis = require("./ReactDefaultPerfAnalysis");
+var ReactMount = require("./ReactMount");
+var ReactPerf = require("./ReactPerf");
+
+var performanceNow = require("./performanceNow");
+
+function roundFloat(val) {
+  return Math.floor(val * 100) / 100;
+}
+
+var ReactDefaultPerf = {
+  _allMeasurements: [], // last item in the list is the current one
+  _injected: false,
+
+  start: function() {
+    if (!ReactDefaultPerf._injected) {
+      ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure);
+    }
+
+    ReactDefaultPerf._allMeasurements.length = 0;
+    ReactPerf.enableMeasure = true;
+  },
+
+  stop: function() {
+    ReactPerf.enableMeasure = false;
+  },
+
+  getLastMeasurements: function() {
+    return ReactDefaultPerf._allMeasurements;
+  },
+
+  printExclusive: function(measurements) {
+    measurements = measurements || ReactDefaultPerf._allMeasurements;
+    var summary = ReactDefaultPerfAnalysis.getExclusiveSummary(measurements);
+    console.table(summary.map(function(item) {
+      return {
+        'Component class name': item.componentName,
+        'Total inclusive time (ms)': roundFloat(item.inclusive),
+        'Total exclusive time (ms)': roundFloat(item.exclusive),
+        'Exclusive time per instance (ms)': roundFloat(item.exclusive / item.count),
+        'Instances': item.count
+      };
+    }));
+    console.log(
+      'Total time:',
+      ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'
+    );
+  },
+
+  printInclusive: function(measurements) {
+    measurements = measurements || ReactDefaultPerf._allMeasurements;
+    var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements);
+    console.table(summary.map(function(item) {
+      return {
+        'Owner > component': item.componentName,
+        'Inclusive time (ms)': roundFloat(item.time),
+        'Instances': item.count
+      };
+    }));
+    console.log(
+      'Total time:',
+      ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'
+    );
+  },
+
+  printWasted: function(measurements) {
+    measurements = measurements || ReactDefaultPerf._allMeasurements;
+    var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(
+      measurements,
+      true
+    );
+    console.table(summary.map(function(item) {
+      return {
+        'Owner > component': item.componentName,
+        'Wasted time (ms)': item.time,
+        'Instances': item.count
+      };
+    }));
+    console.log(
+      'Total time:',
+      ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'
+    );
+  },
+
+  printDOM: function(measurements) {
+    measurements = measurements || ReactDefaultPerf._allMeasurements;
+    var summary = ReactDefaultPerfAnalysis.getDOMSummary(measurements);
+    console.table(summary.map(function(item) {
+      var result = {};
+      result[DOMProperty.ID_ATTRIBUTE_NAME] = item.id;
+      result['type'] = item.type;
+      result['args'] = JSON.stringify(item.args);
+      return result;
+    }));
+    console.log(
+      'Total time:',
+      ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'
+    );
+  },
+
+  _recordWrite: function(id, fnName, totalTime, args) {
+    // TODO: totalTime isn't that useful since it doesn't count paints/reflows
+    var writes =
+      ReactDefaultPerf
+        ._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1]
+        .writes;
+    writes[id] = writes[id] || [];
+    writes[id].push({
+      type: fnName,
+      time: totalTime,
+      args: args
+    });
+  },
+
+  measure: function(moduleName, fnName, func) {
+    return function() {var args=Array.prototype.slice.call(arguments,0);
+      var totalTime;
+      var rv;
+      var start;
+
+      if (fnName === '_renderNewRootComponent' ||
+          fnName === 'flushBatchedUpdates') {
+        // A "measurement" is a set of metrics recorded for each flush. We want
+        // to group the metrics for a given flush together so we can look at the
+        // components that rendered and the DOM operations that actually
+        // happened to determine the amount of "wasted work" performed.
+        ReactDefaultPerf._allMeasurements.push({
+          exclusive: {},
+          inclusive: {},
+          counts: {},
+          writes: {},
+          displayNames: {},
+          totalTime: 0
+        });
+        start = performanceNow();
+        rv = func.apply(this, args);
+        ReactDefaultPerf._allMeasurements[
+          ReactDefaultPerf._allMeasurements.length - 1
+        ].totalTime = performanceNow() - start;
+        return rv;
+      } else if (moduleName === 'ReactDOMIDOperations' ||
+        moduleName === 'ReactComponentBrowserEnvironment') {
+        start = performanceNow();
+        rv = func.apply(this, args);
+        totalTime = performanceNow() - start;
+
+        if (fnName === 'mountImageIntoNode') {
+          var mountID = ReactMount.getID(args[1]);
+          ReactDefaultPerf._recordWrite(mountID, fnName, totalTime, args[0]);
+        } else if (fnName === 'dangerouslyProcessChildrenUpdates') {
+          // special format
+          args[0].forEach(function(update) {
+            var writeArgs = {};
+            if (update.fromIndex !== null) {
+              writeArgs.fromIndex = update.fromIndex;
+            }
+            if (update.toIndex !== null) {
+              writeArgs.toIndex = update.toIndex;
+            }
+            if (update.textContent !== null) {
+              writeArgs.textContent = update.textContent;
+            }
+            if (update.markupIndex !== null) {
+              writeArgs.markup = args[1][update.markupIndex];
+            }
+            ReactDefaultPerf._recordWrite(
+              update.parentID,
+              update.type,
+              totalTime,
+              writeArgs
+            );
+          });
+        } else {
+          // basic format
+          ReactDefaultPerf._recordWrite(
+            args[0],
+            fnName,
+            totalTime,
+            Array.prototype.slice.call(args, 1)
+          );
+        }
+        return rv;
+      } else if (moduleName === 'ReactCompositeComponent' && (
+        fnName === 'mountComponent' ||
+        fnName === 'updateComponent' || // TODO: receiveComponent()?
+        fnName === '_renderValidatedComponent')) {
+
+        var rootNodeID = fnName === 'mountComponent' ?
+          args[0] :
+          this._rootNodeID;
+        var isRender = fnName === '_renderValidatedComponent';
+        var entry = ReactDefaultPerf._allMeasurements[
+          ReactDefaultPerf._allMeasurements.length - 1
+        ];
+
+        if (isRender) {
+          entry.counts[rootNodeID] = entry.counts[rootNodeID] || 0;
+          entry.counts[rootNodeID] += 1;
+        }
+
+        start = performanceNow();
+        rv = func.apply(this, args);
+        totalTime = performanceNow() - start;
+
+        var typeOfLog = isRender ? entry.exclusive : entry.inclusive;
+        typeOfLog[rootNodeID] = typeOfLog[rootNodeID] || 0;
+        typeOfLog[rootNodeID] += totalTime;
+
+        entry.displayNames[rootNodeID] = {
+          current: this.constructor.displayName,
+          owner: this._owner ? this._owner.constructor.displayName : '<root>'
+        };
+
+        return rv;
+      } else {
+        return func.apply(this, args);
+      }
+    };
+  }
+};
+
+module.exports = ReactDefaultPerf;
+
+},{"./DOMProperty":8,"./ReactDefaultPerfAnalysis":46,"./ReactMount":55,"./ReactPerf":60,"./performanceNow":124}],46:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactDefaultPerfAnalysis
+ */
+
+var merge = require("./merge");
+
+// Don't try to save users less than 1.2ms (a number I made up)
+var DONT_CARE_THRESHOLD = 1.2;
+var DOM_OPERATION_TYPES = {
+  'mountImageIntoNode': 'set innerHTML',
+  INSERT_MARKUP: 'set innerHTML',
+  MOVE_EXISTING: 'move',
+  REMOVE_NODE: 'remove',
+  TEXT_CONTENT: 'set textContent',
+  'updatePropertyByID': 'update attribute',
+  'deletePropertyByID': 'delete attribute',
+  'updateStylesByID': 'update styles',
+  'updateInnerHTMLByID': 'set innerHTML',
+  'dangerouslyReplaceNodeWithMarkupByID': 'replace'
+};
+
+function getTotalTime(measurements) {
+  // TODO: return number of DOM ops? could be misleading.
+  // TODO: measure dropped frames after reconcile?
+  // TODO: log total time of each reconcile and the top-level component
+  // class that triggered it.
+  var totalTime = 0;
+  for (var i = 0; i < measurements.length; i++) {
+    var measurement = measurements[i];
+    totalTime += measurement.totalTime;
+  }
+  return totalTime;
+}
+
+function getDOMSummary(measurements) {
+  var items = [];
+  for (var i = 0; i < measurements.length; i++) {
+    var measurement = measurements[i];
+    var id;
+
+    for (id in measurement.writes) {
+      measurement.writes[id].forEach(function(write) {
+        items.push({
+          id: id,
+          type: DOM_OPERATION_TYPES[write.type] || write.type,
+          args: write.args
+        });
+      });
+    }
+  }
+  return items;
+}
+
+function getExclusiveSummary(measurements) {
+  var candidates = {};
+  var displayName;
+
+  for (var i = 0; i < measurements.length; i++) {
+    var measurement = measurements[i];
+    var allIDs = merge(measurement.exclusive, measurement.inclusive);
+
+    for (var id in allIDs) {
+      displayName = measurement.displayNames[id].current;
+
+      candidates[displayName] = candidates[displayName] || {
+        componentName: displayName,
+        inclusive: 0,
+        exclusive: 0,
+        count: 0
+      };
+      if (measurement.exclusive[id]) {
+        candidates[displayName].exclusive += measurement.exclusive[id];
+      }
+      if (measurement.inclusive[id]) {
+        candidates[displayName].inclusive += measurement.inclusive[id];
+      }
+      if (measurement.counts[id]) {
+        candidates[displayName].count += measurement.counts[id];
+      }
+    }
+  }
+
+  // Now make a sorted array with the results.
+  var arr = [];
+  for (displayName in candidates) {
+    if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) {
+      arr.push(candidates[displayName]);
+    }
+  }
+
+  arr.sort(function(a, b) {
+    return b.exclusive - a.exclusive;
+  });
+
+  return arr;
+}
+
+function getInclusiveSummary(measurements, onlyClean) {
+  var candidates = {};
+  var inclusiveKey;
+
+  for (var i = 0; i < measurements.length; i++) {
+    var measurement = measurements[i];
+    var allIDs = merge(measurement.exclusive, measurement.inclusive);
+    var cleanComponents;
+
+    if (onlyClean) {
+      cleanComponents = getUnchangedComponents(measurement);
+    }
+
+    for (var id in allIDs) {
+      if (onlyClean && !cleanComponents[id]) {
+        continue;
+      }
+
+      var displayName = measurement.displayNames[id];
+
+      // Inclusive time is not useful for many components without knowing where
+      // they are instantiated. So we aggregate inclusive time with both the
+      // owner and current displayName as the key.
+      inclusiveKey = displayName.owner + ' > ' + displayName.current;
+
+      candidates[inclusiveKey] = candidates[inclusiveKey] || {
+        componentName: inclusiveKey,
+        time: 0,
+        count: 0
+      };
+
+      if (measurement.inclusive[id]) {
+        candidates[inclusiveKey].time += measurement.inclusive[id];
+      }
+      if (measurement.counts[id]) {
+        candidates[inclusiveKey].count += measurement.counts[id];
+      }
+    }
+  }
+
+  // Now make a sorted array with the results.
+  var arr = [];
+  for (inclusiveKey in candidates) {
+    if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) {
+      arr.push(candidates[inclusiveKey]);
+    }
+  }
+
+  arr.sort(function(a, b) {
+    return b.time - a.time;
+  });
+
+  return arr;
+}
+
+function getUnchangedComponents(measurement) {
+  // For a given reconcile, look at which components did not actually
+  // render anything to the DOM and return a mapping of their ID to
+  // the amount of time it took to render the entire subtree.
+  var cleanComponents = {};
+  var dirtyLeafIDs = Object.keys(measurement.writes);
+  var allIDs = merge(measurement.exclusive, measurement.inclusive);
+
+  for (var id in allIDs) {
+    var isDirty = false;
+    // For each component that rendered, see if a component that triggerd
+    // a DOM op is in its subtree.
+    for (var i = 0; i < dirtyLeafIDs.length; i++) {
+      if (dirtyLeafIDs[i].indexOf(id) === 0) {
+        isDirty = true;
+        break;
+      }
+    }
+    if (!isDirty && measurement.counts[id] > 0) {
+      cleanComponents[id] = true;
+    }
+  }
+  return cleanComponents;
+}
+
+var ReactDefaultPerfAnalysis = {
+  getExclusiveSummary: getExclusiveSummary,
+  getInclusiveSummary: getInclusiveSummary,
+  getDOMSummary: getDOMSummary,
+  getTotalTime: getTotalTime
+};
+
+module.exports = ReactDefaultPerfAnalysis;
+
+},{"./merge":117}],47:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactErrorUtils
+ * @typechecks
+ */
+
+"use strict";
+
+var ReactErrorUtils = {
+  /**
+   * Creates a guarded version of a function. This is supposed to make debugging
+   * of event handlers easier. To aid debugging with the browser's debugger,
+   * this currently simply returns the original function.
+   *
+   * @param {function} func Function to be executed
+   * @param {string} name The name of the guard
+   * @return {function}
+   */
+  guard: function(func, name) {
+    return func;
+  }
+};
+
+module.exports = ReactErrorUtils;
+
+},{}],48:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactEventEmitter
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var EventConstants = require("./EventConstants");
+var EventListener = require("./EventListener");
+var EventPluginHub = require("./EventPluginHub");
+var EventPluginRegistry = require("./EventPluginRegistry");
+var ExecutionEnvironment = require("./ExecutionEnvironment");
+var ReactEventEmitterMixin = require("./ReactEventEmitterMixin");
+var ViewportMetrics = require("./ViewportMetrics");
+
+var invariant = require("./invariant");
+var isEventSupported = require("./isEventSupported");
+var merge = require("./merge");
+
+/**
+ * Summary of `ReactEventEmitter` event handling:
+ *
+ *  - Top-level delegation is used to trap native browser events. We normalize
+ *    and de-duplicate events to account for browser quirks.
+ *
+ *  - Forward these native events (with the associated top-level type used to
+ *    trap it) to `EventPluginHub`, which in turn will ask plugins if they want
+ *    to extract any synthetic events.
+ *
+ *  - The `EventPluginHub` will then process each event by annotating them with
+ *    "dispatches", a sequence of listeners and IDs that care about that event.
+ *
+ *  - The `EventPluginHub` then dispatches the events.
+ *
+ * Overview of React and the event system:
+ *
+ *                   .
+ * +------------+    .
+ * |    DOM     |    .
+ * +------------+    .                         +-----------+
+ *       +           .               +--------+|SimpleEvent|
+ *       |           .               |         |Plugin     |
+ * +-----|------+    .               v         +-----------+
+ * |     |      |    .    +--------------+                    +------------+
+ * |     +-----------.--->|EventPluginHub|                    |    Event   |
+ * |            |    .    |              |     +-----------+  | Propagators|
+ * | ReactEvent |    .    |              |     |TapEvent   |  |------------|
+ * |  Emitter   |    .    |              |<---+|Plugin     |  |other plugin|
+ * |            |    .    |              |     +-----------+  |  utilities |
+ * |     +-----------.--->|              |                    +------------+
+ * |     |      |    .    +--------------+
+ * +-----|------+    .                ^        +-----------+
+ *       |           .                |        |Enter/Leave|
+ *       +           .                +-------+|Plugin     |
+ * +-------------+   .                         +-----------+
+ * | application |   .
+ * |-------------|   .
+ * |             |   .
+ * |             |   .
+ * +-------------+   .
+ *                   .
+ *    React Core     .  General Purpose Event Plugin System
+ */
+
+var alreadyListeningTo = {};
+var isMonitoringScrollValue = false;
+var reactTopListenersCounter = 0;
+
+// For events like 'submit' which don't consistently bubble (which we trap at a
+// lower node than `document`), binding at `document` would cause duplicate
+// events so we don't include them here
+var topEventMapping = {
+  topBlur: 'blur',
+  topChange: 'change',
+  topClick: 'click',
+  topCompositionEnd: 'compositionend',
+  topCompositionStart: 'compositionstart',
+  topCompositionUpdate: 'compositionupdate',
+  topContextMenu: 'contextmenu',
+  topCopy: 'copy',
+  topCut: 'cut',
+  topDoubleClick: 'dblclick',
+  topDrag: 'drag',
+  topDragEnd: 'dragend',
+  topDragEnter: 'dragenter',
+  topDragExit: 'dragexit',
+  topDragLeave: 'dragleave',
+  topDragOver: 'dragover',
+  topDragStart: 'dragstart',
+  topDrop: 'drop',
+  topFocus: 'focus',
+  topInput: 'input',
+  topKeyDown: 'keydown',
+  topKeyPress: 'keypress',
+  topKeyUp: 'keyup',
+  topMouseDown: 'mousedown',
+  topMouseMove: 'mousemove',
+  topMouseOut: 'mouseout',
+  topMouseOver: 'mouseover',
+  topMouseUp: 'mouseup',
+  topPaste: 'paste',
+  topScroll: 'scroll',
+  topSelectionChange: 'selectionchange',
+  topTouchCancel: 'touchcancel',
+  topTouchEnd: 'touchend',
+  topTouchMove: 'touchmove',
+  topTouchStart: 'touchstart',
+  topWheel: 'wheel'
+};
+
+/**
+ * To ensure no conflicts with other potential React instances on the page
+ */
+var topListenersIDKey = "_reactListenersID" + String(Math.random()).slice(2);
+
+function getListeningForDocument(mountAt) {
+  if (mountAt[topListenersIDKey] == null) {
+    mountAt[topListenersIDKey] = reactTopListenersCounter++;
+    alreadyListeningTo[mountAt[topListenersIDKey]] = {};
+  }
+  return alreadyListeningTo[mountAt[topListenersIDKey]];
+}
+
+/**
+ * Traps top-level events by using event bubbling.
+ *
+ * @param {string} topLevelType Record from `EventConstants`.
+ * @param {string} handlerBaseName Event name (e.g. "click").
+ * @param {DOMEventTarget} element Element on which to attach listener.
+ * @internal
+ */
+function trapBubbledEvent(topLevelType, handlerBaseName, element) {
+  EventListener.listen(
+    element,
+    handlerBaseName,
+    ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback(
+      topLevelType
+    )
+  );
+}
+
+/**
+ * Traps a top-level event by using event capturing.
+ *
+ * @param {string} topLevelType Record from `EventConstants`.
+ * @param {string} handlerBaseName Event name (e.g. "click").
+ * @param {DOMEventTarget} element Element on which to attach listener.
+ * @internal
+ */
+function trapCapturedEvent(topLevelType, handlerBaseName, element) {
+  EventListener.capture(
+    element,
+    handlerBaseName,
+    ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback(
+      topLevelType
+    )
+  );
+}
+
+/**
+ * `ReactEventEmitter` is used to attach top-level event listeners. For example:
+ *
+ *   ReactEventEmitter.putListener('myID', 'onClick', myFunction);
+ *
+ * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'.
+ *
+ * @internal
+ */
+var ReactEventEmitter = merge(ReactEventEmitterMixin, {
+
+  /**
+   * React references `ReactEventTopLevelCallback` using this property in order
+   * to allow dependency injection.
+   */
+  TopLevelCallbackCreator: null,
+
+  injection: {
+    /**
+     * @param {function} TopLevelCallbackCreator
+     */
+    injectTopLevelCallbackCreator: function(TopLevelCallbackCreator) {
+      ReactEventEmitter.TopLevelCallbackCreator = TopLevelCallbackCreator;
+    }
+  },
+
+  /**
+   * Sets whether or not any created callbacks should be enabled.
+   *
+   * @param {boolean} enabled True if callbacks should be enabled.
+   */
+  setEnabled: function(enabled) {
+    ("production" !== "development" ? invariant(
+      ExecutionEnvironment.canUseDOM,
+      'setEnabled(...): Cannot toggle event listening in a Worker thread. ' +
+      'This is likely a bug in the framework. Please report immediately.'
+    ) : invariant(ExecutionEnvironment.canUseDOM));
+    if (ReactEventEmitter.TopLevelCallbackCreator) {
+      ReactEventEmitter.TopLevelCallbackCreator.setEnabled(enabled);
+    }
+  },
+
+  /**
+   * @return {boolean} True if callbacks are enabled.
+   */
+  isEnabled: function() {
+    return !!(
+      ReactEventEmitter.TopLevelCallbackCreator &&
+      ReactEventEmitter.TopLevelCallbackCreator.isEnabled()
+    );
+  },
+
+  /**
+   * We listen for bubbled touch events on the document object.
+   *
+   * Firefox v8.01 (and possibly others) exhibited strange behavior when
+   * mounting `onmousemove` events at some node that was not the document
+   * element. The symptoms were that if your mouse is not moving over something
+   * contained within that mount point (for example on the background) the
+   * top-level listeners for `onmousemove` won't be called. However, if you
+   * register the `mousemove` on the document object, then it will of course
+   * catch all `mousemove`s. This along with iOS quirks, justifies restricting
+   * top-level listeners to the document object only, at least for these
+   * movement types of events and possibly all events.
+   *
+   * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
+   *
+   * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
+   * they bubble to document.
+   *
+   * @param {string} registrationName Name of listener (e.g. `onClick`).
+   * @param {DOMDocument} contentDocument Document which owns the container
+   */
+  listenTo: function(registrationName, contentDocument) {
+    var mountAt = contentDocument;
+    var isListening = getListeningForDocument(mountAt);
+    var dependencies = EventPluginRegistry.
+      registrationNameDependencies[registrationName];
+
+    var topLevelTypes = EventConstants.topLevelTypes;
+    for (var i = 0, l = dependencies.length; i < l; i++) {
+      var dependency = dependencies[i];
+      if (!isListening[dependency]) {
+        var topLevelType = topLevelTypes[dependency];
+
+        if (topLevelType === topLevelTypes.topWheel) {
+          if (isEventSupported('wheel')) {
+            trapBubbledEvent(topLevelTypes.topWheel, 'wheel', mountAt);
+          } else if (isEventSupported('mousewheel')) {
+            trapBubbledEvent(topLevelTypes.topWheel, 'mousewheel', mountAt);
+          } else {
+            // Firefox needs to capture a different mouse scroll event.
+            // @see http://www.quirksmode.org/dom/events/tests/scroll.html
+            trapBubbledEvent(
+              topLevelTypes.topWheel,
+              'DOMMouseScroll',
+              mountAt);
+          }
+        } else if (topLevelType === topLevelTypes.topScroll) {
+
+          if (isEventSupported('scroll', true)) {
+            trapCapturedEvent(topLevelTypes.topScroll, 'scroll', mountAt);
+          } else {
+            trapBubbledEvent(topLevelTypes.topScroll, 'scroll', window);
+          }
+        } else if (topLevelType === topLevelTypes.topFocus ||
+            topLevelType === topLevelTypes.topBlur) {
+
+          if (isEventSupported('focus', true)) {
+            trapCapturedEvent(topLevelTypes.topFocus, 'focus', mountAt);
+            trapCapturedEvent(topLevelTypes.topBlur, 'blur', mountAt);
+          } else if (isEventSupported('focusin')) {
+            // IE has `focusin` and `focusout` events which bubble.
+            // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
+            trapBubbledEvent(topLevelTypes.topFocus, 'focusin', mountAt);
+            trapBubbledEvent(topLevelTypes.topBlur, 'focusout', mountAt);
+          }
+
+          // to make sure blur and focus event listeners are only attached once
+          isListening[topLevelTypes.topBlur] = true;
+          isListening[topLevelTypes.topFocus] = true;
+        } else if (topEventMapping[dependency]) {
+          trapBubbledEvent(topLevelType, topEventMapping[dependency], mountAt);
+        }
+
+        isListening[dependency] = true;
+      }
+    }
+  },
+
+  /**
+   * Listens to window scroll and resize events. We cache scroll values so that
+   * application code can access them without triggering reflows.
+   *
+   * NOTE: Scroll events do not bubble.
+   *
+   * @see http://www.quirksmode.org/dom/events/scroll.html
+   */
+  ensureScrollValueMonitoring: function(){
+    if (!isMonitoringScrollValue) {
+      var refresh = ViewportMetrics.refreshScrollValues;
+      EventListener.listen(window, 'scroll', refresh);
+      EventListener.listen(window, 'resize', refresh);
+      isMonitoringScrollValue = true;
+    }
+  },
+
+  eventNameDispatchConfigs: EventPluginHub.eventNameDispatchConfigs,
+
+  registrationNameModules: EventPluginHub.registrationNameModules,
+
+  putListener: EventPluginHub.putListener,
+
+  getListener: EventPluginHub.getListener,
+
+  deleteListener: EventPluginHub.deleteListener,
+
+  deleteAllListeners: EventPluginHub.deleteAllListeners,
+
+  trapBubbledEvent: trapBubbledEvent,
+
+  trapCapturedEvent: trapCapturedEvent
+
+});
+
+module.exports = ReactEventEmitter;
+
+},{"./EventConstants":14,"./EventListener":15,"./EventPluginHub":16,"./EventPluginRegistry":17,"./ExecutionEnvironment":20,"./ReactEventEmitterMixin":49,"./ViewportMetrics":85,"./invariant":108,"./isEventSupported":109,"./merge":117}],49:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactEventEmitterMixin
+ */
+
+"use strict";
+
+var EventPluginHub = require("./EventPluginHub");
+var ReactUpdates = require("./ReactUpdates");
+
+function runEventQueueInBatch(events) {
+  EventPluginHub.enqueueEvents(events);
+  EventPluginHub.processEventQueue();
+}
+
+var ReactEventEmitterMixin = {
+
+  /**
+   * Streams a fired top-level event to `EventPluginHub` where plugins have the
+   * opportunity to create `ReactEvent`s to be dispatched.
+   *
+   * @param {string} topLevelType Record from `EventConstants`.
+   * @param {object} topLevelTarget The listening component root node.
+   * @param {string} topLevelTargetID ID of `topLevelTarget`.
+   * @param {object} nativeEvent Native environment event.
+   */
+  handleTopLevel: function(
+      topLevelType,
+      topLevelTarget,
+      topLevelTargetID,
+      nativeEvent) {
+    var events = EventPluginHub.extractEvents(
+      topLevelType,
+      topLevelTarget,
+      topLevelTargetID,
+      nativeEvent
+    );
+
+    // Event queue being processed in the same cycle allows `preventDefault`.
+    ReactUpdates.batchedUpdates(runEventQueueInBatch, events);
+  }
+};
+
+module.exports = ReactEventEmitterMixin;
+
+},{"./EventPluginHub":16,"./ReactUpdates":70}],50:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactEventTopLevelCallback
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var PooledClass = require("./PooledClass");
+var ReactEventEmitter = require("./ReactEventEmitter");
+var ReactInstanceHandles = require("./ReactInstanceHandles");
+var ReactMount = require("./ReactMount");
+
+var getEventTarget = require("./getEventTarget");
+var mixInto = require("./mixInto");
+
+/**
+ * @type {boolean}
+ * @private
+ */
+var _topLevelListenersEnabled = true;
+
+/**
+ * Finds the parent React component of `node`.
+ *
+ * @param {*} node
+ * @return {?DOMEventTarget} Parent container, or `null` if the specified node
+ *                           is not nested.
+ */
+function findParent(node) {
+  // TODO: It may be a good idea to cache this to prevent unnecessary DOM
+  // traversal, but caching is difficult to do correctly without using a
+  // mutation observer to listen for all DOM changes.
+  var nodeID = ReactMount.getID(node);
+  var rootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID);
+  var container = ReactMount.findReactContainerForID(rootID);
+  var parent = ReactMount.getFirstReactDOM(container);
+  return parent;
+}
+
+/**
+ * Calls ReactEventEmitter.handleTopLevel for each node stored in bookKeeping's
+ * ancestor list. Separated from createTopLevelCallback to avoid try/finally
+ * deoptimization.
+ *
+ * @param {string} topLevelType
+ * @param {DOMEvent} nativeEvent
+ * @param {TopLevelCallbackBookKeeping} bookKeeping
+ */
+function handleTopLevelImpl(topLevelType, nativeEvent, bookKeeping) {
+  var topLevelTarget = ReactMount.getFirstReactDOM(
+    getEventTarget(nativeEvent)
+  ) || window;
+
+  // Loop through the hierarchy, in case there's any nested components.
+  // It's important that we build the array of ancestors before calling any
+  // event handlers, because event handlers can modify the DOM, leading to
+  // inconsistencies with ReactMount's node cache. See #1105.
+  var ancestor = topLevelTarget;
+  while (ancestor) {
+    bookKeeping.ancestors.push(ancestor);
+    ancestor = findParent(ancestor);
+  }
+
+  for (var i = 0, l = bookKeeping.ancestors.length; i < l; i++) {
+    topLevelTarget = bookKeeping.ancestors[i];
+    var topLevelTargetID = ReactMount.getID(topLevelTarget) || '';
+    ReactEventEmitter.handleTopLevel(
+      topLevelType,
+      topLevelTarget,
+      topLevelTargetID,
+      nativeEvent
+    );
+  }
+}
+
+// Used to store ancestor hierarchy in top level callback
+function TopLevelCallbackBookKeeping() {
+  this.ancestors = [];
+}
+mixInto(TopLevelCallbackBookKeeping, {
+  destructor: function() {
+    this.ancestors.length = 0;
+  }
+});
+PooledClass.addPoolingTo(TopLevelCallbackBookKeeping);
+
+/**
+ * Top-level callback creator used to implement event handling using delegation.
+ * This is used via dependency injection.
+ */
+var ReactEventTopLevelCallback = {
+
+  /**
+   * Sets whether or not any created callbacks should be enabled.
+   *
+   * @param {boolean} enabled True if callbacks should be enabled.
+   */
+  setEnabled: function(enabled) {
+    _topLevelListenersEnabled = !!enabled;
+  },
+
+  /**
+   * @return {boolean} True if callbacks are enabled.
+   */
+  isEnabled: function() {
+    return _topLevelListenersEnabled;
+  },
+
+  /**
+   * Creates a callback for the supplied `topLevelType` that could be added as
+   * a listener to the document. The callback computes a `topLevelTarget` which
+   * should be the root node of a mounted React component where the listener
+   * is attached.
+   *
+   * @param {string} topLevelType Record from `EventConstants`.
+   * @return {function} Callback for handling top-level events.
+   */
+  createTopLevelCallback: function(topLevelType) {
+    return function(nativeEvent) {
+      if (!_topLevelListenersEnabled) {
+        return;
+      }
+
+      var bookKeeping = TopLevelCallbackBookKeeping.getPooled();
+      try {
+        handleTopLevelImpl(topLevelType, nativeEvent, bookKeeping);
+      } finally {
+        TopLevelCallbackBookKeeping.release(bookKeeping);
+      }
+    };
+  }
+
+};
+
+module.exports = ReactEventTopLevelCallback;
+
+},{"./PooledClass":23,"./ReactEventEmitter":48,"./ReactInstanceHandles":53,"./ReactMount":55,"./getEventTarget":101,"./mixInto":120}],51:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactInjection
+ */
+
+"use strict";
+
+var DOMProperty = require("./DOMProperty");
+var EventPluginHub = require("./EventPluginHub");
+var ReactDOM = require("./ReactDOM");
+var ReactEventEmitter = require("./ReactEventEmitter");
+var ReactPerf = require("./ReactPerf");
+var ReactRootIndex = require("./ReactRootIndex");
+var ReactUpdates = require("./ReactUpdates");
+
+var ReactInjection = {
+  DOMProperty: DOMProperty.injection,
+  EventPluginHub: EventPluginHub.injection,
+  DOM: ReactDOM.injection,
+  EventEmitter: ReactEventEmitter.injection,
+  Perf: ReactPerf.injection,
+  RootIndex: ReactRootIndex.injection,
+  Updates: ReactUpdates.injection
+};
+
+module.exports = ReactInjection;
+
+},{"./DOMProperty":8,"./EventPluginHub":16,"./ReactDOM":32,"./ReactEventEmitter":48,"./ReactPerf":60,"./ReactRootIndex":67,"./ReactUpdates":70}],52:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactInputSelection
+ */
+
+"use strict";
+
+var ReactDOMSelection = require("./ReactDOMSelection");
+
+var containsNode = require("./containsNode");
+var getActiveElement = require("./getActiveElement");
+
+function isInDocument(node) {
+  return containsNode(document.documentElement, node);
+}
+
+/**
+ * @ReactInputSelection: React input selection module. Based on Selection.js,
+ * but modified to be suitable for react and has a couple of bug fixes (doesn't
+ * assume buttons have range selections allowed).
+ * Input selection module for React.
+ */
+var ReactInputSelection = {
+
+  hasSelectionCapabilities: function(elem) {
+    return elem && (
+      (elem.nodeName === 'INPUT' && elem.type === 'text') ||
+      elem.nodeName === 'TEXTAREA' ||
+      elem.contentEditable === 'true'
+    );
+  },
+
+  getSelectionInformation: function() {
+    var focusedElem = getActiveElement();
+    return {
+      focusedElem: focusedElem,
+      selectionRange:
+          ReactInputSelection.hasSelectionCapabilities(focusedElem) ?
+          ReactInputSelection.getSelection(focusedElem) :
+          null
+    };
+  },
+
+  /**
+   * @restoreSelection: If any selection information was potentially lost,
+   * restore it. This is useful when performing operations that could remove dom
+   * nodes and place them back in, resulting in focus being lost.
+   */
+  restoreSelection: function(priorSelectionInformation) {
+    var curFocusedElem = getActiveElement();
+    var priorFocusedElem = priorSelectionInformation.focusedElem;
+    var priorSelectionRange = priorSelectionInformation.selectionRange;
+    if (curFocusedElem !== priorFocusedElem &&
+        isInDocument(priorFocusedElem)) {
+      if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) {
+        ReactInputSelection.setSelection(
+          priorFocusedElem,
+          priorSelectionRange
+        );
+      }
+      priorFocusedElem.focus();
+    }
+  },
+
+  /**
+   * @getSelection: Gets the selection bounds of a focused textarea, input or
+   * contentEditable node.
+   * - at input: Look up selection bounds of this input
+   * - at return {start: selectionStart, end: selectionEnd}
+   */
+  getSelection: function(input) {
+    var selection;
+
+    if ('selectionStart' in input) {
+      // Modern browser with input or textarea.
+      selection = {
+        start: input.selectionStart,
+        end: input.selectionEnd
+      };
+    } else if (document.selection && input.nodeName === 'INPUT') {
+      // IE8 input.
+      var range = document.selection.createRange();
+      // There can only be one selection per document in IE, so it must
+      // be in our element.
+      if (range.parentElement() === input) {
+        selection = {
+          start: -range.moveStart('character', -input.value.length),
+          end: -range.moveEnd('character', -input.value.length)
+        };
+      }
+    } else {
+      // Content editable or old IE textarea.
+      selection = ReactDOMSelection.getOffsets(input);
+    }
+
+    return selection || {start: 0, end: 0};
+  },
+
+  /**
+   * @setSelection: Sets the selection bounds of a textarea or input and focuses
+   * the input.
+   * - at input     Set selection bounds of this input or textarea
+   * - at offsets   Object of same form that is returned from get*
+   */
+  setSelection: function(input, offsets) {
+    var start = offsets.start;
+    var end = offsets.end;
+    if (typeof end === 'undefined') {
+      end = start;
+    }
+
+    if ('selectionStart' in input) {
+      input.selectionStart = start;
+      input.selectionEnd = Math.min(end, input.value.length);
+    } else if (document.selection && input.nodeName === 'INPUT') {
+      var range = input.createTextRange();
+      range.collapse(true);
+      range.moveStart('character', start);
+      range.moveEnd('character', end - start);
+      range.select();
+    } else {
+      ReactDOMSelection.setOffsets(input, offsets);
+    }
+  }
+};
+
+module.exports = ReactInputSelection;
+
+},{"./ReactDOMSelection":41,"./containsNode":88,"./getActiveElement":99}],53:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactInstanceHandles
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var ReactRootIndex = require("./ReactRootIndex");
+
+var invariant = require("./invariant");
+
+var SEPARATOR = '.';
+var SEPARATOR_LENGTH = SEPARATOR.length;
+
+/**
+ * Maximum depth of traversals before we consider the possibility of a bad ID.
+ */
+var MAX_TREE_DEPTH = 100;
+
+/**
+ * Creates a DOM ID prefix to use when mounting React components.
+ *
+ * @param {number} index A unique integer
+ * @return {string} React root ID.
+ * @internal
+ */
+function getReactRootIDString(index) {
+  return SEPARATOR + index.toString(36);
+}
+
+/**
+ * Checks if a character in the supplied ID is a separator or the end.
+ *
+ * @param {string} id A React DOM ID.
+ * @param {number} index Index of the character to check.
+ * @return {boolean} True if the character is a separator or end of the ID.
+ * @private
+ */
+function isBoundary(id, index) {
+  return id.charAt(index) === SEPARATOR || index === id.length;
+}
+
+/**
+ * Checks if the supplied string is a valid React DOM ID.
+ *
+ * @param {string} id A React DOM ID, maybe.
+ * @return {boolean} True if the string is a valid React DOM ID.
+ * @private
+ */
+function isValidID(id) {
+  return id === '' || (
+    id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR
+  );
+}
+
+/**
+ * Checks if the first ID is an ancestor of or equal to the second ID.
+ *
+ * @param {string} ancestorID
+ * @param {string} descendantID
+ * @return {boolean} True if `ancestorID` is an ancestor of `descendantID`.
+ * @internal
+ */
+function isAncestorIDOf(ancestorID, descendantID) {
+  return (
+    descendantID.indexOf(ancestorID) === 0 &&
+    isBoundary(descendantID, ancestorID.length)
+  );
+}
+
+/**
+ * Gets the parent ID of the supplied React DOM ID, `id`.
+ *
+ * @param {string} id ID of a component.
+ * @return {string} ID of the parent, or an empty string.
+ * @private
+ */
+function getParentID(id) {
+  return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : '';
+}
+
+/**
+ * Gets the next DOM ID on the tree path from the supplied `ancestorID` to the
+ * supplied `destinationID`. If they are equal, the ID is returned.
+ *
+ * @param {string} ancestorID ID of an ancestor node of `destinationID`.
+ * @param {string} destinationID ID of the destination node.
+ * @return {string} Next ID on the path from `ancestorID` to `destinationID`.
+ * @private
+ */
+function getNextDescendantID(ancestorID, destinationID) {
+  ("production" !== "development" ? invariant(
+    isValidID(ancestorID) && isValidID(destinationID),
+    'getNextDescendantID(%s, %s): Received an invalid React DOM ID.',
+    ancestorID,
+    destinationID
+  ) : invariant(isValidID(ancestorID) && isValidID(destinationID)));
+  ("production" !== "development" ? invariant(
+    isAncestorIDOf(ancestorID, destinationID),
+    'getNextDescendantID(...): React has made an invalid assumption about ' +
+    'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.',
+    ancestorID,
+    destinationID
+  ) : invariant(isAncestorIDOf(ancestorID, destinationID)));
+  if (ancestorID === destinationID) {
+    return ancestorID;
+  }
+  // Skip over the ancestor and the immediate separator. Traverse until we hit
+  // another separator or we reach the end of `destinationID`.
+  var start = ancestorID.length + SEPARATOR_LENGTH;
+  for (var i = start; i < destinationID.length; i++) {
+    if (isBoundary(destinationID, i)) {
+      break;
+    }
+  }
+  return destinationID.substr(0, i);
+}
+
+/**
+ * Gets the nearest common ancestor ID of two IDs.
+ *
+ * Using this ID scheme, the nearest common ancestor ID is the longest common
+ * prefix of the two IDs that immediately preceded a "marker" in both strings.
+ *
+ * @param {string} oneID
+ * @param {string} twoID
+ * @return {string} Nearest common ancestor ID, or the empty string if none.
+ * @private
+ */
+function getFirstCommonAncestorID(oneID, twoID) {
+  var minLength = Math.min(oneID.length, twoID.length);
+  if (minLength === 0) {
+    return '';
+  }
+  var lastCommonMarkerIndex = 0;
+  // Use `<=` to traverse until the "EOL" of the shorter string.
+  for (var i = 0; i <= minLength; i++) {
+    if (isBoundary(oneID, i) && isBoundary(twoID, i)) {
+      lastCommonMarkerIndex = i;
+    } else if (oneID.charAt(i) !== twoID.charAt(i)) {
+      break;
+    }
+  }
+  var longestCommonID = oneID.substr(0, lastCommonMarkerIndex);
+  ("production" !== "development" ? invariant(
+    isValidID(longestCommonID),
+    'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s',
+    oneID,
+    twoID,
+    longestCommonID
+  ) : invariant(isValidID(longestCommonID)));
+  return longestCommonID;
+}
+
+/**
+ * Traverses the parent path between two IDs (either up or down). The IDs must
+ * not be the same, and there must exist a parent path between them. If the
+ * callback returns `false`, traversal is stopped.
+ *
+ * @param {?string} start ID at which to start traversal.
+ * @param {?string} stop ID at which to end traversal.
+ * @param {function} cb Callback to invoke each ID with.
+ * @param {?boolean} skipFirst Whether or not to skip the first node.
+ * @param {?boolean} skipLast Whether or not to skip the last node.
+ * @private
+ */
+function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) {
+  start = start || '';
+  stop = stop || '';
+  ("production" !== "development" ? invariant(
+    start !== stop,
+    'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.',
+    start
+  ) : invariant(start !== stop));
+  var traverseUp = isAncestorIDOf(stop, start);
+  ("production" !== "development" ? invariant(
+    traverseUp || isAncestorIDOf(start, stop),
+    'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' +
+    'not have a parent path.',
+    start,
+    stop
+  ) : invariant(traverseUp || isAncestorIDOf(start, stop)));
+  // Traverse from `start` to `stop` one depth at a time.
+  var depth = 0;
+  var traverse = traverseUp ? getParentID : getNextDescendantID;
+  for (var id = start; /* until break */; id = traverse(id, stop)) {
+    var ret;
+    if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) {
+      ret = cb(id, traverseUp, arg);
+    }
+    if (ret === false || id === stop) {
+      // Only break //after// visiting `stop`.
+      break;
+    }
+    ("production" !== "development" ? invariant(
+      depth++ < MAX_TREE_DEPTH,
+      'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' +
+      'traversing the React DOM ID tree. This may be due to malformed IDs: %s',
+      start, stop
+    ) : invariant(depth++ < MAX_TREE_DEPTH));
+  }
+}
+
+/**
+ * Manages the IDs assigned to DOM representations of React components. This
+ * uses a specific scheme in order to traverse the DOM efficiently (e.g. in
+ * order to simulate events).
+ *
+ * @internal
+ */
+var ReactInstanceHandles = {
+
+  /**
+   * Constructs a React root ID
+   * @return {string} A React root ID.
+   */
+  createReactRootID: function() {
+    return getReactRootIDString(ReactRootIndex.createReactRootIndex());
+  },
+
+  /**
+   * Constructs a React ID by joining a root ID with a name.
+   *
+   * @param {string} rootID Root ID of a parent component.
+   * @param {string} name A component's name (as flattened children).
+   * @return {string} A React ID.
+   * @internal
+   */
+  createReactID: function(rootID, name) {
+    return rootID + name;
+  },
+
+  /**
+   * Gets the DOM ID of the React component that is the root of the tree that
+   * contains the React component with the supplied DOM ID.
+   *
+   * @param {string} id DOM ID of a React component.
+   * @return {?string} DOM ID of the React component that is the root.
+   * @internal
+   */
+  getReactRootIDFromNodeID: function(id) {
+    if (id && id.charAt(0) === SEPARATOR && id.length > 1) {
+      var index = id.indexOf(SEPARATOR, 1);
+      return index > -1 ? id.substr(0, index) : id;
+    }
+    return null;
+  },
+
+  /**
+   * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
+   * should would receive a `mouseEnter` or `mouseLeave` event.
+   *
+   * NOTE: Does not invoke the callback on the nearest common ancestor because
+   * nothing "entered" or "left" that element.
+   *
+   * @param {string} leaveID ID being left.
+   * @param {string} enterID ID being entered.
+   * @param {function} cb Callback to invoke on each entered/left ID.
+   * @param {*} upArg Argument to invoke the callback with on left IDs.
+   * @param {*} downArg Argument to invoke the callback with on entered IDs.
+   * @internal
+   */
+  traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) {
+    var ancestorID = getFirstCommonAncestorID(leaveID, enterID);
+    if (ancestorID !== leaveID) {
+      traverseParentPath(leaveID, ancestorID, cb, upArg, false, true);
+    }
+    if (ancestorID !== enterID) {
+      traverseParentPath(ancestorID, enterID, cb, downArg, true, false);
+    }
+  },
+
+  /**
+   * Simulates the traversal of a two-phase, capture/bubble event dispatch.
+   *
+   * NOTE: This traversal happens on IDs without touching the DOM.
+   *
+   * @param {string} targetID ID of the target node.
+   * @param {function} cb Callback to invoke.
+   * @param {*} arg Argument to invoke the callback with.
+   * @internal
+   */
+  traverseTwoPhase: function(targetID, cb, arg) {
+    if (targetID) {
+      traverseParentPath('', targetID, cb, arg, true, false);
+      traverseParentPath(targetID, '', cb, arg, false, true);
+    }
+  },
+
+  /**
+   * Traverse a node ID, calling the supplied `cb` for each ancestor ID. For
+   * example, passing `.0.$row-0.1` would result in `cb` getting called
+   * with `.0`, `.0.$row-0`, and `.0.$row-0.1`.
+   *
+   * NOTE: This traversal happens on IDs without touching the DOM.
+   *
+   * @param {string} targetID ID of the target node.
+   * @param {function} cb Callback to invoke.
+   * @param {*} arg Argument to invoke the callback with.
+   * @internal
+   */
+  traverseAncestors: function(targetID, cb, arg) {
+    traverseParentPath('', targetID, cb, arg, true, false);
+  },
+
+  /**
+   * Exposed for unit testing.
+   * @private
+   */
+  _getFirstCommonAncestorID: getFirstCommonAncestorID,
+
+  /**
+   * Exposed for unit testing.
+   * @private
+   */
+  _getNextDescendantID: getNextDescendantID,
+
+  isAncestorIDOf: isAncestorIDOf,
+
+  SEPARATOR: SEPARATOR
+
+};
+
+module.exports = ReactInstanceHandles;
+
+},{"./ReactRootIndex":67,"./invariant":108}],54:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactMarkupChecksum
+ */
+
+"use strict";
+
+var adler32 = require("./adler32");
+
+var ReactMarkupChecksum = {
+  CHECKSUM_ATTR_NAME: 'data-react-checksum',
+
+  /**
+   * @param {string} markup Markup string
+   * @return {string} Markup string with checksum attribute attached
+   */
+  addChecksumToMarkup: function(markup) {
+    var checksum = adler32(markup);
+    return markup.replace(
+      '>',
+      ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '">'
+    );
+  },
+
+  /**
+   * @param {string} markup to use
+   * @param {DOMElement} element root React element
+   * @returns {boolean} whether or not the markup is the same
+   */
+  canReuseMarkup: function(markup, element) {
+    var existingChecksum = element.getAttribute(
+      ReactMarkupChecksum.CHECKSUM_ATTR_NAME
+    );
+    existingChecksum = existingChecksum && parseInt(existingChecksum, 10);
+    var markupChecksum = adler32(markup);
+    return markupChecksum === existingChecksum;
+  }
+};
+
+module.exports = ReactMarkupChecksum;
+
+},{"./adler32":87}],55:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactMount
+ */
+
+"use strict";
+
+var DOMProperty = require("./DOMProperty");
+var ReactEventEmitter = require("./ReactEventEmitter");
+var ReactInstanceHandles = require("./ReactInstanceHandles");
+var ReactPerf = require("./ReactPerf");
+
+var containsNode = require("./containsNode");
+var getReactRootElementInContainer = require("./getReactRootElementInContainer");
+var invariant = require("./invariant");
+var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
+
+var SEPARATOR = ReactInstanceHandles.SEPARATOR;
+
+var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME;
+var nodeCache = {};
+
+var ELEMENT_NODE_TYPE = 1;
+var DOC_NODE_TYPE = 9;
+
+/** Mapping from reactRootID to React component instance. */
+var instancesByReactRootID = {};
+
+/** Mapping from reactRootID to `container` nodes. */
+var containersByReactRootID = {};
+
+if ("production" !== "development") {
+  /** __DEV__-only mapping from reactRootID to root elements. */
+  var rootElementsByReactRootID = {};
+}
+
+// Used to store breadth-first search state in findComponentRoot.
+var findComponentRootReusableArray = [];
+
+/**
+ * @param {DOMElement} container DOM element that may contain a React component.
+ * @return {?string} A "reactRoot" ID, if a React component is rendered.
+ */
+function getReactRootID(container) {
+  var rootElement = getReactRootElementInContainer(container);
+  return rootElement && ReactMount.getID(rootElement);
+}
+
+/**
+ * Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form
+ * element can return its control whose name or ID equals ATTR_NAME. All
+ * DOM nodes support `getAttributeNode` but this can also get called on
+ * other objects so just return '' if we're given something other than a
+ * DOM node (such as window).
+ *
+ * @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node.
+ * @return {string} ID of the supplied `domNode`.
+ */
+function getID(node) {
+  var id = internalGetID(node);
+  if (id) {
+    if (nodeCache.hasOwnProperty(id)) {
+      var cached = nodeCache[id];
+      if (cached !== node) {
+        ("production" !== "development" ? invariant(
+          !isValid(cached, id),
+          'ReactMount: Two valid but unequal nodes with the same `%s`: %s',
+          ATTR_NAME, id
+        ) : invariant(!isValid(cached, id)));
+
+        nodeCache[id] = node;
+      }
+    } else {
+      nodeCache[id] = node;
+    }
+  }
+
+  return id;
+}
+
+function internalGetID(node) {
+  // If node is something like a window, document, or text node, none of
+  // which support attributes or a .getAttribute method, gracefully return
+  // the empty string, as if the attribute were missing.
+  return node && node.getAttribute && node.getAttribute(ATTR_NAME) || '';
+}
+
+/**
+ * Sets the React-specific ID of the given node.
+ *
+ * @param {DOMElement} node The DOM node whose ID will be set.
+ * @param {string} id The value of the ID attribute.
+ */
+function setID(node, id) {
+  var oldID = internalGetID(node);
+  if (oldID !== id) {
+    delete nodeCache[oldID];
+  }
+  node.setAttribute(ATTR_NAME, id);
+  nodeCache[id] = node;
+}
+
+/**
+ * Finds the node with the supplied React-generated DOM ID.
+ *
+ * @param {string} id A React-generated DOM ID.
+ * @return {DOMElement} DOM node with the suppled `id`.
+ * @internal
+ */
+function getNode(id) {
+  if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
+    nodeCache[id] = ReactMount.findReactNodeByID(id);
+  }
+  return nodeCache[id];
+}
+
+/**
+ * A node is "valid" if it is contained by a currently mounted container.
+ *
+ * This means that the node does not have to be contained by a document in
+ * order to be considered valid.
+ *
+ * @param {?DOMElement} node The candidate DOM node.
+ * @param {string} id The expected ID of the node.
+ * @return {boolean} Whether the node is contained by a mounted container.
+ */
+function isValid(node, id) {
+  if (node) {
+    ("production" !== "development" ? invariant(
+      internalGetID(node) === id,
+      'ReactMount: Unexpected modification of `%s`',
+      ATTR_NAME
+    ) : invariant(internalGetID(node) === id));
+
+    var container = ReactMount.findReactContainerForID(id);
+    if (container && containsNode(container, node)) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+/**
+ * Causes the cache to forget about one React-specific ID.
+ *
+ * @param {string} id The ID to forget.
+ */
+function purgeID(id) {
+  delete nodeCache[id];
+}
+
+var deepestNodeSoFar = null;
+function findDeepestCachedAncestorImpl(ancestorID) {
+  var ancestor = nodeCache[ancestorID];
+  if (ancestor && isValid(ancestor, ancestorID)) {
+    deepestNodeSoFar = ancestor;
+  } else {
+    // This node isn't populated in the cache, so presumably none of its
+    // descendants are. Break out of the loop.
+    return false;
+  }
+}
+
+/**
+ * Return the deepest cached node whose ID is a prefix of `targetID`.
+ */
+function findDeepestCachedAncestor(targetID) {
+  deepestNodeSoFar = null;
+  ReactInstanceHandles.traverseAncestors(
+    targetID,
+    findDeepestCachedAncestorImpl
+  );
+
+  var foundNode = deepestNodeSoFar;
+  deepestNodeSoFar = null;
+  return foundNode;
+}
+
+/**
+ * Mounting is the process of initializing a React component by creatings its
+ * representative DOM elements and inserting them into a supplied `container`.
+ * Any prior content inside `container` is destroyed in the process.
+ *
+ *   ReactMount.renderComponent(
+ *     component,
+ *     document.getElementById('container')
+ *   );
+ *
+ *   <div id="container">                   <-- Supplied `container`.
+ *     <div data-reactid=".3">              <-- Rendered reactRoot of React
+ *       // ...                                 component.
+ *     </div>
+ *   </div>
+ *
+ * Inside of `container`, the first element rendered is the "reactRoot".
+ */
+var ReactMount = {
+  /** Time spent generating markup. */
+  totalInstantiationTime: 0,
+
+  /** Time spent inserting markup into the DOM. */
+  totalInjectionTime: 0,
+
+  /** Whether support for touch events should be initialized. */
+  useTouchEvents: false,
+
+  /** Exposed for debugging purposes **/
+  _instancesByReactRootID: instancesByReactRootID,
+
+  /**
+   * This is a hook provided to support rendering React components while
+   * ensuring that the apparent scroll position of its `container` does not
+   * change.
+   *
+   * @param {DOMElement} container The `container` being rendered into.
+   * @param {function} renderCallback This must be called once to do the render.
+   */
+  scrollMonitor: function(container, renderCallback) {
+    renderCallback();
+  },
+
+  /**
+   * Take a component that's already mounted into the DOM and replace its props
+   * @param {ReactComponent} prevComponent component instance already in the DOM
+   * @param {ReactComponent} nextComponent component instance to render
+   * @param {DOMElement} container container to render into
+   * @param {?function} callback function triggered on completion
+   */
+  _updateRootComponent: function(
+      prevComponent,
+      nextComponent,
+      container,
+      callback) {
+    var nextProps = nextComponent.props;
+    ReactMount.scrollMonitor(container, function() {
+      prevComponent.replaceProps(nextProps, callback);
+    });
+
+    if ("production" !== "development") {
+      // Record the root element in case it later gets transplanted.
+      rootElementsByReactRootID[getReactRootID(container)] =
+        getReactRootElementInContainer(container);
+    }
+
+    return prevComponent;
+  },
+
+  /**
+   * Register a component into the instance map and starts scroll value
+   * monitoring
+   * @param {ReactComponent} nextComponent component instance to render
+   * @param {DOMElement} container container to render into
+   * @return {string} reactRoot ID prefix
+   */
+  _registerComponent: function(nextComponent, container) {
+    ("production" !== "development" ? invariant(
+      container && (
+        container.nodeType === ELEMENT_NODE_TYPE ||
+        container.nodeType === DOC_NODE_TYPE
+      ),
+      '_registerComponent(...): Target container is not a DOM element.'
+    ) : invariant(container && (
+      container.nodeType === ELEMENT_NODE_TYPE ||
+      container.nodeType === DOC_NODE_TYPE
+    )));
+
+    ReactEventEmitter.ensureScrollValueMonitoring();
+
+    var reactRootID = ReactMount.registerContainer(container);
+    instancesByReactRootID[reactRootID] = nextComponent;
+    return reactRootID;
+  },
+
+  /**
+   * Render a new component into the DOM.
+   * @param {ReactComponent} nextComponent component instance to render
+   * @param {DOMElement} container container to render into
+   * @param {boolean} shouldReuseMarkup if we should skip the markup insertion
+   * @return {ReactComponent} nextComponent
+   */
+  _renderNewRootComponent: ReactPerf.measure(
+    'ReactMount',
+    '_renderNewRootComponent',
+    function(
+        nextComponent,
+        container,
+        shouldReuseMarkup) {
+      var reactRootID = ReactMount._registerComponent(nextComponent, container);
+      nextComponent.mountComponentIntoNode(
+        reactRootID,
+        container,
+        shouldReuseMarkup
+      );
+
+      if ("production" !== "development") {
+        // Record the root element in case it later gets transplanted.
+        rootElementsByReactRootID[reactRootID] =
+          getReactRootElementInContainer(container);
+      }
+
+      return nextComponent;
+    }
+  ),
+
+  /**
+   * Renders a React component into the DOM in the supplied `container`.
+   *
+   * If the React component was previously rendered into `container`, this will
+   * perform an update on it and only mutate the DOM as necessary to reflect the
+   * latest React component.
+   *
+   * @param {ReactComponent} nextComponent Component instance to render.
+   * @param {DOMElement} container DOM element to render into.
+   * @param {?function} callback function triggered on completion
+   * @return {ReactComponent} Component instance rendered in `container`.
+   */
+  renderComponent: function(nextComponent, container, callback) {
+    var prevComponent = instancesByReactRootID[getReactRootID(container)];
+
+    if (prevComponent) {
+      if (shouldUpdateReactComponent(prevComponent, nextComponent)) {
+        return ReactMount._updateRootComponent(
+          prevComponent,
+          nextComponent,
+          container,
+          callback
+        );
+      } else {
+        ReactMount.unmountComponentAtNode(container);
+      }
+    }
+
+    var reactRootElement = getReactRootElementInContainer(container);
+    var containerHasReactMarkup =
+      reactRootElement && ReactMount.isRenderedByReact(reactRootElement);
+
+    var shouldReuseMarkup = containerHasReactMarkup && !prevComponent;
+
+    var component = ReactMount._renderNewRootComponent(
+      nextComponent,
+      container,
+      shouldReuseMarkup
+    );
+    callback && callback.call(component);
+    return component;
+  },
+
+  /**
+   * Constructs a component instance of `constructor` with `initialProps` and
+   * renders it into the supplied `container`.
+   *
+   * @param {function} constructor React component constructor.
+   * @param {?object} props Initial props of the component instance.
+   * @param {DOMElement} container DOM element to render into.
+   * @return {ReactComponent} Component instance rendered in `container`.
+   */
+  constructAndRenderComponent: function(constructor, props, container) {
+    return ReactMount.renderComponent(constructor(props), container);
+  },
+
+  /**
+   * Constructs a component instance of `constructor` with `initialProps` and
+   * renders it into a container node identified by supplied `id`.
+   *
+   * @param {function} componentConstructor React component constructor
+   * @param {?object} props Initial props of the component instance.
+   * @param {string} id ID of the DOM element to render into.
+   * @return {ReactComponent} Component instance rendered in the container node.
+   */
+  constructAndRenderComponentByID: function(constructor, props, id) {
+    var domNode = document.getElementById(id);
+    ("production" !== "development" ? invariant(
+      domNode,
+      'Tried to get element with id of "%s" but it is not present on the page.',
+      id
+    ) : invariant(domNode));
+    return ReactMount.constructAndRenderComponent(constructor, props, domNode);
+  },
+
+  /**
+   * Registers a container node into which React components will be rendered.
+   * This also creates the "reactRoot" ID that will be assigned to the element
+   * rendered within.
+   *
+   * @param {DOMElement} container DOM element to register as a container.
+   * @return {string} The "reactRoot" ID of elements rendered within.
+   */
+  registerContainer: function(container) {
+    var reactRootID = getReactRootID(container);
+    if (reactRootID) {
+      // If one exists, make sure it is a valid "reactRoot" ID.
+      reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID);
+    }
+    if (!reactRootID) {
+      // No valid "reactRoot" ID found, create one.
+      reactRootID = ReactInstanceHandles.createReactRootID();
+    }
+    containersByReactRootID[reactRootID] = container;
+    return reactRootID;
+  },
+
+  /**
+   * Unmounts and destroys the React component rendered in the `container`.
+   *
+   * @param {DOMElement} container DOM element containing a React component.
+   * @return {boolean} True if a component was found in and unmounted from
+   *                   `container`
+   */
+  unmountComponentAtNode: function(container) {
+    var reactRootID = getReactRootID(container);
+    var component = instancesByReactRootID[reactRootID];
+    if (!component) {
+      return false;
+    }
+    ReactMount.unmountComponentFromNode(component, container);
+    delete instancesByReactRootID[reactRootID];
+    delete containersByReactRootID[reactRootID];
+    if ("production" !== "development") {
+      delete rootElementsByReactRootID[reactRootID];
+    }
+    return true;
+  },
+
+  /**
+   * Unmounts a component and removes it from the DOM.
+   *
+   * @param {ReactComponent} instance React component instance.
+   * @param {DOMElement} container DOM element to unmount from.
+   * @final
+   * @internal
+   * @see {ReactMount.unmountComponentAtNode}
+   */
+  unmountComponentFromNode: function(instance, container) {
+    instance.unmountComponent();
+
+    if (container.nodeType === DOC_NODE_TYPE) {
+      container = container.documentElement;
+    }
+
+    // http://jsperf.com/emptying-a-node
+    while (container.lastChild) {
+      container.removeChild(container.lastChild);
+    }
+  },
+
+  /**
+   * Finds the container DOM element that contains React component to which the
+   * supplied DOM `id` belongs.
+   *
+   * @param {string} id The ID of an element rendered by a React component.
+   * @return {?DOMElement} DOM element that contains the `id`.
+   */
+  findReactContainerForID: function(id) {
+    var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id);
+    var container = containersByReactRootID[reactRootID];
+
+    if ("production" !== "development") {
+      var rootElement = rootElementsByReactRootID[reactRootID];
+      if (rootElement && rootElement.parentNode !== container) {
+        ("production" !== "development" ? invariant(
+          // Call internalGetID here because getID calls isValid which calls
+          // findReactContainerForID (this function).
+          internalGetID(rootElement) === reactRootID,
+          'ReactMount: Root element ID differed from reactRootID.'
+        ) : invariant(// Call internalGetID here because getID calls isValid which calls
+        // findReactContainerForID (this function).
+        internalGetID(rootElement) === reactRootID));
+
+        var containerChild = container.firstChild;
+        if (containerChild &&
+            reactRootID === internalGetID(containerChild)) {
+          // If the container has a new child with the same ID as the old
+          // root element, then rootElementsByReactRootID[reactRootID] is
+          // just stale and needs to be updated. The case that deserves a
+          // warning is when the container is empty.
+          rootElementsByReactRootID[reactRootID] = containerChild;
+        } else {
+          console.warn(
+            'ReactMount: Root element has been removed from its original ' +
+            'container. New container:', rootElement.parentNode
+          );
+        }
+      }
+    }
+
+    return container;
+  },
+
+  /**
+   * Finds an element rendered by React with the supplied ID.
+   *
+   * @param {string} id ID of a DOM node in the React component.
+   * @return {DOMElement} Root DOM node of the React component.
+   */
+  findReactNodeByID: function(id) {
+    var reactRoot = ReactMount.findReactContainerForID(id);
+    return ReactMount.findComponentRoot(reactRoot, id);
+  },
+
+  /**
+   * True if the supplied `node` is rendered by React.
+   *
+   * @param {*} node DOM Element to check.
+   * @return {boolean} True if the DOM Element appears to be rendered by React.
+   * @internal
+   */
+  isRenderedByReact: function(node) {
+    if (node.nodeType !== 1) {
+      // Not a DOMElement, therefore not a React component
+      return false;
+    }
+    var id = ReactMount.getID(node);
+    return id ? id.charAt(0) === SEPARATOR : false;
+  },
+
+  /**
+   * Traverses up the ancestors of the supplied node to find a node that is a
+   * DOM representation of a React component.
+   *
+   * @param {*} node
+   * @return {?DOMEventTarget}
+   * @internal
+   */
+  getFirstReactDOM: function(node) {
+    var current = node;
+    while (current && current.parentNode !== current) {
+      if (ReactMount.isRenderedByReact(current)) {
+        return current;
+      }
+      current = current.parentNode;
+    }
+    return null;
+  },
+
+  /**
+   * Finds a node with the supplied `targetID` inside of the supplied
+   * `ancestorNode`.  Exploits the ID naming scheme to perform the search
+   * quickly.
+   *
+   * @param {DOMEventTarget} ancestorNode Search from this root.
+   * @pararm {string} targetID ID of the DOM representation of the component.
+   * @return {DOMEventTarget} DOM node with the supplied `targetID`.
+   * @internal
+   */
+  findComponentRoot: function(ancestorNode, targetID) {
+    var firstChildren = findComponentRootReusableArray;
+    var childIndex = 0;
+
+    var deepestAncestor = findDeepestCachedAncestor(targetID) || ancestorNode;
+
+    firstChildren[0] = deepestAncestor.firstChild;
+    firstChildren.length = 1;
+
+    while (childIndex < firstChildren.length) {
+      var child = firstChildren[childIndex++];
+      var targetChild;
+
+      while (child) {
+        var childID = ReactMount.getID(child);
+        if (childID) {
+          // Even if we find the node we're looking for, we finish looping
+          // through its siblings to ensure they're cached so that we don't have
+          // to revisit this node again. Otherwise, we make n^2 calls to getID
+          // when visiting the many children of a single node in order.
+
+          if (targetID === childID) {
+            targetChild = child;
+          } else if (ReactInstanceHandles.isAncestorIDOf(childID, targetID)) {
+            // If we find a child whose ID is an ancestor of the given ID,
+            // then we can be sure that we only want to search the subtree
+            // rooted at this child, so we can throw out the rest of the
+            // search state.
+            firstChildren.length = childIndex = 0;
+            firstChildren.push(child.firstChild);
+          }
+
+        } else {
+          // If this child had no ID, then there's a chance that it was
+          // injected automatically by the browser, as when a `<table>`
+          // element sprouts an extra `<tbody>` child as a side effect of
+          // `.innerHTML` parsing. Optimistically continue down this
+          // branch, but not before examining the other siblings.
+          firstChildren.push(child.firstChild);
+        }
+
+        child = child.nextSibling;
+      }
+
+      if (targetChild) {
+        // Emptying firstChildren/findComponentRootReusableArray is
+        // not necessary for correctness, but it helps the GC reclaim
+        // any nodes that were left at the end of the search.
+        firstChildren.length = 0;
+
+        return targetChild;
+      }
+    }
+
+    firstChildren.length = 0;
+
+    ("production" !== "development" ? invariant(
+      false,
+      'findComponentRoot(..., %s): Unable to find element. This probably ' +
+      'means the DOM was unexpectedly mutated (e.g., by the browser). ' +
+      'Try inspecting the child nodes of the element with React ID `%s`.',
+      targetID,
+      ReactMount.getID(ancestorNode)
+    ) : invariant(false));
+  },
+
+
+  /**
+   * React ID utilities.
+   */
+
+  getReactRootID: getReactRootID,
+
+  getID: getID,
+
+  setID: setID,
+
+  getNode: getNode,
+
+  purgeID: purgeID
+};
+
+module.exports = ReactMount;
+
+},{"./DOMProperty":8,"./ReactEventEmitter":48,"./ReactInstanceHandles":53,"./ReactPerf":60,"./containsNode":88,"./getReactRootElementInContainer":104,"./invariant":108,"./shouldUpdateReactComponent":126}],56:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactMountReady
+ */
+
+"use strict";
+
+var PooledClass = require("./PooledClass");
+
+var mixInto = require("./mixInto");
+
+/**
+ * A specialized pseudo-event module to help keep track of components waiting to
+ * be notified when their DOM representations are available for use.
+ *
+ * This implements `PooledClass`, so you should never need to instantiate this.
+ * Instead, use `ReactMountReady.getPooled()`.
+ *
+ * @param {?array<function>} initialCollection
+ * @class ReactMountReady
+ * @implements PooledClass
+ * @internal
+ */
+function ReactMountReady(initialCollection) {
+  this._queue = initialCollection || null;
+}
+
+mixInto(ReactMountReady, {
+
+  /**
+   * Enqueues a callback to be invoked when `notifyAll` is invoked. This is used
+   * to enqueue calls to `componentDidMount` and `componentDidUpdate`.
+   *
+   * @param {ReactComponent} component Component being rendered.
+   * @param {function(DOMElement)} callback Invoked when `notifyAll` is invoked.
+   * @internal
+   */
+  enqueue: function(component, callback) {
+    this._queue = this._queue || [];
+    this._queue.push({component: component, callback: callback});
+  },
+
+  /**
+   * Invokes all enqueued callbacks and clears the queue. This is invoked after
+   * the DOM representation of a component has been created or updated.
+   *
+   * @internal
+   */
+  notifyAll: function() {
+    var queue = this._queue;
+    if (queue) {
+      this._queue = null;
+      for (var i = 0, l = queue.length; i < l; i++) {
+        var component = queue[i].component;
+        var callback = queue[i].callback;
+        callback.call(component);
+      }
+      queue.length = 0;
+    }
+  },
+
+  /**
+   * Resets the internal queue.
+   *
+   * @internal
+   */
+  reset: function() {
+    this._queue = null;
+  },
+
+  /**
+   * `PooledClass` looks for this.
+   */
+  destructor: function() {
+    this.reset();
+  }
+
+});
+
+PooledClass.addPoolingTo(ReactMountReady);
+
+module.exports = ReactMountReady;
+
+},{"./PooledClass":23,"./mixInto":120}],57:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactMultiChild
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var ReactComponent = require("./ReactComponent");
+var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes");
+
+var flattenChildren = require("./flattenChildren");
+var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
+
+/**
+ * Updating children of a component may trigger recursive updates. The depth is
+ * used to batch recursive updates to render markup more efficiently.
+ *
+ * @type {number}
+ * @private
+ */
+var updateDepth = 0;
+
+/**
+ * Queue of update configuration objects.
+ *
+ * Each object has a `type` property that is in `ReactMultiChildUpdateTypes`.
+ *
+ * @type {array<object>}
+ * @private
+ */
+var updateQueue = [];
+
+/**
+ * Queue of markup to be rendered.
+ *
+ * @type {array<string>}
+ * @private
+ */
+var markupQueue = [];
+
+/**
+ * Enqueues markup to be rendered and inserted at a supplied index.
+ *
+ * @param {string} parentID ID of the parent component.
+ * @param {string} markup Markup that renders into an element.
+ * @param {number} toIndex Destination index.
+ * @private
+ */
+function enqueueMarkup(parentID, markup, toIndex) {
+  // NOTE: Null values reduce hidden classes.
+  updateQueue.push({
+    parentID: parentID,
+    parentNode: null,
+    type: ReactMultiChildUpdateTypes.INSERT_MARKUP,
+    markupIndex: markupQueue.push(markup) - 1,
+    textContent: null,
+    fromIndex: null,
+    toIndex: toIndex
+  });
+}
+
+/**
+ * Enqueues moving an existing element to another index.
+ *
+ * @param {string} parentID ID of the parent component.
+ * @param {number} fromIndex Source index of the existing element.
+ * @param {number} toIndex Destination index of the element.
+ * @private
+ */
+function enqueueMove(parentID, fromIndex, toIndex) {
+  // NOTE: Null values reduce hidden classes.
+  updateQueue.push({
+    parentID: parentID,
+    parentNode: null,
+    type: ReactMultiChildUpdateTypes.MOVE_EXISTING,
+    markupIndex: null,
+    textContent: null,
+    fromIndex: fromIndex,
+    toIndex: toIndex
+  });
+}
+
+/**
+ * Enqueues removing an element at an index.
+ *
+ * @param {string} parentID ID of the parent component.
+ * @param {number} fromIndex Index of the element to remove.
+ * @private
+ */
+function enqueueRemove(parentID, fromIndex) {
+  // NOTE: Null values reduce hidden classes.
+  updateQueue.push({
+    parentID: parentID,
+    parentNode: null,
+    type: ReactMultiChildUpdateTypes.REMOVE_NODE,
+    markupIndex: null,
+    textContent: null,
+    fromIndex: fromIndex,
+    toIndex: null
+  });
+}
+
+/**
+ * Enqueues setting the text content.
+ *
+ * @param {string} parentID ID of the parent component.
+ * @param {string} textContent Text content to set.
+ * @private
+ */
+function enqueueTextContent(parentID, textContent) {
+  // NOTE: Null values reduce hidden classes.
+  updateQueue.push({
+    parentID: parentID,
+    parentNode: null,
+    type: ReactMultiChildUpdateTypes.TEXT_CONTENT,
+    markupIndex: null,
+    textContent: textContent,
+    fromIndex: null,
+    toIndex: null
+  });
+}
+
+/**
+ * Processes any enqueued updates.
+ *
+ * @private
+ */
+function processQueue() {
+  if (updateQueue.length) {
+    ReactComponent.BackendIDOperations.dangerouslyProcessChildrenUpdates(
+      updateQueue,
+      markupQueue
+    );
+    clearQueue();
+  }
+}
+
+/**
+ * Clears any enqueued updates.
+ *
+ * @private
+ */
+function clearQueue() {
+  updateQueue.length = 0;
+  markupQueue.length = 0;
+}
+
+/**
+ * ReactMultiChild are capable of reconciling multiple children.
+ *
+ * @class ReactMultiChild
+ * @internal
+ */
+var ReactMultiChild = {
+
+  /**
+   * Provides common functionality for components that must reconcile multiple
+   * children. This is used by `ReactDOMComponent` to mount, update, and
+   * unmount child components.
+   *
+   * @lends {ReactMultiChild.prototype}
+   */
+  Mixin: {
+
+    /**
+     * Generates a "mount image" for each of the supplied children. In the case
+     * of `ReactDOMComponent`, a mount image is a string of markup.
+     *
+     * @param {?object} nestedChildren Nested child maps.
+     * @return {array} An array of mounted representations.
+     * @internal
+     */
+    mountChildren: function(nestedChildren, transaction) {
+      var children = flattenChildren(nestedChildren);
+      var mountImages = [];
+      var index = 0;
+      this._renderedChildren = children;
+      for (var name in children) {
+        var child = children[name];
+        if (children.hasOwnProperty(name)) {
+          // Inlined for performance, see `ReactInstanceHandles.createReactID`.
+          var rootID = this._rootNodeID + name;
+          var mountImage = child.mountComponent(
+            rootID,
+            transaction,
+            this._mountDepth + 1
+          );
+          child._mountIndex = index;
+          mountImages.push(mountImage);
+          index++;
+        }
+      }
+      return mountImages;
+    },
+
+    /**
+     * Replaces any rendered children with a text content string.
+     *
+     * @param {string} nextContent String of content.
+     * @internal
+     */
+    updateTextContent: function(nextContent) {
+      updateDepth++;
+      var errorThrown = true;
+      try {
+        var prevChildren = this._renderedChildren;
+        // Remove any rendered children.
+        for (var name in prevChildren) {
+          if (prevChildren.hasOwnProperty(name)) {
+            this._unmountChildByName(prevChildren[name], name);
+          }
+        }
+        // Set new text content.
+        this.setTextContent(nextContent);
+        errorThrown = false;
+      } finally {
+        updateDepth--;
+        if (!updateDepth) {
+          errorThrown ? clearQueue() : processQueue();
+        }
+      }
+    },
+
+    /**
+     * Updates the rendered children with new children.
+     *
+     * @param {?object} nextNestedChildren Nested child maps.
+     * @param {ReactReconcileTransaction} transaction
+     * @internal
+     */
+    updateChildren: function(nextNestedChildren, transaction) {
+      updateDepth++;
+      var errorThrown = true;
+      try {
+        this._updateChildren(nextNestedChildren, transaction);
+        errorThrown = false;
+      } finally {
+        updateDepth--;
+        if (!updateDepth) {
+          errorThrown ? clearQueue() : processQueue();
+        }
+      }
+    },
+
+    /**
+     * Improve performance by isolating this hot code path from the try/catch
+     * block in `updateChildren`.
+     *
+     * @param {?object} nextNestedChildren Nested child maps.
+     * @param {ReactReconcileTransaction} transaction
+     * @final
+     * @protected
+     */
+    _updateChildren: function(nextNestedChildren, transaction) {
+      var nextChildren = flattenChildren(nextNestedChildren);
+      var prevChildren = this._renderedChildren;
+      if (!nextChildren && !prevChildren) {
+        return;
+      }
+      var name;
+      // `nextIndex` will increment for each child in `nextChildren`, but
+      // `lastIndex` will be the last index visited in `prevChildren`.
+      var lastIndex = 0;
+      var nextIndex = 0;
+      for (name in nextChildren) {
+        if (!nextChildren.hasOwnProperty(name)) {
+          continue;
+        }
+        var prevChild = prevChildren && prevChildren[name];
+        var nextChild = nextChildren[name];
+        if (shouldUpdateReactComponent(prevChild, nextChild)) {
+          this.moveChild(prevChild, nextIndex, lastIndex);
+          lastIndex = Math.max(prevChild._mountIndex, lastIndex);
+          prevChild.receiveComponent(nextChild, transaction);
+          prevChild._mountIndex = nextIndex;
+        } else {
+          if (prevChild) {
+            // Update `lastIndex` before `_mountIndex` gets unset by unmounting.
+            lastIndex = Math.max(prevChild._mountIndex, lastIndex);
+            this._unmountChildByName(prevChild, name);
+          }
+          this._mountChildByNameAtIndex(
+            nextChild, name, nextIndex, transaction
+          );
+        }
+        nextIndex++;
+      }
+      // Remove children that are no longer present.
+      for (name in prevChildren) {
+        if (prevChildren.hasOwnProperty(name) &&
+            !(nextChildren && nextChildren[name])) {
+          this._unmountChildByName(prevChildren[name], name);
+        }
+      }
+    },
+
+    /**
+     * Unmounts all rendered children. This should be used to clean up children
+     * when this component is unmounted.
+     *
+     * @internal
+     */
+    unmountChildren: function() {
+      var renderedChildren = this._renderedChildren;
+      for (var name in renderedChildren) {
+        var renderedChild = renderedChildren[name];
+        // TODO: When is this not true?
+        if (renderedChild.unmountComponent) {
+          renderedChild.unmountComponent();
+        }
+      }
+      this._renderedChildren = null;
+    },
+
+    /**
+     * Moves a child component to the supplied index.
+     *
+     * @param {ReactComponent} child Component to move.
+     * @param {number} toIndex Destination index of the element.
+     * @param {number} lastIndex Last index visited of the siblings of `child`.
+     * @protected
+     */
+    moveChild: function(child, toIndex, lastIndex) {
+      // If the index of `child` is less than `lastIndex`, then it needs to
+      // be moved. Otherwise, we do not need to move it because a child will be
+      // inserted or moved before `child`.
+      if (child._mountIndex < lastIndex) {
+        enqueueMove(this._rootNodeID, child._mountIndex, toIndex);
+      }
+    },
+
+    /**
+     * Creates a child component.
+     *
+     * @param {ReactComponent} child Component to create.
+     * @param {string} mountImage Markup to insert.
+     * @protected
+     */
+    createChild: function(child, mountImage) {
+      enqueueMarkup(this._rootNodeID, mountImage, child._mountIndex);
+    },
+
+    /**
+     * Removes a child component.
+     *
+     * @param {ReactComponent} child Child to remove.
+     * @protected
+     */
+    removeChild: function(child) {
+      enqueueRemove(this._rootNodeID, child._mountIndex);
+    },
+
+    /**
+     * Sets this text content string.
+     *
+     * @param {string} textContent Text content to set.
+     * @protected
+     */
+    setTextContent: function(textContent) {
+      enqueueTextContent(this._rootNodeID, textContent);
+    },
+
+    /**
+     * Mounts a child with the supplied name.
+     *
+     * NOTE: This is part of `updateChildren` and is here for readability.
+     *
+     * @param {ReactComponent} child Component to mount.
+     * @param {string} name Name of the child.
+     * @param {number} index Index at which to insert the child.
+     * @param {ReactReconcileTransaction} transaction
+     * @private
+     */
+    _mountChildByNameAtIndex: function(child, name, index, transaction) {
+      // Inlined for performance, see `ReactInstanceHandles.createReactID`.
+      var rootID = this._rootNodeID + name;
+      var mountImage = child.mountComponent(
+        rootID,
+        transaction,
+        this._mountDepth + 1
+      );
+      child._mountIndex = index;
+      this.createChild(child, mountImage);
+      this._renderedChildren = this._renderedChildren || {};
+      this._renderedChildren[name] = child;
+    },
+
+    /**
+     * Unmounts a rendered child by name.
+     *
+     * NOTE: This is part of `updateChildren` and is here for readability.
+     *
+     * @param {ReactComponent} child Component to unmount.
+     * @param {string} name Name of the child in `this._renderedChildren`.
+     * @private
+     */
+    _unmountChildByName: function(child, name) {
+      // TODO: When is this not true?
+      if (ReactComponent.isValidComponent(child)) {
+        this.removeChild(child);
+        child._mountIndex = null;
+        child.unmountComponent();
+        delete this._renderedChildren[name];
+      }
+    }
+
+  }
+
+};
+
+module.exports = ReactMultiChild;
+
+},{"./ReactComponent":26,"./ReactMultiChildUpdateTypes":58,"./flattenChildren":97,"./shouldUpdateReactComponent":126}],58:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactMultiChildUpdateTypes
+ */
+
+"use strict";
+
+var keyMirror = require("./keyMirror");
+
+/**
+ * When a component's children are updated, a series of update configuration
+ * objects are created in order to batch and serialize the required changes.
+ *
+ * Enumerates all the possible types of update configurations.
+ *
+ * @internal
+ */
+var ReactMultiChildUpdateTypes = keyMirror({
+  INSERT_MARKUP: null,
+  MOVE_EXISTING: null,
+  REMOVE_NODE: null,
+  TEXT_CONTENT: null
+});
+
+module.exports = ReactMultiChildUpdateTypes;
+
+},{"./keyMirror":114}],59:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactOwner
+ */
+
+"use strict";
+
+var invariant = require("./invariant");
+
+/**
+ * ReactOwners are capable of storing references to owned components.
+ *
+ * All components are capable of //being// referenced by owner components, but
+ * only ReactOwner components are capable of //referencing// owned components.
+ * The named reference is known as a "ref".
+ *
+ * Refs are available when mounted and updated during reconciliation.
+ *
+ *   var MyComponent = React.createClass({
+ *     render: function() {
+ *       return (
+ *         <div onClick={this.handleClick}>
+ *           <CustomComponent ref="custom" />
+ *         </div>
+ *       );
+ *     },
+ *     handleClick: function() {
+ *       this.refs.custom.handleClick();
+ *     },
+ *     componentDidMount: function() {
+ *       this.refs.custom.initialize();
+ *     }
+ *   });
+ *
+ * Refs should rarely be used. When refs are used, they should only be done to
+ * control data that is not handled by React's data flow.
+ *
+ * @class ReactOwner
+ */
+var ReactOwner = {
+
+  /**
+   * @param {?object} object
+   * @return {boolean} True if `object` is a valid owner.
+   * @final
+   */
+  isValidOwner: function(object) {
+    return !!(
+      object &&
+      typeof object.attachRef === 'function' &&
+      typeof object.detachRef === 'function'
+    );
+  },
+
+  /**
+   * Adds a component by ref to an owner component.
+   *
+   * @param {ReactComponent} component Component to reference.
+   * @param {string} ref Name by which to refer to the component.
+   * @param {ReactOwner} owner Component on which to record the ref.
+   * @final
+   * @internal
+   */
+  addComponentAsRefTo: function(component, ref, owner) {
+    ("production" !== "development" ? invariant(
+      ReactOwner.isValidOwner(owner),
+      'addComponentAsRefTo(...): Only a ReactOwner can have refs. This ' +
+      'usually means that you\'re trying to add a ref to a component that ' +
+      'doesn\'t have an owner (that is, was not created inside of another ' +
+      'component\'s `render` method). Try rendering this component inside of ' +
+      'a new top-level component which will hold the ref.'
+    ) : invariant(ReactOwner.isValidOwner(owner)));
+    owner.attachRef(ref, component);
+  },
+
+  /**
+   * Removes a component by ref from an owner component.
+   *
+   * @param {ReactComponent} component Component to dereference.
+   * @param {string} ref Name of the ref to remove.
+   * @param {ReactOwner} owner Component on which the ref is recorded.
+   * @final
+   * @internal
+   */
+  removeComponentAsRefFrom: function(component, ref, owner) {
+    ("production" !== "development" ? invariant(
+      ReactOwner.isValidOwner(owner),
+      'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. This ' +
+      'usually means that you\'re trying to remove a ref to a component that ' +
+      'doesn\'t have an owner (that is, was not created inside of another ' +
+      'component\'s `render` method). Try rendering this component inside of ' +
+      'a new top-level component which will hold the ref.'
+    ) : invariant(ReactOwner.isValidOwner(owner)));
+    // Check that `component` is still the current ref because we do not want to
+    // detach the ref if another component stole it.
+    if (owner.refs[ref] === component) {
+      owner.detachRef(ref);
+    }
+  },
+
+  /**
+   * A ReactComponent must mix this in to have refs.
+   *
+   * @lends {ReactOwner.prototype}
+   */
+  Mixin: {
+
+    /**
+     * Lazily allocates the refs object and stores `component` as `ref`.
+     *
+     * @param {string} ref Reference name.
+     * @param {component} component Component to store as `ref`.
+     * @final
+     * @private
+     */
+    attachRef: function(ref, component) {
+      ("production" !== "development" ? invariant(
+        component.isOwnedBy(this),
+        'attachRef(%s, ...): Only a component\'s owner can store a ref to it.',
+        ref
+      ) : invariant(component.isOwnedBy(this)));
+      var refs = this.refs || (this.refs = {});
+      refs[ref] = component;
+    },
+
+    /**
+     * Detaches a reference name.
+     *
+     * @param {string} ref Name to dereference.
+     * @final
+     * @private
+     */
+    detachRef: function(ref) {
+      delete this.refs[ref];
+    }
+
+  }
+
+};
+
+module.exports = ReactOwner;
+
+},{"./invariant":108}],60:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactPerf
+ * @typechecks static-only
+ */
+
+"use strict";
+
+/**
+ * ReactPerf is a general AOP system designed to measure performance. This
+ * module only has the hooks: see ReactDefaultPerf for the analysis tool.
+ */
+var ReactPerf = {
+  /**
+   * Boolean to enable/disable measurement. Set to false by default to prevent
+   * accidental logging and perf loss.
+   */
+  enableMeasure: false,
+
+  /**
+   * Holds onto the measure function in use. By default, don't measure
+   * anything, but we'll override this if we inject a measure function.
+   */
+  storedMeasure: _noMeasure,
+
+  /**
+   * Use this to wrap methods you want to measure. Zero overhead in production.
+   *
+   * @param {string} objName
+   * @param {string} fnName
+   * @param {function} func
+   * @return {function}
+   */
+  measure: function(objName, fnName, func) {
+    if ("production" !== "development") {
+      var measuredFunc = null;
+      return function() {
+        if (ReactPerf.enableMeasure) {
+          if (!measuredFunc) {
+            measuredFunc = ReactPerf.storedMeasure(objName, fnName, func);
+          }
+          return measuredFunc.apply(this, arguments);
+        }
+        return func.apply(this, arguments);
+      };
+    }
+    return func;
+  },
+
+  injection: {
+    /**
+     * @param {function} measure
+     */
+    injectMeasure: function(measure) {
+      ReactPerf.storedMeasure = measure;
+    }
+  }
+};
+
+/**
+ * Simply passes through the measured function, without measuring it.
+ *
+ * @param {string} objName
+ * @param {string} fnName
+ * @param {function} func
+ * @return {function}
+ */
+function _noMeasure(objName, fnName, func) {
+  return func;
+}
+
+module.exports = ReactPerf;
+
+},{}],61:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactPropTransferer
+ */
+
+"use strict";
+
+var emptyFunction = require("./emptyFunction");
+var invariant = require("./invariant");
+var joinClasses = require("./joinClasses");
+var merge = require("./merge");
+
+/**
+ * Creates a transfer strategy that will merge prop values using the supplied
+ * `mergeStrategy`. If a prop was previously unset, this just sets it.
+ *
+ * @param {function} mergeStrategy
+ * @return {function}
+ */
+function createTransferStrategy(mergeStrategy) {
+  return function(props, key, value) {
+    if (!props.hasOwnProperty(key)) {
+      props[key] = value;
+    } else {
+      props[key] = mergeStrategy(props[key], value);
+    }
+  };
+}
+
+/**
+ * Transfer strategies dictate how props are transferred by `transferPropsTo`.
+ * NOTE: if you add any more exceptions to this list you should be sure to
+ * update `cloneWithProps()` accordingly.
+ */
+var TransferStrategies = {
+  /**
+   * Never transfer `children`.
+   */
+  children: emptyFunction,
+  /**
+   * Transfer the `className` prop by merging them.
+   */
+  className: createTransferStrategy(joinClasses),
+  /**
+   * Never transfer the `key` prop.
+   */
+  key: emptyFunction,
+  /**
+   * Never transfer the `ref` prop.
+   */
+  ref: emptyFunction,
+  /**
+   * Transfer the `style` prop (which is an object) by merging them.
+   */
+  style: createTransferStrategy(merge)
+};
+
+/**
+ * ReactPropTransferer are capable of transferring props to another component
+ * using a `transferPropsTo` method.
+ *
+ * @class ReactPropTransferer
+ */
+var ReactPropTransferer = {
+
+  TransferStrategies: TransferStrategies,
+
+  /**
+   * Merge two props objects using TransferStrategies.
+   *
+   * @param {object} oldProps original props (they take precedence)
+   * @param {object} newProps new props to merge in
+   * @return {object} a new object containing both sets of props merged.
+   */
+  mergeProps: function(oldProps, newProps) {
+    var props = merge(oldProps);
+
+    for (var thisKey in newProps) {
+      if (!newProps.hasOwnProperty(thisKey)) {
+        continue;
+      }
+
+      var transferStrategy = TransferStrategies[thisKey];
+
+      if (transferStrategy) {
+        transferStrategy(props, thisKey, newProps[thisKey]);
+      } else if (!props.hasOwnProperty(thisKey)) {
+        props[thisKey] = newProps[thisKey];
+      }
+    }
+
+    return props;
+  },
+
+  /**
+   * @lends {ReactPropTransferer.prototype}
+   */
+  Mixin: {
+
+    /**
+     * Transfer props from this component to a target component.
+     *
+     * Props that do not have an explicit transfer strategy will be transferred
+     * only if the target component does not already have the prop set.
+     *
+     * This is usually used to pass down props to a returned root component.
+     *
+     * @param {ReactComponent} component Component receiving the properties.
+     * @return {ReactComponent} The supplied `component`.
+     * @final
+     * @protected
+     */
+    transferPropsTo: function(component) {
+      ("production" !== "development" ? invariant(
+        component._owner === this,
+        '%s: You can\'t call transferPropsTo() on a component that you ' +
+        'don\'t own, %s. This usually means you are calling ' +
+        'transferPropsTo() on a component passed in as props or children.',
+        this.constructor.displayName,
+        component.constructor.displayName
+      ) : invariant(component._owner === this));
+
+      component.props = ReactPropTransferer.mergeProps(
+        component.props,
+        this.props
+      );
+
+      return component;
+    }
+
+  }
+};
+
+module.exports = ReactPropTransferer;
+
+},{"./emptyFunction":95,"./invariant":108,"./joinClasses":113,"./merge":117}],62:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactPropTypeLocationNames
+ */
+
+"use strict";
+
+var ReactPropTypeLocationNames = {};
+
+if ("production" !== "development") {
+  ReactPropTypeLocationNames = {
+    prop: 'prop',
+    context: 'context',
+    childContext: 'child context'
+  };
+}
+
+module.exports = ReactPropTypeLocationNames;
+
+},{}],63:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactPropTypeLocations
+ */
+
+"use strict";
+
+var keyMirror = require("./keyMirror");
+
+var ReactPropTypeLocations = keyMirror({
+  prop: null,
+  context: null,
+  childContext: null
+});
+
+module.exports = ReactPropTypeLocations;
+
+},{"./keyMirror":114}],64:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactPropTypes
+ */
+
+"use strict";
+
+var ReactComponent = require("./ReactComponent");
+var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames");
+
+var warning = require("./warning");
+var createObjectFrom = require("./createObjectFrom");
+
+/**
+ * Collection of methods that allow declaration and validation of props that are
+ * supplied to React components. Example usage:
+ *
+ *   var Props = require('ReactPropTypes');
+ *   var MyArticle = React.createClass({
+ *     propTypes: {
+ *       // An optional string prop named "description".
+ *       description: Props.string,
+ *
+ *       // A required enum prop named "category".
+ *       category: Props.oneOf(['News','Photos']).isRequired,
+ *
+ *       // A prop named "dialog" that requires an instance of Dialog.
+ *       dialog: Props.instanceOf(Dialog).isRequired
+ *     },
+ *     render: function() { ... }
+ *   });
+ *
+ * A more formal specification of how these methods are used:
+ *
+ *   type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)
+ *   decl := ReactPropTypes.{type}(.isRequired)?
+ *
+ * Each and every declaration produces a function with the same signature. This
+ * allows the creation of custom validation functions. For example:
+ *
+ *   var Props = require('ReactPropTypes');
+ *   var MyLink = React.createClass({
+ *     propTypes: {
+ *       // An optional string or URI prop named "href".
+ *       href: function(props, propName, componentName) {
+ *         var propValue = props[propName];
+ *         warning(
+ *           propValue == null ||
+ *           typeof propValue === 'string' ||
+ *           propValue instanceof URI,
+ *           'Invalid `%s` supplied to `%s`, expected string or URI.',
+ *           propName,
+ *           componentName
+ *         );
+ *       }
+ *     },
+ *     render: function() { ... }
+ *   });
+ *
+ * @internal
+ */
+var Props = {
+
+  array: createPrimitiveTypeChecker('array'),
+  bool: createPrimitiveTypeChecker('boolean'),
+  func: createPrimitiveTypeChecker('function'),
+  number: createPrimitiveTypeChecker('number'),
+  object: createPrimitiveTypeChecker('object'),
+  string: createPrimitiveTypeChecker('string'),
+
+  shape: createShapeTypeChecker,
+  oneOf: createEnumTypeChecker,
+  oneOfType: createUnionTypeChecker,
+  arrayOf: createArrayOfTypeChecker,
+
+  instanceOf: createInstanceTypeChecker,
+
+  renderable: createRenderableTypeChecker(),
+
+  component: createComponentTypeChecker(),
+
+  any: createAnyTypeChecker()
+};
+
+var ANONYMOUS = '<<anonymous>>';
+
+function isRenderable(propValue) {
+  switch(typeof propValue) {
+    case 'number':
+    case 'string':
+      return true;
+    case 'object':
+      if (Array.isArray(propValue)) {
+        return propValue.every(isRenderable);
+      }
+      if (ReactComponent.isValidComponent(propValue)) {
+        return true;
+      }
+      for (var k in propValue) {
+        if (!isRenderable(propValue[k])) {
+          return false;
+        }
+      }
+      return true;
+    default:
+      return false;
+  }
+}
+
+// Equivalent of typeof but with special handling for arrays
+function getPropType(propValue) {
+  var propType = typeof propValue;
+  if (propType === 'object' && Array.isArray(propValue)) {
+    return 'array';
+  }
+  return propType;
+}
+
+function createAnyTypeChecker() {
+  function validateAnyType(
+    shouldWarn, propValue, propName, componentName, location
+  ) {
+    return true; // is always valid
+  }
+  return createChainableTypeChecker(validateAnyType);
+}
+
+function createPrimitiveTypeChecker(expectedType) {
+  function validatePrimitiveType(
+    shouldWarn, propValue, propName, componentName, location
+  ) {
+    var propType = getPropType(propValue);
+    var isValid = propType === expectedType;
+    if (shouldWarn) {
+      ("production" !== "development" ? warning(
+        isValid,
+        'Invalid %s `%s` of type `%s` supplied to `%s`, expected `%s`.',
+        ReactPropTypeLocationNames[location],
+        propName,
+        propType,
+        componentName,
+        expectedType
+      ) : null);
+    }
+    return isValid;
+  }
+  return createChainableTypeChecker(validatePrimitiveType);
+}
+
+function createEnumTypeChecker(expectedValues) {
+  var expectedEnum = createObjectFrom(expectedValues);
+  function validateEnumType(
+    shouldWarn, propValue, propName, componentName, location
+  ) {
+    var isValid = expectedEnum[propValue];
+    if (shouldWarn) {
+      ("production" !== "development" ? warning(
+        isValid,
+        'Invalid %s `%s` supplied to `%s`, expected one of %s.',
+        ReactPropTypeLocationNames[location],
+        propName,
+        componentName,
+        JSON.stringify(Object.keys(expectedEnum))
+      ) : null);
+    }
+    return isValid;
+  }
+  return createChainableTypeChecker(validateEnumType);
+}
+
+function createShapeTypeChecker(shapeTypes) {
+  function validateShapeType(
+    shouldWarn, propValue, propName, componentName, location
+  ) {
+    var propType = getPropType(propValue);
+    var isValid = propType === 'object';
+    if (isValid) {
+      for (var key in shapeTypes) {
+        var checker = shapeTypes[key];
+        if (checker && !checker(propValue, key, componentName, location)) {
+          return false;
+        }
+      }
+    }
+    if (shouldWarn) {
+      ("production" !== "development" ? warning(
+        isValid,
+        'Invalid %s `%s` of type `%s` supplied to `%s`, expected `object`.',
+        ReactPropTypeLocationNames[location],
+        propName,
+        propType,
+        componentName
+      ) : null);
+    }
+    return isValid;
+  }
+  return createChainableTypeChecker(validateShapeType);
+}
+
+function createInstanceTypeChecker(expectedClass) {
+  function validateInstanceType(
+    shouldWarn, propValue, propName, componentName, location
+  ) {
+    var isValid = propValue instanceof expectedClass;
+    if (shouldWarn) {
+      ("production" !== "development" ? warning(
+        isValid,
+        'Invalid %s `%s` supplied to `%s`, expected instance of `%s`.',
+        ReactPropTypeLocationNames[location],
+        propName,
+        componentName,
+        expectedClass.name || ANONYMOUS
+      ) : null);
+    }
+    return isValid;
+  }
+  return createChainableTypeChecker(validateInstanceType);
+}
+
+function createArrayOfTypeChecker(propTypeChecker) {
+  function validateArrayType(
+    shouldWarn, propValue, propName, componentName, location
+  ) {
+    var isValid = Array.isArray(propValue);
+    if (isValid) {
+      for (var i = 0; i < propValue.length; i++) {
+        if (!propTypeChecker(propValue, i, componentName, location)) {
+          return false;
+        }
+      }
+    }
+    if (shouldWarn) {
+      ("production" !== "development" ? warning(
+        isValid,
+        'Invalid %s `%s` supplied to `%s`, expected an array.',
+        ReactPropTypeLocationNames[location],
+        propName,
+        componentName
+      ) : null);
+    }
+    return isValid;
+  }
+  return createChainableTypeChecker(validateArrayType);
+}
+
+function createRenderableTypeChecker() {
+  function validateRenderableType(
+    shouldWarn, propValue, propName, componentName, location
+  ) {
+    var isValid = isRenderable(propValue);
+    if (shouldWarn) {
+      ("production" !== "development" ? warning(
+        isValid,
+        'Invalid %s `%s` supplied to `%s`, expected a renderable prop.',
+        ReactPropTypeLocationNames[location],
+        propName,
+        componentName
+      ) : null);
+    }
+    return isValid;
+  }
+  return createChainableTypeChecker(validateRenderableType);
+}
+
+function createComponentTypeChecker() {
+  function validateComponentType(
+    shouldWarn, propValue, propName, componentName, location
+  ) {
+    var isValid = ReactComponent.isValidComponent(propValue);
+    if (shouldWarn) {
+      ("production" !== "development" ? warning(
+        isValid,
+        'Invalid %s `%s` supplied to `%s`, expected a React component.',
+        ReactPropTypeLocationNames[location],
+        propName,
+        componentName
+      ) : null);
+    }
+    return isValid;
+  }
+  return createChainableTypeChecker(validateComponentType);
+}
+
+function createUnionTypeChecker(arrayOfValidators) {
+  return function(props, propName, componentName, location) {
+    var isValid = false;
+    for (var ii = 0; ii < arrayOfValidators.length; ii++) {
+      var validate = arrayOfValidators[ii];
+      if (typeof validate.weak === 'function') {
+        validate = validate.weak;
+      }
+      if (validate(props, propName, componentName, location)) {
+        isValid = true;
+        break;
+      }
+    }
+    ("production" !== "development" ? warning(
+      isValid,
+      'Invalid %s `%s` supplied to `%s`.',
+      ReactPropTypeLocationNames[location],
+      propName,
+      componentName || ANONYMOUS
+    ) : null);
+    return isValid;
+  };
+}
+
+function createChainableTypeChecker(validate) {
+  function checkType(
+    isRequired, shouldWarn, props, propName, componentName, location
+  ) {
+    var propValue = props[propName];
+    if (propValue != null) {
+      // Only validate if there is a value to check.
+      return validate(
+        shouldWarn,
+        propValue,
+        propName,
+        componentName || ANONYMOUS,
+        location
+      );
+    } else {
+      var isValid = !isRequired;
+      if (shouldWarn) {
+        ("production" !== "development" ? warning(
+          isValid,
+          'Required %s `%s` was not specified in `%s`.',
+          ReactPropTypeLocationNames[location],
+          propName,
+          componentName || ANONYMOUS
+        ) : null);
+      }
+      return isValid;
+    }
+  }
+
+  var checker = checkType.bind(null, false, true);
+  checker.weak = checkType.bind(null, false, false);
+  checker.isRequired = checkType.bind(null, true, true);
+  checker.weak.isRequired = checkType.bind(null, true, false);
+  checker.isRequired.weak = checker.weak.isRequired;
+
+  return checker;
+}
+
+module.exports = Props;
+
+},{"./ReactComponent":26,"./ReactPropTypeLocationNames":62,"./createObjectFrom":93,"./warning":129}],65:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactPutListenerQueue
+ */
+
+"use strict";
+
+var PooledClass = require("./PooledClass");
+var ReactEventEmitter = require("./ReactEventEmitter");
+
+var mixInto = require("./mixInto");
+
+function ReactPutListenerQueue() {
+  this.listenersToPut = [];
+}
+
+mixInto(ReactPutListenerQueue, {
+  enqueuePutListener: function(rootNodeID, propKey, propValue) {
+    this.listenersToPut.push({
+      rootNodeID: rootNodeID,
+      propKey: propKey,
+      propValue: propValue
+    });
+  },
+
+  putListeners: function() {
+    for (var i = 0; i < this.listenersToPut.length; i++) {
+      var listenerToPut = this.listenersToPut[i];
+      ReactEventEmitter.putListener(
+        listenerToPut.rootNodeID,
+        listenerToPut.propKey,
+        listenerToPut.propValue
+      );
+    }
+  },
+
+  reset: function() {
+    this.listenersToPut.length = 0;
+  },
+
+  destructor: function() {
+    this.reset();
+  }
+});
+
+PooledClass.addPoolingTo(ReactPutListenerQueue);
+
+module.exports = ReactPutListenerQueue;
+
+},{"./PooledClass":23,"./ReactEventEmitter":48,"./mixInto":120}],66:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactReconcileTransaction
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var ExecutionEnvironment = require("./ExecutionEnvironment");
+var PooledClass = require("./PooledClass");
+var ReactEventEmitter = require("./ReactEventEmitter");
+var ReactInputSelection = require("./ReactInputSelection");
+var ReactMountReady = require("./ReactMountReady");
+var ReactPutListenerQueue = require("./ReactPutListenerQueue");
+var Transaction = require("./Transaction");
+
+var mixInto = require("./mixInto");
+
+/**
+ * Ensures that, when possible, the selection range (currently selected text
+ * input) is not disturbed by performing the transaction.
+ */
+var SELECTION_RESTORATION = {
+  /**
+   * @return {Selection} Selection information.
+   */
+  initialize: ReactInputSelection.getSelectionInformation,
+  /**
+   * @param {Selection} sel Selection information returned from `initialize`.
+   */
+  close: ReactInputSelection.restoreSelection
+};
+
+/**
+ * Suppresses events (blur/focus) that could be inadvertently dispatched due to
+ * high level DOM manipulations (like temporarily removing a text input from the
+ * DOM).
+ */
+var EVENT_SUPPRESSION = {
+  /**
+   * @return {boolean} The enabled status of `ReactEventEmitter` before the
+   * reconciliation.
+   */
+  initialize: function() {
+    var currentlyEnabled = ReactEventEmitter.isEnabled();
+    ReactEventEmitter.setEnabled(false);
+    return currentlyEnabled;
+  },
+
+  /**
+   * @param {boolean} previouslyEnabled Enabled status of `ReactEventEmitter`
+   *   before the reconciliation occured. `close` restores the previous value.
+   */
+  close: function(previouslyEnabled) {
+    ReactEventEmitter.setEnabled(previouslyEnabled);
+  }
+};
+
+/**
+ * Provides a `ReactMountReady` queue for collecting `onDOMReady` callbacks
+ * during the performing of the transaction.
+ */
+var ON_DOM_READY_QUEUEING = {
+  /**
+   * Initializes the internal `onDOMReady` queue.
+   */
+  initialize: function() {
+    this.reactMountReady.reset();
+  },
+
+  /**
+   * After DOM is flushed, invoke all registered `onDOMReady` callbacks.
+   */
+  close: function() {
+    this.reactMountReady.notifyAll();
+  }
+};
+
+var PUT_LISTENER_QUEUEING = {
+  initialize: function() {
+    this.putListenerQueue.reset();
+  },
+
+  close: function() {
+    this.putListenerQueue.putListeners();
+  }
+};
+
+/**
+ * Executed within the scope of the `Transaction` instance. Consider these as
+ * being member methods, but with an implied ordering while being isolated from
+ * each other.
+ */
+var TRANSACTION_WRAPPERS = [
+  PUT_LISTENER_QUEUEING,
+  SELECTION_RESTORATION,
+  EVENT_SUPPRESSION,
+  ON_DOM_READY_QUEUEING
+];
+
+/**
+ * Currently:
+ * - The order that these are listed in the transaction is critical:
+ * - Suppresses events.
+ * - Restores selection range.
+ *
+ * Future:
+ * - Restore document/overflow scroll positions that were unintentionally
+ *   modified via DOM insertions above the top viewport boundary.
+ * - Implement/integrate with customized constraint based layout system and keep
+ *   track of which dimensions must be remeasured.
+ *
+ * @class ReactReconcileTransaction
+ */
+function ReactReconcileTransaction() {
+  this.reinitializeTransaction();
+  this.reactMountReady = ReactMountReady.getPooled(null);
+  this.putListenerQueue = ReactPutListenerQueue.getPooled();
+}
+
+var Mixin = {
+  /**
+   * @see Transaction
+   * @abstract
+   * @final
+   * @return {array<object>} List of operation wrap proceedures.
+   *   TODO: convert to array<TransactionWrapper>
+   */
+  getTransactionWrappers: function() {
+    if (ExecutionEnvironment.canUseDOM) {
+      return TRANSACTION_WRAPPERS;
+    } else {
+      return [];
+    }
+  },
+
+  /**
+   * @return {object} The queue to collect `onDOMReady` callbacks with.
+   *   TODO: convert to ReactMountReady
+   */
+  getReactMountReady: function() {
+    return this.reactMountReady;
+  },
+
+  getPutListenerQueue: function() {
+    return this.putListenerQueue;
+  },
+
+  /**
+   * `PooledClass` looks for this, and will invoke this before allowing this
+   * instance to be resused.
+   */
+  destructor: function() {
+    ReactMountReady.release(this.reactMountReady);
+    this.reactMountReady = null;
+
+    ReactPutListenerQueue.release(this.putListenerQueue);
+    this.putListenerQueue = null;
+  }
+};
+
+
+mixInto(ReactReconcileTransaction, Transaction.Mixin);
+mixInto(ReactReconcileTransaction, Mixin);
+
+PooledClass.addPoolingTo(ReactReconcileTransaction);
+
+module.exports = ReactReconcileTransaction;
+
+},{"./ExecutionEnvironment":20,"./PooledClass":23,"./ReactEventEmitter":48,"./ReactInputSelection":52,"./ReactMountReady":56,"./ReactPutListenerQueue":65,"./Transaction":84,"./mixInto":120}],67:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactRootIndex
+ * @typechecks
+ */
+
+"use strict";
+
+var ReactRootIndexInjection = {
+  /**
+   * @param {function} _createReactRootIndex
+   */
+  injectCreateReactRootIndex: function(_createReactRootIndex) {
+    ReactRootIndex.createReactRootIndex = _createReactRootIndex;
+  }
+};
+
+var ReactRootIndex = {
+  createReactRootIndex: null,
+  injection: ReactRootIndexInjection
+};
+
+module.exports = ReactRootIndex;
+
+},{}],68:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @typechecks static-only
+ * @providesModule ReactServerRendering
+ */
+"use strict";
+
+var ReactComponent = require("./ReactComponent");
+var ReactInstanceHandles = require("./ReactInstanceHandles");
+var ReactMarkupChecksum = require("./ReactMarkupChecksum");
+var ReactReconcileTransaction = require("./ReactReconcileTransaction");
+
+var invariant = require("./invariant");
+
+/**
+ * @param {ReactComponent} component
+ * @return {string} the markup
+ */
+function renderComponentToString(component) {
+  ("production" !== "development" ? invariant(
+    ReactComponent.isValidComponent(component),
+    'renderComponentToString(): You must pass a valid ReactComponent.'
+  ) : invariant(ReactComponent.isValidComponent(component)));
+
+  ("production" !== "development" ? invariant(
+    !(arguments.length === 2 && typeof arguments[1] === 'function'),
+    'renderComponentToString(): This function became synchronous and now ' +
+    'returns the generated markup. Please remove the second parameter.'
+  ) : invariant(!(arguments.length === 2 && typeof arguments[1] === 'function')));
+
+  var id = ReactInstanceHandles.createReactRootID();
+  var transaction = ReactReconcileTransaction.getPooled();
+  transaction.reinitializeTransaction();
+  try {
+    return transaction.perform(function() {
+      var markup = component.mountComponent(id, transaction, 0);
+      return ReactMarkupChecksum.addChecksumToMarkup(markup);
+    }, null);
+  } finally {
+    ReactReconcileTransaction.release(transaction);
+  }
+}
+
+module.exports = {
+  renderComponentToString: renderComponentToString
+};
+
+},{"./ReactComponent":26,"./ReactInstanceHandles":53,"./ReactMarkupChecksum":54,"./ReactReconcileTransaction":66,"./invariant":108}],69:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactTextComponent
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var DOMPropertyOperations = require("./DOMPropertyOperations");
+var ReactComponent = require("./ReactComponent");
+
+var escapeTextForBrowser = require("./escapeTextForBrowser");
+var mixInto = require("./mixInto");
+
+/**
+ * Text nodes violate a couple assumptions that React makes about components:
+ *
+ *  - When mounting text into the DOM, adjacent text nodes are merged.
+ *  - Text nodes cannot be assigned a React root ID.
+ *
+ * This component is used to wrap strings in elements so that they can undergo
+ * the same reconciliation that is applied to elements.
+ *
+ * TODO: Investigate representing React components in the DOM with text nodes.
+ *
+ * @class ReactTextComponent
+ * @extends ReactComponent
+ * @internal
+ */
+var ReactTextComponent = function(initialText) {
+  this.construct({text: initialText});
+};
+
+mixInto(ReactTextComponent, ReactComponent.Mixin);
+mixInto(ReactTextComponent, {
+
+  /**
+   * Creates the markup for this text node. This node is not intended to have
+   * any features besides containing text content.
+   *
+   * @param {string} rootID DOM ID of the root node.
+   * @param {ReactReconcileTransaction} transaction
+   * @param {number} mountDepth number of components in the owner hierarchy
+   * @return {string} Markup for this text node.
+   * @internal
+   */
+  mountComponent: function(rootID, transaction, mountDepth) {
+    ReactComponent.Mixin.mountComponent.call(
+      this,
+      rootID,
+      transaction,
+      mountDepth
+    );
+    return (
+      '<span ' + DOMPropertyOperations.createMarkupForID(rootID) + '>' +
+        escapeTextForBrowser(this.props.text) +
+      '</span>'
+    );
+  },
+
+  /**
+   * Updates this component by updating the text content.
+   *
+   * @param {object} nextComponent Contains the next text content.
+   * @param {ReactReconcileTransaction} transaction
+   * @internal
+   */
+  receiveComponent: function(nextComponent, transaction) {
+    var nextProps = nextComponent.props;
+    if (nextProps.text !== this.props.text) {
+      this.props.text = nextProps.text;
+      ReactComponent.BackendIDOperations.updateTextContentByID(
+        this._rootNodeID,
+        nextProps.text
+      );
+    }
+  }
+
+});
+
+// Expose the constructor on itself and the prototype for consistency with other
+// descriptors.
+ReactTextComponent.type = ReactTextComponent;
+ReactTextComponent.prototype.type = ReactTextComponent;
+
+module.exports = ReactTextComponent;
+
+},{"./DOMPropertyOperations":9,"./ReactComponent":26,"./escapeTextForBrowser":96,"./mixInto":120}],70:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ReactUpdates
+ */
+
+"use strict";
+
+var ReactPerf = require("./ReactPerf");
+
+var invariant = require("./invariant");
+
+var dirtyComponents = [];
+
+var batchingStrategy = null;
+
+function ensureBatchingStrategy() {
+  ("production" !== "development" ? invariant(batchingStrategy, 'ReactUpdates: must inject a batching strategy') : invariant(batchingStrategy));
+}
+
+function batchedUpdates(callback, param) {
+  ensureBatchingStrategy();
+  batchingStrategy.batchedUpdates(callback, param);
+}
+
+/**
+ * Array comparator for ReactComponents by owner depth
+ *
+ * @param {ReactComponent} c1 first component you're comparing
+ * @param {ReactComponent} c2 second component you're comparing
+ * @return {number} Return value usable by Array.prototype.sort().
+ */
+function mountDepthComparator(c1, c2) {
+  return c1._mountDepth - c2._mountDepth;
+}
+
+function runBatchedUpdates() {
+  // Since reconciling a component higher in the owner hierarchy usually (not
+  // always -- see shouldComponentUpdate()) will reconcile children, reconcile
+  // them before their children by sorting the array.
+
+  dirtyComponents.sort(mountDepthComparator);
+
+  for (var i = 0; i < dirtyComponents.length; i++) {
+    // If a component is unmounted before pending changes apply, ignore them
+    // TODO: Queue unmounts in the same list to avoid this happening at all
+    var component = dirtyComponents[i];
+    if (component.isMounted()) {
+      // If performUpdateIfNecessary happens to enqueue any new updates, we
+      // shouldn't execute the callbacks until the next render happens, so
+      // stash the callbacks first
+      var callbacks = component._pendingCallbacks;
+      component._pendingCallbacks = null;
+      component.performUpdateIfNecessary();
+      if (callbacks) {
+        for (var j = 0; j < callbacks.length; j++) {
+          callbacks[j].call(component);
+        }
+      }
+    }
+  }
+}
+
+function clearDirtyComponents() {
+  dirtyComponents.length = 0;
+}
+
+var flushBatchedUpdates = ReactPerf.measure(
+  'ReactUpdates',
+  'flushBatchedUpdates',
+  function() {
+    // Run these in separate functions so the JIT can optimize
+    try {
+      runBatchedUpdates();
+    } finally {
+      clearDirtyComponents();
+    }
+  }
+);
+
+/**
+ * Mark a component as needing a rerender, adding an optional callback to a
+ * list of functions which will be executed once the rerender occurs.
+ */
+function enqueueUpdate(component, callback) {
+  ("production" !== "development" ? invariant(
+    !callback || typeof callback === "function",
+    'enqueueUpdate(...): You called `setProps`, `replaceProps`, ' +
+    '`setState`, `replaceState`, or `forceUpdate` with a callback that ' +
+    'isn\'t callable.'
+  ) : invariant(!callback || typeof callback === "function"));
+  ensureBatchingStrategy();
+
+  if (!batchingStrategy.isBatchingUpdates) {
+    component.performUpdateIfNecessary();
+    callback && callback.call(component);
+    return;
+  }
+
+  dirtyComponents.push(component);
+
+  if (callback) {
+    if (component._pendingCallbacks) {
+      component._pendingCallbacks.push(callback);
+    } else {
+      component._pendingCallbacks = [callback];
+    }
+  }
+}
+
+var ReactUpdatesInjection = {
+  injectBatchingStrategy: function(_batchingStrategy) {
+    ("production" !== "development" ? invariant(
+      _batchingStrategy,
+      'ReactUpdates: must provide a batching strategy'
+    ) : invariant(_batchingStrategy));
+    ("production" !== "development" ? invariant(
+      typeof _batchingStrategy.batchedUpdates === 'function',
+      'ReactUpdates: must provide a batchedUpdates() function'
+    ) : invariant(typeof _batchingStrategy.batchedUpdates === 'function'));
+    ("production" !== "development" ? invariant(
+      typeof _batchingStrategy.isBatchingUpdates === 'boolean',
+      'ReactUpdates: must provide an isBatchingUpdates boolean attribute'
+    ) : invariant(typeof _batchingStrategy.isBatchingUpdates === 'boolean'));
+    batchingStrategy = _batchingStrategy;
+  }
+};
+
+var ReactUpdates = {
+  batchedUpdates: batchedUpdates,
+  enqueueUpdate: enqueueUpdate,
+  flushBatchedUpdates: flushBatchedUpdates,
+  injection: ReactUpdatesInjection
+};
+
+module.exports = ReactUpdates;
+
+},{"./ReactPerf":60,"./invariant":108}],71:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule SelectEventPlugin
+ */
+
+"use strict";
+
+var EventConstants = require("./EventConstants");
+var EventPropagators = require("./EventPropagators");
+var ReactInputSelection = require("./ReactInputSelection");
+var SyntheticEvent = require("./SyntheticEvent");
+
+var getActiveElement = require("./getActiveElement");
+var isTextInputElement = require("./isTextInputElement");
+var keyOf = require("./keyOf");
+var shallowEqual = require("./shallowEqual");
+
+var topLevelTypes = EventConstants.topLevelTypes;
+
+var eventTypes = {
+  select: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onSelect: null}),
+      captured: keyOf({onSelectCapture: null})
+    },
+    dependencies: [
+      topLevelTypes.topBlur,
+      topLevelTypes.topContextMenu,
+      topLevelTypes.topFocus,
+      topLevelTypes.topKeyDown,
+      topLevelTypes.topMouseDown,
+      topLevelTypes.topMouseUp,
+      topLevelTypes.topSelectionChange
+    ]
+  }
+};
+
+var activeElement = null;
+var activeElementID = null;
+var lastSelection = null;
+var mouseDown = false;
+
+/**
+ * Get an object which is a unique representation of the current selection.
+ *
+ * The return value will not be consistent across nodes or browsers, but
+ * two identical selections on the same node will return identical objects.
+ *
+ * @param {DOMElement} node
+ * @param {object}
+ */
+function getSelection(node) {
+  if ('selectionStart' in node &&
+      ReactInputSelection.hasSelectionCapabilities(node)) {
+    return {
+      start: node.selectionStart,
+      end: node.selectionEnd
+    };
+  } else if (document.selection) {
+    var range = document.selection.createRange();
+    return {
+      parentElement: range.parentElement(),
+      text: range.text,
+      top: range.boundingTop,
+      left: range.boundingLeft
+    };
+  } else {
+    var selection = window.getSelection();
+    return {
+      anchorNode: selection.anchorNode,
+      anchorOffset: selection.anchorOffset,
+      focusNode: selection.focusNode,
+      focusOffset: selection.focusOffset
+    };
+  }
+}
+
+/**
+ * Poll selection to see whether it's changed.
+ *
+ * @param {object} nativeEvent
+ * @return {?SyntheticEvent}
+ */
+function constructSelectEvent(nativeEvent) {
+  // Ensure we have the right element, and that the user is not dragging a
+  // selection (this matches native `select` event behavior). In HTML5, select
+  // fires only on input and textarea thus if there's no focused element we
+  // won't dispatch.
+  if (mouseDown ||
+      activeElement == null ||
+      activeElement != getActiveElement()) {
+    return;
+  }
+
+  // Only fire when selection has actually changed.
+  var currentSelection = getSelection(activeElement);
+  if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
+    lastSelection = currentSelection;
+
+    var syntheticEvent = SyntheticEvent.getPooled(
+      eventTypes.select,
+      activeElementID,
+      nativeEvent
+    );
+
+    syntheticEvent.type = 'select';
+    syntheticEvent.target = activeElement;
+
+    EventPropagators.accumulateTwoPhaseDispatches(syntheticEvent);
+
+    return syntheticEvent;
+  }
+}
+
+/**
+ * This plugin creates an `onSelect` event that normalizes select events
+ * across form elements.
+ *
+ * Supported elements are:
+ * - input (see `isTextInputElement`)
+ * - textarea
+ * - contentEditable
+ *
+ * This differs from native browser implementations in the following ways:
+ * - Fires on contentEditable fields as well as inputs.
+ * - Fires for collapsed selection.
+ * - Fires after user input.
+ */
+var SelectEventPlugin = {
+
+  eventTypes: eventTypes,
+
+  /**
+   * @param {string} topLevelType Record from `EventConstants`.
+   * @param {DOMEventTarget} topLevelTarget The listening component root node.
+   * @param {string} topLevelTargetID ID of `topLevelTarget`.
+   * @param {object} nativeEvent Native browser event.
+   * @return {*} An accumulation of synthetic events.
+   * @see {EventPluginHub.extractEvents}
+   */
+  extractEvents: function(
+      topLevelType,
+      topLevelTarget,
+      topLevelTargetID,
+      nativeEvent) {
+
+    switch (topLevelType) {
+      // Track the input node that has focus.
+      case topLevelTypes.topFocus:
+        if (isTextInputElement(topLevelTarget) ||
+            topLevelTarget.contentEditable === 'true') {
+          activeElement = topLevelTarget;
+          activeElementID = topLevelTargetID;
+          lastSelection = null;
+        }
+        break;
+      case topLevelTypes.topBlur:
+        activeElement = null;
+        activeElementID = null;
+        lastSelection = null;
+        break;
+
+      // Don't fire the event while the user is dragging. This matches the
+      // semantics of the native select event.
+      case topLevelTypes.topMouseDown:
+        mouseDown = true;
+        break;
+      case topLevelTypes.topContextMenu:
+      case topLevelTypes.topMouseUp:
+        mouseDown = false;
+        return constructSelectEvent(nativeEvent);
+
+      // Chrome and IE fire non-standard event when selection is changed (and
+      // sometimes when it hasn't).
+      // Firefox doesn't support selectionchange, so check selection status
+      // after each key entry. The selection changes after keydown and before
+      // keyup, but we check on keydown as well in the case of holding down a
+      // key, when multiple keydown events are fired but only one keyup is.
+      case topLevelTypes.topSelectionChange:
+      case topLevelTypes.topKeyDown:
+      case topLevelTypes.topKeyUp:
+        return constructSelectEvent(nativeEvent);
+    }
+  }
+};
+
+module.exports = SelectEventPlugin;
+
+},{"./EventConstants":14,"./EventPropagators":19,"./ReactInputSelection":52,"./SyntheticEvent":77,"./getActiveElement":99,"./isTextInputElement":111,"./keyOf":115,"./shallowEqual":125}],72:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ServerReactRootIndex
+ * @typechecks
+ */
+
+"use strict";
+
+/**
+ * Size of the reactRoot ID space. We generate random numbers for React root
+ * IDs and if there's a collision the events and DOM update system will
+ * get confused. In the future we need a way to generate GUIDs but for
+ * now this will work on a smaller scale.
+ */
+var GLOBAL_MOUNT_POINT_MAX = Math.pow(2, 53);
+
+var ServerReactRootIndex = {
+  createReactRootIndex: function() {
+    return Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX);
+  }
+};
+
+module.exports = ServerReactRootIndex;
+
+},{}],73:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule SimpleEventPlugin
+ */
+
+"use strict";
+
+var EventConstants = require("./EventConstants");
+var EventPluginUtils = require("./EventPluginUtils");
+var EventPropagators = require("./EventPropagators");
+var SyntheticClipboardEvent = require("./SyntheticClipboardEvent");
+var SyntheticEvent = require("./SyntheticEvent");
+var SyntheticFocusEvent = require("./SyntheticFocusEvent");
+var SyntheticKeyboardEvent = require("./SyntheticKeyboardEvent");
+var SyntheticMouseEvent = require("./SyntheticMouseEvent");
+var SyntheticDragEvent = require("./SyntheticDragEvent");
+var SyntheticTouchEvent = require("./SyntheticTouchEvent");
+var SyntheticUIEvent = require("./SyntheticUIEvent");
+var SyntheticWheelEvent = require("./SyntheticWheelEvent");
+
+var invariant = require("./invariant");
+var keyOf = require("./keyOf");
+
+var topLevelTypes = EventConstants.topLevelTypes;
+
+var eventTypes = {
+  blur: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onBlur: true}),
+      captured: keyOf({onBlurCapture: true})
+    }
+  },
+  click: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onClick: true}),
+      captured: keyOf({onClickCapture: true})
+    }
+  },
+  contextMenu: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onContextMenu: true}),
+      captured: keyOf({onContextMenuCapture: true})
+    }
+  },
+  copy: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onCopy: true}),
+      captured: keyOf({onCopyCapture: true})
+    }
+  },
+  cut: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onCut: true}),
+      captured: keyOf({onCutCapture: true})
+    }
+  },
+  doubleClick: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onDoubleClick: true}),
+      captured: keyOf({onDoubleClickCapture: true})
+    }
+  },
+  drag: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onDrag: true}),
+      captured: keyOf({onDragCapture: true})
+    }
+  },
+  dragEnd: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onDragEnd: true}),
+      captured: keyOf({onDragEndCapture: true})
+    }
+  },
+  dragEnter: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onDragEnter: true}),
+      captured: keyOf({onDragEnterCapture: true})
+    }
+  },
+  dragExit: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onDragExit: true}),
+      captured: keyOf({onDragExitCapture: true})
+    }
+  },
+  dragLeave: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onDragLeave: true}),
+      captured: keyOf({onDragLeaveCapture: true})
+    }
+  },
+  dragOver: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onDragOver: true}),
+      captured: keyOf({onDragOverCapture: true})
+    }
+  },
+  dragStart: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onDragStart: true}),
+      captured: keyOf({onDragStartCapture: true})
+    }
+  },
+  drop: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onDrop: true}),
+      captured: keyOf({onDropCapture: true})
+    }
+  },
+  focus: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onFocus: true}),
+      captured: keyOf({onFocusCapture: true})
+    }
+  },
+  input: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onInput: true}),
+      captured: keyOf({onInputCapture: true})
+    }
+  },
+  keyDown: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onKeyDown: true}),
+      captured: keyOf({onKeyDownCapture: true})
+    }
+  },
+  keyPress: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onKeyPress: true}),
+      captured: keyOf({onKeyPressCapture: true})
+    }
+  },
+  keyUp: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onKeyUp: true}),
+      captured: keyOf({onKeyUpCapture: true})
+    }
+  },
+  load: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onLoad: true}),
+      captured: keyOf({onLoadCapture: true})
+    }
+  },
+  error: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onError: true}),
+      captured: keyOf({onErrorCapture: true})
+    }
+  },
+  // Note: We do not allow listening to mouseOver events. Instead, use the
+  // onMouseEnter/onMouseLeave created by `EnterLeaveEventPlugin`.
+  mouseDown: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onMouseDown: true}),
+      captured: keyOf({onMouseDownCapture: true})
+    }
+  },
+  mouseMove: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onMouseMove: true}),
+      captured: keyOf({onMouseMoveCapture: true})
+    }
+  },
+  mouseOut: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onMouseOut: true}),
+      captured: keyOf({onMouseOutCapture: true})
+    }
+  },
+  mouseOver: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onMouseOver: true}),
+      captured: keyOf({onMouseOverCapture: true})
+    }
+  },
+  mouseUp: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onMouseUp: true}),
+      captured: keyOf({onMouseUpCapture: true})
+    }
+  },
+  paste: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onPaste: true}),
+      captured: keyOf({onPasteCapture: true})
+    }
+  },
+  reset: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onReset: true}),
+      captured: keyOf({onResetCapture: true})
+    }
+  },
+  scroll: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onScroll: true}),
+      captured: keyOf({onScrollCapture: true})
+    }
+  },
+  submit: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onSubmit: true}),
+      captured: keyOf({onSubmitCapture: true})
+    }
+  },
+  touchCancel: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onTouchCancel: true}),
+      captured: keyOf({onTouchCancelCapture: true})
+    }
+  },
+  touchEnd: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onTouchEnd: true}),
+      captured: keyOf({onTouchEndCapture: true})
+    }
+  },
+  touchMove: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onTouchMove: true}),
+      captured: keyOf({onTouchMoveCapture: true})
+    }
+  },
+  touchStart: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onTouchStart: true}),
+      captured: keyOf({onTouchStartCapture: true})
+    }
+  },
+  wheel: {
+    phasedRegistrationNames: {
+      bubbled: keyOf({onWheel: true}),
+      captured: keyOf({onWheelCapture: true})
+    }
+  }
+};
+
+var topLevelEventsToDispatchConfig = {
+  topBlur:        eventTypes.blur,
+  topClick:       eventTypes.click,
+  topContextMenu: eventTypes.contextMenu,
+  topCopy:        eventTypes.copy,
+  topCut:         eventTypes.cut,
+  topDoubleClick: eventTypes.doubleClick,
+  topDrag:        eventTypes.drag,
+  topDragEnd:     eventTypes.dragEnd,
+  topDragEnter:   eventTypes.dragEnter,
+  topDragExit:    eventTypes.dragExit,
+  topDragLeave:   eventTypes.dragLeave,
+  topDragOver:    eventTypes.dragOver,
+  topDragStart:   eventTypes.dragStart,
+  topDrop:        eventTypes.drop,
+  topError:       eventTypes.error,
+  topFocus:       eventTypes.focus,
+  topInput:       eventTypes.input,
+  topKeyDown:     eventTypes.keyDown,
+  topKeyPress:    eventTypes.keyPress,
+  topKeyUp:       eventTypes.keyUp,
+  topLoad:        eventTypes.load,
+  topMouseDown:   eventTypes.mouseDown,
+  topMouseMove:   eventTypes.mouseMove,
+  topMouseOut:    eventTypes.mouseOut,
+  topMouseOver:   eventTypes.mouseOver,
+  topMouseUp:     eventTypes.mouseUp,
+  topPaste:       eventTypes.paste,
+  topReset:       eventTypes.reset,
+  topScroll:      eventTypes.scroll,
+  topSubmit:      eventTypes.submit,
+  topTouchCancel: eventTypes.touchCancel,
+  topTouchEnd:    eventTypes.touchEnd,
+  topTouchMove:   eventTypes.touchMove,
+  topTouchStart:  eventTypes.touchStart,
+  topWheel:       eventTypes.wheel
+};
+
+for (var topLevelType in topLevelEventsToDispatchConfig) {
+  topLevelEventsToDispatchConfig[topLevelType].dependencies = [topLevelType];
+}
+
+var SimpleEventPlugin = {
+
+  eventTypes: eventTypes,
+
+  /**
+   * Same as the default implementation, except cancels the event when return
+   * value is false.
+   *
+   * @param {object} Event to be dispatched.
+   * @param {function} Application-level callback.
+   * @param {string} domID DOM ID to pass to the callback.
+   */
+  executeDispatch: function(event, listener, domID) {
+    var returnValue = EventPluginUtils.executeDispatch(event, listener, domID);
+    if (returnValue === false) {
+      event.stopPropagation();
+      event.preventDefault();
+    }
+  },
+
+  /**
+   * @param {string} topLevelType Record from `EventConstants`.
+   * @param {DOMEventTarget} topLevelTarget The listening component root node.
+   * @param {string} topLevelTargetID ID of `topLevelTarget`.
+   * @param {object} nativeEvent Native browser event.
+   * @return {*} An accumulation of synthetic events.
+   * @see {EventPluginHub.extractEvents}
+   */
+  extractEvents: function(
+      topLevelType,
+      topLevelTarget,
+      topLevelTargetID,
+      nativeEvent) {
+    var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
+    if (!dispatchConfig) {
+      return null;
+    }
+    var EventConstructor;
+    switch (topLevelType) {
+      case topLevelTypes.topInput:
+      case topLevelTypes.topLoad:
+      case topLevelTypes.topError:
+      case topLevelTypes.topReset:
+      case topLevelTypes.topSubmit:
+        // HTML Events
+        // @see http://www.w3.org/TR/html5/index.html#events-0
+        EventConstructor = SyntheticEvent;
+        break;
+      case topLevelTypes.topKeyDown:
+      case topLevelTypes.topKeyPress:
+      case topLevelTypes.topKeyUp:
+        EventConstructor = SyntheticKeyboardEvent;
+        break;
+      case topLevelTypes.topBlur:
+      case topLevelTypes.topFocus:
+        EventConstructor = SyntheticFocusEvent;
+        break;
+      case topLevelTypes.topClick:
+        // Firefox creates a click event on right mouse clicks. This removes the
+        // unwanted click events.
+        if (nativeEvent.button === 2) {
+          return null;
+        }
+        /* falls through */
+      case topLevelTypes.topContextMenu:
+      case topLevelTypes.topDoubleClick:
+      case topLevelTypes.topMouseDown:
+      case topLevelTypes.topMouseMove:
+      case topLevelTypes.topMouseOut:
+      case topLevelTypes.topMouseOver:
+      case topLevelTypes.topMouseUp:
+        EventConstructor = SyntheticMouseEvent;
+        break;
+      case topLevelTypes.topDrag:
+      case topLevelTypes.topDragEnd:
+      case topLevelTypes.topDragEnter:
+      case topLevelTypes.topDragExit:
+      case topLevelTypes.topDragLeave:
+      case topLevelTypes.topDragOver:
+      case topLevelTypes.topDragStart:
+      case topLevelTypes.topDrop:
+        EventConstructor = SyntheticDragEvent;
+        break;
+      case topLevelTypes.topTouchCancel:
+      case topLevelTypes.topTouchEnd:
+      case topLevelTypes.topTouchMove:
+      case topLevelTypes.topTouchStart:
+        EventConstructor = SyntheticTouchEvent;
+        break;
+      case topLevelTypes.topScroll:
+        EventConstructor = SyntheticUIEvent;
+        break;
+      case topLevelTypes.topWheel:
+        EventConstructor = SyntheticWheelEvent;
+        break;
+      case topLevelTypes.topCopy:
+      case topLevelTypes.topCut:
+      case topLevelTypes.topPaste:
+        EventConstructor = SyntheticClipboardEvent;
+        break;
+    }
+    ("production" !== "development" ? invariant(
+      EventConstructor,
+      'SimpleEventPlugin: Unhandled event type, `%s`.',
+      topLevelType
+    ) : invariant(EventConstructor));
+    var event = EventConstructor.getPooled(
+      dispatchConfig,
+      topLevelTargetID,
+      nativeEvent
+    );
+    EventPropagators.accumulateTwoPhaseDispatches(event);
+    return event;
+  }
+
+};
+
+module.exports = SimpleEventPlugin;
+
+},{"./EventConstants":14,"./EventPluginUtils":18,"./EventPropagators":19,"./SyntheticClipboardEvent":74,"./SyntheticDragEvent":76,"./SyntheticEvent":77,"./SyntheticFocusEvent":78,"./SyntheticKeyboardEvent":79,"./SyntheticMouseEvent":80,"./SyntheticTouchEvent":81,"./SyntheticUIEvent":82,"./SyntheticWheelEvent":83,"./invariant":108,"./keyOf":115}],74:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule SyntheticClipboardEvent
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var SyntheticEvent = require("./SyntheticEvent");
+
+/**
+ * @interface Event
+ * @see http://www.w3.org/TR/clipboard-apis/
+ */
+var ClipboardEventInterface = {
+  clipboardData: function(event) {
+    return (
+      'clipboardData' in event ?
+        event.clipboardData :
+        window.clipboardData
+    );
+  }
+};
+
+/**
+ * @param {object} dispatchConfig Configuration used to dispatch this event.
+ * @param {string} dispatchMarker Marker identifying the event target.
+ * @param {object} nativeEvent Native browser event.
+ * @extends {SyntheticUIEvent}
+ */
+function SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent) {
+  SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
+}
+
+SyntheticEvent.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface);
+
+module.exports = SyntheticClipboardEvent;
+
+
+},{"./SyntheticEvent":77}],75:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule SyntheticCompositionEvent
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var SyntheticEvent = require("./SyntheticEvent");
+
+/**
+ * @interface Event
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
+ */
+var CompositionEventInterface = {
+  data: null
+};
+
+/**
+ * @param {object} dispatchConfig Configuration used to dispatch this event.
+ * @param {string} dispatchMarker Marker identifying the event target.
+ * @param {object} nativeEvent Native browser event.
+ * @extends {SyntheticUIEvent}
+ */
+function SyntheticCompositionEvent(
+  dispatchConfig,
+  dispatchMarker,
+  nativeEvent) {
+  SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
+}
+
+SyntheticEvent.augmentClass(
+  SyntheticCompositionEvent,
+  CompositionEventInterface
+);
+
+module.exports = SyntheticCompositionEvent;
+
+
+},{"./SyntheticEvent":77}],76:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule SyntheticDragEvent
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var SyntheticMouseEvent = require("./SyntheticMouseEvent");
+
+/**
+ * @interface DragEvent
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
+ */
+var DragEventInterface = {
+  dataTransfer: null
+};
+
+/**
+ * @param {object} dispatchConfig Configuration used to dispatch this event.
+ * @param {string} dispatchMarker Marker identifying the event target.
+ * @param {object} nativeEvent Native browser event.
+ * @extends {SyntheticUIEvent}
+ */
+function SyntheticDragEvent(dispatchConfig, dispatchMarker, nativeEvent) {
+  SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
+}
+
+SyntheticMouseEvent.augmentClass(SyntheticDragEvent, DragEventInterface);
+
+module.exports = SyntheticDragEvent;
+
+},{"./SyntheticMouseEvent":80}],77:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule SyntheticEvent
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var PooledClass = require("./PooledClass");
+
+var emptyFunction = require("./emptyFunction");
+var getEventTarget = require("./getEventTarget");
+var merge = require("./merge");
+var mergeInto = require("./mergeInto");
+
+/**
+ * @interface Event
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
+ */
+var EventInterface = {
+  type: null,
+  target: getEventTarget,
+  // currentTarget is set when dispatching; no use in copying it here
+  currentTarget: emptyFunction.thatReturnsNull,
+  eventPhase: null,
+  bubbles: null,
+  cancelable: null,
+  timeStamp: function(event) {
+    return event.timeStamp || Date.now();
+  },
+  defaultPrevented: null,
+  isTrusted: null
+};
+
+/**
+ * Synthetic events are dispatched by event plugins, typically in response to a
+ * top-level event delegation handler.
+ *
+ * These systems should generally use pooling to reduce the frequency of garbage
+ * collection. The system should check `isPersistent` to determine whether the
+ * event should be released into the pool after being dispatched. Users that
+ * need a persisted event should invoke `persist`.
+ *
+ * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
+ * normalizing browser quirks. Subclasses do not necessarily have to implement a
+ * DOM interface; custom application-specific events can also subclass this.
+ *
+ * @param {object} dispatchConfig Configuration used to dispatch this event.
+ * @param {string} dispatchMarker Marker identifying the event target.
+ * @param {object} nativeEvent Native browser event.
+ */
+function SyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent) {
+  this.dispatchConfig = dispatchConfig;
+  this.dispatchMarker = dispatchMarker;
+  this.nativeEvent = nativeEvent;
+
+  var Interface = this.constructor.Interface;
+  for (var propName in Interface) {
+    if (!Interface.hasOwnProperty(propName)) {
+      continue;
+    }
+    var normalize = Interface[propName];
+    if (normalize) {
+      this[propName] = normalize(nativeEvent);
+    } else {
+      this[propName] = nativeEvent[propName];
+    }
+  }
+
+  var defaultPrevented = nativeEvent.defaultPrevented != null ?
+    nativeEvent.defaultPrevented :
+    nativeEvent.returnValue === false;
+  if (defaultPrevented) {
+    this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
+  } else {
+    this.isDefaultPrevented = emptyFunction.thatReturnsFalse;
+  }
+  this.isPropagationStopped = emptyFunction.thatReturnsFalse;
+}
+
+mergeInto(SyntheticEvent.prototype, {
+
+  preventDefault: function() {
+    this.defaultPrevented = true;
+    var event = this.nativeEvent;
+    event.preventDefault ? event.preventDefault() : event.returnValue = false;
+    this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
+  },
+
+  stopPropagation: function() {
+    var event = this.nativeEvent;
+    event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true;
+    this.isPropagationStopped = emptyFunction.thatReturnsTrue;
+  },
+
+  /**
+   * We release all dispatched `SyntheticEvent`s after each event loop, adding
+   * them back into the pool. This allows a way to hold onto a reference that
+   * won't be added back into the pool.
+   */
+  persist: function() {
+    this.isPersistent = emptyFunction.thatReturnsTrue;
+  },
+
+  /**
+   * Checks if this event should be released back into the pool.
+   *
+   * @return {boolean} True if this should not be released, false otherwise.
+   */
+  isPersistent: emptyFunction.thatReturnsFalse,
+
+  /**
+   * `PooledClass` looks for `destructor` on each instance it releases.
+   */
+  destructor: function() {
+    var Interface = this.constructor.Interface;
+    for (var propName in Interface) {
+      this[propName] = null;
+    }
+    this.dispatchConfig = null;
+    this.dispatchMarker = null;
+    this.nativeEvent = null;
+  }
+
+});
+
+SyntheticEvent.Interface = EventInterface;
+
+/**
+ * Helper to reduce boilerplate when creating subclasses.
+ *
+ * @param {function} Class
+ * @param {?object} Interface
+ */
+SyntheticEvent.augmentClass = function(Class, Interface) {
+  var Super = this;
+
+  var prototype = Object.create(Super.prototype);
+  mergeInto(prototype, Class.prototype);
+  Class.prototype = prototype;
+  Class.prototype.constructor = Class;
+
+  Class.Interface = merge(Super.Interface, Interface);
+  Class.augmentClass = Super.augmentClass;
+
+  PooledClass.addPoolingTo(Class, PooledClass.threeArgumentPooler);
+};
+
+PooledClass.addPoolingTo(SyntheticEvent, PooledClass.threeArgumentPooler);
+
+module.exports = SyntheticEvent;
+
+},{"./PooledClass":23,"./emptyFunction":95,"./getEventTarget":101,"./merge":117,"./mergeInto":119}],78:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule SyntheticFocusEvent
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var SyntheticUIEvent = require("./SyntheticUIEvent");
+
+/**
+ * @interface FocusEvent
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
+ */
+var FocusEventInterface = {
+  relatedTarget: null
+};
+
+/**
+ * @param {object} dispatchConfig Configuration used to dispatch this event.
+ * @param {string} dispatchMarker Marker identifying the event target.
+ * @param {object} nativeEvent Native browser event.
+ * @extends {SyntheticUIEvent}
+ */
+function SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent) {
+  SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
+}
+
+SyntheticUIEvent.augmentClass(SyntheticFocusEvent, FocusEventInterface);
+
+module.exports = SyntheticFocusEvent;
+
+},{"./SyntheticUIEvent":82}],79:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule SyntheticKeyboardEvent
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var SyntheticUIEvent = require("./SyntheticUIEvent");
+
+var getEventKey = require("./getEventKey");
+
+/**
+ * @interface KeyboardEvent
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
+ */
+var KeyboardEventInterface = {
+  key: getEventKey,
+  location: null,
+  ctrlKey: null,
+  shiftKey: null,
+  altKey: null,
+  metaKey: null,
+  repeat: null,
+  locale: null,
+  // Legacy Interface
+  'char': null,
+  charCode: null,
+  keyCode: null,
+  which: null
+};
+
+/**
+ * @param {object} dispatchConfig Configuration used to dispatch this event.
+ * @param {string} dispatchMarker Marker identifying the event target.
+ * @param {object} nativeEvent Native browser event.
+ * @extends {SyntheticUIEvent}
+ */
+function SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent) {
+  SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
+}
+
+SyntheticUIEvent.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface);
+
+module.exports = SyntheticKeyboardEvent;
+
+},{"./SyntheticUIEvent":82,"./getEventKey":100}],80:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule SyntheticMouseEvent
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var SyntheticUIEvent = require("./SyntheticUIEvent");
+var ViewportMetrics = require("./ViewportMetrics");
+
+/**
+ * @interface MouseEvent
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
+ */
+var MouseEventInterface = {
+  screenX: null,
+  screenY: null,
+  clientX: null,
+  clientY: null,
+  ctrlKey: null,
+  shiftKey: null,
+  altKey: null,
+  metaKey: null,
+  button: function(event) {
+    // Webkit, Firefox, IE9+
+    // which:  1 2 3
+    // button: 0 1 2 (standard)
+    var button = event.button;
+    if ('which' in event) {
+      return button;
+    }
+    // IE<9
+    // which:  undefined
+    // button: 0 0 0
+    // button: 1 4 2 (onmouseup)
+    return button === 2 ? 2 : button === 4 ? 1 : 0;
+  },
+  buttons: null,
+  relatedTarget: function(event) {
+    return event.relatedTarget || (
+      event.fromElement === event.srcElement ?
+        event.toElement :
+        event.fromElement
+    );
+  },
+  // "Proprietary" Interface.
+  pageX: function(event) {
+    return 'pageX' in event ?
+      event.pageX :
+      event.clientX + ViewportMetrics.currentScrollLeft;
+  },
+  pageY: function(event) {
+    return 'pageY' in event ?
+      event.pageY :
+      event.clientY + ViewportMetrics.currentScrollTop;
+  }
+};
+
+/**
+ * @param {object} dispatchConfig Configuration used to dispatch this event.
+ * @param {string} dispatchMarker Marker identifying the event target.
+ * @param {object} nativeEvent Native browser event.
+ * @extends {SyntheticUIEvent}
+ */
+function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent) {
+  SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
+}
+
+SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface);
+
+module.exports = SyntheticMouseEvent;
+
+},{"./SyntheticUIEvent":82,"./ViewportMetrics":85}],81:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule SyntheticTouchEvent
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var SyntheticUIEvent = require("./SyntheticUIEvent");
+
+/**
+ * @interface TouchEvent
+ * @see http://www.w3.org/TR/touch-events/
+ */
+var TouchEventInterface = {
+  touches: null,
+  targetTouches: null,
+  changedTouches: null,
+  altKey: null,
+  metaKey: null,
+  ctrlKey: null,
+  shiftKey: null
+};
+
+/**
+ * @param {object} dispatchConfig Configuration used to dispatch this event.
+ * @param {string} dispatchMarker Marker identifying the event target.
+ * @param {object} nativeEvent Native browser event.
+ * @extends {SyntheticUIEvent}
+ */
+function SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent) {
+  SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
+}
+
+SyntheticUIEvent.augmentClass(SyntheticTouchEvent, TouchEventInterface);
+
+module.exports = SyntheticTouchEvent;
+
+},{"./SyntheticUIEvent":82}],82:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule SyntheticUIEvent
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var SyntheticEvent = require("./SyntheticEvent");
+
+/**
+ * @interface UIEvent
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
+ */
+var UIEventInterface = {
+  view: null,
+  detail: null
+};
+
+/**
+ * @param {object} dispatchConfig Configuration used to dispatch this event.
+ * @param {string} dispatchMarker Marker identifying the event target.
+ * @param {object} nativeEvent Native browser event.
+ * @extends {SyntheticEvent}
+ */
+function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent) {
+  SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
+}
+
+SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface);
+
+module.exports = SyntheticUIEvent;
+
+},{"./SyntheticEvent":77}],83:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule SyntheticWheelEvent
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var SyntheticMouseEvent = require("./SyntheticMouseEvent");
+
+/**
+ * @interface WheelEvent
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
+ */
+var WheelEventInterface = {
+  deltaX: function(event) {
+    return (
+      'deltaX' in event ? event.deltaX :
+      // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
+      'wheelDeltaX' in event ? -event.wheelDeltaX : 0
+    );
+  },
+  deltaY: function(event) {
+    return (
+      'deltaY' in event ? event.deltaY :
+      // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
+      'wheelDeltaY' in event ? -event.wheelDeltaY :
+      // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
+      'wheelDelta' in event ? -event.wheelDelta : 0
+    );
+  },
+  deltaZ: null,
+
+  // Browsers without "deltaMode" is reporting in raw wheel delta where one
+  // notch on the scroll is always +/- 120, roughly equivalent to pixels.
+  // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
+  // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
+  deltaMode: null
+};
+
+/**
+ * @param {object} dispatchConfig Configuration used to dispatch this event.
+ * @param {string} dispatchMarker Marker identifying the event target.
+ * @param {object} nativeEvent Native browser event.
+ * @extends {SyntheticMouseEvent}
+ */
+function SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent) {
+  SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
+}
+
+SyntheticMouseEvent.augmentClass(SyntheticWheelEvent, WheelEventInterface);
+
+module.exports = SyntheticWheelEvent;
+
+},{"./SyntheticMouseEvent":80}],84:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule Transaction
+ */
+
+"use strict";
+
+var invariant = require("./invariant");
+
+/**
+ * `Transaction` creates a black box that is able to wrap any method such that
+ * certain invariants are maintained before and after the method is invoked
+ * (Even if an exception is thrown while invoking the wrapped method). Whoever
+ * instantiates a transaction can provide enforcers of the invariants at
+ * creation time. The `Transaction` class itself will supply one additional
+ * automatic invariant for you - the invariant that any transaction instance
+ * should not be run while it is already being run. You would typically create a
+ * single instance of a `Transaction` for reuse multiple times, that potentially
+ * is used to wrap several different methods. Wrappers are extremely simple -
+ * they only require implementing two methods.
+ *
+ * <pre>
+ *                       wrappers (injected at creation time)
+ *                                      +        +
+ *                                      |        |
+ *                    +-----------------|--------|--------------+
+ *                    |                 v        |              |
+ *                    |      +---------------+   |              |
+ *                    |   +--|    wrapper1   |---|----+         |
+ *                    |   |  +---------------+   v    |         |
+ *                    |   |          +-------------+  |         |
+ *                    |   |     +----|   wrapper2  |--------+   |
+ *                    |   |     |    +-------------+  |     |   |
+ *                    |   |     |                     |     |   |
+ *                    |   v     v                     v     v   | wrapper
+ *                    | +---+ +---+   +---------+   +---+ +---+ | invariants
+ * perform(anyMethod) | |   | |   |   |         |   |   | |   | | maintained
+ * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
+ *                    | |   | |   |   |         |   |   | |   | |
+ *                    | |   | |   |   |         |   |   | |   | |
+ *                    | |   | |   |   |         |   |   | |   | |
+ *                    | +---+ +---+   +---------+   +---+ +---+ |
+ *                    |  initialize                    close    |
+ *                    +-----------------------------------------+
+ * </pre>
+ *
+ * Bonus:
+ * - Reports timing metrics by method name and wrapper index.
+ *
+ * Use cases:
+ * - Preserving the input selection ranges before/after reconciliation.
+ *   Restoring selection even in the event of an unexpected error.
+ * - Deactivating events while rearranging the DOM, preventing blurs/focuses,
+ *   while guaranteeing that afterwards, the event system is reactivated.
+ * - Flushing a queue of collected DOM mutations to the main UI thread after a
+ *   reconciliation takes place in a worker thread.
+ * - Invoking any collected `componentDidUpdate` callbacks after rendering new
+ *   content.
+ * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue
+ *   to preserve the `scrollTop` (an automatic scroll aware DOM).
+ * - (Future use case): Layout calculations before and after DOM upates.
+ *
+ * Transactional plugin API:
+ * - A module that has an `initialize` method that returns any precomputation.
+ * - and a `close` method that accepts the precomputation. `close` is invoked
+ *   when the wrapped process is completed, or has failed.
+ *
+ * @param {Array<TransactionalWrapper>} transactionWrapper Wrapper modules
+ * that implement `initialize` and `close`.
+ * @return {Transaction} Single transaction for reuse in thread.
+ *
+ * @class Transaction
+ */
+var Mixin = {
+  /**
+   * Sets up this instance so that it is prepared for collecting metrics. Does
+   * so such that this setup method may be used on an instance that is already
+   * initialized, in a way that does not consume additional memory upon reuse.
+   * That can be useful if you decide to make your subclass of this mixin a
+   * "PooledClass".
+   */
+  reinitializeTransaction: function() {
+    this.transactionWrappers = this.getTransactionWrappers();
+    if (!this.wrapperInitData) {
+      this.wrapperInitData = [];
+    } else {
+      this.wrapperInitData.length = 0;
+    }
+    if (!this.timingMetrics) {
+      this.timingMetrics = {};
+    }
+    this.timingMetrics.methodInvocationTime = 0;
+    if (!this.timingMetrics.wrapperInitTimes) {
+      this.timingMetrics.wrapperInitTimes = [];
+    } else {
+      this.timingMetrics.wrapperInitTimes.length = 0;
+    }
+    if (!this.timingMetrics.wrapperCloseTimes) {
+      this.timingMetrics.wrapperCloseTimes = [];
+    } else {
+      this.timingMetrics.wrapperCloseTimes.length = 0;
+    }
+    this._isInTransaction = false;
+  },
+
+  _isInTransaction: false,
+
+  /**
+   * @abstract
+   * @return {Array<TransactionWrapper>} Array of transaction wrappers.
+   */
+  getTransactionWrappers: null,
+
+  isInTransaction: function() {
+    return !!this._isInTransaction;
+  },
+
+  /**
+   * Executes the function within a safety window. Use this for the top level
+   * methods that result in large amounts of computation/mutations that would
+   * need to be safety checked.
+   *
+   * @param {function} method Member of scope to call.
+   * @param {Object} scope Scope to invoke from.
+   * @param {Object?=} args... Arguments to pass to the method (optional).
+   *                           Helps prevent need to bind in many cases.
+   * @return Return value from `method`.
+   */
+  perform: function(method, scope, a, b, c, d, e, f) {
+    ("production" !== "development" ? invariant(
+      !this.isInTransaction(),
+      'Transaction.perform(...): Cannot initialize a transaction when there ' +
+      'is already an outstanding transaction.'
+    ) : invariant(!this.isInTransaction()));
+    var memberStart = Date.now();
+    var errorThrown;
+    var ret;
+    try {
+      this._isInTransaction = true;
+      // Catching errors makes debugging more difficult, so we start with
+      // errorThrown set to true before setting it to false after calling
+      // close -- if it's still set to true in the finally block, it means
+      // one of these calls threw.
+      errorThrown = true;
+      this.initializeAll(0);
+      ret = method.call(scope, a, b, c, d, e, f);
+      errorThrown = false;
+    } finally {
+      var memberEnd = Date.now();
+      this.methodInvocationTime += (memberEnd - memberStart);
+      try {
+        if (errorThrown) {
+          // If `method` throws, prefer to show that stack trace over any thrown
+          // by invoking `closeAll`.
+          try {
+            this.closeAll(0);
+          } catch (err) {
+          }
+        } else {
+          // Since `method` didn't throw, we don't want to silence the exception
+          // here.
+          this.closeAll(0);
+        }
+      } finally {
+        this._isInTransaction = false;
+      }
+    }
+    return ret;
+  },
+
+  initializeAll: function(startIndex) {
+    var transactionWrappers = this.transactionWrappers;
+    var wrapperInitTimes = this.timingMetrics.wrapperInitTimes;
+    for (var i = startIndex; i < transactionWrappers.length; i++) {
+      var initStart = Date.now();
+      var wrapper = transactionWrappers[i];
+      try {
+        // Catching errors makes debugging more difficult, so we start with the
+        // OBSERVED_ERROR state before overwriting it with the real return value
+        // of initialize -- if it's still set to OBSERVED_ERROR in the finally
+        // block, it means wrapper.initialize threw.
+        this.wrapperInitData[i] = Transaction.OBSERVED_ERROR;
+        this.wrapperInitData[i] = wrapper.initialize ?
+          wrapper.initialize.call(this) :
+          null;
+      } finally {
+        var curInitTime = wrapperInitTimes[i];
+        var initEnd = Date.now();
+        wrapperInitTimes[i] = (curInitTime || 0) + (initEnd - initStart);
+
+        if (this.wrapperInitData[i] === Transaction.OBSERVED_ERROR) {
+          // The initializer for wrapper i threw an error; initialize the
+          // remaining wrappers but silence any exceptions from them to ensure
+          // that the first error is the one to bubble up.
+          try {
+            this.initializeAll(i + 1);
+          } catch (err) {
+          }
+        }
+      }
+    }
+  },
+
+  /**
+   * Invokes each of `this.transactionWrappers.close[i]` functions, passing into
+   * them the respective return values of `this.transactionWrappers.init[i]`
+   * (`close`rs that correspond to initializers that failed will not be
+   * invoked).
+   */
+  closeAll: function(startIndex) {
+    ("production" !== "development" ? invariant(
+      this.isInTransaction(),
+      'Transaction.closeAll(): Cannot close transaction when none are open.'
+    ) : invariant(this.isInTransaction()));
+    var transactionWrappers = this.transactionWrappers;
+    var wrapperCloseTimes = this.timingMetrics.wrapperCloseTimes;
+    for (var i = startIndex; i < transactionWrappers.length; i++) {
+      var wrapper = transactionWrappers[i];
+      var closeStart = Date.now();
+      var initData = this.wrapperInitData[i];
+      var errorThrown;
+      try {
+        // Catching errors makes debugging more difficult, so we start with
+        // errorThrown set to true before setting it to false after calling
+        // close -- if it's still set to true in the finally block, it means
+        // wrapper.close threw.
+        errorThrown = true;
+        if (initData !== Transaction.OBSERVED_ERROR) {
+          wrapper.close && wrapper.close.call(this, initData);
+        }
+        errorThrown = false;
+      } finally {
+        var closeEnd = Date.now();
+        var curCloseTime = wrapperCloseTimes[i];
+        wrapperCloseTimes[i] = (curCloseTime || 0) + (closeEnd - closeStart);
+
+        if (errorThrown) {
+          // The closer for wrapper i threw an error; close the remaining
+          // wrappers but silence any exceptions from them to ensure that the
+          // first error is the one to bubble up.
+          try {
+            this.closeAll(i + 1);
+          } catch (e) {
+          }
+        }
+      }
+    }
+    this.wrapperInitData.length = 0;
+  }
+};
+
+var Transaction = {
+
+  Mixin: Mixin,
+
+  /**
+   * Token to look for to determine if an error occured.
+   */
+  OBSERVED_ERROR: {}
+
+};
+
+module.exports = Transaction;
+
+},{"./invariant":108}],85:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule ViewportMetrics
+ */
+
+"use strict";
+
+var getUnboundedScrollPosition = require("./getUnboundedScrollPosition");
+
+var ViewportMetrics = {
+
+  currentScrollLeft: 0,
+
+  currentScrollTop: 0,
+
+  refreshScrollValues: function() {
+    var scrollPosition = getUnboundedScrollPosition(window);
+    ViewportMetrics.currentScrollLeft = scrollPosition.x;
+    ViewportMetrics.currentScrollTop = scrollPosition.y;
+  }
+
+};
+
+module.exports = ViewportMetrics;
+
+},{"./getUnboundedScrollPosition":106}],86:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule accumulate
+ */
+
+"use strict";
+
+var invariant = require("./invariant");
+
+/**
+ * Accumulates items that must not be null or undefined.
+ *
+ * This is used to conserve memory by avoiding array allocations.
+ *
+ * @return {*|array<*>} An accumulation of items.
+ */
+function accumulate(current, next) {
+  ("production" !== "development" ? invariant(
+    next != null,
+    'accumulate(...): Accumulated items must be not be null or undefined.'
+  ) : invariant(next != null));
+  if (current == null) {
+    return next;
+  } else {
+    // Both are not empty. Warning: Never call x.concat(y) when you are not
+    // certain that x is an Array (x could be a string with concat method).
+    var currentIsArray = Array.isArray(current);
+    var nextIsArray = Array.isArray(next);
+    if (currentIsArray) {
+      return current.concat(next);
+    } else {
+      if (nextIsArray) {
+        return [current].concat(next);
+      } else {
+        return [current, next];
+      }
+    }
+  }
+}
+
+module.exports = accumulate;
+
+},{"./invariant":108}],87:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule adler32
+ */
+
+/* jslint bitwise:true */
+
+"use strict";
+
+var MOD = 65521;
+
+// This is a clean-room implementation of adler32 designed for detecting
+// if markup is not what we expect it to be. It does not need to be
+// cryptographically strong, only reasonable good at detecting if markup
+// generated on the server is different than that on the client.
+function adler32(data) {
+  var a = 1;
+  var b = 0;
+  for (var i = 0; i < data.length; i++) {
+    a = (a + data.charCodeAt(i)) % MOD;
+    b = (b + a) % MOD;
+  }
+  return a | (b << 16);
+}
+
+module.exports = adler32;
+
+},{}],88:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule containsNode
+ * @typechecks
+ */
+
+var isTextNode = require("./isTextNode");
+
+/*jslint bitwise:true */
+
+/**
+ * Checks if a given DOM node contains or is another DOM node.
+ *
+ * @param {?DOMNode} outerNode Outer DOM node.
+ * @param {?DOMNode} innerNode Inner DOM node.
+ * @return {boolean} True if `outerNode` contains or is `innerNode`.
+ */
+function containsNode(outerNode, innerNode) {
+  if (!outerNode || !innerNode) {
+    return false;
+  } else if (outerNode === innerNode) {
+    return true;
+  } else if (isTextNode(outerNode)) {
+    return false;
+  } else if (isTextNode(innerNode)) {
+    return containsNode(outerNode, innerNode.parentNode);
+  } else if (outerNode.contains) {
+    return outerNode.contains(innerNode);
+  } else if (outerNode.compareDocumentPosition) {
+    return !!(outerNode.compareDocumentPosition(innerNode) & 16);
+  } else {
+    return false;
+  }
+}
+
+module.exports = containsNode;
+
+},{"./isTextNode":112}],89:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule copyProperties
+ */
+
+/**
+ * Copy properties from one or more objects (up to 5) into the first object.
+ * This is a shallow copy. It mutates the first object and also returns it.
+ *
+ * NOTE: `arguments` has a very significant performance penalty, which is why
+ * we don't support unlimited arguments.
+ */
+function copyProperties(obj, a, b, c, d, e, f) {
+  obj = obj || {};
+
+  if ("production" !== "development") {
+    if (f) {
+      throw new Error('Too many arguments passed to copyProperties');
+    }
+  }
+
+  var args = [a, b, c, d, e];
+  var ii = 0, v;
+  while (args[ii]) {
+    v = args[ii++];
+    for (var k in v) {
+      obj[k] = v[k];
+    }
+
+    // IE ignores toString in object iteration.. See:
+    // webreflection.blogspot.com/2007/07/quick-fix-internet-explorer-and.html
+    if (v.hasOwnProperty && v.hasOwnProperty('toString') &&
+        (typeof v.toString != 'undefined') && (obj.toString !== v.toString)) {
+      obj.toString = v.toString;
+    }
+  }
+
+  return obj;
+}
+
+module.exports = copyProperties;
+
+},{}],90:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule createArrayFrom
+ * @typechecks
+ */
+
+var toArray = require("./toArray");
+
+/**
+ * Perform a heuristic test to determine if an object is "array-like".
+ *
+ *   A monk asked Joshu, a Zen master, "Has a dog Buddha nature?"
+ *   Joshu replied: "Mu."
+ *
+ * This function determines if its argument has "array nature": it returns
+ * true if the argument is an actual array, an `arguments' object, or an
+ * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()).
+ *
+ * It will return false for other array-like objects like Filelist.
+ *
+ * @param {*} obj
+ * @return {boolean}
+ */
+function hasArrayNature(obj) {
+  return (
+    // not null/false
+    !!obj &&
+    // arrays are objects, NodeLists are functions in Safari
+    (typeof obj == 'object' || typeof obj == 'function') &&
+    // quacks like an array
+    ('length' in obj) &&
+    // not window
+    !('setInterval' in obj) &&
+    // no DOM node should be considered an array-like
+    // a 'select' element has 'length' and 'item' properties on IE8
+    (typeof obj.nodeType != 'number') &&
+    (
+      // a real array
+      (// HTMLCollection/NodeList
+      (Array.isArray(obj) ||
+      // arguments
+      ('callee' in obj) || 'item' in obj))
+    )
+  );
+}
+
+/**
+ * Ensure that the argument is an array by wrapping it in an array if it is not.
+ * Creates a copy of the argument if it is already an array.
+ *
+ * This is mostly useful idiomatically:
+ *
+ *   var createArrayFrom = require('createArrayFrom');
+ *
+ *   function takesOneOrMoreThings(things) {
+ *     things = createArrayFrom(things);
+ *     ...
+ *   }
+ *
+ * This allows you to treat `things' as an array, but accept scalars in the API.
+ *
+ * If you need to convert an array-like object, like `arguments`, into an array
+ * use toArray instead.
+ *
+ * @param {*} obj
+ * @return {array}
+ */
+function createArrayFrom(obj) {
+  if (!hasArrayNature(obj)) {
+    return [obj];
+  } else if (Array.isArray(obj)) {
+    return obj.slice();
+  } else {
+    return toArray(obj);
+  }
+}
+
+module.exports = createArrayFrom;
+
+},{"./toArray":127}],91:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule createFullPageComponent
+ * @typechecks
+ */
+
+"use strict";
+
+// Defeat circular references by requiring this directly.
+var ReactCompositeComponent = require("./ReactCompositeComponent");
+
+var invariant = require("./invariant");
+
+/**
+ * Create a component that will throw an exception when unmounted.
+ *
+ * Components like <html> <head> and <body> can't be removed or added
+ * easily in a cross-browser way, however it's valuable to be able to
+ * take advantage of React's reconciliation for styling and <title>
+ * management. So we just document it and throw in dangerous cases.
+ *
+ * @param {function} componentClass convenience constructor to wrap
+ * @return {function} convenience constructor of new component
+ */
+function createFullPageComponent(componentClass) {
+  var FullPageComponent = ReactCompositeComponent.createClass({
+    displayName: 'ReactFullPageComponent' + (
+      componentClass.componentConstructor.displayName || ''
+    ),
+
+    componentWillUnmount: function() {
+      ("production" !== "development" ? invariant(
+        false,
+        '%s tried to unmount. Because of cross-browser quirks it is ' +
+        'impossible to unmount some top-level components (eg <html>, <head>, ' +
+        'and <body>) reliably and efficiently. To fix this, have a single ' +
+        'top-level component that never unmounts render these elements.',
+        this.constructor.displayName
+      ) : invariant(false));
+    },
+
+    render: function() {
+      return this.transferPropsTo(componentClass(null, this.props.children));
+    }
+  });
+
+  return FullPageComponent;
+}
+
+module.exports = createFullPageComponent;
+
+},{"./ReactCompositeComponent":29,"./invariant":108}],92:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule createNodesFromMarkup
+ * @typechecks
+ */
+
+/*jslint evil: true, sub: true */
+
+var ExecutionEnvironment = require("./ExecutionEnvironment");
+
+var createArrayFrom = require("./createArrayFrom");
+var getMarkupWrap = require("./getMarkupWrap");
+var invariant = require("./invariant");
+
+/**
+ * Dummy container used to render all markup.
+ */
+var dummyNode =
+  ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
+
+/**
+ * Pattern used by `getNodeName`.
+ */
+var nodeNamePattern = /^\s*<(\w+)/;
+
+/**
+ * Extracts the `nodeName` of the first element in a string of markup.
+ *
+ * @param {string} markup String of markup.
+ * @return {?string} Node name of the supplied markup.
+ */
+function getNodeName(markup) {
+  var nodeNameMatch = markup.match(nodeNamePattern);
+  return nodeNameMatch && nodeNameMatch[1].toLowerCase();
+}
+
+/**
+ * Creates an array containing the nodes rendered from the supplied markup. The
+ * optionally supplied `handleScript` function will be invoked once for each
+ * <script> element that is rendered. If no `handleScript` function is supplied,
+ * an exception is thrown if any <script> elements are rendered.
+ *
+ * @param {string} markup A string of valid HTML markup.
+ * @param {?function} handleScript Invoked once for each rendered <script>.
+ * @return {array<DOMElement|DOMTextNode>} An array of rendered nodes.
+ */
+function createNodesFromMarkup(markup, handleScript) {
+  var node = dummyNode;
+  ("production" !== "development" ? invariant(!!dummyNode, 'createNodesFromMarkup dummy not initialized') : invariant(!!dummyNode));
+  var nodeName = getNodeName(markup);
+
+  var wrap = nodeName && getMarkupWrap(nodeName);
+  if (wrap) {
+    node.innerHTML = wrap[1] + markup + wrap[2];
+
+    var wrapDepth = wrap[0];
+    while (wrapDepth--) {
+      node = node.lastChild;
+    }
+  } else {
+    node.innerHTML = markup;
+  }
+
+  var scripts = node.getElementsByTagName('script');
+  if (scripts.length) {
+    ("production" !== "development" ? invariant(
+      handleScript,
+      'createNodesFromMarkup(...): Unexpected <script> element rendered.'
+    ) : invariant(handleScript));
+    createArrayFrom(scripts).forEach(handleScript);
+  }
+
+  var nodes = createArrayFrom(node.childNodes);
+  while (node.lastChild) {
+    node.removeChild(node.lastChild);
+  }
+  return nodes;
+}
+
+module.exports = createNodesFromMarkup;
+
+},{"./ExecutionEnvironment":20,"./createArrayFrom":90,"./getMarkupWrap":102,"./invariant":108}],93:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule createObjectFrom
+ */
+
+/**
+ * Construct an object from an array of keys
+ * and optionally specified value or list of values.
+ *
+ *  >>> createObjectFrom(['a','b','c']);
+ *  {a: true, b: true, c: true}
+ *
+ *  >>> createObjectFrom(['a','b','c'], false);
+ *  {a: false, b: false, c: false}
+ *
+ *  >>> createObjectFrom(['a','b','c'], 'monkey');
+ *  {c:'monkey', b:'monkey' c:'monkey'}
+ *
+ *  >>> createObjectFrom(['a','b','c'], [1,2,3]);
+ *  {a: 1, b: 2, c: 3}
+ *
+ *  >>> createObjectFrom(['women', 'men'], [true, false]);
+ *  {women: true, men: false}
+ *
+ * @param   Array   list of keys
+ * @param   mixed   optional value or value array.  defaults true.
+ * @returns object
+ */
+function createObjectFrom(keys, values /* = true */) {
+  if ("production" !== "development") {
+    if (!Array.isArray(keys)) {
+      throw new TypeError('Must pass an array of keys.');
+    }
+  }
+
+  var object = {};
+  var isArray = Array.isArray(values);
+  if (typeof values == 'undefined') {
+    values = true;
+  }
+
+  for (var ii = keys.length; ii--;) {
+    object[keys[ii]] = isArray ? values[ii] : values;
+  }
+  return object;
+}
+
+module.exports = createObjectFrom;
+
+},{}],94:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule dangerousStyleValue
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var CSSProperty = require("./CSSProperty");
+
+/**
+ * Convert a value into the proper css writable value. The `styleName` name
+ * name should be logical (no hyphens), as specified
+ * in `CSSProperty.isUnitlessNumber`.
+ *
+ * @param {string} styleName CSS property name such as `topMargin`.
+ * @param {*} value CSS property value such as `10px`.
+ * @return {string} Normalized style value with dimensions applied.
+ */
+function dangerousStyleValue(styleName, value) {
+  // Note that we've removed escapeTextForBrowser() calls here since the
+  // whole string will be escaped when the attribute is injected into
+  // the markup. If you provide unsafe user data here they can inject
+  // arbitrary CSS which may be problematic (I couldn't repro this):
+  // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
+  // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
+  // This is not an XSS hole but instead a potential CSS injection issue
+  // which has lead to a greater discussion about how we're going to
+  // trust URLs moving forward. See #2115901
+
+  var isEmpty = value == null || typeof value === 'boolean' || value === '';
+  if (isEmpty) {
+    return '';
+  }
+
+  var isNonNumeric = isNaN(value);
+  if (isNonNumeric || value === 0 || CSSProperty.isUnitlessNumber[styleName]) {
+    return '' + value; // cast to string
+  }
+
+  return value + 'px';
+}
+
+module.exports = dangerousStyleValue;
+
+},{"./CSSProperty":2}],95:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule emptyFunction
+ */
+
+var copyProperties = require("./copyProperties");
+
+function makeEmptyFunction(arg) {
+  return function() {
+    return arg;
+  };
+}
+
+/**
+ * This function accepts and discards inputs; it has no side effects. This is
+ * primarily useful idiomatically for overridable function endpoints which
+ * always need to be callable, since JS lacks a null-call idiom ala Cocoa.
+ */
+function emptyFunction() {}
+
+copyProperties(emptyFunction, {
+  thatReturns: makeEmptyFunction,
+  thatReturnsFalse: makeEmptyFunction(false),
+  thatReturnsTrue: makeEmptyFunction(true),
+  thatReturnsNull: makeEmptyFunction(null),
+  thatReturnsThis: function() { return this; },
+  thatReturnsArgument: function(arg) { return arg; }
+});
+
+module.exports = emptyFunction;
+
+},{"./copyProperties":89}],96:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule escapeTextForBrowser
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var ESCAPE_LOOKUP = {
+  "&": "&",
+  ">": ">",
+  "<": "<",
+  "\"": """,
+  "'": "&#x27;",
+  "/": "&#x2f;"
+};
+
+var ESCAPE_REGEX = /[&><"'\/]/g;
+
+function escaper(match) {
+  return ESCAPE_LOOKUP[match];
+}
+
+/**
+ * Escapes text to prevent scripting attacks.
+ *
+ * @param {*} text Text value to escape.
+ * @return {string} An escaped string.
+ */
+function escapeTextForBrowser(text) {
+  return ('' + text).replace(ESCAPE_REGEX, escaper);
+}
+
+module.exports = escapeTextForBrowser;
+
+},{}],97:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule flattenChildren
+ */
+
+"use strict";
+
+var invariant = require("./invariant");
+var traverseAllChildren = require("./traverseAllChildren");
+
+/**
+ * @param {function} traverseContext Context passed through traversal.
+ * @param {?ReactComponent} child React child component.
+ * @param {!string} name String name of key path to child.
+ */
+function flattenSingleChildIntoContext(traverseContext, child, name) {
+  // We found a component instance.
+  var result = traverseContext;
+  ("production" !== "development" ? invariant(
+    !result.hasOwnProperty(name),
+    'flattenChildren(...): Encountered two children with the same key, `%s`. ' +
+    'Children keys must be unique.',
+    name
+  ) : invariant(!result.hasOwnProperty(name)));
+  if (child != null) {
+    result[name] = child;
+  }
+}
+
+/**
+ * Flattens children that are typically specified as `props.children`. Any null
+ * children will not be included in the resulting object.
+ * @return {!object} flattened children keyed by name.
+ */
+function flattenChildren(children) {
+  if (children == null) {
+    return children;
+  }
+  var result = {};
+  traverseAllChildren(children, flattenSingleChildIntoContext, result);
+  return result;
+}
+
+module.exports = flattenChildren;
+
+},{"./invariant":108,"./traverseAllChildren":128}],98:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule forEachAccumulated
+ */
+
+"use strict";
+
+/**
+ * @param {array} an "accumulation" of items which is either an Array or
+ * a single item. Useful when paired with the `accumulate` module. This is a
+ * simple utility that allows us to reason about a collection of items, but
+ * handling the case when there is exactly one item (and we do not need to
+ * allocate an array).
+ */
+var forEachAccumulated = function(arr, cb, scope) {
+  if (Array.isArray(arr)) {
+    arr.forEach(cb, scope);
+  } else if (arr) {
+    cb.call(scope, arr);
+  }
+};
+
+module.exports = forEachAccumulated;
+
+},{}],99:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule getActiveElement
+ * @typechecks
+ */
+
+/**
+ * Same as document.activeElement but wraps in a try-catch block. In IE it is
+ * not safe to call document.activeElement if there is nothing focused.
+ *
+ * The activeElement will be null only if the document body is not yet defined.
+ */
+function getActiveElement() /*?DOMElement*/ {
+  try {
+    return document.activeElement || document.body;
+  } catch (e) {
+    return document.body;
+  }
+}
+
+module.exports = getActiveElement;
+
+},{}],100:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule getEventKey
+ * @typechecks static-only
+ */
+
+"use strict";
+
+/**
+ * Normalization of deprecated HTML5 "key" values
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
+ */
+var normalizeKey = {
+  'Esc': 'Escape',
+  'Spacebar': ' ',
+  'Left': 'ArrowLeft',
+  'Up': 'ArrowUp',
+  'Right': 'ArrowRight',
+  'Down': 'ArrowDown',
+  'Del': 'Delete',
+  'Win': 'OS',
+  'Menu': 'ContextMenu',
+  'Apps': 'ContextMenu',
+  'Scroll': 'ScrollLock',
+  'MozPrintableKey': 'Unidentified'
+};
+
+/**
+ * Translation from legacy "which/keyCode" to HTML5 "key"
+ * Only special keys supported, all others depend on keyboard layout or browser
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
+ */
+var translateToKey = {
+  8: 'Backspace',
+  9: 'Tab',
+  12: 'Clear',
+  13: 'Enter',
+  16: 'Shift',
+  17: 'Control',
+  18: 'Alt',
+  19: 'Pause',
+  20: 'CapsLock',
+  27: 'Escape',
+  32: ' ',
+  33: 'PageUp',
+  34: 'PageDown',
+  35: 'End',
+  36: 'Home',
+  37: 'ArrowLeft',
+  38: 'ArrowUp',
+  39: 'ArrowRight',
+  40: 'ArrowDown',
+  45: 'Insert',
+  46: 'Delete',
+  112: 'F1', 113: 'F2', 114: 'F3', 115: 'F4', 116: 'F5', 117: 'F6',
+  118: 'F7', 119: 'F8', 120: 'F9', 121: 'F10', 122: 'F11', 123: 'F12',
+  144: 'NumLock',
+  145: 'ScrollLock',
+  224: 'Meta'
+};
+
+/**
+ * @param {object} nativeEvent Native browser event.
+ * @return {string} Normalized `key` property.
+ */
+function getEventKey(nativeEvent) {
+  return 'key' in nativeEvent ?
+    normalizeKey[nativeEvent.key] || nativeEvent.key :
+    translateToKey[nativeEvent.which || nativeEvent.keyCode] || 'Unidentified';
+}
+
+module.exports = getEventKey;
+
+},{}],101:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule getEventTarget
+ * @typechecks static-only
+ */
+
+"use strict";
+
+/**
+ * Gets the target node from a native browser event by accounting for
+ * inconsistencies in browser DOM APIs.
+ *
+ * @param {object} nativeEvent Native browser event.
+ * @return {DOMEventTarget} Target node.
+ */
+function getEventTarget(nativeEvent) {
+  var target = nativeEvent.target || nativeEvent.srcElement || window;
+  // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
+  // @see http://www.quirksmode.org/js/events_properties.html
+  return target.nodeType === 3 ? target.parentNode : target;
+}
+
+module.exports = getEventTarget;
+
+},{}],102:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule getMarkupWrap
+ */
+
+var ExecutionEnvironment = require("./ExecutionEnvironment");
+
+var invariant = require("./invariant");
+
+/**
+ * Dummy container used to detect which wraps are necessary.
+ */
+var dummyNode =
+  ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
+
+/**
+ * Some browsers cannot use `innerHTML` to render certain elements standalone,
+ * so we wrap them, render the wrapped nodes, then extract the desired node.
+ *
+ * In IE8, certain elements cannot render alone, so wrap all elements ('*').
+ */
+var shouldWrap = {
+  // Force wrapping for SVG elements because if they get created inside a <div>,
+  // they will be initialized in the wrong namespace (and will not display).
+  'circle': true,
+  'defs': true,
+  'g': true,
+  'line': true,
+  'linearGradient': true,
+  'path': true,
+  'polygon': true,
+  'polyline': true,
+  'radialGradient': true,
+  'rect': true,
+  'stop': true,
+  'text': true
+};
+
+var selectWrap = [1, '<select multiple="true">', '</select>'];
+var tableWrap = [1, '<table>', '</table>'];
+var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
+
+var svgWrap = [1, '<svg>', '</svg>'];
+
+var markupWrap = {
+  '*': [1, '?<div>', '</div>'],
+
+  'area': [1, '<map>', '</map>'],
+  'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
+  'legend': [1, '<fieldset>', '</fieldset>'],
+  'param': [1, '<object>', '</object>'],
+  'tr': [2, '<table><tbody>', '</tbody></table>'],
+
+  'optgroup': selectWrap,
+  'option': selectWrap,
+
+  'caption': tableWrap,
+  'colgroup': tableWrap,
+  'tbody': tableWrap,
+  'tfoot': tableWrap,
+  'thead': tableWrap,
+
+  'td': trWrap,
+  'th': trWrap,
+
+  'circle': svgWrap,
+  'defs': svgWrap,
+  'g': svgWrap,
+  'line': svgWrap,
+  'linearGradient': svgWrap,
+  'path': svgWrap,
+  'polygon': svgWrap,
+  'polyline': svgWrap,
+  'radialGradient': svgWrap,
+  'rect': svgWrap,
+  'stop': svgWrap,
+  'text': svgWrap
+};
+
+/**
+ * Gets the markup wrap configuration for the supplied `nodeName`.
+ *
+ * NOTE: This lazily detects which wraps are necessary for the current browser.
+ *
+ * @param {string} nodeName Lowercase `nodeName`.
+ * @return {?array} Markup wrap configuration, if applicable.
+ */
+function getMarkupWrap(nodeName) {
+  ("production" !== "development" ? invariant(!!dummyNode, 'Markup wrapping node not initialized') : invariant(!!dummyNode));
+  if (!markupWrap.hasOwnProperty(nodeName)) {
+    nodeName = '*';
+  }
+  if (!shouldWrap.hasOwnProperty(nodeName)) {
+    if (nodeName === '*') {
+      dummyNode.innerHTML = '<link />';
+    } else {
+      dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>';
+    }
+    shouldWrap[nodeName] = !dummyNode.firstChild;
+  }
+  return shouldWrap[nodeName] ? markupWrap[nodeName] : null;
+}
+
+
+module.exports = getMarkupWrap;
+
+},{"./ExecutionEnvironment":20,"./invariant":108}],103:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule getNodeForCharacterOffset
+ */
+
+"use strict";
+
+/**
+ * Given any node return the first leaf node without children.
+ *
+ * @param {DOMElement|DOMTextNode} node
+ * @return {DOMElement|DOMTextNode}
+ */
+function getLeafNode(node) {
+  while (node && node.firstChild) {
+    node = node.firstChild;
+  }
+  return node;
+}
+
+/**
+ * Get the next sibling within a container. This will walk up the
+ * DOM if a node's siblings have been exhausted.
+ *
+ * @param {DOMElement|DOMTextNode} node
+ * @return {?DOMElement|DOMTextNode}
+ */
+function getSiblingNode(node) {
+  while (node) {
+    if (node.nextSibling) {
+      return node.nextSibling;
+    }
+    node = node.parentNode;
+  }
+}
+
+/**
+ * Get object describing the nodes which contain characters at offset.
+ *
+ * @param {DOMElement|DOMTextNode} root
+ * @param {number} offset
+ * @return {?object}
+ */
+function getNodeForCharacterOffset(root, offset) {
+  var node = getLeafNode(root);
+  var nodeStart = 0;
+  var nodeEnd = 0;
+
+  while (node) {
+    if (node.nodeType == 3) {
+      nodeEnd = nodeStart + node.textContent.length;
+
+      if (nodeStart <= offset && nodeEnd >= offset) {
+        return {
+          node: node,
+          offset: offset - nodeStart
+        };
+      }
+
+      nodeStart = nodeEnd;
+    }
+
+    node = getLeafNode(getSiblingNode(node));
+  }
+}
+
+module.exports = getNodeForCharacterOffset;
+
+},{}],104:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule getReactRootElementInContainer
+ */
+
+"use strict";
+
+var DOC_NODE_TYPE = 9;
+
+/**
+ * @param {DOMElement|DOMDocument} container DOM element that may contain
+ *                                           a React component
+ * @return {?*} DOM element that may have the reactRoot ID, or null.
+ */
+function getReactRootElementInContainer(container) {
+  if (!container) {
+    return null;
+  }
+
+  if (container.nodeType === DOC_NODE_TYPE) {
+    return container.documentElement;
+  } else {
+    return container.firstChild;
+  }
+}
+
+module.exports = getReactRootElementInContainer;
+
+},{}],105:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule getTextContentAccessor
+ */
+
+"use strict";
+
+var ExecutionEnvironment = require("./ExecutionEnvironment");
+
+var contentKey = null;
+
+/**
+ * Gets the key used to access text content on a DOM node.
+ *
+ * @return {?string} Key used to access text content.
+ * @internal
+ */
+function getTextContentAccessor() {
+  if (!contentKey && ExecutionEnvironment.canUseDOM) {
+    // Prefer textContent to innerText because many browsers support both but
+    // SVG <text> elements don't support innerText even when <div> does.
+    contentKey = 'textContent' in document.createElement('div') ?
+      'textContent' :
+      'innerText';
+  }
+  return contentKey;
+}
+
+module.exports = getTextContentAccessor;
+
+},{"./ExecutionEnvironment":20}],106:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule getUnboundedScrollPosition
+ * @typechecks
+ */
+
+"use strict";
+
+/**
+ * Gets the scroll position of the supplied element or window.
+ *
+ * The return values are unbounded, unlike `getScrollPosition`. This means they
+ * may be negative or exceed the element boundaries (which is possible using
+ * inertial scrolling).
+ *
+ * @param {DOMWindow|DOMElement} scrollable
+ * @return {object} Map with `x` and `y` keys.
+ */
+function getUnboundedScrollPosition(scrollable) {
+  if (scrollable === window) {
+    return {
+      x: window.pageXOffset || document.documentElement.scrollLeft,
+      y: window.pageYOffset || document.documentElement.scrollTop
+    };
+  }
+  return {
+    x: scrollable.scrollLeft,
+    y: scrollable.scrollTop
+  };
+}
+
+module.exports = getUnboundedScrollPosition;
+
+},{}],107:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule hyphenate
+ * @typechecks
+ */
+
+var _uppercasePattern = /([A-Z])/g;
+
+/**
+ * Hyphenates a camelcased string, for example:
+ *
+ *   > hyphenate('backgroundColor')
+ *   < "background-color"
+ *
+ * @param {string} string
+ * @return {string}
+ */
+function hyphenate(string) {
+  return string.replace(_uppercasePattern, '-$1').toLowerCase();
+}
+
+module.exports = hyphenate;
+
+},{}],108:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule invariant
+ */
+
+"use strict";
+
+/**
+ * Use invariant() to assert state which your program assumes to be true.
+ *
+ * Provide sprintf-style format (only %s is supported) and arguments
+ * to provide information about what broke and what you were
+ * expecting.
+ *
+ * The invariant message will be stripped in production, but the invariant
+ * will remain to ensure logic does not differ in production.
+ */
+
+var invariant = function(condition) {
+  if (!condition) {
+    var error = new Error(
+      'Minified exception occured; use the non-minified dev environment for ' +
+      'the full error message and additional helpful warnings.'
+    );
+    error.framesToPop = 1;
+    throw error;
+  }
+};
+
+if ("production" !== "development") {
+  invariant = function(condition, format, a, b, c, d, e, f) {
+    if (format === undefined) {
+      throw new Error('invariant requires an error message argument');
+    }
+
+    if (!condition) {
+      var args = [a, b, c, d, e, f];
+      var argIndex = 0;
+      var error = new Error(
+        'Invariant Violation: ' +
+        format.replace(/%s/g, function() { return args[argIndex++]; })
+      );
+      error.framesToPop = 1; // we don't care about invariant's own frame
+      throw error;
+    }
+  };
+}
+
+module.exports = invariant;
+
+},{}],109:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule isEventSupported
+ */
+
+"use strict";
+
+var ExecutionEnvironment = require("./ExecutionEnvironment");
+
+var useHasFeature;
+if (ExecutionEnvironment.canUseDOM) {
+  useHasFeature =
+    document.implementation &&
+    document.implementation.hasFeature &&
+    // always returns true in newer browsers as per the standard.
+    // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
+    document.implementation.hasFeature('', '') !== true;
+}
+
+/**
+ * Checks if an event is supported in the current execution environment.
+ *
+ * NOTE: This will not work correctly for non-generic events such as `change`,
+ * `reset`, `load`, `error`, and `select`.
+ *
+ * Borrows from Modernizr.
+ *
+ * @param {string} eventNameSuffix Event name, e.g. "click".
+ * @param {?boolean} capture Check if the capture phase is supported.
+ * @return {boolean} True if the event is supported.
+ * @internal
+ * @license Modernizr 3.0.0pre (Custom Build) | MIT
+ */
+function isEventSupported(eventNameSuffix, capture) {
+  if (!ExecutionEnvironment.canUseDOM ||
+      capture && !('addEventListener' in document)) {
+    return false;
+  }
+
+  var eventName = 'on' + eventNameSuffix;
+  var isSupported = eventName in document;
+
+  if (!isSupported) {
+    var element = document.createElement('div');
+    element.setAttribute(eventName, 'return;');
+    isSupported = typeof element[eventName] === 'function';
+  }
+
+  if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') {
+    // This is the only way to test support for the `wheel` event in IE9+.
+    isSupported = document.implementation.hasFeature('Events.wheel', '3.0');
+  }
+
+  return isSupported;
+}
+
+module.exports = isEventSupported;
+
+},{"./ExecutionEnvironment":20}],110:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule isNode
+ * @typechecks
+ */
+
+/**
+ * @param {*} object The object to check.
+ * @return {boolean} Whether or not the object is a DOM node.
+ */
+function isNode(object) {
+  return !!(object && (
+    typeof Node !== 'undefined' ? object instanceof Node :
+      typeof object === 'object' &&
+      typeof object.nodeType === 'number' &&
+      typeof object.nodeName === 'string'
+  ));
+}
+
+module.exports = isNode;
+
+},{}],111:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule isTextInputElement
+ */
+
+"use strict";
+
+/**
+ * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
+ */
+var supportedInputTypes = {
+  'color': true,
+  'date': true,
+  'datetime': true,
+  'datetime-local': true,
+  'email': true,
+  'month': true,
+  'number': true,
+  'password': true,
+  'range': true,
+  'search': true,
+  'tel': true,
+  'text': true,
+  'time': true,
+  'url': true,
+  'week': true
+};
+
+function isTextInputElement(elem) {
+  return elem && (
+    (elem.nodeName === 'INPUT' && supportedInputTypes[elem.type]) ||
+    elem.nodeName === 'TEXTAREA'
+  );
+}
+
+module.exports = isTextInputElement;
+
+},{}],112:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule isTextNode
+ * @typechecks
+ */
+
+var isNode = require("./isNode");
+
+/**
+ * @param {*} object The object to check.
+ * @return {boolean} Whether or not the object is a DOM text node.
+ */
+function isTextNode(object) {
+  return isNode(object) && object.nodeType == 3;
+}
+
+module.exports = isTextNode;
+
+},{"./isNode":110}],113:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule joinClasses
+ * @typechecks static-only
+ */
+
+"use strict";
+
+/**
+ * Combines multiple className strings into one.
+ * http://jsperf.com/joinclasses-args-vs-array
+ *
+ * @param {...?string} classes
+ * @return {string}
+ */
+function joinClasses(className/*, ... */) {
+  if (!className) {
+    className = '';
+  }
+  var nextClass;
+  var argLength = arguments.length;
+  if (argLength > 1) {
+    for (var ii = 1; ii < argLength; ii++) {
+      nextClass = arguments[ii];
+      nextClass && (className += ' ' + nextClass);
+    }
+  }
+  return className;
+}
+
+module.exports = joinClasses;
+
+},{}],114:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule keyMirror
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var invariant = require("./invariant");
+
+/**
+ * Constructs an enumeration with keys equal to their value.
+ *
+ * For example:
+ *
+ *   var COLORS = keyMirror({blue: null, red: null});
+ *   var myColor = COLORS.blue;
+ *   var isColorValid = !!COLORS[myColor];
+ *
+ * The last line could not be performed if the values of the generated enum were
+ * not equal to their keys.
+ *
+ *   Input:  {key1: val1, key2: val2}
+ *   Output: {key1: key1, key2: key2}
+ *
+ * @param {object} obj
+ * @return {object}
+ */
+var keyMirror = function(obj) {
+  var ret = {};
+  var key;
+  ("production" !== "development" ? invariant(
+    obj instanceof Object && !Array.isArray(obj),
+    'keyMirror(...): Argument must be an object.'
+  ) : invariant(obj instanceof Object && !Array.isArray(obj)));
+  for (key in obj) {
+    if (!obj.hasOwnProperty(key)) {
+      continue;
+    }
+    ret[key] = key;
+  }
+  return ret;
+};
+
+module.exports = keyMirror;
+
+},{"./invariant":108}],115:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule keyOf
+ */
+
+/**
+ * Allows extraction of a minified key. Let's the build system minify keys
+ * without loosing the ability to dynamically use key strings as values
+ * themselves. Pass in an object with a single key/val pair and it will return
+ * you the string key of that single record. Suppose you want to grab the
+ * value for a key 'className' inside of an object. Key/val minification may
+ * have aliased that key to be 'xa12'. keyOf({className: null}) will return
+ * 'xa12' in that case. Resolve keys you want to use once at startup time, then
+ * reuse those resolutions.
+ */
+var keyOf = function(oneKeyObj) {
+  var key;
+  for (key in oneKeyObj) {
+    if (!oneKeyObj.hasOwnProperty(key)) {
+      continue;
+    }
+    return key;
+  }
+  return null;
+};
+
+
+module.exports = keyOf;
+
+},{}],116:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule memoizeStringOnly
+ * @typechecks static-only
+ */
+
+"use strict";
+
+/**
+ * Memoizes the return value of a function that accepts one string argument.
+ *
+ * @param {function} callback
+ * @return {function}
+ */
+function memoizeStringOnly(callback) {
+  var cache = {};
+  return function(string) {
+    if (cache.hasOwnProperty(string)) {
+      return cache[string];
+    } else {
+      return cache[string] = callback.call(this, string);
+    }
+  };
+}
+
+module.exports = memoizeStringOnly;
+
+},{}],117:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule merge
+ */
+
+"use strict";
+
+var mergeInto = require("./mergeInto");
+
+/**
+ * Shallow merges two structures into a return value, without mutating either.
+ *
+ * @param {?object} one Optional object with properties to merge from.
+ * @param {?object} two Optional object with properties to merge from.
+ * @return {object} The shallow extension of one by two.
+ */
+var merge = function(one, two) {
+  var result = {};
+  mergeInto(result, one);
+  mergeInto(result, two);
+  return result;
+};
+
+module.exports = merge;
+
+},{"./mergeInto":119}],118:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule mergeHelpers
+ *
+ * requiresPolyfills: Array.isArray
+ */
+
+"use strict";
+
+var invariant = require("./invariant");
+var keyMirror = require("./keyMirror");
+
+/**
+ * Maximum number of levels to traverse. Will catch circular structures.
+ * @const
+ */
+var MAX_MERGE_DEPTH = 36;
+
+/**
+ * We won't worry about edge cases like new String('x') or new Boolean(true).
+ * Functions are considered terminals, and arrays are not.
+ * @param {*} o The item/object/value to test.
+ * @return {boolean} true iff the argument is a terminal.
+ */
+var isTerminal = function(o) {
+  return typeof o !== 'object' || o === null;
+};
+
+var mergeHelpers = {
+
+  MAX_MERGE_DEPTH: MAX_MERGE_DEPTH,
+
+  isTerminal: isTerminal,
+
+  /**
+   * Converts null/undefined values into empty object.
+   *
+   * @param {?Object=} arg Argument to be normalized (nullable optional)
+   * @return {!Object}
+   */
+  normalizeMergeArg: function(arg) {
+    return arg === undefined || arg === null ? {} : arg;
+  },
+
+  /**
+   * If merging Arrays, a merge strategy *must* be supplied. If not, it is
+   * likely the caller's fault. If this function is ever called with anything
+   * but `one` and `two` being `Array`s, it is the fault of the merge utilities.
+   *
+   * @param {*} one Array to merge into.
+   * @param {*} two Array to merge from.
+   */
+  checkMergeArrayArgs: function(one, two) {
+    ("production" !== "development" ? invariant(
+      Array.isArray(one) && Array.isArray(two),
+      'Tried to merge arrays, instead got %s and %s.',
+      one,
+      two
+    ) : invariant(Array.isArray(one) && Array.isArray(two)));
+  },
+
+  /**
+   * @param {*} one Object to merge into.
+   * @param {*} two Object to merge from.
+   */
+  checkMergeObjectArgs: function(one, two) {
+    mergeHelpers.checkMergeObjectArg(one);
+    mergeHelpers.checkMergeObjectArg(two);
+  },
+
+  /**
+   * @param {*} arg
+   */
+  checkMergeObjectArg: function(arg) {
+    ("production" !== "development" ? invariant(
+      !isTerminal(arg) && !Array.isArray(arg),
+      'Tried to merge an object, instead got %s.',
+      arg
+    ) : invariant(!isTerminal(arg) && !Array.isArray(arg)));
+  },
+
+  /**
+   * Checks that a merge was not given a circular object or an object that had
+   * too great of depth.
+   *
+   * @param {number} Level of recursion to validate against maximum.
+   */
+  checkMergeLevel: function(level) {
+    ("production" !== "development" ? invariant(
+      level < MAX_MERGE_DEPTH,
+      'Maximum deep merge depth exceeded. You may be attempting to merge ' +
+      'circular structures in an unsupported way.'
+    ) : invariant(level < MAX_MERGE_DEPTH));
+  },
+
+  /**
+   * Checks that the supplied merge strategy is valid.
+   *
+   * @param {string} Array merge strategy.
+   */
+  checkArrayStrategy: function(strategy) {
+    ("production" !== "development" ? invariant(
+      strategy === undefined || strategy in mergeHelpers.ArrayStrategies,
+      'You must provide an array strategy to deep merge functions to ' +
+      'instruct the deep merge how to resolve merging two arrays.'
+    ) : invariant(strategy === undefined || strategy in mergeHelpers.ArrayStrategies));
+  },
+
+  /**
+   * Set of possible behaviors of merge algorithms when encountering two Arrays
+   * that must be merged together.
+   * - `clobber`: The left `Array` is ignored.
+   * - `indexByIndex`: The result is achieved by recursively deep merging at
+   *   each index. (not yet supported.)
+   */
+  ArrayStrategies: keyMirror({
+    Clobber: true,
+    IndexByIndex: true
+  })
+
+};
+
+module.exports = mergeHelpers;
+
+},{"./invariant":108,"./keyMirror":114}],119:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule mergeInto
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var mergeHelpers = require("./mergeHelpers");
+
+var checkMergeObjectArg = mergeHelpers.checkMergeObjectArg;
+
+/**
+ * Shallow merges two structures by mutating the first parameter.
+ *
+ * @param {object} one Object to be merged into.
+ * @param {?object} two Optional object with properties to merge from.
+ */
+function mergeInto(one, two) {
+  checkMergeObjectArg(one);
+  if (two != null) {
+    checkMergeObjectArg(two);
+    for (var key in two) {
+      if (!two.hasOwnProperty(key)) {
+        continue;
+      }
+      one[key] = two[key];
+    }
+  }
+}
+
+module.exports = mergeInto;
+
+},{"./mergeHelpers":118}],120:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule mixInto
+ */
+
+"use strict";
+
+/**
+ * Simply copies properties to the prototype.
+ */
+var mixInto = function(constructor, methodBag) {
+  var methodName;
+  for (methodName in methodBag) {
+    if (!methodBag.hasOwnProperty(methodName)) {
+      continue;
+    }
+    constructor.prototype[methodName] = methodBag[methodName];
+  }
+};
+
+module.exports = mixInto;
+
+},{}],121:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule objMap
+ */
+
+"use strict";
+
+/**
+ * For each key/value pair, invokes callback func and constructs a resulting
+ * object which contains, for every key in obj, values that are the result of
+ * of invoking the function:
+ *
+ *   func(value, key, iteration)
+ *
+ * @param {?object} obj Object to map keys over
+ * @param {function} func Invoked for each key/val pair.
+ * @param {?*} context
+ * @return {?object} Result of mapping or null if obj is falsey
+ */
+function objMap(obj, func, context) {
+  if (!obj) {
+    return null;
+  }
+  var i = 0;
+  var ret = {};
+  for (var key in obj) {
+    if (obj.hasOwnProperty(key)) {
+      ret[key] = func.call(context, obj[key], key, i++);
+    }
+  }
+  return ret;
+}
+
+module.exports = objMap;
+
+},{}],122:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule objMapKeyVal
+ */
+
+"use strict";
+
+/**
+ * Behaves the same as `objMap` but invokes func with the key first, and value
+ * second. Use `objMap` unless you need this special case.
+ * Invokes func as:
+ *
+ *   func(key, value, iteration)
+ *
+ * @param {?object} obj Object to map keys over
+ * @param {!function} func Invoked for each key/val pair.
+ * @param {?*} context
+ * @return {?object} Result of mapping or null if obj is falsey
+ */
+function objMapKeyVal(obj, func, context) {
+  if (!obj) {
+    return null;
+  }
+  var i = 0;
+  var ret = {};
+  for (var key in obj) {
+    if (obj.hasOwnProperty(key)) {
+      ret[key] = func.call(context, key, obj[key], i++);
+    }
+  }
+  return ret;
+}
+
+module.exports = objMapKeyVal;
+
+},{}],123:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule onlyChild
+ */
+"use strict";
+
+var ReactComponent = require("./ReactComponent");
+
+var invariant = require("./invariant");
+
+/**
+ * Returns the first child in a collection of children and verifies that there
+ * is only one child in the collection. The current implementation of this
+ * function assumes that a single child gets passed without a wrapper, but the
+ * purpose of this helper function is to abstract away the particular structure
+ * of children.
+ *
+ * @param {?object} children Child collection structure.
+ * @return {ReactComponent} The first and only `ReactComponent` contained in the
+ * structure.
+ */
+function onlyChild(children) {
+  ("production" !== "development" ? invariant(
+    ReactComponent.isValidComponent(children),
+    'onlyChild must be passed a children with exactly one child.'
+  ) : invariant(ReactComponent.isValidComponent(children)));
+  return children;
+}
+
+module.exports = onlyChild;
+
+},{"./ReactComponent":26,"./invariant":108}],124:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule performanceNow
+ * @typechecks static-only
+ */
+
+"use strict";
+
+var ExecutionEnvironment = require("./ExecutionEnvironment");
+
+/**
+ * Detect if we can use window.performance.now() and gracefully
+ * fallback to Date.now() if it doesn't exist.
+ * We need to support Firefox < 15 for now due to Facebook's webdriver
+ * infrastructure.
+ */
+var performance = null;
+
+if (ExecutionEnvironment.canUseDOM) {
+  performance = window.performance || window.webkitPerformance;
+}
+
+if (!performance || !performance.now) {
+  performance = Date;
+}
+
+var performanceNow = performance.now.bind(performance);
+
+module.exports = performanceNow;
+
+},{"./ExecutionEnvironment":20}],125:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule shallowEqual
+ */
+
+"use strict";
+
+/**
+ * Performs equality by iterating through keys on an object and returning
+ * false when any key has values which are not strictly equal between
+ * objA and objB. Returns true when the values of all keys are strictly equal.
+ *
+ * @return {boolean}
+ */
+function shallowEqual(objA, objB) {
+  if (objA === objB) {
+    return true;
+  }
+  var key;
+  // Test for A's keys different from B.
+  for (key in objA) {
+    if (objA.hasOwnProperty(key) &&
+        (!objB.hasOwnProperty(key) || objA[key] !== objB[key])) {
+      return false;
+    }
+  }
+  // Test for B'a keys missing from A.
+  for (key in objB) {
+    if (objB.hasOwnProperty(key) && !objA.hasOwnProperty(key)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+module.exports = shallowEqual;
+
+},{}],126:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule shouldUpdateReactComponent
+ * @typechecks static-only
+ */
+
+"use strict";
+
+/**
+ * Given a `prevComponent` and `nextComponent`, determines if `prevComponent`
+ * should be updated as opposed to being destroyed or replaced.
+ *
+ * @param {?object} prevComponent
+ * @param {?object} nextComponent
+ * @return {boolean} True if `prevComponent` should be updated.
+ * @protected
+ */
+function shouldUpdateReactComponent(prevComponent, nextComponent) {
+  // TODO: Remove warning after a release.
+  if (prevComponent && nextComponent &&
+      prevComponent.constructor === nextComponent.constructor && (
+        (prevComponent.props && prevComponent.props.key) ===
+        (nextComponent.props && nextComponent.props.key)
+      )) {
+    if (prevComponent._owner === nextComponent._owner) {
+      return true;
+    } else {
+      if ("production" !== "development") {
+        if (prevComponent.state) {
+          console.warn(
+            'A recent change to React has been found to impact your code. ' +
+            'A mounted component will now be unmounted and replaced by a ' +
+            'component (of the same class) if their owners are different. ' +
+            'Previously, ownership was not considered when updating.',
+            prevComponent,
+            nextComponent
+          );
+        }
+      }
+    }
+  }
+  return false;
+}
+
+module.exports = shouldUpdateReactComponent;
+
+},{}],127:[function(require,module,exports){
+/**
+ * Copyright 2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule toArray
+ * @typechecks
+ */
+
+var invariant = require("./invariant");
+
+/**
+ * Convert array-like objects to arrays.
+ *
+ * This API assumes the caller knows the contents of the data type. For less
+ * well defined inputs use createArrayFrom.
+ *
+ * @param {object|function} obj
+ * @return {array}
+ */
+function toArray(obj) {
+  var length = obj.length;
+
+  // Some browse builtin objects can report typeof 'function' (e.g. NodeList in
+  // old versions of Safari).
+  ("production" !== "development" ? invariant(
+    !Array.isArray(obj) &&
+    (typeof obj === 'object' || typeof obj === 'function'),
+    'toArray: Array-like object expected'
+  ) : invariant(!Array.isArray(obj) &&
+  (typeof obj === 'object' || typeof obj === 'function')));
+
+  ("production" !== "development" ? invariant(
+    typeof length === 'number',
+    'toArray: Object needs a length property'
+  ) : invariant(typeof length === 'number'));
+
+  ("production" !== "development" ? invariant(
+    length === 0 ||
+    (length - 1) in obj,
+    'toArray: Object should have keys for indices'
+  ) : invariant(length === 0 ||
+  (length - 1) in obj));
+
+  // Old IE doesn't give collections access to hasOwnProperty. Assume inputs
+  // without method will throw during the slice call and skip straight to the
+  // fallback.
+  if (obj.hasOwnProperty) {
+    try {
+      return Array.prototype.slice.call(obj);
+    } catch (e) {
+      // IE < 9 does not support Array#slice on collections objects
+    }
+  }
+
+  // Fall back to copying key by key. This assumes all keys have a value,
+  // so will not preserve sparsely populated inputs.
+  var ret = Array(length);
+  for (var ii = 0; ii < length; ii++) {
+    ret[ii] = obj[ii];
+  }
+  return ret;
+}
+
+module.exports = toArray;
+
+},{"./invariant":108}],128:[function(require,module,exports){
+/**
+ * Copyright 2013-2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule traverseAllChildren
+ */
+
+"use strict";
+
+var ReactInstanceHandles = require("./ReactInstanceHandles");
+var ReactTextComponent = require("./ReactTextComponent");
+
+var invariant = require("./invariant");
+
+var SEPARATOR = ReactInstanceHandles.SEPARATOR;
+var SUBSEPARATOR = ':';
+
+/**
+ * TODO: Test that:
+ * 1. `mapChildren` transforms strings and numbers into `ReactTextComponent`.
+ * 2. it('should fail when supplied duplicate key', function() {
+ * 3. That a single child and an array with one item have the same key pattern.
+ * });
+ */
+
+var userProvidedKeyEscaperLookup = {
+  '=': '=0',
+  '.': '=1',
+  ':': '=2'
+};
+
+var userProvidedKeyEscapeRegex = /[=.:]/g;
+
+function userProvidedKeyEscaper(match) {
+  return userProvidedKeyEscaperLookup[match];
+}
+
+/**
+ * Generate a key string that identifies a component within a set.
+ *
+ * @param {*} component A component that could contain a manual key.
+ * @param {number} index Index that is used if a manual key is not provided.
+ * @return {string}
+ */
+function getComponentKey(component, index) {
+  if (component && component.props && component.props.key != null) {
+    // Explicit key
+    return wrapUserProvidedKey(component.props.key);
+  }
+  // Implicit key determined by the index in the set
+  return index.toString(36);
+}
+
+/**
+ * Escape a component key so that it is safe to use in a reactid.
+ *
+ * @param {*} key Component key to be escaped.
+ * @return {string} An escaped string.
+ */
+function escapeUserProvidedKey(text) {
+  return ('' + text).replace(
+    userProvidedKeyEscapeRegex,
+    userProvidedKeyEscaper
+  );
+}
+
+/**
+ * Wrap a `key` value explicitly provided by the user to distinguish it from
+ * implicitly-generated keys generated by a component's index in its parent.
+ *
+ * @param {string} key Value of a user-provided `key` attribute
+ * @return {string}
+ */
+function wrapUserProvidedKey(key) {
+  return '$' + escapeUserProvidedKey(key);
+}
+
+/**
+ * @param {?*} children Children tree container.
+ * @param {!string} nameSoFar Name of the key path so far.
+ * @param {!number} indexSoFar Number of children encountered until this point.
+ * @param {!function} callback Callback to invoke with each child found.
+ * @param {?*} traverseContext Used to pass information throughout the traversal
+ * process.
+ * @return {!number} The number of children in this subtree.
+ */
+var traverseAllChildrenImpl =
+  function(children, nameSoFar, indexSoFar, callback, traverseContext) {
+    var subtreeCount = 0;  // Count of children found in the current subtree.
+    if (Array.isArray(children)) {
+      for (var i = 0; i < children.length; i++) {
+        var child = children[i];
+        var nextName = (
+          nameSoFar +
+          (nameSoFar ? SUBSEPARATOR : SEPARATOR) +
+          getComponentKey(child, i)
+        );
+        var nextIndex = indexSoFar + subtreeCount;
+        subtreeCount += traverseAllChildrenImpl(
+          child,
+          nextName,
+          nextIndex,
+          callback,
+          traverseContext
+        );
+      }
+    } else {
+      var type = typeof children;
+      var isOnlyChild = nameSoFar === '';
+      // If it's the only child, treat the name as if it was wrapped in an array
+      // so that it's consistent if the number of children grows
+      var storageName =
+        isOnlyChild ? SEPARATOR + getComponentKey(children, 0) : nameSoFar;
+      if (children == null || type === 'boolean') {
+        // All of the above are perceived as null.
+        callback(traverseContext, null, storageName, indexSoFar);
+        subtreeCount = 1;
+      } else if (children.mountComponentIntoNode) {
+        callback(traverseContext, children, storageName, indexSoFar);
+        subtreeCount = 1;
+      } else {
+        if (type === 'object') {
+          ("production" !== "development" ? invariant(
+            !children || children.nodeType !== 1,
+            'traverseAllChildren(...): Encountered an invalid child; DOM ' +
+            'elements are not valid children of React components.'
+          ) : invariant(!children || children.nodeType !== 1));
+          for (var key in children) {
+            if (children.hasOwnProperty(key)) {
+              subtreeCount += traverseAllChildrenImpl(
+                children[key],
+                (
+                  nameSoFar + (nameSoFar ? SUBSEPARATOR : SEPARATOR) +
+                  wrapUserProvidedKey(key) + SUBSEPARATOR +
+                  getComponentKey(children[key], 0)
+                ),
+                indexSoFar + subtreeCount,
+                callback,
+                traverseContext
+              );
+            }
+          }
+        } else if (type === 'string') {
+          var normalizedText = new ReactTextComponent(children);
+          callback(traverseContext, normalizedText, storageName, indexSoFar);
+          subtreeCount += 1;
+        } else if (type === 'number') {
+          var normalizedNumber = new ReactTextComponent('' + children);
+          callback(traverseContext, normalizedNumber, storageName, indexSoFar);
+          subtreeCount += 1;
+        }
+      }
+    }
+    return subtreeCount;
+  };
+
+/**
+ * Traverses children that are typically specified as `props.children`, but
+ * might also be specified through attributes:
+ *
+ * - `traverseAllChildren(this.props.children, ...)`
+ * - `traverseAllChildren(this.props.leftPanelChildren, ...)`
+ *
+ * The `traverseContext` is an optional argument that is passed through the
+ * entire traversal. It can be used to store accumulations or anything else that
+ * the callback might find relevant.
+ *
+ * @param {?*} children Children tree object.
+ * @param {!function} callback To invoke upon traversing each child.
+ * @param {?*} traverseContext Context for traversal.
+ */
+function traverseAllChildren(children, callback, traverseContext) {
+  if (children !== null && children !== undefined) {
+    traverseAllChildrenImpl(children, '', 0, callback, traverseContext);
+  }
+}
+
+module.exports = traverseAllChildren;
+
+},{"./ReactInstanceHandles":53,"./ReactTextComponent":69,"./invariant":108}],129:[function(require,module,exports){
+/**
+ * Copyright 2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @providesModule warning
+ */
+
+"use strict";
+
+var emptyFunction = require("./emptyFunction");
+
+/**
+ * Similar to invariant but only logs a warning if the condition is not met.
+ * This can be used to log issues in development environments in critical
+ * paths. Removing the logging code for production environments will keep the
+ * same logic and follow the same code paths.
+ */
+
+var warning = emptyFunction;
+
+if ("production" !== "development") {
+  warning = function(condition, format ) {var args=Array.prototype.slice.call(arguments,2);
+    if (format === undefined) {
+      throw new Error(
+        '`warning(condition, format, ...args)` requires a warning ' +
+        'message argument'
+      );
+    }
+
+    if (!condition) {
+      var argIndex = 0;
+      console.warn('Warning: ' + format.replace(/%s/g, function()  {return args[argIndex++];}));
+    }
+  };
+}
+
+module.exports = warning;
+
+},{"./emptyFunction":95}]},{},[24])
+(24)
+});
\ No newline at end of file
diff --git a/app/gui/qt/SonicPi.pro b/app/gui/qt/SonicPi.pro
index 1a27820..e87a89d 100644
--- a/app/gui/qt/SonicPi.pro
+++ b/app/gui/qt/SonicPi.pro
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, distribution,
@@ -19,29 +19,40 @@
 
 # -- Change to match the location of QScintilla on your system
 #
- LIBS += -L/Users/sam/Downloads/tmp/QScintilla-gpl-2.9/Qt4Qt5 -lqscintilla2
+ LIBS += -L/Users/sam/Downloads/tmp/QScintilla-gpl-2.9/Qt4Qt5
  INCLUDEPATH += /Users/sam/Downloads/tmp/QScintilla-gpl-2.9/Qt4Qt5
  DEPENDPATH += /Users/sam/Downloads/tmp/QScintilla-gpl-2.9/Qt4Qt5
 # --
 
-QT       += core gui concurrent network
-
-greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
-
+TARGET = 'sonic-pi'
 
+QT += core gui concurrent network
+greaterThan(QT_MAJOR_VERSION, 4) {
+  QT += widgets
+}
 
-TARGET = 'sonic-pi'
+# Linux only
+unix:!macx {
+  lessThan(QT_MAJOR_VERSION, 5) {
+    LIBS += -lqscintilla2
+  } else {
+    LIBS += -lqt5scintilla2
+  }
+  QMAKE_CXXFLAGS += -Wall -Werror -Wextra
+}
 
+# Mac OS X only
 macx {
   TARGET = 'Sonic Pi'
+  LIBS += -lqscintilla2
   QT += macextras
   DEFINES += DONT_USE_OSX_KEYS
-}
-
-!win32 {
   QMAKE_CXXFLAGS += -Wall -Werror -Wextra
 }
+
+# Windows only
 win32 {
+  LIBS += -lqscintilla2
   QMAKE_CXXFLAGS += /WX
   DEFINES += _CRT_SECURE_NO_WARNINGS _WINSOCK_DEPRECATED_NO_WARNINGS
 }
@@ -58,9 +69,9 @@ SOURCES += main.cpp \
            sonicpiscintilla.cpp \
            oschandler.cpp \
            sonicpilog.cpp \
-           sonicpiserver.cpp \
-           sonicpiudpserver.cpp \
-           sonicpitcpserver.cpp \
+           sonic_pi_osc_server.cpp \
+           sonic_pi_udp_osc_server.cpp \
+           sonic_pi_tcp_osc_server.cpp \
            sonicpitheme.cpp
 win32 {
 # have to link these explicitly for some reason
@@ -76,10 +87,10 @@ HEADERS  += mainwindow.h \
             sonicpiapis.h \
             sonicpiscintilla.h \
             oschandler.h \
-            sonicpiserver.h \
-            sonicpiudpserver.h \
+            sonic_pi_osc_server.h \
+            sonic_pi_udp_osc_server.h \
+            sonic_pi_tcp_osc_server.h \
             ruby_help.h \
-            sonicpitcpserver.h \
             sonicpitheme.h
 
 TRANSLATIONS = lang/sonic-pi_de.ts \
@@ -89,7 +100,9 @@ TRANSLATIONS = lang/sonic-pi_de.ts \
                lang/sonic-pi_pl.ts \
                lang/sonic-pi_fr.ts \
                lang/sonic-pi_es.ts \
-               lang/sonic-pi_hu.ts
+               lang/sonic-pi_hu.ts \
+               lang/sonic-pi_zh-Hans.ts \
+               lang/sonic-pi_zh-Hant.ts \
 
 OTHER_FILES += \
     images/copy.png \
@@ -108,7 +121,6 @@ RESOURCES += \
 RC_FILE = SonicPi.rc
 
 ICON = images/app.icns
-LIBS         += -lqscintilla2
 
 win32 {
 	install_qsci.files = $$[QT_INSTALL_LIBS]\qscintilla2.dll
diff --git a/app/gui/qt/SonicPi.qrc b/app/gui/qt/SonicPi.qrc
index 9128a86..089f95b 100644
--- a/app/gui/qt/SonicPi.qrc
+++ b/app/gui/qt/SonicPi.qrc
@@ -6,6 +6,7 @@
         <file>images/prefs.png</file>
         <file>images/run.png</file>
         <file>images/save.png</file>
+        <file>images/load.png</file>
         <file>images/stop.png</file>
         <file>images/rec.png</file>
         <file>images/recording_a.png</file>
@@ -49,6 +50,7 @@
         <file>images/coreteam/josephwilk.png</file>
         <file>images/coreteam/xavierriley.png</file>
         <file>images/coreteam/jweather.png</file>
+        <file>images/coreteam/hannozulla.png</file>
 
         <file>html/doc.html</file>
         <file>html/info.html</file>
@@ -65,5 +67,7 @@
         <file>lang/sonic-pi_fr.qm</file>
         <file>lang/sonic-pi_es.qm</file>
         <file>lang/sonic-pi_hu.qm</file>
+        <file>lang/sonic-pi_zh-Hans.qm</file>
+        <file>lang/sonic-pi_zh-Hant.qm</file>
     </qresource>
 </RCC>
diff --git a/app/gui/qt/api_list.h b/app/gui/qt/api_list.h
index fe3b625..4d5db74 100644
--- a/app/gui/qt/api_list.h
+++ b/app/gui/qt/api_list.h
@@ -3,7 +3,7 @@
 // Full project source: https://github.com/samaaron/sonic-pi
 // License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 //
-// Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 // All rights reserved.
 //
 // Permission is granted for use, copying, modification, and
diff --git a/app/gui/qt/html/doc.html b/app/gui/qt/html/doc.html
index 7cd16b8..97f2743 100644
--- a/app/gui/qt/html/doc.html
+++ b/app/gui/qt/html/doc.html
@@ -9,10 +9,13 @@
  ___/ / /_/ / / / / / /__   / ____/ /
 /____/\____/_/ /_/_/\___/  /_/   /_/
     </pre>
-    <p class="strapline"><b>music_as <span class="highlight">:code</span></b><br/>
-    <b>code_as <span class="highlight">:art</span></b></p>
 
-    <p class="version">v2.9</p>
+    <p class="strapline">
+      <pre>music_as <span class="highlight">:code</span>
+ code_as <span class="highlight">:art</span></pre>
+    </p>
+
+    <p class="version">v2.10</p>
 
   </center>
 
diff --git a/app/gui/qt/html/info.html b/app/gui/qt/html/info.html
index 40de598..96c39b1 100644
--- a/app/gui/qt/html/info.html
+++ b/app/gui/qt/html/info.html
@@ -21,13 +21,14 @@
 
     <br/>
 
-    <p>
-      <b>music_as <span class="highlight">:code</span></b><br/>
-      <b>code_as <span class="highlight">:art</span></b>
+
+    <p class="strapline">
+      <pre>music_as <span class="highlight">:code</span>
+code_as <span class="highlight">:art</span></pre>
     </p>
 
     <br/>
 
-    <p class="version">v2.9</p>
+    <p class="version">v2.10</p>
   </center>
 </body>
diff --git a/app/gui/qt/images/coreteam/hannozulla.png b/app/gui/qt/images/coreteam/hannozulla.png
new file mode 100644
index 0000000..80d2ebc
Binary files /dev/null and b/app/gui/qt/images/coreteam/hannozulla.png differ
diff --git a/app/gui/qt/images/load.png b/app/gui/qt/images/load.png
new file mode 100644
index 0000000..dae9ac8
Binary files /dev/null and b/app/gui/qt/images/load.png differ
diff --git a/app/gui/qt/images/logo.txt b/app/gui/qt/images/logo.txt
index f8aa1a1..cf6d9b8 100644
--- a/app/gui/qt/images/logo.txt
+++ b/app/gui/qt/images/logo.txt
@@ -18,3 +18,5 @@
     /____/\____/_/ /_/_/\___/  /_/   /_/
 
      The Live Coding Synth for Everyone
+
+            http://sonic-pi.net
diff --git a/app/gui/qt/images/save.png b/app/gui/qt/images/save.png
index 515a1d3..e04975a 100644
Binary files a/app/gui/qt/images/save.png and b/app/gui/qt/images/save.png differ
diff --git a/app/gui/qt/images/splash.png b/app/gui/qt/images/splash.png
index b6e5a4e..0725387 100644
Binary files a/app/gui/qt/images/splash.png and b/app/gui/qt/images/splash.png differ
diff --git a/app/gui/qt/images/splash at 2x.png b/app/gui/qt/images/splash at 2x.png
index db6b10e..8991bbf 100644
Binary files a/app/gui/qt/images/splash at 2x.png and b/app/gui/qt/images/splash at 2x.png differ
diff --git a/app/gui/qt/lang/sonic-pi_es.ts b/app/gui/qt/lang/sonic-pi_es.ts
index d5ae1bb..a3b0f84 100644
--- a/app/gui/qt/lang/sonic-pi_es.ts
+++ b/app/gui/qt/lang/sonic-pi_es.ts
@@ -65,7 +65,7 @@
     <message>
         <location filename="../mainwindow.cpp" line="754"/>
         <source>Use this slider to change the system volume of your Raspberry Pi.</source>
-        <translation>Usa este slider para cambiar el volumen del sistema en tu Raspberry Pi</translation>
+        <translation>Usa este "slider" para cambiar el volumen del sistema en tu Raspberry Pi.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="756"/>
@@ -76,7 +76,8 @@
         <location filename="../mainwindow.cpp" line="757"/>
         <source>Advanced audio settings for working with
 external PA systems when performing with Sonic Pi.</source>
-        <translation>Configuraciones de audio avanzadas para trabajar con sistemas externos PA al momento de hacer performing con Sonic Pi</translation>
+        <translation>Configuraciones de audio avanzadas para trabajar con 
+sistemas externos PA al momento de hacer performing con Sonic Pi.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="758"/>
@@ -88,7 +89,9 @@ external PA systems when performing with Sonic Pi.</source>
         <source>Toggle stereo inversion.
 If enabled, audio sent to the left speaker will
 be routed to the right speaker and visa versa.</source>
-        <translation>Cambia la inversión del estereo.  Si se encuentra activado, el audio del speaker izquierdo se ruteara al parlante derecho, o a la inversa</translation>
+        <translation>Cambia la inversión del estéreo.
+Si se encuentra activado, el audio del altavoz izquierdo 
+se desviará al altavoz derecho, o viceversa.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="761"/>
@@ -113,7 +116,9 @@ can only handle mono.</source>
         <source>Toggle synth argument checking functions.
 If disabled, certain synth opt values may
 create unexpectedly loud or uncomfortable sounds.</source>
-        <translation>Cambia la opción de chequeo de argumentos en el sintetizador. Si se encuentra deshabilitado, ciertas opciones generarán sonidos muy fuertes o incómodos</translation>
+        <translation>Cambia la opción de comprobación de argumentos en el sintetizador.
+Si se encuentra deshabilitado, ciertas opciones generarán sonidos muy
+fuertes o incómodos.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="778"/>
@@ -126,7 +131,10 @@ create unexpectedly loud or uncomfortable sounds.</source>
 Firstly, there is the headphone jack of the Raspberry Pi itself.
 Secondly, some HDMI monitors/TVs support audio through the HDMI port.
 Use these buttons to force the output to the one you want.</source>
-        <translation>Tu Raspberry Pi cuenta con dos opciones para salida de sonido.  Primero, tenemos el conector jack para la conexión de audífonos en el mismo Raspberry Pi Segundo, algunos monitores HDMI soportan salida de audio por medio del puerto HDMI Usa estos botones para forzar la salida de audio en alguna de estas dos opciones</translation>
+        <translation>Tu Raspberry Pi cuenta con dos opciones para salida de sonido.
+Primero, tenemos el conector jack para la conexión de auriculares en el propio Raspberry Pi. 
+Segundo, algunos monitores HDMI soportan salida de audio por medio del puerto HDMI. 
+Usa estos botones para forzar la salida de audio en alguna de estas dos opciones.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="780"/>
@@ -163,7 +171,9 @@ Use these buttons to force the output to the one you want.</source>
         <source>Toggle log messages.
 If disabled, activity such as synth and sample
 triggering will not be printed to the log by default.</source>
-        <translation>Cambiar opción de logear mensajes. Si esta opción está deshabilitada, actividades como la activación del sintetizador o sample no se imprimirán en el log por default</translation>
+        <translation>Cambiar opción de registrar mensajes.
+Si esta opción está deshabilitada, actividades como el disparador del sintetizador 
+o muestra no se imprimirán en el registro por defecto.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="808"/>
@@ -175,7 +185,9 @@ triggering will not be printed to the log by default.</source>
         <source>Toggle log clearing on run.
 If enabled, the log is cleared each
 time the run button is pressed.</source>
-        <translation>Cambia opción de limpiar log al iniciar.  Si se encuentra habilitado, el log se limpiará cada vez que se presione el boton de iniciar</translation>
+        <translation>Cambia opción de limpiar registro al iniciar. 
+Si se encuentra habilitado, el registro se limpiará 
+cada vez que se presione el botón de iniciar.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="811"/>
@@ -204,7 +216,8 @@ However, they will not be visible in the logs.</source>
         <location filename="../mainwindow.cpp" line="827"/>
         <source>Toggle automatic update checking.
 This check involves sending anonymous information about your platform and version.</source>
-        <translation>Cambia la opción del chequeo automático de actualizaciones.  Este chequeo consiste en enviar información anónima de tu plataforma y versión actuales</translation>
+        <translation>Cambia la opción del comprobación automática de actualizaciones.  
+Esta verificación conlleva enviar información anónima de tu plataforma y versión actuales.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="828"/>
@@ -215,7 +228,8 @@ This check involves sending anonymous information about your platform and versio
         <location filename="../mainwindow.cpp" line="829"/>
         <source>Force a check for updates now.
 This check involves sending anonymous information about your platform and version.</source>
-        <translation>Chequea inmediatamente la existencia de actualizaciones.  Este chequeo consiste en enviar información anónima de tu plataforma y versión actuales</translation>
+        <translation>Comprobar inmediatamente la existencia de actualizaciones.  
+Esta verificación conlleva enviar información anónima de tu plataforma y versión actuales.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="830"/>
@@ -240,7 +254,7 @@ This check involves sending anonymous information about your platform and versio
     <message>
         <location filename="../mainwindow.cpp" line="856"/>
         <source>Configure editor display options.</source>
-        <translation>Configurar opciones de display del editor</translation>
+        <translation>Configurar opciones de pantalla del editor.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="857"/>
@@ -250,7 +264,7 @@ This check involves sending anonymous information about your platform and versio
     <message>
         <location filename="../mainwindow.cpp" line="858"/>
         <source>Configure editor look and feel.</source>
-        <translation>Configura el aspecto del editor</translation>
+        <translation>Configura el aspecto del editor.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="859"/>
@@ -260,7 +274,7 @@ This check involves sending anonymous information about your platform and versio
     <message>
         <location filename="../mainwindow.cpp" line="860"/>
         <source>Configure automation features.</source>
-        <translation>Configura las características de automatización</translation>
+        <translation>Configura las características de automatización.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="861"/>
@@ -280,7 +294,7 @@ This check involves sending anonymous information about your platform and versio
     <message>
         <location filename="../mainwindow.cpp" line="865"/>
         <source>Toggle line number visibility.</source>
-        <translation>Cambia la visibilidad del número de lineas</translation>
+        <translation>Cambia la visibilidad del número de lineas.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="866"/>
@@ -290,7 +304,7 @@ This check involves sending anonymous information about your platform and versio
     <message>
         <location filename="../mainwindow.cpp" line="867"/>
         <source>Toggle visibility of the log.</source>
-        <translation>Cambia opción de visibilidad del log</translation>
+        <translation>Cambia opción de visibilidad del registro.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="869"/>
@@ -300,7 +314,7 @@ This check involves sending anonymous information about your platform and versio
     <message>
         <location filename="../mainwindow.cpp" line="870"/>
         <source>Toggle visibility of the control buttons.</source>
-        <translation>Cambia la opción de visibilidad de las opciones del log</translation>
+        <translation>Cambia la opción de visibilidad de las opciones del registro.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="872"/>
@@ -310,7 +324,7 @@ This check involves sending anonymous information about your platform and versio
     <message>
         <location filename="../mainwindow.cpp" line="874"/>
         <source>Toggle visibility of the buffer selection tabs.</source>
-        <translation>Cambia la visibilidad de los tabs de selección de buffer</translation>
+        <translation>Cambia la visibilidad de los tabs de selección de buffer.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="875"/>
@@ -320,7 +334,7 @@ This check involves sending anonymous information about your platform and versio
     <message>
         <location filename="../mainwindow.cpp" line="876"/>
         <source>Toggle full screen mode.</source>
-        <translation>Cambia la opción de pantalla completa</translation>
+        <translation>Cambia la opción de pantalla completa.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="877"/>
@@ -330,13 +344,14 @@ This check involves sending anonymous information about your platform and versio
     <message>
         <location filename="../mainwindow.cpp" line="878"/>
         <source>Toggle dark mode.</source>
-        <translation>Cambia opción de modo dark</translation>
+        <translation>Cambia opción de modo dark.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="878"/>
         <source>
 Dark mode is perfect for live coding in night clubs.</source>
-        <translation>La opción Dark es perfecta para hacer live coding en discotecas o lugares con poca luminosidad</translation>
+        <translation>
+La opción Dark es perfecta para hacer live coding en discotecas o lugares con poca luminosidad.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="917"/>
@@ -381,7 +396,7 @@ Dark mode is perfect for live coding in night clubs.</source>
     <message>
         <location filename="../mainwindow.cpp" line="1207"/>
         <source>Workspace %1</source>
-        <translation>Workspace %1</translation>
+        <translation>Directorio de trabajo %1</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1223"/>
@@ -727,7 +742,7 @@ Get Sonic Pi %1</source>
     <name>SonicPiUDPServer</name>
     <message>
         <location filename="../sonicpiudpserver.cpp" line="24"/>
-        <source>Is Sonic Pi already running?  Can't open UDP port 4558.</source>
+        <source>Is Sonic Pi already running?  Can't open UDP port 4558.</source>
         <translation>Se encuentra corriendo otra instancia de Sonic Pi?, no se puede abrir el puerto UDP 4558.</translation>
     </message>
 </context>
diff --git a/app/gui/qt/lang/sonic-pi_fr.ts b/app/gui/qt/lang/sonic-pi_fr.ts
index 22236eb..38b4a4f 100644
--- a/app/gui/qt/lang/sonic-pi_fr.ts
+++ b/app/gui/qt/lang/sonic-pi_fr.ts
@@ -1,133 +1,144 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
-<TS version="2.0" language="fr_FR">
-<defaultcodec>UTF-8</defaultcodec>
+<TS version="2.1" language="fr_FR">
 <context>
     <name>MainWindow</name>
     <message>
-        <location filename="../mainwindow.cpp" line="152"/>
+        <location filename="../mainwindow.cpp" line="262"/>
         <source>Sonic Pi update info</source>
         <translation>Info de mise à jour de Sonic Pi</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="295"/>
+        <location filename="../mainwindow.cpp" line="366"/>
         <source>Buffer %1</source>
         <translation>Buffer %1</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="359"/>
+        <location filename="../mainwindow.cpp" line="430"/>
         <source>Preferences</source>
         <translation>Préférences</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="372"/>
+        <location filename="../mainwindow.cpp" line="443"/>
         <source>Log</source>
         <translation>Trace</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="413"/>
-        <location filename="../mainwindow.cpp" line="1919"/>
+        <location filename="../mainwindow.cpp" line="484"/>
+        <location filename="../mainwindow.cpp" line="2023"/>
         <source>Help</source>
         <translation>Aide</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="444"/>
-        <location filename="../mainwindow.cpp" line="2151"/>
-        <location filename="../mainwindow.cpp" line="2169"/>
+        <location filename="../mainwindow.cpp" line="167"/>
+        <location filename="../mainwindow.cpp" line="2258"/>
+        <location filename="../mainwindow.cpp" line="2276"/>
         <source>Sonic Pi</source>
         <translation>Sonic Pi</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="458"/>
+        <location filename="../mainwindow.cpp" line="220"/>
         <source>Welcome to Sonic Pi</source>
         <translation>Bienvenue à Sonic Pi</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="600"/>
+        <location filename="../mainwindow.cpp" line="636"/>
         <source>Indenting selection...</source>
         <translation>Indentation de la sélection...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="604"/>
+        <location filename="../mainwindow.cpp" line="640"/>
         <source>Indenting line...</source>
         <translation>Indentation de la ligne...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="633"/>
         <source>Commenting selection...</source>
-        <translation>Commentant la sélection...</translation>
+        <translation type="vanished">Commentant la sélection...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="637"/>
         <source>Commenting line...</source>
-        <translation>Commentant la ligne...</translation>
+        <translation type="vanished">Commentant la ligne...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="716"/>
         <source>Ruby could not be started, is it installed and in your PATH?</source>
-        <translation>Ruby ne peut être lancé, est-il installé et dans votre PATH ?</translation>
+        <translation type="vanished">Ruby ne peut être lancé, est-il installé et dans votre PATH ?</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="669"/>
+        <source>Toggle selection comment...</source>
+        <translation>Commenter/Décommenter la sélection ...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="673"/>
+        <source>Toggle line comment...</source>
+        <translation>Commenter/Décommenter la ligne ...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="802"/>
+        <location filename="../mainwindow.cpp" line="747"/>
+        <source>The Sonic Pi server could not be started!</source>
+        <translation>Le serveur Sonic Pi n'a pas pu être lancé !</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="849"/>
         <source>Raspberry Pi System Volume</source>
         <translation>Volume du son du Raspberry Pi</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="803"/>
+        <location filename="../mainwindow.cpp" line="850"/>
         <source>Use this slider to change the system volume of your Raspberry Pi.</source>
-        <translation>Utilisez ce curseur pour changer le volume du son de votre Raspberry Pi</translation>
+        <translation>Utilisez ce curseur pour changer le volume du son de votre Raspberry Pi.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="805"/>
+        <location filename="../mainwindow.cpp" line="852"/>
         <source>Advanced Audio</source>
         <translation>Audio avancé</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="806"/>
+        <location filename="../mainwindow.cpp" line="853"/>
         <source>Advanced audio settings for working with
 external PA systems when performing with Sonic Pi.</source>
-        <translation>Paramètres audio avancés pour l'utilisation
-d'un amplificateur externe avec Sonic Pi</translation>
+        <translation>Paramètres audio avancés pour l'utilisation
+d'un amplificateur externe avec Sonic Pi.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="807"/>
+        <location filename="../mainwindow.cpp" line="854"/>
         <source>Invert Stereo</source>
         <translation>Stéréo inversée</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="808"/>
+        <location filename="../mainwindow.cpp" line="855"/>
         <source>Toggle stereo inversion.
 If enabled, audio sent to the left speaker will
 be routed to the right speaker and visa versa.</source>
         <translation>Bascule en stéréo inversée.
 Si activée, le son destiné au haut-parleur de gauche sera
-dirigé vers le haut-parleur de droite et vice et versa</translation>
+dirigé vers le haut-parleur de droite et vice et versa.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="810"/>
+        <location filename="../mainwindow.cpp" line="857"/>
         <source>Force Mono</source>
         <translation>Mono forcé</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="811"/>
+        <location filename="../mainwindow.cpp" line="858"/>
         <source>Toggle mono mode.
 If enabled both right and left audio is mixed and
 the same signal is sent to both speakers.
 Useful when working with external systems that
 can only handle mono.</source>
         <translation>Bascule en mode mono.
-Si activée, l'audio de gauche est mélangé avec celui de droite
+Si activée, l'audio de gauche est mélangé avec celui de droite
 et le même signal est dirigé vers les deux haut-parleurs. 
 Utile quand on travaille avec des systèmes externes qui 
 ne supportent que le mono.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="814"/>
+        <location filename="../mainwindow.cpp" line="861"/>
         <source>Safe mode</source>
         <translation>Mode sécurisé</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="815"/>
+        <location filename="../mainwindow.cpp" line="862"/>
         <source>Toggle synth argument checking functions.
 If disabled, certain synth opt values may
 create unexpectedly loud or uncomfortable sounds.</source>
@@ -136,81 +147,81 @@ Si désactivée, certaines valeurs des options de synth peuvent
 engendrer des sons forts ou inconfortables de manière imprévue.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="827"/>
+        <location filename="../mainwindow.cpp" line="874"/>
         <source>Raspberry Pi Audio Output</source>
         <translation>Sortie audio du Raspberry Pi</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="828"/>
+        <location filename="../mainwindow.cpp" line="875"/>
         <source>Your Raspberry Pi has two forms of audio output.
 Firstly, there is the headphone jack of the Raspberry Pi itself.
 Secondly, some HDMI monitors/TVs support audio through the HDMI port.
 Use these buttons to force the output to the one you want.</source>
         <translation>Votre Raspberry Pi a deux sorties audio.
 Premièrement, il y a la prise jack pour écouteurs du Raspberry PI lui-même.
-Deuxièmement, des moniteurs ou TV supportent l'audio via la prise HDMI.
+Deuxièmement, des moniteurs ou TV supportent l'audio via la prise HDMI.
 Utilisez ces boutons pour forcer la sortie vers ce que vous souhaitez.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="829"/>
+        <location filename="../mainwindow.cpp" line="876"/>
         <source>&Default</source>
         <translation>&Défaut</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="830"/>
+        <location filename="../mainwindow.cpp" line="877"/>
         <source>&Headphones</source>
         <translation>&Écouteurs</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="831"/>
+        <location filename="../mainwindow.cpp" line="878"/>
         <source>&HDMI</source>
         <translation>&HDMI</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="851"/>
+        <location filename="../mainwindow.cpp" line="898"/>
         <source>Logging</source>
         <translation>Trace</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="852"/>
+        <location filename="../mainwindow.cpp" line="899"/>
         <source>Configure debug behaviour</source>
         <translation>Configuration du comportement de débogage</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="854"/>
+        <location filename="../mainwindow.cpp" line="901"/>
         <source>Log synths</source>
         <translation>Trace les synthés</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="855"/>
+        <location filename="../mainwindow.cpp" line="902"/>
         <source>Toggle log messages.
 If disabled, activity such as synth and sample
 triggering will not be printed to the log by default.</source>
         <translation>Bascule des messages de trace.
-Si désactivée, l'activité telle que le jeu des synthés et des échantillons 
+Si désactivée, l'activité telle que le jeu des synthés et des échantillons 
 ne sera pas affichée dans la trace par défaut.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="857"/>
+        <location filename="../mainwindow.cpp" line="904"/>
         <source>Clear log on run</source>
         <translation>Efface la trace avant exécution</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="858"/>
+        <location filename="../mainwindow.cpp" line="905"/>
         <source>Toggle log clearing on run.
 If enabled, the log is cleared each
 time the run button is pressed.</source>
-        <translation>Bascule de l'effacement de la trace avant exécution.
+        <translation>Bascule de l'effacement de la trace avant exécution.
 Si activé, la trace est effacée à chaque appui 
 sur le bouton run.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="860"/>
+        <location filename="../mainwindow.cpp" line="907"/>
         <source>Log cues</source>
         <translation>Trace des cues</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="861"/>
+        <location filename="../mainwindow.cpp" line="908"/>
         <source>Enable or disable logging of cues.
 If disabled, cues will still trigger.
 However, they will not be visible in the logs.</source>
@@ -219,554 +230,591 @@ Si désactivée, les cues continueront à être émis.
 Toutefois, ils ne seront pas visibles dans la trace.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="870"/>
+        <location filename="../mainwindow.cpp" line="917"/>
         <source>Transparency</source>
         <translation>Transparence</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="881"/>
-        <location filename="../mainwindow.cpp" line="1003"/>
+        <location filename="../mainwindow.cpp" line="928"/>
+        <location filename="../mainwindow.cpp" line="1060"/>
         <source>Updates</source>
         <translation>Mises à jour</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="883"/>
+        <location filename="../mainwindow.cpp" line="930"/>
         <source>Check for updates</source>
         <translation>Vérification des mises à jour</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="885"/>
+        <location filename="../mainwindow.cpp" line="932"/>
         <source>Toggle automatic update checking.
 This check involves sending anonymous information about your platform and version.</source>
-        <translation>Bascule de la vérification automatique des mises à jour.
-Cette vérification implique l'envoi d'informations anonymes 
-sur votre plateforme et votre version</translation>
+        <translation>Activer/Désactiver la vérification automatique des mises à jour.
+Cette vérification implique l'envoi d'informations anonymes sur votre plateforme et votre version.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="886"/>
+        <location filename="../mainwindow.cpp" line="933"/>
         <source>Check now</source>
         <translation>Vérification sur le champ</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="887"/>
+        <location filename="../mainwindow.cpp" line="934"/>
         <source>Force a check for updates now.
 This check involves sending anonymous information about your platform and version.</source>
-        <translation>Force une vérification des mises à jour sur le champ.
-Cette vérification implique l'envoi d'informations anonymes 
-sur votre plateforme et votre version</translation>
+        <translation>Force une vérification des mises à jour.
+Cette vérification implique l'envoi d'informations anonymes à propos de votre plateforme et de votre version.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="888"/>
+        <location filename="../mainwindow.cpp" line="935"/>
         <source>Get update</source>
-        <translation>Obtention d'une mise à jour</translation>
+        <translation>Obtention d'une mise à jour</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="889"/>
+        <location filename="../mainwindow.cpp" line="936"/>
         <source>Visit http://sonic-pi.net to download new version</source>
         <translation>Visitez http://sonic-pi.net pour télécharger une nouvelle version</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="894"/>
+        <location filename="../mainwindow.cpp" line="941"/>
         <source>Update Info</source>
         <translation>Information de mise à jour</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="913"/>
+        <location filename="../mainwindow.cpp" line="960"/>
         <source>Show and Hide</source>
         <translation>Montre et cache</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="914"/>
+        <location filename="../mainwindow.cpp" line="961"/>
         <source>Configure editor display options.</source>
-        <translation>Configuration des options d'affichage de l'éditeur</translation>
+        <translation>Configuration des options d'affichage de l'éditeur.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="915"/>
+        <location filename="../mainwindow.cpp" line="962"/>
         <source>Look and Feel</source>
         <translation>Look and Feel</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="916"/>
+        <location filename="../mainwindow.cpp" line="963"/>
         <source>Configure editor look and feel.</source>
-        <translation>Configuration du look and feel de l'éditeur</translation>
+        <translation>Configuration du look and feel de l'éditeur.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="917"/>
+        <location filename="../mainwindow.cpp" line="964"/>
         <source>Automation</source>
         <translation>Automatisation</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="918"/>
+        <location filename="../mainwindow.cpp" line="965"/>
         <source>Configure automation features.</source>
-        <translation>Configuration des caractéristiques de l'automatisation</translation>
+        <translation>Configurer les fonctionnalités d'automatisation.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="919"/>
+        <location filename="../mainwindow.cpp" line="966"/>
         <source>Auto-align</source>
         <translation>Alignement automatique</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="920"/>
+        <location filename="../mainwindow.cpp" line="967"/>
         <source>Automatically align code on Run</source>
-        <translation>Alignement automatique du code à l'exécution</translation>
+        <translation>Alignement automatique du code à l'exécution</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="922"/>
+        <location filename="../mainwindow.cpp" line="969"/>
         <source>Show line numbers</source>
         <translation>Affichage des numéros de ligne</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="923"/>
+        <location filename="../mainwindow.cpp" line="970"/>
         <source>Toggle line number visibility.</source>
-        <translation>Bascule de la visibilité des numéros de ligne</translation>
+        <translation>Activer/désactiver la visibilité des numéros de ligne.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="924"/>
+        <location filename="../mainwindow.cpp" line="971"/>
         <source>Show log</source>
         <translation>Affichage de la trace</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="925"/>
+        <location filename="../mainwindow.cpp" line="972"/>
         <source>Toggle visibility of the log.</source>
-        <translation>Bascule de la visibilité de la trace</translation>
+        <translation>Activer/désactiver la visibilité du journal.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="927"/>
+        <location filename="../mainwindow.cpp" line="974"/>
         <source>Show buttons</source>
         <translation>Affichage des boutons</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="928"/>
+        <location filename="../mainwindow.cpp" line="975"/>
         <source>Toggle visibility of the control buttons.</source>
-        <translation>Bascule de la visibilité des boutons de contrôle</translation>
+        <translation>Activer/désactiver la visibilité des boutons de contrôle.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="930"/>
+        <location filename="../mainwindow.cpp" line="977"/>
         <source>Show tabs</source>
         <translation>Affichage des onglets</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="932"/>
+        <location filename="../mainwindow.cpp" line="979"/>
         <source>Toggle visibility of the buffer selection tabs.</source>
-        <translation>Bascule de l'affichage des onglets de sélection des buffers</translation>
+        <translation>Activer/désactiver l'affichage des onglets de sélection des buffers.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="933"/>
+        <location filename="../mainwindow.cpp" line="980"/>
         <source>Full screen</source>
         <translation>Plein écran</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="934"/>
+        <location filename="../mainwindow.cpp" line="981"/>
         <source>Toggle full screen mode.</source>
-        <translation>Bascule du mode plein écran</translation>
+        <translation>Activer/désactiver le mode plein écran.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="935"/>
+        <location filename="../mainwindow.cpp" line="982"/>
         <source>Dark mode</source>
         <translation>Mode sombre</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="936"/>
+        <location filename="../mainwindow.cpp" line="983"/>
         <source>Toggle dark mode.</source>
-        <translation>Bascule du mode sombre</translation>
+        <translation>Activer/désactiver le mode sombre.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="983"/>
+        <source>
+Dark mode is perfect for live coding in night clubs.</source>
+        <translation>Le thème foncé est parfait pour coder en boîte de nuit.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1243"/>
+        <source>Load Sonic-Pi file</source>
+        <translation>Charger un fichier Sonic Pi</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2001"/>
+        <source>Run the code in the current buffer</source>
+        <translation>Exécuter le code du buffer courant</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="936"/>
         <source>Dark mode is perfect for live coding in night clubs.</source>
-        <translation>Le mode sombre est parfait pour le codage en live dans les boîtes de nuit</translation>
+        <translation type="vanished">Le mode sombre est parfait pour le codage en live dans les boites de nuit.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="975"/>
+        <location filename="../mainwindow.cpp" line="1022"/>
         <source>Audio</source>
         <translation>Audio</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="987"/>
+        <location filename="../mainwindow.cpp" line="1034"/>
         <source>Editor</source>
         <translation>Éditeur</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="988"/>
+        <location filename="../mainwindow.cpp" line="1035"/>
         <source>Studio</source>
         <translation>Studio</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="990"/>
-        <location filename="../mainwindow.cpp" line="995"/>
+        <location filename="../mainwindow.cpp" line="1037"/>
+        <location filename="../mainwindow.cpp" line="1047"/>
         <source>Performance</source>
         <translation>Interprétation</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="991"/>
+        <location filename="../mainwindow.cpp" line="1038"/>
         <source>Settings useful for performing with Sonic Pi</source>
-        <translation>Paramètres utiles pour l'interprétation avec Sonic Pi</translation>
+        <translation>Paramètres utiles pour l'interprétation avec Sonic Pi</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1086"/>
+        <location filename="../mainwindow.cpp" line="1148"/>
         <source>Server boot error...</source>
         <translation>Erreur du lanceur du serveur...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1086"/>
         <source>Apologies, a critical error occurred during startup</source>
-        <translation>Veuillez nous excuser, une erreur critique s'est produite
-pendant le démarrage.</translation>
+        <translation type="vanished">Veuillez nous excuser, une erreur critique s'est produite pendant le démarrage</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1086"/>
+        <location filename="../mainwindow.cpp" line="1148"/>
         <source>Please consider reporting a bug at</source>
-        <translation>Envisagez SVP la signalisation d'un bogue à</translation>
+        <translation>Envisagez SVP la signalisation d'un bogue à</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1148"/>
+        <source>Sonic Pi Boot Error
+
+Apologies, a critical error occurred during startup</source>
+        <translation>Erreur de démarrage de Sonic Pi
+
+Veuillez nous excuser, une erreur critique s'est produite pendant le démarrage</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1180"/>
+        <location filename="../mainwindow.cpp" line="1255"/>
         <source>Save Current Buffer</source>
         <translation>Sauvegarde du buffer courant</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1248"/>
+        <location filename="../mainwindow.cpp" line="1255"/>
+        <source>Ruby (*.rb)</source>
+        <translation></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1326"/>
         <source>Running Code...</source>
         <translation>Exécution du code...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1274"/>
         <source>Workspace %1</source>
-        <translation>Buffer %1</translation>
+        <translation type="vanished">Buffer %1</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1290"/>
+        <location filename="../mainwindow.cpp" line="1368"/>
         <source>Zooming In...</source>
         <translation>Zoom arrière...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1297"/>
+        <location filename="../mainwindow.cpp" line="1375"/>
         <source>Zooming Out...</source>
         <translation>Zoom avant...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1304"/>
+        <location filename="../mainwindow.cpp" line="1382"/>
         <source>Beautifying...</source>
         <translation>Embellissement...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1324"/>
+        <location filename="../mainwindow.cpp" line="1402"/>
         <source>Reloading...</source>
         <translation>Rechargement...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1331"/>
+        <location filename="../mainwindow.cpp" line="1409"/>
         <source>Checking for updates...</source>
         <translation>Vérification des mises à jour...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1339"/>
+        <location filename="../mainwindow.cpp" line="1417"/>
         <source>Enabling update checking...</source>
         <translation>Activation de la vérification des mises à jour...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1347"/>
+        <location filename="../mainwindow.cpp" line="1425"/>
         <source>Disabling update checking...</source>
         <translation>Désactivation de la vérification des mises à jour...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1355"/>
+        <location filename="../mainwindow.cpp" line="1433"/>
         <source>Enabling Mixer HPF...</source>
         <translation>Activation du filtre passe-haut...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1364"/>
+        <location filename="../mainwindow.cpp" line="1442"/>
         <source>Disabling Mixer HPF...</source>
         <translation>Désactivation du filtre passe-haut...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1372"/>
+        <location filename="../mainwindow.cpp" line="1450"/>
         <source>Enabling Mixer LPF...</source>
         <translation>Activation du filtre passe-bas...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1381"/>
+        <location filename="../mainwindow.cpp" line="1459"/>
         <source>Disabling Mixer LPF...</source>
         <translation>Désactivation du filtre passe-bas...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1389"/>
+        <location filename="../mainwindow.cpp" line="1467"/>
         <source>Enabling Inverted Stereo...</source>
-        <translation>Activation de l'inversion stéréo...</translation>
+        <translation>Activation de l'inversion stéréo...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1397"/>
+        <location filename="../mainwindow.cpp" line="1475"/>
         <source>Enabling Standard Stereo...</source>
         <translation>Activation de la stéréo standard...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1405"/>
+        <location filename="../mainwindow.cpp" line="1483"/>
         <source>Mono Mode...</source>
         <translation>Mode mono...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1413"/>
+        <location filename="../mainwindow.cpp" line="1491"/>
         <source>Stereo Mode...</source>
         <translation>Mode stéréo...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1422"/>
+        <location filename="../mainwindow.cpp" line="1500"/>
         <source>Stopping...</source>
         <translation>Arrêt...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1506"/>
+        <location filename="../mainwindow.cpp" line="1596"/>
         <source>Updating System Volume...</source>
-        <translation>Changement du volume du son du système</translation>
+        <translation>Mise à jour du volume système...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1728"/>
+        <location filename="../mainwindow.cpp" line="1818"/>
         <source>Switching To Headphone Audio Output...</source>
         <translation>Aiguillage vers la sortie écouteurs...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1744"/>
+        <location filename="../mainwindow.cpp" line="1834"/>
         <source>Switching To HDMI Audio Output...</source>
         <translation>Aiguillage vers la sortie HDMI...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1759"/>
+        <location filename="../mainwindow.cpp" line="1849"/>
         <source>Switching To Default Audio Output...</source>
         <translation>Aiguillage vers la sortie par défaut...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1901"/>
+        <location filename="../mainwindow.cpp" line="2000"/>
         <source>Run</source>
-        <translation>Run</translation>
+        <translation>Lancer</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1902"/>
         <source>Run the code in the current workspace</source>
-        <translation>Exécute le code dans le buffer courant</translation>
+        <translation type="vanished">Exécute le code dans le buffer courant</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1906"/>
+        <location filename="../mainwindow.cpp" line="2006"/>
         <source>Stop</source>
         <translation>Stop</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1907"/>
+        <location filename="../mainwindow.cpp" line="2007"/>
         <source>Stop all running code</source>
-        <translation>Arrête l'exécution de tous les codes</translation>
+        <translation>Arrête l'exécution de tous les codes</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1910"/>
+        <location filename="../mainwindow.cpp" line="2010"/>
         <source>Save As...</source>
         <translation>Enregistrer sous...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1911"/>
+        <location filename="../mainwindow.cpp" line="2011"/>
         <source>Save current buffer as an external file</source>
         <translation>Enregistre le buffer courant dans un fichier externe</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1914"/>
+        <location filename="../mainwindow.cpp" line="2014"/>
+        <source>Load</source>
+        <translation>Charger</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2015"/>
+        <source>Load an external file in the current buffer</source>
+        <translation>Charger un fichier externe dans le buffer courant</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2018"/>
         <source>Info</source>
         <translation>Info</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1915"/>
+        <location filename="../mainwindow.cpp" line="2019"/>
         <source>See information about Sonic Pi</source>
-        <translation>Voir l'information sur Sonic Pi</translation>
+        <translation>Voir l'information sur Sonic Pi</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1920"/>
+        <location filename="../mainwindow.cpp" line="2024"/>
         <source>Toggle help pane</source>
-        <translation>Bascule de l'affichage du panneau d'aide</translation>
+        <translation>Bascule de l'affichage du panneau d'aide</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1923"/>
+        <location filename="../mainwindow.cpp" line="2027"/>
         <source>Prefs</source>
         <translation>Prefs</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1924"/>
+        <location filename="../mainwindow.cpp" line="2028"/>
         <source>Toggle preferences pane</source>
-        <translation>Bascule de l'affichage du panneau des préférences</translation>
+        <translation>Bascule de l'affichage du panneau des préférences</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1928"/>
-        <location filename="../mainwindow.cpp" line="2050"/>
-        <location filename="../mainwindow.cpp" line="2051"/>
+        <location filename="../mainwindow.cpp" line="2032"/>
+        <location filename="../mainwindow.cpp" line="2158"/>
+        <location filename="../mainwindow.cpp" line="2159"/>
         <source>Start Recording</source>
-        <translation>Démarrage de l'enregistrement</translation>
+        <translation>Démarrage de l'enregistrement</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1929"/>
+        <location filename="../mainwindow.cpp" line="2033"/>
         <source>Start recording to WAV audio file</source>
-        <translation>Démarre l'enregistrement vers un fichier audio WAV</translation>
+        <translation>Démarre l'enregistrement vers un fichier audio WAV</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1933"/>
+        <location filename="../mainwindow.cpp" line="2037"/>
         <source>Auto-Align Text</source>
         <translation>Alignement automatique du texte</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1934"/>
+        <location filename="../mainwindow.cpp" line="2038"/>
         <source>Improve readability of code</source>
-        <translation>Amélioration de la lisibilité du code</translation>
+        <translation>Améliore de la lisibilité du code</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1938"/>
-        <location filename="../mainwindow.cpp" line="1939"/>
+        <location filename="../mainwindow.cpp" line="2044"/>
         <source>Increase Text Size</source>
         <translation>Augmente la taille du texte</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1943"/>
-        <location filename="../mainwindow.cpp" line="1944"/>
+        <location filename="../mainwindow.cpp" line="2051"/>
         <source>Decrease Text Size</source>
         <translation>Diminue la taille du texte</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1949"/>
+        <location filename="../mainwindow.cpp" line="2056"/>
         <source>Tools</source>
         <translation>Outils</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1996"/>
+        <location filename="../mainwindow.cpp" line="2104"/>
         <source>About</source>
         <translation>A propos</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1997"/>
+        <location filename="../mainwindow.cpp" line="2105"/>
         <source>Core Team</source>
         <translation>Équipe principale</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1998"/>
+        <location filename="../mainwindow.cpp" line="2106"/>
         <source>Contributors</source>
         <translation>Contributeurs</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="1999"/>
+        <location filename="../mainwindow.cpp" line="2107"/>
         <source>Community</source>
         <translation>Communauté</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2000"/>
+        <location filename="../mainwindow.cpp" line="2108"/>
         <source>License</source>
-        <translation>License</translation>
+        <translation>Licence</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2001"/>
+        <location filename="../mainwindow.cpp" line="2109"/>
         <source>History</source>
         <translation>Historique</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2022"/>
+        <location filename="../mainwindow.cpp" line="2130"/>
         <source>Sonic Pi - Info</source>
         <translation>Sonic Pi - Info</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2042"/>
-        <location filename="../mainwindow.cpp" line="2043"/>
+        <location filename="../mainwindow.cpp" line="2150"/>
+        <location filename="../mainwindow.cpp" line="2151"/>
         <source>Stop Recording</source>
-        <translation>Arrête l'enregistrement</translation>
+        <translation>Arrêter l'enregistrement</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2056"/>
+        <location filename="../mainwindow.cpp" line="2164"/>
         <source>Save Recording</source>
-        <translation>Sauvegarde de l'enregistrement</translation>
+        <translation>Sauvegarde de l'enregistrement</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2164"/>
+        <source>Wavefile (*.wav)</source>
+        <translation></translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2075"/>
+        <location filename="../mainwindow.cpp" line="2183"/>
         <source>Ready...</source>
         <translation>Prêt...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2152"/>
+        <location filename="../mainwindow.cpp" line="2259"/>
         <source>Cannot read file %1:
 %2.</source>
         <translation>Lecture impossible du fichier %1:
 %2.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2162"/>
+        <location filename="../mainwindow.cpp" line="2269"/>
         <source>File loaded...</source>
         <translation>Fichier chargé...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2170"/>
+        <location filename="../mainwindow.cpp" line="2277"/>
         <source>Cannot write file %1:
 %2.</source>
         <translation>Écriture impossible du fichier %1:
 %2.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2187"/>
+        <location filename="../mainwindow.cpp" line="2294"/>
         <source>File saved...</source>
         <translation>Fichier enregistré...</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2412"/>
+        <location filename="../mainwindow.cpp" line="2520"/>
         <source>Last checked %1</source>
         <translation>%1 vérifié en dernier</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2414"/>
+        <location filename="../mainwindow.cpp" line="2522"/>
         <source>Sonic Pi checks for updates
 every two weeks.</source>
         <translation>Sonic Pi vérifie les mises à jour
 toutes les deux semaines.</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2416"/>
+        <location filename="../mainwindow.cpp" line="2524"/>
         <source>This is Sonic Pi %1</source>
-        <translation>C'est Sonic Pi %1</translation>
+        <translation>C'est Sonic Pi %1</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2417"/>
+        <location filename="../mainwindow.cpp" line="2525"/>
         <source>Version %2 is now available!</source>
         <translation>La version %2 est maintenant disponible !</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2421"/>
+        <location filename="../mainwindow.cpp" line="2529"/>
         <source>New version available!
 Get Sonic Pi %1</source>
         <translation>Nouvelle version disponible !
 Obtenez Sonic Pi %1</translation>
     </message>
     <message>
-        <location filename="../mainwindow.cpp" line="2447"/>
+        <location filename="../mainwindow.cpp" line="2553"/>
         <source>Welcome back. Now get your live code on...</source>
-        <translation>Retour bienvenu. Obtenez maintenant votre code sur...</translation>
+        <translation>Bon retour. Obtenez maintenant votre code sur...</translation>
     </message>
     <message>
-        <location filename="../ruby_help.h" line="80"/>
-        <location filename="../ruby_help.h" line="139"/>
-        <location filename="../ruby_help.h" line="199"/>
-        <location filename="../ruby_help.h" line="218"/>
-        <location filename="../ruby_help.h" line="278"/>
-        <location filename="../ruby_help.h" line="338"/>
+        <location filename="../ruby_help.h" line="79"/>
+        <location filename="../ruby_help.h" line="140"/>
+        <location filename="../ruby_help.h" line="200"/>
+        <location filename="../ruby_help.h" line="260"/>
+        <location filename="../ruby_help.h" line="279"/>
+        <location filename="../ruby_help.h" line="339"/>
+        <location filename="../ruby_help.h" line="409"/>
         <source>Tutorial</source>
         <translation>Tutoriel</translation>
     </message>
     <message>
-        <location filename="../ruby_help.h" line="370"/>
+        <location filename="../ruby_help.h" line="443"/>
         <source>Examples</source>
         <translation>Exemples</translation>
     </message>
     <message>
-        <location filename="../ruby_help.h" line="410"/>
+        <location filename="../ruby_help.h" line="489"/>
         <source>Synths</source>
         <translation>Synths</translation>
     </message>
     <message>
-        <location filename="../ruby_help.h" line="446"/>
+        <location filename="../ruby_help.h" line="530"/>
         <source>Fx</source>
         <translation>Fx</translation>
     </message>
     <message>
-        <location filename="../ruby_help.h" line="463"/>
+        <location filename="../ruby_help.h" line="547"/>
         <source>Samples</source>
         <translation>Échantillons</translation>
     </message>
     <message>
-        <location filename="../ruby_help.h" line="629"/>
+        <location filename="../ruby_help.h" line="735"/>
         <source>Lang</source>
         <translation>Langage</translation>
     </message>
@@ -780,11 +828,18 @@ Obtenez Sonic Pi %1</translation>
     </message>
 </context>
 <context>
+    <name>SonicPiUDPOSCServer</name>
+    <message>
+        <location filename="../sonic_pi_udp_osc_server.cpp" line="24"/>
+        <source>Is Sonic Pi already running?  Can't open UDP port 4558.</source>
+        <translation>Y a-t-il une autre instance de Sonic Pi toujours en cours d'exécution ? Ouverture du port UDP 4558 impossible.</translation>
+    </message>
+</context>
+<context>
     <name>SonicPiUDPServer</name>
     <message>
-        <location filename="../sonicpiudpserver.cpp" line="24"/>
         <source>Is Sonic Pi already running?  Can't open UDP port 4558.</source>
-        <translation>Sonic Pi toujours en cours d'exécution ? Ouverture du port UDP 4558 impossible</translation>
+        <translation type="vanished">Sonic Pi est-il déjà en cours d'exécution ? Impossible d'ouvrir le port UDP 4558.</translation>
     </message>
 </context>
 </TS>
diff --git a/app/gui/qt/lang/sonic-pi_nb.ts b/app/gui/qt/lang/sonic-pi_nb.ts
index 8354c4d..d8771ba 100644
--- a/app/gui/qt/lang/sonic-pi_nb.ts
+++ b/app/gui/qt/lang/sonic-pi_nb.ts
@@ -17,12 +17,12 @@
     <message>
         <location filename="../mainwindow.cpp" line="360"/>
         <source>Preferences</source>
-        <translation type="unfinished">Oppsett</translation>
+        <translation>Innstillinger</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="373"/>
         <source>Log</source>
-        <translation type="unfinished">Logg</translation>
+        <translation>Logg</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="414"/>
@@ -35,12 +35,12 @@
         <location filename="../mainwindow.cpp" line="2152"/>
         <location filename="../mainwindow.cpp" line="2170"/>
         <source>Sonic Pi</source>
-        <translation type="unfinished">Sonic Pi</translation>
+        <translation>Sonic Pi</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="459"/>
         <source>Welcome to Sonic Pi</source>
-        <translation type="unfinished">Velkommen til Sonic Pi</translation>
+        <translation>Velkommen til Sonic Pi</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="601"/>
@@ -50,7 +50,7 @@
     <message>
         <location filename="../mainwindow.cpp" line="605"/>
         <source>Indenting line...</source>
-        <translation type="unfinished">Rykk inn linje...</translation>
+        <translation type="unfinished">Rykker inn linje...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="634"/>
@@ -65,7 +65,7 @@
     <message>
         <location filename="../mainwindow.cpp" line="717"/>
         <source>Ruby could not be started, is it installed and in your PATH?</source>
-        <translation type="unfinished">Kunne ikke starte rubu.  Er den installert og i din PATH?</translation>
+        <translation>Kunne ikke starte ruby.  Er den installert og i din PATH?</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="803"/>
@@ -86,21 +86,22 @@
         <location filename="../mainwindow.cpp" line="807"/>
         <source>Advanced audio settings for working with
 external PA systems when performing with Sonic Pi.</source>
-        <translation type="unfinished">Avanserte lydoppsett for å bruke eksterne PA-systemer mens du spiller med Sonic Pi.</translation>
+        <translation>Avanserte lydoppsett for å bruke eksterne
+PA-systemer mens du spiller med Sonic Pi.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="808"/>
         <source>Invert Stereo</source>
-        <translation type="unfinished">Inverter stereo</translation>
+        <translation>Inverter stereo</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="809"/>
         <source>Toggle stereo inversion.
 If enabled, audio sent to the left speaker will
 be routed to the right speaker and visa versa.</source>
-        <translation type="unfinished">Styr stereo-invertering.
+        <translation>Styr stereo-invertering.
 Hvis aktiv, så blir lyd sendt til venstre høytaler
-istedet sendt til det høyre høytaleren og visa versa.</translation>
+i stedet overført til det høyre høytaleren og visa versa.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="811"/>
@@ -137,7 +138,7 @@ lage uventede høye eller ubehagelige lyder.</translation>
     <message>
         <location filename="../mainwindow.cpp" line="828"/>
         <source>Raspberry Pi Audio Output</source>
-        <translation type="unfinished">Lyduttak på Raspberry Pi</translation>
+        <translation>Lyduttak på Raspberry Pi</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="829"/>
@@ -158,7 +159,7 @@ Bruk disse knappene for å tvinge bruk av lydutgangen du ønsker.</translation>
     <message>
         <location filename="../mainwindow.cpp" line="831"/>
         <source>&Headphones</source>
-        <translation type="unfinished">&Hodetelefoner</translation>
+        <translation>&Hodetelefoner</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="832"/>
@@ -168,7 +169,7 @@ Bruk disse knappene for å tvinge bruk av lydutgangen du ønsker.</translation>
     <message>
         <location filename="../mainwindow.cpp" line="852"/>
         <source>Logging</source>
-        <translation type="unfinished">Logging</translation>
+        <translation>Logging</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="853"/>
@@ -178,7 +179,7 @@ Bruk disse knappene for å tvinge bruk av lydutgangen du ønsker.</translation>
     <message>
         <location filename="../mainwindow.cpp" line="855"/>
         <source>Log synths</source>
-        <translation type="unfinished">Logg synther</translation>
+        <translation>Logg synther</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="856"/>
@@ -192,83 +193,85 @@ sampleutløsning som utgangspunkt ikke skrives til loggen.</translation>
     <message>
         <location filename="../mainwindow.cpp" line="858"/>
         <source>Clear log on run</source>
-        <translation type="unfinished">Nullstill logg ved kjøring</translation>
+        <translation>Nullstill logg ved kjøring</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="859"/>
         <source>Toggle log clearing on run.
 If enabled, the log is cleared each
 time the run button is pressed.</source>
-        <translation type="unfinished">Styr logg-nullstilling ved kjøring.
+        <translation>Styr logg-nullstilling ved kjøring.
 Hvis aktiv, så nullstilles loggen hver
 gang kjør-knappen trykkes.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="861"/>
         <source>Log cues</source>
-        <translation type="unfinished"></translation>
+        <translation>Logg vink</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="862"/>
         <source>Enable or disable logging of cues.
 If disabled, cues will still trigger.
 However, they will not be visible in the logs.</source>
-        <translation type="unfinished"></translation>
+        <translation>Styr logging av vink.
+Hvis utkoblet, så vil vink fortsatt utløses.
+De vil dermot ikke være synlige i loggene.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="871"/>
         <source>Transparency</source>
-        <translation type="unfinished">Gjennomsiktighet</translation>
+        <translation>Gjennomsiktighet</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="882"/>
         <location filename="../mainwindow.cpp" line="1004"/>
         <source>Updates</source>
-        <translation type="unfinished">Oppdateringer</translation>
+        <translation>Oppdateringer</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="884"/>
         <source>Check for updates</source>
-        <translation type="unfinished">Sjekk etter oppdateringer</translation>
+        <translation>Sjekk etter oppdateringer</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="886"/>
         <source>Toggle automatic update checking.
 This check involves sending anonymous information about your platform and version.</source>
-        <translation type="unfinished">Styr automatisk oppdateringsjekk.
+        <translation>Styr automatisk oppdateringsjekk.
 Denne sjekken innebærer å sende anonym informasjon om din platform og versjon.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="887"/>
         <source>Check now</source>
-        <translation type="unfinished">Sjekk nå</translation>
+        <translation>Sjekk nå</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="888"/>
         <source>Force a check for updates now.
 This check involves sending anonymous information about your platform and version.</source>
-        <translation type="unfinished">Tving igjennom en sjekk etter oppdateringer nå.
+        <translation>Tving igjennom en sjekk etter oppdateringer nå.
 Denne sjekken innebærer å sende anonym informasjon om din platform og versjon.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="889"/>
         <source>Get update</source>
-        <translation type="unfinished">Hent oppdatering</translation>
+        <translation>Hent oppdatering</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="890"/>
         <source>Visit http://sonic-pi.net to download new version</source>
-        <translation type="unfinished">Besøk http://sonic-pi.net for å laste ned ny versjon</translation>
+        <translation>Besøk http://sonic-pi.net for å laste ned ny versjon</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="895"/>
         <source>Update Info</source>
-        <translation type="unfinished">Oppdateringsopplysninger</translation>
+        <translation>Oppdateringsopplysninger</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="914"/>
         <source>Show and Hide</source>
-        <translation type="unfinished">Vis og skjul</translation>
+        <translation>Vis og skjul</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="915"/>
@@ -278,62 +281,62 @@ Denne sjekken innebærer å sende anonym informasjon om din platform og versjon.
     <message>
         <location filename="../mainwindow.cpp" line="916"/>
         <source>Look and Feel</source>
-        <translation type="unfinished">Utseende og oppførsel</translation>
+        <translation>Utseende og oppførsel</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="917"/>
         <source>Configure editor look and feel.</source>
-        <translation type="unfinished">Still inn hvordan skriveprogrammet ser ut og oppfører seg.</translation>
+        <translation>Oppsett av utseende og oppførsel for skrivefeltet.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="918"/>
         <source>Automation</source>
-        <translation type="unfinished">Automatisering</translation>
+        <translation>Automatisering</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="919"/>
         <source>Configure automation features.</source>
-        <translation type="unfinished">Still inn automatiseringsegenskaper.</translation>
+        <translation>Sett opp automatiseringsegenskaper.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="920"/>
         <source>Auto-align</source>
-        <translation type="unfinished">Auto-innrykk</translation>
+        <translation>Auto-innrykk</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="921"/>
         <source>Automatically align code on Run</source>
-        <translation type="unfinished">Fiks innrykk automatisk ved kjøring</translation>
+        <translation>Fiks innrykk automatisk ved kjøring</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="923"/>
         <source>Show line numbers</source>
-        <translation type="unfinished">Vis linjenummer</translation>
+        <translation>Vis linjenummer</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="924"/>
         <source>Toggle line number visibility.</source>
-        <translation type="unfinished">Styr om linjenummer skal vises.</translation>
+        <translation>Styr synlighet for linjenummer.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="925"/>
         <source>Show log</source>
-        <translation type="unfinished">Vis logg</translation>
+        <translation>Vis logg</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="926"/>
         <source>Toggle visibility of the log.</source>
-        <translation type="unfinished">Styr synligheten for loggen.</translation>
+        <translation>Styr synligheten for loggen.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="928"/>
         <source>Show buttons</source>
-        <translation type="unfinished">Vis knapper</translation>
+        <translation>Vis knapper</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="929"/>
         <source>Toggle visibility of the control buttons.</source>
-        <translation type="unfinished">Styr synlighet for kontrollknappene.</translation>
+        <translation>Styr synlighet for kontrollknappene.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="931"/>
@@ -348,69 +351,70 @@ Denne sjekken innebærer å sende anonym informasjon om din platform og versjon.
     <message>
         <location filename="../mainwindow.cpp" line="934"/>
         <source>Full screen</source>
-        <translation type="unfinished">Fullskjerm</translation>
+        <translation>Fullskjerm</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="935"/>
         <source>Toggle full screen mode.</source>
-        <translation type="unfinished">Styr fullskjermtilstand.</translation>
+        <translation>Styr fullskjermtilstand.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="936"/>
         <source>Dark mode</source>
-        <translation type="unfinished">Mørk fremtoning</translation>
+        <translation>Mørk fremtoning</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="937"/>
         <source>Toggle dark mode.</source>
-        <translation type="unfinished">Styr mørk fremtoning.</translation>
+        <translation>Styr mørk fremtoning.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="937"/>
         <source>
 Dark mode is perfect for live coding in night clubs.</source>
-        <translation type="unfinished">Mørk fremtoning er perfekt for direkte-kodinger på nattklubber.</translation>
+        <translation>
+Mørk fremtoning er perfekt for koding på direkten i nattklubber.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="976"/>
         <source>Audio</source>
-        <translation type="unfinished">Lyd</translation>
+        <translation>Lyd</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="988"/>
         <source>Editor</source>
-        <translation type="unfinished">Skriveprogram</translation>
+        <translation>Skrivefelt</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="989"/>
         <source>Studio</source>
-        <translation type="unfinished">Studio</translation>
+        <translation>Studio</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="991"/>
         <location filename="../mainwindow.cpp" line="996"/>
         <source>Performance</source>
-        <translation type="unfinished">Fremvisning</translation>
+        <translation>Fremføring</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="992"/>
         <source>Settings useful for performing with Sonic Pi</source>
-        <translation type="unfinished">Oppsett nyttig for fremføring med Sonic Pi</translation>
+        <translation>Oppsett nyttig ved fremføring med Sonic Pi</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1087"/>
         <source>Server boot error...</source>
-        <translation type="unfinished">Tjeneroppstart-feil...</translation>
+        <translation>Feil ved tjeneroppstart...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1087"/>
         <source>Apologies, a critical error occurred during startup</source>
-        <translation type="unfinished">Beklager, en kritisk feil skjedde under oppstart</translation>
+        <translation>Beklager, en kritisk feil skjedde under oppstart</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1087"/>
         <source>Please consider reporting a bug at</source>
-        <translation type="unfinished">Veldig fint om du vurderer å rapportere feil til</translation>
+        <translation>Veldig fint om du vurderer å rapportere feil til</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1181"/>
@@ -420,12 +424,12 @@ Dark mode is perfect for live coding in night clubs.</source>
     <message>
         <location filename="../mainwindow.cpp" line="1249"/>
         <source>Running Code...</source>
-        <translation type="unfinished">Kjørende kode...</translation>
+        <translation>Kjørende kode...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1275"/>
         <source>Workspace %1</source>
-        <translation type="unfinished">Arbeidsområde %1</translation>
+        <translation>Arbeidsområde %1</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1291"/>
@@ -440,27 +444,27 @@ Dark mode is perfect for live coding in night clubs.</source>
     <message>
         <location filename="../mainwindow.cpp" line="1305"/>
         <source>Beautifying...</source>
-        <translation type="unfinished">Gjør vakrere...</translation>
+        <translation>Gjør vakrere...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1325"/>
         <source>Reloading...</source>
-        <translation type="unfinished">Last på nytt...</translation>
+        <translation>Laster på nytt...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1332"/>
         <source>Checking for updates...</source>
-        <translation type="unfinished">Ser etter oppdateringer...</translation>
+        <translation>Ser etter oppdateringer...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1340"/>
         <source>Enabling update checking...</source>
-        <translation type="unfinished">Aktiverer oppdaterings-sjekking...</translation>
+        <translation>Aktiverer oppdaterings-sjekking...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1348"/>
         <source>Disabling update checking...</source>
-        <translation type="unfinished">Kobler ut oppdaterings-sjekking...</translation>
+        <translation>Kobler ut oppdaterings-sjekking...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1356"/>
@@ -485,12 +489,12 @@ Dark mode is perfect for live coding in night clubs.</source>
     <message>
         <location filename="../mainwindow.cpp" line="1390"/>
         <source>Enabling Inverted Stereo...</source>
-        <translation type="unfinished">Aktiver invertert stereo...</translation>
+        <translation>Aktiver invertert stereo...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1398"/>
         <source>Enabling Standard Stereo...</source>
-        <translation type="unfinished">Aktiverer standard stereo...</translation>
+        <translation>Aktiverer standard stereo...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1406"/>
@@ -505,7 +509,7 @@ Dark mode is perfect for live coding in night clubs.</source>
     <message>
         <location filename="../mainwindow.cpp" line="1423"/>
         <source>Stopping...</source>
-        <translation type="unfinished">Stopper...</translation>
+        <translation>Stopper...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1507"/>
@@ -515,17 +519,17 @@ Dark mode is perfect for live coding in night clubs.</source>
     <message>
         <location filename="../mainwindow.cpp" line="1729"/>
         <source>Switching To Headphone Audio Output...</source>
-        <translation type="unfinished">Bytter til hodetelefonlyduttak...</translation>
+        <translation>Bytter til hodetelefonlyduttak...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1745"/>
         <source>Switching To HDMI Audio Output...</source>
-        <translation type="unfinished">Bytter til HDMI-lyduttak...</translation>
+        <translation>Bytter til HDMI-lyduttak...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1760"/>
         <source>Switching To Default Audio Output...</source>
-        <translation type="unfinished">Endrer til default-lyduttak...</translation>
+        <translation>Endrer til default-lyduttak...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1902"/>
@@ -535,7 +539,7 @@ Dark mode is perfect for live coding in night clubs.</source>
     <message>
         <location filename="../mainwindow.cpp" line="1903"/>
         <source>Run the code in the current workspace</source>
-        <translation type="unfinished">Kjør koden i det aktive arbeidsområdet</translation>
+        <translation>Kjør koden i det aktive arbeidsområdet</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1907"/>
@@ -545,7 +549,7 @@ Dark mode is perfect for live coding in night clubs.</source>
     <message>
         <location filename="../mainwindow.cpp" line="1908"/>
         <source>Stop all running code</source>
-        <translation type="unfinished">Stopp all kjørende kode</translation>
+        <translation>Stopp all kjørende kode</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1911"/>
@@ -570,17 +574,17 @@ Dark mode is perfect for live coding in night clubs.</source>
     <message>
         <location filename="../mainwindow.cpp" line="1921"/>
         <source>Toggle help pane</source>
-        <translation type="unfinished">Styr hjelpepanelet</translation>
+        <translation>Styr hjelpepanel</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1924"/>
         <source>Prefs</source>
-        <translation type="unfinished">Oppsett</translation>
+        <translation>Innstillinger</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1925"/>
         <source>Toggle preferences pane</source>
-        <translation type="unfinished">Styr oppsettpanelet</translation>
+        <translation>Styr innstillingspanel</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1929"/>
@@ -602,19 +606,19 @@ Dark mode is perfect for live coding in night clubs.</source>
     <message>
         <location filename="../mainwindow.cpp" line="1935"/>
         <source>Improve readability of code</source>
-        <translation type="unfinished">Forbedre lesbarheten til koden</translation>
+        <translation>Gjør koden mer lesbar</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1939"/>
         <location filename="../mainwindow.cpp" line="1940"/>
         <source>Increase Text Size</source>
-        <translation type="unfinished">Øk tekststørrelsen</translation>
+        <translation>Øk skriftstørrelsen</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1944"/>
         <location filename="../mainwindow.cpp" line="1945"/>
         <source>Decrease Text Size</source>
-        <translation type="unfinished">Reduser tekststørrelsen</translation>
+        <translation>Reduser skriftstørrelsen</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1950"/>
@@ -629,27 +633,27 @@ Dark mode is perfect for live coding in night clubs.</source>
     <message>
         <location filename="../mainwindow.cpp" line="1998"/>
         <source>Core Team</source>
-        <translation type="unfinished">Kjernegruppen</translation>
+        <translation>Kjernegruppen</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="1999"/>
         <source>Contributors</source>
-        <translation type="unfinished">Bidragsytere</translation>
+        <translation>Bidragsytere</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2000"/>
         <source>Community</source>
-        <translation type="unfinished">Fellesskap</translation>
+        <translation>Fellesskap</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2001"/>
         <source>License</source>
-        <translation type="unfinished">Lisens</translation>
+        <translation>Lisens</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2002"/>
         <source>History</source>
-        <translation type="unfinished">Historie</translation>
+        <translation>Historie</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2023"/>
@@ -660,72 +664,75 @@ Dark mode is perfect for live coding in night clubs.</source>
         <location filename="../mainwindow.cpp" line="2043"/>
         <location filename="../mainwindow.cpp" line="2044"/>
         <source>Stop Recording</source>
-        <translation type="unfinished">Stop opptak</translation>
+        <translation>Stop opptak</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2057"/>
         <source>Save Recording</source>
-        <translation type="unfinished">Lagre opptak</translation>
+        <translation>Lagre opptak</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2076"/>
         <source>Ready...</source>
-        <translation type="unfinished">Klar...</translation>
+        <translation>Klar...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2153"/>
         <source>Cannot read file %1:
 %2.</source>
-        <translation type="unfinished">Kan ikke lese fil %1: %2.</translation>
+        <translation>Kan ikke lese fil %1:
+%2.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2163"/>
         <source>File loaded...</source>
-        <translation type="unfinished">Filen lastet...</translation>
+        <translation>Lastet fil...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2171"/>
         <source>Cannot write file %1:
 %2.</source>
-        <translation type="unfinished">Kan ikke skrive filen %1: %2.</translation>
+        <translation>Kan ikke skrive filen %1:
+%2.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2188"/>
         <source>File saved...</source>
-        <translation type="unfinished">Lagret filen...</translation>
+        <translation>Lagret filen...</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2413"/>
         <source>Last checked %1</source>
-        <translation type="unfinished">Sist sjekket %1</translation>
+        <translation>Sist sjekket %1</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2415"/>
         <source>Sonic Pi checks for updates
 every two weeks.</source>
-        <translation type="unfinished">Sonic Pi sjekker etter oppdateringer hver andre uke.</translation>
+        <translation>Sonic Pi sjekker etter oppdateringer
+hver andre uke.</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2417"/>
         <source>This is Sonic Pi %1</source>
-        <translation type="unfinished">Dette er Sonic Pi %1</translation>
+        <translation>Dette er Sonic Pi %1</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2418"/>
         <source>Version %2 is now available!</source>
-        <translation type="unfinished">Utgave %2 er nå tilgjengelig!</translation>
+        <translation>Utgave %2 er nå tilgjengelig!</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2422"/>
         <source>New version available!
 Get Sonic Pi %1</source>
-        <translation type="unfinished">Ny utgave er tilgjengelig!
+        <translation>Ny utgave er tilgjengelig!
 Skaff Sonic Pi %1</translation>
     </message>
     <message>
         <location filename="../mainwindow.cpp" line="2448"/>
         <source>Welcome back. Now get your live code on...</source>
-        <translation type="unfinished">Velkommen tilbake. Nå kan du live-kode på...</translation>
+        <translation>Velkommen tilbake. Nå kan du direkte-kode på...</translation>
     </message>
     <message>
         <location filename="../ruby_help.h" line="80"/>
@@ -735,7 +742,7 @@ Skaff Sonic Pi %1</translation>
         <location filename="../ruby_help.h" line="278"/>
         <location filename="../ruby_help.h" line="338"/>
         <source>Tutorial</source>
-        <translation type="unfinished">Innføring</translation>
+        <translation>Innføring</translation>
     </message>
     <message>
         <location filename="../ruby_help.h" line="370"/>
@@ -745,7 +752,7 @@ Skaff Sonic Pi %1</translation>
     <message>
         <location filename="../ruby_help.h" line="410"/>
         <source>Synths</source>
-        <translation type="unfinished">Synth-er</translation>
+        <translation>Synth-er</translation>
     </message>
     <message>
         <location filename="../ruby_help.h" line="446"/>
@@ -760,7 +767,7 @@ Skaff Sonic Pi %1</translation>
     <message>
         <location filename="../ruby_help.h" line="629"/>
         <source>Lang</source>
-        <translation type="unfinished">Språk</translation>
+        <translation>Språk</translation>
     </message>
 </context>
 <context>
@@ -775,8 +782,8 @@ Skaff Sonic Pi %1</translation>
     <name>SonicPiUDPServer</name>
     <message>
         <location filename="../sonicpiudpserver.cpp" line="24"/>
-        <source>Is Sonic Pi already running?  Can't open UDP port 4558.</source>
-        <translation type="unfinished">Kjører Sonic Pi allerede? Klarer ikke åpne UDP port 4558.</translation>
+        <source>Is Sonic Pi already running?  Can't open UDP port 4558.</source>
+        <translation>Kjører Sonic Pi allerede? Klarer ikke åpne UDP port 4558.</translation>
     </message>
 </context>
 </TS>
diff --git a/app/gui/qt/lang/sonic-pi_ru.ts b/app/gui/qt/lang/sonic-pi_ru.ts
new file mode 100644
index 0000000..f291b68
--- /dev/null
+++ b/app/gui/qt/lang/sonic-pi_ru.ts
@@ -0,0 +1,753 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="ru_RU">
+<context>
+    <name>MainWindow</name>
+    <message>
+        <location filename="../mainwindow.cpp" line="168"/>
+        <location filename="../mainwindow.cpp" line="2237"/>
+        <location filename="../mainwindow.cpp" line="2255"/>
+        <source>Sonic Pi</source>
+        <translation>Sonic Pi</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="221"/>
+        <source>Welcome to Sonic Pi</source>
+        <translation>Добро пожаловать в Sonic Pi</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="263"/>
+        <source>Sonic Pi update info</source>
+        <translation>Информация об обновлениях Sonic Pi</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="370"/>
+        <source>Buffer %1</source>
+        <translation>Буфер %1</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="434"/>
+        <source>Preferences</source>
+        <translation>Параметры</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="447"/>
+        <source>Log</source>
+        <translation>Журнал</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="488"/>
+        <location filename="../mainwindow.cpp" line="2003"/>
+        <source>Help</source>
+        <translation>Помощь</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="632"/>
+        <source>Indenting selection...</source>
+        <translation>Отступ выделения...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="636"/>
+        <source>Indenting line...</source>
+        <translation>Отступ линии...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="665"/>
+        <source>Commenting selection...</source>
+        <translation>Комментирование выделения...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="669"/>
+        <source>Commenting line...</source>
+        <translation>Комментирование строки...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="743"/>
+        <source>The Sonic Pi server could not be started!</source>
+        <translation>Сервер Sonic Pi не может быть запущен!</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="845"/>
+        <source>Raspberry Pi System Volume</source>
+        <translation>Системная Громкость Paspberry Pi</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="846"/>
+        <source>Use this slider to change the system volume of your Raspberry Pi.</source>
+        <translation>Используйте этот ползунок чтобы изменить системную громкость вашего Raspberry Pi.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="848"/>
+        <source>Advanced Audio</source>
+        <translation>Расширенное Аудио</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="849"/>
+        <source>Advanced audio settings for working with
+external PA systems when performing with Sonic Pi.</source>
+        <translatorcomment>Из-за отсутствия контекста непонятно, что такое PA systems</translatorcomment>
+        <translation>Расширенные аудио настройки для работы
+с внешними ПА системами.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="850"/>
+        <source>Invert Stereo</source>
+        <translation>Инвертировать Стерео</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="851"/>
+        <source>Toggle stereo inversion.
+If enabled, audio sent to the left speaker will
+be routed to the right speaker and visa versa.</source>
+        <translation>Включить/выключить инвертирование стерео.
+Если включено, аудио сигнал, посылаемый в
+левый динамик будет перенаправлен в правый
+динамик и наоборот.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="853"/>
+        <source>Force Mono</source>
+        <translation>Пренудительное Моно</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="854"/>
+        <source>Toggle mono mode.
+If enabled both right and left audio is mixed and
+the same signal is sent to both speakers.
+Useful when working with external systems that
+can only handle mono.</source>
+        <translation>Включить/выключить моно режим.
+Если включено, правый и левый аудио 
+каналы смешиваются и этот смешанный сигнал
+ поступает в оба динамика.
+Полезно при работе с внешними системами,
+способными обрабатывать только моно сигнал.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="857"/>
+        <source>Safe mode</source>
+        <translation>Безопасный режим</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="858"/>
+        <source>Toggle synth argument checking functions.
+If disabled, certain synth opt values may
+create unexpectedly loud or uncomfortable sounds.</source>
+        <translation>Включить/выключить функции проверки аргументов синтезатора.
+Если выключено, некоторые значения опций синтезаторов смогут
+вызвать неожиданно громкий или неприятный звук.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="870"/>
+        <source>Raspberry Pi Audio Output</source>
+        <translation>Аудио Выход Paspberry Pi</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="871"/>
+        <source>Your Raspberry Pi has two forms of audio output.
+Firstly, there is the headphone jack of the Raspberry Pi itself.
+Secondly, some HDMI monitors/TVs support audio through the HDMI port.
+Use these buttons to force the output to the one you want.</source>
+        <translation>Ваш Raspberry Pi имеет два интерфейса вывода звука.
+Первый - это разъём для наушников.
+Второй - воспроизведение аудио через HDMI порт
+(поддерживается некоторыми HDMI мониторами и телевизорами).
+Используйте эти кнопки для вывода звука на тот интерфейс,
+ на который хотите.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="872"/>
+        <source>&Default</source>
+        <translation>&По умолчанию</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="873"/>
+        <source>&Headphones</source>
+        <translation>&Наушники</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="874"/>
+        <source>&HDMI</source>
+        <translation>&HDMI</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="894"/>
+        <source>Logging</source>
+        <translation>Журналирование</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="895"/>
+        <source>Configure debug behaviour</source>
+        <translation>Настроить поведение отладки</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="897"/>
+        <source>Log synths</source>
+        <translation>Журнал синтезаторов</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="898"/>
+        <source>Toggle log messages.
+If disabled, activity such as synth and sample
+triggering will not be printed to the log by default.</source>
+        <translation>Включить/выключить журнал сообщений.
+Если отключено, активность, такая как срабатывание
+синтезатора или сэмпла не будет выводиться
+в журнал по умолчанию.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="900"/>
+        <source>Clear log on run</source>
+        <translation>Очищать журнал при выполнении</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="901"/>
+        <source>Toggle log clearing on run.
+If enabled, the log is cleared each
+time the run button is pressed.</source>
+        <translation>Включить/выключить очистку журнала при выполнении.
+Если включено, журнал очищается каждый раз,
+когда нажимается кнопка Выполнить.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="903"/>
+        <source>Log cues</source>
+        <translation>Журнал сигналов</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="904"/>
+        <source>Enable or disable logging of cues.
+If disabled, cues will still trigger.
+However, they will not be visible in the logs.</source>
+        <translation>Включить/выключить ведение журнала сигналов.
+Если отключить, сигналы по-прежнему будут воспроизводиться.
+Однако они не будут видны в журнале.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="913"/>
+        <source>Transparency</source>
+        <translation>Прозрачность</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="924"/>
+        <location filename="../mainwindow.cpp" line="1056"/>
+        <source>Updates</source>
+        <translation>Обновления</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="926"/>
+        <source>Check for updates</source>
+        <translation>Проверить наличие обновлений</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="928"/>
+        <source>Toggle automatic update checking.
+This check involves sending anonymous information about your platform and version.</source>
+        <translation>Включить/выключить автоматическую проверку обновлений.
+Эта проверка предполагает отправку анонимной информации о вашей платформе и версии.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="929"/>
+        <source>Check now</source>
+        <translation>Проверить сейчас</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="930"/>
+        <source>Force a check for updates now.
+This check involves sending anonymous information about your platform and version.</source>
+        <translation>Принудительно проверить обновления сейчас.
+Эта проверка предполагает отправку анонимной информации о вашей платформе и версии.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="931"/>
+        <source>Get update</source>
+        <translation>Получить обновления</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="932"/>
+        <source>Visit http://sonic-pi.net to download new version</source>
+        <translation>Посетить http://sonic-pi.net чтобы скачать новую версию</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="937"/>
+        <source>Update Info</source>
+        <translation>Информация об обновлениях</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="956"/>
+        <source>Show and Hide</source>
+        <translation>Показать/Скрыть</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="957"/>
+        <source>Configure editor display options.</source>
+        <translation>Настроить параметры отображения редактора.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="958"/>
+        <source>Look and Feel</source>
+        <translation>Внешний вид</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="959"/>
+        <source>Configure editor look and feel.</source>
+        <translation>Настроить внешний вид редактора.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="960"/>
+        <source>Automation</source>
+        <translation>Автоматизация</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="961"/>
+        <source>Configure automation features.</source>
+        <translation>Настроить функции автоматизации.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="962"/>
+        <source>Auto-align</source>
+        <translation>Автовыравнивание</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="963"/>
+        <source>Automatically align code on Run</source>
+        <translation>Автоматически выравнивать код при Выполнении</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="965"/>
+        <source>Show line numbers</source>
+        <translation>Показать номера строк</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="966"/>
+        <source>Toggle line number visibility.</source>
+        <translation>Показать/скрыть номера строк.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="967"/>
+        <source>Show log</source>
+        <translation>Показать журнал</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="968"/>
+        <source>Toggle visibility of the log.</source>
+        <translation>Показать/скрыть журнал.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="970"/>
+        <source>Show buttons</source>
+        <translation>Показать кнопки</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="971"/>
+        <source>Toggle visibility of the control buttons.</source>
+        <translation>Показать/скрыть кнопки управления.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="973"/>
+        <source>Show tabs</source>
+        <translation>Показать вкладки</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="975"/>
+        <source>Toggle visibility of the buffer selection tabs.</source>
+        <translation>Показать/скрыть вкладки выбора буфера.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="976"/>
+        <source>Full screen</source>
+        <translation>На полный экран</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="977"/>
+        <source>Toggle full screen mode.</source>
+        <translation>Включить/выключить полноэкранный режим.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="978"/>
+        <source>Dark mode</source>
+        <translation>Тёмный режим</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="979"/>
+        <source>Toggle dark mode.</source>
+        <translation>Включить/выключить тёмный режим.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="979"/>
+        <source>
+Dark mode is perfect for live coding in night clubs.</source>
+        <translation>Тёмный режим идеально подходит для лайв-кодинга в ночных клубах.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1018"/>
+        <source>Audio</source>
+        <translation>Аудио</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1030"/>
+        <source>Editor</source>
+        <translation>Редактор</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1031"/>
+        <source>Studio</source>
+        <translation>Студия</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1033"/>
+        <location filename="../mainwindow.cpp" line="1043"/>
+        <source>Performance</source>
+        <translation>Выступление</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1034"/>
+        <source>Settings useful for performing with Sonic Pi</source>
+        <translation>Параметры необходимые для выступления с Sonic Pi</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1144"/>
+        <source>Server boot error...</source>
+        <translation>Ошибка загрузки сервера...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1144"/>
+        <source>Sonic Pi Boot Error
+
+Apologies, a critical error occurred during startup</source>
+        <translation>Ошибка Загрузки Sonic Pi
+
+Извините, произошла критическая ошибка во время запуска</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1144"/>
+        <source>Please consider reporting a bug at</source>
+        <translation>Пожалуйста, рассмотрите возможность сообщать об ошибке в</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1239"/>
+        <source>Save Current Buffer</source>
+        <translation>Сохранить Текущий Буфер</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1310"/>
+        <source>Running Code...</source>
+        <translation>Выполнение Кода...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1352"/>
+        <source>Zooming In...</source>
+        <translation>Увеличение масштаба...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1359"/>
+        <source>Zooming Out...</source>
+        <translation>Уменьшение масштаба...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1366"/>
+        <source>Beautifying...</source>
+        <translation>Украшение...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1386"/>
+        <source>Reloading...</source>
+        <translation>Перезагрузка...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1393"/>
+        <source>Checking for updates...</source>
+        <translation>Проверка обновлений...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1401"/>
+        <source>Enabling update checking...</source>
+        <translation>Активирование проверки обновлений...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1409"/>
+        <source>Disabling update checking...</source>
+        <translation>Отключение проверки обновлений...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1417"/>
+        <source>Enabling Mixer HPF...</source>
+        <translation>Активирование Микшера ВЧФ...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1426"/>
+        <source>Disabling Mixer HPF...</source>
+        <translation>Отключение Микшера ВЧФ...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1434"/>
+        <source>Enabling Mixer LPF...</source>
+        <translation>Активирование Микшера НЧФ...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1443"/>
+        <source>Disabling Mixer LPF...</source>
+        <translation>Отключение Микшера НЧФ...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1451"/>
+        <source>Enabling Inverted Stereo...</source>
+        <translation>Активирование Инвертированного Стерео...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1459"/>
+        <source>Enabling Standard Stereo...</source>
+        <translation>Активирование Стандартного Стерео...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1467"/>
+        <source>Mono Mode...</source>
+        <translation>Моно Режим...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1475"/>
+        <source>Stereo Mode...</source>
+        <translation>Стерео Режим...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1484"/>
+        <source>Stopping...</source>
+        <translation>Остановка...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1580"/>
+        <source>Updating System Volume...</source>
+        <translation>Обновление системной громкости...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1802"/>
+        <source>Switching To Headphone Audio Output...</source>
+        <translation>Переключение на Аудио Выход Наушников...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1818"/>
+        <source>Switching To HDMI Audio Output...</source>
+        <translation>Переключение на Аудио Выход HDMI...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1833"/>
+        <source>Switching To Default Audio Output...</source>
+        <translation>Переключение на Аудио Выход По Умолчанию...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1984"/>
+        <source>Run</source>
+        <translation>Выполнить</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1985"/>
+        <source>Run the code in the current buffer</source>
+        <translation>Выполнить код текущего буфера</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1990"/>
+        <source>Stop</source>
+        <translation>Остановить</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1991"/>
+        <source>Stop all running code</source>
+        <translation>Остановить весь запущенный код</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1994"/>
+        <source>Save As...</source>
+        <translation>Сохранить Как...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1995"/>
+        <source>Save current buffer as an external file</source>
+        <translation>Сохранить текущий буфер как внешний файл</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1998"/>
+        <source>Info</source>
+        <translation>Информация</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1999"/>
+        <source>See information about Sonic Pi</source>
+        <translation>Посмотреть информацию о Sonic Pi</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2004"/>
+        <source>Toggle help pane</source>
+        <translation>Показать/скрыть панель помощи</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2007"/>
+        <source>Prefs</source>
+        <translation>Параметры</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2008"/>
+        <source>Toggle preferences pane</source>
+        <translation>Показать/скрыть панель настроек</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2012"/>
+        <location filename="../mainwindow.cpp" line="2137"/>
+        <location filename="../mainwindow.cpp" line="2138"/>
+        <source>Start Recording</source>
+        <translation>Начать Запись</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2013"/>
+        <source>Start recording to WAV audio file</source>
+        <translation>Начать запись в WAV аудио файл</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2017"/>
+        <source>Auto-Align Text</source>
+        <translation>Автовыравнивание текста</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2018"/>
+        <source>Improve readability of code</source>
+        <translation>Улучшить читаемость кода</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2024"/>
+        <source>Increase Text Size</source>
+        <translation>Увеличить Размер Текста</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2031"/>
+        <source>Decrease Text Size</source>
+        <translation>Уменьшить Размер Текста</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2036"/>
+        <source>Tools</source>
+        <translation>Инструменты</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2083"/>
+        <source>About</source>
+        <translation>О Sonic Pi</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2084"/>
+        <source>Core Team</source>
+        <translation>Ядро Команды</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2085"/>
+        <source>Contributors</source>
+        <translation>Внесли вклад</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2086"/>
+        <source>Community</source>
+        <translation>Сообщество</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2087"/>
+        <source>License</source>
+        <translation>Лицензия</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2088"/>
+        <source>History</source>
+        <translation>История</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2109"/>
+        <source>Sonic Pi - Info</source>
+        <translation>Информация o Sonic Pi</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2129"/>
+        <location filename="../mainwindow.cpp" line="2130"/>
+        <source>Stop Recording</source>
+        <translation>Остановить Запись</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2143"/>
+        <source>Save Recording</source>
+        <translation>Сохранить Запись</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2162"/>
+        <source>Ready...</source>
+        <translation>Подготовка...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2238"/>
+        <source>Cannot read file %1:
+%2.</source>
+        <translation>Не удаётся прочитать файл %1: %2.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2248"/>
+        <source>File loaded...</source>
+        <translation>Файл загружен...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2256"/>
+        <source>Cannot write file %1:
+%2.</source>
+        <translation>Не удаётся записать файл %1: %2.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2273"/>
+        <source>File saved...</source>
+        <translation>Файл сохранён...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2499"/>
+        <source>Last checked %1</source>
+        <translation>Последняя проверка %1</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2501"/>
+        <source>Sonic Pi checks for updates
+every two weeks.</source>
+        <translation>Sonic Pi проверяет наличие обновлений
+каждые две недели.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2503"/>
+        <source>This is Sonic Pi %1</source>
+        <translation>Это Sonic Pi %1</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2504"/>
+        <source>Version %2 is now available!</source>
+        <translation>Версия %2 теперь доступна!</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2508"/>
+        <source>New version available!
+Get Sonic Pi %1</source>
+        <translation>Доступна новая версия!
+Получить Sonic Pi %1</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2532"/>
+        <source>Welcome back. Now get your live code on...</source>
+        <translation>С возвращением. Начните свой лайв кодинг...</translation>
+    </message>
+</context>
+<context>
+    <name>QObject</name>
+    <message>
+        <location filename="../main.cpp" line="43"/>
+        <source>Sonic Pi</source>
+        <translation>Sonic Pi</translation>
+    </message>
+</context>
+<context>
+    <name>SonicPiUDPOSCServer</name>
+    <message>
+        <location filename="../sonic_pi_udp_osc_server.cpp" line="24"/>
+        <source>Is Sonic Pi already running?  Can't open UDP port 4558.</source>
+        <translation>Sonic Pi уже запущен? Не могу открыть UDP порт 4558.</translation>
+    </message>
+</context>
+</TS>
diff --git a/app/gui/qt/lang/sonic-pi_zh-Hans.ts b/app/gui/qt/lang/sonic-pi_zh-Hans.ts
new file mode 100644
index 0000000..b73a235
--- /dev/null
+++ b/app/gui/qt/lang/sonic-pi_zh-Hans.ts
@@ -0,0 +1,783 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="zh_CN">
+<context>
+    <name>MainWindow</name>
+    <message>
+        <location filename="../mainwindow.cpp" line="201"/>
+        <location filename="../mainwindow.cpp" line="2336"/>
+        <location filename="../mainwindow.cpp" line="2356"/>
+        <source>Sonic Pi</source>
+        <translation>Sonic Pi</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="254"/>
+        <source>Welcome to Sonic Pi</source>
+        <translation>欢迎进入Sonic Pi的世界</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="296"/>
+        <source>Sonic Pi update info</source>
+        <translation>Sonic Piæ›´æ–°</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="400"/>
+        <source>Buffer %1</source>
+        <translation>编辑器窗口 %1</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="464"/>
+        <source>Preferences</source>
+        <translation>偏好设置</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="477"/>
+        <source>Log</source>
+        <translation>日志</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="518"/>
+        <location filename="../mainwindow.cpp" line="2097"/>
+        <source>Help</source>
+        <translation>帮助</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="670"/>
+        <source>Indenting selection...</source>
+        <translation>缩进选中区域</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="674"/>
+        <source>Indenting line...</source>
+        <translation>缩进当前行</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="703"/>
+        <source>Toggle selection comment...</source>
+        <translation>注释/取消注释选中区域</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="707"/>
+        <source>Toggle line comment...</source>
+        <translation>注释/取消注释当前行</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="765"/>
+        <source>The Sonic Pi server could not be started!</source>
+        <translation>Sonic Pi服务器无法启动。</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="872"/>
+        <source>Raspberry Pi System Volume</source>
+        <translation>Raspberry Pi系统音量</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="873"/>
+        <source>Use this slider to change the system volume of your Raspberry Pi.</source>
+        <translation>请用这个滑块调整Raspberry Pi的系统音量</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="875"/>
+        <source>Advanced Audio</source>
+        <translation>高级音量选项</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="876"/>
+        <source>Advanced audio settings for working with
+external PA systems when performing with Sonic Pi.</source>
+        <translation>外接PA系统的高级音量选项</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="877"/>
+        <source>Invert Stereo</source>
+        <translation>反转立体声声道</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="878"/>
+        <source>Toggle stereo inversion.
+If enabled, audio sent to the left speaker will
+be routed to the right speaker and visa versa.</source>
+        <translation>打开/关闭立体声声道反转</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="880"/>
+        <source>Force Mono</source>
+        <translation>强制单声道</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="881"/>
+        <source>Toggle mono mode.
+If enabled both right and left audio is mixed and
+the same signal is sent to both speakers.
+Useful when working with external systems that
+can only handle mono.</source>
+        <translation>打开/关闭强制单声道</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="884"/>
+        <source>Safe mode</source>
+        <translation>安全模式</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="885"/>
+        <source>Toggle synth argument checking functions.
+If disabled, certain synth opt values may
+create unexpectedly loud or uncomfortable sounds.</source>
+        <translation>打开/关闭合成器参数检查</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="897"/>
+        <source>Raspberry Pi Audio Output</source>
+        <translation>Raspberry Pi音频输出</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="898"/>
+        <source>Your Raspberry Pi has two forms of audio output.
+Firstly, there is the headphone jack of the Raspberry Pi itself.
+Secondly, some HDMI monitors/TVs support audio through the HDMI port.
+Use these buttons to force the output to the one you want.</source>
+        <translation>你的Raspberry Pi有两种音频输出模式。第一种是通过系统的耳机接口输出;
+            第二种是通过HDMI接口。你可以通过以下按钮来选择你希望使用的音频输出方式</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="899"/>
+        <source>&Default</source>
+        <translation>&默认</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="900"/>
+        <source>&Headphones</source>
+        <translation>&耳机接口</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="901"/>
+        <source>&HDMI</source>
+        <translation>&HDMI接口</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="921"/>
+        <source>Logging</source>
+        <translation>日志选项</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="922"/>
+        <source>Configure debug behaviour</source>
+        <translation>配置调试模式</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="924"/>
+        <source>Log synths</source>
+        <translation>记录声音合成</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="925"/>
+        <source>Toggle log messages.
+If disabled, activity such as synth and sample
+triggering will not be printed to the log by default.</source>
+        <translation>是否记录日志</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="927"/>
+        <source>Clear log on run</source>
+        <translation>重新运行时清空日志</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="928"/>
+        <source>Toggle log clearing on run.
+If enabled, the log is cleared each
+time the run button is pressed.</source>
+        <translation>是否在运行时自动清空日志</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="930"/>
+        <source>Log cues</source>
+        <translation>记录提示</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="931"/>
+        <source>Enable or disable logging of cues.
+If disabled, cues will still trigger.
+However, they will not be visible in the logs.</source>
+        <translation>是否记录提示到日志</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="933"/>
+        <source>Log Auto Scroll</source>
+        <translation>日志自动滚动</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="934"/>
+        <source>Toggle log auto scrolling.
+If enabled the log is scrolled to the botton after every new message is displayed.</source>
+        <translation>是否自动滚动日志</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="944"/>
+        <source>Transparency</source>
+        <translation>透明度</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="955"/>
+        <location filename="../mainwindow.cpp" line="1087"/>
+        <source>Updates</source>
+        <translation>æ›´æ–°</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="957"/>
+        <source>Check for updates</source>
+        <translation>检查更新</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="959"/>
+        <source>Toggle automatic update checking.
+This check involves sending anonymous information about your platform and version.</source>
+        <translation>打开/关闭自动更新(以及上传匿名版本信息)</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="960"/>
+        <source>Check now</source>
+        <translation>立即检查更新</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="961"/>
+        <source>Force a check for updates now.
+This check involves sending anonymous information about your platform and version.</source>
+        <translation>立即检查更新(并上传匿名版本信息)</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="962"/>
+        <source>Get update</source>
+        <translation>获取更新</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="963"/>
+        <source>Visit http://sonic-pi.net to download new version</source>
+        <translation>访问http://sonic-pi.net下载新版本</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="968"/>
+        <source>Update Info</source>
+        <translation>更新信息</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="987"/>
+        <source>Show and Hide</source>
+        <translation>显示/隐藏</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="988"/>
+        <source>Configure editor display options.</source>
+        <translation>代码编辑器选项</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="989"/>
+        <source>Look and Feel</source>
+        <translation>外观</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="990"/>
+        <source>Configure editor look and feel.</source>
+        <translation>设置代码编辑器外观</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="991"/>
+        <source>Automation</source>
+        <translation>自动化</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="992"/>
+        <source>Configure automation features.</source>
+        <translation>设置自动化选项</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="993"/>
+        <source>Auto-align</source>
+        <translation>自动对齐</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="994"/>
+        <source>Automatically align code on Run</source>
+        <translation>运行时自动对齐代码</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="996"/>
+        <source>Show line numbers</source>
+        <translation>显示行号</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="997"/>
+        <source>Toggle line number visibility.</source>
+        <translation>是否显示行号</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="998"/>
+        <source>Show log</source>
+        <translation>显示日志</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="999"/>
+        <source>Toggle visibility of the log.</source>
+        <translation>是否显示日志</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1001"/>
+        <source>Show buttons</source>
+        <translation>显示控制按钮</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1002"/>
+        <source>Toggle visibility of the control buttons.</source>
+        <translation>是否显示控制按钮</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1004"/>
+        <source>Show tabs</source>
+        <translation>显示编辑器窗口选择栏</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1006"/>
+        <source>Toggle visibility of the buffer selection tabs.</source>
+        <translation>是否显示编辑器窗口选择栏</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1007"/>
+        <source>Full screen</source>
+        <translation>全屏模式</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1008"/>
+        <source>Toggle full screen mode.</source>
+        <translation>打开/关闭全屏模式</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1009"/>
+        <source>Dark mode</source>
+        <translation>夜灯模式</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1010"/>
+        <source>Toggle dark mode.</source>
+        <translation>打开/关闭夜灯模式</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1010"/>
+        <source>
+Dark mode is perfect for live coding in night clubs.</source>
+        <translation>夜灯模式适用于在灯光教案的场所使用</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1049"/>
+        <source>Audio</source>
+        <translation>音频</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1061"/>
+        <source>Editor</source>
+        <translation>编辑器</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1062"/>
+        <source>Studio</source>
+        <translation>工作室</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1064"/>
+        <location filename="../mainwindow.cpp" line="1074"/>
+        <source>Performance</source>
+        <translation>性能</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1065"/>
+        <source>Settings useful for performing with Sonic Pi</source>
+        <translation>表演用设置</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1200"/>
+        <source>Server boot error...</source>
+        <translation>服务器启动错误...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1200"/>
+        <source>Sonic Pi Boot Error
+
+Apologies, a critical error occurred during startup</source>
+        <translation>Sonic Pi启动错误
+
+很抱歉,Sonic Pi启动过程中发生错误
+        </translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1200"/>
+        <source>Please consider reporting a bug at</source>
+        <translation>你可以报告这个bug</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1305"/>
+        <location filename="../mainwindow.cpp" line="1318"/>
+        <source>Buffer files(*.rb *.txt)</source>
+        <translation>Sonic-Pi代码文件 (*.rb *.txt)</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1306"/>
+        <source>Load Sonic-Pi Buffer</source>
+        <translation>加载Sonic-Pi代码</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1306"/>
+        <location filename="../mainwindow.cpp" line="1319"/>
+        <source>Buffer files(*.rb *.txt);;Text files (*.txt);;Ruby (*.rb);;All files (*.*)</source>
+        <translation>Sonic-Pi代码文件 (*.rb *.txt);;Text files (*.txt);;Ruby (*.rb);;所有文件 (*.*)</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1319"/>
+        <source>Save Current Buffer</source>
+        <translation>保存当前编辑器窗口代码</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1390"/>
+        <source>Running Code...</source>
+        <translation>运行代码</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1432"/>
+        <source>Zooming In...</source>
+        <translation>放大...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1439"/>
+        <source>Zooming Out...</source>
+        <translation>缩小...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1446"/>
+        <source>Beautifying...</source>
+        <translation>美化...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1466"/>
+        <source>Reloading...</source>
+        <translation>重新载入...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1473"/>
+        <source>Checking for updates...</source>
+        <translation>检查更新...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1481"/>
+        <source>Enabling update checking...</source>
+        <translation>开启更新检查...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1489"/>
+        <source>Disabling update checking...</source>
+        <translation>关闭更新检查...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1497"/>
+        <source>Enabling Mixer HPF...</source>
+        <translation>启用高通滤波器...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1506"/>
+        <source>Disabling Mixer HPF...</source>
+        <translation>禁用高通滤波器...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1514"/>
+        <source>Enabling Mixer LPF...</source>
+        <translation>启用低通滤波器...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1523"/>
+        <source>Disabling Mixer LPF...</source>
+        <translation>禁用低通滤波器...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1531"/>
+        <source>Enabling Inverted Stereo...</source>
+        <translation>启用反转立体声...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1539"/>
+        <source>Enabling Standard Stereo...</source>
+        <translation>启用标准立体声...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1547"/>
+        <source>Mono Mode...</source>
+        <translation>单声道模式...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1555"/>
+        <source>Stereo Mode...</source>
+        <translation>立体声模式...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1564"/>
+        <source>Stopping...</source>
+        <translation>终止当前任务...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1660"/>
+        <source>Updating System Volume...</source>
+        <translation>更新系统音量...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1676"/>
+        <source>Log Auto Scroll on...</source>
+        <translation>日志窗口自动滚动开启...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1678"/>
+        <source>Log Auto Scroll off...</source>
+        <translation>日志窗口自动滚动关闭...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1892"/>
+        <source>Switching To Headphone Audio Output...</source>
+        <translation>切换到耳机音频输出...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1908"/>
+        <source>Switching To HDMI Audio Output...</source>
+        <translation>切换到HDMI音频输出...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1923"/>
+        <source>Switching To Default Audio Output...</source>
+        <translation>切换到默认音频输出...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2074"/>
+        <source>Run</source>
+        <translation>运行</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2075"/>
+        <source>Run the code in the current buffer</source>
+        <translation>运行当前编辑器窗口内的代码</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2080"/>
+        <source>Stop</source>
+        <translation>停止</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2081"/>
+        <source>Stop all running code</source>
+        <translation>停止所有代码运行</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2084"/>
+        <source>Save As...</source>
+        <translation>另存为...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2085"/>
+        <source>Save current buffer as an external file</source>
+        <translation>保存当前编辑器窗口为外部文件</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2088"/>
+        <source>Load</source>
+        <translation>载入</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2089"/>
+        <source>Load an external file in the current buffer</source>
+        <translation>载入外部文件到当前编辑器窗口</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2092"/>
+        <source>Info</source>
+        <translation>信息</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2093"/>
+        <source>See information about Sonic Pi</source>
+        <translation>查看Sonic Pi相关信息</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2098"/>
+        <source>Toggle help pane</source>
+        <translation>打开/关闭帮助栏</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2101"/>
+        <source>Prefs</source>
+        <translation>偏好选项</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2102"/>
+        <source>Toggle preferences pane</source>
+        <translation>打开/关闭偏好选项栏</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2106"/>
+        <location filename="../mainwindow.cpp" line="2234"/>
+        <location filename="../mainwindow.cpp" line="2235"/>
+        <source>Start Recording</source>
+        <translation>开始录制</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2107"/>
+        <source>Start recording to WAV audio file</source>
+        <translation>开始录制到wav文件</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2111"/>
+        <source>Auto-Align Text</source>
+        <translation>自动对齐</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2112"/>
+        <source>Improve readability of code</source>
+        <translation>提高代码可读性</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2118"/>
+        <source>Increase Text Size</source>
+        <translation>增大字体</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2125"/>
+        <source>Decrease Text Size</source>
+        <translation>减小字体</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2130"/>
+        <source>Tools</source>
+        <translation>工具</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2180"/>
+        <source>About</source>
+        <translation>关于</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2181"/>
+        <source>Core Team</source>
+        <translation>核心团队</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2182"/>
+        <source>Contributors</source>
+        <translation>项目参与者</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2183"/>
+        <source>Community</source>
+        <translation>社区</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2184"/>
+        <source>License</source>
+        <translation>License</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2185"/>
+        <source>History</source>
+        <translation>历史</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2206"/>
+        <source>Sonic Pi - Info</source>
+        <translation>Sonic Pi - 信息</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2226"/>
+        <location filename="../mainwindow.cpp" line="2227"/>
+        <source>Stop Recording</source>
+        <translation>停止录制</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2240"/>
+        <source>Save Recording</source>
+        <translation>保存录音</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2240"/>
+        <source>Wavefile (*.wav)</source>
+        <translation>波形文件 (*.wav)</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2259"/>
+        <source>Ready...</source>
+        <translation>就绪...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2337"/>
+        <source>Cannot read file %1:
+%2.</source>
+        <translation>无法读取文件 %1:
+        %2.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2348"/>
+        <source>File loaded...</source>
+        <translation>文件已加载...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2357"/>
+        <source>Cannot write file %1:
+%2.</source>
+        <translation>无法写入文件 %1:
+        %2.</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2375"/>
+        <source>File saved...</source>
+        <translation>文件已保存...</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2601"/>
+        <source>Last checked %1</source>
+        <translation>上次检查 %1</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2603"/>
+        <source>Sonic Pi checks for updates
+every two weeks.</source>
+        <translation>Sonic Pi每两周检查一次更新</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2605"/>
+        <source>This is Sonic Pi %1</source>
+        <translation>这是Sonic Pi %1</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2606"/>
+        <source>Version %2 is now available!</source>
+        <translation>新版本 %2 已经就绪,可供下载。</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2610"/>
+        <source>New version available!
+Get Sonic Pi %1</source>
+        <translation>发现新版本!
+        获取Sonic Pi %1</translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2636"/>
+        <source>Welcome back. Now get your live code on...</source>
+        <translation>欢迎回来。现在加载你的代码...</translation>
+    </message>
+</context>
+<context>
+    <name>QObject</name>
+    <message>
+        <location filename="../main.cpp" line="43"/>
+        <source>Sonic Pi</source>
+        <translation>Sonic Pi</translation>
+    </message>
+</context>
+<context>
+    <name>SonicPiUDPOSCServer</name>
+    <message>
+        <location filename="../sonic_pi_udp_osc_server.cpp" line="37"/>
+        <source>Is Sonic Pi already running?  Can't open UDP port 4558.</source>
+        <translation>无法打开UDP端口4558。请确定Sonic Pi是否已在运行。</translation>
+    </message>
+</context>
+</TS>
diff --git a/app/gui/qt/lang/sonic-pi_zh-Hant.ts b/app/gui/qt/lang/sonic-pi_zh-Hant.ts
new file mode 100644
index 0000000..655e33a
--- /dev/null
+++ b/app/gui/qt/lang/sonic-pi_zh-Hant.ts
@@ -0,0 +1,776 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="zh_TW">
+<context>
+    <name>MainWindow</name>
+    <message>
+        <location filename="../mainwindow.cpp" line="201"/>
+        <location filename="../mainwindow.cpp" line="2336"/>
+        <location filename="../mainwindow.cpp" line="2356"/>
+        <source>Sonic Pi</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="254"/>
+        <source>Welcome to Sonic Pi</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="296"/>
+        <source>Sonic Pi update info</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="400"/>
+        <source>Buffer %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="464"/>
+        <source>Preferences</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="477"/>
+        <source>Log</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="518"/>
+        <location filename="../mainwindow.cpp" line="2097"/>
+        <source>Help</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="670"/>
+        <source>Indenting selection...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="674"/>
+        <source>Indenting line...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="703"/>
+        <source>Toggle selection comment...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="707"/>
+        <source>Toggle line comment...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="765"/>
+        <source>The Sonic Pi server could not be started!</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="872"/>
+        <source>Raspberry Pi System Volume</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="873"/>
+        <source>Use this slider to change the system volume of your Raspberry Pi.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="875"/>
+        <source>Advanced Audio</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="876"/>
+        <source>Advanced audio settings for working with
+external PA systems when performing with Sonic Pi.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="877"/>
+        <source>Invert Stereo</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="878"/>
+        <source>Toggle stereo inversion.
+If enabled, audio sent to the left speaker will
+be routed to the right speaker and visa versa.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="880"/>
+        <source>Force Mono</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="881"/>
+        <source>Toggle mono mode.
+If enabled both right and left audio is mixed and
+the same signal is sent to both speakers.
+Useful when working with external systems that
+can only handle mono.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="884"/>
+        <source>Safe mode</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="885"/>
+        <source>Toggle synth argument checking functions.
+If disabled, certain synth opt values may
+create unexpectedly loud or uncomfortable sounds.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="897"/>
+        <source>Raspberry Pi Audio Output</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="898"/>
+        <source>Your Raspberry Pi has two forms of audio output.
+Firstly, there is the headphone jack of the Raspberry Pi itself.
+Secondly, some HDMI monitors/TVs support audio through the HDMI port.
+Use these buttons to force the output to the one you want.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="899"/>
+        <source>&Default</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="900"/>
+        <source>&Headphones</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="901"/>
+        <source>&HDMI</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="921"/>
+        <source>Logging</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="922"/>
+        <source>Configure debug behaviour</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="924"/>
+        <source>Log synths</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="925"/>
+        <source>Toggle log messages.
+If disabled, activity such as synth and sample
+triggering will not be printed to the log by default.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="927"/>
+        <source>Clear log on run</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="928"/>
+        <source>Toggle log clearing on run.
+If enabled, the log is cleared each
+time the run button is pressed.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="930"/>
+        <source>Log cues</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="931"/>
+        <source>Enable or disable logging of cues.
+If disabled, cues will still trigger.
+However, they will not be visible in the logs.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="933"/>
+        <source>Log Auto Scroll</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="934"/>
+        <source>Toggle log auto scrolling.
+If enabled the log is scrolled to the botton after every new message is displayed.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="944"/>
+        <source>Transparency</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="955"/>
+        <location filename="../mainwindow.cpp" line="1087"/>
+        <source>Updates</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="957"/>
+        <source>Check for updates</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="959"/>
+        <source>Toggle automatic update checking.
+This check involves sending anonymous information about your platform and version.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="960"/>
+        <source>Check now</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="961"/>
+        <source>Force a check for updates now.
+This check involves sending anonymous information about your platform and version.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="962"/>
+        <source>Get update</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="963"/>
+        <source>Visit http://sonic-pi.net to download new version</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="968"/>
+        <source>Update Info</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="987"/>
+        <source>Show and Hide</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="988"/>
+        <source>Configure editor display options.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="989"/>
+        <source>Look and Feel</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="990"/>
+        <source>Configure editor look and feel.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="991"/>
+        <source>Automation</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="992"/>
+        <source>Configure automation features.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="993"/>
+        <source>Auto-align</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="994"/>
+        <source>Automatically align code on Run</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="996"/>
+        <source>Show line numbers</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="997"/>
+        <source>Toggle line number visibility.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="998"/>
+        <source>Show log</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="999"/>
+        <source>Toggle visibility of the log.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1001"/>
+        <source>Show buttons</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1002"/>
+        <source>Toggle visibility of the control buttons.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1004"/>
+        <source>Show tabs</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1006"/>
+        <source>Toggle visibility of the buffer selection tabs.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1007"/>
+        <source>Full screen</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1008"/>
+        <source>Toggle full screen mode.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1009"/>
+        <source>Dark mode</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1010"/>
+        <source>Toggle dark mode.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1010"/>
+        <source>
+Dark mode is perfect for live coding in night clubs.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1049"/>
+        <source>Audio</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1061"/>
+        <source>Editor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1062"/>
+        <source>Studio</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1064"/>
+        <location filename="../mainwindow.cpp" line="1074"/>
+        <source>Performance</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1065"/>
+        <source>Settings useful for performing with Sonic Pi</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1200"/>
+        <source>Server boot error...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1200"/>
+        <source>Sonic Pi Boot Error
+
+Apologies, a critical error occurred during startup</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1200"/>
+        <source>Please consider reporting a bug at</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1305"/>
+        <location filename="../mainwindow.cpp" line="1318"/>
+        <source>Buffer files(*.rb *.txt)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1306"/>
+        <source>Load Sonic-Pi Buffer</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1306"/>
+        <location filename="../mainwindow.cpp" line="1319"/>
+        <source>Buffer files(*.rb *.txt);;Text files (*.txt);;Ruby (*.rb);;All files (*.*)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1319"/>
+        <source>Save Current Buffer</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1390"/>
+        <source>Running Code...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1432"/>
+        <source>Zooming In...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1439"/>
+        <source>Zooming Out...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1446"/>
+        <source>Beautifying...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1466"/>
+        <source>Reloading...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1473"/>
+        <source>Checking for updates...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1481"/>
+        <source>Enabling update checking...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1489"/>
+        <source>Disabling update checking...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1497"/>
+        <source>Enabling Mixer HPF...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1506"/>
+        <source>Disabling Mixer HPF...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1514"/>
+        <source>Enabling Mixer LPF...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1523"/>
+        <source>Disabling Mixer LPF...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1531"/>
+        <source>Enabling Inverted Stereo...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1539"/>
+        <source>Enabling Standard Stereo...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1547"/>
+        <source>Mono Mode...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1555"/>
+        <source>Stereo Mode...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1564"/>
+        <source>Stopping...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1660"/>
+        <source>Updating System Volume...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1676"/>
+        <source>Log Auto Scroll on...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1678"/>
+        <source>Log Auto Scroll off...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1892"/>
+        <source>Switching To Headphone Audio Output...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1908"/>
+        <source>Switching To HDMI Audio Output...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="1923"/>
+        <source>Switching To Default Audio Output...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2074"/>
+        <source>Run</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2075"/>
+        <source>Run the code in the current buffer</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2080"/>
+        <source>Stop</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2081"/>
+        <source>Stop all running code</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2084"/>
+        <source>Save As...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2085"/>
+        <source>Save current buffer as an external file</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2088"/>
+        <source>Load</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2089"/>
+        <source>Load an external file in the current buffer</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2092"/>
+        <source>Info</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2093"/>
+        <source>See information about Sonic Pi</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2098"/>
+        <source>Toggle help pane</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2101"/>
+        <source>Prefs</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2102"/>
+        <source>Toggle preferences pane</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2106"/>
+        <location filename="../mainwindow.cpp" line="2234"/>
+        <location filename="../mainwindow.cpp" line="2235"/>
+        <source>Start Recording</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2107"/>
+        <source>Start recording to WAV audio file</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2111"/>
+        <source>Auto-Align Text</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2112"/>
+        <source>Improve readability of code</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2118"/>
+        <source>Increase Text Size</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2125"/>
+        <source>Decrease Text Size</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2130"/>
+        <source>Tools</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2180"/>
+        <source>About</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2181"/>
+        <source>Core Team</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2182"/>
+        <source>Contributors</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2183"/>
+        <source>Community</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2184"/>
+        <source>License</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2185"/>
+        <source>History</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2206"/>
+        <source>Sonic Pi - Info</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2226"/>
+        <location filename="../mainwindow.cpp" line="2227"/>
+        <source>Stop Recording</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2240"/>
+        <source>Save Recording</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2240"/>
+        <source>Wavefile (*.wav)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2259"/>
+        <source>Ready...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2337"/>
+        <source>Cannot read file %1:
+%2.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2348"/>
+        <source>File loaded...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2357"/>
+        <source>Cannot write file %1:
+%2.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2375"/>
+        <source>File saved...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2601"/>
+        <source>Last checked %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2603"/>
+        <source>Sonic Pi checks for updates
+every two weeks.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2605"/>
+        <source>This is Sonic Pi %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2606"/>
+        <source>Version %2 is now available!</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2610"/>
+        <source>New version available!
+Get Sonic Pi %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../mainwindow.cpp" line="2636"/>
+        <source>Welcome back. Now get your live code on...</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>QObject</name>
+    <message>
+        <location filename="../main.cpp" line="43"/>
+        <source>Sonic Pi</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>SonicPiUDPOSCServer</name>
+    <message>
+        <location filename="../sonic_pi_udp_osc_server.cpp" line="37"/>
+        <source>Is Sonic Pi already running?  Can't open UDP port 4558.</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+</TS>
diff --git a/app/gui/qt/main.cpp b/app/gui/qt/main.cpp
index 65fa12d..7405d39 100644
--- a/app/gui/qt/main.cpp
+++ b/app/gui/qt/main.cpp
@@ -3,7 +3,7 @@
 // Full project source: https://github.com/samaaron/sonic-pi
 // License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 //
-// Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 // All rights reserved.
 //
 // Permission is granted for use, copying, modification, and
diff --git a/app/gui/qt/mainwindow.cpp b/app/gui/qt/mainwindow.cpp
index 0af6cf7..f3c62bd 100644
--- a/app/gui/qt/mainwindow.cpp
+++ b/app/gui/qt/mainwindow.cpp
@@ -3,7 +3,7 @@
 // Full project source: https://github.com/samaaron/sonic-pi
 // License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 //
-// Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 // All rights reserved.
 //
 // Permission is granted for use, copying, modification, and
@@ -19,6 +19,7 @@
 #include <fstream>
 
 // Qt stuff
+#include <QSysInfo>
 #include <QDate>
 #include <QDesktopServices>
 #include <QDir>
@@ -58,7 +59,6 @@
 #include <QScrollArea>
 #include <QShortcut>
 #include <QToolButton>
-#include <QSettings>
 #include <QScrollBar>
 #include <QSignalMapper>
 #include <QSplitter>
@@ -74,8 +74,8 @@
 
 #include "oschandler.h"
 #include "sonicpilog.h"
-#include "sonicpiudpserver.h"
-#include "sonicpitcpserver.h"
+#include "sonic_pi_udp_osc_server.h"
+#include "sonic_pi_tcp_osc_server.h"
 
 // OSC stuff
 #include "oscpkt.hh"
@@ -102,85 +102,200 @@ MainWindow::MainWindow(QApplication &app, bool i18n, QMainWindow* splash)
 MainWindow::MainWindow(QApplication &app, bool i18n, QSplashScreen* splash)
 #endif
 {
-  QThreadPool::globalInstance()->setMaxThreadCount(3);
-  app.installEventFilter(this);
-  app.processEvents();
+  if (QCoreApplication::applicationDirPath().startsWith("/usr/bin/")) {
 
-  setupLogPathAndRedirectStdOut();
-  std::cout << "\n\n\n";
+    // use FHS directory scheme:
+    // Sonic Pi is installed in /usr/bin from a Linux distribution's package
+
+    ruby_path = "/usr/bin/ruby";
+    ruby_server_path = "/usr/lib/sonic-pi/server/bin/sonic-pi-server.rb";
+    sample_path = "/usr/share/sonic-pi/samples";
+
+  } else if (QCoreApplication::applicationDirPath().startsWith("/opt/")) {
+
+    // use /opt directory scheme:
+    // Sonic Pi is installed in /opt from the Raspbian .deb package
+
+    ruby_path = "/usr/bin/ruby";
+    ruby_server_path = "/opt/sonic-pi/server/bin/sonic-pi-server.rb";
+    sample_path = "/opt/sonic-pi/etc/samples";
+
+  } else {
+
+    // Sonic Pi is installed in the user's home directory
+    // or has been installed on Windows / OSX
+
+    QString root_path = rootPath();
+
+#if defined(Q_OS_WIN)
+    ruby_path = QDir::toNativeSeparators(root_path + "/app/server/native/windows/ruby/bin/ruby.exe");
+#elif defined(Q_OS_MAC)
+    ruby_path = root_path + "/server/native/osx/ruby/bin/ruby";
+#else
+    ruby_path = root_path + "/app/server/native/raspberry/ruby/bin/ruby";
+#endif
+
+    QFile file(ruby_path);
+    if(!file.exists()) {
+      // fallback to user's locally installed ruby
+      ruby_path = "ruby";
+    }
+
+    ruby_server_path = QDir::toNativeSeparators(root_path + "/app/server/bin/sonic-pi-server.rb");
+    sample_path = QDir::toNativeSeparators(root_path + "/etc/samples");
+
+  }
+
+  sp_user_path           = QDir::toNativeSeparators(sonicPiHomePath() + "/.sonic-pi");
+  sp_user_tmp_path       = QDir::toNativeSeparators(sp_user_path + "/.writableTesterPath");
+  log_path               = QDir::toNativeSeparators(sp_user_path + "/log");
+  server_error_log_path  = QDir::toNativeSeparators(log_path + "/server-errors.log");
+  server_output_log_path = QDir::toNativeSeparators(log_path + "/server-output.log");
+  gui_log_path           = QDir::toNativeSeparators(log_path + QDir::separator() + "gui.log");
+  scsynth_log_path       = QDir::toNativeSeparators(log_path + QDir::separator() + "scsynth.log");
+
+  QFile file(sp_user_tmp_path);
+  if (!file.open(QIODevice::WriteOnly)) {
+    homeDirWritable = false;
+  }
+  else {
+    homeDirWritable = true;
+    file.close();
+  }
 
-  guiID = QUuid::createUuid().toString();
   loaded_workspaces = false;
+  is_recording = false;
+  show_rec_icon_a = false;
+  restoreDocPane = false;
+  focusMode = false;
+  version = "2.10.0";
+  latest_version = "";
+  version_num = 0;
+  latest_version_num = 0;
   this->splash = splash;
-  protocol = UDP;
+  this->i18n = i18n;
+  guiID = QUuid::createUuid().toString();
+  QSettings settings("uk.ac.cam.cl", "Sonic Pi");
+  defaultTextBrowserStyle = "QTextBrowser { selection-color: white; selection-background-color: deeppink; padding-left:10; padding-top:10; padding-bottom:10; padding-right:10 ; background:white;}";
+
+  QThreadPool::globalInstance()->setMaxThreadCount(3);
+  app.installEventFilter(this);
+  app.processEvents();
 
+  protocol = UDP;
   if(protocol == TCP){
     clientSock = new QTcpSocket(this);
   }
 
-  this->i18n = i18n;
-
+  setupLogPathAndRedirectStdOut();
   printAsciiArtLogo();
 
-  startServer();
+  setupTheme();
+  lexer = new SonicPiLexer(theme);
 
-  setUnifiedTitleAndToolBarOnMac(true);
-  setWindowIcon(QIcon(":images/icon-smaller.png"));
+  setupWindowStructure();
+  createShortcuts();
+  createToolBar();
+  createStatusBar();
+  createInfoPane();
+  setWindowTitle(tr("Sonic Pi"));
+  initPrefsWindow();
+  readSettings();
+  updateTabsVisibility();
+  updateButtonVisibility();
+  updateLogVisibility();
+  initDocsWindow();
 
-  defaultTextBrowserStyle = "QTextBrowser { selection-color: white; selection-background-color: deeppink; padding-left:10; padding-top:10; padding-bottom:10; padding-right:10 ; background:white;}";
+  //setup autocompletion
+  autocomplete->loadSamples(sample_path);
 
-  is_recording = false;
-  show_rec_icon_a = false;
+  OscHandler* handler = new OscHandler(this, outputPane, errorPane, theme);
 
-  rec_flash_timer = new QTimer(this);
-  connect(rec_flash_timer, SIGNAL(timeout()), this, SLOT(toggleRecordingOnIcon()));
+  if(protocol == UDP){
+    sonicPiOSCServer = new SonicPiUDPOSCServer(this, handler);
+    osc_thread = QtConcurrent::run(sonicPiOSCServer, &SonicPiOSCServer::start);
+  }
+  else{
+    sonicPiOSCServer = new SonicPiTCPOSCServer(this, handler);
+    sonicPiOSCServer->start();
+  }
 
-  // Setup output and error panes
-  version = "";
-  latest_version = "";
-  version_num = 0;
-  latest_version_num = 0;
-  outputPane = new SonicPiLog;
-  errorPane = new QTextBrowser;
-  errorPane->setOpenExternalLinks(true);
 
-  update_info = new QLabel(tr("Sonic Pi update info"));
-  update_info->setWordWrap(true);
+  // Wait to hear back from the server before continuing
+  startRubyServer();
+  if (waitForServiceSync()){
+    // We have a connection! Finish up loading app...
 
-  // Syntax highlighting
+
+    loadWorkspaces();
+    requestVersion();
+
+    splashClose();
+
+
+    showWindow();
+    updateDarkMode();
+    updateFullScreenMode();
+    showWelcomeScreen();
+
+    connect(&app, SIGNAL( aboutToQuit() ), this, SLOT( onExitCleanup() ) );
+    QTimer *timer = new QTimer(this);
+    connect(timer, SIGNAL(timeout()), this, SLOT(heartbeatOSC()));
+    timer->start(1000);
+
+  }
+}
+
+void MainWindow::showWelcomeScreen() {
   QSettings settings("uk.ac.cam.cl", "Sonic Pi");
+if(settings.value("first_time", 1).toInt() == 1) {
+    QTextBrowser* startupPane = new QTextBrowser;
+    startupPane->setFixedSize(600, 615);
+    startupPane->setWindowIcon(QIcon(":images/icon-smaller.png"));
+    startupPane->setWindowTitle(tr("Welcome to Sonic Pi"));
+    addUniversalCopyShortcuts(startupPane);
+    startupPane->document()->setDefaultStyleSheet(readFile(":/theme/light/doc-styles.css"));
+    startupPane->setSource(QUrl("qrc:///html/startup.html"));
+    startupPane->setStyleSheet(defaultTextBrowserStyle);
+    docWidget->show();
+    startupPane->show();
+  }
+}
+
+void MainWindow::setupTheme() {
+
+  // Syntax highlighting
   QString themeFilename = QDir::homePath() + QDir::separator() + ".sonic-pi" + QDir::separator() + "theme.properties";
   QFile themeFile(themeFilename);
-  SonicPiTheme *theme;
   if(themeFile.exists()){
     std::cout << "[GUI] - using custom editor colours" << std::endl;
     QSettings settings(themeFilename, QSettings::IniFormat);
     theme = new SonicPiTheme(this, &settings, settings.value("prefs/dark-mode").toBool());
-    lexer = new SonicPiLexer(theme);
   }
   else{
+
     std::cout << "[GUI] - using default editor colours" << std::endl;
+    QSettings settings("uk.ac.cam.cl", "Sonic Pi");
     theme = new SonicPiTheme(this, 0, settings.value("prefs/dark-mode").toBool());
-    lexer = new SonicPiLexer(theme);
-  }
 
+  }
+}
 
+void MainWindow::setupWindowStructure() {
 
+  setUnifiedTitleAndToolBarOnMac(true);
+  setWindowIcon(QIcon(":images/icon-smaller.png"));
 
-  QTimer *timer = new QTimer(this);
-  connect(timer, SIGNAL(timeout()), this, SLOT(heartbeatOSC()));
-  timer->start(1000);
+  rec_flash_timer = new QTimer(this);
+  connect(rec_flash_timer, SIGNAL(timeout()), this, SLOT(toggleRecordingOnIcon()));
 
-  OscHandler* handler = new OscHandler(this, outputPane, errorPane, theme);
+  // Setup output and error panes
 
-  if(protocol == UDP){
-    sonicPiServer = new SonicPiUDPServer(this, handler);
-    osc_thread = QtConcurrent::run(sonicPiServer, &SonicPiServer::startServer);
-  }
-  else{
-    sonicPiServer = new SonicPiTCPServer(this, handler);
-    sonicPiServer->startServer();
-  }
+  outputPane = new SonicPiLog;
+  errorPane = new QTextBrowser;
+  errorPane->setOpenExternalLinks(true);
+  update_info = new QLabel(tr("Sonic Pi update info"));
+  update_info->setWordWrap(true);
 
   // Window layout
   tabs = new QTabWidget();
@@ -193,6 +308,7 @@ MainWindow::MainWindow(QApplication &app, bool i18n, QSplashScreen* splash)
   // create workspaces and add them to the tabs
   // workspace shortcuts
   signalMapper = new QSignalMapper (this) ;
+  retSignalMapper = new QSignalMapper (this) ;
   for(int ws = 0; ws < workspace_max; ws++) {
     std::string s;
 
@@ -204,6 +320,11 @@ MainWindow::MainWindow(QApplication &app, bool i18n, QSplashScreen* splash)
     connect (indentLine, SIGNAL(activated()), signalMapper, SLOT(map())) ;
     signalMapper -> setMapping (indentLine, (QObject*)workspace);
 
+    QShortcut *newLineAndIndent = new QShortcut(QKeySequence("Return"), workspace);
+    connect (newLineAndIndent, SIGNAL(activated()), retSignalMapper, SLOT(map())) ;
+    retSignalMapper -> setMapping (newLineAndIndent, (QObject*)workspace);
+
+
     //transpose chars
     QShortcut *transposeChars = new QShortcut(ctrlKey('t'), workspace);
     connect (transposeChars, SIGNAL(activated()), workspace, SLOT(transposeChars())) ;
@@ -248,12 +369,9 @@ MainWindow::MainWindow(QApplication &app, bool i18n, QSplashScreen* splash)
     //escape
     QShortcut *escape = new QShortcut(ctrlKey('g'), workspace);
     QShortcut *escape2 = new QShortcut(QKeySequence("Escape"), workspace);
-    connect(escape, SIGNAL(activated()), workspace, SLOT(escapeAndCancelSelection()));
-    connect(escape, SIGNAL(activated()), this, SLOT(resetErrorPane()));
-    connect(escape, SIGNAL(activated()), workspace, SLOT(clearLineMarkers()));
-    connect(escape2, SIGNAL(activated()), workspace, SLOT(escapeAndCancelSelection()));
-    connect(escape2, SIGNAL(activated()), this, SLOT(resetErrorPane()));
-    connect(escape2, SIGNAL(activated()), workspace, SLOT(clearLineMarkers()));
+    connect(escape, SIGNAL(activated()), this, SLOT(escapeWorkspaces()));
+    connect(escape2, SIGNAL(activated()), this, SLOT(escapeWorkspaces()));
+
 
     //quick nav by jumping up and down 10 lines at a time
     QShortcut *forwardTenLines = new QShortcut(shiftMetaKey('u'), workspace);
@@ -291,16 +409,15 @@ MainWindow::MainWindow(QApplication &app, bool i18n, QSplashScreen* splash)
     tabs->addTab(workspace, w);
   }
 
+  connect(retSignalMapper, SIGNAL(mapped(QObject*)), this, SLOT(returnAndIndentLine(QObject*)));
   connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(changeTab(int)));
-  connect(signalMapper, SIGNAL(mapped(QObject*)), this, SLOT(completeListOrIndentLine(QObject*)));
+  connect(signalMapper, SIGNAL(mapped(QObject*)), this, SLOT(completeSnippetListOrIndentLine(QObject*)));
 
   QFont font("Monospace");
   font.setStyleHint(QFont::Monospace);
   lexer->setDefaultFont(font);
 
   autocomplete = new SonicPiAPIs(lexer);
-  autocomplete->loadSamples(sample_path);
-
   // adding universal shortcuts to outputpane seems to
   // steal events from doc system!?
   // addUniversalCopyShortcuts(outputPane);
@@ -429,51 +546,15 @@ MainWindow::MainWindow(QApplication &app, bool i18n, QSplashScreen* splash)
   mainWidget->setLayout(mainWidgetLayout);
   setCentralWidget(mainWidget);
 
-  createShortcuts();
-  createToolBar();
-  createStatusBar();
-  createInfoPane();
-
-  readSettings();
-
-
-  setWindowTitle(tr("Sonic Pi"));
-
-  connect(&app, SIGNAL( aboutToQuit() ), this, SLOT( onExitCleanup() ) );
-
-
+}
 
-  initPrefsWindow();
+void MainWindow::escapeWorkspaces() {
+  resetErrorPane();
 
-  if(settings.value("first_time", 1).toInt() == 1) {
-    QTextBrowser* startupPane = new QTextBrowser;
-    startupPane->setFixedSize(600, 615);
-    startupPane->setWindowIcon(QIcon(":images/icon-smaller.png"));
-    startupPane->setWindowTitle(tr("Welcome to Sonic Pi"));
-    addUniversalCopyShortcuts(startupPane);
-    startupPane->document()->setDefaultStyleSheet(readFile(":/theme/light/doc-styles.css"));
-    startupPane->setSource(QUrl("qrc:///html/startup.html"));
-    startupPane->setStyleSheet(defaultTextBrowserStyle);
-    docWidget->show();
-    startupPane->show();
+  for (int w=0; w < workspace_max; w++) {
+    workspaces[w]->escapeAndCancelSelection();
+    workspaces[w]->clearLineMarkers();
   }
-
-  restoreDocPane = false;
-
-  focusMode = false;
-
-  // Wait to hear back from the server before continuing
-  waitForServiceSync();
-  serverStarted();
-
-  updateDarkMode();
-  initDocsWindow();
-  updateFullScreenMode();
-  updateTabsVisibility();
-  updateButtonVisibility();
-  updateLogVisibility();
-
-  requestVersion();
 }
 
 void MainWindow::changeTab(int id){
@@ -548,7 +629,6 @@ void MainWindow::updateLogVisibility(){
   }
 }
 
-
 void MainWindow::toggleTabsVisibility() {
   show_tabs->toggle();
   updateTabsVisibility();
@@ -581,17 +661,53 @@ void MainWindow::updateButtonVisibility(){
   }
 }
 
-void MainWindow::completeListOrIndentLine(QObject* ws){
+void MainWindow::completeSnippetListOrIndentLine(QObject* ws){
   SonicPiScintilla *spws = ((SonicPiScintilla*)ws);
   if(spws->isListActive()) {
     spws->tabCompleteifList();
   }
   else {
-    indentCurrentLineOrSelection(spws);
+    completeSnippetOrIndentCurrentLineOrSelection(spws);
   }
 }
 
-void MainWindow::indentCurrentLineOrSelection(SonicPiScintilla* ws) {
+
+void MainWindow::returnAndIndentLine(QObject* ws){
+  SonicPiScintilla *spws = ((SonicPiScintilla*)ws);
+
+  if(spws->isListActive()) {
+    spws->tabCompleteifList();
+  }
+  else {
+    if(auto_indent_on_run->isChecked()) {
+      newlineAndIndent(spws);
+    } else {
+      spws->newLine();
+    }
+  }
+}
+
+
+
+void MainWindow::newlineAndIndent(SonicPiScintilla* ws) {
+  int point_line, point_index, first_line;
+  ws->getCursorPosition(&point_line, &point_index);
+  first_line = ws->firstVisibleLine();
+
+  std::string code = ws->text().toStdString();
+
+  Message msg("/buffer-newline-and-indent");
+  msg.pushStr(guiID.toStdString());
+  std::string filename = workspaceFilename(ws);
+  msg.pushStr(filename);
+  msg.pushStr(code);
+  msg.pushInt32(point_line);
+  msg.pushInt32(point_index);
+  msg.pushInt32(first_line);
+  sendOSC(msg);
+}
+
+void MainWindow::completeSnippetOrIndentCurrentLineOrSelection(SonicPiScintilla* ws) {
   int start_line, finish_line, point_line, point_index;
   ws->getCursorPosition(&point_line, &point_index);
   if(ws->hasSelectedText()) {
@@ -607,7 +723,7 @@ void MainWindow::indentCurrentLineOrSelection(SonicPiScintilla* ws) {
 
   std::string code = ws->text().toStdString();
 
-  Message msg("/complete-snippet-or-indent-selection");
+  Message msg("/buffer-section-complete-snippet-or-indent-selection");
   msg.pushStr(guiID.toStdString());
   std::string filename = workspaceFilename(ws);
   msg.pushStr(filename);
@@ -628,11 +744,11 @@ void MainWindow::toggleComment(SonicPiScintilla* ws) {
   int start_line, finish_line, point_line, point_index;
   ws->getCursorPosition(&point_line, &point_index);
   if(ws->hasSelectedText()) {
-    statusBar()->showMessage(tr("Commenting selection..."), 2000);
+    statusBar()->showMessage(tr("Toggle selection comment..."), 2000);
     int unused_a, unused_b;
     ws->getSelection(&start_line, &unused_a, &finish_line, &unused_b);
   } else {
-    statusBar()->showMessage(tr("Commenting line..."), 2000);
+    statusBar()->showMessage(tr("Toggle line comment..."), 2000);
     start_line = point_line;
     finish_line = point_line;
   }
@@ -640,7 +756,7 @@ void MainWindow::toggleComment(SonicPiScintilla* ws) {
 
   std::string code = ws->text().toStdString();
 
-  Message msg("/toggle-comment");
+  Message msg("/buffer-section-toggle-comment");
   msg.pushStr(guiID.toStdString());
   std::string filename = workspaceFilename(ws);
   msg.pushStr(filename);
@@ -663,7 +779,7 @@ QString MainWindow::rootPath() {
 #endif
 }
 
-void MainWindow::startServer(){
+void MainWindow::startRubyServer(){
 
   // kill any zombie processes that may exist
   // better: test to see if UDP ports are in use, only kill/sleep if so
@@ -674,78 +790,75 @@ void MainWindow::startServer(){
   sendOSC(msg);
   sleep(2);
 
+  serverProcess = new QProcess();
 
-    serverProcess = new QProcess();
-
-    QString root = rootPath();
-
-  #if defined(Q_OS_WIN)
-    QString prg_path = root + "/app/server/native/windows/ruby/bin/ruby.exe";
-    QString prg_arg = root + "/app/server/bin/sonic-pi-server.rb";
-    sample_path = root + "/etc/samples";
-  #elif defined(Q_OS_MAC)
-    QString prg_path = root + "/server/native/osx/ruby/bin/ruby";
-    QString prg_arg = root + "/server/bin/sonic-pi-server.rb";
-    sample_path = root + "/etc/samples";
-  #else
-    //assuming Raspberry Pi
-    QString prg_path = root + "/app/server/native/raspberry/ruby/bin/ruby";
-    QFile file(prg_path);
-    if(!file.exists()) {
-      // use system ruby if bundled ruby doesn't exist
-      prg_path = "/usr/bin/ruby";
-    }
-
-    QString prg_arg = root + "/app/server/bin/sonic-pi-server.rb";
-    sample_path = root + "/etc/samples";
-  #endif
-
-    prg_path = QDir::toNativeSeparators(prg_path);
-    prg_arg = QDir::toNativeSeparators(prg_arg);
+  QStringList args;
+  args << ruby_server_path;
 
+  if(protocol == TCP){
+    args << "-t";
+  }
 
-    QStringList args;
-    args << prg_arg;
+  std::cout << "[GUI] - booting live coding server" << std::endl;
+  if(homeDirWritable) {
+    serverProcess->setStandardErrorFile(server_error_log_path);
+    serverProcess->setStandardOutputFile(server_output_log_path);
+  }
+  serverProcess->start(ruby_path, args);
+  if (!serverProcess->waitForStarted()) {
+    invokeStartupError(tr("The Sonic Pi server could not be started!"));
+    return;
+  }
+}
 
-    if(protocol == TCP){
-        args << "-t";
+bool MainWindow::waitForServiceSync() {
+  QString contents;
+  std::cout << "[GUI] - waiting for server to boot..." << std::endl;
+  bool server_booted = false;
+  if (!homeDirWritable) {
+    // we can't monitor the logs so hope for the best!
+    sleep(15);
+    server_booted = true;
+  } else {
+    for(int i = 0; i < 60; i ++) {
+      contents = readFile(server_output_log_path);
+      if (contents.contains("Sonic Pi Server successfully booted.")) {
+        std::cout << std::endl << "[GUI] - server successfully booted." << std::endl;
+        server_booted = true;
+        break;
+      } else {
+        std::cout << ".";
+        sleep(1);
+      }
     }
+  }
 
+  if (!server_booted) {
+      std::cout << std::endl << "[GUI] - Critical error! Could not boot server." << std::endl;
+      invokeStartupError("Critical server error - could not boot server!");
+      return false;
+  }
 
-
-    //    std::cout << "[GUI] - exec "<< prg_path.toStdString() << " " << prg_arg.toStdString() << std::endl;
-
-    std::cout << "[GUI] - booting live coding server" << std::endl;
-    QString sp_error_log_path = log_path + QDir::separator() + "server-errors.log";
-    QString sp_output_log_path = log_path + QDir::separator() + "server-output.log";
-    serverProcess->setStandardErrorFile(sp_error_log_path);
-    serverProcess->setStandardOutputFile(sp_output_log_path);
-    serverProcess->start(prg_path, args);
-    if (!serverProcess->waitForStarted()) {
-      invokeStartupError(tr("The Sonic Pi server could not be started!"));
-      return;
-    }
-}
-
-void MainWindow::waitForServiceSync() {
   int timeout = 60;
   std::cout << "[GUI] - waiting for server to connect..." << std::endl;
-  while (sonicPiServer->waitForServer() && timeout-- > 0) {
+  while (sonicPiOSCServer->waitForServer() && timeout-- > 0) {
     sleep(1);
-    if(sonicPiServer->isIncomingPortOpen()) {
+    if(sonicPiOSCServer->isIncomingPortOpen()) {
       Message msg("/ping");
       msg.pushStr(guiID.toStdString());
       msg.pushStr("QtClient/1/hello");
       sendOSC(msg);
     }
   }
-  if (!sonicPiServer->isServerStarted()) {
-      std::cout << "[GUI] - critical error!" << std::endl;
-      invokeStartupError("Critical server error!");
+  if (!sonicPiOSCServer->isServerStarted()) {
+      std::cout << "[GUI] - Critical error! Could not connect to server." << std::endl;
+      invokeStartupError("Critical server error - could not connect to server!");
+      return false;
+  } else {
+    std::cout << "[GUI] - server connection established" << std::endl;
+    return true;
   }
 
-  std::cout << "[GUI] - server connection established" << std::endl;
-
 }
 
 void MainWindow::splashClose() {
@@ -756,12 +869,8 @@ void MainWindow::splashClose() {
 #endif
 }
 
-void MainWindow::serverStarted() {
-  splashClose();
-  loadWorkspaces();
-
+void MainWindow::showWindow() {
   QSettings settings("uk.ac.cam.cl", "Sonic Pi");
-
   if(settings.value("first_time", 1).toInt() == 1) {
     showMaximized();
   } else {
@@ -809,20 +918,17 @@ void MainWindow::initPrefsWindow() {
 
   QGroupBox *advancedAudioBox = new QGroupBox(tr("Advanced Audio"));
   advancedAudioBox->setToolTip(tr("Advanced audio settings for working with\nexternal PA systems when performing with Sonic Pi."));
-  mixer_invert_stereo = new QCheckBox(tr("Invert Stereo"));
+  mixer_invert_stereo = new QCheckBox(tr("Invert stereo"));
   mixer_invert_stereo->setToolTip(tr("Toggle stereo inversion.\nIf enabled, audio sent to the left speaker will\nbe routed to the right speaker and visa versa."));
   connect(mixer_invert_stereo, SIGNAL(clicked()), this, SLOT(update_mixer_invert_stereo()));
-  mixer_force_mono = new QCheckBox(tr("Force Mono"));
+  mixer_force_mono = new QCheckBox(tr("Force mono"));
   mixer_force_mono->setToolTip(tr("Toggle mono mode.\nIf enabled both right and left audio is mixed and\nthe same signal is sent to both speakers.\nUseful when working with external systems that\ncan only handle mono."));
   connect(mixer_force_mono, SIGNAL(clicked()), this, SLOT(update_mixer_force_mono()));
 
-  check_args = new QCheckBox(tr("Safe mode"));
-  check_args->setToolTip(tr("Toggle synth argument checking functions.\nIf disabled, certain synth opt values may\ncreate unexpectedly loud or uncomfortable sounds."));
-
   QVBoxLayout *advanced_audio_box_layout = new QVBoxLayout;
   advanced_audio_box_layout->addWidget(mixer_invert_stereo);
   advanced_audio_box_layout->addWidget(mixer_force_mono);
-  advanced_audio_box_layout->addWidget(check_args);
+
   // audio_box->addWidget(radio2);
   // audio_box->addWidget(radio3);
   // audio_box->addStretch(1);
@@ -856,6 +962,9 @@ void MainWindow::initPrefsWindow() {
   QGroupBox *debug_box = new QGroupBox(tr("Logging"));
   debug_box->setToolTip(tr("Configure debug behaviour"));
 
+  QGroupBox *synths_box = new QGroupBox(tr("Synths and FX"));
+  synths_box->setToolTip(tr("Modify behaviour of synths and FX"));
+
   print_output = new QCheckBox(tr("Log synths"));
   print_output->setToolTip(tr("Toggle log messages.\nIf disabled, activity such as synth and sample\ntriggering will not be printed to the log by default."));
 
@@ -865,12 +974,34 @@ void MainWindow::initPrefsWindow() {
   log_cues = new QCheckBox(tr("Log cues"));
   log_cues->setToolTip(tr("Enable or disable logging of cues.\nIf disabled, cues will still trigger.\nHowever, they will not be visible in the logs."));
 
+  log_auto_scroll = new QCheckBox(tr("Log auto scroll"));
+  log_auto_scroll->setToolTip(tr("Toggle log auto scrolling.\nIf enabled the log is scrolled to the botton after every new message is displayed."));
+  connect(log_auto_scroll, SIGNAL(clicked()), this, SLOT(updateLogAutoScroll()));
+
+  check_args = new QCheckBox(tr("Safe mode"));
+  check_args->setToolTip(tr("Toggle synth argument checking functions.\nIf disabled, certain synth opt values may\ncreate unexpectedly loud or uncomfortable sounds."));
+
+
+  enable_external_synths_cb = new QCheckBox(tr("Enable external synths and FX"));
+  enable_external_synths_cb->setToolTip(tr("When enabled, Sonic Pi will allow\nsynths and FX loaded via load_synthdefs\nto be triggered.\n\nWhen disabled, Sonic Pi will complain\nwhen you attempt to use a synth or FX\nwhich isn't recognised."));
+
+  synth_trigger_timing_guarantees_cb = new QCheckBox(tr("Enforce timing guarantees"));
+  synth_trigger_timing_guarantees_cb->setToolTip(tr("When enabled, Sonic Pi will refuse\nto trigger synths and FX if\nit is too late to do so\n\nWhen disabled, Sonic Pi will always\nattemptto trigger synths and FX\neven when a little late."));
+
   QVBoxLayout *debug_box_layout = new QVBoxLayout;
   debug_box_layout->addWidget(print_output);
   debug_box_layout->addWidget(log_cues);
+  debug_box_layout->addWidget(log_auto_scroll);
   debug_box_layout->addWidget(clear_output_on_run);
   debug_box->setLayout(debug_box_layout);
 
+  QVBoxLayout *synths_box_layout = new QVBoxLayout;
+  synths_box_layout->addWidget(check_args);
+  synths_box_layout->addWidget(synth_trigger_timing_guarantees_cb);
+  synths_box_layout->addWidget(enable_external_synths_cb);
+
+
+  synths_box->setLayout(synths_box_layout);
 
   QGroupBox *transparency_box = new QGroupBox(tr("Transparency"));
   QGridLayout *transparency_box_layout = new QGridLayout;
@@ -893,7 +1024,7 @@ void MainWindow::initPrefsWindow() {
   visit_sonic_pi_net = new QPushButton(tr("Get update"));
   visit_sonic_pi_net->setToolTip(tr("Visit http://sonic-pi.net to download new version"));
   visit_sonic_pi_net->setVisible(false);
-  check_updates_now->setMaximumWidth(100);
+  check_updates_now->setMaximumWidth(110);
   visit_sonic_pi_net->setMaximumWidth(150);
 
   QGroupBox *update_info_box = new QGroupBox(tr("Update Info"));
@@ -980,12 +1111,12 @@ void MainWindow::initPrefsWindow() {
   prefTabs->addTab(audio_prefs_box, tr("Audio"));
 #endif
 
-    QGroupBox *studio_prefs_box = new QGroupBox();
+  QGroupBox *studio_prefs_box = new QGroupBox();
   QGridLayout *studio_prefs_box_layout = new QGridLayout;
 
-  studio_prefs_box_layout->addWidget(advancedAudioBox, 0, 0);
-
+  studio_prefs_box_layout->addWidget(synths_box, 0, 0);
   studio_prefs_box_layout->addWidget(debug_box, 0, 1);
+  studio_prefs_box_layout->addWidget(advancedAudioBox, 1, 1);
 
   studio_prefs_box->setLayout(studio_prefs_box_layout);
 
@@ -1045,7 +1176,10 @@ void MainWindow::initPrefsWindow() {
   print_output->setChecked(settings.value("prefs/print-output", true).toBool());
   clear_output_on_run->setChecked(settings.value("prefs/clear-output-on-run", true).toBool());
   log_cues->setChecked(settings.value("prefs/log-cues", true).toBool());
+  log_auto_scroll->setChecked(settings.value("prefs/log-auto-scroll", true).toBool());
   show_line_numbers->setChecked(settings.value("prefs/show-line-numbers", true).toBool());
+  enable_external_synths_cb->setChecked(settings.value("prefs/enable-external-synths", false).toBool());
+  synth_trigger_timing_guarantees_cb->setChecked(settings.value("prefs/synth-trigger-timing-guarantees", false).toBool());
   dark_mode->setChecked(settings.value("prefs/dark-mode", false).toBool());
   mixer_force_mono->setChecked(settings.value("prefs/mixer-force-mono", false).toBool());
   mixer_invert_stereo->setChecked(settings.value("prefs/mixer-invert-stereo", false).toBool());
@@ -1068,6 +1202,7 @@ void MainWindow::initPrefsWindow() {
   update_mixer_force_mono();
   changeRPSystemVol(stored_vol);
   update_check_updates();
+  updateLogAutoScroll();
 
   if(settings.value("prefs/rp/force-audio-default", true).toBool()) {
     setRPSystemAudioAuto();
@@ -1082,9 +1217,23 @@ void MainWindow::initPrefsWindow() {
 
 }
 
+void MainWindow::setMessageBoxStyle() {
+  // Set text color to black and background colors to white for the error message display
+  QPalette p = QApplication::palette();
+  p.setColor(QPalette::WindowText,"#000");
+  p.setColor(QPalette::ButtonText,"#000");
+  p.setColor(QPalette::Text,"#000");
+  p.setColor(QPalette::Base,"#FFF");
+  QApplication::setPalette(p);
+}
+
 void MainWindow::invokeStartupError(QString msg) {
+  if(startup_error_reported) {
+    return;
+  }
+
   startup_error_reported = true;
-  sonicPiServer->stopServer();
+  sonicPiOSCServer->stop();
   QMetaObject::invokeMethod(this, "startupError",
 			    Qt::QueuedConnection,
 			    Q_ARG(QString, msg));
@@ -1093,28 +1242,40 @@ void MainWindow::invokeStartupError(QString msg) {
 void MainWindow::startupError(QString msg) {
   splashClose();
 
-  QString gui_log = readFile(log_path + QDir::separator() + "gui.log");
-  QString server_errors_log = readFile(log_path + QDir::separator() + "server-errors.log");
-  QString server_output_log = readFile(log_path + QDir::separator() + "server-output.log");
+  setMessageBoxStyle();
+  QString gui_log;
+  QString scsynth_log;
+  QString server_output_log;
+  QString server_error_log;
+  if(homeDirWritable) {
+    gui_log = readFile(gui_log_path);
+    scsynth_log = readFile(scsynth_log_path);
+    server_output_log = readFile(server_output_log_path);
+    server_error_log = readFile(server_error_log_path);
+  }
+  else {
+    gui_log = "Permissions error: unable to access log";
+    scsynth_log = "Permissions error: unable to access log";
+    server_output_log = "Permissions error: unable to access log";
+    server_error_log = "Permissions error: unable to access log";
+  }
 
   QMessageBox *box = new QMessageBox(QMessageBox::Warning,
-				     tr("Server boot error..."), tr("Apologies, a critical error occurred during startup") + ":\n\n " + msg + "\n\n" + tr("Please consider reporting a bug at") + "\nhttp://github.com/samaaron/sonic-pi/issues");
-  QString error_report = "Detailed Error Report:\n\nGUI log\n-------\n" + gui_log + "\n\n\nServer Errors\n-------------\n\n" + server_errors_log + "\n\n\nServer Output\n-------------\n\n" + server_output_log;
+				     tr("Server boot error..."), tr("Sonic Pi Boot Error\n\nApologies, a critical error occurred during startup") + ":\n\n " + msg + "\n\n" + tr("Please consider reporting a bug at") + "\nhttp://github.com/samaaron/sonic-pi/issues");
+  QString error_report = "Sonic Pi Boot Error Report\n==================\n\n\nSystem Information\n----------------\n\n* Sonic Pi version: " + version + "\n* OS: " + osDescription() + "\n\n\nGUI Log\n-------\n\n**" + gui_log_path + "**\n```\n" + gui_log + "\n```\n\n\nServer Errors\n-------------\n\n**" + server_error_log_path + "**\n```\n" + server_error_log + "\n```\n\n\nServer Output\n-------------\n\n**" + server_output_log_path + "**\n```\n" + server_output_log + "\n```\n\n\nScsynth Output\n--------------\n\n**" + scsynth_log_path + "**\n```\n" + scsynth_log + "\n```\n";
   box->setDetailedText(error_report);
 
   QGridLayout* layout = (QGridLayout*)box->layout();
   QSpacerItem* hSpacer = new QSpacerItem(200, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
   layout->addItem(hSpacer, layout->rowCount(), 0, 1, layout->columnCount());
   box->exec();
+  std::cout << "[GUI] - Aborting. Sorry about this." << std::endl;
   close();
 }
 
 void MainWindow::replaceBuffer(QString id, QString content, int line, int index, int first_line) {
   SonicPiScintilla* ws = filenameToWorkspace(id.toStdString());
-  ws->selectAll();
-  ws->replaceSelectedText(content);
-  ws->setCursorPosition(line, index);
-  ws->setFirstVisibleLine(first_line);
+  ws->replaceBuffer(content, line, index, first_line);
 }
 
 void MainWindow::replaceLines(QString id, QString content, int start_line, int finish_line, int point_line, int point_index) {
@@ -1123,6 +1284,16 @@ void MainWindow::replaceLines(QString id, QString content, int start_line, int f
   ws->setCursorPosition(point_line, point_index);
 }
 
+QString MainWindow::osDescription() {
+#if QT_VERSION >= 0x050400
+  return QSysInfo::prettyProductName();
+#else
+  // prettyProductName requires QT 5.4
+  //
+  return QString("Assuming Linux");
+#endif
+}
+
 std::string MainWindow::number_name(int i) {
   switch(i) {
   case 0: return "zero";
@@ -1190,9 +1361,24 @@ QString MainWindow::currentTabLabel()
 }
 
 
+bool MainWindow::loadFile()
+{
+  QString selfilter = QString("%1 (*.rb *.txt)").arg(tr("Buffer files"));
+  QString fileName = QFileDialog::getOpenFileName(this, tr("Load Sonic Pi Buffer"), QDir::homePath() + "/Desktop", QString("%1 (*.rb *.txt);;%2 (*.txt);;%3 (*.rb);;%4 (*.*)").arg(tr("Buffer files")).arg(tr("Text files")).arg(tr("Ruby files")).arg(tr("All files")), &selfilter) ;
+  if(!fileName.isEmpty()){
+    SonicPiScintilla* p = (SonicPiScintilla*)tabs->currentWidget();
+    loadFile(fileName, p);
+    return true;
+  } else {
+    return false;
+  }
+}
+
 bool MainWindow::saveAs()
 {
-  QString fileName = QFileDialog::getSaveFileName(this, tr("Save Current Buffer"), QDir::homePath() + "/Desktop");
+  QString selfilter = QString("%1 (*.rb *.txt)").arg(tr("Buffer files"));
+  QString fileName = QFileDialog::getSaveFileName(this, tr("Save Current Buffer"), QDir::homePath() + "/Desktop", QString("%1 (*.rb *.txt);;%2 (*.txt);;%3 (*.rb);;%4 (*.*)").arg(tr("Buffer files")).arg(tr("Text files")).arg(tr("Ruby files")).arg(tr("All files")), &selfilter) ;
+
   if(!fileName.isEmpty()){
     if (!fileName.contains(QRegExp("\\.[a-z]+$"))) {
         fileName = fileName + ".txt";
@@ -1269,27 +1455,33 @@ void MainWindow::runCode()
   msg.pushStr(guiID.toStdString());
   std::string filename = workspaceFilename( (SonicPiScintilla*)tabs->currentWidget());
   msg.pushStr(filename);
+
   if(!print_output->isChecked()) {
     code = "use_debug false #__nosave__ set by Qt GUI user preferences.\n" + code ;
   }
+
   if(!log_cues->isChecked()) {
     code = "use_cue_logging false #__nosave__ set by Qt GUI user preferences.\n" + code ;
   }
-  else{
-    code = "use_debug true #__nosave__ set by Qt GUI user preferences.\n" + code ;
+
+  if(check_args->isChecked()) {
+    code = "use_arg_checks true #__nosave__ set by Qt GUI user preferences.\n" + code ;
   }
-  if(!check_args->isChecked()) {
-    code = "use_arg_checks false #__nosave__ set by Qt GUI user preferences.\n" + code ;
+
+  if(enable_external_synths_cb->isChecked()) {
+     code = "use_external_synths true #__nosave__ set by Qt GUI user preferences.\n" + code ;
   }
-  else {
-    code = "use_arg_checks true #__nosave__ set by Qt GUI user preferences.\n" + code ;
+
+  if(synth_trigger_timing_guarantees_cb->isChecked()) {
+     code = "use_timing_guarantees true #__nosave__ set by Qt GUI user preferences.\n" + code ;
   }
+
   if(clear_output_on_run->isChecked()){
     outputPane->clear();
   }
 
   msg.pushStr(code);
-  msg.pushStr(QString(tr("Workspace %1")).arg(tabs->currentIndex()).toStdString());
+  msg.pushStr(filename);
   sendOSC(msg);
 
   QTimer::singleShot(500, this, SLOT(unhighlightCode()));
@@ -1326,7 +1518,7 @@ void MainWindow::beautifyCode()
   int index = 0;
   ws->getCursorPosition(&line, &index);
   int first_line = ws->firstVisibleLine();
-  Message msg("/beautify-buffer");
+  Message msg("/buffer-beautify");
   msg.pushStr(guiID.toStdString());
   std::string filename = workspaceFilename( (SonicPiScintilla*)tabs->currentWidget());
   msg.pushStr(filename);
@@ -1473,15 +1665,7 @@ void MainWindow::helpContext()
     int line, pos;
     ws->getCursorPosition(&line, &pos);
     QString text = ws->text(line);
-    int start, end;
-    for (start = pos; start > 0; start--) {
-      if (!text[start-1].isLetter() && text[start-1] != '_') break;
-    }
-    QString identifierEndChars = QString("?!_=");
-    for (end = pos; end < text.length(); end++) {
-      if (!text[end].isLetter() && !identifierEndChars.contains(text[end])) break;
-    }
-    selection = text.mid(start, end-start);
+    selection = ws->wordAtLineIndex(line, pos);
   }
   selection = selection.toLower();
   if (selection[0] == ':')
@@ -1489,9 +1673,19 @@ void MainWindow::helpContext()
 
   if (helpKeywords.contains(selection)) {
     struct help_entry entry = helpKeywords[selection];
-    QMetaObject::invokeMethod(docsCentral, "setCurrentIndex",
-			      Q_ARG(int, entry.pageIndex));
     QListWidget *list = helpLists[entry.pageIndex];
+
+    // force current row to be changed
+    // by setting it to a different value to
+    // entry.entryIndex and then setting it
+    // back. That way it always gets displayed
+    // in the GUI :-)
+    if (entry.entryIndex == 0) {
+      list->setCurrentRow(1);
+    } else {
+      list->setCurrentRow(0);
+    }
+    docsCentral->setCurrentIndex(entry.pageIndex);
     list->setCurrentRow(entry.entryIndex);
   }
 }
@@ -1545,6 +1739,16 @@ void MainWindow::toggleDarkMode() {
   updateDarkMode();
 }
 
+void MainWindow::updateLogAutoScroll() {
+  bool val = log_auto_scroll->isChecked();
+  outputPane->forceScrollDown(val);
+  if(val) {
+    statusBar()->showMessage(tr("Log Auto Scroll on..."), 2000);
+    } else {
+    statusBar()->showMessage(tr("Log Auto Scroll off..."), 2000);
+  }
+ }
+
 void MainWindow::updateDarkMode(){
   SonicPiTheme *currentTheme = lexer->theme;
 
@@ -1923,7 +2127,7 @@ void MainWindow::createShortcuts()
 
   new QShortcut(metaKey('{'), this, SLOT(tabPrev()));
   new QShortcut(metaKey('}'), this, SLOT(tabNext()));
-  //new QShortcut(metaKey('U'), this, SLOT(reloadServerCode()));
+  new QShortcut(QKeySequence("F8"), this, SLOT(reloadServerCode()));
 
   new QShortcut(QKeySequence("F9"), this, SLOT(toggleButtonVisibility()));
   new QShortcut(shiftMetaKey('B'), this, SLOT(toggleButtonVisibility()));
@@ -1950,6 +2154,10 @@ void MainWindow::createToolBar()
   QAction *saveAsAct = new QAction(QIcon(":/images/save.png"), tr("Save As..."), this);
   setupAction(saveAsAct, 0, tr("Save current buffer as an external file"), SLOT(saveAs()));
 
+  // Load
+  QAction *loadFileAct = new QAction(QIcon(":/images/load.png"), tr("Load"), this);
+  setupAction(loadFileAct, 0, tr("Load an external file in the current buffer"), SLOT(loadFile()));
+
   // Info
   QAction *infoAct = new QAction(QIcon(":/images/info.png"), tr("Info"), this);
   setupAction(infoAct, 0, tr("See information about Sonic Pi"),
@@ -1975,13 +2183,16 @@ void MainWindow::createToolBar()
 
   // Font Size Increase
   QAction *textIncAct = new QAction(QIcon(":/images/size_up.png"),
-			    tr("Increase Text Size"), this);
-  setupAction(textIncAct, 0, tr("Increase Text Size"), SLOT(zoomCurrentWorkspaceIn()));
+			    tr(""), this);
+  setupAction(textIncAct, 0, tr(""), SLOT(zoomCurrentWorkspaceIn()));
+  textIncAct->setToolTip(tooltipStrMeta('+', tr("Increase Text Size")));
 
   // Font Size Decrease
   QAction *textDecAct = new QAction(QIcon(":/images/size_down.png"),
-			    tr("Decrease Text Size"), this);
-  setupAction(textDecAct, 0, tr("Decrease Text Size"), SLOT(zoomCurrentWorkspaceOut()));
+			    tr(""), this);
+
+  setupAction(textDecAct, 0, tr(""), SLOT(zoomCurrentWorkspaceOut()));
+  textDecAct->setToolTip(tooltipStrMeta('-', tr("Decrease Text Size")));
 
   QWidget *spacer = new QWidget();
   spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
@@ -1991,13 +2202,16 @@ void MainWindow::createToolBar()
   toolBar->setIconSize(QSize(270/3, 111/3));
   toolBar->addAction(runAct);
   toolBar->addAction(stopAct);
-
-  toolBar->addAction(saveAsAct);
   toolBar->addAction(recAct);
+
   toolBar->addWidget(spacer);
 
+  toolBar->addAction(saveAsAct);
+  toolBar->addAction(loadFileAct);
+
   toolBar->addAction(textDecAct);
   toolBar->addAction(textIncAct);
+
   dynamic_cast<QToolButton*>(toolBar->widgetForAction(textDecAct))->setAutoRepeat(true);
   dynamic_cast<QToolButton*>(toolBar->widgetForAction(textIncAct))->setAutoRepeat(true);
 
@@ -2093,7 +2307,7 @@ void MainWindow::toggleRecording() {
     Message msg("/stop-recording");
     msg.pushStr(guiID.toStdString());
     sendOSC(msg);
-    QString fileName = QFileDialog::getSaveFileName(this, tr("Save Recording"), QDir::homePath() + "/Desktop/my-recording.wav");
+    QString fileName = QFileDialog::getSaveFileName(this, tr("Save Recording"), QDir::homePath() + "/Desktop", tr("Wavefile (*.wav)"));
     if (!fileName.isEmpty()) {
       Message msg("/save-recording");
       msg.pushStr(guiID.toStdString());
@@ -2118,7 +2332,6 @@ void MainWindow::createStatusBar()
 
 void MainWindow::readSettings() {
   // Pref settings are read in MainWindow::initPrefsWindow()
-
   QSettings settings("uk.ac.cam.cl", "Sonic Pi");
   QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
   QSize size = settings.value("size", QSize(400, 400)).toSize();
@@ -2159,10 +2372,14 @@ void MainWindow::writeSettings()
   settings.setValue("prefs/print-output", print_output->isChecked());
   settings.setValue("prefs/clear-output-on-run", clear_output_on_run->isChecked());
   settings.setValue("prefs/log-cues", log_cues->isChecked());
+  settings.setValue("prefs/log-auto-scroll", log_auto_scroll->isChecked());
   settings.setValue("prefs/show-line-numbers", show_line_numbers->isChecked());
+  settings.setValue("prefs/enable-external-synths", enable_external_synths_cb->isChecked());
+  settings.setValue("prefs/synth-trigger-timing-guarantees", synth_trigger_timing_guarantees_cb->isChecked());
   settings.setValue("prefs/dark-mode", dark_mode->isChecked());
   settings.setValue("prefs/mixer-force-mono", mixer_force_mono->isChecked());
   settings.setValue("prefs/mixer-invert-stereo", mixer_invert_stereo->isChecked());
+  settings.setValue("prefs/", mixer_invert_stereo->isChecked());
 
   settings.setValue("prefs/rp/force-audio-default", rp_force_audio_default->isChecked());
   settings.setValue("prefs/rp/force-audio-headphones", rp_force_audio_headphones->isChecked());
@@ -2188,10 +2405,12 @@ void MainWindow::loadFile(const QString &fileName, SonicPiScintilla* &text)
 {
   QFile file(fileName);
   if (!file.open(QFile::ReadOnly)) {
+    setMessageBoxStyle();
     QMessageBox::warning(this, tr("Sonic Pi"),
 			 tr("Cannot read file %1:\n%2.")
 			 .arg(fileName)
 			 .arg(file.errorString()));
+    updateDarkMode();
     return;
   }
 
@@ -2206,10 +2425,12 @@ bool MainWindow::saveFile(const QString &fileName, SonicPiScintilla* text)
 {
   QFile file(fileName);
   if (!file.open(QFile::WriteOnly)) {
+    setMessageBoxStyle();
     QMessageBox::warning(this, tr("Sonic Pi"),
 			 tr("Cannot write file %1:\n%2.")
 			 .arg(fileName)
 			 .arg(file.errorString()));
+    updateDarkMode();
     return false;
   }
 
@@ -2243,16 +2464,20 @@ SonicPiScintilla* MainWindow::filenameToWorkspace(std::string filename)
 
 void MainWindow::onExitCleanup()
 {
+
   setupLogPathAndRedirectStdOut();
+  std::cout << "[GUI] - stopping OSC server" << std::endl;
+  sonicPiOSCServer->stop();
+  if(protocol == TCP){
+    clientSock->close();
+  }
   if(serverProcess->state() == QProcess::NotRunning) {
     std::cout << "[GUI] - warning, server process is not running." << std::endl;
-    sonicPiServer->stopServer();
-    if(protocol == TCP){
-      clientSock->close();
-    }
   } else {
-    if (loaded_workspaces)
+    if (loaded_workspaces) {
+      // this should be a synchorous call to avoid the following sleep
       saveWorkspaces();
+    }
     sleep(1);
     std::cout << "[GUI] - asking server process to exit..." << std::endl;
     Message msg("/exit");
@@ -2418,14 +2643,11 @@ QString MainWindow::asciiArtLogo(){
 
 void MainWindow::printAsciiArtLogo(){
   QString s = asciiArtLogo();
-  std::cout << std::endl << std::endl << std::endl;
 #if QT_VERSION >= 0x050400
   qDebug().noquote() << s;
-  std::cout << std::endl << std::endl;
 #else
   //noquote requires QT 5.4
   qDebug() << s;
-  std::cout << std::endl;
 #endif
 }
 
@@ -2446,7 +2668,7 @@ void MainWindow::updateVersionNumber(QString v, int v_num,QString latest_v, int
   latest_version_num = latest_v_num;
 
   // update status bar
-  versionLabel->setText(QString("Sonic Pi " + v + " on " + platform));
+  versionLabel->setText(QString("Sonic Pi " + v + " on " + platform + " "));
 
   // update preferences
   QString last_update_check = tr("Last checked %1").arg(last_checked.toString());
@@ -2469,14 +2691,14 @@ void MainWindow::updateVersionNumber(QString v, int v_num,QString latest_v, int
 
 
 void MainWindow::setupLogPathAndRedirectStdOut() {
-  QString sp_user_path = QDir::homePath() + QDir::separator() + ".sonic-pi";
-  log_path =  sp_user_path + QDir::separator() + "log";
   QDir().mkdir(sp_user_path);
   QDir().mkdir(log_path);
 
-  coutbuf = std::cout.rdbuf();
-  stdlog.open(QString(log_path + "/gui.log").toStdString().c_str());
-  std::cout.rdbuf(stdlog.rdbuf());
+  if(homeDirWritable) {
+    coutbuf = std::cout.rdbuf();
+    stdlog.open(gui_log_path.toStdString().c_str());
+    std::cout.rdbuf(stdlog.rdbuf());
+  }
 }
 
 
@@ -2489,4 +2711,16 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *evt)
     }
     return QMainWindow::eventFilter(obj, evt);
 }
+
+
+
+QString MainWindow::sonicPiHomePath() {
+  QString path = qgetenv("SONIC_PI_HOME").constData();
+  if (path.isEmpty()) {
+    return QDir::homePath();
+  }
+  else {
+    return path;
+  }
+}
 #include "ruby_help.h"
diff --git a/app/gui/qt/mainwindow.h b/app/gui/qt/mainwindow.h
index 424bab8..8cb4a91 100644
--- a/app/gui/qt/mainwindow.h
+++ b/app/gui/qt/mainwindow.h
@@ -3,7 +3,7 @@
 // Full project source: https://github.com/samaaron/sonic-pi
 // License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 //
-// Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 // All rights reserved.
 //
 // Permission is granted for use, copying, modification, and
@@ -37,6 +37,7 @@
 #include <sstream>
 #include <fstream>
 #include <QSignalMapper>
+#include "sonicpitheme.h"
 
 class QAction;
 class QMenu;
@@ -50,7 +51,7 @@ class QSlider;
 class SonicPiAPIs;
 class SonicPiLog;
 class SonicPiScintilla;
-class SonicPiServer;
+class SonicPiOSCServer;
 
 struct help_page {
   QString title;
@@ -74,7 +75,7 @@ public:
     MainWindow(QApplication &ref, bool i18n, QSplashScreen* splash);
 #endif
 
-    SonicPiServer *sonicPiServer;
+    SonicPiOSCServer *sonicPiOSCServer;
     enum {UDP=0, TCP=1};
     QCheckBox *dark_mode;
     bool loaded_workspaces;
@@ -88,6 +89,8 @@ public slots:
     void invokeStartupError(QString msg);
 
 private slots:
+    QString sonicPiHomePath();
+    void updateLogAutoScroll();
     bool eventFilter(QObject *obj, QEvent *evt);
     void changeTab(int id);
     QString asciiArtLogo();
@@ -102,8 +105,10 @@ private slots:
     void disableCheckUpdates();
     void stopCode();
     void beautifyCode();
-    void completeListOrIndentLine(QObject *ws);
-    void indentCurrentLineOrSelection(SonicPiScintilla *ws);
+    void newlineAndIndent(SonicPiScintilla *ws);
+    void returnAndIndentLine(QObject *ws);
+    void completeSnippetListOrIndentLine(QObject *ws);
+    void completeSnippetOrIndentCurrentLineOrSelection(SonicPiScintilla *ws);
     void toggleCommentInCurrentWorkspace();
     void toggleComment(SonicPiScintilla *ws);
     void reloadServerCode();
@@ -117,6 +122,7 @@ private slots:
     void mixerHpfDisable();
     void mixerLpfDisable();
     QString currentTabLabel();
+    bool loadFile();
     bool saveAs();
     void about();
     void help();
@@ -134,8 +140,9 @@ private slots:
     void showPrefsPane();
     void updateDocPane(QListWidgetItem *cur);
     void updateDocPane2(QListWidgetItem *cur, QListWidgetItem *prev);
-    void serverStarted();
+    void showWindow();
     void splashClose();
+    void setMessageBoxStyle();
     void startupError(QString msg);
     void replaceBuffer(QString id, QString content, int line, int index, int first_line);
     void replaceLines(QString id, QString content, int first_line, int finish_line, int point_line, int point_index);
@@ -166,13 +173,19 @@ private slots:
     void heartbeatOSC();
     void zoomCurrentWorkspaceIn();
     void zoomCurrentWorkspaceOut();
+    void showWelcomeScreen();
+    void setupWindowStructure();
+    void setupTheme();
+    void escapeWorkspaces();
 
 private:
 
+    QString osDescription();
     void setupLogPathAndRedirectStdOut();
     QSignalMapper *signalMapper;
-    void startServer();
-    void waitForServiceSync();
+    QSignalMapper *retSignalMapper;
+    void startRubyServer();
+    bool waitForServiceSync();
     void clearOutputPanels();
     void createShortcuts();
     void createToolBar();
@@ -249,6 +262,7 @@ private:
     QProcess *serverProcess;
 
     SonicPiLexer *lexer;
+    SonicPiTheme *theme;
 
     QToolBar *toolBar;
 
@@ -260,6 +274,9 @@ private:
     QCheckBox *check_args;
     QCheckBox *clear_output_on_run;
     QCheckBox *log_cues;
+    QCheckBox *log_auto_scroll;
+    QCheckBox *enable_external_synths_cb;
+    QCheckBox *synth_trigger_timing_guarantees_cb;
     QCheckBox *show_line_numbers;
     QCheckBox *auto_indent_on_run;
     QCheckBox *full_screen;
@@ -288,7 +305,7 @@ private:
     std::ofstream stdlog;
 
     SonicPiAPIs *autocomplete;
-    QString sample_path, log_path;
+    QString sample_path, log_path, sp_user_path, sp_user_tmp_path, ruby_server_path, ruby_path, server_error_log_path, server_output_log_path, gui_log_path, scsynth_log_path;
     QString defaultTextBrowserStyle;
 
     QString version;
@@ -301,7 +318,7 @@ private:
     QLabel *versionLabel;
 
     QString guiID;
-
+    bool homeDirWritable;
 };
 
 #endif
diff --git a/app/gui/qt/oschandler.cpp b/app/gui/qt/oschandler.cpp
index af7da1b..2bbe6d9 100644
--- a/app/gui/qt/oschandler.cpp
+++ b/app/gui/qt/oschandler.cpp
@@ -1,3 +1,17 @@
+//--
+// This file is part of Sonic Pi: http://sonic-pi.net
+// Full project source: https://github.com/samaaron/sonic-pi
+// License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+//
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+// All rights reserved.
+//
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
+// notice is included.
+//++
+
+
 // OSC stuff
 #include "oscpkt.hh"
 #include "oschandler.h"
@@ -44,12 +58,17 @@ void OscHandler::oscMessage(std::vector<char> buffer){
       }
       else if (msg->match("/info")) {
         std::string s;
-        if (msg->arg().popStr(s).isOkNoMoreArgs()) {
+        int style;
+        if (msg->arg().popInt32(style).popStr(s).isOkNoMoreArgs()) {
           // Evil nasties!
           // See: http://www.qtforum.org/article/26801/qt4-threads-and-widgets.html
 
           QMetaObject::invokeMethod( out, "setTextColor",           Qt::QueuedConnection, Q_ARG(QColor, theme->color("LogInfoForeground")));
+          if(style == 1) {
+          QMetaObject::invokeMethod( out, "setTextBackgroundColor", Qt::QueuedConnection, Q_ARG(QColor, theme->color("LogInfoBackgroundStyle1")));
+          } else {
           QMetaObject::invokeMethod( out, "setTextBackgroundColor", Qt::QueuedConnection, Q_ARG(QColor, theme->color("LogInfoBackground")));
+          }
 
           QMetaObject::invokeMethod( out, "appendPlainText",        Qt::QueuedConnection, Q_ARG(QString, QString::fromStdString("=> " + s + "\n")) );
 
diff --git a/app/gui/qt/oschandler.h b/app/gui/qt/oschandler.h
index 35c8d88..af51291 100644
--- a/app/gui/qt/oschandler.h
+++ b/app/gui/qt/oschandler.h
@@ -1,3 +1,16 @@
+//--
+// This file is part of Sonic Pi: http://sonic-pi.net
+// Full project source: https://github.com/samaaron/sonic-pi
+// License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+//
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+// All rights reserved.
+//
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
+// notice is included.
+//++
+
 #ifndef OSCHANDLER_H
 #define OSCHANDLER_H
 
diff --git a/app/gui/qt/prune.rb b/app/gui/qt/prune.rb
index e61b393..e835858 100755
--- a/app/gui/qt/prune.rb
+++ b/app/gui/qt/prune.rb
@@ -5,7 +5,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/gui/qt/sonic_pi_osc_server.cpp b/app/gui/qt/sonic_pi_osc_server.cpp
new file mode 100644
index 0000000..149ab71
--- /dev/null
+++ b/app/gui/qt/sonic_pi_osc_server.cpp
@@ -0,0 +1,43 @@
+//--
+// This file is part of Sonic Pi: http://sonic-pi.net
+// Full project source: https://github.com/samaaron/sonic-pi
+// License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+//
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+// All rights reserved.
+//
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
+// notice is included.
+//++
+
+
+#include "sonic_pi_osc_server.h"
+
+SonicPiOSCServer::SonicPiOSCServer(MainWindow *sonicPiWindow, OscHandler *oscHandler) :
+    QObject(sonicPiWindow)
+{
+    handler = oscHandler;
+    osc_incoming_port_open = false;
+    parent = sonicPiWindow;
+    stop_server = false;
+}
+
+bool SonicPiOSCServer::waitForServer(){
+  return !handler->server_started && continueListening();
+}
+
+bool SonicPiOSCServer::continueListening(){
+  return !handler->signal_server_stop && !stop_server;
+}
+
+bool SonicPiOSCServer::isIncomingPortOpen(){
+  return osc_incoming_port_open;
+}
+
+bool SonicPiOSCServer::isServerStarted(){
+  return handler->server_started;
+}
+
+void SonicPiOSCServer::stop(){}
+void SonicPiOSCServer::start(){}
diff --git a/app/gui/qt/sonic_pi_osc_server.h b/app/gui/qt/sonic_pi_osc_server.h
new file mode 100644
index 0000000..026d457
--- /dev/null
+++ b/app/gui/qt/sonic_pi_osc_server.h
@@ -0,0 +1,47 @@
+//--
+// This file is part of Sonic Pi: http://sonic-pi.net
+// Full project source: https://github.com/samaaron/sonic-pi
+// License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+//
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+// All rights reserved.
+//
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
+// notice is included.
+//++
+
+#ifndef SONICPIOSCSERVER_H
+#define SONICPIOSCSERVER_H
+
+#include <QObject>
+#include "oschandler.h"
+
+class SonicPiOSCServer : public QObject
+{
+    Q_OBJECT
+public:
+    explicit SonicPiOSCServer(MainWindow *parent = 0, OscHandler *handler = 0);
+    bool waitForServer();
+    bool isIncomingPortOpen();
+    bool isServerStarted();
+
+
+signals:
+
+public slots:
+   virtual void stop();
+   virtual void start();
+
+protected:
+    OscHandler* handler;
+    MainWindow* parent;
+    bool osc_incoming_port_open;
+    bool stop_server;
+
+    bool continueListening();
+
+
+};
+
+#endif // SONICPIOSCSERVER_H
diff --git a/app/gui/qt/sonic_pi_tcp_osc_server.cpp b/app/gui/qt/sonic_pi_tcp_osc_server.cpp
new file mode 100644
index 0000000..d562151
--- /dev/null
+++ b/app/gui/qt/sonic_pi_tcp_osc_server.cpp
@@ -0,0 +1,84 @@
+#include "sonic_pi_tcp_osc_server.h"
+#include "mainwindow.h"
+
+// Qt stuff
+#include <QtNetwork>
+#include <QTcpSocket>
+
+#include "sonic_pi_osc_server.h"
+
+// OSC stuff
+#include "oscpkt.hh"
+
+SonicPiTCPOSCServer::SonicPiTCPOSCServer(MainWindow *sonicPiWindow, OscHandler *oscHandler) : SonicPiOSCServer(sonicPiWindow, oscHandler)
+{
+    tcpServer = new QTcpServer(sonicPiWindow);
+    buffer.clear();
+    blockSize = 0;
+
+    connect(tcpServer, SIGNAL(newConnection()), this, SLOT(client()));
+}
+
+void SonicPiTCPOSCServer::start(){
+    int PORT_NUM = 4558;
+    if(tcpServer->listen(QHostAddress::LocalHost, PORT_NUM)){
+      std::cout << "[GUI] - TCP OSC Server started: " << PORT_NUM << std::endl;
+      handler->server_started = true;
+    }
+    else{
+      tcpServer->close();
+      std::cerr << "[GUI] - Server failed to start!";
+    }
+
+ }
+
+void SonicPiTCPOSCServer::stop(){
+    tcpServer->close();
+}
+
+void SonicPiTCPOSCServer::logError(QAbstractSocket::SocketError e){
+    std::cerr << "[GUI] - Socket error:" << e;
+}
+
+void SonicPiTCPOSCServer::client(){
+    //In TCP we have no ack signal as we don't block the main loop.
+    //Hence assume if we get a connection from a client its booted and ready.
+    QMetaObject::invokeMethod(parent, "serverStarted", Qt::QueuedConnection);
+    socket = tcpServer->nextPendingConnection();
+    connect(socket, SIGNAL(readyRead()), this, SLOT(readMessage()));
+    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(logError(QAbstractSocket::SocketError)));
+    connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
+    std::vector<char>().swap(buffer);
+}
+
+void SonicPiTCPOSCServer::readMessage()
+{
+    while(socket->bytesAvailable() > 0){
+        if (blockSize == 0) {
+            if (socket->bytesAvailable() < (int)sizeof(quint32)){
+                return;
+            }
+
+            socket->read((char *)&blockSize, sizeof(quint32));
+            blockSize = qToBigEndian(blockSize);
+        }
+
+        if (socket->bytesAvailable() < blockSize){
+            return;
+        }
+
+        buffer.resize(blockSize);
+        int bytesRead = socket->read(&buffer[0], blockSize);
+
+        if(bytesRead < 0 || (uint32_t)bytesRead != blockSize) {
+            std::cerr << "[GUI] - Error: read: " << bytesRead << " Expected:" << blockSize << "\n";
+            blockSize = 0;
+            return;
+        }
+        std::vector<char> tmp(buffer);
+        tmp.swap(buffer);
+        handler->oscMessage(buffer);
+        blockSize = 0;
+        std::vector<char>().swap(buffer);
+    }
+}
diff --git a/app/gui/qt/sonic_pi_tcp_osc_server.h b/app/gui/qt/sonic_pi_tcp_osc_server.h
new file mode 100644
index 0000000..f94d0f1
--- /dev/null
+++ b/app/gui/qt/sonic_pi_tcp_osc_server.h
@@ -0,0 +1,36 @@
+#ifndef SONIC_PI_TCP_OSC_SERVER_H
+#define SONIC_PI_TCP_OSC_SERVER_H
+
+#include "oschandler.h"
+#include "sonic_pi_osc_server.h"
+#include "mainwindow.h"
+
+#include <QtCore>
+#include <QtNetwork>
+#include <QTcpSocket>
+
+class SonicPiTCPOSCServer :  public SonicPiOSCServer
+{
+    Q_OBJECT
+
+public:
+    explicit SonicPiTCPOSCServer(MainWindow *parent, OscHandler *handler = 0);
+
+    quint32 blockSize;
+
+public slots:
+    void stop();
+    void start();
+    void readMessage();
+    void client();
+    void logError(QAbstractSocket::SocketError);
+
+private:
+    void handleMessage();
+
+    QTcpServer *tcpServer;
+    QTcpSocket *socket;
+    std::vector<char> buffer;
+};
+
+#endif // SONIC_PI_TCP_OSC_SERVER_H
diff --git a/app/gui/qt/sonic_pi_udp_osc_server.cpp b/app/gui/qt/sonic_pi_udp_osc_server.cpp
new file mode 100644
index 0000000..07361df
--- /dev/null
+++ b/app/gui/qt/sonic_pi_udp_osc_server.cpp
@@ -0,0 +1,52 @@
+//--
+// This file is part of Sonic Pi: http://sonic-pi.net
+// Full project source: https://github.com/samaaron/sonic-pi
+// License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+//
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+// All rights reserved.
+//
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
+// notice is included.
+//++
+
+#include "sonic_pi_udp_osc_server.h"
+#include "sonic_pi_osc_server.h"
+#include "udp.hh"
+
+SonicPiUDPOSCServer::SonicPiUDPOSCServer(MainWindow *sonicPiWindow, OscHandler *oscHandler) : SonicPiOSCServer(sonicPiWindow, oscHandler)
+{
+  handler = oscHandler;
+  osc_incoming_port_open = false;
+  parent = sonicPiWindow;
+  stop_server = false;
+}
+
+void SonicPiUDPOSCServer::stop(){
+  stop_server = true;
+}
+
+void SonicPiUDPOSCServer::start(){
+  std::cout << "[GUI] - starting UDP OSC Server on port 4558..." << std::endl;
+  int PORT_NUM = 4558;
+  oscpkt::UdpSocket sock;
+  sock.bindTo(PORT_NUM);
+  if (!sock.isOk()) {
+    std::cout << "[GUI] - unable to listen to UDP OSC messages on port 4558" << std::endl;
+    parent->invokeStartupError(tr("Is Sonic Pi already running?  Can't open UDP port 4558."));
+    return;
+  }
+
+  std::cout << "[GUI] - UDP OSC Server ready and listening" << std::endl << std::flush;
+
+  osc_incoming_port_open = true;
+
+  while (sock.isOk() && continueListening()) {
+    if (sock.receiveNextPacket(30 /* timeout, in ms */)) {
+      handler->oscMessage(sock.buffer);
+      std::vector<char>().swap(sock.buffer);
+      std::cout << std::flush;
+    }
+  }
+}
diff --git a/app/gui/qt/sonic_pi_udp_osc_server.h b/app/gui/qt/sonic_pi_udp_osc_server.h
new file mode 100644
index 0000000..38ed27e
--- /dev/null
+++ b/app/gui/qt/sonic_pi_udp_osc_server.h
@@ -0,0 +1,34 @@
+//--
+// This file is part of Sonic Pi: http://sonic-pi.net
+// Full project source: https://github.com/samaaron/sonic-pi
+// License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+//
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+// All rights reserved.
+//
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
+// notice is included.
+//++
+
+#ifndef SONIC_PI_UDP_OSC_SERVER_H
+#define SONIC_PI_UDP_OSC_SERVER_H
+
+#include "oschandler.h"
+#include "sonic_pi_osc_server.h"
+#include "mainwindow.h"
+
+class SonicPiUDPOSCServer : public SonicPiOSCServer
+{
+    Q_OBJECT
+
+public:
+    explicit SonicPiUDPOSCServer(MainWindow *parent, OscHandler *handler = 0);
+
+public slots:
+    void stop();
+    void start();
+
+};
+
+#endif // SONIC_PI_UDP_OSC_SERVER_H
diff --git a/app/gui/qt/sonicpiapis.cpp b/app/gui/qt/sonicpiapis.cpp
index 9ffc5af..33cd8a1 100644
--- a/app/gui/qt/sonicpiapis.cpp
+++ b/app/gui/qt/sonicpiapis.cpp
@@ -3,14 +3,15 @@
 // Full project source: https://github.com/samaaron/sonic-pi
 // License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 //
-// Copyright 2013, 2014 by Sam Aaron (http://sam.aaron.name).
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 // All rights reserved.
 //
-// Permission is granted for use, copying, modification, distribution,
-// and distribution of modified versions of this work as long as this
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
 // notice is included.
 //++
 
+
 #include <QDir>
 #include <iostream>
 
@@ -23,7 +24,7 @@ SonicPiAPIs::SonicPiAPIs(QsciLexer *lexer)
     : QsciAbstractAPIs(lexer)
 {
   // manually managed for now
-  keywords[Chord] << "'1'" << "'5'" << "'+5'" << "'m+5'" << ":sus2" << ":sus4" << "'6'" << ":m6" << "'7sus2'" << "'7sus4'" << "'7-5'" << "'m7-5'" << "'7+5'" << "'m7+5'" << "'9'" << ":m9" << "'m7+9'" << ":maj9" << "'9sus4'" << "'6*9'" << "'m6*9'" << "'7-9'" << "'m7-9'" << "'7-10'" << "'9+5'" << "'m9+5'" << "'7+5-9'" << "'m7+5-9'" << "'11'" << ":m11" << ":maj11" << "'11+'" << "'m11+'" << "'13'" << ":m13" << ":major" << ":M" << ":minor" << ":m" << ":major7" << ":dom7" << "'7'" << ":M7" << ":minor7" << ":m7" << ":augmented" << ":a" << ":diminished" << ":dim" << ":i" << ":diminished7" << ":dim7" << ":i7";
+  keywords[Chord] << "'1'" << "'5'" << "'+5'" << "'m+5'" << ":sus2" << ":sus4" << "'6'" << ":m6" << "'7sus2'" << "'7sus4'" << "'7-5'" << "'m7-5'" << "'7+5'" << "'m7+5'" << "'9'" << ":m9" << "'m7+9'" << ":maj9" << "'9sus4'" << "'6*9'" << "'m6*9'" << "'7-9'" << "'m7-9'" << "'7-10'" << "'9+5'" << "'m9+5'" << "'7+5-9'" << "'m7+5-9'" << "'11'" << ":m11" << ":maj11" << "'11+'" << "'m11+'" << "'13'" << ":m13" << ":add2" << ":add4" << ":add9" << ":add11" << ":add13" << ":madd2" << ":madd4" << ":madd9" << ":madd11" << ":madd13" << ":major" << ":M" << ":minor" << ":m" << ":major7" << ":dom7" << "'7'" << ":M7" << ":minor7" << ":m7" << ":augmented" << ":a" << ":diminished" << ":dim" << ":i" << ":diminished7" << ":dim7" << ":i7";
 
   keywords[Scale] << ":diatonic" << ":ionian" << ":major" << ":dorian" << ":phrygian" << ":lydian" << ":mixolydian" << ":aeolian" << ":minor" << ":locrian" << ":hex_major6" << ":hex_dorian" << ":hex_phrygian" << ":hex_major7" << ":hex_sus" << ":hex_aeolian" << ":minor_pentatonic" << ":yu" << ":major_pentatonic" << ":gong" << ":egyptian" << ":shang" << ":jiao" << ":zhi" << ":ritusen" << ":whole_tone" << ":whole" << ":chromatic" << ":harmonic_minor" << ":melodic_minor_asc" << ":hungarian_minor" << ":octatonic" << ":messiaen1" << ":messiaen2" << ":messiaen3" << ":messiaen4" << ":messiaen5" << ":messiaen6" << ":messiaen7" << ":super_locrian" << ":hirajoshi" << ":kumoi" << ":neapolitan_major" << ":bartok" << ":bhairav" << ":locrian_major" << ":ahirbhairav" << ":enigmatic" << ":neapolitan_minor" << ":pelog" << ":augmented2" << ":scriabin" << ":harmonic_major" << ":melodic_minor_desc" << ":romanian_minor" << ":hindu" << ":iwato" << ":melodic_minor" << ":diminished2" << ":marva" << ":melodic_major" << ":indian" << ":spanish" << ":prometheus" << ":diminished" << ":todi" << ":leading_whole" << ":augmented" << ":purvi" << ":chinese" << ":lydian_minor";
 
@@ -31,7 +32,9 @@ SonicPiAPIs::SonicPiAPIs(QsciLexer *lexer)
 
   keywords[PlayParam] << "amp:" << "attack:" << "release:" << "sustain:" << "decay:" << "env_curve:" << "sustain_level:" << "pan:" << "attack_level:" << "decay_level:" << "on:" << "slide:" << "pitch:";
 
-  keywords[SampleParam] << "amp:" << "pan:" << "attack:" << "decay:" << "sustain:" << "release:" << "attack_level:" << "decay_level:" << "sustain_level:" << "env_curve:" << "rate:" << "beat_stretch:" << "start:" << "finish:" << "res:" << "cutoff:" << "cutoff_attack:" << "cutoff_decay:" << "cutoff_sustain:" << "cutoff_release:" << "cutoff_attack_level:" << "cutoff_decay_level:" << "cutoff_sustain_level:" << "cutoff_env_curve:" << "norm:" << "rpitch:" << "pitch:" << "pitch_stretch:" << "window_size:" << "pitch_dis:" << "time_dis:";
+  keywords[SampleParam] << "amp:" << "pan:" << "attack:" << "decay:" << "sustain:" << "release:" << "attack_level:" << "decay_level:" << "sustain_level:" << "env_curve:" << "rate:" << "beat_stretch:" << "start:" << "finish:" << "res:" << "lpf:" << "lpf_min:" << "lpf_attack:" << "lpf_decay:" << "lpf_sustain:" << "lpf_release:" << "lpf_init_level:" << "lpf_attack_level:" << "lpf_decay_level:" << "lpf_sustain_level:" << "lpf_release_level" << "lpf_env_curve:" << "hpf:" << "hpf_max:" <<"hpf_attack:" << "hpf_decay:" << "hpf_sustain:" << "hpf_release:" << "hpf_init_level:" << "hpf_attack_level:" << "hpf_decay_level:" << "hpf_sustain_level:" <<  "hpf_release_level:" << "hpf_env_curve:" << "norm:" << "rpitch:" << "pitch:" << "pitch_stretch:" << "window_size:" << "pitch_dis:" << "time_dis:" << "compress:" << "threshold:" << "clamp_time:" << "slope_above:" << "slope_below:" << "relax_time:" << "pre_amp:";
+
+  keywords[Examples] << ":haunted" << ":ambient_experiment" << ":chord_inversions" << "filtered_dnb" << ":fm_noise" << ":jungle" << ":ocean" << ":reich_phase" << ":acid" << ":ambient" << ":compus_beats" << ":echo_drama" << ":idm_breakbeat" << ":tron_bike" << ":wob_rhyth" << ":bach" << ":driving_pulse" << ":monday_blues" << ":rerezzed" << ":square_skit" << ":blimp_zones" << ":blip_rhythm" << ":shufflit" << ":tilburg_2" << ":time_machine" << ":sonic_dreams";
 
   keywords[Tuning] << ":just" << ":pythagorean" << ":meantone" << ":equal";
 }
@@ -41,7 +44,7 @@ SonicPiAPIs::SonicPiAPIs(QsciLexer *lexer)
 void SonicPiAPIs::loadSamples(QString sample_path) {
   QDir dir(sample_path);
   QStringList filetypes;
-  filetypes << "*.wav";
+  filetypes << "*.wav" << "*.wave" << "*.aif" << "*.aiff" << "*.flac";
   dir.setNameFilters(filetypes);
 
   QFileInfoList files = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
@@ -97,12 +100,14 @@ void SonicPiAPIs::updateAutoCompletionList(const QStringList &context,
        << ", partial = " << partial.toStdString() << endl;
   */
 
-  if (last == "sample" || last == "sample_info" || last == "sample_duration" || last == "use_sample_bpm" || last == "sample_buffer" || last == "sample_loaded?") {
+  if (last == "sample" || last == "sample_info" || last == "sample_duration" || last == "use_sample_bpm" || last == "sample_buffer" || last == "sample_loaded?" || last == "load_sample" || last == "load_samples") {
     ctx = Sample;
   } else if (last == "with_fx" || last == "use_fx") {
     ctx = FX;
   } else if (last == "with_synth" || last == "use_synth" || last == "synth") {
     ctx = Synth;
+  } else if (last == "load_example") {
+    ctx = Examples;
 
   // autocomplete the second arg of scale/chord
   } else if (lastButOne == "scale") {
@@ -142,6 +147,9 @@ void SonicPiAPIs::updateAutoCompletionList(const QStringList &context,
   } else if (words.length() >= 2 && first == "sample") {
     if (last.endsWith(':')) return; // don't try to complete parameters
     ctx = SampleParam;
+  } else if (first == "use_sample_defaults" || first == "with_sample_defaults") {
+    if (last.endsWith(':')) return; // don't try to complete parameters
+    ctx = SampleParam;
 
   } else if (context.length() > 1) {
     if (partial.length() <= 2) {
diff --git a/app/gui/qt/sonicpiapis.h b/app/gui/qt/sonicpiapis.h
index ae20c95..4250e2c 100644
--- a/app/gui/qt/sonicpiapis.h
+++ b/app/gui/qt/sonicpiapis.h
@@ -3,23 +3,21 @@
 // Full project source: https://github.com/samaaron/sonic-pi
 // License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 //
-// Copyright 2013, 2014 by Sam Aaron (http://sam.aaron.name).
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 // All rights reserved.
 //
-// Permission is granted for use, copying, modification, distribution,
-// and distribution of modified versions of this work as long as this
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
 // notice is included.
 //++
 
-
 #include <Qsci/qsciabstractapis.h>
 #include <QHash>
 
 class SonicPiAPIs : public QsciAbstractAPIs
 {
  public:
-  enum { Func, FX, Synth, Sample, Chord, Scale, MCBlock, PlayParam, SampleParam, Tuning,
-	 NContext };
+  enum { Func, FX, Synth, Sample, Chord, Scale, MCBlock, PlayParam, SampleParam, Tuning, Examples, NContext};
 
   SonicPiAPIs(QsciLexer *lexer);
 
diff --git a/app/gui/qt/sonicpilexer.cpp b/app/gui/qt/sonicpilexer.cpp
index 9448de3..cd38ef4 100644
--- a/app/gui/qt/sonicpilexer.cpp
+++ b/app/gui/qt/sonicpilexer.cpp
@@ -3,11 +3,11 @@
 // Full project source: https://github.com/samaaron/sonic-pi
 // License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 //
-// Copyright 2013, 2014 by Sam Aaron (http://sam.aaron.name).
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 // All rights reserved.
 //
-// Permission is granted for use, copying, modification, distribution,
-// and distribution of modified versions of this work as long as this
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
 // notice is included.
 //++
 
diff --git a/app/gui/qt/sonicpilexer.h b/app/gui/qt/sonicpilexer.h
index a8f5e21..72ab766 100644
--- a/app/gui/qt/sonicpilexer.h
+++ b/app/gui/qt/sonicpilexer.h
@@ -3,15 +3,14 @@
 // Full project source: https://github.com/samaaron/sonic-pi
 // License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 //
-// Copyright 2013, 2014 by Sam Aaron (http://sam.aaron.name).
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 // All rights reserved.
 //
-// Permission is granted for use, copying, modification, distribution,
-// and distribution of modified versions of this work as long as this
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
 // notice is included.
 //++
 
-
 #include  <Qsci/qscilexerruby.h>
 
 #include "sonicpitheme.h"
@@ -28,5 +27,3 @@ public:
   SonicPiTheme *theme;
 
 };
-
-
diff --git a/app/gui/qt/sonicpilog.cpp b/app/gui/qt/sonicpilog.cpp
index 519e7f2..c1d6be6 100644
--- a/app/gui/qt/sonicpilog.cpp
+++ b/app/gui/qt/sonicpilog.cpp
@@ -1,13 +1,35 @@
+//--
+// This file is part of Sonic Pi: http://sonic-pi.net
+// Full project source: https://github.com/samaaron/sonic-pi
+// License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+//
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+// All rights reserved.
+//
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
+// notice is included.
+//++
+
+
 #include "sonicpilog.h"
 
 // Standard stuff
 #include <vector>
 #include "sonicpitheme.h"
+#include <QScrollBar>
 
 SonicPiLog::SonicPiLog(QWidget *parent) : QPlainTextEdit(parent)
 {
+  forceScroll = true;
+}
+
+void SonicPiLog::forceScrollDown(bool force)
+{
+  forceScroll = force;
 }
 
+
 void SonicPiLog::setTextColor(QColor c)
 {
   QTextCharFormat tf;
@@ -105,4 +127,9 @@ void SonicPiLog::handleMultiMessage(SonicPiLog::MultiMessage mm)
       setCurrentCharFormat(tf);
     }
     appendPlainText(QString::fromStdString(" "));
+
+    if(forceScroll) {
+      QScrollBar *sb = verticalScrollBar();
+      sb->setValue(sb->maximum());
+    }
 }
diff --git a/app/gui/qt/sonicpilog.h b/app/gui/qt/sonicpilog.h
index 54d7647..44eb1ab 100644
--- a/app/gui/qt/sonicpilog.h
+++ b/app/gui/qt/sonicpilog.h
@@ -1,3 +1,16 @@
+//--
+// This file is part of Sonic Pi: http://sonic-pi.net
+// Full project source: https://github.com/samaaron/sonic-pi
+// License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+//
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+// All rights reserved.
+//
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
+// notice is included.
+//++
+
 #ifndef SONICPILOG_H
 #define SONICPILOG_H
 
@@ -10,6 +23,7 @@ class SonicPiLog : public QPlainTextEdit
     Q_OBJECT
 public:
     explicit SonicPiLog(QWidget *parent = 0);
+    bool forceScroll;
 
     struct Message
     {
@@ -34,6 +48,7 @@ public slots:
     void setTextBackgroundColor(QColor c);
     void setFontFamily(QString font_name);
     void handleMultiMessage(SonicPiLog::MultiMessage mm);
+    void forceScrollDown(bool force);
 
 protected:
 };
diff --git a/app/gui/qt/sonicpiscintilla.cpp b/app/gui/qt/sonicpiscintilla.cpp
index 9f43fc9..e1c08f1 100644
--- a/app/gui/qt/sonicpiscintilla.cpp
+++ b/app/gui/qt/sonicpiscintilla.cpp
@@ -3,11 +3,11 @@
 // Full project source: https://github.com/samaaron/sonic-pi
 // License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 //
-// Copyright 2013, 2014 by Sam Aaron (http://sam.aaron.name).
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 // All rights reserved.
 //
-// Permission is granted for use, copying, modification, distribution,
-// and distribution of modified versions of this work as long as this
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
 // notice is included.
 //++
 
@@ -26,7 +26,7 @@ SonicPiScintilla::SonicPiScintilla(SonicPiLexer *lexer, SonicPiTheme *theme)
   standardCommands()->clearKeys();
   standardCommands()->clearAlternateKeys();
   QString skey;
-  QSettings settings("sonic-pi.net", "Key bindings");
+  QSettings settings("sonic-pi.net", "Default Key bindings");
 
 #if defined(Q_OS_MAC)
   int SPi_CTRL = Qt::META;
@@ -87,9 +87,6 @@ SonicPiScintilla::SonicPiScintilla(SonicPiLexer *lexer, SonicPiTheme *theme)
   addKeyBinding(settings, QsciCommand::Delete, Qt::Key_D | SPi_CTRL);
   addKeyBinding(settings, QsciCommand::VerticalCentreCaret, Qt::Key_L | SPi_CTRL);
 
-  // tab return
-  addKeyBinding(settings, QsciCommand::Newline, Qt::Key_Return);
-
   addKeyBinding(settings, QsciCommand::Backtab, Qt::Key_Tab | Qt::SHIFT);
 
   // copy paste
@@ -204,7 +201,7 @@ void SonicPiScintilla::cutLineFromPoint()
   int linenum, index;
   getCursorPosition(&linenum, &index);
 
-  if (text(linenum) == "\n")
+  if (text(linenum).mid(index).contains(QRegExp("^\\s*\\n")))
   {
     setSelection(linenum, index, linenum + 1, 0);
     SendScintilla(SCI_CUT);
@@ -213,10 +210,6 @@ void SonicPiScintilla::cutLineFromPoint()
       //  SendScintilla(SCI_CLEARSELECTIONS);
       int pos = SendScintilla(SCI_GETCURRENTPOS);
 
-      while (text(linenum).endsWith(",\n")) {
-        linenum++;
-        moveLines(1);
-      }
       SendScintilla(SCI_LINEEND);
       SendScintilla(SCI_SETANCHOR, pos);
       SendScintilla(SCI_CUT);
@@ -479,3 +472,18 @@ void SonicPiScintilla::zoomFontOut() {
   setProperty("zoom", QVariant(zoom));
   zoomTo(zoom);
 }
+
+void SonicPiScintilla::newLine() {
+  SendScintilla(QsciCommand::Newline);
+}
+
+void SonicPiScintilla::replaceBuffer(QString content, int line, int index, int first_line) {
+  beginUndoAction();
+  insert(" ");
+  SendScintilla(QsciCommand::Delete);
+  selectAll();
+  replaceSelectedText(content);
+  setCursorPosition(line, index);
+  setFirstVisibleLine(first_line);
+  endUndoAction();
+}
diff --git a/app/gui/qt/sonicpiscintilla.h b/app/gui/qt/sonicpiscintilla.h
index 9d51083..7403d61 100644
--- a/app/gui/qt/sonicpiscintilla.h
+++ b/app/gui/qt/sonicpiscintilla.h
@@ -3,15 +3,14 @@
 // Full project source: https://github.com/samaaron/sonic-pi
 // License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 //
-// Copyright 2013, 2014 by Sam Aaron (http://sam.aaron.name).
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 // All rights reserved.
 //
-// Permission is granted for use, copying, modification, distribution,
-// and distribution of modified versions of this work as long as this
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
 // notice is included.
 //++
 
-
 #include <Qsci/qsciscintilla.h>
 #include "sonicpitheme.h"
 
@@ -58,6 +57,8 @@ class SonicPiScintilla : public QsciScintilla
     void unhighlightAll();
     void zoomFontIn();
     void zoomFontOut();
+    void newLine();
+    void replaceBuffer(QString content, int line, int index, int first_line);
 
  private:
     void addKeyBinding(QSettings &qs, int cmd, int key);
diff --git a/app/gui/qt/sonicpiserver.cpp b/app/gui/qt/sonicpiserver.cpp
deleted file mode 100644
index d634d06..0000000
--- a/app/gui/qt/sonicpiserver.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "sonicpiserver.h"
-
-SonicPiServer::SonicPiServer(MainWindow *sonicPiWindow, OscHandler *oscHandler) :
-    QObject(sonicPiWindow)
-{
-    handler = oscHandler;
-    osc_incoming_port_open = false;
-    parent = sonicPiWindow;
-    stop_server = false;
-}
-
-bool SonicPiServer::waitForServer(){
-  return !handler->server_started && continueListening();
-}
-
-bool SonicPiServer::continueListening(){
-  return !handler->signal_server_stop && !stop_server;
-}
-
-bool SonicPiServer::isIncomingPortOpen(){
-  return osc_incoming_port_open;
-}
-
-bool SonicPiServer::isServerStarted(){
-  return handler->server_started;
-}
-
-void SonicPiServer::stopServer(){}
-void SonicPiServer::startServer(){}
diff --git a/app/gui/qt/sonicpiserver.h b/app/gui/qt/sonicpiserver.h
deleted file mode 100644
index 5ef4118..0000000
--- a/app/gui/qt/sonicpiserver.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef SONICPISERVER_H
-#define SONICPISERVER_H
-
-#include <QObject>
-#include "oschandler.h"
-
-class SonicPiServer : public QObject
-{
-    Q_OBJECT
-public:
-    explicit SonicPiServer(MainWindow *parent = 0, OscHandler *handler = 0);
-    bool waitForServer();
-    bool isIncomingPortOpen();
-    bool isServerStarted();
-
-
-signals:
-
-public slots:
-   virtual void stopServer();
-   virtual void startServer();
-
-protected:
-    OscHandler* handler;
-    MainWindow* parent;
-    bool osc_incoming_port_open;
-    bool stop_server;
-
-    bool continueListening();
-
-
-};
-
-#endif // SONICPISERVER_H
diff --git a/app/gui/qt/sonicpitcpserver.cpp b/app/gui/qt/sonicpitcpserver.cpp
deleted file mode 100644
index b6e96fe..0000000
--- a/app/gui/qt/sonicpitcpserver.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-#include "sonicpitcpserver.h"
-#include "mainwindow.h"
-
-// Qt stuff
-#include <QtNetwork>
-#include <QTcpSocket>
-
-#include "sonicpiserver.h"
-
-// OSC stuff
-#include "oscpkt.hh"
-
-SonicPiTCPServer::SonicPiTCPServer(MainWindow *sonicPiWindow, OscHandler *oscHandler) : SonicPiServer(sonicPiWindow, oscHandler)
-{
-    tcpServer = new QTcpServer(sonicPiWindow);
-    buffer.clear();
-    blockSize = 0;
-
-    connect(tcpServer, SIGNAL(newConnection()), this, SLOT(client()));
-}
-
-void SonicPiTCPServer::startServer(){
-    int PORT_NUM = 4558;
-    if(tcpServer->listen(QHostAddress::LocalHost, PORT_NUM)){
-      std::cout << "[GUI] - TCP OSC Server started: " << PORT_NUM << std::endl;
-      handler->server_started = true;
-    }
-    else{
-      tcpServer->close();
-      std::cerr << "[GUI] - Server failed to start!";
-    }
-
- }
-
-void SonicPiTCPServer::stopServer(){
-    tcpServer->close();
-}
-
-void SonicPiTCPServer::logError(QAbstractSocket::SocketError e){
-    std::cerr << "[GUI] - Socket error:" << e;
-}
-
-void SonicPiTCPServer::client(){
-    //In TCP we have no ack signal as we don't block the main loop.
-    //Hence assume if we get a connection from a client its booted and ready.
-    QMetaObject::invokeMethod(parent, "serverStarted", Qt::QueuedConnection);
-    socket = tcpServer->nextPendingConnection();
-    connect(socket, SIGNAL(readyRead()), this, SLOT(readMessage()));
-    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(logError(QAbstractSocket::SocketError)));
-    connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
-    std::vector<char>().swap(buffer);
-}
-
-void SonicPiTCPServer::readMessage()
-{
-    while(socket->bytesAvailable() > 0){
-        if (blockSize == 0) {
-            if (socket->bytesAvailable() < (int)sizeof(quint32)){
-                return;
-            }
-
-            socket->read((char *)&blockSize, sizeof(quint32));
-            blockSize = qToBigEndian(blockSize);
-        }
-
-        if (socket->bytesAvailable() < blockSize){
-            return;
-        }
-
-        buffer.resize(blockSize);
-        int bytesRead = socket->read(&buffer[0], blockSize);
-
-        if(bytesRead < 0 || (uint32_t)bytesRead != blockSize) {
-            std::cerr << "[GUI] - Error: read: " << bytesRead << " Expected:" << blockSize << "\n";
-            blockSize = 0;
-            return;
-        }
-        std::vector<char> tmp(buffer);
-        tmp.swap(buffer);
-        handler->oscMessage(buffer);
-        blockSize = 0;
-        std::vector<char>().swap(buffer);
-    }
-}
diff --git a/app/gui/qt/sonicpitcpserver.h b/app/gui/qt/sonicpitcpserver.h
deleted file mode 100644
index f4de443..0000000
--- a/app/gui/qt/sonicpitcpserver.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef SONICPITCPSERVER_H
-#define SONICPITCPSERVER_H
-
-#include "oschandler.h"
-#include "sonicpiserver.h"
-#include "mainwindow.h"
-
-#include <QtCore>
-#include <QtNetwork>
-#include <QTcpSocket>
-
-#include "oschandler.h"
-#include "sonicpiserver.h"
-#include "mainwindow.h"
-
-class SonicPiTCPServer :  public SonicPiServer
-{
-    Q_OBJECT
-
-public:
-    explicit SonicPiTCPServer(MainWindow *parent, OscHandler *handler = 0);
-
-    quint32 blockSize;
-
-public slots:
-    void stopServer();
-    void startServer();
-    void readMessage();
-    void client();
-    void logError(QAbstractSocket::SocketError);
-
-private:
-    void handleMessage();
-
-    QTcpServer *tcpServer;
-    QTcpSocket *socket;
-    std::vector<char> buffer;
-};
-
-#endif // SONICPITCPSERVER_H
diff --git a/app/gui/qt/sonicpitheme.cpp b/app/gui/qt/sonicpitheme.cpp
index e86b47a..02355a2 100644
--- a/app/gui/qt/sonicpitheme.cpp
+++ b/app/gui/qt/sonicpitheme.cpp
@@ -1,3 +1,17 @@
+//--
+// This file is part of Sonic Pi: http://sonic-pi.net
+// Full project source: https://github.com/samaaron/sonic-pi
+// License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+//
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+// All rights reserved.
+//
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
+// notice is included.
+//++
+
+
 #include "sonicpitheme.h"
 
 SonicPiTheme::SonicPiTheme(QObject *parent, QSettings *settings, bool dark) : QObject(parent)
@@ -115,6 +129,7 @@ QMap<QString, QString> SonicPiTheme::lightTheme(){
     themeSettings["LogBackground"] = "white";
     themeSettings["LogForeground"] = "black";
     themeSettings["LogInfoBackground"] = "#5e5e5e";
+    themeSettings["LogInfoBackgroundStyle1"] = "DeepPink";
     themeSettings["LogInfoForeground"] = "white";
     themeSettings["LogDefaultForeground"] = "#5e5e5e";
 
@@ -201,6 +216,7 @@ QMap<QString, QString> SonicPiTheme::darkTheme(){
     themeSettings["LogBackground"] = "black";
     themeSettings["LogForeground"] = "white";
     themeSettings["LogInfoBackground"] = "#2c3539";
+    themeSettings["LogInfoBackgroundStyle1"] = "DeepPink";
     themeSettings["LogInfoForeground"] = "white";
     themeSettings["LogDefaultForeground"] = "white";
 
diff --git a/app/gui/qt/sonicpitheme.h b/app/gui/qt/sonicpitheme.h
index 5e6a511..275458a 100644
--- a/app/gui/qt/sonicpitheme.h
+++ b/app/gui/qt/sonicpitheme.h
@@ -1,3 +1,16 @@
+//--
+// This file is part of Sonic Pi: http://sonic-pi.net
+// Full project source: https://github.com/samaaron/sonic-pi
+// License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+//
+// Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+// All rights reserved.
+//
+// Permission is granted for use, copying, modification, and
+// distribution of modified versions of this work as long as this
+// notice is included.
+//++
+
 #ifndef SONICPITHEME_H
 #define SONICPITHEME_H
 
diff --git a/app/gui/qt/sonicpiudpserver.cpp b/app/gui/qt/sonicpiudpserver.cpp
deleted file mode 100644
index a246d6c..0000000
--- a/app/gui/qt/sonicpiudpserver.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "sonicpiudpserver.h"
-#include "sonicpiserver.h"
-#include "udp.hh"
-
-SonicPiUDPServer::SonicPiUDPServer(MainWindow *sonicPiWindow, OscHandler *oscHandler) : SonicPiServer(sonicPiWindow, oscHandler)
-{
-  handler = oscHandler;
-  osc_incoming_port_open = false;
-  parent = sonicPiWindow;
-  stop_server = false;
-}
-
-void SonicPiUDPServer::stopServer(){
-  stop_server = true;
-}
-
-void SonicPiUDPServer::startServer(){
-  std::cout << "[GUI] - starting UDP OSC Server on port 4558..." << std::endl;
-  int PORT_NUM = 4558;
-  oscpkt::UdpSocket sock;
-  sock.bindTo(PORT_NUM);
-  if (!sock.isOk()) {
-    std::cout << "[GUI] - unable to listen to UDP OSC messages on port 4558" << std::endl;
-    parent->invokeStartupError(tr("Is Sonic Pi already running?  Can't open UDP port 4558."));
-    return;
-  }
-
-  std::cout << "[GUI] - UDP OSC Server ready and listening" << std::endl << std::flush;
-
-  osc_incoming_port_open = true;
-
-  while (sock.isOk() && continueListening()) {
-    if (sock.receiveNextPacket(30 /* timeout, in ms */)) {
-      handler->oscMessage(sock.buffer);
-      std::vector<char>().swap(sock.buffer);
-      std::cout << std::flush;
-    }
-  }
-}
diff --git a/app/gui/qt/sonicpiudpserver.h b/app/gui/qt/sonicpiudpserver.h
deleted file mode 100644
index dd3ab7f..0000000
--- a/app/gui/qt/sonicpiudpserver.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef SONICPIUDPSERVER_H
-#define SONICPIUDPSERVER_H
-
-#include "oschandler.h"
-#include "sonicpiserver.h"
-#include "mainwindow.h"
-
-class SonicPiUDPServer : public SonicPiServer
-{
-    Q_OBJECT
-
-public:
-    explicit SonicPiUDPServer(MainWindow *parent, OscHandler *handler = 0);
-
-public slots:
-    void stopServer();
-    void startServer();
-
-};
-
-#endif // SONICPIUDPSERVER_H
diff --git a/app/gui/qt/theme/dark/doc-styles.css b/app/gui/qt/theme/dark/doc-styles.css
index c9f4fae..c63efdb 100644
--- a/app/gui/qt/theme/dark/doc-styles.css
+++ b/app/gui/qt/theme/dark/doc-styles.css
@@ -28,11 +28,13 @@ em {
 }
 
 .error_description {
+    font-size: medium;
     background-color: deeppink;
     color: white;
 }
 
 .syntax_error_description {
+    font-size: medium;
     background-color: dodgerblue;
     color: white;
 }
diff --git a/app/gui/qt/theme/light/doc-styles.css b/app/gui/qt/theme/light/doc-styles.css
index 540805b..b167ca1 100644
--- a/app/gui/qt/theme/light/doc-styles.css
+++ b/app/gui/qt/theme/light/doc-styles.css
@@ -29,11 +29,13 @@ em {
 }
 
 .error_description {
+    font-size: medium;
     background-color: deeppink;
     color: white;
 }
 
 .syntax_error_description {
+    font-size: medium;
     background-color: dodgerblue;
     color: white;
 }
diff --git a/app/gui/qt/udp.hh b/app/gui/qt/udp.hh
index 7a37c55..fc1f387 100644
--- a/app/gui/qt/udp.hh
+++ b/app/gui/qt/udp.hh
@@ -54,6 +54,7 @@
 #include <cassert>
 #include <string>
 #include <vector>
+#include <iostream>
 
 namespace oscpkt {
 
diff --git a/app/gui/qt/win-build-app.bat b/app/gui/qt/win-build-app.bat
index 0ad0f27..7b204fb 100644
--- a/app/gui/qt/win-build-app.bat
+++ b/app/gui/qt/win-build-app.bat
@@ -3,6 +3,7 @@ cd %~dp0
 copy /Y ruby_help.tmpl ruby_help.h
 ..\..\server\native\windows\ruby\bin\ruby ../../server/bin/qt-doc.rb -o ruby_help.h
 @IF ERRORLEVEL==9009 goto :noruby
+ at IF ERRORLEVEL==1 goto :docfail
 
 lrelease SonicPi.pro
 @IF ERRORLEVEL==9009 goto :noqt
@@ -17,6 +18,10 @@ nmake
 nmake install
 cd release
 windeployqt Sonic-Pi.exe -printsupport
+
+ at echo Removing faulty english translation file
+if exist translations\qt_en.qm del translations\qt_en.qm
+
 cd ..
 
 @goto :done
@@ -33,4 +38,8 @@ cd ..
 @echo Did not find VS2013 tools in your PATH, please start a command prompt from Visual Studio 2013/Visual Studio Tools/VS2013 x86 Native Tools Command Prompt
 @goto :done
 
+:docfail
+ at echo qt-doc.rb failed, which means everything else will fail as well -- fix Ruby environment first
+ at goto :done
+
 :done
diff --git a/app/server/bin/compile-extensions.rb b/app/server/bin/compile-extensions.rb
index 2bd5259..8d00b6f 100755
--- a/app/server/bin/compile-extensions.rb
+++ b/app/server/bin/compile-extensions.rb
@@ -4,7 +4,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/bin/doc.rb b/app/server/bin/doc.rb
index ae3dd5e..c1e5674 100755
--- a/app/server/bin/doc.rb
+++ b/app/server/bin/doc.rb
@@ -4,7 +4,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/bin/qt-doc.rb b/app/server/bin/qt-doc.rb
index c5588fd..b6d0cc4 100755
--- a/app/server/bin/qt-doc.rb
+++ b/app/server/bin/qt-doc.rb
@@ -4,7 +4,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/bin/sonic-pi-server.rb b/app/server/bin/sonic-pi-server.rb
index c489b54..9c4ac71 100755
--- a/app/server/bin/sonic-pi-server.rb
+++ b/app/server/bin/sonic-pi-server.rb
@@ -4,7 +4,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -13,6 +13,7 @@
 #++
 
 require 'cgi'
+require 'rbconfig'
 
 require_relative "../core.rb"
 require_relative "../sonicpi/lib/sonicpi/studio"
@@ -28,6 +29,8 @@ require_relative "../sonicpi/lib/sonicpi/runtime"
 
 require 'multi_json'
 
+puts "Sonic Pi server booting..."
+
 include SonicPi::Util
 
 server_port = ARGV[1] ? ARGV[0].to_i : 4557
@@ -42,19 +45,6 @@ protocol = case ARGV[0]
 
 puts "Using protocol: #{protocol}"
 
-os = case RUBY_PLATFORM
-     when /.*arm.*-linux.*/
-       :raspberry
-     when /.*linux.*/
-       :linux
-     when /.*darwin.*/
-       :osx
-     when /.*mingw.*/
-       :windows
-     else
-       RUBY_PLATFORM
-     end
-
 if protocol == :tcp
   gui = SonicPi::OSC::TCPClient.new("127.0.0.1", client_port, use_encoder_cache: true)
 else
@@ -82,21 +72,25 @@ end
 
 
 at_exit do
+  STDOUT.puts "Server is exiting."
   begin
+    STDOUT.puts "Shutting down GUI..."
     gui.send("/exited")
   rescue Errno::EPIPE => e
     STDERR.puts "GUI not listening."
   end
+  STDOUT.puts "Goodbye :-)"
 end
 
 user_methods = Module.new
-name = "SonicPiSpiderUser1" # this should be autogenerated
+name = "SonicPiLang" # this should be autogenerated
 klass = Object.const_set name, Class.new(SonicPi::Runtime)
 
 klass.send(:include, user_methods)
 klass.send(:include, SonicPi::Lang::Core)
 klass.send(:include, SonicPi::Lang::Sound)
 klass.send(:include, SonicPi::Lang::Minecraft)
+klass.send(:define_method, :inspect) { "Runtime" }
 #klass.send(:include, SonicPi::Lang::Pattern)
 
 ws_out = Queue.new
@@ -108,10 +102,14 @@ begin
   if File.exists?(init_path)
     sp.__spider_eval(File.read(init_path))
   else
+    begin
     File.open(init_path, "w") do |f|
       f.puts "# Sonic Pi init file"
       f.puts "# Code in here will be evaluated on launch."
       f.puts ""
+      end
+    rescue
+      log "Warning: unable to create init file at #{init_path}"
     end
   end
 
@@ -159,7 +157,17 @@ osc_server.add_method("/load-buffer") do |args|
   sp.__load_buffer args[1]
 end
 
-osc_server.add_method("/complete-snippet-or-indent-selection") do |args|
+osc_server.add_method("/buffer-newline-and-indent") do |args|
+  gui_id = args[0]
+  id = args[1]
+  buf = args[2]
+  point_line = args[3]
+  point_index = args[4]
+  first_line = args[5]
+  sp.__buffer_newline_and_indent(id, buf, point_line, point_index, first_line)
+end
+
+osc_server.add_method("/buffer-section-complete-snippet-or-indent-selection") do |args|
   gui_id = args[0]
   id = args[1]
   buf = args[2]
@@ -167,10 +175,21 @@ osc_server.add_method("/complete-snippet-or-indent-selection") do |args|
   finish_line = args[4]
   point_line = args[5]
   point_index = args[6]
-  sp.__complete_snippet_or_indent_lines(id, buf, start_line, finish_line, point_line, point_index)
+  sp.__buffer_complete_snippet_or_indent_lines(id, buf, start_line, finish_line, point_line, point_index)
 end
 
-osc_server.add_method("/toggle-comment") do |args|
+osc_server.add_method("/buffer-indent-selection") do |args|
+  gui_id = args[0]
+  id = args[1]
+  buf = args[2]
+  start_line = args[3]
+  finish_line = args[4]
+  point_line = args[5]
+  point_index = args[6]
+  sp.__buffer_indent_lines(id, buf, start_line, finish_line, point_line, point_index)
+end
+
+osc_server.add_method("/buffer-section-toggle-comment") do |args|
   gui_id = args[0]
   id = args[1]
   buf = args[2]
@@ -181,14 +200,14 @@ osc_server.add_method("/toggle-comment") do |args|
   sp.__toggle_comment(id, buf, start_line, finish_line, point_line, point_index)
 end
 
-osc_server.add_method("/beautify-buffer") do |args|
+osc_server.add_method("/buffer-beautify") do |args|
   gui_id = args[0]
   id = args[1]
   buf = args[2]
   line = args[3]
   index = args[4]
   first_line = args[5]
-  sp.__beautify_buffer(id, buf, line, index, first_line)
+  sp.__buffer_beautify(id, buf, line, index, first_line)
 end
 
 osc_server.add_method("/ping") do |args|
@@ -318,7 +337,7 @@ out_t = Thread.new do
         when :multi_message
           gui.send("/multi_message", message[:jobid], message[:thread_name].to_s, message[:runtime].to_s, message[:val].size, *message[:val].flatten)
         when :info
-          gui.send("/info", message[:val])
+          gui.send("/info", message[:style] || 0, message[:val] || "")
         when :syntax_error
           desc = message[:val] || ""
           line = message[:line] || -1
@@ -376,4 +395,9 @@ out_t = Thread.new do
   end
 end
 
+puts "This is Sonic Pi #{sp.__current_version} running on #{os} with ruby api #{RbConfig::CONFIG['ruby_version']}."
+puts "Sonic Pi Server successfully booted."
+
+STDOUT.flush
+
 out_t.join
diff --git a/app/server/bin/standalone.rb b/app/server/bin/standalone.rb
index bacf396..558d159 100755
--- a/app/server/bin/standalone.rb
+++ b/app/server/bin/standalone.rb
@@ -4,7 +4,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/bin/test.rb b/app/server/bin/test.rb
index 72a6552..297cc09 100755
--- a/app/server/bin/test.rb
+++ b/app/server/bin/test.rb
@@ -4,7 +4,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/bin/ws.rb b/app/server/bin/ws.rb
index 3c3ca61..c731654 100755
--- a/app/server/bin/ws.rb
+++ b/app/server/bin/ws.rb
@@ -4,7 +4,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/core.rb b/app/server/core.rb
index f4d2bc6..16eb2f4 100755
--- a/app/server/core.rb
+++ b/app/server/core.rb
@@ -4,7 +4,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -31,7 +31,26 @@ os = case RUBY_PLATFORM
      else
        RUBY_PLATFORM
      end
-$:.unshift "#{File.expand_path("../rb-native", __FILE__)}/#{os}/#{ruby_api}/"
+ruby_gem_native_path = "#{File.expand_path("../rb-native", __FILE__)}"
+ruby_gem_api_path = "#{ruby_gem_native_path}/#{os}/#{ruby_api}"
+
+unless File.directory?(ruby_gem_api_path)
+  STDERR.puts "*** COULD NOT FIND RUBY GEMS REQUIRED BY SONIC PI ***"
+  STDERR.puts "Directory '#{ruby_gem_api_path}' not found."
+  STDERR.puts "Your ruby interpreter is '#{RbConfig.ruby}', supporting ruby api #{ruby_api}."
+  Dir.entries("#{ruby_gem_native_path}/#{os}/")
+    .select { |d| (File.directory?("#{ruby_gem_native_path}/#{os}/#{d}") && d != '.' && d != '..') }
+    .each do |installed_ruby_api|
+      STDERR.puts "The Sonic Pi on your computer was installed for ruby api #{installed_ruby_api}."
+    end
+  STDERR.puts "Please refer to the Sonic Pi install instructions."
+  STDERR.puts "For installation, you need to run 'app/server/bin/compile-extensions.rb'."
+  STDERR.puts "If you change or upgrade your ruby interpreter later, you may need to run it again."
+
+  raise "Could not access ruby gem directory"
+end
+
+$:.unshift ruby_gem_api_path
 
 require 'win32/process' if os == :windows
 
@@ -52,8 +71,13 @@ require 'wavefile'
 module SonicPi
   module Core
     module SPRand
+      # use FHS directory scheme:
+      # check if Sonic Pi's ruby server is not running inside the
+      # user's home directory, but is installed in /usr/lib/sonic-pi
+      # on Linux from a distribution's package
+      random_numbers_path = File.dirname(__FILE__).start_with?("/usr/lib/sonic-pi") ? "/usr/share/sonic-pi" : "../../../etc"
       # Read in same random numbers as server for random stream sync
-      @@random_numbers = ::WaveFile::Reader.new(File.expand_path("../../../etc/buffers/rand-stream.wav", __FILE__), ::WaveFile::Format.new(:mono, :float, 44100)).read(441000).samples.freeze
+      @@random_numbers = ::WaveFile::Reader.new(File.expand_path("#{random_numbers_path}/buffers/rand-stream.wav", __FILE__), ::WaveFile::Format.new(:mono, :float, 44100)).read(441000).samples.freeze
 
       def self.to_a
         @@random_numbers
@@ -93,6 +117,11 @@ module SonicPi
         Thread.current.thread_variable_get(:sonic_pi_spider_random_gen_idx) || 0
       end
 
+      def self.get_seed_plus_idx
+        (Thread.current.thread_variable_get(:sonic_pi_spider_random_gen_idx) || 0) +
+          Thread.current.thread_variable_get(:sonic_pi_spider_random_gen_seed) || 0
+      end
+
       def self.rand!(max=1, idx=nil)
         idx = inc_idx! unless idx
         rand_peek(max, idx)
@@ -212,7 +241,6 @@ module SonicPi
     class SPVector < Hamster::Vector
       include TLMixin
       def initialize(list)
-        raise EmptyVectorError, "Cannot create an empty vector" if list.empty?
         super
       end
 
@@ -224,8 +252,36 @@ module SonicPi
         self.class.new(a)
       end
 
+      def list_diff(other)
+        ___sp_preserve_vec_kind(self.to_a - other.to_a)
+      end
+
+      def list_concat(other)
+        ___sp_preserve_vec_kind(self.to_a + other.to_a)
+      end
+
+      def -(other)
+        if other.is_a?(Array) || other.is_a?(SPVector)
+          return list_diff(other)
+        else
+          o = other.to_f
+          return self.map{|el| el - o}
+        end
+      end
+
+      def +(other)
+        if other.is_a?(Array) || other.is_a?(SPVector)
+          return list_concat(other)
+        else
+          o = other.to_f
+          return self.map{|el| el + o}
+        end
+      end
+
       def [](idx, len=(missing_length = true))
+        return nil unless idx
         raise InvalidIndexError, "Invalid index: #{idx.inspect}, was expecting a number or range" unless idx && (idx.is_a?(Numeric) || idx.is_a?(Range))
+        return nil if self.empty?
         if idx.is_a?(Numeric) && missing_length
           idx = map_index(idx)
           super idx
@@ -286,6 +342,51 @@ module SonicPi
         drop_last(1)
       end
 
+      def take(n)
+        return [].ring if n == 0
+        return self.reverse.take(-n) if n < 0
+        return super if n <= @size
+        self + take(n - @size)
+      end
+
+      def drop(n)
+        return [].ring if n >= @size
+        super
+      end
+
+      def pick(n=nil, *opts)
+        # mangle args to extract nice behaviour
+        if !n.is_a?(Numeric) && opts.empty?
+          opts = n
+          n = nil
+        else
+          opts = opts[0]
+        end
+
+        if opts.is_a?(Hash)
+          s = opts[:skip]
+        else
+          s = nil
+        end
+
+        n = @size unless n
+        raise "pick requires n to be a number, got: #{n.inspect}" unless n.is_a? Numeric
+
+        res = []
+        if s
+          raise "skip: opt needs to be a number, got: #{s.inspect}" unless s.is_a? Numeric
+          n.times do
+            SonicPi::Core::SPRand.inc_idx!(s)
+            res << self.choose
+          end
+        else
+          n.times do
+            res << self.choose
+          end
+        end
+        res.ring
+      end
+
       def inspect
         a = self.to_a
         if a.empty?
@@ -308,6 +409,10 @@ module SonicPi
         end
         ___sp_preserve_vec_kind(res)
       end
+
+      def map_index(idx)
+        idx
+      end
     end
 
     class RingVector < SPVector
@@ -448,6 +553,17 @@ class Array
     self[SonicPi::Core::SPRand.rand_i!(self.size)]
   end
 
+  def pick(n=nil)
+    n = @size unless n
+    raise "pick requires n to be a number, got: #{n.inspect}" unless n.is_a? Numeric
+
+    res = []
+    n.times do
+      res << self.choose
+    end
+    res
+  end
+
   alias_method :__orig_sample__, :sample
   def sample(*args, &blk)
 
diff --git a/app/server/native/osx/.gitkeep b/app/server/native/osx/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/native/raspberry/extra-ugens b/app/server/native/raspberry/extra-ugens
new file mode 120000
index 0000000..c4e3d69
--- /dev/null
+++ b/app/server/native/raspberry/extra-ugens
@@ -0,0 +1 @@
+extra-ugens-jessie
\ No newline at end of file
diff --git a/app/server/native/raspberry/extra-ugens-jessie/AY_UGen.so b/app/server/native/raspberry/extra-ugens-jessie/AY_UGen.so
new file mode 100755
index 0000000..4941774
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/AY_UGen.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/AmbisonicUGens.so b/app/server/native/raspberry/extra-ugens-jessie/AmbisonicUGens.so
new file mode 100755
index 0000000..fc561dd
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/AmbisonicUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/AntiAliasingOscillators.so b/app/server/native/raspberry/extra-ugens-jessie/AntiAliasingOscillators.so
new file mode 100755
index 0000000..be42c86
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/AntiAliasingOscillators.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/AtkUGens.so b/app/server/native/raspberry/extra-ugens-jessie/AtkUGens.so
new file mode 100755
index 0000000..569d425
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/AtkUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/AttackSlope.so b/app/server/native/raspberry/extra-ugens-jessie/AttackSlope.so
new file mode 100755
index 0000000..ecd63de
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/AttackSlope.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/AuditoryModeling.so b/app/server/native/raspberry/extra-ugens-jessie/AuditoryModeling.so
new file mode 100755
index 0000000..665f9c0
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/AuditoryModeling.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/BBCut2UGens.so b/app/server/native/raspberry/extra-ugens-jessie/BBCut2UGens.so
new file mode 100755
index 0000000..b056bd2
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/BBCut2UGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/BatPVUgens.so b/app/server/native/raspberry/extra-ugens-jessie/BatPVUgens.so
new file mode 100755
index 0000000..ebe0f8f
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/BatPVUgens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/BatUGens.so b/app/server/native/raspberry/extra-ugens-jessie/BatUGens.so
new file mode 100755
index 0000000..d041b1d
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/BatUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/BeatStatistics.so b/app/server/native/raspberry/extra-ugens-jessie/BeatStatistics.so
new file mode 100755
index 0000000..0505358
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/BeatStatistics.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/BerlachUGens.so b/app/server/native/raspberry/extra-ugens-jessie/BerlachUGens.so
new file mode 100755
index 0000000..1d4ff6d
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/BerlachUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/BetablockerUGens.so b/app/server/native/raspberry/extra-ugens-jessie/BetablockerUGens.so
new file mode 100755
index 0000000..905f0ec
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/BetablockerUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/BhobChaos.so b/app/server/native/raspberry/extra-ugens-jessie/BhobChaos.so
new file mode 100755
index 0000000..8be44b7
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/BhobChaos.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/BhobFFT.so b/app/server/native/raspberry/extra-ugens-jessie/BhobFFT.so
new file mode 100755
index 0000000..8893afd
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/BhobFFT.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/BhobFilt.so b/app/server/native/raspberry/extra-ugens-jessie/BhobFilt.so
new file mode 100755
index 0000000..bca56b3
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/BhobFilt.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/BhobGrain.so b/app/server/native/raspberry/extra-ugens-jessie/BhobGrain.so
new file mode 100755
index 0000000..61c30ec
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/BhobGrain.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/BhobNoise.so b/app/server/native/raspberry/extra-ugens-jessie/BhobNoise.so
new file mode 100755
index 0000000..6f310fe
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/BhobNoise.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/BlackrainUGens.so b/app/server/native/raspberry/extra-ugens-jessie/BlackrainUGens.so
new file mode 100755
index 0000000..da8f27a
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/BlackrainUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/Chromagram.so b/app/server/native/raspberry/extra-ugens-jessie/Chromagram.so
new file mode 100755
index 0000000..d6f3302
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/Chromagram.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/Concat.so b/app/server/native/raspberry/extra-ugens-jessie/Concat.so
new file mode 100755
index 0000000..c698970
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/Concat.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/DWGBowed.so b/app/server/native/raspberry/extra-ugens-jessie/DWGBowed.so
new file mode 100755
index 0000000..7639609
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/DWGBowed.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/DWGPlucked.so b/app/server/native/raspberry/extra-ugens-jessie/DWGPlucked.so
new file mode 100755
index 0000000..4ec442b
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/DWGPlucked.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/DiodeRingMod.so b/app/server/native/raspberry/extra-ugens-jessie/DiodeRingMod.so
new file mode 100755
index 0000000..c7f246b
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/DiodeRingMod.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/DistortionUGens.so b/app/server/native/raspberry/extra-ugens-jessie/DistortionUGens.so
new file mode 100755
index 0000000..e762340
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/DistortionUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/FM7.so b/app/server/native/raspberry/extra-ugens-jessie/FM7.so
new file mode 100755
index 0000000..0fcb478
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/FM7.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/FeatureSave.so b/app/server/native/raspberry/extra-ugens-jessie/FeatureSave.so
new file mode 100755
index 0000000..1d3d781
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/FeatureSave.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/GlitchUGens.so b/app/server/native/raspberry/extra-ugens-jessie/GlitchUGens.so
new file mode 100755
index 0000000..e6fb915
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/GlitchUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/Greyhole.so b/app/server/native/raspberry/extra-ugens-jessie/Greyhole.so
new file mode 100755
index 0000000..c713aa6
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/Greyhole.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/JPverb.so b/app/server/native/raspberry/extra-ugens-jessie/JPverb.so
new file mode 100755
index 0000000..6c3567e
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/JPverb.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/JoshAmbiUGens.so b/app/server/native/raspberry/extra-ugens-jessie/JoshAmbiUGens.so
new file mode 100755
index 0000000..1bf1b70
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/JoshAmbiUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/JoshGrainUGens.so b/app/server/native/raspberry/extra-ugens-jessie/JoshGrainUGens.so
new file mode 100755
index 0000000..d1e4762
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/JoshGrainUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/JoshPVUGens.so b/app/server/native/raspberry/extra-ugens-jessie/JoshPVUGens.so
new file mode 100755
index 0000000..3e63ed3
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/JoshPVUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/JoshUGens.so b/app/server/native/raspberry/extra-ugens-jessie/JoshUGens.so
new file mode 100755
index 0000000..ea20259
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/JoshUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/KeyClarity.so b/app/server/native/raspberry/extra-ugens-jessie/KeyClarity.so
new file mode 100755
index 0000000..a41797a
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/KeyClarity.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/KeyMode.so b/app/server/native/raspberry/extra-ugens-jessie/KeyMode.so
new file mode 100755
index 0000000..a551be7
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/KeyMode.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/LadspaUGen.so b/app/server/native/raspberry/extra-ugens-jessie/LadspaUGen.so
new file mode 100755
index 0000000..9df0554
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/LadspaUGen.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/LoopBuf.so b/app/server/native/raspberry/extra-ugens-jessie/LoopBuf.so
new file mode 100755
index 0000000..c4ccd3b
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/LoopBuf.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/MCLDBufferUGens.so b/app/server/native/raspberry/extra-ugens-jessie/MCLDBufferUGens.so
new file mode 100755
index 0000000..66f9fe3
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/MCLDBufferUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/MCLDCepstrumUGens.so b/app/server/native/raspberry/extra-ugens-jessie/MCLDCepstrumUGens.so
new file mode 100755
index 0000000..d01147d
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/MCLDCepstrumUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/MCLDChaosUGens.so b/app/server/native/raspberry/extra-ugens-jessie/MCLDChaosUGens.so
new file mode 100755
index 0000000..d4cb26e
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/MCLDChaosUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/MCLDDistortionUGens.so b/app/server/native/raspberry/extra-ugens-jessie/MCLDDistortionUGens.so
new file mode 100755
index 0000000..7f79692
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/MCLDDistortionUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/MCLDFFTUGens.so b/app/server/native/raspberry/extra-ugens-jessie/MCLDFFTUGens.so
new file mode 100755
index 0000000..32aab2d
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/MCLDFFTUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/MCLDFilterUGens.so b/app/server/native/raspberry/extra-ugens-jessie/MCLDFilterUGens.so
new file mode 100755
index 0000000..6dac1d4
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/MCLDFilterUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/MCLDGetenvUGen.so b/app/server/native/raspberry/extra-ugens-jessie/MCLDGetenvUGen.so
new file mode 100755
index 0000000..e6b7462
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/MCLDGetenvUGen.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/MCLDOscUGens.so b/app/server/native/raspberry/extra-ugens-jessie/MCLDOscUGens.so
new file mode 100755
index 0000000..b4bd4c5
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/MCLDOscUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/MCLDPollUGens.so b/app/server/native/raspberry/extra-ugens-jessie/MCLDPollUGens.so
new file mode 100755
index 0000000..60b503d
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/MCLDPollUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/MCLDSOMUGens.so b/app/server/native/raspberry/extra-ugens-jessie/MCLDSOMUGens.so
new file mode 100755
index 0000000..e9a3c52
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/MCLDSOMUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/MCLDSparseUGens.so b/app/server/native/raspberry/extra-ugens-jessie/MCLDSparseUGens.so
new file mode 100755
index 0000000..7a98b64
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/MCLDSparseUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/MCLDTreeUGens.so b/app/server/native/raspberry/extra-ugens-jessie/MCLDTreeUGens.so
new file mode 100755
index 0000000..d4d97ee
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/MCLDTreeUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/MCLDTriggeredStatsUgens.so b/app/server/native/raspberry/extra-ugens-jessie/MCLDTriggeredStatsUgens.so
new file mode 100755
index 0000000..7c28519
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/MCLDTriggeredStatsUgens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/MdaUGens.so b/app/server/native/raspberry/extra-ugens-jessie/MdaUGens.so
new file mode 100755
index 0000000..6e940aa
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/MdaUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/MembraneUGens.so b/app/server/native/raspberry/extra-ugens-jessie/MembraneUGens.so
new file mode 100755
index 0000000..ed957ad
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/MembraneUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/NCAnalysisUGens.so b/app/server/native/raspberry/extra-ugens-jessie/NCAnalysisUGens.so
new file mode 100755
index 0000000..cccf4b8
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/NCAnalysisUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/Neuromodules.so b/app/server/native/raspberry/extra-ugens-jessie/Neuromodules.so
new file mode 100755
index 0000000..8f7e39f
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/Neuromodules.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/NoiseRing.so b/app/server/native/raspberry/extra-ugens-jessie/NoiseRing.so
new file mode 100755
index 0000000..ac36780
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/NoiseRing.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/OnsetStatistics.so b/app/server/native/raspberry/extra-ugens-jessie/OnsetStatistics.so
new file mode 100755
index 0000000..671642d
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/OnsetStatistics.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/OteyPianoUGens.so b/app/server/native/raspberry/extra-ugens-jessie/OteyPianoUGens.so
new file mode 100755
index 0000000..1f80613
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/OteyPianoUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/PitchDetection.so b/app/server/native/raspberry/extra-ugens-jessie/PitchDetection.so
new file mode 100755
index 0000000..b1b9ed5
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/PitchDetection.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/RFWUGens.so b/app/server/native/raspberry/extra-ugens-jessie/RFWUGens.so
new file mode 100755
index 0000000..a745a71
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/RFWUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/RMEQSuite.so b/app/server/native/raspberry/extra-ugens-jessie/RMEQSuite.so
new file mode 100755
index 0000000..8778967
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/RMEQSuite.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/SLUGens.so b/app/server/native/raspberry/extra-ugens-jessie/SLUGens.so
new file mode 100755
index 0000000..47a88c0
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/SLUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/SensoryDissonance.so b/app/server/native/raspberry/extra-ugens-jessie/SensoryDissonance.so
new file mode 100755
index 0000000..12f8ec3
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/SensoryDissonance.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/StkUGens.so b/app/server/native/raspberry/extra-ugens-jessie/StkUGens.so
new file mode 100755
index 0000000..4b9ec3b
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/StkUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/SummerUGens.so b/app/server/native/raspberry/extra-ugens-jessie/SummerUGens.so
new file mode 100755
index 0000000..a3cafb5
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/SummerUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/TJUGens.so b/app/server/native/raspberry/extra-ugens-jessie/TJUGens.so
new file mode 100755
index 0000000..95b3ae1
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/TJUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/TagSystemUgens.so b/app/server/native/raspberry/extra-ugens-jessie/TagSystemUgens.so
new file mode 100755
index 0000000..9f7aea0
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/TagSystemUgens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/VBAP.so b/app/server/native/raspberry/extra-ugens-jessie/VBAP.so
new file mode 100755
index 0000000..b86acef
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/VBAP.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/VOSIM.so b/app/server/native/raspberry/extra-ugens-jessie/VOSIM.so
new file mode 100755
index 0000000..b3a1da3
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/VOSIM.so differ
diff --git a/app/server/native/raspberry/extra-ugens-jessie/complexRes.so b/app/server/native/raspberry/extra-ugens-jessie/complexRes.so
new file mode 100755
index 0000000..f24e0f1
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-jessie/complexRes.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/AY_UGen.so b/app/server/native/raspberry/extra-ugens-wheezy/AY_UGen.so
new file mode 100755
index 0000000..d02aab8
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/AY_UGen.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/AmbisonicUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/AmbisonicUGens.so
new file mode 100755
index 0000000..0692a1f
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/AmbisonicUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/AtkUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/AtkUGens.so
new file mode 100755
index 0000000..833d2d5
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/AtkUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/BatUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/BatUGens.so
new file mode 100755
index 0000000..056adab
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/BatUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/BerlachUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/BerlachUGens.so
new file mode 100755
index 0000000..8d4bc94
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/BerlachUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/BhobChaos.so b/app/server/native/raspberry/extra-ugens-wheezy/BhobChaos.so
new file mode 100755
index 0000000..4309d3f
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/BhobChaos.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/BhobFilt.so b/app/server/native/raspberry/extra-ugens-wheezy/BhobFilt.so
new file mode 100755
index 0000000..c568f61
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/BhobFilt.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/BhobGrain.so b/app/server/native/raspberry/extra-ugens-wheezy/BhobGrain.so
new file mode 100755
index 0000000..24192cb
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/BhobGrain.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/BhobNoise.so b/app/server/native/raspberry/extra-ugens-wheezy/BhobNoise.so
new file mode 100755
index 0000000..fcbdb26
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/BhobNoise.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/BlackrainUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/BlackrainUGens.so
new file mode 100755
index 0000000..c5e9289
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/BlackrainUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/DistortionUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/DistortionUGens.so
new file mode 100755
index 0000000..1a380ca
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/DistortionUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/GlitchUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/GlitchUGens.so
new file mode 100755
index 0000000..7ce714c
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/GlitchUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/JoshAmbiUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/JoshAmbiUGens.so
new file mode 100755
index 0000000..5ab7f3a
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/JoshAmbiUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/JoshGrainUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/JoshGrainUGens.so
new file mode 100755
index 0000000..c997ddd
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/JoshGrainUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/JoshUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/JoshUGens.so
new file mode 100755
index 0000000..d8d9eb3
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/JoshUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/LadspaUGen.so b/app/server/native/raspberry/extra-ugens-wheezy/LadspaUGen.so
new file mode 100755
index 0000000..bf54c50
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/LadspaUGen.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/LoopBuf.so b/app/server/native/raspberry/extra-ugens-wheezy/LoopBuf.so
new file mode 100755
index 0000000..87e9a24
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/LoopBuf.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/MCLDBufferUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/MCLDBufferUGens.so
new file mode 100755
index 0000000..d3a4315
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/MCLDBufferUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/MCLDChaosUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/MCLDChaosUGens.so
new file mode 100755
index 0000000..d370585
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/MCLDChaosUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/MCLDDistortionUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/MCLDDistortionUGens.so
new file mode 100755
index 0000000..9a63ed7
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/MCLDDistortionUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/MCLDFilterUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/MCLDFilterUGens.so
new file mode 100755
index 0000000..db7cd36
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/MCLDFilterUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/MCLDGetenvUGen.so b/app/server/native/raspberry/extra-ugens-wheezy/MCLDGetenvUGen.so
new file mode 100755
index 0000000..9798d4d
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/MCLDGetenvUGen.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/MCLDOscUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/MCLDOscUGens.so
new file mode 100755
index 0000000..07c9730
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/MCLDOscUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/MCLDPollUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/MCLDPollUGens.so
new file mode 100755
index 0000000..2c943e3
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/MCLDPollUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/MCLDSOMUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/MCLDSOMUGens.so
new file mode 100755
index 0000000..44afe1c
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/MCLDSOMUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/MCLDTreeUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/MCLDTreeUGens.so
new file mode 100755
index 0000000..dd0d868
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/MCLDTreeUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/MCLDTriggeredStatsUgens.so b/app/server/native/raspberry/extra-ugens-wheezy/MCLDTriggeredStatsUgens.so
new file mode 100755
index 0000000..fd48da2
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/MCLDTriggeredStatsUgens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/MdaUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/MdaUGens.so
new file mode 100755
index 0000000..8699314
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/MdaUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/MembraneUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/MembraneUGens.so
new file mode 100755
index 0000000..1e1e0e4
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/MembraneUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/RFWUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/RFWUGens.so
new file mode 100755
index 0000000..614a2f8
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/RFWUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/RMEQSuite.so b/app/server/native/raspberry/extra-ugens-wheezy/RMEQSuite.so
new file mode 100755
index 0000000..8161e6f
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/RMEQSuite.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/SLUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/SLUGens.so
new file mode 100755
index 0000000..983d627
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/SLUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/StkUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/StkUGens.so
new file mode 100755
index 0000000..a1485ed
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/StkUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/SummerUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/SummerUGens.so
new file mode 100755
index 0000000..e4c812f
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/SummerUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/TJUGens.so b/app/server/native/raspberry/extra-ugens-wheezy/TJUGens.so
new file mode 100755
index 0000000..c2087da
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/TJUGens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/TagSystemUgens.so b/app/server/native/raspberry/extra-ugens-wheezy/TagSystemUgens.so
new file mode 100755
index 0000000..7ca272a
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/TagSystemUgens.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/VBAP.so b/app/server/native/raspberry/extra-ugens-wheezy/VBAP.so
new file mode 100755
index 0000000..77c182b
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/VBAP.so differ
diff --git a/app/server/native/raspberry/extra-ugens-wheezy/VOSIM.so b/app/server/native/raspberry/extra-ugens-wheezy/VOSIM.so
new file mode 100755
index 0000000..1f15d45
Binary files /dev/null and b/app/server/native/raspberry/extra-ugens-wheezy/VOSIM.so differ
diff --git a/app/server/sonicpi/lib/sonicpi/allocator.rb b/app/server/sonicpi/lib/sonicpi/allocator.rb
index 94af3f2..88cbd77 100644
--- a/app/server/sonicpi/lib/sonicpi/allocator.rb
+++ b/app/server/sonicpi/lib/sonicpi/allocator.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/atom.rb b/app/server/sonicpi/lib/sonicpi/atom.rb
index c716160..ce9381c 100644
--- a/app/server/sonicpi/lib/sonicpi/atom.rb
+++ b/app/server/sonicpi/lib/sonicpi/atom.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/audiobus.rb b/app/server/sonicpi/lib/sonicpi/audiobus.rb
index e905a47..1fb4308 100644
--- a/app/server/sonicpi/lib/sonicpi/audiobus.rb
+++ b/app/server/sonicpi/lib/sonicpi/audiobus.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/audiobusallocator.rb b/app/server/sonicpi/lib/sonicpi/audiobusallocator.rb
index cc2fbd6..4d15340 100644
--- a/app/server/sonicpi/lib/sonicpi/audiobusallocator.rb
+++ b/app/server/sonicpi/lib/sonicpi/audiobusallocator.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/blanknode.rb b/app/server/sonicpi/lib/sonicpi/blanknode.rb
index 81b0b44..18a5134 100644
--- a/app/server/sonicpi/lib/sonicpi/blanknode.rb
+++ b/app/server/sonicpi/lib/sonicpi/blanknode.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/buffer.rb b/app/server/sonicpi/lib/sonicpi/buffer.rb
index eaeeacf..a957b93 100644
--- a/app/server/sonicpi/lib/sonicpi/buffer.rb
+++ b/app/server/sonicpi/lib/sonicpi/buffer.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -42,9 +42,9 @@ module SonicPi
 
     def to_s
       if @path
-        "#<Buffer @id=#{@id}, @num_chans=#{@num_chans}, @num_frames=#{num_frames}, @sample_rate=#{@sample_rate}, @duration=#{@duration}, @path=#{@path}>"
+        "#<Buffer @id=#{@id}, @num_chans=#{@num_chans}, @num_frames=#{@num_frames}, @sample_rate=#{@sample_rate}, @duration=#{@duration}, @path=#{@path}>"
       else
-        "#<Buffer @id=#{@id}, @num_chans=#{@num_chans}, @num_frames=#{num_frames}, @sample_rate=#{@sample_rate}, @duration=#{@duration}>"
+        "#<Buffer @id=#{@id}, @num_chans=#{@num_chans}, @num_frames=#{@num_frames}, @sample_rate=#{@sample_rate}, @duration=#{@duration}>"
       end
     end
 
diff --git a/app/server/sonicpi/lib/sonicpi/bufferstream.rb b/app/server/sonicpi/lib/sonicpi/bufferstream.rb
index 3b829f7..20d6432 100644
--- a/app/server/sonicpi/lib/sonicpi/bufferstream.rb
+++ b/app/server/sonicpi/lib/sonicpi/bufferstream.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/bus.rb b/app/server/sonicpi/lib/sonicpi/bus.rb
index deb80b2..243e372 100644
--- a/app/server/sonicpi/lib/sonicpi/bus.rb
+++ b/app/server/sonicpi/lib/sonicpi/bus.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/busallocator.rb b/app/server/sonicpi/lib/sonicpi/busallocator.rb
index 4091117..470ca7c 100644
--- a/app/server/sonicpi/lib/sonicpi/busallocator.rb
+++ b/app/server/sonicpi/lib/sonicpi/busallocator.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/chainnode.rb b/app/server/sonicpi/lib/sonicpi/chainnode.rb
index 3f0321c..8a7d54f 100644
--- a/app/server/sonicpi/lib/sonicpi/chainnode.rb
+++ b/app/server/sonicpi/lib/sonicpi/chainnode.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/chord.rb b/app/server/sonicpi/lib/sonicpi/chord.rb
index 6b45cba..e47fea2 100644
--- a/app/server/sonicpi/lib/sonicpi/chord.rb
+++ b/app/server/sonicpi/lib/sonicpi/chord.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -61,6 +61,16 @@ module SonicPi
         "m11+"        => [0, 3, 7, 10, 14, 18],
         "13"          => [0, 4, 7, 10, 14, 17, 21],
         "m13"         => [0, 3, 7, 10, 14, 17, 21],
+        "add2"        => [0, 2, 4, 7],
+        "add4"        => [0, 4, 5, 7],
+        "add9"        => [0, 4, 7, 14],
+        "add11"       => [0, 4, 7, 17],
+        "add13"       => [0, 4, 7, 21],
+        "madd2"       => [0, 2, 3, 7],
+        "madd4"       => [0, 3, 5, 7],
+        "madd9"       => [0, 3, 7, 14],
+        "madd11"      => [0, 3, 7, 17],
+        "madd13"      => [0, 3, 7, 21],
         "major"       => major,
         "M"           => major,
         "minor"       => minor,
diff --git a/app/server/sonicpi/lib/sonicpi/chordgroup.rb b/app/server/sonicpi/lib/sonicpi/chordgroup.rb
index 3f0a4b6..75e2c09 100644
--- a/app/server/sonicpi/lib/sonicpi/chordgroup.rb
+++ b/app/server/sonicpi/lib/sonicpi/chordgroup.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/config/settings.rb b/app/server/sonicpi/lib/sonicpi/config/settings.rb
index 8e17962..aa495f4 100644
--- a/app/server/sonicpi/lib/sonicpi/config/settings.rb
+++ b/app/server/sonicpi/lib/sonicpi/config/settings.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/controlbus.rb b/app/server/sonicpi/lib/sonicpi/controlbus.rb
index 5b5cdc9..3fe58a9 100644
--- a/app/server/sonicpi/lib/sonicpi/controlbus.rb
+++ b/app/server/sonicpi/lib/sonicpi/controlbus.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/controlbusallocator.rb b/app/server/sonicpi/lib/sonicpi/controlbusallocator.rb
index 57b67e9..17cb13e 100644
--- a/app/server/sonicpi/lib/sonicpi/controlbusallocator.rb
+++ b/app/server/sonicpi/lib/sonicpi/controlbusallocator.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/counter.rb b/app/server/sonicpi/lib/sonicpi/counter.rb
index 58400a0..5e5ac60 100644
--- a/app/server/sonicpi/lib/sonicpi/counter.rb
+++ b/app/server/sonicpi/lib/sonicpi/counter.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/fxnode.rb b/app/server/sonicpi/lib/sonicpi/fxnode.rb
index 4752cb0..b8ff7f9 100644
--- a/app/server/sonicpi/lib/sonicpi/fxnode.rb
+++ b/app/server/sonicpi/lib/sonicpi/fxnode.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/fxreplacenode.rb b/app/server/sonicpi/lib/sonicpi/fxreplacenode.rb
index 98856cb..f62408a 100644
--- a/app/server/sonicpi/lib/sonicpi/fxreplacenode.rb
+++ b/app/server/sonicpi/lib/sonicpi/fxreplacenode.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/gitsave.rb b/app/server/sonicpi/lib/sonicpi/gitsave.rb
index b44dbd7..f11364e 100644
--- a/app/server/sonicpi/lib/sonicpi/gitsave.rb
+++ b/app/server/sonicpi/lib/sonicpi/gitsave.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -33,7 +33,6 @@ module SonicPi
     end
 
     def save!(filename, content, msgpre="")
-      puts "saving: #{filename}"
       oid = @repo.write(content, :blob)
       index = @repo.index
       index.reload
diff --git a/app/server/sonicpi/lib/sonicpi/group.rb b/app/server/sonicpi/lib/sonicpi/group.rb
index 19f0f44..2e13f38 100644
--- a/app/server/sonicpi/lib/sonicpi/group.rb
+++ b/app/server/sonicpi/lib/sonicpi/group.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/incomingevents.rb b/app/server/sonicpi/lib/sonicpi/incomingevents.rb
index 4abf3a2..334654d 100644
--- a/app/server/sonicpi/lib/sonicpi/incomingevents.rb
+++ b/app/server/sonicpi/lib/sonicpi/incomingevents.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -104,6 +104,10 @@ module SonicPi
       to_s
     end
 
+    def shutdown
+      @handler_thread.kill
+    end
+
     private
 
     def q_sync_insert_handler(handle, key, block, prom)
diff --git a/app/server/sonicpi/lib/sonicpi/jobs.rb b/app/server/sonicpi/lib/sonicpi/jobs.rb
index 1fbc1f4..d05701e 100644
--- a/app/server/sonicpi/lib/sonicpi/jobs.rb
+++ b/app/server/sonicpi/lib/sonicpi/jobs.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/lang/core.rb b/app/server/sonicpi/lib/sonicpi/lang/core.rb
index 249343f..e0fa5aa 100644
--- a/app/server/sonicpi/lib/sonicpi/lang/core.rb
+++ b/app/server/sonicpi/lib/sonicpi/lang/core.rb
@@ -4,7 +4,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -14,6 +14,7 @@
 require_relative 'support/docsystem'
 require_relative "../version"
 require_relative "../util"
+require 'active_support/inflector'
 
 ## TODO: create _* equivalents of all fns - for silent (i.e computation) versions
 
@@ -307,6 +308,58 @@ module SonicPi
 
 
 
+      def on(condition, &blk)
+        blk.call if truthy?(condition)
+      end
+      doc name:           :on,
+          introduced:     Version.new(2,10,0),
+          summary:        "Optionally evaluate block",
+          args:           [[:condition, :truthy]],
+          returns:        nil,
+          opts:           nil,
+          accepts_block:  false,
+          doc:            "Optionally evaluate the block depending on the truthiness of the supplied condition. The truthiness rules are as follows: all values are seen as true except for: false, nil and 0. Lambdas will be automatically called and the truthiness of their results used.",
+      examples:       [
+"
+on true do
+  play 70     #=> will play 70 as true is truthy
+end",
+"
+on 1 do
+  play 70     #=> will play 70 as 1 is truthy
+end",
+"
+on 0 do
+  play 70     #=> will *not* play 70 as 0 is not truthy
+end",
+"
+on false do
+  play 70     #=> will *not* play 70 as false is not truthy
+end",
+"
+on nil do
+  play 70     #=> will *not* play 70 as nil is not truthy
+end",
+"
+on lambda{true} do
+  play 70     #=> will play 70 as the lambda returns a truthy value
+end",
+"
+on lambda{false} do
+  play 70     #=> will *not* play 70 as the lambda does not return a truthy value
+end",
+"
+on lambda{[true, false].choose} do
+  play 70     #=> will maybe play 70 depending on the choice in the lambda
+end"
+
+
+
+      ]
+
+
+
+
       def bools(*args)
         args.map do |a|
           if (a == 0) || (not a)
@@ -587,25 +640,65 @@ module SonicPi
 
 
 
-      def octs(start, num_octs=1)
+      def halves(start, num_halves=1)
+        raise "Start value for halves needs to be a number, got: #{start.inspect}" unless start.is_a?(Numeric)
+        start = start.to_f
+        return doubles(start, num_halves * -1) if num_halves < 0
         a = []
-        num_octs.times do |i|
-          a << (note(start) + (12 * i))
+        val = start
+        num_halves.times do
+          a << val
+          val /= 2.0
         end
         a.ring
       end
-      doc name:           :octs,
-          introduced:     Version.new(2,8,0),
-          summary:        "Create a ring of octaves",
-          args:           [[:start, :note], [:num_octaves, :pos_int]],
+      doc name:           :halves,
+          introduced:     Version.new(2,10,0),
+          summary:        "Create a ring of successive halves",
+          args:           [[:start, :number], [:num_halves, :int]],
+          returns:        :ring,
+          opts:           nil,
+          accepts_block:  false,
+          doc:            "Create a ring containing the results of successive halving of the `start` value. If `num_halves` is negative, will return a ring of `doubles`.",
+          examples:       [
+        "(halves 60, 2)  #=> (ring 60, 30)",
+        "(halves 120, 3) #=> (ring 120, 60, 30)",
+        "(halves 120, 5) #=> (ring 120, 60, 30, 15, 7.5)",
+        "(halves 30, -5) #=> (ring 30, 60, 120, 240, 480)"
+      ]
+
+
+
+
+      def doubles(start, num_doubles=1)
+        raise "Start value for doubles needs to be a number, got: #{start.inspect}" unless start.is_a?(Numeric)
+        return halves(start, num_doubles * -1) if num_doubles < 0
+        start = start.to_f
+        a = []
+        val = start
+        num_doubles.times do
+          a << val
+          val *= 2.0
+        end
+        a.ring
+      end
+      doc name:           :doubles,
+          introduced:     Version.new(2,10,0),
+          summary:        "Create a ring of successive doubles",
+          args:           [[:start, :number], [:num_doubles, :int]],
           returns:        :ring,
           opts:           nil,
           accepts_block:  false,
-          doc:            "Create a ring of successive octaves starting at `start` for `num_octaves`. ",
+          doc:            "Create a ring containing the results of successive doubling of the `start` value. If `num_doubles` is negative, will return a ring of `halves`.",
           examples:       [
-        "(octs 60, 2)  #=> (ring 60, 72)",
-        "(octs :e3, 3) #=> (ring 52, 64, 76)"
-]
+        "(doubles 60, 2)  #=> (ring 60, 120)",
+        "(doubles 1.5, 3) #=> (ring 1.5, 3, 6)",
+        "(doubles 1.5, 5) #=> (ring 1.5, 3, 6, 12, 24)",
+        "(doubles 100, -4) #=> (ring 100, 50, 25, 12.5)"
+      ]
+
+
+
 
       def vector(*args)
         SonicPi::Core::SPVector.new(args)
@@ -697,6 +790,32 @@ module SonicPi
 
 
 
+      def pick(items, n=nil, *args)
+        items.pick(n, *args)
+      end
+      doc name:           :pick,
+          introduced:     Version.new(2,10,0),
+          summary:        "Randomly pick from list (with duplicates)",
+          args:           [[:list, :array], [:n, :number_or_nil]],
+          opts:           {:skip => "Number of rands to skip over with each successive pick"},
+          accepts_block:  false,
+          doc:            "Pick n elements from list or ring. Unlike shuffle, after each element has been picked, it is 'returned' to the list so it may be picked again. This means there may be duplicates in the result. If n is greater than the size of the ring/list then duplicates are guaranteed to be in the result.
+
+If `n` isn't supplied it defaults to the size of the list/ring.",
+         examples:       ["
+puts [1, 2, 3, 4, 5].pick(3) #=> [4, 4, 3]",
+"
+puts (ring 1, 2, 3, 4, 5).pick(3) #=> (ring 4, 4, 3)",
+
+"
+puts (ring 1, 2).pick(5) #=> (ring 2, 2, 1, 1, 1)",
+"
+puts (ring 1, 2, 3).pick #=> (ring 3, 3, 2)"
+      ]
+
+
+
+
       def inc(n)
         n + 1
       end
@@ -739,6 +858,10 @@ module SonicPi
         args_h = resolve_synth_opts_hash_or_array(args)
 
         sync_sym = args_h[:sync]
+        sync_bpm_sym = args_h[:sync_bpm]
+        sync_sym = nil if sync_bpm_sym
+
+        raise "livelock detection - live_loop cannot sync with itself - please choose another sync name for live_loop #{name.inspect}" if name == sync_sym || name == sync_bpm_sym
 
         delay = args_h[:delay]
         raise "live_loop's delay: opt must be a number, got #{delay.inspect}" if delay && !delay.is_a?(Numeric)
@@ -762,7 +885,7 @@ module SonicPi
           raise "Live loop block must only accept 0 or 1 args"
         end
 
-        in_thread(name: ll_name, delay: delay, sync: sync_sym) do
+        in_thread(name: ll_name, delay: delay, sync: sync_sym, sync_bpm: sync_bpm_sym) do
           Thread.current.thread_variable_set :sonic_pi__not_inherited__live_loop_auto_cue, auto_cue
           if args_h.has_key?(:init)
             res = args_h[:init]
@@ -793,6 +916,7 @@ module SonicPi
                            :auto_cue => "enable or disable automatic cue (default is true)",
                            :delay    => "Initial delay in beats before the live_loop starts. Default is 0.",
                            :sync     => "Initial sync symbol. Will sync with this symbol before the live_loop starts.",
+                           :sync_bpm => "Initial sync symbol. Will sync with this symbol before the live_loop starts. Live loop will also inherit the BPM of the thread which cued the symbol.",
                            :seed     => "override initial random generator seed before starting loop."
       },
           accepts_block:  true,
@@ -937,7 +1061,9 @@ puts slept #=> Returns false as there were no sleeps in the block"]
       doc name:           :at,
           introduced:     Version.new(2,1,0),
           summary:        "Asynchronous Time. Run a block at the given time(s)",
-          doc:            "Given a list of times, run the block once after waiting each given time. If passed an optional params list, will pass each param individually to each block call. If size of params list is smaller than the times list, the param values will act as rings (rotate through). If the block is given 1 arg, the times are fed through. If the block is given 2 args, both the times and the params are fed through. A third block arg will receive the index of the time.",
+          doc:            "Given a list of times, run the block once after waiting each given time. If passed an optional params list, will pass each param individually to each block call. If size of params list is smaller than the times list, the param values will act as rings (rotate through). If the block is given 1 arg, the times are fed through. If the block is given 2 args, both the times and the params are fed through. A third block arg will receive the index of the time.
+
+Note, all code within the block is executed in its own thread. Therefore despite inheriting all thread locals such as the random stream and ticks, modifications will be isolated to the block and will not affect external code.",
           args:           [[:times, :list],
                            [:params, :list]],
           opts:           nil,
@@ -945,6 +1071,11 @@ puts slept #=> Returns false as there were no sleeps in the block"]
           requires_block: true,
           async_block:    true,
           examples:       ["
+  at 4 do
+    sample :ambi_choir    # play sample after waiting for 4 beats
+  end
+  ",
+  "
   at [1, 2, 4] do  # plays a note after waiting 1 beat,
     play 75           # then after 1 more beat,
   end                 # then after 2 more beats (4 beats total)
@@ -979,7 +1110,31 @@ puts slept #=> Returns false as there were no sleeps in the block"]
   at [0, 0.5, 2], [:a, :b] do |t, b, idx|  #If you specify the block with 3 args, it will pass through the time, the param and the index
     puts [t, b, idx] #=> prints out [0, :a, 0], [0.5, :b, 1], then [2, :a, 2]
   end
-  "
+  ",
+  " # at does not consume & interfere with the outer random stream
+puts \"main: \", rand  # 0.75006103515625
+rand_back
+at 1 do         # the random stream inside the at block is separate and
+                # isolated from the outer stream.
+  puts \"at:\", rand # 0.9287109375
+  puts \"at:\", rand # 0.1043701171875
+end
+
+sleep 2
+puts \"main: \", rand # value is still 0.75006103515625
+",
+
+"
+            # Each block run within at has its own isolated random stream:
+at [1, 2] do
+            # first time round (after 1 beat) prints:
+  puts rand # 0.9287109375
+  puts rand # 0.1043701171875
+end
+            # second time round (after 2 beats) prints:
+            # 0.1043701171875
+            # 0.764617919921875
+"
       ]
 
 
@@ -1449,6 +1604,7 @@ puts slept #=> Returns false as there were no sleeps in the block"]
           introduced:     Version.new(2,3,0),
           summary:        "Random number in centred distribution",
           args:           [[:width, :number], [:centre, :number]],
+          alt_args:       [[:width, :number]],
           opts:           {:step => "Step size of value to quantise to."},
           accepts_block:  false,
           doc:            "Returns a random number within the range with width around centre. If optional arg `step:` is used, the result is quantised by step.",
@@ -1830,37 +1986,37 @@ puts slept #=> Returns false as there were no sleeps in the block"]
 
 
       def use_cue_logging(v, &block)
-           raise "use_cue_logging does not work with a do/end block. Perhaps you meant with_cue_logging" if block
-           Thread.current.thread_variable_set(:sonic_pi_suppress_cue_logging, !v)
-         end
-         doc name:          :use_cue_logging,
-             introduced:    Version.new(2,6,0),
-             summary:       "Enable and disable cue logging",
-             doc:           "Enable or disable log messages created on cues. This does not disable the cues themselves, it just stops them from being printed to the log",
-             args:          [[:true_or_false, :boolean]],
-             opts:          nil,
-             accepts_block: false,
-             examples:      ["use_cue_logging true # Turn on cue messages", "use_cue_logging false # Disable cue messages"]
-
-
-
-
-         def with_cue_logging(v, &block)
-           raise "with_cue_logging requires a do/end block. Perhaps you meant use_cue_logging" unless block
-           current = Thread.current.thread_variable_get(:sonic_pi_suppress_cue_logging)
-           Thread.current.thread_variable_set(:sonic_pi_suppress_cue_logging, !v)
-           block.call
-           Thread.current.thread_variable_set(:sonic_pi_suppress_cue_logging, current)
-         end
-         doc name:          :with_cue_logging,
-             introduced:    Version.new(2,6,0),
-             summary:       "Block-level enable and disable cue logging",
-             doc:           "Similar to use_cue_logging except only applies to code within supplied `do`/`end` block. Previous cue log value is restored after block.",
-             args:          [[:true_or_false, :boolean]],
-             opts:          nil,
-             accepts_block: true,
-             requires_block: true,
-             examples:      ["
+        raise "use_cue_logging does not work with a do/end block. Perhaps you meant with_cue_logging" if block
+        Thread.current.thread_variable_set(:sonic_pi_suppress_cue_logging, !v)
+      end
+      doc name:          :use_cue_logging,
+          introduced:    Version.new(2,6,0),
+          summary:       "Enable and disable cue logging",
+          doc:           "Enable or disable log messages created on cues. This does not disable the cues themselves, it just stops them from being printed to the log",
+          args:          [[:true_or_false, :boolean]],
+          opts:          nil,
+          accepts_block: false,
+          examples:      ["use_cue_logging true # Turn on cue messages", "use_cue_logging false # Disable cue messages"]
+
+
+
+
+      def with_cue_logging(v, &block)
+        raise "with_cue_logging requires a do/end block. Perhaps you meant use_cue_logging" unless block
+        current = Thread.current.thread_variable_get(:sonic_pi_suppress_cue_logging)
+        Thread.current.thread_variable_set(:sonic_pi_suppress_cue_logging, !v)
+        block.call
+        Thread.current.thread_variable_set(:sonic_pi_suppress_cue_logging, current)
+      end
+      doc name:          :with_cue_logging,
+          introduced:    Version.new(2,6,0),
+          summary:       "Block-level enable and disable cue logging",
+          doc:           "Similar to use_cue_logging except only applies to code within supplied `do`/`end` block. Previous cue log value is restored after block.",
+          args:          [[:true_or_false, :boolean]],
+          opts:          nil,
+          accepts_block: true,
+          requires_block: true,
+          examples:      ["
   # Turn on debugging:
   use_cue_logging true
 
@@ -2057,7 +2213,8 @@ puts slept #=> Returns false as there were no sleeps in the block"]
 
 
       def density(d, &block)
-        raise "density must be a positive number" unless d.is_a?(Numeric) && d >= 0
+        raise "density must be called with a do/end block." unless block
+        raise "density must be a positive number. Got: #{d.inspect}." unless d.is_a?(Numeric) && d >= 0
         reps = d < 1 ? 1.0 : d
         with_bpm_mul d do
           if block.arity == 0
@@ -2103,6 +2260,32 @@ puts slept #=> Returns false as there were no sleeps in the block"]
   "    ]
 
 
+      def current_random_seed
+        SonicPi::Core::SPRand.get_seed_plus_idx
+      end
+      doc name:          :current_random_seed,
+          introduced:    Version.new(2,10,0),
+          summary:       "Get current random seed",
+          doc:           "Returns the current random seed.
+
+This can be set via the fns `use_random_seed` and `with_random_seed. It is incremented every time you use the random number generator via fns such as `choose` and `rand`.",
+          args:          [],
+          opts:          nil,
+          accepts_block: false,
+          examples:      ["
+  puts current_random_seed # Print out the current random seed",
+"
+## Resetting the seed back to a known place
+puts rand               #=>  0.75006103515625
+puts rand               #=>  0.733917236328125
+a = current_random_seed # Grab the current seed
+puts rand               #=> 0.464202880859375
+puts rand               #=> 0.24249267578125
+use_random_seed a       # Restore the seed
+                        # we'll now get the same random values:
+puts rand               #=> 0.464202880859375
+puts rand               #=> 0.24249267578125
+"]
 
 
       def current_bpm
@@ -2145,6 +2328,28 @@ Affected by calls to `use_bpm`, `with_bpm`, `use_sample_bpm` and `with_sample_bp
 
 
 
+      def beat
+        Thread.current.thread_variable_get(:sonic_pi_spider_beat)
+      end
+      doc name:          :beat,
+          introduced:    Version.new(2,10,0),
+          summary:       "Get current beat",
+          doc:           "Returns the beat value for the current thread/live_loop. Beats are advanced only by calls to `sleep` and `sync`. Beats are distinct from virtual time (the value obtained by calling `vt`) in that it has no notion of rate. It is just essentially a counter for sleeps. After a `sync`, the beat is overridden with the beat value from the thread which called `cue`. ",
+          args:          [[]],
+          opts:          nil,
+          accepts_block: false,
+          examples:      ["
+  use_bpm 120  # The current BPM makes no difference
+  puts beat    #=> 0
+  sleep 1
+  puts beat    #=> 1
+  use_bpm 2000
+  sleep 2
+  puts beat    #=> 3"]
+
+
+
+
       def rt(t)
         t / Thread.current.thread_variable_get(:sonic_pi_spider_sleep_mul)
       end
@@ -2191,6 +2396,8 @@ Affected by calls to `use_bpm`, `with_bpm`, `use_sample_bpm` and `with_sample_bp
       def sleep(beats)
         # Schedule messages
         __schedule_delayed_blocks_and_messages!
+        curr_beat = Thread.current.thread_variable_get(:sonic_pi_spider_beat)
+        Thread.current.thread_variable_set(:sonic_pi_spider_beat, curr_beat + beats)
 
         return if beats == 0
         # Grab the current virtual time
@@ -2241,7 +2448,7 @@ Affected by calls to `use_bpm`, `with_bpm`, `use_sample_bpm` and `with_sample_bp
       end
       doc name:           :sleep,
           introduced:     Version.new(2,0,0),
-          summary:        "Wait for duration",
+          summary:        "Wait for beat duration",
           doc:            "Wait for a number of beats before triggering the next command. Beats are converted to seconds by scaling to the current bpm setting.",
           args:           [[:beats, :number]],
           opts:           nil,
@@ -2316,6 +2523,7 @@ Affected by calls to `use_bpm`, `with_bpm`, `use_sample_bpm` and `with_sample_bp
         payload = {
           :time => Thread.current.thread_variable_get(:sonic_pi_spider_time),
           :sleep_mul => Thread.current.thread_variable_get(:sonic_pi_spider_sleep_mul),
+          :beat => Thread.current.thread_variable_get(:sonic_pi_spider_beat),
           :run => current_job_id,
           :cue_map => args_h,
           :cue => cue_id
@@ -2361,7 +2569,7 @@ Affected by calls to `use_bpm`, `with_bpm`, `use_sample_bpm` and `with_sample_bp
   "
   in_thread do   # Start a metronome thread
     loop do      # Loop forever:
-      cue :tick # sending tick heartbeat messages
+      cue :tick  # sending tick heartbeat messages
       sleep 0.5  # and sleeping for 0.5 beats between ticks
     end
   end
@@ -2383,27 +2591,55 @@ Affected by calls to `use_bpm`, `with_bpm`, `use_sample_bpm` and `with_sample_bp
   # We can now play sounds using the metronome:
 
   in_thread do
-    loop do                    # In the main thread, just loop
-      sync :foo               # waiting for :foo cue messages
+    loop do              # In the main thread, just loop
+      sync :foo          # waiting for :foo cue messages
       sample :elec_beep  # after which play the elec beep sample
     end
   end
 
   in_thread do
-    loop do                    # In the main thread, just loop
-      sync :bar               # waiting for :bar cue messages
+    loop do              # In the main thread, just loop
+      sync :bar          # waiting for :bar cue messages
       sample :elec_flip  # after which play the elec flip sample
     end
   end
 
   in_thread do
-    loop do                    # In the main thread, just loop
-      sync :baz               # waiting for :baz cue messages
+    loop do              # In the main thread, just loop
+      sync :baz          # waiting for :baz cue messages
       sample :elec_blup  # after which play the elec blup sample
     end
-  end"
+  end",
+
+  "
+  in_thread do
+    loop do
+      cue :tick, foo: 64  # sending tick heartbeat messages with a value :foo
+      sleep 0.5
+    end
+  end
+
+  # The value for :foo can now be used in synced threads
+
+  loop do
+    values = sync :tick
+    play values[:foo]    # play the note value from :foo
+  end",
       ]
 
+      def sync_bpm(cue_ids, opts={})
+        sync cue_ids, opts.merge({bpm_sync: true})
+      end
+      doc name:           :sync_bpm,
+          introduced:     Version.new(2,10,0),
+          summary:        "Sync and inherit BPM from other threads ",
+          doc:            "An alias for `sync` with the `bpm_sync:` opt set to true.`",
+          args:           [[:cue_id, :symbol]],
+          opts:           {},
+          accepts_block:  false,
+          advances_time:  true,
+          examples:       ["See examples for sync"]
+
 
       def sync(cue_ids, opts={})
         cue_ids = [cue_ids] if cue_ids.is_a?(Symbol) || cue_ids.is_a?(String) || cue_ids.is_a?(SPSym)
@@ -2429,6 +2665,7 @@ Affected by calls to `use_bpm`, `with_bpm`, `use_sample_bpm` and `with_sample_bp
         payload = p.get
         time = payload[:time]
         sleep_mul = payload[:sleep_mul]
+        beat = payload[:beat]
         bpm_sync = opts.has_key?(:bpm_sync) ? opts[:bpm_sync] : false
         run_id = payload[:run]
         cue_map = payload[:cue_map]
@@ -2436,6 +2673,7 @@ Affected by calls to `use_bpm`, `with_bpm`, `use_sample_bpm` and `with_sample_bp
         cue_map = cue_map || {}
         cue_id = payload[:cue]
         cue_map[:cue] = cue_id
+        Thread.current.thread_variable_set :sonic_pi_spider_beat, beat
         Thread.current.thread_variable_set :sonic_pi_spider_time, time
         Thread.current.thread_variable_set(:sonic_pi_spider_sleep_mul, sleep_mul) if bpm_sync
 
@@ -2523,6 +2761,8 @@ Affected by calls to `use_bpm`, `with_bpm`, `use_sample_bpm` and `with_sample_bp
         name = args_h[:name]
         delay = args_h[:delay]
         sync_sym = args_h[:sync]
+        sync_bpm_sym = args_h[:sync_bpm]
+        sync_sym = nil if sync_bpm_sym
 
         raise "in_thread's delay: opt must be a number, got #{delay.inspect}" if delay && !delay.is_a?(Numeric)
 
@@ -2619,6 +2859,7 @@ Affected by calls to `use_bpm`, `with_bpm`, `use_sample_bpm` and `with_sample_bp
           begin
             sleep delay if delay
             sync sync_sym if sync_sym
+            sync_bpm sync_bpm_sym if sync_bpm_sym
             block.call
             # ensure delayed jobs and messages are honoured for this
             # thread:
@@ -2631,7 +2872,7 @@ Affected by calls to `use_bpm`, `with_bpm`, `use_sample_bpm` and `with_sample_bp
               __schedule_delayed_blocks_and_messages!
             end
           rescue Exception => e
-              if name
+            if name
               __error e, "Thread death +--> #{name.inspect}"
             else
               __error e, "Thread death!"
@@ -2671,7 +2912,8 @@ It is possible to delay the initial trigger of the thread on creation with both
           args:           [],
           opts:           {:name  => "Make this thread a named thread with name. If a thread with this name already exists, a new thread will not be created.",
                            :delay => "Initial delay in beats before the thread starts. Default is 0.",
-                           :sync => "Initial sync symbol. Will sync with this symbol before the thread starts."},
+                           :sync => "Initial sync symbol. Will sync with this symbol before the thread starts.",
+                           :sync_bpm => "Initial sync symbol. Will sync with this symbol before the live_loop starts. Live loop will also inherit the BPM of the thread which cued the symbol.",},
           accepts_block:  true,
           requires_block: true,
           async_block:    true,
@@ -2837,6 +3079,41 @@ assert_equal [:a, :b, :c].size,  3 # ensure lists can be correctly counted
 assert_equal 3, 5, \"something is seriously wrong!\"
 " ]
 
+      def load_buffer(path)
+        path = File.expand_path(path.to_s)
+        raise "Unable to load buffer - no file found with path: #{path}" unless File.exists?(path)
+        buf = __current_job_info[:workspace]
+        __info "loading #{buf} with #{path}"
+        __replace_buffer(buf, File.read(path))
+      end
+      doc name:           :load_buffer,
+          introduced:     Version.new(2,10,0),
+          summary:        "Load the contents of a file to the current buffer",
+          doc:            "Given a path to a file, will read the contents and load it into the current buffer. This will replace any previous content.",
+          args:           [[:path, :string]],
+          opts:           nil,
+          accepts_block:  false,
+          examples:       ["
+load_buffer \"~/sonic-pi-tracks/phat-beats.rb\" # will replace content of current buffer with contents of the file"]
+
+
+      def load_example(example_name)
+        path = Dir[examples_path + '/**/' + example_name.to_s + '.rb'].first
+        raise "Error - no example found with name: #{example_name.inspect}" unless path
+        buf = __current_job_info[:workspace]
+        __info "loading #{buf} with #{path}"
+        title = ActiveSupport::Inflector.titleize(example_name)
+        __replace_buffer(buf, "# #{title}\n" + File.read(path))
+      end
+      doc name:           :load_example,
+          introduced:     Version.new(2,10,0),
+          summary:        "Load a built-in example",
+          doc:            "Given a keyword representing an example, will load it into the current buffer. This will replace any previous content.",
+          args:           [[:path, :string]],
+          opts:           nil,
+          accepts_block:  false,
+          examples:       ["
+load_example :rerezzed # will replace content of current buffer with the rerezzed example"]
 
       def __on_thread_death(&block)
         gc_jobs = Thread.current.thread_variable_get(:sonic_pi__not_inherited__spider_in_thread_gc_jobs) || []
diff --git a/app/server/sonicpi/lib/sonicpi/lang/minecraftpi.rb b/app/server/sonicpi/lib/sonicpi/lang/minecraftpi.rb
index 5cf6b4c..2447119 100644
--- a/app/server/sonicpi/lib/sonicpi/lang/minecraftpi.rb
+++ b/app/server/sonicpi/lib/sonicpi/lang/minecraftpi.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification and distribution
diff --git a/app/server/sonicpi/lib/sonicpi/lang/pattern.rb b/app/server/sonicpi/lib/sonicpi/lang/pattern.rb
index ab8840c..20f3eb5 100644
--- a/app/server/sonicpi/lib/sonicpi/lang/pattern.rb
+++ b/app/server/sonicpi/lib/sonicpi/lang/pattern.rb
@@ -4,7 +4,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/lang/sound.rb b/app/server/sonicpi/lib/sonicpi/lang/sound.rb
index e5460e0..75f3b2b 100644
--- a/app/server/sonicpi/lib/sonicpi/lang/sound.rb
+++ b/app/server/sonicpi/lib/sonicpi/lang/sound.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -20,6 +20,7 @@ require_relative "../blanknode"
 require_relative "../chainnode"
 require_relative "../fxnode"
 require_relative "../fxreplacenode"
+require_relative "../lazynode"
 require_relative "../note"
 require_relative "../scale"
 require_relative "../chord"
@@ -27,6 +28,7 @@ require_relative "../chordgroup"
 require_relative "../synthtracker"
 require_relative "../version"
 require_relative "../tuning"
+require_relative "../sample_loader"
 require_relative "support/docsystem"
 
 class Symbol
@@ -39,6 +41,15 @@ class Symbol
     return self if (self == :r) || (self == :rest)
     SonicPi::Note.resolve_midi_note_without_octave(self) + SonicPi::Note.resolve_midi_note_without_octave(other)
   end
+
+  def to_f
+    return 0.0 if (self == :r) || (self == :rest)
+    SonicPi::Note.resolve_midi_note_without_octave(self).to_f
+  end
+
+  def to_i
+    self.to_f.to_i
+  end
 end
 
 class NilClass
@@ -87,9 +98,9 @@ module SonicPi
             @server_init_args = splat.take(4)
 
             @mod_sound_home_dir = Dir.home
-            @simple_sampler_args = [:amp, :amp_slide, :amp_slide_shape, :amp_slide_curve, :pan, :pan_slide, :pan_slide_shape, :pan_slide_curve, :cutoff, :cutoff_slide, :cutoff_slide_shape, :cutoff_slide_curve, :res, :res_slide, :res_slide_shape, :res_slide_curve, :rate, :slide, :beat_stretch, :rpitch]
+            @simple_sampler_args = [:amp, :amp_slide, :amp_slide_shape, :amp_slide_curve, :pan, :pan_slide, :pan_slide_shape, :pan_slide_curve, :cutoff, :cutoff_slide, :cutoff_slide_shape, :cutoff_slide_curve, :lpf, :lpf_slide, :lpf_slide_shape, :lpf_slide_curve, :hpf, :hpf_slide, :hpf_slide_shape, :hpf_slide_curve, :rate, :slide, :beat_stretch, :rpitch, :attack, :decay, :sustain, :release, :attack_level, :decay_level, :sustain_level, :env_curve]
 
-            @tuning = Tuning.new
+            init_tuning
 
             @blank_node = BlankNode.new
             @job_proms_queues = {}
@@ -99,6 +110,8 @@ module SonicPi
 
             @sample_paths_cache = {}
 
+            @sample_loader = SampleLoader.new("#{samples_path}/**")
+
             @JOB_GROUPS_A = Atom.new(Hamster::Hash.new)
             @JOB_GROUP_MUTEX = Mutex.new
             @JOB_FX_GROUP_MUTEX = Mutex.new
@@ -178,8 +191,25 @@ module SonicPi
         end
       end
 
+      # Deprecated fns
+
+      def current_sample_pack_aliases(*args)
+        raise "Sorry, current_sample_pack_aliases is no longer supported since v2.10. Please read Section 3.7 of the tutorial for a more powerful replacement."
+      end
+
+      def with_sample_pack_as(*args)
+        raise "Sorry, with_sample_pack_as is no longer supported since v2.10. Please read Section 3.7 of the tutorial for a more powerful replacement."
+      end
+
+      def use_sample_pack_as(*args)
+        raise "Sorry, use_sample_pack_as is no longer supported since v2.10. Please read Section 3.7 of the tutorial for a more powerful replacement."
+      end
+
+
+
 
       def reboot
+        @sample_loader.reset!
         return nil if @mod_sound_studio.rebooting
         __no_kill_block do
           __stop_other_jobs
@@ -195,9 +225,45 @@ module SonicPi
         stop
       end
 
+
+
+
+      def octs(start, num_octs=1)
+        a = []
+        num_octs.times do |i|
+          a << (note(start) + (12 * i))
+        end
+        a.ring
+      end
+      doc name:           :octs,
+          introduced:     Version.new(2,8,0),
+          summary:        "Create a ring of octaves",
+          args:           [[:start, :note], [:num_octaves, :pos_int]],
+          returns:        :ring,
+          opts:           nil,
+          accepts_block:  false,
+          doc:            "Create a ring of successive octaves starting at `start` for `num_octaves`. ",
+          examples:       [
+        "(octs 60, 2)  #=> (ring 60, 72)",
+        "(octs :e3, 3) #=> (ring 52, 64, 76)"
+]
+
+
+
+
       def sample_free(*paths)
-        full_paths = paths.map{ |p| resolve_sample_symbol_path(p)}
-        @mod_sound_studio.free_sample(full_paths)
+        paths.each do |p|
+          p = [p] unless p.is_a?(Array)
+          filts_and_sources, args_a = sample_split_filts_and_opts(p)
+          resolve_sample_paths(filts_and_sources).each do |p|
+            if sample_loaded?(p)
+              @mod_sound_studio.free_sample([p])
+              __info "Freed sample: #{p.inspect}"
+            end
+          end
+        end
+
+
       end
       doc name:           :sample_free,
           introduced:     Version.new(2,9,0),
@@ -206,7 +272,9 @@ module SonicPi
           returns:        nil,
           opts:           nil,
           accepts_block:  false,
-          doc:            "Frees the memory and resources consumed by loading the sample on the server. Subsequent calls to `sample` and friends will re-load the sample on the server. You may pass multiple samples to free at once.",
+          doc:            "Frees the memory and resources consumed by loading the sample on the server. Subsequent calls to `sample` and friends will re-load the sample on the server.
+
+You may also specify the same set of source and filter pre-args available to `sample` itself. `sample_free` will then free all matching samples. See `sample`'s docs for more information.",
           examples:       ["
 sample :loop_amen # The Amen break is now loaded into memory and played
 sleep 2
@@ -227,7 +295,18 @@ sample :ambi_lunar_land
 sleep 2
 sample_free :loop_amen, :ambi_lunar_land
 sample :loop_amen                        # re-loads and plays amen
-sample :ambi_lunar_land                  # re-loads and plays lunar land"]
+sample :ambi_lunar_land                  # re-loads and plays lunar land",
+
+"# Using source and filter pre-args
+dir = \"/path/to/sample/dir\"
+sample_free dir # frees any loaded samples in \"/path/to/sample/dir\"
+sample_free dir, 1 # frees sample with index 1 in \"/path/to/sample/dir\"
+sample_free dir, :foo # frees sample with name \"foo\" in \"/path/to/sample/dir\"
+sample_free dir, /[Bb]ar/ # frees sample which matches regex /[Bb]ar/ in \"/path/to/sample/dir\"
+
+",
+
+ ]
 
 
 
@@ -338,27 +417,62 @@ sample :loop_amen        # re-loads and plays amen"]
         if args_h.has_key?(:on)
           on = args_h.delete(:on)
           return truthy?(on)
+        else
+          return true
         end
+      end
 
-        tls = if sample
-                Thread.current.thread_variable_get(:sonic_pi_mod_sound_sample_defaults)
-              else
-                Thread.current.thread_variable_get(:sonic_pi_mod_sound_synth_defaults)
-              end
+      def use_timing_guarantees(v, &block)
+        raise "use_timing_guarantees does not work with a do/end block. Perhaps you meant with_timing_guarantees" if block
+        Thread.current.thread_variable_set(:sonic_pi_mod_sound_timing_guarantees, v)
+      end
+      doc name:           :use_timing_guarantees,
+          introduced:     Version.new(2,10,0),
+          summary:        "Inhibit synth triggers if too late",
+          doc:            "If set to true, synths will not trigger if it is too late. If false, some synth triggers may be late.",
+          args:           [[:bool, :true_or_false]],
+          opts:           nil,
+          accepts_block:  true,
+          examples:       ["
+use_timing_guarantees true
+
+sample :loop_amen  #=> if time is behind by any margin, this will not trigger",
+        "
+use_timing_guarantees false
 
-        return true unless tls
+sample :loop_amen  #=> unless time is too far behind, this will trigger even when late."]
 
-        if tls.has_key?(:on)
-          # need to normalise it!
-          on = tls.delete(:on)
-          return truthy?(on)
 
-        end
 
-        true
+      def with_timing_guarantees(v, &block)
+        raise "use_timing_guarantees requires a do/end block. Perhaps you meant use_timing_guarnatees" unless block
+        current = Thread.current.thread_variable_get(:sonic_pi_mod_sound_timing_guarantees)
+        Thread.current.thread_variable_set(:sonic_pi_mod_sound_timing_guarantees, v)
+        res = block.call
+        Thread.current.thread_variable_set(:sonic_pi_mod_sound_timing_guarantees, current)
+        res
       end
+      doc name:           :with_timing_guarantees,
+          introduced:     Version.new(2,10,0),
+          summary:        "Block-scoped inhibition of synth triggers if too late",
+          doc:            "For the given block, if set to true, synths will not trigger if it is too late. If false, some synth triggers may be late. After the block has completed, the previous value is restored. ",
+          args:           [[:bool, :true_or_false]],
+          opts:           nil,
+          accepts_block:  true,
+          examples:       ["
+with_timing_guarantees true
+  sample :loop_amen  #=> if time is behind by any margin, this will not trigger
+end",
+"
+with_timing_guarantees false
+  sample :loop_amen  #=> unless time is too far behind, this will trigger even when late.
+end"]
 
 
+      def use_external_synths(v, &block)
+        raise "use_external_synths does not work with a do/end block. Perhaps you meant with_external_synths" if block
+        Thread.current.thread_variable_set(:sonic_pi_mod_sound_use_external_synths, v)
+      end
 
 
       def use_timing_warnings(v, &block)
@@ -379,15 +493,13 @@ sample :loop_amen        # re-loads and plays amen"]
       end
 
 
-
-
       def use_sample_bpm(sample_name, *args)
         args_h = resolve_synth_opts_hash_or_array(args)
         num_beats = args_h[:num_beats] || 1
 
         # Don't use sample_duration as that is stretched to the current
         # bpm!
-        sd = load_sample(sample_name).duration
+        sd = sample_buffer(sample_name).duration
         use_bpm(num_beats * (60.0 / sd))
       end
       doc name:           :use_sample_bpm,
@@ -426,7 +538,7 @@ end"]
         num_beats = args_h[:num_beats] || 1
         # Don't use sample_duration as that is stretched to the current
         # bpm!
-        sd = load_sample(sample_name).duration
+        sd = sample_buffer(sample_name).duration
         with_bpm(num_beats * (60.0 / sd), &block)
       end
       doc name:           :with_sample_bpm,
@@ -756,8 +868,27 @@ play 90 # Args are checked
 
 "]
 
+      def set_cent_tuning!(shift)
+        @mod_sound_studio.cent_tuning = shift
+      end
+      doc name:          :set_cent_tuning!,
+          introduced:    Version.new(2,10,0),
+          summary:       "Global Cent tuning",
+          doc:           "Globally tune Sonic Pi to play with another external instrument.
+
+Uniformly tunes your music by shifting all notes played by the specified number of cents. To shift up by a cent use a cent tuning of 1. To shift down use negative numbers. One semitone consists of 100 cents.
 
+See `use_cent_tuning` for setting the cent tuning value locally for a specific thread or `live_loop`. This is a global value and will shift the tuning for *all* notes. It will also persist for the entire session.
 
+Important note: the cent tuning set by `set_cent_tuning!` is independent of any thread-local cent tuning values set by `use_cent_tuning` or `with_cent_tuning`. ",
+          args:          [[:cent_shift, :number]],
+          opts:          nil,
+          accepts_block: false,
+          intro_fn:       false,
+          examples:      ["
+play 50 # Plays note 50
+set_cent_tuning! 1
+play 50 # Plays note 50.01"]
 
       def use_cent_tuning(shift, &block)
         raise "use_cent_tuning does not work with a do/end block. Perhaps you meant with_cent_tuning" if block
@@ -964,10 +1095,11 @@ play 64 # Plays note 64"]
       def with_tuning(tuning, fundamental_note = :c, &block)
         raise "with_tuning requires a do/end block. Perhaps you meant use_tuning" unless block
         raise "tuning value must be a symbol like :just or :equal, got #{tuning.inspect}" unless tuning.is_a?(Symbol)
-        curr_tuning, curr_fundamental = Thread.current.thread_variable_get(:sonic_pi_mod_sound_tuning)
+        curr_tuning_info = Thread.current.thread_variable_get(:sonic_pi_mod_sound_tuning)
+        curr_tuning, curr_fundamental = curr_tuning_info
         Thread.current.thread_variable_set(:sonic_pi_mod_sound_tuning, [tuning, fundamental_note])
         res = block.call
-        Thread.current.thread_variable_set(:sonic_pi_mod_sound_tuning, [curr_tuning, curr_fundamental])
+        Thread.current.thread_variable_set(:sonic_pi_mod_sound_tuning, curr_tuning_info)
         res
       end
       doc name:          :with_tuning,
@@ -989,7 +1121,8 @@ end
 play :e4 # Plays note 64"]
 
 
-      def use_synth(synth_name, &block)
+      def use_synth(synth_name, *args, &block)
+        raise "use_synth does not accept opts such as #{arg_h_pp(resolve_synth_opts_hash_or_array(args))}. \n Consider using use_synth_defaults." unless args.empty?
         raise "use_synth does not work with a do/end block. Perhaps you meant with_synth" if block
         set_current_synth synth_name
       end
@@ -1009,7 +1142,8 @@ play 50 # Plays with mod_sine synth"]
 
 
 
-      def with_synth(synth_name, &block)
+      def with_synth(synth_name, *args, &block)
+        raise "with_synth does not accept opts such as #{arg_h_pp(resolve_synth_opts_hash_or_array(args))}. \n Consider using with_synth_defaults." unless args.empty?
         raise "with_synth must be called with a do/end block. Perhaps you meant use_synth" unless block
         orig_synth = current_synth_name
         set_current_synth synth_name
@@ -1184,18 +1318,24 @@ set_mixer_control! lpf: 30, lpf_slide: 16 # slide the global lpf to 30 over 16 b
 
 
       def synth(synth_name, *args)
-        ensure_good_timing!
+        synth_name = current_synth unless synth_name
         args_h = resolve_synth_opts_hash_or_array(args)
+        tls = Thread.current.thread_variable_get(:sonic_pi_mod_sound_synth_defaults) || {}
 
-        return nil unless should_trigger?(args_h)
+        args_h = tls.merge(args_h)
+
+        return @blank_node unless should_trigger?(args_h)
 
         if rest? args_h
-          __delayed_message "synth #{synth_name.to_sym.inspect}, {note: :rest}"
-          return nil
+          unless Thread.current.thread_variable_get(:sonic_pi_mod_sound_synth_silent)
+            __delayed_message "synth #{synth_name.to_sym.inspect}, {note: :rest}"
+          end
+          return @blank_node
         end
 
+
         notes = args_h[:notes] || args_h[:note]
-        if notes.is_a?(SonicPi::Core::RingVector) || notes.is_a?(Array)
+        if notes.is_a?(SonicPi::Core::SPVector) || notes.is_a?(Array)
           args_h.delete(:notes)
           args_h.delete(:note)
           shifted_notes = notes.map {|n| normalise_transpose_and_tune_note_from_args(n, args_h)}
@@ -1214,6 +1354,8 @@ set_mixer_control! lpf: 30, lpf_slide: 16 # slide the global lpf to 30 over 16 b
 
 If note: opt is `nil`, `:r` or `:rest`, play is ignored and treated as a rest. Also, if the `on:` opt is specified and returns `false`, or `nil` then play is similarly ignored and treated as a rest.
 
+If the synth name is `nil` behaviour is identical to that of `play` in that the `current_synth` will determine the actual synth triggered.
+
 Note that the default opts listed are only a guide to the most common opts across all the synths. Not all synths support all the default opts and each synth typically supports many more opts specific to that synth. For example, the `:tb303` synth supports 45 unique opts. For a full list of a synth's opts see its documentation in the Help system. This can be accessed directly by clicking on the name of the synth and using the shortcut `C-i`",
           args:          [[:synth_name, :symbol]],
           opts:          DEFAULT_PLAY_OPTS,
@@ -1263,39 +1405,11 @@ end
 
 
       def play(n, *args)
-        ensure_good_timing!
-        case n
-        when Array, SonicPi::Core::RingVector
-          return play_chord(n, *args)
-        when Hash
-          # Allow a single hash argument to function unsurprisingly
-          if args.empty?
-            args = n
-          else
-            args_h = resolve_synth_opts_hash_or_array(args)
-            args = n.merge(args_h)
-          end
-        end
-
-        n = note(n)
-
-        synth_name = current_synth_name
-
-        if n.nil?
-          unless Thread.current.thread_variable_get(:sonic_pi_mod_sound_synth_silent)
-            __delayed_message "synth #{synth_name.to_sym.inspect}, {note: :rest}"
-          end
-
-          return nil
+        if n.is_a?(Hash) && args.empty?
+          synth nil, n
+        else
+          synth nil, {note: n}, *args
         end
-
-        init_args_h = {}
-        args_h = resolve_synth_opts_hash_or_array(args)
-
-        return nil unless should_trigger?(args_h)
-
-        n = normalise_transpose_and_tune_note_from_args(n, args_h)
-        trigger_inst synth_name, {note: n}.merge(init_args_h.merge(args_h))
       end
       doc name:          :play,
           introduced:    Version.new(2,0,0),
@@ -1421,13 +1535,12 @@ play 44"]
 
 
       def play_chord(notes, *args)
-        ensure_good_timing!
         args_h = resolve_synth_opts_hash_or_array(args)
-        return nil unless should_trigger?(args_h)
+        return @blank_node unless should_trigger?(args_h)
         shifted_notes = notes.map {|n| normalise_transpose_and_tune_note_from_args(n, args_h)}
 
         synth_name = current_synth_name
-        trigger_chord(synth_name, shifted_notes, args)
+        trigger_chord(synth_name, shifted_notes, args_h)
       end
       doc name:          :play_chord,
           introduced:    Version.new(2,0,0),
@@ -1758,7 +1871,10 @@ play 60 # plays note 60 with an amp of 0.5, pan of -1 and defaults for rest of a
         fx_synth_name = "fx_#{fx_name}"
         info = Synths::SynthInfo.get_info(fx_synth_name)
 
-        fx_synth_name = fx_name unless info
+        unless info
+          raise "Unknown FX #{fx_name.inspect}" unless Thread.current.thread_variable_get(:sonic_pi_mod_sound_use_external_synths)
+          fx_synth_name = fx_name
+        end
 
         start_subthreads = []
         end_subthreads = []
@@ -1964,6 +2080,7 @@ play 60 # plays note 60 with an amp of 0.5, pan of -1 and defaults for rest of a
           :sonic_pi_spider_delayed_blocks,
           :sonic_pi_spider_delayed_messages,
           :sonic_pi_spider_time,
+          :sonic_pi_spider_beat,
           :sonic_pi_spider_arg_bpm_scaling,
           :sonic_pi_spider_random_gen_idx,
           :sonic_pi_spider_random_gen_seed,
@@ -2072,7 +2189,7 @@ end
       def use_sample_pack(pack, &block)
         raise "use_sample_pack does not work with a block. Perhaps you meant with_sample_pack" if block
         if pack == :default
-          pack = samples_path + "/"
+          pack = samples_path + "/**"
         else
           pack = "#{pack}/" if File.directory?(pack)
         end
@@ -2082,55 +2199,26 @@ end
       doc name:          :use_sample_pack,
           introduced:    Version.new(2,0,0),
           summary:       "Use sample pack",
-          doc:           "Given a path to a folder of samples on your filesystem, this method makes any `.wav`, `.wave`, `.aif` or `.aiff` files in that folder available as samples. Consider using `use_sample_pack_as` when using multiple sample packs. Use `use_sample_pack :default` To revert back to the default built-in samples.",
+          doc:           "Given a path to a folder of samples on your filesystem, this method makes any `.wav`, `.wave`, `.aif`, `.aiff` or `.flac` files in that folder available as samples. Use `use_sample_pack :default` To revert back to the default built-in samples.",
           args:          [[:pack_path, :string]],
           opts:          nil,
           accepts_block: false,
           examples:
         ["
 use_sample_pack '/home/yourname/path/to/sample/dir'
-sample :foo  #=> plays /home/yourname/path/to/sample/dir/foo.{wav|wave|aif|aiff}
-             #   where {wav|wave|aif|aiff} means one of wav, wave aif or aiff.
+sample :foo  #=> plays /home/yourname/path/to/sample/dir/foo.{wav|wave|aif|aiff|flac}
+             #   where {wav|wave|aif|aiff|flac} means one of wav, wave, aif, aiff or flac.
 sample :bd_haus #=> will not work unless there's a sample in '/home/yourname/path/to/sample/dir'
-                #   called bd_haus.{wav|wave|aif|aiff}
+                #   called bd_haus.{wav|wave|aif|aiff|flac}
 use_sample_pack :default
 sample :bd_haus #=> will play the built-in bd_haus.wav sample" ]
 
 
-
-
-      def use_sample_pack_as(pack, pack_alias, &block)
-        raise "use_sample_pack_as does not work with a block. Perhaps you meant with_sample_pack_as" if block
-        pack = "#{pack}/" if File.directory?(pack)
-        aliases = Thread.current.thread_variable_get(:sonic_pi_mod_sound_sample_aliases) || Hamster::Hash.new
-        new_aliases = aliases.put pack_alias.to_s, pack
-        Thread.current.thread_variable_set(:sonic_pi_mod_sound_sample_aliases, new_aliases)
-      end
-      doc name:          :use_sample_pack_as,
-          introduced:    Version.new(2,0,0),
-          summary:       "Use sample pack alias",
-          doc:           "Similar to `use_sample_pack` except you can assign prefix aliases for samples. This lets you 'namespace' your sounds so that they don't clash, even if they have the same filename.",
-          args:          [[:path, :string], [:alias, :string]],
-          opts:          nil,
-          accepts_block: false,
-          examples:      ["
-# let's say you have two folders of your own sample files,
-# and they both contain a file named 'bass.wav'
-use_sample_pack_as '/home/yourname/my/cool/samples/guitar', :my_guitars
-use_sample_pack_as '/home/yourname/my/cool/samples/drums', :my_drums
-
-# You can now play both the 'bass.wav' samples, as they've had the symbol stuck on the front
-sample :my_guitars__bass    #=> plays '/home/yourname/my/cool/samples/guitar/bass.wav'
-sample :my_drums__bass  #=> plays '/home/yourname/my/cool/samples/drums/bass.wav'"]
-
-
-
-
       def with_sample_pack(pack, &block)
         raise "with_sample_pack requires a block. Perhaps you meant use_sample_pack" unless block
         if pack == :default
           # allow user to reset sample pack with the :default keyword
-          pack = samples_path
+          pack = samples_path + "/**"
         else
           # ensure directories have trailing /
           pack = "#{pack}/" if File.directory?(pack)
@@ -2144,42 +2232,14 @@ sample :my_drums__bass  #=> plays '/home/yourname/my/cool/samples/drums/bass.wav
       doc name:           :with_sample_pack,
           introduced:     Version.new(2,0,0),
           summary:        "Block-level use sample pack",
-          doc:            "Given a path to a folder of samples on your filesystem, this method makes any `.wav`, `.wave`, `.aif`, or `.aiff` files in that folder available as samples inside the given block. Consider using `with_sample_pack_as` when using multiple sample packs.",
+          doc:            "Given a path to a folder of samples on your filesystem, this method makes any `.wav`, `.wave`, `.aif`, `.aiff` or `.flac` files in that folder available as samples inside the given block.",
           args:           [[:pack_path, :string]],
           opts:           nil,
           accepts_block:  true,
           requires_block: true,
           examples:       ["
 with_sample_pack '/path/to/sample/dir' do
-  sample :foo  #=> plays /path/to/sample/dir/foo.{wav|wave|aif|aiff}
-end"]
-
-
-
-
-      def with_sample_pack_as(pack, name, &block)
-        raise "with_sample_pack_as requires a do/end block. Perhaps you meant use_sample_pack_as" unless block
-        pack = "#{pack}/" if File.directory?(pack)
-        current = Thread.current.thread_variable_get(:sonic_pi_mod_sound_sample_aliases)
-        aliases = current || Hamster::Hash.new
-        new_aliases = aliases.put name.to_s, pack
-        Thread.current.thread_variable_set(:sonic_pi_mod_sound_sample_aliases, new_aliases)
-        res = block.call
-        Thread.current.thread_variable_set(:sonic_pi_mod_sound_sample_aliases, current)
-        res
-      end
-      doc name:           :with_sample_pack_as,
-          introduced:     Version.new(2,0,0),
-          summary:        "Block-level use sample pack alias",
-          doc:            "Similar to `with_sample_pack` except you can assign prefix aliases for samples. This lets you 'namespace' your sounds so that they don't clash, even if they have the same filename.",
-          args:           [[:pack_path, :string]],
-          opts:           nil,
-          accepts_block:  true,
-          requires_block: true,
-          examples:       ["
-with_sample_pack_as '/home/yourname/path/to/sample/dir', :my_samples do
-  # The foo sample is now available, with a prefix of 'my_samples'
-  sample :my_samples__foo  #=> plays /home/yourname/path/to/sample/dir/foo.{wav|wave|aif|aiff}
+  sample :foo  #=> plays /path/to/sample/dir/foo.{wav|wave|aif|aiff|flac}
 end"]
 
 
@@ -2221,20 +2281,7 @@ puts current_sample_pack # Print out the current sample pack"]
 
 
 
-      def current_sample_pack_aliases
-        Thread.current.thread_variable_get(:sonic_pi_mod_sound_sample_aliases)
-      end
-      doc name:          :current_sample_pack_aliases,
-          introduced:    Version.new(2,0,0),
-          summary:       "Get current sample pack aliases",
-          doc:           "Returns a map containing the current sample pack aliases.
 
-This can be set via the fns `use_sample_pack_as` and `with_sample_pack_as`.",
-          args:          [],
-          opts:          nil,
-          accepts_block: false,
-          examples:      ["
-puts current_sample_pack_aliases # Print out the current sample pack aliases"]
 
 
 
@@ -2438,22 +2485,18 @@ set_volume! 2 # Set the main system volume to 2",
 
 
 
-      def sample_loaded?(path)
-        case path
-        when Symbol
-          full_path = resolve_sample_symbol_path(path)
-          return @mod_sound_studio.sample_loaded?(full_path)
-        when String
-          path = File.expand_path(path)
-          return @mod_sound_studio.sample_loaded?(path)
-        else
-          raise "Unknown sample description: #{path}"
-        end
+      def sample_loaded?(*args)
+        filts_and_sources, args_a = sample_split_filts_and_opts(args)
+        path = resolve_sample_path(filts_and_sources)
+
+        path = File.expand_path(path)
+        return @mod_sound_studio.sample_loaded?(path)
       end
+
       doc name:          :sample_loaded?,
           introduced:    Version.new(2,2,0),
           summary:       "Test if sample was pre-loaded",
-          doc:           "Given a path to a `.wav`, `.wave`, `.aif` or `.aiff` file, returns `true` if the sample has already been loaded.",
+          doc:           "Given a path to a `.wav`, `.wave`, `.aif`, `.aiff` or `.flac` file, returns `true` if the sample has already been loaded.",
           args:          [[:path, :string]],
           opts:          nil,
           accepts_block: false,
@@ -2463,80 +2506,75 @@ puts sample_loaded? :elec_blip # prints true because it has been pre-loaded
 puts sample_loaded? :misc_burp # prints false because it has not been loaded"]
 
 
-
-
-      def load_sample(path)
-        case path
-        when Symbol
-          full_path = resolve_sample_symbol_path(path)
-          info, cached = @mod_sound_studio.load_sample(full_path)
-          __info "Loaded sample :#{path}" unless cached
-          return info
-        when String
-          raise "Attempted to load sample with an empty string as path" if path.empty?
-          path = File.expand_path(path)
-          if File.exists?(path)
-            info, cached = @mod_sound_studio.load_sample(path)
-            __info "Loaded sample #{path.inspect}" unless cached
-            return info
-          else
-            raise "No sample exists with path #{path}"
-          end
-        else
-          raise "Unknown sample description: #{path}. Expected a symbol such as :loop_amen or a string containing a path."
+      def load_sample(*args)
+        filts_and_sources, args_a = sample_split_filts_and_opts(args)
+        paths = sample_find_candidates(filts_and_sources)
+        paths.map do |p|
+          load_sample_at_path p
         end
       end
       doc name:          :load_sample,
           introduced:    Version.new(2,0,0),
-          summary:       "Pre-load sample",
-          doc:           "Given a path to a `.wav`, `.wave`, `.aif` or `.aiff` file, this loads the file and makes it available as a sample. See `load_samples` for loading multiple samples in one go.",
+          summary:       "Pre-load sample(s)",
+          doc:           "Given a path to a `.wav`, `.wave`, `.aif`, `.aiff` or `.flac` file, pre-loads the sample into memory.
+
+You may also specify the same set of source and filter pre-args available to `sample` itself. `load_sample` will then load all matching samples. See `sample`'s docs for more information." ,
+
           args:          [[:path, :string]],
           opts:          nil,
           accepts_block: false,
           examples:      ["
 load_sample :elec_blip # :elec_blip is now loaded and ready to play as a sample
-sample :elec_blip # No delay takes place when attempting to trigger it"]
+sample :elec_blip # No delay takes place when attempting to trigger it",
 
+"# Using source and filter pre-args
+dir = \"/path/to/sample/dir\"
+load_sample dir # loads any samples in \"/path/to/sample/dir\"
+load_sample dir, 1 # loads sample with index 1 in \"/path/to/sample/dir\"
+load_sample dir, :foo # loads sample with name \"foo\" in \"/path/to/sample/dir\"
+load_sample dir, /[Bb]ar/ # loads sample which matches regex /[Bb]ar/ in \"/path/to/sample/dir\"
 
+"      ]
 
 
-      def load_samples(*paths)
-        paths.each do |p|
-          if p.kind_of?(Array)
-            load_samples *p
-          else
-            load_sample p
-          end
-        end
+      def load_samples(*args)
+        load_sample(*args)
       end
       doc name:          :load_samples,
           introduced:    Version.new(2,0,0),
           summary:       "Pre-load samples",
-          doc:           "Given an array of paths to `.wav`, `.wave`, `.aif` or `.aiff` files, loads them all into memory so that they may be played with via sample with no delay. See `load_sample`.",
+          doc:           "Synonym for load_sample",
           args:          [[:paths, :list]],
           opts:          nil,
           accepts_block: false,
-          examples:      ["
-sample :ambi_choir # This has to first load the sample before it can play it which may
-                   # cause unwanted delay.
+          examples:      ["# See load_sample for examples"]
 
-load_samples [:elec_plip, :elec_blip] # Let's load some samples in advance of using them
-sample :elec_plip                     # When we play :elec_plip, there is no extra delay
-                                      # as it has already been loaded.",
 
-        "
-load_samples :elec_plip, :elec_blip # You may omit the square brackets, and
-                                    # simply list all samples you wish to load
-sample :elec_blip                   # Before playing them.",
-        "
-load_samples [\"/home/pi/samples/foo.wav\"] # You may also load full paths to samples.
-sample \"/home/pi/sample/foo.wav\"          # And then trigger them with no more loading."]
+
+
+      def load_sample_at_path(path)
+        case path
+        when Symbol
+          full_path = resolve_sample_symbol_path(path)
+          info, cached = @mod_sound_studio.load_sample(full_path)
+          __info "Loaded sample :#{path}" unless cached
+          return info
+        when String
+          raise "Attempted to load sample with an empty string as path" if path.empty?
+          path = File.expand_path(path)
+          info, cached = @mod_sound_studio.load_sample(path)
+          __info "Loaded sample #{unify_tilde_dir(path).inspect}" unless cached
+          return info
+        else
+          raise "Unknown sample description: #{path.inspect}\n Expected a symbol such as :loop_amen or a string containing a path."
+        end
+      end
 
 
 
 
-      def sample_info(path)
-        load_sample(path)
+      def sample_info(*args)
+        sample_buffer(*args)
       end
       doc name:          :sample_info,
           introduced:    Version.new(2,0,0),
@@ -2550,8 +2588,10 @@ sample \"/home/pi/sample/foo.wav\"          # And then trigger them with no more
 
 
 
-      def sample_buffer(path)
-        load_sample(path)
+      def sample_buffer(*args)
+        filts_and_sources, args_a = sample_split_filts_and_opts(args)
+        path = resolve_sample_path(filts_and_sources)
+        load_sample_at_path(path)
       end
       doc name:          :sample_buffer,
           introduced:    Version.new(2,0,0),
@@ -2565,9 +2605,11 @@ sample \"/home/pi/sample/foo.wav\"          # And then trigger them with no more
 
 
 
-      def sample_duration(path, *args)
-        dur = load_sample(path).duration
-        args_h = resolve_synth_opts_hash_or_array(args)
+      def sample_duration(*args)
+        filts_and_sources, args_a = sample_split_filts_and_opts(args)
+        path = resolve_sample_path(filts_and_sources)
+        dur = load_sample_at_path(path).duration
+        args_h = merge_synth_arg_maps_array(args_a)
         t_l_args = Thread.current.thread_variable_get(:sonic_pi_mod_sound_sample_defaults) || {}
         t_l_args.each do |k, v|
             args_h[k] = v unless args_h.has_key? k
@@ -2619,10 +2661,13 @@ sample \"/home/pi/sample/foo.wav\"          # And then trigger them with no more
           return real_dur
         end
       end
+
       doc name:          :sample_duration,
           introduced:    Version.new(2,0,0),
           summary:       "Get duration of sample in beats",
-          doc:           "Given the name of a loaded sample, or a path to a `.wav`, `.wave`, `.aif` or `.aiff` file returns the length of time in beats that the sample would play for. `sample_duration` understands and accounts for all the opts you can pass to `sample` which have an effect on the playback duration such as `rate:`. The time returned is scaled to the current bpm.",
+          doc:           "Given the name of a loaded sample, or a path to a `.wav`, `.wave`, `.aif`, `.aiff` or `.flac` file returns the length of time in beats that the sample would play for. `sample_duration` understands and accounts for all the opts you can pass to `sample` which have an effect on the playback duration such as `rate:`. The time returned is scaled to the current BPM.
+
+*Note:* avoid using `sample_duration` to set the sleep time in `live_loop`s, prefer stretching the sample with the `beat_stretch:` opt or changing the BPM instead. See the examples below for details.",
           args:          [[:path, :string]],
           opts:          {:rate    => "Rate modifier. For example, doubling the rate will halve the duration.",
                           :start   => "Start position of sample playback as a value from 0 to 1",
@@ -2762,151 +2807,425 @@ sample :loop_amen                    # starting it again
 
       ]
 
+      def sample_split_filts_and_opts(args)
+        idx = args.find_index {|el| el.is_a?(Hash)}
+        if idx
+          filts_and_sources =  args[0...idx]
+          opts = args[idx..-1]
+        else
+          filts_and_sources =  args
+          opts = {}
+        end
+
+        return filts_and_sources, opts
+      end
+
+      def resolve_sample_paths(filts_and_sources)
+        sample_find_candidates(filts_and_sources)
+      end
 
+      def resolve_sample_path(filts_and_sources)
+        resolve_sample_paths(filts_and_sources)[0]
+      end
 
 
-      def sample(path, *args_a_or_h)
-        return if path == nil
 
-        # Allow for hash only variant with :sample_name
-        # and procs as sample name inline with note()
-        case path
-        when Proc
-          return sample(path.call, *args_a_or_h)
-        when Hash
-          if path.has_key? :name
-            # handle case where sample receives Hash and args
-            new_path = path.delete(:name)
-            args_h = resolve_synth_opts_hash_or_array(args_a_or_h)
-            return sample(new_path, path.merge(args_h))
-          else
-            return nil
-          end
-        end
 
-        ensure_good_timing!
-        if path.is_a? Buffer
-          buf_info = path
-          if buf_info.path
-            path = buf_info.path
+      def sample_paths(*args)
+        filts_and_sources, args_a = sample_split_filts_and_opts(args)
+        resolve_sample_paths(filts_and_sources).ring
+      end
+      doc name:          :sample_paths,
+          introduced:    Version.new(2,10,0),
+          summary:       "Sample Pack Filter Resolution",
+          doc:           "Accepts the same pre-args and opts as `sample` and returns a ring of matched sample paths.",
+          args:          [[:pre_args, :source_and_filter_types]],
+          returns:       :ring,
+          opts:          nil,
+          accepts_block: false,
+          examples:      ["
+sample_paths \"/path/to/samples/\" #=> ring of all top-level samples in /path/to/samples",
+"
+sample_paths \"/path/to/samples/**\" #=> ring of all nested samples in /path/to/samples",
+"
+sample_paths \"/path/to/samples/\", \"foo\" #=> ring of all samples in /path/to/samples
+                                                containing the string \"foo\" in their filename."     ]
+
+
+
+
+      def sample(*args)
+        filts_and_sources, args_a = sample_split_filts_and_opts(args)
+        args_h = merge_synth_arg_maps_array(args_a)
+        tls = Thread.current.thread_variable_get(:sonic_pi_mod_sound_sample_defaults) || {}
+
+        args_h = tls.merge(args_h)
+
+
+        return @blank_node unless should_trigger?(args_h, true)
+
+        if filts_and_sources.size == 0
+          if args_h.has_key?(:sample_name)
+            # handle case where sample receives only opts
+            path = resolve_sample_path([args_h.delete(:sample_name)])
           else
-            path = "Buffer [#{buffer_info.id}]"
+            return @blank_node
           end
         else
-          buf_info = load_sample(path)
+          path = resolve_sample_path(filts_and_sources)
         end
-        args_h = resolve_synth_opts_hash_or_array(args_a_or_h)
 
-        return nil unless should_trigger?(args_h, true)
+        if path == nil
+          __delayed_message "sample #{filts_and_sources.inspect}\n           - no match found, skipping."
+          return @blank_node
+        end
+
+        path = unify_tilde_dir(path) if path.is_a? String
+
+        # Combine thread local defaults here as
+        # normalise_and_resolve_synth_args has only been taught about
+        # synth thread local defaults
+
 
-        trigger_sampler path, buf_info.id, buf_info.num_chans, args_h
+
+        if @mod_sound_studio.sample_loaded?(path)
+          return trigger_sampler path, args_h
+        else
+          res = Promise.new
+          in_thread { res.deliver!(trigger_sampler path, args_h)}
+          return LazyNode.new(res)
+        end
       end
+
       doc name:          :sample,
           introduced:    Version.new(2,0,0),
           summary:       "Trigger sample",
-          doc:           "This is the main method for playing back recorded sound files (samples). Sonic Pi comes with lots of great samples included (see the section under help) but you can also load and play `.wav`, `.wave`, `.aif` or `.aiff` files from anywhere on your computer too. The `rate:` opt affects both the speed and the pitch of the playback. To control the rate of the sample in a pitch-meaningful way take a look at the `rpitch:` opt.
+          doc:           "Play back a recorded sound file (sample). Sonic Pi comes with lots of great samples included (see the section under help) but you can also load and play `.wav`, `.wave`, `.aif`, `.aiff` or `.flac` files from anywhere on your computer too. To play a built-in sample use the corresponding keyword such as `sample :bd_haus`. To play any file on your computer use a full path such as `sample \"/path/to/sample.wav\"`.
 
-The sampler synth has two separate envelopes - one for amplitude and one for the cutoff value for a resonant low pass filter. These work very similar to the standard synth envelopes except for two major differences. Firstly, the envelope times do not stretch or shrink to match the BPM. Secondly, the sustain time by default stretches to make the envelope fit the length of the sample. This is explained in detail in the tutorial.
+There are many opts for manipulating the playback. For example, the `rate:` opt affects both the speed and the pitch of the playback. To control the rate of the sample in a pitch-meaningful way take a look at the `rpitch:` opt.
+
+The sampler synth has three separate envelopes - one for amplitude, one for a low pass filter and another for a high pass filter. These work very similar to the standard synth envelopes except for two major differences. Firstly, the envelope times do not stretch or shrink to match the BPM. Secondly, the sustain time by default stretches to make the envelope fit the length of the sample. This is explained in detail in the tutorial.
+
+Samples are loaded on-the-fly when first requested (and subsequently remembered). If the sample loading process takes longer than the schedule ahead time, the sample trigger will be skipped rather than be played late and out of time. To avoid this you may preload any samples you wish to work with using `load_sample` or `load_samples`.
+
+Finally, the sampler supports a powerful filtering system to make it easier to work with large folders of samples. The filter commands must be used before the first standard opt. There are six kinds of filter parameters you may use:
+
+1. Folder strings - `\"/foo/bar\"` - which will add all samples within the folder to the set of candidates.
+2. Sample strings - `\"/path/to/sample.wav\"` - which will add the specific sample to the set of candidates.
+3. Other strings - `\"foobar\"` - which will filter the candidates based on whether the filename contains the string.
+4. Regular expressions - `/b[aA]z.*/` - which will filter the candidates based on whether the regular expression matches the filename.
+5. Keywords - `:quux` - will filter the candidates based on whether the keyword is a direct match of the filename (without extension).
+7. Numbers - `0` - will select the candidate with that index (wrapping round like a ring if necessary).
+8. Lists of the above - `[\"/foo/bar\", \"baz\", /0-9.*/]` - will recurse down and work through the internal filter parameters as if they were in the top level.
+
+By combining commands which add to the candidates and then filtering those candidates it is possible to work with folders full of samples in very powerful ways. Note that the specific ordering of filter parameters is irrelevant with the exception of the numbers - in which case the last number is the index. All the candidates will be gathered first before the filters are applied.
+",
 
-Check out the `use_sample_pack` and `use_sample_pack_as` fns for details on making it easy to work with a whole folder of your own sample files. Note, that on the first trigger of a sample, Sonic Pi has to load the sample which takes some time and may cause timing issues. To preload the samples you wish to work with consider using `load_sample` or `load_samples`.",
           args:          [[:name_or_path, :symbol_or_string]],
           opts:          {:rate          => "Rate with which to play back the sample. Higher rates mean an increase in pitch and a decrease in duration. Default is 1.",
                           :beat_stretch  => "Stretch (or shrink) the sample to last for exactly the specified number of beats. Please note - this does *not* keep the pitch constant and is essentially the same as modifying the rate directly.",
-                          :pitch_stretch => "Stretch (or shrink) the sample to last for exactly the specified number of beats. This attempts to keep the pitch constant using the pitch: opt. Note, it's very likely you'll need to experiment with the `window_size:`, `pitch_dis:` and `time_dis:` opts depending on the sample and the amount you'd like to stretch/shrink from original size.",
-                          :attack        => "Time to reach full volume. Default is 0",
+                          :pitch_stretch => "Stretch (or shrink) the sample to last for exactly the specified number of beats. This attempts to keep the pitch constant using the `pitch:` opt. Note, it's very likely you'll need to experiment with the `window_size:`, `pitch_dis:` and `time_dis:` opts depending on the sample and the amount you'd like to stretch/shrink from original size.",
+                          :attack        => "Time to reach full volume. Default is 0.",
                           :sustain       => "Time to stay at full volume. Default is to stretch to length of sample (minus attack and release times).",
-                          :release       => "Time (from the end of the sample) to go from full amplitude to 0. Default is 0",
+                          :release       => "Time (from the end of the sample) to go from full amplitude to 0. Default is 0.",
                           :start         => "Position in sample as a fraction between 0 and 1 to start playback. Default is 0.",
                           :finish        => "Position in sample as a fraction between 0 and 1 to end playback. Default is 1.",
-                          :pan           => "Stereo position of audio. -1 is left ear only, 1 is right ear only, and values in between position the sound accordingly. Default is 0",
-                          :amp           => "Amplitude of playback",
-                          :norm          => "Normalise the audio (make quieter parts of the sample louder and louder parts quieter) - this is similar to the normaliser FX. This may emphasise any clicks caused by clipping.",
-                          :cutoff               => "Cutoff value of the built-in resonant low pass filter (rlpf) in MIDI notes. Unless specified, the rlpf is *not* added to the signal chain.",
-                          :cutoff_attack_level  => "The peak cutoff (value of cutoff at peak of attack) as a MIDI note. Default value is 130.",
-                          :cutoff_decay_level   => "The level of cutoff after the decay phase as a MIDI note. Default value is `:cutoff_attack_level`.",
-                          :cutoff_sustain_level => "The sustain cutoff (value of cutoff at sustain time) as a MIDI note. Default value is `:cutoff_decay_level`.",
-                          :cutoff_attack        => "Attack time for cutoff filter. Amount of time (in beats) for sound to reach full cutoff value. Default value is set to match amp envelope's attack value.",
-                          :cutoff_decay         => "Decay time for cutoff filter. Amount of time (in beats) for sound to move from full cutoff value (cutoff attack level) to the cutoff sustain level. Default value is set to match amp envelope's decay value.",
-                          :cutoff_sustain       =>  "Amount of time for cutoff value to remain at sustain level in beats. When -1 (the default) will auto-stretch.",
-                          :cutoff_release       => "Amount of time (in beats) for sound to move from cutoff sustain value to cutoff min value. Default value is set to match amp envelope's release value.",
-                          :cutoff_env_curve     => "Select the shape of the curve between levels in the cutoff envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed",
-                          :res           => "Cutoff-specific opt. Only honoured if cutoff: is specified. Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.",
-                          :rpitch        => "Rate modified pitch. Multiplies the rate by the appropriate ratio to shift up or down the specified amount in MIDI notes. Please note - this does *not* keep the duration and rhythmical rate constant and ie essentially the same as modifying the rate directly.",
+                          :pan           => "Stereo position of audio. -1 is left ear only, 1 is right ear only, and values in between position the sound accordingly. Default is 0.",
+                          :amp           => "Amplitude of playback.",
+                          :pre_amp           => "Amplitude multiplier which takes place immediately before any internal FX such as the low pass filter, compressor or pitch modification. Use this opt if you want to overload the compressor.",
+                          :norm              => "Normalise the audio (make quieter parts of the sample louder and louder parts quieter) - this is similar to the normaliser FX. This may emphasise any clicks caused by clipping.",
+                          :lpf               => "Cutoff value of the built-in low pass filter (lpf) in MIDI notes. Unless specified, the lpf is *not* added to the signal chain.",
+                          :lpf_init_level => "The initial low pass filter envelope value as a MIDI note. This envelope is bypassed if no lpf env opts are specified. Default value is to match the `lpf_min:` opt.",
+                          :lpf_attack_level  => "The peak lpf cutoff (value of cutoff at peak of attack) as a MIDI note. Default value is to match the `lpf_decay_level:` opt.",
+                          :lpf_decay_level   => "The level of lpf cutoff after the decay phase as a MIDI note. Default value is to match the `lpf_sustain_level:` opt.",
+                          :lpf_sustain_level => "The sustain cutoff (value of lpf cutoff at sustain time) as a MIDI note. Default value is to match the `lpf_release_level:` opt.",
+                          :lpf_release_level => "The final value of the low pass filter envelope as a MIDI note. This envelope is bypassed if no lpf env opts are specified. Default value is to match the `lpf:` opt.",
+                          :lpf_attack        => "Attack time for lpf cutoff filter. Amount of time (in beats) for sound to reach full cutoff value. Default value is set to match amp envelope's attack value.",
+                          :lpf_decay         => "Decay time for lpf cutoff filter. Amount of time (in beats) for sound to move from full cutoff value (cutoff attack level) to the cutoff sustain level. Default value is set to match amp envelope's decay value.",
+                          :lpf_sustain       =>  "Amount of time for lpf cutoff value to remain at sustain level in beats. When -1 (the default) will auto-stretch.",
+                          :lpf_release       => "Amount of time (in beats) for sound to move from lpf cutoff sustain value to lpf cutoff min value. Default value is set to match amp envelope's release value.",
+                          :lpf_min           => "Starting value of the lpf cutoff envelope. Default is 30.",
+                          :lpf_env_curve     => "Select the shape of the curve between levels in the lpf cutoff envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed.",
+                          :hpf               => "Cutoff value of the built-in high pass filter (hpf) in MIDI notes. Unless specified, the hpf is *not* added to the signal chain.",
+                          :hpf_init_level => "The initial high pass filter envelope value as a MIDI note. This envelope is bypassed if no hpf env opts are specified. Default value is set to 130.",
+                          :hpf_attack_level  => "The peak hpf cutoff (value of cutoff at peak of attack) as a MIDI note. Default value is to match the `hpf_decay_level:` opt.",
+                          :hpf_decay_level   => "The level of hpf cutoff after the decay phase as a MIDI note. Default value is to match the `hpf_sustain_level:` opt.",
+                          :hpf_sustain_level => "The sustain cutoff (value of hpf cutoff at sustain time) as a MIDI note. Default value is to match the `hpf_release_level:` opt.",
+                          :hpf_release_level => "The sustain hpf cutoff (value of hpf cutoff at sustain time) as a MIDI note. Default value is to match the `hpf:` opt.",
+                          :hpf_attack        => "Attack time for hpf cutoff filter. Amount of time (in beats) for sound to reach full cutoff value. Default value is set to match amp envelope's attack value.",
+                          :hpf_decay         => "Decay time for hpf cutoff filter. Amount of time (in beats) for sound to move from full cutoff value (cutoff attack level) to the cutoff sustain level. Default value is set to match amp envelope's decay value.",
+                          :hpf_sustain       =>  "Amount of time for hpf cutoff value to remain at sustain level in beats. When -1 (the default) will auto-stretch.",
+                          :hpf_release       => "Amount of time (in beats) for sound to move from hpf cutoff sustain value to hpf cutoff min value. Default value is set to match amp envelope's release value.",
+                          :hpf_env_curve     => "Select the shape of the curve between levels in the hpf cutoff envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed.",
+                          :hpf_max           => "Maximum value of the high pass filter envelope. Default is 200.",
+                          :rpitch        => "Rate modified pitch. Multiplies the rate by the appropriate ratio to shift up or down the specified amount in MIDI notes. Please note - this does *not* keep the duration and rhythmical rate constant and is essentially the same as modifying the rate directly.",
                           :pitch         => "Pitch adjustment in semitones. 1 is up a semitone, 12 is up an octave, -12 is down an octave etc. Maximum upper limit of 24 (up 2 octaves). Lower limit of -72 (down 6 octaves). Decimal numbers can be used for fine tuning.",
-                          :window_size   => "Pitch shift-specific opt - only honoured if the pitch: opt is used. Pitch shift works by chopping the input into tiny slices, then playing these slices at a higher or lower rate. If we make the slices small enough and overlap them, it sounds like the original sound with the pitch changed. The window_size is the length of the slices and is measured in seconds. It needs to be around 0.2 (200ms) or greater for pitched sounds like guitar or bass, and needs to be around 0.02 (20ms) or lower for percussive sounds like drum loops. You can experiment with this to get the best sound for your input.",
-                          :pitch_dis     => "Pitch shift-specific opt - only honoured if the pitch: opt is used. Pitch dispersion - how much random variation in pitch to add. Using a low value like 0.001 can help to \"soften up\" the metallic sounds, especially on drum loops. To be really technical, pitch_dispersion is the maximum random deviation of the pitch from the pitch ratio (which is set by the pitch param)",
-                          :time_dis      => "Pitch shift-specific opt - only honoured if the pitch: opt is used. Time dispersion - how much random delay before playing each grain (measured in seconds). Again, low values here like 0.001 can help to soften up metallic sounds introduced by the effect. Large values are also fun as they can make soundscapes and textures from the input, although you will most likely lose the rhythm of the original. NB - This won't have an effect if it's larger than window_size.",
-                          :slide         => "Default slide time in beats for all slide opts. Individually specified slide opts will override this value" },
+                          :window_size   => "Pitch shift-specific opt - only honoured if the `pitch:` opt is used. Pitch shift works by chopping the input into tiny slices, then playing these slices at a higher or lower rate. If we make the slices small enough and overlap them, it sounds like the original sound with the pitch changed. The window_size is the length of the slices and is measured in seconds. It needs to be around 0.2 (200ms) or greater for pitched sounds like guitar or bass, and needs to be around 0.02 (20ms) or lower for percussive sounds like drum loops. You can experiment with this to get the best sound for your input.",
+                          :pitch_dis     => "Pitch shift-specific opt - only honoured if the `pitch:` opt is used. Pitch dispersion - how much random variation in pitch to add. Using a low value like 0.001 can help to \"soften up\" the metallic sounds, especially on drum loops. To be really technical, pitch_dispersion is the maximum random deviation of the pitch from the pitch ratio (which is set by the `pitch:` opt).",
+                          :time_dis      => "Pitch shift-specific opt - only honoured if the `pitch:` opt is used. Time dispersion - how much random delay before playing each grain (measured in seconds). Again, low values here like 0.001 can help to soften up metallic sounds introduced by the effect. Large values are also fun as they can make soundscapes and textures from the input, although you will most likely lose the rhythm of the original. NB - This won't have an effect if it's larger than window_size.",
+
+
+                          :compress => "Enable the compressor. This sits at the end of the internal FX chain immediately before the `amp:` opt. Therefore to drive the compressor use the `pre_amp:` opt which will amplify the signal before it hits any internal FX. The compressor compresses the dynamic range of the incoming signal. Equivalent to automatically turning the amp down when the signal gets too loud and then back up again when it's quiet. Useful for ensuring the containing signal doesn't overwhelm other aspects of the sound. Also a general purpose hard-knee dynamic range processor which can be tuned via the opts to both expand and compress the signal.",
+
+                          :threshold => "Threshold value determining the break point between slope_below and slope_above. Only valid if the compressor is enabled by turning on the `compress:` opt.",
+
+                          :slope_below => "Slope of the amplitude curve below the threshold. A value of 1 means that the output of signals with amplitude below the threshold will be unaffected. Greater values will magnify and smaller values will attenuate the signal. Only valid if the compressor is enabled by turning on the `compress:` opt.",
+                          :slope_above => "Slope of the amplitude curve above the threshold. A value of 1 means that the output of signals with amplitude above the threshold will be unaffected. Greater values will magnify and smaller values will attenuate the signal. Only valid if the compressor is enabled by turning on the `compress:` opt.",
+
+                          :clamp_time => "Time taken for the amplitude adjustments to kick in fully (in seconds). This is usually pretty small (not much more than 10 milliseconds). Also known as the time of the attack phase. Only valid if the compressor is enabled by turning on the `compress:` opt.",
+
+                          :relax_time => "Time taken for the amplitude adjustments to be released. Usually a little longer than clamp_time. If both times are too short, you can get some (possibly unwanted) artefacts. Also known as the time of the release phase. Only valid if the compressor is enabled by turning on the `compress:` opt.",
+
+
+                          :slide      => "Default slide time in beats for all slide opts. Individually specified slide opts will override this value." },
           accepts_block: false,
           intro_fn:       true,
 
 
           examples:      ["
-sample :perc_bell # plays one of Sonic Pi's built in samples",
-        "sample '/home/yourname/path/to/a/sample.wav' # plays a wav|wave|aif|aiff file from your local filesystem",
-        "# Let's play with the rate parameter
-# play one of the included samples
-sample :loop_amen
-sleep sample_duration(:loop_amen) # this sleeps for exactly the length of the sample
+# Play a built-in sample
 
-# Setting a rate of 0.5 will cause the sample to
-#   a) play half as fast
-#   b) play an octave down in pitch
-#
-# Listen:
-sample :loop_amen, rate: 0.5
-sleep sample_duration(:loop_amen, rate: 0.5)
-
-# Setting a really low number means the sample takes
-# a very long time to finish! Also it sounds very
-# different to the original sound
-sample :loop_amen, rate: 0.05
-sleep sample_duration(:loop_amen, rate: 0.05)",
-        "# Setting a really negative number can be lots of fun
-# It plays the sample backwards!
-sample :loop_amen, rate: -1
-sleep sample_duration(:loop_amen, rate: 1)  # there's no need to give sample_duration a negative number though
-
-                                             # Using a rate of -0.5 is just like using the positive 0.5
-                                             # (lower in pitch and slower) except backwards
-sample :loop_amen, rate: -0.5
-sleep sample_duration(:loop_amen, rate: 0.5) # there's no need to give sample_duration a negative number though",
-        "# BE CAREFUL
-# Don't set the rate to 0 though because it will get stuck
-# and won't make any sound at all!
-# We can see that the following would take Infinity seconds to finish
-puts sample_duration(:loop_amen, rate: 0)",
-        "# Just like the play method, we can assign our sample player
-# to a variable and control the rate parameter whilst it's playing.
-#
-# The following example sounds a bit like a vinyl speeding up
-# Note, this technique only works when you don't use envelope or start/finish opts.
-s = sample :loop_amen_full, rate: 0.05
-sleep 1
-control(s, rate: 0.2)
-sleep 1
-control(s, rate: 0.4)
-sleep 1
-control(s, rate: 0.6)
-sleep 1
-control(s, rate: 0.8)
-sleep 1
-control(s, rate: 1)",
+sample :loop_amen # Plays the Amen break",
         "
-# Using the :start and :finish parameters you can play a section of the sample.
-# The default start is 0 and the default finish is 1
-sample :loop_amen, start: 0.5, finish: 1 # play the last half of a sample",
+# Play two samples at the same time
+# with incredible timing accuracy
+
+sample :loop_amen
+sample :ambi_lunar_land # Note, for timing guarantees select the pref:
+                        #   Studio -> Synths and FX -> Enforce timing guarantees",
         "
-# You can also play part of any sample backwards by using a start value that's
-# higher than the finish
-sample :loop_amen, start: 1, finish: 0.5 # play the last half backwards",
+# Create a simple repeating bass drum
+
+live_loop :bass do
+  sample :bd_haus
+  sleep 0.5
+end",
+        "
+# Create a more complex rhythm with multiple live loops:
+
+live_loop :rhythm do
+  sample :tabla_ghe3 if (spread 5, 7).tick
+  sleep 0.125
+end
+
+live_loop :bd, sync: :rhythm do
+  sample :bd_haus, lpf: 90, amp: 2
+  sleep 0.5
+end",
+        "
+# Change the playback speed of the sample using rate:
+
+sample :loop_amen, rate: 0.5 # Play the Amen break at half speed
+                             # for old school hip-hop",
+        "
+# Speed things up
+
+sample :loop_amen, rate: 1.5 # Play the Amen break at 1.5x speed
+                             # for a jungle/gabba sound",
+        "
+# Go backwards
+
+sample :loop_amen, rate: -1 # Negative rates play the sample backwards",
+        "
+# Fast rewind
+
+sample :loop_amen, rate: -3 # Play backwards at 3x speed for a fast rewind effect",
+        "
+# Start mid sample
+
+sample :loop_amen, start: 0.5 # Start playback half way through",
+        "
+# Finish mid sample
+
+sample :loop_amen, finish: 0.5 # Finish playback half way through",
+        "
+# Play part of a sample
+
+sample :loop_amen, start: 0.125, finish: 0.25 # Play the second eighth of the sample",
+        "
+# Finishing before the start plays backwards
+
+sample :loop_amen, start: 0.25, finish: 0.125 # Play the second eighth of the sample backwards",
+        "
+# Play a section of a sample half speed backwards
+
+sample :loop_amen, start: 0.125, finish: 0.25, rate: -0.25 # Play the second eighth of the
+                                                           # amen break backwards at a
+                                                           # quarter speed",
+        "
+# Build a simple beat slicer
+
+use_sample_bpm :loop_amen                    # Set the BPM to match the amen break sample
+
+live_loop :beat_slicer do
+  n = 8                                      # Set number of slices. Try changing this
+                                             # to 2, 4, 6, 16 or 32
+
+  d = 1.0 / n                                # Calculate the duration of a slice as a
+                                             # fraction of the sample
+
+  s = (line 0, 1, steps: n).choose           # Create a ring of starting points and
+                                             # randomly choose one
+
+  f = s + d                                  # Calculate the finish point
+
+  sample :loop_amen, start: s, finish: f     # Play the specific part of the sample
+
+  sleep d                                    # Sleep for the duration of the slice
+end",
+        "
+# Play with the built-in low pass filter, high pass filter and compressor
+
+sample :loop_amen, lpf: 80, hpf: 70, compress: 1, pre_amp: 10 # Make the amen break sound punchy.",
+        "
+# Use the cutoff filter envelopes
+
+sample :loop_garzul, lpf_attack: 8 # Sweep the low pass filter up over 8 beats
+sleep 8
+sample :loop_garzul, hpf_attack: 8 # Sweep the high pass filter down over 8 beats",
+        "
+# Sample stretching
+
+puts sample_duration :loop_industrial                   # => 0.88347
+puts sample_duration :loop_industrial, beat_stretch: 1  # => 1
+
+live_loop :industrial do
+  sample :loop_industrial, beat_stretch: 1              # Stretch the sample to make it 1 beat long
+  sleep 1                                               # This now loops perfectly.
+                                                        # However, note that stretching/shrinking
+                                                        # also modifies the pitch.
+end",
+        "
+# Sample shrinking
+
+puts sample_duration :loop_garzul                       # => 8
+puts sample_duration :loop_garzul, beat_stretch: 6      # => 6
+
+live_loop :garzul do
+  sample :loop_garzul, beat_stretch: 6                  # As :loop_garzul is longer than 6 beats
+                                                        # it is shrunk to fit. This increases the
+                                                        # pitch.
+
+  sleep 6
+end",
+        "
+# Sample stretching matches the BPM
+
+use_bpm 30                                              # Set the BPM to 30
+
+puts sample_duration :loop_garzul                       # => 4.0 (at 30 BPM the sample lasts for 4 beats)
+puts sample_duration :loop_garzul, beat_stretch: 6      # => 6.0
+
+live_loop :garzul do
+  sample :loop_garzul, beat_stretch: 6                  # The sample is stretched to match 6 beats at 30 BPM
+  sleep 6
+end",
         "
-# You can also specify the sample using a Hash with a `:sample_name` key
-sample {sample_name: :loop_amen, rate: 2}",
+# External samples
+
+sample \"/path/to/sample.wav\"                          # Play any Wav, Aif or FLAC sample on your computer
+                                                        # by simply passing a string representing the full
+                                                        # path",
         "
-# You can also specify the sample using a lambda that yields a symbol
-# although you probably don't need a lambda for this in most cases.
-sample lambda { [:loop_amen, :loop_garzul].choose }"]
+# Sample pack filtering
+
+dir = \"/path/to/dir/of/samples\"                       # You can easily work with a directory of samples
+
+sample dir                                              # Play the first sample in the directory
+                                                        # (it is sorted alphabetically)
+
+sample dir, 1                                           # Play the second sample in the directory
+
+sample dir, 99                                          # Play the 99th sample in the directory, or if there
+                                                        # are fewer, treat the directory like a ring and keep
+                                                        # wrapping the index round until a sample is found.
+                                                        # For example, if there are 90 samples, the 10th sample
+                                                        # is played (index 9).
+
+sample dir, \"120\"                                     # Play the first sample in the directory that contains
+                                                        # the substring \"120\".
+                                                        # For example, this may be \"beat1_120_rave.wav\"
+
+sample dir, \"120\", 1                                  # Play the second sample in the directory that contains
+                                                        # the substring \"100\".
+                                                        # For example, this may be \"beat2_120_rave.wav\"
+
+sample dir, /beat[0-9]/                                 # Play the first sample in the directory that matches
+                                                        # the regular expression /beat[0-9]/.
+                                                        # For example, this may be \"beat0_100_trance.wav\"
+                                                        # You may use the full power of Ruby's regular expression
+                                                        # system here: http://ruby-doc.org/core-2.1.1/Regexp.html
+
+sample dir, /beat[0-9]0/, \"100\"                       # Play the first sample in the directory that both matches
+                                                        # the regular expression /beat[0-9]0/ and contains the
+                                                        # the substring \"100\".
+                                                        # For example, this may be \"beat10_100_rave.wav\"",
+        "
+# Filtering built-in samples
+
+                                                        # If you don't pass a directory source, you can filter over
+                                                        # the built-in samples.
+sample \"tabla_\"                                       # Play the first built-in sample that contains the substring
+                                                        # \"tabla\"
+
+sample \"tabla_\", 2                                    # Play the second built-in sample that contains the substring
+                                                        # \"tabla\"",
+        "
+# Play with whole directories of samples
+
+load_samples \"tabla_\"                                 # You may pass any of the source/filter options to load_samples
+                                                        # to load all matching samples. This will load all the built-in
+                                                        # samples containing the substring \"tabla_\"
+
+live_loop :tabla do
+  sample \"tabla_\", tick                               # Treat the matching samples as a ring and tick through them
+  sleep 0.125
+end",
+        "
+# Specify multiple sources
+
+dir1 = \"/path/to/sample/directory\"
+dir2 = \"/path/to/other/sample/directory\"
+
+sample dir1, dir2, \"foo\"                              # Match the first sample that contains the string \"foo\" out of
+                                                        # all the samples in dir1 and dir2 combined.
+
+                                                        # Note that the sources must be listed before any filters.",
+        "
+# List contents recursively
+dir = \"/path/to/sample/directory\"                     # By default the list of all top-level samples within the directory
+                                                        # is considered.
+dir_recursive = \"/path/to/sample/directory/**\"        # However, if you finish your directory string with ** then if that
+                                                        # directory contains other directories then the samples within the
+                                                        # subdirectories and their subsubdirectories in turn are considered.
+
+sample dir, 0                                           # Play the first top-level sample in the directory
+
+sample dir_recursive, 0                                 # Play the first sample found after combinining all samples found in
+                                                        # the directory and all directories within it recursively.
+                                                        # Note that if there are many sub directories this may take some time
+                                                        # to execute. However, the result is cached so subsequent calls will
+                                                        # be fast.",
+        "
+# Bespoke filters
+
+
+filter = lambda do |candidates|                         # If the built-in String, Regexp and index filters are not sufficient
+  [candidates.choose]                                   # you may write your own. They need to be a function which takes a list
+end                                                     # of paths to samples and return a list of samples. This one returns a
+                                                        # list of a single randomly selected sample.
+8.times do
+  sample \"drum_\", filter                              # Play 8 randomly selected samples from the built-in sample set that also
+  sleep 0.25                                            # contain the substring \"drum_\"
+end"
+]
+
+
+
+
+
+
+
 
 
 
@@ -2953,7 +3272,7 @@ puts status # Returns something similar to:
         when Proc
           return note(n.call, *args)
         when Hash
-          return note(n[:note], *args)
+          raise "Unable to create a note from the Map: #{n.inspect}"
         end
 
         return Note.resolve_midi_note_without_octave(n) if args.empty?
@@ -3075,7 +3394,18 @@ play degree(2, :C3, :minor)
 
 
 
-      def scale(tonic, name, *opts)
+      def scale(tonic_or_name, *opts)
+        tonic = 0
+        name = :minor
+        if opts.size == 0
+          name = tonic_or_name
+        elsif (opts.size == 1) && opts[0].is_a?(Hash)
+          name = tonic_or_name
+        else
+          tonic = tonic_or_name
+          name = opts.shift
+        end
+
         opts = resolve_synth_opts_hash_or_array(opts)
         opts = {:num_octaves => 1}.merge(opts)
         Scale.new(tonic, name,  opts[:num_octaves]).ring
@@ -3083,22 +3413,22 @@ play degree(2, :C3, :minor)
       doc name:          :scale,
           introduced:    Version.new(2,0,0),
           summary:       "Create scale",
-          doc:           "Creates a ring of MIDI note numbers when given a tonic note and a scale type. Also takes an optional `num_octaves:` parameter (octave `1` is the default)",
+          doc:           "Creates a ring of MIDI note numbers when given a tonic note and a scale name. Also takes an optional `num_octaves:` parameter (octave `1` is the default). If only passed the scale name, the tonic defaults to 0. See examples.",
           args:          [[:tonic, :symbol], [:name, :symbol]],
           returns:        :ring,
           opts:          {:num_octaves => "The number of octaves you'd like the scale to consist of. More octaves means a larger scale. Default is 1."},
           accepts_block: false,
           intro_fn:       true,
           examples:      ["
-puts scale(:C, :major) # returns the following ring of MIDI note numbers: (ring 60, 62, 64, 65, 67, 69, 71, 72)",
+puts (scale :C, :major) # returns the following ring of MIDI note numbers: (ring 60, 62, 64, 65, 67, 69, 71, 72)",
         "# anywhere you can use a list or ring of notes, you can also use scale
 play_pattern (scale :C, :major)",
         "# you can use the :num_octaves parameter to get more notes
-play_pattern(:C, :major, num_octaves: 2)",
+play_pattern (scale :C, :major, num_octaves: 2)",
         "# Scales can start with any note:
 puts (scale 50, :minor) #=> (ring 50, 52, 53, 55, 57, 58, 60, 62)
 puts (scale 50.1, :minor) #=> (ring 50.1, 52.1, 53.1, 55.1, 57.1, 58.1, 60.1, 62.1)
-puts (scale 0, :minor) #=> (ring 0, 2, 3, 5, 7, 8, 10, 12)",
+puts (scale :minor) #=> (ring 0, 2, 3, 5, 7, 8, 10, 12)",
 
 
 " # scales are also rings
@@ -3218,7 +3548,18 @@ end",
 
 
 
-      def chord(tonic, name=:major, *opts)
+      def chord(tonic_or_name, *opts)
+        tonic = 0
+        name = :minor
+        if opts.size == 0
+          name = tonic_or_name
+        elsif (opts.size == 1) && opts[0].is_a?(Hash)
+          name = tonic_or_name
+        else
+          tonic = tonic_or_name
+          name = opts.shift
+        end
+
         return [] unless tonic
         opts = resolve_synth_opts_hash_or_array(opts)
         c = []
@@ -3234,7 +3575,7 @@ end",
       doc name:          :chord,
           introduced:    Version.new(2,0,0),
           summary:       "Create chord",
-          doc:           "Creates an immutable ring of Midi note numbers when given a tonic note and a chord type",
+          doc:           "Creates an immutable ring of Midi note numbers when given a tonic note and a chord type. If only passed a chord type, will default the tonic to 0. See examples.",
           args:          [[:tonic, :symbol], [:name, :symbol]],
           returns:        :ring,
           opts:          {invert: "Apply the specified num inversions to chord. See the fn `chord_invert`.",
@@ -3253,6 +3594,9 @@ play (chord :e3, :minor, invert: 1) # Play the first inversion of :e3, :minor -
 play (chord :e3, :minor, invert: 2) # Play the first inversion of :e3, :minor - (ring 59, 64, 67)
 ",
 
+"# You can create a chord without a tonic:
+puts (chord :minor) #=> (ring 0, 3, 7)",
+
 "# chords are great for arpeggiators
 live_loop :arp do
   play chord(:e, :minor, num_octaves: 2).tick, release: 0.1
@@ -3295,6 +3639,16 @@ end",
 (chord :C, 'm11+')
 (chord :C, '13')
 (chord :C, :m13)
+(chord :C, :add2)
+(chord :C, :add4)
+(chord :C, :add9)
+(chord :C, :add11)
+(chord :C, :add13)
+(chord :C, :madd2)
+(chord :C, :madd4)
+(chord :C, :madd9)
+(chord :C, :madd11)
+(chord :C, :madd13)
 (chord :C, :major)
 (chord :C, :M)
 (chord :C, :minor)
@@ -3320,7 +3674,7 @@ end",
 
       def chord_invert(notes, shift)
         raise "Inversion shift value must be a number, got #{shift.inspect}" unless shift.is_a?(Numeric)
-        raise "Notes must be a list of notes, got #{notes.inspect}" unless (notes.is_a?(SonicPi::Core::RingVector) || notes.is_a?(Array))
+        raise "Notes must be a list of notes, got #{notes.inspect}" unless (notes.is_a?(SonicPi::Core::SPVector) || notes.is_a?(Array))
         if(shift > 0)
           chord_invert(notes.to_a[1..-1] + [notes.to_a[0]+12], shift-1)
         elsif(shift < 0)
@@ -3358,11 +3712,12 @@ play (chord_invert (chord :A3, \"M\"), 2) #Second inversion - (ring 64, 69, 73)
 
 
       def control(node, *args)
-        ensure_good_timing!
-        return nil if node.nil?
 
+        return nil if node.nil?
+        raise "You may only control a SynthNode. You tried to control a #{node.class}: #{node.inspect}" unless node.is_a?(Node)
         args_h = resolve_synth_opts_hash_or_array(args)
 
+        return nil unless should_trigger?(args_h)
         # set default slide times
         default_slide_time = args_h[:slide]
         args_h.delete :slide
@@ -3374,20 +3729,25 @@ play (chord_invert (chord :A3, \"M\"), 2) #Second inversion - (ring 64, 69, 73)
           resolve_midi_args!(args_h, info)
         end
 
-        if args_h.has_key?(:note)
-          n = normalise_transpose_and_tune_note_from_args(args_h[:note], args_h)
-          args_h[:note] = n
-        end
 
-        notes = args_h[:notes]
-        if node.is_a?(ChordGroup) && notes
+
+        if node.is_a?(ChordGroup)
+
+          note = args_h.delete(:note)
+          notes = args_h.delete(:notes)
+          notes = note if note && !notes
+          notes = [notes] unless notes.is_a?(Array) || notes.is_a?(SonicPi::Core::SPVector)
+          normalise_args! args_h
           # don't normalise notes key as it is special
           # when controlling ChordGroups.
           # TODO: remove this hard coded behaviour
-          args_h.delete(:notes)
-          normalise_args! args_h
           args_h[:notes] = notes.map{|n| normalise_transpose_and_tune_note_from_args(n, args_h)}
         else
+          note = args_h[:note]
+          if note
+            note = normalise_transpose_and_tune_note_from_args(note, args_h)
+            args_h[:note] = note
+          end
           normalise_args! args_h
         end
 
@@ -3395,6 +3755,13 @@ play (chord_invert (chord :A3, \"M\"), 2) #Second inversion - (ring 64, 69, 73)
           info.ctl_validate!(args_h) if info
         end
 
+        if Thread.current.thread_variable_get(:sonic_pi_mod_sound_timing_guarantees)
+          unless in_good_time?
+            __delayed_message "!! Out of time, skipping: control node #{node.id}, #{arg_h_pp(args_h)}"
+            return node
+          end
+        end
+
         node.control args_h
 
         unless Thread.current.thread_variable_get(:sonic_pi_mod_sound_synth_silent)
@@ -3405,7 +3772,7 @@ play (chord_invert (chord :A3, \"M\"), 2) #Second inversion - (ring 64, 69, 73)
       doc name:          :control,
           introduced:    Version.new(2,0,0),
           summary:       "Control running synth",
-          doc:           "Control a running synth node by passing new parameters to it. A synth node represents a running synth and can be obtained by assigning the return value of a call to play or sample or by specifying a parameter to the do/end block of an FX. You may modify any of the parameters you can set when triggering the synth, sample or FX. See documentation for opt details. If the synth to control is a chord, then control will change all the notes of that chord group at once to a new target set of notes - see example. ",
+          doc:           "Control a running synth node by passing new parameters to it. A synth node represents a running synth and can be obtained by assigning the return value of a call to play or sample or by specifying a parameter to the do/end block of an FX. You may modify any of the parameters you can set when triggering the synth, sample or FX. See documentation for opt details. If the synth to control is a chord, then control will change all the notes of that chord group at once to a new target set of notes - see example. Also, you may use the on: opt to conditionally trigger the control - see the docs for the `synth` and `sample` fns for more information.",
           args:          [[:node, :synth_node]],
           opts:          {},
           accepts_block: false,
@@ -3490,7 +3857,7 @@ control cg, notes: (chord :e3, :m13)                     # slide to new chord wi
 
 
       def kill(node)
-        ensure_good_timing!
+        in_good_time?
         return nil if node.nil?
 
         alive = node.live?
@@ -3523,13 +3890,16 @@ kill bar"]
 
 
       def sample_names(group)
-        Synths::BaseInfo.grouped_samples[group][:samples].ring
+        g = Synths::BaseInfo.grouped_samples[group]
+        raise "Unknown sample group #{group.inspect}" unless g
+        g[:samples].sort.ring
       end
       doc name:          :sample_names,
           introduced:    Version.new(2,0,0),
           summary:       "Get sample names",
-          doc:           "Return a list of sample names for the specified group",
+          doc:           "Return a ring of sample names for the specified group",
           args:          [[:group, :symbol]],
+          returns:        :ring,
           opts:          nil,
           accepts_block: false,
           examples:      []
@@ -3538,7 +3908,7 @@ kill bar"]
 
 
       def all_sample_names
-        Synths::BaseInfo.all_samples.ring
+        Synths::BaseInfo.all_samples.sort.ring
       end
       doc name:          :all_sample_names,
           introduced:    Version.new(2,0,0),
@@ -3553,7 +3923,7 @@ kill bar"]
 
 
       def sample_groups
-        Synths::BaseInfo.grouped_samples.keys.ring
+        Synths::BaseInfo.grouped_samples.keys.sort.ring
       end
       doc name:          :sample_groups,
           introduced:    Version.new(2,0,0),
@@ -3568,7 +3938,7 @@ kill bar"]
 
 
       def synth_names
-        Synths::BaseInfo.all_synths.ring
+        Synths::BaseInfo.all_synths.sort.ring
       end
       doc name:          :synth_names,
           introduced:    Version.new(2,9,0),
@@ -3580,6 +3950,17 @@ kill bar"]
           examples:      []
 
 
+      def fx_names
+        Synths::BaseInfo.all_fx.sort.ring
+      end
+      doc name:          :fx_names,
+          introduced:    Version.new(2,10,0),
+          summary:       "Get all FX names",
+          doc:           "Return a list of all the FX available",
+          args:          [],
+          opts:          nil,
+          accepts_block: false,
+          examples:      []
 
 
       def load_synthdefs(path=synthdef_path)
@@ -3593,9 +3974,15 @@ kill bar"]
           summary:       "Load external synthdefs",
           doc:           "Load all pre-compiled synth designs in the specified directory. The binary files containing synth designs need to have the extension `.scsyndef`. This is useful if you wish to use your own SuperCollider synthesiser designs within Sonic Pi.
 
-## Important note
+## Important notes
+
+You may not trigger external synthdefs unless you enable the following GUI preference:
 
-If you wish your synth to work with Sonic Pi's automatic stereo sound infrastructure *you need to ensure your synth outputs a stereo signal* to an audio bus with an index specified by a synth arg named `out_bus`. For example, the following synth would work nicely:
+```
+Studio -> Synths -> Enable external synths and FX
+```
+
+Also, if you wish your synth to work with Sonic Pi's automatic stereo sound infrastructure *you need to ensure your synth outputs a stereo signal* to an audio bus with an index specified by a synth arg named `out_bus`. For example, the following synth would work nicely:
 
 
     (
@@ -3615,7 +4002,7 @@ If you wish your synth to work with Sonic Pi's automatic stereo sound infrastruc
 
 
       def scale_names
-        Scale::SCALE.keys.ring
+        Scale::SCALE.keys.sort.ring
       end
       doc name:          :scale_names,
           introduced:    Version.new(2,6,0),
@@ -3628,7 +4015,7 @@ If you wish your synth to work with Sonic Pi's automatic stereo sound infrastruc
 
 
       def chord_names
-        Chord::CHORD.keys.ring
+        Chord::CHORD.keys.sort.ring
       end
       doc name:          :chord_names,
           introduced:    Version.new(2,6,0),
@@ -3641,6 +4028,10 @@ If you wish your synth to work with Sonic Pi's automatic stereo sound infrastruc
 
       private
 
+      def init_tuning
+        @tuning = Tuning.new
+      end
+
       def normalise_args!(args_h, defaults={})
         args_h.keys.each do |k|
           v = args_h[k]
@@ -3655,7 +4046,7 @@ If you wish your synth to work with Sonic Pi's automatic stereo sound infrastruc
             when FalseClass
               args_h[k] = 0.0
             when NilClass
-              args_h[k] = 0.0
+              args_h[k] = nil
             else
               begin
                 args_h[k] = res.to_f
@@ -3672,7 +4063,7 @@ If you wish your synth to work with Sonic Pi's automatic stereo sound infrastruc
           when FalseClass
             args_h[k] = 0.0
           when NilClass
-            args_h[k] = 0.0
+            args_h[k] = nil
           else
             begin
               args_h[k] = v.to_f
@@ -3685,49 +4076,13 @@ If you wish your synth to work with Sonic Pi's automatic stereo sound infrastruc
       end
 
       def find_sample_with_path(path)
-        ["wav", "aiff", "aif", "wave"].each do |ext|
+        ["wav", "wave", "aif", "aiff", "flac"].each do |ext|
           full = "#{path}.#{ext}"
           return full if File.exists?(full)
         end
         return nil
       end
 
-      def fetch_or_cache_sample_path(sym)
-        cached = @sample_paths_cache[sym]
-        return cached if cached
-
-        res = find_sample_with_path("#{samples_path}/#{sym.to_s}")
-
-        raise "No sample exists called :#{sym} in default sample pack" unless res
-        @sample_paths_cache[sym] = res
-        res
-      end
-
-      def resolve_sample_symbol_path(sym)
-        aliases = Thread.current.thread_variable_get(:sonic_pi_mod_sound_sample_aliases)
-        path = Thread.current.thread_variable_get(:sonic_pi_mod_sound_sample_path)
-
-        return fetch_or_cache_sample_path(sym) unless (aliases || path)
-
-        if (aliases &&
-            (m       = sym.to_s.match /\A(.+?)__(.+)/) &&
-            (p       = aliases[m[1]]))
-          path = p
-          sym = m[2]
-          partial = "#{p}#{sym}"
-        elsif path
-          partial = path + sym.to_s
-        else
-          path = samples_path
-          partial = path + "/" + sym.to_s
-        end
-
-        res = find_sample_with_path(partial)
-
-        raise "No sample exists called #{sym.inspect} in sample pack #{path.inspect} (#{File.expand_path(path)})" unless res
-
-        res
-      end
 
       def complex_sampler_args?(args_h)
         # break out early if any of the 'complex' keys exist in the
@@ -3737,79 +4092,75 @@ If you wish your synth to work with Sonic Pi's automatic stereo sound infrastruc
       end
 
 
-      def trigger_sampler(path, buf_id, num_chans, args_h, group=current_job_synth_group)
+      def resolve_specific_sampler(num_chans, args_h)
         if complex_sampler_args?(args_h)
           #complex
-          synth_name = (num_chans == 1) ? :mono_player : :stereo_player
+          (num_chans == 1) ? :mono_player : :stereo_player
         else
           #basic
-          synth_name = (num_chans == 1) ? :basic_mono_player : :basic_stereo_player
+          (num_chans == 1) ? :basic_mono_player : :basic_stereo_player
         end
-
-        trigger_specific_sampler(synth_name, path, buf_id, num_chans, args_h, group)
       end
 
-      def trigger_specific_sampler(sampler_type, path, buf_id, num_chans, args_h, group=current_job_synth_group)
+      def trigger_sampler(path, args_h, group=current_job_synth_group)
+        case path
+        when Buffer
+          buf_info = path
+          if buf_info.path
+            path = buf_info.path
+          else
+            path = path[0]
+          end
+        else
+          buf_info = load_sample_at_path(path)
+        end
+        sn = resolve_specific_sampler(buf_info.num_chans, args_h)
 
-        sn = sampler_type.to_sym
         info = Synths::SynthInfo.get_info(sn)
-        path = unify_tilde_dir(path) if path.is_a? String
-
-        # Combine thread local defaults here as
-        # normalise_and_resolve_synth_args has only been taught about
-        # synth thread local defaults
-        t_l_args = Thread.current.thread_variable_get(:sonic_pi_mod_sound_sample_defaults) || {}
-        t_l_args.each do |k, v|
-            args_h[k] = v unless args_h.has_key? k
-        end
+        args_h = normalise_and_resolve_sample_args(path, args_h, info)
 
-        stretch_duration = args_h[:beat_stretch]
-        if stretch_duration
-          raise "beat_stretch: opt needs to be a positive number. Got: #{stretch_duration.inspect}" unless stretch_duration.is_a?(Numeric) && stretch_duration > 0
-          stretch_duration = stretch_duration.to_f
-          rate = args_h[:rate] || 1
-          dur = load_sample(path).duration
-          args_h[:rate] = (1.0 / stretch_duration) * rate * (current_bpm / (60.0 / dur))
-        end
+        buf_id = buf_info.id
 
-        pitch_stretch_duration = args_h[:pitch_stretch]
-        if pitch_stretch_duration
-          raise "pitch_stretch: opt needs to be a positive number. Got: #{pitch_stretch_duration.inspect}" unless pitch_stretch_duration.is_a?(Numeric) && pitch_stretch_duration > 0
-          pitch_stretch_duration = pitch_stretch_duration.to_f
-          rate = args_h[:rate] || 1
-          dur = load_sample(path).duration
-          new_rate = (1.0 / pitch_stretch_duration) * (current_bpm / (60.0 / dur))
-          pitch_shift = ratio_to_pitch(new_rate)
-          args_h[:rate] = new_rate * rate
-          args_h[:pitch] = args_h[:pitch].to_f - pitch_shift
-        end
-
-        rate_pitch = args_h[:rpitch]
-        if rate_pitch
-          new_rate = pitch_to_ratio(rate_pitch.to_f)
-          args_h[:rate] = new_rate * (args_h[:rate] || 1)
+        if Thread.current.thread_variable_get(:sonic_pi_mod_sound_timing_guarantees)
+          unless in_good_time?
+            if args_h.empty?
+              __delayed_message "!! Out of time, skipping: sample #{path.inspect}"
+            else
+              __delayed_message "!! Out of time, skipping: sample #{path.inspect}, #{arg_h_pp(args_h)}"
+            end
+            return @blank_node
+          end
         end
 
-        args_h = normalise_and_resolve_synth_args(args_h, info)
-
 
         unless Thread.current.thread_variable_get(:sonic_pi_mod_sound_synth_silent)
           if args_h.empty?
-            __delayed_message "sample #{path.inspect}"
+            __delayed_message "sample #{File.dirname(path).inspect},\n           #{File.basename(path).inspect}"
           else
-            __delayed_message "sample #{path.inspect}, #{arg_h_pp(args_h)}"
+            __delayed_message "sample #{File.dirname(path).inspect},\n           #{File.basename(path).inspect}, #{arg_h_pp(args_h)}"
+
           end
         end
         add_arg_slide_times!(args_h, info)
         args_h[:buf] = buf_id
-        trigger_synth(sn, args_h, group, info)
+        return trigger_synth(sn, args_h, group, info)
       end
 
+
       def trigger_inst(synth_name, args_h, group=current_job_synth_group)
         sn = synth_name.to_sym
         info = Synths::SynthInfo.get_info(sn)
+        raise "Unknown synth #{sn.inspect}" unless info || Thread.current.thread_variable_get(:sonic_pi_mod_sound_use_external_synths)
+        processed_args = normalise_and_resolve_synth_args(args_h, info, true)
+
+        if Thread.current.thread_variable_get(:sonic_pi_mod_sound_timing_guarantees)
+          unless in_good_time?
+            __delayed_message "!! Out of time, skipping: synth #{synth_name.inspect}, #{arg_h_pp(processed_args)}"
+
+            return @blank_node
+          end
+        end
 
-        processed_args = normalise_and_resolve_synth_args(args_h, info, nil, true)
 
         unless Thread.current.thread_variable_get(:sonic_pi_mod_sound_synth_silent)
           __delayed_message "synth #{synth_name.inspect}, #{arg_h_pp(processed_args)}"
@@ -3823,11 +4174,18 @@ If you wish your synth to work with Sonic Pi's automatic stereo sound infrastruc
         sn = synth_name.to_sym
         info = Synths::SynthInfo.get_info(sn)
         args_h = resolve_synth_opts_hash_or_array(args_a_or_h)
-        args_h = normalise_and_resolve_synth_args(args_h, info, nil, true)
+        args_h = normalise_and_resolve_synth_args(args_h, info, true)
 
         chord_group = @mod_sound_studio.new_group(:tail, group, "CHORD")
         cg = ChordGroup.new(chord_group, notes, info)
 
+        if Thread.current.thread_variable_get(:sonic_pi_mod_sound_timing_guarantees)
+          unless in_good_time?
+            __delayed_message "!! Out of time, skipping: synth #{sn.inspect}, #{arg_h_pp({note: notes}.merge(args_h))}"
+            return @blank_node
+          end
+        end
+
         unless Thread.current.thread_variable_get(:sonic_pi_mod_sound_synth_silent)
           __delayed_message "synth #{sn.inspect}, #{arg_h_pp({note: notes}.merge(args_h))}"
        end
@@ -3849,8 +4207,7 @@ If you wish your synth to work with Sonic Pi's automatic stereo sound infrastruc
       end
 
       def trigger_fx(synth_name, args_h, info, in_bus, group=current_fx_group, now=false, t_minus_delta=false)
-
-        args_h = normalise_and_resolve_synth_args(args_h, info, nil, true)
+        args_h = normalise_and_resolve_synth_args(args_h, info, false)
         add_arg_slide_times!(args_h, info)
         out_bus = current_out_bus
         n = trigger_synth(synth_name, args_h, group, info, now, out_bus, t_minus_delta)
@@ -3859,10 +4216,18 @@ If you wish your synth to work with Sonic Pi's automatic stereo sound infrastruc
 
       # Function that actually triggers synths now that all args are resolved
       def trigger_synth(synth_name, args_h, group, info, now=false, out_bus=nil, t_minus_delta=false)
+
+
+
         add_out_bus_and_rand_buf!(args_h, out_bus)
         orig_synth_name = synth_name
+
         synth_name = info ? info.scsynth_name : synth_name
+
         validate_if_necessary! info, args_h
+
+        ensure_good_timing!
+
         job_id = current_job_id
         __no_kill_block do
 
@@ -3896,15 +4261,62 @@ If you wish your synth to work with Sonic Pi's automatic stereo sound infrastruc
       end
 
 
-      def normalise_and_resolve_synth_args(args_h, info, out_bus=nil, combine_tls=false)
+      def normalise_and_resolve_sample_args(path, args_h, info, combine_tls=false)
+        purge_nil_vals!(args_h)
+
+        defaults = info ? info.arg_defaults : {}
+        t_l_args = Thread.current.thread_variable_get(:sonic_pi_mod_sound_sample_defaults) || {}
+        t_l_args.each do |k, v|
+          args_h[k] = v unless args_h.has_key? k || v.nil?
+        end
+
+        stretch_duration = args_h[:beat_stretch]
+        if stretch_duration
+          raise "beat_stretch: opt needs to be a positive number. Got: #{stretch_duration.inspect}" unless stretch_duration.is_a?(Numeric) && stretch_duration > 0
+          stretch_duration = stretch_duration.to_f
+          rate = args_h[:rate] || 1
+          dur = sample_buffer(path).duration
+          args_h[:rate] = (1.0 / stretch_duration) * rate * (current_bpm / (60.0 / dur))
+        end
+
+        pitch_stretch_duration = args_h[:pitch_stretch]
+        if pitch_stretch_duration
+          raise "pitch_stretch: opt needs to be a positive number. Got: #{pitch_stretch_duration.inspect}" unless pitch_stretch_duration.is_a?(Numeric) && pitch_stretch_duration > 0
+          pitch_stretch_duration = pitch_stretch_duration.to_f
+          rate = args_h[:rate] || 1
+          dur = sample_buffer(path).duration
+          new_rate = (1.0 / pitch_stretch_duration) * (current_bpm / (60.0 / dur))
+          pitch_shift = ratio_to_pitch(new_rate)
+          args_h[:rate] = new_rate * rate
+          args_h[:pitch] = args_h[:pitch].to_f - pitch_shift
+        end
+
+        rate_pitch = args_h[:rpitch]
+        if rate_pitch
+          new_rate = pitch_to_ratio(rate_pitch.to_f)
+          args_h[:rate] = new_rate * (args_h[:rate] || 1)
+        end
+
+        args_h = info.munge_opts(args_h) if info
+        resolve_midi_args!(args_h, info) if info
+        normalise_args!(args_h, defaults)
+        scale_time_args_to_bpm!(args_h, info, true) if info && Thread.current.thread_variable_get(:sonic_pi_spider_arg_bpm_scaling)
+        args_h
+      end
+
+
+      def normalise_and_resolve_synth_args(args_h, info, combine_tls=false)
+        purge_nil_vals!(args_h)
         defaults = info ? info.arg_defaults : {}
         if combine_tls
           t_l_args = Thread.current.thread_variable_get(:sonic_pi_mod_sound_synth_defaults) || {}
           t_l_args.each do |k, v|
-            args_h[k] = v unless args_h.has_key? k
+            args_h[k] = v unless args_h.has_key? k || v.nil?
           end
         end
 
+        args_h = info.munge_opts(args_h) if info
+
         resolve_midi_args!(args_h, info) if info
         normalise_args!(args_h, defaults)
         scale_time_args_to_bpm!(args_h, info, true) if info && Thread.current.thread_variable_get(:sonic_pi_spider_arg_bpm_scaling)
@@ -4154,10 +4566,29 @@ If you wish your synth to work with Sonic Pi's automatic stereo sound infrastruc
 
       def ensure_good_timing!
         return true if Thread.current.thread_variable_get(:sonic_pi_mod_sound_disable_timing_warnings)
+        raise "Timing Exception: thread got too far behind time." if time_diff > 1.1
+      end
 
+      def time_diff
+        # negative values mean we're ahead of time
+        # positive values mean we're behind time
         vt  = Thread.current.thread_variable_get :sonic_pi_spider_time
-        sat = @mod_sound_studio.sched_ahead_time + 1.1
-        raise "Timing Exception: thread got too far behind time." if (Time.now - sat) > vt
+        sat = @mod_sound_studio.sched_ahead_time
+        compensated = (Time.now - sat)
+        compensated - vt
+      end
+
+      def in_good_time?(error_window=0)
+        diff = time_diff
+        if diff < error_window
+          return true
+        else
+          if diff < 1.1
+            return false
+          else
+            raise "Timing Exception: thread got too far behind time."
+          end
+        end
       end
 
       def current_synth_name
@@ -4169,47 +4600,6 @@ If you wish your synth to work with Sonic Pi's automatic stereo sound infrastruc
         Thread.current.thread_variable_set(:sonic_pi_mod_sound_current_synth_name, name)
       end
 
-      def __freesound_path(id)
-        cache_dir = home_dir + '/freesound/'
-        ensure_dir(cache_dir)
-
-        cache_file = cache_dir + "freesound-" + id.to_s + ".wav"
-
-        return cache_file if File.exists?(cache_file)
-
-        __info "Caching freesound #{id}..."
-
-        in_thread(name: "download_freesound_#{id}".to_sym) do
-          # API key borrowed from Overtone
-          apiURL = 'http://www.freesound.org/api/sounds/' + id.to_s + '/serve/?api_key=47efd585321048819a2328721507ee23'
-
-          resp = Net::HTTP.get_response(URI(apiURL))
-          case resp
-          when Net::HTTPSuccess then
-            if not resp['Content-Disposition'] =~ /\.wav\"$/ then
-              raise 'Only WAV freesounds are supported, sorry!'
-            end
-
-            open(cache_file, 'wb') do |file|
-              file.write(resp.body)
-            end
-            __info "Freesound #{id} loaded and ready to fire!"
-          else
-            __info "Failed to download freesound #{id}: " + resp.value
-          end
-        end
-        return nil
-      end
-      #        doc name:          :freesound_path,
-      #            introduced:    Version.new(2,1,0),
-      #            summary:       "Return local path for sound from freesound.org",
-      #            doc:           "Download and cache a sample by ID from freesound.org. Returns path as string if cached. If not cached, returns nil and starts a background thread to download the sample.",
-      #            args:          [[:id, :number]],
-      #            opts:          nil,
-      #            accepts_block: false,
-      #            examples:      ["
-      # puts freesound(250129)    # preloads a freesound and prints its local path, such as '/home/user/.sonic_pi/freesound/250129.wav'"]
-
       def scale_time_args_to_bpm!(args_h, info, force_add = true)
         # some of the args in args_h need to be scaled to match the
         # current bpm. Check in info to see if that's necessary and if
@@ -4285,46 +4675,20 @@ If you wish your synth to work with Sonic Pi's automatic stereo sound infrastruc
           n += (cent_shift / 100.0)
         end
 
+        if @mod_sound_studio
+          n += (@mod_sound_studio.cent_tuning / 100.0)
+        end
+
         n += args_h[:pitch].to_f
 
         n = normalise_tuning(n)
         return n
       end
 
-
-      def __freesound(id, *opts)
-        path = __freesound_path(id)
-        arg_h = resolve_synth_opts_hash_or_array(opts)
-        fallback = arg_h[:fallback]
-
-        if path
-          sample path
-        elsif fallback
-          raise "Freesound fallback must be a symbol" unless fallback.is_a? Symbol
-          __info "Freesound #{id} not yet loaded, playing #{fallback}"
-          sample fallback
-        else
-          __info "Freesound #{id} not yet loaded, skipping"
-        end
-
+      def sample_find_candidates(*args)
+        @sample_loader.find_candidates(*args)
       end
-      #        doc name:          :freesound,
-      #            introduced:    Version.new(2,1,0),
-      #            summary:       "Play sample from freesound.org",
-      #            doc:           "Fetch from cache (or download then cache) a sample by ID from freesound.org, and then play it.",
-      #            args:          [[:id, :number]],
-      #            opts:          {:fallback => "Symbol representing built-in sample to play if the freesound id isn't yet downloaded"},
-      #            accepts_block: false,
-      #            examples:      ["
-      # freesound(250129)  # takes time to download the first time, but then the sample is cached locally
-      # ",
-      # "
-      # loop do
-      #   sample freesound(27130)
-      #   sleep sample_duration(27130)
-      # end
-      # "
-      # ]
     end
+
   end
 end
diff --git a/app/server/sonicpi/lib/sonicpi/lang/support/docsystem.rb b/app/server/sonicpi/lib/sonicpi/lang/support/docsystem.rb
index 2dd5050..0f5cb83 100644
--- a/app/server/sonicpi/lib/sonicpi/lang/support/docsystem.rb
+++ b/app/server/sonicpi/lib/sonicpi/lang/support/docsystem.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/lazybuffer.rb b/app/server/sonicpi/lib/sonicpi/lazybuffer.rb
new file mode 100644
index 0000000..76779d4
--- /dev/null
+++ b/app/server/sonicpi/lib/sonicpi/lazybuffer.rb
@@ -0,0 +1,73 @@
+#--
+# This file is part of Sonic Pi: http://sonic-pi.net
+# Full project source: https://github.com/samaaron/sonic-pi
+# License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+#
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+# All rights reserved.
+#
+# Permission is granted for use, copying, modification, and
+# distribution of modified versions of this work as long as this
+# notice is included.
+#++
+
+require_relative "buffer"
+module SonicPi
+  class LazyBuffer < Buffer
+    def initialize(server, id, prom)
+      @server = server
+      @id = id
+      @prom = prom
+      @realised = false
+      @prom_mut = Mutex.new
+    end
+
+    def num_frames
+      wait_for_prom unless @realised
+      @num_frames
+    end
+
+    def num_chans
+      wait_for_prom unless @realised
+      @num_chans
+    end
+
+    def sample_rate
+      wait_for_prom unless @realised
+      @sample_rate
+    end
+
+    def duration
+      wait_for_prom unless @realised
+      @duration
+    end
+
+    def to_s
+      wait_for_prom unless @realised
+      if @path
+        "#<Buffer @id=#{@id}, @num_chans=#{@num_chans}, @num_frames=#{@num_frames}, @sample_rate=#{@sample_rate}, @duration=#{@duration}, @path=#{@path}>"
+      else
+        "#<Buffer @id=#{@id}, @num_chans=#{@num_chans.inspect}, @num_frames=#{@num_frames}, @sample_rate=#{@sample_rate}, @duration=#{@duration}>"
+      end
+    end
+
+
+    private
+
+    def wait_for_prom
+      return true if @realised
+      @prom_mut.synchronize do
+        return true if @realised
+        num_frames, num_chans, sample_rate = @prom.get
+        @num_frames = num_frames
+        @num_chans = num_chans
+        @sample_rate = sample_rate
+        @duration = num_frames.to_f / sample_rate.to_f
+        @state = :live
+        @mutex = Mutex.new
+        @path = nil
+        @realised = true
+      end
+    end
+  end
+end
diff --git a/app/server/sonicpi/lib/sonicpi/lazynode.rb b/app/server/sonicpi/lib/sonicpi/lazynode.rb
new file mode 100644
index 0000000..c89baf3
--- /dev/null
+++ b/app/server/sonicpi/lib/sonicpi/lazynode.rb
@@ -0,0 +1,150 @@
+#--
+# This file is part of Sonic Pi: http://sonic-pi.net
+# Full project source: https://github.com/samaaron/sonic-pi
+# License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+#
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+# All rights reserved.
+#
+# Permission is granted for use, copying, modification, and
+# distribution of modified versions of this work as long as this
+# notice is included.
+#++
+require_relative "synthnode"
+
+module SonicPi
+  class LazyNode < SynthNode
+
+    def initialize(prom)
+      @realised = false
+      @prom_mut = Mutex.new
+      @node = nil
+      @prom = prom
+    end
+
+    def args
+      wait_for_prom unless @realised
+      @node.args
+    end
+
+    def name
+      wait_for_prom unless @realised
+      @node.name
+    end
+
+    def on_destroyed(&block)
+      wait_for_prom unless @realised
+      @node.on_destroyed(&block)
+    end
+
+    def on_started(&block)
+      wait_for_prom unless @realised
+      @node.on_started(&block)
+    end
+
+    def kill(now=false)
+      wait_for_prom unless @realised
+      @node.kill(now)
+    end
+
+    def pause(now=false)
+      wait_for_prom unless @realised
+      @node.pause(now)
+    end
+
+    def run(now=false)
+      wait_for_prom unless @realised
+      @node.run(now)
+    end
+
+    def ctl(*args)
+      wait_for_prom unless @realised
+      @node.ctl(*args)
+    end
+
+    def control(*args)
+      wait_for_prom unless @realised
+      @node.ctl(*args)
+    end
+
+    def ctl_now(*args)
+      wait_for_prom unless @realised
+      @node.ctl_now(*args)
+    end
+
+    def live?
+      wait_for_prom unless @realised
+      @node.live?
+    end
+
+    def destroyed?
+      wait_for_prom unless @realised
+      @node.destroyed?
+    end
+
+    def paused?
+      wait_for_prom unless @realised
+      @node.paused?
+    end
+
+    def running?
+      wait_for_prom unless @realised
+      @node.running?
+    end
+
+    def state
+      wait_for_prom unless @realised
+      @node.state
+    end
+
+    def name
+      wait_for_prom unless @realised
+      @node.name
+    end
+
+    def to_i
+      wait_for_prom unless @realised
+      @node.to_i
+    end
+
+    def to_f
+      wait_for_prom unless @realised
+      @node.to_f
+    end
+
+    def to_s
+      wait_for_prom unless @realised
+      "#<SonicPi::LazySynthNode @id=#{@node.id}>"
+    end
+
+    def id
+      wait_for_prom unless @realised
+      @node.id
+    end
+
+    def inspect
+      wait_for_prom unless @realised
+      to_s
+    end
+
+    def blank_node?
+      false
+    end
+
+    def info
+      wait_for_prom unless @realised
+      @node.info
+    end
+
+
+    private
+
+    def wait_for_prom
+      return true if @realised
+      @prom_mut.synchronize do
+        return true if @realised
+        @node = @prom.get
+      end
+    end
+  end
+end
diff --git a/app/server/sonicpi/lib/sonicpi/lifecyclehooks.rb b/app/server/sonicpi/lib/sonicpi/lifecyclehooks.rb
index db7badc..6167d61 100644
--- a/app/server/sonicpi/lib/sonicpi/lifecyclehooks.rb
+++ b/app/server/sonicpi/lib/sonicpi/lifecyclehooks.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/node.rb b/app/server/sonicpi/lib/sonicpi/node.rb
index 257d836..e7e1be9 100644
--- a/app/server/sonicpi/lib/sonicpi/node.rb
+++ b/app/server/sonicpi/lib/sonicpi/node.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/nodeproxy.rb b/app/server/sonicpi/lib/sonicpi/nodeproxy.rb
index 9139f64..c4d9d0f 100644
--- a/app/server/sonicpi/lib/sonicpi/nodeproxy.rb
+++ b/app/server/sonicpi/lib/sonicpi/nodeproxy.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/note.rb b/app/server/sonicpi/lib/sonicpi/note.rb
index d9d0bd7..795f27c 100644
--- a/app/server/sonicpi/lib/sonicpi/note.rb
+++ b/app/server/sonicpi/lib/sonicpi/note.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/osc/osc.rb b/app/server/sonicpi/lib/sonicpi/osc/osc.rb
index be7a937..ba5ac09 100644
--- a/app/server/sonicpi/lib/sonicpi/osc/osc.rb
+++ b/app/server/sonicpi/lib/sonicpi/osc/osc.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/osc/oscdecode.rb b/app/server/sonicpi/lib/sonicpi/osc/oscdecode.rb
index e5b9e17..97db68b 100644
--- a/app/server/sonicpi/lib/sonicpi/osc/oscdecode.rb
+++ b/app/server/sonicpi/lib/sonicpi/osc/oscdecode.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/osc/oscencode.rb b/app/server/sonicpi/lib/sonicpi/osc/oscencode.rb
index 0f62a9c..c338665 100644
--- a/app/server/sonicpi/lib/sonicpi/osc/oscencode.rb
+++ b/app/server/sonicpi/lib/sonicpi/osc/oscencode.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -96,7 +96,7 @@ module SonicPi
 
             args_encoded << get_from_or_add_to_string_cache(arg)
           else
-            raise "Unknown arg type to encode: #{arg}"
+            raise "Unknown arg type to encode: #{arg.inspect}"
           end
         end
 
diff --git a/app/server/sonicpi/lib/sonicpi/osc/tcp_client.rb b/app/server/sonicpi/lib/sonicpi/osc/tcp_client.rb
index acfccaf..e7dd542 100644
--- a/app/server/sonicpi/lib/sonicpi/osc/tcp_client.rb
+++ b/app/server/sonicpi/lib/sonicpi/osc/tcp_client.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/osc/tcp_server.rb b/app/server/sonicpi/lib/sonicpi/osc/tcp_server.rb
index b675946..be29dfe 100644
--- a/app/server/sonicpi/lib/sonicpi/osc/tcp_server.rb
+++ b/app/server/sonicpi/lib/sonicpi/osc/tcp_server.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/osc/udp_client.rb b/app/server/sonicpi/lib/sonicpi/osc/udp_client.rb
index 3d165f4..37491d7 100644
--- a/app/server/sonicpi/lib/sonicpi/osc/udp_client.rb
+++ b/app/server/sonicpi/lib/sonicpi/osc/udp_client.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/osc/udp_server.rb b/app/server/sonicpi/lib/sonicpi/osc/udp_server.rb
index 50fb04f..181ef50 100644
--- a/app/server/sonicpi/lib/sonicpi/osc/udp_server.rb
+++ b/app/server/sonicpi/lib/sonicpi/osc/udp_server.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -15,7 +15,7 @@ require 'socket'
 module SonicPi
   module OSC
     class UDPServer
-      def initialize(port, opts={}, &proc)
+      def initialize(port, opts={}, &global_method)
         open = opts[:open]
         use_decoder_cache = opts[:use_decoder_cache]
         decoder_cache_size = opts[:decoder_cache_size] || 1000
@@ -30,7 +30,7 @@ module SonicPi
           @socket.bind('127.0.0.1', port )
         end
         @matchers = {}
-        @global_matcher = proc
+        @global_matcher = global_method
         @decoder = OscDecode.new(use_decoder_cache, decoder_cache_size)
         @encoder = OscEncode.new(use_encoder_cache, encoder_cache_size)
         @listener_thread = Thread.new {start_listener}
@@ -71,7 +71,18 @@ module SonicPi
 
       def start_listener
         loop do
-          osc_data, network = @socket.recvfrom( 16384 )
+          begin
+            osc_data, network = @socket.recvfrom( 16384 )
+          rescue Exception => e
+            STDERR.puts "\n==========="
+            STDERR.puts "Critical: UDP Server for address #{address} had issues receiving reading socket"
+            STDERR.puts e.message
+            STDERR.puts e.backtrace.inspect
+            STDERR.puts "===========\n"
+            Kernel.sleep 1
+            redo
+          end
+
           begin
             address, args = @decoder.decode_single_message(osc_data)
             if @global_matcher
diff --git a/app/server/sonicpi/lib/sonicpi/preparser.rb b/app/server/sonicpi/lib/sonicpi/preparser.rb
index a6a5dac..076e4db 100644
--- a/app/server/sonicpi/lib/sonicpi/preparser.rb
+++ b/app/server/sonicpi/lib/sonicpi/preparser.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -23,7 +23,7 @@ module SonicPi
     def self.preparse(rb)
       SonicPi::Lang::Core.vec_fns.each do |fn|
         fn = fn[:name].to_s
-        rb.gsub!(/\((\s*)#{fn}(\s)/, '\1' + fn + '(\2')
+        rb.gsub!(/\((\s*)#{fn}([, ]+)/) {|s| ' ' + $1 + fn + '(' + (' ' * ($2.size - 1))}
 
         rb.gsub!(/:([a-zA-Z0-9\!\?=_]+:[a-zA-Z0-9\!\?=_]+[a-zA-Z0-9\!\?=_]*)/){|s| "::SonicPi::SPSym.new(#{$1.split(':').map(&:to_sym)})"}
 
diff --git a/app/server/sonicpi/lib/sonicpi/promise.rb b/app/server/sonicpi/lib/sonicpi/promise.rb
index 3925e20..2cbc1f8 100644
--- a/app/server/sonicpi/lib/sonicpi/promise.rb
+++ b/app/server/sonicpi/lib/sonicpi/promise.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/rcv_dispatch.rb b/app/server/sonicpi/lib/sonicpi/rcv_dispatch.rb
index b7d7895..aad5b3f 100644
--- a/app/server/sonicpi/lib/sonicpi/rcv_dispatch.rb
+++ b/app/server/sonicpi/lib/sonicpi/rcv_dispatch.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/runtime.rb b/app/server/sonicpi/lib/sonicpi/runtime.rb
index 7a1d7dd..5ebabf1 100644
--- a/app/server/sonicpi/lib/sonicpi/runtime.rb
+++ b/app/server/sonicpi/lib/sonicpi/runtime.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -176,9 +176,7 @@ module SonicPi
     end
 
     def __print_version_outdated_info(v=@server_version)
-      __info "Your version of Sonic Pi is outdated"
-      __info "The latest is #{v}"
-      __info "Please consider updating..."
+      __info "--- IMPORTANT NOTICE ---\n\n   Your version of Sonic Pi is outdated\n   The latest is #{v}\n   Please consider updating:\n\n   http://sonic-pi.net\n\n", 1
     end
 
 
@@ -192,8 +190,8 @@ module SonicPi
       end
     end
 
-    def __info(s)
-      @msg_queue.push({:type => :info, :val => s.to_s})
+    def __info(s, style=0)
+      @msg_queue.push({:type => :info, :style => style, :val => s.to_s})
     end
 
     def __multi_message(m)
@@ -312,9 +310,15 @@ module SonicPi
       err_msg.gsub!(/for #<SonicPiSpiderUser[a-z0-9:]+>/, '')
       res = ""
       if line != -1
-        res = res + "[#{info[:workspace]}, line #{line}]"
+
+        # TODO: Remove this hack when we have projects
+        w = info[:workspace]
+        w = "buffer " + w[10..-1]
+        # TODO: end of hack
+
+        res = res + "[#{w}, line #{line}]"
       else
-        res = res + "[#{info[:workspace]}]"
+        res = res + "[#{w}]"
       end
       res = res + "\n" + m if m
       res = res + "\n #{err_msg}"
@@ -389,6 +393,8 @@ module SonicPi
       @user_jobs.each_id do |id|
         __stop_job id
       end
+      # Force a GC collection now everything has stopped
+      GC.start
     end
 
     def __stop_other_jobs
@@ -437,16 +443,24 @@ module SonicPi
       return nil
     end
 
-    def __complete_snippet_or_indent_lines(workspace_id, buf, start_line, finish_line, point_line, point_index)
+    def __indent_lines(buf)
+
+    end
+
+
+    def __buffer_indent_lines(workspace_id, buf, start_line, finish_line, point_line, point_index)
+      __buffer_complete_snippet_or_indent_lines(workspace_id, buf, start_line, finish_line, point_line, point_index, false)
+    end
+
+    def __complete_snippet_or_indent_lines(buf, start_line, finish_line, point_line, point_index, complete_snippet=true)
       orig_finish_line = finish_line
       snippet_completion = false
-      id = workspace_id.to_s
       buf = buf + "\n"
       buf_lines = buf.lines.to_a
       if (start_line == finish_line)
         completion_line = buf_lines[start_line].to_s.rstrip
 
-        c = __snippet_completion?(completion_line[0...point_index])
+        c = complete_snippet && __snippet_completion?(completion_line[0...point_index])
         if c
           snippet_completion = true
           completion_key, val = *c
@@ -489,13 +503,17 @@ module SonicPi
         # Calculate amount of whitespace at start of original line
         orig_point_line = buf_lines[point_line]
         orig_point_line_ws_len = orig_point_line[/\A */].size
-
-        if buf_lines[point_line] =~ /^\s*$/
-          #line is just whitespace, put in a dummy line so it gets autoindented
-          buf_lines[point_line] = "#dummy\n"
-          dummy_line = true
-        else
-          dummy_line = false
+        dummy_lines = false
+        dummy_point_line = false
+
+        (start_line..finish_line).each do |line_idx|
+          b = buf_lines[line_idx]
+          if b.match(/\A\s*\Z/)
+            #line is just whitespace, put in a dummy line so it gets autoindented
+            buf_lines[line_idx] = "#___sonic_pi_dummy_line___\n"
+            dummy_lines = true
+            dummy_point_line = true if point_line == line_idx
+          end
         end
       else
         manipulate_point = false
@@ -508,7 +526,7 @@ module SonicPi
       # calculate amount of whitespace at start of beautified line
       beautiful_lines = beautiful.lines.to_a
       if manipulate_point
-        if dummy_line
+        if dummy_point_line
           # remove dummy line and extract leading whitespace
           indented_dummy = beautiful_lines[point_line]
           indented_dummy_whitespace = indented_dummy.match(/\A(\s*)/)[1]
@@ -525,13 +543,47 @@ module SonicPi
           point_index = new_point_line.size - 1 if point_index > new_point_line.size
           point_index = orig_point_line_ws_len if point_index < orig_point_line_ws_len
         end
+
+        if dummy_lines
+          # remove other dummy lines
+          (start_line..finish_line).each do |line_idx|
+            line = beautiful_lines[line_idx]
+            m = line.match(/\A(\s*)#___sonic_pi_dummy_line___/)
+            beautiful_lines[line_idx] = m[1] + "\n" if m
+          end
+        end
       end
       indented_lines = beautiful_lines[start_line..finish_line].join
       finish_line = orig_finish_line if snippet_completion
-      @msg_queue.push({type: "replace-lines", buffer_id: id, val: indented_lines, start_line: start_line, finish_line: finish_line, point_line: point_line, point_index: point_index})
 
+      return {val: indented_lines, start_line: start_line, finish_line: finish_line, point_line: point_line, point_index: point_index}
+    end
+
+    def __buffer_complete_snippet_or_indent_lines(workspace_id, buf, start_line, finish_line, point_line, point_index, complete_snippet=true)
+      id = workspace_id.to_s
+      res = __complete_snippet_or_indent_lines(buf, start_line, finish_line, point_line, point_index, true)
+      @msg_queue.push(res.merge({type: "replace-lines", buffer_id: id}))
+    end
+
+    def __buffer_newline_and_indent(workspace_id, buf, point_line, point_index, first_line)
+        id = workspace_id.to_s
+      lines =  buf.lines.to_a
+      if lines == []
+        lines = ["\n"]
+      else
+        if lines[point_line]
+          lines[point_line].insert(point_index , "\n")
+        else
+          lines[point_line] = "\n"
+        end
+      end
+
+      buf = lines.join
+
+      __buffer_beautify(id, buf, point_line + 1, 0, first_line)
     end
 
+
     def __toggle_comment(workspace_id, buf, start_line, finish_line, point_line, point_index)
       id = workspace_id.to_s
       indented_linex = ""
@@ -542,17 +594,16 @@ module SonicPi
       # Otherwise comment
       lines = buf_lines[start_line..finish_line]
 
-      if(lines.all?{|el| el.match(/^\s*#.*/) || el.match(/^\s*$/)})
-        # need to uncomment
+      if(lines.all?{|el| el.match(/^\s*#.*?/) || el.match(/^\s*$/)})
+        # need to uncomment ##| style comments
         lines = lines.map do |l|
-          m = l.match(/^(\s*)#+[ ]?(.*)/)
+          m = l.match(/^(\s*)#[#\| ]*(.*)/)
           if m
             m[1] + m[2] + "\n"
           else
             l
           end
         end
-
       else
         # need to comment
         # find shortest amount of whitespace at beginning of line
@@ -563,18 +614,26 @@ module SonicPi
         end
 
         lines.each do |l|
-          l[ws] = "# #{l[ws]}" unless l.match(/^(\s*)$/)
+          l[ws] = "##| #{l[ws]}" unless l.match(/^(\s*)$/)
         end
       end
 
       @msg_queue.push({type: "replace-lines", buffer_id: id, val: lines.join, start_line: start_line, finish_line: finish_line, point_line: point_line, point_index: point_index})
     end
 
-    def __beautify_buffer(id, buf, line, index, first_line)
+    def __buffer_beautify(id, buf, line, index, first_line)
       id = id.to_s
       buf = buf + "\n"
       buf_lines = buf.lines.to_a
-
+      buf = buf_lines.inspect
+      buf_lines = buf_lines.map! do |l|
+        if l.match /^\s*$/
+          "_____sonic_pi_tmp_insert_____\n"
+        else
+          l
+        end
+      end
+      buf = buf_lines.join
       ## ensure point isn't beyond buffer
       max_buf_idx = buf_lines.size - 1
       line  = max_buf_idx if line > max_buf_idx
@@ -591,8 +650,11 @@ module SonicPi
       # calculate amount of whitespace at start of beautified line
       beautiful_lines = beautiful.lines.to_a
       beautiful_len = beautiful_lines.size
+      beautiful_lines.map! {|l| l.slice! "_____sonic_pi_tmp_insert_____" ; l}
+
       post_line = beautiful_lines[line]
       post_ws_len = post_line[/\A */].size
+      beautiful = beautiful_lines.join
 
       # shift index based on how much the line was indented so the
       # cursor stays in the same place relative to the original line
@@ -600,25 +662,12 @@ module SonicPi
       index = index + (post_ws_len - prev_ws_len)
       index = post_line.size - 1 if index > post_line.size
 
-      # Strip whitespace at the beginning of the buffer
-      beautiful.lstrip!
-
       # adjust line number based on how many lines were removed as a
       # result of the whitespace stripping
       post_lstrip_len = beautiful.lines.to_a.size
       line = line - (beautiful_len - post_lstrip_len)
       line = 0 if line < 0
-
-      # Strip whitespace from the end of the buffer
-      beautiful.rstrip!
-      post_rstrip_len = beautiful.lines.to_a.size
-
-      # move point to end of buffer if whitespace stripping at end of
-      # buffer put point out of bounds
-      if line >= post_rstrip_len
-        line = post_rstrip_len
-        index = beautiful.lines.to_a.last.size
-      end
+      beautiful.chomp!
       @msg_queue.push({type: "replace-buffer", buffer_id: id, val: beautiful, line: line, index: index, first_line: first_line})
     end
 
@@ -651,7 +700,7 @@ module SonicPi
 
       # skip __nosave lines for error reporting
       firstline = 1
-      firstline -= code.split(/\r?\n/).count{|l| l.include? "#__nosave__"}
+      firstline -= code.lines.to_a.take_while{|l| l.include? "#__nosave__"}.count
       start_t_prom = Promise.new
       info[:workspace] = 'eval' unless info[:workspace]
       job = Thread.new do
@@ -680,7 +729,12 @@ module SonicPi
           start_t_prom.deliver! now
           Thread.current.thread_variable_set :sonic_pi_spider_time, now
           Thread.current.thread_variable_set :sonic_pi_spider_start_time, now
-          @global_start_time = now if num_running_jobs == 1
+          Thread.current.thread_variable_set :sonic_pi_spider_beat, 0
+          if num_running_jobs == 1
+            @global_start_time = now
+            # Force a GC collection before we start making music!
+            GC.start
+          end
           __info "Starting run #{id}"
           code = PreParser.preparse(code)
 
@@ -696,8 +750,14 @@ module SonicPi
             error_line = ""
             if line
               line = line.to_i
-              err_msg = "[#{info[:workspace]}, line #{line}] \n #{message}"
-              error_line = code.lines.to_a[line + 1] ||  ""
+
+              # TODO: Remove this hack when we have projects
+              w = info[:workspace]
+              w = "buffer " + w[10..-1]
+              # TODO: end of hack
+
+              err_msg = "[#{w}, line #{line}] \n #{message}"
+              error_line = code.lines.to_a[line] ||  ""
             else
               line = -1
               err_msg = "\n #{e.message}"
@@ -736,11 +796,12 @@ module SonicPi
     end
 
     def __exit
+      log "Runtime - shutting down..."
+      @event_t.kill
+      log "Runtime - stopping all jobs..."
       __stop_jobs
       @msg_queue.push({:type => :exit, :jobid => __current_job_id, :jobinfo => __current_job_info})
-      @event_t.kill
-
-
+      log "Runtime - shutdown completed."
     end
 
     def __describe_threads
@@ -849,7 +910,7 @@ module SonicPi
     end
 
     def filter_for_save(s)
-      s.split(/\r?\n/).reject{|l| l.include? "#__nosave__"}.join("\n")
+      s.lines.to_a.reject{|l| l.include? "#__nosave__"}.join
     end
 
     def sthread(name)
@@ -875,8 +936,7 @@ module SonicPi
       @git_hash = __extract_git_hash
       gh_short = @git_hash ? "-#{@git_hash[0, 5]}" : ""
       @settings = Config::Settings.new(user_settings_path)
-      # @version = Version.new(2, 9, 0, "dev#{gh_short}")
-      @version = Version.new(2, 9, 0)
+      @version = Version.new(2, 10, 0)
       @server_version = __server_version
       @life_hooks = LifeCycleHooks.new
       @msg_queue = msg_queue
@@ -898,7 +958,11 @@ module SonicPi
 
       @gui_heartbeats = {}
       @gui_last_heartbeat = nil
-      @gitsave = GitSave.new(project_path)
+      begin
+        @gitsave = GitSave.new(project_path)
+      rescue
+        @gitsave = nil
+      end
 
       @save_queue = SizedQueue.new(20)
 
@@ -922,19 +986,18 @@ module SonicPi
             File.open(path, 'w') {|f| f.write(content) }
             @gitsave.save!(filename, content, "#{@version} -- #{@session_id} -- ")
           rescue Exception => e
+            log "Exception saving buffer #{filename}:\n#{e.inspect}"
             ##TODO: remove this and ensure that git saving actually works
             ##instead of cowardly hiding the issue!
           end
         end
       end
-      __info "Welcome to Sonic Pi"
+      __info "Welcome to Sonic Pi", 1
       __info "Session #{@session_id[0..7]}"
       date = Time.now
       __info "#{date.strftime("%A")} #{date.day.ordinalize} #{date.strftime("%B, %Y")}"
       __info "%02d:%02d, %s" % [date.hour, date.min, date.zone]
 
-      __info "#{@version} Ready..."
-
       __info [
 "Hello, somewhere in the world
    the sun is shining
@@ -945,7 +1008,7 @@ module SonicPi
 "Turn your head towards the sun
    and the shadows
    will fall
-   behind you."].sample
+   behind you."].sample, 1
 
       msg = @settings.get(:message) || ""
       msg = msg.strip
@@ -954,7 +1017,17 @@ module SonicPi
 
       __info msg unless msg.empty?
 
+
       load_snippets(snippets_path, true)
+
+      if safe_mode?
+        __info "!!WARNING!! - file permissions issue:\n   Unable to write to folder #{home_dir} \n   Booting in SAFE MODE.\n   Buffer auto-saving is disabled, please save your work manually.", 1
+      end
+
+      log "Unable to initialise git repo at #{project_path}" unless @gitsave
+
+      __info "#{@version} Ready..."
+
     end
 
 
diff --git a/app/server/sonicpi/lib/sonicpi/sample_loader.rb b/app/server/sonicpi/lib/sonicpi/sample_loader.rb
new file mode 100644
index 0000000..3a37808
--- /dev/null
+++ b/app/server/sonicpi/lib/sonicpi/sample_loader.rb
@@ -0,0 +1,184 @@
+#--
+# This file is part of Sonic Pi: http://sonic-pi.net
+# Full project source: https://github.com/samaaron/sonic-pi
+# License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+#
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+# All rights reserved.
+#
+# Permission is granted for use, copying, modification, and
+# distribution of modified versions of this work as long as this
+# notice is included.
+#++
+
+module SonicPi
+  class SampleLoader
+    def initialize(samples_path)
+      @cached_candidates = {}
+      @cached_extracted_candidates = {}
+      @cached_extracted_candidates_mutex = Mutex.new
+      @cached_candidates_mutex = Mutex.new
+      @cached_folder_contents = {}
+      @mutex = Mutex.new
+      @folder_contents_mutex = Mutex.new
+
+      @samples_path = samples_path
+    end
+
+    def find_candidates(filts_and_sources)
+      return [] if filts_and_sources.empty?
+      filts_and_sources.flatten!
+
+      res = @cached_candidates[filts_and_sources]
+      return res if res
+
+      orig_candidates, filters_and_procs = split_candidates_and_filts(filts_and_sources)
+
+      candidates = extract_candidates(orig_candidates).dup
+      found_proc = false
+
+      if orig_candidates.empty?
+        default_samples_paths.each do |p|
+          if p.end_with?("**")
+            candidates.concat(ls_samples(p[0...-2], true))
+          else
+            candidates.concat(ls_samples(p))
+          end
+        end
+      end
+      filters_and_procs.each do |f|
+        case f
+        when String
+          candidates.keep_if do |v|
+            bn = File.basename(v, ".*")
+            bn.downcase.include?(f.downcase) || (File.basename(v) == f)
+          end
+        when Symbol
+          candidates.keep_if do |v|
+            bn = File.basename(v, ".*")
+            bn == f.to_s
+          end
+        when Regexp
+          candidates.keep_if do |v|
+            bn = File.basename(v, ".*")
+            bn.match f
+          end
+        when Fixnum
+          unless candidates.empty?
+            candidates = [candidates[f % candidates.size]]
+          end
+        when NilClass
+          # Do nothing
+        when Proc
+          raise "Sample Pack Proc needs to accept either 0 or 1 arguments. Found #{block.arity}" unless f.arity == 1
+          found_proc = true
+          candidates = f.call(candidates)
+          raise "Sample Pack Filter Proc needs to return an array or ring. Got #{candidates.class}: #{candidates.inspect}" unless candidates.is_a?(Array) || candidates.is_a?(SonicPi::Core::RingVector)
+        else
+          raise "Unknown sample filter type: #{f.class} - got: #{f.inspect}"
+        end
+      end
+
+      # don't cache contents if there's a proc as it may be stateful or
+      # random and therefore the same proc might exhibit different
+      # behaviour each time it is called.
+      unless found_proc
+        @mutex.synchronize do
+          @cached_candidates[filts_and_sources] = candidates.freeze
+        end
+        #end mutex
+      end
+
+      return candidates
+    end
+
+
+    def extract_candidates(candidates)
+      return [] if candidates.empty?
+      cached_all_candidates = @cached_extracted_candidates[candidates]
+      return cached_all_candidates if cached_all_candidates
+
+      @cached_extracted_candidates_mutex.synchronize do
+        cached_all_candidates = @cached_extracted_candidates[candidates]
+        return cached_all_candidates if cached_all_candidates
+
+        all_candidates = []
+
+        candidates.each do |c|
+          expanded = File.expand_path(c)
+          if expanded.end_with?("**") && File.directory?(expanded[0...-2])
+            all_candidates.concat(ls_samples(expanded[0...-2], true))
+          elsif File.directory?(expanded)
+            all_candidates.concat(ls_samples(expanded))
+          elsif File.exists?(expanded)
+            all_candidates << expanded
+          else
+            raise "Unknown sample candidate kind: #{expanded.inspect}. Not a file, directory or /** glob."
+          end
+          all_candidates_copy = all_candidates.clone
+          @cached_extracted_candidates[candidates] = all_candidates_copy.freeze
+        end
+
+        return all_candidates
+      end
+    end
+
+
+    def split_candidates_and_filts(filts_and_sources)
+      candidates = []
+      idx = 0
+      filts_and_sources.each_with_index do |el|
+        break unless el.is_a?(String)
+
+        p = File.expand_path(el)
+
+        if @cached_folder_contents[p] || File.exists?(p) || (p.end_with?("**") && File.directory?(p[0...-2]))
+          idx += 1
+          candidates << p
+        else
+          break
+        end
+      end
+
+      return candidates, filts_and_sources[idx..-1]
+    end
+
+    def ls_samples(path, recursive=false)
+      return [] unless File.directory?(path)
+      res = @cached_folder_contents[path]
+      return res if res
+
+      @folder_contents_mutex.synchronize do
+        res = @cached_folder_contents[path]
+        return res if res
+        if recursive
+          res = Dir.chdir(path) { Dir.glob("**/*.{wav,wave,aif,aiff,flac}").map {|path| File.expand_path(path) } }.sort
+        else
+          res = Dir.chdir(path) { Dir.glob("*.{wav,wave,aif,aiff,flac}").map {|path| File.expand_path(path) } }.sort
+        end
+        @cached_folder_contents[path] = res.freeze
+      end
+      res
+    end
+
+    def reset!
+      @cached_extracted_candidates_mutex.synchronize do
+        @cached_candidates_mutex.synchronize do
+          @mutex.synchronize do
+            @cached_extracted_candidates = {}
+            @cached_candidates = {}
+            @cached_folder_contents = {}
+          end
+        end
+      end
+    end
+
+    private
+
+    def default_samples_paths
+      path = Thread.current.thread_variable_get(:sonic_pi_mod_sound_sample_path) || @samples_path
+      path = [path] unless path.is_a?(Array) or path.is_a?(SonicPi::Core::SPVector)
+    end
+
+  end
+end
diff --git a/app/server/sonicpi/lib/sonicpi/scale.rb b/app/server/sonicpi/lib/sonicpi/scale.rb
index 7f689c9..caf8bd5 100644
--- a/app/server/sonicpi/lib/sonicpi/scale.rb
+++ b/app/server/sonicpi/lib/sonicpi/scale.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/scsynthexternal.rb b/app/server/sonicpi/lib/sonicpi/scsynthexternal.rb
index ea8a8ac..8c7b217 100644
--- a/app/server/sonicpi/lib/sonicpi/scsynthexternal.rb
+++ b/app/server/sonicpi/lib/sonicpi/scsynthexternal.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -67,7 +67,11 @@ module SonicPi
 
     def shutdown
       log "Sending /quit command to server"
-      @server.send(@hostname, @port, "/quit")
+      begin
+        @server.send(@hostname, @port, "/quit")
+      rescue Exception => e
+        log "Error during scsynth shutdown when attempting to send /quit OSC message to server #{@hostname} on port #{@port}"
+      end
       @server.stop
       t1, t2 = nil, nil
       if @jack_pid
@@ -113,20 +117,32 @@ module SonicPi
       log "going to kill #{pid}"
       return kill_pid_win(pid) if os == :windows
       pid = Integer(pid)
-      Process.kill(15, pid)
-
-      safe_wait.to_i.times do
-        sleep 1
-        begin
-          alive = Process.waitpid(pid, Process::WNOHANG)
-          return unless alive
-        rescue SystemCallError
-          # process is definitely dead!
-          return nil
+      begin
+        Process.kill(15, pid)
+        safe_wait.to_i.times do
+          begin
+            alive = Process.waitpid(pid, Process::WNOHANG)
+            unless alive
+              log "Successfully killed #{pid}"
+              return nil
+            end
+          rescue Exception => e
+            # process is definitely dead!
+            log "Error waiting for process #{pid} - assumed already killed"
+            return nil
+          end
+          sleep 1
         end
+
+        Process.kill(9, pid)
+        log "Forcibly killed #{pid}"
+      rescue Errno::ECHILD => e
+        log "Unable to wait for #{pid} - child process does not exist"
+      rescue Errno::ESRCH
+        log "Unable to kill #{pid} - process does not exist"
       end
 
-      Process.kill(9, pid)
+      return nil
     end
 
     def boot
@@ -183,17 +199,6 @@ module SonicPi
       log ""
     end
 
-    def osx_scsynth_path
-      potential_paths = [
-        "#{native_path}/scsynth",
-        "/Applications/SuperCollider/scsynth",
-        "/Applications/SuperCollider.app/Contents/Resources/scsynth",
-        "/Applications/SuperCollider/SuperCollider.app/Contents/Resources/scsynth"]
-      path = potential_paths.find {|path| File.exists? path }
-      raise "Unable to find SuperCollider. Is it installed? I looked here: #{potential_paths.inspect}" unless path
-      path
-    end
-
     def scsynth_path
       case os
       when :raspberry
@@ -201,26 +206,32 @@ module SonicPi
       when :linux
         "scsynth"
       when :osx
-        osx_scsynth_path
+        path = "#{native_path}/scsynth"
+        raise "Unable to find SuperCollider. Is it installed? I looked here: #{path.inspect}" unless File.exists?(path)
+        path
       when :windows
-        potential_paths = ["#{native_path}/scsynth.exe"]
-        path = potential_paths.find {|path| File.exists? path }
-        raise "Unable to find SuperCollider. Is it installed? I looked here: #{potential_paths.inspect}" unless path
+        path = "#{native_path}/scsynth.exe"
+        raise "Unable to find SuperCollider. Is it installed? I looked here: #{path.inspect}" unless File.exists?(path)
         path
       end
     end
 
     def boot_and_wait(*args)
+      log "Boot - Starting the SuperCollider server..."
       p = Promise.new
       p2 = Promise.new
 
       booted = false
       connected = false
-      FileUtils.rm scsynth_log_path if File.exists?(scsynth_log_path)
 
-      log "Boot - Starting the SuperCollider server..."
-      @scsynth_log_file = File.open(scsynth_log_path, 'w')
-      @scsynth_log_file.puts "# Starting SuperCollider #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}"
+      begin
+        FileUtils.rm scsynth_log_path if File.exists?(scsynth_log_path)
+        @scsynth_log_file = File.open(scsynth_log_path, 'w')
+      rescue
+        @scsynth_log_file = nil
+      end
+
+      @scsynth_log_file.puts "# Starting SuperCollider #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}" if @scsynth_log_file
       at_exit { @scsynth_log_file.close if @scsynth_log_file}
       scsynth_pipe = IO.popen(args)
       @scsynth_pid = scsynth_pipe.pid
@@ -243,7 +254,10 @@ module SonicPi
         t1.kill
         Process.kill(9, @scsynth_pid)
       end
-      raise "Unable to boot SuperCollider - boot server log does not report server ready" unless v
+      raise "Unable to boot SuperCollider - boot server log did not report server ready" unless v
+
+      log "Boot - SuperCollider booted successfully."
+      log "Boot - Connecting to the SuperCollider server..."
 
       boot_s = OSC::UDPServer.new(5998) do |a, b|
         log "Boot - Receiving ack from server on port 5998"
@@ -269,12 +283,14 @@ module SonicPi
       rescue Exception => e
         Process.kill(9, @scsynth_pid)
       ensure
-
         t2.kill
         boot_s.stop
       end
 
-      raise "Boot - Unable to connect to scsynth" unless connected
+      unless connected
+        log "Boot - Unable to connect to SuperCollider"
+        raise "Boot - Unable to connect to SuperCollider"
+      end
 
       log "Boot - Server connection established"
     end
@@ -303,7 +319,7 @@ module SonicPi
           audio_out_rate = CoreAudio.default_output_device.nominal_rate
           log "Boot - Input audio rate now: #{audio_in_rate}"
           log "Boot - Output audio rate now: #{audio_out_rate}"
-          if audio_in.nominal_rate != audio_out.nominal_rate
+          if (audio_in_rate != :unknown_in_rate) && (audio_out_rate != :unknown_out_rate) && (audio_in_rate != audio_out_rate)
             log "Boot - Sample rates do not match, exiting"
             raise
           end
@@ -339,7 +355,7 @@ module SonicPi
       sys("jackd -R -p 32 -d alsa -d hw:#{audio_card} -n 3 -p 2048 -r 44100& ")
 
       # Wait for Jackd to start
-      while `jack_wait -c`.match /not.*/
+      while `jack_wait -c`.match /^not running$/
         sleep 0.25
       end
 
@@ -359,7 +375,7 @@ module SonicPi
       log_boot_msg
       log "Booting on Linux"
       #Start Jack if not already running
-      if `jack_wait -c`.match /not.*/
+      if `jack_wait -c`.match /^not running$/
         #Jack not running - start a new instance
         log "Jackd not running on system. Starting..."
         sys("jackd -R -T -p 32 -d alsa -n 3 -p 2048 -r 44100& ")
diff --git a/app/server/sonicpi/lib/sonicpi/scsynthnative.rb b/app/server/sonicpi/lib/sonicpi/scsynthnative.rb
index c570c96..28b2321 100644
--- a/app/server/sonicpi/lib/sonicpi/scsynthnative.rb
+++ b/app/server/sonicpi/lib/sonicpi/scsynthnative.rb
@@ -5,7 +5,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/server.rb b/app/server/sonicpi/lib/sonicpi/server.rb
index a3101f5..fc595ed 100644
--- a/app/server/sonicpi/lib/sonicpi/server.rb
+++ b/app/server/sonicpi/lib/sonicpi/server.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -18,7 +18,7 @@ require_relative "controlbusallocator"
 require_relative "promise"
 require_relative "incomingevents"
 require_relative "counter"
-require_relative "buffer"
+require_relative "lazybuffer"
 require_relative "bufferstream"
 require_relative "scsynthexternal"
 #require_relative "scsynthnative"
@@ -332,16 +332,15 @@ module SonicPi
     def buffer_info(id)
       prom = Promise.new
       @osc_events.add_handler(@osc_path_b_info, @osc_events.gensym("/sonicpi/server")) do |payload|
-        if (id == payload.to_a[0])
-          prom.deliver!  payload
+        p = payload.to_a
+        if (id == p[0])
+          p.shift
+          prom.deliver! p
           :remove_handler
         end
       end
       osc @osc_path_b_query, id
-      res = prom.get
-
-      args = res.to_a
-      Buffer.new(self, args[0], args[1], args[2], args[3])
+      LazyBuffer.new(self, id, prom)
     end
 
     def with_done_sync(&block)
@@ -451,6 +450,7 @@ module SonicPi
 
     def shutdown
       @scsynth.shutdown
+      @osc_events.shutdown
     end
 
   end
diff --git a/app/server/sonicpi/lib/sonicpi/sthread.rb b/app/server/sonicpi/lib/sonicpi/sthread.rb
index 6b83ebd..76c21c5 100644
--- a/app/server/sonicpi/lib/sonicpi/sthread.rb
+++ b/app/server/sonicpi/lib/sonicpi/sthread.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/studio.rb b/app/server/sonicpi/lib/sonicpi/studio.rb
index b718b85..7b29cab 100644
--- a/app/server/sonicpi/lib/sonicpi/studio.rb
+++ b/app/server/sonicpi/lib/sonicpi/studio.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -24,6 +24,8 @@ module SonicPi
 
     attr_reader :synth_group, :fx_group, :mixer_group, :recording_group, :mixer_id, :mixer_bus, :mixer, :max_concurrent_synths, :rand_buf_id, :amp, :rebooting
 
+    attr_accessor :cent_tuning
+
     def initialize(hostname, port, msg_queue, max_concurrent_synths)
       @hostname = hostname
       @port = port
@@ -34,40 +36,61 @@ module SonicPi
       @sample_sem = Mutex.new
       @reboot_mutex = Mutex.new
       @rebooting = false
+      @cent_tuning = 0
+      @reboot_queue = Queue.new
+      @reboot_queue << :check
+
       init_studio
       reset_server
-      @check_server_t = Thread.new do
+
+      @server_rebooter = Thread.new do
         Thread.current.thread_variable_set(:sonic_pi_thread_group, "server checker")
         Thread.current.priority = 300
+        Kernel.sleep 10
         loop do
-          unless @rebooting
-            begin
-              if @server.status(5)
-                # server is alive
-              else
-                @error_occured_mutex.synchronize do
-                  @error_occurred_since_last_check = true
-                end
-                message "Sound server is down."
+          vs = []
+          vs << @reboot_queue.pop
+          # drain any other messages
+          @reboot_queue.size.times {vs << @reboot_queue.pop}
+          begin
+            if vs.include? :reboot
+              begin
+                server_reboot
+                Kernel.sleep 10
+                @reboot_queue << :check
+              rescue Exception => e
+                message "Error rebooting server:  #{e}, #{e.backtrace}"
+                message "Attempting to reboot again in 10s"
                 begin
-                  reboot
-                rescue
-                  message "Error rebooting server"
+                  message "Forcing shutdown of any running server"
+                  @server.shutdown
+                rescue Exception => e
+                  message "Error shutting down server:  #{e}, #{e.backtrace}"
                 end
+                Kernel.sleep 10
+                @reboot_queue << :reboot
               end
-            rescue
-              @error_occured_mutex.synchronize do
-                @error_occurred_since_last_check = true
-              end
-              message "Error communicating with sound server."
+            else
               begin
-                reboot
-              rescue
-                message "Error rebooting server"
+                if @server.status(5)
+                  # server is alive
+                  # check again in 5 seconds...
+                  Thread.new do
+                    Kernel.sleep 5
+                    @reboot_queue << :check
+                  end
+                else
+                  message "Sound server is down. Rebooting..."
+                  @reboot_queue << :reboot
+                end
+              rescue Exception => e
+                message "Error communicating with sound server. Rebooting...  #{e}, #{e.backtrace}"
+                @reboot_queue <<  :reboot
               end
             end
+          rescue Exception => e
+            message "Error in reboot thread: #{e}, #{e.backtrace}"
           end
-          Kernel.sleep 5
         end
       end
     end
@@ -81,15 +104,6 @@ module SonicPi
       server.add_event_handler("/sonic-pi/amp", "/sonic-pi/amp") do |payload|
         @amp = [payload[2], payload[3]]
       end
-      # load rand stream directly - ensuring it doesn't get considered as a 'sample'
-      rand_buf_id = server.buffer_alloc_read(buffers_path + "/rand-stream.wav").to_i
-      old_samples = @samples
-      @samples = {}
-
-      (old_samples || {}).each do |k, v|
-        message "Reloading sample - #{unify_tilde_dir(k)}"
-        internal_load_sample(k, server)
-      end
 
       old_synthdefs = @loaded_synthdefs
       @loaded_synthdefs = Set.new
@@ -99,6 +113,22 @@ module SonicPi
         internal_load_synthdefs(s, server)
       end
 
+      # load rand stream directly - ensuring it doesn't get considered as a 'sample'
+      rand_buf_id = server.buffer_alloc_read(buffers_path + "/rand-stream.wav").to_i
+      old_samples = @samples
+      @samples = {}
+
+      Thread.new do
+        Thread.current.thread_variable_set(:sonic_pi_thread_group, "Studio sample loader")
+        Thread.current.priority = -10
+        (old_samples || {}).each do |k, v|
+          message "Reloading sample - #{unify_tilde_dir(k)}"
+          internal_load_sample(k, server)
+        end
+      end
+
+
+
       @recorders = {}
       @recording_mutex = Mutex.new
       @server = server
@@ -117,7 +147,7 @@ module SonicPi
     end
 
     def load_synthdefs(path, server=@server)
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:load_synthdefs)
       internal_load_synthdefs(path, server)
     end
 
@@ -126,12 +156,12 @@ module SonicPi
     end
 
     def load_sample(path, server=@server)
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:load_sample)
       internal_load_sample(path, server)
     end
 
     def free_sample(paths, server=@server)
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:free_sample)
       @sample_sem.synchronize do
         paths.each do |p|
           info = @samples[p]
@@ -143,7 +173,7 @@ module SonicPi
     end
 
     def free_all_samples(server=@server)
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:free_all_samples)
       @sample_sem.synchronize do
         @samples.each do |k, v|
           server.buffer_free(v)
@@ -154,7 +184,7 @@ module SonicPi
 
 
     def start_amp_monitor
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:start_amp_monitor)
       unless @amp_synth
         @amp_synth = @server.trigger_synth :head, @recording_group, "sonic-pi-amp_stereo_monitor", {"bus" => 0}, true
       end
@@ -162,25 +192,25 @@ module SonicPi
 
 
     def trigger_synth(synth_name, group, args, info, now=false, t_minus_delta=false )
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:trigger_synth)
       @server.trigger_synth(:head, group, synth_name, args, info, now, t_minus_delta)
     end
 
     def volume=(vol)
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:invert)
       message "Setting main volume to #{vol}"
       @server.node_ctl @mixer, {"amp" => vol}
     end
 
     def mixer_invert_stereo(invert)
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:mixer_invert_stereo)
       # invert should be true or false
       invert_i = invert ? 1 : 0
       @server.node_ctl @mixer, {"invert_stereo" => invert_i}, true
     end
 
     def mixer_control(opts)
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:mixer_control)
       now = 0
       opts = opts.clone
       if opts[:now].is_a?(Numeric)
@@ -193,80 +223,75 @@ module SonicPi
     end
 
     def mixer_reset
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:mixer_reset)
       info = Synths::SynthInfo.get_info(:main_mixer)
       mixer_control(info.slide_arg_defaults)
       mixer_control(info.arg_defaults)
     end
 
     def mixer_stereo_mode
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:mixer_stereo_mode)
       @server.node_ctl @mixer, {"force_mono" => 0}, true
     end
 
     def mixer_mono_mode
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:mixer_mono_mode)
       @server.node_ctl @mixer, {"force_mono" => 1}, true
     end
 
     def status
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:status)
       @server.status
     end
 
     def stop
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:stop)
       @server.clear_schedule
       @server.group_clear @synth_group
     end
 
     def new_group(position, target, name="")
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:new_group)
       @server.create_group(position, target, name)
     end
 
     def new_synth_group(id=-1)
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:new_synth_group)
       new_group(:tail, @synth_group, "Run-#{id}-Synths")
     end
 
     def new_fx_group(id=-1)
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:new_fx_group)
       new_group(:tail, @fx_group, "Run-#{id}-FX")
     end
 
     def new_fx_bus
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:new_fx_bus)
       @server.allocate_audio_bus
     end
 
     def sched_ahead_time
-      raise StudioCurrentlyRebootingError if @rebooting
       @server.sched_ahead_time
     end
 
     def sched_ahead_time=(t)
-      raise StudioCurrentlyRebootingError if @rebooting
       @server.sched_ahead_time = t
     end
 
     def control_delta
-      raise StudioCurrentlyRebootingError if @rebooting
       @server.control_delta
     end
 
     def control_delta=(t)
-      raise StudioCurrentlyRebootingError if @rebooting
       @server.control_delta = t
     end
 
     def recording?(bus=0)
-      raise StudioCurrentlyRebootingError if @rebooting
       @recorders[bus]
     end
 
     def recording_start(path, bus=0)
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:recording_start)
       return false if @recorders[bus]
       @recording_mutex.synchronize do
         return false if @recorders[bus]
@@ -278,7 +303,7 @@ module SonicPi
     end
 
     def recording_stop(bus=0)
-      raise StudioCurrentlyRebootingError if @rebooting
+      check_for_server_rebooting!(:recording_stop)
       return false unless @recorders[bus]
       @recording_mutex.synchronize do
         return false unless @recorders[bus]
@@ -291,28 +316,46 @@ module SonicPi
     end
 
     def shutdown
-      raise StudioCurrentlyRebootingError if @rebooting
-      @server.shutdown
+      @server_reboot.kill
+      begin
+        @server.shutdown
+      rescue Exception => e
+      end
     end
 
+
     def reboot
-      return nil if @rebooting
-      @reboot_mutex.synchronize do
-        @rebooting = true
-        message "Rebooting server. Please wait..."
-        @server.shutdown
-        init_studio
-        reset_server
-        message "Server ready."
-        @rebooting = false
-      end
-      true
+      @reboot_queue.push :reboot
     end
 
     private
 
+    def server_reboot
+      # Important:
+      # This method should only be called from the @server_rebooter
+      # thread.
+      @rebooting = true
+      message "Rebooting server. Please wait..."
+      @server.shutdown
+      init_studio
+      reset_server
+      message "Server ready."
+      @rebooting = false
+      true
+    end
+
+    def check_for_server_rebooting!(msg=nil)
+      if @rebooting
+        message "Oops, already rebooting: #{msg}"
+        log "Oops, already rebooting: #{msg}"
+        raise StudioCurrentlyRebootingError if @rebooting
+      end
+    end
+
     def message(s)
-      @msg_queue.push({:type => :info, :val => "Studio: #{s.to_s}"})
+      m = s.to_s
+      log "Studio - #{m}"
+      @msg_queue.push({:type => :info, :val => "Studio: #{m}"})
     end
 
 
@@ -345,8 +388,9 @@ module SonicPi
       buf_info = nil
       @sample_sem.synchronize do
         return @samples[path] if @samples[path]
-        buf_info = server.buffer_alloc_read(path)
-        buf_info.path = path
+        raise "No sample exists with path:\n  #{unify_tilde_dir(path).inspect}" unless File.exists?(path) && !File.directory?(path)
+          buf_info = server.buffer_alloc_read(path)
+          buf_info.path = path
         @samples[path] = buf_info
       end
       [buf_info, false]
diff --git a/app/server/sonicpi/lib/sonicpi/synthnode.rb b/app/server/sonicpi/lib/sonicpi/synthnode.rb
index ac7cac4..642798c 100644
--- a/app/server/sonicpi/lib/sonicpi/synthnode.rb
+++ b/app/server/sonicpi/lib/sonicpi/synthnode.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/synthnodeproxy.rb b/app/server/sonicpi/lib/sonicpi/synthnodeproxy.rb
index cbfc40d..dd530ae 100644
--- a/app/server/sonicpi/lib/sonicpi/synthnodeproxy.rb
+++ b/app/server/sonicpi/lib/sonicpi/synthnodeproxy.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/synths/synthinfo.rb b/app/server/sonicpi/lib/sonicpi/synths/synthinfo.rb
index 1dcf671..208ef88 100644
--- a/app/server/sonicpi/lib/sonicpi/synths/synthinfo.rb
+++ b/app/server/sonicpi/lib/sonicpi/synths/synthinfo.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -43,6 +43,18 @@ module SonicPi
         r + smallest
       end
 
+      def alias_opts!(alias_opt, orig_opt, args_h)
+        if args_h.has_key?(alias_opt) && !args_h.has_key?(orig_opt)
+          args_h[orig_opt] = args_h[alias_opt]
+          args_h.delete(alias_opt)
+        end
+        args_h
+      end
+
+      def munge_opts(args_h)
+        args_h
+      end
+
       def doc
         "Please write documentation!"
       end
@@ -93,7 +105,8 @@ module SonicPi
 
         args_h.each do |k, v|
           k_sym = k.to_sym
-          arg_information = @info[k_sym] || {}
+          arg_information = @info[k_sym]
+          next unless arg_information
           arg_validations = arg_information[:validations] || []
           arg_validations(k_sym).each do |v_fn, msg|
             raise "Value of opt #{k_sym.inspect} #{msg}, got #{v.inspect}." unless v_fn.call(args_h)
@@ -538,6 +551,9 @@ module SonicPi
     end
 
     class SonicPiSynth < SynthInfo
+      def user_facing?
+        true
+      end
     end
 
     class DullBell < SonicPiSynth
@@ -875,6 +891,24 @@ module SonicPi
       end
     end
 
+    class DTri < DSaw
+      def name
+        "Detuned Triangle Wave"
+      end
+
+      def introduced
+        Version.new(2, 10, 0)
+      end
+
+      def synth_name
+        "dtri"
+      end
+
+      def doc
+        "A pair of detuned triangle waves passed through a low pass filter. Two pulse waves with slightly different frequencies generates a nice thick sound which can be used as a basis for some nice bass sounds. Thicken the sound by increasing the detune value, or create an octave-playing synth by choosing a detune of 12 (12 MIDI notes is an octave)."
+      end
+    end
+
     class DPulse < DSaw
       def name
         "Detuned Pulse Wave"
@@ -1768,6 +1802,112 @@ module SonicPi
       end
     end
 
+    class SynthPluck < SonicPiSynth
+      def name
+        "SynthPluck"
+      end
+
+      def introduced
+        Version.new(2,10,0)
+      end
+
+      def synth_name
+        "pluck"
+      end
+
+      def doc
+        "A basic plucked string synthesiser that uses Karplus-Strong synthesis. Note that due to the plucked nature of this synth the envelope opts such as `attack:`, `sustain:` and `release:` do not work as expected. They can only shorten the natural length of the note, not prolong it. Also, the `note:` opt will only honour whole tones."
+      end
+
+      def arg_defaults
+        {
+          :note => 52,
+          :note_slide => 0,
+          :note_slide_shape => 1,
+          :note_slide_curve => 0,
+          :amp => 1,
+          :amp_slide => 0,
+          :amp_slide_shape => 1,
+          :amp_slide_curve => 0,
+          :pan => 0,
+          :pan_slide => 0,
+          :pan_slide_shape => 1,
+          :pan_slide_curve => 0,
+          :attack => 0,
+          :sustain => 0,
+          :release => 1,
+          :attack_level => 1,
+          :decay => 0,
+          :decay_level => :sustain_level,
+          :sustain_level => 1,
+          :noise_amp => 0.8,
+          :max_delay_time => 0.125,
+          :pluck_decay => 30,
+          :coef => 0.3
+        }
+      end
+
+      def specific_arg_info
+        {
+          :note =>
+          {
+            :doc => "Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`. Note that the piano synth can only play whole tones such as 60 and does not handle floats such as 60.3",
+            :validations => [v_positive(:note)],
+            :modulatable => true
+          },
+
+          :noise_amp => {
+            :doc => "Amplitude of source (pink) noise.",
+            :validations => [v_between_inclusive(:noise_amp, 0, 1)],
+            :modulatable => false},
+
+          :max_delay_time => {
+            :doc => "Maximum length of the delay line buffer.",
+            :validations => [v_between_inclusive(:max_delay_time, 0.125, 1)],
+            :modulatable => false},
+
+          :pluck_decay => {
+            :doc => "How long the pluck takes to stabilise on a note. This doesn't have a dramatic effect on the sound.",
+            :validations => [v_between_inclusive(:pluck_decay, 1, 100)],
+            :modulatable => false},
+
+          :coef =>
+          {
+            :doc => "Coefficient of the internal OnePole filter. Values around zero are resonant and bright, values towards 1 sound more dampened and cutoff. It's a little bit like playing nearer the soundhole/fingerboard for values near zero and more toward the bridge for values approaching one, although this isn't an exact comparison.",
+            :validations => [v_between_inclusive(:coef, -1, 1)],
+            :modulatable => false
+          },
+
+          :decay =>
+          {
+            :doc => "Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level). With the piano synth, this opt can only have the effect of controlling the amp within the natural duration of the note and can not prolong the sound.",
+            :validations => [v_positive(:decay)],
+            :modulatable => false,
+            :bpm_scale => true
+          },
+
+          :sustain =>
+          {
+            :doc => "Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. With the piano synth, this opt can only have the effect of controlling the amp within the natural duration of the note and can not prolong the sound.",
+            :validations => [v_positive(:sustain)],
+            :modulatable => false,
+            :bpm_scale => true
+          },
+
+          :release =>
+          {
+            :doc => "Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. With the piano synth, this opt can only have the effect of controlling the amp within the natural duration of the note and can not prolong the sound.",
+            :validations => [v_positive(:release)],
+            :modulatable => false,
+            :bpm_scale => true
+          }
+
+
+        }
+
+      end
+    end
+
     class SynthPiano < SonicPiSynth
       def name
         "SynthPiano"
@@ -2229,7 +2369,7 @@ module SonicPi
         {
           :norm =>
           {
-            :doc => "Normalise the audio (make quieter parts of the sample louder and louder parts quieter) - this is similar to the normaliser FX. This may emphasise any clicks caused by clipping.",
+            :doc => "Normalise the audio (make quieter parts of the synth's sound louder and louder parts quieter) - this is similar to the normaliser FX. This may emphasise any clicks caused by clipping.",
             :validations => [v_one_of(:norm, [0, 1])],
             :modulatable => true
           },
@@ -2447,6 +2587,127 @@ module SonicPi
 
     end
 
+    class ChipLead < SonicPiSynth
+      def name
+        "Chip Lead"
+      end
+
+      def introduced
+        Version.new(2,10,0)
+      end
+
+      def synth_name
+        "chiplead"
+      end
+
+      def doc
+        "A slightly clipped square (pulse) wave with phases of 12.5%, 25% or 50% modelled after the 2A03 chip found in voices 1 and 2 of the NES games console. This can be used for retro sounding leads and harmonised lines. This also adds an opt 'note_resolution' which locks the note slide to certain pitches which are multiples of the step size. This allows for emulation of the sweep setting on the 2A03."
+      end
+
+      def arg_defaults
+        {
+          :note => 60,
+          :note_slide => 0,
+          :note_slide_shape => 1,
+          :note_slide_curve => 0,
+          :note_resolution => 0.1,
+          :amp => 1,
+          :amp_slide => 0,
+          :amp_slide_shape => 1,
+          :amp_slide_curve => 0,
+          :pan => 0,
+          :pan_slide => 0,
+          :pan_slide_shape => 1,
+          :pan_slide_curve => 0,
+
+          :attack => 0,
+          :decay => 0,
+          :sustain => 0,
+          :release => 1,
+          :attack_level => 1,
+          :decay_level => :sustain_level,
+          :sustain_level => 1,
+          :env_curve => 2,
+
+          :width => 0
+        }
+      end
+
+      def specific_arg_info
+        {
+          :width =>
+          {
+            :doc => "Which of the three pulse_widths to use - 0 => 12.5%, 1 => 25%, 2 => 50%",
+            :validations => [v_one_of(:width, [0, 1, 2])],
+            :modulatable => true,
+          },
+
+          :note_resolution =>
+          {
+            :doc => "Locks down the note resolution to be multiples of this (MIDI) number. For example, a `note_resolution:` of 1 will only allow semitones to be played. When used in conjunction with `note_slide:` produces a staircase of notes rather than a continuous line which is how things were on the NES. Set to 0 to disable. This wasn't a feature of this triangle (bass) channel on the original chip but some emulators have added it in since.",
+            :validations => [v_positive(:note_resolution)],
+            :modulatable => true
+          },
+        }
+      end
+    end
+
+    class ChipBass < SonicPiSynth
+      def name
+        "Chip Bass"
+      end
+
+      def introduced
+        Version.new(2,10,0)
+      end
+
+      def synth_name
+        "chipbass"
+      end
+
+      def doc
+        "A 16 step triangle wave modelled after the 2A03 chip found in voice 3 of the NES games console. This can be used for retro sounding basslines. For complete authenticity with the 2A03 bear in mind that the triangle channel on that chip didn't have a volume control."
+      end
+
+      def arg_defaults
+        {
+          :note => 60,
+          :note_slide => 0,
+          :note_slide_shape => 1,
+          :note_slide_curve => 0,
+          :note_resolution => 0.1,
+          :amp => 1,
+          :amp_slide => 0,
+          :amp_slide_shape => 1,
+          :amp_slide_curve => 0,
+          :pan => 0,
+          :pan_slide => 0,
+          :pan_slide_shape => 1,
+          :pan_slide_curve => 0,
+
+          :attack => 0,
+          :decay => 0,
+          :sustain => 0,
+          :release => 1,
+          :attack_level => 1,
+          :decay_level => :sustain_level,
+          :sustain_level => 1,
+          :env_curve => 2,
+        }
+      end
+
+      def specific_arg_info
+        {
+          :note_resolution =>
+          {
+            :doc => "Locks down the note resolution to be multiples of this (MIDI) number. For example, a `note_resolution:` of 1 will only allow semitones to be played. When used in conjunction with `note_slide:` produces a staircase of notes rather than a continuous line which is how things were on the NES. Set to 0 to disable. This wasn't a feature of this triangle (bass) channel on the original chip but some emulators have added it in since.",
+            :validations => [v_positive(:note_resolution)],
+            :modulatable => true
+          },
+        }
+      end
+    end
+
     class Pitchless < SonicPiSynth
     end
 
@@ -2575,56 +2836,218 @@ module SonicPi
 
     end
 
-    class StudioInfo < SonicPiSynth
-
-    end
-
-    class SoundIn < StudioInfo
+    class ChipNoise < Noise
       def name
-        "Sound In"
+        "Chip Noise"
       end
 
       def introduced
-        Version.new(2,0,0)
+        Version.new(2,10,0)
       end
 
       def synth_name
-        "sound_in"
+        "chipnoise"
+      end
+
+      def doc
+        "Generates noise whose values are either -1 or 1 (like a pulse or square wave) with one of 16 particular frequencies. This is similar to the noise channel on the 2A03 chip used in the NES games console, although it lacks the same Pseudo-Random Number Generator (PRNG) and doesn't implement the 2A03's lesser used noise mode. The amplitude envelope defaults to moving by step to keep that 16 bit feel and this synth also has a slight soft clipping to better imitate the original sound of the device. Use for retro effects, hand claps, snare drums and hi-hats."
       end
 
       def arg_defaults
         {
           :amp => 1,
           :amp_slide => 0,
-          :amp_slide_shape => 1,
-          :amp_slide_curve => 0,
+          :amp_slide_shape => 0,
+          :amp_slide_curve => 1,
           :pan => 0,
           :pan_slide => 0,
           :pan_slide_shape => 1,
           :pan_slide_curve => 0,
-          :input => 0
+
+          :attack => 0,
+          :decay => 0,
+          :sustain => 1,
+          :release => 0,
+          :attack_level => 1,
+          :decay_level => :sustain_level,
+          :sustain_level => 1,
+          :env_curve => 0,
+
+          :freq_band => 0,
+          :freq_band_slide => 0,
+          :freq_band_slide_shape => 1,
+          :freq_band_slide_curve => 0,
         }
       end
 
-    end
+      def specific_arg_info
+        {
+          :freq_band =>
+          {
+            :doc => "Which of the 16 frequency bands to use, from 0 to 15. These range from 220Hz to 225kHz as on the original chip. This arg will accept floats but round to the nearest integer to allow for sweeping through the 16 set points with envelopes.",
+            :validations => [v_between_inclusive(:freq_band, 0, 15)],
+            :modulatable => true,
+          },
 
+          :freq_band_slide =>
+          {
+            :doc => generic_slide_doc(:freq_band),
+            :validations => [v_positive(:freq_band_slide)],
+            :modulatable => true,
+            :bpm_scale => true
+          },
+        }
+      end
+    end
 
+    class StudioInfo < SonicPiSynth
+      def user_facing?
+        false
+      end
+    end
 
-    class BasicMonoPlayer < StudioInfo
+    class SoundIn < StudioInfo
       def name
-        "Basic Mono Sample Player (no env)"
+        "Sound In"
       end
 
       def introduced
-        Version.new(2,0,0)
+        Version.new(2,10,0)
       end
 
       def synth_name
-        "basic_mono_player"
+        "sound_in"
       end
 
       def doc
-        ""
+        "Treat sound card input as a synth. If your audio card has inputs, you may use this synth to feed the incoming audio into Sonic Pi. This synth will read in a single mono audio stream - for example from a standard microphone or guitar. See `:sound_in_stereo` for a similar synth capable of reading in a stereo signal.
+
+As with all Sonic Pi synths, there is a default envelope which determines the duration of the lifetime of the synth. Therefore, to get a continuous stream of audio, you need to place consecutive calls to this synth in iteration or a `live_loop`. For example:
+
+```
+live_loop :playback do
+```
+
+```
+   synth :sound_in, sustain: 8
+```
+
+```
+   sleep 8
+```
+
+```
+end
+```
+Note that if the microphone and speaker are close together (on a laptop or in a small room) you will potentially get a harsh feedback sound."
+      end
+
+      def arg_defaults
+        {
+          :amp => 1,
+          :amp_slide => 0,
+          :amp_slide_shape => 1,
+          :amp_slide_curve => 0,
+          :pan => 0,
+          :pan_slide => 0,
+          :pan_slide_shape => 1,
+          :pan_slide_curve => 0,
+
+          :attack => 0,
+          :decay => 0,
+          :sustain => 1,
+          :release => 0,
+          :attack_level => 1,
+          :decay_level => :sustain_level,
+          :sustain_level => 1,
+          :env_curve => 0,
+
+          :input => 1
+        }
+      end
+
+      def specific_arg_info
+        {
+          :input =>
+          {
+            :doc => "Sound card input channel to obtain audio from. Indexing starts at 1 so input 1 represents the first channel, and channel 2 can be represented by `input: 2`",
+            :validations => [v_greater_than_oet(:input, 1)],
+            :modulatable => true,
+          }
+        }
+      end
+
+    end
+
+    class SoundInStereo < SoundIn
+      def name
+        "Sound In Stereo"
+      end
+
+      def synth_name
+        "sound_in_stereo"
+      end
+
+      def specific_arg_info
+        {
+          :input =>
+          {
+            :doc => "First of two consecutive sound card input channels to obtain audio from. Indexing starts at 1 so input 1 represents the first channel, and channel 2 can be represented by `input: 2`",
+            :validations => [v_greater_than_oet(:input, 1)],
+            :modulatable => true,
+          }
+        }
+      end
+
+      def doc
+        "Treat sound card input as a synth. If your audio card has inputs, you may use this synth to feed the incoming audio into Sonic Pi. This synth will read in a stereo audio stream - for example from a stereo microphone or external stereo keyboard. See `:sound_in` for a similar synth capable of reading in a mono signal. The stereo input is expected to be on consecutive sound card channels.
+
+As with all Sonic Pi synths, there is a default envelope which determines the duration of the lifetime of the synth. Therefore, to get a continuous stream of audio, you need to place consecutive calls to this synth in iteration or a `live_loop`. For example:
+
+```
+live_loop :playback do
+```
+
+```
+   synth :sound_in_stereo, sustain: 8
+```
+
+```
+   sleep 8
+```
+
+```
+end
+```
+
+Note that if the microphone and speaker are close together (on a laptop or in a small room) you will potentially get a harsh feedback sound."
+      end
+    end
+
+
+    class BasicMonoPlayer < StudioInfo
+      def name
+        "Basic Mono Sample Player (no env)"
+      end
+
+      def introduced
+        Version.new(2,0,0)
+      end
+
+      def synth_name
+        "basic_mono_player"
+      end
+
+      def doc
+        ""
+      end
+
+      def munge_opts(args_h)
+        alias_opts!(:cutoff, :lpf, args_h)
+        alias_opts!(:cutoff_slide, :lpf_slide, args_h)
+        alias_opts!(:cutoff_slide_curve, :lpf_slide_curve, args_h)
+        alias_opts!(:cutoff_slide_shape, :lpf_slide_shape, args_h)
+        args_h
       end
 
       def arg_defaults
@@ -2638,14 +3061,14 @@ module SonicPi
           :pan_slide_shape => 1,
           :pan_slide_curve => 0,
           :rate => 1,
-          :cutoff => 0,
-          :cutoff_slide => 0,
-          :cutoff_slide_shape => 1,
-          :cutoff_slide_curve => 0,
-          :res => 0,
-          :res_slide => 0,
-          :res_slide_shape => 1,
-          :res_slide_curve => 0,
+          :lpf => -1,
+          :lpf_slide => 0,
+          :lpf_slide_shape => 1,
+          :lpf_slide_curve => 0,
+          :hpf => -1,
+          :hpf_slide => 0,
+          :hpf_slide_shape => 1,
+          :hpf_slide_curve => 0
         }
       end
 
@@ -2655,8 +3078,18 @@ module SonicPi
           {
             :validations => [v_not_zero(:rate)],
             :modulatable => false
+          },
+
+
+          :lpf =>
+          {
+            :doc => "Low pass filter cutoff value. A MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.",
+            :validations => [v_positive(:lpf), v_less_than(:lpf, 131)],
+            :modulatable => true,
+            :midi => true
           }
         }
+
       end
     end
 
@@ -2678,7 +3111,7 @@ module SonicPi
       end
     end
 
-    class MonoPlayer < StudioInfo
+    class MonoPlayer < BasicMonoPlayer
       def name
         "Mono Sample Player"
       end
@@ -2701,46 +3134,71 @@ module SonicPi
           :amp_slide => 0,
           :amp_slide_shape => 1,
           :amp_slide_curve => 0,
+          :pre_amp => 1,
+          :pre_amp_slide => 0,
+          :pre_amp_slide_shape => 1,
+          :pre_amp_slide_curve => 0,
           :pan => 0,
           :pan_slide => 0,
           :pan_slide_shape => 1,
           :pan_slide_curve => 0,
 
+
           :attack => 0,
           :decay => 0,
           :sustain => -1,
           :release => 0,
 
+          :lpf => -1,
+          :lpf_slide => 0,
+          :lpf_slide_shape => 1,
+          :lpf_slide_curve => 0,
+          :lpf_attack => 0,
+          :lpf_decay => 0,
+          :lpf_sustain => -1,
+          :lpf_release => 0,
+          :lpf_init_level => -1,
+          :lpf_attack_level => -1,
+          :lpf_decay_level => -1,
+          :lpf_sustain_level => -1,
+          :lpf_release_level => -1,
+          :lpf_env_curve => 2,
+          :lpf_min => -1,
+          :lpf_min_slide => 0,
+          :lpf_min_slide_shape => 1,
+          :lpf_min_slide_curve => 0,
+
+          :hpf => -1,
+          :hpf_slide => 0,
+          :hpf_slide_shape => 1,
+          :hpf_slide_curve => 0,
+          :hpf_attack => 0,
+          :hpf_sustain => -1,
+          :hpf_decay => 0,
+          :hpf_release => 0,
+          :hpf_init_level => -1,
+          :hpf_attack_level => -1,
+          :hpf_decay_level => -1,
+          :hpf_sustain_level => -1,
+          :hpf_release_level => -1,
+          :hpf_env_curve => 2,
+          :hpf_max => -1,
+          :hpf_max_slide => 0,
+          :hpf_max_slide_shape => 1,
+          :hpf_max_slide_curve => 0,
+
+
           :attack_level => 1,
           :decay_level => :sustain_level,
           :sustain_level => 1,
           :env_curve => 2,
 
-          :cutoff_attack => 0,
-          :cutoff_decay => 0,
-          :cutoff_sustain => -1,
-          :cutoff_release => 0,
-          :cutoff_attack_level => :cutoff,
-          :cutoff_decay_level => :cutoff,
-          :cutoff_sustain_level => :cutoff,
-          :cutoff_env_curve => 2,
-          :cutoff_min => 30,
-          :cutoff_min_slide => 0,
-          :cutoff_min_slide_shape => 1,
-          :cutoff_min_slide_curve => 0,
 
           :rate => 1,
           :start => 0,
           :finish => 1,
 
-          :res => 0,
-          :res_slide => 0,
-          :res_slide_shape => 1,
-          :res_slide_curve => 0,
-          :cutoff => 0,
-          :cutoff_slide => 0,
-          :cutoff_slide_shape => 1,
-          :cutoff_slide_curve => 0,
+
           :norm => 0,
 
           :pitch => 0,
@@ -2758,25 +3216,49 @@ module SonicPi
           :time_dis => 0.0,
           :time_dis_slide => 0,
           :time_dis_slide_shape => 1,
-          :time_dis_slide_curve => 0
+          :time_dis_slide_curve => 0,
+
+          :compress => 0,
+          :threshold => 0.2,
+          :threshold_slide => 0,
+          :threshold_slide_shape => 1,
+          :threshold_slide_curve => 0,
+          :clamp_time => 0.01,
+          :clamp_time_slide => 0,
+          :clamp_time_slide_shape => 1,
+          :clamp_time_slide_curve => 0,
+          :slope_above => 0.5,
+          :slope_above_slide => 0,
+          :slope_above_slide_shape => 1,
+          :slope_above_slide_curve => 0,
+          :slope_below => 1,
+          :slope_below_slide => 0,
+          :slope_below_slide_shape => 1,
+          :slope_below_slide_curve => 0,
+          :relax_time => 0.01,
+          :relax_time_slide => 0,
+          :relax_time_slide_shape => 1,
+          :relax_time_slide_curve => 0
         }
       end
 
       def specific_arg_info
-        {
+        super.merge({
 
           :attack =>
           {
             :doc => "Duration of the attack phase of the envelope.",
             :validations => [v_positive(:attack)],
-            :modulatable => false
+            :modulatable => false,
+            :default => 0
           },
 
           :decay =>
           {
             :doc => "Duration of the decay phase of the envelope.",
             :validations => [v_positive(:decay)],
-            :modulatable => false
+            :modulatable => false,
+            :default => 0
           },
 
           :sustain =>
@@ -2784,152 +3266,397 @@ module SonicPi
             :doc => "Duration of the sustain phase of the envelope. When -1 (the default) will auto-stretch.",
             :validations => [[lambda{|args| v = args[:sustain] ; (v == -1) || (v >= 0)}, "must either be a positive value or -1"]],
 
-            :modulatable => false
+            :modulatable => false,
+            :default => -1
           },
 
           :release =>
           {
             :doc => "Duration of the release phase of the envelope.",
             :validations => [v_positive(:release)],
+            :modulatable => false,
+            :default => 0
+          },
+
+
+          :rate =>
+          {
+            :doc => "Rate with which to play back - default is 1. Playing the sample at rate 2 will play it back at double the normal speed. This will have the effect of doubling the frequencies in the sample and halving the playback time. Use rates lower than 1 to slow the sample down. Negative rates will play the sample in reverse.",
+            :validations => [v_not_zero(:rate)],
+            :modulatable => false,
+            :default => 1
+          },
+
+          :start =>
+          {
+            :doc => "A fraction (between 0 and 1) representing where in the sample to start playback. 1 represents the end of the sample, 0.5 half-way through etc.",
+            :validations => [v_between_inclusive(:start, 0, 1)],
+            :modulatable => false,
+            :default => 0
+          },
+
+          :finish =>
+          {
+            :doc => "A fraction (between 0 and 1) representing where in the sample to finish playback. 1 represents the end of the sample, 0.5 half-way through etc.",
+            :validations => [v_between_inclusive(:finish, 0, 1)],
+            :modulatable => false,
+            :default => 1
+          },
+
+          :norm =>
+          {
+            :doc => "Normalise the audio (make quieter parts of the sample louder and louder parts quieter) - this is similar to the normaliser FX. This may emphasise any clicks caused by clipping.",
+            :validations => [v_one_of(:norm, [0, 1])],
+            :modulatable => true,
+            :default => 0
+          },
+
+          :window_size =>
+          {
+            :doc => "Pitch shift works by chopping the input into tiny slices, then playing these slices at a higher or lower rate. If we make the slices small enough and overlap them, it sounds like the original sound with the pitch changed.
+
+  The window_size is the length of the slices and is measured in seconds. It needs to be around 0.2 (200ms) or greater for pitched sounds like guitar or bass, and needs to be around 0.02 (20ms) or lower for percussive sounds like drum loops. You can experiment with this to get the best sound for your input.",
+            :validations => [v_greater_than(:window_size, 0.00005)],
+            :modulatable => true,
+            :default => 0.2
+          },
+
+          :pitch =>
+          {
+            :doc => "Pitch adjustment in semitones. 1 is up a semitone, 12 is up an octave, -12 is down an octave etc. Maximum upper limit of 24 (up 2 octaves). Lower limit of -72 (down 6 octaves). Decimal numbers can be used for fine tuning.",
+            :validations => [v_greater_than_oet(:pitch, -72), v_less_than_oet(:pitch, 24)],
+            :modulatable => true,
+            :default => 0
+          },
+
+          :pitch_dis =>
+          {
+            :doc => "Pitch dispersion - how much random variation in pitch to add. Using a low value like 0.001 can help to \"soften up\" the metallic sounds, especially on drum loops. To be really technical, pitch_dispersion is the maximum random deviation of the pitch from the pitch ratio (which is set by the pitch param)",
+            :validations => [v_greater_than_oet(:pitch_dis, 0)],
+            :modulatable => true
+          },
+
+          :time_dis =>
+          {
+            :doc => "Time dispersion - how much random delay before playing each grain (measured in seconds). Again, low values here like 0.001 can help to soften up metallic sounds introduced by the effect. Large values are also fun as they can make soundscapes and textures from the input, although you will most likely lose the rhythm of the original. NB - This won't have an effect if it's larger than window_size.",
+            :validations => [v_greater_than_oet(:time_dis, 0)],
+            :modulatable => true
+          },
+
+          :lpf_init_level =>
+          {
+            :doc => "The initial low pass filter envelope value as a MIDI note. This envelope is bypassed if no lpf env opts are specified. Default value is to match the `lpf_min:` opt.",
+            :validations => [v_between_inclusive(:lpf_init_level, 0, 130)],
+            :default => "lpf_min",
+            :modulatable => false,
+            :midi => true
+          },
+
+          :lpf_attack_level =>
+          {
+            :doc => "The peak low pass filter envelope value after the attack phase as a MIDI note. This envelope is bypassed if no lpf env opts are specified. Default value is match the `lpf_decay_level:` opt.",
+            :validations => [v_between_inclusive(:lpf_attack_level, 0, 130)],
+            :modulatable => false,
+            :default => "lpf_decay_level",
+            :midi => true
+          },
+
+          :lpf_decay_level =>
+          {
+            :doc => "The level of the low pass filter envelope after the decay phase as a MIDI note. This envelope is bypassed if no lpf env opts are specified. Default value is to match the `lpf_sustain_level:` opt.",
+            :validations => [v_between_inclusive(:lpf_decay_level, 0, 130)],
+            :modulatable => false,
+            :default => "lpf_sustain_level",
+            :midi => true
+          },
+
+          :lpf_sustain_level =>
+          {
+            :doc => "The level of the low pass filter envelope after the sustain phase as a MIDI note. This envelope is bypassed if no lpf env opts are specified. Default value is to match the `lpf_release_level:` opt.",
+            :validations => [v_between_inclusive(:lpf_sustain_level, 0, 130)],
+            :modulatable => false,
+            :default => "lpf_release_level",
+            :midi => true
+          },
+
+          :lpf_release_level =>
+          {
+            :doc => "The final value of the low pass filter envelope as a MIDI note. This envelope is bypassed if no lpf env opts are specified. Default value is to match the `lpf:` opt.",
+            :validations => [v_between_inclusive(:lpf_release_level, 0, 130)],
+            :modulatable => false,
+            :default => "lpf",
+            :midi => true
+          },
+
+          :lpf_attack =>
+          {
+            :doc => "Attack time for low pass filter envelope. Amount of time (in beats) for sound to reach attack_level value. This envelope is bypassed if no lpf env opts are specified.  Default value is set to match amp envelope's attack value.",
+            :validations => [v_positive(:lpf_attack)],
+            :modulatable => false,
+            :default => "attack"
+          },
+
+          :lpf_decay =>
+          {
+            :doc => "Decay time for low pass filter envelope. Amount of time (in beats) for sound to move from `lpf_attack_level:` to the `lpf_sustain_level:`. This envelope is bypassed if no lpf env opts are specified.  Default value is set to match amp envelope's decay value.",
+            :validations => [v_positive(:lpf_decay)],
+            :modulatable => false,
+            :default => "decay"
+          },
+
+          :lpf_sustain =>
+          {
+            :doc => "Amount of time for low pass filter envelope value to remain at sustain level in beats. This envelope is bypassed if no lpf env opts are specified.  When -1 (the default) will auto-stretch.",
+            :validations => [[lambda{|args| v = args[:lpf_sustain] ; (v == -1) || (v >= 0)}, "must either be a positive value or -1"]],
+            :modulatable => false,
+            :default => "sustain"
+          },
+
+          :lpf_release =>
+          {
+            :doc => "Amount of time (in beats) for sound to move from `lpf_sustain_level:` to `lpf_release_level:`. This envelope is bypassed if no lpf env opts are specified. ",
+            :validations => [v_positive(:lpf_release)],
+            :modulatable => false,
+            :default => "release"
+          },
+
+          :lpf_env_curve =>
+          {
+            :doc => "Select the shape of the curve between levels in the cutoff envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed",
+            :validations => [v_one_of(:lpf_env_curve, [1, 2, 3, 4, 6, 7])],
             :modulatable => false
           },
 
-
-          :rate =>
+          :lpf_min =>
+          {
+            :doc => "The minimum low pass filter value.",
+            :validations => [v_less_than_oet(:lpf_min, 130)],
+            :modulatable => true,
+            :default => 130,
+            :midi => true
+          },
+
+          :lpf_min_slide =>
+          {
+            :doc => generic_slide_doc(:lpf_min),
+            :validations => [v_positive(:lpf_min_slide)],
+            :modulatable => true,
+            :bpm_scale => true
+                      },
+
+          :hpf_init_level =>
+          {
+            :doc => "The initial high pass filter envelope value as a MIDI note. This envelope is bypassed if no hpf env opts are specified. Default value is set to 130",
+            :validations => [v_between_inclusive(:hpf_init_level, 0, 130)],
+            :modulatable => false,
+            :default => 130,
+            :midi => true
+          },
+
+          :hpf_attack_level =>
+          {
+            :doc => "The peak hpf cutoff (value of hpf cutoff at peak of attack) as a MIDI note.",
+            :validations => [v_between_inclusive(:hpf_attack_level, 0, 130)],
+            :modulatable => false,
+            :midi => true,
+            :default => "hpf_decay_level"
+          },
+
+          :hpf_decay_level =>
+          {
+            :doc => "The level of hpf cutoff after the decay phase as a MIDI note.",
+            :validations => [v_between_inclusive(:hpf_decay_level, 0, 130)],
+            :modulatable => false,
+            :midi => true,
+            :default => "hpf_sustain_level"
+
+          },
+
+
+          :hpf_sustain_level =>
+          {
+            :doc => "The sustain hpf cutoff (value of hpf cutoff at sustain time) as a MIDI note.",
+            :validations => [v_between_inclusive(:hpf_sustain_level, 0, 130)],
+            :modulatable => false,
+            :midi => true,
+            :default => "hpf_release_level"
+          },
+
+          :hpf_release_level =>
+          {
+            :doc => "The sustain hpf cutoff (value of hpf cutoff at sustain time) as a MIDI note.",
+            :validations => [v_between_inclusive(:hpf_release_level, 0, 130)],
+            :modulatable => false,
+            :midi => true,
+            :default => "hpf"
+          },
+
+
+          :hpf_attack =>
+          {
+            :doc => "Attack time for hpf cutoff filter. Amount of time (in beats) for sound to reach full hpf cutoff value. Default value is set to match amp envelope's attack value.",
+            :validations => [v_positive(:hpf_attack)],
+            :modulatable => false,
+            :default => "attack"
+          },
+
+          :hpf_decay =>
+          {
+            :doc => "Decay time for hpf cutoff filter. Amount of time (in beats) for sound to move from full hpf cutoff value (cutoff attack level) to the hpf cutoff sustain level. Default value is set to match amp envelope's decay value.",
+            :validations => [v_positive(:hpf_decay)],
+            :modulatable => false,
+            :default => "decay"
+          },
+
+          :hpf_sustain =>
+          {
+            :doc => "Amount of time for hpf cutoff value to remain at hpf sustain level in beats. When -1 (the default) will auto-stretch.",
+            :validations => [[lambda{|args| v = args[:hpf_sustain] ; (v == -1) || (v >= 0)}, "must either be a positive value or -1"]],
+            :modulatable => false,
+            :default => "sustain"
+          },
+
+          :hpf_release =>
           {
-            :doc => "Rate with which to play back - default is 1. Playing the sample at rate 2 will play it back at double the normal speed. This will have the effect of doubling the frequencies in the sample and halving the playback time. Use rates lower than 1 to slow the sample down. Negative rates will play the sample in reverse.",
-            :validations => [v_not_zero(:rate)],
-            :modulatable => false
+            :doc => "Amount of time (in beats) for sound to move from hpf cutoff sustain value to hpf cutoff min value. Default value is set to match amp envelope's release value.",
+            :validations => [v_positive(:hpf_release)],
+            :modulatable => false,
+            :default => "release"
           },
 
-          :start =>
+          :hpf_env_curve =>
           {
-            :doc => "A fraction (between 0 and 1) representing where in the sample to start playback. 1 represents the end of the sample, 0.5 half-way through etc.",
-            :validations => [v_between_inclusive(:start, 0, 1)],
+            :doc => "Select the shape of the curve between levels in the hpf cutoff envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed",
+            :validations => [v_one_of(:hpf_env_curve, [1, 2, 3, 4, 6, 7])],
             :modulatable => false
           },
 
-          :finish =>
+          :hpf_min =>
           {
-            :doc => "A fraction (between 0 and 1) representing where in the sample to finish playback. 1 represents the end of the sample, 0.5 half-way through etc.",
-            :validations => [v_between_inclusive(:finish, 0, 1)],
-            :modulatable => false
+            :doc => "The minimum cutoff value.",
+            :validations => [v_less_than_oet(:hpf_min, 130)],
+            :modulatable => true,
+            :midi => true
           },
 
-          :norm =>
+          :hpf_min_slide =>
           {
-            :doc => "Normalise the audio (make quieter parts of the sample louder and louder parts quieter) - this is similar to the normaliser FX. This may emphasise any clicks caused by clipping.",
-            :validations => [v_one_of(:norm, [0, 1])],
-            :modulatable => true
+            :doc => generic_slide_doc(:hpf_min),
+            :validations => [v_positive(:hpf_min_slide)],
+            :modulatable => true,
+            :bpm_scale => true
           },
 
-          :res =>
+
+          :hpf_max =>
           {
-            :doc => "Filter resonance as a value between 0 and 1. Only functional if a cutoff value is specified. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.",
-            :validations => [v_positive(:res), v_less_than(:res, 1)],
-            :modulatable => true
+            :doc => "The maximum high pass filter value.",
+            :validations => [v_less_than_oet(:hpf_max, 130)],
+            :modulatable => true,
+            :default => 200,
+            :midi => true
           },
 
-          :window_size =>
-          {
-            :doc => "Pitch shift works by chopping the input into tiny slices, then playing these slices at a higher or lower rate. If we make the slices small enough and overlap them, it sounds like the original sound with the pitch changed.
 
-  The window_size is the length of the slices and is measured in seconds. It needs to be around 0.2 (200ms) or greater for pitched sounds like guitar or bass, and needs to be around 0.02 (20ms) or lower for percussive sounds like drum loops. You can experiment with this to get the best sound for your input.",
-            :validations => [v_greater_than(:window_size, 0.00005)],
+          :compress =>
+          {
+            :doc => "Enable the compressor. This sits at the end of the internal FX chain immediately before the `amp:` opt. Therefore to drive the compressor use the `pre_amp:` opt which will amplify the signal before it hits any internal FX. The compressor compresses the dynamic range of the incoming signal. Equivalent to automatically turning the amp down when the signal gets too loud and then back up again when it's quiet. Useful for ensuring the containing signal doesn't overwhelm other aspects of the sound. Also a general purpose hard-knee dynamic range processor which can be tuned via the opts to both expand and compress the signal.",
+            :validations => [v_one_of(:compress, [0, 1])],
             :modulatable => true
           },
 
-          :pitch_dis =>
+          :threshold =>
           {
-            :doc => "Pitch dispersion - how much random variation in pitch to add. Using a low value like 0.001 can help to \"soften up\" the metallic sounds, especially on drum loops. To be really technical, pitch_dispersion is the maximum random deviation of the pitch from the pitch ratio (which is set by the pitch param)",
-            :validations => [v_greater_than_oet(:pitch_dis, 0)],
+            :doc => "Threshold value determining the break point between slope_below and slope_above. Only valid if the compressor is enabled by turning on the comp: opt.",
+            :validations => [v_positive(:threshold)],
             :modulatable => true
           },
-          :time_dis =>
+
+          :threshold_slide =>
           {
-            :doc => "Time dispersion - how much random delay before playing each grain (measured in seconds). Again, low values here like 0.001 can help to soften up metallic sounds introduced by the effect. Large values are also fun as they can make soundscapes and textures from the input, although you will most likely lose the rhythm of the original. NB - This won't have an effect if it's larger than window_size.",
-            :validations => [v_greater_than_oet(:time_dis, 0)],
-            :modulatable => true
+            :doc => generic_slide_doc(:threshold),
+            :validations => [v_positive(:threshold_slide)],
+            :modulatable => true,
+            :bpm_scale => true
           },
 
-          :cutoff_attack_level =>
+          :slope_below =>
           {
-            :doc => "The peak cutoff (value of cutoff at peak of attack) as a MIDI note.",
-            :validations => [v_between_inclusive(:cutoff_attack_level, 0, 130)],
-            :modulatable => false
+            :doc => "Slope of the amplitude curve below the threshold. A value of 1 means that the output of signals with amplitude below the threshold will be unaffected. Greater values will magnify and smaller values will attenuate the signal. Only valid if the compressor is enabled by turning on the comp: opt.",
+            :validations => [],
+            :modulatable => true
           },
 
-          :cutoff_decay_level =>
+          :slope_below_slide =>
           {
-            :doc => "The level of cutoff after the decay phase as a MIDI note.",
-            :validations => [v_between_inclusive(:cutoff_decay_level, 0, 130)],
-            :modulatable => false
+            :doc => generic_slide_doc(:slope_below),
+            :validations => [v_positive(:slope_below_slide)],
+            :modulatable => true,
+            :bpm_scale => true
           },
 
-
-          :cutoff_sustain_level =>
+          :slope_above =>
           {
-            :doc => "The sustain cutoff (value of cutoff at sustain time) as a MIDI note.",
-            :validations => [v_between_inclusive(:cutoff_sustain_level, 0, 130)],
-            :modulatable => false
+            :doc => "Slope of the amplitude curve above the threshold. A value of 1 means that the output of signals with amplitude above the threshold will be unaffected. Greater values will magnify and smaller values will attenuate the signal. Only valid if the compressor is enabled by turning on the comp: opt.",
+
+            :validations => [],
+            :modulatable => true
           },
 
-          :cutoff_attack =>
+          :slope_above_slide =>
           {
-            :doc => "Attack time for cutoff filter. Amount of time (in beats) for sound to reach full cutoff value. Default value is set to match amp envelope's attack value.",
-            :validations => [v_positive(:cutoff_attack)],
-            :modulatable => false,
-            :default => "attack"
+            :doc => generic_slide_doc(:slope_above),
+            :validations => [v_positive(:slope_above_slide)],
+            :modulatable => true,
+            :bpm_scale => true
           },
 
-          :cutoff_decay =>
+          :clamp_time =>
           {
-            :doc => "Decay time for cutoff filter. Amount of time (in beats) for sound to move from full cutoff value (cutoff attack level) to the cutoff sustain level. Default value is set to match amp envelope's decay value.",
-            :validations => [v_positive(:cutoff_decay)],
-            :modulatable => false,
-            :default => "decay"
+            :doc => "Time taken for the amplitude adjustments to kick in fully (in seconds). This is usually pretty small (not much more than 10 milliseconds). Also known as the time of the attack phase. Only valid if the compressor is enabled by turning on the comp: opt.",
+            :validations => [v_positive(:clamp_time)],
+            :modulatable => true
           },
 
-          :cutoff_sustain =>
+          :clamp_time_slide =>
           {
-            :doc => "Amount of time for cutoff value to remain at sustain level in beats. When -1 (the default) will auto-stretch.",
-            :validations => [[lambda{|args| v = args[:cutoff_sustain] ; (v == -1) || (v >= 0)}, "must either be a positive value or -1"]],
-            :modulatable => false,
-            :default => "sustain"
+            :doc => generic_slide_doc(:clamp_time),
+            :validations => [v_positive(:clamp_time_slide)],
+            :modulatable => true,
+            :bpm_scale => true
           },
 
-          :cutoff_release =>
+          :relax_time =>
           {
-            :doc => "Amount of time (in beats) for sound to move from cutoff sustain value to cutoff min value. Default value is set to match amp envelope's release value.",
-            :validations => [v_positive(:cutoff_release)],
-            :modulatable => false,
-            :default => "release"
+            :doc => "Time taken for the amplitude adjustments to be released. Usually a little longer than clamp_time. If both times are too short, you can get some (possibly unwanted) artefacts. Also known as the time of the release phase. Only valid if the compressor is enabled by turning on the comp: opt.",
+            :validations => [v_positive(:relax_time)],
+            :modulatable => true
           },
 
-          :cutoff_env_curve =>
+          :relax_time_slide =>
           {
-            :doc => "Select the shape of the curve between levels in the cutoff envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed",
-            :validations => [v_one_of(:cutoff_env_curve, [1, 2, 3, 4, 6, 7])],
-            :modulatable => false
+            :doc => generic_slide_doc(:relax_time),
+            :validations => [v_positive(:relax_time_slide)],
+            :modulatable => true,
+            :bpm_scale => true
           },
 
-          :cutoff_min =>
+          :pre_amp =>
           {
-            :doc => "The minimum cutoff value.",
-            :validations => [v_less_than_oet(:cutoff_min, 130)],
-            :modulatable => true,
-            :midi => true
+            :doc => "Amplitude multiplier which takes place immediately before any internal FX such as the low pass filter, compressor or pitch modification. Use this opt if you want to overload the compressor.",
+            :validations => [v_positive(:pre_amp)],
+            :modulatable => true
           },
 
-          :cutoff_min_slide =>
+          :pre_amp_slide =>
           {
-            :doc => generic_slide_doc(:cutoff_min),
-            :validations => [v_positive(:cutoff_min_slide)],
+            :doc => generic_slide_doc(:pre_amp),
+            :validations => [v_positive(:pre_amp_slide)],
             :modulatable => true,
             :bpm_scale => true
-          },
+          }
 
-        }
+        })
       end
 
     end
@@ -3024,6 +3751,9 @@ module SonicPi
     end
 
     class FXInfo < BaseInfo
+      def user_facing?
+        true
+      end
 
       def trigger_with_logical_clock?
         true
@@ -3461,6 +4191,41 @@ module SonicPi
       end
     end
 
+    class FXMono < FXInfo
+      def name
+        "Mono"
+      end
+
+      def introduced
+        Version.new(2,10,0)
+      end
+
+      def synth_name
+        "fx_mono"
+      end
+
+      def doc
+        "Sum left and right channels. Useful with stereo samples that you need as a mono sound, or for use with panslicer."
+      end
+
+      def arg_defaults
+        {
+          :amp => 1,
+          :amp_slide => 0,
+          :amp_slide_shape => 1,
+          :amp_slide_curve => 0,
+          :pan => 0,
+          :pan_slide => 0,
+          :pan_slide_shape => 1,
+          :pan_slide_curve => 0,
+          :mix => 1,
+          :mix_slide => 0,
+          :mix_slide_shape => 1,
+          :mix_slide_curve => 0,
+        }
+      end
+    end
+
     class FXEcho < FXInfo
       def name
         "Echo"
@@ -4452,6 +5217,80 @@ module SonicPi
       end
     end
 
+    class FXWhammy < FXInfo
+      def name
+        "Whammy"
+      end
+
+      def introduced
+        Version.new(2,10,0)
+      end
+
+      def synth_name
+        "fx_whammy"
+      end
+
+      def doc
+        "A cheap sounding transposition effect, with a slightly robotic edge. Good for adding alien sounds and harmonies to everything from beeps to guitar samples. It's similar to pitch shift although not as smooth sounding."
+      end
+
+      def arg_defaults
+        {
+          :amp => 1,
+          :amp_slide => 0,
+          :amp_slide_shape => 1,
+          :amp_slide_curve => 0,
+          :mix => 1,
+          :pre_amp => 1,
+          :pre_amp_slide => 0,
+          :pre_amp_slide_shape => 1,
+          :pre_amp_slide_curve => 0,
+          :transpose => 12,
+          :transpose_slide => 0,
+          :transpose_slide_shape => 1,
+          :transpose_slide_curve => 0,
+          :max_delay_time => 1,
+          :deltime => 0.05,
+          :grainsize => 0.075
+        }
+      end
+
+      def specific_arg_info
+        {
+
+          :transpose =>
+          {
+            :doc => "This is how much to transpose the input, expressed as a midi pitch.",
+            :modulatable => true
+          },
+
+          :transpose_slide =>
+          {
+            :doc => generic_slide_doc(:transpose),
+            :validations => [v_positive(:transpose_slide)],
+            :modulatable => true,
+          },
+
+          :deltime =>
+          {
+            :doc => "The delay time to be used for the effect. This shouldn't need to be adjusted.",
+            :validations => [v_positive(:deltime)],
+          },
+
+          :max_delay_time =>
+          {
+            :doc => "The max delay time to be used for the effect. This shouldn't need to be adjusted.",
+            :validations => [v_positive(:max_delay_time)],
+          },
+
+          :grainsize =>
+          {
+            :doc => "The size of the initial grain used for transposition. This shouldn't need to be adjusted.",
+            :validations => [v_positive(:grainsize)],
+          },
+        }
+      end
+    end
 
     class FXCompressor < FXInfo
       def name
@@ -4586,6 +5425,56 @@ module SonicPi
       end
     end
 
+    class FXVowel < FXInfo
+      def name
+        "Vowel"
+      end
+
+      def introduced
+        Version.new(2,10,0)
+      end
+
+      def synth_name
+        "fx_vowel"
+      end
+
+      def arg_defaults
+        {
+          :amp => 1,
+          :amp_slide => 0,
+          :amp_slide_shape => 1,
+          :amp_slide_curve => 0,
+          :pre_amp => 1,
+          :pre_amp_slide => 0,
+          :pre_amp_slide_shape => 1,
+          :pre_amp_slide_curve => 0,
+          :vowel_sound => 1,
+          :voice => 0
+        }
+      end
+
+      def specific_arg_info
+        {
+          :vowel_sound =>
+          {
+            :doc => "1,2,3,4,5 => A,E,I,O,U",
+            :validations => [v_one_of(:vowel_sound, [1,2,3,4,5])],
+            :modulatable => true
+          },
+          :voice =>
+          {
+            :doc => "0,1,2,3,4 => Soprano,Alto,Counter Tenor, Tenor, Bass",
+            :validations => [v_one_of(:voice, [0,1,2,3,4])],
+            :modulatable => true
+          }
+        }
+      end
+
+      def doc
+        "This effect filters the input to match a human voice singing a certain vowel sound. Human singing voice sounds are easily achieved with a source of a saw wave with a little vibrato."
+      end
+    end
+
     class FXOctaver < FXInfo
       def name
         "Octaver"
@@ -4613,52 +5502,48 @@ module SonicPi
           :pre_amp_slide => 0,
           :pre_amp_slide_shape => 1,
           :pre_amp_slide_curve => 0,
-          :oct1_amp => 1,
-          :oct1_amp_slide => 0,
-          :oct1_amp_slide_shape => 1,
-          :oct1_amp_slide_curve => 0,
-          :oct1_interval => 12,
-          :oct1_interval_slide => 0,
-          :oct1_interval_slide_shape => 1,
-          :oct1_interval_slide_curve => 0,
-          :oct2_amp => 1,
-          :oct2_amp_slide => 0,
-          :oct2_amp_slide_shape => 1,
-          :oct2_amp_slide_curve => 0,
-          :oct3_amp => 1,
-          :oct3_amp_slide => 0,
-          :oct3_amp_slide_shape => 1,
-          :oct3_amp_slide_curve => 0
+          :super_amp => 1,
+          :super_amp_slide => 0,
+          :super_amp_slide_shape => 1,
+          :super_amp_slide_curve => 0,
+          :sub_amp => 1,
+          :sub_amp_slide => 0,
+          :sub_amp_slide_shape => 1,
+          :sub_amp_slide_curve => 0,
+          :subsub_amp => 1,
+          :subsub_amp_slide => 0,
+          :subsub_amp_slide_shape => 1,
+          :subsub_amp_slide_curve => 0
         }
       end
 
       def specific_arg_info
         {
-          :oct1_amp =>
+          :super_amp =>
           {
             :doc => "Volume of the signal 1 octave above the input",
-            :validations => [v_positive(:oct1_amp)],
+            :validations => [v_positive(:super_amp)],
             :modulatable => true
           },
-          :oct2_amp =>
+          :sub_amp =>
           {
             :doc => "Volume of the signal 1 octave below the input",
-            :validations => [v_positive(:oct2_amp)],
+            :validations => [v_positive(:sub_amp)],
             :modulatable => true
           },
-          :oct3_amp =>
+          :subsub_amp =>
           {
             :doc => "Volume of the signal 2 octaves below the input",
-            :validations => [v_positive(:oct3_amp)],
+            :validations => [v_positive(:subsub_amp)],
             :modulatable => true
           }
         }
       end
 
       def doc
-        "This harmoniser adds three pitches based on the input sound. The first is the original sound transposed up an octave, the second is the original sound transposed down an octave and the third is the original sound transposed down two octaves.
+        "This effect adds three pitches based on the input sound. The first is the original sound transposed up an octave (super_amp), the second is the original sound transposed down an octave (sub_amp) and the third is the original sound transposed down two octaves (subsub_amp).
 
-  The way the transpositions are done adds some distortion, particularly to the lower octaves, whilst the upper octave has a 'cheap' quality. This effect is often used in guitar effects pedals but it can work with other sounds too."
+  The way the transpositions are done adds some distortion/fuzz, particularly to the lower octaves, whilst the upper octave has a 'cheap' quality. This effect is often used in guitar effects pedals but it can work with other sounds too. There's a great description of the science behind this on Wikipedia here: https://en.wikipedia.org/wiki/Octave_effect"
       end
     end
 
@@ -5418,7 +6303,7 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
           :mix_slide => 0,
           :mix_slide_shape => 1,
           :mix_slide_curve => 0,
-          :krunch => 1,
+          :krunch => 5,
           :krunch_slide => 0,
           :krunch_slide_shape => 1,
           :krunch_slide_curve => 0,
@@ -5870,7 +6755,9 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
             :drum_cymbal_closed,
             :drum_cymbal_pedal,
             :drum_bass_soft,
-            :drum_bass_hard]},
+            :drum_bass_hard,
+            :drum_cowbell,
+            :drum_roll]},
 
         :elec => {
           :desc => "Electric Sounds",
@@ -5915,7 +6802,9 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
           :desc => "Miscellaneous Sounds",
           :prefix => "misc_",
           :samples => [
-            :misc_burp]},
+            :misc_burp,
+            :misc_crow,
+            :misc_cineboom]},
 
         :perc => {
           :desc => "Percussive Sounds",
@@ -5923,7 +6812,9 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
           :samples => [
             :perc_bell,
             :perc_snap,
-            :perc_snap2]},
+            :perc_snap2,
+            :perc_swash,
+            :perc_till]},
 
         :ambi => {
           :desc => "Ambient Sounds",
@@ -5953,7 +6844,7 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
             :bass_voxy_hit_c,
             :bass_dnb_f]},
 
-        :snares => {
+        :sn => {
           :desc => "Snare Drums",
           :prefix => "sn_",
           :samples => [
@@ -5961,7 +6852,7 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
             :sn_dolf,
             :sn_zome]},
 
-        :bass_drums => {
+        :bd => {
           :desc => "Bass Drums",
           :prefix => "bd_",
           :samples => [
@@ -5988,7 +6879,51 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
             :loop_amen_full,
             :loop_garzul,
             :loop_mika,
-            :loop_breakbeat]}}
+            :loop_breakbeat,
+            :loop_safari,
+            :loop_tabla]},
+
+        :tabla => {
+          :desc => "Sounds of a Tabla Drum",
+          :prefix => "tabla_",
+          :samples => [
+            :tabla_tas1,
+            :tabla_tas2,
+            :tabla_tas3,
+            :tabla_ke1,
+            :tabla_ke2,
+            :tabla_ke3,
+            :tabla_na,
+            :tabla_na_o,
+            :tabla_tun1,
+            :tabla_tun2,
+            :tabla_tun3,
+            :tabla_te1,
+            :tabla_te2,
+            :tabla_te_ne,
+            :tabla_te_m,
+            :tabla_ghe1,
+            :tabla_ghe2,
+            :tabla_ghe3,
+            :tabla_ghe4,
+            :tabla_ghe5,
+            :tabla_ghe6,
+            :tabla_ghe7,
+            :tabla_ghe8,
+            :tabla_dhec,
+            :tabla_na_s,
+            :tabla_re]},
+
+        :vinyl => {
+          :desc => "Vinyl sounds",
+          :prefix => "vinyl_",
+          :samples => [
+            :vinyl_backspin,
+            :vinyl_rewind,
+            :vinyl_scratch,
+            :vinyl_hiss]}
+        }
+
 
       @@all_samples = (@@grouped_samples.values.reduce([]) {|s, el| s << el[:samples]}).flatten
 
@@ -6005,6 +6940,7 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
         :tri => Tri.new,
         :dsaw => DSaw.new,
         :dpulse => DPulse.new,
+        :dtri => DTri.new,
         :fm => FM.new,
         :mod_fm => ModFM.new,
         :mod_saw => ModSaw.new,
@@ -6013,6 +6949,8 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
         :mod_beep => ModSine.new,
         :mod_tri => ModTri.new,
         :mod_pulse => ModPulse.new,
+        :chiplead => ChipLead.new,
+        :chipbass => ChipBass.new,
         :tb303 => TB303.new,
         :supersaw => Supersaw.new,
         :hoover => Hoover.new,
@@ -6027,13 +6965,16 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
         :stereo_player => StereoPlayer.new,
         :blade => SynthViolin.new,
         :piano => SynthPiano.new,
+        :pluck => SynthPluck.new,
 
         :sound_in => SoundIn.new,
+        :sound_in_stereo => SoundInStereo.new,
         :noise => Noise.new,
         :pnoise => PNoise.new,
         :bnoise => BNoise.new,
         :gnoise => GNoise.new,
         :cnoise => CNoise.new,
+        :chipnoise => ChipNoise.new,
 
         :basic_mono_player => BasicMonoPlayer.new,
         :basic_stereo_player => BasicStereoPlayer.new,
@@ -6046,6 +6987,7 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
         :fx_gverb => FXGVerb.new,
         :fx_replace_reverb => FXReverb.new,
         :fx_level => FXLevel.new,
+        :fx_mono => FXMono.new,
         :fx_replace_level => FXLevel.new,
         :fx_echo => FXEcho.new,
         :fx_replace_echo => FXEcho.new,
@@ -6057,6 +6999,7 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
         :fx_ixi_techno => FXIXITechno.new,
         :fx_replace_ixi_techno => FXIXITechno.new,
         :fx_compressor => FXCompressor.new,
+        :fx_whammy => FXWhammy.new,
         :fx_replace_compressor => FXCompressor.new,
         :fx_rlpf => FXRLPF.new,
         :fx_replace_rlpf => FXRLPF.new,
@@ -6089,7 +7032,8 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
         :fx_pitch_shift => FXPitchShift.new,
         :fx_ring_mod => FXRingMod.new,
         #:fx_chorus => FXChorus.new,
-        #:fx_harmoniser => FXHarmoniser.new,
+        :fx_octaver => FXOctaver.new,
+        :fx_vowel => FXVowel.new,
         :fx_flanger => FXFlanger.new
       }
 
@@ -6110,7 +7054,12 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
       end
 
       def self.all_synths
-        @@synth_infos.keys
+        @@synth_infos.select {|k, v| v.is_a?(SonicPiSynth) && v.user_facing?}.keys
+      end
+
+      def self.all_fx
+        fx = @@synth_infos.select {|k, v| v.is_a?(FXInfo) && v.user_facing? && !k.to_s.include?('replace_')}.keys
+        fx.map { |k, v| k.to_s[3..-1].to_sym }
       end
 
       def self.info_doc_html_map(klass)
@@ -6141,10 +7090,9 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
           doc << "<p><table class=\"arguments\"><tr>\n"
           cnt = 0
           v.arg_info.each do |ak, av|
-            doc << "</tr><tr>" if (cnt > 0) and cnt % 6 == 0
-            td_class = cnt.even? ? "even" : "odd"
-            doc << "<td class=\"#{td_class}\"><a href=\"##{ak}\">#{ak}:</a></td>\n"
-            doc << "<td class=\"#{td_class}\">#{av[:default]}</td>\n"
+            doc << "</tr><tr>" if (cnt > 0) and cnt % 4 == 0
+            doc << "<td class=\"even\"><a href=\"##{ak}\">#{ak}:</a></td>\n"
+            doc << "<td class=\"odd\">#{av[:default]}</td>\n"
             cnt += 1
           end
           doc << "</tr></table></p>\n\n"
@@ -6166,7 +7114,7 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
           doc << "<p class=\"introduced\">"
           doc << "Introduced in " << v.introduced.to_s << "</p>\n\n"
 
-          doc << "<h2>Parameters</h2>\n"
+          doc << "<h2>Options</h2>\n"
 
           doc << "<p><table class=\"details\">\n"
 
@@ -6184,7 +7132,7 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
             doc << "   Default: #{av[:default]}\n"
             doc << "   <br/>#{av[:constraints].join(",").capitalize}\n" unless av[:constraints].empty?
             doc << "   <br/>#{av[:modulatable] ? "May be changed whilst playing" : "Can not be changed once set"}\n"
-            doc << "   <br/><a href=\"#slide\">Has slide parameters to shape changes</a>\n" if av[:slidable]
+            doc << "   <br/><a href=\"#slide\">Has slide options to shape changes</a>\n" if av[:slidable]
             doc << "   <br/>Scaled with current BPM value\n" if av[:bpm_scale]
             doc << "  </p>\n"
             doc << " </td>\n"
@@ -6196,8 +7144,8 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
 
           if any_slidable then
             doc << "<a name=slide></a>\n"
-            doc << "<h2>Slide Parameters</h2>\n"
-            doc << "<p>Any parameter that is slidable has three additional parameters named _slide, _slide_curve, and _slide_shape.  For example, 'amp' is slidable, so you can also set amp_slide, amp_slide_curve, and amp_slide_shape with the following effects:</p>\n"
+            doc << "<h2>Slide Options</h2>\n"
+            doc << "<p>Any parameter that is slidable has three additional options named _slide, _slide_curve, and _slide_shape.  For example, 'amp' is slidable, so you can also set amp_slide, amp_slide_curve, and amp_slide_shape with the following effects:</p>\n"
             slide_args = {
               :_slide => {:default => 0, :doc=>v.generic_slide_doc('parameter')},
               :_slide_shape => {:default=>5, :doc=>v.generic_slide_shape_doc('parameter')},
@@ -6236,12 +7184,14 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
 
         get_all.each do |k, v|
           next unless v.is_a? klass
+          next if k.to_s.include? 'replace_'
           snake_case = v.name.downcase.gsub(/ /, "-")
           res << "* [#{v.name}](##{snake_case})\n"
         end
         res << "\n"
         get_all.each do |k, v|
           next unless v.is_a? klass
+          next if k.to_s.include? 'replace_'
           res << "## " << v.name << "\n\n"
           res << "### Key:\n"
           mk = key_mod ? key_mod.call(k) : k
@@ -6257,7 +7207,7 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
             res << "    - #{av[:modulatable] ? "May be changed whilst playing" : "Can not be changed once set"}\n"
             res << "    - Scaled with current BPM value\n" if av[:bpm_scale]
             res << "    - Accepts note symbols such as :e3\n" if av[:midi]
-            res << "    - Has slide parameters for shaping changes\n" if av[:slidable]
+            res << "    - Has slide options for shaping changes\n" if av[:slidable]
           end
           res << "\n\n"
 
@@ -6292,10 +7242,9 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
           doc << "<h1>" << v[:desc] << "</h1>\n"
           doc << "<p><table class=\"arguments\"><tr>\n"
           StereoPlayer.new.arg_info.each do |ak, av|
-            doc << "</tr><tr>" if (cnt > 0) and cnt % 6 == 0
-            td_class = cnt.even? ? "even" : "odd"
-            doc << "<td class=\"#{td_class}\"><a href=\"##{ak}\">#{ak}:</a></td>\n"
-            doc << "<td class=\"#{td_class}\">#{av[:default]}</td>\n"
+            doc << "</tr><tr>" if (cnt > 0) and cnt % 4 == 0
+            doc << "<td class=\"even\"><a href=\"##{ak}\">#{ak}:</a></td>\n"
+            doc << "<td class=\"odd\">#{av[:default]}</td>\n"
             cnt += 1
           end
           doc << "</tr></table></p>\n"
@@ -6311,11 +7260,10 @@ Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a gi
 
           cnt = 0
           StereoPlayer.new.arg_info.each do |ak, av|
-            td_class = cnt.even? ? "even" : "odd"
             doc << "<a name=\"#{ak}\"></a>\n"
             doc << "<tr>\n"
-            doc << " <td class=\"#{td_class} key\">#{ak}:</td>\n"
-            doc << " <td class=\"#{td_class}\">\n"
+            doc << " <td class=\"even key\">#{ak}:</td>\n"
+            doc << " <td class=\"odd\">\n"
             doc << "  <p>#{av[:doc] || 'write me'}</p>\n"
             doc << "  <p class=\"properties\">\n"
             doc << "   Default: #{av[:default]}\n"
diff --git a/app/server/sonicpi/lib/sonicpi/synthtracker.rb b/app/server/sonicpi/lib/sonicpi/synthtracker.rb
index a9601f2..87e75ce 100644
--- a/app/server/sonicpi/lib/sonicpi/synthtracker.rb
+++ b/app/server/sonicpi/lib/sonicpi/synthtracker.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/tuning.rb b/app/server/sonicpi/lib/sonicpi/tuning.rb
index 6e779d2..7020eaa 100644
--- a/app/server/sonicpi/lib/sonicpi/tuning.rb
+++ b/app/server/sonicpi/lib/sonicpi/tuning.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -95,11 +95,11 @@ module SonicPi
     end
 
     def midi_to_hz(n)
-      440.0 * (2 ** ((n - 69) / 12.0))
+      (440.0 * (2 ** ((n - 69) / 12.0))).round(9)
     end
 
     def hz_to_midi(freq)
-      (12 * (Math.log(freq * 0.0022727272727) / Math.log(2))) + 69
+      ((12 * (Math.log(freq * 0.0022727272727) / Math.log(2))) + 69).round(9)
     end
 
     private
diff --git a/app/server/sonicpi/lib/sonicpi/util.rb b/app/server/sonicpi/lib/sonicpi/util.rb
index fb75765..3dd9285 100644
--- a/app/server/sonicpi/lib/sonicpi/util.rb
+++ b/app/server/sonicpi/lib/sonicpi/util.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -16,13 +16,43 @@ require 'securerandom'
 
 module SonicPi
   module Util
+    @@safe_mode = false
     @@tilde_dir = Dir.home
     @@project_path = nil
     @@log_path = nil
     @@current_uuid = nil
     @@home_dir = nil
     @@util_lock = Mutex.new
-    @@raspberry_pi_1 = RUBY_PLATFORM.match(/.*arm.*-linux.*/) && File.exists?('/proc/cpuinfo') && !(`cat /proc/cpuinfo | grep ARMv6`.empty?)
+    @@raspberry_pi_1 = RUBY_PLATFORM.match(/.*arm.*-linux.*/) && File.exists?('/proc/cpuinfo') && !(`cat /proc/cpuinfo | grep BCM2708`).empty?
+    @@raspberry_pi_2 = RUBY_PLATFORM.match(/.*arm.*-linux.*/) && File.exists?('/proc/cpuinfo') && !(`cat /proc/cpuinfo | grep BCM2709`).empty? && (`cat /proc/cpuinfo | grep crc32`).empty?
+    @@raspberry_pi_3 = RUBY_PLATFORM.match(/.*arm.*-linux.*/) && File.exists?('/proc/cpuinfo') && !(`cat /proc/cpuinfo | grep BCM2709`).empty? && !(`cat /proc/cpuinfo | grep crc32`).empty?
+
+    @@home_dir = File.expand_path((ENV['SONIC_PI_HOME'] || Dir.home) + '/.sonic-pi/')
+    @@project_path = @@home_dir + '/store/default/'
+    @@log_path = @@home_dir + '/log/'
+
+    [@@home_dir, @@project_path, @@log_path].each do |dir|
+
+      begin
+        FileUtils.mkdir_p(dir) unless File.exists?(dir)
+      rescue
+        @@safe_mode = true
+        STDERR.puts "Unable to create #{dir} due to permissions errors"
+      end
+    end
+
+    begin
+      @@log_file = File.open("#{@@log_path}/debug.log", 'w')
+    rescue
+      @@safe_mode = true
+      STDERR.puts "Unable to open log file #{@@log_path}/debug.log"
+      @@log_file = nil
+    end
+
+
+    at_exit do
+      @@log_file.close if @@log_file
+    end
 
     def os
       case RUBY_PLATFORM
@@ -39,12 +69,20 @@ module SonicPi
       end
     end
 
+    def raspberry_pi?
+      os == :raspberry
+    end
+
     def raspberry_pi_1?
       os == :raspberry && @@raspberry_pi_1
     end
 
     def raspberry_pi_2?
-      os == :raspberry && !@@raspberry_pi_1
+      os == :raspberry && @@raspberry_pi_2
+    end
+
+    def raspberry_pi_3?
+      os == :raspberry && @@raspberry_pi_3
     end
 
     def unify_tilde_dir(path)
@@ -61,10 +99,10 @@ module SonicPi
     end
 
     def default_sched_ahead_time
-      if (os == :raspberry)
+      if raspberry_pi_1?
         1
       else
-        0.2
+        0.5
       end
     end
 
@@ -72,9 +110,13 @@ module SonicPi
       case os
       when :raspberry
         if raspberry_pi_1?
-          "Raspberry Pi"
-        else
+          "Raspberry Pi 1"
+        elsif raspberry_pi_2?
           "Raspberry Pi 2"
+        elsif raspberry_pi_3?
+          "Raspberry Pi 3"
+        else
+          "Raspberry Pi"
         end
       when :linux
         "Linux"
@@ -86,24 +128,19 @@ module SonicPi
     end
 
     def default_control_delta
-      if raspberry_pi_1?
-        0.02
-      elsif raspberry_pi_2?
-        0.013
+      if raspberry_pi?
+        if raspberry_pi_1?
+          0.02
+        else
+          0.013
+        end
       else
         0.005
       end
     end
 
     def home_dir
-      return @@home_dir if @@home_dir
-      @@util_lock.synchronize do
-        return @@home_dir if @@home_dir
-        path = File.expand_path((ENV['SONIC_PI_HOME'] || Dir.home) + '/.sonic-pi/')
-        ensure_dir(path)
-        @@home_dir = path
-        path
-      end
+      @@home_dir
     end
 
     def init_path
@@ -111,26 +148,11 @@ module SonicPi
     end
 
     def project_path
-      return @@project_path if @@project_path
-      @@util_lock.synchronize do
-        return @@project_path if @@project_path
-        ## TODO: allow user to modify this for different projects
-        path = home_dir + '/store/default/'
-        ensure_dir(path)
-        @@project_path = path
-        path
-      end
+      @@project_path
     end
 
     def log_path
-      return @@log_path if @@log_path
-      @@util_lock.synchronize do
-        return @@log_path if @@log_path
-        path = home_dir + '/log/'
-        ensure_dir(path)
-        @@log_path = path
-        path
-      end
+      @@log_path
     end
 
     def global_uuid
@@ -150,14 +172,32 @@ module SonicPi
 
         # invalid or no uuid - create and store a new one
         new_uuid = SecureRandom.uuid
-        File.open(path, 'w') {|f| f.write(new_uuid)}
+        begin
+          File.open(path, 'w') {|f| f.write(new_uuid)}
+        rescue
+          @@safe_mode = true
+          log "Unable to write uuid file to #{path}"
+        end
         @@current_uuid = new_uuid
         new_uuid
       end
     end
 
     def ensure_dir(d)
-      FileUtils.mkdir_p(d) unless File.exists?(d)
+      begin
+        FileUtils.mkdir_p(dir) unless File.exists?(dir)
+      rescue
+        @@safe_mode = true
+        log "Unable to create #{dir} due to permissions errors"
+      end
+    end
+
+    def linux_fhs?
+      # use FHS directory scheme:
+      # check if Sonic Pi's ruby server is not running inside the
+      # user's home directory, but is installed in /usr/lib/sonic-pi
+      # on Linux from a distribution's package
+      File.dirname(__FILE__).start_with?("/usr/lib/sonic-pi")
     end
 
     def root_path
@@ -169,11 +209,15 @@ module SonicPi
     end
 
     def snippets_path
-      File.absolute_path("#{etc_path}/snippets")
+      linux_fhs? ?
+        File.absolute_path("/usr/share/sonic-pi/snippets") :
+        File.absolute_path("#{etc_path}/snippets")
     end
 
     def doc_path
-      File.absolute_path("#{etc_path}/doc")
+      linux_fhs? ?
+        File.absolute_path("/usr/share/doc/sonic-pi") :
+        File.absolute_path("#{etc_path}/doc")
     end
 
     def cheatsheets_path
@@ -185,19 +229,27 @@ module SonicPi
     end
 
     def tmp_path
-      File.absolute_path("#{root_path}/tmp")
+      linux_fhs? ?
+        File.absolute_path("/tmp") :
+        File.absolute_path("#{root_path}/tmp")
     end
 
     def synthdef_path
-      File.absolute_path("#{etc_path}/synthdefs/compiled")
+      linux_fhs? ?
+        File.absolute_path("/usr/share/sonic-pi/synthdefs/compiled") :
+        File.absolute_path("#{etc_path}/synthdefs/compiled")
     end
 
     def samples_path
-      File.absolute_path("#{etc_path}/samples")
+      linux_fhs? ?
+        File.absolute_path("/usr/share/sonic-pi/samples") :
+        File.absolute_path("#{etc_path}/samples")
     end
 
     def buffers_path
-      File.absolute_path("#{etc_path}/buffers")
+      linux_fhs? ?
+        File.absolute_path("/usr/share/sonic-pi/buffers") :
+        File.absolute_path("#{etc_path}/buffers")
     end
 
     def app_path
@@ -243,9 +295,12 @@ module SonicPi
     end
 
     def log_raw(s)
-        # TODO: consider moving this into a worker thread to reduce file
-        # io overhead:
-      File.open("#{log_path}/debug.log", 'a') {|f| f.write("[#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}] #{s}")}
+      if @@log_file
+        @@log_file.write("[#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}] #{s}")
+        @@log_file.flush
+      else
+        Kernel.puts("[#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}] #{s}")
+      end
     end
 
     def log_exception(e, context="")
@@ -267,6 +322,7 @@ module SonicPi
     def log(message)
       if debug_mode
         res = ""
+        res << "\n" if message.empty?
         first = true
         while !(message.empty?)
           if first
@@ -277,7 +333,6 @@ module SonicPi
             res << "                                        "
             res << message.slice!(0..133)
             res << "\n"
-
           end
         end
         log_raw res
@@ -322,18 +377,27 @@ module SonicPi
       return res if idx == size
       left = (opts_a[idx..-1])
       raise "There must be an even number of trailing synth args" unless left.size.even?
-      res.merge(Hash[*left])
+      h = Hash[*left]
+      res.merge()
+    end
+
+    def purge_nil_vals!(m)
+      m.delete_if { |k, v| v.nil? }
     end
 
     def arg_h_pp(arg_h)
       s = "{"
       arg_h.each do |k, v|
-        rounded = v.is_a?(Float) ? v.round(4) : v.inspect
-        s << "#{k}: #{rounded}, "
+        if v
+          rounded = v.is_a?(Float) ? v.round(4) : v.inspect
+          s << "#{k}: #{rounded}, "
+        end
       end
       s.chomp(", ") << "}"
     end
 
-
+    def safe_mode?
+      @@safe_mode
+    end
   end
 end
diff --git a/app/server/sonicpi/lib/sonicpi/version.rb b/app/server/sonicpi/lib/sonicpi/version.rb
index 7934229..ab92279 100644
--- a/app/server/sonicpi/lib/sonicpi/version.rb
+++ b/app/server/sonicpi/lib/sonicpi/version.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/lib/sonicpi/wrappingarray.rb b/app/server/sonicpi/lib/sonicpi/wrappingarray.rb
index 7851725..4288662 100644
--- a/app/server/sonicpi/lib/sonicpi/wrappingarray.rb
+++ b/app/server/sonicpi/lib/sonicpi/wrappingarray.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/fake_built_in_sample_dir/beans.flac b/app/server/sonicpi/test/fake_built_in_sample_dir/beans.flac
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/sonicpi/test/fake_built_in_sample_dir/foo.wav b/app/server/sonicpi/test/fake_built_in_sample_dir/foo.wav
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/sonicpi/test/fake_built_in_sample_dir/quux.wav b/app/server/sonicpi/test/fake_built_in_sample_dir/quux.wav
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/sonicpi/test/fake_sample_dir/a_text_file.txt b/app/server/sonicpi/test/fake_sample_dir/a_text_file.txt
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/sonicpi/test/fake_sample_dir/bar_baz.aiff b/app/server/sonicpi/test/fake_sample_dir/bar_baz.aiff
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/sonicpi/test/fake_sample_dir/buzz_100.flac b/app/server/sonicpi/test/fake_sample_dir/buzz_100.flac
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/sonicpi/test/fake_sample_dir/eggs.wav b/app/server/sonicpi/test/fake_sample_dir/eggs.wav
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/sonicpi/test/fake_sample_dir/first_foo.wav b/app/server/sonicpi/test/fake_sample_dir/first_foo.wav
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/sonicpi/test/fake_sample_dir/foo.wav b/app/server/sonicpi/test/fake_sample_dir/foo.wav
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/sonicpi/test/fake_sample_dir/subdir/quux.wav b/app/server/sonicpi/test/fake_sample_dir/subdir/quux.wav
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/sonicpi/test/fake_sample_dir/woo_100.aiff b/app/server/sonicpi/test/fake_sample_dir/woo_100.aiff
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/sonicpi/test/fake_sample_dir/xylophone-test-samp.wave b/app/server/sonicpi/test/fake_sample_dir/xylophone-test-samp.wave
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/sonicpi/test/lang/core/test_chance.rb b/app/server/sonicpi/test/lang/core/test_chance.rb
index bcb7358..356b15c 100644
--- a/app/server/sonicpi/test/lang/core/test_chance.rb
+++ b/app/server/sonicpi/test/lang/core/test_chance.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/lang/core/test_quantise.rb b/app/server/sonicpi/test/lang/core/test_quantise.rb
index 8dbca9f..b43753b 100644
--- a/app/server/sonicpi/test/lang/core/test_quantise.rb
+++ b/app/server/sonicpi/test/lang/core/test_quantise.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/lang/core/test_spark.rb b/app/server/sonicpi/test/lang/core/test_spark.rb
index e62734f..4a308b1 100644
--- a/app/server/sonicpi/test/lang/core/test_spark.rb
+++ b/app/server/sonicpi/test/lang/core/test_spark.rb
@@ -4,7 +4,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/lang/core/test_tick.rb b/app/server/sonicpi/test/lang/core/test_tick.rb
index a57f64f..003ce5a 100644
--- a/app/server/sonicpi/test/lang/core/test_tick.rb
+++ b/app/server/sonicpi/test/lang/core/test_tick.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/lang/sound/test_invert_chord.rb b/app/server/sonicpi/test/lang/sound/test_invert_chord.rb
index 2aa9982..57062a0 100644
--- a/app/server/sonicpi/test/lang/sound/test_invert_chord.rb
+++ b/app/server/sonicpi/test/lang/sound/test_invert_chord.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/lang/sound/test_note.rb b/app/server/sonicpi/test/lang/sound/test_note.rb
index 585cbbe..1060852 100644
--- a/app/server/sonicpi/test/lang/sound/test_note.rb
+++ b/app/server/sonicpi/test/lang/sound/test_note.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/lang/sound/test_note_info.rb b/app/server/sonicpi/test/lang/sound/test_note_info.rb
index 6f916f0..b761225 100644
--- a/app/server/sonicpi/test/lang/sound/test_note_info.rb
+++ b/app/server/sonicpi/test/lang/sound/test_note_info.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/lang/sound/test_note_range.rb b/app/server/sonicpi/test/lang/sound/test_note_range.rb
index bea3f9d..c13fa55 100644
--- a/app/server/sonicpi/test/lang/sound/test_note_range.rb
+++ b/app/server/sonicpi/test/lang/sound/test_note_range.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/lang/sound/test_play.rb b/app/server/sonicpi/test/lang/sound/test_play.rb
index 547c2be..45e93bc 100644
--- a/app/server/sonicpi/test/lang/sound/test_play.rb
+++ b/app/server/sonicpi/test/lang/sound/test_play.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -28,6 +28,7 @@ module SonicPi
       @mock_sound.stubs(:ensure_good_timing!) # avoid loading Spider class
       @mock_sound.stubs(:__delayed_user_message)
       @mock_sound.stubs(:current_synth_name).returns(:beep)
+      @mock_sound.send(:init_tuning)
     end
 
     def test_play_with_various_args
@@ -38,13 +39,38 @@ module SonicPi
       @mock_sound.play :c, release: 0.1
 
       # Single hash
-      @mock_sound.expects(:trigger_inst).with(:beep, {note: :c, release: 0.1})
+      @mock_sound.expects(:trigger_inst).with(:beep, {note: 60, release: 0.1})
       @mock_sound.play({note: :c, release: 0.1})
 
-      # Hash and args
-      @mock_sound.expects(:trigger_inst).with(:beep, {note: :c, amp: 1, release: 0.1})
-      @mock_sound.play({note: :c, amp: 1}, {release: 0.1})
+      # nils are culled (but only prior to encoding as an OSC message)
+      @mock_sound.expects(:trigger_inst).with(:beep, {note: 60, cutoff: nil})
+      @mock_sound.play({note: :c, cutoff: nil})
     end
 
+    def test_multi_notes
+      @mock_sound.expects(:trigger_chord).with(:beep, [62.0], {})
+      @mock_sound.play [62]
+    end
+
+    def test_note_with_tuning
+      @mock_sound.expects(:trigger_inst).with(:beep, {note: 62.039100017})
+      @mock_sound.with_tuning :just do
+        @mock_sound.play 62
+      end
+    end
+
+    def test_chord_with_tuning
+      @mock_sound.expects(:trigger_chord).with(:beep, [62.039100017], {})
+      @mock_sound.with_tuning :just do
+        @mock_sound.play [62]
+      end
+    end
+
+    def test_play_chord_with_tuning
+      @mock_sound.expects(:trigger_chord).with(:beep, [62.039100017], {})
+      @mock_sound.with_tuning :just do
+        @mock_sound.play_chord [62]
+      end
+    end
   end
 end
diff --git a/app/server/sonicpi/test/lang/sound/test_play_nested_pattern.rb b/app/server/sonicpi/test/lang/sound/test_play_nested_pattern.rb
index 3c5c967..ccc0a25 100644
--- a/app/server/sonicpi/test/lang/sound/test_play_nested_pattern.rb
+++ b/app/server/sonicpi/test/lang/sound/test_play_nested_pattern.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/lang/sound/test_sample.rb b/app/server/sonicpi/test/lang/sound/test_sample.rb
index 08e98a1..5c0910a 100644
--- a/app/server/sonicpi/test/lang/sound/test_sample.rb
+++ b/app/server/sonicpi/test/lang/sound/test_sample.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -16,37 +16,51 @@ require_relative "../../../lib/sonicpi/atom"
 require_relative "../../../lib/sonicpi/buffer"
 require_relative "../../../lib/sonicpi/lang/core"
 require_relative "../../../lib/sonicpi/lang/sound"
+require_relative "../../../lib/sonicpi/synths/synthinfo"
 require 'mocha/setup'
 require 'ostruct'
 
 module SonicPi
   class SampleTester < Minitest::Test
+    class MockStudio
+      def initialize
+        @mod_sound_studio = Object.new
+        @mod_sound_studio.stubs(:sample_loaded?).returns(true)
+      end
+    end
+
     def setup
-      @mock_sound = Object.new
+      @mock_sound = MockStudio.new
       @mock_sound.extend(Lang::Sound)
       @mock_sound.extend(Lang::Core)
       @mock_sound.stubs(:sleep) # avoid loading Spider class
       @mock_sound.stubs(:ensure_good_timing!) # avoid loading Spider class
-      @mock_sound.stubs(:load_sample).returns(OpenStruct.new({id: 42, num_chans: 2}))
+      @mock_sound.stubs(:sample_loaded?).returns(true)
+      @mock_sound.stubs(:__delayed_user_message).returns(true)
+      @mock_sound.stubs(:sample_find_candidates).returns(["/foo/bar.wav"])
+      @mock_sound.stubs(:load_sample_at_path).returns(OpenStruct.new({id: 42, num_chans: 2}))
+      @info = Synths::SynthInfo.get_info(:stereo_player)
     end
 
     def test_sample_with_various_args
-      @mock_sound.expects(:trigger_sampler).with(:loop_amen, 42, 2, {})
+      @mock_sound.expects(:trigger_sampler).with("/foo/bar.wav",  {})
       @mock_sound.sample :loop_amen
 
-      @mock_sound.expects(:trigger_sampler).with(:loop_amen, 42, 2, {rate: 2})
+      @mock_sound.expects(:trigger_sampler).with("/foo/bar.wav", {rate: 2})
       @mock_sound.sample :loop_amen, rate: 2
 
-      @mock_sound.expects(:trigger_sampler).with(:loop_amen, 42, 2, {rate: 2})
-      @mock_sound.sample lambda { :loop_amen }, rate: 2
+      # # This works in the codebase, but need to figure out a nice way of
+      # # testing it...
+      # # @mock_sound.expects(:trigger_sampler).with(:loop_amen, 42, 2, {rate: 2})
+      # # @mock_sound.sample lambda { :loop_amen }, rate: 2
 
-      # Single hash
-      @mock_sound.expects(:trigger_sampler).with(:loop_amen, 42, 2, {rate: 2})
-      @mock_sound.sample name: :loop_amen, rate: 2
+      #Single hash
+      @mock_sound.expects(:trigger_sampler).with("/foo/bar.wav", {rate: 2})
+      @mock_sound.sample sample_name: :loop_amen, rate: 2
 
       # Hash and args
-      @mock_sound.expects(:trigger_sampler).with(:loop_amen, 42, 2, {rate: 2})
-      @mock_sound.sample({name: :loop_amen}, {rate: 2})
+      @mock_sound.expects(:trigger_sampler).with("/foo/bar.wav", {rate: 2})
+      @mock_sound.sample({sample_name: :loop_amen}, {rate: 2})
     end
 
   end
diff --git a/app/server/sonicpi/test/lang/sound/test_sample_duration.rb b/app/server/sonicpi/test/lang/sound/test_sample_duration.rb
index 25e515d..ce334af 100644
--- a/app/server/sonicpi/test/lang/sound/test_sample_duration.rb
+++ b/app/server/sonicpi/test/lang/sound/test_sample_duration.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -13,16 +13,18 @@
 
 require_relative "../../setup_test"
 require_relative "../../../lib/sonicpi/util"
-require_relative "../../../lib/sonicpi/lang/sound"
+require_relative "../../../lib/sonicpi/sample_loader"
 
 module SonicPi
   module Lang
     module Sound
       module_function :sample_duration
       module_function :pitch_to_ratio
+      module_function :sample_split_filts_and_opts
+
 
       # mock out load_sample to always return a sample with duration 8
-      def self.load_sample(path)
+      def self.load_sample_at_path(path)
         mock_samp = Struct.new(:duration)
         mock_samp.new(8)
       end
@@ -31,6 +33,10 @@ module SonicPi
       def self.current_bpm
         60
       end
+
+      def self.resolve_sample_path(*args)
+        "/foo/bar"
+      end
     end
   end
 
diff --git a/app/server/sonicpi/test/lang/sound/test_sample_loader.rb b/app/server/sonicpi/test/lang/sound/test_sample_loader.rb
new file mode 100644
index 0000000..537bda7
--- /dev/null
+++ b/app/server/sonicpi/test/lang/sound/test_sample_loader.rb
@@ -0,0 +1,233 @@
+#--
+# This file is part of Sonic Pi: http://sonic-pi.net
+# Full project source: https://github.com/samaaron/sonic-pi
+# License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+#
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+# All rights reserved.
+#
+# Permission is granted for use, copying, modification, and
+# distribution of modified versions of this work as long as this
+# notice is included.
+#++
+
+require_relative "../../setup_test"
+require_relative "../../../lib/sonicpi/sample_loader"
+
+module SonicPi
+  class SampleLoaderTester < Minitest::Test
+    def setup
+      @fake_built_in_sample_dir = File.expand_path("#{File.dirname(__FILE__)}../../../fake_built_in_sample_dir")
+      # Contains:
+      # - beans.flac
+      # - foo.wav
+      # - quux.wav
+
+      @fake_sample_dir = File.expand_path("#{File.dirname(__FILE__)}../../../fake_sample_dir")
+      # Contains:
+      # -  a_text_file.txt
+      # -  bar_baz.aiff
+      # -  buzz_100.flac
+      # -  eggs.wav
+      # -  first_foo.wav
+      # -  foo.wav
+      # -  woo_100.aiff
+      # -  xylophone-test-samp.wave
+      # -  subdir
+      #    |
+      #    - quux.wav
+      @loader = SampleLoader.new(@fake_sample_dir)
+      @loader.stubs(:default_samples_paths).returns([@fake_built_in_sample_dir])
+    end
+
+    def test_ls_candidates
+      files = [
+        @fake_built_in_sample_dir + "/beans.flac",
+        @fake_built_in_sample_dir + "/foo.wav",
+        @fake_built_in_sample_dir + "/quux.wav"]
+
+      assert_equal(@loader.ls_samples(@fake_built_in_sample_dir), files)
+      # test cache
+      assert_equal(@loader.ls_samples(@fake_built_in_sample_dir), files)
+    end
+
+    def test_split_candidates_and_filts_simple
+      filts_and_sources = [@fake_sample_dir, 1]
+      candidates, filts = @loader.split_candidates_and_filts(filts_and_sources)
+      assert_equal([@fake_sample_dir], candidates)
+      assert_equal([1], filts)
+    end
+
+    def test_split_candidates_and_filts_no_filts
+      filts_and_sources = [@fake_sample_dir]
+      candidates, filts = @loader.split_candidates_and_filts(filts_and_sources)
+      assert_equal([@fake_sample_dir], candidates)
+      assert_equal([], filts)
+    end
+
+    def test_split_candidates_and_filts_multi_candidates_no_filts
+      filts_and_sources = [@fake_sample_dir, @fake_sample_dir + "/eggs.wav"]
+      candidates, filts = @loader.split_candidates_and_filts(filts_and_sources)
+      assert_equal([@fake_sample_dir, @fake_sample_dir + "/eggs.wav"], candidates)
+      assert_equal([], filts)
+    end
+
+    def test_split_candidates_and_filts_no_candidates_no_filts
+      filts_and_sources = []
+      candidates, filts = @loader.split_candidates_and_filts(filts_and_sources)
+      assert_equal([], candidates)
+      assert_equal([], filts)
+    end
+
+    def test_split_candidates_and_filts_no_candidates_one_filt
+      filts_and_sources = [:foo]
+      candidates, filts = @loader.split_candidates_and_filts(filts_and_sources)
+      assert_equal([], candidates)
+      assert_equal([:foo], filts)
+    end
+
+    def test_split_candidates_and_filts_no_candidates_one_filt2
+      filts_and_sources = [:woo_100]
+      candidates, filts = @loader.split_candidates_and_filts(filts_and_sources)
+      assert_equal([], candidates)
+      assert_equal([:woo_100], filts)
+    end
+
+    def test_split_candidates_and_filts_no_candidates_one_string_filt
+      filts_and_sources = ["foobar"]
+      candidates, filts = @loader.split_candidates_and_filts(filts_and_sources)
+      assert_equal([], candidates)
+      assert_equal(["foobar"], filts)
+    end
+
+    def test_split_candidates_and_filts_no_candidates_multi_filts
+      filts_and_sources = ["foobar", 1, :foo, /bar/]
+      candidates, filts = @loader.split_candidates_and_filts(filts_and_sources)
+      assert_equal([], candidates)
+      assert_equal(["foobar", 1, :foo, /bar/], filts)
+    end
+
+    def test_split_candidates_and_filts_glob_candidate
+      filts_and_sources = [@fake_sample_dir + "/**"]
+      candidates, filts = @loader.split_candidates_and_filts(filts_and_sources)
+      assert_equal([@fake_sample_dir + "/**"], candidates)
+      assert_equal([], filts)
+    end
+
+    def test_single_builtin_symbol
+      res = @loader.find_candidates([:beans])
+      assert_equal(res, ["#{@fake_built_in_sample_dir}/beans.flac"])
+    end
+
+    def test_single_builtin_symbol_cache
+      res = @loader.find_candidates([:foo])
+      assert_equal(res, ["#{@fake_built_in_sample_dir}/foo.wav"])
+      res = @loader.find_candidates([:foo])
+      assert_equal(res, ["#{@fake_built_in_sample_dir}/foo.wav"])
+      res = @loader.find_candidates([:foo])
+      assert_equal(res, ["#{@fake_built_in_sample_dir}/foo.wav"])
+      res = @loader.find_candidates([:quux])
+      assert_equal(res, ["#{@fake_built_in_sample_dir}/quux.wav"])
+      res = @loader.find_candidates([:quux])
+      assert_equal(res, ["#{@fake_built_in_sample_dir}/quux.wav"])
+    end
+
+    def test_path_and_symbol_does_not_include_builtin_samples
+      res = @loader.find_candidates([@fake_sample_dir, :foo])
+      refute_includes(res, "#{@fake_built_in_sample_dir}/foo.wav")
+    end
+
+
+    def test_globs_count
+      res = @loader.find_candidates(["#{@fake_sample_dir}/**"])
+      assert_equal(res.count, 8)
+    end
+
+    def test_non_globs_count
+      res = @loader.find_candidates([@fake_sample_dir])
+      assert_equal(res.count, 7)
+    end
+
+    def test_globs_filt
+      res = @loader.find_candidates(["#{@fake_sample_dir}/**", :quux])
+      assert_equal(["#{@fake_sample_dir}/subdir/quux.wav"], res)
+    end
+
+    def test_non_globs_filt_does_not_include_subdir
+      res = @loader.find_candidates([@fake_sample_dir, :quux])
+      assert_equal([], res)
+    end
+
+    def test_non_globs_symbol_matches_name_exactly
+      res = @loader.find_candidates([@fake_sample_dir, :foo])
+      assert_equal(res, ["#{@fake_sample_dir}/foo.wav"])
+    end
+
+    def test_idx
+      res = @loader.find_candidates([@fake_sample_dir, 1])
+      assert_equal(["#{@fake_sample_dir}/buzz_100.flac"], res)
+    end
+
+    def test_mult_idx_overrides
+      res = @loader.find_candidates([@fake_sample_dir, 1, 3, 5, 1])
+      assert_equal(["#{@fake_sample_dir}/buzz_100.flac"], res)
+    end
+
+    def test_idx_wrap
+      res = @loader.find_candidates([@fake_sample_dir, 7])
+      assert_equal(["#{@fake_sample_dir}/bar_baz.aiff"], res)
+    end
+
+    def test_glob_idx_wrap
+      res = @loader.find_candidates([@fake_sample_dir + "/**", 8])
+      assert_equal(["#{@fake_sample_dir}/bar_baz.aiff"], res)
+    end
+
+    def test_str_filter
+      res = @loader.find_candidates([@fake_sample_dir, "100"])
+      assert_equal(["#{@fake_sample_dir}/buzz_100.flac",
+                    "#{@fake_sample_dir}/woo_100.aiff"], res)
+    end
+
+    def test_regex_filter
+      res = @loader.find_candidates([@fake_sample_dir, /b[uU]zz/])
+      assert_equal(["#{@fake_sample_dir}/buzz_100.flac"], res)
+    end
+
+    def test_1_arity_proc_filter
+      proc = lambda {|c| c.keep_if { |v| v.include? "foo"}}
+      res = @loader.find_candidates([@fake_sample_dir, proc])
+      assert_equal(["#{@fake_sample_dir}/first_foo.wav",
+                    "#{@fake_sample_dir}/foo.wav"], res)
+    end
+
+    def test_multi_filters
+      identity_proc = lambda {|c| c }
+      res = @loader.find_candidates([@fake_sample_dir, identity_proc, "100", /100/, 1])
+      assert_equal(["#{@fake_sample_dir}/woo_100.aiff"], res)
+    end
+
+    def test_multi_filters_with_nil
+      identity_proc = lambda {|c| c }
+      res = @loader.find_candidates([@fake_sample_dir, nil, identity_proc, "100", /100/, nil, 1])
+      assert_equal(["#{@fake_sample_dir}/woo_100.aiff"], res)
+    end
+
+    def test_arrays
+      identity_proc = lambda {|c| c }
+      res = @loader.find_candidates([@fake_sample_dir, [[identity_proc, "100"], /100/], [1]])
+      assert_equal(["#{@fake_sample_dir}/woo_100.aiff"], res)
+    end
+
+    def test_string_filtering_with_hyphens
+      res = @loader.find_candidates([@fake_sample_dir, "xylophone-"])
+      assert_equal(["#{@fake_sample_dir}/xylophone-test-samp.wave"], res)
+    end
+
+    def test_empty_strings_dont_filter
+      res = @loader.find_candidates([@fake_sample_dir, "", "xylophone-", "", ""])
+      assert_equal(["#{@fake_sample_dir}/xylophone-test-samp.wave"], res)
+    end
+
+  end
+end
diff --git a/app/server/sonicpi/test/lang/sound/test_sound.rb b/app/server/sonicpi/test/lang/sound/test_sound.rb
new file mode 100644
index 0000000..ae746ef
--- /dev/null
+++ b/app/server/sonicpi/test/lang/sound/test_sound.rb
@@ -0,0 +1,68 @@
+#--
+# This file is part of Sonic Pi: http://sonic-pi.net
+# Full project source: https://github.com/samaaron/sonic-pi
+# License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+#
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+# All rights reserved.
+#
+# Permission is granted for use, copying, modification, and
+# distribution of modified versions of this work as long as this
+# notice is included.
+#++
+
+require_relative "../../setup_test"
+require_relative "../../../lib/sonicpi/lang/sound"
+
+module SonicPi
+  class SoundTester < Minitest::Test
+    
+    def setup
+      @mock_sound = Object.new
+      @mock_sound.extend(Lang::Sound)
+    end
+    
+    def test_rest
+      assert_equal(false, @mock_sound.rest?(1))
+      
+      assert_equal(true, @mock_sound.rest?(:rest))
+      assert_equal(true, @mock_sound.rest?(:r))
+      assert_equal(false, @mock_sound.rest?(:norest))
+      
+      assert_equal(true, @mock_sound.rest?(nil))
+      
+      assert_equal(false, @mock_sound.rest?(Hash.new))
+      
+      assert_equal(false, @mock_sound.rest?("a string"))
+    end
+    
+    def test_truthy
+      assert_equal(false, @mock_sound.truthy?(0))
+      assert_equal(true, @mock_sound.truthy?(1))
+      assert_equal(true, @mock_sound.truthy?(-1))    
+      assert_equal(true, @mock_sound.truthy?(0.01))
+      
+      assert_equal(false, @mock_sound.truthy?(nil))
+      
+      assert_equal(true, @mock_sound.truthy?(true))
+      assert_equal(false, @mock_sound.truthy?(false))
+      
+      proc = Proc.new {true}
+      assert_equal(true, @mock_sound.truthy?(proc))
+    end
+    
+    def test_should_trigger
+      h = {on: true, a: 123, c: "d"}
+      assert_equal(true, @mock_sound.should_trigger?(h))
+      assert_equal(false, h.has_key?(:on))
+      
+      h = {on: false, a: 123, c: "d"}
+      assert_equal(false, @mock_sound.should_trigger?(h))
+      assert_equal(false, h.has_key?(:on))
+      
+      h = {a: 123, c: "d"}
+      assert_equal(true, @mock_sound.should_trigger?(h))
+    end
+  
+  end
+end
diff --git a/app/server/sonicpi/test/performance/test_osc_perf.rb b/app/server/sonicpi/test/performance/test_osc_perf.rb
index 4c45ea2..f705b49 100644
--- a/app/server/sonicpi/test/performance/test_osc_perf.rb
+++ b/app/server/sonicpi/test/performance/test_osc_perf.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/test_chord.rb b/app/server/sonicpi/test/test_chord.rb
index 66cd452..74cf6f6 100644
--- a/app/server/sonicpi/test/test_chord.rb
+++ b/app/server/sonicpi/test/test_chord.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/test_note.rb b/app/server/sonicpi/test/test_note.rb
index c111794..f031cc6 100644
--- a/app/server/sonicpi/test/test_note.rb
+++ b/app/server/sonicpi/test/test_note.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/test_osc.rb b/app/server/sonicpi/test/test_osc.rb
index d2576d1..4231be0 100644
--- a/app/server/sonicpi/test/test_osc.rb
+++ b/app/server/sonicpi/test/test_osc.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/test_preparser.rb b/app/server/sonicpi/test/test_preparser.rb
index 256820d..25adb23 100644
--- a/app/server/sonicpi/test/test_preparser.rb
+++ b/app/server/sonicpi/test/test_preparser.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -23,7 +23,31 @@ module SonicPi
 
     def test_basic_ring_change
       a = "(ring 50, 60, 70)"
-      b = "ring( 50, 60, 70)"
+      b = " ring(50, 60, 70)"
+      assert_equal(b, PreParser.preparse(a))
+    end
+
+    def test_basic_ring_change_with_leading_space
+      a = "(  ring 50, 60, 70)"
+      b = "   ring(50, 60, 70)"
+      assert_equal(b, PreParser.preparse(a))
+    end
+
+    def test_basic_rings_with_commas
+      a = "(ring, 50, 60, 70)"
+      b = " ring( 50, 60, 70)"
+      assert_equal(b, PreParser.preparse(a))
+    end
+
+    def test_basic_rings_with_commas_and_no_space
+      a = "(ring,50, 60, 70)"
+      b = " ring(50, 60, 70)"
+      assert_equal(b, PreParser.preparse(a))
+    end
+
+    def test_spaced_rings_with_commas
+      a = "(ring , 50, 60, 70)"
+      b = " ring(  50, 60, 70)"
       assert_equal(b, PreParser.preparse(a))
     end
 
diff --git a/app/server/sonicpi/test/test_promise.rb b/app/server/sonicpi/test/test_promise.rb
index 72a9fad..459e769 100644
--- a/app/server/sonicpi/test/test_promise.rb
+++ b/app/server/sonicpi/test/test_promise.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/test_ring.rb b/app/server/sonicpi/test/test_ring.rb
index a433c5c..521184f 100644
--- a/app/server/sonicpi/test/test_ring.rb
+++ b/app/server/sonicpi/test/test_ring.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
@@ -25,9 +25,8 @@ module SonicPi
       assert_equal(SonicPi::Core::RingVector, stretch([:e1], 3).class)
       assert_equal([:a2,:a2], stretch(:a2, 2))
 
-      assert_raises SonicPi::Core::EmptyVectorError do
-        stretch([:e2], 0)
-      end
+      assert_equal(stretch([:e2], 0), ring())
+
     end
 
     def test_knit
@@ -35,16 +34,11 @@ module SonicPi
       assert_equal(knit(:e1, 3, :c1, 2), [:e1, :e1, :e1, :c1, :c1])
       assert_equal(knit(:e2, -1, :c1, 3), [:c1, :c1, :c1])
       assert_equal(knit(:e1, 3).class, SonicPi::Core::RingVector)
-      assert_raises SonicPi::Core::EmptyVectorError do
-        knit(:e2, 0)
-      end
-
-      assert_raises SonicPi::Core::EmptyVectorError do
-        knit(:e2, -1)
-      end
+      assert_equal(knit([:e2], 0), ring())
+      assert_equal(knit(:e2, -1), ring())
 
       assert_raises RuntimeError, "even number" do
-        knit(:e2, 1, :c3)
+        assert_equal(knit(:e2, 1, :c3), ring())
       end
 
     end
@@ -59,10 +53,8 @@ module SonicPi
       assert_equal(range(10, 50, step: 10), [10, 20, 30, 40])
       assert_equal(range(1, 5, step: -1), [1, 2, 3, 4])
       assert_equal(range(1, 3).class, SonicPi::Core::RingVector)
+      assert_equal(range(10, 10, step: -1), ring())
 
-      assert_raises SonicPi::Core::EmptyVectorError do
-        range(10, 10, step: -1)
-      end
     end
 
 
@@ -89,14 +81,42 @@ module SonicPi
       assert_equal(bools(:a, 1, nil, true, 0), [true, true, false, true, false])
       assert_equal(bools(1,0, 0).class, SonicPi::Core::RingVector)
 
-      assert_raises SonicPi::Core::EmptyVectorError do
-        assert_equal(bools(), [])
-      end
+
+      assert_equal(bools(), ring())
+
     end
 
     def test_spread
       assert_equal(spread(5, 13), [true, false, false, true, false, false, true, false, true, false, false, true, false])
       assert_equal(spread(3, 8, rotate: 1),  [true, false, false, true, false, true, false, false])
     end
+
+    def test_plus
+      assert_equal(ring(1, 2, 3) + 10, ring(11.0, 12.0, 13.0))
+    end
+
+    def test_list_plus
+      assert_equal(ring(1, 2, 3) + ring(4), ring(1, 2, 3, 4))
+      assert_equal(ring(1, 2, 3) + ring(1), ring(1, 2, 3, 1))
+    end
+
+    def test_minus
+      assert_equal(ring(10, 20, 30) - 5, ring(5.0, 15.0, 25.0))
+    end
+
+    def test_list_minus
+      assert_equal(ring(1, 2, 3) - ring(1), ring(2, 3))
+      assert_equal(ring(1, 2, 3) - ring(10), ring(1, 2, 3))
+    end
+
+    def test_take
+      assert_equal(ring(1), ring(1, 2, 3).take(1))
+      assert_equal(ring(1, 2), ring(1, 2, 3).take(2))
+      assert_equal(ring(1, 2, 3, 1), ring(1, 2, 3).take(4))
+      assert_equal(ring(3), ring(1, 2, 3).take(-1))
+      assert_equal(ring(3, 2), ring(1, 2, 3).take(-2))
+      assert_equal(ring(3, 2, 1, 3, 2), ring(1, 2, 3).take(-5))
+      assert_equal(ring(), ring(1, 2, 3).take(0))
+    end
   end
 end
diff --git a/app/server/sonicpi/test/test_scale.rb b/app/server/sonicpi/test/test_scale.rb
index 894205d..f5b3a1b 100644
--- a/app/server/sonicpi/test/test_scale.rb
+++ b/app/server/sonicpi/test/test_scale.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/test_tuning.rb b/app/server/sonicpi/test/test_tuning.rb
index fc62470..276811c 100644
--- a/app/server/sonicpi/test/test_tuning.rb
+++ b/app/server/sonicpi/test/test_tuning.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/test_util.rb b/app/server/sonicpi/test/test_util.rb
index 90aa664..28efedc 100644
--- a/app/server/sonicpi/test/test_util.rb
+++ b/app/server/sonicpi/test/test_util.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/sonicpi/test/test_vector.rb b/app/server/sonicpi/test/test_vector.rb
new file mode 100644
index 0000000..4f5ceca
--- /dev/null
+++ b/app/server/sonicpi/test/test_vector.rb
@@ -0,0 +1,30 @@
+#--
+# This file is part of Sonic Pi: http://sonic-pi.net
+# Full project source: https://github.com/samaaron/sonic-pi
+# License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+#
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+# All rights reserved.
+#
+# Permission is granted for use, copying, modification, and
+# distribution of modified versions of this work as long as this
+# notice is included.
+#++
+
+require_relative "./setup_test"
+require_relative "../lib/sonicpi/lang/core"
+
+module SonicPi
+  class VectorTester < Minitest::Test
+    include SonicPi::Lang::Core
+
+    def test_index
+      v = vector(:a, :b, :c)
+      assert_equal(v[0], :a)
+      assert_equal(v[-1], :c)
+      assert_equal(v[-100], nil)
+      assert_equal(v[100], nil)
+    end
+
+  end
+end
diff --git a/app/server/sonicpi/test/test_version.rb b/app/server/sonicpi/test/test_version.rb
index dd9a564..c4c8ab9 100644
--- a/app/server/sonicpi/test/test_version.rb
+++ b/app/server/sonicpi/test/test_version.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/util.rb b/app/server/util.rb
index b853034..8092852 100644
--- a/app/server/util.rb
+++ b/app/server/util.rb
@@ -3,7 +3,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/app/server/vendor/activesupport/CHANGELOG.md b/app/server/vendor/activesupport/CHANGELOG.md
new file mode 100644
index 0000000..f65d9ea
--- /dev/null
+++ b/app/server/vendor/activesupport/CHANGELOG.md
@@ -0,0 +1,56 @@
+*   `ActiveSupport::SafeBuffer#prepend` acts like `String#prepend` and modifies
+    instance in-place, returning self. `ActiveSupport::SafeBuffer#prepend!` is
+    deprecated.
+
+    *Pavel Pravosud*
+
+*   `HashWithIndifferentAccess` better respects `#to_hash` on objects it's
+    given. In particular, `.new`, `#update`, `#merge`, `#replace` all accept
+    objects which respond to `#to_hash`, even if those objects are not Hashes
+    directly.
+
+    *Peter Jaros*
+
+*   Deprecate `Class#superclass_delegating_accessor`, use `Class#class_attribute` instead.
+
+    *Akshay Vishnoi*
+
+*   Ensure classes which `include Enumerable` get `#to_json` in addition to
+    `#as_json`.
+
+    *Sammy Larbi*
+
+*   Change the signature of `fetch_multi` to return a hash rather than an
+    array. This makes it consistent with the output of `read_multi`.
+
+    *Parker Selbert*
+
+*   Introduce `Concern#class_methods` as a sleek alternative to clunky
+    `module ClassMethods`. Add `Kernel#concern` to define at the toplevel
+    without chunky `module Foo; extend ActiveSupport::Concern` boilerplate.
+
+        # app/models/concerns/authentication.rb
+        concern :Authentication do
+          included do
+            after_create :generate_private_key
+          end
+
+          class_methods do
+            def authenticate(credentials)
+              # ...
+            end
+          end
+
+          def generate_private_key
+            # ...
+          end
+        end
+
+        # app/models/user.rb
+        class User < ActiveRecord::Base
+          include Authentication
+        end
+
+    *Jeremy Kemper*
+
+Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/activesupport/CHANGELOG.md) for previous changes.
diff --git a/app/server/vendor/activesupport/MIT-LICENSE b/app/server/vendor/activesupport/MIT-LICENSE
new file mode 100644
index 0000000..d06d4f3
--- /dev/null
+++ b/app/server/vendor/activesupport/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2005-2014 David Heinemeier Hansson
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/README.rdoc b/app/server/vendor/activesupport/README.rdoc
new file mode 100644
index 0000000..f358276
--- /dev/null
+++ b/app/server/vendor/activesupport/README.rdoc
@@ -0,0 +1,35 @@
+= Active Support -- Utility classes and Ruby extensions from Rails
+
+Active Support is a collection of utility classes and standard library
+extensions that were found useful for the Rails framework. These additions
+reside in this package so they can be loaded as needed in Ruby projects
+outside of Rails.
+
+
+== Download and installation
+
+The latest version of Active Support can be installed with RubyGems:
+
+  % [sudo] gem install activesupport
+
+Source code can be downloaded as part of the Rails project on GitHub:
+
+* https://github.com/rails/rails/tree/master/activesupport
+
+
+== License
+
+Active Support is released under the MIT license:
+
+* http://www.opensource.org/licenses/MIT
+
+
+== Support
+
+API documentation is at:
+
+* http://api.rubyonrails.org
+
+Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
+
+* https://github.com/rails/rails/issues
diff --git a/app/server/vendor/activesupport/Rakefile b/app/server/vendor/activesupport/Rakefile
new file mode 100644
index 0000000..5ba1536
--- /dev/null
+++ b/app/server/vendor/activesupport/Rakefile
@@ -0,0 +1,32 @@
+require 'rake/testtask'
+require 'rubygems/package_task'
+
+task :default => :test
+Rake::TestTask.new do |t|
+  t.libs << 'test'
+  t.pattern = 'test/**/*_test.rb'
+  t.warning = true
+  t.verbose = true
+end
+
+
+namespace :test do
+  task :isolated do
+    Dir.glob("test/**/*_test.rb").all? do |file|
+      sh(Gem.ruby, '-w', '-Ilib:test', file)
+    end or raise "Failures"
+  end
+end
+
+spec = eval(File.read('activesupport.gemspec'))
+
+Gem::PackageTask.new(spec) do |p|
+  p.gem_spec = spec
+end
+
+desc "Release to rubygems"
+task :release => :package do
+  require 'rake/gemcutter'
+  Rake::Gemcutter::Tasks.new(spec).define
+  Rake::Task['gem:push'].invoke
+end
diff --git a/app/server/vendor/activesupport/activesupport.gemspec b/app/server/vendor/activesupport/activesupport.gemspec
new file mode 100644
index 0000000..f3625e8
--- /dev/null
+++ b/app/server/vendor/activesupport/activesupport.gemspec
@@ -0,0 +1,28 @@
+version = File.read(File.expand_path('../../RAILS_VERSION', __FILE__)).strip
+
+Gem::Specification.new do |s|
+  s.platform    = Gem::Platform::RUBY
+  s.name        = 'activesupport'
+  s.version     = version
+  s.summary     = 'A toolkit of support libraries and Ruby core extensions extracted from the Rails framework.'
+  s.description = 'A toolkit of support libraries and Ruby core extensions extracted from the Rails framework. Rich support for multibyte strings, internationalization, time zones, and testing.'
+
+  s.required_ruby_version = '>= 1.9.3'
+
+  s.license = 'MIT'
+
+  s.author   = 'David Heinemeier Hansson'
+  s.email    = 'david at loudthinking.com'
+  s.homepage = 'http://www.rubyonrails.org'
+
+  s.files        = Dir['CHANGELOG.md', 'MIT-LICENSE', 'README.rdoc', 'lib/**/*']
+  s.require_path = 'lib'
+
+  s.rdoc_options.concat ['--encoding',  'UTF-8']
+
+  s.add_dependency 'i18n',       '~> 0.6', '>= 0.6.9'
+  s.add_dependency 'json',       '~> 1.7', '>= 1.7.7'
+  s.add_dependency 'tzinfo',     '~> 1.1'
+  s.add_dependency 'minitest',   '~> 5.1'
+  s.add_dependency 'thread_safe','~> 0.1'
+end
diff --git a/app/server/vendor/activesupport/bin/generate_tables b/app/server/vendor/activesupport/bin/generate_tables
new file mode 100755
index 0000000..f39e89b
--- /dev/null
+++ b/app/server/vendor/activesupport/bin/generate_tables
@@ -0,0 +1,144 @@
+#!/usr/bin/env ruby
+
+begin
+  $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
+  require 'active_support'
+rescue IOError
+end
+
+require 'open-uri'
+require 'tmpdir'
+
+module ActiveSupport
+  module Multibyte
+    module Unicode
+
+      class UnicodeDatabase
+        def load; end
+      end
+
+      class DatabaseGenerator
+        BASE_URI = "http://www.unicode.org/Public/#{UNICODE_VERSION}/ucd/"
+        SOURCES = {
+          :codepoints => BASE_URI + 'UnicodeData.txt',
+          :composition_exclusion => BASE_URI + 'CompositionExclusions.txt',
+          :grapheme_break_property => BASE_URI + 'auxiliary/GraphemeBreakProperty.txt',
+          :cp1252 => 'http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT'
+        }
+
+        def initialize
+          @ucd = Unicode::UnicodeDatabase.new
+        end
+
+        def parse_codepoints(line)
+          codepoint = Codepoint.new
+          raise "Could not parse input." unless line =~ /^
+            ([0-9A-F]+);        # code
+            ([^;]+);            # name
+            ([A-Z]+);           # general category
+            ([0-9]+);           # canonical combining class
+            ([A-Z]+);           # bidi class
+            (<([A-Z]*)>)?       # decomposition type
+            ((\ ?[0-9A-F]+)*);  # decomposition mapping
+            ([0-9]*);           # decimal digit
+            ([0-9]*);           # digit
+            ([^;]*);            # numeric
+            ([YN]*);            # bidi mirrored
+            ([^;]*);            # unicode 1.0 name
+            ([^;]*);            # iso comment
+            ([0-9A-F]*);        # simple uppercase mapping
+            ([0-9A-F]*);        # simple lowercase mapping
+            ([0-9A-F]*)$/ix     # simple titlecase mapping
+          codepoint.code              = $1.hex
+          #codepoint.name              = $2
+          #codepoint.category          = $3
+          codepoint.combining_class   = Integer($4)
+          #codepoint.bidi_class        = $5
+          codepoint.decomp_type       = $7
+          codepoint.decomp_mapping    = ($8=='') ? nil : $8.split.collect { |element| element.hex }
+          #codepoint.bidi_mirrored     = ($13=='Y') ? true : false
+          codepoint.uppercase_mapping = ($16=='') ? 0 : $16.hex
+          codepoint.lowercase_mapping = ($17=='') ? 0 : $17.hex
+          #codepoint.titlecase_mapping = ($18=='') ? nil : $18.hex
+          @ucd.codepoints[codepoint.code] = codepoint
+        end
+
+        def parse_grapheme_break_property(line)
+          if line =~ /^([0-9A-F.]+)\s*;\s*([\w]+)\s*#/
+            type = $2.downcase.intern
+            @ucd.boundary[type] ||= []
+            if $1.include? '..'
+              parts = $1.split '..'
+              @ucd.boundary[type] << (parts[0].hex..parts[1].hex)
+            else
+              @ucd.boundary[type] << $1.hex
+            end
+          end
+        end
+
+        def parse_composition_exclusion(line)
+          if line =~ /^([0-9A-F]+)/i
+            @ucd.composition_exclusion << $1.hex
+          end
+        end
+
+        def parse_cp1252(line)
+          if line =~ /^([0-9A-Fx]+)\s([0-9A-Fx]+)/i
+            @ucd.cp1252[$1.hex] = $2.hex
+          end
+        end
+
+        def create_composition_map
+          @ucd.codepoints.each do |_, cp|
+            if !cp.nil? and cp.combining_class == 0 and cp.decomp_type.nil? and !cp.decomp_mapping.nil? and cp.decomp_mapping.length == 2 and @ucd.codepoints[cp.decomp_mapping[0]].combining_class == 0 and !@ucd.composition_exclusion.include?(cp.code)
+              @ucd.composition_map[cp.decomp_mapping[0]] ||= {}
+              @ucd.composition_map[cp.decomp_mapping[0]][cp.decomp_mapping[1]] = cp.code
+            end
+          end
+        end
+
+        def normalize_boundary_map
+          @ucd.boundary.each do |k,v|
+            if [:lf, :cr].include? k
+              @ucd.boundary[k] = v[0]
+            end
+          end
+        end
+
+        def parse
+          SOURCES.each do |type, url|
+            filename =  File.join(Dir.tmpdir, "#{url.split('/').last}")
+            unless File.exist?(filename)
+              $stderr.puts "Downloading #{url.split('/').last}"
+              File.open(filename, 'wb') do |target|
+                open(url) do |source|
+                  source.each_line { |line| target.write line }
+                end
+              end
+            end
+            File.open(filename) do |file|
+              file.each_line { |line| send "parse_#{type}".intern, line }
+            end
+          end
+          create_composition_map
+          normalize_boundary_map
+        end
+
+        def dump_to(filename)
+          File.open(filename, 'wb') do |f|
+            f.write Marshal.dump([@ucd.codepoints, @ucd.composition_exclusion, @ucd.composition_map, @ucd.boundary, @ucd.cp1252])
+          end
+        end
+      end
+    end
+  end
+end
+
+if __FILE__ == $0
+  filename = ActiveSupport::Multibyte::Unicode::UnicodeDatabase.filename
+  generator = ActiveSupport::Multibyte::Unicode::DatabaseGenerator.new
+  generator.parse
+  print "Writing to: #{filename}"
+  generator.dump_to filename
+  puts " (#{File.size(filename)} bytes)"
+end
diff --git a/app/server/vendor/activesupport/lib/active_support.rb b/app/server/vendor/activesupport/lib/active_support.rb
new file mode 100644
index 0000000..ab0054b
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support.rb
@@ -0,0 +1,75 @@
+#--
+# Copyright (c) 2005-2014 David Heinemeier Hansson
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#++
+
+require 'securerandom'
+require "active_support/dependencies/autoload"
+require "active_support/version"
+require "active_support/logger"
+require "active_support/lazy_load_hooks"
+
+module ActiveSupport
+  extend ActiveSupport::Autoload
+
+  autoload :Concern
+  autoload :Dependencies
+  autoload :DescendantsTracker
+  autoload :FileUpdateChecker
+  autoload :LogSubscriber
+  autoload :Notifications
+
+  eager_autoload do
+    autoload :BacktraceCleaner
+    autoload :ProxyObject
+    autoload :Benchmarkable
+    autoload :Cache
+    autoload :Callbacks
+    autoload :Configurable
+    autoload :Deprecation
+    autoload :Gzip
+    autoload :Inflector
+    autoload :JSON
+    autoload :KeyGenerator
+    autoload :MessageEncryptor
+    autoload :MessageVerifier
+    autoload :Multibyte
+    autoload :NumberHelper
+    autoload :OptionMerger
+    autoload :OrderedHash
+    autoload :OrderedOptions
+    autoload :StringInquirer
+    autoload :TaggedLogging
+    autoload :XmlMini
+  end
+
+  autoload :Rescuable
+  autoload :SafeBuffer, "active_support/core_ext/string/output_safety"
+  autoload :TestCase
+
+  def self.eager_load!
+    super
+
+    NumberHelper.eager_load!
+  end
+end
+
+autoload :I18n, "active_support/i18n"
diff --git a/app/server/vendor/activesupport/lib/active_support/all.rb b/app/server/vendor/activesupport/lib/active_support/all.rb
new file mode 100644
index 0000000..f537818
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/all.rb
@@ -0,0 +1,3 @@
+require 'active_support'
+require 'active_support/time'
+require 'active_support/core_ext'
diff --git a/app/server/vendor/activesupport/lib/active_support/backtrace_cleaner.rb b/app/server/vendor/activesupport/lib/active_support/backtrace_cleaner.rb
new file mode 100644
index 0000000..d58578b
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/backtrace_cleaner.rb
@@ -0,0 +1,103 @@
+module ActiveSupport
+  # Backtraces often include many lines that are not relevant for the context
+  # under review. This makes it hard to find the signal amongst the backtrace
+  # noise, and adds debugging time. With a BacktraceCleaner, filters and
+  # silencers are used to remove the noisy lines, so that only the most relevant
+  # lines remain.
+  #
+  # Filters are used to modify lines of data, while silencers are used to remove
+  # lines entirely. The typical filter use case is to remove lengthy path
+  # information from the start of each line, and view file paths relevant to the
+  # app directory instead of the file system root. The typical silencer use case
+  # is to exclude the output of a noisy library from the backtrace, so that you
+  # can focus on the rest.
+  #
+  #   bc = BacktraceCleaner.new
+  #   bc.add_filter   { |line| line.gsub(Rails.root, '') } # strip the Rails.root prefix
+  #   bc.add_silencer { |line| line =~ /mongrel|rubygems/ } # skip any lines from mongrel or rubygems
+  #   bc.clean(exception.backtrace) # perform the cleanup
+  #
+  # To reconfigure an existing BacktraceCleaner (like the default one in Rails)
+  # and show as much data as possible, you can always call
+  # <tt>BacktraceCleaner#remove_silencers!</tt>, which will restore the
+  # backtrace to a pristine state. If you need to reconfigure an existing
+  # BacktraceCleaner so that it does not filter or modify the paths of any lines
+  # of the backtrace, you can call <tt>BacktraceCleaner#remove_filters!</tt>
+  # These two methods will give you a completely untouched backtrace.
+  #
+  # Inspired by the Quiet Backtrace gem by Thoughtbot.
+  class BacktraceCleaner
+    def initialize
+      @filters, @silencers = [], []
+    end
+
+    # Returns the backtrace after all filters and silencers have been run
+    # against it. Filters run first, then silencers.
+    def clean(backtrace, kind = :silent)
+      filtered = filter_backtrace(backtrace)
+
+      case kind
+      when :silent
+        silence(filtered)
+      when :noise
+        noise(filtered)
+      else
+        filtered
+      end
+    end
+    alias :filter :clean
+
+    # Adds a filter from the block provided. Each line in the backtrace will be
+    # mapped against this filter.
+    #
+    #   # Will turn "/my/rails/root/app/models/person.rb" into "/app/models/person.rb"
+    #   backtrace_cleaner.add_filter { |line| line.gsub(Rails.root, '') }
+    def add_filter(&block)
+      @filters << block
+    end
+
+    # Adds a silencer from the block provided. If the silencer returns +true+
+    # for a given line, it will be excluded from the clean backtrace.
+    #
+    #   # Will reject all lines that include the word "mongrel", like "/gems/mongrel/server.rb" or "/app/my_mongrel_server/rb"
+    #   backtrace_cleaner.add_silencer { |line| line =~ /mongrel/ }
+    def add_silencer(&block)
+      @silencers << block
+    end
+
+    # Will remove all silencers, but leave in the filters. This is useful if
+    # your context of debugging suddenly expands as you suspect a bug in one of
+    # the libraries you use.
+    def remove_silencers!
+      @silencers = []
+    end
+
+    # Removes all filters, but leaves in silencers. Useful if you suddenly
+    # need to see entire filepaths in the backtrace that you had already
+    # filtered out.
+    def remove_filters!
+      @filters = []
+    end
+
+    private
+      def filter_backtrace(backtrace)
+        @filters.each do |f|
+          backtrace = backtrace.map { |line| f.call(line) }
+        end
+
+        backtrace
+      end
+
+      def silence(backtrace)
+        @silencers.each do |s|
+          backtrace = backtrace.reject { |line| s.call(line) }
+        end
+
+        backtrace
+      end
+
+      def noise(backtrace)
+        backtrace - silence(backtrace)
+      end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/benchmarkable.rb b/app/server/vendor/activesupport/lib/active_support/benchmarkable.rb
new file mode 100644
index 0000000..805b7a7
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/benchmarkable.rb
@@ -0,0 +1,49 @@
+require 'active_support/core_ext/benchmark'
+require 'active_support/core_ext/hash/keys'
+
+module ActiveSupport
+  module Benchmarkable
+    # Allows you to measure the execution time of a block in a template and
+    # records the result to the log. Wrap this block around expensive operations
+    # or possible bottlenecks to get a time reading for the operation. For
+    # example, let's say you thought your file processing method was taking too
+    # long; you could wrap it in a benchmark block.
+    #
+    #  <% benchmark 'Process data files' do %>
+    #    <%= expensive_files_operation %>
+    #  <% end %>
+    #
+    # That would add something like "Process data files (345.2ms)" to the log,
+    # which you can then use to compare timings when optimizing your code.
+    #
+    # You may give an optional logger level (<tt>:debug</tt>, <tt>:info</tt>,
+    # <tt>:warn</tt>, <tt>:error</tt>) as the <tt>:level</tt> option. The
+    # default logger level value is <tt>:info</tt>.
+    #
+    #  <% benchmark 'Low-level files', level: :debug do %>
+    #    <%= lowlevel_files_operation %>
+    #  <% end %>
+    #
+    # Finally, you can pass true as the third argument to silence all log
+    # activity (other than the timing information) from inside the block. This
+    # is great for boiling down a noisy block to just a single statement that
+    # produces one log line:
+    #
+    #  <% benchmark 'Process data files', level: :info, silence: true do %>
+    #    <%= expensive_and_chatty_files_operation %>
+    #  <% end %>
+    def benchmark(message = "Benchmarking", options = {})
+      if logger
+        options.assert_valid_keys(:level, :silence)
+        options[:level] ||= :info
+
+        result = nil
+        ms = Benchmark.ms { result = options[:silence] ? silence { yield } : yield }
+        logger.send(options[:level], '%s (%.1fms)' % [ message, ms ])
+        result
+      else
+        yield
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/builder.rb b/app/server/vendor/activesupport/lib/active_support/builder.rb
new file mode 100644
index 0000000..321e462
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/builder.rb
@@ -0,0 +1,6 @@
+begin
+  require 'builder'
+rescue LoadError => e
+  $stderr.puts "You don't have builder installed in your application. Please add it to your Gemfile and run bundle install"
+  raise e
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/cache.rb b/app/server/vendor/activesupport/lib/active_support/cache.rb
new file mode 100644
index 0000000..a627fa8
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/cache.rb
@@ -0,0 +1,718 @@
+require 'benchmark'
+require 'zlib'
+require 'active_support/core_ext/array/extract_options'
+require 'active_support/core_ext/array/wrap'
+require 'active_support/core_ext/benchmark'
+require 'active_support/core_ext/module/attribute_accessors'
+require 'active_support/core_ext/numeric/bytes'
+require 'active_support/core_ext/numeric/time'
+require 'active_support/core_ext/object/to_param'
+require 'active_support/core_ext/string/inflections'
+
+module ActiveSupport
+  # See ActiveSupport::Cache::Store for documentation.
+  module Cache
+    autoload :FileStore,     'active_support/cache/file_store'
+    autoload :MemoryStore,   'active_support/cache/memory_store'
+    autoload :MemCacheStore, 'active_support/cache/mem_cache_store'
+    autoload :NullStore,     'active_support/cache/null_store'
+
+    # These options mean something to all cache implementations. Individual cache
+    # implementations may support additional options.
+    UNIVERSAL_OPTIONS = [:namespace, :compress, :compress_threshold, :expires_in, :race_condition_ttl]
+
+    module Strategy
+      autoload :LocalCache, 'active_support/cache/strategy/local_cache'
+    end
+
+    class << self
+      # Creates a new CacheStore object according to the given options.
+      #
+      # If no arguments are passed to this method, then a new
+      # ActiveSupport::Cache::MemoryStore object will be returned.
+      #
+      # If you pass a Symbol as the first argument, then a corresponding cache
+      # store class under the ActiveSupport::Cache namespace will be created.
+      # For example:
+      #
+      #   ActiveSupport::Cache.lookup_store(:memory_store)
+      #   # => returns a new ActiveSupport::Cache::MemoryStore object
+      #
+      #   ActiveSupport::Cache.lookup_store(:mem_cache_store)
+      #   # => returns a new ActiveSupport::Cache::MemCacheStore object
+      #
+      # Any additional arguments will be passed to the corresponding cache store
+      # class's constructor:
+      #
+      #   ActiveSupport::Cache.lookup_store(:file_store, '/tmp/cache')
+      #   # => same as: ActiveSupport::Cache::FileStore.new('/tmp/cache')
+      #
+      # If the first argument is not a Symbol, then it will simply be returned:
+      #
+      #   ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new)
+      #   # => returns MyOwnCacheStore.new
+      def lookup_store(*store_option)
+        store, *parameters = *Array.wrap(store_option).flatten
+
+        case store
+        when Symbol
+          retrieve_store_class(store).new(*parameters)
+        when nil
+          ActiveSupport::Cache::MemoryStore.new
+        else
+          store
+        end
+      end
+
+      # Expands out the +key+ argument into a key that can be used for the
+      # cache store. Optionally accepts a namespace, and all keys will be
+      # scoped within that namespace.
+      #
+      # If the +key+ argument provided is an array, or responds to +to_a+, then
+      # each of elements in the array will be turned into parameters/keys and
+      # concatenated into a single key. For example:
+      #
+      #   expand_cache_key([:foo, :bar])               # => "foo/bar"
+      #   expand_cache_key([:foo, :bar], "namespace")  # => "namespace/foo/bar"
+      #
+      # The +key+ argument can also respond to +cache_key+ or +to_param+.
+      def expand_cache_key(key, namespace = nil)
+        expanded_cache_key = namespace ? "#{namespace}/" : ""
+
+        if prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
+          expanded_cache_key << "#{prefix}/"
+        end
+
+        expanded_cache_key << retrieve_cache_key(key)
+        expanded_cache_key
+      end
+
+      private
+        def retrieve_cache_key(key)
+          case
+          when key.respond_to?(:cache_key) then key.cache_key
+          when key.is_a?(Array)            then key.map { |element| retrieve_cache_key(element) }.to_param
+          when key.respond_to?(:to_a)      then retrieve_cache_key(key.to_a)
+          else                                  key.to_param
+          end.to_s
+        end
+
+        # Obtains the specified cache store class, given the name of the +store+.
+        # Raises an error when the store class cannot be found.
+        def retrieve_store_class(store)
+          require "active_support/cache/#{store}"
+        rescue LoadError => e
+          raise "Could not find cache store adapter for #{store} (#{e})"
+        else
+          ActiveSupport::Cache.const_get(store.to_s.camelize)
+        end
+    end
+
+    # An abstract cache store class. There are multiple cache store
+    # implementations, each having its own additional features. See the classes
+    # under the ActiveSupport::Cache module, e.g.
+    # ActiveSupport::Cache::MemCacheStore. MemCacheStore is currently the most
+    # popular cache store for large production websites.
+    #
+    # Some implementations may not support all methods beyond the basic cache
+    # methods of +fetch+, +write+, +read+, +exist?+, and +delete+.
+    #
+    # ActiveSupport::Cache::Store can store any serializable Ruby object.
+    #
+    #   cache = ActiveSupport::Cache::MemoryStore.new
+    #
+    #   cache.read('city')   # => nil
+    #   cache.write('city', "Duckburgh")
+    #   cache.read('city')   # => "Duckburgh"
+    #
+    # Keys are always translated into Strings and are case sensitive. When an
+    # object is specified as a key and has a +cache_key+ method defined, this
+    # method will be called to define the key.  Otherwise, the +to_param+
+    # method will be called. Hashes and Arrays can also be used as keys. The
+    # elements will be delimited by slashes, and the elements within a Hash
+    # will be sorted by key so they are consistent.
+    #
+    #   cache.read('city') == cache.read(:city)   # => true
+    #
+    # Nil values can be cached.
+    #
+    # If your cache is on a shared infrastructure, you can define a namespace
+    # for your cache entries. If a namespace is defined, it will be prefixed on
+    # to every key. The namespace can be either a static value or a Proc. If it
+    # is a Proc, it will be invoked when each key is evaluated so that you can
+    # use application logic to invalidate keys.
+    #
+    #   cache.namespace = -> { @last_mod_time }  # Set the namespace to a variable
+    #   @last_mod_time = Time.now  # Invalidate the entire cache by changing namespace
+    #
+    # Caches can also store values in a compressed format to save space and
+    # reduce time spent sending data. Since there is overhead, values must be
+    # large enough to warrant compression. To turn on compression either pass
+    # <tt>compress: true</tt> in the initializer or as an option to +fetch+
+    # or +write+. To specify the threshold at which to compress values, set the
+    # <tt>:compress_threshold</tt> option. The default threshold is 16K.
+    class Store
+      cattr_accessor :logger, :instance_writer => true
+
+      attr_reader :silence, :options
+      alias :silence? :silence
+
+      # Create a new cache. The options will be passed to any write method calls
+      # except for <tt>:namespace</tt> which can be used to set the global
+      # namespace for the cache.
+      def initialize(options = nil)
+        @options = options ? options.dup : {}
+      end
+
+      # Silence the logger.
+      def silence!
+        @silence = true
+        self
+      end
+
+      # Silence the logger within a block.
+      def mute
+        previous_silence, @silence = defined?(@silence) && @silence, true
+        yield
+      ensure
+        @silence = previous_silence
+      end
+
+      # Set to +true+ if cache stores should be instrumented.
+      # Default is +false+.
+      def self.instrument=(boolean)
+        Thread.current[:instrument_cache_store] = boolean
+      end
+
+      def self.instrument
+        Thread.current[:instrument_cache_store] || false
+      end
+
+      # Fetches data from the cache, using the given key. If there is data in
+      # the cache with the given key, then that data is returned.
+      #
+      # If there is no such data in the cache (a cache miss), then +nil+ will be
+      # returned. However, if a block has been passed, that block will be passed
+      # the key and executed in the event of a cache miss. The return value of the
+      # block will be written to the cache under the given cache key, and that
+      # return value will be returned.
+      #
+      #   cache.write('today', 'Monday')
+      #   cache.fetch('today')  # => "Monday"
+      #
+      #   cache.fetch('city')   # => nil
+      #   cache.fetch('city') do
+      #     'Duckburgh'
+      #   end
+      #   cache.fetch('city')   # => "Duckburgh"
+      #
+      # You may also specify additional options via the +options+ argument.
+      # Setting <tt>force: true</tt> will force a cache miss:
+      #
+      #   cache.write('today', 'Monday')
+      #   cache.fetch('today', force: true)  # => nil
+      #
+      # Setting <tt>:compress</tt> will store a large cache entry set by the call
+      # in a compressed format.
+      #
+      # Setting <tt>:expires_in</tt> will set an expiration time on the cache.
+      # All caches support auto-expiring content after a specified number of
+      # seconds. This value can be specified as an option to the constructor
+      # (in which case all entries will be affected), or it can be supplied to
+      # the +fetch+ or +write+ method to effect just one entry.
+      #
+      #   cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
+      #   cache.write(key, value, expires_in: 1.minute) # Set a lower value for one entry
+      #
+      # Setting <tt>:race_condition_ttl</tt> is very useful in situations where
+      # a cache entry is used very frequently and is under heavy load. If a
+      # cache expires and due to heavy load several different processes will try
+      # to read data natively and then they all will try to write to cache. To
+      # avoid that case the first process to find an expired cache entry will
+      # bump the cache expiration time by the value set in <tt>:race_condition_ttl</tt>.
+      # Yes, this process is extending the time for a stale value by another few
+      # seconds. Because of extended life of the previous cache, other processes
+      # will continue to use slightly stale data for a just a bit longer. In the
+      # meantime that first process will go ahead and will write into cache the
+      # new value. After that all the processes will start getting new value.
+      # The key is to keep <tt>:race_condition_ttl</tt> small.
+      #
+      # If the process regenerating the entry errors out, the entry will be
+      # regenerated after the specified number of seconds. Also note that the
+      # life of stale cache is extended only if it expired recently. Otherwise
+      # a new value is generated and <tt>:race_condition_ttl</tt> does not play
+      # any role.
+      #
+      #   # Set all values to expire after one minute.
+      #   cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 1.minute)
+      #
+      #   cache.write('foo', 'original value')
+      #   val_1 = nil
+      #   val_2 = nil
+      #   sleep 60
+      #
+      #   Thread.new do
+      #     val_1 = cache.fetch('foo', race_condition_ttl: 10) do
+      #       sleep 1
+      #       'new value 1'
+      #     end
+      #   end
+      #
+      #   Thread.new do
+      #     val_2 = cache.fetch('foo', race_condition_ttl: 10) do
+      #       'new value 2'
+      #     end
+      #   end
+      #
+      #   # val_1 => "new value 1"
+      #   # val_2 => "original value"
+      #   # sleep 10 # First thread extend the life of cache by another 10 seconds
+      #   # cache.fetch('foo') => "new value 1"
+      #
+      # Other options will be handled by the specific cache store implementation.
+      # Internally, #fetch calls #read_entry, and calls #write_entry on a cache
+      # miss. +options+ will be passed to the #read and #write calls.
+      #
+      # For example, MemCacheStore's #write method supports the +:raw+
+      # option, which tells the memcached server to store all values as strings.
+      # We can use this option with #fetch too:
+      #
+      #   cache = ActiveSupport::Cache::MemCacheStore.new
+      #   cache.fetch("foo", force: true, raw: true) do
+      #     :bar
+      #   end
+      #   cache.fetch('foo') # => "bar"
+      def fetch(name, options = nil)
+        if block_given?
+          options = merged_options(options)
+          key = namespaced_key(name, options)
+
+          cached_entry = find_cached_entry(key, name, options) unless options[:force]
+          entry = handle_expired_entry(cached_entry, key, options)
+
+          if entry
+            get_entry_value(entry, name, options)
+          else
+            save_block_result_to_cache(name, options) { |_name| yield _name }
+          end
+        else
+          read(name, options)
+        end
+      end
+
+      # Fetches data from the cache, using the given key. If there is data in
+      # the cache with the given key, then that data is returned. Otherwise,
+      # +nil+ is returned.
+      #
+      # Options are passed to the underlying cache implementation.
+      def read(name, options = nil)
+        options = merged_options(options)
+        key = namespaced_key(name, options)
+        instrument(:read, name, options) do |payload|
+          entry = read_entry(key, options)
+          if entry
+            if entry.expired?
+              delete_entry(key, options)
+              payload[:hit] = false if payload
+              nil
+            else
+              payload[:hit] = true if payload
+              entry.value
+            end
+          else
+            payload[:hit] = false if payload
+            nil
+          end
+        end
+      end
+
+      # Read multiple values at once from the cache. Options can be passed
+      # in the last argument.
+      #
+      # Some cache implementation may optimize this method.
+      #
+      # Returns a hash mapping the names provided to the values found.
+      def read_multi(*names)
+        options = names.extract_options!
+        options = merged_options(options)
+        results = {}
+        names.each do |name|
+          key = namespaced_key(name, options)
+          entry = read_entry(key, options)
+          if entry
+            if entry.expired?
+              delete_entry(key, options)
+            else
+              results[name] = entry.value
+            end
+          end
+        end
+        results
+      end
+
+      # Fetches data from the cache, using the given keys. If there is data in
+      # the cache with the given keys, then that data is returned. Otherwise,
+      # the supplied block is called for each key for which there was no data,
+      # and the result will be written to the cache and returned.
+      #
+      # Options are passed to the underlying cache implementation.
+      #
+      # Returns a hash with the data for each of the names. For example:
+      #
+      #   cache.write("bim", "bam")
+      #   cache.fetch_multi("bim", "boom") { |key| key * 2 }
+      #   # => { "bam" => "bam", "boom" => "boomboom" }
+      #
+      def fetch_multi(*names)
+        options = names.extract_options!
+        options = merged_options(options)
+        results = read_multi(*names, options)
+
+        names.each_with_object({}) do |name, memo|
+          memo[name] = results.fetch(name) do
+            value = yield name
+            write(name, value, options)
+            value
+          end
+        end
+      end
+
+      # Writes the value to the cache, with the key.
+      #
+      # Options are passed to the underlying cache implementation.
+      def write(name, value, options = nil)
+        options = merged_options(options)
+
+        instrument(:write, name, options) do
+          entry = Entry.new(value, options)
+          write_entry(namespaced_key(name, options), entry, options)
+        end
+      end
+
+      # Deletes an entry in the cache. Returns +true+ if an entry is deleted.
+      #
+      # Options are passed to the underlying cache implementation.
+      def delete(name, options = nil)
+        options = merged_options(options)
+
+        instrument(:delete, name) do
+          delete_entry(namespaced_key(name, options), options)
+        end
+      end
+
+      # Returns +true+ if the cache contains an entry for the given key.
+      #
+      # Options are passed to the underlying cache implementation.
+      def exist?(name, options = nil)
+        options = merged_options(options)
+
+        instrument(:exist?, name) do
+          entry = read_entry(namespaced_key(name, options), options)
+          (entry && !entry.expired?) || false
+        end
+      end
+
+      # Delete all entries with keys matching the pattern.
+      #
+      # Options are passed to the underlying cache implementation.
+      #
+      # All implementations may not support this method.
+      def delete_matched(matcher, options = nil)
+        raise NotImplementedError.new("#{self.class.name} does not support delete_matched")
+      end
+
+      # Increment an integer value in the cache.
+      #
+      # Options are passed to the underlying cache implementation.
+      #
+      # All implementations may not support this method.
+      def increment(name, amount = 1, options = nil)
+        raise NotImplementedError.new("#{self.class.name} does not support increment")
+      end
+
+      # Decrement an integer value in the cache.
+      #
+      # Options are passed to the underlying cache implementation.
+      #
+      # All implementations may not support this method.
+      def decrement(name, amount = 1, options = nil)
+        raise NotImplementedError.new("#{self.class.name} does not support decrement")
+      end
+
+      # Cleanup the cache by removing expired entries.
+      #
+      # Options are passed to the underlying cache implementation.
+      #
+      # All implementations may not support this method.
+      def cleanup(options = nil)
+        raise NotImplementedError.new("#{self.class.name} does not support cleanup")
+      end
+
+      # Clear the entire cache. Be careful with this method since it could
+      # affect other processes if shared cache is being used.
+      #
+      # The options hash is passed to the underlying cache implementation.
+      #
+      # All implementations may not support this method.
+      def clear(options = nil)
+        raise NotImplementedError.new("#{self.class.name} does not support clear")
+      end
+
+      protected
+        # Add the namespace defined in the options to a pattern designed to
+        # match keys. Implementations that support delete_matched should call
+        # this method to translate a pattern that matches names into one that
+        # matches namespaced keys.
+        def key_matcher(pattern, options)
+          prefix = options[:namespace].is_a?(Proc) ? options[:namespace].call : options[:namespace]
+          if prefix
+            source = pattern.source
+            if source.start_with?('^')
+              source = source[1, source.length]
+            else
+              source = ".*#{source[0, source.length]}"
+            end
+            Regexp.new("^#{Regexp.escape(prefix)}:#{source}", pattern.options)
+          else
+            pattern
+          end
+        end
+
+        # Read an entry from the cache implementation. Subclasses must implement
+        # this method.
+        def read_entry(key, options) # :nodoc:
+          raise NotImplementedError.new
+        end
+
+        # Write an entry to the cache implementation. Subclasses must implement
+        # this method.
+        def write_entry(key, entry, options) # :nodoc:
+          raise NotImplementedError.new
+        end
+
+        # Delete an entry from the cache implementation. Subclasses must
+        # implement this method.
+        def delete_entry(key, options) # :nodoc:
+          raise NotImplementedError.new
+        end
+
+      private
+        # Merge the default options with ones specific to a method call.
+        def merged_options(call_options) # :nodoc:
+          if call_options
+            options.merge(call_options)
+          else
+            options.dup
+          end
+        end
+
+        # Expand key to be a consistent string value. Invoke +cache_key+ if
+        # object responds to +cache_key+. Otherwise, +to_param+ method will be
+        # called. If the key is a Hash, then keys will be sorted alphabetically.
+        def expanded_key(key) # :nodoc:
+          return key.cache_key.to_s if key.respond_to?(:cache_key)
+
+          case key
+          when Array
+            if key.size > 1
+              key = key.collect{|element| expanded_key(element)}
+            else
+              key = key.first
+            end
+          when Hash
+            key = key.sort_by { |k,_| k.to_s }.collect{|k,v| "#{k}=#{v}"}
+          end
+
+          key.to_param
+        end
+
+        # Prefix a key with the namespace. Namespace and key will be delimited
+        # with a colon.
+        def namespaced_key(key, options)
+          key = expanded_key(key)
+          namespace = options[:namespace] if options
+          prefix = namespace.is_a?(Proc) ? namespace.call : namespace
+          key = "#{prefix}:#{key}" if prefix
+          key
+        end
+
+        def instrument(operation, key, options = nil)
+          log(operation, key, options)
+
+          if self.class.instrument
+            payload = { :key => key }
+            payload.merge!(options) if options.is_a?(Hash)
+            ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload){ yield(payload) }
+          else
+            yield(nil)
+          end
+        end
+
+        def log(operation, key, options = nil)
+          return unless logger && logger.debug? && !silence?
+          logger.debug("Cache #{operation}: #{key}#{options.blank? ? "" : " (#{options.inspect})"}")
+        end
+
+        def find_cached_entry(key, name, options)
+          instrument(:read, name, options) do |payload|
+            payload[:super_operation] = :fetch if payload
+            read_entry(key, options)
+          end
+        end
+
+        def handle_expired_entry(entry, key, options)
+          if entry && entry.expired?
+            race_ttl = options[:race_condition_ttl].to_i
+            if race_ttl && (Time.now.to_f - entry.expires_at <= race_ttl)
+              # When an entry has :race_condition_ttl defined, put the stale entry back into the cache
+              # for a brief period while the entry is begin recalculated.
+              entry.expires_at = Time.now + race_ttl
+              write_entry(key, entry, :expires_in => race_ttl * 2)
+            else
+              delete_entry(key, options)
+            end
+            entry = nil
+          end
+          entry
+        end
+
+        def get_entry_value(entry, name, options)
+          instrument(:fetch_hit, name, options) { |payload| }
+          entry.value
+        end
+
+        def save_block_result_to_cache(name, options)
+          result = instrument(:generate, name, options) do |payload|
+            yield(name)
+          end
+
+          write(name, result, options)
+          result
+        end
+    end
+
+    # This class is used to represent cache entries. Cache entries have a value and an optional
+    # expiration time. The expiration time is used to support the :race_condition_ttl option
+    # on the cache.
+    #
+    # Since cache entries in most instances will be serialized, the internals of this class are highly optimized
+    # using short instance variable names that are lazily defined.
+    class Entry # :nodoc:
+      DEFAULT_COMPRESS_LIMIT = 16.kilobytes
+
+      # Create a new cache entry for the specified value. Options supported are
+      # +:compress+, +:compress_threshold+, and +:expires_in+.
+      def initialize(value, options = {})
+        if should_compress?(value, options)
+          @value = compress(value)
+          @compressed = true
+        else
+          @value = value
+        end
+
+        @created_at = Time.now.to_f
+        @expires_in = options[:expires_in]
+        @expires_in = @expires_in.to_f if @expires_in
+      end
+
+      def value
+        convert_version_4beta1_entry! if defined?(@v)
+        compressed? ? uncompress(@value) : @value
+      end
+
+      # Check if the entry is expired. The +expires_in+ parameter can override
+      # the value set when the entry was created.
+      def expired?
+        convert_version_4beta1_entry! if defined?(@value)
+        @expires_in && @created_at + @expires_in <= Time.now.to_f
+      end
+
+      def expires_at
+        @expires_in ? @created_at + @expires_in : nil
+      end
+
+      def expires_at=(value)
+        if value
+          @expires_in = value.to_f - @created_at
+        else
+          @expires_in = nil
+        end
+      end
+
+      # Returns the size of the cached value. This could be less than
+      # <tt>value.size</tt> if the data is compressed.
+      def size
+        if defined?(@s)
+          @s
+        else
+          case value
+          when NilClass
+            0
+          when String
+            @value.bytesize
+          else
+            @s = Marshal.dump(@value).bytesize
+          end
+        end
+      end
+
+      # Duplicate the value in a class. This is used by cache implementations that don't natively
+      # serialize entries to protect against accidental cache modifications.
+      def dup_value!
+        convert_version_4beta1_entry! if defined?(@v)
+
+        if @value && !compressed? && !(@value.is_a?(Numeric) || @value == true || @value == false)
+          if @value.is_a?(String)
+            @value = @value.dup
+          else
+            @value = Marshal.load(Marshal.dump(@value))
+          end
+        end
+      end
+
+      private
+        def should_compress?(value, options)
+          if value && options[:compress]
+            compress_threshold = options[:compress_threshold] || DEFAULT_COMPRESS_LIMIT
+            serialized_value_size = (value.is_a?(String) ? value : Marshal.dump(value)).bytesize
+
+            return true if serialized_value_size >= compress_threshold
+          end
+
+          false
+        end
+
+        def compressed?
+          defined?(@compressed) ? @compressed : false
+        end
+
+        def compress(value)
+          Zlib::Deflate.deflate(Marshal.dump(value))
+        end
+
+        def uncompress(value)
+          Marshal.load(Zlib::Inflate.inflate(value))
+        end
+
+        # The internals of this method changed between Rails 3.x and 4.0. This method provides the glue
+        # to ensure that cache entries created under the old version still work with the new class definition.
+        def convert_version_4beta1_entry!
+          if defined?(@v)
+            @value = @v
+            remove_instance_variable(:@v)
+          end
+
+          if defined?(@c)
+            @compressed = @c
+            remove_instance_variable(:@c)
+          end
+
+          if defined?(@x) && @x
+            @created_at ||= Time.now.to_f
+            @expires_in = @x - @created_at
+            remove_instance_variable(:@x)
+          end
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/cache/file_store.rb b/app/server/vendor/activesupport/lib/active_support/cache/file_store.rb
new file mode 100644
index 0000000..8ed60ae
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/cache/file_store.rb
@@ -0,0 +1,185 @@
+require 'active_support/core_ext/marshal'
+require 'active_support/core_ext/file/atomic'
+require 'active_support/core_ext/string/conversions'
+require 'uri/common'
+
+module ActiveSupport
+  module Cache
+    # A cache store implementation which stores everything on the filesystem.
+    #
+    # FileStore implements the Strategy::LocalCache strategy which implements
+    # an in-memory cache inside of a block.
+    class FileStore < Store
+      attr_reader :cache_path
+
+      DIR_FORMATTER = "%03X"
+      FILENAME_MAX_SIZE = 228 # max filename size on file system is 255, minus room for timestamp and random characters appended by Tempfile (used by atomic write)
+      EXCLUDED_DIRS = ['.', '..'].freeze
+
+      def initialize(cache_path, options = nil)
+        super(options)
+        @cache_path = cache_path.to_s
+        extend Strategy::LocalCache
+      end
+
+      # Deletes all items from the cache. In this case it deletes all the entries in the specified
+      # file store directory except for .gitkeep. Be careful which directory is specified in your
+      # config file when using +FileStore+ because everything in that directory will be deleted.
+      def clear(options = nil)
+        root_dirs = Dir.entries(cache_path).reject {|f| (EXCLUDED_DIRS + [".gitkeep"]).include?(f)}
+        FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)})
+      end
+
+      # Preemptively iterates through all stored keys and removes the ones which have expired.
+      def cleanup(options = nil)
+        options = merged_options(options)
+        search_dir(cache_path) do |fname|
+          key = file_path_key(fname)
+          entry = read_entry(key, options)
+          delete_entry(key, options) if entry && entry.expired?
+        end
+      end
+
+      # Increments an already existing integer value that is stored in the cache.
+      # If the key is not found nothing is done.
+      def increment(name, amount = 1, options = nil)
+        modify_value(name, amount, options)
+      end
+
+      # Decrements an already existing integer value that is stored in the cache.
+      # If the key is not found nothing is done.
+      def decrement(name, amount = 1, options = nil)
+        modify_value(name, -amount, options)
+      end
+
+      def delete_matched(matcher, options = nil)
+        options = merged_options(options)
+        instrument(:delete_matched, matcher.inspect) do
+          matcher = key_matcher(matcher, options)
+          search_dir(cache_path) do |path|
+            key = file_path_key(path)
+            delete_entry(key, options) if key.match(matcher)
+          end
+        end
+      end
+
+      protected
+
+        def read_entry(key, options)
+          file_name = key_file_path(key)
+          if File.exist?(file_name)
+            File.open(file_name) { |f| Marshal.load(f) }
+          end
+        rescue => e
+          logger.error("FileStoreError (#{e}): #{e.message}") if logger
+          nil
+        end
+
+        def write_entry(key, entry, options)
+          file_name = key_file_path(key)
+          return false if options[:unless_exist] && File.exist?(file_name)
+          ensure_cache_path(File.dirname(file_name))
+          File.atomic_write(file_name, cache_path) {|f| Marshal.dump(entry, f)}
+          true
+        end
+
+        def delete_entry(key, options)
+          file_name = key_file_path(key)
+          if File.exist?(file_name)
+            begin
+              File.delete(file_name)
+              delete_empty_directories(File.dirname(file_name))
+              true
+            rescue => e
+              # Just in case the error was caused by another process deleting the file first.
+              raise e if File.exist?(file_name)
+              false
+            end
+          end
+        end
+
+      private
+        # Lock a file for a block so only one process can modify it at a time.
+        def lock_file(file_name, &block) # :nodoc:
+          if File.exist?(file_name)
+            File.open(file_name, 'r+') do |f|
+              begin
+                f.flock File::LOCK_EX
+                yield
+              ensure
+                f.flock File::LOCK_UN
+              end
+            end
+          else
+            yield
+          end
+        end
+
+        # Translate a key into a file path.
+        def key_file_path(key)
+          fname = URI.encode_www_form_component(key)
+          hash = Zlib.adler32(fname)
+          hash, dir_1 = hash.divmod(0x1000)
+          dir_2 = hash.modulo(0x1000)
+          fname_paths = []
+
+          # Make sure file name doesn't exceed file system limits.
+          begin
+            fname_paths << fname[0, FILENAME_MAX_SIZE]
+            fname = fname[FILENAME_MAX_SIZE..-1]
+          end until fname.blank?
+
+          File.join(cache_path, DIR_FORMATTER % dir_1, DIR_FORMATTER % dir_2, *fname_paths)
+        end
+
+        # Translate a file path into a key.
+        def file_path_key(path)
+          fname = path[cache_path.to_s.size..-1].split(File::SEPARATOR, 4).last
+          URI.decode_www_form_component(fname, Encoding::UTF_8)
+        end
+
+        # Delete empty directories in the cache.
+        def delete_empty_directories(dir)
+          return if File.realpath(dir) == File.realpath(cache_path)
+          if Dir.entries(dir).reject {|f| EXCLUDED_DIRS.include?(f)}.empty?
+            Dir.delete(dir) rescue nil
+            delete_empty_directories(File.dirname(dir))
+          end
+        end
+
+        # Make sure a file path's directories exist.
+        def ensure_cache_path(path)
+          FileUtils.makedirs(path) unless File.exist?(path)
+        end
+
+        def search_dir(dir, &callback)
+          return if !File.exist?(dir)
+          Dir.foreach(dir) do |d|
+            next if EXCLUDED_DIRS.include?(d)
+            name = File.join(dir, d)
+            if File.directory?(name)
+              search_dir(name, &callback)
+            else
+              callback.call name
+            end
+          end
+        end
+
+        # Modifies the amount of an already existing integer value that is stored in the cache.
+        # If the key is not found nothing is done.
+        def modify_value(name, amount, options)
+          file_name = key_file_path(namespaced_key(name, options))
+
+          lock_file(file_name) do
+            options = merged_options(options)
+
+            if num = read(name, options)
+              num = num.to_i + amount
+              write(name, num, options)
+              num
+            end
+          end
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/cache/mem_cache_store.rb b/app/server/vendor/activesupport/lib/active_support/cache/mem_cache_store.rb
new file mode 100644
index 0000000..61b4f0b
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/cache/mem_cache_store.rb
@@ -0,0 +1,198 @@
+begin
+  require 'dalli'
+rescue LoadError => e
+  $stderr.puts "You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install"
+  raise e
+end
+
+require 'digest/md5'
+require 'active_support/core_ext/marshal'
+require 'active_support/core_ext/array/extract_options'
+
+module ActiveSupport
+  module Cache
+    # A cache store implementation which stores data in Memcached:
+    # http://memcached.org/
+    #
+    # This is currently the most popular cache store for production websites.
+    #
+    # Special features:
+    # - Clustering and load balancing. One can specify multiple memcached servers,
+    #   and MemCacheStore will load balance between all available servers. If a
+    #   server goes down, then MemCacheStore will ignore it until it comes back up.
+    #
+    # MemCacheStore implements the Strategy::LocalCache strategy which implements
+    # an in-memory cache inside of a block.
+    class MemCacheStore < Store
+      ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n
+
+      def self.build_mem_cache(*addresses)
+        addresses = addresses.flatten
+        options = addresses.extract_options!
+        addresses = ["localhost:11211"] if addresses.empty?
+        Dalli::Client.new(addresses, options)
+      end
+
+      # Creates a new MemCacheStore object, with the given memcached server
+      # addresses. Each address is either a host name, or a host-with-port string
+      # in the form of "host_name:port". For example:
+      #
+      #   ActiveSupport::Cache::MemCacheStore.new("localhost", "server-downstairs.localnetwork:8229")
+      #
+      # If no addresses are specified, then MemCacheStore will connect to
+      # localhost port 11211 (the default memcached port).
+      def initialize(*addresses)
+        addresses = addresses.flatten
+        options = addresses.extract_options!
+        super(options)
+
+        unless [String, Dalli::Client, NilClass].include?(addresses.first.class)
+          raise ArgumentError, "First argument must be an empty array, an array of hosts or a Dalli::Client instance."
+        end
+        if addresses.first.is_a?(Dalli::Client)
+          @data = addresses.first
+        else
+          mem_cache_options = options.dup
+          UNIVERSAL_OPTIONS.each{|name| mem_cache_options.delete(name)}
+          @data = self.class.build_mem_cache(*(addresses + [mem_cache_options]))
+        end
+
+        extend Strategy::LocalCache
+        extend LocalCacheWithRaw
+      end
+
+      # Reads multiple values from the cache using a single call to the
+      # servers for all keys. Options can be passed in the last argument.
+      def read_multi(*names)
+        options = names.extract_options!
+        options = merged_options(options)
+        keys_to_names = Hash[names.map{|name| [escape_key(namespaced_key(name, options)), name]}]
+        raw_values = @data.get_multi(keys_to_names.keys, :raw => true)
+        values = {}
+        raw_values.each do |key, value|
+          entry = deserialize_entry(value)
+          values[keys_to_names[key]] = entry.value unless entry.expired?
+        end
+        values
+      end
+
+      # Increment a cached value. This method uses the memcached incr atomic
+      # operator and can only be used on values written with the :raw option.
+      # Calling it on a value not stored with :raw will initialize that value
+      # to zero.
+      def increment(name, amount = 1, options = nil) # :nodoc:
+        options = merged_options(options)
+        instrument(:increment, name, :amount => amount) do
+          @data.incr(escape_key(namespaced_key(name, options)), amount)
+        end
+      rescue Dalli::DalliError => e
+        logger.error("DalliError (#{e}): #{e.message}") if logger
+        nil
+      end
+
+      # Decrement a cached value. This method uses the memcached decr atomic
+      # operator and can only be used on values written with the :raw option.
+      # Calling it on a value not stored with :raw will initialize that value
+      # to zero.
+      def decrement(name, amount = 1, options = nil) # :nodoc:
+        options = merged_options(options)
+        instrument(:decrement, name, :amount => amount) do
+          @data.decr(escape_key(namespaced_key(name, options)), amount)
+        end
+      rescue Dalli::DalliError => e
+        logger.error("DalliError (#{e}): #{e.message}") if logger
+        nil
+      end
+
+      # Clear the entire cache on all memcached servers. This method should
+      # be used with care when shared cache is being used.
+      def clear(options = nil)
+        @data.flush_all
+      rescue Dalli::DalliError => e
+        logger.error("DalliError (#{e}): #{e.message}") if logger
+        nil
+      end
+
+      # Get the statistics from the memcached servers.
+      def stats
+        @data.stats
+      end
+
+      protected
+        # Read an entry from the cache.
+        def read_entry(key, options) # :nodoc:
+          deserialize_entry(@data.get(escape_key(key), options))
+        rescue Dalli::DalliError => e
+          logger.error("DalliError (#{e}): #{e.message}") if logger
+          nil
+        end
+
+        # Write an entry to the cache.
+        def write_entry(key, entry, options) # :nodoc:
+          method = options && options[:unless_exist] ? :add : :set
+          value = options[:raw] ? entry.value.to_s : entry
+          expires_in = options[:expires_in].to_i
+          if expires_in > 0 && !options[:raw]
+            # Set the memcache expire a few minutes in the future to support race condition ttls on read
+            expires_in += 5.minutes
+          end
+          @data.send(method, escape_key(key), value, expires_in, options)
+        rescue Dalli::DalliError => e
+          logger.error("DalliError (#{e}): #{e.message}") if logger
+          false
+        end
+
+        # Delete an entry from the cache.
+        def delete_entry(key, options) # :nodoc:
+          @data.delete(escape_key(key))
+        rescue Dalli::DalliError => e
+          logger.error("DalliError (#{e}): #{e.message}") if logger
+          false
+        end
+
+      private
+
+        # Memcache keys are binaries. So we need to force their encoding to binary
+        # before applying the regular expression to ensure we are escaping all
+        # characters properly.
+        def escape_key(key)
+          key = key.to_s.dup
+          key = key.force_encoding(Encoding::ASCII_8BIT)
+          key = key.gsub(ESCAPE_KEY_CHARS){ |match| "%#{match.getbyte(0).to_s(16).upcase}" }
+          key = "#{key[0, 213]}:md5:#{Digest::MD5.hexdigest(key)}" if key.size > 250
+          key
+        end
+
+        def deserialize_entry(raw_value)
+          if raw_value
+            entry = Marshal.load(raw_value) rescue raw_value
+            entry.is_a?(Entry) ? entry : Entry.new(entry)
+          else
+            nil
+          end
+        end
+
+      # Provide support for raw values in the local cache strategy.
+      module LocalCacheWithRaw # :nodoc:
+        protected
+          def read_entry(key, options)
+            entry = super
+            if options[:raw] && local_cache && entry
+               entry = deserialize_entry(entry.value)
+            end
+            entry
+          end
+
+          def write_entry(key, entry, options) # :nodoc:
+            retval = super
+            if options[:raw] && local_cache && retval
+              raw_entry = Entry.new(entry.value.to_s)
+              raw_entry.expires_at = entry.expires_at
+              local_cache.write_entry(key, raw_entry, options)
+            end
+            retval
+          end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/cache/memory_store.rb b/app/server/vendor/activesupport/lib/active_support/cache/memory_store.rb
new file mode 100644
index 0000000..8a0523d
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/cache/memory_store.rb
@@ -0,0 +1,172 @@
+require 'monitor'
+
+module ActiveSupport
+  module Cache
+    # A cache store implementation which stores everything into memory in the
+    # same process. If you're running multiple Ruby on Rails server processes
+    # (which is the case if you're using mongrel_cluster or Phusion Passenger),
+    # then this means that Rails server process instances won't be able
+    # to share cache data with each other and this may not be the most
+    # appropriate cache in that scenario.
+    #
+    # This cache has a bounded size specified by the :size options to the
+    # initializer (default is 32Mb). When the cache exceeds the allotted size,
+    # a cleanup will occur which tries to prune the cache down to three quarters
+    # of the maximum size by removing the least recently used entries.
+    #
+    # MemoryStore is thread-safe.
+    class MemoryStore < Store
+      def initialize(options = nil)
+        options ||= {}
+        super(options)
+        @data = {}
+        @key_access = {}
+        @max_size = options[:size] || 32.megabytes
+        @max_prune_time = options[:max_prune_time] || 2
+        @cache_size = 0
+        @monitor = Monitor.new
+        @pruning = false
+      end
+
+      def clear(options = nil)
+        synchronize do
+          @data.clear
+          @key_access.clear
+          @cache_size = 0
+        end
+      end
+
+      # Preemptively iterates through all stored keys and removes the ones which have expired.
+      def cleanup(options = nil)
+        options = merged_options(options)
+        instrument(:cleanup, :size => @data.size) do
+          keys = synchronize{ @data.keys }
+          keys.each do |key|
+            entry = @data[key]
+            delete_entry(key, options) if entry && entry.expired?
+          end
+        end
+      end
+
+      # To ensure entries fit within the specified memory prune the cache by removing the least
+      # recently accessed entries.
+      def prune(target_size, max_time = nil)
+        return if pruning?
+        @pruning = true
+        begin
+          start_time = Time.now
+          cleanup
+          instrument(:prune, target_size, :from => @cache_size) do
+            keys = synchronize{ @key_access.keys.sort{|a,b| @key_access[a].to_f <=> @key_access[b].to_f} }
+            keys.each do |key|
+              delete_entry(key, options)
+              return if @cache_size <= target_size || (max_time && Time.now - start_time > max_time)
+            end
+          end
+        ensure
+          @pruning = false
+        end
+      end
+
+      # Returns true if the cache is currently being pruned.
+      def pruning?
+        @pruning
+      end
+
+      # Increment an integer value in the cache.
+      def increment(name, amount = 1, options = nil)
+        synchronize do
+          options = merged_options(options)
+          if num = read(name, options)
+            num = num.to_i + amount
+            write(name, num, options)
+            num
+          else
+            nil
+          end
+        end
+      end
+
+      # Decrement an integer value in the cache.
+      def decrement(name, amount = 1, options = nil)
+        synchronize do
+          options = merged_options(options)
+          if num = read(name, options)
+            num = num.to_i - amount
+            write(name, num, options)
+            num
+          else
+            nil
+          end
+        end
+      end
+
+      def delete_matched(matcher, options = nil)
+        options = merged_options(options)
+        instrument(:delete_matched, matcher.inspect) do
+          matcher = key_matcher(matcher, options)
+          keys = synchronize { @data.keys }
+          keys.each do |key|
+            delete_entry(key, options) if key.match(matcher)
+          end
+        end
+      end
+
+      def inspect # :nodoc:
+        "<##{self.class.name} entries=#{@data.size}, size=#{@cache_size}, options=#{@options.inspect}>"
+      end
+
+      # Synchronize calls to the cache. This should be called wherever the underlying cache implementation
+      # is not thread safe.
+      def synchronize(&block) # :nodoc:
+        @monitor.synchronize(&block)
+      end
+
+      protected
+
+        PER_ENTRY_OVERHEAD = 240
+
+        def cached_size(key, entry)
+          key.to_s.bytesize + entry.size + PER_ENTRY_OVERHEAD
+        end
+
+        def read_entry(key, options) # :nodoc:
+          entry = @data[key]
+          synchronize do
+            if entry
+              @key_access[key] = Time.now.to_f
+            else
+              @key_access.delete(key)
+            end
+          end
+          entry
+        end
+
+        def write_entry(key, entry, options) # :nodoc:
+          entry.dup_value!
+          synchronize do
+            old_entry = @data[key]
+            return false if @data.key?(key) && options[:unless_exist]
+            if old_entry
+              @cache_size -= (old_entry.size - entry.size)
+            else
+              @cache_size += cached_size(key, entry)
+            end
+            @key_access[key] = Time.now.to_f
+            @data[key] = entry
+            prune(@max_size * 0.75, @max_prune_time) if @cache_size > @max_size
+            true
+          end
+        end
+
+        def delete_entry(key, options) # :nodoc:
+          synchronize do
+            @key_access.delete(key)
+            entry = @data.delete(key)
+            @cache_size -= cached_size(key, entry) if entry
+            !!entry
+          end
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/cache/null_store.rb b/app/server/vendor/activesupport/lib/active_support/cache/null_store.rb
new file mode 100644
index 0000000..4427eaa
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/cache/null_store.rb
@@ -0,0 +1,44 @@
+module ActiveSupport
+  module Cache
+    # A cache store implementation which doesn't actually store anything. Useful in
+    # development and test environments where you don't want caching turned on but
+    # need to go through the caching interface.
+    #
+    # This cache does implement the local cache strategy, so values will actually
+    # be cached inside blocks that utilize this strategy. See
+    # ActiveSupport::Cache::Strategy::LocalCache for more details.
+    class NullStore < Store
+      def initialize(options = nil)
+        super(options)
+        extend Strategy::LocalCache
+      end
+
+      def clear(options = nil)
+      end
+
+      def cleanup(options = nil)
+      end
+
+      def increment(name, amount = 1, options = nil)
+      end
+
+      def decrement(name, amount = 1, options = nil)
+      end
+
+      def delete_matched(matcher, options = nil)
+      end
+
+      protected
+        def read_entry(key, options) # :nodoc:
+        end
+
+        def write_entry(key, entry, options) # :nodoc:
+          true
+        end
+
+        def delete_entry(key, options) # :nodoc:
+          false
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/cache/strategy/local_cache.rb b/app/server/vendor/activesupport/lib/active_support/cache/strategy/local_cache.rb
new file mode 100644
index 0000000..e9ee98a
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/cache/strategy/local_cache.rb
@@ -0,0 +1,160 @@
+require 'active_support/core_ext/object/duplicable'
+require 'active_support/core_ext/string/inflections'
+
+module ActiveSupport
+  module Cache
+    module Strategy
+      # Caches that implement LocalCache will be backed by an in-memory cache for the
+      # duration of a block. Repeated calls to the cache for the same key will hit the
+      # in-memory cache for faster access.
+      module LocalCache
+        autoload :Middleware, 'active_support/cache/strategy/local_cache_middleware'
+
+        # Class for storing and registering the local caches.
+        class LocalCacheRegistry # :nodoc:
+          extend ActiveSupport::PerThreadRegistry
+
+          def initialize
+            @registry = {}
+          end
+
+          def cache_for(local_cache_key)
+            @registry[local_cache_key]
+          end
+
+          def set_cache_for(local_cache_key, value)
+            @registry[local_cache_key] = value
+          end
+
+          def self.set_cache_for(l, v); instance.set_cache_for l, v; end
+          def self.cache_for(l); instance.cache_for l; end
+        end
+
+        # Simple memory backed cache. This cache is not thread safe and is intended only
+        # for serving as a temporary memory cache for a single thread.
+        class LocalStore < Store
+          def initialize
+            super
+            @data = {}
+          end
+
+          # Don't allow synchronizing since it isn't thread safe,
+          def synchronize # :nodoc:
+            yield
+          end
+
+          def clear(options = nil)
+            @data.clear
+          end
+
+          def read_entry(key, options)
+            @data[key]
+          end
+
+          def write_entry(key, value, options)
+            @data[key] = value
+            true
+          end
+
+          def delete_entry(key, options)
+            !!@data.delete(key)
+          end
+        end
+
+        # Use a local cache for the duration of block.
+        def with_local_cache
+          use_temporary_local_cache(LocalStore.new) { yield }
+        end
+        # Middleware class can be inserted as a Rack handler to be local cache for the
+        # duration of request.
+        def middleware
+          @middleware ||= Middleware.new(
+            "ActiveSupport::Cache::Strategy::LocalCache",
+            local_cache_key)
+        end
+
+        def clear(options = nil) # :nodoc:
+          local_cache.clear(options) if local_cache
+          super
+        end
+
+        def cleanup(options = nil) # :nodoc:
+          local_cache.clear(options) if local_cache
+          super
+        end
+
+        def increment(name, amount = 1, options = nil) # :nodoc:
+          value = bypass_local_cache{super}
+          set_cache_value(value, name, amount, options)
+          value
+        end
+
+        def decrement(name, amount = 1, options = nil) # :nodoc:
+          value = bypass_local_cache{super}
+          set_cache_value(value, name, amount, options)
+          value
+        end
+
+        protected
+          def read_entry(key, options) # :nodoc:
+            if local_cache
+              entry = local_cache.read_entry(key, options)
+              unless entry
+                entry = super
+                local_cache.write_entry(key, entry, options)
+              end
+              entry
+            else
+              super
+            end
+          end
+
+          def write_entry(key, entry, options) # :nodoc:
+            local_cache.write_entry(key, entry, options) if local_cache
+            super
+          end
+
+          def delete_entry(key, options) # :nodoc:
+            local_cache.delete_entry(key, options) if local_cache
+            super
+          end
+
+          def set_cache_value(value, name, amount, options)
+            if local_cache
+              local_cache.mute do
+                if value
+                  local_cache.write(name, value, options)
+                else
+                  local_cache.delete(name, options)
+                end
+              end
+            end
+          end
+
+        private
+
+          def local_cache_key
+            @local_cache_key ||= "#{self.class.name.underscore}_local_cache_#{object_id}".gsub(/[\/-]/, '_').to_sym
+          end
+
+          def local_cache
+            LocalCacheRegistry.cache_for(local_cache_key)
+          end
+
+          def bypass_local_cache
+            use_temporary_local_cache(nil) { yield }
+          end
+
+          def use_temporary_local_cache(temporary_cache)
+            save_cache = LocalCacheRegistry.cache_for(local_cache_key)
+            begin
+              LocalCacheRegistry.set_cache_for(local_cache_key, temporary_cache)
+              yield
+            ensure
+              LocalCacheRegistry.set_cache_for(local_cache_key, save_cache)
+            end
+          end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/cache/strategy/local_cache_middleware.rb b/app/server/vendor/activesupport/lib/active_support/cache/strategy/local_cache_middleware.rb
new file mode 100644
index 0000000..901c2e0
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/cache/strategy/local_cache_middleware.rb
@@ -0,0 +1,39 @@
+require 'rack/body_proxy'
+module ActiveSupport
+  module Cache
+    module Strategy
+      module LocalCache
+
+        #--
+        # This class wraps up local storage for middlewares. Only the middleware method should
+        # construct them.
+        class Middleware # :nodoc:
+          attr_reader :name, :local_cache_key
+
+          def initialize(name, local_cache_key)
+            @name             = name
+            @local_cache_key = local_cache_key
+            @app              = nil
+          end
+
+          def new(app)
+            @app = app
+            self
+          end
+
+          def call(env)
+            LocalCacheRegistry.set_cache_for(local_cache_key, LocalStore.new)
+            response = @app.call(env)
+            response[2] = ::Rack::BodyProxy.new(response[2]) do
+              LocalCacheRegistry.set_cache_for(local_cache_key, nil)
+            end
+            response
+          rescue Exception
+            LocalCacheRegistry.set_cache_for(local_cache_key, nil)
+            raise
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/callbacks.rb b/app/server/vendor/activesupport/lib/active_support/callbacks.rb
new file mode 100644
index 0000000..e14ece7
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/callbacks.rb
@@ -0,0 +1,745 @@
+require 'active_support/concern'
+require 'active_support/descendants_tracker'
+require 'active_support/core_ext/array/extract_options'
+require 'active_support/core_ext/class/attribute'
+require 'active_support/core_ext/kernel/reporting'
+require 'active_support/core_ext/kernel/singleton_class'
+require 'thread'
+
+module ActiveSupport
+  # Callbacks are code hooks that are run at key points in an object's life cycle.
+  # The typical use case is to have a base class define a set of callbacks
+  # relevant to the other functionality it supplies, so that subclasses can
+  # install callbacks that enhance or modify the base functionality without
+  # needing to override or redefine methods of the base class.
+  #
+  # Mixing in this module allows you to define the events in the object's
+  # life cycle that will support callbacks (via +ClassMethods.define_callbacks+),
+  # set the instance methods, procs, or callback objects to be called (via
+  # +ClassMethods.set_callback+), and run the installed callbacks at the
+  # appropriate times (via +run_callbacks+).
+  #
+  # Three kinds of callbacks are supported: before callbacks, run before a
+  # certain event; after callbacks, run after the event; and around callbacks,
+  # blocks that surround the event, triggering it when they yield. Callback code
+  # can be contained in instance methods, procs or lambdas, or callback objects
+  # that respond to certain predetermined methods. See +ClassMethods.set_callback+
+  # for details.
+  #
+  #   class Record
+  #     include ActiveSupport::Callbacks
+  #     define_callbacks :save
+  #
+  #     def save
+  #       run_callbacks :save do
+  #         puts "- save"
+  #       end
+  #     end
+  #   end
+  #
+  #   class PersonRecord < Record
+  #     set_callback :save, :before, :saving_message
+  #     def saving_message
+  #       puts "saving..."
+  #     end
+  #
+  #     set_callback :save, :after do |object|
+  #       puts "saved"
+  #     end
+  #   end
+  #
+  #   person = PersonRecord.new
+  #   person.save
+  #
+  # Output:
+  #   saving...
+  #   - save
+  #   saved
+  module Callbacks
+    extend Concern
+
+    included do
+      extend ActiveSupport::DescendantsTracker
+    end
+
+    CALLBACK_FILTER_TYPES = [:before, :after, :around]
+
+    # Runs the callbacks for the given event.
+    #
+    # Calls the before and around callbacks in the order they were set, yields
+    # the block (if given one), and then runs the after callbacks in reverse
+    # order.
+    #
+    # If the callback chain was halted, returns +false+. Otherwise returns the
+    # result of the block, or +true+ if no block is given.
+    #
+    #   run_callbacks :save do
+    #     save
+    #   end
+    def run_callbacks(kind, &block)
+      cbs = send("_#{kind}_callbacks")
+      if cbs.empty?
+        yield if block_given?
+      else
+        runner = cbs.compile
+        e = Filters::Environment.new(self, false, nil, block)
+        runner.call(e).value
+      end
+    end
+
+    private
+
+    # A hook invoked every time a before callback is halted.
+    # This can be overridden in AS::Callback implementors in order
+    # to provide better debugging/logging.
+    def halted_callback_hook(filter)
+    end
+
+    module Conditionals # :nodoc:
+      class Value
+        def initialize(&block)
+          @block = block
+        end
+        def call(target, value); @block.call(value); end
+      end
+    end
+
+    module Filters
+      Environment = Struct.new(:target, :halted, :value, :run_block)
+
+      class End
+        def call(env)
+          block = env.run_block
+          env.value = !env.halted && (!block || block.call)
+          env
+        end
+      end
+      ENDING = End.new
+
+      class Before
+        def self.build(next_callback, user_callback, user_conditions, chain_config, filter)
+          halted_lambda = chain_config[:terminator]
+
+          if chain_config.key?(:terminator) && user_conditions.any?
+            halting_and_conditional(next_callback, user_callback, user_conditions, halted_lambda, filter)
+          elsif chain_config.key? :terminator
+            halting(next_callback, user_callback, halted_lambda, filter)
+          elsif user_conditions.any?
+            conditional(next_callback, user_callback, user_conditions)
+          else
+            simple next_callback, user_callback
+          end
+        end
+
+        private
+
+        def self.halting_and_conditional(next_callback, user_callback, user_conditions, halted_lambda, filter)
+          lambda { |env|
+            target = env.target
+            value  = env.value
+            halted = env.halted
+
+            if !halted && user_conditions.all? { |c| c.call(target, value) }
+              result = user_callback.call target, value
+              env.halted = halted_lambda.call(target, result)
+              if env.halted
+                target.send :halted_callback_hook, filter
+              end
+            end
+            next_callback.call env
+          }
+        end
+
+        def self.halting(next_callback, user_callback, halted_lambda, filter)
+          lambda { |env|
+            target = env.target
+            value  = env.value
+            halted = env.halted
+
+            unless halted
+              result = user_callback.call target, value
+              env.halted = halted_lambda.call(target, result)
+              if env.halted
+                target.send :halted_callback_hook, filter
+              end
+            end
+            next_callback.call env
+          }
+        end
+
+        def self.conditional(next_callback, user_callback, user_conditions)
+          lambda { |env|
+            target = env.target
+            value  = env.value
+
+            if user_conditions.all? { |c| c.call(target, value) }
+              user_callback.call target, value
+            end
+            next_callback.call env
+          }
+        end
+
+        def self.simple(next_callback, user_callback)
+          lambda { |env|
+            user_callback.call env.target, env.value
+            next_callback.call env
+          }
+        end
+      end
+
+      class After
+        def self.build(next_callback, user_callback, user_conditions, chain_config)
+          if chain_config[:skip_after_callbacks_if_terminated]
+            if chain_config.key?(:terminator) && user_conditions.any?
+              halting_and_conditional(next_callback, user_callback, user_conditions)
+            elsif chain_config.key?(:terminator)
+              halting(next_callback, user_callback)
+            elsif user_conditions.any?
+              conditional next_callback, user_callback, user_conditions
+            else
+              simple next_callback, user_callback
+            end
+          else
+            if user_conditions.any?
+              conditional next_callback, user_callback, user_conditions
+            else
+              simple next_callback, user_callback
+            end
+          end
+        end
+
+        private
+
+        def self.halting_and_conditional(next_callback, user_callback, user_conditions)
+          lambda { |env|
+            env = next_callback.call env
+            target = env.target
+            value  = env.value
+            halted = env.halted
+
+            if !halted && user_conditions.all? { |c| c.call(target, value) }
+              user_callback.call target, value
+            end
+            env
+          }
+        end
+
+        def self.halting(next_callback, user_callback)
+          lambda { |env|
+            env = next_callback.call env
+            unless env.halted
+              user_callback.call env.target, env.value
+            end
+            env
+          }
+        end
+
+        def self.conditional(next_callback, user_callback, user_conditions)
+          lambda { |env|
+            env = next_callback.call env
+            target = env.target
+            value  = env.value
+
+            if user_conditions.all? { |c| c.call(target, value) }
+              user_callback.call target, value
+            end
+            env
+          }
+        end
+
+        def self.simple(next_callback, user_callback)
+          lambda { |env|
+            env = next_callback.call env
+            user_callback.call env.target, env.value
+            env
+          }
+        end
+      end
+
+      class Around
+        def self.build(next_callback, user_callback, user_conditions, chain_config)
+          if chain_config.key?(:terminator) && user_conditions.any?
+            halting_and_conditional(next_callback, user_callback, user_conditions)
+          elsif chain_config.key? :terminator
+            halting(next_callback, user_callback)
+          elsif user_conditions.any?
+            conditional(next_callback, user_callback, user_conditions)
+          else
+            simple(next_callback, user_callback)
+          end
+        end
+
+        private
+
+        def self.halting_and_conditional(next_callback, user_callback, user_conditions)
+          lambda { |env|
+            target = env.target
+            value  = env.value
+            halted = env.halted
+
+            if !halted && user_conditions.all? { |c| c.call(target, value) }
+              user_callback.call(target, value) {
+                env = next_callback.call env
+                env.value
+              }
+              env
+            else
+              next_callback.call env
+            end
+          }
+        end
+
+        def self.halting(next_callback, user_callback)
+          lambda { |env|
+            target = env.target
+            value  = env.value
+
+            unless env.halted
+              user_callback.call(target, value) {
+                env = next_callback.call env
+                env.value
+              }
+              env
+            else
+              next_callback.call env
+            end
+          }
+        end
+
+        def self.conditional(next_callback, user_callback, user_conditions)
+          lambda { |env|
+            target = env.target
+            value  = env.value
+
+            if user_conditions.all? { |c| c.call(target, value) }
+              user_callback.call(target, value) {
+                env = next_callback.call env
+                env.value
+              }
+              env
+            else
+              next_callback.call env
+            end
+          }
+        end
+
+        def self.simple(next_callback, user_callback)
+          lambda { |env|
+            user_callback.call(env.target, env.value) {
+              env = next_callback.call env
+              env.value
+            }
+            env
+          }
+        end
+      end
+    end
+
+    class Callback #:nodoc:#
+      def self.build(chain, filter, kind, options)
+        new chain.name, filter, kind, options, chain.config
+      end
+
+      attr_accessor :kind, :name
+      attr_reader :chain_config
+
+      def initialize(name, filter, kind, options, chain_config)
+        @chain_config  = chain_config
+        @name    = name
+        @kind    = kind
+        @filter  = filter
+        @key     = compute_identifier filter
+        @if      = Array(options[:if])
+        @unless  = Array(options[:unless])
+      end
+
+      def filter; @key; end
+      def raw_filter; @filter; end
+
+      def merge(chain, new_options)
+        options = {
+          :if     => @if.dup,
+          :unless => @unless.dup
+        }
+
+        options[:if].concat     Array(new_options.fetch(:unless, []))
+        options[:unless].concat Array(new_options.fetch(:if, []))
+
+        self.class.build chain, @filter, @kind, options
+      end
+
+      def matches?(_kind, _filter)
+        @kind == _kind && filter == _filter
+      end
+
+      def duplicates?(other)
+        case @filter
+        when Symbol, String
+          matches?(other.kind, other.filter)
+        else
+          false
+        end
+      end
+
+      # Wraps code with filter
+      def apply(next_callback)
+        user_conditions = conditions_lambdas
+        user_callback = make_lambda @filter
+
+        case kind
+        when :before
+          Filters::Before.build(next_callback, user_callback, user_conditions, chain_config, @filter)
+        when :after
+          Filters::After.build(next_callback, user_callback, user_conditions, chain_config)
+        when :around
+          Filters::Around.build(next_callback, user_callback, user_conditions, chain_config)
+        end
+      end
+
+      private
+
+      def invert_lambda(l)
+        lambda { |*args, &blk| !l.call(*args, &blk) }
+      end
+
+      # Filters support:
+      #
+      #   Symbols:: A method to call.
+      #   Strings:: Some content to evaluate.
+      #   Procs::   A proc to call with the object.
+      #   Objects:: An object with a <tt>before_foo</tt> method on it to call.
+      #
+      # All of these objects are compiled into methods and handled
+      # the same after this point:
+      #
+      #   Symbols:: Already methods.
+      #   Strings:: class_eval'd into methods.
+      #   Procs::   using define_method compiled into methods.
+      #   Objects::
+      #     a method is created that calls the before_foo method
+      #     on the object.
+      def make_lambda(filter)
+        case filter
+        when Symbol
+          lambda { |target, _, &blk| target.send filter, &blk }
+        when String
+          l = eval "lambda { |value| #{filter} }"
+          lambda { |target, value| target.instance_exec(value, &l) }
+        when Conditionals::Value then filter
+        when ::Proc
+          if filter.arity > 1
+            return lambda { |target, _, &block|
+              raise ArgumentError unless block
+              target.instance_exec(target, block, &filter)
+            }
+          end
+
+          if filter.arity <= 0
+            lambda { |target, _| target.instance_exec(&filter) }
+          else
+            lambda { |target, _| target.instance_exec(target, &filter) }
+          end
+        else
+          scopes = Array(chain_config[:scope])
+          method_to_call = scopes.map{ |s| public_send(s) }.join("_")
+
+          lambda { |target, _, &blk|
+            filter.public_send method_to_call, target, &blk
+          }
+        end
+      end
+
+      def compute_identifier(filter)
+        case filter
+        when String, ::Proc
+          filter.object_id
+        else
+          filter
+        end
+      end
+
+      def conditions_lambdas
+        @if.map { |c| make_lambda c } +
+          @unless.map { |c| invert_lambda make_lambda c }
+      end
+    end
+
+    # An Array with a compile method.
+    class CallbackChain #:nodoc:#
+      include Enumerable
+
+      attr_reader :name, :config
+
+      def initialize(name, config)
+        @name = name
+        @config = {
+          :scope => [ :kind ]
+        }.merge!(config)
+        @chain = []
+        @callbacks = nil
+        @mutex = Mutex.new
+      end
+
+      def each(&block); @chain.each(&block); end
+      def index(o);     @chain.index(o); end
+      def empty?;       @chain.empty?; end
+
+      def insert(index, o)
+        @callbacks = nil
+        @chain.insert(index, o)
+      end
+
+      def delete(o)
+        @callbacks = nil
+        @chain.delete(o)
+      end
+
+      def clear
+        @callbacks = nil
+        @chain.clear
+        self
+      end
+
+      def initialize_copy(other)
+        @callbacks = nil
+        @chain     = other.chain.dup
+        @mutex     = Mutex.new
+      end
+
+      def compile
+        @callbacks || @mutex.synchronize do
+          @callbacks ||= @chain.reverse.inject(Filters::ENDING) do |chain, callback|
+            callback.apply chain
+          end
+        end
+      end
+
+      def append(*callbacks)
+        callbacks.each { |c| append_one(c) }
+      end
+
+      def prepend(*callbacks)
+        callbacks.each { |c| prepend_one(c) }
+      end
+
+      protected
+      def chain; @chain; end
+
+      private
+
+      def append_one(callback)
+        @callbacks = nil
+        remove_duplicates(callback)
+        @chain.push(callback)
+      end
+
+      def prepend_one(callback)
+        @callbacks = nil
+        remove_duplicates(callback)
+        @chain.unshift(callback)
+      end
+
+      def remove_duplicates(callback)
+        @callbacks = nil
+        @chain.delete_if { |c| callback.duplicates?(c) }
+      end
+    end
+
+    module ClassMethods
+      def normalize_callback_params(filters, block) # :nodoc:
+        type = CALLBACK_FILTER_TYPES.include?(filters.first) ? filters.shift : :before
+        options = filters.extract_options!
+        filters.unshift(block) if block
+        [type, filters, options.dup]
+      end
+
+      # This is used internally to append, prepend and skip callbacks to the
+      # CallbackChain.
+      def __update_callbacks(name) #:nodoc:
+        ([self] + ActiveSupport::DescendantsTracker.descendants(self)).reverse.each do |target|
+          chain = target.get_callbacks name
+          yield target, chain.dup
+        end
+      end
+
+      # Install a callback for the given event.
+      #
+      #   set_callback :save, :before, :before_meth
+      #   set_callback :save, :after,  :after_meth, if: :condition
+      #   set_callback :save, :around, ->(r, &block) { stuff; result = block.call; stuff }
+      #
+      # The second arguments indicates whether the callback is to be run +:before+,
+      # +:after+, or +:around+ the event. If omitted, +:before+ is assumed. This
+      # means the first example above can also be written as:
+      #
+      #   set_callback :save, :before_meth
+      #
+      # The callback can be specified as a symbol naming an instance method; as a
+      # proc, lambda, or block; as a string to be instance evaluated; or as an
+      # object that responds to a certain method determined by the <tt>:scope</tt>
+      # argument to +define_callbacks+.
+      #
+      # If a proc, lambda, or block is given, its body is evaluated in the context
+      # of the current object. It can also optionally accept the current object as
+      # an argument.
+      #
+      # Before and around callbacks are called in the order that they are set;
+      # after callbacks are called in the reverse order.
+      #
+      # Around callbacks can access the return value from the event, if it
+      # wasn't halted, from the +yield+ call.
+      #
+      # ===== Options
+      #
+      # * <tt>:if</tt> - A symbol naming an instance method or a proc; the
+      #   callback will be called only when it returns a +true+ value.
+      # * <tt>:unless</tt> - A symbol naming an instance method or a proc; the
+      #   callback will be called only when it returns a +false+ value.
+      # * <tt>:prepend</tt> - If +true+, the callback will be prepended to the
+      #   existing chain rather than appended.
+      def set_callback(name, *filter_list, &block)
+        type, filters, options = normalize_callback_params(filter_list, block)
+        self_chain = get_callbacks name
+        mapped = filters.map do |filter|
+          Callback.build(self_chain, filter, type, options)
+        end
+
+        __update_callbacks(name) do |target, chain|
+          options[:prepend] ? chain.prepend(*mapped) : chain.append(*mapped)
+          target.set_callbacks name, chain
+        end
+      end
+
+      # Skip a previously set callback. Like +set_callback+, <tt>:if</tt> or
+      # <tt>:unless</tt> options may be passed in order to control when the
+      # callback is skipped.
+      #
+      #   class Writer < Person
+      #      skip_callback :validate, :before, :check_membership, if: -> { self.age > 18 }
+      #   end
+      def skip_callback(name, *filter_list, &block)
+        type, filters, options = normalize_callback_params(filter_list, block)
+
+        __update_callbacks(name) do |target, chain|
+          filters.each do |filter|
+            filter = chain.find {|c| c.matches?(type, filter) }
+
+            if filter && options.any?
+              new_filter = filter.merge(chain, options)
+              chain.insert(chain.index(filter), new_filter)
+            end
+
+            chain.delete(filter)
+          end
+          target.set_callbacks name, chain
+        end
+      end
+
+      # Remove all set callbacks for the given event.
+      def reset_callbacks(name)
+        callbacks = get_callbacks name
+
+        ActiveSupport::DescendantsTracker.descendants(self).each do |target|
+          chain = target.get_callbacks(name).dup
+          callbacks.each { |c| chain.delete(c) }
+          target.set_callbacks name, chain
+        end
+
+        self.set_callbacks name, callbacks.dup.clear
+      end
+
+      # Define sets of events in the object life cycle that support callbacks.
+      #
+      #   define_callbacks :validate
+      #   define_callbacks :initialize, :save, :destroy
+      #
+      # ===== Options
+      #
+      # * <tt>:terminator</tt> - Determines when a before filter will halt the
+      #   callback chain, preventing following callbacks from being called and
+      #   the event from being triggered. This should be a lambda to be executed.
+      #   The current object and the return result of the callback will be called
+      #   with the lambda.
+      #
+      #     define_callbacks :validate, terminator: ->(target, result) { result == false }
+      #
+      #   In this example, if any before validate callbacks returns +false+,
+      #   other callbacks are not executed. Defaults to +false+, meaning no value
+      #   halts the chain.
+      #
+      # * <tt>:skip_after_callbacks_if_terminated</tt> - Determines if after
+      #   callbacks should be terminated by the <tt>:terminator</tt> option. By
+      #   default after callbacks executed no matter if callback chain was
+      #   terminated or not. Option makes sense only when <tt>:terminator</tt>
+      #   option is specified.
+      #
+      # * <tt>:scope</tt> - Indicates which methods should be executed when an
+      #   object is used as a callback.
+      #
+      #     class Audit
+      #       def before(caller)
+      #         puts 'Audit: before is called'
+      #       end
+      #
+      #       def before_save(caller)
+      #         puts 'Audit: before_save is called'
+      #       end
+      #     end
+      #
+      #     class Account
+      #       include ActiveSupport::Callbacks
+      #
+      #       define_callbacks :save
+      #       set_callback :save, :before, Audit.new
+      #
+      #       def save
+      #         run_callbacks :save do
+      #           puts 'save in main'
+      #         end
+      #       end
+      #     end
+      #
+      #   In the above case whenever you save an account the method
+      #   <tt>Audit#before</tt> will be called. On the other hand
+      #
+      #     define_callbacks :save, scope: [:kind, :name]
+      #
+      #   would trigger <tt>Audit#before_save</tt> instead. That's constructed
+      #   by calling <tt>#{kind}_#{name}</tt> on the given instance. In this
+      #   case "kind" is "before" and "name" is "save". In this context +:kind+
+      #   and +:name+ have special meanings: +:kind+ refers to the kind of
+      #   callback (before/after/around) and +:name+ refers to the method on
+      #   which callbacks are being defined.
+      #
+      #   A declaration like
+      #
+      #     define_callbacks :save, scope: [:name]
+      #
+      #   would call <tt>Audit#save</tt>.
+      def define_callbacks(*names)
+        options = names.extract_options!
+        if options.key?(:terminator) && String === options[:terminator]
+          ActiveSupport::Deprecation.warn "String based terminators are deprecated, please use a lambda"
+          value = options[:terminator]
+          line = class_eval "lambda { |result| #{value} }", __FILE__, __LINE__
+          options[:terminator] = lambda { |target, result| target.instance_exec(result, &line) }
+        end
+
+        names.each do |name|
+          class_attribute "_#{name}_callbacks"
+          set_callbacks name, CallbackChain.new(name, options)
+        end
+      end
+
+      protected
+
+      def get_callbacks(name)
+        send "_#{name}_callbacks"
+      end
+
+      def set_callbacks(name, callbacks)
+        send "_#{name}_callbacks=", callbacks
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/concern.rb b/app/server/vendor/activesupport/lib/active_support/concern.rb
new file mode 100644
index 0000000..9d5cee5
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/concern.rb
@@ -0,0 +1,142 @@
+module ActiveSupport
+  # A typical module looks like this:
+  #
+  #   module M
+  #     def self.included(base)
+  #       base.extend ClassMethods
+  #       base.class_eval do
+  #         scope :disabled, -> { where(disabled: true) }
+  #       end
+  #     end
+  #
+  #     module ClassMethods
+  #       ...
+  #     end
+  #   end
+  #
+  # By using <tt>ActiveSupport::Concern</tt> the above module could instead be
+  # written as:
+  #
+  #   require 'active_support/concern'
+  #
+  #   module M
+  #     extend ActiveSupport::Concern
+  #
+  #     included do
+  #       scope :disabled, -> { where(disabled: true) }
+  #     end
+  #
+  #     class_methods do
+  #       ...
+  #     end
+  #   end
+  #
+  # Moreover, it gracefully handles module dependencies. Given a +Foo+ module
+  # and a +Bar+ module which depends on the former, we would typically write the
+  # following:
+  #
+  #   module Foo
+  #     def self.included(base)
+  #       base.class_eval do
+  #         def self.method_injected_by_foo
+  #           ...
+  #         end
+  #       end
+  #     end
+  #   end
+  #
+  #   module Bar
+  #     def self.included(base)
+  #       base.method_injected_by_foo
+  #     end
+  #   end
+  #
+  #   class Host
+  #     include Foo # We need to include this dependency for Bar
+  #     include Bar # Bar is the module that Host really needs
+  #   end
+  #
+  # But why should +Host+ care about +Bar+'s dependencies, namely +Foo+? We
+  # could try to hide these from +Host+ directly including +Foo+ in +Bar+:
+  #
+  #   module Bar
+  #     include Foo
+  #     def self.included(base)
+  #       base.method_injected_by_foo
+  #     end
+  #   end
+  #
+  #   class Host
+  #     include Bar
+  #   end
+  #
+  # Unfortunately this won't work, since when +Foo+ is included, its <tt>base</tt>
+  # is the +Bar+ module, not the +Host+ class. With <tt>ActiveSupport::Concern</tt>,
+  # module dependencies are properly resolved:
+  #
+  #   require 'active_support/concern'
+  #
+  #   module Foo
+  #     extend ActiveSupport::Concern
+  #     included do
+  #       def self.method_injected_by_foo
+  #         ...
+  #       end
+  #     end
+  #   end
+  #
+  #   module Bar
+  #     extend ActiveSupport::Concern
+  #     include Foo
+  #
+  #     included do
+  #       self.method_injected_by_foo
+  #     end
+  #   end
+  #
+  #   class Host
+  #     include Bar # works, Bar takes care now of its dependencies
+  #   end
+  module Concern
+    class MultipleIncludedBlocks < StandardError #:nodoc:
+      def initialize
+        super "Cannot define multiple 'included' blocks for a Concern"
+      end
+    end
+
+    def self.extended(base) #:nodoc:
+      base.instance_variable_set(:@_dependencies, [])
+    end
+
+    def append_features(base)
+      if base.instance_variable_defined?(:@_dependencies)
+        base.instance_variable_get(:@_dependencies) << self
+        return false
+      else
+        return false if base < self
+        @_dependencies.each { |dep| base.send(:include, dep) }
+        super
+        base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods)
+        base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block)
+      end
+    end
+
+    def included(base = nil, &block)
+      if base.nil?
+        raise MultipleIncludedBlocks if instance_variable_defined?(:@_included_block)
+
+        @_included_block = block
+      else
+        super
+      end
+    end
+
+    def class_methods(&class_methods_module_definition)
+      mod = const_defined?(:ClassMethods) ?
+        const_get(:ClassMethods) :
+        const_set(:ClassMethods, Module.new)
+
+      mod.module_eval(&class_methods_module_definition)
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/concurrency/latch.rb b/app/server/vendor/activesupport/lib/active_support/concurrency/latch.rb
new file mode 100644
index 0000000..1507de4
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/concurrency/latch.rb
@@ -0,0 +1,27 @@
+require 'thread'
+require 'monitor'
+
+module ActiveSupport
+  module Concurrency
+    class Latch
+      def initialize(count = 1)
+        @count = count
+        @lock = Monitor.new
+        @cv = @lock.new_cond
+      end
+
+      def release
+        @lock.synchronize do
+          @count -= 1 if @count > 0
+          @cv.broadcast if @count.zero?
+        end
+      end
+
+      def await
+        @lock.synchronize do
+          @cv.wait_while { @count > 0 }
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/configurable.rb b/app/server/vendor/activesupport/lib/active_support/configurable.rb
new file mode 100644
index 0000000..3dd44e3
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/configurable.rb
@@ -0,0 +1,147 @@
+require 'active_support/concern'
+require 'active_support/ordered_options'
+require 'active_support/core_ext/array/extract_options'
+
+module ActiveSupport
+  # Configurable provides a <tt>config</tt> method to store and retrieve
+  # configuration options as an <tt>OrderedHash</tt>.
+  module Configurable
+    extend ActiveSupport::Concern
+
+    class Configuration < ActiveSupport::InheritableOptions
+      def compile_methods!
+        self.class.compile_methods!(keys)
+      end
+
+      # Compiles reader methods so we don't have to go through method_missing.
+      def self.compile_methods!(keys)
+        keys.reject { |m| method_defined?(m) }.each do |key|
+          class_eval <<-RUBY, __FILE__, __LINE__ + 1
+            def #{key}; _get(#{key.inspect}); end
+          RUBY
+        end
+      end
+    end
+
+    module ClassMethods
+      def config
+        @_config ||= if respond_to?(:superclass) && superclass.respond_to?(:config)
+          superclass.config.inheritable_copy
+        else
+          # create a new "anonymous" class that will host the compiled reader methods
+          Class.new(Configuration).new
+        end
+      end
+
+      def configure
+        yield config
+      end
+
+      # Allows you to add shortcut so that you don't have to refer to attribute
+      # through config. Also look at the example for config to contrast.
+      #
+      # Defines both class and instance config accessors.
+      #
+      #   class User
+      #     include ActiveSupport::Configurable
+      #     config_accessor :allowed_access
+      #   end
+      #
+      #   User.allowed_access # => nil
+      #   User.allowed_access = false
+      #   User.allowed_access # => false
+      #
+      #   user = User.new
+      #   user.allowed_access # => false
+      #   user.allowed_access = true
+      #   user.allowed_access # => true
+      #
+      #   User.allowed_access # => false
+      #
+      # The attribute name must be a valid method name in Ruby.
+      #
+      #   class User
+      #     include ActiveSupport::Configurable
+      #     config_accessor :"1_Badname"
+      #   end
+      #   # => NameError: invalid config attribute name
+      #
+      # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
+      # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
+      #
+      #   class User
+      #     include ActiveSupport::Configurable
+      #     config_accessor :allowed_access, instance_reader: false, instance_writer: false
+      #   end
+      #
+      #   User.allowed_access = false
+      #   User.allowed_access # => false
+      #
+      #   User.new.allowed_access = true # => NoMethodError
+      #   User.new.allowed_access        # => NoMethodError
+      #
+      # Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
+      #
+      #   class User
+      #     include ActiveSupport::Configurable
+      #     config_accessor :allowed_access, instance_accessor: false
+      #   end
+      #
+      #   User.allowed_access = false
+      #   User.allowed_access # => false
+      #
+      #   User.new.allowed_access = true # => NoMethodError
+      #   User.new.allowed_access        # => NoMethodError
+      #
+      # Also you can pass a block to set up the attribute with a default value.
+      #
+      #   class User
+      #     include ActiveSupport::Configurable
+      #     config_accessor :hair_colors do
+      #       [:brown, :black, :blonde, :red]
+      #     end
+      #   end
+      #
+      #   User.hair_colors # => [:brown, :black, :blonde, :red]
+      def config_accessor(*names)
+        options = names.extract_options!
+
+        names.each do |name|
+          raise NameError.new('invalid config attribute name') unless name =~ /\A[_A-Za-z]\w*\z/
+
+          reader, reader_line = "def #{name}; config.#{name}; end", __LINE__
+          writer, writer_line = "def #{name}=(value); config.#{name} = value; end", __LINE__
+
+          singleton_class.class_eval reader, __FILE__, reader_line
+          singleton_class.class_eval writer, __FILE__, writer_line
+
+          unless options[:instance_accessor] == false
+            class_eval reader, __FILE__, reader_line unless options[:instance_reader] == false
+            class_eval writer, __FILE__, writer_line unless options[:instance_writer] == false
+          end
+          send("#{name}=", yield) if block_given?
+        end
+      end
+    end
+
+    # Reads and writes attributes from a configuration <tt>OrderedHash</tt>.
+    #
+    #   require 'active_support/configurable'
+    #
+    #   class User
+    #     include ActiveSupport::Configurable
+    #   end
+    #
+    #   user = User.new
+    #
+    #   user.config.allowed_access = true
+    #   user.config.level = 1
+    #
+    #   user.config.allowed_access # => true
+    #   user.config.level          # => 1
+    def config
+      @_config ||= self.class.config.inheritable_copy
+    end
+  end
+end
+
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext.rb b/app/server/vendor/activesupport/lib/active_support/core_ext.rb
new file mode 100644
index 0000000..199aa91
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext.rb
@@ -0,0 +1,3 @@
+Dir["#{File.dirname(__FILE__)}/core_ext/*.rb"].each do |path|
+  require path
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/array.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/array.rb
new file mode 100644
index 0000000..7d0c1e4
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/array.rb
@@ -0,0 +1,6 @@
+require 'active_support/core_ext/array/wrap'
+require 'active_support/core_ext/array/access'
+require 'active_support/core_ext/array/conversions'
+require 'active_support/core_ext/array/extract_options'
+require 'active_support/core_ext/array/grouping'
+require 'active_support/core_ext/array/prepend_and_append'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/array/access.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/array/access.rb
new file mode 100644
index 0000000..67f58bc
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/array/access.rb
@@ -0,0 +1,56 @@
+class Array
+  # Returns the tail of the array from +position+.
+  #
+  #   %w( a b c d ).from(0)  # => ["a", "b", "c", "d"]
+  #   %w( a b c d ).from(2)  # => ["c", "d"]
+  #   %w( a b c d ).from(10) # => []
+  #   %w().from(0)           # => []
+  def from(position)
+    self[position, length] || []
+  end
+
+  # Returns the beginning of the array up to +position+.
+  #
+  #   %w( a b c d ).to(0)  # => ["a"]
+  #   %w( a b c d ).to(2)  # => ["a", "b", "c"]
+  #   %w( a b c d ).to(10) # => ["a", "b", "c", "d"]
+  #   %w().to(0)           # => []
+  def to(position)
+    first position + 1
+  end
+
+  # Equal to <tt>self[1]</tt>.
+  #
+  #   %w( a b c d e ).second # => "b"
+  def second
+    self[1]
+  end
+
+  # Equal to <tt>self[2]</tt>.
+  #
+  #   %w( a b c d e ).third # => "c"
+  def third
+    self[2]
+  end
+
+  # Equal to <tt>self[3]</tt>.
+  #
+  #   %w( a b c d e ).fourth # => "d"
+  def fourth
+    self[3]
+  end
+
+  # Equal to <tt>self[4]</tt>.
+  #
+  #   %w( a b c d e ).fifth # => "e"
+  def fifth
+    self[4]
+  end
+
+  # Equal to <tt>self[41]</tt>. Also known as accessing "the reddit".
+  #
+  #   (1..42).to_a.forty_two # => 42
+  def forty_two
+    self[41]
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/array/conversions.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/array/conversions.rb
new file mode 100644
index 0000000..76ffd23
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/array/conversions.rb
@@ -0,0 +1,209 @@
+require 'active_support/xml_mini'
+require 'active_support/core_ext/hash/keys'
+require 'active_support/core_ext/string/inflections'
+require 'active_support/core_ext/object/to_param'
+require 'active_support/core_ext/object/to_query'
+
+class Array
+  # Converts the array to a comma-separated sentence where the last element is
+  # joined by the connector word.
+  #
+  # You can pass the following options to change the default behavior. If you
+  # pass an option key that doesn't exist in the list below, it will raise an
+  # <tt>ArgumentError</tt>.
+  #
+  # ==== Options
+  #
+  # * <tt>:words_connector</tt> - The sign or word used to join the elements
+  #   in arrays with two or more elements (default: ", ").
+  # * <tt>:two_words_connector</tt> - The sign or word used to join the elements
+  #   in arrays with two elements (default: " and ").
+  # * <tt>:last_word_connector</tt> - The sign or word used to join the last element
+  #   in arrays with three or more elements (default: ", and ").
+  # * <tt>:locale</tt> - If +i18n+ is available, you can set a locale and use
+  #   the connector options defined on the 'support.array' namespace in the
+  #   corresponding dictionary file.
+  #
+  # ==== Examples
+  #
+  #   [].to_sentence                      # => ""
+  #   ['one'].to_sentence                 # => "one"
+  #   ['one', 'two'].to_sentence          # => "one and two"
+  #   ['one', 'two', 'three'].to_sentence # => "one, two, and three"
+  #
+  #   ['one', 'two'].to_sentence(passing: 'invalid option')
+  #   # => ArgumentError: Unknown key :passing
+  #
+  #   ['one', 'two'].to_sentence(two_words_connector: '-')
+  #   # => "one-two"
+  #
+  #   ['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ')
+  #   # => "one or two or at least three"
+  #
+  # Using <tt>:locale</tt> option:
+  #
+  #   # Given this locale dictionary:
+  #   #
+  #   #   es:
+  #   #     support:
+  #   #       array:
+  #   #         words_connector: " o "
+  #   #         two_words_connector: " y "
+  #   #         last_word_connector: " o al menos "
+  #
+  #   ['uno', 'dos'].to_sentence(locale: :es)
+  #   # => "uno y dos"
+  #
+  #   ['uno', 'dos', 'tres'].to_sentence(locale: :es)
+  #   # => "uno o dos o al menos tres"
+  def to_sentence(options = {})
+    options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
+
+    default_connectors = {
+      :words_connector     => ', ',
+      :two_words_connector => ' and ',
+      :last_word_connector => ', and '
+    }
+    if defined?(I18n)
+      i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {})
+      default_connectors.merge!(i18n_connectors)
+    end
+    options = default_connectors.merge!(options)
+
+    case length
+    when 0
+      ''
+    when 1
+      self[0].to_s.dup
+    when 2
+      "#{self[0]}#{options[:two_words_connector]}#{self[1]}"
+    else
+      "#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
+    end
+  end
+
+  # Extends <tt>Array#to_s</tt> to convert a collection of elements into a
+  # comma separated id list if <tt>:db</tt> argument is given as the format.
+  #
+  #   Blog.all.to_formatted_s(:db) # => "1,2,3"
+  def to_formatted_s(format = :default)
+    case format
+    when :db
+      if empty?
+        'null'
+      else
+        collect { |element| element.id }.join(',')
+      end
+    else
+      to_default_s
+    end
+  end
+  alias_method :to_default_s, :to_s
+  alias_method :to_s, :to_formatted_s
+
+  # Returns a string that represents the array in XML by invoking +to_xml+
+  # on each element. Active Record collections delegate their representation
+  # in XML to this method.
+  #
+  # All elements are expected to respond to +to_xml+, if any of them does
+  # not then an exception is raised.
+  #
+  # The root node reflects the class name of the first element in plural
+  # if all elements belong to the same type and that's not Hash:
+  #
+  #   customer.projects.to_xml
+  #
+  #   <?xml version="1.0" encoding="UTF-8"?>
+  #   <projects type="array">
+  #     <project>
+  #       <amount type="decimal">20000.0</amount>
+  #       <customer-id type="integer">1567</customer-id>
+  #       <deal-date type="date">2008-04-09</deal-date>
+  #       ...
+  #     </project>
+  #     <project>
+  #       <amount type="decimal">57230.0</amount>
+  #       <customer-id type="integer">1567</customer-id>
+  #       <deal-date type="date">2008-04-15</deal-date>
+  #       ...
+  #     </project>
+  #   </projects>
+  #
+  # Otherwise the root element is "objects":
+  #
+  #   [{ foo: 1, bar: 2}, { baz: 3}].to_xml
+  #
+  #   <?xml version="1.0" encoding="UTF-8"?>
+  #   <objects type="array">
+  #     <object>
+  #       <bar type="integer">2</bar>
+  #       <foo type="integer">1</foo>
+  #     </object>
+  #     <object>
+  #       <baz type="integer">3</baz>
+  #     </object>
+  #   </objects>
+  #
+  # If the collection is empty the root element is "nil-classes" by default:
+  #
+  #   [].to_xml
+  #
+  #   <?xml version="1.0" encoding="UTF-8"?>
+  #   <nil-classes type="array"/>
+  #
+  # To ensure a meaningful root element use the <tt>:root</tt> option:
+  #
+  #   customer_with_no_projects.projects.to_xml(root: 'projects')
+  #
+  #   <?xml version="1.0" encoding="UTF-8"?>
+  #   <projects type="array"/>
+  #
+  # By default name of the node for the children of root is <tt>root.singularize</tt>.
+  # You can change it with the <tt>:children</tt> option.
+  #
+  # The +options+ hash is passed downwards:
+  #
+  #   Message.all.to_xml(skip_types: true)
+  #
+  #   <?xml version="1.0" encoding="UTF-8"?>
+  #   <messages>
+  #     <message>
+  #       <created-at>2008-03-07T09:58:18+01:00</created-at>
+  #       <id>1</id>
+  #       <name>1</name>
+  #       <updated-at>2008-03-07T09:58:18+01:00</updated-at>
+  #       <user-id>1</user-id>
+  #     </message>
+  #   </messages>
+  #
+  def to_xml(options = {})
+    require 'active_support/builder' unless defined?(Builder)
+
+    options = options.dup
+    options[:indent]  ||= 2
+    options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
+    options[:root]    ||= \
+      if first.class != Hash && all? { |e| e.is_a?(first.class) }
+        underscored = ActiveSupport::Inflector.underscore(first.class.name)
+        ActiveSupport::Inflector.pluralize(underscored).tr('/', '_')
+      else
+        'objects'
+      end
+
+    builder = options[:builder]
+    builder.instruct! unless options.delete(:skip_instruct)
+
+    root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options)
+    children = options.delete(:children) || root.singularize
+    attributes = options[:skip_types] ? {} : { type: 'array' }
+
+    if empty?
+      builder.tag!(root, attributes)
+    else
+      builder.tag!(root, attributes) do
+        each { |value| ActiveSupport::XmlMini.to_tag(children, value, options) }
+        yield builder if block_given?
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/array/extract_options.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/array/extract_options.rb
new file mode 100644
index 0000000..9008a0d
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/array/extract_options.rb
@@ -0,0 +1,29 @@
+class Hash
+  # By default, only instances of Hash itself are extractable.
+  # Subclasses of Hash may implement this method and return
+  # true to declare themselves as extractable. If a Hash
+  # is extractable, Array#extract_options! pops it from
+  # the Array when it is the last element of the Array.
+  def extractable_options?
+    instance_of?(Hash)
+  end
+end
+
+class Array
+  # Extracts options from a set of arguments. Removes and returns the last
+  # element in the array if it's a hash, otherwise returns a blank hash.
+  #
+  #   def options(*args)
+  #     args.extract_options!
+  #   end
+  #
+  #   options(1, 2)        # => {}
+  #   options(1, 2, a: :b) # => {:a=>:b}
+  def extract_options!
+    if last.is_a?(Hash) && last.extractable_options?
+      pop
+    else
+      {}
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/array/grouping.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/array/grouping.rb
new file mode 100644
index 0000000..3529d57
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/array/grouping.rb
@@ -0,0 +1,111 @@
+class Array
+  # Splits or iterates over the array in groups of size +number+,
+  # padding any remaining slots with +fill_with+ unless it is +false+.
+  #
+  #   %w(1 2 3 4 5 6 7 8 9 10).in_groups_of(3) {|group| p group}
+  #   ["1", "2", "3"]
+  #   ["4", "5", "6"]
+  #   ["7", "8", "9"]
+  #   ["10", nil, nil]
+  #
+  #   %w(1 2 3 4 5).in_groups_of(2, ' ') {|group| p group}
+  #   ["1", "2"]
+  #   ["3", "4"]
+  #   ["5", " "]
+  #
+  #   %w(1 2 3 4 5).in_groups_of(2, false) {|group| p group}
+  #   ["1", "2"]
+  #   ["3", "4"]
+  #   ["5"]
+  def in_groups_of(number, fill_with = nil)
+    if fill_with == false
+      collection = self
+    else
+      # size % number gives how many extra we have;
+      # subtracting from number gives how many to add;
+      # modulo number ensures we don't add group of just fill.
+      padding = (number - size % number) % number
+      collection = dup.concat(Array.new(padding, fill_with))
+    end
+
+    if block_given?
+      collection.each_slice(number) { |slice| yield(slice) }
+    else
+      collection.each_slice(number).to_a
+    end
+  end
+
+  # Splits or iterates over the array in +number+ of groups, padding any
+  # remaining slots with +fill_with+ unless it is +false+.
+  #
+  #   %w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group}
+  #   ["1", "2", "3", "4"]
+  #   ["5", "6", "7", nil]
+  #   ["8", "9", "10", nil]
+  #
+  #   %w(1 2 3 4 5 6 7 8 9 10).in_groups(3, ' ') {|group| p group}
+  #   ["1", "2", "3", "4"]
+  #   ["5", "6", "7", " "]
+  #   ["8", "9", "10", " "]
+  #
+  #   %w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
+  #   ["1", "2", "3"]
+  #   ["4", "5"]
+  #   ["6", "7"]
+  def in_groups(number, fill_with = nil)
+    # size.div number gives minor group size;
+    # size % number gives how many objects need extra accommodation;
+    # each group hold either division or division + 1 items.
+    division = size.div number
+    modulo = size % number
+
+    # create a new array avoiding dup
+    groups = []
+    start = 0
+
+    number.times do |index|
+      length = division + (modulo > 0 && modulo > index ? 1 : 0)
+      groups << last_group = slice(start, length)
+      last_group << fill_with if fill_with != false &&
+        modulo > 0 && length == division
+      start += length
+    end
+
+    if block_given?
+      groups.each { |g| yield(g) }
+    else
+      groups
+    end
+  end
+
+  # Divides the array into one or more subarrays based on a delimiting +value+
+  # or the result of an optional block.
+  #
+  #   [1, 2, 3, 4, 5].split(3)              # => [[1, 2], [4, 5]]
+  #   (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
+  def split(value = nil)
+    if block_given?
+      inject([[]]) do |results, element|
+        if yield(element)
+          results << []
+        else
+          results.last << element
+        end
+
+        results
+      end
+    else
+      results, arr = [[]], self.dup
+      until arr.empty?
+        if (idx = arr.index(value))
+          results.last.concat(arr.shift(idx))
+          arr.shift
+          results << []
+        else
+          results.last.concat(arr.shift(arr.size))
+        end
+      end
+      results
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/array/prepend_and_append.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/array/prepend_and_append.rb
new file mode 100644
index 0000000..f8d48b6
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/array/prepend_and_append.rb
@@ -0,0 +1,7 @@
+class Array
+  # The human way of thinking about adding stuff to the end of a list is with append.
+  alias_method :append,  :<<
+
+  # The human way of thinking about adding stuff to the beginning of a list is with prepend.
+  alias_method :prepend, :unshift
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/array/wrap.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/array/wrap.rb
new file mode 100644
index 0000000..152eb02
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/array/wrap.rb
@@ -0,0 +1,45 @@
+class Array
+  # Wraps its argument in an array unless it is already an array (or array-like).
+  #
+  # Specifically:
+  #
+  # * If the argument is +nil+ an empty list is returned.
+  # * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
+  # * Otherwise, returns an array with the argument as its single element.
+  #
+  #     Array.wrap(nil)       # => []
+  #     Array.wrap([1, 2, 3]) # => [1, 2, 3]
+  #     Array.wrap(0)         # => [0]
+  #
+  # This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
+  #
+  # * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
+  #   moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
+  #   +nil+ right away.
+  # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
+  #   raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
+  # * It does not call +to_a+ on the argument, but returns an empty array if argument is +nil+.
+  #
+  # The second point is easily explained with some enumerables:
+  #
+  #   Array(foo: :bar)      # => [[:foo, :bar]]
+  #   Array.wrap(foo: :bar) # => [{:foo=>:bar}]
+  #
+  # There's also a related idiom that uses the splat operator:
+  #
+  #   [*object]
+  #
+  # which returns <tt>[]</tt> for +nil+, but calls to <tt>Array(object)</tt> otherwise.
+  #
+  # The differences with <tt>Kernel#Array</tt> explained above
+  # apply to the rest of <tt>object</tt>s.
+  def self.wrap(object)
+    if object.nil?
+      []
+    elsif object.respond_to?(:to_ary)
+      object.to_ary || [object]
+    else
+      [object]
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/benchmark.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/benchmark.rb
new file mode 100644
index 0000000..eb25b2b
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/benchmark.rb
@@ -0,0 +1,14 @@
+require 'benchmark'
+
+class << Benchmark
+  # Benchmark realtime in milliseconds.
+  #
+  #   Benchmark.realtime { User.all }
+  #   # => 8.0e-05
+  #
+  #   Benchmark.ms { User.all }
+  #   # => 0.074
+  def ms
+    1000 * realtime { yield }
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/big_decimal.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/big_decimal.rb
new file mode 100644
index 0000000..8143113
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/big_decimal.rb
@@ -0,0 +1 @@
+require 'active_support/core_ext/big_decimal/conversions'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/big_decimal/conversions.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/big_decimal/conversions.rb
new file mode 100644
index 0000000..843c592
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/big_decimal/conversions.rb
@@ -0,0 +1,16 @@
+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class BigDecimal
+  DEFAULT_STRING_FORMAT = 'F'
+  def to_formatted_s(*args)
+    if args[0].is_a?(Symbol)
+      super
+    else
+      format = args[0] || DEFAULT_STRING_FORMAT
+      _original_to_s(format)
+    end
+  end
+  alias_method :_original_to_s, :to_s
+  alias_method :to_s, :to_formatted_s
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/big_decimal/yaml_conversions.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/big_decimal/yaml_conversions.rb
new file mode 100644
index 0000000..46ba93e
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/big_decimal/yaml_conversions.rb
@@ -0,0 +1,14 @@
+ActiveSupport::Deprecation.warn 'core_ext/big_decimal/yaml_conversions is deprecated and will be removed in the future.'
+
+require 'bigdecimal'
+require 'yaml'
+require 'active_support/core_ext/big_decimal/conversions'
+
+class BigDecimal
+  YAML_MAPPING = { 'Infinity' => '.Inf', '-Infinity' => '-.Inf', 'NaN' => '.NaN' }
+
+  def encode_with(coder)
+    string = to_s
+    coder.represent_scalar(nil, YAML_MAPPING[string] || string)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/class.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/class.rb
new file mode 100644
index 0000000..c750a10
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/class.rb
@@ -0,0 +1,3 @@
+require 'active_support/core_ext/class/attribute'
+require 'active_support/core_ext/class/delegating_attributes'
+require 'active_support/core_ext/class/subclasses'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/class/attribute.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/class/attribute.rb
new file mode 100644
index 0000000..f2a221c
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/class/attribute.rb
@@ -0,0 +1,127 @@
+require 'active_support/core_ext/kernel/singleton_class'
+require 'active_support/core_ext/module/remove_method'
+require 'active_support/core_ext/array/extract_options'
+
+class Class
+  # Declare a class-level attribute whose value is inheritable by subclasses.
+  # Subclasses can change their own value and it will not impact parent class.
+  #
+  #   class Base
+  #     class_attribute :setting
+  #   end
+  #
+  #   class Subclass < Base
+  #   end
+  #
+  #   Base.setting = true
+  #   Subclass.setting            # => true
+  #   Subclass.setting = false
+  #   Subclass.setting            # => false
+  #   Base.setting                # => true
+  #
+  # In the above case as long as Subclass does not assign a value to setting
+  # by performing <tt>Subclass.setting = _something_ </tt>, <tt>Subclass.setting</tt>
+  # would read value assigned to parent class. Once Subclass assigns a value then
+  # the value assigned by Subclass would be returned.
+  #
+  # This matches normal Ruby method inheritance: think of writing an attribute
+  # on a subclass as overriding the reader method. However, you need to be aware
+  # when using +class_attribute+ with mutable structures as +Array+ or +Hash+.
+  # In such cases, you don't want to do changes in places but use setters:
+  #
+  #   Base.setting = []
+  #   Base.setting                # => []
+  #   Subclass.setting            # => []
+  #
+  #   # Appending in child changes both parent and child because it is the same object:
+  #   Subclass.setting << :foo
+  #   Base.setting               # => [:foo]
+  #   Subclass.setting           # => [:foo]
+  #
+  #   # Use setters to not propagate changes:
+  #   Base.setting = []
+  #   Subclass.setting += [:foo]
+  #   Base.setting               # => []
+  #   Subclass.setting           # => [:foo]
+  #
+  # For convenience, an instance predicate method is defined as well.
+  # To skip it, pass <tt>instance_predicate: false</tt>.
+  #
+  #   Subclass.setting?       # => false
+  #
+  # Instances may overwrite the class value in the same way:
+  #
+  #   Base.setting = true
+  #   object = Base.new
+  #   object.setting          # => true
+  #   object.setting = false
+  #   object.setting          # => false
+  #   Base.setting            # => true
+  #
+  # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
+  #
+  #   object.setting          # => NoMethodError
+  #   object.setting?         # => NoMethodError
+  #
+  # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
+  #
+  #   object.setting = false  # => NoMethodError
+  #
+  # To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
+  def class_attribute(*attrs)
+    options = attrs.extract_options!
+    instance_reader = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
+    instance_writer = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true)
+    instance_predicate = options.fetch(:instance_predicate, true)
+
+    attrs.each do |name|
+      define_singleton_method(name) { nil }
+      define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
+
+      ivar = "@#{name}"
+
+      define_singleton_method("#{name}=") do |val|
+        singleton_class.class_eval do
+          remove_possible_method(name)
+          define_method(name) { val }
+        end
+
+        if singleton_class?
+          class_eval do
+            remove_possible_method(name)
+            define_method(name) do
+              if instance_variable_defined? ivar
+                instance_variable_get ivar
+              else
+                singleton_class.send name
+              end
+            end
+          end
+        end
+        val
+      end
+
+      if instance_reader
+        remove_possible_method name
+        define_method(name) do
+          if instance_variable_defined?(ivar)
+            instance_variable_get ivar
+          else
+            self.class.public_send name
+          end
+        end
+        define_method("#{name}?") { !!public_send(name) } if instance_predicate
+      end
+
+      attr_writer name if instance_writer
+    end
+  end
+
+  private
+
+    unless respond_to?(:singleton_class?)
+      def singleton_class?
+        ancestors.first != self
+      end
+    end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
new file mode 100644
index 0000000..84d5e95
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
@@ -0,0 +1,4 @@
+# cattr_* became mattr_* aliases in 7dfbd91b0780fbd6a1dd9bfbc176e10894871d2d,
+# but we keep this around for libraries that directly require it knowing they
+# want cattr_*. No need to deprecate.
+require 'active_support/core_ext/module/attribute_accessors'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
new file mode 100644
index 0000000..1c305c5
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
@@ -0,0 +1,45 @@
+require 'active_support/core_ext/kernel/singleton_class'
+require 'active_support/core_ext/module/remove_method'
+require 'active_support/core_ext/module/deprecation'
+
+
+class Class
+  def superclass_delegating_accessor(name, options = {})
+    # Create private _name and _name= methods that can still be used if the public
+    # methods are overridden.
+    _superclass_delegating_accessor("_#{name}", options)
+
+    # Generate the public methods name, name=, and name?.
+    # These methods dispatch to the private _name, and _name= methods, making them
+    # overridable.
+    singleton_class.send(:define_method, name) { send("_#{name}") }
+    singleton_class.send(:define_method, "#{name}?") { !!send("_#{name}") }
+    singleton_class.send(:define_method, "#{name}=") { |value| send("_#{name}=", value) }
+
+    # If an instance_reader is needed, generate public instance methods name and name?.
+    if options[:instance_reader] != false
+      define_method(name) { send("_#{name}") }
+      define_method("#{name}?") { !!send("#{name}") }
+    end
+  end
+
+  deprecate superclass_delegating_accessor: :class_attribute
+
+  private
+    # Take the object being set and store it in a method. This gives us automatic
+    # inheritance behavior, without having to store the object in an instance
+    # variable and look up the superclass chain manually.
+    def _stash_object_in_method(object, method, instance_reader = true)
+      singleton_class.remove_possible_method(method)
+      singleton_class.send(:define_method, method) { object }
+      remove_possible_method(method)
+      define_method(method) { object } if instance_reader
+    end
+
+    def _superclass_delegating_accessor(name, options = {})
+      singleton_class.send(:define_method, "#{name}=") do |value|
+        _stash_object_in_method(value, name, options[:instance_reader] != false)
+      end
+      send("#{name}=", nil)
+    end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/class/subclasses.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/class/subclasses.rb
new file mode 100644
index 0000000..3c4bfc5
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/class/subclasses.rb
@@ -0,0 +1,42 @@
+require 'active_support/core_ext/module/anonymous'
+require 'active_support/core_ext/module/reachable'
+
+class Class
+  begin
+    ObjectSpace.each_object(Class.new) {}
+
+    def descendants # :nodoc:
+      descendants = []
+      ObjectSpace.each_object(singleton_class) do |k|
+        descendants.unshift k unless k == self
+      end
+      descendants
+    end
+  rescue StandardError # JRuby
+    def descendants # :nodoc:
+      descendants = []
+      ObjectSpace.each_object(Class) do |k|
+        descendants.unshift k if k < self
+      end
+      descendants.uniq!
+      descendants
+    end
+  end
+
+  # Returns an array with the direct children of +self+.
+  #
+  #   Integer.subclasses # => [Fixnum, Bignum]
+  #
+  #   class Foo; end
+  #   class Bar < Foo; end
+  #   class Baz < Bar; end
+  #
+  #   Foo.subclasses # => [Bar]
+  def subclasses
+    subclasses, chain = [], descendants
+    chain.each do |k|
+      subclasses << k unless chain.any? { |c| c > k }
+    end
+    subclasses
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/date.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/date.rb
new file mode 100644
index 0000000..465fedd
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/date.rb
@@ -0,0 +1,5 @@
+require 'active_support/core_ext/date/acts_like'
+require 'active_support/core_ext/date/calculations'
+require 'active_support/core_ext/date/conversions'
+require 'active_support/core_ext/date/zones'
+
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/date/acts_like.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/date/acts_like.rb
new file mode 100644
index 0000000..cd90cee
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/date/acts_like.rb
@@ -0,0 +1,8 @@
+require 'active_support/core_ext/object/acts_like'
+
+class Date
+  # Duck-types as a Date-like class. See Object#acts_like?.
+  def acts_like_date?
+    true
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/date/calculations.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/date/calculations.rb
new file mode 100644
index 0000000..c60e833
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/date/calculations.rb
@@ -0,0 +1,143 @@
+require 'date'
+require 'active_support/duration'
+require 'active_support/core_ext/object/acts_like'
+require 'active_support/core_ext/date/zones'
+require 'active_support/core_ext/time/zones'
+require 'active_support/core_ext/date_and_time/calculations'
+
+class Date
+  include DateAndTime::Calculations
+
+  class << self
+    attr_accessor :beginning_of_week_default
+
+    # Returns the week start (e.g. :monday) for the current request, if this has been set (via Date.beginning_of_week=).
+    # If <tt>Date.beginning_of_week</tt> has not been set for the current request, returns the week start specified in <tt>config.beginning_of_week</tt>.
+    # If no config.beginning_of_week was specified, returns :monday.
+    def beginning_of_week
+      Thread.current[:beginning_of_week] || beginning_of_week_default || :monday
+    end
+
+    # Sets <tt>Date.beginning_of_week</tt> to a week start (e.g. :monday) for current request/thread.
+    #
+    # This method accepts any of the following day symbols:
+    # :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday
+    def beginning_of_week=(week_start)
+      Thread.current[:beginning_of_week] = find_beginning_of_week!(week_start)
+    end
+
+    # Returns week start day symbol (e.g. :monday), or raises an ArgumentError for invalid day symbol.
+    def find_beginning_of_week!(week_start)
+      raise ArgumentError, "Invalid beginning of week: #{week_start}" unless ::Date::DAYS_INTO_WEEK.key?(week_start)
+      week_start
+    end
+
+    # Returns a new Date representing the date 1 day ago (i.e. yesterday's date).
+    def yesterday
+      ::Date.current.yesterday
+    end
+
+    # Returns a new Date representing the date 1 day after today (i.e. tomorrow's date).
+    def tomorrow
+      ::Date.current.tomorrow
+    end
+
+    # Returns Time.zone.today when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise just returns Date.today.
+    def current
+      ::Time.zone ? ::Time.zone.today : ::Date.today
+    end
+  end
+
+  # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
+  # and then subtracts the specified number of seconds.
+  def ago(seconds)
+    in_time_zone.since(-seconds)
+  end
+
+  # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
+  # and then adds the specified number of seconds
+  def since(seconds)
+    in_time_zone.since(seconds)
+  end
+  alias :in :since
+
+  # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
+  def beginning_of_day
+    in_time_zone
+  end
+  alias :midnight :beginning_of_day
+  alias :at_midnight :beginning_of_day
+  alias :at_beginning_of_day :beginning_of_day
+
+  # Converts Date to a Time (or DateTime if necessary) with the time portion set to the middle of the day (12:00)
+  def middle_of_day
+    in_time_zone.middle_of_day
+  end
+  alias :midday :middle_of_day
+  alias :noon :middle_of_day
+  alias :at_midday :middle_of_day
+  alias :at_noon :middle_of_day
+  alias :at_middle_of_day :middle_of_day
+
+  # Converts Date to a Time (or DateTime if necessary) with the time portion set to the end of the day (23:59:59)
+  def end_of_day
+    in_time_zone.end_of_day
+  end
+  alias :at_end_of_day :end_of_day
+
+  def plus_with_duration(other) #:nodoc:
+    if ActiveSupport::Duration === other
+      other.since(self)
+    else
+      plus_without_duration(other)
+    end
+  end
+  alias_method :plus_without_duration, :+
+  alias_method :+, :plus_with_duration
+
+  def minus_with_duration(other) #:nodoc:
+    if ActiveSupport::Duration === other
+      plus_with_duration(-other)
+    else
+      minus_without_duration(other)
+    end
+  end
+  alias_method :minus_without_duration, :-
+  alias_method :-, :minus_with_duration
+
+  # Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with
+  # any of these keys: <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>.
+  def advance(options)
+    options = options.dup
+    d = self
+    d = d >> options.delete(:years) * 12 if options[:years]
+    d = d >> options.delete(:months)     if options[:months]
+    d = d +  options.delete(:weeks) * 7  if options[:weeks]
+    d = d +  options.delete(:days)       if options[:days]
+    d
+  end
+
+  # Returns a new Date where one or more of the elements have been changed according to the +options+ parameter.
+  # The +options+ parameter is a hash with a combination of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>.
+  #
+  #   Date.new(2007, 5, 12).change(day: 1)               # => Date.new(2007, 5, 1)
+  #   Date.new(2007, 5, 12).change(year: 2005, month: 1) # => Date.new(2005, 1, 12)
+  def change(options)
+    ::Date.new(
+      options.fetch(:year, year),
+      options.fetch(:month, month),
+      options.fetch(:day, day)
+    )
+  end
+  
+  # Allow Date to be compared with Time by converting to DateTime and relying on the <=> from there.
+  def compare_with_coercion(other)
+    if other.is_a?(Time)
+      self.to_datetime <=> other
+    else
+      compare_without_coercion(other)
+    end
+  end
+  alias_method :compare_without_coercion, :<=>
+  alias_method :<=>, :compare_with_coercion
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/date/conversions.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/date/conversions.rb
new file mode 100644
index 0000000..df419a6
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/date/conversions.rb
@@ -0,0 +1,88 @@
+require 'date'
+require 'active_support/inflector/methods'
+require 'active_support/core_ext/date/zones'
+require 'active_support/core_ext/module/remove_method'
+
+class Date
+  DATE_FORMATS = {
+    :short        => '%e %b',
+    :long         => '%B %e, %Y',
+    :db           => '%Y-%m-%d',
+    :number       => '%Y%m%d',
+    :long_ordinal => lambda { |date|
+      day_format = ActiveSupport::Inflector.ordinalize(date.day)
+      date.strftime("%B #{day_format}, %Y") # => "April 25th, 2007"
+    },
+    :rfc822       => '%e %b %Y',
+    :iso8601      => lambda { |date| date.iso8601 }
+  }
+
+  # Ruby 1.9 has Date#to_time which converts to localtime only.
+  remove_method :to_time
+
+  # Ruby 1.9 has Date#xmlschema which converts to a string without the time
+  # component. This removal may generate an issue on FreeBSD, that's why we
+  # need to use remove_possible_method here
+  remove_possible_method :xmlschema
+
+  # Convert to a formatted string. See DATE_FORMATS for predefined formats.
+  #
+  # This method is aliased to <tt>to_s</tt>.
+  #
+  #   date = Date.new(2007, 11, 10)       # => Sat, 10 Nov 2007
+  #
+  #   date.to_formatted_s(:db)            # => "2007-11-10"
+  #   date.to_s(:db)                      # => "2007-11-10"
+  #
+  #   date.to_formatted_s(:short)         # => "10 Nov"
+  #   date.to_formatted_s(:long)          # => "November 10, 2007"
+  #   date.to_formatted_s(:long_ordinal)  # => "November 10th, 2007"
+  #   date.to_formatted_s(:rfc822)        # => "10 Nov 2007"
+  #   date.to_formatted_s(:iso8601)       # => "2007-11-10"
+  #
+  # == Adding your own date formats to to_formatted_s
+  # You can add your own formats to the Date::DATE_FORMATS hash.
+  # Use the format name as the hash key and either a strftime string
+  # or Proc instance that takes a date argument as the value.
+  #
+  #   # config/initializers/date_formats.rb
+  #   Date::DATE_FORMATS[:month_and_year] = '%B %Y'
+  #   Date::DATE_FORMATS[:short_ordinal] = ->(date) { date.strftime("%B #{date.day.ordinalize}") }
+  def to_formatted_s(format = :default)
+    if formatter = DATE_FORMATS[format]
+      if formatter.respond_to?(:call)
+        formatter.call(self).to_s
+      else
+        strftime(formatter)
+      end
+    else
+      to_default_s
+    end
+  end
+  alias_method :to_default_s, :to_s
+  alias_method :to_s, :to_formatted_s
+
+  # Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005"
+  def readable_inspect
+    strftime('%a, %d %b %Y')
+  end
+  alias_method :default_inspect, :inspect
+  alias_method :inspect, :readable_inspect
+
+  # Converts a Date instance to a Time, where the time is set to the beginning of the day.
+  # The timezone can be either :local or :utc (default :local).
+  #
+  #   date = Date.new(2007, 11, 10)  # => Sat, 10 Nov 2007
+  #
+  #   date.to_time                   # => Sat Nov 10 00:00:00 0800 2007
+  #   date.to_time(:local)           # => Sat Nov 10 00:00:00 0800 2007
+  #
+  #   date.to_time(:utc)             # => Sat Nov 10 00:00:00 UTC 2007
+  def to_time(form = :local)
+    ::Time.send(form, year, month, day)
+  end
+
+  def xmlschema
+    in_time_zone.xmlschema
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/date/zones.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/date/zones.rb
new file mode 100644
index 0000000..d109b43
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/date/zones.rb
@@ -0,0 +1,6 @@
+require 'date'
+require 'active_support/core_ext/date_and_time/zones'
+
+class Date
+  include DateAndTime::Zones
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb
new file mode 100644
index 0000000..b85e49a
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb
@@ -0,0 +1,251 @@
+module DateAndTime
+  module Calculations
+    DAYS_INTO_WEEK = {
+      :monday    => 0,
+      :tuesday   => 1,
+      :wednesday => 2,
+      :thursday  => 3,
+      :friday    => 4,
+      :saturday  => 5,
+      :sunday    => 6
+    }
+
+    # Returns a new date/time representing yesterday.
+    def yesterday
+      advance(:days => -1)
+    end
+
+    # Returns a new date/time representing tomorrow.
+    def tomorrow
+      advance(:days => 1)
+    end
+
+    # Returns true if the date/time is today.
+    def today?
+      to_date == ::Date.current
+    end
+
+    # Returns true if the date/time is in the past.
+    def past?
+      self < self.class.current
+    end
+
+    # Returns true if the date/time is in the future.
+    def future?
+      self > self.class.current
+    end
+
+    # Returns a new date/time the specified number of days ago.
+    def days_ago(days)
+      advance(:days => -days)
+    end
+
+    # Returns a new date/time the specified number of days in the future.
+    def days_since(days)
+      advance(:days => days)
+    end
+
+    # Returns a new date/time the specified number of weeks ago.
+    def weeks_ago(weeks)
+      advance(:weeks => -weeks)
+    end
+
+    # Returns a new date/time the specified number of weeks in the future.
+    def weeks_since(weeks)
+      advance(:weeks => weeks)
+    end
+
+    # Returns a new date/time the specified number of months ago.
+    def months_ago(months)
+      advance(:months => -months)
+    end
+
+    # Returns a new date/time the specified number of months in the future.
+    def months_since(months)
+      advance(:months => months)
+    end
+
+    # Returns a new date/time the specified number of years ago.
+    def years_ago(years)
+      advance(:years => -years)
+    end
+
+    # Returns a new date/time the specified number of years in the future.
+    def years_since(years)
+      advance(:years => years)
+    end
+
+    # Returns a new date/time at the start of the month.
+    # DateTime objects will have a time set to 0:00.
+    def beginning_of_month
+      first_hour(change(:day => 1))
+    end
+    alias :at_beginning_of_month :beginning_of_month
+
+    # Returns a new date/time at the start of the quarter.
+    # Example: 1st January, 1st July, 1st October.
+    # DateTime objects will have a time set to 0:00.
+    def beginning_of_quarter
+      first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month }
+      beginning_of_month.change(:month => first_quarter_month)
+    end
+    alias :at_beginning_of_quarter :beginning_of_quarter
+
+    # Returns a new date/time at the end of the quarter.
+    # Example: 31st March, 30th June, 30th September.
+    # DateTime objects will have a time set to 23:59:59.
+    def end_of_quarter
+      last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month }
+      beginning_of_month.change(:month => last_quarter_month).end_of_month
+    end
+    alias :at_end_of_quarter :end_of_quarter
+
+    # Return a new date/time at the beginning of the year.
+    # Example: 1st January.
+    # DateTime objects will have a time set to 0:00.
+    def beginning_of_year
+      change(:month => 1).beginning_of_month
+    end
+    alias :at_beginning_of_year :beginning_of_year
+
+    # Returns a new date/time representing the given day in the next week.
+    # The +given_day_in_next_week+ defaults to the beginning of the week
+    # which is determined by +Date.beginning_of_week+ or +config.beginning_of_week+
+    # when set. +DateTime+ objects have their time set to 0:00.
+    def next_week(given_day_in_next_week = Date.beginning_of_week)
+      first_hour(weeks_since(1).beginning_of_week.days_since(days_span(given_day_in_next_week)))
+    end
+
+    # Short-hand for months_since(1).
+    def next_month
+      months_since(1)
+    end
+
+    # Short-hand for months_since(3)
+    def next_quarter
+      months_since(3)
+    end
+
+    # Short-hand for years_since(1).
+    def next_year
+      years_since(1)
+    end
+
+    # Returns a new date/time representing the given day in the previous week.
+    # Week is assumed to start on +start_day+, default is
+    # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
+    # DateTime objects have their time set to 0:00.
+    def prev_week(start_day = Date.beginning_of_week)
+      first_hour(weeks_ago(1).beginning_of_week.days_since(days_span(start_day)))
+    end
+    alias_method :last_week, :prev_week
+
+    # Short-hand for months_ago(1).
+    def prev_month
+      months_ago(1)
+    end
+    alias_method :last_month, :prev_month
+
+    # Short-hand for months_ago(3).
+    def prev_quarter
+      months_ago(3)
+    end
+    alias_method :last_quarter, :prev_quarter
+
+    # Short-hand for years_ago(1).
+    def prev_year
+      years_ago(1)
+    end
+    alias_method :last_year, :prev_year
+
+    # Returns the number of days to the start of the week on the given day.
+    # Week is assumed to start on +start_day+, default is
+    # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
+    def days_to_week_start(start_day = Date.beginning_of_week)
+      start_day_number = DAYS_INTO_WEEK[start_day]
+      current_day_number = wday != 0 ? wday - 1 : 6
+      (current_day_number - start_day_number) % 7
+    end
+
+    # Returns a new date/time representing the start of this week on the given day.
+    # Week is assumed to start on +start_day+, default is
+    # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
+    # +DateTime+ objects have their time set to 0:00.
+    def beginning_of_week(start_day = Date.beginning_of_week)
+      result = days_ago(days_to_week_start(start_day))
+      acts_like?(:time) ? result.midnight : result
+    end
+    alias :at_beginning_of_week :beginning_of_week
+
+    # Returns Monday of this week assuming that week starts on Monday.
+    # +DateTime+ objects have their time set to 0:00.
+    def monday
+      beginning_of_week(:monday)
+    end
+
+    # Returns a new date/time representing the end of this week on the given day.
+    # Week is assumed to start on +start_day+, default is
+    # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
+    # DateTime objects have their time set to 23:59:59.
+    def end_of_week(start_day = Date.beginning_of_week)
+      last_hour(days_since(6 - days_to_week_start(start_day)))
+    end
+    alias :at_end_of_week :end_of_week
+
+    # Returns Sunday of this week assuming that week starts on Monday.
+    # +DateTime+ objects have their time set to 23:59:59.
+    def sunday
+      end_of_week(:monday)
+    end
+
+    # Returns a new date/time representing the end of the month.
+    # DateTime objects will have a time set to 23:59:59.
+    def end_of_month
+      last_day = ::Time.days_in_month(month, year)
+      last_hour(days_since(last_day - day))
+    end
+    alias :at_end_of_month :end_of_month
+
+    # Returns a new date/time representing the end of the year.
+    # DateTime objects will have a time set to 23:59:59.
+    def end_of_year
+      change(:month => 12).end_of_month
+    end
+    alias :at_end_of_year :end_of_year
+
+    # Returns a Range representing the whole week of the current date/time.
+    # Week starts on start_day, default is <tt>Date.week_start</tt> or <tt>config.week_start</tt> when set.
+    def all_week(start_day = Date.beginning_of_week)
+      beginning_of_week(start_day)..end_of_week(start_day)
+    end
+
+    # Returns a Range representing the whole month of the current date/time.
+    def all_month
+      beginning_of_month..end_of_month
+    end
+
+    # Returns a Range representing the whole quarter of the current date/time.
+    def all_quarter
+      beginning_of_quarter..end_of_quarter
+    end
+
+    # Returns a Range representing the whole year of the current date/time.
+    def all_year
+      beginning_of_year..end_of_year
+    end
+
+    private
+
+    def first_hour(date_or_time)
+      date_or_time.acts_like?(:time) ? date_or_time.beginning_of_day : date_or_time
+    end
+
+    def last_hour(date_or_time)
+      date_or_time.acts_like?(:time) ? date_or_time.end_of_day : date_or_time
+    end
+
+    def days_span(day)
+      (DAYS_INTO_WEEK[day] - DAYS_INTO_WEEK[Date.beginning_of_week]) % 7
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/date_and_time/zones.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/date_and_time/zones.rb
new file mode 100644
index 0000000..96c6df9
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/date_and_time/zones.rb
@@ -0,0 +1,41 @@
+module DateAndTime
+  module Zones
+    # Returns the simultaneous time in <tt>Time.zone</tt> if a zone is given or
+    # if Time.zone_default is set. Otherwise, it returns the current time.
+    #
+    #   Time.zone = 'Hawaii'        # => 'Hawaii'
+    #   DateTime.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+    #   Date.new(2000).in_time_zone  # => Sat, 01 Jan 2000 00:00:00 HST -10:00
+    #
+    # This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone
+    # instead of the operating system's time zone.
+    #
+    # You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument,
+    # and the conversion will be based on that zone instead of <tt>Time.zone</tt>.
+    #
+    #   Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
+    #   DateTime.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
+    #   Date.new(2000).in_time_zone('Alaska')  # => Sat, 01 Jan 2000 00:00:00 AKST -09:00
+    def in_time_zone(zone = ::Time.zone)
+      time_zone = ::Time.find_zone! zone
+      time = acts_like?(:time) ? self : nil
+
+      if time_zone
+        time_with_zone(time, time_zone)
+      else
+        time || self.to_time
+      end
+    end
+
+    private
+
+    def time_with_zone(time, zone)
+      if time
+        ActiveSupport::TimeWithZone.new(time.utc? ? time : time.getutc, zone)
+      else
+        ActiveSupport::TimeWithZone.new(nil, zone, to_time(:utc))
+      end
+    end
+  end
+end
+
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/date_time.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/date_time.rb
new file mode 100644
index 0000000..e8a27b9
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/date_time.rb
@@ -0,0 +1,4 @@
+require 'active_support/core_ext/date_time/acts_like'
+require 'active_support/core_ext/date_time/calculations'
+require 'active_support/core_ext/date_time/conversions'
+require 'active_support/core_ext/date_time/zones'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/date_time/acts_like.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/date_time/acts_like.rb
new file mode 100644
index 0000000..8fbbe0d
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/date_time/acts_like.rb
@@ -0,0 +1,14 @@
+require 'date'
+require 'active_support/core_ext/object/acts_like'
+
+class DateTime
+  # Duck-types as a Date-like class. See Object#acts_like?.
+  def acts_like_date?
+    true
+  end
+
+  # Duck-types as a Time-like class. See Object#acts_like?.
+  def acts_like_time?
+    true
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/date_time/calculations.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/date_time/calculations.rb
new file mode 100644
index 0000000..73ad0aa
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/date_time/calculations.rb
@@ -0,0 +1,161 @@
+require 'date'
+
+class DateTime
+  class << self
+    # Returns <tt>Time.zone.now.to_datetime</tt> when <tt>Time.zone</tt> or
+    # <tt>config.time_zone</tt> are set, otherwise returns
+    # <tt>Time.now.to_datetime</tt>.
+    def current
+      ::Time.zone ? ::Time.zone.now.to_datetime : ::Time.now.to_datetime
+    end
+  end
+
+  # Seconds since midnight: DateTime.now.seconds_since_midnight.
+  def seconds_since_midnight
+    sec + (min * 60) + (hour * 3600)
+  end
+
+  # Returns the number of seconds until 23:59:59.
+  #
+  #   DateTime.new(2012, 8, 29,  0,  0,  0).seconds_until_end_of_day # => 86399
+  #   DateTime.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103
+  #   DateTime.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0
+  def seconds_until_end_of_day
+    end_of_day.to_i - to_i
+  end
+
+  # Returns a new DateTime where one or more of the elements have been changed
+  # according to the +options+ parameter. The time options (<tt>:hour</tt>,
+  # <tt>:min</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is
+  # passed, then minute and sec is set to 0. If the hour and minute is passed,
+  # then sec is set to 0. The +options+ parameter takes a hash with any of these
+  # keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>,
+  # <tt>:min</tt>, <tt>:sec</tt>, <tt>:offset</tt>, <tt>:start</tt>.
+  #
+  #   DateTime.new(2012, 8, 29, 22, 35, 0).change(day: 1)              # => DateTime.new(2012, 8, 1, 22, 35, 0)
+  #   DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1)  # => DateTime.new(1981, 8, 1, 22, 35, 0)
+  #   DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => DateTime.new(1981, 8, 29, 0, 0, 0)
+  def change(options)
+    ::DateTime.civil(
+      options.fetch(:year, year),
+      options.fetch(:month, month),
+      options.fetch(:day, day),
+      options.fetch(:hour, hour),
+      options.fetch(:min, options[:hour] ? 0 : min),
+      options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec + sec_fraction),
+      options.fetch(:offset, offset),
+      options.fetch(:start, start)
+    )
+  end
+
+  # Uses Date to provide precise Time calculations for years, months, and days.
+  # The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
+  # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
+  # <tt>:minutes</tt>, <tt>:seconds</tt>.
+  def advance(options)
+    d = to_date.advance(options)
+    datetime_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
+    seconds_to_advance = \
+      options.fetch(:seconds, 0) +
+      options.fetch(:minutes, 0) * 60 +
+      options.fetch(:hours, 0) * 3600
+
+    if seconds_to_advance.zero?
+      datetime_advanced_by_date
+    else
+      datetime_advanced_by_date.since seconds_to_advance
+    end
+  end
+
+  # Returns a new DateTime representing the time a number of seconds ago.
+  # Do not use this method in combination with x.months, use months_ago instead!
+  def ago(seconds)
+    since(-seconds)
+  end
+
+  # Returns a new DateTime representing the time a number of seconds since the
+  # instance time. Do not use this method in combination with x.months, use
+  # months_since instead!
+  def since(seconds)
+    self + Rational(seconds.round, 86400)
+  end
+  alias :in :since
+
+  # Returns a new DateTime representing the start of the day (0:00).
+  def beginning_of_day
+    change(:hour => 0)
+  end
+  alias :midnight :beginning_of_day
+  alias :at_midnight :beginning_of_day
+  alias :at_beginning_of_day :beginning_of_day
+
+  # Returns a new DateTime representing the middle of the day (12:00)
+  def middle_of_day
+    change(:hour => 12)
+  end
+  alias :midday :middle_of_day
+  alias :noon :middle_of_day
+  alias :at_midday :middle_of_day
+  alias :at_noon :middle_of_day
+  alias :at_middle_of_day :middle_of_day
+
+  # Returns a new DateTime representing the end of the day (23:59:59).
+  def end_of_day
+    change(:hour => 23, :min => 59, :sec => 59)
+  end
+  alias :at_end_of_day :end_of_day
+
+  # Returns a new DateTime representing the start of the hour (hh:00:00).
+  def beginning_of_hour
+    change(:min => 0)
+  end
+  alias :at_beginning_of_hour :beginning_of_hour
+
+  # Returns a new DateTime representing the end of the hour (hh:59:59).
+  def end_of_hour
+    change(:min => 59, :sec => 59)
+  end
+  alias :at_end_of_hour :end_of_hour
+
+  # Returns a new DateTime representing the start of the minute (hh:mm:00).
+  def beginning_of_minute
+    change(:sec => 0)
+  end
+  alias :at_beginning_of_minute :beginning_of_minute
+
+  # Returns a new DateTime representing the end of the minute (hh:mm:59).
+  def end_of_minute
+    change(:sec => 59)
+  end
+  alias :at_end_of_minute :end_of_minute
+
+  # Adjusts DateTime to UTC by adding its offset value; offset is set to 0.
+  #
+  #   DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24))     # => Mon, 21 Feb 2005 10:11:12 -0600
+  #   DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 +0000
+  def utc
+    new_offset(0)
+  end
+  alias_method :getutc, :utc
+
+  # Returns +true+ if <tt>offset == 0</tt>.
+  def utc?
+    offset == 0
+  end
+
+  # Returns the offset value in seconds.
+  def utc_offset
+    (offset * 86400).to_i
+  end
+
+  # Layers additional behavior on DateTime#<=> so that Time and
+  # ActiveSupport::TimeWithZone instances can be compared with a DateTime.
+  def <=>(other)
+    if other.respond_to? :to_datetime
+      super other.to_datetime
+    else
+      nil
+    end
+  end
+
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/date_time/conversions.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/date_time/conversions.rb
new file mode 100644
index 0000000..6ddfb72
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/date_time/conversions.rb
@@ -0,0 +1,103 @@
+require 'date'
+require 'active_support/inflector/methods'
+require 'active_support/core_ext/time/conversions'
+require 'active_support/core_ext/date_time/calculations'
+require 'active_support/values/time_zone'
+
+class DateTime
+  # Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.
+  #
+  # This method is aliased to <tt>to_s</tt>.
+  #
+  # === Examples
+  #   datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0)   # => Tue, 04 Dec 2007 00:00:00 +0000
+  #
+  #   datetime.to_formatted_s(:db)            # => "2007-12-04 00:00:00"
+  #   datetime.to_s(:db)                      # => "2007-12-04 00:00:00"
+  #   datetime.to_s(:number)                  # => "20071204000000"
+  #   datetime.to_formatted_s(:short)         # => "04 Dec 00:00"
+  #   datetime.to_formatted_s(:long)          # => "December 04, 2007 00:00"
+  #   datetime.to_formatted_s(:long_ordinal)  # => "December 4th, 2007 00:00"
+  #   datetime.to_formatted_s(:rfc822)        # => "Tue, 04 Dec 2007 00:00:00 +0000"
+  #   datetime.to_formatted_s(:iso8601)       # => "2007-12-04T00:00:00+00:00"
+  #
+  # == Adding your own datetime formats to to_formatted_s
+  # DateTime formats are shared with Time. You can add your own to the
+  # Time::DATE_FORMATS hash. Use the format name as the hash key and
+  # either a strftime string or Proc instance that takes a time or
+  # datetime argument as the value.
+  #
+  #   # config/initializers/time_formats.rb
+  #   Time::DATE_FORMATS[:month_and_year] = '%B %Y'
+  #   Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }
+  def to_formatted_s(format = :default)
+    if formatter = ::Time::DATE_FORMATS[format]
+      formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
+    else
+      to_default_s
+    end
+  end
+  alias_method :to_default_s, :to_s if instance_methods(false).include?(:to_s)
+  alias_method :to_s, :to_formatted_s
+
+  #
+  #   datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24))
+  #   datetime.formatted_offset         # => "-06:00"
+  #   datetime.formatted_offset(false)  # => "-0600"
+  def formatted_offset(colon = true, alternate_utc_string = nil)
+    utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
+  end
+
+  # Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000".
+  def readable_inspect
+    to_s(:rfc822)
+  end
+  alias_method :default_inspect, :inspect
+  alias_method :inspect, :readable_inspect
+
+  # Returns DateTime with local offset for given year if format is local else
+  # offset is zero.
+  #
+  #   DateTime.civil_from_format :local, 2012
+  #   # => Sun, 01 Jan 2012 00:00:00 +0300
+  #   DateTime.civil_from_format :local, 2012, 12, 17
+  #   # => Mon, 17 Dec 2012 00:00:00 +0000
+  def self.civil_from_format(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0)
+    if utc_or_local.to_sym == :local
+      offset = ::Time.local(year, month, day).utc_offset.to_r / 86400
+    else
+      offset = 0
+    end
+    civil(year, month, day, hour, min, sec, offset)
+  end
+
+  # Converts +self+ to a floating-point number of seconds since the Unix epoch.
+  def to_f
+    seconds_since_unix_epoch.to_f
+  end
+
+  # Converts +self+ to an integer number of seconds since the Unix epoch.
+  def to_i
+    seconds_since_unix_epoch.to_i
+  end
+
+  # Returns the fraction of a second as microseconds
+  def usec
+    (sec_fraction * 1_000_000).to_i
+  end
+
+  # Returns the fraction of a second as nanoseconds
+  def nsec
+    (sec_fraction * 1_000_000_000).to_i
+  end
+
+  private
+
+  def offset_in_seconds
+    (offset * 86400).to_i
+  end
+
+  def seconds_since_unix_epoch
+    (jd - 2440588) * 86400 - offset_in_seconds + seconds_since_midnight
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/date_time/zones.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/date_time/zones.rb
new file mode 100644
index 0000000..c39f358
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/date_time/zones.rb
@@ -0,0 +1,6 @@
+require 'date'
+require 'active_support/core_ext/date_and_time/zones'
+
+class DateTime
+  include DateAndTime::Zones
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/enumerable.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/enumerable.rb
new file mode 100644
index 0000000..1343beb
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/enumerable.rb
@@ -0,0 +1,80 @@
+module Enumerable
+  # Calculates a sum from the elements.
+  #
+  #  payments.sum { |p| p.price * p.tax_rate }
+  #  payments.sum(&:price)
+  #
+  # The latter is a shortcut for:
+  #
+  #  payments.inject(0) { |sum, p| sum + p.price }
+  #
+  # It can also calculate the sum without the use of a block.
+  #
+  #  [5, 15, 10].sum # => 30
+  #  ['foo', 'bar'].sum # => "foobar"
+  #  [[1, 2], [3, 1, 5]].sum => [1, 2, 3, 1, 5]
+  #
+  # The default sum of an empty list is zero. You can override this default:
+  #
+  #  [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
+  def sum(identity = 0, &block)
+    if block_given?
+      map(&block).sum(identity)
+    else
+      inject { |sum, element| sum + element } || identity
+    end
+  end
+
+  # Convert an enumerable to a hash.
+  #
+  #   people.index_by(&:login)
+  #     => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...}
+  #   people.index_by { |person| "#{person.first_name} #{person.last_name}" }
+  #     => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}
+  def index_by
+    if block_given?
+      Hash[map { |elem| [yield(elem), elem] }]
+    else
+      to_enum(:index_by) { size if respond_to?(:size) }
+    end
+  end
+
+  # Returns +true+ if the enumerable has more than 1 element. Functionally
+  # equivalent to <tt>enum.to_a.size > 1</tt>. Can be called with a block too,
+  # much like any?, so <tt>people.many? { |p| p.age > 26 }</tt> returns +true+
+  # if more than one person is over 26.
+  def many?
+    cnt = 0
+    if block_given?
+      any? do |element|
+        cnt += 1 if yield element
+        cnt > 1
+      end
+    else
+      any? { (cnt += 1) > 1 }
+    end
+  end
+
+  # The negative of the <tt>Enumerable#include?</tt>. Returns +true+ if the
+  # collection does not include the object.
+  def exclude?(object)
+    !include?(object)
+  end
+end
+
+class Range #:nodoc:
+  # Optimize range sum to use arithmetic progression if a block is not given and
+  # we have a range of numeric values.
+  def sum(identity = 0)
+    if block_given? || !(first.is_a?(Integer) && last.is_a?(Integer))
+      super
+    else
+      actual_last = exclude_end? ? (last - 1) : last
+      if actual_last >= first
+        (actual_last - first + 1) * (actual_last + first) / 2
+      else
+        identity
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/file.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/file.rb
new file mode 100644
index 0000000..dc24afb
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/file.rb
@@ -0,0 +1 @@
+require 'active_support/core_ext/file/atomic'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/file/atomic.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/file/atomic.rb
new file mode 100644
index 0000000..0e7e3ba
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/file/atomic.rb
@@ -0,0 +1,63 @@
+require 'fileutils'
+
+class File
+  # Write to a file atomically. Useful for situations where you don't
+  # want other processes or threads to see half-written files.
+  #
+  #   File.atomic_write('important.file') do |file|
+  #     file.write('hello')
+  #   end
+  #
+  # If your temp directory is not on the same filesystem as the file you're
+  # trying to write, you can provide a different temporary directory.
+  #
+  #   File.atomic_write('/data/something.important', '/data/tmp') do |file|
+  #     file.write('hello')
+  #   end
+  def self.atomic_write(file_name, temp_dir = Dir.tmpdir)
+    require 'tempfile' unless defined?(Tempfile)
+    require 'fileutils' unless defined?(FileUtils)
+
+    temp_file = Tempfile.new(basename(file_name), temp_dir)
+    temp_file.binmode
+    yield temp_file
+    temp_file.close
+
+    if File.exist?(file_name)
+      # Get original file permissions
+      old_stat = stat(file_name)
+    else
+      # If not possible, probe which are the default permissions in the
+      # destination directory.
+      old_stat = probe_stat_in(dirname(file_name))
+    end
+
+    # Overwrite original file with temp file
+    FileUtils.mv(temp_file.path, file_name)
+
+    # Set correct permissions on new file
+    begin
+      chown(old_stat.uid, old_stat.gid, file_name)
+      # This operation will affect filesystem ACL's
+      chmod(old_stat.mode, file_name)
+    rescue Errno::EPERM
+      # Changing file ownership failed, moving on.
+    end
+  end
+
+  # Private utility method.
+  def self.probe_stat_in(dir) #:nodoc:
+    basename = [
+      '.permissions_check',
+      Thread.current.object_id,
+      Process.pid,
+      rand(1000000)
+    ].join('.')
+
+    file_name = join(dir, basename)
+    FileUtils.touch(file_name)
+    stat(file_name)
+  ensure
+    FileUtils.rm_f(file_name) if file_name
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/hash.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/hash.rb
new file mode 100644
index 0000000..f68e166
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/hash.rb
@@ -0,0 +1,8 @@
+require 'active_support/core_ext/hash/compact'
+require 'active_support/core_ext/hash/conversions'
+require 'active_support/core_ext/hash/deep_merge'
+require 'active_support/core_ext/hash/except'
+require 'active_support/core_ext/hash/indifferent_access'
+require 'active_support/core_ext/hash/keys'
+require 'active_support/core_ext/hash/reverse_merge'
+require 'active_support/core_ext/hash/slice'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/hash/compact.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/compact.rb
new file mode 100644
index 0000000..6566215
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/compact.rb
@@ -0,0 +1,20 @@
+class Hash
+  # Returns a hash with non +nil+ values.
+  # 
+  #   hash = { a: true, b: false, c: nil}
+  #   hash.compact # => { a: true, b: false}
+  #   hash # => { a: true, b: false, c: nil}
+  #   { c: nil }.compact # => {}
+  def compact
+    self.select { |_, value| !value.nil? }
+  end
+  
+  # Replaces current hash with non +nil+ values.
+  # 
+  #   hash = { a: true, b: false, c: nil}
+  #   hash.compact! # => { a: true, b: false}
+  #   hash # => { a: true, b: false}
+  def compact!
+    self.reject! { |_, value| value.nil? }
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/hash/conversions.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/conversions.rb
new file mode 100644
index 0000000..6c3e48a
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/conversions.rb
@@ -0,0 +1,243 @@
+require 'active_support/xml_mini'
+require 'active_support/time'
+require 'active_support/core_ext/object/blank'
+require 'active_support/core_ext/object/to_param'
+require 'active_support/core_ext/object/to_query'
+require 'active_support/core_ext/array/wrap'
+require 'active_support/core_ext/hash/reverse_merge'
+require 'active_support/core_ext/string/inflections'
+
+class Hash
+  # Returns a string containing an XML representation of its receiver:
+  #
+  #   { foo: 1, bar: 2 }.to_xml
+  #   # =>
+  #   # <?xml version="1.0" encoding="UTF-8"?>
+  #   # <hash>
+  #   #   <foo type="integer">1</foo>
+  #   #   <bar type="integer">2</bar>
+  #   # </hash>
+  #
+  # To do so, the method loops over the pairs and builds nodes that depend on
+  # the _values_. Given a pair +key+, +value+:
+  #
+  # * If +value+ is a hash there's a recursive call with +key+ as <tt>:root</tt>.
+  #
+  # * If +value+ is an array there's a recursive call with +key+ as <tt>:root</tt>,
+  #   and +key+ singularized as <tt>:children</tt>.
+  #
+  # * If +value+ is a callable object it must expect one or two arguments. Depending
+  #   on the arity, the callable is invoked with the +options+ hash as first argument
+  #   with +key+ as <tt>:root</tt>, and +key+ singularized as second argument. The
+  #   callable can add nodes by using <tt>options[:builder]</tt>.
+  #
+  #     'foo'.to_xml(lambda { |options, key| options[:builder].b(key) })
+  #     # => "<b>foo</b>"
+  #
+  # * If +value+ responds to +to_xml+ the method is invoked with +key+ as <tt>:root</tt>.
+  #
+  #     class Foo
+  #       def to_xml(options)
+  #         options[:builder].bar 'fooing!'
+  #       end
+  #     end
+  #
+  #     { foo: Foo.new }.to_xml(skip_instruct: true)
+  #     # =>
+  #     # <hash>
+  #     #   <bar>fooing!</bar>
+  #     # </hash>
+  #
+  # * Otherwise, a node with +key+ as tag is created with a string representation of
+  #   +value+ as text node. If +value+ is +nil+ an attribute "nil" set to "true" is added.
+  #   Unless the option <tt>:skip_types</tt> exists and is true, an attribute "type" is
+  #   added as well according to the following mapping:
+  #
+  #     XML_TYPE_NAMES = {
+  #       "Symbol"     => "symbol",
+  #       "Fixnum"     => "integer",
+  #       "Bignum"     => "integer",
+  #       "BigDecimal" => "decimal",
+  #       "Float"      => "float",
+  #       "TrueClass"  => "boolean",
+  #       "FalseClass" => "boolean",
+  #       "Date"       => "date",
+  #       "DateTime"   => "dateTime",
+  #       "Time"       => "dateTime"
+  #     }
+  #
+  # By default the root node is "hash", but that's configurable via the <tt>:root</tt> option.
+  #
+  # The default XML builder is a fresh instance of <tt>Builder::XmlMarkup</tt>. You can
+  # configure your own builder with the <tt>:builder</tt> option. The method also accepts
+  # options like <tt>:dasherize</tt> and friends, they are forwarded to the builder.
+  def to_xml(options = {})
+    require 'active_support/builder' unless defined?(Builder)
+
+    options = options.dup
+    options[:indent]  ||= 2
+    options[:root]    ||= 'hash'
+    options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
+
+    builder = options[:builder]
+    builder.instruct! unless options.delete(:skip_instruct)
+
+    root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options)
+
+    builder.tag!(root) do
+      each { |key, value| ActiveSupport::XmlMini.to_tag(key, value, options) }
+      yield builder if block_given?
+    end
+  end
+
+  class << self
+    # Returns a Hash containing a collection of pairs when the key is the node name and the value is
+    # its content
+    #
+    #   xml = <<-XML
+    #     <?xml version="1.0" encoding="UTF-8"?>
+    #       <hash>
+    #         <foo type="integer">1</foo>
+    #         <bar type="integer">2</bar>
+    #       </hash>
+    #   XML
+    #
+    #   hash = Hash.from_xml(xml)
+    #   # => {"hash"=>{"foo"=>1, "bar"=>2}}
+    #
+    # +DisallowedType+ is raised if the XML contains attributes with <tt>type="yaml"</tt> or
+    # <tt>type="symbol"</tt>. Use <tt>Hash.from_trusted_xml</tt> to parse this XML.
+    def from_xml(xml, disallowed_types = nil)
+      ActiveSupport::XMLConverter.new(xml, disallowed_types).to_h
+    end
+
+    # Builds a Hash from XML just like <tt>Hash.from_xml</tt>, but also allows Symbol and YAML.
+    def from_trusted_xml(xml)
+      from_xml xml, []
+    end
+  end
+end
+
+module ActiveSupport
+  class XMLConverter # :nodoc:
+    class DisallowedType < StandardError
+      def initialize(type)
+        super "Disallowed type attribute: #{type.inspect}"
+      end
+    end
+
+    DISALLOWED_TYPES = %w(symbol yaml)
+
+    def initialize(xml, disallowed_types = nil)
+      @xml = normalize_keys(XmlMini.parse(xml))
+      @disallowed_types = disallowed_types || DISALLOWED_TYPES
+    end
+
+    def to_h
+      deep_to_h(@xml)
+    end
+
+    private
+      def normalize_keys(params)
+        case params
+          when Hash
+            Hash[params.map { |k,v| [k.to_s.tr('-', '_'), normalize_keys(v)] } ]
+          when Array
+            params.map { |v| normalize_keys(v) }
+          else
+            params
+        end
+      end
+
+      def deep_to_h(value)
+        case value
+          when Hash
+            process_hash(value)
+          when Array
+            process_array(value)
+          when String
+            value
+          else
+            raise "can't typecast #{value.class.name} - #{value.inspect}"
+        end
+      end
+
+      def process_hash(value)
+        if value.include?('type') && !value['type'].is_a?(Hash) && @disallowed_types.include?(value['type'])
+          raise DisallowedType, value['type']
+        end
+
+        if become_array?(value)
+          _, entries = Array.wrap(value.detect { |k,v| not v.is_a?(String) })
+          if entries.nil? || value['__content__'].try(:empty?)
+            []
+          else
+            case entries
+            when Array
+              entries.collect { |v| deep_to_h(v) }
+            when Hash
+              [deep_to_h(entries)]
+            else
+              raise "can't typecast #{entries.inspect}"
+            end
+          end
+        elsif become_content?(value)
+          process_content(value)
+
+        elsif become_empty_string?(value)
+          ''
+        elsif become_hash?(value)
+          xml_value = Hash[value.map { |k,v| [k, deep_to_h(v)] }]
+
+          # Turn { files: { file: #<StringIO> } } into { files: #<StringIO> } so it is compatible with
+          # how multipart uploaded files from HTML appear
+          xml_value['file'].is_a?(StringIO) ? xml_value['file'] : xml_value
+        end
+      end
+
+      def become_content?(value)
+        value['type'] == 'file' || (value['__content__'] && (value.keys.size == 1 || value['__content__'].present?))
+      end
+
+      def become_array?(value)
+        value['type'] == 'array'
+      end
+
+      def become_empty_string?(value)
+        # { "string" => true }
+        # No tests fail when the second term is removed.
+        value['type'] == 'string' && value['nil'] != 'true'
+      end
+
+      def become_hash?(value)
+        !nothing?(value) && !garbage?(value)
+      end
+
+      def nothing?(value)
+        # blank or nil parsed values are represented by nil
+        value.blank? || value['nil'] == 'true'
+      end
+
+      def garbage?(value)
+        # If the type is the only element which makes it then
+        # this still makes the value nil, except if type is
+        # a XML node(where type['value'] is a Hash)
+        value['type'] && !value['type'].is_a?(::Hash) && value.size == 1
+      end
+
+      def process_content(value)
+        content = value['__content__']
+        if parser = ActiveSupport::XmlMini::PARSING[value['type']]
+          parser.arity == 1 ? parser.call(content) : parser.call(content, value)
+        else
+          content
+        end
+      end
+
+      def process_array(value)
+        value.map! { |i| deep_to_h(i) }
+        value.length > 1 ? value : value.first
+      end
+
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/hash/deep_merge.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
new file mode 100644
index 0000000..dc86c92
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
@@ -0,0 +1,27 @@
+class Hash
+  # Returns a new hash with +self+ and +other_hash+ merged recursively.
+  #
+  #   h1 = { x: { y: [4, 5, 6] }, z: [7, 8, 9] }
+  #   h2 = { x: { y: [7, 8, 9] }, z: 'xyz' }
+  #
+  #   h1.deep_merge(h2) # => {x: {y: [7, 8, 9]}, z: "xyz"}
+  #   h2.deep_merge(h1) # => {x: {y: [4, 5, 6]}, z: [7, 8, 9]}
+  #   h1.deep_merge(h2) { |key, old, new| Array.wrap(old) + Array.wrap(new) }
+  #   # => {:x=>{:y=>[4, 5, 6, 7, 8, 9]}, :z=>[7, 8, 9, "xyz"]}
+  def deep_merge(other_hash, &block)
+    dup.deep_merge!(other_hash, &block)
+  end
+
+  # Same as +deep_merge+, but modifies +self+.
+  def deep_merge!(other_hash, &block)
+    other_hash.each_pair do |k,v|
+      tv = self[k]
+      if tv.is_a?(Hash) && v.is_a?(Hash)
+        self[k] = tv.deep_merge(v, &block)
+      else
+        self[k] = block && tv ? block.call(k, tv, v) : v
+      end
+    end
+    self
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/hash/except.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/except.rb
new file mode 100644
index 0000000..682d089
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/except.rb
@@ -0,0 +1,15 @@
+class Hash
+  # Returns a hash that includes everything but the given keys. This is useful for
+  # limiting a set of parameters to everything but a few known toggles:
+  #
+  #   @person.update(params[:person].except(:admin))
+  def except(*keys)
+    dup.except!(*keys)
+  end
+
+  # Replaces the hash without the given keys.
+  def except!(*keys)
+    keys.each { |key| delete(key) }
+    self
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
new file mode 100644
index 0000000..970d6fa
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
@@ -0,0 +1,23 @@
+require 'active_support/hash_with_indifferent_access'
+
+class Hash
+
+  # Returns an <tt>ActiveSupport::HashWithIndifferentAccess</tt> out of its receiver:
+  #
+  #   { a: 1 }.with_indifferent_access['a'] # => 1
+  def with_indifferent_access
+    ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default(self)
+  end
+
+  # Called when object is nested under an object that receives
+  # #with_indifferent_access. This method will be called on the current object
+  # by the enclosing object and is aliased to #with_indifferent_access by
+  # default. Subclasses of Hash may overwrite this method to return +self+ if
+  # converting to an <tt>ActiveSupport::HashWithIndifferentAccess</tt> would not be
+  # desirable.
+  #
+  #   b = { b: 1 }
+  #   { a: b }.with_indifferent_access['a'] # calls b.nested_under_indifferent_access
+  #   # => {"b"=>32}
+  alias nested_under_indifferent_access with_indifferent_access
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/hash/keys.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/keys.rb
new file mode 100644
index 0000000..3d41aa8
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/keys.rb
@@ -0,0 +1,140 @@
+class Hash
+  # Returns a new hash with all keys converted using the block operation.
+  #
+  #  hash = { name: 'Rob', age: '28' }
+  #
+  #  hash.transform_keys{ |key| key.to_s.upcase }
+  #  # => {"NAME"=>"Rob", "AGE"=>"28"}
+  def transform_keys
+    result = {}
+    each_key do |key|
+      result[yield(key)] = self[key]
+    end
+    result
+  end
+
+  # Destructively convert all keys using the block operations.
+  # Same as transform_keys but modifies +self+.
+  def transform_keys!
+    keys.each do |key|
+      self[yield(key)] = delete(key)
+    end
+    self
+  end
+
+  # Returns a new hash with all keys converted to strings.
+  #
+  #   hash = { name: 'Rob', age: '28' }
+  #
+  #   hash.stringify_keys
+  #   # => { "name" => "Rob", "age" => "28" }
+  def stringify_keys
+    transform_keys{ |key| key.to_s }
+  end
+
+  # Destructively convert all keys to strings. Same as
+  # +stringify_keys+, but modifies +self+.
+  def stringify_keys!
+    transform_keys!{ |key| key.to_s }
+  end
+
+  # Returns a new hash with all keys converted to symbols, as long as
+  # they respond to +to_sym+.
+  #
+  #   hash = { 'name' => 'Rob', 'age' => '28' }
+  #
+  #   hash.symbolize_keys
+  #   # => { name: "Rob", age: "28" }
+  def symbolize_keys
+    transform_keys{ |key| key.to_sym rescue key }
+  end
+  alias_method :to_options,  :symbolize_keys
+
+  # Destructively convert all keys to symbols, as long as they respond
+  # to +to_sym+. Same as +symbolize_keys+, but modifies +self+.
+  def symbolize_keys!
+    transform_keys!{ |key| key.to_sym rescue key }
+  end
+  alias_method :to_options!, :symbolize_keys!
+
+  # Validate all keys in a hash match <tt>*valid_keys</tt>, raising ArgumentError
+  # on a mismatch. Note that keys are NOT treated indifferently, meaning if you
+  # use strings for keys but assert symbols as keys, this will fail.
+  #
+  #   { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: :years. Valid keys are: :name, :age"
+  #   { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: :name. Valid keys are: 'name', 'age'"
+  #   { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age)   # => passes, raises nothing
+  def assert_valid_keys(*valid_keys)
+    valid_keys.flatten!
+    each_key do |k|
+      unless valid_keys.include?(k)
+        raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}")
+      end
+    end
+  end
+
+  # Returns a new hash with all keys converted by the block operation.
+  # This includes the keys from the root hash and from all
+  # nested hashes.
+  #
+  #  hash = { person: { name: 'Rob', age: '28' } }
+  #
+  #  hash.deep_transform_keys{ |key| key.to_s.upcase }
+  #  # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}}
+  def deep_transform_keys(&block)
+    result = {}
+    each do |key, value|
+      result[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys(&block) : value
+    end
+    result
+  end
+
+  # Destructively convert all keys by using the block operation.
+  # This includes the keys from the root hash and from all
+  # nested hashes.
+  def deep_transform_keys!(&block)
+    keys.each do |key|
+      value = delete(key)
+      self[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys!(&block) : value
+    end
+    self
+  end
+
+  # Returns a new hash with all keys converted to strings.
+  # This includes the keys from the root hash and from all
+  # nested hashes.
+  #
+  #   hash = { person: { name: 'Rob', age: '28' } }
+  #
+  #   hash.deep_stringify_keys
+  #   # => {"person"=>{"name"=>"Rob", "age"=>"28"}}
+  def deep_stringify_keys
+    deep_transform_keys{ |key| key.to_s }
+  end
+
+  # Destructively convert all keys to strings.
+  # This includes the keys from the root hash and from all
+  # nested hashes.
+  def deep_stringify_keys!
+    deep_transform_keys!{ |key| key.to_s }
+  end
+
+  # Returns a new hash with all keys converted to symbols, as long as
+  # they respond to +to_sym+. This includes the keys from the root hash
+  # and from all nested hashes.
+  #
+  #   hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
+  #
+  #   hash.deep_symbolize_keys
+  #   # => {:person=>{:name=>"Rob", :age=>"28"}}
+  def deep_symbolize_keys
+    deep_transform_keys{ |key| key.to_sym rescue key }
+  end
+
+  # Destructively convert all keys to symbols, as long as they respond
+  # to +to_sym+. This includes the keys from the root hash and from all
+  # nested hashes.
+  def deep_symbolize_keys!
+    deep_transform_keys!{ |key| key.to_sym rescue key }
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb
new file mode 100644
index 0000000..fbb4824
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb
@@ -0,0 +1,22 @@
+class Hash
+  # Merges the caller into +other_hash+. For example,
+  #
+  #   options = options.reverse_merge(size: 25, velocity: 10)
+  #
+  # is equivalent to
+  #
+  #   options = { size: 25, velocity: 10 }.merge(options)
+  #
+  # This is particularly useful for initializing an options hash
+  # with default values.
+  def reverse_merge(other_hash)
+    other_hash.merge(self)
+  end
+
+  # Destructive +reverse_merge+.
+  def reverse_merge!(other_hash)
+    # right wins if there is no left
+    merge!( other_hash ){|key,left,right| left }
+  end
+  alias_method :reverse_update, :reverse_merge!
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/hash/slice.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/slice.rb
new file mode 100644
index 0000000..8ad600b
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/hash/slice.rb
@@ -0,0 +1,42 @@
+class Hash
+  # Slice a hash to include only the given keys. This is useful for
+  # limiting an options hash to valid keys before passing to a method:
+  #
+  #   def search(criteria = {})
+  #     criteria.assert_valid_keys(:mass, :velocity, :time)
+  #   end
+  #
+  #   search(options.slice(:mass, :velocity, :time))
+  #
+  # If you have an array of keys you want to limit to, you should splat them:
+  #
+  #   valid_keys = [:mass, :velocity, :time]
+  #   search(options.slice(*valid_keys))
+  def slice(*keys)
+    keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
+    keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
+  end
+
+  # Replaces the hash with only the given keys.
+  # Returns a hash containing the removed key/value pairs.
+  #
+  #   { a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b)
+  #   # => {:c=>3, :d=>4}
+  def slice!(*keys)
+    keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
+    omit = slice(*self.keys - keys)
+    hash = slice(*keys)
+    hash.default      = default
+    hash.default_proc = default_proc if default_proc
+    replace(hash)
+    omit
+  end
+
+  # Removes and returns the key/value pairs matching the given keys.
+  #
+  #   { a: 1, b: 2, c: 3, d: 4 }.extract!(:a, :b) # => {:a=>1, :b=>2}
+  #   { a: 1, b: 2 }.extract!(:a, :x)             # => {:a=>1}
+  def extract!(*keys)
+    keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) }
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/integer.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/integer.rb
new file mode 100644
index 0000000..a44a1b4
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/integer.rb
@@ -0,0 +1,3 @@
+require 'active_support/core_ext/integer/multiple'
+require 'active_support/core_ext/integer/inflections'
+require 'active_support/core_ext/integer/time'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/integer/inflections.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/integer/inflections.rb
new file mode 100644
index 0000000..56f2ed5
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/integer/inflections.rb
@@ -0,0 +1,29 @@
+require 'active_support/inflector'
+
+class Integer
+  # Ordinalize turns a number into an ordinal string used to denote the
+  # position in an ordered sequence such as 1st, 2nd, 3rd, 4th.
+  #
+  #  1.ordinalize     # => "1st"
+  #  2.ordinalize     # => "2nd"
+  #  1002.ordinalize  # => "1002nd"
+  #  1003.ordinalize  # => "1003rd"
+  #  -11.ordinalize   # => "-11th"
+  #  -1001.ordinalize # => "-1001st"
+  def ordinalize
+    ActiveSupport::Inflector.ordinalize(self)
+  end
+
+  # Ordinal returns the suffix used to denote the position
+  # in an ordered sequence such as 1st, 2nd, 3rd, 4th.
+  #
+  #  1.ordinal     # => "st"
+  #  2.ordinal     # => "nd"
+  #  1002.ordinal  # => "nd"
+  #  1003.ordinal  # => "rd"
+  #  -11.ordinal   # => "th"
+  #  -1001.ordinal # => "st"
+  def ordinal
+    ActiveSupport::Inflector.ordinal(self)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/integer/multiple.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/integer/multiple.rb
new file mode 100644
index 0000000..c668c7c
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/integer/multiple.rb
@@ -0,0 +1,10 @@
+class Integer
+  # Check whether the integer is evenly divisible by the argument.
+  #
+  #   0.multiple_of?(0)  # => true
+  #   6.multiple_of?(5)  # => false
+  #   10.multiple_of?(2) # => true
+  def multiple_of?(number)
+    number != 0 ? self % number == 0 : zero?
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/integer/time.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/integer/time.rb
new file mode 100644
index 0000000..82080ff
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/integer/time.rb
@@ -0,0 +1,44 @@
+require 'active_support/duration'
+require 'active_support/core_ext/numeric/time'
+
+class Integer
+  # Enables the use of time calculations and declarations, like <tt>45.minutes +
+  # 2.hours + 4.years</tt>.
+  #
+  # These methods use Time#advance for precise date calculations when using
+  # <tt>from_now</tt>, +ago+, etc. as well as adding or subtracting their
+  # results from a Time object.
+  #
+  #   # equivalent to Time.now.advance(months: 1)
+  #   1.month.from_now
+  #
+  #   # equivalent to Time.now.advance(years: 2)
+  #   2.years.from_now
+  #
+  #   # equivalent to Time.now.advance(months: 4, years: 5)
+  #   (4.months + 5.years).from_now
+  #
+  # While these methods provide precise calculation when used as in the examples
+  # above, care should be taken to note that this is not true if the result of
+  # +months+, +years+, etc is converted before use:
+  #
+  #   # equivalent to 30.days.to_i.from_now
+  #   1.month.to_i.from_now
+  #
+  #   # equivalent to 365.25.days.to_f.from_now
+  #   1.year.to_f.from_now
+  #
+  # In such cases, Ruby's core
+  # Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and
+  # Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision
+  # date and time arithmetic.
+  def months
+    ActiveSupport::Duration.new(self * 30.days, [[:months, self]])
+  end
+  alias :month :months
+
+  def years
+    ActiveSupport::Duration.new(self * 365.25.days, [[:years, self]])
+  end
+  alias :year :years
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/kernel.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/kernel.rb
new file mode 100644
index 0000000..aa19aed
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/kernel.rb
@@ -0,0 +1,5 @@
+require 'active_support/core_ext/kernel/agnostics'
+require 'active_support/core_ext/kernel/concern'
+require 'active_support/core_ext/kernel/debugger'
+require 'active_support/core_ext/kernel/reporting'
+require 'active_support/core_ext/kernel/singleton_class'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/kernel/agnostics.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/kernel/agnostics.rb
new file mode 100644
index 0000000..64837d8
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/kernel/agnostics.rb
@@ -0,0 +1,11 @@
+class Object
+  # Makes backticks behave (somewhat more) similarly on all platforms.
+  # On win32 `nonexistent_command` raises Errno::ENOENT; on Unix, the
+  # spawned shell prints a message to stderr and sets $?. We emulate
+  # Unix on the former but not the latter.
+  def `(command) #:nodoc:
+    super
+  rescue Errno::ENOENT => e
+    STDERR.puts "#$0: #{e}"
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/kernel/concern.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/kernel/concern.rb
new file mode 100644
index 0000000..bf72caa
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/kernel/concern.rb
@@ -0,0 +1,10 @@
+require 'active_support/core_ext/module/concerning'
+
+module Kernel
+  # A shortcut to define a toplevel concern, not within a module.
+  #
+  # See Module::Concerning for more.
+  def concern(topic, &module_definition)
+    Object.concern topic, &module_definition
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/kernel/debugger.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/kernel/debugger.rb
new file mode 100644
index 0000000..2073cac
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/kernel/debugger.rb
@@ -0,0 +1,10 @@
+module Kernel
+  unless respond_to?(:debugger)
+    # Starts a debugging session if the +debugger+ gem has been loaded (call rails server --debugger to do load it).
+    def debugger
+      message = "\n***** Debugger requested, but was not available (ensure the debugger gem is listed in Gemfile/installed as gem): Start server with --debugger to enable *****\n"
+      defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
+    end
+    alias breakpoint debugger unless respond_to?(:breakpoint)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/kernel/reporting.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/kernel/reporting.rb
new file mode 100644
index 0000000..f3f8416
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/kernel/reporting.rb
@@ -0,0 +1,114 @@
+require 'rbconfig'
+require 'tempfile'
+
+module Kernel
+  # Sets $VERBOSE to nil for the duration of the block and back to its original
+  # value afterwards.
+  #
+  #   silence_warnings do
+  #     value = noisy_call # no warning voiced
+  #   end
+  #
+  #   noisy_call # warning voiced
+  def silence_warnings
+    with_warnings(nil) { yield }
+  end
+
+  # Sets $VERBOSE to +true+ for the duration of the block and back to its
+  # original value afterwards.
+  def enable_warnings
+    with_warnings(true) { yield }
+  end
+
+  # Sets $VERBOSE for the duration of the block and back to its original
+  # value afterwards.
+  def with_warnings(flag)
+    old_verbose, $VERBOSE = $VERBOSE, flag
+    yield
+  ensure
+    $VERBOSE = old_verbose
+  end
+
+  # For compatibility
+  def silence_stderr #:nodoc:
+    silence_stream(STDERR) { yield }
+  end
+
+  # Silences any stream for the duration of the block.
+  #
+  #   silence_stream(STDOUT) do
+  #     puts 'This will never be seen'
+  #   end
+  #
+  #   puts 'But this will'
+  #
+  # This method is not thread-safe.
+  def silence_stream(stream)
+    old_stream = stream.dup
+    stream.reopen(RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ? 'NUL:' : '/dev/null')
+    stream.sync = true
+    yield
+  ensure
+    stream.reopen(old_stream)
+    old_stream.close
+  end
+
+  # Blocks and ignores any exception passed as argument if raised within the block.
+  #
+  #   suppress(ZeroDivisionError) do
+  #     1/0
+  #     puts 'This code is NOT reached'
+  #   end
+  #
+  #   puts 'This code gets executed and nothing related to ZeroDivisionError was seen'
+  def suppress(*exception_classes)
+    yield
+  rescue *exception_classes
+  end
+
+  # Captures the given stream and returns it:
+  #
+  #   stream = capture(:stdout) { puts 'notice' }
+  #   stream # => "notice\n"
+  #
+  #   stream = capture(:stderr) { warn 'error' }
+  #   stream # => "error\n"
+  #
+  # even for subprocesses:
+  #
+  #   stream = capture(:stdout) { system('echo notice') }
+  #   stream # => "notice\n"
+  #
+  #   stream = capture(:stderr) { system('echo error 1>&2') }
+  #   stream # => "error\n"
+  def capture(stream)
+    stream = stream.to_s
+    captured_stream = Tempfile.new(stream)
+    stream_io = eval("$#{stream}")
+    origin_stream = stream_io.dup
+    stream_io.reopen(captured_stream)
+
+    yield
+
+    stream_io.rewind
+    return captured_stream.read
+  ensure
+    captured_stream.close
+    captured_stream.unlink
+    stream_io.reopen(origin_stream)
+  end
+  alias :silence :capture
+
+  # Silences both STDOUT and STDERR, even for subprocesses.
+  #
+  #   quietly { system 'bundle install' }
+  #
+  # This method is not thread-safe.
+  def quietly
+    silence_stream(STDOUT) do
+      silence_stream(STDERR) do
+        yield
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/kernel/singleton_class.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/kernel/singleton_class.rb
new file mode 100644
index 0000000..9bbf1bb
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/kernel/singleton_class.rb
@@ -0,0 +1,6 @@
+module Kernel
+  # class_eval on an object acts like singleton_class.class_eval.
+  def class_eval(*args, &block)
+    singleton_class.class_eval(*args, &block)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/load_error.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/load_error.rb
new file mode 100644
index 0000000..fe24f37
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/load_error.rb
@@ -0,0 +1,25 @@
+class LoadError
+  REGEXPS = [
+    /^no such file to load -- (.+)$/i,
+    /^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i,
+    /^Missing API definition file in (.+)$/i,
+    /^cannot load such file -- (.+)$/i,
+  ]
+
+  unless method_defined?(:path)
+    def path
+      @path ||= begin
+        REGEXPS.find do |regex|
+          message =~ regex
+        end
+        $1
+      end
+    end
+  end
+
+  def is_missing?(location)
+    location.sub(/\.rb$/, '') == path.sub(/\.rb$/, '')
+  end
+end
+
+MissingSourceFile = LoadError
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/marshal.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/marshal.rb
new file mode 100644
index 0000000..56c79c0
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/marshal.rb
@@ -0,0 +1,21 @@
+require 'active_support/core_ext/module/aliasing'
+
+module Marshal
+  class << self
+    def load_with_autoloading(source)
+      load_without_autoloading(source)
+    rescue ArgumentError, NameError => exc
+      if exc.message.match(%r|undefined class/module (.+)|)
+        # try loading the class/module
+        $1.constantize
+        # if it is a IO we need to go back to read the object
+        source.rewind if source.respond_to?(:rewind)
+        retry
+      else
+        raise exc
+      end
+    end
+
+    alias_method_chain :load, :autoloading
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/module.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/module.rb
new file mode 100644
index 0000000..b4efff8
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/module.rb
@@ -0,0 +1,11 @@
+require 'active_support/core_ext/module/aliasing'
+require 'active_support/core_ext/module/introspection'
+require 'active_support/core_ext/module/anonymous'
+require 'active_support/core_ext/module/reachable'
+require 'active_support/core_ext/module/attribute_accessors'
+require 'active_support/core_ext/module/attr_internal'
+require 'active_support/core_ext/module/concerning'
+require 'active_support/core_ext/module/delegation'
+require 'active_support/core_ext/module/deprecation'
+require 'active_support/core_ext/module/remove_method'
+require 'active_support/core_ext/module/qualified_const'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/module/aliasing.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/module/aliasing.rb
new file mode 100644
index 0000000..580cb80
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/module/aliasing.rb
@@ -0,0 +1,69 @@
+class Module
+  # Encapsulates the common pattern of:
+  #
+  #   alias_method :foo_without_feature, :foo
+  #   alias_method :foo, :foo_with_feature
+  #
+  # With this, you simply do:
+  #
+  #   alias_method_chain :foo, :feature
+  #
+  # And both aliases are set up for you.
+  #
+  # Query and bang methods (foo?, foo!) keep the same punctuation:
+  #
+  #   alias_method_chain :foo?, :feature
+  #
+  # is equivalent to
+  #
+  #   alias_method :foo_without_feature?, :foo?
+  #   alias_method :foo?, :foo_with_feature?
+  #
+  # so you can safely chain foo, foo?, and foo! with the same feature.
+  def alias_method_chain(target, feature)
+    # Strip out punctuation on predicates or bang methods since
+    # e.g. target?_without_feature is not a valid method name.
+    aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
+    yield(aliased_target, punctuation) if block_given?
+
+    with_method = "#{aliased_target}_with_#{feature}#{punctuation}"
+    without_method = "#{aliased_target}_without_#{feature}#{punctuation}"
+
+    alias_method without_method, target
+    alias_method target, with_method
+
+    case
+    when public_method_defined?(without_method)
+      public target
+    when protected_method_defined?(without_method)
+      protected target
+    when private_method_defined?(without_method)
+      private target
+    end
+  end
+
+  # Allows you to make aliases for attributes, which includes
+  # getter, setter, and query methods.
+  #
+  #   class Content < ActiveRecord::Base
+  #     # has a title attribute
+  #   end
+  #
+  #   class Email < Content
+  #     alias_attribute :subject, :title
+  #   end
+  #
+  #   e = Email.find(1)
+  #   e.title    # => "Superstars"
+  #   e.subject  # => "Superstars"
+  #   e.subject? # => true
+  #   e.subject = "Megastars"
+  #   e.title    # => "Megastars"
+  def alias_attribute(new_name, old_name)
+    module_eval <<-STR, __FILE__, __LINE__ + 1
+      def #{new_name}; self.#{old_name}; end          # def subject; self.title; end
+      def #{new_name}?; self.#{old_name}?; end        # def subject?; self.title?; end
+      def #{new_name}=(v); self.#{old_name} = v; end  # def subject=(v); self.title = v; end
+    STR
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/module/anonymous.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/module/anonymous.rb
new file mode 100644
index 0000000..b0c7b02
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/module/anonymous.rb
@@ -0,0 +1,19 @@
+class Module
+  # A module may or may not have a name.
+  #
+  #   module M; end
+  #   M.name # => "M"
+  #
+  #   m = Module.new
+  #   m.name # => nil
+  #
+  # A module gets a name when it is first assigned to a constant. Either
+  # via the +module+ or +class+ keyword or by an explicit assignment:
+  #
+  #   m = Module.new # creates an anonymous module
+  #   M = m          # => m gets a name here as a side-effect
+  #   m.name         # => "M"
+  def anonymous?
+    name.nil?
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/module/attr_internal.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/module/attr_internal.rb
new file mode 100644
index 0000000..67f0e03
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/module/attr_internal.rb
@@ -0,0 +1,39 @@
+class Module
+  # Declares an attribute reader backed by an internally-named instance variable.
+  def attr_internal_reader(*attrs)
+    attrs.each {|attr_name| attr_internal_define(attr_name, :reader)}
+  end
+
+  # Declares an attribute writer backed by an internally-named instance variable.
+  def attr_internal_writer(*attrs)
+    attrs.each {|attr_name| attr_internal_define(attr_name, :writer)}
+  end
+
+  # Declares an attribute reader and writer backed by an internally-named instance
+  # variable.
+  def attr_internal_accessor(*attrs)
+    attr_internal_reader(*attrs)
+    attr_internal_writer(*attrs)
+  end
+  alias_method :attr_internal, :attr_internal_accessor
+
+  class << self; attr_accessor :attr_internal_naming_format end
+  self.attr_internal_naming_format = '@_%s'
+
+  private
+    def attr_internal_ivar_name(attr)
+      Module.attr_internal_naming_format % attr
+    end
+
+    def attr_internal_define(attr_name, type)
+      internal_name = attr_internal_ivar_name(attr_name).sub(/\A@/, '')
+      # class_eval is necessary on 1.9 or else the methods are made private
+      class_eval do
+        # use native attr_* methods as they are faster on some Ruby implementations
+        send("attr_#{type}", internal_name)
+      end
+      attr_name, internal_name = "#{attr_name}=", "#{internal_name}=" if type == :writer
+      alias_method attr_name, internal_name
+      remove_method internal_name
+    end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
new file mode 100644
index 0000000..d317df5
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
@@ -0,0 +1,212 @@
+require 'active_support/core_ext/array/extract_options'
+
+# Extends the module object with class/module and instance accessors for
+# class/module attributes, just like the native attr* accessors for instance
+# attributes.
+class Module
+  # Defines a class attribute and creates a class and instance reader methods.
+  # The underlying the class variable is set to +nil+, if it is not previously
+  # defined.
+  #
+  #   module HairColors
+  #     mattr_reader :hair_colors
+  #   end
+  #
+  #   HairColors.hair_colors # => nil
+  #   HairColors.class_variable_set("@@hair_colors", [:brown, :black])
+  #   HairColors.hair_colors # => [:brown, :black]
+  #
+  # The attribute name must be a valid method name in Ruby.
+  #
+  #   module Foo
+  #     mattr_reader :"1_Badname "
+  #   end
+  #   # => NameError: invalid attribute name
+  #
+  # If you want to opt out the creation on the instance reader method, pass
+  # <tt>instance_reader: false</tt> or <tt>instance_accessor: false</tt>.
+  #
+  #   module HairColors
+  #     mattr_writer :hair_colors, instance_reader: false
+  #   end
+  #
+  #   class Person
+  #     include HairColors
+  #   end
+  #
+  #   Person.new.hair_colors # => NoMethodError
+  #
+  #
+  # Also, you can pass a block to set up the attribute with a default value.
+  #
+  #   module HairColors
+  #     cattr_reader :hair_colors do
+  #       [:brown, :black, :blonde, :red]
+  #     end
+  #   end
+  #
+  #   class Person
+  #     include HairColors
+  #   end
+  #
+  #   Person.hair_colors # => [:brown, :black, :blonde, :red]
+  def mattr_reader(*syms)
+    options = syms.extract_options!
+    syms.each do |sym|
+      raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/
+      class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+        @@#{sym} = nil unless defined? @@#{sym}
+
+        def self.#{sym}
+          @@#{sym}
+        end
+      EOS
+
+      unless options[:instance_reader] == false || options[:instance_accessor] == false
+        class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+          def #{sym}
+            @@#{sym}
+          end
+        EOS
+      end
+      class_variable_set("@@#{sym}", yield) if block_given?
+    end
+  end
+  alias :cattr_reader :mattr_reader
+
+  # Defines a class attribute and creates a class and instance writer methods to
+  # allow assignment to the attribute.
+  #
+  #   module HairColors
+  #     mattr_writer :hair_colors
+  #   end
+  #
+  #   class Person
+  #     include HairColors
+  #   end
+  #
+  #   HairColors.hair_colors = [:brown, :black]
+  #   Person.class_variable_get("@@hair_colors") # => [:brown, :black]
+  #   Person.new.hair_colors = [:blonde, :red]
+  #   HairColors.class_variable_get("@@hair_colors") # => [:blonde, :red]
+  #
+  # If you want to opt out the instance writer method, pass
+  # <tt>instance_writer: false</tt> or <tt>instance_accessor: false</tt>.
+  #
+  #   module HairColors
+  #     mattr_writer :hair_colors, instance_writer: false
+  #   end
+  #
+  #   class Person
+  #     include HairColors
+  #   end
+  #
+  #   Person.new.hair_colors = [:blonde, :red] # => NoMethodError
+  #
+  # Also, you can pass a block to set up the attribute with a default value.
+  #
+  #   class HairColors
+  #     mattr_writer :hair_colors do
+  #       [:brown, :black, :blonde, :red]
+  #     end
+  #   end
+  #
+  #   class Person
+  #     include HairColors
+  #   end
+  #
+  #   Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
+  def mattr_writer(*syms)
+    options = syms.extract_options!
+    syms.each do |sym|
+      raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/
+      class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+        @@#{sym} = nil unless defined? @@#{sym}
+
+        def self.#{sym}=(obj)
+          @@#{sym} = obj
+        end
+      EOS
+
+      unless options[:instance_writer] == false || options[:instance_accessor] == false
+        class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+          def #{sym}=(obj)
+            @@#{sym} = obj
+          end
+        EOS
+      end
+      send("#{sym}=", yield) if block_given?
+    end
+  end
+  alias :cattr_writer :mattr_writer
+
+  # Defines both class and instance accessors for class attributes.
+  #
+  #   module HairColors
+  #     mattr_accessor :hair_colors
+  #   end
+  #
+  #   class Person
+  #     include HairColors
+  #   end
+  #
+  #   Person.hair_colors = [:brown, :black, :blonde, :red]
+  #   Person.hair_colors     # => [:brown, :black, :blonde, :red]
+  #   Person.new.hair_colors # => [:brown, :black, :blonde, :red]
+  #
+  # If a subclass changes the value then that would also change the value for
+  # parent class. Similarly if parent class changes the value then that would
+  # change the value of subclasses too.
+  #
+  #   class Male < Person
+  #   end
+  #
+  #   Male.hair_colors << :blue
+  #   Person.hair_colors # => [:brown, :black, :blonde, :red, :blue]
+  #
+  # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
+  # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
+  #
+  #   module HairColors
+  #     mattr_accessor :hair_colors, instance_writer: false, instance_reader: false
+  #   end
+  #
+  #   class Person
+  #     include HairColors
+  #   end
+  #
+  #   Person.new.hair_colors = [:brown]  # => NoMethodError
+  #   Person.new.hair_colors             # => NoMethodError
+  #
+  # Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
+  #
+  #   module HairColors
+  #     mattr_accessor :hair_colors, instance_accessor: false
+  #   end
+  #
+  #   class Person
+  #     include HairColors
+  #   end
+  #
+  #   Person.new.hair_colors = [:brown]  # => NoMethodError
+  #   Person.new.hair_colors             # => NoMethodError
+  #
+  # Also you can pass a block to set up the attribute with a default value.
+  #
+  #   module HairColors
+  #     mattr_accessor :hair_colors do
+  #       [:brown, :black, :blonde, :red]
+  #     end
+  #   end
+  #
+  #   class Person
+  #     include HairColors
+  #   end
+  #
+  #   Person.class_variable_get("@@hair_colors") #=> [:brown, :black, :blonde, :red]
+  def mattr_accessor(*syms, &blk)
+    mattr_reader(*syms, &blk)
+    mattr_writer(*syms, &blk)
+  end
+  alias :cattr_accessor :mattr_accessor
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/module/concerning.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/module/concerning.rb
new file mode 100644
index 0000000..07a3924
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/module/concerning.rb
@@ -0,0 +1,135 @@
+require 'active_support/concern'
+
+class Module
+  # = Bite-sized separation of concerns
+  #
+  # We often find ourselves with a medium-sized chunk of behavior that we'd
+  # like to extract, but only mix in to a single class.
+  #
+  # Extracting a plain old Ruby object to encapsulate it and collaborate or
+  # delegate to the original object is often a good choice, but when there's
+  # no additional state to encapsulate or we're making DSL-style declarations
+  # about the parent class, introducing new collaborators can obfuscate rather
+  # than simplify.
+  #
+  # The typical route is to just dump everything in a monolithic class, perhaps
+  # with a comment, as a least-bad alternative. Using modules in separate files
+  # means tedious sifting to get a big-picture view.
+  #
+  # = Dissatisfying ways to separate small concerns
+  #
+  # == Using comments:
+  #
+  #   class Todo
+  #     # Other todo implementation
+  #     # ...
+  #
+  #     ## Event tracking
+  #     has_many :events
+  #
+  #     before_create :track_creation
+  #     after_destroy :track_deletion
+  #
+  #     private
+  #       def track_creation
+  #         # ...
+  #       end
+  #   end
+  #
+  # == With an inline module:
+  #
+  # Noisy syntax.
+  #
+  #   class Todo
+  #     # Other todo implementation
+  #     # ...
+  #
+  #     module EventTracking
+  #       extend ActiveSupport::Concern
+  #
+  #       included do
+  #         has_many :events
+  #         before_create :track_creation
+  #         after_destroy :track_deletion
+  #       end
+  #
+  #       private
+  #         def track_creation
+  #           # ...
+  #         end
+  #     end
+  #     include EventTracking
+  #   end
+  #
+  # == Mix-in noise exiled to its own file:
+  #
+  # Once our chunk of behavior starts pushing the scroll-to-understand it's
+  # boundary, we give in and move it to a separate file. At this size, the
+  # overhead feels in good proportion to the size of our extraction, despite
+  # diluting our at-a-glance sense of how things really work.
+  #
+  #   class Todo
+  #     # Other todo implementation
+  #     # ...
+  #
+  #     include TodoEventTracking
+  #   end
+  #
+  # = Introducing Module#concerning
+  #
+  # By quieting the mix-in noise, we arrive at a natural, low-ceremony way to
+  # separate bite-sized concerns.
+  #
+  #   class Todo
+  #     # Other todo implementation
+  #     # ...
+  #
+  #     concerning :EventTracking do
+  #       included do
+  #         has_many :events
+  #         before_create :track_creation
+  #         after_destroy :track_deletion
+  #       end
+  #
+  #       private
+  #         def track_creation
+  #           # ...
+  #         end
+  #     end
+  #   end
+  #
+  #   Todo.ancestors
+  #   # => Todo, Todo::EventTracking, Object
+  #
+  # This small step has some wonderful ripple effects. We can
+  # * grok the behavior of our class in one glance,
+  # * clean up monolithic junk-drawer classes by separating their concerns, and
+  # * stop leaning on protected/private for crude "this is internal stuff" modularity.
+  module Concerning
+    # Define a new concern and mix it in.
+    def concerning(topic, &block)
+      include concern(topic, &block)
+    end
+
+    # A low-cruft shortcut to define a concern.
+    #
+    #   concern :EventTracking do
+    #     ...
+    #   end
+    #
+    # is equivalent to
+    #
+    #   module EventTracking
+    #     extend ActiveSupport::Concern
+    #
+    #     ...
+    #   end
+    def concern(topic, &module_definition)
+      const_set topic, Module.new {
+        extend ::ActiveSupport::Concern
+        module_eval(&module_definition)
+      }
+    end
+  end
+  include Concerning
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/module/delegation.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/module/delegation.rb
new file mode 100644
index 0000000..f855833
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -0,0 +1,209 @@
+class Module
+  # Error generated by +delegate+ when a method is called on +nil+ and +allow_nil+
+  # option is not used.
+  class DelegationError < NoMethodError; end
+
+  # Provides a +delegate+ class method to easily expose contained objects'
+  # public methods as your own.
+  #
+  # ==== Options
+  # * <tt>:to</tt> - Specifies the target object
+  # * <tt>:prefix</tt> - Prefixes the new method with the target name or a custom prefix
+  # * <tt>:allow_nil</tt> - if set to true, prevents a +NoMethodError+ to be raised
+  #
+  # The macro receives one or more method names (specified as symbols or
+  # strings) and the name of the target object via the <tt>:to</tt> option
+  # (also a symbol or string).
+  #
+  # Delegation is particularly useful with Active Record associations:
+  #
+  #   class Greeter < ActiveRecord::Base
+  #     def hello
+  #       'hello'
+  #     end
+  #
+  #     def goodbye
+  #       'goodbye'
+  #     end
+  #   end
+  #
+  #   class Foo < ActiveRecord::Base
+  #     belongs_to :greeter
+  #     delegate :hello, to: :greeter
+  #   end
+  #
+  #   Foo.new.hello   # => "hello"
+  #   Foo.new.goodbye # => NoMethodError: undefined method `goodbye' for #<Foo:0x1af30c>
+  #
+  # Multiple delegates to the same target are allowed:
+  #
+  #   class Foo < ActiveRecord::Base
+  #     belongs_to :greeter
+  #     delegate :hello, :goodbye, to: :greeter
+  #   end
+  #
+  #   Foo.new.goodbye # => "goodbye"
+  #
+  # Methods can be delegated to instance variables, class variables, or constants
+  # by providing them as a symbols:
+  #
+  #   class Foo
+  #     CONSTANT_ARRAY = [0,1,2,3]
+  #     @@class_array  = [4,5,6,7]
+  #
+  #     def initialize
+  #       @instance_array = [8,9,10,11]
+  #     end
+  #     delegate :sum, to: :CONSTANT_ARRAY
+  #     delegate :min, to: :@@class_array
+  #     delegate :max, to: :@instance_array
+  #   end
+  #
+  #   Foo.new.sum # => 6
+  #   Foo.new.min # => 4
+  #   Foo.new.max # => 11
+  #
+  # It's also possible to delegate a method to the class by using +:class+:
+  #
+  #   class Foo
+  #     def self.hello
+  #       "world"
+  #     end
+  #
+  #     delegate :hello, to: :class
+  #   end
+  #
+  #   Foo.new.hello # => "world"
+  #
+  # Delegates can optionally be prefixed using the <tt>:prefix</tt> option. If the value
+  # is <tt>true</tt>, the delegate methods are prefixed with the name of the object being
+  # delegated to.
+  #
+  #   Person = Struct.new(:name, :address)
+  #
+  #   class Invoice < Struct.new(:client)
+  #     delegate :name, :address, to: :client, prefix: true
+  #   end
+  #
+  #   john_doe = Person.new('John Doe', 'Vimmersvej 13')
+  #   invoice = Invoice.new(john_doe)
+  #   invoice.client_name    # => "John Doe"
+  #   invoice.client_address # => "Vimmersvej 13"
+  #
+  # It is also possible to supply a custom prefix.
+  #
+  #   class Invoice < Struct.new(:client)
+  #     delegate :name, :address, to: :client, prefix: :customer
+  #   end
+  #
+  #   invoice = Invoice.new(john_doe)
+  #   invoice.customer_name    # => 'John Doe'
+  #   invoice.customer_address # => 'Vimmersvej 13'
+  #
+  # If the target is +nil+ and does not respond to the delegated method a
+  # +NoMethodError+ is raised, as with any other value. Sometimes, however, it
+  # makes sense to be robust to that situation and that is the purpose of the
+  # <tt>:allow_nil</tt> option: If the target is not +nil+, or it is and
+  # responds to the method, everything works as usual. But if it is +nil+ and
+  # does not respond to the delegated method, +nil+ is returned.
+  #
+  #   class User < ActiveRecord::Base
+  #     has_one :profile
+  #     delegate :age, to: :profile
+  #   end
+  #
+  #   User.new.age # raises NoMethodError: undefined method `age'
+  #
+  # But if not having a profile yet is fine and should not be an error
+  # condition:
+  #
+  #   class User < ActiveRecord::Base
+  #     has_one :profile
+  #     delegate :age, to: :profile, allow_nil: true
+  #   end
+  #
+  #   User.new.age # nil
+  #
+  # Note that if the target is not +nil+ then the call is attempted regardless of the
+  # <tt>:allow_nil</tt> option, and thus an exception is still raised if said object
+  # does not respond to the method:
+  #
+  #   class Foo
+  #     def initialize(bar)
+  #       @bar = bar
+  #     end
+  #
+  #     delegate :name, to: :@bar, allow_nil: true
+  #   end
+  #
+  #   Foo.new("Bar").name # raises NoMethodError: undefined method `name'
+  #
+  # The target method must be public, otherwise it will raise +NoMethodError+.
+  #
+  def delegate(*methods)
+    options = methods.pop
+    unless options.is_a?(Hash) && to = options[:to]
+      raise ArgumentError, 'Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter).'
+    end
+
+    prefix, allow_nil = options.values_at(:prefix, :allow_nil)
+
+    if prefix == true && to =~ /^[^a-z_]/
+      raise ArgumentError, 'Can only automatically set the delegation prefix when delegating to a method.'
+    end
+
+    method_prefix = \
+      if prefix
+        "#{prefix == true ? to : prefix}_"
+      else
+        ''
+      end
+
+    file, line = caller.first.split(':', 2)
+    line = line.to_i
+
+    to = to.to_s
+    to = 'self.class' if to == 'class'
+
+    methods.each do |method|
+      # Attribute writer methods only accept one argument. Makes sure []=
+      # methods still accept two arguments.
+      definition = (method =~ /[^\]]=$/) ? 'arg' : '*args, &block'
+
+      # The following generated methods call the target exactly once, storing
+      # the returned value in a dummy variable.
+      #
+      # Reason is twofold: On one hand doing less calls is in general better.
+      # On the other hand it could be that the target has side-effects,
+      # whereas conceptually, from the user point of view, the delegator should
+      # be doing one call.
+      if allow_nil
+        method_def = [
+          "def #{method_prefix}#{method}(#{definition})",  # def customer_name(*args, &block)
+          "_ = #{to}",                                     #   _ = client
+          "if !_.nil? || nil.respond_to?(:#{method})",     #   if !_.nil? || nil.respond_to?(:name)
+          "  _.#{method}(#{definition})",                  #     _.name(*args, &block)
+          "end",                                           #   end
+        "end"                                              # end
+        ].join ';'
+      else
+        exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
+
+        method_def = [
+          "def #{method_prefix}#{method}(#{definition})",  # def customer_name(*args, &block)
+          " _ = #{to}",                                    #   _ = client
+          "  _.#{method}(#{definition})",                  #   _.name(*args, &block)
+          "rescue NoMethodError => e",                     # rescue NoMethodError => e
+          "  if _.nil? && e.name == :#{method}",           #   if _.nil? && e.name == :name
+          "    #{exception}",                              #     # add helpful message to the exception
+          "  else",                                        #   else
+          "    raise",                                     #     raise
+          "  end",                                         #   end
+          "end"                                            # end
+        ].join ';'
+      end
+
+      module_eval(method_def, file, line)
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/module/deprecation.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/module/deprecation.rb
new file mode 100644
index 0000000..56d670f
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/module/deprecation.rb
@@ -0,0 +1,23 @@
+class Module
+  #   deprecate :foo
+  #   deprecate bar: 'message'
+  #   deprecate :foo, :bar, baz: 'warning!', qux: 'gone!'
+  #
+  # You can also use custom deprecator instance:
+  #
+  #   deprecate :foo, deprecator: MyLib::Deprecator.new
+  #   deprecate :foo, bar: "warning!", deprecator: MyLib::Deprecator.new
+  #
+  # \Custom deprecators must respond to <tt>deprecation_warning(deprecated_method_name, message, caller_backtrace)</tt>
+  # method where you can implement your custom warning behavior.
+  #
+  #   class MyLib::Deprecator
+  #     def deprecation_warning(deprecated_method_name, message, caller_backtrace = nil)
+  #        message = "#{deprecated_method_name} is deprecated and will be removed from MyLibrary | #{message}"
+  #        Kernel.warn message
+  #     end
+  #   end
+  def deprecate(*method_names)
+    ActiveSupport::Deprecation.deprecate_methods(self, *method_names)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/module/introspection.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/module/introspection.rb
new file mode 100644
index 0000000..f1d26ef
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/module/introspection.rb
@@ -0,0 +1,62 @@
+require 'active_support/inflector'
+
+class Module
+  # Returns the name of the module containing this one.
+  #
+  #   M::N.parent_name # => "M"
+  def parent_name
+    if defined? @parent_name
+      @parent_name
+    else
+      @parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
+    end
+  end
+
+  # Returns the module which contains this one according to its name.
+  #
+  #   module M
+  #     module N
+  #     end
+  #   end
+  #   X = M::N
+  #
+  #   M::N.parent # => M
+  #   X.parent    # => M
+  #
+  # The parent of top-level and anonymous modules is Object.
+  #
+  #   M.parent          # => Object
+  #   Module.new.parent # => Object
+  def parent
+    parent_name ? ActiveSupport::Inflector.constantize(parent_name) : Object
+  end
+
+  # Returns all the parents of this module according to its name, ordered from
+  # nested outwards. The receiver is not contained within the result.
+  #
+  #   module M
+  #     module N
+  #     end
+  #   end
+  #   X = M::N
+  #
+  #   M.parents    # => [Object]
+  #   M::N.parents # => [M, Object]
+  #   X.parents    # => [M, Object]
+  def parents
+    parents = []
+    if parent_name
+      parts = parent_name.split('::')
+      until parts.empty?
+        parents << ActiveSupport::Inflector.constantize(parts * '::')
+        parts.pop
+      end
+    end
+    parents << Object unless parents.include? Object
+    parents
+  end
+
+  def local_constants #:nodoc:
+    constants(false)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/module/method_transplanting.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/module/method_transplanting.rb
new file mode 100644
index 0000000..b1097cc
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/module/method_transplanting.rb
@@ -0,0 +1,11 @@
+class Module
+  ###
+  # TODO: remove this after 1.9 support is dropped
+  def methods_transplantable? # :nodoc:
+    x = Module.new { def foo; end }
+    Module.new { define_method :bar, x.instance_method(:foo) }
+    true
+  rescue TypeError
+    false
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/module/qualified_const.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/module/qualified_const.rb
new file mode 100644
index 0000000..6552501
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/module/qualified_const.rb
@@ -0,0 +1,52 @@
+require 'active_support/core_ext/string/inflections'
+
+#--
+# Allows code reuse in the methods below without polluting Module.
+#++
+module QualifiedConstUtils
+  def self.raise_if_absolute(path)
+    raise NameError.new("wrong constant name #$&") if path =~ /\A::[^:]+/
+  end
+
+  def self.names(path)
+    path.split('::')
+  end
+end
+
+##
+# Extends the API for constants to be able to deal with qualified names. Arguments
+# are assumed to be relative to the receiver.
+#
+#--
+# Qualified names are required to be relative because we are extending existing
+# methods that expect constant names, ie, relative paths of length 1. For example,
+# Object.const_get('::String') raises NameError and so does qualified_const_get.
+#++
+class Module
+  def qualified_const_defined?(path, search_parents=true)
+    QualifiedConstUtils.raise_if_absolute(path)
+
+    QualifiedConstUtils.names(path).inject(self) do |mod, name|
+      return unless mod.const_defined?(name, search_parents)
+      mod.const_get(name)
+    end
+    return true
+  end
+
+  def qualified_const_get(path)
+    QualifiedConstUtils.raise_if_absolute(path)
+
+    QualifiedConstUtils.names(path).inject(self) do |mod, name|
+      mod.const_get(name)
+    end
+  end
+
+  def qualified_const_set(path, value)
+    QualifiedConstUtils.raise_if_absolute(path)
+
+    const_name = path.demodulize
+    mod_name = path.deconstantize
+    mod = mod_name.empty? ? self : qualified_const_get(mod_name)
+    mod.const_set(const_name, value)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/module/reachable.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/module/reachable.rb
new file mode 100644
index 0000000..5d3d0e9
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/module/reachable.rb
@@ -0,0 +1,8 @@
+require 'active_support/core_ext/module/anonymous'
+require 'active_support/core_ext/string/inflections'
+
+class Module
+  def reachable? #:nodoc:
+    !anonymous? && name.safe_constantize.equal?(self)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/module/remove_method.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/module/remove_method.rb
new file mode 100644
index 0000000..719071d
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/module/remove_method.rb
@@ -0,0 +1,12 @@
+class Module
+  def remove_possible_method(method)
+    if method_defined?(method) || private_method_defined?(method)
+      undef_method(method)
+    end
+  end
+
+  def redefine_method(method, &block)
+    remove_possible_method(method)
+    define_method(method, &block)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/name_error.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/name_error.rb
new file mode 100644
index 0000000..e1ebd4f
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/name_error.rb
@@ -0,0 +1,18 @@
+class NameError
+  # Extract the name of the missing constant from the exception message.
+  def missing_name
+    if /undefined local variable or method/ !~ message
+      $1 if /((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/ =~ message
+    end
+  end
+
+  # Was this exception raised because the given name was missing?
+  def missing_name?(name)
+    if name.is_a? Symbol
+      last_name = (missing_name || '').split('::').last
+      last_name == name.to_s
+    else
+      missing_name == name.to_s
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/numeric.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/numeric.rb
new file mode 100644
index 0000000..a6bc062
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/numeric.rb
@@ -0,0 +1,3 @@
+require 'active_support/core_ext/numeric/bytes'
+require 'active_support/core_ext/numeric/time'
+require 'active_support/core_ext/numeric/conversions'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/numeric/bytes.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/numeric/bytes.rb
new file mode 100644
index 0000000..deea8e9
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/numeric/bytes.rb
@@ -0,0 +1,44 @@
+class Numeric
+  KILOBYTE = 1024
+  MEGABYTE = KILOBYTE * 1024
+  GIGABYTE = MEGABYTE * 1024
+  TERABYTE = GIGABYTE * 1024
+  PETABYTE = TERABYTE * 1024
+  EXABYTE  = PETABYTE * 1024
+
+  # Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
+  def bytes
+    self
+  end
+  alias :byte :bytes
+
+  def kilobytes
+    self * KILOBYTE
+  end
+  alias :kilobyte :kilobytes
+
+  def megabytes
+    self * MEGABYTE
+  end
+  alias :megabyte :megabytes
+
+  def gigabytes
+    self * GIGABYTE
+  end
+  alias :gigabyte :gigabytes
+
+  def terabytes
+    self * TERABYTE
+  end
+  alias :terabyte :terabytes
+
+  def petabytes
+    self * PETABYTE
+  end
+  alias :petabyte :petabytes
+
+  def exabytes
+    self * EXABYTE
+  end
+  alias :exabyte :exabytes
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/numeric/conversions.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/numeric/conversions.rb
new file mode 100644
index 0000000..6d3635c
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/numeric/conversions.rb
@@ -0,0 +1,135 @@
+require 'active_support/core_ext/big_decimal/conversions'
+require 'active_support/number_helper'
+
+class Numeric
+
+  # Provides options for converting numbers into formatted strings.
+  # Options are provided for phone numbers, currency, percentage,
+  # precision, positional notation, file size and pretty printing.
+  #
+  # ==== Options
+  #
+  # For details on which formats use which options, see ActiveSupport::NumberHelper
+  #
+  # ==== Examples
+  #
+  #  Phone Numbers:
+  #  5551234.to_s(:phone)                                     # => 555-1234
+  #  1235551234.to_s(:phone)                                  # => 123-555-1234
+  #  1235551234.to_s(:phone, area_code: true)                 # => (123) 555-1234
+  #  1235551234.to_s(:phone, delimiter: ' ')                  # => 123 555 1234
+  #  1235551234.to_s(:phone, area_code: true, extension: 555) # => (123) 555-1234 x 555
+  #  1235551234.to_s(:phone, country_code: 1)                 # => +1-123-555-1234
+  #  1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.')
+  #  # => +1.123.555.1234 x 1343
+  #
+  #  Currency:
+  #  1234567890.50.to_s(:currency)                 # => $1,234,567,890.50
+  #  1234567890.506.to_s(:currency)                # => $1,234,567,890.51
+  #  1234567890.506.to_s(:currency, precision: 3)  # => $1,234,567,890.506
+  #  1234567890.506.to_s(:currency, locale: :fr)   # => 1 234 567 890,51 €
+  #  -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
+  #  # => ($1,234,567,890.50)
+  #  1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '')
+  #  # => £1234567890,50
+  #  1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '', format: '%n %u')
+  #  # => 1234567890,50 £
+  #
+  #  Percentage:
+  #  100.to_s(:percentage)                                  # => 100.000%
+  #  100.to_s(:percentage, precision: 0)                    # => 100%
+  #  1000.to_s(:percentage, delimiter: '.', separator: ',') # => 1.000,000%
+  #  302.24398923423.to_s(:percentage, precision: 5)        # => 302.24399%
+  #  1000.to_s(:percentage, locale: :fr)                    # => 1 000,000%
+  #  100.to_s(:percentage, format: '%n  %')                 # => 100  %
+  #
+  #  Delimited:
+  #  12345678.to_s(:delimited)                     # => 12,345,678
+  #  12345678.05.to_s(:delimited)                  # => 12,345,678.05
+  #  12345678.to_s(:delimited, delimiter: '.')     # => 12.345.678
+  #  12345678.to_s(:delimited, delimiter: ',')     # => 12,345,678
+  #  12345678.05.to_s(:delimited, separator: ' ')  # => 12,345,678 05
+  #  12345678.05.to_s(:delimited, locale: :fr)     # => 12 345 678,05
+  #  98765432.98.to_s(:delimited, delimiter: ' ', separator: ',')
+  #  # => 98 765 432,98
+  #
+  #  Rounded:
+  #  111.2345.to_s(:rounded)                                      # => 111.235
+  #  111.2345.to_s(:rounded, precision: 2)                        # => 111.23
+  #  13.to_s(:rounded, precision: 5)                              # => 13.00000
+  #  389.32314.to_s(:rounded, precision: 0)                       # => 389
+  #  111.2345.to_s(:rounded, significant: true)                   # => 111
+  #  111.2345.to_s(:rounded, precision: 1, significant: true)     # => 100
+  #  13.to_s(:rounded, precision: 5, significant: true)           # => 13.000
+  #  111.234.to_s(:rounded, locale: :fr)                          # => 111,234
+  #  13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
+  #  # => 13
+  #  389.32314.to_s(:rounded, precision: 4, significant: true)    # => 389.3
+  #  1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.')
+  #  # => 1.111,23
+  #
+  #  Human-friendly size in Bytes:
+  #  123.to_s(:human_size)                                   # => 123 Bytes
+  #  1234.to_s(:human_size)                                  # => 1.21 KB
+  #  12345.to_s(:human_size)                                 # => 12.1 KB
+  #  1234567.to_s(:human_size)                               # => 1.18 MB
+  #  1234567890.to_s(:human_size)                            # => 1.15 GB
+  #  1234567890123.to_s(:human_size)                         # => 1.12 TB
+  #  1234567.to_s(:human_size, precision: 2)                 # => 1.2 MB
+  #  483989.to_s(:human_size, precision: 2)                  # => 470 KB
+  #  1234567.to_s(:human_size, precision: 2, separator: ',') # => 1,2 MB
+  #  1234567890123.to_s(:human_size, precision: 5)           # => "1.1229 TB"
+  #  524288000.to_s(:human_size, precision: 5)               # => "500 MB"
+  #
+  #  Human-friendly format:
+  #  123.to_s(:human)                                       # => "123"
+  #  1234.to_s(:human)                                      # => "1.23 Thousand"
+  #  12345.to_s(:human)                                     # => "12.3 Thousand"
+  #  1234567.to_s(:human)                                   # => "1.23 Million"
+  #  1234567890.to_s(:human)                                # => "1.23 Billion"
+  #  1234567890123.to_s(:human)                             # => "1.23 Trillion"
+  #  1234567890123456.to_s(:human)                          # => "1.23 Quadrillion"
+  #  1234567890123456789.to_s(:human)                       # => "1230 Quadrillion"
+  #  489939.to_s(:human, precision: 2)                      # => "490 Thousand"
+  #  489939.to_s(:human, precision: 4)                      # => "489.9 Thousand"
+  #  1234567.to_s(:human, precision: 4,
+  #                   significant: false)                   # => "1.2346 Million"
+  #  1234567.to_s(:human, precision: 1,
+  #                   separator: ',',
+  #                   significant: false)                   # => "1,2 Million"
+  def to_formatted_s(format = :default, options = {})
+    case format
+    when :phone
+      return ActiveSupport::NumberHelper.number_to_phone(self, options)
+    when :currency
+      return ActiveSupport::NumberHelper.number_to_currency(self, options)
+    when :percentage
+      return ActiveSupport::NumberHelper.number_to_percentage(self, options)
+    when :delimited
+      return ActiveSupport::NumberHelper.number_to_delimited(self, options)
+    when :rounded
+      return ActiveSupport::NumberHelper.number_to_rounded(self, options)
+    when :human
+      return ActiveSupport::NumberHelper.number_to_human(self, options)
+    when :human_size
+      return ActiveSupport::NumberHelper.number_to_human_size(self, options)
+    else
+      self.to_default_s
+    end
+  end
+
+  [Float, Fixnum, Bignum, BigDecimal].each do |klass|
+    klass.send(:alias_method, :to_default_s, :to_s)
+
+    klass.send(:define_method, :to_s) do |*args|
+      if args[0].is_a?(Symbol)
+        format = args[0]
+        options = args[1] || {}
+
+        self.to_formatted_s(format, options)
+      else
+        to_default_s(*args)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/numeric/time.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/numeric/time.rb
new file mode 100644
index 0000000..704c424
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/numeric/time.rb
@@ -0,0 +1,87 @@
+require 'active_support/duration'
+require 'active_support/core_ext/time/calculations'
+require 'active_support/core_ext/time/acts_like'
+
+class Numeric
+  # Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
+  #
+  # These methods use Time#advance for precise date calculations when using from_now, ago, etc.
+  # as well as adding or subtracting their results from a Time object. For example:
+  #
+  #   # equivalent to Time.current.advance(months: 1)
+  #   1.month.from_now
+  #
+  #   # equivalent to Time.current.advance(years: 2)
+  #   2.years.from_now
+  #
+  #   # equivalent to Time.current.advance(months: 4, years: 5)
+  #   (4.months + 5.years).from_now
+  #
+  # While these methods provide precise calculation when used as in the examples above, care
+  # should be taken to note that this is not true if the result of `months', `years', etc is
+  # converted before use:
+  #
+  #   # equivalent to 30.days.to_i.from_now
+  #   1.month.to_i.from_now
+  #
+  #   # equivalent to 365.25.days.to_f.from_now
+  #   1.year.to_f.from_now
+  #
+  # In such cases, Ruby's core
+  # Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and
+  # Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision
+  # date and time arithmetic.
+  def seconds
+    ActiveSupport::Duration.new(self, [[:seconds, self]])
+  end
+  alias :second :seconds
+
+  def minutes
+    ActiveSupport::Duration.new(self * 60, [[:seconds, self * 60]])
+  end
+  alias :minute :minutes
+
+  def hours
+    ActiveSupport::Duration.new(self * 3600, [[:seconds, self * 3600]])
+  end
+  alias :hour :hours
+
+  def days
+    ActiveSupport::Duration.new(self * 24.hours, [[:days, self]])
+  end
+  alias :day :days
+
+  def weeks
+    ActiveSupport::Duration.new(self * 7.days, [[:days, self * 7]])
+  end
+  alias :week :weeks
+
+  def fortnights
+    ActiveSupport::Duration.new(self * 2.weeks, [[:days, self * 14]])
+  end
+  alias :fortnight :fortnights
+
+  # Reads best without arguments:  10.minutes.ago
+  def ago(time = ::Time.current)
+    ActiveSupport::Deprecation.warn "Calling #ago or #until on a number (e.g. 5.ago) is deprecated and will be removed in the future, use 5.seconds.ago instead"
+    time - self
+  end
+
+  # Reads best with argument:  10.minutes.until(time)
+  alias :until :ago
+
+  # Reads best with argument:  10.minutes.since(time)
+  def since(time = ::Time.current)
+    ActiveSupport::Deprecation.warn "Calling #since or #from_now on a number (e.g. 5.since) is deprecated and will be removed in the future, use 5.seconds.since instead"
+    time + self
+  end
+
+  # Reads best without arguments:  10.minutes.from_now
+  alias :from_now :since
+
+  # Used with the standard time durations, like 1.hour.in_milliseconds -- 
+  # so we can feed them to JavaScript functions like getTime().
+  def in_milliseconds
+    self * 1000
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/object.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/object.rb
new file mode 100644
index 0000000..f4f9152
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/object.rb
@@ -0,0 +1,14 @@
+require 'active_support/core_ext/object/acts_like'
+require 'active_support/core_ext/object/blank'
+require 'active_support/core_ext/object/duplicable'
+require 'active_support/core_ext/object/deep_dup'
+require 'active_support/core_ext/object/try'
+require 'active_support/core_ext/object/inclusion'
+
+require 'active_support/core_ext/object/conversions'
+require 'active_support/core_ext/object/instance_variables'
+
+require 'active_support/core_ext/object/json'
+require 'active_support/core_ext/object/to_param'
+require 'active_support/core_ext/object/to_query'
+require 'active_support/core_ext/object/with_options'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/object/acts_like.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/object/acts_like.rb
new file mode 100644
index 0000000..3912cc5
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/object/acts_like.rb
@@ -0,0 +1,10 @@
+class Object
+  # A duck-type assistant method. For example, Active Support extends Date
+  # to define an <tt>acts_like_date?</tt> method, and extends Time to define
+  # <tt>acts_like_time?</tt>. As a result, we can do <tt>x.acts_like?(:time)</tt> and
+  # <tt>x.acts_like?(:date)</tt> to do duck-type-safe comparisons, since classes that
+  # we want to act like Time simply need to define an <tt>acts_like_time?</tt> method.
+  def acts_like?(duck)
+    respond_to? :"acts_like_#{duck}?"
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/object/blank.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/object/blank.rb
new file mode 100644
index 0000000..38e4347
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/object/blank.rb
@@ -0,0 +1,131 @@
+# encoding: utf-8
+
+class Object
+  # An object is blank if it's false, empty, or a whitespace string.
+  # For example, '', '   ', +nil+, [], and {} are all blank.
+  #
+  # This simplifies
+  #
+  #   address.nil? || address.empty?
+  #
+  # to
+  #
+  #   address.blank?
+  #
+  # @return [true, false]
+  def blank?
+    respond_to?(:empty?) ? !!empty? : !self
+  end
+
+  # An object is present if it's not blank.
+  #
+  # @return [true, false]
+  def present?
+    !blank?
+  end
+
+  # Returns the receiver if it's present otherwise returns +nil+.
+  # <tt>object.presence</tt> is equivalent to
+  #
+  #    object.present? ? object : nil
+  #
+  # For example, something like
+  #
+  #   state   = params[:state]   if params[:state].present?
+  #   country = params[:country] if params[:country].present?
+  #   region  = state || country || 'US'
+  #
+  # becomes
+  #
+  #   region = params[:state].presence || params[:country].presence || 'US'
+  #
+  # @return [Object]
+  def presence
+    self if present?
+  end
+end
+
+class NilClass
+  # +nil+ is blank:
+  #
+  #   nil.blank? # => true
+  #
+  # @return [true]
+  def blank?
+    true
+  end
+end
+
+class FalseClass
+  # +false+ is blank:
+  #
+  #   false.blank? # => true
+  #
+  # @return [true]
+  def blank?
+    true
+  end
+end
+
+class TrueClass
+  # +true+ is not blank:
+  #
+  #   true.blank? # => false
+  #
+  # @return [false]
+  def blank?
+    false
+  end
+end
+
+class Array
+  # An array is blank if it's empty:
+  #
+  #   [].blank?      # => true
+  #   [1,2,3].blank? # => false
+  #
+  # @return [true, false]
+  alias_method :blank?, :empty?
+end
+
+class Hash
+  # A hash is blank if it's empty:
+  #
+  #   {}.blank?                # => true
+  #   { key: 'value' }.blank?  # => false
+  #
+  # @return [true, false]
+  alias_method :blank?, :empty?
+end
+
+class String
+  BLANK_RE = /\A[[:space:]]*\z/
+
+  # A string is blank if it's empty or contains whitespaces only:
+  #
+  #   ''.blank?       # => true
+  #   '   '.blank?    # => true
+  #   "\t\n\r".blank? # => true
+  #   ' blah '.blank? # => false
+  #
+  # Unicode whitespace is supported:
+  #
+  #   "\u00a0".blank? # => true
+  #
+  # @return [true, false]
+  def blank?
+    BLANK_RE === self
+  end
+end
+
+class Numeric #:nodoc:
+  # No number is blank:
+  #
+  #   1.blank? # => false
+  #   0.blank? # => false
+  #
+  # @return [false]
+  def blank?
+    false
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/object/conversions.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/object/conversions.rb
new file mode 100644
index 0000000..540f7aa
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/object/conversions.rb
@@ -0,0 +1,4 @@
+require 'active_support/core_ext/object/to_param'
+require 'active_support/core_ext/object/to_query'
+require 'active_support/core_ext/array/conversions'
+require 'active_support/core_ext/hash/conversions'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/object/deep_dup.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/object/deep_dup.rb
new file mode 100644
index 0000000..2e99f4a
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/object/deep_dup.rb
@@ -0,0 +1,46 @@
+require 'active_support/core_ext/object/duplicable'
+
+class Object
+  # Returns a deep copy of object if it's duplicable. If it's
+  # not duplicable, returns +self+.
+  #
+  #   object = Object.new
+  #   dup    = object.deep_dup
+  #   dup.instance_variable_set(:@a, 1)
+  #
+  #   object.instance_variable_defined?(:@a) # => false
+  #   dup.instance_variable_defined?(:@a)    # => true
+  def deep_dup
+    duplicable? ? dup : self
+  end
+end
+
+class Array
+  # Returns a deep copy of array.
+  #
+  #   array = [1, [2, 3]]
+  #   dup   = array.deep_dup
+  #   dup[1][2] = 4
+  #
+  #   array[1][2] # => nil
+  #   dup[1][2]   # => 4
+  def deep_dup
+    map { |it| it.deep_dup }
+  end
+end
+
+class Hash
+  # Returns a deep copy of hash.
+  #
+  #   hash = { a: { b: 'b' } }
+  #   dup  = hash.deep_dup
+  #   dup[:a][:c] = 'c'
+  #
+  #   hash[:a][:c] # => nil
+  #   dup[:a][:c]  # => "c"
+  def deep_dup
+    each_with_object(dup) do |(key, value), hash|
+      hash[key.deep_dup] = value.deep_dup
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/object/duplicable.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/object/duplicable.rb
new file mode 100644
index 0000000..9cd7485
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/object/duplicable.rb
@@ -0,0 +1,90 @@
+#--
+# Most objects are cloneable, but not all. For example you can't dup +nil+:
+#
+#   nil.dup # => TypeError: can't dup NilClass
+#
+# Classes may signal their instances are not duplicable removing +dup+/+clone+
+# or raising exceptions from them. So, to dup an arbitrary object you normally
+# use an optimistic approach and are ready to catch an exception, say:
+#
+#   arbitrary_object.dup rescue object
+#
+# Rails dups objects in a few critical spots where they are not that arbitrary.
+# That rescue is very expensive (like 40 times slower than a predicate), and it
+# is often triggered.
+#
+# That's why we hardcode the following cases and check duplicable? instead of
+# using that rescue idiom.
+#++
+class Object
+  # Can you safely dup this object?
+  #
+  # False for +nil+, +false+, +true+, symbol, and number objects;
+  # true otherwise.
+  def duplicable?
+    true
+  end
+end
+
+class NilClass
+  # +nil+ is not duplicable:
+  #
+  #   nil.duplicable? # => false
+  #   nil.dup         # => TypeError: can't dup NilClass
+  def duplicable?
+    false
+  end
+end
+
+class FalseClass
+  # +false+ is not duplicable:
+  #
+  #   false.duplicable? # => false
+  #   false.dup         # => TypeError: can't dup FalseClass
+  def duplicable?
+    false
+  end
+end
+
+class TrueClass
+  # +true+ is not duplicable:
+  #
+  #   true.duplicable? # => false
+  #   true.dup         # => TypeError: can't dup TrueClass
+  def duplicable?
+    false
+  end
+end
+
+class Symbol
+  # Symbols are not duplicable:
+  #
+  #   :my_symbol.duplicable? # => false
+  #   :my_symbol.dup         # => TypeError: can't dup Symbol
+  def duplicable?
+    false
+  end
+end
+
+class Numeric
+  # Numbers are not duplicable:
+  #
+  #  3.duplicable? # => false
+  #  3.dup         # => TypeError: can't dup Fixnum
+  def duplicable?
+    false
+  end
+end
+
+require 'bigdecimal'
+class BigDecimal
+  begin
+    BigDecimal.new('4.56').dup
+
+    def duplicable?
+      true
+    end
+  rescue TypeError
+    # can't dup, so use superclass implementation
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/object/inclusion.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/object/inclusion.rb
new file mode 100644
index 0000000..55f281b
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/object/inclusion.rb
@@ -0,0 +1,27 @@
+class Object
+  # Returns true if this object is included in the argument. Argument must be
+  # any object which responds to +#include?+. Usage:
+  #
+  #   characters = ["Konata", "Kagami", "Tsukasa"]
+  #   "Konata".in?(characters) # => true
+  #
+  # This will throw an ArgumentError if the argument doesn't respond
+  # to +#include?+.
+  def in?(another_object)
+    another_object.include?(self)
+  rescue NoMethodError
+    raise ArgumentError.new("The parameter passed to #in? must respond to #include?")
+  end
+
+  # Returns the receiver if it's included in the argument otherwise returns +nil+.
+  # Argument must be any object which responds to +#include?+. Usage:
+  #
+  #   params[:bucket_type].presence_in %w( project calendar )
+  #
+  # This will throw an ArgumentError if the argument doesn't respond to +#include?+.
+  #
+  # @return [Object]
+  def presence_in(another_object)
+    self.in?(another_object) ? self : nil
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/object/instance_variables.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/object/instance_variables.rb
new file mode 100644
index 0000000..755e1c6
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/object/instance_variables.rb
@@ -0,0 +1,28 @@
+class Object
+  # Returns a hash with string keys that maps instance variable names without "@" to their
+  # corresponding values.
+  #
+  #   class C
+  #     def initialize(x, y)
+  #       @x, @y = x, y
+  #     end
+  #   end
+  #
+  #   C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
+  def instance_values
+    Hash[instance_variables.map { |name| [name[1..-1], instance_variable_get(name)] }]
+  end
+
+  # Returns an array of instance variable names as strings including "@".
+  #
+  #   class C
+  #     def initialize(x, y)
+  #       @x, @y = x, y
+  #     end
+  #   end
+  #
+  #   C.new(0, 1).instance_variable_names # => ["@y", "@x"]
+  def instance_variable_names
+    instance_variables.map { |var| var.to_s }
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/object/json.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/object/json.rb
new file mode 100644
index 0000000..5496692
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/object/json.rb
@@ -0,0 +1,197 @@
+# Hack to load json gem first so we can overwrite its to_json.
+require 'json'
+require 'bigdecimal'
+require 'active_support/core_ext/big_decimal/conversions' # for #to_s
+require 'active_support/core_ext/hash/except'
+require 'active_support/core_ext/hash/slice'
+require 'active_support/core_ext/object/instance_variables'
+require 'time'
+require 'active_support/core_ext/time/conversions'
+require 'active_support/core_ext/date_time/conversions'
+require 'active_support/core_ext/date/conversions'
+require 'active_support/core_ext/module/aliasing'
+
+# The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
+# their default behavior. That said, we need to define the basic to_json method in all of them,
+# otherwise they will always use to_json gem implementation, which is backwards incompatible in
+# several cases (for instance, the JSON implementation for Hash does not work) with inheritance
+# and consequently classes as ActiveSupport::OrderedHash cannot be serialized to json.
+#
+# On the other hand, we should avoid conflict with ::JSON.{generate,dump}(obj). Unfortunately, the
+# JSON gem's encoder relies on its own to_json implementation to encode objects. Since it always
+# passes a ::JSON::State object as the only argument to to_json, we can detect that and forward the
+# calls to the original to_json method.
+#
+# It should be noted that when using ::JSON.{generate,dump} directly, ActiveSupport's encoder is
+# bypassed completely. This means that as_json won't be invoked and the JSON gem will simply
+# ignore any options it does not natively understand. This also means that ::JSON.{generate,dump}
+# should give exactly the same results with or without active support.
+[Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass, Enumerable].each do |klass|
+  klass.class_eval do
+    def to_json_with_active_support_encoder(options = nil)
+      if options.is_a?(::JSON::State)
+        # Called from JSON.{generate,dump}, forward it to JSON gem's to_json
+        self.to_json_without_active_support_encoder(options)
+      else
+        # to_json is being invoked directly, use ActiveSupport's encoder
+        ActiveSupport::JSON.encode(self, options)
+      end
+    end
+
+    alias_method_chain :to_json, :active_support_encoder
+  end
+end
+
+class Object
+  def as_json(options = nil) #:nodoc:
+    if respond_to?(:to_hash)
+      to_hash.as_json(options)
+    else
+      instance_values.as_json(options)
+    end
+  end
+end
+
+class Struct #:nodoc:
+  def as_json(options = nil)
+    Hash[members.zip(values)].as_json(options)
+  end
+end
+
+class TrueClass
+  def as_json(options = nil) #:nodoc:
+    self
+  end
+end
+
+class FalseClass
+  def as_json(options = nil) #:nodoc:
+    self
+  end
+end
+
+class NilClass
+  def as_json(options = nil) #:nodoc:
+    self
+  end
+end
+
+class String
+  def as_json(options = nil) #:nodoc:
+    self
+  end
+end
+
+class Symbol
+  def as_json(options = nil) #:nodoc:
+    to_s
+  end
+end
+
+class Numeric
+  def as_json(options = nil) #:nodoc:
+    self
+  end
+end
+
+class Float
+  # Encoding Infinity or NaN to JSON should return "null". The default returns
+  # "Infinity" or "NaN" which are not valid JSON.
+  def as_json(options = nil) #:nodoc:
+    finite? ? self : nil
+  end
+end
+
+class BigDecimal
+  # A BigDecimal would be naturally represented as a JSON number. Most libraries,
+  # however, parse non-integer JSON numbers directly as floats. Clients using
+  # those libraries would get in general a wrong number and no way to recover
+  # other than manually inspecting the string with the JSON code itself.
+  #
+  # That's why a JSON string is returned. The JSON literal is not numeric, but
+  # if the other end knows by contract that the data is supposed to be a
+  # BigDecimal, it still has the chance to post-process the string and get the
+  # real value.
+  def as_json(options = nil) #:nodoc:
+    finite? ? to_s : nil
+  end
+end
+
+class Regexp
+  def as_json(options = nil) #:nodoc:
+    to_s
+  end
+end
+
+module Enumerable
+  def as_json(options = nil) #:nodoc:
+    to_a.as_json(options)
+  end
+end
+
+class Range
+  def as_json(options = nil) #:nodoc:
+    to_s
+  end
+end
+
+class Array
+  def as_json(options = nil) #:nodoc:
+    map { |v| options ? v.as_json(options.dup) : v.as_json }
+  end
+end
+
+class Hash
+  def as_json(options = nil) #:nodoc:
+    # create a subset of the hash by applying :only or :except
+    subset = if options
+      if attrs = options[:only]
+        slice(*Array(attrs))
+      elsif attrs = options[:except]
+        except(*Array(attrs))
+      else
+        self
+      end
+    else
+      self
+    end
+
+    Hash[subset.map { |k, v| [k.to_s, options ? v.as_json(options.dup) : v.as_json] }]
+  end
+end
+
+class Time
+  def as_json(options = nil) #:nodoc:
+    if ActiveSupport.use_standard_json_time_format
+      xmlschema(ActiveSupport::JSON::Encoding.time_precision)
+    else
+      %(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
+    end
+  end
+end
+
+class Date
+  def as_json(options = nil) #:nodoc:
+    if ActiveSupport.use_standard_json_time_format
+      strftime("%Y-%m-%d")
+    else
+      strftime("%Y/%m/%d")
+    end
+  end
+end
+
+class DateTime
+  def as_json(options = nil) #:nodoc:
+    if ActiveSupport.use_standard_json_time_format
+      xmlschema(ActiveSupport::JSON::Encoding.time_precision)
+    else
+      strftime('%Y/%m/%d %H:%M:%S %z')
+    end
+  end
+end
+
+class Process::Status #:nodoc:
+  def as_json(options = nil)
+    { :exitstatus => exitstatus, :pid => pid }
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/object/to_json.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/object/to_json.rb
new file mode 100644
index 0000000..f58364f
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/object/to_json.rb
@@ -0,0 +1,5 @@
+ActiveSupport::Deprecation.warn 'You have required `active_support/core_ext/object/to_json`. ' \
+  'This file will be removed in Rails 4.2. You should require `active_support/core_ext/object/json` ' \
+  'instead.'
+
+require 'active_support/core_ext/object/json'
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/object/to_param.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/object/to_param.rb
new file mode 100644
index 0000000..13be003
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/object/to_param.rb
@@ -0,0 +1,62 @@
+class Object
+  # Alias of <tt>to_s</tt>.
+  def to_param
+    to_s
+  end
+end
+
+class NilClass
+  # Returns +self+.
+  def to_param
+    self
+  end
+end
+
+class TrueClass
+  # Returns +self+.
+  def to_param
+    self
+  end
+end
+
+class FalseClass
+  # Returns +self+.
+  def to_param
+    self
+  end
+end
+
+class Array
+  # Calls <tt>to_param</tt> on all its elements and joins the result with
+  # slashes. This is used by <tt>url_for</tt> in Action Pack.
+  def to_param
+    collect { |e| e.to_param }.join '/'
+  end
+end
+
+class Hash
+  # Returns a string representation of the receiver suitable for use as a URL
+  # query string:
+  #
+  #   {name: 'David', nationality: 'Danish'}.to_param
+  #   # => "name=David&nationality=Danish"
+  #
+  # An optional namespace can be passed to enclose the param names:
+  #
+  #   {name: 'David', nationality: 'Danish'}.to_param('user')
+  #   # => "user[name]=David&user[nationality]=Danish"
+  #
+  # The string pairs "key=value" that conform the query string
+  # are sorted lexicographically in ascending order.
+  #
+  # This method is also aliased as +to_query+.
+  def to_param(namespace = nil)
+    if empty?
+      namespace ? nil.to_query(namespace) : ''
+    else
+      collect do |key, value|
+        value.to_query(namespace ? "#{namespace}[#{key}]" : key)
+      end.sort! * '&'
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/object/to_query.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/object/to_query.rb
new file mode 100644
index 0000000..37352fa
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/object/to_query.rb
@@ -0,0 +1,32 @@
+require 'active_support/core_ext/object/to_param'
+
+class Object
+  # Converts an object into a string suitable for use as a URL query string, using the given <tt>key</tt> as the
+  # param name.
+  #
+  # Note: This method is defined as a default implementation for all Objects for Hash#to_query to work.
+  def to_query(key)
+    require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
+    "#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
+  end
+end
+
+class Array
+  # Converts an array into a string suitable for use as a URL query string,
+  # using the given +key+ as the param name.
+  #
+  #   ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
+  def to_query(key)
+    prefix = "#{key}[]"
+
+    if empty?
+      nil.to_query(prefix)
+    else
+      collect { |value| value.to_query(prefix) }.join '&'
+    end
+  end
+end
+
+class Hash
+  alias_method :to_query, :to_param
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/object/try.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/object/try.rb
new file mode 100644
index 0000000..48190e1
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/object/try.rb
@@ -0,0 +1,78 @@
+class Object
+  # Invokes the public method whose name goes as first argument just like
+  # +public_send+ does, except that if the receiver does not respond to it the
+  # call returns +nil+ rather than raising an exception.
+  #
+  # This method is defined to be able to write
+  #
+  #   @person.try(:name)
+  #
+  # instead of
+  #
+  #   @person ? @person.name : nil
+  #
+  # +try+ returns +nil+ when called on +nil+ regardless of whether it responds
+  # to the method:
+  #
+  #   nil.try(:to_i) # => nil, rather than 0
+  #
+  # Arguments and blocks are forwarded to the method if invoked:
+  #
+  #   @posts.try(:each_slice, 2) do |a, b|
+  #     ...
+  #   end
+  #
+  # The number of arguments in the signature must match. If the object responds
+  # to the method the call is attempted and +ArgumentError+ is still raised
+  # otherwise.
+  #
+  # If +try+ is called without arguments it yields the receiver to a given
+  # block unless it is +nil+:
+  #
+  #   @person.try do |p|
+  #     ...
+  #   end
+  #
+  # Please also note that +try+ is defined on +Object+, therefore it won't work
+  # with instances of classes that do not have +Object+ among their ancestors,
+  # like direct subclasses of +BasicObject+. For example, using +try+ with
+  # +SimpleDelegator+ will delegate +try+ to the target instead of calling it on
+  # delegator itself.
+  def try(*a, &b)
+    if a.empty? && block_given?
+      yield self
+    else
+      public_send(*a, &b) if respond_to?(a.first)
+    end
+  end
+
+  # Same as #try, but will raise a NoMethodError exception if the receiving is not nil and
+  # does not implement the tried method.
+  def try!(*a, &b)
+    if a.empty? && block_given?
+      yield self
+    else
+      public_send(*a, &b)
+    end
+  end
+end
+
+class NilClass
+  # Calling +try+ on +nil+ always returns +nil+.
+  # It becomes specially helpful when navigating through associations that may return +nil+.
+  #
+  #   nil.try(:name) # => nil
+  #
+  # Without +try+
+  #   @person && !@person.children.blank? && @person.children.first.name
+  #
+  # With +try+
+  #   @person.try(:children).try(:first).try(:name)
+  def try(*args)
+    nil
+  end
+
+  def try!(*args)
+    nil
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/object/with_options.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/object/with_options.rb
new file mode 100644
index 0000000..42e388b
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/object/with_options.rb
@@ -0,0 +1,42 @@
+require 'active_support/option_merger'
+
+class Object
+  # An elegant way to factor duplication out of options passed to a series of
+  # method calls. Each method called in the block, with the block variable as
+  # the receiver, will have its options merged with the default +options+ hash
+  # provided. Each method called on the block variable must take an options
+  # hash as its final argument.
+  #
+  # Without <tt>with_options></tt>, this code contains duplication:
+  #
+  #   class Account < ActiveRecord::Base
+  #     has_many :customers, dependent: :destroy
+  #     has_many :products,  dependent: :destroy
+  #     has_many :invoices,  dependent: :destroy
+  #     has_many :expenses,  dependent: :destroy
+  #   end
+  #
+  # Using <tt>with_options</tt>, we can remove the duplication:
+  #
+  #   class Account < ActiveRecord::Base
+  #     with_options dependent: :destroy do |assoc|
+  #       assoc.has_many :customers
+  #       assoc.has_many :products
+  #       assoc.has_many :invoices
+  #       assoc.has_many :expenses
+  #     end
+  #   end
+  #
+  # It can also be used with an explicit receiver:
+  #
+  #   I18n.with_options locale: user.locale, scope: 'newsletter' do |i18n|
+  #     subject i18n.t :subject
+  #     body    i18n.t :body, user_name: user.name
+  #   end
+  #
+  # <tt>with_options</tt> can also be nested since the call is forwarded to its receiver.
+  # Each nesting level will merge inherited defaults in addition to their own.
+  def with_options(options)
+    yield ActiveSupport::OptionMerger.new(self, options)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/range.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/range.rb
new file mode 100644
index 0000000..9368e81
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/range.rb
@@ -0,0 +1,4 @@
+require 'active_support/core_ext/range/conversions'
+require 'active_support/core_ext/range/include_range'
+require 'active_support/core_ext/range/overlaps'
+require 'active_support/core_ext/range/each'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/range/conversions.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/range/conversions.rb
new file mode 100644
index 0000000..b1a1278
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/range/conversions.rb
@@ -0,0 +1,19 @@
+class Range
+  RANGE_FORMATS = {
+    :db => Proc.new { |start, stop| "BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'" }
+  }
+
+  # Gives a human readable format of the range.
+  #
+  #   (1..100).to_formatted_s # => "1..100"
+  def to_formatted_s(format = :default)
+    if formatter = RANGE_FORMATS[format]
+      formatter.call(first, last)
+    else
+      to_default_s
+    end
+  end
+
+  alias_method :to_default_s, :to_s
+  alias_method :to_s, :to_formatted_s
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/range/each.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/range/each.rb
new file mode 100644
index 0000000..ecef78f
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/range/each.rb
@@ -0,0 +1,23 @@
+require 'active_support/core_ext/module/aliasing'
+
+class Range #:nodoc:
+
+  def each_with_time_with_zone(&block)
+    ensure_iteration_allowed
+    each_without_time_with_zone(&block)
+  end
+  alias_method_chain :each, :time_with_zone
+
+  def step_with_time_with_zone(n = 1, &block)
+    ensure_iteration_allowed
+    step_without_time_with_zone(n, &block)
+  end
+  alias_method_chain :step, :time_with_zone
+
+  private
+  def ensure_iteration_allowed
+    if first.is_a?(Time)
+      raise TypeError, "can't iterate from #{first.class}"
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/range/include_range.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/range/include_range.rb
new file mode 100644
index 0000000..3a07401
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/range/include_range.rb
@@ -0,0 +1,23 @@
+require 'active_support/core_ext/module/aliasing'
+
+class Range
+  # Extends the default Range#include? to support range comparisons.
+  #  (1..5).include?(1..5) # => true
+  #  (1..5).include?(2..3) # => true
+  #  (1..5).include?(2..6) # => false
+  #
+  # The native Range#include? behavior is untouched.
+  #  ('a'..'f').include?('c') # => true
+  #  (5..9).include?(11) # => false
+  def include_with_range?(value)
+    if value.is_a?(::Range)
+      # 1...10 includes 1..9 but it does not include 1..10.
+      operator = exclude_end? && !value.exclude_end? ? :< : :<=
+      include_without_range?(value.first) && value.last.send(operator, last)
+    else
+      include_without_range?(value)
+    end
+  end
+
+  alias_method_chain :include?, :range
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/range/overlaps.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/range/overlaps.rb
new file mode 100644
index 0000000..603657c
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/range/overlaps.rb
@@ -0,0 +1,8 @@
+class Range
+  # Compare two ranges and see if they overlap each other
+  #  (1..5).overlaps?(4..6) # => true
+  #  (1..5).overlaps?(7..9) # => false
+  def overlaps?(other)
+    cover?(other.first) || other.cover?(first)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/regexp.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/regexp.rb
new file mode 100644
index 0000000..784145f
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/regexp.rb
@@ -0,0 +1,5 @@
+class Regexp #:nodoc:
+  def multiline?
+    options & MULTILINE == MULTILINE
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/string.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/string.rb
new file mode 100644
index 0000000..c656db2
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/string.rb
@@ -0,0 +1,13 @@
+require 'active_support/core_ext/string/conversions'
+require 'active_support/core_ext/string/filters'
+require 'active_support/core_ext/string/multibyte'
+require 'active_support/core_ext/string/starts_ends_with'
+require 'active_support/core_ext/string/inflections'
+require 'active_support/core_ext/string/access'
+require 'active_support/core_ext/string/behavior'
+require 'active_support/core_ext/string/output_safety'
+require 'active_support/core_ext/string/exclude'
+require 'active_support/core_ext/string/strip'
+require 'active_support/core_ext/string/inquiry'
+require 'active_support/core_ext/string/indent'
+require 'active_support/core_ext/string/zones'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/string/access.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/string/access.rb
new file mode 100644
index 0000000..6018fd9
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/string/access.rb
@@ -0,0 +1,104 @@
+class String
+  # If you pass a single Fixnum, returns a substring of one character at that
+  # position. The first character of the string is at position 0, the next at
+  # position 1, and so on. If a range is supplied, a substring containing
+  # characters at offsets given by the range is returned. In both cases, if an
+  # offset is negative, it is counted from the end of the string. Returns nil
+  # if the initial offset falls outside the string. Returns an empty string if
+  # the beginning of the range is greater than the end of the string.
+  #
+  #   str = "hello"
+  #   str.at(0)      # => "h"
+  #   str.at(1..3)   # => "ell"
+  #   str.at(-2)     # => "l"
+  #   str.at(-2..-1) # => "lo"
+  #   str.at(5)      # => nil
+  #   str.at(5..-1)  # => ""
+  #
+  # If a Regexp is given, the matching portion of the string is returned.
+  # If a String is given, that given string is returned if it occurs in
+  # the string. In both cases, nil is returned if there is no match.
+  #
+  #   str = "hello"
+  #   str.at(/lo/) # => "lo"
+  #   str.at(/ol/) # => nil
+  #   str.at("lo") # => "lo"
+  #   str.at("ol") # => nil
+  def at(position)
+    self[position]
+  end
+
+  # Returns a substring from the given position to the end of the string.
+  # If the position is negative, it is counted from the end of the string.
+  #
+  #   str = "hello"
+  #   str.from(0)  # => "hello"
+  #   str.from(3)  # => "lo"
+  #   str.from(-2) # => "lo"
+  #
+  # You can mix it with +to+ method and do fun things like:
+  #
+  #   str = "hello"
+  #   str.from(0).to(-1) # => "hello"
+  #   str.from(1).to(-2) # => "ell"
+  def from(position)
+    self[position..-1]
+  end
+
+  # Returns a substring from the beginning of the string to the given position.
+  # If the position is negative, it is counted from the end of the string.
+  #
+  #   str = "hello"
+  #   str.to(0)  # => "h"
+  #   str.to(3)  # => "hell"
+  #   str.to(-2) # => "hell"
+  #
+  # You can mix it with +from+ method and do fun things like:
+  #
+  #   str = "hello"
+  #   str.from(0).to(-1) # => "hello"
+  #   str.from(1).to(-2) # => "ell"
+  def to(position)
+    self[0..position]
+  end
+
+  # Returns the first character. If a limit is supplied, returns a substring
+  # from the beginning of the string until it reaches the limit value. If the
+  # given limit is greater than or equal to the string length, returns self.
+  #
+  #   str = "hello"
+  #   str.first    # => "h"
+  #   str.first(1) # => "h"
+  #   str.first(2) # => "he"
+  #   str.first(0) # => ""
+  #   str.first(6) # => "hello"
+  def first(limit = 1)
+    if limit == 0
+      ''
+    elsif limit >= size
+      self
+    else
+      to(limit - 1)
+    end
+  end
+
+  # Returns the last character of the string. If a limit is supplied, returns a substring
+  # from the end of the string until it reaches the limit value (counting backwards). If
+  # the given limit is greater than or equal to the string length, returns self.
+  #
+  #   str = "hello"
+  #   str.last    # => "o"
+  #   str.last(1) # => "o"
+  #   str.last(2) # => "lo"
+  #   str.last(0) # => ""
+  #   str.last(6) # => "hello"
+  def last(limit = 1)
+    if limit == 0
+      ''
+    elsif limit >= size
+      self
+    else
+      from(-limit)
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/string/behavior.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/string/behavior.rb
new file mode 100644
index 0000000..4aa9600
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/string/behavior.rb
@@ -0,0 +1,6 @@
+class String
+  # Enable more predictable duck-typing on String-like classes. See <tt>Object#acts_like?</tt>.
+  def acts_like_string?
+    true
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/string/conversions.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/string/conversions.rb
new file mode 100644
index 0000000..3e0cb8a
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/string/conversions.rb
@@ -0,0 +1,56 @@
+require 'date'
+require 'active_support/core_ext/time/calculations'
+
+class String
+  # Converts a string to a Time value.
+  # The +form+ can be either :utc or :local (default :local).
+  #
+  # The time is parsed using Time.parse method.
+  # If +form+ is :local, then the time is in the system timezone.
+  # If the date part is missing then the current date is used and if
+  # the time part is missing then it is assumed to be 00:00:00.
+  #
+  #   "13-12-2012".to_time               # => 2012-12-13 00:00:00 +0100
+  #   "06:12".to_time                    # => 2012-12-13 06:12:00 +0100
+  #   "2012-12-13 06:12".to_time         # => 2012-12-13 06:12:00 +0100
+  #   "2012-12-13T06:12".to_time         # => 2012-12-13 06:12:00 +0100
+  #   "2012-12-13T06:12".to_time(:utc)   # => 2012-12-13 05:12:00 UTC
+  #   "12/13/2012".to_time               # => ArgumentError: argument out of range
+  def to_time(form = :local)
+    parts = Date._parse(self, false)
+    return if parts.empty?
+
+    now = Time.now
+    time = Time.new(
+      parts.fetch(:year, now.year),
+      parts.fetch(:mon, now.month),
+      parts.fetch(:mday, now.day),
+      parts.fetch(:hour, 0),
+      parts.fetch(:min, 0),
+      parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
+      parts.fetch(:offset, form == :utc ? 0 : nil)
+    )
+
+    form == :utc ? time.utc : time.getlocal
+  end
+
+  # Converts a string to a Date value.
+  #
+  #   "1-1-2012".to_date   # => Sun, 01 Jan 2012
+  #   "01/01/2012".to_date # => Sun, 01 Jan 2012
+  #   "2012-12-13".to_date # => Thu, 13 Dec 2012
+  #   "12/13/2012".to_date # => ArgumentError: invalid date
+  def to_date
+    ::Date.parse(self, false) unless blank?
+  end
+
+  # Converts a string to a DateTime value.
+  #
+  #   "1-1-2012".to_datetime            # => Sun, 01 Jan 2012 00:00:00 +0000
+  #   "01/01/2012 23:59:59".to_datetime # => Sun, 01 Jan 2012 23:59:59 +0000
+  #   "2012-12-13 12:50".to_datetime    # => Thu, 13 Dec 2012 12:50:00 +0000
+  #   "12/13/2012".to_datetime          # => ArgumentError: invalid date
+  def to_datetime
+    ::DateTime.parse(self, false) unless blank?
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/string/exclude.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/string/exclude.rb
new file mode 100644
index 0000000..0ac684f
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/string/exclude.rb
@@ -0,0 +1,11 @@
+class String
+  # The inverse of <tt>String#include?</tt>. Returns true if the string
+  # does not include the other string.
+  #
+  #   "hello".exclude? "lo" # => false
+  #   "hello".exclude? "ol" # => true
+  #   "hello".exclude? ?h   # => false
+  def exclude?(string)
+    !include?(string)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/string/filters.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/string/filters.rb
new file mode 100644
index 0000000..49c0df6
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/string/filters.rb
@@ -0,0 +1,65 @@
+class String
+  # Returns the string, first removing all whitespace on both ends of
+  # the string, and then changing remaining consecutive whitespace
+  # groups into one space each.
+  #
+  # Note that it handles both ASCII and Unicode whitespace like mongolian vowel separator (U+180E).
+  #
+  #   %{ Multi-line
+  #      string }.squish                   # => "Multi-line string"
+  #   " foo   bar    \n   \t   boo".squish # => "foo bar boo"
+  def squish
+    dup.squish!
+  end
+
+  # Performs a destructive squish. See String#squish.
+  def squish!
+    gsub!(/\A[[:space:]]+/, '')
+    gsub!(/[[:space:]]+\z/, '')
+    gsub!(/[[:space:]]+/, ' ')
+    self
+  end
+
+  # Returns a new string with all occurrences of the pattern removed. Short-hand for String#gsub(pattern, '').
+  def remove(pattern)
+    gsub pattern, ''
+  end
+
+  # Alters the string by removing all occurrences of the pattern. Short-hand for String#gsub!(pattern, '').
+  def remove!(pattern)
+    gsub! pattern, ''
+  end
+
+  # Truncates a given +text+ after a given <tt>length</tt> if +text+ is longer than <tt>length</tt>:
+  #
+  #   'Once upon a time in a world far far away'.truncate(27)
+  #   # => "Once upon a time in a wo..."
+  #
+  # Pass a string or regexp <tt>:separator</tt> to truncate +text+ at a natural break:
+  #
+  #   'Once upon a time in a world far far away'.truncate(27, separator: ' ')
+  #   # => "Once upon a time in a..."
+  #
+  #   'Once upon a time in a world far far away'.truncate(27, separator: /\s/)
+  #   # => "Once upon a time in a..."
+  #
+  # The last characters will be replaced with the <tt>:omission</tt> string (defaults to "...")
+  # for a total length not exceeding <tt>length</tt>:
+  #
+  #   'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)')
+  #   # => "And they f... (continued)"
+  def truncate(truncate_at, options = {})
+    return dup unless length > truncate_at
+
+    omission = options[:omission] || '...'
+    length_with_room_for_omission = truncate_at - omission.length
+    stop = \
+      if options[:separator]
+        rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
+      else
+        length_with_room_for_omission
+      end
+
+    "#{self[0, stop]}#{omission}"
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/string/indent.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/string/indent.rb
new file mode 100644
index 0000000..ce3a69c
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/string/indent.rb
@@ -0,0 +1,43 @@
+class String
+  # Same as +indent+, except it indents the receiver in-place.
+  #
+  # Returns the indented string, or +nil+ if there was nothing to indent.
+  def indent!(amount, indent_string=nil, indent_empty_lines=false)
+    indent_string = indent_string || self[/^[ \t]/] || ' '
+    re = indent_empty_lines ? /^/ : /^(?!$)/
+    gsub!(re, indent_string * amount)
+  end
+
+  # Indents the lines in the receiver:
+  #
+  #   <<EOS.indent(2)
+  #   def some_method
+  #     some_code
+  #   end
+  #   EOS
+  #   # =>
+  #     def some_method
+  #       some_code
+  #     end
+  #
+  # The second argument, +indent_string+, specifies which indent string to
+  # use. The default is +nil+, which tells the method to make a guess by
+  # peeking at the first indented line, and fallback to a space if there is
+  # none.
+  #
+  #   "  foo".indent(2)        # => "    foo"
+  #   "foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar"
+  #   "foo".indent(2, "\t")    # => "\t\tfoo"
+  #
+  # While +indent_string+ is typically one space or tab, it may be any string.
+  #
+  # The third argument, +indent_empty_lines+, is a flag that says whether
+  # empty lines should be indented. Default is false.
+  #
+  #   "foo\n\nbar".indent(2)            # => "  foo\n\n  bar"
+  #   "foo\n\nbar".indent(2, nil, true) # => "  foo\n  \n  bar"
+  #
+  def indent(amount, indent_string=nil, indent_empty_lines=false)
+    dup.tap {|_| _.indent!(amount, indent_string, indent_empty_lines)}
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/string/inflections.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/string/inflections.rb
new file mode 100644
index 0000000..cf9b1a4
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/string/inflections.rb
@@ -0,0 +1,214 @@
+require 'active_support/inflector/methods'
+require 'active_support/inflector/transliterate'
+
+# String inflections define new methods on the String class to transform names for different purposes.
+# For instance, you can figure out the name of a table from the name of a class.
+#
+#   'ScaleScore'.tableize # => "scale_scores"
+#
+class String
+  # Returns the plural form of the word in the string.
+  #
+  # If the optional parameter +count+ is specified,
+  # the singular form will be returned if <tt>count == 1</tt>.
+  # For any other value of +count+ the plural will be returned.
+  #
+  # If the optional parameter +locale+ is specified,
+  # the word will be pluralized as a word of that language.
+  # By default, this parameter is set to <tt>:en</tt>.
+  # You must define your own inflection rules for languages other than English.
+  #
+  #   'post'.pluralize             # => "posts"
+  #   'octopus'.pluralize          # => "octopi"
+  #   'sheep'.pluralize            # => "sheep"
+  #   'words'.pluralize            # => "words"
+  #   'the blue mailman'.pluralize # => "the blue mailmen"
+  #   'CamelOctopus'.pluralize     # => "CamelOctopi"
+  #   'apple'.pluralize(1)         # => "apple"
+  #   'apple'.pluralize(2)         # => "apples"
+  #   'ley'.pluralize(:es)         # => "leyes"
+  #   'ley'.pluralize(1, :es)      # => "ley"
+  def pluralize(count = nil, locale = :en)
+    locale = count if count.is_a?(Symbol)
+    if count == 1
+      self
+    else
+      ActiveSupport::Inflector.pluralize(self, locale)
+    end
+  end
+
+  # The reverse of +pluralize+, returns the singular form of a word in a string.
+  #
+  # If the optional parameter +locale+ is specified,
+  # the word will be singularized as a word of that language.
+  # By default, this parameter is set to <tt>:en</tt>.
+  # You must define your own inflection rules for languages other than English.
+  #
+  #   'posts'.singularize            # => "post"
+  #   'octopi'.singularize           # => "octopus"
+  #   'sheep'.singularize            # => "sheep"
+  #   'word'.singularize             # => "word"
+  #   'the blue mailmen'.singularize # => "the blue mailman"
+  #   'CamelOctopi'.singularize      # => "CamelOctopus"
+  #   'leyes'.singularize(:es)       # => "ley"
+  def singularize(locale = :en)
+    ActiveSupport::Inflector.singularize(self, locale)
+  end
+
+  # +constantize+ tries to find a declared constant with the name specified
+  # in the string. It raises a NameError when the name is not in CamelCase
+  # or is not initialized.  See ActiveSupport::Inflector.constantize
+  #
+  #   'Module'.constantize  # => Module
+  #   'Class'.constantize   # => Class
+  #   'blargle'.constantize # => NameError: wrong constant name blargle
+  def constantize
+    ActiveSupport::Inflector.constantize(self)
+  end
+
+  # +safe_constantize+ tries to find a declared constant with the name specified
+  # in the string. It returns nil when the name is not in CamelCase
+  # or is not initialized.  See ActiveSupport::Inflector.safe_constantize
+  #
+  #   'Module'.safe_constantize  # => Module
+  #   'Class'.safe_constantize   # => Class
+  #   'blargle'.safe_constantize # => nil
+  def safe_constantize
+    ActiveSupport::Inflector.safe_constantize(self)
+  end
+
+  # By default, +camelize+ converts strings to UpperCamelCase. If the argument to camelize
+  # is set to <tt>:lower</tt> then camelize produces lowerCamelCase.
+  #
+  # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
+  #
+  #   'active_record'.camelize                # => "ActiveRecord"
+  #   'active_record'.camelize(:lower)        # => "activeRecord"
+  #   'active_record/errors'.camelize         # => "ActiveRecord::Errors"
+  #   'active_record/errors'.camelize(:lower) # => "activeRecord::Errors"
+  def camelize(first_letter = :upper)
+    case first_letter
+    when :upper
+      ActiveSupport::Inflector.camelize(self, true)
+    when :lower
+      ActiveSupport::Inflector.camelize(self, false)
+    end
+  end
+  alias_method :camelcase, :camelize
+
+  # Capitalizes all the words and replaces some characters in the string to create
+  # a nicer looking title. +titleize+ is meant for creating pretty output. It is not
+  # used in the Rails internals.
+  #
+  # +titleize+ is also aliased as +titlecase+.
+  #
+  #   'man from the boondocks'.titleize # => "Man From The Boondocks"
+  #   'x-men: the last stand'.titleize  # => "X Men: The Last Stand"
+  def titleize
+    ActiveSupport::Inflector.titleize(self)
+  end
+  alias_method :titlecase, :titleize
+
+  # The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
+  #
+  # +underscore+ will also change '::' to '/' to convert namespaces to paths.
+  #
+  #   'ActiveModel'.underscore         # => "active_model"
+  #   'ActiveModel::Errors'.underscore # => "active_model/errors"
+  def underscore
+    ActiveSupport::Inflector.underscore(self)
+  end
+
+  # Replaces underscores with dashes in the string.
+  #
+  #   'puni_puni'.dasherize # => "puni-puni"
+  def dasherize
+    ActiveSupport::Inflector.dasherize(self)
+  end
+
+  # Removes the module part from the constant expression in the string.
+  #
+  #   'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections"
+  #   'Inflections'.demodulize                                       # => "Inflections"
+  #
+  # See also +deconstantize+.
+  def demodulize
+    ActiveSupport::Inflector.demodulize(self)
+  end
+
+  # Removes the rightmost segment from the constant expression in the string.
+  #
+  #   'Net::HTTP'.deconstantize   # => "Net"
+  #   '::Net::HTTP'.deconstantize # => "::Net"
+  #   'String'.deconstantize      # => ""
+  #   '::String'.deconstantize    # => ""
+  #   ''.deconstantize            # => ""
+  #
+  # See also +demodulize+.
+  def deconstantize
+    ActiveSupport::Inflector.deconstantize(self)
+  end
+
+  # Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
+  #
+  #   class Person
+  #     def to_param
+  #       "#{id}-#{name.parameterize}"
+  #     end
+  #   end
+  #
+  #   @person = Person.find(1)
+  #   # => #<Person id: 1, name: "Donald E. Knuth">
+  #
+  #   <%= link_to(@person.name, person_path) %>
+  #   # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
+  def parameterize(sep = '-')
+    ActiveSupport::Inflector.parameterize(self, sep)
+  end
+
+  # Creates the name of a table like Rails does for models to table names. This method
+  # uses the +pluralize+ method on the last word in the string.
+  #
+  #   'RawScaledScorer'.tableize # => "raw_scaled_scorers"
+  #   'egg_and_ham'.tableize     # => "egg_and_hams"
+  #   'fancyCategory'.tableize   # => "fancy_categories"
+  def tableize
+    ActiveSupport::Inflector.tableize(self)
+  end
+
+  # Create a class name from a plural table name like Rails does for table names to models.
+  # Note that this returns a string and not a class. (To convert to an actual class
+  # follow +classify+ with +constantize+.)
+  #
+  #   'egg_and_hams'.classify # => "EggAndHam"
+  #   'posts'.classify        # => "Post"
+  def classify
+    ActiveSupport::Inflector.classify(self)
+  end
+
+  # Capitalizes the first word, turns underscores into spaces, and strips a
+  # trailing '_id' if present.
+  # Like +titleize+, this is meant for creating pretty output.
+  #
+  # The capitalization of the first word can be turned off by setting the
+  # optional parameter +capitalize+ to false.
+  # By default, this parameter is true.
+  #
+  #   'employee_salary'.humanize              # => "Employee salary"
+  #   'author_id'.humanize                    # => "Author"
+  #   'author_id'.humanize(capitalize: false) # => "author"
+  def humanize(options = {})
+    ActiveSupport::Inflector.humanize(self, options)
+  end
+
+  # Creates a foreign key name from a class name.
+  # +separate_class_name_and_id_with_underscore+ sets whether
+  # the method should put '_' between the name and 'id'.
+  #
+  #   'Message'.foreign_key        # => "message_id"
+  #   'Message'.foreign_key(false) # => "messageid"
+  #   'Admin::Post'.foreign_key    # => "post_id"
+  def foreign_key(separate_class_name_and_id_with_underscore = true)
+    ActiveSupport::Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/string/inquiry.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/string/inquiry.rb
new file mode 100644
index 0000000..1dcd949
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/string/inquiry.rb
@@ -0,0 +1,13 @@
+require 'active_support/string_inquirer'
+
+class String
+  # Wraps the current string in the <tt>ActiveSupport::StringInquirer</tt> class,
+  # which gives you a prettier way to test for equality.
+  #
+  #   env = 'production'.inquiry
+  #   env.production?  # => true
+  #   env.development? # => false
+  def inquiry
+    ActiveSupport::StringInquirer.new(self)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/string/multibyte.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/string/multibyte.rb
new file mode 100644
index 0000000..a124202
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/string/multibyte.rb
@@ -0,0 +1,49 @@
+# encoding: utf-8
+require 'active_support/multibyte'
+
+class String
+  # == Multibyte proxy
+  #
+  # +mb_chars+ is a multibyte safe proxy for string methods.
+  #
+  # It creates and returns an instance of the ActiveSupport::Multibyte::Chars class which
+  # encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy
+  # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string.
+  #
+  #   name = 'Claus Müller'
+  #   name.reverse # => "rell??M sualC"
+  #   name.length  # => 13
+  #
+  #   name.mb_chars.reverse.to_s # => "rellüM sualC"
+  #   name.mb_chars.length       # => 12
+  #
+  # == Method chaining
+  #
+  # All the methods on the Chars proxy which normally return a string will return a Chars object. This allows
+  # method chaining on the result of any of these methods.
+  #
+  #   name.mb_chars.reverse.length # => 12
+  #
+  # == Interoperability and configuration
+  #
+  # The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between
+  # String and Char work like expected. The bang! methods change the internal string representation in the Chars
+  # object. Interoperability problems can be resolved easily with a +to_s+ call.
+  #
+  # For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For
+  # information about how to change the default Multibyte behavior see ActiveSupport::Multibyte.
+  def mb_chars
+    ActiveSupport::Multibyte.proxy_class.new(self)
+  end
+
+  def is_utf8?
+    case encoding
+    when Encoding::UTF_8
+      valid_encoding?
+    when Encoding::ASCII_8BIT, Encoding::US_ASCII
+      dup.force_encoding(Encoding::UTF_8).valid_encoding?
+    else
+      false
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/string/output_safety.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/string/output_safety.rb
new file mode 100644
index 0000000..2c8995b
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -0,0 +1,243 @@
+require 'erb'
+require 'active_support/core_ext/kernel/singleton_class'
+require 'active_support/deprecation'
+
+class ERB
+  module Util
+    HTML_ESCAPE = { '&' => '&',  '>' => '>',   '<' => '<', '"' => '"', "'" => ''' }
+    JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003e', '<' => '\u003c', "\u2028" => '\u2028', "\u2029" => '\u2029' }
+    HTML_ESCAPE_REGEXP = /[&"'><]/
+    HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+));)/
+    JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
+
+    # A utility method for escaping HTML tag characters.
+    # This method is also aliased as <tt>h</tt>.
+    #
+    # In your ERB templates, use this method to escape any unsafe content. For example:
+    #   <%=h @person.name %>
+    #
+    #   puts html_escape('is a > 0 & a < 10?')
+    #   # => is a > 0 & a < 10?
+    def html_escape(s)
+      s = s.to_s
+      if s.html_safe?
+        s
+      else
+        s.gsub(HTML_ESCAPE_REGEXP, HTML_ESCAPE).html_safe
+      end
+    end
+
+    # Aliasing twice issues a warning "discarding old...". Remove first to avoid it.
+    remove_method(:h)
+    alias h html_escape
+
+    module_function :h
+
+    singleton_class.send(:remove_method, :html_escape)
+    module_function :html_escape
+
+    # A utility method for escaping HTML without affecting existing escaped entities.
+    #
+    #   html_escape_once('1 < 2 & 3')
+    #   # => "1 < 2 & 3"
+    #
+    #   html_escape_once('<< Accept & Checkout')
+    #   # => "<< Accept & Checkout"
+    def html_escape_once(s)
+      result = s.to_s.gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
+      s.html_safe? ? result.html_safe : result
+    end
+
+    module_function :html_escape_once
+
+    # A utility method for escaping HTML entities in JSON strings. Specifically, the
+    # &, > and < characters are replaced with their equivalent unicode escaped form -
+    # \u0026, \u003e, and \u003c. The Unicode sequences \u2028 and \u2029 are also
+    # escaped as they are treated as newline characters in some JavaScript engines.
+    # These sequences have identical meaning as the original characters inside the
+    # context of a JSON string, so assuming the input is a valid and well-formed
+    # JSON value, the output will have equivalent meaning when parsed:
+    #
+    #   json = JSON.generate({ name: "</script><script>alert('PWNED!!!')</script>"})
+    #   # => "{\"name\":\"</script><script>alert('PWNED!!!')</script>\"}"
+    #
+    #   json_escape(json)
+    #   # => "{\"name\":\"\\u003C/script\\u003E\\u003Cscript\\u003Ealert('PWNED!!!')\\u003C/script\\u003E\"}"
+    #
+    #   JSON.parse(json) == JSON.parse(json_escape(json))
+    #   # => true
+    #
+    # The intended use case for this method is to escape JSON strings before including
+    # them inside a script tag to avoid XSS vulnerability:
+    #
+    #   <script>
+    #     var currentUser = <%= raw json_escape(current_user.to_json) %>;
+    #   </script>
+    #
+    # It is necessary to +raw+ the result of +json_escape+, so that quotation marks
+    # don't get converted to <tt>"</tt> entities. +json_escape+ doesn't
+    # automatically flag the result as HTML safe, since the raw value is unsafe to
+    # use inside HTML attributes.
+    #
+    # If you need to output JSON elsewhere in your HTML, you can just do something
+    # like this, as any unsafe characters (including quotation marks) will be
+    # automatically escaped for you:
+    #
+    #   <div data-user-info="<%= current_user.to_json %>">...</div>
+    #
+    # WARNING: this helper only works with valid JSON. Using this on non-JSON values
+    # will open up serious XSS vulnerabilities. For example, if you replace the
+    # +current_user.to_json+ in the example above with user input instead, the browser
+    # will happily eval() that string as JavaScript.
+    #
+    # The escaping performed in this method is identical to those performed in the
+    # Active Support JSON encoder when +ActiveSupport.escape_html_entities_in_json+ is
+    # set to true. Because this transformation is idempotent, this helper can be
+    # applied even if +ActiveSupport.escape_html_entities_in_json+ is already true.
+    #
+    # Therefore, when you are unsure if +ActiveSupport.escape_html_entities_in_json+
+    # is enabled, or if you are unsure where your JSON string originated from, it
+    # is recommended that you always apply this helper (other libraries, such as the
+    # JSON gem, do not provide this kind of protection by default; also some gems
+    # might override +to_json+ to bypass Active Support's encoder).
+    def json_escape(s)
+      result = s.to_s.gsub(JSON_ESCAPE_REGEXP, JSON_ESCAPE)
+      s.html_safe? ? result.html_safe : result
+    end
+
+    module_function :json_escape
+  end
+end
+
+class Object
+  def html_safe?
+    false
+  end
+end
+
+class Numeric
+  def html_safe?
+    true
+  end
+end
+
+module ActiveSupport #:nodoc:
+  class SafeBuffer < String
+    UNSAFE_STRING_METHODS = %w(
+      capitalize chomp chop delete downcase gsub lstrip next reverse rstrip
+      slice squeeze strip sub succ swapcase tr tr_s upcase
+    )
+
+    alias_method :original_concat, :concat
+    private :original_concat
+
+    class SafeConcatError < StandardError
+      def initialize
+        super 'Could not concatenate to the buffer because it is not html safe.'
+      end
+    end
+
+    def [](*args)
+      if args.size < 2
+        super
+      else
+        if html_safe?
+          new_safe_buffer = super
+          new_safe_buffer.instance_eval { @html_safe = true }
+          new_safe_buffer
+        else
+          to_str[*args]
+        end
+      end
+    end
+
+    def safe_concat(value)
+      raise SafeConcatError unless html_safe?
+      original_concat(value)
+    end
+
+    def initialize(*)
+      @html_safe = true
+      super
+    end
+
+    def initialize_copy(other)
+      super
+      @html_safe = other.html_safe?
+    end
+
+    def clone_empty
+      self[0, 0]
+    end
+
+    %w[concat prepend].each do |method_name|
+      define_method method_name do |value|
+        super(html_escape_interpolated_argument(value))
+      end
+    end
+    alias << concat
+
+    def prepend!(value)
+      ActiveSupport::Deprecation.deprecation_warning "ActiveSupport::SafeBuffer#prepend!", :prepend
+      prepend value
+    end
+
+    def +(other)
+      dup.concat(other)
+    end
+
+    def %(args)
+      case args
+      when Hash
+        escaped_args = Hash[args.map { |k,arg| [k, html_escape_interpolated_argument(arg)] }]
+      else
+        escaped_args = Array(args).map { |arg| html_escape_interpolated_argument(arg) }
+      end
+
+      self.class.new(super(escaped_args))
+    end
+
+    def html_safe?
+      defined?(@html_safe) && @html_safe
+    end
+
+    def to_s
+      self
+    end
+
+    def to_param
+      to_str
+    end
+
+    def encode_with(coder)
+      coder.represent_scalar nil, to_str
+    end
+
+    UNSAFE_STRING_METHODS.each do |unsafe_method|
+      if unsafe_method.respond_to?(unsafe_method)
+        class_eval <<-EOT, __FILE__, __LINE__ + 1
+          def #{unsafe_method}(*args, &block)       # def capitalize(*args, &block)
+            to_str.#{unsafe_method}(*args, &block)  #   to_str.capitalize(*args, &block)
+          end                                       # end
+
+          def #{unsafe_method}!(*args)              # def capitalize!(*args)
+            @html_safe = false                      #   @html_safe = false
+            super                                   #   super
+          end                                       # end
+        EOT
+      end
+    end
+
+    private
+
+    def html_escape_interpolated_argument(arg)
+      (!html_safe? || arg.html_safe?) ? arg : ERB::Util.h(arg)
+    end
+  end
+end
+
+class String
+  def html_safe
+    ActiveSupport::SafeBuffer.new(self)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb
new file mode 100644
index 0000000..641acf6
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb
@@ -0,0 +1,4 @@
+class String
+  alias_method :starts_with?, :start_with?
+  alias_method :ends_with?, :end_with?
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/string/strip.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/string/strip.rb
new file mode 100644
index 0000000..086c610
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/string/strip.rb
@@ -0,0 +1,26 @@
+require 'active_support/core_ext/object/try'
+
+class String
+  # Strips indentation in heredocs.
+  #
+  # For example in
+  #
+  #   if options[:usage]
+  #     puts <<-USAGE.strip_heredoc
+  #       This command does such and such.
+  #
+  #       Supported options are:
+  #         -h         This message
+  #         ...
+  #     USAGE
+  #   end
+  #
+  # the user would see the usage message aligned against the left margin.
+  #
+  # Technically, it looks for the least indented line in the whole string, and removes
+  # that amount of leading whitespace.
+  def strip_heredoc
+    indent = scan(/^[ \t]*(?=\S)/).min.try(:size) || 0
+    gsub(/^[ \t]{#{indent}}/, '')
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/string/zones.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/string/zones.rb
new file mode 100644
index 0000000..510c884
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/string/zones.rb
@@ -0,0 +1,14 @@
+require 'active_support/core_ext/string/conversions'
+require 'active_support/core_ext/time/zones'
+
+class String
+  # Converts String to a TimeWithZone in the current zone if Time.zone or Time.zone_default
+  # is set, otherwise converts String to a Time via String#to_time
+  def in_time_zone(zone = ::Time.zone)
+    if zone
+      ::Time.find_zone!(zone).parse(self)
+    else
+      to_time
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/struct.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/struct.rb
new file mode 100644
index 0000000..c2c3004
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/struct.rb
@@ -0,0 +1,6 @@
+#  Backport of Struct#to_h from Ruby 2.0
+class Struct # :nodoc:
+  def to_h
+    Hash[members.zip(values)]
+  end
+end unless Struct.instance_methods.include?(:to_h)
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/thread.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/thread.rb
new file mode 100644
index 0000000..ac1ffa4
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/thread.rb
@@ -0,0 +1,79 @@
+class Thread
+  LOCK = Mutex.new # :nodoc:
+
+  # Returns the value of a thread local variable that has been set. Note that
+  # these are different than fiber local values.
+  #
+  # Thread local values are carried along with threads, and do not respect
+  # fibers. For example:
+  #
+  #   Thread.new {
+  #     Thread.current.thread_variable_set("foo", "bar") # set a thread local
+  #     Thread.current["foo"] = "bar"                    # set a fiber local
+  #
+  #     Fiber.new {
+  #       Fiber.yield [
+  #         Thread.current.thread_variable_get("foo"), # get the thread local
+  #         Thread.current["foo"],                     # get the fiber local
+  #       ]
+  #     }.resume
+  #   }.join.value # => ['bar', nil]
+  #
+  # The value <tt>"bar"</tt> is returned for the thread local, where +nil+ is returned
+  # for the fiber local. The fiber is executed in the same thread, so the
+  # thread local values are available.
+  def thread_variable_get(key)
+    _locals[key.to_sym]
+  end
+
+  # Sets a thread local with +key+ to +value+. Note that these are local to
+  # threads, and not to fibers. Please see Thread#thread_variable_get for
+  # more information.
+  def thread_variable_set(key, value)
+    _locals[key.to_sym] = value
+  end
+
+  # Returns an array of the names of the thread-local variables (as Symbols).
+  #
+  #    thr = Thread.new do
+  #      Thread.current.thread_variable_set(:cat, 'meow')
+  #      Thread.current.thread_variable_set("dog", 'woof')
+  #    end
+  #    thr.join               # => #<Thread:0x401b3f10 dead>
+  #    thr.thread_variables   # => [:dog, :cat]
+  #
+  # Note that these are not fiber local variables. Please see Thread#thread_variable_get
+  # for more details.
+  def thread_variables
+    _locals.keys
+  end
+
+  # Returns <tt>true</tt> if the given string (or symbol) exists as a
+  # thread-local variable.
+  #
+  #    me = Thread.current
+  #    me.thread_variable_set(:oliver, "a")
+  #    me.thread_variable?(:oliver)    # => true
+  #    me.thread_variable?(:stanley)   # => false
+  #
+  # Note that these are not fiber local variables. Please see Thread#thread_variable_get
+  # for more details.
+  def thread_variable?(key)
+    _locals.has_key?(key.to_sym)
+  end
+
+  def freeze
+    _locals.freeze
+    super
+  end
+
+  private
+
+  def _locals
+    if defined?(@_locals)
+      @_locals
+    else
+      LOCK.synchronize { @_locals ||= {} }
+    end
+  end
+end unless Thread.instance_methods.include?(:thread_variable_set)
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/time.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/time.rb
new file mode 100644
index 0000000..32cffe2
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/time.rb
@@ -0,0 +1,5 @@
+require 'active_support/core_ext/time/acts_like'
+require 'active_support/core_ext/time/calculations'
+require 'active_support/core_ext/time/conversions'
+require 'active_support/core_ext/time/marshal'
+require 'active_support/core_ext/time/zones'
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/time/acts_like.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/time/acts_like.rb
new file mode 100644
index 0000000..3f853b7
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/time/acts_like.rb
@@ -0,0 +1,8 @@
+require 'active_support/core_ext/object/acts_like'
+
+class Time
+  # Duck-types as a Time-like class. See Object#acts_like?.
+  def acts_like_time?
+    true
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/time/calculations.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/time/calculations.rb
new file mode 100644
index 0000000..89cd751
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -0,0 +1,257 @@
+require 'active_support/duration'
+require 'active_support/core_ext/time/conversions'
+require 'active_support/time_with_zone'
+require 'active_support/core_ext/time/zones'
+require 'active_support/core_ext/date_and_time/calculations'
+
+class Time
+  include DateAndTime::Calculations
+
+  COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
+
+  class << self
+    # Overriding case equality method so that it returns true for ActiveSupport::TimeWithZone instances
+    def ===(other)
+      super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
+    end
+
+    # Return the number of days in the given month.
+    # If no year is specified, it will use the current year.
+    def days_in_month(month, year = now.year)
+      if month == 2 && ::Date.gregorian_leap?(year)
+        29
+      else
+        COMMON_YEAR_DAYS_IN_MONTH[month]
+      end
+    end
+
+    # Returns <tt>Time.zone.now</tt> when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise just returns <tt>Time.now</tt>.
+    def current
+      ::Time.zone ? ::Time.zone.now : ::Time.now
+    end
+
+    # Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime
+    # instances can be used when called with a single argument
+    def at_with_coercion(*args)
+      return at_without_coercion(*args) if args.size != 1
+
+      # Time.at can be called with a time or numerical value
+      time_or_number = args.first
+
+      if time_or_number.is_a?(ActiveSupport::TimeWithZone) || time_or_number.is_a?(DateTime)
+        at_without_coercion(time_or_number.to_f).getlocal
+      else
+        at_without_coercion(time_or_number)
+      end
+    end
+    alias_method :at_without_coercion, :at
+    alias_method :at, :at_with_coercion
+  end
+
+  # Seconds since midnight: Time.now.seconds_since_midnight
+  def seconds_since_midnight
+    to_i - change(:hour => 0).to_i + (usec / 1.0e+6)
+  end
+
+  # Returns the number of seconds until 23:59:59.
+  #
+  #   Time.new(2012, 8, 29,  0,  0,  0).seconds_until_end_of_day # => 86399
+  #   Time.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103
+  #   Time.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0
+  def seconds_until_end_of_day
+    end_of_day.to_i - to_i
+  end
+
+  # Returns a new Time where one or more of the elements have been changed according
+  # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
+  # <tt>:sec</tt>, <tt>:usec</tt>) reset cascadingly, so if only the hour is passed,
+  # then minute, sec, and usec is set to 0. If the hour and minute is passed, then
+  # sec and usec is set to 0.  The +options+ parameter takes a hash with any of these
+  # keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>,
+  # <tt>:sec</tt>, <tt>:usec</tt>.
+  #
+  #   Time.new(2012, 8, 29, 22, 35, 0).change(day: 1)              # => Time.new(2012, 8, 1, 22, 35, 0)
+  #   Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1)  # => Time.new(1981, 8, 1, 22, 35, 0)
+  #   Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
+  def change(options)
+    new_year  = options.fetch(:year, year)
+    new_month = options.fetch(:month, month)
+    new_day   = options.fetch(:day, day)
+    new_hour  = options.fetch(:hour, hour)
+    new_min   = options.fetch(:min, options[:hour] ? 0 : min)
+    new_sec   = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
+    new_usec  = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
+
+    if utc?
+      ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
+    elsif zone
+      ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
+    else
+      ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
+    end
+  end
+
+  # Uses Date to provide precise Time calculations for years, months, and days
+  # according to the proleptic Gregorian calendar. The +options+ parameter
+  # takes a hash with any of these keys: <tt>:years</tt>, <tt>:months</tt>,
+  # <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>, <tt>:minutes</tt>,
+  # <tt>:seconds</tt>.
+  def advance(options)
+    unless options[:weeks].nil?
+      options[:weeks], partial_weeks = options[:weeks].divmod(1)
+      options[:days] = options.fetch(:days, 0) + 7 * partial_weeks
+    end
+
+    unless options[:days].nil?
+      options[:days], partial_days = options[:days].divmod(1)
+      options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
+    end
+
+    d = to_date.advance(options)
+    d = d.gregorian if d.julian?
+    time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
+    seconds_to_advance = \
+      options.fetch(:seconds, 0) +
+      options.fetch(:minutes, 0) * 60 +
+      options.fetch(:hours, 0) * 3600
+
+    if seconds_to_advance.zero?
+      time_advanced_by_date
+    else
+      time_advanced_by_date.since(seconds_to_advance)
+    end
+  end
+
+  # Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension
+  def ago(seconds)
+    since(-seconds)
+  end
+
+  # Returns a new Time representing the time a number of seconds since the instance time
+  def since(seconds)
+    self + seconds
+  rescue
+    to_datetime.since(seconds)
+  end
+  alias :in :since
+
+  # Returns a new Time representing the start of the day (0:00)
+  def beginning_of_day
+    #(self - seconds_since_midnight).change(usec: 0)
+    change(:hour => 0)
+  end
+  alias :midnight :beginning_of_day
+  alias :at_midnight :beginning_of_day
+  alias :at_beginning_of_day :beginning_of_day
+
+  # Returns a new Time representing the middle of the day (12:00)
+  def middle_of_day
+    change(:hour => 12)
+  end
+  alias :midday :middle_of_day
+  alias :noon :middle_of_day
+  alias :at_midday :middle_of_day
+  alias :at_noon :middle_of_day
+  alias :at_middle_of_day :middle_of_day
+
+  # Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9)
+  def end_of_day
+    change(
+      :hour => 23,
+      :min => 59,
+      :sec => 59,
+      :usec => Rational(999999999, 1000)
+    )
+  end
+  alias :at_end_of_day :end_of_day
+
+  # Returns a new Time representing the start of the hour (x:00)
+  def beginning_of_hour
+    change(:min => 0)
+  end
+  alias :at_beginning_of_hour :beginning_of_hour
+
+  # Returns a new Time representing the end of the hour, x:59:59.999999 (.999999999 in ruby1.9)
+  def end_of_hour
+    change(
+      :min => 59,
+      :sec => 59,
+      :usec => Rational(999999999, 1000)
+    )
+  end
+  alias :at_end_of_hour :end_of_hour
+
+  # Returns a new Time representing the start of the minute (x:xx:00)
+  def beginning_of_minute
+    change(:sec => 0)
+  end
+  alias :at_beginning_of_minute :beginning_of_minute
+
+  # Returns a new Time representing the end of the minute, x:xx:59.999999 (.999999999 in ruby1.9)
+  def end_of_minute
+    change(
+      :sec => 59,
+      :usec => Rational(999999999, 1000)
+    )
+  end
+  alias :at_end_of_minute :end_of_minute
+
+  # Returns a Range representing the whole day of the current time.
+  def all_day
+    beginning_of_day..end_of_day
+  end
+
+  def plus_with_duration(other) #:nodoc:
+    if ActiveSupport::Duration === other
+      other.since(self)
+    else
+      plus_without_duration(other)
+    end
+  end
+  alias_method :plus_without_duration, :+
+  alias_method :+, :plus_with_duration
+
+  def minus_with_duration(other) #:nodoc:
+    if ActiveSupport::Duration === other
+      other.until(self)
+    else
+      minus_without_duration(other)
+    end
+  end
+  alias_method :minus_without_duration, :-
+  alias_method :-, :minus_with_duration
+
+  # Time#- can also be used to determine the number of seconds between two Time instances.
+  # We're layering on additional behavior so that ActiveSupport::TimeWithZone instances
+  # are coerced into values that Time#- will recognize
+  def minus_with_coercion(other)
+    other = other.comparable_time if other.respond_to?(:comparable_time)
+    other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other)
+  end
+  alias_method :minus_without_coercion, :-
+  alias_method :-, :minus_with_coercion
+
+  # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
+  # can be chronologically compared with a Time
+  def compare_with_coercion(other)
+    # we're avoiding Time#to_datetime cause it's expensive
+    if other.is_a?(Time)
+      compare_without_coercion(other.to_time)
+    else
+      to_datetime <=> other
+    end
+  end
+  alias_method :compare_without_coercion, :<=>
+  alias_method :<=>, :compare_with_coercion
+
+  # Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances
+  # can be eql? to an equivalent Time
+  def eql_with_coercion(other)
+    # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison
+    other = other.comparable_time if other.respond_to?(:comparable_time)
+    eql_without_coercion(other)
+  end
+  alias_method :eql_without_coercion, :eql?
+  alias_method :eql?, :eql_with_coercion
+
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/time/conversions.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/time/conversions.rb
new file mode 100644
index 0000000..9fd2615
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/time/conversions.rb
@@ -0,0 +1,65 @@
+require 'active_support/inflector/methods'
+require 'active_support/values/time_zone'
+
+class Time
+  DATE_FORMATS = {
+    :db           => '%Y-%m-%d %H:%M:%S',
+    :number       => '%Y%m%d%H%M%S',
+    :nsec         => '%Y%m%d%H%M%S%9N',
+    :time         => '%H:%M',
+    :short        => '%d %b %H:%M',
+    :long         => '%B %d, %Y %H:%M',
+    :long_ordinal => lambda { |time|
+      day_format = ActiveSupport::Inflector.ordinalize(time.day)
+      time.strftime("%B #{day_format}, %Y %H:%M")
+    },
+    :rfc822       => lambda { |time|
+      offset_format = time.formatted_offset(false)
+      time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
+    },
+    :iso8601      => lambda { |time| time.iso8601 }
+  }
+
+  # Converts to a formatted string. See DATE_FORMATS for builtin formats.
+  #
+  # This method is aliased to <tt>to_s</tt>.
+  #
+  #   time = Time.now                    # => Thu Jan 18 06:10:17 CST 2007
+  #
+  #   time.to_formatted_s(:time)         # => "06:10"
+  #   time.to_s(:time)                   # => "06:10"
+  #
+  #   time.to_formatted_s(:db)           # => "2007-01-18 06:10:17"
+  #   time.to_formatted_s(:number)       # => "20070118061017"
+  #   time.to_formatted_s(:short)        # => "18 Jan 06:10"
+  #   time.to_formatted_s(:long)         # => "January 18, 2007 06:10"
+  #   time.to_formatted_s(:long_ordinal) # => "January 18th, 2007 06:10"
+  #   time.to_formatted_s(:rfc822)       # => "Thu, 18 Jan 2007 06:10:17 -0600"
+  #   time.to_formatted_s(:iso8601)      # => "2007-01-18T06:10:17-06:00"
+  #
+  # == Adding your own time formats to +to_formatted_s+
+  # You can add your own formats to the Time::DATE_FORMATS hash.
+  # Use the format name as the hash key and either a strftime string
+  # or Proc instance that takes a time argument as the value.
+  #
+  #   # config/initializers/time_formats.rb
+  #   Time::DATE_FORMATS[:month_and_year] = '%B %Y'
+  #   Time::DATE_FORMATS[:short_ordinal]  = ->(time) { time.strftime("%B #{time.day.ordinalize}") }
+  def to_formatted_s(format = :default)
+    if formatter = DATE_FORMATS[format]
+      formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
+    else
+      to_default_s
+    end
+  end
+  alias_method :to_default_s, :to_s
+  alias_method :to_s, :to_formatted_s
+
+  # Returns the UTC offset as an +HH:MM formatted string.
+  #
+  #   Time.local(2000).formatted_offset        # => "-06:00"
+  #   Time.local(2000).formatted_offset(false) # => "-0600"
+  def formatted_offset(colon = true, alternate_utc_string = nil)
+    utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/time/marshal.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/time/marshal.rb
new file mode 100644
index 0000000..497c4c3
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/time/marshal.rb
@@ -0,0 +1,30 @@
+# Ruby 1.9.2 adds utc_offset and zone to Time, but marshaling only
+# preserves utc_offset. Preserve zone also, even though it may not
+# work in some edge cases.
+if Time.local(2010).zone != Marshal.load(Marshal.dump(Time.local(2010))).zone
+  class Time
+    class << self
+      alias_method :_load_without_zone, :_load
+      def _load(marshaled_time)
+        time = _load_without_zone(marshaled_time)
+        time.instance_eval do
+          if zone = defined?(@_zone) && remove_instance_variable('@_zone')
+            ary = to_a
+            ary[0] += subsec if ary[0] == sec
+            ary[-1] = zone
+            utc? ? Time.utc(*ary) : Time.local(*ary)
+          else
+            self
+          end
+        end
+      end
+    end
+
+    alias_method :_dump_without_zone, :_dump
+    def _dump(*args)
+      obj = dup
+      obj.instance_variable_set('@_zone', zone)
+      obj.send :_dump_without_zone, *args
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/time/zones.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/time/zones.rb
new file mode 100644
index 0000000..bbda04d
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/time/zones.rb
@@ -0,0 +1,78 @@
+require 'active_support/time_with_zone'
+require 'active_support/core_ext/date_and_time/zones'
+
+class Time
+  include DateAndTime::Zones
+  class << self
+    attr_accessor :zone_default
+
+    # Returns the TimeZone for the current request, if this has been set (via Time.zone=).
+    # If <tt>Time.zone</tt> has not been set for the current request, returns the TimeZone specified in <tt>config.time_zone</tt>.
+    def zone
+      Thread.current[:time_zone] || zone_default
+    end
+
+    # Sets <tt>Time.zone</tt> to a TimeZone object for the current request/thread.
+    #
+    # This method accepts any of the following:
+    #
+    # * A Rails TimeZone object.
+    # * An identifier for a Rails TimeZone object (e.g., "Eastern Time (US & Canada)", <tt>-5.hours</tt>).
+    # * A TZInfo::Timezone object.
+    # * An identifier for a TZInfo::Timezone object (e.g., "America/New_York").
+    #
+    # Here's an example of how you might set <tt>Time.zone</tt> on a per request basis and reset it when the request is done.
+    # <tt>current_user.time_zone</tt> just needs to return a string identifying the user's preferred time zone:
+    #
+    #   class ApplicationController < ActionController::Base
+    #     around_filter :set_time_zone
+    #
+    #     def set_time_zone
+    #       if logged_in?
+    #         Time.use_zone(current_user.time_zone) { yield }
+    #       else
+    #         yield
+    #       end
+    #     end
+    #   end
+    def zone=(time_zone)
+      Thread.current[:time_zone] = find_zone!(time_zone)
+    end
+
+    # Allows override of <tt>Time.zone</tt> locally inside supplied block; resets <tt>Time.zone</tt> to existing value when done.
+    def use_zone(time_zone)
+      new_zone = find_zone!(time_zone)
+      begin
+        old_zone, ::Time.zone = ::Time.zone, new_zone
+        yield
+      ensure
+        ::Time.zone = old_zone
+      end
+    end
+
+    # Returns a TimeZone instance or nil, or raises an ArgumentError for invalid timezones.
+    def find_zone!(time_zone)
+      if !time_zone || time_zone.is_a?(ActiveSupport::TimeZone)
+        time_zone
+      else
+        # lookup timezone based on identifier (unless we've been passed a TZInfo::Timezone)
+        unless time_zone.respond_to?(:period_for_local)
+          time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone)
+        end
+
+        # Return if a TimeZone instance, or wrap in a TimeZone instance if a TZInfo::Timezone
+        if time_zone.is_a?(ActiveSupport::TimeZone)
+          time_zone
+        else
+          ActiveSupport::TimeZone.create(time_zone.name, nil, time_zone)
+        end
+      end
+    rescue TZInfo::InvalidTimezoneIdentifier
+      raise ArgumentError, "Invalid Timezone: #{time_zone}"
+    end
+
+    def find_zone(time_zone)
+      find_zone!(time_zone) rescue nil
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/core_ext/uri.rb b/app/server/vendor/activesupport/lib/active_support/core_ext/uri.rb
new file mode 100644
index 0000000..bfe0832
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/core_ext/uri.rb
@@ -0,0 +1,26 @@
+# encoding: utf-8
+
+require 'uri'
+str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
+parser = URI::Parser.new
+
+unless str == parser.unescape(parser.escape(str))
+  URI::Parser.class_eval do
+    remove_method :unescape
+    def unescape(str, escaped = /%[a-fA-F\d]{2}/)
+      # TODO: Are we actually sure that ASCII == UTF-8?
+      # YK: My initial experiments say yes, but let's be sure please
+      enc = str.encoding
+      enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
+      str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(enc)
+    end
+  end
+end
+
+module URI
+  class << self
+    def parser
+      @parser ||= URI::Parser.new
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/dependencies.rb b/app/server/vendor/activesupport/lib/active_support/dependencies.rb
new file mode 100644
index 0000000..59675d7
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/dependencies.rb
@@ -0,0 +1,748 @@
+require 'set'
+require 'thread'
+require 'thread_safe'
+require 'pathname'
+require 'active_support/core_ext/module/aliasing'
+require 'active_support/core_ext/module/attribute_accessors'
+require 'active_support/core_ext/module/introspection'
+require 'active_support/core_ext/module/anonymous'
+require 'active_support/core_ext/module/qualified_const'
+require 'active_support/core_ext/object/blank'
+require 'active_support/core_ext/kernel/reporting'
+require 'active_support/core_ext/load_error'
+require 'active_support/core_ext/name_error'
+require 'active_support/core_ext/string/starts_ends_with'
+require 'active_support/inflector'
+
+module ActiveSupport #:nodoc:
+  module Dependencies #:nodoc:
+    extend self
+
+    # Should we turn on Ruby warnings on the first load of dependent files?
+    mattr_accessor :warnings_on_first_load
+    self.warnings_on_first_load = false
+
+    # All files ever loaded.
+    mattr_accessor :history
+    self.history = Set.new
+
+    # All files currently loaded.
+    mattr_accessor :loaded
+    self.loaded = Set.new
+
+    # Should we load files or require them?
+    mattr_accessor :mechanism
+    self.mechanism = ENV['NO_RELOAD'] ? :require : :load
+
+    # The set of directories from which we may automatically load files. Files
+    # under these directories will be reloaded on each request in development mode,
+    # unless the directory also appears in autoload_once_paths.
+    mattr_accessor :autoload_paths
+    self.autoload_paths = []
+
+    # The set of directories from which automatically loaded constants are loaded
+    # only once. All directories in this set must also be present in +autoload_paths+.
+    mattr_accessor :autoload_once_paths
+    self.autoload_once_paths = []
+
+    # An array of qualified constant names that have been loaded. Adding a name
+    # to this array will cause it to be unloaded the next time Dependencies are
+    # cleared.
+    mattr_accessor :autoloaded_constants
+    self.autoloaded_constants = []
+
+    # An array of constant names that need to be unloaded on every request. Used
+    # to allow arbitrary constants to be marked for unloading.
+    mattr_accessor :explicitly_unloadable_constants
+    self.explicitly_unloadable_constants = []
+
+    # The logger is used for generating information on the action run-time
+    # (including benchmarking) if available. Can be set to nil for no logging.
+    # Compatible with both Ruby's own Logger and Log4r loggers.
+    mattr_accessor :logger
+
+    # Set to +true+ to enable logging of const_missing and file loads.
+    mattr_accessor :log_activity
+    self.log_activity = false
+
+    # The WatchStack keeps a stack of the modules being watched as files are
+    # loaded. If a file in the process of being loaded (parent.rb) triggers the
+    # load of another file (child.rb) the stack will ensure that child.rb
+    # handles the new constants.
+    #
+    # If child.rb is being autoloaded, its constants will be added to
+    # autoloaded_constants. If it was being `require`d, they will be discarded.
+    #
+    # This is handled by walking back up the watch stack and adding the constants
+    # found by child.rb to the list of original constants in parent.rb.
+    class WatchStack
+      include Enumerable
+
+      # @watching is a stack of lists of constants being watched. For instance,
+      # if parent.rb is autoloaded, the stack will look like [[Object]]. If
+      # parent.rb then requires namespace/child.rb, the stack will look like
+      # [[Object], [Namespace]].
+
+      def initialize
+        @watching = []
+        @stack = Hash.new { |h,k| h[k] = [] }
+      end
+
+      def each(&block)
+        @stack.each(&block)
+      end
+
+      def watching?
+        !@watching.empty?
+      end
+
+      # Returns a list of new constants found since the last call to
+      # <tt>watch_namespaces</tt>.
+      def new_constants
+        constants = []
+
+        # Grab the list of namespaces that we're looking for new constants under
+        @watching.last.each do |namespace|
+          # Retrieve the constants that were present under the namespace when watch_namespaces
+          # was originally called
+          original_constants = @stack[namespace].last
+
+          mod = Inflector.constantize(namespace) if Dependencies.qualified_const_defined?(namespace)
+          next unless mod.is_a?(Module)
+
+          # Get a list of the constants that were added
+          new_constants = mod.local_constants - original_constants
+
+          # self[namespace] returns an Array of the constants that are being evaluated
+          # for that namespace. For instance, if parent.rb requires child.rb, the first
+          # element of self[Object] will be an Array of the constants that were present
+          # before parent.rb was required. The second element will be an Array of the
+          # constants that were present before child.rb was required.
+          @stack[namespace].each do |namespace_constants|
+            namespace_constants.concat(new_constants)
+          end
+
+          # Normalize the list of new constants, and add them to the list we will return
+          new_constants.each do |suffix|
+            constants << ([namespace, suffix] - ["Object"]).join("::")
+          end
+        end
+        constants
+      ensure
+        # A call to new_constants is always called after a call to watch_namespaces
+        pop_modules(@watching.pop)
+      end
+
+      # Add a set of modules to the watch stack, remembering the initial
+      # constants.
+      def watch_namespaces(namespaces)
+        @watching << namespaces.map do |namespace|
+          module_name = Dependencies.to_constant_name(namespace)
+          original_constants = Dependencies.qualified_const_defined?(module_name) ?
+            Inflector.constantize(module_name).local_constants : []
+
+          @stack[module_name] << original_constants
+          module_name
+        end
+      end
+
+      private
+      def pop_modules(modules)
+        modules.each { |mod| @stack[mod].pop }
+      end
+    end
+
+    # An internal stack used to record which constants are loaded by any block.
+    mattr_accessor :constant_watch_stack
+    self.constant_watch_stack = WatchStack.new
+
+    # Module includes this module.
+    module ModuleConstMissing #:nodoc:
+      def self.append_features(base)
+        base.class_eval do
+          # Emulate #exclude via an ivar
+          return if defined?(@_const_missing) && @_const_missing
+          @_const_missing = instance_method(:const_missing)
+          remove_method(:const_missing)
+        end
+        super
+      end
+
+      def self.exclude_from(base)
+        base.class_eval do
+          define_method :const_missing, @_const_missing
+          @_const_missing = nil
+        end
+      end
+
+      def const_missing(const_name)
+        from_mod = anonymous? ? guess_for_anonymous(const_name) : self
+        Dependencies.load_missing_constant(from_mod, const_name)
+      end
+
+      # Dependencies assumes the name of the module reflects the nesting (unless
+      # it can be proven that is not the case), and the path to the file that
+      # defines the constant. Anonymous modules cannot follow these conventions
+      # and we assume therefore the user wants to refer to a top-level constant.
+      def guess_for_anonymous(const_name)
+        if Object.const_defined?(const_name)
+          raise NameError, "#{const_name} cannot be autoloaded from an anonymous class or module"
+        else
+          Object
+        end
+      end
+
+      def unloadable(const_desc = self)
+        super(const_desc)
+      end
+    end
+
+    # Object includes this module.
+    module Loadable #:nodoc:
+      def self.exclude_from(base)
+        base.class_eval { define_method(:load, Kernel.instance_method(:load)) }
+      end
+
+      def require_or_load(file_name)
+        Dependencies.require_or_load(file_name)
+      end
+
+      # Interprets a file using <tt>mechanism</tt> and marks its defined
+      # constants as autoloaded. <tt>file_name</tt> can be either a string or
+      # respond to <tt>to_path</tt>.
+      #
+      # Use this method in code that absolutely needs a certain constant to be
+      # defined at that point. A typical use case is to make constant name
+      # resolution deterministic for constants with the same relative name in
+      # different namespaces whose evaluation would depend on load order
+      # otherwise.
+      def require_dependency(file_name, message = "No such file to load -- %s")
+        file_name = file_name.to_path if file_name.respond_to?(:to_path)
+        unless file_name.is_a?(String)
+          raise ArgumentError, "the file name must either be a String or implement #to_path -- you passed #{file_name.inspect}"
+        end
+
+        Dependencies.depend_on(file_name, message)
+      end
+
+      def load_dependency(file)
+        if Dependencies.load? && ActiveSupport::Dependencies.constant_watch_stack.watching?
+          Dependencies.new_constants_in(Object) { yield }
+        else
+          yield
+        end
+      rescue Exception => exception  # errors from loading file
+        exception.blame_file! file if exception.respond_to? :blame_file!
+        raise
+      end
+
+      def load(file, wrap = false)
+        result = false
+        load_dependency(file) { result = super }
+        result
+      end
+
+      def require(file)
+        result = false
+        load_dependency(file) { result = super }
+        result
+      end
+
+      # Mark the given constant as unloadable. Unloadable constants are removed
+      # each time dependencies are cleared.
+      #
+      # Note that marking a constant for unloading need only be done once. Setup
+      # or init scripts may list each unloadable constant that may need unloading;
+      # each constant will be removed for every subsequent clear, as opposed to
+      # for the first clear.
+      #
+      # The provided constant descriptor may be a (non-anonymous) module or class,
+      # or a qualified constant name as a string or symbol.
+      #
+      # Returns +true+ if the constant was not previously marked for unloading,
+      # +false+ otherwise.
+      def unloadable(const_desc)
+        Dependencies.mark_for_unload const_desc
+      end
+    end
+
+    # Exception file-blaming.
+    module Blamable #:nodoc:
+      def blame_file!(file)
+        (@blamed_files ||= []).unshift file
+      end
+
+      def blamed_files
+        @blamed_files ||= []
+      end
+
+      def describe_blame
+        return nil if blamed_files.empty?
+        "This error occurred while loading the following files:\n   #{blamed_files.join "\n   "}"
+      end
+
+      def copy_blame!(exc)
+        @blamed_files = exc.blamed_files.clone
+        self
+      end
+    end
+
+    def hook!
+      Object.class_eval { include Loadable }
+      Module.class_eval { include ModuleConstMissing }
+      Exception.class_eval { include Blamable }
+    end
+
+    def unhook!
+      ModuleConstMissing.exclude_from(Module)
+      Loadable.exclude_from(Object)
+    end
+
+    def load?
+      mechanism == :load
+    end
+
+    def depend_on(file_name, message = "No such file to load -- %s.rb")
+      path = search_for_file(file_name)
+      require_or_load(path || file_name)
+    rescue LoadError => load_error
+      if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1]
+        load_error.message.replace(message % file_name)
+        load_error.copy_blame!(load_error)
+      end
+      raise
+    end
+
+    def clear
+      log_call
+      loaded.clear
+      remove_unloadable_constants!
+    end
+
+    def require_or_load(file_name, const_path = nil)
+      log_call file_name, const_path
+      file_name = $` if file_name =~ /\.rb\z/
+      expanded = File.expand_path(file_name)
+      return if loaded.include?(expanded)
+
+      # Record that we've seen this file *before* loading it to avoid an
+      # infinite loop with mutual dependencies.
+      loaded << expanded
+
+      begin
+        if load?
+          log "loading #{file_name}"
+
+          # Enable warnings if this file has not been loaded before and
+          # warnings_on_first_load is set.
+          load_args = ["#{file_name}.rb"]
+          load_args << const_path unless const_path.nil?
+
+          if !warnings_on_first_load or history.include?(expanded)
+            result = load_file(*load_args)
+          else
+            enable_warnings { result = load_file(*load_args) }
+          end
+        else
+          log "requiring #{file_name}"
+          result = require file_name
+        end
+      rescue Exception
+        loaded.delete expanded
+        raise
+      end
+
+      # Record history *after* loading so first load gets warnings.
+      history << expanded
+      result
+    end
+
+    # Is the provided constant path defined?
+    def qualified_const_defined?(path)
+      Object.qualified_const_defined?(path.sub(/^::/, ''), false)
+    end
+
+    # Given +path+, a filesystem path to a ruby file, return an array of
+    # constant paths which would cause Dependencies to attempt to load this
+    # file.
+    def loadable_constants_for_path(path, bases = autoload_paths)
+      path = $` if path =~ /\.rb\z/
+      expanded_path = File.expand_path(path)
+      paths = []
+
+      bases.each do |root|
+        expanded_root = File.expand_path(root)
+        next unless %r{\A#{Regexp.escape(expanded_root)}(/|\\)} =~ expanded_path
+
+        nesting = expanded_path[(expanded_root.size)..-1]
+        nesting = nesting[1..-1] if nesting && nesting[0] == ?/
+        next if nesting.blank?
+
+        paths << nesting.camelize
+      end
+
+      paths.uniq!
+      paths
+    end
+
+    # Search for a file in autoload_paths matching the provided suffix.
+    def search_for_file(path_suffix)
+      path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb")
+
+      autoload_paths.each do |root|
+        path = File.join(root, path_suffix)
+        return path if File.file? path
+      end
+      nil # Gee, I sure wish we had first_match ;-)
+    end
+
+    # Does the provided path_suffix correspond to an autoloadable module?
+    # Instead of returning a boolean, the autoload base for this module is
+    # returned.
+    def autoloadable_module?(path_suffix)
+      autoload_paths.each do |load_path|
+        return load_path if File.directory? File.join(load_path, path_suffix)
+      end
+      nil
+    end
+
+    def load_once_path?(path)
+      # to_s works around a ruby1.9 issue where String#starts_with?(Pathname)
+      # will raise a TypeError: no implicit conversion of Pathname into String
+      autoload_once_paths.any? { |base| path.starts_with? base.to_s }
+    end
+
+    # Attempt to autoload the provided module name by searching for a directory
+    # matching the expected path suffix. If found, the module is created and
+    # assigned to +into+'s constants with the name +const_name+. Provided that
+    # the directory was loaded from a reloadable base path, it is added to the
+    # set of constants that are to be unloaded.
+    def autoload_module!(into, const_name, qualified_name, path_suffix)
+      return nil unless base_path = autoloadable_module?(path_suffix)
+      mod = Module.new
+      into.const_set const_name, mod
+      autoloaded_constants << qualified_name unless autoload_once_paths.include?(base_path)
+      mod
+    end
+
+    # Load the file at the provided path. +const_paths+ is a set of qualified
+    # constant names. When loading the file, Dependencies will watch for the
+    # addition of these constants. Each that is defined will be marked as
+    # autoloaded, and will be removed when Dependencies.clear is next called.
+    #
+    # If the second parameter is left off, then Dependencies will construct a
+    # set of names that the file at +path+ may define. See
+    # +loadable_constants_for_path+ for more details.
+    def load_file(path, const_paths = loadable_constants_for_path(path))
+      log_call path, const_paths
+      const_paths = [const_paths].compact unless const_paths.is_a? Array
+      parent_paths = const_paths.collect { |const_path| const_path[/.*(?=::)/] || ::Object }
+
+      result = nil
+      newly_defined_paths = new_constants_in(*parent_paths) do
+        result = Kernel.load path
+      end
+
+      autoloaded_constants.concat newly_defined_paths unless load_once_path?(path)
+      autoloaded_constants.uniq!
+      log "loading #{path} defined #{newly_defined_paths * ', '}" unless newly_defined_paths.empty?
+      result
+    end
+
+    # Returns the constant path for the provided parent and constant name.
+    def qualified_name_for(mod, name)
+      mod_name = to_constant_name mod
+      mod_name == "Object" ? name.to_s : "#{mod_name}::#{name}"
+    end
+
+    # Load the constant named +const_name+ which is missing from +from_mod+. If
+    # it is not possible to load the constant into from_mod, try its parent
+    # module using +const_missing+.
+    def load_missing_constant(from_mod, const_name)
+      log_call from_mod, const_name
+
+      unless qualified_const_defined?(from_mod.name) && Inflector.constantize(from_mod.name).equal?(from_mod)
+        raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
+      end
+
+      qualified_name = qualified_name_for from_mod, const_name
+      path_suffix = qualified_name.underscore
+
+      file_path = search_for_file(path_suffix)
+
+      if file_path
+        expanded = File.expand_path(file_path)
+        expanded.sub!(/\.rb\z/, '')
+
+        if loaded.include?(expanded)
+          raise "Circular dependency detected while autoloading constant #{qualified_name}"
+        else
+          require_or_load(expanded, qualified_name)
+          raise LoadError, "Unable to autoload constant #{qualified_name}, expected #{file_path} to define it" unless from_mod.const_defined?(const_name, false)
+          return from_mod.const_get(const_name)
+        end
+      elsif mod = autoload_module!(from_mod, const_name, qualified_name, path_suffix)
+        return mod
+      elsif (parent = from_mod.parent) && parent != from_mod &&
+            ! from_mod.parents.any? { |p| p.const_defined?(const_name, false) }
+        # If our parents do not have a constant named +const_name+ then we are free
+        # to attempt to load upwards. If they do have such a constant, then this
+        # const_missing must be due to from_mod::const_name, which should not
+        # return constants from from_mod's parents.
+        begin
+          # Since Ruby does not pass the nesting at the point the unknown
+          # constant triggered the callback we cannot fully emulate constant
+          # name lookup and need to make a trade-off: we are going to assume
+          # that the nesting in the body of Foo::Bar is [Foo::Bar, Foo] even
+          # though it might not be. Counterexamples are
+          #
+          #   class Foo::Bar
+          #     Module.nesting # => [Foo::Bar]
+          #   end
+          #
+          # or
+          #
+          #   module M::N
+          #     module S::T
+          #       Module.nesting # => [S::T, M::N]
+          #     end
+          #   end
+          #
+          # for example.
+          return parent.const_missing(const_name)
+        rescue NameError => e
+          raise unless e.missing_name? qualified_name_for(parent, const_name)
+        end
+      end
+
+      raise NameError,
+            "uninitialized constant #{qualified_name}",
+            caller.reject { |l| l.starts_with? __FILE__ }
+    end
+
+    # Remove the constants that have been autoloaded, and those that have been
+    # marked for unloading. Before each constant is removed a callback is sent
+    # to its class/module if it implements +before_remove_const+.
+    #
+    # The callback implementation should be restricted to cleaning up caches, etc.
+    # as the environment will be in an inconsistent state, e.g. other constants
+    # may have already been unloaded and not accessible.
+    def remove_unloadable_constants!
+      autoloaded_constants.each { |const| remove_constant const }
+      autoloaded_constants.clear
+      Reference.clear!
+      explicitly_unloadable_constants.each { |const| remove_constant const }
+    end
+
+    class ClassCache
+      def initialize
+        @store = ThreadSafe::Cache.new
+      end
+
+      def empty?
+        @store.empty?
+      end
+
+      def key?(key)
+        @store.key?(key)
+      end
+
+      def get(key)
+        key = key.name if key.respond_to?(:name)
+        @store[key] ||= Inflector.constantize(key)
+      end
+      alias :[] :get
+
+      def safe_get(key)
+        key = key.name if key.respond_to?(:name)
+        @store[key] ||= Inflector.safe_constantize(key)
+      end
+
+      def store(klass)
+        return self unless klass.respond_to?(:name)
+        raise(ArgumentError, 'anonymous classes cannot be cached') if klass.name.empty?
+        @store[klass.name] = klass
+        self
+      end
+
+      def clear!
+        @store.clear
+      end
+    end
+
+    Reference = ClassCache.new
+
+    # Store a reference to a class +klass+.
+    def reference(klass)
+      Reference.store klass
+    end
+
+    # Get the reference for class named +name+.
+    # Raises an exception if referenced class does not exist.
+    def constantize(name)
+      Reference.get(name)
+    end
+
+    # Get the reference for class named +name+ if one exists.
+    # Otherwise returns +nil+.
+    def safe_constantize(name)
+      Reference.safe_get(name)
+    end
+
+    # Determine if the given constant has been automatically loaded.
+    def autoloaded?(desc)
+      return false if desc.is_a?(Module) && desc.anonymous?
+      name = to_constant_name desc
+      return false unless qualified_const_defined? name
+      return autoloaded_constants.include?(name)
+    end
+
+    # Will the provided constant descriptor be unloaded?
+    def will_unload?(const_desc)
+      autoloaded?(const_desc) ||
+        explicitly_unloadable_constants.include?(to_constant_name(const_desc))
+    end
+
+    # Mark the provided constant name for unloading. This constant will be
+    # unloaded on each request, not just the next one.
+    def mark_for_unload(const_desc)
+      name = to_constant_name const_desc
+      if explicitly_unloadable_constants.include? name
+        false
+      else
+        explicitly_unloadable_constants << name
+        true
+      end
+    end
+
+    # Run the provided block and detect the new constants that were loaded during
+    # its execution. Constants may only be regarded as 'new' once -- so if the
+    # block calls +new_constants_in+ again, then the constants defined within the
+    # inner call will not be reported in this one.
+    #
+    # If the provided block does not run to completion, and instead raises an
+    # exception, any new constants are regarded as being only partially defined
+    # and will be removed immediately.
+    def new_constants_in(*descs)
+      log_call(*descs)
+
+      constant_watch_stack.watch_namespaces(descs)
+      aborting = true
+
+      begin
+        yield # Now yield to the code that is to define new constants.
+        aborting = false
+      ensure
+        new_constants = constant_watch_stack.new_constants
+
+        log "New constants: #{new_constants * ', '}"
+        return new_constants unless aborting
+
+        log "Error during loading, removing partially loaded constants "
+        new_constants.each { |c| remove_constant(c) }.clear
+      end
+
+      []
+    end
+
+    # Convert the provided const desc to a qualified constant name (as a string).
+    # A module, class, symbol, or string may be provided.
+    def to_constant_name(desc) #:nodoc:
+      case desc
+        when String then desc.sub(/^::/, '')
+        when Symbol then desc.to_s
+        when Module
+          desc.name ||
+            raise(ArgumentError, "Anonymous modules have no name to be referenced by")
+        else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
+      end
+    end
+
+    def remove_constant(const) #:nodoc:
+      # Normalize ::Foo, ::Object::Foo, Object::Foo, Object::Object::Foo, etc. as Foo.
+      normalized = const.to_s.sub(/\A::/, '')
+      normalized.sub!(/\A(Object::)+/, '')
+
+      constants = normalized.split('::')
+      to_remove = constants.pop
+
+      # Remove the file path from the loaded list.
+      file_path = search_for_file(const.underscore)
+      if file_path
+        expanded = File.expand_path(file_path)
+        expanded.sub!(/\.rb\z/, '')
+        self.loaded.delete(expanded)
+      end
+
+      if constants.empty?
+        parent = Object
+      else
+        # This method is robust to non-reachable constants.
+        #
+        # Non-reachable constants may be passed if some of the parents were
+        # autoloaded and already removed. It is easier to do a sanity check
+        # here than require the caller to be clever. We check the parent
+        # rather than the very const argument because we do not want to
+        # trigger Kernel#autoloads, see the comment below.
+        parent_name = constants.join('::')
+        return unless qualified_const_defined?(parent_name)
+        parent = constantize(parent_name)
+      end
+
+      log "removing constant #{const}"
+
+      # In an autoloaded user.rb like this
+      #
+      #   autoload :Foo, 'foo'
+      #
+      #   class User < ActiveRecord::Base
+      #   end
+      #
+      # we correctly register "Foo" as being autoloaded. But if the app does
+      # not use the "Foo" constant we need to be careful not to trigger
+      # loading "foo.rb" ourselves. While #const_defined? and #const_get? do
+      # require the file, #autoload? and #remove_const don't.
+      #
+      # We are going to remove the constant nonetheless ---which exists as
+      # far as Ruby is concerned--- because if the user removes the macro
+      # call from a class or module that were not autoloaded, as in the
+      # example above with Object, accessing to that constant must err.
+      unless parent.autoload?(to_remove)
+        begin
+          constantized = parent.const_get(to_remove, false)
+        rescue NameError
+          log "the constant #{const} is not reachable anymore, skipping"
+          return
+        else
+          constantized.before_remove_const if constantized.respond_to?(:before_remove_const)
+        end
+      end
+
+      begin
+        parent.instance_eval { remove_const to_remove }
+      rescue NameError
+        log "the constant #{const} is not reachable anymore, skipping"
+      end
+    end
+
+    protected
+      def log_call(*args)
+        if log_activity?
+          arg_str = args.collect { |arg| arg.inspect } * ', '
+          /in `([a-z_\?\!]+)'/ =~ caller(1).first
+          selector = $1 || '<unknown>'
+          log "called #{selector}(#{arg_str})"
+        end
+      end
+
+      def log(msg)
+        logger.debug "Dependencies: #{msg}" if log_activity?
+      end
+
+      def log_activity?
+        logger && log_activity
+      end
+  end
+end
+
+ActiveSupport::Dependencies.hook!
diff --git a/app/server/vendor/activesupport/lib/active_support/dependencies/autoload.rb b/app/server/vendor/activesupport/lib/active_support/dependencies/autoload.rb
new file mode 100644
index 0000000..c0dba5f
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/dependencies/autoload.rb
@@ -0,0 +1,77 @@
+require "active_support/inflector/methods"
+
+module ActiveSupport
+  # Autoload and eager load conveniences for your library.
+  #
+  # This module allows you to define autoloads based on
+  # Rails conventions (i.e. no need to define the path
+  # it is automatically guessed based on the filename)
+  # and also define a set of constants that needs to be
+  # eager loaded:
+  #
+  #   module MyLib
+  #     extend ActiveSupport::Autoload
+  #
+  #     autoload :Model
+  #
+  #     eager_autoload do
+  #       autoload :Cache
+  #     end
+  #   end
+  #
+  # Then your library can be eager loaded by simply calling:
+  #
+  #   MyLib.eager_load!
+  module Autoload
+    def self.extended(base) # :nodoc:
+      base.class_eval do
+        @_autoloads = {}
+        @_under_path = nil
+        @_at_path = nil
+        @_eager_autoload = false
+      end
+    end
+
+    def autoload(const_name, path = @_at_path)
+      unless path
+        full = [name, @_under_path, const_name.to_s].compact.join("::")
+        path = Inflector.underscore(full)
+      end
+
+      if @_eager_autoload
+        @_autoloads[const_name] = path
+      end
+
+      super const_name, path
+    end
+
+    def autoload_under(path)
+      @_under_path, old_path = path, @_under_path
+      yield
+    ensure
+      @_under_path = old_path
+    end
+
+    def autoload_at(path)
+      @_at_path, old_path = path, @_at_path
+      yield
+    ensure
+      @_at_path = old_path
+    end
+
+    def eager_autoload
+      old_eager, @_eager_autoload = @_eager_autoload, true
+      yield
+    ensure
+      @_eager_autoload = old_eager
+    end
+
+    def eager_load!
+      @_autoloads.values.each { |file| require file }
+    end
+
+    def autoloads
+      @_autoloads
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/deprecation.rb b/app/server/vendor/activesupport/lib/active_support/deprecation.rb
new file mode 100644
index 0000000..ab16977
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/deprecation.rb
@@ -0,0 +1,43 @@
+require 'singleton'
+
+module ActiveSupport
+  # \Deprecation specifies the API used by Rails to deprecate methods, instance
+  # variables, objects and constants.
+  class Deprecation
+    # active_support.rb sets an autoload for ActiveSupport::Deprecation.
+    #
+    # If these requires were at the top of the file the constant would not be
+    # defined by the time their files were loaded. Since some of them reopen
+    # ActiveSupport::Deprecation its autoload would be triggered, resulting in
+    # a circular require warning for active_support/deprecation.rb.
+    #
+    # So, we define the constant first, and load dependencies later.
+    require 'active_support/deprecation/instance_delegator'
+    require 'active_support/deprecation/behaviors'
+    require 'active_support/deprecation/reporting'
+    require 'active_support/deprecation/method_wrappers'
+    require 'active_support/deprecation/proxy_wrappers'
+    require 'active_support/core_ext/module/deprecation'
+
+    include Singleton
+    include InstanceDelegator
+    include Behavior
+    include Reporting
+    include MethodWrapper
+
+    # The version number in which the deprecated behavior will be removed, by default.
+    attr_accessor :deprecation_horizon
+
+    # It accepts two parameters on initialization. The first is a version of library
+    # and the second is a library name
+    #
+    #   ActiveSupport::Deprecation.new('2.0', 'MyLibrary')
+    def initialize(deprecation_horizon = '4.2', gem_name = 'Rails')
+      self.gem_name = gem_name
+      self.deprecation_horizon = deprecation_horizon
+      # By default, warnings are not silenced and debugging is off.
+      self.silenced = false
+      self.debug = false
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/deprecation/behaviors.rb b/app/server/vendor/activesupport/lib/active_support/deprecation/behaviors.rb
new file mode 100644
index 0000000..328b8c3
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/deprecation/behaviors.rb
@@ -0,0 +1,76 @@
+require "active_support/notifications"
+
+module ActiveSupport
+  class DeprecationException < StandardError
+  end
+
+  class Deprecation
+    # Default warning behaviors per Rails.env.
+    DEFAULT_BEHAVIORS = {
+      raise: ->(message, callstack) {
+        e = DeprecationException.new(message)
+        e.set_backtrace(callstack)
+        raise e
+      },
+
+      stderr: ->(message, callstack) {
+        $stderr.puts(message)
+        $stderr.puts callstack.join("\n  ") if debug
+      },
+
+      log: ->(message, callstack) {
+        logger =
+            if defined?(Rails) && Rails.logger
+              Rails.logger
+            else
+              require 'active_support/logger'
+              ActiveSupport::Logger.new($stderr)
+            end
+        logger.warn message
+        logger.debug callstack.join("\n  ") if debug
+      },
+
+      notify: ->(message, callstack) {
+        ActiveSupport::Notifications.instrument("deprecation.rails",
+                                                :message => message, :callstack => callstack)
+      },
+
+      silence: ->(message, callstack) {},
+    }
+
+    module Behavior
+      # Whether to print a backtrace along with the warning.
+      attr_accessor :debug
+
+      # Returns the current behavior or if one isn't set, defaults to +:stderr+.
+      def behavior
+        @behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
+      end
+
+      # Sets the behavior to the specified value. Can be a single value, array,
+      # or an object that responds to +call+.
+      #
+      # Available behaviors:
+      #
+      # [+raise+]   Raise <tt>ActiveSupport::DeprecationException</tt>.
+      # [+stderr+]  Log all deprecation warnings to +$stderr+.
+      # [+log+]     Log all deprecation warnings to +Rails.logger+.
+      # [+notify+]  Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
+      # [+silence+] Do nothing.
+      #
+      # Setting behaviors only affects deprecations that happen after boot time.
+      # Deprecation warnings raised by gems are not affected by this setting
+      # because they happen before Rails boots up.
+      #
+      #   ActiveSupport::Deprecation.behavior = :stderr
+      #   ActiveSupport::Deprecation.behavior = [:stderr, :log]
+      #   ActiveSupport::Deprecation.behavior = MyCustomHandler
+      #   ActiveSupport::Deprecation.behavior = ->(message, callstack) {
+      #     # custom stuff
+      #   }
+      def behavior=(behavior)
+        @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || b }
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/deprecation/instance_delegator.rb b/app/server/vendor/activesupport/lib/active_support/deprecation/instance_delegator.rb
new file mode 100644
index 0000000..8472a58
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/deprecation/instance_delegator.rb
@@ -0,0 +1,24 @@
+require 'active_support/core_ext/kernel/singleton_class'
+require 'active_support/core_ext/module/delegation'
+
+module ActiveSupport
+  class Deprecation
+    module InstanceDelegator # :nodoc:
+      def self.included(base)
+        base.extend(ClassMethods)
+        base.public_class_method :new
+      end
+
+      module ClassMethods # :nodoc:
+        def include(included_module)
+          included_module.instance_methods.each { |m| method_added(m) }
+          super
+        end
+
+        def method_added(method_name)
+          singleton_class.delegate(method_name, to: :instance)
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/deprecation/method_wrappers.rb b/app/server/vendor/activesupport/lib/active_support/deprecation/method_wrappers.rb
new file mode 100644
index 0000000..cab8a1b
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/deprecation/method_wrappers.rb
@@ -0,0 +1,44 @@
+require 'active_support/core_ext/module/aliasing'
+require 'active_support/core_ext/array/extract_options'
+
+module ActiveSupport
+  class Deprecation
+    module MethodWrapper
+      # Declare that a method has been deprecated.
+      #
+      #   module Fred
+      #     extend self
+      #
+      #     def foo; end
+      #     def bar; end
+      #     def baz; end
+      #   end
+      #
+      #   ActiveSupport::Deprecation.deprecate_methods(Fred, :foo, bar: :qux, baz: 'use Bar#baz instead')
+      #   # => [:foo, :bar, :baz]
+      #
+      #   Fred.foo
+      #   # => "DEPRECATION WARNING: foo is deprecated and will be removed from Rails 4.1."
+      #
+      #   Fred.bar
+      #   # => "DEPRECATION WARNING: bar is deprecated and will be removed from Rails 4.1 (use qux instead)."
+      #
+      #   Fred.baz
+      #   # => "DEPRECATION WARNING: baz is deprecated and will be removed from Rails 4.1 (use Bar#baz instead)."
+      def deprecate_methods(target_module, *method_names)
+        options = method_names.extract_options!
+        deprecator = options.delete(:deprecator) || ActiveSupport::Deprecation.instance
+        method_names += options.keys
+
+        method_names.each do |method_name|
+          target_module.alias_method_chain(method_name, :deprecation) do |target, punctuation|
+            target_module.send(:define_method, "#{target}_with_deprecation#{punctuation}") do |*args, &block|
+              deprecator.deprecation_warning(method_name, options[method_name])
+              send(:"#{target}_without_deprecation#{punctuation}", *args, &block)
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/deprecation/proxy_wrappers.rb b/app/server/vendor/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
new file mode 100644
index 0000000..a03a66b
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
@@ -0,0 +1,126 @@
+require 'active_support/inflector/methods'
+
+module ActiveSupport
+  class Deprecation
+    class DeprecationProxy #:nodoc:
+      def self.new(*args, &block)
+        object = args.first
+
+        return object unless object
+        super
+      end
+
+      instance_methods.each { |m| undef_method m unless m =~ /^__|^object_id$/ }
+
+      # Don't give a deprecation warning on inspect since test/unit and error
+      # logs rely on it for diagnostics.
+      def inspect
+        target.inspect
+      end
+
+      private
+        def method_missing(called, *args, &block)
+          warn caller, called, args
+          target.__send__(called, *args, &block)
+        end
+    end
+
+    # This DeprecatedObjectProxy transforms object to deprecated object.
+    #
+    #   @old_object = DeprecatedObjectProxy.new(Object.new, "Don't use this object anymore!")
+    #   @old_object = DeprecatedObjectProxy.new(Object.new, "Don't use this object anymore!", deprecator_instance)
+    #
+    # When someone executes any method except +inspect+ on proxy object this will
+    # trigger +warn+ method on +deprecator_instance+.
+    #
+    # Default deprecator is <tt>ActiveSupport::Deprecation</tt>
+    class DeprecatedObjectProxy < DeprecationProxy
+      def initialize(object, message, deprecator = ActiveSupport::Deprecation.instance)
+        @object = object
+        @message = message
+        @deprecator = deprecator
+      end
+
+      private
+        def target
+          @object
+        end
+
+        def warn(callstack, called, args)
+          @deprecator.warn(@message, callstack)
+        end
+    end
+
+    # This DeprecatedInstanceVariableProxy transforms instance variable to
+    # deprecated instance variable.
+    #
+    #   class Example
+    #     def initialize(deprecator)
+    #       @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request, :@request, deprecator)
+    #       @_request = :a_request
+    #     end
+    #
+    #     def request
+    #       @_request
+    #     end
+    #
+    #     def old_request
+    #       @request
+    #     end
+    #   end
+    #
+    # When someone execute any method on @request variable this will trigger
+    # +warn+ method on +deprecator_instance+ and will fetch <tt>@_request</tt>
+    # variable via +request+ method and execute the same method on non-proxy
+    # instance variable.
+    #
+    # Default deprecator is <tt>ActiveSupport::Deprecation</tt>.
+    class DeprecatedInstanceVariableProxy < DeprecationProxy
+      def initialize(instance, method, var = "@#{method}", deprecator = ActiveSupport::Deprecation.instance)
+        @instance = instance
+        @method = method
+        @var = var
+        @deprecator = deprecator
+      end
+
+      private
+        def target
+          @instance.__send__(@method)
+        end
+
+        def warn(callstack, called, args)
+          @deprecator.warn("#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}. Args: #{args.inspect}", callstack)
+        end
+    end
+
+    # This DeprecatedConstantProxy transforms constant to deprecated constant.
+    #
+    #   OLD_CONST = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('OLD_CONST', 'NEW_CONST')
+    #   OLD_CONST = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('OLD_CONST', 'NEW_CONST', deprecator_instance)
+    #
+    # When someone use old constant this will trigger +warn+ method on
+    # +deprecator_instance+.
+    #
+    # Default deprecator is <tt>ActiveSupport::Deprecation</tt>.
+    class DeprecatedConstantProxy < DeprecationProxy
+      def initialize(old_const, new_const, deprecator = ActiveSupport::Deprecation.instance)
+        @old_const = old_const
+        @new_const = new_const
+        @deprecator = deprecator
+      end
+
+      def class
+        target.class
+      end
+
+      private
+        def target
+          ActiveSupport::Inflector.constantize(@new_const.to_s)
+        end
+
+        def warn(callstack, called, args)
+          @deprecator.warn("#{@old_const} is deprecated! Use #{@new_const} instead.", callstack)
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/deprecation/reporting.rb b/app/server/vendor/activesupport/lib/active_support/deprecation/reporting.rb
new file mode 100644
index 0000000..a7d265d
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/deprecation/reporting.rb
@@ -0,0 +1,94 @@
+module ActiveSupport
+  class Deprecation
+    module Reporting
+      # Whether to print a message (silent mode)
+      attr_accessor :silenced
+      # Name of gem where method is deprecated
+      attr_accessor :gem_name
+
+      # Outputs a deprecation warning to the output configured by
+      # <tt>ActiveSupport::Deprecation.behavior</tt>.
+      #
+      #   ActiveSupport::Deprecation.warn('something broke!')
+      #   # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
+      def warn(message = nil, callstack = nil)
+        return if silenced
+
+        callstack ||= caller(2)
+        deprecation_message(callstack, message).tap do |m|
+          behavior.each { |b| b.call(m, callstack) }
+        end
+      end
+
+      # Silence deprecation warnings within the block.
+      #
+      #   ActiveSupport::Deprecation.warn('something broke!')
+      #   # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
+      #
+      #   ActiveSupport::Deprecation.silence do
+      #     ActiveSupport::Deprecation.warn('something broke!')
+      #   end
+      #   # => nil
+      def silence
+        old_silenced, @silenced = @silenced, true
+        yield
+      ensure
+        @silenced = old_silenced
+      end
+
+      def deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = nil)
+        caller_backtrace ||= caller(2)
+        deprecated_method_warning(deprecated_method_name, message).tap do |msg|
+          warn(msg, caller_backtrace)
+        end
+      end
+
+      private
+        # Outputs a deprecation warning message
+        #
+        #   ActiveSupport::Deprecation.deprecated_method_warning(:method_name)
+        #   # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon}"
+        #   ActiveSupport::Deprecation.deprecated_method_warning(:method_name, :another_method)
+        #   # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon} (use another_method instead)"
+        #   ActiveSupport::Deprecation.deprecated_method_warning(:method_name, "Optional message")
+        #   # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon} (Optional message)"
+        def deprecated_method_warning(method_name, message = nil)
+          warning = "#{method_name} is deprecated and will be removed from #{gem_name} #{deprecation_horizon}"
+          case message
+            when Symbol then "#{warning} (use #{message} instead)"
+            when String then "#{warning} (#{message})"
+            else warning
+          end
+        end
+
+        def deprecation_message(callstack, message = nil)
+          message ||= "You are using deprecated behavior which will be removed from the next major or minor release."
+          message += '.' unless message =~ /\.$/
+          "DEPRECATION WARNING: #{message} #{deprecation_caller_message(callstack)}"
+        end
+
+        def deprecation_caller_message(callstack)
+          file, line, method = extract_callstack(callstack)
+          if file
+            if line && method
+              "(called from #{method} at #{file}:#{line})"
+            else
+              "(called from #{file}:#{line})"
+            end
+          end
+        end
+
+        def extract_callstack(callstack)
+          rails_gem_root = File.expand_path("../../../../..", __FILE__) + "/"
+          offending_line = callstack.find { |line| !line.start_with?(rails_gem_root) } || callstack.first
+          if offending_line
+            if md = offending_line.match(/^(.+?):(\d+)(?::in `(.*?)')?/)
+              md.captures
+            else
+              offending_line
+            end
+          end
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/descendants_tracker.rb b/app/server/vendor/activesupport/lib/active_support/descendants_tracker.rb
new file mode 100644
index 0000000..27861e0
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/descendants_tracker.rb
@@ -0,0 +1,60 @@
+module ActiveSupport
+  # This module provides an internal implementation to track descendants
+  # which is faster than iterating through ObjectSpace.
+  module DescendantsTracker
+    @@direct_descendants = {}
+
+    class << self
+      def direct_descendants(klass)
+        @@direct_descendants[klass] || []
+      end
+
+      def descendants(klass)
+        arr = []
+        accumulate_descendants(klass, arr)
+        arr
+      end
+
+      def clear
+        if defined? ActiveSupport::Dependencies
+          @@direct_descendants.each do |klass, descendants|
+            if ActiveSupport::Dependencies.autoloaded?(klass)
+              @@direct_descendants.delete(klass)
+            else
+              descendants.reject! { |v| ActiveSupport::Dependencies.autoloaded?(v) }
+            end
+          end
+        else
+          @@direct_descendants.clear
+        end
+      end
+
+      # This is the only method that is not thread safe, but is only ever called
+      # during the eager loading phase.
+      def store_inherited(klass, descendant)
+        (@@direct_descendants[klass] ||= []) << descendant
+      end
+
+      private
+      def accumulate_descendants(klass, acc)
+        if direct_descendants = @@direct_descendants[klass]
+          acc.concat(direct_descendants)
+          direct_descendants.each { |direct_descendant| accumulate_descendants(direct_descendant, acc) }
+        end
+      end
+    end
+
+    def inherited(base)
+      DescendantsTracker.store_inherited(self, base)
+      super
+    end
+
+    def direct_descendants
+      DescendantsTracker.direct_descendants(self)
+    end
+
+    def descendants
+      DescendantsTracker.descendants(self)
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/duration.rb b/app/server/vendor/activesupport/lib/active_support/duration.rb
new file mode 100644
index 0000000..7df4857
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/duration.rb
@@ -0,0 +1,114 @@
+require 'active_support/proxy_object'
+require 'active_support/core_ext/array/conversions'
+require 'active_support/core_ext/object/acts_like'
+
+module ActiveSupport
+  # Provides accurate date and time measurements using Date#advance and
+  # Time#advance, respectively. It mainly supports the methods on Numeric.
+  #
+  #   1.month.ago       # equivalent to Time.now.advance(months: -1)
+  class Duration < ProxyObject
+    attr_accessor :value, :parts
+
+    def initialize(value, parts) #:nodoc:
+      @value, @parts = value, parts
+    end
+
+    # Adds another Duration or a Numeric to this Duration. Numeric values
+    # are treated as seconds.
+    def +(other)
+      if Duration === other
+        Duration.new(value + other.value, @parts + other.parts)
+      else
+        Duration.new(value + other, @parts + [[:seconds, other]])
+      end
+    end
+
+    # Subtracts another Duration or a Numeric from this Duration. Numeric
+    # values are treated as seconds.
+    def -(other)
+      self + (-other)
+    end
+
+    def -@ #:nodoc:
+      Duration.new(-value, parts.map { |type,number| [type, -number] })
+    end
+
+    def is_a?(klass) #:nodoc:
+      Duration == klass || value.is_a?(klass)
+    end
+    alias :kind_of? :is_a?
+
+    # Returns +true+ if +other+ is also a Duration instance with the
+    # same +value+, or if <tt>other == value</tt>.
+    def ==(other)
+      if Duration === other
+        other.value == value
+      else
+        other == value
+      end
+    end
+
+    def self.===(other) #:nodoc:
+      other.is_a?(Duration)
+    rescue ::NoMethodError
+      false
+    end
+
+    # Calculates a new Time or Date that is as far in the future
+    # as this Duration represents.
+    def since(time = ::Time.current)
+      sum(1, time)
+    end
+    alias :from_now :since
+
+    # Calculates a new Time or Date that is as far in the past
+    # as this Duration represents.
+    def ago(time = ::Time.current)
+      sum(-1, time)
+    end
+    alias :until :ago
+
+    def inspect #:nodoc:
+      parts.
+        reduce(::Hash.new(0)) { |h,(l,r)| h[l] += r; h }.
+        sort_by {|unit,  _ | [:years, :months, :days, :minutes, :seconds].index(unit)}.
+        map     {|unit, val| "#{val} #{val == 1 ? unit.to_s.chop : unit.to_s}"}.
+        to_sentence(:locale => :en)
+    end
+
+    def as_json(options = nil) #:nodoc:
+      to_i
+    end
+
+    protected
+
+      def sum(sign, time = ::Time.current) #:nodoc:
+        parts.inject(time) do |t,(type,number)|
+          if t.acts_like?(:time) || t.acts_like?(:date)
+            if type == :seconds
+              t.since(sign * number)
+            else
+              t.advance(type => sign * number)
+            end
+          else
+            raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
+          end
+        end
+      end
+
+    private
+
+      # We define it as a workaround to Ruby 2.0.0-p353 bug.
+      # For more information, check rails/rails#13055.
+      # It should be dropped once a new Ruby patch-level
+      # release after 2.0.0-p353 happens.
+      def ===(other) #:nodoc:
+        value === other
+      end
+
+      def method_missing(method, *args, &block) #:nodoc:
+        value.send(method, *args, &block)
+      end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/file_update_checker.rb b/app/server/vendor/activesupport/lib/active_support/file_update_checker.rb
new file mode 100644
index 0000000..78b627c
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/file_update_checker.rb
@@ -0,0 +1,137 @@
+module ActiveSupport
+  # FileUpdateChecker specifies the API used by Rails to watch files
+  # and control reloading. The API depends on four methods:
+  #
+  # * +initialize+ which expects two parameters and one block as
+  #   described below.
+  #
+  # * +updated?+ which returns a boolean if there were updates in
+  #   the filesystem or not.
+  #
+  # * +execute+ which executes the given block on initialization
+  #   and updates the latest watched files and timestamp.
+  #
+  # * +execute_if_updated+ which just executes the block if it was updated.
+  #
+  # After initialization, a call to +execute_if_updated+ must execute
+  # the block only if there was really a change in the filesystem.
+  #
+  # This class is used by Rails to reload the I18n framework whenever
+  # they are changed upon a new request.
+  #
+  #   i18n_reloader = ActiveSupport::FileUpdateChecker.new(paths) do
+  #     I18n.reload!
+  #   end
+  #
+  #   ActionDispatch::Reloader.to_prepare do
+  #     i18n_reloader.execute_if_updated
+  #   end
+  class FileUpdateChecker
+    # It accepts two parameters on initialization. The first is an array
+    # of files and the second is an optional hash of directories. The hash must
+    # have directories as keys and the value is an array of extensions to be
+    # watched under that directory.
+    #
+    # This method must also receive a block that will be called once a path
+    # changes. The array of files and list of directories cannot be changed
+    # after FileUpdateChecker has been initialized.
+    def initialize(files, dirs={}, &block)
+      @files = files.freeze
+      @glob  = compile_glob(dirs)
+      @block = block
+
+      @watched    = nil
+      @updated_at = nil
+
+      @last_watched   = watched
+      @last_update_at = updated_at(@last_watched)
+    end
+
+    # Check if any of the entries were updated. If so, the watched and/or
+    # updated_at values are cached until the block is executed via +execute+
+    # or +execute_if_updated+.
+    def updated?
+      current_watched = watched
+      if @last_watched.size != current_watched.size
+        @watched = current_watched
+        true
+      else
+        current_updated_at = updated_at(current_watched)
+        if @last_update_at < current_updated_at
+          @watched    = current_watched
+          @updated_at = current_updated_at
+          true
+        else
+          false
+        end
+      end
+    end
+
+    # Executes the given block and updates the latest watched files and
+    # timestamp.
+    def execute
+      @last_watched   = watched
+      @last_update_at = updated_at(@last_watched)
+      @block.call
+    ensure
+      @watched = nil
+      @updated_at = nil
+    end
+
+    # Execute the block given if updated.
+    def execute_if_updated
+      if updated?
+        execute
+        true
+      else
+        false
+      end
+    end
+
+    private
+
+    def watched
+      @watched || begin
+        all = @files.select { |f| File.exist?(f) }
+        all.concat(Dir[@glob]) if @glob
+        all
+      end
+    end
+
+    def updated_at(paths)
+      @updated_at || max_mtime(paths) || Time.at(0)
+    end
+
+    # This method returns the maximum mtime of the files in +paths+, or +nil+
+    # if the array is empty.
+    #
+    # Files with a mtime in the future are ignored. Such abnormal situation
+    # can happen for example if the user changes the clock by hand. It is
+    # healthy to consider this edge case because with mtimes in the future
+    # reloading is not triggered.
+    def max_mtime(paths)
+      time_now = Time.now
+      paths.map {|path| File.mtime(path)}.reject {|mtime| time_now < mtime}.max
+    end
+
+    def compile_glob(hash)
+      hash.freeze # Freeze so changes aren't accidentally pushed
+      return if hash.empty?
+
+      globs = hash.map do |key, value|
+        "#{escape(key)}/**/*#{compile_ext(value)}"
+      end
+      "{#{globs.join(",")}}"
+    end
+
+    def escape(key)
+      key.gsub(',','\,')
+    end
+
+    def compile_ext(array)
+      array = Array(array)
+      return if array.empty?
+      ".{#{array.join(",")}}"
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/file_watcher.rb b/app/server/vendor/activesupport/lib/active_support/file_watcher.rb
new file mode 100644
index 0000000..81e63e7
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/file_watcher.rb
@@ -0,0 +1,36 @@
+module ActiveSupport
+  class FileWatcher
+    class Backend
+      def initialize(path, watcher)
+        @watcher = watcher
+        @path    = path
+      end
+
+      def trigger(files)
+        @watcher.trigger(files)
+      end
+    end
+
+    def initialize
+      @regex_matchers = {}
+    end
+
+    def watch(pattern, &block)
+      @regex_matchers[pattern] = block
+    end
+
+    def trigger(files)
+      trigger_files = Hash.new { |h,k| h[k] = Hash.new { |h2,k2| h2[k2] = [] } }
+
+      files.each do |file, state|
+        @regex_matchers.each do |pattern, block|
+          trigger_files[block][state] << file if pattern === file
+        end
+      end
+
+      trigger_files.each do |block, payload|
+        block.call payload
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/gem_version.rb b/app/server/vendor/activesupport/lib/active_support/gem_version.rb
new file mode 100644
index 0000000..83a3bf7
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/gem_version.rb
@@ -0,0 +1,15 @@
+module ActiveSupport
+  # Returns the version of the currently loaded ActiveSupport as a <tt>Gem::Version</tt>
+  def self.gem_version
+    Gem::Version.new VERSION::STRING
+  end
+
+  module VERSION
+    MAJOR = 4
+    MINOR = 2
+    TINY  = 0
+    PRE   = "alpha"
+
+    STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/gzip.rb b/app/server/vendor/activesupport/lib/active_support/gzip.rb
new file mode 100644
index 0000000..b837c87
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/gzip.rb
@@ -0,0 +1,36 @@
+require 'zlib'
+require 'stringio'
+
+module ActiveSupport
+  # A convenient wrapper for the zlib standard library that allows
+  # compression/decompression of strings with gzip.
+  #
+  #   gzip = ActiveSupport::Gzip.compress('compress me!')
+  #   # => "\x1F\x8B\b\x00o\x8D\xCDO\x00\x03K\xCE\xCF-(J-.V\xC8MU\x04\x00R>n\x83\f\x00\x00\x00"
+  #
+  #   ActiveSupport::Gzip.decompress(gzip)
+  #   # => "compress me!" 
+  module Gzip
+    class Stream < StringIO
+      def initialize(*)
+        super
+        set_encoding "BINARY"
+      end
+      def close; rewind; end
+    end
+
+    # Decompresses a gzipped string.
+    def self.decompress(source)
+      Zlib::GzipReader.new(StringIO.new(source)).read
+    end
+
+    # Compresses a string using gzip.
+    def self.compress(source, level=Zlib::DEFAULT_COMPRESSION, strategy=Zlib::DEFAULT_STRATEGY)
+      output = Stream.new
+      gz = Zlib::GzipWriter.new(output, level, strategy)
+      gz.write(source)
+      gz.close
+      output.string
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/hash_with_indifferent_access.rb b/app/server/vendor/activesupport/lib/active_support/hash_with_indifferent_access.rb
new file mode 100644
index 0000000..a4ebdea
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/hash_with_indifferent_access.rb
@@ -0,0 +1,272 @@
+require 'active_support/core_ext/hash/keys'
+
+module ActiveSupport
+  # Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
+  # to be the same.
+  #
+  #   rgb = ActiveSupport::HashWithIndifferentAccess.new
+  #
+  #   rgb[:black] = '#000000'
+  #   rgb[:black]  # => '#000000'
+  #   rgb['black'] # => '#000000'
+  #
+  #   rgb['white'] = '#FFFFFF'
+  #   rgb[:white]  # => '#FFFFFF'
+  #   rgb['white'] # => '#FFFFFF'
+  #
+  # Internally symbols are mapped to strings when used as keys in the entire
+  # writing interface (calling <tt>[]=</tt>, <tt>merge</tt>, etc). This
+  # mapping belongs to the public interface. For example, given:
+  #
+  #   hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)
+  #
+  # You are guaranteed that the key is returned as a string:
+  #
+  #   hash.keys # => ["a"]
+  #
+  # Technically other types of keys are accepted:
+  #
+  #   hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)
+  #   hash[0] = 0
+  #   hash # => {"a"=>1, 0=>0}
+  #
+  # but this class is intended for use cases where strings or symbols are the
+  # expected keys and it is convenient to understand both as the same. For
+  # example the +params+ hash in Ruby on Rails.
+  #
+  # Note that core extensions define <tt>Hash#with_indifferent_access</tt>:
+  #
+  #   rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access
+  #
+  # which may be handy.
+  class HashWithIndifferentAccess < Hash
+    # Returns +true+ so that <tt>Array#extract_options!</tt> finds members of
+    # this class.
+    def extractable_options?
+      true
+    end
+
+    def with_indifferent_access
+      dup
+    end
+
+    def nested_under_indifferent_access
+      self
+    end
+
+    def initialize(constructor = {})
+      if constructor.respond_to?(:to_hash)
+        super()
+        update(constructor.to_hash)
+      else
+        super(constructor)
+      end
+    end
+
+    def default(key = nil)
+      if key.is_a?(Symbol) && include?(key = key.to_s)
+        self[key]
+      else
+        super
+      end
+    end
+
+    def self.new_from_hash_copying_default(hash)
+      hash = hash.to_hash
+      new(hash).tap do |new_hash|
+        new_hash.default = hash.default
+      end
+    end
+
+    def self.[](*args)
+      new.merge!(Hash[*args])
+    end
+
+    alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
+    alias_method :regular_update, :update unless method_defined?(:regular_update)
+
+    # Assigns a new value to the hash:
+    #
+    #   hash = ActiveSupport::HashWithIndifferentAccess.new
+    #   hash[:key] = 'value'
+    #
+    # This value can be later fetched using either +:key+ or +'key'+.
+    def []=(key, value)
+      regular_writer(convert_key(key), convert_value(value, for: :assignment))
+    end
+
+    alias_method :store, :[]=
+
+    # Updates the receiver in-place, merging in the hash passed as argument:
+    #
+    #   hash_1 = ActiveSupport::HashWithIndifferentAccess.new
+    #   hash_1[:key] = 'value'
+    #
+    #   hash_2 = ActiveSupport::HashWithIndifferentAccess.new
+    #   hash_2[:key] = 'New Value!'
+    #
+    #   hash_1.update(hash_2) # => {"key"=>"New Value!"}
+    #
+    # The argument can be either an
+    # <tt>ActiveSupport::HashWithIndifferentAccess</tt> or a regular +Hash+.
+    # In either case the merge respects the semantics of indifferent access.
+    #
+    # If the argument is a regular hash with keys +:key+ and +"key"+ only one
+    # of the values end up in the receiver, but which one is unspecified.
+    #
+    # When given a block, the value for duplicated keys will be determined
+    # by the result of invoking the block with the duplicated key, the value
+    # in the receiver, and the value in +other_hash+. The rules for duplicated
+    # keys follow the semantics of indifferent access:
+    #
+    #   hash_1[:key] = 10
+    #   hash_2['key'] = 12
+    #   hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
+    def update(other_hash)
+      if other_hash.is_a? HashWithIndifferentAccess
+        super(other_hash)
+      else
+        other_hash.to_hash.each_pair do |key, value|
+          if block_given? && key?(key)
+            value = yield(convert_key(key), self[key], value)
+          end
+          regular_writer(convert_key(key), convert_value(value))
+        end
+        self
+      end
+    end
+
+    alias_method :merge!, :update
+
+    # Checks the hash for a key matching the argument passed in:
+    #
+    #   hash = ActiveSupport::HashWithIndifferentAccess.new
+    #   hash['key'] = 'value'
+    #   hash.key?(:key)  # => true
+    #   hash.key?('key') # => true
+    def key?(key)
+      super(convert_key(key))
+    end
+
+    alias_method :include?, :key?
+    alias_method :has_key?, :key?
+    alias_method :member?, :key?
+
+    # Same as <tt>Hash#fetch</tt> where the key passed as argument can be
+    # either a string or a symbol:
+    #
+    #   counters = ActiveSupport::HashWithIndifferentAccess.new
+    #   counters[:foo] = 1
+    #
+    #   counters.fetch('foo')          # => 1
+    #   counters.fetch(:bar, 0)        # => 0
+    #   counters.fetch(:bar) { |key| 0 } # => 0
+    #   counters.fetch(:zoo)           # => KeyError: key not found: "zoo"
+    def fetch(key, *extras)
+      super(convert_key(key), *extras)
+    end
+
+    # Returns an array of the values at the specified indices:
+    #
+    #   hash = ActiveSupport::HashWithIndifferentAccess.new
+    #   hash[:a] = 'x'
+    #   hash[:b] = 'y'
+    #   hash.values_at('a', 'b') # => ["x", "y"]
+    def values_at(*indices)
+      indices.collect { |key| self[convert_key(key)] }
+    end
+
+    # Returns an exact copy of the hash.
+    def dup
+      self.class.new(self).tap do |new_hash|
+        new_hash.default = default
+      end
+    end
+
+    # This method has the same semantics of +update+, except it does not
+    # modify the receiver but rather returns a new hash with indifferent
+    # access with the result of the merge.
+    def merge(hash, &block)
+      self.dup.update(hash, &block)
+    end
+
+    # Like +merge+ but the other way around: Merges the receiver into the
+    # argument and returns a new hash with indifferent access as result:
+    #
+    #   hash = ActiveSupport::HashWithIndifferentAccess.new
+    #   hash['a'] = nil
+    #   hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
+    def reverse_merge(other_hash)
+      super(self.class.new_from_hash_copying_default(other_hash))
+    end
+
+    # Same semantics as +reverse_merge+ but modifies the receiver in-place.
+    def reverse_merge!(other_hash)
+      replace(reverse_merge( other_hash ))
+    end
+
+    # Replaces the contents of this hash with other_hash.
+    #
+    #   h = { "a" => 100, "b" => 200 }
+    #   h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400}
+    def replace(other_hash)
+      super(self.class.new_from_hash_copying_default(other_hash))
+    end
+
+    # Removes the specified key from the hash.
+    def delete(key)
+      super(convert_key(key))
+    end
+
+    def stringify_keys!; self end
+    def deep_stringify_keys!; self end
+    def stringify_keys; dup end
+    def deep_stringify_keys; dup end
+    undef :symbolize_keys!
+    undef :deep_symbolize_keys!
+    def symbolize_keys; to_hash.symbolize_keys! end
+    def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
+    def to_options!; self end
+
+    def select(*args, &block)
+      dup.tap { |hash| hash.select!(*args, &block) }
+    end
+
+    def reject(*args, &block)
+      dup.tap { |hash| hash.reject!(*args, &block) }
+    end
+
+    # Convert to a regular hash with string keys.
+    def to_hash
+      _new_hash= {}
+      each do |key, value|
+        _new_hash[convert_key(key)] = convert_value(value, for: :to_hash)
+      end
+      Hash.new(default).merge!(_new_hash)
+    end
+
+    protected
+      def convert_key(key)
+        key.kind_of?(Symbol) ? key.to_s : key
+      end
+
+      def convert_value(value, options = {})
+        if value.is_a? Hash
+          if options[:for] == :to_hash
+            value.to_hash
+          else
+            value.nested_under_indifferent_access
+          end
+        elsif value.is_a?(Array)
+          unless options[:for] == :assignment
+            value = value.dup
+          end
+          value.map! { |e| convert_value(e, options) }
+        else
+          value
+        end
+      end
+  end
+end
+
+HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
diff --git a/app/server/vendor/activesupport/lib/active_support/i18n.rb b/app/server/vendor/activesupport/lib/active_support/i18n.rb
new file mode 100644
index 0000000..6cc9819
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/i18n.rb
@@ -0,0 +1,13 @@
+require 'active_support/core_ext/hash/deep_merge'
+require 'active_support/core_ext/hash/except'
+require 'active_support/core_ext/hash/slice'
+begin
+  require 'i18n'
+rescue LoadError => e
+  $stderr.puts "The i18n gem is not available. Please add it to your Gemfile and run bundle install"
+  raise e
+end
+require 'active_support/lazy_load_hooks'
+
+ActiveSupport.run_load_hooks(:i18n)
+I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
diff --git a/app/server/vendor/activesupport/lib/active_support/i18n_railtie.rb b/app/server/vendor/activesupport/lib/active_support/i18n_railtie.rb
new file mode 100644
index 0000000..23cd671
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/i18n_railtie.rb
@@ -0,0 +1,96 @@
+require "active_support"
+require "active_support/file_update_checker"
+require "active_support/core_ext/array/wrap"
+
+module I18n
+  class Railtie < Rails::Railtie
+    config.i18n = ActiveSupport::OrderedOptions.new
+    config.i18n.railties_load_path = []
+    config.i18n.load_path = []
+    config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
+    # Enforce I18n to check the available locales when setting a locale.
+    config.i18n.enforce_available_locales = true
+
+    # Set the i18n configuration after initialization since a lot of
+    # configuration is still usually done in application initializers.
+    config.after_initialize do |app|
+      I18n::Railtie.initialize_i18n(app)
+    end
+
+    # Trigger i18n config before any eager loading has happened
+    # so it's ready if any classes require it when eager loaded.
+    config.before_eager_load do |app|
+      I18n::Railtie.initialize_i18n(app)
+    end
+
+  protected
+
+    @i18n_inited = false
+
+    # Setup i18n configuration.
+    def self.initialize_i18n(app)
+      return if @i18n_inited
+
+      fallbacks = app.config.i18n.delete(:fallbacks)
+
+      # Avoid issues with setting the default_locale by disabling available locales
+      # check while configuring.
+      enforce_available_locales = app.config.i18n.delete(:enforce_available_locales)
+      enforce_available_locales = I18n.enforce_available_locales unless I18n.enforce_available_locales.nil?
+      I18n.enforce_available_locales = false
+
+      app.config.i18n.each do |setting, value|
+        case setting
+        when :railties_load_path
+          app.config.i18n.load_path.unshift(*value)
+        when :load_path
+          I18n.load_path += value
+        else
+          I18n.send("#{setting}=", value)
+        end
+      end
+
+      init_fallbacks(fallbacks) if fallbacks && validate_fallbacks(fallbacks)
+
+      # Restore available locales check so it will take place from now on.
+      I18n.enforce_available_locales = enforce_available_locales
+
+      reloader = ActiveSupport::FileUpdateChecker.new(I18n.load_path.dup){ I18n.reload! }
+      app.reloaders << reloader
+      ActionDispatch::Reloader.to_prepare { reloader.execute_if_updated }
+      reloader.execute
+
+      @i18n_inited = true
+    end
+
+    def self.include_fallbacks_module
+      I18n.backend.class.send(:include, I18n::Backend::Fallbacks)
+    end
+
+    def self.init_fallbacks(fallbacks)
+      include_fallbacks_module
+
+      args = case fallbacks
+      when ActiveSupport::OrderedOptions
+        [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
+      when Hash, Array
+        Array.wrap(fallbacks)
+      else # TrueClass
+        []
+      end
+
+      I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
+    end
+
+    def self.validate_fallbacks(fallbacks)
+      case fallbacks
+      when ActiveSupport::OrderedOptions
+        !fallbacks.empty?
+      when TrueClass, Array, Hash
+        true
+      else
+        raise "Unexpected fallback type #{fallbacks.inspect}"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/inflections.rb b/app/server/vendor/activesupport/lib/active_support/inflections.rb
new file mode 100644
index 0000000..2ca1124
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/inflections.rb
@@ -0,0 +1,70 @@
+require 'active_support/inflector/inflections'
+
+#--
+# Defines the standard inflection rules. These are the starting point for
+# new projects and are not considered complete. The current set of inflection
+# rules is frozen. This means, we do not change them to become more complete.
+# This is a safety measure to keep existing applications from breaking.
+#++
+module ActiveSupport
+  Inflector.inflections(:en) do |inflect|
+    inflect.plural(/$/, 's')
+    inflect.plural(/s$/i, 's')
+    inflect.plural(/^(ax|test)is$/i, '\1es')
+    inflect.plural(/(octop|vir)us$/i, '\1i')
+    inflect.plural(/(octop|vir)i$/i, '\1i')
+    inflect.plural(/(alias|status)$/i, '\1es')
+    inflect.plural(/(bu)s$/i, '\1ses')
+    inflect.plural(/(buffal|tomat)o$/i, '\1oes')
+    inflect.plural(/([ti])um$/i, '\1a')
+    inflect.plural(/([ti])a$/i, '\1a')
+    inflect.plural(/sis$/i, 'ses')
+    inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
+    inflect.plural(/(hive)$/i, '\1s')
+    inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
+    inflect.plural(/(x|ch|ss|sh)$/i, '\1es')
+    inflect.plural(/(matr|vert|ind)(?:ix|ex)$/i, '\1ices')
+    inflect.plural(/^(m|l)ouse$/i, '\1ice')
+    inflect.plural(/^(m|l)ice$/i, '\1ice')
+    inflect.plural(/^(ox)$/i, '\1en')
+    inflect.plural(/^(oxen)$/i, '\1')
+    inflect.plural(/(quiz)$/i, '\1zes')
+
+    inflect.singular(/s$/i, '')
+    inflect.singular(/(ss)$/i, '\1')
+    inflect.singular(/(n)ews$/i, '\1ews')
+    inflect.singular(/([ti])a$/i, '\1um')
+    inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '\1sis')
+    inflect.singular(/(^analy)(sis|ses)$/i, '\1sis')
+    inflect.singular(/([^f])ves$/i, '\1fe')
+    inflect.singular(/(hive)s$/i, '\1')
+    inflect.singular(/(tive)s$/i, '\1')
+    inflect.singular(/([lr])ves$/i, '\1f')
+    inflect.singular(/([^aeiouy]|qu)ies$/i, '\1y')
+    inflect.singular(/(s)eries$/i, '\1eries')
+    inflect.singular(/(m)ovies$/i, '\1ovie')
+    inflect.singular(/(x|ch|ss|sh)es$/i, '\1')
+    inflect.singular(/^(m|l)ice$/i, '\1ouse')
+    inflect.singular(/(bus)(es)?$/i, '\1')
+    inflect.singular(/(o)es$/i, '\1')
+    inflect.singular(/(shoe)s$/i, '\1')
+    inflect.singular(/(cris|test)(is|es)$/i, '\1is')
+    inflect.singular(/^(a)x[ie]s$/i, '\1xis')
+    inflect.singular(/(octop|vir)(us|i)$/i, '\1us')
+    inflect.singular(/(alias|status)(es)?$/i, '\1')
+    inflect.singular(/^(ox)en/i, '\1')
+    inflect.singular(/(vert|ind)ices$/i, '\1ex')
+    inflect.singular(/(matr)ices$/i, '\1ix')
+    inflect.singular(/(quiz)zes$/i, '\1')
+    inflect.singular(/(database)s$/i, '\1')
+
+    inflect.irregular('person', 'people')
+    inflect.irregular('man', 'men')
+    inflect.irregular('child', 'children')
+    inflect.irregular('sex', 'sexes')
+    inflect.irregular('move', 'moves')
+    inflect.irregular('zombie', 'zombies')
+
+    inflect.uncountable(%w(equipment information rice money species series fish sheep jeans police))
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/inflector.rb b/app/server/vendor/activesupport/lib/active_support/inflector.rb
new file mode 100644
index 0000000..215a60e
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/inflector.rb
@@ -0,0 +1,7 @@
+# in case active_support/inflector is required without the rest of active_support
+require 'active_support/inflector/inflections'
+require 'active_support/inflector/transliterate'
+require 'active_support/inflector/methods'
+
+require 'active_support/inflections'
+require 'active_support/core_ext/string/inflections'
diff --git a/app/server/vendor/activesupport/lib/active_support/inflector/inflections.rb b/app/server/vendor/activesupport/lib/active_support/inflector/inflections.rb
new file mode 100644
index 0000000..eda0edf
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/inflector/inflections.rb
@@ -0,0 +1,211 @@
+require 'thread_safe'
+require 'active_support/core_ext/array/prepend_and_append'
+require 'active_support/i18n'
+
+module ActiveSupport
+  module Inflector
+    extend self
+
+    # A singleton instance of this class is yielded by Inflector.inflections,
+    # which can then be used to specify additional inflection rules. If passed
+    # an optional locale, rules for other languages can be specified. The
+    # default locale is <tt>:en</tt>. Only rules for English are provided.
+    #
+    #   ActiveSupport::Inflector.inflections(:en) do |inflect|
+    #     inflect.plural /^(ox)$/i, '\1\2en'
+    #     inflect.singular /^(ox)en/i, '\1'
+    #
+    #     inflect.irregular 'octopus', 'octopi'
+    #
+    #     inflect.uncountable 'equipment'
+    #   end
+    #
+    # New rules are added at the top. So in the example above, the irregular
+    # rule for octopus will now be the first of the pluralization and
+    # singularization rules that is runs. This guarantees that your rules run
+    # before any of the rules that may already have been loaded.
+    class Inflections
+      @__instance__ = ThreadSafe::Cache.new
+
+      def self.instance(locale = :en)
+        @__instance__[locale] ||= new
+      end
+
+      attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex
+
+      def initialize
+        @plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], [], [], {}, /(?=a)b/
+      end
+
+      # Private, for the test suite.
+      def initialize_dup(orig) # :nodoc:
+        %w(plurals singulars uncountables humans acronyms acronym_regex).each do |scope|
+          instance_variable_set("@#{scope}", orig.send(scope).dup)
+        end
+      end
+
+      # Specifies a new acronym. An acronym must be specified as it will appear
+      # in a camelized string. An underscore string that contains the acronym
+      # will retain the acronym when passed to +camelize+, +humanize+, or
+      # +titleize+. A camelized string that contains the acronym will maintain
+      # the acronym when titleized or humanized, and will convert the acronym
+      # into a non-delimited single lowercase word when passed to +underscore+.
+      #
+      #   acronym 'HTML'
+      #   titleize 'html'     # => 'HTML'
+      #   camelize 'html'     # => 'HTML'
+      #   underscore 'MyHTML' # => 'my_html'
+      #
+      # The acronym, however, must occur as a delimited unit and not be part of
+      # another word for conversions to recognize it:
+      #
+      #   acronym 'HTTP'
+      #   camelize 'my_http_delimited' # => 'MyHTTPDelimited'
+      #   camelize 'https'             # => 'Https', not 'HTTPs'
+      #   underscore 'HTTPS'           # => 'http_s', not 'https'
+      #
+      #   acronym 'HTTPS'
+      #   camelize 'https'   # => 'HTTPS'
+      #   underscore 'HTTPS' # => 'https'
+      #
+      # Note: Acronyms that are passed to +pluralize+ will no longer be
+      # recognized, since the acronym will not occur as a delimited unit in the
+      # pluralized result. To work around this, you must specify the pluralized
+      # form as an acronym as well:
+      #
+      #    acronym 'API'
+      #    camelize(pluralize('api')) # => 'Apis'
+      #
+      #    acronym 'APIs'
+      #    camelize(pluralize('api')) # => 'APIs'
+      #
+      # +acronym+ may be used to specify any word that contains an acronym or
+      # otherwise needs to maintain a non-standard capitalization. The only
+      # restriction is that the word must begin with a capital letter.
+      #
+      #   acronym 'RESTful'
+      #   underscore 'RESTful'           # => 'restful'
+      #   underscore 'RESTfulController' # => 'restful_controller'
+      #   titleize 'RESTfulController'   # => 'RESTful Controller'
+      #   camelize 'restful'             # => 'RESTful'
+      #   camelize 'restful_controller'  # => 'RESTfulController'
+      #
+      #   acronym 'McDonald'
+      #   underscore 'McDonald' # => 'mcdonald'
+      #   camelize 'mcdonald'   # => 'McDonald'
+      def acronym(word)
+        @acronyms[word.downcase] = word
+        @acronym_regex = /#{@acronyms.values.join("|")}/
+      end
+
+      # Specifies a new pluralization rule and its replacement. The rule can
+      # either be a string or a regular expression. The replacement should
+      # always be a string that may include references to the matched data from
+      # the rule.
+      def plural(rule, replacement)
+        @uncountables.delete(rule) if rule.is_a?(String)
+        @uncountables.delete(replacement)
+        @plurals.prepend([rule, replacement])
+      end
+
+      # Specifies a new singularization rule and its replacement. The rule can
+      # either be a string or a regular expression. The replacement should
+      # always be a string that may include references to the matched data from
+      # the rule.
+      def singular(rule, replacement)
+        @uncountables.delete(rule) if rule.is_a?(String)
+        @uncountables.delete(replacement)
+        @singulars.prepend([rule, replacement])
+      end
+
+      # Specifies a new irregular that applies to both pluralization and
+      # singularization at the same time. This can only be used for strings, not
+      # regular expressions. You simply pass the irregular in singular and
+      # plural form.
+      #
+      #   irregular 'octopus', 'octopi'
+      #   irregular 'person', 'people'
+      def irregular(singular, plural)
+        @uncountables.delete(singular)
+        @uncountables.delete(plural)
+
+        s0 = singular[0]
+        srest = singular[1..-1]
+
+        p0 = plural[0]
+        prest = plural[1..-1]
+
+        if s0.upcase == p0.upcase
+          plural(/(#{s0})#{srest}$/i, '\1' + prest)
+          plural(/(#{p0})#{prest}$/i, '\1' + prest)
+
+          singular(/(#{s0})#{srest}$/i, '\1' + srest)
+          singular(/(#{p0})#{prest}$/i, '\1' + srest)
+        else
+          plural(/#{s0.upcase}(?i)#{srest}$/,   p0.upcase   + prest)
+          plural(/#{s0.downcase}(?i)#{srest}$/, p0.downcase + prest)
+          plural(/#{p0.upcase}(?i)#{prest}$/,   p0.upcase   + prest)
+          plural(/#{p0.downcase}(?i)#{prest}$/, p0.downcase + prest)
+
+          singular(/#{s0.upcase}(?i)#{srest}$/,   s0.upcase   + srest)
+          singular(/#{s0.downcase}(?i)#{srest}$/, s0.downcase + srest)
+          singular(/#{p0.upcase}(?i)#{prest}$/,   s0.upcase   + srest)
+          singular(/#{p0.downcase}(?i)#{prest}$/, s0.downcase + srest)
+        end
+      end
+
+      # Add uncountable words that shouldn't be attempted inflected.
+      #
+      #   uncountable 'money'
+      #   uncountable 'money', 'information'
+      #   uncountable %w( money information rice )
+      def uncountable(*words)
+        (@uncountables << words).flatten!
+      end
+
+      # Specifies a humanized form of a string by a regular expression rule or
+      # by a string mapping. When using a regular expression based replacement,
+      # the normal humanize formatting is called after the replacement. When a
+      # string is used, the human form should be specified as desired (example:
+      # 'The name', not 'the_name').
+      #
+      #   human /_cnt$/i, '\1_count'
+      #   human 'legacy_col_person_name', 'Name'
+      def human(rule, replacement)
+        @humans.prepend([rule, replacement])
+      end
+
+      # Clears the loaded inflections within a given scope (default is
+      # <tt>:all</tt>). Give the scope as a symbol of the inflection type, the
+      # options are: <tt>:plurals</tt>, <tt>:singulars</tt>, <tt>:uncountables</tt>,
+      # <tt>:humans</tt>.
+      #
+      #   clear :all
+      #   clear :plurals
+      def clear(scope = :all)
+        case scope
+          when :all
+            @plurals, @singulars, @uncountables, @humans = [], [], [], []
+          else
+            instance_variable_set "@#{scope}", []
+        end
+      end
+    end
+
+    # Yields a singleton instance of Inflector::Inflections so you can specify
+    # additional inflector rules. If passed an optional locale, rules for other
+    # languages can be specified. If not specified, defaults to <tt>:en</tt>.
+    # Only rules for English are provided.
+    #
+    #   ActiveSupport::Inflector.inflections(:en) do |inflect|
+    #     inflect.uncountable 'rails'
+    #   end
+    def inflections(locale = :en)
+      if block_given?
+        yield Inflections.instance(locale)
+      else
+        Inflections.instance(locale)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/inflector/methods.rb b/app/server/vendor/activesupport/lib/active_support/inflector/methods.rb
new file mode 100644
index 0000000..a270c44
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/inflector/methods.rb
@@ -0,0 +1,360 @@
+# encoding: utf-8
+
+require 'active_support/inflections'
+
+module ActiveSupport
+  # The Inflector transforms words from singular to plural, class names to table
+  # names, modularized class names to ones without, and class names to foreign
+  # keys. The default inflections for pluralization, singularization, and
+  # uncountable words are kept in inflections.rb.
+  #
+  # The Rails core team has stated patches for the inflections library will not
+  # be accepted in order to avoid breaking legacy applications which may be
+  # relying on errant inflections. If you discover an incorrect inflection and
+  # require it for your application or wish to define rules for languages other
+  # than English, please correct or add them yourself (explained below).
+  module Inflector
+    extend self
+
+    # Returns the plural form of the word in the string.
+    #
+    # If passed an optional +locale+ parameter, the word will be
+    # pluralized using rules defined for that language. By default,
+    # this parameter is set to <tt>:en</tt>.
+    #
+    #   'post'.pluralize             # => "posts"
+    #   'octopus'.pluralize          # => "octopi"
+    #   'sheep'.pluralize            # => "sheep"
+    #   'words'.pluralize            # => "words"
+    #   'CamelOctopus'.pluralize     # => "CamelOctopi"
+    #   'ley'.pluralize(:es)         # => "leyes"
+    def pluralize(word, locale = :en)
+      apply_inflections(word, inflections(locale).plurals)
+    end
+
+    # The reverse of +pluralize+, returns the singular form of a word in a
+    # string.
+    #
+    # If passed an optional +locale+ parameter, the word will be
+    # singularized using rules defined for that language. By default,
+    # this parameter is set to <tt>:en</tt>.
+    #
+    #   'posts'.singularize            # => "post"
+    #   'octopi'.singularize           # => "octopus"
+    #   'sheep'.singularize            # => "sheep"
+    #   'word'.singularize             # => "word"
+    #   'CamelOctopi'.singularize      # => "CamelOctopus"
+    #   'leyes'.singularize(:es)       # => "ley"
+    def singularize(word, locale = :en)
+      apply_inflections(word, inflections(locale).singulars)
+    end
+
+    # By default, +camelize+ converts strings to UpperCamelCase. If the argument
+    # to +camelize+ is set to <tt>:lower</tt> then +camelize+ produces
+    # lowerCamelCase.
+    #
+    # +camelize+ will also convert '/' to '::' which is useful for converting
+    # paths to namespaces.
+    #
+    #   'active_model'.camelize                # => "ActiveModel"
+    #   'active_model'.camelize(:lower)        # => "activeModel"
+    #   'active_model/errors'.camelize         # => "ActiveModel::Errors"
+    #   'active_model/errors'.camelize(:lower) # => "activeModel::Errors"
+    #
+    # As a rule of thumb you can think of +camelize+ as the inverse of
+    # +underscore+, though there are cases where that does not hold:
+    #
+    #   'SSLError'.underscore.camelize # => "SslError"
+    def camelize(term, uppercase_first_letter = true)
+      string = term.to_s
+      if uppercase_first_letter
+        string = string.sub(/^[a-z\d]*/) { inflections.acronyms[$&] || $&.capitalize }
+      else
+        string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
+      end
+      string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }
+      string.gsub!('/', '::')
+      string
+    end
+
+    # Makes an underscored, lowercase form from the expression in the string.
+    #
+    # Changes '::' to '/' to convert namespaces to paths.
+    #
+    #   'ActiveModel'.underscore         # => "active_model"
+    #   'ActiveModel::Errors'.underscore # => "active_model/errors"
+    #
+    # As a rule of thumb you can think of +underscore+ as the inverse of
+    # +camelize+, though there are cases where that does not hold:
+    #
+    #   'SSLError'.underscore.camelize # => "SslError"
+    def underscore(camel_cased_word)
+      return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/
+      word = camel_cased_word.to_s.gsub('::', '/')
+      word.gsub!(/(?:([A-Za-z\d])|^)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
+      word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
+      word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
+      word.tr!("-", "_")
+      word.downcase!
+      word
+    end
+
+    # Capitalizes the first word, turns underscores into spaces, and strips a
+    # trailing '_id' if present.
+    # Like +titleize+, this is meant for creating pretty output.
+    #
+    # The capitalization of the first word can be turned off by setting the
+    # optional parameter +capitalize+ to false.
+    # By default, this parameter is true.
+    #
+    #   humanize('employee_salary')              # => "Employee salary"
+    #   humanize('author_id')                    # => "Author"
+    #   humanize('author_id', capitalize: false) # => "author"
+    def humanize(lower_case_and_underscored_word, options = {})
+      result = lower_case_and_underscored_word.to_s.dup
+      inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
+      result.gsub!(/_id$/, "")
+      result.tr!('_', ' ')
+      result.gsub!(/([a-z\d]*)/i) { |match|
+        "#{inflections.acronyms[match] || match.downcase}"
+      }
+      result.gsub!(/^\w/) { |match| match.upcase } if options.fetch(:capitalize, true)
+      result
+    end
+
+    # Capitalizes all the words and replaces some characters in the string to
+    # create a nicer looking title. +titleize+ is meant for creating pretty
+    # output. It is not used in the Rails internals.
+    #
+    # +titleize+ is also aliased as +titlecase+.
+    #
+    #   'man from the boondocks'.titleize   # => "Man From The Boondocks"
+    #   'x-men: the last stand'.titleize    # => "X Men: The Last Stand"
+    #   'TheManWithoutAPast'.titleize       # => "The Man Without A Past"
+    #   'raiders_of_the_lost_ark'.titleize  # => "Raiders Of The Lost Ark"
+    def titleize(word)
+      humanize(underscore(word)).gsub(/\b(?<!['’`])[a-z]/) { $&.capitalize }
+    end
+
+    # Create the name of a table like Rails does for models to table names. This
+    # method uses the +pluralize+ method on the last word in the string.
+    #
+    #   'RawScaledScorer'.tableize # => "raw_scaled_scorers"
+    #   'egg_and_ham'.tableize     # => "egg_and_hams"
+    #   'fancyCategory'.tableize   # => "fancy_categories"
+    def tableize(class_name)
+      pluralize(underscore(class_name))
+    end
+
+    # Create a class name from a plural table name like Rails does for table
+    # names to models. Note that this returns a string and not a Class (To
+    # convert to an actual class follow +classify+ with +constantize+).
+    #
+    #   'egg_and_hams'.classify # => "EggAndHam"
+    #   'posts'.classify        # => "Post"
+    #
+    # Singular names are not handled correctly:
+    #
+    #   'business'.classify     # => "Busines"
+    def classify(table_name)
+      # strip out any leading schema name
+      camelize(singularize(table_name.to_s.sub(/.*\./, '')))
+    end
+
+    # Replaces underscores with dashes in the string.
+    #
+    #   'puni_puni'.dasherize # => "puni-puni"
+    def dasherize(underscored_word)
+      underscored_word.tr('_', '-')
+    end
+
+    # Removes the module part from the expression in the string.
+    #
+    #   'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections"
+    #   'Inflections'.demodulize                                       # => "Inflections"
+    #
+    # See also +deconstantize+.
+    def demodulize(path)
+      path = path.to_s
+      if i = path.rindex('::')
+        path[(i+2)..-1]
+      else
+        path
+      end
+    end
+
+    # Removes the rightmost segment from the constant expression in the string.
+    #
+    #   'Net::HTTP'.deconstantize   # => "Net"
+    #   '::Net::HTTP'.deconstantize # => "::Net"
+    #   'String'.deconstantize      # => ""
+    #   '::String'.deconstantize    # => ""
+    #   ''.deconstantize            # => ""
+    #
+    # See also +demodulize+.
+    def deconstantize(path)
+      path.to_s[0, path.rindex('::') || 0] # implementation based on the one in facets' Module#spacename
+    end
+
+    # Creates a foreign key name from a class name.
+    # +separate_class_name_and_id_with_underscore+ sets whether
+    # the method should put '_' between the name and 'id'.
+    #
+    #   'Message'.foreign_key        # => "message_id"
+    #   'Message'.foreign_key(false) # => "messageid"
+    #   'Admin::Post'.foreign_key    # => "post_id"
+    def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
+      underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
+    end
+
+    # Tries to find a constant with the name specified in the argument string.
+    #
+    #   'Module'.constantize     # => Module
+    #   'Test::Unit'.constantize # => Test::Unit
+    #
+    # The name is assumed to be the one of a top-level constant, no matter
+    # whether it starts with "::" or not. No lexical context is taken into
+    # account:
+    #
+    #   C = 'outside'
+    #   module M
+    #     C = 'inside'
+    #     C               # => 'inside'
+    #     'C'.constantize # => 'outside', same as ::C
+    #   end
+    #
+    # NameError is raised when the name is not in CamelCase or the constant is
+    # unknown.
+    def constantize(camel_cased_word)
+      names = camel_cased_word.split('::')
+
+      # Trigger a builtin NameError exception including the ill-formed constant in the message.
+      Object.const_get(camel_cased_word) if names.empty?
+
+      # Remove the first blank element in case of '::ClassName' notation.
+      names.shift if names.size > 1 && names.first.empty?
+
+      names.inject(Object) do |constant, name|
+        if constant == Object
+          constant.const_get(name)
+        else
+          candidate = constant.const_get(name)
+          next candidate if constant.const_defined?(name, false)
+          next candidate unless Object.const_defined?(name)
+
+          # Go down the ancestors to check it it's owned
+          # directly before we reach Object or the end of ancestors.
+          constant = constant.ancestors.inject do |const, ancestor|
+            break const    if ancestor == Object
+            break ancestor if ancestor.const_defined?(name, false)
+            const
+          end
+
+          # owner is in Object, so raise
+          constant.const_get(name, false)
+        end
+      end
+    end
+
+    # Tries to find a constant with the name specified in the argument string.
+    #
+    #   'Module'.safe_constantize     # => Module
+    #   'Test::Unit'.safe_constantize # => Test::Unit
+    #
+    # The name is assumed to be the one of a top-level constant, no matter
+    # whether it starts with "::" or not. No lexical context is taken into
+    # account:
+    #
+    #   C = 'outside'
+    #   module M
+    #     C = 'inside'
+    #     C                    # => 'inside'
+    #     'C'.safe_constantize # => 'outside', same as ::C
+    #   end
+    #
+    # +nil+ is returned when the name is not in CamelCase or the constant (or
+    # part of it) is unknown.
+    #
+    #   'blargle'.safe_constantize  # => nil
+    #   'UnknownModule'.safe_constantize  # => nil
+    #   'UnknownModule::Foo::Bar'.safe_constantize  # => nil
+    def safe_constantize(camel_cased_word)
+      constantize(camel_cased_word)
+    rescue NameError => e
+      raise unless e.message =~ /(uninitialized constant|wrong constant name) #{const_regexp(camel_cased_word)}$/ ||
+        e.name.to_s == camel_cased_word.to_s
+    rescue ArgumentError => e
+      raise unless e.message =~ /not missing constant #{const_regexp(camel_cased_word)}\!$/
+    end
+
+    # Returns the suffix that should be added to a number to denote the position
+    # in an ordered sequence such as 1st, 2nd, 3rd, 4th.
+    #
+    #   ordinal(1)     # => "st"
+    #   ordinal(2)     # => "nd"
+    #   ordinal(1002)  # => "nd"
+    #   ordinal(1003)  # => "rd"
+    #   ordinal(-11)   # => "th"
+    #   ordinal(-1021) # => "st"
+    def ordinal(number)
+      abs_number = number.to_i.abs
+
+      if (11..13).include?(abs_number % 100)
+        "th"
+      else
+        case abs_number % 10
+          when 1; "st"
+          when 2; "nd"
+          when 3; "rd"
+          else    "th"
+        end
+      end
+    end
+
+    # Turns a number into an ordinal string used to denote the position in an
+    # ordered sequence such as 1st, 2nd, 3rd, 4th.
+    #
+    #   ordinalize(1)     # => "1st"
+    #   ordinalize(2)     # => "2nd"
+    #   ordinalize(1002)  # => "1002nd"
+    #   ordinalize(1003)  # => "1003rd"
+    #   ordinalize(-11)   # => "-11th"
+    #   ordinalize(-1021) # => "-1021st"
+    def ordinalize(number)
+      "#{number}#{ordinal(number)}"
+    end
+
+    private
+
+    # Mount a regular expression that will match part by part of the constant.
+    #
+    #   const_regexp("Foo::Bar::Baz") # => /Foo(::Bar(::Baz)?)?/
+    #   const_regexp("::")            # => /::/
+    def const_regexp(camel_cased_word) #:nodoc:
+      parts = camel_cased_word.split("::")
+
+      return Regexp.escape(camel_cased_word) if parts.blank?
+
+      last  = parts.pop
+
+      parts.reverse.inject(last) do |acc, part|
+        part.empty? ? acc : "#{part}(::#{acc})?"
+      end
+    end
+
+    # Applies inflection rules for +singularize+ and +pluralize+.
+    #
+    #  apply_inflections('post', inflections.plurals)    # => "posts"
+    #  apply_inflections('posts', inflections.singulars) # => "post"
+    def apply_inflections(word, rules)
+      result = word.to_s.dup
+
+      if word.empty? || inflections.uncountables.include?(result.downcase[/\b\w+\Z/])
+        result
+      else
+        rules.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
+        result
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/inflector/transliterate.rb b/app/server/vendor/activesupport/lib/active_support/inflector/transliterate.rb
new file mode 100644
index 0000000..1cde417
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/inflector/transliterate.rb
@@ -0,0 +1,97 @@
+# encoding: utf-8
+require 'active_support/core_ext/string/multibyte'
+require 'active_support/i18n'
+
+module ActiveSupport
+  module Inflector
+
+    # Replaces non-ASCII characters with an ASCII approximation, or if none
+    # exists, a replacement character which defaults to "?".
+    #
+    #    transliterate('Ærøskøbing')
+    #    # => "AEroskobing"
+    #
+    # Default approximations are provided for Western/Latin characters,
+    # e.g, "ø", "ñ", "é", "ß", etc.
+    #
+    # This method is I18n aware, so you can set up custom approximations for a
+    # locale. This can be useful, for example, to transliterate German's "ü"
+    # and "ö" to "ue" and "oe", or to add support for transliterating Russian
+    # to ASCII.
+    #
+    # In order to make your custom transliterations available, you must set
+    # them as the <tt>i18n.transliterate.rule</tt> i18n key:
+    #
+    #   # Store the transliterations in locales/de.yml
+    #   i18n:
+    #     transliterate:
+    #       rule:
+    #         ü: "ue"
+    #         ö: "oe"
+    #
+    #   # Or set them using Ruby
+    #   I18n.backend.store_translations(:de, i18n: {
+    #     transliterate: {
+    #       rule: {
+    #         'ü' => 'ue',
+    #         'ö' => 'oe'
+    #       }
+    #     }
+    #   })
+    #
+    # The value for <tt>i18n.transliterate.rule</tt> can be a simple Hash that
+    # maps characters to ASCII approximations as shown above, or, for more
+    # complex requirements, a Proc:
+    #
+    #   I18n.backend.store_translations(:de, i18n: {
+    #     transliterate: {
+    #       rule: ->(string) { MyTransliterator.transliterate(string) }
+    #     }
+    #   })
+    #
+    # Now you can have different transliterations for each locale:
+    #
+    #   I18n.locale = :en
+    #   transliterate('Jürgen')
+    #   # => "Jurgen"
+    #
+    #   I18n.locale = :de
+    #   transliterate('Jürgen')
+    #   # => "Juergen"
+    def transliterate(string, replacement = "?")
+      I18n.transliterate(ActiveSupport::Multibyte::Unicode.normalize(
+        ActiveSupport::Multibyte::Unicode.tidy_bytes(string), :c),
+          :replacement => replacement)
+    end
+
+    # Replaces special characters in a string so that it may be used as part of
+    # a 'pretty' URL.
+    #
+    #   class Person
+    #     def to_param
+    #       "#{id}-#{name.parameterize}"
+    #     end
+    #   end
+    #
+    #   @person = Person.find(1)
+    #   # => #<Person id: 1, name: "Donald E. Knuth">
+    #
+    #   <%= link_to(@person.name, person_path(@person)) %>
+    #   # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
+    def parameterize(string, sep = '-')
+      # replace accented chars with their ascii equivalents
+      parameterized_string = transliterate(string)
+      # Turn unwanted chars into the separator
+      parameterized_string.gsub!(/[^a-z0-9\-_]+/i, sep)
+      unless sep.nil? || sep.empty?
+        re_sep = Regexp.escape(sep)
+        # No more than one of the separator in a row.
+        parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
+        # Remove leading/trailing separator.
+        parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '')
+      end
+      parameterized_string.downcase
+    end
+
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/json.rb b/app/server/vendor/activesupport/lib/active_support/json.rb
new file mode 100644
index 0000000..3e1d9b1
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/json.rb
@@ -0,0 +1,2 @@
+require 'active_support/json/decoding'
+require 'active_support/json/encoding'
diff --git a/app/server/vendor/activesupport/lib/active_support/json/decoding.rb b/app/server/vendor/activesupport/lib/active_support/json/decoding.rb
new file mode 100644
index 0000000..8b5fc70
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/json/decoding.rb
@@ -0,0 +1,73 @@
+require 'active_support/core_ext/module/attribute_accessors'
+require 'active_support/core_ext/module/delegation'
+require 'json'
+
+module ActiveSupport
+  # Look for and parse json strings that look like ISO 8601 times.
+  mattr_accessor :parse_json_times
+
+  module JSON
+    # matches YAML-formatted dates
+    DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/
+    
+    class << self
+      # Parses a JSON string (JavaScript Object Notation) into a hash.
+      # See www.json.org for more info.
+      #
+      #   ActiveSupport::JSON.decode("{\"team\":\"rails\",\"players\":\"36\"}")
+      #   => {"team" => "rails", "players" => "36"}
+      def decode(json, options = {})
+        if options.present?
+          raise ArgumentError, "In Rails 4.1, ActiveSupport::JSON.decode no longer " \
+            "accepts an options hash for MultiJSON. MultiJSON reached its end of life " \
+            "and has been removed."
+        end
+
+        data = ::JSON.parse(json, quirks_mode: true)
+
+        if ActiveSupport.parse_json_times
+          convert_dates_from(data)
+        else
+          data
+        end
+      end
+
+      # Returns the class of the error that will be raised when there is an
+      # error in decoding JSON. Using this method means you won't directly
+      # depend on the ActiveSupport's JSON implementation, in case it changes
+      # in the future.
+      #
+      #   begin
+      #     obj = ActiveSupport::JSON.decode(some_string)
+      #   rescue ActiveSupport::JSON.parse_error
+      #     Rails.logger.warn("Attempted to decode invalid JSON: #{some_string}")
+      #   end
+      def parse_error
+        ::JSON::ParserError
+      end
+
+      private
+
+      def convert_dates_from(data)
+        case data
+        when nil
+          nil
+        when DATE_REGEX
+          begin
+            DateTime.parse(data)
+          rescue ArgumentError
+            data
+          end
+        when Array
+          data.map! { |d| convert_dates_from(d) }
+        when Hash
+          data.each do |key, value|
+            data[key] = convert_dates_from(value)
+          end
+        else
+          data
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/json/encoding.rb b/app/server/vendor/activesupport/lib/active_support/json/encoding.rb
new file mode 100644
index 0000000..f29d422
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/json/encoding.rb
@@ -0,0 +1,172 @@
+require 'active_support/core_ext/object/json'
+require 'active_support/core_ext/module/delegation'
+
+module ActiveSupport
+  class << self
+    delegate :use_standard_json_time_format, :use_standard_json_time_format=,
+      :time_precision, :time_precision=,
+      :escape_html_entities_in_json, :escape_html_entities_in_json=,
+      :encode_big_decimal_as_string, :encode_big_decimal_as_string=,
+      :json_encoder, :json_encoder=,
+      :to => :'ActiveSupport::JSON::Encoding'
+  end
+
+  module JSON
+    # Dumps objects in JSON (JavaScript Object Notation).
+    # See www.json.org for more info.
+    #
+    #   ActiveSupport::JSON.encode({ team: 'rails', players: '36' })
+    #   # => "{\"team\":\"rails\",\"players\":\"36\"}"
+    def self.encode(value, options = nil)
+      Encoding.json_encoder.new(options).encode(value)
+    end
+
+    module Encoding #:nodoc:
+      class JSONGemEncoder #:nodoc:
+        attr_reader :options
+
+        def initialize(options = nil)
+          @options = options || {}
+        end
+
+        # Encode the given object into a JSON string
+        def encode(value)
+          stringify jsonify value.as_json(options.dup)
+        end
+
+        private
+          # Rails does more escaping than the JSON gem natively does (we
+          # escape \u2028 and \u2029 and optionally >, <, & to work around
+          # certain browser problems).
+          ESCAPED_CHARS = {
+            "\u2028" => '\u2028',
+            "\u2029" => '\u2029',
+            '>'      => '\u003e',
+            '<'      => '\u003c',
+            '&'      => '\u0026',
+            }
+
+          ESCAPE_REGEX_WITH_HTML_ENTITIES = /[\u2028\u2029><&]/u
+          ESCAPE_REGEX_WITHOUT_HTML_ENTITIES = /[\u2028\u2029]/u
+
+          # This class wraps all the strings we see and does the extra escaping
+          class EscapedString < String #:nodoc:
+            def to_json(*)
+              if Encoding.escape_html_entities_in_json
+                super.gsub ESCAPE_REGEX_WITH_HTML_ENTITIES, ESCAPED_CHARS
+              else
+                super.gsub ESCAPE_REGEX_WITHOUT_HTML_ENTITIES, ESCAPED_CHARS
+              end
+            end
+          end
+
+          # Mark these as private so we don't leak encoding-specific constructs
+          private_constant :ESCAPED_CHARS, :ESCAPE_REGEX_WITH_HTML_ENTITIES,
+            :ESCAPE_REGEX_WITHOUT_HTML_ENTITIES, :EscapedString
+
+          # Convert an object into a "JSON-ready" representation composed of
+          # primitives like Hash, Array, String, Numeric, and true/false/nil.
+          # Recursively calls #as_json to the object to recursively build a
+          # fully JSON-ready object.
+          #
+          # This allows developers to implement #as_json without having to
+          # worry about what base types of objects they are allowed to return
+          # or having to remember to call #as_json recursively.
+          #
+          # Note: the +options+ hash passed to +object.to_json+ is only passed
+          # to +object.as_json+, not any of this method's recursive +#as_json+
+          # calls.
+          def jsonify(value)
+            case value
+            when String
+              EscapedString.new(value)
+            when Numeric, NilClass, TrueClass, FalseClass
+              value
+            when Hash
+              Hash[value.map { |k, v| [jsonify(k), jsonify(v)] }]
+            when Array
+              value.map { |v| jsonify(v) }
+            else
+              jsonify value.as_json
+            end
+          end
+
+          # Encode a "jsonified" Ruby data structure using the JSON gem
+          def stringify(jsonified)
+            ::JSON.generate(jsonified, quirks_mode: true, max_nesting: false)
+          end
+      end
+
+      class << self
+        # If true, use ISO 8601 format for dates and times. Otherwise, fall back
+        # to the Active Support legacy format.
+        attr_accessor :use_standard_json_time_format
+
+        # If true, encode >, <, & as escaped unicode sequences (e.g. > as \u003e)
+        # as a safety measure.
+        attr_accessor :escape_html_entities_in_json
+
+        # Sets the precision of encoded time values.
+        # Defaults to 3 (equivalent to millisecond precision)
+        attr_accessor :time_precision
+
+        # Sets the encoder used by Rails to encode Ruby objects into JSON strings
+        # in +Object#to_json+ and +ActiveSupport::JSON.encode+.
+        attr_accessor :json_encoder
+
+        def encode_big_decimal_as_string=(as_string)
+          message = \
+            "The JSON encoder in Rails 4.1 no longer supports encoding BigDecimals as JSON numbers. Instead, " \
+            "the new encoder will always encode them as strings.\n\n" \
+            "You are seeing this error because you have 'active_support.encode_big_decimal_as_string' in " \
+            "your configuration file. If you have been setting this to true, you can safely remove it from " \
+            "your configuration. Otherwise, you should add the 'activesupport-json_encoder' gem to your " \
+            "Gemfile in order to restore this functionality."
+
+          raise NotImplementedError, message
+        end
+
+        def encode_big_decimal_as_string
+          message = \
+            "The JSON encoder in Rails 4.1 no longer supports encoding BigDecimals as JSON numbers. Instead, " \
+            "the new encoder will always encode them as strings.\n\n" \
+            "You are seeing this error because you are trying to check the value of the related configuration, " \
+            "'active_support.encode_big_decimal_as_string'. If your application depends on this option, you should " \
+            "add the 'activesupport-json_encoder' gem to your Gemfile. For now, this option will always be true. " \
+            "In the future, it will be removed from Rails, so you should stop checking its value."
+
+          ActiveSupport::Deprecation.warn message
+
+          true
+        end
+
+        # Deprecate CircularReferenceError
+        def const_missing(name)
+          if name == :CircularReferenceError
+            message = "The JSON encoder in Rails 4.1 no longer offers protection from circular references. " \
+                      "You are seeing this warning because you are rescuing from (or otherwise referencing) " \
+                      "ActiveSupport::Encoding::CircularReferenceError. In the future, this error will be " \
+                      "removed from Rails. You should remove these rescue blocks from your code and ensure " \
+                      "that your data structures are free of circular references so they can be properly " \
+                      "serialized into JSON.\n\n" \
+                      "For example, the following Hash contains a circular reference to itself:\n" \
+                      "   h = {}\n" \
+                      "   h['circular'] = h\n" \
+                      "In this case, calling h.to_json would not work properly."
+
+            ActiveSupport::Deprecation.warn message
+
+            SystemStackError
+          else
+            super
+          end
+        end
+      end
+
+      self.use_standard_json_time_format = true
+      self.escape_html_entities_in_json  = true
+      self.json_encoder = JSONGemEncoder
+      self.time_precision = 3
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/key_generator.rb b/app/server/vendor/activesupport/lib/active_support/key_generator.rb
new file mode 100644
index 0000000..51d2da3
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/key_generator.rb
@@ -0,0 +1,73 @@
+require 'thread_safe'
+require 'openssl'
+
+module ActiveSupport
+  # KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2
+  # It can be used to derive a number of keys for various purposes from a given secret.
+  # This lets Rails applications have a single secure secret, but avoid reusing that
+  # key in multiple incompatible contexts.
+  class KeyGenerator
+    def initialize(secret, options = {})
+      @secret = secret
+      # The default iterations are higher than required for our key derivation uses
+      # on the off chance someone uses this for password storage
+      @iterations = options[:iterations] || 2**16
+    end
+
+    # Returns a derived key suitable for use.  The default key_size is chosen
+    # to be compatible with the default settings of ActiveSupport::MessageVerifier.
+    # i.e. OpenSSL::Digest::SHA1#block_length
+    def generate_key(salt, key_size=64)
+      OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size)
+    end
+  end
+
+  # CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid
+  # re-executing the key generation process when it's called using the same salt and
+  # key_size
+  class CachingKeyGenerator
+    def initialize(key_generator)
+      @key_generator = key_generator
+      @cache_keys = ThreadSafe::Cache.new
+    end
+
+    # Returns a derived key suitable for use.  The default key_size is chosen
+    # to be compatible with the default settings of ActiveSupport::MessageVerifier.
+    # i.e. OpenSSL::Digest::SHA1#block_length
+    def generate_key(salt, key_size=64)
+      @cache_keys["#{salt}#{key_size}"] ||= @key_generator.generate_key(salt, key_size)
+    end
+  end
+
+  class LegacyKeyGenerator # :nodoc:
+    SECRET_MIN_LENGTH = 30 # Characters
+
+    def initialize(secret)
+      ensure_secret_secure(secret)
+      @secret = secret
+    end
+
+    def generate_key(salt)
+      @secret
+    end
+
+    private
+
+    # To prevent users from using something insecure like "Password" we make sure that the
+    # secret they've provided is at least 30 characters in length.
+    def ensure_secret_secure(secret)
+      if secret.blank?
+        raise ArgumentError, "A secret is required to generate an integrity hash " \
+          "for cookie session data. Set a secret_key_base of at least " \
+          "#{SECRET_MIN_LENGTH} characters in config/secrets.yml."
+      end
+
+      if secret.length < SECRET_MIN_LENGTH
+        raise ArgumentError, "Secret should be something secure, " \
+          "like \"#{SecureRandom.hex(16)}\". The value you " \
+          "provided, \"#{secret}\", is shorter than the minimum length " \
+          "of #{SECRET_MIN_LENGTH} characters."
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/lazy_load_hooks.rb b/app/server/vendor/activesupport/lib/active_support/lazy_load_hooks.rb
new file mode 100644
index 0000000..e2b8f0f
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/lazy_load_hooks.rb
@@ -0,0 +1,48 @@
+module ActiveSupport
+  # lazy_load_hooks allows Rails to lazily load a lot of components and thus
+  # making the app boot faster. Because of this feature now there is no need to
+  # require <tt>ActiveRecord::Base</tt> at boot time purely to apply
+  # configuration. Instead a hook is registered that applies configuration once
+  # <tt>ActiveRecord::Base</tt> is loaded. Here <tt>ActiveRecord::Base</tt> is
+  # used as example but this feature can be applied elsewhere too.
+  #
+  # Here is an example where +on_load+ method is called to register a hook.
+  #
+  #   initializer 'active_record.initialize_timezone' do
+  #     ActiveSupport.on_load(:active_record) do
+  #       self.time_zone_aware_attributes = true
+  #       self.default_timezone = :utc
+  #     end
+  #   end
+  #
+  # When the entirety of +activerecord/lib/active_record/base.rb+ has been
+  # evaluated then +run_load_hooks+ is invoked. The very last line of
+  # +activerecord/lib/active_record/base.rb+ is:
+  #
+  #   ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
+  @load_hooks = Hash.new { |h,k| h[k] = [] }
+  @loaded = Hash.new { |h,k| h[k] = [] }
+
+  def self.on_load(name, options = {}, &block)
+    @loaded[name].each do |base|
+      execute_hook(base, options, block)
+    end
+
+    @load_hooks[name] << [block, options]
+  end
+
+  def self.execute_hook(base, options, block)
+    if options[:yield]
+      block.call(base)
+    else
+      base.instance_eval(&block)
+    end
+  end
+
+  def self.run_load_hooks(name, base = Object)
+    @loaded[name] << base
+    @load_hooks[name].each do |hook, options|
+      execute_hook(base, options, hook)
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/locale/en.yml b/app/server/vendor/activesupport/lib/active_support/locale/en.yml
new file mode 100644
index 0000000..a4563ac
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/locale/en.yml
@@ -0,0 +1,133 @@
+en:
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y-%m-%d"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+    day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
+    abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
+    abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
+    # Used in date_select and datetime_select.
+    order:
+      - year
+      - month
+      - day
+
+  time:
+    formats:
+      default: "%a, %d %b %Y %H:%M:%S %z"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "am"
+    pm: "pm"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      words_connector: ", "
+      two_words_connector: " and "
+      last_word_connector: ", and "
+  number:
+    # Used in NumberHelper.number_to_delimited()
+    # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
+    format:
+      # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
+      separator: "."
+      # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three)
+      delimiter: ","
+      # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
+      precision: 3
+      # If set to true, precision will mean the number of significant digits instead
+      # of the number of decimal digits (1234 with precision 2 becomes 1200, 1.23543 becomes 1.2)
+      significant: false
+      # If set, the zeros after the decimal separator will always be stripped (eg.: 1.200 will be 1.2)
+      strip_insignificant_zeros: false
+
+    # Used in NumberHelper.number_to_currency()
+    currency:
+      format:
+        # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
+        format: "%u%n"
+        unit: "$"
+        # These five are to override number.format and are optional
+        separator: "."
+        delimiter: ","
+        precision: 2
+        significant: false
+        strip_insignificant_zeros: false
+
+    # Used in NumberHelper.number_to_percentage()
+    percentage:
+      format:
+        # These five are to override number.format and are optional
+        # separator:
+        delimiter: ""
+        # precision:
+        # significant: false
+        # strip_insignificant_zeros: false
+        format: "%n%"
+
+    # Used in NumberHelper.number_to_rounded()
+    precision:
+      format:
+        # These five are to override number.format and are optional
+        # separator:
+        delimiter: ""
+        # precision:
+        # significant: false
+        # strip_insignificant_zeros: false
+
+    # Used in NumberHelper.number_to_human_size() and NumberHelper.number_to_human()
+    human:
+      format:
+        # These five are to override number.format and are optional
+        # separator:
+        delimiter: ""
+        precision: 3
+        significant: true
+        strip_insignificant_zeros: true
+      # Used in number_to_human_size()
+      storage_units:
+        # Storage units output formatting.
+        # %u is the storage unit, %n is the number (default: 2 MB)
+        format: "%n %u"
+        units:
+          byte:
+            one:   "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+      # Used in NumberHelper.number_to_human()
+      decimal_units:
+        format: "%n %u"
+        # Decimal units output formatting
+        # By default we will only quantify some of the exponents
+        # but the commented ones might be defined or overridden
+        # by the user.
+        units:
+          # femto: Quadrillionth
+          # pico: Trillionth
+          # nano: Billionth
+          # micro: Millionth
+          # mili: Thousandth
+          # centi: Hundredth
+          # deci: Tenth
+          unit: ""
+          # ten:
+          #   one: Ten
+          #   other: Tens
+          # hundred: Hundred
+          thousand: Thousand
+          million: Million
+          billion: Billion
+          trillion: Trillion
+          quadrillion: Quadrillion
diff --git a/app/server/vendor/activesupport/lib/active_support/log_subscriber.rb b/app/server/vendor/activesupport/lib/active_support/log_subscriber.rb
new file mode 100644
index 0000000..e95dc5a
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/log_subscriber.rb
@@ -0,0 +1,109 @@
+require 'active_support/core_ext/module/attribute_accessors'
+require 'active_support/core_ext/class/attribute'
+require 'active_support/subscriber'
+
+module ActiveSupport
+  # ActiveSupport::LogSubscriber is an object set to consume
+  # ActiveSupport::Notifications with the sole purpose of logging them.
+  # The log subscriber dispatches notifications to a registered object based
+  # on its given namespace.
+  #
+  # An example would be Active Record log subscriber responsible for logging
+  # queries:
+  #
+  #   module ActiveRecord
+  #     class LogSubscriber < ActiveSupport::LogSubscriber
+  #       def sql(event)
+  #         "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}"
+  #       end
+  #     end
+  #   end
+  #
+  # And it's finally registered as:
+  #
+  #   ActiveRecord::LogSubscriber.attach_to :active_record
+  #
+  # Since we need to know all instance methods before attaching the log
+  # subscriber, the line above should be called after your
+  # <tt>ActiveRecord::LogSubscriber</tt> definition.
+  #
+  # After configured, whenever a "sql.active_record" notification is published,
+  # it will properly dispatch the event (ActiveSupport::Notifications::Event) to
+  # the sql method.
+  #
+  # Log subscriber also has some helpers to deal with logging and automatically
+  # flushes all logs when the request finishes (via action_dispatch.callback
+  # notification) in a Rails environment.
+  class LogSubscriber < Subscriber
+    # Embed in a String to clear all previous ANSI sequences.
+    CLEAR   = "\e[0m"
+    BOLD    = "\e[1m"
+
+    # Colors
+    BLACK   = "\e[30m"
+    RED     = "\e[31m"
+    GREEN   = "\e[32m"
+    YELLOW  = "\e[33m"
+    BLUE    = "\e[34m"
+    MAGENTA = "\e[35m"
+    CYAN    = "\e[36m"
+    WHITE   = "\e[37m"
+
+    mattr_accessor :colorize_logging
+    self.colorize_logging = true
+
+    class << self
+      def logger
+        @logger ||= if defined?(Rails) && Rails.respond_to?(:logger)
+          Rails.logger
+        end
+      end
+
+      attr_writer :logger
+
+      def log_subscribers
+        subscribers
+      end
+
+      # Flush all log_subscribers' logger.
+      def flush_all!
+        logger.flush if logger.respond_to?(:flush)
+      end
+    end
+
+    def logger
+      LogSubscriber.logger
+    end
+
+    def start(name, id, payload)
+      super if logger
+    end
+
+    def finish(name, id, payload)
+      super if logger
+    rescue Exception => e
+      logger.error "Could not log #{name.inspect} event. #{e.class}: #{e.message} #{e.backtrace}"
+    end
+
+  protected
+
+    %w(info debug warn error fatal unknown).each do |level|
+      class_eval <<-METHOD, __FILE__, __LINE__ + 1
+        def #{level}(progname = nil, &block)
+          logger.#{level}(progname, &block) if logger
+        end
+      METHOD
+    end
+
+    # Set color by using a string or one of the defined constants. If a third
+    # option is set to +true+, it also adds bold to the string. This is based
+    # on the Highline implementation and will automatically append CLEAR to the
+    # end of the returned String.
+    def color(text, color, bold=false)
+      return text unless colorize_logging
+      color = self.class.const_get(color.upcase) if color.is_a?(Symbol)
+      bold  = bold ? BOLD : ""
+      "#{bold}#{color}#{text}#{CLEAR}"
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/log_subscriber/test_helper.rb b/app/server/vendor/activesupport/lib/active_support/log_subscriber/test_helper.rb
new file mode 100644
index 0000000..75f353f
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/log_subscriber/test_helper.rb
@@ -0,0 +1,104 @@
+require 'active_support/log_subscriber'
+require 'active_support/logger'
+require 'active_support/notifications'
+
+module ActiveSupport
+  class LogSubscriber
+    # Provides some helpers to deal with testing log subscribers by setting up
+    # notifications. Take for instance Active Record subscriber tests:
+    #
+    #   class SyncLogSubscriberTest < ActiveSupport::TestCase
+    #     include ActiveSupport::LogSubscriber::TestHelper
+    #
+    #     def setup
+    #       ActiveRecord::LogSubscriber.attach_to(:active_record)
+    #     end
+    #
+    #     def test_basic_query_logging
+    #       Developer.all.to_a
+    #       wait
+    #       assert_equal 1, @logger.logged(:debug).size
+    #       assert_match(/Developer Load/, @logger.logged(:debug).last)
+    #       assert_match(/SELECT \* FROM "developers"/, @logger.logged(:debug).last)
+    #     end
+    #   end
+    #
+    # All you need to do is to ensure that your log subscriber is added to
+    # Rails::Subscriber, as in the second line of the code above. The test
+    # helpers are responsible for setting up the queue, subscriptions and
+    # turning colors in logs off.
+    #
+    # The messages are available in the @logger instance, which is a logger with
+    # limited powers (it actually does not send anything to your output), and
+    # you can collect them doing @logger.logged(level), where level is the level
+    # used in logging, like info, debug, warn and so on.
+    module TestHelper
+      def setup
+        @logger   = MockLogger.new
+        @notifier = ActiveSupport::Notifications::Fanout.new
+
+        ActiveSupport::LogSubscriber.colorize_logging = false
+
+        @old_notifier = ActiveSupport::Notifications.notifier
+        set_logger(@logger)
+        ActiveSupport::Notifications.notifier = @notifier
+      end
+
+      def teardown
+        set_logger(nil)
+        ActiveSupport::Notifications.notifier = @old_notifier
+      end
+
+      class MockLogger
+        include ActiveSupport::Logger::Severity
+
+        attr_reader :flush_count
+        attr_accessor :level
+
+        def initialize(level = DEBUG)
+          @flush_count = 0
+          @level = level
+          @logged = Hash.new { |h,k| h[k] = [] }
+        end
+
+        def method_missing(level, message = nil)
+           if block_given?
+             @logged[level] << yield
+           else
+             @logged[level] << message
+           end
+        end
+
+        def logged(level)
+          @logged[level].compact.map { |l| l.to_s.strip }
+        end
+
+        def flush
+          @flush_count += 1
+        end
+
+        ActiveSupport::Logger::Severity.constants.each do |severity|
+          class_eval <<-EOT, __FILE__, __LINE__ + 1
+            def #{severity.downcase}?
+              #{severity} >= @level
+            end
+          EOT
+        end
+      end
+
+      # Wait notifications to be published.
+      def wait
+        @notifier.wait
+      end
+
+      # Overwrite if you use another logger in your log subscriber.
+      #
+      #   def logger
+      #     ActiveRecord::Base.logger = @logger
+      #   end
+      def set_logger(logger)
+        ActiveSupport::LogSubscriber.logger = logger
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/logger.rb b/app/server/vendor/activesupport/lib/active_support/logger.rb
new file mode 100644
index 0000000..33fccdc
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/logger.rb
@@ -0,0 +1,57 @@
+require 'active_support/core_ext/module/attribute_accessors'
+require 'active_support/logger_silence'
+require 'logger'
+
+module ActiveSupport
+  class Logger < ::Logger
+    include LoggerSilence
+
+    # Broadcasts logs to multiple loggers.
+    def self.broadcast(logger) # :nodoc:
+      Module.new do
+        define_method(:add) do |*args, &block|
+          logger.add(*args, &block)
+          super(*args, &block)
+        end
+
+        define_method(:<<) do |x|
+          logger << x
+          super(x)
+        end
+
+        define_method(:close) do
+          logger.close
+          super()
+        end
+
+        define_method(:progname=) do |name|
+          logger.progname = name
+          super(name)
+        end
+
+        define_method(:formatter=) do |formatter|
+          logger.formatter = formatter
+          super(formatter)
+        end
+
+        define_method(:level=) do |level|
+          logger.level = level
+          super(level)
+        end
+      end
+    end
+
+    def initialize(*args)
+      super
+      @formatter = SimpleFormatter.new
+    end
+
+    # Simple formatter which only displays the message.
+    class SimpleFormatter < ::Logger::Formatter
+      # This method is invoked when a log event occurs
+      def call(severity, timestamp, progname, msg)
+        "#{String === msg ? msg : msg.inspect}\n"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/logger_silence.rb b/app/server/vendor/activesupport/lib/active_support/logger_silence.rb
new file mode 100644
index 0000000..a8efdef
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/logger_silence.rb
@@ -0,0 +1,24 @@
+require 'active_support/concern'
+
+module LoggerSilence
+  extend ActiveSupport::Concern
+  
+  included do
+    cattr_accessor :silencer
+    self.silencer = true
+  end
+
+  # Silences the logger for the duration of the block.
+  def silence(temporary_level = Logger::ERROR)
+    if silencer
+      begin
+        old_logger_level, self.level = level, temporary_level
+        yield self
+      ensure
+        self.level = old_logger_level
+      end
+    else
+      yield self
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/lib/active_support/message_encryptor.rb b/app/server/vendor/activesupport/lib/active_support/message_encryptor.rb
new file mode 100644
index 0000000..b019ad0
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/message_encryptor.rb
@@ -0,0 +1,106 @@
+require 'openssl'
+require 'base64'
+require 'active_support/core_ext/array/extract_options'
+
+module ActiveSupport
+  # MessageEncryptor is a simple way to encrypt values which get stored
+  # somewhere you don't trust.
+  #
+  # The cipher text and initialization vector are base64 encoded and returned
+  # to you.
+  #
+  # This can be used in situations similar to the <tt>MessageVerifier</tt>, but
+  # where you don't want users to be able to determine the value of the payload.
+  #
+  #   salt  = SecureRandom.random_bytes(64)
+  #   key   = ActiveSupport::KeyGenerator.new('password').generate_key(salt) # => "\x89\xE0\x156\xAC..."
+  #   crypt = ActiveSupport::MessageEncryptor.new(key)                       # => #<ActiveSupport::MessageEncryptor ...>
+  #   encrypted_data = crypt.encrypt_and_sign('my secret data')              # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
+  #   crypt.decrypt_and_verify(encrypted_data)                               # => "my secret data"
+  class MessageEncryptor
+    module NullSerializer #:nodoc:
+      def self.load(value)
+        value
+      end
+
+      def self.dump(value)
+        value
+      end
+    end
+
+    class InvalidMessage < StandardError; end
+    OpenSSLCipherError = OpenSSL::Cipher::CipherError
+
+    # Initialize a new MessageEncryptor. +secret+ must be at least as long as
+    # the cipher key size. For the default 'aes-256-cbc' cipher, this is 256
+    # bits. If you are using a user-entered secret, you can generate a suitable
+    # key with <tt>OpenSSL::Digest::SHA256.new(user_secret).digest</tt> or
+    # similar.
+    #
+    # Options:
+    # * <tt>:cipher</tt>     - Cipher to use. Can be any cipher returned by
+    #   <tt>OpenSSL::Cipher.ciphers</tt>. Default is 'aes-256-cbc'.
+    # * <tt>:serializer</tt> - Object serializer to use. Default is +Marshal+.
+    def initialize(secret, *signature_key_or_options)
+      options = signature_key_or_options.extract_options!
+      sign_secret = signature_key_or_options.first
+      @secret = secret
+      @sign_secret = sign_secret
+      @cipher = options[:cipher] || 'aes-256-cbc'
+      @verifier = MessageVerifier.new(@sign_secret || @secret, :serializer => NullSerializer)
+      @serializer = options[:serializer] || Marshal
+    end
+
+    # Encrypt and sign a message. We need to sign the message in order to avoid
+    # padding attacks. Reference: http://www.limited-entropy.com/padding-oracle-attacks.
+    def encrypt_and_sign(value)
+      verifier.generate(_encrypt(value))
+    end
+
+    # Decrypt and verify a message. We need to verify the message in order to
+    # avoid padding attacks. Reference: http://www.limited-entropy.com/padding-oracle-attacks.
+    def decrypt_and_verify(value)
+      _decrypt(verifier.verify(value))
+    end
+
+    private
+
+    def _encrypt(value)
+      cipher = new_cipher
+      cipher.encrypt
+      cipher.key = @secret
+
+      # Rely on OpenSSL for the initialization vector
+      iv = cipher.random_iv
+
+      encrypted_data = cipher.update(@serializer.dump(value))
+      encrypted_data << cipher.final
+
+      "#{::Base64.strict_encode64 encrypted_data}--#{::Base64.strict_encode64 iv}"
+    end
+
+    def _decrypt(encrypted_message)
+      cipher = new_cipher
+      encrypted_data, iv = encrypted_message.split("--").map {|v| ::Base64.strict_decode64(v)}
+
+      cipher.decrypt
+      cipher.key = @secret
+      cipher.iv  = iv
+
+      decrypted_data = cipher.update(encrypted_data)
+      decrypted_data << cipher.final
+
+      @serializer.load(decrypted_data)
+    rescue OpenSSLCipherError, TypeError, ArgumentError
+      raise InvalidMessage
+    end
+
+    def new_cipher
+      OpenSSL::Cipher::Cipher.new(@cipher)
+    end
+
+    def verifier
+      @verifier
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/message_verifier.rb b/app/server/vendor/activesupport/lib/active_support/message_verifier.rb
new file mode 100644
index 0000000..8e6e1dc
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/message_verifier.rb
@@ -0,0 +1,73 @@
+require 'base64'
+require 'active_support/core_ext/object/blank'
+
+module ActiveSupport
+  # +MessageVerifier+ makes it easy to generate and verify messages which are
+  # signed to prevent tampering.
+  #
+  # This is useful for cases like remember-me tokens and auto-unsubscribe links
+  # where the session store isn't suitable or available.
+  #
+  # Remember Me:
+  #   cookies[:remember_me] = @verifier.generate([@user.id, 2.weeks.from_now])
+  #
+  # In the authentication filter:
+  #
+  #   id, time = @verifier.verify(cookies[:remember_me])
+  #   if time < Time.now
+  #     self.current_user = User.find(id)
+  #   end
+  #
+  # By default it uses Marshal to serialize the message. If you want to use
+  # another serialization method, you can set the serializer in the options
+  # hash upon initialization:
+  #
+  #   @verifier = ActiveSupport::MessageVerifier.new('s3Krit', serializer: YAML)
+  class MessageVerifier
+    class InvalidSignature < StandardError; end
+
+    def initialize(secret, options = {})
+      @secret = secret
+      @digest = options[:digest] || 'SHA1'
+      @serializer = options[:serializer] || Marshal
+    end
+
+    def verify(signed_message)
+      raise InvalidSignature if signed_message.blank?
+
+      data, digest = signed_message.split("--")
+      if data.present? && digest.present? && secure_compare(digest, generate_digest(data))
+        begin
+          @serializer.load(::Base64.strict_decode64(data))
+        rescue ArgumentError => argument_error
+          raise InvalidSignature if argument_error.message =~ %r{invalid base64}
+          raise
+        end
+      else
+        raise InvalidSignature
+      end
+    end
+
+    def generate(value)
+      data = ::Base64.strict_encode64(@serializer.dump(value))
+      "#{data}--#{generate_digest(data)}"
+    end
+
+    private
+      # constant-time comparison algorithm to prevent timing attacks
+      def secure_compare(a, b)
+        return false unless a.bytesize == b.bytesize
+
+        l = a.unpack "C#{a.bytesize}"
+
+        res = 0
+        b.each_byte { |byte| res |= byte ^ l.shift }
+        res == 0
+      end
+
+      def generate_digest(data)
+        require 'openssl' unless defined?(OpenSSL)
+        OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@digest).new, @secret, data)
+      end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/multibyte.rb b/app/server/vendor/activesupport/lib/active_support/multibyte.rb
new file mode 100644
index 0000000..ffebd9a
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/multibyte.rb
@@ -0,0 +1,21 @@
+module ActiveSupport #:nodoc:
+  module Multibyte
+    autoload :Chars, 'active_support/multibyte/chars'
+    autoload :Unicode, 'active_support/multibyte/unicode'
+
+    # The proxy class returned when calling mb_chars. You can use this accessor
+    # to configure your own proxy class so you can support other encodings. See
+    # the ActiveSupport::Multibyte::Chars implementation for an example how to
+    # do this.
+    #
+    #   ActiveSupport::Multibyte.proxy_class = CharsForUTF32
+    def self.proxy_class=(klass)
+      @proxy_class = klass
+    end
+
+    # Returns the current proxy class.
+    def self.proxy_class
+      @proxy_class ||= ActiveSupport::Multibyte::Chars
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/multibyte/chars.rb b/app/server/vendor/activesupport/lib/active_support/multibyte/chars.rb
new file mode 100644
index 0000000..3c0cf9f
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/multibyte/chars.rb
@@ -0,0 +1,222 @@
+# encoding: utf-8
+require 'active_support/json'
+require 'active_support/core_ext/string/access'
+require 'active_support/core_ext/string/behavior'
+require 'active_support/core_ext/module/delegation'
+
+module ActiveSupport #:nodoc:
+  module Multibyte #:nodoc:
+    # Chars enables you to work transparently with UTF-8 encoding in the Ruby
+    # String class without having extensive knowledge about the encoding. A
+    # Chars object accepts a string upon initialization and proxies String
+    # methods in an encoding safe manner. All the normal String methods are also
+    # implemented on the proxy.
+    #
+    # String methods are proxied through the Chars object, and can be accessed
+    # through the +mb_chars+ method. Methods which would normally return a
+    # String object now return a Chars object so methods can be chained.
+    #
+    #   'The Perfect String  '.mb_chars.downcase.strip.normalize # => "the perfect string"
+    #
+    # Chars objects are perfectly interchangeable with String objects as long as
+    # no explicit class checks are made. If certain methods do explicitly check
+    # the class, call +to_s+ before you pass chars objects to them.
+    #
+    #   bad.explicit_checking_method 'T'.mb_chars.downcase.to_s
+    #
+    # The default Chars implementation assumes that the encoding of the string
+    # is UTF-8, if you want to handle different encodings you can write your own
+    # multibyte string handler and configure it through
+    # ActiveSupport::Multibyte.proxy_class.
+    #
+    #   class CharsForUTF32
+    #     def size
+    #       @wrapped_string.size / 4
+    #     end
+    #
+    #     def self.accepts?(string)
+    #       string.length % 4 == 0
+    #     end
+    #   end
+    #
+    #   ActiveSupport::Multibyte.proxy_class = CharsForUTF32
+    class Chars
+      include Comparable
+      attr_reader :wrapped_string
+      alias to_s wrapped_string
+      alias to_str wrapped_string
+
+      delegate :<=>, :=~, :acts_like_string?, :to => :wrapped_string
+
+      # Creates a new Chars instance by wrapping _string_.
+      def initialize(string)
+        @wrapped_string = string
+        @wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen?
+      end
+
+      # Forward all undefined methods to the wrapped string.
+      def method_missing(method, *args, &block)
+        result = @wrapped_string.__send__(method, *args, &block)
+        if method.to_s =~ /!$/
+          self if result
+        else
+          result.kind_of?(String) ? chars(result) : result
+        end
+      end
+
+      # Returns +true+ if _obj_ responds to the given method. Private methods
+      # are included in the search only if the optional second parameter
+      # evaluates to +true+.
+      def respond_to_missing?(method, include_private)
+        @wrapped_string.respond_to?(method, include_private)
+      end
+
+      # Returns +true+ when the proxy class can handle the string. Returns
+      # +false+ otherwise.
+      def self.consumes?(string)
+        string.encoding == Encoding::UTF_8
+      end
+
+      # Works just like <tt>String#split</tt>, with the exception that the items
+      # in the resulting list are Chars instances instead of String. This makes
+      # chaining methods easier.
+      #
+      #   'Café périferôl'.mb_chars.split(/é/).map { |part| part.upcase.to_s } # => ["CAF", " P", "RIFERÔL"]
+      def split(*args)
+        @wrapped_string.split(*args).map { |i| self.class.new(i) }
+      end
+
+      # Works like like <tt>String#slice!</tt>, but returns an instance of
+      # Chars, or nil if the string was not modified.
+      def slice!(*args)
+        chars(@wrapped_string.slice!(*args))
+      end
+
+      # Reverses all characters in the string.
+      #
+      #   'Café'.mb_chars.reverse.to_s # => 'éfaC'
+      def reverse
+        chars(Unicode.unpack_graphemes(@wrapped_string).reverse.flatten.pack('U*'))
+      end
+
+      # Limits the byte size of the string to a number of bytes without breaking
+      # characters. Usable when the storage for a string is limited for some
+      # reason.
+      #
+      #   'こんにちは'.mb_chars.limit(7).to_s # => "こん"
+      def limit(limit)
+        slice(0...translate_offset(limit))
+      end
+
+      # Converts characters in the string to uppercase.
+      #
+      #   'Laurent, où sont les tests ?'.mb_chars.upcase.to_s # => "LAURENT, OÙ SONT LES TESTS ?"
+      def upcase
+        chars Unicode.upcase(@wrapped_string)
+      end
+
+      # Converts characters in the string to lowercase.
+      #
+      #   'VĚDA A VÝZKUM'.mb_chars.downcase.to_s # => "věda a výzkum"
+      def downcase
+        chars Unicode.downcase(@wrapped_string)
+      end
+
+      # Converts characters in the string to the opposite case.
+      #
+      #    'El Cañón".mb_chars.swapcase.to_s # => "eL cAÑÓN"
+      def swapcase
+        chars Unicode.swapcase(@wrapped_string)
+      end
+
+      # Converts the first character to uppercase and the remainder to lowercase.
+      #
+      #  'über'.mb_chars.capitalize.to_s # => "Über"
+      def capitalize
+        (slice(0) || chars('')).upcase + (slice(1..-1) || chars('')).downcase
+      end
+
+      # Capitalizes the first letter of every word, when possible.
+      #
+      #   "ÉL QUE SE ENTERÓ".mb_chars.titleize    # => "Él Que Se Enteró"
+      #   "日本語".mb_chars.titleize                 # => "日本語"
+      def titleize
+        chars(downcase.to_s.gsub(/\b('?\S)/u) { Unicode.upcase($1)})
+      end
+      alias_method :titlecase, :titleize
+
+      # Returns the KC normalization of the string by default. NFKC is
+      # considered the best normalization form for passing strings to databases
+      # and validations.
+      #
+      # * <tt>form</tt> - The form you want to normalize in. Should be one of the following:
+      #   <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>. Default is
+      #   ActiveSupport::Multibyte::Unicode.default_normalization_form
+      def normalize(form = nil)
+        chars(Unicode.normalize(@wrapped_string, form))
+      end
+
+      # Performs canonical decomposition on all the characters.
+      #
+      #   'é'.length                         # => 2
+      #   'é'.mb_chars.decompose.to_s.length # => 3
+      def decompose
+        chars(Unicode.decompose(:canonical, @wrapped_string.codepoints.to_a).pack('U*'))
+      end
+
+      # Performs composition on all the characters.
+      #
+      #   'é'.length                       # => 3
+      #   'é'.mb_chars.compose.to_s.length # => 2
+      def compose
+        chars(Unicode.compose(@wrapped_string.codepoints.to_a).pack('U*'))
+      end
+
+      # Returns the number of grapheme clusters in the string.
+      #
+      #   'क्षि'.mb_chars.length   # => 4
+      #   'क्षि'.mb_chars.grapheme_length # => 3
+      def grapheme_length
+        Unicode.unpack_graphemes(@wrapped_string).length
+      end
+
+      # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
+      # resulting in a valid UTF-8 string.
+      #
+      # Passing +true+ will forcibly tidy all bytes, assuming that the string's
+      # encoding is entirely CP1252 or ISO-8859-1.
+      def tidy_bytes(force = false)
+        chars(Unicode.tidy_bytes(@wrapped_string, force))
+      end
+
+      def as_json(options = nil) #:nodoc:
+        to_s.as_json(options)
+      end
+
+      %w(capitalize downcase reverse tidy_bytes upcase).each do |method|
+        define_method("#{method}!") do |*args|
+          @wrapped_string = send(method, *args).to_s
+          self
+        end
+      end
+
+      protected
+
+        def translate_offset(byte_offset) #:nodoc:
+          return nil if byte_offset.nil?
+          return 0   if @wrapped_string == ''
+
+          begin
+            @wrapped_string.byteslice(0...byte_offset).unpack('U*').length
+          rescue ArgumentError
+            byte_offset -= 1
+            retry
+          end
+        end
+
+        def chars(string) #:nodoc:
+          self.class.new(string)
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/multibyte/unicode.rb b/app/server/vendor/activesupport/lib/active_support/multibyte/unicode.rb
new file mode 100644
index 0000000..ea3cdcd
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/multibyte/unicode.rb
@@ -0,0 +1,390 @@
+# encoding: utf-8
+module ActiveSupport
+  module Multibyte
+    module Unicode
+
+      extend self
+
+      # A list of all available normalization forms.
+      # See http://www.unicode.org/reports/tr15/tr15-29.html for more
+      # information about normalization.
+      NORMALIZATION_FORMS = [:c, :kc, :d, :kd]
+
+      # The Unicode version that is supported by the implementation
+      UNICODE_VERSION = '6.3.0'
+
+      # The default normalization used for operations that require
+      # normalization. It can be set to any of the normalizations
+      # in NORMALIZATION_FORMS.
+      #
+      #   ActiveSupport::Multibyte::Unicode.default_normalization_form = :c
+      attr_accessor :default_normalization_form
+      @default_normalization_form = :kc
+
+      # Hangul character boundaries and properties
+      HANGUL_SBASE = 0xAC00
+      HANGUL_LBASE = 0x1100
+      HANGUL_VBASE = 0x1161
+      HANGUL_TBASE = 0x11A7
+      HANGUL_LCOUNT = 19
+      HANGUL_VCOUNT = 21
+      HANGUL_TCOUNT = 28
+      HANGUL_NCOUNT = HANGUL_VCOUNT * HANGUL_TCOUNT
+      HANGUL_SCOUNT = 11172
+      HANGUL_SLAST = HANGUL_SBASE + HANGUL_SCOUNT
+      HANGUL_JAMO_FIRST = 0x1100
+      HANGUL_JAMO_LAST = 0x11FF
+
+      # All the unicode whitespace
+      WHITESPACE = [
+        (0x0009..0x000D).to_a, # White_Space # Cc   [5] <control-0009>..<control-000D>
+        0x0020,                # White_Space # Zs       SPACE
+        0x0085,                # White_Space # Cc       <control-0085>
+        0x00A0,                # White_Space # Zs       NO-BREAK SPACE
+        0x1680,                # White_Space # Zs       OGHAM SPACE MARK
+        0x180E,                # White_Space # Zs       MONGOLIAN VOWEL SEPARATOR
+        (0x2000..0x200A).to_a, # White_Space # Zs  [11] EN QUAD..HAIR SPACE
+        0x2028,                # White_Space # Zl       LINE SEPARATOR
+        0x2029,                # White_Space # Zp       PARAGRAPH SEPARATOR
+        0x202F,                # White_Space # Zs       NARROW NO-BREAK SPACE
+        0x205F,                # White_Space # Zs       MEDIUM MATHEMATICAL SPACE
+        0x3000,                # White_Space # Zs       IDEOGRAPHIC SPACE
+      ].flatten.freeze
+
+      # BOM (byte order mark) can also be seen as whitespace, it's a
+      # non-rendering character used to distinguish between little and big
+      # endian. This is not an issue in utf-8, so it must be ignored.
+      LEADERS_AND_TRAILERS = WHITESPACE + [65279] # ZERO-WIDTH NO-BREAK SPACE aka BOM
+
+      # Returns a regular expression pattern that matches the passed Unicode
+      # codepoints.
+      def self.codepoints_to_pattern(array_of_codepoints) #:nodoc:
+        array_of_codepoints.collect{ |e| [e].pack 'U*' }.join('|')
+      end
+      TRAILERS_PAT = /(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+\Z/u
+      LEADERS_PAT = /\A(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+/u
+
+      # Detect whether the codepoint is in a certain character class. Returns
+      # +true+ when it's in the specified character class and +false+ otherwise.
+      # Valid character classes are: <tt>:cr</tt>, <tt>:lf</tt>, <tt>:l</tt>,
+      # <tt>:v</tt>, <tt>:lv</tt>, <tt>:lvt</tt> and <tt>:t</tt>.
+      #
+      # Primarily used by the grapheme cluster support.
+      def in_char_class?(codepoint, classes)
+        classes.detect { |c| database.boundary[c] === codepoint } ? true : false
+      end
+
+      # Unpack the string at grapheme boundaries. Returns a list of character
+      # lists.
+      #
+      #   Unicode.unpack_graphemes('क्षि') # => [[2325, 2381], [2359], [2367]]
+      #   Unicode.unpack_graphemes('Café') # => [[67], [97], [102], [233]]
+      def unpack_graphemes(string)
+        codepoints = string.codepoints.to_a
+        unpacked = []
+        pos = 0
+        marker = 0
+        eoc = codepoints.length
+        while(pos < eoc)
+          pos += 1
+          previous = codepoints[pos-1]
+          current = codepoints[pos]
+          if (
+              # CR X LF
+              ( previous == database.boundary[:cr] and current == database.boundary[:lf] ) or
+              # L X (L|V|LV|LVT)
+              ( database.boundary[:l] === previous and in_char_class?(current, [:l,:v,:lv,:lvt]) ) or
+              # (LV|V) X (V|T)
+              ( in_char_class?(previous, [:lv,:v]) and in_char_class?(current, [:v,:t]) ) or
+              # (LVT|T) X (T)
+              ( in_char_class?(previous, [:lvt,:t]) and database.boundary[:t] === current ) or
+              # X Extend
+              (database.boundary[:extend] === current)
+            )
+          else
+            unpacked << codepoints[marker..pos-1]
+            marker = pos
+          end
+        end
+        unpacked
+      end
+
+      # Reverse operation of unpack_graphemes.
+      #
+      #   Unicode.pack_graphemes(Unicode.unpack_graphemes('क्षि')) # => 'क्षि'
+      def pack_graphemes(unpacked)
+        unpacked.flatten.pack('U*')
+      end
+
+      # Re-order codepoints so the string becomes canonical.
+      def reorder_characters(codepoints)
+        length = codepoints.length- 1
+        pos = 0
+        while pos < length do
+          cp1, cp2 = database.codepoints[codepoints[pos]], database.codepoints[codepoints[pos+1]]
+          if (cp1.combining_class > cp2.combining_class) && (cp2.combining_class > 0)
+            codepoints[pos..pos+1] = cp2.code, cp1.code
+            pos += (pos > 0 ? -1 : 1)
+          else
+            pos += 1
+          end
+        end
+        codepoints
+      end
+
+      # Decompose composed characters to the decomposed form.
+      def decompose(type, codepoints)
+        codepoints.inject([]) do |decomposed, cp|
+          # if it's a hangul syllable starter character
+          if HANGUL_SBASE <= cp and cp < HANGUL_SLAST
+            sindex = cp - HANGUL_SBASE
+            ncp = [] # new codepoints
+            ncp << HANGUL_LBASE + sindex / HANGUL_NCOUNT
+            ncp << HANGUL_VBASE + (sindex % HANGUL_NCOUNT) / HANGUL_TCOUNT
+            tindex = sindex % HANGUL_TCOUNT
+            ncp << (HANGUL_TBASE + tindex) unless tindex == 0
+            decomposed.concat ncp
+          # if the codepoint is decomposable in with the current decomposition type
+          elsif (ncp = database.codepoints[cp].decomp_mapping) and (!database.codepoints[cp].decomp_type || type == :compatibility)
+            decomposed.concat decompose(type, ncp.dup)
+          else
+            decomposed << cp
+          end
+        end
+      end
+
+      # Compose decomposed characters to the composed form.
+      def compose(codepoints)
+        pos = 0
+        eoa = codepoints.length - 1
+        starter_pos = 0
+        starter_char = codepoints[0]
+        previous_combining_class = -1
+        while pos < eoa
+          pos += 1
+          lindex = starter_char - HANGUL_LBASE
+          # -- Hangul
+          if 0 <= lindex and lindex < HANGUL_LCOUNT
+            vindex = codepoints[starter_pos+1] - HANGUL_VBASE rescue vindex = -1
+            if 0 <= vindex and vindex < HANGUL_VCOUNT
+              tindex = codepoints[starter_pos+2] - HANGUL_TBASE rescue tindex = -1
+              if 0 <= tindex and tindex < HANGUL_TCOUNT
+                j = starter_pos + 2
+                eoa -= 2
+              else
+                tindex = 0
+                j = starter_pos + 1
+                eoa -= 1
+              end
+              codepoints[starter_pos..j] = (lindex * HANGUL_VCOUNT + vindex) * HANGUL_TCOUNT + tindex + HANGUL_SBASE
+            end
+            starter_pos += 1
+            starter_char = codepoints[starter_pos]
+          # -- Other characters
+          else
+            current_char = codepoints[pos]
+            current = database.codepoints[current_char]
+            if current.combining_class > previous_combining_class
+              if ref = database.composition_map[starter_char]
+                composition = ref[current_char]
+              else
+                composition = nil
+              end
+              unless composition.nil?
+                codepoints[starter_pos] = composition
+                starter_char = composition
+                codepoints.delete_at pos
+                eoa -= 1
+                pos -= 1
+                previous_combining_class = -1
+              else
+                previous_combining_class = current.combining_class
+              end
+            else
+              previous_combining_class = current.combining_class
+            end
+            if current.combining_class == 0
+              starter_pos = pos
+              starter_char = codepoints[pos]
+            end
+          end
+        end
+        codepoints
+      end
+
+      # Ruby >= 2.1 has String#scrub, which is faster than the workaround used for < 2.1.
+      if '<3'.respond_to?(:scrub)
+        # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
+        # resulting in a valid UTF-8 string.
+        #
+        # Passing +true+ will forcibly tidy all bytes, assuming that the string's
+        # encoding is entirely CP1252 or ISO-8859-1.
+        def tidy_bytes(string, force = false)
+          return string if string.empty?
+          return recode_windows1252_chars(string) if force
+          string.scrub { |bad| recode_windows1252_chars(bad) }
+        end
+      else
+        def tidy_bytes(string, force = false)
+          return string if string.empty?
+          return recode_windows1252_chars(string) if force
+
+          # We can't transcode to the same format, so we choose a nearly-identical encoding.
+          # We're going to 'transcode' bytes from UTF-8 when possible, then fall back to
+          # CP1252 when we get errors. The final string will be 'converted' back to UTF-8
+          # before returning.
+          reader = Encoding::Converter.new(Encoding::UTF_8, Encoding::UTF_16LE)
+
+          source = string.dup
+          out = ''.force_encoding(Encoding::UTF_16LE)
+
+          loop do
+            reader.primitive_convert(source, out)
+            _, _, _, error_bytes, _ = reader.primitive_errinfo
+            break if error_bytes.nil?
+            out << error_bytes.encode(Encoding::UTF_16LE, Encoding::Windows_1252, invalid: :replace, undef: :replace)
+          end
+
+          reader.finish
+
+          out.encode!(Encoding::UTF_8)
+        end
+      end
+
+      # Returns the KC normalization of the string by default. NFKC is
+      # considered the best normalization form for passing strings to databases
+      # and validations.
+      #
+      # * <tt>string</tt> - The string to perform normalization on.
+      # * <tt>form</tt> - The form you want to normalize in. Should be one of
+      #   the following: <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>.
+      #   Default is ActiveSupport::Multibyte.default_normalization_form.
+      def normalize(string, form=nil)
+        form ||= @default_normalization_form
+        # See http://www.unicode.org/reports/tr15, Table 1
+        codepoints = string.codepoints.to_a
+        case form
+          when :d
+            reorder_characters(decompose(:canonical, codepoints))
+          when :c
+            compose(reorder_characters(decompose(:canonical, codepoints)))
+          when :kd
+            reorder_characters(decompose(:compatibility, codepoints))
+          when :kc
+            compose(reorder_characters(decompose(:compatibility, codepoints)))
+          else
+            raise ArgumentError, "#{form} is not a valid normalization variant", caller
+        end.pack('U*')
+      end
+
+      def downcase(string)
+        apply_mapping string, :lowercase_mapping
+      end
+
+      def upcase(string)
+        apply_mapping string, :uppercase_mapping
+      end
+
+      def swapcase(string)
+        apply_mapping string, :swapcase_mapping
+      end
+
+      # Holds data about a codepoint in the Unicode database.
+      class Codepoint
+        attr_accessor :code, :combining_class, :decomp_type, :decomp_mapping, :uppercase_mapping, :lowercase_mapping
+
+        # Initializing Codepoint object with default values
+        def initialize
+          @combining_class = 0
+          @uppercase_mapping = 0
+          @lowercase_mapping = 0
+        end
+
+        def swapcase_mapping
+          uppercase_mapping > 0 ? uppercase_mapping : lowercase_mapping
+        end
+      end
+
+      # Holds static data from the Unicode database.
+      class UnicodeDatabase
+        ATTRIBUTES = :codepoints, :composition_exclusion, :composition_map, :boundary, :cp1252
+
+        attr_writer(*ATTRIBUTES)
+
+        def initialize
+          @codepoints = Hash.new(Codepoint.new)
+          @composition_exclusion = []
+          @composition_map = {}
+          @boundary = {}
+          @cp1252 = {}
+        end
+
+        # Lazy load the Unicode database so it's only loaded when it's actually used
+        ATTRIBUTES.each do |attr_name|
+          class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+            def #{attr_name}     # def codepoints
+              load               #   load
+              @#{attr_name}      #   @codepoints
+            end                  # end
+          EOS
+        end
+
+        # Loads the Unicode database and returns all the internal objects of
+        # UnicodeDatabase.
+        def load
+          begin
+            @codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read }
+          rescue => e
+              raise IOError.new("Couldn't load the Unicode tables for UTF8Handler (#{e.message}), ActiveSupport::Multibyte is unusable")
+          end
+
+          # Redefine the === method so we can write shorter rules for grapheme cluster breaks
+          @boundary.each do |k,_|
+            @boundary[k].instance_eval do
+              def ===(other)
+                detect { |i| i === other } ? true : false
+              end
+            end if @boundary[k].kind_of?(Array)
+          end
+
+          # define attr_reader methods for the instance variables
+          class << self
+            attr_reader(*ATTRIBUTES)
+          end
+        end
+
+        # Returns the directory in which the data files are stored.
+        def self.dirname
+          File.dirname(__FILE__) + '/../values/'
+        end
+
+        # Returns the filename for the data file for this version.
+        def self.filename
+          File.expand_path File.join(dirname, "unicode_tables.dat")
+        end
+      end
+
+      private
+
+      def apply_mapping(string, mapping) #:nodoc:
+        string.each_codepoint.map do |codepoint|
+          cp = database.codepoints[codepoint]
+          if cp and (ncp = cp.send(mapping)) and ncp > 0
+            ncp
+          else
+            codepoint
+          end
+        end.pack('U*')
+      end
+
+      def recode_windows1252_chars(string)
+        string.encode(Encoding::UTF_8, Encoding::Windows_1252, invalid: :replace, undef: :replace)
+      end
+
+      def database
+        @database ||= UnicodeDatabase.new
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/notifications.rb b/app/server/vendor/activesupport/lib/active_support/notifications.rb
new file mode 100644
index 0000000..7a96c66
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/notifications.rb
@@ -0,0 +1,207 @@
+require 'active_support/notifications/instrumenter'
+require 'active_support/notifications/fanout'
+require 'active_support/per_thread_registry'
+
+module ActiveSupport
+  # = Notifications
+  #
+  # <tt>ActiveSupport::Notifications</tt> provides an instrumentation API for
+  # Ruby.
+  #
+  # == Instrumenters
+  #
+  # To instrument an event you just need to do:
+  #
+  #   ActiveSupport::Notifications.instrument('render', extra: :information) do
+  #     render text: 'Foo'
+  #   end
+  #
+  # That executes the block first and notifies all subscribers once done.
+  #
+  # In the example above +render+ is the name of the event, and the rest is called
+  # the _payload_. The payload is a mechanism that allows instrumenters to pass
+  # extra information to subscribers. Payloads consist of a hash whose contents
+  # are arbitrary and generally depend on the event.
+  #
+  # == Subscribers
+  #
+  # You can consume those events and the information they provide by registering
+  # a subscriber.
+  #
+  #   ActiveSupport::Notifications.subscribe('render') do |name, start, finish, id, payload|
+  #     name    # => String, name of the event (such as 'render' from above)
+  #     start   # => Time, when the instrumented block started execution
+  #     finish  # => Time, when the instrumented block ended execution
+  #     id      # => String, unique ID for this notification
+  #     payload # => Hash, the payload
+  #   end
+  #
+  # For instance, let's store all "render" events in an array:
+  #
+  #   events = []
+  #
+  #   ActiveSupport::Notifications.subscribe('render') do |*args|
+  #     events << ActiveSupport::Notifications::Event.new(*args)
+  #   end
+  #
+  # That code returns right away, you are just subscribing to "render" events.
+  # The block is saved and will be called whenever someone instruments "render":
+  #
+  #   ActiveSupport::Notifications.instrument('render', extra: :information) do
+  #     render text: 'Foo'
+  #   end
+  #
+  #   event = events.first
+  #   event.name      # => "render"
+  #   event.duration  # => 10 (in milliseconds)
+  #   event.payload   # => { extra: :information }
+  #
+  # The block in the <tt>subscribe</tt> call gets the name of the event, start
+  # timestamp, end timestamp, a string with a unique identifier for that event
+  # (something like "535801666f04d0298cd6"), and a hash with the payload, in
+  # that order.
+  #
+  # If an exception happens during that particular instrumentation the payload will
+  # have a key <tt>:exception</tt> with an array of two elements as value: a string with
+  # the name of the exception class, and the exception message.
+  #
+  # As the previous example depicts, the class <tt>ActiveSupport::Notifications::Event</tt>
+  # is able to take the arguments as they come and provide an object-oriented
+  # interface to that data.
+  #
+  # It is also possible to pass an object as the second parameter passed to the
+  # <tt>subscribe</tt> method instead of a block:
+  #
+  #   module ActionController
+  #     class PageRequest
+  #       def call(name, started, finished, unique_id, payload)
+  #         Rails.logger.debug ['notification:', name, started, finished, unique_id, payload].join(' ')
+  #       end
+  #     end
+  #   end
+  #
+  #   ActiveSupport::Notifications.subscribe('process_action.action_controller', ActionController::PageRequest.new)
+  #
+  # resulting in the following output within the logs including a hash with the payload:
+  #
+  #   notification: process_action.action_controller 2012-04-13 01:08:35 +0300 2012-04-13 01:08:35 +0300 af358ed7fab884532ec7 {
+  #      controller: "Devise::SessionsController",
+  #      action: "new",
+  #      params: {"action"=>"new", "controller"=>"devise/sessions"},
+  #      format: :html,
+  #      method: "GET",
+  #      path: "/login/sign_in",
+  #      status: 200,
+  #      view_runtime: 279.3080806732178,
+  #      db_runtime: 40.053
+  #    }
+  #
+  # You can also subscribe to all events whose name matches a certain regexp:
+  #
+  #   ActiveSupport::Notifications.subscribe(/render/) do |*args|
+  #     ...
+  #   end
+  #
+  # and even pass no argument to <tt>subscribe</tt>, in which case you are subscribing
+  # to all events.
+  #
+  # == Temporary Subscriptions
+  #
+  # Sometimes you do not want to subscribe to an event for the entire life of
+  # the application. There are two ways to unsubscribe.
+  #
+  # WARNING: The instrumentation framework is designed for long-running subscribers,
+  # use this feature sparingly because it wipes some internal caches and that has
+  # a negative impact on performance.
+  #
+  # === Subscribe While a Block Runs
+  #
+  # You can subscribe to some event temporarily while some block runs. For
+  # example, in
+  #
+  #   callback = lambda {|*args| ... }
+  #   ActiveSupport::Notifications.subscribed(callback, "sql.active_record") do
+  #     ...
+  #   end
+  #
+  # the callback will be called for all "sql.active_record" events instrumented
+  # during the execution of the block. The callback is unsubscribed automatically
+  # after that.
+  #
+  # === Manual Unsubscription
+  #
+  # The +subscribe+ method returns a subscriber object:
+  #
+  #   subscriber = ActiveSupport::Notifications.subscribe("render") do |*args|
+  #     ...
+  #   end
+  #
+  # To prevent that block from being called anymore, just unsubscribe passing
+  # that reference:
+  #
+  #   ActiveSupport::Notifications.unsubscribe(subscriber)
+  #
+  # == Default Queue
+  #
+  # Notifications ships with a queue implementation that consumes and publishes events
+  # to all log subscribers. You can use any queue implementation you want.
+  #
+  module Notifications
+    class << self
+      attr_accessor :notifier
+
+      def publish(name, *args)
+        notifier.publish(name, *args)
+      end
+
+      def instrument(name, payload = {})
+        if notifier.listening?(name)
+          instrumenter.instrument(name, payload) { yield payload if block_given? }
+        else
+          yield payload if block_given?
+        end
+      end
+
+      def subscribe(*args, &block)
+        notifier.subscribe(*args, &block)
+      end
+
+      def subscribed(callback, *args, &block)
+        subscriber = subscribe(*args, &callback)
+        yield
+      ensure
+        unsubscribe(subscriber)
+      end
+
+      def unsubscribe(args)
+        notifier.unsubscribe(args)
+      end
+
+      def instrumenter
+        InstrumentationRegistry.instance.instrumenter_for(notifier)
+      end
+    end
+
+    # This class is a registry which holds all of the +Instrumenter+ objects
+    # in a particular thread local. To access the +Instrumenter+ object for a
+    # particular +notifier+, you can call the following method:
+    #
+    #   InstrumentationRegistry.instrumenter_for(notifier)
+    #
+    # The instrumenters for multiple notifiers are held in a single instance of
+    # this class.
+    class InstrumentationRegistry # :nodoc:
+      extend ActiveSupport::PerThreadRegistry
+
+      def initialize
+        @registry = {}
+      end
+
+      def instrumenter_for(notifier)
+        @registry[notifier] ||= Instrumenter.new(notifier)
+      end
+    end
+
+    self.notifier = Fanout.new
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/notifications/fanout.rb b/app/server/vendor/activesupport/lib/active_support/notifications/fanout.rb
new file mode 100644
index 0000000..8f5fa64
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/notifications/fanout.rb
@@ -0,0 +1,152 @@
+require 'mutex_m'
+require 'thread_safe'
+
+module ActiveSupport
+  module Notifications
+    # This is a default queue implementation that ships with Notifications.
+    # It just pushes events to all registered log subscribers.
+    #
+    # This class is thread safe. All methods are reentrant.
+    class Fanout
+      include Mutex_m
+
+      def initialize
+        @subscribers = []
+        @listeners_for = ThreadSafe::Cache.new
+        super
+      end
+
+      def subscribe(pattern = nil, block = Proc.new)
+        subscriber = Subscribers.new pattern, block
+        synchronize do
+          @subscribers << subscriber
+          @listeners_for.clear
+        end
+        subscriber
+      end
+
+      def unsubscribe(subscriber)
+        synchronize do
+          @subscribers.reject! { |s| s.matches?(subscriber) }
+          @listeners_for.clear
+        end
+      end
+
+      def start(name, id, payload)
+        listeners_for(name).each { |s| s.start(name, id, payload) }
+      end
+
+      def finish(name, id, payload)
+        listeners_for(name).each { |s| s.finish(name, id, payload) }
+      end
+
+      def publish(name, *args)
+        listeners_for(name).each { |s| s.publish(name, *args) }
+      end
+
+      def listeners_for(name)
+        # this is correctly done double-checked locking (ThreadSafe::Cache's lookups have volatile semantics)
+        @listeners_for[name] || synchronize do
+          # use synchronisation when accessing @subscribers
+          @listeners_for[name] ||= @subscribers.select { |s| s.subscribed_to?(name) }
+        end
+      end
+
+      def listening?(name)
+        listeners_for(name).any?
+      end
+
+      # This is a sync queue, so there is no waiting.
+      def wait
+      end
+
+      module Subscribers # :nodoc:
+        def self.new(pattern, listener)
+          if listener.respond_to?(:start) and listener.respond_to?(:finish)
+            subscriber = Evented.new pattern, listener
+          else
+            subscriber = Timed.new pattern, listener
+          end
+
+          unless pattern
+            AllMessages.new(subscriber)
+          else
+            subscriber
+          end
+        end
+
+        class Evented #:nodoc:
+          def initialize(pattern, delegate)
+            @pattern = pattern
+            @delegate = delegate
+            @can_publish = delegate.respond_to?(:publish)
+          end
+
+          def publish(name, *args)
+            if @can_publish
+              @delegate.publish name, *args
+            end
+          end
+
+          def start(name, id, payload)
+            @delegate.start name, id, payload
+          end
+
+          def finish(name, id, payload)
+            @delegate.finish name, id, payload
+          end
+
+          def subscribed_to?(name)
+            @pattern === name.to_s
+          end
+
+          def matches?(subscriber_or_name)
+            self === subscriber_or_name ||
+              @pattern && @pattern === subscriber_or_name
+          end
+        end
+
+        class Timed < Evented
+          def publish(name, *args)
+            @delegate.call name, *args
+          end
+
+          def start(name, id, payload)
+            timestack = Thread.current[:_timestack] ||= []
+            timestack.push Time.now
+          end
+
+          def finish(name, id, payload)
+            timestack = Thread.current[:_timestack]
+            started = timestack.pop
+            @delegate.call(name, started, Time.now, id, payload)
+          end
+        end
+
+        class AllMessages # :nodoc:
+          def initialize(delegate)
+            @delegate = delegate
+          end
+
+          def start(name, id, payload)
+            @delegate.start name, id, payload
+          end
+
+          def finish(name, id, payload)
+            @delegate.finish name, id, payload
+          end
+
+          def publish(name, *args)
+            @delegate.publish name, *args
+          end
+
+          def subscribed_to?(name)
+            true
+          end
+
+          alias :matches? :===
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/notifications/instrumenter.rb b/app/server/vendor/activesupport/lib/active_support/notifications/instrumenter.rb
new file mode 100644
index 0000000..3a244b3
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/notifications/instrumenter.rb
@@ -0,0 +1,73 @@
+require 'securerandom'
+
+module ActiveSupport
+  module Notifications
+    # Instrumenters are stored in a thread local.
+    class Instrumenter
+      attr_reader :id
+
+      def initialize(notifier)
+        @id       = unique_id
+        @notifier = notifier
+      end
+
+      # Instrument the given block by measuring the time taken to execute it
+      # and publish it. Notice that events get sent even if an error occurs
+      # in the passed-in block.
+      def instrument(name, payload={})
+        start name, payload
+        begin
+          yield payload
+        rescue Exception => e
+          payload[:exception] = [e.class.name, e.message]
+          raise e
+        ensure
+          finish name, payload
+        end
+      end
+
+      # Send a start notification with +name+ and +payload+.
+      def start(name, payload)
+        @notifier.start name, @id, payload
+      end
+
+      # Send a finish notification with +name+ and +payload+.
+      def finish(name, payload)
+        @notifier.finish name, @id, payload
+      end
+
+      private
+
+      def unique_id
+        SecureRandom.hex(10)
+      end
+    end
+
+    class Event
+      attr_reader :name, :time, :transaction_id, :payload, :children
+      attr_accessor :end
+
+      def initialize(name, start, ending, transaction_id, payload)
+        @name           = name
+        @payload        = payload.dup
+        @time           = start
+        @transaction_id = transaction_id
+        @end            = ending
+        @children       = []
+        @duration       = nil
+      end
+
+      def duration
+        @duration ||= 1000.0 * (self.end - time)
+      end
+
+      def <<(event)
+        @children << event
+      end
+
+      def parent_of?(event)
+        @children.include? event
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/number_helper.rb b/app/server/vendor/activesupport/lib/active_support/number_helper.rb
new file mode 100644
index 0000000..b169e3a
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/number_helper.rb
@@ -0,0 +1,346 @@
+module ActiveSupport
+  module NumberHelper
+    extend ActiveSupport::Autoload
+
+    eager_autoload do
+      autoload :NumberConverter
+      autoload :NumberToRoundedConverter
+      autoload :NumberToDelimitedConverter
+      autoload :NumberToHumanConverter
+      autoload :NumberToHumanSizeConverter
+      autoload :NumberToPhoneConverter
+      autoload :NumberToCurrencyConverter
+      autoload :NumberToPercentageConverter
+    end
+
+    extend self
+
+    # Formats a +number+ into a US phone number (e.g., (555)
+    # 123-9876). You can customize the format in the +options+ hash.
+    #
+    # ==== Options
+    #
+    # * <tt>:area_code</tt> - Adds parentheses around the area code.
+    # * <tt>:delimiter</tt> - Specifies the delimiter to use
+    #   (defaults to "-").
+    # * <tt>:extension</tt> - Specifies an extension to add to the
+    #   end of the generated number.
+    # * <tt>:country_code</tt> - Sets the country code for the phone
+    #   number.
+    # ==== Examples
+    #
+    #   number_to_phone(5551234)                                     # => 555-1234
+    #   number_to_phone('5551234')                                   # => 555-1234
+    #   number_to_phone(1235551234)                                  # => 123-555-1234
+    #   number_to_phone(1235551234, area_code: true)                 # => (123) 555-1234
+    #   number_to_phone(1235551234, delimiter: ' ')                  # => 123 555 1234
+    #   number_to_phone(1235551234, area_code: true, extension: 555) # => (123) 555-1234 x 555
+    #   number_to_phone(1235551234, country_code: 1)                 # => +1-123-555-1234
+    #   number_to_phone('123a456')                                   # => 123a456
+    #
+    #   number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: '.')
+    #   # => +1.123.555.1234 x 1343
+    def number_to_phone(number, options = {})
+      NumberToPhoneConverter.convert(number, options)
+    end
+
+    # Formats a +number+ into a currency string (e.g., $13.65). You
+    # can customize the format in the +options+ hash.
+    #
+    # ==== Options
+    #
+    # * <tt>:locale</tt> - Sets the locale to be used for formatting
+    #   (defaults to current locale).
+    # * <tt>:precision</tt> - Sets the level of precision (defaults
+    #   to 2).
+    # * <tt>:unit</tt> - Sets the denomination of the currency
+    #   (defaults to "$").
+    # * <tt>:separator</tt> - Sets the separator between the units
+    #   (defaults to ".").
+    # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
+    #   to ",").
+    # * <tt>:format</tt> - Sets the format for non-negative numbers
+    #   (defaults to "%u%n").  Fields are <tt>%u</tt> for the
+    #   currency, and <tt>%n</tt> for the number.
+    # * <tt>:negative_format</tt> - Sets the format for negative
+    #   numbers (defaults to prepending an hyphen to the formatted
+    #   number given by <tt>:format</tt>).  Accepts the same fields
+    #   than <tt>:format</tt>, except <tt>%n</tt> is here the
+    #   absolute value of the number.
+    #
+    # ==== Examples
+    #
+    #   number_to_currency(1234567890.50)                # => $1,234,567,890.50
+    #   number_to_currency(1234567890.506)               # => $1,234,567,890.51
+    #   number_to_currency(1234567890.506, precision: 3) # => $1,234,567,890.506
+    #   number_to_currency(1234567890.506, locale: :fr)  # => 1 234 567 890,51 €
+    #   number_to_currency('123a456')                    # => $123a456
+    #
+    #   number_to_currency(-1234567890.50, negative_format: '(%u%n)')
+    #   # => ($1,234,567,890.50)
+    #   number_to_currency(1234567890.50, unit: '£', separator: ',', delimiter: '')
+    #   # => £1234567890,50
+    #   number_to_currency(1234567890.50, unit: '£', separator: ',', delimiter: '', format: '%n %u')
+    #   # => 1234567890,50 £
+    def number_to_currency(number, options = {})
+      NumberToCurrencyConverter.convert(number, options)
+    end
+
+    # Formats a +number+ as a percentage string (e.g., 65%). You can
+    # customize the format in the +options+ hash.
+    #
+    # ==== Options
+    #
+    # * <tt>:locale</tt> - Sets the locale to be used for formatting
+    #   (defaults to current locale).
+    # * <tt>:precision</tt> - Sets the precision of the number
+    #   (defaults to 3).
+    # * <tt>:significant</tt> - If +true+, precision will be the #
+    #   of significant_digits. If +false+, the # of fractional
+    #   digits (defaults to +false+).
+    # * <tt>:separator</tt> - Sets the separator between the
+    #   fractional and integer digits (defaults to ".").
+    # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
+    #   to "").
+    # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
+    #   insignificant zeros after the decimal separator (defaults to
+    #   +false+).
+    # * <tt>:format</tt> - Specifies the format of the percentage
+    #   string The number field is <tt>%n</tt> (defaults to "%n%").
+    #
+    # ==== Examples
+    #
+    #   number_to_percentage(100)                                  # => 100.000%
+    #   number_to_percentage('98')                                 # => 98.000%
+    #   number_to_percentage(100, precision: 0)                    # => 100%
+    #   number_to_percentage(1000, delimiter: '.', separator: ',') # => 1.000,000%
+    #   number_to_percentage(302.24398923423, precision: 5)        # => 302.24399%
+    #   number_to_percentage(1000, locale: :fr)                    # => 1 000,000%
+    #   number_to_percentage('98a')                                # => 98a%
+    #   number_to_percentage(100, format: '%n  %')                 # => 100  %
+    def number_to_percentage(number, options = {})
+      NumberToPercentageConverter.convert(number, options)
+    end
+
+    # Formats a +number+ with grouped thousands using +delimiter+
+    # (e.g., 12,324). You can customize the format in the +options+
+    # hash.
+    #
+    # ==== Options
+    #
+    # * <tt>:locale</tt> - Sets the locale to be used for formatting
+    #   (defaults to current locale).
+    # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
+    #   to ",").
+    # * <tt>:separator</tt> - Sets the separator between the
+    #   fractional and integer digits (defaults to ".").
+    #
+    # ==== Examples
+    #
+    #   number_to_delimited(12345678)                    # => 12,345,678
+    #   number_to_delimited('123456')                    # => 123,456
+    #   number_to_delimited(12345678.05)                 # => 12,345,678.05
+    #   number_to_delimited(12345678, delimiter: '.')    # => 12.345.678
+    #   number_to_delimited(12345678, delimiter: ',')    # => 12,345,678
+    #   number_to_delimited(12345678.05, separator: ' ') # => 12,345,678 05
+    #   number_to_delimited(12345678.05, locale: :fr)    # => 12 345 678,05
+    #   number_to_delimited('112a')                      # => 112a
+    #   number_to_delimited(98765432.98, delimiter: ' ', separator: ',')
+    #   # => 98 765 432,98
+    def number_to_delimited(number, options = {})
+      NumberToDelimitedConverter.convert(number, options)
+    end
+
+    # Formats a +number+ with the specified level of
+    # <tt>:precision</tt> (e.g., 112.32 has a precision of 2 if
+    # +:significant+ is +false+, and 5 if +:significant+ is +true+).
+    # You can customize the format in the +options+ hash.
+    #
+    # ==== Options
+    #
+    # * <tt>:locale</tt> - Sets the locale to be used for formatting
+    #   (defaults to current locale).
+    # * <tt>:precision</tt> - Sets the precision of the number
+    #   (defaults to 3).
+    # * <tt>:significant</tt> - If +true+, precision will be the #
+    #   of significant_digits. If +false+, the # of fractional
+    #   digits (defaults to +false+).
+    # * <tt>:separator</tt> - Sets the separator between the
+    #   fractional and integer digits (defaults to ".").
+    # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
+    #   to "").
+    # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
+    #   insignificant zeros after the decimal separator (defaults to
+    #   +false+).
+    #
+    # ==== Examples
+    #
+    #   number_to_rounded(111.2345)                                  # => 111.235
+    #   number_to_rounded(111.2345, precision: 2)                    # => 111.23
+    #   number_to_rounded(13, precision: 5)                          # => 13.00000
+    #   number_to_rounded(389.32314, precision: 0)                   # => 389
+    #   number_to_rounded(111.2345, significant: true)               # => 111
+    #   number_to_rounded(111.2345, precision: 1, significant: true) # => 100
+    #   number_to_rounded(13, precision: 5, significant: true)       # => 13.000
+    #   number_to_rounded(111.234, locale: :fr)                      # => 111,234
+    #
+    #   number_to_rounded(13, precision: 5, significant: true, strip_insignificant_zeros: true)
+    #   # => 13
+    #
+    #   number_to_rounded(389.32314, precision: 4, significant: true) # => 389.3
+    #   number_to_rounded(1111.2345, precision: 2, separator: ',', delimiter: '.')
+    #   # => 1.111,23
+    def number_to_rounded(number, options = {})
+      NumberToRoundedConverter.convert(number, options)
+    end
+
+    # Formats the bytes in +number+ into a more understandable
+    # representation (e.g., giving it 1500 yields 1.5 KB). This
+    # method is useful for reporting file sizes to users. You can
+    # customize the format in the +options+ hash.
+    #
+    # See <tt>number_to_human</tt> if you want to pretty-print a
+    # generic number.
+    #
+    # ==== Options
+    #
+    # * <tt>:locale</tt> - Sets the locale to be used for formatting
+    #   (defaults to current locale).
+    # * <tt>:precision</tt> - Sets the precision of the number
+    #   (defaults to 3).
+    # * <tt>:significant</tt> - If +true+, precision will be the #
+    #   of significant_digits. If +false+, the # of fractional
+    #   digits (defaults to +true+)
+    # * <tt>:separator</tt> - Sets the separator between the
+    #   fractional and integer digits (defaults to ".").
+    # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
+    #   to "").
+    # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
+    #   insignificant zeros after the decimal separator (defaults to
+    #   +true+)
+    # * <tt>:prefix</tt> - If +:si+ formats the number using the SI
+    #   prefix (defaults to :binary)
+    #
+    # ==== Examples
+    #
+    #   number_to_human_size(123)                                    # => 123 Bytes
+    #   number_to_human_size(1234)                                   # => 1.21 KB
+    #   number_to_human_size(12345)                                  # => 12.1 KB
+    #   number_to_human_size(1234567)                                # => 1.18 MB
+    #   number_to_human_size(1234567890)                             # => 1.15 GB
+    #   number_to_human_size(1234567890123)                          # => 1.12 TB
+    #   number_to_human_size(1234567, precision: 2)                  # => 1.2 MB
+    #   number_to_human_size(483989, precision: 2)                   # => 470 KB
+    #   number_to_human_size(1234567, precision: 2, separator: ',')  # => 1,2 MB
+    #
+    # Non-significant zeros after the fractional separator are stripped out by
+    # default (set <tt>:strip_insignificant_zeros</tt> to +false+ to change that):
+    #
+    #   number_to_human_size(1234567890123, precision: 5) # => "1.1229 TB"
+    #   number_to_human_size(524288000, precision: 5)     # => "500 MB"
+    def number_to_human_size(number, options = {})
+      NumberToHumanSizeConverter.convert(number, options)
+    end
+
+    # Pretty prints (formats and approximates) a number in a way it
+    # is more readable by humans (eg.: 1200000000 becomes "1.2
+    # Billion"). This is useful for numbers that can get very large
+    # (and too hard to read).
+    #
+    # See <tt>number_to_human_size</tt> if you want to print a file
+    # size.
+    #
+    # You can also define your own unit-quantifier names if you want
+    # to use other decimal units (eg.: 1500 becomes "1.5
+    # kilometers", 0.150 becomes "150 milliliters", etc). You may
+    # define a wide range of unit quantifiers, even fractional ones
+    # (centi, deci, mili, etc).
+    #
+    # ==== Options
+    #
+    # * <tt>:locale</tt> - Sets the locale to be used for formatting
+    #   (defaults to current locale).
+    # * <tt>:precision</tt> - Sets the precision of the number
+    #   (defaults to 3).
+    # * <tt>:significant</tt> - If +true+, precision will be the #
+    #   of significant_digits. If +false+, the # of fractional
+    #   digits (defaults to +true+)
+    # * <tt>:separator</tt> - Sets the separator between the
+    #   fractional and integer digits (defaults to ".").
+    # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
+    #   to "").
+    # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
+    #   insignificant zeros after the decimal separator (defaults to
+    #   +true+)
+    # * <tt>:units</tt> - A Hash of unit quantifier names. Or a
+    #   string containing an i18n scope where to find this hash. It
+    #   might have the following keys:
+    #   * *integers*: <tt>:unit</tt>, <tt>:ten</tt>,
+    #     *<tt>:hundred</tt>, <tt>:thousand</tt>, <tt>:million</tt>,
+    #     *<tt>:billion</tt>, <tt>:trillion</tt>,
+    #     *<tt>:quadrillion</tt>
+    #   * *fractionals*: <tt>:deci</tt>, <tt>:centi</tt>,
+    #     *<tt>:mili</tt>, <tt>:micro</tt>, <tt>:nano</tt>,
+    #     *<tt>:pico</tt>, <tt>:femto</tt>
+    # * <tt>:format</tt> - Sets the format of the output string
+    #   (defaults to "%n %u"). The field types are:
+    #   * %u - The quantifier (ex.: 'thousand')
+    #   * %n - The number
+    #
+    # ==== Examples
+    #
+    #   number_to_human(123)                         # => "123"
+    #   number_to_human(1234)                        # => "1.23 Thousand"
+    #   number_to_human(12345)                       # => "12.3 Thousand"
+    #   number_to_human(1234567)                     # => "1.23 Million"
+    #   number_to_human(1234567890)                  # => "1.23 Billion"
+    #   number_to_human(1234567890123)               # => "1.23 Trillion"
+    #   number_to_human(1234567890123456)            # => "1.23 Quadrillion"
+    #   number_to_human(1234567890123456789)         # => "1230 Quadrillion"
+    #   number_to_human(489939, precision: 2)        # => "490 Thousand"
+    #   number_to_human(489939, precision: 4)        # => "489.9 Thousand"
+    #   number_to_human(1234567, precision: 4,
+    #                            significant: false) # => "1.2346 Million"
+    #   number_to_human(1234567, precision: 1,
+    #                            separator: ',',
+    #                            significant: false) # => "1,2 Million"
+    #
+    # Non-significant zeros after the decimal separator are stripped
+    # out by default (set <tt>:strip_insignificant_zeros</tt> to
+    # +false+ to change that):
+    #
+    #   number_to_human(12345012345, significant_digits: 6) # => "12.345 Billion"
+    #   number_to_human(500000000, precision: 5)            # => "500 Million"
+    #
+    # ==== Custom Unit Quantifiers
+    #
+    # You can also use your own custom unit quantifiers:
+    #  number_to_human(500000, units: { unit: 'ml', thousand: 'lt' })  # => "500 lt"
+    #
+    # If in your I18n locale you have:
+    #
+    #   distance:
+    #     centi:
+    #       one: "centimeter"
+    #       other: "centimeters"
+    #     unit:
+    #       one: "meter"
+    #       other: "meters"
+    #     thousand:
+    #       one: "kilometer"
+    #       other: "kilometers"
+    #     billion: "gazillion-distance"
+    #
+    # Then you could do:
+    #
+    #   number_to_human(543934, units: :distance)            # => "544 kilometers"
+    #   number_to_human(54393498, units: :distance)          # => "54400 kilometers"
+    #   number_to_human(54393498000, units: :distance)       # => "54.4 gazillion-distance"
+    #   number_to_human(343, units: :distance, precision: 1) # => "300 meters"
+    #   number_to_human(1, units: :distance)                 # => "1 meter"
+    #   number_to_human(0.34, units: :distance)              # => "34 centimeters"
+    def number_to_human(number, options = {})
+      NumberToHumanConverter.convert(number, options)
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/number_helper/number_converter.rb b/app/server/vendor/activesupport/lib/active_support/number_helper/number_converter.rb
new file mode 100644
index 0000000..9d976f1
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/number_helper/number_converter.rb
@@ -0,0 +1,182 @@
+require 'active_support/core_ext/big_decimal/conversions'
+require 'active_support/core_ext/object/blank'
+require 'active_support/core_ext/hash/keys'
+require 'active_support/i18n'
+require 'active_support/core_ext/class/attribute'
+
+module ActiveSupport
+  module NumberHelper
+    class NumberConverter # :nodoc:
+      # Default and i18n option namespace per class
+      class_attribute :namespace
+
+      # Does the object need a number that is a valid float?
+      class_attribute :validate_float
+
+      attr_reader :number, :opts
+
+      DEFAULTS = {
+        # Used in number_to_delimited
+        # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
+        format: {
+          # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
+          separator: ".",
+          # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three)
+          delimiter: ",",
+          # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
+          precision: 3,
+          # If set to true, precision will mean the number of significant digits instead
+          # of the number of decimal digits (1234 with precision 2 becomes 1200, 1.23543 becomes 1.2)
+          significant: false,
+          # If set, the zeros after the decimal separator will always be stripped (eg.: 1.200 will be 1.2)
+          strip_insignificant_zeros: false
+        },
+
+        # Used in number_to_currency
+        currency: {
+          format: {
+            format: "%u%n",
+            negative_format: "-%u%n",
+            unit: "$",
+            # These five are to override number.format and are optional
+            separator: ".",
+            delimiter: ",",
+            precision: 2,
+            significant: false,
+            strip_insignificant_zeros: false
+          }
+        },
+
+        # Used in number_to_percentage
+        percentage: {
+          format: {
+            delimiter: "",
+            format: "%n%"
+          }
+        },
+
+        # Used in number_to_rounded
+        precision: {
+          format: {
+            delimiter: ""
+          }
+        },
+
+        # Used in number_to_human_size and number_to_human
+        human: {
+          format: {
+            # These five are to override number.format and are optional
+            delimiter: "",
+            precision: 3,
+            significant: true,
+            strip_insignificant_zeros: true
+          },
+          # Used in number_to_human_size
+          storage_units: {
+            # Storage units output formatting.
+            # %u is the storage unit, %n is the number (default: 2 MB)
+            format: "%n %u",
+            units: {
+              byte: "Bytes",
+              kb: "KB",
+              mb: "MB",
+              gb: "GB",
+              tb: "TB"
+            }
+          },
+          # Used in number_to_human
+          decimal_units: {
+            format: "%n %u",
+            # Decimal units output formatting
+            # By default we will only quantify some of the exponents
+            # but the commented ones might be defined or overridden
+            # by the user.
+            units: {
+              # femto: Quadrillionth
+              # pico: Trillionth
+              # nano: Billionth
+              # micro: Millionth
+              # mili: Thousandth
+              # centi: Hundredth
+              # deci: Tenth
+              unit: "",
+              # ten:
+              #   one: Ten
+              #   other: Tens
+              # hundred: Hundred
+              thousand: "Thousand",
+              million: "Million",
+              billion: "Billion",
+              trillion: "Trillion",
+              quadrillion: "Quadrillion"
+            }
+          }
+        }
+      }
+
+      def self.convert(number, options)
+        new(number, options).execute
+      end
+
+      def initialize(number, options)
+        @number = number
+        @opts   = options.symbolize_keys
+      end
+
+      def execute
+        if !number
+          nil
+        elsif validate_float? && !valid_float?
+          number
+        else
+          convert
+        end
+      end
+
+      private
+
+        def options
+          @options ||= format_options.merge(opts)
+        end
+
+        def format_options #:nodoc:
+          default_format_options.merge!(i18n_format_options)
+        end
+
+        def default_format_options #:nodoc:
+          options = DEFAULTS[:format].dup
+          options.merge!(DEFAULTS[namespace][:format]) if namespace
+          options
+        end
+
+        def i18n_format_options #:nodoc:
+          locale = opts[:locale]
+          options = I18n.translate(:'number.format', locale: locale, default: {}).dup
+
+          if namespace
+            options.merge!(I18n.translate(:"number.#{namespace}.format", locale: locale, default: {}))
+          end
+
+          options
+        end
+
+        def translate_number_value_with_default(key, i18n_options = {}) #:nodoc:
+          I18n.translate(key, { default: default_value(key), scope: :number }.merge!(i18n_options))
+        end
+
+        def translate_in_locale(key, i18n_options = {})
+          translate_number_value_with_default(key, { locale: options[:locale] }.merge(i18n_options))
+        end
+
+        def default_value(key)
+          key.split('.').reduce(DEFAULTS) { |defaults, k| defaults[k.to_sym] }
+        end
+
+        def valid_float? #:nodoc:
+          Float(number)
+        rescue ArgumentError, TypeError
+          false
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_currency_converter.rb b/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_currency_converter.rb
new file mode 100644
index 0000000..9ae27a8
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_currency_converter.rb
@@ -0,0 +1,46 @@
+module ActiveSupport
+  module NumberHelper
+    class NumberToCurrencyConverter < NumberConverter # :nodoc:
+      self.namespace = :currency
+
+      def convert
+        number = self.number.to_s.strip
+        format = options[:format]
+
+        if is_negative?(number)
+          format = options[:negative_format]
+          number = absolute_value(number)
+        end
+
+        rounded_number = NumberToRoundedConverter.convert(number, options)
+        format.gsub('%n', rounded_number).gsub('%u', options[:unit])
+      end
+
+      private
+
+        def is_negative?(number)
+          number.to_f.phase != 0
+        end
+
+        def absolute_value(number)
+          number.respond_to?("abs") ? number.abs : number.sub(/\A-/, '')
+        end
+
+        def options
+          @options ||= begin
+            defaults = default_format_options.merge(i18n_opts)
+            # Override negative format if format options is given
+            defaults[:negative_format] = "-#{opts[:format]}" if opts[:format]
+            defaults.merge!(opts)
+          end
+        end
+
+        def i18n_opts
+          # Set International negative format if not exists
+          i18n = i18n_format_options
+          i18n[:negative_format] ||= "-#{i18n[:format]}" if i18n[:format]
+          i18n
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_delimited_converter.rb b/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_delimited_converter.rb
new file mode 100644
index 0000000..6405afc
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_delimited_converter.rb
@@ -0,0 +1,21 @@
+module ActiveSupport
+  module NumberHelper
+    class NumberToDelimitedConverter < NumberConverter #:nodoc:
+      self.validate_float = true
+
+      DELIMITED_REGEX = /(\d)(?=(\d\d\d)+(?!\d))/
+
+      def convert
+        parts.join(options[:separator])
+      end
+
+      private
+
+        def parts
+          left, right = number.to_s.split('.')
+          left.gsub!(DELIMITED_REGEX) { "#{$1}#{options[:delimiter]}" }
+          [left, right].compact
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_human_converter.rb b/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_human_converter.rb
new file mode 100644
index 0000000..9a3dc52
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_human_converter.rb
@@ -0,0 +1,66 @@
+module ActiveSupport
+  module NumberHelper
+    class NumberToHumanConverter < NumberConverter # :nodoc:
+      DECIMAL_UNITS = { 0 => :unit, 1 => :ten, 2 => :hundred, 3 => :thousand, 6 => :million, 9 => :billion, 12 => :trillion, 15 => :quadrillion,
+        -1 => :deci, -2 => :centi, -3 => :mili, -6 => :micro, -9 => :nano, -12 => :pico, -15 => :femto }
+      INVERTED_DECIMAL_UNITS = DECIMAL_UNITS.invert
+
+      self.namespace      = :human
+      self.validate_float = true
+
+      def convert # :nodoc:
+        @number = Float(number)
+
+        # for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
+        unless options.key?(:strip_insignificant_zeros)
+          options[:strip_insignificant_zeros] = true
+        end
+
+        units = opts[:units]
+        exponent = calculate_exponent(units)
+        @number = number / (10 ** exponent)
+
+        unit = determine_unit(units, exponent)
+
+        rounded_number = NumberToRoundedConverter.convert(number, options)
+        format.gsub(/%n/, rounded_number).gsub(/%u/, unit).strip
+      end
+
+      private
+
+        def format
+          options[:format] || translate_in_locale('human.decimal_units.format')
+        end
+
+        def determine_unit(units, exponent)
+          exp = DECIMAL_UNITS[exponent]
+          case units
+          when Hash
+            units[exp] || ''
+          when String, Symbol
+            I18n.translate("#{units}.#{exp}", :locale => options[:locale], :count => number.to_i)
+          else
+            translate_in_locale("human.decimal_units.units.#{exp}", count: number.to_i)
+          end
+        end
+
+        def calculate_exponent(units)
+          exponent = number != 0 ? Math.log10(number.abs).floor : 0
+          unit_exponents(units).find { |e| exponent >= e } || 0
+        end
+
+        def unit_exponents(units)
+          case units
+          when Hash
+            units
+          when String, Symbol
+            I18n.translate(units.to_s, :locale => options[:locale], :raise => true)
+          when nil
+            translate_in_locale("human.decimal_units.units", raise: true)
+          else
+            raise ArgumentError, ":units must be a Hash or String translation scope."
+          end.keys.map { |e_name| INVERTED_DECIMAL_UNITS[e_name] }.sort_by { |e| -e }
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_human_size_converter.rb b/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_human_size_converter.rb
new file mode 100644
index 0000000..78d2c9a
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_human_size_converter.rb
@@ -0,0 +1,58 @@
+module ActiveSupport
+  module NumberHelper
+    class NumberToHumanSizeConverter < NumberConverter #:nodoc:
+      STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb]
+
+      self.namespace      = :human
+      self.validate_float = true
+
+      def convert
+        @number = Float(number)
+
+        # for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
+        unless options.key?(:strip_insignificant_zeros)
+          options[:strip_insignificant_zeros] = true
+        end
+
+        if smaller_than_base?
+          number_to_format = number.to_i.to_s
+        else
+          human_size = number / (base ** exponent)
+          number_to_format = NumberToRoundedConverter.convert(human_size, options)
+        end
+        conversion_format.gsub(/%n/, number_to_format).gsub(/%u/, unit)
+      end
+
+      private
+
+        def conversion_format
+          translate_number_value_with_default('human.storage_units.format', :locale => options[:locale], :raise => true)
+        end
+
+        def unit
+          translate_number_value_with_default(storage_unit_key, :locale => options[:locale], :count => number.to_i, :raise => true)
+        end
+
+        def storage_unit_key
+          key_end = smaller_than_base? ? 'byte' : STORAGE_UNITS[exponent]
+          "human.storage_units.units.#{key_end}"
+        end
+
+        def exponent
+          max = STORAGE_UNITS.size - 1
+          exp = (Math.log(number) / Math.log(base)).to_i
+          exp = max if exp > max # avoid overflow for the highest unit
+          exp
+        end
+
+        def smaller_than_base?
+          number.to_i < base
+        end
+
+        def base
+          opts[:prefix] == :si ? 1000 : 1024
+        end
+    end
+  end
+end
+
diff --git a/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_percentage_converter.rb b/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_percentage_converter.rb
new file mode 100644
index 0000000..eafe284
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_percentage_converter.rb
@@ -0,0 +1,12 @@
+module ActiveSupport
+  module NumberHelper
+    class NumberToPercentageConverter < NumberConverter # :nodoc:
+      self.namespace = :percentage
+
+      def convert
+        rounded_number = NumberToRoundedConverter.convert(number, options)
+        options[:format].gsub('%n', rounded_number)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_phone_converter.rb b/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_phone_converter.rb
new file mode 100644
index 0000000..af2ee56
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_phone_converter.rb
@@ -0,0 +1,49 @@
+module ActiveSupport
+  module NumberHelper
+    class NumberToPhoneConverter < NumberConverter #:nodoc:
+      def convert
+        str  = country_code(opts[:country_code])
+        str << convert_to_phone_number(number.to_s.strip)
+        str << phone_ext(opts[:extension])
+      end
+
+      private
+
+        def convert_to_phone_number(number)
+          if opts[:area_code]
+            convert_with_area_code(number)
+          else
+            convert_without_area_code(number)
+          end
+        end
+
+        def convert_with_area_code(number)
+          number.gsub!(/(\d{1,3})(\d{3})(\d{4}$)/,"(\\1) \\2#{delimiter}\\3")
+          number
+        end
+
+        def convert_without_area_code(number)
+          number.gsub!(/(\d{0,3})(\d{3})(\d{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3")
+          number.slice!(0, 1) if start_with_delimiter?(number)
+          number
+        end
+
+        def start_with_delimiter?(number)
+          delimiter.present? && number.start_with?(delimiter)
+        end
+
+        def delimiter
+          opts[:delimiter] || "-"
+        end
+
+        def country_code(code)
+          code.blank? ? "" : "+#{code}#{delimiter}"
+        end
+
+        def phone_ext(ext)
+          ext.blank? ? "" : " x #{ext}"
+        end
+    end
+  end
+end
+
diff --git a/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb b/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb
new file mode 100644
index 0000000..c45f6cd
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb
@@ -0,0 +1,91 @@
+module ActiveSupport
+  module NumberHelper
+    class NumberToRoundedConverter < NumberConverter # :nodoc:
+      self.namespace      = :precision
+      self.validate_float = true
+
+      def convert
+        precision = options.delete :precision
+        significant = options.delete :significant
+
+        case number
+        when Float, String
+          @number = BigDecimal(number.to_s)
+        when Rational
+          if significant
+            @number = BigDecimal(number, digit_count(number.to_i) + precision)
+          else
+            @number = BigDecimal(number, precision)
+          end
+        else
+          @number = number.to_d
+        end
+
+        if significant && precision > 0
+          digits, rounded_number = digits_and_rounded_number(precision)
+          precision -= digits
+          precision = 0 if precision < 0 # don't let it be negative
+        else
+          rounded_number = number.round(precision)
+          rounded_number = rounded_number.to_i if precision == 0
+          rounded_number = rounded_number.abs if rounded_number.zero? # prevent showing negative zeros
+        end
+
+        formatted_string =
+          if BigDecimal === rounded_number && rounded_number.finite?
+            s = rounded_number.to_s('F') + '0'*precision
+            a, b = s.split('.', 2)
+            a + '.' + b[0, precision]
+          else
+            "%01.#{precision}f" % rounded_number
+          end
+
+        delimited_number = NumberToDelimitedConverter.convert(formatted_string, options)
+        format_number(delimited_number)
+      end
+
+      private
+
+        def digits_and_rounded_number(precision)
+          if zero?
+            [1, 0]
+          else
+            digits = digit_count(number)
+            multiplier = 10 ** (digits - precision)
+            rounded_number = calculate_rounded_number(multiplier)
+            digits = digit_count(rounded_number) # After rounding, the number of digits may have changed
+            [digits, rounded_number]
+          end
+        end
+
+        def calculate_rounded_number(multiplier)
+          (number / BigDecimal.new(multiplier.to_f.to_s)).round * multiplier
+        end
+
+        def digit_count(number)
+          (Math.log10(absolute_number(number)) + 1).floor
+        end
+
+        def strip_insignificant_zeros
+          options[:strip_insignificant_zeros]
+        end
+
+        def format_number(number)
+          if strip_insignificant_zeros
+            escaped_separator = Regexp.escape(options[:separator])
+            number.sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '')
+          else
+            number
+          end
+        end
+
+        def absolute_number(number)
+          number.respond_to?(:abs) ? number.abs : number.to_d.abs
+        end
+
+        def zero?
+          number.respond_to?(:zero?) ? number.zero? : number.to_d.zero?
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/option_merger.rb b/app/server/vendor/activesupport/lib/active_support/option_merger.rb
new file mode 100644
index 0000000..dea84e4
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/option_merger.rb
@@ -0,0 +1,25 @@
+require 'active_support/core_ext/hash/deep_merge'
+
+module ActiveSupport
+  class OptionMerger #:nodoc:
+    instance_methods.each do |method|
+      undef_method(method) if method !~ /^(__|instance_eval|class|object_id)/
+    end
+
+    def initialize(context, options)
+      @context, @options = context, options
+    end
+
+    private
+      def method_missing(method, *arguments, &block)
+        if arguments.first.is_a?(Proc)
+          proc = arguments.pop
+          arguments << lambda { |*args| @options.deep_merge(proc.call(*args)) }
+        else
+          arguments << (arguments.last.respond_to?(:to_hash) ? @options.deep_merge(arguments.pop) : @options.dup)
+        end
+
+        @context.__send__(method, *arguments, &block)
+      end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/ordered_hash.rb b/app/server/vendor/activesupport/lib/active_support/ordered_hash.rb
new file mode 100644
index 0000000..4680d5a
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/ordered_hash.rb
@@ -0,0 +1,48 @@
+require 'yaml'
+
+YAML.add_builtin_type("omap") do |type, val|
+  ActiveSupport::OrderedHash[val.map{ |v| v.to_a.first }]
+end
+
+module ActiveSupport
+  # <tt>ActiveSupport::OrderedHash</tt> implements a hash that preserves
+  # insertion order.
+  #
+  #   oh = ActiveSupport::OrderedHash.new
+  #   oh[:a] = 1
+  #   oh[:b] = 2
+  #   oh.keys # => [:a, :b], this order is guaranteed
+  #
+  # Also, maps the +omap+ feature for YAML files
+  # (See http://yaml.org/type/omap.html) to support ordered items
+  # when loading from yaml.
+  #
+  # <tt>ActiveSupport::OrderedHash</tt> is namespaced to prevent conflicts
+  # with other implementations.
+  class OrderedHash < ::Hash
+    def to_yaml_type
+      "!tag:yaml.org,2002:omap"
+    end
+
+    def encode_with(coder)
+      coder.represent_seq '!omap', map { |k,v| { k => v } }
+    end
+
+    def select(*args, &block)
+      dup.tap { |hash| hash.select!(*args, &block) }
+    end
+
+    def reject(*args, &block)
+      dup.tap { |hash| hash.reject!(*args, &block) }
+    end
+
+    def nested_under_indifferent_access
+      self
+    end
+
+    # Returns true to make sure that this hash is extractable via <tt>Array#extract_options!</tt>
+    def extractable_options?
+      true
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/ordered_options.rb b/app/server/vendor/activesupport/lib/active_support/ordered_options.rb
new file mode 100644
index 0000000..a33e2c5
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/ordered_options.rb
@@ -0,0 +1,67 @@
+module ActiveSupport
+  # Usually key value pairs are handled something like this:
+  #
+  #   h = {}
+  #   h[:boy] = 'John'
+  #   h[:girl] = 'Mary'
+  #   h[:boy]  # => 'John'
+  #   h[:girl] # => 'Mary'
+  #
+  # Using +OrderedOptions+, the above code could be reduced to:
+  #
+  #   h = ActiveSupport::OrderedOptions.new
+  #   h.boy = 'John'
+  #   h.girl = 'Mary'
+  #   h.boy  # => 'John'
+  #   h.girl # => 'Mary'
+  class OrderedOptions < Hash
+    alias_method :_get, :[] # preserve the original #[] method
+    protected :_get # make it protected
+
+    def []=(key, value)
+      super(key.to_sym, value)
+    end
+
+    def [](key)
+      super(key.to_sym)
+    end
+
+    def method_missing(name, *args)
+      name_string = name.to_s
+      if name_string.chomp!('=')
+        self[name_string] = args.first
+      else
+        self[name]
+      end
+    end
+
+    def respond_to_missing?(name, include_private)
+      true
+    end
+  end
+
+  # +InheritableOptions+ provides a constructor to build an +OrderedOptions+
+  # hash inherited from another hash.
+  #
+  # Use this if you already have some hash and you want to create a new one based on it.
+  #
+  #   h = ActiveSupport::InheritableOptions.new({ girl: 'Mary', boy: 'John' })
+  #   h.girl # => 'Mary'
+  #   h.boy  # => 'John'
+  class InheritableOptions < OrderedOptions
+    def initialize(parent = nil)
+      if parent.kind_of?(OrderedOptions)
+        # use the faster _get when dealing with OrderedOptions
+        super() { |h,k| parent._get(k) }
+      elsif parent
+        super() { |h,k| parent[k] }
+      else
+        super()
+      end
+    end
+
+    def inheritable_copy
+      self.class.new(self)
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/per_thread_registry.rb b/app/server/vendor/activesupport/lib/active_support/per_thread_registry.rb
new file mode 100644
index 0000000..ca2e4d5
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/per_thread_registry.rb
@@ -0,0 +1,53 @@
+module ActiveSupport
+  # This module is used to encapsulate access to thread local variables.
+  #
+  # Instead of polluting the thread locals namespace:
+  #
+  #   Thread.current[:connection_handler]
+  #
+  # you define a class that extends this module:
+  #
+  #   module ActiveRecord
+  #     class RuntimeRegistry
+  #       extend ActiveSupport::PerThreadRegistry
+  #
+  #       attr_accessor :connection_handler
+  #     end
+  #   end
+  #
+  # and invoke the declared instance accessors as class methods. So
+  #
+  #   ActiveRecord::RuntimeRegistry.connection_handler = connection_handler
+  #
+  # sets a connection handler local to the current thread, and
+  #
+  #   ActiveRecord::RuntimeRegistry.connection_handler
+  #
+  # returns a connection handler local to the current thread.
+  #
+  # This feature is accomplished by instantiating the class and storing the
+  # instance as a thread local keyed by the class name. In the example above
+  # a key "ActiveRecord::RuntimeRegistry" is stored in <tt>Thread.current</tt>.
+  # The class methods proxy to said thread local instance.
+  #
+  # If the class has an initializer, it must accept no arguments.
+  module PerThreadRegistry
+    def self.extended(object)
+      object.instance_variable_set '@per_thread_registry_key', object.name.freeze
+    end
+
+    def instance
+      Thread.current[@per_thread_registry_key] ||= new
+    end
+
+    protected
+      def method_missing(name, *args, &block) # :nodoc:
+        # Caches the method definition as a singleton method of the receiver.
+        define_singleton_method(name) do |*a, &b|
+          instance.public_send(name, *a, &b)
+        end
+
+        send(name, *args, &block)
+      end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/proxy_object.rb b/app/server/vendor/activesupport/lib/active_support/proxy_object.rb
new file mode 100644
index 0000000..20a0fd8
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/proxy_object.rb
@@ -0,0 +1,13 @@
+module ActiveSupport
+  # A class with no predefined methods that behaves similarly to Builder's
+  # BlankSlate. Used for proxy classes.
+  class ProxyObject < ::BasicObject
+    undef_method :==
+    undef_method :equal?
+
+    # Let ActiveSupport::ProxyObject at least raise exceptions.
+    def raise(*args)
+      ::Object.send(:raise, *args)
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/rails.rb b/app/server/vendor/activesupport/lib/active_support/rails.rb
new file mode 100644
index 0000000..b05c3ff
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/rails.rb
@@ -0,0 +1,27 @@
+# This is private interface.
+#
+# Rails components cherry pick from Active Support as needed, but there are a
+# few features that are used for sure some way or another and it is not worth
+# to put individual requires absolutely everywhere. Think blank? for example.
+#
+# This file is loaded by every Rails component except Active Support itself,
+# but it does not belong to the Rails public interface. It is internal to
+# Rails and can change anytime.
+
+# Defines Object#blank? and Object#present?.
+require 'active_support/core_ext/object/blank'
+
+# Rails own autoload, eager_load, etc.
+require 'active_support/dependencies/autoload'
+
+# Support for ClassMethods and the included macro.
+require 'active_support/concern'
+
+# Defines Class#class_attribute.
+require 'active_support/core_ext/class/attribute'
+
+# Defines Module#delegate.
+require 'active_support/core_ext/module/delegation'
+
+# Defines ActiveSupport::Deprecation.
+require 'active_support/deprecation'
diff --git a/app/server/vendor/activesupport/lib/active_support/railtie.rb b/app/server/vendor/activesupport/lib/active_support/railtie.rb
new file mode 100644
index 0000000..133aa6a
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/railtie.rb
@@ -0,0 +1,46 @@
+require "active_support"
+require "active_support/i18n_railtie"
+
+module ActiveSupport
+  class Railtie < Rails::Railtie # :nodoc:
+    config.active_support = ActiveSupport::OrderedOptions.new
+
+    config.eager_load_namespaces << ActiveSupport
+
+    initializer "active_support.deprecation_behavior" do |app|
+      if deprecation = app.config.active_support.deprecation
+        ActiveSupport::Deprecation.behavior = deprecation
+      end
+    end
+
+    # Sets the default value for Time.zone
+    # If assigned value cannot be matched to a TimeZone, an exception will be raised.
+    initializer "active_support.initialize_time_zone" do |app|
+      require 'active_support/core_ext/time/zones'
+      zone_default = Time.find_zone!(app.config.time_zone)
+
+      unless zone_default
+        raise 'Value assigned to config.time_zone not recognized. ' \
+          'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
+      end
+
+      Time.zone_default = zone_default
+    end
+
+    # Sets the default week start
+    # If assigned value is not a valid day symbol (e.g. :sunday, :monday, ...), an exception will be raised.
+    initializer "active_support.initialize_beginning_of_week" do |app|
+      require 'active_support/core_ext/date/calculations'
+      beginning_of_week_default = Date.find_beginning_of_week!(app.config.beginning_of_week)
+
+      Date.beginning_of_week_default = beginning_of_week_default
+    end
+
+    initializer "active_support.set_configs" do |app|
+      app.config.active_support.each do |k, v|
+        k = "#{k}="
+        ActiveSupport.send(k, v) if ActiveSupport.respond_to? k
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/rescuable.rb b/app/server/vendor/activesupport/lib/active_support/rescuable.rb
new file mode 100644
index 0000000..a7eba91
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/rescuable.rb
@@ -0,0 +1,119 @@
+require 'active_support/concern'
+require 'active_support/core_ext/class/attribute'
+require 'active_support/core_ext/string/inflections'
+require 'active_support/core_ext/array/extract_options'
+
+module ActiveSupport
+  # Rescuable module adds support for easier exception handling.
+  module Rescuable
+    extend Concern
+
+    included do
+      class_attribute :rescue_handlers
+      self.rescue_handlers = []
+    end
+
+    module ClassMethods
+      # Rescue exceptions raised in controller actions.
+      #
+      # <tt>rescue_from</tt> receives a series of exception classes or class
+      # names, and a trailing <tt>:with</tt> option with the name of a method
+      # or a Proc object to be called to handle them. Alternatively a block can
+      # be given.
+      #
+      # Handlers that take one argument will be called with the exception, so
+      # that the exception can be inspected when dealing with it.
+      #
+      # Handlers are inherited. They are searched from right to left, from
+      # bottom to top, and up the hierarchy. The handler of the first class for
+      # which <tt>exception.is_a?(klass)</tt> holds true is the one invoked, if
+      # any.
+      #
+      #   class ApplicationController < ActionController::Base
+      #     rescue_from User::NotAuthorized, with: :deny_access # self defined exception
+      #     rescue_from ActiveRecord::RecordInvalid, with: :show_errors
+      #
+      #     rescue_from 'MyAppError::Base' do |exception|
+      #       render xml: exception, status: 500
+      #     end
+      #
+      #     protected
+      #       def deny_access
+      #         ...
+      #       end
+      #
+      #       def show_errors(exception)
+      #         exception.record.new_record? ? ...
+      #       end
+      #   end
+      #
+      # Exceptions raised inside exception handlers are not propagated up.
+      def rescue_from(*klasses, &block)
+        options = klasses.extract_options!
+
+        unless options.has_key?(:with)
+          if block_given?
+            options[:with] = block
+          else
+            raise ArgumentError, "Need a handler. Supply an options hash that has a :with key as the last argument."
+          end
+        end
+
+        klasses.each do |klass|
+          key = if klass.is_a?(Class) && klass <= Exception
+            klass.name
+          elsif klass.is_a?(String)
+            klass
+          else
+            raise ArgumentError, "#{klass} is neither an Exception nor a String"
+          end
+
+          # put the new handler at the end because the list is read in reverse
+          self.rescue_handlers += [[key, options[:with]]]
+        end
+      end
+    end
+
+    # Tries to rescue the exception by looking up and calling a registered handler.
+    def rescue_with_handler(exception)
+      if handler = handler_for_rescue(exception)
+        handler.arity != 0 ? handler.call(exception) : handler.call
+        true # don't rely on the return value of the handler
+      end
+    end
+
+    def handler_for_rescue(exception)
+      # We go from right to left because pairs are pushed onto rescue_handlers
+      # as rescue_from declarations are found.
+      _, rescuer = self.class.rescue_handlers.reverse.detect do |klass_name, handler|
+        # The purpose of allowing strings in rescue_from is to support the
+        # declaration of handler associations for exception classes whose
+        # definition is yet unknown.
+        #
+        # Since this loop needs the constants it would be inconsistent to
+        # assume they should exist at this point. An early raised exception
+        # could trigger some other handler and the array could include
+        # precisely a string whose corresponding constant has not yet been
+        # seen. This is why we are tolerant to unknown constants.
+        #
+        # Note that this tolerance only matters if the exception was given as
+        # a string, otherwise a NameError will be raised by the interpreter
+        # itself when rescue_from CONSTANT is executed.
+        klass = self.class.const_get(klass_name) rescue nil
+        klass ||= klass_name.constantize rescue nil
+        exception.is_a?(klass) if klass
+      end
+
+      case rescuer
+      when Symbol
+        method(rescuer)
+      when Proc
+        if rescuer.arity == 0
+          Proc.new { instance_exec(&rescuer) }
+        else
+          Proc.new { |_exception| instance_exec(_exception, &rescuer) }
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/string_inquirer.rb b/app/server/vendor/activesupport/lib/active_support/string_inquirer.rb
new file mode 100644
index 0000000..45271c9
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/string_inquirer.rb
@@ -0,0 +1,26 @@
+module ActiveSupport
+  # Wrapping a string in this class gives you a prettier way to test
+  # for equality. The value returned by <tt>Rails.env</tt> is wrapped
+  # in a StringInquirer object so instead of calling this:
+  #
+  #   Rails.env == 'production'
+  #
+  # you can call this:
+  #
+  #   Rails.env.production?
+  class StringInquirer < String
+    private
+
+      def respond_to_missing?(method_name, include_private = false)
+        method_name[-1] == '?'
+      end
+
+      def method_missing(method_name, *arguments)
+        if method_name[-1] == '?'
+          self == method_name[0..-2]
+        else
+          super
+        end
+      end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/subscriber.rb b/app/server/vendor/activesupport/lib/active_support/subscriber.rb
new file mode 100644
index 0000000..4b9b485
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/subscriber.rb
@@ -0,0 +1,116 @@
+require 'active_support/per_thread_registry'
+
+module ActiveSupport
+  # ActiveSupport::Subscriber is an object set to consume
+  # ActiveSupport::Notifications. The subscriber dispatches notifications to
+  # a registered object based on its given namespace.
+  #
+  # An example would be Active Record subscriber responsible for collecting
+  # statistics about queries:
+  #
+  #   module ActiveRecord
+  #     class StatsSubscriber < ActiveSupport::Subscriber
+  #       def sql(event)
+  #         Statsd.timing("sql.#{event.payload[:name]}", event.duration)
+  #       end
+  #     end
+  #   end
+  #
+  # And it's finally registered as:
+  #
+  #   ActiveRecord::StatsSubscriber.attach_to :active_record
+  #
+  # Since we need to know all instance methods before attaching the log
+  # subscriber, the line above should be called after your subscriber definition.
+  #
+  # After configured, whenever a "sql.active_record" notification is published,
+  # it will properly dispatch the event (ActiveSupport::Notifications::Event) to
+  # the +sql+ method.
+  class Subscriber
+    class << self
+
+      # Attach the subscriber to a namespace.
+      def attach_to(namespace, subscriber=new, notifier=ActiveSupport::Notifications)
+        @namespace  = namespace
+        @subscriber = subscriber
+        @notifier   = notifier
+
+        subscribers << subscriber
+
+        # Add event subscribers for all existing methods on the class.
+        subscriber.public_methods(false).each do |event|
+          add_event_subscriber(event)
+        end
+      end
+
+      # Adds event subscribers for all new methods added to the class.
+      def method_added(event)
+        # Only public methods are added as subscribers, and only if a notifier
+        # has been set up. This means that subscribers will only be set up for
+        # classes that call #attach_to.
+        if public_method_defined?(event) && notifier
+          add_event_subscriber(event)
+        end
+      end
+
+      def subscribers
+        @@subscribers ||= []
+      end
+
+      protected
+
+      attr_reader :subscriber, :notifier, :namespace
+
+      def add_event_subscriber(event)
+        return if %w{ start finish }.include?(event.to_s)
+
+        notifier.subscribe("#{event}.#{namespace}", subscriber)
+      end
+    end
+
+    def initialize
+      @queue_key = [self.class.name, object_id].join "-"
+      super
+    end
+
+    def start(name, id, payload)
+      e = ActiveSupport::Notifications::Event.new(name, Time.now, nil, id, payload)
+      parent = event_stack.last
+      parent << e if parent
+
+      event_stack.push e
+    end
+
+    def finish(name, id, payload)
+      finished  = Time.now
+      event     = event_stack.pop
+      event.end = finished
+      event.payload.merge!(payload)
+
+      method = name.split('.').first
+      send(method, event)
+    end
+
+    private
+
+      def event_stack
+        SubscriberQueueRegistry.instance.get_queue(@queue_key)
+      end
+  end
+
+  # This is a registry for all the event stacks kept for subscribers.
+  #
+  # See the documentation of <tt>ActiveSupport::PerThreadRegistry</tt>
+  # for further details.
+  class SubscriberQueueRegistry # :nodoc:
+    extend PerThreadRegistry
+
+    def initialize
+      @registry = {}
+    end
+
+    def get_queue(queue_key)
+      @registry[queue_key] ||= []
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/tagged_logging.rb b/app/server/vendor/activesupport/lib/active_support/tagged_logging.rb
new file mode 100644
index 0000000..d5c2222
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/tagged_logging.rb
@@ -0,0 +1,76 @@
+require 'active_support/core_ext/module/delegation'
+require 'active_support/core_ext/object/blank'
+require 'logger'
+require 'active_support/logger'
+
+module ActiveSupport
+  # Wraps any standard Logger object to provide tagging capabilities.
+  #
+  #   logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
+  #   logger.tagged('BCX') { logger.info 'Stuff' }                            # Logs "[BCX] Stuff"
+  #   logger.tagged('BCX', "Jason") { logger.info 'Stuff' }                   # Logs "[BCX] [Jason] Stuff"
+  #   logger.tagged('BCX') { logger.tagged('Jason') { logger.info 'Stuff' } } # Logs "[BCX] [Jason] Stuff"
+  #
+  # This is used by the default Rails.logger as configured by Railties to make
+  # it easy to stamp log lines with subdomains, request ids, and anything else
+  # to aid debugging of multi-user production applications.
+  module TaggedLogging
+    module Formatter # :nodoc:
+      # This method is invoked when a log event occurs.
+      def call(severity, timestamp, progname, msg)
+        super(severity, timestamp, progname, "#{tags_text}#{msg}")
+      end
+
+      def tagged(*tags)
+        new_tags = push_tags(*tags)
+        yield self
+      ensure
+        pop_tags(new_tags.size)
+      end
+
+      def push_tags(*tags)
+        tags.flatten.reject(&:blank?).tap do |new_tags|
+          current_tags.concat new_tags
+        end
+      end
+
+      def pop_tags(size = 1)
+        current_tags.pop size
+      end
+
+      def clear_tags!
+        current_tags.clear
+      end
+
+      def current_tags
+        Thread.current[:activesupport_tagged_logging_tags] ||= []
+      end
+
+      private
+        def tags_text
+          tags = current_tags
+          if tags.any?
+            tags.collect { |tag| "[#{tag}] " }.join
+          end
+        end
+    end
+
+    def self.new(logger)
+      # Ensure we set a default formatter so we aren't extending nil!
+      logger.formatter ||= ActiveSupport::Logger::SimpleFormatter.new
+      logger.formatter.extend Formatter
+      logger.extend(self)
+    end
+
+    delegate :push_tags, :pop_tags, :clear_tags!, to: :formatter
+
+    def tagged(*tags)
+      formatter.tagged(*tags) { yield self }
+    end
+
+    def flush
+      clear_tags!
+      super if defined?(super)
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/test_case.rb b/app/server/vendor/activesupport/lib/active_support/test_case.rb
new file mode 100644
index 0000000..2fb5c04
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/test_case.rb
@@ -0,0 +1,66 @@
+gem 'minitest' # make sure we get the gem, not stdlib
+require 'minitest'
+require 'active_support/testing/tagged_logging'
+require 'active_support/testing/setup_and_teardown'
+require 'active_support/testing/assertions'
+require 'active_support/testing/deprecation'
+require 'active_support/testing/declarative'
+require 'active_support/testing/isolation'
+require 'active_support/testing/constant_lookup'
+require 'active_support/testing/time_helpers'
+require 'active_support/core_ext/kernel/reporting'
+require 'active_support/deprecation'
+
+begin
+  silence_warnings { require 'mocha/setup' }
+rescue LoadError
+end
+
+module ActiveSupport
+  class TestCase < ::Minitest::Test
+    Assertion = Minitest::Assertion
+
+    alias_method :method_name, :name
+
+    $tags = {}
+    def self.for_tag(tag)
+      yield if $tags[tag]
+    end
+
+    # FIXME: we have tests that depend on run order, we should fix that and
+    # remove this method call.
+    self.i_suck_and_my_tests_are_order_dependent!
+
+    include ActiveSupport::Testing::TaggedLogging
+    include ActiveSupport::Testing::SetupAndTeardown
+    include ActiveSupport::Testing::Assertions
+    include ActiveSupport::Testing::Deprecation
+    include ActiveSupport::Testing::TimeHelpers
+    extend ActiveSupport::Testing::Declarative
+
+    # test/unit backwards compatibility methods
+    alias :assert_raise :assert_raises
+    alias :assert_not_empty :refute_empty
+    alias :assert_not_equal :refute_equal
+    alias :assert_not_in_delta :refute_in_delta
+    alias :assert_not_in_epsilon :refute_in_epsilon
+    alias :assert_not_includes :refute_includes
+    alias :assert_not_instance_of :refute_instance_of
+    alias :assert_not_kind_of :refute_kind_of
+    alias :assert_no_match :refute_match
+    alias :assert_not_nil :refute_nil
+    alias :assert_not_operator :refute_operator
+    alias :assert_not_predicate :refute_predicate
+    alias :assert_not_respond_to :refute_respond_to
+    alias :assert_not_same :refute_same
+
+    # Fails if the block raises an exception.
+    #
+    #   assert_nothing_raised do
+    #     ...
+    #   end
+    def assert_nothing_raised(*args)
+      yield
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/testing/assertions.rb b/app/server/vendor/activesupport/lib/active_support/testing/assertions.rb
new file mode 100644
index 0000000..76a591b
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/testing/assertions.rb
@@ -0,0 +1,97 @@
+require 'active_support/core_ext/object/blank'
+
+module ActiveSupport
+  module Testing
+    module Assertions
+      # Assert that an expression is not truthy. Passes if <tt>object</tt> is
+      # +nil+ or +false+. "Truthy" means "considered true in a conditional"
+      # like <tt>if foo</tt>.
+      #
+      #   assert_not nil    # => true
+      #   assert_not false  # => true
+      #   assert_not 'foo'  # => 'foo' is not nil or false
+      #
+      # An error message can be specified.
+      #
+      #   assert_not foo, 'foo should be false'
+      def assert_not(object, message = nil)
+        message ||= "Expected #{mu_pp(object)} to be nil or false"
+        assert !object, message
+      end
+
+      # Test numeric difference between the return value of an expression as a
+      # result of what is evaluated in the yielded block.
+      #
+      #   assert_difference 'Article.count' do
+      #     post :create, article: {...}
+      #   end
+      #
+      # An arbitrary expression is passed in and evaluated.
+      #
+      #   assert_difference 'assigns(:article).comments(:reload).size' do
+      #     post :create, comment: {...}
+      #   end
+      #
+      # An arbitrary positive or negative difference can be specified.
+      # The default is <tt>1</tt>.
+      #
+      #   assert_difference 'Article.count', -1 do
+      #     post :delete, id: ...
+      #   end
+      #
+      # An array of expressions can also be passed in and evaluated.
+      #
+      #   assert_difference [ 'Article.count', 'Post.count' ], 2 do
+      #     post :create, article: {...}
+      #   end
+      #
+      # A lambda or a list of lambdas can be passed in and evaluated:
+      #
+      #   assert_difference ->{ Article.count }, 2 do
+      #     post :create, article: {...}
+      #   end
+      #
+      #   assert_difference [->{ Article.count }, ->{ Post.count }], 2 do
+      #     post :create, article: {...}
+      #   end
+      #
+      # An error message can be specified.
+      #
+      #   assert_difference 'Article.count', -1, 'An Article should be destroyed' do
+      #     post :delete, id: ...
+      #   end
+      def assert_difference(expression, difference = 1, message = nil, &block)
+        expressions = Array(expression)
+
+        exps = expressions.map { |e|
+          e.respond_to?(:call) ? e : lambda { eval(e, block.binding) }
+        }
+        before = exps.map { |e| e.call }
+
+        yield
+
+        expressions.zip(exps).each_with_index do |(code, e), i|
+          error  = "#{code.inspect} didn't change by #{difference}"
+          error  = "#{message}.\n#{error}" if message
+          assert_equal(before[i] + difference, e.call, error)
+        end
+      end
+
+      # Assertion that the numeric result of evaluating an expression is not
+      # changed before and after invoking the passed in block.
+      #
+      #   assert_no_difference 'Article.count' do
+      #     post :create, article: invalid_attributes
+      #   end
+      #
+      # An error message can be specified.
+      #
+      #   assert_no_difference 'Article.count', 'An Article should not be created' do
+      #     post :create, article: invalid_attributes
+      #   end
+      def assert_no_difference(expression, message = nil, &block)
+        assert_difference expression, 0, message, &block
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/testing/autorun.rb b/app/server/vendor/activesupport/lib/active_support/testing/autorun.rb
new file mode 100644
index 0000000..5aa5f46
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/testing/autorun.rb
@@ -0,0 +1,5 @@
+gem 'minitest'
+
+require 'minitest'
+
+Minitest.autorun
diff --git a/app/server/vendor/activesupport/lib/active_support/testing/constant_lookup.rb b/app/server/vendor/activesupport/lib/active_support/testing/constant_lookup.rb
new file mode 100644
index 0000000..1b2a75c
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/testing/constant_lookup.rb
@@ -0,0 +1,54 @@
+require "active_support/concern"
+require "active_support/inflector"
+
+module ActiveSupport
+  module Testing
+    # Resolves a constant from a minitest spec name.
+    #
+    # Given the following spec-style test:
+    #
+    #   describe WidgetsController, :index do
+    #     describe "authenticated user" do
+    #       describe "returns widgets" do
+    #         it "has a controller that exists" do
+    #           assert_kind_of WidgetsController, @controller
+    #         end
+    #       end
+    #     end
+    #   end
+    #
+    # The test will have the following name:
+    #
+    #   "WidgetsController::index::authenticated user::returns widgets"
+    #
+    # The constant WidgetsController can be resolved from the name.
+    # The following code will resolve the constant:
+    #
+    #   controller = determine_constant_from_test_name(name) do |constant|
+    #     Class === constant && constant < ::ActionController::Metal
+    #   end
+    module ConstantLookup
+      extend ::ActiveSupport::Concern
+
+      module ClassMethods  # :nodoc:
+        def determine_constant_from_test_name(test_name)
+          names = test_name.split "::"
+          while names.size > 0 do
+            names.last.sub!(/Test$/, "")
+            begin
+              constant = names.join("::").constantize
+              break(constant) if yield(constant)
+            rescue NoMethodError # subclass of NameError
+              raise
+            rescue NameError
+              # Constant wasn't found, move on
+            ensure
+              names.pop
+            end
+          end
+        end
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/testing/declarative.rb b/app/server/vendor/activesupport/lib/active_support/testing/declarative.rb
new file mode 100644
index 0000000..e709e6e
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/testing/declarative.rb
@@ -0,0 +1,50 @@
+module ActiveSupport
+  module Testing
+    module Declarative
+
+      def self.extended(klass) #:nodoc:
+        klass.class_eval do
+
+          unless method_defined?(:describe)
+            def self.describe(text)
+              if block_given?
+                super
+              else
+                message = "`describe` without a block is deprecated, please switch to: `def self.name; #{text.inspect}; end`\n"
+                ActiveSupport::Deprecation.warn message
+
+                class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
+                  def self.name
+                    "#{text}"
+                  end
+                RUBY_EVAL
+              end
+            end
+          end
+
+        end
+      end
+
+      unless defined?(Spec)
+        # Helper to define a test method using a String. Under the hood, it replaces
+        # spaces with underscores and defines the test method.
+        #
+        #   test "verify something" do
+        #     ...
+        #   end
+        def test(name, &block)
+          test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
+          defined = method_defined? test_name
+          raise "#{test_name} is already defined in #{self}" if defined
+          if block_given?
+            define_method(test_name, &block)
+          else
+            define_method(test_name) do
+              flunk "No implementation provided for #{name}"
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/testing/deprecation.rb b/app/server/vendor/activesupport/lib/active_support/testing/deprecation.rb
new file mode 100644
index 0000000..6c94c61
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/testing/deprecation.rb
@@ -0,0 +1,35 @@
+require 'active_support/deprecation'
+
+module ActiveSupport
+  module Testing
+    module Deprecation #:nodoc:
+      def assert_deprecated(match = nil, &block)
+        result, warnings = collect_deprecations(&block)
+        assert !warnings.empty?, "Expected a deprecation warning within the block but received none"
+        if match
+          match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp)
+          assert warnings.any? { |w| w =~ match }, "No deprecation warning matched #{match}: #{warnings.join(', ')}"
+        end
+        result
+      end
+
+      def assert_not_deprecated(&block)
+        result, deprecations = collect_deprecations(&block)
+        assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n  #{deprecations * "\n  "}"
+        result
+      end
+
+      def collect_deprecations
+        old_behavior = ActiveSupport::Deprecation.behavior
+        deprecations = []
+        ActiveSupport::Deprecation.behavior = Proc.new do |message, callstack|
+          deprecations << message
+        end
+        result = yield
+        [result, deprecations]
+      ensure
+        ActiveSupport::Deprecation.behavior = old_behavior
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/testing/isolation.rb b/app/server/vendor/activesupport/lib/active_support/testing/isolation.rb
new file mode 100644
index 0000000..908af17
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/testing/isolation.rb
@@ -0,0 +1,91 @@
+require 'rbconfig'
+
+module ActiveSupport
+  module Testing
+    module Isolation
+      require 'thread'
+
+      def self.included(klass) #:nodoc:
+        klass.class_eval do
+          parallelize_me!
+        end
+      end
+
+      def self.forking_env?
+        !ENV["NO_FORK"] && ((RbConfig::CONFIG['host_os'] !~ /mswin|mingw/) && (RUBY_PLATFORM !~ /java/))
+      end
+
+      @@class_setup_mutex = Mutex.new
+
+      def _run_class_setup      # class setup method should only happen in parent
+        @@class_setup_mutex.synchronize do
+          unless defined?(@@ran_class_setup) || ENV['ISOLATION_TEST']
+            self.class.setup if self.class.respond_to?(:setup)
+            @@ran_class_setup = true
+          end
+        end
+      end
+
+      def run
+        serialized = run_in_isolation do
+          super
+        end
+
+        Marshal.load(serialized)
+      end
+
+      module Forking
+        def run_in_isolation(&blk)
+          read, write = IO.pipe
+          read.binmode
+          write.binmode
+
+          pid = fork do
+            read.close
+            yield
+            write.puts [Marshal.dump(self.dup)].pack("m")
+            exit!
+          end
+
+          write.close
+          result = read.read
+          Process.wait2(pid)
+          return result.unpack("m")[0]
+        end
+      end
+
+      module Subprocess
+        ORIG_ARGV = ARGV.dup unless defined?(ORIG_ARGV)
+
+        # Crazy H4X to get this working in windows / jruby with
+        # no forking.
+        def run_in_isolation(&blk)
+          require "tempfile"
+
+          if ENV["ISOLATION_TEST"]
+            yield
+            File.open(ENV["ISOLATION_OUTPUT"], "w") do |file|
+              file.puts [Marshal.dump(self.dup)].pack("m")
+            end
+            exit!
+          else
+            Tempfile.open("isolation") do |tmpfile|
+              ENV["ISOLATION_TEST"]   = self.class.name
+              ENV["ISOLATION_OUTPUT"] = tmpfile.path
+
+              load_paths = $-I.map {|p| "-I\"#{File.expand_path(p)}\"" }.join(" ")
+              `#{Gem.ruby} #{load_paths} #{$0} #{ORIG_ARGV.join(" ")}`
+
+              ENV.delete("ISOLATION_TEST")
+              ENV.delete("ISOLATION_OUTPUT")
+
+              return tmpfile.read.unpack("m")[0]
+            end
+          end
+        end
+      end
+
+      include forking_env? ? Forking : Subprocess
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/testing/setup_and_teardown.rb b/app/server/vendor/activesupport/lib/active_support/testing/setup_and_teardown.rb
new file mode 100644
index 0000000..33f2b8d
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/testing/setup_and_teardown.rb
@@ -0,0 +1,50 @@
+require 'active_support/concern'
+require 'active_support/callbacks'
+
+module ActiveSupport
+  module Testing
+    # Adds support for +setup+ and +teardown+ callbacks.
+    # These callbacks serve as a replacement to overwriting the
+    # <tt>#setup</tt> and <tt>#teardown</tt> methods of your TestCase.
+    #
+    #   class ExampleTest < ActiveSupport::TestCase
+    #     setup do
+    #       # ...
+    #     end
+    #
+    #     teardown do
+    #       # ...
+    #     end
+    #   end
+    module SetupAndTeardown
+      extend ActiveSupport::Concern
+
+      included do
+        include ActiveSupport::Callbacks
+        define_callbacks :setup, :teardown
+      end
+
+      module ClassMethods
+        # Add a callback, which runs before <tt>TestCase#setup</tt>.
+        def setup(*args, &block)
+          set_callback(:setup, :before, *args, &block)
+        end
+
+        # Add a callback, which runs after <tt>TestCase#teardown</tt>.
+        def teardown(*args, &block)
+          set_callback(:teardown, :after, *args, &block)
+        end
+      end
+
+      def before_setup # :nodoc:
+        super
+        run_callbacks :setup
+      end
+
+      def after_teardown # :nodoc:
+        run_callbacks :teardown
+        super
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/testing/tagged_logging.rb b/app/server/vendor/activesupport/lib/active_support/testing/tagged_logging.rb
new file mode 100644
index 0000000..f4cee64
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/testing/tagged_logging.rb
@@ -0,0 +1,25 @@
+module ActiveSupport
+  module Testing
+    # Logs a "PostsControllerTest: test name" heading before each test to
+    # make test.log easier to search and follow along with.
+    module TaggedLogging #:nodoc:
+      attr_writer :tagged_logger
+
+      def before_setup
+        if tagged_logger
+          heading = "#{self.class}: #{name}"
+          divider = '-' * heading.size
+          tagged_logger.info divider
+          tagged_logger.info heading
+          tagged_logger.info divider
+        end
+        super
+      end
+
+      private
+        def tagged_logger
+          @tagged_logger ||= (defined?(Rails.logger) && Rails.logger)
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/testing/time_helpers.rb b/app/server/vendor/activesupport/lib/active_support/testing/time_helpers.rb
new file mode 100644
index 0000000..eefa842
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/testing/time_helpers.rb
@@ -0,0 +1,127 @@
+module ActiveSupport
+  module Testing
+    class SimpleStubs # :nodoc:
+      Stub = Struct.new(:object, :method_name, :original_method)
+
+      def initialize
+        @stubs = {}
+      end
+
+      def stub_object(object, method_name, return_value)
+        key = [object.object_id, method_name]
+
+        if stub = @stubs[key]
+          unstub_object(stub)
+        end
+
+        new_name = "__simple_stub__#{method_name}"
+
+        @stubs[key] = Stub.new(object, method_name, new_name)
+
+        object.singleton_class.send :alias_method, new_name, method_name
+        object.define_singleton_method(method_name) { return_value }
+      end
+
+      def unstub_all!
+        @stubs.each_value do |stub|
+          unstub_object(stub)
+        end
+        @stubs = {}
+      end
+
+      private
+
+        def unstub_object(stub)
+          singleton_class = stub.object.singleton_class
+          singleton_class.send :undef_method, stub.method_name
+          singleton_class.send :alias_method, stub.method_name, stub.original_method
+          singleton_class.send :undef_method, stub.original_method
+        end
+    end
+
+    # Containing helpers that helps you test passage of time.
+    module TimeHelpers
+      # Changes current time to the time in the future or in the past by a given time difference by
+      # stubbing +Time.now+ and +Date.today+.
+      #
+      #   Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+      #   travel 1.day
+      #   Time.current # => Sun, 10 Nov 2013 15:34:49 EST -05:00
+      #   Date.current # => Sun, 10 Nov 2013
+      #
+      # This method also accepts a block, which will return the current time back to its original
+      # state at the end of the block:
+      #
+      #   Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+      #   travel 1.day do
+      #     User.create.created_at # => Sun, 10 Nov 2013 15:34:49 EST -05:00
+      #   end
+      #   Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+      def travel(duration, &block)
+        travel_to Time.now + duration, &block
+      end
+
+      # Changes current time to the given time by stubbing +Time.now+ and
+      # +Date.today+ to return the time or date passed into this method.
+      #
+      #   Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+      #   travel_to Time.new(2004, 11, 24, 01, 04, 44)
+      #   Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
+      #   Date.current # => Wed, 24 Nov 2004
+      #
+      # Dates are taken as their timestamp at the beginning of the day in the
+      # application time zone. <tt>Time.current</tt> returns said timestamp,
+      # and <tt>Time.now</tt> its equivalent in the system time zone. Similarly,
+      # <tt>Date.current</tt> returns a date equal to the argument, and
+      # <tt>Date.today</tt> the date according to <tt>Time.now</tt>, which may
+      # be different. (Note that you rarely want to deal with <tt>Time.now</tt>,
+      # or <tt>Date.today</tt>, in order to honor the application time zone
+      # please always use <tt>Time.current</tt> and <tt>Date.current</tt>.)
+      #
+      # This method also accepts a block, which will return the current time back to its original
+      # state at the end of the block:
+      #
+      #   Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+      #   travel_to Time.new(2004, 11, 24, 01, 04, 44) do
+      #     Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
+      #   end
+      #   Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+      def travel_to(date_or_time, &block)
+        if date_or_time.is_a?(Date) && !date_or_time.is_a?(DateTime)
+          now = date_or_time.midnight.to_time
+        else
+          now = date_or_time.to_time
+        end
+
+        simple_stubs.stub_object(Time, :now, now)
+        simple_stubs.stub_object(Date, :today, now.to_date)
+
+        if block_given?
+          begin
+            block.call
+          ensure
+            travel_back
+          end
+        end
+      end
+
+      # Returns the current time back to its original state, by removing the stubs added by
+      # `travel` and `travel_to`.
+      #
+      #   Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+      #   travel_to Time.new(2004, 11, 24, 01, 04, 44)
+      #   Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
+      #   travel_back
+      #   Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+      def travel_back
+        simple_stubs.unstub_all!
+      end
+
+      private
+
+        def simple_stubs
+          @simple_stubs ||= SimpleStubs.new
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/time.rb b/app/server/vendor/activesupport/lib/active_support/time.rb
new file mode 100644
index 0000000..92a5939
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/time.rb
@@ -0,0 +1,20 @@
+require 'active_support'
+
+module ActiveSupport
+  autoload :Duration, 'active_support/duration'
+  autoload :TimeWithZone, 'active_support/time_with_zone'
+  autoload :TimeZone, 'active_support/values/time_zone'
+end
+
+require 'date'
+require 'time'
+
+require 'active_support/core_ext/time'
+require 'active_support/core_ext/date'
+require 'active_support/core_ext/date_time'
+
+require 'active_support/core_ext/integer/time'
+require 'active_support/core_ext/numeric/time'
+
+require 'active_support/core_ext/string/conversions'
+require 'active_support/core_ext/string/zones'
diff --git a/app/server/vendor/activesupport/lib/active_support/time_with_zone.rb b/app/server/vendor/activesupport/lib/active_support/time_with_zone.rb
new file mode 100644
index 0000000..c25c97c
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/time_with_zone.rb
@@ -0,0 +1,402 @@
+require 'active_support/values/time_zone'
+require 'active_support/core_ext/object/acts_like'
+
+module ActiveSupport
+  # A Time-like class that can represent a time in any time zone. Necessary
+  # because standard Ruby Time instances are limited to UTC and the
+  # system's <tt>ENV['TZ']</tt> zone.
+  #
+  # You shouldn't ever need to create a TimeWithZone instance directly via +new+.
+  # Instead use methods +local+, +parse+, +at+ and +now+ on TimeZone instances,
+  # and +in_time_zone+ on Time and DateTime instances.
+  #
+  #   Time.zone = 'Eastern Time (US & Canada)'        # => 'Eastern Time (US & Canada)'
+  #   Time.zone.local(2007, 2, 10, 15, 30, 45)        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
+  #   Time.zone.parse('2007-02-10 15:30:45')          # => Sat, 10 Feb 2007 15:30:45 EST -05:00
+  #   Time.zone.at(1170361845)                        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
+  #   Time.zone.now                                   # => Sun, 18 May 2008 13:07:55 EDT -04:00
+  #   Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone  # => Sat, 10 Feb 2007 15:30:45 EST -05:00
+  #
+  # See Time and TimeZone for further documentation of these methods.
+  #
+  # TimeWithZone instances implement the same API as Ruby Time instances, so
+  # that Time and TimeWithZone instances are interchangeable.
+  #
+  #   t = Time.zone.now                     # => Sun, 18 May 2008 13:27:25 EDT -04:00
+  #   t.hour                                # => 13
+  #   t.dst?                                # => true
+  #   t.utc_offset                          # => -14400
+  #   t.zone                                # => "EDT"
+  #   t.to_s(:rfc822)                       # => "Sun, 18 May 2008 13:27:25 -0400"
+  #   t + 1.day                             # => Mon, 19 May 2008 13:27:25 EDT -04:00
+  #   t.beginning_of_year                   # => Tue, 01 Jan 2008 00:00:00 EST -05:00
+  #   t > Time.utc(1999)                    # => true
+  #   t.is_a?(Time)                         # => true
+  #   t.is_a?(ActiveSupport::TimeWithZone)  # => true
+  class TimeWithZone
+
+    # Report class name as 'Time' to thwart type checking.
+    def self.name
+      'Time'
+    end
+
+    include Comparable
+    attr_reader :time_zone
+
+    def initialize(utc_time, time_zone, local_time = nil, period = nil)
+      @utc, @time_zone, @time = utc_time, time_zone, local_time
+      @period = @utc ? period : get_period_and_ensure_valid_local_time(period)
+    end
+
+    # Returns a Time or DateTime instance that represents the time in +time_zone+.
+    def time
+      @time ||= period.to_local(@utc)
+    end
+
+    # Returns a Time or DateTime instance that represents the time in UTC.
+    def utc
+      @utc ||= period.to_utc(@time)
+    end
+    alias_method :comparable_time, :utc
+    alias_method :getgm, :utc
+    alias_method :getutc, :utc
+    alias_method :gmtime, :utc
+
+    # Returns the underlying TZInfo::TimezonePeriod.
+    def period
+      @period ||= time_zone.period_for_utc(@utc)
+    end
+
+    # Returns the simultaneous time in <tt>Time.zone</tt>, or the specified zone.
+    def in_time_zone(new_zone = ::Time.zone)
+      return self if time_zone == new_zone
+      utc.in_time_zone(new_zone)
+    end
+
+    # Returns a <tt>Time.local()</tt> instance of the simultaneous time in your
+    # system's <tt>ENV['TZ']</tt> zone.
+    def localtime
+      utc.respond_to?(:getlocal) ? utc.getlocal : utc.to_time.getlocal
+    end
+    alias_method :getlocal, :localtime
+
+    # Returns true if the current time is within Daylight Savings Time for the
+    # specified time zone.
+    #
+    #   Time.zone = 'Eastern Time (US & Canada)'    # => 'Eastern Time (US & Canada)'
+    #   Time.zone.parse("2012-5-30").dst?           # => true
+    #   Time.zone.parse("2012-11-30").dst?          # => false
+    def dst?
+      period.dst?
+    end
+    alias_method :isdst, :dst?
+
+    # Returns true if the current time zone is set to UTC.
+    #
+    #   Time.zone = 'UTC'                           # => 'UTC'
+    #   Time.zone.now.utc?                          # => true
+    #   Time.zone = 'Eastern Time (US & Canada)'    # => 'Eastern Time (US & Canada)'
+    #   Time.zone.now.utc?                          # => false
+    def utc?
+      time_zone.name == 'UTC'
+    end
+    alias_method :gmt?, :utc?
+
+    # Returns the offset from current time to UTC time in seconds.
+    def utc_offset
+      period.utc_total_offset
+    end
+    alias_method :gmt_offset, :utc_offset
+    alias_method :gmtoff, :utc_offset
+
+    # Returns a formatted string of the offset from UTC, or an alternative
+    # string if the time zone is already UTC.
+    #
+    #   Time.zone = 'Eastern Time (US & Canada)'   # => "Eastern Time (US & Canada)"
+    #   Time.zone.now.formatted_offset(true)       # => "-05:00"
+    #   Time.zone.now.formatted_offset(false)      # => "-0500"
+    #   Time.zone = 'UTC'                          # => "UTC"
+    #   Time.zone.now.formatted_offset(true, "0")  # => "0"
+    def formatted_offset(colon = true, alternate_utc_string = nil)
+      utc? && alternate_utc_string || TimeZone.seconds_to_utc_offset(utc_offset, colon)
+    end
+
+    # Time uses +zone+ to display the time zone abbreviation, so we're
+    # duck-typing it.
+    def zone
+      period.zone_identifier.to_s
+    end
+
+    def inspect
+      "#{time.strftime('%a, %d %b %Y %H:%M:%S')} #{zone} #{formatted_offset}"
+    end
+
+    def xmlschema(fraction_digits = 0)
+      fraction = if fraction_digits.to_i > 0
+        (".%06i" % time.usec)[0, fraction_digits.to_i + 1]
+      end
+
+      "#{time.strftime("%Y-%m-%dT%H:%M:%S")}#{fraction}#{formatted_offset(true, 'Z')}"
+    end
+    alias_method :iso8601, :xmlschema
+
+    # Coerces time to a string for JSON encoding. The default format is ISO 8601.
+    # You can get %Y/%m/%d %H:%M:%S +offset style by setting
+    # <tt>ActiveSupport::JSON::Encoding.use_standard_json_time_format</tt>
+    # to +false+.
+    #
+    #   # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
+    #   Time.utc(2005,2,1,15,15,10).in_time_zone("Hawaii").to_json
+    #   # => "2005-02-01T05:15:10.000-10:00"
+    #
+    #   # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
+    #   Time.utc(2005,2,1,15,15,10).in_time_zone("Hawaii").to_json
+    #   # => "2005/02/01 05:15:10 -1000"
+    def as_json(options = nil)
+      if ActiveSupport::JSON::Encoding.use_standard_json_time_format
+        xmlschema(ActiveSupport::JSON::Encoding.time_precision)
+      else
+        %(#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
+      end
+    end
+
+    def encode_with(coder)
+      if coder.respond_to?(:represent_object)
+        coder.represent_object(nil, utc)
+      else
+        coder.represent_scalar(nil, utc.strftime("%Y-%m-%d %H:%M:%S.%9NZ"))
+      end
+    end
+
+    # Returns a string of the object's date and time in the format used by
+    # HTTP requests.
+    #
+    #   Time.zone.now.httpdate  # => "Tue, 01 Jan 2013 04:39:43 GMT"
+    def httpdate
+      utc.httpdate
+    end
+
+    # Returns a string of the object's date and time in the RFC 2822 standard
+    # format.
+    #
+    #   Time.zone.now.rfc2822  # => "Tue, 01 Jan 2013 04:51:39 +0000"
+    def rfc2822
+      to_s(:rfc822)
+    end
+    alias_method :rfc822, :rfc2822
+
+    # <tt>:db</tt> format outputs time in UTC; all others output time in local.
+    # Uses TimeWithZone's +strftime+, so <tt>%Z</tt> and <tt>%z</tt> work correctly.
+    def to_s(format = :default)
+      if format == :db
+        utc.to_s(format)
+      elsif formatter = ::Time::DATE_FORMATS[format]
+        formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
+      else
+        "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby 1.9 Time#to_s format
+      end
+    end
+    alias_method :to_formatted_s, :to_s
+
+    # Replaces <tt>%Z</tt> and <tt>%z</tt> directives with +zone+ and
+    # +formatted_offset+, respectively, before passing to Time#strftime, so
+    # that zone information is correct
+    def strftime(format)
+      format = format.gsub('%Z', zone)
+                     .gsub('%z',   formatted_offset(false))
+                     .gsub('%:z',  formatted_offset(true))
+                     .gsub('%::z', formatted_offset(true) + ":00")
+      time.strftime(format)
+    end
+
+    # Use the time in UTC for comparisons.
+    def <=>(other)
+      utc <=> other
+    end
+
+    # Returns true if the current object's time is within the specified
+    # +min+ and +max+ time.
+    def between?(min, max)
+      utc.between?(min, max)
+    end
+
+    # Returns true if the current object's time is in the past.
+    def past?
+      utc.past?
+    end
+
+    # Returns true if the current object's time falls within
+    # the current day.
+    def today?
+      time.today?
+    end
+
+    # Returns true if the current object's time is in the future.
+    def future?
+      utc.future?
+    end
+
+    def eql?(other)
+      utc.eql?(other)
+    end
+
+    def hash
+      utc.hash
+    end
+
+    def +(other)
+      # If we're adding a Duration of variable length (i.e., years, months, days), move forward from #time,
+      # otherwise move forward from #utc, for accuracy when moving across DST boundaries
+      if duration_of_variable_length?(other)
+        method_missing(:+, other)
+      else
+        result = utc.acts_like?(:date) ? utc.since(other) : utc + other rescue utc.since(other)
+        result.in_time_zone(time_zone)
+      end
+    end
+
+    def -(other)
+      # If we're subtracting a Duration of variable length (i.e., years, months, days), move backwards from #time,
+      # otherwise move backwards #utc, for accuracy when moving across DST boundaries
+      if other.acts_like?(:time)
+        utc.to_f - other.to_f
+      elsif duration_of_variable_length?(other)
+        method_missing(:-, other)
+      else
+        result = utc.acts_like?(:date) ? utc.ago(other) : utc - other rescue utc.ago(other)
+        result.in_time_zone(time_zone)
+      end
+    end
+
+    def since(other)
+      # If we're adding a Duration of variable length (i.e., years, months, days), move forward from #time,
+      # otherwise move forward from #utc, for accuracy when moving across DST boundaries
+      if duration_of_variable_length?(other)
+        method_missing(:since, other)
+      else
+        utc.since(other).in_time_zone(time_zone)
+      end
+    end
+
+    def ago(other)
+      since(-other)
+    end
+
+    def advance(options)
+      # If we're advancing a value of variable length (i.e., years, weeks, months, days), advance from #time,
+      # otherwise advance from #utc, for accuracy when moving across DST boundaries
+      if options.values_at(:years, :weeks, :months, :days).any?
+        method_missing(:advance, options)
+      else
+        utc.advance(options).in_time_zone(time_zone)
+      end
+    end
+
+    %w(year mon month day mday wday yday hour min sec usec nsec to_date).each do |method_name|
+      class_eval <<-EOV, __FILE__, __LINE__ + 1
+        def #{method_name}    # def month
+          time.#{method_name} #   time.month
+        end                   # end
+      EOV
+    end
+
+    def to_a
+      [time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone]
+    end
+
+    def to_f
+      utc.to_f
+    end
+
+    def to_i
+      utc.to_i
+    end
+    alias_method :tv_sec, :to_i
+
+    def to_r
+      utc.to_r
+    end
+
+    # Return an instance of Time in the system timezone.
+    def to_time
+      utc.to_time
+    end
+
+    def to_datetime
+      utc.to_datetime.new_offset(Rational(utc_offset, 86_400))
+    end
+
+    # So that +self+ <tt>acts_like?(:time)</tt>.
+    def acts_like_time?
+      true
+    end
+
+    # Say we're a Time to thwart type checking.
+    def is_a?(klass)
+      klass == ::Time || super
+    end
+    alias_method :kind_of?, :is_a?
+
+    def freeze
+      period; utc; time # preload instance variables before freezing
+      super
+    end
+
+    def marshal_dump
+      [utc, time_zone.name, time]
+    end
+
+    def marshal_load(variables)
+      initialize(variables[0].utc, ::Time.find_zone(variables[1]), variables[2].utc)
+    end
+
+    # Ensure proxy class responds to all methods that underlying time instance
+    # responds to.
+    def respond_to_missing?(sym, include_priv)
+      # consistently respond false to acts_like?(:date), regardless of whether #time is a Time or DateTime
+      return false if sym.to_sym == :acts_like_date?
+      time.respond_to?(sym, include_priv)
+    end
+
+    # Send the missing method to +time+ instance, and wrap result in a new
+    # TimeWithZone with the existing +time_zone+.
+    def method_missing(sym, *args, &block)
+      wrap_with_time_zone time.__send__(sym, *args, &block)
+    rescue NoMethodError => e
+      raise e, e.message.sub(time.inspect, self.inspect), e.backtrace
+    end
+
+    private
+      def get_period_and_ensure_valid_local_time(period)
+        # we don't want a Time.local instance enforcing its own DST rules as well,
+        # so transfer time values to a utc constructor if necessary
+        @time = transfer_time_values_to_utc_constructor(@time) unless @time.utc?
+        begin
+          period || @time_zone.period_for_local(@time)
+        rescue ::TZInfo::PeriodNotFound
+          # time is in the "spring forward" hour gap, so we're moving the time forward one hour and trying again
+          @time += 1.hour
+          retry
+        end
+      end
+
+      def transfer_time_values_to_utc_constructor(time)
+        ::Time.utc(time.year, time.month, time.day, time.hour, time.min, time.sec, Rational(time.nsec, 1000))
+      end
+
+      def duration_of_variable_length?(obj)
+        ActiveSupport::Duration === obj && obj.parts.any? {|p| [:years, :months, :days].include?(p[0]) }
+      end
+
+      def wrap_with_time_zone(time)
+        if time.acts_like?(:time)
+          periods = time_zone.periods_for_local(time)
+          self.class.new(nil, time_zone, time, periods.include?(period) ? period : nil)
+        elsif time.is_a?(Range)
+          wrap_with_time_zone(time.begin)..wrap_with_time_zone(time.end)
+        else
+          time
+        end
+      end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/values/time_zone.rb b/app/server/vendor/activesupport/lib/active_support/values/time_zone.rb
new file mode 100644
index 0000000..38f0d26
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/values/time_zone.rb
@@ -0,0 +1,421 @@
+require 'tzinfo'
+require 'thread_safe'
+require 'active_support/core_ext/object/blank'
+require 'active_support/core_ext/object/try'
+
+module ActiveSupport
+  # The TimeZone class serves as a wrapper around TZInfo::Timezone instances.
+  # It allows us to do the following:
+  #
+  # * Limit the set of zones provided by TZInfo to a meaningful subset of 146
+  #   zones.
+  # * Retrieve and display zones with a friendlier name
+  #   (e.g., "Eastern Time (US & Canada)" instead of "America/New_York").
+  # * Lazily load TZInfo::Timezone instances only when they're needed.
+  # * Create ActiveSupport::TimeWithZone instances via TimeZone's +local+,
+  #   +parse+, +at+ and +now+ methods.
+  #
+  # If you set <tt>config.time_zone</tt> in the Rails Application, you can
+  # access this TimeZone object via <tt>Time.zone</tt>:
+  #
+  #   # application.rb:
+  #   class Application < Rails::Application
+  #     config.time_zone = 'Eastern Time (US & Canada)'
+  #   end
+  #
+  #   Time.zone      # => #<TimeZone:0x514834...>
+  #   Time.zone.name # => "Eastern Time (US & Canada)"
+  #   Time.zone.now  # => Sun, 18 May 2008 14:30:44 EDT -04:00
+  #
+  # The version of TZInfo bundled with Active Support only includes the
+  # definitions necessary to support the zones defined by the TimeZone class.
+  # If you need to use zones that aren't defined by TimeZone, you'll need to
+  # install the TZInfo gem (if a recent version of the gem is installed locally,
+  # this will be used instead of the bundled version.)
+  class TimeZone
+    # Keys are Rails TimeZone names, values are TZInfo identifiers.
+    MAPPING = {
+      "International Date Line West" => "Pacific/Midway",
+      "Midway Island"                => "Pacific/Midway",
+      "American Samoa"               => "Pacific/Pago_Pago",
+      "Hawaii"                       => "Pacific/Honolulu",
+      "Alaska"                       => "America/Juneau",
+      "Pacific Time (US & Canada)"   => "America/Los_Angeles",
+      "Tijuana"                      => "America/Tijuana",
+      "Mountain Time (US & Canada)"  => "America/Denver",
+      "Arizona"                      => "America/Phoenix",
+      "Chihuahua"                    => "America/Chihuahua",
+      "Mazatlan"                     => "America/Mazatlan",
+      "Central Time (US & Canada)"   => "America/Chicago",
+      "Saskatchewan"                 => "America/Regina",
+      "Guadalajara"                  => "America/Mexico_City",
+      "Mexico City"                  => "America/Mexico_City",
+      "Monterrey"                    => "America/Monterrey",
+      "Central America"              => "America/Guatemala",
+      "Eastern Time (US & Canada)"   => "America/New_York",
+      "Indiana (East)"               => "America/Indiana/Indianapolis",
+      "Bogota"                       => "America/Bogota",
+      "Lima"                         => "America/Lima",
+      "Quito"                        => "America/Lima",
+      "Atlantic Time (Canada)"       => "America/Halifax",
+      "Caracas"                      => "America/Caracas",
+      "La Paz"                       => "America/La_Paz",
+      "Santiago"                     => "America/Santiago",
+      "Newfoundland"                 => "America/St_Johns",
+      "Brasilia"                     => "America/Sao_Paulo",
+      "Buenos Aires"                 => "America/Argentina/Buenos_Aires",
+      "Montevideo"                   => "America/Montevideo",
+      "Georgetown"                   => "America/Guyana",
+      "Greenland"                    => "America/Godthab",
+      "Mid-Atlantic"                 => "Atlantic/South_Georgia",
+      "Azores"                       => "Atlantic/Azores",
+      "Cape Verde Is."               => "Atlantic/Cape_Verde",
+      "Dublin"                       => "Europe/Dublin",
+      "Edinburgh"                    => "Europe/London",
+      "Lisbon"                       => "Europe/Lisbon",
+      "London"                       => "Europe/London",
+      "Casablanca"                   => "Africa/Casablanca",
+      "Monrovia"                     => "Africa/Monrovia",
+      "UTC"                          => "Etc/UTC",
+      "Belgrade"                     => "Europe/Belgrade",
+      "Bratislava"                   => "Europe/Bratislava",
+      "Budapest"                     => "Europe/Budapest",
+      "Ljubljana"                    => "Europe/Ljubljana",
+      "Prague"                       => "Europe/Prague",
+      "Sarajevo"                     => "Europe/Sarajevo",
+      "Skopje"                       => "Europe/Skopje",
+      "Warsaw"                       => "Europe/Warsaw",
+      "Zagreb"                       => "Europe/Zagreb",
+      "Brussels"                     => "Europe/Brussels",
+      "Copenhagen"                   => "Europe/Copenhagen",
+      "Madrid"                       => "Europe/Madrid",
+      "Paris"                        => "Europe/Paris",
+      "Amsterdam"                    => "Europe/Amsterdam",
+      "Berlin"                       => "Europe/Berlin",
+      "Bern"                         => "Europe/Berlin",
+      "Rome"                         => "Europe/Rome",
+      "Stockholm"                    => "Europe/Stockholm",
+      "Vienna"                       => "Europe/Vienna",
+      "West Central Africa"          => "Africa/Algiers",
+      "Bucharest"                    => "Europe/Bucharest",
+      "Cairo"                        => "Africa/Cairo",
+      "Helsinki"                     => "Europe/Helsinki",
+      "Kyiv"                         => "Europe/Kiev",
+      "Riga"                         => "Europe/Riga",
+      "Sofia"                        => "Europe/Sofia",
+      "Tallinn"                      => "Europe/Tallinn",
+      "Vilnius"                      => "Europe/Vilnius",
+      "Athens"                       => "Europe/Athens",
+      "Istanbul"                     => "Europe/Istanbul",
+      "Minsk"                        => "Europe/Minsk",
+      "Jerusalem"                    => "Asia/Jerusalem",
+      "Harare"                       => "Africa/Harare",
+      "Pretoria"                     => "Africa/Johannesburg",
+      "Moscow"                       => "Europe/Moscow",
+      "St. Petersburg"               => "Europe/Moscow",
+      "Volgograd"                    => "Europe/Moscow",
+      "Kuwait"                       => "Asia/Kuwait",
+      "Riyadh"                       => "Asia/Riyadh",
+      "Nairobi"                      => "Africa/Nairobi",
+      "Baghdad"                      => "Asia/Baghdad",
+      "Tehran"                       => "Asia/Tehran",
+      "Abu Dhabi"                    => "Asia/Muscat",
+      "Muscat"                       => "Asia/Muscat",
+      "Baku"                         => "Asia/Baku",
+      "Tbilisi"                      => "Asia/Tbilisi",
+      "Yerevan"                      => "Asia/Yerevan",
+      "Kabul"                        => "Asia/Kabul",
+      "Ekaterinburg"                 => "Asia/Yekaterinburg",
+      "Islamabad"                    => "Asia/Karachi",
+      "Karachi"                      => "Asia/Karachi",
+      "Tashkent"                     => "Asia/Tashkent",
+      "Chennai"                      => "Asia/Kolkata",
+      "Kolkata"                      => "Asia/Kolkata",
+      "Mumbai"                       => "Asia/Kolkata",
+      "New Delhi"                    => "Asia/Kolkata",
+      "Kathmandu"                    => "Asia/Kathmandu",
+      "Astana"                       => "Asia/Dhaka",
+      "Dhaka"                        => "Asia/Dhaka",
+      "Sri Jayawardenepura"          => "Asia/Colombo",
+      "Almaty"                       => "Asia/Almaty",
+      "Novosibirsk"                  => "Asia/Novosibirsk",
+      "Rangoon"                      => "Asia/Rangoon",
+      "Bangkok"                      => "Asia/Bangkok",
+      "Hanoi"                        => "Asia/Bangkok",
+      "Jakarta"                      => "Asia/Jakarta",
+      "Krasnoyarsk"                  => "Asia/Krasnoyarsk",
+      "Beijing"                      => "Asia/Shanghai",
+      "Chongqing"                    => "Asia/Chongqing",
+      "Hong Kong"                    => "Asia/Hong_Kong",
+      "Urumqi"                       => "Asia/Urumqi",
+      "Kuala Lumpur"                 => "Asia/Kuala_Lumpur",
+      "Singapore"                    => "Asia/Singapore",
+      "Taipei"                       => "Asia/Taipei",
+      "Perth"                        => "Australia/Perth",
+      "Irkutsk"                      => "Asia/Irkutsk",
+      "Ulaanbaatar"                  => "Asia/Ulaanbaatar",
+      "Seoul"                        => "Asia/Seoul",
+      "Osaka"                        => "Asia/Tokyo",
+      "Sapporo"                      => "Asia/Tokyo",
+      "Tokyo"                        => "Asia/Tokyo",
+      "Yakutsk"                      => "Asia/Yakutsk",
+      "Darwin"                       => "Australia/Darwin",
+      "Adelaide"                     => "Australia/Adelaide",
+      "Canberra"                     => "Australia/Melbourne",
+      "Melbourne"                    => "Australia/Melbourne",
+      "Sydney"                       => "Australia/Sydney",
+      "Brisbane"                     => "Australia/Brisbane",
+      "Hobart"                       => "Australia/Hobart",
+      "Vladivostok"                  => "Asia/Vladivostok",
+      "Guam"                         => "Pacific/Guam",
+      "Port Moresby"                 => "Pacific/Port_Moresby",
+      "Magadan"                      => "Asia/Magadan",
+      "Solomon Is."                  => "Pacific/Guadalcanal",
+      "New Caledonia"                => "Pacific/Noumea",
+      "Fiji"                         => "Pacific/Fiji",
+      "Kamchatka"                    => "Asia/Kamchatka",
+      "Marshall Is."                 => "Pacific/Majuro",
+      "Auckland"                     => "Pacific/Auckland",
+      "Wellington"                   => "Pacific/Auckland",
+      "Nuku'alofa"                   => "Pacific/Tongatapu",
+      "Tokelau Is."                  => "Pacific/Fakaofo",
+      "Chatham Is."                  => "Pacific/Chatham",
+      "Samoa"                        => "Pacific/Apia"
+    }
+
+    UTC_OFFSET_WITH_COLON = '%s%02d:%02d'
+    UTC_OFFSET_WITHOUT_COLON = UTC_OFFSET_WITH_COLON.sub(':', '')
+
+    @lazy_zones_map = ThreadSafe::Cache.new
+
+    # Assumes self represents an offset from UTC in seconds (as returned from
+    # Time#utc_offset) and turns this into an +HH:MM formatted string.
+    #
+    #   TimeZone.seconds_to_utc_offset(-21_600) # => "-06:00"
+    def self.seconds_to_utc_offset(seconds, colon = true)
+      format = colon ? UTC_OFFSET_WITH_COLON : UTC_OFFSET_WITHOUT_COLON
+      sign = (seconds < 0 ? '-' : '+')
+      hours = seconds.abs / 3600
+      minutes = (seconds.abs % 3600) / 60
+      format % [sign, hours, minutes]
+    end
+
+    include Comparable
+    attr_reader :name
+    attr_reader :tzinfo
+
+    # Create a new TimeZone object with the given name and offset. The
+    # offset is the number of seconds that this time zone is offset from UTC
+    # (GMT). Seconds were chosen as the offset unit because that is the unit
+    # that Ruby uses to represent time zone offsets (see Time#utc_offset).
+    def initialize(name, utc_offset = nil, tzinfo = nil)
+      @name = name
+      @utc_offset = utc_offset
+      @tzinfo = tzinfo || TimeZone.find_tzinfo(name)
+      @current_period = nil
+    end
+
+    # Returns the offset of this time zone from UTC in seconds.
+    def utc_offset
+      if @utc_offset
+        @utc_offset
+      else
+        @current_period ||= tzinfo.try(:current_period)
+        @current_period.try(:utc_offset)
+      end
+    end
+
+    # Returns the offset of this time zone as a formatted string, of the
+    # format "+HH:MM".
+    def formatted_offset(colon=true, alternate_utc_string = nil)
+      utc_offset == 0 && alternate_utc_string || self.class.seconds_to_utc_offset(utc_offset, colon)
+    end
+
+    # Compare this time zone to the parameter. The two are compared first on
+    # their offsets, and then by name.
+    def <=>(zone)
+      return unless zone.respond_to? :utc_offset
+      result = (utc_offset <=> zone.utc_offset)
+      result = (name <=> zone.name) if result == 0
+      result
+    end
+
+    # Compare #name and TZInfo identifier to a supplied regexp, returning +true+
+    # if a match is found.
+    def =~(re)
+      re === name || re === MAPPING[name]
+    end
+
+    # Returns a textual representation of this time zone.
+    def to_s
+      "(GMT#{formatted_offset}) #{name}"
+    end
+
+    # Method for creating new ActiveSupport::TimeWithZone instance in time zone
+    # of +self+ from given values.
+    #
+    #   Time.zone = 'Hawaii'                    # => "Hawaii"
+    #   Time.zone.local(2007, 2, 1, 15, 30, 45) # => Thu, 01 Feb 2007 15:30:45 HST -10:00
+    def local(*args)
+      time = Time.utc(*args)
+      ActiveSupport::TimeWithZone.new(nil, self, time)
+    end
+
+    # Method for creating new ActiveSupport::TimeWithZone instance in time zone
+    # of +self+ from number of seconds since the Unix epoch.
+    #
+    #   Time.zone = 'Hawaii'        # => "Hawaii"
+    #   Time.utc(2000).to_f         # => 946684800.0
+    #   Time.zone.at(946684800.0)   # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+    def at(secs)
+      Time.at(secs).utc.in_time_zone(self)
+    end
+
+    # Method for creating new ActiveSupport::TimeWithZone instance in time zone
+    # of +self+ from parsed string.
+    #
+    #   Time.zone = 'Hawaii'                   # => "Hawaii"
+    #   Time.zone.parse('1999-12-31 14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+    #
+    # If upper components are missing from the string, they are supplied from
+    # TimeZone#now:
+    #
+    #   Time.zone.now               # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+    #   Time.zone.parse('22:30:00') # => Fri, 31 Dec 1999 22:30:00 HST -10:00
+    def parse(str, now=now())
+      parts = Date._parse(str, false)
+      return if parts.empty?
+
+      time = Time.new(
+        parts.fetch(:year, now.year),
+        parts.fetch(:mon, now.month),
+        parts.fetch(:mday, now.day),
+        parts.fetch(:hour, 0),
+        parts.fetch(:min, 0),
+        parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
+        parts.fetch(:offset, 0)
+      )
+
+      if parts[:offset]
+        TimeWithZone.new(time.utc, self)
+      else
+        TimeWithZone.new(nil, self, time)
+      end
+    end
+
+    # Returns an ActiveSupport::TimeWithZone instance representing the current
+    # time in the time zone represented by +self+.
+    #
+    #   Time.zone = 'Hawaii'  # => "Hawaii"
+    #   Time.zone.now         # => Wed, 23 Jan 2008 20:24:27 HST -10:00
+    def now
+      time_now.utc.in_time_zone(self)
+    end
+
+    # Return the current date in this time zone.
+    def today
+      tzinfo.now.to_date
+    end
+
+    # Returns the next date in this time zone.
+    def tomorrow
+      today + 1
+    end
+
+    # Returns the previous date in this time zone.
+    def yesterday
+      today - 1
+    end
+
+    # Adjust the given time to the simultaneous time in the time zone
+    # represented by +self+. Returns a Time.utc() instance -- if you want an
+    # ActiveSupport::TimeWithZone instance, use Time#in_time_zone() instead.
+    def utc_to_local(time)
+      tzinfo.utc_to_local(time)
+    end
+
+    # Adjust the given time to the simultaneous time in UTC. Returns a
+    # Time.utc() instance.
+    def local_to_utc(time, dst=true)
+      tzinfo.local_to_utc(time, dst)
+    end
+
+    # Available so that TimeZone instances respond like TZInfo::Timezone
+    # instances.
+    def period_for_utc(time)
+      tzinfo.period_for_utc(time)
+    end
+
+    # Available so that TimeZone instances respond like TZInfo::Timezone
+    # instances.
+    def period_for_local(time, dst=true)
+      tzinfo.period_for_local(time, dst)
+    end
+
+    def periods_for_local(time) #:nodoc:
+      tzinfo.periods_for_local(time)
+    end
+
+    def self.find_tzinfo(name)
+      TZInfo::TimezoneProxy.new(MAPPING[name] || name)
+    end
+
+    class << self
+      alias_method :create, :new
+
+      # Returns a TimeZone instance with the given name, or +nil+ if no
+      # such TimeZone instance exists. (This exists to support the use of
+      # this class with the +composed_of+ macro.)
+      def new(name)
+        self[name]
+      end
+
+      # Returns an array of all TimeZone objects. There are multiple
+      # TimeZone objects per time zone, in many cases, to make it easier
+      # for users to find their own time zone.
+      def all
+        @zones ||= zones_map.values.sort
+      end
+
+      def zones_map
+        @zones_map ||= begin
+          MAPPING.each_key {|place| self[place]} # load all the zones
+          @lazy_zones_map
+        end
+      end
+
+      # Locate a specific time zone object. If the argument is a string, it
+      # is interpreted to mean the name of the timezone to locate. If it is a
+      # numeric value it is either the hour offset, or the second offset, of the
+      # timezone to find. (The first one with that offset will be returned.)
+      # Returns +nil+ if no such time zone is known to the system.
+      def [](arg)
+        case arg
+          when String
+          begin
+            @lazy_zones_map[arg] ||= create(arg).tap { |tz| tz.utc_offset }
+          rescue TZInfo::InvalidTimezoneIdentifier
+            nil
+          end
+          when Numeric, ActiveSupport::Duration
+            arg *= 3600 if arg.abs <= 13
+            all.find { |z| z.utc_offset == arg.to_i }
+          else
+            raise ArgumentError, "invalid argument to TimeZone[]: #{arg.inspect}"
+        end
+      end
+
+      # A convenience method for returning a collection of TimeZone objects
+      # for time zones in the USA.
+      def us_zones
+        @us_zones ||= all.find_all { |z| z.name =~ /US|Arizona|Indiana|Hawaii|Alaska/ }
+      end
+    end
+
+    private
+
+    def time_now
+      Time.now
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/values/unicode_tables.dat b/app/server/vendor/activesupport/lib/active_support/values/unicode_tables.dat
new file mode 100644
index 0000000..394ee95
Binary files /dev/null and b/app/server/vendor/activesupport/lib/active_support/values/unicode_tables.dat differ
diff --git a/app/server/vendor/activesupport/lib/active_support/version.rb b/app/server/vendor/activesupport/lib/active_support/version.rb
new file mode 100644
index 0000000..fe03984
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/version.rb
@@ -0,0 +1,8 @@
+require_relative 'gem_version'
+
+module ActiveSupport
+  # Returns the version of the currently loaded ActiveSupport as a <tt>Gem::Version</tt>
+  def self.version
+    gem_version
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/xml_mini.rb b/app/server/vendor/activesupport/lib/active_support/xml_mini.rb
new file mode 100644
index 0000000..009ee4d
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/xml_mini.rb
@@ -0,0 +1,191 @@
+require 'time'
+require 'base64'
+require 'bigdecimal'
+require 'active_support/core_ext/module/delegation'
+require 'active_support/core_ext/string/inflections'
+require 'active_support/core_ext/date_time/calculations'
+
+module ActiveSupport
+  # = XmlMini
+  #
+  # To use the much faster libxml parser:
+  #   gem 'libxml-ruby', '=0.9.7'
+  #   XmlMini.backend = 'LibXML'
+  module XmlMini
+    extend self
+
+    # This module decorates files deserialized using Hash.from_xml with
+    # the <tt>original_filename</tt> and <tt>content_type</tt> methods.
+    module FileLike #:nodoc:
+      attr_writer :original_filename, :content_type
+
+      def original_filename
+        @original_filename || 'untitled'
+      end
+
+      def content_type
+        @content_type || 'application/octet-stream'
+      end
+    end
+
+    DEFAULT_ENCODINGS = {
+      "binary" => "base64"
+    } unless defined?(DEFAULT_ENCODINGS)
+
+    TYPE_NAMES = {
+      "Symbol"     => "symbol",
+      "Fixnum"     => "integer",
+      "Bignum"     => "integer",
+      "BigDecimal" => "decimal",
+      "Float"      => "float",
+      "TrueClass"  => "boolean",
+      "FalseClass" => "boolean",
+      "Date"       => "date",
+      "DateTime"   => "dateTime",
+      "Time"       => "dateTime",
+      "Array"      => "array",
+      "Hash"       => "hash"
+    } unless defined?(TYPE_NAMES)
+
+    FORMATTING = {
+      "symbol"   => Proc.new { |symbol| symbol.to_s },
+      "date"     => Proc.new { |date| date.to_s(:db) },
+      "dateTime" => Proc.new { |time| time.xmlschema },
+      "binary"   => Proc.new { |binary| ::Base64.encode64(binary) },
+      "yaml"     => Proc.new { |yaml| yaml.to_yaml }
+    } unless defined?(FORMATTING)
+
+    # TODO use regexp instead of Date.parse
+    unless defined?(PARSING)
+      PARSING = {
+        "symbol"       => Proc.new { |symbol|  symbol.to_s.to_sym },
+        "date"         => Proc.new { |date|    ::Date.parse(date) },
+        "datetime"     => Proc.new { |time|    Time.xmlschema(time).utc rescue ::DateTime.parse(time).utc },
+        "integer"      => Proc.new { |integer| integer.to_i },
+        "float"        => Proc.new { |float|   float.to_f },
+        "decimal"      => Proc.new { |number|  BigDecimal(number) },
+        "boolean"      => Proc.new { |boolean| %w(1 true).include?(boolean.to_s.strip) },
+        "string"       => Proc.new { |string|  string.to_s },
+        "yaml"         => Proc.new { |yaml|    YAML::load(yaml) rescue yaml },
+        "base64Binary" => Proc.new { |bin|     ::Base64.decode64(bin) },
+        "binary"       => Proc.new { |bin, entity| _parse_binary(bin, entity) },
+        "file"         => Proc.new { |file, entity| _parse_file(file, entity) }
+      }
+
+      PARSING.update(
+        "double"   => PARSING["float"],
+        "dateTime" => PARSING["datetime"]
+      )
+    end
+
+    delegate :parse, :to => :backend
+
+    def backend
+      current_thread_backend || @backend
+    end
+
+    def backend=(name)
+      backend = name && cast_backend_name_to_module(name)
+      self.current_thread_backend = backend if current_thread_backend
+      @backend = backend
+    end
+
+    def with_backend(name)
+      old_backend = current_thread_backend
+      self.current_thread_backend = name && cast_backend_name_to_module(name)
+      yield
+    ensure
+      self.current_thread_backend = old_backend
+    end
+
+    def to_tag(key, value, options)
+      type_name = options.delete(:type)
+      merged_options = options.merge(:root => key, :skip_instruct => true)
+
+      if value.is_a?(::Method) || value.is_a?(::Proc)
+        if value.arity == 1
+          value.call(merged_options)
+        else
+          value.call(merged_options, key.to_s.singularize)
+        end
+      elsif value.respond_to?(:to_xml)
+        value.to_xml(merged_options)
+      else
+        type_name ||= TYPE_NAMES[value.class.name]
+        type_name ||= value.class.name if value && !value.respond_to?(:to_str)
+        type_name   = type_name.to_s   if type_name
+        type_name   = "dateTime" if type_name == "datetime"
+
+        key = rename_key(key.to_s, options)
+
+        attributes = options[:skip_types] || type_name.nil? ? { } : { :type => type_name }
+        attributes[:nil] = true if value.nil?
+
+        encoding = options[:encoding] || DEFAULT_ENCODINGS[type_name]
+        attributes[:encoding] = encoding if encoding
+
+        formatted_value = FORMATTING[type_name] && !value.nil? ?
+          FORMATTING[type_name].call(value) : value
+
+        options[:builder].tag!(key, formatted_value, attributes)
+      end
+    end
+
+    def rename_key(key, options = {})
+      camelize  = options[:camelize]
+      dasherize = !options.has_key?(:dasherize) || options[:dasherize]
+      if camelize
+        key = true == camelize ? key.camelize : key.camelize(camelize)
+      end
+      key = _dasherize(key) if dasherize
+      key
+    end
+
+    protected
+
+    def _dasherize(key)
+      # $2 must be a non-greedy regex for this to work
+      left, middle, right = /\A(_*)(.*?)(_*)\Z/.match(key.strip)[1,3]
+      "#{left}#{middle.tr('_ ', '--')}#{right}"
+    end
+
+    # TODO: Add support for other encodings
+    def _parse_binary(bin, entity) #:nodoc:
+      case entity['encoding']
+      when 'base64'
+        ::Base64.decode64(bin)
+      else
+        bin
+      end
+    end
+
+    def _parse_file(file, entity)
+      f = StringIO.new(::Base64.decode64(file))
+      f.extend(FileLike)
+      f.original_filename = entity['name']
+      f.content_type = entity['content_type']
+      f
+    end
+
+    private
+
+      def current_thread_backend
+        Thread.current[:xml_mini_backend]
+      end
+
+      def current_thread_backend=(name)
+        Thread.current[:xml_mini_backend] = name && cast_backend_name_to_module(name)
+      end
+
+      def cast_backend_name_to_module(name)
+        if name.is_a?(Module)
+          name
+        else
+          require "active_support/xml_mini/#{name.downcase}"
+          ActiveSupport.const_get("XmlMini_#{name}")
+        end
+      end
+  end
+
+  XmlMini.backend = 'REXML'
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/xml_mini/jdom.rb b/app/server/vendor/activesupport/lib/active_support/xml_mini/jdom.rb
new file mode 100644
index 0000000..27c64c4
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/xml_mini/jdom.rb
@@ -0,0 +1,180 @@
+raise "JRuby is required to use the JDOM backend for XmlMini" unless RUBY_PLATFORM =~ /java/
+
+require 'jruby'
+include Java
+
+require 'active_support/core_ext/object/blank'
+
+java_import javax.xml.parsers.DocumentBuilder unless defined? DocumentBuilder
+java_import javax.xml.parsers.DocumentBuilderFactory unless defined? DocumentBuilderFactory
+java_import java.io.StringReader unless defined? StringReader
+java_import org.xml.sax.InputSource unless defined? InputSource
+java_import org.xml.sax.Attributes unless defined? Attributes
+java_import org.w3c.dom.Node unless defined? Node
+
+module ActiveSupport
+  module XmlMini_JDOM #:nodoc:
+    extend self
+
+    CONTENT_KEY = '__content__'.freeze
+
+    NODE_TYPE_NAMES = %w{ATTRIBUTE_NODE CDATA_SECTION_NODE COMMENT_NODE DOCUMENT_FRAGMENT_NODE
+    DOCUMENT_NODE DOCUMENT_TYPE_NODE ELEMENT_NODE ENTITY_NODE ENTITY_REFERENCE_NODE NOTATION_NODE
+    PROCESSING_INSTRUCTION_NODE TEXT_NODE}
+
+    node_type_map = {}
+    NODE_TYPE_NAMES.each { |type| node_type_map[Node.send(type)] = type }
+
+    # Parse an XML Document string or IO into a simple hash using Java's jdom.
+    # data::
+    #   XML Document string or IO to parse
+    def parse(data)
+      if data.respond_to?(:read)
+        data = data.read
+      end
+
+      if data.blank?
+        {}
+      else
+        @dbf = DocumentBuilderFactory.new_instance
+        # secure processing of java xml
+        # http://www.ibm.com/developerworks/xml/library/x-tipcfsx/index.html
+        @dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false)
+        @dbf.setFeature("http://xml.org/sax/features/external-general-entities", false)
+        @dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false)
+        @dbf.setFeature(javax.xml.XMLConstants::FEATURE_SECURE_PROCESSING, true)
+        xml_string_reader = StringReader.new(data)
+        xml_input_source = InputSource.new(xml_string_reader)
+        doc = @dbf.new_document_builder.parse(xml_input_source)
+        merge_element!({CONTENT_KEY => ''}, doc.document_element)
+      end
+    end
+
+    private
+
+    # Convert an XML element and merge into the hash
+    #
+    # hash::
+    #   Hash to merge the converted element into.
+    # element::
+    #   XML element to merge into hash
+    def merge_element!(hash, element)
+      delete_empty(hash)
+      merge!(hash, element.tag_name, collapse(element))
+    end
+
+    def delete_empty(hash)
+      hash.delete(CONTENT_KEY) if hash[CONTENT_KEY] == ''
+    end
+
+    # Actually converts an XML document element into a data structure.
+    #
+    # element::
+    #   The document element to be collapsed.
+    def collapse(element)
+      hash = get_attributes(element)
+
+      child_nodes = element.child_nodes
+      if child_nodes.length > 0
+        (0...child_nodes.length).each do |i|
+          child = child_nodes.item(i)
+          merge_element!(hash, child) unless child.node_type == Node.TEXT_NODE
+        end
+        merge_texts!(hash, element) unless empty_content?(element)
+        hash
+      else
+        merge_texts!(hash, element)
+      end
+    end
+
+    # Merge all the texts of an element into the hash
+    #
+    # hash::
+    #   Hash to add the converted element to.
+    # element::
+    #   XML element whose texts are to me merged into the hash
+    def merge_texts!(hash, element)
+      delete_empty(hash)
+      text_children = texts(element)
+      if text_children.join.empty?
+        hash
+      else
+        # must use value to prevent double-escaping
+        merge!(hash, CONTENT_KEY, text_children.join)
+      end
+    end
+
+    # Adds a new key/value pair to an existing Hash. If the key to be added
+    # already exists and the existing value associated with key is not
+    # an Array, it will be wrapped in an Array. Then the new value is
+    # appended to that Array.
+    #
+    # hash::
+    #   Hash to add key/value pair to.
+    # key::
+    #   Key to be added.
+    # value::
+    #   Value to be associated with key.
+    def merge!(hash, key, value)
+      if hash.has_key?(key)
+        if hash[key].instance_of?(Array)
+          hash[key] << value
+        else
+          hash[key] = [hash[key], value]
+        end
+      elsif value.instance_of?(Array)
+        hash[key] = [value]
+      else
+        hash[key] = value
+      end
+      hash
+    end
+
+    # Converts the attributes array of an XML element into a hash.
+    # Returns an empty Hash if node has no attributes.
+    #
+    # element::
+    #   XML element to extract attributes from.
+    def get_attributes(element)
+      attribute_hash = {}
+      attributes = element.attributes
+      (0...attributes.length).each do |i|
+         attribute_hash[CONTENT_KEY] ||= ''
+         attribute_hash[attributes.item(i).name] =  attributes.item(i).value
+       end
+      attribute_hash
+    end
+
+    # Determines if a document element has text content
+    #
+    # element::
+    #   XML element to be checked.
+    def texts(element)
+      texts = []
+      child_nodes = element.child_nodes
+      (0...child_nodes.length).each do |i|
+        item = child_nodes.item(i)
+        if item.node_type == Node.TEXT_NODE
+          texts << item.get_data
+        end
+      end
+      texts
+    end
+
+    # Determines if a document element has text content
+    #
+    # element::
+    #   XML element to be checked.
+    def empty_content?(element)
+      text = ''
+      child_nodes = element.child_nodes
+      (0...child_nodes.length).each do |i|
+        item = child_nodes.item(i)
+        if item.node_type == Node.TEXT_NODE
+          text << item.get_data.strip
+        end
+      end
+      text.strip.length == 0
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/xml_mini/libxml.rb b/app/server/vendor/activesupport/lib/active_support/xml_mini/libxml.rb
new file mode 100644
index 0000000..47a2824
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/xml_mini/libxml.rb
@@ -0,0 +1,79 @@
+require 'libxml'
+require 'active_support/core_ext/object/blank'
+require 'stringio'
+
+module ActiveSupport
+  module XmlMini_LibXML #:nodoc:
+    extend self
+
+    # Parse an XML Document string or IO into a simple hash using libxml.
+    # data::
+    #   XML Document string or IO to parse
+    def parse(data)
+      if !data.respond_to?(:read)
+        data = StringIO.new(data || '')
+      end
+
+      char = data.getc
+      if char.nil?
+        {}
+      else
+        data.ungetc(char)
+        LibXML::XML::Parser.io(data).parse.to_hash
+      end
+    end
+
+  end
+end
+
+module LibXML #:nodoc:
+  module Conversions #:nodoc:
+    module Document #:nodoc:
+      def to_hash
+        root.to_hash
+      end
+    end
+
+    module Node #:nodoc:
+      CONTENT_ROOT = '__content__'.freeze
+
+      # Convert XML document to hash.
+      #
+      # hash::
+      #   Hash to merge the converted element into.
+      def to_hash(hash={})
+        node_hash = {}
+
+        # Insert node hash into parent hash correctly.
+        case hash[name]
+          when Array then hash[name] << node_hash
+          when Hash  then hash[name] = [hash[name], node_hash]
+          when nil   then hash[name] = node_hash
+        end
+
+        # Handle child elements
+        each_child do |c|
+          if c.element?
+            c.to_hash(node_hash)
+          elsif c.text? || c.cdata?
+            node_hash[CONTENT_ROOT] ||= ''
+            node_hash[CONTENT_ROOT] << c.content
+          end
+        end
+
+        # Remove content node if it is blank
+        if node_hash.length > 1 && node_hash[CONTENT_ROOT].blank?
+          node_hash.delete(CONTENT_ROOT)
+        end
+
+        # Handle attributes
+        each_attr { |a| node_hash[a.name] = a.value }
+
+        hash
+      end
+    end
+  end
+end
+
+LibXML::XML::Document.send(:include, LibXML::Conversions::Document)
+LibXML::XML::Node.send(:include, LibXML::Conversions::Node)
diff --git a/app/server/vendor/activesupport/lib/active_support/xml_mini/libxmlsax.rb b/app/server/vendor/activesupport/lib/active_support/xml_mini/libxmlsax.rb
new file mode 100644
index 0000000..70a9529
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/xml_mini/libxmlsax.rb
@@ -0,0 +1,85 @@
+require 'libxml'
+require 'active_support/core_ext/object/blank'
+require 'stringio'
+
+module ActiveSupport
+  module XmlMini_LibXMLSAX #:nodoc:
+    extend self
+
+    # Class that will build the hash while the XML document
+    # is being parsed using SAX events.
+    class HashBuilder
+
+      include LibXML::XML::SaxParser::Callbacks
+
+      CONTENT_KEY   = '__content__'.freeze
+      HASH_SIZE_KEY = '__hash_size__'.freeze
+
+      attr_reader :hash
+
+      def current_hash
+        @hash_stack.last
+      end
+
+      def on_start_document
+        @hash = { CONTENT_KEY => '' }
+        @hash_stack = [@hash]
+      end
+
+      def on_end_document
+        @hash = @hash_stack.pop
+        @hash.delete(CONTENT_KEY)
+      end
+
+      def on_start_element(name, attrs = {})
+        new_hash = { CONTENT_KEY => '' }.merge!(attrs)
+        new_hash[HASH_SIZE_KEY] = new_hash.size + 1
+
+        case current_hash[name]
+          when Array then current_hash[name] << new_hash
+          when Hash  then current_hash[name] = [current_hash[name], new_hash]
+          when nil   then current_hash[name] = new_hash
+        end
+
+        @hash_stack.push(new_hash)
+      end
+
+      def on_end_element(name)
+        if current_hash.length > current_hash.delete(HASH_SIZE_KEY) && current_hash[CONTENT_KEY].blank? || current_hash[CONTENT_KEY] == ''
+          current_hash.delete(CONTENT_KEY)
+        end
+        @hash_stack.pop
+      end
+
+      def on_characters(string)
+        current_hash[CONTENT_KEY] << string
+      end
+
+      alias_method :on_cdata_block, :on_characters
+    end
+
+    attr_accessor :document_class
+    self.document_class = HashBuilder
+
+    def parse(data)
+      if !data.respond_to?(:read)
+        data = StringIO.new(data || '')
+      end
+
+      char = data.getc
+      if char.nil?
+        {}
+      else
+        data.ungetc(char)
+
+        LibXML::XML::Error.set_handler(&LibXML::XML::Error::QUIET_HANDLER)
+        parser = LibXML::XML::SaxParser.io(data)
+        document = self.document_class.new
+
+        parser.callbacks = document
+        parser.parse
+        document.hash
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/xml_mini/nokogiri.rb b/app/server/vendor/activesupport/lib/active_support/xml_mini/nokogiri.rb
new file mode 100644
index 0000000..7398d4f
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/xml_mini/nokogiri.rb
@@ -0,0 +1,83 @@
+begin
+  require 'nokogiri'
+rescue LoadError => e
+  $stderr.puts "You don't have nokogiri installed in your application. Please add it to your Gemfile and run bundle install"
+  raise e
+end
+require 'active_support/core_ext/object/blank'
+require 'stringio'
+
+module ActiveSupport
+  module XmlMini_Nokogiri #:nodoc:
+    extend self
+
+    # Parse an XML Document string or IO into a simple hash using libxml / nokogiri.
+    # data::
+    #   XML Document string or IO to parse
+    def parse(data)
+      if !data.respond_to?(:read)
+        data = StringIO.new(data || '')
+      end
+
+      char = data.getc
+      if char.nil?
+        {}
+      else
+        data.ungetc(char)
+        doc = Nokogiri::XML(data)
+        raise doc.errors.first if doc.errors.length > 0
+        doc.to_hash
+      end
+    end
+
+    module Conversions #:nodoc:
+      module Document #:nodoc:
+        def to_hash
+          root.to_hash
+        end
+      end
+
+      module Node #:nodoc:
+        CONTENT_ROOT = '__content__'.freeze
+
+        # Convert XML document to hash.
+        #
+        # hash::
+        #   Hash to merge the converted element into.
+        def to_hash(hash={})
+          node_hash = {}
+
+          # Insert node hash into parent hash correctly.
+          case hash[name]
+            when Array then hash[name] << node_hash
+            when Hash  then hash[name] = [hash[name], node_hash]
+            when nil   then hash[name] = node_hash
+          end
+
+          # Handle child elements
+          children.each do |c|
+            if c.element?
+              c.to_hash(node_hash)
+            elsif c.text? || c.cdata?
+              node_hash[CONTENT_ROOT] ||= ''
+              node_hash[CONTENT_ROOT] << c.content
+            end
+          end
+
+          # Remove content node if it is blank and there are child tags
+          if node_hash.length > 1 && node_hash[CONTENT_ROOT].blank?
+            node_hash.delete(CONTENT_ROOT)
+          end
+
+          # Handle attributes
+          attribute_nodes.each { |a| node_hash[a.node_name] = a.value }
+
+          hash
+        end
+      end
+    end
+
+    Nokogiri::XML::Document.send(:include, Conversions::Document)
+    Nokogiri::XML::Node.send(:include, Conversions::Node)
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/xml_mini/nokogirisax.rb b/app/server/vendor/activesupport/lib/active_support/xml_mini/nokogirisax.rb
new file mode 100644
index 0000000..be2d6a4
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/xml_mini/nokogirisax.rb
@@ -0,0 +1,87 @@
+begin
+  require 'nokogiri'
+rescue LoadError => e
+  $stderr.puts "You don't have nokogiri installed in your application. Please add it to your Gemfile and run bundle install"
+  raise e
+end
+require 'active_support/core_ext/object/blank'
+require 'stringio'
+
+module ActiveSupport
+  module XmlMini_NokogiriSAX #:nodoc:
+    extend self
+
+    # Class that will build the hash while the XML document
+    # is being parsed using SAX events.
+    class HashBuilder < Nokogiri::XML::SAX::Document
+
+      CONTENT_KEY   = '__content__'.freeze
+      HASH_SIZE_KEY = '__hash_size__'.freeze
+
+      attr_reader :hash
+
+      def current_hash
+        @hash_stack.last
+      end
+
+      def start_document
+        @hash = {}
+        @hash_stack = [@hash]
+      end
+
+      def end_document
+        raise "Parse stack not empty!" if @hash_stack.size > 1
+      end
+
+      def error(error_message)
+        raise error_message
+      end
+
+      def start_element(name, attrs = [])
+        new_hash = { CONTENT_KEY => '' }.merge!(Hash[attrs])
+        new_hash[HASH_SIZE_KEY] = new_hash.size + 1
+
+        case current_hash[name]
+          when Array then current_hash[name] << new_hash
+          when Hash  then current_hash[name] = [current_hash[name], new_hash]
+          when nil   then current_hash[name] = new_hash
+        end
+
+        @hash_stack.push(new_hash)
+      end
+
+      def end_element(name)
+        if current_hash.length > current_hash.delete(HASH_SIZE_KEY) && current_hash[CONTENT_KEY].blank? || current_hash[CONTENT_KEY] == ''
+          current_hash.delete(CONTENT_KEY)
+        end
+        @hash_stack.pop
+      end
+
+      def characters(string)
+        current_hash[CONTENT_KEY] << string
+      end
+
+      alias_method :cdata_block, :characters
+    end
+
+    attr_accessor :document_class
+    self.document_class = HashBuilder
+
+    def parse(data)
+      if !data.respond_to?(:read)
+        data = StringIO.new(data || '')
+      end
+
+      char = data.getc
+      if char.nil?
+        {}
+      else
+        data.ungetc(char)
+        document = self.document_class.new
+        parser = Nokogiri::XML::SAX::Parser.new(document)
+        parser.parse(data)
+        document.hash
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/lib/active_support/xml_mini/rexml.rb b/app/server/vendor/activesupport/lib/active_support/xml_mini/rexml.rb
new file mode 100644
index 0000000..5c7c78b
--- /dev/null
+++ b/app/server/vendor/activesupport/lib/active_support/xml_mini/rexml.rb
@@ -0,0 +1,129 @@
+require 'active_support/core_ext/kernel/reporting'
+require 'active_support/core_ext/object/blank'
+require 'stringio'
+
+module ActiveSupport
+  module XmlMini_REXML #:nodoc:
+    extend self
+
+    CONTENT_KEY = '__content__'.freeze
+
+    # Parse an XML Document string or IO into a simple hash.
+    #
+    # Same as XmlSimple::xml_in but doesn't shoot itself in the foot,
+    # and uses the defaults from Active Support.
+    #
+    # data::
+    #   XML Document string or IO to parse
+    def parse(data)
+      if !data.respond_to?(:read)
+        data = StringIO.new(data || '')
+      end
+
+      char = data.getc
+      if char.nil?
+        {}
+      else
+        data.ungetc(char)
+        silence_warnings { require 'rexml/document' } unless defined?(REXML::Document)
+        doc = REXML::Document.new(data)
+
+        if doc.root
+          merge_element!({}, doc.root)
+        else
+          raise REXML::ParseException,
+            "The document #{doc.to_s.inspect} does not have a valid root"
+        end
+      end
+    end
+
+    private
+      # Convert an XML element and merge into the hash
+      #
+      # hash::
+      #   Hash to merge the converted element into.
+      # element::
+      #   XML element to merge into hash
+      def merge_element!(hash, element)
+        merge!(hash, element.name, collapse(element))
+      end
+
+      # Actually converts an XML document element into a data structure.
+      #
+      # element::
+      #   The document element to be collapsed.
+      def collapse(element)
+        hash = get_attributes(element)
+
+        if element.has_elements?
+          element.each_element {|child| merge_element!(hash, child) }
+          merge_texts!(hash, element) unless empty_content?(element)
+          hash
+        else
+          merge_texts!(hash, element)
+        end
+      end
+
+      # Merge all the texts of an element into the hash
+      #
+      # hash::
+      #   Hash to add the converted element to.
+      # element::
+      #   XML element whose texts are to me merged into the hash
+      def merge_texts!(hash, element)
+        unless element.has_text?
+          hash
+        else
+          # must use value to prevent double-escaping
+          texts = ''
+          element.texts.each { |t| texts << t.value }
+          merge!(hash, CONTENT_KEY, texts)
+        end
+      end
+
+      # Adds a new key/value pair to an existing Hash. If the key to be added
+      # already exists and the existing value associated with key is not
+      # an Array, it will be wrapped in an Array. Then the new value is
+      # appended to that Array.
+      #
+      # hash::
+      #   Hash to add key/value pair to.
+      # key::
+      #   Key to be added.
+      # value::
+      #   Value to be associated with key.
+      def merge!(hash, key, value)
+        if hash.has_key?(key)
+          if hash[key].instance_of?(Array)
+            hash[key] << value
+          else
+            hash[key] = [hash[key], value]
+          end
+        elsif value.instance_of?(Array)
+          hash[key] = [value]
+        else
+          hash[key] = value
+        end
+        hash
+      end
+
+      # Converts the attributes array of an XML element into a hash.
+      # Returns an empty Hash if node has no attributes.
+      #
+      # element::
+      #   XML element to extract attributes from.
+      def get_attributes(element)
+        attributes = {}
+        element.attributes.each { |n,v| attributes[n] = v }
+        attributes
+      end
+
+      # Determines if a document element has text content
+      #
+      # element::
+      #   XML element to be checked.
+      def empty_content?(element)
+        element.texts.join.blank?
+      end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/abstract_unit.rb b/app/server/vendor/activesupport/test/abstract_unit.rb
new file mode 100644
index 0000000..0b393e0
--- /dev/null
+++ b/app/server/vendor/activesupport/test/abstract_unit.rb
@@ -0,0 +1,38 @@
+ORIG_ARGV = ARGV.dup
+
+begin
+  old, $VERBOSE = $VERBOSE, nil
+  require File.expand_path('../../../load_paths', __FILE__)
+ensure
+  $VERBOSE = old
+end
+
+require 'active_support/core_ext/kernel/reporting'
+
+silence_warnings do
+  Encoding.default_internal = "UTF-8"
+  Encoding.default_external = "UTF-8"
+end
+
+require 'active_support/testing/autorun'
+
+ENV['NO_RELOAD'] = '1'
+require 'active_support'
+
+Thread.abort_on_exception = true
+
+# Show backtraces for deprecated behavior for quicker cleanup.
+ActiveSupport::Deprecation.debug = true
+
+# Disable available locale checks to avoid warnings running the test suite.
+I18n.enforce_available_locales = false
+
+# Skips the current run on Rubinius using Minitest::Assertions#skip
+def rubinius_skip(message = '')
+  skip message if RUBY_ENGINE == 'rbx'
+end
+
+# Skips the current run on JRuby using Minitest::Assertions#skip
+def jruby_skip(message = '')
+  skip message if defined?(JRUBY_VERSION)
+end
diff --git a/app/server/vendor/activesupport/test/autoload_test.rb b/app/server/vendor/activesupport/test/autoload_test.rb
new file mode 100644
index 0000000..7d02d83
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoload_test.rb
@@ -0,0 +1,70 @@
+require 'abstract_unit'
+
+class TestAutoloadModule < ActiveSupport::TestCase
+  include ActiveSupport::Testing::Isolation
+
+  module ::Fixtures
+    extend ActiveSupport::Autoload
+
+    module Autoload
+      extend ActiveSupport::Autoload
+    end
+  end
+
+  test "the autoload module works like normal autoload" do
+    module ::Fixtures::Autoload
+      autoload :SomeClass, "fixtures/autoload/some_class"
+    end
+
+    assert_nothing_raised { ::Fixtures::Autoload::SomeClass }
+  end
+
+  test "when specifying an :eager constant it still works like normal autoload by default" do
+    module ::Fixtures::Autoload
+      autoload :SomeClass, "fixtures/autoload/some_class"
+    end
+
+    assert !$LOADED_FEATURES.include?("fixtures/autoload/some_class.rb")
+    assert_nothing_raised { ::Fixtures::Autoload::SomeClass }
+  end
+
+  test "the location of autoloaded constants defaults to :name.underscore" do
+    module ::Fixtures::Autoload
+      autoload :SomeClass
+    end
+
+    assert !$LOADED_FEATURES.include?("fixtures/autoload/some_class.rb")
+    assert_nothing_raised { ::Fixtures::Autoload::SomeClass }
+  end
+
+  test "the location of :eager autoloaded constants defaults to :name.underscore" do
+    module ::Fixtures::Autoload
+      autoload :SomeClass
+    end
+
+    ::Fixtures::Autoload.eager_load!
+    assert_nothing_raised { ::Fixtures::Autoload::SomeClass }
+  end
+
+  test "a directory for a block of autoloads can be specified" do
+    module ::Fixtures
+      autoload_under "autoload" do
+        autoload :AnotherClass
+      end
+    end
+
+    assert !$LOADED_FEATURES.include?("fixtures/autoload/another_class.rb")
+    assert_nothing_raised { ::Fixtures::AnotherClass }
+  end
+
+  test "a path for a block of autoloads can be specified" do
+    module ::Fixtures
+      autoload_at "fixtures/autoload/another_class" do
+        autoload :AnotherClass
+      end
+    end
+
+    assert !$LOADED_FEATURES.include?("fixtures/autoload/another_class.rb")
+    assert_nothing_raised { ::Fixtures::AnotherClass }
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/a/b.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/a/b.rb
new file mode 100644
index 0000000..9c9e645
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/a/b.rb
@@ -0,0 +1,2 @@
+class A::B
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/a/c/d.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/a/c/d.rb
new file mode 100644
index 0000000..0f40d6f
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/a/c/d.rb
@@ -0,0 +1,2 @@
+class A::C::D
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/a/c/e/f.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/a/c/e/f.rb
new file mode 100644
index 0000000..57dba5a
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/a/c/e/f.rb
@@ -0,0 +1,2 @@
+class A::C::E::F
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/application.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/application.rb
new file mode 100644
index 0000000..d7d3096
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/application.rb
@@ -0,0 +1 @@
+ApplicationController = 10
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/circular1.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/circular1.rb
new file mode 100644
index 0000000..a45761f
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/circular1.rb
@@ -0,0 +1,6 @@
+silence_warnings do
+  Circular2
+end
+
+class Circular1
+end
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/circular2.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/circular2.rb
new file mode 100644
index 0000000..c847fa5
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/circular2.rb
@@ -0,0 +1,4 @@
+Circular1
+
+class Circular2
+end
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/class_folder.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/class_folder.rb
new file mode 100644
index 0000000..ad2b27b
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/class_folder.rb
@@ -0,0 +1,3 @@
+class ClassFolder
+  ConstantInClassFolder = 'indeed'
+end
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/class_folder/class_folder_subclass.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/class_folder/class_folder_subclass.rb
new file mode 100644
index 0000000..402609c
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/class_folder/class_folder_subclass.rb
@@ -0,0 +1,3 @@
+class ClassFolder::ClassFolderSubclass < ClassFolder
+  ConstantInClassFolder = 'indeed'
+end
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/class_folder/inline_class.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/class_folder/inline_class.rb
new file mode 100644
index 0000000..8235e90
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/class_folder/inline_class.rb
@@ -0,0 +1,2 @@
+class ClassFolder::InlineClass
+end
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/class_folder/nested_class.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/class_folder/nested_class.rb
new file mode 100644
index 0000000..57a13d8
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/class_folder/nested_class.rb
@@ -0,0 +1,7 @@
+class ClassFolder
+  class NestedClass
+  end
+
+  class SiblingClass
+  end
+end
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/conflict.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/conflict.rb
new file mode 100644
index 0000000..4ac6201
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/conflict.rb
@@ -0,0 +1 @@
+Conflict = 2
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/counting_loader.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/counting_loader.rb
new file mode 100644
index 0000000..4225c44
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/counting_loader.rb
@@ -0,0 +1,5 @@
+$counting_loaded_times ||= 0
+$counting_loaded_times += 1
+
+module CountingLoader
+end
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/cross_site_dependency.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/cross_site_dependency.rb
new file mode 100644
index 0000000..21ee554
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/cross_site_dependency.rb
@@ -0,0 +1,2 @@
+class CrossSiteDependency
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/e.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/e.rb
new file mode 100644
index 0000000..2f59e4f
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/e.rb
@@ -0,0 +1,2 @@
+class E
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/html/some_class.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/html/some_class.rb
new file mode 100644
index 0000000..b43d15d
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/html/some_class.rb
@@ -0,0 +1,4 @@
+module HTML
+  class SomeClass
+  end
+end
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/load_path/loaded_constant.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/load_path/loaded_constant.rb
new file mode 100644
index 0000000..e3d1218
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/load_path/loaded_constant.rb
@@ -0,0 +1,3 @@
+module LoadedConstant
+end
+
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/loads_constant.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/loads_constant.rb
new file mode 100644
index 0000000..0b30dc8
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/loads_constant.rb
@@ -0,0 +1,5 @@
+module LoadsConstant
+end
+
+# The _ = assignment is to prevent warnings
+_ = RequiresConstant
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/module_folder/inline_class.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/module_folder/inline_class.rb
new file mode 100644
index 0000000..ca83437
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/module_folder/inline_class.rb
@@ -0,0 +1,2 @@
+class ModuleFolder::InlineClass
+end
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/module_folder/nested_class.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/module_folder/nested_class.rb
new file mode 100644
index 0000000..fc4076b
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/module_folder/nested_class.rb
@@ -0,0 +1,4 @@
+module ModuleFolder
+  class NestedClass
+  end
+end
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/module_folder/nested_sibling.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/module_folder/nested_sibling.rb
new file mode 100644
index 0000000..80244b8
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/module_folder/nested_sibling.rb
@@ -0,0 +1,2 @@
+class ModuleFolder::NestedSibling
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/module_with_custom_const_missing/a/b.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/module_with_custom_const_missing/a/b.rb
new file mode 100644
index 0000000..d12d02f
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/module_with_custom_const_missing/a/b.rb
@@ -0,0 +1 @@
+ModuleWithCustomConstMissing::A::B = "10"
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/multiple_constant_file.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/multiple_constant_file.rb
new file mode 100644
index 0000000..a9ff4eb
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/multiple_constant_file.rb
@@ -0,0 +1,2 @@
+MultipleConstantFile = 10
+SiblingConstant = MultipleConstantFile * 2
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/raises_name_error.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/raises_name_error.rb
new file mode 100644
index 0000000..a49960a
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/raises_name_error.rb
@@ -0,0 +1,3 @@
+class RaisesNameError
+  FooBarBaz
+end
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/raises_no_method_error.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/raises_no_method_error.rb
new file mode 100644
index 0000000..e1b8fce
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/raises_no_method_error.rb
@@ -0,0 +1,3 @@
+class RaisesNoMethodError
+  self.foobar_method_doesnt_exist
+end
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/requires_constant.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/requires_constant.rb
new file mode 100644
index 0000000..14804a0
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/requires_constant.rb
@@ -0,0 +1,5 @@
+require "loaded_constant"
+
+module RequiresConstant
+end
+
diff --git a/app/server/vendor/activesupport/test/autoloading_fixtures/should_not_be_required.rb b/app/server/vendor/activesupport/test/autoloading_fixtures/should_not_be_required.rb
new file mode 100644
index 0000000..1fcf170
--- /dev/null
+++ b/app/server/vendor/activesupport/test/autoloading_fixtures/should_not_be_required.rb
@@ -0,0 +1 @@
+ShouldNotBeAutoloaded = 0
diff --git a/app/server/vendor/activesupport/test/benchmarkable_test.rb b/app/server/vendor/activesupport/test/benchmarkable_test.rb
new file mode 100644
index 0000000..04d4f5e
--- /dev/null
+++ b/app/server/vendor/activesupport/test/benchmarkable_test.rb
@@ -0,0 +1,62 @@
+require 'abstract_unit'
+
+class BenchmarkableTest < ActiveSupport::TestCase
+  include ActiveSupport::Benchmarkable
+
+  attr_reader :buffer, :logger
+
+  class Buffer
+    include Enumerable
+
+    def initialize; @lines = []; end
+    def each(&block); @lines.each(&block); end
+    def write(x); @lines << x; end
+    def close; end
+    def last; @lines.last; end
+    def size; @lines.size; end
+    def empty?; @lines.empty?; end
+  end
+
+  def setup
+    @buffer = Buffer.new
+    @logger = ActiveSupport::Logger.new(@buffer)
+  end
+
+  def test_without_block
+    assert_raise(LocalJumpError) { benchmark }
+    assert buffer.empty?
+  end
+
+  def test_defaults
+    i_was_run = false
+    benchmark { i_was_run = true }
+    assert i_was_run
+    assert_last_logged
+  end
+
+  def test_with_message
+    i_was_run = false
+    benchmark('test_run') { i_was_run = true }
+    assert i_was_run
+    assert_last_logged 'test_run'
+  end
+
+  def test_within_level
+    logger.level = ActiveSupport::Logger::DEBUG
+    benchmark('included_debug_run', :level => :debug) { }
+    assert_last_logged 'included_debug_run'
+  end
+
+  def test_outside_level
+    logger.level = ActiveSupport::Logger::ERROR
+    benchmark('skipped_debug_run', :level => :debug) { }
+    assert_no_match(/skipped_debug_run/, buffer.last)
+  ensure
+    logger.level = ActiveSupport::Logger::DEBUG
+  end
+
+  private
+    def assert_last_logged(message = 'Benchmarking')
+      assert_match(/^#{message} \(.*\)$/, buffer.last)
+    end
+end
diff --git a/app/server/vendor/activesupport/test/broadcast_logger_test.rb b/app/server/vendor/activesupport/test/broadcast_logger_test.rb
new file mode 100644
index 0000000..6d4e3b7
--- /dev/null
+++ b/app/server/vendor/activesupport/test/broadcast_logger_test.rb
@@ -0,0 +1,82 @@
+require 'abstract_unit'
+
+module ActiveSupport
+  class BroadcastLoggerTest < TestCase
+    attr_reader :logger, :log1, :log2
+    def setup
+      @log1 = FakeLogger.new
+      @log2 = FakeLogger.new
+      @log1.extend Logger.broadcast @log2
+      @logger = @log1
+    end
+
+    def test_debug
+      logger.debug "foo"
+      assert_equal 'foo', log1.adds.first[2]
+      assert_equal 'foo', log2.adds.first[2]
+    end
+
+    def test_close
+      logger.close
+      assert log1.closed, 'should be closed'
+      assert log2.closed, 'should be closed'
+    end
+
+    def test_chevrons
+      logger << "foo"
+      assert_equal %w{ foo }, log1.chevrons
+      assert_equal %w{ foo }, log2.chevrons
+    end
+
+    def test_level
+      assert_nil logger.level
+      logger.level = 10
+      assert_equal 10, log1.level
+      assert_equal 10, log2.level
+    end
+
+    def test_progname
+      assert_nil logger.progname
+      logger.progname = 10
+      assert_equal 10, log1.progname
+      assert_equal 10, log2.progname
+    end
+
+    def test_formatter
+      assert_nil logger.formatter
+      logger.formatter = 10
+      assert_equal 10, log1.formatter
+      assert_equal 10, log2.formatter
+    end
+
+    class FakeLogger
+      attr_reader :adds, :closed, :chevrons
+      attr_accessor :level, :progname, :formatter
+
+      def initialize
+        @adds      = []
+        @closed    = false
+        @chevrons  = []
+        @level     = nil
+        @progname  = nil
+        @formatter = nil
+      end
+
+      def debug msg, &block
+        add(:omg, nil, msg, &block)
+      end
+
+      def << x
+        @chevrons << x
+      end
+
+      def add(*args)
+        @adds << args
+      end
+
+      def close
+        @closed = true
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/caching_test.rb b/app/server/vendor/activesupport/test/caching_test.rb
new file mode 100644
index 0000000..18923f6
--- /dev/null
+++ b/app/server/vendor/activesupport/test/caching_test.rb
@@ -0,0 +1,1072 @@
+require 'logger'
+require 'abstract_unit'
+require 'active_support/cache'
+require 'dependencies_test_helpers'
+
+module ActiveSupport
+  module Cache
+    module Strategy
+      module LocalCache
+        class MiddlewareTest < ActiveSupport::TestCase
+          def test_local_cache_cleared_on_close
+            key = "super awesome key"
+            assert_nil LocalCacheRegistry.cache_for key
+            middleware = Middleware.new('<3', key).new(->(env) {
+              assert LocalCacheRegistry.cache_for(key), 'should have a cache'
+              [200, {}, []]
+            })
+            _, _, body = middleware.call({})
+            assert LocalCacheRegistry.cache_for(key), 'should still have a cache'
+            body.each { }
+            assert LocalCacheRegistry.cache_for(key), 'should still have a cache'
+            body.close
+            assert_nil LocalCacheRegistry.cache_for(key)
+          end
+
+          def test_local_cache_cleared_on_exception
+            key = "super awesome key"
+            assert_nil LocalCacheRegistry.cache_for key
+            middleware = Middleware.new('<3', key).new(->(env) {
+              assert LocalCacheRegistry.cache_for(key), 'should have a cache'
+              raise
+            })
+            assert_raises(RuntimeError) { middleware.call({}) }
+            assert_nil LocalCacheRegistry.cache_for(key)
+          end
+        end
+      end
+    end
+  end
+end
+
+class CacheKeyTest < ActiveSupport::TestCase
+  def test_entry_legacy_optional_ivars
+    legacy = Class.new(ActiveSupport::Cache::Entry) do
+      def initialize(value, options = {})
+        @value = value
+        @expires_in = nil
+        @created_at = nil
+        super
+      end
+    end
+
+    entry = legacy.new 'foo'
+    assert_equal 'foo', entry.value
+  end
+
+  def test_expand_cache_key
+    assert_equal '1/2/true', ActiveSupport::Cache.expand_cache_key([1, '2', true])
+    assert_equal 'name/1/2/true', ActiveSupport::Cache.expand_cache_key([1, '2', true], :name)
+  end
+
+  def test_expand_cache_key_with_rails_cache_id
+    begin
+      ENV['RAILS_CACHE_ID'] = 'c99'
+      assert_equal 'c99/foo', ActiveSupport::Cache.expand_cache_key(:foo)
+      assert_equal 'c99/foo', ActiveSupport::Cache.expand_cache_key([:foo])
+      assert_equal 'c99/foo/bar', ActiveSupport::Cache.expand_cache_key([:foo, :bar])
+      assert_equal 'nm/c99/foo', ActiveSupport::Cache.expand_cache_key(:foo, :nm)
+      assert_equal 'nm/c99/foo', ActiveSupport::Cache.expand_cache_key([:foo], :nm)
+      assert_equal 'nm/c99/foo/bar', ActiveSupport::Cache.expand_cache_key([:foo, :bar], :nm)
+    ensure
+      ENV['RAILS_CACHE_ID'] = nil
+    end
+  end
+
+  def test_expand_cache_key_with_rails_app_version
+    begin
+      ENV['RAILS_APP_VERSION'] = 'rails3'
+      assert_equal 'rails3/foo', ActiveSupport::Cache.expand_cache_key(:foo)
+    ensure
+      ENV['RAILS_APP_VERSION'] = nil
+    end
+  end
+
+  def test_expand_cache_key_rails_cache_id_should_win_over_rails_app_version
+    begin
+      ENV['RAILS_CACHE_ID'] = 'c99'
+      ENV['RAILS_APP_VERSION'] = 'rails3'
+      assert_equal 'c99/foo', ActiveSupport::Cache.expand_cache_key(:foo)
+    ensure
+      ENV['RAILS_CACHE_ID'] = nil
+      ENV['RAILS_APP_VERSION'] = nil
+    end
+  end
+
+  def test_expand_cache_key_respond_to_cache_key
+    key = 'foo'
+    def key.cache_key
+      :foo_key
+    end
+    assert_equal 'foo_key', ActiveSupport::Cache.expand_cache_key(key)
+  end
+
+  def test_expand_cache_key_array_with_something_that_responds_to_cache_key
+    key = 'foo'
+    def key.cache_key
+      :foo_key
+    end
+    assert_equal 'foo_key', ActiveSupport::Cache.expand_cache_key([key])
+  end
+
+  def test_expand_cache_key_of_nil
+    assert_equal '', ActiveSupport::Cache.expand_cache_key(nil)
+  end
+
+  def test_expand_cache_key_of_false
+    assert_equal 'false', ActiveSupport::Cache.expand_cache_key(false)
+  end
+
+  def test_expand_cache_key_of_true
+    assert_equal 'true', ActiveSupport::Cache.expand_cache_key(true)
+  end
+
+  def test_expand_cache_key_of_array_like_object
+    assert_equal 'foo/bar/baz', ActiveSupport::Cache.expand_cache_key(%w{foo bar baz}.to_enum)
+  end
+end
+
+class CacheStoreSettingTest < ActiveSupport::TestCase
+  def test_file_fragment_cache_store
+    store = ActiveSupport::Cache.lookup_store :file_store, "/path/to/cache/directory"
+    assert_kind_of(ActiveSupport::Cache::FileStore, store)
+    assert_equal "/path/to/cache/directory", store.cache_path
+  end
+
+  def test_mem_cache_fragment_cache_store
+    Dalli::Client.expects(:new).with(%w[localhost], {})
+    store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost"
+    assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
+  end
+
+  def test_mem_cache_fragment_cache_store_with_given_mem_cache
+    mem_cache = Dalli::Client.new
+    Dalli::Client.expects(:new).never
+    store = ActiveSupport::Cache.lookup_store :mem_cache_store, mem_cache
+    assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
+  end
+
+  def test_mem_cache_fragment_cache_store_with_not_dalli_client
+    Dalli::Client.expects(:new).never
+    memcache = Object.new
+    assert_raises(ArgumentError) do
+      ActiveSupport::Cache.lookup_store :mem_cache_store, memcache
+    end
+  end
+
+  def test_mem_cache_fragment_cache_store_with_multiple_servers
+    Dalli::Client.expects(:new).with(%w[localhost 192.168.1.1], {})
+    store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost", '192.168.1.1'
+    assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
+  end
+
+  def test_mem_cache_fragment_cache_store_with_options
+    Dalli::Client.expects(:new).with(%w[localhost 192.168.1.1], { :timeout => 10 })
+    store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost", '192.168.1.1', :namespace => 'foo', :timeout => 10
+    assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
+    assert_equal 'foo', store.options[:namespace]
+  end
+
+  def test_object_assigned_fragment_cache_store
+    store = ActiveSupport::Cache.lookup_store ActiveSupport::Cache::FileStore.new("/path/to/cache/directory")
+    assert_kind_of(ActiveSupport::Cache::FileStore, store)
+    assert_equal "/path/to/cache/directory", store.cache_path
+  end
+end
+
+class CacheStoreNamespaceTest < ActiveSupport::TestCase
+  def test_static_namespace
+    cache = ActiveSupport::Cache.lookup_store(:memory_store, :namespace => "tester")
+    cache.write("foo", "bar")
+    assert_equal "bar", cache.read("foo")
+    assert_equal "bar", cache.instance_variable_get(:@data)["tester:foo"].value
+  end
+
+  def test_proc_namespace
+    test_val = "tester"
+    proc = lambda{test_val}
+    cache = ActiveSupport::Cache.lookup_store(:memory_store, :namespace => proc)
+    cache.write("foo", "bar")
+    assert_equal "bar", cache.read("foo")
+    assert_equal "bar", cache.instance_variable_get(:@data)["tester:foo"].value
+  end
+
+  def test_delete_matched_key_start
+    cache = ActiveSupport::Cache.lookup_store(:memory_store, :namespace => "tester")
+    cache.write("foo", "bar")
+    cache.write("fu", "baz")
+    cache.delete_matched(/^fo/)
+    assert !cache.exist?("foo")
+    assert cache.exist?("fu")
+  end
+
+  def test_delete_matched_key
+    cache = ActiveSupport::Cache.lookup_store(:memory_store, :namespace => "foo")
+    cache.write("foo", "bar")
+    cache.write("fu", "baz")
+    cache.delete_matched(/OO/i)
+    assert !cache.exist?("foo")
+    assert cache.exist?("fu")
+  end
+end
+
+# Tests the base functionality that should be identical across all cache stores.
+module CacheStoreBehavior
+  def test_should_read_and_write_strings
+    assert @cache.write('foo', 'bar')
+    assert_equal 'bar', @cache.read('foo')
+  end
+
+  def test_should_overwrite
+    @cache.write('foo', 'bar')
+    @cache.write('foo', 'baz')
+    assert_equal 'baz', @cache.read('foo')
+  end
+
+  def test_fetch_without_cache_miss
+    @cache.write('foo', 'bar')
+    @cache.expects(:write).never
+    assert_equal 'bar', @cache.fetch('foo') { 'baz' }
+  end
+
+  def test_fetch_with_cache_miss
+    @cache.expects(:write).with('foo', 'baz', @cache.options)
+    assert_equal 'baz', @cache.fetch('foo') { 'baz' }
+  end
+
+  def test_fetch_with_cache_miss_passes_key_to_block
+    cache_miss = false
+    assert_equal 3, @cache.fetch('foo') { |key| cache_miss = true; key.length }
+    assert cache_miss
+
+    cache_miss = false
+    assert_equal 3, @cache.fetch('foo') { |key| cache_miss = true; key.length }
+    assert !cache_miss
+  end
+
+  def test_fetch_with_forced_cache_miss
+    @cache.write('foo', 'bar')
+    @cache.expects(:read).never
+    @cache.expects(:write).with('foo', 'bar', @cache.options.merge(:force => true))
+    @cache.fetch('foo', :force => true) { 'bar' }
+  end
+
+  def test_fetch_with_cached_nil
+    @cache.write('foo', nil)
+    @cache.expects(:write).never
+    assert_nil @cache.fetch('foo') { 'baz' }
+  end
+
+  def test_should_read_and_write_hash
+    assert @cache.write('foo', {:a => "b"})
+    assert_equal({:a => "b"}, @cache.read('foo'))
+  end
+
+  def test_should_read_and_write_integer
+    assert @cache.write('foo', 1)
+    assert_equal 1, @cache.read('foo')
+  end
+
+  def test_should_read_and_write_nil
+    assert @cache.write('foo', nil)
+    assert_equal nil, @cache.read('foo')
+  end
+
+  def test_should_read_and_write_false
+    assert @cache.write('foo', false)
+    assert_equal false, @cache.read('foo')
+  end
+
+  def test_read_multi
+    @cache.write('foo', 'bar')
+    @cache.write('fu', 'baz')
+    @cache.write('fud', 'biz')
+    assert_equal({"foo" => "bar", "fu" => "baz"}, @cache.read_multi('foo', 'fu'))
+  end
+
+  def test_read_multi_with_expires
+    time = Time.now
+    @cache.write('foo', 'bar', :expires_in => 10)
+    @cache.write('fu', 'baz')
+    @cache.write('fud', 'biz')
+    Time.stubs(:now).returns(time + 11)
+    assert_equal({"fu" => "baz"}, @cache.read_multi('foo', 'fu'))
+  end
+
+  def test_fetch_multi
+    @cache.write('foo', 'bar')
+    @cache.write('fud', 'biz')
+
+    values = @cache.fetch_multi('foo', 'fu', 'fud') { |value| value * 2 }
+
+    assert_equal({ 'foo' => 'bar', 'fu' => 'fufu', 'fud' => 'biz' }, values)
+    assert_equal('fufu', @cache.read('fu'))
+  end
+
+  def test_multi_with_objects
+    foo = stub(:title => 'FOO!', :cache_key => 'foo')
+    bar = stub(:cache_key => 'bar')
+
+    @cache.write('bar', 'BAM!')
+
+    values = @cache.fetch_multi(foo, bar) { |object| object.title }
+
+    assert_equal({ foo => 'FOO!', bar => 'BAM!' }, values)
+  end
+
+  def test_read_and_write_compressed_small_data
+    @cache.write('foo', 'bar', :compress => true)
+    assert_equal 'bar', @cache.read('foo')
+  end
+
+  def test_read_and_write_compressed_large_data
+    @cache.write('foo', 'bar', :compress => true, :compress_threshold => 2)
+    assert_equal 'bar', @cache.read('foo')
+  end
+
+  def test_read_and_write_compressed_nil
+    @cache.write('foo', nil, :compress => true)
+    assert_nil @cache.read('foo')
+  end
+
+  def test_cache_key
+    obj = Object.new
+    def obj.cache_key
+      :foo
+    end
+    @cache.write(obj, "bar")
+    assert_equal "bar", @cache.read("foo")
+  end
+
+  def test_param_as_cache_key
+    obj = Object.new
+    def obj.to_param
+      "foo"
+    end
+    @cache.write(obj, "bar")
+    assert_equal "bar", @cache.read("foo")
+  end
+
+  def test_array_as_cache_key
+    @cache.write([:fu, "foo"], "bar")
+    assert_equal "bar", @cache.read("fu/foo")
+  end
+
+  def test_hash_as_cache_key
+    @cache.write({:foo => 1, :fu => 2}, "bar")
+    assert_equal "bar", @cache.read("foo=1/fu=2")
+  end
+
+  def test_keys_are_case_sensitive
+    @cache.write("foo", "bar")
+    assert_nil @cache.read("FOO")
+  end
+
+  def test_exist
+    @cache.write('foo', 'bar')
+    assert_equal true, @cache.exist?('foo')
+    assert_equal false, @cache.exist?('bar')
+  end
+
+  def test_nil_exist
+    @cache.write('foo', nil)
+    assert @cache.exist?('foo')
+  end
+
+  def test_delete
+    @cache.write('foo', 'bar')
+    assert @cache.exist?('foo')
+    assert @cache.delete('foo')
+    assert !@cache.exist?('foo')
+  end
+
+  def test_original_store_objects_should_not_be_immutable
+    bar = 'bar'
+    @cache.write('foo', bar)
+    assert_nothing_raised { bar.gsub!(/.*/, 'baz') }
+  end
+
+  def test_expires_in
+    time = Time.local(2008, 4, 24)
+    Time.stubs(:now).returns(time)
+
+    @cache.write('foo', 'bar')
+    assert_equal 'bar', @cache.read('foo')
+
+    Time.stubs(:now).returns(time + 30)
+    assert_equal 'bar', @cache.read('foo')
+
+    Time.stubs(:now).returns(time + 61)
+    assert_nil @cache.read('foo')
+  end
+
+  def test_race_condition_protection
+    time = Time.now
+    @cache.write('foo', 'bar', :expires_in => 60)
+    Time.stubs(:now).returns(time + 61)
+    result = @cache.fetch('foo', :race_condition_ttl => 10) do
+      assert_equal 'bar', @cache.read('foo')
+      "baz"
+    end
+    assert_equal "baz", result
+  end
+
+  def test_race_condition_protection_is_limited
+    time = Time.now
+    @cache.write('foo', 'bar', :expires_in => 60)
+    Time.stubs(:now).returns(time + 71)
+    result = @cache.fetch('foo', :race_condition_ttl => 10) do
+      assert_equal nil, @cache.read('foo')
+      "baz"
+    end
+    assert_equal "baz", result
+  end
+
+  def test_race_condition_protection_is_safe
+    time = Time.now
+    @cache.write('foo', 'bar', :expires_in => 60)
+    Time.stubs(:now).returns(time + 61)
+    begin
+      @cache.fetch('foo', :race_condition_ttl => 10) do
+        assert_equal 'bar', @cache.read('foo')
+        raise ArgumentError.new
+      end
+    rescue ArgumentError
+    end
+    assert_equal "bar", @cache.read('foo')
+    Time.stubs(:now).returns(time + 91)
+    assert_nil @cache.read('foo')
+  end
+
+  def test_crazy_key_characters
+    crazy_key = "#/:*(<+=> )&$%@?;'\"\'`~-"
+    assert @cache.write(crazy_key, "1", :raw => true)
+    assert_equal "1", @cache.read(crazy_key)
+    assert_equal "1", @cache.fetch(crazy_key)
+    assert @cache.delete(crazy_key)
+    assert_equal "2", @cache.fetch(crazy_key, :raw => true) { "2" }
+    assert_equal 3, @cache.increment(crazy_key)
+    assert_equal 2, @cache.decrement(crazy_key)
+  end
+
+  def test_really_long_keys
+    key = ""
+    900.times{key << "x"}
+    assert @cache.write(key, "bar")
+    assert_equal "bar", @cache.read(key)
+    assert_equal "bar", @cache.fetch(key)
+    assert_nil @cache.read("#{key}x")
+    assert_equal({key => "bar"}, @cache.read_multi(key))
+    assert @cache.delete(key)
+  end
+end
+
+# https://rails.lighthouseapp.com/projects/8994/tickets/6225-memcachestore-cant-deal-with-umlauts-and-special-characters
+# The error is caused by character encodings that can't be compared with ASCII-8BIT regular expressions and by special
+# characters like the umlaut in UTF-8.
+module EncodedKeyCacheBehavior
+  Encoding.list.each do |encoding|
+    define_method "test_#{encoding.name.underscore}_encoded_values" do
+      key = "foo".force_encoding(encoding)
+      assert @cache.write(key, "1", :raw => true)
+      assert_equal "1", @cache.read(key)
+      assert_equal "1", @cache.fetch(key)
+      assert @cache.delete(key)
+      assert_equal "2", @cache.fetch(key, :raw => true) { "2" }
+      assert_equal 3, @cache.increment(key)
+      assert_equal 2, @cache.decrement(key)
+    end
+  end
+
+  def test_common_utf8_values
+    key = "\xC3\xBCmlaut".force_encoding(Encoding::UTF_8)
+    assert @cache.write(key, "1", :raw => true)
+    assert_equal "1", @cache.read(key)
+    assert_equal "1", @cache.fetch(key)
+    assert @cache.delete(key)
+    assert_equal "2", @cache.fetch(key, :raw => true) { "2" }
+    assert_equal 3, @cache.increment(key)
+    assert_equal 2, @cache.decrement(key)
+  end
+
+  def test_retains_encoding
+    key = "\xC3\xBCmlaut".force_encoding(Encoding::UTF_8)
+    assert @cache.write(key, "1", :raw => true)
+    assert_equal Encoding::UTF_8, key.encoding
+  end
+end
+
+module CacheDeleteMatchedBehavior
+  def test_delete_matched
+    @cache.write("foo", "bar")
+    @cache.write("fu", "baz")
+    @cache.write("foo/bar", "baz")
+    @cache.write("fu/baz", "bar")
+    @cache.delete_matched(/oo/)
+    assert !@cache.exist?("foo")
+    assert @cache.exist?("fu")
+    assert !@cache.exist?("foo/bar")
+    assert @cache.exist?("fu/baz")
+  end
+end
+
+module CacheIncrementDecrementBehavior
+  def test_increment
+    @cache.write('foo', 1, :raw => true)
+    assert_equal 1, @cache.read('foo').to_i
+    assert_equal 2, @cache.increment('foo')
+    assert_equal 2, @cache.read('foo').to_i
+    assert_equal 3, @cache.increment('foo')
+    assert_equal 3, @cache.read('foo').to_i
+    assert_nil @cache.increment('bar')
+  end
+
+  def test_decrement
+    @cache.write('foo', 3, :raw => true)
+    assert_equal 3, @cache.read('foo').to_i
+    assert_equal 2, @cache.decrement('foo')
+    assert_equal 2, @cache.read('foo').to_i
+    assert_equal 1, @cache.decrement('foo')
+    assert_equal 1, @cache.read('foo').to_i
+    assert_nil @cache.decrement('bar')
+  end
+end
+
+module LocalCacheBehavior
+  def test_local_writes_are_persistent_on_the_remote_cache
+    retval = @cache.with_local_cache do
+      @cache.write('foo', 'bar')
+    end
+    assert retval
+    assert_equal 'bar', @cache.read('foo')
+  end
+
+  def test_clear_also_clears_local_cache
+    @cache.with_local_cache do
+      @cache.write('foo', 'bar')
+      @cache.clear
+      assert_nil @cache.read('foo')
+    end
+
+    assert_nil @cache.read('foo')
+  end
+
+  def test_local_cache_of_write
+    @cache.with_local_cache do
+      @cache.write('foo', 'bar')
+      @peek.delete('foo')
+      assert_equal 'bar', @cache.read('foo')
+    end
+  end
+
+  def test_local_cache_of_read
+    @cache.write('foo', 'bar')
+    @cache.with_local_cache do
+      assert_equal 'bar', @cache.read('foo')
+    end
+  end
+
+  def test_local_cache_of_write_nil
+    @cache.with_local_cache do
+      assert @cache.write('foo', nil)
+      assert_nil @cache.read('foo')
+      @peek.write('foo', 'bar')
+      assert_nil @cache.read('foo')
+    end
+  end
+
+  def test_local_cache_of_delete
+    @cache.with_local_cache do
+      @cache.write('foo', 'bar')
+      @cache.delete('foo')
+      assert_nil @cache.read('foo')
+    end
+  end
+
+  def test_local_cache_of_exist
+    @cache.with_local_cache do
+      @cache.write('foo', 'bar')
+      @peek.delete('foo')
+      assert @cache.exist?('foo')
+    end
+  end
+
+  def test_local_cache_of_increment
+    @cache.with_local_cache do
+      @cache.write('foo', 1, :raw => true)
+      @peek.write('foo', 2, :raw => true)
+      @cache.increment('foo')
+      assert_equal 3, @cache.read('foo')
+    end
+  end
+
+  def test_local_cache_of_decrement
+    @cache.with_local_cache do
+      @cache.write('foo', 1, :raw => true)
+      @peek.write('foo', 3, :raw => true)
+      @cache.decrement('foo')
+      assert_equal 2, @cache.read('foo')
+    end
+  end
+
+  def test_middleware
+    app = lambda { |env|
+      result = @cache.write('foo', 'bar')
+      assert_equal 'bar', @cache.read('foo') # make sure 'foo' was written
+      assert result
+      [200, {}, []]
+    }
+    app = @cache.middleware.new(app)
+    app.call({})
+  end
+end
+
+module AutoloadingCacheBehavior
+  include DependenciesTestHelpers
+  def test_simple_autoloading
+    with_autoloading_fixtures do
+      @cache.write('foo', E.new)
+    end
+
+    remove_constants(:E)
+    ActiveSupport::Dependencies.clear
+
+    with_autoloading_fixtures do
+      assert_kind_of E, @cache.read('foo')
+    end
+
+    remove_constants(:E)
+    ActiveSupport::Dependencies.clear
+  end
+
+  def test_two_classes_autoloading
+    with_autoloading_fixtures do
+      @cache.write('foo', [E.new, ClassFolder.new])
+    end
+
+    remove_constants(:E, :ClassFolder)
+    ActiveSupport::Dependencies.clear
+
+    with_autoloading_fixtures do
+      loaded = @cache.read('foo')
+      assert_kind_of Array, loaded
+      assert_equal 2, loaded.size
+      assert_kind_of E, loaded[0]
+      assert_kind_of ClassFolder, loaded[1]
+    end
+
+    remove_constants(:E, :ClassFolder)
+    ActiveSupport::Dependencies.clear
+  end
+end
+
+class FileStoreTest < ActiveSupport::TestCase
+  def setup
+    Dir.mkdir(cache_dir) unless File.exist?(cache_dir)
+    @cache = ActiveSupport::Cache.lookup_store(:file_store, cache_dir, :expires_in => 60)
+    @peek = ActiveSupport::Cache.lookup_store(:file_store, cache_dir, :expires_in => 60)
+    @cache_with_pathname = ActiveSupport::Cache.lookup_store(:file_store, Pathname.new(cache_dir), :expires_in => 60)
+
+    @buffer = StringIO.new
+    @cache.logger = ActiveSupport::Logger.new(@buffer)
+  end
+
+  def teardown
+    FileUtils.rm_r(cache_dir)
+  end
+
+  def cache_dir
+    File.join(Dir.pwd, 'tmp_cache')
+  end
+
+  include CacheStoreBehavior
+  include LocalCacheBehavior
+  include CacheDeleteMatchedBehavior
+  include CacheIncrementDecrementBehavior
+  include AutoloadingCacheBehavior
+
+  def test_clear
+    filepath = File.join(cache_dir, ".gitkeep")
+    FileUtils.touch(filepath)
+    @cache.clear
+    assert File.exist?(filepath)
+  end
+
+  def test_key_transformation
+    key = @cache.send(:key_file_path, "views/index?id=1")
+    assert_equal "views/index?id=1", @cache.send(:file_path_key, key)
+  end
+
+  def test_key_transformation_with_pathname
+    FileUtils.touch(File.join(cache_dir, "foo"))
+    key = @cache_with_pathname.send(:key_file_path, "views/index?id=1")
+    assert_equal "views/index?id=1", @cache_with_pathname.send(:file_path_key, key)
+  end
+
+  # Test that generated cache keys are short enough to have Tempfile stuff added to them and
+  # remain valid
+  def test_filename_max_size
+    key = "#{'A' * ActiveSupport::Cache::FileStore::FILENAME_MAX_SIZE}"
+    path = @cache.send(:key_file_path, key)
+    Dir::Tmpname.create(path) do |tmpname, n, opts|
+      assert File.basename(tmpname+'.lock').length <= 255, "Temp filename too long: #{File.basename(tmpname+'.lock').length}"
+    end
+  end
+
+  # Because file systems have a maximum filename size, filenames > max size should be split in to directories
+  # If filename is 'AAAAB', where max size is 4, the returned path should be AAAA/B
+  def test_key_transformation_max_filename_size
+    key = "#{'A' * ActiveSupport::Cache::FileStore::FILENAME_MAX_SIZE}B"
+    path = @cache.send(:key_file_path, key)
+    assert path.split('/').all? { |dir_name| dir_name.size <= ActiveSupport::Cache::FileStore::FILENAME_MAX_SIZE}
+    assert_equal 'B', File.basename(path)
+  end
+
+  # If nothing has been stored in the cache, there is a chance the cache directory does not yet exist
+  # Ensure delete_matched gracefully handles this case
+  def test_delete_matched_when_cache_directory_does_not_exist
+    assert_nothing_raised(Exception) do
+      ActiveSupport::Cache::FileStore.new('/test/cache/directory').delete_matched(/does_not_exist/)
+    end
+  end
+
+  def test_delete_does_not_delete_empty_parent_dir
+    sub_cache_dir = File.join(cache_dir, 'subdir/')
+    sub_cache_store = ActiveSupport::Cache::FileStore.new(sub_cache_dir)
+    assert_nothing_raised(Exception) do
+      assert sub_cache_store.write('foo', 'bar')
+      assert sub_cache_store.delete('foo')
+    end
+    assert File.exist?(cache_dir), "Parent of top level cache dir was deleted!"
+    assert File.exist?(sub_cache_dir), "Top level cache dir was deleted!"
+    assert Dir.entries(sub_cache_dir).reject {|f| ActiveSupport::Cache::FileStore::EXCLUDED_DIRS.include?(f)}.empty?
+  end
+
+  def test_log_exception_when_cache_read_fails
+    File.expects(:exist?).raises(StandardError, "failed")
+    @cache.send(:read_entry, "winston", {})
+    assert @buffer.string.present?
+  end
+
+  def test_cleanup_removes_all_expired_entries
+    time = Time.now
+    @cache.write('foo', 'bar', expires_in: 10)
+    @cache.write('baz', 'qux')
+    @cache.write('quux', 'corge', expires_in: 20)
+    Time.stubs(:now).returns(time + 15)
+    @cache.cleanup
+    assert_not @cache.exist?('foo')
+    assert @cache.exist?('baz')
+    assert @cache.exist?('quux')
+  end
+
+  def test_write_with_unless_exist
+    assert_equal true, @cache.write(1, "aaaaaaaaaa")
+    assert_equal false, @cache.write(1, "aaaaaaaaaa", unless_exist: true)
+    @cache.write(1, nil)
+    assert_equal false, @cache.write(1, "aaaaaaaaaa", unless_exist: true)
+  end
+end
+
+class MemoryStoreTest < ActiveSupport::TestCase
+  def setup
+    @record_size = ActiveSupport::Cache.lookup_store(:memory_store).send(:cached_size, 1, ActiveSupport::Cache::Entry.new("aaaaaaaaaa"))
+    @cache = ActiveSupport::Cache.lookup_store(:memory_store, :expires_in => 60, :size => @record_size * 10 + 1)
+  end
+
+  include CacheStoreBehavior
+  include CacheDeleteMatchedBehavior
+  include CacheIncrementDecrementBehavior
+
+  def test_prune_size
+    @cache.write(1, "aaaaaaaaaa") && sleep(0.001)
+    @cache.write(2, "bbbbbbbbbb") && sleep(0.001)
+    @cache.write(3, "cccccccccc") && sleep(0.001)
+    @cache.write(4, "dddddddddd") && sleep(0.001)
+    @cache.write(5, "eeeeeeeeee") && sleep(0.001)
+    @cache.read(2) && sleep(0.001)
+    @cache.read(4)
+    @cache.prune(@record_size * 3)
+    assert @cache.exist?(5)
+    assert @cache.exist?(4)
+    assert !@cache.exist?(3), "no entry"
+    assert @cache.exist?(2)
+    assert !@cache.exist?(1), "no entry"
+  end
+
+  def test_prune_size_on_write
+    @cache.write(1, "aaaaaaaaaa") && sleep(0.001)
+    @cache.write(2, "bbbbbbbbbb") && sleep(0.001)
+    @cache.write(3, "cccccccccc") && sleep(0.001)
+    @cache.write(4, "dddddddddd") && sleep(0.001)
+    @cache.write(5, "eeeeeeeeee") && sleep(0.001)
+    @cache.write(6, "ffffffffff") && sleep(0.001)
+    @cache.write(7, "gggggggggg") && sleep(0.001)
+    @cache.write(8, "hhhhhhhhhh") && sleep(0.001)
+    @cache.write(9, "iiiiiiiiii") && sleep(0.001)
+    @cache.write(10, "kkkkkkkkkk") && sleep(0.001)
+    @cache.read(2) && sleep(0.001)
+    @cache.read(4) && sleep(0.001)
+    @cache.write(11, "llllllllll")
+    assert @cache.exist?(11)
+    assert @cache.exist?(10)
+    assert @cache.exist?(9)
+    assert @cache.exist?(8)
+    assert @cache.exist?(7)
+    assert !@cache.exist?(6), "no entry"
+    assert !@cache.exist?(5), "no entry"
+    assert @cache.exist?(4)
+    assert !@cache.exist?(3), "no entry"
+    assert @cache.exist?(2)
+    assert !@cache.exist?(1), "no entry"
+  end
+
+  def test_prune_size_on_write_based_on_key_length
+    @cache.write(1, "aaaaaaaaaa") && sleep(0.001)
+    @cache.write(2, "bbbbbbbbbb") && sleep(0.001)
+    @cache.write(3, "cccccccccc") && sleep(0.001)
+    @cache.write(4, "dddddddddd") && sleep(0.001)
+    @cache.write(5, "eeeeeeeeee") && sleep(0.001)
+    @cache.write(6, "ffffffffff") && sleep(0.001)
+    @cache.write(7, "gggggggggg") && sleep(0.001)
+    @cache.write(8, "hhhhhhhhhh") && sleep(0.001)
+    @cache.write(9, "iiiiiiiiii") && sleep(0.001)
+    long_key = '*' * 2 * @record_size
+    @cache.write(long_key, "llllllllll")
+    assert @cache.exist?(long_key)
+    assert @cache.exist?(9)
+    assert @cache.exist?(8)
+    assert @cache.exist?(7)
+    assert @cache.exist?(6)
+    assert !@cache.exist?(5), "no entry"
+    assert !@cache.exist?(4), "no entry"
+    assert !@cache.exist?(3), "no entry"
+    assert !@cache.exist?(2), "no entry"
+    assert !@cache.exist?(1), "no entry"
+  end
+
+  def test_pruning_is_capped_at_a_max_time
+    def @cache.delete_entry (*args)
+      sleep(0.01)
+      super
+    end
+    @cache.write(1, "aaaaaaaaaa") && sleep(0.001)
+    @cache.write(2, "bbbbbbbbbb") && sleep(0.001)
+    @cache.write(3, "cccccccccc") && sleep(0.001)
+    @cache.write(4, "dddddddddd") && sleep(0.001)
+    @cache.write(5, "eeeeeeeeee") && sleep(0.001)
+    @cache.prune(30, 0.001)
+    assert @cache.exist?(5)
+    assert @cache.exist?(4)
+    assert @cache.exist?(3)
+    assert @cache.exist?(2)
+    assert !@cache.exist?(1)
+  end
+
+  def test_write_with_unless_exist
+    assert_equal true, @cache.write(1, "aaaaaaaaaa")
+    assert_equal false, @cache.write(1, "aaaaaaaaaa", :unless_exist => true)
+    @cache.write(1, nil)
+    assert_equal false, @cache.write(1, "aaaaaaaaaa", :unless_exist => true)
+  end
+end
+
+class MemCacheStoreTest < ActiveSupport::TestCase
+  require 'dalli'
+
+  begin
+    ss = Dalli::Client.new('localhost:11211').stats
+    raise Dalli::DalliError unless ss['localhost:11211']
+
+    MEMCACHE_UP = true
+  rescue Dalli::DalliError
+    $stderr.puts "Skipping memcached tests. Start memcached and try again."
+    MEMCACHE_UP = false
+  end
+
+  def setup
+    skip "memcache server is not up" unless MEMCACHE_UP
+
+    @cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :expires_in => 60)
+    @peek = ActiveSupport::Cache.lookup_store(:mem_cache_store)
+    @data = @cache.instance_variable_get(:@data)
+    @cache.clear
+    @cache.silence!
+    @cache.logger = ActiveSupport::Logger.new("/dev/null")
+  end
+
+  include CacheStoreBehavior
+  include LocalCacheBehavior
+  include CacheIncrementDecrementBehavior
+  include EncodedKeyCacheBehavior
+  include AutoloadingCacheBehavior
+
+  def test_raw_values
+    cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true)
+    cache.clear
+    cache.write("foo", 2)
+    assert_equal "2", cache.read("foo")
+  end
+
+  def test_raw_values_with_marshal
+    cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true)
+    cache.clear
+    cache.write("foo", Marshal.dump([]))
+    assert_equal [], cache.read("foo")
+  end
+
+  def test_local_cache_raw_values
+    cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true)
+    cache.clear
+    cache.with_local_cache do
+      cache.write("foo", 2)
+      assert_equal "2", cache.read("foo")
+    end
+  end
+
+  def test_local_cache_raw_values_with_marshal
+    cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true)
+    cache.clear
+    cache.with_local_cache do
+      cache.write("foo", Marshal.dump([]))
+      assert_equal [], cache.read("foo")
+    end
+  end
+
+  def test_read_should_return_a_different_object_id_each_time_it_is_called
+    @cache.write('foo', 'bar')
+    assert_not_equal @cache.read('foo').object_id, @cache.read('foo').object_id
+    value = @cache.read('foo')
+    value << 'bingo'
+    assert_not_equal value, @cache.read('foo')
+  end
+end
+
+class NullStoreTest < ActiveSupport::TestCase
+  def setup
+    @cache = ActiveSupport::Cache.lookup_store(:null_store)
+  end
+
+  def test_clear
+    @cache.clear
+  end
+
+  def test_cleanup
+    @cache.cleanup
+  end
+
+  def test_write
+    assert_equal true, @cache.write("name", "value")
+  end
+
+  def test_read
+    @cache.write("name", "value")
+    assert_nil @cache.read("name")
+  end
+
+  def test_delete
+    @cache.write("name", "value")
+    assert_equal false, @cache.delete("name")
+  end
+
+  def test_increment
+    @cache.write("name", 1, :raw => true)
+    assert_nil @cache.increment("name")
+  end
+
+  def test_decrement
+    @cache.write("name", 1, :raw => true)
+    assert_nil @cache.increment("name")
+  end
+
+  def test_delete_matched
+    @cache.write("name", "value")
+    @cache.delete_matched(/name/)
+  end
+
+  def test_local_store_strategy
+    @cache.with_local_cache do
+      @cache.write("name", "value")
+      assert_equal "value", @cache.read("name")
+      @cache.delete("name")
+      assert_nil @cache.read("name")
+      @cache.write("name", "value")
+    end
+    assert_nil @cache.read("name")
+  end
+
+  def test_setting_nil_cache_store
+    assert ActiveSupport::Cache.lookup_store.class.name, ActiveSupport::Cache::NullStore.name
+  end
+end
+
+class CacheStoreLoggerTest < ActiveSupport::TestCase
+  def setup
+    @cache = ActiveSupport::Cache.lookup_store(:memory_store)
+
+    @buffer = StringIO.new
+    @cache.logger = ActiveSupport::Logger.new(@buffer)
+  end
+
+  def test_logging
+    @cache.fetch('foo') { 'bar' }
+    assert @buffer.string.present?
+  end
+
+  def test_mute_logging
+    @cache.mute { @cache.fetch('foo') { 'bar' } }
+    assert @buffer.string.blank?
+  end
+end
+
+class CacheEntryTest < ActiveSupport::TestCase
+  def test_expired
+    entry = ActiveSupport::Cache::Entry.new("value")
+    assert !entry.expired?, 'entry not expired'
+    entry = ActiveSupport::Cache::Entry.new("value", :expires_in => 60)
+    assert !entry.expired?, 'entry not expired'
+    time = Time.now + 61
+    Time.stubs(:now).returns(time)
+    assert entry.expired?, 'entry is expired'
+  end
+
+  def test_compress_values
+    value = "value" * 100
+    entry = ActiveSupport::Cache::Entry.new(value, :compress => true, :compress_threshold => 1)
+    assert_equal value, entry.value
+    assert(value.bytesize > entry.size, "value is compressed")
+  end
+
+  def test_non_compress_values
+    value = "value" * 100
+    entry = ActiveSupport::Cache::Entry.new(value)
+    assert_equal value, entry.value
+    assert_equal value.bytesize, entry.size
+  end
+
+  def test_restoring_version_4beta1_entries
+    version_4beta1_entry = ActiveSupport::Cache::Entry.allocate
+    version_4beta1_entry.instance_variable_set(:@v, "hello")
+    version_4beta1_entry.instance_variable_set(:@x, Time.now.to_i + 60)
+    entry = Marshal.load(Marshal.dump(version_4beta1_entry))
+    assert_equal "hello", entry.value
+    assert_equal false, entry.expired?
+  end
+
+  def test_restoring_compressed_version_4beta1_entries
+    version_4beta1_entry = ActiveSupport::Cache::Entry.allocate
+    version_4beta1_entry.instance_variable_set(:@v, Zlib::Deflate.deflate(Marshal.dump("hello")))
+    version_4beta1_entry.instance_variable_set(:@c, true)
+    entry = Marshal.load(Marshal.dump(version_4beta1_entry))
+    assert_equal "hello", entry.value
+  end
+
+  def test_restoring_expired_version_4beta1_entries
+    version_4beta1_entry = ActiveSupport::Cache::Entry.allocate
+    version_4beta1_entry.instance_variable_set(:@v, "hello")
+    version_4beta1_entry.instance_variable_set(:@x, Time.now.to_i - 1)
+    entry = Marshal.load(Marshal.dump(version_4beta1_entry))
+    assert_equal "hello", entry.value
+    assert_equal true, entry.expired?
+  end
+end
diff --git a/app/server/vendor/activesupport/test/callback_inheritance_test.rb b/app/server/vendor/activesupport/test/callback_inheritance_test.rb
new file mode 100644
index 0000000..1adfe4e
--- /dev/null
+++ b/app/server/vendor/activesupport/test/callback_inheritance_test.rb
@@ -0,0 +1,176 @@
+require 'abstract_unit'
+
+class GrandParent
+  include ActiveSupport::Callbacks
+
+  attr_reader :log, :action_name
+  def initialize(action_name)
+    @action_name, @log = action_name, []
+  end
+
+  define_callbacks :dispatch
+  set_callback :dispatch, :before, :before1, :before2, :if => proc {|c| c.action_name == "index" || c.action_name == "update" }
+  set_callback :dispatch, :after, :after1, :after2, :if => proc {|c| c.action_name == "update" || c.action_name == "delete" }
+
+  def before1
+    @log << "before1"
+  end
+
+  def before2
+    @log << "before2"
+  end
+
+  def after1
+    @log << "after1"
+  end
+
+  def after2
+    @log << "after2"
+  end
+
+  def dispatch
+    run_callbacks :dispatch do
+      @log << action_name
+    end
+    self
+  end
+end
+
+class Parent < GrandParent
+  skip_callback :dispatch, :before, :before2, :unless => proc {|c| c.action_name == "update" }
+  skip_callback :dispatch, :after, :after2, :unless => proc {|c| c.action_name == "delete" }
+end
+
+class Child < GrandParent
+  skip_callback :dispatch, :before, :before2, :unless => proc {|c| c.action_name == "update" }, :if => :state_open?
+
+  def state_open?
+    @state == :open
+  end
+
+  def initialize(action_name, state)
+    super(action_name)
+    @state = state
+  end
+end
+
+class EmptyParent
+  include ActiveSupport::Callbacks
+
+  def performed?
+    @performed ||= false
+  end
+
+  define_callbacks :dispatch
+
+  def perform!
+    @performed = true
+  end
+
+  def dispatch
+    run_callbacks :dispatch
+    self
+  end
+end
+
+class EmptyChild < EmptyParent
+  set_callback :dispatch, :before, :do_nothing
+
+  def do_nothing
+  end
+end
+
+class CountingParent
+  include ActiveSupport::Callbacks
+
+  attr_reader :count
+
+  define_callbacks :dispatch
+
+  def initialize
+    @count = 0
+  end
+
+  def count!
+    @count += 1
+  end
+
+  def dispatch
+    run_callbacks(:dispatch)
+    self
+  end
+end
+
+class CountingChild < CountingParent
+end
+
+class BasicCallbacksTest < ActiveSupport::TestCase
+  def setup
+    @index    = GrandParent.new("index").dispatch
+    @update   = GrandParent.new("update").dispatch
+    @delete   = GrandParent.new("delete").dispatch
+  end
+
+  def test_basic_conditional_callback1
+    assert_equal %w(before1 before2 index), @index.log
+  end
+
+  def test_basic_conditional_callback2
+    assert_equal %w(before1 before2 update after2 after1), @update.log
+  end
+
+  def test_basic_conditional_callback3
+    assert_equal %w(delete after2 after1), @delete.log
+  end
+end
+
+class InheritedCallbacksTest < ActiveSupport::TestCase
+  def setup
+    @index    = Parent.new("index").dispatch
+    @update   = Parent.new("update").dispatch
+    @delete   = Parent.new("delete").dispatch
+  end
+
+  def test_inherited_excluded
+    assert_equal %w(before1 index), @index.log
+  end
+
+  def test_inherited_not_excluded
+    assert_equal %w(before1 before2 update after1), @update.log
+  end
+
+  def test_partially_excluded
+    assert_equal %w(delete after2 after1), @delete.log
+  end
+end
+
+class InheritedCallbacksTest2 < ActiveSupport::TestCase
+  def setup
+    @update1 = Child.new("update", :open).dispatch
+    @update2 = Child.new("update", :closed).dispatch
+  end
+
+  def test_crazy_mix_on
+    assert_equal %w(before1 update after2 after1), @update1.log
+  end
+
+  def test_crazy_mix_off
+    assert_equal %w(before1 before2 update after2 after1), @update2.log
+  end
+end
+
+class DynamicInheritedCallbacks < ActiveSupport::TestCase
+  def test_callbacks_looks_to_the_superclass_before_running
+    child = EmptyChild.new.dispatch
+    assert !child.performed?
+    EmptyParent.set_callback :dispatch, :before, :perform!
+    child = EmptyChild.new.dispatch
+    assert child.performed?
+  end
+
+  def test_callbacks_should_be_performed_once_in_child_class
+    CountingParent.set_callback(:dispatch, :before) { count! }
+    child = CountingChild.new.dispatch
+    assert_equal 1, child.count
+  end
+end
diff --git a/app/server/vendor/activesupport/test/callbacks_test.rb b/app/server/vendor/activesupport/test/callbacks_test.rb
new file mode 100644
index 0000000..32c2dfd
--- /dev/null
+++ b/app/server/vendor/activesupport/test/callbacks_test.rb
@@ -0,0 +1,1003 @@
+require 'abstract_unit'
+
+module CallbacksTest
+  class Record
+    include ActiveSupport::Callbacks
+
+    define_callbacks :save
+
+    def self.before_save(*filters, &blk)
+      set_callback(:save, :before, *filters, &blk)
+    end
+
+    def self.after_save(*filters, &blk)
+      set_callback(:save, :after, *filters, &blk)
+    end
+
+    class << self
+      def callback_symbol(callback_method)
+        method_name = :"#{callback_method}_method"
+        define_method(method_name) do
+          history << [callback_method, :symbol]
+        end
+        method_name
+      end
+
+      def callback_string(callback_method)
+        "history << [#{callback_method.to_sym.inspect}, :string]"
+      end
+
+      def callback_proc(callback_method)
+        Proc.new { |model| model.history << [callback_method, :proc] }
+      end
+
+      def callback_object(callback_method)
+        klass = Class.new
+        klass.send(:define_method, callback_method) do |model|
+          model.history << [:"#{callback_method}_save", :object]
+        end
+        klass.new
+      end
+    end
+
+    def history
+      @history ||= []
+    end
+  end
+
+  class CallbackClass
+    def self.before(model)
+      model.history << [:before_save, :class]
+    end
+    
+    def self.after(model)
+      model.history << [:after_save, :class]
+    end
+  end
+
+  class Person < Record
+    [:before_save, :after_save].each do |callback_method|
+      callback_method_sym = callback_method.to_sym
+      send(callback_method, callback_symbol(callback_method_sym))
+      send(callback_method, callback_string(callback_method_sym))
+      send(callback_method, callback_proc(callback_method_sym))
+      send(callback_method, callback_object(callback_method_sym.to_s.gsub(/_save/, '')))
+      send(callback_method, CallbackClass)
+      send(callback_method) { |model| model.history << [callback_method_sym, :block] }
+    end
+
+    def save
+      run_callbacks :save
+    end
+  end
+
+  class PersonSkipper < Person
+    skip_callback :save, :before, :before_save_method, :if => :yes
+    skip_callback :save, :after, :before_save_method, :unless => :yes
+    skip_callback :save, :after, :before_save_method, :if => :no
+    skip_callback :save, :before, :before_save_method, :unless => :no
+    skip_callback :save, :before, CallbackClass , :if => :yes
+    def yes; true; end
+    def no; false; end
+  end
+
+  class PersonForProgrammaticSkipping < Person
+  end
+
+  class ParentController
+    include ActiveSupport::Callbacks
+
+    define_callbacks :dispatch
+
+    set_callback :dispatch, :before, :log, :unless => proc {|c| c.action_name == :index || c.action_name == :show }
+    set_callback :dispatch, :after, :log2
+
+    attr_reader :action_name, :logger
+    def initialize(action_name)
+      @action_name, @logger = action_name, []
+    end
+
+    def log
+      @logger << action_name
+    end
+
+    def log2
+      @logger << action_name
+    end
+
+    def dispatch
+      run_callbacks :dispatch do
+        @logger << "Done"
+      end
+      self
+    end
+  end
+
+  class Child < ParentController
+    skip_callback :dispatch, :before, :log, :if => proc {|c| c.action_name == :update}
+    skip_callback :dispatch, :after, :log2
+  end
+
+  class OneTimeCompile < Record
+    @@starts_true, @@starts_false = true, false
+
+    def initialize
+      super
+    end
+
+    before_save Proc.new {|r| r.history << [:before_save, :starts_true, :if] }, :if => :starts_true
+    before_save Proc.new {|r| r.history << [:before_save, :starts_false, :if] }, :if => :starts_false
+    before_save Proc.new {|r| r.history << [:before_save, :starts_true, :unless] }, :unless => :starts_true
+    before_save Proc.new {|r| r.history << [:before_save, :starts_false, :unless] }, :unless => :starts_false
+
+    def starts_true
+      if @@starts_true
+        @@starts_true = false
+        return true
+      end
+      @@starts_true
+    end
+
+    def starts_false
+      unless @@starts_false
+        @@starts_false = true
+        return false
+      end
+      @@starts_false
+    end
+
+    def save
+      run_callbacks :save
+    end
+  end
+
+  class OneTimeCompileTest < ActiveSupport::TestCase
+    def test_optimized_first_compile
+      around = OneTimeCompile.new
+      around.save
+      assert_equal [
+        [:before_save, :starts_true, :if],
+        [:before_save, :starts_true, :unless]
+      ], around.history
+    end
+  end
+
+  class AfterSaveConditionalPerson < Record
+    after_save Proc.new { |r| r.history << [:after_save, :string1] }
+    after_save Proc.new { |r| r.history << [:after_save, :string2] }
+    def save
+      run_callbacks :save
+    end
+  end
+
+  class AfterSaveConditionalPersonCallbackTest < ActiveSupport::TestCase
+    def test_after_save_runs_in_the_reverse_order
+      person = AfterSaveConditionalPerson.new
+      person.save
+      assert_equal [
+        [:after_save, :string2],
+        [:after_save, :string1]
+      ], person.history
+    end
+  end
+
+
+
+  class ConditionalPerson < Record
+    # proc
+    before_save Proc.new { |r| r.history << [:before_save, :proc] }, :if => Proc.new { |r| true }
+    before_save Proc.new { |r| r.history << "b00m" }, :if => Proc.new { |r| false }
+    before_save Proc.new { |r| r.history << [:before_save, :proc] }, :unless => Proc.new { |r| false }
+    before_save Proc.new { |r| r.history << "b00m" }, :unless => Proc.new { |r| true }
+    # symbol
+    before_save Proc.new { |r| r.history << [:before_save, :symbol] }, :if => :yes
+    before_save Proc.new { |r| r.history << "b00m" }, :if => :no
+    before_save Proc.new { |r| r.history << [:before_save, :symbol] }, :unless => :no
+    before_save Proc.new { |r| r.history << "b00m" }, :unless => :yes
+    # string
+    before_save Proc.new { |r| r.history << [:before_save, :string] }, :if => 'yes'
+    before_save Proc.new { |r| r.history << "b00m" }, :if => 'no'
+    before_save Proc.new { |r| r.history << [:before_save, :string] }, :unless => 'no'
+    before_save Proc.new { |r| r.history << "b00m" }, :unless => 'yes'
+    # Combined if and unless
+    before_save Proc.new { |r| r.history << [:before_save, :combined_symbol] }, :if => :yes, :unless => :no
+    before_save Proc.new { |r| r.history << "b00m" }, :if => :yes, :unless => :yes
+
+    def yes; true; end
+    def other_yes; true; end
+    def no; false; end
+    def other_no; false; end
+
+    def save
+      run_callbacks :save
+    end
+  end
+
+  class CleanPerson < ConditionalPerson
+    reset_callbacks :save
+  end
+
+  class MySuper
+    include ActiveSupport::Callbacks
+    define_callbacks :save
+  end
+
+  class AroundPerson < MySuper
+    attr_reader :history
+
+    set_callback :save, :before, :nope,           :if =>     :no
+    set_callback :save, :before, :nope,           :unless => :yes
+    set_callback :save, :after,  :tweedle
+    set_callback :save, :before, "tweedle_dee"
+    set_callback :save, :before, proc {|m| m.history << "yup" }
+    set_callback :save, :before, :nope,           :if =>     proc { false }
+    set_callback :save, :before, :nope,           :unless => proc { true }
+    set_callback :save, :before, :yup,            :if =>     proc { true }
+    set_callback :save, :before, :yup,            :unless => proc { false }
+    set_callback :save, :around, :tweedle_dum
+    set_callback :save, :around, :w0tyes,         :if =>     :yes
+    set_callback :save, :around, :w0tno,          :if =>     :no
+    set_callback :save, :around, :tweedle_deedle
+
+    def no; false; end
+    def yes; true; end
+
+    def nope
+      @history << "boom"
+    end
+
+    def yup
+      @history << "yup"
+    end
+
+    def w0tyes
+      @history << "w0tyes before"
+      yield
+      @history << "w0tyes after"
+    end
+
+    def w0tno
+      @history << "boom"
+      yield
+    end
+
+    def tweedle_dee
+      @history << "tweedle dee"
+    end
+
+    def tweedle_dum
+      @history << "tweedle dum pre"
+      yield
+      @history << "tweedle dum post"
+    end
+
+    def tweedle
+      @history << "tweedle"
+    end
+
+    def tweedle_deedle
+      @history << "tweedle deedle pre"
+      yield
+      @history << "tweedle deedle post"
+    end
+
+    def initialize
+      @history = []
+    end
+
+    def save
+      run_callbacks :save do
+        @history << "running"
+      end
+    end
+  end
+
+  class AroundPersonResult < MySuper
+    attr_reader :result
+
+    set_callback :save, :after, :tweedle_1
+    set_callback :save, :around, :tweedle_dum
+    set_callback :save, :after, :tweedle_2
+
+    def tweedle_dum
+      @result = yield
+    end
+
+    def tweedle_1
+      :tweedle_1
+    end
+
+    def tweedle_2
+      :tweedle_2
+    end
+
+    def save
+      run_callbacks :save do
+        :running
+      end
+    end
+  end
+
+  class HyphenatedCallbacks
+    include ActiveSupport::Callbacks
+    define_callbacks :save
+    attr_reader :stuff
+
+    set_callback :save, :before, :action, :if => :yes
+
+    def yes() true end
+
+    def action
+      @stuff = "ACTION"
+    end
+
+    def save
+      run_callbacks :save do
+        @stuff
+      end
+    end
+  end
+
+  module ExtendModule
+    def self.extended(base)
+      base.class_eval do
+        set_callback :save, :before, :record3
+      end
+    end
+    def record3
+      @recorder << 3
+    end
+  end
+
+  module IncludeModule
+    def self.included(base)
+      base.class_eval do
+        set_callback :save, :before, :record2
+      end
+    end
+    def record2
+      @recorder << 2
+    end
+  end
+
+  class ExtendCallbacks
+
+    include ActiveSupport::Callbacks
+
+    define_callbacks :save
+    set_callback :save, :before, :record1
+
+    include IncludeModule
+
+    def save
+      run_callbacks :save
+    end
+
+    attr_reader :recorder
+
+    def initialize
+      @recorder = []
+    end
+
+    private
+
+      def record1
+        @recorder << 1
+      end
+  end
+
+  class AroundCallbacksTest < ActiveSupport::TestCase
+    def test_save_around
+      around = AroundPerson.new
+      around.save
+      assert_equal [
+        "tweedle dee",
+        "yup", "yup",
+        "tweedle dum pre",
+        "w0tyes before",
+        "tweedle deedle pre",
+        "running",
+        "tweedle deedle post",
+        "w0tyes after",
+        "tweedle dum post",
+        "tweedle"
+      ], around.history
+    end
+  end
+
+  class AroundCallbackResultTest < ActiveSupport::TestCase
+    def test_save_around
+      around = AroundPersonResult.new
+      around.save
+      assert_equal :running, around.result
+    end
+  end
+
+  class SkipCallbacksTest < ActiveSupport::TestCase
+    def test_skip_person
+      person = PersonSkipper.new
+      assert_equal [], person.history
+      person.save
+      assert_equal [
+        [:before_save, :string],
+        [:before_save, :proc],
+        [:before_save, :object],
+        [:before_save, :block],
+        [:after_save, :block],
+        [:after_save, :class],
+        [:after_save, :object],
+        [:after_save, :proc],
+        [:after_save, :string],
+        [:after_save, :symbol]
+      ], person.history
+    end
+
+    def test_skip_person_programmatically
+      PersonForProgrammaticSkipping._save_callbacks.each do |save_callback|
+        if "before" == save_callback.kind.to_s
+          PersonForProgrammaticSkipping.skip_callback("save", save_callback.kind, save_callback.filter)
+        end
+      end
+      person = PersonForProgrammaticSkipping.new
+      assert_equal [], person.history
+      person.save
+      assert_equal [
+        [:after_save, :block],
+        [:after_save, :class],
+        [:after_save, :object],
+        [:after_save, :proc],
+        [:after_save, :string],
+        [:after_save, :symbol]
+      ], person.history
+    end
+  end
+
+  class CallbacksTest < ActiveSupport::TestCase
+
+    def test_save_person
+      person = Person.new
+      assert_equal [], person.history
+      person.save
+      assert_equal [
+        [:before_save, :symbol],
+        [:before_save, :string],
+        [:before_save, :proc],
+        [:before_save, :object],
+        [:before_save, :class],
+        [:before_save, :block],
+        [:after_save, :block],
+        [:after_save, :class],
+        [:after_save, :object],
+        [:after_save, :proc],
+        [:after_save, :string],
+        [:after_save, :symbol]
+      ], person.history
+    end
+  end
+
+  class ConditionalCallbackTest < ActiveSupport::TestCase
+    def test_save_conditional_person
+      person = ConditionalPerson.new
+      person.save
+      assert_equal [
+        [:before_save, :proc],
+        [:before_save, :proc],
+        [:before_save, :symbol],
+        [:before_save, :symbol],
+        [:before_save, :string],
+        [:before_save, :string],
+        [:before_save, :combined_symbol],
+      ], person.history
+    end
+  end
+
+
+
+  class ResetCallbackTest < ActiveSupport::TestCase
+    def test_save_conditional_person
+      person = CleanPerson.new
+      person.save
+      assert_equal [], person.history
+    end
+  end
+
+  class CallbackTerminator
+    include ActiveSupport::Callbacks
+
+    define_callbacks :save, :terminator => ->(_,result) { result == :halt }
+
+    set_callback :save, :before, :first
+    set_callback :save, :before, :second
+    set_callback :save, :around, :around_it
+    set_callback :save, :before, :third
+    set_callback :save, :after, :first
+    set_callback :save, :around, :around_it
+    set_callback :save, :after, :second
+    set_callback :save, :around, :around_it
+    set_callback :save, :after, :third
+
+
+    attr_reader :history, :saved, :halted
+    def initialize
+      @history = []
+    end
+
+    def around_it
+      @history << "around1"
+      yield
+      @history << "around2"
+    end
+
+    def first
+      @history << "first"
+    end
+
+    def second
+      @history << "second"
+      :halt
+    end
+
+    def third
+      @history << "third"
+    end
+
+    def save
+      run_callbacks :save do
+        @saved = true
+      end
+    end
+
+    def halted_callback_hook(filter)
+      @halted = filter
+    end
+  end
+
+  class CallbackObject
+    def before(caller)
+      caller.record << "before"
+    end
+
+    def before_save(caller)
+      caller.record << "before save"
+    end
+
+    def around(caller)
+      caller.record << "around before"
+      yield
+      caller.record << "around after"
+    end
+  end
+
+  class UsingObjectBefore
+    include ActiveSupport::Callbacks
+
+    define_callbacks :save
+    set_callback :save, :before, CallbackObject.new
+
+    attr_accessor :record
+    def initialize
+      @record = []
+    end
+
+    def save
+      run_callbacks :save do
+        @record << "yielded"
+      end
+    end
+  end
+
+  class UsingObjectAround
+    include ActiveSupport::Callbacks
+
+    define_callbacks :save
+    set_callback :save, :around, CallbackObject.new
+
+    attr_accessor :record
+    def initialize
+      @record = []
+    end
+
+    def save
+      run_callbacks :save do
+        @record << "yielded"
+      end
+    end
+  end
+
+  class CustomScopeObject
+    include ActiveSupport::Callbacks
+
+    define_callbacks :save, :scope => [:kind, :name]
+    set_callback :save, :before, CallbackObject.new
+
+    attr_accessor :record
+    def initialize
+      @record = []
+    end
+
+    def save
+      run_callbacks :save do
+        @record << "yielded"
+        "CallbackResult"
+      end
+    end
+  end
+
+  class OneTwoThreeSave
+    include ActiveSupport::Callbacks
+
+    define_callbacks :save
+
+    attr_accessor :record
+
+    def initialize
+      @record = []
+    end
+
+    def save
+      run_callbacks :save do
+        @record << "yielded"
+      end
+    end
+
+    def first
+      @record << "one"
+    end
+
+    def second
+      @record << "two"
+    end
+
+    def third
+      @record << "three"
+    end
+  end
+
+  class DuplicatingCallbacks < OneTwoThreeSave
+    set_callback :save, :before, :first, :second
+    set_callback :save, :before, :first, :third
+  end
+
+  class DuplicatingCallbacksInSameCall < OneTwoThreeSave
+    set_callback :save, :before, :first, :second, :first, :third
+  end
+
+  class UsingObjectTest < ActiveSupport::TestCase
+    def test_before_object
+      u = UsingObjectBefore.new
+      u.save
+      assert_equal ["before", "yielded"], u.record
+    end
+
+    def test_around_object
+      u = UsingObjectAround.new
+      u.save
+      assert_equal ["around before", "yielded", "around after"], u.record
+    end
+
+    def test_customized_object
+      u = CustomScopeObject.new
+      u.save
+      assert_equal ["before save", "yielded"], u.record
+    end
+
+    def test_block_result_is_returned
+      u = CustomScopeObject.new
+      assert_equal "CallbackResult", u.save
+    end
+  end
+
+  class CallbackTerminatorTest < ActiveSupport::TestCase
+    def test_termination
+      terminator = CallbackTerminator.new
+      terminator.save
+      assert_equal ["first", "second", "third", "second", "first"], terminator.history
+    end
+
+    def test_termination_invokes_hook
+      terminator = CallbackTerminator.new
+      terminator.save
+      assert_equal :second, terminator.halted
+    end
+
+    def test_block_never_called_if_terminated
+      obj = CallbackTerminator.new
+      obj.save
+      assert !obj.saved
+    end
+  end
+
+  class HyphenatedKeyTest < ActiveSupport::TestCase
+    def test_save
+      obj = HyphenatedCallbacks.new
+      obj.save
+      assert_equal "ACTION", obj.stuff
+    end
+  end
+
+  class WriterSkipper < Person
+    attr_accessor :age
+    skip_callback :save, :before, :before_save_method, :if => lambda {self.age > 21}
+  end
+
+  class WriterCallbacksTest < ActiveSupport::TestCase
+    def test_skip_writer
+      writer = WriterSkipper.new
+      writer.age = 18
+      assert_equal [], writer.history
+      writer.save
+      assert_equal [
+        [:before_save, :symbol],
+        [:before_save, :string],
+        [:before_save, :proc],
+        [:before_save, :object],
+        [:before_save, :class],
+        [:before_save, :block],
+        [:after_save, :block],
+        [:after_save, :class],
+        [:after_save, :object],
+        [:after_save, :proc],
+        [:after_save, :string],
+        [:after_save, :symbol]
+      ], writer.history
+    end
+  end
+
+  class ExtendCallbacksTest < ActiveSupport::TestCase
+    def test_save
+      model = ExtendCallbacks.new.extend ExtendModule
+      model.save
+      assert_equal [1, 2, 3], model.recorder
+    end
+  end
+
+  class ExcludingDuplicatesCallbackTest < ActiveSupport::TestCase
+    def test_excludes_duplicates_in_separate_calls
+      model = DuplicatingCallbacks.new
+      model.save
+      assert_equal ["two", "one", "three", "yielded"], model.record
+    end
+
+    def test_excludes_duplicates_in_one_call
+      model = DuplicatingCallbacksInSameCall.new
+      model.save
+      assert_equal ["two", "one", "three", "yielded"], model.record
+    end
+  end
+
+  class CallbackProcTest < ActiveSupport::TestCase
+    def build_class(callback)
+      Class.new {
+        include ActiveSupport::Callbacks
+        define_callbacks :foo
+        set_callback :foo, :before, callback
+        def run; run_callbacks :foo; end
+      }
+    end
+
+    def test_proc_arity_0
+      calls = []
+      klass = build_class(->() { calls << :foo })
+      klass.new.run
+      assert_equal [:foo], calls
+    end
+
+    def test_proc_arity_1
+      calls = []
+      klass = build_class(->(o) { calls << o })
+      instance = klass.new
+      instance.run
+      assert_equal [instance], calls
+    end
+
+    def test_proc_arity_2
+      assert_raises(ArgumentError) do
+        klass = build_class(->(x,y) { })
+        klass.new.run
+      end
+    end
+
+    def test_proc_negative_called_with_empty_list
+      calls = []
+      klass = build_class(->(*args) { calls << args })
+      klass.new.run
+      assert_equal [[]], calls
+    end
+  end
+
+  class ConditionalTests < ActiveSupport::TestCase
+    def build_class(callback)
+      Class.new {
+        include ActiveSupport::Callbacks
+        define_callbacks :foo
+        set_callback :foo, :before, :foo, :if => callback
+        def foo; end
+        def run; run_callbacks :foo; end
+      }
+    end
+
+    # FIXME: do we really want to support classes as conditionals?  There were
+    # no tests for it previous to this.
+    def test_class_conditional_with_scope
+      z = []
+      callback = Class.new {
+        define_singleton_method(:foo) { |o| z << o }
+      }
+      klass = Class.new {
+        include ActiveSupport::Callbacks
+        define_callbacks :foo, :scope => [:name]
+        set_callback :foo, :before, :foo, :if => callback
+        def run; run_callbacks :foo; end
+        private
+        def foo; end
+      }
+      object = klass.new
+      object.run
+      assert_equal [object], z
+    end
+
+    # FIXME: do we really want to support classes as conditionals?  There were
+    # no tests for it previous to this.
+    def test_class
+      z = []
+      klass = build_class Class.new {
+        define_singleton_method(:before) { |o| z << o }
+      }
+      object = klass.new
+      object.run
+      assert_equal [object], z
+    end
+
+    def test_proc_negative_arity # passes an empty list if *args
+      z = []
+      object = build_class(->(*args) { z << args }).new
+      object.run
+      assert_equal [], z.flatten
+    end
+
+    def test_proc_arity0
+      z = []
+      object = build_class(->() { z << 0 }).new
+      object.run
+      assert_equal [0], z
+    end
+
+    def test_proc_arity1
+      z = []
+      object = build_class(->(x) { z << x }).new
+      object.run
+      assert_equal [object], z
+    end
+
+    def test_proc_arity2
+      assert_raises(ArgumentError) do
+        object = build_class(->(a,b) { }).new
+        object.run
+      end
+    end
+  end
+
+  class ResetCallbackTest < ActiveSupport::TestCase
+    def build_class(memo)
+      klass = Class.new {
+        include ActiveSupport::Callbacks
+        define_callbacks :foo
+        set_callback :foo, :before, :hello
+        def run; run_callbacks :foo; end
+      }
+      klass.class_eval {
+        define_method(:hello) { memo << :hi }
+      }
+      klass
+    end
+
+    def test_reset_callbacks
+      events = []
+      klass = build_class events
+      klass.new.run
+      assert_equal 1, events.length
+
+      klass.reset_callbacks :foo
+      klass.new.run
+      assert_equal 1, events.length
+    end
+
+    def test_reset_impacts_subclasses
+      events = []
+      klass = build_class events
+      subclass = Class.new(klass) { set_callback :foo, :before, :world }
+      subclass.class_eval { define_method(:world) { events << :world } }
+
+      subclass.new.run
+      assert_equal 2, events.length
+
+      klass.reset_callbacks :foo
+      subclass.new.run
+      assert_equal 3, events.length
+    end
+  end
+
+  class CallbackTypeTest < ActiveSupport::TestCase
+    def build_class(callback, n = 10)
+      Class.new {
+        include ActiveSupport::Callbacks
+        define_callbacks :foo
+        n.times { set_callback :foo, :before, callback }
+        def run; run_callbacks :foo; end
+        def self.skip(thing); skip_callback :foo, :before, thing; end
+      }
+    end
+
+    def test_add_class
+      calls = []
+      callback = Class.new {
+        define_singleton_method(:before) { |o| calls << o }
+      }
+      build_class(callback).new.run
+      assert_equal 10, calls.length
+    end
+
+    def test_add_lambda
+      calls = []
+      build_class(->(o) { calls << o }).new.run
+      assert_equal 10, calls.length
+    end
+
+    def test_add_symbol
+      calls = []
+      klass = build_class(:bar)
+      klass.class_eval { define_method(:bar) { calls << klass } }
+      klass.new.run
+      assert_equal 1, calls.length
+    end
+
+    def test_add_eval
+      calls = []
+      klass = build_class("bar")
+      klass.class_eval { define_method(:bar) { calls << klass } }
+      klass.new.run
+      assert_equal 1, calls.length
+    end
+
+    def test_skip_class # removes one at a time
+      calls = []
+      callback = Class.new {
+        define_singleton_method(:before) { |o| calls << o }
+      }
+      klass = build_class(callback)
+      9.downto(0) { |i|
+        klass.skip callback
+        klass.new.run
+        assert_equal i, calls.length
+        calls.clear
+      }
+    end
+
+    def test_skip_lambda # removes nothing
+      calls = []
+      callback = ->(o) { calls << o }
+      klass = build_class(callback)
+      10.times { klass.skip callback }
+      klass.new.run
+      assert_equal 10, calls.length
+    end
+
+    def test_skip_symbol # removes all
+      calls = []
+      klass = build_class(:bar)
+      klass.class_eval { define_method(:bar) { calls << klass } }
+      klass.skip :bar
+      klass.new.run
+      assert_equal 0, calls.length
+    end
+
+    def test_skip_eval # removes nothing
+      calls = []
+      klass = build_class("bar")
+      klass.class_eval { define_method(:bar) { calls << klass } }
+      klass.skip "bar"
+      klass.new.run
+      assert_equal 1, calls.length
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/class_cache_test.rb b/app/server/vendor/activesupport/test/class_cache_test.rb
new file mode 100644
index 0000000..b96f476
--- /dev/null
+++ b/app/server/vendor/activesupport/test/class_cache_test.rb
@@ -0,0 +1,78 @@
+require 'abstract_unit'
+require 'active_support/dependencies'
+
+module ActiveSupport
+  module Dependencies
+    class ClassCacheTest < ActiveSupport::TestCase
+      def setup
+        @cache = ClassCache.new
+      end
+
+      def test_empty?
+        assert @cache.empty?
+        @cache.store(ClassCacheTest)
+        assert !@cache.empty?
+      end
+
+      def test_clear!
+        assert @cache.empty?
+        @cache.store(ClassCacheTest)
+        assert !@cache.empty?
+        @cache.clear!
+        assert @cache.empty?
+      end
+
+      def test_set_key
+        @cache.store(ClassCacheTest)
+        assert @cache.key?(ClassCacheTest.name)
+      end
+
+      def test_get_with_class
+        @cache.store(ClassCacheTest)
+        assert_equal ClassCacheTest, @cache.get(ClassCacheTest)
+      end
+
+      def test_get_with_name
+        @cache.store(ClassCacheTest)
+        assert_equal ClassCacheTest, @cache.get(ClassCacheTest.name)
+      end
+
+      def test_get_constantizes
+        assert @cache.empty?
+        assert_equal ClassCacheTest, @cache.get(ClassCacheTest.name)
+      end
+
+      def test_get_constantizes_fails_on_invalid_names
+        assert @cache.empty?
+        assert_raise NameError do
+          @cache.get("OmgTotallyInvalidConstantName")
+        end
+      end
+
+      def test_get_alias
+        assert @cache.empty?
+        assert_equal @cache[ClassCacheTest.name], @cache.get(ClassCacheTest.name)
+      end
+
+      def test_safe_get_constantizes
+        assert @cache.empty?
+        assert_equal ClassCacheTest, @cache.safe_get(ClassCacheTest.name)
+      end
+
+      def test_safe_get_constantizes_doesnt_fail_on_invalid_names
+        assert @cache.empty?
+        assert_equal nil, @cache.safe_get("OmgTotallyInvalidConstantName")
+      end
+
+      def test_new_rejects_strings
+        @cache.store ClassCacheTest.name
+        assert !@cache.key?(ClassCacheTest.name)
+      end
+
+      def test_store_returns_self
+        x = @cache.store ClassCacheTest
+        assert_equal @cache, x
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/clean_backtrace_test.rb b/app/server/vendor/activesupport/test/clean_backtrace_test.rb
new file mode 100644
index 0000000..dd67a45
--- /dev/null
+++ b/app/server/vendor/activesupport/test/clean_backtrace_test.rb
@@ -0,0 +1,70 @@
+require 'abstract_unit'
+
+class BacktraceCleanerFilterTest < ActiveSupport::TestCase
+  def setup
+    @bc = ActiveSupport::BacktraceCleaner.new
+    @bc.add_filter { |line| line.gsub("/my/prefix", '') }
+  end
+
+  test "backtrace should filter all lines in a backtrace, removing prefixes" do
+    assert_equal \
+        ["/my/class.rb", "/my/module.rb"],
+        @bc.clean(["/my/prefix/my/class.rb", "/my/prefix/my/module.rb"])
+  end
+
+  test "backtrace cleaner should allow removing filters" do
+    @bc.remove_filters!
+    assert_equal "/my/prefix/my/class.rb", @bc.clean(["/my/prefix/my/class.rb"]).first
+  end
+
+  test "backtrace should contain unaltered lines if they dont match a filter" do
+    assert_equal "/my/other_prefix/my/class.rb", @bc.clean([ "/my/other_prefix/my/class.rb" ]).first
+  end
+
+end
+
+class BacktraceCleanerSilencerTest < ActiveSupport::TestCase
+  def setup
+    @bc = ActiveSupport::BacktraceCleaner.new
+    @bc.add_silencer { |line| line =~ /mongrel/ }
+  end
+
+  test "backtrace should not contain lines that match the silencer" do
+    assert_equal \
+      [ "/other/class.rb" ],
+      @bc.clean([ "/mongrel/class.rb", "/other/class.rb", "/mongrel/stuff.rb" ])
+  end
+end
+
+class BacktraceCleanerMultipleSilencersTest < ActiveSupport::TestCase
+  def setup
+    @bc = ActiveSupport::BacktraceCleaner.new
+    @bc.add_silencer { |line| line =~ /mongrel/ }
+    @bc.add_silencer { |line| line =~ /yolo/ }
+  end
+
+  test "backtrace should not contain lines that match the silencers" do
+    assert_equal \
+      [ "/other/class.rb" ],
+      @bc.clean([ "/mongrel/class.rb", "/other/class.rb", "/mongrel/stuff.rb", "/other/yolo.rb" ])
+  end
+
+  test "backtrace should only contain lines that match the silencers" do
+    assert_equal \
+      [ "/mongrel/class.rb", "/mongrel/stuff.rb", "/other/yolo.rb" ],
+      @bc.clean([ "/mongrel/class.rb", "/other/class.rb", "/mongrel/stuff.rb", "/other/yolo.rb" ],
+                :noise)
+  end
+end
+
+class BacktraceCleanerFilterAndSilencerTest < ActiveSupport::TestCase
+  def setup
+    @bc = ActiveSupport::BacktraceCleaner.new
+    @bc.add_filter   { |line| line.gsub("/mongrel", "") }
+    @bc.add_silencer { |line| line =~ /mongrel/ }
+  end
+
+  test "backtrace should not silence lines that has first had their silence hook filtered out" do
+    assert_equal [ "/class.rb" ], @bc.clean([ "/mongrel/class.rb" ])
+  end
+end
diff --git a/app/server/vendor/activesupport/test/clean_logger_test.rb b/app/server/vendor/activesupport/test/clean_logger_test.rb
new file mode 100644
index 0000000..02693a9
--- /dev/null
+++ b/app/server/vendor/activesupport/test/clean_logger_test.rb
@@ -0,0 +1,29 @@
+require 'abstract_unit'
+require 'stringio'
+require 'active_support/logger'
+
+class CleanLoggerTest < ActiveSupport::TestCase
+  def setup
+    @out = StringIO.new
+    @logger = ActiveSupport::Logger.new(@out)
+  end
+
+  def test_format_message
+    @logger.error 'error'
+    assert_equal "error\n", @out.string
+  end
+
+  def test_datetime_format
+    @logger.formatter = Logger::Formatter.new
+    @logger.formatter.datetime_format = "%Y-%m-%d"
+    @logger.debug 'debug'
+    assert_equal "%Y-%m-%d", @logger.formatter.datetime_format
+    assert_match(/D, \[\d\d\d\d-\d\d-\d\d#\d+\] DEBUG -- : debug/, @out.string)
+  end
+
+  def test_nonstring_formatting
+    an_object = [1, 2, 3, 4, 5]
+    @logger.debug an_object
+    assert_equal("#{an_object.inspect}\n", @out.string)
+  end
+end
diff --git a/app/server/vendor/activesupport/test/concern_test.rb b/app/server/vendor/activesupport/test/concern_test.rb
new file mode 100644
index 0000000..60bd8a0
--- /dev/null
+++ b/app/server/vendor/activesupport/test/concern_test.rb
@@ -0,0 +1,104 @@
+require 'abstract_unit'
+require 'active_support/concern'
+
+class ConcernTest < ActiveSupport::TestCase
+  module Baz
+    extend ActiveSupport::Concern
+
+    class_methods do
+      def baz
+        "baz"
+      end
+
+      def included_ran=(value)
+        @@included_ran = value
+      end
+
+      def included_ran
+        @@included_ran
+      end
+    end
+
+    included do
+      self.included_ran = true
+    end
+
+    def baz
+      "baz"
+    end
+  end
+
+  module Bar
+    extend ActiveSupport::Concern
+
+    include Baz
+
+    module ClassMethods
+      def baz
+        "bar's baz + " + super
+      end
+    end
+
+    def bar
+      "bar"
+    end
+
+    def baz
+      "bar+" + super
+    end
+  end
+
+  module Foo
+    extend ActiveSupport::Concern
+
+    include Bar, Baz
+  end
+
+  def setup
+    @klass = Class.new
+  end
+
+  def test_module_is_included_normally
+    @klass.send(:include, Baz)
+    assert_equal "baz", @klass.new.baz
+    assert @klass.included_modules.include?(ConcernTest::Baz)
+  end
+
+  def test_class_methods_are_extended
+    @klass.send(:include, Baz)
+    assert_equal "baz", @klass.baz
+    assert_equal ConcernTest::Baz::ClassMethods, (class << @klass; self.included_modules; end)[0]
+  end
+
+  def test_included_block_is_ran
+    @klass.send(:include, Baz)
+    assert_equal true, @klass.included_ran
+  end
+
+  def test_modules_dependencies_are_met
+    @klass.send(:include, Bar)
+    assert_equal "bar", @klass.new.bar
+    assert_equal "bar+baz", @klass.new.baz
+    assert_equal "bar's baz + baz", @klass.baz
+    assert @klass.included_modules.include?(ConcernTest::Bar)
+  end
+
+  def test_dependencies_with_multiple_modules
+    @klass.send(:include, Foo)
+    assert_equal [ConcernTest::Foo, ConcernTest::Bar, ConcernTest::Baz], @klass.included_modules[0..2]
+  end
+
+  def test_raise_on_multiple_included_calls
+    assert_raises(ActiveSupport::Concern::MultipleIncludedBlocks) do
+      Module.new do
+        extend ActiveSupport::Concern
+
+        included do
+        end
+
+        included do
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/configurable_test.rb b/app/server/vendor/activesupport/test/configurable_test.rb
new file mode 100644
index 0000000..ef847fc
--- /dev/null
+++ b/app/server/vendor/activesupport/test/configurable_test.rb
@@ -0,0 +1,123 @@
+require 'abstract_unit'
+require 'active_support/configurable'
+
+class ConfigurableActiveSupport < ActiveSupport::TestCase
+  class Parent
+    include ActiveSupport::Configurable
+    config_accessor :foo
+    config_accessor :bar, instance_reader: false, instance_writer: false
+    config_accessor :baz, instance_accessor: false
+  end
+
+  class Child < Parent
+  end
+
+  setup do
+    Parent.config.clear
+    Parent.config.foo = :bar
+
+    Child.config.clear
+  end
+
+  test "adds a configuration hash" do
+    assert_equal({ foo: :bar }, Parent.config)
+  end
+
+  test "adds a configuration hash to a module as well" do
+    mixin = Module.new { include ActiveSupport::Configurable }
+    mixin.config.foo = :bar
+    assert_equal({ foo: :bar }, mixin.config)
+  end
+
+  test "configuration hash is inheritable" do
+    assert_equal :bar, Child.config.foo
+    assert_equal :bar, Parent.config.foo
+
+    Child.config.foo = :baz
+    assert_equal :baz, Child.config.foo
+    assert_equal :bar, Parent.config.foo
+  end
+
+  test "configuration accessors are not available on instance" do
+    instance = Parent.new
+
+    assert !instance.respond_to?(:bar)
+    assert !instance.respond_to?(:bar=)
+
+    assert !instance.respond_to?(:baz)
+    assert !instance.respond_to?(:baz=)
+  end
+
+  test "configuration accessors can take a default value" do
+    parent = Class.new do
+      include ActiveSupport::Configurable
+      config_accessor :hair_colors, :tshirt_colors do
+        [:black, :blue, :white]
+      end
+    end
+
+    assert_equal [:black, :blue, :white], parent.hair_colors
+    assert_equal [:black, :blue, :white], parent.tshirt_colors
+  end
+
+  test "configuration hash is available on instance" do
+    instance = Parent.new
+    assert_equal :bar, instance.config.foo
+    assert_equal :bar, Parent.config.foo
+
+    instance.config.foo = :baz
+    assert_equal :baz, instance.config.foo
+    assert_equal :bar, Parent.config.foo
+  end
+
+  test "configuration is crystalizeable" do
+    parent = Class.new { include ActiveSupport::Configurable }
+    child  = Class.new(parent)
+
+    parent.config.bar = :foo
+    assert_method_not_defined parent.config, :bar
+    assert_method_not_defined child.config, :bar
+    assert_method_not_defined child.new.config, :bar
+
+    parent.config.compile_methods!
+    assert_equal :foo, parent.config.bar
+    assert_equal :foo, child.new.config.bar
+
+    assert_method_defined parent.config, :bar
+    assert_method_defined child.config, :bar
+    assert_method_defined child.new.config, :bar
+  end
+
+  test "should raise name error if attribute name is invalid" do
+    assert_raises NameError do
+      Class.new do
+        include ActiveSupport::Configurable
+        config_accessor "invalid attribute name"
+      end
+    end
+
+    assert_raises NameError do
+      Class.new do
+        include ActiveSupport::Configurable
+        config_accessor "invalid\nattribute"
+      end
+    end
+
+    assert_raises NameError do
+      Class.new do
+        include ActiveSupport::Configurable
+        config_accessor "invalid\n"
+      end
+    end
+  end
+
+  def assert_method_defined(object, method)
+    methods = object.public_methods.map(&:to_s)
+    assert methods.include?(method.to_s), "Expected #{methods.inspect} to include #{method.to_s.inspect}"
+  end
+
+  def assert_method_not_defined(object, method)
+    methods = object.public_methods.map(&:to_s)
+    assert !methods.include?(method.to_s), "Expected #{methods.inspect} to not include #{method.to_s.inspect}"
+  end
+end
diff --git a/app/server/vendor/activesupport/test/constantize_test_cases.rb b/app/server/vendor/activesupport/test/constantize_test_cases.rb
new file mode 100644
index 0000000..bbeb710
--- /dev/null
+++ b/app/server/vendor/activesupport/test/constantize_test_cases.rb
@@ -0,0 +1,75 @@
+module Ace
+  module Base
+    class Case
+      class Dice
+      end
+    end
+    class Fase < Case
+    end
+  end
+  class Gas
+    include Base
+  end
+end
+
+class Object
+  module AddtlGlobalConstants
+    class Case
+      class Dice
+      end
+    end
+  end
+  include AddtlGlobalConstants
+end
+
+module ConstantizeTestCases
+  def run_constantize_tests_on
+    assert_equal Ace::Base::Case, yield("Ace::Base::Case")
+    assert_equal Ace::Base::Case, yield("::Ace::Base::Case")
+    assert_equal Ace::Base::Case::Dice, yield("Ace::Base::Case::Dice")
+    assert_equal Ace::Base::Fase::Dice, yield("Ace::Base::Fase::Dice")
+    assert_equal Ace::Gas::Case, yield("Ace::Gas::Case")
+    assert_equal Ace::Gas::Case::Dice, yield("Ace::Gas::Case::Dice")
+    assert_equal Case::Dice, yield("Case::Dice")
+    assert_equal Case::Dice, yield("Object::Case::Dice")
+    assert_equal ConstantizeTestCases, yield("ConstantizeTestCases")
+    assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases")
+    assert_raises(NameError) { yield("UnknownClass") }
+    assert_raises(NameError) { yield("UnknownClass::Ace") }
+    assert_raises(NameError) { yield("UnknownClass::Ace::Base") }
+    assert_raises(NameError) { yield("An invalid string") }
+    assert_raises(NameError) { yield("InvalidClass\n") }
+    assert_raises(NameError) { yield("Ace::ConstantizeTestCases") }
+    assert_raises(NameError) { yield("Ace::Base::ConstantizeTestCases") }
+    assert_raises(NameError) { yield("Ace::Gas::Base") }
+    assert_raises(NameError) { yield("Ace::Gas::ConstantizeTestCases") }
+    assert_raises(NameError) { yield("") }
+    assert_raises(NameError) { yield("::") }
+  end
+
+  def run_safe_constantize_tests_on
+    assert_equal Ace::Base::Case, yield("Ace::Base::Case")
+    assert_equal Ace::Base::Case, yield("::Ace::Base::Case")
+    assert_equal Ace::Base::Case::Dice, yield("Ace::Base::Case::Dice")
+    assert_equal Ace::Base::Fase::Dice, yield("Ace::Base::Fase::Dice")
+    assert_equal Ace::Gas::Case, yield("Ace::Gas::Case")
+    assert_equal Ace::Gas::Case::Dice, yield("Ace::Gas::Case::Dice")
+    assert_equal Case::Dice, yield("Case::Dice")
+    assert_equal Case::Dice, yield("Object::Case::Dice")
+    assert_equal ConstantizeTestCases, yield("ConstantizeTestCases")
+    assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases")
+    assert_nil yield("")
+    assert_nil yield("::")
+    assert_nil yield("UnknownClass")
+    assert_nil yield("UnknownClass::Ace")
+    assert_nil yield("UnknownClass::Ace::Base")
+    assert_nil yield("An invalid string")
+    assert_nil yield("InvalidClass\n")
+    assert_nil yield("blargle")
+    assert_nil yield("Ace::ConstantizeTestCases")
+    assert_nil yield("Ace::Base::ConstantizeTestCases")
+    assert_nil yield("Ace::Gas::Base")
+    assert_nil yield("Ace::Gas::ConstantizeTestCases")
+    assert_nil yield("#<Class:0x7b8b718b>::Nested_1")
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/array_ext_test.rb b/app/server/vendor/activesupport/test/core_ext/array_ext_test.rb
new file mode 100644
index 0000000..57722fd
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/array_ext_test.rb
@@ -0,0 +1,451 @@
+require 'abstract_unit'
+require 'active_support/core_ext/array'
+require 'active_support/core_ext/big_decimal'
+require 'active_support/core_ext/object/conversions'
+
+require 'active_support/core_ext' # FIXME: pulling in all to_xml extensions
+require 'active_support/hash_with_indifferent_access'
+
+class ArrayExtAccessTests < ActiveSupport::TestCase
+  def test_from
+    assert_equal %w( a b c d ), %w( a b c d ).from(0)
+    assert_equal %w( c d ), %w( a b c d ).from(2)
+    assert_equal %w(), %w( a b c d ).from(10)
+  end
+
+  def test_to
+    assert_equal %w( a ), %w( a b c d ).to(0)
+    assert_equal %w( a b c ), %w( a b c d ).to(2)
+    assert_equal %w( a b c d ), %w( a b c d ).to(10)
+  end
+
+  def test_second_through_tenth
+    array = (1..42).to_a
+
+    assert_equal array[1], array.second
+    assert_equal array[2], array.third
+    assert_equal array[3], array.fourth
+    assert_equal array[4], array.fifth
+    assert_equal array[41], array.forty_two
+  end
+end
+
+class ArrayExtToParamTests < ActiveSupport::TestCase
+  class ToParam < String
+    def to_param
+      "#{self}1"
+    end
+  end
+
+  def test_string_array
+    assert_equal '', %w().to_param
+    assert_equal 'hello/world', %w(hello world).to_param
+    assert_equal 'hello/10', %w(hello 10).to_param
+  end
+
+  def test_number_array
+    assert_equal '10/20', [10, 20].to_param
+  end
+
+  def test_to_param_array
+    assert_equal 'custom1/param1', [ToParam.new('custom'), ToParam.new('param')].to_param
+  end
+end
+
+class ArrayExtToSentenceTests < ActiveSupport::TestCase
+  def test_plain_array_to_sentence
+    assert_equal "", [].to_sentence
+    assert_equal "one", ['one'].to_sentence
+    assert_equal "one and two", ['one', 'two'].to_sentence
+    assert_equal "one, two, and three", ['one', 'two', 'three'].to_sentence
+  end
+
+  def test_to_sentence_with_words_connector
+    assert_equal "one two, and three", ['one', 'two', 'three'].to_sentence(:words_connector => ' ')
+    assert_equal "one & two, and three", ['one', 'two', 'three'].to_sentence(:words_connector => ' & ')
+    assert_equal "onetwo, and three", ['one', 'two', 'three'].to_sentence(:words_connector => nil)
+  end
+
+  def test_to_sentence_with_last_word_connector
+    assert_equal "one, two, and also three", ['one', 'two', 'three'].to_sentence(:last_word_connector => ', and also ')
+    assert_equal "one, twothree", ['one', 'two', 'three'].to_sentence(:last_word_connector => nil)
+    assert_equal "one, two three", ['one', 'two', 'three'].to_sentence(:last_word_connector => ' ')
+    assert_equal "one, two and three", ['one', 'two', 'three'].to_sentence(:last_word_connector => ' and ')
+  end
+
+  def test_two_elements
+    assert_equal "one and two", ['one', 'two'].to_sentence
+    assert_equal "one two", ['one', 'two'].to_sentence(:two_words_connector => ' ')
+  end
+
+  def test_one_element
+    assert_equal "one", ['one'].to_sentence
+  end
+
+  def test_one_element_not_same_object
+    elements = ["one"]
+    assert_not_equal elements[0].object_id, elements.to_sentence.object_id
+  end
+
+  def test_one_non_string_element
+    assert_equal '1', [1].to_sentence
+  end
+
+  def test_does_not_modify_given_hash
+    options = { words_connector: ' ' }
+    assert_equal "one two, and three", ['one', 'two', 'three'].to_sentence(options)
+    assert_equal({ words_connector: ' ' }, options)
+  end
+
+  def test_with_blank_elements
+    assert_equal ", one, , two, and three", [nil, 'one', '', 'two', 'three'].to_sentence
+  end
+end
+
+class ArrayExtToSTests < ActiveSupport::TestCase
+  def test_to_s_db
+    collection = [
+      Class.new { def id() 1 end }.new,
+      Class.new { def id() 2 end }.new,
+      Class.new { def id() 3 end }.new
+    ]
+
+    assert_equal "null", [].to_s(:db)
+    assert_equal "1,2,3", collection.to_s(:db)
+  end
+end
+
+class ArrayExtGroupingTests < ActiveSupport::TestCase
+  def setup
+    Fixnum.send :private, :/  # test we avoid Integer#/ (redefined by mathn)
+  end
+
+  def teardown
+    Fixnum.send :public, :/
+  end
+
+  def test_in_groups_of_with_perfect_fit
+    groups = []
+    ('a'..'i').to_a.in_groups_of(3) do |group|
+      groups << group
+    end
+
+    assert_equal [%w(a b c), %w(d e f), %w(g h i)], groups
+    assert_equal [%w(a b c), %w(d e f), %w(g h i)], ('a'..'i').to_a.in_groups_of(3)
+  end
+
+  def test_in_groups_of_with_padding
+    groups = []
+    ('a'..'g').to_a.in_groups_of(3) do |group|
+      groups << group
+    end
+
+    assert_equal [%w(a b c), %w(d e f), ['g', nil, nil]], groups
+  end
+
+  def test_in_groups_of_pads_with_specified_values
+    groups = []
+
+    ('a'..'g').to_a.in_groups_of(3, 'foo') do |group|
+      groups << group
+    end
+
+    assert_equal [%w(a b c), %w(d e f), ['g', 'foo', 'foo']], groups
+  end
+
+  def test_in_groups_of_without_padding
+    groups = []
+
+    ('a'..'g').to_a.in_groups_of(3, false) do |group|
+      groups << group
+    end
+
+    assert_equal [%w(a b c), %w(d e f), ['g']], groups
+  end
+
+  def test_in_groups_returned_array_size
+    array = (1..7).to_a
+
+    1.upto(array.size + 1) do |number|
+      assert_equal number, array.in_groups(number).size
+    end
+  end
+
+  def test_in_groups_with_empty_array
+    assert_equal [[], [], []], [].in_groups(3)
+  end
+
+  def test_in_groups_with_block
+    array = (1..9).to_a
+    groups = []
+
+    array.in_groups(3) do |group|
+      groups << group
+    end
+
+    assert_equal array.in_groups(3), groups
+  end
+
+  def test_in_groups_with_perfect_fit
+    assert_equal [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
+      (1..9).to_a.in_groups(3)
+  end
+
+  def test_in_groups_with_padding
+    array = (1..7).to_a
+
+    assert_equal [[1, 2, 3], [4, 5, nil], [6, 7, nil]],
+      array.in_groups(3)
+    assert_equal [[1, 2, 3], [4, 5, 'foo'], [6, 7, 'foo']],
+      array.in_groups(3, 'foo')
+  end
+
+  def test_in_groups_without_padding
+    assert_equal [[1, 2, 3], [4, 5], [6, 7]],
+      (1..7).to_a.in_groups(3, false)
+  end
+end
+
+class ArraySplitTests < ActiveSupport::TestCase
+  def test_split_with_empty_array
+    assert_equal [[]], [].split(0)
+  end
+
+  def test_split_with_argument
+    a = [1, 2, 3, 4, 5]
+    assert_equal [[1, 2], [4, 5]],  a.split(3)
+    assert_equal [[1, 2, 3, 4, 5]], a.split(0)
+    assert_equal [1, 2, 3, 4, 5], a
+  end
+
+  def test_split_with_block
+    a = (1..10).to_a
+    assert_equal [[1, 2], [4, 5], [7, 8], [10]], a.split { |i| i % 3 == 0 }
+    assert_equal [1, 2, 3, 4, 5, 6, 7, 8, 9 ,10], a
+  end
+
+  def test_split_with_edge_values
+    a = [1, 2, 3, 4, 5]
+    assert_equal [[], [2, 3, 4, 5]],  a.split(1)
+    assert_equal [[1, 2, 3, 4], []],  a.split(5)
+    assert_equal [[], [2, 3, 4], []], a.split { |i| i == 1 || i == 5 }
+    assert_equal [1, 2, 3, 4, 5], a
+  end
+end
+
+class ArrayToXmlTests < ActiveSupport::TestCase
+  def test_to_xml
+    xml = [
+      { :name => "David", :age => 26, :age_in_millis => 820497600000 },
+      { :name => "Jason", :age => 31, :age_in_millis => BigDecimal.new('1.0') }
+    ].to_xml(:skip_instruct => true, :indent => 0)
+
+    assert_equal '<objects type="array"><object>', xml.first(30)
+    assert xml.include?(%(<age type="integer">26</age>)), xml
+    assert xml.include?(%(<age-in-millis type="integer">820497600000</age-in-millis>)), xml
+    assert xml.include?(%(<name>David</name>)), xml
+    assert xml.include?(%(<age type="integer">31</age>)), xml
+    assert xml.include?(%(<age-in-millis type="decimal">1.0</age-in-millis>)), xml
+    assert xml.include?(%(<name>Jason</name>)), xml
+  end
+
+  def test_to_xml_with_dedicated_name
+    xml = [
+      { :name => "David", :age => 26, :age_in_millis => 820497600000 }, { :name => "Jason", :age => 31 }
+    ].to_xml(:skip_instruct => true, :indent => 0, :root => "people")
+
+    assert_equal '<people type="array"><person>', xml.first(29)
+  end
+
+  def test_to_xml_with_options
+    xml = [
+      { :name => "David", :street_address => "Paulina" }, { :name => "Jason", :street_address => "Evergreen" }
+    ].to_xml(:skip_instruct => true, :skip_types => true, :indent => 0)
+
+    assert_equal "<objects><object>", xml.first(17)
+    assert xml.include?(%(<street-address>Paulina</street-address>))
+    assert xml.include?(%(<name>David</name>))
+    assert xml.include?(%(<street-address>Evergreen</street-address>))
+    assert xml.include?(%(<name>Jason</name>))
+  end
+
+  def test_to_xml_with_dasherize_false
+    xml = [
+      { :name => "David", :street_address => "Paulina" }, { :name => "Jason", :street_address => "Evergreen" }
+    ].to_xml(:skip_instruct => true, :skip_types => true, :indent => 0, :dasherize => false)
+
+    assert_equal "<objects><object>", xml.first(17)
+    assert xml.include?(%(<street_address>Paulina</street_address>))
+    assert xml.include?(%(<street_address>Evergreen</street_address>))
+  end
+
+  def test_to_xml_with_dasherize_true
+    xml = [
+      { :name => "David", :street_address => "Paulina" }, { :name => "Jason", :street_address => "Evergreen" }
+    ].to_xml(:skip_instruct => true, :skip_types => true, :indent => 0, :dasherize => true)
+
+    assert_equal "<objects><object>", xml.first(17)
+    assert xml.include?(%(<street-address>Paulina</street-address>))
+    assert xml.include?(%(<street-address>Evergreen</street-address>))
+  end
+
+  def test_to_with_instruct
+    xml = [
+      { :name => "David", :age => 26, :age_in_millis => 820497600000 },
+      { :name => "Jason", :age => 31, :age_in_millis => BigDecimal.new('1.0') }
+    ].to_xml(:skip_instruct => false, :indent => 0)
+
+    assert_match(/^<\?xml [^>]*/, xml)
+    assert_equal 0, xml.rindex(/<\?xml /)
+  end
+
+  def test_to_xml_with_block
+    xml = [
+      { :name => "David", :age => 26, :age_in_millis => 820497600000 },
+      { :name => "Jason", :age => 31, :age_in_millis => BigDecimal.new('1.0') }
+    ].to_xml(:skip_instruct => true, :indent => 0) do |builder|
+      builder.count 2
+    end
+
+    assert xml.include?(%(<count>2</count>)), xml
+  end
+
+  def test_to_xml_with_empty
+    xml = [].to_xml
+    assert_match(/type="array"\/>/, xml)
+  end
+
+  def test_to_xml_dups_options
+    options = {:skip_instruct => true}
+    [].to_xml(options)
+    # :builder, etc, shouldn't be added to options
+    assert_equal({:skip_instruct => true}, options)
+  end
+end
+
+class ArrayExtractOptionsTests < ActiveSupport::TestCase
+  class HashSubclass < Hash
+  end
+
+  class ExtractableHashSubclass < Hash
+    def extractable_options?
+      true
+    end
+  end
+
+  def test_extract_options
+    assert_equal({}, [].extract_options!)
+    assert_equal({}, [1].extract_options!)
+    assert_equal({:a=>:b}, [{:a=>:b}].extract_options!)
+    assert_equal({:a=>:b}, [1, {:a=>:b}].extract_options!)
+  end
+
+  def test_extract_options_doesnt_extract_hash_subclasses
+    hash = HashSubclass.new
+    hash[:foo] = 1
+    array = [hash]
+    options = array.extract_options!
+    assert_equal({}, options)
+    assert_equal [hash], array
+  end
+
+  def test_extract_options_extracts_extractable_subclass
+    hash = ExtractableHashSubclass.new
+    hash[:foo] = 1
+    array = [hash]
+    options = array.extract_options!
+    assert_equal({:foo => 1}, options)
+    assert_equal [], array
+  end
+
+  def test_extract_options_extracts_hwia
+    hash = [{:foo => 1}.with_indifferent_access]
+    options = hash.extract_options!
+    assert_equal 1, options[:foo]
+  end
+end
+
+class ArrayWrapperTests < ActiveSupport::TestCase
+  class FakeCollection
+    def to_ary
+      ["foo", "bar"]
+    end
+  end
+
+  class Proxy
+    def initialize(target) @target = target end
+    def method_missing(*a) @target.send(*a) end
+  end
+
+  class DoubtfulToAry
+    def to_ary
+      :not_an_array
+    end
+  end
+
+  class NilToAry
+    def to_ary
+      nil
+    end
+  end
+
+  def test_array
+    ary = %w(foo bar)
+    assert_same ary, Array.wrap(ary)
+  end
+
+  def test_nil
+    assert_equal [], Array.wrap(nil)
+  end
+
+  def test_object
+    o = Object.new
+    assert_equal [o], Array.wrap(o)
+  end
+
+  def test_string
+    assert_equal ["foo"], Array.wrap("foo")
+  end
+
+  def test_string_with_newline
+    assert_equal ["foo\nbar"], Array.wrap("foo\nbar")
+  end
+
+  def test_object_with_to_ary
+    assert_equal ["foo", "bar"], Array.wrap(FakeCollection.new)
+  end
+
+  def test_proxy_object
+    p = Proxy.new(Object.new)
+    assert_equal [p], Array.wrap(p)
+  end
+
+  def test_proxy_to_object_with_to_ary
+    p = Proxy.new(FakeCollection.new)
+    assert_equal [p], Array.wrap(p)
+  end
+
+  def test_struct
+    o = Struct.new(:foo).new(123)
+    assert_equal [o], Array.wrap(o)
+  end
+
+  def test_wrap_returns_wrapped_if_to_ary_returns_nil
+    o = NilToAry.new
+    assert_equal [o], Array.wrap(o)
+  end
+
+  def test_wrap_does_not_complain_if_to_ary_does_not_return_an_array
+    assert_equal DoubtfulToAry.new.to_ary, Array.wrap(DoubtfulToAry.new)
+  end
+end
+
+class ArrayPrependAppendTest < ActiveSupport::TestCase
+  def test_append
+    assert_equal [1, 2], [1].append(2)
+  end
+
+  def test_prepend
+    assert_equal [2, 1], [1].prepend(2)
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/big_decimal/yaml_conversions_test.rb b/app/server/vendor/activesupport/test/core_ext/big_decimal/yaml_conversions_test.rb
new file mode 100644
index 0000000..e634679
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/big_decimal/yaml_conversions_test.rb
@@ -0,0 +1,11 @@
+require 'abstract_unit'
+
+class BigDecimalYamlConversionsTest < ActiveSupport::TestCase
+  def test_to_yaml
+    assert_deprecated { require 'active_support/core_ext/big_decimal/yaml_conversions' }
+    assert_match("--- 100000.30020320320000000000000000000000000000001\n", BigDecimal.new('100000.30020320320000000000000000000000000000001').to_yaml)
+    assert_match("--- .Inf\n",  BigDecimal.new('Infinity').to_yaml)
+    assert_match("--- .NaN\n",  BigDecimal.new('NaN').to_yaml)
+    assert_match("--- -.Inf\n", BigDecimal.new('-Infinity').to_yaml)
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/bigdecimal_test.rb b/app/server/vendor/activesupport/test/core_ext/bigdecimal_test.rb
new file mode 100644
index 0000000..423a3f2
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/bigdecimal_test.rb
@@ -0,0 +1,9 @@
+require 'abstract_unit'
+require 'active_support/core_ext/big_decimal'
+
+class BigDecimalTest < ActiveSupport::TestCase
+  def test_to_s
+    bd = BigDecimal.new '0.01'
+    assert_equal '0.01', bd.to_s
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/blank_test.rb b/app/server/vendor/activesupport/test/core_ext/blank_test.rb
new file mode 100644
index 0000000..246bc7f
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/blank_test.rb
@@ -0,0 +1,36 @@
+# encoding: utf-8
+
+require 'abstract_unit'
+require 'active_support/core_ext/object/blank'
+
+class BlankTest < ActiveSupport::TestCase
+  class EmptyTrue
+    def empty?
+      0
+    end
+  end
+
+  class EmptyFalse
+    def empty?
+      nil
+    end
+  end
+
+  BLANK = [ EmptyTrue.new, nil, false, '', '   ', "  \n\t  \r ", ' ', "\u00a0", [], {} ]
+  NOT   = [ EmptyFalse.new, Object.new, true, 0, 1, 'a', [nil], { nil => 0 } ]
+
+  def test_blank
+    BLANK.each { |v| assert_equal true, v.blank?,  "#{v.inspect} should be blank" }
+    NOT.each   { |v| assert_equal false, v.blank?, "#{v.inspect} should not be blank" }
+  end
+
+  def test_present
+    BLANK.each { |v| assert_equal false, v.present?, "#{v.inspect} should not be present" }
+    NOT.each   { |v| assert_equal true, v.present?,  "#{v.inspect} should be present" }
+  end
+
+  def test_presence
+    BLANK.each { |v| assert_equal nil, v.presence, "#{v.inspect}.presence should return nil" }
+    NOT.each   { |v| assert_equal v,   v.presence, "#{v.inspect}.presence should return self" }
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/class/attribute_test.rb b/app/server/vendor/activesupport/test/core_ext/class/attribute_test.rb
new file mode 100644
index 0000000..e7a1334
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/class/attribute_test.rb
@@ -0,0 +1,91 @@
+require 'abstract_unit'
+require 'active_support/core_ext/class/attribute'
+
+class ClassAttributeTest < ActiveSupport::TestCase
+  def setup
+    @klass = Class.new { class_attribute :setting }
+    @sub = Class.new(@klass)
+  end
+
+  test 'defaults to nil' do
+    assert_nil @klass.setting
+    assert_nil @sub.setting
+  end
+
+  test 'inheritable' do
+    @klass.setting = 1
+    assert_equal 1, @sub.setting
+  end
+
+  test 'overridable' do
+    @sub.setting = 1
+    assert_nil @klass.setting
+
+    @klass.setting = 2
+    assert_equal 1, @sub.setting
+
+    assert_equal 1, Class.new(@sub).setting
+  end
+
+  test 'predicate method' do
+    assert_equal false, @klass.setting?
+    @klass.setting = 1
+    assert_equal true, @klass.setting?
+  end
+
+  test 'instance reader delegates to class' do
+    assert_nil @klass.new.setting
+
+    @klass.setting = 1
+    assert_equal 1, @klass.new.setting
+  end
+
+  test 'instance override' do
+    object = @klass.new
+    object.setting = 1
+    assert_nil @klass.setting
+    @klass.setting = 2
+    assert_equal 1, object.setting
+  end
+
+  test 'instance predicate' do
+    object = @klass.new
+    assert_equal false, object.setting?
+    object.setting = 1
+    assert_equal true, object.setting?
+  end
+
+  test 'disabling instance writer' do
+    object = Class.new { class_attribute :setting, :instance_writer => false }.new
+    assert_raise(NoMethodError) { object.setting = 'boom' }
+  end
+
+  test 'disabling instance reader' do
+    object = Class.new { class_attribute :setting, :instance_reader => false }.new
+    assert_raise(NoMethodError) { object.setting }
+    assert_raise(NoMethodError) { object.setting? }
+  end
+
+  test 'disabling both instance writer and reader' do
+    object = Class.new { class_attribute :setting, :instance_accessor => false }.new
+    assert_raise(NoMethodError) { object.setting }
+    assert_raise(NoMethodError) { object.setting? }
+    assert_raise(NoMethodError) { object.setting = 'boom' }
+  end
+
+  test 'disabling instance predicate' do
+    object = Class.new { class_attribute :setting, instance_predicate: false }.new
+    assert_raise(NoMethodError) { object.setting? }
+  end
+
+  test 'works well with singleton classes' do
+    object = @klass.new
+    object.singleton_class.setting = 'foo'
+    assert_equal 'foo', object.setting
+  end
+
+  test 'setter returns set value' do
+    val = @klass.send(:setting=, 1)
+    assert_equal 1, val
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/class/delegating_attributes_test.rb b/app/server/vendor/activesupport/test/core_ext/class/delegating_attributes_test.rb
new file mode 100644
index 0000000..447b1d1
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/class/delegating_attributes_test.rb
@@ -0,0 +1,122 @@
+require 'abstract_unit'
+require 'active_support/core_ext/class/delegating_attributes'
+
+module DelegatingFixtures
+  class Parent
+  end
+
+  class Child < Parent
+    ActiveSupport::Deprecation.silence do
+      superclass_delegating_accessor :some_attribute
+    end
+  end
+
+  class Mokopuna < Child
+  end
+
+  class PercysMom
+    ActiveSupport::Deprecation.silence do
+      superclass_delegating_accessor :superpower
+    end
+  end
+
+  class Percy < PercysMom
+  end
+end
+
+class DelegatingAttributesTest < ActiveSupport::TestCase
+  include DelegatingFixtures
+  attr_reader :single_class
+
+  def setup
+    @single_class = Class.new(Object)
+  end
+
+  def test_simple_accessor_declaration
+    assert_deprecated do
+      single_class.superclass_delegating_accessor :both
+    end
+
+    # Class should have accessor and mutator
+    # the instance should have an accessor only
+    assert_respond_to single_class, :both
+    assert_respond_to single_class, :both=
+    assert single_class.public_instance_methods.map(&:to_s).include?("both")
+    assert !single_class.public_instance_methods.map(&:to_s).include?("both=")
+  end
+
+  def test_simple_accessor_declaration_with_instance_reader_false
+    _instance_methods = single_class.public_instance_methods
+
+    assert_deprecated do
+      single_class.superclass_delegating_accessor :no_instance_reader, :instance_reader => false
+    end
+
+    assert_respond_to single_class, :no_instance_reader
+    assert_respond_to single_class, :no_instance_reader=
+    assert !_instance_methods.include?(:no_instance_reader)
+    assert !_instance_methods.include?(:no_instance_reader?)
+    assert !_instance_methods.include?(:_no_instance_reader)
+  end
+
+  def test_working_with_simple_attributes
+    assert_deprecated do
+      single_class.superclass_delegating_accessor :both
+    end
+
+    single_class.both = "HMMM"
+
+    assert_equal "HMMM", single_class.both
+    assert_equal true, single_class.both?
+
+    assert_equal "HMMM", single_class.new.both
+    assert_equal true, single_class.new.both?
+
+    single_class.both = false
+    assert_equal false, single_class.both?
+  end
+
+  def test_child_class_delegates_to_parent_but_can_be_overridden
+    parent = Class.new
+
+    assert_deprecated do
+      parent.superclass_delegating_accessor :both
+    end
+
+    child = Class.new(parent)
+    parent.both = "1"
+    assert_equal "1", child.both
+
+    child.both = "2"
+    assert_equal "1", parent.both
+    assert_equal "2", child.both
+
+    parent.both = "3"
+    assert_equal "3", parent.both
+    assert_equal "2", child.both
+  end
+
+  def test_delegation_stops_at_the_right_level
+    assert_nil Percy.superpower
+    assert_nil PercysMom.superpower
+
+    PercysMom.superpower = :heatvision
+    assert_equal :heatvision, Percy.superpower
+  end
+
+  def test_delegation_stops_for_nil
+    Mokopuna.some_attribute = nil
+    Child.some_attribute="1"
+
+    assert_equal "1", Child.some_attribute
+    assert_nil Mokopuna.some_attribute
+  ensure
+    Child.some_attribute=nil
+  end
+
+  def test_deprecation_warning
+    assert_deprecated(/superclass_delegating_accessor is deprecated/) do
+      single_class.superclass_delegating_accessor :test_attribute
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/class_test.rb b/app/server/vendor/activesupport/test/core_ext/class_test.rb
new file mode 100644
index 0000000..9c6c579
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/class_test.rb
@@ -0,0 +1,28 @@
+require 'abstract_unit'
+require 'active_support/core_ext/class'
+require 'set'
+
+class ClassTest < ActiveSupport::TestCase
+  class Parent; end
+  class Foo < Parent; end
+  class Bar < Foo; end
+  class Baz < Bar; end
+
+  class A < Parent; end
+  class B < A; end
+  class C < B; end
+
+  def test_descendants
+    assert_equal [Foo, Bar, Baz, A, B, C].to_set, Parent.descendants.to_set
+    assert_equal [Bar, Baz].to_set, Foo.descendants.to_set
+    assert_equal [Baz], Bar.descendants
+    assert_equal [], Baz.descendants
+  end
+
+  def test_subclasses
+    assert_equal [Foo, A].to_set, Parent.subclasses.to_set
+    assert_equal [Bar], Foo.subclasses
+    assert_equal [Baz], Bar.subclasses
+    assert_equal [], Baz.subclasses
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/date_and_time_behavior.rb b/app/server/vendor/activesupport/test/core_ext/date_and_time_behavior.rb
new file mode 100644
index 0000000..b4ef5a0
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/date_and_time_behavior.rb
@@ -0,0 +1,241 @@
+require 'abstract_unit'
+
+module DateAndTimeBehavior
+  def test_yesterday
+    assert_equal date_time_init(2005,2,21,10,10,10), date_time_init(2005,2,22,10,10,10).yesterday
+    assert_equal date_time_init(2005,2,28,10,10,10), date_time_init(2005,3,2,10,10,10).yesterday.yesterday
+  end
+
+  def test_tomorrow
+    assert_equal date_time_init(2005,2,23,10,10,10), date_time_init(2005,2,22,10,10,10).tomorrow
+    assert_equal date_time_init(2005,3,2,10,10,10),  date_time_init(2005,2,28,10,10,10).tomorrow.tomorrow
+  end
+
+  def test_days_ago
+    assert_equal date_time_init(2005,6,4,10,10,10),  date_time_init(2005,6,5,10,10,10).days_ago(1)
+    assert_equal date_time_init(2005,5,31,10,10,10),   date_time_init(2005,6,5,10,10,10).days_ago(5)
+  end
+
+  def test_days_since
+    assert_equal date_time_init(2005,6,6,10,10,10),  date_time_init(2005,6,5,10,10,10).days_since(1)
+    assert_equal date_time_init(2005,1,1,10,10,10), date_time_init(2004,12,31,10,10,10).days_since(1)
+  end
+
+  def test_weeks_ago
+    assert_equal date_time_init(2005,5,29,10,10,10),  date_time_init(2005,6,5,10,10,10).weeks_ago(1)
+    assert_equal date_time_init(2005,5,1,10,10,10),   date_time_init(2005,6,5,10,10,10).weeks_ago(5)
+    assert_equal date_time_init(2005,4,24,10,10,10),  date_time_init(2005,6,5,10,10,10).weeks_ago(6)
+    assert_equal date_time_init(2005,2,27,10,10,10),  date_time_init(2005,6,5,10,10,10).weeks_ago(14)
+    assert_equal date_time_init(2004,12,25,10,10,10), date_time_init(2005,1,1,10,10,10).weeks_ago(1)
+  end
+
+  def test_weeks_since
+    assert_equal date_time_init(2005,7,14,10,10,10), date_time_init(2005,7,7,10,10,10).weeks_since(1)
+    assert_equal date_time_init(2005,7,14,10,10,10), date_time_init(2005,7,7,10,10,10).weeks_since(1)
+    assert_equal date_time_init(2005,7,4,10,10,10),  date_time_init(2005,6,27,10,10,10).weeks_since(1)
+    assert_equal date_time_init(2005,1,4,10,10,10),  date_time_init(2004,12,28,10,10,10).weeks_since(1)
+  end
+
+  def test_months_ago
+    assert_equal date_time_init(2005,5,5,10,10,10),  date_time_init(2005,6,5,10,10,10).months_ago(1)
+    assert_equal date_time_init(2004,11,5,10,10,10), date_time_init(2005,6,5,10,10,10).months_ago(7)
+    assert_equal date_time_init(2004,12,5,10,10,10), date_time_init(2005,6,5,10,10,10).months_ago(6)
+    assert_equal date_time_init(2004,6,5,10,10,10),  date_time_init(2005,6,5,10,10,10).months_ago(12)
+    assert_equal date_time_init(2003,6,5,10,10,10),  date_time_init(2005,6,5,10,10,10).months_ago(24)
+  end
+
+  def test_months_since
+    assert_equal date_time_init(2005,7,5,10,10,10),   date_time_init(2005,6,5,10,10,10).months_since(1)
+    assert_equal date_time_init(2006,1,5,10,10,10),   date_time_init(2005,12,5,10,10,10).months_since(1)
+    assert_equal date_time_init(2005,12,5,10,10,10),  date_time_init(2005,6,5,10,10,10).months_since(6)
+    assert_equal date_time_init(2006,6,5,10,10,10),   date_time_init(2005,12,5,10,10,10).months_since(6)
+    assert_equal date_time_init(2006,1,5,10,10,10),   date_time_init(2005,6,5,10,10,10).months_since(7)
+    assert_equal date_time_init(2006,6,5,10,10,10),   date_time_init(2005,6,5,10,10,10).months_since(12)
+    assert_equal date_time_init(2007,6,5,10,10,10),   date_time_init(2005,6,5,10,10,10).months_since(24)
+    assert_equal date_time_init(2005,4,30,10,10,10),  date_time_init(2005,3,31,10,10,10).months_since(1)
+    assert_equal date_time_init(2005,2,28,10,10,10),  date_time_init(2005,1,29,10,10,10).months_since(1)
+    assert_equal date_time_init(2005,2,28,10,10,10),  date_time_init(2005,1,30,10,10,10).months_since(1)
+    assert_equal date_time_init(2005,2,28,10,10,10),  date_time_init(2005,1,31,10,10,10).months_since(1)
+  end
+
+  def test_years_ago
+    assert_equal date_time_init(2004,6,5,10,10,10),  date_time_init(2005,6,5,10,10,10).years_ago(1)
+    assert_equal date_time_init(1998,6,5,10,10,10),  date_time_init(2005,6,5,10,10,10).years_ago(7)
+    assert_equal date_time_init(2003,2,28,10,10,10), date_time_init(2004,2,29,10,10,10).years_ago(1) # 1 year ago from leap day
+  end
+
+  def test_years_since
+    assert_equal date_time_init(2006,6,5,10,10,10),  date_time_init(2005,6,5,10,10,10).years_since(1)
+    assert_equal date_time_init(2012,6,5,10,10,10),  date_time_init(2005,6,5,10,10,10).years_since(7)
+    assert_equal date_time_init(2005,2,28,10,10,10), date_time_init(2004,2,29,10,10,10).years_since(1) # 1 year since leap day
+    assert_equal date_time_init(2182,6,5,10,10,10),  date_time_init(2005,6,5,10,10,10).years_since(177)
+  end
+
+  def test_beginning_of_month
+    assert_equal date_time_init(2005,2,1,0,0,0), date_time_init(2005,2,22,10,10,10).beginning_of_month
+  end
+
+  def test_beginning_of_quarter
+    assert_equal date_time_init(2005,1,1,0,0,0),  date_time_init(2005,2,15,10,10,10).beginning_of_quarter
+    assert_equal date_time_init(2005,1,1,0,0,0),  date_time_init(2005,1,1,0,0,0).beginning_of_quarter
+    assert_equal date_time_init(2005,10,1,0,0,0), date_time_init(2005,12,31,10,10,10).beginning_of_quarter
+    assert_equal date_time_init(2005,4,1,0,0,0),  date_time_init(2005,6,30,23,59,59).beginning_of_quarter
+  end
+
+  def test_end_of_quarter
+    assert_equal date_time_init(2007,3,31,23,59,59,Rational(999999999, 1000)), date_time_init(2007,2,15,10,10,10).end_of_quarter
+    assert_equal date_time_init(2007,3,31,23,59,59,Rational(999999999, 1000)), date_time_init(2007,3,31,0,0,0).end_of_quarter
+    assert_equal date_time_init(2007,12,31,23,59,59,Rational(999999999, 1000)), date_time_init(2007,12,21,10,10,10).end_of_quarter
+    assert_equal date_time_init(2007,6,30,23,59,59,Rational(999999999, 1000)), date_time_init(2007,4,1,0,0,0).end_of_quarter
+    assert_equal date_time_init(2008,6,30,23,59,59,Rational(999999999, 1000)), date_time_init(2008,5,31,0,0,0).end_of_quarter
+  end
+
+  def test_beginning_of_year
+    assert_equal date_time_init(2005,1,1,0,0,0), date_time_init(2005,2,22,10,10,10).beginning_of_year
+  end
+
+  def test_next_week
+    #   M   |   T  | W | T | F | S | S #   M   | T |   W   | T |  F  | S | S #
+    #       | 22/2 |   |   |   |   |   # 28/2  |   |       |   |     |   |   # monday in next week `next_week`
+    #       | 22/2 |   |   |   |   |   #       |   |       |   | 4/3 |   |   # friday in next week `next_week(:friday)`
+    # 23/10 |      |   |   |   |   |   # 30/10 |   |       |   |     |   |   # monday in next week `next_week`
+    # 23/10 |      |   |   |   |   |   #       |   |  1/11 |   |     |   |   # wednesday in next week `next_week(:wednesday)`
+    assert_equal date_time_init(2005,2,28,0,0,0),  date_time_init(2005,2,22,15,15,10).next_week
+    assert_equal date_time_init(2005,3,4,0,0,0),   date_time_init(2005,2,22,15,15,10).next_week(:friday)
+    assert_equal date_time_init(2006,10,30,0,0,0), date_time_init(2006,10,23,0,0,0).next_week
+    assert_equal date_time_init(2006,11,1,0,0,0),  date_time_init(2006,10,23,0,0,0).next_week(:wednesday)
+  end
+
+  def test_next_week_with_default_beginning_of_week_set
+    with_bw_default(:tuesday) do
+      assert_equal Time.local(2012, 3, 28), Time.local(2012, 3, 21).next_week(:wednesday)
+      assert_equal Time.local(2012, 3, 31), Time.local(2012, 3, 21).next_week(:saturday)
+      assert_equal Time.local(2012, 3, 27), Time.local(2012, 3, 21).next_week(:tuesday)
+      assert_equal Time.local(2012, 4, 02), Time.local(2012, 3, 21).next_week(:monday)
+    end
+  end
+
+  def test_next_month_on_31st
+    assert_equal date_time_init(2005,9,30,15,15,10), date_time_init(2005,8,31,15,15,10).next_month
+  end
+
+  def test_next_quarter_on_31st
+    assert_equal date_time_init(2005,11,30,15,15,10), date_time_init(2005,8,31,15,15,10).next_quarter
+  end
+
+  def test_next_year
+    assert_equal date_time_init(2006,6,5,10,10,10), date_time_init(2005,6,5,10,10,10).next_year
+  end
+
+  def test_prev_week
+    assert_equal date_time_init(2005,2,21,0,0,0),  date_time_init(2005,3,1,15,15,10).prev_week
+    assert_equal date_time_init(2005,2,22,0,0,0),  date_time_init(2005,3,1,15,15,10).prev_week(:tuesday)
+    assert_equal date_time_init(2005,2,25,0,0,0),  date_time_init(2005,3,1,15,15,10).prev_week(:friday)
+    assert_equal date_time_init(2006,10,30,0,0,0), date_time_init(2006,11,6,0,0,0).prev_week
+    assert_equal date_time_init(2006,11,15,0,0,0), date_time_init(2006,11,23,0,0,0).prev_week(:wednesday)
+  end
+
+  def test_prev_week_with_default_beginning_of_week
+    with_bw_default(:tuesday) do
+      assert_equal Time.local(2012, 3, 14), Time.local(2012, 3, 21).prev_week(:wednesday)
+      assert_equal Time.local(2012, 3, 17), Time.local(2012, 3, 21).prev_week(:saturday)
+      assert_equal Time.local(2012, 3, 13), Time.local(2012, 3, 21).prev_week(:tuesday)
+      assert_equal Time.local(2012, 3, 19), Time.local(2012, 3, 21).prev_week(:monday)
+    end
+  end
+
+  def test_prev_month_on_31st
+    assert_equal date_time_init(2004,2,29,10,10,10), date_time_init(2004,3,31,10,10,10).prev_month
+  end
+
+  def test_prev_quarter_on_31st
+    assert_equal date_time_init(2004,2,29,10,10,10), date_time_init(2004,5,31,10,10,10).prev_quarter
+  end
+
+  def test_prev_year
+    assert_equal date_time_init(2004,6,5,10,10,10),  date_time_init(2005,6,5,10,10,10).prev_year
+  end
+
+  def test_days_to_week_start
+    assert_equal 0, date_time_init(2011,11,01,0,0,0).days_to_week_start(:tuesday)
+    assert_equal 1, date_time_init(2011,11,02,0,0,0).days_to_week_start(:tuesday)
+    assert_equal 2, date_time_init(2011,11,03,0,0,0).days_to_week_start(:tuesday)
+    assert_equal 3, date_time_init(2011,11,04,0,0,0).days_to_week_start(:tuesday)
+    assert_equal 4, date_time_init(2011,11,05,0,0,0).days_to_week_start(:tuesday)
+    assert_equal 5, date_time_init(2011,11,06,0,0,0).days_to_week_start(:tuesday)
+    assert_equal 6, date_time_init(2011,11,07,0,0,0).days_to_week_start(:tuesday)
+
+    assert_equal 3, date_time_init(2011,11,03,0,0,0).days_to_week_start(:monday)
+    assert_equal 3, date_time_init(2011,11,04,0,0,0).days_to_week_start(:tuesday)
+    assert_equal 3, date_time_init(2011,11,05,0,0,0).days_to_week_start(:wednesday)
+    assert_equal 3, date_time_init(2011,11,06,0,0,0).days_to_week_start(:thursday)
+    assert_equal 3, date_time_init(2011,11,07,0,0,0).days_to_week_start(:friday)
+    assert_equal 3, date_time_init(2011,11,8,0,0,0).days_to_week_start(:saturday)
+    assert_equal 3, date_time_init(2011,11,9,0,0,0).days_to_week_start(:sunday)
+  end
+
+  def test_days_to_week_start_with_default_set
+    with_bw_default(:friday) do
+      assert_equal 6, Time.local(2012,03,8,0,0,0).days_to_week_start
+      assert_equal 5, Time.local(2012,03,7,0,0,0).days_to_week_start
+      assert_equal 4, Time.local(2012,03,6,0,0,0).days_to_week_start
+      assert_equal 3, Time.local(2012,03,5,0,0,0).days_to_week_start
+      assert_equal 2, Time.local(2012,03,4,0,0,0).days_to_week_start
+      assert_equal 1, Time.local(2012,03,3,0,0,0).days_to_week_start
+      assert_equal 0, Time.local(2012,03,2,0,0,0).days_to_week_start
+    end
+  end
+
+  def test_beginning_of_week
+    assert_equal date_time_init(2005,1,31,0,0,0),  date_time_init(2005,2,4,10,10,10).beginning_of_week
+    assert_equal date_time_init(2005,11,28,0,0,0), date_time_init(2005,11,28,0,0,0).beginning_of_week #monday
+    assert_equal date_time_init(2005,11,28,0,0,0), date_time_init(2005,11,29,0,0,0).beginning_of_week #tuesday
+    assert_equal date_time_init(2005,11,28,0,0,0), date_time_init(2005,11,30,0,0,0).beginning_of_week #wednesday
+    assert_equal date_time_init(2005,11,28,0,0,0), date_time_init(2005,12,01,0,0,0).beginning_of_week #thursday
+    assert_equal date_time_init(2005,11,28,0,0,0), date_time_init(2005,12,02,0,0,0).beginning_of_week #friday
+    assert_equal date_time_init(2005,11,28,0,0,0), date_time_init(2005,12,03,0,0,0).beginning_of_week #saturday
+    assert_equal date_time_init(2005,11,28,0,0,0), date_time_init(2005,12,04,0,0,0).beginning_of_week #sunday
+  end
+
+  def test_end_of_week
+    assert_equal date_time_init(2008,1,6,23,59,59,Rational(999999999, 1000)), date_time_init(2007,12,31,10,10,10).end_of_week
+    assert_equal date_time_init(2007,9,2,23,59,59,Rational(999999999, 1000)), date_time_init(2007,8,27,0,0,0).end_of_week #monday
+    assert_equal date_time_init(2007,9,2,23,59,59,Rational(999999999, 1000)), date_time_init(2007,8,28,0,0,0).end_of_week #tuesday
+    assert_equal date_time_init(2007,9,2,23,59,59,Rational(999999999, 1000)), date_time_init(2007,8,29,0,0,0).end_of_week #wednesday
+    assert_equal date_time_init(2007,9,2,23,59,59,Rational(999999999, 1000)), date_time_init(2007,8,30,0,0,0).end_of_week #thursday
+    assert_equal date_time_init(2007,9,2,23,59,59,Rational(999999999, 1000)), date_time_init(2007,8,31,0,0,0).end_of_week #friday
+    assert_equal date_time_init(2007,9,2,23,59,59,Rational(999999999, 1000)), date_time_init(2007,9,01,0,0,0).end_of_week #saturday
+    assert_equal date_time_init(2007,9,2,23,59,59,Rational(999999999, 1000)), date_time_init(2007,9,02,0,0,0).end_of_week #sunday
+  end
+
+  def test_end_of_month
+    assert_equal date_time_init(2005,3,31,23,59,59,Rational(999999999, 1000)), date_time_init(2005,3,20,10,10,10).end_of_month
+    assert_equal date_time_init(2005,2,28,23,59,59,Rational(999999999, 1000)), date_time_init(2005,2,20,10,10,10).end_of_month
+    assert_equal date_time_init(2005,4,30,23,59,59,Rational(999999999, 1000)), date_time_init(2005,4,20,10,10,10).end_of_month
+  end
+
+  def test_end_of_year
+    assert_equal date_time_init(2007,12,31,23,59,59,Rational(999999999, 1000)), date_time_init(2007,2,22,10,10,10).end_of_year
+    assert_equal date_time_init(2007,12,31,23,59,59,Rational(999999999, 1000)), date_time_init(2007,12,31,10,10,10).end_of_year
+  end
+
+  def test_monday_with_default_beginning_of_week_set
+    with_bw_default(:saturday) do
+      assert_equal date_time_init(2012,9,17,0,0,0), date_time_init(2012,9,18,0,0,0).monday
+    end
+  end
+
+  def test_sunday_with_default_beginning_of_week_set
+    with_bw_default(:wednesday) do
+      assert_equal date_time_init(2012,9,23,23,59,59, Rational(999999999, 1000)), date_time_init(2012,9,19,0,0,0).sunday
+    end
+  end
+
+  def with_bw_default(bw = :monday)
+    old_bw = Date.beginning_of_week
+    Date.beginning_of_week = bw
+    yield
+  ensure
+    Date.beginning_of_week = old_bw
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/date_ext_test.rb b/app/server/vendor/activesupport/test/core_ext/date_ext_test.rb
new file mode 100644
index 0000000..5d0af03
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/date_ext_test.rb
@@ -0,0 +1,387 @@
+require 'abstract_unit'
+require 'active_support/time'
+require 'core_ext/date_and_time_behavior'
+
+class DateExtCalculationsTest < ActiveSupport::TestCase
+  def date_time_init(year,month,day,*args)
+    Date.new(year,month,day)
+  end
+
+  include DateAndTimeBehavior
+
+  def test_yesterday_in_calendar_reform
+    assert_equal Date.new(1582,10,4), Date.new(1582,10,15).yesterday
+  end
+
+  def test_tomorrow_in_calendar_reform
+    assert_equal Date.new(1582,10,15), Date.new(1582,10,4).tomorrow
+  end
+
+  def test_to_s
+    date = Date.new(2005, 2, 21)
+    assert_equal "2005-02-21",          date.to_s
+    assert_equal "21 Feb",              date.to_s(:short)
+    assert_equal "February 21, 2005",   date.to_s(:long)
+    assert_equal "February 21st, 2005", date.to_s(:long_ordinal)
+    assert_equal "2005-02-21",          date.to_s(:db)
+    assert_equal "21 Feb 2005",         date.to_s(:rfc822)
+    assert_equal "2005-02-21",          date.to_s(:iso8601)
+  end
+
+  def test_readable_inspect
+    assert_equal "Mon, 21 Feb 2005", Date.new(2005, 2, 21).readable_inspect
+    assert_equal Date.new(2005, 2, 21).readable_inspect, Date.new(2005, 2, 21).inspect
+  end
+
+  def test_to_time
+    with_env_tz 'US/Eastern' do
+      assert_equal Time, Date.new(2005, 2, 21).to_time.class
+      assert_equal Time.local(2005, 2, 21), Date.new(2005, 2, 21).to_time
+      assert_equal Time.local(2005, 2, 21).utc_offset, Date.new(2005, 2, 21).to_time.utc_offset
+    end
+
+    silence_warnings do
+      0.upto(138) do |year|
+        [:utc, :local].each do |format|
+          assert_equal year, Date.new(year).to_time(format).year
+        end
+      end
+    end
+  end
+
+  def test_compare_to_time
+    assert Date.yesterday < Time.now
+  end
+
+  def test_to_datetime
+    assert_equal DateTime.civil(2005, 2, 21), Date.new(2005, 2, 21).to_datetime
+    assert_equal 0, Date.new(2005, 2, 21).to_datetime.offset # use UTC offset
+    assert_equal ::Date::ITALY, Date.new(2005, 2, 21).to_datetime.start # use Ruby's default start value
+  end
+
+  def test_to_date
+    assert_equal Date.new(2005, 2, 21), Date.new(2005, 2, 21).to_date
+  end
+
+  def test_change
+    assert_equal Date.new(2005, 2, 21), Date.new(2005, 2, 11).change(:day => 21)
+    assert_equal Date.new(2007, 5, 11), Date.new(2005, 2, 11).change(:year => 2007, :month => 5)
+    assert_equal Date.new(2006,2,22), Date.new(2005,2,22).change(:year => 2006)
+    assert_equal Date.new(2005,6,22), Date.new(2005,2,22).change(:month => 6)
+  end
+
+  def test_sunday
+    assert_equal Date.new(2008,3,2), Date.new(2008,3,02).sunday
+    assert_equal Date.new(2008,3,2), Date.new(2008,2,29).sunday
+  end
+
+  def test_beginning_of_week_in_calendar_reform
+    assert_equal Date.new(1582,10,1), Date.new(1582,10,15).beginning_of_week #friday
+  end
+
+  def test_end_of_week_in_calendar_reform
+    assert_equal Date.new(1582,10,17), Date.new(1582,10,4).end_of_week #thursday
+  end
+
+  def test_end_of_year
+    assert_equal Date.new(2008,12,31).to_s, Date.new(2008,2,22).end_of_year.to_s
+  end
+
+  def test_end_of_month
+    assert_equal Date.new(2005,3,31), Date.new(2005,3,20).end_of_month
+    assert_equal Date.new(2005,2,28), Date.new(2005,2,20).end_of_month
+    assert_equal Date.new(2005,4,30), Date.new(2005,4,20).end_of_month
+  end
+
+  def test_prev_year_in_leap_years
+    assert_equal Date.new(1999,2,28), Date.new(2000,2,29).prev_year
+  end
+
+  def test_prev_year_in_calendar_reform
+    assert_equal Date.new(1582,10,4), Date.new(1583,10,14).prev_year
+  end
+
+  def test_last_year
+    assert_equal Date.new(2004,6,5),  Date.new(2005,6,5).last_year
+  end
+
+  def test_last_year_in_leap_years
+    assert_equal Date.new(1999,2,28), Date.new(2000,2,29).last_year
+  end
+
+  def test_last_year_in_calendar_reform
+    assert_equal Date.new(1582,10,4), Date.new(1583,10,14).last_year
+  end
+
+  def test_next_year_in_leap_years
+    assert_equal Date.new(2001,2,28), Date.new(2000,2,29).next_year
+  end
+
+  def test_next_year_in_calendar_reform
+    assert_equal Date.new(1582,10,4), Date.new(1581,10,10).next_year
+  end
+
+  def test_advance
+    assert_equal Date.new(2006,2,28), Date.new(2005,2,28).advance(:years => 1)
+    assert_equal Date.new(2005,6,28), Date.new(2005,2,28).advance(:months => 4)
+    assert_equal Date.new(2005,3,21), Date.new(2005,2,28).advance(:weeks => 3)
+    assert_equal Date.new(2005,3,5), Date.new(2005,2,28).advance(:days => 5)
+    assert_equal Date.new(2012,9,28), Date.new(2005,2,28).advance(:years => 7, :months => 7)
+    assert_equal Date.new(2013,10,3), Date.new(2005,2,28).advance(:years => 7, :months => 19, :days => 5)
+    assert_equal Date.new(2013,10,17), Date.new(2005,2,28).advance(:years => 7, :months => 19, :weeks => 2, :days => 5)
+    assert_equal Date.new(2005,2,28), Date.new(2004,2,29).advance(:years => 1) #leap day plus one year
+  end
+
+  def test_advance_does_first_years_and_then_days
+    assert_equal Date.new(2012, 2, 29), Date.new(2011, 2, 28).advance(:years => 1, :days => 1)
+    # If day was done first we would jump to 2012-03-01 instead.
+  end
+
+  def test_advance_does_first_months_and_then_days
+    assert_equal Date.new(2010, 3, 29), Date.new(2010, 2, 28).advance(:months => 1, :days => 1)
+    # If day was done first we would jump to 2010-04-01 instead.
+  end
+
+  def test_advance_in_calendar_reform
+    assert_equal Date.new(1582,10,15), Date.new(1582,10,4).advance(:days => 1)
+    assert_equal Date.new(1582,10,4), Date.new(1582,10,15).advance(:days => -1)
+    5.upto(14) do |day|
+      assert_equal Date.new(1582,10,4), Date.new(1582,9,day).advance(:months => 1)
+      assert_equal Date.new(1582,10,4), Date.new(1582,11,day).advance(:months => -1)
+      assert_equal Date.new(1582,10,4), Date.new(1581,10,day).advance(:years => 1)
+      assert_equal Date.new(1582,10,4), Date.new(1583,10,day).advance(:years => -1)
+    end
+  end
+
+  def test_last_week
+    assert_equal Date.new(2005,5,9), Date.new(2005,5,17).last_week
+    assert_equal Date.new(2006,12,25), Date.new(2007,1,7).last_week
+    assert_equal Date.new(2010,2,12), Date.new(2010,2,19).last_week(:friday)
+    assert_equal Date.new(2010,2,13), Date.new(2010,2,19).last_week(:saturday)
+    assert_equal Date.new(2010,2,27), Date.new(2010,3,4).last_week(:saturday)
+  end
+
+  def test_next_week_in_calendar_reform
+    assert_equal Date.new(1582,10,15), Date.new(1582,9,30).next_week(:friday)
+    assert_equal Date.new(1582,10,18), Date.new(1582,10,4).next_week
+  end
+
+  def test_last_month_on_31st
+    assert_equal Date.new(2004, 2, 29), Date.new(2004, 3, 31).last_month
+  end
+
+  def test_last_quarter_on_31st
+    assert_equal Date.new(2004, 2, 29), Date.new(2004, 5, 31).last_quarter
+  end
+
+  def test_yesterday_constructor
+    assert_equal Date.current - 1, Date.yesterday
+  end
+
+  def test_yesterday_constructor_when_zone_is_not_set
+    with_env_tz 'UTC' do
+      with_tz_default do
+        assert_equal(Date.today - 1, Date.yesterday)
+      end
+    end
+  end
+
+  def test_yesterday_constructor_when_zone_is_set
+    with_env_tz 'UTC' do
+      with_tz_default ActiveSupport::TimeZone['Eastern Time (US & Canada)'] do # UTC -5
+        Time.stubs(:now).returns Time.local(2000, 1, 1)
+        assert_equal Date.new(1999, 12, 30), Date.yesterday
+      end
+    end
+  end
+
+  def test_tomorrow_constructor
+    assert_equal Date.current + 1, Date.tomorrow
+  end
+
+  def test_tomorrow_constructor_when_zone_is_not_set
+    with_env_tz 'UTC' do
+      with_tz_default do
+        assert_equal(Date.today + 1, Date.tomorrow)
+      end
+    end
+  end
+
+  def test_tomorrow_constructor_when_zone_is_set
+    with_env_tz 'UTC' do
+      with_tz_default ActiveSupport::TimeZone['Europe/Paris'] do # UTC +1
+        Time.stubs(:now).returns Time.local(1999, 12, 31, 23)
+        assert_equal Date.new(2000, 1, 2), Date.tomorrow
+      end
+    end
+  end
+
+  def test_since
+    assert_equal Time.local(2005,2,21,0,0,45), Date.new(2005,2,21).since(45)
+  end
+
+  def test_since_when_zone_is_set
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    with_env_tz 'UTC' do
+      with_tz_default zone do
+        assert_equal zone.local(2005,2,21,0,0,45), Date.new(2005,2,21).since(45)
+        assert_equal zone, Date.new(2005,2,21).since(45).time_zone
+      end
+    end
+  end
+
+  def test_ago
+    assert_equal Time.local(2005,2,20,23,59,15), Date.new(2005,2,21).ago(45)
+  end
+
+  def test_ago_when_zone_is_set
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    with_env_tz 'UTC' do
+      with_tz_default zone do
+        assert_equal zone.local(2005,2,20,23,59,15), Date.new(2005,2,21).ago(45)
+        assert_equal zone, Date.new(2005,2,21).ago(45).time_zone
+      end
+    end
+  end
+
+  def test_beginning_of_day
+    assert_equal Time.local(2005,2,21,0,0,0), Date.new(2005,2,21).beginning_of_day
+  end
+
+  def test_middle_of_day
+    assert_equal Time.local(2005,2,21,12,0,0), Date.new(2005,2,21).middle_of_day
+  end
+
+  def test_beginning_of_day_when_zone_is_set
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    with_env_tz 'UTC' do
+      with_tz_default zone do
+        assert_equal zone.local(2005,2,21,0,0,0), Date.new(2005,2,21).beginning_of_day
+        assert_equal zone, Date.new(2005,2,21).beginning_of_day.time_zone
+      end
+    end
+  end
+
+  def test_end_of_day
+    assert_equal Time.local(2005,2,21,23,59,59,Rational(999999999, 1000)), Date.new(2005,2,21).end_of_day
+  end
+
+  def test_end_of_day_when_zone_is_set
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    with_env_tz 'UTC' do
+      with_tz_default zone do
+        assert_equal zone.local(2005,2,21,23,59,59,Rational(999999999, 1000)), Date.new(2005,2,21).end_of_day
+        assert_equal zone, Date.new(2005,2,21).end_of_day.time_zone
+      end
+    end
+  end
+
+  def test_all_week
+    assert_equal Date.new(2011,6,6)..Date.new(2011,6,12), Date.new(2011,6,7).all_week
+    assert_equal Date.new(2011,6,5)..Date.new(2011,6,11), Date.new(2011,6,7).all_week(:sunday)
+  end
+
+  def test_all_month
+    assert_equal Date.new(2011,6,1)..Date.new(2011,6,30), Date.new(2011,6,7).all_month
+  end
+
+  def test_all_quarter
+    assert_equal Date.new(2011,4,1)..Date.new(2011,6,30), Date.new(2011,6,7).all_quarter
+  end
+
+  def test_all_year
+    assert_equal Date.new(2011,1,1)..Date.new(2011,12,31), Date.new(2011,6,7).all_year
+  end
+
+  def test_xmlschema
+    with_env_tz 'US/Eastern' do
+      assert_match(/^1980-02-28T00:00:00-05:?00$/, Date.new(1980, 2, 28).xmlschema)
+      assert_match(/^1980-06-28T00:00:00-04:?00$/, Date.new(1980, 6, 28).xmlschema)
+      # these tests are only of interest on platforms where older dates #to_time fail over to DateTime
+      if ::DateTime === Date.new(1880, 6, 28).to_time
+        assert_match(/^1880-02-28T00:00:00-05:?00$/, Date.new(1880, 2, 28).xmlschema)
+        assert_match(/^1880-06-28T00:00:00-05:?00$/, Date.new(1880, 6, 28).xmlschema) # DateTimes aren't aware of DST rules
+      end
+    end
+  end
+
+  def test_xmlschema_when_zone_is_set
+    with_env_tz 'UTC' do
+      with_tz_default ActiveSupport::TimeZone['Eastern Time (US & Canada)'] do # UTC -5
+        assert_match(/^1980-02-28T00:00:00-05:?00$/, Date.new(1980, 2, 28).xmlschema)
+        assert_match(/^1980-06-28T00:00:00-04:?00$/, Date.new(1980, 6, 28).xmlschema)
+      end
+    end
+  end
+
+  def test_past
+    Date.stubs(:current).returns(Date.new(2000, 1, 1))
+    assert_equal true, Date.new(1999, 12, 31).past?
+    assert_equal false, Date.new(2000,1,1).past?
+    assert_equal false, Date.new(2000,1,2).past?
+  end
+
+  def test_future
+    Date.stubs(:current).returns(Date.new(2000, 1, 1))
+    assert_equal false, Date.new(1999, 12, 31).future?
+    assert_equal false, Date.new(2000,1,1).future?
+    assert_equal true, Date.new(2000,1,2).future?
+  end
+
+  def test_current_returns_date_today_when_zone_not_set
+    with_env_tz 'US/Central' do
+      Time.stubs(:now).returns Time.local(1999, 12, 31, 23)
+      assert_equal Date.today, Date.current
+    end
+  end
+
+  def test_current_returns_time_zone_today_when_zone_is_set
+    Time.zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    with_env_tz 'US/Central' do
+      assert_equal ::Time.zone.today, Date.current
+    end
+  ensure
+    Time.zone = nil
+  end
+
+  def test_date_advance_should_not_change_passed_options_hash
+    options = { :years => 3, :months => 11, :days => 2 }
+    Date.new(2005,2,28).advance(options)
+    assert_equal({ :years => 3, :months => 11, :days => 2 }, options)
+  end
+
+  protected
+    def with_env_tz(new_tz = 'US/Eastern')
+      old_tz, ENV['TZ'] = ENV['TZ'], new_tz
+      yield
+    ensure
+      old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+    end
+
+    def with_tz_default(tz = nil)
+      old_tz = Time.zone
+      Time.zone = tz
+      yield
+    ensure
+      Time.zone = old_tz
+    end
+end
+
+class DateExtBehaviorTest < ActiveSupport::TestCase
+  def test_date_acts_like_date
+    assert Date.new.acts_like_date?
+  end
+
+  def test_freeze_doesnt_clobber_memoized_instance_methods
+    assert_nothing_raised do
+      Date.today.freeze.inspect
+    end
+  end
+
+  def test_can_freeze_twice
+    assert_nothing_raised do
+      Date.today.freeze.freeze
+    end
+  end
+end
+
diff --git a/app/server/vendor/activesupport/test/core_ext/date_time_ext_test.rb b/app/server/vendor/activesupport/test/core_ext/date_time_ext_test.rb
new file mode 100644
index 0000000..0a40aeb
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/date_time_ext_test.rb
@@ -0,0 +1,357 @@
+require 'abstract_unit'
+require 'active_support/time'
+require 'core_ext/date_and_time_behavior'
+
+class DateTimeExtCalculationsTest < ActiveSupport::TestCase
+  def date_time_init(year,month,day,hour,minute,second,*args)
+    DateTime.civil(year,month,day,hour,minute,second)
+  end
+
+  include DateAndTimeBehavior
+
+  def test_to_s
+    datetime = DateTime.new(2005, 2, 21, 14, 30, 0, 0)
+    assert_equal "2005-02-21 14:30:00",               datetime.to_s(:db)
+    assert_equal "14:30",                             datetime.to_s(:time)
+    assert_equal "21 Feb 14:30",                      datetime.to_s(:short)
+    assert_equal "February 21, 2005 14:30",           datetime.to_s(:long)
+    assert_equal "Mon, 21 Feb 2005 14:30:00 +0000",   datetime.to_s(:rfc822)
+    assert_equal "February 21st, 2005 14:30",         datetime.to_s(:long_ordinal)
+    assert_match(/^2005-02-21T14:30:00(Z|\+00:00)$/,  datetime.to_s)
+
+    with_env_tz "US/Central" do
+      assert_equal "2009-02-05T14:30:05-06:00", DateTime.civil(2009, 2, 5, 14, 30, 5, Rational(-21600, 86400)).to_s(:iso8601)
+      assert_equal "2008-06-09T04:05:01-05:00", DateTime.civil(2008, 6, 9, 4, 5, 1, Rational(-18000, 86400)).to_s(:iso8601)
+      assert_equal "2009-02-05T14:30:05+00:00", DateTime.civil(2009, 2, 5, 14, 30, 5).to_s(:iso8601)
+    end
+  end
+
+  def test_readable_inspect
+    datetime = DateTime.new(2005, 2, 21, 14, 30, 0)
+    assert_equal "Mon, 21 Feb 2005 14:30:00 +0000", datetime.readable_inspect
+    assert_equal datetime.readable_inspect, datetime.inspect
+  end
+
+  def test_custom_date_format
+    Time::DATE_FORMATS[:custom] = '%Y%m%d%H%M%S'
+    assert_equal '20050221143000', DateTime.new(2005, 2, 21, 14, 30, 0).to_s(:custom)
+    Time::DATE_FORMATS.delete(:custom)
+  end
+
+  def test_to_date
+    assert_equal Date.new(2005, 2, 21), DateTime.new(2005, 2, 21, 14, 30, 0).to_date
+  end
+
+  def test_to_datetime
+    assert_equal DateTime.new(2005, 2, 21, 14, 30, 0), DateTime.new(2005, 2, 21, 14, 30, 0).to_datetime
+  end
+
+  def test_to_time
+    with_env_tz 'US/Eastern' do
+      assert_equal Time, DateTime.new(2005, 2, 21, 10, 11, 12, 0).to_time.class
+      assert_equal Time.local(2005, 2, 21, 5, 11, 12), DateTime.new(2005, 2, 21, 10, 11, 12, 0).to_time
+      assert_equal Time.local(2005, 2, 21, 5, 11, 12).utc_offset, DateTime.new(2005, 2, 21, 10, 11, 12, 0).to_time.utc_offset
+    end
+  end
+
+  def test_to_time_preserves_fractional_seconds
+    assert_equal Time.utc(2005, 2, 21, 10, 11, 12, 256), DateTime.new(2005, 2, 21, 10, 11, 12 + Rational(256, 1000000), 0).to_time
+  end
+
+  def test_civil_from_format
+    assert_equal Time.local(2010, 5, 4, 0, 0, 0), DateTime.civil_from_format(:local, 2010, 5, 4)
+    assert_equal Time.utc(2010, 5, 4, 0, 0, 0), DateTime.civil_from_format(:utc, 2010, 5, 4)
+  end
+
+  def test_seconds_since_midnight
+    assert_equal 1,DateTime.civil(2005,1,1,0,0,1).seconds_since_midnight
+    assert_equal 60,DateTime.civil(2005,1,1,0,1,0).seconds_since_midnight
+    assert_equal 3660,DateTime.civil(2005,1,1,1,1,0).seconds_since_midnight
+    assert_equal 86399,DateTime.civil(2005,1,1,23,59,59).seconds_since_midnight
+  end
+
+  def test_seconds_until_end_of_day
+    assert_equal 0, DateTime.civil(2005,1,1,23,59,59).seconds_until_end_of_day
+    assert_equal 1, DateTime.civil(2005,1,1,23,59,58).seconds_until_end_of_day
+    assert_equal 60, DateTime.civil(2005,1,1,23,58,59).seconds_until_end_of_day
+    assert_equal 3660, DateTime.civil(2005,1,1,22,58,59).seconds_until_end_of_day
+    assert_equal 86399, DateTime.civil(2005,1,1,0,0,0).seconds_until_end_of_day
+  end
+
+  def test_beginning_of_day
+    assert_equal DateTime.civil(2005,2,4,0,0,0), DateTime.civil(2005,2,4,10,10,10).beginning_of_day
+  end
+
+  def test_middle_of_day
+    assert_equal DateTime.civil(2005,2,4,12,0,0), DateTime.civil(2005,2,4,10,10,10).middle_of_day
+  end
+
+  def test_end_of_day
+    assert_equal DateTime.civil(2005,2,4,23,59,59), DateTime.civil(2005,2,4,10,10,10).end_of_day
+  end
+
+  def test_beginning_of_hour
+    assert_equal DateTime.civil(2005,2,4,19,0,0), DateTime.civil(2005,2,4,19,30,10).beginning_of_hour
+  end
+
+  def test_end_of_hour
+    assert_equal DateTime.civil(2005,2,4,19,59,59), DateTime.civil(2005,2,4,19,30,10).end_of_hour
+  end
+
+  def test_beginning_of_minute
+    assert_equal DateTime.civil(2005,2,4,19,30,0), DateTime.civil(2005,2,4,19,30,10).beginning_of_minute
+  end
+
+  def test_end_of_minute
+    assert_equal DateTime.civil(2005,2,4,19,30,59), DateTime.civil(2005,2,4,19,30,10).end_of_minute
+  end
+
+  def test_end_of_month
+    assert_equal DateTime.civil(2005,3,31,23,59,59), DateTime.civil(2005,3,20,10,10,10).end_of_month
+    assert_equal DateTime.civil(2005,2,28,23,59,59), DateTime.civil(2005,2,20,10,10,10).end_of_month
+    assert_equal DateTime.civil(2005,4,30,23,59,59), DateTime.civil(2005,4,20,10,10,10).end_of_month
+  end
+
+  def test_last_year
+    assert_equal DateTime.civil(2004,6,5,10),  DateTime.civil(2005,6,5,10,0,0).last_year
+  end
+
+  def test_ago
+    assert_equal DateTime.civil(2005,2,22,10,10,9),  DateTime.civil(2005,2,22,10,10,10).ago(1)
+    assert_equal DateTime.civil(2005,2,22,9,10,10),  DateTime.civil(2005,2,22,10,10,10).ago(3600)
+    assert_equal DateTime.civil(2005,2,20,10,10,10), DateTime.civil(2005,2,22,10,10,10).ago(86400*2)
+    assert_equal DateTime.civil(2005,2,20,9,9,45),   DateTime.civil(2005,2,22,10,10,10).ago(86400*2 + 3600 + 25)
+  end
+
+  def test_since
+    assert_equal DateTime.civil(2005,2,22,10,10,11), DateTime.civil(2005,2,22,10,10,10).since(1)
+    assert_equal DateTime.civil(2005,2,22,11,10,10), DateTime.civil(2005,2,22,10,10,10).since(3600)
+    assert_equal DateTime.civil(2005,2,24,10,10,10), DateTime.civil(2005,2,22,10,10,10).since(86400*2)
+    assert_equal DateTime.civil(2005,2,24,11,10,35), DateTime.civil(2005,2,22,10,10,10).since(86400*2 + 3600 + 25)
+    assert_equal DateTime.civil(2005,2,22,10,10,11), DateTime.civil(2005,2,22,10,10,10).since(1.333)
+    assert_equal DateTime.civil(2005,2,22,10,10,12), DateTime.civil(2005,2,22,10,10,10).since(1.667)
+  end
+
+  def test_change
+    assert_equal DateTime.civil(2006,2,22,15,15,10), DateTime.civil(2005,2,22,15,15,10).change(:year => 2006)
+    assert_equal DateTime.civil(2005,6,22,15,15,10), DateTime.civil(2005,2,22,15,15,10).change(:month => 6)
+    assert_equal DateTime.civil(2012,9,22,15,15,10), DateTime.civil(2005,2,22,15,15,10).change(:year => 2012, :month => 9)
+    assert_equal DateTime.civil(2005,2,22,16),       DateTime.civil(2005,2,22,15,15,10).change(:hour => 16)
+    assert_equal DateTime.civil(2005,2,22,16,45),    DateTime.civil(2005,2,22,15,15,10).change(:hour => 16, :min => 45)
+    assert_equal DateTime.civil(2005,2,22,15,45),    DateTime.civil(2005,2,22,15,15,10).change(:min => 45)
+
+    # datetime with fractions of a second
+    assert_equal DateTime.civil(2005,2,1,15,15,10.7), DateTime.civil(2005,2,22,15,15,10.7).change(:day => 1)
+  end
+
+  def test_advance
+    assert_equal DateTime.civil(2006,2,28,15,15,10),  DateTime.civil(2005,2,28,15,15,10).advance(:years => 1)
+    assert_equal DateTime.civil(2005,6,28,15,15,10),  DateTime.civil(2005,2,28,15,15,10).advance(:months => 4)
+    assert_equal DateTime.civil(2005,3,21,15,15,10),  DateTime.civil(2005,2,28,15,15,10).advance(:weeks => 3)
+    assert_equal DateTime.civil(2005,3,5,15,15,10),   DateTime.civil(2005,2,28,15,15,10).advance(:days => 5)
+    assert_equal DateTime.civil(2012,9,28,15,15,10),  DateTime.civil(2005,2,28,15,15,10).advance(:years => 7, :months => 7)
+    assert_equal DateTime.civil(2013,10,3,15,15,10),  DateTime.civil(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :days => 5)
+    assert_equal DateTime.civil(2013,10,17,15,15,10), DateTime.civil(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :weeks => 2, :days => 5)
+    assert_equal DateTime.civil(2001,12,27,15,15,10), DateTime.civil(2005,2,28,15,15,10).advance(:years => -3, :months => -2, :days => -1)
+    assert_equal DateTime.civil(2005,2,28,15,15,10),  DateTime.civil(2004,2,29,15,15,10).advance(:years => 1) #leap day plus one year
+    assert_equal DateTime.civil(2005,2,28,20,15,10),  DateTime.civil(2005,2,28,15,15,10).advance(:hours => 5)
+    assert_equal DateTime.civil(2005,2,28,15,22,10),  DateTime.civil(2005,2,28,15,15,10).advance(:minutes => 7)
+    assert_equal DateTime.civil(2005,2,28,15,15,19),  DateTime.civil(2005,2,28,15,15,10).advance(:seconds => 9)
+    assert_equal DateTime.civil(2005,2,28,20,22,19),  DateTime.civil(2005,2,28,15,15,10).advance(:hours => 5, :minutes => 7, :seconds => 9)
+    assert_equal DateTime.civil(2005,2,28,10,8,1),    DateTime.civil(2005,2,28,15,15,10).advance(:hours => -5, :minutes => -7, :seconds => -9)
+    assert_equal DateTime.civil(2013,10,17,20,22,19), DateTime.civil(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :weeks => 2, :days => 5, :hours => 5, :minutes => 7, :seconds => 9)
+  end
+
+  def test_advanced_processes_first_the_date_deltas_and_then_the_time_deltas
+    # If the time deltas were processed first, the following datetimes would be advanced to 2010/04/01 instead.
+    assert_equal DateTime.civil(2010, 3, 29), DateTime.civil(2010, 2, 28, 23, 59, 59).advance(:months => 1, :seconds => 1)
+    assert_equal DateTime.civil(2010, 3, 29), DateTime.civil(2010, 2, 28, 23, 59).advance(:months => 1, :minutes => 1)
+    assert_equal DateTime.civil(2010, 3, 29), DateTime.civil(2010, 2, 28, 23).advance(:months => 1, :hours => 1)
+    assert_equal DateTime.civil(2010, 3, 29), DateTime.civil(2010, 2, 28, 22, 58, 59).advance(:months => 1, :hours => 1, :minutes => 1, :seconds => 1)
+  end
+
+  def test_last_week
+    assert_equal DateTime.civil(2005,2,21), DateTime.civil(2005,3,1,15,15,10).last_week
+    assert_equal DateTime.civil(2005,2,22), DateTime.civil(2005,3,1,15,15,10).last_week(:tuesday)
+    assert_equal DateTime.civil(2005,2,25), DateTime.civil(2005,3,1,15,15,10).last_week(:friday)
+    assert_equal DateTime.civil(2006,10,30), DateTime.civil(2006,11,6,0,0,0).last_week
+    assert_equal DateTime.civil(2006,11,15), DateTime.civil(2006,11,23,0,0,0).last_week(:wednesday)
+  end
+
+  def test_last_month_on_31st
+    assert_equal DateTime.civil(2004, 2, 29), DateTime.civil(2004, 3, 31).last_month
+  end
+
+  def test_last_quarter_on_31st
+    assert_equal DateTime.civil(2004, 2, 29), DateTime.civil(2004, 5, 31).last_quarter
+  end
+
+  def test_xmlschema
+    assert_match(/^1880-02-28T15:15:10\+00:?00$/, DateTime.civil(1880, 2, 28, 15, 15, 10).xmlschema)
+    assert_match(/^1980-02-28T15:15:10\+00:?00$/, DateTime.civil(1980, 2, 28, 15, 15, 10).xmlschema)
+    assert_match(/^2080-02-28T15:15:10\+00:?00$/, DateTime.civil(2080, 2, 28, 15, 15, 10).xmlschema)
+    assert_match(/^1880-02-28T15:15:10-06:?00$/, DateTime.civil(1880, 2, 28, 15, 15, 10, -0.25).xmlschema)
+    assert_match(/^1980-02-28T15:15:10-06:?00$/, DateTime.civil(1980, 2, 28, 15, 15, 10, -0.25).xmlschema)
+    assert_match(/^2080-02-28T15:15:10-06:?00$/, DateTime.civil(2080, 2, 28, 15, 15, 10, -0.25).xmlschema)
+  end
+
+  def test_today_with_offset
+    Date.stubs(:current).returns(Date.new(2000, 1, 1))
+    assert_equal false, DateTime.civil(1999,12,31,23,59,59, Rational(-18000, 86400)).today?
+    assert_equal true,  DateTime.civil(2000,1,1,0,0,0, Rational(-18000, 86400)).today?
+    assert_equal true,  DateTime.civil(2000,1,1,23,59,59, Rational(-18000, 86400)).today?
+    assert_equal false, DateTime.civil(2000,1,2,0,0,0, Rational(-18000, 86400)).today?
+  end
+
+  def test_today_without_offset
+    Date.stubs(:current).returns(Date.new(2000, 1, 1))
+    assert_equal false, DateTime.civil(1999,12,31,23,59,59).today?
+    assert_equal true,  DateTime.civil(2000,1,1,0).today?
+    assert_equal true,  DateTime.civil(2000,1,1,23,59,59).today?
+    assert_equal false, DateTime.civil(2000,1,2,0).today?
+  end
+
+  def test_past_with_offset
+    DateTime.stubs(:current).returns(DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)))
+    assert_equal true,  DateTime.civil(2005,2,10,15,30,44, Rational(-18000, 86400)).past?
+    assert_equal false,  DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)).past?
+    assert_equal false,  DateTime.civil(2005,2,10,15,30,46, Rational(-18000, 86400)).past?
+  end
+
+  def test_past_without_offset
+    DateTime.stubs(:current).returns(DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)))
+    assert_equal true,  DateTime.civil(2005,2,10,20,30,44).past?
+    assert_equal false,  DateTime.civil(2005,2,10,20,30,45).past?
+    assert_equal false,  DateTime.civil(2005,2,10,20,30,46).past?
+  end
+
+  def test_future_with_offset
+    DateTime.stubs(:current).returns(DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)))
+    assert_equal false,  DateTime.civil(2005,2,10,15,30,44, Rational(-18000, 86400)).future?
+    assert_equal false,  DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)).future?
+    assert_equal true,  DateTime.civil(2005,2,10,15,30,46, Rational(-18000, 86400)).future?
+  end
+
+  def test_future_without_offset
+    DateTime.stubs(:current).returns(DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)))
+    assert_equal false,  DateTime.civil(2005,2,10,20,30,44).future?
+    assert_equal false,  DateTime.civil(2005,2,10,20,30,45).future?
+    assert_equal true,  DateTime.civil(2005,2,10,20,30,46).future?
+  end
+
+  def test_current_returns_date_today_when_zone_is_not_set
+    with_env_tz 'US/Eastern' do
+      Time.stubs(:now).returns Time.local(1999, 12, 31, 23, 59, 59)
+      assert_equal DateTime.new(1999, 12, 31, 23, 59, 59, Rational(-18000, 86400)), DateTime.current
+    end
+  end
+
+  def test_current_returns_time_zone_today_when_zone_is_set
+    Time.zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    with_env_tz 'US/Eastern' do
+      Time.stubs(:now).returns Time.local(1999, 12, 31, 23, 59, 59)
+      assert_equal DateTime.new(1999, 12, 31, 23, 59, 59, Rational(-18000, 86400)), DateTime.current
+    end
+  ensure
+    Time.zone = nil
+  end
+
+  def test_current_without_time_zone
+    assert_kind_of DateTime, DateTime.current
+  end
+
+  def test_current_with_time_zone
+    with_env_tz 'US/Eastern' do
+      assert_kind_of DateTime, DateTime.current
+    end
+  end
+
+  def test_acts_like_date
+    assert DateTime.new.acts_like_date?
+  end
+
+  def test_acts_like_time
+    assert DateTime.new.acts_like_time?
+  end
+
+  def test_utc?
+    assert_equal true, DateTime.civil(2005, 2, 21, 10, 11, 12).utc?
+    assert_equal true, DateTime.civil(2005, 2, 21, 10, 11, 12, 0).utc?
+    assert_equal false, DateTime.civil(2005, 2, 21, 10, 11, 12, 0.25).utc?
+    assert_equal false, DateTime.civil(2005, 2, 21, 10, 11, 12, -0.25).utc?
+  end
+
+  def test_utc_offset
+    assert_equal 0, DateTime.civil(2005, 2, 21, 10, 11, 12).utc_offset
+    assert_equal 0, DateTime.civil(2005, 2, 21, 10, 11, 12, 0).utc_offset
+    assert_equal 21600, DateTime.civil(2005, 2, 21, 10, 11, 12, 0.25).utc_offset
+    assert_equal( -21600, DateTime.civil(2005, 2, 21, 10, 11, 12, -0.25).utc_offset )
+    assert_equal( -18000, DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-5, 24)).utc_offset )
+  end
+
+  def test_utc
+    assert_equal DateTime.civil(2005, 2, 21, 16, 11, 12, 0), DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc
+    assert_equal DateTime.civil(2005, 2, 21, 15, 11, 12, 0), DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-5, 24)).utc
+    assert_equal DateTime.civil(2005, 2, 21, 10, 11, 12, 0), DateTime.civil(2005, 2, 21, 10, 11, 12, 0).utc
+    assert_equal DateTime.civil(2005, 2, 21, 9, 11, 12, 0), DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(1, 24)).utc
+    assert_equal DateTime.civil(2005, 2, 21, 9, 11, 12, 0), DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(1, 24)).getutc
+  end
+
+  def test_formatted_offset_with_utc
+    assert_equal '+00:00', DateTime.civil(2000).formatted_offset
+    assert_equal '+0000', DateTime.civil(2000).formatted_offset(false)
+    assert_equal 'UTC', DateTime.civil(2000).formatted_offset(true, 'UTC')
+  end
+
+  def test_formatted_offset_with_local
+    dt = DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-5, 24))
+    assert_equal '-05:00', dt.formatted_offset
+    assert_equal '-0500', dt.formatted_offset(false)
+  end
+
+  def test_compare_with_time
+    assert_equal  1, DateTime.civil(2000) <=> Time.utc(1999, 12, 31, 23, 59, 59)
+    assert_equal  0, DateTime.civil(2000) <=> Time.utc(2000, 1, 1, 0, 0, 0)
+    assert_equal(-1, DateTime.civil(2000) <=> Time.utc(2000, 1, 1, 0, 0, 1))
+  end
+
+  def test_compare_with_datetime
+    assert_equal  1, DateTime.civil(2000) <=> DateTime.civil(1999, 12, 31, 23, 59, 59)
+    assert_equal  0, DateTime.civil(2000) <=> DateTime.civil(2000, 1, 1, 0, 0, 0)
+    assert_equal(-1, DateTime.civil(2000) <=> DateTime.civil(2000, 1, 1, 0, 0, 1))
+  end
+
+  def test_compare_with_time_with_zone
+    assert_equal  1, DateTime.civil(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(1999, 12, 31, 23, 59, 59), ActiveSupport::TimeZone['UTC'] )
+    assert_equal  0, DateTime.civil(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['UTC'] )
+    assert_equal(-1, DateTime.civil(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1), ActiveSupport::TimeZone['UTC'] ))
+  end
+
+  def test_to_f
+    assert_equal 946684800.0, DateTime.civil(2000).to_f
+    assert_equal 946684800.0, DateTime.civil(1999,12,31,19,0,0,Rational(-5,24)).to_f
+  end
+
+  def test_to_i
+    assert_equal 946684800, DateTime.civil(2000).to_i
+    assert_equal 946684800, DateTime.civil(1999,12,31,19,0,0,Rational(-5,24)).to_i
+  end
+
+  def test_usec
+    assert_equal 0, DateTime.civil(2000).usec
+    assert_equal 500000, DateTime.civil(2000, 1, 1, 0, 0, Rational(1,2)).usec
+  end
+
+  def test_nsec
+    assert_equal 0, DateTime.civil(2000).nsec
+    assert_equal 500000000, DateTime.civil(2000, 1, 1, 0, 0, Rational(1,2)).nsec
+  end
+
+  protected
+    def with_env_tz(new_tz = 'US/Eastern')
+      old_tz, ENV['TZ'] = ENV['TZ'], new_tz
+      yield
+    ensure
+      old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+    end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/deep_dup_test.rb b/app/server/vendor/activesupport/test/core_ext/deep_dup_test.rb
new file mode 100644
index 0000000..91d558d
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/deep_dup_test.rb
@@ -0,0 +1,53 @@
+require 'abstract_unit'
+require 'active_support/core_ext/object'
+
+class DeepDupTest < ActiveSupport::TestCase
+
+  def test_array_deep_dup
+    array = [1, [2, 3]]
+    dup = array.deep_dup
+    dup[1][2] = 4
+    assert_equal nil, array[1][2]
+    assert_equal 4, dup[1][2]
+  end
+
+  def test_hash_deep_dup
+    hash = { :a => { :b => 'b' } }
+    dup = hash.deep_dup
+    dup[:a][:c] = 'c'
+    assert_equal nil, hash[:a][:c]
+    assert_equal 'c', dup[:a][:c]
+  end
+
+  def test_array_deep_dup_with_hash_inside
+    array = [1, { :a => 2, :b => 3 } ]
+    dup = array.deep_dup
+    dup[1][:c] = 4
+    assert_equal nil, array[1][:c]
+    assert_equal 4, dup[1][:c]
+  end
+
+  def test_hash_deep_dup_with_array_inside
+    hash = { :a => [1, 2] }
+    dup = hash.deep_dup
+    dup[:a][2] = 'c'
+    assert_equal nil, hash[:a][2]
+    assert_equal 'c', dup[:a][2]
+  end
+
+  def test_deep_dup_initialize
+    zero_hash = Hash.new 0
+    hash = { :a => zero_hash }
+    dup = hash.deep_dup
+    assert_equal 0, dup[:a][44]
+  end
+
+  def test_object_deep_dup
+    object = Object.new
+    dup = object.deep_dup
+    dup.instance_variable_set(:@a, 1)
+    assert !object.instance_variable_defined?(:@a)
+    assert dup.instance_variable_defined?(:@a)
+  end
+
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/duplicable_test.rb b/app/server/vendor/activesupport/test/core_ext/duplicable_test.rb
new file mode 100644
index 0000000..e0566e0
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/duplicable_test.rb
@@ -0,0 +1,38 @@
+require 'abstract_unit'
+require 'bigdecimal'
+require 'active_support/core_ext/object/duplicable'
+require 'active_support/core_ext/numeric/time'
+
+class DuplicableTest < ActiveSupport::TestCase
+  RAISE_DUP  = [nil, false, true, :symbol, 1, 2.3, 5.seconds]
+  YES = ['1', Object.new, /foo/, [], {}, Time.now, Class.new, Module.new]
+  NO = []
+
+  begin
+    bd = BigDecimal.new('4.56')
+    YES << bd.dup
+  rescue TypeError
+    RAISE_DUP << bd
+  end
+
+
+  def test_duplicable
+    (RAISE_DUP + NO).each do |v|
+      assert !v.duplicable?
+    end
+
+    YES.each do |v|
+      assert v.duplicable?, "#{v.class} should be duplicable"
+    end
+
+    (YES + NO).each do |v|
+      assert_nothing_raised { v.dup }
+    end
+
+    RAISE_DUP.each do |v|
+      assert_raises(TypeError, v.class.name) do
+        v.dup
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/duration_test.rb b/app/server/vendor/activesupport/test/core_ext/duration_test.rb
new file mode 100644
index 0000000..28ba333
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/duration_test.rb
@@ -0,0 +1,171 @@
+require 'abstract_unit'
+require 'active_support/inflector'
+require 'active_support/time'
+require 'active_support/json'
+
+class DurationTest < ActiveSupport::TestCase
+  def test_is_a
+    d = 1.day
+    assert d.is_a?(ActiveSupport::Duration)
+    assert_kind_of ActiveSupport::Duration, d
+    assert_kind_of Numeric, d
+    assert_kind_of Fixnum, d
+    assert !d.is_a?(Hash)
+
+    k = Class.new
+    class << k; undef_method :== end
+    assert !d.is_a?(k)
+  end
+
+  def test_threequals
+    assert ActiveSupport::Duration === 1.day
+    assert !(ActiveSupport::Duration === 1.day.to_i)
+    assert !(ActiveSupport::Duration === 'foo')
+    assert !(ActiveSupport::Duration === ActiveSupport::ProxyObject.new)
+  end
+
+  def test_equals
+    assert 1.day == 1.day
+    assert 1.day == 1.day.to_i
+    assert 1.day.to_i == 1.day
+    assert !(1.day == 'foo')
+  end
+
+  def test_inspect
+    assert_equal '0 seconds',                       0.seconds.inspect
+    assert_equal '1 month',                         1.month.inspect
+    assert_equal '1 month and 1 day',               (1.month + 1.day).inspect
+    assert_equal '6 months and -2 days',            (6.months - 2.days).inspect
+    assert_equal '10 seconds',                      10.seconds.inspect
+    assert_equal '10 years, 2 months, and 1 day',   (10.years + 2.months + 1.day).inspect
+    assert_equal '10 years, 2 months, and 1 day',   (10.years + 1.month  + 1.day + 1.month).inspect
+    assert_equal '10 years, 2 months, and 1 day',   (1.day + 10.years + 2.months).inspect
+    assert_equal '7 days',                          1.week.inspect
+    assert_equal '14 days',                         1.fortnight.inspect
+  end
+
+  def test_minus_with_duration_does_not_break_subtraction_of_date_from_date
+    assert_nothing_raised { Date.today - Date.today }
+  end
+
+  def test_plus_with_time
+    assert_equal 1 + 1.second, 1.second + 1, "Duration + Numeric should == Numeric + Duration"
+  end
+
+  def test_argument_error
+    e = assert_raise ArgumentError do
+      1.second.ago('')
+    end
+    assert_equal 'expected a time or date, got ""', e.message, "ensure ArgumentError is not being raised by dependencies.rb"
+  end
+
+  def test_fractional_weeks
+    assert_equal((86400 * 7) * 1.5, 1.5.weeks)
+    assert_equal((86400 * 7) * 1.7, 1.7.weeks)
+  end
+
+  def test_fractional_days
+    assert_equal 86400 * 1.5, 1.5.days
+    assert_equal 86400 * 1.7, 1.7.days
+  end
+
+  def test_since_and_ago
+    t = Time.local(2000)
+    assert t + 1, 1.second.since(t)
+    assert t - 1, 1.second.ago(t)
+  end
+
+  def test_since_and_ago_without_argument
+    now = Time.now
+    assert 1.second.since >= now + 1
+    now = Time.now
+    assert 1.second.ago >= now - 1
+  end
+
+  def test_since_and_ago_with_fractional_days
+    t = Time.local(2000)
+    # since
+    assert_equal 36.hours.since(t), 1.5.days.since(t)
+    assert_in_delta((24 * 1.7).hours.since(t), 1.7.days.since(t), 1)
+    # ago
+    assert_equal 36.hours.ago(t), 1.5.days.ago(t)
+    assert_in_delta((24 * 1.7).hours.ago(t), 1.7.days.ago(t), 1)
+  end
+
+  def test_since_and_ago_with_fractional_weeks
+    t = Time.local(2000)
+    # since
+    assert_equal((7 * 36).hours.since(t), 1.5.weeks.since(t))
+    assert_in_delta((7 * 24 * 1.7).hours.since(t), 1.7.weeks.since(t), 1)
+    # ago
+    assert_equal((7 * 36).hours.ago(t), 1.5.weeks.ago(t))
+    assert_in_delta((7 * 24 * 1.7).hours.ago(t), 1.7.weeks.ago(t), 1)
+  end
+
+  def test_since_and_ago_anchored_to_time_now_when_time_zone_is_not_set
+    Time.zone = nil
+    with_env_tz 'US/Eastern' do
+      Time.stubs(:now).returns Time.local(2000)
+      # since
+      assert_not_instance_of ActiveSupport::TimeWithZone, 5.seconds.since
+      assert_equal Time.local(2000,1,1,0,0,5), 5.seconds.since
+      # ago
+      assert_not_instance_of ActiveSupport::TimeWithZone, 5.seconds.ago
+      assert_equal Time.local(1999,12,31,23,59,55), 5.seconds.ago
+    end
+  end
+
+  def test_since_and_ago_anchored_to_time_zone_now_when_time_zone_is_set
+    Time.zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    with_env_tz 'US/Eastern' do
+      Time.stubs(:now).returns Time.local(2000)
+      # since
+      assert_instance_of ActiveSupport::TimeWithZone, 5.seconds.since
+      assert_equal Time.utc(2000,1,1,0,0,5), 5.seconds.since.time
+      assert_equal 'Eastern Time (US & Canada)', 5.seconds.since.time_zone.name
+      # ago
+      assert_instance_of ActiveSupport::TimeWithZone, 5.seconds.ago
+      assert_equal Time.utc(1999,12,31,23,59,55), 5.seconds.ago.time
+      assert_equal 'Eastern Time (US & Canada)', 5.seconds.ago.time_zone.name
+    end
+  ensure
+    Time.zone = nil
+  end
+
+  def test_adding_hours_across_dst_boundary
+    with_env_tz 'CET' do
+      assert_equal Time.local(2009,3,29,0,0,0) + 24.hours, Time.local(2009,3,30,1,0,0)
+    end
+  end
+
+  def test_adding_day_across_dst_boundary
+    with_env_tz 'CET' do
+      assert_equal Time.local(2009,3,29,0,0,0) + 1.day, Time.local(2009,3,30,0,0,0)
+    end
+  end
+
+  def test_delegation_with_block_works
+    counter = 0
+    assert_nothing_raised do
+      1.minute.times {counter += 1}
+    end
+    assert_equal counter, 60
+  end
+
+  def test_to_json
+    assert_equal '172800', 2.days.to_json
+  end
+
+  def test_case_when
+    cased = case 1.day when 1.day then "ok" end
+    assert_equal cased, "ok"
+  end
+
+  protected
+    def with_env_tz(new_tz = 'US/Eastern')
+      old_tz, ENV['TZ'] = ENV['TZ'], new_tz
+      yield
+    ensure
+      old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+    end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/enumerable_test.rb b/app/server/vendor/activesupport/test/core_ext/enumerable_test.rb
new file mode 100644
index 0000000..6fcf6e8
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/enumerable_test.rb
@@ -0,0 +1,106 @@
+require 'abstract_unit'
+require 'active_support/core_ext/array'
+require 'active_support/core_ext/enumerable'
+
+Payment = Struct.new(:price)
+class SummablePayment < Payment
+  def +(p) self.class.new(price + p.price) end
+end
+
+class EnumerableTests < ActiveSupport::TestCase
+
+  class GenericEnumerable
+    include Enumerable
+    def initialize(values = [1, 2, 3])
+      @values = values
+    end
+
+    def each
+      @values.each{|v| yield v}
+    end
+  end
+
+  def test_sums
+    enum = GenericEnumerable.new([5, 15, 10])
+    assert_equal 30, enum.sum
+    assert_equal 60, enum.sum { |i| i * 2}
+
+    enum = GenericEnumerable.new(%w(a b c))
+    assert_equal 'abc', enum.sum
+    assert_equal 'aabbcc', enum.sum { |i| i * 2 }
+
+    payments = GenericEnumerable.new([ Payment.new(5), Payment.new(15), Payment.new(10) ])
+    assert_equal 30, payments.sum(&:price)
+    assert_equal 60, payments.sum { |p| p.price * 2 }
+
+    payments = GenericEnumerable.new([ SummablePayment.new(5), SummablePayment.new(15) ])
+    assert_equal SummablePayment.new(20), payments.sum
+    assert_equal SummablePayment.new(20), payments.sum { |p| p }
+  end
+
+  def test_nil_sums
+    expected_raise = TypeError
+
+    assert_raise(expected_raise) { GenericEnumerable.new([5, 15, nil]).sum }
+
+    payments = GenericEnumerable.new([ Payment.new(5), Payment.new(15), Payment.new(10), Payment.new(nil) ])
+    assert_raise(expected_raise) { payments.sum(&:price) }
+
+    assert_equal 60, payments.sum { |p| p.price.to_i * 2 }
+  end
+
+  def test_empty_sums
+    assert_equal 0, GenericEnumerable.new([]).sum
+    assert_equal 0, GenericEnumerable.new([]).sum { |i| i + 10 }
+    assert_equal Payment.new(0), GenericEnumerable.new([]).sum(Payment.new(0))
+  end
+
+  def test_range_sums
+    assert_equal 20, (1..4).sum { |i| i * 2 }
+    assert_equal 10, (1..4).sum
+    assert_equal 10, (1..4.5).sum
+    assert_equal 6, (1...4).sum
+    assert_equal 'abc', ('a'..'c').sum
+    assert_equal 50_000_005_000_000, (0..10_000_000).sum
+    assert_equal 0, (10..0).sum
+    assert_equal 5, (10..0).sum(5)
+    assert_equal 10, (10..10).sum
+    assert_equal 42, (10...10).sum(42)
+  end
+
+  def test_index_by
+    payments = GenericEnumerable.new([ Payment.new(5), Payment.new(15), Payment.new(10) ])
+    assert_equal({ 5 => Payment.new(5), 15 => Payment.new(15), 10 => Payment.new(10) },
+                 payments.index_by { |p| p.price })
+    assert_equal Enumerator, payments.index_by.class
+    if Enumerator.method_defined? :size
+      assert_equal nil, payments.index_by.size
+      assert_equal 42, (1..42).index_by.size
+    end
+    assert_equal({ 5 => Payment.new(5), 15 => Payment.new(15), 10 => Payment.new(10) },
+                 payments.index_by.each { |p| p.price })
+  end
+
+  def test_many
+    assert_equal false, GenericEnumerable.new([]         ).many?
+    assert_equal false, GenericEnumerable.new([ 1 ]      ).many?
+    assert_equal true,  GenericEnumerable.new([ 1, 2 ]   ).many?
+
+    assert_equal false, GenericEnumerable.new([]         ).many? {|x| x > 1 }
+    assert_equal false, GenericEnumerable.new([ 2 ]      ).many? {|x| x > 1 }
+    assert_equal false, GenericEnumerable.new([ 1, 2 ]   ).many? {|x| x > 1 }
+    assert_equal true,  GenericEnumerable.new([ 1, 2, 2 ]).many? {|x| x > 1 }
+  end
+
+  def test_many_iterates_only_on_what_is_needed
+    infinity = 1.0/0.0
+    very_long_enum = 0..infinity
+    assert_equal true, very_long_enum.many?
+    assert_equal true, very_long_enum.many?{|x| x > 100}
+  end
+
+  def test_exclude?
+    assert_equal true,  GenericEnumerable.new([ 1 ]).exclude?(2)
+    assert_equal false, GenericEnumerable.new([ 1 ]).exclude?(1)
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/file_test.rb b/app/server/vendor/activesupport/test/core_ext/file_test.rb
new file mode 100644
index 0000000..2c04e96
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/file_test.rb
@@ -0,0 +1,68 @@
+require 'abstract_unit'
+require 'active_support/core_ext/file'
+
+class AtomicWriteTest < ActiveSupport::TestCase
+  def test_atomic_write_without_errors
+    contents = "Atomic Text"
+    File.atomic_write(file_name, Dir.pwd) do |file|
+      file.write(contents)
+      assert !File.exist?(file_name)
+    end
+    assert File.exist?(file_name)
+    assert_equal contents, File.read(file_name)
+  ensure
+    File.unlink(file_name) rescue nil
+  end
+
+  def test_atomic_write_doesnt_write_when_block_raises
+    File.atomic_write(file_name) do |file|
+      file.write("testing")
+      raise "something bad"
+    end
+  rescue
+    assert !File.exist?(file_name)
+  end
+
+  def test_atomic_write_preserves_file_permissions
+    contents = "Atomic Text"
+    File.open(file_name, "w", 0755) do |file|
+      file.write(contents)
+      assert File.exist?(file_name)
+    end
+    assert File.exist?(file_name)
+    assert_equal 0100755 & ~File.umask, file_mode
+    assert_equal contents, File.read(file_name)
+
+    File.atomic_write(file_name, Dir.pwd) do |file|
+      file.write(contents)
+      assert File.exist?(file_name)
+    end
+    assert File.exist?(file_name)
+    assert_equal 0100755 & ~File.umask, file_mode
+    assert_equal contents, File.read(file_name)
+  ensure
+    File.unlink(file_name) rescue nil
+  end
+
+  def test_atomic_write_preserves_default_file_permissions
+    contents = "Atomic Text"
+    File.atomic_write(file_name, Dir.pwd) do |file|
+      file.write(contents)
+      assert !File.exist?(file_name)
+    end
+    assert File.exist?(file_name)
+    assert_equal File.probe_stat_in(Dir.pwd).mode, file_mode
+    assert_equal contents, File.read(file_name)
+  ensure
+    File.unlink(file_name) rescue nil
+  end
+
+  private
+    def file_name
+      "atomic.file"
+    end
+
+    def file_mode
+      File.stat(file_name).mode
+    end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/hash_ext_test.rb b/app/server/vendor/activesupport/test/core_ext/hash_ext_test.rb
new file mode 100644
index 0000000..69a380c
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/hash_ext_test.rb
@@ -0,0 +1,1592 @@
+require 'abstract_unit'
+require 'active_support/core_ext/hash'
+require 'bigdecimal'
+require 'active_support/core_ext/string/access'
+require 'active_support/ordered_hash'
+require 'active_support/core_ext/object/conversions'
+require 'active_support/core_ext/object/deep_dup'
+require 'active_support/inflections'
+
+class HashExtTest < ActiveSupport::TestCase
+  class IndifferentHash < ActiveSupport::HashWithIndifferentAccess
+  end
+
+  class SubclassingArray < Array
+  end
+
+  class SubclassingHash < Hash
+  end
+
+  class NonIndifferentHash < Hash
+    def nested_under_indifferent_access
+      self
+    end
+  end
+
+  class HashByConversion
+    def initialize(hash)
+      @hash = hash
+    end
+
+    def to_hash
+      @hash
+    end
+  end
+
+  def setup
+    @strings = { 'a' => 1, 'b' => 2 }
+    @nested_strings = { 'a' => { 'b' => { 'c' => 3 } } }
+    @symbols = { :a  => 1, :b  => 2 }
+    @nested_symbols = { :a => { :b => { :c => 3 } } }
+    @mixed   = { :a  => 1, 'b' => 2 }
+    @nested_mixed   = { 'a' => { :b => { 'c' => 3 } } }
+    @fixnums = {  0  => 1,  1  => 2 }
+    @nested_fixnums = {  0  => { 1  => { 2 => 3} } }
+    @illegal_symbols = { [] => 3 }
+    @nested_illegal_symbols = { [] => { [] => 3} }
+    @upcase_strings = { 'A' => 1, 'B' => 2 }
+    @nested_upcase_strings = { 'A' => { 'B' => { 'C' => 3 } } }
+  end
+
+  def test_methods
+    h = {}
+    assert_respond_to h, :transform_keys
+    assert_respond_to h, :transform_keys!
+    assert_respond_to h, :deep_transform_keys
+    assert_respond_to h, :deep_transform_keys!
+    assert_respond_to h, :symbolize_keys
+    assert_respond_to h, :symbolize_keys!
+    assert_respond_to h, :deep_symbolize_keys
+    assert_respond_to h, :deep_symbolize_keys!
+    assert_respond_to h, :stringify_keys
+    assert_respond_to h, :stringify_keys!
+    assert_respond_to h, :deep_stringify_keys
+    assert_respond_to h, :deep_stringify_keys!
+    assert_respond_to h, :to_options
+    assert_respond_to h, :to_options!
+    assert_respond_to h, :compact
+    assert_respond_to h, :compact!
+  end
+
+  def test_transform_keys
+    assert_equal @upcase_strings, @strings.transform_keys{ |key| key.to_s.upcase }
+    assert_equal @upcase_strings, @symbols.transform_keys{ |key| key.to_s.upcase }
+    assert_equal @upcase_strings, @mixed.transform_keys{ |key| key.to_s.upcase }
+  end
+
+  def test_transform_keys_not_mutates
+    transformed_hash = @mixed.dup
+    transformed_hash.transform_keys{ |key| key.to_s.upcase }
+    assert_equal @mixed, transformed_hash
+  end
+
+  def test_deep_transform_keys
+    assert_equal @nested_upcase_strings, @nested_symbols.deep_transform_keys{ |key| key.to_s.upcase }
+    assert_equal @nested_upcase_strings, @nested_strings.deep_transform_keys{ |key| key.to_s.upcase }
+    assert_equal @nested_upcase_strings, @nested_mixed.deep_transform_keys{ |key| key.to_s.upcase }
+  end
+
+  def test_deep_transform_keys_not_mutates
+    transformed_hash = @nested_mixed.deep_dup
+    transformed_hash.deep_transform_keys{ |key| key.to_s.upcase }
+    assert_equal @nested_mixed, transformed_hash
+  end
+
+  def test_transform_keys!
+    assert_equal @upcase_strings, @symbols.dup.transform_keys!{ |key| key.to_s.upcase }
+    assert_equal @upcase_strings, @strings.dup.transform_keys!{ |key| key.to_s.upcase }
+    assert_equal @upcase_strings, @mixed.dup.transform_keys!{ |key| key.to_s.upcase }
+  end
+
+  def test_transform_keys_with_bang_mutates
+    transformed_hash = @mixed.dup
+    transformed_hash.transform_keys!{ |key| key.to_s.upcase }
+    assert_equal @upcase_strings, transformed_hash
+    assert_equal @mixed, { :a => 1, "b" => 2 }
+  end
+
+  def test_deep_transform_keys!
+    assert_equal @nested_upcase_strings, @nested_symbols.deep_dup.deep_transform_keys!{ |key| key.to_s.upcase }
+    assert_equal @nested_upcase_strings, @nested_strings.deep_dup.deep_transform_keys!{ |key| key.to_s.upcase }
+    assert_equal @nested_upcase_strings, @nested_mixed.deep_dup.deep_transform_keys!{ |key| key.to_s.upcase }
+  end
+
+  def test_deep_transform_keys_with_bang_mutates
+    transformed_hash = @nested_mixed.deep_dup
+    transformed_hash.deep_transform_keys!{ |key| key.to_s.upcase }
+    assert_equal @nested_upcase_strings, transformed_hash
+    assert_equal @nested_mixed, { 'a' => { :b => { 'c' => 3 } } }
+  end
+
+  def test_symbolize_keys
+    assert_equal @symbols, @symbols.symbolize_keys
+    assert_equal @symbols, @strings.symbolize_keys
+    assert_equal @symbols, @mixed.symbolize_keys
+  end
+
+  def test_symbolize_keys_not_mutates
+    transformed_hash = @mixed.dup
+    transformed_hash.symbolize_keys
+    assert_equal @mixed, transformed_hash
+  end
+
+  def test_deep_symbolize_keys
+    assert_equal @nested_symbols, @nested_symbols.deep_symbolize_keys
+    assert_equal @nested_symbols, @nested_strings.deep_symbolize_keys
+    assert_equal @nested_symbols, @nested_mixed.deep_symbolize_keys
+  end
+
+  def test_deep_symbolize_keys_not_mutates
+    transformed_hash = @nested_mixed.deep_dup
+    transformed_hash.deep_symbolize_keys
+    assert_equal @nested_mixed, transformed_hash
+  end
+
+  def test_symbolize_keys!
+    assert_equal @symbols, @symbols.dup.symbolize_keys!
+    assert_equal @symbols, @strings.dup.symbolize_keys!
+    assert_equal @symbols, @mixed.dup.symbolize_keys!
+  end
+
+  def test_symbolize_keys_with_bang_mutates
+    transformed_hash = @mixed.dup
+    transformed_hash.deep_symbolize_keys!
+    assert_equal @symbols, transformed_hash
+    assert_equal @mixed, { :a => 1, "b" => 2 }
+  end
+
+  def test_deep_symbolize_keys!
+    assert_equal @nested_symbols, @nested_symbols.deep_dup.deep_symbolize_keys!
+    assert_equal @nested_symbols, @nested_strings.deep_dup.deep_symbolize_keys!
+    assert_equal @nested_symbols, @nested_mixed.deep_dup.deep_symbolize_keys!
+  end
+
+  def test_deep_symbolize_keys_with_bang_mutates
+    transformed_hash = @nested_mixed.deep_dup
+    transformed_hash.deep_symbolize_keys!
+    assert_equal @nested_symbols, transformed_hash
+    assert_equal @nested_mixed, { 'a' => { :b => { 'c' => 3 } } }
+  end
+
+  def test_symbolize_keys_preserves_keys_that_cant_be_symbolized
+    assert_equal @illegal_symbols, @illegal_symbols.symbolize_keys
+    assert_equal @illegal_symbols, @illegal_symbols.dup.symbolize_keys!
+  end
+
+  def test_deep_symbolize_keys_preserves_keys_that_cant_be_symbolized
+    assert_equal @nested_illegal_symbols, @nested_illegal_symbols.deep_symbolize_keys
+    assert_equal @nested_illegal_symbols, @nested_illegal_symbols.deep_dup.deep_symbolize_keys!
+  end
+
+  def test_symbolize_keys_preserves_fixnum_keys
+    assert_equal @fixnums, @fixnums.symbolize_keys
+    assert_equal @fixnums, @fixnums.dup.symbolize_keys!
+  end
+
+  def test_deep_symbolize_keys_preserves_fixnum_keys
+    assert_equal @nested_fixnums, @nested_fixnums.deep_symbolize_keys
+    assert_equal @nested_fixnums, @nested_fixnums.deep_dup.deep_symbolize_keys!
+  end
+
+  def test_stringify_keys
+    assert_equal @strings, @symbols.stringify_keys
+    assert_equal @strings, @strings.stringify_keys
+    assert_equal @strings, @mixed.stringify_keys
+  end
+
+  def test_stringify_keys_not_mutates
+    transformed_hash = @mixed.dup
+    transformed_hash.stringify_keys
+    assert_equal @mixed, transformed_hash
+  end
+
+  def test_deep_stringify_keys
+    assert_equal @nested_strings, @nested_symbols.deep_stringify_keys
+    assert_equal @nested_strings, @nested_strings.deep_stringify_keys
+    assert_equal @nested_strings, @nested_mixed.deep_stringify_keys
+  end
+
+  def test_deep_stringify_keys_not_mutates
+    transformed_hash = @nested_mixed.deep_dup
+    transformed_hash.deep_stringify_keys
+    assert_equal @nested_mixed, transformed_hash
+  end
+
+  def test_stringify_keys!
+    assert_equal @strings, @symbols.dup.stringify_keys!
+    assert_equal @strings, @strings.dup.stringify_keys!
+    assert_equal @strings, @mixed.dup.stringify_keys!
+  end
+
+  def test_stringify_keys_with_bang_mutates
+    transformed_hash = @mixed.dup
+    transformed_hash.stringify_keys!
+    assert_equal @strings, transformed_hash
+    assert_equal @mixed, { :a => 1, "b" => 2 }
+  end
+
+  def test_deep_stringify_keys!
+    assert_equal @nested_strings, @nested_symbols.deep_dup.deep_stringify_keys!
+    assert_equal @nested_strings, @nested_strings.deep_dup.deep_stringify_keys!
+    assert_equal @nested_strings, @nested_mixed.deep_dup.deep_stringify_keys!
+  end
+
+  def test_deep_stringify_keys_with_bang_mutates
+    transformed_hash = @nested_mixed.deep_dup
+    transformed_hash.deep_stringify_keys!
+    assert_equal @nested_strings, transformed_hash
+    assert_equal @nested_mixed, { 'a' => { :b => { 'c' => 3 } } }
+  end
+
+  def test_symbolize_keys_for_hash_with_indifferent_access
+    assert_instance_of Hash, @symbols.with_indifferent_access.symbolize_keys
+    assert_equal @symbols, @symbols.with_indifferent_access.symbolize_keys
+    assert_equal @symbols, @strings.with_indifferent_access.symbolize_keys
+    assert_equal @symbols, @mixed.with_indifferent_access.symbolize_keys
+  end
+
+  def test_deep_symbolize_keys_for_hash_with_indifferent_access
+    assert_instance_of Hash, @nested_symbols.with_indifferent_access.deep_symbolize_keys
+    assert_equal @nested_symbols, @nested_symbols.with_indifferent_access.deep_symbolize_keys
+    assert_equal @nested_symbols, @nested_strings.with_indifferent_access.deep_symbolize_keys
+    assert_equal @nested_symbols, @nested_mixed.with_indifferent_access.deep_symbolize_keys
+  end
+
+
+  def test_symbolize_keys_bang_for_hash_with_indifferent_access
+    assert_raise(NoMethodError) { @symbols.with_indifferent_access.dup.symbolize_keys! }
+    assert_raise(NoMethodError) { @strings.with_indifferent_access.dup.symbolize_keys! }
+    assert_raise(NoMethodError) { @mixed.with_indifferent_access.dup.symbolize_keys! }
+  end
+
+  def test_deep_symbolize_keys_bang_for_hash_with_indifferent_access
+    assert_raise(NoMethodError) { @nested_symbols.with_indifferent_access.deep_dup.deep_symbolize_keys! }
+    assert_raise(NoMethodError) { @nested_strings.with_indifferent_access.deep_dup.deep_symbolize_keys! }
+    assert_raise(NoMethodError) { @nested_mixed.with_indifferent_access.deep_dup.deep_symbolize_keys! }
+  end
+
+  def test_symbolize_keys_preserves_keys_that_cant_be_symbolized_for_hash_with_indifferent_access
+    assert_equal @illegal_symbols, @illegal_symbols.with_indifferent_access.symbolize_keys
+    assert_raise(NoMethodError) { @illegal_symbols.with_indifferent_access.dup.symbolize_keys! }
+  end
+
+  def test_deep_symbolize_keys_preserves_keys_that_cant_be_symbolized_for_hash_with_indifferent_access
+    assert_equal @nested_illegal_symbols, @nested_illegal_symbols.with_indifferent_access.deep_symbolize_keys
+    assert_raise(NoMethodError) { @nested_illegal_symbols.with_indifferent_access.deep_dup.deep_symbolize_keys! }
+  end
+
+  def test_symbolize_keys_preserves_fixnum_keys_for_hash_with_indifferent_access
+    assert_equal @fixnums, @fixnums.with_indifferent_access.symbolize_keys
+    assert_raise(NoMethodError) { @fixnums.with_indifferent_access.dup.symbolize_keys! }
+  end
+
+  def test_deep_symbolize_keys_preserves_fixnum_keys_for_hash_with_indifferent_access
+    assert_equal @nested_fixnums, @nested_fixnums.with_indifferent_access.deep_symbolize_keys
+    assert_raise(NoMethodError) { @nested_fixnums.with_indifferent_access.deep_dup.deep_symbolize_keys! }
+  end
+
+  def test_stringify_keys_for_hash_with_indifferent_access
+    assert_instance_of ActiveSupport::HashWithIndifferentAccess, @symbols.with_indifferent_access.stringify_keys
+    assert_equal @strings, @symbols.with_indifferent_access.stringify_keys
+    assert_equal @strings, @strings.with_indifferent_access.stringify_keys
+    assert_equal @strings, @mixed.with_indifferent_access.stringify_keys
+  end
+
+  def test_deep_stringify_keys_for_hash_with_indifferent_access
+    assert_instance_of ActiveSupport::HashWithIndifferentAccess, @nested_symbols.with_indifferent_access.deep_stringify_keys
+    assert_equal @nested_strings, @nested_symbols.with_indifferent_access.deep_stringify_keys
+    assert_equal @nested_strings, @nested_strings.with_indifferent_access.deep_stringify_keys
+    assert_equal @nested_strings, @nested_mixed.with_indifferent_access.deep_stringify_keys
+  end
+
+  def test_stringify_keys_bang_for_hash_with_indifferent_access
+    assert_instance_of ActiveSupport::HashWithIndifferentAccess, @symbols.with_indifferent_access.dup.stringify_keys!
+    assert_equal @strings, @symbols.with_indifferent_access.dup.stringify_keys!
+    assert_equal @strings, @strings.with_indifferent_access.dup.stringify_keys!
+    assert_equal @strings, @mixed.with_indifferent_access.dup.stringify_keys!
+  end
+
+  def test_deep_stringify_keys_bang_for_hash_with_indifferent_access
+    assert_instance_of ActiveSupport::HashWithIndifferentAccess, @nested_symbols.with_indifferent_access.dup.deep_stringify_keys!
+    assert_equal @nested_strings, @nested_symbols.with_indifferent_access.deep_dup.deep_stringify_keys!
+    assert_equal @nested_strings, @nested_strings.with_indifferent_access.deep_dup.deep_stringify_keys!
+    assert_equal @nested_strings, @nested_mixed.with_indifferent_access.deep_dup.deep_stringify_keys!
+  end
+
+  def test_nested_under_indifferent_access
+    foo = { "foo" => SubclassingHash.new.tap { |h| h["bar"] = "baz" } }.with_indifferent_access
+    assert_kind_of ActiveSupport::HashWithIndifferentAccess, foo["foo"]
+
+    foo = { "foo" => NonIndifferentHash.new.tap { |h| h["bar"] = "baz" } }.with_indifferent_access
+    assert_kind_of NonIndifferentHash, foo["foo"]
+
+    foo = { "foo" => IndifferentHash.new.tap { |h| h["bar"] = "baz" } }.with_indifferent_access
+    assert_kind_of IndifferentHash, foo["foo"]
+  end
+
+  def test_indifferent_assorted
+    @strings = @strings.with_indifferent_access
+    @symbols = @symbols.with_indifferent_access
+    @mixed   = @mixed.with_indifferent_access
+
+    assert_equal 'a', @strings.__send__(:convert_key, :a)
+
+    assert_equal 1, @strings.fetch('a')
+    assert_equal 1, @strings.fetch(:a.to_s)
+    assert_equal 1, @strings.fetch(:a)
+
+    hashes = { :@strings => @strings, :@symbols => @symbols, :@mixed => @mixed }
+    method_map = { :'[]' => 1, :fetch => 1, :values_at => [1],
+      :has_key? => true, :include? => true, :key? => true,
+      :member? => true }
+
+    hashes.each do |name, hash|
+      method_map.sort_by { |m| m.to_s }.each do |meth, expected|
+        assert_equal(expected, hash.__send__(meth, 'a'),
+                     "Calling #{name}.#{meth} 'a'")
+        assert_equal(expected, hash.__send__(meth, :a),
+                     "Calling #{name}.#{meth} :a")
+      end
+    end
+
+    assert_equal [1, 2], @strings.values_at('a', 'b')
+    assert_equal [1, 2], @strings.values_at(:a, :b)
+    assert_equal [1, 2], @symbols.values_at('a', 'b')
+    assert_equal [1, 2], @symbols.values_at(:a, :b)
+    assert_equal [1, 2], @mixed.values_at('a', 'b')
+    assert_equal [1, 2], @mixed.values_at(:a, :b)
+  end
+
+  def test_indifferent_reading
+    hash = HashWithIndifferentAccess.new
+    hash["a"] = 1
+    hash["b"] = true
+    hash["c"] = false
+    hash["d"] = nil
+
+    assert_equal 1, hash[:a]
+    assert_equal true, hash[:b]
+    assert_equal false, hash[:c]
+    assert_equal nil, hash[:d]
+    assert_equal nil, hash[:e]
+  end
+
+  def test_indifferent_reading_with_nonnil_default
+    hash = HashWithIndifferentAccess.new(1)
+    hash["a"] = 1
+    hash["b"] = true
+    hash["c"] = false
+    hash["d"] = nil
+
+    assert_equal 1, hash[:a]
+    assert_equal true, hash[:b]
+    assert_equal false, hash[:c]
+    assert_equal nil, hash[:d]
+    assert_equal 1, hash[:e]
+  end
+
+  def test_indifferent_writing
+    hash = HashWithIndifferentAccess.new
+    hash[:a] = 1
+    hash['b'] = 2
+    hash[3] = 3
+
+    assert_equal hash['a'], 1
+    assert_equal hash['b'], 2
+    assert_equal hash[:a], 1
+    assert_equal hash[:b], 2
+    assert_equal hash[3], 3
+  end
+
+  def test_indifferent_update
+    hash = HashWithIndifferentAccess.new
+    hash[:a] = 'a'
+    hash['b'] = 'b'
+
+    updated_with_strings = hash.update(@strings)
+    updated_with_symbols = hash.update(@symbols)
+    updated_with_mixed = hash.update(@mixed)
+
+    assert_equal updated_with_strings[:a], 1
+    assert_equal updated_with_strings['a'], 1
+    assert_equal updated_with_strings['b'], 2
+
+    assert_equal updated_with_symbols[:a], 1
+    assert_equal updated_with_symbols['b'], 2
+    assert_equal updated_with_symbols[:b], 2
+
+    assert_equal updated_with_mixed[:a], 1
+    assert_equal updated_with_mixed['b'], 2
+
+    assert [updated_with_strings, updated_with_symbols, updated_with_mixed].all? { |h| h.keys.size == 2 }
+  end
+
+  def test_update_with_to_hash_conversion
+    hash = HashWithIndifferentAccess.new
+    hash.update HashByConversion.new({ :a => 1 })
+    assert_equal hash['a'], 1
+  end
+
+  def test_indifferent_merging
+    hash = HashWithIndifferentAccess.new
+    hash[:a] = 'failure'
+    hash['b'] = 'failure'
+
+    other = { 'a' => 1, :b => 2 }
+
+    merged = hash.merge(other)
+
+    assert_equal HashWithIndifferentAccess, merged.class
+    assert_equal 1, merged[:a]
+    assert_equal 2, merged['b']
+
+    hash.update(other)
+
+    assert_equal 1, hash[:a]
+    assert_equal 2, hash['b']
+  end
+
+  def test_merge_with_to_hash_conversion
+    hash = HashWithIndifferentAccess.new
+    merged = hash.merge HashByConversion.new({ :a => 1 })
+    assert_equal merged['a'], 1
+  end
+
+  def test_indifferent_replace
+    hash = HashWithIndifferentAccess.new
+    hash[:a] = 42
+
+    replaced = hash.replace(b: 12)
+
+    assert hash.key?('b')
+    assert !hash.key?(:a)
+    assert_equal 12, hash[:b]
+    assert_same hash, replaced
+  end
+
+  def test_replace_with_to_hash_conversion
+    hash = HashWithIndifferentAccess.new
+    hash[:a] = 42
+
+    replaced = hash.replace(HashByConversion.new(b: 12))
+
+    assert hash.key?('b')
+    assert !hash.key?(:a)
+    assert_equal 12, hash[:b]
+    assert_same hash, replaced
+  end
+
+  def test_indifferent_merging_with_block
+    hash = HashWithIndifferentAccess.new
+    hash[:a] = 1
+    hash['b'] = 3
+
+    other = { 'a' => 4, :b => 2, 'c' => 10 }
+
+    merged = hash.merge(other) { |key, old, new| old > new ? old : new }
+
+    assert_equal HashWithIndifferentAccess, merged.class
+    assert_equal 4, merged[:a]
+    assert_equal 3, merged['b']
+    assert_equal 10, merged[:c]
+
+    other_indifferent = HashWithIndifferentAccess.new('a' => 9, :b => 2)
+
+    merged = hash.merge(other_indifferent) { |key, old, new| old + new }
+
+    assert_equal HashWithIndifferentAccess, merged.class
+    assert_equal 10, merged[:a]
+    assert_equal 5, merged[:b]
+  end
+
+  def test_indifferent_reverse_merging
+    hash = HashWithIndifferentAccess.new('some' => 'value', 'other' => 'value')
+    hash.reverse_merge!(:some => 'noclobber', :another => 'clobber')
+    assert_equal 'value', hash[:some]
+    assert_equal 'clobber', hash[:another]
+  end
+
+  def test_indifferent_deleting
+    get_hash = proc{ { :a => 'foo' }.with_indifferent_access }
+    hash = get_hash.call
+    assert_equal hash.delete(:a), 'foo'
+    assert_equal hash.delete(:a), nil
+    hash = get_hash.call
+    assert_equal hash.delete('a'), 'foo'
+    assert_equal hash.delete('a'), nil
+  end
+
+  def test_indifferent_select
+    hash = ActiveSupport::HashWithIndifferentAccess.new(@strings).select {|k,v| v == 1}
+
+    assert_equal({ 'a' => 1 }, hash)
+    assert_instance_of ActiveSupport::HashWithIndifferentAccess, hash
+  end
+
+  def test_indifferent_select_returns_a_hash_when_unchanged
+    hash = ActiveSupport::HashWithIndifferentAccess.new(@strings).select {|k,v| true}
+
+    assert_instance_of ActiveSupport::HashWithIndifferentAccess, hash
+  end
+
+  def test_indifferent_select_bang
+    indifferent_strings = ActiveSupport::HashWithIndifferentAccess.new(@strings)
+    indifferent_strings.select! {|k,v| v == 1}
+
+    assert_equal({ 'a' => 1 }, indifferent_strings)
+    assert_instance_of ActiveSupport::HashWithIndifferentAccess, indifferent_strings
+  end
+
+  def test_indifferent_reject
+    hash = ActiveSupport::HashWithIndifferentAccess.new(@strings).reject {|k,v| v != 1}
+
+    assert_equal({ 'a' => 1 }, hash)
+    assert_instance_of ActiveSupport::HashWithIndifferentAccess, hash
+  end
+
+  def test_indifferent_reject_bang
+    indifferent_strings = ActiveSupport::HashWithIndifferentAccess.new(@strings)
+    indifferent_strings.reject! {|k,v| v != 1}
+
+    assert_equal({ 'a' => 1 }, indifferent_strings)
+    assert_instance_of ActiveSupport::HashWithIndifferentAccess, indifferent_strings
+  end
+
+  def test_indifferent_to_hash
+    # Should convert to a Hash with String keys.
+    assert_equal @strings, @mixed.with_indifferent_access.to_hash
+
+    # Should preserve the default value.
+    mixed_with_default = @mixed.dup
+    mixed_with_default.default = '1234'
+    roundtrip = mixed_with_default.with_indifferent_access.to_hash
+    assert_equal @strings, roundtrip
+    assert_equal '1234', roundtrip.default
+    new_to_hash = @nested_mixed.with_indifferent_access.to_hash
+    assert_not new_to_hash.instance_of?(HashWithIndifferentAccess)
+    assert_not new_to_hash["a"].instance_of?(HashWithIndifferentAccess)
+    assert_not new_to_hash["a"]["b"].instance_of?(HashWithIndifferentAccess)
+  end
+
+  def test_lookup_returns_the_same_object_that_is_stored_in_hash_indifferent_access
+    hash = HashWithIndifferentAccess.new {|h, k| h[k] = []}
+    hash[:a] << 1
+
+    assert_equal [1], hash[:a]
+  end
+
+  def test_with_indifferent_access_has_no_side_effects_on_existing_hash
+    hash = {content: [{:foo => :bar, 'bar' => 'baz'}]}
+    hash.with_indifferent_access
+
+    assert_equal [:foo, "bar"], hash[:content].first.keys
+  end
+
+  def test_indifferent_hash_with_array_of_hashes
+    hash = { "urls" => { "url" => [ { "address" => "1" }, { "address" => "2" } ] }}.with_indifferent_access
+    assert_equal "1", hash[:urls][:url].first[:address]
+
+    hash = hash.to_hash
+    assert_not hash.instance_of?(HashWithIndifferentAccess)
+    assert_not hash["urls"].instance_of?(HashWithIndifferentAccess)
+    assert_not hash["urls"]["url"].first.instance_of?(HashWithIndifferentAccess)
+  end
+
+  def test_should_preserve_array_subclass_when_value_is_array
+    array = SubclassingArray.new
+    array << { "address" => "1" }
+    hash = { "urls" => { "url" => array }}.with_indifferent_access
+    assert_equal SubclassingArray, hash[:urls][:url].class
+  end
+
+  def test_should_preserve_array_class_when_hash_value_is_frozen_array
+    array = SubclassingArray.new
+    array << { "address" => "1" }
+    hash = { "urls" => { "url" => array.freeze }}.with_indifferent_access
+    assert_equal SubclassingArray, hash[:urls][:url].class
+  end
+
+  def test_stringify_and_symbolize_keys_on_indifferent_preserves_hash
+    h = HashWithIndifferentAccess.new
+    h[:first] = 1
+    h = h.stringify_keys
+    assert_equal 1, h['first']
+    h = HashWithIndifferentAccess.new
+    h['first'] = 1
+    h = h.symbolize_keys
+    assert_equal 1, h[:first]
+  end
+
+  def test_deep_stringify_and_deep_symbolize_keys_on_indifferent_preserves_hash
+    h = HashWithIndifferentAccess.new
+    h[:first] = 1
+    h = h.deep_stringify_keys
+    assert_equal 1, h['first']
+    h = HashWithIndifferentAccess.new
+    h['first'] = 1
+    h = h.deep_symbolize_keys
+    assert_equal 1, h[:first]
+  end
+
+  def test_to_options_on_indifferent_preserves_hash
+    h = HashWithIndifferentAccess.new
+    h['first'] = 1
+    h.to_options!
+    assert_equal 1, h['first']
+  end
+
+  def test_indifferent_subhashes
+    h = {'user' => {'id' => 5}}.with_indifferent_access
+    ['user', :user].each {|user| [:id, 'id'].each {|id| assert_equal 5, h[user][id], "h[#{user.inspect}][#{id.inspect}] should be 5"}}
+
+    h = {:user => {:id => 5}}.with_indifferent_access
+    ['user', :user].each {|user| [:id, 'id'].each {|id| assert_equal 5, h[user][id], "h[#{user.inspect}][#{id.inspect}] should be 5"}}
+  end
+
+  def test_indifferent_duplication
+    # Should preserve default value
+    h = HashWithIndifferentAccess.new
+    h.default = '1234'
+    assert_equal h.default, h.dup.default
+
+    # Should preserve class for subclasses
+    h = IndifferentHash.new
+    assert_equal h.class, h.dup.class
+  end
+
+  def test_assert_valid_keys
+    assert_nothing_raised do
+      { :failure => "stuff", :funny => "business" }.assert_valid_keys([ :failure, :funny ])
+      { :failure => "stuff", :funny => "business" }.assert_valid_keys(:failure, :funny)
+    end
+
+    exception = assert_raise ArgumentError do
+      { :failore => "stuff", :funny => "business" }.assert_valid_keys([ :failure, :funny ])
+    end
+    assert_equal "Unknown key: :failore. Valid keys are: :failure, :funny", exception.message
+
+    exception = assert_raise ArgumentError do
+      { :failore => "stuff", :funny => "business" }.assert_valid_keys(:failure, :funny)
+    end
+    assert_equal "Unknown key: :failore. Valid keys are: :failure, :funny", exception.message
+  end
+
+  def test_assorted_keys_not_stringified
+    original = {Object.new => 2, 1 => 2, [] => true}
+    indiff = original.with_indifferent_access
+    assert(!indiff.keys.any? {|k| k.kind_of? String}, "A key was converted to a string!")
+  end
+
+  def test_deep_merge
+    hash_1 = { :a => "a", :b => "b", :c => { :c1 => "c1", :c2 => "c2", :c3 => { :d1 => "d1" } } }
+    hash_2 = { :a => 1, :c => { :c1 => 2, :c3 => { :d2 => "d2" } } }
+    expected = { :a => 1, :b => "b", :c => { :c1 => 2, :c2 => "c2", :c3 => { :d1 => "d1", :d2 => "d2" } } }
+    assert_equal expected, hash_1.deep_merge(hash_2)
+
+    hash_1.deep_merge!(hash_2)
+    assert_equal expected, hash_1
+  end
+
+  def test_deep_merge_with_block
+    hash_1 = { :a => "a", :b => "b", :c => { :c1 => "c1", :c2 => "c2", :c3 => { :d1 => "d1" } } }
+    hash_2 = { :a => 1, :c => { :c1 => 2, :c3 => { :d2 => "d2" } } }
+    expected = { :a => [:a, "a", 1], :b => "b", :c => { :c1 => [:c1, "c1", 2], :c2 => "c2", :c3 => { :d1 => "d1", :d2 => "d2" } } }
+    assert_equal(expected, hash_1.deep_merge(hash_2) { |k,o,n| [k, o, n] })
+
+    hash_1.deep_merge!(hash_2) { |k,o,n| [k, o, n] }
+    assert_equal expected, hash_1
+  end
+
+  def test_deep_merge_on_indifferent_access
+    hash_1 = HashWithIndifferentAccess.new({ :a => "a", :b => "b", :c => { :c1 => "c1", :c2 => "c2", :c3 => { :d1 => "d1" } } })
+    hash_2 = HashWithIndifferentAccess.new({ :a => 1, :c => { :c1 => 2, :c3 => { :d2 => "d2" } } })
+    hash_3 = { :a => 1, :c => { :c1 => 2, :c3 => { :d2 => "d2" } } }
+    expected = { "a" => 1, "b" => "b", "c" => { "c1" => 2, "c2" => "c2", "c3" => { "d1" => "d1", "d2" => "d2" } } }
+    assert_equal expected, hash_1.deep_merge(hash_2)
+    assert_equal expected, hash_1.deep_merge(hash_3)
+
+    hash_1.deep_merge!(hash_2)
+    assert_equal expected, hash_1
+  end
+
+  def test_store_on_indifferent_access
+    hash = HashWithIndifferentAccess.new
+    hash.store(:test1, 1)
+    hash.store('test1', 11)
+    hash[:test2] = 2
+    hash['test2'] = 22
+    expected = { "test1" => 11, "test2" => 22 }
+    assert_equal expected, hash
+  end
+
+  def test_constructor_on_indifferent_access
+    hash = HashWithIndifferentAccess[:foo, 1]
+    assert_equal 1, hash[:foo]
+    assert_equal 1, hash['foo']
+    hash[:foo] = 3
+    assert_equal 3, hash[:foo]
+    assert_equal 3, hash['foo']
+  end
+
+  def test_reverse_merge
+    defaults = { :a => "x", :b => "y", :c => 10 }.freeze
+    options  = { :a => 1, :b => 2 }
+    expected = { :a => 1, :b => 2, :c => 10 }
+
+    # Should merge defaults into options, creating a new hash.
+    assert_equal expected, options.reverse_merge(defaults)
+    assert_not_equal expected, options
+
+    # Should merge! defaults into options, replacing options.
+    merged = options.dup
+    assert_equal expected, merged.reverse_merge!(defaults)
+    assert_equal expected, merged
+
+    # Should be an alias for reverse_merge!
+    merged = options.dup
+    assert_equal expected, merged.reverse_update(defaults)
+    assert_equal expected, merged
+  end
+
+  def test_slice
+    original = { :a => 'x', :b => 'y', :c => 10 }
+    expected = { :a => 'x', :b => 'y' }
+
+    # Should return a new hash with only the given keys.
+    assert_equal expected, original.slice(:a, :b)
+    assert_not_equal expected, original
+  end
+
+  def test_slice_inplace
+    original = { :a => 'x', :b => 'y', :c => 10 }
+    expected = { :c => 10 }
+
+    # Should replace the hash with only the given keys.
+    assert_equal expected, original.slice!(:a, :b)
+  end
+
+  def test_slice_with_an_array_key
+    original = { :a => 'x', :b => 'y', :c => 10, [:a, :b] => "an array key" }
+    expected = { [:a, :b] => "an array key", :c => 10 }
+
+    # Should return a new hash with only the given keys when given an array key.
+    assert_equal expected, original.slice([:a, :b], :c)
+    assert_not_equal expected, original
+  end
+
+  def test_slice_inplace_with_an_array_key
+    original = { :a => 'x', :b => 'y', :c => 10, [:a, :b] => "an array key" }
+    expected = { :a => 'x', :b => 'y' }
+
+    # Should replace the hash with only the given keys when given an array key.
+    assert_equal expected, original.slice!([:a, :b], :c)
+  end
+
+  def test_slice_with_splatted_keys
+    original = { :a => 'x', :b => 'y', :c => 10, [:a, :b] => "an array key" }
+    expected = { :a => 'x', :b => "y" }
+
+    # Should grab each of the splatted keys.
+    assert_equal expected, original.slice(*[:a, :b])
+  end
+
+  def test_indifferent_slice
+    original = { :a => 'x', :b => 'y', :c => 10 }.with_indifferent_access
+    expected = { :a => 'x', :b => 'y' }.with_indifferent_access
+
+    [['a', 'b'], [:a, :b]].each do |keys|
+      # Should return a new hash with only the given keys.
+      assert_equal expected, original.slice(*keys), keys.inspect
+      assert_not_equal expected, original
+    end
+  end
+
+  def test_indifferent_slice_inplace
+    original = { :a => 'x', :b => 'y', :c => 10 }.with_indifferent_access
+    expected = { :c => 10 }.with_indifferent_access
+
+    [['a', 'b'], [:a, :b]].each do |keys|
+      # Should replace the hash with only the given keys.
+      copy = original.dup
+      assert_equal expected, copy.slice!(*keys)
+    end
+  end
+
+  def test_indifferent_slice_access_with_symbols
+    original = {'login' => 'bender', 'password' => 'shiny', 'stuff' => 'foo'}
+    original = original.with_indifferent_access
+
+    slice = original.slice(:login, :password)
+
+    assert_equal 'bender', slice[:login]
+    assert_equal 'bender', slice['login']
+  end
+
+  def test_slice_bang_does_not_override_default
+    hash = Hash.new(0)
+    hash.update(a: 1, b: 2)
+
+    hash.slice!(:a)
+
+    assert_equal 0, hash[:c]
+  end
+
+  def test_slice_bang_does_not_override_default_proc
+    hash = Hash.new { |h, k| h[k] = [] }
+    hash.update(a: 1, b: 2)
+
+    hash.slice!(:a)
+
+    assert_equal [], hash[:c]
+  end
+
+  def test_extract
+    original = {:a => 1, :b => 2, :c => 3, :d => 4}
+    expected = {:a => 1, :b => 2}
+    remaining = {:c => 3, :d => 4}
+
+    assert_equal expected, original.extract!(:a, :b, :x)
+    assert_equal remaining, original
+  end
+
+  def test_extract_nils
+    original = {:a => nil, :b => nil}
+    expected = {:a => nil}
+    extracted = original.extract!(:a, :x)
+
+    assert_equal expected, extracted
+    assert_equal nil, extracted[:a]
+    assert_equal nil, extracted[:x]
+  end
+
+  def test_indifferent_extract
+    original = {:a => 1, 'b' => 2, :c => 3, 'd' => 4}.with_indifferent_access
+    expected = {:a => 1, :b => 2}.with_indifferent_access
+    remaining = {:c => 3, :d => 4}.with_indifferent_access
+
+    [['a', 'b'], [:a, :b]].each do |keys|
+      copy = original.dup
+      assert_equal expected, copy.extract!(*keys)
+      assert_equal remaining, copy
+    end
+  end
+
+  def test_except
+    original = { :a => 'x', :b => 'y', :c => 10 }
+    expected = { :a => 'x', :b => 'y' }
+
+    # Should return a new hash without the given keys.
+    assert_equal expected, original.except(:c)
+    assert_not_equal expected, original
+
+    # Should replace the hash without the given keys.
+    assert_equal expected, original.except!(:c)
+    assert_equal expected, original
+  end
+
+  def test_except_with_more_than_one_argument
+    original = { :a => 'x', :b => 'y', :c => 10 }
+    expected = { :a => 'x' }
+    assert_equal expected, original.except(:b, :c)
+  end
+
+  def test_except_with_original_frozen
+    original = { :a => 'x', :b => 'y' }
+    original.freeze
+    assert_nothing_raised { original.except(:a) }
+  end
+
+  def test_except_with_mocha_expectation_on_original
+    original = { :a => 'x', :b => 'y' }
+    original.expects(:delete).never
+    original.except(:a)
+  end
+
+  def test_compact
+    hash_contain_nil_value = @symbols.merge(z: nil)
+    hash_with_only_nil_values = { a: nil, b: nil }
+    
+    h = hash_contain_nil_value.dup
+    assert_equal(@symbols, h.compact)
+    assert_equal(hash_contain_nil_value, h)
+    
+    h = hash_with_only_nil_values.dup
+    assert_equal({}, h.compact)
+    assert_equal(hash_with_only_nil_values, h)
+  end
+
+  def test_compact!
+    hash_contain_nil_value = @symbols.merge(z: nil)
+    hash_with_only_nil_values = { a: nil, b: nil }
+    
+    h = hash_contain_nil_value.dup
+    assert_equal(@symbols, h.compact!)
+    assert_equal(@symbols, h)
+    
+    h = hash_with_only_nil_values.dup
+    assert_equal({}, h.compact!)
+    assert_equal({}, h)
+  end
+
+  def test_new_with_to_hash_conversion
+    hash = HashWithIndifferentAccess.new(HashByConversion.new(a: 1))
+    assert hash.key?('a')
+    assert_equal 1, hash[:a]
+  end
+end
+
+class IWriteMyOwnXML
+  def to_xml(options = {})
+    options[:indent] ||= 2
+    xml = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
+    xml.instruct! unless options[:skip_instruct]
+    xml.level_one do
+      xml.tag!(:second_level, 'content')
+    end
+  end
+end
+
+class HashExtToParamTests < ActiveSupport::TestCase
+  class ToParam < String
+    def to_param
+      "#{self}-1"
+    end
+  end
+
+  def test_string_hash
+    assert_equal '', {}.to_param
+    assert_equal 'hello=world', { :hello => "world" }.to_param
+    assert_equal 'hello=10', { "hello" => 10 }.to_param
+    assert_equal 'hello=world&say_bye=true', {:hello => "world", "say_bye" => true}.to_param
+  end
+
+  def test_number_hash
+    assert_equal '10=20&30=40&50=60', {10 => 20, 30 => 40, 50 => 60}.to_param
+  end
+
+  def test_to_param_hash
+    assert_equal 'custom-1=param-1&custom2-1=param2-1', {ToParam.new('custom') => ToParam.new('param'), ToParam.new('custom2') => ToParam.new('param2')}.to_param
+  end
+
+  def test_to_param_hash_escapes_its_keys_and_values
+    assert_equal 'param+1=A+string+with+%2F+characters+%26+that+should+be+%3F+escaped', { 'param 1' => 'A string with / characters & that should be ? escaped' }.to_param
+  end
+
+  def test_to_param_orders_by_key_in_ascending_order
+    assert_equal 'a=2&b=1&c=0', Hash[*%w(b 1 c 0 a 2)].to_param
+  end
+end
+
+class HashToXmlTest < ActiveSupport::TestCase
+  def setup
+    @xml_options = { :root => :person, :skip_instruct => true, :indent => 0 }
+  end
+
+  def test_one_level
+    xml = { :name => "David", :street => "Paulina" }.to_xml(@xml_options)
+    assert_equal "<person>", xml.first(8)
+    assert xml.include?(%(<street>Paulina</street>))
+    assert xml.include?(%(<name>David</name>))
+  end
+
+  def test_one_level_dasherize_false
+    xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:dasherize => false))
+    assert_equal "<person>", xml.first(8)
+    assert xml.include?(%(<street_name>Paulina</street_name>))
+    assert xml.include?(%(<name>David</name>))
+  end
+
+  def test_one_level_dasherize_true
+    xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:dasherize => true))
+    assert_equal "<person>", xml.first(8)
+    assert xml.include?(%(<street-name>Paulina</street-name>))
+    assert xml.include?(%(<name>David</name>))
+  end
+
+  def test_one_level_camelize_true
+    xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:camelize => true))
+    assert_equal "<Person>", xml.first(8)
+    assert xml.include?(%(<StreetName>Paulina</StreetName>))
+    assert xml.include?(%(<Name>David</Name>))
+  end
+
+  def test_one_level_camelize_lower
+    xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:camelize => :lower))
+    assert_equal "<person>", xml.first(8)
+    assert xml.include?(%(<streetName>Paulina</streetName>))
+    assert xml.include?(%(<name>David</name>))
+  end
+
+  def test_one_level_with_types
+    xml = { :name => "David", :street => "Paulina", :age => 26, :age_in_millis => 820497600000, :moved_on => Date.new(2005, 11, 15), :resident => :yes }.to_xml(@xml_options)
+    assert_equal "<person>", xml.first(8)
+    assert xml.include?(%(<street>Paulina</street>))
+    assert xml.include?(%(<name>David</name>))
+    assert xml.include?(%(<age type="integer">26</age>))
+    assert xml.include?(%(<age-in-millis type="integer">820497600000</age-in-millis>))
+    assert xml.include?(%(<moved-on type="date">2005-11-15</moved-on>))
+    assert xml.include?(%(<resident type="symbol">yes</resident>))
+  end
+
+  def test_one_level_with_nils
+    xml = { :name => "David", :street => "Paulina", :age => nil }.to_xml(@xml_options)
+    assert_equal "<person>", xml.first(8)
+    assert xml.include?(%(<street>Paulina</street>))
+    assert xml.include?(%(<name>David</name>))
+    assert xml.include?(%(<age nil="true"/>))
+  end
+
+  def test_one_level_with_skipping_types
+    xml = { :name => "David", :street => "Paulina", :age => nil }.to_xml(@xml_options.merge(:skip_types => true))
+    assert_equal "<person>", xml.first(8)
+    assert xml.include?(%(<street>Paulina</street>))
+    assert xml.include?(%(<name>David</name>))
+    assert xml.include?(%(<age nil="true"/>))
+  end
+
+  def test_one_level_with_yielding
+    xml = { :name => "David", :street => "Paulina" }.to_xml(@xml_options) do |x|
+      x.creator("Rails")
+    end
+
+    assert_equal "<person>", xml.first(8)
+    assert xml.include?(%(<street>Paulina</street>))
+    assert xml.include?(%(<name>David</name>))
+    assert xml.include?(%(<creator>Rails</creator>))
+  end
+
+  def test_two_levels
+    xml = { :name => "David", :address => { :street => "Paulina" } }.to_xml(@xml_options)
+    assert_equal "<person>", xml.first(8)
+    assert xml.include?(%(<address><street>Paulina</street></address>))
+    assert xml.include?(%(<name>David</name>))
+  end
+
+  def test_two_levels_with_second_level_overriding_to_xml
+    xml = { :name => "David", :address => { :street => "Paulina" }, :child => IWriteMyOwnXML.new }.to_xml(@xml_options)
+    assert_equal "<person>", xml.first(8)
+    assert xml.include?(%(<address><street>Paulina</street></address>))
+    assert xml.include?(%(<level_one><second_level>content</second_level></level_one>))
+  end
+
+  def test_two_levels_with_array
+    xml = { :name => "David", :addresses => [{ :street => "Paulina" }, { :street => "Evergreen" }] }.to_xml(@xml_options)
+    assert_equal "<person>", xml.first(8)
+    assert xml.include?(%(<addresses type="array"><address>))
+    assert xml.include?(%(<address><street>Paulina</street></address>))
+    assert xml.include?(%(<address><street>Evergreen</street></address>))
+    assert xml.include?(%(<name>David</name>))
+  end
+
+  def test_three_levels_with_array
+    xml = { :name => "David", :addresses => [{ :streets => [ { :name => "Paulina" }, { :name => "Paulina" } ] } ] }.to_xml(@xml_options)
+    assert xml.include?(%(<addresses type="array"><address><streets type="array"><street><name>))
+  end
+
+  def test_timezoned_attributes
+    xml = {
+      :created_at => Time.utc(1999,2,2),
+      :local_created_at => Time.utc(1999,2,2).in_time_zone('Eastern Time (US & Canada)')
+    }.to_xml(@xml_options)
+    assert_match %r{<created-at type=\"dateTime\">1999-02-02T00:00:00Z</created-at>}, xml
+    assert_match %r{<local-created-at type=\"dateTime\">1999-02-01T19:00:00-05:00</local-created-at>}, xml
+  end
+
+  def test_multiple_records_from_xml_with_attributes_other_than_type_ignores_them_without_exploding
+    topics_xml = <<-EOT
+      <topics type="array" page="1" page-count="1000" per-page="2">
+        <topic>
+          <title>The First Topic</title>
+          <author-name>David</author-name>
+          <id type="integer">1</id>
+          <approved type="boolean">false</approved>
+          <replies-count type="integer">0</replies-count>
+          <replies-close-in type="integer">2592000000</replies-close-in>
+          <written-on type="date">2003-07-16</written-on>
+          <viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
+          <content>Have a nice day</content>
+          <author-email-address>david at loudthinking.com</author-email-address>
+          <parent-id nil="true"></parent-id>
+        </topic>
+        <topic>
+          <title>The Second Topic</title>
+          <author-name>Jason</author-name>
+          <id type="integer">1</id>
+          <approved type="boolean">false</approved>
+          <replies-count type="integer">0</replies-count>
+          <replies-close-in type="integer">2592000000</replies-close-in>
+          <written-on type="date">2003-07-16</written-on>
+          <viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
+          <content>Have a nice day</content>
+          <author-email-address>david at loudthinking.com</author-email-address>
+          <parent-id></parent-id>
+        </topic>
+      </topics>
+    EOT
+
+    expected_topic_hash = {
+      :title => "The First Topic",
+      :author_name => "David",
+      :id => 1,
+      :approved => false,
+      :replies_count => 0,
+      :replies_close_in => 2592000000,
+      :written_on => Date.new(2003, 7, 16),
+      :viewed_at => Time.utc(2003, 7, 16, 9, 28),
+      :content => "Have a nice day",
+      :author_email_address => "david at loudthinking.com",
+      :parent_id => nil
+    }.stringify_keys
+
+    assert_equal expected_topic_hash, Hash.from_xml(topics_xml)["topics"].first
+  end
+
+  def test_single_record_from_xml
+    topic_xml = <<-EOT
+      <topic>
+        <title>The First Topic</title>
+        <author-name>David</author-name>
+        <id type="integer">1</id>
+        <approved type="boolean"> true </approved>
+        <replies-count type="integer">0</replies-count>
+        <replies-close-in type="integer">2592000000</replies-close-in>
+        <written-on type="date">2003-07-16</written-on>
+        <viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
+        <author-email-address>david at loudthinking.com</author-email-address>
+        <parent-id></parent-id>
+        <ad-revenue type="decimal">1.5</ad-revenue>
+        <optimum-viewing-angle type="float">135</optimum-viewing-angle>
+      </topic>
+    EOT
+
+    expected_topic_hash = {
+      :title => "The First Topic",
+      :author_name => "David",
+      :id => 1,
+      :approved => true,
+      :replies_count => 0,
+      :replies_close_in => 2592000000,
+      :written_on => Date.new(2003, 7, 16),
+      :viewed_at => Time.utc(2003, 7, 16, 9, 28),
+      :author_email_address => "david at loudthinking.com",
+      :parent_id => nil,
+      :ad_revenue => BigDecimal("1.50"),
+      :optimum_viewing_angle => 135.0,
+    }.stringify_keys
+
+    assert_equal expected_topic_hash, Hash.from_xml(topic_xml)["topic"]
+  end
+
+  def test_single_record_from_xml_with_nil_values
+    topic_xml = <<-EOT
+      <topic>
+        <title></title>
+        <id type="integer"></id>
+        <approved type="boolean"></approved>
+        <written-on type="date"></written-on>
+        <viewed-at type="datetime"></viewed-at>
+        <parent-id></parent-id>
+      </topic>
+    EOT
+
+    expected_topic_hash = {
+      :title      => nil,
+      :id         => nil,
+      :approved   => nil,
+      :written_on => nil,
+      :viewed_at  => nil,
+      :parent_id  => nil
+    }.stringify_keys
+
+    assert_equal expected_topic_hash, Hash.from_xml(topic_xml)["topic"]
+  end
+
+  def test_multiple_records_from_xml
+    topics_xml = <<-EOT
+      <topics type="array">
+        <topic>
+          <title>The First Topic</title>
+          <author-name>David</author-name>
+          <id type="integer">1</id>
+          <approved type="boolean">false</approved>
+          <replies-count type="integer">0</replies-count>
+          <replies-close-in type="integer">2592000000</replies-close-in>
+          <written-on type="date">2003-07-16</written-on>
+          <viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
+          <content>Have a nice day</content>
+          <author-email-address>david at loudthinking.com</author-email-address>
+          <parent-id nil="true"></parent-id>
+        </topic>
+        <topic>
+          <title>The Second Topic</title>
+          <author-name>Jason</author-name>
+          <id type="integer">1</id>
+          <approved type="boolean">false</approved>
+          <replies-count type="integer">0</replies-count>
+          <replies-close-in type="integer">2592000000</replies-close-in>
+          <written-on type="date">2003-07-16</written-on>
+          <viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
+          <content>Have a nice day</content>
+          <author-email-address>david at loudthinking.com</author-email-address>
+          <parent-id></parent-id>
+        </topic>
+      </topics>
+    EOT
+
+    expected_topic_hash = {
+      :title => "The First Topic",
+      :author_name => "David",
+      :id => 1,
+      :approved => false,
+      :replies_count => 0,
+      :replies_close_in => 2592000000,
+      :written_on => Date.new(2003, 7, 16),
+      :viewed_at => Time.utc(2003, 7, 16, 9, 28),
+      :content => "Have a nice day",
+      :author_email_address => "david at loudthinking.com",
+      :parent_id => nil
+    }.stringify_keys
+
+    assert_equal expected_topic_hash, Hash.from_xml(topics_xml)["topics"].first
+  end
+
+  def test_single_record_from_xml_with_attributes_other_than_type
+    topic_xml = <<-EOT
+    <rsp stat="ok">
+      <photos page="1" pages="1" perpage="100" total="16">
+        <photo id="175756086" owner="55569174 at N00" secret="0279bf37a1" server="76" title="Colored Pencil PhotoBooth Fun" ispublic="1" isfriend="0" isfamily="0"/>
+      </photos>
+    </rsp>
+    EOT
+
+    expected_topic_hash = {
+      :id => "175756086",
+      :owner => "55569174 at N00",
+      :secret => "0279bf37a1",
+      :server => "76",
+      :title => "Colored Pencil PhotoBooth Fun",
+      :ispublic => "1",
+      :isfriend => "0",
+      :isfamily => "0",
+    }.stringify_keys
+
+    assert_equal expected_topic_hash, Hash.from_xml(topic_xml)["rsp"]["photos"]["photo"]
+  end
+
+  def test_all_caps_key_from_xml
+    test_xml = <<-EOT
+      <ABC3XYZ>
+        <TEST>Lorem Ipsum</TEST>
+      </ABC3XYZ>
+    EOT
+
+    expected_hash = {
+      "ABC3XYZ" => {
+        "TEST" => "Lorem Ipsum"
+      }
+    }
+
+    assert_equal expected_hash, Hash.from_xml(test_xml)
+  end
+
+  def test_empty_array_from_xml
+    blog_xml = <<-XML
+      <blog>
+        <posts type="array"></posts>
+      </blog>
+    XML
+    expected_blog_hash = {"blog" => {"posts" => []}}
+    assert_equal expected_blog_hash, Hash.from_xml(blog_xml)
+  end
+
+  def test_empty_array_with_whitespace_from_xml
+    blog_xml = <<-XML
+      <blog>
+        <posts type="array">
+        </posts>
+      </blog>
+    XML
+    expected_blog_hash = {"blog" => {"posts" => []}}
+    assert_equal expected_blog_hash, Hash.from_xml(blog_xml)
+  end
+
+  def test_array_with_one_entry_from_xml
+    blog_xml = <<-XML
+      <blog>
+        <posts type="array">
+          <post>a post</post>
+        </posts>
+      </blog>
+    XML
+    expected_blog_hash = {"blog" => {"posts" => ["a post"]}}
+    assert_equal expected_blog_hash, Hash.from_xml(blog_xml)
+  end
+
+  def test_array_with_multiple_entries_from_xml
+    blog_xml = <<-XML
+      <blog>
+        <posts type="array">
+          <post>a post</post>
+          <post>another post</post>
+        </posts>
+      </blog>
+    XML
+    expected_blog_hash = {"blog" => {"posts" => ["a post", "another post"]}}
+    assert_equal expected_blog_hash, Hash.from_xml(blog_xml)
+  end
+
+  def test_file_from_xml
+    blog_xml = <<-XML
+      <blog>
+        <logo type="file" name="logo.png" content_type="image/png">
+        </logo>
+      </blog>
+    XML
+    hash = Hash.from_xml(blog_xml)
+    assert hash.has_key?('blog')
+    assert hash['blog'].has_key?('logo')
+
+    file = hash['blog']['logo']
+    assert_equal 'logo.png', file.original_filename
+    assert_equal 'image/png', file.content_type
+  end
+
+  def test_file_from_xml_with_defaults
+    blog_xml = <<-XML
+      <blog>
+        <logo type="file">
+        </logo>
+      </blog>
+    XML
+    file = Hash.from_xml(blog_xml)['blog']['logo']
+    assert_equal 'untitled', file.original_filename
+    assert_equal 'application/octet-stream', file.content_type
+  end
+
+  def test_tag_with_attrs_and_whitespace
+    xml = <<-XML
+      <blog name="bacon is the best">
+      </blog>
+    XML
+    hash = Hash.from_xml(xml)
+    assert_equal "bacon is the best", hash['blog']['name']
+  end
+
+  def test_empty_cdata_from_xml
+    xml = "<data><![CDATA[]]></data>"
+
+    assert_equal "", Hash.from_xml(xml)["data"]
+  end
+
+  def test_xsd_like_types_from_xml
+    bacon_xml = <<-EOT
+    <bacon>
+      <weight type="double">0.5</weight>
+      <price type="decimal">12.50</price>
+      <chunky type="boolean"> 1 </chunky>
+      <expires-at type="dateTime">2007-12-25T12:34:56+0000</expires-at>
+      <notes type="string"></notes>
+      <illustration type="base64Binary">YmFiZS5wbmc=</illustration>
+      <caption type="binary" encoding="base64">VGhhdCdsbCBkbywgcGlnLg==</caption>
+    </bacon>
+    EOT
+
+    expected_bacon_hash = {
+      :weight => 0.5,
+      :chunky => true,
+      :price => BigDecimal("12.50"),
+      :expires_at => Time.utc(2007,12,25,12,34,56),
+      :notes => "",
+      :illustration => "babe.png",
+      :caption => "That'll do, pig."
+    }.stringify_keys
+
+    assert_equal expected_bacon_hash, Hash.from_xml(bacon_xml)["bacon"]
+  end
+
+  def test_type_trickles_through_when_unknown
+    product_xml = <<-EOT
+    <product>
+      <weight type="double">0.5</weight>
+      <image type="ProductImage"><filename>image.gif</filename></image>
+
+    </product>
+    EOT
+
+    expected_product_hash = {
+      :weight => 0.5,
+      :image => {'type' => 'ProductImage', 'filename' => 'image.gif' },
+    }.stringify_keys
+
+    assert_equal expected_product_hash, Hash.from_xml(product_xml)["product"]
+  end
+
+  def test_from_xml_raises_on_disallowed_type_attributes
+    assert_raise ActiveSupport::XMLConverter::DisallowedType do
+      Hash.from_xml '<product><name type="foo">value</name></product>', %w(foo)
+    end
+  end
+
+  def test_from_xml_disallows_symbol_and_yaml_types_by_default
+    assert_raise ActiveSupport::XMLConverter::DisallowedType do
+      Hash.from_xml '<product><name type="symbol">value</name></product>'
+    end
+
+    assert_raise ActiveSupport::XMLConverter::DisallowedType do
+      Hash.from_xml '<product><name type="yaml">value</name></product>'
+    end
+  end
+
+  def test_from_trusted_xml_allows_symbol_and_yaml_types
+    expected = { 'product' => { 'name' => :value }}
+    assert_equal expected, Hash.from_trusted_xml('<product><name type="symbol">value</name></product>')
+    assert_equal expected, Hash.from_trusted_xml('<product><name type="yaml">:value</name></product>')
+  end
+
+  def test_should_use_default_value_for_unknown_key
+    hash_wia = HashWithIndifferentAccess.new(3)
+    assert_equal 3, hash_wia[:new_key]
+  end
+
+  def test_should_use_default_value_if_no_key_is_supplied
+    hash_wia = HashWithIndifferentAccess.new(3)
+    assert_equal 3, hash_wia.default
+  end
+
+  def test_should_nil_if_no_default_value_is_supplied
+    hash_wia = HashWithIndifferentAccess.new
+    assert_nil hash_wia.default
+  end
+
+  def test_should_return_dup_for_with_indifferent_access
+    hash_wia = HashWithIndifferentAccess.new
+    assert_equal hash_wia, hash_wia.with_indifferent_access
+    assert_not_same hash_wia, hash_wia.with_indifferent_access
+  end
+
+  def test_should_copy_the_default_value_when_converting_to_hash_with_indifferent_access
+    hash = Hash.new(3)
+    hash_wia = hash.with_indifferent_access
+    assert_equal 3, hash_wia.default
+  end
+
+  # The XML builder seems to fail miserably when trying to tag something
+  # with the same name as a Kernel method (throw, test, loop, select ...)
+  def test_kernel_method_names_to_xml
+    hash     = { :throw => { :ball => 'red' } }
+    expected = '<person><throw><ball>red</ball></throw></person>'
+
+    assert_nothing_raised do
+      assert_equal expected, hash.to_xml(@xml_options)
+    end
+  end
+
+  def test_empty_string_works_for_typecast_xml_value
+    assert_nothing_raised do
+      ActiveSupport::XMLConverter.new("").to_h
+    end
+  end
+
+  def test_escaping_to_xml
+    hash = {
+      :bare_string        => 'First & Last Name',
+      :pre_escaped_string => 'First & Last Name'
+    }.stringify_keys
+
+    expected_xml = '<person><bare-string>First & Last Name</bare-string><pre-escaped-string>First &amp; Last Name</pre-escaped-string></person>'
+    assert_equal expected_xml, hash.to_xml(@xml_options)
+  end
+
+  def test_unescaping_from_xml
+    xml_string = '<person><bare-string>First & Last Name</bare-string><pre-escaped-string>First &amp; Last Name</pre-escaped-string></person>'
+    expected_hash = {
+      :bare_string        => 'First & Last Name',
+      :pre_escaped_string => 'First & Last Name'
+    }.stringify_keys
+    assert_equal expected_hash, Hash.from_xml(xml_string)['person']
+  end
+
+  def test_roundtrip_to_xml_from_xml
+    hash = {
+      :bare_string        => 'First & Last Name',
+      :pre_escaped_string => 'First & Last Name'
+    }.stringify_keys
+
+    assert_equal hash, Hash.from_xml(hash.to_xml(@xml_options))['person']
+  end
+
+  def test_datetime_xml_type_with_utc_time
+    alert_xml = <<-XML
+      <alert>
+        <alert_at type="datetime">2008-02-10T15:30:45Z</alert_at>
+      </alert>
+    XML
+    alert_at = Hash.from_xml(alert_xml)['alert']['alert_at']
+    assert alert_at.utc?
+    assert_equal Time.utc(2008, 2, 10, 15, 30, 45), alert_at
+  end
+
+  def test_datetime_xml_type_with_non_utc_time
+    alert_xml = <<-XML
+      <alert>
+        <alert_at type="datetime">2008-02-10T10:30:45-05:00</alert_at>
+      </alert>
+    XML
+    alert_at = Hash.from_xml(alert_xml)['alert']['alert_at']
+    assert alert_at.utc?
+    assert_equal Time.utc(2008, 2, 10, 15, 30, 45), alert_at
+  end
+
+  def test_datetime_xml_type_with_far_future_date
+    alert_xml = <<-XML
+      <alert>
+        <alert_at type="datetime">2050-02-10T15:30:45Z</alert_at>
+      </alert>
+    XML
+    alert_at = Hash.from_xml(alert_xml)['alert']['alert_at']
+    assert alert_at.utc?
+    assert_equal 2050,  alert_at.year
+    assert_equal 2,     alert_at.month
+    assert_equal 10,    alert_at.day
+    assert_equal 15,    alert_at.hour
+    assert_equal 30,    alert_at.min
+    assert_equal 45,    alert_at.sec
+  end
+
+  def test_to_xml_dups_options
+    options = {:skip_instruct => true}
+    {}.to_xml(options)
+    # :builder, etc, shouldn't be added to options
+    assert_equal({:skip_instruct => true}, options)
+  end
+
+  def test_expansion_count_is_limited
+    expected =
+      case ActiveSupport::XmlMini.backend.name
+      when 'ActiveSupport::XmlMini_REXML';        RuntimeError
+      when 'ActiveSupport::XmlMini_Nokogiri';     Nokogiri::XML::SyntaxError
+      when 'ActiveSupport::XmlMini_NokogiriSAX';  RuntimeError
+      when 'ActiveSupport::XmlMini_LibXML';       LibXML::XML::Error
+      when 'ActiveSupport::XmlMini_LibXMLSAX';    LibXML::XML::Error
+      end
+
+    assert_raise expected do
+      attack_xml = <<-EOT
+      <?xml version="1.0" encoding="UTF-8"?>
+      <!DOCTYPE member [
+        <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
+        <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
+        <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
+        <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
+        <!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
+        <!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
+        <!ENTITY g "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
+      ]>
+      <member>
+      &a;
+      </member>
+      EOT
+      Hash.from_xml(attack_xml)
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/integer_ext_test.rb b/app/server/vendor/activesupport/test/core_ext/integer_ext_test.rb
new file mode 100644
index 0000000..41736fb
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/integer_ext_test.rb
@@ -0,0 +1,30 @@
+require 'abstract_unit'
+require 'active_support/core_ext/integer'
+
+class IntegerExtTest < ActiveSupport::TestCase
+  PRIME = 22953686867719691230002707821868552601124472329079
+
+  def test_multiple_of
+    [ -7, 0, 7, 14 ].each { |i| assert i.multiple_of?(7) }
+    [ -7, 7, 14 ].each { |i| assert ! i.multiple_of?(6) }
+
+    # test the 0 edge case
+    assert 0.multiple_of?(0)
+    assert !5.multiple_of?(0)
+
+    # test with a prime
+    [2, 3, 5, 7].each { |i| assert !PRIME.multiple_of?(i) }
+  end
+
+  def test_ordinalize
+    # These tests are mostly just to ensure that the ordinalize method exists.
+    # Its results are tested comprehensively in the inflector test cases.
+    assert_equal '1st', 1.ordinalize
+    assert_equal '8th', 8.ordinalize
+  end
+
+  def test_ordinal
+    assert_equal 'st', 1.ordinal
+    assert_equal 'th', 8.ordinal
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/kernel/concern_test.rb b/app/server/vendor/activesupport/test/core_ext/kernel/concern_test.rb
new file mode 100644
index 0000000..9b1fdda
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/kernel/concern_test.rb
@@ -0,0 +1,12 @@
+require 'abstract_unit'
+require 'active_support/core_ext/kernel/concern'
+
+class KernelConcernTest < ActiveSupport::TestCase
+  def test_may_be_defined_at_toplevel
+    mod = ::TOPLEVEL_BINDING.eval 'concern(:ToplevelConcern) { }'
+    assert_equal mod, ::ToplevelConcern
+    assert_kind_of ActiveSupport::Concern, ::ToplevelConcern
+    assert !Object.ancestors.include?(::ToplevelConcern), mod.ancestors.inspect
+    Object.send :remove_const, :ToplevelConcern
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/kernel_test.rb b/app/server/vendor/activesupport/test/core_ext/kernel_test.rb
new file mode 100644
index 0000000..18b2511
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/kernel_test.rb
@@ -0,0 +1,140 @@
+require 'abstract_unit'
+require 'active_support/core_ext/kernel'
+
+class KernelTest < ActiveSupport::TestCase
+  def test_silence_warnings
+    silence_warnings { assert_nil $VERBOSE }
+    assert_equal 1234, silence_warnings { 1234 }
+  end
+
+  def test_silence_warnings_verbose_invariant
+    old_verbose = $VERBOSE
+    silence_warnings { raise }
+    flunk
+  rescue
+    assert_equal old_verbose, $VERBOSE
+  end
+
+
+  def test_enable_warnings
+    enable_warnings { assert_equal true, $VERBOSE }
+    assert_equal 1234, enable_warnings { 1234 }
+  end
+
+  def test_enable_warnings_verbose_invariant
+    old_verbose = $VERBOSE
+    enable_warnings { raise }
+    flunk
+  rescue
+    assert_equal old_verbose, $VERBOSE
+  end
+
+
+  def test_silence_stderr
+    old_stderr_position = STDERR.tell
+    silence_stderr { STDERR.puts 'hello world' }
+    assert_equal old_stderr_position, STDERR.tell
+  rescue Errno::ESPIPE
+    # Skip if we can't STDERR.tell
+  end
+
+  def test_silence_stream
+    old_stream_position = STDOUT.tell
+    silence_stream(STDOUT) { STDOUT.puts 'hello world' }
+    assert_equal old_stream_position, STDOUT.tell
+  rescue Errno::ESPIPE
+    # Skip if we can't stream.tell
+  end
+
+  def test_silence_stream_closes_file_descriptors
+    stream     = StringIO.new
+    dup_stream = StringIO.new
+    stream.stubs(:dup).returns(dup_stream)
+    dup_stream.expects(:close)
+    silence_stream(stream) { stream.puts 'hello world' }
+  end
+
+  def test_quietly
+    old_stdout_position, old_stderr_position = STDOUT.tell, STDERR.tell
+    quietly do
+      puts 'see me, feel me'
+      STDERR.puts 'touch me, heal me'
+    end
+    assert_equal old_stdout_position, STDOUT.tell
+    assert_equal old_stderr_position, STDERR.tell
+  rescue Errno::ESPIPE
+    # Skip if we can't STDERR.tell
+  end
+
+  def test_silence_stderr_with_return_value
+    assert_equal 1, silence_stderr { 1 }
+  end
+
+  def test_class_eval
+    o = Object.new
+    class << o; @x = 1; end
+    assert_equal 1, o.class_eval { @x }
+  end
+
+  def test_capture
+    assert_equal 'STDERR', capture(:stderr) { $stderr.print 'STDERR' }
+    assert_equal 'STDOUT', capture(:stdout) { print 'STDOUT' }
+    assert_equal "STDERR\n", capture(:stderr) { system('echo STDERR 1>&2') }
+    assert_equal "STDOUT\n", capture(:stdout) { system('echo STDOUT') }
+  end
+end
+
+class KernelSuppressTest < ActiveSupport::TestCase
+  def test_reraise
+    assert_raise(LoadError) do
+      suppress(ArgumentError) { raise LoadError }
+    end
+  end
+
+  def test_suppression
+    suppress(ArgumentError) { raise ArgumentError }
+    suppress(LoadError) { raise LoadError }
+    suppress(LoadError, ArgumentError) { raise LoadError }
+    suppress(LoadError, ArgumentError) { raise ArgumentError }
+  end
+end
+
+class MockStdErr
+  attr_reader :output
+  def puts(message)
+    @output ||= []
+    @output << message
+  end
+
+  def info(message)
+    puts(message)
+  end
+
+  def write(message)
+    puts(message)
+  end
+end
+
+class KernelDebuggerTest < ActiveSupport::TestCase
+  def test_debugger_not_available_message_to_stderr
+    old_stderr = $stderr
+    $stderr = MockStdErr.new
+    debugger
+    assert_match(/Debugger requested/, $stderr.output.first)
+  ensure
+    $stderr = old_stderr
+  end
+
+  def test_debugger_not_available_message_to_rails_logger
+    rails = Class.new do
+      def self.logger
+        @logger ||= MockStdErr.new
+      end
+    end
+    Object.const_set(:Rails, rails)
+    debugger
+    assert_match(/Debugger requested/, rails.logger.output.first)
+  ensure
+    Object.send(:remove_const, :Rails)
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/load_error_test.rb b/app/server/vendor/activesupport/test/core_ext/load_error_test.rb
new file mode 100644
index 0000000..31863d0
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/load_error_test.rb
@@ -0,0 +1,32 @@
+require 'abstract_unit'
+require 'active_support/core_ext/load_error'
+
+class TestMissingSourceFile < ActiveSupport::TestCase
+  def test_with_require
+    assert_raise(MissingSourceFile) { require 'no_this_file_don\'t_exist' }
+  end
+  def test_with_load
+    assert_raise(MissingSourceFile) { load 'nor_does_this_one' }
+  end
+  def test_path
+    begin load 'nor/this/one.rb'
+    rescue MissingSourceFile => e
+      assert_equal 'nor/this/one.rb', e.path
+    end
+  end
+end
+
+class TestLoadError < ActiveSupport::TestCase
+  def test_with_require
+    assert_raise(LoadError) { require 'no_this_file_don\'t_exist' }
+  end
+  def test_with_load
+    assert_raise(LoadError) { load 'nor_does_this_one' }
+  end
+  def test_path
+    begin load 'nor/this/one.rb'
+    rescue LoadError => e
+      assert_equal 'nor/this/one.rb', e.path
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/core_ext/marshal_test.rb b/app/server/vendor/activesupport/test/core_ext/marshal_test.rb
new file mode 100644
index 0000000..8f3f710
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/marshal_test.rb
@@ -0,0 +1,124 @@
+require 'abstract_unit'
+require 'active_support/core_ext/marshal'
+require 'dependencies_test_helpers'
+
+class MarshalTest < ActiveSupport::TestCase
+  include ActiveSupport::Testing::Isolation
+  include DependenciesTestHelpers
+
+  def teardown
+    ActiveSupport::Dependencies.clear
+    remove_constants(:E, :ClassFolder)
+  end
+
+  test "that Marshal#load still works" do
+    sanity_data = ["test", [1, 2, 3], {a: [1, 2, 3]}, ActiveSupport::TestCase]
+    sanity_data.each do |obj|
+      dumped = Marshal.dump(obj)
+      assert_equal Marshal.load_without_autoloading(dumped), Marshal.load(dumped)
+    end
+  end
+
+  test "that a missing class is autoloaded from string" do
+    dumped = nil
+    with_autoloading_fixtures do
+      dumped = Marshal.dump(E.new)
+    end
+
+    remove_constants(:E)
+    ActiveSupport::Dependencies.clear
+
+    with_autoloading_fixtures do
+      assert_kind_of E, Marshal.load(dumped)
+    end
+  end
+
+  test "that classes in sub modules work" do
+    dumped = nil
+    with_autoloading_fixtures do
+      dumped = Marshal.dump(ClassFolder::ClassFolderSubclass.new)
+    end
+
+    remove_constants(:ClassFolder)
+    ActiveSupport::Dependencies.clear
+
+    with_autoloading_fixtures do
+      assert_kind_of ClassFolder::ClassFolderSubclass, Marshal.load(dumped)
+    end
+  end
+
+  test "that more than one missing class is autoloaded" do
+    dumped = nil
+    with_autoloading_fixtures do
+      dumped = Marshal.dump([E.new, ClassFolder.new])
+    end
+
+    remove_constants(:E, :ClassFolder)
+    ActiveSupport::Dependencies.clear
+
+    with_autoloading_fixtures do
+      loaded = Marshal.load(dumped)
+      assert_equal 2, loaded.size
+      assert_kind_of E, loaded[0]
+      assert_kind_of ClassFolder, loaded[1]
+    end
+  end
+
+  test "that a real missing class is causing an exception" do
+    dumped = nil
+    with_autoloading_fixtures do
+      dumped = Marshal.dump(E.new)
+    end
+
+    remove_constants(:E)
+    ActiveSupport::Dependencies.clear
+
+    assert_raise(NameError) do
+      Marshal.load(dumped)
+    end
+  end
+
+  test "when first class is autoloaded and second not" do
+    dumped = nil
+    class SomeClass
+    end
+
+    with_autoloading_fixtures do
+      dumped = Marshal.dump([E.new, SomeClass.new])
+    end
+
+    remove_constants(:E)
+    self.class.send(:remove_const, :SomeClass)
+    ActiveSupport::Dependencies.clear
+
+    with_autoloading_fixtures do
+      assert_raise(NameError) do
+        Marshal.load(dumped)
+      end
+
+      assert_nothing_raised("E failed to load while we expect only SomeClass to fail loading") do
+        E.new
+      end
+
+      assert_raise(NameError, "We expected SomeClass to not be loaded but it is!") do
+        SomeClass.new
+      end
+    end
+  end
+
+  test "loading classes from files trigger autoloading" do
+    Tempfile.open("object_serializer_test") do |f|
+      with_autoloading_fixtures do
+        Marshal.dump(E.new, f)
+      end
+
+      f.rewind
+      remove_constants(:E)
+      ActiveSupport::Dependencies.clear
+
+      with_autoloading_fixtures do
+        assert_kind_of E, Marshal.load(f)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/core_ext/module/anonymous_test.rb b/app/server/vendor/activesupport/test/core_ext/module/anonymous_test.rb
new file mode 100644
index 0000000..cb556af
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/module/anonymous_test.rb
@@ -0,0 +1,14 @@
+require 'abstract_unit'
+require 'active_support/core_ext/module/anonymous'
+
+class AnonymousTest < ActiveSupport::TestCase
+  test "an anonymous class or module are anonymous" do
+    assert Module.new.anonymous?
+    assert Class.new.anonymous?
+  end
+
+  test "a named class or module are not anonymous" do
+    assert !Kernel.anonymous?
+    assert !Object.anonymous?
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/core_ext/module/attr_internal_test.rb b/app/server/vendor/activesupport/test/core_ext/module/attr_internal_test.rb
new file mode 100644
index 0000000..2aea14c
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/module/attr_internal_test.rb
@@ -0,0 +1,53 @@
+require 'abstract_unit'
+require 'active_support/core_ext/module/attr_internal'
+
+class AttrInternalTest < ActiveSupport::TestCase
+  def setup
+    @target = Class.new
+    @instance = @target.new
+  end
+
+  def test_reader
+    assert_nothing_raised { @target.attr_internal_reader :foo }
+
+    assert !@instance.instance_variable_defined?('@_foo')
+    assert_raise(NoMethodError) { @instance.foo = 1 }
+
+    @instance.instance_variable_set('@_foo', 1)
+    assert_nothing_raised { assert_equal 1, @instance.foo }
+  end
+
+  def test_writer
+    assert_nothing_raised { @target.attr_internal_writer :foo }
+
+    assert !@instance.instance_variable_defined?('@_foo')
+    assert_nothing_raised { assert_equal 1, @instance.foo = 1 }
+
+    assert_equal 1, @instance.instance_variable_get('@_foo')
+    assert_raise(NoMethodError) { @instance.foo }
+  end
+
+  def test_accessor
+    assert_nothing_raised { @target.attr_internal :foo }
+
+    assert !@instance.instance_variable_defined?('@_foo')
+    assert_nothing_raised { assert_equal 1, @instance.foo = 1 }
+
+    assert_equal 1, @instance.instance_variable_get('@_foo')
+    assert_nothing_raised { assert_equal 1, @instance.foo }
+  end
+
+  def test_naming_format
+    assert_equal '@_%s', Module.attr_internal_naming_format
+    assert_nothing_raised { Module.attr_internal_naming_format = '@abc%sdef' }
+    @target.attr_internal :foo
+
+    assert !@instance.instance_variable_defined?('@_foo')
+    assert !@instance.instance_variable_defined?('@abcfoodef')
+    assert_nothing_raised { @instance.foo = 1 }
+    assert !@instance.instance_variable_defined?('@_foo')
+    assert @instance.instance_variable_defined?('@abcfoodef')
+  ensure
+    Module.attr_internal_naming_format = '@_%s'
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/module/attribute_accessor_test.rb b/app/server/vendor/activesupport/test/core_ext/module/attribute_accessor_test.rb
new file mode 100644
index 0000000..48f3cc5
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/module/attribute_accessor_test.rb
@@ -0,0 +1,79 @@
+require 'abstract_unit'
+require 'active_support/core_ext/module/attribute_accessors'
+
+class ModuleAttributeAccessorTest < ActiveSupport::TestCase
+  def setup
+    m = @module = Module.new do
+      mattr_accessor :foo
+      mattr_accessor :bar, :instance_writer => false
+      mattr_reader   :shaq, :instance_reader => false
+      mattr_accessor :camp, :instance_accessor => false
+
+      cattr_accessor(:defa) { 'default_accessor_value' }
+      cattr_reader(:defr) { 'default_reader_value' }
+      cattr_writer(:defw) { 'default_writer_value' }
+      cattr_accessor(:quux) { :quux }
+    end
+    @class = Class.new
+    @class.instance_eval { include m }
+    @object = @class.new
+  end
+
+  def test_should_use_mattr_default
+    assert_nil @module.foo
+    assert_nil @object.foo
+  end
+
+  def test_should_set_mattr_value
+    @module.foo = :test
+    assert_equal :test, @object.foo
+
+    @object.foo = :test2
+    assert_equal :test2, @module.foo
+  end
+
+  def test_cattr_accessor_default_value
+    assert_equal :quux, @module.quux
+    assert_equal :quux, @object.quux
+  end
+
+  def test_should_not_create_instance_writer
+    assert_respond_to @module, :foo
+    assert_respond_to @module, :foo=
+    assert_respond_to @object, :bar
+    assert !@object.respond_to?(:bar=)
+  end
+
+  def test_should_not_create_instance_reader
+    assert_respond_to @module, :shaq
+    assert !@object.respond_to?(:shaq)
+  end
+
+  def test_should_not_create_instance_accessors
+    assert_respond_to @module, :camp
+    assert !@object.respond_to?(:camp)
+    assert !@object.respond_to?(:camp=)
+  end
+
+  def test_should_raise_name_error_if_attribute_name_is_invalid
+    exception = assert_raises NameError do
+      Class.new do
+        cattr_reader "1nvalid"
+      end
+    end
+    assert_equal "invalid attribute name: 1nvalid", exception.message
+
+    exception = assert_raises NameError do
+      Class.new do
+        cattr_writer "1nvalid"
+      end
+    end
+    assert_equal "invalid attribute name: 1nvalid", exception.message
+  end
+
+  def test_should_use_default_value_if_block_passed
+    assert_equal 'default_accessor_value', @module.defa
+    assert_equal 'default_reader_value', @module.defr
+    assert_equal 'default_writer_value', @module.class_variable_get('@@defw')
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/module/attribute_aliasing_test.rb b/app/server/vendor/activesupport/test/core_ext/module/attribute_aliasing_test.rb
new file mode 100644
index 0000000..29c3053
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/module/attribute_aliasing_test.rb
@@ -0,0 +1,59 @@
+require 'abstract_unit'
+require 'active_support/core_ext/module/aliasing'
+
+module AttributeAliasing
+  class Content
+    attr_accessor :title, :Data
+
+    def initialize
+      @title, @Data = nil, nil
+    end
+
+    def title?
+      !title.nil?
+    end
+
+    def Data?
+      !self.Data.nil?
+    end
+  end
+
+  class Email < Content
+    alias_attribute :subject, :title
+    alias_attribute :body, :Data
+  end
+end
+
+class AttributeAliasingTest < ActiveSupport::TestCase
+  def test_attribute_alias
+    e = AttributeAliasing::Email.new
+
+    assert !e.subject?
+
+    e.title = "Upgrade computer"
+    assert_equal "Upgrade computer", e.subject
+    assert e.subject?
+
+    e.subject = "We got a long way to go"
+    assert_equal "We got a long way to go", e.title
+    assert e.title?
+  end
+
+  def test_aliasing_to_uppercase_attributes
+    # Although it's very un-Ruby, some people's AR-mapped tables have
+    # upper-case attributes, and when people want to alias those names
+    # to more sensible ones, everything goes *foof*.
+    e = AttributeAliasing::Email.new
+
+    assert !e.body?
+    assert !e.Data?
+
+    e.body = "No, really, this is not a joke."
+    assert_equal "No, really, this is not a joke.", e.Data
+    assert e.Data?
+
+    e.Data = "Uppercased methods are teh suck"
+    assert_equal "Uppercased methods are teh suck", e.body
+    assert e.body?
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/module/concerning_test.rb b/app/server/vendor/activesupport/test/core_ext/module/concerning_test.rb
new file mode 100644
index 0000000..07d860b
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/module/concerning_test.rb
@@ -0,0 +1,65 @@
+require 'abstract_unit'
+require 'active_support/core_ext/module/concerning'
+
+class ModuleConcerningTest < ActiveSupport::TestCase
+  def test_concerning_declares_a_concern_and_includes_it_immediately
+    klass = Class.new { concerning(:Foo) { } }
+    assert klass.ancestors.include?(klass::Foo), klass.ancestors.inspect
+  end
+end
+
+class ModuleConcernTest < ActiveSupport::TestCase
+  def test_concern_creates_a_module_extended_with_active_support_concern
+    klass = Class.new do
+      concern :Baz do
+        included { @foo = 1 }
+        def should_be_public; end
+      end
+    end
+
+    # Declares a concern but doesn't include it
+    assert klass.const_defined?(:Baz, false)
+    assert !ModuleConcernTest.const_defined?(:Baz)
+    assert_kind_of ActiveSupport::Concern, klass::Baz
+    assert !klass.ancestors.include?(klass::Baz), klass.ancestors.inspect
+
+    # Public method visibility by default
+    assert klass::Baz.public_instance_methods.map(&:to_s).include?('should_be_public')
+
+    # Calls included hook
+    assert_equal 1, Class.new { include klass::Baz }.instance_variable_get('@foo')
+  end
+
+  class Foo
+    concerning :Bar do
+      module ClassMethods
+        def will_be_orphaned; end
+      end
+
+      const_set :ClassMethods, Module.new {
+        def hacked_on; end
+      }
+
+      # Doesn't overwrite existing ClassMethods module.
+      class_methods do
+        def nicer_dsl; end
+      end
+
+      # Doesn't overwrite previous class_methods definitions.
+      class_methods do
+        def doesnt_clobber; end
+      end
+    end
+  end
+
+  def test_using_class_methods_blocks_instead_of_ClassMethods_module
+    assert !Foo.respond_to?(:will_be_orphaned)
+    assert Foo.respond_to?(:hacked_on)
+    assert Foo.respond_to?(:nicer_dsl)
+    assert Foo.respond_to?(:doesnt_clobber)
+
+    # Orphan in Foo::ClassMethods, not Bar::ClassMethods.
+    assert Foo.const_defined?(:ClassMethods)
+    assert Foo::ClassMethods.method_defined?(:will_be_orphaned)
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/module/qualified_const_test.rb b/app/server/vendor/activesupport/test/core_ext/module/qualified_const_test.rb
new file mode 100644
index 0000000..37c9228
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/module/qualified_const_test.rb
@@ -0,0 +1,108 @@
+require 'abstract_unit'
+require 'active_support/core_ext/module/qualified_const'
+
+module QualifiedConstTestMod
+  X = false
+
+  module M
+    X = 1
+
+    class C
+      X = 2
+    end
+  end
+
+  module N
+    include M
+  end
+end
+
+class QualifiedConstTest < ActiveSupport::TestCase
+  test "Object.qualified_const_defined?" do
+    assert Object.qualified_const_defined?("QualifiedConstTestMod")
+    assert !Object.qualified_const_defined?("NonExistingQualifiedConstTestMod")
+
+    assert Object.qualified_const_defined?("QualifiedConstTestMod::X")
+    assert !Object.qualified_const_defined?("QualifiedConstTestMod::Y")
+
+    assert Object.qualified_const_defined?("QualifiedConstTestMod::M::X")
+    assert !Object.qualified_const_defined?("QualifiedConstTestMod::M::Y")
+
+    if Module.method(:const_defined?).arity == 1
+      assert !Object.qualified_const_defined?("QualifiedConstTestMod::N::X")
+    else
+      assert Object.qualified_const_defined?("QualifiedConstTestMod::N::X")
+      assert !Object.qualified_const_defined?("QualifiedConstTestMod::N::X", false)
+      assert Object.qualified_const_defined?("QualifiedConstTestMod::N::X", true)
+    end
+  end
+
+  test "mod.qualified_const_defined?" do
+    assert QualifiedConstTestMod.qualified_const_defined?("M")
+    assert !QualifiedConstTestMod.qualified_const_defined?("NonExistingM")
+
+    assert QualifiedConstTestMod.qualified_const_defined?("M::X")
+    assert !QualifiedConstTestMod.qualified_const_defined?("M::Y")
+
+    assert QualifiedConstTestMod.qualified_const_defined?("M::C::X")
+    assert !QualifiedConstTestMod.qualified_const_defined?("M::C::Y")
+
+    if Module.method(:const_defined?).arity == 1
+      assert !QualifiedConstTestMod.qualified_const_defined?("QualifiedConstTestMod::N::X")
+    else
+      assert QualifiedConstTestMod.qualified_const_defined?("N::X")
+      assert !QualifiedConstTestMod.qualified_const_defined?("N::X", false)
+      assert QualifiedConstTestMod.qualified_const_defined?("N::X", true)
+    end
+  end
+
+  test "qualified_const_get" do
+    assert_equal false, Object.qualified_const_get("QualifiedConstTestMod::X")
+    assert_equal false, QualifiedConstTestMod.qualified_const_get("X")
+    assert_equal 1, QualifiedConstTestMod.qualified_const_get("M::X")
+    assert_equal 1, QualifiedConstTestMod.qualified_const_get("N::X")
+    assert_equal 2, QualifiedConstTestMod.qualified_const_get("M::C::X")
+
+    assert_raise(NameError) { QualifiedConstTestMod.qualified_const_get("M::C::Y")}
+  end
+
+  test "qualified_const_set" do
+    begin
+      m = Module.new
+      assert_equal m, Object.qualified_const_set("QualifiedConstTestMod2", m)
+      assert_equal m, ::QualifiedConstTestMod2
+
+      # We are going to assign to existing constants on purpose, so silence warnings.
+      silence_warnings do
+        assert_equal true, QualifiedConstTestMod.qualified_const_set("QualifiedConstTestMod::X", true)
+        assert_equal true, QualifiedConstTestMod::X
+
+        assert_equal 10, QualifiedConstTestMod::M.qualified_const_set("X", 10)
+        assert_equal 10, QualifiedConstTestMod::M::X
+      end
+    ensure
+      silence_warnings do
+        QualifiedConstTestMod.qualified_const_set('QualifiedConstTestMod::X', false)
+        QualifiedConstTestMod::M.qualified_const_set('X', 1)
+      end
+    end
+  end
+
+  test "reject absolute paths" do
+    assert_raise_with_message(NameError, "wrong constant name ::X") { Object.qualified_const_defined?("::X")}
+    assert_raise_with_message(NameError, "wrong constant name ::X") { Object.qualified_const_defined?("::X::Y")}
+
+    assert_raise_with_message(NameError, "wrong constant name ::X") { Object.qualified_const_get("::X")}
+    assert_raise_with_message(NameError, "wrong constant name ::X") { Object.qualified_const_get("::X::Y")}
+
+    assert_raise_with_message(NameError, "wrong constant name ::X") { Object.qualified_const_set("::X", nil)}
+    assert_raise_with_message(NameError, "wrong constant name ::X") { Object.qualified_const_set("::X::Y", nil)}
+  end
+
+  private
+
+  def assert_raise_with_message(expected_exception, expected_message, &block)
+    exception = assert_raise(expected_exception, &block)
+    assert_equal expected_message, exception.message
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/module/reachable_test.rb b/app/server/vendor/activesupport/test/core_ext/module/reachable_test.rb
new file mode 100644
index 0000000..80eb31a
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/module/reachable_test.rb
@@ -0,0 +1,41 @@
+require 'abstract_unit'
+require 'active_support/core_ext/module/reachable'
+
+class AnonymousTest < ActiveSupport::TestCase
+  test "an anonymous class or module is not reachable" do
+    assert !Module.new.reachable?
+    assert !Class.new.reachable?
+  end
+
+  test "ordinary named classes or modules are reachable" do
+    assert Kernel.reachable?
+    assert Object.reachable?
+  end
+
+  test "a named class or module whose constant has gone is not reachable" do
+    c = eval "class C; end; C"
+    m = eval "module M; end; M"
+
+    self.class.send(:remove_const, :C)
+    self.class.send(:remove_const, :M)
+
+    assert !c.reachable?
+    assert !m.reachable?
+  end
+
+  test "a named class or module whose constants store different objects are not reachable" do
+    c = eval "class C; end; C"
+    m = eval "module M; end; M"
+
+    self.class.send(:remove_const, :C)
+    self.class.send(:remove_const, :M)
+
+    eval "class C; end"
+    eval "module M; end"
+
+    assert C.reachable?
+    assert M.reachable?
+    assert !c.reachable?
+    assert !m.reachable?
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/core_ext/module/remove_method_test.rb b/app/server/vendor/activesupport/test/core_ext/module/remove_method_test.rb
new file mode 100644
index 0000000..4657f0c
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/module/remove_method_test.rb
@@ -0,0 +1,29 @@
+require 'abstract_unit'
+require 'active_support/core_ext/module/remove_method'
+
+module RemoveMethodTests
+  class A
+    def do_something
+      return 1
+    end
+    
+  end
+end
+
+class RemoveMethodTest < ActiveSupport::TestCase
+  
+  def test_remove_method_from_an_object
+    RemoveMethodTests::A.class_eval{
+      self.remove_possible_method(:do_something)
+    }
+    assert !RemoveMethodTests::A.new.respond_to?(:do_something)
+  end
+  
+  def test_redefine_method_in_an_object
+    RemoveMethodTests::A.class_eval{
+      self.redefine_method(:do_something) { return 100 }
+    }
+    assert_equal 100, RemoveMethodTests::A.new.do_something
+  end
+
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/core_ext/module_test.rb b/app/server/vendor/activesupport/test/core_ext/module_test.rb
new file mode 100644
index 0000000..ff6e218
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/module_test.rb
@@ -0,0 +1,498 @@
+require 'abstract_unit'
+require 'active_support/core_ext/module'
+
+module One
+  Constant1 = "Hello World"
+  Constant2 = "What's up?"
+end
+
+class Ab
+  include One
+  Constant1 = "Hello World" # Will have different object id than One::Constant1
+  Constant3 = "Goodbye World"
+end
+
+module Yz
+  module Zy
+    class Cd
+      include One
+    end
+  end
+end
+
+Somewhere = Struct.new(:street, :city) do
+  attr_accessor :name
+end
+
+class Someone < Struct.new(:name, :place)
+  delegate :street, :city, :to_f, :to => :place
+  delegate :name=, :to => :place, :prefix => true
+  delegate :upcase, :to => "place.city"
+  delegate :table_name, :to => :class
+  delegate :table_name, :to => :class, :prefix => true
+
+  def self.table_name
+    'some_table'
+  end
+
+  FAILED_DELEGATE_LINE = __LINE__ + 1
+  delegate :foo, :to => :place
+
+  FAILED_DELEGATE_LINE_2 = __LINE__ + 1
+  delegate :bar, :to => :place, :allow_nil => true
+end
+
+Invoice   = Struct.new(:client) do
+  delegate :street, :city, :name, :to => :client, :prefix => true
+  delegate :street, :city, :name, :to => :client, :prefix => :customer
+end
+
+Project   = Struct.new(:description, :person) do
+  delegate :name, :to => :person, :allow_nil => true
+  delegate :to_f, :to => :description, :allow_nil => true
+end
+
+Developer = Struct.new(:client) do
+  delegate :name, :to => :client, :prefix => nil
+end
+
+Tester = Struct.new(:client) do
+  delegate :name, :to => :client, :prefix => false
+end
+
+Product = Struct.new(:name) do
+  delegate :name, :to => :manufacturer, :prefix => true
+  delegate :name, :to => :type, :prefix => true
+
+  def manufacturer
+    @manufacturer ||= begin
+      nil.unknown_method
+    end
+  end
+
+  def type
+    @type ||= begin
+      nil.type_name
+    end
+  end
+end
+
+class ParameterSet
+  delegate :[], :[]=, :to => :@params
+
+  def initialize
+    @params = {:foo => "bar"}
+  end
+end
+
+class Name
+  delegate :upcase, :to => :@full_name
+
+  def initialize(first, last)
+    @full_name = "#{first} #{last}"
+  end
+end
+
+class SideEffect
+  attr_reader :ints
+
+  delegate :to_i, :to => :shift, :allow_nil => true
+  delegate :to_s, :to => :shift
+
+  def initialize
+    @ints = [1, 2, 3]
+  end
+
+  def shift
+    @ints.shift
+  end
+end
+
+class ModuleTest < ActiveSupport::TestCase
+  def setup
+    @david = Someone.new("David", Somewhere.new("Paulina", "Chicago"))
+  end
+
+  def test_delegation_to_methods
+    assert_equal "Paulina", @david.street
+    assert_equal "Chicago", @david.city
+  end
+
+  def test_delegation_to_assignment_method
+    @david.place_name = "Fred"
+    assert_equal "Fred", @david.place.name
+  end
+
+  def test_delegation_to_index_get_method
+    @params = ParameterSet.new
+    assert_equal "bar", @params[:foo]
+  end
+
+  def test_delegation_to_index_set_method
+    @params = ParameterSet.new
+    @params[:foo] = "baz"
+    assert_equal "baz", @params[:foo]
+  end
+
+  def test_delegation_down_hierarchy
+    assert_equal "CHICAGO", @david.upcase
+  end
+
+  def test_delegation_to_instance_variable
+    david = Name.new("David", "Hansson")
+    assert_equal "DAVID HANSSON", david.upcase
+  end
+
+  def test_delegation_to_class_method
+    assert_equal 'some_table', @david.table_name
+    assert_equal 'some_table', @david.class_table_name
+  end
+
+  def test_missing_delegation_target
+    assert_raise(ArgumentError) do
+      Name.send :delegate, :nowhere
+    end
+    assert_raise(ArgumentError) do
+      Name.send :delegate, :noplace, :tos => :hollywood
+    end
+  end
+
+  def test_delegation_prefix
+    invoice = Invoice.new(@david)
+    assert_equal invoice.client_name, "David"
+    assert_equal invoice.client_street, "Paulina"
+    assert_equal invoice.client_city, "Chicago"
+  end
+
+  def test_delegation_custom_prefix
+    invoice = Invoice.new(@david)
+    assert_equal invoice.customer_name, "David"
+    assert_equal invoice.customer_street, "Paulina"
+    assert_equal invoice.customer_city, "Chicago"
+  end
+
+  def test_delegation_prefix_with_nil_or_false
+    assert_equal Developer.new(@david).name, "David"
+    assert_equal Tester.new(@david).name, "David"
+  end
+
+  def test_delegation_prefix_with_instance_variable
+    assert_raise ArgumentError do
+      Class.new do
+        def initialize(client)
+          @client = client
+        end
+        delegate :name, :address, :to => :@client, :prefix => true
+      end
+    end
+  end
+
+  def test_delegation_with_allow_nil
+    rails = Project.new("Rails", Someone.new("David"))
+    assert_equal rails.name, "David"
+  end
+
+  def test_delegation_with_allow_nil_and_nil_value
+    rails = Project.new("Rails")
+    assert_nil rails.name
+  end
+
+  # Ensures with check for nil, not for a falseish target.
+  def test_delegation_with_allow_nil_and_false_value
+    project = Project.new(false, false)
+    assert_raise(NoMethodError) { project.name }
+  end
+
+  def test_delegation_with_allow_nil_and_invalid_value
+    rails = Project.new("Rails", "David")
+    assert_raise(NoMethodError) { rails.name }
+  end
+
+  def test_delegation_with_allow_nil_and_nil_value_and_prefix
+    Project.class_eval do
+      delegate :name, :to => :person, :allow_nil => true, :prefix => true
+    end
+    rails = Project.new("Rails")
+    assert_nil rails.person_name
+  end
+
+  def test_delegation_without_allow_nil_and_nil_value
+    david = Someone.new("David")
+    assert_raise(Module::DelegationError) { david.street }
+  end
+
+  def test_delegation_to_method_that_exists_on_nil
+    nil_person = Someone.new(nil)
+    assert_equal 0.0, nil_person.to_f
+  end
+
+  def test_delegation_to_method_that_exists_on_nil_when_allowing_nil
+    nil_project = Project.new(nil)
+    assert_equal 0.0, nil_project.to_f
+  end
+
+  def test_delegation_does_not_raise_error_when_removing_singleton_instance_methods
+    parent = Class.new do
+      def self.parent_method; end
+    end
+
+    assert_nothing_raised do
+      Class.new(parent) do
+        class << self
+          delegate :parent_method, :to => :superclass
+        end
+      end
+    end
+  end
+
+  def test_delegation_line_number
+    _, line = Someone.instance_method(:foo).source_location
+    assert_equal Someone::FAILED_DELEGATE_LINE, line
+  end
+
+  def test_delegate_line_with_nil
+    _, line = Someone.instance_method(:bar).source_location
+    assert_equal Someone::FAILED_DELEGATE_LINE_2, line
+  end
+
+  def test_delegation_exception_backtrace
+    someone = Someone.new("foo", "bar")
+    someone.foo
+  rescue NoMethodError => e
+    file_and_line = "#{__FILE__}:#{Someone::FAILED_DELEGATE_LINE}"
+    # We can't simply check the first line of the backtrace, because JRuby reports the call to __send__ in the backtrace.
+    assert e.backtrace.any?{|a| a.include?(file_and_line)},
+           "[#{e.backtrace.inspect}] did not include [#{file_and_line}]"
+  end
+
+  def test_delegation_exception_backtrace_with_allow_nil
+    someone = Someone.new("foo", "bar")
+    someone.bar
+  rescue NoMethodError => e
+    file_and_line = "#{__FILE__}:#{Someone::FAILED_DELEGATE_LINE_2}"
+    # We can't simply check the first line of the backtrace, because JRuby reports the call to __send__ in the backtrace.
+    assert e.backtrace.any?{|a| a.include?(file_and_line)},
+           "[#{e.backtrace.inspect}] did not include [#{file_and_line}]"
+  end
+
+  def test_delegation_invokes_the_target_exactly_once
+    se = SideEffect.new
+
+    assert_equal 1, se.to_i
+    assert_equal [2, 3], se.ints
+
+    assert_equal '2', se.to_s
+    assert_equal [3], se.ints
+  end
+
+  def test_delegation_doesnt_mask_nested_no_method_error_on_nil_receiver
+    product = Product.new('Widget')
+
+    # Nested NoMethodError is a different name from the delegation
+    assert_raise(NoMethodError) { product.manufacturer_name }
+
+    # Nested NoMethodError is the same name as the delegation
+    assert_raise(NoMethodError) { product.type_name }
+  end
+
+  def test_parent
+    assert_equal Yz::Zy, Yz::Zy::Cd.parent
+    assert_equal Yz, Yz::Zy.parent
+    assert_equal Object, Yz.parent
+  end
+
+  def test_parents
+    assert_equal [Yz::Zy, Yz, Object], Yz::Zy::Cd.parents
+    assert_equal [Yz, Object], Yz::Zy.parents
+  end
+
+  def test_local_constants
+    assert_equal %w(Constant1 Constant3), Ab.local_constants.sort.map(&:to_s)
+  end
+end
+
+module BarMethodAliaser
+  def self.included(foo_class)
+    foo_class.class_eval do
+      include BarMethods
+      alias_method_chain :bar, :baz
+    end
+  end
+end
+
+module BarMethods
+  def bar_with_baz
+    bar_without_baz << '_with_baz'
+  end
+
+  def quux_with_baz!
+    quux_without_baz! << '_with_baz'
+  end
+
+  def quux_with_baz?
+    false
+  end
+
+  def quux_with_baz=(v)
+    send(:quux_without_baz=, v) << '_with_baz'
+  end
+
+  def duck_with_orange
+    duck_without_orange << '_with_orange'
+  end
+end
+
+class MethodAliasingTest < ActiveSupport::TestCase
+  def setup
+    Object.const_set :FooClassWithBarMethod, Class.new { def bar() 'bar' end }
+    @instance = FooClassWithBarMethod.new
+  end
+
+  def teardown
+    Object.instance_eval { remove_const :FooClassWithBarMethod }
+  end
+
+  def test_alias_method_chain
+    assert @instance.respond_to?(:bar)
+    feature_aliases = [:bar_with_baz, :bar_without_baz]
+
+    feature_aliases.each do |method|
+      assert !@instance.respond_to?(method)
+    end
+
+    assert_equal 'bar', @instance.bar
+
+    FooClassWithBarMethod.class_eval { include BarMethodAliaser }
+
+    feature_aliases.each do |method|
+      assert_respond_to @instance, method
+    end
+
+    assert_equal 'bar_with_baz', @instance.bar
+    assert_equal 'bar', @instance.bar_without_baz
+  end
+
+  def test_alias_method_chain_with_punctuation_method
+    FooClassWithBarMethod.class_eval do
+      def quux!; 'quux' end
+    end
+
+    assert !@instance.respond_to?(:quux_with_baz!)
+    FooClassWithBarMethod.class_eval do
+      include BarMethodAliaser
+      alias_method_chain :quux!, :baz
+    end
+    assert_respond_to @instance, :quux_with_baz!
+
+    assert_equal 'quux_with_baz', @instance.quux!
+    assert_equal 'quux', @instance.quux_without_baz!
+  end
+
+  def test_alias_method_chain_with_same_names_between_predicates_and_bang_methods
+    FooClassWithBarMethod.class_eval do
+      def quux!; 'quux!' end
+      def quux?; true end
+      def quux=(v); 'quux=' end
+    end
+
+    assert !@instance.respond_to?(:quux_with_baz!)
+    assert !@instance.respond_to?(:quux_with_baz?)
+    assert !@instance.respond_to?(:quux_with_baz=)
+
+    FooClassWithBarMethod.class_eval { include BarMethodAliaser }
+    assert_respond_to @instance, :quux_with_baz!
+    assert_respond_to @instance, :quux_with_baz?
+    assert_respond_to @instance, :quux_with_baz=
+
+
+    FooClassWithBarMethod.alias_method_chain :quux!, :baz
+    assert_equal 'quux!_with_baz', @instance.quux!
+    assert_equal 'quux!', @instance.quux_without_baz!
+
+    FooClassWithBarMethod.alias_method_chain :quux?, :baz
+    assert_equal false, @instance.quux?
+    assert_equal true,  @instance.quux_without_baz?
+
+    FooClassWithBarMethod.alias_method_chain :quux=, :baz
+    assert_equal 'quux=_with_baz', @instance.send(:quux=, 1234)
+    assert_equal 'quux=', @instance.send(:quux_without_baz=, 1234)
+  end
+
+  def test_alias_method_chain_with_feature_punctuation
+    FooClassWithBarMethod.class_eval do
+      def quux; 'quux' end
+      def quux?; 'quux?' end
+      include BarMethodAliaser
+      alias_method_chain :quux, :baz!
+    end
+
+    assert_nothing_raised do
+      assert_equal 'quux_with_baz', @instance.quux_with_baz!
+    end
+
+    assert_raise(NameError) do
+      FooClassWithBarMethod.alias_method_chain :quux?, :baz!
+    end
+  end
+
+  def test_alias_method_chain_yields_target_and_punctuation
+    args = nil
+
+    FooClassWithBarMethod.class_eval do
+      def quux?; end
+      include BarMethods
+
+      FooClassWithBarMethod.alias_method_chain :quux?, :baz do |target, punctuation|
+        args = [target, punctuation]
+      end
+    end
+
+    assert_not_nil args
+    assert_equal 'quux', args[0]
+    assert_equal '?', args[1]
+  end
+
+  def test_alias_method_chain_preserves_private_method_status
+    FooClassWithBarMethod.class_eval do
+      def duck; 'duck' end
+      include BarMethodAliaser
+      private :duck
+      alias_method_chain :duck, :orange
+    end
+
+    assert_raise NoMethodError do
+      @instance.duck
+    end
+
+    assert_equal 'duck_with_orange', @instance.instance_eval { duck }
+    assert FooClassWithBarMethod.private_method_defined?(:duck)
+  end
+
+  def test_alias_method_chain_preserves_protected_method_status
+    FooClassWithBarMethod.class_eval do
+      def duck; 'duck' end
+      include BarMethodAliaser
+      protected :duck
+      alias_method_chain :duck, :orange
+    end
+
+    assert_raise NoMethodError do
+      @instance.duck
+    end
+
+    assert_equal 'duck_with_orange', @instance.instance_eval { duck }
+    assert FooClassWithBarMethod.protected_method_defined?(:duck)
+  end
+
+  def test_alias_method_chain_preserves_public_method_status
+    FooClassWithBarMethod.class_eval do
+      def duck; 'duck' end
+      include BarMethodAliaser
+      public :duck
+      alias_method_chain :duck, :orange
+    end
+
+    assert_equal 'duck_with_orange', @instance.duck
+    assert FooClassWithBarMethod.public_method_defined?(:duck)
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/name_error_test.rb b/app/server/vendor/activesupport/test/core_ext/name_error_test.rb
new file mode 100644
index 0000000..7525f80
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/name_error_test.rb
@@ -0,0 +1,21 @@
+require 'abstract_unit'
+require 'active_support/core_ext/name_error'
+
+class NameErrorTest < ActiveSupport::TestCase
+  def test_name_error_should_set_missing_name
+    exc = assert_raise NameError do
+      SomeNameThatNobodyWillUse____Really ? 1 : 0
+    end
+    assert_equal "NameErrorTest::SomeNameThatNobodyWillUse____Really", exc.missing_name
+    assert exc.missing_name?(:SomeNameThatNobodyWillUse____Really)
+    assert exc.missing_name?("NameErrorTest::SomeNameThatNobodyWillUse____Really")
+  end
+
+  def test_missing_method_should_ignore_missing_name
+    exc = assert_raise NameError do
+      some_method_that_does_not_exist
+    end
+    assert !exc.missing_name?(:Foo)
+    assert_nil exc.missing_name
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/numeric_ext_test.rb b/app/server/vendor/activesupport/test/core_ext/numeric_ext_test.rb
new file mode 100644
index 0000000..3b1dabe
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/numeric_ext_test.rb
@@ -0,0 +1,442 @@
+require 'abstract_unit'
+require 'active_support/time'
+require 'active_support/core_ext/numeric'
+require 'active_support/core_ext/integer'
+
+class NumericExtTimeAndDateTimeTest < ActiveSupport::TestCase
+  def setup
+    @now = Time.local(2005,2,10,15,30,45)
+    @dtnow = DateTime.civil(2005,2,10,15,30,45)
+    @seconds = {
+      1.minute   => 60,
+      10.minutes => 600,
+      1.hour + 15.minutes => 4500,
+      2.days + 4.hours + 30.minutes => 189000,
+      5.years + 1.month + 1.fortnight => 161589600
+    }
+  end
+
+  def test_units
+    @seconds.each do |actual, expected|
+      assert_equal expected, actual
+    end
+  end
+
+  def test_deprecated_since_and_ago
+    assert_equal @now + 1, assert_deprecated { 1.since(@now) }
+    assert_equal @now - 1, assert_deprecated { 1.ago(@now) }
+  end
+
+  def test_deprecated_since_and_ago_without_argument
+    now = Time.now
+    assert assert_deprecated { 1.since } >= now + 1
+    now = Time.now
+    assert assert_deprecated { 1.ago } >= now - 1
+  end
+
+  def test_irregular_durations
+    assert_equal @now.advance(:days => 3000), 3000.days.since(@now)
+    assert_equal @now.advance(:months => 1), 1.month.since(@now)
+    assert_equal @now.advance(:months => -1), 1.month.until(@now)
+    assert_equal @now.advance(:years => 20), 20.years.since(@now)
+    assert_equal @dtnow.advance(:days => 3000), 3000.days.since(@dtnow)
+    assert_equal @dtnow.advance(:months => 1), 1.month.since(@dtnow)
+    assert_equal @dtnow.advance(:months => -1), 1.month.until(@dtnow)
+    assert_equal @dtnow.advance(:years => 20), 20.years.since(@dtnow)
+  end
+
+  def test_duration_addition
+    assert_equal @now.advance(:days => 1).advance(:months => 1), (1.day + 1.month).since(@now)
+    assert_equal @now.advance(:days => 7), (1.week + 5.seconds - 5.seconds).since(@now)
+    assert_equal @now.advance(:years => 2), (4.years - 2.years).since(@now)
+    assert_equal @dtnow.advance(:days => 1).advance(:months => 1), (1.day + 1.month).since(@dtnow)
+    assert_equal @dtnow.advance(:days => 7), (1.week + 5.seconds - 5.seconds).since(@dtnow)
+    assert_equal @dtnow.advance(:years => 2), (4.years - 2.years).since(@dtnow)
+  end
+
+  def test_time_plus_duration
+    assert_equal @now + 8, @now + 8.seconds
+    assert_equal @now + 22.9, @now + 22.9.seconds
+    assert_equal @now.advance(:days => 15), @now + 15.days
+    assert_equal @now.advance(:months => 1), @now + 1.month
+    assert_equal @dtnow.since(8), @dtnow + 8.seconds
+    assert_equal @dtnow.since(22.9), @dtnow + 22.9.seconds
+    assert_equal @dtnow.advance(:days => 15), @dtnow + 15.days
+    assert_equal @dtnow.advance(:months => 1), @dtnow + 1.month
+  end
+
+  def test_chaining_duration_operations
+    assert_equal @now.advance(:days => 2).advance(:months => -3), @now + 2.days - 3.months
+    assert_equal @now.advance(:days => 1).advance(:months => 2), @now + 1.day + 2.months
+    assert_equal @dtnow.advance(:days => 2).advance(:months => -3), @dtnow + 2.days - 3.months
+    assert_equal @dtnow.advance(:days => 1).advance(:months => 2), @dtnow + 1.day + 2.months
+  end
+
+  def test_duration_after_conversion_is_no_longer_accurate
+    assert_equal 30.days.to_i.seconds.since(@now), 1.month.to_i.seconds.since(@now)
+    assert_equal 365.25.days.to_f.seconds.since(@now), 1.year.to_f.seconds.since(@now)
+    assert_equal 30.days.to_i.seconds.since(@dtnow), 1.month.to_i.seconds.since(@dtnow)
+    assert_equal 365.25.days.to_f.seconds.since(@dtnow), 1.year.to_f.seconds.since(@dtnow)
+  end
+
+  def test_add_one_year_to_leap_day
+    assert_equal Time.utc(2005,2,28,15,15,10), Time.utc(2004,2,29,15,15,10) + 1.year
+    assert_equal DateTime.civil(2005,2,28,15,15,10), DateTime.civil(2004,2,29,15,15,10) + 1.year
+  end
+
+  def test_since_and_ago_anchored_to_time_now_when_time_zone_is_not_set
+    Time.zone = nil
+    with_env_tz 'US/Eastern' do
+      Time.stubs(:now).returns Time.local(2000)
+      # since
+      assert_not_instance_of ActiveSupport::TimeWithZone, assert_deprecated { 5.since }
+      assert_equal Time.local(2000,1,1,0,0,5), assert_deprecated { 5.since }
+      # ago
+      assert_not_instance_of ActiveSupport::TimeWithZone, assert_deprecated { 5.ago }
+      assert_equal Time.local(1999,12,31,23,59,55), assert_deprecated { 5.ago }
+    end
+  end
+
+  def test_since_and_ago_anchored_to_time_zone_now_when_time_zone_is_set
+    Time.zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    with_env_tz 'US/Eastern' do
+      Time.stubs(:now).returns Time.local(2000)
+      # since
+      assert_instance_of ActiveSupport::TimeWithZone, assert_deprecated { 5.since }
+      assert_equal Time.utc(2000,1,1,0,0,5), assert_deprecated { 5.since.time }
+      assert_equal 'Eastern Time (US & Canada)',  assert_deprecated { 5.since.time_zone.name }
+      # ago
+      assert_instance_of ActiveSupport::TimeWithZone, assert_deprecated { 5.ago }
+      assert_equal Time.utc(1999,12,31,23,59,55), assert_deprecated { 5.ago.time }
+      assert_equal 'Eastern Time (US & Canada)', assert_deprecated { 5.ago.time_zone.name }
+    end
+  ensure
+    Time.zone = nil
+  end
+
+  protected
+    def with_env_tz(new_tz = 'US/Eastern')
+      old_tz, ENV['TZ'] = ENV['TZ'], new_tz
+      yield
+    ensure
+      old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+    end
+end
+
+class NumericExtDateTest < ActiveSupport::TestCase
+  def setup
+    @today = Date.today
+  end
+
+  def test_date_plus_duration
+    assert_equal @today + 1, @today + 1.day
+    assert_equal @today >> 1, @today + 1.month
+    assert_equal @today.to_time.since(1), @today + 1.second
+    assert_equal @today.to_time.since(60), @today + 1.minute
+    assert_equal @today.to_time.since(60*60), @today + 1.hour
+  end
+
+  def test_chaining_duration_operations
+    assert_equal @today.advance(:days => 2).advance(:months => -3), @today + 2.days - 3.months
+    assert_equal @today.advance(:days => 1).advance(:months => 2), @today + 1.day + 2.months
+  end
+
+  def test_add_one_year_to_leap_day
+    assert_equal Date.new(2005,2,28), Date.new(2004,2,29) + 1.year
+  end
+end
+
+class NumericExtSizeTest < ActiveSupport::TestCase
+  def test_unit_in_terms_of_another
+    assert_equal 1024.bytes, 1.kilobyte
+    assert_equal 1024.kilobytes, 1.megabyte
+    assert_equal 3584.0.kilobytes, 3.5.megabytes
+    assert_equal 3584.0.megabytes, 3.5.gigabytes
+    assert_equal 1.kilobyte ** 4, 1.terabyte
+    assert_equal 1024.kilobytes + 2.megabytes, 3.megabytes
+    assert_equal 2.gigabytes / 4, 512.megabytes
+    assert_equal 256.megabytes * 20 + 5.gigabytes, 10.gigabytes
+    assert_equal 1.kilobyte ** 5, 1.petabyte
+    assert_equal 1.kilobyte ** 6, 1.exabyte
+  end
+
+  def test_units_as_bytes_independently
+    assert_equal 3145728, 3.megabytes
+    assert_equal 3145728, 3.megabyte
+    assert_equal 3072, 3.kilobytes
+    assert_equal 3072, 3.kilobyte
+    assert_equal 3221225472, 3.gigabytes
+    assert_equal 3221225472, 3.gigabyte
+    assert_equal 3298534883328, 3.terabytes
+    assert_equal 3298534883328, 3.terabyte
+    assert_equal 3377699720527872, 3.petabytes
+    assert_equal 3377699720527872, 3.petabyte
+    assert_equal 3458764513820540928, 3.exabytes
+    assert_equal 3458764513820540928, 3.exabyte
+  end
+end
+
+class NumericExtFormattingTest < ActiveSupport::TestCase
+  def kilobytes(number)
+    number * 1024
+  end
+
+  def megabytes(number)
+    kilobytes(number) * 1024
+  end
+
+  def gigabytes(number)
+    megabytes(number) * 1024
+  end
+
+  def terabytes(number)
+    gigabytes(number) * 1024
+  end
+
+  def test_to_s__phone
+    assert_equal("555-1234", 5551234.to_s(:phone))
+    assert_equal("800-555-1212", 8005551212.to_s(:phone))
+    assert_equal("(800) 555-1212", 8005551212.to_s(:phone, :area_code => true))
+    assert_equal("800 555 1212", 8005551212.to_s(:phone, :delimiter => " "))
+    assert_equal("(800) 555-1212 x 123", 8005551212.to_s(:phone, :area_code => true, :extension => 123))
+    assert_equal("800-555-1212", 8005551212.to_s(:phone, :extension => "  "))
+    assert_equal("555.1212", 5551212.to_s(:phone, :delimiter => '.'))
+    assert_equal("+1-800-555-1212", 8005551212.to_s(:phone, :country_code => 1))
+    assert_equal("+18005551212", 8005551212.to_s(:phone, :country_code => 1, :delimiter => ''))
+    assert_equal("22-555-1212", 225551212.to_s(:phone))
+    assert_equal("+45-22-555-1212", 225551212.to_s(:phone, :country_code => 45))
+  end
+
+  def test_to_s__currency
+    assert_equal("$1,234,567,890.50", 1234567890.50.to_s(:currency))
+    assert_equal("$1,234,567,890.51", 1234567890.506.to_s(:currency))
+    assert_equal("-$1,234,567,890.50", -1234567890.50.to_s(:currency))
+    assert_equal("-$ 1,234,567,890.50", -1234567890.50.to_s(:currency, :format => "%u %n"))
+    assert_equal("($1,234,567,890.50)", -1234567890.50.to_s(:currency, :negative_format => "(%u%n)"))
+    assert_equal("$1,234,567,892", 1234567891.50.to_s(:currency, :precision => 0))
+    assert_equal("$1,234,567,890.5", 1234567890.50.to_s(:currency, :precision => 1))
+    assert_equal("£1234567890,50", 1234567890.50.to_s(:currency, :unit => "£", :separator => ",", :delimiter => ""))
+  end
+
+
+  def test_to_s__rounded
+    assert_equal("-111.235", -111.2346.to_s(:rounded))
+    assert_equal("111.235", 111.2346.to_s(:rounded))
+    assert_equal("31.83", 31.825.to_s(:rounded, :precision => 2))
+    assert_equal("111.23", 111.2346.to_s(:rounded, :precision => 2))
+    assert_equal("111.00", 111.to_s(:rounded, :precision => 2))
+    assert_equal("3268", (32.6751 * 100.00).to_s(:rounded, :precision => 0))
+    assert_equal("112", 111.50.to_s(:rounded, :precision => 0))
+    assert_equal("1234567892", 1234567891.50.to_s(:rounded, :precision => 0))
+    assert_equal("0", 0.to_s(:rounded, :precision => 0))
+    assert_equal("0.00100", 0.001.to_s(:rounded, :precision => 5))
+    assert_equal("0.001", 0.00111.to_s(:rounded, :precision => 3))
+    assert_equal("10.00", 9.995.to_s(:rounded, :precision => 2))
+    assert_equal("11.00", 10.995.to_s(:rounded, :precision => 2))
+    assert_equal("0.00", -0.001.to_s(:rounded, :precision => 2))
+  end
+
+  def test_to_s__percentage
+    assert_equal("100.000%", 100.to_s(:percentage))
+    assert_equal("100%", 100.to_s(:percentage, :precision => 0))
+    assert_equal("302.06%", 302.0574.to_s(:percentage, :precision => 2))
+    assert_equal("123.4%", 123.400.to_s(:percentage, :precision => 3, :strip_insignificant_zeros => true))
+    assert_equal("1.000,000%", 1000.to_s(:percentage, :delimiter => '.', :separator => ','))
+    assert_equal("1000.000  %", 1000.to_s(:percentage, :format => "%n  %"))
+  end
+
+  def test_to_s__delimited
+    assert_equal("12,345,678", 12345678.to_s(:delimited))
+    assert_equal("0", 0.to_s(:delimited))
+    assert_equal("123", 123.to_s(:delimited))
+    assert_equal("123,456", 123456.to_s(:delimited))
+    assert_equal("123,456.78", 123456.78.to_s(:delimited))
+    assert_equal("123,456.789", 123456.789.to_s(:delimited))
+    assert_equal("123,456.78901", 123456.78901.to_s(:delimited))
+    assert_equal("123,456,789.78901", 123456789.78901.to_s(:delimited))
+    assert_equal("0.78901", 0.78901.to_s(:delimited))
+  end
+
+  def test_to_s__delimited__with_options_hash
+    assert_equal '12 345 678', 12345678.to_s(:delimited, :delimiter => ' ')
+    assert_equal '12,345,678-05', 12345678.05.to_s(:delimited, :separator => '-')
+    assert_equal '12.345.678,05', 12345678.05.to_s(:delimited, :separator => ',', :delimiter => '.')
+    assert_equal '12.345.678,05', 12345678.05.to_s(:delimited, :delimiter => '.', :separator => ',')
+  end
+
+
+  def test_to_s__rounded_with_custom_delimiter_and_separator
+    assert_equal '31,83',       31.825.to_s(:rounded, :precision => 2, :separator => ',')
+    assert_equal '1.231,83',    1231.825.to_s(:rounded, :precision => 2, :separator => ',', :delimiter => '.')
+  end
+
+  def test_to_s__rounded__with_significant_digits
+    assert_equal "124000", 123987.to_s(:rounded, :precision => 3, :significant => true)
+    assert_equal "120000000", 123987876.to_s(:rounded, :precision => 2, :significant => true )
+    assert_equal "9775", 9775.to_s(:rounded, :precision => 4, :significant => true )
+    assert_equal "5.4", 5.3923.to_s(:rounded, :precision => 2, :significant => true )
+    assert_equal "5", 5.3923.to_s(:rounded, :precision => 1, :significant => true )
+    assert_equal "1", 1.232.to_s(:rounded, :precision => 1, :significant => true )
+    assert_equal "7", 7.to_s(:rounded, :precision => 1, :significant => true )
+    assert_equal "1", 1.to_s(:rounded, :precision => 1, :significant => true )
+    assert_equal "53", 52.7923.to_s(:rounded, :precision => 2, :significant => true )
+    assert_equal "9775.00", 9775.to_s(:rounded, :precision => 6, :significant => true )
+    assert_equal "5.392900", 5.3929.to_s(:rounded, :precision => 7, :significant => true )
+    assert_equal "0.0", 0.to_s(:rounded, :precision => 2, :significant => true )
+    assert_equal "0", 0.to_s(:rounded, :precision => 1, :significant => true )
+    assert_equal "0.0001", 0.0001.to_s(:rounded, :precision => 1, :significant => true )
+    assert_equal "0.000100", 0.0001.to_s(:rounded, :precision => 3, :significant => true )
+    assert_equal "0.0001", 0.0001111.to_s(:rounded, :precision => 1, :significant => true )
+    assert_equal "10.0", 9.995.to_s(:rounded, :precision => 3, :significant => true)
+    assert_equal "9.99", 9.994.to_s(:rounded, :precision => 3, :significant => true)
+    assert_equal "11.0", 10.995.to_s(:rounded, :precision => 3, :significant => true)
+  end
+
+  def test_to_s__rounded__with_strip_insignificant_zeros
+    assert_equal "9775.43", 9775.43.to_s(:rounded, :precision => 4, :strip_insignificant_zeros => true )
+    assert_equal "9775.2", 9775.2.to_s(:rounded, :precision => 6, :significant => true, :strip_insignificant_zeros => true )
+    assert_equal "0", 0.to_s(:rounded, :precision => 6, :significant => true, :strip_insignificant_zeros => true )
+  end
+
+  def test_to_s__rounded__with_significant_true_and_zero_precision
+    # Zero precision with significant is a mistake (would always return zero),
+    # so we treat it as if significant was false (increases backwards compatibility for number_to_human_size)
+    assert_equal "124", 123.987.to_s(:rounded, :precision => 0, :significant => true)
+    assert_equal "12", 12.to_s(:rounded, :precision => 0, :significant => true )
+  end
+
+  def test_to_s__human_size
+    assert_equal '0 Bytes',   0.to_s(:human_size)
+    assert_equal '1 Byte',    1.to_s(:human_size)
+    assert_equal '3 Bytes',   3.14159265.to_s(:human_size)
+    assert_equal '123 Bytes', 123.0.to_s(:human_size)
+    assert_equal '123 Bytes', 123.to_s(:human_size)
+    assert_equal '1.21 KB',   1234.to_s(:human_size)
+    assert_equal '12.1 KB',   12345.to_s(:human_size)
+    assert_equal '1.18 MB',   1234567.to_s(:human_size)
+    assert_equal '1.15 GB',   1234567890.to_s(:human_size)
+    assert_equal '1.12 TB',   1234567890123.to_s(:human_size)
+    assert_equal '1030 TB',   terabytes(1026).to_s(:human_size)
+    assert_equal '444 KB',    kilobytes(444).to_s(:human_size)
+    assert_equal '1020 MB',   megabytes(1023).to_s(:human_size)
+    assert_equal '3 TB',      terabytes(3).to_s(:human_size)
+    assert_equal '1.2 MB',    1234567.to_s(:human_size, :precision => 2)
+    assert_equal '3 Bytes',   3.14159265.to_s(:human_size, :precision => 4)
+    assert_equal '1 KB',      kilobytes(1.0123).to_s(:human_size, :precision => 2)
+    assert_equal '1.01 KB',   kilobytes(1.0100).to_s(:human_size, :precision => 4)
+    assert_equal '10 KB',     kilobytes(10.000).to_s(:human_size, :precision => 4)
+    assert_equal '1 Byte',    1.1.to_s(:human_size)
+    assert_equal '10 Bytes',  10.to_s(:human_size)
+  end
+
+  def test_to_s__human_size_with_si_prefix
+    assert_equal '3 Bytes',    3.14159265.to_s(:human_size, :prefix => :si)
+    assert_equal '123 Bytes',  123.0.to_s(:human_size, :prefix => :si)
+    assert_equal '123 Bytes',  123.to_s(:human_size, :prefix => :si)
+    assert_equal '1.23 KB',    1234.to_s(:human_size, :prefix => :si)
+    assert_equal '12.3 KB',    12345.to_s(:human_size, :prefix => :si)
+    assert_equal '1.23 MB',    1234567.to_s(:human_size, :prefix => :si)
+    assert_equal '1.23 GB',    1234567890.to_s(:human_size, :prefix => :si)
+    assert_equal '1.23 TB',    1234567890123.to_s(:human_size, :prefix => :si)
+  end
+
+  def test_to_s__human_size_with_options_hash
+    assert_equal '1.2 MB',   1234567.to_s(:human_size, :precision => 2)
+    assert_equal '3 Bytes',  3.14159265.to_s(:human_size, :precision => 4)
+    assert_equal '1 KB',     kilobytes(1.0123).to_s(:human_size, :precision => 2)
+    assert_equal '1.01 KB',  kilobytes(1.0100).to_s(:human_size, :precision => 4)
+    assert_equal '10 KB',    kilobytes(10.000).to_s(:human_size, :precision => 4)
+    assert_equal '1 TB',     1234567890123.to_s(:human_size, :precision => 1)
+    assert_equal '500 MB',   524288000.to_s(:human_size, :precision=>3)
+    assert_equal '10 MB',    9961472.to_s(:human_size, :precision=>0)
+    assert_equal '40 KB',    41010.to_s(:human_size, :precision => 1)
+    assert_equal '40 KB',    41100.to_s(:human_size, :precision => 2)
+    assert_equal '1.0 KB',   kilobytes(1.0123).to_s(:human_size, :precision => 2, :strip_insignificant_zeros => false)
+    assert_equal '1.012 KB', kilobytes(1.0123).to_s(:human_size, :precision => 3, :significant => false)
+    assert_equal '1 KB',     kilobytes(1.0123).to_s(:human_size, :precision => 0, :significant => true) #ignores significant it precision is 0
+  end
+
+  def test_to_s__human_size_with_custom_delimiter_and_separator
+    assert_equal '1,01 KB',     kilobytes(1.0123).to_s(:human_size, :precision => 3, :separator => ',')
+    assert_equal '1,01 KB',     kilobytes(1.0100).to_s(:human_size, :precision => 4, :separator => ',')
+    assert_equal '1.000,1 TB',  terabytes(1000.1).to_s(:human_size, :precision => 5, :delimiter => '.', :separator => ',')
+  end
+
+  def test_number_to_human
+    assert_equal '-123', -123.to_s(:human)
+    assert_equal '-0.5', -0.5.to_s(:human)
+    assert_equal '0',   0.to_s(:human)
+    assert_equal '0.5', 0.5.to_s(:human)
+    assert_equal '123', 123.to_s(:human)
+    assert_equal '1.23 Thousand', 1234.to_s(:human)
+    assert_equal '12.3 Thousand', 12345.to_s(:human)
+    assert_equal '1.23 Million', 1234567.to_s(:human)
+    assert_equal '1.23 Billion', 1234567890.to_s(:human)
+    assert_equal '1.23 Trillion', 1234567890123.to_s(:human)
+    assert_equal '1.23 Quadrillion', 1234567890123456.to_s(:human)
+    assert_equal '1230 Quadrillion', 1234567890123456789.to_s(:human)
+    assert_equal '490 Thousand', 489939.to_s(:human, :precision => 2)
+    assert_equal '489.9 Thousand', 489939.to_s(:human, :precision => 4)
+    assert_equal '489 Thousand', 489000.to_s(:human, :precision => 4)
+    assert_equal '489.0 Thousand', 489000.to_s(:human, :precision => 4, :strip_insignificant_zeros => false)
+    assert_equal '1.2346 Million', 1234567.to_s(:human, :precision => 4, :significant => false)
+    assert_equal '1,2 Million', 1234567.to_s(:human, :precision => 1, :significant => false, :separator => ',')
+    assert_equal '1 Million', 1234567.to_s(:human, :precision => 0, :significant => true, :separator => ',') #significant forced to false
+  end
+
+  def test_number_to_human_with_custom_units
+    #Only integers
+    volume = {:unit => "ml", :thousand => "lt", :million => "m3"}
+    assert_equal '123 lt', 123456.to_s(:human, :units => volume)
+    assert_equal '12 ml', 12.to_s(:human, :units => volume)
+    assert_equal '1.23 m3', 1234567.to_s(:human, :units => volume)
+
+    #Including fractionals
+    distance = {:mili => "mm", :centi => "cm", :deci => "dm", :unit => "m", :ten => "dam", :hundred => "hm", :thousand => "km"}
+    assert_equal '1.23 mm', 0.00123.to_s(:human, :units => distance)
+    assert_equal '1.23 cm', 0.0123.to_s(:human, :units => distance)
+    assert_equal '1.23 dm', 0.123.to_s(:human, :units => distance)
+    assert_equal '1.23 m',  1.23.to_s(:human, :units => distance)
+    assert_equal '1.23 dam', 12.3.to_s(:human, :units => distance)
+    assert_equal '1.23 hm', 123.to_s(:human, :units => distance)
+    assert_equal '1.23 km', 1230.to_s(:human, :units => distance)
+    assert_equal '1.23 km', 1230.to_s(:human, :units => distance)
+    assert_equal '1.23 km', 1230.to_s(:human, :units => distance)
+    assert_equal '12.3 km', 12300.to_s(:human, :units => distance)
+
+    #The quantifiers don't need to be a continuous sequence
+    gangster = {:hundred => "hundred bucks", :million => "thousand quids"}
+    assert_equal '1 hundred bucks', 100.to_s(:human, :units => gangster)
+    assert_equal '25 hundred bucks', 2500.to_s(:human, :units => gangster)
+    assert_equal '25 thousand quids', 25000000.to_s(:human, :units => gangster)
+    assert_equal '12300 thousand quids', 12345000000.to_s(:human, :units => gangster)
+
+    #Spaces are stripped from the resulting string
+    assert_equal '4', 4.to_s(:human, :units => {:unit => "", :ten => 'tens '})
+    assert_equal '4.5  tens', 45.to_s(:human, :units => {:unit => "", :ten => ' tens   '})
+  end
+
+  def test_number_to_human_with_custom_format
+    assert_equal '123 times Thousand', 123456.to_s(:human, :format => "%n times %u")
+    volume = {:unit => "ml", :thousand => "lt", :million => "m3"}
+    assert_equal '123.lt', 123456.to_s(:human, :units => volume, :format => "%n.%u")
+  end
+
+  def test_to_s__injected_on_proper_types
+    assert_equal Fixnum, 1230.class
+    assert_equal '1.23 Thousand', 1230.to_s(:human)
+
+    assert_equal Float, Float(1230).class
+    assert_equal '1.23 Thousand', Float(1230).to_s(:human)
+
+    assert_equal Bignum, (100**10).class
+    assert_equal '100000 Quadrillion', (100**10).to_s(:human)
+
+    assert_equal BigDecimal, BigDecimal("1000010").class
+    assert_equal '1 Million', BigDecimal("1000010").to_s(:human)
+  end
+  
+  def test_in_milliseconds
+    assert_equal 10_000, 10.seconds.in_milliseconds
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/object/inclusion_test.rb b/app/server/vendor/activesupport/test/core_ext/object/inclusion_test.rb
new file mode 100644
index 0000000..b054a8d
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/object/inclusion_test.rb
@@ -0,0 +1,55 @@
+require 'abstract_unit'
+require 'active_support/core_ext/object/inclusion'
+
+class InTest < ActiveSupport::TestCase
+  def test_in_array
+    assert 1.in?([1,2])
+    assert !3.in?([1,2])
+  end
+
+  def test_in_hash
+    h = { "a" => 100, "b" => 200 }
+    assert "a".in?(h)
+    assert !"z".in?(h)
+  end
+
+  def test_in_string
+    assert "lo".in?("hello")
+    assert !"ol".in?("hello")
+    assert ?h.in?("hello")
+  end
+
+  def test_in_range
+    assert 25.in?(1..50)
+    assert !75.in?(1..50)
+  end
+
+  def test_in_set
+    s = Set.new([1,2])
+    assert 1.in?(s)
+    assert !3.in?(s)
+  end
+
+  module A
+  end
+  class B
+    include A
+  end
+  class C < B
+  end
+
+  def test_in_module
+    assert A.in?(B)
+    assert A.in?(C)
+    assert !A.in?(A)
+  end
+  
+  def test_no_method_catching
+    assert_raise(ArgumentError) { 1.in?(1) }
+  end
+  
+  def test_presence_in
+    assert_equal "stuff", "stuff".presence_in(%w( lots of stuff ))
+    assert_nil "stuff".presence_in(%w( lots of crap ))
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/object/json_test.rb b/app/server/vendor/activesupport/test/core_ext/object/json_test.rb
new file mode 100644
index 0000000..d3d3153
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/object/json_test.rb
@@ -0,0 +1,9 @@
+require 'abstract_unit'
+
+class JsonTest < ActiveSupport::TestCase
+  # See activesupport/test/json/encoding_test.rb for JSON encoding tests
+
+  def test_deprecated_require_to_json_rb
+    assert_deprecated { require 'active_support/core_ext/object/to_json' }
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/object/to_param_test.rb b/app/server/vendor/activesupport/test/core_ext/object/to_param_test.rb
new file mode 100644
index 0000000..bd7c6c4
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/object/to_param_test.rb
@@ -0,0 +1,19 @@
+require 'abstract_unit'
+require 'active_support/core_ext/object/to_param'
+
+class ToParamTest < ActiveSupport::TestCase
+  def test_object
+    foo = Object.new
+    def foo.to_s; 'foo' end
+    assert_equal 'foo', foo.to_param
+  end
+
+  def test_nil
+    assert_nil nil.to_param
+  end
+
+  def test_boolean
+    assert_equal true, true.to_param
+    assert_equal false, false.to_param
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/object/to_query_test.rb b/app/server/vendor/activesupport/test/core_ext/object/to_query_test.rb
new file mode 100644
index 0000000..f887a9e
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/object/to_query_test.rb
@@ -0,0 +1,66 @@
+require 'abstract_unit'
+require 'active_support/ordered_hash'
+require 'active_support/core_ext/object/to_query'
+require 'active_support/core_ext/string/output_safety'
+
+class ToQueryTest < ActiveSupport::TestCase
+  def test_simple_conversion
+    assert_query_equal 'a=10', :a => 10
+  end
+
+  def test_cgi_escaping
+    assert_query_equal 'a%3Ab=c+d', 'a:b' => 'c d'
+  end
+
+  def test_html_safe_parameter_key
+    assert_query_equal 'a%3Ab=c+d', 'a:b'.html_safe => 'c d'
+  end
+
+  def test_html_safe_parameter_value
+    assert_query_equal 'a=%5B10%5D', 'a' => '[10]'.html_safe
+  end
+
+  def test_nil_parameter_value
+    empty = Object.new
+    def empty.to_param; nil end
+    assert_query_equal 'a=', 'a' => empty
+  end
+
+  def test_nested_conversion
+    assert_query_equal 'person%5Blogin%5D=seckar&person%5Bname%5D=Nicholas',
+      :person => Hash[:login, 'seckar', :name, 'Nicholas']
+  end
+
+  def test_multiple_nested
+    assert_query_equal 'account%5Bperson%5D%5Bid%5D=20&person%5Bid%5D=10',
+      Hash[:account, {:person => {:id => 20}}, :person, {:id => 10}]
+  end
+
+  def test_array_values
+    assert_query_equal 'person%5Bid%5D%5B%5D=10&person%5Bid%5D%5B%5D=20',
+      :person => {:id => [10, 20]}
+  end
+
+  def test_array_values_are_not_sorted
+    assert_query_equal 'person%5Bid%5D%5B%5D=20&person%5Bid%5D%5B%5D=10',
+      :person => {:id => [20, 10]}
+  end
+
+  def test_nested_empty_hash
+    assert_equal '',
+      {}.to_query
+    assert_query_equal 'a=1&b%5Bc%5D=3&b%5Bd%5D=',
+      { a: 1, b: { c: 3, d: {} } }
+    assert_query_equal 'b%5Bc%5D=false&b%5Be%5D=&b%5Bf%5D=&p=12',
+      { p: 12, b: { c: false, e: nil, f: '' } }
+    assert_query_equal 'b%5Bc%5D=3&b%5Bf%5D=&b%5Bk%5D=',
+      { b: { c: 3, k: {}, f: '' } }
+    assert_query_equal 'a%5B%5D=&b=3',
+      {a: [], b: 3}
+  end
+
+  private
+    def assert_query_equal(expected, actual)
+      assert_equal expected.split('&'), actual.to_query.split('&')
+    end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/object_and_class_ext_test.rb b/app/server/vendor/activesupport/test/core_ext/object_and_class_ext_test.rb
new file mode 100644
index 0000000..0f454fd
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/object_and_class_ext_test.rb
@@ -0,0 +1,156 @@
+require 'abstract_unit'
+require 'active_support/time'
+require 'active_support/core_ext/object'
+require 'active_support/core_ext/class/subclasses'
+
+class ObjectTests < ActiveSupport::TestCase
+  class DuckTime
+    def acts_like_time?
+      true
+    end
+  end
+
+  def test_duck_typing
+    object = Object.new
+    time   = Time.now
+    date   = Date.today
+    dt     = DateTime.new
+    duck   = DuckTime.new
+
+    assert !object.acts_like?(:time)
+    assert !object.acts_like?(:date)
+
+    assert time.acts_like?(:time)
+    assert !time.acts_like?(:date)
+
+    assert !date.acts_like?(:time)
+    assert date.acts_like?(:date)
+
+    assert dt.acts_like?(:time)
+    assert dt.acts_like?(:date)
+
+    assert duck.acts_like?(:time)
+    assert !duck.acts_like?(:date)
+  end
+end
+
+class ObjectInstanceVariableTest < ActiveSupport::TestCase
+  def setup
+    @source, @dest = Object.new, Object.new
+    @source.instance_variable_set(:@bar, 'bar')
+    @source.instance_variable_set(:@baz, 'baz')
+  end
+
+  def test_instance_variable_names
+    assert_equal %w(@bar @baz), @source.instance_variable_names.sort
+  end
+
+  def test_instance_values
+    object = Object.new
+    object.instance_variable_set :@a, 1
+    object.instance_variable_set :@b, 2
+    assert_equal({'a' => 1, 'b' => 2}, object.instance_values)
+  end
+
+  def test_instance_exec_passes_arguments_to_block
+    assert_equal %w(hello goodbye), 'hello'.instance_exec('goodbye') { |v| [self, v] }
+  end
+
+  def test_instance_exec_with_frozen_obj
+    assert_equal %w(olleh goodbye), 'hello'.freeze.instance_exec('goodbye') { |v| [reverse, v] }
+  end
+
+  def test_instance_exec_nested
+    assert_equal %w(goodbye olleh bar), 'hello'.instance_exec('goodbye') { |arg|
+      [arg] + instance_exec('bar') { |v| [reverse, v] } }
+  end
+end
+
+class ObjectTryTest < ActiveSupport::TestCase
+  def setup
+    @string = "Hello"
+  end
+
+  def test_nonexisting_method
+    method = :undefined_method
+    assert !@string.respond_to?(method)
+    assert_nil @string.try(method)
+  end
+
+  def test_nonexisting_method_with_arguments
+    method = :undefined_method
+    assert !@string.respond_to?(method)
+    assert_nil @string.try(method, 'llo', 'y')
+  end
+
+  def test_nonexisting_method_bang
+    method = :undefined_method
+    assert !@string.respond_to?(method)
+    assert_raise(NoMethodError) { @string.try!(method) }
+  end
+
+  def test_nonexisting_method_with_arguments_bang
+    method = :undefined_method
+    assert !@string.respond_to?(method)
+    assert_raise(NoMethodError) { @string.try!(method, 'llo', 'y') }
+  end
+
+  def test_try_only_block_bang
+    assert_equal @string.reverse, @string.try! { |s| s.reverse }
+  end
+
+  def test_valid_method
+    assert_equal 5, @string.try(:size)
+  end
+
+  def test_argument_forwarding
+    assert_equal 'Hey', @string.try(:sub, 'llo', 'y')
+  end
+
+  def test_block_forwarding
+    assert_equal 'Hey', @string.try(:sub, 'llo') { |match| 'y' }
+  end
+
+  def test_nil_to_type
+    assert_nil nil.try(:to_s)
+    assert_nil nil.try(:to_i)
+  end
+
+  def test_false_try
+    assert_equal 'false', false.try(:to_s)
+  end
+
+  def test_try_only_block
+    assert_equal @string.reverse, @string.try { |s| s.reverse }
+  end
+
+  def test_try_only_block_nil
+    ran = false
+    nil.try { ran = true }
+    assert_equal false, ran
+  end
+
+  def test_try_with_private_method_bang
+    klass = Class.new do
+      private
+
+      def private_method
+        'private method'
+      end
+    end
+
+    assert_raise(NoMethodError) { klass.new.try!(:private_method) }
+  end
+  
+  def test_try_with_private_method
+    klass = Class.new do
+      private
+
+      def private_method
+        'private method'
+      end
+    end
+
+    assert_nil klass.new.try(:private_method)
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/range_ext_test.rb b/app/server/vendor/activesupport/test/core_ext/range_ext_test.rb
new file mode 100644
index 0000000..150e6b6
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/range_ext_test.rb
@@ -0,0 +1,119 @@
+require 'abstract_unit'
+require 'active_support/time'
+require 'active_support/core_ext/range'
+
+class RangeTest < ActiveSupport::TestCase
+  def test_to_s_from_dates
+    date_range = Date.new(2005, 12, 10)..Date.new(2005, 12, 12)
+    assert_equal "BETWEEN '2005-12-10' AND '2005-12-12'", date_range.to_s(:db)
+  end
+
+  def test_to_s_from_times
+    date_range = Time.utc(2005, 12, 10, 15, 30)..Time.utc(2005, 12, 10, 17, 30)
+    assert_equal "BETWEEN '2005-12-10 15:30:00' AND '2005-12-10 17:30:00'", date_range.to_s(:db)
+  end
+  
+  def test_date_range
+    assert_instance_of Range, DateTime.new..DateTime.new
+    assert_instance_of Range, DateTime::Infinity.new..DateTime::Infinity.new
+  end
+
+  def test_overlaps_last_inclusive
+    assert((1..5).overlaps?(5..10))
+  end
+
+  def test_overlaps_last_exclusive
+    assert !(1...5).overlaps?(5..10)
+  end
+
+  def test_overlaps_first_inclusive
+    assert((5..10).overlaps?(1..5))
+  end
+
+  def test_overlaps_first_exclusive
+    assert !(5..10).overlaps?(1...5)
+  end
+
+  def test_should_include_identical_inclusive
+    assert((1..10).include?(1..10))
+  end
+
+  def test_should_include_identical_exclusive
+    assert((1...10).include?(1...10))
+  end
+
+  def test_should_include_other_with_exclusive_end
+    assert((1..10).include?(1...10))
+  end
+
+  def test_should_compare_identical_inclusive
+    assert((1..10) === (1..10))
+  end
+
+  def test_should_compare_identical_exclusive
+    assert((1...10) === (1...10))
+  end
+
+  def test_should_compare_other_with_exclusive_end
+    assert((1..10) === (1...10))
+  end
+
+  def test_exclusive_end_should_not_include_identical_with_inclusive_end
+    assert !(1...10).include?(1..10)
+  end
+
+  def test_should_not_include_overlapping_first
+    assert !(2..8).include?(1..3)
+  end
+
+  def test_should_not_include_overlapping_last
+    assert !(2..8).include?(5..9)
+  end
+
+  def test_should_include_identical_exclusive_with_floats
+    assert((1.0...10.0).include?(1.0...10.0))
+  end
+
+  def test_cover_is_not_override
+    range = (1..3)
+    assert range.method(:include?) != range.method(:cover?)
+  end
+
+  def test_overlaps_on_time
+    time_range_1 = Time.utc(2005, 12, 10, 15, 30)..Time.utc(2005, 12, 10, 17, 30)
+    time_range_2 = Time.utc(2005, 12, 10, 17, 00)..Time.utc(2005, 12, 10, 18, 00)
+    assert time_range_1.overlaps?(time_range_2)
+  end
+
+  def test_no_overlaps_on_time
+    time_range_1 = Time.utc(2005, 12, 10, 15, 30)..Time.utc(2005, 12, 10, 17, 30)
+    time_range_2 = Time.utc(2005, 12, 10, 17, 31)..Time.utc(2005, 12, 10, 18, 00)
+    assert !time_range_1.overlaps?(time_range_2)
+  end
+
+  def test_each_on_time_with_zone
+    twz = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone['Eastern Time (US & Canada)'] , Time.utc(2006,11,28,10,30))
+    assert_raises TypeError do
+      ((twz - 1.hour)..twz).each {}
+    end
+  end
+
+  def test_step_on_time_with_zone
+    twz = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone['Eastern Time (US & Canada)'] , Time.utc(2006,11,28,10,30))
+    assert_raises TypeError do
+      ((twz - 1.hour)..twz).step(1) {}
+    end
+  end
+
+  def test_include_on_time_with_zone
+    twz = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone['Eastern Time (US & Canada)'] , Time.utc(2006,11,28,10,30))
+    assert_raises TypeError do
+      ((twz - 1.hour)..twz).include?(twz)
+    end
+  end
+
+  def test_date_time_with_each
+    datetime = DateTime.now
+    assert ((datetime - 1.hour)..datetime).each {}
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/regexp_ext_test.rb b/app/server/vendor/activesupport/test/core_ext/regexp_ext_test.rb
new file mode 100644
index 0000000..c2398d3
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/regexp_ext_test.rb
@@ -0,0 +1,10 @@
+require 'abstract_unit'
+require 'active_support/core_ext/regexp'
+
+class RegexpExtAccessTests < ActiveSupport::TestCase
+  def test_multiline
+    assert_equal true, //m.multiline?
+    assert_equal false, //.multiline?
+    assert_equal false, /(?m:)/.multiline?
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/string_ext_test.rb b/app/server/vendor/activesupport/test/core_ext/string_ext_test.rb
new file mode 100644
index 0000000..ea12f1c
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/string_ext_test.rb
@@ -0,0 +1,806 @@
+# encoding: utf-8
+require 'date'
+require 'abstract_unit'
+require 'inflector_test_cases'
+require 'constantize_test_cases'
+
+require 'active_support/inflector'
+require 'active_support/core_ext/string'
+require 'active_support/time'
+require 'active_support/core_ext/string/strip'
+require 'active_support/core_ext/string/output_safety'
+require 'active_support/core_ext/string/indent'
+
+class StringInflectionsTest < ActiveSupport::TestCase
+  include InflectorTestCases
+  include ConstantizeTestCases
+
+  def test_strip_heredoc_on_an_empty_string
+    assert_equal '', ''.strip_heredoc
+  end
+
+  def test_strip_heredoc_on_a_string_with_no_lines
+    assert_equal 'x', 'x'.strip_heredoc
+    assert_equal 'x', '    x'.strip_heredoc
+  end
+
+  def test_strip_heredoc_on_a_heredoc_with_no_margin
+    assert_equal "foo\nbar", "foo\nbar".strip_heredoc
+    assert_equal "foo\n  bar", "foo\n  bar".strip_heredoc
+  end
+
+  def test_strip_heredoc_on_a_regular_indented_heredoc
+    assert_equal "foo\n  bar\nbaz\n", <<-EOS.strip_heredoc
+      foo
+        bar
+      baz
+    EOS
+  end
+
+  def test_strip_heredoc_on_a_regular_indented_heredoc_with_blank_lines
+    assert_equal "foo\n  bar\n\nbaz\n", <<-EOS.strip_heredoc
+      foo
+        bar
+
+      baz
+    EOS
+  end
+
+  def test_pluralize
+    SingularToPlural.each do |singular, plural|
+      assert_equal(plural, singular.pluralize)
+    end
+
+    assert_equal("plurals", "plurals".pluralize)
+
+    assert_equal("blargles", "blargle".pluralize(0))
+    assert_equal("blargle", "blargle".pluralize(1))
+    assert_equal("blargles", "blargle".pluralize(2))
+  end
+
+  def test_singularize
+    SingularToPlural.each do |singular, plural|
+      assert_equal(singular, plural.singularize)
+    end
+  end
+
+  def test_titleize
+    MixtureToTitleCase.each do |before, titleized|
+      assert_equal(titleized, before.titleize)
+    end
+  end
+
+  def test_camelize
+    CamelToUnderscore.each do |camel, underscore|
+      assert_equal(camel, underscore.camelize)
+    end
+  end
+
+  def test_camelize_lower
+    assert_equal('capital', 'Capital'.camelize(:lower))
+  end
+
+  def test_dasherize
+    UnderscoresToDashes.each do |underscored, dasherized|
+      assert_equal(dasherized, underscored.dasherize)
+    end
+  end
+
+  def test_underscore
+    CamelToUnderscore.each do |camel, underscore|
+      assert_equal(underscore, camel.underscore)
+    end
+
+    assert_equal "html_tidy", "HTMLTidy".underscore
+    assert_equal "html_tidy_generator", "HTMLTidyGenerator".underscore
+  end
+
+  def test_underscore_to_lower_camel
+    UnderscoreToLowerCamel.each do |underscored, lower_camel|
+      assert_equal(lower_camel, underscored.camelize(:lower))
+    end
+  end
+
+  def test_demodulize
+    assert_equal "Account", "MyApplication::Billing::Account".demodulize
+  end
+
+  def test_deconstantize
+    assert_equal "MyApplication::Billing", "MyApplication::Billing::Account".deconstantize
+  end
+
+  def test_foreign_key
+    ClassNameToForeignKeyWithUnderscore.each do |klass, foreign_key|
+      assert_equal(foreign_key, klass.foreign_key)
+    end
+
+    ClassNameToForeignKeyWithoutUnderscore.each do |klass, foreign_key|
+      assert_equal(foreign_key, klass.foreign_key(false))
+    end
+  end
+
+  def test_tableize
+    ClassNameToTableName.each do |class_name, table_name|
+      assert_equal(table_name, class_name.tableize)
+    end
+  end
+
+  def test_classify
+    ClassNameToTableName.each do |class_name, table_name|
+      assert_equal(class_name, table_name.classify)
+    end
+  end
+
+  def test_string_parameterized_normal
+    StringToParameterized.each do |normal, slugged|
+      assert_equal(normal.parameterize, slugged)
+    end
+  end
+
+  def test_string_parameterized_no_separator
+    StringToParameterizeWithNoSeparator.each do |normal, slugged|
+      assert_equal(normal.parameterize(''), slugged)
+    end
+  end
+
+  def test_string_parameterized_underscore
+    StringToParameterizeWithUnderscore.each do |normal, slugged|
+      assert_equal(normal.parameterize('_'), slugged)
+    end
+  end
+
+  def test_humanize
+    UnderscoreToHuman.each do |underscore, human|
+      assert_equal(human, underscore.humanize)
+    end
+  end
+
+  def test_humanize_without_capitalize
+    UnderscoreToHumanWithoutCapitalize.each do |underscore, human|
+      assert_equal(human, underscore.humanize(capitalize: false))
+    end
+  end
+
+  def test_humanize_with_html_escape
+    assert_equal 'Hello', ERB::Util.html_escape("hello").humanize
+  end
+
+  def test_ord
+    assert_equal 97, 'a'.ord
+    assert_equal 97, 'abc'.ord
+  end
+
+  def test_starts_ends_with_alias
+    s = "hello"
+    assert s.starts_with?('h')
+    assert s.starts_with?('hel')
+    assert !s.starts_with?('el')
+
+    assert s.ends_with?('o')
+    assert s.ends_with?('lo')
+    assert !s.ends_with?('el')
+  end
+
+  def test_string_squish
+    original = %{\u180E\u180E A string surrounded by unicode mongolian vowel separators,
+      with tabs(\t\t), newlines(\n\n), unicode nextlines(\u0085\u0085) and many spaces(  ). \u180E\u180E}
+
+    expected = "A string surrounded by unicode mongolian vowel separators, " +
+      "with tabs( ), newlines( ), unicode nextlines( ) and many spaces( )."
+
+    # Make sure squish returns what we expect:
+    assert_equal original.squish,  expected
+    # But doesn't modify the original string:
+    assert_not_equal original, expected
+
+    # Make sure squish! returns what we expect:
+    assert_equal original.squish!, expected
+    # And changes the original string:
+    assert_equal original, expected
+  end
+
+  def test_string_inquiry
+    assert "production".inquiry.production?
+    assert !"production".inquiry.development?
+  end
+
+  def test_truncate
+    assert_equal "Hello World!", "Hello World!".truncate(12)
+    assert_equal "Hello Wor...", "Hello World!!".truncate(12)
+  end
+
+  def test_truncate_with_omission_and_seperator
+    assert_equal "Hello[...]", "Hello World!".truncate(10, :omission => "[...]")
+    assert_equal "Hello[...]", "Hello Big World!".truncate(13, :omission => "[...]", :separator => ' ')
+    assert_equal "Hello Big[...]", "Hello Big World!".truncate(14, :omission => "[...]", :separator => ' ')
+    assert_equal "Hello Big[...]", "Hello Big World!".truncate(15, :omission => "[...]", :separator => ' ')
+  end
+
+  def test_truncate_with_omission_and_regexp_seperator
+    assert_equal "Hello[...]", "Hello Big World!".truncate(13, :omission => "[...]", :separator => /\s/)
+    assert_equal "Hello Big[...]", "Hello Big World!".truncate(14, :omission => "[...]", :separator => /\s/)
+    assert_equal "Hello Big[...]", "Hello Big World!".truncate(15, :omission => "[...]", :separator => /\s/)
+  end
+
+  def test_truncate_multibyte
+    assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".force_encoding(Encoding::UTF_8),
+      "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding(Encoding::UTF_8).truncate(10)
+  end
+
+  def test_truncate_should_not_be_html_safe
+    assert !"Hello World!".truncate(12).html_safe?
+  end
+
+  def test_remove
+    assert_equal "Summer", "Fast Summer".remove(/Fast /)
+    assert_equal "Summer", "Fast Summer".remove!(/Fast /)
+  end
+
+  def test_constantize
+    run_constantize_tests_on do |string|
+      string.constantize
+    end
+  end
+
+  def test_safe_constantize
+    run_safe_constantize_tests_on do |string|
+      string.safe_constantize
+    end
+  end
+end
+
+class StringAccessTest < ActiveSupport::TestCase
+  test "#at with Fixnum, returns a substring of one character at that position" do
+    assert_equal "h", "hello".at(0)
+  end
+
+  test "#at with Range, returns a substring containing characters at offsets" do
+    assert_equal "lo", "hello".at(-2..-1)
+  end
+
+  test "#at with Regex, returns the matching portion of the string" do
+    assert_equal "lo", "hello".at(/lo/)
+    assert_equal nil, "hello".at(/nonexisting/)
+  end
+
+  test "#from with positive Fixnum, returns substring from the given position to the end" do
+    assert_equal "llo", "hello".from(2)
+  end
+
+  test "#from with negative Fixnum, position is counted from the end" do
+    assert_equal "lo", "hello".from(-2)
+  end
+
+  test "#to with positive Fixnum, substring from the beginning to the given position" do
+    assert_equal "hel", "hello".to(2)
+  end
+
+  test "#to with negative Fixnum, position is counted from the end" do
+    assert_equal "hell", "hello".to(-2)
+  end
+
+  test "#from and #to can be combined" do
+    assert_equal "hello", "hello".from(0).to(-1)
+    assert_equal "ell", "hello".from(1).to(-2)
+  end
+
+  test "#first returns the first character" do
+    assert_equal "h", "hello".first
+    assert_equal 'x', 'x'.first
+  end
+
+  test "#first with Fixnum, returns a substring from the beginning to position" do
+    assert_equal "he", "hello".first(2)
+    assert_equal "", "hello".first(0)
+    assert_equal "hello", "hello".first(10)
+    assert_equal 'x', 'x'.first(4)
+  end
+
+  test "#last returns the last character" do
+    assert_equal "o", "hello".last
+    assert_equal 'x', 'x'.last
+  end
+
+  test "#last with Fixnum, returns a substring from the end to position" do
+    assert_equal "llo", "hello".last(3)
+    assert_equal "hello", "hello".last(10)
+    assert_equal "", "hello".last(0)
+    assert_equal 'x', 'x'.last(4)
+  end
+
+  test "access returns a real string" do
+    hash = {}
+    hash["h"] = true
+    hash["hello123".at(0)] = true
+    assert_equal %w(h), hash.keys
+
+    hash = {}
+    hash["llo"] = true
+    hash["hello".from(2)] = true
+    assert_equal %w(llo), hash.keys
+
+    hash = {}
+    hash["hel"] = true
+    hash["hello".to(2)] = true
+    assert_equal %w(hel), hash.keys
+
+    hash = {}
+    hash["hello"] = true
+    hash["123hello".last(5)] = true
+    assert_equal %w(hello), hash.keys
+
+    hash = {}
+    hash["hello"] = true
+    hash["hello123".first(5)] = true
+    assert_equal %w(hello), hash.keys
+  end
+end
+
+class StringConversionsTest < ActiveSupport::TestCase
+  def test_string_to_time
+    with_env_tz "Europe/Moscow" do
+      assert_equal Time.utc(2005, 2, 27, 23, 50), "2005-02-27 23:50".to_time(:utc)
+      assert_equal Time.local(2005, 2, 27, 23, 50), "2005-02-27 23:50".to_time
+      assert_equal Time.utc(2005, 2, 27, 23, 50, 19, 275038), "2005-02-27T23:50:19.275038".to_time(:utc)
+      assert_equal Time.local(2005, 2, 27, 23, 50, 19, 275038), "2005-02-27T23:50:19.275038".to_time
+      assert_equal Time.utc(2039, 2, 27, 23, 50), "2039-02-27 23:50".to_time(:utc)
+      assert_equal Time.local(2039, 2, 27, 23, 50), "2039-02-27 23:50".to_time
+      assert_equal Time.local(2011, 2, 27, 17, 50), "2011-02-27 13:50 -0100".to_time
+      assert_equal Time.utc(2011, 2, 27, 23, 50), "2011-02-27 22:50 -0100".to_time(:utc)
+      assert_equal Time.local(2005, 2, 27, 22, 50), "2005-02-27 14:50 -0500".to_time
+      assert_nil "".to_time
+    end
+  end
+
+  def test_string_to_time_utc_offset
+    with_env_tz "US/Eastern" do
+      assert_equal 0, "2005-02-27 23:50".to_time(:utc).utc_offset
+      assert_equal(-18000, "2005-02-27 23:50".to_time.utc_offset)
+      assert_equal 0, "2005-02-27 22:50 -0100".to_time(:utc).utc_offset
+      assert_equal(-18000, "2005-02-27 22:50 -0100".to_time.utc_offset)
+    end
+  end
+
+  def test_partial_string_to_time
+    with_env_tz "Europe/Moscow" do
+      now = Time.now
+      assert_equal Time.local(now.year, now.month, now.day, 23, 50), "23:50".to_time
+      assert_equal Time.utc(now.year, now.month, now.day, 23, 50), "23:50".to_time(:utc)
+      assert_equal Time.local(now.year, now.month, now.day, 18, 50), "13:50 -0100".to_time
+      assert_equal Time.utc(now.year, now.month, now.day, 23, 50), "22:50 -0100".to_time(:utc)
+    end
+  end
+
+  def test_standard_time_string_to_time_when_current_time_is_standard_time
+    with_env_tz "US/Eastern" do
+      Time.stubs(:now).returns(Time.local(2012, 1, 1))
+      assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time
+      assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 -0800".to_time
+      assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 -0800".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 -0500".to_time
+      assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 -0500".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 5, 0), "2012-01-01 10:00 UTC".to_time
+      assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00 UTC".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 PST".to_time
+      assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 PST".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 EST".to_time
+      assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 EST".to_time(:utc)
+    end
+  end
+
+  def test_standard_time_string_to_time_when_current_time_is_daylight_savings
+    with_env_tz "US/Eastern" do
+      Time.stubs(:now).returns(Time.local(2012, 7, 1))
+      assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time
+      assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 -0800".to_time
+      assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 -0800".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 -0500".to_time
+      assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 -0500".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 5, 0), "2012-01-01 10:00 UTC".to_time
+      assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00 UTC".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 PST".to_time
+      assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 PST".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 EST".to_time
+      assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 EST".to_time(:utc)
+    end
+  end
+
+  def test_daylight_savings_string_to_time_when_current_time_is_standard_time
+    with_env_tz "US/Eastern" do
+      Time.stubs(:now).returns(Time.local(2012, 1, 1))
+      assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time
+      assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 -0700".to_time
+      assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 -0700".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 -0400".to_time
+      assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 -0400".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 6, 0), "2012-07-01 10:00 UTC".to_time
+      assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00 UTC".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 PDT".to_time
+      assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 PDT".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 EDT".to_time
+      assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 EDT".to_time(:utc)
+    end
+  end
+
+  def test_daylight_savings_string_to_time_when_current_time_is_daylight_savings
+    with_env_tz "US/Eastern" do
+      Time.stubs(:now).returns(Time.local(2012, 7, 1))
+      assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time
+      assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 -0700".to_time
+      assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 -0700".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 -0400".to_time
+      assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 -0400".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 6, 0), "2012-07-01 10:00 UTC".to_time
+      assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00 UTC".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 PDT".to_time
+      assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 PDT".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 EDT".to_time
+      assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 EDT".to_time(:utc)
+    end
+  end
+
+  def test_partial_string_to_time_when_current_time_is_standard_time
+    with_env_tz "US/Eastern" do
+      Time.stubs(:now).returns(Time.local(2012, 1, 1))
+      assert_equal Time.local(2012, 1, 1, 10, 0), "10:00".to_time
+      assert_equal Time.utc(2012, 1, 1, 10, 0),  "10:00".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 6, 0), "10:00 -0100".to_time
+      assert_equal Time.utc(2012, 1, 1, 11, 0), "10:00 -0100".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 10, 0), "10:00 -0500".to_time
+      assert_equal Time.utc(2012, 1, 1, 15, 0), "10:00 -0500".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 5, 0), "10:00 UTC".to_time
+      assert_equal Time.utc(2012, 1, 1, 10, 0), "10:00 UTC".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 13, 0), "10:00 PST".to_time
+      assert_equal Time.utc(2012, 1, 1, 18, 0), "10:00 PST".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 12, 0), "10:00 PDT".to_time
+      assert_equal Time.utc(2012, 1, 1, 17, 0), "10:00 PDT".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 10, 0), "10:00 EST".to_time
+      assert_equal Time.utc(2012, 1, 1, 15, 0), "10:00 EST".to_time(:utc)
+      assert_equal Time.local(2012, 1, 1, 9, 0), "10:00 EDT".to_time
+      assert_equal Time.utc(2012, 1, 1, 14, 0), "10:00 EDT".to_time(:utc)
+    end
+  end
+
+  def test_partial_string_to_time_when_current_time_is_daylight_savings
+    with_env_tz "US/Eastern" do
+      Time.stubs(:now).returns(Time.local(2012, 7, 1))
+      assert_equal Time.local(2012, 7, 1, 10, 0), "10:00".to_time
+      assert_equal Time.utc(2012, 7, 1, 10, 0), "10:00".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 7, 0), "10:00 -0100".to_time
+      assert_equal Time.utc(2012, 7, 1, 11, 0), "10:00 -0100".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 11, 0), "10:00 -0500".to_time
+      assert_equal Time.utc(2012, 7, 1, 15, 0), "10:00 -0500".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 6, 0), "10:00 UTC".to_time
+      assert_equal Time.utc(2012, 7, 1, 10, 0), "10:00 UTC".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 14, 0), "10:00 PST".to_time
+      assert_equal Time.utc(2012, 7, 1, 18, 0), "10:00 PST".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 13, 0), "10:00 PDT".to_time
+      assert_equal Time.utc(2012, 7, 1, 17, 0), "10:00 PDT".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 11, 0), "10:00 EST".to_time
+      assert_equal Time.utc(2012, 7, 1, 15, 0), "10:00 EST".to_time(:utc)
+      assert_equal Time.local(2012, 7, 1, 10, 0), "10:00 EDT".to_time
+      assert_equal Time.utc(2012, 7, 1, 14, 0), "10:00 EDT".to_time(:utc)
+    end
+  end
+
+  def test_string_to_datetime
+    assert_equal DateTime.civil(2039, 2, 27, 23, 50), "2039-02-27 23:50".to_datetime
+    assert_equal 0, "2039-02-27 23:50".to_datetime.offset # use UTC offset
+    assert_equal ::Date::ITALY, "2039-02-27 23:50".to_datetime.start # use Ruby's default start value
+    assert_equal DateTime.civil(2039, 2, 27, 23, 50, 19 + Rational(275038, 1000000), "-04:00"), "2039-02-27T23:50:19.275038-04:00".to_datetime
+    assert_nil "".to_datetime
+  end
+
+  def test_partial_string_to_datetime
+    now = DateTime.now
+    assert_equal DateTime.civil(now.year, now.month, now.day, 23, 50), "23:50".to_datetime
+    assert_equal DateTime.civil(now.year, now.month, now.day, 23, 50, 0, "-04:00"), "23:50 -0400".to_datetime
+  end
+
+  def test_string_to_date
+    assert_equal Date.new(2005, 2, 27), "2005-02-27".to_date
+    assert_nil "".to_date
+    assert_equal Date.new(Date.today.year, 2, 3), "Feb 3rd".to_date
+  end
+
+  protected
+    def with_env_tz(new_tz = 'US/Eastern')
+      old_tz, ENV['TZ'] = ENV['TZ'], new_tz
+      yield
+    ensure
+      old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+    end
+end
+
+class StringBehaviourTest < ActiveSupport::TestCase
+  def test_acts_like_string
+    assert 'Bambi'.acts_like_string?
+  end
+end
+
+class CoreExtStringMultibyteTest < ActiveSupport::TestCase
+  UTF8_STRING = 'こにちわ'
+  ASCII_STRING = 'ohayo'.encode('US-ASCII')
+  EUC_JP_STRING = 'さよなら'.encode('EUC-JP')
+  INVALID_UTF8_STRING = "\270\236\010\210\245"
+
+  def test_core_ext_adds_mb_chars
+    assert_respond_to UTF8_STRING, :mb_chars
+  end
+
+  def test_string_should_recognize_utf8_strings
+    assert UTF8_STRING.is_utf8?
+    assert ASCII_STRING.is_utf8?
+    assert !EUC_JP_STRING.is_utf8?
+    assert !INVALID_UTF8_STRING.is_utf8?
+  end
+
+  def test_mb_chars_returns_instance_of_proxy_class
+    assert_kind_of ActiveSupport::Multibyte.proxy_class, UTF8_STRING.mb_chars
+  end
+end
+
+class OutputSafetyTest < ActiveSupport::TestCase
+  def setup
+    @string = "hello"
+    @object = Class.new(Object) do
+      def to_s
+        "other"
+      end
+    end.new
+  end
+
+  test "A string is unsafe by default" do
+    assert !@string.html_safe?
+  end
+
+  test "A string can be marked safe" do
+    string = @string.html_safe
+    assert string.html_safe?
+  end
+
+  test "Marking a string safe returns the string" do
+    assert_equal @string, @string.html_safe
+  end
+
+  test "A fixnum is safe by default" do
+    assert 5.html_safe?
+  end
+
+  test "a float is safe by default" do
+    assert 5.7.html_safe?
+  end
+
+  test "An object is unsafe by default" do
+    assert !@object.html_safe?
+  end
+
+  test "Adding an object to a safe string returns a safe string" do
+    string = @string.html_safe
+    string << @object
+
+    assert_equal "helloother", string
+    assert string.html_safe?
+  end
+
+  test "Adding a safe string to another safe string returns a safe string" do
+    @other_string = "other".html_safe
+    string = @string.html_safe
+    @combination = @other_string + string
+
+    assert_equal "otherhello", @combination
+    assert @combination.html_safe?
+  end
+
+  test "Adding an unsafe string to a safe string escapes it and returns a safe string" do
+    @other_string = "other".html_safe
+    @combination = @other_string + "<foo>"
+    @other_combination = @string + "<foo>"
+
+    assert_equal "other<foo>", @combination
+    assert_equal "hello<foo>", @other_combination
+
+    assert @combination.html_safe?
+    assert !@other_combination.html_safe?
+  end
+
+  test "Prepending safe onto unsafe yields unsafe" do
+    @string.prepend "other".html_safe
+    assert !@string.html_safe?
+    assert_equal @string, "otherhello"
+  end
+
+  test "Prepending unsafe onto safe yields escaped safe" do
+    other = "other".html_safe
+    other.prepend "<foo>"
+    assert other.html_safe?
+    assert_equal other, "<foo>other"
+  end
+
+  test "Deprecated #prepend! method is still present" do
+    other = "other".html_safe
+
+    assert_deprecated do
+      other.prepend! "<foo>"
+    end
+
+    assert_equal other, "<foo>other"
+  end
+
+  test "Concatting safe onto unsafe yields unsafe" do
+    @other_string = "other"
+
+    string = @string.html_safe
+    @other_string.concat(string)
+    assert !@other_string.html_safe?
+  end
+
+  test "Concatting unsafe onto safe yields escaped safe" do
+    @other_string = "other".html_safe
+    string = @other_string.concat("<foo>")
+    assert_equal "other<foo>", string
+    assert string.html_safe?
+  end
+
+  test "Concatting safe onto safe yields safe" do
+    @other_string = "other".html_safe
+    string = @string.html_safe
+
+    @other_string.concat(string)
+    assert @other_string.html_safe?
+  end
+
+  test "Concatting safe onto unsafe with << yields unsafe" do
+    @other_string = "other"
+    string = @string.html_safe
+
+    @other_string << string
+    assert !@other_string.html_safe?
+  end
+
+  test "Concatting unsafe onto safe with << yields escaped safe" do
+    @other_string = "other".html_safe
+    string = @other_string << "<foo>"
+    assert_equal "other<foo>", string
+    assert string.html_safe?
+  end
+
+  test "Concatting safe onto safe with << yields safe" do
+    @other_string = "other".html_safe
+    string = @string.html_safe
+
+    @other_string << string
+    assert @other_string.html_safe?
+  end
+
+  test "Concatting safe onto unsafe with % yields unsafe" do
+    @other_string = "other%s"
+    string = @string.html_safe
+
+    @other_string = @other_string % string
+    assert !@other_string.html_safe?
+  end
+
+  test "Concatting unsafe onto safe with % yields escaped safe" do
+    @other_string = "other%s".html_safe
+    string = @other_string % "<foo>"
+
+    assert_equal "other<foo>", string
+    assert string.html_safe?
+  end
+
+  test "Concatting safe onto safe with % yields safe" do
+    @other_string = "other%s".html_safe
+    string = @string.html_safe
+
+    @other_string = @other_string % string
+    assert @other_string.html_safe?
+  end
+
+  test "Concatting with % doesn't modify a string" do
+    @other_string = ["<p>", "<b>", "<h1>"]
+    _ = "%s %s %s".html_safe % @other_string
+
+    assert_equal ["<p>", "<b>", "<h1>"], @other_string
+  end
+
+  test "Concatting a fixnum to safe always yields safe" do
+    string = @string.html_safe
+    string = string.concat(13)
+    assert_equal "hello".concat(13), string
+    assert string.html_safe?
+  end
+
+  test 'emits normal string yaml' do
+    assert_equal 'foo'.to_yaml, 'foo'.html_safe.to_yaml(:foo => 1)
+  end
+
+  test "call to_param returns a normal string" do
+    string = @string.html_safe
+    assert string.html_safe?
+    assert !string.to_param.html_safe?
+  end
+
+  test "ERB::Util.html_escape should escape unsafe characters" do
+    string = '<>&"\''
+    expected = '<>&"''
+    assert_equal expected, ERB::Util.html_escape(string)
+  end
+
+  test "ERB::Util.html_escape should correctly handle invalid UTF-8 strings" do
+    string = [192, 60].pack('CC')
+    expected = 192.chr + "<"
+    assert_equal expected, ERB::Util.html_escape(string)
+  end
+
+  test "ERB::Util.html_escape should not escape safe strings" do
+    string = "<b>hello</b>".html_safe
+    assert_equal string, ERB::Util.html_escape(string)
+  end
+end
+
+class StringExcludeTest < ActiveSupport::TestCase
+  test 'inverse of #include' do
+    assert_equal false, 'foo'.exclude?('o')
+    assert_equal true, 'foo'.exclude?('p')
+  end
+end
+
+class StringIndentTest < ActiveSupport::TestCase
+  test 'does not indent strings that only contain newlines (edge cases)' do
+    ['', "\n", "\n" * 7].each do |str|
+      assert_nil str.indent!(8)
+      assert_equal str, str.indent(8)
+      assert_equal str, str.indent(1, "\t")
+    end
+  end
+
+  test "by default, indents with spaces if the existing indentation uses them" do
+    assert_equal "    foo\n      bar", "foo\n  bar".indent(4)
+  end
+
+  test "by default, indents with tabs if the existing indentation uses them" do
+    assert_equal "\tfoo\n\t\t\bar", "foo\n\t\bar".indent(1)
+  end
+
+  test "by default, indents with spaces as a fallback if there is no indentation" do
+    assert_equal "   foo\n   bar\n   baz", "foo\nbar\nbaz".indent(3)
+  end
+
+  # Nothing is said about existing indentation that mixes spaces and tabs, so
+  # there is nothing to test.
+
+  test 'uses the indent char if passed' do
+    assert_equal <<EXPECTED, <<ACTUAL.indent(4, '.')
+....  def some_method(x, y)
+....    some_code
+....  end
+EXPECTED
+  def some_method(x, y)
+    some_code
+  end
+ACTUAL
+
+    assert_equal <<EXPECTED, <<ACTUAL.indent(2, ' ')
+    def some_method(x, y)
+      some_code
+    end
+EXPECTED
+  def some_method(x, y)
+    some_code
+  end
+ACTUAL
+  end
+
+  test "does not indent blank lines by default" do
+    assert_equal " foo\n\n bar", "foo\n\nbar".indent(1)
+  end
+
+  test 'indents blank lines if told so' do
+    assert_equal " foo\n \n bar", "foo\n\nbar".indent(1, nil, true)
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/struct_test.rb b/app/server/vendor/activesupport/test/core_ext/struct_test.rb
new file mode 100644
index 0000000..0dff7b3
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/struct_test.rb
@@ -0,0 +1,10 @@
+require 'abstract_unit'
+require 'active_support/core_ext/struct'
+
+class StructExt < ActiveSupport::TestCase
+  def test_to_h
+    x = Struct.new(:foo, :bar)
+    z = x.new(1, 2)
+    assert_equal({ foo: 1, bar: 2 }, z.to_h)
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/thread_test.rb b/app/server/vendor/activesupport/test/core_ext/thread_test.rb
new file mode 100644
index 0000000..6a7c6e0
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/thread_test.rb
@@ -0,0 +1,75 @@
+require 'abstract_unit'
+require 'active_support/core_ext/thread'
+
+class ThreadExt < ActiveSupport::TestCase
+  def test_main_thread_variable_in_enumerator
+    assert_equal Thread.main, Thread.current
+
+    Thread.current.thread_variable_set :foo, "bar"
+
+    thread, value = Fiber.new {
+      Fiber.yield [Thread.current, Thread.current.thread_variable_get(:foo)]
+    }.resume
+
+    assert_equal Thread.current, thread
+    assert_equal Thread.current.thread_variable_get(:foo), value
+  end
+
+  def test_thread_variable_in_enumerator
+    Thread.new {
+      Thread.current.thread_variable_set :foo, "bar"
+
+      thread, value = Fiber.new {
+        Fiber.yield [Thread.current, Thread.current.thread_variable_get(:foo)]
+      }.resume
+
+      assert_equal Thread.current, thread
+      assert_equal Thread.current.thread_variable_get(:foo), value
+    }.join
+  end
+
+  def test_thread_variables
+    assert_equal [], Thread.new { Thread.current.thread_variables }.join.value
+
+    t = Thread.new {
+      Thread.current.thread_variable_set(:foo, "bar")
+      Thread.current.thread_variables
+    }
+    assert_equal [:foo], t.join.value
+  end
+
+  def test_thread_variable?
+    assert_not Thread.new { Thread.current.thread_variable?("foo") }.join.value
+    t = Thread.new {
+      Thread.current.thread_variable_set("foo", "bar")
+    }.join
+
+    assert t.thread_variable?("foo")
+    assert t.thread_variable?(:foo)
+    assert_not t.thread_variable?(:bar)
+  end
+
+  def test_thread_variable_strings_and_symbols_are_the_same_key
+    t = Thread.new {}.join
+    t.thread_variable_set("foo", "bar")
+    assert_equal "bar", t.thread_variable_get(:foo)
+  end
+
+  def test_thread_variable_frozen
+    t = Thread.new { }.join
+    t.freeze
+    assert_raises(RuntimeError) do
+      t.thread_variable_set(:foo, "bar")
+    end
+  end
+
+  def test_thread_variable_frozen_after_set
+    t = Thread.new { }.join
+    t.thread_variable_set :foo, "bar"
+    t.freeze
+    assert_raises(RuntimeError) do
+      t.thread_variable_set(:baz, "qux")
+    end
+  end
+
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/time_ext_test.rb b/app/server/vendor/activesupport/test/core_ext/time_ext_test.rb
new file mode 100644
index 0000000..e0a4b1b
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/time_ext_test.rb
@@ -0,0 +1,900 @@
+require 'abstract_unit'
+require 'active_support/time'
+require 'core_ext/date_and_time_behavior'
+
+class TimeExtCalculationsTest < ActiveSupport::TestCase
+  def date_time_init(year,month,day,hour,minute,second,usec=0)
+    Time.local(year,month,day,hour,minute,second,usec)
+  end
+
+  include DateAndTimeBehavior
+
+  def test_seconds_since_midnight
+    assert_equal 1,Time.local(2005,1,1,0,0,1).seconds_since_midnight
+    assert_equal 60,Time.local(2005,1,1,0,1,0).seconds_since_midnight
+    assert_equal 3660,Time.local(2005,1,1,1,1,0).seconds_since_midnight
+    assert_equal 86399,Time.local(2005,1,1,23,59,59).seconds_since_midnight
+    assert_equal 60.00001,Time.local(2005,1,1,0,1,0,10).seconds_since_midnight
+  end
+
+  def test_seconds_since_midnight_at_daylight_savings_time_start
+    with_env_tz 'US/Eastern' do
+      # dt: US: 2005 April 3rd 2:00am ST => April 3rd 3:00am DT
+      assert_equal 2*3600-1, Time.local(2005,4,3,1,59,59).seconds_since_midnight, 'just before DST start'
+      assert_equal 2*3600+1, Time.local(2005,4,3,3, 0, 1).seconds_since_midnight, 'just after DST start'
+    end
+
+    with_env_tz 'NZ' do
+      # dt: New Zealand: 2006 October 1st 2:00am ST => October 1st 3:00am DT
+      assert_equal 2*3600-1, Time.local(2006,10,1,1,59,59).seconds_since_midnight, 'just before DST start'
+      assert_equal 2*3600+1, Time.local(2006,10,1,3, 0, 1).seconds_since_midnight, 'just after DST start'
+    end
+  end
+
+  def test_seconds_since_midnight_at_daylight_savings_time_end
+    with_env_tz 'US/Eastern' do
+      # st: US: 2005 October 30th 2:00am DT => October 30th 1:00am ST
+      # avoid setting a time between 1:00 and 2:00 since that requires specifying whether DST is active
+      assert_equal 1*3600-1, Time.local(2005,10,30,0,59,59).seconds_since_midnight, 'just before DST end'
+      assert_equal 3*3600+1, Time.local(2005,10,30,2, 0, 1).seconds_since_midnight, 'just after DST end'
+
+      # now set a time between 1:00 and 2:00 by specifying whether DST is active
+      # uses: Time.local( sec, min, hour, day, month, year, wday, yday, isdst, tz )
+      assert_equal 1*3600+30*60, Time.local(0,30,1,30,10,2005,0,0,true,ENV['TZ']).seconds_since_midnight, 'before DST end'
+      assert_equal 2*3600+30*60, Time.local(0,30,1,30,10,2005,0,0,false,ENV['TZ']).seconds_since_midnight, 'after DST end'
+    end
+
+    with_env_tz 'NZ' do
+      # st: New Zealand: 2006 March 19th 3:00am DT => March 19th 2:00am ST
+      # avoid setting a time between 2:00 and 3:00 since that requires specifying whether DST is active
+      assert_equal 2*3600-1, Time.local(2006,3,19,1,59,59).seconds_since_midnight, 'just before DST end'
+      assert_equal 4*3600+1, Time.local(2006,3,19,3, 0, 1).seconds_since_midnight, 'just after DST end'
+
+      # now set a time between 2:00 and 3:00 by specifying whether DST is active
+      # uses: Time.local( sec, min, hour, day, month, year, wday, yday, isdst, tz )
+      assert_equal 2*3600+30*60, Time.local(0,30,2,19,3,2006,0,0,true, ENV['TZ']).seconds_since_midnight, 'before DST end'
+      assert_equal 3*3600+30*60, Time.local(0,30,2,19,3,2006,0,0,false,ENV['TZ']).seconds_since_midnight, 'after DST end'
+    end
+  end
+
+  def test_seconds_until_end_of_day
+    assert_equal 0, Time.local(2005,1,1,23,59,59).seconds_until_end_of_day
+    assert_equal 1, Time.local(2005,1,1,23,59,58).seconds_until_end_of_day
+    assert_equal 60, Time.local(2005,1,1,23,58,59).seconds_until_end_of_day
+    assert_equal 3660, Time.local(2005,1,1,22,58,59).seconds_until_end_of_day
+    assert_equal 86399, Time.local(2005,1,1,0,0,0).seconds_until_end_of_day
+  end
+
+  def test_seconds_until_end_of_day_at_daylight_savings_time_start
+    with_env_tz 'US/Eastern' do
+      # dt: US: 2005 April 3rd 2:00am ST => April 3rd 3:00am DT
+      assert_equal 21*3600, Time.local(2005,4,3,1,59,59).seconds_until_end_of_day, 'just before DST start'
+      assert_equal 21*3600-2, Time.local(2005,4,3,3,0,1).seconds_until_end_of_day, 'just after DST start'
+    end
+
+    with_env_tz 'NZ' do
+      # dt: New Zealand: 2006 October 1st 2:00am ST => October 1st 3:00am DT
+      assert_equal 21*3600, Time.local(2006,10,1,1,59,59).seconds_until_end_of_day, 'just before DST start'
+      assert_equal 21*3600-2, Time.local(2006,10,1,3,0,1).seconds_until_end_of_day, 'just after DST start'
+    end
+  end
+
+  def test_seconds_until_end_of_day_at_daylight_savings_time_end
+    with_env_tz 'US/Eastern' do
+      # st: US: 2005 October 30th 2:00am DT => October 30th 1:00am ST
+      # avoid setting a time between 1:00 and 2:00 since that requires specifying whether DST is active
+      assert_equal 24*3600, Time.local(2005,10,30,0,59,59).seconds_until_end_of_day, 'just before DST end'
+      assert_equal 22*3600-2, Time.local(2005,10,30,2,0,1).seconds_until_end_of_day, 'just after DST end'
+
+      # now set a time between 1:00 and 2:00 by specifying whether DST is active
+      # uses: Time.local( sec, min, hour, day, month, year, wday, yday, isdst, tz )
+      assert_equal 24*3600-30*60-1, Time.local(0,30,1,30,10,2005,0,0,true,ENV['TZ']).seconds_until_end_of_day, 'before DST end'
+      assert_equal 23*3600-30*60-1, Time.local(0,30,1,30,10,2005,0,0,false,ENV['TZ']).seconds_until_end_of_day, 'after DST end'
+    end
+
+    with_env_tz 'NZ' do
+      # st: New Zealand: 2006 March 19th 3:00am DT => March 19th 2:00am ST
+      # avoid setting a time between 2:00 and 3:00 since that requires specifying whether DST is active
+      assert_equal 23*3600, Time.local(2006,3,19,1,59,59).seconds_until_end_of_day, 'just before DST end'
+      assert_equal 21*3600-2, Time.local(2006,3,19,3,0,1).seconds_until_end_of_day, 'just after DST end'
+
+      # now set a time between 2:00 and 3:00 by specifying whether DST is active
+      # uses: Time.local( sec, min, hour, day, month, year, wday, yday, isdst, tz )
+      assert_equal 23*3600-30*60-1, Time.local(0,30,2,19,3,2006,0,0,true, ENV['TZ']).seconds_until_end_of_day, 'before DST end'
+      assert_equal 22*3600-30*60-1, Time.local(0,30,2,19,3,2006,0,0,false,ENV['TZ']).seconds_until_end_of_day, 'after DST end'
+    end
+  end
+
+  def test_beginning_of_day
+    assert_equal Time.local(2005,2,4,0,0,0), Time.local(2005,2,4,10,10,10).beginning_of_day
+    with_env_tz 'US/Eastern' do
+      assert_equal Time.local(2006,4,2,0,0,0), Time.local(2006,4,2,10,10,10).beginning_of_day, 'start DST'
+      assert_equal Time.local(2006,10,29,0,0,0), Time.local(2006,10,29,10,10,10).beginning_of_day, 'ends DST'
+    end
+    with_env_tz 'NZ' do
+      assert_equal Time.local(2006,3,19,0,0,0), Time.local(2006,3,19,10,10,10).beginning_of_day, 'ends DST'
+      assert_equal Time.local(2006,10,1,0,0,0), Time.local(2006,10,1,10,10,10).beginning_of_day, 'start DST'
+    end
+  end
+
+  def test_middle_of_day
+    assert_equal Time.local(2005,2,4,12,0,0), Time.local(2005,2,4,10,10,10).middle_of_day
+    with_env_tz 'US/Eastern' do
+      assert_equal Time.local(2006,4,2,12,0,0), Time.local(2006,4,2,10,10,10).middle_of_day, 'start DST'
+      assert_equal Time.local(2006,10,29,12,0,0), Time.local(2006,10,29,10,10,10).middle_of_day, 'ends DST'
+    end
+    with_env_tz 'NZ' do
+      assert_equal Time.local(2006,3,19,12,0,0), Time.local(2006,3,19,10,10,10).middle_of_day, 'ends DST'
+      assert_equal Time.local(2006,10,1,12,0,0), Time.local(2006,10,1,10,10,10).middle_of_day, 'start DST'
+    end
+  end
+
+  def test_beginning_of_hour
+    assert_equal Time.local(2005,2,4,19,0,0), Time.local(2005,2,4,19,30,10).beginning_of_hour
+  end
+
+  def test_beginning_of_minute
+    assert_equal Time.local(2005,2,4,19,30,0), Time.local(2005,2,4,19,30,10).beginning_of_minute
+  end
+
+  def test_end_of_day
+    assert_equal Time.local(2007,8,12,23,59,59,Rational(999999999, 1000)), Time.local(2007,8,12,10,10,10).end_of_day
+    with_env_tz 'US/Eastern' do
+      assert_equal Time.local(2007,4,2,23,59,59,Rational(999999999, 1000)), Time.local(2007,4,2,10,10,10).end_of_day, 'start DST'
+      assert_equal Time.local(2007,10,29,23,59,59,Rational(999999999, 1000)), Time.local(2007,10,29,10,10,10).end_of_day, 'ends DST'
+    end
+    with_env_tz 'NZ' do
+      assert_equal Time.local(2006,3,19,23,59,59,Rational(999999999, 1000)), Time.local(2006,3,19,10,10,10).end_of_day, 'ends DST'
+      assert_equal Time.local(2006,10,1,23,59,59,Rational(999999999, 1000)), Time.local(2006,10,1,10,10,10).end_of_day, 'start DST'
+    end
+  end
+
+  def test_end_of_hour
+    assert_equal Time.local(2005,2,4,19,59,59,Rational(999999999, 1000)), Time.local(2005,2,4,19,30,10).end_of_hour
+  end
+
+  def test_end_of_minute
+    assert_equal Time.local(2005,2,4,19,30,59,Rational(999999999, 1000)), Time.local(2005,2,4,19,30,10).end_of_minute
+  end
+
+  def test_last_year
+    assert_equal Time.local(2004,6,5,10),  Time.local(2005,6,5,10,0,0).last_year
+  end
+
+  def test_ago
+    assert_equal Time.local(2005,2,22,10,10,9),  Time.local(2005,2,22,10,10,10).ago(1)
+    assert_equal Time.local(2005,2,22,9,10,10),  Time.local(2005,2,22,10,10,10).ago(3600)
+    assert_equal Time.local(2005,2,20,10,10,10), Time.local(2005,2,22,10,10,10).ago(86400*2)
+    assert_equal Time.local(2005,2,20,9,9,45),   Time.local(2005,2,22,10,10,10).ago(86400*2 + 3600 + 25)
+  end
+
+  def test_daylight_savings_time_crossings_backward_start
+    with_env_tz 'US/Eastern' do
+      # dt: US: 2005 April 3rd 4:18am
+      assert_equal Time.local(2005,4,2,3,18,0), Time.local(2005,4,3,4,18,0).ago(24.hours), 'dt-24.hours=>st'
+      assert_equal Time.local(2005,4,2,3,18,0), Time.local(2005,4,3,4,18,0).ago(86400), 'dt-86400=>st'
+      assert_equal Time.local(2005,4,2,3,18,0), Time.local(2005,4,3,4,18,0).ago(86400.seconds), 'dt-86400.seconds=>st'
+
+      assert_equal Time.local(2005,4,1,4,18,0), Time.local(2005,4,2,4,18,0).ago(24.hours), 'st-24.hours=>st'
+      assert_equal Time.local(2005,4,1,4,18,0), Time.local(2005,4,2,4,18,0).ago(86400), 'st-86400=>st'
+      assert_equal Time.local(2005,4,1,4,18,0), Time.local(2005,4,2,4,18,0).ago(86400.seconds), 'st-86400.seconds=>st'
+    end
+    with_env_tz 'NZ' do
+      # dt: New Zealand: 2006 October 1st 4:18am
+      assert_equal Time.local(2006,9,30,3,18,0), Time.local(2006,10,1,4,18,0).ago(24.hours), 'dt-24.hours=>st'
+      assert_equal Time.local(2006,9,30,3,18,0), Time.local(2006,10,1,4,18,0).ago(86400), 'dt-86400=>st'
+      assert_equal Time.local(2006,9,30,3,18,0), Time.local(2006,10,1,4,18,0).ago(86400.seconds), 'dt-86400.seconds=>st'
+
+      assert_equal Time.local(2006,9,29,4,18,0), Time.local(2006,9,30,4,18,0).ago(24.hours), 'st-24.hours=>st'
+      assert_equal Time.local(2006,9,29,4,18,0), Time.local(2006,9,30,4,18,0).ago(86400), 'st-86400=>st'
+      assert_equal Time.local(2006,9,29,4,18,0), Time.local(2006,9,30,4,18,0).ago(86400.seconds), 'st-86400.seconds=>st'
+    end
+  end
+
+  def test_daylight_savings_time_crossings_backward_end
+    with_env_tz 'US/Eastern' do
+      # st: US: 2005 October 30th 4:03am
+      assert_equal Time.local(2005,10,29,5,3), Time.local(2005,10,30,4,3,0).ago(24.hours), 'st-24.hours=>dt'
+      assert_equal Time.local(2005,10,29,5,3), Time.local(2005,10,30,4,3,0).ago(86400), 'st-86400=>dt'
+      assert_equal Time.local(2005,10,29,5,3), Time.local(2005,10,30,4,3,0).ago(86400.seconds), 'st-86400.seconds=>dt'
+
+      assert_equal Time.local(2005,10,28,4,3), Time.local(2005,10,29,4,3,0).ago(24.hours), 'dt-24.hours=>dt'
+      assert_equal Time.local(2005,10,28,4,3), Time.local(2005,10,29,4,3,0).ago(86400), 'dt-86400=>dt'
+      assert_equal Time.local(2005,10,28,4,3), Time.local(2005,10,29,4,3,0).ago(86400.seconds), 'dt-86400.seconds=>dt'
+    end
+    with_env_tz 'NZ' do
+      # st: New Zealand: 2006 March 19th 4:03am
+      assert_equal Time.local(2006,3,18,5,3), Time.local(2006,3,19,4,3,0).ago(24.hours), 'st-24.hours=>dt'
+      assert_equal Time.local(2006,3,18,5,3), Time.local(2006,3,19,4,3,0).ago(86400), 'st-86400=>dt'
+      assert_equal Time.local(2006,3,18,5,3), Time.local(2006,3,19,4,3,0).ago(86400.seconds), 'st-86400.seconds=>dt'
+
+      assert_equal Time.local(2006,3,17,4,3), Time.local(2006,3,18,4,3,0).ago(24.hours), 'dt-24.hours=>dt'
+      assert_equal Time.local(2006,3,17,4,3), Time.local(2006,3,18,4,3,0).ago(86400), 'dt-86400=>dt'
+      assert_equal Time.local(2006,3,17,4,3), Time.local(2006,3,18,4,3,0).ago(86400.seconds), 'dt-86400.seconds=>dt'
+    end
+  end
+
+  def test_daylight_savings_time_crossings_backward_start_1day
+    with_env_tz 'US/Eastern' do
+      # dt: US: 2005 April 3rd 4:18am
+      assert_equal Time.local(2005,4,2,4,18,0), Time.local(2005,4,3,4,18,0).ago(1.day), 'dt-1.day=>st'
+      assert_equal Time.local(2005,4,1,4,18,0), Time.local(2005,4,2,4,18,0).ago(1.day), 'st-1.day=>st'
+    end
+    with_env_tz 'NZ' do
+      # dt: New Zealand: 2006 October 1st 4:18am
+      assert_equal Time.local(2006,9,30,4,18,0), Time.local(2006,10,1,4,18,0).ago(1.day), 'dt-1.day=>st'
+      assert_equal Time.local(2006,9,29,4,18,0), Time.local(2006,9,30,4,18,0).ago(1.day), 'st-1.day=>st'
+    end
+  end
+
+  def test_daylight_savings_time_crossings_backward_end_1day
+    with_env_tz 'US/Eastern' do
+      # st: US: 2005 October 30th 4:03am
+      assert_equal Time.local(2005,10,29,4,3), Time.local(2005,10,30,4,3,0).ago(1.day), 'st-1.day=>dt'
+      assert_equal Time.local(2005,10,28,4,3), Time.local(2005,10,29,4,3,0).ago(1.day), 'dt-1.day=>dt'
+    end
+    with_env_tz 'NZ' do
+      # st: New Zealand: 2006 March 19th 4:03am
+      assert_equal Time.local(2006,3,18,4,3), Time.local(2006,3,19,4,3,0).ago(1.day), 'st-1.day=>dt'
+      assert_equal Time.local(2006,3,17,4,3), Time.local(2006,3,18,4,3,0).ago(1.day), 'dt-1.day=>dt'
+    end
+  end
+
+  def test_since
+    assert_equal Time.local(2005,2,22,10,10,11), Time.local(2005,2,22,10,10,10).since(1)
+    assert_equal Time.local(2005,2,22,11,10,10), Time.local(2005,2,22,10,10,10).since(3600)
+    assert_equal Time.local(2005,2,24,10,10,10), Time.local(2005,2,22,10,10,10).since(86400*2)
+    assert_equal Time.local(2005,2,24,11,10,35), Time.local(2005,2,22,10,10,10).since(86400*2 + 3600 + 25)
+    # when out of range of Time, returns a DateTime
+    assert_equal DateTime.civil(2038,1,20,11,59,59), Time.utc(2038,1,18,11,59,59).since(86400*2)
+  end
+
+  def test_daylight_savings_time_crossings_forward_start
+    with_env_tz 'US/Eastern' do
+      # st: US: 2005 April 2nd 7:27pm
+      assert_equal Time.local(2005,4,3,20,27,0), Time.local(2005,4,2,19,27,0).since(24.hours), 'st+24.hours=>dt'
+      assert_equal Time.local(2005,4,3,20,27,0), Time.local(2005,4,2,19,27,0).since(86400), 'st+86400=>dt'
+      assert_equal Time.local(2005,4,3,20,27,0), Time.local(2005,4,2,19,27,0).since(86400.seconds), 'st+86400.seconds=>dt'
+
+      assert_equal Time.local(2005,4,4,19,27,0), Time.local(2005,4,3,19,27,0).since(24.hours), 'dt+24.hours=>dt'
+      assert_equal Time.local(2005,4,4,19,27,0), Time.local(2005,4,3,19,27,0).since(86400), 'dt+86400=>dt'
+      assert_equal Time.local(2005,4,4,19,27,0), Time.local(2005,4,3,19,27,0).since(86400.seconds), 'dt+86400.seconds=>dt'
+    end
+    with_env_tz 'NZ' do
+      # st: New Zealand: 2006 September 30th 7:27pm
+      assert_equal Time.local(2006,10,1,20,27,0), Time.local(2006,9,30,19,27,0).since(24.hours), 'st+24.hours=>dt'
+      assert_equal Time.local(2006,10,1,20,27,0), Time.local(2006,9,30,19,27,0).since(86400), 'st+86400=>dt'
+      assert_equal Time.local(2006,10,1,20,27,0), Time.local(2006,9,30,19,27,0).since(86400.seconds), 'st+86400.seconds=>dt'
+
+      assert_equal Time.local(2006,10,2,19,27,0), Time.local(2006,10,1,19,27,0).since(24.hours), 'dt+24.hours=>dt'
+      assert_equal Time.local(2006,10,2,19,27,0), Time.local(2006,10,1,19,27,0).since(86400), 'dt+86400=>dt'
+      assert_equal Time.local(2006,10,2,19,27,0), Time.local(2006,10,1,19,27,0).since(86400.seconds), 'dt+86400.seconds=>dt'
+    end
+  end
+
+  def test_daylight_savings_time_crossings_forward_start_1day
+    with_env_tz 'US/Eastern' do
+      # st: US: 2005 April 2nd 7:27pm
+      assert_equal Time.local(2005,4,3,19,27,0), Time.local(2005,4,2,19,27,0).since(1.day), 'st+1.day=>dt'
+      assert_equal Time.local(2005,4,4,19,27,0), Time.local(2005,4,3,19,27,0).since(1.day), 'dt+1.day=>dt'
+    end
+    with_env_tz 'NZ' do
+      # st: New Zealand: 2006 September 30th 7:27pm
+      assert_equal Time.local(2006,10,1,19,27,0), Time.local(2006,9,30,19,27,0).since(1.day), 'st+1.day=>dt'
+      assert_equal Time.local(2006,10,2,19,27,0), Time.local(2006,10,1,19,27,0).since(1.day), 'dt+1.day=>dt'
+    end
+  end
+
+  def test_daylight_savings_time_crossings_forward_start_tomorrow
+    with_env_tz 'US/Eastern' do
+      # st: US: 2005 April 2nd 7:27pm
+      assert_equal Time.local(2005,4,3,19,27,0), Time.local(2005,4,2,19,27,0).tomorrow, 'st+1.day=>dt'
+      assert_equal Time.local(2005,4,4,19,27,0), Time.local(2005,4,3,19,27,0).tomorrow, 'dt+1.day=>dt'
+    end
+    with_env_tz 'NZ' do
+      # st: New Zealand: 2006 September 30th 7:27pm
+      assert_equal Time.local(2006,10,1,19,27,0), Time.local(2006,9,30,19,27,0).tomorrow, 'st+1.day=>dt'
+      assert_equal Time.local(2006,10,2,19,27,0), Time.local(2006,10,1,19,27,0).tomorrow, 'dt+1.day=>dt'
+    end
+  end
+
+  def test_daylight_savings_time_crossings_backward_start_yesterday
+    with_env_tz 'US/Eastern' do
+      # st: US: 2005 April 2nd 7:27pm
+      assert_equal Time.local(2005,4,2,19,27,0), Time.local(2005,4,3,19,27,0).yesterday, 'dt-1.day=>st'
+      assert_equal Time.local(2005,4,3,19,27,0), Time.local(2005,4,4,19,27,0).yesterday, 'dt-1.day=>dt'
+    end
+    with_env_tz 'NZ' do
+      # st: New Zealand: 2006 September 30th 7:27pm
+      assert_equal Time.local(2006,9,30,19,27,0), Time.local(2006,10,1,19,27,0).yesterday, 'dt-1.day=>st'
+      assert_equal Time.local(2006,10,1,19,27,0), Time.local(2006,10,2,19,27,0).yesterday, 'dt-1.day=>dt'
+    end
+  end
+
+  def test_daylight_savings_time_crossings_forward_end
+    with_env_tz 'US/Eastern' do
+      # dt: US: 2005 October 30th 12:45am
+      assert_equal Time.local(2005,10,30,23,45,0), Time.local(2005,10,30,0,45,0).since(24.hours), 'dt+24.hours=>st'
+      assert_equal Time.local(2005,10,30,23,45,0), Time.local(2005,10,30,0,45,0).since(86400), 'dt+86400=>st'
+      assert_equal Time.local(2005,10,30,23,45,0), Time.local(2005,10,30,0,45,0).since(86400.seconds), 'dt+86400.seconds=>st'
+
+      assert_equal Time.local(2005,11, 1,0,45,0), Time.local(2005,10,31,0,45,0).since(24.hours), 'st+24.hours=>st'
+      assert_equal Time.local(2005,11, 1,0,45,0), Time.local(2005,10,31,0,45,0).since(86400), 'st+86400=>st'
+      assert_equal Time.local(2005,11, 1,0,45,0), Time.local(2005,10,31,0,45,0).since(86400.seconds), 'st+86400.seconds=>st'
+    end
+    with_env_tz 'NZ' do
+      # dt: New Zealand: 2006 March 19th 1:45am
+      assert_equal Time.local(2006,3,20,0,45,0), Time.local(2006,3,19,1,45,0).since(24.hours), 'dt+24.hours=>st'
+      assert_equal Time.local(2006,3,20,0,45,0), Time.local(2006,3,19,1,45,0).since(86400), 'dt+86400=>st'
+      assert_equal Time.local(2006,3,20,0,45,0), Time.local(2006,3,19,1,45,0).since(86400.seconds), 'dt+86400.seconds=>st'
+
+      assert_equal Time.local(2006,3,21,1,45,0), Time.local(2006,3,20,1,45,0).since(24.hours), 'st+24.hours=>st'
+      assert_equal Time.local(2006,3,21,1,45,0), Time.local(2006,3,20,1,45,0).since(86400), 'st+86400=>st'
+      assert_equal Time.local(2006,3,21,1,45,0), Time.local(2006,3,20,1,45,0).since(86400.seconds), 'st+86400.seconds=>st'
+    end
+  end
+
+  def test_daylight_savings_time_crossings_forward_end_1day
+    with_env_tz 'US/Eastern' do
+      # dt: US: 2005 October 30th 12:45am
+      assert_equal Time.local(2005,10,31,0,45,0), Time.local(2005,10,30,0,45,0).since(1.day), 'dt+1.day=>st'
+      assert_equal Time.local(2005,11, 1,0,45,0), Time.local(2005,10,31,0,45,0).since(1.day), 'st+1.day=>st'
+    end
+    with_env_tz 'NZ' do
+      # dt: New Zealand: 2006 March 19th 1:45am
+      assert_equal Time.local(2006,3,20,1,45,0), Time.local(2006,3,19,1,45,0).since(1.day), 'dt+1.day=>st'
+      assert_equal Time.local(2006,3,21,1,45,0), Time.local(2006,3,20,1,45,0).since(1.day), 'st+1.day=>st'
+    end
+  end
+
+  def test_daylight_savings_time_crossings_forward_end_tomorrow
+    with_env_tz 'US/Eastern' do
+      # dt: US: 2005 October 30th 12:45am
+      assert_equal Time.local(2005,10,31,0,45,0), Time.local(2005,10,30,0,45,0).tomorrow, 'dt+1.day=>st'
+      assert_equal Time.local(2005,11, 1,0,45,0), Time.local(2005,10,31,0,45,0).tomorrow, 'st+1.day=>st'
+    end
+    with_env_tz 'NZ' do
+      # dt: New Zealand: 2006 March 19th 1:45am
+      assert_equal Time.local(2006,3,20,1,45,0), Time.local(2006,3,19,1,45,0).tomorrow, 'dt+1.day=>st'
+      assert_equal Time.local(2006,3,21,1,45,0), Time.local(2006,3,20,1,45,0).tomorrow, 'st+1.day=>st'
+    end
+  end
+
+  def test_daylight_savings_time_crossings_backward_end_yesterday
+    with_env_tz 'US/Eastern' do
+      # dt: US: 2005 October 30th 12:45am
+      assert_equal Time.local(2005,10,30,0,45,0), Time.local(2005,10,31,0,45,0).yesterday, 'st-1.day=>dt'
+      assert_equal Time.local(2005,10, 31,0,45,0), Time.local(2005,11,1,0,45,0).yesterday, 'st-1.day=>st'
+    end
+    with_env_tz 'NZ' do
+      # dt: New Zealand: 2006 March 19th 1:45am
+      assert_equal Time.local(2006,3,19,1,45,0), Time.local(2006,3,20,1,45,0).yesterday, 'st-1.day=>dt'
+      assert_equal Time.local(2006,3,20,1,45,0), Time.local(2006,3,21,1,45,0).yesterday, 'st-1.day=>st'
+    end
+  end
+
+  def test_change
+    assert_equal Time.local(2006,2,22,15,15,10), Time.local(2005,2,22,15,15,10).change(:year => 2006)
+    assert_equal Time.local(2005,6,22,15,15,10), Time.local(2005,2,22,15,15,10).change(:month => 6)
+    assert_equal Time.local(2012,9,22,15,15,10), Time.local(2005,2,22,15,15,10).change(:year => 2012, :month => 9)
+    assert_equal Time.local(2005,2,22,16),       Time.local(2005,2,22,15,15,10).change(:hour => 16)
+    assert_equal Time.local(2005,2,22,16,45),    Time.local(2005,2,22,15,15,10).change(:hour => 16, :min => 45)
+    assert_equal Time.local(2005,2,22,15,45),    Time.local(2005,2,22,15,15,10).change(:min => 45)
+
+    assert_equal Time.local(2005,1,2, 5, 0, 0, 0), Time.local(2005,1,2,11,22,33,44).change(:hour => 5)
+    assert_equal Time.local(2005,1,2,11, 6, 0, 0), Time.local(2005,1,2,11,22,33,44).change(:min  => 6)
+    assert_equal Time.local(2005,1,2,11,22, 7, 0), Time.local(2005,1,2,11,22,33,44).change(:sec  => 7)
+    assert_equal Time.local(2005,1,2,11,22,33, 8), Time.local(2005,1,2,11,22,33,44).change(:usec => 8)
+  end
+
+  def test_utc_change
+    assert_equal Time.utc(2006,2,22,15,15,10), Time.utc(2005,2,22,15,15,10).change(:year => 2006)
+    assert_equal Time.utc(2005,6,22,15,15,10), Time.utc(2005,2,22,15,15,10).change(:month => 6)
+    assert_equal Time.utc(2012,9,22,15,15,10), Time.utc(2005,2,22,15,15,10).change(:year => 2012, :month => 9)
+    assert_equal Time.utc(2005,2,22,16),       Time.utc(2005,2,22,15,15,10).change(:hour => 16)
+    assert_equal Time.utc(2005,2,22,16,45),    Time.utc(2005,2,22,15,15,10).change(:hour => 16, :min => 45)
+    assert_equal Time.utc(2005,2,22,15,45),    Time.utc(2005,2,22,15,15,10).change(:min => 45)
+  end
+
+  def test_offset_change
+    assert_equal Time.new(2006,2,22,15,15,10,"-08:00"), Time.new(2005,2,22,15,15,10,"-08:00").change(:year => 2006)
+    assert_equal Time.new(2005,6,22,15,15,10,"-08:00"), Time.new(2005,2,22,15,15,10,"-08:00").change(:month => 6)
+    assert_equal Time.new(2012,9,22,15,15,10,"-08:00"), Time.new(2005,2,22,15,15,10,"-08:00").change(:year => 2012, :month => 9)
+    assert_equal Time.new(2005,2,22,16,0,0,"-08:00"),   Time.new(2005,2,22,15,15,10,"-08:00").change(:hour => 16)
+    assert_equal Time.new(2005,2,22,16,45,0,"-08:00"),  Time.new(2005,2,22,15,15,10,"-08:00").change(:hour => 16, :min => 45)
+    assert_equal Time.new(2005,2,22,15,45,0,"-08:00"),  Time.new(2005,2,22,15,15,10,"-08:00").change(:min => 45)
+  end
+
+  def test_advance
+    assert_equal Time.local(2006,2,28,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => 1)
+    assert_equal Time.local(2005,6,28,15,15,10), Time.local(2005,2,28,15,15,10).advance(:months => 4)
+    assert_equal Time.local(2005,3,21,15,15,10), Time.local(2005,2,28,15,15,10).advance(:weeks => 3)
+    assert_equal Time.local(2005,3,25,3,15,10), Time.local(2005,2,28,15,15,10).advance(:weeks => 3.5)
+    assert_in_delta Time.local(2005,3,26,12,51,10), Time.local(2005,2,28,15,15,10).advance(:weeks => 3.7), 1
+    assert_equal Time.local(2005,3,5,15,15,10), Time.local(2005,2,28,15,15,10).advance(:days => 5)
+    assert_equal Time.local(2005,3,6,3,15,10), Time.local(2005,2,28,15,15,10).advance(:days => 5.5)
+    assert_in_delta Time.local(2005,3,6,8,3,10), Time.local(2005,2,28,15,15,10).advance(:days => 5.7), 1
+    assert_equal Time.local(2012,9,28,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => 7, :months => 7)
+    assert_equal Time.local(2013,10,3,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :days => 5)
+    assert_equal Time.local(2013,10,17,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :weeks => 2, :days => 5)
+    assert_equal Time.local(2001,12,27,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => -3, :months => -2, :days => -1)
+    assert_equal Time.local(2005,2,28,15,15,10), Time.local(2004,2,29,15,15,10).advance(:years => 1) #leap day plus one year
+    assert_equal Time.local(2005,2,28,20,15,10), Time.local(2005,2,28,15,15,10).advance(:hours => 5)
+    assert_equal Time.local(2005,2,28,15,22,10), Time.local(2005,2,28,15,15,10).advance(:minutes => 7)
+    assert_equal Time.local(2005,2,28,15,15,19), Time.local(2005,2,28,15,15,10).advance(:seconds => 9)
+    assert_equal Time.local(2005,2,28,20,22,19), Time.local(2005,2,28,15,15,10).advance(:hours => 5, :minutes => 7, :seconds => 9)
+    assert_equal Time.local(2005,2,28,10,8,1), Time.local(2005,2,28,15,15,10).advance(:hours => -5, :minutes => -7, :seconds => -9)
+    assert_equal Time.local(2013,10,17,20,22,19), Time.local(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :weeks => 2, :days => 5, :hours => 5, :minutes => 7, :seconds => 9)
+  end
+
+  def test_utc_advance
+    assert_equal Time.utc(2006,2,22,15,15,10), Time.utc(2005,2,22,15,15,10).advance(:years => 1)
+    assert_equal Time.utc(2005,6,22,15,15,10), Time.utc(2005,2,22,15,15,10).advance(:months => 4)
+    assert_equal Time.utc(2005,3,21,15,15,10), Time.utc(2005,2,28,15,15,10).advance(:weeks => 3)
+    assert_equal Time.utc(2005,3,25,3,15,10), Time.utc(2005,2,28,15,15,10).advance(:weeks => 3.5)
+    assert_in_delta Time.utc(2005,3,26,12,51,10), Time.utc(2005,2,28,15,15,10).advance(:weeks => 3.7), 1
+    assert_equal Time.utc(2005,3,5,15,15,10), Time.utc(2005,2,28,15,15,10).advance(:days => 5)
+    assert_equal Time.utc(2005,3,6,3,15,10), Time.utc(2005,2,28,15,15,10).advance(:days => 5.5)
+    assert_in_delta Time.utc(2005,3,6,8,3,10), Time.utc(2005,2,28,15,15,10).advance(:days => 5.7), 1
+    assert_equal Time.utc(2012,9,22,15,15,10), Time.utc(2005,2,22,15,15,10).advance(:years => 7, :months => 7)
+    assert_equal Time.utc(2013,10,3,15,15,10), Time.utc(2005,2,22,15,15,10).advance(:years => 7, :months => 19, :days => 11)
+    assert_equal Time.utc(2013,10,17,15,15,10), Time.utc(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :weeks => 2, :days => 5)
+    assert_equal Time.utc(2001,12,27,15,15,10), Time.utc(2005,2,28,15,15,10).advance(:years => -3, :months => -2, :days => -1)
+    assert_equal Time.utc(2005,2,28,15,15,10), Time.utc(2004,2,29,15,15,10).advance(:years => 1) #leap day plus one year
+    assert_equal Time.utc(2005,2,28,20,15,10), Time.utc(2005,2,28,15,15,10).advance(:hours => 5)
+    assert_equal Time.utc(2005,2,28,15,22,10), Time.utc(2005,2,28,15,15,10).advance(:minutes => 7)
+    assert_equal Time.utc(2005,2,28,15,15,19), Time.utc(2005,2,28,15,15,10).advance(:seconds => 9)
+    assert_equal Time.utc(2005,2,28,20,22,19), Time.utc(2005,2,28,15,15,10).advance(:hours => 5, :minutes => 7, :seconds => 9)
+    assert_equal Time.utc(2005,2,28,10,8,1), Time.utc(2005,2,28,15,15,10).advance(:hours => -5, :minutes => -7, :seconds => -9)
+    assert_equal Time.utc(2013,10,17,20,22,19), Time.utc(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :weeks => 2, :days => 5, :hours => 5, :minutes => 7, :seconds => 9)
+  end
+
+  def test_offset_advance
+    assert_equal Time.new(2006,2,22,15,15,10,'-08:00'), Time.new(2005,2,22,15,15,10,'-08:00').advance(:years => 1)
+    assert_equal Time.new(2005,6,22,15,15,10,'-08:00'), Time.new(2005,2,22,15,15,10,'-08:00').advance(:months => 4)
+    assert_equal Time.new(2005,3,21,15,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:weeks => 3)
+    assert_equal Time.new(2005,3,25,3,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:weeks => 3.5)
+    assert_in_delta Time.new(2005,3,26,12,51,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:weeks => 3.7), 1
+    assert_equal Time.new(2005,3,5,15,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:days => 5)
+    assert_equal Time.new(2005,3,6,3,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:days => 5.5)
+    assert_in_delta Time.new(2005,3,6,8,3,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:days => 5.7), 1
+    assert_equal Time.new(2012,9,22,15,15,10,'-08:00'), Time.new(2005,2,22,15,15,10,'-08:00').advance(:years => 7, :months => 7)
+    assert_equal Time.new(2013,10,3,15,15,10,'-08:00'), Time.new(2005,2,22,15,15,10,'-08:00').advance(:years => 7, :months => 19, :days => 11)
+    assert_equal Time.new(2013,10,17,15,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:years => 7, :months => 19, :weeks => 2, :days => 5)
+    assert_equal Time.new(2001,12,27,15,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:years => -3, :months => -2, :days => -1)
+    assert_equal Time.new(2005,2,28,15,15,10,'-08:00'), Time.new(2004,2,29,15,15,10,'-08:00').advance(:years => 1) #leap day plus one year
+    assert_equal Time.new(2005,2,28,20,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:hours => 5)
+    assert_equal Time.new(2005,2,28,15,22,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:minutes => 7)
+    assert_equal Time.new(2005,2,28,15,15,19,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:seconds => 9)
+    assert_equal Time.new(2005,2,28,20,22,19,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:hours => 5, :minutes => 7, :seconds => 9)
+    assert_equal Time.new(2005,2,28,10,8,1,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:hours => -5, :minutes => -7, :seconds => -9)
+    assert_equal Time.new(2013,10,17,20,22,19,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:years => 7, :months => 19, :weeks => 2, :days => 5, :hours => 5, :minutes => 7, :seconds => 9)
+  end
+
+  def test_advance_with_nsec
+    t = Time.at(0, Rational(108635108, 1000))
+    assert_equal t, t.advance(:months => 0)
+  end
+
+  def test_advance_gregorian_proleptic
+    assert_equal Time.local(1582,10,14,15,15,10), Time.local(1582,10,15,15,15,10).advance(:days => -1)
+    assert_equal Time.local(1582,10,15,15,15,10), Time.local(1582,10,14,15,15,10).advance(:days => 1)
+    assert_equal Time.local(1582,10,5,15,15,10), Time.local(1582,10,4,15,15,10).advance(:days => 1)
+    assert_equal Time.local(1582,10,4,15,15,10), Time.local(1582,10,5,15,15,10).advance(:days => -1)
+  end
+
+  def test_last_week
+    with_env_tz 'US/Eastern' do
+      assert_equal Time.local(2005,2,21), Time.local(2005,3,1,15,15,10).last_week
+      assert_equal Time.local(2005,2,22), Time.local(2005,3,1,15,15,10).last_week(:tuesday)
+      assert_equal Time.local(2005,2,25), Time.local(2005,3,1,15,15,10).last_week(:friday)
+      assert_equal Time.local(2006,10,30), Time.local(2006,11,6,0,0,0).last_week
+      assert_equal Time.local(2006,11,15), Time.local(2006,11,23,0,0,0).last_week(:wednesday)
+    end
+  end
+
+  def test_next_week_near_daylight_start
+    with_env_tz 'US/Eastern' do
+      assert_equal Time.local(2006,4,3), Time.local(2006,4,2,23,1,0).next_week, 'just crossed standard => daylight'
+    end
+    with_env_tz 'NZ' do
+      assert_equal Time.local(2006,10,2), Time.local(2006,10,1,23,1,0).next_week, 'just crossed standard => daylight'
+    end
+  end
+
+  def test_next_week_near_daylight_end
+    with_env_tz 'US/Eastern' do
+      assert_equal Time.local(2006,10,30), Time.local(2006,10,29,23,1,0).next_week, 'just crossed daylight => standard'
+    end
+    with_env_tz 'NZ' do
+      assert_equal Time.local(2006,3,20), Time.local(2006,3,19,23,1,0).next_week, 'just crossed daylight => standard'
+    end
+  end
+
+  def test_to_s
+    time = Time.utc(2005, 2, 21, 17, 44, 30.12345678901)
+    assert_equal time.to_default_s,                 time.to_s
+    assert_equal time.to_default_s,                 time.to_s(:doesnt_exist)
+    assert_equal "2005-02-21 17:44:30",             time.to_s(:db)
+    assert_equal "21 Feb 17:44",                    time.to_s(:short)
+    assert_equal "17:44",                           time.to_s(:time)
+    assert_equal "20050221174430",                  time.to_s(:number)
+    assert_equal "20050221174430123456789",         time.to_s(:nsec)
+    assert_equal "February 21, 2005 17:44",         time.to_s(:long)
+    assert_equal "February 21st, 2005 17:44",       time.to_s(:long_ordinal)
+    with_env_tz "UTC" do
+      assert_equal "Mon, 21 Feb 2005 17:44:30 +0000", time.to_s(:rfc822)
+    end
+    with_env_tz "US/Central" do
+      assert_equal "Thu, 05 Feb 2009 14:30:05 -0600", Time.local(2009, 2, 5, 14, 30, 5).to_s(:rfc822)
+      assert_equal "Mon, 09 Jun 2008 04:05:01 -0500", Time.local(2008, 6, 9, 4, 5, 1).to_s(:rfc822)
+      assert_equal "2009-02-05T14:30:05-06:00", Time.local(2009, 2, 5, 14, 30, 5).to_s(:iso8601)
+      assert_equal "2008-06-09T04:05:01-05:00", Time.local(2008, 6, 9, 4, 5, 1).to_s(:iso8601)
+      assert_equal "2009-02-05T14:30:05Z", Time.utc(2009, 2, 5, 14, 30, 5).to_s(:iso8601)
+    end
+  end
+
+  def test_custom_date_format
+    Time::DATE_FORMATS[:custom] = '%Y%m%d%H%M%S'
+    assert_equal '20050221143000', Time.local(2005, 2, 21, 14, 30, 0).to_s(:custom)
+    Time::DATE_FORMATS.delete(:custom)
+  end
+
+  def test_to_date
+    assert_equal Date.new(2005, 2, 21), Time.local(2005, 2, 21, 17, 44, 30).to_date
+  end
+
+  def test_to_datetime
+    assert_equal Time.utc(2005, 2, 21, 17, 44, 30).to_datetime, DateTime.civil(2005, 2, 21, 17, 44, 30, 0)
+    with_env_tz 'US/Eastern' do
+      assert_equal Time.local(2005, 2, 21, 17, 44, 30).to_datetime, DateTime.civil(2005, 2, 21, 17, 44, 30, Rational(Time.local(2005, 2, 21, 17, 44, 30).utc_offset, 86400))
+    end
+    with_env_tz 'NZ' do
+      assert_equal Time.local(2005, 2, 21, 17, 44, 30).to_datetime, DateTime.civil(2005, 2, 21, 17, 44, 30, Rational(Time.local(2005, 2, 21, 17, 44, 30).utc_offset, 86400))
+    end
+    assert_equal ::Date::ITALY, Time.utc(2005, 2, 21, 17, 44, 30).to_datetime.start # use Ruby's default start value
+  end
+
+  def test_to_time
+    with_env_tz 'US/Eastern' do
+      assert_equal Time, Time.local(2005, 2, 21, 17, 44, 30).to_time.class
+      assert_equal Time.local(2005, 2, 21, 17, 44, 30), Time.local(2005, 2, 21, 17, 44, 30).to_time
+      assert_equal Time.local(2005, 2, 21, 17, 44, 30).utc_offset, Time.local(2005, 2, 21, 17, 44, 30).to_time.utc_offset
+    end
+  end
+
+  # NOTE: this test seems to fail (changeset 1958) only on certain platforms,
+  # like OSX, and FreeBSD 5.4.
+  def test_fp_inaccuracy_ticket_1836
+    midnight = Time.local(2005, 2, 21, 0, 0, 0)
+    assert_equal midnight.midnight, (midnight + 1.hour + 0.000001).midnight
+  end
+
+  def test_days_in_month_with_year
+    assert_equal 31, Time.days_in_month(1, 2005)
+
+    assert_equal 28, Time.days_in_month(2, 2005)
+    assert_equal 29, Time.days_in_month(2, 2004)
+    assert_equal 29, Time.days_in_month(2, 2000)
+    assert_equal 28, Time.days_in_month(2, 1900)
+
+    assert_equal 31, Time.days_in_month(3, 2005)
+    assert_equal 30, Time.days_in_month(4, 2005)
+    assert_equal 31, Time.days_in_month(5, 2005)
+    assert_equal 30, Time.days_in_month(6, 2005)
+    assert_equal 31, Time.days_in_month(7, 2005)
+    assert_equal 31, Time.days_in_month(8, 2005)
+    assert_equal 30, Time.days_in_month(9, 2005)
+    assert_equal 31, Time.days_in_month(10, 2005)
+    assert_equal 30, Time.days_in_month(11, 2005)
+    assert_equal 31, Time.days_in_month(12, 2005)
+  end
+
+  def test_days_in_month_feb_in_common_year_without_year_arg
+    Time.stubs(:now).returns(Time.utc(2007))
+    assert_equal 28, Time.days_in_month(2)
+  end
+
+  def test_days_in_month_feb_in_leap_year_without_year_arg
+    Time.stubs(:now).returns(Time.utc(2008))
+    assert_equal 29, Time.days_in_month(2)
+  end
+
+  def test_last_month_on_31st
+    assert_equal Time.local(2004, 2, 29), Time.local(2004, 3, 31).last_month
+  end
+
+  def test_xmlschema_is_available
+    assert_nothing_raised { Time.now.xmlschema }
+  end
+
+  def test_today_with_time_local
+    Date.stubs(:current).returns(Date.new(2000, 1, 1))
+    assert_equal false, Time.local(1999,12,31,23,59,59).today?
+    assert_equal true,  Time.local(2000,1,1,0).today?
+    assert_equal true,  Time.local(2000,1,1,23,59,59).today?
+    assert_equal false, Time.local(2000,1,2,0).today?
+  end
+
+  def test_today_with_time_utc
+    Date.stubs(:current).returns(Date.new(2000, 1, 1))
+    assert_equal false, Time.utc(1999,12,31,23,59,59).today?
+    assert_equal true,  Time.utc(2000,1,1,0).today?
+    assert_equal true,  Time.utc(2000,1,1,23,59,59).today?
+    assert_equal false, Time.utc(2000,1,2,0).today?
+  end
+
+  def test_past_with_time_current_as_time_local
+    with_env_tz 'US/Eastern' do
+      Time.stubs(:current).returns(Time.local(2005,2,10,15,30,45))
+      assert_equal true,  Time.local(2005,2,10,15,30,44).past?
+      assert_equal false,  Time.local(2005,2,10,15,30,45).past?
+      assert_equal false,  Time.local(2005,2,10,15,30,46).past?
+      assert_equal true,  Time.utc(2005,2,10,20,30,44).past?
+      assert_equal false,  Time.utc(2005,2,10,20,30,45).past?
+      assert_equal false,  Time.utc(2005,2,10,20,30,46).past?
+    end
+  end
+
+  def test_past_with_time_current_as_time_with_zone
+    with_env_tz 'US/Eastern' do
+      twz = Time.utc(2005,2,10,15,30,45).in_time_zone('Central Time (US & Canada)')
+      Time.stubs(:current).returns(twz)
+      assert_equal true,  Time.local(2005,2,10,10,30,44).past?
+      assert_equal false,  Time.local(2005,2,10,10,30,45).past?
+      assert_equal false,  Time.local(2005,2,10,10,30,46).past?
+      assert_equal true,  Time.utc(2005,2,10,15,30,44).past?
+      assert_equal false,  Time.utc(2005,2,10,15,30,45).past?
+      assert_equal false,  Time.utc(2005,2,10,15,30,46).past?
+    end
+  end
+
+  def test_future_with_time_current_as_time_local
+    with_env_tz 'US/Eastern' do
+      Time.stubs(:current).returns(Time.local(2005,2,10,15,30,45))
+      assert_equal false,  Time.local(2005,2,10,15,30,44).future?
+      assert_equal false,  Time.local(2005,2,10,15,30,45).future?
+      assert_equal true,  Time.local(2005,2,10,15,30,46).future?
+      assert_equal false,  Time.utc(2005,2,10,20,30,44).future?
+      assert_equal false,  Time.utc(2005,2,10,20,30,45).future?
+      assert_equal true,  Time.utc(2005,2,10,20,30,46).future?
+    end
+  end
+
+  def test_future_with_time_current_as_time_with_zone
+    with_env_tz 'US/Eastern' do
+      twz = Time.utc(2005,2,10,15,30,45).in_time_zone('Central Time (US & Canada)')
+      Time.stubs(:current).returns(twz)
+      assert_equal false,  Time.local(2005,2,10,10,30,44).future?
+      assert_equal false,  Time.local(2005,2,10,10,30,45).future?
+      assert_equal true,  Time.local(2005,2,10,10,30,46).future?
+      assert_equal false,  Time.utc(2005,2,10,15,30,44).future?
+      assert_equal false,  Time.utc(2005,2,10,15,30,45).future?
+      assert_equal true,  Time.utc(2005,2,10,15,30,46).future?
+    end
+  end
+
+  def test_acts_like_time
+    assert Time.new.acts_like_time?
+  end
+
+  def test_formatted_offset_with_utc
+    assert_equal '+00:00', Time.utc(2000).formatted_offset
+    assert_equal '+0000', Time.utc(2000).formatted_offset(false)
+    assert_equal 'UTC', Time.utc(2000).formatted_offset(true, 'UTC')
+  end
+
+  def test_formatted_offset_with_local
+    with_env_tz 'US/Eastern' do
+      assert_equal '-05:00', Time.local(2000).formatted_offset
+      assert_equal '-0500', Time.local(2000).formatted_offset(false)
+      assert_equal '-04:00', Time.local(2000, 7).formatted_offset
+      assert_equal '-0400', Time.local(2000, 7).formatted_offset(false)
+    end
+  end
+
+  def test_compare_with_time
+    assert_equal  1, Time.utc(2000) <=> Time.utc(1999, 12, 31, 23, 59, 59, 999)
+    assert_equal  0, Time.utc(2000) <=> Time.utc(2000, 1, 1, 0, 0, 0)
+    assert_equal(-1, Time.utc(2000) <=> Time.utc(2000, 1, 1, 0, 0, 0, 001))
+  end
+
+  def test_compare_with_datetime
+    assert_equal  1, Time.utc(2000) <=> DateTime.civil(1999, 12, 31, 23, 59, 59)
+    assert_equal  0, Time.utc(2000) <=> DateTime.civil(2000, 1, 1, 0, 0, 0)
+    assert_equal(-1, Time.utc(2000) <=> DateTime.civil(2000, 1, 1, 0, 0, 1))
+  end
+
+  def test_compare_with_time_with_zone
+    assert_equal  1, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(1999, 12, 31, 23, 59, 59), ActiveSupport::TimeZone['UTC'] )
+    assert_equal  0, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['UTC'] )
+    assert_equal(-1, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1), ActiveSupport::TimeZone['UTC'] ))
+  end
+
+  def test_at_with_datetime
+    assert_equal Time.utc(2000, 1, 1, 0, 0, 0), Time.at(DateTime.civil(2000, 1, 1, 0, 0, 0))
+
+    # Only test this if the underlying Time.at raises a TypeError
+    begin
+      Time.at_without_coercion(Time.now, 0)
+    rescue TypeError
+      assert_raise(TypeError) { assert_equal(Time.utc(2000, 1, 1, 0, 0, 0), Time.at(DateTime.civil(2000, 1, 1, 0, 0, 0), 0)) }
+    end
+  end
+
+  def test_at_with_datetime_returns_local_time
+    with_env_tz 'US/Eastern' do
+      dt = DateTime.civil(2000, 1, 1, 0, 0, 0, '+0')
+      assert_equal Time.local(1999, 12, 31, 19, 0, 0), Time.at(dt)
+      assert_equal 'EST', Time.at(dt).zone
+      assert_equal(-18000, Time.at(dt).utc_offset)
+
+      # Daylight savings
+      dt = DateTime.civil(2000, 7, 1, 1, 0, 0, '+1')
+      assert_equal Time.local(2000, 6, 30, 20, 0, 0), Time.at(dt)
+      assert_equal 'EDT', Time.at(dt).zone
+      assert_equal(-14400, Time.at(dt).utc_offset)
+    end
+  end
+
+  def test_at_with_time_with_zone
+    assert_equal Time.utc(2000, 1, 1, 0, 0, 0), Time.at(ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['UTC']))
+
+    # Only test this if the underlying Time.at raises a TypeError
+    begin
+      Time.at_without_coercion(Time.now, 0)
+    rescue TypeError
+      assert_raise(TypeError) { assert_equal(Time.utc(2000, 1, 1, 0, 0, 0), Time.at(ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['UTC']), 0)) }
+    end
+  end
+
+  def test_at_with_time_with_zone_returns_local_time
+    with_env_tz 'US/Eastern' do
+      twz = ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['London'])
+      assert_equal Time.local(1999, 12, 31, 19, 0, 0), Time.at(twz)
+      assert_equal 'EST', Time.at(twz).zone
+      assert_equal(-18000, Time.at(twz).utc_offset)
+
+      # Daylight savings
+      twz = ActiveSupport::TimeWithZone.new(Time.utc(2000, 7, 1, 0, 0, 0), ActiveSupport::TimeZone['London'])
+      assert_equal Time.local(2000, 6, 30, 20, 0, 0), Time.at(twz)
+      assert_equal 'EDT', Time.at(twz).zone
+      assert_equal(-14400, Time.at(twz).utc_offset)
+    end
+  end
+
+  def test_at_with_time_microsecond_precision
+    assert_equal Time.at(Time.utc(2000, 1, 1, 0, 0, 0, 111)).to_f, Time.utc(2000, 1, 1, 0, 0, 0, 111).to_f
+  end
+
+  def test_at_with_utc_time
+    with_env_tz 'US/Eastern' do
+      assert_equal Time.utc(2000), Time.at(Time.utc(2000))
+      assert_equal 'UTC', Time.at(Time.utc(2000)).zone
+      assert_equal(0, Time.at(Time.utc(2000)).utc_offset)
+    end
+  end
+
+  def test_at_with_local_time
+    with_env_tz 'US/Eastern' do
+      assert_equal Time.local(2000), Time.at(Time.local(2000))
+      assert_equal 'EST', Time.at(Time.local(2000)).zone
+      assert_equal(-18000, Time.at(Time.local(2000)).utc_offset)
+
+      assert_equal Time.local(2000, 7, 1), Time.at(Time.local(2000, 7, 1))
+      assert_equal 'EDT', Time.at(Time.local(2000, 7, 1)).zone
+      assert_equal(-14400, Time.at(Time.local(2000, 7, 1)).utc_offset)
+    end
+  end
+
+  def test_eql?
+    assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']) )
+    assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) )
+    assert_equal false,Time.utc(2000, 1, 1, 0, 0, 1).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']) )
+  end
+
+  def test_minus_with_time_with_zone
+    assert_equal  86_400.0, Time.utc(2000, 1, 2) - ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1), ActiveSupport::TimeZone['UTC'] )
+  end
+
+  def test_minus_with_datetime
+    assert_equal  86_400.0, Time.utc(2000, 1, 2) - DateTime.civil(2000, 1, 1)
+  end
+
+  def test_time_created_with_local_constructor_cannot_represent_times_during_hour_skipped_by_dst
+    with_env_tz 'US/Eastern' do
+      # On Apr 2 2006 at 2:00AM in US, clocks were moved forward to 3:00AM.
+      # Therefore, 2AM EST doesn't exist for this date; Time.local fails over to 3:00AM EDT
+      assert_equal Time.local(2006, 4, 2, 3), Time.local(2006, 4, 2, 2)
+      assert Time.local(2006, 4, 2, 2).dst?
+    end
+  end
+
+  def test_case_equality
+    assert Time === Time.utc(2000)
+    assert Time === ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC'])
+    assert Time === Class.new(Time).utc(2000)
+    assert_equal false, Time === DateTime.civil(2000)
+    assert_equal false, Class.new(Time) === Time.utc(2000)
+    assert_equal false, Class.new(Time) === ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC'])
+  end
+
+  def test_all_day
+    assert_equal Time.local(2011,6,7,0,0,0)..Time.local(2011,6,7,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_day
+  end
+
+  def test_all_day_with_timezone
+    beginning_of_day = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone["Hawaii"], Time.local(2011,6,7,0,0,0))
+    end_of_day = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone["Hawaii"], Time.local(2011,6,7,23,59,59,Rational(999999999, 1000)))
+
+    assert_equal beginning_of_day, ActiveSupport::TimeWithZone.new(Time.local(2011,6,7,10,10,10), ActiveSupport::TimeZone["Hawaii"]).all_day.begin
+    assert_equal end_of_day, ActiveSupport::TimeWithZone.new(Time.local(2011,6,7,10,10,10), ActiveSupport::TimeZone["Hawaii"]).all_day.end
+  end
+
+  def test_all_week
+    assert_equal Time.local(2011,6,6,0,0,0)..Time.local(2011,6,12,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_week
+    assert_equal Time.local(2011,6,5,0,0,0)..Time.local(2011,6,11,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_week(:sunday)
+  end
+
+  def test_all_month
+    assert_equal Time.local(2011,6,1,0,0,0)..Time.local(2011,6,30,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_month
+  end
+
+  def test_all_quarter
+    assert_equal Time.local(2011,4,1,0,0,0)..Time.local(2011,6,30,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_quarter
+  end
+
+  def test_all_year
+    assert_equal Time.local(2011,1,1,0,0,0)..Time.local(2011,12,31,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_year
+  end
+
+  protected
+    def with_env_tz(new_tz = 'US/Eastern')
+      old_tz, ENV['TZ'] = ENV['TZ'], new_tz
+      yield
+    ensure
+      old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+    end
+
+end
+
+class TimeExtMarshalingTest < ActiveSupport::TestCase
+  def test_marshaling_with_utc_instance
+    t = Time.utc(2000)
+    unmarshaled = Marshal.load(Marshal.dump(t))
+    assert_equal "UTC", unmarshaled.zone
+    assert_equal t, unmarshaled
+  end
+
+  def test_marshaling_with_local_instance
+    t = Time.local(2000)
+    unmarshaled = Marshal.load(Marshal.dump(t))
+    assert_equal t.zone, unmarshaled.zone
+    assert_equal t, unmarshaled
+  end
+
+  def test_marshaling_with_frozen_utc_instance
+    t = Time.utc(2000).freeze
+    unmarshaled = Marshal.load(Marshal.dump(t))
+    assert_equal "UTC", unmarshaled.zone
+    assert_equal t, unmarshaled
+  end
+
+  def test_marshaling_with_frozen_local_instance
+    t = Time.local(2000).freeze
+    unmarshaled = Marshal.load(Marshal.dump(t))
+    assert_equal t.zone, unmarshaled.zone
+    assert_equal t, unmarshaled
+  end
+
+  def test_marshalling_preserves_fractional_seconds
+    t = Time.parse('00:00:00.500')
+    unmarshaled = Marshal.load(Marshal.dump(t))
+    assert_equal t.to_f, unmarshaled.to_f
+    assert_equal t, unmarshaled
+  end
+
+  def test_last_quarter_on_31st
+    assert_equal Time.local(2004, 2, 29), Time.local(2004, 5, 31).last_quarter
+  end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/time_with_zone_test.rb b/app/server/vendor/activesupport/test/core_ext/time_with_zone_test.rb
new file mode 100644
index 0000000..7fe4d4a
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/time_with_zone_test.rb
@@ -0,0 +1,1138 @@
+require 'abstract_unit'
+require 'active_support/time'
+
+class TimeWithZoneTest < ActiveSupport::TestCase
+
+  def setup
+    @utc = Time.utc(2000, 1, 1, 0)
+    @time_zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    @twz = ActiveSupport::TimeWithZone.new(@utc, @time_zone)
+  end
+
+  def test_utc
+    assert_equal @utc, @twz.utc
+  end
+
+  def test_time
+    assert_equal Time.utc(1999, 12, 31, 19), @twz.time
+  end
+
+  def test_time_zone
+    assert_equal @time_zone, @twz.time_zone
+  end
+
+  def test_in_time_zone
+    Time.use_zone 'Alaska' do
+      assert_equal ActiveSupport::TimeWithZone.new(@utc, ActiveSupport::TimeZone['Alaska']), @twz.in_time_zone
+    end
+  end
+
+  def test_in_time_zone_with_argument
+    assert_equal ActiveSupport::TimeWithZone.new(@utc, ActiveSupport::TimeZone['Alaska']), @twz.in_time_zone('Alaska')
+  end
+
+  def test_in_time_zone_with_new_zone_equal_to_old_zone_does_not_create_new_object
+    assert_equal @twz.object_id, @twz.in_time_zone(ActiveSupport::TimeZone['Eastern Time (US & Canada)']).object_id
+  end
+
+  def test_in_time_zone_with_bad_argument
+    assert_raise(ArgumentError) { @twz.in_time_zone('No such timezone exists') }
+    assert_raise(ArgumentError) { @twz.in_time_zone(-15.hours) }
+    assert_raise(ArgumentError) { @twz.in_time_zone(Object.new) }
+  end
+
+  def test_localtime
+    assert_equal @twz.localtime, @twz.utc.getlocal
+  end
+
+  def test_utc?
+    assert_equal false, @twz.utc?
+    assert_equal true, ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']).utc?
+  end
+
+  def test_formatted_offset
+    assert_equal '-05:00', @twz.formatted_offset
+    assert_equal '-04:00', ActiveSupport::TimeWithZone.new(Time.utc(2000, 6), @time_zone).formatted_offset #dst
+  end
+
+  def test_dst?
+    assert_equal false, @twz.dst?
+    assert_equal true, ActiveSupport::TimeWithZone.new(Time.utc(2000, 6), @time_zone).dst?
+  end
+
+  def test_zone
+    assert_equal 'EST', @twz.zone
+    assert_equal 'EDT', ActiveSupport::TimeWithZone.new(Time.utc(2000, 6), @time_zone).zone #dst
+  end
+
+  def test_nsec
+    local     = Time.local(2011,6,7,23,59,59,Rational(999999999, 1000))
+    with_zone = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone["Hawaii"], local)
+
+    assert_equal local.nsec, with_zone.nsec
+    assert_equal with_zone.nsec, 999999999
+  end
+
+  def test_strftime
+    assert_equal '1999-12-31 19:00:00 EST -0500', @twz.strftime('%Y-%m-%d %H:%M:%S %Z %z')
+  end
+
+  def test_inspect
+    assert_equal 'Fri, 31 Dec 1999 19:00:00 EST -05:00', @twz.inspect
+  end
+
+  def test_to_s
+    assert_equal '1999-12-31 19:00:00 -0500', @twz.to_s
+  end
+
+  def test_to_formatted_s
+    assert_equal '1999-12-31 19:00:00 -0500', @twz.to_formatted_s
+  end
+
+  def test_to_s_db
+    assert_equal '2000-01-01 00:00:00', @twz.to_s(:db)
+  end
+
+  def test_xmlschema
+    assert_equal "1999-12-31T19:00:00-05:00", @twz.xmlschema
+  end
+
+  def test_xmlschema_with_fractional_seconds
+    @twz += 0.1234560001 # advance the time by a fraction of a second
+    assert_equal "1999-12-31T19:00:00.123-05:00", @twz.xmlschema(3)
+    assert_equal "1999-12-31T19:00:00.123456-05:00", @twz.xmlschema(6)
+    assert_equal "1999-12-31T19:00:00.123456-05:00", @twz.xmlschema(12)
+  end
+
+  def test_xmlschema_with_fractional_seconds_lower_than_hundred_thousand
+    @twz += 0.001234 # advance the time by a fraction
+    assert_equal "1999-12-31T19:00:00.001-05:00", @twz.xmlschema(3)
+    assert_equal "1999-12-31T19:00:00.001234-05:00", @twz.xmlschema(6)
+    assert_equal "1999-12-31T19:00:00.001234-05:00", @twz.xmlschema(12)
+  end
+
+  def test_xmlschema_with_nil_fractional_seconds
+    assert_equal "1999-12-31T19:00:00-05:00", @twz.xmlschema(nil)
+  end
+
+  def test_to_yaml
+    assert_match(/^--- 2000-01-01 00:00:00(\.0+)?\s*Z\n/, @twz.to_yaml)
+  end
+
+  def test_ruby_to_yaml
+    assert_match(/---\s*\n:twz: 2000-01-01 00:00:00(\.0+)?\s*Z\n/, {:twz => @twz}.to_yaml)
+  end
+
+  def test_httpdate
+    assert_equal 'Sat, 01 Jan 2000 00:00:00 GMT', @twz.httpdate
+  end
+
+  def test_rfc2822
+    assert_equal "Fri, 31 Dec 1999 19:00:00 -0500", @twz.rfc2822
+  end
+
+  def test_compare_with_time
+    assert_equal  1, @twz <=> Time.utc(1999, 12, 31, 23, 59, 59)
+    assert_equal  0, @twz <=> Time.utc(2000, 1, 1, 0, 0, 0)
+    assert_equal(-1, @twz <=> Time.utc(2000, 1, 1, 0, 0, 1))
+  end
+
+  def test_compare_with_datetime
+    assert_equal  1, @twz <=> DateTime.civil(1999, 12, 31, 23, 59, 59)
+    assert_equal  0, @twz <=> DateTime.civil(2000, 1, 1, 0, 0, 0)
+    assert_equal(-1, @twz <=> DateTime.civil(2000, 1, 1, 0, 0, 1))
+  end
+
+  def test_compare_with_time_with_zone
+    assert_equal  1, @twz <=> ActiveSupport::TimeWithZone.new( Time.utc(1999, 12, 31, 23, 59, 59), ActiveSupport::TimeZone['UTC'] )
+    assert_equal  0, @twz <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['UTC'] )
+    assert_equal(-1, @twz <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1), ActiveSupport::TimeZone['UTC'] ))
+  end
+
+  def test_between?
+    assert @twz.between?(Time.utc(1999,12,31,23,59,59), Time.utc(2000,1,1,0,0,1))
+    assert_equal false, @twz.between?(Time.utc(2000,1,1,0,0,1), Time.utc(2000,1,1,0,0,2))
+  end
+
+  def test_today
+    Date.stubs(:current).returns(Date.new(2000, 1, 1))
+    assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.utc(1999,12,31,23,59,59) ).today?
+    assert_equal true,  ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.utc(2000,1,1,0) ).today?
+    assert_equal true,  ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.utc(2000,1,1,23,59,59) ).today?
+    assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.utc(2000,1,2,0) ).today?
+  end
+
+  def test_past_with_time_current_as_time_local
+    with_env_tz 'US/Eastern' do
+      Time.stubs(:current).returns(Time.local(2005,2,10,15,30,45))
+      assert_equal true,  ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,44)).past?
+      assert_equal false,  ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45)).past?
+      assert_equal false,  ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,46)).past?
+    end
+  end
+
+  def test_past_with_time_current_as_time_with_zone
+    twz = ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45) )
+    Time.stubs(:current).returns(twz)
+    assert_equal true,  ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,44)).past?
+    assert_equal false,  ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45)).past?
+    assert_equal false,  ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,46)).past?
+  end
+
+  def test_future_with_time_current_as_time_local
+    with_env_tz 'US/Eastern' do
+      Time.stubs(:current).returns(Time.local(2005,2,10,15,30,45))
+      assert_equal false,  ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,44)).future?
+      assert_equal false,  ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45)).future?
+      assert_equal true,  ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,46)).future?
+    end
+  end
+
+  def test_future_with_time_current_as_time_with_zone
+    twz = ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45) )
+    Time.stubs(:current).returns(twz)
+    assert_equal false,  ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,44)).future?
+    assert_equal false,  ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45)).future?
+    assert_equal true,  ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,46)).future?
+  end
+
+  def test_eql?
+    assert_equal true, @twz.eql?(Time.utc(2000))
+    assert_equal true, @twz.eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) )
+    assert_equal false, @twz.eql?( Time.utc(2000, 1, 1, 0, 0, 1) )
+    assert_equal false, @twz.eql?( DateTime.civil(1999, 12, 31, 23, 59, 59) )
+  end
+
+  def test_hash
+    assert_equal Time.utc(2000).hash, @twz.hash
+    assert_equal Time.utc(2000).hash, ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]).hash
+  end
+
+  def test_plus_with_integer
+    assert_equal Time.utc(1999, 12, 31, 19, 0 ,5), (@twz + 5).time
+  end
+
+  def test_plus_with_integer_when_self_wraps_datetime
+    datetime = DateTime.civil(2000, 1, 1, 0)
+    twz = ActiveSupport::TimeWithZone.new(datetime, @time_zone)
+    assert_equal DateTime.civil(1999, 12, 31, 19, 0 ,5), (twz + 5).time
+  end
+
+  def test_plus_when_crossing_time_class_limit
+    twz = ActiveSupport::TimeWithZone.new(Time.utc(2038, 1, 19), @time_zone)
+    assert_equal [0, 0, 19, 19, 1, 2038], (twz + 86_400).to_a[0,6]
+  end
+
+  def test_plus_with_duration
+    assert_equal Time.utc(2000, 1, 5, 19, 0 ,0), (@twz + 5.days).time
+  end
+
+  def test_minus_with_integer
+    assert_equal Time.utc(1999, 12, 31, 18, 59 ,55), (@twz - 5).time
+  end
+
+  def test_minus_with_integer_when_self_wraps_datetime
+    datetime = DateTime.civil(2000, 1, 1, 0)
+    twz = ActiveSupport::TimeWithZone.new(datetime, @time_zone)
+    assert_equal DateTime.civil(1999, 12, 31, 18, 59 ,55), (twz - 5).time
+  end
+
+  def test_minus_with_duration
+    assert_equal Time.utc(1999, 12, 26, 19, 0 ,0), (@twz - 5.days).time
+  end
+
+  def test_minus_with_time
+    assert_equal  86_400.0,  ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 2), ActiveSupport::TimeZone['UTC'] ) - Time.utc(2000, 1, 1)
+    assert_equal  86_400.0,  ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 2), ActiveSupport::TimeZone['Hawaii'] ) - Time.utc(2000, 1, 1)
+  end
+
+  def test_minus_with_time_with_zone
+    twz1 = ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1), ActiveSupport::TimeZone['UTC'] )
+    twz2 = ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 2), ActiveSupport::TimeZone['UTC'] )
+    assert_equal  86_400.0,  twz2 - twz1
+  end
+
+  def test_minus_with_datetime
+    assert_equal  86_400.0,  ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 2), ActiveSupport::TimeZone['UTC'] ) - DateTime.civil(2000, 1, 1)
+  end
+
+  def test_minus_with_wrapped_datetime
+    assert_equal  86_400.0,  ActiveSupport::TimeWithZone.new( DateTime.civil(2000, 1, 2), ActiveSupport::TimeZone['UTC'] ) - Time.utc(2000, 1, 1)
+    assert_equal  86_400.0,  ActiveSupport::TimeWithZone.new( DateTime.civil(2000, 1, 2), ActiveSupport::TimeZone['UTC'] ) - DateTime.civil(2000, 1, 1)
+  end
+
+  def test_plus_and_minus_enforce_spring_dst_rules
+    utc = Time.utc(2006,4,2,6,59,59) # == Apr 2 2006 01:59:59 EST; i.e., 1 second before daylight savings start
+    twz = ActiveSupport::TimeWithZone.new(utc, @time_zone)
+    assert_equal Time.utc(2006,4,2,1,59,59), twz.time
+    assert_equal false, twz.dst?
+    assert_equal 'EST', twz.zone
+    twz = twz + 1
+    assert_equal Time.utc(2006,4,2,3), twz.time # adding 1 sec springs forward to 3:00AM EDT
+    assert_equal true, twz.dst?
+    assert_equal 'EDT', twz.zone
+    twz = twz - 1 # subtracting 1 second takes goes back to 1:59:59AM EST
+    assert_equal Time.utc(2006,4,2,1,59,59), twz.time
+    assert_equal false, twz.dst?
+    assert_equal 'EST', twz.zone
+  end
+
+  def test_plus_and_minus_enforce_fall_dst_rules
+    utc = Time.utc(2006,10,29,5,59,59) # == Oct 29 2006 01:59:59 EST; i.e., 1 second before daylight savings end
+    twz = ActiveSupport::TimeWithZone.new(utc, @time_zone)
+    assert_equal Time.utc(2006,10,29,1,59,59), twz.time
+    assert_equal true, twz.dst?
+    assert_equal 'EDT', twz.zone
+    twz = twz + 1
+    assert_equal Time.utc(2006,10,29,1), twz.time # adding 1 sec falls back from 1:59:59 EDT to 1:00AM EST
+    assert_equal false, twz.dst?
+    assert_equal 'EST', twz.zone
+    twz = twz - 1
+    assert_equal Time.utc(2006,10,29,1,59,59), twz.time # subtracting 1 sec goes back to 1:59:59AM EDT
+    assert_equal true, twz.dst?
+    assert_equal 'EDT', twz.zone
+  end
+
+  def test_to_a
+    assert_equal [45, 30, 5, 1, 2, 2000, 2, 32, false, "HST"], ActiveSupport::TimeWithZone.new( Time.utc(2000, 2, 1, 15, 30, 45), ActiveSupport::TimeZone['Hawaii'] ).to_a
+  end
+
+  def test_to_f
+    result = ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1), ActiveSupport::TimeZone['Hawaii'] ).to_f
+    assert_equal 946684800.0, result
+    assert_kind_of Float, result
+  end
+
+  def test_to_i
+    result = ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1), ActiveSupport::TimeZone['Hawaii'] ).to_i
+    assert_equal 946684800, result
+    assert_kind_of Integer, result
+  end
+
+  def test_to_i_with_wrapped_datetime
+    datetime = DateTime.civil(2000, 1, 1, 0)
+    twz = ActiveSupport::TimeWithZone.new(datetime, @time_zone)
+    assert_equal 946684800, twz.to_i
+  end
+
+  def test_to_r
+    result = ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1), ActiveSupport::TimeZone['Hawaii']).to_r
+    assert_equal Rational(946684800, 1), result
+    assert_kind_of Rational, result
+  end
+
+  def test_time_at
+    time = ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1), ActiveSupport::TimeZone['Hawaii'])
+    assert_equal time, Time.at(time)
+  end
+
+  def test_to_time
+    with_env_tz 'US/Eastern' do
+      assert_equal Time, @twz.to_time.class
+      assert_equal Time.local(1999, 12, 31, 19), @twz.to_time
+      assert_equal Time.local(1999, 12, 31, 19).utc_offset, @twz.to_time.utc_offset
+    end
+  end
+
+  def test_to_date
+    # 1 sec before midnight Jan 1 EST
+    assert_equal Date.new(1999, 12, 31), ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 4, 59, 59), ActiveSupport::TimeZone['Eastern Time (US & Canada)'] ).to_date
+    # midnight Jan 1 EST
+    assert_equal Date.new(2000,  1,  1), ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 5,  0,  0), ActiveSupport::TimeZone['Eastern Time (US & Canada)'] ).to_date
+    # 1 sec before midnight Jan 2 EST
+    assert_equal Date.new(2000,  1,  1), ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 2, 4, 59, 59), ActiveSupport::TimeZone['Eastern Time (US & Canada)'] ).to_date
+    # midnight Jan 2 EST
+    assert_equal Date.new(2000,  1,  2), ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 2, 5,  0,  0), ActiveSupport::TimeZone['Eastern Time (US & Canada)'] ).to_date
+  end
+
+  def test_to_datetime
+    assert_equal DateTime.civil(1999, 12, 31, 19, 0, 0, Rational(-18_000, 86_400)),  @twz.to_datetime
+  end
+
+  def test_acts_like_time
+    assert @twz.acts_like?(:time)
+    assert ActiveSupport::TimeWithZone.new(DateTime.civil(2000), @time_zone).acts_like?(:time)
+  end
+
+  def test_acts_like_date
+    assert_equal false, @twz.acts_like?(:date)
+    assert_equal false, ActiveSupport::TimeWithZone.new(DateTime.civil(2000), @time_zone).acts_like?(:date)
+  end
+
+  def test_is_a
+    assert_kind_of Time, @twz
+    assert_kind_of Time, @twz
+    assert_kind_of ActiveSupport::TimeWithZone, @twz
+  end
+
+  def test_class_name
+    assert_equal 'Time', ActiveSupport::TimeWithZone.name
+  end
+
+  def test_method_missing_with_time_return_value
+    assert_instance_of ActiveSupport::TimeWithZone, @twz.months_since(1)
+    assert_equal Time.utc(2000, 1, 31, 19, 0 ,0), @twz.months_since(1).time
+  end
+
+  def test_marshal_dump_and_load
+    marshal_str = Marshal.dump(@twz)
+    mtime = Marshal.load(marshal_str)
+    assert_equal Time.utc(2000, 1, 1, 0), mtime.utc
+    assert mtime.utc.utc?
+    assert_equal ActiveSupport::TimeZone['Eastern Time (US & Canada)'], mtime.time_zone
+    assert_equal Time.utc(1999, 12, 31, 19), mtime.time
+    assert mtime.time.utc?
+    assert_equal @twz.inspect, mtime.inspect
+  end
+
+  def test_marshal_dump_and_load_with_tzinfo_identifier
+    twz = ActiveSupport::TimeWithZone.new(@utc, TZInfo::Timezone.get('America/New_York'))
+    marshal_str = Marshal.dump(twz)
+    mtime = Marshal.load(marshal_str)
+    assert_equal Time.utc(2000, 1, 1, 0), mtime.utc
+    assert mtime.utc.utc?
+    assert_equal 'America/New_York', mtime.time_zone.name
+    assert_equal Time.utc(1999, 12, 31, 19), mtime.time
+    assert mtime.time.utc?
+    assert_equal @twz.inspect, mtime.inspect
+  end
+
+  def test_freeze
+    @twz.freeze
+    assert @twz.frozen?
+  end
+
+  def test_freeze_preloads_instance_variables
+    @twz.freeze
+    assert_nothing_raised do
+      @twz.period
+      @twz.time
+    end
+  end
+
+  def test_method_missing_with_non_time_return_value
+    @twz.time.expects(:foo).returns('bar')
+    assert_equal 'bar', @twz.foo
+  end
+
+  def test_date_part_value_methods
+    twz = ActiveSupport::TimeWithZone.new(Time.utc(1999,12,31,19,18,17,500), @time_zone)
+    twz.expects(:method_missing).never
+    assert_equal 1999, twz.year
+    assert_equal 12, twz.month
+    assert_equal 31, twz.day
+    assert_equal 14, twz.hour
+    assert_equal 18, twz.min
+    assert_equal 17, twz.sec
+    assert_equal 500, twz.usec
+    assert_equal 5, twz.wday
+    assert_equal 365, twz.yday
+  end
+
+  def test_usec_returns_0_when_datetime_is_wrapped
+    twz = ActiveSupport::TimeWithZone.new(DateTime.civil(2000), @time_zone)
+    assert_equal 0, twz.usec
+  end
+
+  def test_usec_returns_sec_fraction_when_datetime_is_wrapped
+    twz = ActiveSupport::TimeWithZone.new(DateTime.civil(2000, 1, 1, 0, 0, Rational(1,2)), @time_zone)
+    assert_equal 500000, twz.usec
+  end
+
+  def test_nsec_returns_sec_fraction_when_datetime_is_wrapped
+    twz = ActiveSupport::TimeWithZone.new(DateTime.civil(2000, 1, 1, 0, 0, Rational(1,2)), @time_zone)
+    assert_equal 500000000, twz.nsec
+  end
+
+  def test_utc_to_local_conversion_saves_period_in_instance_variable
+    assert_nil @twz.instance_variable_get('@period')
+    @twz.time
+    assert_kind_of TZInfo::TimezonePeriod, @twz.instance_variable_get('@period')
+  end
+
+  def test_instance_created_with_local_time_returns_correct_utc_time
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(1999, 12, 31, 19))
+    assert_equal Time.utc(2000), twz.utc
+  end
+
+  def test_instance_created_with_local_time_enforces_spring_dst_rules
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,4,2,2)) # first second of DST
+    assert_equal Time.utc(2006,4,2,3), twz.time # springs forward to 3AM
+    assert_equal true, twz.dst?
+    assert_equal 'EDT', twz.zone
+  end
+
+  def test_instance_created_with_local_time_enforces_fall_dst_rules
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,10,29,1)) # 1AM can be either DST or non-DST; we'll pick DST
+    assert_equal Time.utc(2006,10,29,1), twz.time
+    assert_equal true, twz.dst?
+    assert_equal 'EDT', twz.zone
+  end
+
+  def test_ruby_19_weekday_name_query_methods
+    %w(sunday? monday? tuesday? wednesday? thursday? friday? saturday?).each do |name|
+      assert_respond_to @twz, name
+      assert_equal @twz.send(name), @twz.method(name).call
+    end
+  end
+
+  def test_utc_to_local_conversion_with_far_future_datetime
+    assert_equal [0,0,19,31,12,2049], ActiveSupport::TimeWithZone.new(DateTime.civil(2050), @time_zone).to_a[0,6]
+  end
+
+  def test_local_to_utc_conversion_with_far_future_datetime
+    assert_equal DateTime.civil(2050).to_f, ActiveSupport::TimeWithZone.new(nil, @time_zone, DateTime.civil(2049,12,31,19)).to_f
+  end
+
+  def test_change
+    assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect
+    assert_equal "Mon, 31 Dec 2001 19:00:00 EST -05:00", @twz.change(:year => 2001).inspect
+    assert_equal "Wed, 31 Mar 1999 19:00:00 EST -05:00", @twz.change(:month => 3).inspect
+    assert_equal "Wed, 03 Mar 1999 19:00:00 EST -05:00", @twz.change(:month => 2).inspect
+    assert_equal "Wed, 15 Dec 1999 19:00:00 EST -05:00", @twz.change(:day => 15).inspect
+    assert_equal "Fri, 31 Dec 1999 06:00:00 EST -05:00", @twz.change(:hour => 6).inspect
+    assert_equal "Fri, 31 Dec 1999 19:15:00 EST -05:00", @twz.change(:min => 15).inspect
+    assert_equal "Fri, 31 Dec 1999 19:00:30 EST -05:00", @twz.change(:sec => 30).inspect
+  end
+
+  def test_change_at_dst_boundary
+    twz = ActiveSupport::TimeWithZone.new(Time.at(1319936400).getutc, ActiveSupport::TimeZone['Madrid'])
+    assert_equal twz, twz.change(:min => 0)
+  end
+
+  def test_round_at_dst_boundary
+    twz = ActiveSupport::TimeWithZone.new(Time.at(1319936400).getutc, ActiveSupport::TimeZone['Madrid'])
+    assert_equal twz, twz.round
+  end
+
+  def test_advance
+    assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect
+    assert_equal "Mon, 31 Dec 2001 19:00:00 EST -05:00", @twz.advance(:years => 2).inspect
+    assert_equal "Fri, 31 Mar 2000 19:00:00 EST -05:00", @twz.advance(:months => 3).inspect
+    assert_equal "Tue, 04 Jan 2000 19:00:00 EST -05:00", @twz.advance(:days => 4).inspect
+    assert_equal "Sat, 01 Jan 2000 01:00:00 EST -05:00", @twz.advance(:hours => 6).inspect
+    assert_equal "Fri, 31 Dec 1999 19:15:00 EST -05:00", @twz.advance(:minutes => 15).inspect
+    assert_equal "Fri, 31 Dec 1999 19:00:30 EST -05:00", @twz.advance(:seconds => 30).inspect
+  end
+
+  def test_beginning_of_year
+    assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect
+    assert_equal "Fri, 01 Jan 1999 00:00:00 EST -05:00", @twz.beginning_of_year.inspect
+  end
+
+  def test_end_of_year
+    assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect
+    assert_equal "Fri, 31 Dec 1999 23:59:59 EST -05:00", @twz.end_of_year.inspect
+  end
+
+  def test_beginning_of_month
+    assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect
+    assert_equal "Wed, 01 Dec 1999 00:00:00 EST -05:00", @twz.beginning_of_month.inspect
+  end
+
+  def test_end_of_month
+    assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect
+    assert_equal "Fri, 31 Dec 1999 23:59:59 EST -05:00", @twz.end_of_month.inspect
+  end
+
+  def test_beginning_of_day
+    assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect
+    assert_equal "Fri, 31 Dec 1999 00:00:00 EST -05:00", @twz.beginning_of_day.inspect
+  end
+
+  def test_end_of_day
+    assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect
+    assert_equal "Fri, 31 Dec 1999 23:59:59 EST -05:00", @twz.end_of_day.inspect
+  end
+
+  def test_beginning_of_hour
+    utc = Time.utc(2000, 1, 1, 0, 30)
+    twz = ActiveSupport::TimeWithZone.new(utc, @time_zone)
+    assert_equal "Fri, 31 Dec 1999 19:30:00 EST -05:00", twz.inspect
+    assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", twz.beginning_of_hour.inspect
+  end
+
+  def test_end_of_hour
+    utc = Time.utc(2000, 1, 1, 0, 30)
+    twz = ActiveSupport::TimeWithZone.new(utc, @time_zone)
+    assert_equal "Fri, 31 Dec 1999 19:30:00 EST -05:00", twz.inspect
+    assert_equal "Fri, 31 Dec 1999 19:59:59 EST -05:00", twz.end_of_hour.inspect
+  end
+
+  def test_beginning_of_minute
+    utc = Time.utc(2000, 1, 1, 0, 30, 10)
+    twz = ActiveSupport::TimeWithZone.new(utc, @time_zone)
+    assert_equal "Fri, 31 Dec 1999 19:30:10 EST -05:00", twz.inspect
+    assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", twz.beginning_of_hour.inspect
+  end
+
+  def test_end_of_minute
+    utc = Time.utc(2000, 1, 1, 0, 30, 10)
+    twz = ActiveSupport::TimeWithZone.new(utc, @time_zone)
+    assert_equal "Fri, 31 Dec 1999 19:30:10 EST -05:00", twz.inspect
+    assert_equal "Fri, 31 Dec 1999 19:30:59 EST -05:00", twz.end_of_minute.inspect
+  end
+
+  def test_since
+    assert_equal "Fri, 31 Dec 1999 19:00:01 EST -05:00", @twz.since(1).inspect
+  end
+
+  def test_ago
+    assert_equal "Fri, 31 Dec 1999 18:59:59 EST -05:00", @twz.ago(1).inspect
+  end
+
+  def test_seconds_since_midnight
+    assert_equal 19 * 60 * 60, @twz.seconds_since_midnight
+  end
+
+  def test_advance_1_year_from_leap_day
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2004,2,29))
+    assert_equal "Mon, 28 Feb 2005 00:00:00 EST -05:00", twz.advance(:years => 1).inspect
+    assert_equal "Mon, 28 Feb 2005 00:00:00 EST -05:00", twz.years_since(1).inspect
+    assert_equal "Mon, 28 Feb 2005 00:00:00 EST -05:00", twz.since(1.year).inspect
+    assert_equal "Mon, 28 Feb 2005 00:00:00 EST -05:00", (twz + 1.year).inspect
+  end
+
+  def test_advance_1_month_from_last_day_of_january
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2005,1,31))
+    assert_equal "Mon, 28 Feb 2005 00:00:00 EST -05:00", twz.advance(:months => 1).inspect
+    assert_equal "Mon, 28 Feb 2005 00:00:00 EST -05:00", twz.months_since(1).inspect
+    assert_equal "Mon, 28 Feb 2005 00:00:00 EST -05:00", twz.since(1.month).inspect
+    assert_equal "Mon, 28 Feb 2005 00:00:00 EST -05:00", (twz + 1.month).inspect
+  end
+
+  def test_advance_1_month_from_last_day_of_january_during_leap_year
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2000,1,31))
+    assert_equal "Tue, 29 Feb 2000 00:00:00 EST -05:00", twz.advance(:months => 1).inspect
+    assert_equal "Tue, 29 Feb 2000 00:00:00 EST -05:00", twz.months_since(1).inspect
+    assert_equal "Tue, 29 Feb 2000 00:00:00 EST -05:00", twz.since(1.month).inspect
+    assert_equal "Tue, 29 Feb 2000 00:00:00 EST -05:00", (twz + 1.month).inspect
+  end
+
+  def test_advance_1_month_into_spring_dst_gap
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,3,2,2))
+    assert_equal "Sun, 02 Apr 2006 03:00:00 EDT -04:00", twz.advance(:months => 1).inspect
+    assert_equal "Sun, 02 Apr 2006 03:00:00 EDT -04:00", twz.months_since(1).inspect
+    assert_equal "Sun, 02 Apr 2006 03:00:00 EDT -04:00", twz.since(1.month).inspect
+    assert_equal "Sun, 02 Apr 2006 03:00:00 EDT -04:00", (twz + 1.month).inspect
+  end
+
+  def test_advance_1_second_into_spring_dst_gap
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,4,2,1,59,59))
+    assert_equal "Sun, 02 Apr 2006 03:00:00 EDT -04:00", twz.advance(:seconds => 1).inspect
+    assert_equal "Sun, 02 Apr 2006 03:00:00 EDT -04:00", (twz + 1).inspect
+    assert_equal "Sun, 02 Apr 2006 03:00:00 EDT -04:00", twz.since(1).inspect
+    assert_equal "Sun, 02 Apr 2006 03:00:00 EDT -04:00", twz.since(1.second).inspect
+    assert_equal "Sun, 02 Apr 2006 03:00:00 EDT -04:00", (twz + 1.second).inspect
+  end
+
+  def test_advance_1_day_across_spring_dst_transition
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,4,1,10,30))
+    # In 2006, spring DST transition occurred Apr 2 at 2AM; this day was only 23 hours long
+    # When we advance 1 day, we want to end up at the same time on the next day
+    assert_equal "Sun, 02 Apr 2006 10:30:00 EDT -04:00", twz.advance(:days => 1).inspect
+    assert_equal "Sun, 02 Apr 2006 10:30:00 EDT -04:00", twz.since(1.days).inspect
+    assert_equal "Sun, 02 Apr 2006 10:30:00 EDT -04:00", (twz + 1.days).inspect
+    assert_equal "Sun, 02 Apr 2006 10:30:01 EDT -04:00", twz.since(1.days + 1.second).inspect
+    assert_equal "Sun, 02 Apr 2006 10:30:01 EDT -04:00", (twz + 1.days + 1.second).inspect
+  end
+
+  def test_advance_1_day_across_spring_dst_transition_backwards
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,4,2,10,30))
+    # In 2006, spring DST transition occurred Apr 2 at 2AM; this day was only 23 hours long
+    # When we advance back 1 day, we want to end up at the same time on the previous day
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", twz.advance(:days => -1).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", twz.ago(1.days).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", (twz - 1.days).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:01 EST -05:00", twz.ago(1.days - 1.second).inspect
+  end
+
+  def test_advance_1_day_expressed_as_number_of_seconds_minutes_or_hours_across_spring_dst_transition
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,4,1,10,30))
+    # In 2006, spring DST transition occurred Apr 2 at 2AM; this day was only 23 hours long
+    # When we advance a specific number of hours, minutes or seconds, we want to advance exactly that amount
+    assert_equal "Sun, 02 Apr 2006 11:30:00 EDT -04:00", (twz + 86400).inspect
+    assert_equal "Sun, 02 Apr 2006 11:30:00 EDT -04:00", (twz + 86400.seconds).inspect
+    assert_equal "Sun, 02 Apr 2006 11:30:00 EDT -04:00", twz.since(86400).inspect
+    assert_equal "Sun, 02 Apr 2006 11:30:00 EDT -04:00", twz.since(86400.seconds).inspect
+    assert_equal "Sun, 02 Apr 2006 11:30:00 EDT -04:00", twz.advance(:seconds => 86400).inspect
+    assert_equal "Sun, 02 Apr 2006 11:30:00 EDT -04:00", (twz + 1440.minutes).inspect
+    assert_equal "Sun, 02 Apr 2006 11:30:00 EDT -04:00", twz.since(1440.minutes).inspect
+    assert_equal "Sun, 02 Apr 2006 11:30:00 EDT -04:00", twz.advance(:minutes => 1440).inspect
+    assert_equal "Sun, 02 Apr 2006 11:30:00 EDT -04:00", (twz + 24.hours).inspect
+    assert_equal "Sun, 02 Apr 2006 11:30:00 EDT -04:00", twz.since(24.hours).inspect
+    assert_equal "Sun, 02 Apr 2006 11:30:00 EDT -04:00", twz.advance(:hours => 24).inspect
+  end
+
+  def test_advance_1_day_expressed_as_number_of_seconds_minutes_or_hours_across_spring_dst_transition_backwards
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,4,2,11,30))
+    # In 2006, spring DST transition occurred Apr 2 at 2AM; this day was only 23 hours long
+    # When we advance a specific number of hours, minutes or seconds, we want to advance exactly that amount
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", (twz - 86400).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", (twz - 86400.seconds).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", twz.ago(86400).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", twz.ago(86400.seconds).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", twz.advance(:seconds => -86400).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", (twz - 1440.minutes).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", twz.ago(1440.minutes).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", twz.advance(:minutes => -1440).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", (twz - 24.hours).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", twz.ago(24.hours).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", twz.advance(:hours => -24).inspect
+  end
+
+  def test_advance_1_day_across_fall_dst_transition
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,10,28,10,30))
+    # In 2006, fall DST transition occurred Oct 29 at 2AM; this day was 25 hours long
+    # When we advance 1 day, we want to end up at the same time on the next day
+    assert_equal "Sun, 29 Oct 2006 10:30:00 EST -05:00", twz.advance(:days => 1).inspect
+    assert_equal "Sun, 29 Oct 2006 10:30:00 EST -05:00", twz.since(1.days).inspect
+    assert_equal "Sun, 29 Oct 2006 10:30:00 EST -05:00", (twz + 1.days).inspect
+    assert_equal "Sun, 29 Oct 2006 10:30:01 EST -05:00", twz.since(1.days + 1.second).inspect
+    assert_equal "Sun, 29 Oct 2006 10:30:01 EST -05:00", (twz + 1.days + 1.second).inspect
+  end
+
+  def test_advance_1_day_across_fall_dst_transition_backwards
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,10,29,10,30))
+    # In 2006, fall DST transition occurred Oct 29 at 2AM; this day was 25 hours long
+    # When we advance backwards 1 day, we want to end up at the same time on the previous day
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", twz.advance(:days => -1).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", twz.ago(1.days).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", (twz - 1.days).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:01 EDT -04:00", twz.ago(1.days - 1.second).inspect
+  end
+
+  def test_advance_1_day_expressed_as_number_of_seconds_minutes_or_hours_across_fall_dst_transition
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,10,28,10,30))
+    # In 2006, fall DST transition occurred Oct 29 at 2AM; this day was 25 hours long
+    # When we advance a specific number of hours, minutes or seconds, we want to advance exactly that amount
+    assert_equal "Sun, 29 Oct 2006 09:30:00 EST -05:00", (twz + 86400).inspect
+    assert_equal "Sun, 29 Oct 2006 09:30:00 EST -05:00", (twz + 86400.seconds).inspect
+    assert_equal "Sun, 29 Oct 2006 09:30:00 EST -05:00", twz.since(86400).inspect
+    assert_equal "Sun, 29 Oct 2006 09:30:00 EST -05:00", twz.since(86400.seconds).inspect
+    assert_equal "Sun, 29 Oct 2006 09:30:00 EST -05:00", twz.advance(:seconds => 86400).inspect
+    assert_equal "Sun, 29 Oct 2006 09:30:00 EST -05:00", (twz + 1440.minutes).inspect
+    assert_equal "Sun, 29 Oct 2006 09:30:00 EST -05:00", twz.since(1440.minutes).inspect
+    assert_equal "Sun, 29 Oct 2006 09:30:00 EST -05:00", twz.advance(:minutes => 1440).inspect
+    assert_equal "Sun, 29 Oct 2006 09:30:00 EST -05:00", (twz + 24.hours).inspect
+    assert_equal "Sun, 29 Oct 2006 09:30:00 EST -05:00", twz.since(24.hours).inspect
+    assert_equal "Sun, 29 Oct 2006 09:30:00 EST -05:00", twz.advance(:hours => 24).inspect
+  end
+
+  def test_advance_1_day_expressed_as_number_of_seconds_minutes_or_hours_across_fall_dst_transition_backwards
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,10,29,9,30))
+    # In 2006, fall DST transition occurred Oct 29 at 2AM; this day was 25 hours long
+    # When we advance a specific number of hours, minutes or seconds, we want to advance exactly that amount
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", (twz - 86400).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", (twz - 86400.seconds).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", twz.ago(86400).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", twz.ago(86400.seconds).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", twz.advance(:seconds => -86400).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", (twz - 1440.minutes).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", twz.ago(1440.minutes).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", twz.advance(:minutes => -1440).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", (twz - 24.hours).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", twz.ago(24.hours).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", twz.advance(:hours => -24).inspect
+  end
+
+  def test_advance_1_month_across_spring_dst_transition
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,4,1,10,30))
+    assert_equal "Mon, 01 May 2006 10:30:00 EDT -04:00", twz.advance(:months => 1).inspect
+    assert_equal "Mon, 01 May 2006 10:30:00 EDT -04:00", twz.months_since(1).inspect
+    assert_equal "Mon, 01 May 2006 10:30:00 EDT -04:00", twz.since(1.month).inspect
+    assert_equal "Mon, 01 May 2006 10:30:00 EDT -04:00", (twz + 1.month).inspect
+  end
+
+  def test_advance_1_month_across_spring_dst_transition_backwards
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,5,1,10,30))
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", twz.advance(:months => -1).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", twz.months_ago(1).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", twz.ago(1.month).inspect
+    assert_equal "Sat, 01 Apr 2006 10:30:00 EST -05:00", (twz - 1.month).inspect
+  end
+
+  def test_advance_1_month_across_fall_dst_transition
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,10,28,10,30))
+    assert_equal "Tue, 28 Nov 2006 10:30:00 EST -05:00", twz.advance(:months => 1).inspect
+    assert_equal "Tue, 28 Nov 2006 10:30:00 EST -05:00", twz.months_since(1).inspect
+    assert_equal "Tue, 28 Nov 2006 10:30:00 EST -05:00", twz.since(1.month).inspect
+    assert_equal "Tue, 28 Nov 2006 10:30:00 EST -05:00", (twz + 1.month).inspect
+  end
+
+  def test_advance_1_month_across_fall_dst_transition_backwards
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2006,11,28,10,30))
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", twz.advance(:months => -1).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", twz.months_ago(1).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", twz.ago(1.month).inspect
+    assert_equal "Sat, 28 Oct 2006 10:30:00 EDT -04:00", (twz - 1.month).inspect
+  end
+
+  def test_advance_1_year
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2008,2,15,10,30))
+    assert_equal "Sun, 15 Feb 2009 10:30:00 EST -05:00", twz.advance(:years => 1).inspect
+    assert_equal "Sun, 15 Feb 2009 10:30:00 EST -05:00", twz.years_since(1).inspect
+    assert_equal "Sun, 15 Feb 2009 10:30:00 EST -05:00", (twz + 1.year).inspect
+    assert_equal "Thu, 15 Feb 2007 10:30:00 EST -05:00", twz.advance(:years => -1).inspect
+    assert_equal "Thu, 15 Feb 2007 10:30:00 EST -05:00", twz.years_ago(1).inspect
+    assert_equal "Thu, 15 Feb 2007 10:30:00 EST -05:00", (twz - 1.year).inspect
+  end
+
+  def test_advance_1_year_during_dst
+    twz = ActiveSupport::TimeWithZone.new(nil, @time_zone, Time.utc(2008,7,15,10,30))
+    assert_equal "Wed, 15 Jul 2009 10:30:00 EDT -04:00", twz.advance(:years => 1).inspect
+    assert_equal "Wed, 15 Jul 2009 10:30:00 EDT -04:00", twz.years_since(1).inspect
+    assert_equal "Wed, 15 Jul 2009 10:30:00 EDT -04:00", (twz + 1.year).inspect
+    assert_equal "Sun, 15 Jul 2007 10:30:00 EDT -04:00", twz.advance(:years => -1).inspect
+    assert_equal "Sun, 15 Jul 2007 10:30:00 EDT -04:00", twz.years_ago(1).inspect
+    assert_equal "Sun, 15 Jul 2007 10:30:00 EDT -04:00", (twz - 1.year).inspect
+  end
+
+  def test_no_method_error_has_proper_context
+    e = assert_raises(NoMethodError) {
+      @twz.this_method_does_not_exist
+    }
+    assert_equal "undefined method `this_method_does_not_exist' for Fri, 31 Dec 1999 19:00:00 EST -05:00:Time", e.message
+    assert_no_match "rescue", e.backtrace.first
+  end
+
+  protected
+    def with_env_tz(new_tz = 'US/Eastern')
+      old_tz, ENV['TZ'] = ENV['TZ'], new_tz
+      yield
+    ensure
+      old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+    end
+end
+
+class TimeWithZoneMethodsForTimeAndDateTimeTest < ActiveSupport::TestCase
+  def setup
+    @t, @dt = Time.utc(2000), DateTime.civil(2000)
+  end
+
+  def teardown
+    Time.zone = nil
+  end
+
+  def test_in_time_zone
+    Time.use_zone 'Alaska' do
+      assert_equal 'Fri, 31 Dec 1999 15:00:00 AKST -09:00', @t.in_time_zone.inspect
+      assert_equal 'Fri, 31 Dec 1999 15:00:00 AKST -09:00', @dt.in_time_zone.inspect
+    end
+    Time.use_zone 'Hawaii' do
+      assert_equal 'Fri, 31 Dec 1999 14:00:00 HST -10:00', @t.in_time_zone.inspect
+      assert_equal 'Fri, 31 Dec 1999 14:00:00 HST -10:00', @dt.in_time_zone.inspect
+    end
+    Time.use_zone nil do
+      assert_equal @t, @t.in_time_zone
+      assert_equal @dt, @dt.in_time_zone
+    end
+  end
+
+  def test_nil_time_zone
+    Time.use_zone nil do
+      assert !@t.in_time_zone.respond_to?(:period), 'no period method'
+      assert !@dt.in_time_zone.respond_to?(:period), 'no period method'
+    end
+  end
+
+  def test_in_time_zone_with_argument
+    Time.use_zone 'Eastern Time (US & Canada)' do # Time.zone will not affect #in_time_zone(zone)
+      assert_equal 'Fri, 31 Dec 1999 15:00:00 AKST -09:00', @t.in_time_zone('Alaska').inspect
+      assert_equal 'Fri, 31 Dec 1999 15:00:00 AKST -09:00', @dt.in_time_zone('Alaska').inspect
+      assert_equal 'Fri, 31 Dec 1999 14:00:00 HST -10:00', @t.in_time_zone('Hawaii').inspect
+      assert_equal 'Fri, 31 Dec 1999 14:00:00 HST -10:00', @dt.in_time_zone('Hawaii').inspect
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 UTC +00:00', @t.in_time_zone('UTC').inspect
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 UTC +00:00', @dt.in_time_zone('UTC').inspect
+      assert_equal 'Fri, 31 Dec 1999 15:00:00 AKST -09:00', @t.in_time_zone(-9.hours).inspect
+    end
+  end
+
+  def test_in_time_zone_with_invalid_argument
+    assert_raise(ArgumentError) {  @t.in_time_zone("No such timezone exists") }
+    assert_raise(ArgumentError) { @dt.in_time_zone("No such timezone exists") }
+    assert_raise(ArgumentError) {  @t.in_time_zone(-15.hours) }
+    assert_raise(ArgumentError) { @dt.in_time_zone(-15.hours) }
+    assert_raise(ArgumentError) {  @t.in_time_zone(Object.new) }
+    assert_raise(ArgumentError) { @dt.in_time_zone(Object.new) }
+  end
+
+  def test_in_time_zone_with_time_local_instance
+    with_env_tz 'US/Eastern' do
+      time = Time.local(1999, 12, 31, 19) # == Time.utc(2000)
+      assert_equal 'Fri, 31 Dec 1999 15:00:00 AKST -09:00', time.in_time_zone('Alaska').inspect
+    end
+  end
+
+  def test_localtime
+    Time.zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    assert_equal @dt.in_time_zone.localtime, @dt.in_time_zone.utc.to_time.getlocal
+  ensure
+    Time.zone = nil
+  end
+
+  def test_use_zone
+    Time.zone = 'Alaska'
+    Time.use_zone 'Hawaii' do
+      assert_equal ActiveSupport::TimeZone['Hawaii'], Time.zone
+    end
+    assert_equal ActiveSupport::TimeZone['Alaska'], Time.zone
+  end
+
+  def test_use_zone_with_exception_raised
+    Time.zone = 'Alaska'
+    assert_raise RuntimeError do
+      Time.use_zone('Hawaii') { raise RuntimeError }
+    end
+    assert_equal ActiveSupport::TimeZone['Alaska'], Time.zone
+  end
+
+  def test_use_zone_raises_on_invalid_timezone
+    Time.zone = 'Alaska'
+    assert_raise ArgumentError do
+      Time.use_zone("No such timezone exists") { }
+    end
+    assert_equal ActiveSupport::TimeZone['Alaska'], Time.zone
+  end
+
+  def test_time_zone_getter_and_setter
+    Time.zone = ActiveSupport::TimeZone['Alaska']
+    assert_equal ActiveSupport::TimeZone['Alaska'], Time.zone
+    Time.zone = 'Alaska'
+    assert_equal ActiveSupport::TimeZone['Alaska'], Time.zone
+    Time.zone = -9.hours
+    assert_equal ActiveSupport::TimeZone['Alaska'], Time.zone
+    Time.zone = nil
+    assert_equal nil, Time.zone
+  end
+
+  def test_time_zone_getter_and_setter_with_zone_default_set
+    Time.zone_default = ActiveSupport::TimeZone['Alaska']
+    assert_equal ActiveSupport::TimeZone['Alaska'], Time.zone
+    Time.zone = ActiveSupport::TimeZone['Hawaii']
+    assert_equal ActiveSupport::TimeZone['Hawaii'], Time.zone
+    Time.zone = nil
+    assert_equal ActiveSupport::TimeZone['Alaska'], Time.zone
+  ensure
+    Time.zone = nil
+    Time.zone_default = nil
+  end
+
+  def test_time_zone_setter_is_thread_safe
+    Time.use_zone 'Paris' do
+      t1 = Thread.new { Time.zone = 'Alaska' }.join
+      t2 = Thread.new { Time.zone = 'Hawaii' }.join
+      assert t1.stop?, "Thread 1 did not finish running"
+      assert t2.stop?, "Thread 2 did not finish running"
+      assert_equal ActiveSupport::TimeZone['Paris'], Time.zone
+      assert_equal ActiveSupport::TimeZone['Alaska'], t1[:time_zone]
+      assert_equal ActiveSupport::TimeZone['Hawaii'], t2[:time_zone]
+    end
+  end
+
+  def test_time_zone_setter_with_tzinfo_timezone_object_wraps_in_rails_time_zone
+    tzinfo = TZInfo::Timezone.get('America/New_York')
+    Time.zone = tzinfo
+    assert_kind_of ActiveSupport::TimeZone, Time.zone
+    assert_equal tzinfo, Time.zone.tzinfo
+    assert_equal 'America/New_York', Time.zone.name
+    assert_equal(-18_000, Time.zone.utc_offset)
+  end
+
+  def test_time_zone_setter_with_tzinfo_timezone_identifier_does_lookup_and_wraps_in_rails_time_zone
+    Time.zone = 'America/New_York'
+    assert_kind_of ActiveSupport::TimeZone, Time.zone
+    assert_equal 'America/New_York', Time.zone.tzinfo.name
+    assert_equal 'America/New_York', Time.zone.name
+    assert_equal(-18_000, Time.zone.utc_offset)
+  end
+
+  def test_time_zone_setter_with_invalid_zone
+    assert_raise(ArgumentError){ Time.zone = "No such timezone exists" }
+    assert_raise(ArgumentError){ Time.zone = -15.hours }
+    assert_raise(ArgumentError){ Time.zone = Object.new }
+  end
+
+  def test_find_zone_without_bang_returns_nil_if_time_zone_can_not_be_found
+    assert_nil Time.find_zone('No such timezone exists')
+    assert_nil Time.find_zone(-15.hours)
+    assert_nil Time.find_zone(Object.new)
+  end
+
+  def test_find_zone_with_bang_raises_if_time_zone_can_not_be_found
+    assert_raise(ArgumentError) { Time.find_zone!('No such timezone exists') }
+    assert_raise(ArgumentError) { Time.find_zone!(-15.hours) }
+    assert_raise(ArgumentError) { Time.find_zone!(Object.new) }
+  end
+
+  def test_time_zone_setter_with_find_zone_without_bang
+    assert_nil Time.zone = Time.find_zone('No such timezone exists')
+    assert_nil Time.zone = Time.find_zone(-15.hours)
+    assert_nil Time.zone = Time.find_zone(Object.new)
+  end
+
+  def test_current_returns_time_now_when_zone_not_set
+    with_env_tz 'US/Eastern' do
+      Time.stubs(:now).returns Time.local(2000)
+      assert_equal false, Time.current.is_a?(ActiveSupport::TimeWithZone)
+      assert_equal Time.local(2000), Time.current
+    end
+  end
+
+  def test_current_returns_time_zone_now_when_zone_set
+    Time.zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    with_env_tz 'US/Eastern' do
+      Time.stubs(:now).returns Time.local(2000)
+      assert_equal true, Time.current.is_a?(ActiveSupport::TimeWithZone)
+      assert_equal 'Eastern Time (US & Canada)', Time.current.time_zone.name
+      assert_equal Time.utc(2000), Time.current.time
+    end
+  ensure
+    Time.zone = nil
+  end
+
+  def test_time_in_time_zone_doesnt_affect_receiver
+    with_env_tz 'Europe/London' do
+      time = Time.local(2000, 7, 1)
+      time_with_zone = time.in_time_zone('Eastern Time (US & Canada)')
+      assert_equal Time.utc(2000, 6, 30, 23, 0, 0), time_with_zone
+      assert_not time.utc?, 'time expected to be local, but is UTC'
+    end
+  end
+
+  protected
+    def with_env_tz(new_tz = 'US/Eastern')
+      old_tz, ENV['TZ'] = ENV['TZ'], new_tz
+      yield
+    ensure
+      old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+    end
+end
+
+class TimeWithZoneMethodsForDate < ActiveSupport::TestCase
+  def setup
+    @d = Date.civil(2000)
+  end
+
+  def teardown
+    Time.zone = nil
+  end
+
+  def test_in_time_zone
+    with_tz_default 'Alaska' do
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 AKST -09:00', @d.in_time_zone.inspect
+    end
+    with_tz_default 'Hawaii' do
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 HST -10:00', @d.in_time_zone.inspect
+    end
+    with_tz_default nil do
+      assert_equal @d.to_time, @d.in_time_zone
+    end
+  end
+
+  def test_nil_time_zone
+    with_tz_default nil do
+      assert !@d.in_time_zone.respond_to?(:period), 'no period method'
+    end
+  end
+
+  def test_in_time_zone_with_argument
+    with_tz_default 'Eastern Time (US & Canada)' do # Time.zone will not affect #in_time_zone(zone)
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 AKST -09:00', @d.in_time_zone('Alaska').inspect
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 HST -10:00', @d.in_time_zone('Hawaii').inspect
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 UTC +00:00', @d.in_time_zone('UTC').inspect
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 AKST -09:00', @d.in_time_zone(-9.hours).inspect
+    end
+  end
+
+  def test_in_time_zone_with_invalid_argument
+    assert_raise(ArgumentError) { @d.in_time_zone("No such timezone exists") }
+    assert_raise(ArgumentError) { @d.in_time_zone(-15.hours) }
+    assert_raise(ArgumentError) { @d.in_time_zone(Object.new) }
+  end
+
+  protected
+    def with_tz_default(tz = nil)
+      old_tz = Time.zone
+      Time.zone = tz
+      yield
+    ensure
+      Time.zone = old_tz
+    end
+end
+
+class TimeWithZoneMethodsForString < ActiveSupport::TestCase
+  def setup
+    @s = "Sat, 01 Jan 2000 00:00:00"
+    @u = "Sat, 01 Jan 2000 00:00:00 UTC +00:00"
+    @z = "Fri, 31 Dec 1999 19:00:00 EST -05:00"
+  end
+
+  def teardown
+    Time.zone = nil
+  end
+
+  def test_in_time_zone
+    with_tz_default 'Alaska' do
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 AKST -09:00', @s.in_time_zone.inspect
+      assert_equal 'Fri, 31 Dec 1999 15:00:00 AKST -09:00', @u.in_time_zone.inspect
+      assert_equal 'Fri, 31 Dec 1999 15:00:00 AKST -09:00', @z.in_time_zone.inspect
+    end
+    with_tz_default 'Hawaii' do
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 HST -10:00', @s.in_time_zone.inspect
+      assert_equal 'Fri, 31 Dec 1999 14:00:00 HST -10:00', @u.in_time_zone.inspect
+      assert_equal 'Fri, 31 Dec 1999 14:00:00 HST -10:00', @z.in_time_zone.inspect
+    end
+    with_tz_default nil do
+      assert_equal @s.to_time, @s.in_time_zone
+      assert_equal @u.to_time, @u.in_time_zone
+      assert_equal @z.to_time, @z.in_time_zone
+    end
+  end
+
+  def test_nil_time_zone
+    with_tz_default nil do
+      assert !@s.in_time_zone.respond_to?(:period), 'no period method'
+      assert !@u.in_time_zone.respond_to?(:period), 'no period method'
+      assert !@z.in_time_zone.respond_to?(:period), 'no period method'
+    end
+  end
+
+  def test_in_time_zone_with_argument
+    with_tz_default 'Eastern Time (US & Canada)' do # Time.zone will not affect #in_time_zone(zone)
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 AKST -09:00', @s.in_time_zone('Alaska').inspect
+      assert_equal 'Fri, 31 Dec 1999 15:00:00 AKST -09:00', @u.in_time_zone('Alaska').inspect
+      assert_equal 'Fri, 31 Dec 1999 15:00:00 AKST -09:00', @z.in_time_zone('Alaska').inspect
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 HST -10:00', @s.in_time_zone('Hawaii').inspect
+      assert_equal 'Fri, 31 Dec 1999 14:00:00 HST -10:00', @u.in_time_zone('Hawaii').inspect
+      assert_equal 'Fri, 31 Dec 1999 14:00:00 HST -10:00', @z.in_time_zone('Hawaii').inspect
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 UTC +00:00', @s.in_time_zone('UTC').inspect
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 UTC +00:00', @u.in_time_zone('UTC').inspect
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 UTC +00:00', @z.in_time_zone('UTC').inspect
+      assert_equal 'Sat, 01 Jan 2000 00:00:00 AKST -09:00', @s.in_time_zone(-9.hours).inspect
+      assert_equal 'Fri, 31 Dec 1999 15:00:00 AKST -09:00', @u.in_time_zone(-9.hours).inspect
+      assert_equal 'Fri, 31 Dec 1999 15:00:00 AKST -09:00', @z.in_time_zone(-9.hours).inspect
+    end
+  end
+
+  def test_in_time_zone_with_invalid_argument
+    assert_raise(ArgumentError) { @s.in_time_zone("No such timezone exists") }
+    assert_raise(ArgumentError) { @u.in_time_zone("No such timezone exists") }
+    assert_raise(ArgumentError) { @z.in_time_zone("No such timezone exists") }
+    assert_raise(ArgumentError) { @s.in_time_zone(-15.hours) }
+    assert_raise(ArgumentError) { @u.in_time_zone(-15.hours) }
+    assert_raise(ArgumentError) { @z.in_time_zone(-15.hours) }
+    assert_raise(ArgumentError) { @s.in_time_zone(Object.new) }
+    assert_raise(ArgumentError) { @u.in_time_zone(Object.new) }
+    assert_raise(ArgumentError) { @z.in_time_zone(Object.new) }
+  end
+
+  protected
+    def with_tz_default(tz = nil)
+      old_tz = Time.zone
+      Time.zone = tz
+      yield
+    ensure
+      Time.zone = old_tz
+    end
+end
diff --git a/app/server/vendor/activesupport/test/core_ext/uri_ext_test.rb b/app/server/vendor/activesupport/test/core_ext/uri_ext_test.rb
new file mode 100644
index 0000000..03e388d
--- /dev/null
+++ b/app/server/vendor/activesupport/test/core_ext/uri_ext_test.rb
@@ -0,0 +1,13 @@
+# encoding: utf-8
+require 'abstract_unit'
+require 'uri'
+require 'active_support/core_ext/uri'
+
+class URIExtTest < ActiveSupport::TestCase
+  def test_uri_decode_handle_multibyte
+    str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
+
+    parser = URI::Parser.new
+    assert_equal str, parser.unescape(parser.escape(str))
+  end
+end
diff --git a/app/server/vendor/activesupport/test/dependencies/check_warnings.rb b/app/server/vendor/activesupport/test/dependencies/check_warnings.rb
new file mode 100644
index 0000000..03c3dca
--- /dev/null
+++ b/app/server/vendor/activesupport/test/dependencies/check_warnings.rb
@@ -0,0 +1,2 @@
+$check_warnings_load_count += 1
+$checked_verbose = $VERBOSE
diff --git a/app/server/vendor/activesupport/test/dependencies/conflict.rb b/app/server/vendor/activesupport/test/dependencies/conflict.rb
new file mode 100644
index 0000000..e888b7b
--- /dev/null
+++ b/app/server/vendor/activesupport/test/dependencies/conflict.rb
@@ -0,0 +1 @@
+Conflict = 1
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/dependencies/cross_site_depender.rb b/app/server/vendor/activesupport/test/dependencies/cross_site_depender.rb
new file mode 100644
index 0000000..a31015f
--- /dev/null
+++ b/app/server/vendor/activesupport/test/dependencies/cross_site_depender.rb
@@ -0,0 +1,3 @@
+class CrossSiteDepender
+  CrossSiteDependency
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/dependencies/mutual_one.rb b/app/server/vendor/activesupport/test/dependencies/mutual_one.rb
new file mode 100644
index 0000000..576eb31
--- /dev/null
+++ b/app/server/vendor/activesupport/test/dependencies/mutual_one.rb
@@ -0,0 +1,4 @@
+$mutual_dependencies_count += 1
+require_dependency 'mutual_two'
+require_dependency 'mutual_two.rb'
+require_dependency 'mutual_two'
diff --git a/app/server/vendor/activesupport/test/dependencies/mutual_two.rb b/app/server/vendor/activesupport/test/dependencies/mutual_two.rb
new file mode 100644
index 0000000..fdbc2dc
--- /dev/null
+++ b/app/server/vendor/activesupport/test/dependencies/mutual_two.rb
@@ -0,0 +1,4 @@
+$mutual_dependencies_count += 1
+require_dependency 'mutual_one.rb'
+require_dependency 'mutual_one'
+require_dependency 'mutual_one.rb'
diff --git a/app/server/vendor/activesupport/test/dependencies/raises_exception.rb b/app/server/vendor/activesupport/test/dependencies/raises_exception.rb
new file mode 100644
index 0000000..dd745ac
--- /dev/null
+++ b/app/server/vendor/activesupport/test/dependencies/raises_exception.rb
@@ -0,0 +1,3 @@
+$raises_exception_load_count += 1
+raise Exception, 'Loading me failed, so do not add to loaded or history.'
+$raises_exception_load_count += 1
diff --git a/app/server/vendor/activesupport/test/dependencies/raises_exception_without_blame_file.rb b/app/server/vendor/activesupport/test/dependencies/raises_exception_without_blame_file.rb
new file mode 100644
index 0000000..4b2da6f
--- /dev/null
+++ b/app/server/vendor/activesupport/test/dependencies/raises_exception_without_blame_file.rb
@@ -0,0 +1,5 @@
+exception = Exception.new('I am not blamable!')
+class << exception
+  undef_method(:blame_file!)
+end
+raise exception
diff --git a/app/server/vendor/activesupport/test/dependencies/requires_nonexistent0.rb b/app/server/vendor/activesupport/test/dependencies/requires_nonexistent0.rb
new file mode 100644
index 0000000..7e24b39
--- /dev/null
+++ b/app/server/vendor/activesupport/test/dependencies/requires_nonexistent0.rb
@@ -0,0 +1 @@
+require 'RMagickDontExistDude'
diff --git a/app/server/vendor/activesupport/test/dependencies/requires_nonexistent1.rb b/app/server/vendor/activesupport/test/dependencies/requires_nonexistent1.rb
new file mode 100644
index 0000000..41e6668
--- /dev/null
+++ b/app/server/vendor/activesupport/test/dependencies/requires_nonexistent1.rb
@@ -0,0 +1 @@
+require_dependency 'requires_nonexistent0'
diff --git a/app/server/vendor/activesupport/test/dependencies/service_one.rb b/app/server/vendor/activesupport/test/dependencies/service_one.rb
new file mode 100644
index 0000000..f43bfea
--- /dev/null
+++ b/app/server/vendor/activesupport/test/dependencies/service_one.rb
@@ -0,0 +1,5 @@
+$loaded_service_one ||= 0
+$loaded_service_one += 1
+
+class ServiceOne
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/dependencies/service_two.rb b/app/server/vendor/activesupport/test/dependencies/service_two.rb
new file mode 100644
index 0000000..5205a78
--- /dev/null
+++ b/app/server/vendor/activesupport/test/dependencies/service_two.rb
@@ -0,0 +1,2 @@
+class ServiceTwo
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/dependencies_test.rb b/app/server/vendor/activesupport/test/dependencies_test.rb
new file mode 100644
index 0000000..4ca63b3
--- /dev/null
+++ b/app/server/vendor/activesupport/test/dependencies_test.rb
@@ -0,0 +1,997 @@
+require 'abstract_unit'
+require 'pp'
+require 'active_support/dependencies'
+require 'dependencies_test_helpers'
+
+module ModuleWithMissing
+  mattr_accessor :missing_count
+  def self.const_missing(name)
+    self.missing_count += 1
+    name
+  end
+end
+
+module ModuleWithConstant
+  InheritedConstant = "Hello"
+end
+
+class DependenciesTest < ActiveSupport::TestCase
+  def teardown
+    ActiveSupport::Dependencies.clear
+  end
+
+  include DependenciesTestHelpers
+
+  def test_depend_on_path
+    skip "LoadError#path does not exist" if RUBY_VERSION < '2.0.0'
+
+    expected = assert_raises(LoadError) do
+      Kernel.require 'omgwtfbbq'
+    end
+
+    e = assert_raises(LoadError) do
+      ActiveSupport::Dependencies.depend_on 'omgwtfbbq'
+    end
+    assert_equal expected.path, e.path
+  end
+
+  def test_require_dependency_accepts_an_object_which_implements_to_path
+    o = Object.new
+    def o.to_path; 'dependencies/service_one'; end
+    assert_nothing_raised {
+      require_dependency o
+    }
+    assert defined?(ServiceOne)
+  ensure
+    remove_constants(:ServiceOne)
+  end
+
+  def test_tracking_loaded_files
+    require_dependency 'dependencies/service_one'
+    require_dependency 'dependencies/service_two'
+    assert_equal 2, ActiveSupport::Dependencies.loaded.size
+  ensure
+    Object.send(:remove_const, :ServiceOne) if Object.const_defined?(:ServiceOne)
+    Object.send(:remove_const, :ServiceTwo) if Object.const_defined?(:ServiceTwo)
+  end
+
+  def test_tracking_identical_loaded_files
+    require_dependency 'dependencies/service_one'
+    require_dependency 'dependencies/service_one'
+    assert_equal 1, ActiveSupport::Dependencies.loaded.size
+  ensure
+    Object.send(:remove_const, :ServiceOne) if Object.const_defined?(:ServiceOne)
+  end
+
+  def test_missing_dependency_raises_missing_source_file
+    assert_raise(MissingSourceFile) { require_dependency("missing_service") }
+  end
+
+  def test_dependency_which_raises_exception_isnt_added_to_loaded_set
+    with_loading do
+      filename = 'dependencies/raises_exception'
+      $raises_exception_load_count = 0
+
+      5.times do |count|
+        e = assert_raise Exception, 'should have loaded dependencies/raises_exception which raises an exception' do
+          require_dependency filename
+        end
+
+        assert_equal 'Loading me failed, so do not add to loaded or history.', e.message
+        assert_equal count + 1, $raises_exception_load_count
+
+        assert !ActiveSupport::Dependencies.loaded.include?(filename)
+        assert !ActiveSupport::Dependencies.history.include?(filename)
+      end
+    end
+  end
+
+  def test_dependency_which_raises_doesnt_blindly_call_blame_file!
+    with_loading do
+      filename = 'dependencies/raises_exception_without_blame_file'
+
+      assert_raises(Exception) { require_dependency filename }
+    end
+  end
+
+  def test_warnings_should_be_enabled_on_first_load
+    with_loading 'dependencies' do
+      old_warnings, ActiveSupport::Dependencies.warnings_on_first_load = ActiveSupport::Dependencies.warnings_on_first_load, true
+
+      filename = "check_warnings"
+      expanded = File.expand_path("#{File.dirname(__FILE__)}/dependencies/#{filename}")
+      $check_warnings_load_count = 0
+
+      assert !ActiveSupport::Dependencies.loaded.include?(expanded)
+      assert !ActiveSupport::Dependencies.history.include?(expanded)
+
+      silence_warnings { require_dependency filename }
+      assert_equal 1, $check_warnings_load_count
+      assert_equal true, $checked_verbose, 'On first load warnings should be enabled.'
+
+      assert ActiveSupport::Dependencies.loaded.include?(expanded)
+      ActiveSupport::Dependencies.clear
+      assert !ActiveSupport::Dependencies.loaded.include?(expanded)
+      assert ActiveSupport::Dependencies.history.include?(expanded)
+
+      silence_warnings { require_dependency filename }
+      assert_equal 2, $check_warnings_load_count
+      assert_equal nil, $checked_verbose, 'After first load warnings should be left alone.'
+
+      assert ActiveSupport::Dependencies.loaded.include?(expanded)
+      ActiveSupport::Dependencies.clear
+      assert !ActiveSupport::Dependencies.loaded.include?(expanded)
+      assert ActiveSupport::Dependencies.history.include?(expanded)
+
+      enable_warnings { require_dependency filename }
+      assert_equal 3, $check_warnings_load_count
+      assert_equal true, $checked_verbose, 'After first load warnings should be left alone.'
+
+      assert ActiveSupport::Dependencies.loaded.include?(expanded)
+      ActiveSupport::Dependencies.warnings_on_first_load = old_warnings
+    end
+  end
+
+  def test_mutual_dependencies_dont_infinite_loop
+    with_loading 'dependencies' do
+      $mutual_dependencies_count = 0
+      assert_nothing_raised { require_dependency 'mutual_one' }
+      assert_equal 2, $mutual_dependencies_count
+
+      ActiveSupport::Dependencies.clear
+
+      $mutual_dependencies_count = 0
+      assert_nothing_raised { require_dependency 'mutual_two' }
+      assert_equal 2, $mutual_dependencies_count
+    end
+  end
+
+  def test_circular_autoloading_detection
+    with_autoloading_fixtures do
+      e = assert_raise(RuntimeError) { Circular1 }
+      assert_equal "Circular dependency detected while autoloading constant Circular1", e.message
+    end
+  end
+
+  def test_module_loading
+    with_autoloading_fixtures do
+      assert_kind_of Module, A
+      assert_kind_of Class, A::B
+      assert_kind_of Class, A::C::D
+      assert_kind_of Class, A::C::E::F
+    end
+  end
+
+  def test_non_existing_const_raises_name_error
+    with_autoloading_fixtures do
+      assert_raise(NameError) { DoesNotExist }
+      assert_raise(NameError) { NoModule::DoesNotExist }
+      assert_raise(NameError) { A::DoesNotExist }
+      assert_raise(NameError) { A::B::DoesNotExist }
+    end
+  end
+
+  def test_directories_manifest_as_modules_unless_const_defined
+    with_autoloading_fixtures do
+      assert_kind_of Module, ModuleFolder
+      Object.__send__ :remove_const, :ModuleFolder
+    end
+  end
+
+  def test_module_with_nested_class
+    with_autoloading_fixtures do
+      assert_kind_of Class, ModuleFolder::NestedClass
+      Object.__send__ :remove_const, :ModuleFolder
+    end
+  end
+
+  def test_module_with_nested_inline_class
+    with_autoloading_fixtures do
+      assert_kind_of Class, ModuleFolder::InlineClass
+      Object.__send__ :remove_const, :ModuleFolder
+    end
+  end
+
+  def test_directories_may_manifest_as_nested_classes
+    with_autoloading_fixtures do
+      assert_kind_of Class, ClassFolder
+      Object.__send__ :remove_const, :ClassFolder
+    end
+  end
+
+  def test_class_with_nested_class
+    with_autoloading_fixtures do
+      assert_kind_of Class, ClassFolder::NestedClass
+      Object.__send__ :remove_const, :ClassFolder
+    end
+  end
+
+  def test_class_with_nested_inline_class
+    with_autoloading_fixtures do
+      assert_kind_of Class, ClassFolder::InlineClass
+      Object.__send__ :remove_const, :ClassFolder
+    end
+  end
+
+  def test_class_with_nested_inline_subclass_of_parent
+    with_autoloading_fixtures do
+      assert_kind_of Class, ClassFolder::ClassFolderSubclass
+      assert_kind_of Class, ClassFolder
+      assert_equal 'indeed', ClassFolder::ClassFolderSubclass::ConstantInClassFolder
+      Object.__send__ :remove_const, :ClassFolder
+    end
+  end
+
+  def test_nested_class_can_access_sibling
+    with_autoloading_fixtures do
+      sibling = ModuleFolder::NestedClass.class_eval "NestedSibling"
+      assert defined?(ModuleFolder::NestedSibling)
+      assert_equal ModuleFolder::NestedSibling, sibling
+      Object.__send__ :remove_const, :ModuleFolder
+    end
+  end
+
+  def test_doesnt_break_normal_require
+    path = File.expand_path("../autoloading_fixtures/load_path", __FILE__)
+    original_path = $:.dup
+    original_features = $".dup
+    $:.push(path)
+
+    with_autoloading_fixtures do
+      # The _ = assignments are to prevent warnings
+      _ = RequiresConstant
+      assert defined?(RequiresConstant)
+      assert defined?(LoadedConstant)
+      ActiveSupport::Dependencies.clear
+      _ = RequiresConstant
+      assert defined?(RequiresConstant)
+      assert defined?(LoadedConstant)
+    end
+  ensure
+    remove_constants(:RequiresConstant, :LoadedConstant, :LoadsConstant)
+    $".replace(original_features)
+    $:.replace(original_path)
+  end
+
+  def test_doesnt_break_normal_require_nested
+    path = File.expand_path("../autoloading_fixtures/load_path", __FILE__)
+    original_path = $:.dup
+    original_features = $".dup
+    $:.push(path)
+
+    with_autoloading_fixtures do
+      # The _ = assignments are to prevent warnings
+      _ = LoadsConstant
+      assert defined?(LoadsConstant)
+      assert defined?(LoadedConstant)
+      ActiveSupport::Dependencies.clear
+      _ = LoadsConstant
+      assert defined?(LoadsConstant)
+      assert defined?(LoadedConstant)
+    end
+  ensure
+    remove_constants(:RequiresConstant, :LoadedConstant, :LoadsConstant)
+    $".replace(original_features)
+    $:.replace(original_path)
+  end
+
+  def test_require_returns_true_when_file_not_yet_required
+    path = File.expand_path("../autoloading_fixtures/load_path", __FILE__)
+    original_path = $:.dup
+    original_features = $".dup
+    $:.push(path)
+
+    with_loading do
+      assert_equal true, require('loaded_constant')
+    end
+  ensure
+    remove_constants(:LoadedConstant)
+    $".replace(original_features)
+    $:.replace(original_path)
+  end
+
+  def test_require_returns_true_when_file_not_yet_required_even_when_no_new_constants_added
+    path = File.expand_path("../autoloading_fixtures/load_path", __FILE__)
+    original_path = $:.dup
+    original_features = $".dup
+    $:.push(path)
+
+    with_loading do
+      Object.module_eval "module LoadedConstant; end"
+      assert_equal true, require('loaded_constant')
+    end
+  ensure
+    remove_constants(:LoadedConstant)
+    $".replace(original_features)
+    $:.replace(original_path)
+  end
+
+  def test_require_returns_false_when_file_already_required
+    path = File.expand_path("../autoloading_fixtures/load_path", __FILE__)
+    original_path = $:.dup
+    original_features = $".dup
+    $:.push(path)
+
+    with_loading do
+      require 'loaded_constant'
+      assert_equal false, require('loaded_constant')
+    end
+  ensure
+    remove_constants(:LoadedConstant)
+    $".replace(original_features)
+    $:.replace(original_path)
+  end
+
+  def test_require_raises_load_error_when_file_not_found
+    with_loading do
+      assert_raise(LoadError) { require 'this_file_dont_exist_dude' }
+    end
+  ensure
+    remove_constants(:LoadedConstant)
+  end
+
+  def test_load_returns_true_when_file_found
+    path = File.expand_path("../autoloading_fixtures/load_path", __FILE__)
+    original_path = $:.dup
+    original_features = $".dup
+    $:.push(path)
+
+    with_loading do
+      assert_equal true, load('loaded_constant.rb')
+      assert_equal true, load('loaded_constant.rb')
+    end
+  ensure
+    remove_constants(:LoadedConstant)
+    $".replace(original_features)
+    $:.replace(original_path)
+  end
+
+  def test_load_raises_load_error_when_file_not_found
+    with_loading do
+      assert_raise(LoadError) { load 'this_file_dont_exist_dude.rb' }
+    end
+  ensure
+    remove_constants(:LoadedConstant)
+  end
+
+  def failing_test_access_thru_and_upwards_fails
+    with_autoloading_fixtures do
+      assert ! defined?(ModuleFolder)
+      assert_raise(NameError) { ModuleFolder::Object }
+      assert_raise(NameError) { ModuleFolder::NestedClass::Object }
+      Object.__send__ :remove_const, :ModuleFolder
+    end
+  end
+
+  def test_non_existing_const_raises_name_error_with_fully_qualified_name
+    with_autoloading_fixtures do
+      e = assert_raise(NameError) { A::DoesNotExist.nil? }
+      assert_equal "uninitialized constant A::DoesNotExist", e.message
+
+      e = assert_raise(NameError) { A::B::DoesNotExist.nil? }
+      assert_equal "uninitialized constant A::B::DoesNotExist", e.message
+    end
+  end
+
+  def test_smart_name_error_strings
+    e = assert_raise NameError do
+      Object.module_eval "ImaginaryObject"
+    end
+    assert_includes "uninitialized constant ImaginaryObject", e.message
+  end
+
+  def test_loadable_constants_for_path_should_handle_empty_autoloads
+    assert_equal [], ActiveSupport::Dependencies.loadable_constants_for_path('hello')
+  end
+
+  def test_loadable_constants_for_path_should_handle_relative_paths
+    fake_root = 'dependencies'
+    relative_root = File.dirname(__FILE__) + '/dependencies'
+    ['', '/'].each do |suffix|
+      with_loading fake_root + suffix do
+        assert_equal ["A::B"], ActiveSupport::Dependencies.loadable_constants_for_path(relative_root + '/a/b')
+      end
+    end
+  end
+
+  def test_loadable_constants_for_path_should_provide_all_results
+    fake_root = '/usr/apps/backpack'
+    with_loading fake_root, fake_root + '/lib' do
+      root = ActiveSupport::Dependencies.autoload_paths.first
+      assert_equal ["Lib::A::B", "A::B"], ActiveSupport::Dependencies.loadable_constants_for_path(root + '/lib/a/b')
+    end
+  end
+
+  def test_loadable_constants_for_path_should_uniq_results
+    fake_root = '/usr/apps/backpack/lib'
+    with_loading fake_root, fake_root + '/' do
+      root = ActiveSupport::Dependencies.autoload_paths.first
+      assert_equal ["A::B"], ActiveSupport::Dependencies.loadable_constants_for_path(root + '/a/b')
+    end
+  end
+
+  def test_loadable_constants_with_load_path_without_trailing_slash
+    path = File.dirname(__FILE__) + '/autoloading_fixtures/class_folder/inline_class.rb'
+    with_loading 'autoloading_fixtures/class/' do
+      assert_equal [], ActiveSupport::Dependencies.loadable_constants_for_path(path)
+    end
+  end
+
+  def test_qualified_const_defined
+    assert ActiveSupport::Dependencies.qualified_const_defined?("Object")
+    assert ActiveSupport::Dependencies.qualified_const_defined?("::Object")
+    assert ActiveSupport::Dependencies.qualified_const_defined?("::Object::Kernel")
+    assert ActiveSupport::Dependencies.qualified_const_defined?("::ActiveSupport::TestCase")
+  end
+
+  def test_qualified_const_defined_should_not_call_const_missing
+    ModuleWithMissing.missing_count = 0
+    assert ! ActiveSupport::Dependencies.qualified_const_defined?("ModuleWithMissing::A")
+    assert_equal 0, ModuleWithMissing.missing_count
+    assert ! ActiveSupport::Dependencies.qualified_const_defined?("ModuleWithMissing::A::B")
+    assert_equal 0, ModuleWithMissing.missing_count
+  end
+
+  def test_qualified_const_defined_explodes_with_invalid_const_name
+    assert_raises(NameError) { ActiveSupport::Dependencies.qualified_const_defined?("invalid") }
+  end
+
+  def test_autoloaded?
+    with_autoloading_fixtures do
+      assert ! ActiveSupport::Dependencies.autoloaded?("ModuleFolder")
+      assert ! ActiveSupport::Dependencies.autoloaded?("ModuleFolder::NestedClass")
+
+      assert ActiveSupport::Dependencies.autoloaded?(ModuleFolder)
+
+      assert ActiveSupport::Dependencies.autoloaded?("ModuleFolder")
+      assert ! ActiveSupport::Dependencies.autoloaded?("ModuleFolder::NestedClass")
+
+      assert ActiveSupport::Dependencies.autoloaded?(ModuleFolder::NestedClass)
+
+      assert ActiveSupport::Dependencies.autoloaded?("ModuleFolder")
+      assert ActiveSupport::Dependencies.autoloaded?("ModuleFolder::NestedClass")
+
+      assert ActiveSupport::Dependencies.autoloaded?("::ModuleFolder")
+      assert ActiveSupport::Dependencies.autoloaded?(:ModuleFolder)
+
+      # Anonymous modules aren't autoloaded.
+      assert !ActiveSupport::Dependencies.autoloaded?(Module.new)
+
+      nil_name = Module.new
+      def nil_name.name() nil end
+      assert !ActiveSupport::Dependencies.autoloaded?(nil_name)
+
+      Object.class_eval { remove_const :ModuleFolder }
+    end
+  end
+
+  def test_qualified_name_for
+    assert_equal "A", ActiveSupport::Dependencies.qualified_name_for(Object, :A)
+    assert_equal "A", ActiveSupport::Dependencies.qualified_name_for(:Object, :A)
+    assert_equal "A", ActiveSupport::Dependencies.qualified_name_for("Object", :A)
+    assert_equal "A", ActiveSupport::Dependencies.qualified_name_for("::Object", :A)
+
+    assert_equal "ActiveSupport::Dependencies::A", ActiveSupport::Dependencies.qualified_name_for(:'ActiveSupport::Dependencies', :A)
+    assert_equal "ActiveSupport::Dependencies::A", ActiveSupport::Dependencies.qualified_name_for(ActiveSupport::Dependencies, :A)
+  end
+
+  def test_file_search
+    with_loading 'dependencies' do
+      root = ActiveSupport::Dependencies.autoload_paths.first
+      assert_equal nil, ActiveSupport::Dependencies.search_for_file('service_three')
+      assert_equal nil, ActiveSupport::Dependencies.search_for_file('service_three.rb')
+      assert_equal root + '/service_one.rb', ActiveSupport::Dependencies.search_for_file('service_one')
+      assert_equal root + '/service_one.rb', ActiveSupport::Dependencies.search_for_file('service_one.rb')
+    end
+  end
+
+  def test_file_search_uses_first_in_load_path
+    with_loading 'dependencies', 'autoloading_fixtures' do
+      deps, autoload = ActiveSupport::Dependencies.autoload_paths
+      assert_match %r/dependencies/, deps
+      assert_match %r/autoloading_fixtures/, autoload
+
+      assert_equal deps + '/conflict.rb', ActiveSupport::Dependencies.search_for_file('conflict')
+    end
+    with_loading 'autoloading_fixtures', 'dependencies' do
+      autoload, deps = ActiveSupport::Dependencies.autoload_paths
+      assert_match %r/dependencies/, deps
+      assert_match %r/autoloading_fixtures/, autoload
+
+      assert_equal autoload + '/conflict.rb', ActiveSupport::Dependencies.search_for_file('conflict')
+    end
+
+  end
+
+  def test_custom_const_missing_should_work
+    Object.module_eval <<-end_eval, __FILE__, __LINE__ + 1
+      module ModuleWithCustomConstMissing
+        def self.const_missing(name)
+          const_set name, name.to_s.hash
+        end
+
+        module A
+        end
+      end
+    end_eval
+
+    with_autoloading_fixtures do
+      assert_kind_of Integer, ::ModuleWithCustomConstMissing::B
+      assert_kind_of Module, ::ModuleWithCustomConstMissing::A
+      assert_kind_of String, ::ModuleWithCustomConstMissing::A::B
+    end
+  end
+
+  def test_const_missing_in_anonymous_modules_loads_top_level_constants
+    with_autoloading_fixtures do
+      # class_eval STRING pushes the class to the nesting of the eval'ed code.
+      klass = Class.new.class_eval "E"
+      assert_equal E, klass
+    end
+  end
+
+  def test_const_missing_in_anonymous_modules_raises_if_the_constant_belongs_to_Object
+    with_autoloading_fixtures do
+      require_dependency 'e'
+
+      mod = Module.new
+      e = assert_raise(NameError) { mod::E }
+      assert_equal 'E cannot be autoloaded from an anonymous class or module', e.message
+    end
+  end
+
+  def test_removal_from_tree_should_be_detected
+    with_loading 'dependencies' do
+      c = ServiceOne
+      ActiveSupport::Dependencies.clear
+      assert ! defined?(ServiceOne)
+      e = assert_raise ArgumentError do
+        ActiveSupport::Dependencies.load_missing_constant(c, :FakeMissing)
+      end
+      assert_match %r{ServiceOne has been removed from the module tree}i, e.message
+    end
+  end
+
+  def test_references_should_work
+    with_loading 'dependencies' do
+      c = ActiveSupport::Dependencies.reference("ServiceOne")
+      service_one_first = ServiceOne
+      assert_equal service_one_first, c.get("ServiceOne")
+      ActiveSupport::Dependencies.clear
+      assert ! defined?(ServiceOne)
+
+      service_one_second = ServiceOne
+      assert_not_equal service_one_first, c.get("ServiceOne")
+      assert_equal service_one_second, c.get("ServiceOne")
+    end
+  end
+
+  def test_constantize_shortcut_for_cached_constant_lookups
+    with_loading 'dependencies' do
+      assert_equal ServiceOne, ActiveSupport::Dependencies.constantize("ServiceOne")
+    end
+  end
+
+  def test_nested_load_error_isnt_rescued
+    with_loading 'dependencies' do
+      assert_raise(MissingSourceFile) do
+        RequiresNonexistent1
+      end
+    end
+  end
+
+  def test_autoload_once_paths_do_not_add_to_autoloaded_constants
+    with_autoloading_fixtures do
+      ActiveSupport::Dependencies.autoload_once_paths = ActiveSupport::Dependencies.autoload_paths.dup
+
+      assert ! ActiveSupport::Dependencies.autoloaded?("ModuleFolder")
+      assert ! ActiveSupport::Dependencies.autoloaded?("ModuleFolder::NestedClass")
+      assert ! ActiveSupport::Dependencies.autoloaded?(ModuleFolder)
+
+      1 if ModuleFolder::NestedClass # 1 if to avoid warning
+      assert ! ActiveSupport::Dependencies.autoloaded?(ModuleFolder::NestedClass)
+    end
+  ensure
+    Object.class_eval { remove_const :ModuleFolder }
+    ActiveSupport::Dependencies.autoload_once_paths = []
+  end
+
+  def test_autoload_once_pathnames_do_not_add_to_autoloaded_constants
+    with_autoloading_fixtures do
+      pathnames = ActiveSupport::Dependencies.autoload_paths.collect{|p| Pathname.new(p)}
+      ActiveSupport::Dependencies.autoload_paths = pathnames
+      ActiveSupport::Dependencies.autoload_once_paths = pathnames
+
+      assert ! ActiveSupport::Dependencies.autoloaded?("ModuleFolder")
+      assert ! ActiveSupport::Dependencies.autoloaded?("ModuleFolder::NestedClass")
+      assert ! ActiveSupport::Dependencies.autoloaded?(ModuleFolder)
+
+      1 if ModuleFolder::NestedClass # 1 if to avoid warning
+      assert ! ActiveSupport::Dependencies.autoloaded?(ModuleFolder::NestedClass)
+    end
+  ensure
+    Object.class_eval { remove_const :ModuleFolder }
+    ActiveSupport::Dependencies.autoload_once_paths = []
+  end
+
+  def test_application_should_special_case_application_controller
+    with_autoloading_fixtures do
+      require_dependency 'application'
+      assert_equal 10, ApplicationController
+      assert ActiveSupport::Dependencies.autoloaded?(:ApplicationController)
+    end
+  end
+
+  def test_preexisting_constants_are_not_marked_as_autoloaded
+    with_autoloading_fixtures do
+      require_dependency 'e'
+      assert ActiveSupport::Dependencies.autoloaded?(:E)
+      ActiveSupport::Dependencies.clear
+    end
+
+    Object.const_set :E, Class.new
+    with_autoloading_fixtures do
+      require_dependency 'e'
+      assert ! ActiveSupport::Dependencies.autoloaded?(:E), "E shouldn't be marked autoloaded!"
+      ActiveSupport::Dependencies.clear
+    end
+
+  ensure
+    Object.class_eval { remove_const :E }
+  end
+
+  def test_constants_in_capitalized_nesting_marked_as_autoloaded
+    with_autoloading_fixtures do
+      ActiveSupport::Dependencies.load_missing_constant(HTML, "SomeClass")
+
+      assert ActiveSupport::Dependencies.autoloaded?("HTML::SomeClass")
+    end
+  end
+
+  def test_unloadable
+    with_autoloading_fixtures do
+      Object.const_set :M, Module.new
+      M.unloadable
+
+      ActiveSupport::Dependencies.clear
+      assert ! defined?(M)
+
+      Object.const_set :M, Module.new
+      ActiveSupport::Dependencies.clear
+      assert ! defined?(M), "Dependencies should unload unloadable constants each time"
+    end
+  end
+
+  def test_unloadable_should_fail_with_anonymous_modules
+    with_autoloading_fixtures do
+      m = Module.new
+      assert_raise(ArgumentError) { m.unloadable }
+    end
+  end
+
+  def test_unloadable_should_return_change_flag
+    with_autoloading_fixtures do
+      Object.const_set :M, Module.new
+      assert_equal true, M.unloadable
+      assert_equal false, M.unloadable
+    end
+  ensure
+    Object.class_eval { remove_const :M }
+  end
+
+  def test_unloadable_constants_should_receive_callback
+    Object.const_set :C, Class.new
+    C.unloadable
+    C.expects(:before_remove_const).once
+    assert C.respond_to?(:before_remove_const)
+    ActiveSupport::Dependencies.clear
+    assert !defined?(C)
+  ensure
+    Object.class_eval { remove_const :C } if defined?(C)
+  end
+
+  def test_new_contants_in_without_constants
+    assert_equal [], (ActiveSupport::Dependencies.new_constants_in(Object) { })
+    assert ActiveSupport::Dependencies.constant_watch_stack.all? {|k,v| v.empty? }
+  end
+
+  def test_new_constants_in_with_a_single_constant
+    assert_equal ["Hello"], ActiveSupport::Dependencies.new_constants_in(Object) {
+                              Object.const_set :Hello, 10
+                            }.map(&:to_s)
+    assert ActiveSupport::Dependencies.constant_watch_stack.all? {|k,v| v.empty? }
+  ensure
+    Object.class_eval { remove_const :Hello }
+  end
+
+  def test_new_constants_in_with_nesting
+    outer = ActiveSupport::Dependencies.new_constants_in(Object) do
+      Object.const_set :OuterBefore, 10
+
+      assert_equal ["Inner"], ActiveSupport::Dependencies.new_constants_in(Object) {
+                                Object.const_set :Inner, 20
+                              }.map(&:to_s)
+
+      Object.const_set :OuterAfter, 30
+    end
+
+    assert_equal ["OuterAfter", "OuterBefore"], outer.sort.map(&:to_s)
+    assert ActiveSupport::Dependencies.constant_watch_stack.all? {|k,v| v.empty? }
+  ensure
+    %w(OuterBefore Inner OuterAfter).each do |name|
+      Object.class_eval { remove_const name if const_defined?(name) }
+    end
+  end
+
+  def test_new_constants_in_module
+    Object.const_set :M, Module.new
+
+    outer = ActiveSupport::Dependencies.new_constants_in(M) do
+      M.const_set :OuterBefore, 10
+
+      inner = ActiveSupport::Dependencies.new_constants_in(M) do
+        M.const_set :Inner, 20
+      end
+      assert_equal ["M::Inner"], inner
+
+      M.const_set :OuterAfter, 30
+    end
+    assert_equal ["M::OuterAfter", "M::OuterBefore"], outer.sort
+    assert ActiveSupport::Dependencies.constant_watch_stack.all? {|k,v| v.empty? }
+  ensure
+    Object.class_eval { remove_const :M }
+  end
+
+  def test_new_constants_in_module_using_name
+    outer = ActiveSupport::Dependencies.new_constants_in(:M) do
+      Object.const_set :M, Module.new
+      M.const_set :OuterBefore, 10
+
+      inner = ActiveSupport::Dependencies.new_constants_in(:M) do
+        M.const_set :Inner, 20
+      end
+      assert_equal ["M::Inner"], inner
+
+      M.const_set :OuterAfter, 30
+    end
+    assert_equal ["M::OuterAfter", "M::OuterBefore"], outer.sort
+    assert ActiveSupport::Dependencies.constant_watch_stack.all? {|k,v| v.empty? }
+  ensure
+    Object.class_eval { remove_const :M }
+  end
+
+  def test_new_constants_in_with_inherited_constants
+    m = ActiveSupport::Dependencies.new_constants_in(:Object) do
+      Object.class_eval { include ModuleWithConstant }
+    end
+    assert_equal [], m
+  end
+
+  def test_new_constants_in_with_illegal_module_name_raises_correct_error
+    assert_raise(NameError) do
+      ActiveSupport::Dependencies.new_constants_in("Illegal-Name") {}
+    end
+  end
+
+  def test_file_with_multiple_constants_and_require_dependency
+    with_autoloading_fixtures do
+      assert ! defined?(MultipleConstantFile)
+      assert ! defined?(SiblingConstant)
+
+      require_dependency 'multiple_constant_file'
+      assert defined?(MultipleConstantFile)
+      assert defined?(SiblingConstant)
+      assert ActiveSupport::Dependencies.autoloaded?(:MultipleConstantFile)
+      assert ActiveSupport::Dependencies.autoloaded?(:SiblingConstant)
+
+      ActiveSupport::Dependencies.clear
+
+      assert ! defined?(MultipleConstantFile)
+      assert ! defined?(SiblingConstant)
+    end
+  end
+
+  def test_file_with_multiple_constants_and_auto_loading
+    with_autoloading_fixtures do
+      assert ! defined?(MultipleConstantFile)
+      assert ! defined?(SiblingConstant)
+
+      assert_equal 10, MultipleConstantFile
+
+      assert defined?(MultipleConstantFile)
+      assert defined?(SiblingConstant)
+      assert ActiveSupport::Dependencies.autoloaded?(:MultipleConstantFile)
+      assert ActiveSupport::Dependencies.autoloaded?(:SiblingConstant)
+
+      ActiveSupport::Dependencies.clear
+
+      assert ! defined?(MultipleConstantFile)
+      assert ! defined?(SiblingConstant)
+    end
+  end
+
+  def test_nested_file_with_multiple_constants_and_require_dependency
+    with_autoloading_fixtures do
+      assert ! defined?(ClassFolder::NestedClass)
+      assert ! defined?(ClassFolder::SiblingClass)
+
+      require_dependency 'class_folder/nested_class'
+
+      assert defined?(ClassFolder::NestedClass)
+      assert defined?(ClassFolder::SiblingClass)
+      assert ActiveSupport::Dependencies.autoloaded?("ClassFolder::NestedClass")
+      assert ActiveSupport::Dependencies.autoloaded?("ClassFolder::SiblingClass")
+
+      ActiveSupport::Dependencies.clear
+
+      assert ! defined?(ClassFolder::NestedClass)
+      assert ! defined?(ClassFolder::SiblingClass)
+    end
+  end
+
+  def test_nested_file_with_multiple_constants_and_auto_loading
+    with_autoloading_fixtures do
+      assert ! defined?(ClassFolder::NestedClass)
+      assert ! defined?(ClassFolder::SiblingClass)
+
+      assert_kind_of Class, ClassFolder::NestedClass
+
+      assert defined?(ClassFolder::NestedClass)
+      assert defined?(ClassFolder::SiblingClass)
+      assert ActiveSupport::Dependencies.autoloaded?("ClassFolder::NestedClass")
+      assert ActiveSupport::Dependencies.autoloaded?("ClassFolder::SiblingClass")
+
+      ActiveSupport::Dependencies.clear
+
+      assert ! defined?(ClassFolder::NestedClass)
+      assert ! defined?(ClassFolder::SiblingClass)
+    end
+  end
+
+  def test_autoload_doesnt_shadow_no_method_error_with_relative_constant
+    with_autoloading_fixtures do
+      assert !defined?(::RaisesNoMethodError), "::RaisesNoMethodError is defined but it hasn't been referenced yet!"
+      2.times do
+        assert_raise(NoMethodError) { RaisesNoMethodError }
+        assert !defined?(::RaisesNoMethodError), "::RaisesNoMethodError is defined but it should have failed!"
+      end
+    end
+
+  ensure
+    Object.class_eval { remove_const :RaisesNoMethodError if const_defined?(:RaisesNoMethodError) }
+  end
+
+  def test_autoload_doesnt_shadow_no_method_error_with_absolute_constant
+    with_autoloading_fixtures do
+      assert !defined?(::RaisesNoMethodError), "::RaisesNoMethodError is defined but it hasn't been referenced yet!"
+      2.times do
+        assert_raise(NoMethodError) { ::RaisesNoMethodError }
+        assert !defined?(::RaisesNoMethodError), "::RaisesNoMethodError is defined but it should have failed!"
+      end
+    end
+
+  ensure
+    Object.class_eval { remove_const :RaisesNoMethodError if const_defined?(:RaisesNoMethodError) }
+  end
+
+  def test_autoload_doesnt_shadow_error_when_mechanism_not_set_to_load
+    with_autoloading_fixtures do
+      ActiveSupport::Dependencies.mechanism = :require
+      2.times do
+        assert_raise(NameError) { assert_equal 123, ::RaisesNameError::FooBarBaz }
+      end
+    end
+  end
+
+  def test_autoload_doesnt_shadow_name_error
+    with_autoloading_fixtures do
+      Object.send(:remove_const, :RaisesNameError) if defined?(::RaisesNameError)
+      2.times do
+        e = assert_raise NameError do
+          ::RaisesNameError::FooBarBaz.object_id
+        end
+        assert_equal 'uninitialized constant RaisesNameError::FooBarBaz', e.message
+        assert !defined?(::RaisesNameError), "::RaisesNameError is defined but it should have failed!"
+      end
+
+      assert !defined?(::RaisesNameError)
+      2.times do
+        assert_raise(NameError) { ::RaisesNameError }
+        assert !defined?(::RaisesNameError), "::RaisesNameError is defined but it should have failed!"
+      end
+    end
+
+  ensure
+    Object.class_eval { remove_const :RaisesNoMethodError if const_defined?(:RaisesNoMethodError) }
+  end
+
+  def test_remove_constant_handles_double_colon_at_start
+    Object.const_set 'DeleteMe', Module.new
+    DeleteMe.const_set 'OrMe', Module.new
+    ActiveSupport::Dependencies.remove_constant "::DeleteMe::OrMe"
+    assert ! defined?(DeleteMe::OrMe)
+    assert defined?(DeleteMe)
+    ActiveSupport::Dependencies.remove_constant "::DeleteMe"
+    assert ! defined?(DeleteMe)
+  end
+
+  def test_remove_constant_does_not_trigger_loading_autoloads
+    constant = 'ShouldNotBeAutoloaded'
+    Object.class_eval do
+      autoload constant, File.expand_path('../autoloading_fixtures/should_not_be_required', __FILE__)
+    end
+
+    assert_nil ActiveSupport::Dependencies.remove_constant(constant), "Kernel#autoload has been triggered by remove_constant"
+    assert !defined?(ShouldNotBeAutoloaded)
+  end
+
+  def test_remove_constant_does_not_autoload_already_removed_parents_as_a_side_effect
+    with_autoloading_fixtures do
+      _ = ::A    # assignment to silence parse-time warning "possibly useless use of :: in void context"
+      _ = ::A::B # assignment to silence parse-time warning "possibly useless use of :: in void context"
+      ActiveSupport::Dependencies.remove_constant('A')
+      ActiveSupport::Dependencies.remove_constant('A::B')
+      assert !defined?(A)
+    end
+  end
+
+  def test_load_once_constants_should_not_be_unloaded
+    with_autoloading_fixtures do
+      ActiveSupport::Dependencies.autoload_once_paths = ActiveSupport::Dependencies.autoload_paths
+      _ = ::A # assignment to silence parse-time warning "possibly useless use of :: in void context"
+      assert defined?(A)
+      ActiveSupport::Dependencies.clear
+      assert defined?(A)
+    end
+  ensure
+    ActiveSupport::Dependencies.autoload_once_paths = []
+    Object.class_eval { remove_const :A if const_defined?(:A) }
+  end
+
+  def test_access_unloaded_constants_for_reload
+    with_autoloading_fixtures do
+      assert_kind_of Module, A
+      assert_kind_of Class, A::B # Necessary to load A::B for the test
+      ActiveSupport::Dependencies.mark_for_unload(A::B)
+      ActiveSupport::Dependencies.remove_unloadable_constants!
+       
+      A::B # Make sure no circular dependency error
+    end
+  end
+
+
+  def test_autoload_once_paths_should_behave_when_recursively_loading
+    with_loading 'dependencies', 'autoloading_fixtures' do
+      ActiveSupport::Dependencies.autoload_once_paths = [ActiveSupport::Dependencies.autoload_paths.last]
+      assert !defined?(CrossSiteDependency)
+      assert_nothing_raised { CrossSiteDepender.nil? }
+      assert defined?(CrossSiteDependency)
+      assert !ActiveSupport::Dependencies.autoloaded?(CrossSiteDependency),
+        "CrossSiteDependency shouldn't be marked as autoloaded!"
+      ActiveSupport::Dependencies.clear
+      assert defined?(CrossSiteDependency),
+        "CrossSiteDependency shouldn't have been unloaded!"
+    end
+  ensure
+    ActiveSupport::Dependencies.autoload_once_paths = []
+  end
+
+  def test_hook_called_multiple_times
+    assert_nothing_raised { ActiveSupport::Dependencies.hook! }
+  end
+
+  def test_unhook
+    ActiveSupport::Dependencies.unhook!
+    assert !Module.new.respond_to?(:const_missing_without_dependencies)
+    assert !Module.new.respond_to?(:load_without_new_constant_marking)
+  ensure
+    ActiveSupport::Dependencies.hook!
+  end
+
+private
+  def remove_constants(*constants)
+    constants.each do |constant|
+      Object.send(:remove_const, constant) if Object.const_defined?(constant)
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/dependencies_test_helpers.rb b/app/server/vendor/activesupport/test/dependencies_test_helpers.rb
new file mode 100644
index 0000000..9268512
--- /dev/null
+++ b/app/server/vendor/activesupport/test/dependencies_test_helpers.rb
@@ -0,0 +1,27 @@
+module DependenciesTestHelpers
+  def with_loading(*from)
+    old_mechanism, ActiveSupport::Dependencies.mechanism = ActiveSupport::Dependencies.mechanism, :load
+    this_dir = File.dirname(__FILE__)
+    parent_dir = File.dirname(this_dir)
+    path_copy = $LOAD_PATH.dup
+    $LOAD_PATH.unshift(parent_dir) unless $LOAD_PATH.include?(parent_dir)
+    prior_autoload_paths = ActiveSupport::Dependencies.autoload_paths
+    ActiveSupport::Dependencies.autoload_paths = from.collect { |f| "#{this_dir}/#{f}" }
+    yield
+  ensure
+    $LOAD_PATH.replace(path_copy)
+    ActiveSupport::Dependencies.autoload_paths = prior_autoload_paths
+    ActiveSupport::Dependencies.mechanism = old_mechanism
+    ActiveSupport::Dependencies.explicitly_unloadable_constants = []
+  end
+
+  def with_autoloading_fixtures(&block)
+    with_loading 'autoloading_fixtures', &block
+  end
+
+  def remove_constants(*constants)
+    constants.each do |constant|
+      Object.send(:remove_const, constant) if Object.const_defined?(constant)
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/deprecation/proxy_wrappers_test.rb b/app/server/vendor/activesupport/test/deprecation/proxy_wrappers_test.rb
new file mode 100644
index 0000000..e4f0f0f
--- /dev/null
+++ b/app/server/vendor/activesupport/test/deprecation/proxy_wrappers_test.rb
@@ -0,0 +1,22 @@
+require 'abstract_unit'
+require 'active_support/deprecation'
+
+class ProxyWrappersTest < ActiveSupport::TestCase
+  Waffles     = false
+  NewWaffles  = :hamburgers
+
+  def test_deprecated_object_proxy_doesnt_wrap_falsy_objects
+    proxy = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(nil, "message")
+    assert !proxy
+  end
+
+  def test_deprecated_instance_variable_proxy_doesnt_wrap_falsy_objects
+    proxy = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(nil, :waffles)
+    assert !proxy
+  end
+
+  def test_deprecated_constant_proxy_doesnt_wrap_falsy_objects
+    proxy = ActiveSupport::Deprecation::DeprecatedConstantProxy.new(Waffles, NewWaffles)
+    assert !proxy
+  end
+end
diff --git a/app/server/vendor/activesupport/test/deprecation_test.rb b/app/server/vendor/activesupport/test/deprecation_test.rb
new file mode 100644
index 0000000..ee1c695
--- /dev/null
+++ b/app/server/vendor/activesupport/test/deprecation_test.rb
@@ -0,0 +1,358 @@
+require 'abstract_unit'
+
+class Deprecatee
+  def initialize
+    @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request)
+    @_request = 'there we go'
+  end
+  def request; @_request end
+  def old_request; @request end
+
+  def partially(foo = nil)
+    ActiveSupport::Deprecation.warn('calling with foo=nil is out') if foo.nil?
+  end
+
+  def not() 2 end
+  def none() 1 end
+  def one(a) a end
+  def multi(a,b,c) [a,b,c] end
+  deprecate :none, :one, :multi
+
+  def a; end
+  def b; end
+  def c; end
+  def d; end
+  def e; end
+  deprecate :a, :b, :c => :e, :d => "you now need to do something extra for this one"
+
+  def f=(v); end
+  deprecate :f=
+
+  module B
+    C = 1
+  end
+  A = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Deprecatee::A', 'Deprecatee::B::C')
+end
+
+
+class DeprecationTest < ActiveSupport::TestCase
+  def setup
+    # Track the last warning.
+    @old_behavior = ActiveSupport::Deprecation.behavior
+    @last_message = nil
+    ActiveSupport::Deprecation.behavior = Proc.new { |message| @last_message = message }
+
+    @dtc = Deprecatee.new
+  end
+
+  def teardown
+    ActiveSupport::Deprecation.behavior = @old_behavior
+  end
+
+  def test_inline_deprecation_warning
+    assert_deprecated(/foo=nil/) do
+      @dtc.partially
+    end
+  end
+
+  def test_undeprecated
+    assert_not_deprecated do
+      assert_equal 2, @dtc.not
+    end
+  end
+
+  def test_deprecate_class_method
+    assert_deprecated(/none is deprecated/) do
+      assert_equal 1, @dtc.none
+    end
+
+    assert_deprecated(/one is deprecated/) do
+      assert_equal 1, @dtc.one(1)
+    end
+
+    assert_deprecated(/multi is deprecated/) do
+      assert_equal [1,2,3], @dtc.multi(1,2,3)
+    end
+  end
+
+  def test_deprecate_object
+    deprecated_object = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(Object.new, ':bomb:')
+    assert_deprecated(/:bomb:/) { deprecated_object.to_s }
+  end
+
+  def test_nil_behavior_is_ignored
+    ActiveSupport::Deprecation.behavior = nil
+    assert_deprecated(/foo=nil/) { @dtc.partially }
+  end
+
+  def test_several_behaviors
+    @a, @b = nil, nil
+
+    ActiveSupport::Deprecation.behavior = [
+      Proc.new { |msg, callstack| @a = msg },
+      Proc.new { |msg, callstack| @b = msg }
+    ]
+
+    @dtc.partially
+    assert_match(/foo=nil/, @a)
+    assert_match(/foo=nil/, @b)
+  end
+
+  def test_raise_behaviour
+    ActiveSupport::Deprecation.behavior = :raise
+
+    message   = 'Revise this deprecated stuff now!'
+    callstack = %w(foo bar baz)
+
+    e = assert_raise ActiveSupport::DeprecationException do
+      ActiveSupport::Deprecation.behavior.first.call(message, callstack)
+    end
+    assert_equal message, e.message
+    assert_equal callstack, e.backtrace
+  end
+
+  def test_default_stderr_behavior
+    ActiveSupport::Deprecation.behavior = :stderr
+    behavior = ActiveSupport::Deprecation.behavior.first
+
+    content = capture(:stderr) {
+      assert_nil behavior.call('Some error!', ['call stack!'])
+    }
+    assert_match(/Some error!/, content)
+    assert_match(/call stack!/, content)
+  end
+
+  def test_default_stderr_behavior_with_warn_method
+    ActiveSupport::Deprecation.behavior = :stderr
+
+    content = capture(:stderr) {
+      ActiveSupport::Deprecation.warn('Instance error!', ['instance call stack!'])
+    }
+
+    assert_match(/Instance error!/, content)
+    assert_match(/instance call stack!/, content)
+  end
+
+  def test_default_silence_behavior
+    ActiveSupport::Deprecation.behavior = :silence
+    behavior = ActiveSupport::Deprecation.behavior.first
+
+    stderr_output = capture(:stderr) {
+      assert_nil behavior.call('Some error!', ['call stack!'])
+    }
+    assert stderr_output.blank?
+  end
+
+  def test_deprecated_instance_variable_proxy
+    assert_not_deprecated { @dtc.request.size }
+
+    assert_deprecated('@request.size') { assert_equal @dtc.request.size, @dtc.old_request.size }
+    assert_deprecated('@request.to_s') { assert_equal @dtc.request.to_s, @dtc.old_request.to_s }
+  end
+
+  def test_deprecated_instance_variable_proxy_shouldnt_warn_on_inspect
+    assert_not_deprecated { assert_equal @dtc.request.inspect, @dtc.old_request.inspect }
+  end
+
+  def test_deprecated_constant_proxy
+    assert_not_deprecated { Deprecatee::B::C }
+    assert_deprecated('Deprecatee::A') { assert_equal Deprecatee::B::C, Deprecatee::A }
+    assert_not_deprecated { assert_equal Deprecatee::B::C.class, Deprecatee::A.class }
+  end
+
+  def test_assert_deprecation_without_match
+    assert_deprecated do
+      @dtc.partially
+    end
+  end
+
+  def test_assert_deprecated_matches_any_warning
+    assert_deprecated 'abc' do
+      ActiveSupport::Deprecation.warn 'abc'
+      ActiveSupport::Deprecation.warn 'def'
+    end
+  rescue Minitest::Assertion
+    flunk 'assert_deprecated should match any warning in block, not just the last one'
+  end
+
+  def test_assert_not_deprecated_returns_result_of_block
+    assert_equal 123, assert_not_deprecated { 123 }
+  end
+
+  def test_assert_deprecated_returns_result_of_block
+    result = assert_deprecated('abc') do
+      ActiveSupport::Deprecation.warn 'abc'
+      123
+    end
+    assert_equal 123, result
+  end
+
+  def test_assert_deprecated_warn_work_with_default_behavior
+    ActiveSupport::Deprecation.instance_variable_set('@behavior' , nil)
+    assert_deprecated('abc') do
+      ActiveSupport::Deprecation.warn 'abc'
+    end
+  end
+
+  def test_silence
+    ActiveSupport::Deprecation.silence do
+      assert_not_deprecated { @dtc.partially }
+    end
+
+    ActiveSupport::Deprecation.silenced = true
+    assert_not_deprecated { @dtc.partially }
+    ActiveSupport::Deprecation.silenced = false
+  end
+
+  def test_deprecation_without_explanation
+    assert_deprecated { @dtc.a }
+    assert_deprecated { @dtc.b }
+    assert_deprecated { @dtc.f = :foo }
+  end
+
+  def test_deprecation_with_alternate_method
+    assert_deprecated(/use e instead/) { @dtc.c }
+  end
+
+  def test_deprecation_with_explicit_message
+    assert_deprecated(/you now need to do something extra for this one/) { @dtc.d }
+  end
+
+  def test_deprecation_in_other_object
+    messages = []
+
+    klass = Class.new do
+      delegate :warn, :behavior=, to: ActiveSupport::Deprecation
+    end
+
+    o = klass.new
+    o.behavior = Proc.new { |message, callstack| messages << message }
+    assert_difference("messages.size") do
+      o.warn("warning")
+    end
+  end
+
+  def test_deprecated_method_with_custom_method_warning
+    deprecator = deprecator_with_messages
+
+    class << deprecator
+      private
+        def deprecated_method_warning(method, message)
+          "deprecator.deprecated_method_warning.#{method}"
+        end
+    end
+
+    deprecatee = Class.new do
+      def method
+      end
+      deprecate :method, deprecator: deprecator
+    end
+
+    deprecatee.new.method
+    assert deprecator.messages.first.match("DEPRECATION WARNING: deprecator.deprecated_method_warning.method")
+  end
+
+  def test_deprecate_with_custom_deprecator
+    custom_deprecator = mock('Deprecator') do
+      expects(:deprecation_warning)
+    end
+
+    klass = Class.new do
+      def method
+      end
+      deprecate :method, deprecator: custom_deprecator
+    end
+
+    klass.new.method
+  end
+
+  def test_deprecated_constant_with_deprecator_given
+    deprecator = deprecator_with_messages
+    klass = Class.new
+    klass.const_set(:OLD, ActiveSupport::Deprecation::DeprecatedConstantProxy.new('klass::OLD', 'Object', deprecator) )
+    assert_difference("deprecator.messages.size") do
+      klass::OLD.to_s
+    end
+  end
+
+  def test_deprecated_instance_variable_with_instance_deprecator
+    deprecator = deprecator_with_messages
+
+    klass = Class.new() do
+      def initialize(deprecator)
+        @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request, :@request, deprecator)
+        @_request = :a_request
+      end
+      def request; @_request end
+      def old_request; @request end
+    end
+
+    assert_difference("deprecator.messages.size") { klass.new(deprecator).old_request.to_s }
+  end
+
+  def test_deprecated_instance_variable_with_given_deprecator
+    deprecator = deprecator_with_messages
+
+    klass = Class.new do
+      define_method(:initialize) do
+        @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request, :@request, deprecator)
+        @_request = :a_request
+      end
+      def request; @_request end
+      def old_request; @request end
+    end
+
+    assert_difference("deprecator.messages.size") { klass.new.old_request.to_s }
+  end
+
+  def test_delegate_deprecator_instance
+    klass = Class.new do
+      attr_reader :last_message
+      delegate :warn, :behavior=, to: ActiveSupport::Deprecation
+
+      def initialize
+        self.behavior = [Proc.new { |message| @last_message = message }]
+      end
+
+      def deprecated_method
+        warn(deprecated_method_warning(:deprecated_method, "You are calling deprecated method"))
+      end
+
+      private
+        def deprecated_method_warning(method_name, message = nil)
+          message || "#{method_name} is deprecated and will be removed from This Library"
+        end
+    end
+
+    object = klass.new
+    object.deprecated_method
+    assert_match(/You are calling deprecated method/, object.last_message)
+  end
+
+  def test_default_gem_name
+    deprecator = ActiveSupport::Deprecation.new
+
+    deprecator.send(:deprecated_method_warning, :deprecated_method, "You are calling deprecated method").tap do |message|
+      assert_match(/is deprecated and will be removed from Rails/, message)
+    end
+  end
+
+  def test_custom_gem_name
+    deprecator = ActiveSupport::Deprecation.new('2.0', 'Custom')
+
+    deprecator.send(:deprecated_method_warning, :deprecated_method, "You are calling deprecated method").tap do |message|
+      assert_match(/is deprecated and will be removed from Custom/, message)
+    end
+  end
+
+  private
+    def deprecator_with_messages
+      klass = Class.new(ActiveSupport::Deprecation)
+      deprecator = klass.new
+      deprecator.behavior = Proc.new{|message, callstack| deprecator.messages << message}
+      def deprecator.messages
+        @messages ||= []
+      end
+      deprecator
+    end
+end
diff --git a/app/server/vendor/activesupport/test/descendants_tracker_test_cases.rb b/app/server/vendor/activesupport/test/descendants_tracker_test_cases.rb
new file mode 100644
index 0000000..69e0469
--- /dev/null
+++ b/app/server/vendor/activesupport/test/descendants_tracker_test_cases.rb
@@ -0,0 +1,65 @@
+require 'set'
+
+module DescendantsTrackerTestCases
+  class Parent
+    extend ActiveSupport::DescendantsTracker
+  end
+
+  class Child1 < Parent
+  end
+
+  class Child2 < Parent
+  end
+
+  class Grandchild1 < Child1
+  end
+
+  class Grandchild2 < Child1
+  end
+
+  ALL = [Parent, Child1, Child2, Grandchild1, Grandchild2]
+
+  def test_descendants
+    assert_equal_sets [Child1, Grandchild1, Grandchild2, Child2], Parent.descendants
+    assert_equal_sets [Grandchild1, Grandchild2], Child1.descendants
+    assert_equal_sets [], Child2.descendants
+  end
+
+  def test_direct_descendants
+    assert_equal_sets [Child1, Child2], Parent.direct_descendants
+    assert_equal_sets [Grandchild1, Grandchild2], Child1.direct_descendants
+    assert_equal_sets [], Child2.direct_descendants
+  end
+
+  def test_clear
+    mark_as_autoloaded(*ALL) do
+      ActiveSupport::DescendantsTracker.clear
+      ALL.each do |k|
+        assert ActiveSupport::DescendantsTracker.descendants(k).empty?
+      end
+    end
+  end
+
+  protected
+
+  def assert_equal_sets(expected, actual)
+    assert_equal Set.new(expected), Set.new(actual)
+  end
+
+  def mark_as_autoloaded(*klasses)
+    # If ActiveSupport::Dependencies is not loaded, forget about autoloading.
+    # This allows using AS::DescendantsTracker without AS::Dependencies.
+    if defined? ActiveSupport::Dependencies
+      old_autoloaded = ActiveSupport::Dependencies.autoloaded_constants.dup
+      ActiveSupport::Dependencies.autoloaded_constants = klasses.map(&:name)
+    end
+
+    old_descendants = ActiveSupport::DescendantsTracker.class_eval("@@direct_descendants").dup
+    old_descendants.each { |k, v| old_descendants[k] = v.dup }
+
+    yield
+  ensure
+    ActiveSupport::Dependencies.autoloaded_constants = old_autoloaded if defined? ActiveSupport::Dependencies
+    ActiveSupport::DescendantsTracker.class_eval("@@direct_descendants").replace(old_descendants)
+  end
+end
diff --git a/app/server/vendor/activesupport/test/descendants_tracker_with_autoloading_test.rb b/app/server/vendor/activesupport/test/descendants_tracker_with_autoloading_test.rb
new file mode 100644
index 0000000..a2ae066
--- /dev/null
+++ b/app/server/vendor/activesupport/test/descendants_tracker_with_autoloading_test.rb
@@ -0,0 +1,34 @@
+require 'abstract_unit'
+require 'active_support/descendants_tracker'
+require 'active_support/dependencies'
+require 'descendants_tracker_test_cases'
+
+class DescendantsTrackerWithAutoloadingTest < ActiveSupport::TestCase
+  include DescendantsTrackerTestCases
+
+  def test_clear_with_autoloaded_parent_children_and_grandchildren
+    mark_as_autoloaded(*ALL) do
+      ActiveSupport::DescendantsTracker.clear
+      ALL.each do |k|
+        assert ActiveSupport::DescendantsTracker.descendants(k).empty?
+      end
+    end
+  end
+
+  def test_clear_with_autoloaded_children_and_grandchildren
+    mark_as_autoloaded Child1, Grandchild1, Grandchild2 do
+      ActiveSupport::DescendantsTracker.clear
+      assert_equal_sets [Child2], Parent.descendants
+      assert_equal_sets [], Child2.descendants
+    end
+  end
+
+  def test_clear_with_autoloaded_grandchildren
+    mark_as_autoloaded Grandchild1, Grandchild2 do
+      ActiveSupport::DescendantsTracker.clear
+      assert_equal_sets [Child1, Child2], Parent.descendants
+      assert_equal_sets [], Child1.descendants
+      assert_equal_sets [], Child2.descendants
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/descendants_tracker_without_autoloading_test.rb b/app/server/vendor/activesupport/test/descendants_tracker_without_autoloading_test.rb
new file mode 100644
index 0000000..00b449a
--- /dev/null
+++ b/app/server/vendor/activesupport/test/descendants_tracker_without_autoloading_test.rb
@@ -0,0 +1,17 @@
+require 'abstract_unit'
+require 'active_support/descendants_tracker'
+require 'descendants_tracker_test_cases'
+
+class DescendantsTrackerWithoutAutoloadingTest < ActiveSupport::TestCase
+  include DescendantsTrackerTestCases
+
+  # Regression test for #8422. https://github.com/rails/rails/issues/8442
+  def test_clear_without_autoloaded_singleton_parent
+    mark_as_autoloaded do
+      parent_instance = Parent.new
+      parent_instance.singleton_class.descendants
+      ActiveSupport::DescendantsTracker.clear
+      assert !ActiveSupport::DescendantsTracker.class_variable_get(:@@direct_descendants).key?(parent_instance.singleton_class)
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/file_update_checker_test.rb b/app/server/vendor/activesupport/test/file_update_checker_test.rb
new file mode 100644
index 0000000..bd1df0f
--- /dev/null
+++ b/app/server/vendor/activesupport/test/file_update_checker_test.rb
@@ -0,0 +1,112 @@
+require 'abstract_unit'
+require 'fileutils'
+require 'thread'
+
+MTIME_FIXTURES_PATH = File.expand_path("../fixtures", __FILE__)
+
+class FileUpdateCheckerWithEnumerableTest < ActiveSupport::TestCase
+  FILES = %w(1.txt 2.txt 3.txt)
+
+  def setup
+    FileUtils.mkdir_p("tmp_watcher")
+    FileUtils.touch(FILES)
+  end
+
+  def teardown
+    FileUtils.rm_rf("tmp_watcher")
+    FileUtils.rm_rf(FILES)
+  end
+
+  def test_should_not_execute_the_block_if_no_paths_are_given
+    i = 0
+    checker = ActiveSupport::FileUpdateChecker.new([]){ i += 1 }
+    checker.execute_if_updated
+    assert_equal 0, i
+  end
+
+  def test_should_not_invoke_the_block_if_no_file_has_changed
+    i = 0
+    checker = ActiveSupport::FileUpdateChecker.new(FILES){ i += 1 }
+    5.times { assert !checker.execute_if_updated }
+    assert_equal 0, i
+  end
+
+  def test_should_invoke_the_block_if_a_file_has_changed
+    i = 0
+    checker = ActiveSupport::FileUpdateChecker.new(FILES){ i += 1 }
+    sleep(1)
+    FileUtils.touch(FILES)
+    assert checker.execute_if_updated
+    assert_equal 1, i
+  end
+
+  def test_should_be_robust_enough_to_handle_deleted_files
+    i = 0
+    checker = ActiveSupport::FileUpdateChecker.new(FILES){ i += 1 }
+    FileUtils.rm(FILES)
+    assert checker.execute_if_updated
+    assert_equal 1, i
+  end
+
+  def test_should_be_robust_to_handle_files_with_wrong_modified_time
+    i = 0
+    now = Time.now
+    time = Time.mktime(now.year + 1, now.month, now.day) # wrong mtime from the future
+    File.utime time, time, FILES[2]
+
+    checker = ActiveSupport::FileUpdateChecker.new(FILES){ i += 1 }
+
+    sleep(1)
+    FileUtils.touch(FILES[0..1])
+
+    assert checker.execute_if_updated
+    assert_equal 1, i
+  end
+
+  def test_should_cache_updated_result_until_execute
+    i = 0
+    checker = ActiveSupport::FileUpdateChecker.new(FILES){ i += 1 }
+    assert !checker.updated?
+
+    sleep(1)
+    FileUtils.touch(FILES)
+
+    assert checker.updated?
+    checker.execute
+    assert !checker.updated?
+  end
+
+  def test_should_invoke_the_block_if_a_watched_dir_changed_its_glob
+    i = 0
+    checker = ActiveSupport::FileUpdateChecker.new([], "tmp_watcher" => [:txt]){ i += 1 }
+    FileUtils.cd "tmp_watcher" do
+      FileUtils.touch(FILES)
+    end
+    assert checker.execute_if_updated
+    assert_equal 1, i
+  end
+
+  def test_should_not_invoke_the_block_if_a_watched_dir_changed_its_glob
+    i = 0
+    checker = ActiveSupport::FileUpdateChecker.new([], "tmp_watcher" => :rb){ i += 1 }
+    FileUtils.cd "tmp_watcher" do
+      FileUtils.touch(FILES)
+    end
+    assert !checker.execute_if_updated
+    assert_equal 0, i
+  end
+
+  def test_should_not_block_if_a_strange_filename_used
+    FileUtils.mkdir_p("tmp_watcher/valid,yetstrange,path,")
+    FileUtils.touch(FILES.map { |file_name| "tmp_watcher/valid,yetstrange,path,/#{file_name}" })
+
+    test = Thread.new do
+      ActiveSupport::FileUpdateChecker.new([],"tmp_watcher/valid,yetstrange,path," => :txt) { i += 1 }
+      Thread.exit
+    end
+    test.priority = -1
+    test.join(5)
+
+    assert !test.alive?
+  end
+end
diff --git a/app/server/vendor/activesupport/test/fixtures/autoload/another_class.rb b/app/server/vendor/activesupport/test/fixtures/autoload/another_class.rb
new file mode 100644
index 0000000..a240b3d
--- /dev/null
+++ b/app/server/vendor/activesupport/test/fixtures/autoload/another_class.rb
@@ -0,0 +1,2 @@
+class Fixtures::AnotherClass
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/fixtures/autoload/some_class.rb b/app/server/vendor/activesupport/test/fixtures/autoload/some_class.rb
new file mode 100644
index 0000000..13b3c73
--- /dev/null
+++ b/app/server/vendor/activesupport/test/fixtures/autoload/some_class.rb
@@ -0,0 +1,2 @@
+class Fixtures::Autoload::SomeClass
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/fixtures/xml/jdom_doctype.dtd b/app/server/vendor/activesupport/test/fixtures/xml/jdom_doctype.dtd
new file mode 100644
index 0000000..8948049
--- /dev/null
+++ b/app/server/vendor/activesupport/test/fixtures/xml/jdom_doctype.dtd
@@ -0,0 +1 @@
+<!ENTITY a "external entity">
diff --git a/app/server/vendor/activesupport/test/fixtures/xml/jdom_entities.txt b/app/server/vendor/activesupport/test/fixtures/xml/jdom_entities.txt
new file mode 100644
index 0000000..0337fda
--- /dev/null
+++ b/app/server/vendor/activesupport/test/fixtures/xml/jdom_entities.txt
@@ -0,0 +1 @@
+<!ENTITY a "hello">
diff --git a/app/server/vendor/activesupport/test/fixtures/xml/jdom_include.txt b/app/server/vendor/activesupport/test/fixtures/xml/jdom_include.txt
new file mode 100644
index 0000000..239ca3a
--- /dev/null
+++ b/app/server/vendor/activesupport/test/fixtures/xml/jdom_include.txt
@@ -0,0 +1 @@
+include me
diff --git a/app/server/vendor/activesupport/test/gzip_test.rb b/app/server/vendor/activesupport/test/gzip_test.rb
new file mode 100644
index 0000000..0e3cf3b
--- /dev/null
+++ b/app/server/vendor/activesupport/test/gzip_test.rb
@@ -0,0 +1,33 @@
+require 'abstract_unit'
+require 'active_support/core_ext/object/blank'
+
+class GzipTest < ActiveSupport::TestCase
+  def test_compress_should_decompress_to_the_same_value
+    assert_equal "Hello World", ActiveSupport::Gzip.decompress(ActiveSupport::Gzip.compress("Hello World"))
+    assert_equal "Hello World", ActiveSupport::Gzip.decompress(ActiveSupport::Gzip.compress("Hello World", Zlib::NO_COMPRESSION))
+    assert_equal "Hello World", ActiveSupport::Gzip.decompress(ActiveSupport::Gzip.compress("Hello World", Zlib::BEST_SPEED))
+    assert_equal "Hello World", ActiveSupport::Gzip.decompress(ActiveSupport::Gzip.compress("Hello World", Zlib::BEST_COMPRESSION))
+    assert_equal "Hello World", ActiveSupport::Gzip.decompress(ActiveSupport::Gzip.compress("Hello World", nil, Zlib::FILTERED))
+    assert_equal "Hello World", ActiveSupport::Gzip.decompress(ActiveSupport::Gzip.compress("Hello World", nil, Zlib::HUFFMAN_ONLY))
+    assert_equal "Hello World", ActiveSupport::Gzip.decompress(ActiveSupport::Gzip.compress("Hello World", nil, nil))
+  end
+
+  def test_compress_should_return_a_binary_string
+    compressed = ActiveSupport::Gzip.compress('')
+
+    assert_equal Encoding.find('binary'), compressed.encoding
+    assert !compressed.blank?, "a compressed blank string should not be blank"
+  end
+
+  def test_compress_should_return_gzipped_string_by_compression_level
+    source_string = "Hello World"*100
+
+    gzipped_by_speed = ActiveSupport::Gzip.compress(source_string, Zlib::BEST_SPEED)
+    assert_equal 1, Zlib::GzipReader.new(StringIO.new(gzipped_by_speed)).level
+
+    gzipped_by_best_compression = ActiveSupport::Gzip.compress(source_string, Zlib::BEST_COMPRESSION)
+    assert_equal 9, Zlib::GzipReader.new(StringIO.new(gzipped_by_best_compression)).level
+
+    assert_equal true, (gzipped_by_best_compression.bytesize < gzipped_by_speed.bytesize)
+  end
+end
diff --git a/app/server/vendor/activesupport/test/i18n_test.rb b/app/server/vendor/activesupport/test/i18n_test.rb
new file mode 100644
index 0000000..5ef59b6
--- /dev/null
+++ b/app/server/vendor/activesupport/test/i18n_test.rb
@@ -0,0 +1,105 @@
+require 'abstract_unit'
+require 'active_support/time'
+require 'active_support/core_ext/array/conversions'
+
+class I18nTest < ActiveSupport::TestCase
+  def setup
+    @date = Date.parse("2008-7-2")
+    @time = Time.utc(2008, 7, 2, 16, 47, 1)
+  end
+
+  def test_time_zone_localization_with_default_format
+    now = Time.local(2000)
+    assert_equal now.strftime("%a, %d %b %Y %H:%M:%S %z"), I18n.localize(now)
+  end
+
+  def test_date_localization_should_use_default_format
+    assert_equal @date.strftime("%Y-%m-%d"), I18n.localize(@date)
+  end
+
+  def test_date_localization_with_default_format
+    assert_equal @date.strftime("%Y-%m-%d"), I18n.localize(@date, :format => :default)
+  end
+
+  def test_date_localization_with_short_format
+    assert_equal @date.strftime("%b %d"), I18n.localize(@date, :format => :short)
+  end
+
+  def test_date_localization_with_long_format
+    assert_equal @date.strftime("%B %d, %Y"), I18n.localize(@date, :format => :long)
+  end
+
+  def test_time_localization_should_use_default_format
+    assert_equal @time.strftime("%a, %d %b %Y %H:%M:%S %z"), I18n.localize(@time)
+  end
+
+  def test_time_localization_with_default_format
+    assert_equal @time.strftime("%a, %d %b %Y %H:%M:%S %z"), I18n.localize(@time, :format => :default)
+  end
+
+  def test_time_localization_with_short_format
+    assert_equal @time.strftime("%d %b %H:%M"), I18n.localize(@time, :format => :short)
+  end
+
+  def test_time_localization_with_long_format
+    assert_equal @time.strftime("%B %d, %Y %H:%M"), I18n.localize(@time, :format => :long)
+  end
+
+  def test_day_names
+    assert_equal Date::DAYNAMES, I18n.translate(:'date.day_names')
+  end
+
+  def test_abbr_day_names
+    assert_equal Date::ABBR_DAYNAMES, I18n.translate(:'date.abbr_day_names')
+  end
+
+  def test_month_names
+    assert_equal Date::MONTHNAMES, I18n.translate(:'date.month_names')
+  end
+
+  def test_abbr_month_names
+    assert_equal Date::ABBR_MONTHNAMES, I18n.translate(:'date.abbr_month_names')
+  end
+
+  def test_date_order
+    assert_equal %w(year month day), I18n.translate(:'date.order')
+  end
+
+  def test_time_am
+    assert_equal 'am', I18n.translate(:'time.am')
+  end
+
+  def test_time_pm
+    assert_equal 'pm', I18n.translate(:'time.pm')
+  end
+
+  def test_words_connector
+    assert_equal ', ', I18n.translate(:'support.array.words_connector')
+  end
+
+  def test_two_words_connector
+    assert_equal ' and ', I18n.translate(:'support.array.two_words_connector')
+  end
+
+  def test_last_word_connector
+    assert_equal ', and ', I18n.translate(:'support.array.last_word_connector')
+  end
+
+  def test_to_sentence
+    default_two_words_connector = I18n.translate(:'support.array.two_words_connector')
+    default_last_word_connector = I18n.translate(:'support.array.last_word_connector')
+    assert_equal 'a, b, and c', %w[a b c].to_sentence
+    I18n.backend.store_translations 'en', :support => { :array => { :two_words_connector => ' & ' } }
+    assert_equal 'a & b', %w[a b].to_sentence
+    I18n.backend.store_translations 'en', :support => { :array => { :last_word_connector => ' and ' } }
+    assert_equal 'a, b and c', %w[a b c].to_sentence
+  ensure
+    I18n.backend.store_translations 'en', :support => { :array => { :two_words_connector => default_two_words_connector } }
+    I18n.backend.store_translations 'en', :support => { :array => { :last_word_connector => default_last_word_connector } }
+  end
+
+  def test_to_sentence_with_empty_i18n_store
+    I18n.backend.store_translations 'empty', {}
+    assert_equal 'a, b, and c', %w[a b c].to_sentence(locale: 'empty')
+  end
+end
diff --git a/app/server/vendor/activesupport/test/inflector_test.rb b/app/server/vendor/activesupport/test/inflector_test.rb
new file mode 100644
index 0000000..35967ba
--- /dev/null
+++ b/app/server/vendor/activesupport/test/inflector_test.rb
@@ -0,0 +1,523 @@
+require 'abstract_unit'
+require 'active_support/inflector'
+
+require 'inflector_test_cases'
+require 'constantize_test_cases'
+
+class InflectorTest < ActiveSupport::TestCase
+  include InflectorTestCases
+  include ConstantizeTestCases
+
+  def test_pluralize_plurals
+    assert_equal "plurals", ActiveSupport::Inflector.pluralize("plurals")
+    assert_equal "Plurals", ActiveSupport::Inflector.pluralize("Plurals")
+  end
+
+  def test_pluralize_empty_string
+    assert_equal "", ActiveSupport::Inflector.pluralize("")
+  end
+
+  ActiveSupport::Inflector.inflections.uncountable.each do |word|
+    define_method "test_uncountability_of_#{word}" do
+      assert_equal word, ActiveSupport::Inflector.singularize(word)
+      assert_equal word, ActiveSupport::Inflector.pluralize(word)
+      assert_equal ActiveSupport::Inflector.pluralize(word), ActiveSupport::Inflector.singularize(word)
+    end
+  end
+
+  def test_uncountable_word_is_not_greedy
+    with_dup do
+      uncountable_word = "ors"
+      countable_word = "sponsor"
+
+      ActiveSupport::Inflector.inflections.uncountable << uncountable_word
+
+      assert_equal uncountable_word, ActiveSupport::Inflector.singularize(uncountable_word)
+      assert_equal uncountable_word, ActiveSupport::Inflector.pluralize(uncountable_word)
+      assert_equal ActiveSupport::Inflector.pluralize(uncountable_word), ActiveSupport::Inflector.singularize(uncountable_word)
+
+      assert_equal "sponsor", ActiveSupport::Inflector.singularize(countable_word)
+      assert_equal "sponsors", ActiveSupport::Inflector.pluralize(countable_word)
+      assert_equal "sponsor", ActiveSupport::Inflector.singularize(ActiveSupport::Inflector.pluralize(countable_word))
+    end
+  end
+
+  SingularToPlural.each do |singular, plural|
+    define_method "test_pluralize_singular_#{singular}" do
+      assert_equal(plural, ActiveSupport::Inflector.pluralize(singular))
+      assert_equal(plural.capitalize, ActiveSupport::Inflector.pluralize(singular.capitalize))
+    end
+  end
+
+  SingularToPlural.each do |singular, plural|
+    define_method "test_singularize_plural_#{plural}" do
+      assert_equal(singular, ActiveSupport::Inflector.singularize(plural))
+      assert_equal(singular.capitalize, ActiveSupport::Inflector.singularize(plural.capitalize))
+    end
+  end
+
+  SingularToPlural.each do |singular, plural|
+    define_method "test_pluralize_plural_#{plural}" do
+      assert_equal(plural, ActiveSupport::Inflector.pluralize(plural))
+      assert_equal(plural.capitalize, ActiveSupport::Inflector.pluralize(plural.capitalize))
+    end
+
+    define_method "test_singularize_singular_#{singular}" do
+      assert_equal(singular, ActiveSupport::Inflector.singularize(singular))
+      assert_equal(singular.capitalize, ActiveSupport::Inflector.singularize(singular.capitalize))
+    end
+  end
+
+
+  def test_overwrite_previous_inflectors
+    with_dup do
+      assert_equal("series", ActiveSupport::Inflector.singularize("series"))
+      ActiveSupport::Inflector.inflections.singular "series", "serie"
+      assert_equal("serie", ActiveSupport::Inflector.singularize("series"))
+    end
+  end
+
+  MixtureToTitleCase.each_with_index do |(before, titleized), index|
+    define_method "test_titleize_mixture_to_title_case_#{index}" do
+      assert_equal(titleized, ActiveSupport::Inflector.titleize(before), "mixture \
+        to TitleCase failed for #{before}")
+    end
+  end
+
+  def test_camelize
+    CamelToUnderscore.each do |camel, underscore|
+      assert_equal(camel, ActiveSupport::Inflector.camelize(underscore))
+    end
+  end
+
+  def test_camelize_with_lower_downcases_the_first_letter
+    assert_equal('capital', ActiveSupport::Inflector.camelize('Capital', false))
+  end
+
+  def test_camelize_with_underscores
+    assert_equal("CamelCase", ActiveSupport::Inflector.camelize('Camel_Case'))
+  end
+
+  def test_acronyms
+    ActiveSupport::Inflector.inflections do |inflect|
+      inflect.acronym("API")
+      inflect.acronym("HTML")
+      inflect.acronym("HTTP")
+      inflect.acronym("RESTful")
+      inflect.acronym("W3C")
+      inflect.acronym("PhD")
+      inflect.acronym("RoR")
+      inflect.acronym("SSL")
+    end
+
+    #  camelize             underscore            humanize              titleize
+    [
+      ["API",               "api",                "API",                "API"],
+      ["APIController",     "api_controller",     "API controller",     "API Controller"],
+      ["Nokogiri::HTML",    "nokogiri/html",      "Nokogiri/HTML",      "Nokogiri/HTML"],
+      ["HTTPAPI",           "http_api",           "HTTP API",           "HTTP API"],
+      ["HTTP::Get",         "http/get",           "HTTP/get",           "HTTP/Get"],
+      ["SSLError",          "ssl_error",          "SSL error",          "SSL Error"],
+      ["RESTful",           "restful",            "RESTful",            "RESTful"],
+      ["RESTfulController", "restful_controller", "RESTful controller", "RESTful Controller"],
+      ["IHeartW3C",         "i_heart_w3c",        "I heart W3C",        "I Heart W3C"],
+      ["PhDRequired",       "phd_required",       "PhD required",       "PhD Required"],
+      ["IRoRU",             "i_ror_u",            "I RoR u",            "I RoR U"],
+      ["RESTfulHTTPAPI",    "restful_http_api",   "RESTful HTTP API",   "RESTful HTTP API"],
+
+      # misdirection
+      ["Capistrano",        "capistrano",         "Capistrano",       "Capistrano"],
+      ["CapiController",    "capi_controller",    "Capi controller",  "Capi Controller"],
+      ["HttpsApis",         "https_apis",         "Https apis",       "Https Apis"],
+      ["Html5",             "html5",              "Html5",            "Html5"],
+      ["Restfully",         "restfully",          "Restfully",        "Restfully"],
+      ["RoRails",           "ro_rails",           "Ro rails",         "Ro Rails"]
+    ].each do |camel, under, human, title|
+      assert_equal(camel, ActiveSupport::Inflector.camelize(under))
+      assert_equal(camel, ActiveSupport::Inflector.camelize(camel))
+      assert_equal(under, ActiveSupport::Inflector.underscore(under))
+      assert_equal(under, ActiveSupport::Inflector.underscore(camel))
+      assert_equal(title, ActiveSupport::Inflector.titleize(under))
+      assert_equal(title, ActiveSupport::Inflector.titleize(camel))
+      assert_equal(human, ActiveSupport::Inflector.humanize(under))
+    end
+  end
+
+  def test_acronym_override
+    ActiveSupport::Inflector.inflections do |inflect|
+      inflect.acronym("API")
+      inflect.acronym("LegacyApi")
+    end
+
+    assert_equal("LegacyApi", ActiveSupport::Inflector.camelize("legacyapi"))
+    assert_equal("LegacyAPI", ActiveSupport::Inflector.camelize("legacy_api"))
+    assert_equal("SomeLegacyApi", ActiveSupport::Inflector.camelize("some_legacyapi"))
+    assert_equal("Nonlegacyapi", ActiveSupport::Inflector.camelize("nonlegacyapi"))
+  end
+
+  def test_acronyms_camelize_lower
+    ActiveSupport::Inflector.inflections do |inflect|
+      inflect.acronym("API")
+      inflect.acronym("HTML")
+    end
+
+    assert_equal("htmlAPI", ActiveSupport::Inflector.camelize("html_api", false))
+    assert_equal("htmlAPI", ActiveSupport::Inflector.camelize("htmlAPI", false))
+    assert_equal("htmlAPI", ActiveSupport::Inflector.camelize("HTMLAPI", false))
+  end
+
+  def test_underscore_acronym_sequence
+    ActiveSupport::Inflector.inflections do |inflect|
+      inflect.acronym("API")
+      inflect.acronym("JSON")
+      inflect.acronym("HTML")
+    end
+
+    assert_equal("json_html_api", ActiveSupport::Inflector.underscore("JSONHTMLAPI"))
+  end
+
+  def test_underscore
+    CamelToUnderscore.each do |camel, underscore|
+      assert_equal(underscore, ActiveSupport::Inflector.underscore(camel))
+    end
+    CamelToUnderscoreWithoutReverse.each do |camel, underscore|
+      assert_equal(underscore, ActiveSupport::Inflector.underscore(camel))
+    end
+  end
+
+  def test_camelize_with_module
+    CamelWithModuleToUnderscoreWithSlash.each do |camel, underscore|
+      assert_equal(camel, ActiveSupport::Inflector.camelize(underscore))
+    end
+  end
+
+  def test_underscore_with_slashes
+    CamelWithModuleToUnderscoreWithSlash.each do |camel, underscore|
+      assert_equal(underscore, ActiveSupport::Inflector.underscore(camel))
+    end
+  end
+
+  def test_demodulize
+    assert_equal "Account", ActiveSupport::Inflector.demodulize("MyApplication::Billing::Account")
+    assert_equal "Account", ActiveSupport::Inflector.demodulize("Account")
+    assert_equal "", ActiveSupport::Inflector.demodulize("")
+  end
+
+  def test_deconstantize
+    assert_equal "MyApplication::Billing", ActiveSupport::Inflector.deconstantize("MyApplication::Billing::Account")
+    assert_equal "::MyApplication::Billing", ActiveSupport::Inflector.deconstantize("::MyApplication::Billing::Account")
+
+    assert_equal "MyApplication", ActiveSupport::Inflector.deconstantize("MyApplication::Billing")
+    assert_equal "::MyApplication", ActiveSupport::Inflector.deconstantize("::MyApplication::Billing")
+
+    assert_equal "", ActiveSupport::Inflector.deconstantize("Account")
+    assert_equal "", ActiveSupport::Inflector.deconstantize("::Account")
+    assert_equal "", ActiveSupport::Inflector.deconstantize("")
+  end
+
+  def test_foreign_key
+    ClassNameToForeignKeyWithUnderscore.each do |klass, foreign_key|
+      assert_equal(foreign_key, ActiveSupport::Inflector.foreign_key(klass))
+    end
+
+    ClassNameToForeignKeyWithoutUnderscore.each do |klass, foreign_key|
+      assert_equal(foreign_key, ActiveSupport::Inflector.foreign_key(klass, false))
+    end
+  end
+
+  def test_tableize
+    ClassNameToTableName.each do |class_name, table_name|
+      assert_equal(table_name, ActiveSupport::Inflector.tableize(class_name))
+    end
+  end
+
+# FIXME: get following tests to pass on jruby, currently skipped
+#
+# Currently this fails because ActiveSupport::Multibyte::Unicode#tidy_bytes
+# required a specific Encoding::Converter(UTF-8 to UTF8-MAC) which unavailable on JRuby
+# causing our tests to error out.
+# related bug http://jira.codehaus.org/browse/JRUBY-7194
+  def test_parameterize
+    jruby_skip "UTF-8 to UTF8-MAC Converter is unavailable"
+    StringToParameterized.each do |some_string, parameterized_string|
+      assert_equal(parameterized_string, ActiveSupport::Inflector.parameterize(some_string))
+    end
+  end
+
+  def test_parameterize_and_normalize
+    jruby_skip "UTF-8 to UTF8-MAC Converter is unavailable"
+    StringToParameterizedAndNormalized.each do |some_string, parameterized_string|
+      assert_equal(parameterized_string, ActiveSupport::Inflector.parameterize(some_string))
+    end
+  end
+
+  def test_parameterize_with_custom_separator
+    jruby_skip "UTF-8 to UTF8-MAC Converter is unavailable"
+    StringToParameterizeWithUnderscore.each do |some_string, parameterized_string|
+      assert_equal(parameterized_string, ActiveSupport::Inflector.parameterize(some_string, '_'))
+    end
+  end
+
+  def test_parameterize_with_multi_character_separator
+    jruby_skip "UTF-8 to UTF8-MAC Converter is unavailable"
+    StringToParameterized.each do |some_string, parameterized_string|
+      assert_equal(parameterized_string.gsub('-', '__sep__'), ActiveSupport::Inflector.parameterize(some_string, '__sep__'))
+    end
+  end
+
+  def test_classify
+    ClassNameToTableName.each do |class_name, table_name|
+      assert_equal(class_name, ActiveSupport::Inflector.classify(table_name))
+      assert_equal(class_name, ActiveSupport::Inflector.classify("table_prefix." + table_name))
+    end
+  end
+
+  def test_classify_with_symbol
+    assert_nothing_raised do
+      assert_equal 'FooBar', ActiveSupport::Inflector.classify(:foo_bars)
+    end
+  end
+
+  def test_classify_with_leading_schema_name
+    assert_equal 'FooBar', ActiveSupport::Inflector.classify('schema.foo_bar')
+  end
+
+  def test_humanize
+    UnderscoreToHuman.each do |underscore, human|
+      assert_equal(human, ActiveSupport::Inflector.humanize(underscore))
+    end
+  end
+
+  def test_humanize_without_capitalize
+    UnderscoreToHumanWithoutCapitalize.each do |underscore, human|
+      assert_equal(human, ActiveSupport::Inflector.humanize(underscore, capitalize: false))
+    end
+  end
+
+  def test_humanize_by_rule
+    ActiveSupport::Inflector.inflections do |inflect|
+      inflect.human(/_cnt$/i, '\1_count')
+      inflect.human(/^prefx_/i, '\1')
+    end
+    assert_equal("Jargon count", ActiveSupport::Inflector.humanize("jargon_cnt"))
+    assert_equal("Request", ActiveSupport::Inflector.humanize("prefx_request"))
+  end
+
+  def test_humanize_by_string
+    ActiveSupport::Inflector.inflections do |inflect|
+      inflect.human("col_rpted_bugs", "Reported bugs")
+    end
+    assert_equal("Reported bugs", ActiveSupport::Inflector.humanize("col_rpted_bugs"))
+    assert_equal("Col rpted bugs", ActiveSupport::Inflector.humanize("COL_rpted_bugs"))
+  end
+
+  def test_constantize
+    run_constantize_tests_on do |string|
+      ActiveSupport::Inflector.constantize(string)
+    end
+  end
+
+  def test_safe_constantize
+    run_safe_constantize_tests_on do |string|
+      ActiveSupport::Inflector.safe_constantize(string)
+    end
+  end
+
+  def test_ordinal
+    OrdinalNumbers.each do |number, ordinalized|
+      assert_equal(ordinalized, number + ActiveSupport::Inflector.ordinal(number))
+    end
+  end
+
+  def test_ordinalize
+    OrdinalNumbers.each do |number, ordinalized|
+      assert_equal(ordinalized, ActiveSupport::Inflector.ordinalize(number))
+    end
+  end
+
+  def test_dasherize
+    UnderscoresToDashes.each do |underscored, dasherized|
+      assert_equal(dasherized, ActiveSupport::Inflector.dasherize(underscored))
+    end
+  end
+
+  def test_underscore_as_reverse_of_dasherize
+    UnderscoresToDashes.each_key do |underscored|
+      assert_equal(underscored, ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.dasherize(underscored)))
+    end
+  end
+
+  def test_underscore_to_lower_camel
+    UnderscoreToLowerCamel.each do |underscored, lower_camel|
+      assert_equal(lower_camel, ActiveSupport::Inflector.camelize(underscored, false))
+    end
+  end
+
+  def test_symbol_to_lower_camel
+    SymbolToLowerCamel.each do |symbol, lower_camel|
+      assert_equal(lower_camel, ActiveSupport::Inflector.camelize(symbol, false))
+    end
+  end
+
+  %w{plurals singulars uncountables humans}.each do |inflection_type|
+    class_eval <<-RUBY, __FILE__, __LINE__ + 1
+      def test_clear_#{inflection_type}
+        with_dup do
+          ActiveSupport::Inflector.inflections.clear :#{inflection_type}
+          assert ActiveSupport::Inflector.inflections.#{inflection_type}.empty?, \"#{inflection_type} inflections should be empty after clear :#{inflection_type}\"
+        end
+      end
+    RUBY
+  end
+
+  def test_inflector_locality
+    ActiveSupport::Inflector.inflections(:es) do |inflect|
+      inflect.plural(/$/, 's')
+      inflect.plural(/z$/i, 'ces')
+
+      inflect.singular(/s$/, '')
+      inflect.singular(/es$/, '')
+
+      inflect.irregular('el', 'los')
+    end
+
+    assert_equal('hijos', 'hijo'.pluralize(:es))
+    assert_equal('luces', 'luz'.pluralize(:es))
+    assert_equal('luzs', 'luz'.pluralize)
+
+    assert_equal('sociedad', 'sociedades'.singularize(:es))
+    assert_equal('sociedade', 'sociedades'.singularize)
+
+    assert_equal('los', 'el'.pluralize(:es))
+    assert_equal('els', 'el'.pluralize)
+
+    ActiveSupport::Inflector.inflections(:es) { |inflect| inflect.clear }
+
+    assert ActiveSupport::Inflector.inflections(:es).plurals.empty?
+    assert ActiveSupport::Inflector.inflections(:es).singulars.empty?
+    assert !ActiveSupport::Inflector.inflections.plurals.empty?
+    assert !ActiveSupport::Inflector.inflections.singulars.empty?
+  end
+
+  def test_clear_all
+    with_dup do
+      ActiveSupport::Inflector.inflections do |inflect|
+        # ensure any data is present
+        inflect.plural(/(quiz)$/i, '\1zes')
+        inflect.singular(/(database)s$/i, '\1')
+        inflect.uncountable('series')
+        inflect.human("col_rpted_bugs", "Reported bugs")
+
+        inflect.clear :all
+
+        assert inflect.plurals.empty?
+        assert inflect.singulars.empty?
+        assert inflect.uncountables.empty?
+        assert inflect.humans.empty?
+      end
+    end
+  end
+
+  def test_clear_with_default
+    with_dup do
+      ActiveSupport::Inflector.inflections do |inflect|
+        # ensure any data is present
+        inflect.plural(/(quiz)$/i, '\1zes')
+        inflect.singular(/(database)s$/i, '\1')
+        inflect.uncountable('series')
+        inflect.human("col_rpted_bugs", "Reported bugs")
+
+        inflect.clear
+
+        assert inflect.plurals.empty?
+        assert inflect.singulars.empty?
+        assert inflect.uncountables.empty?
+        assert inflect.humans.empty?
+      end
+    end
+  end
+
+  Irregularities.each do |singular, plural|
+    define_method("test_irregularity_between_#{singular}_and_#{plural}") do
+      with_dup do
+        ActiveSupport::Inflector.inflections do |inflect|
+          inflect.irregular(singular, plural)
+          assert_equal singular, ActiveSupport::Inflector.singularize(plural)
+          assert_equal plural, ActiveSupport::Inflector.pluralize(singular)
+        end
+      end
+    end
+  end
+
+  Irregularities.each do |singular, plural|
+    define_method("test_pluralize_of_irregularity_#{plural}_should_be_the_same") do
+      with_dup do
+        ActiveSupport::Inflector.inflections do |inflect|
+          inflect.irregular(singular, plural)
+          assert_equal plural, ActiveSupport::Inflector.pluralize(plural)
+        end
+      end
+    end
+  end
+
+  Irregularities.each do |singular, plural|
+    define_method("test_singularize_of_irregularity_#{singular}_should_be_the_same") do
+      with_dup do
+        ActiveSupport::Inflector.inflections do |inflect|
+          inflect.irregular(singular, plural)
+          assert_equal singular, ActiveSupport::Inflector.singularize(singular)
+        end
+      end
+    end
+  end
+
+  [ :all, [] ].each do |scope|
+    ActiveSupport::Inflector.inflections do |inflect|
+      define_method("test_clear_inflections_with_#{scope.kind_of?(Array) ? "no_arguments" : scope}") do
+        # save all the inflections
+        singulars, plurals, uncountables = inflect.singulars, inflect.plurals, inflect.uncountables
+
+        # clear all the inflections
+        inflect.clear(*scope)
+
+        assert_equal [], inflect.singulars
+        assert_equal [], inflect.plurals
+        assert_equal [], inflect.uncountables
+
+        # restore all the inflections
+        singulars.reverse.each { |singular| inflect.singular(*singular) }
+        plurals.reverse.each   { |plural|   inflect.plural(*plural) }
+        inflect.uncountable(uncountables)
+
+        assert_equal singulars, inflect.singulars
+        assert_equal plurals, inflect.plurals
+        assert_equal uncountables, inflect.uncountables
+      end
+    end
+  end
+
+  %w(plurals singulars uncountables humans acronyms).each do |scope|
+    ActiveSupport::Inflector.inflections do |inflect|
+      define_method("test_clear_inflections_with_#{scope}") do
+        with_dup do
+          # clear the inflections
+          inflect.clear(scope)
+          assert_equal [], inflect.send(scope)
+        end
+      end
+    end
+  end
+
+  # Dups the singleton and yields, restoring the original inflections later.
+  # Use this in tests what modify the state of the singleton.
+  #
+  # This helper is implemented by setting @__instance__ because in some tests
+  # there are module functions that access ActiveSupport::Inflector.inflections,
+  # so we need to replace the singleton itself.
+  def with_dup
+    original = ActiveSupport::Inflector::Inflections.instance_variable_get(:@__instance__)
+    ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, original.dup)
+  ensure
+    ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, original)
+  end
+end
diff --git a/app/server/vendor/activesupport/test/inflector_test_cases.rb b/app/server/vendor/activesupport/test/inflector_test_cases.rb
new file mode 100644
index 0000000..dd03a61
--- /dev/null
+++ b/app/server/vendor/activesupport/test/inflector_test_cases.rb
@@ -0,0 +1,321 @@
+# encoding: utf-8
+
+module InflectorTestCases
+  SingularToPlural = {
+    "search"      => "searches",
+    "switch"      => "switches",
+    "fix"         => "fixes",
+    "box"         => "boxes",
+    "process"     => "processes",
+    "address"     => "addresses",
+    "case"        => "cases",
+    "stack"       => "stacks",
+    "wish"        => "wishes",
+    "fish"        => "fish",
+    "jeans"       => "jeans",
+    "funky jeans" => "funky jeans",
+    "my money"    => "my money",
+
+    "category"    => "categories",
+    "query"       => "queries",
+    "ability"     => "abilities",
+    "agency"      => "agencies",
+    "movie"       => "movies",
+
+    "archive"     => "archives",
+
+    "index"       => "indices",
+
+    "wife"        => "wives",
+    "safe"        => "saves",
+    "half"        => "halves",
+
+    "move"        => "moves",
+
+    "salesperson" => "salespeople",
+    "person"      => "people",
+
+    "spokesman"   => "spokesmen",
+    "man"         => "men",
+    "woman"       => "women",
+
+    "basis"       => "bases",
+    "diagnosis"   => "diagnoses",
+    "diagnosis_a" => "diagnosis_as",
+
+    "datum"       => "data",
+    "medium"      => "media",
+    "stadium"     => "stadia",
+    "analysis"    => "analyses",
+    "my_analysis" => "my_analyses",
+
+    "node_child"  => "node_children",
+    "child"       => "children",
+
+    "experience"  => "experiences",
+    "day"         => "days",
+
+    "comment"     => "comments",
+    "foobar"      => "foobars",
+    "newsletter"  => "newsletters",
+
+    "old_news"    => "old_news",
+    "news"        => "news",
+
+    "series"      => "series",
+    "miniseries"  => "miniseries",
+    "species"     => "species",
+
+    "quiz"        => "quizzes",
+
+    "perspective" => "perspectives",
+
+    "ox"          => "oxen",
+    "photo"       => "photos",
+    "buffalo"     => "buffaloes",
+    "tomato"      => "tomatoes",
+    "dwarf"       => "dwarves",
+    "elf"         => "elves",
+    "information" => "information",
+    "equipment"   => "equipment",
+    "bus"         => "buses",
+    "status"      => "statuses",
+    "status_code" => "status_codes",
+    "mouse"       => "mice",
+
+    "louse"       => "lice",
+    "house"       => "houses",
+    "octopus"     => "octopi",
+    "virus"       => "viri",
+    "alias"       => "aliases",
+    "portfolio"   => "portfolios",
+
+    "vertex"      => "vertices",
+    "matrix"      => "matrices",
+    "matrix_fu"   => "matrix_fus",
+
+    "axis"        => "axes",
+    "taxi"        => "taxis", # prevents regression
+    "testis"      => "testes",
+    "crisis"      => "crises",
+
+    "rice"        => "rice",
+    "shoe"        => "shoes",
+
+    "horse"       => "horses",
+    "prize"       => "prizes",
+    "edge"        => "edges",
+
+    "database"    => "databases",
+
+    # regression tests against improper inflection regexes
+    "|ice"        => "|ices",
+    "|ouse"       => "|ouses",
+    "slice"       => "slices",
+    "police"      => "police"
+  }
+
+  CamelToUnderscore = {
+    "Product"               => "product",
+    "SpecialGuest"          => "special_guest",
+    "ApplicationController" => "application_controller",
+    "Area51Controller"      => "area51_controller"
+  }
+
+  UnderscoreToLowerCamel = {
+    "product"                => "product",
+    "special_guest"          => "specialGuest",
+    "application_controller" => "applicationController",
+    "area51_controller"      => "area51Controller"
+  }
+
+  SymbolToLowerCamel = {
+    :product                => 'product',
+    :special_guest          => 'specialGuest',
+    :application_controller => 'applicationController',
+    :area51_controller      => 'area51Controller'
+  }
+
+  CamelToUnderscoreWithoutReverse = {
+    "HTMLTidy"              => "html_tidy",
+    "HTMLTidyGenerator"     => "html_tidy_generator",
+    "FreeBSD"               => "free_bsd",
+    "HTML"                  => "html",
+  }
+
+  CamelWithModuleToUnderscoreWithSlash = {
+    "Admin::Product" => "admin/product",
+    "Users::Commission::Department" => "users/commission/department",
+    "UsersSection::CommissionDepartment" => "users_section/commission_department",
+  }
+
+  ClassNameToForeignKeyWithUnderscore = {
+    "Person" => "person_id",
+    "MyApplication::Billing::Account" => "account_id"
+  }
+
+  ClassNameToForeignKeyWithoutUnderscore = {
+    "Person" => "personid",
+    "MyApplication::Billing::Account" => "accountid"
+  }
+
+  ClassNameToTableName = {
+    "PrimarySpokesman" => "primary_spokesmen",
+    "NodeChild"        => "node_children"
+  }
+
+  StringToParameterized = {
+    "Donald E. Knuth"                     => "donald-e-knuth",
+    "Random text with *(bad)* characters" => "random-text-with-bad-characters",
+    "Allow_Under_Scores"                  => "allow_under_scores",
+    "Trailing bad characters!@#"          => "trailing-bad-characters",
+    "!@#Leading bad characters"           => "leading-bad-characters",
+    "Squeeze   separators"                => "squeeze-separators",
+    "Test with + sign"                    => "test-with-sign",
+    "Test with malformed utf8 \251"       => "test-with-malformed-utf8"
+  }
+
+  StringToParameterizeWithNoSeparator = {
+    "Donald E. Knuth"                     => "donaldeknuth",
+    "With-some-dashes"                    => "with-some-dashes",
+    "Random text with *(bad)* characters" => "randomtextwithbadcharacters",
+    "Trailing bad characters!@#"          => "trailingbadcharacters",
+    "!@#Leading bad characters"           => "leadingbadcharacters",
+    "Squeeze   separators"                => "squeezeseparators",
+    "Test with + sign"                    => "testwithsign",
+    "Test with malformed utf8 \251"       => "testwithmalformedutf8"
+  }
+
+  StringToParameterizeWithUnderscore = {
+    "Donald E. Knuth"                     => "donald_e_knuth",
+    "Random text with *(bad)* characters" => "random_text_with_bad_characters",
+    "With-some-dashes"                    => "with-some-dashes",
+    "Retain_underscore"                   => "retain_underscore",
+    "Trailing bad characters!@#"          => "trailing_bad_characters",
+    "!@#Leading bad characters"           => "leading_bad_characters",
+    "Squeeze   separators"                => "squeeze_separators",
+    "Test with + sign"                    => "test_with_sign",
+    "Test with malformed utf8 \251"       => "test_with_malformed_utf8"
+  }
+
+  StringToParameterizedAndNormalized = {
+    "Malmö"                               => "malmo",
+    "Garçons"                             => "garcons",
+    "Ops\331"                             => "opsu",
+    "Ærøskøbing"                          => "aeroskobing",
+    "Aßlar"                               => "asslar",
+    "Japanese: 日本語"                    => "japanese"
+  }
+
+  UnderscoreToHuman = {
+    "employee_salary" => "Employee salary",
+    "employee_id"     => "Employee",
+    "underground"     => "Underground"
+  }
+
+  UnderscoreToHumanWithoutCapitalize = {
+    "employee_salary" => "employee salary",
+    "employee_id"     => "employee",
+    "underground"     => "underground"
+  }
+
+  MixtureToTitleCase = {
+    'active_record'         => 'Active Record',
+    'ActiveRecord'          => 'Active Record',
+    'action web service'    => 'Action Web Service',
+    'Action Web Service'    => 'Action Web Service',
+    'Action web service'    => 'Action Web Service',
+    'actionwebservice'      => 'Actionwebservice',
+    'Actionwebservice'      => 'Actionwebservice',
+    "david's code"          => "David's Code",
+    "David's code"          => "David's Code",
+    "david's Code"          => "David's Code",
+    "sgt. pepper's"         => "Sgt. Pepper's",
+    "i've just seen a face" => "I've Just Seen A Face",
+    "maybe you'll be there" => "Maybe You'll Be There",
+    "¿por qué?"             => '¿Por Qué?',
+    "Fred’s"                => "Fred’s",
+    "Fred`s"                => "Fred`s"
+  }
+
+  OrdinalNumbers = {
+    "-1" => "-1st",
+    "-2" => "-2nd",
+    "-3" => "-3rd",
+    "-4" => "-4th",
+    "-5" => "-5th",
+    "-6" => "-6th",
+    "-7" => "-7th",
+    "-8" => "-8th",
+    "-9" => "-9th",
+    "-10" => "-10th",
+    "-11" => "-11th",
+    "-12" => "-12th",
+    "-13" => "-13th",
+    "-14" => "-14th",
+    "-20" => "-20th",
+    "-21" => "-21st",
+    "-22" => "-22nd",
+    "-23" => "-23rd",
+    "-24" => "-24th",
+    "-100" => "-100th",
+    "-101" => "-101st",
+    "-102" => "-102nd",
+    "-103" => "-103rd",
+    "-104" => "-104th",
+    "-110" => "-110th",
+    "-111" => "-111th",
+    "-112" => "-112th",
+    "-113" => "-113th",
+    "-1000" => "-1000th",
+    "-1001" => "-1001st",
+    "0" => "0th",
+    "1" => "1st",
+    "2" => "2nd",
+    "3" => "3rd",
+    "4" => "4th",
+    "5" => "5th",
+    "6" => "6th",
+    "7" => "7th",
+    "8" => "8th",
+    "9" => "9th",
+    "10" => "10th",
+    "11" => "11th",
+    "12" => "12th",
+    "13" => "13th",
+    "14" => "14th",
+    "20" => "20th",
+    "21" => "21st",
+    "22" => "22nd",
+    "23" => "23rd",
+    "24" => "24th",
+    "100" => "100th",
+    "101" => "101st",
+    "102" => "102nd",
+    "103" => "103rd",
+    "104" => "104th",
+    "110" => "110th",
+    "111" => "111th",
+    "112" => "112th",
+    "113" => "113th",
+    "1000" => "1000th",
+    "1001" => "1001st"
+  }
+
+  UnderscoresToDashes = {
+    "street"                => "street",
+    "street_address"        => "street-address",
+    "person_street_address" => "person-street-address"
+  }
+
+  Irregularities = {
+    'person' => 'people',
+    'man'    => 'men',
+    'child'  => 'children',
+    'sex'    => 'sexes',
+    'move'   => 'moves',
+    'cow'    => 'kine', # Test inflections with different starting letters
+    'zombie' => 'zombies',
+    'genus'  => 'genera'
+  }
+end
diff --git a/app/server/vendor/activesupport/test/json/decoding_test.rb b/app/server/vendor/activesupport/test/json/decoding_test.rb
new file mode 100644
index 0000000..07d7e53
--- /dev/null
+++ b/app/server/vendor/activesupport/test/json/decoding_test.rb
@@ -0,0 +1,105 @@
+# encoding: utf-8
+require 'abstract_unit'
+require 'active_support/json'
+require 'active_support/time'
+
+class TestJSONDecoding < ActiveSupport::TestCase
+  class Foo
+    def self.json_create(object)
+      "Foo"
+    end
+  end
+
+  TESTS = {
+    %q({"returnTo":{"\/categories":"\/"}})        => {"returnTo" => {"/categories" => "/"}},
+    %q({"return\\"To\\":":{"\/categories":"\/"}}) => {"return\"To\":" => {"/categories" => "/"}},
+    %q({"returnTo":{"\/categories":1}})          => {"returnTo" => {"/categories" => 1}},
+    %({"returnTo":[1,"a"]})                    => {"returnTo" => [1, "a"]},
+    %({"returnTo":[1,"\\"a\\",", "b"]})        => {"returnTo" => [1, "\"a\",", "b"]},
+    %({"a": "'", "b": "5,000"})                  => {"a" => "'", "b" => "5,000"},
+    %({"a": "a's, b's and c's", "b": "5,000"})   => {"a" => "a's, b's and c's", "b" => "5,000"},
+    # multibyte
+    %({"matzue": "松江", "asakusa": "浅草"}) => {"matzue" => "松江", "asakusa" => "浅草"},
+    %({"a": "2007-01-01"})                       => {'a' => Date.new(2007, 1, 1)},
+    %({"a": "2007-01-01 01:12:34 Z"})            => {'a' => Time.utc(2007, 1, 1, 1, 12, 34)},
+    %(["2007-01-01 01:12:34 Z"])                 => [Time.utc(2007, 1, 1, 1, 12, 34)],
+    %(["2007-01-01 01:12:34 Z", "2007-01-01 01:12:35 Z"]) => [Time.utc(2007, 1, 1, 1, 12, 34), Time.utc(2007, 1, 1, 1, 12, 35)],
+    # no time zone
+    %({"a": "2007-01-01 01:12:34"})              => {'a' => "2007-01-01 01:12:34"},
+    # invalid date
+    %({"a": "1089-10-40"})                       => {'a' => "1089-10-40"},
+    # xmlschema date notation
+    %({"a": "2009-08-10T19:01:02Z"})             => {'a' => Time.utc(2009, 8, 10, 19, 1, 2)},
+    %({"a": "2009-08-10T19:01:02+02:00"})        => {'a' => Time.utc(2009, 8, 10, 17, 1, 2)},
+    %({"a": "2009-08-10T19:01:02-05:00"})        => {'a' => Time.utc(2009, 8, 11, 00, 1, 2)},
+    # needs to be *exact*
+    %({"a": " 2007-01-01 01:12:34 Z "})          => {'a' => " 2007-01-01 01:12:34 Z "},
+    %({"a": "2007-01-01 : it's your birthday"})  => {'a' => "2007-01-01 : it's your birthday"},
+    %([])    => [],
+    %({})    => {},
+    %({"a":1})     => {"a" => 1},
+    %({"a": ""})    => {"a" => ""},
+    %({"a":"\\""}) => {"a" => "\""},
+    %({"a": null})  => {"a" => nil},
+    %({"a": true})  => {"a" => true},
+    %({"a": false}) => {"a" => false},
+    %q({"bad":"\\\\","trailing":""}) => {"bad" => "\\", "trailing" => ""},
+    %q({"a": "http:\/\/test.host\/posts\/1"}) => {"a" => "http://test.host/posts/1"},
+    %q({"a": "\u003cunicode\u0020escape\u003e"}) => {"a" => "<unicode escape>"},
+    %q({"a": "\\\\u0020skip double backslashes"}) => {"a" => "\\u0020skip double backslashes"},
+    %q({"a": "\u003cbr /\u003e"}) => {'a' => "<br />"},
+    %q({"b":["\u003ci\u003e","\u003cb\u003e","\u003cu\u003e"]}) => {'b' => ["<i>","<b>","<u>"]},
+    # test combination of dates and escaped or unicode encoded data in arrays
+    %q([{"d":"1970-01-01", "s":"\u0020escape"},{"d":"1970-01-01", "s":"\u0020escape"}]) =>
+      [{'d' => Date.new(1970, 1, 1), 's' => ' escape'},{'d' => Date.new(1970, 1, 1), 's' => ' escape'}],
+    %q([{"d":"1970-01-01","s":"http:\/\/example.com"},{"d":"1970-01-01","s":"http:\/\/example.com"}]) =>
+      [{'d' => Date.new(1970, 1, 1), 's' => 'http://example.com'},
+       {'d' => Date.new(1970, 1, 1), 's' => 'http://example.com'}],
+    # tests escaping of "\n" char with Yaml backend
+    %q({"a":"\n"})  => {"a"=>"\n"},
+    %q({"a":"\u000a"}) => {"a"=>"\n"},
+    %q({"a":"Line1\u000aLine2"}) => {"a"=>"Line1\nLine2"},
+    # prevent json unmarshalling
+    %q({"json_class":"TestJSONDecoding::Foo"}) => {"json_class"=>"TestJSONDecoding::Foo"},
+    # json "fragments" - these are invalid JSON, but ActionPack relies on this
+    %q("a string") => "a string",
+    %q(1.1) => 1.1,
+    %q(1) => 1,
+    %q(-1) => -1,
+    %q(true) => true,
+    %q(false) => false,
+    %q(null) => nil
+  }
+
+  TESTS.each_with_index do |(json, expected), index|
+    test "json decodes #{index}" do
+      prev = ActiveSupport.parse_json_times
+      ActiveSupport.parse_json_times = true
+      silence_warnings do
+        assert_equal expected, ActiveSupport::JSON.decode(json), "JSON decoding \
+        failed for #{json}"
+      end
+      ActiveSupport.parse_json_times = prev
+    end
+  end
+
+  test "json decodes time json with time parsing disabled" do
+    prev = ActiveSupport.parse_json_times
+    ActiveSupport.parse_json_times = false
+    expected = {"a" => "2007-01-01 01:12:34 Z"}
+    assert_equal expected, ActiveSupport::JSON.decode(%({"a": "2007-01-01 01:12:34 Z"}))
+    ActiveSupport.parse_json_times = prev
+  end
+
+  def test_failed_json_decoding
+    assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%(undefined)) }
+    assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%({a: 1})) }
+    assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%({: 1})) }
+    assert_raise(ActiveSupport::JSON.parse_error) { ActiveSupport::JSON.decode(%()) }
+  end
+
+  def test_cannot_pass_unsupported_options
+    assert_raise(ArgumentError) { ActiveSupport::JSON.decode("", create_additions: true) }
+  end
+end
+
diff --git a/app/server/vendor/activesupport/test/json/encoding_test.rb b/app/server/vendor/activesupport/test/json/encoding_test.rb
new file mode 100644
index 0000000..f22d7b8
--- /dev/null
+++ b/app/server/vendor/activesupport/test/json/encoding_test.rb
@@ -0,0 +1,546 @@
+# encoding: utf-8
+require 'securerandom'
+require 'abstract_unit'
+require 'active_support/core_ext/string/inflections'
+require 'active_support/json'
+require 'active_support/time'
+
+class TestJSONEncoding < ActiveSupport::TestCase
+  class Foo
+    def initialize(a, b)
+      @a, @b = a, b
+    end
+  end
+
+  class Hashlike
+    def to_hash
+      { :foo => "hello", :bar => "world" }
+    end
+  end
+
+  class Custom
+    def initialize(serialized)
+      @serialized = serialized
+    end
+
+    def as_json(options = nil)
+      @serialized
+    end
+  end
+
+  class CustomWithOptions
+    attr_accessor :foo, :bar
+
+    def as_json(options={})
+      options[:only] = %w(foo bar)
+      super(options)
+    end
+  end
+
+  class OptionsTest
+    def as_json(options = :default)
+      options
+    end
+  end
+
+  class HashWithAsJson < Hash
+    attr_accessor :as_json_called
+
+    def initialize(*)
+      super
+    end
+
+    def as_json(options={})
+      @as_json_called = true
+      super
+    end
+  end
+
+  TrueTests     = [[ true,  %(true)  ]]
+  FalseTests    = [[ false, %(false) ]]
+  NilTests      = [[ nil,   %(null)  ]]
+  NumericTests  = [[ 1,     %(1)     ],
+                   [ 2.5,   %(2.5)   ],
+                   [ 0.0/0.0,   %(null) ],
+                   [ 1.0/0.0,   %(null) ],
+                   [ -1.0/0.0,  %(null) ],
+                   [ BigDecimal('0.0')/BigDecimal('0.0'),  %(null) ],
+                   [ BigDecimal('2.5'), %("#{BigDecimal('2.5').to_s}") ]]
+
+  StringTests   = [[ 'this is the <string>',     %("this is the \\u003cstring\\u003e")],
+                   [ 'a "string" with quotes & an ampersand', %("a \\"string\\" with quotes \\u0026 an ampersand") ],
+                   [ 'http://test.host/posts/1', %("http://test.host/posts/1")],
+                   [ "Control characters: \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\u2028\u2029",
+                     %("Control characters: \\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f\\u2028\\u2029") ]]
+
+  ArrayTests    = [[ ['a', 'b', 'c'],          %([\"a\",\"b\",\"c\"])          ],
+                   [ [1, 'a', :b, nil, false], %([1,\"a\",\"b\",null,false]) ]]
+
+  RangeTests    = [[ 1..2,     %("1..2")],
+                   [ 1...2,    %("1...2")],
+                   [ 1.5..2.5, %("1.5..2.5")]]
+
+  SymbolTests   = [[ :a,     %("a")    ],
+                   [ :this,  %("this") ],
+                   [ :"a b", %("a b")  ]]
+
+  ObjectTests   = [[ Foo.new(1, 2), %({\"a\":1,\"b\":2}) ]]
+  HashlikeTests = [[ Hashlike.new, %({\"bar\":\"world\",\"foo\":\"hello\"}) ]]
+  CustomTests   = [[ Custom.new("custom"), '"custom"' ],
+                   [ Custom.new(nil), 'null' ],
+                   [ Custom.new(:a), '"a"' ],
+                   [ Custom.new([ :foo, "bar" ]), '["foo","bar"]' ],
+                   [ Custom.new({ :foo => "hello", :bar => "world" }), '{"bar":"world","foo":"hello"}' ],
+                   [ Custom.new(Hashlike.new), '{"bar":"world","foo":"hello"}' ],
+                   [ Custom.new(Custom.new(Custom.new(:a))), '"a"' ]]
+
+  RegexpTests   = [[ /^a/, '"(?-mix:^a)"' ], [/^\w{1,2}[a-z]+/ix, '"(?ix-m:^\\\\w{1,2}[a-z]+)"']]
+
+  DateTests     = [[ Date.new(2005,2,1), %("2005/02/01") ]]
+  TimeTests     = [[ Time.utc(2005,2,1,15,15,10), %("2005/02/01 15:15:10 +0000") ]]
+  DateTimeTests = [[ DateTime.civil(2005,2,1,15,15,10), %("2005/02/01 15:15:10 +0000") ]]
+
+  StandardDateTests     = [[ Date.new(2005,2,1), %("2005-02-01") ]]
+  StandardTimeTests     = [[ Time.utc(2005,2,1,15,15,10), %("2005-02-01T15:15:10.000Z") ]]
+  StandardDateTimeTests = [[ DateTime.civil(2005,2,1,15,15,10), %("2005-02-01T15:15:10.000+00:00") ]]
+  StandardStringTests   = [[ 'this is the <string>', %("this is the <string>")]]
+
+  def sorted_json(json)
+    return json unless json =~ /^\{.*\}$/
+    '{' + json[1..-2].split(',').sort.join(',') + '}'
+  end
+
+  constants.grep(/Tests$/).each do |class_tests|
+    define_method("test_#{class_tests[0..-6].underscore}") do
+      begin
+        prev = ActiveSupport.use_standard_json_time_format
+
+        ActiveSupport.escape_html_entities_in_json  = class_tests !~ /^Standard/
+        ActiveSupport.use_standard_json_time_format = class_tests =~ /^Standard/
+        self.class.const_get(class_tests).each do |pair|
+          assert_equal pair.last, sorted_json(ActiveSupport::JSON.encode(pair.first))
+        end
+      ensure
+        ActiveSupport.escape_html_entities_in_json  = false
+        ActiveSupport.use_standard_json_time_format = prev
+      end
+    end
+  end
+
+  def test_process_status
+    # There doesn't seem to be a good way to get a handle on a Process::Status object without actually
+    # creating a child process, hence this to populate $?
+    system("not_a_real_program_#{SecureRandom.hex}")
+    assert_equal %({"exitstatus":#{$?.exitstatus},"pid":#{$?.pid}}), ActiveSupport::JSON.encode($?)
+  end
+
+  def test_hash_encoding
+    assert_equal %({\"a\":\"b\"}), ActiveSupport::JSON.encode(:a => :b)
+    assert_equal %({\"a\":1}), ActiveSupport::JSON.encode('a' => 1)
+    assert_equal %({\"a\":[1,2]}), ActiveSupport::JSON.encode('a' => [1,2])
+    assert_equal %({"1":2}), ActiveSupport::JSON.encode(1 => 2)
+
+    assert_equal %({\"a\":\"b\",\"c\":\"d\"}), sorted_json(ActiveSupport::JSON.encode(:a => :b, :c => :d))
+  end
+
+  def test_utf8_string_encoded_properly
+    result = ActiveSupport::JSON.encode('€2.99')
+    assert_equal '"€2.99"', result
+    assert_equal(Encoding::UTF_8, result.encoding)
+
+    result = ActiveSupport::JSON.encode('✎☺')
+    assert_equal '"✎☺"', result
+    assert_equal(Encoding::UTF_8, result.encoding)
+  end
+
+  def test_non_utf8_string_transcodes
+    s = '二'.encode('Shift_JIS')
+    result = ActiveSupport::JSON.encode(s)
+    assert_equal '"二"', result
+    assert_equal Encoding::UTF_8, result.encoding
+  end
+
+  def test_wide_utf8_chars
+    w = '𠜎'
+    result = ActiveSupport::JSON.encode(w)
+    assert_equal '"𠜎"', result
+  end
+
+  def test_wide_utf8_roundtrip
+    hash = { string: "𐒑" }
+    json = ActiveSupport::JSON.encode(hash)
+    decoded_hash = ActiveSupport::JSON.decode(json)
+    assert_equal "𐒑", decoded_hash['string']
+  end
+
+  def test_reading_encode_big_decimal_as_string_option
+    assert_deprecated do
+      assert ActiveSupport.encode_big_decimal_as_string
+    end
+  end
+
+  def test_setting_deprecated_encode_big_decimal_as_string_option
+    assert_raise(NotImplementedError) do
+      ActiveSupport.encode_big_decimal_as_string = true
+    end
+
+    assert_raise(NotImplementedError) do
+      ActiveSupport.encode_big_decimal_as_string = false
+    end
+  end
+
+  def test_exception_raised_when_encoding_circular_reference_in_array
+    a = [1]
+    a << a
+    assert_deprecated do
+      assert_raise(ActiveSupport::JSON::Encoding::CircularReferenceError) { ActiveSupport::JSON.encode(a) }
+    end
+  end
+
+  def test_exception_raised_when_encoding_circular_reference_in_hash
+    a = { :name => 'foo' }
+    a[:next] = a
+    assert_deprecated do
+      assert_raise(ActiveSupport::JSON::Encoding::CircularReferenceError) { ActiveSupport::JSON.encode(a) }
+    end
+  end
+
+  def test_exception_raised_when_encoding_circular_reference_in_hash_inside_array
+    a = { :name => 'foo', :sub => [] }
+    a[:sub] << a
+    assert_deprecated do
+      assert_raise(ActiveSupport::JSON::Encoding::CircularReferenceError) { ActiveSupport::JSON.encode(a) }
+    end
+  end
+
+  def test_hash_key_identifiers_are_always_quoted
+    values = {0 => 0, 1 => 1, :_ => :_, "$" => "$", "a" => "a", :A => :A, :A0 => :A0, "A0B" => "A0B"}
+    assert_equal %w( "$" "A" "A0" "A0B" "_" "a" "0" "1" ).sort, object_keys(ActiveSupport::JSON.encode(values))
+  end
+
+  def test_hash_should_allow_key_filtering_with_only
+    assert_equal %({"a":1}), ActiveSupport::JSON.encode({'a' => 1, :b => 2, :c => 3}, :only => 'a')
+  end
+
+  def test_hash_should_allow_key_filtering_with_except
+    assert_equal %({"b":2}), ActiveSupport::JSON.encode({'foo' => 'bar', :b => 2, :c => 3}, :except => ['foo', :c])
+  end
+
+  def test_time_to_json_includes_local_offset
+    with_standard_json_time_format(true) do
+      with_env_tz 'US/Eastern' do
+        assert_equal %("2005-02-01T15:15:10.000-05:00"), ActiveSupport::JSON.encode(Time.local(2005,2,1,15,15,10))
+      end
+    end
+  end
+
+  def test_hash_with_time_to_json
+    with_standard_json_time_format(false) do
+      assert_equal '{"time":"2009/01/01 00:00:00 +0000"}', { :time => Time.utc(2009) }.to_json
+    end
+  end
+
+  def test_nested_hash_with_float
+    assert_nothing_raised do
+      hash = {
+        "CHI" => {
+          :display_name => "chicago",
+          :latitude => 123.234
+        }
+      }
+      ActiveSupport::JSON.encode(hash)
+    end
+  end
+
+  def test_hash_like_with_options
+    h = Hashlike.new
+    json = h.to_json :only => [:foo]
+
+    assert_equal({"foo"=>"hello"}, JSON.parse(json))
+  end
+
+  def test_object_to_json_with_options
+    obj = Object.new
+    obj.instance_variable_set :@foo, "hello"
+    obj.instance_variable_set :@bar, "world"
+    json = obj.to_json :only => ["foo"]
+
+    assert_equal({"foo"=>"hello"}, JSON.parse(json))
+  end
+
+  def test_struct_to_json_with_options
+    struct = Struct.new(:foo, :bar).new
+    struct.foo = "hello"
+    struct.bar = "world"
+    json = struct.to_json :only => [:foo]
+
+    assert_equal({"foo"=>"hello"}, JSON.parse(json))
+  end
+
+  def test_hash_should_pass_encoding_options_to_children_in_as_json
+    person = {
+      :name => 'John',
+      :address => {
+        :city => 'London',
+        :country => 'UK'
+      }
+    }
+    json = person.as_json :only => [:address, :city]
+
+    assert_equal({ 'address' => { 'city' => 'London' }}, json)
+  end
+
+  def test_hash_should_pass_encoding_options_to_children_in_to_json
+    person = {
+      :name => 'John',
+      :address => {
+        :city => 'London',
+        :country => 'UK'
+      }
+    }
+    json = person.to_json :only => [:address, :city]
+
+    assert_equal(%({"address":{"city":"London"}}), json)
+  end
+
+  def test_array_should_pass_encoding_options_to_children_in_as_json
+    people = [
+      { :name => 'John', :address => { :city => 'London', :country => 'UK' }},
+      { :name => 'Jean', :address => { :city => 'Paris' , :country => 'France' }}
+    ]
+    json = people.as_json :only => [:address, :city]
+    expected = [
+      { 'address' => { 'city' => 'London' }},
+      { 'address' => { 'city' => 'Paris' }}
+    ]
+
+    assert_equal(expected, json)
+  end
+
+  def test_array_should_pass_encoding_options_to_children_in_to_json
+    people = [
+      { :name => 'John', :address => { :city => 'London', :country => 'UK' }},
+      { :name => 'Jean', :address => { :city => 'Paris' , :country => 'France' }}
+    ]
+    json = people.to_json :only => [:address, :city]
+
+    assert_equal(%([{"address":{"city":"London"}},{"address":{"city":"Paris"}}]), json)
+  end
+
+  People = Class.new(BasicObject) do
+    include Enumerable
+    def initialize()
+      @people = [
+        { :name => 'John', :address => { :city => 'London', :country => 'UK' }},
+        { :name => 'Jean', :address => { :city => 'Paris' , :country => 'France' }}
+      ]
+    end
+    def each(*, &blk)
+      @people.each do |p|
+        yield p if blk
+        p
+      end.each
+    end
+  end
+
+  def test_enumerable_should_generate_json_with_as_json
+    json = People.new.as_json :only => [:address, :city]
+    expected = [
+      { 'address' => { 'city' => 'London' }},
+      { 'address' => { 'city' => 'Paris' }}
+    ]
+
+    assert_equal(expected, json)
+  end
+
+  def test_enumerable_should_generate_json_with_to_json
+    json = People.new.to_json :only => [:address, :city]
+    assert_equal(%([{"address":{"city":"London"}},{"address":{"city":"Paris"}}]), json)
+  end
+
+  def test_enumerable_should_pass_encoding_options_to_children_in_as_json
+    json = People.new.each.as_json :only => [:address, :city]
+    expected = [
+      { 'address' => { 'city' => 'London' }},
+      { 'address' => { 'city' => 'Paris' }}
+    ]
+
+    assert_equal(expected, json)
+  end
+
+  def test_enumerable_should_pass_encoding_options_to_children_in_to_json
+    json = People.new.each.to_json :only => [:address, :city]
+
+    assert_equal(%([{"address":{"city":"London"}},{"address":{"city":"Paris"}}]), json)
+  end
+
+  def test_hash_to_json_should_not_keep_options_around
+    f = CustomWithOptions.new
+    f.foo = "hello"
+    f.bar = "world"
+
+    hash = {"foo" => f, "other_hash" => {"foo" => "other_foo", "test" => "other_test"}}
+    assert_equal({"foo"=>{"foo"=>"hello","bar"=>"world"},
+                  "other_hash" => {"foo"=>"other_foo","test"=>"other_test"}}, ActiveSupport::JSON.decode(hash.to_json))
+  end
+
+  def test_array_to_json_should_not_keep_options_around
+    f = CustomWithOptions.new
+    f.foo = "hello"
+    f.bar = "world"
+
+    array = [f, {"foo" => "other_foo", "test" => "other_test"}]
+    assert_equal([{"foo"=>"hello","bar"=>"world"},
+                  {"foo"=>"other_foo","test"=>"other_test"}], ActiveSupport::JSON.decode(array.to_json))
+  end
+
+  def test_hash_as_json_without_options
+    json = { foo: OptionsTest.new }.as_json
+    assert_equal({"foo" => :default}, json)
+  end
+
+  def test_array_as_json_without_options
+    json = [ OptionsTest.new ].as_json
+    assert_equal([:default], json)
+  end
+
+  def test_struct_encoding
+    Struct.new('UserNameAndEmail', :name, :email)
+    Struct.new('UserNameAndDate', :name, :date)
+    Struct.new('Custom', :name, :sub)
+    user_email = Struct::UserNameAndEmail.new 'David', 'sample at example.com'
+    user_birthday = Struct::UserNameAndDate.new 'David', Date.new(2010, 01, 01)
+    custom = Struct::Custom.new 'David', user_birthday
+
+
+    json_strings = ""
+    json_string_and_date = ""
+    json_custom = ""
+
+    assert_nothing_raised do
+      json_strings = user_email.to_json
+      json_string_and_date = user_birthday.to_json
+      json_custom = custom.to_json
+    end
+
+    assert_equal({"name" => "David",
+                  "sub" => {
+                    "name" => "David",
+                    "date" => "2010-01-01" }}, ActiveSupport::JSON.decode(json_custom))
+
+    assert_equal({"name" => "David", "email" => "sample at example.com"},
+                 ActiveSupport::JSON.decode(json_strings))
+
+    assert_equal({"name" => "David", "date" => "2010-01-01"},
+                 ActiveSupport::JSON.decode(json_string_and_date))
+  end
+
+  def test_nil_true_and_false_represented_as_themselves
+    assert_equal nil,   nil.as_json
+    assert_equal true,  true.as_json
+    assert_equal false, false.as_json
+  end
+
+  def test_json_gem_dump_by_passing_active_support_encoder
+    h = HashWithAsJson.new
+    h[:foo] = "hello"
+    h[:bar] = "world"
+
+    assert_equal %({"foo":"hello","bar":"world"}), JSON.dump(h)
+    assert_nil h.as_json_called
+  end
+
+  def test_json_gem_generate_by_passing_active_support_encoder
+    h = HashWithAsJson.new
+    h[:foo] = "hello"
+    h[:bar] = "world"
+
+    assert_equal %({"foo":"hello","bar":"world"}), JSON.generate(h)
+    assert_nil h.as_json_called
+  end
+
+  def test_json_gem_pretty_generate_by_passing_active_support_encoder
+    h = HashWithAsJson.new
+    h[:foo] = "hello"
+    h[:bar] = "world"
+
+    assert_equal <<EXPECTED.chomp, JSON.pretty_generate(h)
+{
+  "foo": "hello",
+  "bar": "world"
+}
+EXPECTED
+    assert_nil h.as_json_called
+  end
+
+  def test_twz_to_json_with_use_standard_json_time_format_config_set_to_false
+    with_standard_json_time_format(false) do
+      zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+      time = ActiveSupport::TimeWithZone.new(Time.utc(2000), zone)
+      assert_equal "\"1999/12/31 19:00:00 -0500\"", ActiveSupport::JSON.encode(time)
+    end
+  end
+
+  def test_twz_to_json_with_use_standard_json_time_format_config_set_to_true
+    with_standard_json_time_format(true) do
+      zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+      time = ActiveSupport::TimeWithZone.new(Time.utc(2000), zone)
+      assert_equal "\"1999-12-31T19:00:00.000-05:00\"", ActiveSupport::JSON.encode(time)
+    end
+  end
+
+  def test_twz_to_json_with_custom_time_precision
+    with_standard_json_time_format(true) do
+      ActiveSupport::JSON::Encoding.time_precision = 0
+      zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+      time = ActiveSupport::TimeWithZone.new(Time.utc(2000), zone)
+      assert_equal "\"1999-12-31T19:00:00-05:00\"", ActiveSupport::JSON.encode(time)
+    end
+  ensure
+    ActiveSupport::JSON::Encoding.time_precision = 3
+  end
+
+  def test_time_to_json_with_custom_time_precision
+    with_standard_json_time_format(true) do
+      ActiveSupport::JSON::Encoding.time_precision = 0
+      assert_equal "\"2000-01-01T00:00:00Z\"", ActiveSupport::JSON.encode(Time.utc(2000))
+    end
+  ensure
+    ActiveSupport::JSON::Encoding.time_precision = 3
+  end
+
+  def test_datetime_to_json_with_custom_time_precision
+    with_standard_json_time_format(true) do
+      ActiveSupport::JSON::Encoding.time_precision = 0
+      assert_equal "\"2000-01-01T00:00:00+00:00\"", ActiveSupport::JSON.encode(DateTime.new(2000))
+    end
+  ensure
+    ActiveSupport::JSON::Encoding.time_precision = 3
+  end
+
+  def test_twz_to_json_when_wrapping_a_date_time
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    time = ActiveSupport::TimeWithZone.new(DateTime.new(2000), zone)
+    assert_equal '"1999-12-31T19:00:00.000-05:00"', ActiveSupport::JSON.encode(time)
+  end
+
+  protected
+
+    def object_keys(json_object)
+      json_object[1..-2].scan(/([^{}:,\s]+):/).flatten.sort
+    end
+
+    def with_env_tz(new_tz = 'US/Eastern')
+      old_tz, ENV['TZ'] = ENV['TZ'], new_tz
+      yield
+    ensure
+      old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+    end
+
+    def with_standard_json_time_format(boolean = true)
+      old, ActiveSupport.use_standard_json_time_format = ActiveSupport.use_standard_json_time_format, boolean
+      yield
+    ensure
+      ActiveSupport.use_standard_json_time_format = old
+    end
+end
diff --git a/app/server/vendor/activesupport/test/key_generator_test.rb b/app/server/vendor/activesupport/test/key_generator_test.rb
new file mode 100644
index 0000000..525082d
--- /dev/null
+++ b/app/server/vendor/activesupport/test/key_generator_test.rb
@@ -0,0 +1,32 @@
+require 'abstract_unit'
+
+begin
+  require 'openssl'
+  OpenSSL::PKCS5
+rescue LoadError, NameError
+  $stderr.puts "Skipping KeyGenerator test: broken OpenSSL install"
+else
+
+require 'active_support/time'
+require 'active_support/json'
+
+class KeyGeneratorTest < ActiveSupport::TestCase
+  def setup
+    @secret    = SecureRandom.hex(64)
+    @generator = ActiveSupport::KeyGenerator.new(@secret, :iterations=>2)
+  end
+
+  test "Generating a key of the default length" do
+    derived_key = @generator.generate_key("some_salt")
+    assert_kind_of String, derived_key
+    assert_equal OpenSSL::Digest::SHA1.new.block_length, derived_key.length, "Should have generated a key of the default size"
+  end
+
+  test "Generating a key of an alternative length" do
+    derived_key = @generator.generate_key("some_salt", 32)
+    assert_kind_of String, derived_key
+    assert_equal 32, derived_key.length, "Should have generated a key of the right size"
+  end
+end
+
+end
diff --git a/app/server/vendor/activesupport/test/lazy_load_hooks_test.rb b/app/server/vendor/activesupport/test/lazy_load_hooks_test.rb
new file mode 100644
index 0000000..7851634
--- /dev/null
+++ b/app/server/vendor/activesupport/test/lazy_load_hooks_test.rb
@@ -0,0 +1,96 @@
+require 'abstract_unit'
+
+class LazyLoadHooksTest < ActiveSupport::TestCase
+  def test_basic_hook
+    i = 0
+    ActiveSupport.on_load(:basic_hook) { i += 1 }
+    ActiveSupport.run_load_hooks(:basic_hook)
+    assert_equal 1, i
+  end
+
+  def test_basic_hook_with_two_registrations
+    i = 0
+    ActiveSupport.on_load(:basic_hook_with_two) { i += incr }
+    assert_equal 0, i
+    ActiveSupport.run_load_hooks(:basic_hook_with_two, FakeContext.new(2))
+    assert_equal 2, i
+    ActiveSupport.run_load_hooks(:basic_hook_with_two, FakeContext.new(5))
+    assert_equal 7, i
+  end
+
+  def test_hook_registered_after_run
+    i = 0
+    ActiveSupport.run_load_hooks(:registered_after)
+    assert_equal 0, i
+    ActiveSupport.on_load(:registered_after) { i += 1 }
+    assert_equal 1, i
+  end
+
+  def test_hook_registered_after_run_with_two_registrations
+    i = 0
+    ActiveSupport.run_load_hooks(:registered_after_with_two, FakeContext.new(2))
+    ActiveSupport.run_load_hooks(:registered_after_with_two, FakeContext.new(5))
+    assert_equal 0, i
+    ActiveSupport.on_load(:registered_after_with_two) { i += incr }
+    assert_equal 7, i
+  end
+
+  def test_hook_registered_interleaved_run_with_two_registrations
+    i = 0
+    ActiveSupport.run_load_hooks(:registered_interleaved_with_two, FakeContext.new(2))
+    assert_equal 0, i
+    ActiveSupport.on_load(:registered_interleaved_with_two) { i += incr }
+    assert_equal 2, i
+    ActiveSupport.run_load_hooks(:registered_interleaved_with_two, FakeContext.new(5))
+    assert_equal 7, i
+  end
+
+  def test_hook_receives_a_context
+    i = 0
+    ActiveSupport.on_load(:contextual) { i += incr }
+    assert_equal 0, i
+    ActiveSupport.run_load_hooks(:contextual, FakeContext.new(2))
+    assert_equal 2, i
+  end
+
+  def test_hook_receives_a_context_afterward
+    i = 0
+    ActiveSupport.run_load_hooks(:contextual_after, FakeContext.new(2))
+    assert_equal 0, i
+    ActiveSupport.on_load(:contextual_after) { i += incr }
+    assert_equal 2, i
+  end
+
+  def test_hook_with_yield_true
+    i = 0
+    ActiveSupport.on_load(:contextual_yield, :yield => true) do |obj|
+      i += obj.incr + incr_amt
+    end
+    assert_equal 0, i
+    ActiveSupport.run_load_hooks(:contextual_yield, FakeContext.new(2))
+    assert_equal 7, i
+  end
+
+  def test_hook_with_yield_true_afterward
+    i = 0
+    ActiveSupport.run_load_hooks(:contextual_yield_after, FakeContext.new(2))
+    assert_equal 0, i
+    ActiveSupport.on_load(:contextual_yield_after, :yield => true) do |obj|
+      i += obj.incr + incr_amt
+    end
+    assert_equal 7, i
+  end
+
+private
+
+  def incr_amt
+    5
+  end
+
+  class FakeContext
+    attr_reader :incr
+    def initialize(incr)
+      @incr = incr
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/load_paths_test.rb b/app/server/vendor/activesupport/test/load_paths_test.rb
new file mode 100644
index 0000000..ac617a9
--- /dev/null
+++ b/app/server/vendor/activesupport/test/load_paths_test.rb
@@ -0,0 +1,16 @@
+require 'abstract_unit'
+
+class LoadPathsTest < ActiveSupport::TestCase
+  def test_uniq_load_paths
+    load_paths_count = $LOAD_PATH.inject({}) { |paths, path|
+      expanded_path = File.expand_path(path)
+      paths[expanded_path] ||= 0
+      paths[expanded_path] += 1
+      paths
+    }
+    load_paths_count[File.expand_path('../../lib', __FILE__)] -= 1
+
+    load_paths_count.select! { |k, v| v > 1 }
+    assert load_paths_count.empty?, load_paths_count.inspect
+  end
+end
diff --git a/app/server/vendor/activesupport/test/log_subscriber_test.rb b/app/server/vendor/activesupport/test/log_subscriber_test.rb
new file mode 100644
index 0000000..2a0e8d2
--- /dev/null
+++ b/app/server/vendor/activesupport/test/log_subscriber_test.rb
@@ -0,0 +1,123 @@
+require 'abstract_unit'
+require 'active_support/log_subscriber/test_helper'
+
+class MyLogSubscriber < ActiveSupport::LogSubscriber
+  attr_reader :event
+
+  def some_event(event)
+    @event = event
+    info event.name
+  end
+
+  def foo(event)
+    debug "debug"
+    info { "info" }
+    warn "warn"
+  end
+
+  def bar(event)
+    info "#{color("cool", :red)}, #{color("isn't it?", :blue, true)}"
+  end
+
+  def puke(event)
+    raise "puke"
+  end
+end
+
+class SyncLogSubscriberTest < ActiveSupport::TestCase
+  include ActiveSupport::LogSubscriber::TestHelper
+
+  def setup
+    super
+    @log_subscriber = MyLogSubscriber.new
+  end
+
+  def teardown
+    super
+    ActiveSupport::LogSubscriber.log_subscribers.clear
+  end
+
+  def instrument(*args, &block)
+    ActiveSupport::Notifications.instrument(*args, &block)
+  end
+
+  def test_proxies_method_to_rails_logger
+    @log_subscriber.foo(nil)
+    assert_equal %w(debug), @logger.logged(:debug)
+    assert_equal %w(info), @logger.logged(:info)
+    assert_equal %w(warn), @logger.logged(:warn)
+  end
+
+  def test_set_color_for_messages
+    ActiveSupport::LogSubscriber.colorize_logging = true
+    @log_subscriber.bar(nil)
+    assert_equal "\e[31mcool\e[0m, \e[1m\e[34misn't it?\e[0m", @logger.logged(:info).last
+  end
+
+  def test_does_not_set_color_if_colorize_logging_is_set_to_false
+    @log_subscriber.bar(nil)
+    assert_equal "cool, isn't it?", @logger.logged(:info).last
+  end
+
+  def test_event_is_sent_to_the_registered_class
+    ActiveSupport::LogSubscriber.attach_to :my_log_subscriber, @log_subscriber
+    instrument "some_event.my_log_subscriber"
+    wait
+    assert_equal %w(some_event.my_log_subscriber), @logger.logged(:info)
+  end
+
+  def test_event_is_an_active_support_notifications_event
+    ActiveSupport::LogSubscriber.attach_to :my_log_subscriber, @log_subscriber
+    instrument "some_event.my_log_subscriber"
+    wait
+    assert_kind_of ActiveSupport::Notifications::Event, @log_subscriber.event
+  end
+
+  def test_does_not_send_the_event_if_it_doesnt_match_the_class
+    ActiveSupport::LogSubscriber.attach_to :my_log_subscriber, @log_subscriber
+    instrument "unknown_event.my_log_subscriber"
+    wait
+    # If we get here, it means that NoMethodError was not raised.
+  end
+
+  def test_does_not_send_the_event_if_logger_is_nil
+    ActiveSupport::LogSubscriber.logger = nil
+    @log_subscriber.expects(:some_event).never
+    ActiveSupport::LogSubscriber.attach_to :my_log_subscriber, @log_subscriber
+    instrument "some_event.my_log_subscriber"
+    wait
+  end
+
+  def test_does_not_fail_with_non_namespaced_events
+    ActiveSupport::LogSubscriber.attach_to :my_log_subscriber, @log_subscriber
+    instrument "whatever"
+    wait
+  end
+
+  def test_flushes_loggers
+    ActiveSupport::LogSubscriber.attach_to :my_log_subscriber, @log_subscriber
+    ActiveSupport::LogSubscriber.flush_all!
+    assert_equal 1, @logger.flush_count
+  end
+
+  def test_flushes_the_same_logger_just_once
+    ActiveSupport::LogSubscriber.attach_to :my_log_subscriber, @log_subscriber
+    ActiveSupport::LogSubscriber.attach_to :another, @log_subscriber
+    ActiveSupport::LogSubscriber.flush_all!
+    wait
+    assert_equal 1, @logger.flush_count
+  end
+
+  def test_logging_does_not_die_on_failures
+    ActiveSupport::LogSubscriber.attach_to :my_log_subscriber, @log_subscriber
+    instrument "puke.my_log_subscriber"
+    instrument "some_event.my_log_subscriber"
+    wait
+
+    assert_equal 1, @logger.logged(:info).size
+    assert_equal 'some_event.my_log_subscriber', @logger.logged(:info).last
+
+    assert_equal 1, @logger.logged(:error).size
+    assert_match 'Could not log "puke.my_log_subscriber" event. RuntimeError: puke', @logger.logged(:error).last
+  end
+end
diff --git a/app/server/vendor/activesupport/test/logger_test.rb b/app/server/vendor/activesupport/test/logger_test.rb
new file mode 100644
index 0000000..d280184
--- /dev/null
+++ b/app/server/vendor/activesupport/test/logger_test.rb
@@ -0,0 +1,133 @@
+require 'abstract_unit'
+require 'multibyte_test_helpers'
+require 'stringio'
+require 'fileutils'
+require 'tempfile'
+
+class LoggerTest < ActiveSupport::TestCase
+  include MultibyteTestHelpers
+
+  Logger = ActiveSupport::Logger
+
+  def setup
+    @message = "A debug message"
+    @integer_message = 12345
+    @output  = StringIO.new
+    @logger  = Logger.new(@output)
+  end
+
+  def test_write_binary_data_to_existing_file
+    t = Tempfile.new ['development', 'log']
+    t.binmode
+    t.write 'hi mom!'
+    t.close
+
+    f = File.open(t.path, 'w')
+    f.binmode
+
+    logger = Logger.new f
+    logger.level = Logger::DEBUG
+
+    str = "\x80"
+    str.force_encoding("ASCII-8BIT")
+
+    logger.add Logger::DEBUG, str
+  ensure
+    logger.close
+    t.close true
+  end
+
+  def test_write_binary_data_create_file
+    fname = File.join Dir.tmpdir, 'lol', 'rofl.log'
+    FileUtils.mkdir_p File.dirname(fname)
+    f = File.open(fname, 'w')
+    f.binmode
+
+    logger = Logger.new f
+    logger.level = Logger::DEBUG
+
+    str = "\x80"
+    str.force_encoding("ASCII-8BIT")
+
+    logger.add Logger::DEBUG, str
+  ensure
+    logger.close
+    File.unlink fname
+  end
+
+  def test_should_log_debugging_message_when_debugging
+    @logger.level = Logger::DEBUG
+    @logger.add(Logger::DEBUG, @message)
+    assert @output.string.include?(@message)
+  end
+
+  def test_should_not_log_debug_messages_when_log_level_is_info
+    @logger.level = Logger::INFO
+    @logger.add(Logger::DEBUG, @message)
+    assert ! @output.string.include?(@message)
+  end
+
+  def test_should_add_message_passed_as_block_when_using_add
+    @logger.level = Logger::INFO
+    @logger.add(Logger::INFO) {@message}
+    assert @output.string.include?(@message)
+  end
+
+  def test_should_add_message_passed_as_block_when_using_shortcut
+    @logger.level = Logger::INFO
+    @logger.info {@message}
+    assert @output.string.include?(@message)
+  end
+
+  def test_should_convert_message_to_string
+    @logger.level = Logger::INFO
+    @logger.info @integer_message
+    assert @output.string.include?(@integer_message.to_s)
+  end
+
+  def test_should_convert_message_to_string_when_passed_in_block
+    @logger.level = Logger::INFO
+    @logger.info {@integer_message}
+    assert @output.string.include?(@integer_message.to_s)
+  end
+
+  def test_should_not_evaluate_block_if_message_wont_be_logged
+    @logger.level = Logger::INFO
+    evaluated = false
+    @logger.add(Logger::DEBUG) {evaluated = true}
+    assert evaluated == false
+  end
+
+  def test_should_not_mutate_message
+    message_copy = @message.dup
+    @logger.info @message
+    assert_equal message_copy, @message
+  end
+
+  def test_should_know_if_its_loglevel_is_below_a_given_level
+    Logger::Severity.constants.each do |level|
+      next if level.to_s == 'UNKNOWN'
+      @logger.level = Logger::Severity.const_get(level) - 1
+      assert @logger.send("#{level.downcase}?"), "didn't know if it was #{level.downcase}? or below"
+    end
+  end
+
+  def test_buffer_multibyte
+    @logger.info(UNICODE_STRING)
+    @logger.info(BYTE_STRING)
+    assert @output.string.include?(UNICODE_STRING)
+    byte_string = @output.string.dup
+    byte_string.force_encoding("ASCII-8BIT")
+    assert byte_string.include?(BYTE_STRING)
+  end
+  
+  def test_silencing_everything_but_errors
+    @logger.silence do
+      @logger.debug "NOT THERE"
+      @logger.error "THIS IS HERE"
+    end
+    
+    assert !@output.string.include?("NOT THERE")
+    assert @output.string.include?("THIS IS HERE")
+  end
+end
diff --git a/app/server/vendor/activesupport/test/message_encryptor_test.rb b/app/server/vendor/activesupport/test/message_encryptor_test.rb
new file mode 100644
index 0000000..b6c0a08
--- /dev/null
+++ b/app/server/vendor/activesupport/test/message_encryptor_test.rb
@@ -0,0 +1,101 @@
+require 'abstract_unit'
+
+begin
+  require 'openssl'
+  OpenSSL::Digest::SHA1
+rescue LoadError, NameError
+  $stderr.puts "Skipping MessageEncryptor test: broken OpenSSL install"
+else
+
+require 'active_support/time'
+require 'active_support/json'
+
+class MessageEncryptorTest < ActiveSupport::TestCase
+  class JSONSerializer
+    def dump(value)
+      ActiveSupport::JSON.encode(value)
+    end
+
+    def load(value)
+      ActiveSupport::JSON.decode(value)
+    end
+  end
+
+  def setup
+    @secret    = SecureRandom.hex(64)
+    @verifier  = ActiveSupport::MessageVerifier.new(@secret, :serializer => ActiveSupport::MessageEncryptor::NullSerializer)
+    @encryptor = ActiveSupport::MessageEncryptor.new(@secret)
+    @data = { :some => "data", :now => Time.local(2010) }
+  end
+
+  def test_encrypting_twice_yields_differing_cipher_text
+    first_message = @encryptor.encrypt_and_sign(@data).split("--").first
+    second_message = @encryptor.encrypt_and_sign(@data).split("--").first
+    assert_not_equal first_message, second_message
+  end
+
+  def test_messing_with_either_encrypted_values_causes_failure
+    text, iv = @verifier.verify(@encryptor.encrypt_and_sign(@data)).split("--")
+    assert_not_decrypted([iv, text] * "--")
+    assert_not_decrypted([text, munge(iv)] * "--")
+    assert_not_decrypted([munge(text), iv] * "--")
+    assert_not_decrypted([munge(text), munge(iv)] * "--")
+  end
+
+  def test_messing_with_verified_values_causes_failures
+    text, iv = @encryptor.encrypt_and_sign(@data).split("--")
+    assert_not_verified([iv, text] * "--")
+    assert_not_verified([text, munge(iv)] * "--")
+    assert_not_verified([munge(text), iv] * "--")
+    assert_not_verified([munge(text), munge(iv)] * "--")
+  end
+
+  def test_signed_round_tripping
+    message = @encryptor.encrypt_and_sign(@data)
+    assert_equal @data, @encryptor.decrypt_and_verify(message)
+  end
+
+  def test_alternative_serialization_method
+    prev = ActiveSupport.use_standard_json_time_format
+    ActiveSupport.use_standard_json_time_format = true
+    encryptor = ActiveSupport::MessageEncryptor.new(SecureRandom.hex(64), SecureRandom.hex(64), :serializer => JSONSerializer.new)
+    message = encryptor.encrypt_and_sign({ :foo => 123, 'bar' => Time.utc(2010) })
+    exp = { "foo" => 123, "bar" => "2010-01-01T00:00:00.000Z" }
+    assert_equal exp, encryptor.decrypt_and_verify(message)
+  ensure
+    ActiveSupport.use_standard_json_time_format = prev
+  end
+
+  def test_message_obeys_strict_encoding
+    bad_encoding_characters = "\n!@#"
+    message, iv = @encryptor.encrypt_and_sign("This is a very \n\nhumble string"+bad_encoding_characters)
+
+    assert_not_decrypted("#{::Base64.encode64 message.to_s}--#{::Base64.encode64 iv.to_s}")
+    assert_not_verified("#{::Base64.encode64 message.to_s}--#{::Base64.encode64 iv.to_s}")
+
+    assert_not_decrypted([iv,  message] * bad_encoding_characters)
+    assert_not_verified([iv,  message] * bad_encoding_characters)
+  end
+
+  private
+
+  def assert_not_decrypted(value)
+    assert_raise(ActiveSupport::MessageEncryptor::InvalidMessage) do
+      @encryptor.decrypt_and_verify(@verifier.generate(value))
+    end
+  end
+
+  def assert_not_verified(value)
+    assert_raise(ActiveSupport::MessageVerifier::InvalidSignature) do
+      @encryptor.decrypt_and_verify(value)
+    end
+  end
+
+  def munge(base64_string)
+    bits = ::Base64.strict_decode64(base64_string)
+    bits.reverse!
+    ::Base64.strict_encode64(bits)
+  end
+end
+
+end
diff --git a/app/server/vendor/activesupport/test/message_verifier_test.rb b/app/server/vendor/activesupport/test/message_verifier_test.rb
new file mode 100644
index 0000000..a5748d2
--- /dev/null
+++ b/app/server/vendor/activesupport/test/message_verifier_test.rb
@@ -0,0 +1,79 @@
+require 'abstract_unit'
+
+begin
+  require 'openssl'
+  OpenSSL::Digest::SHA1
+rescue LoadError, NameError
+  $stderr.puts "Skipping MessageVerifier test: broken OpenSSL install"
+else
+
+require 'active_support/time'
+require 'active_support/json'
+
+class MessageVerifierTest < ActiveSupport::TestCase
+
+  class JSONSerializer
+    def dump(value)
+      ActiveSupport::JSON.encode(value)
+    end
+
+    def load(value)
+      ActiveSupport::JSON.decode(value)
+    end
+  end
+
+  def setup
+    @verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!")
+    @data = { :some => "data", :now => Time.local(2010) }
+  end
+
+  def test_simple_round_tripping
+    message = @verifier.generate(@data)
+    assert_equal @data, @verifier.verify(message)
+  end
+
+  def test_missing_signature_raises
+    assert_not_verified(nil)
+    assert_not_verified("")
+  end
+
+  def test_tampered_data_raises
+    data, hash = @verifier.generate(@data).split("--")
+    assert_not_verified("#{data.reverse}--#{hash}")
+    assert_not_verified("#{data}--#{hash.reverse}")
+    assert_not_verified("purejunk")
+  end
+
+  def test_alternative_serialization_method
+    prev = ActiveSupport.use_standard_json_time_format
+    ActiveSupport.use_standard_json_time_format = true
+    verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!", :serializer => JSONSerializer.new)
+    message = verifier.generate({ :foo => 123, 'bar' => Time.utc(2010) })
+    exp = { "foo" => 123, "bar" => "2010-01-01T00:00:00.000Z" }
+    assert_equal exp, verifier.verify(message)
+  ensure
+    ActiveSupport.use_standard_json_time_format = prev
+  end
+
+  def test_raise_error_when_argument_class_is_not_loaded
+    # To generate the valid message below:
+    #
+    #   AutoloadClass = Struct.new(:foo)
+    #   valid_message = @verifier.generate(foo: AutoloadClass.new('foo'))
+    #
+    valid_message = "BAh7BjoIZm9vbzonTWVzc2FnZVZlcmlmaWVyVGVzdDo6QXV0b2xvYWRDbGFzcwY6CUBmb29JIghmb28GOgZFVA==--f3ef39a5241c365083770566dc7a9eb5d6ace914"
+    exception = assert_raise(ArgumentError, NameError) do
+      @verifier.verify(valid_message)
+    end
+    assert_includes ["uninitialized constant MessageVerifierTest::AutoloadClass",
+                    "undefined class/module MessageVerifierTest::AutoloadClass"], exception.message
+  end
+
+  def assert_not_verified(message)
+    assert_raise(ActiveSupport::MessageVerifier::InvalidSignature) do
+      @verifier.verify(message)
+    end
+  end
+end
+
+end
diff --git a/app/server/vendor/activesupport/test/multibyte_chars_test.rb b/app/server/vendor/activesupport/test/multibyte_chars_test.rb
new file mode 100644
index 0000000..659fceb
--- /dev/null
+++ b/app/server/vendor/activesupport/test/multibyte_chars_test.rb
@@ -0,0 +1,713 @@
+# encoding: utf-8
+require 'abstract_unit'
+require 'multibyte_test_helpers'
+require 'active_support/core_ext/string/multibyte'
+
+class String
+  def __method_for_multibyte_testing_with_integer_result; 1; end
+  def __method_for_multibyte_testing; 'result'; end
+  def __method_for_multibyte_testing!; 'result'; end
+  def __method_for_multibyte_testing_that_returns_nil!; end
+end
+
+class MultibyteCharsTest < ActiveSupport::TestCase
+  include MultibyteTestHelpers
+
+  def setup
+    @proxy_class = ActiveSupport::Multibyte::Chars
+    @chars = @proxy_class.new UNICODE_STRING
+  end
+
+  def test_wraps_the_original_string
+    assert_equal UNICODE_STRING, @chars.to_s
+    assert_equal UNICODE_STRING, @chars.wrapped_string
+  end
+
+  def test_should_allow_method_calls_to_string
+    assert_nothing_raised do
+      @chars.__method_for_multibyte_testing
+    end
+    assert_raise NoMethodError do
+      @chars.__unknown_method
+    end
+  end
+
+  def test_forwarded_method_calls_should_return_new_chars_instance
+    assert_kind_of @proxy_class, @chars.__method_for_multibyte_testing
+    assert_not_equal @chars.object_id, @chars.__method_for_multibyte_testing.object_id
+  end
+
+  def test_forwarded_bang_method_calls_should_return_the_original_chars_instance_when_result_is_not_nil
+    assert_kind_of @proxy_class, @chars.__method_for_multibyte_testing!
+    assert_equal @chars.object_id, @chars.__method_for_multibyte_testing!.object_id
+  end
+
+  def test_forwarded_bang_method_calls_should_return_nil_when_result_is_nil
+    assert_nil @chars.__method_for_multibyte_testing_that_returns_nil!
+  end
+
+  def test_methods_are_forwarded_to_wrapped_string_for_byte_strings
+    original_encoding = BYTE_STRING.encoding
+    assert_equal BYTE_STRING.length, BYTE_STRING.mb_chars.length
+  ensure
+    BYTE_STRING.force_encoding(original_encoding)
+  end
+
+  def test_forwarded_method_with_non_string_result_should_be_returned_vertabim
+    assert_equal ''.__method_for_multibyte_testing_with_integer_result, @chars.__method_for_multibyte_testing_with_integer_result
+  end
+
+  def test_should_concatenate
+    mb_a = 'a'.mb_chars
+    mb_b = 'b'.mb_chars
+    assert_equal 'ab', mb_a + 'b'
+    assert_equal 'ab', 'a' + mb_b
+    assert_equal 'ab', mb_a + mb_b
+
+    assert_equal 'ab', mb_a << 'b'
+    assert_equal 'ab', 'a' << mb_b
+    assert_equal 'abb', mb_a << mb_b
+  end
+
+  def test_consumes_utf8_strings
+    assert @proxy_class.consumes?(UNICODE_STRING)
+    assert @proxy_class.consumes?(ASCII_STRING)
+    assert !@proxy_class.consumes?(BYTE_STRING)
+  end
+
+  def test_concatenation_should_return_a_proxy_class_instance
+    assert_equal ActiveSupport::Multibyte.proxy_class, ('a'.mb_chars + 'b').class
+    assert_equal ActiveSupport::Multibyte.proxy_class, ('a'.mb_chars << 'b').class
+  end
+
+  def test_ascii_strings_are_treated_at_utf8_strings
+    assert_equal ActiveSupport::Multibyte.proxy_class, ASCII_STRING.mb_chars.class
+  end
+
+  def test_concatenate_should_return_proxy_instance
+    assert(('a'.mb_chars + 'b').kind_of?(@proxy_class))
+    assert(('a'.mb_chars + 'b'.mb_chars).kind_of?(@proxy_class))
+    assert(('a'.mb_chars << 'b').kind_of?(@proxy_class))
+    assert(('a'.mb_chars << 'b'.mb_chars).kind_of?(@proxy_class))
+  end
+
+  def test_should_return_string_as_json
+    assert_equal UNICODE_STRING, @chars.as_json
+  end
+end
+
+class MultibyteCharsUTF8BehaviourTest < ActiveSupport::TestCase
+  include MultibyteTestHelpers
+
+  def setup
+    @chars = UNICODE_STRING.dup.mb_chars
+    # Ruby 1.9 only supports basic whitespace
+    @whitespace = "\n\t "
+    @byte_order_mark = [65279].pack('U')
+  end
+
+  def test_split_should_return_an_array_of_chars_instances
+    @chars.split(//).each do |character|
+      assert_kind_of ActiveSupport::Multibyte.proxy_class, character
+    end
+  end
+
+  %w{capitalize downcase lstrip reverse rstrip swapcase upcase}.each do |method|
+    class_eval(<<-EOTESTS, __FILE__, __LINE__ + 1)
+      def test_#{method}_bang_should_return_self_when_modifying_wrapped_string
+        chars = ' él piDió Un bUen café '
+        assert_equal chars.object_id, chars.send("#{method}!").object_id
+      end
+
+      def test_#{method}_bang_should_change_wrapped_string
+        original = ' él piDió Un bUen café '
+        proxy = chars(original.dup)
+        proxy.send("#{method}!")
+        assert_not_equal original, proxy.to_s
+      end
+    EOTESTS
+  end
+
+  def test_tidy_bytes_bang_should_return_self
+    assert_equal @chars.object_id, @chars.tidy_bytes!.object_id
+  end
+
+  def test_tidy_bytes_bang_should_change_wrapped_string
+    original = " Un bUen café \x92"
+    proxy = chars(original.dup)
+    proxy.tidy_bytes!
+    assert_not_equal original, proxy.to_s
+  end
+
+  def test_unicode_string_should_have_utf8_encoding
+    assert_equal Encoding::UTF_8, UNICODE_STRING.encoding
+  end
+
+  def test_identity
+    assert_equal @chars, @chars
+    assert @chars.eql?(@chars)
+    assert !@chars.eql?(UNICODE_STRING)
+  end
+
+  def test_string_methods_are_chainable
+    assert chars('').insert(0, '').kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').rjust(1).kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').ljust(1).kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').center(1).kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').rstrip.kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').lstrip.kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').strip.kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').reverse.kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars(' ').slice(0).kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').limit(0).kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').upcase.kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').downcase.kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').capitalize.kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').normalize.kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').decompose.kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').compose.kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').tidy_bytes.kind_of?(ActiveSupport::Multibyte.proxy_class)
+    assert chars('').swapcase.kind_of?(ActiveSupport::Multibyte.proxy_class)
+  end
+
+  def test_should_be_equal_to_the_wrapped_string
+    assert_equal UNICODE_STRING, @chars
+    assert_equal @chars, UNICODE_STRING
+  end
+
+  def test_should_not_be_equal_to_an_other_string
+    assert_not_equal @chars, 'other'
+    assert_not_equal 'other', @chars
+  end
+
+  def test_sortability
+    words = %w(builder armor zebra).sort_by { |s| s.mb_chars }
+    assert_equal %w(armor builder zebra), words
+  end
+
+  def test_should_return_character_offset_for_regexp_matches
+    assert_nil(@chars =~ /wrong/u)
+    assert_equal 0, (@chars =~ /こ/u)
+    assert_equal 0, (@chars =~ /こに/u)
+    assert_equal 1, (@chars =~ /に/u)
+    assert_equal 2, (@chars =~ /ち/u)
+    assert_equal 3, (@chars =~ /わ/u)
+  end
+
+  def test_should_use_character_offsets_for_insert_offsets
+    assert_equal '', ''.mb_chars.insert(0, '')
+    assert_equal 'こわにちわ', @chars.insert(1, 'わ')
+    assert_equal 'こわわわにちわ', @chars.insert(2, 'わわ')
+    assert_equal 'わこわわわにちわ', @chars.insert(0, 'わ')
+    assert_equal 'わこわわわにちわ', @chars.wrapped_string
+  end
+
+  def test_insert_should_be_destructive
+    @chars.insert(1, 'わ')
+    assert_equal 'こわにちわ', @chars
+  end
+
+  def test_insert_throws_index_error
+    assert_raise(IndexError) { @chars.insert(-12, 'わ')}
+    assert_raise(IndexError) { @chars.insert(12, 'わ') }
+  end
+
+  def test_should_know_if_one_includes_the_other
+    assert @chars.include?('')
+    assert @chars.include?('ち')
+    assert @chars.include?('わ')
+    assert !@chars.include?('こちわ')
+    assert !@chars.include?('a')
+  end
+
+  def test_include_raises_when_nil_is_passed
+    assert_raises TypeError, NoMethodError, "Expected chars.include?(nil) to raise TypeError or NoMethodError" do
+      @chars.include?(nil)
+    end
+  end
+
+  def test_index_should_return_character_offset
+    assert_nil @chars.index('u')
+    assert_equal 0, @chars.index('こに')
+    assert_equal 2, @chars.index('ち')
+    assert_equal 2, @chars.index('ち', -2)
+    assert_equal nil, @chars.index('ち', -1)
+    assert_equal 3, @chars.index('わ')
+    assert_equal 5, 'ééxééx'.mb_chars.index('x', 4)
+  end
+
+  def test_rindex_should_return_character_offset
+    assert_nil @chars.rindex('u')
+    assert_equal 1, @chars.rindex('に')
+    assert_equal 2, @chars.rindex('ち', -2)
+    assert_nil @chars.rindex('ち', -3)
+    assert_equal 6, 'Café périferôl'.mb_chars.rindex('é')
+    assert_equal 13, 'Café périferôl'.mb_chars.rindex(/\w/u)
+  end
+
+  def test_indexed_insert_should_take_character_offsets
+    @chars[2] = 'a'
+    assert_equal 'こにaわ', @chars
+    @chars[2] = 'ηη'
+    assert_equal 'こにηηわ', @chars
+    @chars[3, 2] = 'λλλ'
+    assert_equal 'こにηλλλ', @chars
+    @chars[1, 0] = "λ"
+    assert_equal 'こλにηλλλ', @chars
+    @chars[4..6] = "ηη"
+    assert_equal 'こλにηηη', @chars
+    @chars[/ηη/] = "λλλ"
+    assert_equal 'こλにλλλη', @chars
+    @chars[/(λλ)(.)/, 2] = "α"
+    assert_equal 'こλにλλαη', @chars
+    @chars["α"] = "¢"
+    assert_equal 'こλにλλ¢η', @chars
+    @chars["λλ"] = "ααα"
+    assert_equal 'こλにααα¢η', @chars
+  end
+
+  def test_indexed_insert_should_raise_on_index_overflow
+    before = @chars.to_s
+    assert_raise(IndexError) { @chars[10] = 'a' }
+    assert_raise(IndexError) { @chars[10, 4] = 'a' }
+    assert_raise(IndexError) { @chars[/ii/] = 'a' }
+    assert_raise(IndexError) { @chars[/()/, 10] = 'a' }
+    assert_equal before, @chars
+  end
+
+  def test_indexed_insert_should_raise_on_range_overflow
+    before = @chars.to_s
+    assert_raise(RangeError) { @chars[10..12] = 'a' }
+    assert_equal before, @chars
+  end
+
+  def test_rjust_should_raise_argument_errors_on_bad_arguments
+    assert_raise(ArgumentError) { @chars.rjust(10, '') }
+    assert_raise(ArgumentError) { @chars.rjust }
+  end
+
+  def test_rjust_should_count_characters_instead_of_bytes
+    assert_equal UNICODE_STRING, @chars.rjust(-3)
+    assert_equal UNICODE_STRING, @chars.rjust(0)
+    assert_equal UNICODE_STRING, @chars.rjust(4)
+    assert_equal " #{UNICODE_STRING}", @chars.rjust(5)
+    assert_equal "   #{UNICODE_STRING}", @chars.rjust(7)
+    assert_equal "---#{UNICODE_STRING}", @chars.rjust(7, '-')
+    assert_equal "ααα#{UNICODE_STRING}", @chars.rjust(7, 'α')
+    assert_equal "aba#{UNICODE_STRING}", @chars.rjust(7, 'ab')
+    assert_equal "αηα#{UNICODE_STRING}", @chars.rjust(7, 'αη')
+    assert_equal "αηαη#{UNICODE_STRING}", @chars.rjust(8, 'αη')
+  end
+
+  def test_ljust_should_raise_argument_errors_on_bad_arguments
+    assert_raise(ArgumentError) { @chars.ljust(10, '') }
+    assert_raise(ArgumentError) { @chars.ljust }
+  end
+
+  def test_ljust_should_count_characters_instead_of_bytes
+    assert_equal UNICODE_STRING, @chars.ljust(-3)
+    assert_equal UNICODE_STRING, @chars.ljust(0)
+    assert_equal UNICODE_STRING, @chars.ljust(4)
+    assert_equal "#{UNICODE_STRING} ", @chars.ljust(5)
+    assert_equal "#{UNICODE_STRING}   ", @chars.ljust(7)
+    assert_equal "#{UNICODE_STRING}---", @chars.ljust(7, '-')
+    assert_equal "#{UNICODE_STRING}ααα", @chars.ljust(7, 'α')
+    assert_equal "#{UNICODE_STRING}aba", @chars.ljust(7, 'ab')
+    assert_equal "#{UNICODE_STRING}αηα", @chars.ljust(7, 'αη')
+    assert_equal "#{UNICODE_STRING}αηαη", @chars.ljust(8, 'αη')
+  end
+
+  def test_center_should_raise_argument_errors_on_bad_arguments
+    assert_raise(ArgumentError) { @chars.center(10, '') }
+    assert_raise(ArgumentError) { @chars.center }
+  end
+
+  def test_center_should_count_characters_instead_of_bytes
+    assert_equal UNICODE_STRING, @chars.center(-3)
+    assert_equal UNICODE_STRING, @chars.center(0)
+    assert_equal UNICODE_STRING, @chars.center(4)
+    assert_equal "#{UNICODE_STRING} ", @chars.center(5)
+    assert_equal " #{UNICODE_STRING} ", @chars.center(6)
+    assert_equal " #{UNICODE_STRING}  ", @chars.center(7)
+    assert_equal "--#{UNICODE_STRING}--", @chars.center(8, '-')
+    assert_equal "--#{UNICODE_STRING}---", @chars.center(9, '-')
+    assert_equal "αα#{UNICODE_STRING}αα", @chars.center(8, 'α')
+    assert_equal "αα#{UNICODE_STRING}ααα", @chars.center(9, 'α')
+    assert_equal "a#{UNICODE_STRING}ab", @chars.center(7, 'ab')
+    assert_equal "ab#{UNICODE_STRING}ab", @chars.center(8, 'ab')
+    assert_equal "abab#{UNICODE_STRING}abab", @chars.center(12, 'ab')
+    assert_equal "α#{UNICODE_STRING}αη", @chars.center(7, 'αη')
+    assert_equal "αη#{UNICODE_STRING}αη", @chars.center(8, 'αη')
+  end
+
+  def test_lstrip_strips_whitespace_from_the_left_of_the_string
+    assert_equal UNICODE_STRING, UNICODE_STRING.mb_chars.lstrip
+    assert_equal UNICODE_STRING, (@whitespace + UNICODE_STRING).mb_chars.lstrip
+    assert_equal UNICODE_STRING + @whitespace, (@whitespace + UNICODE_STRING + @whitespace).mb_chars.lstrip
+  end
+
+  def test_rstrip_strips_whitespace_from_the_right_of_the_string
+    assert_equal UNICODE_STRING, UNICODE_STRING.mb_chars.rstrip
+    assert_equal UNICODE_STRING, (UNICODE_STRING + @whitespace).mb_chars.rstrip
+    assert_equal @whitespace + UNICODE_STRING, (@whitespace + UNICODE_STRING + @whitespace).mb_chars.rstrip
+  end
+
+  def test_strip_strips_whitespace
+    assert_equal UNICODE_STRING, UNICODE_STRING.mb_chars.strip
+    assert_equal UNICODE_STRING, (@whitespace + UNICODE_STRING).mb_chars.strip
+    assert_equal UNICODE_STRING, (UNICODE_STRING + @whitespace).mb_chars.strip
+    assert_equal UNICODE_STRING, (@whitespace + UNICODE_STRING + @whitespace).mb_chars.strip
+  end
+
+  def test_stripping_whitespace_leaves_whitespace_within_the_string_intact
+    string_with_whitespace = UNICODE_STRING + @whitespace + UNICODE_STRING
+    assert_equal string_with_whitespace, string_with_whitespace.mb_chars.strip
+    assert_equal string_with_whitespace, string_with_whitespace.mb_chars.lstrip
+    assert_equal string_with_whitespace, string_with_whitespace.mb_chars.rstrip
+  end
+
+  def test_size_returns_characters_instead_of_bytes
+    assert_equal 0, ''.mb_chars.size
+    assert_equal 4, @chars.size
+    assert_equal 4, @chars.length
+    assert_equal 5, ASCII_STRING.mb_chars.size
+  end
+
+  def test_reverse_reverses_characters
+    assert_equal '', ''.mb_chars.reverse
+    assert_equal 'わちにこ', @chars.reverse
+  end
+
+  def test_reverse_should_work_with_normalized_strings
+    str = 'bös'
+    reversed_str = 'söb'
+    assert_equal chars(reversed_str).normalize(:kc), chars(str).normalize(:kc).reverse
+    assert_equal chars(reversed_str).normalize(:c), chars(str).normalize(:c).reverse
+    assert_equal chars(reversed_str).normalize(:d), chars(str).normalize(:d).reverse
+    assert_equal chars(reversed_str).normalize(:kd), chars(str).normalize(:kd).reverse
+    assert_equal chars(reversed_str).decompose, chars(str).decompose.reverse
+    assert_equal chars(reversed_str).compose, chars(str).compose.reverse
+  end
+
+  def test_slice_should_take_character_offsets
+    assert_equal nil, ''.mb_chars.slice(0)
+    assert_equal 'こ', @chars.slice(0)
+    assert_equal 'わ', @chars.slice(3)
+    assert_equal nil, ''.mb_chars.slice(-1..1)
+    assert_equal nil, ''.mb_chars.slice(-1, 1)
+    assert_equal '', ''.mb_chars.slice(0..10)
+    assert_equal 'にちわ', @chars.slice(1..3)
+    assert_equal 'にちわ', @chars.slice(1, 3)
+    assert_equal 'こ', @chars.slice(0, 1)
+    assert_equal 'ちわ', @chars.slice(2..10)
+    assert_equal '', @chars.slice(4..10)
+    assert_equal 'に', @chars.slice(/に/u)
+    assert_equal 'にち', @chars.slice(/に./u)
+    assert_equal nil, @chars.slice(/unknown/u)
+    assert_equal 'にち', @chars.slice(/(にち)/u, 1)
+    assert_equal nil, @chars.slice(/(にち)/u, 2)
+    assert_equal nil, @chars.slice(7..6)
+  end
+
+  def test_slice_bang_returns_sliced_out_substring
+    assert_equal 'にち', @chars.slice!(1..2)
+  end
+
+  def test_slice_bang_removes_the_slice_from_the_receiver
+    chars = 'úüù'.mb_chars
+    chars.slice!(0,2)
+    assert_equal 'ù', chars
+  end
+
+  def test_slice_should_throw_exceptions_on_invalid_arguments
+    assert_raise(TypeError) { @chars.slice(2..3, 1) }
+    assert_raise(TypeError) { @chars.slice(1, 2..3) }
+    assert_raise(ArgumentError) { @chars.slice(1, 1, 1) }
+  end
+
+  def test_ord_should_return_unicode_value_for_first_character
+    assert_equal 12371, @chars.ord
+  end
+
+  def test_upcase_should_upcase_ascii_characters
+    assert_equal '', ''.mb_chars.upcase
+    assert_equal 'ABC', 'aBc'.mb_chars.upcase
+  end
+
+  def test_downcase_should_downcase_ascii_characters
+    assert_equal '', ''.mb_chars.downcase
+    assert_equal 'abc', 'aBc'.mb_chars.downcase
+  end
+
+  def test_swapcase_should_swap_ascii_characters
+    assert_equal '', ''.mb_chars.swapcase
+    assert_equal 'AbC', 'aBc'.mb_chars.swapcase
+  end
+
+  def test_capitalize_should_work_on_ascii_characters
+    assert_equal '', ''.mb_chars.capitalize
+    assert_equal 'Abc', 'abc'.mb_chars.capitalize
+  end
+
+  def test_titleize_should_work_on_ascii_characters
+    assert_equal '', ''.mb_chars.titleize
+    assert_equal 'Abc Abc', 'abc abc'.mb_chars.titleize
+  end
+
+  def test_respond_to_knows_which_methods_the_proxy_responds_to
+    assert ''.mb_chars.respond_to?(:slice) # Defined on Chars
+    assert ''.mb_chars.respond_to?(:capitalize!) # Defined on Chars
+    assert ''.mb_chars.respond_to?(:gsub) # Defined on String
+    assert !''.mb_chars.respond_to?(:undefined_method) # Not defined
+  end
+
+  def test_method_works_for_proxyed_methods
+    assert_equal 'll', 'hello'.mb_chars.method(:slice).call(2..3) # Defined on Chars
+    chars = 'hello'.mb_chars
+    assert_equal 'Hello', chars.method(:capitalize!).call # Defined on Chars
+    assert_equal 'Hello', chars
+    assert_equal 'jello', 'hello'.mb_chars.method(:gsub).call(/h/, 'j') # Defined on String
+    assert_raise(NameError){ ''.mb_chars.method(:undefined_method) } # Not defined
+  end
+
+  def test_acts_like_string
+    assert 'Bambi'.mb_chars.acts_like_string?
+  end
+end
+
+# The default Multibyte Chars proxy has more features than the normal string implementation. Tests
+# for the implementation of these features should run on all Ruby versions and shouldn't be tested
+# through the proxy methods.
+class MultibyteCharsExtrasTest < ActiveSupport::TestCase
+  include MultibyteTestHelpers
+
+  def test_upcase_should_be_unicode_aware
+    assert_equal "АБВГД\0F", chars("аБвгд\0f").upcase
+    assert_equal 'こにちわ', chars('こにちわ').upcase
+  end
+
+  def test_downcase_should_be_unicode_aware
+    assert_equal "абвгд\0f", chars("аБвгд\0F").downcase
+    assert_equal 'こにちわ', chars('こにちわ').downcase
+  end
+
+  def test_swapcase_should_be_unicode_aware
+    assert_equal "аaéÜ\0f", chars("АAÉü\0F").swapcase
+    assert_equal 'こにちわ', chars('こにちわ').swapcase
+  end
+
+  def test_capitalize_should_be_unicode_aware
+    { 'аБвг аБвг' => 'Абвг абвг',
+      'аБвг АБВГ' => 'Абвг абвг',
+      'АБВГ АБВГ' => 'Абвг абвг',
+      '' => '' }.each do |f,t|
+        assert_equal t, chars(f).capitalize
+    end
+  end
+
+  def test_titleize_should_be_unicode_aware
+    assert_equal "Él Que Se Enteró", chars("ÉL QUE SE ENTERÓ").titleize
+    assert_equal "Абвг Абвг", chars("аБвг аБвг").titleize
+  end
+
+  def test_titleize_should_not_affect_characters_that_do_not_case_fold
+    assert_equal "日本語", chars("日本語").titleize
+  end
+
+  def test_limit_should_not_break_on_blank_strings
+    example = chars('')
+    assert_equal example, example.limit(0)
+    assert_equal example, example.limit(1)
+  end
+
+  def test_limit_should_work_on_a_multibyte_string
+    example = chars(UNICODE_STRING)
+    bytesize = UNICODE_STRING.bytesize
+
+    assert_equal UNICODE_STRING, example.limit(bytesize)
+    assert_equal '', example.limit(0)
+    assert_equal '', example.limit(1)
+    assert_equal 'こ', example.limit(3)
+    assert_equal 'こに', example.limit(6)
+    assert_equal 'こに', example.limit(8)
+    assert_equal 'こにち', example.limit(9)
+    assert_equal 'こにちわ', example.limit(50)
+  end
+
+  def test_limit_should_work_on_an_ascii_string
+    ascii = chars(ASCII_STRING)
+    assert_equal ASCII_STRING, ascii.limit(ASCII_STRING.length)
+    assert_equal '', ascii.limit(0)
+    assert_equal 'o', ascii.limit(1)
+    assert_equal 'oh', ascii.limit(2)
+    assert_equal 'ohay', ascii.limit(4)
+    assert_equal 'ohayo', ascii.limit(50)
+  end
+
+  def test_limit_should_keep_under_the_specified_byte_limit
+    example = chars(UNICODE_STRING)
+    (1..UNICODE_STRING.length).each do |limit|
+      assert example.limit(limit).to_s.length <= limit
+    end
+  end
+
+  def test_composition_exclusion_is_set_up_properly
+    # Normalization of DEVANAGARI LETTER QA breaks when composition exclusion isn't used correctly
+    qa = [0x915, 0x93c].pack('U*')
+    assert_equal qa, chars(qa).normalize(:c)
+  end
+
+  # Test for the Public Review Issue #29, bad explanation of composition might lead to a
+  # bad implementation: http://www.unicode.org/review/pr-29.html
+  def test_normalization_C_pri_29
+    [
+      [0x0B47, 0x0300, 0x0B3E],
+      [0x1100, 0x0300, 0x1161]
+    ].map { |c| c.pack('U*') }.each do |c|
+      assert_equal_codepoints c, chars(c).normalize(:c)
+    end
+  end
+
+  def test_normalization_shouldnt_strip_null_bytes
+    null_byte_str = "Test\0test"
+
+    assert_equal null_byte_str, chars(null_byte_str).normalize(:kc)
+    assert_equal null_byte_str, chars(null_byte_str).normalize(:c)
+    assert_equal null_byte_str, chars(null_byte_str).normalize(:d)
+    assert_equal null_byte_str, chars(null_byte_str).normalize(:kd)
+    assert_equal null_byte_str, chars(null_byte_str).decompose
+    assert_equal null_byte_str, chars(null_byte_str).compose
+  end
+
+  def test_simple_normalization
+    comp_str = [
+      44,  # LATIN CAPITAL LETTER D
+      307, # COMBINING DOT ABOVE
+      328, # COMBINING OGONEK
+      323 # COMBINING DOT BELOW
+    ].pack("U*")
+
+    assert_equal_codepoints '', chars('').normalize
+    assert_equal_codepoints [44,105,106,328,323].pack("U*"), chars(comp_str).normalize(:kc).to_s
+    assert_equal_codepoints [44,307,328,323].pack("U*"), chars(comp_str).normalize(:c).to_s
+    assert_equal_codepoints [44,307,110,780,78,769].pack("U*"), chars(comp_str).normalize(:d).to_s
+    assert_equal_codepoints [44,105,106,110,780,78,769].pack("U*"), chars(comp_str).normalize(:kd).to_s
+  end
+
+  def test_should_compute_grapheme_length
+    [
+      ['', 0],
+      ['abc', 3],
+      ['こにちわ', 4],
+      [[0x0924, 0x094D, 0x0930].pack('U*'), 2],
+      [%w(cr lf), 1],
+      [%w(l l), 1],
+      [%w(l v), 1],
+      [%w(l lv), 1],
+      [%w(l lvt), 1],
+      [%w(lv v), 1],
+      [%w(lv t), 1],
+      [%w(v v), 1],
+      [%w(v t), 1],
+      [%w(lvt t), 1],
+      [%w(t t), 1],
+      [%w(n extend), 1],
+      [%w(n n), 2],
+      [%w(n cr lf n), 3],
+      [%w(n l v t), 2]
+    ].each do |input, expected_length|
+      if input.kind_of?(Array)
+        str = string_from_classes(input)
+      else
+        str = input
+      end
+      assert_equal expected_length, chars(str).grapheme_length
+    end
+  end
+
+  def test_tidy_bytes_should_tidy_bytes
+
+    single_byte_cases = {
+      "\x21" => "!",   # Valid ASCII byte, low
+      "\x41" => "A",   # Valid ASCII byte, mid
+      "\x7E" => "~",   # Valid ASCII byte, high
+      "\x80" => "€",   # Continuation byte, low (cp125)
+      "\x94" => "”",   # Continuation byte, mid (cp125)
+      "\x9F" => "Ÿ",   # Continuation byte, high (cp125)
+      "\xC0" => "À",   # Overlong encoding, start of 2-byte sequence, but codepoint < 128
+      "\xC1" => "Á",   # Overlong encoding, start of 2-byte sequence, but codepoint < 128
+      "\xC2" => "Â",   # Start of 2-byte sequence, low
+      "\xC8" => "È",   # Start of 2-byte sequence, mid
+      "\xDF" => "ß",   # Start of 2-byte sequence, high
+      "\xE0" => "à",   # Start of 3-byte sequence, low
+      "\xE8" => "è",   # Start of 3-byte sequence, mid
+      "\xEF" => "ï",   # Start of 3-byte sequence, high
+      "\xF0" => "ð",   # Start of 4-byte sequence
+      "\xF1" => "ñ",   # Unused byte
+      "\xFF" => "ÿ",   # Restricted byte
+      "\x00" => "\x00" # null char
+    }
+
+    single_byte_cases.each do |bad, good|
+      assert_equal good, chars(bad).tidy_bytes.to_s
+      assert_equal "#{good}#{good}", chars("#{bad}#{bad}").tidy_bytes
+      assert_equal "#{good}#{good}#{good}", chars("#{bad}#{bad}#{bad}").tidy_bytes
+      assert_equal "#{good}a", chars("#{bad}a").tidy_bytes
+      assert_equal "#{good}á", chars("#{bad}á").tidy_bytes
+      assert_equal "a#{good}a", chars("a#{bad}a").tidy_bytes
+      assert_equal "á#{good}á", chars("á#{bad}á").tidy_bytes
+      assert_equal "a#{good}", chars("a#{bad}").tidy_bytes
+      assert_equal "á#{good}", chars("á#{bad}").tidy_bytes
+    end
+
+    byte_string = "\270\236\010\210\245"
+    tidy_string = [0xb8, 0x17e, 0x8, 0x2c6, 0xa5].pack('U*')
+    assert_equal_codepoints tidy_string, chars(byte_string).tidy_bytes
+    assert_nothing_raised { chars(byte_string).tidy_bytes.to_s.unpack('U*') }
+
+    # UTF-8 leading byte followed by too few continuation bytes
+    assert_equal_codepoints "\xc3\xb0\xc2\xa5\xc2\xa4\x21", chars("\xf0\xa5\xa4\x21").tidy_bytes
+  end
+
+  def test_tidy_bytes_should_forcibly_tidy_bytes_if_specified
+    byte_string = "\xF0\xA5\xA4\xA4" # valid as both CP-1252 and UTF-8, but with different interpretations.
+    assert_not_equal "𥤤", chars(byte_string).tidy_bytes
+    # Forcible conversion to UTF-8
+    assert_equal "𥤤", chars(byte_string).tidy_bytes(true)
+  end
+
+  def test_class_is_not_forwarded
+    assert_equal BYTE_STRING.dup.mb_chars.class, ActiveSupport::Multibyte::Chars
+  end
+
+  private
+
+  def string_from_classes(classes)
+    # Characters from the character classes as described in UAX #29
+    character_from_class = {
+      :l => 0x1100, :v => 0x1160, :t => 0x11A8, :lv => 0xAC00, :lvt => 0xAC01, :cr => 0x000D, :lf => 0x000A,
+      :extend => 0x094D, :n => 0x64
+    }
+    classes.collect do |k|
+      character_from_class[k.intern]
+    end.pack('U*')
+  end
+end
+
+class MultibyteInternalsTest < ActiveSupport::TestCase
+  include MultibyteTestHelpers
+
+  test "Chars translates a character offset to a byte offset" do
+    example = chars("Puisque c'était son erreur, il m'a aidé")
+    [
+      [0, 0],
+      [3, 3],
+      [12, 11],
+      [14, 13],
+      [41, 39]
+    ].each do |byte_offset, character_offset|
+      assert_equal character_offset, example.send(:translate_offset, byte_offset),
+        "Expected byte offset #{byte_offset} to translate to #{character_offset}"
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/multibyte_conformance.rb b/app/server/vendor/activesupport/test/multibyte_conformance.rb
new file mode 100644
index 0000000..2baf724
--- /dev/null
+++ b/app/server/vendor/activesupport/test/multibyte_conformance.rb
@@ -0,0 +1,129 @@
+# encoding: utf-8
+
+require 'abstract_unit'
+require 'multibyte_test_helpers'
+
+require 'fileutils'
+require 'open-uri'
+require 'tmpdir'
+
+class Downloader
+  def self.download(from, to)
+    unless File.exist?(to)
+      $stderr.puts "Downloading #{from} to #{to}"
+      unless File.exist?(File.dirname(to))
+        system "mkdir -p #{File.dirname(to)}"
+      end
+      open(from) do |source|
+        File.open(to, 'w') do |target|
+          source.each_line do |l|
+            target.write l
+          end
+        end
+       end
+     end
+  end
+end
+
+class MultibyteConformanceTest < ActiveSupport::TestCase
+  include MultibyteTestHelpers
+
+  UNIDATA_URL = "http://www.unicode.org/Public/#{ActiveSupport::Multibyte::Unicode::UNICODE_VERSION}/ucd"
+  UNIDATA_FILE = '/NormalizationTest.txt'
+  CACHE_DIR = File.join(Dir.tmpdir, 'cache')
+
+  def setup
+    FileUtils.mkdir_p(CACHE_DIR)
+    Downloader.download(UNIDATA_URL + UNIDATA_FILE, CACHE_DIR + UNIDATA_FILE)
+    @proxy = ActiveSupport::Multibyte::Chars
+  end
+
+  def test_normalizations_C
+    each_line_of_norm_tests do |*cols|
+      col1, col2, col3, col4, col5, comment = *cols
+
+      # CONFORMANCE:
+      # 1. The following invariants must be true for all conformant implementations
+      #
+      #    NFC
+      #      c2 ==  NFC(c1) ==  NFC(c2) ==  NFC(c3)
+      assert_equal_codepoints col2, @proxy.new(col1).normalize(:c), "Form C - Col 2 has to be NFC(1) - #{comment}"
+      assert_equal_codepoints col2, @proxy.new(col2).normalize(:c), "Form C - Col 2 has to be NFC(2) - #{comment}"
+      assert_equal_codepoints col2, @proxy.new(col3).normalize(:c), "Form C - Col 2 has to be NFC(3) - #{comment}"
+      #
+      #      c4 ==  NFC(c4) ==  NFC(c5)
+      assert_equal_codepoints col4, @proxy.new(col4).normalize(:c), "Form C - Col 4 has to be C(4) - #{comment}"
+      assert_equal_codepoints col4, @proxy.new(col5).normalize(:c), "Form C - Col 4 has to be C(5) - #{comment}"
+    end
+  end
+
+  def test_normalizations_D
+    each_line_of_norm_tests do |*cols|
+      col1, col2, col3, col4, col5, comment = *cols
+      #
+      #    NFD
+      #      c3 ==  NFD(c1) ==  NFD(c2) ==  NFD(c3)
+      assert_equal_codepoints col3, @proxy.new(col1).normalize(:d), "Form D - Col 3 has to be NFD(1) - #{comment}"
+      assert_equal_codepoints col3, @proxy.new(col2).normalize(:d), "Form D - Col 3 has to be NFD(2) - #{comment}"
+      assert_equal_codepoints col3, @proxy.new(col3).normalize(:d), "Form D - Col 3 has to be NFD(3) - #{comment}"
+      #      c5 ==  NFD(c4) ==  NFD(c5)
+      assert_equal_codepoints col5, @proxy.new(col4).normalize(:d), "Form D - Col 5 has to be NFD(4) - #{comment}"
+      assert_equal_codepoints col5, @proxy.new(col5).normalize(:d), "Form D - Col 5 has to be NFD(5) - #{comment}"
+    end
+  end
+
+  def test_normalizations_KC
+    each_line_of_norm_tests do | *cols |
+      col1, col2, col3, col4, col5, comment = *cols
+      #
+      #    NFKC
+      #      c4 == NFKC(c1) == NFKC(c2) == NFKC(c3) == NFKC(c4) == NFKC(c5)
+      assert_equal_codepoints col4, @proxy.new(col1).normalize(:kc), "Form D - Col 4 has to be NFKC(1) - #{comment}"
+      assert_equal_codepoints col4, @proxy.new(col2).normalize(:kc), "Form D - Col 4 has to be NFKC(2) - #{comment}"
+      assert_equal_codepoints col4, @proxy.new(col3).normalize(:kc), "Form D - Col 4 has to be NFKC(3) - #{comment}"
+      assert_equal_codepoints col4, @proxy.new(col4).normalize(:kc), "Form D - Col 4 has to be NFKC(4) - #{comment}"
+      assert_equal_codepoints col4, @proxy.new(col5).normalize(:kc), "Form D - Col 4 has to be NFKC(5) - #{comment}"
+    end
+  end
+
+  def test_normalizations_KD
+    each_line_of_norm_tests do | *cols |
+      col1, col2, col3, col4, col5, comment = *cols
+      #
+      #    NFKD
+      #      c5 == NFKD(c1) == NFKD(c2) == NFKD(c3) == NFKD(c4) == NFKD(c5)
+      assert_equal_codepoints col5, @proxy.new(col1).normalize(:kd), "Form KD - Col 5 has to be NFKD(1) - #{comment}"
+      assert_equal_codepoints col5, @proxy.new(col2).normalize(:kd), "Form KD - Col 5 has to be NFKD(2) - #{comment}"
+      assert_equal_codepoints col5, @proxy.new(col3).normalize(:kd), "Form KD - Col 5 has to be NFKD(3) - #{comment}"
+      assert_equal_codepoints col5, @proxy.new(col4).normalize(:kd), "Form KD - Col 5 has to be NFKD(4) - #{comment}"
+      assert_equal_codepoints col5, @proxy.new(col5).normalize(:kd), "Form KD - Col 5 has to be NFKD(5) - #{comment}"
+    end
+  end
+
+  protected
+    def each_line_of_norm_tests(&block)
+      lines = 0
+      max_test_lines = 0 # Don't limit below 38, because that's the header of the testfile
+      File.open(File.join(CACHE_DIR, UNIDATA_FILE), 'r') do | f |
+        until f.eof? || (max_test_lines > 38 and lines > max_test_lines)
+          lines += 1
+          line = f.gets.chomp!
+          next if (line.empty? || line =~ /^\#/)
+
+          cols, comment = line.split("#")
+          cols = cols.split(";").map{|e| e.strip}.reject{|e| e.empty? }
+          next unless cols.length == 5
+
+          # codepoints are in hex in the test suite, pack wants them as integers
+          cols.map!{|c| c.split.map{|codepoint| codepoint.to_i(16)}.pack("U*") }
+          cols << comment
+
+          yield(*cols)
+        end
+      end
+    end
+
+    def inspect_codepoints(str)
+      str.to_s.unpack("U*").map{|cp| cp.to_s(16) }.join(' ')
+    end
+end
\ No newline at end of file
diff --git a/app/server/vendor/activesupport/test/multibyte_test_helpers.rb b/app/server/vendor/activesupport/test/multibyte_test_helpers.rb
new file mode 100644
index 0000000..fdbe2f4
--- /dev/null
+++ b/app/server/vendor/activesupport/test/multibyte_test_helpers.rb
@@ -0,0 +1,19 @@
+# encoding: utf-8
+
+module MultibyteTestHelpers
+  UNICODE_STRING = 'こにちわ'
+  ASCII_STRING = 'ohayo'
+  BYTE_STRING = "\270\236\010\210\245".force_encoding("ASCII-8BIT")
+
+  def chars(str)
+    ActiveSupport::Multibyte::Chars.new(str)
+  end
+
+  def inspect_codepoints(str)
+    str.to_s.unpack("U*").map{|cp| cp.to_s(16) }.join(' ')
+  end
+
+  def assert_equal_codepoints(expected, actual, message=nil)
+    assert_equal(inspect_codepoints(expected), inspect_codepoints(actual), message)
+  end
+end
diff --git a/app/server/vendor/activesupport/test/multibyte_unicode_database_test.rb b/app/server/vendor/activesupport/test/multibyte_unicode_database_test.rb
new file mode 100644
index 0000000..bec65da
--- /dev/null
+++ b/app/server/vendor/activesupport/test/multibyte_unicode_database_test.rb
@@ -0,0 +1,26 @@
+# encoding: utf-8
+require 'abstract_unit'
+
+
+class MultibyteUnicodeDatabaseTest < ActiveSupport::TestCase
+
+  include ActiveSupport::Multibyte::Unicode
+
+  def setup
+    @ucd = UnicodeDatabase.new
+  end
+
+  UnicodeDatabase::ATTRIBUTES.each do |attribute|
+    define_method "test_lazy_loading_on_attribute_access_of_#{attribute}" do
+      @ucd.expects(:load)
+      @ucd.send(attribute)
+    end
+  end
+
+  def test_load
+    @ucd.load
+    UnicodeDatabase::ATTRIBUTES.each do |attribute|
+      assert @ucd.send(attribute).length > 1
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/notifications/evented_notification_test.rb b/app/server/vendor/activesupport/test/notifications/evented_notification_test.rb
new file mode 100644
index 0000000..f690ad4
--- /dev/null
+++ b/app/server/vendor/activesupport/test/notifications/evented_notification_test.rb
@@ -0,0 +1,87 @@
+require 'abstract_unit'
+
+module ActiveSupport
+  module Notifications
+    class EventedTest < ActiveSupport::TestCase
+      class Listener
+        attr_reader :events
+
+        def initialize
+          @events   = []
+        end
+
+        def start(name, id, payload)
+          @events << [:start, name, id, payload]
+        end
+
+        def finish(name, id, payload)
+          @events << [:finish, name, id, payload]
+        end
+      end
+
+      class ListenerWithTimedSupport < Listener
+        def call(name, start, finish, id, payload)
+          @events << [:call, name, start, finish, id, payload]
+        end
+      end
+
+      def test_evented_listener
+        notifier = Fanout.new
+        listener = Listener.new
+        notifier.subscribe 'hi', listener
+        notifier.start  'hi', 1, {}
+        notifier.start  'hi', 2, {}
+        notifier.finish 'hi', 2, {}
+        notifier.finish 'hi', 1, {}
+
+        assert_equal 4, listener.events.length
+        assert_equal [
+          [:start, 'hi', 1, {}],
+          [:start, 'hi', 2, {}],
+          [:finish, 'hi', 2, {}],
+          [:finish, 'hi', 1, {}],
+        ], listener.events
+      end
+
+      def test_evented_listener_no_events
+        notifier = Fanout.new
+        listener = Listener.new
+        notifier.subscribe 'hi', listener
+        notifier.start  'world', 1, {}
+        assert_equal 0, listener.events.length
+      end
+
+      def test_listen_to_everything
+        notifier = Fanout.new
+        listener = Listener.new
+        notifier.subscribe nil, listener
+        notifier.start  'hello', 1, {}
+        notifier.start  'world', 1, {}
+        notifier.finish  'world', 1, {}
+        notifier.finish  'hello', 1, {}
+
+        assert_equal 4, listener.events.length
+        assert_equal [
+          [:start,  'hello', 1, {}],
+          [:start,  'world', 1, {}],
+          [:finish,  'world', 1, {}],
+          [:finish,  'hello', 1, {}],
+        ], listener.events
+      end
+
+      def test_evented_listener_priority
+        notifier = Fanout.new
+        listener = ListenerWithTimedSupport.new
+        notifier.subscribe 'hi', listener
+
+        notifier.start 'hi', 1, {}
+        notifier.finish 'hi', 1, {}
+
+        assert_equal [
+          [:start, 'hi', 1, {}],
+          [:finish, 'hi', 1, {}]
+        ], listener.events
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/notifications/instrumenter_test.rb b/app/server/vendor/activesupport/test/notifications/instrumenter_test.rb
new file mode 100644
index 0000000..f46e96f
--- /dev/null
+++ b/app/server/vendor/activesupport/test/notifications/instrumenter_test.rb
@@ -0,0 +1,58 @@
+require 'abstract_unit'
+require 'active_support/notifications/instrumenter'
+
+module ActiveSupport
+  module Notifications
+    class InstrumenterTest < ActiveSupport::TestCase
+      class TestNotifier
+        attr_reader :starts, :finishes
+
+        def initialize
+          @starts   = []
+          @finishes = []
+        end
+
+        def start(*args);  @starts << args; end
+        def finish(*args); @finishes << args; end
+      end
+
+      attr_reader :instrumenter, :notifier, :payload
+
+      def setup
+        super
+        @notifier     = TestNotifier.new
+        @instrumenter = Instrumenter.new @notifier
+        @payload      =  { :foo => Object.new }
+      end
+
+      def test_instrument
+        called  = false
+        instrumenter.instrument("foo", payload) {
+          called = true
+        }
+
+        assert called
+      end
+
+      def test_instrument_yields_the_payload_for_further_modification
+        assert_equal 2, instrumenter.instrument("awesome") { |p| p[:result] = 1 + 1 }
+        assert_equal 1, notifier.finishes.size
+        name, _, payload = notifier.finishes.first
+        assert_equal "awesome", name
+        assert_equal Hash[:result => 2], payload
+      end
+
+      def test_start
+        instrumenter.start("foo", payload)
+        assert_equal [["foo", instrumenter.id, payload]], notifier.starts
+        assert_predicate notifier.finishes, :empty?
+      end
+
+      def test_finish
+        instrumenter.finish("foo", payload)
+        assert_equal [["foo", instrumenter.id, payload]], notifier.finishes
+        assert_predicate notifier.starts, :empty?
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/notifications_test.rb b/app/server/vendor/activesupport/test/notifications_test.rb
new file mode 100644
index 0000000..f729f0a
--- /dev/null
+++ b/app/server/vendor/activesupport/test/notifications_test.rb
@@ -0,0 +1,266 @@
+require 'abstract_unit'
+require 'active_support/core_ext/module/delegation'
+
+module Notifications
+  class TestCase < ActiveSupport::TestCase
+    def setup
+      @old_notifier = ActiveSupport::Notifications.notifier
+      @notifier = ActiveSupport::Notifications::Fanout.new
+      ActiveSupport::Notifications.notifier = @notifier
+      @events = []
+      @named_events = []
+      @subscription = @notifier.subscribe { |*args| @events << event(*args) }
+      @named_subscription = @notifier.subscribe("named.subscription") { |*args| @named_events << event(*args) }
+    end
+
+    def teardown
+      ActiveSupport::Notifications.notifier = @old_notifier
+    end
+
+  private
+
+    def event(*args)
+      ActiveSupport::Notifications::Event.new(*args)
+    end
+  end
+
+  class SubscribedTest < TestCase
+    def test_subscribed
+      name     = "foo"
+      name2    = name * 2
+      expected = [name, name]
+
+      events   = []
+      callback = lambda {|*_| events << _.first}
+      ActiveSupport::Notifications.subscribed(callback, name) do
+        ActiveSupport::Notifications.instrument(name)
+        ActiveSupport::Notifications.instrument(name2)
+        ActiveSupport::Notifications.instrument(name)
+      end
+      assert_equal expected, events
+
+      ActiveSupport::Notifications.instrument(name)
+      assert_equal expected, events
+    end
+  end
+
+  class UnsubscribeTest < TestCase
+    def test_unsubscribing_removes_a_subscription
+      @notifier.publish :foo
+      @notifier.wait
+      assert_equal [[:foo]], @events
+      @notifier.unsubscribe(@subscription)
+      @notifier.publish :foo
+      @notifier.wait
+      assert_equal [[:foo]], @events
+    end
+
+    def test_unsubscribing_by_name_removes_a_subscription
+      @notifier.publish "named.subscription", :foo
+      @notifier.wait
+      assert_equal [["named.subscription", :foo]], @named_events
+      @notifier.unsubscribe("named.subscription")
+      @notifier.publish "named.subscription", :foo
+      @notifier.wait
+      assert_equal [["named.subscription", :foo]], @named_events
+    end
+
+    def test_unsubscribing_by_name_leaves_the_other_subscriptions
+      @notifier.publish "named.subscription", :foo
+      @notifier.wait
+      assert_equal [["named.subscription", :foo]], @events
+      @notifier.unsubscribe("named.subscription")
+      @notifier.publish "named.subscription", :foo
+      @notifier.wait
+      assert_equal [["named.subscription", :foo], ["named.subscription", :foo]], @events
+    end
+
+  private
+    def event(*args)
+      args
+    end
+  end
+
+  class TestSubscriber
+    attr_reader :starts, :finishes, :publishes
+
+    def initialize
+      @starts    = []
+      @finishes  = []
+      @publishes = []
+    end
+
+    def start(*args);  @starts << args; end
+    def finish(*args); @finishes << args; end
+    def publish(*args); @publishes << args; end
+  end
+
+  class SyncPubSubTest < TestCase
+    def test_events_are_published_to_a_listener
+      @notifier.publish :foo
+      @notifier.wait
+      assert_equal [[:foo]], @events
+    end
+
+    def test_publishing_multiple_times_works
+      @notifier.publish :foo
+      @notifier.publish :foo
+      @notifier.wait
+      assert_equal [[:foo], [:foo]], @events
+    end
+
+    def test_publishing_after_a_new_subscribe_works
+      @notifier.publish :foo
+      @notifier.publish :foo
+
+      @notifier.subscribe("not_existent") do |*args|
+        @events << ActiveSupport::Notifications::Event.new(*args)
+      end
+
+      @notifier.publish :foo
+      @notifier.publish :foo
+      @notifier.wait
+
+      assert_equal [[:foo]] * 4, @events
+    end
+
+    def test_log_subscriber_with_string
+      events = []
+      @notifier.subscribe('1') { |*args| events << args }
+
+      @notifier.publish '1'
+      @notifier.publish '1.a'
+      @notifier.publish 'a.1'
+      @notifier.wait
+
+      assert_equal [['1']], events
+    end
+
+    def test_log_subscriber_with_pattern
+      events = []
+      @notifier.subscribe(/\d/) { |*args| events << args }
+
+      @notifier.publish '1'
+      @notifier.publish 'a.1'
+      @notifier.publish '1.a'
+      @notifier.wait
+
+      assert_equal [['1'], ['a.1'], ['1.a']], events
+    end
+
+    def test_multiple_log_subscribers
+      @another = []
+      @notifier.subscribe { |*args| @another << args }
+      @notifier.publish :foo
+      @notifier.wait
+
+      assert_equal [[:foo]], @events
+      assert_equal [[:foo]], @another
+    end
+
+    def test_publish_with_subscriber
+      subscriber = TestSubscriber.new
+      @notifier.subscribe nil, subscriber
+      @notifier.publish :foo
+
+      assert_equal [[:foo]], subscriber.publishes
+    end
+
+    private
+      def event(*args)
+        args
+      end
+  end
+
+  class InstrumentationTest < TestCase
+    delegate :instrument, :to => ActiveSupport::Notifications
+
+    def test_instrument_returns_block_result
+      assert_equal 2, instrument(:awesome) { 1 + 1 }
+    end
+
+    def test_instrument_yields_the_payload_for_further_modification
+      assert_equal 2, instrument(:awesome) { |p| p[:result] = 1 + 1 }
+      assert_equal 1, @events.size
+      assert_equal :awesome, @events.first.name
+      assert_equal Hash[:result => 2], @events.first.payload
+    end
+
+    def test_instrumenter_exposes_its_id
+      assert_equal 20, ActiveSupport::Notifications.instrumenter.id.size
+    end
+
+    def test_nested_events_can_be_instrumented
+      instrument(:awesome, :payload => "notifications") do
+        instrument(:wot, :payload => "child") do
+          1 + 1
+        end
+
+        assert_equal 1, @events.size
+        assert_equal :wot, @events.first.name
+        assert_equal Hash[:payload => "child"], @events.first.payload
+      end
+
+      assert_equal 2, @events.size
+      assert_equal :awesome, @events.last.name
+      assert_equal Hash[:payload => "notifications"], @events.last.payload
+    end
+
+    def test_instrument_publishes_when_exception_is_raised
+      begin
+        instrument(:awesome, :payload => "notifications") do
+          raise "FAIL"
+        end
+      rescue RuntimeError => e
+        assert_equal "FAIL", e.message
+      end
+
+      assert_equal 1, @events.size
+      assert_equal Hash[:payload => "notifications",
+        :exception => ["RuntimeError", "FAIL"]], @events.last.payload
+    end
+
+    def test_event_is_pushed_even_without_block
+      instrument(:awesome, :payload => "notifications")
+      assert_equal 1, @events.size
+      assert_equal :awesome, @events.last.name
+      assert_equal Hash[:payload => "notifications"], @events.last.payload
+    end
+  end
+
+  class EventTest < TestCase
+    def test_events_are_initialized_with_details
+      time = Time.now
+      event = event(:foo, time, time + 0.01, random_id, {})
+
+      assert_equal    :foo, event.name
+      assert_equal    time, event.time
+      assert_in_delta 10.0, event.duration, 0.00001
+    end
+
+    def test_events_consumes_information_given_as_payload
+      event = event(:foo, Time.now, Time.now + 1, random_id, :payload => :bar)
+      assert_equal Hash[:payload => :bar], event.payload
+    end
+
+    def test_event_is_parent_based_on_children
+      time = Time.utc(2009, 01, 01, 0, 0, 1)
+
+      parent    = event(:foo, Time.utc(2009), Time.utc(2009) + 100, random_id, {})
+      child     = event(:foo, time, time + 10, random_id, {})
+      not_child = event(:foo, time, time + 100, random_id, {})
+
+      parent.children << child
+
+      assert parent.parent_of?(child)
+      assert !child.parent_of?(parent)
+      assert !parent.parent_of?(not_child)
+      assert !not_child.parent_of?(parent)
+    end
+
+    protected
+      def random_id
+        @random_id ||= SecureRandom.hex(10)
+      end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/number_helper_i18n_test.rb b/app/server/vendor/activesupport/test/number_helper_i18n_test.rb
new file mode 100644
index 0000000..65aecec
--- /dev/null
+++ b/app/server/vendor/activesupport/test/number_helper_i18n_test.rb
@@ -0,0 +1,156 @@
+require 'abstract_unit'
+require 'active_support/number_helper'
+
+module ActiveSupport
+  class NumberHelperI18nTest < ActiveSupport::TestCase
+    include ActiveSupport::NumberHelper
+
+    def setup
+      I18n.backend.store_translations 'ts',
+        :number => {
+        :format => { :precision => 3, :delimiter => ',', :separator => '.', :significant => false, :strip_insignificant_zeros => false },
+        :currency => { :format => { :unit => '&$', :format => '%u - %n', :negative_format => '(%u - %n)', :precision => 2 } },
+        :human => {
+          :format => {
+            :precision => 2,
+            :significant => true,
+            :strip_insignificant_zeros => true
+          },
+          :storage_units => {
+            :format => "%n %u",
+            :units => {
+              :byte => "b",
+              :kb => "k"
+            }
+          },
+          :decimal_units => {
+            :format => "%n %u",
+            :units => {
+              :deci => {:one => "Tenth", :other => "Tenths"},
+              :unit =>  "u",
+              :ten => {:one => "Ten", :other => "Tens"},
+              :thousand => "t",
+              :million => "m",
+              :billion =>"b",
+              :trillion =>"t" ,
+              :quadrillion =>"q"
+            }
+          }
+        },
+        :percentage => { :format => {:delimiter => '', :precision => 2, :strip_insignificant_zeros => true} },
+        :precision => { :format => {:delimiter => '', :significant => true} }
+      },
+      :custom_units_for_number_to_human => {:mili => "mm", :centi => "cm", :deci => "dm", :unit => "m", :ten => "dam", :hundred => "hm", :thousand => "km"}
+    end
+
+    def test_number_to_i18n_currency
+      assert_equal("&$ - 10.00", number_to_currency(10, :locale => 'ts'))
+      assert_equal("(&$ - 10.00)", number_to_currency(-10, :locale => 'ts'))
+      assert_equal("-10.00 - &$", number_to_currency(-10, :locale => 'ts', :format => "%n - %u"))
+    end
+
+    def test_number_to_currency_with_empty_i18n_store
+      I18n.backend.store_translations 'empty', {}
+
+      assert_equal("$10.00", number_to_currency(10, :locale => 'empty'))
+      assert_equal("-$10.00", number_to_currency(-10, :locale => 'empty'))
+    end
+
+    def test_locale_default_format_has_precedence_over_helper_defaults
+      I18n.backend.store_translations 'ts',
+        { :number => { :format => { :separator => ";" } } }
+
+      assert_equal("&$ - 10;00", number_to_currency(10, :locale => 'ts'))
+    end
+
+    def test_number_to_currency_without_currency_negative_format
+      I18n.backend.store_translations 'no_negative_format', :number => {
+        :currency => { :format => { :unit => '@', :format => '%n %u' } }
+      }
+
+      assert_equal("-10.00 @", number_to_currency(-10, :locale => 'no_negative_format'))
+    end
+
+    def test_number_with_i18n_precision
+      #Delimiter was set to ""
+      assert_equal("10000", number_to_rounded(10000, :locale => 'ts'))
+
+      #Precision inherited and significant was set
+      assert_equal("1.00", number_to_rounded(1.0, :locale => 'ts'))
+    end
+
+    def test_number_with_i18n_precision_and_empty_i18n_store
+      I18n.backend.store_translations 'empty', {}
+
+      assert_equal("123456789.123", number_to_rounded(123456789.123456789, :locale => 'empty'))
+      assert_equal("1.000", number_to_rounded(1.0000, :locale => 'empty'))
+    end
+
+    def test_number_with_i18n_delimiter
+      #Delimiter "," and separator "."
+      assert_equal("1,000,000.234", number_to_delimited(1000000.234, :locale => 'ts'))
+    end
+
+    def test_number_with_i18n_delimiter_and_empty_i18n_store
+      I18n.backend.store_translations 'empty', {}
+
+      assert_equal("1,000,000.234", number_to_delimited(1000000.234, :locale => 'empty'))
+    end
+
+    def test_number_to_i18n_percentage
+      # to see if strip_insignificant_zeros is true
+      assert_equal("1%", number_to_percentage(1, :locale => 'ts'))
+      # precision is 2, significant should be inherited
+      assert_equal("1.24%", number_to_percentage(1.2434, :locale => 'ts'))
+      # no delimiter
+      assert_equal("12434%", number_to_percentage(12434, :locale => 'ts'))
+    end
+
+    def test_number_to_i18n_percentage_and_empty_i18n_store
+      I18n.backend.store_translations 'empty', {}
+
+      assert_equal("1.000%", number_to_percentage(1, :locale => 'empty'))
+      assert_equal("1.243%", number_to_percentage(1.2434, :locale => 'empty'))
+      assert_equal("12434.000%", number_to_percentage(12434, :locale => 'empty'))
+    end
+
+    def test_number_to_i18n_human_size
+      #b for bytes and k for kbytes
+      assert_equal("2 k", number_to_human_size(2048, :locale => 'ts'))
+      assert_equal("42 b", number_to_human_size(42, :locale => 'ts'))
+    end
+
+    def test_number_to_i18n_human_size_with_empty_i18n_store
+      I18n.backend.store_translations 'empty', {}
+
+      assert_equal("2 KB", number_to_human_size(2048, :locale => 'empty'))
+      assert_equal("42 Bytes", number_to_human_size(42, :locale => 'empty'))
+    end
+
+    def test_number_to_human_with_default_translation_scope
+      #Using t for thousand
+      assert_equal "2 t", number_to_human(2000, :locale => 'ts')
+      #Significant was set to true with precision 2, using b for billion
+      assert_equal "1.2 b", number_to_human(1234567890, :locale => 'ts')
+      #Using pluralization (Ten/Tens and Tenth/Tenths)
+      assert_equal "1 Tenth", number_to_human(0.1, :locale => 'ts')
+      assert_equal "1.3 Tenth", number_to_human(0.134, :locale => 'ts')
+      assert_equal "2 Tenths", number_to_human(0.2, :locale => 'ts')
+      assert_equal "1 Ten", number_to_human(10, :locale => 'ts')
+      assert_equal "1.2 Ten", number_to_human(12, :locale => 'ts')
+      assert_equal "2 Tens", number_to_human(20, :locale => 'ts')
+    end
+
+    def test_number_to_human_with_empty_i18n_store
+      I18n.backend.store_translations 'empty', {}
+
+      assert_equal "2 Thousand", number_to_human(2000, :locale => 'empty')
+      assert_equal "1.23 Billion", number_to_human(1234567890, :locale => 'empty')
+    end
+
+    def test_number_to_human_with_custom_translation_scope
+      #Significant was set to true with precision 2, with custom translated units
+      assert_equal "4.3 cm", number_to_human(0.0432, :locale => 'ts', :units => :custom_units_for_number_to_human)
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/number_helper_test.rb b/app/server/vendor/activesupport/test/number_helper_test.rb
new file mode 100644
index 0000000..9bdb920
--- /dev/null
+++ b/app/server/vendor/activesupport/test/number_helper_test.rb
@@ -0,0 +1,391 @@
+require 'abstract_unit'
+require 'active_support/number_helper'
+
+module ActiveSupport
+  module NumberHelper
+    class NumberHelperTest < ActiveSupport::TestCase
+
+      class TestClassWithInstanceNumberHelpers
+        include ActiveSupport::NumberHelper
+      end
+
+      class TestClassWithClassNumberHelpers
+        extend ActiveSupport::NumberHelper
+      end
+
+      def setup
+        @instance_with_helpers = TestClassWithInstanceNumberHelpers.new
+      end
+
+      def kilobytes(number)
+        number * 1024
+      end
+
+      def megabytes(number)
+        kilobytes(number) * 1024
+      end
+
+      def gigabytes(number)
+        megabytes(number) * 1024
+      end
+
+      def terabytes(number)
+        gigabytes(number) * 1024
+      end
+
+      def test_number_to_phone
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal("555-1234", number_helper.number_to_phone(5551234))
+          assert_equal("800-555-1212", number_helper.number_to_phone(8005551212))
+          assert_equal("(800) 555-1212", number_helper.number_to_phone(8005551212, {:area_code => true}))
+          assert_equal("", number_helper.number_to_phone("", {:area_code => true}))
+          assert_equal("800 555 1212", number_helper.number_to_phone(8005551212, {:delimiter => " "}))
+          assert_equal("(800) 555-1212 x 123", number_helper.number_to_phone(8005551212, {:area_code => true, :extension => 123}))
+          assert_equal("800-555-1212", number_helper.number_to_phone(8005551212, :extension => "  "))
+          assert_equal("555.1212", number_helper.number_to_phone(5551212, :delimiter => '.'))
+          assert_equal("800-555-1212", number_helper.number_to_phone("8005551212"))
+          assert_equal("+1-800-555-1212", number_helper.number_to_phone(8005551212, :country_code => 1))
+          assert_equal("+18005551212", number_helper.number_to_phone(8005551212, :country_code => 1, :delimiter => ''))
+          assert_equal("22-555-1212", number_helper.number_to_phone(225551212))
+          assert_equal("+45-22-555-1212", number_helper.number_to_phone(225551212, :country_code => 45))
+        end
+      end
+
+      def test_number_to_currency
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal("$1,234,567,890.50", number_helper.number_to_currency(1234567890.50))
+          assert_equal("$1,234,567,890.51", number_helper.number_to_currency(1234567890.506))
+          assert_equal("-$1,234,567,890.50", number_helper.number_to_currency(-1234567890.50))
+          assert_equal("-$ 1,234,567,890.50", number_helper.number_to_currency(-1234567890.50, {:format => "%u %n"}))
+          assert_equal("($1,234,567,890.50)", number_helper.number_to_currency(-1234567890.50, {:negative_format => "(%u%n)"}))
+          assert_equal("$1,234,567,892", number_helper.number_to_currency(1234567891.50, {:precision => 0}))
+          assert_equal("$1,234,567,890.5", number_helper.number_to_currency(1234567890.50, {:precision => 1}))
+          assert_equal("£1234567890,50", number_helper.number_to_currency(1234567890.50, {:unit => "£", :separator => ",", :delimiter => ""}))
+          assert_equal("$1,234,567,890.50", number_helper.number_to_currency("1234567890.50"))
+          assert_equal("1,234,567,890.50 Kč", number_helper.number_to_currency("1234567890.50", {:unit => "Kč", :format => "%n %u"}))
+          assert_equal("1,234,567,890.50 - Kč", number_helper.number_to_currency("-1234567890.50", {:unit => "Kč", :format => "%n %u", :negative_format => "%n - %u"}))
+          assert_equal("0.00", number_helper.number_to_currency(+0.0, {:unit => "", :negative_format => "(%n)"}))
+          assert_equal("(0.00)", number_helper.number_to_currency(-0.0, {:unit => "", :negative_format => "(%n)"}))
+        end
+      end
+
+      def test_number_to_percentage
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal("100.000%", number_helper.number_to_percentage(100))
+          assert_equal("100%", number_helper.number_to_percentage(100, {:precision => 0}))
+          assert_equal("302.06%", number_helper.number_to_percentage(302.0574, {:precision => 2}))
+          assert_equal("100.000%", number_helper.number_to_percentage("100"))
+          assert_equal("1000.000%", number_helper.number_to_percentage("1000"))
+          assert_equal("123.4%", number_helper.number_to_percentage(123.400, :precision => 3, :strip_insignificant_zeros => true))
+          assert_equal("1.000,000%", number_helper.number_to_percentage(1000, :delimiter => '.', :separator => ','))
+          assert_equal("1000.000  %", number_helper.number_to_percentage(1000, :format => "%n  %"))
+          assert_equal("98a%", number_helper.number_to_percentage("98a"))
+          assert_equal("NaN%", number_helper.number_to_percentage(Float::NAN))
+          assert_equal("Inf%", number_helper.number_to_percentage(Float::INFINITY))
+        end
+      end
+
+      def test_to_delimited
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal("12,345,678", number_helper.number_to_delimited(12345678))
+          assert_equal("0", number_helper.number_to_delimited(0))
+          assert_equal("123", number_helper.number_to_delimited(123))
+          assert_equal("123,456", number_helper.number_to_delimited(123456))
+          assert_equal("123,456.78", number_helper.number_to_delimited(123456.78))
+          assert_equal("123,456.789", number_helper.number_to_delimited(123456.789))
+          assert_equal("123,456.78901", number_helper.number_to_delimited(123456.78901))
+          assert_equal("123,456,789.78901", number_helper.number_to_delimited(123456789.78901))
+          assert_equal("0.78901", number_helper.number_to_delimited(0.78901))
+          assert_equal("123,456.78", number_helper.number_to_delimited("123456.78"))
+        end
+      end
+
+      def test_to_delimited_with_options_hash
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal '12 345 678', number_helper.number_to_delimited(12345678, :delimiter => ' ')
+          assert_equal '12,345,678-05', number_helper.number_to_delimited(12345678.05, :separator => '-')
+          assert_equal '12.345.678,05', number_helper.number_to_delimited(12345678.05, :separator => ',', :delimiter => '.')
+        end
+      end
+
+      def test_to_rounded
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal("-111.235", number_helper.number_to_rounded(-111.2346))
+          assert_equal("111.235", number_helper.number_to_rounded(111.2346))
+          assert_equal("31.83", number_helper.number_to_rounded(31.825, :precision => 2))
+          assert_equal("111.23", number_helper.number_to_rounded(111.2346, :precision => 2))
+          assert_equal("111.00", number_helper.number_to_rounded(111, :precision => 2))
+          assert_equal("111.235", number_helper.number_to_rounded("111.2346"))
+          assert_equal("31.83", number_helper.number_to_rounded("31.825", :precision => 2))
+          assert_equal("3268", number_helper.number_to_rounded((32.6751 * 100.00), :precision => 0))
+          assert_equal("112", number_helper.number_to_rounded(111.50, :precision => 0))
+          assert_equal("1234567892", number_helper.number_to_rounded(1234567891.50, :precision => 0))
+          assert_equal("0", number_helper.number_to_rounded(0, :precision => 0))
+          assert_equal("0.00100", number_helper.number_to_rounded(0.001, :precision => 5))
+          assert_equal("0.001", number_helper.number_to_rounded(0.00111, :precision => 3))
+          assert_equal("10.00", number_helper.number_to_rounded(9.995, :precision => 2))
+          assert_equal("11.00", number_helper.number_to_rounded(10.995, :precision => 2))
+          assert_equal("0.00", number_helper.number_to_rounded(-0.001, :precision => 2))
+
+          assert_equal("111.23460000000000000000", number_helper.number_to_rounded(111.2346, :precision => 20))
+          assert_equal("111.23460000000000000000", number_helper.number_to_rounded(Rational(1112346, 10000), :precision => 20))
+          assert_equal("111.23460000000000000000", number_helper.number_to_rounded('111.2346', :precision => 20))
+          assert_equal("111.23460000000000000000", number_helper.number_to_rounded(BigDecimal(111.2346, Float::DIG), :precision => 20))
+          assert_equal("111.2346" + "0"*96, number_helper.number_to_rounded('111.2346', :precision => 100))
+        end
+      end
+
+      def test_to_rounded_with_custom_delimiter_and_separator
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal '31,83',       number_helper.number_to_rounded(31.825, :precision => 2, :separator => ',')
+          assert_equal '1.231,83',    number_helper.number_to_rounded(1231.825, :precision => 2, :separator => ',', :delimiter => '.')
+        end
+      end
+
+      def test_to_rounded_with_significant_digits
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal "124000", number_helper.number_to_rounded(123987, :precision => 3, :significant => true)
+          assert_equal "120000000", number_helper.number_to_rounded(123987876, :precision => 2, :significant => true )
+          assert_equal "40000", number_helper.number_to_rounded("43523", :precision => 1, :significant => true )
+          assert_equal "9775", number_helper.number_to_rounded(9775, :precision => 4, :significant => true )
+          assert_equal "5.4", number_helper.number_to_rounded(5.3923, :precision => 2, :significant => true )
+          assert_equal "5", number_helper.number_to_rounded(5.3923, :precision => 1, :significant => true )
+          assert_equal "1", number_helper.number_to_rounded(1.232, :precision => 1, :significant => true )
+          assert_equal "7", number_helper.number_to_rounded(7, :precision => 1, :significant => true )
+          assert_equal "1", number_helper.number_to_rounded(1, :precision => 1, :significant => true )
+          assert_equal "53", number_helper.number_to_rounded(52.7923, :precision => 2, :significant => true )
+          assert_equal "9775.00", number_helper.number_to_rounded(9775, :precision => 6, :significant => true )
+          assert_equal "5.392900", number_helper.number_to_rounded(5.3929, :precision => 7, :significant => true )
+          assert_equal "0.0", number_helper.number_to_rounded(0, :precision => 2, :significant => true )
+          assert_equal "0", number_helper.number_to_rounded(0, :precision => 1, :significant => true )
+          assert_equal "0.0001", number_helper.number_to_rounded(0.0001, :precision => 1, :significant => true )
+          assert_equal "0.000100", number_helper.number_to_rounded(0.0001, :precision => 3, :significant => true )
+          assert_equal "0.0001", number_helper.number_to_rounded(0.0001111, :precision => 1, :significant => true )
+          assert_equal "10.0", number_helper.number_to_rounded(9.995, :precision => 3, :significant => true)
+          assert_equal "9.99", number_helper.number_to_rounded(9.994, :precision => 3, :significant => true)
+          assert_equal "11.0", number_helper.number_to_rounded(10.995, :precision => 3, :significant => true)
+
+          assert_equal "9775.0000000000000000", number_helper.number_to_rounded(9775, :precision => 20, :significant => true )
+          assert_equal "9775.0000000000000000", number_helper.number_to_rounded(9775.0, :precision => 20, :significant => true )
+          assert_equal "9775.0000000000000000", number_helper.number_to_rounded(Rational(9775, 1), :precision => 20, :significant => true )
+          assert_equal "97.750000000000000000", number_helper.number_to_rounded(Rational(9775, 100), :precision => 20, :significant => true )
+          assert_equal "9775.0000000000000000", number_helper.number_to_rounded(BigDecimal(9775), :precision => 20, :significant => true )
+          assert_equal "9775.0000000000000000", number_helper.number_to_rounded("9775", :precision => 20, :significant => true )
+          assert_equal "9775." + "0"*96, number_helper.number_to_rounded("9775", :precision => 100, :significant => true )
+        end
+      end
+
+      def test_to_rounded_with_strip_insignificant_zeros
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal "9775.43", number_helper.number_to_rounded(9775.43, :precision => 4, :strip_insignificant_zeros => true )
+          assert_equal "9775.2", number_helper.number_to_rounded(9775.2, :precision => 6, :significant => true, :strip_insignificant_zeros => true )
+          assert_equal "0", number_helper.number_to_rounded(0, :precision => 6, :significant => true, :strip_insignificant_zeros => true )
+        end
+      end
+
+      def test_to_rounded_with_significant_true_and_zero_precision
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          # Zero precision with significant is a mistake (would always return zero),
+          # so we treat it as if significant was false (increases backwards compatibility for number_to_human_size)
+          assert_equal "124", number_helper.number_to_rounded(123.987, :precision => 0, :significant => true)
+          assert_equal "12", number_helper.number_to_rounded(12, :precision => 0, :significant => true )
+          assert_equal "12", number_helper.number_to_rounded("12.3", :precision => 0, :significant => true )
+        end
+      end
+
+      def test_number_number_to_human_size
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal '0 Bytes',   number_helper.number_to_human_size(0)
+          assert_equal '1 Byte',    number_helper.number_to_human_size(1)
+          assert_equal '3 Bytes',   number_helper.number_to_human_size(3.14159265)
+          assert_equal '123 Bytes', number_helper.number_to_human_size(123.0)
+          assert_equal '123 Bytes', number_helper.number_to_human_size(123)
+          assert_equal '1.21 KB',    number_helper.number_to_human_size(1234)
+          assert_equal '12.1 KB',   number_helper.number_to_human_size(12345)
+          assert_equal '1.18 MB',    number_helper.number_to_human_size(1234567)
+          assert_equal '1.15 GB',    number_helper.number_to_human_size(1234567890)
+          assert_equal '1.12 TB',    number_helper.number_to_human_size(1234567890123)
+          assert_equal '1030 TB',   number_helper.number_to_human_size(terabytes(1026))
+          assert_equal '444 KB',    number_helper.number_to_human_size(kilobytes(444))
+          assert_equal '1020 MB',   number_helper.number_to_human_size(megabytes(1023))
+          assert_equal '3 TB',      number_helper.number_to_human_size(terabytes(3))
+          assert_equal '1.2 MB',   number_helper.number_to_human_size(1234567, :precision => 2)
+          assert_equal '3 Bytes',   number_helper.number_to_human_size(3.14159265, :precision => 4)
+          assert_equal '123 Bytes', number_helper.number_to_human_size('123')
+          assert_equal '1 KB',   number_helper.number_to_human_size(kilobytes(1.0123), :precision => 2)
+          assert_equal '1.01 KB',   number_helper.number_to_human_size(kilobytes(1.0100), :precision => 4)
+          assert_equal '10 KB',   number_helper.number_to_human_size(kilobytes(10.000), :precision => 4)
+          assert_equal '1 Byte',   number_helper.number_to_human_size(1.1)
+          assert_equal '10 Bytes', number_helper.number_to_human_size(10)
+        end
+      end
+
+      def test_number_to_human_size_with_si_prefix
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal '3 Bytes',    number_helper.number_to_human_size(3.14159265, :prefix => :si)
+          assert_equal '123 Bytes',  number_helper.number_to_human_size(123.0, :prefix => :si)
+          assert_equal '123 Bytes',  number_helper.number_to_human_size(123, :prefix => :si)
+          assert_equal '1.23 KB',    number_helper.number_to_human_size(1234, :prefix => :si)
+          assert_equal '12.3 KB',    number_helper.number_to_human_size(12345, :prefix => :si)
+          assert_equal '1.23 MB',    number_helper.number_to_human_size(1234567, :prefix => :si)
+          assert_equal '1.23 GB',    number_helper.number_to_human_size(1234567890, :prefix => :si)
+          assert_equal '1.23 TB',    number_helper.number_to_human_size(1234567890123, :prefix => :si)
+        end
+      end
+
+      def test_number_to_human_size_with_options_hash
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal '1.2 MB',   number_helper.number_to_human_size(1234567, :precision => 2)
+          assert_equal '3 Bytes',   number_helper.number_to_human_size(3.14159265, :precision => 4)
+          assert_equal '1 KB',   number_helper.number_to_human_size(kilobytes(1.0123), :precision => 2)
+          assert_equal '1.01 KB',   number_helper.number_to_human_size(kilobytes(1.0100), :precision => 4)
+          assert_equal '10 KB',     number_helper.number_to_human_size(kilobytes(10.000), :precision => 4)
+          assert_equal '1 TB', number_helper.number_to_human_size(1234567890123, :precision => 1)
+          assert_equal '500 MB', number_helper.number_to_human_size(524288000, :precision=>3)
+          assert_equal '10 MB', number_helper.number_to_human_size(9961472, :precision=>0)
+          assert_equal '40 KB', number_helper.number_to_human_size(41010, :precision => 1)
+          assert_equal '40 KB', number_helper.number_to_human_size(41100, :precision => 2)
+          assert_equal '1.0 KB',   number_helper.number_to_human_size(kilobytes(1.0123), :precision => 2, :strip_insignificant_zeros => false)
+          assert_equal '1.012 KB',   number_helper.number_to_human_size(kilobytes(1.0123), :precision => 3, :significant => false)
+          assert_equal '1 KB',   number_helper.number_to_human_size(kilobytes(1.0123), :precision => 0, :significant => true) #ignores significant it precision is 0
+        end
+      end
+
+      def test_number_to_human_size_with_custom_delimiter_and_separator
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal '1,01 KB',     number_helper.number_to_human_size(kilobytes(1.0123), :precision => 3, :separator => ',')
+          assert_equal '1,01 KB',     number_helper.number_to_human_size(kilobytes(1.0100), :precision => 4, :separator => ',')
+          assert_equal '1.000,1 TB',  number_helper.number_to_human_size(terabytes(1000.1), :precision => 5, :delimiter => '.', :separator => ',')
+        end
+      end
+
+      def test_number_to_human
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal '-123', number_helper.number_to_human(-123)
+          assert_equal '-0.5', number_helper.number_to_human(-0.5)
+          assert_equal '0',   number_helper.number_to_human(0)
+          assert_equal '0.5', number_helper.number_to_human(0.5)
+          assert_equal '123', number_helper.number_to_human(123)
+          assert_equal '1.23 Thousand', number_helper.number_to_human(1234)
+          assert_equal '12.3 Thousand', number_helper.number_to_human(12345)
+          assert_equal '1.23 Million', number_helper.number_to_human(1234567)
+          assert_equal '1.23 Billion', number_helper.number_to_human(1234567890)
+          assert_equal '1.23 Trillion', number_helper.number_to_human(1234567890123)
+          assert_equal '1.23 Quadrillion', number_helper.number_to_human(1234567890123456)
+          assert_equal '1230 Quadrillion', number_helper.number_to_human(1234567890123456789)
+          assert_equal '490 Thousand', number_helper.number_to_human(489939, :precision => 2)
+          assert_equal '489.9 Thousand', number_helper.number_to_human(489939, :precision => 4)
+          assert_equal '489 Thousand', number_helper.number_to_human(489000, :precision => 4)
+          assert_equal '489.0 Thousand', number_helper.number_to_human(489000, :precision => 4, :strip_insignificant_zeros => false)
+          assert_equal '1.2346 Million', number_helper.number_to_human(1234567, :precision => 4, :significant => false)
+          assert_equal '1,2 Million', number_helper.number_to_human(1234567, :precision => 1, :significant => false, :separator => ',')
+          assert_equal '1 Million', number_helper.number_to_human(1234567, :precision => 0, :significant => true, :separator => ',') #significant forced to false
+        end
+      end
+
+      def test_number_to_human_with_custom_units
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          #Only integers
+          volume = {:unit => "ml", :thousand => "lt", :million => "m3"}
+          assert_equal '123 lt', number_helper.number_to_human(123456, :units => volume)
+          assert_equal '12 ml', number_helper.number_to_human(12, :units => volume)
+          assert_equal '1.23 m3', number_helper.number_to_human(1234567, :units => volume)
+
+          #Including fractionals
+          distance = {:mili => "mm", :centi => "cm", :deci => "dm", :unit => "m", :ten => "dam", :hundred => "hm", :thousand => "km"}
+          assert_equal '1.23 mm', number_helper.number_to_human(0.00123, :units => distance)
+          assert_equal '1.23 cm', number_helper.number_to_human(0.0123, :units => distance)
+          assert_equal '1.23 dm', number_helper.number_to_human(0.123, :units => distance)
+          assert_equal '1.23 m', number_helper.number_to_human(1.23, :units => distance)
+          assert_equal '1.23 dam', number_helper.number_to_human(12.3, :units => distance)
+          assert_equal '1.23 hm', number_helper.number_to_human(123, :units => distance)
+          assert_equal '1.23 km', number_helper.number_to_human(1230, :units => distance)
+          assert_equal '1.23 km', number_helper.number_to_human(1230, :units => distance)
+          assert_equal '1.23 km', number_helper.number_to_human(1230, :units => distance)
+          assert_equal '12.3 km', number_helper.number_to_human(12300, :units => distance)
+
+          #The quantifiers don't need to be a continuous sequence
+          gangster = {:hundred => "hundred bucks", :million => "thousand quids"}
+          assert_equal '1 hundred bucks', number_helper.number_to_human(100, :units => gangster)
+          assert_equal '25 hundred bucks', number_helper.number_to_human(2500, :units => gangster)
+          assert_equal '25 thousand quids', number_helper.number_to_human(25000000, :units => gangster)
+          assert_equal '12300 thousand quids', number_helper.number_to_human(12345000000, :units => gangster)
+
+          #Spaces are stripped from the resulting string
+          assert_equal '4', number_helper.number_to_human(4, :units => {:unit => "", :ten => 'tens '})
+          assert_equal '4.5  tens', number_helper.number_to_human(45, :units => {:unit => "", :ten => ' tens   '})
+        end
+      end
+
+      def test_number_to_human_with_custom_units_that_are_missing_the_needed_key
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal '123', number_helper.number_to_human(123, units: { thousand: 'k'})
+          assert_equal '123', number_helper.number_to_human(123, units: {})
+        end
+      end
+
+      def test_number_to_human_with_custom_format
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal '123 times Thousand', number_helper.number_to_human(123456, :format => "%n times %u")
+          volume = {:unit => "ml", :thousand => "lt", :million => "m3"}
+          assert_equal '123.lt', number_helper.number_to_human(123456, :units => volume, :format => "%n.%u")
+        end
+      end
+
+      def test_number_helpers_should_return_nil_when_given_nil
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_nil number_helper.number_to_phone(nil)
+          assert_nil number_helper.number_to_currency(nil)
+          assert_nil number_helper.number_to_percentage(nil)
+          assert_nil number_helper.number_to_delimited(nil)
+          assert_nil number_helper.number_to_rounded(nil)
+          assert_nil number_helper.number_to_human_size(nil)
+          assert_nil number_helper.number_to_human(nil)
+        end
+      end
+
+      def test_number_helpers_do_not_mutate_options_hash
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          options = { 'raise' => true }
+
+          number_helper.number_to_phone(1, options)
+          assert_equal({ 'raise' => true }, options)
+
+          number_helper.number_to_currency(1, options)
+          assert_equal({ 'raise' => true }, options)
+
+          number_helper.number_to_percentage(1, options)
+          assert_equal({ 'raise' => true }, options)
+
+          number_helper.number_to_delimited(1, options)
+          assert_equal({ 'raise' => true }, options)
+
+          number_helper.number_to_rounded(1, options)
+          assert_equal({ 'raise' => true }, options)
+
+          number_helper.number_to_human_size(1, options)
+          assert_equal({ 'raise' => true }, options)
+
+          number_helper.number_to_human(1, options)
+          assert_equal({ 'raise' => true }, options)
+        end
+      end
+
+      def test_number_helpers_should_return_non_numeric_param_unchanged
+        [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper|
+          assert_equal("+1-x x 123", number_helper.number_to_phone("x", :country_code => 1, :extension => 123))
+          assert_equal("x", number_helper.number_to_phone("x"))
+          assert_equal("$x.", number_helper.number_to_currency("x."))
+          assert_equal("$x", number_helper.number_to_currency("x"))
+          assert_equal("x%", number_helper.number_to_percentage("x"))
+          assert_equal("x", number_helper.number_to_delimited("x"))
+          assert_equal("x.", number_helper.number_to_rounded("x."))
+          assert_equal("x", number_helper.number_to_rounded("x"))
+          assert_equal "x", number_helper.number_to_human_size('x')
+          assert_equal "x", number_helper.number_to_human('x')
+        end
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/activesupport/test/option_merger_test.rb b/app/server/vendor/activesupport/test/option_merger_test.rb
new file mode 100644
index 0000000..9d139b6
--- /dev/null
+++ b/app/server/vendor/activesupport/test/option_merger_test.rb
@@ -0,0 +1,86 @@
+require 'abstract_unit'
+require 'active_support/core_ext/object/with_options'
+
+class OptionMergerTest < ActiveSupport::TestCase
+  def setup
+    @options = {:hello => 'world'}
+  end
+
+  def test_method_with_options_merges_options_when_options_are_present
+    local_options = {:cool => true}
+
+    with_options(@options) do |o|
+      assert_equal local_options, method_with_options(local_options)
+      assert_equal @options.merge(local_options),
+        o.method_with_options(local_options)
+    end
+  end
+
+  def test_method_with_options_appends_options_when_options_are_missing
+    with_options(@options) do |o|
+      assert_equal Hash.new, method_with_options
+      assert_equal @options, o.method_with_options
+    end
+  end
+
+  def test_method_with_options_allows_to_overwrite_options
+    local_options = {:hello => 'moon'}
+    assert_equal @options.keys, local_options.keys
+
+    with_options(@options) do |o|
+      assert_equal local_options, method_with_options(local_options)
+      assert_equal @options.merge(local_options),
+        o.method_with_options(local_options)
+      assert_equal local_options, o.method_with_options(local_options)
+    end
+    with_options(local_options) do |o|
+      assert_equal local_options.merge(@options),
+        o.method_with_options(@options)
+    end
+  end
+
+  def test_nested_method_with_options_containing_hashes_merge
+    with_options :conditions => { :method => :get } do |outer|
+      outer.with_options :conditions => { :domain => "www" } do |inner|
+        expected = { :conditions => { :method => :get, :domain => "www" } }
+        assert_equal expected, inner.method_with_options
+      end
+    end
+  end
+
+  def test_nested_method_with_options_containing_hashes_overwrite
+    with_options :conditions => { :method => :get, :domain => "www" } do |outer|
+      outer.with_options :conditions => { :method => :post } do |inner|
+        expected = { :conditions => { :method => :post, :domain => "www" } }
+        assert_equal expected, inner.method_with_options
+      end
+    end
+  end
+
+  def test_nested_method_with_options_containing_hashes_going_deep
+    with_options :html => { :class => "foo", :style => { :margin => 0, :display => "block" } } do |outer|
+      outer.with_options :html => { :title => "bar", :style => { :margin => "1em", :color => "#fff" } } do |inner|
+        expected = { :html => { :class => "foo", :title => "bar", :style => { :margin => "1em", :display => "block", :color => "#fff" } } }
+        assert_equal expected, inner.method_with_options
+      end
+    end
+  end
+
+  def test_nested_method_with_options_using_lambda
+    local_lambda = lambda { { :lambda => true } }
+    with_options(@options) do |o|
+      assert_equal @options.merge(local_lambda.call),
+        o.method_with_options(local_lambda).call
+    end
+  end
+
+  # Needed when counting objects with the ObjectSpace
+  def test_option_merger_class_method
+    assert_equal ActiveSupport::OptionMerger, ActiveSupport::OptionMerger.new('', '').class
+  end
+
+  private
+    def method_with_options(options = {})
+      options
+    end
+end
diff --git a/app/server/vendor/activesupport/test/ordered_hash_test.rb b/app/server/vendor/activesupport/test/ordered_hash_test.rb
new file mode 100644
index 0000000..460a616
--- /dev/null
+++ b/app/server/vendor/activesupport/test/ordered_hash_test.rb
@@ -0,0 +1,322 @@
+require 'abstract_unit'
+require 'active_support/json'
+require 'active_support/core_ext/object/json'
+require 'active_support/core_ext/hash/indifferent_access'
+require 'active_support/core_ext/array/extract_options'
+
+class OrderedHashTest < ActiveSupport::TestCase
+  def setup
+    @keys =   %w( blue   green  red    pink   orange )
+    @values = %w( 000099 009900 aa0000 cc0066 cc6633 )
+    @hash = Hash.new
+    @ordered_hash = ActiveSupport::OrderedHash.new
+
+    @keys.each_with_index do |key, index|
+      @hash[key] = @values[index]
+      @ordered_hash[key] = @values[index]
+    end
+  end
+
+  def test_order
+    assert_equal @keys,   @ordered_hash.keys
+    assert_equal @values, @ordered_hash.values
+  end
+
+  def test_access
+    assert @hash.all? { |k, v| @ordered_hash[k] == v }
+  end
+
+  def test_assignment
+    key, value = 'purple', '5422a8'
+
+    @ordered_hash[key] = value
+    assert_equal @keys.length + 1, @ordered_hash.length
+    assert_equal key, @ordered_hash.keys.last
+    assert_equal value, @ordered_hash.values.last
+    assert_equal value, @ordered_hash[key]
+  end
+
+  def test_delete
+    key, value = 'white', 'ffffff'
+    bad_key = 'black'
+
+    @ordered_hash[key] = value
+    assert_equal @keys.length + 1, @ordered_hash.length
+    assert_equal @ordered_hash.keys.length, @ordered_hash.length
+
+    assert_equal value, @ordered_hash.delete(key)
+    assert_equal @keys.length, @ordered_hash.length
+    assert_equal @ordered_hash.keys.length, @ordered_hash.length
+
+    assert_nil @ordered_hash.delete(bad_key)
+  end
+
+  def test_to_hash
+    assert_same @ordered_hash, @ordered_hash.to_hash
+  end
+
+  def test_to_a
+    assert_equal @keys.zip(@values), @ordered_hash.to_a
+  end
+
+  def test_has_key
+    assert_equal true, @ordered_hash.has_key?('blue')
+    assert_equal true, @ordered_hash.key?('blue')
+    assert_equal true, @ordered_hash.include?('blue')
+    assert_equal true, @ordered_hash.member?('blue')
+
+    assert_equal false, @ordered_hash.has_key?('indigo')
+    assert_equal false, @ordered_hash.key?('indigo')
+    assert_equal false, @ordered_hash.include?('indigo')
+    assert_equal false, @ordered_hash.member?('indigo')
+  end
+
+  def test_has_value
+    assert_equal true, @ordered_hash.has_value?('000099')
+    assert_equal true, @ordered_hash.value?('000099')
+    assert_equal false, @ordered_hash.has_value?('ABCABC')
+    assert_equal false, @ordered_hash.value?('ABCABC')
+  end
+
+  def test_each_key
+    keys = []
+    assert_equal @ordered_hash, @ordered_hash.each_key { |k| keys << k }
+    assert_equal @keys, keys
+    assert_kind_of Enumerator, @ordered_hash.each_key
+  end
+
+  def test_each_value
+    values = []
+    assert_equal @ordered_hash, @ordered_hash.each_value { |v| values << v }
+    assert_equal @values, values
+    assert_kind_of Enumerator, @ordered_hash.each_value
+  end
+
+  def test_each
+    values = []
+    assert_equal @ordered_hash, @ordered_hash.each {|key, value| values << value}
+    assert_equal @values, values
+    assert_kind_of Enumerator, @ordered_hash.each
+  end
+
+  def test_each_with_index
+    @ordered_hash.each_with_index { |pair, index| assert_equal [@keys[index], @values[index]], pair}
+  end
+
+  def test_each_pair
+    values = []
+    keys = []
+    @ordered_hash.each_pair do |key, value|
+      keys << key
+      values << value
+    end
+    assert_equal @values, values
+    assert_equal @keys, keys
+    assert_kind_of Enumerator, @ordered_hash.each_pair
+  end
+
+  def test_find_all
+    assert_equal @keys, @ordered_hash.find_all { true }.map(&:first)
+  end
+
+  def test_select
+    new_ordered_hash = @ordered_hash.select { true }
+    assert_equal @keys, new_ordered_hash.map(&:first)
+    assert_instance_of ActiveSupport::OrderedHash, new_ordered_hash
+  end
+
+  def test_delete_if
+    copy = @ordered_hash.dup
+    copy.delete('pink')
+    assert_equal copy, @ordered_hash.delete_if { |k, _| k == 'pink' }
+    assert !@ordered_hash.keys.include?('pink')
+  end
+
+  def test_reject!
+    (copy = @ordered_hash.dup).delete('pink')
+    @ordered_hash.reject! { |k, _| k == 'pink' }
+    assert_equal copy, @ordered_hash
+    assert !@ordered_hash.keys.include?('pink')
+  end
+
+  def test_reject
+    copy = @ordered_hash.dup
+    new_ordered_hash = @ordered_hash.reject { |k, _| k == 'pink' }
+    assert_equal copy, @ordered_hash
+    assert !new_ordered_hash.keys.include?('pink')
+    assert @ordered_hash.keys.include?('pink')
+    assert_instance_of ActiveSupport::OrderedHash, new_ordered_hash
+  end
+
+  def test_clear
+    @ordered_hash.clear
+    assert_equal [], @ordered_hash.keys
+  end
+
+  def test_merge
+    other_hash =  ActiveSupport::OrderedHash.new
+    other_hash['purple'] = '800080'
+    other_hash['violet'] = 'ee82ee'
+    merged = @ordered_hash.merge other_hash
+    assert_equal merged.length, @ordered_hash.length + other_hash.length
+    assert_equal @keys + ['purple', 'violet'], merged.keys
+  end
+
+  def test_merge_with_block
+    hash = ActiveSupport::OrderedHash.new
+    hash[:a] = 0
+    hash[:b] = 0
+    merged = hash.merge(:b => 2, :c => 7) do |key, old_value, new_value|
+      new_value + 1
+    end
+
+    assert_equal 0, merged[:a]
+    assert_equal 3, merged[:b]
+    assert_equal 7, merged[:c]
+  end
+
+  def test_merge_bang_with_block
+    hash = ActiveSupport::OrderedHash.new
+    hash[:a] = 0
+    hash[:b] = 0
+    hash.merge!(:a => 1, :c => 7) do |key, old_value, new_value|
+      new_value + 3
+    end
+
+    assert_equal 4, hash[:a]
+    assert_equal 0, hash[:b]
+    assert_equal 7, hash[:c]
+  end
+
+  def test_shift
+    pair = @ordered_hash.shift
+    assert_equal [@keys.first, @values.first], pair
+    assert !@ordered_hash.keys.include?(pair.first)
+  end
+
+  def test_keys
+    original = @ordered_hash.keys.dup
+    @ordered_hash.keys.pop
+    assert_equal original, @ordered_hash.keys
+  end
+
+  def test_inspect
+    assert @ordered_hash.inspect.include?(@hash.inspect)
+  end
+
+  def test_json
+    ordered_hash = ActiveSupport::OrderedHash[:foo, :bar]
+    hash = Hash[:foo, :bar]
+    assert_equal ordered_hash.to_json, hash.to_json
+  end
+
+  def test_alternate_initialization_with_splat
+    alternate = ActiveSupport::OrderedHash[1,2,3,4]
+    assert_kind_of ActiveSupport::OrderedHash, alternate
+    assert_equal [1, 3], alternate.keys
+  end
+
+  def test_alternate_initialization_with_array
+    alternate = ActiveSupport::OrderedHash[ [
+      [1, 2],
+      [3, 4],
+      [ 'missing value' ]
+    ]]
+
+    assert_kind_of ActiveSupport::OrderedHash, alternate
+    assert_equal [1, 3, 'missing value'], alternate.keys
+    assert_equal [2, 4, nil ], alternate.values
+  end
+
+  def test_alternate_initialization_raises_exception_on_odd_length_args
+    assert_raises ArgumentError do
+      ActiveSupport::OrderedHash[1,2,3,4,5]
+    end
+  end
+
+  def test_replace_updates_keys
+    @other_ordered_hash = ActiveSupport::OrderedHash[:black, '000000', :white, '000000']
+    original = @ordered_hash.replace(@other_ordered_hash)
+    assert_same original, @ordered_hash
+    assert_equal @other_ordered_hash.keys, @ordered_hash.keys
+  end
+
+  def test_nested_under_indifferent_access
+    flash = {:a => ActiveSupport::OrderedHash[:b, 1, :c, 2]}.with_indifferent_access
+    assert_kind_of ActiveSupport::OrderedHash, flash[:a]
+  end
+
+  def test_each_after_yaml_serialization
+    assert_equal @values, YAML.load(YAML.dump(@ordered_hash)).values
+  end
+
+  def test_each_when_yielding_to_block_with_splat
+    hash_values         = []
+    ordered_hash_values = []
+
+    @hash.each         { |*v| hash_values         << v }
+    @ordered_hash.each { |*v| ordered_hash_values << v }
+
+    assert_equal hash_values.sort, ordered_hash_values.sort
+  end
+
+  def test_each_pair_when_yielding_to_block_with_splat
+    hash_values         = []
+    ordered_hash_values = []
+
+    @hash.each_pair         { |*v| hash_values         << v }
+    @ordered_hash.each_pair { |*v| ordered_hash_values << v }
+
+    assert_equal hash_values.sort, ordered_hash_values.sort
+  end
+
+  def test_order_after_yaml_serialization
+    @deserialized_ordered_hash = YAML.load(YAML.dump(@ordered_hash))
+
+    assert_equal @keys,   @deserialized_ordered_hash.keys
+    assert_equal @values, @deserialized_ordered_hash.values
+  end
+
+  def test_order_after_yaml_serialization_with_nested_arrays
+    @ordered_hash[:array] = %w(a b c)
+
+    @deserialized_ordered_hash = YAML.load(YAML.dump(@ordered_hash))
+
+    assert_equal @ordered_hash.keys,   @deserialized_ordered_hash.keys
+    assert_equal @ordered_hash.values, @deserialized_ordered_hash.values
+  end
+
+  def test_psych_serialize
+    @deserialized_ordered_hash = Psych.load(Psych.dump(@ordered_hash))
+
+    values = @deserialized_ordered_hash.map { |_, value| value }
+    assert_equal @values, values
+  end
+
+  def test_psych_serialize_tag
+    yaml = Psych.dump(@ordered_hash)
+    assert_match '!omap', yaml
+  end
+
+  def test_has_yaml_tag
+    @ordered_hash[:array] = %w(a b c)
+    assert_match '!omap', YAML.dump(@ordered_hash)
+  end
+
+  def test_update_sets_keys
+    @updated_ordered_hash = ActiveSupport::OrderedHash.new
+    @updated_ordered_hash.update(:name => "Bob")
+    assert_equal [:name],  @updated_ordered_hash.keys
+  end
+
+  def test_invert
+    expected = ActiveSupport::OrderedHash[@values.zip(@keys)]
+    assert_equal expected, @ordered_hash.invert
+    assert_equal @values.zip(@keys), @ordered_hash.invert.to_a
+  end
+
+  def test_extractable
+    @ordered_hash[:rails] = "snowman"
+    assert_equal @ordered_hash, [1, 2, @ordered_hash].extract_options!
+  end
+end
diff --git a/app/server/vendor/activesupport/test/ordered_options_test.rb b/app/server/vendor/activesupport/test/ordered_options_test.rb
new file mode 100644
index 0000000..fdc745b
--- /dev/null
+++ b/app/server/vendor/activesupport/test/ordered_options_test.rb
@@ -0,0 +1,88 @@
+require 'abstract_unit'
+require 'active_support/ordered_options'
+
+class OrderedOptionsTest < ActiveSupport::TestCase
+  def test_usage
+    a = ActiveSupport::OrderedOptions.new
+
+    assert_nil a[:not_set]
+
+    a[:allow_concurrency] = true
+    assert_equal 1, a.size
+    assert a[:allow_concurrency]
+
+    a[:allow_concurrency] = false
+    assert_equal 1, a.size
+    assert !a[:allow_concurrency]
+
+    a["else_where"] = 56
+    assert_equal 2, a.size
+    assert_equal 56, a[:else_where]
+  end
+
+  def test_looping
+    a = ActiveSupport::OrderedOptions.new
+
+    a[:allow_concurrency] = true
+    a["else_where"] = 56
+
+    test = [[:allow_concurrency, true], [:else_where, 56]]
+
+    a.each_with_index do |(key, value), index|
+      assert_equal test[index].first, key
+      assert_equal test[index].last, value
+    end
+  end
+
+  def test_method_access
+    a = ActiveSupport::OrderedOptions.new
+
+    assert_nil a.not_set
+
+    a.allow_concurrency = true
+    assert_equal 1, a.size
+    assert a.allow_concurrency
+
+    a.allow_concurrency = false
+    assert_equal 1, a.size
+    assert !a.allow_concurrency
+
+    a.else_where = 56
+    assert_equal 2, a.size
+    assert_equal 56, a.else_where
+  end
+
+  def test_inheritable_options_continues_lookup_in_parent
+    parent = ActiveSupport::OrderedOptions.new
+    parent[:foo] = true
+
+    child = ActiveSupport::InheritableOptions.new(parent)
+    assert child.foo
+  end
+
+  def test_inheritable_options_can_override_parent
+    parent = ActiveSupport::OrderedOptions.new
+    parent[:foo] = :bar
+
+    child = ActiveSupport::InheritableOptions.new(parent)
+    child[:foo] = :baz
+
+    assert_equal :baz, child.foo
+  end
+
+  def test_inheritable_options_inheritable_copy
+    original = ActiveSupport::InheritableOptions.new
+    copy     = original.inheritable_copy
+
+    assert copy.kind_of?(original.class)
+    assert_not_equal copy.object_id, original.object_id
+  end
+
+  def test_introspection
+    a = ActiveSupport::OrderedOptions.new
+    assert a.respond_to?(:blah)
+    assert a.respond_to?(:blah=)
+    assert_equal 42, a.method(:blah=).call(42)
+    assert_equal 42, a.method(:blah).call
+  end
+end
diff --git a/app/server/vendor/activesupport/test/rescuable_test.rb b/app/server/vendor/activesupport/test/rescuable_test.rb
new file mode 100644
index 0000000..ec9d231
--- /dev/null
+++ b/app/server/vendor/activesupport/test/rescuable_test.rb
@@ -0,0 +1,105 @@
+require 'abstract_unit'
+
+class WraithAttack < StandardError
+end
+
+class NuclearExplosion < StandardError
+end
+
+class MadRonon < StandardError
+end
+
+class CoolError < StandardError
+end
+
+class Stargate
+  attr_accessor :result
+
+  include ActiveSupport::Rescuable
+
+  rescue_from WraithAttack, :with => :sos_first
+
+  rescue_from WraithAttack, :with => :sos
+
+  rescue_from 'NuclearExplosion' do
+    @result = 'alldead'
+  end
+
+  rescue_from MadRonon do |e|
+    @result = e.message
+  end
+
+  def dispatch(method)
+    send(method)
+  rescue Exception => e
+    rescue_with_handler(e)
+  end
+
+  def attack
+    raise WraithAttack
+  end
+
+  def nuke
+    raise NuclearExplosion
+  end
+
+  def ronanize
+    raise MadRonon.new("dex")
+  end
+
+  def sos
+    @result = 'killed'
+  end
+
+  def sos_first
+    @result = 'sos_first'
+  end
+
+end
+
+class CoolStargate < Stargate
+  attr_accessor :result
+
+  include ActiveSupport::Rescuable
+
+  rescue_from CoolError, :with => :sos_cool_error
+
+  def sos_cool_error
+    @result = 'sos_cool_error'
+  end
+end
+
+
+class RescuableTest < ActiveSupport::TestCase
+  def setup
+    @stargate = Stargate.new
+    @cool_stargate = CoolStargate.new
+  end
+
+  def test_rescue_from_with_method
+    @stargate.dispatch :attack
+    assert_equal 'killed', @stargate.result
+  end
+
+  def test_rescue_from_with_block
+    @stargate.dispatch :nuke
+    assert_equal 'alldead', @stargate.result
+  end
+
+  def test_rescue_from_with_block_with_args
+    @stargate.dispatch :ronanize
+    assert_equal 'dex', @stargate.result
+  end
+
+  def test_rescues_defined_later_are_added_at_end_of_the_rescue_handlers_array
+    expected = ["WraithAttack", "WraithAttack", "NuclearExplosion", "MadRonon"]
+    result = @stargate.send(:rescue_handlers).collect {|e| e.first}
+    assert_equal expected, result
+  end
+
+  def test_children_should_inherit_rescue_definitions_from_parents_and_child_rescue_should_be_appended
+    expected = ["WraithAttack", "WraithAttack", "NuclearExplosion", "MadRonon", "CoolError"]
+    result = @cool_stargate.send(:rescue_handlers).collect {|e| e.first}
+    assert_equal expected, result
+  end
+end
diff --git a/app/server/vendor/activesupport/test/safe_buffer_test.rb b/app/server/vendor/activesupport/test/safe_buffer_test.rb
new file mode 100644
index 0000000..efa9d5e
--- /dev/null
+++ b/app/server/vendor/activesupport/test/safe_buffer_test.rb
@@ -0,0 +1,168 @@
+require 'abstract_unit'
+require 'active_support/core_ext/string/inflections'
+require 'yaml'
+
+class SafeBufferTest < ActiveSupport::TestCase
+  def setup
+    @buffer = ActiveSupport::SafeBuffer.new
+  end
+
+  def test_titleize
+    assert_equal 'Foo', "foo".html_safe.titleize
+  end
+
+  test "Should look like a string" do
+    assert @buffer.is_a?(String)
+    assert_equal "", @buffer
+  end
+
+  test "Should escape a raw string which is passed to them" do
+    @buffer << "<script>"
+    assert_equal "<script>", @buffer
+  end
+
+  test "Should NOT escape a safe value passed to it" do
+    @buffer << "<script>".html_safe
+    assert_equal "<script>", @buffer
+  end
+
+  test "Should not mess with an innocuous string" do
+    @buffer << "Hello"
+    assert_equal "Hello", @buffer
+  end
+
+  test "Should not mess with a previously escape test" do
+    @buffer << ERB::Util.html_escape("<script>")
+    assert_equal "<script>", @buffer
+  end
+
+  test "Should be considered safe" do
+    assert @buffer.html_safe?
+  end
+
+  test "Should return a safe buffer when calling to_s" do
+    new_buffer = @buffer.to_s
+    assert_equal ActiveSupport::SafeBuffer, new_buffer.class
+  end
+
+  test "Should be converted to_yaml" do
+    str  = 'hello!'
+    buf  = ActiveSupport::SafeBuffer.new str
+    yaml = buf.to_yaml
+
+    assert_match(/^--- #{str}/, yaml)
+    assert_equal 'hello!', YAML.load(yaml)
+  end
+
+  test "Should work in nested to_yaml conversion" do
+    str  = 'hello!'
+    data = { 'str' => ActiveSupport::SafeBuffer.new(str) }
+    yaml = YAML.dump data
+    assert_equal({'str' => str}, YAML.load(yaml))
+  end
+
+  test "Should work with underscore" do
+    str = "MyTest".html_safe.underscore
+    assert_equal "my_test", str
+  end
+
+  test "Should not return safe buffer from gsub" do
+    altered_buffer = @buffer.gsub('', 'asdf')
+    assert_equal 'asdf', altered_buffer
+    assert !altered_buffer.html_safe?
+  end
+
+  test "Should not return safe buffer from gsub!" do
+    @buffer.gsub!('', 'asdf')
+    assert_equal 'asdf', @buffer
+    assert !@buffer.html_safe?
+  end
+
+  test "Should escape dirty buffers on add" do
+    clean = "hello".html_safe
+    @buffer.gsub!('', '<>')
+    assert_equal "hello<>", clean + @buffer
+  end
+
+  test "Should concat as a normal string when safe" do
+    clean = "hello".html_safe
+    @buffer.gsub!('', '<>')
+    assert_equal "<>hello", @buffer + clean
+  end
+
+  test "Should preserve html_safe? status on copy" do
+    @buffer.gsub!('', '<>')
+    assert !@buffer.dup.html_safe?
+  end
+
+  test "Should return safe buffer when added with another safe buffer" do
+    clean = "<script>".html_safe
+    result_buffer = @buffer + clean
+    assert result_buffer.html_safe?
+    assert_equal "<script>", result_buffer
+  end
+
+  test "Should raise an error when safe_concat is called on unsafe buffers" do
+    @buffer.gsub!('', '<>')
+    assert_raise ActiveSupport::SafeBuffer::SafeConcatError do
+      @buffer.safe_concat "BUSTED"
+    end
+  end
+
+  test "Should not fail if the returned object is not a string" do
+    assert_kind_of NilClass, @buffer.slice("chipchop")
+  end
+
+  test "clone_empty returns an empty buffer" do
+    assert_equal '', ActiveSupport::SafeBuffer.new('foo').clone_empty
+  end
+
+  test "clone_empty keeps the original dirtyness" do
+    assert @buffer.clone_empty.html_safe?
+    assert !@buffer.gsub!('', '').clone_empty.html_safe?
+  end
+
+  test "Should be safe when sliced if original value was safe" do
+    new_buffer = @buffer[0,0]
+    assert_not_nil new_buffer
+    assert new_buffer.html_safe?, "should be safe"
+  end
+
+  test "Should continue unsafe on slice" do
+    x = 'foo'.html_safe.gsub!('f', '<script>alert("lolpwnd");</script>')
+
+    # calling gsub! makes the dirty flag true
+    assert !x.html_safe?, "should not be safe"
+
+    # getting a slice of it
+    y = x[0..-1]
+
+    # should still be unsafe
+    assert !y.html_safe?, "should not be safe"
+  end
+
+  test 'Should work with interpolation (array argument)' do
+    x = 'foo %s bar'.html_safe % ['qux']
+    assert_equal 'foo qux bar', x
+  end
+
+  test 'Should work with interpolation (hash argument)' do
+    x = 'foo %{x} bar'.html_safe % { x: 'qux' }
+    assert_equal 'foo qux bar', x
+  end
+
+  test 'Should escape unsafe interpolated args' do
+    x = 'foo %{x} bar'.html_safe % { x: '<br/>' }
+    assert_equal 'foo <br/> bar', x
+  end
+
+  test 'Should not escape safe interpolated args' do
+    x = 'foo %{x} bar'.html_safe % { x: '<br/>'.html_safe }
+    assert_equal 'foo <br/> bar', x
+  end
+
+  test 'Should interpolate to a safe string' do
+    x = 'foo %{x} bar'.html_safe % { x: 'qux' }
+    assert x.html_safe?, 'should be safe'
+  end
+end
diff --git a/app/server/vendor/activesupport/test/string_inquirer_test.rb b/app/server/vendor/activesupport/test/string_inquirer_test.rb
new file mode 100644
index 0000000..a2ed577
--- /dev/null
+++ b/app/server/vendor/activesupport/test/string_inquirer_test.rb
@@ -0,0 +1,23 @@
+require 'abstract_unit'
+
+class StringInquirerTest < ActiveSupport::TestCase
+  def setup
+    @string_inquirer = ActiveSupport::StringInquirer.new('production')
+  end
+
+  def test_match
+    assert @string_inquirer.production?
+  end
+
+  def test_miss
+    assert_not @string_inquirer.development?
+  end
+
+  def test_missing_question_mark
+    assert_raise(NoMethodError) { @string_inquirer.production }
+  end
+
+  def test_respond_to
+    assert_respond_to @string_inquirer, :development?
+  end
+end
diff --git a/app/server/vendor/activesupport/test/subscriber_test.rb b/app/server/vendor/activesupport/test/subscriber_test.rb
new file mode 100644
index 0000000..253411a
--- /dev/null
+++ b/app/server/vendor/activesupport/test/subscriber_test.rb
@@ -0,0 +1,40 @@
+require 'abstract_unit'
+require 'active_support/subscriber'
+
+class TestSubscriber < ActiveSupport::Subscriber
+  attach_to :doodle
+
+  cattr_reader :event
+
+  def self.clear
+    @@event = nil
+  end
+
+  def open_party(event)
+    @@event = event
+  end
+
+  private
+
+  def private_party(event)
+    @@event = event
+  end
+end
+
+class SubscriberTest < ActiveSupport::TestCase
+  def setup
+    TestSubscriber.clear
+  end
+
+  def test_attaches_subscribers
+    ActiveSupport::Notifications.instrument("open_party.doodle")
+
+    assert_equal "open_party.doodle", TestSubscriber.event.name
+  end
+
+  def test_does_not_attach_private_methods
+    ActiveSupport::Notifications.instrument("private_party.doodle")
+
+    assert_nil TestSubscriber.event
+  end
+end
diff --git a/app/server/vendor/activesupport/test/tagged_logging_test.rb b/app/server/vendor/activesupport/test/tagged_logging_test.rb
new file mode 100644
index 0000000..27f6294
--- /dev/null
+++ b/app/server/vendor/activesupport/test/tagged_logging_test.rb
@@ -0,0 +1,102 @@
+require 'abstract_unit'
+require 'active_support/logger'
+require 'active_support/tagged_logging'
+
+class TaggedLoggingTest < ActiveSupport::TestCase
+  class MyLogger < ::ActiveSupport::Logger
+    def flush(*)
+      info "[FLUSHED]"
+    end
+  end
+
+  setup do
+    @output = StringIO.new
+    @logger = ActiveSupport::TaggedLogging.new(MyLogger.new(@output))
+  end
+
+  test 'sets logger.formatter if missing and extends it with a tagging API' do
+    logger = Logger.new(StringIO.new)
+    assert_nil logger.formatter
+    ActiveSupport::TaggedLogging.new(logger)
+    assert_not_nil logger.formatter
+    assert logger.formatter.respond_to?(:tagged)
+  end
+
+  test "tagged once" do
+    @logger.tagged("BCX") { @logger.info "Funky time" }
+    assert_equal "[BCX] Funky time\n", @output.string
+  end
+
+  test "tagged twice" do
+    @logger.tagged("BCX") { @logger.tagged("Jason") { @logger.info "Funky time" } }
+    assert_equal "[BCX] [Jason] Funky time\n", @output.string
+  end
+
+  test "tagged thrice at once" do
+    @logger.tagged("BCX", "Jason", "New") { @logger.info "Funky time" }
+    assert_equal "[BCX] [Jason] [New] Funky time\n", @output.string
+  end
+
+  test "tagged are flattened" do
+    @logger.tagged("BCX", %w(Jason New)) { @logger.info "Funky time" }
+    assert_equal "[BCX] [Jason] [New] Funky time\n", @output.string
+  end
+
+  test "push and pop tags directly" do
+    assert_equal %w(A B C), @logger.push_tags('A', ['B', '  ', ['C']])
+    @logger.info 'a'
+    assert_equal %w(C), @logger.pop_tags
+    @logger.info 'b'
+    assert_equal %w(B), @logger.pop_tags(1)
+    @logger.info 'c'
+    assert_equal [], @logger.clear_tags!
+    @logger.info 'd'
+    assert_equal "[A] [B] [C] a\n[A] [B] b\n[A] c\nd\n", @output.string
+  end
+
+  test "does not strip message content" do
+    @logger.info "  Hello"
+    assert_equal "  Hello\n", @output.string
+  end
+
+  test "provides access to the logger instance" do
+    @logger.tagged("BCX") { |logger| logger.info "Funky time" }
+    assert_equal "[BCX] Funky time\n", @output.string
+  end
+
+  test "tagged once with blank and nil" do
+    @logger.tagged(nil, "", "New") { @logger.info "Funky time" }
+    assert_equal "[New] Funky time\n", @output.string
+  end
+
+  test "keeps each tag in their own thread" do
+    @logger.tagged("BCX") do
+      Thread.new do
+        @logger.tagged("OMG") { @logger.info "Cool story bro" }
+      end.join
+      @logger.info "Funky time"
+    end
+    assert_equal "[OMG] Cool story bro\n[BCX] Funky time\n", @output.string
+  end
+
+  test "cleans up the taggings on flush" do
+    @logger.tagged("BCX") do
+      Thread.new do
+        @logger.tagged("OMG") do
+          @logger.flush
+          @logger.info "Cool story bro"
+        end
+      end.join
+    end
+    assert_equal "[FLUSHED]\nCool story bro\n", @output.string
+  end
+
+  test "mixed levels of tagging" do
+    @logger.tagged("BCX") do
+      @logger.tagged("Jason") { @logger.info "Funky time" }
+      @logger.info "Junky time!"
+    end
+
+    assert_equal "[BCX] [Jason] Funky time\n[BCX] Junky time!\n", @output.string
+  end
+end
diff --git a/app/server/vendor/activesupport/test/test_test.rb b/app/server/vendor/activesupport/test/test_test.rb
new file mode 100644
index 0000000..0fa08c0
--- /dev/null
+++ b/app/server/vendor/activesupport/test/test_test.rb
@@ -0,0 +1,220 @@
+require 'abstract_unit'
+require 'active_support/core_ext/date'
+require 'active_support/core_ext/numeric/time'
+
+class AssertDifferenceTest < ActiveSupport::TestCase
+  def setup
+    @object = Class.new do
+      attr_accessor :num
+      def increment
+        self.num += 1
+      end
+
+      def decrement
+        self.num -= 1
+      end
+    end.new
+    @object.num = 0
+  end
+
+  def test_assert_not
+    assert_equal true, assert_not(nil)
+    assert_equal true, assert_not(false)
+
+    e = assert_raises(Minitest::Assertion) { assert_not true }
+    assert_equal 'Expected true to be nil or false', e.message
+
+    e = assert_raises(Minitest::Assertion) { assert_not true, 'custom' }
+    assert_equal 'custom', e.message
+  end
+
+  def test_assert_no_difference
+    assert_no_difference '@object.num' do
+      # ...
+    end
+  end
+
+  def test_assert_difference
+    assert_difference '@object.num', +1 do
+      @object.increment
+    end
+  end
+
+  def test_assert_difference_with_implicit_difference
+    assert_difference '@object.num' do
+      @object.increment
+    end
+  end
+
+  def test_arbitrary_expression
+    assert_difference '@object.num + 1', +2 do
+      @object.increment
+      @object.increment
+    end
+  end
+
+  def test_negative_differences
+    assert_difference '@object.num', -1 do
+      @object.decrement
+    end
+  end
+
+  def test_expression_is_evaluated_in_the_appropriate_scope
+    silence_warnings do
+      local_scope = local_scope = 'foo'
+      assert_difference('local_scope; @object.num') { @object.increment }
+    end
+  end
+
+  def test_array_of_expressions
+    assert_difference [ '@object.num', '@object.num + 1' ], +1 do
+      @object.increment
+    end
+  end
+
+  def test_array_of_expressions_identify_failure
+    assert_raises(Minitest::Assertion) do
+      assert_difference ['@object.num', '1 + 1'] do
+        @object.increment
+      end
+    end
+  end
+
+  def test_array_of_expressions_identify_failure_when_message_provided
+    assert_raises(Minitest::Assertion) do
+      assert_difference ['@object.num', '1 + 1'], 1, 'something went wrong' do
+        @object.increment
+      end
+    end
+  end
+end
+
+class AlsoDoingNothingTest < ActiveSupport::TestCase
+end
+
+# Setup and teardown callbacks.
+class SetupAndTeardownTest < ActiveSupport::TestCase
+  setup :reset_callback_record, :foo
+  teardown :foo, :sentinel
+
+  def test_inherited_setup_callbacks
+    assert_equal [:reset_callback_record, :foo], self.class._setup_callbacks.map(&:raw_filter)
+    assert_equal [:foo], @called_back
+    assert_equal [:foo, :sentinel], self.class._teardown_callbacks.map(&:raw_filter)
+  end
+
+  def setup
+  end
+
+  def teardown
+  end
+
+  protected
+
+    def reset_callback_record
+      @called_back = []
+    end
+
+    def foo
+      @called_back << :foo
+    end
+
+    def sentinel
+      assert_equal [:foo], @called_back
+    end
+end
+
+class SubclassSetupAndTeardownTest < SetupAndTeardownTest
+  setup :bar
+  teardown :bar
+
+  def test_inherited_setup_callbacks
+    assert_equal [:reset_callback_record, :foo, :bar], self.class._setup_callbacks.map(&:raw_filter)
+    assert_equal [:foo, :bar], @called_back
+    assert_equal [:foo, :sentinel, :bar], self.class._teardown_callbacks.map(&:raw_filter)
+  end
+
+  protected
+    def bar
+      @called_back << :bar
+    end
+
+    def sentinel
+      assert_equal [:foo, :bar, :bar], @called_back
+    end
+end
+
+class TestCaseTaggedLoggingTest < ActiveSupport::TestCase
+  def before_setup
+    require 'stringio'
+    @out = StringIO.new
+    self.tagged_logger = ActiveSupport::TaggedLogging.new(Logger.new(@out))
+    super
+  end
+
+  def test_logs_tagged_with_current_test_case
+    assert_match "#{self.class}: #{name}\n", @out.string
+  end
+end
+
+class TimeHelperTest < ActiveSupport::TestCase
+  setup do
+    Time.stubs now: Time.now
+  end
+
+  teardown do
+    travel_back
+  end
+
+  def test_time_helper_travel
+    expected_time = Time.now + 1.day
+    travel 1.day
+
+    assert_equal expected_time, Time.now
+    assert_equal expected_time.to_date, Date.today
+  end
+
+  def test_time_helper_travel_with_block
+    expected_time = Time.now + 1.day
+
+    travel 1.day do
+      assert_equal expected_time, Time.now
+      assert_equal expected_time.to_date, Date.today
+    end
+
+    assert_not_equal expected_time, Time.now
+    assert_not_equal expected_time.to_date, Date.today
+  end
+
+  def test_time_helper_travel_to
+    expected_time = Time.new(2004, 11, 24, 01, 04, 44)
+    travel_to expected_time
+
+    assert_equal expected_time, Time.now
+    assert_equal Date.new(2004, 11, 24), Date.today
+  end
+
+  def test_time_helper_travel_to_with_block
+    expected_time = Time.new(2004, 11, 24, 01, 04, 44)
+
+    travel_to expected_time do
+      assert_equal expected_time, Time.now
+      assert_equal Date.new(2004, 11, 24), Date.today
+    end
+
+    assert_not_equal expected_time, Time.now
+    assert_not_equal Date.new(2004, 11, 24), Date.today
+  end
+
+  def test_time_helper_travel_back
+    expected_time = Time.new(2004, 11, 24, 01, 04, 44)
+
+    travel_to expected_time
+    assert_equal expected_time, Time.now
+    assert_equal Date.new(2004, 11, 24), Date.today
+    travel_back
+
+    assert_not_equal expected_time, Time.now
+    assert_not_equal Date.new(2004, 11, 24), Date.today
+  end
+end
diff --git a/app/server/vendor/activesupport/test/testing/constant_lookup_test.rb b/app/server/vendor/activesupport/test/testing/constant_lookup_test.rb
new file mode 100644
index 0000000..71a9561
--- /dev/null
+++ b/app/server/vendor/activesupport/test/testing/constant_lookup_test.rb
@@ -0,0 +1,68 @@
+require 'abstract_unit'
+require 'dependencies_test_helpers'
+
+class Foo; end
+class Bar < Foo
+  def index; end
+  def self.index; end
+end
+module FooBar; end
+
+class ConstantLookupTest < ActiveSupport::TestCase
+  include ActiveSupport::Testing::ConstantLookup
+  include DependenciesTestHelpers
+
+  def find_foo(name)
+    self.class.determine_constant_from_test_name(name) do |constant|
+      Class === constant && constant < Foo
+    end
+  end
+
+  def find_module(name)
+    self.class.determine_constant_from_test_name(name) do |constant|
+      Module === constant
+    end
+  end
+
+  def test_find_bar_from_foo
+    assert_equal Bar, find_foo("Bar")
+    assert_equal Bar, find_foo("Bar::index")
+    assert_equal Bar, find_foo("Bar::index::authenticated")
+    assert_equal Bar, find_foo("BarTest")
+    assert_equal Bar, find_foo("BarTest::index")
+    assert_equal Bar, find_foo("BarTest::index::authenticated")
+  end
+
+  def test_find_module
+    assert_equal FooBar, find_module("FooBar")
+    assert_equal FooBar, find_module("FooBar::index")
+    assert_equal FooBar, find_module("FooBar::index::authenticated")
+    assert_equal FooBar, find_module("FooBarTest")
+    assert_equal FooBar, find_module("FooBarTest::index")
+    assert_equal FooBar, find_module("FooBarTest::index::authenticated")
+  end
+
+  def test_returns_nil_when_cant_find_foo
+    assert_nil find_foo("DoesntExist")
+    assert_nil find_foo("DoesntExistTest")
+    assert_nil find_foo("DoesntExist::Nadda")
+    assert_nil find_foo("DoesntExist::Nadda::Nope")
+    assert_nil find_foo("DoesntExist::Nadda::Nope::NotHere")
+  end
+
+  def test_returns_nil_when_cant_find_module
+    assert_nil find_module("DoesntExist")
+    assert_nil find_module("DoesntExistTest")
+    assert_nil find_module("DoesntExist::Nadda")
+    assert_nil find_module("DoesntExist::Nadda::Nope")
+    assert_nil find_module("DoesntExist::Nadda::Nope::NotHere")
+  end
+
+  def test_does_not_swallow_exception_on_no_method_error
+    assert_raises(NoMethodError) {
+      with_autoloading_fixtures {
+        self.class.determine_constant_from_test_name("RaisesNoMethodError")
+      }
+    }
+  end
+end
diff --git a/app/server/vendor/activesupport/test/time_zone_test.rb b/app/server/vendor/activesupport/test/time_zone_test.rb
new file mode 100644
index 0000000..79ec57a
--- /dev/null
+++ b/app/server/vendor/activesupport/test/time_zone_test.rb
@@ -0,0 +1,418 @@
+require 'abstract_unit'
+require 'active_support/time'
+
+class TimeZoneTest < ActiveSupport::TestCase
+  def test_utc_to_local
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    assert_equal Time.utc(1999, 12, 31, 19), zone.utc_to_local(Time.utc(2000, 1)) # standard offset -0500
+    assert_equal Time.utc(2000, 6, 30, 20), zone.utc_to_local(Time.utc(2000, 7)) # dst offset -0400
+  end
+
+  def test_local_to_utc
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    assert_equal Time.utc(2000, 1, 1, 5), zone.local_to_utc(Time.utc(2000, 1)) # standard offset -0500
+    assert_equal Time.utc(2000, 7, 1, 4), zone.local_to_utc(Time.utc(2000, 7)) # dst offset -0400
+  end
+
+  def test_period_for_local
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    assert_instance_of TZInfo::TimezonePeriod, zone.period_for_local(Time.utc(2000))
+  end
+
+  ActiveSupport::TimeZone::MAPPING.keys.each do |name|
+    define_method("test_map_#{name.downcase.gsub(/[^a-z]/, '_')}_to_tzinfo") do
+      zone = ActiveSupport::TimeZone[name]
+      assert_respond_to zone.tzinfo, :period_for_local
+    end
+  end
+
+  def test_from_integer_to_map
+    assert_instance_of ActiveSupport::TimeZone, ActiveSupport::TimeZone[-28800] # PST
+  end
+
+  def test_from_duration_to_map
+    assert_instance_of ActiveSupport::TimeZone, ActiveSupport::TimeZone[-480.minutes] # PST
+  end
+
+  ActiveSupport::TimeZone.all.each do |zone|
+    name = zone.name.downcase.gsub(/[^a-z]/, '_')
+    define_method("test_from_#{name}_to_map") do
+      assert_instance_of ActiveSupport::TimeZone, ActiveSupport::TimeZone[zone.name]
+    end
+
+    define_method("test_utc_offset_for_#{name}") do
+      period = zone.tzinfo.current_period
+      assert_equal period.utc_offset, zone.utc_offset
+    end
+  end
+
+  def test_now
+    with_env_tz 'US/Eastern' do
+      zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'].dup
+      def zone.time_now; Time.local(2000); end
+      assert_instance_of ActiveSupport::TimeWithZone, zone.now
+      assert_equal Time.utc(2000,1,1,5), zone.now.utc
+      assert_equal Time.utc(2000), zone.now.time
+      assert_equal zone, zone.now.time_zone
+    end
+  end
+
+  def test_now_enforces_spring_dst_rules
+    with_env_tz 'US/Eastern' do
+      zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'].dup
+      def zone.time_now
+        Time.local(2006,4,2,2) # 2AM springs forward to 3AM
+      end
+
+      assert_equal Time.utc(2006,4,2,3), zone.now.time
+      assert_equal true, zone.now.dst?
+    end
+  end
+
+  def test_now_enforces_fall_dst_rules
+    with_env_tz 'US/Eastern' do
+      zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'].dup
+      def zone.time_now
+        Time.at(1162098000) # equivalent to 1AM DST
+      end
+      assert_equal Time.utc(2006,10,29,1), zone.now.time
+      assert_equal true, zone.now.dst?
+    end
+  end
+
+  def test_unknown_timezones_delegation_to_tzinfo
+    zone = ActiveSupport::TimeZone['America/Montevideo']
+    assert_equal ActiveSupport::TimeZone, zone.class
+    assert_equal zone.object_id, ActiveSupport::TimeZone['America/Montevideo'].object_id
+    assert_equal Time.utc(2010, 1, 31, 22), zone.utc_to_local(Time.utc(2010, 2)) # daylight saving offset -0200
+    assert_equal Time.utc(2010, 3, 31, 21), zone.utc_to_local(Time.utc(2010, 4)) # standard offset -0300
+  end
+
+  def test_today
+    travel_to(Time.utc(2000, 1, 1, 4, 59, 59)) # 1 sec before midnight Jan 1 EST
+    assert_equal Date.new(1999, 12, 31), ActiveSupport::TimeZone['Eastern Time (US & Canada)'].today
+    travel_to(Time.utc(2000, 1, 1, 5)) # midnight Jan 1 EST
+    assert_equal Date.new(2000, 1, 1), ActiveSupport::TimeZone['Eastern Time (US & Canada)'].today
+    travel_to(Time.utc(2000, 1, 2, 4, 59, 59)) # 1 sec before midnight Jan 2 EST
+    assert_equal Date.new(2000, 1, 1), ActiveSupport::TimeZone['Eastern Time (US & Canada)'].today
+    travel_to(Time.utc(2000, 1, 2, 5)) # midnight Jan 2 EST
+    assert_equal Date.new(2000, 1, 2), ActiveSupport::TimeZone['Eastern Time (US & Canada)'].today
+    travel_back
+  end
+
+  def test_tomorrow
+    travel_to(Time.utc(2000, 1, 1, 4, 59, 59)) # 1 sec before midnight Jan 1 EST
+    assert_equal Date.new(2000, 1, 1), ActiveSupport::TimeZone['Eastern Time (US & Canada)'].tomorrow
+    travel_to(Time.utc(2000, 1, 1, 5)) # midnight Jan 1 EST
+    assert_equal Date.new(2000, 1, 2), ActiveSupport::TimeZone['Eastern Time (US & Canada)'].tomorrow
+    travel_to(Time.utc(2000, 1, 2, 4, 59, 59)) # 1 sec before midnight Jan 2 EST
+    assert_equal Date.new(2000, 1, 2), ActiveSupport::TimeZone['Eastern Time (US & Canada)'].tomorrow
+    travel_to(Time.utc(2000, 1, 2, 5)) # midnight Jan 2 EST
+    assert_equal Date.new(2000, 1, 3), ActiveSupport::TimeZone['Eastern Time (US & Canada)'].tomorrow
+    travel_back
+  end
+
+  def test_yesterday
+    travel_to(Time.utc(2000, 1, 1, 4, 59, 59)) # 1 sec before midnight Jan 1 EST
+    assert_equal Date.new(1999, 12, 30), ActiveSupport::TimeZone['Eastern Time (US & Canada)'].yesterday
+    travel_to(Time.utc(2000, 1, 1, 5)) # midnight Jan 1 EST
+    assert_equal Date.new(1999, 12, 31), ActiveSupport::TimeZone['Eastern Time (US & Canada)'].yesterday
+    travel_to(Time.utc(2000, 1, 2, 4, 59, 59)) # 1 sec before midnight Jan 2 EST
+    assert_equal Date.new(1999, 12, 31), ActiveSupport::TimeZone['Eastern Time (US & Canada)'].yesterday
+    travel_to(Time.utc(2000, 1, 2, 5)) # midnight Jan 2 EST
+    assert_equal Date.new(2000, 1, 1), ActiveSupport::TimeZone['Eastern Time (US & Canada)'].yesterday
+    travel_back
+  end
+
+  def test_travel_to_a_date
+    with_env_tz do
+      Time.use_zone('Hawaii') do
+        date = Date.new(2014, 2, 18)
+        time = date.midnight
+
+        travel_to date do
+          assert_equal date, Date.current
+          assert_equal time, Time.current
+        end
+      end
+    end
+  end
+
+  def test_travel_to_travels_back_and_reraises_if_the_block_raises
+    ts = Time.current - 1.second
+
+    travel_to ts do
+      raise
+    end
+
+    flunk # ensure travel_to re-raises
+  rescue
+    assert_not_equal ts, Time.current
+  end
+
+  def test_local
+    time = ActiveSupport::TimeZone["Hawaii"].local(2007, 2, 5, 15, 30, 45)
+    assert_equal Time.utc(2007, 2, 5, 15, 30, 45), time.time
+    assert_equal ActiveSupport::TimeZone["Hawaii"], time.time_zone
+  end
+
+  def test_local_with_old_date
+    time = ActiveSupport::TimeZone["Hawaii"].local(1850, 2, 5, 15, 30, 45)
+    assert_equal [45,30,15,5,2,1850], time.to_a[0,6]
+    assert_equal ActiveSupport::TimeZone["Hawaii"], time.time_zone
+  end
+
+  def test_local_enforces_spring_dst_rules
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    twz = zone.local(2006,4,2,1,59,59) # 1 second before DST start
+    assert_equal Time.utc(2006,4,2,1,59,59), twz.time
+    assert_equal Time.utc(2006,4,2,6,59,59), twz.utc
+    assert_equal false, twz.dst?
+    assert_equal 'EST', twz.zone
+    twz2 = zone.local(2006,4,2,2) # 2AM does not exist because at 2AM, time springs forward to 3AM
+    assert_equal Time.utc(2006,4,2,3), twz2.time # twz is created for 3AM
+    assert_equal Time.utc(2006,4,2,7), twz2.utc
+    assert_equal true, twz2.dst?
+    assert_equal 'EDT', twz2.zone
+    twz3 = zone.local(2006,4,2,2,30) # 2:30AM does not exist because at 2AM, time springs forward to 3AM
+    assert_equal Time.utc(2006,4,2,3,30), twz3.time # twz is created for 3:30AM
+    assert_equal Time.utc(2006,4,2,7,30), twz3.utc
+    assert_equal true, twz3.dst?
+    assert_equal 'EDT', twz3.zone
+  end
+
+  def test_local_enforces_fall_dst_rules
+    # 1AM during fall DST transition is ambiguous, it could be either DST or non-DST 1AM
+    # Mirroring Time.local behavior, this method selects the DST time
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    twz = zone.local(2006,10,29,1)
+    assert_equal Time.utc(2006,10,29,1), twz.time
+    assert_equal Time.utc(2006,10,29,5), twz.utc
+    assert_equal true, twz.dst?
+    assert_equal 'EDT', twz.zone
+  end
+
+  def test_at
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    secs = 946684800.0
+    twz = zone.at(secs)
+    assert_equal Time.utc(1999,12,31,19), twz.time
+    assert_equal Time.utc(2000), twz.utc
+    assert_equal zone, twz.time_zone
+    assert_equal secs, twz.to_f
+  end
+
+  def test_at_with_old_date
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    secs = DateTime.civil(1850).to_f
+    twz = zone.at(secs)
+    assert_equal [1850, 1, 1, 0], [twz.utc.year, twz.utc.mon, twz.utc.day, twz.utc.hour]
+    assert_equal zone, twz.time_zone
+    assert_equal secs, twz.to_f
+  end
+
+  def test_parse
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    twz = zone.parse('1999-12-31 19:00:00')
+    assert_equal Time.utc(1999,12,31,19), twz.time
+    assert_equal Time.utc(2000), twz.utc
+    assert_equal zone, twz.time_zone
+  end
+
+  def test_parse_string_with_timezone
+    (-11..13).each do |timezone_offset|
+      zone = ActiveSupport::TimeZone[timezone_offset]
+      twz = zone.parse('1999-12-31 19:00:00')
+      assert_equal twz, zone.parse(twz.to_s)
+    end
+  end
+
+  def test_parse_with_old_date
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    twz = zone.parse('1883-12-31 19:00:00')
+    assert_equal [0,0,19,31,12,1883], twz.to_a[0,6]
+    assert_equal zone, twz.time_zone
+  end
+
+  def test_parse_far_future_date_with_time_zone_offset_in_string
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    twz = zone.parse('2050-12-31 19:00:00 -10:00') # i.e., 2050-01-01 05:00:00 UTC
+    assert_equal [0,0,0,1,1,2051], twz.to_a[0,6]
+    assert_equal zone, twz.time_zone
+  end
+
+  def test_parse_returns_nil_when_string_without_date_information_is_passed_in
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    assert_nil zone.parse('foobar')
+    assert_nil zone.parse('   ')
+  end
+
+  def test_parse_with_incomplete_date
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    zone.stubs(:now).returns zone.local(1999,12,31)
+    twz = zone.parse('19:00:00')
+    assert_equal Time.utc(1999,12,31,19), twz.time
+  end
+
+  def test_parse_should_not_black_out_system_timezone_dst_jump
+    with_env_tz('EET') do
+      zone = ActiveSupport::TimeZone['Pacific Time (US & Canada)']
+      twz = zone.parse('2012-03-25 03:29:00')
+      assert_equal [0, 29, 3, 25, 3, 2012], twz.to_a[0,6]
+    end
+  end
+
+  def test_parse_should_black_out_app_timezone_dst_jump
+    with_env_tz('EET') do
+      zone = ActiveSupport::TimeZone['Pacific Time (US & Canada)']
+      twz = zone.parse('2012-03-11 02:29:00')
+      assert_equal [0, 29, 3, 11, 3, 2012], twz.to_a[0,6]
+    end
+  end
+
+  def test_parse_with_missing_time_components
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    zone.stubs(:now).returns zone.local(1999, 12, 31, 12, 59, 59)
+    twz = zone.parse('2012-12-01')
+    assert_equal Time.utc(2012, 12, 1), twz.time
+  end
+
+  def test_parse_with_javascript_date
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    twz = zone.parse("Mon May 28 2012 00:00:00 GMT-0700 (PDT)")
+    assert_equal Time.utc(2012, 5, 28, 7, 0, 0), twz.utc
+  end
+
+  def test_parse_doesnt_use_local_dst
+    with_env_tz 'US/Eastern' do
+      zone = ActiveSupport::TimeZone['UTC']
+      twz = zone.parse('2013-03-10 02:00:00')
+      assert_equal Time.utc(2013, 3, 10, 2, 0, 0), twz.time
+    end
+  end
+
+  def test_parse_handles_dst_jump
+    with_env_tz 'US/Eastern' do
+      zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+      twz = zone.parse('2013-03-10 02:00:00')
+      assert_equal Time.utc(2013, 3, 10, 3, 0, 0), twz.time
+    end
+  end
+
+  def test_utc_offset_lazy_loaded_from_tzinfo_when_not_passed_in_to_initialize
+    tzinfo = TZInfo::Timezone.get('America/New_York')
+    zone = ActiveSupport::TimeZone.create(tzinfo.name, nil, tzinfo)
+    assert_equal nil, zone.instance_variable_get('@utc_offset')
+    assert_equal(-18_000, zone.utc_offset)
+  end
+
+  def test_seconds_to_utc_offset_with_colon
+    assert_equal "-06:00", ActiveSupport::TimeZone.seconds_to_utc_offset(-21_600)
+    assert_equal "+00:00", ActiveSupport::TimeZone.seconds_to_utc_offset(0)
+    assert_equal "+05:00", ActiveSupport::TimeZone.seconds_to_utc_offset(18_000)
+  end
+
+  def test_seconds_to_utc_offset_without_colon
+    assert_equal "-0600", ActiveSupport::TimeZone.seconds_to_utc_offset(-21_600, false)
+    assert_equal "+0000", ActiveSupport::TimeZone.seconds_to_utc_offset(0, false)
+    assert_equal "+0500", ActiveSupport::TimeZone.seconds_to_utc_offset(18_000, false)
+  end
+
+  def test_seconds_to_utc_offset_with_negative_offset
+    assert_equal "-01:00", ActiveSupport::TimeZone.seconds_to_utc_offset(-3_600)
+    assert_equal "-00:59", ActiveSupport::TimeZone.seconds_to_utc_offset(-3_599)
+    assert_equal "-05:30", ActiveSupport::TimeZone.seconds_to_utc_offset(-19_800)
+  end
+
+  def test_formatted_offset_positive
+    zone = ActiveSupport::TimeZone['New Delhi']
+    assert_equal "+05:30", zone.formatted_offset
+    assert_equal "+0530", zone.formatted_offset(false)
+  end
+
+  def test_formatted_offset_negative
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    assert_equal "-05:00", zone.formatted_offset
+    assert_equal "-0500", zone.formatted_offset(false)
+  end
+
+  def test_z_format_strings
+    zone = ActiveSupport::TimeZone['Tokyo']
+    twz = zone.now
+    assert_equal '+0900',     twz.strftime('%z')
+    assert_equal '+09:00',    twz.strftime('%:z')
+    assert_equal '+09:00:00', twz.strftime('%::z')
+  end
+
+  def test_formatted_offset_zero
+    zone = ActiveSupport::TimeZone['London']
+    assert_equal "+00:00", zone.formatted_offset
+    assert_equal "UTC", zone.formatted_offset(true, 'UTC')
+  end
+
+  def test_zone_compare
+    zone1 = ActiveSupport::TimeZone['Central Time (US & Canada)'] # offset -0600
+    zone2 = ActiveSupport::TimeZone['Eastern Time (US & Canada)'] # offset -0500
+    assert zone1 < zone2
+    assert zone2 > zone1
+    assert zone1 == zone1
+  end
+
+  def test_zone_match
+    zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+    assert zone =~ /Eastern/
+    assert zone =~ /New_York/
+    assert zone !~ /Nonexistent_Place/
+  end
+
+  def test_to_s
+    assert_equal "(GMT+05:30) New Delhi", ActiveSupport::TimeZone['New Delhi'].to_s
+  end
+
+  def test_all_sorted
+    all = ActiveSupport::TimeZone.all
+    1.upto( all.length-1 ) do |i|
+      assert all[i-1] < all[i]
+    end
+  end
+
+  def test_index
+    assert_nil ActiveSupport::TimeZone["bogus"]
+    assert_instance_of ActiveSupport::TimeZone, ActiveSupport::TimeZone["Central Time (US & Canada)"]
+    assert_instance_of ActiveSupport::TimeZone, ActiveSupport::TimeZone[8]
+    assert_raise(ArgumentError) { ActiveSupport::TimeZone[false] }
+  end
+
+  def test_unknown_zone_should_have_tzinfo_but_exception_on_utc_offset
+    zone = ActiveSupport::TimeZone.create("bogus")
+    assert_instance_of TZInfo::TimezoneProxy, zone.tzinfo
+    assert_raise(TZInfo::InvalidTimezoneIdentifier) { zone.utc_offset }
+  end
+
+  def test_unknown_zone_with_utc_offset
+    zone = ActiveSupport::TimeZone.create("bogus", -21_600)
+    assert_equal(-21_600, zone.utc_offset)
+  end
+
+  def test_unknown_zones_dont_store_mapping_keys
+    ActiveSupport::TimeZone["bogus"]
+    assert !ActiveSupport::TimeZone.zones_map.key?("bogus")
+  end
+
+  def test_new
+    assert_equal ActiveSupport::TimeZone["Central Time (US & Canada)"], ActiveSupport::TimeZone.new("Central Time (US & Canada)")
+  end
+
+  def test_us_zones
+    assert ActiveSupport::TimeZone.us_zones.include?(ActiveSupport::TimeZone["Hawaii"])
+    assert !ActiveSupport::TimeZone.us_zones.include?(ActiveSupport::TimeZone["Kuala Lumpur"])
+  end
+
+  protected
+    def with_env_tz(new_tz = 'US/Eastern')
+      old_tz, ENV['TZ'] = ENV['TZ'], new_tz
+      yield
+    ensure
+      old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+    end
+end
diff --git a/app/server/vendor/activesupport/test/transliterate_test.rb b/app/server/vendor/activesupport/test/transliterate_test.rb
new file mode 100644
index 0000000..e0f85f4
--- /dev/null
+++ b/app/server/vendor/activesupport/test/transliterate_test.rb
@@ -0,0 +1,35 @@
+# encoding: utf-8
+require 'abstract_unit'
+require 'active_support/inflector/transliterate'
+
+class TransliterateTest < ActiveSupport::TestCase
+  def test_transliterate_should_not_change_ascii_chars
+    (0..127).each do |byte|
+      char = [byte].pack("U")
+      assert_equal char, ActiveSupport::Inflector.transliterate(char)
+    end
+  end
+
+  def test_transliterate_should_approximate_ascii
+    # create string with range of Unicode"s western characters with
+    # diacritics, excluding the division and multiplication signs which for
+    # some reason or other are floating in the middle of all the letters.
+    string = (0xC0..0x17E).to_a.reject {|c| [0xD7, 0xF7].include?(c)}.pack("U*")
+    string.each_char do |char|
+      assert_match %r{^[a-zA-Z']*$}, ActiveSupport::Inflector.transliterate(char)
+    end
+  end
+
+  def test_transliterate_should_work_with_custom_i18n_rules_and_uncomposed_utf8
+    char = [117, 776].pack("U*") # "ü" as ASCII "u" plus COMBINING DIAERESIS
+    I18n.backend.store_translations(:de, :i18n => {:transliterate => {:rule => {"ü" => "ue"}}})
+    default_locale, I18n.locale = I18n.locale, :de
+    assert_equal "ue", ActiveSupport::Inflector.transliterate(char)
+  ensure
+    I18n.locale = default_locale
+  end
+
+  def test_transliterate_should_allow_a_custom_replacement_char
+    assert_equal "a*b", ActiveSupport::Inflector.transliterate("aç´¢b", "*")
+  end
+end
diff --git a/app/server/vendor/activesupport/test/xml_mini/jdom_engine_test.rb b/app/server/vendor/activesupport/test/xml_mini/jdom_engine_test.rb
new file mode 100644
index 0000000..ed4de8a
--- /dev/null
+++ b/app/server/vendor/activesupport/test/xml_mini/jdom_engine_test.rb
@@ -0,0 +1,188 @@
+if RUBY_PLATFORM =~ /java/
+  require 'abstract_unit'
+  require 'active_support/xml_mini'
+  require 'active_support/core_ext/hash/conversions'
+
+
+  class JDOMEngineTest < ActiveSupport::TestCase
+    include ActiveSupport
+
+    FILES_DIR = File.dirname(__FILE__) + '/../fixtures/xml'
+
+    def setup
+      @default_backend = XmlMini.backend
+      XmlMini.backend = 'JDOM'
+    end
+
+    def teardown
+      XmlMini.backend = @default_backend
+    end
+
+    def test_file_from_xml
+       hash = Hash.from_xml(<<-eoxml)
+         <blog>
+           <logo type="file" name="logo.png" content_type="image/png">
+           </logo>
+         </blog>
+       eoxml
+       assert hash.has_key?('blog')
+       assert hash['blog'].has_key?('logo')
+
+       file = hash['blog']['logo']
+       assert_equal 'logo.png', file.original_filename
+       assert_equal 'image/png', file.content_type
+    end
+
+    def test_not_allowed_to_expand_entities_to_files
+      attack_xml = <<-EOT
+      <!DOCTYPE member [
+        <!ENTITY a SYSTEM "file://#{FILES_DIR}/jdom_include.txt">
+      ]>
+      <member>x&a;</member>
+      EOT
+      assert_equal 'x', Hash.from_xml(attack_xml)["member"]
+    end
+
+    def test_not_allowed_to_expand_parameter_entities_to_files
+      attack_xml = <<-EOT
+      <!DOCTYPE member [
+        <!ENTITY % b SYSTEM "file://#{FILES_DIR}/jdom_entities.txt">
+        %b;
+      ]>
+      <member>x&a;</member>
+      EOT
+      assert_raise Java::OrgXmlSax::SAXParseException do
+        assert_equal 'x', Hash.from_xml(attack_xml)["member"]
+      end
+    end
+
+
+    def test_not_allowed_to_load_external_doctypes
+      attack_xml = <<-EOT
+      <!DOCTYPE member SYSTEM "file://#{FILES_DIR}/jdom_doctype.dtd">
+      <member>x&a;</member>
+      EOT
+      assert_equal 'x', Hash.from_xml(attack_xml)["member"]
+    end
+
+    def test_exception_thrown_on_expansion_attack
+      assert_raise Java::OrgXmlSax::SAXParseException do
+        attack_xml = <<-EOT
+      <!DOCTYPE member [
+        <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
+        <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
+        <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
+        <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
+        <!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
+        <!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
+        <!ENTITY g "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
+      ]>
+      <member>
+      &a;
+      </member>
+        EOT
+        Hash.from_xml(attack_xml)
+      end
+    end
+
+    def test_setting_JDOM_as_backend
+      XmlMini.backend = 'JDOM'
+      assert_equal XmlMini_JDOM, XmlMini.backend
+    end
+
+    def test_blank_returns_empty_hash
+      assert_equal({}, XmlMini.parse(nil))
+      assert_equal({}, XmlMini.parse(''))
+    end
+
+    def test_array_type_makes_an_array
+      assert_equal_rexml(<<-eoxml)
+      <blog>
+        <posts type="array">
+          <post>a post</post>
+          <post>another post</post>
+        </posts>
+      </blog>
+      eoxml
+    end
+
+    def test_one_node_document_as_hash
+      assert_equal_rexml(<<-eoxml)
+    <products/>
+      eoxml
+    end
+
+    def test_one_node_with_attributes_document_as_hash
+      assert_equal_rexml(<<-eoxml)
+    <products foo="bar"/>
+      eoxml
+    end
+
+    def test_products_node_with_book_node_as_hash
+      assert_equal_rexml(<<-eoxml)
+    <products>
+      <book name="awesome" id="12345" />
+    </products>
+      eoxml
+    end
+
+    def test_products_node_with_two_book_nodes_as_hash
+      assert_equal_rexml(<<-eoxml)
+    <products>
+      <book name="awesome" id="12345" />
+      <book name="america" id="67890" />
+    </products>
+      eoxml
+    end
+
+    def test_single_node_with_content_as_hash
+      assert_equal_rexml(<<-eoxml)
+      <products>
+        hello world
+      </products>
+      eoxml
+    end
+
+    def test_children_with_children
+      assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+        <book name="america" id="67890" />
+      </products>
+    </root>
+      eoxml
+    end
+
+    def test_children_with_text
+      assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+        hello everyone
+      </products>
+    </root>
+      eoxml
+    end
+
+    def test_children_with_non_adjacent_text
+      assert_equal_rexml(<<-eoxml)
+    <root>
+      good
+      <products>
+        hello everyone
+      </products>
+      morning
+    </root>
+      eoxml
+    end
+
+    private
+      def assert_equal_rexml(xml)
+        parsed_xml = XmlMini.parse(xml)
+        hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
+        assert_equal(hash, parsed_xml)
+      end
+  end
+
+else
+  # don't run these test because we aren't running in JRuby
+end
diff --git a/app/server/vendor/activesupport/test/xml_mini/libxml_engine_test.rb b/app/server/vendor/activesupport/test/xml_mini/libxml_engine_test.rb
new file mode 100644
index 0000000..a8df2e1
--- /dev/null
+++ b/app/server/vendor/activesupport/test/xml_mini/libxml_engine_test.rb
@@ -0,0 +1,204 @@
+begin
+  require 'libxml'
+rescue LoadError
+  # Skip libxml tests
+else
+require 'abstract_unit'
+require 'active_support/xml_mini'
+require 'active_support/core_ext/hash/conversions'
+
+class LibxmlEngineTest < ActiveSupport::TestCase
+  include ActiveSupport
+
+  def setup
+    @default_backend = XmlMini.backend
+    XmlMini.backend = 'LibXML'
+
+    LibXML::XML::Error.set_handler(&lambda { |error| }) #silence libxml, exceptions will do
+  end
+
+  def teardown
+    XmlMini.backend = @default_backend
+  end
+
+  def test_exception_thrown_on_expansion_attack
+    assert_raise LibXML::XML::Error do
+      attack_xml = %{<?xml version="1.0" encoding="UTF-8"?>
+      <!DOCTYPE member [
+        <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
+        <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
+        <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
+        <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
+        <!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
+        <!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
+        <!ENTITY g "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
+      ]>
+      <member>
+      &a;
+      </member>
+     }
+      Hash.from_xml(attack_xml)
+    end
+  end
+
+  def test_setting_libxml_as_backend
+    XmlMini.backend = 'LibXML'
+    assert_equal XmlMini_LibXML, XmlMini.backend
+  end
+
+  def test_blank_returns_empty_hash
+    assert_equal({}, XmlMini.parse(nil))
+    assert_equal({}, XmlMini.parse(''))
+  end
+
+  def test_array_type_makes_an_array
+    assert_equal_rexml(<<-eoxml)
+      <blog>
+        <posts type="array">
+          <post>a post</post>
+          <post>another post</post>
+        </posts>
+      </blog>
+    eoxml
+  end
+
+  def test_one_node_document_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products/>
+    eoxml
+  end
+
+  def test_one_node_with_attributes_document_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products foo="bar"/>
+    eoxml
+  end
+
+  def test_products_node_with_book_node_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products>
+      <book name="awesome" id="12345" />
+    </products>
+    eoxml
+  end
+
+  def test_products_node_with_two_book_nodes_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products>
+      <book name="awesome" id="12345" />
+      <book name="america" id="67890" />
+    </products>
+    eoxml
+  end
+
+  def test_single_node_with_content_as_hash
+    assert_equal_rexml(<<-eoxml)
+      <products>
+        hello world
+      </products>
+    eoxml
+  end
+
+  def test_children_with_children
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+        <book name="america" id="67890" />
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_text
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+        hello everyone
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_non_adjacent_text
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      good
+      <products>
+        hello everyone
+      </products>
+      morning
+    </root>
+    eoxml
+  end
+
+  def test_parse_from_io
+    io = StringIO.new(<<-eoxml)
+    <root>
+      good
+      <products>
+        hello everyone
+      </products>
+      morning
+    </root>
+    eoxml
+    assert_equal_rexml(io)
+  end
+
+  def test_children_with_simple_cdata
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+         <![CDATA[cdatablock]]>
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_multiple_cdata
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+         <![CDATA[cdatablock1]]><![CDATA[cdatablock2]]>
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_text_and_cdata
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+        hello <![CDATA[cdatablock]]>
+        morning
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_blank_text
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>   </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_blank_text_and_attribute
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products type="file">   </products>
+    </root>
+    eoxml
+  end
+
+
+  private
+    def assert_equal_rexml(xml)
+      parsed_xml = XmlMini.parse(xml)
+      xml.rewind if xml.respond_to?(:rewind)
+      hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
+      assert_equal(hash, parsed_xml)
+    end
+end
+
+end
diff --git a/app/server/vendor/activesupport/test/xml_mini/libxmlsax_engine_test.rb b/app/server/vendor/activesupport/test/xml_mini/libxmlsax_engine_test.rb
new file mode 100644
index 0000000..d6d9063
--- /dev/null
+++ b/app/server/vendor/activesupport/test/xml_mini/libxmlsax_engine_test.rb
@@ -0,0 +1,195 @@
+begin
+  require 'libxml'
+rescue LoadError
+  # Skip libxml tests
+else
+require 'abstract_unit'
+require 'active_support/xml_mini'
+require 'active_support/core_ext/hash/conversions'
+
+class LibXMLSAXEngineTest < ActiveSupport::TestCase
+  include ActiveSupport
+
+  def setup
+    @default_backend = XmlMini.backend
+    XmlMini.backend = 'LibXMLSAX'
+  end
+
+  def teardown
+    XmlMini.backend = @default_backend
+  end
+
+  def test_exception_thrown_on_expansion_attack
+    assert_raise LibXML::XML::Error do
+      attack_xml = <<-EOT
+      <?xml version="1.0" encoding="UTF-8"?>
+      <!DOCTYPE member [
+        <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
+        <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
+        <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
+        <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
+        <!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
+        <!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
+        <!ENTITY g "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
+      ]>
+      <member>
+      &a;
+      </member>
+      EOT
+
+      Hash.from_xml(attack_xml)
+    end
+  end
+
+  def test_setting_libxml_as_backend
+    XmlMini.backend = 'LibXMLSAX'
+    assert_equal XmlMini_LibXMLSAX, XmlMini.backend
+  end
+
+  def test_blank_returns_empty_hash
+    assert_equal({}, XmlMini.parse(nil))
+    assert_equal({}, XmlMini.parse(''))
+  end
+
+  def test_array_type_makes_an_array
+    assert_equal_rexml(<<-eoxml)
+      <blog>
+        <posts type="array">
+          <post>a post</post>
+          <post>another post</post>
+        </posts>
+      </blog>
+    eoxml
+  end
+
+  def test_one_node_document_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products/>
+    eoxml
+  end
+
+  def test_one_node_with_attributes_document_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products foo="bar"/>
+    eoxml
+  end
+
+  def test_products_node_with_book_node_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products>
+      <book name="awesome" id="12345" />
+    </products>
+    eoxml
+  end
+
+  def test_products_node_with_two_book_nodes_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products>
+      <book name="awesome" id="12345" />
+      <book name="america" id="67890" />
+    </products>
+    eoxml
+  end
+
+  def test_single_node_with_content_as_hash
+    assert_equal_rexml(<<-eoxml)
+      <products>
+        hello world
+      </products>
+    eoxml
+  end
+
+  def test_children_with_children
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+        <book name="america" id="67890" />
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_text
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+        hello everyone
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_non_adjacent_text
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      good
+      <products>
+        hello everyone
+      </products>
+      morning
+    </root>
+    eoxml
+  end
+
+  def test_parse_from_io
+    io = StringIO.new(<<-eoxml)
+    <root>
+      good
+      <products>
+        hello everyone
+      </products>
+      morning
+    </root>
+    eoxml
+    assert_equal_rexml(io)
+  end
+
+  def test_children_with_simple_cdata
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+         <![CDATA[cdatablock]]>
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_multiple_cdata
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+         <![CDATA[cdatablock1]]><![CDATA[cdatablock2]]>
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_text_and_cdata
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+        hello <![CDATA[cdatablock]]>
+        morning
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_blank_text
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>   </products>
+    </root>
+    eoxml
+  end
+
+  private
+    def assert_equal_rexml(xml)
+      parsed_xml = XmlMini.parse(xml)
+      xml.rewind if xml.respond_to?(:rewind)
+      hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
+      assert_equal(hash, parsed_xml)
+    end
+end
+
+end
diff --git a/app/server/vendor/activesupport/test/xml_mini/nokogiri_engine_test.rb b/app/server/vendor/activesupport/test/xml_mini/nokogiri_engine_test.rb
new file mode 100644
index 0000000..2e96257
--- /dev/null
+++ b/app/server/vendor/activesupport/test/xml_mini/nokogiri_engine_test.rb
@@ -0,0 +1,217 @@
+begin
+  require 'nokogiri'
+rescue LoadError
+  # Skip nokogiri tests
+else
+require 'abstract_unit'
+require 'active_support/xml_mini'
+require 'active_support/core_ext/hash/conversions'
+
+class NokogiriEngineTest < ActiveSupport::TestCase
+  include ActiveSupport
+
+  def setup
+    @default_backend = XmlMini.backend
+    XmlMini.backend = 'Nokogiri'
+  end
+
+  def teardown
+    XmlMini.backend = @default_backend
+  end
+
+  def test_file_from_xml
+    hash = Hash.from_xml(<<-eoxml)
+      <blog>
+        <logo type="file" name="logo.png" content_type="image/png">
+        </logo>
+      </blog>
+    eoxml
+    assert hash.has_key?('blog')
+    assert hash['blog'].has_key?('logo')
+
+    file = hash['blog']['logo']
+    assert_equal 'logo.png', file.original_filename
+    assert_equal 'image/png', file.content_type
+  end
+
+  def test_exception_thrown_on_expansion_attack
+    assert_raise Nokogiri::XML::SyntaxError do
+      attack_xml = <<-EOT
+      <?xml version="1.0" encoding="UTF-8"?>
+      <!DOCTYPE member [
+        <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
+        <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
+        <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
+        <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
+        <!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
+        <!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
+        <!ENTITY g "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
+      ]>
+      <member>
+      &a;
+      </member>
+      EOT
+      Hash.from_xml(attack_xml)
+    end
+  end
+
+  def test_setting_nokogiri_as_backend
+    XmlMini.backend = 'Nokogiri'
+    assert_equal XmlMini_Nokogiri, XmlMini.backend
+  end
+
+  def test_blank_returns_empty_hash
+    assert_equal({}, XmlMini.parse(nil))
+    assert_equal({}, XmlMini.parse(''))
+  end
+
+  def test_array_type_makes_an_array
+    assert_equal_rexml(<<-eoxml)
+      <blog>
+        <posts type="array">
+          <post>a post</post>
+          <post>another post</post>
+        </posts>
+      </blog>
+    eoxml
+  end
+
+  def test_one_node_document_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products/>
+    eoxml
+  end
+
+  def test_one_node_with_attributes_document_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products foo="bar"/>
+    eoxml
+  end
+
+  def test_products_node_with_book_node_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products>
+      <book name="awesome" id="12345" />
+    </products>
+    eoxml
+  end
+
+  def test_products_node_with_two_book_nodes_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products>
+      <book name="awesome" id="12345" />
+      <book name="america" id="67890" />
+    </products>
+    eoxml
+  end
+
+  def test_single_node_with_content_as_hash
+    assert_equal_rexml(<<-eoxml)
+      <products>
+        hello world
+      </products>
+    eoxml
+  end
+
+  def test_children_with_children
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+        <book name="america" id="67890" />
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_text
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+        hello everyone
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_non_adjacent_text
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      good
+      <products>
+        hello everyone
+      </products>
+      morning
+    </root>
+    eoxml
+  end
+
+  def test_parse_from_io
+    io = StringIO.new(<<-eoxml)
+    <root>
+      good
+      <products>
+        hello everyone
+      </products>
+      morning
+    </root>
+    eoxml
+    assert_equal_rexml(io)
+  end
+
+  def test_children_with_simple_cdata
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+         <![CDATA[cdatablock]]>
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_multiple_cdata
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+         <![CDATA[cdatablock1]]><![CDATA[cdatablock2]]>
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_text_and_cdata
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+        hello <![CDATA[cdatablock]]>
+        morning
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_blank_text
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>   </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_blank_text_and_attribute
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products type="file">   </products>
+    </root>
+    eoxml
+  end
+
+  private
+    def assert_equal_rexml(xml)
+      parsed_xml = XmlMini.parse(xml)
+      xml.rewind if xml.respond_to?(:rewind)
+      hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
+      assert_equal(hash, parsed_xml)
+    end
+end
+
+end
diff --git a/app/server/vendor/activesupport/test/xml_mini/nokogirisax_engine_test.rb b/app/server/vendor/activesupport/test/xml_mini/nokogirisax_engine_test.rb
new file mode 100644
index 0000000..4f078f3
--- /dev/null
+++ b/app/server/vendor/activesupport/test/xml_mini/nokogirisax_engine_test.rb
@@ -0,0 +1,218 @@
+begin
+  require 'nokogiri'
+rescue LoadError
+  # Skip nokogiri tests
+else
+require 'abstract_unit'
+require 'active_support/xml_mini'
+require 'active_support/core_ext/hash/conversions'
+
+class NokogiriSAXEngineTest < ActiveSupport::TestCase
+  include ActiveSupport
+
+  def setup
+    @default_backend = XmlMini.backend
+    XmlMini.backend = 'NokogiriSAX'
+  end
+
+  def teardown
+    XmlMini.backend = @default_backend
+  end
+
+  def test_file_from_xml
+    hash = Hash.from_xml(<<-eoxml)
+      <blog>
+        <logo type="file" name="logo.png" content_type="image/png">
+        </logo>
+      </blog>
+    eoxml
+    assert hash.has_key?('blog')
+    assert hash['blog'].has_key?('logo')
+
+    file = hash['blog']['logo']
+    assert_equal 'logo.png', file.original_filename
+    assert_equal 'image/png', file.content_type
+  end
+
+  def test_exception_thrown_on_expansion_attack
+    assert_raise RuntimeError do
+      attack_xml = <<-EOT
+      <?xml version="1.0" encoding="UTF-8"?>
+      <!DOCTYPE member [
+        <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
+        <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
+        <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
+        <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
+        <!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
+        <!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
+        <!ENTITY g "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
+      ]>
+      <member>
+      &a;
+      </member>
+      EOT
+
+      Hash.from_xml(attack_xml)
+    end
+  end
+
+  def test_setting_nokogirisax_as_backend
+    XmlMini.backend = 'NokogiriSAX'
+    assert_equal XmlMini_NokogiriSAX, XmlMini.backend
+  end
+
+  def test_blank_returns_empty_hash
+    assert_equal({}, XmlMini.parse(nil))
+    assert_equal({}, XmlMini.parse(''))
+  end
+
+  def test_array_type_makes_an_array
+    assert_equal_rexml(<<-eoxml)
+      <blog>
+        <posts type="array">
+          <post>a post</post>
+          <post>another post</post>
+        </posts>
+      </blog>
+    eoxml
+  end
+
+  def test_one_node_document_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products/>
+    eoxml
+  end
+
+  def test_one_node_with_attributes_document_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products foo="bar"/>
+    eoxml
+  end
+
+  def test_products_node_with_book_node_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products>
+      <book name="awesome" id="12345" />
+    </products>
+    eoxml
+  end
+
+  def test_products_node_with_two_book_nodes_as_hash
+    assert_equal_rexml(<<-eoxml)
+    <products>
+      <book name="awesome" id="12345" />
+      <book name="america" id="67890" />
+    </products>
+    eoxml
+  end
+
+  def test_single_node_with_content_as_hash
+    assert_equal_rexml(<<-eoxml)
+      <products>
+        hello world
+      </products>
+    eoxml
+  end
+
+  def test_children_with_children
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+        <book name="america" id="67890" />
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_text
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+        hello everyone
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_non_adjacent_text
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      good
+      <products>
+        hello everyone
+      </products>
+      morning
+    </root>
+    eoxml
+  end
+
+  def test_parse_from_io
+    io = StringIO.new(<<-eoxml)
+    <root>
+      good
+      <products>
+        hello everyone
+      </products>
+      morning
+    </root>
+    eoxml
+    assert_equal_rexml(io)
+  end
+
+  def test_children_with_simple_cdata
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+         <![CDATA[cdatablock]]>
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_multiple_cdata
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+         <![CDATA[cdatablock1]]><![CDATA[cdatablock2]]>
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_text_and_cdata
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>
+        hello <![CDATA[cdatablock]]>
+        morning
+      </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_blank_text
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products>   </products>
+    </root>
+    eoxml
+  end
+
+  def test_children_with_blank_text_and_attribute
+    assert_equal_rexml(<<-eoxml)
+    <root>
+      <products type="file">   </products>
+    </root>
+    eoxml
+  end
+
+  private
+    def assert_equal_rexml(xml)
+      parsed_xml = XmlMini.parse(xml)
+      xml.rewind if xml.respond_to?(:rewind)
+      hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
+      assert_equal(hash, parsed_xml)
+    end
+end
+
+end
diff --git a/app/server/vendor/activesupport/test/xml_mini/rexml_engine_test.rb b/app/server/vendor/activesupport/test/xml_mini/rexml_engine_test.rb
new file mode 100644
index 0000000..0c1f118
--- /dev/null
+++ b/app/server/vendor/activesupport/test/xml_mini/rexml_engine_test.rb
@@ -0,0 +1,37 @@
+require 'abstract_unit'
+require 'active_support/xml_mini'
+
+class REXMLEngineTest < ActiveSupport::TestCase
+  include ActiveSupport
+
+  def test_default_is_rexml
+    assert_equal XmlMini_REXML, XmlMini.backend
+  end
+
+  def test_set_rexml_as_backend
+    XmlMini.backend = 'REXML'
+    assert_equal XmlMini_REXML, XmlMini.backend
+  end
+
+  def test_parse_from_io
+    XmlMini.backend = 'REXML'
+    io = StringIO.new(<<-eoxml)
+    <root>
+      good
+      <products>
+        hello everyone
+      </products>
+      morning
+    </root>
+    eoxml
+    assert_equal_rexml(io)
+  end
+
+  private
+    def assert_equal_rexml(xml)
+      parsed_xml = XmlMini.parse(xml)
+      xml.rewind if xml.respond_to?(:rewind)
+      hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
+      assert_equal(hash, parsed_xml)
+    end
+end
diff --git a/app/server/vendor/activesupport/test/xml_mini_test.rb b/app/server/vendor/activesupport/test/xml_mini_test.rb
new file mode 100644
index 0000000..753effb
--- /dev/null
+++ b/app/server/vendor/activesupport/test/xml_mini_test.rb
@@ -0,0 +1,296 @@
+require 'abstract_unit'
+require 'active_support/xml_mini'
+require 'active_support/builder'
+
+module XmlMiniTest
+  class RenameKeyTest < ActiveSupport::TestCase
+    def test_rename_key_dasherizes_by_default
+      assert_equal "my-key", ActiveSupport::XmlMini.rename_key("my_key")
+    end
+
+    def test_rename_key_does_nothing_with_dasherize_true
+      assert_equal "my-key", ActiveSupport::XmlMini.rename_key("my_key", :dasherize => true)
+    end
+
+    def test_rename_key_does_nothing_with_dasherize_false
+      assert_equal "my_key", ActiveSupport::XmlMini.rename_key("my_key", :dasherize => false)
+    end
+
+    def test_rename_key_camelizes_with_camelize_true
+      assert_equal "MyKey", ActiveSupport::XmlMini.rename_key("my_key", :camelize => true)
+    end
+
+    def test_rename_key_lower_camelizes_with_camelize_lower
+      assert_equal "myKey", ActiveSupport::XmlMini.rename_key("my_key", :camelize => :lower)
+    end
+
+    def test_rename_key_lower_camelizes_with_camelize_upper
+      assert_equal "MyKey", ActiveSupport::XmlMini.rename_key("my_key", :camelize => :upper)
+    end
+
+    def test_rename_key_does_not_dasherize_leading_underscores
+      assert_equal "_id", ActiveSupport::XmlMini.rename_key("_id")
+    end
+
+    def test_rename_key_with_leading_underscore_dasherizes_interior_underscores
+      assert_equal "_my-key", ActiveSupport::XmlMini.rename_key("_my_key")
+    end
+
+    def test_rename_key_does_not_dasherize_trailing_underscores
+      assert_equal "id_", ActiveSupport::XmlMini.rename_key("id_")
+    end
+
+    def test_rename_key_with_trailing_underscore_dasherizes_interior_underscores
+      assert_equal "my-key_", ActiveSupport::XmlMini.rename_key("my_key_")
+    end
+
+    def test_rename_key_does_not_dasherize_multiple_leading_underscores
+      assert_equal "__id", ActiveSupport::XmlMini.rename_key("__id")
+    end
+
+    def test_rename_key_does_not_dasherize_multiple_trailing_underscores
+      assert_equal "id__", ActiveSupport::XmlMini.rename_key("id__")
+    end
+  end
+
+  class ToTagTest < ActiveSupport::TestCase
+    def assert_xml(xml)
+      assert_equal xml, @options[:builder].target!
+    end
+
+    def setup
+      @xml = ActiveSupport::XmlMini
+      @options = {:skip_instruct => true, :builder => Builder::XmlMarkup.new}
+    end
+
+    test "#to_tag accepts a callable object and passes options with the builder" do
+      @xml.to_tag(:some_tag, lambda {|o| o[:builder].br }, @options)
+      assert_xml "<br/>"
+    end
+
+    test "#to_tag accepts a callable object and passes options and tag name" do
+      @xml.to_tag(:tag, lambda {|o, t| o[:builder].b(t) }, @options)
+      assert_xml "<b>tag</b>"
+    end
+
+    test "#to_tag accepts an object responding to #to_xml and passes the options, where :root is key" do
+      obj = Object.new
+      obj.instance_eval do
+        def to_xml(options) options[:builder].yo(options[:root].to_s) end
+      end
+
+      @xml.to_tag(:tag, obj, @options)
+      assert_xml "<yo>tag</yo>"
+    end
+
+    test "#to_tag accepts arbitrary objects responding to #to_str" do
+      @xml.to_tag(:b, "Howdy", @options)
+      assert_xml "<b>Howdy</b>"
+    end
+
+    test "#to_tag should dasherize the space when passed a string with spaces as a key" do
+      @xml.to_tag("New   York", 33, @options)
+      assert_xml "<New---York type=\"integer\">33</New---York>"
+    end
+
+    test "#to_tag should dasherize the space when passed a symbol with spaces as a key" do
+      @xml.to_tag(:"New   York", 33, @options)
+      assert_xml "<New---York type=\"integer\">33</New---York>"
+    end
+    # TODO: test the remaining functions hidden in #to_tag.
+  end
+
+  class WithBackendTest < ActiveSupport::TestCase
+    module REXML end
+    module LibXML end
+    module Nokogiri end
+
+    setup do
+      @xml, @default_backend = ActiveSupport::XmlMini, ActiveSupport::XmlMini.backend
+    end
+
+    teardown do
+      ActiveSupport::XmlMini.backend = @default_backend
+    end
+
+    test "#with_backend should switch backend and then switch back" do
+      @xml.backend = REXML
+      @xml.with_backend(LibXML) do
+        assert_equal LibXML, @xml.backend
+        @xml.with_backend(Nokogiri) do
+          assert_equal Nokogiri, @xml.backend
+        end
+        assert_equal LibXML, @xml.backend
+      end
+      assert_equal REXML, @xml.backend
+    end
+
+    test "backend switch inside #with_backend block" do
+      @xml.with_backend(LibXML) do
+        @xml.backend = REXML
+        assert_equal REXML, @xml.backend
+      end
+      assert_equal REXML, @xml.backend
+    end
+  end
+
+  class ThreadSafetyTest < ActiveSupport::TestCase
+    module REXML end
+    module LibXML end
+
+    setup do
+      @xml, @default_backend = ActiveSupport::XmlMini, ActiveSupport::XmlMini.backend
+    end
+
+    teardown do
+      ActiveSupport::XmlMini.backend = @default_backend
+    end
+
+    test "#with_backend should be thread-safe" do
+      @xml.backend = REXML
+      t = Thread.new do
+        @xml.with_backend(LibXML) { sleep 1 }
+      end
+      sleep 0.1 while t.status != "sleep"
+
+      # We should get `old_backend` here even while another
+      # thread is using `new_backend`.
+      assert_equal REXML, @xml.backend
+    end
+
+    test "nested #with_backend should be thread-safe" do
+      @xml.with_backend(REXML) do
+        t = Thread.new do
+          @xml.with_backend(LibXML) { sleep 1 }
+        end
+        sleep 0.1 while t.status != "sleep"
+
+        assert_equal REXML, @xml.backend
+      end
+    end
+  end
+
+  class ParsingTest < ActiveSupport::TestCase
+    def setup
+      @parsing = ActiveSupport::XmlMini::PARSING
+    end
+
+    def test_symbol
+      parser = @parsing['symbol']
+      assert_equal :symbol, parser.call('symbol')
+      assert_equal :symbol, parser.call(:symbol)
+      assert_equal :'123', parser.call(123)
+      assert_raises(ArgumentError) { parser.call(Date.new(2013,11,12,02,11)) }
+    end
+
+    def test_date
+      parser = @parsing['date']
+      assert_equal Date.new(2013,11,12), parser.call("2013-11-12T0211Z")
+      assert_raises(TypeError) { parser.call(1384190018) }
+      assert_raises(ArgumentError) { parser.call("not really a date") }
+    end
+
+    def test_datetime
+      parser = @parsing['datetime']
+      assert_equal Time.new(2013,11,12,02,11,00,0), parser.call("2013-11-12T02:11:00Z")
+      assert_equal DateTime.new(2013,11,12), parser.call("2013-11-12T0211Z")
+      assert_equal DateTime.new(2013,11,12,02,11), parser.call("2013-11-12T02:11Z")
+      assert_equal DateTime.new(2013,11,12,02,11), parser.call("2013-11-12T11:11+9")
+      assert_raises(ArgumentError) { parser.call("1384190018") }
+    end
+
+    def test_integer
+      parser = @parsing['integer']
+      assert_equal 123, parser.call(123)
+      assert_equal 123, parser.call(123.003)
+      assert_equal 123, parser.call("123")
+      assert_equal 0, parser.call("")
+      assert_raises(ArgumentError) { parser.call(Date.new(2013,11,12,02,11)) }
+    end
+
+    def test_float
+      parser = @parsing['float']
+      assert_equal 123, parser.call("123")
+      assert_equal 123.003, parser.call("123.003")
+      assert_equal 123.0, parser.call("123,003")
+      assert_equal 0.0, parser.call("")
+      assert_equal 123, parser.call(123)
+      assert_equal 123.05, parser.call(123.05)
+      assert_raises(ArgumentError) { parser.call(Date.new(2013,11,12,02,11)) }
+    end
+
+    def test_decimal
+      parser = @parsing['decimal']
+      assert_equal 123, parser.call("123")
+      assert_equal 123.003, parser.call("123.003")
+      assert_equal 123.0, parser.call("123,003")
+      assert_equal 0.0, parser.call("")
+      assert_equal 123, parser.call(123)
+      assert_raises(ArgumentError) { parser.call(123.04) }
+      assert_raises(ArgumentError) { parser.call(Date.new(2013,11,12,02,11)) }
+    end
+
+    def test_boolean
+      parser = @parsing['boolean']
+      [1, true, "1"].each do |value|
+        assert parser.call(value)
+      end
+
+      [0, false, "0"].each do |value|
+        assert_not parser.call(value)
+      end
+    end
+
+    def test_string
+      parser = @parsing['string']
+      assert_equal "123", parser.call(123)
+      assert_equal "123", parser.call("123")
+      assert_equal "[]", parser.call("[]")
+      assert_equal "[]", parser.call([])
+      assert_equal "{}", parser.call({})
+      assert_raises(ArgumentError) { parser.call(Date.new(2013,11,12,02,11)) }
+    end
+
+    def test_yaml
+      yaml = <<YAML
+product:
+  - sku         : BL394D
+    quantity    : 4
+    description : Basketball
+YAML
+      expected = {
+        "product"=> [
+          {"sku"=>"BL394D", "quantity"=>4, "description"=>"Basketball"}
+        ]
+      }
+      parser = @parsing['yaml']
+      assert_equal(expected, parser.call(yaml))
+      assert_equal({1 => 'test'}, parser.call({1 => 'test'}))
+      assert_equal({"1 => 'test'"=>nil}, parser.call("{1 => 'test'}"))
+    end
+
+    def test_base64Binary_and_binary
+      base64 = <<BASE64
+TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
+IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
+dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
+dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
+ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=
+BASE64
+      expected_base64 = <<EXPECTED
+Man is distinguished, not only by his reason, but by this singular passion from
+other animals, which is a lust of the mind, that by a perseverance of delight
+in the continued and indefatigable generation of knowledge, exceeds the short
+vehemence of any carnal pleasure.
+EXPECTED
+
+      parser = @parsing['base64Binary']
+      assert_equal expected_base64.gsub(/\n/," ").strip, parser.call(base64)
+      parser.call("NON BASE64 INPUT")
+
+      parser = @parsing['binary']
+      assert_equal expected_base64.gsub(/\n/," ").strip, parser.call(base64, 'encoding' => 'base64')
+      assert_equal "IGNORED INPUT", parser.call("IGNORED INPUT", {})
+    end
+  end
+end
diff --git a/app/server/vendor/ast-2.0.0/.gitignore b/app/server/vendor/ast-2.0.0/.gitignore
new file mode 100755
index 0000000..85e0e98
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/.gitignore
@@ -0,0 +1,8 @@
+.bundle
+Gemfile.lock
+pkg/*
+.rbx/
+*.sublime-*
+doc/
+.yardoc/
+coverage/
\ No newline at end of file
diff --git a/app/server/vendor/ast-2.0.0/.travis.yml b/app/server/vendor/ast-2.0.0/.travis.yml
new file mode 100755
index 0000000..c95620f
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/.travis.yml
@@ -0,0 +1,9 @@
+language: ruby
+rvm:
+ - 1.8.7
+ - 1.9.2
+ - 1.9.3
+ - 2.0
+ - jruby-18mode
+ - jruby-19mode
+ - rbx-2
diff --git a/app/server/vendor/ast-2.0.0/.yardopts b/app/server/vendor/ast-2.0.0/.yardopts
new file mode 100755
index 0000000..2b11d98
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/.yardopts
@@ -0,0 +1 @@
+-r README.YARD.md -m markdown --protected
diff --git a/app/server/vendor/ast-2.0.0/CHANGELOG.md b/app/server/vendor/ast-2.0.0/CHANGELOG.md
new file mode 100755
index 0000000..50daf5d
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/CHANGELOG.md
@@ -0,0 +1,9 @@
+Changelog
+=========
+
+v1.1.0 (2013-06-17)
+-------------------
+
+API changes:
+
+  * AST::Processor#process will return nil if passed nil, instead of raising NoMethodError.
diff --git a/app/server/vendor/ast-2.0.0/Gemfile b/app/server/vendor/ast-2.0.0/Gemfile
new file mode 100755
index 0000000..1a3112f
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/Gemfile
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in furnace.gemspec
+gemspec
\ No newline at end of file
diff --git a/app/server/vendor/ast-2.0.0/LICENSE.MIT b/app/server/vendor/ast-2.0.0/LICENSE.MIT
new file mode 100755
index 0000000..7c483cf
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/LICENSE.MIT
@@ -0,0 +1,20 @@
+Copyright (c) 2011-2013  Peter Zotov <whitequark at whitequark.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/ast-2.0.0/README.YARD.md b/app/server/vendor/ast-2.0.0/README.YARD.md
new file mode 100755
index 0000000..bf8a31d
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/README.YARD.md
@@ -0,0 +1,12 @@
+{AST} is a library for manipulating abstract syntax trees.
+
+It embraces immutability; each AST node is inherently frozen at
+creation, and updating a child node requires recreating that node
+and its every parent, recursively.
+
+This is a design choice. It does create some pressure on
+garbage collector, but completely eliminates all concurrency
+and aliasing problems.
+
+See also {AST::Node}, {AST::Processor} and {AST::Sexp} for additional
+recommendations and design patterns.
diff --git a/app/server/vendor/ast-2.0.0/README.md b/app/server/vendor/ast-2.0.0/README.md
new file mode 100755
index 0000000..04d22dd
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/README.md
@@ -0,0 +1,23 @@
+# AST
+
+[![Build Status](https://travis-ci.org/whitequark/ast.png?branch=master)](https://travis-ci.org/whitequark/ast)
+[![Code Climate](https://codeclimate.com/github/whitequark/ast.png)](https://codeclimate.com/github/whitequark/ast)
+[![Coverage Status](https://coveralls.io/repos/whitequark/ast/badge.png?branch=master)](https://coveralls.io/r/whitequark/ast)
+
+AST is a small library for working with immutable abstract syntax trees.
+
+## Installation
+
+    $ gem install ast
+
+## Usage
+
+See the documentation at [GitHub](http://whitequark.github.com/ast/frames.html) or [rdoc.info](http://rdoc.info/gems/ast).
+
+## Contributing
+
+1. Fork it
+2. Create your feature branch (`git checkout -b my-new-feature`)
+3. Commit your changes (`git commit -am 'Add some feature'`)
+4. Push to the branch (`git push origin my-new-feature`)
+5. Create new Pull Request
diff --git a/app/server/vendor/ast-2.0.0/Rakefile b/app/server/vendor/ast-2.0.0/Rakefile
new file mode 100755
index 0000000..9c583ee
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/Rakefile
@@ -0,0 +1,19 @@
+require 'bundler/gem_tasks'
+require 'bundler/setup'
+
+task :default => :test
+
+desc "Run test suite"
+task :test do
+  sh "bacon -Itest -a"
+end
+
+PAGES_REPO = 'git at github.com:whitequark/ast'
+
+desc "Build and deploy documentation to GitHub pages"
+task :pages do
+  system "git clone #{PAGES_REPO} gh-temp/ -b gh-pages; rm gh-temp/* -rf; touch gh-temp/.nojekyll" or abort
+  system "yardoc -o gh-temp/;" or abort
+  system "cd gh-temp/; git add -A; git commit -m 'Updated pages.'; git push -f origin gh-pages" or abort
+  FileUtils.rm_rf 'gh-temp'
+end
diff --git a/app/server/vendor/ast-2.0.0/ast.gemspec b/app/server/vendor/ast-2.0.0/ast.gemspec
new file mode 100755
index 0000000..b9ec323
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/ast.gemspec
@@ -0,0 +1,28 @@
+Gem::Specification.new do |s|
+  s.name        = 'ast'
+  s.version     = '2.0.0'
+  s.license     = 'MIT'
+  s.authors     = ["Peter Zotov"]
+  s.email       = ["whitequark at whitequark.org"]
+  s.homepage    = "https://whitequark.github.io/ast/"
+  s.summary     = %q{A library for working with Abstract Syntax Trees.}
+  s.description = s.summary
+
+  s.files         = `git ls-files`.split("\n")
+  s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
+  s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+  s.require_paths = ["lib"]
+
+  s.add_development_dependency 'rake',                '~> 10.0'
+
+  s.add_development_dependency 'bacon',               '~> 1.2'
+  s.add_development_dependency 'bacon-colored_output'
+  s.add_development_dependency 'simplecov'
+
+  s.add_development_dependency 'coveralls'
+  s.add_development_dependency 'json_pure' # for coveralls on 1.9.2
+  s.add_development_dependency 'mime-types', '~> 1.25' # for coveralls on 1.8.7
+
+  s.add_development_dependency 'yard'
+  s.add_development_dependency 'kramdown'
+end
diff --git a/app/server/vendor/ast-2.0.0/lib/ast.rb b/app/server/vendor/ast-2.0.0/lib/ast.rb
new file mode 100755
index 0000000..4ca859c
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/lib/ast.rb
@@ -0,0 +1,17 @@
+# {AST} is a library for manipulating abstract syntax trees.
+#
+# It embraces immutability; each AST node is inherently frozen at
+# creation, and updating a child node requires recreating that node
+# and its every parent, recursively.
+# This is a design choice. It does create some pressure on
+# garbage collector, but completely eliminates all concurrency
+# and aliasing problems.
+#
+# See also {AST::Node}, {AST::Processor} and {AST::Sexp} for additional
+# recommendations and design patterns.
+#
+module AST
+  require 'ast/node'
+  require 'ast/processor'
+  require 'ast/sexp'
+end
diff --git a/app/server/vendor/ast-2.0.0/lib/ast/node.rb b/app/server/vendor/ast-2.0.0/lib/ast/node.rb
new file mode 100755
index 0000000..511c70d
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/lib/ast/node.rb
@@ -0,0 +1,232 @@
+module AST
+  # Node is an immutable class, instances of which represent abstract
+  # syntax tree nodes. It combines semantic information (i.e. anything
+  # that affects the algorithmic properties of a program) with
+  # meta-information (line numbers or compiler intermediates).
+  #
+  # Notes on inheritance
+  # ====================
+  #
+  # The distinction between semantics and metadata is important. Complete
+  # semantic information should be contained within just the {#type} and
+  # {#children} of a Node instance; in other words, if an AST was to be
+  # stripped of all meta-information, it should remain a valid AST which
+  # could be successfully processed to yield a result with the same
+  # algorithmic properties.
+  #
+  # Thus, Node should never be inherited in order to define methods which
+  # affect or return semantic information, such as getters for `class_name`,
+  # `superclass` and `body` in the case of a hypothetical `ClassNode`. The
+  # correct solution is to use a generic Node with a {#type} of `:class`
+  # and three children. See also {Processor} for tips on working with such
+  # ASTs.
+  #
+  # On the other hand, Node can and should be inherited to define
+  # application-specific metadata (see also {#initialize}) or customize the
+  # printing format. It is expected that an application would have one or two
+  # such classes and use them across the entire codebase.
+  #
+  # The rationale for this pattern is extensibility and maintainability.
+  # Unlike static ones, dynamic languages do not require the presence of a
+  # predefined, rigid structure, nor does it improve dispatch efficiency,
+  # and while such a structure can certainly be defined, it does not add
+  # any value but incurs a maintaining cost.
+  # For example, extending the AST even with a transformation-local
+  # temporary node type requires making globally visible changes to
+  # the codebase.
+  #
+  class Node
+    # Returns the type of this node.
+    # @return [Symbol]
+    attr_reader :type
+
+    # Returns the children of this node.
+    # The returned value is frozen.
+    # @return [Array]
+    attr_reader :children
+
+    # Returns the precomputed hash value for this node
+    # @return [Fixnum]
+    attr_reader :hash
+
+    # Constructs a new instance of Node.
+    #
+    # The arguments `type` and `children` are converted with `to_sym` and
+    # `to_a` respectively. Additionally, the result of converting `children`
+    # is frozen. While mutating the arguments is generally considered harmful,
+    # the most common case is to pass an array literal to the constructor. If
+    # your code does not expect the argument to be frozen, use `#dup`.
+    #
+    # The `properties` hash is passed to {#assign_properties}.
+    def initialize(type, children=[], properties={})
+      @type, @children = type.to_sym, children.to_a.freeze
+
+      assign_properties(properties)
+
+      @hash = [@type, @children, self.class].hash
+
+      freeze
+    end
+
+    # Test if other object is equal to
+    # @param [Object] other
+    # @return [Boolean]
+    def eql?(other)
+      self.class.eql?(other.class)   &&
+      @type.eql?(other.type)         &&
+      @children.eql?(other.children)
+    end
+
+    # By default, each entry in the `properties` hash is assigned to
+    # an instance variable in this instance of Node. A subclass should define
+    # attribute readers for such variables. The values passed in the hash
+    # are not frozen or whitelisted; such behavior can also be implemented\
+    # by subclassing Node and overriding this method.
+    #
+    # @return [nil]
+    def assign_properties(properties)
+      properties.each do |name, value|
+        instance_variable_set :"@#{name}", value
+      end
+
+      nil
+    end
+    protected :assign_properties
+
+    alias   :original_dup :dup
+    private :original_dup
+
+    # Nodes are already frozen, so there is no harm in returning the
+    # current node as opposed to initializing from scratch and freezing
+    # another one.
+    #
+    # @return self
+    def dup
+      self
+    end
+
+    # Returns a new instance of Node where non-nil arguments replace the
+    # corresponding fields of `self`.
+    #
+    # For example, `Node.new(:foo, [ 1, 2 ]).updated(:bar)` would yield
+    # `(bar 1 2)`, and `Node.new(:foo, [ 1, 2 ]).updated(nil, [])` would
+    # yield `(foo)`.
+    #
+    # If the resulting node would be identical to `self`, does nothing.
+    #
+    # @param  [Symbol, nil] type
+    # @param  [Array, nil]  children
+    # @param  [Hash, nil]   properties
+    # @return [AST::Node]
+    def updated(type=nil, children=nil, properties=nil)
+      new_type       = type       || @type
+      new_children   = children   || @children
+      new_properties = properties || {}
+
+      if @type == new_type &&
+          @children == new_children &&
+          properties.nil?
+        self
+      else
+        original_dup.send :initialize, new_type, new_children, new_properties
+      end
+    end
+
+    # Compares `self` to `other`, possibly converting with `to_ast`. Only
+    # `type` and `children` are compared; metadata is deliberately ignored.
+    #
+    # @return [Boolean]
+    def ==(other)
+      if equal?(other)
+        true
+      elsif other.respond_to? :to_ast
+        other = other.to_ast
+        other.type == self.type &&
+          other.children == self.children
+      else
+        false
+      end
+    end
+
+    # Concatenates `array` with `children` and returns the resulting node.
+    #
+    # @return [AST::Node]
+    def concat(array)
+      updated(nil, @children + array.to_a)
+    end
+
+    alias + concat
+
+    # Appends `element` to `children` and returns the resulting node.
+    #
+    # @return [AST::Node]
+    def append(element)
+      updated(nil, @children + [element])
+    end
+
+    alias << append
+
+    # Converts `self` to a concise s-expression, omitting any children.
+    #
+    # @return [String]
+    def to_s
+      "(#{fancy_type} ...)"
+    end
+
+    # Returns {#children}. This is very useful in order to decompose nodes
+    # concisely. For example:
+    #
+    #     node = s(:gasgn, :$foo, s(:integer, 1))
+    #     s
+    #     var_name, value = *node
+    #     p var_name # => :$foo
+    #     p value    # => (integer 1)
+    #
+    # @return [Array]
+    def to_a
+      children
+    end
+
+    # Converts `self` to a pretty-printed s-expression.
+    #
+    # @param  [Integer] indent Base indentation level.
+    # @return [String]
+    def to_sexp(indent=0)
+      indented = "  " * indent
+      sexp = "#{indented}(#{fancy_type}"
+
+      first_node_child = children.index do |child|
+        child.is_a?(Node) || child.is_a?(Array)
+      end || children.count
+
+      children.each_with_index do |child, idx|
+        if child.is_a?(Node) && idx >= first_node_child
+          sexp << "\n#{child.to_sexp(indent + 1)}"
+        else
+          sexp << " #{child.inspect}"
+        end
+      end
+
+      sexp << ")"
+
+      sexp
+    end
+    alias :inspect :to_sexp
+
+    # @return [AST::Node] self
+    def to_ast
+      self
+    end
+
+    protected
+
+    # Returns `@type` with all underscores replaced by dashes. This allows
+    # to write symbol literals without quotes in Ruby sources and yet have
+    # nicely looking s-expressions.
+    #
+    # @return [String]
+    def fancy_type
+      @type.to_s.gsub('_', '-')
+    end
+  end
+end
diff --git a/app/server/vendor/ast-2.0.0/lib/ast/processor.rb b/app/server/vendor/ast-2.0.0/lib/ast/processor.rb
new file mode 100755
index 0000000..c5b5452
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/lib/ast/processor.rb
@@ -0,0 +1,266 @@
+module AST
+  # Processor is a class which helps transforming one AST into another.
+  # In a nutshell, the {#process} method accepts a {Node} and dispatches
+  # it to a handler corresponding to its type, and returns a (possibly)
+  # updated variant of the node.
+  #
+  # Processor has a set of associated design patterns. They are best
+  # explained with a concrete example. Let's define a simple arithmetic
+  # language and an AST format for it:
+  #
+  # Terminals (AST nodes which do not have other AST nodes inside):
+  #
+  #   * `(integer <int-literal>)`,
+  #
+  # Nonterminals (AST nodes with other nodes as children):
+  #
+  #   * `(add <node> <node>)`,
+  #   * `(multiply <node> <node>)`,
+  #   * `(divide <node> <node>)`,
+  #   * `(negate <node>)`,
+  #   * `(store <node> <string-literal>)`: stores value of `<node>` into a variable named `<string-literal>`,
+  #   * `(load <string-literal>)`: loads value of a variable named `<string-literal>`,
+  #   * `(each <node> ...): computes each of the `<node>`s and prints the result.
+  #
+  # All AST nodes have the same Ruby class, and therefore they don't
+  # know how to traverse themselves. (A solution which dynamically checks the
+  # type of children is possible, but is slow and error-prone.) So, a subclass
+  # of Processor which knows how to traverse the entire tree should be defined.
+  # Such subclass has a handler for each nonterminal node which recursively
+  # processes children nodes:
+  #
+  #     require 'ast'
+  #
+  #     class ArithmeticsProcessor < AST::Processor
+  #       # This method traverses any binary operators such as (add) or (multiply).
+  #       def process_binary_op(node)
+  #         # Children aren't decomposed automatically; it is suggested to use Ruby
+  #         # multiple assignment expansion, as it is very convenient here.
+  #         left_expr, right_expr = *node
+  #
+  #         # AST::Node#updated won't change node type if nil is passed as a first
+  #         # argument, which allows to reuse the same handler for multiple node types
+  #         # using `alias' (below).
+  #         node.updated(nil, [
+  #           process(left_expr),
+  #           process(right_expr)
+  #         ])
+  #       end
+  #       alias on_add      process_binary_op
+  #       alias on_multiply process_binary_op
+  #       alias on_divide   process_binary_op
+  #
+  #       def on_negate(node)
+  #         # It is also possible to use #process_all for more compact code
+  #         # if every child is a Node.
+  #         node.updated(nil, process_all(node))
+  #       end
+  #
+  #       def on_store(node)
+  #         expr, variable_name = *node
+  #
+  #         # Note that variable_name is not a Node and thus isn't passed to #process.
+  #         node.updated(nil, [
+  #           process(expr),
+  #           variable_name
+  #         ])
+  #       end
+  #
+  #       # (load) is effectively a terminal node, and so it does not need
+  #       # an explicit handler, as the following is the default behavior.
+  #       def on_load(node)
+  #         nil
+  #       end
+  #
+  #       def on_each(node)
+  #         node.updated(nil, process_all(node))
+  #       end
+  #     end
+  #
+  # Let's test our ArithmeticsProcessor:
+  #
+  #     include AST::Sexp
+  #     expr = s(:add, s(:integer, 2), s(:integer, 2))
+  #
+  #     p ArithmeticsProcessor.new.process(expr) == expr # => true
+  #
+  # As expected, it does not change anything at all. This isn't actually
+  # very useful, so let's now define a Calculator, which will compute the
+  # expression values:
+  #
+  #     # This Processor folds nonterminal nodes and returns an (integer)
+  #     # terminal node.
+  #     class ArithmeticsCalculator < ArithmeticsProcessor
+  #       def compute_op(node)
+  #         # First, node children are processed and then unpacked to local
+  #         # variables.
+  #         nodes = process_all(node)
+  #
+  #         if nodes.all? { |node| node.type == :integer }
+  #           # If each of those nodes represents a literal, we can fold this
+  #           # node!
+  #           values = nodes.map { |node| node.children.first }
+  #           AST::Node.new(:integer, [
+  #             yield(values)
+  #           ])
+  #         else
+  #           # Otherwise, we can just leave the current node in the tree and
+  #           # only update it with processed children nodes, which can be
+  #           # partially folded.
+  #           node.updated(nil, nodes)
+  #         end
+  #       end
+  #
+  #       def on_add(node)
+  #         compute_op(node) { |left, right| left + right }
+  #       end
+  #
+  #       def on_multiply(node)
+  #         compute_op(node) { |left, right| left * right }
+  #       end
+  #     end
+  #
+  # Let's check:
+  #
+  #     p ArithmeticsCalculator.new.process(expr) # => (integer 4)
+  #
+  # Excellent, the calculator works! Now, a careful reader could notice that
+  # the ArithmeticsCalculator does not know how to divide numbers. What if we
+  # pass an expression with division to it?
+  #
+  #     expr_with_division = \
+  #       s(:add,
+  #         s(:integer, 1),
+  #         s(:divide,
+  #           s(:add, s(:integer, 8), s(:integer, 4)),
+  #           s(:integer, 3))) # 1 + (8 + 4) / 3
+  #
+  #     folded_expr_with_division = ArithmeticsCalculator.new.process(expr_with_division)
+  #     p folded_expr_with_division
+  #     # => (add
+  #     #      (integer 1)
+  #     #      (divide
+  #     #        (integer 12)
+  #     #        (integer 3)))
+  #
+  # As you can see, the expression was folded _partially_: the inner `(add)` node which
+  # could be computed was folded to `(integer 12)`, the `(divide)` node is left as-is
+  # because there is no computing handler for it, and the root `(add)` node was also left
+  # as it is because some of its children were not literals.
+  #
+  # Note that this partial folding is only possible because the _data_ format, i.e.
+  # the format in which the computed values of the nodes are represented, is the same as
+  # the AST itself.
+  #
+  # Let's extend our ArithmeticsCalculator class further.
+  #
+  #     class ArithmeticsCalculator
+  #       def on_divide(node)
+  #         compute_op(node) { |left, right| left / right }
+  #       end
+  #
+  #       def on_negate(node)
+  #         # Note how #compute_op works regardless of the operator arity.
+  #         compute_op(node) { |value| -value }
+  #       end
+  #     end
+  #
+  # Now, let's apply our renewed ArithmeticsCalculator to a partial result of previous
+  # evaluation:
+  #
+  #     p ArithmeticsCalculator.new.process(expr_with_division) # => (integer 5)
+  #
+  # Five! Excellent. This is also pretty much how CRuby 1.8 executed its programs.
+  #
+  # Now, let's do some automated bug searching. Division by zero is an error, right?
+  # So if we could detect that someone has divided by zero before the program is even
+  # run, that could save some debugging time.
+  #
+  #     class DivisionByZeroVerifier < ArithmeticsProcessor
+  #       class VerificationFailure < Exception; end
+  #
+  #       def on_divide(node)
+  #         # You need to process the children to handle nested divisions
+  #         # such as:
+  #         # (divide
+  #         #   (integer 1)
+  #         #   (divide (integer 1) (integer 0))
+  #         left, right = process_all(node)
+  #
+  #         if right.type == :integer &&
+  #            right.children.first == 0
+  #           raise VerificationFailure, "Ouch! This code divides by zero."
+  #         end
+  #       end
+  #
+  #       def divides_by_zero?(ast)
+  #         process(ast)
+  #         false
+  #       rescue VerificationFailure
+  #         true
+  #       end
+  #     end
+  #
+  #     nice_expr = \
+  #       s(:divide,
+  #         s(:add, s(:integer, 10), s(:integer, 2)),
+  #         s(:integer, 4))
+  #
+  #     p DivisionByZeroVerifier.new.divides_by_zero?(nice_expr)
+  #     # => false. Good.
+  #
+  #     bad_expr = \
+  #       s(:add, s(:integer, 10),
+  #         s(:divide, s(:integer, 1), s(:integer, 0)))
+  #
+  #     p DivisionByZeroVerifier.new.divides_by_zero?(bad_expr)
+  #     # => true. WHOOPS. DO NOT RUN THIS.
+  #
+  # Of course, this won't detect more complex cases... unless you use some partial
+  # evaluation before! The possibilites are endless. Have fun.
+  class Processor
+    # Dispatches `node`. If a node has type `:foo`, then a handler named
+    # `on_foo` is invoked with one argument, the `node`; if there isn't
+    # such a handler, {#handler_missing} is invoked with the same argument.
+    #
+    # If the handler returns `nil`, `node` is returned; otherwise, the return
+    # value of the handler is passed along.
+    #
+    # @param  [AST::Node, nil] node
+    # @return [AST::Node, nil]
+    def process(node)
+      return if node.nil?
+
+      node = node.to_ast
+
+      # Invoke a specific handler
+      on_handler = :"on_#{node.type}"
+      if respond_to? on_handler
+        new_node = send on_handler, node
+      else
+        new_node = handler_missing(node)
+      end
+
+      node = new_node if new_node
+
+      node
+    end
+
+    # {#process}es each node from `nodes` and returns an array of results.
+    #
+    # @param  [Array<AST::Node>] nodes
+    # @return [Array<AST::Node>]
+    def process_all(nodes)
+      nodes.to_a.map do |node|
+        process node
+      end
+    end
+
+    # Default handler. Does nothing.
+    #
+    # @param  [AST::Node] node
+    # @return [AST::Node, nil]
+    def handler_missing(node)
+    end
+  end
+end
diff --git a/app/server/vendor/ast-2.0.0/lib/ast/sexp.rb b/app/server/vendor/ast-2.0.0/lib/ast/sexp.rb
new file mode 100755
index 0000000..9b03d26
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/lib/ast/sexp.rb
@@ -0,0 +1,30 @@
+module AST
+  # This simple module is very useful in the cases where one needs
+  # to define deeply nested ASTs from Ruby code, for example, in
+  # tests. It should be used like this:
+  #
+  #     describe YourLanguage::AST do
+  #       include Sexp
+  #
+  #       it "should correctly parse expressions" do
+  #         YourLanguage.parse("1 + 2 * 3").should ==
+  #             s(:add,
+  #               s(:integer, 1),
+  #               s(:multiply,
+  #                 s(:integer, 2),
+  #                 s(:integer, 3)))
+  #       end
+  #     end
+  #
+  # This way the amount of boilerplate code is greatly reduced.
+  module Sexp
+    # Creates a {Node} with type `type` and children `children`.
+    # Note that the resulting node is of the type AST::Node and not a
+    # subclass.
+    # This would not pose a problem with comparisons, as {Node#==}
+    # ignores metadata.
+    def s(type, *children)
+      Node.new(type, children)
+    end
+  end
+end
diff --git a/app/server/vendor/ast-2.0.0/test/helper.rb b/app/server/vendor/ast-2.0.0/test/helper.rb
new file mode 100755
index 0000000..681b37f
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/test/helper.rb
@@ -0,0 +1,17 @@
+require 'bacon'
+require 'bacon/colored_output'
+
+require 'simplecov'
+require 'coveralls'
+
+SimpleCov.start do
+  self.formatter = SimpleCov::Formatter::MultiFormatter[
+    SimpleCov::Formatter::HTMLFormatter,
+    Coveralls::SimpleCov::Formatter
+  ]
+
+  # Exclude the testsuite itself.
+  add_filter "/test/"
+end
+
+require 'ast'
diff --git a/app/server/vendor/ast-2.0.0/test/test_ast.rb b/app/server/vendor/ast-2.0.0/test/test_ast.rb
new file mode 100755
index 0000000..e05fa4d
--- /dev/null
+++ b/app/server/vendor/ast-2.0.0/test/test_ast.rb
@@ -0,0 +1,243 @@
+require 'helper'
+
+describe AST::Node do
+  extend AST::Sexp
+
+  class MetaNode < AST::Node
+    attr_reader :meta
+  end
+
+  before do
+    @node = AST::Node.new(:node, [ 0, 1 ])
+    @metanode = MetaNode.new(:node, [ 0, 1 ], :meta => 'value')
+  end
+
+  it 'should have accessors for type and children' do
+    @node.type.should.equal :node
+    @node.children.should.equal [0, 1]
+  end
+
+  it 'should set metadata' do
+    @metanode.meta.should.equal 'value'
+  end
+
+  it 'should be frozen' do
+    @node.frozen?.should.be.true
+    @node.children.frozen?.should.be.true
+  end
+
+  it 'should return self when duping' do
+    @node.dup.should.equal? @node
+  end
+
+  it 'should return an updated node, but only if needed' do
+    @node.updated().should.be.identical_to @node
+    @node.updated(:node).should.be.identical_to @node
+    @node.updated(nil, [0, 1]).should.be.identical_to @node
+
+    updated = @node.updated(:other_node)
+    updated.should.not.be.identical_to @node
+    updated.type.should.equal :other_node
+    updated.children.should.equal @node.children
+
+    updated.frozen?.should.be.true
+
+    updated = @node.updated(nil, [1, 1])
+    updated.should.not.be.identical_to @node
+    updated.type.should.equal @node.type
+    updated.children.should.equal [1, 1]
+
+    updated = @metanode.updated(nil, nil, :meta => 'other_value')
+    updated.meta.should.equal 'other_value'
+  end
+
+  it 'should use fancy type in to_s' do
+    node = AST::Node.new(:ast_node)
+    node.to_s.should.equal '(ast-node ...)'
+  end
+
+  it 'should format to_sexp correctly' do
+    AST::Node.new(:a, [ :sym, [ 1, 2 ] ]).to_sexp.should.equal '(a :sym [1, 2])'
+    AST::Node.new(:a, [ :sym, @node ]).to_sexp.should.equal "(a :sym\n  (node 0 1))"
+    AST::Node.new(:a, [ :sym,
+      AST::Node.new(:b, [ @node, @node ])
+    ]).to_sexp.should.equal "(a :sym\n  (b\n    (node 0 1)\n    (node 0 1)))"
+  end
+
+  it 'should return self in to_ast' do
+    @node.to_ast.should.be.identical_to @node
+  end
+
+  it 'should only use type and children to compute #hash' do
+    @node.hash.should.equal([@node.type, @node.children, @node.class].hash)
+  end
+
+  it 'should only use type and children in #eql? comparisons' do
+    # Not identical but equivalent
+    @node.eql?(AST::Node.new(:node, [0, 1])).should.be.true
+    # Not identical and not equivalent
+    @node.eql?(AST::Node.new(:other, [0, 1])).should.be.false
+    # Not identical and not equivalent because of differend class
+    @node.eql?(@metanode).should.be.false
+  end
+
+  it 'should only use type and children in #== comparisons' do
+    @node.should.equal @node
+    @node.should.equal @metanode
+    @node.should.not.equal :foo
+
+    mock_node = Object.new.tap do |obj|
+      def obj.to_ast
+        self
+      end
+
+      def obj.type
+        :node
+      end
+
+      def obj.children
+        [ 0, 1 ]
+      end
+    end
+    @node.should.equal mock_node
+  end
+
+  it 'should allow to decompose nodes with a, b = *node' do
+    node = s(:gasgn, :$foo, s(:integer, 1))
+
+    var_name, value = *node
+    var_name.should.equal :$foo
+    value.should.equal s(:integer, 1)
+  end
+
+  it 'should concatenate with arrays' do
+    node = s(:gasgn, :$foo)
+    (node + [s(:integer, 1)]).
+        should.equal s(:gasgn, :$foo, s(:integer, 1))
+  end
+
+  it 'should append elements' do
+    node = s(:array)
+    (node << s(:integer, 1) << s(:string, "foo")).
+        should.equal s(:array, s(:integer, 1), s(:string, "foo"))
+  end
+
+  begin
+    eval <<-CODE
+    it 'should not trigger a rubinius bug' do
+      bar = [ s(:bar, 1) ]
+      baz = s(:baz, 2)
+      s(:foo, *bar, baz).should.equal s(:foo, s(:bar, 1), s(:baz, 2))
+    end
+    CODE
+  rescue SyntaxError
+    # Running on 1.8, ignore.
+  end
+end
+
+describe AST::Processor do
+  extend AST::Sexp
+
+  def have_sexp(text)
+    text = text.lines.map { |line| line.sub /^ +\|(.+)/, '\1' }.join.rstrip
+    lambda { |ast| ast.to_sexp == text }
+  end
+
+  class MockProcessor < AST::Processor
+    attr_reader :counts
+
+    def initialize
+      @counts = Hash.new(0)
+    end
+
+    def on_root(node)
+      count_node(node)
+      node.updated(nil, process_all(node.children))
+    end
+    alias on_body on_root
+
+    def on_def(node)
+      count_node(node)
+      name, arglist, body = node.children
+      node.updated(:def, [ name, process(arglist), process(body) ])
+    end
+
+    def handler_missing(node)
+      count_node(node)
+    end
+
+    def count_node(node)
+      @counts[node.type] += 1; nil
+    end
+  end
+
+  before do
+    @ast = AST::Node.new(:root, [
+      AST::Node.new(:def, [ :func,
+        AST::Node.new(:arglist, [ :foo, :bar ]),
+        AST::Node.new(:body, [
+          AST::Node.new(:invoke, [ :puts, "Hello world" ])
+        ])
+      ]),
+      AST::Node.new(:invoke, [ :func ])
+    ])
+
+    @processor = MockProcessor.new
+  end
+
+  it 'should visit every node' do
+    @processor.process(@ast).should.equal @ast
+    @processor.counts.should.equal({
+      :root    => 1,
+      :def     => 1,
+      :arglist => 1,
+      :body    => 1,
+      :invoke  => 2,
+    })
+  end
+
+  it 'should be able to replace inner nodes' do
+    def @processor.on_arglist(node)
+      node.updated(:new_fancy_arglist)
+    end
+
+    @processor.process(@ast).should have_sexp(<<-SEXP)
+    |(root
+    |  (def :func
+    |    (new-fancy-arglist :foo :bar)
+    |    (body
+    |      (invoke :puts "Hello world")))
+    |  (invoke :func))
+    SEXP
+  end
+
+  it 'should build sexps' do
+    s(:add,
+      s(:integer, 1),
+      s(:multiply,
+        s(:integer, 2),
+        s(:integer, 3))).should have_sexp(<<-SEXP)
+    |(add
+    |  (integer 1)
+    |  (multiply
+    |    (integer 2)
+    |    (integer 3)))
+    SEXP
+  end
+
+  it 'should return nil if passed nil' do
+    @processor.process(nil).should == nil
+  end
+
+  it 'should refuse to process non-nodes' do
+    lambda { @processor.process([]) }.should.raise NoMethodError, %r|to_ast|
+  end
+
+  it 'should allow to visit nodes with process_all(node)' do
+    @processor.process_all s(:foo, s(:bar), s(:integer, 1))
+    @processor.counts.should.equal({
+      :bar =>     1,
+      :integer => 1,
+    })
+  end
+end
diff --git a/app/server/vendor/atomic/.gitignore b/app/server/vendor/atomic/.gitignore
new file mode 100755
index 0000000..5f3f73d
--- /dev/null
+++ b/app/server/vendor/atomic/.gitignore
@@ -0,0 +1,8 @@
+.*.sw?
+lib/atomic_reference.jar
+/nbproject
+ext/*.bundle
+ext/*.so
+ext/*.jar
+pkg
+*.gem
diff --git a/app/server/vendor/atomic/.travis.yml b/app/server/vendor/atomic/.travis.yml
new file mode 100755
index 0000000..315bff9
--- /dev/null
+++ b/app/server/vendor/atomic/.travis.yml
@@ -0,0 +1,10 @@
+language: ruby
+rvm:
+  - 2.0.0
+  - 1.9.3
+  - 1.8.7
+  - jruby-18mode # JRuby in 1.8 mode
+  - jruby-19mode # JRuby in 1.9 mode
+  - rbx-2
+jdk:
+  - oraclejdk8
diff --git a/app/server/vendor/atomic/Gemfile b/app/server/vendor/atomic/Gemfile
new file mode 100755
index 0000000..55034a9
--- /dev/null
+++ b/app/server/vendor/atomic/Gemfile
@@ -0,0 +1,4 @@
+source "https://rubygems.org"
+
+gem 'rake-compiler'
+gem 'minitest', '>= 5.0.0', :group => :development
diff --git a/app/server/vendor/atomic/LICENSE b/app/server/vendor/atomic/LICENSE
new file mode 100755
index 0000000..5336718
--- /dev/null
+++ b/app/server/vendor/atomic/LICENSE
@@ -0,0 +1,144 @@
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and distribution as 
+defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that 
+is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities that 
+control, are controlled by, or are under common control with that entity. For the purposes 
+of this definition, "control" means (i) the power, direct or indirect, to cause the 
+direction or management of such entity, whether by contract or otherwise, or (ii) ownership 
+of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of 
+such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by 
+this License.
+
+"Source" form shall mean the preferred form for making modifications, including but not 
+limited to software source code, documentation source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or translation of 
+a Source form, including but not limited to compiled object code, generated documentation, 
+and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made available 
+under the License, as indicated by a copyright notice that is included in or attached to the 
+work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on 
+(or derived from) the Work and for which the editorial revisions, annotations, elaborations, 
+or other modifications represent, as a whole, an original work of authorship. For the 
+purposes of this License, Derivative Works shall not include works that remain separable 
+from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works 
+thereof.
+
+"Contribution" shall mean any work of authorship, including the original version of the Work 
+and any modifications or additions to that Work or Derivative Works thereof, that is 
+intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by 
+an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the 
+purposes of this definition, "submitted" means any form of electronic, verbal, or written 
+communication sent to the Licensor or its representatives, including but not limited to 
+communication on electronic mailing lists, source code control systems, and issue tracking 
+systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and 
+improving the Work, but excluding communication that is conspicuously marked or otherwise 
+designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a 
+Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each 
+Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, 
+royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, 
+publicly display, publicly perform, sublicense, and distribute the Work and such Derivative 
+Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this License, each 
+Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, 
+royalty-free, irrevocable (except as stated in this section) patent license to make, have 
+made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license 
+applies only to those patent claims licensable by such Contributor that are necessarily 
+infringed by their Contribution(s) alone or by combination of their Contribution(s) with the 
+Work to which such Contribution(s) was submitted. If You institute patent litigation against 
+any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or 
+a Contribution incorporated within the Work constitutes direct or contributory patent 
+infringement, then any patent licenses granted to You under this License for that Work shall 
+terminate as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works 
+thereof in any medium, with or without modifications, and in Source or Object form, provided 
+that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of this License; 
+and
+
+You must cause any modified files to carry prominent notices stating that You changed the 
+files; and
+
+You must retain, in the Source form of any Derivative Works that You distribute, all 
+copyright, patent, trademark, and attribution notices from the Source form of the Work, 
+excluding those notices that do not pertain to any part of the Derivative Works; and
+
+If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative 
+Works that You distribute must include a readable copy of the attribution notices contained 
+within such NOTICE file, excluding those notices that do not pertain to any part of the 
+Derivative Works, in at least one of the following places: within a NOTICE text file 
+distributed as part of the Derivative Works; within the Source form or documentation, if 
+provided along with the Derivative Works; or, within a display generated by the Derivative 
+Works, if and wherever such third-party notices normally appear. The contents of the NOTICE 
+file are for informational purposes only and do not modify the License. You may add Your own 
+attribution notices within Derivative Works that You distribute, alongside or as an addendum 
+to the NOTICE text from the Work, provided that such additional attribution notices cannot 
+be construed as modifying the License. You may add Your own copyright statement to Your 
+modifications and may provide additional or different license terms and conditions for use, 
+reproduction, or distribution of Your modifications, or for any such Derivative Works as a 
+whole, provided Your use, reproduction, and distribution of the Work otherwise complies with 
+the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution 
+intentionally submitted for inclusion in the Work by You to the Licensor shall be under the 
+terms and conditions of this License, without any additional terms or conditions. 
+Notwithstanding the above, nothing herein shall supersede or modify the terms of any 
+separate license agreement you may have executed with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names, trademarks, 
+service marks, or product names of the Licensor, except as required for reasonable and 
+customary use in describing the origin of the Work and reproducing the content of the NOTICE 
+file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, 
+Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" 
+BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, 
+without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, 
+MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for 
+determining the appropriateness of using or redistributing the Work and assume any risks 
+associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in tort 
+(including negligence), contract, or otherwise, unless required by applicable law (such as 
+deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be 
+liable to You for damages, including any direct, indirect, special, incidental, or 
+consequential damages of any character arising as a result of this License or out of the use 
+or inability to use the Work (including but not limited to damages for loss of goodwill, 
+work stoppage, computer failure or malfunction, or any and all other commercial damages or 
+losses), even if such Contributor has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative 
+Works thereof, You may choose to offer, and charge a fee for, acceptance of support, 
+warranty, indemnity, or other liability obligations and/or rights consistent with this 
+License. However, in accepting such obligations, You may act only on Your own behalf and on 
+Your sole responsibility, not on behalf of any other Contributor, and only if You agree to 
+indemnify, defend, and hold each Contributor harmless for any liability incurred by, or 
+claims asserted against, such Contributor by reason of your accepting any such warranty or 
+additional liability.
+
+END OF TERMS AND CONDITIONS
diff --git a/app/server/vendor/atomic/README.md b/app/server/vendor/atomic/README.md
new file mode 100755
index 0000000..6001f9f
--- /dev/null
+++ b/app/server/vendor/atomic/README.md
@@ -0,0 +1,53 @@
+atomic: An atomic reference implementation for JRuby, Rubinius, and MRI.
+========================================================================
+
+[![Build Status](https://travis-ci.org/headius/ruby-atomic.png?branch=master)](https://travis-ci.org/headius/ruby-atomic)
+
+Summary
+=======
+
+This library provides:
+
+* an Atomic class that guarantees atomic updates to its contained value
+
+The Atomic class provides accessors for the contained "value" plus two update methods:
+
+* update will run the provided block, passing the current value and replacing it with the block result if the value has not been changed in the meantime. It may run the block repeatedly if there are other concurrent updates in progress.
+* try_update will run the provided block, passing the current value and replacing it with the block result. If the value changes before the update can happen, it will throw an Atomic::ConcurrentUpdateError.
+
+The atomic repository is at http://github.com/headius/ruby-atomic.
+
+Usage
+=====
+
+The simplest way to use "atomic" is to call the "update" or "try_update" methods.
+
+"try_update" and "update" both call the given block, passing the current value and using the block's result as the new value. If the value is updated by another thread before the block completes, "try update" raises a ConcurrentUpdateError and "update" retries the block. Because "update" may call the block several times when multiple threads are all updating the same value, the block's logic should be kept as simple as possible.
+
+```ruby
+require 'atomic'
+
+my_atomic = Atomic.new(0)
+my_atomic.update {|v| v + 1}
+begin
+  my_atomic.try_update {|v| v + 1}
+rescue Atomic::ConcurrentUpdateError => cue
+  # deal with it (retry, propagate, etc)
+end
+```
+
+It's also possible to use the regular get/set operations on the Atomic, if you want to avoid the exception and respond to contended changes in some other way.
+
+```ruby
+my_atomic = Atomic.new(0)
+my_atomic.value # => 0
+my_atomic.value = 1
+my_atomic.swap(2) # => 1
+my_atomic.compare_and_swap(2, 3) # => true, updated to 3
+my_atomic.compare_and_swap(2, 3) # => false, current is not 2
+```
+
+Building
+========
+
+As of 1.1.0, JDK8 is required to build the atomic gem, since it attempts to use the new atomic Unsafe.getAndSetObject method only in JDK8. The resulting code should still work fine as far back as Java 5.
diff --git a/app/server/vendor/atomic/Rakefile b/app/server/vendor/atomic/Rakefile
new file mode 100755
index 0000000..a0e109c
--- /dev/null
+++ b/app/server/vendor/atomic/Rakefile
@@ -0,0 +1,63 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http:#www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'rake'
+require 'rake/testtask'
+
+task :default => :test
+
+desc "Run tests"
+Rake::TestTask.new :test do |t|
+  t.libs << "lib"
+  t.libs << "ext"
+  t.test_files = FileList["test/**/*.rb"]
+end
+
+desc "Run benchmarks"
+task :bench do
+  exec "ruby -Ilib -Iext test/bench_atomic.rb"
+end
+
+if defined?(JRUBY_VERSION)
+  require 'ant'
+
+  directory "pkg/classes"
+
+  desc "Clean up build artifacts"
+  task :clean do
+    rm_rf "pkg/classes"
+    rm_rf "lib/refqueue.jar"
+  end
+
+  desc "Compile the extension"
+  task :compile_java => "pkg/classes" do |t|
+    ant.javac :srcdir => "ext", :destdir => t.prerequisites.first,
+      :source => "1.5", :target => "1.5", :debug => true,
+      :classpath => "${java.class.path}:${sun.boot.class.path}"
+  end
+
+  desc "Build the jar"
+  task :jar => :compile_java do
+    ant.jar :basedir => "pkg/classes", :destfile => "lib/atomic_reference.jar", :includes => "**/*.class"
+  end
+
+  task :compile => :jar
+else
+  require "rake/extensiontask"
+  Rake::ExtensionTask.new "atomic" do |ext|
+    ext.ext_dir = 'ext'
+    ext.name ='atomic_reference'
+  end
+end
+
+task :package => :compile
+task :test => :compile
diff --git a/app/server/vendor/atomic/atomic.gemspec b/app/server/vendor/atomic/atomic.gemspec
new file mode 100755
index 0000000..3f65f94
--- /dev/null
+++ b/app/server/vendor/atomic/atomic.gemspec
@@ -0,0 +1,24 @@
+# -*- encoding: utf-8 -*-
+
+# Update these to get proper version and commit history
+
+Gem::Specification.new do |s|
+  s.name = %q{atomic}
+  s.version = "1.1.16"
+  s.authors = ["Charles Oliver Nutter", "MenTaLguY", "Sokolov Yura"]
+  s.date = Time.now.strftime('%Y-%m-%d')
+  s.summary = "An atomic reference implementation for JRuby, Rubinius, and MRI"
+  s.description = s.summary
+  s.email = ["headius at headius.com", "mental at rydia.net", "funny.falcon at gmail.com"]
+  s.homepage = "http://github.com/headius/ruby-atomic"
+  s.require_paths = ["lib"]
+  s.licenses = ["Apache-2.0"]
+  s.test_files = Dir["test/test*.rb"]
+  if defined?(JRUBY_VERSION)
+    s.files = Dir['lib/atomic_reference.jar']
+    s.platform = 'java'
+  else
+    s.extensions = 'ext/extconf.rb'
+  end
+  s.files += `git ls-files`.lines.map(&:chomp)
+end
diff --git a/app/server/vendor/atomic/examples/atomic_example.rb b/app/server/vendor/atomic/examples/atomic_example.rb
new file mode 100755
index 0000000..115cd86
--- /dev/null
+++ b/app/server/vendor/atomic/examples/atomic_example.rb
@@ -0,0 +1,24 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'atomic'
+
+my_atomic = Atomic.new(0)
+my_atomic.update {|v| v + 1}
+puts "new value: #{my_atomic.value}"
+
+begin
+  my_atomic.try_update {|v| v + 1}
+rescue Atomic::ConcurrentUpdateError => cue
+  # deal with it (retry, propagate, etc)
+end
+puts "new value: #{my_atomic.value}"
diff --git a/app/server/vendor/atomic/examples/bench_atomic.rb b/app/server/vendor/atomic/examples/bench_atomic.rb
new file mode 100755
index 0000000..09a7b06
--- /dev/null
+++ b/app/server/vendor/atomic/examples/bench_atomic.rb
@@ -0,0 +1,121 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'benchmark'
+require 'atomic'
+require 'thread'
+Thread.abort_on_exception = true
+
+$go = false # for synchronizing parallel threads
+
+# number of updates on the value
+N = ARGV[1] ? ARGV[1].to_i : 100_000
+
+# number of threads for parallel test
+M = ARGV[0] ? ARGV[0].to_i : 100
+
+
+puts "*** Sequential updates ***"
+Benchmark.bm(10) do |x|
+  value = 0
+  x.report "no lock" do
+    N.times do
+      value += 1
+    end
+  end
+
+  @lock = Mutex.new
+  x.report "mutex" do
+    value = 0
+    N.times do
+      @lock.synchronize do
+        value += 1
+      end
+    end
+  end
+
+  @atom = Atomic.new(0)
+  x.report "atomic" do
+    N.times do
+      @atom.update{|x| x += 1}
+    end
+  end
+end
+
+def para_setup(num_threads, count, &block)
+  if num_threads % 2 > 0
+    raise ArgumentError, "num_threads must be a multiple of two"
+  end
+  raise ArgumentError, "need block" unless block_given?
+
+  # Keep those threads together
+  tg = ThreadGroup.new
+
+  num_threads.times do |i|
+    diff = (i % 2 == 0) ? 1 : -1
+
+    t = Thread.new do
+      nil until $go
+      count.times do
+        yield diff
+      end
+    end
+
+    tg.add(t)
+  end
+
+  # Make sure all threads are started
+  while tg.list.find{|t| t.status != "run"}
+    Thread.pass
+  end
+
+  # For good measure
+  GC.start
+
+  tg
+end
+
+def para_run(tg)
+  $go = true
+  tg.list.each{|t| t.join}
+  $go = false
+end
+
+puts "*** Parallel updates ***"
+Benchmark.bm(10) do |bm|
+  # This is not secure
+  value = 0
+  tg = para_setup(M, N/M) do |diff|
+    value += diff
+  end
+  bm.report("no lock"){ para_run(tg) }
+
+
+  value = 0
+  @lock = Mutex.new
+  tg = para_setup(M, N/M) do |diff|
+    @lock.synchronize do
+      value += diff
+    end
+  end
+  bm.report("mutex"){ para_run(tg) }
+  raise unless value == 0
+
+
+  @atom = Atomic.new(0)
+  tg = para_setup(M, N/M) do |diff|
+    @atom.update{|x| x + diff}
+  end
+  bm.report("atomic"){ para_run(tg) }
+  raise unless @atom.value == 0
+
+end
diff --git a/app/server/vendor/atomic/examples/bench_atomic_1.rb b/app/server/vendor/atomic/examples/bench_atomic_1.rb
new file mode 100755
index 0000000..ee5eb1e
--- /dev/null
+++ b/app/server/vendor/atomic/examples/bench_atomic_1.rb
@@ -0,0 +1,149 @@
+#!/usr/bin/env ruby
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+$: << File.expand_path('../../lib', __FILE__)
+
+require 'optparse'
+require 'thread'
+require 'benchmark'
+
+require 'atomic'
+
+Thread.abort_on_exception = true
+
+$conf = {
+  :lock => "atomic",
+  :num_threads => 100,
+  :count => 100_000,
+  :count_per_thread => nil,
+  :slow => nil,
+}
+
+OptionParser.new do |opts|
+  opts.on("-c", "--count NUM") do |n|
+    $conf[:count] = n.to_i
+  end
+  opts.on("-p", "--count-per-thread") do |n|
+    $conf[:count_per_thread] = n.to_i
+  end
+  opts.on("-t", "--num-threads NUM") do |n|
+    $conf[:num_threads] = n.to_i
+  end
+  opts.on("-s", "--slow NUM") do |n|
+    $conf[:slow] = n.to_i
+  end
+  opts.on("-l", "--lock atomic|mutex") do |x|
+    $conf[:lock] = x
+  end
+  opts.on("-h", "--help"){ puts opts; exit }
+end.parse!(ARGV)
+
+unless $conf[:count_per_thread]
+  $conf[:count_per_thread] = $conf[:count] / $conf[:num_threads]
+end
+$conf.delete(:count)
+
+if $conf[:slow].to_i > 0
+  require 'digest/md5'
+  def slow_down
+    $conf[:slow].times do |i|
+      Digest::MD5.hexdigest(i.to_s)
+    end
+  end
+
+  ret = []
+  10.times do
+    m = Benchmark.measure{ slow_down }
+    ret << m.real
+  end
+
+  $conf[:slow_time] = [ret.min, ret.max]
+else
+  def slow_down; end
+end
+
+$stderr.puts $conf.inspect
+
+def para_prepare(&block)
+  num_threads = $conf[:num_threads]
+  count = $conf[:count_per_thread]
+
+  if num_threads % 2 > 0
+    raise ArgumentError, "num_threads must be a multiple of two"
+  end
+
+  # Keep those threads together
+  tg = ThreadGroup.new
+
+  num_threads.times do |i|
+    diff = (i % 2 == 0) ? 1 : -1
+
+    t = Thread.new do
+      nil until $go
+      count.times do
+        yield diff
+      end
+    end
+
+    tg.add(t)
+  end
+
+  # Make sure all threads are started
+  while tg.list.find{|t| t.status != "run"}
+    Thread.pass
+  end
+
+  # For good measure
+  GC.start
+
+  $go = false
+
+  tg
+end
+
+
+
+$tg = nil
+if $conf[:lock] == "atomic"
+  $atom = Atomic.new(0)
+  $tg = para_prepare do |diff|
+    $atom.update do |x|
+      slow_down
+      x + diff
+    end
+  end
+else
+  $lock = Mutex.new
+  $value = 0
+  $tg = para_prepare do |diff|
+    $lock.synchronize do
+      slow_down
+      $value += diff
+    end
+  end
+end
+
+
+# Run !
+#
+# NOTE: It seems to me that this measurement method
+#       is sensible to how the system dispatches his resources.
+#
+#       More precise caluclation could be done using
+#       getrusage's times
+ret = Benchmark.measure do
+  $go = true
+  $tg.list.each{|t| t.join}
+  $go = false
+end
+puts ret.real
diff --git a/app/server/vendor/atomic/examples/graph_atomic_bench.rb b/app/server/vendor/atomic/examples/graph_atomic_bench.rb
new file mode 100755
index 0000000..d118073
--- /dev/null
+++ b/app/server/vendor/atomic/examples/graph_atomic_bench.rb
@@ -0,0 +1,81 @@
+#!/usr/bin/env ruby
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'optparse'
+
+conf = {
+  :vary => "threads",
+  :lock => "atomic"
+}
+
+OptionParser.new do |opts|
+  opts.on("-l", "--lock atomic|mutex") do |l|
+    conf[:lock] = l
+  end
+  opts.on("-v", "--vary threads|speed") do |v|
+    conf[:vary] = v
+  end
+  opts.on("-h", "--help"){ puts opts; exit }
+end.parse!(ARGV)
+
+result = File.open("results_#{conf[:lock]}_#{conf[:vary]}.csv", "w")
+
+
+if conf[:vary] == "threads"
+  # Vary the number of concurrent threads that update the value.
+  #
+  # There is a total count of 1mio updates that is distributed
+  # between the number of threads.
+  #
+  # A pair number of threads is used so that even add and odd substract 1.
+  # This avoid creating instances for Bignum since the number should
+  # stay in the Fixnum range.
+  #
+  (1..100).each do |i|
+    i = i * 2
+
+    ret = []
+    10.times do
+      ret << `ruby ./bench_atomic_1.rb -l #{conf[:lock]} -t #{i}`.to_f
+    end
+
+    line = ([i] + ret).join(', ')
+
+    puts line
+    result.puts line
+  end
+elsif conf[:vary] == "speed"
+  # Varies the execution time of the update block
+  # by using long calulation (MD5)
+  #
+  # NOTE: Thread.pass and sleep() are not usable by the atomic
+  #       lock. It needs to run the whole block without hitting
+  #       another atomic update otherwise it has to retry
+  #
+  # The expected result is that the atomic lock's performance
+  # will hit a certain threshold where it will be worse than mutexes.
+  #
+  (1..30).each do |i|
+
+    ret = []
+    10.times do
+      ret << `ruby ./bench_atomic_1.rb -l #{conf[:lock]} -s #{i}`.to_f
+    end
+
+    line = ([i] + ret).join(', ')
+
+    puts line
+    result.puts line
+  end
+end
diff --git a/app/server/vendor/atomic/ext/AtomicReferenceService.java b/app/server/vendor/atomic/ext/AtomicReferenceService.java
new file mode 100755
index 0000000..8ecd087
--- /dev/null
+++ b/app/server/vendor/atomic/ext/AtomicReferenceService.java
@@ -0,0 +1,24 @@
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import java.io.IOException;
+        
+import org.jruby.Ruby;
+import org.jruby.runtime.load.BasicLibraryService;
+
+public class AtomicReferenceService implements BasicLibraryService {
+    public boolean basicLoad(final Ruby runtime) throws IOException {
+        new org.jruby.ext.atomic.AtomicReferenceLibrary().load(runtime, false);
+        return true;
+    }
+}
+
diff --git a/app/server/vendor/atomic/ext/atomic_reference.c b/app/server/vendor/atomic/ext/atomic_reference.c
new file mode 100755
index 0000000..fbbbca1
--- /dev/null
+++ b/app/server/vendor/atomic/ext/atomic_reference.c
@@ -0,0 +1,119 @@
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <ruby.h>
+#if defined(__sun)
+#include <atomic.h>
+#endif
+
+#ifdef HAVE_LIBKERN_OSATOMIC_H
+#include <libkern/OSAtomic.h>
+#endif
+
+static void ir_mark(void *value) {
+    rb_gc_mark_maybe((VALUE) value);
+}
+
+static VALUE ir_alloc(VALUE klass) {
+    return rb_data_object_alloc(klass, (void *) Qnil, ir_mark, NULL);
+}
+
+static VALUE ir_initialize(int argc, VALUE* argv, VALUE self) {
+    VALUE value = Qnil;
+    if (rb_scan_args(argc, argv, "01", &value) == 1) {
+	value = argv[0];
+    }
+    DATA_PTR(self) = (void *) value;
+    return Qnil;
+}
+
+static VALUE ir_get(VALUE self) {
+#if HAVE_GCC_SYNC
+    __sync_synchronize();
+#elif defined _MSC_VER
+    MemoryBarrier();
+#elif __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
+    OSMemoryBarrier();
+#endif
+    return (VALUE) DATA_PTR(self);
+}
+
+static VALUE ir_set(VALUE self, VALUE new_value) {
+    DATA_PTR(self) = (void *) new_value;
+#if HAVE_GCC_SYNC
+    __sync_synchronize();
+#elif defined _MSC_VER
+    MemoryBarrier();
+#elif __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
+    OSMemoryBarrier();
+#endif
+    return new_value;
+}
+
+static VALUE ir_get_and_set(VALUE self, VALUE new_value) {
+    VALUE old_value = ir_get(self);
+    ir_set(self, new_value);
+    return old_value;
+}
+
+static VALUE ir_compare_and_set(volatile VALUE self, VALUE expect_value, VALUE new_value) {
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
+    if (OSAtomicCompareAndSwap64(expect_value, new_value, &DATA_PTR(self))) {
+	return Qtrue;
+    }
+#elif defined(__sun)
+/*  Assuming VALUE is uintptr_t */
+/*  Based on the definition of uintptr_t from /usr/include/sys/int_types.h */
+#if defined(_LP64) || defined(_I32LPx)
+    /*  64-bit: uintptr_t === unsigned long */
+    if (atomic_cas_ulong((uintptr_t *) &DATA_PTR(self), expect_value, new_value)) {
+        return Qtrue;
+    }
+#else
+    /*  32-bit: uintptr_t === unsigned int */
+    if (atomic_cas_uint((uintptr_t *) &DATA_PTR(self), expect_value, new_value)) {
+        return Qtrue;
+    }
+#endif
+#elif defined _MSC_VER && defined _M_AMD64
+    if (InterlockedCompareExchange64((LONGLONG*)&DATA_PTR(self), new_value, expect_value)) {
+	return Qtrue;
+    }
+#elif defined _MSC_VER && defined _M_IX86
+    if (InterlockedCompareExchange((LONG*)&DATA_PTR(self), new_value, expect_value)) {
+	return Qtrue;
+    }
+#else
+    if (__sync_bool_compare_and_swap(&DATA_PTR(self), expect_value, new_value)) {
+	return Qtrue;
+    }
+#endif
+    return Qfalse;
+}
+
+void Init_atomic_reference() {
+    VALUE cAtomic;
+
+    cAtomic = rb_define_class_under(rb_cObject, "Atomic", rb_cObject);
+
+    rb_define_alloc_func(cAtomic, ir_alloc);
+
+    rb_define_method(cAtomic, "initialize", ir_initialize, -1);
+    rb_define_method(cAtomic, "get", ir_get, 0);
+    rb_define_method(cAtomic, "value", ir_get, 0);
+    rb_define_method(cAtomic, "set", ir_set, 1);
+    rb_define_method(cAtomic, "value=", ir_set, 1);
+    rb_define_method(cAtomic, "get_and_set", ir_get_and_set, 1);
+    rb_define_method(cAtomic, "swap", ir_get_and_set, 1);
+    rb_define_method(cAtomic, "compare_and_set", ir_compare_and_set, 2);
+    rb_define_method(cAtomic, "compare_and_swap", ir_compare_and_set, 2);
+}
diff --git a/app/server/vendor/atomic/ext/extconf.rb b/app/server/vendor/atomic/ext/extconf.rb
new file mode 100755
index 0000000..6baa607
--- /dev/null
+++ b/app/server/vendor/atomic/ext/extconf.rb
@@ -0,0 +1,47 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'mkmf'
+extension_name = 'atomic_reference'
+dir_config(extension_name)
+
+have_header "libkern/OSAtomic.h"
+
+def compiler_is_gcc
+  if CONFIG["GCC"] && CONFIG["GCC"] != ""
+    return true
+  elsif ( # This could stand to be more generic...  but I am afraid.
+    CONFIG["CC"] =~ /\bgcc\b/
+  )
+    return true
+  end
+  return false
+end
+
+
+if compiler_is_gcc
+  case CONFIG["arch"]
+  when /mswin32|mingw|solaris/
+      $CFLAGS += " -march=native"
+  when 'i686-linux'
+      $CFLAGS += " -march=i686"
+  end
+end
+
+try_run(<<CODE,$CFLAGS) && ($defs << '-DHAVE_GCC_SYNC')
+int main() {
+  __sync_synchronize();
+  return 0;
+}
+CODE
+
+create_makefile(extension_name)
diff --git a/app/server/vendor/atomic/ext/org/jruby/ext/atomic/AtomicReferenceLibrary.java b/app/server/vendor/atomic/ext/org/jruby/ext/atomic/AtomicReferenceLibrary.java
new file mode 100755
index 0000000..f549d93
--- /dev/null
+++ b/app/server/vendor/atomic/ext/org/jruby/ext/atomic/AtomicReferenceLibrary.java
@@ -0,0 +1,186 @@
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.jruby.ext.atomic;
+
+import java.lang.reflect.Field;
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+import org.jruby.Ruby;
+import org.jruby.RubyClass;
+import org.jruby.RubyModule;
+import org.jruby.RubyNumeric;
+import org.jruby.RubyObject;
+import org.jruby.anno.JRubyClass;
+import org.jruby.anno.JRubyMethod;
+import org.jruby.runtime.ObjectAllocator;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.runtime.load.Library;
+
+/**
+ * This library adds an atomic reference type to JRuby for use in the atomic
+ * library. We do a native version to avoid the implicit value coercion that
+ * normally happens through JI.
+ * 
+ * @author headius
+ */
+public class AtomicReferenceLibrary implements Library {
+    public void load(Ruby runtime, boolean wrap) throws IOException {
+        RubyClass atomicCls = runtime.defineClass("Atomic", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR);
+        try {
+            sun.misc.Unsafe.class.getMethod("getAndSetObject", Object.class);
+            atomicCls.setAllocator(JRUBYREFERENCE8_ALLOCATOR);
+        } catch (Exception e) {
+            // leave it as Java 6/7 version
+        }
+        atomicCls.defineAnnotatedMethods(JRubyReference.class);
+    }
+    
+    private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() {
+        public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+            return new JRubyReference(runtime, klazz);
+        }
+    };
+    
+    private static final ObjectAllocator JRUBYREFERENCE8_ALLOCATOR = new ObjectAllocator() {
+        public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+            return new JRubyReference8(runtime, klazz);
+        }
+    };
+
+    @JRubyClass(name="JRubyReference", parent="Object")
+    public static class JRubyReference extends RubyObject {
+        volatile IRubyObject reference;
+        
+        static final sun.misc.Unsafe UNSAFE;
+        static final long referenceOffset;
+
+        static {
+            try {
+                UNSAFE = UnsafeHolder.U;
+                Class k = JRubyReference.class;
+                referenceOffset = UNSAFE.objectFieldOffset(k.getDeclaredField("reference"));
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public JRubyReference(Ruby runtime, RubyClass klass) {
+            super(runtime, klass);
+        }
+
+        @JRubyMethod
+        public IRubyObject initialize(ThreadContext context) {
+            UNSAFE.putObject(this, referenceOffset, context.nil);
+            return context.nil;
+        }
+
+        @JRubyMethod
+        public IRubyObject initialize(ThreadContext context, IRubyObject value) {
+            UNSAFE.putObject(this, referenceOffset, value);
+            return context.nil;
+        }
+
+        @JRubyMethod(name = {"get", "value"})
+        public IRubyObject get() {
+            return reference;
+        }
+
+        @JRubyMethod(name = {"set", "value="})
+        public IRubyObject set(IRubyObject newValue) {
+            UNSAFE.putObjectVolatile(this, referenceOffset, newValue);
+            return newValue;
+        }
+
+        @JRubyMethod(name = {"compare_and_set", "compare_and_swap"})
+        public IRubyObject compare_and_set(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) {
+            Ruby runtime = context.runtime;
+            
+            if (expectedValue instanceof RubyNumeric) {
+                // numerics are not always idempotent in Ruby, so we need to do slower logic
+                return compareAndSetNumeric(context, expectedValue, newValue);
+            }
+            
+            return runtime.newBoolean(UNSAFE.compareAndSwapObject(this, referenceOffset, expectedValue, newValue));
+        }
+
+        @JRubyMethod(name = {"get_and_set", "swap"})
+        public IRubyObject get_and_set(ThreadContext context, IRubyObject newValue) {
+            // less-efficient version for Java 6 and 7
+            while (true) {
+                IRubyObject oldValue = get();
+                if (UNSAFE.compareAndSwapObject(this, referenceOffset, oldValue, newValue)) {
+                    return oldValue;
+                }
+            }
+        }
+        
+        private IRubyObject compareAndSetNumeric(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) {
+            Ruby runtime = context.runtime;
+            
+            // loop until:
+            // * reference CAS would succeed for same-valued objects
+            // * current and expected have different values as determined by #equals
+            while (true) {
+                IRubyObject current = reference;
+
+                if (!(current instanceof RubyNumeric)) {
+                    // old value is not numeric, CAS fails
+                    return runtime.getFalse();
+                }
+
+                RubyNumeric currentNumber = (RubyNumeric)current;
+                if (!currentNumber.equals(expectedValue)) {
+                    // current number does not equal expected, fail CAS
+                    return runtime.getFalse();
+                }
+
+                // check that current has not changed, or else allow loop to repeat
+                boolean success = UNSAFE.compareAndSwapObject(this, referenceOffset, current, newValue);
+                if (success) {
+                    // value is same and did not change in interim...success
+                    return runtime.getTrue();
+                }
+            }
+        }
+    }
+
+    private static final class UnsafeHolder {
+	private UnsafeHolder(){}
+	    
+	public static final sun.misc.Unsafe U = loadUnsafe();
+	
+	private static sun.misc.Unsafe loadUnsafe() {
+	    try {
+		Class unsafeClass = Class.forName("sun.misc.Unsafe");
+		Field f = unsafeClass.getDeclaredField("theUnsafe");
+		f.setAccessible(true);
+		return (sun.misc.Unsafe) f.get(null);
+	    } catch (Exception e) {
+		return null;
+	    }
+	}
+    }
+    
+    public static class JRubyReference8 extends JRubyReference {
+        public JRubyReference8(Ruby runtime, RubyClass klass) {
+            super(runtime, klass);
+        }
+
+        @Override
+        public IRubyObject get_and_set(ThreadContext context, IRubyObject newValue) {
+            // efficient version for Java 8
+            return (IRubyObject)UNSAFE.getAndSetObject(this, referenceOffset, newValue);
+        }
+    }
+}
diff --git a/app/server/vendor/atomic/lib/atomic.rb b/app/server/vendor/atomic/lib/atomic.rb
new file mode 100755
index 0000000..7720b97
--- /dev/null
+++ b/app/server/vendor/atomic/lib/atomic.rb
@@ -0,0 +1,26 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+begin
+  # force fallback impl with FORCE_ATOMIC_FALLBACK=1
+  if /[^0fF]/ =~ ENV['FORCE_ATOMIC_FALLBACK']
+    ruby_engine = 'fallback'
+  else
+    ruby_engine = defined?(RUBY_ENGINE)? RUBY_ENGINE : 'ruby'
+  end
+
+  require "atomic/#{ruby_engine}"
+
+rescue LoadError
+  warn "#{__FILE__}:#{__LINE__}: unsupported Ruby engine `#{RUBY_ENGINE}', using less-efficient Atomic impl"
+  require 'atomic/fallback'
+end
diff --git a/app/server/vendor/atomic/lib/atomic/concurrent_update_error.rb b/app/server/vendor/atomic/lib/atomic/concurrent_update_error.rb
new file mode 100755
index 0000000..9d7035a
--- /dev/null
+++ b/app/server/vendor/atomic/lib/atomic/concurrent_update_error.rb
@@ -0,0 +1,18 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+class Atomic
+  class ConcurrentUpdateError < ThreadError
+    # frozen pre-allocated backtrace to speed ConcurrentUpdateError
+    CONC_UP_ERR_BACKTRACE = ['backtrace elided; set verbose to enable'].freeze
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/atomic/lib/atomic/delegated_update.rb b/app/server/vendor/atomic/lib/atomic/delegated_update.rb
new file mode 100755
index 0000000..f031c4e
--- /dev/null
+++ b/app/server/vendor/atomic/lib/atomic/delegated_update.rb
@@ -0,0 +1,37 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'atomic/concurrent_update_error'
+
+# Define update methods that delegate to @ref field
+class Atomic
+  # Pass the current value to the given block, replacing it
+  # with the block's result. May retry if the value changes
+  # during the block's execution.
+  def update
+    true until @ref.compare_and_set(old_value = @ref.get, new_value = yield(old_value))
+    new_value
+  end
+
+  def try_update
+    old_value = @ref.get
+    new_value = yield old_value
+    unless @ref.compare_and_set(old_value, new_value)
+      if $VERBOSE
+        raise ConcurrentUpdateError, "Update failed"
+      else
+        raise ConcurrentUpdateError, "Update failed", ConcurrentUpdateError::CONC_UP_ERR_BACKTRACE
+      end
+    end
+    new_value
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/atomic/lib/atomic/direct_update.rb b/app/server/vendor/atomic/lib/atomic/direct_update.rb
new file mode 100755
index 0000000..d823752
--- /dev/null
+++ b/app/server/vendor/atomic/lib/atomic/direct_update.rb
@@ -0,0 +1,37 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'atomic/concurrent_update_error'
+
+# Define update methods that use direct paths
+class Atomic
+  # Pass the current value to the given block, replacing it
+  # with the block's result. May retry if the value changes
+  # during the block's execution.
+  def update
+    true until compare_and_set(old_value = get, new_value = yield(old_value))
+    new_value
+  end
+
+  def try_update
+    old_value = get
+    new_value = yield old_value
+    unless compare_and_set(old_value, new_value)
+      if $VERBOSE
+        raise ConcurrentUpdateError, "Update failed"
+      else
+        raise ConcurrentUpdateError, "Update failed", ConcurrentUpdateError::CONC_UP_ERR_BACKTRACE
+      end
+    end
+    new_value
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/atomic/lib/atomic/fallback.rb b/app/server/vendor/atomic/lib/atomic/fallback.rb
new file mode 100755
index 0000000..66d9164
--- /dev/null
+++ b/app/server/vendor/atomic/lib/atomic/fallback.rb
@@ -0,0 +1,54 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'thread'
+require 'atomic/direct_update'
+
+# Portable/generic (but not very memory or scheduling-efficient) fallback
+class Atomic #:nodoc: all
+  def initialize(value = nil)
+    @mutex = Mutex.new
+    @value = value
+  end
+
+  def get
+    @mutex.synchronize { @value }
+  end
+  alias value get
+
+  def set(new_value)
+    @mutex.synchronize { @value = new_value }
+  end
+  alias value= set
+
+  def get_and_set(new_value)
+    @mutex.synchronize do
+      old_value = @value
+      @value = new_value
+      old_value
+    end
+  end
+  alias swap get_and_set
+
+  def compare_and_set(old_value, new_value)
+    return false unless @mutex.try_lock
+    begin
+      return false unless @value.equal? old_value
+      @value = new_value
+    ensure
+      @mutex.unlock
+    end
+    true
+  end
+  
+  require 'atomic/numeric_cas_wrapper'
+end
\ No newline at end of file
diff --git a/app/server/vendor/atomic/lib/atomic/jruby.rb b/app/server/vendor/atomic/lib/atomic/jruby.rb
new file mode 100755
index 0000000..9c8b041
--- /dev/null
+++ b/app/server/vendor/atomic/lib/atomic/jruby.rb
@@ -0,0 +1,14 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'atomic_reference'
+require 'atomic/direct_update'
\ No newline at end of file
diff --git a/app/server/vendor/atomic/lib/atomic/numeric_cas_wrapper.rb b/app/server/vendor/atomic/lib/atomic/numeric_cas_wrapper.rb
new file mode 100755
index 0000000..919f362
--- /dev/null
+++ b/app/server/vendor/atomic/lib/atomic/numeric_cas_wrapper.rb
@@ -0,0 +1,32 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+class Atomic
+  alias _compare_and_set compare_and_set
+  def compare_and_set(expected, new)
+    if expected.kind_of? Numeric
+      while true
+        old = get
+        
+        return false unless old.kind_of? Numeric
+        
+        return false unless old == expected
+        
+        result = _compare_and_set(old, new)
+        return result if result
+      end
+    else
+      _compare_and_set(expected, new)
+    end
+  end
+  alias compare_and_swap compare_and_set
+end
\ No newline at end of file
diff --git a/app/server/vendor/atomic/lib/atomic/rbx.rb b/app/server/vendor/atomic/lib/atomic/rbx.rb
new file mode 100755
index 0000000..39cb52c
--- /dev/null
+++ b/app/server/vendor/atomic/lib/atomic/rbx.rb
@@ -0,0 +1,21 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# extend Rubinius's version adding aliases and numeric logic
+class Atomic < Rubinius::AtomicReference
+  alias value get
+  alias value= set
+  alias swap get_and_set
+end
+
+require 'atomic/direct_update'
+require 'atomic/numeric_cas_wrapper'
diff --git a/app/server/vendor/atomic/lib/atomic/ruby.rb b/app/server/vendor/atomic/lib/atomic/ruby.rb
new file mode 100755
index 0000000..bb1aab7
--- /dev/null
+++ b/app/server/vendor/atomic/lib/atomic/ruby.rb
@@ -0,0 +1,34 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+begin
+  require 'atomic_reference'
+rescue LoadError
+  require 'rbconfig'
+  ruby_api = RbConfig::CONFIG['ruby_version']
+  os = case RUBY_PLATFORM
+       when /.*arm.*-linux.*/
+         :raspberry
+       when /.*linux.*/
+         :linux
+       when /.*darwin.*/
+         :osx
+       when /.*mingw.*/
+         :windows
+       else
+         RUBY_PLATFORM
+       end
+  require_relative "../../../../rb-native/#{os}/#{ruby_api}/atomic_reference"
+
+end
+
+require 'atomic/direct_update'
+require 'atomic/numeric_cas_wrapper'
diff --git a/app/server/vendor/atomic/test/test_atomic.rb b/app/server/vendor/atomic/test/test_atomic.rb
new file mode 100755
index 0000000..0e8f62a
--- /dev/null
+++ b/app/server/vendor/atomic/test/test_atomic.rb
@@ -0,0 +1,139 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http:#www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'minitest/autorun'
+require 'atomic'
+
+class TestAtomic < Minitest::Test
+  def test_construct
+    atomic = Atomic.new
+    assert_equal nil, atomic.value
+    
+    atomic = Atomic.new(0)
+    assert_equal 0, atomic.value
+  end
+  
+  def test_value
+    atomic = Atomic.new(0)
+    atomic.value = 1
+    
+    assert_equal 1, atomic.value
+  end
+  
+  def test_update
+    # use a number outside JRuby's fixnum cache range, to ensure identity is preserved
+    atomic = Atomic.new(1000)
+    res = atomic.update {|v| v + 1}
+    
+    assert_equal 1001, atomic.value
+    assert_equal 1001, res
+  end
+  
+  def test_try_update
+    # use a number outside JRuby's fixnum cache range, to ensure identity is preserved
+    atomic = Atomic.new(1000)
+    res = atomic.try_update {|v| v + 1}
+    
+    assert_equal 1001, atomic.value
+    assert_equal 1001, res
+  end
+
+  def test_swap
+    atomic = Atomic.new(1000)
+    res = atomic.swap(1001)
+
+    assert_equal 1001, atomic.value
+    assert_equal 1000, res
+  end
+  
+  def test_try_update_fails
+    # use a number outside JRuby's fixnum cache range, to ensure identity is preserved
+    atomic = Atomic.new(1000)
+    assert_raises Atomic::ConcurrentUpdateError do
+      # assigning within block exploits implementation detail for test
+      atomic.try_update{|v| atomic.value = 1001 ; v + 1}
+    end
+  end
+
+  def test_update_retries
+    tries = 0
+    # use a number outside JRuby's fixnum cache range, to ensure identity is preserved
+    atomic = Atomic.new(1000)
+    # assigning within block exploits implementation detail for test
+    atomic.update{|v| tries += 1 ; atomic.value = 1001 ; v + 1}
+    assert_equal 2, tries
+  end
+  
+  def test_numeric_cas
+    atomic = Atomic.new(0)
+    
+    # 9-bit idempotent Fixnum (JRuby)
+    max_8 = 2**256 - 1
+    min_8 = -(2**256)
+    
+    atomic.set(max_8)
+    max_8.upto(max_8 + 2) do |i|
+      assert atomic.compare_and_swap(i, i+1), "CAS failed for numeric #{i} => #{i + 1}"
+    end
+    
+    atomic.set(min_8)
+    min_8.downto(min_8 - 2) do |i|
+      assert atomic.compare_and_swap(i, i-1), "CAS failed for numeric #{i} => #{i - 1}"
+    end
+    
+    # 64-bit idempotent Fixnum (MRI, Rubinius)
+    max_64 = 2**62 - 1
+    min_64 = -(2**62)
+    
+    atomic.set(max_64)
+    max_64.upto(max_64 + 2) do |i|
+      assert atomic.compare_and_swap(i, i+1), "CAS failed for numeric #{i} => #{i + 1}"
+    end
+    
+    atomic.set(min_64)
+    min_64.downto(min_64 - 2) do |i|
+      assert atomic.compare_and_swap(i, i-1), "CAS failed for numeric #{i} => #{i - 1}"
+    end
+    
+    # 64-bit overflow into Bignum (JRuby)
+    max_64 = 2**63 - 1
+    min_64 = (-2**63)
+    
+    atomic.set(max_64)
+    max_64.upto(max_64 + 2) do |i|
+      assert atomic.compare_and_swap(i, i+1), "CAS failed for numeric #{i} => #{i + 1}"
+    end
+    
+    atomic.set(min_64)
+    min_64.downto(min_64 - 2) do |i|
+      assert atomic.compare_and_swap(i, i-1), "CAS failed for numeric #{i} => #{i - 1}"
+    end
+    
+    # non-idempotent Float (JRuby, Rubinius, MRI < 2.0.0 or 32-bit)
+    atomic.set(1.0 + 0.1)
+    assert atomic.compare_and_set(1.0 + 0.1, 1.2), "CAS failed for #{1.0 + 0.1} => 1.2"
+    
+    # Bignum
+    atomic.set(2**100)
+    assert atomic.compare_and_set(2**100, 0), "CAS failed for #{2**100} => 0"
+    
+    # Rational
+    require 'rational' unless ''.respond_to? :to_r
+    atomic.set(Rational(1,3))
+    assert atomic.compare_and_set(Rational(1,3), 0), "CAS failed for #{Rational(1,3)} => 0"
+    
+    # Complex
+    require 'complex' unless ''.respond_to? :to_c
+    atomic.set(Complex(1,2))
+    assert atomic.compare_and_set(Complex(1,2), 0), "CAS failed for #{Complex(1,2)} => 0"
+  end
+end
diff --git a/app/server/vendor/benchmark-ips-2.3.0/.autotest b/app/server/vendor/benchmark-ips-2.3.0/.autotest
new file mode 100644
index 0000000..ef753ad
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/.autotest
@@ -0,0 +1,23 @@
+# -*- ruby -*-
+
+require 'autotest/restart'
+
+# Autotest.add_hook :initialize do |at|
+#   at.extra_files << "../some/external/dependency.rb"
+#
+#   at.libs << ":../some/external"
+#
+#   at.add_exception 'vendor'
+#
+#   at.add_mapping(/dependency.rb/) do |f, _|
+#     at.files_matching(/test_.*rb$/)
+#   end
+#
+#   %w(TestA TestB).each do |klass|
+#     at.extra_class_map[klass] = "test/test_misc.rb"
+#   end
+# end
+
+# Autotest.add_hook :run_command do |at|
+#   system "rake build"
+# end
diff --git a/app/server/vendor/benchmark-ips-2.3.0/.gitignore b/app/server/vendor/benchmark-ips-2.3.0/.gitignore
new file mode 100644
index 0000000..03d7177
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/.gitignore
@@ -0,0 +1,5 @@
+log
+tmp
+pkg
+doc
+Gemfile.lock
diff --git a/app/server/vendor/benchmark-ips-2.3.0/.travis.yml b/app/server/vendor/benchmark-ips-2.3.0/.travis.yml
new file mode 100644
index 0000000..6160d09
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/.travis.yml
@@ -0,0 +1,12 @@
+language: ruby
+sudo: false
+rvm:
+  - 1.8.7
+  - 1.9.2
+  - 1.9.3
+  - 2.0.0
+  - 2.1.0
+  - 2.1.2
+  - 2.2.2
+  - ree
+  - ruby-head
diff --git a/app/server/vendor/benchmark-ips-2.3.0/Gemfile b/app/server/vendor/benchmark-ips-2.3.0/Gemfile
new file mode 100644
index 0000000..9b9e97b
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/Gemfile
@@ -0,0 +1,8 @@
+source 'https://rubygems.org'
+gem 'hoe'
+
+gem 'minitest', :group => :test
+
+if RUBY_VERSION < "1.9"
+  gem 'json'
+end
diff --git a/app/server/vendor/benchmark-ips-2.3.0/History.txt b/app/server/vendor/benchmark-ips-2.3.0/History.txt
new file mode 100644
index 0000000..bd59f4b
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/History.txt
@@ -0,0 +1,87 @@
+=== 2.3.0 / 2015-07-20
+
+* 2 minor features:
+  * Support keyword arguments
+  * Allow any datatype for labels (use #to_s conversion)
+
+* 1 doc/test changes:
+  * Newer Travis for 1.8.7, ree, and 2.2.2
+
+* 3 PRs merged:
+  * Merge pull request #41 from kbrock/kwargs-support
+  * Merge pull request #42 from kbrock/newer_travis
+  * Merge pull request #43 from kbrock/non_to_s_labels
+
+=== 2.2.0 / 2015-05-09
+
+* 1 minor features:
+  * Fix quiet mode
+  * Allow passing a custom suite via config
+  * Silent a job if a suite was passed and is quiet
+  * Export report to json file.
+  * Accept symbol as report's argument.
+
+* 2 doc fixes:
+  * Squish duplicate `to` in README
+  * Update copyright to 2015. [ci skip]
+
+* 9 PRs merged:
+  * Merge pull request #37 from splattael/patch-1
+  * Merge pull request #36 from kirs/quiet-mode
+  * Merge pull request #35 from JuanitoFatas/doc/suite
+  * Merge pull request #34 from splattael/config-suite
+  * Merge pull request #33 from splattael/suite-quiet
+  * Merge pull request #32 from O-I/remove-gemfile-lock
+  * Merge pull request #31 from JuanitoFatas/doc/bump-copyright-year
+  * Merge pull request #29 from JuanitoFatas/feature/json-export
+  * Merge pull request #26 from JuanitoFatas/feature/takes-symbol-as-report-parameter
+
+=== 2.1.1 / 2015-01-12
+
+* 1 minor fix:
+  * Don't send label through printf so that % work directly
+
+* 1 documenation changes:
+  * Use HEREDOC and wrap at 80 chars for example result description
+
+* 1 usage fix:
+  * Add gemspec for use via bundler git
+
+* 1 PR merged:
+  * Merge pull request #24 from zzak/simple-format-result-description
+
+=== 2.1.0 / 2014-11-10
+
+* Documentation changes:
+  * Many documentation fixes by Juanito Fatas!
+  * Minor readme fix by Will Leinweber
+
+* 2 minor features:
+  * Displaying the total runtime for a job is suppressed unless interesting
+  * Formatting of large values improved (human vs raw mode)
+    * Contributed by Charles Oliver Nutter
+
+=== 2.0.0 / 2014-06-18
+
+* The 'Davy Stevenson' release!
+  * Codename: Springtime Hummingbird Dance
+
+ * Big API refactoring so the internal bits are easier to use
+ * Bump to 2.0 because return types changed to make the API better
+
+* Contributors added:
+  *  Davy Stevenson
+  *  Juanito Fatas
+  *  Benoit Daloze
+  *  Matias
+  *  Tony Arcieri
+  *  Vipul A M
+  *  Zachary Scott
+  *  schneems (Richard Schneeman)
+
+=== 1.0.0 / 2012-03-23
+
+* 1 major enhancement
+
+  * Birthday!
+
diff --git a/app/server/vendor/benchmark-ips-2.3.0/Manifest.txt b/app/server/vendor/benchmark-ips-2.3.0/Manifest.txt
new file mode 100644
index 0000000..13f6062
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/Manifest.txt
@@ -0,0 +1,11 @@
+.autotest
+History.txt
+Manifest.txt
+README.md
+Rakefile
+lib/benchmark/compare.rb
+lib/benchmark/ips.rb
+lib/benchmark/ips/report.rb
+lib/benchmark/ips/job.rb
+lib/benchmark/timing.rb
+test/test_benchmark_ips.rb
diff --git a/app/server/vendor/benchmark-ips-2.3.0/README.md b/app/server/vendor/benchmark-ips-2.3.0/README.md
new file mode 100644
index 0000000..6cf3210
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/README.md
@@ -0,0 +1,179 @@
+[![Gem Version](https://badge.fury.io/rb/benchmark-ips.svg)](http://badge.fury.io/rb/benchmark-ips)
+[![Build Status](https://secure.travis-ci.org/evanphx/benchmark-ips.svg)](http://travis-ci.org/evanphx/benchmark-ips)
+[![Inline docs](http://inch-ci.org/github/evanphx/benchmark-ips.svg)](http://inch-ci.org/github/evanphx/benchmark-ips)
+
+# benchmark-ips
+
+* https://github.com/evanphx/benchmark-ips
+
+* [documentation](http://rubydoc.info/gems/benchmark-ips)
+
+## DESCRIPTION:
+
+A iterations per second enhancement to Benchmark.
+
+## FEATURES/PROBLEMS:
+
+ * benchmark/ips - benchmarks a blocks iterations/second. For short snippits
+   of code, ips automatically figures out how many times to run the code
+   to get interesting data. No more guessing at random iteration counts!
+
+## SYNOPSIS:
+
+```ruby
+require 'benchmark/ips'
+
+Benchmark.ips do |x|
+  # Configure the number of seconds used during
+  # the warmup phase (default 2) and calculation phase (default 5)
+  x.config(:time => 5, :warmup => 2)
+
+  # These parameters can also be configured this way
+  x.time = 5
+  x.warmup = 2
+
+  # Typical mode, runs the block as many times as it can
+  x.report("addition") { 1 + 2 }
+
+  # To reduce overhead, the number of iterations is passed in
+  # and the block must run the code the specific number of times.
+  # Used for when the workload is very small and any overhead
+  # introduces incorrectable errors.
+  x.report("addition2") do |times|
+    i = 0
+    while i < times
+      1 + 2
+      i += 1
+    end
+  end
+
+  # To reduce overhead even more, grafts the code given into
+  # the loop that performs the iterations internally to reduce
+  # overhead. Typically not needed, use the |times| form instead.
+  x.report("addition3", "1 + 2")
+
+  # Really long labels should be formatted correctly
+  x.report("addition-test-long-label") { 1 + 2 }
+
+  # Compare the iterations per second of the various reports!
+  x.compare!
+end
+```
+
+This will generate the following report:
+
+```
+Calculating -------------------------------------
+            addition    71.254k i/100ms
+           addition2    68.658k i/100ms
+           addition3    83.079k i/100ms
+addition-test-long-label
+                        70.129k i/100ms
+-------------------------------------------------
+            addition     4.955M (± 8.7%) i/s -     24.155M
+           addition2    24.011M (± 9.5%) i/s -    114.246M
+           addition3    23.958M (±10.1%) i/s -    115.064M
+addition-test-long-label
+                         5.014M (± 9.1%) i/s -     24.545M
+
+Comparison:
+           addition2: 24011974.8 i/s
+           addition3: 23958619.8 i/s - 1.00x slower
+addition-test-long-label:  5014756.0 i/s - 4.79x slower
+            addition:  4955278.9 i/s - 4.85x slower
+```
+
+Benchmark/ips will report the number of iterations per second for a given block
+of code. When analyzing the results, notice the percent of [standard
+deviation](http://en.wikipedia.org/wiki/Standard\_deviation) which tells us how
+spread out our measurements are from the average. A high standard deviation
+could indicate the results having too much variability.
+
+One benefit to using this method is benchmark-ips automatically determines the
+data points for testing our code, so we can focus on the results instead of
+guessing iteration counts as we do with the traditional Benchmark library.
+
+### Custom Suite
+
+Pass a custom suite to disable garbage collection during benchmark:
+
+```ruby
+require 'benchmark/ips'
+
+# Enable and start GC before each job run. Disable GC afterwards.
+#
+# Inspired by https://www.omniref.com/ruby/2.2.1/symbols/Benchmark/bm?#annotation=4095926&line=182
+class GCSuite
+  def warming(*)
+    run_gc
+  end
+
+  def running(*)
+    run_gc
+  end
+
+  def warmup_stats(*)
+  end
+
+  def add_report(*)
+  end
+
+  private
+
+  def run_gc
+    GC.enable
+    GC.start
+    GC.disable
+  end
+end
+
+suite = GCSuite.new
+
+Benchmark.ips do |x|
+  x.config(:suite => suite)
+  x.report("job1") { ... }
+  x.report("job2") { ... }
+end
+```
+
+## REQUIREMENTS:
+
+* None!
+
+## INSTALL:
+
+    $ gem install benchmark-ips
+
+## DEVELOPERS:
+
+After checking out the source, run:
+
+    $ rake newb
+
+This task will install any missing dependencies, run the tests/specs,
+and generate the RDoc.
+
+## LICENSE:
+
+(The MIT License)
+
+Copyright (c) 2015 Evan Phoenix
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/benchmark-ips-2.3.0/Rakefile b/app/server/vendor/benchmark-ips-2.3.0/Rakefile
new file mode 100644
index 0000000..73a9f95
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/Rakefile
@@ -0,0 +1,26 @@
+# -*- ruby -*-
+
+require 'rubygems'
+require 'hoe'
+
+Hoe.plugin :minitest
+Hoe.plugin :git
+
+hoe = Hoe.spec 'benchmark-ips' do
+  developer('Evan Phoenix', 'evan at phx.io')
+
+  self.readme_file = 'README.md'
+
+  license "MIT"
+end
+
+file "#{hoe.spec.name}.gemspec" => ['Rakefile', "lib/benchmark/ips.rb"] do |t|
+  puts "Generating #{t.name}"
+  File.open(t.name, 'wb') { |f| f.write hoe.spec.to_ruby }
+end
+
+desc "Generate or update the standalone gemspec file for the project"
+task :gemspec => ["#{hoe.spec.name}.gemspec"]
+
+
+# vim: syntax=ruby
diff --git a/app/server/vendor/benchmark-ips-2.3.0/benchmark-ips.gemspec b/app/server/vendor/benchmark-ips-2.3.0/benchmark-ips.gemspec
new file mode 100644
index 0000000..bb62c41
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/benchmark-ips.gemspec
@@ -0,0 +1,47 @@
+# -*- encoding: utf-8 -*-
+# stub: benchmark-ips 2.1.0 ruby lib
+
+d = File.read(File.expand_path("../lib/benchmark/ips.rb", __FILE__))
+if d =~ /VERSION = "(\d+\.\d+\.\d+)"/
+  version = $1
+else
+  version = "0.0.1"
+end
+
+Gem::Specification.new do |s|
+  s.name = "benchmark-ips"
+  s.version = version
+
+  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+  s.require_paths = ["lib"]
+  s.authors = ["Evan Phoenix"]
+  s.date = "2015-01-12"
+  s.description = "A iterations per second enhancement to Benchmark."
+  s.email = ["evan at phx.io"]
+  s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.md"]
+  s.files = [".autotest", ".gemtest", "History.txt", "Manifest.txt", "README.md", "Rakefile", "lib/benchmark/compare.rb", "lib/benchmark/ips.rb", "lib/benchmark/ips/job.rb", "lib/benchmark/ips/report.rb", "lib/benchmark/timing.rb", "test/test_benchmark_ips.rb"]
+  s.homepage = "https://github.com/evanphx/benchmark-ips"
+  s.licenses = ["MIT"]
+  s.rdoc_options = ["--main", "README.md"]
+  s.rubygems_version = "2.2.2"
+  s.summary = "A iterations per second enhancement to Benchmark."
+  s.test_files = ["test/test_benchmark_ips.rb"]
+
+  if s.respond_to? :specification_version then
+    s.specification_version = 4
+
+    if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+      s.add_development_dependency(%q<minitest>, ["~> 5.4"])
+      s.add_development_dependency(%q<rdoc>, ["~> 4.0"])
+      s.add_development_dependency(%q<hoe>, ["~> 3.13"])
+    else
+      s.add_dependency(%q<minitest>, ["~> 5.4"])
+      s.add_dependency(%q<rdoc>, ["~> 4.0"])
+      s.add_dependency(%q<hoe>, ["~> 3.13"])
+    end
+  else
+    s.add_dependency(%q<minitest>, ["~> 5.4"])
+    s.add_dependency(%q<rdoc>, ["~> 4.0"])
+    s.add_dependency(%q<hoe>, ["~> 3.13"])
+  end
+end
diff --git a/app/server/vendor/benchmark-ips-2.3.0/examples/simple.rb b/app/server/vendor/benchmark-ips-2.3.0/examples/simple.rb
new file mode 100755
index 0000000..ea36ff4
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/examples/simple.rb
@@ -0,0 +1,47 @@
+#!/usr/bin/env ruby
+
+require 'benchmark/ips'
+
+Benchmark.ips do |x|
+
+  # Configure the number of seconds used during
+  # the warmup phase and calculation phase
+  x.config(:time => 5, :warmup => 2)
+
+  # These parameters can also be configured this way
+  x.time = 5
+  x.warmup = 2
+
+  # Typical mode, runs the block as many times as it can
+  x.report("addition") { 1 + 2 }
+
+  # To reduce overhead, the number of iterations is passed in
+  # and the block must run the code the specific number of times.
+  # Used for when the workload is very small and any overhead
+  # introduces incorrectable errors.
+  x.report(:addition2) do |times|
+    i = 0
+    while i < times
+      1 + 2
+      i += 1
+    end
+  end
+
+  # To reduce overhead even more, grafts the code given into
+  # the loop that performs the iterations internally to reduce
+  # overhead. Typically not needed, use the |times| form instead.
+  x.report("addition3", "1 + 2")
+
+  # Really long labels should be formatted correctly
+  x.report("addition-test-long-label") { 1 + 2 }
+
+  x.compare!
+end
+
+puts <<-EOD
+Typical results will show addition2 & addition3 to be the most performant, and
+they should perform reasonably similarly. You should see addition and
+addition-test-long-label to perform very similarly to each other (as they are
+running the same test, just with different labels), and they should both run in
+the neighborhood of 3.5 times slower than addition2 and addition3."
+EOD
diff --git a/app/server/vendor/benchmark-ips-2.3.0/lib/benchmark/compare.rb b/app/server/vendor/benchmark-ips-2.3.0/lib/benchmark/compare.rb
new file mode 100644
index 0000000..daa885d
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/lib/benchmark/compare.rb
@@ -0,0 +1,72 @@
+module Benchmark
+  # Functionality of performaing comparison between reports.
+  #
+  # Usage:
+  #
+  # Add +x.compare!+ to perform comparison between reports.
+  #
+  # Example:
+  #   > Benchmark.ips do |x|
+  #     x.report('Reduce using tag')     { [*1..10].reduce(:+) }
+  #     x.report('Reduce using to_proc') { [*1..10].reduce(&:+) }
+  #     x.compare!
+  #   end
+  #
+  #   Calculating -------------------------------------
+  #       Reduce using tag     19216 i/100ms
+  #   Reduce using to_proc     17437 i/100ms
+  #   -------------------------------------------------
+  #       Reduce using tag   278950.0 (±8.5%) i/s -    1402768 in   5.065112s
+  #   Reduce using to_proc   247295.4 (±8.0%) i/s -    1238027 in   5.037299s
+  #
+  #   Comparison:
+  #       Reduce using tag:   278950.0 i/s
+  #   Reduce using to_proc:   247295.4 i/s - 1.13x slower
+  #
+  # Besides regular Calculating report, this will also indicates which one is slower.
+  module Compare
+
+    # Compare between reports, prints out facts of each report:
+    # runtime, comparative speed difference.
+    # @param reports [Array<Report>] Reports to compare.
+    def compare(*reports)
+      return if reports.size < 2
+
+      iter = false
+      sorted = reports.sort do |a,b|
+        if a.respond_to? :ips
+          iter = true
+          b.ips <=> a.ips
+        else
+          a.runtime <=> b.runtime
+        end
+      end
+
+      best = sorted.shift
+
+      $stdout.puts "\nComparison:"
+
+      if iter
+        $stdout.printf "%20s: %10.1f i/s\n", best.label, best.ips
+      else
+        $stdout.puts "#{best.rjust(20)}: #{best.runtime}s"
+      end
+
+      sorted.each do |report|
+        name = report.label.to_s
+
+        if iter
+          x = (best.ips.to_f / report.ips.to_f)
+          $stdout.printf "%20s: %10.1f i/s - %.2fx slower\n", name, report.ips, x
+        else
+          x = "%.2f" % (report.ips.to_f / best.ips.to_f)
+          $stdout.puts "#{name.rjust(20)}: #{report.runtime}s - #{x}x slower"
+        end
+      end
+
+      $stdout.puts
+    end
+  end
+
+  extend Benchmark::Compare
+end
diff --git a/app/server/vendor/benchmark-ips-2.3.0/lib/benchmark/ips.rb b/app/server/vendor/benchmark-ips-2.3.0/lib/benchmark/ips.rb
new file mode 100644
index 0000000..b9c3f4f
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/lib/benchmark/ips.rb
@@ -0,0 +1,103 @@
+# encoding: utf-8
+require 'benchmark/timing'
+require 'benchmark/compare'
+require 'benchmark/ips/report'
+require 'benchmark/ips/job'
+
+# Performance benchmarking library
+module Benchmark
+  # Benchmark in iterations per second, no more guessing!
+  # @see https://github.com/evanphx/benchmark-ips
+  module IPS
+
+    # Benchmark-ips Gem version.
+    VERSION = "2.3.0"
+
+    # CODENAME of current version.
+    CODENAME = "Monsoon BBQ"
+
+    # Measure code in block, each code's benchmarked result will display in
+    # iteration per second with standard deviation in given time.
+    # @param time [Integer] Specify how long should benchmark your code in seconds.
+    # @param warmup [Integer] Specify how long should Warmup time run in seconds.
+    # @return [Report]
+    def ips(*args)
+      if args[0].is_a?(Hash)
+        time, warmup, quiet = args[0].values_at(:time, :warmup, :quiet)
+      else
+        time, warmup, quiet = args
+      end
+
+      suite = nil
+
+      sync, $stdout.sync = $stdout.sync, true
+
+      if defined? Benchmark::Suite and Suite.current
+        suite = Benchmark::Suite.current
+      end
+
+      quiet ||= (suite && suite.quiet?)
+
+      job = Job.new({:suite => suite,
+                     :quiet => quiet
+      })
+
+      job_opts = {}
+      job_opts[:time] = time unless time.nil?
+      job_opts[:warmup] = warmup unless warmup.nil?
+
+      job.config job_opts
+
+      yield job
+
+      $stdout.puts "Calculating -------------------------------------" unless quiet
+
+      job.run_warmup
+
+      $stdout.puts "-------------------------------------------------" unless quiet
+
+      job.run
+
+      $stdout.sync = sync
+
+      if job.compare?
+        job.run_comparison
+      end
+
+      if job.json?
+        job.generate_json
+      end
+
+      return job.full_report
+    end
+
+    # Set options for running the benchmarks.
+    # :format => [:human, :raw]
+    #    :human format narrows precision and scales results for readability
+    #    :raw format displays 6 places of precision and exact iteration counts
+    def self.options
+      @options ||= {:format => :human}
+    end
+
+    module Helpers
+      def scale(value)
+        scale = (Math.log10(value) / 3).to_i
+        suffix = case scale
+        when 1; 'k'
+        when 2; 'M'
+        when 3; 'B'
+        when 4; 'T'
+        when 5; 'Q'
+        else
+          # < 1000 or > 10^15, no scale or suffix
+          scale = 0
+          ' '
+        end
+        "%10.3f#{suffix}" % (value.to_f / (1000 ** scale))
+      end
+      module_function :scale
+    end
+  end
+
+  extend Benchmark::IPS # make ips available as module-level method
+end
diff --git a/app/server/vendor/benchmark-ips-2.3.0/lib/benchmark/ips/job.rb b/app/server/vendor/benchmark-ips-2.3.0/lib/benchmark/ips/job.rb
new file mode 100644
index 0000000..a7d52a3
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/lib/benchmark/ips/job.rb
@@ -0,0 +1,337 @@
+module Benchmark
+  module IPS
+    # Benchmark jobs.
+    class Job
+      # Microseconds per 100 millisecond.
+      MICROSECONDS_PER_100MS = 100_000
+      # Microseconds per second.
+      MICROSECONDS_PER_SECOND = 1_000_000
+      # The percentage of the expected runtime to allow
+      # before reporting a weird runtime
+      MAX_TIME_SKEW = 0.05
+
+      # Entries in Benchmark Jobs.
+      class Entry
+        # Instantiate the Benchmark::IPS::Job::Entry.
+        # @param label [#to_s] Label of Benchmarked code.
+        # @param action [String, Proc] Code to be benchmarked.
+        # @raise [ArgumentError] Raises when action is not String or not responding to +call+.
+        def initialize(label, action)
+          @label = label
+
+          if action.kind_of? String
+            compile action
+            @action = self
+            @as_action = true
+          else
+            unless action.respond_to? :call
+              raise ArgumentError, "invalid action, must respond to #call"
+            end
+
+            @action = action
+
+            if action.respond_to? :arity and action.arity > 0
+              @call_loop = true
+            else
+              @call_loop = false
+            end
+
+            @as_action = false
+          end
+        end
+
+        # The label of benchmarking action.
+        # @return [#to_s] Label of action.
+        attr_reader :label
+
+        # The benchmarking action.
+        # @return [String, Proc] Code to be called, could be String / Proc.
+        attr_reader :action
+
+        # Add padding to label's right if label's length < 20,
+        # Otherwise add a new line and 20 whitespaces.
+        # @return [String] Right justified label.
+        def label_rjust
+          label = @label.to_s
+          if label.size > 20
+            "#{label}\n#{' ' * 20}"
+          else
+            label.rjust(20)
+          end
+        end
+
+        # Call action by given times, return if + at call_loop+ is present.
+        # @param times [Integer] Times to call + at action+.
+        # @return [Integer] Number of times the + at action+ has been called.
+        def call_times(times)
+          return @action.call(times) if @call_loop
+
+          act = @action
+
+          i = 0
+          while i < times
+            act.call
+            i += 1
+          end
+        end
+
+        # Compile code into +call_times+ method.
+        # @param str [String] Code to be compiled.
+        # @return [Symbol] :call_times.
+        def compile(str)
+          m = (class << self; self; end)
+          code = <<-CODE
+            def call_times(__total);
+              __i = 0
+              while __i < __total
+                #{str};
+                __i += 1
+              end
+            end
+          CODE
+          m.class_eval code
+        end
+      end # End of Entry
+
+      # class Job
+
+      # Two-element arrays, consisting of label and block pairs.
+      # @return [Array<Entry>] list of entries
+      attr_reader :list
+
+      # Determining whether to run comparison utility.
+      # @return [Boolean] true if needs to run compare.
+      attr_reader :compare
+
+      # Report object containing information about the run.
+      # @return [Report] the report object.
+      attr_reader :full_report
+
+      # Storing Iterations in time period.
+      # @return [Hash]
+      attr_reader :timing
+
+      # Warmup time setter and getter (in seconds).
+      # @return [Integer]
+      attr_accessor :warmup
+
+      # Calculation time setter and getter (in seconds).
+      # @return [Integer]
+      attr_accessor :time
+
+      # Instantiate the Benchmark::IPS::Job.
+      # @option opts [Benchmark::Suite] (nil) :suite Specify Benchmark::Suite.
+      # @option opts [Boolean] (false) :quiet Suppress the printing of information.
+      def initialize opts={}
+        @suite = opts[:suite] || nil
+        @quiet = opts[:quiet] || false
+        @list = []
+        @compare = false
+        @json_path = false
+
+        @timing = {}
+        @full_report = Report.new
+
+        # Default warmup and calculation time in seconds.
+        @warmup = 2
+        @time = 5
+      end
+
+      # Job configuration options, set + at warmup+ and + at time+.
+      # @option opts [Integer] :warmup Warmup time.
+      # @option opts [Integer] :time Calculation time.
+      def config opts
+        @warmup = opts[:warmup] if opts[:warmup]
+        @time = opts[:time] if opts[:time]
+        @suite = opts[:suite] if opts[:suite]
+      end
+
+      # Return true if job needs to be compared.
+      # @return [Boolean] Need to compare?
+      def compare?
+        @compare
+      end
+
+      # Set @compare to true.
+      def compare!
+        @compare = true
+      end
+
+
+      # Return true if job needs to generate json.
+      # @return [Boolean] Need to generate json?
+      def json?
+        !!@json_path
+      end
+
+      # Set @json_path to given path, defaults to "data.json".
+      def json!(path="data.json")
+        @json_path = path
+      end
+
+      # Registers the given label and block pair in the job list.
+      # @param label [String] Label of benchmarked code.
+      # @param str [String] Code to be benchamrked.
+      # @param blk [Proc] Code to be benchamrked.
+      # @raise [ArgumentError] Raises if str and blk are both present.
+      # @raise [ArgumentError] Raises if str and blk are both absent.
+      def item(label="", str=nil, &blk) # :yield:
+        if blk and str
+          raise ArgumentError, "specify a block and a str, but not both"
+        end
+
+        action = str || blk
+        raise ArgumentError, "no block or string" unless action
+
+        @list.push Entry.new(label, action)
+        self
+      end
+      alias_method :report, :item
+
+      # Calculate the cycles needed to run for approx 100ms,
+      # given the number of iterations to run the given time.
+      # @param [Float] time_msec Each iteration's time in ms.
+      # @param [Integer] iters Iterations.
+      # @return [Integer] Cycles per 100ms.
+      def cycles_per_100ms time_msec, iters
+        cycles = ((MICROSECONDS_PER_100MS / time_msec) * iters).to_i
+        cycles = 1 if cycles <= 0
+        cycles
+      end
+
+      # Calculate the time difference of before and after in microseconds.
+      # @param [Time] before time.
+      # @param [Time] after time.
+      # @return [Float] Time difference of before and after.
+      def time_us before, after
+        (after.to_f - before.to_f) * MICROSECONDS_PER_SECOND
+      end
+
+      # Calculate the interations per second given the number
+      # of cycles run and the time in microseconds that elapsed.
+      # @param [Integer] cycles Cycles.
+      # @param [Integer] time_us Time in microsecond.
+      # @return [Float] Iteration per second.
+      def iterations_per_sec cycles, time_us
+        MICROSECONDS_PER_SECOND * (cycles.to_f / time_us.to_f)
+      end
+
+      # Run warmup.
+      def run_warmup
+        @list.each do |item|
+          @suite.warming item.label, @warmup if @suite
+
+          unless @quiet
+            $stdout.print item.label_rjust
+          end
+
+          Timing.clean_env
+
+          before = Time.now
+          target = Time.now + @warmup
+
+          warmup_iter = 0
+
+          while Time.now < target
+            item.call_times(1)
+            warmup_iter += 1
+          end
+
+          after = Time.now
+
+          warmup_time_us = time_us before, after
+
+          @timing[item] = cycles_per_100ms warmup_time_us, warmup_iter
+
+          case Benchmark::IPS.options[:format]
+          when :human
+            $stdout.printf "%s i/100ms\n", Helpers.scale(@timing[item]) unless @quiet
+          else
+            $stdout.printf "%10d i/100ms\n", @timing[item] unless @quiet
+          end
+
+          @suite.warmup_stats warmup_time_us, @timing[item] if @suite
+        end
+      end
+
+      # Run calculation.
+      def run
+        @list.each do |item|
+          @suite.running item.label, @time if @suite
+
+          unless @quiet
+            $stdout.print item.label_rjust
+          end
+
+          Timing.clean_env
+
+          iter = 0
+
+          target = Time.now + @time
+
+          measurements_us = []
+
+          # Running this number of cycles should take around 100ms.
+          cycles = @timing[item]
+
+          while Time.now < target
+            before = Time.now
+            item.call_times cycles
+            after = Time.now
+
+            # If for some reason the timing said this took no time (O_o)
+            # then ignore the iteration entirely and start another.
+            iter_us = time_us before, after
+            next if iter_us <= 0.0
+
+            iter += cycles
+
+            measurements_us << iter_us
+          end
+
+          final_time = Time.now
+
+          measured_us = measurements_us.inject(0) { |a,i| a + i }
+
+          all_ips = measurements_us.map { |time_us|
+            iterations_per_sec cycles, time_us
+          }
+
+          avg_ips = Timing.mean(all_ips)
+          sd_ips =  Timing.stddev(all_ips).round
+
+          rep = create_report(item, measured_us, iter, avg_ips, sd_ips, cycles)
+
+          if (final_time - target).abs >= (@time.to_f * MAX_TIME_SKEW)
+            rep.show_total_time!
+          end
+
+          $stdout.puts " #{rep.body}" unless @quiet
+
+          @suite.add_report rep, caller(1).first if @suite
+        end
+      end
+
+      # Run comparison of entries in + at full_report+.
+      def run_comparison
+        @full_report.run_comparison
+      end
+
+      # Generate json from + at full_report+.
+      def generate_json
+        @full_report.generate_json @json_path
+      end
+
+      # Create report by add entry to + at full_report+.
+      # @param item [Benchmark::IPS::Job::Entry] Report item.
+      # @param measured_us [Integer] Measured time in microsecond.
+      # @param iter [Integer] Iterations.
+      # @param avg_ips [Float] Average iterations per second.
+      # @param sd_ips [Float] Standard deviation iterations per second.
+      # @param cycles [Integer] Number of Cycles.
+      def create_report(item, measured_us, iter, avg_ips, sd_ips, cycles)
+        @full_report.add_entry item.label, measured_us, iter, avg_ips, sd_ips, cycles
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/benchmark-ips-2.3.0/lib/benchmark/ips/report.rb b/app/server/vendor/benchmark-ips-2.3.0/lib/benchmark/ips/report.rb
new file mode 100644
index 0000000..e53d934
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/lib/benchmark/ips/report.rb
@@ -0,0 +1,174 @@
+# encoding: utf-8
+
+module Benchmark
+  module IPS
+
+    # Report contains benchamrking entries.
+    # Perform operations like add new entry, run comparison between entries.
+    class Report
+
+      # Represents benchmarking code data for Report.
+      class Entry
+        # Instantiate the Benchmark::IPS::Report::Entry.
+        # @param [#to_s] label Label of entry.
+        # @param [Integer] us Measured time in microsecond.
+        # @param [Integer] iters Iterations.
+        # @param [Float] ips Iterations per second.
+        # @param [Float] ips_sd Standard deviation of iterations per second.
+        # @param [Integer] cycles Number of Cycles.
+        def initialize(label, us, iters, ips, ips_sd, cycles)
+          @label = label
+          @microseconds = us
+          @iterations = iters
+          @ips = ips
+          @ips_sd = ips_sd
+          @measurement_cycle = cycles
+          @show_total_time = false
+        end
+
+        # Label of entry.
+        # @return [String] the label of entry.
+        attr_reader :label
+
+        # Measured time in microsecond.
+        # @return [Integer] number of microseconds.
+        attr_reader :microseconds
+
+        # Number of Iterations.
+        # @return [Integer] number of iterations.
+        attr_reader :iterations
+
+        # Iterations per second.
+        # @return [Float] number of iterations per second.
+        attr_reader :ips
+
+        # Standard deviation of iteration per second.
+        # @return [Float] standard deviation of iteration per second.
+        attr_reader :ips_sd
+
+        # Number of Cycles.
+        # @return [Integer] number of cycles.
+        attr_reader :measurement_cycle
+
+        # Control if the total time the job took is reported.
+        # Typically this value is not significant because it's very
+        # close to the expected time, so it's supressed by default.
+        def show_total_time!
+          @show_total_time = true
+        end
+
+        # Return entry's microseconds in seconds.
+        # @return [Float] + at microseconds+ in seconds.
+        def seconds
+          @microseconds.to_f / 1_000_000.0
+        end
+
+        # Return entry's standard deviation of iteration per second in percentage.
+        # @return [Float] + at ips_sd+ in percentage.
+        def stddev_percentage
+          100.0 * (@ips_sd.to_f / @ips.to_f)
+        end
+
+        alias_method :runtime, :seconds
+
+        # Return Entry body text with left padding.
+        # Body text contains information of iteration per second with
+        # percentage of standard deviation, iterations in runtime.
+        # @return [String] Left justified body.
+        def body
+          case Benchmark::IPS.options[:format]
+          when :human
+            left = "%s (±%4.1f%%) i/s" % [Helpers.scale(ips), stddev_percentage]
+            iters = Helpers.scale(@iterations)
+
+            if @show_total_time
+              left.ljust(20) + (" - %s in %10.6fs" % [iters, runtime])
+            else
+              left.ljust(20) + (" - %s" % iters)
+            end
+          else
+            left = "%10.1f (±%.1f%%) i/s" % [ips, stddev_percentage]
+
+            if @show_total_time
+              left.ljust(20) + (" - %10d in %10.6fs" % [@iterations, runtime])
+            else
+              left.ljust(20) + (" - %10d" % @iterations)
+            end
+          end
+        end
+
+        # Return header with padding if + at label+ is < length of 20.
+        # @return [String] Right justified header (+ at label+).
+        def header
+          @label.to_s.rjust(20)
+        end
+
+        # Return string repesentation of Entry object.
+        # @return [String] Header and body.
+        def to_s
+          "#{header} #{body}"
+        end
+
+        # Print entry to current standard output ($stdout).
+        def display
+          $stdout.puts to_s
+        end
+      end # End of Entry
+
+      # class Report
+
+      # Entry to represent each benchamarked code in Report.
+      # @return [Array<Entry>] Entries in Report.
+      attr_reader :entries
+
+      # Instantiate the Report.
+      def initialize
+        @entries = []
+        @data = nil
+      end
+
+      # Add entry to report.
+      # @param label [String] Entry label.
+      # @param microseconds [Integer] Measured time in microsecond.
+      # @param iters [Integer] Iterations.
+      # @param ips [Float] Average Iterations per second.
+      # @param ips_sd [Float] Standard deviation of iterations per second.
+      # @param measurement_cycle [Integer] Number of cycles.
+      # @return [Entry] Last added entry.
+      def add_entry label, microseconds, iters, ips, ips_sd, measurement_cycle
+        @entries << Entry.new(label, microseconds, iters, ips, ips_sd, measurement_cycle)
+        @entries.last
+      end
+
+      # Entries data in array for generate json.
+      # Each entry is a hash, consists of:
+      #   name:   Entry#label
+      #   ips:    Entry#ips
+      #   stddev: Entry#ips_sd
+      # @return [Array] Array of entries
+      def data
+        @data ||= @entries.collect do |entry|
+          {
+            :name => entry.label,
+            :ips =>  entry.ips,
+            :stddev => entry.ips_sd
+          }
+        end
+      end
+
+      # Run comparison of entries.
+      def run_comparison
+        Benchmark.compare(*@entries)
+      end
+
+      # Generate json from Report#data to given path.
+      # @param path [String] path to generate json.
+      def generate_json(path)
+        File.open path, "w" do |f|
+          require "json"
+          f.write JSON.pretty_generate(data)
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/benchmark-ips-2.3.0/lib/benchmark/timing.rb b/app/server/vendor/benchmark-ips-2.3.0/lib/benchmark/timing.rb
new file mode 100644
index 0000000..7b6a3e1
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/lib/benchmark/timing.rb
@@ -0,0 +1,56 @@
+module Benchmark
+  # Perform caclulations on Timing results.
+  module Timing
+
+    # Calculate (arithmetic) mean of given samples.
+    # @param [Array] samples Samples to calculate mean.
+    # @return [Float] Mean of given samples.
+    def self.mean(samples)
+      sum = samples.inject(0) { |acc, i| acc + i }
+      sum / samples.size
+    end
+
+    # Calculate variance of given samples.
+    # @param [Float] m Optional mean (Expected value).
+    # @return [Float] Variance of given samples.
+    def self.variance(samples, m=nil)
+      m ||= mean(samples)
+
+      total = samples.inject(0) { |acc, i| acc + ((i - m) ** 2) }
+
+      total / samples.size
+    end
+
+    # Calculate standard deviation of given samples.
+    # @param [Array] samples Samples to calculate standard deviation.
+    # @param [Float] m Optional mean (Expected value).
+    # @return [Float] standard deviation of given samples.
+    def self.stddev(samples, m=nil)
+      Math.sqrt variance(samples, m)
+    end
+
+    # Resample mean of given samples.
+    # @param [Integer] resample_times Resample times, defaults to 100.
+    # @return [Array] Resampled samples.
+    def self.resample_mean(samples, resample_times=100)
+      resamples = []
+
+      resample_times.times do
+        resample = samples.map { samples[rand(samples.size)] }
+        resamples << Timing.mean(resample)
+      end
+
+      resamples
+    end
+
+    # Recycle unsed objects by starting Garbage Collector.
+    def self.clean_env
+      # rbx
+      if GC.respond_to? :run
+        GC.run(true)
+      else
+        GC.start
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/benchmark-ips-2.3.0/test/test_benchmark_ips.rb b/app/server/vendor/benchmark-ips-2.3.0/test/test_benchmark_ips.rb
new file mode 100644
index 0000000..429f053
--- /dev/null
+++ b/app/server/vendor/benchmark-ips-2.3.0/test/test_benchmark_ips.rb
@@ -0,0 +1,161 @@
+require "minitest/autorun"
+require "benchmark/ips"
+require "stringio"
+
+class TestBenchmarkIPS < Minitest::Test
+  def setup
+    @old_stdout = $stdout
+    $stdout = StringIO.new
+  end
+
+  def teardown
+    $stdout = @old_stdout
+  end
+
+  def test_kwargs
+    Benchmark.ips(:time => 1, :warmup => 1, :quiet => false) do |x|
+      x.report("sleep 0.25") { sleep(0.25) }
+    end
+
+    assert $stdout.string.size > 0
+  end
+
+  def test_output
+    Benchmark.ips(1) do |x|
+      x.report("operation") { 100 * 100 }
+    end
+
+    assert $stdout.string.size > 0
+  end
+
+  def test_quiet
+    Benchmark.ips(1, nil, true) do |x|
+      x.report("operation") { 100 * 100 }
+    end
+
+    assert $stdout.string.size.zero?
+
+    Benchmark.ips(:quiet => true) do |x|
+      x.report("operation") { 100 * 100 }
+    end
+
+    assert $stdout.string.size.zero?
+  end
+
+  def test_ips
+    report = Benchmark.ips do |x|
+      x.config(:time => 1, :warmup => 1)
+      x.report("sleep 0.25") { sleep(0.25) }
+      x.report("sleep 0.05") { sleep(0.05) }
+      x.compare!
+    end
+
+    rep1 = report.entries[0]
+    rep2 = report.entries[1]
+
+    assert_equal "sleep 0.25", rep1.label
+    assert_equal 4, rep1.iterations
+    assert_in_delta 4.0, rep1.ips, 0.2
+
+    assert_equal "sleep 0.05", rep2.label
+    assert_in_delta 20.0, rep2.iterations.to_f, 1.0
+    assert_in_delta 20.0, rep2.ips, 1.0
+  end
+
+  def test_ips_alternate_config
+    report = Benchmark.ips do |x|
+      x.time = 1
+      x.warmup = 1
+      x.report("sleep 0.25") { sleep(0.25) }
+    end
+
+    rep = report.entries.first
+
+    assert_equal "sleep 0.25", rep.label
+    assert_equal 4, rep.iterations
+    assert_in_delta 4.0, rep.ips, 0.2
+  end
+
+  def test_ips_old_config
+    report = Benchmark.ips(1,1) do |x|
+      x.report("sleep 0.25") { sleep(0.25) }
+    end
+
+    rep = report.entries.first
+
+    assert_equal "sleep 0.25", rep.label
+    assert_equal 4, rep.iterations
+    assert_in_delta 4.0, rep.ips, 0.2
+  end
+
+  def test_ips_config_suite
+    suite = Struct.new(:calls) do
+      def method_missing(method, *args)
+        calls << method
+      end
+    end.new([])
+
+    Benchmark.ips(0.1, 0.1) do |x|
+      x.config(:suite => suite)
+      x.report("job") {}
+    end
+
+    assert_equal [:warming, :warmup_stats, :running, :add_report], suite.calls
+  end
+
+  def test_ips_defaults
+    report = Benchmark.ips do |x|
+      x.report("sleep 0.25") { sleep(0.25) }
+    end
+
+    rep = report.entries.first
+
+    assert_equal "sleep 0.25", rep.label
+    assert_equal 4*5, rep.iterations
+    assert_in_delta 4.0, rep.ips, 0.2
+  end
+
+  def test_ips_report_using_symbol
+    report = Benchmark.ips do |x|
+      x.report(:sleep_a_quarter_second) { sleep(0.25) }
+    end
+
+    rep = report.entries.first
+
+    assert_equal :sleep_a_quarter_second, rep.label
+    assert_equal 4*5, rep.iterations
+    assert_in_delta 4.0, rep.ips, 0.2
+  end
+
+  def test_ips_default_data
+    report = Benchmark.ips do |x|
+      x.report("sleep 0.25") { sleep(0.25) }
+    end
+
+    all_data = report.data
+
+    assert all_data
+    assert_equal "sleep 0.25", all_data[0][:name]
+    assert all_data[0][:ips]
+    assert all_data[0][:stddev]
+  end
+
+  def test_json_output
+    json_file = Tempfile.new("data.json")
+
+    Benchmark.ips do |x|
+      x.report("sleep 0.25") { sleep(0.25) }
+      x.json! json_file.path
+    end
+
+    json_data = json_file.read
+    assert json_data
+
+    data = JSON.parse json_data
+    assert data
+    assert_equal 1, data.size
+    assert_equal "sleep 0.25", data[0]["name"]
+    assert data[0]["ips"]
+    assert data[0]["stddev"]
+  end
+end
diff --git a/app/server/vendor/blankslate/MIT-LICENSE b/app/server/vendor/blankslate/MIT-LICENSE
new file mode 100755
index 0000000..c00d4c0
--- /dev/null
+++ b/app/server/vendor/blankslate/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright 2011 Jim Weirich (jim at weirichhouse.org)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/blankslate/README b/app/server/vendor/blankslate/README
new file mode 100755
index 0000000..fcd3f87
--- /dev/null
+++ b/app/server/vendor/blankslate/README
@@ -0,0 +1,31 @@
+BlankSlate
+===
+
+BlankSlate provides an abstract base class with no predefined
+methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
+BlankSlate is useful as a base class when writing classes that
+depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
+
+Copyright 2004, 2006 by Jim Weirich (jim at weirichhouse.org).
+All rights reserved.
+
+
+Extracted from Builder because, for no conceivable reason,
+blankslate isn't in its own gem. Gemified by David Masover,
+moved to gemcutter by Jack Danger Canty (gemcutter at 6brand.com
+if you'd like to own this gem).
+
+Explanation on extraction from David Masover:
+
+So, Builder seems to have the most complete implementation of
+BlankSlate, short of Ruby 1.9's BasicObject. The problem is,
+this is part of Builder, and still inside the Builder gem.
+
+It's especially frustrating, because the Builder source
+(lib/builder/blankslate.rb) seems to acknowledge that there
+should be a separate gem. But the only reference I can find
+refers to onestepback.org's gem repository, which isn't working.
+
+So I built my own. I'll try to keep it up to date with Builder.
+The first three parts of the version number are
+the Builder version; the last part is my revision.
\ No newline at end of file
diff --git a/app/server/vendor/blankslate/blankslate.gemspec b/app/server/vendor/blankslate/blankslate.gemspec
new file mode 100755
index 0000000..20ed989
--- /dev/null
+++ b/app/server/vendor/blankslate/blankslate.gemspec
@@ -0,0 +1,9 @@
+Gem::Specification.new do |s|
+  s.name = 'blankslate'
+  s.version = '2.1.2.3'
+  s.date = '2009-01-03'
+  s.summary = 'BlankSlate extracted from Builder.'
+  s.email = 'dave at 3mix.com'
+  s.authors = ['Jim Weirich', 'David Masover', 'Jack Danger Canty']
+  s.files = ['README', 'lib/blankslate.rb']
+end
diff --git a/app/server/vendor/blankslate/lib/blankslate.rb b/app/server/vendor/blankslate/lib/blankslate.rb
new file mode 100755
index 0000000..b6e9bf7
--- /dev/null
+++ b/app/server/vendor/blankslate/lib/blankslate.rb
@@ -0,0 +1,110 @@
+#!/usr/bin/env ruby
+#--
+# Copyright 2004, 2006 by Jim Weirich (jim at weirichhouse.org).
+# All rights reserved.
+
+# Permission is granted for use, copying, modification, distribution,
+# and distribution of modified versions of this work as long as the
+# above copyright notice is included.
+#++
+
+######################################################################
+# BlankSlate provides an abstract base class with no predefined
+# methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
+# BlankSlate is useful as a base class when writing classes that
+# depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
+#
+class BlankSlate
+  class << self
+    
+    # Hide the method named +name+ in the BlankSlate class.  Don't
+    # hide +instance_eval+ or any method beginning with "__".
+    def hide(name)
+      methods = instance_methods.map(&:to_sym)
+      if methods.include?(name.to_sym) and
+        name !~ /^(__|instance_eval)/
+        @hidden_methods ||= {}
+        @hidden_methods[name.to_sym] = instance_method(name)
+        undef_method name
+      end
+    end
+
+    def find_hidden_method(name)
+      @hidden_methods ||= {}
+      @hidden_methods[name] || superclass.find_hidden_method(name)
+    end
+
+    # Redefine a previously hidden method so that it may be called on a blank
+    # slate object.
+    def reveal(name)
+      hidden_method = find_hidden_method(name)
+      fail "Don't know how to reveal method '#{name}'" unless hidden_method
+      define_method(name, hidden_method)
+    end
+  end
+  
+  instance_methods.each { |m| hide(m) }
+end
+
+######################################################################
+# Since Ruby is very dynamic, methods added to the ancestors of
+# BlankSlate <em>after BlankSlate is defined</em> will show up in the
+# list of available BlankSlate methods.  We handle this by defining a
+# hook in the Object and Kernel classes that will hide any method
+# defined after BlankSlate has been loaded.
+#
+module Kernel
+  class << self
+    alias_method :blank_slate_method_added, :method_added
+
+    # Detect method additions to Kernel and remove them in the
+    # BlankSlate class.
+    def method_added(name)
+      result = blank_slate_method_added(name)
+      return result if self != Kernel
+      BlankSlate.hide(name)
+      result
+    end
+  end
+end
+
+######################################################################
+# Same as above, except in Object.
+#
+class Object
+  class << self
+    alias_method :blank_slate_method_added, :method_added
+
+    # Detect method additions to Object and remove them in the
+    # BlankSlate class.
+    def method_added(name)
+      result = blank_slate_method_added(name)
+      return result if self != Object
+      BlankSlate.hide(name)
+      result
+    end
+
+    def find_hidden_method(name)
+      nil
+    end
+  end
+end
+
+######################################################################
+# Also, modules included into Object need to be scanned and have their
+# instance methods removed from blank slate.  In theory, modules
+# included into Kernel would have to be removed as well, but a
+# "feature" of Ruby prevents late includes into modules from being
+# exposed in the first place.
+#
+class Module
+  alias blankslate_original_append_features append_features
+  def append_features(mod)
+    result = blankslate_original_append_features(mod)
+    return result if mod != Object
+    instance_methods.each do |name|
+      BlankSlate.hide(name)
+    end
+    result
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/blankslate/spec/blankslate_spec.rb b/app/server/vendor/blankslate/spec/blankslate_spec.rb
new file mode 100755
index 0000000..9526445
--- /dev/null
+++ b/app/server/vendor/blankslate/spec/blankslate_spec.rb
@@ -0,0 +1,38 @@
+require 'spec_helper'
+
+describe BlankSlate do
+  let(:blank_slate) { BlankSlate.new }
+  
+  def call(obj, meth, *args)
+    BlankSlate.find_hidden_method(meth).bind(obj).call(*args)
+  end
+  
+  describe "cleanliness" do
+    it "should not have many methods" do
+      BlankSlate.instance_methods.
+        map(&:to_s).sort.
+        should == ["__id__", "__send__", "instance_eval"]
+    end 
+  end
+  
+  context "when methods are added to Object" do
+    after(:each) { 
+      class Object
+        undef :foo
+      end
+    }
+
+    it "should still be blank" do
+      class Object 
+        def foo
+        end
+      end
+      Object.new.foo
+      
+      lambda {
+        BlankSlate.new.foo
+      }.should raise_error(NoMethodError)
+    end 
+    
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/blankslate/spec/spec_helper.rb b/app/server/vendor/blankslate/spec/spec_helper.rb
new file mode 100755
index 0000000..f2b029d
--- /dev/null
+++ b/app/server/vendor/blankslate/spec/spec_helper.rb
@@ -0,0 +1,2 @@
+
+require 'blankslate'
\ No newline at end of file
diff --git a/app/server/vendor/did_you_mean-0.10.0/.gitignore b/app/server/vendor/did_you_mean-0.10.0/.gitignore
new file mode 100755
index 0000000..f928b70
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/.gitignore
@@ -0,0 +1,31 @@
+*.gem
+*.rbc
+.bundle
+.config
+.yardoc
+.DS_Store
+Gemfile.lock
+gemfiles/*.lock
+InstalledFiles
+_yardoc
+coverage
+doc/
+lib/bundler/man
+pkg
+rdoc
+spec/reports
+test/tmp
+test/version_tmp
+tmp
+log
+
+evaluation/dictionary.yml
+benchmark/results
+
+ext/**/*.o
+ext/**/*.so
+ext/**/Makefile
+
+lib/**/*.so
+
+.travis.yml.osx
diff --git a/app/server/vendor/did_you_mean-0.10.0/.travis.yml b/app/server/vendor/did_you_mean-0.10.0/.travis.yml
new file mode 100755
index 0000000..997cec5
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/.travis.yml
@@ -0,0 +1,29 @@
+language: ruby
+script:   bundle exec rake test
+cache:    bundler
+sudo:     false
+
+before_install:
+  - 'if [[ "$TRAVIS_RUBY_VERSION" =~ "jruby" ]]; then rvm get head && rvm use --install $TRAVIS_RUBY_VERSION; fi'
+
+after_success:
+  - bundle exec rake test:accuracy
+  - bundle exec rake benchmark:memory
+
+rvm:
+  - 1.9.3
+  - 2.0.0
+  - 2.1
+  - 2.2
+  - ruby-head
+  - jruby-1.7.21
+  - jruby-9.0.0.0
+  - jruby-head
+  - rbx-2.4.1
+  - rbx-2.5.8
+
+matrix:
+  allow_failures:
+    - rvm: ruby-head
+    - rvm: jruby-head
+  fast_finish: true
diff --git a/app/server/vendor/did_you_mean-0.10.0/CHANGELOG.md b/app/server/vendor/did_you_mean-0.10.0/CHANGELOG.md
new file mode 100755
index 0000000..9027b63
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/CHANGELOG.md
@@ -0,0 +1,229 @@
+## [v0.9.10](https://github.com/yuki24/did_you_mean/tree/v0.9.10)
+
+_<sup>released on 2015-05-14 03:04:47 UTC</sup>_
+
+#### Bug Fixes
+
+- Fixed a bug where a duplicate "did you mean?" message was appended each time `#to_s` is called ( [@danfinnie](https://github.com/danfinnie), [#51](https://github.com/yuki24/did_you_mean/issues/51 "Duplicate output for constants in separate gem"))
+
+## [v0.9.9](https://github.com/yuki24/did_you_mean/tree/v0.9.9)
+
+_<sup>released on 2015-05-13 03:48:19 UTC</sup>_
+
+#### Small/Internal Changes
+
+- Order word suggestions based on Levenshtein distance ( [@tleish](https://github.com/tleish), [#31](https://github.com/yuki24/did_you_mean/pull/31 "Order word suggestions based on Levenshtein.distance."))
+- Reduce memory allocation by about 40%
+- Speed up Levenshtein distance calculation by about 40%
+- The Java extension has been replaced with a pure JRuby implementation
+
+## [v0.9.8](https://github.com/yuki24/did_you_mean/tree/v0.9.8)
+
+_<sup>released on 2015-04-12 01:55:27 UTC</sup>_
+
+#### Internal Changes
+
+- Speed up Levenshtein by 50% and reduce 97% of memory usage
+
+## [v0.9.7](https://github.com/yuki24/did_you_mean/tree/v0.9.7)
+
+_<sup>released on 2015-04-02 04:20:26 UTC</sup>_
+
+#### Bug Fixes
+
+- Fixed an issue where _did\_you\_mean_ doesn't install on JRuby properly.
+
+## [v0.9.6](https://github.com/yuki24/did_you_mean/tree/v0.9.6)
+
+_<sup>released on 2015-01-24 23:19:27 UTC</sup>_
+
+#### Bug Fixes
+
+- Fixed a bug where did\_you\_mean incorrectly suggests protected methods when it just isn't callable ( [@glittershark](https://github.com/glittershark), [#34](https://github.com/yuki24/did_you_mean/issues/34 "Did\_you\_mean incorrectly called when attempting to call protected/private method"))
+
+## [v0.9.5](https://github.com/yuki24/did_you_mean/tree/v0.9.5)
+
+_<sup>released on 2015-01-07 12:41:23 UTC</sup>_
+
+#### Bug Fixes
+
+- Whitelist `#safe_constantize` method from `ActiveSupport::Inflector` to avoid significant performance slowdown ( [@tleish](https://github.com/tleish), [#19](https://github.com/yuki24/did_you_mean/issues/19 "Significant Slowdown when Using Debugger"), [#20](https://github.com/yuki24/did_you_mean/pull/20 "Whitelisting safe\_constantize (ActiveSupport::Inflector) method"))
+
+## [v0.9.4](https://github.com/yuki24/did_you_mean/tree/v0.9.4)
+
+_<sup>released on 2014-11-19 20:00:00 UTC</sup>_
+
+#### Bug Fixes
+
+- Fixed a bug where no suggestions will be made on JRuby
+
+## [v0.9.3](https://github.com/yuki24/did_you_mean/tree/v0.9.3)
+
+_<sup>released on 2014-11-18 03:50:11 UTC</sup>_
+
+**This version has been yanked from rubygems.org as it doesn't work with jRuby at all. Please upgrade to 0.9.4 or higher as soon as possible.**
+
+#### Internal Changes
+
+- Replaced the crazy C extension with a so much better one (thanks to [@nobu](https://github.com/nobu)!)
+
+## [v0.9.2](https://github.com/yuki24/did_you_mean/tree/v0.9.2)
+
+_<sup>released on 2014-11-17 15:32:33 UTC</sup>_
+
+#### Bug Fixes
+
+- Fixed a bug where did\_you\_mean doesn't compile on Ruby 2.1.2/2.1.5 ( [#16](https://github.com/yuki24/did_you_mean/issues/16 "Gem building failed on Debian 6.0.10 x86\_64"))
+
+## [v0.9.1](https://github.com/yuki24/did_you_mean/tree/v0.9.1)
+
+_<sup>released on 2014-11-16 18:54:24 UTC</sup>_
+
+**This version has been yanked from rubygems.org as it doesn't compile on Ruby 2.1.2 and 2.1.5. Please upgrade to 0.9.4 or higher as soon as possible.**
+
+#### Internal Changes
+
+- Shrink the gem size by removing unneeded ruby header files.
+- Now it forces everyone to upgrade the gem when they upgrade Ruby to a new version. This avoids introducing a bug like [#14](https://github.com/yuki24/did_you_mean/issues/14 "Compatibility with `letter\_opener` gem").
+
+## [v0.9.0](https://github.com/yuki24/did_you_mean/tree/v0.9.0)
+
+_<sup>released on 2014-11-09 01:26:31 UTC</sup>_
+
+#### New Features
+
+- did\_you\_mean now suggests instance variable names if `@` is missing ( [#12](https://github.com/yuki24/did_you_mean/issues/12 "Suggest instance- and class-vars"), [<tt>39d1e2b</tt>](https://github.com/yuki24/did_you_mean/commit/39d1e2bd66d6ff8acbc4dd5da922fc7e5fcefb20))
+
+```ruby
+ at full_name = "Yuki Nishijima"
+first_name, last_name = full_name.split(" ")
+# => NameError: undefined local variable or method `full_name' for main:Object
+#
+#     Did you mean? @full_name
+#
+```
+
+#### Bug Fixes
+
+- Fixed a bug where did\_you\_mean changes some behaviours of Ruby 2.1.3/2.1.4 installed on Max OS X ( [#14](https://github.com/yuki24/did_you_mean/issues/14 "Compatibility with `letter\_opener` gem"), [<tt>44c451f</tt>](https://github.com/yuki24/did_you_mean/commit/44c451f8c38b11763ba28ddf1ceb9696707ccea0), [<tt>9ebde21</tt>](https://github.com/yuki24/did_you_mean/commit/9ebde211e92eac8494e704f627c62fea7fdbee16))
+- Fixed a bug where sometimes `NoMethodError` suggests duplicate method names ( [<tt>9865cc5</tt>](https://github.com/yuki24/did_you_mean/commit/9865cc5a9ce926dd9ad4c20d575b710e5f257a4b))
+
+## [v0.8.0](https://github.com/yuki24/did_you_mean/tree/v0.8.0)
+
+_<sup>released on 2014-10-27 02:03:13 UTC</sup>_
+
+**This version has been yanked from rubygems.org as it has a serious bug with Ruby 2.1.3 and 2.1.4 installed on Max OS X. Please upgrade to 0.9.4 or higher as soon as possible.**
+
+#### New Features
+
+- JRuby support!
+
+#### Bug Fixes
+
+- Fixed a bug where did\_you\_mean unexpectedly disables [better\_errors](https://github.com/charliesome/better_errors)'s REPL
+- Replaced [binding\_of\_caller](https://github.com/banister/binding_of_caller) dependency with [interception](https://github.com/ConradIrwin/interception)
+- Fixed the wrong implementation of Levenshtein algorithm ( [#2](https://github.com/yuki24/did_you_mean/pull/2 "Fix bug of DidYouMean::Levenshtein#min3."), [@fortissimo1997](https://github.com/fortissimo1997))
+
+## [v0.7.0](https://github.com/yuki24/did_you_mean/tree/v0.7.0)
+
+_<sup>released on 2014-09-26 03:37:18 UTC</sup>_
+
+**This version has been yanked from rubygems.org as it has a serious bug with Ruby 2.1.3 and 2.1.4 installed on Max OS X. Please upgrade to 0.9.4 or higher as soon as possible.**
+
+#### New Features
+
+- Added support for Ruby 2.1.3, 2.2.0-preview1 and ruby-head
+- Added support for ActiveRecord 4.2.0.beta1
+- Word searching is now about 40% faster than v0.6.0
+- Removed `text` gem dependency
+- Better output on pry and Rspec
+
+#### Small/Internal Changes
+
+- A lot of internal refactoring
+
+## [v0.6.0](https://github.com/yuki24/did_you_mean/tree/v0.6.0)
+
+_<sup>released on 2014-05-18 00:23:24 UTC</sup>_
+
+**This version has been yanked from rubygems.org as it has a serious bug with Ruby 2.1.3 and 2.1.4 installed on Max OS X. Please upgrade to 0.9.0 as soon as possible.**
+
+#### New Features
+
+- Added basic support for constants. Now you'll see class name suggestions when you misspelled a class names/module names:
+
+```ruby
+> Ocject
+# => NameError: uninitialized constant Ocject
+#
+#     Did you mean? Object
+#
+```
+
+#### Bug Fixes
+
+- Fixed a bug where did\_you\_mean segfaults on Ruby head(2.2.0dev)
+
+## [v0.5.0](https://github.com/yuki24/did_you_mean/tree/v0.5.0)
+
+_<sup>released on 2014-05-10 17:59:54 UTC</sup>_
+
+#### New Features
+
+- Added support for Ruby 2.1.2
+
+## [v0.4.0](https://github.com/yuki24/did_you_mean/tree/v0.4.0)
+
+_<sup>released on 2014-04-20 02:10:31 UTC</sup>_
+
+#### New Features
+
+- did\_you\_mean now suggests a similar attribute name when you misspelled it.
+
+```ruby
+User.new(flrst_name: "wrong flrst name")
+# => ActiveRecord::UnknownAttributeError: unknown attribute: flrst_name
+#
+#     Did you mean? first_name: string
+#
+```
+
+#### Bug Fixes
+
+- Fixed a bug where did\_you\_mean doesn't work with `ActiveRecord::UnknownAttributeError`
+
+## [v0.3.1](https://github.com/yuki24/did_you_mean/tree/v0.3.1)
+
+_<sup>released on 2014-03-20 23:16:20 UTC</sup>_
+
+#### Small/Internal Changes
+
+- Changed output for readability.
+- Better algorithm to find the correct method.
+
+## [v0.3.0](https://github.com/yuki24/did_you_mean/tree/v0.3.0)
+
+_<sup>released on 2014-03-20 23:13:13 UTC</sup>_
+
+#### New Features
+
+- Added support for Ruby 2.1.1 and 2.2.0(head).
+
+## [v0.2.0](https://github.com/yuki24/did_you_mean/tree/v0.2.0)
+
+_<sup>released on 2014-03-20 23:12:13 UTC</sup>_
+
+#### Incompatible Changes
+
+- dropped support for JRuby and Rubbinious.
+
+#### New Features
+
+- did\_you\_mean no longer makes Ruby slow.
+
+## [v0.1.0: First Release](https://github.com/yuki24/did_you_mean/tree/v0.1.0)
+
+_<sup>released on 2014-03-20 23:11:14 UTC</sup>_
+
+- Now you will have "did you mean?" experience in Ruby!
+- but still very experimental since this gem makes Ruby a lot slower.
diff --git a/app/server/vendor/did_you_mean-0.10.0/Gemfile b/app/server/vendor/did_you_mean-0.10.0/Gemfile
new file mode 100755
index 0000000..23bb7da
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/Gemfile
@@ -0,0 +1,15 @@
+source 'https://rubygems.org'
+
+# Specify your gem's dependencies in did_you_mean.gemspec
+gemspec
+
+gem 'benchmark-ips'
+gem 'memory_profiler'
+gem 'jaro_winkler', '~> 1.3.6'
+
+platforms :rbx do
+  gem 'rubysl', '~> 2.0'
+  gem 'rubysl-openssl', '2.2.1'
+  gem 'racc'
+  gem 'rubinius-developer_tools'
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/LICENSE.txt b/app/server/vendor/did_you_mean-0.10.0/LICENSE.txt
new file mode 100755
index 0000000..c5c75b7
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/LICENSE.txt
@@ -0,0 +1,22 @@
+Copyright (c) 2014 Yuki Nishijima
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/did_you_mean-0.10.0/README.md b/app/server/vendor/did_you_mean-0.10.0/README.md
new file mode 100755
index 0000000..98e7ab8
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/README.md
@@ -0,0 +1,99 @@
+# did_you_mean [![Gem Version](https://badge.fury.io/rb/did_you_mean.svg)](https://rubygems.org/gems/did_you_mean) [![Build Status](https://travis-ci.org/yuki24/did_you_mean.svg?branch=master)](https://travis-ci.org/yuki24/did_you_mean)
+
+'Did you mean?' experience in Ruby. No, Really.
+
+**For those who are still using 0.6.0, 0.7.0 and 0.8.0, please upgrade to the latest version (0.9.6) as they have a serious bug with Ruby 2.1.3 and 2.1.4 installed on Mac OS X.**
+
+## Installation
+
+Add this line to your application's Gemfile:
+
+```ruby
+gem 'did_you_mean', group: [:development, :test]
+```
+
+## Examples
+
+### NameError
+
+#### Correcting a Misspelled Method Name
+
+```ruby
+class User
+  attr_accessor :first_name, :last_name
+
+  def to_s
+    "#{f1rst_name} #{last_name}" # f1rst_name ???
+  end
+end
+
+user.to_s
+# => NameError: undefined local variable or method `f1rst_name' for #<User:0x0000000928fad8>
+#
+#     Did you mean? #first_name
+#
+```
+
+#### Correcting a Misspelled Class Name
+
+```ruby
+class Book
+  class TableOfContents
+    # ...
+  end
+end
+
+Book::TableofContents # TableofContents ???
+# => NameError: uninitialized constant Book::TableofContents
+#
+#     Did you mean? Book::TableOfContents
+#
+```
+
+#### Suggesting an instance variable name
+
+```ruby
+ at full_name = "Yuki Nishijima"
+first_name, last_name = full_name.split(" ")
+# => NameError: undefined local variable or method `full_name' for main:Object
+#
+#     Did you mean? @full_name
+#
+```
+
+### NoMethodError
+
+```ruby
+# In a Rails controller:
+params.with_inddiferent_access
+# => NoMethodError: undefined method `with_inddiferent_access' for {}:Hash
+#
+#     Did you mean? #with_indifferent_access
+#
+```
+
+## 'Did You Mean' Experience is Everywhere
+
+_did\_you\_mean_ gem automagically puts method suggestions into the error message. This means you'll have the "Did you mean?" experience almost everywhere:
+
+![Did you mean? on BetterErrors](https://raw.githubusercontent.com/yuki24/did_you_mean/master/doc/did_you_mean_example.png)
+
+## Support
+
+_did\_you\_mean_ gem supports the following implementations:
+
+ * MRI 1.9.3, 2.0.0, 2.1.x, 2.2.x and ruby-head
+ * JRuby 1.7.21, 9.0.0.0 and jruby-head
+ * Rubinius 2.4.1 and 2.5.8
+
+## Contributing
+
+1. Fork it (http://github.com/yuki24/did_you_mean/fork)
+2. Create your feature branch (`git checkout -b my-new-feature`)
+3. Commit your changes (`git commit -am 'Add some feature'`)
+4. Push to the branch (`git push origin my-new-feature`)
+5. Create new Pull Request
+
+## License
+
+Copyright (c) 2015 Yuki Nishijima. See MIT-LICENSE for further details.
diff --git a/app/server/vendor/did_you_mean-0.10.0/Rakefile b/app/server/vendor/did_you_mean-0.10.0/Rakefile
new file mode 100755
index 0000000..2db2ed9
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/Rakefile
@@ -0,0 +1,50 @@
+require 'bundler/gem_tasks'
+
+if RUBY_ENGINE == "ruby"
+  require 'rake/extensiontask'
+
+  Rake::ExtensionTask.new 'did_you_mean' do |ext|
+    ext.name    = "method_receiver"
+    ext.lib_dir = "lib/did_you_mean"
+  end
+end
+
+require 'rake/testtask'
+
+Rake::TestTask.new do |task|
+  task.libs << "test"
+  task.pattern = 'test/**/*_test.rb'
+  task.verbose = true
+  # task.warning = true
+end
+
+desc "Run tests"
+task test: [:clobber, :compile] if RUBY_ENGINE == 'ruby'
+task default: :test
+
+namespace :test do
+  namespace :accuracy do
+    desc "Download Wiktionary's Simple English data and save it as a dictionary"
+    task :prepare do
+      sh 'ruby evaluation/dictionary_generator.rb'
+    end
+  end
+
+  desc "Calculate accuracy of the gems' spell checker"
+  task :accuracy do
+    if !File.exist?("evaluation/dictionary.yml")
+      puts 'Generating dictionary for evaluation:'
+      Rake::Task["test:accuracy:prepare"].execute
+      puts "\n"
+    end
+
+    sh 'bundle exec ruby evaluation/calculator.rb'
+  end
+end
+
+namespace :benchmark do
+  desc "Measure memory usage by the did_you_mean gem"
+  task :memory do
+    sh 'bundle exec ruby benchmark/memory_usage.rb'
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/benchmark/jaro_winkler/memory_usage.rb b/app/server/vendor/did_you_mean-0.10.0/benchmark/jaro_winkler/memory_usage.rb
new file mode 100755
index 0000000..9f50199
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/benchmark/jaro_winkler/memory_usage.rb
@@ -0,0 +1,12 @@
+require 'memory_profiler'
+require 'did_you_mean/jaro_winkler'
+
+str1, str2 = "user_signed_in?", "user_logged_in?"
+
+report = MemoryProfiler.report do
+  80.times do
+    DidYouMean::Jaro.distance str1, str2
+  end
+end
+
+report.pretty_print
diff --git a/app/server/vendor/did_you_mean-0.10.0/benchmark/jaro_winkler/speed.rb b/app/server/vendor/did_you_mean-0.10.0/benchmark/jaro_winkler/speed.rb
new file mode 100755
index 0000000..d674944
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/benchmark/jaro_winkler/speed.rb
@@ -0,0 +1,14 @@
+require 'benchmark/ips'
+require 'did_you_mean'
+
+Benchmark.ips do |x|
+  x.report "before" do
+    DidYouMean::Jaro.before_distance "user_signed_in?", "user_logged_in?"
+  end
+
+  x.report "after" do
+    DidYouMean::Jaro.after_distance "user_signed_in?", "user_logged_in?"
+  end
+
+  x.compare!
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/benchmark/levenshtein/memory_usage.rb b/app/server/vendor/did_you_mean-0.10.0/benchmark/levenshtein/memory_usage.rb
new file mode 100755
index 0000000..8980242
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/benchmark/levenshtein/memory_usage.rb
@@ -0,0 +1,12 @@
+require 'memory_profiler'
+require 'did_you_mean/levenshtein'
+
+str1, str2 = "user_signed_in?", "user_logged_in?"
+
+report = MemoryProfiler.report do
+  80.times do
+    DidYouMean::Levenshtein.distance str1, str2
+  end
+end
+
+report.pretty_print
diff --git a/app/server/vendor/did_you_mean-0.10.0/benchmark/levenshtein/speed.rb b/app/server/vendor/did_you_mean-0.10.0/benchmark/levenshtein/speed.rb
new file mode 100755
index 0000000..0217588
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/benchmark/levenshtein/speed.rb
@@ -0,0 +1,17 @@
+require 'benchmark/ips'
+require 'did_you_mean'
+require 'did_you_mean/levenshtein'
+
+STR1, STR2 = "user_signed_in?", "user_logged_in?"
+
+Benchmark.ips do |x|
+  x.report "enumerable" do
+    DidYouMean::Levenshtein.before_distance STR1, STR2
+  end
+
+  x.report "while" do
+    DidYouMean::Levenshtein.after_distance STR1, STR2
+  end
+
+  x.compare!
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/benchmark/memory_usage.rb b/app/server/vendor/did_you_mean-0.10.0/benchmark/memory_usage.rb
new file mode 100755
index 0000000..4ebd1eb
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/benchmark/memory_usage.rb
@@ -0,0 +1,31 @@
+require 'memory_profiler'
+require 'did_you_mean'
+
+# public def foo; end
+# error      = (self.fooo rescue $!)
+# executable = -> { error.to_s }
+
+class DidYouMean::WordCollection
+  include DidYouMean::BaseFinder
+
+  def initialize(words)
+    @words = words
+  end
+
+  def similar_to(input, filter = EMPTY)
+    @suggestions, @input = nil, input
+    suggestions
+  end
+
+  def searches
+    { @input => @words }
+  end
+end if !defined?(DidYouMean::WordCollection)
+
+METHODS    = ''.methods
+INPUT      = 'start_with?'
+collection = DidYouMean::WordCollection.new(METHODS)
+executable = proc { collection.similar_to(INPUT) }
+
+GC.disable
+MemoryProfiler.report { 100.times(&executable) }.pretty_print
diff --git a/app/server/vendor/did_you_mean-0.10.0/did_you_mean.gemspec b/app/server/vendor/did_you_mean-0.10.0/did_you_mean.gemspec
new file mode 100755
index 0000000..5460f53
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/did_you_mean.gemspec
@@ -0,0 +1,36 @@
+# coding: utf-8
+lib = File.expand_path('../lib', __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+require 'did_you_mean/version'
+
+Gem::Specification.new do |spec|
+  spec.name          = "did_you_mean"
+  spec.version       = DidYouMean::VERSION
+  spec.authors       = ["Yuki Nishijima"]
+  spec.email         = ["mail at yukinishijima.net"]
+  spec.summary       = '"Did you mean?" experience in Ruby'
+  spec.description   = '"did you mean?" experience in Ruby: the error message will tell you the right one when you misspelled something.'
+  spec.homepage      = "https://github.com/yuki24/did_you_mean"
+  spec.license       = "MIT"
+
+  spec.files         = `git ls-files`.split($/)
+  spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
+  spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
+  spec.require_paths = ["lib"]
+
+  spec.required_ruby_version = '>= 1.9.3'
+
+  case RUBY_ENGINE
+  when 'ruby'
+    spec.extensions = ["ext/did_you_mean/extconf.rb"]
+  when 'jruby'
+    spec.platform = 'java'
+  end
+
+  spec.add_dependency "interception"
+
+  spec.add_development_dependency "bundler", "~> 1.5"
+  spec.add_development_dependency "rake"
+  spec.add_development_dependency "rake-compiler"
+  spec.add_development_dependency "minitest"
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/evaluation/calculator.rb b/app/server/vendor/did_you_mean-0.10.0/evaluation/calculator.rb
new file mode 100755
index 0000000..16bab8a
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/evaluation/calculator.rb
@@ -0,0 +1,122 @@
+require 'benchmark'
+
+def report(message, &block)
+  time = 1000 * Benchmark.realtime(&block)
+
+  if (time / 1000 / 60) >= 1
+    minutes = (time / 1000 / 60).floor
+    seconds = (time % (60 * 1000)) / 1000
+
+    puts " \e[36m%2dm%.3fs:\e[0m %s" % [minutes, seconds, message]
+  elsif (time / 1000) >= 1
+    seconds = (time % (60 * 1000)) / 1000
+
+    puts " \e[36m%9.3fs:\e[0m %s" % [seconds, message]
+  else
+    puts " \e[36m%8.1fms:\e[0m %s" % [time, message]
+  end
+
+  time
+end
+
+puts "\n"
+
+report "loading program" do
+  require 'yaml'
+  require 'set'
+  require 'did_you_mean'
+
+  begin
+    require 'jaro_winkler'
+    DidYouMean::JaroWinkler.module_eval do
+      module_function
+      def distance(str1, str2)
+        ::JaroWinkler.distance(str1, str2)
+      end if RUBY_ENGINE != 'jruby'
+    end
+  rescue LoadError, NameError
+  end
+
+  class DidYouMean::WordCollection
+    include DidYouMean::BaseFinder
+
+    def initialize(words)
+      @words = words
+    end
+
+    def similar_to(input, filter = EMPTY)
+      @suggestions, @input = nil, input
+      suggestions
+    end
+
+    def searches
+      { @input => @words }
+    end
+
+    private
+    def normalize(str); str; end
+  end if !defined?(DidYouMean::WordCollection)
+end
+
+report "loading dictionary" do
+  yaml = open("evaluation/dictionary.yml").read
+  yaml = YAML.load(yaml).map{|word| word.downcase.tr(" ".freeze, "_".freeze) }
+
+  DICTIONARY = Set.new(yaml)
+end
+
+report "loading corrent/incorrect words" do
+  COLLECTION      = DidYouMean::WordCollection.new(DICTIONARY)
+  INCORRECT_WORDS = YAML.load(open("evaluation/incorrect_words.yaml").read)
+end
+
+total_count         = 0
+correct_count       = 0
+words_not_corrected = []
+filename            = "log/words_not_corrected_#{Time.now.to_i}.yml"
+
+puts "
+ Total number of test data: #{INCORRECT_WORDS.size}
+      did_you_mean version: #{DidYouMean::VERSION}
+
+"
+
+report "calculating accuracy" do
+  index = 0
+  INCORRECT_WORDS.each do |correct, incorrect|
+    if DICTIONARY.include?(correct)
+      total_count += 1
+
+      corrections = COLLECTION.similar_to(incorrect)
+      if corrections.first == correct
+        correct_count += 1
+      else
+        words_not_corrected << {
+          correct         => incorrect,
+          'result'.freeze => corrections
+        }
+      end
+    end
+
+    index += 1
+    puts "processed #{index} items" if index % 100 == 0
+  end
+
+  puts "\n"
+end
+
+puts "
+Evaulation result
+
+  Total count  : #{total_count}
+  Correct count: #{correct_count}
+  Accuracy     : #{correct_count.to_f / total_count}
+
+"
+
+Dir.mkdir('log') unless File.exist?('log')
+File.open(filename, 'w') do |file|
+  file.write(words_not_corrected.to_yaml)
+end
+
+puts "Incorrect suggestions were logged to #{filename}."
diff --git a/app/server/vendor/did_you_mean-0.10.0/evaluation/dictionary_generator.rb b/app/server/vendor/did_you_mean-0.10.0/evaluation/dictionary_generator.rb
new file mode 100755
index 0000000..20ec7e2
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/evaluation/dictionary_generator.rb
@@ -0,0 +1,36 @@
+require 'open-uri'
+require 'cgi'
+require 'json'
+
+per_page = 500
+base_url = "https://simple.wiktionary.org/w/api.php?action=query&aplimit=#{per_page}&list=allpages&format=json"
+filename = "evaluation/dictionary.yml"
+count    = nil
+apfrom   = ""
+num      = 0
+titles   = []
+
+begin
+  url = base_url + "&apfrom=#{apfrom}"
+
+  puts "downloading page %2d: #{url}" % num
+
+  body   = open(url).read
+  json   = JSON.load(body)
+  count  = json["query"]["allpages"].size
+  apfrom = CGI.escape(json["query"]["allpages"].last['title']) if count > 0
+
+  titles += json["query"]["allpages"].map {|hash| hash["title"] }
+  num    += 1
+end while count == per_page
+
+require 'yaml'
+
+File.open(filename, 'w') do |file|
+  file.write(titles.uniq.to_yaml)
+end
+
+puts "
+Number of titles: #{titles.uniq.size}
+Dictionary saved: #{filename}
+"
diff --git a/app/server/vendor/did_you_mean-0.10.0/evaluation/incorrect_words.yaml b/app/server/vendor/did_you_mean-0.10.0/evaluation/incorrect_words.yaml
new file mode 100755
index 0000000..e9e1b91
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/evaluation/incorrect_words.yaml
@@ -0,0 +1,1159 @@
+# This data is based on Birkbeck Spelling Error Corpus: http://ota.ox.ac.uk/headers/0643.xml
+# More specifically, this is a yaml version of the data in FAWTHROP1DAT.643 and FAWTHROP1DAT.643.
+---
+abattoir: abbatoir
+abhorrence: abhorence
+absence: absense
+absorbent: absorbant
+absorption: absorbtion
+accede: acceed
+accelerate: acellerate
+accessible: accesible
+accidentally: accidently
+accommodate: accomodate
+accommodation: accomodation
+accommodations: accomodations
+accompaniment: accompanimen
+accompanying: acompaning
+accomplice: acomplice
+accrued: acrued
+accumulated: acumulated
+accustom: acustom
+achievement: acheivement
+acknowledgment: acknowledgement
+acquaintance: acquantance
+acquiesce: aquiese
+acquiescence: acquiesence
+acquire: aquire
+actually: actualy
+adaptability: adaptibility
+addition: additon
+address: adress
+adequately: adequattly
+adjacent: ajacent
+adjourned: adjorned
+administration: adminstration
+admissible: admissable
+admitting: admiting
+advantageous: advantageos
+advice: advise
+affidavit: afidavit
+aggravated: agravated
+aghast: agast
+agreeable: agreable
+allotted: alloted
+also: allso
+alumnae: alumni
+alumni: alumnae
+amateur: amatuer
+amiable: aimiable
+ammonia: amonia
+analogous: analagous
+analysis: analsis
+analyze: analize
+angel: angell
+anniversary: anniversery
+announcement: anouncement
+annoyance: anoyance
+answer: anwser
+antarctic: antartic
+any: anye
+anything: anythin
+apollo: appolo
+apology: appology
+apparent: apparant
+appearance: appearence
+appearing: appearin
+appetite: appitite
+appetites: appatites
+appropriate: apropriate
+appropriation: apropriation
+approximate: aproximate
+approximately: aproximatly
+archaeological: archeological
+ascertain: assertain
+asinine: assinine
+asking: askin
+asleep: asleeep
+assassinate: assasinate
+assessment: assesment
+assiduous: assidious
+assistance: assistence
+attorneys: attornies
+authoritative: authorative
+auxiliary: auxillary
+available: availble
+awkward: aukward
+bachelor: batchelor
+balloon: baloon
+banana: bananna
+bankruptcy: bankrupcy
+bargaining: baragining
+battalion: batallion
+beam: beame
+before: befor
+beginning: begining
+believe: belive
+belligerent: beligerant
+beneficent: beneficient
+beneficial: benificial
+bitch: bich
+brake: brakke
+brethren: bretheren
+brief: brif
+britain: britian
+britannia: britania
+brown: broun
+bungalow: bungalo
+buoyancy: bouyancy
+buoyant: bouyant
+buried: burried
+bushel: bushell
+business: busness
+buying: buyin
+cancellation: cancelation
+calling: callin
+cantaloupe: cantaloube
+caribbean: carribean
+catalogues: catologues
+category: catagorey
+cemetery: cemetary
+chauffeur: chauffuer
+chemistry: chemestry
+chimneys: chimnies
+cincinnati: cincinatti
+clever: cleva
+coalesced: coalesed
+coherent: coherant
+coliseum: colosium
+collateral: calateral
+colossal: collosal
+colossus: collosus
+commanded: commaunded
+commission: commision
+commitment: committment
+committee: committe
+communicate: comunicate
+comparative: comparitive
+comparatively: comparitively
+compendium: conpendium
+competent: compitent
+concede: consede
+conceive: concieve
+conceived: concieved
+conditions: condicions
+confectionery: confectionary
+confirmation: confermation
+confusing: confusin
+connoisseurs: connoiseurs
+conscience: concience
+conscientious: conscientous
+consensus: concensus
+considering: consderin
+consistent: consistant
+conspired: conpired
+consumer: comsumer
+contemptible: contempible
+continuous: continous
+controllable: controlable
+controversy: controversey
+conveniently: conviently
+coolly: cooly
+corduroy: corderoy
+correspondence: correspondanc
+corrugated: corrigated
+could: coud
+counting: countin
+countryman: countriman
+craftsman: craftman
+curiosity: curiousity
+curriculum: curicculum
+customary: customery
+cynical: synical
+darling: darlin
+decidedly: dicidely
+deem: deam
+definitely: definatly
+delinquent: delinquint
+delirious: dilirious
+delving: delvin
+denying: denyin
+dependant: dependent
+depreciation: depeciation
+descendant: descendent
+description: desacription
+despair: dispair
+deuce: duece
+develop: develope
+development: developement
+dictionary: dictionery
+dignitary: dignatary
+dilapidated: dilapadated
+diminish: diminsh
+dining: dinning
+diphtheria: diptheria
+disappoint: dissappoint
+disappointment: dissappointment
+disastrous: disasterous
+discipline: disiplin
+discrete: discite
+dispel: dispell
+dissipate: disippate
+divine: devine
+doctor: docter
+doctors: docters
+dormitory: dormatory
+doubt: doupt
+drastically: drasticly
+drawing: drawin
+dreaming: dreamin
+drew: drewe
+dropped: droped
+drunkenness: drunkeness
+duchess: dutchess
+duly: duely
+during: durin
+earnest: ernest
+ecstasy: ecstacy
+effecting: effectinge
+effeminate: affeminate
+effervescent: effervesent
+efficiency: effeciency
+eisenhower: eisenhhower
+eligible: elegable
+eliminate: illiminate
+embarrass: embarass
+embarrassment: embarrasment
+encyclopedia: encylopedia
+endorsement: endorsment
+enemy: emeny
+engineers: egnineers
+enlarged: enlargd
+entertained: enterteyned
+equipped: equipt
+equivalent: equivelant
+esteemed: estimed
+every: evrey
+exaggerate: exagerate
+exaggeration: exageration
+examination: eximination
+examining: examinin
+excellence: excelence
+exercises: excercises
+exhilarating: exhilirating
+exhorted: exorted
+existence: existance
+exorbitant: exhorbitant
+experience: experiance
+explicitly: explisitly
+exquisite: exqusite
+eyeing: eying
+facilitate: facilatate
+fascinating: facinating
+fatiguing: fatiging
+fear: feare
+february: febuary
+fictitious: fictitous
+fielder: fiedler
+fiery: firey
+fighting: fieghting
+filipinos: philipinoes
+filthiness: filthness
+finally: finaly
+flammable: flamable
+flourished: florished
+foreign: forien
+forthright: fortright
+forty: fourty
+fox: foxx
+frescos: frescoes
+friend: freind
+fulfill: fullfil
+fundamental: fundemental
+fundamentally: fundementally
+gardener: gardner
+gauge: guage
+generosity: generousity
+genius: genious
+ghastly: gastly
+gnawing: knawing
+gone: gonne
+government: goverment
+grabbing: grabbin
+grammar: grammer
+gramophone: grammophon
+grandeur: granduer
+grateful: greatful
+grievous: grievious
+grill: grille
+guarantee: gaurantee
+guaranteed: guarenteed
+guardian: guardien
+guttural: gutteral
+hammarskjold: hammerskjold
+hand: hande
+handkerchief: hankerchief
+handsome: hansome
+harass: harrass
+having: haveing
+heartrending: heartrendering
+height: heighth
+heinous: hienous
+hemorrhage: hemorrage
+heyday: heydey
+himself: himselfe
+hindrance: hinderence
+humbly: humly
+hurricane: huricane
+hygiene: hygeine
+identified: indentified
+idiosyncrasy: idiocyncracy
+imagination: imagnation
+imitation: immitation
+immediately: imidatly
+immensely: immensly
+impedance: impedence
+impresario: impressario
+incense: insense
+incessant: incesant
+incidentally: incidently
+incompatibility: incompatability
+inconvenience: inconvience
+incorrigible: incorigible
+incredible: incredable
+indefinite: indefinate
+independence: independance
+indictment: inditement
+indispensable: indispensible
+inevitable: inevitible
+infallible: infalable
+infinite: infinate
+ingratitude: ingratitoode
+innocuous: inocuous
+inoculate: innoculate
+insistence: insistance
+instantaneous: instantanous
+instead: insted
+intercede: intersede
+interfered: interferred
+interference: intereference
+interrupted: interupted
+invariably: invarably
+irrelevant: irrelavent
+irreparable: irrepairable
+irresistible: irristible
+itemized: itimized
+jackknife: jacknife
+jaguar: jagaur
+japanese: japaneze
+jaundice: jaundise
+jealousy: jelousy
+jeopardize: jeprodise
+judgment: judgement
+kaleidoscope: kaliedoscope
+kapok: kapock
+khaki: kahki
+kimono: kimona
+kindergarten: kindergarden
+kitchen: kitchin
+knickknacks: knicknacks
+labeled: labelled
+laboratory: labratory
+language: langauge
+leeway: leaway
+leisure: liesure
+leveled: levelled
+library: libray
+license: lisence
+lieutenant: leutenant
+linoleum: linolium
+liquefied: liquified
+liquefy: liquify
+livelihood: livelyhood
+lodestone: loadstone
+lodgment: lodgement
+lonely: lonley
+magnificent: magnigicient
+maintenance: maintainance
+mammoth: mamoth
+management: managment
+maneuver: manuveur
+manufactories: manufacturies
+masterpiece: masterpice
+material: materiel
+mathematics: mathmatics
+mattress: mattres
+maudlin: mauldin
+meant: ment
+medicine: medecine
+meeting: meetin
+mercenary: mercanery
+merchandise: merchandize
+merchantmen: merchantment
+meteorological: meterological
+metropolitan: metropolitian
+millionaire: millionnaire
+miniature: minature
+miscellaneous: miscelaneous
+mischievous: mischievious
+moccasins: mocassins
+momentous: momentus
+mortgage: morgage
+mortgaged: mortgauged
+murmurs: murmers
+mustnt: musnt
+mutilate: mutalate
+mythical: mithical
+nadir: nadar
+naphtha: naptha
+narrative: narative
+naturally: naturaly
+navigating: navagating
+necessarily: necessarilly
+necessary: nessisary
+niagara: niagra
+nickel: nickle
+niggardly: nigardly
+ninetieth: nintieth
+ninetyninth: nintynineth
+nocturnal: nocternal
+nonsense: nonsence
+notwithstanding: nothwithstanding
+nowadays: nowdays
+obbligato: obliggato
+obdurate: obdirate
+occasion: ocassion
+occasionally: occasionaly
+occurred: occureed
+occurrence: occurence
+octopus: octapus
+odyssey: oddysey
+ominous: omenous
+omission: ommision
+onerous: onirous
+opportunities: oppotunities
+opposition: oposition
+oppressor: oppresser
+optician: optitian
+oratorio: orotario
+orchestra: ochestra
+ordinarily: ordinarilly
+origin: origen
+originally: origionally
+own: owne
+pain: paine
+pamphlet: phamplet
+pamphlets: phamplets
+parallel: parellel
+paralysis: parallysis
+paraphernalia: parephernalia
+parenthesis: parenthasis
+participle: participal
+pastime: pasttime
+pastor: paster
+paternity: paternaty
+pavilion: pavillion
+peasant: peasent
+peculiar: pecular
+penance: pennance
+pendulum: pendelum
+penguins: pengiuns
+peninsula: peninsular
+penitentiary: penitentary
+perceive: percieve
+perforation: preforation
+permissible: permissable
+perseverance: perseverence
+personalty: personality
+perspiration: persperation
+persuade: pursuade
+persuaded: pursuaded
+persuasion: persausion
+pertaining: pertaning
+pervaded: prevaded
+pharaohs: pharoahs
+phase: faze
+phenomenal: phenominal
+phenomenon: phenonenon
+philippines: phillipines
+physician: physican
+pickerel: pickeral
+picnicking: picnicing
+pittsburgh: pittsburg
+plagiarism: plaigarism
+plaque: placque
+playwright: playwrite
+pleasant: plesent
+poetry: poetrie
+poisonous: poisenous
+ponderous: pondorous
+possess: posess
+possession: possesion
+possibilities: possablities
+prairie: prarie
+preceding: preceeding
+precipice: presipice
+preferable: preferrable
+preference: preferance
+preferred: prefered
+prejudice: prejedice
+preparation: preperation
+preserved: perserved
+presumptuous: presumptous
+prevalent: prevelant
+preventive: preventative
+prisoner: prisner
+privilege: priviledge
+probably: probabley
+procedure: proceduer
+professor: proffesor
+proffer: profer
+prominent: prominant
+promontory: promonotory
+pronunciation: pronounciation
+propeller: propellor
+prophecy: prophesy
+provisions: provisons
+pseudonym: pseudynom
+psychological: psycological
+public: publick
+publicly: publically
+pumpkin: pumkin
+pursue: persue
+pursuer: persuer
+pursuit: persuit
+qualified: qualafied
+quandary: quandry
+quantities: quanties
+quarantine: quarrantine
+quarreled: quarelled
+quarter: quater
+questionnaire: questionare
+quiescent: quiscent
+quorum: quorem
+radiant: radient
+radiator: radiater
+raise: raize
+rating: rateing
+really: realy
+rebuttal: rebutal
+receded: receeded
+receipt: reciept
+receipts: reciepts
+receive: recieve
+receiver: reciever
+receptacle: receptacel
+recipient: resipient
+reciprocal: reciprocel
+reckon: recon
+reclamation: reclaimation
+recommend: recomend
+recommendation: recomendation
+recommendations: reccomendations
+recommended: recommend
+recommending: recomending
+recompense: recompence
+redundant: redundent
+reference: refference
+referred: refered
+referring: refering
+refrigerator: refrigerater
+regretted: regreted
+rehabilitate: rehabilatate
+relevant: relevaant
+religious: religous
+remembrance: rememberance
+rendezvous: rendevous
+renegade: renagade
+renown: renoun
+reparation: repairation
+repel: repell
+repetition: repitition
+representatives: representitives
+rescinded: resinded
+reservoir: resevoir
+responsibility: responsiblity
+restaurant: restuarant
+restaurateur: restauranteur
+rhapsody: raphsody
+rheumatism: rhuematism
+rhododendron: rhododrendon
+rhubarb: ruhbarb
+rhythm: rythm
+ridiculous: rediculous
+romantic: romantick
+rummage: rumage
+running: runing
+sabbath: sabath
+sacrament: sacrement
+sacrilegious: sacreligious
+safety: safty
+sagacious: sagatious
+sailor: sailer
+sandwich: sanwich
+sanitary: sanatary
+satisfactory: satisfactary
+scarcity: scarsity
+scissors: sissers
+seize: sieze
+seized: siezed
+self: selfe
+sell: selle
+semesters: semisters
+seminary: seminery
+separate: seporate
+sergeant: sergant
+sheep: sheepe
+shepherd: sheperd
+silhouette: silhuette
+shipping: shippin
+shoulder: shouldda
+shoulders: sholders
+showing: showin
+shrubbery: shrubery
+siege: seige
+significant: significent
+silk: silke
+similar: similiar
+simultaneous: similtanous
+sincerity: sincerety
+slimmest: slimest
+smiling: smilin
+sociable: socable
+social: socal
+solemn: solomn
+sophomore: sophmore
+sorority: sororiety
+sought: saught
+source: sorce
+souvenir: souviner
+sovereignty: sovreignty
+sparsely: sparcely
+spear: speer
+specifically: specificly
+specimen: speciment
+specimens: specimans
+spirituous: spiritous
+sprinkle: sprinkel
+starting: startin
+stationary: stationery
+statue: statu
+stirring: stirrin
+stirrups: stirups
+stomach: stomack
+straining: strainin
+straitjacket: straightjacket
+stratagem: strategem
+strategy: stratagy
+strenuous: strenous
+stretched: streched
+stubbornness: stubborness
+suburban: sububan
+success: sucess
+sufficient: suficient
+suffrage: sufferage
+sugar: suger
+suing: sueing
+superficial: superfical
+superintendent: supertendent
+supersede: supercede
+supplement: suplement
+suppress: supress
+surprise: suprise
+surreptitious: sureptitous
+surrounded: surounded
+swearing: swearinge
+syllables: sylables
+symmetry: symetry
+synonymous: synonomous
+systematically: systemetically
+tacit: tasit
+taking: takin
+technically: technecally
+television: televison
+temperament: temperment
+temporarily: temporarly
+temporary: tempory
+tendency: tendancy
+terrestrial: terestial
+terrors: terrours
+that: thatt
+therefore: therefor
+thief: theaf
+think: thinke
+thinking: thinkin
+thorough: thourough
+thoroughly: throughly
+tobacco: tobbaco
+tobogganing: tobboganing
+tonnage: tonage
+tragedy: tradgedy
+tranquility: tranquillity
+tranquillity: tranquility
+transferable: transferrable
+transferred: transfred
+truculent: trucculent
+truly: truley
+tying: tieing
+tyrannical: tyranical
+undoubtedly: undoubtly
+unequaled: unequalled
+unfortunately: unfortunatly
+university: unversity
+unmistakable: unmistakeable
+unparalleled: unparalelled
+until: untill
+usage: useage
+usually: usualy
+usurious: usurous
+utterance: utterence
+vacancy: vancancy
+vaccination: vacinnation
+vacillate: vaccilate
+various: vairious
+vegetable: vegatable
+vengeance: vengance
+vertical: verticle
+vice: vise
+victuals: vituals
+vilify: villify
+villain: villian
+violence: violance
+violin: vioiln
+visible: visable
+vitamins: vitamines
+voucher: vouture
+wagging: waggin
+waggish: wagish
+wednesday: wensday
+weed: weede
+weight: weigth
+weird: wierd
+whether: wether
+which: whitch
+who: whoe
+withhold: withold
+worshiping: worshipping
+yacht: yaht
+yearned: yerned
+yeoman: yoman
+yield: yeild
+zealous: zelous
+zenith: zeenith
+ability: ablity
+academically: academicly
+accept: acept
+accepted: acepted
+access: acess
+accessibility: accessability
+accessing: accesing
+according: acording
+account: acount
+accounts: acounts
+acquaintances: aquantences
+adaptable: adabtable
+addressable: addresable
+adequate: adiquate
+adjournment: adjurnment
+advise: advice
+again: agiin
+agencies: agences
+aggravating: agravating
+allow: alow
+although: athough
+analyse: analiss
+analysed: analised
+analysing: aalysing
+and: anf
+announcing: anouncing
+annoying: anoying
+annual: anual
+anomalies: anomolies
+apologies: appologies
+apologised: appologised
+appeal: apeal
+appendix: apendix
+applicable: aplicable
+applied: upplied
+applying: applieing
+appointment: appoitment
+appointments: apointments
+appreciated: apreciated
+appreciation: apreciation
+approach: aproach
+approached: aproached
+are: arte
+arguing: aurguing
+arranged: arrainged
+arrangeing: aranging
+arrangement: arrangment
+arrangements: araingements
+articles: articals
+assessing: accesing
+associated: assosiated
+atmosphere: atmospher
+auguments: aurgument
+availability: avaiblity
+base: basse
+benefit: benifit
+benefits: benifits
+between: beetween
+bicycle: bicycal
+bingley: bingly
+bonus: bonas
+build: biuld
+building: biulding
+busy: buisy
+career: carrer
+careers: currers
+categories: catagoris
+centrally: centraly
+certain: cirtain
+challenges: chalenges
+challenge: chalange
+choice: choise
+choices: choises
+choose: chose
+choosing: chosing
+clerical: clearical
+clerk: clerck
+collate: colate
+combine: comibine
+commercial: comersial
+comments: coments
+commit: comit
+committees: commitees
+compare: compair
+compared: comppared
+comparison: comparrison
+completely: completly
+component: componant
+composed: compossed
+conditioning: conditining
+conference: conferance
+consider: concider
+considerable: conciderable
+consist: consisit
+consisting: consisiting
+consists: consisits
+contained: contasined
+containing: contasining
+continually: contually
+continued: contuned
+controlled: controled
+conversely: conversly
+corporate: corparate
+credit: creadit
+criticism: citisum
+currently: curruntly
+data: dsata
+dealt: delt
+decide: descide
+decided: descided
+decides: descides
+decision: descisions
+decisions: descisions
+declarations: declaratrions
+definition: defenition
+definitions: defenitions
+demands: diemands
+dependence: dependance
+described: discribed
+desirable: disiable
+desperately: despratly
+diagrammatically: diagrammatica
+different: diffrent
+difficult: dificult
+difficulty: dificulty
+disaggregate: disaggreagte
+disappointing: dissapoiting
+discretion: discresion
+dissension: desention
+dragged: draged
+earlier: earlyer
+earliest: earlyest
+easier: easer
+easily: easyly
+econometric: economtric
+edition: ediition
+eliminated: elimiated
+embellishing: embelishing
+employed: emploied
+employees: emploies
+employment: empolyment
+encompassing: encompasing
+encourage: encorage
+enormously: enomosly
+entirely: entierly
+equalled: equaled
+erroneous: errounous
+especially: especaily
+essential: esential
+eventually: eventully
+evident: evedent
+exact: exsact
+exactly: exsactly
+examine: examin
+excellent: exerlant
+except: excxept
+excessively: exessively
+executed: executted
+expansion: expanion
+expense: expence
+expensive: expencive
+experiences: experances
+explaining: explaning
+exponentially: exponentualy
+extremely: extreemly
+facilities: facilitys
+fails: failes
+'false': faulse
+familiar: familer
+families: familys
+favourable: faverable
+favourably: favorably
+feeling: fealing
+female: femail
+figure: figuar
+figures: figuars
+financial: finatical
+financially: financialy
+flexible: flexable
+forbidden: forbiden
+forecast: forcast
+fourth: forth
+functionally: functionaly
+functions: functuions
+further: futher
+gaining: ganing
+generated: generataed
+geneva: geniva
+geographically: goegraphicaly
+graphically: graphicaly
+guidelines: guidlines
+handle: handel
+hierarchal: hierachial
+hierarchy: hierchy
+however: howeverr
+humour: humor
+ideally: idealy
+immediate: imediate
+inconceivable: inconcievable
+indeed: indead
+independent: independant
+inefficient: ineffiect
+initial: intital
+input: inut
+inquiries: equiries
+insight: insite
+intelligence: inteligence
+interest: intrest
+interesting: intresting
+interpretation: interpritatio
+interrogating: interogationg
+investigated: investegated
+journalism: journaism
+knowledge: knowlege
+largely: largly
+later: latter
+length: lengh
+level: leval
+levels: levals
+lieu: liew
+literature: litriture
+loans: lones
+locally: localy
+luckily: luckeley
+majority: majorty
+manually: manualy
+many: mony
+mathematically: mathematicaly
+matrix: matriiix
+mean: meen
+means: meens
+minutes: muiuets
+misleading: missleading
+monitoring: monitering
+months: monthes
+moving: moveing
+nationally: nationaly
+nature: natior
+necessitates: nessisitates
+necessity: nessesity
+negligible: negligable
+neither: niether
+night: nite
+normally: normaly
+now: noe
+numbers: numbuers
+obtaining: optaning
+occur: occure
+operations: operatins
+operator: opertor
+operators: oprators
+opinion: oppinion
+opportunity: oppotunity
+ordinary: ordenary
+organization: oranisation
+organized: oranised
+orientated: orentated
+output: oputput
+overall: overal
+paid: payed
+parameters: perametres
+partially: partialy
+particular: particulaur
+particularly: particulary
+patterns: pattarns
+per: pere
+perhaps: perhapse
+permanent: perminant
+permanently: perminantly
+personnel: personel
+pivoting: pivting
+politics: polatics
+position: possition
+possible: possable
+prepared: prepaired
+primarily: pimarily
+prior: piror
+proceeding: proceding
+profession: preffeson
+profit: proffit
+profits: proffits
+progresses: progressess
+progression: progresion
+projects: projeccts
+proportions: proprtions
+provide: provid
+provisionally: provisionaly
+proviso: provisoe
+qualities: quaties
+queries: quies
+reaching: reching
+readjusted: reajusted
+received: recived
+receives: recives
+receiving: reciving
+recently: reciently
+refered: reffered
+regained: regined
+register: rgister
+relatively: relitivly
+repetitive: repetative
+representative: representitiv
+requested: rquested
+required: reequired
+research: reserch
+resolved: resoved
+responsibilities: responsibliti
+responsible: responcible
+resulting: reulting
+retirement: retirment
+routine: rouint
+safeguard: safegaurd
+salaries: salarys
+scheme: scheem
+scrutinized: scrutiniesed
+search: serch
+searching: serching
+secretaries: secutaries
+security: seurity
+seen: seeen
+segment: segemnt
+senior: sienior
+sense: sence
+sensible: sensable
+separated: seperated
+separation: seperation
+session: sesion
+set: et
+sheets: sheertes
+shortened: shortend
+shown: hown
+sign: eign
+simular: similar
+singular: singulaur
+someone: somone
+sources: sorces
+speaking: speeking
+standardizing: stanerdizing
+stopped: stoped
+students: studens
+studying: studing
+subsequent: subsiquent
+subtract: subtrcat
+successful: sucssuful
+successive: sucsesive
+such: shuch
+suffering: suufering
+suggested: sugested
+suggestion: sugestion
+suggests: sugests
+suited: suted
+summarys: sumarys
+supervision: supervison
+supplementary: suplementary
+supplements: suplements
+supposedly: supposidly
+surrounding: serounding
+surroundings: suroundings
+surveys: servays
+surveying: servaying
+system: sysem
+table: tasble
+technique: tecnique
+techniques: tecniques
+the: thw
+their: thier
+there: thear
+thermawear: thermawhere
+these: thess
+they: thay
+thoughts: thorts
+through: throut
+throughout: throuout
+timing: timeing
+titles: tittles
+to: ro
+together: togehter
+totally: totaly
+traditionally: traditionaly
+transactions: trasactions
+transportability: transportibil
+triangular: triangulaur
+umbrella: umberalla
+unavailable: unavailble
+understandable: understadable
+unequalled: unequaled
+unequivocally: unequivocaly
+union: unioun
+unique: uneque
+universally: universaly
+unnecessarily: unessasarily
+unnecessary: unessessay
+unresolved: unresloved
+used: usedf
+useful: usful
+user: uers
+utilized: utalised
+valuable: valuble
+variable: varible
+variant: vairiant
+variety: variatry
+virtually: vertually
+visitor: vistor
+visitors: vistors
+voluntary: volantry
+voting: voteing
+weapons: wepons
+weighted: wagted
+were: where
+when: whn
+whereas: wheras
+widely: widly
+will: wil
+within: withing
+would: whould
+written: writen
+years: yesars
diff --git a/app/server/vendor/did_you_mean-0.10.0/ext/did_you_mean/extconf.rb b/app/server/vendor/did_you_mean-0.10.0/ext/did_you_mean/extconf.rb
new file mode 100755
index 0000000..829e43c
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/ext/did_you_mean/extconf.rb
@@ -0,0 +1,2 @@
+require 'mkmf'
+create_makefile 'did_you_mean/method_receiver'
diff --git a/app/server/vendor/did_you_mean-0.10.0/ext/did_you_mean/method_receiver.c b/app/server/vendor/did_you_mean-0.10.0/ext/did_you_mean/method_receiver.c
new file mode 100755
index 0000000..f177760
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/ext/did_you_mean/method_receiver.c
@@ -0,0 +1,20 @@
+#include <ruby.h>
+
+static const rb_data_type_t *type;
+
+static VALUE
+name_err_receiver(VALUE self)
+{
+  VALUE *ptr, mesg = rb_attr_get(self, rb_intern("mesg"));
+  TypedData_Get_Struct(mesg, VALUE, type, ptr);
+  return ptr[1];
+}
+
+void
+Init_method_receiver()
+{
+  VALUE err_mesg = rb_funcall(rb_cNameErrorMesg, '!', 3, Qnil, Qnil, Qnil);
+  type = RTYPEDDATA(err_mesg)->type;
+
+  rb_define_method(rb_eNameError, "receiver", name_err_receiver, 0);
+}
diff --git a/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean.rb b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean.rb
new file mode 100755
index 0000000..025cb57
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean.rb
@@ -0,0 +1,36 @@
+require "interception"
+
+require "did_you_mean/version"
+require "did_you_mean/core_ext/name_error"
+require "did_you_mean/core_ext/no_method_error"
+require "did_you_mean/finders"
+require "did_you_mean/formatter"
+
+module DidYouMean
+  Interception.listen do |exception, binding|
+    # On IRB/pry console, this event is called twice. In the second event,
+    # we get IRB/pry binding. So it shouldn't override @frame_binding if
+    # it's already defined.
+    if DidYouMean.finders.include?(exception.class.to_s) && !exception.instance_variable_defined?(:@frame_binding)
+      exception.instance_variable_set(:@frame_binding, binding)
+    end
+  end
+
+  def self.finders
+    @@finders ||= Hash.new(NullFinder)
+  end
+
+  finders.merge!("NameError" => NameErrorFinders)
+
+  case RUBY_ENGINE
+  when 'ruby', 'jruby'
+    finders["NoMethodError"] = MethodFinder
+  when 'rbx'
+    finders["NoMethodError"] =
+      if (___ rescue $!).class.to_s == "NameError" # For rbx > 2.5.0
+        MethodFinder
+      else
+        MethodFinder::RubiniusSupport              # For rbx < 2.5.0
+      end
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/core_ext/name_error.rb b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/core_ext/name_error.rb
new file mode 100755
index 0000000..a9856e6
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/core_ext/name_error.rb
@@ -0,0 +1,38 @@
+module DidYouMean
+  module Correctable
+    attr_reader :frame_binding
+
+    IGNORED_CALLERS = [
+      /( |`)missing_name'/,
+      /( |`)safe_constantize'/
+    ].freeze
+    private_constant :IGNORED_CALLERS
+
+    def self.included(klass)
+      klass.class_eval do
+        __to_s__ = klass.instance_method(:to_s)
+        define_method(:original_message){ __to_s__.bind(self).call }
+
+        def to_s
+          msg = original_message.dup
+          bt  = caller.first(6)
+
+          msg << Formatter.new(suggestions).to_s if IGNORED_CALLERS.all? {|ignored| bt.grep(ignored).empty? }
+          msg
+        rescue
+          original_message
+        end
+      end
+    end
+
+    def suggestions
+      finder.suggestions
+    end
+
+    def finder
+      @finder ||= DidYouMean.finders[self.class.to_s].new(self)
+    end
+  end
+end
+
+NameError.send(:include, DidYouMean::Correctable)
diff --git a/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/core_ext/no_method_error.rb b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/core_ext/no_method_error.rb
new file mode 100755
index 0000000..d94e103
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/core_ext/no_method_error.rb
@@ -0,0 +1,46 @@
+case RUBY_ENGINE
+when 'ruby'
+  name_error = begin
+    raise_name_error
+  rescue NameError => e
+    e
+  end
+
+  unless name_error.respond_to?(:receiver)
+    require 'did_you_mean/method_receiver'
+  end
+when 'jruby'
+  NoMethodError.class_eval do
+    def to_s
+      receiver unless defined?(@receiver)
+      super
+    end
+
+    def receiver
+      @receiver ||= begin
+        field = JRuby.reference(__message__).java_class.getDeclaredField("object")
+        field.setAccessible(true)
+        field.get(__message__)
+      rescue
+        nil
+      end
+    end
+
+    private
+
+    if JRUBY_VERSION >= '9.0.0.0'
+      def __message__
+        JRuby.reference(self).getMessage
+      end
+    else
+      def __message__
+        error = JRuby.reference(self)
+        error.java_class.getField("message").get(error)
+      end
+    end
+  end
+
+when 'rbx'
+  require 'did_you_mean/core_ext/rubinius'
+  NoMethodError.class_eval { attr_reader :receiver }
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/core_ext/rubinius.rb b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/core_ext/rubinius.rb
new file mode 100755
index 0000000..fd6953c
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/core_ext/rubinius.rb
@@ -0,0 +1,16 @@
+if defined?(Rubinius)
+  class << Rubinius
+    alias raise_with_no_receiver_capturer raise_exception
+
+    def raise_exception(exc)
+      if exc.is_a?(NoMethodError)
+        bt = Rubinius::VM.backtrace(0, true).detect do |x|
+          x.method.name == :method_missing
+        end
+        exc.instance_variable_set(:@receiver, bt.variables.self) if bt
+      end
+
+      raise_with_no_receiver_capturer(exc)
+    end
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/finders.rb b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/finders.rb
new file mode 100755
index 0000000..a3c9de4
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/finders.rb
@@ -0,0 +1,62 @@
+require "did_you_mean/levenshtein"
+require "did_you_mean/jaro_winkler"
+
+module DidYouMean
+  module BaseFinder
+    AT    = "@".freeze
+    EMPTY = "".freeze
+
+    def suggestions
+      @suggestions ||= searches.flat_map do |input, candidates|
+        input     = normalize(input)
+        threshold = input.length > 3 ? 0.834 : 0.77
+
+        seed = candidates.select {|candidate| JaroWinkler.distance(normalize(candidate), input) >= threshold }
+          .sort_by! {|candidate| JaroWinkler.distance(candidate.to_s, input) }
+          .reverse!
+
+        # Correct mistypes
+        threshold   = (input.length * 0.25).ceil
+        corrections = seed.select {|c| Levenshtein.distance(normalize(c), input) <= threshold }
+
+        # Correct misspells
+        if corrections.empty?
+          corrections = seed.select do |candidate|
+            candidate = normalize(candidate)
+            length    = input.length < candidate.length ? input.length : candidate.length
+
+            Levenshtein.distance(candidate, input) < length
+          end.first(1)
+        end
+
+        corrections
+      end
+    end
+
+    def searches
+      raise NotImplementedError
+    end
+
+    private
+
+    def normalize(str_or_symbol) #:nodoc:
+      str = if str_or_symbol.is_a?(String)
+              str_or_symbol.dup
+            else
+              str_or_symbol.to_s
+            end
+
+      str.downcase!
+      str.tr!(AT, EMPTY)
+      str
+    end
+  end
+
+  class NullFinder
+    def initialize(*);  end
+    def suggestions; [] end
+  end
+end
+
+require 'did_you_mean/finders/name_error_finders'
+require 'did_you_mean/finders/method_finder'
diff --git a/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/finders/method_finder.rb b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/finders/method_finder.rb
new file mode 100755
index 0000000..a0dc368
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/finders/method_finder.rb
@@ -0,0 +1,62 @@
+module DidYouMean
+  class MethodFinder
+    include BaseFinder
+    attr_reader :method_name, :receiver
+
+    def initialize(exception)
+      @method_name = exception.name
+      @receiver    = exception.receiver
+      @binding     = exception.frame_binding
+      @location    = exception.backtrace.first
+      @ivar_names  = NameFinder.new(exception).ivar_names
+    end
+
+    def searches
+      {
+        method_name        => method_names,
+        receiver_name.to_s => @ivar_names
+      }
+    end
+
+    def method_names
+      method_names = receiver.methods + receiver.singleton_methods
+      method_names += receiver.private_methods if receiver.equal?(@binding.eval("self"))
+      method_names.delete(method_name)
+      method_names.uniq!
+      method_names
+    end
+
+    def receiver_name
+      return unless @receiver.nil?
+
+      abs_path, lineno, label =
+        /(.*):(.*):in `(.*)'/ =~ @location && [$1, $2.to_i, $3]
+
+      line =
+        case abs_path
+        when "(irb)"
+          Readline::HISTORY.to_a.last
+        when "(pry)"
+          ::Pry.history.to_a.last
+        else
+          File.open(abs_path) do |file|
+            file.detect { file.lineno == lineno }
+          end if File.exist?(abs_path)
+        end
+
+      /@(\w+)*\.#{@method_name}/ =~ line.to_s && $1
+    end
+  end
+
+  if RUBY_ENGINE == 'rbx'
+    module MethodFinder::RubiniusSupport
+      def self.new(exception)
+        if exception.receiver === exception.frame_binding.eval("self")
+          NameErrorFinders.new(exception)
+        else
+          MethodFinder.new(exception)
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/finders/name_error_finders.rb b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/finders/name_error_finders.rb
new file mode 100755
index 0000000..e83e029
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/finders/name_error_finders.rb
@@ -0,0 +1,21 @@
+module DidYouMean
+  module NameErrorFinders
+    def self.included(*)
+      raise "Do not include this module since it overrides Class.new method."
+    end
+
+    def self.new(exception)
+      case exception.original_message
+      when /uninitialized constant/
+        ClassFinder
+      when /undefined local variable or method/, /undefined method/, /uninitialized class variable/
+        NameFinder
+      else
+        NullFinder
+      end.new(exception)
+    end
+  end
+end
+
+require 'did_you_mean/finders/name_error_finders/name_finder'
+require 'did_you_mean/finders/name_error_finders/class_finder'
diff --git a/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/finders/name_error_finders/class_finder.rb b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/finders/name_error_finders/class_finder.rb
new file mode 100755
index 0000000..a20cde7
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/finders/name_error_finders/class_finder.rb
@@ -0,0 +1,77 @@
+require 'delegate'
+
+module DidYouMean
+  class ClassFinder
+    include BaseFinder
+    attr_reader :class_name, :original_message
+
+    def initialize(exception)
+      @class_name, @original_message = exception.name, exception.original_message
+    end
+
+    def searches
+      {name_from_message => class_names}
+    end
+
+    def class_names
+      scopes.flat_map do |scope|
+        scope.constants.map do |c|
+          ClassName.new(c, scope == Object ? EMPTY : "#{scope}::")
+        end
+      end
+    end
+
+    if RUBY_ENGINE == 'jruby'
+      # Always use the original error message to retrieve the user
+      # input since JRuby 1.7 behaves differently from MRI/Rubinius.
+      #
+      #   class Name; end
+      #   error = (Name::DoesNotExist rescue $!)
+      #
+      #   # on MRI/Rubinius
+      #   error.name #=> :DoesNotExist
+      #
+      #   # on JRuby <= 1.7
+      #   error.name #=> :'Name::DoesNotExist'
+      #
+      def name_from_message
+        /([A-Z]\w*$)/.match(original_message)[0]
+      end
+    else
+      def name_from_message
+        class_name || /([A-Z]\w*$)/.match(original_message)[0]
+      end
+    end
+
+    def suggestions
+      super.map(&:full_name)
+    end
+
+    def scopes
+      @scopes ||= scope_base.inject([Object]) do |_scopes, scope|
+        _scopes << _scopes.last.const_get(scope)
+      end
+    end
+
+    private
+
+    def scope_base
+      @scope_base ||= (/(([A-Z]\w*::)*)([A-Z]\w*)$/ =~ original_message ? $1 : "").split("::")
+    end
+
+    class ClassName < SimpleDelegator
+      attr :namespace
+
+      def initialize(name, namespace = '')
+        super(name)
+        @namespace = namespace
+      end
+
+      def full_name
+        self.class.new("#{namespace}#{__getobj__}")
+      end
+    end
+
+    private_constant :ClassName
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/finders/name_error_finders/name_finder.rb b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/finders/name_error_finders/name_finder.rb
new file mode 100755
index 0000000..9b94ad1
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/finders/name_error_finders/name_finder.rb
@@ -0,0 +1,18 @@
+module DidYouMean
+  class NameFinder
+    include BaseFinder
+    attr_reader :name, :method_names, :lvar_names, :ivar_names, :cvar_names
+
+    def initialize(exception)
+      @name         = exception.name.to_s.tr(AT, EMPTY)
+      @lvar_names   = exception.frame_binding.eval("local_variables")
+      @method_names = exception.frame_binding.eval("methods + private_methods")
+      @cvar_names   = exception.frame_binding.eval("self.class.class_variables")
+      @ivar_names   = exception.frame_binding.eval("instance_variables")
+    end
+
+    def searches
+      {name => (lvar_names + method_names + ivar_names + cvar_names)}
+    end
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/formatter.rb b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/formatter.rb
new file mode 100755
index 0000000..450fd5e
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/formatter.rb
@@ -0,0 +1,20 @@
+module DidYouMean
+  class Formatter
+    def initialize(suggestions = [])
+      @suggestions = suggestions
+    end
+
+    def to_s
+      return "" if @suggestions.empty?
+
+      output = "\n\n"
+      output << "    Did you mean? #{format(@suggestions.first)}\n"
+      output << @suggestions.drop(1).map{|word| "#{' ' * 18}#{format(word)}\n" }.join
+      output << " " # for rspec
+    end
+
+    def format(name)
+      name
+    end
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/jaro_winkler.rb b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/jaro_winkler.rb
new file mode 100755
index 0000000..edf2773
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/jaro_winkler.rb
@@ -0,0 +1,87 @@
+module DidYouMean
+  module Jaro
+    module_function
+
+    def distance(str1, str2)
+      str1, str2 = str2, str1 if str1.length > str2.length
+      length1, length2 = str1.length, str2.length
+
+      m          = 0.0
+      t          = 0.0
+      range      = (length2 / 2).floor - 1
+      flags1     = 0
+      flags2     = 0
+
+      # Avoid duplicating enumerable objects
+      # Also, call #to_a since #codepoints returns an Enumerator on Ruby 1.9.3.
+      str1_codepoints = str1.codepoints.to_a
+      str2_codepoints = str2.codepoints.to_a
+
+      i = 0
+      while i < length1
+        last = i + range
+        j    = (i >= range) ? i - range : 0
+
+        while j <= last
+          if flags2[j] == 0 && str1_codepoints[i] == str2_codepoints[j]
+            flags2 |= (1 << j)
+            flags1 |= (1 << i)
+            m += 1
+            break
+          end
+
+          j += 1
+        end
+
+        i += 1
+      end
+
+      k = i = 0
+      while i < length1
+        if flags1[i] != 0
+          j = index = k
+
+          k = while j < length2
+            index = j
+            break(j + 1) if flags2[j] != 0
+
+            j += 1
+          end
+
+          t += 1 if str1_codepoints[i] != str2_codepoints[index]
+        end
+
+        i += 1
+      end
+      t = (t / 2).floor
+
+      m == 0 ? 0 : (m / length1 + m / length2 + (m - t) / m) / 3
+    end
+  end
+
+  module JaroWinkler
+    WEIGHT    = 0.1
+    THRESHOLD = 0.7
+
+    module_function
+
+    def distance(str1, str2)
+      jaro_distance = Jaro.distance(str1, str2)
+
+      if jaro_distance > THRESHOLD
+        codepoints2  = str2.codepoints.to_a
+        prefix_bonus = 0
+
+        i = 0
+        str1.each_codepoint do |char1|
+          char1 == codepoints2[i] && i < 4 ? prefix_bonus += 1 : break
+          i += 1
+        end
+
+        jaro_distance + (prefix_bonus * WEIGHT * (1 - jaro_distance))
+      else
+        jaro_distance
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/levenshtein.rb b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/levenshtein.rb
new file mode 100755
index 0000000..c3f3637
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/levenshtein.rb
@@ -0,0 +1,55 @@
+module DidYouMean
+  module Levenshtein # :nodoc:
+    # This code is based directly on the Text gem implementation
+    # Returns a value representing the "cost" of transforming str1 into str2
+    def distance(str1, str2)
+      n = str1.length
+      m = str2.length
+      return m if n.zero?
+      return n if m.zero?
+
+      d = (0..m).to_a
+      x = nil
+
+      # to avoid duplicating an enumerable object, create it outside of the loop
+      str2_codepoints = str2.codepoints.to_a
+
+      str1.each_codepoint.with_index(1) do |char1, i|
+        j = 0
+        while j < m
+          cost = (char1 == str2_codepoints[j]) ? 0 : 1
+          x = min3(
+            d[j+1] + 1, # insertion
+            i + 1,      # deletion
+            d[j] + cost # substitution
+          )
+          d[j] = i
+          i = x
+
+          j += 1
+        end
+        d[m] = x
+      end
+
+      x
+    end
+    module_function :distance
+
+    private
+
+    # detects the minimum value out of three arguments. This method is
+    # faster than `[a, b, c].min` and puts less GC pressure.
+    # See https://github.com/yuki24/did_you_mean/pull/1 for a performance
+    # benchmark.
+    def min3(a, b, c)
+      if a < b && a < c
+        a
+      elsif b < c
+        b
+      else
+        c
+      end
+    end
+    module_function :min3
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/test_helper.rb b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/test_helper.rb
new file mode 100755
index 0000000..32b60c6
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/test_helper.rb
@@ -0,0 +1,7 @@
+module DidYouMean
+  module TestHelper
+    def assert_suggestion(expected, array)
+      assert_equal [expected], array, "Expected #{array.inspect} to only include #{expected.inspect}"
+    end
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/version.rb b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/version.rb
new file mode 100755
index 0000000..c659880
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/lib/did_you_mean/version.rb
@@ -0,0 +1,3 @@
+module DidYouMean
+  VERSION = "0.10.0"
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/test/core_ext/name_error_extension_test.rb b/app/server/vendor/did_you_mean-0.10.0/test/core_ext/name_error_extension_test.rb
new file mode 100755
index 0000000..55f0769
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/test/core_ext/name_error_extension_test.rb
@@ -0,0 +1,74 @@
+require 'test_helper'
+
+class NameErrorExtensionTest < Minitest::Test
+  class TestFinder
+    def initialize(*); end
+    def suggestions; ["Y U SO SLOW?"]; end
+  end
+
+  def setup
+    @org = DidYouMean.finders[NAME_ERROR.to_s]
+    DidYouMean.finders[NAME_ERROR.to_s] = TestFinder
+
+    @error = assert_raises(NAME_ERROR){ doesnt_exist }
+  end
+
+  def teardown
+    DidYouMean.finders[NAME_ERROR.to_s] = @org
+  end
+
+  def test_message_provides_original_message
+    skip if RUBY_ENGINE == 'rbx'
+
+    assert_match "undefined local variable or method", @error.to_s
+  end
+
+  def test_message
+    assert_match "Did you mean? Y U SO SLOW?", @error.to_s
+    assert_match "Did you mean? Y U SO SLOW?", @error.message
+  end
+
+  def test_to_s_does_not_make_disruptive_changes_to_error_message
+    error = assert_raises(NameError) do
+      raise NameError, "uninitialized constant Object".freeze
+    end
+
+    assert_equal 1, error.to_s.scan("Did you mean?").count
+  end
+end
+
+class IgnoreCallersTest < Minitest::Test
+  class Boomer
+    def initialize(*)
+      raise Exception, "finder was created when it shouldn't!"
+    end
+  end
+
+  def setup
+    @org = DidYouMean.finders[NAME_ERROR.to_s]
+    DidYouMean.finders[NAME_ERROR.to_s] = Boomer
+
+    @error = assert_raises(NAME_ERROR){ doesnt_exist }
+  end
+
+  def teardown
+    DidYouMean.finders[NAME_ERROR.to_s] = @org
+  end
+
+  def test_ignore_missing_name
+    assert_nothing_raised { missing_name }
+  end
+
+  def test_ignore_safe_constantize
+    assert_nothing_raised { safe_constantize }
+  end
+
+  private
+
+  def safe_constantize; @error.message end
+  def missing_name;     @error.message end
+
+  def assert_nothing_raised
+    yield
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/test/core_ext/no_method_error_extension_test.rb b/app/server/vendor/did_you_mean-0.10.0/test/core_ext/no_method_error_extension_test.rb
new file mode 100755
index 0000000..e23cb39
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/test/core_ext/no_method_error_extension_test.rb
@@ -0,0 +1,38 @@
+require 'test_helper'
+
+class NoMethodErrorExtensionTest < Minitest::Test
+  def test_receiver_with_string
+    receiver = "receiver"
+    error = assert_raises(NoMethodError) do
+      receiver.doesnt_exist
+    end
+
+    assert_same receiver, error.receiver
+  end
+
+  def test_receiver_with_class
+    error = assert_raises(NoMethodError) do
+      Object.doesnt_exist
+    end
+
+    assert_same Object, error.receiver
+  end
+
+  def test_receiver_with_class_after_calling_to_s
+    error = assert_raises(NoMethodError) do
+      Object.doesnt_exist
+    end
+
+    error.to_s
+    assert_same Object, error.receiver
+  end
+
+  def test_receiver_with_class_after_calling_message
+    error = assert_raises(NoMethodError) do
+      Object.doesnt_exist
+    end
+
+    error.message
+    assert_same Object, error.receiver
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/test/correctable/class_name_test.rb b/app/server/vendor/did_you_mean-0.10.0/test/correctable/class_name_test.rb
new file mode 100755
index 0000000..9457e27
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/test/correctable/class_name_test.rb
@@ -0,0 +1,65 @@
+require 'test_helper'
+
+module ACRONYM
+end
+
+class Project
+  def self.bo0k
+    Bo0k
+  end
+end
+
+class Book
+  class TableOfContents; end
+
+  def tableof_contents
+    TableofContents
+  end
+
+  class Page
+    def tableof_contents
+      TableofContents
+    end
+
+    def self.tableof_contents
+      TableofContents
+    end
+  end
+end
+
+class ClassNameTest < Minitest::Test
+  def test_suggestions
+    error = assert_raises(NameError) { ::Bo0k }
+    assert_suggestion "Book", error.suggestions
+  end
+
+  def test_suggestions_include_case_specific_class_name
+    error = assert_raises(NameError) { ::Acronym }
+    assert_suggestion "ACRONYM", error.suggestions
+  end
+
+  def test_suggestions_include_top_level_class_name
+    error = assert_raises(NameError) { Project.bo0k }
+    assert_suggestion "Book", error.suggestions
+  end
+
+  def test_names_in_suggestions_have_namespaces
+    error = assert_raises(NameError) { ::Book::TableofContents }
+    assert_suggestion "Book::TableOfContents", error.suggestions
+  end
+
+  def test_suggestions_searches_for_names_in_upper_level_scopes
+    error = assert_raises(NameError) { Book::Page.tableof_contents }
+    assert_suggestion "Book::TableOfContents", error.suggestions
+  end
+
+  def test_suggestions_should_work_from_within_instance_method
+    error = assert_raises(NameError) { ::Book.new.tableof_contents }
+    assert_suggestion "Book::TableOfContents", error.suggestions
+  end
+
+  def test_suggestions_should_work_from_within_instance_method_on_nested_class
+    error = assert_raises(NameError) { ::Book::Page.new.tableof_contents }
+    assert_suggestion "Book::TableOfContents", error.suggestions
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/test/correctable/method_name_test.rb b/app/server/vendor/did_you_mean-0.10.0/test/correctable/method_name_test.rb
new file mode 100755
index 0000000..9d85a91
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/test/correctable/method_name_test.rb
@@ -0,0 +1,84 @@
+require 'test_helper'
+
+class MethodNameTest < Minitest::Test
+  class User
+    def friends; end
+    def first_name; end
+    def descendants; end
+    def call_incorrect_private_method
+      raiae NoMethodError
+    end
+
+    protected
+    def the_protected_method; end
+
+    private
+    def friend; end
+    def the_private_method; end
+
+    class << self
+      def load; end
+    end
+  end
+
+  module UserModule
+    def from_module; end
+  end
+
+  def setup
+    @user = User.new.extend(UserModule)
+  end
+
+  def test_suggestions_include_instance_method
+    error = assert_raises(NoMethodError){ @user.flrst_name }
+
+    assert_suggestion :first_name, error.suggestions
+    assert_match "Did you mean? first_name",  error.to_s
+  end
+
+  def test_suggestions_include_private_method
+    error = assert_raises(NoMethodError){ @user.friend }
+
+    assert_suggestion :friends, error.suggestions
+    assert_match "Did you mean? friends", error.to_s
+  end
+
+  def test_suggestions_include_method_from_module
+    error = assert_raises(NoMethodError){ @user.fr0m_module }
+
+    assert_suggestion :from_module, error.suggestions
+    assert_match "Did you mean? from_module", error.to_s
+  end
+
+  def test_suggestions_include_class_method
+    error = assert_raises(NoMethodError){ User.l0ad }
+
+    assert_suggestion :load, error.suggestions
+    assert_match "Did you mean? load", error.to_s
+  end
+
+  def test_private_methods_should_not_be_suggested
+    error = assert_raises(NoMethodError){ User.new.the_protected_method }
+    refute_includes error.suggestions, :the_protected_method
+
+    error = assert_raises(NoMethodError){ User.new.the_private_method }
+    refute_includes error.suggestions, :the_private_method
+  end
+
+  def test_suggestions_when_private_method_is_called_with_args
+    error = assert_raises(NoMethodError){ @user.call_incorrect_private_method }
+
+    assert_suggestion :raise, error.suggestions
+    assert_match "Did you mean? raise", error.to_s
+  end
+
+  def test_corrects_incorrect_ivar_name
+    skip if RUBY_ENGINE == 'rbx'
+
+    @number = 1
+    error = assert_raises(NoMethodError) { @nubmer.zero? }
+
+    assert_suggestion :@number, error.suggestions
+    assert_match "Did you mean? @number", error.to_s
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/test/correctable/uncorrectable_name_test.rb b/app/server/vendor/did_you_mean-0.10.0/test/correctable/uncorrectable_name_test.rb
new file mode 100755
index 0000000..9183ee8
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/test/correctable/uncorrectable_name_test.rb
@@ -0,0 +1,15 @@
+require 'test_helper'
+
+class UncorrectableNameTest < Minitest::Test
+  class FirstNameError < NameError; end
+
+  def setup
+    @error = assert_raises(FirstNameError) do
+      raise FirstNameError, "Other name error"
+    end
+  end
+
+  def test_message
+    assert_equal "Other name error", @error.message
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/test/correctable/variable_name_test.rb b/app/server/vendor/did_you_mean-0.10.0/test/correctable/variable_name_test.rb
new file mode 100755
index 0000000..021b065
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/test/correctable/variable_name_test.rb
@@ -0,0 +1,79 @@
+require 'test_helper'
+
+class VariableNameTest < Minitest::Test
+  class User
+    def initialize
+      @email_address = 'email_address at address.net'
+    end
+
+    def first_name; end
+    def to_s
+      "#{@first_name} #{@last_name} <#{email_address}>"
+    end
+
+    private
+
+    def cia_codename; "Alexa" end
+  end
+
+  module UserModule
+    def from_module; end
+  end
+
+  def setup
+    @user = User.new.extend(UserModule)
+  end
+
+  def test_suggestions_include_instance_method
+    error = assert_raises(NAME_ERROR) do
+      @user.instance_eval { flrst_name }
+    end
+
+    assert_suggestion :first_name, error.suggestions
+    assert_match "Did you mean? first_name", error.to_s
+  end
+
+  def test_suggestions_include_method_from_module
+    error = assert_raises(NAME_ERROR) do
+      @user.instance_eval { fr0m_module }
+    end
+
+    assert_suggestion :from_module, error.suggestions
+    assert_match "Did you mean? from_module", error.to_s
+  end
+
+  def test_suggestions_include_local_variable_name
+    person  = nil
+    error = (eprson rescue $!) # Do not use @assert_raises here as it changes a scope.
+
+    assert_suggestion :person, error.suggestions
+    assert_match "Did you mean? person", error.to_s
+  end
+
+  def test_suggestions_include_instance_variable_name
+    error = assert_raises(NAME_ERROR){ @user.to_s }
+
+    assert_suggestion :@email_address, error.suggestions
+    assert_match "Did you mean? @email_address", error.to_s
+  end
+
+  def test_suggestions_include_private_method
+    error = assert_raises(NAME_ERROR) do
+      @user.instance_eval { cia_code_name }
+    end
+
+    assert_suggestion :cia_codename,  error.suggestions
+    assert_match "Did you mean? cia_codename",  error.to_s
+  end
+
+  @@does_exist = true
+
+  def test_suggestions_include_class_variable_name
+    skip if RUBY_ENGINE == 'rbx'
+
+    error = assert_raises(NameError){ @@doesnt_exist }
+
+    assert_suggestion :@@does_exist, error.suggestions
+    assert_match "Did you mean? @@does_exist", error.to_s
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/test/edit_distance/jaro_winkler_test.rb b/app/server/vendor/did_you_mean-0.10.0/test/edit_distance/jaro_winkler_test.rb
new file mode 100755
index 0000000..0e9bd42
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/test/edit_distance/jaro_winkler_test.rb
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+require 'test_helper'
+
+class JaroWinklerTest < Minitest::Test
+  def test_jaro_winkler_distance
+    assert_distance 0.9667, 'henka',      'henkan'
+    assert_distance 1.0,    'al',         'al'
+    assert_distance 0.9611, 'martha',     'marhta'
+    assert_distance 0.8324, 'jones',      'johnson'
+    assert_distance 0.9167, 'abcvwxyz',   'zabcvwxy'
+    assert_distance 0.9583, 'abcvwxyz',   'cabvwxyz'
+    assert_distance 0.84,   'dwayne',     'duane'
+    assert_distance 0.8133, 'dixon',      'dicksonx'
+    assert_distance 0.0,    'fvie',       'ten'
+    assert_distance 0.9067, 'does_exist', 'doesnt_exist'
+  end
+
+  def test_jarowinkler_distance_with_utf8_strings
+    assert_distance 0.9818, '變形金剛4:絕跡重生', '變形金剛4: 絕跡重生'
+    assert_distance 0.8222, '連勝文',             '連勝丼'
+    assert_distance 0.8222, '馬英九',             '馬英丸'
+    assert_distance 0.6667, '良い',               'いい'
+  end
+
+  private
+
+  def assert_distance(score, str1, str2)
+    assert_equal score, DidYouMean::JaroWinkler.distance(str1, str2).round(4)
+  end
+end
diff --git a/app/server/vendor/did_you_mean-0.10.0/test/test_helper.rb b/app/server/vendor/did_you_mean-0.10.0/test/test_helper.rb
new file mode 100755
index 0000000..b6b2d2b
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/test/test_helper.rb
@@ -0,0 +1,14 @@
+NAME_ERROR = (___ rescue $!).class
+
+require 'minitest/autorun'
+require 'minitest/unit'
+require 'did_you_mean'
+
+begin
+  MiniTest::Test
+rescue NameError
+  MiniTest::Test = MiniTest::Unit::TestCase
+end
+
+require 'did_you_mean/test_helper'
+MiniTest::Test.send :include, DidYouMean::TestHelper
diff --git a/app/server/vendor/did_you_mean-0.10.0/test/word_collection_test.rb b/app/server/vendor/did_you_mean-0.10.0/test/word_collection_test.rb
new file mode 100755
index 0000000..138a017
--- /dev/null
+++ b/app/server/vendor/did_you_mean-0.10.0/test/word_collection_test.rb
@@ -0,0 +1,90 @@
+require 'test_helper'
+
+class FinderTest < Minitest::Test
+  class WordCollection
+    include DidYouMean::BaseFinder
+
+    def initialize(words)
+      @words = words
+    end
+
+    def similar_to(input, filter = EMPTY)
+      @suggestions, @input = nil, input
+
+      suggestions
+    end
+
+    def searches
+      { @input => @words }
+    end
+  end
+
+  def test_similar_to_corrects_mistypes
+
+    assert_suggestion 'foo',         collection('foo', 'fork')          .similar_to('doo')
+    assert_suggestion 'email',       collection('email', 'fail', 'eval').similar_to('meail')
+    assert_suggestion 'fail',        collection('email', 'fail', 'eval').similar_to('fial')
+    assert_suggestion 'fail',        collection('email', 'fail', 'eval').similar_to('afil')
+    assert_suggestion 'eval',        collection('email', 'fail', 'eval').similar_to('eavl')
+    assert_suggestion 'eval',        collection('email', 'fail', 'eval').similar_to('veal')
+    assert_suggestion 'sub!',        collection('sub', 'gsub', 'sub!')  .similar_to('suv!')
+    assert_suggestion 'sub',         collection('sub', 'gsub', 'sub!')  .similar_to('suv')
+
+    assert_equal %w(gsub! gsub),     collection('sub', 'gsub', 'gsub!').similar_to('gsuv!')
+    assert_equal %w(sub! sub gsub!), collection('sub', 'sub!', 'gsub', 'gsub!').similar_to('ssub!')
+
+    group_methods = %w(groups group_url groups_url group_path)
+    assert_suggestion 'groups', collection(group_methods).similar_to('group')
+
+    group_classes = %w(
+      GroupMembership
+      GroupMembershipPolicy
+      GroupMembershipDecorator
+      GroupMembershipSerializer
+      GroupHelper
+      Group
+      GroupMailer
+      NullGroupMembership
+    )
+
+    #assert_suggestion 'GroupMembership',          collection(group_classes).similar_to('GroupMemberhip')
+    assert_suggestion 'GroupMembershipDecorator', collection(group_classes).similar_to('GroupMemberhipDecorator')
+
+    names = %w(first_name_change first_name_changed? first_name_will_change!)
+    assert_equal names, collection(names).similar_to('first_name_change!')
+
+    assert_empty collection('proc').similar_to 'product_path'
+    assert_empty collection('fork').similar_to 'fooo'
+  end
+
+  def test_similar_to_corrects_misspells
+    assert_suggestion 'descendants',      collection('descendants')     .similar_to('dependents')
+    assert_suggestion 'drag_to',          collection('drag_to')         .similar_to('drag')
+    assert_suggestion 'set_result_count', collection('set_result_count').similar_to('set_result')
+  end
+
+  def test_similar_to_sorts_results_by_simiarity
+    expected = %w(
+      name123456
+      name12345
+      name1234
+      name123
+    )
+
+    actual = WordCollection.new(%w(
+      name12
+      name123
+      name1234
+      name12345
+      name123456
+    )).similar_to("name123456")
+
+    assert_equal expected, actual
+  end
+
+  private
+
+  def collection(*args)
+    WordCollection.new(args.flatten)
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/.gitignore b/app/server/vendor/ffi-1.9.10/.gitignore
new file mode 100755
index 0000000..c1e0bee
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/.gitignore
@@ -0,0 +1,20 @@
+doc/
+bin/
+.yardoc
+*.orig
+nbproject/private
+pkg
+*.orig
+*.rej
+*.patch
+*.diff
+build
+*.so
+*.[oa]
+core
+lib/ffi/types.conf
+lib/ffi_c.bundle
+lib/ffi_c.so
+vendor
+.bundle
+Gemfile.lock
diff --git a/app/server/vendor/ffi-1.9.10/.travis.yml b/app/server/vendor/ffi-1.9.10/.travis.yml
new file mode 100755
index 0000000..9b38679
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/.travis.yml
@@ -0,0 +1,27 @@
+language: ruby
+script: bundle exec rake test
+before_install: gem install bundler
+os:
+  - linux
+  - osx
+rvm:
+  - "1.9.3"
+  - "1.8.7"
+  - "2.0.0"
+  - "2.1"
+  - "2.2"
+  - "ruby-head"
+  - "rbx"
+env:
+  - CC=gcc
+  - CC=clang
+matrix:
+  allow_failures:
+    - os: osx
+      rvm: "2.2"
+    - os: osx
+      rvm: ruby-head
+    - rvm: "rbx"
+    - rvm: "rbx-head"
+    - rvm: "1.8.7"
+    - rvm: "1.9.3"
diff --git a/app/server/vendor/ffi-1.9.10/.yardopts b/app/server/vendor/ffi-1.9.10/.yardopts
new file mode 100755
index 0000000..8ef32b9
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/.yardopts
@@ -0,0 +1,5 @@
+--title "Ruby FFI"
+--charset UTF-8
+--private
+lib/**/*.rb
+ext/**/*.c
\ No newline at end of file
diff --git a/app/server/vendor/ffi-1.9.10/COPYING b/app/server/vendor/ffi-1.9.10/COPYING
new file mode 100755
index 0000000..7622318
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/COPYING
@@ -0,0 +1,49 @@
+Copyright (c) 2008-2013, Ruby FFI project contributors
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the Ruby FFI project nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+libffi, used by this project, is licensed under the MIT license:
+
+libffi - Copyright (c) 1996-2011  Anthony Green, Red Hat, Inc and others.
+See source files for details.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+``Software''), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
diff --git a/app/server/vendor/ffi-1.9.10/Gemfile b/app/server/vendor/ffi-1.9.10/Gemfile
new file mode 100755
index 0000000..328184e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/Gemfile
@@ -0,0 +1,10 @@
+source 'https://rubygems.org'
+
+group :development do
+  gem 'rake', '~> 10.1'
+  gem 'rake-compiler', '~> 0.9.5'
+  gem 'rake-compiler-dock', '~> 0.4.0'
+  gem 'rspec', '~> 3.0'
+  gem 'rubygems-tasks', '~> 0.2.4', :require => 'rubygems/tasks'
+  gem "rubysl", "~> 2.0", :platforms => 'rbx'
+end
diff --git a/app/server/vendor/ffi-1.9.10/LICENSE b/app/server/vendor/ffi-1.9.10/LICENSE
new file mode 100755
index 0000000..ef147e6
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/LICENSE
@@ -0,0 +1,24 @@
+Copyright (c) 2008-2013, Ruby FFI project contributors
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the Ruby FFI project nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/app/server/vendor/ffi-1.9.10/LICENSE.SPECS b/app/server/vendor/ffi-1.9.10/LICENSE.SPECS
new file mode 100755
index 0000000..5c9ffce
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/LICENSE.SPECS
@@ -0,0 +1,22 @@
+Copyright (c) 2008-2012 Ruby-FFI contributors
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/ffi-1.9.10/README.md b/app/server/vendor/ffi-1.9.10/README.md
new file mode 100755
index 0000000..ec4a57f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/README.md
@@ -0,0 +1,109 @@
+# ruby-ffi https://wiki.github.com/ffi/ffi [![Build Status](https://travis-ci.org/ffi/ffi.png?branch=master)](https://travis-ci.org/ffi/ffi)
+
+## Description
+
+Ruby-FFI is a ruby extension for programmatically loading dynamic
+libraries, binding functions within them, and calling those functions
+from Ruby code. Moreover, a Ruby-FFI extension works without changes
+on Ruby and JRuby. [Discover why you should write your next extension
+using Ruby-FFI](https://wiki.github.com/ffi/ffi/why-use-ffi).
+
+## Features/problems
+
+* Intuitive DSL
+* Supports all C native types
+* C structs (also nested), enums and global variables
+* Callbacks from C to ruby
+* Automatic garbage collection of native memory
+
+## Synopsis
+
+```ruby
+require 'ffi'
+
+module MyLib
+  extend FFI::Library
+  ffi_lib 'c'
+  attach_function :puts, [ :string ], :int
+end
+
+MyLib.puts 'Hello, World using libc!'
+```
+
+For less minimalistic and more sane examples you may look at:
+
+* the samples/ folder
+* the examples on the [wiki](https://wiki.github.com/ffi/ffi)
+* the projects using FFI listed on this page (https://wiki.github.com/ffi/ffi/projects-using-ffi)
+
+## Requirements
+
+You need a sane building environment in order to compile the extension.
+At a minimum, you will need:
+* A C compiler (e.g. Xcode on OSX, gcc on everything else)
+* libffi development library - this is commonly in the libffi-dev or libffi-devel
+
+## Installation
+
+From rubygems:
+
+    [sudo] gem install ffi
+
+or from the git repository on github:
+
+    git clone git://github.com/ffi/ffi.git
+    cd ffi
+    rake gem:install
+
+## License
+
+The ffi library is covered by the BSD license, also see the LICENSE file.
+The specs are shared with Rubyspec and are licensed by the same license
+as Rubyspec, see the LICENSE.SPECS file.
+
+## Credits
+
+The following people have submitted code, bug reports, or otherwise contributed to the success of this project:
+
+* Alban Peignier <alban.peignier at free.fr>
+* Aman Gupta <aman at tmm1.net>
+* Andrea Fazzi <andrea.fazzi at alcacoop.it>
+* Andreas Niederl <rico32 at gmx.net>
+* Andrew Cholakian <andrew at andrewvc.com>
+* Antonio Terceiro <terceiro at softwarelivre.org>
+* Brian Candler <B.Candler at pobox.com>
+* Brian D. Burns <burns180 at gmail.com>
+* Bryan Kearney <bkearney at redhat.com>
+* Charlie Savage <cfis at zerista.com>
+* Chikanaga Tomoyuki <nagachika00 at gmail.com>
+* Hongli Lai <hongli at phusion.nl>
+* Ian MacLeod <ian at nevir.net>
+* Jake Douglas <jake at shiftedlabs.com>
+* Jean-Dominique Morani <jdmorani at mac.com>
+* Jeremy Hinegardner <jeremy at hinegardner.org>
+* Jesús García Sáez <blaxter at gmail.com>
+* Joe Khoobyar <joe at ankhcraft.com>
+* Jurij Smakov <jurij at wooyd.org>
+* KISHIMOTO, Makoto <ksmakoto at dd.iij4u.or.jp>
+* Kim Burgestrand <kim at burgestrand.se>
+* Lars Kanis <kanis at comcard.de>
+* Luc Heinrich <luc at honk-honk.com>
+* Luis Lavena <luislavena at gmail.com>
+* Matijs van Zuijlen <matijs at matijs.net>
+* Matthew King <automatthew at gmail.com>
+* Mike Dalessio <mike.dalessio at gmail.com>
+* NARUSE, Yui <naruse at airemix.jp>
+* Park Heesob <phasis at gmail.com>
+* Shin Yee <shinyee at speedgocomputing.com>
+* Stephen Bannasch <stephen.bannasch at gmail.com>
+* Suraj N. Kurapati <sunaku at gmail.com>
+* Sylvain Daubert <sylvain.daubert at laposte.net>
+* Victor Costan
+* beoran at gmail.com
+* ctide <christide at christide.com>
+* emboss <Martin.Bosslet at googlemail.com>
+* hobophobe <unusualtears at gmail.com>
+* meh <meh at paranoici.org>
+* postmodern <postmodern.mod3 at gmail.com>
+* wycats at gmail.com <wycats at gmail.com>
+* Wayne Meissner <wmeissner at gmail.com>
diff --git a/app/server/vendor/ffi-1.9.10/Rakefile b/app/server/vendor/ffi-1.9.10/Rakefile
new file mode 100755
index 0000000..d0639e4
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/Rakefile
@@ -0,0 +1,210 @@
+require 'rubygems/tasks'
+require 'rbconfig'
+require 'rake/clean'
+require File.expand_path("./lib/ffi/version")
+
+USE_RAKE_COMPILER = (RUBY_PLATFORM =~ /java/) ? false : true
+if USE_RAKE_COMPILER
+  require 'rake/extensiontask'
+end
+
+require 'date'
+require 'fileutils'
+require 'rbconfig'
+require 'rspec/core/rake_task'
+require 'rubygems/package_task'
+
+LIBEXT = case RbConfig::CONFIG['host_os'].downcase
+  when /darwin/
+    "dylib"
+  when /mswin|mingw/
+    "dll"
+  else
+    RbConfig::CONFIG['DLEXT']
+  end
+
+CPU = case RbConfig::CONFIG['host_cpu'].downcase
+  when /i[3456]86/
+    # Darwin always reports i686, even when running in 64bit mode
+    if RbConfig::CONFIG['host_os'] =~ /darwin/ && 0xfee1deadbeef.is_a?(Fixnum)
+      "x86_64"
+    else
+      "i386"
+    end
+
+  when /amd64|x86_64/
+    "x86_64"
+
+  when /ppc64|powerpc64/
+    "powerpc64"
+
+  when /ppc|powerpc/
+    "powerpc"
+
+  when /^arm/
+    "arm"
+
+  else
+    RbConfig::CONFIG['host_cpu']
+  end
+
+OS = case RbConfig::CONFIG['host_os'].downcase
+  when /linux/
+    "linux"
+  when /darwin/
+    "darwin"
+  when /freebsd/
+    "freebsd"
+  when /openbsd/
+    "openbsd"
+  when /sunos|solaris/
+    "solaris"
+  when /mswin|mingw/
+    "win32"
+  else
+    RbConfig::CONFIG['host_os'].downcase
+  end
+
+GMAKE = system('which gmake >/dev/null') && 'gmake' || 'make'
+
+LIBTEST = "build/libtest.#{LIBEXT}"
+BUILD_DIR = "build"
+BUILD_EXT_DIR = File.join(BUILD_DIR, "#{RbConfig::CONFIG['arch']}", 'ffi_c', RUBY_VERSION)
+
+def gem_spec
+  @gem_spec ||= Gem::Specification.load('ffi.gemspec')
+end
+
+TEST_DEPS = [ LIBTEST ]
+if RUBY_PLATFORM == "java"
+  RSpec::Core::RakeTask.new(:spec) do |config|
+    config.rspec_opts = YAML.load_file 'spec/spec.opts'
+  end
+else
+  RSpec::Core::RakeTask.new(:spec => :compile) do |config|
+    config.rspec_opts = YAML.load_file 'spec/spec.opts'
+  end
+
+  TEST_DEPS.unshift :compile
+end
+
+desc "Build all packages"
+task :package => 'gem:package'
+
+CLOBBER.include 'lib/ffi/types.conf'
+CLOBBER.include 'pkg'
+
+CLEAN.include 'build'
+CLEAN.include 'conftest.dSYM'
+CLEAN.include 'spec/ffi/fixtures/libtest.{dylib,so,dll}'
+CLEAN.include 'spec/ffi/fixtures/*.o'
+CLEAN.include "pkg/ffi-#{FFI::VERSION}-*-mingw32"
+CLEAN.include "pkg/ffi-#{FFI::VERSION}-java"
+CLEAN.include 'lib/1.*'
+CLEAN.include 'lib/2.*'
+CLEAN.include 'bin'
+
+task :distclean => :clobber
+
+desc "Build the native test lib"
+file "build/libtest.#{LIBEXT}" => FileList['libtest/**/*.[ch]'] do
+  sh %{#{GMAKE} -f libtest/GNUmakefile CPU=#{CPU} OS=#{OS} }
+end
+
+
+desc "Build test helper lib"
+task :libtest => "build/libtest.#{LIBEXT}"
+
+desc "Test the extension"
+task :test => [ :spec ]
+
+
+namespace :bench do
+  ITER = ENV['ITER'] ? ENV['ITER'].to_i : 100000
+  bench_libs = "-Ilib -I#{BUILD_DIR}" unless RUBY_PLATFORM == "java"
+  bench_files = Dir["bench/bench_*.rb"].reject { |f| f == "bench_helper.rb" }
+  bench_files.each do |bench|
+    task File.basename(bench, ".rb")[6..-1] => TEST_DEPS do
+      sh %{#{Gem.ruby} #{bench_libs} #{bench} #{ITER}}
+    end
+  end
+  task :all => TEST_DEPS do
+    bench_files.each do |bench|
+      sh %{#{Gem.ruby} #{bench_libs} #{bench}}
+    end
+  end
+end
+
+task 'spec:run' => TEST_DEPS
+task 'spec:specdoc' => TEST_DEPS
+
+task :default => :specs
+
+namespace 'java' do
+
+  java_gem_spec = Gem::Specification.new do |s|
+    s.name = gem_spec.name
+    s.version = gem_spec.version
+    s.author = gem_spec.author
+    s.email = gem_spec.email
+    s.homepage = gem_spec.homepage
+    s.summary = gem_spec.summary
+    s.description = gem_spec.description
+    s.files = %w(LICENSE COPYING README.md Rakefile)
+    s.has_rdoc = false
+    s.license = gem_spec.license
+    s.platform = 'java'
+  end
+
+  Gem::PackageTask.new(java_gem_spec) do |pkg|
+    pkg.need_zip = true
+    pkg.need_tar = true
+    pkg.package_dir = 'pkg'
+  end
+end
+
+task 'gem:java' => 'java:gem'
+
+
+if USE_RAKE_COMPILER
+  Rake::ExtensionTask.new('ffi_c', gem_spec) do |ext|
+    ext.name = 'ffi_c'                                        # indicate the name of the extension.
+    # ext.lib_dir = BUILD_DIR                                 # put binaries into this folder.
+    ext.tmp_dir = BUILD_DIR                                   # temporary folder used during compilation.
+    ext.cross_compile = true                                  # enable cross compilation (requires cross compile toolchain)
+    ext.cross_platform = %w[i386-mingw32 x64-mingw32]                     # forces the Windows platform instead of the default one
+  end
+
+  ENV['RUBY_CC_VERSION'] ||= '1.8.7:1.9.3:2.0.0:2.1.5:2.2.1'
+
+  ENV['RUBY_CC_VERSION'].to_s.split(':').each do |ruby_version|
+    task "copy:ffi_c:i386-mingw32:#{ruby_version}" do |t|
+      sh "i686-w64-mingw32-strip -S #{BUILD_DIR}/i386-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so"
+    end
+
+    task "copy:ffi_c:x64-mingw32:#{ruby_version}" do |t|
+      sh "x86_64-w64-mingw32-strip -S #{BUILD_DIR}/x64-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so"
+    end
+  end
+
+  desc "build a windows gem without all the ceremony."
+  task "gem:windows" do
+    require "rake_compiler_dock"
+    RakeCompilerDock.sh "bundle && rake cross native gem MAKE='nice make -j`nproc`'"
+  end
+end
+
+Gem::Tasks.new do |t|
+  t.scm.tag.format = '%s'
+end
+
+begin
+  require 'yard'
+
+  namespace :doc do
+    YARD::Rake::YardocTask.new do |yard|
+    end
+  end
+rescue LoadError
+  warn "[warn] YARD unavailable"
+end
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_FFFrV.rb b/app/server/vendor/ffi-1.9.10/bench/bench_FFFrV.rb
new file mode 100755
index 0000000..fb06574
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_FFFrV.rb
@@ -0,0 +1,46 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  attach_function :bench_f32f32f32_v, [ :float, :float, :float ], :void
+  def self.rb_bench(a0, a1, a2); nil; end
+end
+
+
+puts "Benchmark [ :float, :float, :float ], :void performance, #{ITER}x calls"
+f = 1.0
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.bench_f32f32f32_v(f, f, f) }
+  }
+}
+
+puts "Benchmark ruby method(1 arg)  performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.rb_bench(f, f, f) }
+  }
+}
+
+unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+  require 'dl'
+  require 'dl/import'
+  module LibTest
+    if RUBY_VERSION >= "1.9.0"
+      extend DL::Importer
+    else
+      extend DL::Importable
+    end
+    dlload LIBTEST_PATH
+    extern "void bench_f32f32f32_v(float, float, float)"
+  end
+  puts "Benchmark DL void bench(float, float, float) performance, #{ITER}x calls"
+  10.times {
+  f1 = 1.0; f2 = 2.0; f3 = 3.0
+    puts Benchmark.measure {
+      ITER.times { LibTest.bench_f32f32f32_v(f1, f2, f3) }
+    }
+  }
+end
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_FrV.rb b/app/server/vendor/ffi-1.9.10/bench/bench_FrV.rb
new file mode 100755
index 0000000..d9bdc2a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_FrV.rb
@@ -0,0 +1,63 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  attach_function :bench_f32_v, [ :float ], :void
+  def self.rb_bench(i0); nil; end
+end
+
+
+puts "Benchmark [ :float ], :void performance, #{ITER}x calls"
+f = 1.0
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench_f32_v(f)
+      LibTest.bench_f32_v(f)
+      LibTest.bench_f32_v(f)
+      LibTest.bench_f32_v(f)
+      i += 4
+    end
+  }
+}
+
+puts "Benchmark ruby method(1 arg)  performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.rb_bench(f)
+      LibTest.rb_bench(f)
+      LibTest.rb_bench(f)
+      LibTest.rb_bench(f)
+      i += 4
+    end
+  }
+}
+
+unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+  require 'dl'
+  require 'dl/import'
+  module LibTest
+    if RUBY_VERSION >= "1.9.0"
+      extend DL::Importer
+    else
+      extend DL::Importable
+    end
+    dlload LIBTEST_PATH
+    extern "void bench_f32_v(float)"
+  end
+  puts "Benchmark DL void bench(float) performance, #{ITER}x calls"
+  10.times {
+    puts Benchmark.measure {
+      i = 0; while i < ITER
+        LibTest.bench_f32_v(0)
+        LibTest.bench_f32_v(0)
+        LibTest.bench_f32_v(0)
+        LibTest.bench_f32_v(0)
+        i += 4
+      end
+    }
+  }
+end
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_IIIIIIrV.rb b/app/server/vendor/ffi-1.9.10/bench/bench_IIIIIIrV.rb
new file mode 100755
index 0000000..84cb16a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_IIIIIIrV.rb
@@ -0,0 +1,53 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+METHOD = 'bench_s32s32s32s32s32s32_v'
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  attach_function :ffi_bench, METHOD, [ :int, :int, :int, :int, :int, :int ], :void, :save_errno => false
+  def self.rb_bench(i0, i1, i2, i3, i4, i5); nil; end
+end
+
+
+puts "Benchmark [ :int, :int, :int, :int, :int, :int ], :void performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.ffi_bench(1, 2, 3, 4, 5, 6)
+      i += 1
+    end
+  }
+}
+
+puts "Benchmark ruby method(6 arg)  performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.rb_bench(0, 1, 2, 3, 4, 5)
+      i += 1
+    end
+  }
+}
+
+unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+  require 'dl'
+  require 'dl/import'
+  module LibTest
+    if RUBY_VERSION >= "1.9.0"
+      extend DL::Importer
+    else
+      extend DL::Importable
+    end
+    dlload LIBTEST_PATH
+    extern "void bench_s32s32s32s32s32s32_v(int, int, int, int, int, int)"
+  end
+  puts "Benchmark DL void bench(int, int, int) performance, #{ITER}x calls"
+  10.times {
+    puts Benchmark.measure {
+      i = 0; while i < ITER
+        LibTest.bench_s32s32s32s32s32s32_v(0, 1, 2, 3, 4, 5)
+        i += 1
+      end
+    }
+  }
+end
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_IIIrI.rb b/app/server/vendor/ffi-1.9.10/bench/bench_IIIrI.rb
new file mode 100755
index 0000000..312f8c0
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_IIIrI.rb
@@ -0,0 +1,17 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  attach_function :bench, :bench_s32s32s32_v, [ :int, :int, :int ], :int
+end
+
+
+puts "Benchmark [ :int, :int, :int ], :void performance, #{ITER}x calls"
+
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.bench(0, 1, 2) }
+  }
+}
+puts "Benchmark Invoker.call [ :int, :int, :int ], :void performance, #{ITER}x calls"
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_IIIrV.rb b/app/server/vendor/ffi-1.9.10/bench/bench_IIIrV.rb
new file mode 100755
index 0000000..257a1cd
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_IIIrV.rb
@@ -0,0 +1,55 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  attach_function :ffi_bench, :bench_s32s32s32_v, [ :int, :int, :int ], :void, :save_errno => false
+  def self.rb_bench(i0, i1, i2); nil; end
+end
+
+unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+  require 'dl'
+  require 'dl/import'
+  module LibTest
+    if RUBY_VERSION >= "1.9.0"
+      extend DL::Importer
+    else
+      extend DL::Importable
+    end
+    dlload LIBTEST_PATH
+    extern "void bench_s32s32s32_v(int, int, int)"
+  end
+end
+
+
+puts "Benchmark [ :int, :int, :int ], :void performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.ffi_bench(0, 1, 2)
+      i += 1
+    end
+  }
+}
+
+puts "Benchmark ruby method(3 arg)  performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.rb_bench(0, 1, 2)
+      i += 1
+    end
+  }
+}
+unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+puts "Benchmark DL void bench(int, int, int) performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench_s32s32s32_v(0, 1, 2)
+      i += 1
+    end
+  }
+}
+end
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_IrV.rb b/app/server/vendor/ffi-1.9.10/bench/bench_IrV.rb
new file mode 100755
index 0000000..c44ae30
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_IrV.rb
@@ -0,0 +1,61 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  attach_function :ffi_bench, :bench_s32_v, [ :int ], :void, :save_errno => false
+  def self.rb_bench(i0); nil; end
+end
+unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+  require 'dl'
+  require 'dl/import'
+  module LibTest
+    if RUBY_VERSION >= "1.9.0"
+      extend DL::Importer
+    else
+      extend DL::Importable
+    end
+    dlload LIBTEST_PATH
+    extern "void bench_s32_v(int)"
+  end
+end
+
+puts "Benchmark [ :int ], :void performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.ffi_bench(0)
+      LibTest.ffi_bench(0)
+      LibTest.ffi_bench(0)
+      LibTest.ffi_bench(0)
+      i += 4
+    end
+  }
+}
+
+puts "Benchmark ruby method(1 arg)  performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.rb_bench(0)
+      LibTest.rb_bench(0)
+      LibTest.rb_bench(0)
+      LibTest.rb_bench(0)
+      i += 4
+    end
+  }
+}
+
+unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+puts "Benchmark DL void bench(int) performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench_s32_v(0)
+      i += 1
+    end
+  }
+}
+end
+
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_LLLrV.rb b/app/server/vendor/ffi-1.9.10/bench/bench_LLLrV.rb
new file mode 100755
index 0000000..ec658e5
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_LLLrV.rb
@@ -0,0 +1,20 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  attach_function :bench_s64s64s64_v, [ :long_long, :long_long, :long_long ], :void, :save_errno => false
+end
+
+
+puts "Benchmark [ :long_long, :long_long, :long_long ], :void performance, #{ITER}x calls"
+
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench_s64s64s64_v(0, 1, 2)
+      i += 1
+    end
+  }
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_PPPrV.rb b/app/server/vendor/ffi-1.9.10/bench/bench_PPPrV.rb
new file mode 100755
index 0000000..43ea3bd
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_PPPrV.rb
@@ -0,0 +1,112 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+
+  attach_function :bench_ptr, :bench_PPP_v, [ :pointer, :pointer, :pointer ], :void, :save_errno => false
+  attach_function :bench_buffer, :bench_PPP_v, [ :pointer, :pointer, :pointer ], :void, :save_errno => false
+  attach_function :bench_struct, :bench_PPP_v, [ :pointer, :pointer, :pointer ], :void, :save_errno => false
+  attach_function :bench_nil, :bench_PPP_v, [ :pointer, :pointer, :pointer ], :void, :save_errno => false
+  attach_function :bench_conv, :bench_PPP_v, [ :pointer, :pointer, :pointer ], :void, :save_errno => false
+end
+
+
+puts "Benchmark [ :pointer, :pointer, :pointer ], :void performance, #{ITER}x calls"
+ptr = FFI::MemoryPointer.new :int
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench_ptr(ptr, ptr, ptr)
+      LibTest.bench_ptr(ptr, ptr, ptr)
+      LibTest.bench_ptr(ptr, ptr, ptr)
+      LibTest.bench_ptr(ptr, ptr, ptr)
+      i += 4
+    end
+  }
+}
+puts "Benchmark [ :pointer, :pointer, :pointer ], :void with Struct parameters performance #{ITER}x calls"
+
+class TestStruct < FFI::Struct
+  layout :i, :int
+end
+
+s = TestStruct.new(FFI::MemoryPointer.new(TestStruct));
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench_struct(s, s, s)
+      LibTest.bench_struct(s, s, s)
+      LibTest.bench_struct(s, s, s)
+      LibTest.bench_struct(s, s, s)
+      i += 4
+    end
+  }
+}
+
+puts "Benchmark [ :pointer, :pointer, :pointer ], :void with Buffer parameters performance, #{ITER}x calls"
+ptr = FFI::Buffer.new(:int)
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench_buffer(ptr, ptr, ptr)
+      LibTest.bench_buffer(ptr, ptr, ptr)
+      LibTest.bench_buffer(ptr, ptr, ptr)
+      LibTest.bench_buffer(ptr, ptr, ptr)
+      i += 4
+    end
+  }
+}
+
+puts "Benchmark [ :pointer, :pointer, :pointer ], :void with nil parameters performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench_nil(nil, nil, nil)
+      LibTest.bench_nil(nil, nil, nil)
+      LibTest.bench_nil(nil, nil, nil)
+      LibTest.bench_nil(nil, nil, nil)
+      i += 4
+    end
+  }
+}
+
+
+
+puts "Benchmark [ :pointer, :pointer, :pointer ], :void with string parameters performance, #{ITER}x calls"
+ptr = 0.chr * 4
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench_ptr(ptr, ptr, ptr)
+      LibTest.bench_ptr(ptr, ptr, ptr)
+      LibTest.bench_ptr(ptr, ptr, ptr)
+      LibTest.bench_ptr(ptr, ptr, ptr)
+      i += 4
+    end
+  }
+}
+
+class PointerType
+  def initialize(ptr)
+    @pointer = ptr
+  end
+
+  def to_ptr
+    @pointer
+  end
+end
+
+puts "Benchmark [ :pointer, :pointer, :pointer ], :void with to_ptr converting parameters performance, #{ITER}x calls"
+ptr = PointerType.new(FFI::MemoryPointer.new(:int))
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench_conv(ptr, ptr, ptr)
+      LibTest.bench_conv(ptr, ptr, ptr)
+      LibTest.bench_conv(ptr, ptr, ptr)
+      LibTest.bench_conv(ptr, ptr, ptr)
+      i += 4
+    end
+  }
+}
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_PPrV.rb b/app/server/vendor/ffi-1.9.10/bench/bench_PPrV.rb
new file mode 100755
index 0000000..0bf121d
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_PPrV.rb
@@ -0,0 +1,69 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+
+  attach_function :bench, :bench_PP_v, [ :buffer_in, :buffer_in ], :void
+end
+
+
+puts "Benchmark [ :buffer_in, :pointer ], :void performance, #{ITER}x calls"
+ptr = FFI::MemoryPointer.new :int
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.bench(ptr, ptr) }
+  }
+}
+puts "Benchmark [ :buffer_in, :buffer_in ], :void with Struct parameters performance #{ITER}x calls"
+
+class TestStruct < FFI::Struct
+  layout :i, :int
+end
+
+s = TestStruct.new(FFI::MemoryPointer.new(TestStruct));
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.bench(s, s) }
+  }
+}
+
+puts "Benchmark [ :buffer_in, :buffer_in ], :void with nil parameters performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.bench(nil, nil) }
+  }
+}
+
+
+puts "Benchmark [ :buffer_in, :buffer_in ], :void with Buffer parameters performance, #{ITER}x calls"
+ptr = FFI::Buffer.new(:int)
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.bench(ptr, ptr) }
+  }
+}
+
+puts "Benchmark [ :buffer_in, :buffer_in ], :void with one nil, one Buffer parameter performance, #{ITER}x calls"
+ptr = FFI::Buffer.new(:int)
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.bench(nil, ptr) }
+  }
+}
+
+puts "Benchmark [ :buffer_in, :buffer_in ], :void with loop-allocated Buffer parameters performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.bench(FFI::Buffer.new(:int), FFI::Buffer.new(:int)) }
+  }
+}
+
+puts "Benchmark [ :buffer_in, :buffer_in ], :void with loop-allocated MemoryPointer parameters performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.bench(FFI::MemoryPointer.new(:int), FFI::MemoryPointer.new(:int)) }
+  }
+}
+
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_PrV.rb b/app/server/vendor/ffi-1.9.10/bench/bench_PrV.rb
new file mode 100755
index 0000000..c049fd2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_PrV.rb
@@ -0,0 +1,101 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+
+  attach_function :bench, :bench_P_v, [ :buffer_in ], :void, :save_errno => false
+end
+
+
+puts "Benchmark [ :buffer_in ], :void performance (pre allocated pointer), #{ITER}x calls"
+ptr = FFI::MemoryPointer.new :int
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench(ptr)
+      LibTest.bench(ptr)
+      LibTest.bench(ptr)
+      LibTest.bench(ptr)
+      i += 4
+    end
+  }
+}
+
+puts "Benchmark [ :buffer_in ], :void performance (nil param), #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench(nil)
+      LibTest.bench(nil)
+      LibTest.bench(nil)
+      LibTest.bench(nil)
+      i += 4
+    end
+  }
+}
+
+puts "Benchmark [ :buffer_in ], :void performance (pre allocated Buffer param), #{ITER}x calls"
+ptr = FFI::Buffer.new :int
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench(ptr)
+      LibTest.bench(ptr)
+      LibTest.bench(ptr)
+      LibTest.bench(ptr)
+      i += 4
+    end
+  }
+}
+puts "Benchmark [ :buffer_in ], :void performance (const String param), #{ITER}x calls"
+ptr = 'test'
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench(ptr)
+      LibTest.bench(ptr)
+      LibTest.bench(ptr)
+      LibTest.bench(ptr)
+      i += 4
+    end
+  }
+}
+puts "Benchmark [ :buffer_in ], :void performance (loop-allocated Buffer param), #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench(FFI::Buffer.new(4))
+      LibTest.bench(FFI::Buffer.new(4))
+      LibTest.bench(FFI::Buffer.new(4))
+      LibTest.bench(FFI::Buffer.new(4))
+      i += 4
+    end
+  }
+}
+puts "Benchmark [ :buffer_in ], :void performance (loop-allocated String param), #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench(String.new)
+      LibTest.bench(String.new)
+      LibTest.bench(String.new)
+      LibTest.bench(String.new)
+      i += 4
+    end
+  }
+}
+puts "Benchmark [ :buffer_in ], :void performance (loop-allocated MemoryPointer param), #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      LibTest.bench(FFI::MemoryPointer.new(4))
+      LibTest.bench(FFI::MemoryPointer.new(4))
+      LibTest.bench(FFI::MemoryPointer.new(4))
+      LibTest.bench(FFI::MemoryPointer.new(4))
+      i += 4
+    end
+  }
+}
+
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_SrV.rb b/app/server/vendor/ffi-1.9.10/bench/bench_SrV.rb
new file mode 100755
index 0000000..7f4b40c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_SrV.rb
@@ -0,0 +1,16 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  attach_function :bench_S_v, [ :string ], :void
+end
+
+puts "Benchmark [ :string ], :void performance, #{ITER}x calls"
+
+s = 'a' * 1000
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.bench_S_v(s) }
+  }
+}
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_VrI.rb b/app/server/vendor/ffi-1.9.10/bench/bench_VrI.rb
new file mode 100755
index 0000000..3fdf335
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_VrI.rb
@@ -0,0 +1,66 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  attach_function :ffi_bench, :returnInt, [ ], :int, :save_errno => false
+  def self.rb_bench; 0xdeadbeef; end
+end
+
+unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+  require 'dl'
+  require 'dl/import'
+  module LibTest
+    if RUBY_VERSION >= "1.9.0"
+      extend DL::Importer
+    else
+      extend DL::Importable
+    end
+    dlload LIBTEST_PATH
+    extern "int returnInt()"
+  end
+end
+
+puts "Benchmark [ ], :int performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; max = ITER / 4
+    while i < max
+      LibTest.ffi_bench
+      LibTest.ffi_bench
+      LibTest.ffi_bench
+      LibTest.ffi_bench
+      i += 1
+    end
+  }
+}
+
+puts "Benchmark ruby method(), nil performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; max = ITER / 4
+    while i < max
+      LibTest.rb_bench
+      LibTest.rb_bench
+      LibTest.rb_bench
+      LibTest.rb_bench
+      i += 1
+    end
+  }
+}
+
+unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+puts "Benchmark DL void bench() performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; max = ITER / 4
+    while i < max
+      LibTest.returnInt
+      LibTest.returnInt
+      LibTest.returnInt
+      LibTest.returnInt
+      i += 1
+    end
+  }
+}
+end
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_VrV.rb b/app/server/vendor/ffi-1.9.10/bench/bench_VrV.rb
new file mode 100755
index 0000000..c5ddce6
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_VrV.rb
@@ -0,0 +1,71 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  attach_function :ffi_bench, :returnVoid, [ ], :void
+  attach_function :ffi_bench_noerrno, :returnVoid, [ ], :void, :save_errno => false
+  def self.rb_bench; nil; end
+end
+
+unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+  require 'dl'
+  require 'dl/import'
+  module LibTest
+    if RUBY_VERSION >= "1.9.0"
+      extend DL::Importer
+    else
+      extend DL::Importable
+    end
+    dlload LIBTEST_PATH
+    extern "void returnVoid()"
+  end
+end
+
+puts "Benchmark [ ], :void performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0
+    while i < ITER
+      LibTest.ffi_bench
+      i += 1
+    end
+  }
+}
+
+
+unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+puts "Benchmark DL void bench() performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0
+    while i < ITER
+      LibTest.returnVoid
+      i += 1
+    end
+  }
+}
+end
+
+puts "Benchmark [ ], :void no-errno performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0
+    while i < ITER
+      LibTest.ffi_bench_noerrno
+      i += 1
+    end
+  }
+}
+
+puts "Benchmark ruby method(no arg)  performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0
+    while i < ITER
+      LibTest.rb_bench
+      i += 1
+    end
+  }
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_autoptr.rb b/app/server/vendor/ffi-1.9.10/bench/bench_autoptr.rb
new file mode 100755
index 0000000..6027379
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_autoptr.rb
@@ -0,0 +1,42 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+require 'benchmark'
+require 'ffi'
+iter = ITER
+
+class Ptr < FFI::AutoPointer
+  def self.release(ptr)
+    LibC.free(ptr);
+  end
+end
+
+module LibC
+  extend FFI::Library
+  ffi_lib FFI::Library::LIBC
+  attach_function :malloc, [ :long ], Ptr, :ignore_error => true
+  attach_function :malloc2, :malloc, [ :long ], :pointer, :ignore_error => true
+  attach_function :free, [ :pointer ], :void, :ignore_error => true
+  def self.finalizer(ptr) 
+    proc { LibC.free(ptr) }
+  end
+end
+
+
+puts "Benchmark AutoPointer.new performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { LibC.malloc(4) }
+  }
+}
+
+puts "Benchmark ObjectSpace finalizer performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { 
+      ptr = LibC.malloc2(4)
+      ptr2 = FFI::Pointer.new(ptr)
+      ObjectSpace.define_finalizer(ptr2, LibC.finalizer(ptr))
+    }
+  }
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_buffer.rb b/app/server/vendor/ffi-1.9.10/bench/bench_buffer.rb
new file mode 100755
index 0000000..947fe10
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_buffer.rb
@@ -0,0 +1,112 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+require 'benchmark'
+require 'ffi'
+iter = ITER
+
+module BufferBench
+  extend FFI::Library
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  attach_function :bench_s32_v, [ :int ], :void
+  begin
+    attach_function :bench_buffer_in, :ptr_ret_int32_t, [ :buffer_in, :int ], :void
+  rescue FFI::NotFoundError
+    # NetBSD uses #define instead of typedef for these
+    attach_function :bench_buffer_in, :ptr_ret___int32_t, [ :buffer_in, :int ], :void
+  end
+  begin
+    attach_function :bench_buffer_inout, :ptr_ret_int32_t, [ :buffer_inout, :int ], :void
+  rescue FFI::NotFoundError
+    # NetBSD uses #define instead of typedef for these
+    attach_function :bench_buffer_inout, :ptr_ret___int32_t, [ :buffer_inout, :int ], :void
+  end
+  begin
+    attach_function :bench_buffer_out, :ptr_ret_int32_t, [ :buffer_out, :int ], :void
+  rescue FFI::NotFoundError
+    # NetBSD uses #define instead of typedef for these
+    attach_function :bench_buffer_out, :ptr_ret___int32_t, [ :buffer_out, :int ], :void
+  end
+end
+class IntStruct < FFI::Struct
+  layout :i, :int
+end
+puts "Benchmark FFI call(MemoryPointer.new(:int, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { BufferBench.bench_buffer_inout(FFI::MemoryPointer.new(:int, 1, true), 0) }
+  }
+}
+puts "Benchmark FFI call(MemoryPointer.new(4, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { BufferBench.bench_buffer_inout(FFI::MemoryPointer.new(4, 1, true), 0) }
+  }
+}
+puts "Benchmark FFI call(MemoryPointer.new(IntStruct, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { BufferBench.bench_buffer_inout(FFI::MemoryPointer.new(IntStruct, 1, true), 0) }
+  }
+}
+puts "Benchmark FFI call(0.chr * 4) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { BufferBench.bench_buffer_inout(0.chr * 4, 0) }
+  }
+}
+puts "Benchmark FFI call(Buffer.alloc_inout(:int, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { BufferBench.bench_buffer_inout(FFI::Buffer.alloc_inout(:int, 1, true), 0) }
+  }
+}
+puts "Benchmark FFI call(Buffer.alloc_inout(IntStruct, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { BufferBench.bench_buffer_inout(FFI::Buffer.alloc_inout(IntStruct, 1, true), 0) }
+  }
+}
+puts "Benchmark FFI call(Buffer.alloc_inout(4, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { BufferBench.bench_buffer_inout(FFI::Buffer.alloc_inout(4, 1, true), 0) }
+  }
+}
+puts "Benchmark FFI call(Buffer.alloc_in(:int, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { BufferBench.bench_buffer_in(FFI::Buffer.alloc_in(:int, 1, true), 0) }
+  }
+}
+puts "Benchmark FFI call(Buffer.alloc_in(4, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { BufferBench.bench_buffer_in(FFI::Buffer.alloc_in(4, 1, true), 0) }
+  }
+}
+puts "Benchmark FFI call(Buffer.alloc_in(IntStruct, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { BufferBench.bench_buffer_in(FFI::Buffer.alloc_in(IntStruct, 1, true), 0) }
+  }
+}
+puts "Benchmark FFI call(Buffer.alloc_out(:int, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { BufferBench.bench_buffer_out(FFI::Buffer.alloc_out(:int, 1, true), 0) }
+  }
+}
+puts "Benchmark FFI call(Buffer.alloc_out(IntStruct, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { BufferBench.bench_buffer_out(FFI::Buffer.alloc_out(IntStruct, 1, true), 0) }
+  }
+}
+puts "Benchmark FFI call(Buffer.alloc_out(4, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { BufferBench.bench_buffer_out(FFI::Buffer.alloc_out(4, 1, true), 0) }
+  }
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_buffer_alloc.rb b/app/server/vendor/ffi-1.9.10/bench/bench_buffer_alloc.rb
new file mode 100755
index 0000000..62cfc71
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_buffer_alloc.rb
@@ -0,0 +1,46 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+require 'benchmark'
+require 'ffi'
+iter = ITER
+
+puts "Benchmark Buffer.new(:int, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < iter
+      FFI::Buffer.new(:int, 1, true)
+      i += 1
+    end
+  }
+}
+
+puts "Benchmark Buffer.alloc_out(:int, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < iter
+      FFI::Buffer.new_out(:int, 1, true)
+      i += 1
+    end
+  }
+}
+
+puts "Benchmark Buffer.new(4, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < iter
+      FFI::Buffer.new(4, 1, true)
+      i += 1
+    end
+  }
+}
+
+puts "Benchmark Buffer.new(256, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < iter
+      FFI::Buffer.new(256, 1, true)
+      i += 1
+    end
+  }
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_buffer_fill.rb b/app/server/vendor/ffi-1.9.10/bench/bench_buffer_fill.rb
new file mode 100755
index 0000000..89733b8
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_buffer_fill.rb
@@ -0,0 +1,45 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+require 'benchmark'
+require 'ffi'
+iter = ITER
+
+puts "Benchmark Buffer#put_array_of_float performance, #{iter}x"
+
+5.times {
+  ptr = FFI::Buffer.new(:float, 8, false)
+  puts Benchmark.measure {
+    iter.times { 
+      ptr.put_array_of_float(0, [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8 ])
+    }
+  }
+}
+
+
+puts "Benchmark Buffer.new(:float, 8, false)).put_array_of_float performance, #{iter}x"
+5.times {
+  puts Benchmark.measure {
+    iter.times { 
+      ptr = FFI::Buffer.new(:float, 8, false)
+      ptr.put_array_of_float(0, [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8 ])
+    }
+  }
+}
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+
+  attach_function :bench, :bench_P_v, [ :buffer_in ], :void
+end
+
+puts "Benchmark Buffer alloc+fill+call performance, #{iter}x"
+5.times {
+  puts Benchmark.measure {
+    iter.times {
+      ptr = FFI::Buffer.new(:float, 8, false)
+      ptr.put_array_of_float(0, [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8 ])
+      LibTest.bench(ptr)
+    }
+  }
+}
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_chmod.rb b/app/server/vendor/ffi-1.9.10/bench/bench_chmod.rb
new file mode 100755
index 0000000..ea3ac37
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_chmod.rb
@@ -0,0 +1,36 @@
+require 'benchmark'
+require 'ffi'
+require 'ffi/platform'
+
+iter = 10_000
+file = "README"
+
+module Posix
+  extend FFI::Library
+  ffi_lib FFI::Library::LIBC
+
+  def self.chmod(mode, path)
+    if self._chmod(path, mode) != 0
+    end
+  end
+  if FFI::Platform.windows?
+    attach_function :_chmod, :_chmod, [ :string, :int ], :int
+  else
+    attach_function :_chmod, :chmod, [ :string, :int ], :int
+  end
+end
+
+
+puts "Benchmark FFI chmod performance, #{iter}x changing mode"
+10.times {
+  puts Benchmark.measure {
+    iter.times { Posix.chmod(0622, __FILE__) }
+  }
+}
+
+puts "Benchmark Ruby File.chmod performance, #{iter}x changing mode"
+10.times {
+  puts Benchmark.measure {
+    iter.times { File.chmod(0622, __FILE__) }
+  }
+}
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_closure_IIIrV.rb b/app/server/vendor/ffi-1.9.10/bench/bench_closure_IIIrV.rb
new file mode 100755
index 0000000..bbe6631
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_closure_IIIrV.rb
@@ -0,0 +1,90 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  callback :closureIIIrV, [ :int, :int, :int ], :void
+  attach_function :ffi_bench, :testClosureIIIrV, [ :closureIIIrV, :int, :int, :int ], :void
+  def self.rb_bench(a, b, c, &block); yield(a, b, c); end
+end
+unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+  require 'dl'
+  require 'dl/import'
+  module LibTest
+    if RUBY_VERSION >= "1.9.0"
+      extend DL::Importer
+    else
+      extend DL::Importable
+    end
+    dlload LIBTEST_PATH
+    extern "int returnInt()"
+  end
+end
+
+class Foo
+  def call(a, b, c); nil; end
+end
+
+puts "Benchmark [ ], :void closure block, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench(1, 2, 3) { } }
+  }
+}
+
+puts "Benchmark [ ], :void closure callable, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench(Foo.new, 1, 2, 3) }
+  }
+}
+
+
+puts "Benchmark [ ], :void pre-allocated function with block, #{ITER}x calls"
+10.times {
+  fn = FFI::Function.new(:void, [ :int, :int, :int ]) {}
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench(fn, 1, 2, 3) }
+  }
+}
+
+puts "Benchmark [ ], :void pre-allocated function with callable, #{ITER}x calls"
+10.times {
+  fn = FFI::Function.new(:void, [ :int, :int, :int ], Foo.new)
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench(fn, 1, 2, 3) }
+  }
+}
+
+puts "Benchmark [ ], :void pre-allocated proc, #{ITER}x calls"
+10.times {
+  proc = lambda { |a,b,c| }
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench(proc, 1, 2, 3) }
+  }
+}
+
+puts "Benchmark [ ], :void pre-allocated callable, #{ITER}x calls"
+10.times {
+  proc = Foo.new
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench(proc, 1, 2, 3) }
+  }
+}
+
+#unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+#puts "Benchmark DL void bench() performance, #{ITER}x calls"
+#10.times {
+#  puts Benchmark.measure {
+#    ITER.times { LibTest.returnInt }
+#  }
+#}
+#end
+
+puts "Benchmark ruby method(3 arg), #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.rb_bench(1, 2, 3) {} }
+  }
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_closure_IrV.rb b/app/server/vendor/ffi-1.9.10/bench/bench_closure_IrV.rb
new file mode 100755
index 0000000..086d2df
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_closure_IrV.rb
@@ -0,0 +1,53 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  callback :closureVrV, [ ], :void
+  attach_function :ffi_bench, :testClosureIrV, [ :closureVrV, :int ], :void
+  def self.rb_bench(i, &block); nil; end
+end
+unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+  require 'dl'
+  require 'dl/import'
+  module LibTest
+    if RUBY_VERSION >= "1.9.0"
+      extend DL::Importer
+    else
+      extend DL::Importable
+    end
+    dlload LIBTEST_PATH
+    extern "int returnInt()"
+  end
+end
+
+puts "Benchmark [ ], :void closure block performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench(1) { |i| } }
+  }
+}
+
+puts "Benchmark [ ], :void pre-allocated function performance, #{ITER}x calls"
+10.times {
+  fn = FFI::Function.new(:void, [ :int ]) { |i| }
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench(fn, 2) }
+  }
+}
+
+puts "Benchmark [ ], :void pre-allocated callable performance, #{ITER}x calls"
+10.times {
+  fn = Proc.new { |i| }
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench(fn, 2) }
+  }
+}
+
+puts "Benchmark ruby method(1 arg)  performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.rb_bench(1) {} }
+  }
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_closure_VrV.rb b/app/server/vendor/ffi-1.9.10/bench/bench_closure_VrV.rb
new file mode 100755
index 0000000..15d5eb7
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_closure_VrV.rb
@@ -0,0 +1,78 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  callback :closureVrV, [ ], :void
+  
+  attach_function :ffi_bench, :testClosureVrV, [ :closureVrV ], :void
+  @blocking = true
+  attach_function :threaded_bench, :testThreadedClosureVrV, [ :closureVrV, :int ], :void
+  
+  def self.rb_bench(&block)
+    yield
+  end
+end
+
+unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+  require 'dl'
+  require 'dl/import'
+  module LibTest
+    if RUBY_VERSION >= "1.9.0"
+      extend DL::Importer
+    else
+      extend DL::Importable
+    end
+    dlload LIBTEST_PATH
+    extern "int returnInt()"
+  end
+end
+
+puts "Benchmark [ ], :void closure block performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench { } }
+  }
+}
+
+puts "Benchmark [ ], :void pre-allocated function pointer performance, #{ITER}x calls"
+10.times {
+  fn = FFI::Function.new(:void, []) {}
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench fn }
+  }
+}
+
+puts "Benchmark [ ], :void pre-allocated closure performance, #{ITER}x calls"
+10.times {
+  proc = lambda {}
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench proc }
+  }
+}
+
+puts "Benchmark [ ], :void non-ruby thread closure performance, #{ITER}x calls"
+10.times {
+  fn = FFI::Function.new(:void, []) {}
+  puts Benchmark.measure {
+    LibTest.threaded_bench(fn, ITER)
+  }
+}
+
+
+#unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+#puts "Benchmark DL void bench() performance, #{ITER}x calls"
+#10.times {
+#  puts Benchmark.measure {
+#    ITER.times { LibTest.returnInt }
+#  }
+#}
+#end
+
+puts "Benchmark ruby method(no arg)  performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.rb_bench {} }
+  }
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_enum.rb b/app/server/vendor/ffi-1.9.10/bench/bench_enum.rb
new file mode 100755
index 0000000..d4ebf56
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_enum.rb
@@ -0,0 +1,58 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  enum :foo, [ :a, :b, :c ]
+  attach_function :ffi_bench, :bench_s32_v, [ :foo ], :void, :save_errno => false
+  attach_function :ffi_bench_i, :bench_s32_v, [ :int ], :void, :save_errno => false
+  def self.rb_bench(i0); nil; end
+end
+
+puts "Benchmark [ enum ], :void performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench(:a) }
+  }
+}
+
+puts "Benchmark [ enum ], :void with int arg performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench(1) }
+  }
+}
+
+puts "Benchmark [ :int ], :void performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench_i(1) }
+  }
+}
+puts "Benchmark [ :int ], :void with enum arg performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench_i(:a) }
+  }
+}
+unless RUBY_PLATFORM == "java" && JRUBY_VERSION < "1.3.0"
+  require 'dl'
+  require 'dl/import'
+  module LibTest
+    if RUBY_VERSION >= "1.9.0"
+      extend DL::Importer
+    else
+      extend DL::Importable
+    end
+    dlload LIBTEST_PATH
+    extern "void bench_s32_v(int)"
+  end
+end
+
+puts "Benchmark ruby method(1 arg)  performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.rb_bench(:a) }
+  }
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_enum_i.rb b/app/server/vendor/ffi-1.9.10/bench/bench_enum_i.rb
new file mode 100755
index 0000000..62649de
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_enum_i.rb
@@ -0,0 +1,17 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  enum :foo, [ :a, :b, :c ]
+  attach_function :ffi_bench, :bench_s32_v, [ :foo ], :void, :save_errno => true
+  attach_function :ffi_bench_i, :bench_s32_v, [ :int ], :void, :save_errno => true
+  def self.rb_bench(i0); nil; end
+end
+
+puts "Benchmark [ :int ], :void performance, #{ITER}x calls"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibTest.ffi_bench_i(1) }
+  }
+}
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_getlogin.rb b/app/server/vendor/ffi-1.9.10/bench/bench_getlogin.rb
new file mode 100755
index 0000000..4fabf8c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_getlogin.rb
@@ -0,0 +1,29 @@
+require 'benchmark'
+require 'ffi'
+require 'etc'
+
+iter = 1000000
+
+module Posix
+  extend FFI::Library
+  ffi_lib FFI::Library::LIBC
+  attach_function :getlogin, [], :string
+end
+if Posix.getlogin != Etc.getlogin
+  raise ArgumentError, "FFI getlogin returned incorrect value"
+end
+
+puts "Benchmark FFI getlogin(2) performance, #{iter}x"
+
+10.times {
+  puts Benchmark.measure {
+    iter.times { Posix.getlogin }
+  }
+}
+
+puts "Benchmark Etc.getlogin performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { Etc.getlogin }
+  }
+}
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_getpid.rb b/app/server/vendor/ffi-1.9.10/bench/bench_getpid.rb
new file mode 100755
index 0000000..ac1de66
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_getpid.rb
@@ -0,0 +1,34 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+iter = ITER
+
+module Posix
+  extend FFI::Library
+  ffi_lib 'c'
+  if FFI::Platform.windows?
+    attach_function :getpid, :_getpid, [], :uint, :save_errno => false
+  else
+    attach_function :getpid, [], :uint, :save_errno => false
+  end
+end
+
+
+puts "pid=#{Process.pid} Foo.getpid=#{Posix.getpid}"
+puts "Benchmark FFI getpid performance, #{iter}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < iter
+      Posix.getpid
+      i += 1
+    end
+  }
+}
+puts "Benchmark Process.pid performance, #{iter}x calls"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < iter
+      Process.pid
+      i += 1
+    end
+  }
+}
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_gettimeofday.rb b/app/server/vendor/ffi-1.9.10/bench/bench_gettimeofday.rb
new file mode 100755
index 0000000..1f85bbf
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_gettimeofday.rb
@@ -0,0 +1,51 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module Posix
+  extend FFI::Library
+  ffi_lib FFI::Library::LIBC
+
+  attach_function :gettimeofday, [ :buffer_out, :pointer ], :int
+end
+class Timeval < FFI::Struct
+  layout :tv_sec, :ulong, :tv_nsec, :ulong
+end
+
+iter = ITER
+puts "Benchmark FFI gettimeofday(2) (nil, nil) performance, #{iter}x"
+
+10.times {
+  puts Benchmark.measure {
+    iter.times { Posix.gettimeofday(nil, nil) }
+  }
+}
+puts "Benchmark FFI gettimeofday(2) (Timeval.alloc_out, nil) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { Posix.gettimeofday(Timeval.alloc_out, nil) }
+  }
+}
+puts "Benchmark FFI gettimeofday(2) (Timeval.new(FFI::MemoryPointer.new), nil) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { Posix.gettimeofday(Timeval.new(FFI::MemoryPointer.new(Timeval)), nil) }
+  }
+}
+puts "Benchmark FFI gettimeofday(2) (Timeval.new(FFI::Buffer.new), nil) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { Posix.gettimeofday(Timeval.new(FFI::Buffer.new(Timeval)), nil) }
+  }
+}
+puts "Benchmark FFI gettimeofday(2) (pre allocated pointer, nil) performance, #{iter}x"
+10.times {
+  t = Timeval.new FFI::MemoryPointer.new(Timeval)
+  puts Benchmark.measure {
+    iter.times { Posix.gettimeofday(t, nil) }
+  }
+}
+puts "Benchmark Time.now performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { Time.now }
+  }
+}
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_getuid.rb b/app/server/vendor/ffi-1.9.10/bench/bench_getuid.rb
new file mode 100755
index 0000000..103069a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_getuid.rb
@@ -0,0 +1,26 @@
+require 'benchmark'
+require 'ffi'
+
+iter = 100000
+
+module Posix
+  extend FFI::Library
+  ffi_lib FFI::Library::LIBC
+  attach_function :getuid, [], :uint
+end
+
+puts "uid=#{Process.pid} Posix.getuid=#{Posix.getuid}"
+puts "Benchmark FFI getuid performance, #{iter}x calls"
+
+10.times {
+  puts Benchmark.measure {
+    iter.times { Posix.getuid }
+  }
+}
+
+puts "Benchmark Process.uid performance, #{iter}x calls"
+10.times {
+  puts Benchmark.measure {
+    iter.times { Process.uid }
+  }
+}
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_helper.rb b/app/server/vendor/ffi-1.9.10/bench/bench_helper.rb
new file mode 100755
index 0000000..f3091b2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_helper.rb
@@ -0,0 +1,6 @@
+require "rubygems"
+#require 'ffi/times' if RUBY_PLATFORM =~ /java/
+require 'benchmark'
+require 'ffi'
+ITER = ENV['ITER'] ? ENV['ITER'].to_i : 100000
+LIBTEST_PATH = "#{Dir.getwd}/build/libtest.#{FFI::Platform::LIBSUFFIX}"
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_math.rb b/app/server/vendor/ffi-1.9.10/bench/bench_math.rb
new file mode 100755
index 0000000..e24168d
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_math.rb
@@ -0,0 +1,30 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module FFIMath
+  extend FFI::Library
+  ffi_lib 'm'
+  attach_function :cos, [ :double ], :double
+  attach_function :cosf, [ :float ], :float
+end
+if FFIMath.cos(0) != 1
+  raise ArgumentError, "FFI.cos returned incorrect value"
+end
+puts "Benchmark FFI cos(0) performance, #{ITER}x"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { FFIMath.cos(0) }
+  }
+}
+puts "Benchmark FFI cosf(0) performance, #{ITER}x"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { FFIMath.cosf(0) }
+  }
+}
+
+puts "Benchmark Math.cos(0) performance, #{ITER}x"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { Math.cos(0) }
+  }
+}
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_memptr_alloc.rb b/app/server/vendor/ffi-1.9.10/bench/bench_memptr_alloc.rb
new file mode 100755
index 0000000..ab78f28
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_memptr_alloc.rb
@@ -0,0 +1,62 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+require 'benchmark'
+require 'ffi'
+iter = ITER
+
+module LibC
+  extend FFI::Library
+  ffi_lib 'c'
+  attach_function :calloc, [ :size_t, :size_t ], :pointer, :save_errno => false
+  attach_function :free, [ :pointer ], :void, :save_errno => false
+end
+
+puts "Benchmark calloc(1, 4) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < iter
+      ptr = LibC.calloc(1, 4)
+      LibC.free(ptr)
+      i += 1
+    end
+  }
+}
+puts "Benchmark MemoryPointer.new(:int, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < iter
+      FFI::MemoryPointer.new(:int)
+      i += 1
+    end
+  }
+}
+puts "Benchmark MemoryPointer.new(4, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < iter
+      FFI::MemoryPointer.new(4, 1, true)
+      i += 1
+    end
+  }
+}
+[ 8, 16, 32, 64, 128, 256 ].each do |size|
+puts "Benchmark MemoryPointer.new(#{size}, 1, true)) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < iter
+      FFI::MemoryPointer.new(size, 1, true)
+      i += 1
+    end
+  }
+}
+end
+
+if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
+  require 'java'
+  puts "calling java gc"
+  10.times { 
+    java.lang.System.gc 
+    sleep 1
+  }
+end
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_memptr_fill.rb b/app/server/vendor/ffi-1.9.10/bench/bench_memptr_fill.rb
new file mode 100755
index 0000000..28efd6a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_memptr_fill.rb
@@ -0,0 +1,45 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+require 'benchmark'
+require 'ffi'
+iter = ITER
+
+puts "Benchmark MemoryPointer#put_array_of_float performance, #{iter}x"
+
+5.times {
+  ptr = FFI::MemoryPointer.new(:float, 8, false)
+  puts Benchmark.measure {
+    iter.times { 
+      ptr.put_array_of_float(0, [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8 ])
+    }
+  }
+}
+
+
+puts "Benchmark MemoryPointer.new(:float, 8, false)).put_array_of_float performance, #{iter}x"
+5.times {
+  puts Benchmark.measure {
+    iter.times { 
+      ptr = FFI::MemoryPointer.new(:float, 8, false)
+      ptr.put_array_of_float(0, [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8 ])
+    }
+  }
+}
+
+module LibTest
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+
+  attach_function :bench, :bench_P_v, [ :buffer_in ], :void
+end
+
+puts "Benchmark MemoryPointer alloc+fill+call performance, #{iter}x"
+5.times {
+  puts Benchmark.measure {
+    iter.times {
+      ptr = FFI::MemoryPointer.new(:float, 8, false)
+      ptr.put_array_of_float(0, [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8 ])
+      LibTest.bench(ptr)
+    }
+  }
+}
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_strlen.rb b/app/server/vendor/ffi-1.9.10/bench/bench_strlen.rb
new file mode 100755
index 0000000..424a8bf
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_strlen.rb
@@ -0,0 +1,26 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+module LibC
+  extend FFI::Library
+  ffi_lib 'c'
+  attach_function :strlen, [ :string ], :int
+end
+
+if LibC.strlen("test") != 4
+  raise ArgumentError, "FFI.strlen returned incorrect value"
+end
+
+
+puts "Benchmark FFI api strlen(3) performance, #{ITER}x"
+str = 'test' * 10
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibC.strlen(str) }
+  }
+}
+puts "Benchmark FFI api strlen(3), with new string performance, #{ITER}x"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { LibC.strlen('test' * 10) }
+  }
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_struct.rb b/app/server/vendor/ffi-1.9.10/bench/bench_struct.rb
new file mode 100755
index 0000000..47aac76
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_struct.rb
@@ -0,0 +1,62 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+require 'benchmark'
+require 'ffi'
+
+module StructBench
+  extend FFI::Library
+  extend FFI::Library
+  ffi_lib LIBTEST_PATH
+  attach_function :bench_s32_v, [ :int ], :void
+  begin
+    attach_function :bench_struct_in, :ptr_ret_int32_t, [ :buffer_in, :int ], :void
+  rescue FFI::NotFoundError
+    # NetBSD uses #define instead of typedef for these
+    attach_function :bench_struct_in, :ptr_ret___int32_t, [ :buffer_in, :int ], :void
+  end
+  begin
+    attach_function :bench_struct_out, :ptr_ret_int32_t, [ :buffer_out, :int ], :void
+  rescue FFI::NotFoundError
+    # NetBSD uses #define instead of typedef for these
+    attach_function :bench_struct_out, :ptr_ret___int32_t, [ :buffer_out, :int ], :void
+  end
+  begin
+    attach_function :bench_struct_inout, :ptr_ret_int32_t, [ :buffer_inout, :int ], :void
+  rescue FFI::NotFoundError
+    # NetBSD uses #define instead of typedef for these
+    attach_function :bench_struct_inout, :ptr_ret___int32_t, [ :buffer_inout, :int ], :void
+  end
+end
+class TestStruct < FFI::Struct
+  layout :i, :int, :p, :pointer
+end
+
+puts "Benchmark FFI call(Struct.alloc_in) performance, #{ITER}x"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      StructBench.bench_struct_in(TestStruct.alloc_in, 0)
+      i += 1
+    end
+  }
+}
+
+puts "Benchmark FFI call(Struct.alloc_out) performance, #{ITER}x"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      StructBench.bench_struct_out(TestStruct.alloc_out, 0)
+      i += 1
+    end
+  }
+}
+
+puts "Benchmark FFI call(Struct.alloc_inout) performance, #{ITER}x"
+10.times {
+  puts Benchmark.measure {
+    i = 0; while i < ITER
+      StructBench.bench_struct_inout(TestStruct.alloc_inout, 0)
+      i += 1
+    end
+  }
+}
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_struct_field.rb b/app/server/vendor/ffi-1.9.10/bench/bench_struct_field.rb
new file mode 100755
index 0000000..066dc63
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_struct_field.rb
@@ -0,0 +1,77 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+require 'benchmark'
+require 'ffi'
+iter = ITER
+
+class TestStruct < FFI::Struct
+  layout :i, :int, :p, :pointer
+end
+
+s = TestStruct.new(FFI::MemoryPointer.new(TestStruct))
+puts "Benchmark FFI Struct.get(:int) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    i = 0; max = iter / 4; while i < max
+      s[:i]
+      s[:i]
+      s[:i]
+      s[:i]
+      i += 1
+    end
+  }
+}
+
+puts "Benchmark FFI Struct.put(:int) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    i = 0; max = iter / 4; while i < max
+      s[:i] = 0x12345678
+      s[:i] = 0x12345678
+      s[:i] = 0x12345678
+      s[:i] = 0x12345678
+      i += 1
+    end
+  }
+}
+puts "Benchmark FFI Struct.get(:pointer) performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    i = 0; max = iter / 4; while i < max
+      s[:p]
+      s[:p]
+      s[:p]
+      s[:p]
+      i += 1
+    end
+  }
+}
+puts "Benchmark FFI Struct.put(:pointer) performance, #{iter}x"
+10.times {
+  p = FFI::MemoryPointer.new :int
+  puts Benchmark.measure {
+    i = 0; max = iter / 4; while i < max
+      s[:p] = p
+      s[:p] = p
+      s[:p] = p
+      s[:p] = p
+      i += 1
+    end
+  }
+}
+puts "Benchmark FFI Struct.get(:string) performance, #{iter}x"
+class StringStruct < FFI::Struct
+  layout :s, :string
+end
+10.times {
+  mp = FFI::MemoryPointer.new 1024
+  mp.put_string(0, "Hello, World")
+  s = StringStruct.new
+  s.pointer.put_pointer(0, mp)
+  puts Benchmark.measure {
+    i = 0; while i < iter
+      s[:s]
+      i += 1
+    end
+  }
+}
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_struct_size.rb b/app/server/vendor/ffi-1.9.10/bench/bench_struct_size.rb
new file mode 100755
index 0000000..5820d92
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_struct_size.rb
@@ -0,0 +1,33 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+require 'benchmark'
+require 'ffi'
+iter = ITER || 1000_000
+
+class TestStruct < FFI::Struct
+  layout :i, :int, :p, :pointer
+end
+
+puts "Benchmark FFI Struct class size performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { TestStruct.size }
+  }
+}
+
+s = TestStruct.new(FFI::MemoryPointer.new(TestStruct))
+puts "Benchmark FFI Struct instance size performance, #{iter}x"
+10.times {
+  puts Benchmark.measure {
+    iter.times { s.size }
+  }
+}
+
+puts "Benchmark FFI Struct layout size performance, #{iter}x"
+layout = TestStruct.layout
+10.times {
+  puts Benchmark.measure {
+    iter.times { layout.size }
+  }
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_time.rb b/app/server/vendor/ffi-1.9.10/bench/bench_time.rb
new file mode 100755
index 0000000..5967119
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_time.rb
@@ -0,0 +1,45 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module Posix
+  extend FFI::Library
+  ffi_lib FFI::Library::LIBC
+  attach_function :time, [ :buffer_out ], :ulong, :ignore_error => true
+end
+
+puts "Benchmark FFI time(3) with nil argument performance, #{ITER}x"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { Posix.time(nil) }
+  }
+}
+
+puts "Benchmark FFI time(3) with pre-allocated buffer performance, #{ITER}x"
+buf = FFI::Buffer.new(:time_t)
+10.times {
+  puts Benchmark.measure {
+    ITER.times { Posix.time(buf) }
+  }
+}
+
+
+puts "Benchmark FFI time(3) with loop-allocated buffer performance, #{ITER}x"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { Posix.time(FFI::Buffer.new(:time_t)) }
+  }
+}
+
+puts "Benchmark FFI time(3) with pre-allocated pointer performance, #{ITER}x"
+buf = FFI::MemoryPointer.new(:time_t)
+10.times {
+  puts Benchmark.measure {
+    ITER.times { Posix.time(buf) }
+  }
+}
+
+puts "Benchmark Time.now performance, #{ITER}x"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { Time.now }
+  }
+}
diff --git a/app/server/vendor/ffi-1.9.10/bench/bench_umask.rb b/app/server/vendor/ffi-1.9.10/bench/bench_umask.rb
new file mode 100755
index 0000000..220d79d
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/bench/bench_umask.rb
@@ -0,0 +1,60 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "bench_helper"))
+
+module Posix
+  extend FFI::Library
+  ffi_lib 'c'
+  attach_function 'umask', [ :int ], :int
+end
+module NativeFile
+  extend FFI::Library
+  ffi_lib 'c'
+  # Attaching the function to this module is about 10% faster than calling Posix.umask
+  if FFI::Platform.windows?
+    attach_function :_umask, '_umask', [ :int ], :int
+  else
+    attach_function :_umask, 'umask', [ :int ], :int
+  end
+  def self.umask(mask = nil)
+    if mask
+      _umask(mask)
+    else
+      old = _umask(0)
+      _umask(old)
+      old
+    end
+  end
+end
+puts "FFI umask=#{NativeFile.umask} File.umask=#{File.umask}"
+puts "Benchmark File.umask(0777) performance, #{ITER}x"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { File.umask(0777) }
+  }
+}
+puts "Benchmark FFI File.umask(0777) performance, #{ITER}x"
+
+10.times {
+  puts Benchmark.measure {
+    ITER.times { NativeFile.umask(0777) }
+  }
+}
+puts "Benchmark FFI Posix.umask(0777) performance, #{ITER}x"
+
+10.times {
+  puts Benchmark.measure {
+    ITER.times { Posix.umask(0777) }
+  }
+}
+puts "Benchmark File.umask() performance, #{ITER}x"
+10.times {
+  puts Benchmark.measure {
+    ITER.times { File.umask }
+  }
+}
+puts "Benchmark FFI File.umask() performance, #{ITER}x"
+
+10.times {
+  puts Benchmark.measure {
+    ITER.times { NativeFile.umask }
+  }
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/AbstractMemory.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/AbstractMemory.c
new file mode 100755
index 0000000..156d7cf
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/AbstractMemory.c
@@ -0,0 +1,1032 @@
+/*
+ * Copyright (c) 2008, 2009, Wayne Meissner
+ * Copyright (C) 2009 Jake Douglas <jake at shiftedlabs.com>
+ * Copyright (C) 2008 Luc Heinrich <luc at honk-honk.com>
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#ifndef _MSC_VER
+# include <sys/param.h>
+# include <stdint.h>
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+# include "win32/stdint.h"
+#endif
+
+#include <limits.h>
+#include <ruby.h>
+
+#include "rbffi.h"
+#include "compat.h"
+#include "AbstractMemory.h"
+#include "Pointer.h"
+#include "Function.h"
+#include "LongDouble.h"
+
+
+static inline char* memory_address(VALUE self);
+VALUE rbffi_AbstractMemoryClass = Qnil;
+static VALUE NullPointerErrorClass = Qnil;
+static ID id_to_ptr = 0, id_plus = 0, id_call = 0;
+
+static VALUE
+memory_allocate(VALUE klass)
+{
+    AbstractMemory* memory;
+    VALUE obj;
+    obj = Data_Make_Struct(klass, AbstractMemory, NULL, -1, memory);
+    memory->flags = MEM_RD | MEM_WR;
+
+    return obj;
+}
+#define VAL(x, swap) (unlikely(((memory->flags & MEM_SWAP) != 0)) ? swap((x)) : (x))
+
+#define NUM_OP(name, type, toNative, fromNative, swap) \
+static void memory_op_put_##name(AbstractMemory* memory, long off, VALUE value); \
+static void \
+memory_op_put_##name(AbstractMemory* memory, long off, VALUE value) \
+{ \
+    type tmp = (type) VAL(toNative(value), swap); \
+    checkWrite(memory); \
+    checkBounds(memory, off, sizeof(type)); \
+    memcpy(memory->address + off, &tmp, sizeof(tmp)); \
+} \
+static VALUE memory_put_##name(VALUE self, VALUE offset, VALUE value); \
+static VALUE \
+memory_put_##name(VALUE self, VALUE offset, VALUE value) \
+{ \
+    AbstractMemory* memory; \
+    Data_Get_Struct(self, AbstractMemory, memory); \
+    memory_op_put_##name(memory, NUM2LONG(offset), value); \
+    return self; \
+} \
+static VALUE memory_write_##name(VALUE self, VALUE value); \
+static VALUE \
+memory_write_##name(VALUE self, VALUE value) \
+{ \
+    AbstractMemory* memory; \
+    Data_Get_Struct(self, AbstractMemory, memory); \
+    memory_op_put_##name(memory, 0, value); \
+    return self; \
+} \
+static VALUE memory_op_get_##name(AbstractMemory* memory, long off); \
+static VALUE \
+memory_op_get_##name(AbstractMemory* memory, long off) \
+{ \
+    type tmp; \
+    checkRead(memory); \
+    checkBounds(memory, off, sizeof(type)); \
+    memcpy(&tmp, memory->address + off, sizeof(tmp)); \
+    return fromNative(VAL(tmp, swap)); \
+} \
+static VALUE memory_get_##name(VALUE self, VALUE offset); \
+static VALUE \
+memory_get_##name(VALUE self, VALUE offset) \
+{ \
+    AbstractMemory* memory; \
+    Data_Get_Struct(self, AbstractMemory, memory); \
+    return memory_op_get_##name(memory, NUM2LONG(offset)); \
+} \
+static VALUE memory_read_##name(VALUE self); \
+static VALUE \
+memory_read_##name(VALUE self) \
+{ \
+    AbstractMemory* memory; \
+    Data_Get_Struct(self, AbstractMemory, memory); \
+    return memory_op_get_##name(memory, 0); \
+} \
+static MemoryOp memory_op_##name = { memory_op_get_##name, memory_op_put_##name }; \
+\
+static VALUE memory_put_array_of_##name(VALUE self, VALUE offset, VALUE ary); \
+static VALUE \
+memory_put_array_of_##name(VALUE self, VALUE offset, VALUE ary) \
+{ \
+    long count = RARRAY_LEN(ary); \
+    long off = NUM2LONG(offset); \
+    AbstractMemory* memory = MEMORY(self); \
+    long i; \
+    checkWrite(memory); \
+    checkBounds(memory, off, count * sizeof(type)); \
+    for (i = 0; i < count; i++) { \
+        type tmp = (type) VAL(toNative(RARRAY_PTR(ary)[i]), swap); \
+        memcpy(memory->address + off + (i * sizeof(type)), &tmp, sizeof(tmp)); \
+    } \
+    return self; \
+} \
+static VALUE memory_write_array_of_##name(VALUE self, VALUE ary); \
+static VALUE \
+memory_write_array_of_##name(VALUE self, VALUE ary) \
+{ \
+    return memory_put_array_of_##name(self, INT2FIX(0), ary); \
+} \
+static VALUE memory_get_array_of_##name(VALUE self, VALUE offset, VALUE length); \
+static VALUE \
+memory_get_array_of_##name(VALUE self, VALUE offset, VALUE length) \
+{ \
+    long count = NUM2LONG(length); \
+    long off = NUM2LONG(offset); \
+    AbstractMemory* memory = MEMORY(self); \
+    VALUE retVal = rb_ary_new2(count); \
+    long i; \
+    checkRead(memory); \
+    checkBounds(memory, off, count * sizeof(type)); \
+    for (i = 0; i < count; ++i) { \
+        type tmp; \
+        memcpy(&tmp, memory->address + off + (i * sizeof(type)), sizeof(tmp)); \
+        rb_ary_push(retVal, fromNative(VAL(tmp, swap))); \
+    } \
+    return retVal; \
+} \
+static VALUE memory_read_array_of_##name(VALUE self, VALUE length); \
+static VALUE \
+memory_read_array_of_##name(VALUE self, VALUE length) \
+{ \
+    return memory_get_array_of_##name(self, INT2FIX(0), length); \
+}
+
+#define NOSWAP(x) (x)
+#define bswap16(x) (((x) >> 8) & 0xff) | (((x) << 8) & 0xff00);
+static inline int16_t
+SWAPS16(int16_t x)
+{
+    return bswap16(x);
+}
+
+static inline uint16_t
+SWAPU16(uint16_t x)
+{
+    return bswap16(x);
+}
+
+#if !defined(__GNUC__) || (__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)
+#define bswap32(x) \
+       (((x << 24) & 0xff000000) | \
+        ((x <<  8) & 0x00ff0000) | \
+        ((x >>  8) & 0x0000ff00) | \
+        ((x >> 24) & 0x000000ff))
+
+#define bswap64(x) \
+       (((x << 56) & 0xff00000000000000ULL) | \
+        ((x << 40) & 0x00ff000000000000ULL) | \
+        ((x << 24) & 0x0000ff0000000000ULL) | \
+        ((x <<  8) & 0x000000ff00000000ULL) | \
+        ((x >>  8) & 0x00000000ff000000ULL) | \
+        ((x >> 24) & 0x0000000000ff0000ULL) | \
+        ((x >> 40) & 0x000000000000ff00ULL) | \
+        ((x >> 56) & 0x00000000000000ffULL))
+
+static inline int32_t 
+SWAPS32(int32_t x)
+{
+    return bswap32(x);
+}
+
+static inline uint32_t 
+SWAPU32(uint32_t x)
+{
+    return bswap32(x);
+}
+
+static inline int64_t
+SWAPS64(int64_t x)
+{
+    return bswap64(x);
+}
+
+static inline uint64_t
+SWAPU64(uint64_t x)
+{
+    return bswap64(x);
+}
+
+#else
+# define SWAPS32(x) ((int32_t) __builtin_bswap32(x))
+# define SWAPU32(x) ((uint32_t) __builtin_bswap32(x))
+# define SWAPS64(x) ((int64_t) __builtin_bswap64(x))
+# define SWAPU64(x) ((uint64_t) __builtin_bswap64(x))
+#endif
+
+#if LONG_MAX > INT_MAX
+# define SWAPSLONG SWAPS64
+# define SWAPULONG SWAPU64
+#else
+# define SWAPSLONG SWAPS32
+# define SWAPULONG SWAPU32
+#endif
+
+NUM_OP(int8, int8_t, NUM2INT, INT2NUM, NOSWAP);
+NUM_OP(uint8, uint8_t, NUM2UINT, UINT2NUM, NOSWAP);
+NUM_OP(int16, int16_t, NUM2INT, INT2NUM, SWAPS16);
+NUM_OP(uint16, uint16_t, NUM2UINT, UINT2NUM, SWAPU16);
+NUM_OP(int32, int32_t, NUM2INT, INT2NUM, SWAPS32);
+NUM_OP(uint32, uint32_t, NUM2UINT, UINT2NUM, SWAPU32);
+NUM_OP(int64, int64_t, NUM2LL, LL2NUM, SWAPS64);
+NUM_OP(uint64, uint64_t, NUM2ULL, ULL2NUM, SWAPU64);
+NUM_OP(long, long, NUM2LONG, LONG2NUM, SWAPSLONG);
+NUM_OP(ulong, unsigned long, NUM2ULONG, ULONG2NUM, SWAPULONG);
+NUM_OP(float32, float, NUM2DBL, rb_float_new, NOSWAP);
+NUM_OP(float64, double, NUM2DBL, rb_float_new, NOSWAP);
+NUM_OP(longdouble, long double, rbffi_num2longdouble, rbffi_longdouble_new, NOSWAP);
+
+static inline void*
+get_pointer_value(VALUE value)
+{
+    const int type = TYPE(value);
+    if (type == T_DATA && rb_obj_is_kind_of(value, rbffi_PointerClass)) {
+        return memory_address(value);
+    } else if (type == T_NIL) {
+        return NULL;
+    } else if (type == T_FIXNUM) {
+        return (void *) (uintptr_t) FIX2ULONG(value);
+    } else if (type == T_BIGNUM) {
+        return (void *) (uintptr_t) NUM2ULL(value);
+    } else if (rb_respond_to(value, id_to_ptr)) {
+        return MEMORY_PTR(rb_funcall2(value, id_to_ptr, 0, NULL));
+    } else {
+        rb_raise(rb_eArgError, "value is not a pointer");
+        return NULL;
+    }
+}
+
+NUM_OP(pointer, void *, get_pointer_value, rbffi_Pointer_NewInstance, NOSWAP);
+
+static inline uint8_t
+rbffi_bool_value(VALUE value)
+{
+    return RTEST(value);
+}
+
+static inline VALUE
+rbffi_bool_new(uint8_t value)
+{
+    return (value & 1) != 0 ? Qtrue : Qfalse;
+}
+
+NUM_OP(bool, unsigned char, rbffi_bool_value, rbffi_bool_new, NOSWAP);
+
+
+/*
+ * call-seq: memory.clear
+ * Set the memory to all-zero.
+ * @return [self]
+ */
+static VALUE
+memory_clear(VALUE self)
+{
+    AbstractMemory* ptr = MEMORY(self);
+    memset(ptr->address, 0, ptr->size);
+    return self;
+}
+
+/*
+ * call-seq: memory.size
+ * Return memory size in bytes (alias: #total)
+ * @return [Numeric]
+ */
+static VALUE
+memory_size(VALUE self) 
+{
+    AbstractMemory* ptr;
+
+    Data_Get_Struct(self, AbstractMemory, ptr);
+
+    return LONG2NUM(ptr->size);
+}
+
+/*
+ * call-seq: memory.get_string(offset, length=nil)
+ * Return string contained in memory.
+ * @param [Numeric] offset point in buffer to start from
+ * @param [Numeric] length string's length in bytes. If nil, a (memory size - offset) length string is returned).
+ * @return [String]
+ * @raise {IndexError} if +length+ is too great
+ * @raise {NullPointerError} if memory not initialized
+ */
+static VALUE
+memory_get_string(int argc, VALUE* argv, VALUE self)
+{
+    VALUE length = Qnil, offset = Qnil;
+    AbstractMemory* ptr = MEMORY(self);
+    long off, len;
+    char* end;
+    int nargs = rb_scan_args(argc, argv, "11", &offset, &length);
+
+    off = NUM2LONG(offset);
+    len = nargs > 1 && length != Qnil ? NUM2LONG(length) : (ptr->size - off);
+    checkRead(ptr);
+    checkBounds(ptr, off, len);
+
+    end = memchr(ptr->address + off, 0, len);
+    return rb_tainted_str_new((char *) ptr->address + off,
+            (end != NULL ? end - ptr->address - off : len));
+}
+
+/*
+ * call-seq: memory.get_array_of_string(offset, count=nil)
+ * Return an array of strings contained in memory.
+ * @param [Numeric] offset point in memory to start from
+ * @param [Numeric] count number of strings to get. If nil, return all strings
+ * @return [Array<String>]
+ * @raise {IndexError} if +offset+ is too great
+ * @raise {NullPointerError} if memory not initialized
+ */
+static VALUE
+memory_get_array_of_string(int argc, VALUE* argv, VALUE self)
+{
+    VALUE offset = Qnil, countnum = Qnil, retVal = Qnil;
+    AbstractMemory* ptr;
+    long off;
+    int count;
+
+    rb_scan_args(argc, argv, "11", &offset, &countnum);
+    off = NUM2LONG(offset);
+    count = (countnum == Qnil ? 0 : NUM2INT(countnum));
+    retVal = rb_ary_new2(count);
+
+    Data_Get_Struct(self, AbstractMemory, ptr);
+    checkRead(ptr);
+
+    if (countnum != Qnil) {
+        int i;
+
+        checkBounds(ptr, off, count * sizeof (char*));
+        
+        for (i = 0; i < count; ++i) {
+            const char* strptr = *((const char**) (ptr->address + off) + i);
+            rb_ary_push(retVal, (strptr == NULL ? Qnil : rb_tainted_str_new2(strptr)));
+        }
+
+    } else {
+        checkBounds(ptr, off, sizeof (char*));
+        for ( ; off < ptr->size - (long) sizeof (void *); off += (long) sizeof (void *)) {
+            const char* strptr = *(const char**) (ptr->address + off);
+            if (strptr == NULL) {
+                break;
+            }
+            rb_ary_push(retVal, rb_tainted_str_new2(strptr));
+        }
+    }
+
+    return retVal;
+}
+
+/*
+ * call-seq: memory.read_array_of_string(count=nil)
+ * Return an array of strings contained in memory. Same as:
+ *  memory.get_array_of_string(0, count)
+ * @param [Numeric] count number of strings to get. If nil, return all strings
+ * @return [Array<String>]
+ */
+static VALUE 
+memory_read_array_of_string(int argc, VALUE* argv, VALUE self)
+{
+    VALUE* rargv = ALLOCA_N(VALUE, argc + 1);
+    int i;
+
+    rargv[0] = INT2FIX(0);
+    for (i = 0; i < argc; i++) {
+        rargv[i + 1] = argv[i];
+    }
+
+    return memory_get_array_of_string(argc + 1, rargv, self);
+}
+
+
+/*
+ * call-seq: memory.put_string(offset, str)
+ * @param [Numeric] offset
+ * @param [String] str
+ * @return [self]
+ * @raise {SecurityError} when writing unsafe string to memory
+ * @raise {IndexError} if +offset+ is too great
+ * @raise {NullPointerError} if memory not initialized
+ * Put a string in memory.
+ */
+static VALUE
+memory_put_string(VALUE self, VALUE offset, VALUE str)
+{
+    AbstractMemory* ptr = MEMORY(self);
+    long off, len;
+
+    Check_Type(str, T_STRING);
+    off = NUM2LONG(offset);
+    len = RSTRING_LEN(str);
+
+    checkWrite(ptr);
+    checkBounds(ptr, off, len + 1);
+
+    memcpy(ptr->address + off, RSTRING_PTR(str), len);
+    *((char *) ptr->address + off + len) = '\0';
+
+    return self;
+}
+
+/*
+ * call-seq: memory.get_bytes(offset, length)
+ * Return string contained in memory.
+ * @param [Numeric] offset point in buffer to start from
+ * @param [Numeric] length string's length in bytes.
+ * @return [String]
+ * @raise {IndexError} if +length+ is too great
+ * @raise {NullPointerError} if memory not initialized
+ */
+static VALUE
+memory_get_bytes(VALUE self, VALUE offset, VALUE length)
+{
+    AbstractMemory* ptr = MEMORY(self);
+    long off, len;
+    
+    off = NUM2LONG(offset);
+    len = NUM2LONG(length);
+
+    checkRead(ptr);
+    checkBounds(ptr, off, len);
+    
+    return rb_tainted_str_new((char *) ptr->address + off, len);
+}
+
+/*
+ * call-seq: memory.put_bytes(offset, str, index=0, length=nil)
+ * Put a string in memory.
+ * @param [Numeric] offset point in buffer to start from
+ * @param [String] str string to put to memory
+ * @param [Numeric] index
+ * @param [Numeric] length string's length in bytes. If nil, a (memory size - offset) length string is returned).
+ * @return [self]
+ * @raise {IndexError} if +length+ is too great
+ * @raise {NullPointerError} if memory not initialized
+ * @raise {RangeError} if +index+ is negative, or if index+length is greater than size of string
+ * @raise {SecurityError} when writing unsafe string to memory
+ */
+static VALUE
+memory_put_bytes(int argc, VALUE* argv, VALUE self)
+{
+    AbstractMemory* ptr = MEMORY(self);
+    VALUE offset = Qnil, str = Qnil, rbIndex = Qnil, rbLength = Qnil;
+    long off, len, idx;
+    int nargs = rb_scan_args(argc, argv, "22", &offset, &str, &rbIndex, &rbLength);
+
+    Check_Type(str, T_STRING);
+
+    off = NUM2LONG(offset);
+    idx = nargs > 2 ? NUM2LONG(rbIndex) : 0;
+    if (idx < 0) {
+        rb_raise(rb_eRangeError, "index canot be less than zero");
+        return Qnil;
+    }
+    len = nargs > 3 ? NUM2LONG(rbLength) : (RSTRING_LEN(str) - idx);
+    if ((idx + len) > RSTRING_LEN(str)) {
+        rb_raise(rb_eRangeError, "index+length is greater than size of string");
+        return Qnil;
+    }
+
+    checkWrite(ptr);
+    checkBounds(ptr, off, len);
+
+    if (rb_safe_level() >= 1 && OBJ_TAINTED(str)) {
+        rb_raise(rb_eSecurityError, "Writing unsafe string to memory");
+        return Qnil;
+    }
+    memcpy(ptr->address + off, RSTRING_PTR(str) + idx, len);
+
+    return self;
+}
+
+/*
+ * call-seq: memory.read_bytes(length)
+ * @param [Numeric] length of string to return
+ * @return [String]
+ * equivalent to :
+ *  memory.get_bytes(0, length)
+ */
+static VALUE 
+memory_read_bytes(VALUE self, VALUE length)
+{
+    return memory_get_bytes(self, INT2FIX(0), length);
+}
+
+/*
+ * call-seq: memory.write_bytes(str, index=0, length=nil)
+ * @param [String] str string to put to memory
+ * @param [Numeric] index
+ * @param [Numeric] length string's length in bytes. If nil, a (memory size - offset) length string is returned).
+ * @return [self]
+ * equivalent to :
+ *  memory.put_bytes(0, str, index, length)
+ */
+static VALUE 
+memory_write_bytes(int argc, VALUE* argv, VALUE self)
+{
+    VALUE* wargv = ALLOCA_N(VALUE, argc + 1);
+    int i;
+
+    wargv[0] = INT2FIX(0);
+    for (i = 0; i < argc; i++) {
+        wargv[i + 1] = argv[i];
+    }
+
+    return memory_put_bytes(argc + 1, wargv, self);
+}
+
+/*
+ * call-seq: memory.type_size
+ * @return [Numeric] type size in bytes
+ * Get the memory's type size.
+ */
+static VALUE
+memory_type_size(VALUE self)
+{
+    AbstractMemory* ptr;
+
+    Data_Get_Struct(self, AbstractMemory, ptr);
+
+    return INT2NUM(ptr->typeSize);
+}
+
+/*
+ * Document-method: []
+ * call-seq: memory[idx]
+ * @param [Numeric] idx index to access in memory
+ * @return 
+ * Memory read accessor.
+ */
+static VALUE
+memory_aref(VALUE self, VALUE idx)
+{
+    AbstractMemory* ptr;
+    VALUE rbOffset = Qnil;
+
+    Data_Get_Struct(self, AbstractMemory, ptr);
+
+    rbOffset = ULONG2NUM(NUM2ULONG(idx) * ptr->typeSize);
+
+    return rb_funcall2(self, id_plus, 1, &rbOffset);
+}
+
+static inline char*
+memory_address(VALUE obj)
+{
+    return ((AbstractMemory *) DATA_PTR(obj))->address;
+}
+
+static VALUE
+memory_copy_from(VALUE self, VALUE rbsrc, VALUE rblen)
+{
+    AbstractMemory* dst;
+
+    Data_Get_Struct(self, AbstractMemory, dst);
+
+    memcpy(dst->address, rbffi_AbstractMemory_Cast(rbsrc, rbffi_AbstractMemoryClass)->address, NUM2INT(rblen));
+
+    return self;
+}
+
+AbstractMemory*
+rbffi_AbstractMemory_Cast(VALUE obj, VALUE klass)
+{
+    if (rb_obj_is_kind_of(obj, klass)) {
+        AbstractMemory* memory;
+        Data_Get_Struct(obj, AbstractMemory, memory);
+        return memory;
+    }
+
+    rb_raise(rb_eArgError, "Invalid Memory object");
+    return NULL;
+}
+
+void
+rbffi_AbstractMemory_Error(AbstractMemory *mem, int op)
+{
+    VALUE rbErrorClass = mem->address == NULL ? NullPointerErrorClass : rb_eRuntimeError;
+    if (op == MEM_RD) {
+        rb_raise(rbErrorClass, "invalid memory read at address=%p", mem->address);
+    } else if (op == MEM_WR) {
+        rb_raise(rbErrorClass, "invalid memory write at address=%p", mem->address);
+    } else {
+        rb_raise(rbErrorClass, "invalid memory access at address=%p", mem->address);
+    }
+}
+
+static VALUE
+memory_op_get_strptr(AbstractMemory* ptr, long offset)
+{
+    void* tmp = NULL;
+
+    if (ptr != NULL && ptr->address != NULL) {
+        checkRead(ptr);
+        checkBounds(ptr, offset, sizeof(tmp));
+        memcpy(&tmp, ptr->address + offset, sizeof(tmp));
+    }
+
+    return tmp != NULL ? rb_tainted_str_new2(tmp) : Qnil;
+}
+
+static void
+memory_op_put_strptr(AbstractMemory* ptr, long offset, VALUE value)
+{
+    rb_raise(rb_eArgError, "Cannot set :string fields");
+}
+
+static MemoryOp memory_op_strptr = { memory_op_get_strptr, memory_op_put_strptr };
+
+
+MemoryOps rbffi_AbstractMemoryOps = {
+    &memory_op_int8, /*.int8 */
+    &memory_op_uint8, /* .uint8 */
+    &memory_op_int16, /* .int16 */
+    &memory_op_uint16, /* .uint16 */
+    &memory_op_int32, /* .int32 */
+    &memory_op_uint32, /* .uint32 */
+    &memory_op_int64, /* .int64 */
+    &memory_op_uint64, /* .uint64 */
+    &memory_op_long, /* .slong */
+    &memory_op_ulong, /* .uslong */
+    &memory_op_float32, /* .float32 */
+    &memory_op_float64, /* .float64 */
+    &memory_op_longdouble, /* .longdouble */
+    &memory_op_pointer, /* .pointer */
+    &memory_op_strptr, /* .strptr */
+    &memory_op_bool /* .boolOp */
+};
+
+void
+rbffi_AbstractMemory_Init(VALUE moduleFFI)
+{
+    /* 
+     * Document-class: FFI::AbstractMemory
+     * 
+     * {AbstractMemory} is the base class for many memory management classes such as {Buffer}.
+     *
+     * This class has a lot of methods to work with integers :
+     * * put_int<i>size</i>(offset, value)
+     * * get_int<i>size</i>(offset)
+     * * put_uint<i>size</i>(offset, value)
+     * * get_uint<i>size</i>(offset)
+     * * writeuint<i>size</i>(value)
+     * * read_int<i>size</i>
+     * * write_uint<i>size</i>(value)
+     * * read_uint<i>size</i>
+     * * put_array_of_int<i>size</i>(offset, ary)
+     * * get_array_of_int<i>size</i>(offset, length)
+     * * put_array_of_uint<i>size</i>(offset, ary)
+     * * get_array_of_uint<i>size</i>(offset, length)
+     * * write_array_of_int<i>size</i>(ary)
+     * * read_array_of_int<i>size</i>(length)
+     * * write_array_of_uint<i>size</i>(ary)
+     * * read_array_of_uint<i>size</i>(length)
+     * where _size_ is 8, 16, 32 or 64. Same methods exist for long type.
+     *
+     * Aliases exist : _char_ for _int8_, _short_ for _int16_, _int_ for _int32_ and <i>long_long</i> for _int64_.
+     *
+     * Others methods are listed below.
+     */
+    VALUE classMemory = rb_define_class_under(moduleFFI, "AbstractMemory", rb_cObject);
+    rbffi_AbstractMemoryClass = classMemory;
+    /* 
+     * Document-variable: FFI::AbstractMemory 
+     */
+    rb_global_variable(&rbffi_AbstractMemoryClass);
+    rb_define_alloc_func(classMemory, memory_allocate);
+
+    NullPointerErrorClass = rb_define_class_under(moduleFFI, "NullPointerError", rb_eRuntimeError);
+    /* Document-variable: NullPointerError */
+    rb_global_variable(&NullPointerErrorClass);
+
+
+#undef INT
+#define INT(type) \
+    rb_define_method(classMemory, "put_" #type, memory_put_##type, 2); \
+    rb_define_method(classMemory, "get_" #type, memory_get_##type, 1); \
+    rb_define_method(classMemory, "put_u" #type, memory_put_u##type, 2); \
+    rb_define_method(classMemory, "get_u" #type, memory_get_u##type, 1); \
+    rb_define_method(classMemory, "write_" #type, memory_write_##type, 1); \
+    rb_define_method(classMemory, "read_" #type, memory_read_##type, 0); \
+    rb_define_method(classMemory, "write_u" #type, memory_write_u##type, 1); \
+    rb_define_method(classMemory, "read_u" #type, memory_read_u##type, 0); \
+    rb_define_method(classMemory, "put_array_of_" #type, memory_put_array_of_##type, 2); \
+    rb_define_method(classMemory, "get_array_of_" #type, memory_get_array_of_##type, 2); \
+    rb_define_method(classMemory, "put_array_of_u" #type, memory_put_array_of_u##type, 2); \
+    rb_define_method(classMemory, "get_array_of_u" #type, memory_get_array_of_u##type, 2); \
+    rb_define_method(classMemory, "write_array_of_" #type, memory_write_array_of_##type, 1); \
+    rb_define_method(classMemory, "read_array_of_" #type, memory_read_array_of_##type, 1); \
+    rb_define_method(classMemory, "write_array_of_u" #type, memory_write_array_of_u##type, 1); \
+    rb_define_method(classMemory, "read_array_of_u" #type, memory_read_array_of_u##type, 1);
+    
+    INT(int8);
+    INT(int16);
+    INT(int32);
+    INT(int64);
+    INT(long);
+    
+#define ALIAS(name, old) \
+    rb_define_alias(classMemory, "put_" #name, "put_" #old); \
+    rb_define_alias(classMemory, "get_" #name, "get_" #old); \
+    rb_define_alias(classMemory, "put_u" #name, "put_u" #old); \
+    rb_define_alias(classMemory, "get_u" #name, "get_u" #old); \
+    rb_define_alias(classMemory, "write_" #name, "write_" #old); \
+    rb_define_alias(classMemory, "read_" #name, "read_" #old); \
+    rb_define_alias(classMemory, "write_u" #name, "write_u" #old); \
+    rb_define_alias(classMemory, "read_u" #name, "read_u" #old); \
+    rb_define_alias(classMemory, "put_array_of_" #name, "put_array_of_" #old); \
+    rb_define_alias(classMemory, "get_array_of_" #name, "get_array_of_" #old); \
+    rb_define_alias(classMemory, "put_array_of_u" #name, "put_array_of_u" #old); \
+    rb_define_alias(classMemory, "get_array_of_u" #name, "get_array_of_u" #old); \
+    rb_define_alias(classMemory, "write_array_of_" #name, "write_array_of_" #old); \
+    rb_define_alias(classMemory, "read_array_of_" #name, "read_array_of_" #old); \
+    rb_define_alias(classMemory, "write_array_of_u" #name, "write_array_of_u" #old); \
+    rb_define_alias(classMemory, "read_array_of_u" #name, "read_array_of_u" #old);
+    
+    ALIAS(char, int8);
+    ALIAS(short, int16);
+    ALIAS(int, int32);
+    ALIAS(long_long, int64);
+    
+    /*
+     * Document-method: put_float32
+     * call-seq: memory.put_float32offset, value)
+     * @param [Numeric] offset
+     * @param [Numeric] value
+     * @return [self]
+     * Put +value+ as a 32-bit float in memory at offset +offset+ (alias: #put_float).
+     */
+    rb_define_method(classMemory, "put_float32", memory_put_float32, 2);
+    /*
+     * Document-method: get_float32
+     * call-seq: memory.get_float32(offset)
+     * @param [Numeric] offset
+     * @return [Float]
+     * Get a 32-bit float from memory at offset +offset+ (alias: #get_float).
+     */
+    rb_define_method(classMemory, "get_float32", memory_get_float32, 1);
+    rb_define_alias(classMemory, "put_float", "put_float32");
+    rb_define_alias(classMemory, "get_float", "get_float32");
+    /*
+     * Document-method: write_float
+     * call-seq: memory.write_float(value)
+     * @param [Numeric] value
+     * @return [self]
+     * Write +value+ as a 32-bit float in memory.
+     *
+     * Same as:
+     *  memory.put_float(0, value)
+     */
+    rb_define_method(classMemory, "write_float", memory_write_float32, 1);
+    /*
+     * Document-method: read_float
+     * call-seq: memory.read_float
+     * @return [Float]
+     * Read a 32-bit float from memory.
+     *
+     * Same as:
+     *  memory.get_float(0)
+     */
+    rb_define_method(classMemory, "read_float", memory_read_float32, 0);
+    /*
+     * Document-method: put_array_of_float32
+     * call-seq: memory.put_array_of_float32(offset, ary)
+     * @param [Numeric] offset
+     * @param [Array<Numeric>] ary
+     * @return [self]
+     * Put values from +ary+ as 32-bit floats in memory from offset +offset+ (alias: #put_array_of_float).
+     */
+    rb_define_method(classMemory, "put_array_of_float32", memory_put_array_of_float32, 2);
+    /*
+     * Document-method: get_array_of_float32
+     * call-seq: memory.get_array_of_float32(offset, length)
+     * @param [Numeric] offset
+     * @param [Numeric] length number of Float to get
+     * @return [Array<Float>]
+     * Get 32-bit floats in memory from offset +offset+ (alias: #get_array_of_float).
+     */
+    rb_define_method(classMemory, "get_array_of_float32", memory_get_array_of_float32, 2);
+    /*
+     * Document-method: write_array_of_float
+     * call-seq: memory.write_array_of_float(ary)
+     * @param [Array<Numeric>] ary
+     * @return [self]
+     * Write values from +ary+ as 32-bit floats in memory.
+     *
+     * Same as:
+     *  memory.put_array_of_float(0, ary)
+     */
+    rb_define_method(classMemory, "write_array_of_float", memory_write_array_of_float32, 1);
+    /*
+     * Document-method: read_array_of_float
+     * call-seq: memory.read_array_of_float(length)
+     * @param [Numeric] length number of Float to read
+     * @return [Array<Float>]
+     * Read 32-bit floats from memory.
+     *
+     * Same as:
+     *  memory.get_array_of_float(0, ary)
+     */
+    rb_define_method(classMemory, "read_array_of_float", memory_read_array_of_float32, 1);
+    rb_define_alias(classMemory, "put_array_of_float", "put_array_of_float32");
+    rb_define_alias(classMemory, "get_array_of_float", "get_array_of_float32");
+    /*
+     * Document-method: put_float64
+     * call-seq: memory.put_float64(offset, value)
+     * @param [Numeric] offset
+     * @param [Numeric] value
+     * @return [self]
+     * Put +value+ as a 64-bit float (double) in memory at offset +offset+ (alias: #put_double).
+     */
+    rb_define_method(classMemory, "put_float64", memory_put_float64, 2);
+    /*
+     * Document-method: get_float64
+     * call-seq: memory.get_float64(offset)
+     * @param [Numeric] offset
+     * @return [Float]
+     * Get a 64-bit float (double) from memory at offset +offset+ (alias: #get_double).
+     */
+    rb_define_method(classMemory, "get_float64", memory_get_float64, 1);
+    rb_define_alias(classMemory, "put_double", "put_float64");
+    rb_define_alias(classMemory, "get_double", "get_float64");
+    /*
+     * Document-method: write_double
+     * call-seq: memory.write_double(value)
+     * @param [Numeric] value
+     * @return [self]
+     * Write +value+ as a 64-bit float (double) in memory.
+     *
+     * Same as:
+     *  memory.put_double(0, value)
+     */
+    rb_define_method(classMemory, "write_double", memory_write_float64, 1);
+    /*
+     * Document-method: read_double
+     * call-seq: memory.read_double
+     * @return [Float]
+     * Read a 64-bit float (double) from memory.
+     *
+     * Same as:
+     *  memory.get_double(0)
+     */
+    rb_define_method(classMemory, "read_double", memory_read_float64, 0);
+    /*
+     * Document-method: put_array_of_float64
+     * call-seq: memory.put_array_of_float64(offset, ary)
+     * @param [Numeric] offset
+     * @param [Array<Numeric>] ary
+     * @return [self]
+     * Put values from +ary+ as 64-bit floats (doubles) in memory from offset +offset+ (alias: #put_array_of_double).
+     */
+    rb_define_method(classMemory, "put_array_of_float64", memory_put_array_of_float64, 2);
+    /*
+     * Document-method: get_array_of_float64
+     * call-seq: memory.get_array_of_float64(offset, length)
+     * @param [Numeric] offset
+     * @param [Numeric] length number of Float to get
+     * @return [Array<Float>]
+     * Get 64-bit floats (doubles) in memory from offset +offset+ (alias: #get_array_of_double).
+     */
+    rb_define_method(classMemory, "get_array_of_float64", memory_get_array_of_float64, 2);
+    /*
+     * Document-method: write_array_of_double
+     * call-seq: memory.write_array_of_double(ary)
+     * @param [Array<Numeric>] ary
+     * @return [self]
+     * Write values from +ary+ as 64-bit floats (doubles) in memory.
+     *
+     * Same as:
+     *  memory.put_array_of_double(0, ary)
+     */
+    rb_define_method(classMemory, "write_array_of_double", memory_write_array_of_float64, 1);
+    /*
+     * Document-method: read_array_of_double
+     * call-seq: memory.read_array_of_double(length)
+     * @param [Numeric] length number of Float to read
+     * @return [Array<Float>]
+     * Read 64-bit floats (doubles) from memory.
+     *
+     * Same as:
+     *  memory.get_array_of_double(0, ary)
+     */
+    rb_define_method(classMemory, "read_array_of_double", memory_read_array_of_float64, 1);
+    rb_define_alias(classMemory, "put_array_of_double", "put_array_of_float64");
+    rb_define_alias(classMemory, "get_array_of_double", "get_array_of_float64");
+    /*
+     * Document-method: put_pointer
+     * call-seq: memory.put_pointer(offset, value)
+     * @param [Numeric] offset
+     * @param [nil,Pointer, Integer, #to_ptr] value
+     * @return [self]
+     * Put +value+ in memory from +offset+..
+     */
+    rb_define_method(classMemory, "put_pointer", memory_put_pointer, 2);
+    /*
+     * Document-method: get_pointer
+     * call-seq: memory.get_pointer(offset)
+     * @param [Numeric] offset
+     * @return [Pointer]
+     * Get a {Pointer} to the memory from +offset+.
+     */
+    rb_define_method(classMemory, "get_pointer", memory_get_pointer, 1);
+    /*
+     * Document-method: write_pointer
+     * call-seq: memory.write_pointer(value)
+     * @param [nil,Pointer, Integer, #to_ptr] value
+     * @return [self]
+     * Write +value+ in memory.
+     *
+     * Equivalent to:
+     *  memory.put_pointer(0, value)
+     */
+    rb_define_method(classMemory, "write_pointer", memory_write_pointer, 1);
+    /*
+     * Document-method: read_pointer
+     * call-seq: memory.read_pointer
+     * @return [Pointer]
+     * Get a {Pointer} to the memory from base address.
+     *
+     * Equivalent to:
+     *  memory.get_pointer(0)
+     */
+    rb_define_method(classMemory, "read_pointer", memory_read_pointer, 0);
+    /*
+     * Document-method: put_array_of_pointer
+     * call-seq: memory.put_array_of_pointer(offset, ary)
+     * @param [Numeric] offset
+     * @param [Array<#to_ptr>] ary
+     * @return [self]
+     * Put an array of {Pointer} into memory from +offset+.
+     */
+    rb_define_method(classMemory, "put_array_of_pointer", memory_put_array_of_pointer, 2);
+    /*
+     * Document-method: get_array_of_pointer
+     * call-seq: memory.get_array_of_pointer(offset, length)
+     * @param [Numeric] offset
+     * @param [Numeric] length
+     * @return [Array<Pointer>]
+     * Get an array of {Pointer} of length +length+ from +offset+.
+     */
+    rb_define_method(classMemory, "get_array_of_pointer", memory_get_array_of_pointer, 2);
+    /*
+     * Document-method: write_array_of_pointer
+     * call-seq: memory.write_array_of_pointer(ary)
+     * @param [Array<#to_ptr>] ary
+     * @return [self]
+     * Write an array of {Pointer} into memory from +offset+.
+     *
+     * Same as :
+     *  memory.put_array_of_pointer(0, ary)
+     */
+    rb_define_method(classMemory, "write_array_of_pointer", memory_write_array_of_pointer, 1);
+    /*
+     * Document-method: read_array_of_pointer
+     * call-seq: memory.read_array_of_pointer(length)
+     * @param [Numeric] length
+     * @return [Array<Pointer>]
+     * Read an array of {Pointer} of length +length+.
+     *
+     * Same as:
+     *  memory.get_array_of_pointer(0, length)
+     */
+    rb_define_method(classMemory, "read_array_of_pointer", memory_read_array_of_pointer, 1);
+
+    rb_define_method(classMemory, "get_string", memory_get_string, -1);
+    rb_define_method(classMemory, "put_string", memory_put_string, 2);
+    rb_define_method(classMemory, "get_bytes", memory_get_bytes, 2);
+    rb_define_method(classMemory, "put_bytes", memory_put_bytes, -1);
+    rb_define_method(classMemory, "read_bytes", memory_read_bytes, 1);
+    rb_define_method(classMemory, "write_bytes", memory_write_bytes, -1);
+    rb_define_method(classMemory, "get_array_of_string", memory_get_array_of_string, -1);
+
+    rb_define_method(classMemory, "clear", memory_clear, 0);
+    rb_define_method(classMemory, "total", memory_size, 0);
+    rb_define_alias(classMemory, "size", "total");
+    rb_define_method(classMemory, "type_size", memory_type_size, 0);
+    rb_define_method(classMemory, "[]", memory_aref, 1);
+    rb_define_method(classMemory, "__copy_from__", memory_copy_from, 2);
+
+    id_to_ptr = rb_intern("to_ptr");
+    id_call = rb_intern("call");
+    id_plus = rb_intern("+");
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/AbstractMemory.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/AbstractMemory.h
new file mode 100755
index 0000000..1119288
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/AbstractMemory.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2008, 2009, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_ABSTRACTMEMORY_H
+#define	RBFFI_ABSTRACTMEMORY_H
+
+#ifndef _MSC_VER
+#include <sys/param.h>
+#endif
+#include <sys/types.h>
+#ifndef _MSC_VER
+#include <stdint.h>
+#endif
+
+#include "compat.h"
+#include "Types.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+
+#define MEM_RD   0x01
+#define MEM_WR   0x02
+#define MEM_CODE 0x04
+#define MEM_SWAP 0x08
+#define MEM_EMBED 0x10
+
+typedef struct AbstractMemory_ AbstractMemory;
+
+typedef struct {
+    VALUE (*get)(AbstractMemory* ptr, long offset);
+    void (*put)(AbstractMemory* ptr, long offset, VALUE value);
+} MemoryOp;
+
+typedef struct {
+    MemoryOp* int8;
+    MemoryOp* uint8;
+    MemoryOp* int16;
+    MemoryOp* uint16;
+    MemoryOp* int32;
+    MemoryOp* uint32;
+    MemoryOp* int64;
+    MemoryOp* uint64;
+    MemoryOp* slong;
+    MemoryOp* uslong;
+    MemoryOp* float32;
+    MemoryOp* float64;
+    MemoryOp* longdouble;
+    MemoryOp* pointer;
+    MemoryOp* strptr;
+    MemoryOp* boolOp;
+} MemoryOps;
+
+struct AbstractMemory_ {
+    char* address; /* Use char* instead of void* to ensure adding to it works correctly */
+    long size;
+    int flags;
+    int typeSize;
+};
+
+
+extern VALUE rbffi_AbstractMemoryClass;
+extern MemoryOps rbffi_AbstractMemoryOps;
+
+extern void rbffi_AbstractMemory_Init(VALUE ffiModule);
+
+extern AbstractMemory* rbffi_AbstractMemory_Cast(VALUE obj, VALUE klass);
+
+extern void rbffi_AbstractMemory_Error(AbstractMemory *, int op);
+
+static inline void
+checkBounds(AbstractMemory* mem, long off, long len)
+{
+    if (unlikely((off | len | (off + len) | (mem->size - (off + len))) < 0)) {
+        rb_raise(rb_eIndexError, "Memory access offset=%ld size=%ld is out of bounds",
+                off, len);
+    }
+}
+
+static inline void
+checkRead(AbstractMemory* mem)
+{
+    if (unlikely((mem->flags & MEM_RD) == 0)) {
+        rbffi_AbstractMemory_Error(mem, MEM_RD);
+    }
+}
+
+static inline void
+checkWrite(AbstractMemory* mem)
+{
+    if (unlikely((mem->flags & MEM_WR) == 0)) {
+        rbffi_AbstractMemory_Error(mem, MEM_WR);
+    }
+}
+
+static inline MemoryOp*
+get_memory_op(Type* type)
+{
+    switch (type->nativeType) {
+        case NATIVE_INT8:
+            return rbffi_AbstractMemoryOps.int8;
+        case NATIVE_UINT8:
+            return rbffi_AbstractMemoryOps.uint8;
+        case NATIVE_INT16:
+            return rbffi_AbstractMemoryOps.int16;
+        case NATIVE_UINT16:
+            return rbffi_AbstractMemoryOps.uint16;
+        case NATIVE_INT32:
+            return rbffi_AbstractMemoryOps.int32;
+        case NATIVE_UINT32:
+            return rbffi_AbstractMemoryOps.uint32;
+        case NATIVE_INT64:
+            return rbffi_AbstractMemoryOps.int64;
+        case NATIVE_UINT64:
+            return rbffi_AbstractMemoryOps.uint64;
+        case NATIVE_LONG:
+            return rbffi_AbstractMemoryOps.slong;
+        case NATIVE_ULONG:
+            return rbffi_AbstractMemoryOps.uslong;
+        case NATIVE_FLOAT32:
+            return rbffi_AbstractMemoryOps.float32;
+        case NATIVE_FLOAT64:
+            return rbffi_AbstractMemoryOps.float64;
+        case NATIVE_LONGDOUBLE:
+            return rbffi_AbstractMemoryOps.longdouble;
+        case NATIVE_POINTER:
+            return rbffi_AbstractMemoryOps.pointer;
+        case NATIVE_STRING:
+            return rbffi_AbstractMemoryOps.strptr;
+        case NATIVE_BOOL:
+            return rbffi_AbstractMemoryOps.boolOp;
+        default:
+            return NULL;
+    }
+}
+
+#define MEMORY(obj) rbffi_AbstractMemory_Cast((obj), rbffi_AbstractMemoryClass)
+#define MEMORY_PTR(obj) MEMORY((obj))->address
+#define MEMORY_LEN(obj) MEMORY((obj))->size
+
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_ABSTRACTMEMORY_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/ArrayType.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/ArrayType.c
new file mode 100755
index 0000000..bfd666a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/ArrayType.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2009, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ruby.h>
+#include <ffi.h>
+#include "ArrayType.h"
+
+static VALUE array_type_s_allocate(VALUE klass);
+static VALUE array_type_initialize(VALUE self, VALUE rbComponentType, VALUE rbLength);
+static void array_type_mark(ArrayType *);
+static void array_type_free(ArrayType *);
+
+VALUE rbffi_ArrayTypeClass = Qnil;
+
+static VALUE
+array_type_s_allocate(VALUE klass)
+{
+    ArrayType* array;
+    VALUE obj;
+
+    obj = Data_Make_Struct(klass, ArrayType, array_type_mark, array_type_free, array);
+
+    array->base.nativeType = NATIVE_ARRAY;
+    array->base.ffiType = xcalloc(1, sizeof(*array->base.ffiType));
+    array->base.ffiType->type = FFI_TYPE_STRUCT;
+    array->base.ffiType->size = 0;
+    array->base.ffiType->alignment = 0;
+    array->rbComponentType = Qnil;
+
+    return obj;
+}
+
+static void
+array_type_mark(ArrayType *array)
+{
+    rb_gc_mark(array->rbComponentType);
+}
+
+static void
+array_type_free(ArrayType *array)
+{
+    xfree(array->base.ffiType);
+    xfree(array->ffiTypes);
+    xfree(array);
+}
+
+
+/*
+ * call-seq: initialize(component_type, length)
+ * @param [Type] component_type
+ * @param [Numeric] length
+ * @return [self]
+ * A new instance of ArrayType.
+ */
+static VALUE
+array_type_initialize(VALUE self, VALUE rbComponentType, VALUE rbLength)
+{
+    ArrayType* array;
+    int i;
+
+    Data_Get_Struct(self, ArrayType, array);
+
+    array->length = NUM2UINT(rbLength);
+    array->rbComponentType = rbComponentType;
+    Data_Get_Struct(rbComponentType, Type, array->componentType);
+    
+    array->ffiTypes = xcalloc(array->length + 1, sizeof(*array->ffiTypes));
+    array->base.ffiType->elements = array->ffiTypes;
+    array->base.ffiType->size = array->componentType->ffiType->size * array->length;
+    array->base.ffiType->alignment = array->componentType->ffiType->alignment;
+
+    for (i = 0; i < array->length; ++i) {
+        array->ffiTypes[i] = array->componentType->ffiType;
+    }
+
+    return self;
+}
+
+/*
+ * call-seq: length
+ * @return [Numeric]
+ * Get array's length
+ */
+static VALUE
+array_type_length(VALUE self)
+{
+    ArrayType* array;
+
+    Data_Get_Struct(self, ArrayType, array);
+
+    return UINT2NUM(array->length);
+}
+
+/*
+ * call-seq: element_type
+ * @return [Type]
+ * Get element type.
+ */
+static VALUE
+array_type_element_type(VALUE self)
+{
+    ArrayType* array;
+
+    Data_Get_Struct(self, ArrayType, array);
+
+    return array->rbComponentType;
+}
+
+void
+rbffi_ArrayType_Init(VALUE moduleFFI)
+{
+    VALUE ffi_Type;
+
+    ffi_Type = rbffi_TypeClass;
+
+    /*
+     * Document-class: FFI::ArrayType < FFI::Type
+     *
+     * This is a typed array. The type is a {NativeType native type}.
+     */
+    rbffi_ArrayTypeClass = rb_define_class_under(moduleFFI, "ArrayType", ffi_Type);
+    /*
+     * Document-variable: FFI::ArrayType
+     */
+    rb_global_variable(&rbffi_ArrayTypeClass);
+    /*
+     * Document-constant: FFI::Type::Array
+     */
+    rb_define_const(ffi_Type, "Array", rbffi_ArrayTypeClass);
+
+    rb_define_alloc_func(rbffi_ArrayTypeClass, array_type_s_allocate);
+    rb_define_method(rbffi_ArrayTypeClass, "initialize", array_type_initialize, 2);
+    rb_define_method(rbffi_ArrayTypeClass, "length", array_type_length, 0);
+    rb_define_method(rbffi_ArrayTypeClass, "elem_type", array_type_element_type, 0);
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/ArrayType.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/ArrayType.h
new file mode 100755
index 0000000..356ffb1
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/ArrayType.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2009, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_ARRAYTYPE_H
+#define	RBFFI_ARRAYTYPE_H
+
+#include <ruby.h>
+#include <ffi.h>
+#include "Type.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+
+typedef struct ArrayType_ {
+    Type base;
+    int length;
+    ffi_type** ffiTypes;
+    Type* componentType;
+    VALUE rbComponentType;
+} ArrayType;
+
+extern void rbffi_ArrayType_Init(VALUE moduleFFI);
+extern VALUE rbffi_ArrayTypeClass;
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_ARRAYTYPE_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Buffer.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Buffer.c
new file mode 100755
index 0000000..8ae3a59
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Buffer.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2008-2010 Wayne Meissner
+ * Copyright (C) 2009 Aman Gupta <aman at tmm1.net>
+ * 
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MSC_VER
+# include <stdint.h>
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+# include "win32/stdint.h"
+#endif
+#include <limits.h>
+#include <ruby.h>
+#include "rbffi.h"
+#include "rbffi_endian.h"
+#include "AbstractMemory.h"
+
+#define BUFFER_EMBED_MAXLEN (8)
+typedef struct Buffer {
+    AbstractMemory memory;
+    
+    union {
+        VALUE rbParent; /* link to parent buffer */
+        char* storage; /* start of malloc area */
+        long embed[BUFFER_EMBED_MAXLEN / sizeof(long)]; /* storage for tiny allocations */
+    } data;
+} Buffer;
+
+static VALUE buffer_allocate(VALUE klass);
+static VALUE buffer_initialize(int argc, VALUE* argv, VALUE self);
+static void buffer_release(Buffer* ptr);
+static void buffer_mark(Buffer* ptr);
+static VALUE buffer_free(VALUE self);
+
+static VALUE BufferClass = Qnil;
+
+static VALUE
+buffer_allocate(VALUE klass)
+{
+    Buffer* buffer;
+    VALUE obj;
+
+    obj = Data_Make_Struct(klass, Buffer, NULL, buffer_release, buffer);
+    buffer->data.rbParent = Qnil;
+    buffer->memory.flags = MEM_RD | MEM_WR;
+
+    return obj;
+}
+
+static void
+buffer_release(Buffer* ptr)
+{
+    if ((ptr->memory.flags & MEM_EMBED) == 0 && ptr->data.storage != NULL) {
+        xfree(ptr->data.storage);
+        ptr->data.storage = NULL;
+    }
+    
+    xfree(ptr);
+}
+
+/*
+ * call-seq: initialize(size, count=1, clear=false)
+ * @param [Integer, Symbol, #size] Type or size in bytes of a buffer cell
+ * @param [Fixnum] count number of cell in the Buffer
+ * @param [Boolean] clear if true, set the buffer to all-zero
+ * @return [self]
+ * @raise {NoMemoryError} if failed to allocate memory for Buffer
+ * A new instance of Buffer.
+ */
+static VALUE
+buffer_initialize(int argc, VALUE* argv, VALUE self)
+{
+    VALUE rbSize = Qnil, rbCount = Qnil, rbClear = Qnil;
+    Buffer* p;
+    int nargs;
+
+    Data_Get_Struct(self, Buffer, p);
+
+    nargs = rb_scan_args(argc, argv, "12", &rbSize, &rbCount, &rbClear);
+    p->memory.typeSize = rbffi_type_size(rbSize);
+    p->memory.size = p->memory.typeSize * (nargs > 1 ? NUM2LONG(rbCount) : 1);
+
+    if (p->memory.size > BUFFER_EMBED_MAXLEN) {
+        p->data.storage = xmalloc(p->memory.size + 7);
+        if (p->data.storage == NULL) {
+            rb_raise(rb_eNoMemError, "Failed to allocate memory size=%lu bytes", p->memory.size);
+            return Qnil;
+        }
+
+        /* ensure the memory is aligned on at least a 8 byte boundary */
+        p->memory.address = (void *) (((uintptr_t) p->data.storage + 0x7) & (uintptr_t) ~0x7UL);
+    
+        if (p->memory.size > 0 && (nargs < 3 || RTEST(rbClear))) {
+            memset(p->memory.address, 0, p->memory.size);
+        }
+    
+    } else {
+        p->memory.flags |= MEM_EMBED;
+        p->memory.address = (void *) &p->data.embed[0];
+    }
+
+    if (rb_block_given_p()) {
+        return rb_ensure(rb_yield, self, buffer_free, self);
+    }
+
+    return self;
+}
+
+/*
+ * call-seq: initialize_copy(other)
+ * @return [self]
+ * DO NOT CALL THIS METHOD.
+ */
+static VALUE
+buffer_initialize_copy(VALUE self, VALUE other)
+{
+    AbstractMemory* src;
+    Buffer* dst;
+    
+    Data_Get_Struct(self, Buffer, dst);
+    src = rbffi_AbstractMemory_Cast(other, BufferClass);
+    if ((dst->memory.flags & MEM_EMBED) == 0 && dst->data.storage != NULL) {
+        xfree(dst->data.storage);
+    }
+    dst->data.storage = xmalloc(src->size + 7);
+    if (dst->data.storage == NULL) {
+        rb_raise(rb_eNoMemError, "failed to allocate memory size=%lu bytes", src->size);
+        return Qnil;
+    }
+    
+    dst->memory.address = (void *) (((uintptr_t) dst->data.storage + 0x7) & (uintptr_t) ~0x7UL);
+    dst->memory.size = src->size;
+    dst->memory.typeSize = src->typeSize;
+    
+    /* finally, copy the actual buffer contents */
+    memcpy(dst->memory.address, src->address, src->size);
+
+    return self;
+}
+
+static VALUE
+buffer_alloc_inout(int argc, VALUE* argv, VALUE klass)
+{
+    return buffer_initialize(argc, argv, buffer_allocate(klass));
+}
+
+static VALUE
+slice(VALUE self, long offset, long len)
+{
+    Buffer* ptr;
+    Buffer* result;
+    VALUE obj = Qnil;
+    
+    Data_Get_Struct(self, Buffer, ptr);
+    checkBounds(&ptr->memory, offset, len);
+
+    obj = Data_Make_Struct(BufferClass, Buffer, buffer_mark, -1, result);
+    result->memory.address = ptr->memory.address + offset;
+    result->memory.size = len;
+    result->memory.flags = ptr->memory.flags;
+    result->memory.typeSize = ptr->memory.typeSize;
+    result->data.rbParent = self;
+
+    return obj;
+}
+
+/*
+ * call-seq: + offset
+ * @param [Numeric] offset
+ * @return [Buffer] a new instance of Buffer pointing from offset until end of previous buffer.
+ * Add a Buffer with an offset
+ */
+static VALUE
+buffer_plus(VALUE self, VALUE rbOffset)
+{
+    Buffer* ptr;
+    long offset = NUM2LONG(rbOffset);
+
+    Data_Get_Struct(self, Buffer, ptr);
+
+    return slice(self, offset, ptr->memory.size - offset);
+}
+
+/*
+ * call-seq: slice(offset, length)
+ * @param [Numeric] offset
+ * @param [Numeric] length
+ * @return [Buffer] a new instance of Buffer
+ * Slice an existing Buffer.
+ */
+static VALUE
+buffer_slice(VALUE self, VALUE rbOffset, VALUE rbLength)
+{
+    return slice(self, NUM2LONG(rbOffset), NUM2LONG(rbLength));
+}
+
+/*
+ * call-seq: inspect
+ * @return [String]
+ * Inspect a Buffer.
+ */
+static VALUE
+buffer_inspect(VALUE self)
+{
+    char tmp[100];
+    Buffer* ptr;
+
+    Data_Get_Struct(self, Buffer, ptr);
+
+    snprintf(tmp, sizeof(tmp), "#<FFI:Buffer:%p address=%p size=%ld>", ptr, ptr->memory.address, ptr->memory.size);
+    
+    return rb_str_new2(tmp);
+}
+
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+# define SWAPPED_ORDER BIG_ENDIAN
+#else
+# define SWAPPED_ORDER LITTLE_ENDIAN
+#endif
+
+/*
+ * Set or get endianness of Buffer.
+ * @overload order
+ *  @return [:big, :little]
+ *  Get endianness of Buffer.
+ * @overload order(order)
+ *  @param [:big, :little, :network] order
+ *  @return [self]
+ *  Set endinaness of Buffer (+:network+ is an alias for +:big+).
+ */
+static VALUE
+buffer_order(int argc, VALUE* argv, VALUE self)
+{
+    Buffer* ptr;
+
+    Data_Get_Struct(self, Buffer, ptr);
+    if (argc == 0) {
+        int order = (ptr->memory.flags & MEM_SWAP) == 0 ? BYTE_ORDER : SWAPPED_ORDER;
+        return order == BIG_ENDIAN ? ID2SYM(rb_intern("big")) : ID2SYM(rb_intern("little"));
+    } else {
+        VALUE rbOrder = Qnil;
+        int order = BYTE_ORDER;
+
+        if (rb_scan_args(argc, argv, "1", &rbOrder) < 1) {
+            rb_raise(rb_eArgError, "need byte order");
+        }
+        if (SYMBOL_P(rbOrder)) {
+            ID id = SYM2ID(rbOrder);
+            if (id == rb_intern("little")) {
+                order = LITTLE_ENDIAN;
+
+            } else if (id == rb_intern("big") || id == rb_intern("network")) {
+                order = BIG_ENDIAN;
+            }
+        }
+        if (order != BYTE_ORDER) {
+            Buffer* p2;
+            VALUE retval = slice(self, 0, ptr->memory.size);
+
+            Data_Get_Struct(retval, Buffer, p2);
+            p2->memory.flags |= MEM_SWAP;
+            return retval;
+        }
+
+        return self;
+    }
+}
+
+/* Only used to free the buffer if the yield in the initializer throws an exception */
+static VALUE
+buffer_free(VALUE self)
+{
+    Buffer* ptr;
+
+    Data_Get_Struct(self, Buffer, ptr);
+    if ((ptr->memory.flags & MEM_EMBED) == 0 && ptr->data.storage != NULL) {
+        xfree(ptr->data.storage);
+        ptr->data.storage = NULL;
+    }
+
+    return self;
+}
+
+static void
+buffer_mark(Buffer* ptr)
+{
+    rb_gc_mark(ptr->data.rbParent);
+}
+
+void
+rbffi_Buffer_Init(VALUE moduleFFI)
+{
+    VALUE ffi_AbstractMemory =  rbffi_AbstractMemoryClass;
+
+    /*
+     * Document-class: FFI::Buffer < FFI::AbstractMemory
+     *
+     * A Buffer is a function argument type. It should be use with functions playing with C arrays.
+     */
+    BufferClass = rb_define_class_under(moduleFFI, "Buffer", ffi_AbstractMemory);
+
+    /*
+     * Document-variable: FFI::Buffer
+     */
+    rb_global_variable(&BufferClass);
+    rb_define_alloc_func(BufferClass, buffer_allocate);
+
+    /*
+     * Document-method: alloc_inout
+     * call-seq: alloc_inout(*args)
+     * Create a new Buffer for in and out arguments (alias : <i>new_inout</i>).
+     */
+    rb_define_singleton_method(BufferClass, "alloc_inout", buffer_alloc_inout, -1);
+    /*
+     * Document-method: alloc_out
+     * call-seq: alloc_out(*args)
+     * Create a new Buffer for out arguments (alias : <i>new_out</i>).
+     */
+    rb_define_singleton_method(BufferClass, "alloc_out", buffer_alloc_inout, -1);
+    /*
+     * Document-method: alloc_in
+     * call-seq: alloc_in(*args)
+     * Create a new Buffer for in arguments (alias : <i>new_in</i>).
+     */
+    rb_define_singleton_method(BufferClass, "alloc_in", buffer_alloc_inout, -1);
+    rb_define_alias(rb_singleton_class(BufferClass), "new_in", "alloc_in");
+    rb_define_alias(rb_singleton_class(BufferClass), "new_out", "alloc_out");
+    rb_define_alias(rb_singleton_class(BufferClass), "new_inout", "alloc_inout");
+    
+    rb_define_method(BufferClass, "initialize", buffer_initialize, -1);
+    rb_define_method(BufferClass, "initialize_copy", buffer_initialize_copy, 1);
+    rb_define_method(BufferClass, "order", buffer_order, -1);
+    rb_define_method(BufferClass, "inspect", buffer_inspect, 0);
+    rb_define_alias(BufferClass, "length", "total");
+    rb_define_method(BufferClass, "+", buffer_plus, 1);
+    rb_define_method(BufferClass, "slice", buffer_slice, 2);
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Call.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Call.c
new file mode 100755
index 0000000..b028811
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Call.c
@@ -0,0 +1,530 @@
+/*
+ * Copyright (c) 2009, Wayne Meissner
+ * Copyright (c) 2009, Luc Heinrich <luc at honk-honk.com>
+ * Copyright (c) 2009, Mike Dalessio <mike.dalessio at gmail.com>
+ * Copyright (c) 2009, Aman Gupta.
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MSC_VER
+#include <sys/param.h>
+#endif
+#include <sys/types.h>
+#include <stdio.h>
+#ifndef _MSC_VER
+# include <stdint.h>
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+# include "win32/stdint.h"
+#endif
+#include <errno.h>
+#include <ruby.h>
+#if defined(HAVE_NATIVETHREAD) && (defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)) && !defined(_WIN32)
+#  include <signal.h>
+#  include <pthread.h>
+#endif
+#include <ffi.h>
+#include "extconf.h"
+#include "rbffi.h"
+#include "compat.h"
+#include "AbstractMemory.h"
+#include "Pointer.h"
+#include "Struct.h"
+#include "Function.h"
+#include "Type.h"
+#include "LastError.h"
+#include "Call.h"
+#include "MappedType.h"
+#include "Thread.h"
+#include "LongDouble.h"
+
+#ifdef USE_RAW
+#  ifndef __i386__
+#    error "RAW argument packing only supported on i386"
+#  endif
+
+#define INT8_ADJ (4)
+#define INT16_ADJ (4)
+#define INT32_ADJ (4)
+#define INT64_ADJ (8)
+#define LONG_ADJ (sizeof(long))
+#define FLOAT32_ADJ (4)
+#define FLOAT64_ADJ (8)
+#define ADDRESS_ADJ (sizeof(void *))
+#define LONGDOUBLE_ADJ (ffi_type_longdouble.alignment)
+
+#endif /* USE_RAW */
+
+#ifdef USE_RAW
+#  define ADJ(p, a) ((p) = (FFIStorage*) (((char *) p) + a##_ADJ))
+#else
+#  define ADJ(p, a) (++(p))
+#endif
+
+static void* callback_param(VALUE proc, VALUE cbinfo);
+static inline void* getPointer(VALUE value, int type);
+
+static ID id_to_ptr, id_map_symbol, id_to_native;
+
+void
+rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes,
+        FFIStorage* paramStorage, void** ffiValues,
+        VALUE* callbackParameters, int callbackCount, VALUE enums)
+{
+    VALUE callbackProc = Qnil;
+    FFIStorage* param = &paramStorage[0];
+    int i, argidx, cbidx, argCount;
+
+    if (unlikely(paramCount != -1 && paramCount != argc)) {
+        if (argc == (paramCount - 1) && callbackCount == 1 && rb_block_given_p()) {
+            callbackProc = rb_block_proc();
+        } else {
+            rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, paramCount);
+        }
+    }
+
+    argCount = paramCount != -1 ? paramCount : argc;
+
+    for (i = 0, argidx = 0, cbidx = 0; i < argCount; ++i) {
+        Type* paramType = paramTypes[i];
+        int type;
+
+        
+        if (unlikely(paramType->nativeType == NATIVE_MAPPED)) {
+            VALUE values[] = { argv[argidx], Qnil };
+            argv[argidx] = rb_funcall2(((MappedType *) paramType)->rbConverter, id_to_native, 2, values);
+            paramType = ((MappedType *) paramType)->type;
+        }
+
+        type = argidx < argc ? TYPE(argv[argidx]) : T_NONE;
+        ffiValues[i] = param;
+
+        switch (paramType->nativeType) {
+
+            case NATIVE_INT8:
+                if (unlikely(type == T_SYMBOL && enums != Qnil)) {
+                    VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]);
+                    param->s8 = NUM2INT(value);
+                } else {
+                    param->s8 = NUM2INT(argv[argidx]);
+                }
+
+                ++argidx;
+                ADJ(param, INT8);
+                break;
+
+            case NATIVE_INT16:
+                if (unlikely(type == T_SYMBOL && enums != Qnil)) {
+                    VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]);
+                    param->s16 = NUM2INT(value);
+
+                } else {
+                    param->s16 = NUM2INT(argv[argidx]);
+                }
+
+                ++argidx;
+                ADJ(param, INT16);
+                break;
+
+            case NATIVE_INT32:
+                if (unlikely(type == T_SYMBOL && enums != Qnil)) {
+                    VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]);
+                    param->s32 = NUM2INT(value);
+
+                } else {
+                    param->s32 = NUM2INT(argv[argidx]);
+                }
+
+                ++argidx;
+                ADJ(param, INT32);
+                break;
+
+            case NATIVE_BOOL:
+                if (type != T_TRUE && type != T_FALSE) {
+                    rb_raise(rb_eTypeError, "wrong argument type  (expected a boolean parameter)");
+                }
+                param->s8 = argv[argidx++] == Qtrue;
+                ADJ(param, INT8);
+                break;
+
+            case NATIVE_UINT8:
+                if (unlikely(type == T_SYMBOL && enums != Qnil)) {
+                    VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]);
+                    param->u8 = NUM2UINT(value);
+                } else {
+                    param->u8 = NUM2UINT(argv[argidx]);
+                }
+
+                ADJ(param, INT8);
+                ++argidx;
+                break;
+
+            case NATIVE_UINT16:
+                if (unlikely(type == T_SYMBOL && enums != Qnil)) {
+                    VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]);
+                    param->u16 = NUM2UINT(value);
+                } else {
+                    param->u16 = NUM2UINT(argv[argidx]);
+                }
+
+                ADJ(param, INT16);
+                ++argidx;
+                break;
+
+            case NATIVE_UINT32:
+                if (unlikely(type == T_SYMBOL && enums != Qnil)) {
+                    VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]);
+                    param->u32 = NUM2UINT(value);
+                } else {
+                    param->u32 = NUM2UINT(argv[argidx]);
+                }
+
+                ADJ(param, INT32);
+                ++argidx;
+                break;
+
+            case NATIVE_INT64:
+                if (unlikely(type == T_SYMBOL && enums != Qnil)) {
+                    VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]);
+                    param->i64 = NUM2LL(value);
+                } else {
+                    param->i64 = NUM2LL(argv[argidx]);
+                }
+
+                ADJ(param, INT64);
+                ++argidx;
+                break;
+
+            case NATIVE_UINT64:
+                if (unlikely(type == T_SYMBOL && enums != Qnil)) {
+                    VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]);
+                    param->u64 = NUM2ULL(value);
+                } else {
+                    param->u64 = NUM2ULL(argv[argidx]);
+                }
+
+                ADJ(param, INT64);
+                ++argidx;
+                break;
+
+            case NATIVE_LONG:
+                if (unlikely(type == T_SYMBOL && enums != Qnil)) {
+                    VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]);
+                    *(ffi_sarg *) param = NUM2LONG(value);
+                } else {
+                    *(ffi_sarg *) param = NUM2LONG(argv[argidx]);
+                }
+
+                ADJ(param, LONG);
+                ++argidx;
+                break;
+
+            case NATIVE_ULONG:
+                if (unlikely(type == T_SYMBOL && enums != Qnil)) {
+                    VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]);
+                    *(ffi_arg *) param = NUM2ULONG(value);
+                } else {
+                    *(ffi_arg *) param = NUM2ULONG(argv[argidx]);
+                }
+
+                ADJ(param, LONG);
+                ++argidx;
+                break;
+
+            case NATIVE_FLOAT32:
+                if (unlikely(type == T_SYMBOL && enums != Qnil)) {
+                    VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]);
+                    param->f32 = (float) NUM2DBL(value);
+                } else {
+                    param->f32 = (float) NUM2DBL(argv[argidx]);
+                }
+
+                ADJ(param, FLOAT32);
+                ++argidx;
+                break;
+
+            case NATIVE_FLOAT64:
+                if (unlikely(type == T_SYMBOL && enums != Qnil)) {
+                    VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]);
+                    param->f64 = NUM2DBL(value);
+                } else {
+                    param->f64 = NUM2DBL(argv[argidx]);
+                }
+
+                ADJ(param, FLOAT64);
+                ++argidx;
+                break;
+
+            case NATIVE_LONGDOUBLE:
+                if (unlikely(type == T_SYMBOL && enums != Qnil)) {
+                    VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]);
+                    param->ld = rbffi_num2longdouble(value);
+                } else {
+                    param->ld = rbffi_num2longdouble(argv[argidx]);
+                }
+
+                ADJ(param, LONGDOUBLE);
+                ++argidx;
+                break;
+
+
+            case NATIVE_STRING:
+                if (type == T_NIL) {
+                    param->ptr = NULL; 
+                
+                } else {
+                    if (rb_safe_level() >= 1 && OBJ_TAINTED(argv[argidx])) {
+                        rb_raise(rb_eSecurityError, "Unsafe string parameter");
+                    }
+
+                    param->ptr = StringValueCStr(argv[argidx]);
+                }
+
+                ADJ(param, ADDRESS);
+                ++argidx;
+                break;
+
+            case NATIVE_POINTER:
+            case NATIVE_BUFFER_IN:
+            case NATIVE_BUFFER_OUT:
+            case NATIVE_BUFFER_INOUT:
+                param->ptr = getPointer(argv[argidx++], type);
+                ADJ(param, ADDRESS);
+                break;
+
+
+            case NATIVE_FUNCTION:
+            case NATIVE_CALLBACK:
+                if (callbackProc != Qnil) {
+                    param->ptr = callback_param(callbackProc, callbackParameters[cbidx++]);
+                } else {
+                    param->ptr = callback_param(argv[argidx], callbackParameters[cbidx++]);
+                    ++argidx;
+                }
+                ADJ(param, ADDRESS);
+                break;
+
+            case NATIVE_STRUCT:
+                ffiValues[i] = getPointer(argv[argidx++], type);
+                break;
+
+            default:
+                rb_raise(rb_eArgError, "Invalid parameter type: %d", paramType->nativeType);
+        }
+    }
+}
+
+
+typedef struct BlockingCall_ {
+    rbffi_frame_t* frame;
+    void* function;
+    FunctionType* info;
+    void **ffiValues;
+    void* retval;
+    void* params;
+#if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
+    void* stkretval;
+#endif
+} BlockingCall;
+
+static VALUE
+call_blocking_function(void* data)
+{
+    BlockingCall* b = (BlockingCall *) data;
+    b->frame->has_gvl = false;
+    ffi_call(&b->info->ffi_cif, FFI_FN(b->function), b->retval, b->ffiValues);
+    b->frame->has_gvl = true;
+
+    return Qnil;
+}
+
+static VALUE
+do_blocking_call(void *data)
+{
+    rbffi_thread_blocking_region(call_blocking_function, data, (void *) -1, NULL);
+
+    return Qnil;
+}
+
+static VALUE
+save_frame_exception(void *data, VALUE exc)
+{
+    rbffi_frame_t* frame = (rbffi_frame_t *) data;
+    frame->exc = exc;
+    return Qnil;
+}
+
+VALUE
+rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
+{
+    void* retval;
+    void** ffiValues;
+    FFIStorage* params;
+    VALUE rbReturnValue;
+    rbffi_frame_t frame = { 0 };
+    
+    retval = alloca(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
+    
+    if (unlikely(fnInfo->blocking)) {
+        BlockingCall* bc;
+
+        /*
+         * due to the way thread switching works on older ruby variants, we
+         * cannot allocate anything passed to the blocking function on the stack
+         */
+#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
+        ffiValues = ALLOCA_N(void *, fnInfo->parameterCount);
+        params = ALLOCA_N(FFIStorage, fnInfo->parameterCount);
+        bc = ALLOCA_N(BlockingCall, 1);
+        bc->retval = retval;
+#else
+        ffiValues = ALLOC_N(void *, fnInfo->parameterCount);
+        params = ALLOC_N(FFIStorage, fnInfo->parameterCount);
+        bc = ALLOC_N(BlockingCall, 1);
+        bc->retval = xmalloc(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
+        bc->stkretval = retval;
+#endif
+        bc->info = fnInfo;
+        bc->function = function;
+        bc->ffiValues = ffiValues;
+        bc->params = params;
+        bc->frame = &frame;
+
+        rbffi_SetupCallParams(argc, argv,
+            fnInfo->parameterCount, fnInfo->parameterTypes, params, ffiValues,
+            fnInfo->callbackParameters, fnInfo->callbackCount, fnInfo->rbEnums);
+
+        rbffi_frame_push(&frame); 
+        rb_rescue2(do_blocking_call, (VALUE) bc, save_frame_exception, (VALUE) &frame, rb_eException, (VALUE) 0);
+        rbffi_frame_pop(&frame);
+
+#if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
+        memcpy(bc->stkretval, bc->retval, MAX(bc->info->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
+        xfree(bc->params);
+        xfree(bc->ffiValues);
+        xfree(bc->retval);
+        xfree(bc);
+#endif
+    
+    } else {
+
+        ffiValues = ALLOCA_N(void *, fnInfo->parameterCount);
+        params = ALLOCA_N(FFIStorage, fnInfo->parameterCount);
+
+        rbffi_SetupCallParams(argc, argv,
+            fnInfo->parameterCount, fnInfo->parameterTypes, params, ffiValues,
+            fnInfo->callbackParameters, fnInfo->callbackCount, fnInfo->rbEnums);
+
+        rbffi_frame_push(&frame);
+        ffi_call(&fnInfo->ffi_cif, FFI_FN(function), retval, ffiValues);
+        rbffi_frame_pop(&frame);
+    }
+
+    if (unlikely(!fnInfo->ignoreErrno)) {
+        rbffi_save_errno();
+    }    
+
+    if (RTEST(frame.exc) && frame.exc != Qnil) {
+        rb_exc_raise(frame.exc);
+    }
+
+    RB_GC_GUARD(rbReturnValue) = rbffi_NativeValue_ToRuby(fnInfo->returnType, fnInfo->rbReturnType, retval);
+    RB_GC_GUARD(fnInfo->rbReturnType);
+    
+    return rbReturnValue;
+}
+
+static inline void*
+getPointer(VALUE value, int type)
+{
+    if (likely(type == T_DATA && rb_obj_is_kind_of(value, rbffi_AbstractMemoryClass))) {
+
+        return ((AbstractMemory *) DATA_PTR(value))->address;
+
+    } else if (type == T_DATA && rb_obj_is_kind_of(value, rbffi_StructClass)) {
+
+        AbstractMemory* memory = ((Struct *) DATA_PTR(value))->pointer;
+        return memory != NULL ? memory->address : NULL;
+
+    } else if (type == T_STRING) {
+        
+        return StringValuePtr(value);
+
+    } else if (type == T_NIL) {
+
+        return NULL;
+
+    } else if (rb_respond_to(value, id_to_ptr)) {
+
+        VALUE ptr = rb_funcall2(value, id_to_ptr, 0, NULL);
+        if (rb_obj_is_kind_of(ptr, rbffi_AbstractMemoryClass) && TYPE(ptr) == T_DATA) {
+            return ((AbstractMemory *) DATA_PTR(ptr))->address;
+        }
+        rb_raise(rb_eArgError, "to_ptr returned an invalid pointer");
+    }
+
+    rb_raise(rb_eArgError, ":pointer argument is not a valid pointer");
+    return NULL;
+}
+
+Invoker
+rbffi_GetInvoker(FunctionType *fnInfo)
+{
+    return rbffi_CallFunction;
+}
+
+
+static void*
+callback_param(VALUE proc, VALUE cbInfo)
+{
+    VALUE callback ;
+    if (unlikely(proc == Qnil)) {
+        return NULL ;
+    }
+
+    /* Handle Function pointers here */
+    if (rb_obj_is_kind_of(proc, rbffi_FunctionClass)) {
+        AbstractMemory* ptr;
+        Data_Get_Struct(proc, AbstractMemory, ptr);
+        return ptr->address;
+    }
+
+    callback = rbffi_Function_ForProc(cbInfo, proc);
+    RB_GC_GUARD(callback);
+
+    return ((AbstractMemory *) DATA_PTR(callback))->address;
+}
+
+
+void
+rbffi_Call_Init(VALUE moduleFFI)
+{
+    id_to_ptr = rb_intern("to_ptr");
+    id_to_native = rb_intern("to_native");
+    id_map_symbol = rb_intern("__map_symbol");
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Call.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Call.h
new file mode 100755
index 0000000..0b971f2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Call.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2009, Wayne Meissner
+ * Copyright (c) 2009, Luc Heinrich <luc at honk-honk.com>
+ * Copyright (c) 2009, Mike Dalessio <mike.dalessio at gmail.com>
+ * Copyright (c) 2009, Aman Gupta.
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_CALL_H
+#define	RBFFI_CALL_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#if defined(__i386__) && \
+  (defined(HAVE_RAW_API) || defined(USE_INTERNAL_LIBFFI)) && \
+  !defined(_WIN32) && !defined(__WIN32__)
+#  define USE_RAW
+#endif
+
+#if (defined(__i386__) || defined(__x86_64__)) && !(defined(_WIN32) || defined(__WIN32__))
+#  define BYPASS_FFI 1
+#endif
+    
+typedef union {
+#ifdef USE_RAW
+    signed int s8, s16, s32;
+    unsigned int u8, u16, u32;
+#else
+    signed char s8;
+    unsigned char u8;
+    signed short s16;
+    unsigned short u16;
+    signed int s32;
+    unsigned int u32;
+#endif
+    signed long long i64;
+    unsigned long long u64;
+    signed long sl;
+    unsigned long ul;
+    void* ptr;
+    float f32;
+    double f64;
+    long double ld;
+} FFIStorage;
+ 
+extern void rbffi_Call_Init(VALUE moduleFFI);
+
+extern void rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes,
+        FFIStorage* paramStorage, void** ffiValues,
+        VALUE* callbackParameters, int callbackCount, VALUE enums);
+
+struct FunctionType_;
+extern VALUE rbffi_CallFunction(int argc, VALUE* argv, void* function, struct FunctionType_* fnInfo);
+
+typedef VALUE (*Invoker)(int argc, VALUE* argv, void* function, struct FunctionType_* fnInfo);
+
+Invoker rbffi_GetInvoker(struct FunctionType_* fnInfo);
+
+extern VALUE rbffi_GetEnumValue(VALUE enums, VALUE value);
+extern int rbffi_GetSignedIntValue(VALUE value, int type, int minValue, int maxValue, const char* typeName, VALUE enums);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_CALL_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/ClosurePool.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/ClosurePool.c
new file mode 100755
index 0000000..5499b40
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/ClosurePool.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2009, 2010 Wayne Meissner
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MSC_VER
+#include <sys/param.h>
+#endif
+#include <sys/types.h>
+#if defined(__CYGWIN__) || !defined(_WIN32)
+#  include <sys/mman.h>
+#endif
+#include <stdio.h>
+#ifndef _MSC_VER
+# include <stdint.h>
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+# include "win32/stdint.h"
+#endif
+#if defined(__CYGWIN__) || !defined(_WIN32)
+#  include <unistd.h>
+#else
+#  include <winsock2.h>
+#  define _WINSOCKAPI_
+#  include <windows.h>
+#endif
+#include <errno.h>
+#include <ruby.h>
+
+#if defined(_MSC_VER) && !defined(INT8_MIN)
+#  include "win32/stdint.h"
+#endif
+#include <ffi.h>
+#include "rbffi.h"
+#include "compat.h"
+
+#include "Function.h"
+#include "Types.h"
+#include "Type.h"
+#include "LastError.h"
+#include "Call.h"
+
+#include "ClosurePool.h"
+
+
+#ifndef roundup
+#  define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
+#endif
+#ifdef _WIN32
+  typedef char* caddr_t;
+#endif
+
+typedef struct Memory {
+    void* code;
+    void* data;
+    struct Memory* next;
+} Memory;
+
+struct ClosurePool_ {
+    void* ctx;
+    int closureSize;
+    bool (*prep)(void* ctx, void *code, Closure* closure, char* errbuf, size_t errbufsize);
+    struct Memory* blocks; /* Keeps track of all the allocated memory for this pool */
+    Closure* list;
+    long refcnt;
+};
+
+static long pageSize;
+
+static void* allocatePage(void);
+static bool freePage(void *);
+static bool protectPage(void *);
+
+ClosurePool*
+rbffi_ClosurePool_New(int closureSize, 
+        bool (*prep)(void* ctx, void *code, Closure* closure, char* errbuf, size_t errbufsize),
+        void* ctx)
+{
+    ClosurePool* pool;
+
+    pool = xcalloc(1, sizeof(*pool));
+    pool->closureSize = closureSize;
+    pool->ctx = ctx;
+    pool->prep = prep;
+    pool->refcnt = 1;
+    
+    return pool;
+}
+
+void
+cleanup_closure_pool(ClosurePool* pool)
+{
+    Memory* memory;
+    
+    for (memory = pool->blocks; memory != NULL; ) {
+        Memory* next = memory->next;
+        freePage(memory->code);
+        free(memory->data);
+        free(memory);
+        memory = next;
+    }
+    xfree(pool);
+}
+
+void
+rbffi_ClosurePool_Free(ClosurePool* pool)
+{
+    if (pool != NULL) {
+        long refcnt = --(pool->refcnt);
+        if (refcnt == 0) {
+            cleanup_closure_pool(pool);
+        }
+    }
+}
+
+Closure*
+rbffi_Closure_Alloc(ClosurePool* pool)
+{
+    Closure *list = NULL;
+    Memory* block = NULL;
+    caddr_t code = NULL;
+    char errmsg[256];
+    int nclosures;
+    long trampolineSize;
+    int i;
+
+    if (pool->list != NULL) {
+        Closure* closure = pool->list;
+        pool->list = pool->list->next;
+        pool->refcnt++;
+    
+        return closure;
+    }
+
+    trampolineSize = roundup(pool->closureSize, 8);
+    nclosures = (int) (pageSize / trampolineSize);
+    block = calloc(1, sizeof(*block));
+    list = calloc(nclosures, sizeof(*list));
+    code = allocatePage();
+    
+    if (block == NULL || list == NULL || code == NULL) {
+        snprintf(errmsg, sizeof(errmsg), "failed to allocate a page. errno=%d (%s)", errno, strerror(errno));
+        goto error;
+    }
+    
+    for (i = 0; i < nclosures; ++i) {
+        Closure* closure = &list[i];
+        closure->next = &list[i + 1];
+        closure->pool = pool;
+        closure->code = (code + (i * trampolineSize));
+
+        if (!(*pool->prep)(pool->ctx, closure->code, closure, errmsg, sizeof(errmsg))) {
+            goto error;
+        }
+    }
+
+    if (!protectPage(code)) {
+        goto error;
+    }
+
+    /* Track the allocated page + Closure memory area */
+    block->data = list;
+    block->code = code;
+    block->next = pool->blocks;
+    pool->blocks = block;
+
+    /* Thread the new block onto the free list, apart from the first one. */
+    list[nclosures - 1].next = pool->list;
+    pool->list = list->next;
+    pool->refcnt++;
+
+    /* Use the first one as the new handle */
+    return list;
+
+error:
+    free(block);
+    free(list);
+    if (code != NULL) {
+        freePage(code);
+    }
+    
+
+    rb_raise(rb_eRuntimeError, "%s", errmsg);
+    return NULL;
+}
+
+void
+rbffi_Closure_Free(Closure* closure)
+{
+    if (closure != NULL) {
+        ClosurePool* pool = closure->pool;
+        long refcnt;
+        /* Just push it on the front of the free list */
+        closure->next = pool->list;
+        pool->list = closure;
+        refcnt = --(pool->refcnt);
+        if (refcnt == 0) {
+            cleanup_closure_pool(pool);
+        }
+    }
+}
+
+void*
+rbffi_Closure_CodeAddress(Closure* handle)
+{
+    return handle->code;
+}
+
+
+static long
+getPageSize()
+{
+#if !defined(__CYGWIN__) && (defined(_WIN32) || defined(__WIN32__))
+    SYSTEM_INFO si;
+    GetSystemInfo(&si);
+    return si.dwPageSize;
+#else
+    return sysconf(_SC_PAGESIZE);
+#endif
+}
+
+static void*
+allocatePage(void)
+{
+#if !defined(__CYGWIN__) && (defined(_WIN32) || defined(__WIN32__))
+    return VirtualAlloc(NULL, pageSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+#else
+    caddr_t page = mmap(NULL, pageSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
+    return (page != (caddr_t) -1) ? page : NULL;
+#endif
+}
+
+static bool
+freePage(void *addr)
+{
+#if !defined(__CYGWIN__) && (defined(_WIN32) || defined(__WIN32__))
+    return VirtualFree(addr, 0, MEM_RELEASE);
+#else
+    return munmap(addr, pageSize) == 0;
+#endif
+}
+
+static bool
+protectPage(void* page)
+{
+#if !defined(__CYGWIN__) && (defined(_WIN32) || defined(__WIN32__))
+    DWORD oldProtect;
+    return VirtualProtect(page, pageSize, PAGE_EXECUTE_READ, &oldProtect);
+#else
+    return mprotect(page, pageSize, PROT_READ | PROT_EXEC) == 0;
+#endif
+}
+
+void
+rbffi_ClosurePool_Init(VALUE module)
+{
+    pageSize = getPageSize();
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/ClosurePool.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/ClosurePool.h
new file mode 100755
index 0000000..b842375
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/ClosurePool.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2009, 2010 Wayne Meissner
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RUBYFFI_CLOSUREPOOL_H
+#define RUBYFFI_CLOSUREPOOL_H
+
+typedef struct ClosurePool_ ClosurePool;
+typedef struct Closure_ Closure;
+
+struct Closure_ {
+    void* info;      /* opaque handle for storing closure-instance specific data */
+    void* function;  /* closure-instance specific function, called by custom trampoline */
+    void* code;      /* The native trampoline code location */
+    struct ClosurePool_* pool;
+    Closure* next;
+};
+
+void rbffi_ClosurePool_Init(VALUE module);
+
+ClosurePool* rbffi_ClosurePool_New(int closureSize, 
+        bool (*prep)(void* ctx, void *code, Closure* closure, char* errbuf, size_t errbufsize),
+        void* ctx);
+
+void rbffi_ClosurePool_Free(ClosurePool *);
+
+Closure* rbffi_Closure_Alloc(ClosurePool *);
+void rbffi_Closure_Free(Closure *);
+
+void* rbffi_Closure_GetCodeAddress(Closure *);
+
+#endif /* RUBYFFI_CLOSUREPOOL_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/DataConverter.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/DataConverter.c
new file mode 100755
index 0000000..2d5b827
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/DataConverter.c
@@ -0,0 +1,91 @@
+
+#include <ruby.h>
+
+#include <ffi.h>
+#include "rbffi.h"
+
+#include "Type.h"
+#include "MappedType.h"
+
+
+VALUE rbffi_DataConverterClass = Qnil;
+static ID id_native_type_ivar;
+
+/*
+ * Get native type.
+ * @overload native_type(type)
+ *  @param [String, Symbol, Type] type
+ *  @return [Type]
+ *  Get native type from +type+.
+ * @overload native_type
+ *  @raise {NotImplementedError} This method must be overriden.
+ */
+static VALUE
+conv_native_type(int argc, VALUE* argv, VALUE self)
+{
+    if (argc == 0) {
+        if (!rb_ivar_defined(self, id_native_type_ivar)) {
+            rb_raise(rb_eNotImpError, "native_type method not overridden and no native_type set");
+        }
+
+        return rb_ivar_get(self, id_native_type_ivar);
+
+    } else if (argc == 1) {
+        VALUE type = rbffi_Type_Find(argv[0]);
+
+        rb_ivar_set(self, id_native_type_ivar, type);
+
+        return type;
+
+    } else {
+        rb_raise(rb_eArgError, "incorrect arguments");
+    }
+}
+
+/*
+ * call-seq: to_native(value, ctx)
+ * @param value
+ * @param ctx
+ * @return [value]
+ * Convert to a native type.
+ */
+static VALUE
+conv_to_native(VALUE self, VALUE value, VALUE ctx)
+{
+    return value;
+}
+
+/*
+ * call-seq: from_native(value, ctx)
+ * @param value
+ * @param ctx
+ * @return [value]
+ * Convert from a native type.
+ */
+static VALUE
+conv_from_native(VALUE self, VALUE value, VALUE ctx)
+{
+    return value;
+}
+
+
+
+void
+rbffi_DataConverter_Init(VALUE moduleFFI)
+{
+    /*
+     * Document-module: FFI::DataConverter
+     * This module is used to extend somes classes and give then a common API.
+     *
+     * Most of methods defined here must be overriden.
+     */
+    rbffi_DataConverterClass = rb_define_module_under(moduleFFI, "DataConverter");
+
+    rb_define_method(rbffi_DataConverterClass, "native_type", conv_native_type, -1);
+    rb_define_method(rbffi_DataConverterClass, "to_native", conv_to_native, 2);
+    rb_define_method(rbffi_DataConverterClass, "from_native", conv_from_native, 2);
+
+    id_native_type_ivar = rb_intern("@native_type");
+}
+
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/DynamicLibrary.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/DynamicLibrary.c
new file mode 100755
index 0000000..905d020
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/DynamicLibrary.c
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2008-2010 Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#ifndef _MSC_VER
+#  include <stdint.h>
+#endif
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(__CYGWIN__)
+# include <winsock2.h>
+# define _WINSOCKAPI_
+# include <windows.h>
+#else
+# include <dlfcn.h>
+#endif
+#include <ruby.h>
+#if defined(_MSC_VER) && !defined(INT8_MIN)
+#  include "win32/stdint.h"
+#endif
+
+#include <ffi.h>
+
+#include "rbffi.h"
+#include "compat.h"
+#include "AbstractMemory.h"
+#include "Pointer.h"
+#include "DynamicLibrary.h"
+
+typedef struct LibrarySymbol_ {
+    Pointer base;
+    VALUE library;
+    VALUE name;
+} LibrarySymbol;
+
+static VALUE library_initialize(VALUE self, VALUE libname, VALUE libflags);
+static void library_free(Library* lib);
+
+
+static VALUE symbol_allocate(VALUE klass);
+static VALUE symbol_new(VALUE library, void* address, VALUE name);
+static void symbol_mark(LibrarySymbol* sym);
+
+static VALUE LibraryClass = Qnil, SymbolClass = Qnil;
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(__CYGWIN__)
+static void* dl_open(const char* name, int flags);
+static void dl_error(char* buf, int size);
+#define dl_sym(handle, name) GetProcAddress(handle, name)
+#define dl_close(handle) FreeLibrary(handle)
+#else
+# define dl_open(name, flags) dlopen(name, flags != 0 ? flags : RTLD_LAZY)
+# define dl_error(buf, size) do { snprintf(buf, size, "%s", dlerror()); } while(0)
+# define dl_sym(handle, name) dlsym(handle, name)
+# define dl_close(handle) dlclose(handle)
+#endif
+
+static VALUE
+library_allocate(VALUE klass)
+{
+    Library* library;
+    return Data_Make_Struct(klass, Library, NULL, library_free, library);
+}
+
+/*
+ * call-seq: DynamicLibrary.open(libname, libflags)
+ * @param libname (see #initialize)
+ * @param libflags (see #initialize)
+ * @return [FFI::DynamicLibrary]
+ * @raise {LoadError} if +libname+ cannot be opened
+ * Open a library.
+ */
+static VALUE
+library_open(VALUE klass, VALUE libname, VALUE libflags)
+{
+    return library_initialize(library_allocate(klass), libname, libflags);
+}
+
+/*
+ * call-seq: initialize(libname, libflags)
+ * @param [String] libname name of library to open
+ * @param [Fixnum] libflags flags for library to open
+ * @return [FFI::DynamicLibrary]
+ * @raise {LoadError} if +libname+ cannot be opened
+ * A new DynamicLibrary instance.
+ */
+static VALUE
+library_initialize(VALUE self, VALUE libname, VALUE libflags)
+{
+    Library* library;
+    int flags;
+
+    Check_Type(libflags, T_FIXNUM);
+
+    Data_Get_Struct(self, Library, library);
+    flags = libflags != Qnil ? NUM2UINT(libflags) : 0;
+    
+    library->handle = dl_open(libname != Qnil ? StringValueCStr(libname) : NULL, flags);
+    if (library->handle == NULL) {
+        char errmsg[1024];
+        dl_error(errmsg, sizeof(errmsg));
+        rb_raise(rb_eLoadError, "Could not open library '%s': %s",
+                libname != Qnil ? StringValueCStr(libname) : "[current process]",
+                errmsg);
+    }
+#ifdef __CYGWIN__
+    // On Cygwin 1.7.17 "dlsym(dlopen(0,0), 'getpid')" fails. (dlerror: "No such process")
+    // As a workaround we can use "dlsym(RTLD_DEFAULT, 'getpid')" instead.
+    // Since 0 == RTLD_DEFAULT we won't call dl_close later.
+    if (libname == Qnil) {
+        dl_close(library->handle);
+        library->handle = RTLD_DEFAULT;
+    }
+#endif
+    rb_iv_set(self, "@name", libname != Qnil ? libname : rb_str_new2("[current process]"));
+    return self;
+}
+
+static VALUE
+library_dlsym(VALUE self, VALUE name)
+{
+    Library* library;
+    void* address = NULL;
+    Check_Type(name, T_STRING);
+
+    Data_Get_Struct(self, Library, library);
+    address = dl_sym(library->handle, StringValueCStr(name));
+    
+    return address != NULL ? symbol_new(self, address, name) : Qnil;
+}
+
+/*
+ * call-seq: last_error
+ * @return [String] library's last error string
+ */
+static VALUE
+library_dlerror(VALUE self)
+{
+    char errmsg[1024];
+    dl_error(errmsg, sizeof(errmsg));
+    return rb_tainted_str_new2(errmsg);
+}
+
+static void
+library_free(Library* library)
+{
+    /* dlclose() on MacOS tends to segfault - avoid it */
+#ifndef __APPLE__
+    if (library->handle != NULL) {
+        dl_close(library->handle);
+    }
+#endif
+    xfree(library);
+}
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(__CYGWIN__)
+static void*
+dl_open(const char* name, int flags)
+{
+    if (name == NULL) {
+        return GetModuleHandle(NULL);
+    } else {
+        return LoadLibraryExA(name, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+    }
+}
+
+static void
+dl_error(char* buf, int size)
+{
+    FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
+            0, buf, size, NULL);
+}
+#endif
+
+static VALUE
+symbol_allocate(VALUE klass)
+{
+    LibrarySymbol* sym;
+    VALUE obj = Data_Make_Struct(klass, LibrarySymbol, NULL, -1, sym);
+    sym->name = Qnil;
+    sym->library = Qnil;
+    sym->base.rbParent = Qnil;
+
+    return obj;
+}
+
+
+/*
+ * call-seq: initialize_copy(other)
+ * @param [Object] other
+ * @return [nil]
+ * DO NOT CALL THIS METHOD
+ */
+static VALUE
+symbol_initialize_copy(VALUE self, VALUE other)
+{
+    rb_raise(rb_eRuntimeError, "cannot duplicate symbol");
+    return Qnil;
+}
+
+static VALUE
+symbol_new(VALUE library, void* address, VALUE name)
+{
+    LibrarySymbol* sym;
+    VALUE obj = Data_Make_Struct(SymbolClass, LibrarySymbol, symbol_mark, -1, sym);
+
+    sym->base.memory.address = address;
+    sym->base.memory.size = LONG_MAX;
+    sym->base.memory.typeSize = 1;
+    sym->base.memory.flags = MEM_RD | MEM_WR;
+    sym->library = library;
+    sym->name = name;
+
+    return obj;
+}
+
+static void
+symbol_mark(LibrarySymbol* sym)
+{
+    rb_gc_mark(sym->library);
+    rb_gc_mark(sym->name);
+}
+
+/*
+ * call-seq: inspect
+ * @return [String]
+ * Inspect.
+ */
+static VALUE
+symbol_inspect(VALUE self)
+{
+    LibrarySymbol* sym;
+    char buf[256];
+
+    Data_Get_Struct(self, LibrarySymbol, sym);
+    snprintf(buf, sizeof(buf), "#<FFI::Library::Symbol name=%s address=%p>",
+             StringValueCStr(sym->name), sym->base.memory.address);
+    return rb_str_new2(buf);
+}
+
+void
+rbffi_DynamicLibrary_Init(VALUE moduleFFI)
+{
+    /*
+     * Document-class: FFI::DynamicLibrary
+     */
+    LibraryClass = rb_define_class_under(moduleFFI, "DynamicLibrary", rb_cObject);
+    rb_global_variable(&LibraryClass);
+    /*
+     * Document-class: FFI::DynamicLibrary::Symbol < FFI::Pointer
+     *
+     * An instance of this class represents a library symbol. It may be a {Pointer pointer} to
+     * a function or to a variable.
+     */
+    SymbolClass = rb_define_class_under(LibraryClass, "Symbol", rbffi_PointerClass);
+    rb_global_variable(&SymbolClass);
+
+    /*
+     * Document-const: FFI::NativeLibrary
+     * Backward compatibility for FFI::DynamicLibrary
+     */
+    rb_define_const(moduleFFI, "NativeLibrary", LibraryClass); /* backwards compat library */
+    rb_define_alloc_func(LibraryClass, library_allocate);
+    rb_define_singleton_method(LibraryClass, "open", library_open, 2);
+    rb_define_singleton_method(LibraryClass, "last_error", library_dlerror, 0);
+    rb_define_method(LibraryClass, "initialize", library_initialize, 2);
+    /*
+     * Document-method: find_symbol
+     * call-seq: find_symbol(name)
+     * @param [String] name library symbol's name
+     * @return [FFI::DynamicLibrary::Symbol] library symbol
+     */
+    rb_define_method(LibraryClass, "find_symbol", library_dlsym, 1);
+    /*
+     * Document-method: find_function
+     * call-seq: find_function(name)
+     * @param [String] name library function's name
+     * @return [FFI::DynamicLibrary::Symbol] library function symbol
+     */
+    rb_define_method(LibraryClass, "find_function", library_dlsym, 1);
+    /*
+     * Document-method: find_variable
+     * call-seq: find_variable(name)
+     * @param [String] name library variable's name
+     * @return [FFI::DynamicLibrary::Symbol] library variable symbol
+     */
+    rb_define_method(LibraryClass, "find_variable", library_dlsym, 1);
+    rb_define_method(LibraryClass, "last_error", library_dlerror, 0);
+    rb_define_attr(LibraryClass, "name", 1, 0);
+
+    rb_define_alloc_func(SymbolClass, symbol_allocate);
+    rb_undef_method(SymbolClass, "new");
+    rb_define_method(SymbolClass, "inspect", symbol_inspect, 0);
+    rb_define_method(SymbolClass, "initialize_copy", symbol_initialize_copy, 1);
+
+#define DEF(x) rb_define_const(LibraryClass, "RTLD_" #x, UINT2NUM(RTLD_##x))
+    DEF(LAZY);
+    DEF(NOW);
+    DEF(GLOBAL);
+    DEF(LOCAL);
+    DEF(NOLOAD);
+    DEF(NODELETE);
+    DEF(FIRST);
+    DEF(DEEPBIND);
+    DEF(MEMBER);
+    DEF(BINDING_MASK);
+    DEF(LOCATION_MASK);
+    DEF(ALL_MASK);
+#undef DEF
+
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/DynamicLibrary.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/DynamicLibrary.h
new file mode 100755
index 0000000..97bf7bc
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/DynamicLibrary.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2008-2010 Wayne Meissner
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LIBRARY_H
+#define	_LIBRARY_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* if these aren't defined (eg. windows), we need sensible defaults */
+#ifndef RTLD_LAZY
+#define RTLD_LAZY 1
+#endif
+
+#ifndef RTLD_NOW
+#define RTLD_NOW 2
+#endif
+
+#ifndef RTLD_LOCAL
+#define RTLD_LOCAL 4
+#endif
+
+#ifndef RTLD_GLOBAL
+#define RTLD_GLOBAL 8
+#endif
+
+/* If these aren't defined, they're not supported so define as 0 */
+#ifndef RTLD_NOLOAD
+#define RTLD_NOLOAD 0
+#endif
+
+#ifndef RTLD_NODELETE
+#define RTLD_NODELETE 0
+#endif
+
+#ifndef RTLD_FIRST
+#define RTLD_FIRST 0
+#endif
+
+#ifndef RTLD_DEEPBIND
+#define RTLD_DEEPBIND 0
+#endif
+
+#ifndef RTLD_MEMBER
+#define RTLD_MEMBER 0
+#endif
+
+/* convenience */
+#ifndef RTLD_BINDING_MASK
+#define RTLD_BINDING_MASK (RTLD_LAZY | RTLD_NOW)
+#endif
+
+#ifndef RTLD_LOCATION_MASK
+#define RTLD_LOCATION_MASK (RTLD_LOCAL | RTLD_GLOBAL)
+#endif
+
+#ifndef RTLD_ALL_MASK
+#define RTLD_ALL_MASK (RTLD_BINDING_MASK | RTLD_LOCATION_MASK | RTLD_NOLOAD | RTLD_NODELETE | RTLD_FIRST | RTLD_DEEPBIND | RTLD_MEMBER)
+#endif
+
+typedef struct Library {
+    void* handle;
+} Library;
+
+extern void rbffi_DynamicLibrary_Init(VALUE ffiModule);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _LIBRARY_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Function.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Function.c
new file mode 100755
index 0000000..a18b1b3
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Function.c
@@ -0,0 +1,1000 @@
+/*
+ * Copyright (c) 2009-2011 Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MSC_VER
+#include <sys/param.h>
+#endif
+#include <sys/types.h>
+#ifndef _WIN32
+# include <sys/mman.h>
+# include <unistd.h>
+#endif
+
+#include <stdio.h>
+#ifndef _MSC_VER
+# include <stdint.h>
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+# if !defined(INT8_MIN)
+#  include "win32/stdint.h"
+# endif
+#endif
+#include <ruby.h>
+
+#include <ffi.h>
+#if defined(HAVE_NATIVETHREAD) && !defined(_WIN32)
+#include <pthread.h>
+#endif
+#include <fcntl.h>
+
+#include "rbffi.h"
+#include "compat.h"
+
+#include "AbstractMemory.h"
+#include "Pointer.h"
+#include "Struct.h"
+#include "Platform.h"
+#include "Type.h"
+#include "LastError.h"
+#include "Call.h"
+#include "ClosurePool.h"
+#include "MappedType.h"
+#include "Thread.h"
+#include "LongDouble.h"
+#include "MethodHandle.h"
+#include "Function.h"
+
+typedef struct Function_ {
+    Pointer base;
+    FunctionType* info;
+    MethodHandle* methodHandle;
+    bool autorelease;
+    Closure* closure;
+    VALUE rbProc;
+    VALUE rbFunctionInfo;
+} Function;
+
+static void function_mark(Function *);
+static void function_free(Function *);
+static VALUE function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc);
+static void callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data);
+static bool callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize);
+static void* callback_with_gvl(void* data);
+static VALUE invoke_callback(void* data);
+static VALUE save_callback_exception(void* data, VALUE exc);
+
+#define DEFER_ASYNC_CALLBACK 1
+
+
+#if defined(DEFER_ASYNC_CALLBACK)
+static VALUE async_cb_event(void *);
+static VALUE async_cb_call(void *);
+#endif
+
+#ifdef HAVE_RB_THREAD_CALL_WITH_GVL
+extern void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
+#endif
+
+VALUE rbffi_FunctionClass = Qnil;
+
+#if defined(DEFER_ASYNC_CALLBACK)
+static VALUE async_cb_thread = Qnil;
+#endif
+
+static ID id_call = 0, id_to_native = 0, id_from_native = 0, id_cbtable = 0, id_cb_ref = 0;
+
+struct gvl_callback {
+    Closure* closure;
+    void*    retval;
+    void**   parameters;
+    bool done;
+    rbffi_frame_t *frame;
+#if defined(DEFER_ASYNC_CALLBACK)
+    struct gvl_callback* next;
+# ifndef _WIN32
+    pthread_cond_t async_cond;
+    pthread_mutex_t async_mutex;
+# else
+    HANDLE async_event;
+# endif
+#endif
+};
+
+
+#if defined(DEFER_ASYNC_CALLBACK)
+static struct gvl_callback* async_cb_list = NULL;
+# ifndef _WIN32
+    static pthread_mutex_t async_cb_mutex = PTHREAD_MUTEX_INITIALIZER;
+    static pthread_cond_t async_cb_cond = PTHREAD_COND_INITIALIZER;
+#  if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
+    static int async_cb_pipe[2];
+#  endif
+# else
+    static HANDLE async_cb_cond;
+    static CRITICAL_SECTION async_cb_lock;
+#  if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
+    static int async_cb_pipe[2];
+#  endif
+# endif
+#endif
+
+
+static VALUE
+function_allocate(VALUE klass)
+{
+    Function *fn;
+    VALUE obj;
+
+    obj = Data_Make_Struct(klass, Function, function_mark, function_free, fn);
+
+    fn->base.memory.flags = MEM_RD;
+    fn->base.rbParent = Qnil;
+    fn->rbProc = Qnil;
+    fn->rbFunctionInfo = Qnil;
+    fn->autorelease = true;
+
+    return obj;
+}
+
+static void
+function_mark(Function *fn)
+{
+    rb_gc_mark(fn->base.rbParent);
+    rb_gc_mark(fn->rbProc);
+    rb_gc_mark(fn->rbFunctionInfo);
+}
+
+static void
+function_free(Function *fn)
+{
+    if (fn->methodHandle != NULL) {
+        rbffi_MethodHandle_Free(fn->methodHandle);
+    }
+
+    if (fn->closure != NULL && fn->autorelease) {
+        rbffi_Closure_Free(fn->closure);
+    }
+
+    xfree(fn);
+}
+
+/*
+ * @param [Type, Symbol] return_type return type for the function
+ * @param [Array<Type, Symbol>] param_types array of parameters types
+ * @param [Hash] options see {FFI::FunctionType} for available options
+ * @return [self]
+ * A new Function instance.
+ *
+ * Define a function from a Proc or a block.
+ *
+ * @overload initialize(return_type, param_types, options = {}) { |i| ... }
+ *  @yieldparam i parameters for the function
+ * @overload initialize(return_type, param_types, proc, options = {})
+ *  @param [Proc] proc
+ */
+static VALUE
+function_initialize(int argc, VALUE* argv, VALUE self)
+{
+    
+    VALUE rbReturnType = Qnil, rbParamTypes = Qnil, rbProc = Qnil, rbOptions = Qnil;
+    VALUE rbFunctionInfo = Qnil;
+    VALUE infoArgv[3];
+    int nargs;
+
+    nargs = rb_scan_args(argc, argv, "22", &rbReturnType, &rbParamTypes, &rbProc, &rbOptions);
+
+    /*
+     * Callback with block,
+     * e.g. Function.new(:int, [ :int ]) { |i| blah }
+     * or   Function.new(:int, [ :int ], { :convention => :stdcall }) { |i| blah }
+     */
+    if (rb_block_given_p()) {
+        if (nargs > 3) {
+            rb_raise(rb_eArgError, "cannot create function with both proc/address and block");
+        }
+        rbOptions = rbProc;
+        rbProc = rb_block_proc();
+    } else {
+        /* Callback with proc, or Function with address
+         * e.g. Function.new(:int, [ :int ], Proc.new { |i| })
+         *      Function.new(:int, [ :int ], Proc.new { |i| }, { :convention => :stdcall })
+         *      Function.new(:int, [ :int ], addr)
+         *      Function.new(:int, [ :int ], addr, { :convention => :stdcall })
+         */
+    }
+    
+    infoArgv[0] = rbReturnType;
+    infoArgv[1] = rbParamTypes;
+    infoArgv[2] = rbOptions;
+    rbFunctionInfo = rb_class_new_instance(rbOptions != Qnil ? 3 : 2, infoArgv, rbffi_FunctionTypeClass);
+
+    function_init(self, rbFunctionInfo, rbProc);
+    
+    return self;
+}
+
+/*
+ * call-seq: initialize_copy(other)
+ * @return [nil]
+ * DO NOT CALL THIS METHOD
+ */
+static VALUE
+function_initialize_copy(VALUE self, VALUE other)
+{
+    rb_raise(rb_eRuntimeError, "cannot duplicate function instances");
+    return Qnil;
+}
+
+VALUE
+rbffi_Function_NewInstance(VALUE rbFunctionInfo, VALUE rbProc)
+{
+    return function_init(function_allocate(rbffi_FunctionClass), rbFunctionInfo, rbProc);
+}
+
+VALUE
+rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc)
+{
+    VALUE callback, cbref, cbTable;
+    Function* fp;
+
+    cbref = RTEST(rb_ivar_defined(proc, id_cb_ref)) ? rb_ivar_get(proc, id_cb_ref) : Qnil;
+    /* If the first callback reference has the same function function signature, use it */
+    if (cbref != Qnil && CLASS_OF(cbref) == rbffi_FunctionClass) {
+        Data_Get_Struct(cbref, Function, fp);
+        if (fp->rbFunctionInfo == rbFunctionInfo) {
+            return cbref;
+        }
+    }
+    
+    cbTable = RTEST(rb_ivar_defined(proc, id_cbtable)) ? rb_ivar_get(proc, id_cbtable) : Qnil;
+    if (cbTable != Qnil && (callback = rb_hash_aref(cbTable, rbFunctionInfo)) != Qnil) {
+        return callback;
+    }
+    
+    /* No existing function for the proc with that signature, create a new one and cache it */
+    callback = rbffi_Function_NewInstance(rbFunctionInfo, proc);
+    if (cbref == Qnil) {
+        /* If there is no other cb already cached for this proc, we can use the ivar slot */
+        rb_ivar_set(proc, id_cb_ref, callback);
+    } else {
+        /* The proc instance has been used as more than one type of callback, store extras in a hash */
+        cbTable = rb_hash_new();
+        rb_ivar_set(proc, id_cbtable, cbTable);
+        rb_hash_aset(cbTable, rbFunctionInfo, callback);
+    }
+
+    return callback;
+}
+
+static VALUE
+function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
+{
+    Function* fn = NULL;
+    
+    Data_Get_Struct(self, Function, fn);
+
+    fn->rbFunctionInfo = rbFunctionInfo;
+
+    Data_Get_Struct(fn->rbFunctionInfo, FunctionType, fn->info);
+
+    if (rb_obj_is_kind_of(rbProc, rbffi_PointerClass)) {
+        Pointer* orig;
+        Data_Get_Struct(rbProc, Pointer, orig);
+        fn->base.memory = orig->memory;
+        fn->base.rbParent = rbProc;
+
+    } else if (rb_obj_is_kind_of(rbProc, rb_cProc) || rb_respond_to(rbProc, id_call)) {
+        if (fn->info->closurePool == NULL) {
+            fn->info->closurePool = rbffi_ClosurePool_New(sizeof(ffi_closure), callback_prep, fn->info);
+            if (fn->info->closurePool == NULL) {
+                rb_raise(rb_eNoMemError, "failed to create closure pool");
+            }
+        }
+
+#if defined(DEFER_ASYNC_CALLBACK)
+        if (async_cb_thread == Qnil) {
+#if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)) && defined(_WIN32)
+            _pipe(async_cb_pipe, 1024, O_BINARY);
+#elif !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
+            pipe(async_cb_pipe);
+            fcntl(async_cb_pipe[0], F_SETFL, fcntl(async_cb_pipe[0], F_GETFL) | O_NONBLOCK);
+            fcntl(async_cb_pipe[1], F_SETFL, fcntl(async_cb_pipe[1], F_GETFL) | O_NONBLOCK);
+#endif
+            async_cb_thread = rb_thread_create(async_cb_event, NULL);
+        }
+
+#endif
+
+        fn->closure = rbffi_Closure_Alloc(fn->info->closurePool);
+        fn->closure->info = fn;
+        fn->base.memory.address = fn->closure->code;
+        fn->base.memory.size = sizeof(*fn->closure);
+        fn->autorelease = true;
+
+    } else {
+        rb_raise(rb_eTypeError, "wrong argument type %s, expected pointer or proc",
+                rb_obj_classname(rbProc));
+    }
+    
+    fn->rbProc = rbProc;
+
+    return self;
+}
+
+/*
+ * call-seq: call(*args)
+ * @param [Array] args function arguments
+ * @return [FFI::Type]
+ * Call the function
+ */
+static VALUE
+function_call(int argc, VALUE* argv, VALUE self)
+{
+    Function* fn;
+
+    Data_Get_Struct(self, Function, fn);
+
+    return (*fn->info->invoke)(argc, argv, fn->base.memory.address, fn->info);
+}
+
+/*
+ * call-seq: attach(m, name)
+ * @param [Module] m
+ * @param [String] name
+ * @return [self]
+ * Attach a Function to the Module +m+ as +name+.
+ */
+static VALUE
+function_attach(VALUE self, VALUE module, VALUE name)
+{
+    Function* fn;
+    char var[1024];
+
+    Data_Get_Struct(self, Function, fn);
+
+    if (fn->info->parameterCount == -1) {
+        rb_raise(rb_eRuntimeError, "cannot attach variadic functions");
+        return Qnil;
+    }
+
+    if (!rb_obj_is_kind_of(module, rb_cModule)) {
+        rb_raise(rb_eRuntimeError, "trying to attach function to non-module");
+        return Qnil;
+    }
+
+    if (fn->methodHandle == NULL) {
+        fn->methodHandle = rbffi_MethodHandle_Alloc(fn->info, fn->base.memory.address);
+    }
+
+    /*
+     * Stash the Function in a module variable so it does not get garbage collected
+     */
+    snprintf(var, sizeof(var), "@@%s", StringValueCStr(name));
+    rb_cv_set(module, var, self);
+
+    rb_define_singleton_method(module, StringValueCStr(name),
+            rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
+
+    
+    rb_define_method(module, StringValueCStr(name),
+            rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
+
+    return self;
+}
+
+/*
+ * call-seq: autorelease = autorelease
+ * @param [Boolean] autorelease
+ * @return [self]
+ * Set +autorelease+ attribute (See {Pointer}).
+ */
+static VALUE
+function_set_autorelease(VALUE self, VALUE autorelease)
+{
+    Function* fn;
+
+    Data_Get_Struct(self, Function, fn);
+
+    fn->autorelease = RTEST(autorelease);
+
+    return self;
+}
+
+static VALUE
+function_autorelease_p(VALUE self)
+{
+    Function* fn;
+
+    Data_Get_Struct(self, Function, fn);
+
+    return fn->autorelease ? Qtrue : Qfalse;
+}
+
+/*
+ * call-seq: free
+ * @return [self]
+ * Free memory allocated by Function.
+ */
+static VALUE
+function_release(VALUE self)
+{
+    Function* fn;
+
+    Data_Get_Struct(self, Function, fn);
+
+    if (fn->closure == NULL) {
+        rb_raise(rb_eRuntimeError, "cannot free function which was not allocated");
+    }
+    
+    rbffi_Closure_Free(fn->closure);
+    fn->closure = NULL;
+    
+    return self;
+}
+
+static void
+callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
+{
+    struct gvl_callback cb = { 0 };
+    
+    cb.closure = (Closure *) user_data;
+    cb.retval = retval;
+    cb.parameters = parameters;
+    cb.done = false;
+    cb.frame = rbffi_frame_current();
+    
+    if (cb.frame != NULL) cb.frame->exc = Qnil;
+    if (cb.frame != NULL && cb.frame->has_gvl) {
+        callback_with_gvl(&cb);
+
+#if defined(HAVE_RB_THREAD_CALL_WITH_GVL)
+    } else if (cb.frame != NULL) {
+        rb_thread_call_with_gvl(callback_with_gvl, &cb);
+#endif
+#if defined(DEFER_ASYNC_CALLBACK) && !defined(_WIN32)
+    } else {
+        bool empty = false;
+
+        pthread_mutex_init(&cb.async_mutex, NULL);
+        pthread_cond_init(&cb.async_cond, NULL);
+
+        /* Now signal the async callback thread */
+        pthread_mutex_lock(&async_cb_mutex);
+        empty = async_cb_list == NULL;
+        cb.next = async_cb_list;
+        async_cb_list = &cb;
+
+#if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
+        pthread_mutex_unlock(&async_cb_mutex);
+        /* Only signal if the list was empty */
+        if (empty) {
+            char c;
+            write(async_cb_pipe[1], &c, 1);
+        }
+#else
+        pthread_cond_signal(&async_cb_cond);
+        pthread_mutex_unlock(&async_cb_mutex);
+#endif
+
+        /* Wait for the thread executing the ruby callback to signal it is done */
+        pthread_mutex_lock(&cb.async_mutex);
+        while (!cb.done) {
+            pthread_cond_wait(&cb.async_cond, &cb.async_mutex);
+        }
+        pthread_mutex_unlock(&cb.async_mutex);
+        pthread_cond_destroy(&cb.async_cond);
+        pthread_mutex_destroy(&cb.async_mutex);
+
+#elif defined(DEFER_ASYNC_CALLBACK) && defined(_WIN32)
+    } else {
+        bool empty = false;
+
+        cb.async_event = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+        /* Now signal the async callback thread */
+        EnterCriticalSection(&async_cb_lock);
+        empty = async_cb_list == NULL;
+        cb.next = async_cb_list;
+        async_cb_list = &cb;
+        LeaveCriticalSection(&async_cb_lock);
+
+#if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
+        /* Only signal if the list was empty */
+        if (empty) {
+            char c;
+            write(async_cb_pipe[1], &c, 1);
+        }
+#else
+        SetEvent(async_cb_cond);
+#endif
+
+        /* Wait for the thread executing the ruby callback to signal it is done */
+        WaitForSingleObject(cb.async_event, INFINITE);
+        CloseHandle(cb.async_event);
+#endif
+    }
+}
+
+#if defined(DEFER_ASYNC_CALLBACK)
+struct async_wait {
+    void* cb;
+    bool stop;
+};
+
+static VALUE async_cb_wait(void *);
+static void async_cb_stop(void *);
+
+#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
+static VALUE
+async_cb_event(void* unused)
+{
+    struct async_wait w = { 0 };
+
+    w.stop = false;
+    while (!w.stop) {
+#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
+        rb_thread_call_without_gvl(async_cb_wait, &w, async_cb_stop, &w);
+#else
+        rb_thread_blocking_region(async_cb_wait, &w, async_cb_stop, &w);
+#endif
+        if (w.cb != NULL) {
+            /* Start up a new ruby thread to run the ruby callback */
+            rb_thread_create(async_cb_call, w.cb);
+        }
+    }
+
+    return Qnil;
+}
+
+#elif defined(_WIN32)
+static VALUE
+async_cb_event(void* unused)
+{
+    while (true) {
+        struct gvl_callback* cb;
+        char buf[64];
+        fd_set rfds;
+
+        FD_ZERO(&rfds);
+        FD_SET(async_cb_pipe[0], &rfds);
+        rb_thread_select(async_cb_pipe[0] + 1, &rfds, NULL, NULL, NULL);
+        read(async_cb_pipe[0], buf, sizeof(buf));
+
+        EnterCriticalSection(&async_cb_lock);
+        cb = async_cb_list;
+        async_cb_list = NULL;
+        LeaveCriticalSection(&async_cb_lock);
+
+        while (cb != NULL) {
+            struct gvl_callback* next = cb->next;
+            /* Start up a new ruby thread to run the ruby callback */
+            rb_thread_create(async_cb_call, cb);
+            cb = next;
+        }
+    }
+
+    return Qnil;
+}
+#else
+static VALUE
+async_cb_event(void* unused)
+{
+    while (true) {
+        struct gvl_callback* cb;
+        char buf[64];
+
+        if (read(async_cb_pipe[0], buf, sizeof(buf)) < 0) {
+            rb_thread_wait_fd(async_cb_pipe[0]);
+            while (read(async_cb_pipe[0], buf, sizeof (buf)) < 0) {
+                if (rb_io_wait_readable(async_cb_pipe[0]) != Qtrue) {
+                    return Qfalse;
+                }
+            }
+        }
+
+        pthread_mutex_lock(&async_cb_mutex);
+        cb = async_cb_list;
+        async_cb_list = NULL;
+        pthread_mutex_unlock(&async_cb_mutex);
+
+        while (cb != NULL) {
+            struct gvl_callback* next = cb->next;
+            /* Start up a new ruby thread to run the ruby callback */
+            rb_thread_create(async_cb_call, cb);
+            cb = next;
+        }
+    }
+
+    return Qnil;
+}
+#endif
+
+#ifdef _WIN32
+static VALUE
+async_cb_wait(void *data)
+{
+    struct async_wait* w = (struct async_wait *) data;
+
+    w->cb = NULL;
+
+    EnterCriticalSection(&async_cb_lock);
+
+    while (!w->stop && async_cb_list == NULL) {
+        LeaveCriticalSection(&async_cb_lock);
+        WaitForSingleObject(async_cb_cond, INFINITE);
+        EnterCriticalSection(&async_cb_lock);
+    }
+    
+    if (async_cb_list != NULL) {
+        w->cb = async_cb_list;
+        async_cb_list = async_cb_list->next;
+    }
+
+    LeaveCriticalSection(&async_cb_lock);
+    
+    return Qnil;
+}
+
+static void
+async_cb_stop(void *data)
+{
+    struct async_wait* w = (struct async_wait *) data;
+
+    EnterCriticalSection(&async_cb_lock);
+    w->stop = true;
+    LeaveCriticalSection(&async_cb_lock);
+    SetEvent(async_cb_cond);
+}
+
+#else
+static VALUE
+async_cb_wait(void *data)
+{
+    struct async_wait* w = (struct async_wait *) data;
+
+    w->cb = NULL;
+
+    pthread_mutex_lock(&async_cb_mutex);
+
+    while (!w->stop && async_cb_list == NULL) {
+        pthread_cond_wait(&async_cb_cond, &async_cb_mutex);
+    }
+    
+    if (async_cb_list != NULL) {
+        w->cb = async_cb_list;
+        async_cb_list = async_cb_list->next;
+    }
+
+    pthread_mutex_unlock(&async_cb_mutex);
+    
+    return Qnil;
+}
+
+static void
+async_cb_stop(void *data)
+{
+    struct async_wait* w = (struct async_wait *) data;
+
+    pthread_mutex_lock(&async_cb_mutex);
+    w->stop = true;
+    pthread_cond_signal(&async_cb_cond);
+    pthread_mutex_unlock(&async_cb_mutex);
+}
+#endif
+
+static VALUE
+async_cb_call(void *data)
+{
+    struct gvl_callback* cb = (struct gvl_callback *) data;
+    
+    callback_with_gvl(data);
+        
+    /* Signal the original native thread that the ruby code has completed */
+#ifdef _WIN32
+    SetEvent(cb->async_event);
+#else
+    pthread_mutex_lock(&cb->async_mutex);
+    cb->done = true;
+    pthread_cond_signal(&cb->async_cond);
+    pthread_mutex_unlock(&cb->async_mutex);
+#endif
+
+    return Qnil;
+}
+
+#endif
+
+static void *
+callback_with_gvl(void* data)
+{
+    rb_rescue2(invoke_callback, (VALUE) data, save_callback_exception, (VALUE) data, rb_eException, (VALUE) 0);
+    return NULL;
+}
+
+static VALUE
+invoke_callback(void* data)
+{
+    struct gvl_callback* cb = (struct gvl_callback *) data;
+
+    Function* fn = (Function *) cb->closure->info;
+    FunctionType *cbInfo = fn->info;
+    Type* returnType = cbInfo->returnType;
+    void* retval = cb->retval;
+    void** parameters = cb->parameters;
+    VALUE* rbParams;
+    VALUE rbReturnType = cbInfo->rbReturnType;
+    VALUE rbReturnValue;
+    int i;
+
+    rbParams = ALLOCA_N(VALUE, cbInfo->parameterCount);
+    for (i = 0; i < cbInfo->parameterCount; ++i) {
+        VALUE param;
+        Type* paramType = cbInfo->parameterTypes[i];
+        VALUE rbParamType = rb_ary_entry(cbInfo->rbParameterTypes, i);
+
+        if (unlikely(paramType->nativeType == NATIVE_MAPPED)) {
+            rbParamType = ((MappedType *) paramType)->rbType;
+            paramType = ((MappedType *) paramType)->type;
+        }
+
+        switch (paramType->nativeType) {
+            case NATIVE_INT8:
+                param = INT2NUM(*(int8_t *) parameters[i]);
+                break;
+            case NATIVE_UINT8:
+                param = UINT2NUM(*(uint8_t *) parameters[i]);
+                break;
+            case NATIVE_INT16:
+                param = INT2NUM(*(int16_t *) parameters[i]);
+                break;
+            case NATIVE_UINT16:
+                param = UINT2NUM(*(uint16_t *) parameters[i]);
+                break;
+            case NATIVE_INT32:
+                param = INT2NUM(*(int32_t *) parameters[i]);
+                break;
+            case NATIVE_UINT32:
+                param = UINT2NUM(*(uint32_t *) parameters[i]);
+                break;
+            case NATIVE_INT64:
+                param = LL2NUM(*(int64_t *) parameters[i]);
+                break;
+            case NATIVE_UINT64:
+                param = ULL2NUM(*(uint64_t *) parameters[i]);
+                break;
+            case NATIVE_LONG:
+                param = LONG2NUM(*(long *) parameters[i]);
+                break;
+            case NATIVE_ULONG:
+                param = ULONG2NUM(*(unsigned long *) parameters[i]);
+                break;
+            case NATIVE_FLOAT32:
+                param = rb_float_new(*(float *) parameters[i]);
+                break;
+            case NATIVE_FLOAT64:
+                param = rb_float_new(*(double *) parameters[i]);
+                break;
+            case NATIVE_LONGDOUBLE:
+	      param = rbffi_longdouble_new(*(long double *) parameters[i]);
+                break;
+            case NATIVE_STRING:
+                param = (*(void **) parameters[i] != NULL) ? rb_tainted_str_new2(*(char **) parameters[i]) : Qnil;
+                break;
+            case NATIVE_POINTER:
+                param = rbffi_Pointer_NewInstance(*(void **) parameters[i]);
+                break;
+            case NATIVE_BOOL:
+                param = (*(uint8_t *) parameters[i]) ? Qtrue : Qfalse;
+                break;
+
+            case NATIVE_FUNCTION:
+            case NATIVE_CALLBACK:
+            case NATIVE_STRUCT:
+                param = rbffi_NativeValue_ToRuby(paramType, rbParamType, parameters[i]);
+                break;
+
+            default:
+                param = Qnil;
+                break;
+        }
+
+        /* Convert the native value into a custom ruby value */
+        if (unlikely(cbInfo->parameterTypes[i]->nativeType == NATIVE_MAPPED)) {
+            VALUE values[] = { param, Qnil };
+            param = rb_funcall2(((MappedType *) cbInfo->parameterTypes[i])->rbConverter, id_from_native, 2, values);
+        }
+
+        rbParams[i] = param;
+    }
+
+    rbReturnValue = rb_funcall2(fn->rbProc, id_call, cbInfo->parameterCount, rbParams);
+    RB_GC_GUARD_PTR(rbParams);
+    
+    if (unlikely(returnType->nativeType == NATIVE_MAPPED)) {
+        VALUE values[] = { rbReturnValue, Qnil };
+        rbReturnValue = rb_funcall2(((MappedType *) returnType)->rbConverter, id_to_native, 2, values);
+        rbReturnType = ((MappedType *) returnType)->rbType;
+        returnType = ((MappedType* ) returnType)->type;
+    }
+
+    if (rbReturnValue == Qnil || TYPE(rbReturnValue) == T_NIL) {
+        memset(retval, 0, returnType->ffiType->size);
+    } else switch (returnType->nativeType) {
+        case NATIVE_INT8:
+        case NATIVE_INT16:
+        case NATIVE_INT32:
+            *((ffi_sarg *) retval) = NUM2INT(rbReturnValue);
+            break;
+        case NATIVE_UINT8:
+        case NATIVE_UINT16:
+        case NATIVE_UINT32:
+            *((ffi_arg *) retval) = NUM2UINT(rbReturnValue);
+            break;
+        case NATIVE_INT64:
+            *((int64_t *) retval) = NUM2LL(rbReturnValue);
+            break;
+        case NATIVE_UINT64:
+            *((uint64_t *) retval) = NUM2ULL(rbReturnValue);
+            break;
+        case NATIVE_LONG:
+            *((ffi_sarg *) retval) = NUM2LONG(rbReturnValue);
+            break;
+        case NATIVE_ULONG:
+            *((ffi_arg *) retval) = NUM2ULONG(rbReturnValue);
+            break;
+        case NATIVE_FLOAT32:
+            *((float *) retval) = (float) NUM2DBL(rbReturnValue);
+            break;
+        case NATIVE_FLOAT64:
+            *((double *) retval) = NUM2DBL(rbReturnValue);
+            break;
+        case NATIVE_POINTER:
+            if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
+                *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address;
+            } else {
+                /* Default to returning NULL if not a value pointer object.  handles nil case as well */
+                *((void **) retval) = NULL;
+            }
+            break;
+
+        case NATIVE_BOOL:
+            *((ffi_arg *) retval) = rbReturnValue == Qtrue;
+            break;
+
+        case NATIVE_FUNCTION:
+        case NATIVE_CALLBACK:
+            if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
+
+                *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address;
+
+            } else if (rb_obj_is_kind_of(rbReturnValue, rb_cProc) || rb_respond_to(rbReturnValue, id_call)) {
+                VALUE function;
+
+                function = rbffi_Function_ForProc(rbReturnType, rbReturnValue);
+
+                *((void **) retval) = ((AbstractMemory *) DATA_PTR(function))->address;
+            } else {
+                *((void **) retval) = NULL;
+            }
+            break;
+
+        case NATIVE_STRUCT:
+            if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_StructClass)) {
+                AbstractMemory* memory = ((Struct *) DATA_PTR(rbReturnValue))->pointer;
+
+                if (memory->address != NULL) {
+                    memcpy(retval, memory->address, returnType->ffiType->size);
+
+                } else {
+                    memset(retval, 0, returnType->ffiType->size);
+                }
+                
+            } else {
+                memset(retval, 0, returnType->ffiType->size);
+            }
+            break;
+
+        default:
+            *((ffi_arg *) retval) = 0;
+            break;
+    }
+
+    return Qnil;
+}
+
+static VALUE 
+save_callback_exception(void* data, VALUE exc)
+{
+    struct gvl_callback* cb = (struct gvl_callback *) data;
+    
+    memset(cb->retval, 0, ((Function *) cb->closure->info)->info->returnType->ffiType->size);
+    if (cb->frame != NULL) cb->frame->exc = exc;
+    
+    return Qnil;
+}
+
+static bool
+callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize)
+{
+    FunctionType* fnInfo = (FunctionType *) ctx;
+    ffi_status ffiStatus;
+
+    ffiStatus = ffi_prep_closure(code, &fnInfo->ffi_cif, callback_invoke, closure);
+    if (ffiStatus != FFI_OK) {
+        snprintf(errmsg, errmsgsize, "ffi_prep_closure failed.  status=%#x", ffiStatus);
+        return false;
+    }
+
+    return true;
+}
+
+void
+rbffi_Function_Init(VALUE moduleFFI)
+{
+    rbffi_FunctionInfo_Init(moduleFFI);
+    /*
+     * Document-class: FFI::Function < FFI::Pointer
+     */
+    rbffi_FunctionClass = rb_define_class_under(moduleFFI, "Function", rbffi_PointerClass);
+    
+    rb_global_variable(&rbffi_FunctionClass);
+    rb_define_alloc_func(rbffi_FunctionClass, function_allocate);
+
+    rb_define_method(rbffi_FunctionClass, "initialize", function_initialize, -1);
+    rb_define_method(rbffi_FunctionClass, "initialize_copy", function_initialize_copy, 1);
+    rb_define_method(rbffi_FunctionClass, "call", function_call, -1);
+    rb_define_method(rbffi_FunctionClass, "attach", function_attach, 2);
+    rb_define_method(rbffi_FunctionClass, "free", function_release, 0);
+    rb_define_method(rbffi_FunctionClass, "autorelease=", function_set_autorelease, 1);
+    /*
+     * call-seq: autorelease
+     * @return [Boolean]
+     * Get +autorelease+ attribute.
+     * Synonymous for {#autorelease?}.
+     */
+    rb_define_method(rbffi_FunctionClass, "autorelease", function_autorelease_p, 0);
+    /*
+     * call-seq: autorelease?
+     * @return [Boolean] +autorelease+ attribute
+     * Get +autorelease+ attribute.
+     */
+    rb_define_method(rbffi_FunctionClass, "autorelease?", function_autorelease_p, 0);
+
+    id_call = rb_intern("call");
+    id_cbtable = rb_intern("@__ffi_callback_table__");
+    id_cb_ref = rb_intern("@__ffi_callback__");
+    id_to_native = rb_intern("to_native");
+    id_from_native = rb_intern("from_native");
+#if defined(_WIN32)
+    InitializeCriticalSection(&async_cb_lock);
+    async_cb_cond = CreateEvent(NULL, FALSE, FALSE, NULL);
+#endif
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Function.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Function.h
new file mode 100755
index 0000000..052aaf6
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Function.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2009, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_FUNCTION_H
+#define	RBFFI_FUNCTION_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifndef _MSC_VER
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+#endif
+
+#include <ffi.h>
+
+typedef struct FunctionType_ FunctionType;
+
+#include "Type.h"
+#include "Call.h"
+#include "ClosurePool.h"
+
+struct FunctionType_ {
+    Type type; /* The native type of a FunctionInfo object */
+    VALUE rbReturnType;
+    VALUE rbParameterTypes;
+
+    Type* returnType;
+    Type** parameterTypes;
+    NativeType* nativeParameterTypes;
+    ffi_type* ffiReturnType;
+    ffi_type** ffiParameterTypes;
+    ffi_cif ffi_cif;
+    Invoker invoke;
+    ClosurePool* closurePool;
+    int parameterCount;
+    int flags;
+    ffi_abi abi;
+    int callbackCount;
+    VALUE* callbackParameters;
+    VALUE rbEnums;
+    bool ignoreErrno;
+    bool blocking;
+    bool hasStruct;
+};
+
+extern VALUE rbffi_FunctionTypeClass, rbffi_FunctionClass;
+
+void rbffi_Function_Init(VALUE moduleFFI);
+VALUE rbffi_Function_NewInstance(VALUE functionInfo, VALUE proc);
+VALUE rbffi_Function_ForProc(VALUE cbInfo, VALUE proc);
+void rbffi_FunctionInfo_Init(VALUE moduleFFI);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_FUNCTION_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/FunctionInfo.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/FunctionInfo.c
new file mode 100755
index 0000000..8085c87
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/FunctionInfo.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2009, Wayne Meissner
+ * Copyright (C) 2009 Andrea Fazzi <andrea.fazzi at alcacoop.it>
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MSC_VER
+# include <sys/param.h>
+#endif
+#include <sys/types.h>
+#include <stdio.h>
+
+#ifndef _MSC_VER
+# include <stdint.h>
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+#endif
+
+#include <errno.h>
+#include <ruby.h>
+
+#include <ffi.h>
+#include "rbffi.h"
+#include "compat.h"
+
+#include "AbstractMemory.h"
+#include "Types.h"
+#include "Type.h"
+#include "StructByValue.h"
+#include "Function.h"
+
+static VALUE fntype_allocate(VALUE klass);
+static VALUE fntype_initialize(int argc, VALUE* argv, VALUE self);
+static void fntype_mark(FunctionType*);
+static void fntype_free(FunctionType *);
+
+VALUE rbffi_FunctionTypeClass = Qnil;
+
+static VALUE
+fntype_allocate(VALUE klass)
+{
+    FunctionType* fnInfo;
+    VALUE obj = Data_Make_Struct(klass, FunctionType, fntype_mark, fntype_free, fnInfo);
+
+    fnInfo->type.ffiType = &ffi_type_pointer;
+    fnInfo->type.nativeType = NATIVE_FUNCTION;
+    fnInfo->rbReturnType = Qnil;
+    fnInfo->rbParameterTypes = Qnil;
+    fnInfo->rbEnums = Qnil;
+    fnInfo->invoke = rbffi_CallFunction;
+    fnInfo->closurePool = NULL;
+
+    return obj;
+}
+
+static void
+fntype_mark(FunctionType* fnInfo)
+{
+    rb_gc_mark(fnInfo->rbReturnType);
+    rb_gc_mark(fnInfo->rbParameterTypes);
+    rb_gc_mark(fnInfo->rbEnums);
+    if (fnInfo->callbackCount > 0 && fnInfo->callbackParameters != NULL) {
+        rb_gc_mark_locations(&fnInfo->callbackParameters[0], &fnInfo->callbackParameters[fnInfo->callbackCount]);
+    }
+}
+
+static void
+fntype_free(FunctionType* fnInfo)
+{
+    xfree(fnInfo->parameterTypes);
+    xfree(fnInfo->ffiParameterTypes);
+    xfree(fnInfo->nativeParameterTypes);
+    xfree(fnInfo->callbackParameters);
+    if (fnInfo->closurePool != NULL) {
+        rbffi_ClosurePool_Free(fnInfo->closurePool);
+    }
+    xfree(fnInfo);
+}
+
+/*
+ * call-seq: initialize(return_type, param_types, options={})
+ * @param [Type, Symbol] return_type return type for the function
+ * @param [Array<Type, Symbol>] param_types array of parameters types
+ * @param [Hash] options
+ * @option options [Boolean] :blocking set to true if the C function is a blocking call
+ * @option options [Symbol] :convention calling convention see {FFI::Library#calling_convention}
+ * @option options [FFI::Enums] :enums
+ * @return [self]
+ * A new FunctionType instance.
+ */
+static VALUE
+fntype_initialize(int argc, VALUE* argv, VALUE self)
+{
+    FunctionType *fnInfo;
+    ffi_status status;
+    VALUE rbReturnType = Qnil, rbParamTypes = Qnil, rbOptions = Qnil;
+    VALUE rbEnums = Qnil, rbConvention = Qnil, rbBlocking = Qnil;
+#if defined(X86_WIN32)
+    VALUE rbConventionStr;
+#endif
+    int i, nargs;
+
+    nargs = rb_scan_args(argc, argv, "21", &rbReturnType, &rbParamTypes, &rbOptions);
+    if (nargs >= 3 && rbOptions != Qnil) {
+        rbConvention = rb_hash_aref(rbOptions, ID2SYM(rb_intern("convention")));
+        rbEnums = rb_hash_aref(rbOptions, ID2SYM(rb_intern("enums")));
+        rbBlocking = rb_hash_aref(rbOptions, ID2SYM(rb_intern("blocking")));
+    }
+
+    Check_Type(rbParamTypes, T_ARRAY);
+
+    Data_Get_Struct(self, FunctionType, fnInfo);
+    fnInfo->parameterCount = (int) RARRAY_LEN(rbParamTypes);
+    fnInfo->parameterTypes = xcalloc(fnInfo->parameterCount, sizeof(*fnInfo->parameterTypes));
+    fnInfo->ffiParameterTypes = xcalloc(fnInfo->parameterCount, sizeof(ffi_type *));
+    fnInfo->nativeParameterTypes = xcalloc(fnInfo->parameterCount, sizeof(*fnInfo->nativeParameterTypes));
+    fnInfo->rbParameterTypes = rb_ary_new2(fnInfo->parameterCount);
+    fnInfo->rbEnums = rbEnums;
+    fnInfo->blocking = RTEST(rbBlocking);
+    fnInfo->hasStruct = false;
+
+    for (i = 0; i < fnInfo->parameterCount; ++i) {
+        VALUE entry = rb_ary_entry(rbParamTypes, i);
+        VALUE type = rbffi_Type_Lookup(entry);
+
+        if (!RTEST(type)) {
+            VALUE typeName = rb_funcall2(entry, rb_intern("inspect"), 0, NULL);
+            rb_raise(rb_eTypeError, "Invalid parameter type (%s)", RSTRING_PTR(typeName));
+        }
+
+        if (rb_obj_is_kind_of(type, rbffi_FunctionTypeClass)) {
+            REALLOC_N(fnInfo->callbackParameters, VALUE, fnInfo->callbackCount + 1);
+            fnInfo->callbackParameters[fnInfo->callbackCount++] = type;
+        }
+
+        if (rb_obj_is_kind_of(type, rbffi_StructByValueClass)) {
+            fnInfo->hasStruct = true;
+        }
+
+        rb_ary_push(fnInfo->rbParameterTypes, type);
+        Data_Get_Struct(type, Type, fnInfo->parameterTypes[i]);
+        fnInfo->ffiParameterTypes[i] = fnInfo->parameterTypes[i]->ffiType;
+        fnInfo->nativeParameterTypes[i] = fnInfo->parameterTypes[i]->nativeType;
+    }
+
+    fnInfo->rbReturnType = rbffi_Type_Lookup(rbReturnType);
+    if (!RTEST(fnInfo->rbReturnType)) {
+        VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL);
+        rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName));
+    }
+    
+    if (rb_obj_is_kind_of(fnInfo->rbReturnType, rbffi_StructByValueClass)) {
+        fnInfo->hasStruct = true;
+    }
+
+    Data_Get_Struct(fnInfo->rbReturnType, Type, fnInfo->returnType);
+    fnInfo->ffiReturnType = fnInfo->returnType->ffiType;
+
+
+#if defined(X86_WIN32)
+    rbConventionStr = (rbConvention != Qnil) ? rb_funcall2(rbConvention, rb_intern("to_s"), 0, NULL) : Qnil;
+    fnInfo->abi = (rbConventionStr != Qnil && strcmp(StringValueCStr(rbConventionStr), "stdcall") == 0)
+            ? FFI_STDCALL : FFI_DEFAULT_ABI;
+#else
+    fnInfo->abi = FFI_DEFAULT_ABI;
+#endif
+
+    status = ffi_prep_cif(&fnInfo->ffi_cif, fnInfo->abi, fnInfo->parameterCount,
+            fnInfo->ffiReturnType, fnInfo->ffiParameterTypes);
+    switch (status) {
+        case FFI_BAD_ABI:
+            rb_raise(rb_eArgError, "Invalid ABI specified");
+        case FFI_BAD_TYPEDEF:
+            rb_raise(rb_eArgError, "Invalid argument type specified");
+        case FFI_OK:
+            break;
+        default:
+            rb_raise(rb_eArgError, "Unknown FFI error");
+    }
+
+    fnInfo->invoke = rbffi_GetInvoker(fnInfo);
+
+    return self;
+}
+
+/*
+ * call-seq: result_type
+ * @return [Type]
+ * Get the return type of the function type
+ */
+static VALUE
+fntype_result_type(VALUE self)
+{
+    FunctionType* ft;
+
+    Data_Get_Struct(self, FunctionType, ft);
+
+    return ft->rbReturnType;
+}
+
+/*
+ * call-seq: param_types
+ * @return [Array<Type>]
+ * Get parameters types.
+ */
+static VALUE
+fntype_param_types(VALUE self)
+{
+    FunctionType* ft;
+
+    Data_Get_Struct(self, FunctionType, ft);
+
+    return rb_ary_dup(ft->rbParameterTypes);
+}
+
+void
+rbffi_FunctionInfo_Init(VALUE moduleFFI)
+{
+    VALUE ffi_Type;
+
+    ffi_Type = rbffi_TypeClass;
+
+    /*
+     * Document-class: FFI::FunctionType < FFI::Type
+     */
+    rbffi_FunctionTypeClass = rb_define_class_under(moduleFFI, "FunctionType",ffi_Type);
+    rb_global_variable(&rbffi_FunctionTypeClass);
+    /*
+     * Document-const: FFI::CallbackInfo = FFI::FunctionType
+     */
+    rb_define_const(moduleFFI, "CallbackInfo", rbffi_FunctionTypeClass);
+    /*
+     * Document-const: FFI::FunctionInfo = FFI::FunctionType
+     */
+    rb_define_const(moduleFFI, "FunctionInfo", rbffi_FunctionTypeClass);
+    /*
+     * Document-const: FFI::Type::Function = FFI::FunctionType
+     */
+    rb_define_const(ffi_Type, "Function", rbffi_FunctionTypeClass);
+
+    rb_define_alloc_func(rbffi_FunctionTypeClass, fntype_allocate);
+    rb_define_method(rbffi_FunctionTypeClass, "initialize", fntype_initialize, -1);
+    rb_define_method(rbffi_FunctionTypeClass, "result_type", fntype_result_type, 0);
+    rb_define_method(rbffi_FunctionTypeClass, "param_types", fntype_param_types, 0);
+
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/LastError.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/LastError.c
new file mode 100755
index 0000000..795a42e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/LastError.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2008, 2009, Wayne Meissner
+ * Copyright (C) 2009 Aman Gupta <aman at tmm1.net>
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MSC_VER
+# include <sys/param.h>
+#endif
+#include <sys/types.h>
+#include <stdio.h>
+#ifndef _MSC_VER
+# include <stdint.h>
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+#endif
+#include <errno.h>
+#include <ruby.h>
+
+#include "LastError.h"
+
+#if defined(HAVE_NATIVETHREAD) && !defined(_WIN32) && !defined(__WIN32__)
+# include <pthread.h>
+# define USE_PTHREAD_LOCAL
+#endif
+
+typedef struct ThreadData {
+    int td_errno;
+} ThreadData;
+
+#if defined(USE_PTHREAD_LOCAL)
+static pthread_key_t threadDataKey;
+#endif
+
+static inline ThreadData* thread_data_get(void);
+
+#if defined(USE_PTHREAD_LOCAL)
+
+static ThreadData*
+thread_data_init(void)
+{
+    ThreadData* td = xcalloc(1, sizeof(ThreadData));
+
+    pthread_setspecific(threadDataKey, td);
+
+    return td;
+}
+
+
+static inline ThreadData*
+thread_data_get(void)
+{
+    ThreadData* td = pthread_getspecific(threadDataKey);
+    return td != NULL ? td : thread_data_init();
+}
+
+static void
+thread_data_free(void *ptr)
+{
+    xfree(ptr);
+}
+
+#else
+static ID id_thread_data;
+
+static ThreadData*
+thread_data_init(void)
+{
+    ThreadData* td;
+    VALUE obj;
+
+    obj = Data_Make_Struct(rb_cObject, ThreadData, NULL, -1, td);
+    rb_thread_local_aset(rb_thread_current(), id_thread_data, obj);
+
+    return td;
+}
+
+static inline ThreadData*
+thread_data_get()
+{
+    VALUE obj = rb_thread_local_aref(rb_thread_current(), id_thread_data);
+
+    if (obj != Qnil && TYPE(obj) == T_DATA) {
+        return (ThreadData *) DATA_PTR(obj);
+    }
+
+    return thread_data_init();
+}
+
+#endif
+
+
+/*
+ * call-seq: error
+ * @return [Numeric]
+ * Get +errno+ value.
+ */
+static VALUE
+get_last_error(VALUE self)
+{
+    return INT2NUM(thread_data_get()->td_errno);
+}
+
+
+/*
+ * call-seq: error(error)
+ * @param [Numeric] error
+ * @return [nil]
+ * Set +errno+ value.
+ */
+static VALUE
+set_last_error(VALUE self, VALUE error)
+{
+
+#ifdef _WIN32
+    SetLastError(NUM2INT(error));
+#else
+    errno = NUM2INT(error);
+#endif
+
+    return Qnil;
+}
+
+
+void
+rbffi_save_errno(void)
+{
+    int error = 0;
+
+#ifdef _WIN32
+    error = GetLastError();
+#else
+    error = errno;
+#endif
+
+    thread_data_get()->td_errno = error;
+}
+
+
+void
+rbffi_LastError_Init(VALUE moduleFFI)
+{
+    /*
+     * Document-module: FFI::LastError
+     * This module defines a couple of method to set and get +errno+
+     * for current thread.
+     */
+    VALUE moduleError = rb_define_module_under(moduleFFI, "LastError");
+
+    rb_define_module_function(moduleError, "error", get_last_error, 0);
+    rb_define_module_function(moduleError, "error=", set_last_error, 1);
+
+#if defined(USE_PTHREAD_LOCAL)
+    pthread_key_create(&threadDataKey, thread_data_free);
+#else
+    id_thread_data = rb_intern("ffi_thread_local_data");
+#endif /* USE_PTHREAD_LOCAL */
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/LastError.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/LastError.h
new file mode 100755
index 0000000..ee1dfbb
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/LastError.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2008, 2009, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_LASTERROR_H
+#define	RBFFI_LASTERROR_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+
+void rbffi_LastError_Init(VALUE moduleFFI);
+
+void rbffi_save_errno(void);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_LASTERROR_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/LongDouble.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/LongDouble.c
new file mode 100755
index 0000000..a21883a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/LongDouble.c
@@ -0,0 +1,63 @@
+#include "LongDouble.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <float.h>
+
+#if defined (__CYGWIN__) || defined(__INTERIX)
+# define strtold(str, endptr)    ((long double) strtod((str), (endptr)))
+#endif /* defined (__CYGWIN__) */
+
+static VALUE rb_cBigDecimal = Qnil;
+static VALUE bigdecimal_load(VALUE unused);
+static VALUE bigdecimal_failed(VALUE value);
+
+VALUE 
+rbffi_longdouble_new(long double ld)
+{
+    if (!RTEST(rb_cBigDecimal)) {
+        /* allow fallback if the bigdecimal library is unavailable in future ruby versions */
+        rb_cBigDecimal = rb_rescue(bigdecimal_load, Qnil, bigdecimal_failed, rb_cObject);
+    }
+
+    if (RTEST(rb_cBigDecimal) && rb_cBigDecimal != rb_cObject) {
+        char buf[128];
+        return rb_funcall(rb_cBigDecimal, rb_intern("new"), 1, rb_str_new(buf, sprintf(buf, "%.35Le", ld)));
+    }
+
+    /* Fall through to handling as a float */
+    return rb_float_new(ld);
+}
+
+long double 
+rbffi_num2longdouble(VALUE value)
+{
+    if (TYPE(value) == T_FLOAT) {
+        return rb_num2dbl(value);
+    }
+    
+    if (!RTEST(rb_cBigDecimal) && rb_const_defined(rb_cObject, rb_intern("BigDecimal"))) {
+        rb_cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
+    }
+
+    if (RTEST(rb_cBigDecimal) && rb_cBigDecimal != rb_cObject && RTEST(rb_obj_is_kind_of(value, rb_cBigDecimal))) {
+        VALUE s = rb_funcall(value, rb_intern("to_s"), 1, rb_str_new2("E"));
+        return strtold(RSTRING_PTR(s), NULL);
+    }
+
+    /* Fall through to handling as a float */
+    return rb_num2dbl(value);
+}
+
+
+static VALUE 
+bigdecimal_load(VALUE unused)
+{
+    rb_require("bigdecimal");
+    return rb_const_get(rb_cObject, rb_intern("BigDecimal"));
+}
+
+static VALUE 
+bigdecimal_failed(VALUE value)
+{
+    return value;
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/LongDouble.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/LongDouble.h
new file mode 100755
index 0000000..2e52ccb
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/LongDouble.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_LONGDOUBLE_H
+#define	RBFFI_LONGDOUBLE_H
+
+#include <ruby.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifdef _MSC_VER
+#define strtold strtod
+#endif
+
+extern VALUE rbffi_longdouble_new(long double ld);
+extern long double rbffi_num2longdouble(VALUE value);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_LONGDOUBLE_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/MappedType.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/MappedType.c
new file mode 100755
index 0000000..d1a4189
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/MappedType.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2010, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ruby.h>
+
+#include <ffi.h>
+#include "rbffi.h"
+
+#include "Type.h"
+#include "MappedType.h"
+
+
+static VALUE mapped_allocate(VALUE);
+static VALUE mapped_initialize(VALUE, VALUE);
+static void mapped_mark(MappedType *);
+static ID id_native_type, id_to_native, id_from_native;
+
+VALUE rbffi_MappedTypeClass = Qnil;
+
+static VALUE
+mapped_allocate(VALUE klass)
+{
+    MappedType* m;
+
+    VALUE obj = Data_Make_Struct(klass, MappedType, mapped_mark, -1, m);
+
+    m->rbConverter = Qnil;
+    m->rbType = Qnil;
+    m->type = NULL;
+    m->base.nativeType = NATIVE_MAPPED;
+    m->base.ffiType = &ffi_type_void;
+    
+    return obj;
+}
+
+/*
+ * call-seq: initialize(converter)
+ * @param [#native_type, #to_native, #from_native] converter +converter+ must respond to
+ *  all these methods
+ * @return [self]
+ */
+static VALUE
+mapped_initialize(VALUE self, VALUE rbConverter)
+{
+    MappedType* m = NULL;
+    
+    if (!rb_respond_to(rbConverter, id_native_type)) {
+        rb_raise(rb_eNoMethodError, "native_type method not implemented");
+    }
+
+    if (!rb_respond_to(rbConverter, id_to_native)) {
+        rb_raise(rb_eNoMethodError, "to_native method not implemented");
+    }
+
+    if (!rb_respond_to(rbConverter, id_from_native)) {
+        rb_raise(rb_eNoMethodError, "from_native method not implemented");
+    }
+    
+    Data_Get_Struct(self, MappedType, m);
+    m->rbType = rb_funcall2(rbConverter, id_native_type, 0, NULL);
+    if (!(rb_obj_is_kind_of(m->rbType, rbffi_TypeClass))) {
+        rb_raise(rb_eTypeError, "native_type did not return instance of FFI::Type");
+    }
+
+    m->rbConverter = rbConverter;
+    Data_Get_Struct(m->rbType, Type, m->type);
+    m->base.ffiType = m->type->ffiType;
+    
+    return self;
+}
+
+static void
+mapped_mark(MappedType* m)
+{
+    rb_gc_mark(m->rbType);
+    rb_gc_mark(m->rbConverter);
+}
+
+/*
+ * call-seq: mapped_type.native_type
+ * @return [Type]
+ * Get native type of mapped type.
+ */
+static VALUE
+mapped_native_type(VALUE self)
+{
+    MappedType*m = NULL;
+    Data_Get_Struct(self, MappedType, m);
+
+    return m->rbType;
+}
+
+/*
+ * call-seq: mapped_type.to_native(*args)
+ * @param args depends on {FFI::DataConverter} used to initialize +self+
+ */
+static VALUE
+mapped_to_native(int argc, VALUE* argv, VALUE self)
+{
+    MappedType*m = NULL;
+    
+    Data_Get_Struct(self, MappedType, m);
+    
+    return rb_funcall2(m->rbConverter, id_to_native, argc, argv);
+}
+
+/*
+ * call-seq: mapped_type.from_native(*args)
+ * @param args depends on {FFI::DataConverter} used to initialize +self+
+ */
+static VALUE
+mapped_from_native(int argc, VALUE* argv, VALUE self)
+{
+    MappedType*m = NULL;
+    
+    Data_Get_Struct(self, MappedType, m);
+
+    return rb_funcall2(m->rbConverter, id_from_native, argc, argv);
+}
+
+void
+rbffi_MappedType_Init(VALUE moduleFFI)
+{
+    /* 
+     * Document-class: FFI::Type::Mapped < FFI::Type
+     */
+    rbffi_MappedTypeClass = rb_define_class_under(rbffi_TypeClass, "Mapped", rbffi_TypeClass);
+    
+    rb_global_variable(&rbffi_MappedTypeClass);
+
+    id_native_type = rb_intern("native_type");
+    id_to_native = rb_intern("to_native");
+    id_from_native = rb_intern("from_native");
+
+    rb_define_alloc_func(rbffi_MappedTypeClass, mapped_allocate);
+    rb_define_method(rbffi_MappedTypeClass, "initialize", mapped_initialize, 1);
+    rb_define_method(rbffi_MappedTypeClass, "type", mapped_native_type, 0);
+    rb_define_method(rbffi_MappedTypeClass, "native_type", mapped_native_type, 0);
+    rb_define_method(rbffi_MappedTypeClass, "to_native", mapped_to_native, -1);
+    rb_define_method(rbffi_MappedTypeClass, "from_native", mapped_from_native, -1);
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/MappedType.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/MappedType.h
new file mode 100755
index 0000000..4b26cc1
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/MappedType.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_MAPPEDTYPE_H
+#define	RBFFI_MAPPEDTYPE_H
+
+
+#include <ruby.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+
+typedef struct MappedType_ {
+    Type base;
+    Type* type;
+    VALUE rbConverter;
+    VALUE rbType;
+    
+} MappedType;
+
+void rbffi_MappedType_Init(VALUE moduleFFI);
+
+extern VALUE rbffi_MappedTypeClass;
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_MAPPEDTYPE_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/MemoryPointer.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/MemoryPointer.c
new file mode 100755
index 0000000..0d91c35
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/MemoryPointer.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2008, 2009, Wayne Meissner
+ * Copyright (C) 2009 Luc Heinrich <luc at honk-honk.com>
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MSC_VER
+# include <stdbool.h>
+# include <stdint.h>
+#else
+# include "win32/stdbool.h"
+# include "win32/stdint.h"
+#endif
+#include <limits.h>
+#include <ruby.h>
+#include "rbffi.h"
+#include "AbstractMemory.h"
+#include "Pointer.h"
+#include "MemoryPointer.h"
+
+
+static VALUE memptr_allocate(VALUE klass);
+static void memptr_release(Pointer* ptr);
+static VALUE memptr_malloc(VALUE self, long size, long count, bool clear);
+static VALUE memptr_free(VALUE self);
+
+VALUE rbffi_MemoryPointerClass;
+
+#define MEMPTR(obj) ((MemoryPointer *) rbffi_AbstractMemory_Cast(obj, rbffi_MemoryPointerClass))
+
+VALUE
+rbffi_MemoryPointer_NewInstance(long size, long count, bool clear)
+{
+    return memptr_malloc(memptr_allocate(rbffi_MemoryPointerClass), size, count, clear);
+}
+
+static VALUE
+memptr_allocate(VALUE klass)
+{
+    Pointer* p;
+    VALUE obj = Data_Make_Struct(klass, Pointer, NULL, memptr_release, p);
+    p->rbParent = Qnil;
+    p->memory.flags = MEM_RD | MEM_WR;
+
+    return obj;
+}
+
+/*
+ * call-seq: initialize(size, count=1, clear=true)
+ * @param [Fixnum, Bignum, Symbol, FFI::Type] size size of a memory cell (in bytes, or type whom size will be used)
+ * @param [Numeric] count number of cells in memory
+ * @param [Boolean] clear set memory to all-zero if +true+
+ * @return [self]
+ * A new instance of FFI::MemoryPointer.
+ */
+static VALUE
+memptr_initialize(int argc, VALUE* argv, VALUE self)
+{
+    VALUE size = Qnil, count = Qnil, clear = Qnil;
+    int nargs = rb_scan_args(argc, argv, "12", &size, &count, &clear);
+
+    memptr_malloc(self, rbffi_type_size(size), nargs > 1 ? NUM2LONG(count) : 1,
+        RTEST(clear) || clear == Qnil);
+
+    if (rb_block_given_p()) {
+        return rb_ensure(rb_yield, self, memptr_free, self);
+    }
+
+    return self;
+}
+
+static VALUE
+memptr_malloc(VALUE self, long size, long count, bool clear)
+{
+    Pointer* p;
+    unsigned long msize;
+
+    Data_Get_Struct(self, Pointer, p);
+
+    msize = size * count;
+
+    p->storage = xmalloc(msize + 7);
+    if (p->storage == NULL) {
+        rb_raise(rb_eNoMemError, "Failed to allocate memory size=%ld bytes", msize);
+        return Qnil;
+    }
+    p->autorelease = true;
+    p->memory.typeSize = (int) size;
+    p->memory.size = msize;
+    /* ensure the memory is aligned on at least a 8 byte boundary */
+    p->memory.address = (char *) (((uintptr_t) p->storage + 0x7) & (uintptr_t) ~0x7UL);;
+    p->allocated = true;
+
+    if (clear && p->memory.size > 0) {
+        memset(p->memory.address, 0, p->memory.size);
+    }
+
+    return self;
+}
+
+static VALUE
+memptr_free(VALUE self)
+{
+    Pointer* ptr;
+
+    Data_Get_Struct(self, Pointer, ptr);
+
+    if (ptr->allocated) {
+        if (ptr->storage != NULL) {
+            xfree(ptr->storage);
+            ptr->storage = NULL;
+        }
+        ptr->allocated = false;
+    }
+
+    return self;
+}
+
+static void
+memptr_release(Pointer* ptr)
+{
+    if (ptr->autorelease && ptr->allocated && ptr->storage != NULL) {
+        xfree(ptr->storage);
+        ptr->storage = NULL;
+    }
+    xfree(ptr);
+}
+
+/*
+ * call-seq: from_string(s)
+ * @param [String] s string
+ * @return [MemoryPointer]
+ * Create a {MemoryPointer} with +s+ inside.
+ */
+static VALUE
+memptr_s_from_string(VALUE klass, VALUE to_str)
+{
+    VALUE s = StringValue(to_str);
+    VALUE args[] = { INT2FIX(1), LONG2NUM(RSTRING_LEN(s) + 1), Qfalse };
+    VALUE obj = rb_class_new_instance(3, args, klass);
+    rb_funcall(obj, rb_intern("put_string"), 2, INT2FIX(0), s);
+
+    return obj;
+}
+
+void
+rbffi_MemoryPointer_Init(VALUE moduleFFI)
+{
+    VALUE ffi_Pointer;
+
+    ffi_Pointer = rbffi_PointerClass;
+
+    /*
+     * Document-class: FFI::MemoryPointer < FFI::Pointer
+     * A MemoryPointer is a specific {Pointer}. It points to a memory composed of cells. All cells have the
+     * same size.
+     *
+     * @example Create a new MemoryPointer
+     *  mp = FFI::MemoryPointer.new(:long, 16)   # Create a pointer on a memory of 16 long ints.
+     * @example Create a new MemoryPointer from a String
+     *  mp1 = FFI::MemoryPointer.from_string("this is a string")
+     *  # same as:
+     *  mp2 = FFI::MemoryPointer.new(:char,16)
+     *  mp2.put_string("this is a string")
+     */
+    rbffi_MemoryPointerClass = rb_define_class_under(moduleFFI, "MemoryPointer", ffi_Pointer);
+    rb_global_variable(&rbffi_MemoryPointerClass);
+
+    rb_define_alloc_func(rbffi_MemoryPointerClass, memptr_allocate);
+    rb_define_method(rbffi_MemoryPointerClass, "initialize", memptr_initialize, -1);
+    rb_define_singleton_method(rbffi_MemoryPointerClass, "from_string", memptr_s_from_string, 1);
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/MemoryPointer.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/MemoryPointer.h
new file mode 100755
index 0000000..1257683
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/MemoryPointer.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2008, 2009, Wayne Meissner
+ * Copyright (c) 2008, Luc Heinrich <luc at honk-honk.com>
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_MEMORYPOINTER_H
+#define	RBFFI_MEMORYPOINTER_H
+
+#ifndef _MSC_VER
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+#endif
+#include <ruby.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+    extern void rbffi_MemoryPointer_Init(VALUE moduleFFI);
+    extern VALUE rbffi_MemoryPointerClass;
+    extern VALUE rbffi_MemoryPointer_NewInstance(long size, long count, bool clear);
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_MEMORYPOINTER_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/MethodHandle.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/MethodHandle.c
new file mode 100755
index 0000000..cee1df5
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/MethodHandle.c
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2009, 2010 Wayne Meissner
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MSC_VER
+#include <sys/param.h>
+#endif
+#include <sys/types.h>
+#ifndef _WIN32
+# include <sys/mman.h>
+#endif
+#include <stdio.h>
+#ifndef _MSC_VER
+# include <stdint.h>
+# include <stdbool.h>
+#else
+# include "win32/stdint.h"
+# include "win32/stdbool.h"
+#endif
+#ifndef _WIN32
+# include <unistd.h>
+#endif
+#include <errno.h>
+#include <ruby.h>
+#if defined(HAVE_NATIVETHREAD) && !defined(_WIN32) && !defined(__WIN32__)
+# include <pthread.h>
+#endif
+
+#include <ffi.h>
+#include "rbffi.h"
+#include "compat.h"
+
+#include "Function.h"
+#include "Types.h"
+#include "Type.h"
+#include "LastError.h"
+#include "Call.h"
+#include "ClosurePool.h"
+#include "MethodHandle.h"
+
+
+#define MAX_METHOD_FIXED_ARITY (6)
+
+#ifndef roundup
+#  define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
+#endif
+#ifdef _WIN32
+  typedef char* caddr_t;
+#endif
+
+#ifdef USE_RAW
+#  define METHOD_CLOSURE ffi_raw_closure
+#  define METHOD_PARAMS ffi_raw*
+#else
+#  define METHOD_CLOSURE ffi_closure
+#  define METHOD_PARAMS void**
+#endif
+
+
+
+static bool prep_trampoline(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize);
+static long trampoline_size(void);
+
+#if defined(__x86_64__) && (defined(__linux__) || defined(__APPLE__))
+# define CUSTOM_TRAMPOLINE 1
+#endif
+
+
+struct MethodHandle {
+    Closure* closure;
+};
+
+static ClosurePool* defaultClosurePool;
+
+
+MethodHandle*
+rbffi_MethodHandle_Alloc(FunctionType* fnInfo, void* function)
+{
+    MethodHandle* handle;
+    Closure* closure = rbffi_Closure_Alloc(defaultClosurePool);
+    if (closure == NULL) {
+        rb_raise(rb_eNoMemError, "failed to allocate closure from pool");
+        return NULL;
+    }
+
+    handle = xcalloc(1, sizeof(*handle));
+    handle->closure = closure;
+    closure->info = fnInfo;
+    closure->function = function;
+
+    return handle;
+}
+
+void
+rbffi_MethodHandle_Free(MethodHandle* handle)
+{
+    if (handle != NULL) {
+        rbffi_Closure_Free(handle->closure);
+    }
+}
+
+void*
+rbffi_MethodHandle_CodeAddress(MethodHandle* handle)
+{
+    return handle->closure->code;
+}
+
+#ifndef CUSTOM_TRAMPOLINE
+static void attached_method_invoke(ffi_cif* cif, void* retval, METHOD_PARAMS parameters, void* user_data);
+
+static ffi_type* methodHandleParamTypes[] = {
+    &ffi_type_sint,
+    &ffi_type_pointer,
+    &ffi_type_ulong,
+};
+
+static ffi_cif mh_cif;
+
+static bool
+prep_trampoline(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize)
+{
+    ffi_status ffiStatus;
+
+#if defined(USE_RAW)
+    ffiStatus = ffi_prep_raw_closure(code, &mh_cif, attached_method_invoke, closure);
+#else
+    ffiStatus = ffi_prep_closure(code, &mh_cif, attached_method_invoke, closure);
+#endif
+    if (ffiStatus != FFI_OK) {
+        snprintf(errmsg, errmsgsize, "ffi_prep_closure failed.  status=%#x", ffiStatus);
+        return false;
+    }
+
+    return true;
+}
+
+
+static long
+trampoline_size(void)
+{
+    return sizeof(METHOD_CLOSURE);
+}
+
+/*
+ * attached_method_invoke is used functions with more than 6 parameters, or
+ * with struct param or return values
+ */
+static void
+attached_method_invoke(ffi_cif* cif, void* mretval, METHOD_PARAMS parameters, void* user_data)
+{
+    Closure* handle =  (Closure *) user_data;
+    FunctionType* fnInfo = (FunctionType *) handle->info;
+
+#ifdef USE_RAW
+    int argc = parameters[0].sint;
+    VALUE* argv = *(VALUE **) &parameters[1];
+#else
+    int argc = *(int *) parameters[0];
+    VALUE* argv = *(VALUE **) parameters[1];
+#endif
+
+    *(VALUE *) mretval = (*fnInfo->invoke)(argc, argv, handle->function, fnInfo);
+}
+
+#endif
+
+
+
+#if defined(CUSTOM_TRAMPOLINE)
+#if defined(__x86_64__)
+
+static VALUE custom_trampoline(int argc, VALUE* argv, VALUE self, Closure*);
+
+#define TRAMPOLINE_CTX_MAGIC (0xfee1deadcafebabe)
+#define TRAMPOLINE_FUN_MAGIC (0xfeedfacebeeff00d)
+
+/*
+ * This is a hand-coded trampoline to speedup entry from ruby to the FFI translation
+ * layer for x86_64 arches.
+ *
+ * Since a ruby function has exactly 3 arguments, and the first 6 arguments are
+ * passed in registers for x86_64, we can tack on a context pointer by simply
+ * putting a value in %rcx, then jumping to the C trampoline code.
+ *
+ * This results in approx a 30% speedup for x86_64 FFI dispatch
+ */
+__asm__(
+    ".text\n\t"
+    ".globl ffi_trampoline\n\t"
+    ".globl _ffi_trampoline\n\t"
+    "ffi_trampoline:\n\t"
+    "_ffi_trampoline:\n\t"
+    "movabsq $0xfee1deadcafebabe, %rcx\n\t"
+    "movabsq $0xfeedfacebeeff00d, %r11\n\t"
+    "jmpq *%r11\n\t"
+    ".globl ffi_trampoline_end\n\t"
+    "ffi_trampoline_end:\n\t"
+    ".globl _ffi_trampoline_end\n\t"
+    "_ffi_trampoline_end:\n\t"
+);
+
+static VALUE
+custom_trampoline(int argc, VALUE* argv, VALUE self, Closure* handle)
+{
+    FunctionType* fnInfo = (FunctionType *) handle->info;
+    VALUE rbReturnValue;
+    
+    RB_GC_GUARD(rbReturnValue) = (*fnInfo->invoke)(argc, argv, handle->function, fnInfo);
+    RB_GC_GUARD_PTR(argv);
+    RB_GC_GUARD(self);
+
+    return rbReturnValue;
+}
+
+#elif defined(__i386__) && 0
+
+static VALUE custom_trampoline(caddr_t args, Closure*);
+#define TRAMPOLINE_CTX_MAGIC (0xfee1dead)
+#define TRAMPOLINE_FUN_MAGIC (0xbeefcafe)
+
+/*
+ * This is a hand-coded trampoline to speedup entry from ruby to the FFI translation
+ * layer for i386 arches.
+ *
+ * This does not make a discernable difference vs a raw closure, so for now,
+ * it is not enabled.
+ */
+__asm__(
+    ".text\n\t"
+    ".globl ffi_trampoline\n\t"
+    ".globl _ffi_trampoline\n\t"
+    "ffi_trampoline:\n\t"
+    "_ffi_trampoline:\n\t"
+    "subl    $12, %esp\n\t"
+    "leal    16(%esp), %eax\n\t"
+    "movl    %eax, (%esp)\n\t"
+    "movl    $0xfee1dead, 4(%esp)\n\t"
+    "movl    $0xbeefcafe, %eax\n\t"
+    "call    *%eax\n\t"
+    "addl    $12, %esp\n\t"
+    "ret\n\t"
+    ".globl ffi_trampoline_end\n\t"
+    "ffi_trampoline_end:\n\t"
+    ".globl _ffi_trampoline_end\n\t"
+    "_ffi_trampoline_end:\n\t"
+);
+
+static VALUE
+custom_trampoline(caddr_t args, Closure* handle)
+{
+    FunctionType* fnInfo = (FunctionType *) handle->info;
+    return (*fnInfo->invoke)(*(int *) args, *(VALUE **) (args + 4), handle->function, fnInfo);
+}
+
+#endif /* __x86_64__ else __i386__ */
+
+extern void ffi_trampoline(int argc, VALUE* argv, VALUE self);
+extern void ffi_trampoline_end(void);
+static int trampoline_offsets(long *, long *);
+
+static long trampoline_ctx_offset, trampoline_func_offset;
+
+static long
+trampoline_offset(int off, const long value)
+{
+    caddr_t ptr;
+    for (ptr = (caddr_t) &ffi_trampoline + off; ptr < (caddr_t) &ffi_trampoline_end; ++ptr) {
+        if (*(long *) ptr == value) {
+            return ptr - (caddr_t) &ffi_trampoline;
+        }
+    }
+
+    return -1;
+}
+
+static int
+trampoline_offsets(long* ctxOffset, long* fnOffset)
+{
+    *ctxOffset = trampoline_offset(0, TRAMPOLINE_CTX_MAGIC);
+    if (*ctxOffset == -1) {
+        return -1;
+    }
+
+    *fnOffset = trampoline_offset(0, TRAMPOLINE_FUN_MAGIC);
+    if (*fnOffset == -1) {
+        return -1;
+    }
+
+    return 0;
+}
+
+static bool
+prep_trampoline(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize)
+{
+    caddr_t ptr = (caddr_t) code;
+
+    memcpy(ptr, &ffi_trampoline, trampoline_size());
+    /* Patch the context and function addresses into the stub code */
+    *(intptr_t *)(ptr + trampoline_ctx_offset) = (intptr_t) closure;
+    *(intptr_t *)(ptr + trampoline_func_offset) = (intptr_t) custom_trampoline;
+
+    return true;
+}
+
+static long
+trampoline_size(void)
+{
+    return (caddr_t) &ffi_trampoline_end - (caddr_t) &ffi_trampoline;
+}
+
+#endif /* CUSTOM_TRAMPOLINE */
+
+
+void
+rbffi_MethodHandle_Init(VALUE module)
+{
+#ifndef CUSTOM_TRAMPOLINE
+    ffi_status ffiStatus;
+#endif
+
+    defaultClosurePool = rbffi_ClosurePool_New((int) trampoline_size(), prep_trampoline, NULL);
+
+#if defined(CUSTOM_TRAMPOLINE)
+    if (trampoline_offsets(&trampoline_ctx_offset, &trampoline_func_offset) != 0) {
+        rb_raise(rb_eFatal, "Could not locate offsets in trampoline code");
+    }
+#else
+    ffiStatus = ffi_prep_cif(&mh_cif, FFI_DEFAULT_ABI, 3, &ffi_type_ulong,
+            methodHandleParamTypes);
+    if (ffiStatus != FFI_OK) {
+        rb_raise(rb_eFatal, "ffi_prep_cif failed.  status=%#x", ffiStatus);
+    }
+
+#endif
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/MethodHandle.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/MethodHandle.h
new file mode 100755
index 0000000..c3341bf
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/MethodHandle.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_METHODHANDLE_H
+#define	RBFFI_METHODHANDLE_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#include <ruby.h>
+#include "Function.h"
+
+    
+typedef struct MethodHandlePool MethodHandlePool;
+typedef struct MethodHandle MethodHandle;
+
+
+MethodHandle* rbffi_MethodHandle_Alloc(FunctionType* fnInfo, void* function);
+void rbffi_MethodHandle_Free(MethodHandle* handle);
+void* rbffi_MethodHandle_CodeAddress(MethodHandle* handle);
+void rbffi_MethodHandle_Init(VALUE module);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_METHODHANDLE_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Platform.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Platform.c
new file mode 100755
index 0000000..1305ad2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Platform.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2008-2010 Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MSC_VER
+# include <sys/param.h>
+#endif
+# include <sys/types.h>
+#ifndef _MSC_VER
+# include <stdint.h>
+# include <stdbool.h>
+#else
+# include "win32/stdint.h"
+# include "win32/stdbool.h"
+#endif
+#include <ruby.h>
+#include <ctype.h>
+#include "rbffi_endian.h"
+#include "Platform.h"
+
+#if defined(__GNU__) || defined(__GLIBC__)
+# include <gnu/lib-names.h>
+#endif
+
+static VALUE PlatformModule = Qnil;
+
+/*
+ * Determine the cpu type at compile time - useful for MacOSX where the the
+ * system installed ruby incorrectly reports 'host_cpu' as 'powerpc' when running
+ * on intel.
+ */
+#if defined(__x86_64__) || defined(__x86_64) || defined(__amd64) || defined(_M_X64) || defined(_M_AMD64)
+# define CPU "x86_64"
+
+#elif defined(__i386__) || defined(__i386) || defined(_M_IX86)
+# define CPU "i386"
+
+#elif defined(__ppc64__) || defined(__powerpc64__) || defined(_M_PPC)
+# define CPU "ppc64"
+
+#elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc)
+# define CPU "ppc"
+
+/* Need to check for __sparcv9 first, because __sparc will be defined either way. */
+#elif defined(__sparcv9__) || defined(__sparcv9)
+# define CPU "sparcv9"
+
+#elif defined(__sparc__) || defined(__sparc)
+# define CPU "sparc"
+
+#elif defined(__arm__) || defined(__arm)
+# define CPU "arm"
+
+#elif defined(__mips__) || defined(__mips)
+# define CPU "mips"
+
+#elif defined(__s390__)
+# define CPU "s390"
+
+#else
+# define CPU "unknown"
+#endif
+
+static void
+export_primitive_types(VALUE module)
+{
+#define S(name, T) do { \
+    typedef struct { char c; T v; } s; \
+    rb_define_const(module, #name "_ALIGN", INT2NUM((sizeof(s) - sizeof(T)) * 8)); \
+    rb_define_const(module, #name "_SIZE", INT2NUM(sizeof(T)* 8)); \
+} while(0)
+    S(INT8, char);
+    S(INT16, short);
+    S(INT32, int);
+    S(INT64, long long);
+    S(LONG, long);
+    S(FLOAT, float);
+    S(DOUBLE, double);
+    S(ADDRESS, void*);
+#undef S
+}
+
+void
+rbffi_Platform_Init(VALUE moduleFFI)
+{
+    PlatformModule = rb_define_module_under(moduleFFI, "Platform");
+    rb_define_const(PlatformModule, "BYTE_ORDER", INT2FIX(BYTE_ORDER));
+    rb_define_const(PlatformModule, "LITTLE_ENDIAN", INT2FIX(LITTLE_ENDIAN));
+    rb_define_const(PlatformModule, "BIG_ENDIAN", INT2FIX(BIG_ENDIAN));
+    rb_define_const(PlatformModule, "CPU", rb_str_new2(CPU));
+#if defined(__GNU__) || defined(__GLIBC__)
+    rb_define_const(PlatformModule, "GNU_LIBC", rb_str_new2(LIBC_SO));
+#endif
+    export_primitive_types(PlatformModule);
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Platform.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Platform.h
new file mode 100755
index 0000000..5575e34
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Platform.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008-2010 Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_PLATFORM_H
+#define	RBFFI_PLATFORM_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+    extern void rbffi_Platform_Init(VALUE moduleFFI);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_PLATFORM_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Pointer.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Pointer.c
new file mode 100755
index 0000000..edd931c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Pointer.c
@@ -0,0 +1,508 @@
+/*
+ * Copyright (c) 2008, 2009, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MSC_VER
+# include <stdint.h>
+# include <stdbool.h>
+#else
+# include "win32/stdint.h"
+# include "win32/stdbool.h"
+#endif
+#include <limits.h>
+#include <ruby.h>
+#include "rbffi.h"
+#include "rbffi_endian.h"
+#include "AbstractMemory.h"
+#include "Pointer.h"
+
+#define POINTER(obj) rbffi_AbstractMemory_Cast((obj), rbffi_PointerClass)
+
+VALUE rbffi_PointerClass = Qnil;
+VALUE rbffi_NullPointerSingleton = Qnil;
+
+static void ptr_release(Pointer* ptr);
+static void ptr_mark(Pointer* ptr);
+
+VALUE
+rbffi_Pointer_NewInstance(void* addr)
+{
+    Pointer* p;
+    VALUE obj;
+
+    if (addr == NULL) {
+        return rbffi_NullPointerSingleton;
+    }
+
+    obj = Data_Make_Struct(rbffi_PointerClass, Pointer, NULL, -1, p);
+    p->memory.address = addr;
+    p->memory.size = LONG_MAX;
+    p->memory.flags = (addr == NULL) ? 0 : (MEM_RD | MEM_WR);
+    p->memory.typeSize = 1;
+    p->rbParent = Qnil;
+
+    return obj;
+}
+
+static VALUE
+ptr_allocate(VALUE klass)
+{
+    Pointer* p;
+    VALUE obj;
+
+    obj = Data_Make_Struct(klass, Pointer, ptr_mark, ptr_release, p);
+    p->rbParent = Qnil;
+    p->memory.flags = MEM_RD | MEM_WR;
+
+    return obj;
+}
+
+/*
+ * @overload initialize(pointer)
+ *  @param [Pointer] pointer another pointer to initialize from
+ *  Create a new pointer from another {Pointer}.
+ * @overload initialize(type, address)
+ *  @param [Type] type type for pointer
+ *  @param [Integer] address base address for pointer
+ *  Create a new pointer from a {Type} and a base adresse
+ * @return [self]
+ * A new instance of Pointer.
+ */
+static VALUE
+ptr_initialize(int argc, VALUE* argv, VALUE self)
+{
+    Pointer* p;
+    VALUE rbType = Qnil, rbAddress = Qnil;
+    int typeSize = 1;
+
+    Data_Get_Struct(self, Pointer, p);
+
+    switch (rb_scan_args(argc, argv, "11", &rbType, &rbAddress)) {
+        case 1:
+            rbAddress = rbType;
+            typeSize = 1;
+            break;
+        case 2:
+            typeSize = rbffi_type_size(rbType);
+            break;
+        default:
+            rb_raise(rb_eArgError, "Invalid arguments");
+    }
+
+    switch (TYPE(rbAddress)) {
+        case T_FIXNUM:
+        case T_BIGNUM:
+            p->memory.address = (void*) (uintptr_t) NUM2LL(rbAddress);
+            p->memory.size = LONG_MAX;
+            if (p->memory.address == NULL) {
+                p->memory.flags = 0;
+            }
+            break;
+
+        default:
+            if (rb_obj_is_kind_of(rbAddress, rbffi_PointerClass)) {
+                Pointer* orig;
+
+                p->rbParent = rbAddress;
+                Data_Get_Struct(rbAddress, Pointer, orig);
+                p->memory = orig->memory;
+            } else {
+                rb_raise(rb_eTypeError, "wrong argument type, expected Integer or FFI::Pointer");
+            }
+            break;
+    }
+
+    p->memory.typeSize = typeSize;
+
+    return self;
+}
+
+/*
+ * call-seq: ptr.initialize_copy(other)
+ * @param [Pointer] other source for cloning or dupping
+ * @return [self]
+ * @raise {RuntimeError} if +other+ is an unbounded memory area, or is unreable/unwritable
+ * @raise {NoMemError} if failed to allocate memory for new object
+ * DO NOT CALL THIS METHOD.
+ *
+ * This method is internally used by #dup and #clone. Memory contents is copied from +other+.
+ */
+static VALUE
+ptr_initialize_copy(VALUE self, VALUE other)
+{
+    AbstractMemory* src;
+    Pointer* dst;
+    
+    Data_Get_Struct(self, Pointer, dst);
+    src = POINTER(other);
+    if (src->size == LONG_MAX) {
+        rb_raise(rb_eRuntimeError, "cannot duplicate unbounded memory area");
+        return Qnil;
+    }
+    
+    if ((dst->memory.flags & (MEM_RD | MEM_WR)) != (MEM_RD | MEM_WR)) {
+        rb_raise(rb_eRuntimeError, "cannot duplicate unreadable/unwritable memory area");
+        return Qnil;
+    }
+
+    if (dst->storage != NULL) {
+        xfree(dst->storage);
+        dst->storage = NULL;
+    }
+
+    dst->storage = xmalloc(src->size + 7);
+    if (dst->storage == NULL) {
+        rb_raise(rb_eNoMemError, "failed to allocate memory size=%lu bytes", src->size);
+        return Qnil;
+    }
+    
+    dst->allocated = true;
+    dst->autorelease = true;
+    dst->memory.address = (void *) (((uintptr_t) dst->storage + 0x7) & (uintptr_t) ~0x7UL);
+    dst->memory.size = src->size;
+    dst->memory.typeSize = src->typeSize;
+    
+    /* finally, copy the actual memory contents */
+    memcpy(dst->memory.address, src->address, src->size);
+
+    return self;
+}
+
+static VALUE
+slice(VALUE self, long offset, long size)
+{
+    AbstractMemory* ptr;
+    Pointer* p;
+    VALUE retval;
+    
+    Data_Get_Struct(self, AbstractMemory, ptr);
+    checkBounds(ptr, offset, size == LONG_MAX ? 1 : size);
+
+    retval = Data_Make_Struct(rbffi_PointerClass, Pointer, ptr_mark, -1, p);
+
+    p->memory.address = ptr->address + offset;
+    p->memory.size = size;
+    p->memory.flags = ptr->flags;
+    p->memory.typeSize = ptr->typeSize;
+    p->rbParent = self;
+
+    return retval;
+}
+
+/* 
+ * Document-method: +
+ * call-seq: ptr + offset
+ * @param [Numeric] offset
+ * @return [Pointer]
+ * Return a new {Pointer} from an existing pointer and an +offset+.
+ */
+static VALUE
+ptr_plus(VALUE self, VALUE offset)
+{
+    AbstractMemory* ptr;
+    long off = NUM2LONG(offset);
+
+    Data_Get_Struct(self, AbstractMemory, ptr);
+
+    return slice(self, off, ptr->size == LONG_MAX ? LONG_MAX : ptr->size - off);
+}
+
+/*
+ * call-seq: ptr.slice(offset, length)
+ * @param [Numeric] offset
+ * @param [Numeric] length
+ * @return [Pointer]
+ * Return a new {Pointer} from an existing one. This pointer points on same contents 
+ * from +offset+ for a length +length+.
+ */
+static VALUE
+ptr_slice(VALUE self, VALUE rbOffset, VALUE rbLength)
+{
+    return slice(self, NUM2LONG(rbOffset), NUM2LONG(rbLength));
+}
+
+/*
+ * call-seq: ptr.inspect
+ * @return [String]
+ * Inspect pointer object.
+ */
+static VALUE
+ptr_inspect(VALUE self)
+{
+    char buf[100];
+    Pointer* ptr;
+    
+    Data_Get_Struct(self, Pointer, ptr);
+
+    if (ptr->memory.size != LONG_MAX) {
+        snprintf(buf, sizeof(buf), "#<%s address=%p size=%lu>",
+                rb_obj_classname(self), ptr->memory.address, ptr->memory.size);
+    } else {
+        snprintf(buf, sizeof(buf), "#<%s address=%p>", rb_obj_classname(self), ptr->memory.address);
+    }
+
+    return rb_str_new2(buf);
+}
+
+/*
+ * Document-method: null?
+ * call-seq: ptr.null?
+ * @return [Boolean]
+ * Return +true+ if +self+ is a {NULL} pointer.
+ */
+static VALUE
+ptr_null_p(VALUE self)
+{
+    Pointer* ptr;
+
+    Data_Get_Struct(self, Pointer, ptr);
+
+    return ptr->memory.address == NULL ? Qtrue : Qfalse;
+}
+
+/*
+ * Document-method: ==
+ * call-seq: ptr == other
+ * @param [Pointer] other
+ * Check equality between +self+ and +other+. Equality is tested on {#address}.
+ */
+static VALUE
+ptr_equals(VALUE self, VALUE other)
+{
+    Pointer* ptr;
+    
+    Data_Get_Struct(self, Pointer, ptr);
+
+    if (NIL_P(other)) {
+        return ptr->memory.address == NULL ? Qtrue : Qfalse;
+    }
+
+    return ptr->memory.address == POINTER(other)->address ? Qtrue : Qfalse;
+}
+
+/*
+ * call-seq: ptr.address
+ * @return [Numeric] pointer's base address
+ * Return +self+'s base address (alias: #to_i).
+ */
+static VALUE
+ptr_address(VALUE self)
+{
+    Pointer* ptr;
+    
+    Data_Get_Struct(self, Pointer, ptr);
+
+    return ULL2NUM((uintptr_t) ptr->memory.address);
+}
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+# define SWAPPED_ORDER BIG_ENDIAN
+#else
+# define SWAPPED_ORDER LITTLE_ENDIAN
+#endif
+
+/*
+ * Get or set +self+'s endianness
+ * @overload order
+ *  @return [:big, :little] endianness of +self+
+ * @overload order(order)
+ *  @param  [Symbol] order endianness to set (+:little+, +:big+ or +:network+). +:big+ and +:network+ 
+ *   are synonymous.
+ *  @return [self]
+ */
+static VALUE
+ptr_order(int argc, VALUE* argv, VALUE self)
+{
+    Pointer* ptr;
+
+    Data_Get_Struct(self, Pointer, ptr);
+    if (argc == 0) {
+        int order = (ptr->memory.flags & MEM_SWAP) == 0 ? BYTE_ORDER : SWAPPED_ORDER;
+        return order == BIG_ENDIAN ? ID2SYM(rb_intern("big")) : ID2SYM(rb_intern("little"));
+    } else {
+        VALUE rbOrder = Qnil;
+        int order = BYTE_ORDER;
+
+        if (rb_scan_args(argc, argv, "1", &rbOrder) < 1) {
+            rb_raise(rb_eArgError, "need byte order");
+        }
+        if (SYMBOL_P(rbOrder)) {
+            ID id = SYM2ID(rbOrder);
+            if (id == rb_intern("little")) {
+                order = LITTLE_ENDIAN;
+
+            } else if (id == rb_intern("big") || id == rb_intern("network")) {
+                order = BIG_ENDIAN;
+            }
+        }
+        if (order != BYTE_ORDER) {
+            Pointer* p2;
+            VALUE retval = slice(self, 0, ptr->memory.size);
+
+            Data_Get_Struct(retval, Pointer, p2);
+            p2->memory.flags |= MEM_SWAP;
+            return retval;
+        }
+
+        return self;
+    }
+}
+
+
+/*
+ * call-seq: ptr.free
+ * @return [self]
+ * Free memory pointed by +self+.
+ */
+static VALUE
+ptr_free(VALUE self)
+{
+    Pointer* ptr;
+
+    Data_Get_Struct(self, Pointer, ptr);
+
+    if (ptr->allocated) {
+        if (ptr->storage != NULL) {
+            xfree(ptr->storage);
+            ptr->storage = NULL;
+        }
+        ptr->allocated = false;
+
+    } else {
+        VALUE caller = rb_funcall(rb_funcall(Qnil, rb_intern("caller"), 0), rb_intern("first"), 0);
+        
+        rb_warn("calling free on non allocated pointer %s from %s", RSTRING_PTR(ptr_inspect(self)), RSTRING_PTR(rb_str_to_str(caller)));
+    }
+
+    return self;
+}
+
+static VALUE
+ptr_type_size(VALUE self)
+{
+    Pointer* ptr;
+
+    Data_Get_Struct(self, Pointer, ptr);
+    
+    return INT2NUM(ptr->memory.typeSize);
+}
+
+/*
+ * call-seq: ptr.autorelease = autorelease
+ * @param [Boolean] autorelease
+ * @return [Boolean] +autorelease+
+ * Set +autorelease+ attribute. See also Autorelease section.
+ */
+static VALUE
+ptr_autorelease(VALUE self, VALUE autorelease)
+{
+    Pointer* ptr;
+
+    Data_Get_Struct(self, Pointer, ptr);
+    ptr->autorelease = autorelease == Qtrue;
+
+    return autorelease;
+}
+
+/*
+ * call-seq: ptr.autorelease?
+ * @return [Boolean]
+ * Get +autorelease+ attribute. See also Autorelease section.
+ */
+static VALUE
+ptr_autorelease_p(VALUE self)
+{
+    Pointer* ptr;
+
+    Data_Get_Struct(self, Pointer, ptr);
+    
+    return ptr->autorelease ? Qtrue : Qfalse;
+}
+
+
+static void
+ptr_release(Pointer* ptr)
+{
+    if (ptr->autorelease && ptr->allocated && ptr->storage != NULL) {
+        xfree(ptr->storage);
+        ptr->storage = NULL;
+    }
+    xfree(ptr);
+}
+
+static void
+ptr_mark(Pointer* ptr)
+{
+    rb_gc_mark(ptr->rbParent);
+}
+
+void
+rbffi_Pointer_Init(VALUE moduleFFI)
+{
+    VALUE rbNullAddress = ULL2NUM(0);
+    VALUE ffi_AbstractMemory =  rbffi_AbstractMemoryClass;
+
+    /*
+     * Document-class: FFI::Pointer < FFI::AbstractMemory
+     * Pointer class is used to manage C pointers with ease. A {Pointer} object is defined by his
+     * {#address} (as a C pointer). It permits additions with an integer for pointer arithmetic.
+     *
+     * ==Autorelease
+     * A pointer object may autorelease his contents when freed (by default). This behaviour may be
+     * changed with {#autorelease=} method.
+     */
+    rbffi_PointerClass = rb_define_class_under(moduleFFI, "Pointer", ffi_AbstractMemory);
+    /*
+     * Document-variable: Pointer
+     */
+    rb_global_variable(&rbffi_PointerClass);
+
+    rb_define_alloc_func(rbffi_PointerClass, ptr_allocate);
+    rb_define_method(rbffi_PointerClass, "initialize", ptr_initialize, -1);
+    rb_define_method(rbffi_PointerClass, "initialize_copy", ptr_initialize_copy, 1);
+    rb_define_method(rbffi_PointerClass, "inspect", ptr_inspect, 0);
+    rb_define_method(rbffi_PointerClass, "to_s", ptr_inspect, 0);
+    rb_define_method(rbffi_PointerClass, "+", ptr_plus, 1);
+    rb_define_method(rbffi_PointerClass, "slice", ptr_slice, 2);
+    rb_define_method(rbffi_PointerClass, "null?", ptr_null_p, 0);
+    rb_define_method(rbffi_PointerClass, "address", ptr_address, 0);
+    rb_define_alias(rbffi_PointerClass, "to_i", "address");
+    rb_define_method(rbffi_PointerClass, "==", ptr_equals, 1);
+    rb_define_method(rbffi_PointerClass, "order", ptr_order, -1);
+    rb_define_method(rbffi_PointerClass, "autorelease=", ptr_autorelease, 1);
+    rb_define_method(rbffi_PointerClass, "autorelease?", ptr_autorelease_p, 0);
+    rb_define_method(rbffi_PointerClass, "free", ptr_free, 0);
+    rb_define_method(rbffi_PointerClass, "type_size", ptr_type_size, 0);
+
+    rbffi_NullPointerSingleton = rb_class_new_instance(1, &rbNullAddress, rbffi_PointerClass);
+    /*
+     * NULL pointer
+     */
+    rb_define_const(rbffi_PointerClass, "NULL", rbffi_NullPointerSingleton);
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Pointer.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Pointer.h
new file mode 100755
index 0000000..2d86851
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Pointer.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2008, 2009, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_POINTER_H
+#define	RBFFI_POINTER_H
+
+#ifndef _MSC_VER
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+#endif
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#include "AbstractMemory.h"
+
+extern void rbffi_Pointer_Init(VALUE moduleFFI);
+extern VALUE rbffi_Pointer_NewInstance(void* addr);
+extern VALUE rbffi_PointerClass;
+extern VALUE rbffi_NullPointerSingleton;
+
+typedef struct Pointer {
+    AbstractMemory memory;
+    VALUE rbParent;
+    char* storage; /* start of malloc area */
+    bool autorelease;
+    bool allocated;
+} Pointer;
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_POINTER_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Struct.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Struct.c
new file mode 100755
index 0000000..c6428a2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Struct.c
@@ -0,0 +1,829 @@
+/*
+ * Copyright (c) 2008, 2009, Wayne Meissner
+ * Copyright (C) 2009 Luc Heinrich <luc at honk-honk.com>
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#ifndef _MSC_VER
+# include <sys/param.h>
+# include <stdint.h>
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+# include "win32/stdint.h"
+#endif
+#include <ruby.h>
+#include "rbffi.h"
+#include "compat.h"
+#include "AbstractMemory.h"
+#include "Pointer.h"
+#include "MemoryPointer.h"
+#include "Function.h"
+#include "Types.h"
+#include "Function.h"
+#include "StructByValue.h"
+#include "ArrayType.h"
+#include "MappedType.h"
+#include "Struct.h"
+
+typedef struct InlineArray_ {
+    VALUE rbMemory;
+    VALUE rbField;
+
+    AbstractMemory* memory;
+    StructField* field;
+    MemoryOp *op;
+    Type* componentType;
+    ArrayType* arrayType;
+    int length;
+} InlineArray;
+
+
+static void struct_mark(Struct *);
+static void struct_free(Struct *);
+static VALUE struct_class_layout(VALUE klass);
+static void struct_malloc(Struct* s);
+static void inline_array_mark(InlineArray *);
+static void store_reference_value(StructField* f, Struct* s, VALUE value);
+
+VALUE rbffi_StructClass = Qnil;
+
+VALUE rbffi_StructInlineArrayClass = Qnil;
+VALUE rbffi_StructLayoutCharArrayClass = Qnil;
+
+static ID id_pointer_ivar = 0, id_layout_ivar = 0;
+static ID id_get = 0, id_put = 0, id_to_ptr = 0, id_to_s = 0, id_layout = 0;
+
+static inline char*
+memory_address(VALUE self)
+{
+    return ((AbstractMemory *)DATA_PTR((self)))->address;
+}
+
+static VALUE
+struct_allocate(VALUE klass)
+{
+    Struct* s;
+    VALUE obj = Data_Make_Struct(klass, Struct, struct_mark, struct_free, s);
+    
+    s->rbPointer = Qnil;
+    s->rbLayout = Qnil;
+
+    return obj;
+}
+
+/*
+ * call-seq: initialize
+ * @overload initialize(pointer, *args)
+ *  @param [AbstractMemory] pointer
+ *  @param [Array] args
+ * @return [self]
+ */
+static VALUE
+struct_initialize(int argc, VALUE* argv, VALUE self)
+{
+    Struct* s;
+    VALUE rbPointer = Qnil, rest = Qnil, klass = CLASS_OF(self);
+    int nargs;
+
+    Data_Get_Struct(self, Struct, s);
+    
+    nargs = rb_scan_args(argc, argv, "01*", &rbPointer, &rest);
+
+    /* Call up into ruby code to adjust the layout */
+    if (nargs > 1) {
+        s->rbLayout = rb_funcall2(CLASS_OF(self), id_layout, (int) RARRAY_LEN(rest), RARRAY_PTR(rest));
+    } else {
+        s->rbLayout = struct_class_layout(klass);
+    }
+
+    if (!rb_obj_is_kind_of(s->rbLayout, rbffi_StructLayoutClass)) {
+        rb_raise(rb_eRuntimeError, "Invalid Struct layout");
+    }
+
+    Data_Get_Struct(s->rbLayout, StructLayout, s->layout);
+    
+    if (rbPointer != Qnil) {
+        s->pointer = MEMORY(rbPointer);
+        s->rbPointer = rbPointer;
+    } else {
+        struct_malloc(s);
+    }
+
+    return self;
+}
+
+/*
+ * call-seq: initialize_copy(other)
+ * @return [nil]
+ * DO NOT CALL THIS METHOD
+ */
+static VALUE
+struct_initialize_copy(VALUE self, VALUE other)
+{
+    Struct* src;
+    Struct* dst;
+    
+    Data_Get_Struct(self, Struct, dst);
+    Data_Get_Struct(other, Struct, src);
+    if (dst == src) {
+        return self;
+    }
+    
+    dst->rbLayout = src->rbLayout;
+    dst->layout = src->layout;
+    
+    /*
+     * A new MemoryPointer instance is allocated here instead of just calling
+     * #dup on rbPointer, since the Pointer may not know its length, or may
+     * be longer than just this struct.
+     */
+    if (src->pointer->address != NULL) {
+        dst->rbPointer = rbffi_MemoryPointer_NewInstance(1, src->layout->size, false);
+        dst->pointer = MEMORY(dst->rbPointer);
+        memcpy(dst->pointer->address, src->pointer->address, src->layout->size);
+    } else {
+        dst->rbPointer = src->rbPointer;
+        dst->pointer = src->pointer;
+    }
+
+    if (src->layout->referenceFieldCount > 0) {
+        dst->rbReferences = ALLOC_N(VALUE, dst->layout->referenceFieldCount);
+        memcpy(dst->rbReferences, src->rbReferences, dst->layout->referenceFieldCount * sizeof(VALUE));
+    }
+        
+    return self;
+}
+
+static VALUE
+struct_class_layout(VALUE klass)
+{
+    VALUE layout;
+    if (!rb_ivar_defined(klass, id_layout_ivar)) {
+        rb_raise(rb_eRuntimeError, "no Struct layout configured for %s", rb_class2name(klass));
+    }
+
+    layout = rb_ivar_get(klass, id_layout_ivar);
+    if (!rb_obj_is_kind_of(layout, rbffi_StructLayoutClass)) {
+        rb_raise(rb_eRuntimeError, "invalid Struct layout for %s", rb_class2name(klass));
+    }
+
+    return layout;
+}
+
+static StructLayout*
+struct_layout(VALUE self)
+{
+    Struct* s = (Struct *) DATA_PTR(self);
+    if (s->layout != NULL) {
+        return s->layout;
+    }
+
+    if (s->layout == NULL) {
+        s->rbLayout = struct_class_layout(CLASS_OF(self));
+        Data_Get_Struct(s->rbLayout, StructLayout, s->layout);
+    }
+
+    return s->layout;
+}
+
+static Struct*
+struct_validate(VALUE self)
+{
+    Struct* s;
+    Data_Get_Struct(self, Struct, s);
+
+    if (struct_layout(self) == NULL) {
+        rb_raise(rb_eRuntimeError, "struct layout == null");
+    }
+
+    if (s->pointer == NULL) {
+        struct_malloc(s);
+    }
+
+    return s;
+}
+
+static void
+struct_malloc(Struct* s)
+{
+    if (s->rbPointer == Qnil) {
+        s->rbPointer = rbffi_MemoryPointer_NewInstance(s->layout->size, 1, true);
+
+    } else if (!rb_obj_is_kind_of(s->rbPointer, rbffi_AbstractMemoryClass)) {
+        rb_raise(rb_eRuntimeError, "invalid pointer in struct");
+    }
+
+    s->pointer = (AbstractMemory *) DATA_PTR(s->rbPointer);
+}
+
+static void
+struct_mark(Struct *s)
+{
+    rb_gc_mark(s->rbPointer);
+    rb_gc_mark(s->rbLayout);
+    if (s->rbReferences != NULL) {
+        rb_gc_mark_locations(&s->rbReferences[0], &s->rbReferences[s->layout->referenceFieldCount]);
+    }
+}
+
+static void
+struct_free(Struct* s)
+{
+    xfree(s->rbReferences);
+    xfree(s);
+}
+
+
+static void
+store_reference_value(StructField* f, Struct* s, VALUE value)
+{
+    if (unlikely(f->referenceIndex == -1)) {
+        rb_raise(rb_eRuntimeError, "put_reference_value called for non-reference type");
+        return;
+    }
+    if (s->rbReferences == NULL) {
+        int i;
+        s->rbReferences = ALLOC_N(VALUE, s->layout->referenceFieldCount);
+        for (i = 0; i < s->layout->referenceFieldCount; ++i) {
+            s->rbReferences[i] = Qnil;
+        }
+    }
+
+    s->rbReferences[f->referenceIndex] = value;
+}
+
+
+static VALUE
+struct_field(Struct* s, VALUE fieldName)
+{
+    StructLayout* layout = s->layout;
+    VALUE rbField;
+
+    if (likely(SYMBOL_P(fieldName) && st_lookup(layout->fieldSymbolTable, fieldName, (st_data_t *) &rbField))) {
+        return rbField;
+    }
+
+    // TODO does this ever return anything?
+    rbField = rb_hash_aref(layout->rbFieldMap, fieldName);
+    if (rbField == Qnil) {
+        VALUE str = rb_funcall2(fieldName, id_to_s, 0, NULL);
+        rb_raise(rb_eArgError, "No such field '%s'", StringValuePtr(str));
+    }
+
+    return rbField;
+}
+
+/*
+ * call-seq: struct[field_name]
+ * @param field_name field to access
+ * Acces to a Struct field.
+ */
+static VALUE
+struct_aref(VALUE self, VALUE fieldName)
+{
+    Struct* s;
+    VALUE rbField;
+    StructField* f;
+
+    s = struct_validate(self);
+
+    rbField = struct_field(s, fieldName);
+    f = (StructField *) DATA_PTR(rbField);
+
+    if (f->get != NULL) {
+        return (*f->get)(f, s);
+    
+    } else if (f->memoryOp != NULL) {
+        return (*f->memoryOp->get)(s->pointer, f->offset);
+
+    } else {
+    
+        /* call up to the ruby code to fetch the value */
+        return rb_funcall2(rbField, id_get, 1, &s->rbPointer);
+    }
+}
+
+/*
+ * call-seq: []=(field_name, value)
+ * @param field_name field to access
+ * @param value value to set to +field_name+
+ * @return [value]
+ * Set a field in Struct.
+ */
+static VALUE
+struct_aset(VALUE self, VALUE fieldName, VALUE value)
+{
+    Struct* s;
+    VALUE rbField;
+    StructField* f;
+
+
+    s = struct_validate(self);
+
+    rbField = struct_field(s, fieldName);
+    f = (StructField *) DATA_PTR(rbField);
+    if (f->put != NULL) {
+        (*f->put)(f, s, value);
+
+    } else if (f->memoryOp != NULL) {
+
+        (*f->memoryOp->put)(s->pointer, f->offset, value);
+    
+    } else {
+        /* call up to the ruby code to set the value */
+        VALUE argv[2];
+        argv[0] = s->rbPointer;
+        argv[1] = value;
+        rb_funcall2(rbField, id_put, 2, argv);
+    }
+
+    if (f->referenceRequired) {
+        store_reference_value(f, s, value);
+    }
+    
+    return value;
+}
+
+/*
+ * call-seq: pointer= pointer
+ * @param [AbstractMemory] pointer
+ * @return [self]
+ * Make Struct point to +pointer+.
+ */
+static VALUE
+struct_set_pointer(VALUE self, VALUE pointer)
+{
+    Struct* s;
+    StructLayout* layout;
+    AbstractMemory* memory;
+
+    if (!rb_obj_is_kind_of(pointer, rbffi_AbstractMemoryClass)) {
+        rb_raise(rb_eTypeError, "wrong argument type %s (expected Pointer or Buffer)",
+                rb_obj_classname(pointer));
+        return Qnil;
+    }
+
+    
+    Data_Get_Struct(self, Struct, s);
+    Data_Get_Struct(pointer, AbstractMemory, memory);
+    layout = struct_layout(self);
+
+    if ((int) layout->base.ffiType->size > memory->size) {
+        rb_raise(rb_eArgError, "memory of %ld bytes too small for struct %s (expected at least %ld)",
+                memory->size, rb_obj_classname(self), (long) layout->base.ffiType->size);
+    }
+    
+    s->pointer = MEMORY(pointer);
+    s->rbPointer = pointer;
+    rb_ivar_set(self, id_pointer_ivar, pointer);
+
+    return self;
+}
+
+/*
+ * call-seq: pointer
+ * @return [AbstractMemory]
+ * Get pointer to Struct contents.
+ */
+static VALUE
+struct_get_pointer(VALUE self)
+{
+    Struct* s;
+
+    Data_Get_Struct(self, Struct, s);
+
+    return s->rbPointer;
+}
+
+/*
+ * call-seq: layout= layout
+ * @param [StructLayout] layout
+ * @return [self]
+ * Set the Struct's layout.
+ */
+static VALUE
+struct_set_layout(VALUE self, VALUE layout)
+{
+    Struct* s;
+    Data_Get_Struct(self, Struct, s);
+
+    if (!rb_obj_is_kind_of(layout, rbffi_StructLayoutClass)) {
+        rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
+                rb_obj_classname(layout), rb_class2name(rbffi_StructLayoutClass));
+        return Qnil;
+    }
+
+    Data_Get_Struct(layout, StructLayout, s->layout);
+    rb_ivar_set(self, id_layout_ivar, layout);
+
+    return self;
+}
+
+/*
+ * call-seq: layout
+ * @return [StructLayout]
+ * Get the Struct's layout.
+ */
+static VALUE
+struct_get_layout(VALUE self)
+{
+    Struct* s;
+
+    Data_Get_Struct(self, Struct, s);
+
+    return s->rbLayout;
+}
+
+/*
+ * call-seq: null?
+ * @return [Boolean]
+ * Test if Struct's pointer is NULL
+ */
+static VALUE
+struct_null_p(VALUE self)
+{
+    Struct* s;
+
+    Data_Get_Struct(self, Struct, s);
+
+    return s->pointer->address == NULL ? Qtrue : Qfalse;
+}
+
+/*
+ * (see Pointer#order)
+ */
+static VALUE
+struct_order(int argc, VALUE* argv, VALUE self)
+{
+    Struct* s;
+
+    Data_Get_Struct(self, Struct, s);
+    if (argc == 0) {
+        return rb_funcall(s->rbPointer, rb_intern("order"), 0);
+
+    } else {
+        VALUE retval = rb_obj_dup(self);
+        VALUE rbPointer = rb_funcall2(s->rbPointer, rb_intern("order"), argc, argv);
+        struct_set_pointer(retval, rbPointer);
+        
+        return retval;
+    }
+}
+
+static VALUE
+inline_array_allocate(VALUE klass)
+{
+    InlineArray* array;
+    VALUE obj;
+
+    obj = Data_Make_Struct(klass, InlineArray, inline_array_mark, -1, array);
+    array->rbField = Qnil;
+    array->rbMemory = Qnil;
+
+    return obj;
+}
+
+static void
+inline_array_mark(InlineArray* array)
+{
+    rb_gc_mark(array->rbField);
+    rb_gc_mark(array->rbMemory);
+}
+
+/*
+ * Document-method: FFI::Struct::InlineArray#initialize
+ * call-seq: initialize(memory, field)
+ * @param [AbstractMemory] memory
+ * @param [StructField] field
+ * @return [self]
+ */
+static VALUE
+inline_array_initialize(VALUE self, VALUE rbMemory, VALUE rbField)
+{
+    InlineArray* array;
+    
+    Data_Get_Struct(self, InlineArray, array);
+    array->rbMemory = rbMemory;
+    array->rbField = rbField;
+
+    Data_Get_Struct(rbMemory, AbstractMemory, array->memory);
+    Data_Get_Struct(rbField, StructField, array->field);
+    Data_Get_Struct(array->field->rbType, ArrayType, array->arrayType);
+    Data_Get_Struct(array->arrayType->rbComponentType, Type, array->componentType);
+    
+    array->op = get_memory_op(array->componentType);
+    if (array->op == NULL && array->componentType->nativeType == NATIVE_MAPPED) {
+        array->op = get_memory_op(((MappedType *) array->componentType)->type);
+    }
+    
+    array->length = array->arrayType->length;
+
+    return self;
+}
+
+/*
+ * call-seq: size
+ * @return [Numeric]
+ * Get size
+ */
+static VALUE
+inline_array_size(VALUE self)
+{
+    InlineArray* array;
+
+    Data_Get_Struct(self, InlineArray, array);
+
+    return UINT2NUM(((ArrayType *) array->field->type)->length);
+}
+
+static int
+inline_array_offset(InlineArray* array, int index)
+{
+    if (index < 0 || (index >= array->length && array->length > 0)) {
+        rb_raise(rb_eIndexError, "index %d out of bounds", index);
+    }
+
+    return (int) array->field->offset + (index * (int) array->componentType->ffiType->size);
+}
+
+/*
+ * call-seq: [](index)
+ * @param [Numeric] index
+ * @return [Type, Struct]
+ */
+static VALUE
+inline_array_aref(VALUE self, VALUE rbIndex)
+{
+    InlineArray* array;
+
+    Data_Get_Struct(self, InlineArray, array);
+
+    if (array->op != NULL) {
+        VALUE rbNativeValue = array->op->get(array->memory, 
+                inline_array_offset(array, NUM2INT(rbIndex)));
+        if (unlikely(array->componentType->nativeType == NATIVE_MAPPED)) {
+            return rb_funcall(((MappedType *) array->componentType)->rbConverter, 
+                    rb_intern("from_native"), 2, rbNativeValue, Qnil);
+        } else {
+            return rbNativeValue; 
+        }
+        
+    } else if (array->componentType->nativeType == NATIVE_STRUCT) {
+        VALUE rbOffset = INT2NUM(inline_array_offset(array, NUM2INT(rbIndex)));
+        VALUE rbLength = INT2NUM(array->componentType->ffiType->size);
+        VALUE rbPointer = rb_funcall(array->rbMemory, rb_intern("slice"), 2, rbOffset, rbLength);
+
+        return rb_class_new_instance(1, &rbPointer, ((StructByValue *) array->componentType)->rbStructClass);
+    } else {
+
+        rb_raise(rb_eArgError, "get not supported for %s", rb_obj_classname(array->arrayType->rbComponentType));
+        return Qnil;
+    }
+}
+
+/*
+ * call-seq: []=(index, value)
+ * @param [Numeric] index
+ * @param [Type, Struct]
+ * @return [value]
+ */
+static VALUE
+inline_array_aset(VALUE self, VALUE rbIndex, VALUE rbValue)
+{
+    InlineArray* array;
+
+    Data_Get_Struct(self, InlineArray, array);
+
+    if (array->op != NULL) {
+        if (unlikely(array->componentType->nativeType == NATIVE_MAPPED)) {
+            rbValue = rb_funcall(((MappedType *) array->componentType)->rbConverter, 
+                    rb_intern("to_native"), 2, rbValue, Qnil);
+        }
+        array->op->put(array->memory, inline_array_offset(array, NUM2INT(rbIndex)),
+            rbValue);
+        
+    } else if (array->componentType->nativeType == NATIVE_STRUCT) {
+        int offset = inline_array_offset(array, NUM2INT(rbIndex));
+        Struct* s;
+
+        if (!rb_obj_is_kind_of(rbValue, rbffi_StructClass)) {
+            rb_raise(rb_eTypeError, "argument not an instance of struct");
+            return Qnil;
+        }
+
+        checkWrite(array->memory);
+        checkBounds(array->memory, offset, array->componentType->ffiType->size);
+
+        Data_Get_Struct(rbValue, Struct, s);
+        checkRead(s->pointer);
+        checkBounds(s->pointer, 0, array->componentType->ffiType->size);
+
+        memcpy(array->memory->address + offset, s->pointer->address, array->componentType->ffiType->size);
+
+    } else {
+        ArrayType* arrayType;
+        Data_Get_Struct(array->field->rbType, ArrayType, arrayType);
+
+        rb_raise(rb_eArgError, "set not supported for %s", rb_obj_classname(arrayType->rbComponentType));
+        return Qnil;
+    }
+
+    return rbValue;
+}
+
+/*
+ * call-seq: each
+ * Yield block for each element of +self+.
+ */
+static VALUE
+inline_array_each(VALUE self)
+{
+    InlineArray* array;
+    
+    int i;
+
+    Data_Get_Struct(self, InlineArray, array);
+    
+    for (i = 0; i < array->length; ++i) {
+        rb_yield(inline_array_aref(self, INT2FIX(i)));
+    }
+
+    return self;
+}
+
+/*
+ * call-seq: to_a
+ * @return [Array]
+ * Convert +self+ to an array.
+ */
+static VALUE
+inline_array_to_a(VALUE self)
+{
+    InlineArray* array;
+    VALUE obj;
+    int i;
+
+    Data_Get_Struct(self, InlineArray, array);
+    obj = rb_ary_new2(array->length);
+
+    
+    for (i = 0; i < array->length; ++i) {
+        rb_ary_push(obj, inline_array_aref(self, INT2FIX(i)));
+    }
+
+    return obj;
+}
+
+/*
+ * Document-method: FFI::StructLayout::CharArray#to_s
+ * call-seq: to_s
+ * @return [String]
+ * Convert +self+ to a string.
+ */
+static VALUE
+inline_array_to_s(VALUE self)
+{
+    InlineArray* array;
+    VALUE argv[2];
+
+    Data_Get_Struct(self, InlineArray, array);
+ 
+    if (array->componentType->nativeType != NATIVE_INT8 && array->componentType->nativeType != NATIVE_UINT8) {
+        VALUE dummy = Qnil;
+        return rb_call_super(0, &dummy);
+    }
+
+    argv[0] = UINT2NUM(array->field->offset);
+    argv[1] = UINT2NUM(array->length);
+
+    return rb_funcall2(array->rbMemory, rb_intern("get_string"), 2, argv);
+}
+
+/*
+ * call-seq: to_ptr
+ * @return [AbstractMemory]
+ * Get pointer to +self+ content.
+ */
+static VALUE
+inline_array_to_ptr(VALUE self)
+{
+    InlineArray* array;
+    
+    Data_Get_Struct(self, InlineArray, array);
+
+    return rb_funcall(array->rbMemory, rb_intern("slice"), 2,
+        UINT2NUM(array->field->offset), UINT2NUM(array->arrayType->base.ffiType->size));
+}
+
+
+void
+rbffi_Struct_Init(VALUE moduleFFI)
+{
+    VALUE StructClass;
+
+    rbffi_StructLayout_Init(moduleFFI);
+
+    /*
+     * Document-class: FFI::Struct
+     *
+     * A FFI::Struct means to mirror a C struct.
+     *
+     * A Struct is defined as:
+     *  class MyStruct < FFI::Struct
+     *    layout :value1, :int,
+     *           :value2, :double
+     *  end
+     * and is used as:
+     *  my_struct = MyStruct.new
+     *  my_struct[:value1] = 12
+     *
+     * For more information, see http://github.com/ffi/ffi/wiki/Structs
+     */
+    rbffi_StructClass = rb_define_class_under(moduleFFI, "Struct", rb_cObject);
+    StructClass = rbffi_StructClass; // put on a line alone to help RDoc
+    rb_global_variable(&rbffi_StructClass);
+
+    /*
+     * Document-class: FFI::Struct::InlineArray
+     */
+    rbffi_StructInlineArrayClass = rb_define_class_under(rbffi_StructClass, "InlineArray", rb_cObject);
+    rb_global_variable(&rbffi_StructInlineArrayClass);
+
+    /*
+     * Document-class: FFI::StructLayout::CharArray < FFI::Struct::InlineArray
+     */
+    rbffi_StructLayoutCharArrayClass = rb_define_class_under(rbffi_StructLayoutClass, "CharArray", 
+                                                             rbffi_StructInlineArrayClass);
+    rb_global_variable(&rbffi_StructLayoutCharArrayClass);
+
+
+    rb_define_alloc_func(StructClass, struct_allocate);
+    rb_define_method(StructClass, "initialize", struct_initialize, -1);
+    rb_define_method(StructClass, "initialize_copy", struct_initialize_copy, 1);
+    rb_define_method(StructClass, "order", struct_order, -1);
+    
+    rb_define_alias(rb_singleton_class(StructClass), "alloc_in", "new");
+    rb_define_alias(rb_singleton_class(StructClass), "alloc_out", "new");
+    rb_define_alias(rb_singleton_class(StructClass), "alloc_inout", "new");
+    rb_define_alias(rb_singleton_class(StructClass), "new_in", "new");
+    rb_define_alias(rb_singleton_class(StructClass), "new_out", "new");
+    rb_define_alias(rb_singleton_class(StructClass), "new_inout", "new");
+
+    rb_define_method(StructClass, "pointer", struct_get_pointer, 0);
+    rb_define_private_method(StructClass, "pointer=", struct_set_pointer, 1);
+
+    rb_define_method(StructClass, "layout", struct_get_layout, 0);
+    rb_define_private_method(StructClass, "layout=", struct_set_layout, 1);
+
+    rb_define_method(StructClass, "[]", struct_aref, 1);
+    rb_define_method(StructClass, "[]=", struct_aset, 2);
+    rb_define_method(StructClass, "null?", struct_null_p, 0);
+
+    rb_include_module(rbffi_StructInlineArrayClass, rb_mEnumerable);
+    rb_define_alloc_func(rbffi_StructInlineArrayClass, inline_array_allocate);
+    rb_define_method(rbffi_StructInlineArrayClass, "initialize", inline_array_initialize, 2);
+    rb_define_method(rbffi_StructInlineArrayClass, "[]", inline_array_aref, 1);
+    rb_define_method(rbffi_StructInlineArrayClass, "[]=", inline_array_aset, 2);
+    rb_define_method(rbffi_StructInlineArrayClass, "each", inline_array_each, 0);
+    rb_define_method(rbffi_StructInlineArrayClass, "size", inline_array_size, 0);
+    rb_define_method(rbffi_StructInlineArrayClass, "to_a", inline_array_to_a, 0);
+    rb_define_method(rbffi_StructInlineArrayClass, "to_ptr", inline_array_to_ptr, 0);
+
+    rb_define_method(rbffi_StructLayoutCharArrayClass, "to_s", inline_array_to_s, 0);
+    rb_define_alias(rbffi_StructLayoutCharArrayClass, "to_str", "to_s");
+
+    id_pointer_ivar = rb_intern("@pointer");
+    id_layout_ivar = rb_intern("@layout");
+    id_layout = rb_intern("layout");
+    id_get = rb_intern("get");
+    id_put = rb_intern("put");
+    id_to_ptr = rb_intern("to_ptr");
+    id_to_s = rb_intern("to_s");
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Struct.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Struct.h
new file mode 100755
index 0000000..85e8263
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Struct.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2008, 2009, Wayne Meissner
+ * Copyright (c) 2009, Luc Heinrich <luc at honk-honk.com>
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_STRUCT_H
+#define	RBFFI_STRUCT_H
+
+#include "extconf.h"
+#include "AbstractMemory.h"
+#include "Type.h"
+#ifdef RUBY_1_9
+#include <ruby/st.h>
+#else
+#include <st.h>
+#endif
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+    extern void rbffi_Struct_Init(VALUE ffiModule);
+    extern void rbffi_StructLayout_Init(VALUE ffiModule);
+    typedef struct StructField_ StructField;
+    typedef struct StructLayout_ StructLayout;
+    typedef struct Struct_ Struct;
+
+    struct StructField_ {
+        Type* type;
+        unsigned int offset;
+
+        int referenceIndex;
+
+        bool referenceRequired;
+        VALUE rbType;
+        VALUE rbName;
+
+        VALUE (*get)(StructField* field, Struct* s);
+        void (*put)(StructField* field, Struct* s, VALUE value);
+
+        MemoryOp* memoryOp;
+    };
+
+    struct StructLayout_ {
+        Type base;
+        StructField** fields;
+        int fieldCount;
+        int size;
+        int align;
+        ffi_type** ffiTypes;
+        struct st_table* fieldSymbolTable;
+
+        /** The number of reference tracking fields in this struct */
+        int referenceFieldCount;
+        
+        VALUE rbFieldNames;
+        VALUE rbFieldMap;
+        VALUE rbFields;
+    };
+
+    struct Struct_ {
+        StructLayout* layout;
+        AbstractMemory* pointer;
+        VALUE* rbReferences;
+
+        VALUE rbLayout;
+        VALUE rbPointer;
+    };
+
+    extern VALUE rbffi_StructClass, rbffi_StructLayoutClass;
+    extern VALUE rbffi_StructLayoutFieldClass, rbffi_StructLayoutFunctionFieldClass;
+    extern VALUE rbffi_StructLayoutArrayFieldClass;
+    extern VALUE rbffi_StructInlineArrayClass;
+    extern VALUE rbffi_StructLayoutCharArrayClass;
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_STRUCT_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/StructByReference.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/StructByReference.c
new file mode 100755
index 0000000..73e5111
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/StructByReference.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2010, Wayne Meissner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * The name of the author or authors may not be used to endorse or promote
+ *   products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MSC_VER
+# include <sys/param.h>
+#endif
+#include <sys/types.h>
+#include <stdio.h>
+#ifndef _MSC_VER
+# include <stdint.h>
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+# include "win32/stdint.h"
+#endif
+#include <errno.h>
+#include <ruby.h>
+
+#include <ffi.h>
+#include "rbffi.h"
+#include "compat.h"
+
+#include "Pointer.h"
+#include "Struct.h"
+#include "StructByReference.h"
+
+
+#define FFI_ALIGN(v, a)  (((((size_t) (v))-1) | ((a)-1))+1)
+
+static VALUE sbr_allocate(VALUE);
+static VALUE sbr_initialize(VALUE, VALUE);
+static void sbr_mark(StructByReference *);
+
+VALUE rbffi_StructByReferenceClass = Qnil;
+
+static VALUE
+sbr_allocate(VALUE klass)
+{
+    StructByReference* sbr;
+
+    VALUE obj = Data_Make_Struct(klass, StructByReference, sbr_mark, -1, sbr);
+
+    sbr->rbStructClass = Qnil;
+
+    return obj;
+}
+
+/*
+ * call-seq: initialize(struc_class)
+ * @param [Struct] struct_calss
+ * @return [self]
+ * A new instance of StructByReference.
+ */
+static VALUE
+sbr_initialize(VALUE self, VALUE rbStructClass)
+{
+    StructByReference* sbr = NULL;
+    
+    if (!rb_class_inherited_p(rbStructClass, rbffi_StructClass)) {
+        rb_raise(rb_eTypeError, "wrong type (expected subclass of FFI::Struct)");
+    }
+
+    Data_Get_Struct(self, StructByReference, sbr);
+    sbr->rbStructClass = rbStructClass;
+    
+    return self;
+}
+
+static void
+sbr_mark(StructByReference *sbr)
+{
+    rb_gc_mark(sbr->rbStructClass);
+}
+
+
+/*
+ * call-seq: struct_class
+ * @return [Struct]
+ * Get +struct_class+.
+ */
+static VALUE
+sbr_struct_class(VALUE self)
+{
+    StructByReference* sbr;
+
+    Data_Get_Struct(self, StructByReference, sbr);
+
+    return sbr->rbStructClass;
+}
+
+/*
+ * call-seq: native_type
+ * @return [Class]
+ * Always get {FFI::Type}::POINTER.
+ */
+static VALUE
+sbr_native_type(VALUE self)
+{
+    return rb_const_get(rbffi_TypeClass, rb_intern("POINTER"));
+}
+
+/*
+ * call-seq: to_native(value, ctx)
+ * @param [nil, Struct] value
+ * @param [nil] ctx
+ * @return [AbstractMemory] Pointer on +value+.
+ */
+static VALUE
+sbr_to_native(VALUE self, VALUE value, VALUE ctx)
+{
+    StructByReference* sbr;
+    Struct* s;
+
+    if (unlikely(value == Qnil)) {
+        return rbffi_NullPointerSingleton;
+    }
+
+    Data_Get_Struct(self, StructByReference, sbr);
+    if (!rb_obj_is_kind_of(value, sbr->rbStructClass)) {
+        rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
+                rb_obj_classname(value),
+                RSTRING_PTR(rb_class_name(sbr->rbStructClass)));
+    }
+
+    Data_Get_Struct(value, Struct, s);
+
+    return s->rbPointer;
+}
+
+/*
+ * call-seq: from_native(value, ctx)
+ * @param [AbstractMemory] value
+ * @param [nil] ctx
+ * @return [Struct]
+ * Create a struct from content of memory +value+.
+ */
+static VALUE
+sbr_from_native(VALUE self, VALUE value, VALUE ctx)
+{
+    StructByReference* sbr;
+
+    Data_Get_Struct(self, StructByReference, sbr);
+
+    return rb_class_new_instance(1, &value, sbr->rbStructClass);
+}
+
+
+void
+rbffi_StructByReference_Init(VALUE moduleFFI)
+{
+    /*
+     * Document-class: FFI::StructByReference
+     * This class includes {FFI::DataConverter} module.
+     */
+    rbffi_StructByReferenceClass = rb_define_class_under(moduleFFI, "StructByReference", rb_cObject);
+    rb_global_variable(&rbffi_StructByReferenceClass);
+    rb_include_module(rbffi_StructByReferenceClass, rb_const_get(moduleFFI, rb_intern("DataConverter")));
+    
+    rb_define_alloc_func(rbffi_StructByReferenceClass, sbr_allocate);
+    rb_define_method(rbffi_StructByReferenceClass, "initialize", sbr_initialize, 1);
+    rb_define_method(rbffi_StructByReferenceClass, "struct_class", sbr_struct_class, 0);
+    rb_define_method(rbffi_StructByReferenceClass, "native_type", sbr_native_type, 0);
+    rb_define_method(rbffi_StructByReferenceClass, "to_native", sbr_to_native, 2);
+    rb_define_method(rbffi_StructByReferenceClass, "from_native", sbr_from_native, 2);
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/StructByReference.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/StructByReference.h
new file mode 100755
index 0000000..cf797af
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/StructByReference.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2009, Wayne Meissner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * The name of the author or authors may not be used to endorse or promote
+ *   products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_STRUCTBYREFERENCE_H
+#define	RBFFI_STRUCTBYREFERENCE_H
+
+#include <ruby.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct StructByReference_ {
+    VALUE rbStructClass;
+} StructByReference;
+
+void rbffi_StructByReference_Init(VALUE moduleFFI);
+
+extern VALUE rbffi_StructByReferenceClass;
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_STRUCTBYREFERENCE_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/StructByValue.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/StructByValue.c
new file mode 100755
index 0000000..0d9fb9c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/StructByValue.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2009, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MSC_VER
+#include <sys/param.h>
+#endif
+#include <sys/types.h>
+#include <stdio.h>
+#ifndef _MSC_VER
+# include <stdint.h>
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+# include "win32/stdint.h"
+#endif
+#include <errno.h>
+#include <ruby.h>
+
+#include <ffi.h>
+#include "rbffi.h"
+#include "compat.h"
+
+#include "Type.h"
+#include "StructByValue.h"
+#include "Struct.h"
+
+#define FFI_ALIGN(v, a)  (((((size_t) (v))-1) | ((a)-1))+1)
+
+static VALUE sbv_allocate(VALUE);
+static VALUE sbv_initialize(VALUE, VALUE);
+static void sbv_mark(StructByValue *);
+static void sbv_free(StructByValue *);
+
+VALUE rbffi_StructByValueClass = Qnil;
+
+static VALUE
+sbv_allocate(VALUE klass)
+{
+    StructByValue* sbv;
+
+    VALUE obj = Data_Make_Struct(klass, StructByValue, sbv_mark, sbv_free, sbv);
+
+    sbv->rbStructClass = Qnil;
+    sbv->rbStructLayout = Qnil;
+    sbv->base.nativeType = NATIVE_STRUCT;
+
+    sbv->base.ffiType = xcalloc(1, sizeof(*sbv->base.ffiType));
+    sbv->base.ffiType->size = 0;
+    sbv->base.ffiType->alignment = 1;
+    sbv->base.ffiType->type = FFI_TYPE_STRUCT;
+
+    return obj;
+}
+
+static VALUE
+sbv_initialize(VALUE self, VALUE rbStructClass)
+{
+    StructByValue* sbv = NULL;
+    StructLayout* layout = NULL;
+    VALUE rbLayout = Qnil;
+
+    rbLayout = rb_ivar_get(rbStructClass, rb_intern("@layout"));
+    if (!rb_obj_is_instance_of(rbLayout, rbffi_StructLayoutClass)) {
+        rb_raise(rb_eTypeError, "wrong type in @layout ivar (expected FFI::StructLayout)");
+    }
+
+    Data_Get_Struct(rbLayout, StructLayout, layout);
+    Data_Get_Struct(self, StructByValue, sbv);
+    sbv->rbStructClass = rbStructClass;
+    sbv->rbStructLayout = rbLayout;
+
+    /* We can just use everything from the ffi_type directly */
+    *sbv->base.ffiType = *layout->base.ffiType;
+    
+    return self;
+}
+
+static void
+sbv_mark(StructByValue *sbv)
+{
+    rb_gc_mark(sbv->rbStructClass);
+    rb_gc_mark(sbv->rbStructLayout);
+}
+
+static void
+sbv_free(StructByValue *sbv)
+{
+    xfree(sbv->base.ffiType);
+    xfree(sbv);
+}
+
+
+static VALUE
+sbv_layout(VALUE self)
+{
+    StructByValue* sbv;
+
+    Data_Get_Struct(self, StructByValue, sbv);
+    return sbv->rbStructLayout;
+}
+
+static VALUE
+sbv_struct_class(VALUE self)
+{
+    StructByValue* sbv;
+
+    Data_Get_Struct(self, StructByValue, sbv);
+
+    return sbv->rbStructClass;
+}
+
+void
+rbffi_StructByValue_Init(VALUE moduleFFI)
+{
+    rbffi_StructByValueClass = rb_define_class_under(moduleFFI, "StructByValue", rbffi_TypeClass);
+    rb_global_variable(&rbffi_StructByValueClass);
+    rb_define_const(rbffi_TypeClass, "Struct", rbffi_StructByValueClass);
+
+    rb_define_alloc_func(rbffi_StructByValueClass, sbv_allocate);
+    rb_define_method(rbffi_StructByValueClass, "initialize", sbv_initialize, 1);
+    rb_define_method(rbffi_StructByValueClass, "layout", sbv_layout, 0);
+    rb_define_method(rbffi_StructByValueClass, "struct_class", sbv_struct_class, 0);
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/StructByValue.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/StructByValue.h
new file mode 100755
index 0000000..07b2763
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/StructByValue.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_STRUCTBYVALUE_H
+#define	RBFFI_STRUCTBYVALUE_H
+
+#include <ruby.h>
+#include "Type.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct StructByValue_ {
+    Type base;
+    VALUE rbStructClass;
+    VALUE rbStructLayout;
+} StructByValue;
+
+void rbffi_StructByValue_Init(VALUE moduleFFI);
+
+extern VALUE rbffi_StructByValueClass;
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_STRUCTBYVALUE_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/StructLayout.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/StructLayout.c
new file mode 100755
index 0000000..483e532
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/StructLayout.c
@@ -0,0 +1,698 @@
+/*
+ * Copyright (c) 2008, 2009, Wayne Meissner
+ * Copyright (c) 2009, Luc Heinrich <luc at honk-honk.com>
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+
+#ifndef _MSC_VER
+# include <sys/param.h>
+# include <stdint.h>
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+# include "win32/stdint.h"
+#endif
+#include <ruby.h>
+#include "rbffi.h"
+#include "compat.h"
+#include "AbstractMemory.h"
+#include "Pointer.h"
+#include "MemoryPointer.h"
+#include "Function.h"
+#include "Types.h"
+#include "StructByValue.h"
+#include "ArrayType.h"
+#include "Function.h"
+#include "MappedType.h"
+#include "Struct.h"
+
+#define FFI_ALIGN(v, a)  (((((size_t) (v))-1) | ((a)-1))+1)
+
+static void struct_layout_mark(StructLayout *);
+static void struct_layout_free(StructLayout *);
+static void struct_field_mark(StructField* );
+
+VALUE rbffi_StructLayoutFieldClass = Qnil;
+VALUE rbffi_StructLayoutNumberFieldClass = Qnil, rbffi_StructLayoutPointerFieldClass = Qnil;
+VALUE rbffi_StructLayoutStringFieldClass = Qnil;
+VALUE rbffi_StructLayoutFunctionFieldClass = Qnil, rbffi_StructLayoutArrayFieldClass = Qnil;
+
+VALUE rbffi_StructLayoutClass = Qnil;
+
+
+static VALUE
+struct_field_allocate(VALUE klass)
+{
+    StructField* field;
+    VALUE obj;
+
+    obj = Data_Make_Struct(klass, StructField, struct_field_mark, -1, field);
+    field->rbType = Qnil;
+    field->rbName = Qnil;
+
+    return obj;
+}
+
+static void
+struct_field_mark(StructField* f)
+{
+    rb_gc_mark(f->rbType);
+    rb_gc_mark(f->rbName);
+}
+
+/*
+ * call-seq: initialize(name, offset, type)
+ * @param [String,Symbol] name
+ * @param [Fixnum] offset
+ * @param [FFI::Type] type
+ * @return [self]
+ * A new FFI::StructLayout::Field instance.
+ */
+static VALUE
+struct_field_initialize(int argc, VALUE* argv, VALUE self)
+{
+    VALUE rbOffset = Qnil, rbName = Qnil, rbType = Qnil;
+    StructField* field;
+    int nargs;
+
+    Data_Get_Struct(self, StructField, field);
+
+    nargs = rb_scan_args(argc, argv, "3", &rbName, &rbOffset, &rbType);
+
+    if (TYPE(rbName) != T_SYMBOL && TYPE(rbName) != T_STRING) {
+        rb_raise(rb_eTypeError, "wrong argument type %s (expected Symbol/String)",
+                rb_obj_classname(rbName));
+    }
+
+    Check_Type(rbOffset, T_FIXNUM);
+
+    if (!rb_obj_is_kind_of(rbType, rbffi_TypeClass)) {
+        rb_raise(rb_eTypeError, "wrong argument type %s (expected FFI::Type)",
+                rb_obj_classname(rbType));
+    }
+
+    field->offset = NUM2UINT(rbOffset);
+    field->rbName = (TYPE(rbName) == T_SYMBOL) ? rbName : rb_str_intern(rbName);
+    field->rbType = rbType;
+    Data_Get_Struct(field->rbType, Type, field->type);
+    field->memoryOp = get_memory_op(field->type);
+    field->referenceIndex = -1;
+
+    switch (field->type->nativeType == NATIVE_MAPPED ? ((MappedType *) field->type)->type->nativeType : field->type->nativeType) {
+        case NATIVE_FUNCTION:
+        case NATIVE_CALLBACK:
+        case NATIVE_POINTER:
+            field->referenceRequired = true;
+            break;
+
+        default:
+            field->referenceRequired = (rb_respond_to(self, rb_intern("reference_required?"))
+                    && RTEST(rb_funcall2(self, rb_intern("reference_required?"), 0, NULL)))
+                    || (rb_respond_to(rbType, rb_intern("reference_required?"))
+                        && RTEST(rb_funcall2(rbType, rb_intern("reference_required?"), 0, NULL)));
+            break;
+    }
+    
+    return self;
+}
+
+/*
+ * call-seq: offset
+ * @return [Numeric]
+ * Get the field offset.
+ */
+static VALUE
+struct_field_offset(VALUE self)
+{
+    StructField* field;
+    Data_Get_Struct(self, StructField, field);
+    return UINT2NUM(field->offset);
+}
+
+/*
+ * call-seq: size
+ * @return [Numeric]
+ * Get the field size.
+ */
+static VALUE
+struct_field_size(VALUE self)
+{
+    StructField* field;
+    Data_Get_Struct(self, StructField, field);
+    return UINT2NUM(field->type->ffiType->size);
+}
+
+/*
+ * call-seq: alignment
+ * @return [Numeric]
+ * Get the field alignment.
+ */
+static VALUE
+struct_field_alignment(VALUE self)
+{
+    StructField* field;
+    Data_Get_Struct(self, StructField, field);
+    return UINT2NUM(field->type->ffiType->alignment);
+}
+
+/*
+ * call-seq: type
+ * @return [Type]
+ * Get the field type.
+ */
+static VALUE
+struct_field_type(VALUE self)
+{
+    StructField* field;
+    Data_Get_Struct(self, StructField, field);
+
+    return field->rbType;
+}
+
+/*
+ * call-seq: name
+ * @return [Symbol]
+ * Get the field name.
+ */
+static VALUE
+struct_field_name(VALUE self)
+{
+    StructField* field;
+    Data_Get_Struct(self, StructField, field);
+    return field->rbName;
+}
+
+/*
+ * call-seq: get(pointer)
+ * @param [AbstractMemory] pointer pointer on a {Struct}
+ * @return [Object]
+ * Get an object of type {#type} from memory pointed by +pointer+.
+ */
+static VALUE
+struct_field_get(VALUE self, VALUE pointer)
+{
+    StructField* f;
+
+    Data_Get_Struct(self, StructField, f);
+    if (f->memoryOp == NULL) {
+        rb_raise(rb_eArgError, "get not supported for %s", rb_obj_classname(f->rbType));
+        return Qnil;
+    }
+
+    return (*f->memoryOp->get)(MEMORY(pointer), f->offset);
+}
+
+/*
+ * call-seq: put(pointer, value)
+ * @param [AbstractMemory] pointer pointer on a {Struct}
+ * @param [Object] value this object must be a kind of {#type}
+ * @return [self]
+ * Put an object to memory pointed by +pointer+.
+ */
+static VALUE
+struct_field_put(VALUE self, VALUE pointer, VALUE value)
+{
+    StructField* f;
+    
+    Data_Get_Struct(self, StructField, f);
+    if (f->memoryOp == NULL) {
+        rb_raise(rb_eArgError, "put not supported for %s", rb_obj_classname(f->rbType));
+        return self;
+    }
+
+    (*f->memoryOp->put)(MEMORY(pointer), f->offset, value);
+
+    return self;
+}
+
+/*
+ * call-seq: get(pointer)
+ * @param [AbstractMemory] pointer pointer on a {Struct}
+ * @return [Function]
+ * Get a {Function} from memory pointed by +pointer+.
+ */
+static VALUE
+function_field_get(VALUE self, VALUE pointer)
+{
+    StructField* f;
+    
+    Data_Get_Struct(self, StructField, f);
+
+    return rbffi_Function_NewInstance(f->rbType, (*rbffi_AbstractMemoryOps.pointer->get)(MEMORY(pointer), f->offset));
+}
+
+/*
+ * call-seq: put(pointer, proc)
+ * @param [AbstractMemory] pointer pointer to a {Struct}
+ * @param [Function, Proc] proc
+ * @return [Function]
+ * Set a {Function} to memory pointed by +pointer+ as a function. 
+ *
+ * If a Proc is submitted as +proc+, it is automatically transformed to a {Function}.
+ */
+static VALUE
+function_field_put(VALUE self, VALUE pointer, VALUE proc)
+{
+    StructField* f;
+    VALUE value = Qnil;
+
+    Data_Get_Struct(self, StructField, f);
+
+    if (NIL_P(proc) || rb_obj_is_kind_of(proc, rbffi_FunctionClass)) {
+        value = proc;
+    } else if (rb_obj_is_kind_of(proc, rb_cProc) || rb_respond_to(proc, rb_intern("call"))) {
+        value = rbffi_Function_ForProc(f->rbType, proc);
+    } else {
+        rb_raise(rb_eTypeError, "wrong type (expected Proc or Function)");
+    }
+
+    (*rbffi_AbstractMemoryOps.pointer->put)(MEMORY(pointer), f->offset, value);
+
+    return self;
+}
+
+static inline bool
+isCharArray(ArrayType* arrayType)
+{
+    return arrayType->componentType->nativeType == NATIVE_INT8
+            || arrayType->componentType->nativeType == NATIVE_UINT8;
+}
+
+/*
+ * call-seq: get(pointer)
+ * @param [AbstractMemory] pointer pointer on a {Struct}
+ * @return [FFI::StructLayout::CharArray, FFI::Struct::InlineArray]
+ * Get an array from a {Struct}.
+ */
+static VALUE
+array_field_get(VALUE self, VALUE pointer)
+{
+    StructField* f;
+    ArrayType* array;
+    VALUE argv[2];
+
+    Data_Get_Struct(self, StructField, f);
+    Data_Get_Struct(f->rbType, ArrayType, array);
+
+    argv[0] = pointer;
+    argv[1] = self;
+
+    return rb_class_new_instance(2, argv, isCharArray(array)
+            ? rbffi_StructLayoutCharArrayClass : rbffi_StructInlineArrayClass);
+}
+
+/*
+ * call-seq: put(pointer, value)
+ * @param [AbstractMemory] pointer pointer on a {Struct}
+ * @param [String, Array] value +value+ may be a String only if array's type is a kind of +int8+
+ * @return [value]
+ * Set an array in a {Struct}.
+ */
+static VALUE
+array_field_put(VALUE self, VALUE pointer, VALUE value)
+{
+    StructField* f;
+    ArrayType* array;
+    
+
+    Data_Get_Struct(self, StructField, f);
+    Data_Get_Struct(f->rbType, ArrayType, array);
+    
+    if (isCharArray(array) && rb_obj_is_instance_of(value, rb_cString)) {
+        VALUE argv[2];
+
+        argv[0] = INT2FIX(f->offset);
+        argv[1] = value;
+
+        rb_funcall2(pointer, rb_intern("put_string"), 2, argv);
+
+    } else {
+#ifdef notyet
+        MemoryOp* op;
+        int count = RARRAY_LEN(value);
+        int i;
+        AbstractMemory* memory = MEMORY(pointer);
+
+        if (count > array->length) {
+            rb_raise(rb_eIndexError, "array too large");
+        }
+
+        /* clear the contents in case of a short write */
+        checkWrite(memory);
+        checkBounds(memory, f->offset, f->type->ffiType->size);
+        if (count < array->length) {
+            memset(memory->address + f->offset + (count * array->componentType->ffiType->size),
+                    0, (array->length - count) * array->componentType->ffiType->size);
+        }
+
+        /* now copy each element in */
+        if ((op = get_memory_op(array->componentType)) != NULL) {
+
+            for (i = 0; i < count; ++i) {
+                (*op->put)(memory, f->offset + (i * array->componentType->ffiType->size), rb_ary_entry(value, i));
+            }
+
+        } else if (array->componentType->nativeType == NATIVE_STRUCT) {
+
+            for (i = 0; i < count; ++i) {
+                VALUE entry = rb_ary_entry(value, i);
+                Struct* s;
+
+                if (!rb_obj_is_kind_of(entry, rbffi_StructClass)) {
+                    rb_raise(rb_eTypeError, "array element not an instance of FFI::Struct");
+                    break;
+                }
+
+                Data_Get_Struct(entry, Struct, s);
+                checkRead(s->pointer);
+                checkBounds(s->pointer, 0, array->componentType->ffiType->size);
+
+                memcpy(memory->address + f->offset + (i * array->componentType->ffiType->size),
+                        s->pointer->address, array->componentType->ffiType->size);
+            }
+
+        } else {
+            rb_raise(rb_eNotImpError, "put not supported for arrays of type %s", rb_obj_classname(array->rbComponentType));
+        }
+#else
+        rb_raise(rb_eNotImpError, "cannot set array field");
+#endif
+    }
+
+    return value;
+}
+
+
+static VALUE
+struct_layout_allocate(VALUE klass)
+{
+    StructLayout* layout;
+    VALUE obj;
+
+    obj = Data_Make_Struct(klass, StructLayout, struct_layout_mark, struct_layout_free, layout);
+    layout->rbFieldMap = Qnil;
+    layout->rbFieldNames = Qnil;
+    layout->rbFields = Qnil;
+    layout->fieldSymbolTable = st_init_numtable();
+    layout->base.ffiType = xcalloc(1, sizeof(*layout->base.ffiType));
+    layout->base.ffiType->size = 0;
+    layout->base.ffiType->alignment = 0;
+    layout->base.ffiType->type = FFI_TYPE_STRUCT;
+
+    return obj;
+}
+
+/*
+ * call-seq: initialize(fields, size, align)
+ * @param [Array<StructLayout::Field>] fields
+ * @param [Numeric] size
+ * @param [Numeric] align
+ * @return [self]
+ * A new StructLayout instance.
+ */
+static VALUE
+struct_layout_initialize(VALUE self, VALUE fields, VALUE size, VALUE align)
+{
+    StructLayout* layout;
+    ffi_type* ltype;
+    int i;
+
+    Data_Get_Struct(self, StructLayout, layout);
+    layout->fieldCount = (int) RARRAY_LEN(fields);
+    layout->rbFieldMap = rb_hash_new();
+    layout->rbFieldNames = rb_ary_new2(layout->fieldCount);
+    layout->size = (int) FFI_ALIGN(NUM2INT(size),  NUM2INT(align));
+    layout->align = NUM2INT(align);
+    layout->fields = xcalloc(layout->fieldCount, sizeof(StructField *));
+    layout->ffiTypes = xcalloc(layout->fieldCount + 1, sizeof(ffi_type *));
+    layout->rbFields = rb_ary_new2(layout->fieldCount);
+    layout->referenceFieldCount = 0;
+    layout->base.ffiType->elements = layout->ffiTypes;
+    layout->base.ffiType->size = layout->size;
+    layout->base.ffiType->alignment = layout->align;
+
+    ltype = layout->base.ffiType;
+    for (i = 0; i < (int) layout->fieldCount; ++i) {
+        VALUE rbField = rb_ary_entry(fields, i);
+        VALUE rbName;
+        StructField* field;
+        ffi_type* ftype;
+
+
+        if (!rb_obj_is_kind_of(rbField, rbffi_StructLayoutFieldClass)) {
+            rb_raise(rb_eTypeError, "wrong type for field %d.", i);
+        }
+        rbName = rb_funcall2(rbField, rb_intern("name"), 0, NULL);
+
+        Data_Get_Struct(rbField, StructField, field);
+        layout->fields[i] = field;
+
+        if (field->type == NULL || field->type->ffiType == NULL) {
+            rb_raise(rb_eRuntimeError, "type of field %d not supported", i);
+        }
+
+        ftype = field->type->ffiType;
+        if (ftype->size == 0 && i < ((int) layout->fieldCount - 1)) {
+            rb_raise(rb_eTypeError, "type of field %d has zero size", i);
+        }
+
+        if (field->referenceRequired) {
+            field->referenceIndex = layout->referenceFieldCount++;
+        }
+
+
+        layout->ffiTypes[i] = ftype->size > 0 ? ftype : NULL;
+        st_insert(layout->fieldSymbolTable, rbName, rbField);
+        rb_hash_aset(layout->rbFieldMap, rbName, rbField);
+        rb_ary_push(layout->rbFields, rbField);
+        rb_ary_push(layout->rbFieldNames, rbName);
+    }
+
+    if (ltype->size == 0) {
+        rb_raise(rb_eRuntimeError, "Struct size is zero");
+    }
+
+    return self;
+}
+
+/* 
+ * call-seq: [](field)
+ * @param [Symbol] field
+ * @return [StructLayout::Field]
+ * Get a field from the layout.
+ */
+static VALUE
+struct_layout_union_bang(VALUE self) 
+{
+    const ffi_type *alignment_types[] = { &ffi_type_sint8, &ffi_type_sint16, &ffi_type_sint32, &ffi_type_sint64,
+                                          &ffi_type_float, &ffi_type_double, &ffi_type_longdouble, NULL };
+    StructLayout* layout;
+    ffi_type *t = NULL;
+    int count, i;
+
+    Data_Get_Struct(self, StructLayout, layout);
+
+    for (i = 0; alignment_types[i] != NULL; ++i) {
+        if (alignment_types[i]->alignment == layout->align) {
+            t = (ffi_type *) alignment_types[i];
+            break;
+        }
+    }
+    if (t == NULL) {
+        rb_raise(rb_eRuntimeError, "cannot create libffi union representation for alignment %d", layout->align);
+        return Qnil;
+    }
+
+    count = (int) layout->size / (int) t->size;
+    xfree(layout->ffiTypes);
+    layout->ffiTypes = xcalloc(count + 1, sizeof(ffi_type *));
+    layout->base.ffiType->elements = layout->ffiTypes;
+
+    for (i = 0; i < count; ++i) {
+        layout->ffiTypes[i] = t;
+    }
+
+    return self;
+}
+
+static VALUE
+struct_layout_aref(VALUE self, VALUE field)
+{
+    StructLayout* layout;
+
+    Data_Get_Struct(self, StructLayout, layout);
+
+    return rb_hash_aref(layout->rbFieldMap, field);
+}
+
+/*
+ * call-seq: fields
+ * @return [Array<StructLayout::Field>]
+ * Get fields list.
+ */
+static VALUE
+struct_layout_fields(VALUE self)
+{
+    StructLayout* layout;
+
+    Data_Get_Struct(self, StructLayout, layout);
+
+    return rb_ary_dup(layout->rbFields);
+}
+
+/*
+ * call-seq: members
+ * @return [Array<Symbol>]
+ * Get list of field names.
+ */
+static VALUE
+struct_layout_members(VALUE self)
+{
+    StructLayout* layout;
+
+    Data_Get_Struct(self, StructLayout, layout);
+
+    return rb_ary_dup(layout->rbFieldNames);
+}
+
+/*
+ * call-seq: to_a
+ * @return [Array<StructLayout::Field>]
+ * Get an array of fields.
+ */
+static VALUE
+struct_layout_to_a(VALUE self)
+{
+    StructLayout* layout;
+
+    Data_Get_Struct(self, StructLayout, layout);
+
+    return rb_ary_dup(layout->rbFields);
+}
+
+static void
+struct_layout_mark(StructLayout *layout)
+{
+    rb_gc_mark(layout->rbFieldMap);
+    rb_gc_mark(layout->rbFieldNames);
+    rb_gc_mark(layout->rbFields);
+}
+
+static void
+struct_layout_free(StructLayout *layout)
+{
+    xfree(layout->ffiTypes);
+    xfree(layout->base.ffiType);
+    xfree(layout->fields);
+    st_free_table(layout->fieldSymbolTable);
+    xfree(layout);
+}
+
+
+void
+rbffi_StructLayout_Init(VALUE moduleFFI)
+{
+    VALUE ffi_Type = rbffi_TypeClass;
+
+    /*
+     * Document-class: FFI::StructLayout < FFI::Type
+     *
+     * This class aims at defining a struct layout.
+     */
+    rbffi_StructLayoutClass = rb_define_class_under(moduleFFI, "StructLayout", ffi_Type);
+    rb_global_variable(&rbffi_StructLayoutClass);
+    
+    /*
+     * Document-class: FFI::StructLayout::Field
+     * A field in a {StructLayout}.
+     */
+    rbffi_StructLayoutFieldClass = rb_define_class_under(rbffi_StructLayoutClass, "Field", rb_cObject);
+    rb_global_variable(&rbffi_StructLayoutFieldClass);
+
+    /*
+     * Document-class: FFI::StructLayout::Number
+     * A numeric {Field} in a {StructLayout}.
+     */
+    rbffi_StructLayoutNumberFieldClass = rb_define_class_under(rbffi_StructLayoutClass, "Number", rbffi_StructLayoutFieldClass);
+    rb_global_variable(&rbffi_StructLayoutNumberFieldClass);
+
+    /*
+     * Document-class: FFI::StructLayout::String
+     * A string {Field} in a {StructLayout}.
+     */
+    rbffi_StructLayoutStringFieldClass = rb_define_class_under(rbffi_StructLayoutClass, "String", rbffi_StructLayoutFieldClass);
+    rb_global_variable(&rbffi_StructLayoutStringFieldClass);
+
+    /*
+     * Document-class: FFI::StructLayout::Pointer
+     * A pointer {Field} in a {StructLayout}.
+     */
+    rbffi_StructLayoutPointerFieldClass = rb_define_class_under(rbffi_StructLayoutClass, "Pointer", rbffi_StructLayoutFieldClass);
+    rb_global_variable(&rbffi_StructLayoutPointerFieldClass);
+
+    /*
+     * Document-class: FFI::StructLayout::Function
+     * A function pointer {Field} in a {StructLayout}.
+     */
+    rbffi_StructLayoutFunctionFieldClass = rb_define_class_under(rbffi_StructLayoutClass, "Function", rbffi_StructLayoutFieldClass);
+    rb_global_variable(&rbffi_StructLayoutFunctionFieldClass);
+
+    /*
+     * Document-class: FFI::StructLayout::Array
+     * An array {Field} in a {StructLayout}.
+     */
+    rbffi_StructLayoutArrayFieldClass = rb_define_class_under(rbffi_StructLayoutClass, "Array", rbffi_StructLayoutFieldClass);
+    rb_global_variable(&rbffi_StructLayoutArrayFieldClass);
+
+    rb_define_alloc_func(rbffi_StructLayoutFieldClass, struct_field_allocate);
+    rb_define_method(rbffi_StructLayoutFieldClass, "initialize", struct_field_initialize, -1);
+    rb_define_method(rbffi_StructLayoutFieldClass, "offset", struct_field_offset, 0);
+    rb_define_method(rbffi_StructLayoutFieldClass, "size", struct_field_size, 0);
+    rb_define_method(rbffi_StructLayoutFieldClass, "alignment", struct_field_alignment, 0);
+    rb_define_method(rbffi_StructLayoutFieldClass, "name", struct_field_name, 0);
+    rb_define_method(rbffi_StructLayoutFieldClass, "type", struct_field_type, 0);
+    rb_define_method(rbffi_StructLayoutFieldClass, "put", struct_field_put, 2);
+    rb_define_method(rbffi_StructLayoutFieldClass, "get", struct_field_get, 1);
+
+    rb_define_method(rbffi_StructLayoutFunctionFieldClass, "put", function_field_put, 2);
+    rb_define_method(rbffi_StructLayoutFunctionFieldClass, "get", function_field_get, 1);
+
+    rb_define_method(rbffi_StructLayoutArrayFieldClass, "get", array_field_get, 1);
+    rb_define_method(rbffi_StructLayoutArrayFieldClass, "put", array_field_put, 2);
+
+    rb_define_alloc_func(rbffi_StructLayoutClass, struct_layout_allocate);
+    rb_define_method(rbffi_StructLayoutClass, "initialize", struct_layout_initialize, 3);
+    rb_define_method(rbffi_StructLayoutClass, "[]", struct_layout_aref, 1);
+    rb_define_method(rbffi_StructLayoutClass, "fields", struct_layout_fields, 0);
+    rb_define_method(rbffi_StructLayoutClass, "members", struct_layout_members, 0);
+    rb_define_method(rbffi_StructLayoutClass, "to_a", struct_layout_to_a, 0);
+    rb_define_method(rbffi_StructLayoutClass, "__union!", struct_layout_union_bang, 0);
+
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Thread.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Thread.c
new file mode 100755
index 0000000..32ae05f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Thread.c
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2010 Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MSC_VER
+#include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+# include "win32/stdint.h"
+#endif
+
+#if defined(__CYGWIN__) || !defined(_WIN32)
+# include <pthread.h>
+# include <errno.h>
+# include <signal.h>
+# include <unistd.h>
+#else
+# include <winsock2.h>
+# define _WINSOCKAPI_
+# include <windows.h>
+#endif
+#include <fcntl.h>
+#include "Thread.h"
+
+#ifdef _WIN32
+static volatile DWORD frame_thread_key = TLS_OUT_OF_INDEXES;
+#else
+static pthread_key_t thread_data_key;
+struct thread_data {
+    rbffi_frame_t* frame;
+};
+static inline struct thread_data* thread_data_get(void);
+
+#endif
+
+rbffi_frame_t*
+rbffi_frame_current(void)
+{
+#ifdef _WIN32
+    return (rbffi_frame_t *) TlsGetValue(frame_thread_key);
+#else
+    struct thread_data* td = (struct thread_data *) pthread_getspecific(thread_data_key);
+    return td != NULL ? td->frame : NULL;
+#endif
+}
+
+void 
+rbffi_frame_push(rbffi_frame_t* frame)
+{
+    memset(frame, 0, sizeof(*frame));
+    frame->has_gvl = true;
+    frame->exc = Qnil;
+    
+#ifdef _WIN32
+    frame->prev = TlsGetValue(frame_thread_key);
+    TlsSetValue(frame_thread_key, frame);
+#else
+    frame->td = thread_data_get();
+    frame->prev = frame->td->frame;
+    frame->td->frame = frame;
+#endif
+}
+
+void 
+rbffi_frame_pop(rbffi_frame_t* frame)
+{
+#ifdef _WIN32
+    TlsSetValue(frame_thread_key, frame->prev);
+#else
+    frame->td->frame = frame->prev;
+#endif
+}
+
+#if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
+
+#if !defined(_WIN32)
+
+struct BlockingThread {
+    pthread_t tid;
+    VALUE (*fn)(void *);
+    void *data;
+    void (*ubf)(void *);
+    void *data2;
+    VALUE retval;
+    int wrfd;
+    int rdfd;
+};
+
+static void*
+rbffi_blocking_thread(void* args)
+{
+    struct BlockingThread* thr = (struct BlockingThread *) args;
+    char c = 1;
+    VALUE retval;
+    
+    retval = (*thr->fn)(thr->data);
+    
+    pthread_testcancel();
+
+    thr->retval = retval;
+    
+    write(thr->wrfd, &c, sizeof(c));
+
+    return NULL;
+}
+
+static VALUE
+wait_for_thread(void *data)
+{
+    struct BlockingThread* thr = (struct BlockingThread *) data;
+    char c;
+    
+    if (read(thr->rdfd, &c, 1) < 1) {
+        rb_thread_wait_fd(thr->rdfd);
+        while (read(thr->rdfd, &c, 1) < 1 && rb_io_wait_readable(thr->rdfd) == Qtrue) {
+            ;
+        }
+    }
+
+    return Qnil;
+}
+
+static VALUE
+cleanup_blocking_thread(void *data, VALUE exc)
+{
+    struct BlockingThread* thr = (struct BlockingThread *) data;
+
+    if (thr->ubf != (void (*)(void *)) -1) {
+        (*thr->ubf)(thr->data2);
+    } else {
+        pthread_kill(thr->tid, SIGVTALRM);
+    }
+
+    return exc;
+}
+
+VALUE
+rbffi_thread_blocking_region(VALUE (*func)(void *), void *data1, void (*ubf)(void *), void *data2)
+{
+    struct BlockingThread* thr;
+    int fd[2];
+    VALUE exc;
+    
+    if (pipe(fd) < 0) {
+        rb_raise(rb_eSystemCallError, "pipe(2) failed");
+        return Qnil;
+    }
+    fcntl(fd[0], F_SETFL, fcntl(fd[0], F_GETFL) | O_NONBLOCK);
+
+    thr = ALLOC_N(struct BlockingThread, 1);
+    thr->rdfd = fd[0];
+    thr->wrfd = fd[1];
+    thr->fn = func;
+    thr->data = data1;
+    thr->ubf = ubf;
+    thr->data2 = data2;
+    thr->retval = Qnil;
+
+    if (pthread_create(&thr->tid, NULL, rbffi_blocking_thread, thr) != 0) {
+        close(fd[0]);
+        close(fd[1]);
+        xfree(thr);
+        rb_raise(rb_eSystemCallError, "pipe(2) failed");
+        return Qnil;
+    }
+
+    exc = rb_rescue2(wait_for_thread, (VALUE) thr, cleanup_blocking_thread, (VALUE) thr,
+        rb_eException);
+    
+    pthread_join(thr->tid, NULL);
+    close(fd[1]);
+    close(fd[0]);
+    xfree(thr);
+
+    if (exc != Qnil) {
+        rb_exc_raise(exc);
+    }
+
+    return thr->retval;
+}
+
+#else
+/* win32 implementation */
+
+struct BlockingThread {
+    HANDLE tid;
+    VALUE (*fn)(void *);
+    void *data;
+    void (*ubf)(void *);
+    void *data2;
+    VALUE retval;
+    int wrfd;
+    int rdfd;
+};
+
+static DWORD __stdcall
+rbffi_blocking_thread(LPVOID args)
+{
+    struct BlockingThread* thr = (struct BlockingThread *) args;
+    char c = 1;
+    VALUE retval;
+
+    retval = (*thr->fn)(thr->data);
+    thr->retval = retval;
+
+    write(thr->wrfd, &c, sizeof(c));
+
+    return 0;
+}
+
+static VALUE
+wait_for_thread(void *data)
+{
+    struct BlockingThread* thr = (struct BlockingThread *) data;
+    char c, res;
+    fd_set rfds;
+
+    FD_ZERO(&rfds);
+    FD_SET(thr->rdfd, &rfds);
+    rb_thread_select(thr->rdfd + 1, &rfds, NULL, NULL, NULL);
+    read(thr->rdfd, &c, 1);
+    return Qnil;
+}
+
+static VALUE
+cleanup_blocking_thread(void *data, VALUE exc)
+{
+    struct BlockingThread* thr = (struct BlockingThread *) data;
+
+    if (thr->ubf != (void (*)(void *)) -1) {
+        (*thr->ubf)(thr->data2);
+    } else {
+        TerminateThread(thr->tid, 0);
+    }
+
+    return exc;
+}
+
+VALUE
+rbffi_thread_blocking_region(VALUE (*func)(void *), void *data1, void (*ubf)(void *), void *data2)
+{
+    struct BlockingThread* thr;
+    int fd[2];
+    VALUE exc;
+    DWORD state;
+    DWORD res;
+
+    if (_pipe(fd, 1024, O_BINARY) == -1) {
+        rb_raise(rb_eSystemCallError, "_pipe() failed");
+        return Qnil;
+    }
+
+    thr = ALLOC_N(struct BlockingThread, 1);
+    thr->rdfd = fd[0];
+    thr->wrfd = fd[1];
+    thr->fn = func;
+    thr->data = data1;
+    thr->ubf = ubf;
+    thr->data2 = data2;
+    thr->retval = Qnil;
+
+    thr->tid = CreateThread(NULL, 0, rbffi_blocking_thread, thr, 0, NULL);
+    if (!thr->tid) {
+        close(fd[0]);
+        close(fd[1]);
+        xfree(thr);
+        rb_raise(rb_eSystemCallError, "CreateThread() failed");
+        return Qnil;
+    }
+
+    exc = rb_rescue2(wait_for_thread, (VALUE) thr, cleanup_blocking_thread, (VALUE) thr,
+        rb_eException);
+
+    /* The thread should be finished, already. */
+    WaitForSingleObject(thr->tid, INFINITE);
+    CloseHandle(thr->tid);
+    close(fd[1]);
+    close(fd[0]);
+    xfree(thr);
+
+    if (exc != Qnil) {
+        rb_exc_raise(exc);
+    }
+
+    return thr->retval;
+}
+
+#endif /* !_WIN32 */
+
+#endif /* HAVE_RB_THREAD_BLOCKING_REGION */
+
+#ifndef _WIN32
+static struct thread_data* thread_data_init(void);
+
+static inline struct thread_data*
+thread_data_get(void)
+{
+    struct thread_data* td = (struct thread_data *) pthread_getspecific(thread_data_key);
+    return td != NULL ? td : thread_data_init();
+}
+
+static struct thread_data*
+thread_data_init(void)
+{
+    struct thread_data* td = calloc(1, sizeof(struct thread_data));
+
+    pthread_setspecific(thread_data_key, td);
+
+    return td;
+}
+
+static void
+thread_data_free(void *ptr)
+{
+    free(ptr);
+}
+#endif
+
+void
+rbffi_Thread_Init(VALUE moduleFFI)
+{
+#ifdef _WIN32
+    frame_thread_key = TlsAlloc();
+#else
+    pthread_key_create(&thread_data_key, thread_data_free);    
+#endif
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Thread.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Thread.h
new file mode 100755
index 0000000..c51a5a9
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Thread.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2010 Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_THREAD_H
+#define	RBFFI_THREAD_H
+
+#ifndef _MSC_VER
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+# include "win32/stdint.h"
+#endif
+#include <ruby.h>
+#include "extconf.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+
+#ifdef _WIN32
+# include <windows.h>
+#else
+# include <pthread.h>
+#endif
+
+typedef struct {
+#ifdef _WIN32
+    DWORD id;
+#else
+    pthread_t id;
+#endif
+    bool valid;
+    bool has_gvl;
+    VALUE exc;
+} rbffi_thread_t;
+
+typedef struct rbffi_frame {
+#ifndef _WIN32
+    struct thread_data* td;
+#endif
+    struct rbffi_frame* prev;
+    bool has_gvl;
+    VALUE exc;
+} rbffi_frame_t;
+
+rbffi_frame_t* rbffi_frame_current(void);
+void rbffi_frame_push(rbffi_frame_t* frame);
+void rbffi_frame_pop(rbffi_frame_t* frame);
+
+#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
+# define rbffi_thread_blocking_region rb_thread_call_without_gvl
+
+#elif defined(HAVE_RB_THREAD_BLOCKING_REGION)
+# define rbffi_thread_blocking_region rb_thread_blocking_region
+
+#else
+
+VALUE rbffi_thread_blocking_region(VALUE (*func)(void *), void *data1, void (*ubf)(void *), void *data2);
+
+#endif
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_THREAD_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Type.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Type.c
new file mode 100755
index 0000000..034482f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Type.c
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2009, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MSC_VER
+#include <sys/param.h>
+#endif
+
+#include <sys/types.h>
+#include <ruby.h>
+#include <ffi.h>
+#include "rbffi.h"
+#include "compat.h"
+#include "Types.h"
+#include "Type.h"
+
+
+typedef struct BuiltinType_ {
+    Type type;
+    char* name;
+} BuiltinType;
+
+static void builtin_type_free(BuiltinType *);
+
+VALUE rbffi_TypeClass = Qnil;
+
+static VALUE classBuiltinType = Qnil;
+static VALUE moduleNativeType = Qnil;
+static VALUE typeMap = Qnil, sizeMap = Qnil;
+static ID id_find_type = 0, id_type_size = 0, id_size = 0;
+
+static VALUE
+type_allocate(VALUE klass)
+{
+    Type* type;
+    VALUE obj = Data_Make_Struct(klass, Type, NULL, -1, type);
+
+    type->nativeType = -1;
+    type->ffiType = &ffi_type_void;
+    
+    return obj;
+}
+
+/*
+ * Document-method: initialize
+ * call-seq: initialize(value)
+ * @param [Fixnum,Type] value
+ * @return [self]
+ */
+static VALUE
+type_initialize(VALUE self, VALUE value)
+{
+    Type* type;
+    Type* other;
+
+    Data_Get_Struct(self, Type, type);
+
+    if (FIXNUM_P(value)) {
+        type->nativeType = FIX2INT(value);
+    } else if (rb_obj_is_kind_of(value, rbffi_TypeClass)) {
+        Data_Get_Struct(value, Type, other);
+        type->nativeType = other->nativeType;
+        type->ffiType = other->ffiType;
+    } else {
+        rb_raise(rb_eArgError, "wrong type");
+    }
+    
+    return self;
+}
+
+/*
+ * call-seq: type.size
+ * @return [Fixnum]
+ * Return type's size, in bytes.
+ */
+static VALUE
+type_size(VALUE self)
+{
+    Type *type;
+
+    Data_Get_Struct(self, Type, type);
+
+    return INT2FIX(type->ffiType->size);
+}
+
+/*
+ * call-seq: type.alignment
+ * @return [Fixnum]
+ * Get Type alignment.
+ */
+static VALUE
+type_alignment(VALUE self)
+{
+    Type *type;
+
+    Data_Get_Struct(self, Type, type);
+
+    return INT2FIX(type->ffiType->alignment);
+}
+
+/*
+ * call-seq: type.inspect
+ * @return [String]
+ * Inspect {Type} object.
+ */
+static VALUE
+type_inspect(VALUE self)
+{
+    char buf[100];
+    Type *type;
+
+    Data_Get_Struct(self, Type, type);
+
+    snprintf(buf, sizeof(buf), "#<%s:%p size=%d alignment=%d>",
+            rb_obj_classname(self), type, (int) type->ffiType->size, (int) type->ffiType->alignment);
+
+    return rb_str_new2(buf);
+}
+
+static VALUE
+builtin_type_new(VALUE klass, int nativeType, ffi_type* ffiType, const char* name)
+{
+    BuiltinType* type;
+    VALUE obj = Qnil;
+
+    obj = Data_Make_Struct(klass, BuiltinType, NULL, builtin_type_free, type);
+    
+    type->name = strdup(name);
+    type->type.nativeType = nativeType;
+    type->type.ffiType = ffiType;
+
+    return obj;
+}
+
+static void
+builtin_type_free(BuiltinType *type)
+{
+    free(type->name);
+    xfree(type);
+}
+
+/*
+ * call-seq: type.inspect
+ * @return [String]
+ * Inspect {Type::Builtin} object.
+ */
+static VALUE
+builtin_type_inspect(VALUE self)
+{
+    char buf[100];
+    BuiltinType *type;
+
+    Data_Get_Struct(self, BuiltinType, type);
+    snprintf(buf, sizeof(buf), "#<%s:%s size=%d alignment=%d>",
+            rb_obj_classname(self), type->name, (int) type->type.ffiType->size, type->type.ffiType->alignment);
+
+    return rb_str_new2(buf);
+}
+
+int
+rbffi_type_size(VALUE type)
+{
+    int t = TYPE(type);
+    
+    if (t == T_FIXNUM || t == T_BIGNUM) {
+        return NUM2INT(type);
+    
+    } else if (t == T_SYMBOL) {
+        /*
+         * Try looking up directly in the type and size maps
+         */
+        VALUE nType;
+        if ((nType = rb_hash_lookup(typeMap, type)) != Qnil) {
+            if (rb_obj_is_kind_of(nType, rbffi_TypeClass)) {
+                Type* type;
+                Data_Get_Struct(nType, Type, type);
+                return (int) type->ffiType->size;
+            
+            } else if (rb_respond_to(nType, id_size)) {
+                return NUM2INT(rb_funcall2(nType, id_size, 0, NULL));
+            }
+        }
+
+        /* Not found - call up to the ruby version to resolve */
+        return NUM2INT(rb_funcall2(rbffi_FFIModule, id_type_size, 1, &type));
+    
+    } else {
+        return NUM2INT(rb_funcall2(type, id_size, 0, NULL));
+    }
+}
+
+VALUE
+rbffi_Type_Lookup(VALUE name)
+{
+    int t = TYPE(name);
+    if (t == T_SYMBOL || t == T_STRING) {
+        /*
+         * Try looking up directly in the type Map
+         */
+        VALUE nType;
+        if ((nType = rb_hash_lookup(typeMap, name)) != Qnil && rb_obj_is_kind_of(nType, rbffi_TypeClass)) {
+            return nType;
+        }
+    } else if (rb_obj_is_kind_of(name, rbffi_TypeClass)) {
+    
+        return name;
+    }
+
+    /* Nothing found - let caller handle raising exceptions */
+    return Qnil;
+}
+
+/**
+ * rbffi_Type_Find() is like rbffi_Type_Lookup, but an error is raised if the
+ * type is not found.
+ */
+VALUE
+rbffi_Type_Find(VALUE name)
+{
+    VALUE rbType = rbffi_Type_Lookup(name);
+
+    if (!RTEST(rbType)) {
+        VALUE s = rb_inspect(name);
+        rb_raise(rb_eTypeError, "invalid type, %s", RSTRING_PTR(s));
+        RB_GC_GUARD(s);
+    }
+
+    return rbType;
+}
+
+void
+rbffi_Type_Init(VALUE moduleFFI)
+{
+    /*
+     * Document-class: FFI::Type
+     * This class manages C types.
+     *
+     * It embbed {FFI::Type::Builtin} objects as constants (for names,
+     * see {FFI::NativeType}).
+     */
+    rbffi_TypeClass = rb_define_class_under(moduleFFI, "Type", rb_cObject);
+
+    /*
+     * Document-constant: FFI::TypeDefs
+     */
+    rb_define_const(moduleFFI, "TypeDefs", typeMap = rb_hash_new());
+    rb_define_const(moduleFFI, "SizeTypes", sizeMap = rb_hash_new());
+    rb_global_variable(&typeMap);
+    rb_global_variable(&sizeMap);
+    id_find_type = rb_intern("find_type");
+    id_type_size = rb_intern("type_size");
+    id_size = rb_intern("size");
+
+    /*
+     * Document-class: FFI::Type::Builtin
+     * Class for Built-in types.
+     */
+    classBuiltinType = rb_define_class_under(rbffi_TypeClass, "Builtin", rbffi_TypeClass);
+    /*
+     * Document-module: FFI::NativeType
+     * This module defines constants for native (C) types.
+     *
+     * ==Native type constants
+     * Native types are defined by constants :
+     * * INT8, SCHAR, CHAR
+     * * UINT8, UCHAR
+     * * INT16, SHORT, SSHORT
+     * * UINT16, USHORT
+     * * INT32,, INT, SINT
+     * * UINT32, UINT
+     * * INT64, LONG_LONG, SLONG_LONG
+     * * UINT64, ULONG_LONG
+     * * LONG, SLONG
+     * * ULONG
+     * * FLOAT32, FLOAT
+     * * FLOAT64, DOUBLE
+     * * POINTER
+     * * CALLBACK
+     * * FUNCTION
+     * * CHAR_ARRAY
+     * * BOOL
+     * * STRING (immutable string, nul terminated)
+     * * STRUCT (struct-b-value param or result)
+     * * ARRAY (array type definition)
+     * * MAPPED (custom native type)
+     * For function return type only :
+     * * VOID
+     * For function argument type only :
+     * * BUFFER_IN
+     * * BUFFER_OUT
+     * * VARARGS (function takes a variable number of arguments)
+     *
+     * All these constants are exported to {FFI} module prefixed with "TYPE_". 
+     * They are objets from {FFI::Type::Builtin} class.
+     */
+    moduleNativeType = rb_define_module_under(moduleFFI, "NativeType");
+
+    /*
+     * Document-global: FFI::Type
+     */
+    rb_global_variable(&rbffi_TypeClass);
+    rb_global_variable(&classBuiltinType);
+    rb_global_variable(&moduleNativeType);
+
+    rb_define_alloc_func(rbffi_TypeClass, type_allocate);
+    rb_define_method(rbffi_TypeClass, "initialize", type_initialize, 1);
+    rb_define_method(rbffi_TypeClass, "size", type_size, 0);
+    rb_define_method(rbffi_TypeClass, "alignment", type_alignment, 0);
+    rb_define_method(rbffi_TypeClass, "inspect", type_inspect, 0);
+
+    /* Make Type::Builtin non-allocatable */
+    rb_undef_method(CLASS_OF(classBuiltinType), "new");
+    rb_define_method(classBuiltinType, "inspect", builtin_type_inspect, 0);
+    
+    rb_global_variable(&rbffi_TypeClass);
+    rb_global_variable(&classBuiltinType);
+
+    /* Define all the builtin types */
+    #define T(x, ffiType) do { \
+        VALUE t = Qnil; \
+        rb_define_const(rbffi_TypeClass, #x, t = builtin_type_new(classBuiltinType, NATIVE_##x, ffiType, #x)); \
+        rb_define_const(moduleNativeType, #x, t); \
+        rb_define_const(moduleFFI, "TYPE_" #x, t); \
+    } while(0)
+
+    #define A(old_type, new_type) do { \
+        VALUE t = rb_const_get(rbffi_TypeClass, rb_intern(#old_type)); \
+        rb_const_set(rbffi_TypeClass, rb_intern(#new_type), t); \
+    } while(0)
+
+    /*
+     * Document-constant: FFI::Type::Builtin::VOID
+     */
+    T(VOID, &ffi_type_void);
+    T(INT8, &ffi_type_sint8);
+    A(INT8, SCHAR);
+    A(INT8, CHAR);
+    T(UINT8, &ffi_type_uint8);
+    A(UINT8, UCHAR);
+
+    T(INT16, &ffi_type_sint16);
+    A(INT16, SHORT);
+    A(INT16, SSHORT);
+    T(UINT16, &ffi_type_uint16);
+    A(UINT16, USHORT);
+    T(INT32, &ffi_type_sint32);
+    A(INT32, INT);
+    A(INT32, SINT);
+    T(UINT32, &ffi_type_uint32);
+    A(UINT32, UINT);
+    T(INT64, &ffi_type_sint64);
+    A(INT64, LONG_LONG);
+    A(INT64, SLONG_LONG);
+    T(UINT64, &ffi_type_uint64);
+    A(UINT64, ULONG_LONG);
+    T(LONG, &ffi_type_slong);
+    A(LONG, SLONG);
+    T(ULONG, &ffi_type_ulong);
+    T(FLOAT32, &ffi_type_float);
+    A(FLOAT32, FLOAT);
+    T(FLOAT64, &ffi_type_double);
+    A(FLOAT64, DOUBLE);
+    T(LONGDOUBLE, &ffi_type_longdouble);
+    T(POINTER, &ffi_type_pointer);
+    T(STRING, &ffi_type_pointer);
+    T(BUFFER_IN, &ffi_type_pointer);
+    T(BUFFER_OUT, &ffi_type_pointer);
+    T(BUFFER_INOUT, &ffi_type_pointer);
+    T(BOOL, &ffi_type_uchar);
+    T(VARARGS, &ffi_type_void);
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Type.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Type.h
new file mode 100755
index 0000000..d5522ee
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Type.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2009, Wayne Meissner
+ * Copyright (C) 2009 Luc Heinrich <luc at honk-honk.com>
+ *
+ * This file is part of ruby-ffi.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the Evan Phoenix nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef RBFFI_TYPE_H
+#define	RBFFI_TYPE_H
+
+#include <ruby.h>
+#include <ffi.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct Type_ Type;
+
+#include "Types.h"
+    
+struct Type_ {
+    NativeType nativeType;
+    ffi_type* ffiType;
+};
+
+extern VALUE rbffi_TypeClass;
+extern VALUE rbffi_Type_Lookup(VALUE type);
+extern VALUE rbffi_Type_Find(VALUE type);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_TYPE_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Types.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Types.c
new file mode 100755
index 0000000..bccf894
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Types.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2009, Wayne Meissner
+ * Copyright (c) 2009, Luc Heinrich
+ * Copyright (c) 2009, Aman Gupta.
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ruby.h>
+#include "Pointer.h"
+#include "rbffi.h"
+#include "Function.h"
+#include "StructByValue.h"
+#include "Types.h"
+#include "Struct.h"
+#include "MappedType.h"
+#include "MemoryPointer.h"
+#include "LongDouble.h"
+
+static ID id_from_native = 0;
+
+
+VALUE
+rbffi_NativeValue_ToRuby(Type* type, VALUE rbType, const void* ptr)
+{
+    switch (type->nativeType) {
+        case NATIVE_VOID:
+            return Qnil;
+        case NATIVE_INT8:
+          return INT2NUM((signed char) *(ffi_sarg *) ptr);
+        case NATIVE_INT16:
+          return INT2NUM((signed short) *(ffi_sarg *) ptr);
+        case NATIVE_INT32:
+          return INT2NUM((signed int) *(ffi_sarg *) ptr);
+        case NATIVE_LONG:
+            return LONG2NUM((signed long) *(ffi_sarg *) ptr);
+        case NATIVE_INT64:
+            return LL2NUM(*(signed long long *) ptr);
+
+        case NATIVE_UINT8:
+          return UINT2NUM((unsigned char) *(ffi_arg *) ptr);
+        case NATIVE_UINT16:
+          return UINT2NUM((unsigned short) *(ffi_arg *) ptr);
+        case NATIVE_UINT32:
+          return UINT2NUM((unsigned int) *(ffi_arg *) ptr);
+        case NATIVE_ULONG:
+            return ULONG2NUM((unsigned long) *(ffi_arg *) ptr);
+        case NATIVE_UINT64:
+            return ULL2NUM(*(unsigned long long *) ptr);
+
+        case NATIVE_FLOAT32:
+            return rb_float_new(*(float *) ptr);
+        case NATIVE_FLOAT64:
+            return rb_float_new(*(double *) ptr);
+
+        case NATIVE_LONGDOUBLE:
+	  return rbffi_longdouble_new(*(long double *) ptr);
+
+        case NATIVE_STRING:
+            return (*(void **) ptr != NULL) ? rb_tainted_str_new2(*(char **) ptr) : Qnil;
+        case NATIVE_POINTER:
+            return rbffi_Pointer_NewInstance(*(void **) ptr);
+        case NATIVE_BOOL:
+            return ((unsigned char) *(ffi_arg *) ptr) ? Qtrue : Qfalse;
+        
+        case NATIVE_FUNCTION:
+        case NATIVE_CALLBACK: {
+            return *(void **) ptr != NULL 
+                    ? rbffi_Function_NewInstance(rbType, rbffi_Pointer_NewInstance(*(void **) ptr))
+                    : Qnil;
+        }
+
+        case NATIVE_STRUCT: {
+            StructByValue* sbv = (StructByValue *)type;
+            AbstractMemory* mem;
+            VALUE rbMemory = rbffi_MemoryPointer_NewInstance(1, sbv->base.ffiType->size, false);
+
+            Data_Get_Struct(rbMemory, AbstractMemory, mem);
+            memcpy(mem->address, ptr, sbv->base.ffiType->size);
+            RB_GC_GUARD(rbMemory);
+            RB_GC_GUARD(rbType);
+
+            return rb_class_new_instance(1, &rbMemory, sbv->rbStructClass);
+        }
+
+        case NATIVE_MAPPED: {
+            /*
+             * For mapped types, first convert to the real native type, then upcall to
+             * ruby to convert to the expected return type
+             */
+            MappedType* m = (MappedType *) type;
+            VALUE values[2], rbReturnValue;
+
+            values[0] = rbffi_NativeValue_ToRuby(m->type, m->rbType, ptr);
+            values[1] = Qnil;
+            
+
+            rbReturnValue = rb_funcall2(m->rbConverter, id_from_native, 2, values);
+            RB_GC_GUARD(values[0]);
+            RB_GC_GUARD(rbType);
+            
+            return rbReturnValue;
+        }
+    
+        default:
+            rb_raise(rb_eRuntimeError, "Unknown type: %d", type->nativeType);
+            return Qnil;
+    }
+}
+
+void
+rbffi_Types_Init(VALUE moduleFFI)
+{
+    id_from_native = rb_intern("from_native");
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Types.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Types.h
new file mode 100755
index 0000000..0d4806f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Types.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2008, 2009, Wayne Meissner
+ * Copyright (c) 2009, Luc Heinrich <luc at honk-honk.com>
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_TYPES_H
+#define	RBFFI_TYPES_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    NATIVE_VOID,
+    NATIVE_INT8,
+    NATIVE_UINT8,
+    NATIVE_INT16,
+    NATIVE_UINT16,
+    NATIVE_INT32,
+    NATIVE_UINT32,
+    NATIVE_INT64,
+    NATIVE_UINT64,
+    NATIVE_LONG,
+    NATIVE_ULONG,
+    NATIVE_FLOAT32,
+    NATIVE_FLOAT64,
+    NATIVE_LONGDOUBLE,
+    NATIVE_POINTER,
+    NATIVE_CALLBACK,
+    NATIVE_FUNCTION,
+    NATIVE_BUFFER_IN,
+    NATIVE_BUFFER_OUT,
+    NATIVE_BUFFER_INOUT,
+    NATIVE_CHAR_ARRAY,
+    NATIVE_BOOL,
+    
+    /** An immutable string.  Nul terminated, but only copies in to the native function */
+    NATIVE_STRING,
+    
+    /** The function takes a variable number of arguments */
+    NATIVE_VARARGS,
+    
+    /** Struct-by-value param or result */
+    NATIVE_STRUCT,
+
+    /** An array type definition */
+    NATIVE_ARRAY,
+
+    /** Custom native type */
+    NATIVE_MAPPED,
+} NativeType;
+
+#include <ffi.h>
+#include "Type.h"
+
+VALUE rbffi_NativeValue_ToRuby(Type* type, VALUE rbType, const void* ptr);
+void rbffi_Types_Init(VALUE moduleFFI);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_TYPES_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/Variadic.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Variadic.c
new file mode 100755
index 0000000..0027be2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/Variadic.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2008-2010 Wayne Meissner
+ * Copyright (C) 2009 Andrea Fazzi <andrea.fazzi at alcacoop.it>
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MSC_VER
+#include <sys/param.h>
+#endif
+#include <sys/types.h>
+
+#include <stdio.h>
+#ifndef _MSC_VER
+# include <stdint.h>
+# include <stdbool.h>
+#else
+# include "win32/stdbool.h"
+# include "win32/stdint.h"
+#endif
+#include <ruby.h>
+
+#include <ffi.h>
+#include "rbffi.h"
+#include "compat.h"
+
+#include "AbstractMemory.h"
+#include "Pointer.h"
+#include "Types.h"
+#include "Type.h"
+#include "LastError.h"
+#include "MethodHandle.h"
+#include "Call.h"
+#include "Thread.h"
+
+typedef struct VariadicInvoker_ {
+    VALUE rbAddress;
+    VALUE rbReturnType;
+    VALUE rbEnums;
+
+    Type* returnType;
+    ffi_abi abi;
+    void* function;
+    int paramCount;
+} VariadicInvoker;
+
+
+static VALUE variadic_allocate(VALUE klass);
+static VALUE variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes,
+        VALUE rbReturnType, VALUE options);
+static void variadic_mark(VariadicInvoker *);
+
+static VALUE classVariadicInvoker = Qnil;
+
+
+static VALUE
+variadic_allocate(VALUE klass)
+{
+    VariadicInvoker *invoker;
+    VALUE obj = Data_Make_Struct(klass, VariadicInvoker, variadic_mark, -1, invoker);
+
+    invoker->rbAddress = Qnil;
+    invoker->rbEnums = Qnil;
+    invoker->rbReturnType = Qnil;
+
+    return obj;
+}
+
+static void
+variadic_mark(VariadicInvoker *invoker)
+{
+    rb_gc_mark(invoker->rbEnums);
+    rb_gc_mark(invoker->rbAddress);
+    rb_gc_mark(invoker->rbReturnType);
+}
+
+static VALUE
+variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes, VALUE rbReturnType, VALUE options)
+{
+    VariadicInvoker* invoker = NULL;
+    VALUE retval = Qnil;
+    VALUE convention = Qnil;
+    VALUE fixed = Qnil;
+#if defined(X86_WIN32)
+    VALUE rbConventionStr;
+#endif
+    int i;
+
+    Check_Type(options, T_HASH);
+    convention = rb_hash_aref(options, ID2SYM(rb_intern("convention")));
+
+    Data_Get_Struct(self, VariadicInvoker, invoker);
+    invoker->rbEnums = rb_hash_aref(options, ID2SYM(rb_intern("enums")));
+    invoker->rbAddress = rbFunction;
+    invoker->function = rbffi_AbstractMemory_Cast(rbFunction, rbffi_PointerClass)->address;
+
+#if defined(X86_WIN32)
+    rbConventionStr = rb_funcall2(convention, rb_intern("to_s"), 0, NULL);
+    invoker->abi = (RTEST(convention) && strcmp(StringValueCStr(rbConventionStr), "stdcall") == 0)
+            ? FFI_STDCALL : FFI_DEFAULT_ABI;
+#else
+    invoker->abi = FFI_DEFAULT_ABI;
+#endif
+
+    invoker->rbReturnType = rbffi_Type_Lookup(rbReturnType);
+    if (!RTEST(invoker->rbReturnType)) {
+        VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL);
+        rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName));
+    }
+
+    Data_Get_Struct(rbReturnType, Type, invoker->returnType);
+
+    invoker->paramCount = -1;
+
+    fixed = rb_ary_new2(RARRAY_LEN(rbParameterTypes) - 1);
+    for (i = 0; i < RARRAY_LEN(rbParameterTypes); ++i) {
+        VALUE entry = rb_ary_entry(rbParameterTypes, i);
+        VALUE rbType = rbffi_Type_Lookup(entry);
+        Type* type;
+
+        if (!RTEST(rbType)) {
+            VALUE typeName = rb_funcall2(entry, rb_intern("inspect"), 0, NULL);
+            rb_raise(rb_eTypeError, "Invalid parameter type (%s)", RSTRING_PTR(typeName));
+        }
+        Data_Get_Struct(rbType, Type, type);
+        if (type->nativeType != NATIVE_VARARGS) {
+            rb_ary_push(fixed, entry);
+        }
+    }
+    /*
+     * @fixed and @type_map are used by the parameter mangling ruby code
+     */
+    rb_iv_set(self, "@fixed", fixed);
+    rb_iv_set(self, "@type_map", rb_hash_aref(options, ID2SYM(rb_intern("type_map"))));
+
+    return retval;
+}
+
+static VALUE
+variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
+{
+    VariadicInvoker* invoker;
+    FFIStorage* params;
+    void* retval;
+    ffi_cif cif;
+    void** ffiValues;
+    ffi_type** ffiParamTypes;
+    ffi_type* ffiReturnType;
+    Type** paramTypes;
+    VALUE* argv;
+    int paramCount = 0, fixedCount = 0, i;
+    ffi_status ffiStatus;
+    rbffi_frame_t frame = { 0 };
+
+    Check_Type(parameterTypes, T_ARRAY);
+    Check_Type(parameterValues, T_ARRAY);
+
+    Data_Get_Struct(self, VariadicInvoker, invoker);
+    paramCount = (int) RARRAY_LEN(parameterTypes);
+    paramTypes = ALLOCA_N(Type *, paramCount);
+    ffiParamTypes = ALLOCA_N(ffi_type *, paramCount);
+    params = ALLOCA_N(FFIStorage, paramCount);
+    ffiValues = ALLOCA_N(void*, paramCount);
+    argv = ALLOCA_N(VALUE, paramCount);
+    retval = alloca(MAX(invoker->returnType->ffiType->size, FFI_SIZEOF_ARG));
+
+    for (i = 0; i < paramCount; ++i) {
+        VALUE rbType = rb_ary_entry(parameterTypes, i);
+        
+        if (!rb_obj_is_kind_of(rbType, rbffi_TypeClass)) {
+            rb_raise(rb_eTypeError, "wrong type.  Expected (FFI::Type)");
+        }
+        Data_Get_Struct(rbType, Type, paramTypes[i]);
+
+        switch (paramTypes[i]->nativeType) {
+            case NATIVE_INT8:
+            case NATIVE_INT16:
+            case NATIVE_INT32:
+                rbType = rb_const_get(rbffi_TypeClass, rb_intern("INT32"));
+                Data_Get_Struct(rbType, Type, paramTypes[i]);
+                break;
+            case NATIVE_UINT8:
+            case NATIVE_UINT16:
+            case NATIVE_UINT32:
+                rbType = rb_const_get(rbffi_TypeClass, rb_intern("UINT32"));
+                Data_Get_Struct(rbType, Type, paramTypes[i]);
+                break;
+            
+            case NATIVE_FLOAT32:
+                rbType = rb_const_get(rbffi_TypeClass, rb_intern("DOUBLE"));
+                Data_Get_Struct(rbType, Type, paramTypes[i]);
+                break;
+
+            default:
+                break;
+        }
+        
+        
+        ffiParamTypes[i] = paramTypes[i]->ffiType;
+        if (ffiParamTypes[i] == NULL) {
+            rb_raise(rb_eArgError, "Invalid parameter type #%x", paramTypes[i]->nativeType);
+        }
+        argv[i] = rb_ary_entry(parameterValues, i);
+    }
+
+    ffiReturnType = invoker->returnType->ffiType;
+    if (ffiReturnType == NULL) {
+        rb_raise(rb_eArgError, "Invalid return type");
+    }
+
+    /*Get the number of fixed args from @fixed array*/
+    fixedCount = RARRAY_LEN(rb_iv_get(self, "@fixed"));
+
+#ifdef HAVE_FFI_PREP_CIF_VAR
+    ffiStatus = ffi_prep_cif_var(&cif, invoker->abi, fixedCount, paramCount, ffiReturnType, ffiParamTypes);
+#else
+    ffiStatus = ffi_prep_cif(&cif, invoker->abi, paramCount, ffiReturnType, ffiParamTypes);
+#endif
+    switch (ffiStatus) {
+        case FFI_BAD_ABI:
+            rb_raise(rb_eArgError, "Invalid ABI specified");
+        case FFI_BAD_TYPEDEF:
+            rb_raise(rb_eArgError, "Invalid argument type specified");
+        case FFI_OK:
+            break;
+        default:
+            rb_raise(rb_eArgError, "Unknown FFI error");
+    }
+
+    rbffi_SetupCallParams(paramCount, argv, -1, paramTypes, params,
+        ffiValues, NULL, 0, invoker->rbEnums);
+    
+    rbffi_frame_push(&frame);
+    ffi_call(&cif, FFI_FN(invoker->function), retval, ffiValues);
+    rbffi_frame_pop(&frame);
+    
+    rbffi_save_errno();
+    
+    if (RTEST(frame.exc) && frame.exc != Qnil) {
+        rb_exc_raise(frame.exc);
+    }
+
+    return rbffi_NativeValue_ToRuby(invoker->returnType, invoker->rbReturnType, retval);
+}
+
+
+void
+rbffi_Variadic_Init(VALUE moduleFFI)
+{
+    classVariadicInvoker = rb_define_class_under(moduleFFI, "VariadicInvoker", rb_cObject);
+    rb_global_variable(&classVariadicInvoker);
+
+    rb_define_alloc_func(classVariadicInvoker, variadic_allocate);
+
+    rb_define_method(classVariadicInvoker, "initialize", variadic_initialize, 4);
+    rb_define_method(classVariadicInvoker, "invoke", variadic_invoke, 2);
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/compat.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/compat.h
new file mode 100755
index 0000000..4a1c646
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/compat.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008, 2009, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_COMPAT_H
+#define RBFFI_COMPAT_H
+
+#include <ruby.h>
+
+#ifndef RARRAY_LEN
+#  define RARRAY_LEN(ary) RARRAY(ary)->len
+#endif
+
+#ifndef RARRAY_PTR
+#  define RARRAY_PTR(ary) RARRAY(ary)->ptr
+#endif
+
+#ifndef RSTRING_LEN
+#  define RSTRING_LEN(s) RSTRING(s)->len
+#endif
+
+#ifndef RSTRING_PTR
+#  define RSTRING_PTR(s) RSTRING(s)->ptr
+#endif
+
+#ifndef NUM2ULL
+#  define NUM2ULL(x) rb_num2ull((VALUE)x)
+#endif
+
+#ifndef roundup
+#  define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
+#endif
+
+#ifdef __GNUC__
+#  define likely(x) __builtin_expect((x), 1)
+#  define unlikely(x) __builtin_expect((x), 0)
+#else
+#  define likely(x) (x)
+#  define unlikely(x) (x)
+#endif
+
+#ifndef MAX
+#  define MAX(a, b) ((a) < (b) ? (b) : (a))
+#endif
+#ifndef MIN
+#  define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef RB_GC_GUARD
+#  define RB_GC_GUARD(x) (x)
+#endif
+
+#ifndef RB_GC_GUARD_PTR
+#  define RB_GC_GUARD_PTR(x) (x)
+#endif
+
+#endif /* RBFFI_COMPAT_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/extconf.rb b/app/server/vendor/ffi-1.9.10/ext/ffi_c/extconf.rb
new file mode 100755
index 0000000..180634f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/extconf.rb
@@ -0,0 +1,65 @@
+#!/usr/bin/env ruby
+
+if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
+  require 'mkmf'
+  require 'rbconfig'
+  dir_config("ffi_c")
+
+  # recent versions of ruby add restrictive ansi and warning flags on a whim - kill them all
+  $warnflags = ''
+  $CFLAGS.gsub!(/[\s+]-ansi/, '')
+  $CFLAGS.gsub!(/[\s+]-std=[^\s]+/, '')
+  # solaris 10 needs -c99 for <stdbool.h>
+  $CFLAGS << " -std=c99" if RbConfig::CONFIG['host_os'] =~ /solaris(!?2\.11)/
+  
+  if ENV['RUBY_CC_VERSION'].nil? && (pkg_config("libffi") ||
+     have_header("ffi.h") ||
+     find_header("ffi.h", "/usr/local/include", "/usr/include/ffi"))
+
+    # We need at least ffi_call and ffi_prep_closure
+    libffi_ok = have_library("ffi", "ffi_call", [ "ffi.h" ]) ||
+                have_library("libffi", "ffi_call", [ "ffi.h" ])
+    libffi_ok &&= have_func("ffi_prep_closure")
+
+    # Check if the raw api is available.
+    $defs << "-DHAVE_RAW_API" if have_func("ffi_raw_call") && have_func("ffi_prep_raw_closure")
+  end
+  
+  have_func('rb_thread_blocking_region')
+  have_func('rb_thread_call_with_gvl')
+  have_func('rb_thread_call_without_gvl')
+  have_func('ffi_prep_cif_var')
+  
+  $defs << "-DHAVE_EXTCONF_H" if $defs.empty? # needed so create_header works
+  $defs << "-DUSE_INTERNAL_LIBFFI" unless libffi_ok
+  $defs << "-DRUBY_1_9" if RUBY_VERSION >= "1.9.0"
+  $defs << "-DFFI_BUILDING" if RbConfig::CONFIG['host_os'] =~ /mswin/ # for compatibility with newer libffi
+
+  create_header
+  
+  $LOCAL_LIBS << " ./libffi/.libs/libffi_convenience.lib" if !libffi_ok && RbConfig::CONFIG['host_os'] =~ /mswin/
+
+  create_makefile("ffi_c")
+  unless libffi_ok
+    File.open("Makefile", "a") do |mf|
+      mf.puts "LIBFFI_HOST=--host=#{RbConfig::CONFIG['host_alias']}" if RbConfig::CONFIG.has_key?("host_alias")
+      if RbConfig::CONFIG['host_os'].downcase =~ /darwin/
+        mf.puts "include ${srcdir}/libffi.darwin.mk"
+      elsif RbConfig::CONFIG['host_os'].downcase =~ /bsd/
+        mf.puts '.include "${srcdir}/libffi.bsd.mk"'
+      elsif RbConfig::CONFIG['host_os'].downcase =~ /mswin64/
+        mf.puts '!include $(srcdir)/libffi.vc64.mk'
+      elsif RbConfig::CONFIG['host_os'].downcase =~ /mswin32/
+        mf.puts '!include $(srcdir)/libffi.vc.mk'
+      else
+        mf.puts "include ${srcdir}/libffi.mk"
+      end
+    end
+  end
+  
+else
+  File.open("Makefile", "w") do |mf|
+    mf.puts "# Dummy makefile for non-mri rubies"
+    mf.puts "all install::\n"
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/ffi.c
new file mode 100755
index 0000000..ea9a058
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/ffi.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2008, 2009, Wayne Meissner
+ * Copyright (C) 2009 Luc Heinrich <luc at honk-honk.com>
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <ruby.h>
+
+#include <ffi.h>
+
+#include "rbffi.h"
+#include "AbstractMemory.h"
+#include "Pointer.h"
+#include "MemoryPointer.h"
+#include "Struct.h"
+#include "StructByValue.h"
+#include "StructByReference.h"
+#include "DynamicLibrary.h"
+#include "Platform.h"
+#include "Types.h"
+#include "LastError.h"
+#include "Function.h"
+#include "ClosurePool.h"
+#include "MethodHandle.h"
+#include "Call.h"
+#include "ArrayType.h"
+#include "MappedType.h"
+
+void Init_ffi_c(void);
+
+VALUE rbffi_FFIModule = Qnil;
+
+static VALUE moduleFFI = Qnil;
+
+void
+Init_ffi_c(void) 
+{
+    /* 
+     * Document-module: FFI
+     *
+     * This module embbed type constants from {FFI::NativeType}.
+     */
+    rbffi_FFIModule = moduleFFI = rb_define_module("FFI");
+    rb_global_variable(&rbffi_FFIModule);
+
+    rbffi_Thread_Init(rbffi_FFIModule);
+    
+    /* FFI::Type needs to be initialized before most other classes */
+    rbffi_Type_Init(moduleFFI);
+
+    rbffi_DataConverter_Init(moduleFFI);
+
+    rbffi_ArrayType_Init(moduleFFI);
+    rbffi_LastError_Init(moduleFFI);
+    rbffi_Call_Init(moduleFFI);
+    rbffi_ClosurePool_Init(moduleFFI);
+    rbffi_MethodHandle_Init(moduleFFI);
+    rbffi_Platform_Init(moduleFFI);
+    rbffi_AbstractMemory_Init(moduleFFI);
+    rbffi_Pointer_Init(moduleFFI);
+    rbffi_Function_Init(moduleFFI);
+    rbffi_MemoryPointer_Init(moduleFFI);
+    rbffi_Buffer_Init(moduleFFI);
+    rbffi_StructByValue_Init(moduleFFI);
+    rbffi_StructByReference_Init(moduleFFI);
+    rbffi_Struct_Init(moduleFFI);
+    rbffi_DynamicLibrary_Init(moduleFFI);
+    rbffi_Variadic_Init(moduleFFI);
+    rbffi_Types_Init(moduleFFI);
+    rbffi_MappedType_Init(moduleFFI);
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.bsd.mk b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.bsd.mk
new file mode 100755
index 0000000..16ec6b5
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.bsd.mk
@@ -0,0 +1,34 @@
+# -*- makefile -*-
+#
+# Makefile for BSD systems
+#
+
+INCFLAGS += -I${LIBFFI_BUILD_DIR}/include
+LOCAL_LIBS += ${LIBFFI} -lpthread
+
+LIBFFI_CFLAGS = ${FFI_MMAP_EXEC} -pthread
+LIBFFI_BUILD_DIR = ${.CURDIR}/libffi-${arch}
+
+.if ${srcdir} == "."
+  LIBFFI_SRC_DIR := ${.CURDIR}/libffi
+.else
+  LIBFFI_SRC_DIR := ${srcdir}/libffi
+.endif
+
+
+LIBFFI = ${LIBFFI_BUILD_DIR}/.libs/libffi_convenience.a
+LIBFFI_CONFIGURE = ${LIBFFI_SRC_DIR}/configure --disable-static \
+	--with-pic=yes --disable-dependency-tracking
+
+$(OBJS):	${LIBFFI}
+
+$(LIBFFI):		
+	@mkdir -p ${LIBFFI_BUILD_DIR}
+	@if [ ! -f ${LIBFFI_BUILD_DIR}/Makefile ]; then \
+	    echo "Configuring libffi"; \
+	    cd ${LIBFFI_BUILD_DIR} && \
+		/usr/bin/env CC="${CC}" LD="${LD}" CFLAGS="${LIBFFI_CFLAGS}" GREP_OPTIONS="" \
+		/bin/sh ${LIBFFI_CONFIGURE} ${LIBFFI_HOST} > /dev/null; \
+	fi
+	@cd ${LIBFFI_BUILD_DIR} && ${MAKE}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.darwin.mk b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.darwin.mk
new file mode 100755
index 0000000..f68badd
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.darwin.mk
@@ -0,0 +1,95 @@
+# -*- makefile -*-
+
+include ${srcdir}/libffi.gnu.mk
+
+CCACHE := $(shell type -p ccache)
+BUILD_DIR := $(shell pwd)
+
+INCFLAGS += -I"$(BUILD_DIR)"
+
+# Work out which arches we need to compile the lib for
+ARCHES := 
+ARCHFLAGS ?= $(filter -arch %, $(CFLAGS))
+
+ifneq ($(findstring -arch ppc,$(ARCHFLAGS)),)
+  ARCHES += ppc
+endif
+
+ifneq ($(findstring -arch i386,$(ARCHFLAGS)),)
+  ARCHES += i386
+endif
+
+ifneq ($(findstring -arch x86_64,$(ARCHFLAGS)),)
+  ARCHES += x86_64
+endif
+
+ifeq ($(strip $(ARCHES)),)
+LIBFFI_BUILD_DIR = $(BUILD_DIR)/libffi-$(arch)
+# Just build the one (default) architecture
+$(LIBFFI):		
+	@mkdir -p "$(LIBFFI_BUILD_DIR)" "$(@D)"
+	@if [ ! -f "$(LIBFFI_BUILD_DIR)"/Makefile ]; then \
+	    echo "Configuring libffi"; \
+	    cd "$(LIBFFI_BUILD_DIR)" && \
+		/usr/bin/env CC="$(CC)" LD="$(LD)" CFLAGS="$(LIBFFI_CFLAGS)" GREP_OPTIONS="" \
+		/bin/sh $(LIBFFI_CONFIGURE) $(LIBFFI_HOST) > /dev/null; \
+	fi
+	cd "$(LIBFFI_BUILD_DIR)" && $(MAKE)
+
+else
+LIBTARGETS = $(foreach arch,$(ARCHES),"$(BUILD_DIR)"/libffi-$(arch)/.libs/libffi_convenience.a)
+
+# Build a fat binary and assemble
+build_ffi = \
+	mkdir -p "$(BUILD_DIR)"/libffi-$(1); \
+	(if [ ! -f "$(BUILD_DIR)"/libffi-$(1)/Makefile ]; then \
+	    echo "Configuring libffi for $(1)"; \
+	    cd "$(BUILD_DIR)"/libffi-$(1) && \
+	      env CC="$(CCACHE) $(CC)" CFLAGS="-arch $(1) $(LIBFFI_CFLAGS)" LDFLAGS="-arch $(1)" \
+		$(LIBFFI_CONFIGURE) --host=$(1)-apple-darwin > /dev/null; \
+	fi); \
+	env MACOSX_DEPLOYMENT_TARGET=10.4 $(MAKE) -C "$(BUILD_DIR)"/libffi-$(1)
+
+target_ffi = "$(BUILD_DIR)"/libffi-$(1)/.libs/libffi_convenience.a:; $(call build_ffi,$(1))
+
+# Work out which arches we need to compile the lib for
+ifneq ($(findstring ppc,$(ARCHES)),)
+  $(call target_ffi,ppc)
+endif
+
+ifneq ($(findstring i386,$(ARCHES)),)
+  $(call target_ffi,i386)
+endif
+
+ifneq ($(findstring x86_64,$(ARCHES)),)
+  $(call target_ffi,x86_64)
+endif
+
+
+$(LIBFFI):	$(LIBTARGETS)
+	# Assemble into a FAT (x86_64, i386, ppc) library
+	@mkdir -p "$(@D)"
+	/usr/bin/libtool -static -o $@ \
+	    $(foreach arch, $(ARCHES),"$(BUILD_DIR)"/libffi-$(arch)/.libs/libffi_convenience.a)
+	@mkdir -p "$(LIBFFI_BUILD_DIR)"/include
+	$(RM) "$(LIBFFI_BUILD_DIR)"/include/ffi.h
+	@( \
+		printf "#if defined(__i386__)\n"; \
+		printf "#include \"libffi-i386/include/ffi.h\"\n"; \
+		printf "#elif defined(__x86_64__)\n"; \
+		printf "#include \"libffi-x86_64/include/ffi.h\"\n";\
+		printf "#elif defined(__ppc__)\n"; \
+		printf "#include \"libffi-ppc/include/ffi.h\"\n";\
+		printf "#endif\n";\
+	) > "$(LIBFFI_BUILD_DIR)"/include/ffi.h
+	@( \
+		printf "#if defined(__i386__)\n"; \
+		printf "#include \"libffi-i386/include/ffitarget.h\"\n"; \
+		printf "#elif defined(__x86_64__)\n"; \
+		printf "#include \"libffi-x86_64/include/ffitarget.h\"\n";\
+		printf "#elif defined(__ppc__)\n"; \
+		printf "#include \"libffi-ppc/include/ffitarget.h\"\n";\
+		printf "#endif\n";\
+	) > "$(LIBFFI_BUILD_DIR)"/include/ffitarget.h
+
+endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.gnu.mk b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.gnu.mk
new file mode 100755
index 0000000..2af7a75
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.gnu.mk
@@ -0,0 +1,31 @@
+# -*- makefile -*-
+#
+#  Common definitions for all systems that use GNU make
+#
+
+
+# Tack the extra deps onto the autogenerated variables
+INCFLAGS += -I"$(LIBFFI_BUILD_DIR)"/include
+LOCAL_LIBS += $(LIBFFI)
+BUILD_DIR = $(shell pwd)
+LIBFFI_CFLAGS = $(FFI_MMAP_EXEC)
+LIBFFI_BUILD_DIR = $(BUILD_DIR)/libffi-$(arch)
+
+ifeq ($(srcdir),.)
+  LIBFFI_SRC_DIR := $(shell pwd)/libffi
+else ifeq ($(srcdir),..)
+  LIBFFI_SRC_DIR := $(shell pwd)/../libffi
+else
+  LIBFFI_SRC_DIR := $(realpath $(srcdir)/libffi)
+endif
+
+LIBFFI = "$(LIBFFI_BUILD_DIR)"/.libs/libffi_convenience.a
+LIBFFI_CONFIGURE = "$(LIBFFI_SRC_DIR)"/configure --disable-static \
+	--with-pic=yes --disable-dependency-tracking
+
+$(OBJS):	$(LIBFFI)
+
+#
+# libffi.mk or libffi.darwin.mk contains rules for building the actual library
+#
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.mk b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.mk
new file mode 100755
index 0000000..85c15c5
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.mk
@@ -0,0 +1,13 @@
+# -*- makefile -*-
+
+include ${srcdir}/libffi.gnu.mk
+
+$(LIBFFI):		
+	@mkdir -p "$(LIBFFI_BUILD_DIR)" "$@(D)"
+	@if [ ! -f "$(LIBFFI_BUILD_DIR)"/Makefile ]; then \
+	    echo "Configuring libffi"; \
+	    cd "$(LIBFFI_BUILD_DIR)" && \
+		/usr/bin/env CFLAGS="$(LIBFFI_CFLAGS)" GREP_OPTIONS="" \
+		/bin/sh $(LIBFFI_CONFIGURE) $(LIBFFI_HOST) > /dev/null; \
+	fi
+	$(MAKE) -C "$(LIBFFI_BUILD_DIR)"
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.vc.mk b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.vc.mk
new file mode 100755
index 0000000..c62e55f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.vc.mk
@@ -0,0 +1,26 @@
+# -*- makefile -*-
+#
+# Makefile for msvc
+#
+
+# Tack the extra deps onto the autogenerated variables
+INCFLAGS = $(INCFLAGS) -I$(LIBFFI_BUILD_DIR)/include -I$(LIBFFI_BUILD_DIR)/src/x86
+LOCAL_LIBS = $(LOCAL_LIBS) $(LIBFFI)
+BUILD_DIR = $(MAKEDIR)
+LIBFFI_BUILD_DIR = $(BUILD_DIR)/libffi
+
+!IF "$(srcdir)" == "."
+LIBFFI_SRC_DIR = $(MAKEDIR)/libffi
+!ELSE
+LIBFFI_SRC_DIR = $(srcdir)/libffi
+!ENDIF
+
+LIBFFI = $(LIBFFI_BUILD_DIR)/.libs/libffi_convenience.lib
+
+$(OBJS):	$(LIBFFI)
+
+$(LIBFFI):		
+	@$(MAKEDIRS) $(LIBFFI_BUILD_DIR)
+	@cd $(LIBFFI_BUILD_DIR) && $(MAKE) -f Makefile.vc
+	
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.vc64.mk b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.vc64.mk
new file mode 100755
index 0000000..9582948
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi.vc64.mk
@@ -0,0 +1,26 @@
+# -*- makefile -*-
+#
+# Makefile for msvc
+#
+
+# Tack the extra deps onto the autogenerated variables
+INCFLAGS = $(INCFLAGS) -I$(LIBFFI_BUILD_DIR)/include -I$(LIBFFI_BUILD_DIR)/src/x86
+LOCAL_LIBS = $(LOCAL_LIBS) $(LIBFFI)
+BUILD_DIR = $(MAKEDIR)
+LIBFFI_BUILD_DIR = $(BUILD_DIR)/libffi
+
+!IF "$(srcdir)" == "."
+LIBFFI_SRC_DIR = $(MAKEDIR)/libffi
+!ELSE
+LIBFFI_SRC_DIR = $(srcdir)/libffi
+!ENDIF
+
+LIBFFI = $(LIBFFI_BUILD_DIR)/.libs/libffi_convenience.lib
+
+$(OBJS):	$(LIBFFI)
+
+$(LIBFFI):		
+	@$(MAKEDIRS) $(LIBFFI_BUILD_DIR)
+	@cd $(LIBFFI_BUILD_DIR) && $(MAKE) -f Makefile.vc64
+	
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/.document b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/.document
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/ChangeLog b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/ChangeLog
new file mode 100755
index 0000000..d5d1024
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/ChangeLog
@@ -0,0 +1,4600 @@
+2011-08-22  Jasper Lievisse Adriaanse <jasper at openbsd.org>
+
+	* configure.ac: Add OpenBSD/hppa and OpenBSD/powerpc support.
+	* configure: Rebuilt.
+
+2011-07-11  Andrew Haley  <aph at redhat.com>
+
+        * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Clear icache.
+
+2011-06-29  Rainer Orth  <ro at CeBiTec.Uni-Bielefeld.DE>
+
+	* testsuite/libffi.call/cls_double_va.c: Move PR number to comment.
+	* testsuite/libffi.call/cls_longdouble_va.c: Likewise.
+
+2011-06-29  Rainer Orth  <ro at CeBiTec.Uni-Bielefeld.DE>
+
+	PR libffi/46660
+	* testsuite/libffi.call/cls_double_va.c: xfail dg-output on
+	mips-sgi-irix6*.
+	* testsuite/libffi.call/cls_longdouble_va.c: Likewise.
+
+2011-06-14  Rainer Orth  <ro at CeBiTec.Uni-Bielefeld.DE>
+
+	* testsuite/libffi.call/huge_struct.c (test_large_fn): Use PRIu8,
+	PRId8 instead of %hhu, %hhd.
+	* testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRId8,
+	PRIu8): Define.
+	[__sgi__] (PRId8, PRIu8): Define.
+
+2011-04-29  Rainer Orth  <ro at CeBiTec.Uni-Bielefeld.DE>
+
+	* src/alpha/osf.S (UA_SI, FDE_ENCODING, FDE_ENCODE, FDE_ARANGE):
+	Define.
+	Use them to handle ELF vs. ECOFF differences.
+	[__osf__] (_GLOBAL__F_ffi_call_osf): Define.
+
+2011-03-30  Timothy Wall  <twall at users.sf.net>
+
+	* src/powerpc/darwin.S: Fix unknown FDE encoding.
+	* src/powerpc/darwin_closure.S: ditto.
+
+2011-02-25  Anthony Green  <green at moxielogic.com>
+
+	* src/powerpc/ffi.c (ffi_prep_closure_loc): Allow for more
+	32-bit ABIs.
+
+2011-02-15  Anthony Green  <green at moxielogic.com>
+
+	* m4/ax_cc_maxopt.m4: Don't -malign-double or use -ffast-math.
+	* configure: Rebuilt.
+
+2011-02-13  Ralf Wildenhues  <Ralf.Wildenhues at gmx.de>
+
+	* configure: Regenerate.
+
+2011-02-13  Anthony Green  <green at moxielogic.com>
+
+	* include/ffi_common.h (UNLIKELY, LIKELY): Define.
+	* src/x86/ffi64.c (UNLIKELY, LIKELY): Remove definition.
+	* src/prep_cif.c (UNLIKELY, LIKELY): Remove definition.
+
+	* src/prep_cif.c (initialize_aggregate): Convert assertion into
+	FFI_BAD_TYPEDEF return.  Initialize arg size and alignment to 0.
+
+	* src/pa/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
+	just return FFI_BAD_ABI when things are wrong.
+	* src/arm/ffi.c (ffi_prep_closure_loc): Ditto.
+	* src/powerpc/ffi.c (ffi_prep_closure_loc): Ditto.
+	* src/mips/ffi.c (ffi_prep_closure_loc): Ditto.
+	* src/ia64/ffi.c (ffi_prep_closure_loc): Ditto.
+	* src/avr32/ffi.c (ffi_prep_closure_loc): Ditto.
+
+2011-02-11  Anthony Green  <green at moxielogic.com>
+
+	* src/sparc/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
+	just return FFI_BAD_ABI when things are wrong.
+
+2011-02-09  Stuart Shelton  <srcshelton at gmail.com>
+
+	http://bugs.gentoo.org/show_bug.cgi?id=286911
+	* src/mips/ffitarget.h: Clean up error messages.
+	* src/java_raw_api.c (ffi_java_translate_args): Cast raw arg to
+	ffi_raw*.
+	* include/ffi.h.in: Add pragma for SGI compiler.
+
+2011-02-09  Anthony Green  <green at moxielogic.com>
+
+	* configure.ac: Add powerpc64-*-darwin* support.
+
+2011-02-09  Anthony Green <green at moxielogic.com>
+
+	* README: Mention Interix.
+
+2011-02-09  Jonathan Callen  <abcd at gentoo.org>
+
+	* configure.ac: Add Interix to win32/cygwin/mingw case.
+	* configure: Ditto.
+	* src/closures.c: Treat Interix like Cygwin, instead of as a
+	generic win32.
+
+2011-02-09  Anthony Green <green at moxielogic.com>
+
+	* testsuite/libffi.call/err_bad_typedef.c: Remove xfail.
+	* testsuite/libffi.call/err_bad_abi.c: Remove xfail.
+	* src/x86/ffi64.c (UNLIKELY, LIKELY): Define.
+	(ffi_prep_closure_loc): Check for bad ABI.
+	* src/prep_cif.c (UNLIKELY, LIKELY): Define.
+	(initialize_aggregate): Check for bad types.
+
+2011-02-09  Landon Fuller <landonf at plausible.coop>
+
+	* Makefile.am (EXTRA_DIST): Add build-ios.sh, src/arm/gentramp.sh,
+	src/arm/trampoline.S.
+	(nodist_libffi_la_SOURCES): Add src/arc/trampoline.S.
+	* configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Define.
+	* src/arm/ffi.c (ffi_trampoline_table)
+	(ffi_closure_trampoline_table_page, ffi_trampoline_table_entry)
+	(FFI_TRAMPOLINE_CODELOC_CONFIG, FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET)
+	(FFI_TRAMPOLINE_COUNT, ffi_trampoline_lock, ffi_trampoline_tables)
+	(ffi_trampoline_table_alloc, ffi_closure_alloc, ffi_closure_free):
+	Define for FFI_EXEC_TRAMPOLINE_TABLE case (iOS).
+	(ffi_prep_closure_loc): Handl FFI_EXEC_TRAMPOLINE_TABLE case
+	separately.
+	* src/arm/sysv.S: Handle Apple iOS host.
+	* src/closures.c: Handle FFI_EXEC_TRAMPOLINE_TABLE case.
+	* build-ios.sh: New file.
+	* fficonfig.h.in, configure, Makefile.in: Rebuilt.
+	* README: Mention ARM iOS.
+
+2011-02-08  Oren Held  <orenhe at il.ibm.com>
+
+	* src/dlmalloc.c (_STRUCT_MALLINFO): Define in order to avoid
+	redefinition of mallinfo on HP-UX.
+
+2011-02-08  Ginn Chen  <ginn.chen at oracle.com>
+
+	* src/sparc/ffi.c (ffi_call): Make compatible with Solaris Studio
+	aggregate return ABI.  Flush cache.
+	(ffi_prep_closure_loc): Flush cache.
+
+2011-02-11  Anthony Green  <green at moxielogic.com>
+
+	From Tom Honermann <tom.honermann at oracle.com>:
+	* src/powerpc/aix.S (ffi_call_AIX): Support for xlc toolchain on
+	AIX.  Declare .ffi_prep_args.  Insert nops after branch
+	instructions so that the AIX linker can insert TOC reload
+	instructions.
+	* src/powerpc/aix_closure.S: Declare .ffi_closure_helper_DARWIN.
+
+2011-02-08  Ed  <ed at kdtc.net>
+
+	* src/powerpc/asm.h: Fix grammar nit in comment.
+
+2011-02-08  Uli Link  <ul.mcamafia at linkitup.de>
+
+	* include/ffi.h.in (FFI_64_BIT_MAX): Define and use.
+
+2011-02-09  Rainer Orth  <ro at CeBiTec.Uni-Bielefeld.DE>
+
+	PR libffi/46661
+	* testsuite/libffi.call/cls_pointer.c (main): Cast void * to
+	uintptr_t first.
+	* testsuite/libffi.call/cls_pointer_stack.c (main): Likewise.
+
+2011-02-08  Rafael Avila de Espindola  <respindola at mozilla.com>
+
+	* configure.ac: Fix x86 test for pc related relocs.
+	* configure: Rebuilt.
+
+2011-02-07  Joel Sherrill <joel.sherrill at oarcorp.com>
+
+	* libffi/src/m68k/ffi.c: Add RTEMS support for cache flushing.
+	Handle case when CPU variant does not have long double support.
+	* libffi/src/m68k/sysv.S: Add support for mc68000, Coldfire,
+	and cores with soft floating point.
+
+2011-02-07  Joel Sherrill <joel.sherrill at oarcorp.com>
+
+	* configure.ac: Add mips*-*-rtems* support.
+	* configure: Regenerate.
+	* src/mips/ffitarget.h: Ensure needed constants are available
+	for targets which do not have sgidefs.h.
+
+2011-01-26  Dave Korn  <dave.korn.cygwin at gmail.com>
+
+	PR target/40125
+	* configure.ac (AM_LTLDFLAGS): Add -bindir option for windows DLLs.
+	* configure: Regenerate.
+
+2010-12-18  Iain Sandoe  <iains at gcc.gnu.org>
+
+	PR libffi/29152
+	PR libffi/42378
+	* src/powerpc/darwin_closure.S: Provide Darwin64 implementation,
+	update comments.
+	* src/powerpc/ffitarget.h (POWERPC_DARWIN64): New,
+	(FFI_TRAMPOLINE_SIZE): Update for Darwin64.
+	* src/powerpc/darwin.S: Provide Darwin64 implementation,
+	update comments.
+	* src/powerpc/ffi_darwin.c: Likewise.
+
+2010-12-06  Rainer Orth  <ro at CeBiTec.Uni-Bielefeld.DE>
+
+	* configure.ac (libffi_cv_as_ascii_pseudo_op): Use double
+	backslashes.
+	(libffi_cv_as_string_pseudo_op): Likewise.
+	* configure: Regenerate.
+
+2010-12-03  Chung-Lin Tang  <cltang at codesourcery.com>
+
+	* src/arm/sysv.S (ffi_closure_SYSV): Add UNWIND to .pad directive.
+	(ffi_closure_VFP): Same.
+	(ffi_call_VFP): Move down to before ffi_closure_VFP. Add '.fpu vfp'
+	directive.
+
+2010-12-01  Rainer Orth  <ro at CeBiTec.Uni-Bielefeld.DE>
+
+	* testsuite/libffi.call/ffitest.h [__sgi] (PRId64, PRIu64): Define.
+	(PRIuPTR): Define.
+
+2010-11-29  Richard Henderson  <rth at redhat.com>
+	    Rainer Orth  <ro at CeBiTec.Uni-Bielefeld.DE>
+
+	* src/x86/sysv.S (FDE_ENCODING, FDE_ENCODE): Define.
+	(.eh_frame): Use FDE_ENCODING.
+	(.LASFDE1, .LASFDE2, LASFDE3): Simplify with FDE_ENCODE.
+
+2010-11-22  Jacek Caban <jacek at codeweavers.com>
+
+	* configure.ac: Check for symbol underscores on mingw-w64.
+	* configure: Rebuilt.
+	* src/x86/win64.S: Correctly access extern symbols in respect to
+	underscores.
+
+2010-11-15  Rainer Orth  <ro at CeBiTec.Uni-Bielefeld.DE>
+
+	* testsuite/lib/libffi-dg.exp: Rename ...
+	* testsuite/lib/libffi.exp: ... to this.
+	* libffi/testsuite/libffi.call/call.exp: Don't load libffi-dg.exp.
+	* libffi/testsuite/libffi.special/special.exp: Likewise.
+
+2010-10-28  Chung-Lin Tang  <cltang at codesourcery.com>
+
+	* src/arm/ffi.c (ffi_prep_args): Add VFP register argument handling
+	code, new parameter, and return value. Update comments.
+	(ffi_prep_cif_machdep): Add case for VFP struct return values. Add
+	call to layout_vfp_args().
+	(ffi_call_SYSV): Update declaration.
+	(ffi_call_VFP): New declaration.
+	(ffi_call): Add VFP struct return conditions. Call ffi_call_VFP()
+	when ABI is FFI_VFP.
+	(ffi_closure_VFP): New declaration.
+	(ffi_closure_SYSV_inner): Add new vfp_args parameter, update call to
+	ffi_prep_incoming_args_SYSV().
+	(ffi_prep_incoming_args_SYSV): Update parameters. Add VFP argument
+	case handling.
+	(ffi_prep_closure_loc): Pass ffi_closure_VFP to trampoline
+	construction under VFP hard-float.
+	(rec_vfp_type_p): New function.
+	(vfp_type_p): Same.
+	(place_vfp_arg): Same.
+	(layout_vfp_args): Same.
+	* src/arm/ffitarget.h (ffi_abi): Add FFI_VFP. Define FFI_DEFAULT_ABI
+	based on __ARM_PCS_VFP.
+	(FFI_EXTRA_CIF_FIELDS): Define for adding VFP hard-float specific
+	fields.
+	(FFI_TYPE_STRUCT_VFP_FLOAT): Define internally used type code.
+	(FFI_TYPE_STRUCT_VFP_DOUBLE): Same.
+	* src/arm/sysv.S (ffi_call_SYSV): Change call of ffi_prep_args() to
+	direct call. Move function pointer load upwards.
+	(ffi_call_VFP): New function.
+	(ffi_closure_VFP): Same.
+
+	* testsuite/lib/libffi-dg.exp (check-flags): New function.
+	(dg-skip-if): New function.
+	* testsuite/libffi.call/cls_double_va.c: Skip if target is arm*-*-*
+	and compiler options include -mfloat-abi=hard.
+	* testsuite/libffi.call/cls_longdouble_va.c: Same.
+
+2010-10-01  Jakub Jelinek  <jakub at redhat.com>
+
+	PR libffi/45677
+	* src/x86/ffi64.c (ffi_prep_cif_machdep): Ensure cif->bytes is
+	a multiple of 8.
+	* testsuite/libffi.call/many2.c: New test.
+
+2010-08-20  Mark Wielaard  <mjw at redhat.com>
+
+	* src/closures.c (open_temp_exec_file_mnt): Check if getmntent_r
+	returns NULL.
+
+2010-08-09  Andreas Tobler  <andreast at fgznet.ch>
+
+	* configure.ac: Add target powerpc64-*-freebsd*.
+	* configure: Regenerate.
+	* testsuite/libffi.call/cls_align_longdouble_split.c: Pass
+	-mlong-double-128 only to linux targets.
+	* testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise.
+	* testsuite/libffi.call/cls_longdouble.c: Likewise.
+	* testsuite/libffi.call/huge_struct.c: Likewise.
+
+2010-08-05  Dan Witte  <dwitte at mozilla.com>
+
+        * Makefile.am: Pass FFI_DEBUG define to msvcc.sh for linking to the
+        debug CRT when --enable-debug is given.
+        * configure.ac: Define it.
+        * msvcc.sh: Translate -g and -DFFI_DEBUG appropriately.
+
+2010-08-04  Dan Witte  <dwitte at mozilla.com>
+
+	* src/x86/ffitarget.h: Add X86_ANY define for all x86/x86_64
+	platforms.
+	* src/x86/ffi.c: Remove redundant ifdef checks.
+	* src/prep_cif.c: Push stack space computation into src/x86/ffi.c
+	for X86_ANY so return value space doesn't get added twice.
+
+2010-08-03  Neil Rashbrooke <neil at parkwaycc.co.uk>
+
+	* msvcc.sh: Don't pass -safeseh to ml64 because behavior is buggy.
+
+2010-07-22  Dan Witte  <dwitte at mozilla.com>
+
+	* src/*/ffitarget.h: Make FFI_LAST_ABI one past the last valid ABI.
+	* src/prep_cif.c: Fix ABI assertion.
+        * src/cris/ffi.c: Ditto.
+
+2010-07-10  Evan Phoenix  <evan at fallingsnow.net>
+
+	* src/closures.c (selinux_enabled_check): Fix strncmp usage bug.
+
+2010-07-07  Dan Horák <dan at danny.cz>
+
+	* include/ffi.h.in: Protect #define with #ifndef.
+	* src/powerpc/ffitarget.h: Ditto.
+	* src/s390/ffitarget.h: Ditto.
+	* src/sparc/ffitarget.h: Ditto.
+
+2010-07-07   Neil Roberts <neil at linux.intel.com>
+
+	* src/x86/sysv.S (ffi_call_SYSV): Align the stack pointer to
+	16-bytes.
+
+2010-07-02  Jakub Jelinek  <jakub at redhat.com>
+
+	* Makefile.am (AM_MAKEFLAGS): Pass also mandir to submakes.
+	* Makefile.in: Regenerated.
+
+2010-05-19  Rainer Orth  <ro at CeBiTec.Uni-Bielefeld.DE>
+
+	* configure.ac (libffi_cv_as_x86_pcrel): Check for illegal in as
+	output, too.
+	(libffi_cv_as_ascii_pseudo_op): Check for .ascii.
+	(libffi_cv_as_string_pseudo_op): Check for .string.
+	* configure: Regenerate.
+	* fficonfig.h.in: Regenerate.
+	* src/x86/sysv.S (.eh_frame): Use .ascii, .string or error.
+
+2010-05-11  Dan Witte  <dwitte at mozilla.com>
+
+	* doc/libffi.tex: Document previous change.
+
+2010-05-11  Makoto Kato <m_kato at ga2.so-net.ne.jp>
+
+	* src/x86/ffi.c (ffi_call): Don't copy structs passed by value.
+
+2010-05-05  Michael Kohler <michaelkohler at live.com>
+
+	* src/dlmalloc.c (dlfree): Fix spelling.
+	* src/ia64/ffi.c (ffi_prep_cif_machdep): Ditto.
+	* configure.ac: Ditto.
+	* configure: Rebuilt.
+
+2010-04-13  Dan Witte  <dwitte at mozilla.com>
+
+	* msvcc.sh: Build with -W3 instead of -Wall.
+	* src/powerpc/ffi_darwin.c: Remove build warnings.
+	* src/x86/ffi.c: Ditto.
+	* src/x86/ffitarget.h: Ditto.
+
+2010-04-12  Dan Witte  <dwitte at mozilla.com>
+	    Walter Meinl <wuno at lsvw.de>
+
+	* configure.ac: Add OS/2 support.
+	* configure: Rebuilt.
+	* src/closures.c: Ditto.
+	* src/dlmalloc.c: Ditto.
+	* src/x86/win32.S: Ditto.
+
+2010-04-07  Jakub Jelinek  <jakub at redhat.com>
+
+	* testsuite/libffi.call/err_bad_abi.c: Remove unused args variable.
+
+2010-04-02  Ralf Wildenhues  <Ralf.Wildenhues at gmx.de>
+
+	* Makefile.in: Regenerate.
+	* aclocal.m4: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* man/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+
+2010-03-30  Dan Witte  <dwitte at mozilla.com>
+
+	* msvcc.sh: Disable build warnings.
+	* README (tested): Clarify windows build procedure.
+
+2010-03-15  Rainer Orth  <ro at CeBiTec.Uni-Bielefeld.DE>
+
+	* configure.ac (libffi_cv_as_x86_64_unwind_section_type): New test.
+	* configure: Regenerate.
+	* fficonfig.h.in: Regenerate.
+	* libffi/src/x86/unix64.S (.eh_frame)
+	[HAVE_AS_X86_64_UNWIND_SECTION_TYPE]: Use @unwind section type.
+
+2010-03-14  Matthias Klose  <doko at ubuntu.com>
+
+	* src/x86/ffi64.c: Fix typo in comment.
+	* src/x86/ffi.c: Use /* ... */ comment style.
+
+2010-02-24  Rainer Orth  <ro at CeBiTec.Uni-Bielefeld.DE>
+
+	* doc/libffi.texi (The Closure API): Fix typo.
+	* doc/libffi.info: Remove.
+
+2010-02-15  Matthias Klose  <doko at ubuntu.com>
+
+	* src/arm/sysv.S (__ARM_ARCH__): Define for processor
+	__ARM_ARCH_7EM__.
+
+2010-01-15  Anthony Green  <green at redhat.com>
+
+	* README: Add notes on building with Microsoft Visual C++.
+
+2010-01-15  Daniel Witte  <dwitte at mozilla.com>
+
+	* msvcc.sh: New file.
+
+	* src/x86/win32.S: Port assembly routines to MSVC and #ifdef.
+	* src/x86/ffi.c: Tweak function declaration and remove excess
+	parens.
+	* include/ffi.h.in: Add __declspec(align(8)) to typedef struct
+	ffi_closure.
+
+	* src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new
+	function ffi_call_win32 on X86_WIN32.
+	* src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32.
+	(ffi_call_STDCALL): Remove.
+
+	* src/prep_cif.c (ffi_prep_cif): Move stack space allocation code
+	to ffi_prep_cif_machdep for x86.
+	* src/x86/ffi.c (ffi_prep_cif_machdep): To here.
+
+2010-01-15  Oliver Kiddle  <okiddle at yahoo.co.uk>
+
+	* src/x86/ffitarget.h (ffi_abi): Check for __i386 and __amd64 for
+	Sun Studio compiler compatibility.
+
+2010-01-12  Conrad Irwin <conrad.irwin at gmail.com>
+
+	* doc/libffi.texi: Add closure example.
+
+2010-01-07  Rainer Orth  <ro at CeBiTec.Uni-Bielefeld.DE>
+
+	PR libffi/40701
+	* testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRIdLL,
+	PRIuLL, PRId64, PRIu64, PRIuPTR): Define.
+	* testsuite/libffi.call/cls_align_sint64.c: Add -Wno-format on
+	alpha*-dec-osf*.
+	* testsuite/libffi.call/cls_align_uint64.c: Likewise.
+	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
+	* testsuite/libffi.call/return_ll1.c: Likewise.
+	* testsuite/libffi.call/stret_medium2.c: Likewise.
+	* testsuite/libffi.special/ffitestcxx.h (allocate_mmap): Cast
+	MAP_FAILED to char *.
+
+2010-01-06  Rainer Orth  <ro at CeBiTec.Uni-Bielefeld.DE>
+
+	* src/mips/n32.S: Use .abicalls and .eh_frame with __GNUC__.
+
+2009-12-31  Anthony Green  <green at redhat.com>
+
+	* README: Update for libffi 3.0.9.
+
+2009-12-27  Matthias Klose  <doko at ubuntu.com>
+
+	* configure.ac (HAVE_LONG_DOUBLE): Define for mips when
+	appropriate.
+	* configure: Rebuilt.
+
+2009-12-26  Anthony Green  <green at redhat.com>
+
+	* testsuite/libffi.call/cls_longdouble_va.c: Mark as xfail for
+	avr32*-*-*.
+	* testsuite/libffi.call/cls_double_va.c: Ditto.
+
+2009-12-26  Andreas Tobler  <a.tobler at schweiz.org>
+
+	* testsuite/libffi.call/ffitest.h: Conditionally include stdint.h
+	and inttypes.h.
+	* testsuite/libffi.special/unwindtest.cc: Ditto.
+
+2009-12-26  Andreas Tobler  <a.tobler at schweiz.org>
+
+	* configure.ac: Add amd64-*-openbsd*.
+	* configure: Rebuilt.
+	* testsuite/lib/libffi-dg.exp (libffi_target_compile): Link
+	openbsd programs with -lpthread.
+
+2009-12-26  Anthony Green  <green at redhat.com>
+
+	* testsuite/libffi.call/cls_double_va.c,
+	testsuite/libffi.call/cls_longdouble.c,
+	testsuite/libffi.call/cls_longdouble_va.c,
+	testsuite/libffi.call/cls_pointer.c,
+	testsuite/libffi.call/cls_pointer_stack.c: Remove xfail for
+	mips*-*-* and arm*-*-*.
+	* testsuite/libffi.call/cls_align_longdouble_split.c,
+	testsuite/libffi.call/cls_align_longdouble_split2.c,
+	testsuite/libffi.call/stret_medium2.c,
+	testsuite/libffi.call/stret_medium.c,
+	testsuite/libffi.call/stret_large.c,
+	testsuite/libffi.call/stret_large2.c: Remove xfail for arm*-*-*.
+
+2009-12-31  Kay Tietz  <ktietz70 at googlemail.com>
+
+	* testsuite/libffi.call/ffitest.h,
+	testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRuLL): Fix
+	definitions.
+
+2009-12-31  Carlo Bramini  <carlo.bramix at libero.it>
+
+	* configure.ac (AM_LTLDFLAGS): Define for windows hosts.
+	* Makefile.am (libffi_la_LDFLAGS): Add AM_LTLDFLAGS.
+	* configure: Rebuilt.
+	* Makefile.in: Rebuilt.
+
+2009-12-31  Anthony Green  <green at redhat.com>
+	    Blake Chaffin.
+
+	* testsuite/libffi.call/huge_struct.c: New test case from Blake
+	Chaffin @ Apple.
+
+2009-12-28  David Edelsohn  <edelsohn at gnu.org>
+
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Copy abi and nargs to
+	local variables.
+	(aix_adjust_aggregate_sizes): New function.
+	(ffi_prep_cif_machdep): Call it.
+
+2009-12-26  Andreas Tobler  <a.tobler at schweiz.org>
+
+	* configure.ac: Define FFI_MMAP_EXEC_WRIT for the given targets.
+	* configure: Regenerate.
+	* fficonfig.h.in: Likewise.
+	* src/closures.c: Remove the FFI_MMAP_EXEC_WRIT definition for
+	Solaris/x86.
+
+2009-12-26  Andreas Schwab  <schwab at linux-m68k.org>
+
+	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Advance intarg_count
+	when a float arguments is passed in memory.
+	(ffi_closure_helper_SYSV): Mark general registers as used up when
+	a 64bit or soft-float long double argument is passed in memory.
+
+2009-12-25  Matthias Klose  <doko at ubuntu.com>
+
+	* man/ffi_call.3: Fix #include in examples.
+	* doc/libffi.texi: Add dircategory.
+
+2009-12-25  Frank Everdij <f.p.x.everdij at tudelft.nl>
+
+	* include/ffi.h.in: Placed '__GNUC__' ifdef around
+	'__attribute__((aligned(8)))' in ffi_closure, fixes compile for
+	IRIX MIPSPro c99.
+	* include/ffi_common.h: Added '__sgi' define to non
+	'__attribute__((__mode__()))' integer typedefs.
+	* src/mips/ffi.c (ffi_call, ffi_closure_mips_inner_O32,
+	ffi_closure_mips_inner_N32): Added 'defined(_MIPSEB)' to BE check.
+	(ffi_closure_mips_inner_O32, ffi_closure_mips_inner_N32): Added
+	FFI_LONGDOUBLE support and alignment(N32 only).
+	* src/mips/ffitarget.h: Corrected '#include <sgidefs.h>' for IRIX and
+	fixed non '__attribute__((__mode__()))' integer typedefs.
+	* src/mips/n32.S: Put '#ifdef linux' around '.abicalls' and '.eh_frame'
+	since they are Linux/GNU Assembler specific.
+
+2009-12-25  Bradley Smith  <brad at brad-smith.co.uk>
+
+	* configure.ac, Makefile.am, src/avr32/ffi.c,
+	src/avr32/ffitarget.h,
+	src/avr32/sysv.S: Add AVR32 port.
+	* configure, Makefile.in: Rebuilt.
+
+2009-12-21  Andreas Tobler  <a.tobler at schweiz.org>
+
+	* configure.ac: Make i?86 build on FreeBSD and OpenBSD.
+	* configure: Regenerate.
+
+2009-12-15  John David Anglin  <dave.anglin at nrc-cnrc.gc.ca>
+
+	* testsuite/libffi.call/ffitest.h: Define PRIuPTR on PA HP-UX.
+
+2009-12-13  John David Anglin  <dave.anglin at nrc-cnrc.gc.ca>
+
+	* src/pa/ffi.c (ffi_closure_inner_pa32): Handle FFI_TYPE_LONGDOUBLE
+	type on HP-UX.
+
+2009-12-11  Eric Botcazou  <ebotcazou at adacore.com>
+
+	* src/sparc/ffi.c (ffi_closure_sparc_inner_v9): Properly align 'long
+	double' arguments.
+
+2009-12-11  Eric Botcazou  <ebotcazou at adacore.com>
+
+	* testsuite/libffi.call/ffitest.h: Define PRIuPTR on Solaris < 10.
+
+2009-12-10  Rainer Orth  <ro at CeBiTec.Uni-Bielefeld.DE>
+
+	PR libffi/40700
+	* src/closures.c [X86_64 && __sun__ && __svr4__]
+	(FFI_MMAP_EXEC_WRIT): Define.
+
+2009-12-08  David Daney  <ddaney at caviumnetworks.com>
+
+	* testsuite/libffi.call/stret_medium.c: Remove xfail for mips*-*-*
+	* testsuite/libffi.call/cls_align_longdouble_split2.c: Same.
+	* testsuite/libffi.call/stret_large.c: Same.
+	* testsuite/libffi.call/cls_align_longdouble_split.c: Same.
+	* testsuite/libffi.call/stret_large2.c: Same.
+	* testsuite/libffi.call/stret_medium2.c: Same.
+
+2009-12-07  David Edelsohn  <edelsohn at gnu.org>
+
+	* src/powerpc/aix_closure.S (libffi_closure_ASM): Fix tablejump
+	typo.
+
+2009-12-05  David Edelsohn  <edelsohn at gnu.org>
+
+	* src/powerpc/aix.S: Update AIX32 code to be consistent with AIX64
+	code.
+	* src/powerpc/aix_closure.S: Same.
+
+2009-12-05  Ralf Wildenhues  <Ralf.Wildenhues at gmx.de>
+
+	* Makefile.in: Regenerate.
+	* configure: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* man/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+
+2009-12-04  David Edelsohn  <edelsohn at gnu.org>
+
+	* src/powerpc/aix_closure.S: Reorganize 64-bit code to match
+	linux64_closure.S.
+
+2009-12-04  Uros Bizjak  <ubizjak at gmail.com>
+
+	PR libffi/41908
+	* src/x86/ffi64.c (classify_argument): Update from
+	gcc/config/i386/i386.c.
+	(ffi_closure_unix64_inner): Do not use the address of two consecutive
+	SSE registers directly.
+	* testsuite/libffi.call/cls_dbls_struct.c (main): Remove xfail
+	for x86_64 linux targets.
+
+2009-12-04  David Edelsohn  <edelsohn at gnu.org>
+
+	* src/powerpc/ffi_darwin.c (ffi_closure_helper_DARWIN): Increment
+	pfr for long double split between fpr13 and stack.
+
+2009-12-03  David Edelsohn  <edelsohn at gnu.org>
+
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Increment next_arg and
+	fparg_count twice for long double.
+
+2009-12-03  David Edelsohn  <edelsohn at gnu.org>
+
+	PR libffi/42243
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Remove extra parentheses.
+
+2009-12-03  Uros Bizjak  <ubizjak at gmail.com>
+
+	* testsuite/libffi.call/cls_longdouble_va.c (main): Fix format string.
+	Remove xfails for x86 linux targets.
+
+2009-12-02  David Edelsohn  <edelsohn at gnu.org>
+
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Fix typo in INT64
+	case.
+
+2009-12-01  David Edelsohn  <edelsohn at gnu.org>
+
+	* src/powerpc/aix.S (ffi_call_AIX): Convert to more standard
+	register usage.  Call ffi_prep_args directly.  Add long double
+	return value support.
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Double arg increment
+	applies to FFI_TYPE_DOUBLE.  Correct fpr_base increment typo.
+	Separate FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases.
+	(ffi_prep_cif_machdep): Only 16 byte stack alignment in 64 bit
+	mode.
+	(ffi_closure_helper_DARWIN): Remove nf and ng counters.  Move temp
+	into case.
+	* src/powerpc/aix_closure.S: Maintain 16 byte stack alignment.
+	Allocate result area between params and FPRs.
+
+2009-11-30  David Edelsohn  <edelsohn at gnu.org>
+
+	PR target/35484
+	* src/powerpc/ffitarget.h (POWERPC64): Define for PPC64 Linux and
+	AIX64.
+	* src/powerpc/aix.S: Implement AIX64 version.
+	* src/powerpc/aix_closure.S: Implement AIX64 version.
+	(ffi_closure_ASM): Use extsb, lha and displament addresses.
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Implement AIX64
+	support.
+	(ffi_prep_cif_machdep): Same.
+	(ffi_call): Same.
+	(ffi_closure_helper_DARWIN): Same.
+
+2009-11-02  Andreas Tobler  <a.tobler at schweiz.org>
+
+	PR libffi/41908
+	* testsuite/libffi.call/testclosure.c: New test.
+
+2009-09-28  Kai Tietz  <kai.tietz at onevision.com>
+
+	* src/x86/win64.S (_ffi_call_win64 stack): Remove for gnu
+	assembly version use of ___chkstk.
+
+2009-09-23  Matthias Klose  <doko at ubuntu.com>
+
+	PR libffi/40242, PR libffi/41443
+	* src/arm/sysv.S (__ARM_ARCH__): Define for processors
+	__ARM_ARCH_6T2__, __ARM_ARCH_6M__, __ARM_ARCH_7__,
+	__ARM_ARCH_7A__, __ARM_ARCH_7R__, __ARM_ARCH_7M__.
+	Change the conditionals to __SOFTFP__ || __ARM_EABI__
+	for -mfloat-abi=softfp to work.
+
+2009-09-17  Loren J. Rittle  <ljrittle at acm.org>
+
+	PR testsuite/32843 (strikes again)
+	* src/x86/ffi.c (ffi_prep_cif_machdep): Add X86_FREEBSD to
+	enable proper extension on char and short.
+
+2009-09-15  David Daney  <ddaney at caviumnetworks.com>
+
+	* src/java_raw_api.c (ffi_java_raw_to_rvalue): Remove special
+	handling for FFI_TYPE_POINTER.
+	* src/mips/ffitarget.h (FFI_TYPE_STRUCT_D_SOFT,
+	FFI_TYPE_STRUCT_F_SOFT, FFI_TYPE_STRUCT_DD_SOFT,
+	FFI_TYPE_STRUCT_FF_SOFT, FFI_TYPE_STRUCT_FD_SOFT,
+	FFI_TYPE_STRUCT_DF_SOFT, FFI_TYPE_STRUCT_SOFT): New defines.
+	(FFI_N32_SOFT_FLOAT, FFI_N64_SOFT_FLOAT): New ffi_abi enumerations.
+	(enum ffi_abi): Set FFI_DEFAULT_ABI for soft-float.
+	* src/mips/n32.S (ffi_call_N32): Add handling for soft-float
+	structure and pointer returns.
+	(ffi_closure_N32): Add handling for pointer returns.
+	* src/mips/ffi.c (ffi_prep_args, calc_n32_struct_flags,
+	calc_n32_return_struct_flags): Handle soft-float.
+	(ffi_prep_cif_machdep):  Handle soft-float, fix pointer handling.
+	(ffi_call_N32): Declare proper argument types.
+	(ffi_call, copy_struct_N32, ffi_closure_mips_inner_N32): Handle
+	soft-float.
+
+2009-08-24  Ralf Wildenhues  <Ralf.Wildenhues at gmx.de>
+
+	* configure.ac (AC_PREREQ): Bump to 2.64.
+
+2009-08-22  Ralf Wildenhues  <Ralf.Wildenhues at gmx.de>
+
+	* Makefile.am (install-html, install-pdf): Remove.
+	* Makefile.in: Regenerate.
+
+	* Makefile.in: Regenerate.
+	* aclocal.m4: Regenerate.
+	* configure: Regenerate.
+	* fficonfig.h.in: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* man/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+
+2009-07-30  Ralf Wildenhues  <Ralf.Wildenhues at gmx.de>
+
+	* configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force.
+
+2009-07-24  Dave Korn  <dave.korn.cygwin at gmail.com>
+
+	PR libffi/40807
+	* src/x86/ffi.c (ffi_prep_cif_machdep): Also use sign/zero-extending
+	return types for X86_WIN32.
+	* src/x86/win32.S (_ffi_call_SYSV): Handle omitted return types.
+	(_ffi_call_STDCALL, _ffi_closure_SYSV, _ffi_closure_raw_SYSV,
+	_ffi_closure_STDCALL): Likewise.
+
+	* src/closures.c (is_selinux_enabled): Define to const 0 for Cygwin.
+	(dlmmap, dlmunmap): Also use these functions on Cygwin.
+
+2009-07-11  Richard Sandiford  <rdsandiford at googlemail.com>
+
+	PR testsuite/40699
+	PR testsuite/40707
+	PR testsuite/40709
+	* testsuite/lib/libffi-dg.exp: Revert 2009-07-02, 2009-07-01 and
+	2009-06-30 commits.
+
+2009-07-01  Richard Sandiford  <r.sandiford at uk.ibm.com>
+
+	* testsuite/lib/libffi-dg.exp (libffi-init): Set ld_library_path
+	to "" before adding paths.  (This reinstates an assignment that
+	was removed by my 2009-06-30 commit, but changes the initial
+	value from "." to "".)
+
+2009-07-01  H.J. Lu  <hongjiu.lu at intel.com>
+
+	PR testsuite/40601
+	* testsuite/lib/libffi-dg.exp (libffi-init): Properly set
+	gccdir.  Adjust ld_library_path for gcc only if gccdir isn't
+	empty.
+
+2009-06-30  Richard Sandiford  <r.sandiford at uk.ibm.com>
+
+	* testsuite/lib/libffi-dg.exp (libffi-init): Don't add "."
+	to ld_library_path.  Use add_path.  Add just find_libgcc_s
+	to ld_library_path, not every libgcc multilib directory.
+
+2009-06-16  Wim Lewis  <wiml at hhhh.org>
+
+	* src/powerpc/ffi.c: Avoid clobbering cr3 and cr4, which are
+	supposed to be callee-saved.
+	* src/powerpc/sysv.S (small_struct_return_value): Fix overrun of
+	return buffer for odd-size structs.
+
+2009-06-16  Andreas Tobler  <a.tobler at schweiz.org>
+
+	PR libffi/40444
+	* testsuite/lib/libffi-dg.exp (libffi_target_compile): Add
+	allow_stack_execute for Darwin.
+
+2009-06-16  Andrew Haley  <aph at redhat.com>
+
+	* configure.ac (TARGETDIR): Add missing blank lines.
+	* configure: Regenerate.
+
+2009-06-16  Andrew Haley  <aph at redhat.com>
+
+	* testsuite/libffi.call/cls_align_sint64.c,
+	testsuite/libffi.call/cls_align_uint64.c,
+	testsuite/libffi.call/cls_longdouble_va.c,
+	testsuite/libffi.call/cls_ulonglong.c,
+	testsuite/libffi.call/return_ll1.c,
+	testsuite/libffi.call/stret_medium2.c: Fix printf format
+	specifiers.
+	* testsuite/libffi.call/ffitest.h,
+	testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define.
+
+2009-06-15  Andrew Haley  <aph at redhat.com>
+
+	* testsuite/libffi.call/err_bad_typedef.c: xfail everywhere.
+	* testsuite/libffi.call/err_bad_abi.c: Likewise.
+
+2009-06-12  Andrew Haley  <aph at redhat.com>
+
+	* Makefile.am: Remove info_TEXINFOS.
+
+2009-06-12  Andrew Haley  <aph at redhat.com>
+
+	* ChangeLog.libffi: testsuite/libffi.call/cls_align_sint64.c,
+	testsuite/libffi.call/cls_align_uint64.c,
+	testsuite/libffi.call/cls_ulonglong.c,
+	testsuite/libffi.call/return_ll1.c,
+	testsuite/libffi.call/stret_medium2.c: Fix printf format
+	specifiers.
+	testsuite/libffi.special/unwindtest.cc: include stdint.h.
+
+2009-06-11  Timothy Wall  <twall at users.sf.net>
+
+	* Makefile.am,
+	configure.ac,
+	include/ffi.h.in,
+	include/ffi_common.h,
+	src/closures.c,
+	src/dlmalloc.c,
+	src/x86/ffi.c,
+	src/x86/ffitarget.h,
+	src/x86/win64.S (new),
+	README: Added win64 support (mingw or MSVC)
+	* Makefile.in,
+	include/Makefile.in,
+	man/Makefile.in,
+	testsuite/Makefile.in,
+	configure,
+	aclocal.m4: Regenerated
+	* ltcf-c.sh: properly escape cygwin/w32 path
+	* man/ffi_call.3: Clarify size requirements for return value.
+	* src/x86/ffi64.c: Fix filename in comment.
+	* src/x86/win32.S: Remove unused extern.
+
+	* testsuite/libffi.call/closure_fn0.c,
+	testsuite/libffi.call/closure_fn1.c,
+	testsuite/libffi.call/closure_fn2.c,
+	testsuite/libffi.call/closure_fn3.c,
+	testsuite/libffi.call/closure_fn4.c,
+	testsuite/libffi.call/closure_fn5.c,
+	testsuite/libffi.call/closure_fn6.c,
+	testsuite/libffi.call/closure_stdcall.c,
+	testsuite/libffi.call/cls_12byte.c,
+	testsuite/libffi.call/cls_16byte.c,
+	testsuite/libffi.call/cls_18byte.c,
+	testsuite/libffi.call/cls_19byte.c,
+	testsuite/libffi.call/cls_1_1byte.c,
+	testsuite/libffi.call/cls_20byte.c,
+	testsuite/libffi.call/cls_20byte1.c,
+	testsuite/libffi.call/cls_24byte.c,
+	testsuite/libffi.call/cls_2byte.c,
+	testsuite/libffi.call/cls_3_1byte.c,
+	testsuite/libffi.call/cls_3byte1.c,
+ 	testsuite/libffi.call/cls_3byte2.c,
+ 	testsuite/libffi.call/cls_4_1byte.c,
+ 	testsuite/libffi.call/cls_4byte.c,
+ 	testsuite/libffi.call/cls_5_1_byte.c,
+ 	testsuite/libffi.call/cls_5byte.c,
+ 	testsuite/libffi.call/cls_64byte.c,
+ 	testsuite/libffi.call/cls_6_1_byte.c,
+ 	testsuite/libffi.call/cls_6byte.c,
+ 	testsuite/libffi.call/cls_7_1_byte.c,
+ 	testsuite/libffi.call/cls_7byte.c,
+ 	testsuite/libffi.call/cls_8byte.c,
+ 	testsuite/libffi.call/cls_9byte1.c,
+ 	testsuite/libffi.call/cls_9byte2.c,
+ 	testsuite/libffi.call/cls_align_double.c,
+ 	testsuite/libffi.call/cls_align_float.c,
+ 	testsuite/libffi.call/cls_align_longdouble.c,
+ 	testsuite/libffi.call/cls_align_longdouble_split.c,
+ 	testsuite/libffi.call/cls_align_longdouble_split2.c,
+ 	testsuite/libffi.call/cls_align_pointer.c,
+ 	testsuite/libffi.call/cls_align_sint16.c,
+ 	testsuite/libffi.call/cls_align_sint32.c,
+ 	testsuite/libffi.call/cls_align_sint64.c,
+ 	testsuite/libffi.call/cls_align_uint16.c,
+ 	testsuite/libffi.call/cls_align_uint32.c,
+ 	testsuite/libffi.call/cls_align_uint64.c,
+ 	testsuite/libffi.call/cls_dbls_struct.c,
+ 	testsuite/libffi.call/cls_double.c,
+ 	testsuite/libffi.call/cls_double_va.c,
+ 	testsuite/libffi.call/cls_float.c,
+ 	testsuite/libffi.call/cls_longdouble.c,
+ 	testsuite/libffi.call/cls_longdouble_va.c,
+ 	testsuite/libffi.call/cls_multi_schar.c,
+ 	testsuite/libffi.call/cls_multi_sshort.c,
+ 	testsuite/libffi.call/cls_multi_sshortchar.c,
+ 	testsuite/libffi.call/cls_multi_uchar.c,
+ 	testsuite/libffi.call/cls_multi_ushort.c,
+ 	testsuite/libffi.call/cls_multi_ushortchar.c,
+ 	testsuite/libffi.call/cls_pointer.c,
+ 	testsuite/libffi.call/cls_pointer_stack.c,
+ 	testsuite/libffi.call/cls_schar.c,
+ 	testsuite/libffi.call/cls_sint.c,
+ 	testsuite/libffi.call/cls_sshort.c,
+ 	testsuite/libffi.call/cls_uchar.c,
+ 	testsuite/libffi.call/cls_uint.c,
+ 	testsuite/libffi.call/cls_ulonglong.c,
+ 	testsuite/libffi.call/cls_ushort.c,
+ 	testsuite/libffi.call/err_bad_abi.c,
+ 	testsuite/libffi.call/err_bad_typedef.c,
+ 	testsuite/libffi.call/float2.c,
+ 	testsuite/libffi.call/huge_struct.c,
+ 	testsuite/libffi.call/nested_struct.c,
+ 	testsuite/libffi.call/nested_struct1.c,
+ 	testsuite/libffi.call/nested_struct10.c,
+ 	testsuite/libffi.call/nested_struct2.c,
+ 	testsuite/libffi.call/nested_struct3.c,
+ 	testsuite/libffi.call/nested_struct4.c,
+ 	testsuite/libffi.call/nested_struct5.c,
+ 	testsuite/libffi.call/nested_struct6.c,
+ 	testsuite/libffi.call/nested_struct7.c,
+ 	testsuite/libffi.call/nested_struct8.c,
+ 	testsuite/libffi.call/nested_struct9.c,
+ 	testsuite/libffi.call/problem1.c,
+ 	testsuite/libffi.call/return_ldl.c,
+ 	testsuite/libffi.call/return_ll1.c,
+ 	testsuite/libffi.call/stret_large.c,
+ 	testsuite/libffi.call/stret_large2.c,
+ 	testsuite/libffi.call/stret_medium.c,
+ 	testsuite/libffi.call/stret_medium2.c,
+	testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead
+	of checking for MMAP.  Use intptr_t instead of long casts.
+
+2009-06-11  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* testsuite/libffi.call/cls_longdouble_va.c: Add xfail sh*-*-linux-*.
+	* testsuite/libffi.call/err_bad_abi.c: Add xfail sh*-*-*.
+	* testsuite/libffi.call/err_bad_typedef.c: Likewise.
+
+2009-06-09  Andrew Haley  <aph at redhat.com>
+
+	* src/x86/freebsd.S: Add missing file.
+
+2009-06-08  Andrew Haley  <aph at redhat.com>
+
+	Import from libffi 3.0.8:
+
+	* doc/libffi.texi: New file.
+	* doc/libffi.info: Likewise.
+	* doc/stamp-vti: Likewise.
+	* man/Makefile.am: New file.
+	* man/ffi_call.3: New file.
+
+	* Makefile.am (EXTRA_DIST): Add src/x86/darwin64.S,
+	src/dlmalloc.c.
+	(nodist_libffi_la_SOURCES): Add X86_FREEBSD.
+
+	* configure.ac: Bump version to 3.0.8.
+	parisc*-*-linux*: Add.
+	i386-*-freebsd* | i386-*-openbsd*: Add.
+	powerpc-*-beos*: Add.
+	AM_CONDITIONAL X86_FREEBSD: Add.
+	AC_CONFIG_FILES: Add man/Makefile.
+
+	* include/ffi.h.in (FFI_FN): Change void (*)() to void (*)(void).
+
+2009-06-08  Andrew Haley  <aph at redhat.com>
+
+	* README: Import from libffi 3.0.8.
+
+2009-06-08  Andrew Haley  <aph at redhat.com>
+
+	* testsuite/libffi.call/err_bad_abi.c: Add xfails.
+	* testsuite/libffi.call/cls_longdouble_va.c: Add xfails.
+	* testsuite/libffi.call/cls_dbls_struct.c: Add xfail x86_64-*-linux-*.
+	* testsuite/libffi.call/err_bad_typedef.c: Add xfails.
+
+	* testsuite/libffi.call/stret_medium2.c: Add __UNUSED__ to args.
+	* testsuite/libffi.call/stret_medium.c: Likewise.
+	* testsuite/libffi.call/stret_large2.c: Likewise.
+	* testsuite/libffi.call/stret_large.c:  Likewise.
+
+2008-12-26  Timothy Wall  <twall at users.sf.net>
+
+	* testsuite/libffi.call/cls_longdouble.c,
+	testsuite/libffi.call/cls_longdouble_va.c,
+	testsuite/libffi.call/cls_align_longdouble.c,
+	testsuite/libffi.call/cls_align_longdouble_split.c,
+	testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected
+	failures on x86_64 cygwin/mingw.
+
+2008-12-22  Timothy Wall  <twall at users.sf.net>
+
+	* testsuite/libffi.call/closure_fn0.c,
+	testsuite/libffi.call/closure_fn1.c,
+	testsuite/libffi.call/closure_fn2.c,
+	testsuite/libffi.call/closure_fn3.c,
+	testsuite/libffi.call/closure_fn4.c,
+	testsuite/libffi.call/closure_fn5.c,
+	testsuite/libffi.call/closure_fn6.c,
+	testsuite/libffi.call/closure_loc_fn0.c,
+	testsuite/libffi.call/closure_stdcall.c,
+	testsuite/libffi.call/cls_align_pointer.c,
+	testsuite/libffi.call/cls_pointer.c,
+	testsuite/libffi.call/cls_pointer_stack.c: use portable cast from
+	pointer to integer (intptr_t).
+	* testsuite/libffi.call/cls_longdouble.c: disable for win64.
+
+2008-07-24  Anthony Green  <green at redhat.com>
+
+	* testsuite/libffi.call/cls_dbls_struct.c,
+	testsuite/libffi.call/cls_double_va.c,
+	testsuite/libffi.call/cls_longdouble.c,
+	testsuite/libffi.call/cls_longdouble_va.c,
+	testsuite/libffi.call/cls_pointer.c,
+	testsuite/libffi.call/cls_pointer_stack.c,
+	testsuite/libffi.call/err_bad_abi.c: Clean up failures from
+	compiler warnings.
+
+2008-03-04  Anthony Green  <green at redhat.com>
+	    Blake Chaffin
+	    hos at tamanegi.org
+
+	* testsuite/libffi.call/cls_align_longdouble_split2.c
+	  testsuite/libffi.call/cls_align_longdouble_split.c
+	  testsuite/libffi.call/cls_dbls_struct.c
+	  testsuite/libffi.call/cls_double_va.c
+	  testsuite/libffi.call/cls_longdouble.c
+	  testsuite/libffi.call/cls_longdouble_va.c
+	  testsuite/libffi.call/cls_pointer.c
+	  testsuite/libffi.call/cls_pointer_stack.c
+	  testsuite/libffi.call/err_bad_abi.c
+	  testsuite/libffi.call/err_bad_typedef.c
+	  testsuite/libffi.call/stret_large2.c
+	  testsuite/libffi.call/stret_large.c
+	  testsuite/libffi.call/stret_medium2.c
+	  testsuite/libffi.call/stret_medium.c: New tests from Apple.
+
+2009-06-05  Andrew Haley  <aph at redhat.com>
+
+	* src/x86/ffitarget.h, src/x86/ffi.c: Merge stdcall changes from
+	libffi.
+
+2009-06-04  Andrew Haley  <aph at redhat.com>
+
+	* src/x86/ffitarget.h, src/x86/win32.S, src/x86/ffi.c: Back out
+	stdcall changes.
+
+2008-02-26  Anthony Green  <green at redhat.com>
+	    Thomas Heller  <theller at ctypes.org>
+
+	* src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C
+	comment.
+
+2008-02-03  Timothy Wall  <twall at users.sf.net>
+
+	* src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return
+	  offset based on code pointer, not data pointer.
+
+2008-01-31  Timothy Wall <twall at users.sf.net>
+
+	* testsuite/libffi.call/closure_stdcall.c: Add test for stdcall
+	closures.
+	* src/x86/ffitarget.h: Increase size of trampoline for stdcall
+	closures.
+	* src/x86/win32.S: Add assembly for stdcall closure.
+	* src/x86/ffi.c: Initialize stdcall closure trampoline.
+
+2009-06-04  Andrew Haley  <aph at redhat.com>
+
+	* include/ffi.h.in: Change void (*)() to void (*)(void).
+	* src/x86/ffi.c: Likewise.
+
+2009-06-04  Andrew Haley  <aph at redhat.com>
+
+	* src/powerpc/ppc_closure.S: Insert licence header.
+	* src/powerpc/linux64_closure.S: Likewise.
+	* src/m68k/sysv.S: Likewise.
+
+	* src/sh64/ffi.c: Change void (*)() to void (*)(void).
+	* src/powerpc/ffi.c: Likewise.
+	* src/powerpc/ffi_darwin.c: Likewise.
+	* src/m32r/ffi.c: Likewise.
+	* src/sh64/ffi.c: Likewise.
+	* src/x86/ffi64.c: Likewise.
+	* src/alpha/ffi.c: Likewise.
+	* src/alpha/osf.S: Likewise.
+	* src/frv/ffi.c: Likewise.
+	* src/s390/ffi.c: Likewise.
+	* src/pa/ffi.c: Likewise.
+	* src/pa/hpux32.S: Likewise.
+	* src/ia64/unix.S: Likewise.
+	* src/ia64/ffi.c: Likewise.
+	* src/sparc/ffi.c: Likewise.
+	* src/mips/ffi.c: Likewise.
+	* src/sh/ffi.c: Likewise.
+
+2008-02-15  David Daney  <ddaney at avtrex.com>
+
+	* src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE):
+	Define (conditionally), and use it to include cachectl.h.
+	(ffi_prep_closure_loc): Fix cache flushing.
+	* src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define.
+
+2009-06-04  Andrew Haley  <aph at redhat.com>
+
+	include/ffi.h.in,
+	src/arm/ffitarget.h,
+	src/arm/ffi.c,
+	src/arm/sysv.S,
+	src/powerpc/ffitarget.h,
+	src/closures.c,
+	src/sh64/ffitarget.h,
+	src/sh64/ffi.c,
+	src/sh64/sysv.S,
+	src/types.c,
+	src/x86/ffi64.c,
+	src/x86/ffitarget.h,
+	src/x86/win32.S,
+	src/x86/darwin.S,
+	src/x86/ffi.c,
+	src/x86/sysv.S,
+	src/x86/unix64.S,
+	src/alpha/ffitarget.h,
+	src/alpha/ffi.c,
+	src/alpha/osf.S,
+	src/m68k/ffitarget.h,
+	src/frv/ffitarget.h,
+	src/frv/ffi.c,
+	src/s390/ffitarget.h,
+	src/s390/sysv.S,
+	src/cris/ffitarget.h,
+	src/pa/linux.S,
+	src/pa/ffitarget.h,
+	src/pa/ffi.c,
+	src/raw_api.c,
+	src/ia64/ffitarget.h,
+	src/ia64/unix.S,
+	src/ia64/ffi.c,
+	src/ia64/ia64_flags.h,
+	src/java_raw_api.c,
+	src/debug.c,
+	src/sparc/v9.S,
+	src/sparc/ffitarget.h,
+	src/sparc/ffi.c,
+	src/sparc/v8.S,
+	src/mips/ffitarget.h,
+	src/mips/n32.S,
+	src/mips/o32.S,
+	src/mips/ffi.c,
+	src/prep_cif.c,
+	src/sh/ffitarget.h,
+	src/sh/ffi.c,
+	src/sh/sysv.S: Update license text.
+
+2009-05-22  Dave Korn  <dave.korn.cygwin at gmail.com>
+
+	* src/x86/win32.S (_ffi_closure_STDCALL):  New function.
+	(.eh_frame):  Add FDE for it.
+
+2009-05-22  Dave Korn  <dave.korn.cygwin at gmail.com>
+
+	* configure.ac:  Also check if assembler supports pc-relative
+	relocs on X86_WIN32 targets.
+	* configure:  Regenerate.
+	* src/x86/win32.S (ffi_prep_args):  Declare extern, not global.
+	(_ffi_call_SYSV):  Add missing function type symbol .def and
+	add EH markup labels.
+	(_ffi_call_STDCALL):  Likewise.
+	(_ffi_closure_SYSV):  Likewise.
+	(_ffi_closure_raw_SYSV):  Likewise.
+	(.eh_frame):  Add hand-crafted EH data.
+
+2009-04-09  Jakub Jelinek  <jakub at redhat.com>
+
+	* testsuite/lib/libffi-dg.exp: Change copyright header to refer to
+	version 3 of the GNU General Public License and to point readers
+	at the COPYING3 file and the FSF's license web page.
+	* testsuite/libffi.call/call.exp: Likewise.
+	* testsuite/libffi.special/special.exp: Likewise.
+
+2009-03-01  Ralf Wildenhues  <Ralf.Wildenhues at gmx.de>
+
+	* configure: Regenerate.
+
+2008-12-18  Rainer Orth  <ro at TechFak.Uni-Bielefeld.DE>
+
+	PR libffi/26048
+	* configure.ac (HAVE_AS_X86_PCREL): New test.
+	* configure: Regenerate.
+	* fficonfig.h.in: Regenerate.
+	* src/x86/sysv.S [!FFI_NO_RAW_API]: Precalculate
+	RAW_CLOSURE_CIF_OFFSET, RAW_CLOSURE_FUN_OFFSET,
+	RAW_CLOSURE_USER_DATA_OFFSET for the Solaris 10/x86 assembler.
+	(.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL.
+	* src/x86/unix64.S (.Lstore_table): Move to .text section.
+	(.Lload_table): Likewise.
+	(.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL.
+
+2008-12-18  Ralf Wildenhues  <Ralf.Wildenhues at gmx.de>
+
+	* configure: Regenerate.
+
+2008-11-21  Eric Botcazou  <ebotcazou at adacore.com>
+
+	* src/sparc/ffi.c (ffi_prep_cif_machdep): Add support for
+	signed/unsigned int8/16 return values.
+	* src/sparc/v8.S (ffi_call_v8): Likewise.
+	(ffi_closure_v8): Likewise.
+
+2008-09-26  Peter O'Gorman  <pogma at thewrittenword.com>
+	    Steve Ellcey  <sje at cup.hp.com>
+
+	* configure: Regenerate for new libtool.
+	* Makefile.in: Ditto.
+	* include/Makefile.in: Ditto.
+	* aclocal.m4: Ditto.
+
+2008-08-25  Andreas Tobler  <a.tobler at schweiz.org>
+
+	* src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and
+	FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum.
+	Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT.
+	Adjust copyright notice.
+	* src/powerpc/ffi.c: Add two new flags to indicate if we have one
+	register or two register to use for FFI_SYSV structs.
+	(ffi_prep_cif_machdep): Pass the right register flag introduced above.
+	(ffi_closure_helper_SYSV): Fix the return type for
+	FFI_SYSV_TYPE_SMALL_STRUCT. Comment.
+	Adjust copyright notice.
+
+2008-07-16  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned
+	int.
+
+2008-06-17  Ralf Wildenhues  <Ralf.Wildenhues at gmx.de>
+
+	* configure: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+
+2008-06-07  Joseph Myers  <joseph at codesourcery.com>
+
+	* configure.ac (parisc*-*-linux*, powerpc-*-sysv*,
+	powerpc-*-beos*): Remove.
+	* configure: Regenerate.
+
+2008-05-09  Julian Brown  <julian at codesourcery.com>
+
+	* Makefile.am (LTLDFLAGS): New.
+	(libffi_la_LDFLAGS): Use above.
+	* Makefile.in: Regenerate.
+
+2008-04-18  Paolo Bonzini  <bonzini at gnu.org>
+
+	PR bootstrap/35457
+	* aclocal.m4: Regenerate.
+	* configure: Regenerate.
+
+2008-03-26  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* src/sh/sysv.S: Add .note.GNU-stack on Linux.
+	* src/sh64/sysv.S: Likewise.
+
+2008-03-26  Daniel Jacobowitz  <dan at debian.org>
+
+	* src/arm/sysv.S: Fix ARM comment marker.
+
+2008-03-26  Jakub Jelinek  <jakub at redhat.com>
+
+	* src/alpha/osf.S: Add .note.GNU-stack on Linux.
+	* src/s390/sysv.S: Likewise.
+	* src/powerpc/ppc_closure.S: Likewise.
+	* src/powerpc/sysv.S: Likewise.
+	* src/x86/unix64.S: Likewise.
+	* src/x86/sysv.S: Likewise.
+	* src/sparc/v8.S: Likewise.
+	* src/sparc/v9.S: Likewise.
+	* src/m68k/sysv.S: Likewise.
+	* src/arm/sysv.S: Likewise.
+
+2008-03-16  Ralf Wildenhues  <Ralf.Wildenhues at gmx.de>
+
+	* aclocal.m4: Regenerate.
+	* configure: Likewise.
+	* Makefile.in: Likewise.
+	* include/Makefile.in: Likewise.
+	* testsuite/Makefile.in: Likewise.
+
+2008-02-12  Bjoern Koenig  <bkoenig at alpha-tierchen.de>
+	    Andreas Tobler  <a.tobler at schweiz.org>
+
+	* configure.ac: Add amd64-*-freebsd* target.
+	* configure: Regenerate.
+
+2008-01-30  H.J. Lu  <hongjiu.lu at intel.com>
+
+	PR libffi/34612
+	* src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when
+	returning struct.
+
+	* testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer"
+	tests.
+
+2008-01-24  David Edelsohn  <edelsohn at gnu.org>
+
+	* configure: Regenerate.
+
+2008-01-06  Andreas Tobler  <a.tobler at schweiz.org>
+
+	* src/x86/ffi.c (ffi_prep_cif_machdep): Fix thinko.
+
+2008-01-05  Andreas Tobler  <a.tobler at schweiz.org>
+
+	PR testsuite/32843
+	* src/x86/ffi.c (ffi_prep_cif_machdep): Add code for
+	signed/unsigned int8/16 for X86_DARWIN.
+	Updated copyright info.
+	Handle one and two byte structs with special cif->flags.
+	* src/x86/ffitarget.h: Add special types for one and two byte structs.
+	Updated copyright info.
+	* src/x86/darwin.S (ffi_call_SYSV): Rewrite to use a jump table like
+	sysv.S
+	Remove code to pop args from the stack after call.
+	Special-case signed/unsigned for int8/16, one and two byte structs.
+	(ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8,
+	FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32,
+	FFI_TYPE_SINT32.
+	Updated copyright info.
+
+2007-12-08  David Daney  <ddaney at avtrex.com>
+
+	* src/mips/n32.S (ffi_call_N32):  Replace dadd with ADDU, dsub with
+	SUBU, add with ADDU and use smaller code sequences.
+
+2007-12-07  David Daney  <ddaney at avtrex.com>
+
+	* src/mips/ffi.c (ffi_prep_cif_machdep): Handle long double return
+	type.
+
+2007-12-06  David Daney  <ddaney at avtrex.com>
+
+	* include/ffi.h.in (FFI_SIZEOF_JAVA_RAW): Define if not	already
+	defined.
+	(ffi_java_raw): New typedef.
+	(ffi_java_raw_call, ffi_java_ptrarray_to_raw,
+	ffi_java_raw_to_ptrarray): Change parameter types from ffi_raw to
+	ffi_java_raw.
+	(ffi_java_raw_closure) : Same.
+	(ffi_prep_java_raw_closure, ffi_prep_java_raw_closure_loc): Change
+	parameter types.
+	* src/java_raw_api.c (ffi_java_raw_size):  Replace FFI_SIZEOF_ARG with
+	FFI_SIZEOF_JAVA_RAW.
+	(ffi_java_raw_to_ptrarray): Change type of raw to ffi_java_raw.
+	Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. Use
+	sizeof(ffi_java_raw) for alignment calculations.
+	(ffi_java_ptrarray_to_raw): Same.
+	(ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER
+	if FFI_SIZEOF_JAVA_RAW == 4.
+	(ffi_java_raw_to_rvalue): Same.
+	(ffi_java_raw_call): Change type of raw to ffi_java_raw.
+	(ffi_java_translate_args): Same.
+	(ffi_prep_java_raw_closure_loc, ffi_prep_java_raw_closure): Change
+	parameter types.
+	* src/mips/ffitarget.h (FFI_SIZEOF_JAVA_RAW): Define for N32 ABI.
+
+2007-12-06  David Daney  <ddaney at avtrex.com>
+
+	* src/mips/n32.S (ffi_closure_N32): Use 64-bit add instruction on
+	pointer values.
+
+2007-12-01  Andreas Tobler  <a.tobler at schweiz.org>
+
+	PR libffi/31937
+	* src/powerpc/ffitarget.h: Introduce new ABI FFI_LINUX_SOFT_FLOAT.
+	Add local FFI_TYPE_UINT128 to handle soft-float long-double-128.
+	* src/powerpc/ffi.c: Distinguish between __NO_FPRS__ and not and
+	set the NUM_FPR_ARG_REGISTERS according to.
+	Add support for potential soft-float support under hard-float
+	architecture.
+	(ffi_prep_args_SYSV): Set NUM_FPR_ARG_REGISTERS to 0 in case of
+	FFI_LINUX_SOFT_FLOAT, handle float, doubles and long-doubles according
+	to the FFI_LINUX_SOFT_FLOAT ABI.
+	(ffi_prep_cif_machdep): Likewise.
+	(ffi_closure_helper_SYSV): Likewise.
+	* src/powerpc/ppc_closure.S: Make sure not to store float/double
+	on archs where __NO_FPRS__ is true.
+	Add FFI_TYPE_UINT128 support.
+	* src/powerpc/sysv.S: Add support for soft-float long-double-128.
+	Adjust copyright notice.
+
+2007-11-25  Andreas Tobler  <a.tobler at schweiz.org>
+
+	* src/closures.c: Move defintion of MAYBE_UNUSED from here to ...
+	* include/ffi_common.h: ... here.
+	Update copyright.
+
+2007-11-17  Andreas Tobler  <a.tobler at schweiz.org>
+
+	* src/powerpc/sysv.S: Load correct cr to compare if we have long double.
+	* src/powerpc/linux64.S: Likewise.
+	* src/powerpc/ffi.c: Add a comment to show which part goes into cr6.
+	* testsuite/libffi.call/return_ldl.c: New test.
+
+2007-09-04    <aph at redhat.com>
+
+	* src/arm/sysv.S (UNWIND): New.
+	(Whole file): Conditionally compile unwinder directives.
+	* src/arm/sysv.S: Add unwinder directives.
+
+	* src/arm/ffi.c (ffi_prep_args): Align structs by at least 4 bytes.
+	Only treat r0 as a struct address if we're actually returning a
+	struct by address.
+	Only copy the bytes that are actually within a struct.
+	(ffi_prep_cif_machdep): A Composite Type not larger than 4 bytes
+	is returned in r0, not passed by address.
+	(ffi_call): Allocate a word-sized temporary for the case where
+	a composite is returned in r0.
+	(ffi_prep_incoming_args_SYSV): Align as necessary.
+
+2007-08-05  Steven Newbury  <s_j_newbury at yahoo.co.uk>
+
+	* src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Use __clear_cache instead of
+	directly using the sys_cacheflush syscall.
+
+2007-07-27  Andrew Haley  <aph at redhat.com>
+
+	* src/arm/sysv.S (ffi_closure_SYSV): Add soft-float.
+
+2007-09-03  Maciej W. Rozycki  <macro at linux-mips.org>
+
+	* Makefile.am: Unify MIPS_IRIX and MIPS_LINUX into MIPS.
+	* configure.ac: Likewise.
+	* Makefile.in: Regenerate.
+	* include/Makefile.in: Likewise.
+	* testsuite/Makefile.in: Likewise.
+	* configure: Likewise.
+
+2007-08-24  David Daney  <ddaney at avtrex.com>
+
+	* testsuite/libffi.call/return_sl.c: New test.
+
+2007-08-10  David Daney  <ddaney at avtrex.com>
+
+	* testsuite/libffi.call/cls_multi_ushort.c,
+	testsuite/libffi.call/cls_align_uint16.c,
+	testsuite/libffi.call/nested_struct1.c,
+	testsuite/libffi.call/nested_struct3.c,
+	testsuite/libffi.call/cls_7_1_byte.c,
+	testsuite/libffi.call/nested_struct5.c,
+	testsuite/libffi.call/cls_double.c,
+	testsuite/libffi.call/nested_struct7.c,
+	testsuite/libffi.call/cls_sint.c,
+	testsuite/libffi.call/nested_struct9.c,
+	testsuite/libffi.call/cls_20byte1.c,
+	testsuite/libffi.call/cls_multi_sshortchar.c,
+	testsuite/libffi.call/cls_align_sint64.c,
+	testsuite/libffi.call/cls_3byte2.c,
+	testsuite/libffi.call/cls_multi_schar.c,
+	testsuite/libffi.call/cls_multi_uchar.c,
+	testsuite/libffi.call/cls_19byte.c,
+	testsuite/libffi.call/cls_9byte1.c,
+	testsuite/libffi.call/cls_align_float.c,
+	testsuite/libffi.call/closure_fn1.c,
+	testsuite/libffi.call/problem1.c,
+	testsuite/libffi.call/closure_fn3.c,
+	testsuite/libffi.call/cls_sshort.c,
+	testsuite/libffi.call/closure_fn5.c,
+	testsuite/libffi.call/cls_align_double.c,
+	testsuite/libffi.call/nested_struct.c,
+	testsuite/libffi.call/cls_2byte.c,
+	testsuite/libffi.call/nested_struct10.c,
+	testsuite/libffi.call/cls_4byte.c,
+	testsuite/libffi.call/cls_6byte.c,
+	testsuite/libffi.call/cls_8byte.c,
+	testsuite/libffi.call/cls_multi_sshort.c,
+	testsuite/libffi.call/cls_align_sint16.c,
+	testsuite/libffi.call/cls_align_uint32.c,
+	testsuite/libffi.call/cls_20byte.c,
+	testsuite/libffi.call/cls_float.c,
+	testsuite/libffi.call/nested_struct2.c,
+	testsuite/libffi.call/cls_5_1_byte.c,
+	testsuite/libffi.call/nested_struct4.c,
+	testsuite/libffi.call/cls_24byte.c,
+	testsuite/libffi.call/nested_struct6.c,
+	testsuite/libffi.call/cls_64byte.c,
+	testsuite/libffi.call/nested_struct8.c,
+	testsuite/libffi.call/cls_uint.c,
+	testsuite/libffi.call/cls_multi_ushortchar.c,
+	testsuite/libffi.call/cls_schar.c,
+	testsuite/libffi.call/cls_uchar.c,
+	testsuite/libffi.call/cls_align_uint64.c,
+	testsuite/libffi.call/cls_ulonglong.c,
+	testsuite/libffi.call/cls_align_longdouble.c,
+	testsuite/libffi.call/cls_1_1byte.c,
+	testsuite/libffi.call/cls_12byte.c,
+	testsuite/libffi.call/cls_3_1byte.c,
+	testsuite/libffi.call/cls_3byte1.c,
+	testsuite/libffi.call/cls_4_1byte.c,
+	testsuite/libffi.call/cls_6_1_byte.c,
+	testsuite/libffi.call/cls_16byte.c,
+	testsuite/libffi.call/cls_18byte.c,
+	testsuite/libffi.call/closure_fn0.c,
+	testsuite/libffi.call/cls_9byte2.c,
+	testsuite/libffi.call/closure_fn2.c,
+	testsuite/libffi.call/closure_fn4.c,
+	testsuite/libffi.call/cls_ushort.c,
+	testsuite/libffi.call/closure_fn6.c,
+	testsuite/libffi.call/cls_5byte.c,
+	testsuite/libffi.call/cls_align_pointer.c,
+	testsuite/libffi.call/cls_7byte.c,
+	testsuite/libffi.call/cls_align_sint32.c,
+	testsuite/libffi.special/unwindtest_ffi_call.cc,
+	testsuite/libffi.special/unwindtest.cc: Remove xfail for mips64*-*-*.
+
+2007-08-10  David Daney  <ddaney at avtrex.com>
+
+	PR libffi/28313
+	* configure.ac: Don't treat mips64 as a special case.
+	* Makefile.am (nodist_libffi_la_SOURCES): Add n32.S.
+	* configure: Regenerate
+	* Makefile.in: Ditto.
+	* fficonfig.h.in: Ditto.
+	* src/mips/ffitarget.h (REG_L, REG_S, SUBU, ADDU, SRL, LI): Indent.
+	(LA, EH_FRAME_ALIGN, FDE_ADDR_BYTES): New preprocessor macros.
+	(FFI_DEFAULT_ABI): Set for n64 case.
+	(FFI_CLOSURES, FFI_TRAMPOLINE_SIZE): Define for n32 and n64 cases.
+	* src/mips/n32.S (ffi_call_N32): Add debug macros and labels for FDE.
+	(ffi_closure_N32): New function.
+	(.eh_frame): New section
+	* src/mips/o32.S: Clean up comments.
+	(ffi_closure_O32): Pass ffi_closure parameter in $12.
+	* src/mips/ffi.c: Use FFI_MIPS_N32 instead of
+	_MIPS_SIM == _ABIN32 throughout.
+	(FFI_MIPS_STOP_HERE): New, use in place of
+	ffi_stop_here.
+	(ffi_prep_args): Use unsigned long to hold pointer values.  Rewrite
+	to support n32/n64 ABIs.
+	(calc_n32_struct_flags): Rewrite.
+	(calc_n32_return_struct_flags): Remove unused variable.  Reverse
+	position of flag bits.
+	(ffi_prep_cif_machdep): Rewrite n32 portion.
+	(ffi_call): Enable for n64.  Add special handling for small structure
+	return values.
+	(ffi_prep_closure_loc): Add n32 and n64 support.
+	(ffi_closure_mips_inner_O32): Add cast to silence warning.
+	(copy_struct_N32, ffi_closure_mips_inner_N32): New functions.
+
+2007-08-08  David Daney  <ddaney at avtrex.com>
+
+	* testsuite/libffi.call/ffitest.h (ffi_type_mylong): Remove definition.
+	* testsuite/libffi.call/cls_align_uint16.c (main): Use correct type
+	specifiers.
+	* testsuite/libffi.call/nested_struct1.c (main): Ditto.
+	* testsuite/libffi.call/cls_sint.c (main): Ditto.
+	* testsuite/libffi.call/nested_struct9.c (main): Ditto.
+	* testsuite/libffi.call/cls_20byte1.c (main): Ditto.
+	* testsuite/libffi.call/cls_9byte1.c (main): Ditto.
+	* testsuite/libffi.call/closure_fn1.c (main): Ditto.
+	* testsuite/libffi.call/closure_fn3.c (main): Ditto.
+	* testsuite/libffi.call/return_dbl2.c (main): Ditto.
+	* testsuite/libffi.call/cls_sshort.c (main): Ditto.
+	* testsuite/libffi.call/return_fl3.c (main): Ditto.
+	* testsuite/libffi.call/closure_fn5.c (main): Ditto.
+	* testsuite/libffi.call/nested_struct.c (main): Ditto.
+	* testsuite/libffi.call/nested_struct10.c (main): Ditto.
+	* testsuite/libffi.call/return_ll1.c (main): Ditto.
+	* testsuite/libffi.call/cls_8byte.c (main): Ditto.
+	* testsuite/libffi.call/cls_align_uint32.c (main): Ditto.
+	* testsuite/libffi.call/cls_align_sint16.c (main): Ditto.
+	* testsuite/libffi.call/cls_20byte.c (main): Ditto.
+	* testsuite/libffi.call/nested_struct2.c (main): Ditto.
+	* testsuite/libffi.call/cls_24byte.c (main): Ditto.
+	* testsuite/libffi.call/nested_struct6.c (main): Ditto.
+	* testsuite/libffi.call/cls_uint.c (main): Ditto.
+	* testsuite/libffi.call/cls_12byte.c (main): Ditto.
+	* testsuite/libffi.call/cls_16byte.c (main): Ditto.
+	* testsuite/libffi.call/closure_fn0.c (main): Ditto.
+	* testsuite/libffi.call/cls_9byte2.c (main): Ditto.
+	* testsuite/libffi.call/closure_fn2.c (main): Ditto.
+	* testsuite/libffi.call/return_dbl1.c (main): Ditto.
+	* testsuite/libffi.call/closure_fn4.c (main): Ditto.
+	* testsuite/libffi.call/closure_fn6.c (main): Ditto.
+	* testsuite/libffi.call/cls_align_sint32.c (main): Ditto.
+
+2007-08-07  Andrew Haley  <aph at redhat.com>
+
+	* src/x86/sysv.S (ffi_closure_raw_SYSV): Fix typo in previous
+	checkin.
+
+2007-08-06  Andrew Haley  <aph at redhat.com>
+
+	PR testsuite/32843
+	* src/x86/sysv.S (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8,
+	FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32,
+	FFI_TYPE_SINT32.
+
+2007-08-02  David Daney  <ddaney at avtrex.com>
+
+	* testsuite/libffi.call/return_ul.c (main): Define return type as
+	ffi_arg.  Use proper printf conversion specifier.
+
+2007-07-30  Andrew Haley  <aph at redhat.com>
+
+	PR testsuite/32843
+	* src/x86/ffi.c (ffi_prep_cif_machdep): in x86 case, add code for
+	signed/unsigned int8/16.
+	* src/x86/sysv.S (ffi_call_SYSV): Rewrite to:
+	Use a jump table.
+	Remove code to pop args from the stack after call.
+	Special-case signed/unsigned int8/16.
+	* testsuite/libffi.call/return_sc.c (main): Revert.
+
+2007-07-26  Richard Guenther  <rguenther at suse.de>
+
+	PR testsuite/32843
+	* testsuite/libffi.call/return_sc.c (main): Verify call
+	result as signed char, not ffi_arg.
+
+2007-07-16  Rainer Orth  <ro at TechFak.Uni-Bielefeld.DE>
+
+	* configure.ac (i?86-*-solaris2.1[0-9]): Set TARGET to X86_64.
+	* configure: Regenerate.
+
+2007-07-11  David Daney  <ddaney at avtrex.com>
+
+	* src/mips/ffi.c: Don't include sys/cachectl.h.
+	(ffi_prep_closure_loc): Use __builtin___clear_cache() instead of
+	cacheflush().
+
+2007-05-18  Aurelien Jarno  <aurelien at aurel32.net>
+
+	* src/arm/ffi.c (ffi_prep_closure_loc): Renamed and ajusted
+	from (ffi_prep_closure): ... this.
+	(FFI_INIT_TRAMPOLINE): Adjust.
+
+2005-12-31  Phil Blundell  <pb at reciva.com>
+
+	* src/arm/ffi.c (ffi_prep_incoming_args_SYSV,
+	ffi_closure_SYSV_inner, ffi_prep_closure): New, add closure support.
+	* src/arm/sysv.S(ffi_closure_SYSV): Likewise.
+	* src/arm/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise.
+	(FFI_CLOSURES): Enable closure support.
+
+2007-07-03  Andrew Haley  <aph at hedges.billgatliff.com>
+
+	* testsuite/libffi.call/cls_multi_ushort.c,
+	testsuite/libffi.call/cls_align_uint16.c,
+	testsuite/libffi.call/nested_struct1.c,
+	testsuite/libffi.call/nested_struct3.c,
+	testsuite/libffi.call/cls_7_1_byte.c,
+	testsuite/libffi.call/cls_double.c,
+	testsuite/libffi.call/nested_struct5.c,
+	testsuite/libffi.call/nested_struct7.c,
+	testsuite/libffi.call/cls_sint.c,
+	testsuite/libffi.call/nested_struct9.c,
+	testsuite/libffi.call/cls_20byte1.c,
+	testsuite/libffi.call/cls_multi_sshortchar.c,
+	testsuite/libffi.call/cls_align_sint64.c,
+	testsuite/libffi.call/cls_3byte2.c,
+	testsuite/libffi.call/cls_multi_schar.c,
+	testsuite/libffi.call/cls_multi_uchar.c,
+	testsuite/libffi.call/cls_19byte.c,
+	testsuite/libffi.call/cls_9byte1.c,
+	testsuite/libffi.call/cls_align_float.c,
+	testsuite/libffi.call/closure_fn1.c,
+	testsuite/libffi.call/problem1.c,
+	testsuite/libffi.call/closure_fn3.c,
+	testsuite/libffi.call/cls_sshort.c,
+	testsuite/libffi.call/closure_fn5.c,
+	testsuite/libffi.call/cls_align_double.c,
+	testsuite/libffi.call/cls_2byte.c,
+	testsuite/libffi.call/nested_struct.c,
+	testsuite/libffi.call/nested_struct10.c,
+	testsuite/libffi.call/cls_4byte.c,
+	testsuite/libffi.call/cls_6byte.c,
+	testsuite/libffi.call/cls_8byte.c,
+	testsuite/libffi.call/cls_multi_sshort.c,
+	testsuite/libffi.call/cls_align_uint32.c,
+	testsuite/libffi.call/cls_align_sint16.c,
+	testsuite/libffi.call/cls_float.c,
+	testsuite/libffi.call/cls_20byte.c,
+	testsuite/libffi.call/cls_5_1_byte.c,
+	testsuite/libffi.call/nested_struct2.c,
+	testsuite/libffi.call/cls_24byte.c,
+	testsuite/libffi.call/nested_struct4.c,
+	testsuite/libffi.call/nested_struct6.c,
+	testsuite/libffi.call/cls_64byte.c,
+	testsuite/libffi.call/nested_struct8.c,
+	testsuite/libffi.call/cls_uint.c,
+	testsuite/libffi.call/cls_multi_ushortchar.c,
+	testsuite/libffi.call/cls_schar.c,
+	testsuite/libffi.call/cls_uchar.c,
+	testsuite/libffi.call/cls_align_uint64.c,
+	testsuite/libffi.call/cls_ulonglong.c,
+	testsuite/libffi.call/cls_align_longdouble.c,
+	testsuite/libffi.call/cls_1_1byte.c,
+	testsuite/libffi.call/cls_12byte.c,
+	testsuite/libffi.call/cls_3_1byte.c,
+	testsuite/libffi.call/cls_3byte1.c,
+	testsuite/libffi.call/cls_4_1byte.c,
+	testsuite/libffi.call/cls_6_1_byte.c,
+	testsuite/libffi.call/cls_16byte.c,
+	testsuite/libffi.call/cls_18byte.c,
+	testsuite/libffi.call/closure_fn0.c,
+	testsuite/libffi.call/cls_9byte2.c,
+	testsuite/libffi.call/closure_fn2.c,
+	testsuite/libffi.call/closure_fn4.c,
+	testsuite/libffi.call/cls_ushort.c,
+	testsuite/libffi.call/closure_fn6.c,
+	testsuite/libffi.call/cls_5byte.c,
+	testsuite/libffi.call/cls_align_pointer.c,
+	testsuite/libffi.call/cls_7byte.c,
+	testsuite/libffi.call/cls_align_sint32.c,
+	testsuite/libffi.special/unwindtest_ffi_call.cc,
+	testsuite/libffi.special/unwindtest.cc: Enable for ARM.
+
+2007-07-05  H.J. Lu  <hongjiu.lu at intel.com>
+
+	* aclocal.m4: Regenerated.
+
+2007-06-02  Paolo Bonzini  <bonzini at gnu.org>
+
+	* configure: Regenerate.
+
+2007-05-23  Steve Ellcey  <sje at cup.hp.com>
+
+	* Makefile.in: Regenerate.
+	* configure: Regenerate.
+	* aclocal.m4: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+
+2007-05-10  Roman Zippel <zippel at linux-m68k.org>
+
+	* src/m68k/ffi.c (ffi_prep_incoming_args_SYSV,
+	ffi_closure_SYSV_inner,ffi_prep_closure): New, add closure support.
+	* src/m68k/sysv.S(ffi_closure_SYSV,ffi_closure_struct_SYSV): Likewise.
+	* src/m68k/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise.
+	(FFI_CLOSURES): Enable closure support.
+
+2007-05-10  Roman Zippel <zippel at linux-m68k.org>
+
+	* configure.ac (HAVE_AS_CFI_PSEUDO_OP): New test.
+	* configure: Regenerate.
+	* fficonfig.h.in: Regenerate.
+	* src/m68k/sysv.S (CFI_STARTPROC,CFI_ENDPROC,
+	CFI_OFFSET,CFI_DEF_CFA): New macros.
+	(ffi_call_SYSV): Add callframe annotation.
+
+2007-05-10  Roman Zippel <zippel at linux-m68k.org>
+
+	* src/m68k/ffi.c (ffi_prep_args,ffi_prep_cif_machdep): Fix
+	numerous test suite failures.
+	* src/m68k/sysv.S (ffi_call_SYSV): Likewise.
+
+2007-04-11  Paolo Bonzini  <bonzini at gnu.org>
+
+	* Makefile.am (EXTRA_DIST): Bring up to date.
+	* Makefile.in: Regenerate.
+	* src/frv/eabi.S: Remove RCS keyword.
+
+2007-04-06  Richard Henderson  <rth at redhat.com>
+
+	* configure.ac: Tidy target case.
+	(HAVE_LONG_DOUBLE): Allow the target to override.
+	* configure: Regenerate.
+	* include/ffi.h.in: Don't define ffi_type_foo if
+	LIBFFI_HIDE_BASIC_TYPES is defined.
+	(ffi_type_longdouble): If not HAVE_LONG_DOUBLE, define
+	to ffi_type_double.
+	* types.c (LIBFFI_HIDE_BASIC_TYPES): Define.
+	(FFI_TYPEDEF, ffi_type_void): Mark the data const.
+	(ffi_type_longdouble): Special case for Alpha.  Don't define
+	if long double == double.
+
+	* src/alpha/ffi.c (FFI_TYPE_LONGDOUBLE): Assert unique value.
+	(ffi_prep_cif_machdep): Handle it as the 128-bit type.
+	(ffi_call, ffi_closure_osf_inner): Likewise.
+	(ffi_closure_osf_inner): Likewise.  Mark hidden.
+	(ffi_call_osf, ffi_closure_osf): Mark hidden.
+	* src/alpha/ffitarget.h (FFI_LAST_ABI): Tidy definition.
+	* src/alpha/osf.S (ffi_call_osf, ffi_closure_osf): Mark hidden.
+	(load_table): Handle 128-bit long double.
+
+	* testsuite/libffi.call/float4.c: Add -mieee for alpha.
+
+2007-04-06  Tom Tromey  <tromey at redhat.com>
+
+	PR libffi/31491:
+	* README: Fixed bug in example.
+
+2007-04-03  Jakub Jelinek  <jakub at redhat.com>
+
+	* src/closures.c: Include sys/statfs.h.
+	(_GNU_SOURCE): Define on Linux.
+	(FFI_MMAP_EXEC_SELINUX): Define.
+	(selinux_enabled): New variable.
+	(selinux_enabled_check): New function.
+	(is_selinux_enabled): Define.
+	(dlmmap): Use it.
+
+2007-03-24  Uros Bizjak  <ubizjak at gmail.com>
+
+	* testsuite/libffi.call/return_fl2.c (return_fl): Mark as static.
+	Use 'volatile float sum' to create sum of floats to avoid false
+	negative due to excess precision on ix86 targets.
+	(main): Ditto.
+
+2007-03-08  Alexandre Oliva  <aoliva at redhat.com>
+
+	* src/powerpc/ffi.c (flush_icache): Fix left-over from previous
+	patch.
+	(ffi_prep_closure_loc): Remove unneeded casts.  Add needed ones.
+
+2007-03-07  Alexandre Oliva  <aoliva at redhat.com>
+
+	* include/ffi.h.in (ffi_closure_alloc, ffi_closure_free): New.
+	(ffi_prep_closure_loc): New.
+	(ffi_prep_raw_closure_loc): New.
+	(ffi_prep_java_raw_closure_loc): New.
+	* src/closures.c: New file.
+	* src/dlmalloc.c [FFI_MMAP_EXEC_WRIT] (struct malloc_segment):
+	Replace sflags with exec_offset.
+	[FFI_MMAP_EXEC_WRIT] (mmap_exec_offset, add_segment_exec_offset,
+	sub_segment_exec_offset): New macros.
+	(get_segment_flags, set_segment_flags, check_segment_merge): New
+	macros.
+	(is_mmapped_segment, is_extern_segment): Use get_segment_flags.
+	(add_segment, sys_alloc, create_mspace, create_mspace_with_base,
+	destroy_mspace): Use new macros.
+	(sys_alloc): Silence warning.
+	* Makefile.am (libffi_la_SOURCES): Add src/closures.c.
+	* Makefile.in: Rebuilt.
+	* src/prep_cif [FFI_CLOSURES] (ffi_prep_closure): Implement in
+	terms of ffi_prep_closure_loc.
+	* src/raw_api.c (ffi_prep_raw_closure_loc): Renamed and adjusted
+	from...
+	(ffi_prep_raw_closure): ... this.  Re-implement in terms of the
+	renamed version.
+	* src/java_raw_api (ffi_prep_java_raw_closure_loc): Renamed and
+	adjusted from...
+	(ffi_prep_java_raw_closure): ... this.  Re-implement in terms of
+	the renamed version.
+	* src/alpha/ffi.c (ffi_prep_closure_loc): Renamed from
+	(ffi_prep_closure): ... this.
+	* src/pa/ffi.c: Likewise.
+	* src/cris/ffi.c: Likewise.  Adjust.
+	* src/frv/ffi.c: Likewise.
+	* src/ia64/ffi.c: Likewise.
+	* src/mips/ffi.c: Likewise.
+	* src/powerpc/ffi_darwin.c: Likewise.
+	* src/s390/ffi.c: Likewise.
+	* src/sh/ffi.c: Likewise.
+	* src/sh64/ffi.c: Likewise.
+	* src/sparc/ffi.c: Likewise.
+	* src/x86/ffi64.c: Likewise.
+	* src/x86/ffi.c: Likewise.
+	(FFI_INIT_TRAMPOLINE): Adjust.
+	(ffi_prep_raw_closure_loc): Renamed and adjusted from...
+	(ffi_prep_raw_closure): ... this.
+	* src/powerpc/ffi.c (ffi_prep_closure_loc): Renamed from
+	(ffi_prep_closure): ... this.
+	(flush_icache): Adjust.
+
+2007-03-07  Alexandre Oliva  <aoliva at redhat.com>
+
+	* src/dlmalloc.c: New file, imported version 2.8.3 of Doug
+	Lea's malloc.
+
+2007-03-01  Brooks Moses  <brooks.moses at codesourcery.com>
+
+	* Makefile.am: Add dummy install-pdf target.
+	* Makefile.in: Regenerate
+
+2007-02-13  Andreas Krebbel  <krebbel1 at de.ibm.com>
+
+	* src/s390/ffi.c (ffi_prep_args, ffi_prep_cif_machdep,
+	ffi_closure_helper_SYSV): Add long double handling.
+
+2007-02-02  Jakub Jelinek  <jakub at redhat.com>
+
+	* src/powerpc/linux64.S (ffi_call_LINUX64): Move restore of r2
+	immediately after bctrl instruction.
+
+2007-01-18  Alexandre Oliva  <aoliva at redhat.com>
+
+	* Makefile.am (all-recursive, install-recursive,
+	mostlyclean-recursive, clean-recursive, distclean-recursive,
+	maintainer-clean-recursive): Add missing targets.
+	* Makefile.in: Rebuilt.
+
+2006-12-14  Andreas Tobler  <a.tobler at schweiz.org>
+
+	* configure.ac: Add TARGET for x86_64-*-darwin*.
+	* Makefile.am (nodist_libffi_la_SOURCES): Add rules for 64-bit sources
+	for X86_DARWIN.
+	* src/x86/ffitarget.h: Set trampoline size for x86_64-*-darwin*.
+	* src/x86/darwin64.S: New file for x86_64-*-darwin* support.
+	* configure: Regenerate.
+	* Makefile.in: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+	* testsuite/libffi.special/unwindtest_ffi_call.cc: New test case for
+	ffi_call only.
+
+2006-12-13  Andreas Tobler <a.tobler at schweiz.org>
+
+	* aclocal.m4: Regenerate with aclocal -I .. as written in the
+	Makefile.am.
+
+2006-10-31  Geoffrey Keating  <geoffk at apple.com>
+
+	* src/powerpc/ffi_darwin.c (darwin_adjust_aggregate_sizes): New.
+	(ffi_prep_cif_machdep): Call darwin_adjust_aggregate_sizes for
+	Darwin.
+	* testsuite/libffi.call/nested_struct4.c: Remove Darwin XFAIL.
+	* testsuite/libffi.call/nested_struct6.c: Remove Darwin XFAIL.
+
+2006-10-10  Paolo Bonzini  <bonzini at gnu.org>
+	    Sandro Tolaini  <tolaini at libero.it>
+
+	* configure.ac [i*86-*-darwin*]: Set X86_DARWIN symbol and
+	conditional.
+	* configure: Regenerated.
+	* Makefile.am (nodist_libffi_la_SOURCES) [X86_DARWIN]: New case.
+	(EXTRA_DIST): Add src/x86/darwin.S.
+	* Makefile.in: Regenerated.
+	* include/Makefile.in: Regenerated.
+	* testsuite/Makefile.in: Regenerated.
+
+	* src/x86/ffi.c (ffi_prep_cif_machdep) [X86_DARWIN]: Treat like
+	X86_WIN32, and additionally align stack to 16 bytes.
+	* src/x86/darwin.S: New, based on sysv.S.
+	* src/prep_cif.c (ffi_prep_cif) [X86_DARWIN]: Align > 8-byte structs.
+
+2006-09-12  David Daney  <ddaney at avtrex.com>
+
+	PR libffi/23935
+	* include/Makefile.am: Install both ffi.h and ffitarget.h in
+	$(libdir)/gcc/$(target_alias)/$(gcc_version)/include.
+	* aclocal.m4: Regenerated for automake 1.9.6.
+	* Makefile.in: Regenerated.
+	* include/Makefile.in: Regenerated.
+	* testsuite/Makefile.in: Regenerated.
+
+2006-08-17  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* include/ffi_common.h (struct): Revert accidental commit.
+
+2006-08-15  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* include/ffi_common.h: Remove lint directives.
+	* include/ffi.h.in: Likewise.
+
+2006-07-25  Torsten Schoenfeld  <kaffeetisch at gmx.de>
+
+	* include/ffi.h.in (ffi_type_ulong, ffi_type_slong): Define correctly
+	for 32-bit architectures.
+	* testsuite/libffi.call/return_ul.c: New test case.
+
+2006-07-19  David Daney  <ddaney at avtrex.com>
+
+	* testsuite/libffi.call/closure_fn6.c: Remove xfail for mips,
+	xfail remains for mips64.
+
+2006-05-23  Carlos O'Donell  <carlos at codesourcery.com>
+
+	* Makefile.am: Add install-html target. Add install-html to .PHONY
+	* Makefile.in: Regenerate.
+	* aclocal.m4: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+
+2006-05-18  John David Anglin  <dave.anglin at nrc-cnrc.gc.ca>
+
+	* pa/ffi.c (ffi_prep_args_pa32): Load floating point arguments from
+	stack slot.
+
+2006-04-22  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* README: Remove notice about 'Crazy Comments'.
+	* src/debug.c: Remove lint directives. Cleanup white spaces.
+	* src/java_raw_api.c: Likewise.
+	* src/prep_cif.c: Likewise.
+	* src/raw_api.c: Likewise.
+	* src/ffitest.c: Delete. No longer needed, all test cases migrated
+	to the testsuite.
+	* src/arm/ffi.c: Remove lint directives.
+	* src/m32r/ffi.c: Likewise.
+	* src/pa/ffi.c: Likewise.
+	* src/powerpc/ffi.c: Likewise.
+	* src/powerpc/ffi_darwin.c: Likewise.
+	* src/sh/ffi.c: Likewise.
+	* src/sh64/ffi.c: Likewise.
+	* src/x86/ffi.c: Likewise.
+	* testsuite/libffi.call/float2.c: Likewise.
+	* testsuite/libffi.call/promotion.c: Likewise.
+	* testsuite/libffi.call/struct1.c: Likewise.
+
+2006-04-13  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* src/pa/hpux32.S: Correct unwind offset calculation for
+	ffi_closure_pa32.
+	* src/pa/linux.S: Likewise.
+
+2006-04-12  James E Wilson  <wilson at specifix.com>
+
+	PR libgcj/26483
+	* src/ia64/ffi.c (stf_spill, ldf_fill): Rewrite as macros.
+	(hfa_type_load): Call stf_spill.
+	(hfa_type_store): Call ldf_fill.
+	(ffi_call): Adjust calls to above routines.  Add local temps for
+	macro result.
+
+2006-04-10  Matthias Klose  <doko at debian.org>
+
+	* testsuite/lib/libffi-dg.exp (libffi-init): Recognize multilib
+	directory names containing underscores.
+
+2006-04-07  James E Wilson  <wilson at specifix.com>
+
+	* testsuite/libffi.call/float4.c: New testcase.
+
+2006-04-05  John David Anglin  <dave.anglin at nrc-cnrc.gc.ca>
+	    Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* Makefile.am: Add PA_HPUX port.
+	* Makefile.in: Regenerate.
+	* include/Makefile.in: Likewise.
+	* testsuite/Makefile.in: Likewise.
+	* configure.ac: Add PA_HPUX rules.
+	* configure: Regenerate.
+	* src/pa/ffitarget.h: Rename linux target to PA_LINUX.
+	Add PA_HPUX and PA64_HPUX.
+	Rename FFI_LINUX ABI to FFI_PA32 ABI.
+	(FFI_TRAMPOLINE_SIZE): Define for 32-bit HP-UX targets.
+	(FFI_TYPE_SMALL_STRUCT2): Define.
+	(FFI_TYPE_SMALL_STRUCT4): Likewise.
+	(FFI_TYPE_SMALL_STRUCT8): Likewise.
+	(FFI_TYPE_SMALL_STRUCT3): Redefine.
+	(FFI_TYPE_SMALL_STRUCT5): Likewise.
+	(FFI_TYPE_SMALL_STRUCT6): Likewise.
+	(FFI_TYPE_SMALL_STRUCT7): Likewise.
+	* src/pa/ffi.c (ROUND_DOWN): Delete.
+	(fldw, fstw, fldd, fstd): Use '__asm__'.
+	(ffi_struct_type): Add support for FFI_TYPE_SMALL_STRUCT2,
+	FFI_TYPE_SMALL_STRUCT4 and FFI_TYPE_SMALL_STRUCT8.
+	(ffi_prep_args_LINUX): Rename to ffi_prep_args_pa32. Update comment.
+	Simplify incrementing of stack slot variable. Change type of local
+	'n' to unsigned int.
+	(ffi_size_stack_LINUX): Rename to ffi_size_stack_pa32. Handle long
+	double on PA_HPUX.
+	(ffi_prep_cif_machdep): Likewise.
+	(ffi_call): Likewise.
+	(ffi_closure_inner_LINUX): Rename to ffi_closure_inner_pa32. Change
+	return type to ffi_status. Simplify incrementing of stack slot
+	variable. Only copy floating point argument registers when PA_LINUX
+	is true. Reformat debug statement.
+	Add support for FFI_TYPE_SMALL_STRUCT2, FFI_TYPE_SMALL_STRUCT4 and
+	FFI_TYPE_SMALL_STRUCT8.
+	(ffi_closure_LINUX): Rename to ffi_closure_pa32. Add 'extern' to
+	declaration.
+	(ffi_prep_closure): Make linux trampoline conditional on PA_LINUX.
+	Add nops to cache flush.  Add trampoline for PA_HPUX.
+	* src/pa/hpux32.S: New file.
+	* src/pa/linux.S (ffi_call_LINUX): Rename to ffi_call_pa32. Rename
+	ffi_prep_args_LINUX to ffi_prep_args_pa32.
+	Localize labels. Add support for 2, 4 and 8-byte small structs. Handle
+	unaligned destinations in 3, 5, 6 and 7-byte small structs. Order
+	argument type checks so that common argument types appear first.
+	(ffi_closure_LINUX): Rename to ffi_closure_pa32. Rename
+	ffi_closure_inner_LINUX to ffi_closure_inner_pa32.
+
+2006-03-24  Alan Modra  <amodra at bigpond.net.au>
+
+	* src/powerpc/ffitarget.h (enum ffi_abi): Add FFI_LINUX.  Default
+	for 32-bit using IBM extended double format.  Fix FFI_LAST_ABI.
+	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Handle linux variant of
+	FFI_TYPE_LONGDOUBLE.
+	(ffi_prep_args64): Assert using IBM extended double.
+	(ffi_prep_cif_machdep): Don't munge FFI_TYPE_LONGDOUBLE type.
+	Handle FFI_LINUX FFI_TYPE_LONGDOUBLE return and args.
+	(ffi_call): Handle FFI_LINUX.
+	(ffi_closure_helper_SYSV): Non FFI_LINUX long double return needs
+	gpr3 return pointer as for struct return.  Handle FFI_LINUX
+	FFI_TYPE_LONGDOUBLE return and args.  Don't increment "nf"
+	unnecessarily.
+	* src/powerpc/ppc_closure.S (ffi_closure_SYSV): Load both f1 and f2
+	for FFI_TYPE_LONGDOUBLE.  Move epilogue insns into case table.
+	Don't use r6 as pointer to results, instead use sp offset.  Don't
+	make a special call to load lr with case table address, instead
+	use offset from previous call.
+	* src/powerpc/sysv.S (ffi_call_SYSV): Save long double return.
+	* src/powerpc/linux64.S (ffi_call_LINUX64): Simplify long double
+	return.
+
+2006-03-15  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* src/sh64/ffi.c (ffi_prep_cif_machdep): Handle float arguments
+	passed with FP registers correctly.
+	(ffi_closure_helper_SYSV): Likewise.
+	* src/sh64/sysv.S: Likewise.
+
+2006-03-01  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/libffi.special/unwindtest.cc (closure_test_fn): Mark cif,
+	args and userdata unused.
+	(closure_test_fn1): Mark cif and userdata unused.
+	(main): Remove unused res.
+
+2006-02-28  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/libffi.call/call.exp: Adjust FSF address. Add test runs for
+	-O2, -O3, -Os and the warning flags -W -Wall.
+	* testsuite/libffi.special/special.exp: Likewise.
+	* testsuite/libffi.call/ffitest.h: Add an __UNUSED__ macro to mark
+	unused parameter unused for gcc or else do nothing.
+	* testsuite/libffi.special/ffitestcxx.h: Likewise.
+	* testsuite/libffi.call/cls_12byte.c (cls_struct_12byte_gn): Mark cif
+	and userdata unused.
+	* testsuite/libffi.call/cls_16byte.c (cls_struct_16byte_gn): Likewise.
+	* testsuite/libffi.call/cls_18byte.c (cls_struct_18byte_gn): Likewise.
+	* testsuite/libffi.call/cls_19byte.c (cls_struct_19byte_gn): Likewise.
+	* testsuite/libffi.call/cls_1_1byte.c (cls_struct_1_1byte_gn): Likewise.
+	* testsuite/libffi.call/cls_20byte.c (cls_struct_20byte_gn): Likewise.
+	* testsuite/libffi.call/cls_20byte1.c (cls_struct_20byte_gn): Likewise.
+	* testsuite/libffi.call/cls_24byte.c (cls_struct_24byte_gn): Likewise.
+	* testsuite/libffi.call/cls_2byte.c (cls_struct_2byte_gn): Likewise.
+	* testsuite/libffi.call/cls_3_1byte.c (cls_struct_3_1byte_gn): Likewise.
+	* testsuite/libffi.call/cls_3byte1.c (cls_struct_3byte_gn): Likewise.
+	* testsuite/libffi.call/cls_3byte2.c (cls_struct_3byte_gn1): Likewise.
+	* testsuite/libffi.call/cls_4_1byte.c (cls_struct_4_1byte_gn): Likewise.
+	* testsuite/libffi.call/cls_4byte.c (cls_struct_4byte_gn): Likewise.
+	* testsuite/libffi.call/cls_5_1_byte.c (cls_struct_5byte_gn): Likewise.
+	* testsuite/libffi.call/cls_5byte.c (cls_struct_5byte_gn): Likewise.
+	* testsuite/libffi.call/cls_64byte.c (cls_struct_64byte_gn): Likewise.
+	* testsuite/libffi.call/cls_6_1_byte.c (cls_struct_6byte_gn): Likewise.
+	* testsuite/libffi.call/cls_6byte.c (cls_struct_6byte_gn): Likewise.
+	* testsuite/libffi.call/cls_7_1_byte.c (cls_struct_7byte_gn): Likewise.
+	* testsuite/libffi.call/cls_7byte.c (cls_struct_7byte_gn): Likewise.
+	* testsuite/libffi.call/cls_8byte.c (cls_struct_8byte_gn): Likewise.
+	* testsuite/libffi.call/cls_9byte1.c (cls_struct_9byte_gn): Likewise.
+	* testsuite/libffi.call/cls_9byte2.c (cls_struct_9byte_gn): Likewise.
+	* testsuite/libffi.call/cls_align_double.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_align_float.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_align_longdouble.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_align_pointer.c (cls_struct_align_fn): Cast
+	void* to avoid compiler warning.
+	(main): Likewise.
+	(cls_struct_align_gn): Mark cif and userdata unused.
+	* testsuite/libffi.call/cls_align_sint16.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_align_sint32.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_align_sint64.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_align_uint16.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_align_uint32.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_double.c (cls_ret_double_fn): Likewise.
+	* testsuite/libffi.call/cls_float.c (cls_ret_float_fn): Likewise.
+	* testsuite/libffi.call/cls_multi_schar.c (test_func_gn): Mark cif and
+	data unused.
+	(main): Cast res_call to silence gcc.
+	* testsuite/libffi.call/cls_multi_sshort.c (test_func_gn): Mark cif and
+	data unused.
+	(main): Cast res_call to silence gcc.
+	* testsuite/libffi.call/cls_multi_sshortchar.c (test_func_gn): Mark cif
+	and data unused.
+	(main): Cast res_call to silence gcc.
+	* testsuite/libffi.call/cls_multi_uchar.c (test_func_gn): Mark cif and
+	data unused.
+	(main): Cast res_call to silence gcc.
+	* testsuite/libffi.call/cls_multi_ushort.c (test_func_gn): Mark cif and
+	data unused.
+	(main): Cast res_call to silence gcc.
+	* testsuite/libffi.call/cls_multi_ushortchar.c (test_func_gn): Mark cif
+	and data unused.
+	(main): Cast res_call to silence gcc.
+	* testsuite/libffi.call/cls_schar.c (cls_ret_schar_fn): Mark cif and
+	userdata unused.
+	(cls_ret_schar_fn): Cast printf parameter to silence gcc.
+	* testsuite/libffi.call/cls_sint.c (cls_ret_sint_fn): Mark cif and
+	userdata unused.
+	(cls_ret_sint_fn): Cast printf parameter to silence gcc.
+	* testsuite/libffi.call/cls_sshort.c (cls_ret_sshort_fn): Mark cif and
+	userdata unused.
+	(cls_ret_sshort_fn): Cast printf parameter to silence gcc.
+	* testsuite/libffi.call/cls_uchar.c (cls_ret_uchar_fn):  Mark cif and
+	userdata unused.
+	(cls_ret_uchar_fn): Cast printf parameter to silence gcc.
+	* testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Mark cif and
+	userdata unused.
+	(cls_ret_uint_fn): Cast printf parameter to silence gcc.
+	* testsuite/libffi.call/cls_ulonglong.c (cls_ret_ulonglong_fn): Mark cif
+	and userdata unused.
+	* testsuite/libffi.call/cls_ushort.c (cls_ret_ushort_fn): Mark cif and
+	userdata unused.
+	(cls_ret_ushort_fn): Cast printf parameter to silence gcc.
+	* testsuite/libffi.call/float.c (floating): Remove unused parameter e.
+	* testsuite/libffi.call/float1.c (main): Remove unused variable i.
+	Cleanup white spaces.
+	* testsuite/libffi.call/negint.c (checking): Remove unused variable i.
+	* testsuite/libffi.call/nested_struct.c (cls_struct_combined_gn): Mark
+	cif and userdata unused.
+	* testsuite/libffi.call/nested_struct1.c (cls_struct_combined_gn):
+	Likewise.
+	* testsuite/libffi.call/nested_struct10.c (B_gn): Likewise.
+	* testsuite/libffi.call/nested_struct2.c (B_fn): Adjust printf
+	formatters to silence gcc.
+	(B_gn): Mark cif and userdata unused.
+	* testsuite/libffi.call/nested_struct3.c (B_gn): Mark cif and userdata
+	unused.
+	* testsuite/libffi.call/nested_struct4.c: Mention related PR.
+	(B_gn): Mark cif and userdata unused.
+	* testsuite/libffi.call/nested_struct5.c (B_gn): Mark cif and userdata
+	unused.
+	* testsuite/libffi.call/nested_struct6.c: Mention related PR.
+	(B_gn): Mark cif and userdata unused.
+	* testsuite/libffi.call/nested_struct7.c (B_gn): Mark cif and userdata
+	unused.
+	* testsuite/libffi.call/nested_struct8.c (B_gn): Likewise.
+	* testsuite/libffi.call/nested_struct9.c (B_gn): Likewise.
+	* testsuite/libffi.call/problem1.c (stub): Likewise.
+	* testsuite/libffi.call/pyobjc-tc.c (main): Cast the result to silence
+	gcc.
+	* testsuite/libffi.call/return_fl2.c (return_fl): Add the note mentioned
+	in the last commit for this test case in the test case itself.
+	* testsuite/libffi.call/closure_fn0.c (closure_test_fn0): Mark cif as
+	unused.
+	* testsuite/libffi.call/closure_fn1.c (closure_test_fn1): Likewise.
+	* testsuite/libffi.call/closure_fn2.c (closure_test_fn2): Likewise.
+	* testsuite/libffi.call/closure_fn3.c (closure_test_fn3): Likewise.
+	* testsuite/libffi.call/closure_fn4.c (closure_test_fn0): Likewise.
+	* testsuite/libffi.call/closure_fn5.c (closure_test_fn5): Likewise.
+	* testsuite/libffi.call/closure_fn6.c (closure_test_fn0): Likewise.
+
+2006-02-22  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* src/sh/sysv.S: Fix register numbers in the FDE for
+	ffi_closure_SYSV.
+
+2006-02-20  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/libffi.call/return_fl2.c (return_fl): Remove static
+	declaration to avoid a false negative on ix86. See PR323.
+
+2006-02-18  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* src/sh/ffi.c (ffi_closure_helper_SYSV): Remove unused variable
+	and cast integer to void * if needed.  Update the pointer to
+	the FP register saved area correctly.
+
+2006-02-17  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/libffi.call/nested_struct6.c: XFAIL this test until PR25630
+	is fixed.
+	* testsuite/libffi.call/nested_struct4.c: Likewise.
+
+2006-02-16  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/libffi.call/return_dbl.c: New test case.
+	* testsuite/libffi.call/return_dbl1.c: Likewise.
+	* testsuite/libffi.call/return_dbl2.c: Likewise.
+	* testsuite/libffi.call/return_fl.c: Likewise.
+	* testsuite/libffi.call/return_fl1.c: Likewise.
+	* testsuite/libffi.call/return_fl2.c: Likewise.
+	* testsuite/libffi.call/return_fl3.c: Likewise.
+	* testsuite/libffi.call/closure_fn6.c: Likewise.
+
+	* testsuite/libffi.call/nested_struct2.c: Remove ffi_type_mylong
+	definition.
+	* testsuite/libffi.call/ffitest.h: Add ffi_type_mylong definition
+	here to be used by other test cases too.
+
+	* testsuite/libffi.call/nested_struct10.c: New test case.
+	* testsuite/libffi.call/nested_struct9.c: Likewise.
+	* testsuite/libffi.call/nested_struct8.c: Likewise.
+	* testsuite/libffi.call/nested_struct7.c: Likewise.
+	* testsuite/libffi.call/nested_struct6.c: Likewise.
+	* testsuite/libffi.call/nested_struct5.c: Likewise.
+	* testsuite/libffi.call/nested_struct4.c: Likewise.
+
+2006-01-21  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* configure.ac: Enable libffi for sparc64-*-freebsd*.
+	* configure: Rebuilt.
+
+2006-01-18  Jakub Jelinek  <jakub at redhat.com>
+
+	* src/powerpc/sysv.S (smst_two_register): Don't call __ashldi3,
+	instead do the shifting inline.
+	* src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't compute %r5
+	shift count unconditionally.  Simplify load sequences for 1, 2, 3, 4
+	and 8 byte structs, for the remaining struct sizes don't call
+	__lshrdi3, instead do the shifting inline.
+
+2005-12-07  Thiemo Seufer  <ths at networkno.de>
+
+	* src/mips/ffitarget.h: Remove obsolete sgidefs.h include. Add
+	missing parentheses.
+	* src/mips/o32.S (ffi_call_O32): Code formatting. Define
+	and use A3_OFF, FP_OFF, RA_OFF. Micro-optimizations.
+	(ffi_closure_O32): Likewise, but with newly defined A3_OFF2,
+	A2_OFF2, A1_OFF2, A0_OFF2, RA_OFF2, FP_OFF2, S0_OFF2, GP_OFF2,
+	V1_OFF2, V0_OFF2, FA_1_1_OFF2, FA_1_0_OFF2, FA_0_1_OFF2,
+	FA_0_0_OFF2.
+	* src/mips/ffi.c (ffi_prep_args): Code formatting. Fix
+	endianness bugs.
+	(ffi_prep_closure): Improve trampoline instruction scheduling.
+	(ffi_closure_mips_inner_O32): Fix endianness bugs.
+
+2005-12-03  Alan Modra  <amodra at bigpond.net.au>
+
+	* src/powerpc/ffi.c: Formatting.
+	(ffi_prep_args_SYSV): Avoid possible aliasing problems by using unions.
+	(ffi_prep_args64): Likewise.
+
+2005-09-30  Geoffrey Keating  <geoffk at apple.com>
+
+	* testsuite/lib/libffi-dg.exp (libffi_target_compile): For
+	darwin, use -shared-libgcc not -lgcc_s, and explain why.
+
+2005-09-26  Tom Tromey  <tromey at redhat.com>
+
+	* testsuite/libffi.call/float1.c (value_type): New typedef.
+	(CANARY): New define.
+	(main): Check for result buffer overflow.
+	* src/powerpc/linux64.S: Handle linux64 long double returns.
+	* src/powerpc/ffi.c (FLAG_RETURNS_128BITS): New constant.
+	(ffi_prep_cif_machdep): Handle linux64 long double returns.
+
+2005-08-25  Alan Modra  <amodra at bigpond.net.au>
+
+	PR target/23404
+	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Correct placement of stack
+	homed fp args.
+	(ffi_status ffi_prep_cif_machdep): Correct stack sizing for same.
+
+2005-08-11  Jakub Jelinek  <jakub at redhat.com>
+
+	* configure.ac (HAVE_HIDDEN_VISIBILITY_ATTRIBUTE): New test.
+	(AH_BOTTOM): Add FFI_HIDDEN definition.
+	* configure: Rebuilt.
+	* fficonfig.h.in: Rebuilt.
+	* src/powerpc/ffi.c (hidden): Remove.
+	(ffi_closure_LINUX64, ffi_prep_args64, ffi_call_LINUX64,
+	ffi_closure_helper_LINUX64): Use FFI_HIDDEN instead of hidden.
+	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64,
+	.ffi_closure_LINUX64): Use FFI_HIDDEN instead of .hidden.
+	* src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): Remove,
+	add FFI_HIDDEN to its prototype.
+	(ffi_closure_SYSV_inner): New.
+	* src/x86/sysv.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New.
+	* src/x86/win32.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New.
+
+2005-08-10  Alfred M. Szmidt  <ams at gnu.org>
+
+	PR libffi/21819:
+	* configure: Rebuilt.
+	* configure.ac: Handle i*86-*-gnu*.
+
+2005-08-09  Jakub Jelinek  <jakub at redhat.com>
+
+	* src/powerpc/ppc_closure.S (ffi_closure_SYSV): Use
+	DW_CFA_offset_extended_sf rather than
+	DW_CFA_GNU_negative_offset_extended.
+	* src/powerpc/sysv.S (ffi_call_SYSV): Likewise.
+
+2005-07-22  SUGIOKA Toshinobu  <sugioka at itonet.co.jp>
+
+	* src/sh/sysv.S (ffi_call_SYSV): Stop argument popping correctly
+	on sh3.
+	(ffi_closure_SYSV): Change the stack layout for sh3 struct argument.
+	* src/sh/ffi.c (ffi_prep_args): Fix sh3 argument copy, when it is
+	partially on register.
+	(ffi_closure_helper_SYSV): Likewise.
+	(ffi_prep_cif_machdep): Don't set too many cif->flags.
+
+2005-07-20  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* src/sh/ffi.c (ffi_call): Handle small structures correctly.
+	Remove empty line.
+	* src/sh64/ffi.c (simple_type): Remove.
+	(return_type): Handle small structures correctly.
+	(ffi_prep_args): Likewise.
+	(ffi_call): Likewise.
+	(ffi_closure_helper_SYSV): Likewise.
+	* src/sh64/sysv.S (ffi_call_SYSV): Handle 1, 2 and 4-byte return.
+	Emit position independent code if PIC and remove wrong datalabel
+	prefixes from EH data.
+
+2005-07-19  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* Makefile.am (nodist_libffi_la_SOURCES): Add POWERPC_FREEBSD.
+	* Makefile.in: Regenerate.
+	* include/Makefile.in: Likewise.
+	* testsuite/Makefile.in: Likewise.
+	* configure.ac: Add POWERPC_FREEBSD rules.
+	* configure: Regenerate.
+	* src/powerpc/ffitarget.h: Add POWERPC_FREEBSD rules.
+	(FFI_SYSV_TYPE_SMALL_STRUCT): Define.
+	* src/powerpc/ffi.c: Add flags to handle small structure returns
+	in ffi_call_SYSV.
+	(ffi_prep_cif_machdep): Handle small structures for SYSV 4 ABI.
+	Aka FFI_SYSV.
+	(ffi_closure_helper_SYSV): Likewise.
+	* src/powerpc/ppc_closure.S: Add return types for small structures.
+	* src/powerpc/sysv.S: Add bits to handle small structures for
+	final SYSV 4 ABI.
+
+2005-07-10  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/libffi.call/cls_5_1_byte.c: New test file.
+	* testsuite/libffi.call/cls_6_1_byte.c: Likewise.
+	* testsuite/libffi.call/cls_7_1_byte.c: Likewise.
+
+2005-07-05  Randolph Chung  <tausq at debian.org>
+
+	* src/pa/ffi.c (ffi_struct_type): Rename FFI_TYPE_SMALL_STRUCT1
+	as FFI_TYPE_SMALL_STRUCT3.  Break out handling for 5-7 byte
+	structures.  Kill compilation warnings.
+	(ffi_closure_inner_LINUX): Print return values as hex in debug
+	message.  Rename FFI_TYPE_SMALL_STRUCT1 as FFI_TYPE_SMALL_STRUCT3.
+	Properly handle 5-7 byte structure returns.
+	* src/pa/ffitarget.h (FFI_TYPE_SMALL_STRUCT1)
+	(FFI_TYPE_SMALL_STRUCT2): Remove.
+	(FFI_TYPE_SMALL_STRUCT3, FFI_TYPE_SMALL_STRUCT5)
+	(FFI_TYPE_SMALL_STRUCT6, FFI_TYPE_SMALL_STRUCT7): Define.
+	* src/pa/linux.S: Mark source file as using PA1.1 assembly.
+	(checksmst1, checksmst2): Remove.
+	(checksmst3): Optimize handling of 3-byte struct returns.
+	(checksmst567): Properly handle 5-7 byte struct returns.
+
+2005-06-15  Rainer Orth  <ro at TechFak.Uni-Bielefeld.DE>
+
+	PR libgcj/21943
+	* src/mips/n32.S: Enforce PIC code.
+	* src/mips/o32.S: Likewise.
+
+2005-06-15  Rainer Orth  <ro at TechFak.Uni-Bielefeld.DE>
+
+	* configure.ac: Treat i*86-*-solaris2.10 and up as X86_64.
+	* configure: Regenerate.
+
+2005-06-01  Alan Modra  <amodra at bigpond.net.au>
+
+	* src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't use JUMPTARGET
+	to call ffi_closure_helper_SYSV.  Append @local instead.
+	* src/powerpc/sysv.S (ffi_call_SYSV): Likewise for ffi_prep_args_SYSV.
+
+2005-05-17  Kelley Cook  <kcook at gcc.gnu.org>
+
+	* configure.ac: Use AC_C_BIGENDIAN instead of AC_C_BIGENDIAN_CROSS.
+	Use AC_CHECK_SIZEOF instead of AC_COMPILE_CHECK_SIZEOF.
+	* Makefile.am (ACLOCAL_AMFLAGS): Remove -I ../config.
+	* aclocal.m4, configure, fficonfig.h.in, Makefile.in,
+	include/Makefile.in, testsuite/Makefile.in: Regenerate.
+
+2005-05-09  Mike Stump  <mrs at apple.com>
+
+	* configure: Regenerate.
+
+2005-05-08  Richard Henderson  <rth at redhat.com>
+
+	PR libffi/21285
+	* src/alpha/osf.S: Update unwind into to match code.
+
+2005-05-04  Andreas Degert <ad at papyrus-gmbh.de>
+	    Richard Henderson  <rth at redhat.com>
+
+	* src/x86/ffi64.c (ffi_prep_cif_machdep): Save sse-used flag in
+	bit 11 of flags.
+	(ffi_call): Mask return type field.  Pass ssecount to ffi_call_unix64.
+	(ffi_prep_closure): Set carry bit if sse-used flag set.
+	* src/x86/unix64.S (ffi_call_unix64): Add ssecount argument.
+	Only load sse registers if ssecount non-zero.
+	(ffi_closure_unix64): Only save sse registers if carry set on entry.
+
+2005-04-29  Ralf Corsepius  <ralf.corsepius at rtems.org>
+
+	* configure.ac: Add i*86-*-rtems*, sparc*-*-rtems*,
+	powerpc-*rtems*, arm*-*-rtems*, sh-*-rtems*.
+	* configure: Regenerate.
+
+2005-04-20  Hans-Peter Nilsson  <hp at axis.com>
+
+	* testsuite/lib/libffi-dg.exp (libffi-dg-test-1): In regsub use,
+	have Tcl8.3-compatible intermediate variable.
+
+2005-04-18  Simon Posnjak <simon.posnjak at siol.net>
+	    Hans-Peter Nilsson  <hp at axis.com>
+
+	* Makefile.am: Add CRIS support.
+	* configure.ac: Likewise.
+	* Makefile.in, configure, testsuite/Makefile.in,
+	include/Makefile.in: Regenerate.
+	* src/cris: New directory.
+	* src/cris/ffi.c, src/cris/sysv.S, src/cris/ffitarget.h: New files.
+	* src/prep_cif.c (ffi_prep_cif): Wrap in #ifndef __CRIS__.
+
+	* testsuite/lib/libffi-dg.exp (libffi-dg-test-1): Replace \n with
+	\r?\n in output tests.
+
+2005-04-12  Mike Stump  <mrs at apple.com>
+
+	* configure: Regenerate.
+
+2005-03-30  Hans Boehm  <Hans.Boehm at hp.com>
+
+	* src/ia64/ffitarget.h (ffi_arg): Use long long instead of DI.
+
+2005-03-30  Steve Ellcey  <sje at cup.hp.com>
+
+	* src/ia64/ffitarget.h (ffi_arg) ADD DI attribute.
+	(ffi_sarg) Ditto.
+	* src/ia64/unix.S (ffi_closure_unix): Extend gp
+	to 64 bits in ILP32 mode.
+	Load 64 bits even for short data.
+
+2005-03-23  Mike Stump  <mrs at apple.com>
+
+	* src/powerpc/darwin.S: Update for -m64 multilib.
+	* src/powerpc/darwin_closure.S: Likewise.
+
+2005-03-21  Zack Weinberg  <zack at codesourcery.com>
+
+	* configure.ac: Do not invoke TL_AC_GCC_VERSION.
+	Do not set tool_include_dir.
+	* aclocal.m4, configure, Makefile.in, testsuite/Makefile.in:
+	Regenerate.
+	* include/Makefile.am: Set gcc_version and toollibffidir.
+	* include/Makefile.in: Regenerate.
+
+2005-02-22  Andrew Haley  <aph at redhat.com>
+
+	* src/powerpc/ffi.c (ffi_prep_cif_machdep): Bump alignment to
+	odd-numbered register pairs for 64-bit integer types.
+
+2005-02-23  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	PR libffi/20104
+	* testsuite/libffi.call/return_ll1.c: New test case.
+
+2005-02-11  Janis Johnson  <janis187 at us.ibm.com>
+
+	* testsuite/libffi.call/cls_align_longdouble.c: Remove dg-options.
+	* testsuite/libffi.call/float.c: Ditto.
+	* testsuite/libffi.call/float2.c: Ditto.
+	* testsuite/libffi.call/float3.c: Ditto.
+
+2005-02-08  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* src/frv/ffitarget.h: Remove PPC stuff which does not belong to frv.
+
+2005-01-12  Eric Botcazou  <ebotcazou at libertysurf.fr>
+
+	* testsuite/libffi.special/special.exp (cxx_options): Add
+	-shared-libgcc.
+
+2004-12-31  Richard Henderson  <rth at redhat.com>
+
+	* src/types.c (FFI_AGGREGATE_TYPEDEF): Remove.
+	(FFI_TYPEDEF): Rename from FFI_INTEGRAL_TYPEDEF.  Replace size and
+	offset parameters with a type parameter; deduce size and structure
+	alignment.  Update all users.
+
+2004-12-31  Richard Henderson  <rth at redhat.com>
+
+	* src/types.c (FFI_TYPE_POINTER): Define with sizeof.
+	(FFI_TYPE_LONGDOUBLE): Fix for ia64.
+	* src/ia64/ffitarget.h (struct ffi_ia64_trampoline_struct): Move
+	into ffi_prep_closure.
+	* src/ia64/ia64_flags.h, src/ia64/ffi.c, src/ia64/unix.S: Rewrite
+	from scratch.
+
+2004-12-27  Richard Henderson  <rth at redhat.com>
+
+	* src/x86/unix64.S: Fix typo in unwind info.
+
+2004-12-25  Richard Henderson  <rth at redhat.com>
+
+	* src/x86/ffi64.c (struct register_args): Rename from stackLayout.
+	(enum x86_64_reg_class): Add X86_64_COMPLEX_X87_CLASS.
+	(merge_classes): Check for it.
+	(SSE_CLASS_P): New.
+	(classify_argument): Pass byte_offset by value; perform all updates
+	inside struct case.
+	(examine_argument): Add classes argument; handle
+	X86_64_COMPLEX_X87_CLASS.
+	(ffi_prep_args): Merge into ...
+	(ffi_call): ... here.  Share stack frame with ffi_call_unix64.
+	(ffi_prep_cif_machdep): Setup cif->flags for proper structure return.
+	(ffi_fill_return_value): Remove.
+	(ffi_prep_closure): Remove dead assert.
+	(ffi_closure_unix64_inner): Rename from ffi_closure_UNIX64_inner.
+	Rewrite to use struct register_args instead of va_list.  Create
+	flags for handling structure returns.
+	* src/x86/unix64.S: Remove dead strings.
+	(ffi_call_unix64): Rename from ffi_call_UNIX64.  Rewrite to share
+	stack frame with ffi_call.  Handle structure returns properly.
+	(float2sse, floatfloat2sse, double2sse): Remove.
+	(sse2float, sse2double, sse2floatfloat): Remove.
+	(ffi_closure_unix64): Rename from ffi_closure_UNIX64.  Rewrite
+	to handle structure returns properly.
+
+2004-12-08  David Edelsohn  <edelsohn at gnu.org>
+
+	* Makefile.am (AM_MAKEFLAGS): Remove duplicate LIBCFLAGS and
+	PICFLAG.
+	* Makefile.in: Regenerated.
+
+2004-12-02  Richard Sandiford  <rsandifo at redhat.com>
+
+	* configure.ac: Use TL_AC_GCC_VERSION to set gcc_version.
+	* configure, aclocal.m4, Makefile.in: Regenerate.
+	* include/Makefile.in, testsuite/Makefile.in: Regenerate.
+
+2004-11-29  Kelley Cook  <kcook at gcc.gnu.org>
+
+	* configure: Regenerate for libtool change.
+
+2004-11-25  Kelley Cook  <kcook at gcc.gnu.org>
+
+	* configure: Regenerate for libtool reversion.
+
+2004-11-24  Kelley Cook  <kcook at gcc.gnu.org>
+
+	* configure: Regenerate for libtool change.
+
+2004-11-23  John David Anglin  <dave.anglin at nrc-cnrc.gc.ca>
+
+	* testsuite/lib/libffi-dg.exp: Use new procs in target-libpath.exp.
+
+2004-11-23  Richard Sandiford  <rsandifo at redhat.com>
+
+	* src/mips/o32.S (ffi_call_O32, ffi_closure_O32): Use jalr instead
+	of jal.  Use an absolute encoding for the frame information.
+
+2004-11-23  Kelley Cook  <kcook at gcc.gnu.org>
+
+	* Makefile.am: Remove no-dependencies.  Add ACLOCAL_AMFLAGS.
+	* acinclude.m4: Delete logic for sincludes.
+	* aclocal.m4, Makefile.in, configure: Regenerate.
+	* include/Makefile: Likewise.
+	* testsuite/Makefile: Likewise.
+
+2004-11-22  Eric Botcazou  <ebotcazou at libertysurf.fr>
+
+	* src/sparc/ffi.c (ffi_prep_closure): Align doubles and 64-bit integers
+	on a 8-byte boundary.
+	* src/sparc/v8.S (ffi_closure_v8): Reserve frame space for arguments.
+
+2004-10-27  Richard Earnshaw  <rearnsha at arm.com>
+
+	* src/arm/ffi.c (ffi_prep_cif_machdep): Handle functions that return
+	long long values.  Round stack allocation to a multiple of 8 bytes
+	for ATPCS compatibility.
+	* src/arm/sysv.S (ffi_call_SYSV): Rework to avoid use of APCS register
+	names.  Handle returning long long types.  Add Thumb and interworking
+	support.  Improve soft-float code.
+
+2004-10-27  Richard Earnshaw  <rearnsha at arm.com>
+
+	* testsuite/lib/libffi-db.exp (load_gcc_lib): New function.
+	(libffi_exit): New function.
+	(libffi_init): Build the testglue wrapper if needed.
+
+2004-10-25  Eric Botcazou  <ebotcazou at libertysurf.fr>
+
+	PR other/18138
+	* testsuite/lib/libffi-dg.exp: Accept more than one multilib libgcc.
+
+2004-10-25  Kazuhiro Inaoka <inaoka.kazuhiro at renesas.com>
+
+	* src/m32r/libffitarget.h (FFI_CLOSURES): Set to 0.
+
+2004-10-20  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* src/sh/sysv.S (ffi_call_SYSV): Don't align for double data.
+	* testsuite/libffi.call/float3.c: New test case.
+
+2004-10-18  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* src/sh/ffi.c (ffi_prep_closure): Set T bit in trampoline for
+	the function returning a structure pointed with R2.
+	* src/sh/sysv.S (ffi_closure_SYSV): Use R2 as the pointer to
+	the structure return value if T bit set.  Emit position
+	independent code and EH data if PIC.
+
+2004-10-13  Kazuhiro Inaoka  <inaoka.kazuhiro at renesas.com>
+
+	* Makefile.am: Add m32r support.
+	* configure.ac: Likewise.
+	* Makefile.in: Regenerate.
+	* confiugre: Regenerate.
+	* src/types.c: Add m32r port to FFI_INTERNAL_TYPEDEF
+	(uint64, sint64, double, longdouble)
+	* src/m32r: New directory.
+	* src/m32r/ffi.c: New file.
+	* src/m32r/sysv.S: Likewise.
+	* src/m32r/ffitarget.h: Likewise.
+
+2004-10-02  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* testsuite/libffi.call/negint.c: New test case.
+
+2004-09-14  H.J. Lu  <hongjiu.lu at intel.com>
+
+	PR libgcj/17465
+	* testsuite/lib/libffi-dg.exp: Don't use global ld_library_path.
+	Set up LD_LIBRARY_PATH, SHLIB_PATH, LD_LIBRARYN32_PATH,
+	LD_LIBRARY64_PATH, LD_LIBRARY_PATH_32, LD_LIBRARY_PATH_64 and
+	DYLD_LIBRARY_PATH.
+
+2004-09-05  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/libffi.call/many_win32.c: Remove whitespaces.
+	* testsuite/libffi.call/promotion.c: Likewise.
+	* testsuite/libffi.call/return_ll.c: Remove unused var. Cleanup
+	whitespaces.
+	* testsuite/libffi.call/return_sc.c: Likewise.
+	* testsuite/libffi.call/return_uc.c: Likewise.
+
+2004-09-05  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* src/powerpc/darwin.S: Fix comments and identation.
+	* src/powerpc/darwin_closure.S: Likewise.
+
+2004-09-02  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* src/powerpc/ffi_darwin.c: Add flag for longdouble return values.
+	(ffi_prep_args): Handle longdouble arguments.
+	(ffi_prep_cif_machdep): Set flags for longdouble. Calculate space for
+	longdouble.
+	(ffi_closure_helper_DARWIN): Add closure handling for longdouble.
+	* src/powerpc/darwin.S (_ffi_call_DARWIN): Add handling of longdouble
+	values.
+	* src/powerpc/darwin_closure.S (_ffi_closure_ASM): Likewise.
+	* src/types.c: Defined longdouble size and alignment for darwin.
+
+2004-09-02  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* src/powerpc/aix.S: Remove whitespaces.
+	* src/powerpc/aix_closure.S: Likewise.
+	* src/powerpc/asm.h: Likewise.
+	* src/powerpc/ffi.c: Likewise.
+	* src/powerpc/ffitarget.h: Likewise.
+	* src/powerpc/linux64.S: Likewise.
+	* src/powerpc/linux64_closure.S: Likewise.
+	* src/powerpc/ppc_closure.S: Likewise.
+	* src/powerpc/sysv.S: Likewise.
+
+2004-08-30  Anthony Green  <green at redhat.com>
+
+	* Makefile.am: Add frv support.
+	* Makefile.in, testsuite/Makefile.in: Rebuilt.
+	* configure.ac: Read configure.host.
+	* configure.in: Read configure.host.
+	* configure.host: New file.  frv-elf needs libgloss.
+	* include/ffi.h.in: Force ffi_closure to have a nice big (8)
+	alignment.  This is needed to frv and shouldn't harm the others.
+	* include/ffi_common.h (ALIGN_DOWN): New macro.
+	* src/frv/ffi.c, src/frv/ffitarget.h, src/frv/eabi.S: New files.
+
+2004-08-24  David Daney  <daney at avtrex.com>
+
+	* testsuite/libffi.call/closure_fn0.c: Xfail mips64* instead of mips*.
+	* testsuite/libffi.call/closure_fn1.c: Likewise.
+	* testsuite/libffi.call/closure_fn2.c  Likewise.
+	* testsuite/libffi.call/closure_fn3.c: Likewise.
+	* testsuite/libffi.call/closure_fn4.c: Likewise.
+	* testsuite/libffi.call/closure_fn5.c: Likewise.
+	* testsuite/libffi.call/cls_18byte.c: Likewise.
+	* testsuite/libffi.call/cls_19byte.c: Likewise.
+	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte1.c: Likewise.
+	* testsuite/libffi.call/cls_24byte.c: Likewise.
+	* testsuite/libffi.call/cls_2byte.c: Likewise.
+	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_3byte1.c: Likewise.
+	* testsuite/libffi.call/cls_3byte2.c: Likewise.
+	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_4byte.c: Likewise.
+	* testsuite/libffi.call/cls_64byte.c: Likewise.
+	* testsuite/libffi.call/cls_6byte.c: Likewise.
+	* testsuite/libffi.call/cls_7byte.c: Likewise.
+	* testsuite/libffi.call/cls_8byte.c: Likewise.
+	* testsuite/libffi.call/cls_9byte1.c: Likewise.
+	* testsuite/libffi.call/cls_9byte2.c: Likewise.
+	* testsuite/libffi.call/cls_align_double.c: Likewise.
+	* testsuite/libffi.call/cls_align_float.c: Likewise.
+	* testsuite/libffi.call/cls_align_longdouble.c: Likewise.
+	* testsuite/libffi.call/cls_align_pointer.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint16.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint32.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint64.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint16.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint32.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint64.c: Likewise.
+	* testsuite/libffi.call/cls_double.c: Likewise.
+	* testsuite/libffi.call/cls_float.c: Likewise.
+	* testsuite/libffi.call/cls_multi_schar.c: Likewise.
+	* testsuite/libffi.call/cls_multi_sshort.c: Likewise.
+	* testsuite/libffi.call/cls_multi_sshortchar.c: Likewise.
+	* testsuite/libffi.call/cls_multi_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_multi_ushort.c: Likewise.
+	* testsuite/libffi.call/cls_multi_ushortchar.c: Likewise.
+	* testsuite/libffi.call/cls_schar.c: Likewise.
+	* testsuite/libffi.call/cls_sint.c: Likewise.
+	* testsuite/libffi.call/cls_sshort.c: Likewise.
+	* testsuite/libffi.call/cls_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_uint.c: Likewise.
+	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
+	* testsuite/libffi.call/cls_ushort.c: Likewise.
+	* testsuite/libffi.call/nested_struct.c: Likewise.
+	* testsuite/libffi.call/nested_struct1.c: Likewise.
+	* testsuite/libffi.call/nested_struct2.c: Likewise.
+	* testsuite/libffi.call/nested_struct3.c: Likewise.
+	* testsuite/libffi.call/problem1.c: Likewise.
+	* testsuite/libffi.special/unwindtest.cc: Likewise.
+	* testsuite/libffi.call/cls_12byte.c: Likewise and set return value
+	to zero.
+	* testsuite/libffi.call/cls_16byte.c: Likewise.
+	* testsuite/libffi.call/cls_5byte.c: Likewise.
+
+2004-08-23  David Daney <daney at avtrex.com>
+
+	PR libgcj/13141
+	* src/mips/ffitarget.h (FFI_O32_SOFT_FLOAT): New ABI.
+	* src/mips/ffi.c (ffi_prep_args): Fix alignment calculation.
+	(ffi_prep_cif_machdep): Handle FFI_O32_SOFT_FLOAT floating point
+	parameters and return types.
+	(ffi_call): Handle FFI_O32_SOFT_FLOAT ABI.
+	(ffi_prep_closure): Ditto.
+	(ffi_closure_mips_inner_O32): Handle FFI_O32_SOFT_FLOAT ABI, fix
+	alignment calculations.
+	* src/mips/o32.S (ffi_closure_O32): Don't use floating point
+	instructions if FFI_O32_SOFT_FLOAT, make stack frame ABI compliant.
+
+2004-08-14  Casey Marshall <csm at gnu.org>
+
+	* src/mips/ffi.c (ffi_pref_cif_machdep): set `cif->flags' to
+	contain `FFI_TYPE_UINT64' as return type for any 64-bit
+	integer (O32 ABI only).
+	(ffi_prep_closure): new function.
+	(ffi_closure_mips_inner_O32): new function.
+	* src/mips/ffitarget.h: Define `FFI_CLOSURES' and
+	`FFI_TRAMPOLINE_SIZE' appropriately if the ABI is o32.
+	* src/mips/o32.S (ffi_call_O32): add labels for .eh_frame. Return
+	64 bit integers correctly.
+	(ffi_closure_O32): new function.
+	Added DWARF-2 unwind info for both functions.
+
+2004-08-10  Andrew Haley  <aph at redhat.com>
+
+	* src/x86/ffi64.c (ffi_prep_args ): 8-align all stack arguments.
+
+2004-08-01  Robert Millan  <robertmh at gnu.org>
+
+	* configure.ac: Detect knetbsd-gnu and kfreebsd-gnu.
+	* configure: Regenerate.
+
+2004-07-30  Maciej W. Rozycki  <macro at linux-mips.org>
+
+	* acinclude.m4 (AC_FUNC_MMAP_BLACKLIST): Check for <sys/mman.h>
+	and mmap() explicitly instead of relying on preset autoconf cache
+	variables.
+	* aclocal.m4: Regenerate.
+	* configure: Regenerate.
+
+2004-07-11  Ulrich Weigand  <uweigand at de.ibm.com>
+
+	* src/s390/ffi.c (ffi_prep_args): Fix C aliasing violation.
+	(ffi_check_float_struct): Remove unused prototype.
+
+2004-06-30  Geoffrey Keating  <geoffk at apple.com>
+
+	* src/powerpc/ffi_darwin.c (flush_icache): ';' is a comment
+	character on Darwin, use '\n\t' instead.
+
+2004-06-26  Matthias Klose  <doko at debian.org>
+
+	* libtool-version: Fix typo in revision/age.
+
+2004-06-17  Matthias Klose  <doko at debian.org>
+
+	* libtool-version: New.
+	* Makefile.am (libffi_la_LDFLAGS): Use -version-info for soname.
+	* Makefile.in: Regenerate.
+
+2004-06-15  Paolo Bonzini  <bonzini at gnu.org>
+
+	* Makefile.am: Remove useless multilib rules.
+	* Makefile.in: Regenerate.
+	* aclocal.m4: Regenerate with automake 1.8.5.
+	* configure.ac: Remove useless multilib configury.
+	* configure: Regenerate.
+
+2004-06-15  Paolo Bonzini  <bonzini at gnu.org>
+
+	* .cvsignore: New file.
+
+2004-06-10  Jakub Jelinek  <jakub at redhat.com>
+
+	* src/ia64/unix.S (ffi_call_unix): Insert group barrier break
+	fp_done.
+	(ffi_closure_UNIX): Fix f14/f15 adjustment if FLOAT_SZ is ever
+	changed from 8.
+
+2004-06-06  Sean McNeil  <sean at mcneil.com>
+
+	* configure.ac: Add x86_64-*-freebsd* support.
+	* configure: Regenerate.
+
+2004-04-26  Joe Buck <jbuck at welsh-buck.org>
+
+	Bug 15093
+	* configure.ac: Test for existence of mmap and sys/mman.h before
+	checking blacklist.  Fix suggested by Jim Wilson.
+	* configure: Regenerate.
+
+2004-04-26  Matt Austern  <austern at apple.com>
+
+	* src/powerpc/darwin.S: Go through a non-lazy pointer for initial
+	FDE location.
+	* src/powerpc/darwin_closure.S: Likewise.
+
+2004-04-24  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/libffi.call/cls_multi_schar.c (main): Fix initialization
+	error. Reported by Thomas Heller <theller at python.net>.
+	* testsuite/libffi.call/cls_multi_sshort.c (main): Likewise.
+	* testsuite/libffi.call/cls_multi_ushort.c (main): Likewise.
+
+2004-03-20  Matthias Klose  <doko at debian.org>
+
+	* src/pa/linux.S: Fix typo.
+
+2004-03-19  Matthias Klose  <doko at debian.org>
+
+	* Makefile.am: Update.
+	* Makefile.in: Regenerate.
+	* src/pa/ffi.h.in: Remove.
+	* src/pa/ffitarget.h: New file.
+
+2004-02-10  Randolph Chung  <tausq at debian.org>
+
+	* Makefile.am: Add PA support.
+	* Makefile.in: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* configure.ac: Add PA target.
+	* configure: Regenerate.
+	* src/pa/ffi.c: New file.
+	* src/pa/ffi.h.in: Add PA support.
+	* src/pa/linux.S: New file.
+	* prep_cif.c: Add PA support.
+
+2004-03-16  Hosaka Yuji  <hos at tamanegi.org>
+
+	* src/types.c: Fix alignment size of X86_WIN32 case int64 and
+	double.
+	* src/x86/ffi.c (ffi_prep_args): Replace ecif->cif->rtype->type
+	with ecif->cif->flags.
+	(ffi_call, ffi_prep_incoming_args_SYSV): Replace cif->rtype->type
+	with cif->flags.
+	(ffi_prep_cif_machdep): Add X86_WIN32 struct case.
+	(ffi_closure_SYSV): Add 1 or 2-bytes struct case for X86_WIN32.
+	* src/x86/win32.S (retstruct1b, retstruct2b, sc_retstruct1b,
+	sc_retstruct2b): Add for 1 or 2-bytes struct case.
+
+2004-03-15 Kelley Cook <kcook at gcc.gnu.org>
+
+	* configure.in: Rename file to ...
+	* configure.ac: ... this.
+	* fficonfig.h.in: Regenerate.
+	* Makefile.in: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+
+2004-03-12  Matt Austern  <austern at apple.com>
+
+	* src/powerpc/darwin.S: Fix EH information so it corresponds to
+	changes in EH format resulting from addition of linkonce support.
+	* src/powerpc/darwin_closure.S: Likewise.
+
+2004-03-11  Andreas Tobler  <a.tobler at schweiz.ch>
+	    Paolo Bonzini  <bonzini at gnu.org>
+
+	* Makefile.am (AUTOMAKE_OPTIONS): Set them.
+	Remove VPATH. Remove rules for object files. Remove multilib support.
+	(AM_CCASFLAGS): Add.
+	* configure.in (AC_CONFIG_HEADERS): Relace AM_CONFIG_HEADER.
+	(AC_PREREQ): Bump version to 2.59.
+	(AC_INIT): Fill with version info and bug address.
+	(ORIGINAL_LD_FOR_MULTILIBS): Remove.
+	(AM_ENABLE_MULTILIB): Use this instead of AC_ARG_ENABLE.
+	De-precious CC so that the right flags are passed down to multilibs.
+	(AC_MSG_ERROR): Replace obsolete macro AC_ERROR.
+	(AC_CONFIG_FILES): Replace obsolete macro AC_LINK_FILES.
+	(AC_OUTPUT): Reorganize the output with AC_CONFIG_COMMANDS.
+	* configure: Rebuilt.
+	* aclocal.m4: Likewise.
+	* Makefile.in, include/Makefile.in, testsuite/Makefile.in: Likewise.
+	* fficonfig.h.in: Likewise.
+
+2004-03-11  Andreas Schwab  <schwab at suse.de>
+
+	* src/ia64/ffi.c (ffi_prep_incoming_args_UNIX): Get floating point
+	arguments from fp registers only for the first 8 parameter slots.
+	Don't convert a float parameter when passed in memory.
+
+2004-03-09  Hans-Peter Nilsson  <hp at axis.com>
+
+	* configure: Regenerate for config/accross.m4 correction.
+
+2004-02-25  Matt Kraai  <kraai at alumni.cmu.edu>
+
+	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Change
+	ecif->cif->bytes to bytes.
+	(ffi_prep_cif_machdep): Add braces around nested if statement.
+
+2004-02-09  Alan Modra  <amodra at bigpond.net.au>
+
+	* src/types.c (pointer): POWERPC64 has 8 byte pointers.
+
+	* src/powerpc/ffi.c (ffi_prep_args64): Correct long double handling.
+	(ffi_closure_helper_LINUX64): Fix typo.
+	* testsuite/libffi.call/cls_align_longdouble.c: Pass -mlong-double-128
+	for powerpc64-*-*.
+	* testsuite/libffi.call/float.c: Likewise.
+	* testsuite/libffi.call/float2.c: Likewise.
+
+2004-02-08  Alan Modra  <amodra at bigpond.net.au>
+
+	* src/powerpc/ffi.c (ffi_prep_cif_machdep <FFI_LINUX64>): Correct
+	long double function return and long double arg handling.
+	(ffi_closure_helper_LINUX64): Formatting.  Delete unused "ng" var.
+	Use "end_pfr" instead of "nf".  Correct long double handling.
+	Localise "temp".
+	* src/powerpc/linux64.S (ffi_call_LINUX64): Save f2 long double
+	return value.
+	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Allocate
+	space for long double return value.  Adjust stack frame and offsets.
+	Load f2 long double return.
+
+2004-02-07  Alan Modra  <amodra at bigpond.net.au>
+
+	* src/types.c: Use 16 byte long double for POWERPC64.
+
+2004-01-25  Eric Botcazou  <ebotcazou at libertysurf.fr>
+
+	* src/sparc/ffi.c (ffi_prep_args_v9): Shift the parameter array
+	when the structure return address is passed in %o0.
+	(ffi_V9_return_struct): Rename into ffi_v9_layout_struct.
+	(ffi_v9_layout_struct): Align the field following a nested structure
+	on a word boundary.  Use memmove instead of memcpy.
+	(ffi_call): Update call to ffi_V9_return_struct.
+	(ffi_prep_closure): Define 'ctx' only for V8.
+	(ffi_closure_sparc_inner): Clone into ffi_closure_sparc_inner_v8
+	and ffi_closure_sparc_inner_v9.
+	(ffi_closure_sparc_inner_v8): Return long doubles by reference.
+	Always skip the structure return address.  For structures and long
+	doubles, copy the argument directly.
+	(ffi_closure_sparc_inner_v9): Skip the structure return address only
+	if required.  Shift the maximum floating-point slot accordingly.  For
+	big structures, copy the argument directly; otherwise, left-justify the
+	argument and call ffi_v9_layout_struct to lay out the structure on
+	the stack.
+	* src/sparc/v8.S: Undef STACKFRAME before defining it.
+	(ffi_closure_v8): Pass the structure return address.  Update call to
+	ffi_closure_sparc_inner_v8.  Short-circuit FFI_TYPE_INT handling.
+	Skip the 'unimp' insn when returning long doubles and structures.
+	* src/sparc/v9.S: Undef STACKFRAME before defining it.
+	(ffi_closure_v9): Increase the frame size by 2 words.  Short-circuit
+	FFI_TYPE_INT handling.  Load structures both in integers and
+	floating-point registers on return.
+	* README: Update status of the SPARC port.
+
+2004-01-24  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/libffi.call/pyobjc-tc.c (main): Treat result value
+	as of type ffi_arg.
+	* testsuite/libffi.call/struct3.c (main): Fix CHECK.
+
+2004-01-22  Ulrich Weigand  <uweigand at de.ibm.com>
+
+	* testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Treat result
+	value as of type ffi_arg, not unsigned int.
+
+2004-01-21  Michael Ritzert  <ritzert at t-online.de>
+
+	* ffi64.c (ffi_prep_args): Cast the RHS of an assignment instead
+	of the LHS.
+
+2004-01-12  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_32 for
+	Solaris.
+
+2004-01-08  Rainer Orth  <ro at TechFak.Uni-Bielefeld.DE>
+
+	* testsuite/libffi.call/ffitest.h (allocate_mmap): Cast MAP_FAILED
+	to void *.
+
+2003-12-10  Richard Henderson  <rth at redhat.com>
+
+	* testsuite/libffi.call/cls_align_pointer.c: Cast pointers to
+	size_t instead of int.
+
+2003-12-04  Hosaka Yuji  <hos at tamanegi.org>
+
+	* testsuite/libffi.call/many_win32.c: Include <float.h>.
+	* testsuite/libffi.call/many_win32.c (main): Replace variable
+	int i with unsigned long ul.
+
+	* testsuite/libffi.call/cls_align_uint64.c: New test case.
+	* testsuite/libffi.call/cls_align_sint64.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint32.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint32.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint16.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint16.c: Likewise.
+	* testsuite/libffi.call/cls_align_float.c: Likewise.
+	* testsuite/libffi.call/cls_align_double.c: Likewise.
+	* testsuite/libffi.call/cls_align_longdouble.c: Likewise.
+	* testsuite/libffi.call/cls_align_pointer.c: Likewise.
+
+2003-12-02  Hosaka Yuji  <hos at tamanegi.org>
+
+	PR other/13221
+	* src/x86/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV):
+	Align arguments to 32 bits.
+
+2003-12-01  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	PR other/13221
+	* testsuite/libffi.call/cls_multi_sshort.c: New test case.
+	* testsuite/libffi.call/cls_multi_sshortchar.c: Likewise.
+	* testsuite/libffi.call/cls_multi_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_multi_schar.c: Likewise.
+	* testsuite/libffi.call/cls_multi_ushortchar.c: Likewise.
+	* testsuite/libffi.call/cls_multi_ushort.c: Likewise.
+
+	* testsuite/libffi.special/unwindtest.cc: Cosmetics.
+
+2003-11-26  Kaveh R. Ghazi  <ghazi at caip.rutgers.edu>
+
+	* testsuite/libffi.call/ffitest.h: Include <fcntl.h>.
+	* testsuite/libffi.special/ffitestcxx.h: Likewise.
+
+2003-11-22  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* Makefile.in: Rebuilt.
+	* configure: Likewise.
+	* testsuite/libffi.special/unwindtest.cc: Convert the mmap to
+	the right type.
+
+2003-11-21  Andreas Jaeger  <aj at suse.de>
+	    Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* acinclude.m4: Add AC_FUNC_MMAP_BLACKLIST.
+	* configure.in: Call AC_FUNC_MMAP_BLACKLIST.
+	* Makefile.in: Rebuilt.
+	* aclocal.m4: Likewise.
+	* configure: Likewise.
+	* fficonfig.h.in: Likewise.
+	* testsuite/lib/libffi-dg.exp: Add include dir.
+	* testsuite/libffi.call/ffitest.h: Add MMAP definitions.
+	* testsuite/libffi.special/ffitestcxx.h: Likewise.
+	* testsuite/libffi.call/closure_fn0.c: Use MMAP functionality
+	for ffi_closure if available.
+	* testsuite/libffi.call/closure_fn1.c: Likewise.
+	* testsuite/libffi.call/closure_fn2.c: Likewise.
+	* testsuite/libffi.call/closure_fn3.c: Likewise.
+	* testsuite/libffi.call/closure_fn4.c: Likewise.
+	* testsuite/libffi.call/closure_fn5.c: Likewise.
+	* testsuite/libffi.call/cls_12byte.c: Likewise.
+	* testsuite/libffi.call/cls_16byte.c: Likewise.
+	* testsuite/libffi.call/cls_18byte.c: Likewise.
+	* testsuite/libffi.call/cls_19byte.c: Likewise.
+	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte1.c: Likewise.
+	* testsuite/libffi.call/cls_24byte.c: Likewise.
+	* testsuite/libffi.call/cls_2byte.c: Likewise.
+	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_3byte1.c: Likewise.
+	* testsuite/libffi.call/cls_3byte2.c: Likewise.
+	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_4byte.c: Likewise.
+	* testsuite/libffi.call/cls_5byte.c: Likewise.
+	* testsuite/libffi.call/cls_64byte.c: Likewise.
+	* testsuite/libffi.call/cls_6byte.c: Likewise.
+	* testsuite/libffi.call/cls_7byte.c: Likewise.
+	* testsuite/libffi.call/cls_8byte.c: Likewise.
+	* testsuite/libffi.call/cls_9byte1.c: Likewise.
+	* testsuite/libffi.call/cls_9byte2.c: Likewise.
+	* testsuite/libffi.call/cls_double.c: Likewise.
+	* testsuite/libffi.call/cls_float.c: Likewise.
+	* testsuite/libffi.call/cls_schar.c: Likewise.
+	* testsuite/libffi.call/cls_sint.c: Likewise.
+	* testsuite/libffi.call/cls_sshort.c: Likewise.
+	* testsuite/libffi.call/cls_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_uint.c: Likewise.
+	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
+	* testsuite/libffi.call/cls_ushort.c: Likewise.
+	* testsuite/libffi.call/nested_struct.c: Likewise.
+	* testsuite/libffi.call/nested_struct1.c: Likewise.
+	* testsuite/libffi.call/nested_struct2.c: Likewise.
+	* testsuite/libffi.call/nested_struct3.c: Likewise.
+	* testsuite/libffi.call/problem1.c: Likewise.
+	* testsuite/libffi.special/unwindtest.cc: Likewise.
+
+2003-11-20  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/lib/libffi-dg.exp: Make the -lgcc_s conditional.
+
+2003-11-19  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/lib/libffi-dg.exp: Add DYLD_LIBRARY_PATH for darwin.
+	Add -lgcc_s to additional flags.
+
+2003-11-12  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* configure.in, include/Makefile.am: PR libgcj/11147, install
+	the ffitarget.h header file in a gcc versioned and target
+	dependent place.
+	* configure: Regenerated.
+	* Makefile.in, include/Makefile.in: Likewise.
+	* testsuite/Makefile.in: Likewise.
+
+2003-11-09  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/libffi.call/closure_fn0.c: Print result and check
+	with dg-output to make debugging easier.
+	* testsuite/libffi.call/closure_fn1.c: Likewise.
+	* testsuite/libffi.call/closure_fn2.c: Likewise.
+	* testsuite/libffi.call/closure_fn3.c: Likewise.
+	* testsuite/libffi.call/closure_fn4.c: Likewise.
+	* testsuite/libffi.call/closure_fn5.c: Likewise.
+	* testsuite/libffi.call/cls_12byte.c: Likewise.
+	* testsuite/libffi.call/cls_16byte.c: Likewise.
+	* testsuite/libffi.call/cls_18byte.c: Likewise.
+	* testsuite/libffi.call/cls_19byte.c: Likewise.
+	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte1.c: Likewise.
+	* testsuite/libffi.call/cls_24byte.c: Likewise.
+	* testsuite/libffi.call/cls_2byte.c: Likewise.
+	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_3byte1.c: Likewise.
+	* testsuite/libffi.call/cls_3byte2.c: Likewise.
+	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_4byte.c: Likewise.
+	* testsuite/libffi.call/cls_5byte.c: Likewise.
+	* testsuite/libffi.call/cls_64byte.c: Likewise.
+	* testsuite/libffi.call/cls_6byte.c: Likewise.
+	* testsuite/libffi.call/cls_7byte.c: Likewise.
+	* testsuite/libffi.call/cls_8byte.c: Likewise.
+	* testsuite/libffi.call/cls_9byte1.c: Likewise.
+	* testsuite/libffi.call/cls_9byte2.c: Likewise.
+	* testsuite/libffi.call/cls_double.c: Likewise.
+	* testsuite/libffi.call/cls_float.c: Likewise.
+	* testsuite/libffi.call/cls_schar.c: Likewise.
+	* testsuite/libffi.call/cls_sint.c: Likewise.
+	* testsuite/libffi.call/cls_sshort.c: Likewise.
+	* testsuite/libffi.call/cls_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_uint.c: Likewise.
+	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
+	* testsuite/libffi.call/cls_ushort.c: Likewise.
+	* testsuite/libffi.call/problem1.c: Likewise.
+
+	* testsuite/libffi.special/unwindtest.cc: Make ffi_closure
+	static.
+
+2003-11-08  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/libffi.call/cls_9byte2.c: New test case.
+	* testsuite/libffi.call/cls_9byte1.c: Likewise.
+	* testsuite/libffi.call/cls_64byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte1.c: Likewise.
+	* testsuite/libffi.call/cls_19byte.c: Likewise.
+	* testsuite/libffi.call/cls_18byte.c: Likewise.
+	* testsuite/libffi.call/closure_fn4.c: Likewise.
+	* testsuite/libffi.call/closure_fn5.c: Likewise.
+	* testsuite/libffi.call/cls_schar.c: Likewise.
+	* testsuite/libffi.call/cls_sint.c: Likewise.
+	* testsuite/libffi.call/cls_sshort.c: Likewise.
+	* testsuite/libffi.call/nested_struct2.c: Likewise.
+	* testsuite/libffi.call/nested_struct3.c: Likewise.
+
+2003-11-08  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/libffi.call/cls_double.c: Do a check on the result.
+	* testsuite/libffi.call/cls_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_uint.c: Likewise.
+	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
+	* testsuite/libffi.call/cls_ushort.c: Likewise.
+	* testsuite/libffi.call/return_sc.c: Cleanup whitespaces.
+
+2003-11-06  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* src/prep_cif.c (ffi_prep_cif): Move the validity check after
+	the initialization.
+
+2003-10-23  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* src/java_raw_api.c (ffi_java_ptrarray_to_raw): Replace
+	FFI_ASSERT(FALSE) with FFI_ASSERT(0).
+
+2003-10-22  David Daney  <ddaney at avtrex.com>
+
+	* src/mips/ffitarget.h: Replace undefined UINT32 and friends with
+	__attribute__((__mode__(__SI__))) and friends.
+
+2003-10-22  Andreas Schwab  <schwab at suse.de>
+
+	* src/ia64/ffi.c: Replace FALSE/TRUE with false/true.
+
+2003-10-21  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* configure.in: AC_LINK_FILES(ffitarget.h).
+	* configure: Regenerate.
+	* Makefile.in: Likewise.
+	* include/Makefile.in: Likewise.
+	* testsuite/Makefile.in: Likewise.
+	* fficonfig.h.in: Likewise.
+
+2003-10-21  Paolo Bonzini  <bonzini at gnu.org>
+	    Richard Henderson  <rth at redhat.com>
+
+	Avoid that ffi.h includes fficonfig.h.
+
+	* Makefile.am (EXTRA_DIST): Include ffitarget.h files
+	(TARGET_SRC_MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX.
+	(TARGET_SRC_MIPS_SGI): Removed.
+	(MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX.
+	(MIPS_SGI): Removed.
+	(CLEANFILES): Removed.
+	(mostlyclean-am, clean-am, mostlyclean-sub, clean-sub): New
+	targets.
+	* acconfig.h: Removed.
+	* configure.in: Compute sizeofs only for double and long double.
+	Use them to define and subst HAVE_LONG_DOUBLE.  Include comments
+	into AC_DEFINE instead of using acconfig.h.  Create
+	include/ffitarget.h instead of include/fficonfig.h.  Rename
+	MIPS_GCC to MIPS_IRIX, drop MIPS_SGI since we are in gcc's tree.
+	AC_DEFINE EH_FRAME_FLAGS.
+	* include/Makefile.am (DISTCLEANFILES): New automake macro.
+	(hack_DATA): Add ffitarget.h.
+	* include/ffi.h.in: Remove all system specific definitions.
+	Declare raw API even if it is not installed, why bother?
+	Use limits.h instead of SIZEOF_* to define ffi_type_*.  Do
+	not define EH_FRAME_FLAGS, it is in fficonfig.h now.  Include
+	ffitarget.h instead of fficonfig.h.  Remove ALIGN macro.
+	(UINT_ARG, INT_ARG): Removed, use ffi_arg and ffi_sarg instead.
+	* include/ffi_common.h (bool): Do not define.
+	(ffi_assert): Accept failed assertion.
+	(ffi_type_test): Return void and accept file/line.
+	(FFI_ASSERT): Pass stringized failed assertion.
+	(FFI_ASSERT_AT): New macro.
+	(FFI_ASSERT_VALID_TYPE): New macro.
+	(UINT8, SINT8, UINT16, SINT16, UINT32, SINT32,
+	UINT64, SINT64): Define here with gcc's __attribute__ macro
+	instead of in ffi.h
+	(FLOAT32, ALIGN): Define here instead of in ffi.h
+	* include/ffi-mips.h: Removed.  Its content moved to
+	src/mips/ffitarget.h after separating assembly and C sections.
+	* src/alpha/ffi.c, src/alpha/ffi.c, src/java_raw_api.c
+	src/prep_cif.c, src/raw_api.c, src/ia64/ffi.c,
+	src/mips/ffi.c, src/mips/n32.S, src/mips/o32.S,
+	src/mips/ffitarget.h, src/sparc/ffi.c, src/x86/ffi64.c:
+	SIZEOF_ARG -> FFI_SIZEOF_ARG.
+	* src/ia64/ffi.c: Include stdbool.h (provided by GCC 2.95+).
+	* src/debug.c (ffi_assert): Accept stringized failed assertion.
+	(ffi_type_test): Rewritten.
+	* src/prep-cif.c (initialize_aggregate, ffi_prep_cif): Call
+	FFI_ASSERT_VALID_TYPE.
+	* src/alpha/ffitarget.h, src/arm/ffitarget.h,
+	src/ia64/ffitarget.h, src/m68k/ffitarget.h,
+	src/mips/ffitarget.h, src/powerpc/ffitarget.h,
+	src/s390/ffitarget.h, src/sh/ffitarget.h,
+	src/sh64/ffitarget.h, src/sparc/ffitarget.h,
+	src/x86/ffitarget.h: New files.
+	* src/alpha/osf.S, src/arm/sysv.S, src/ia64/unix.S,
+	src/m68k/sysv.S, src/mips/n32.S, src/mips/o32.S,
+	src/powerpc/aix.S, src/powerpc/darwin.S,
+	src/powerpc/ffi_darwin.c, src/powerpc/linux64.S,
+	src/powerpc/linux64_closure.S, src/powerpc/ppc_closure.S,
+	src/powerpc/sysv.S, src/s390/sysv.S, src/sh/sysv.S,
+	src/sh64/sysv.S, src/sparc/v8.S, src/sparc/v9.S,
+	src/x86/sysv.S, src/x86/unix64.S, src/x86/win32.S:
+	include fficonfig.h
+
+2003-10-20  Rainer Orth  <ro at TechFak.Uni-Bielefeld.DE>
+
+	* src/mips/ffi.c: Use _ABIN32, _ABIO32 instead of external
+	_MIPS_SIM_NABI32, _MIPS_SIM_ABI32.
+
+2003-10-19  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Declare bytes again.
+	Used when FFI_DEBUG = 1.
+
+2003-10-14  Alan Modra  <amodra at bigpond.net.au>
+
+	* src/types.c (double, longdouble): Default POWERPC64 to 8 byte size
+	and align.
+
+2003-10-06  Rainer Orth  <ro at TechFak.Uni-Bielefeld.DE>
+
+	* include/ffi_mips.h: Define FFI_MIPS_N32 for N32/N64 ABIs,
+	FFI_MIPS_O32 for O32 ABI.
+
+2003-10-01  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_64 for
+	SPARC64. Cleanup whitespaces.
+
+2003-09-19  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* testsuite/libffi.call/closure_fn0.c: Xfail mips, arm,
+	strongarm, xscale. Cleanup whitespaces.
+	* testsuite/libffi.call/closure_fn1.c: Likewise.
+	* testsuite/libffi.call/closure_fn2.c: Likewise.
+	* testsuite/libffi.call/closure_fn3.c: Likewise.
+	* testsuite/libffi.call/cls_12byte.c: Likewise.
+	* testsuite/libffi.call/cls_16byte.c: Likewise.
+	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte.c: Likewise.
+	* testsuite/libffi.call/cls_24byte.c: Likewise.
+	* testsuite/libffi.call/cls_2byte.c: Likewise.
+	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_3byte1.c: Likewise.
+	* testsuite/libffi.call/cls_3byte2.c: Likewise.
+	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_4byte.c: Likewise.
+	* testsuite/libffi.call/cls_5byte.c: Likewise.
+	* testsuite/libffi.call/cls_6byte.c: Likewise.
+	* testsuite/libffi.call/cls_7byte.c: Likewise.
+	* testsuite/libffi.call/cls_8byte.c: Likewise.
+	* testsuite/libffi.call/cls_double.c: Likewise.
+	* testsuite/libffi.call/cls_float.c: Likewise.
+	* testsuite/libffi.call/cls_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_uint.c: Likewise.
+	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
+	* testsuite/libffi.call/cls_ushort.c: Likewise.
+	* testsuite/libffi.call/nested_struct.c: Likewise.
+	* testsuite/libffi.call/nested_struct1.c: Likewise.
+	* testsuite/libffi.call/problem1.c: Likewise.
+	* testsuite/libffi.special/unwindtest.cc: Likewise.
+	* testsuite/libffi.call/pyobjc-tc.c: Cleanup whitespaces.
+
+2003-09-18  David Edelsohn  <edelsohn at gnu.org>
+
+	* src/powerpc/aix.S: Cleanup whitespaces.
+	* src/powerpc/aix_closure.S: Likewise.
+
+2003-09-18  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* src/powerpc/darwin.S: Cleanup whitespaces, comment formatting.
+	* src/powerpc/darwin_closure.S: Likewise.
+	* src/powerpc/ffi_darwin.c: Likewise.
+
+2003-09-18  Andreas Tobler  <a.tobler at schweiz.ch>
+	    David Edelsohn  <edelsohn at gnu.org>
+
+	* src/types.c (double): Add AIX and Darwin to the right TYPEDEF.
+	* src/powerpc/aix_closure.S: Remove the pointer to the outgoing
+	parameter stack.
+	* src/powerpc/darwin_closure.S: Likewise.
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Handle structures
+	according to the Darwin/AIX ABI.
+	(ffi_prep_cif_machdep): Likewise.
+	(ffi_closure_helper_DARWIN): Likewise.
+	Remove the outgoing parameter stack logic. Simplify the evaluation
+	of the different CASE types.
+	(ffi_prep_clousure): Avoid the casts on lvalues. Change the branch
+	statement in the trampoline code.
+
+2003-09-18  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* src/sh/ffi.c (ffi_prep_args): Take account into the alignement
+	for the register size.
+	(ffi_closure_helper_SYSV): Handle the structure return value
+	address correctly.
+	(ffi_closure_helper_SYSV): Return the appropriate type when
+	the registers are used for the structure return value.
+	* src/sh/sysv.S (ffi_closure_SYSV): Fix the stack layout for
+	the 64-bit return value.  Update copyright years.
+
+2003-09-17  Rainer Orth  <ro at TechFak.Uni-Bielefeld.DE>
+
+	* testsuite/lib/libffi-dg.exp (libffi_target_compile): Search in
+	srcdir for ffi_mips.h.
+
+2003-09-12  Alan Modra  <amodra at bigpond.net.au>
+
+	* src/prep_cif.c (initialize_aggregate): Include tail padding in
+	structure size.
+	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Correct
+	placement of float result.
+	* testsuite/libffi.special/unwindtest.cc (closure_test_fn1): Correct
+	cast of "resp" for big-endian 64 bit machines.
+
+2003-09-11  Alan Modra  <amodra at bigpond.net.au>
+
+	* src/types.c (double, longdouble): Merge identical SH and ARM
+	typedefs, and add POWERPC64.
+	* src/powerpc/ffi.c (ffi_prep_args64): Correct next_arg calc for
+	struct split over gpr and rest.
+	(ffi_prep_cif_machdep): Correct intarg_count for structures.
+	* src/powerpc/linux64.S (ffi_call_LINUX64): Fix gpr offsets.
+
+2003-09-09  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* src/powerpc/ffi.c (ffi_closure_helper_SYSV) Handle struct
+	passing correctly.
+
+2003-09-09  Alan Modra  <amodra at bigpond.net.au>
+
+	* configure: Regenerate.
+
+2003-09-04  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* Makefile.am: Remove build rules for ffitest.
+	* Makefile.in: Rebuilt.
+
+2003-09-04  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* src/java_raw_api.c: Include <stdlib.h> to fix compiler warning
+	about implicit declaration of abort().
+
+2003-09-04  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* Makefile.am: Add dejagnu test framework. Fixes PR other/11411.
+	* Makefile.in: Rebuilt.
+	* configure.in: Add dejagnu test framework.
+	* configure: Rebuilt.
+
+	* testsuite/Makefile.am: New file.
+	* testsuite/Makefile.in: Built
+	* testsuite/lib/libffi-dg.exp: New file.
+	* testsuite/config/default.exp: Likewise.
+	* testsuite/libffi.call/call.exp: Likewise.
+	* testsuite/libffi.call/ffitest.h: Likewise.
+	* testsuite/libffi.call/closure_fn0.c: Likewise.
+	* testsuite/libffi.call/closure_fn1.c: Likewise.
+	* testsuite/libffi.call/closure_fn2.c: Likewise.
+	* testsuite/libffi.call/closure_fn3.c: Likewise.
+	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_2byte.c: Likewise.
+	* testsuite/libffi.call/cls_3byte1.c: Likewise.
+	* testsuite/libffi.call/cls_3byte2.c: Likewise.
+	* testsuite/libffi.call/cls_4byte.c: Likewise.
+	* testsuite/libffi.call/cls_5byte.c: Likewise.
+	* testsuite/libffi.call/cls_6byte.c: Likewise.
+	* testsuite/libffi.call/cls_7byte.c: Likewise.
+	* testsuite/libffi.call/cls_8byte.c: Likewise.
+	* testsuite/libffi.call/cls_12byte.c: Likewise.
+	* testsuite/libffi.call/cls_16byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte.c: Likewise.
+	* testsuite/libffi.call/cls_24byte.c: Likewise.
+	* testsuite/libffi.call/cls_double.c: Likewise.
+	* testsuite/libffi.call/cls_float.c: Likewise.
+	* testsuite/libffi.call/cls_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_uint.c: Likewise.
+	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
+	* testsuite/libffi.call/cls_ushort.c: Likewise.
+	* testsuite/libffi.call/float.c: Likewise.
+	* testsuite/libffi.call/float1.c: Likewise.
+	* testsuite/libffi.call/float2.c: Likewise.
+	* testsuite/libffi.call/many.c: Likewise.
+	* testsuite/libffi.call/many_win32.c: Likewise.
+	* testsuite/libffi.call/nested_struct.c: Likewise.
+	* testsuite/libffi.call/nested_struct1.c: Likewise.
+	* testsuite/libffi.call/pyobjc-tc.c: Likewise.
+	* testsuite/libffi.call/problem1.c: Likewise.
+	* testsuite/libffi.call/promotion.c: Likewise.
+	* testsuite/libffi.call/return_ll.c: Likewise.
+	* testsuite/libffi.call/return_sc.c: Likewise.
+	* testsuite/libffi.call/return_uc.c: Likewise.
+	* testsuite/libffi.call/strlen.c: Likewise.
+	* testsuite/libffi.call/strlen_win32.c: Likewise.
+	* testsuite/libffi.call/struct1.c: Likewise.
+	* testsuite/libffi.call/struct2.c: Likewise.
+	* testsuite/libffi.call/struct3.c: Likewise.
+	* testsuite/libffi.call/struct4.c: Likewise.
+	* testsuite/libffi.call/struct5.c: Likewise.
+	* testsuite/libffi.call/struct6.c: Likewise.
+	* testsuite/libffi.call/struct7.c: Likewise.
+	* testsuite/libffi.call/struct8.c: Likewise.
+	* testsuite/libffi.call/struct9.c: Likewise.
+	* testsuite/libffi.special/special.exp: New file.
+	* testsuite/libffi.special/ffitestcxx.h: Likewise.
+	* testsuite/libffi.special/unwindtest.cc: Likewise.
+
+
+2003-08-13  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* src/sh/ffi.c (OFS_INT16): Set 0 for little endian case.  Update
+	copyright years.
+
+2003-08-02  Alan Modra  <amodra at bigpond.net.au>
+
+	* src/powerpc/ffi.c (ffi_prep_args64): Modify for changed gcc
+	structure passing.
+	(ffi_closure_helper_LINUX64): Likewise.
+	* src/powerpc/linux64.S: Remove code writing to parm save area.
+	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Use return
+	address in lr from ffi_closure_helper_LINUX64 call to calculate
+	table address.  Optimize function tail.
+
+2003-07-28  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* src/sparc/ffi.c: Handle all floating point registers.
+	* src/sparc/v9.S: Likewise. Fixes second part of PR target/11410.
+
+2003-07-11  Gerald Pfeifer  <pfeifer at dbai.tuwien.ac.at>
+
+	* README: Note that libffi is not part of GCC.  Update the project
+	URL and status.
+
+2003-06-19  Franz Sirl  <Franz.Sirl-kernel at lauterbach.com>
+
+	* src/powerpc/ppc_closure.S: Include ffi.h.
+
+2003-06-13  Rainer Orth  <ro at TechFak.Uni-Bielefeld.DE>
+
+	* src/x86/sysv.S: Avoid gas-only .uleb128/.sleb128 directives.
+	Use C style comments.
+
+2003-06-13  Kaz Kojima  <kkojima at rr.iij4u.or.jp>
+
+	* Makefile.am: Add SHmedia support.  Fix a typo of SH support.
+	* Makefile.in: Regenerate.
+	* configure.in (sh64-*-linux*, sh5*-*-linux*): Add target.
+	* configure: Regenerate.
+	* include/ffi.h.in: Add SHmedia support.
+	* src/sh64/ffi.c: New file.
+	* src/sh64/sysv.S: New file.
+
+2003-05-16  Jakub Jelinek  <jakub at redhat.com>
+
+	* configure.in (HAVE_RO_EH_FRAME): Check whether .eh_frame section
+	should be read-only.
+	* configure: Rebuilt.
+	* fficonfig.h.in: Rebuilt.
+	* include/ffi.h.in (EH_FRAME_FLAGS): Define.
+	* src/alpha/osf.S: Use EH_FRAME_FLAGS.
+	* src/powerpc/linux64.S: Likewise.
+	* src/powerpc/linux64_closure.S: Likewise.  Include ffi.h.
+	* src/powerpc/sysv.S: Use EH_FRAME_FLAGS.  Use pcrel encoding
+	if -fpic/-fPIC/-mrelocatable.
+	* src/powerpc/powerpc_closure.S: Likewise.
+	* src/sparc/v8.S: If HAVE_RO_EH_FRAME is defined, don't include
+	#write in .eh_frame flags.
+	* src/sparc/v9.S: Likewise.
+	* src/x86/unix64.S: Use EH_FRAME_FLAGS.
+	* src/x86/sysv.S: Likewise.  Use pcrel encoding if -fpic/-fPIC.
+	* src/s390/sysv.S: Use EH_FRAME_FLAGS.  Include ffi.h.
+
+2003-05-07  Jeff Sturm  <jsturm at one-point.com>
+
+	Fixes PR bootstrap/10656
+	* configure.in (HAVE_AS_REGISTER_PSEUDO_OP): Test assembler
+	support for .register pseudo-op.
+	* src/sparc/v8.S: Use it.
+	* fficonfig.h.in: Rebuilt.
+	* configure: Rebuilt.
+
+2003-04-18  Jakub Jelinek  <jakub at redhat.com>
+
+	* include/ffi.h.in (POWERPC64): Define if 64-bit.
+	(enum ffi_abi): Add FFI_LINUX64 on POWERPC.
+	Make it the default on POWERPC64.
+	(FFI_TRAMPOLINE_SIZE): Define to 24 on POWERPC64.
+	* configure.in: Change powerpc-*-linux* into powerpc*-*-linux*.
+	* configure: Rebuilt.
+	* src/powerpc/ffi.c (hidden): Define.
+	(ffi_prep_args_SYSV): Renamed from
+	ffi_prep_args.  Cast pointers to unsigned long to shut up warnings.
+	(NUM_GPR_ARG_REGISTERS64, NUM_FPR_ARG_REGISTERS64,
+	ASM_NEEDS_REGISTERS64): New.
+	(ffi_prep_args64): New function.
+	(ffi_prep_cif_machdep): Handle FFI_LINUX64 ABI.
+	(ffi_call): Likewise.
+	(ffi_prep_closure): Likewise.
+	(flush_icache): Surround by #ifndef POWERPC64.
+	(ffi_dblfl): New union type.
+	(ffi_closure_helper_SYSV): Use it to avoid aliasing problems.
+	(ffi_closure_helper_LINUX64): New function.
+	* src/powerpc/ppc_closure.S: Surround whole file by #ifndef
+	__powerpc64__.
+	* src/powerpc/sysv.S: Likewise.
+	(ffi_call_SYSV): Rename ffi_prep_args to ffi_prep_args_SYSV.
+	* src/powerpc/linux64.S: New file.
+	* src/powerpc/linux64_closure.S: New file.
+	* Makefile.am (EXTRA_DIST): Add src/powerpc/linux64.S and
+	src/powerpc/linux64_closure.S.
+	(TARGET_SRC_POWERPC): Likewise.
+
+	* src/ffitest.c (closure_test_fn, closure_test_fn1, closure_test_fn2,
+	closure_test_fn3): Fix result printing on big-endian 64-bit
+	machines.
+	(main): Print tst2_arg instead of uninitialized tst2_result.
+
+	* src/ffitest.c (main): Hide what closure pointer really points to
+	from the compiler.
+
+2003-04-16  Richard Earnshaw  <rearnsha at arm.com>
+
+	* configure.in (arm-*-netbsdelf*): Add configuration.
+	(configure): Regenerated.
+
+2003-04-04  Loren J. Rittle  <ljrittle at acm.org>
+
+	* include/Makefile.in: Regenerate.
+
+2003-03-21  Zdenek Dvorak  <rakdver at atrey.karlin.mff.cuni.cz>
+
+	* libffi/include/ffi.h.in: Define X86 instead of X86_64 in 32
+	bit mode.
+	* libffi/src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV):
+	Receive closure pointer through parameter, read args using
+	__builtin_dwarf_cfa.
+	(FFI_INIT_TRAMPOLINE): Send closure reference through eax.
+
+2003-03-12  Andreas Schwab  <schwab at suse.de>
+
+	* configure.in: Avoid trailing /. in toolexeclibdir.
+	* configure: Rebuilt.
+
+2003-03-03  Andreas Tobler <a.tobler at schweiz.ch>
+
+	* src/powerpc/darwin_closure.S: Recode to fit dynamic libraries.
+
+2003-02-06  Andreas Tobler <a.tobler at schweiz.ch>
+
+	* libffi/src/powerpc/darwin_closure.S:
+	Fix alignement bug, allocate 8 bytes for the result.
+	* libffi/src/powerpc/aix_closure.S:
+	Likewise.
+	* libffi/src/powerpc/ffi_darwin.c:
+	Update stackframe description for aix/darwin_closure.S.
+
+2003-02-06  Jakub Jelinek  <jakub at redhat.com>
+
+	* src/s390/ffi.c (ffi_closure_helper_SYSV): Add hidden visibility
+	attribute.
+
+2003-01-31  Christian Cornelssen  <ccorn at cs.tu-berlin.de>,
+	    Andreas Schwab  <schwab at suse.de>
+
+	* configure.in: Adjust command to source config-ml.in to account
+	for changes to the libffi_basedir definition.
+	(libffi_basedir): Remove ${srcdir} from value and include trailing
+	slash if nonempty.
+
+	* configure: Regenerate.
+
+2003-01-29  Franz Sirl  <Franz.Sirl-kernel at lauterbach.com>
+
+	* src/powerpc/ppc_closure.S: Recode to fit shared libs.
+
+2003-01-28  Andrew Haley  <aph at redhat.com>
+
+	* include/ffi.h.in: Enable FFI_CLOSURES for x86_64.
+	* src/x86/ffi64.c (ffi_prep_closure): New.
+	(ffi_closure_UNIX64_inner): New.
+	* src/x86/unix64.S (ffi_closure_UNIX64): New.
+
+2003-01-27  Alexandre Oliva  <aoliva at redhat.com>
+
+	* configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST.
+	Remove USE_LIBDIR conditional.
+	* Makefile.am (toolexecdir, toolexeclibdir): Don't override.
+	* Makefile.in, configure: Rebuilt.
+
+2003-01027  David Edelsohn  <edelsohn at gnu.org>
+
+	* Makefile.am (TARGET_SRC_POWERPC_AIX): Fix typo.
+	* Makefile.in: Regenerate.
+
+2003-01-22  Andrew Haley  <aph at redhat.com>
+
+	* src/powerpc/darwin.S (_ffi_call_AIX): Add Augmentation size to
+	unwind info.
+
+2003-01-21  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* src/powerpc/darwin.S: Add unwind info.
+	* src/powerpc/darwin_closure.S: Likewise.
+
+2003-01-14  Andrew Haley  <aph at redhat.com>
+
+	* src/x86/ffi64.c (ffi_prep_args): Check for void retval.
+	(ffi_prep_cif_machdep): Likewise.
+	* src/x86/unix64.S: Add unwind info.
+
+2003-01-14  Andreas Jaeger  <aj at suse.de>
+
+	* src/ffitest.c (main): Only use ffi_closures if those are
+	supported.
+
+2003-01-13 Andreas Tobler <a.tobler at schweiz.ch>
+
+	* libffi/src/ffitest.c
+	 add closure testcases
+
+2003-01-13 Kevin B. Hendricks <khendricks at ivey.uwo.ca>
+
+	* libffi/src/powerpc/ffi.c
+	 fix alignment bug for float (4 byte aligned iso 8 byte)
+
+2003-01-09  Geoffrey Keating  <geoffk at apple.com>
+
+	* src/powerpc/ffi_darwin.c: Remove RCS version string.
+	* src/powerpc/darwin.S: Remove RCS version string.
+
+2003-01-03  Jeff Sturm  <jsturm at one-point.com>
+
+	* include/ffi.h.in: Add closure defines for SPARC, SPARC64.
+	* src/ffitest.c (main): Use static storage for closure.
+	* src/sparc/ffi.c (ffi_prep_closure, ffi_closure_sparc_inner): New.
+	* src/sparc/v8.S (ffi_closure_v8): New.
+	* src/sparc/v9.S (ffi_closure_v9): New.
+
+2002-11-10  Ranjit Mathew <rmathew at hotmail.com>
+
+	* include/ffi.h.in: Added FFI_STDCALL ffi_type
+	  enumeration for X86_WIN32.
+	* src/x86/win32.S: Added ffi_call_STDCALL function
+	  definition.
+	* src/x86/ffi.c (ffi_call/ffi_raw_call): Added
+	  switch cases for recognising FFI_STDCALL and
+	  calling ffi_call_STDCALL if target is X86_WIN32.
+	* src/ffitest.c (my_stdcall_strlen/stdcall_many):
+	  stdcall versions of the "my_strlen" and "many"
+	  test functions (for X86_WIN32).
+	  Added test cases to test stdcall invocation using
+	  these functions.
+
+2002-12-02  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* src/sh/sysv.S: Add DWARF2 unwind info.
+
+2002-11-27  Ulrich Weigand  <uweigand at de.ibm.com>
+
+	* src/s390/sysv.S (.eh_frame section): Make section read-only.
+
+2002-11-26  Jim Wilson  <wilson at redhat.com>
+
+	* src/types.c (FFI_TYPE_POINTER): Has size 8 on IA64.
+
+2002-11-23  H.J. Lu <hjl at gnu.org>
+
+	* acinclude.m4: Add dummy AM_PROG_LIBTOOL.
+	Include ../config/accross.m4.
+	* aclocal.m4; Rebuild.
+	* configure: Likewise.
+
+2002-11-15  Ulrich Weigand  <uweigand at de.ibm.com>
+
+	* src/s390/sysv.S (.eh_frame section): Adapt to pcrel FDE encoding.
+
+2002-11-11  DJ Delorie  <dj at redhat.com>
+
+	* configure.in: Look for common files in the right place.
+
+2002-10-08  Ulrich Weigand  <uweigand at de.ibm.com>
+
+	* src/java_raw_api.c (ffi_java_raw_to_ptrarray): Interpret
+	raw data as _Jv_word values, not ffi_raw.
+	(ffi_java_ptrarray_to_raw): Likewise.
+	(ffi_java_rvalue_to_raw): New function.
+	(ffi_java_raw_call): Call it.
+	(ffi_java_raw_to_rvalue): New function.
+	(ffi_java_translate_args): Call it.
+	* src/ffitest.c (closure_test_fn): Interpret return value
+	as ffi_arg, not int.
+	* src/s390/ffi.c (ffi_prep_cif_machdep): Add missing
+	FFI_TYPE_POINTER case.
+	(ffi_closure_helper_SYSV): Likewise.  Also, assume return
+	values extended to word size.
+
+2002-10-02  Andreas Jaeger  <aj at suse.de>
+
+	* src/x86/ffi64.c (ffi_prep_cif_machdep): Remove debug output.
+
+2002-10-01  Bo Thorsen  <bo at smetana.suse.de>
+
+	* include/ffi.h.in: Fix i386 win32 compilation.
+
+2002-09-30  Ulrich Weigand  <uweigand at de.ibm.com>
+
+	* configure.in: Add s390x-*-linux-* target.
+	* configure: Regenerate.
+	* include/ffi.h.in: Define S390X for s390x targets.
+	(FFI_CLOSURES): Define for s390/s390x.
+	(FFI_TRAMPOLINE_SIZE): Likewise.
+	(FFI_NATIVE_RAW_API): Likewise.
+	* src/prep_cif.c (ffi_prep_cif): Do not compute stack space for s390.
+	* src/types.c (FFI_TYPE_POINTER): Use 8-byte pointers on s390x.
+	* src/s390/ffi.c: Major rework of existing code.  Add support for
+	s390x targets.  Add closure support.
+	* src/s390/sysv.S: Likewise.
+
+2002-09-29  Richard Earnshaw  <rearnsha at arm.com>
+
+	* src/arm/sysv.S: Fix typo.
+
+2002-09-28  Richard Earnshaw  <rearnsha at arm.com>
+
+	* src/arm/sysv.S: If we don't have machine/asm.h and the pre-processor
+	has defined __USER_LABEL_PREFIX__, then use it in CNAME.
+	(ffi_call_SYSV): Handle soft-float.
+
+2002-09-27  Bo Thorsen  <bo at suse.de>
+
+	* include/ffi.h.in: Fix multilib x86-64 support.
+
+2002-09-22  Kaveh R. Ghazi  <ghazi at caip.rutgers.edu>
+
+	* Makefile.am (all-multi): Fix multilib parallel build.
+
+2002-07-19  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* configure.in (sh[34]*-*-linux*): Add brackets.
+	* configure: Regenerate.
+
+2002-07-18  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* Makefile.am: Add SH support.
+	* Makefile.in: Regenerate.
+	* configure.in (sh-*-linux*, sh[34]*-*-linux*): Add target.
+	* configure: Regenerate.
+	* include/ffi.h.in: Add SH support.
+	* src/sh/ffi.c: New file.
+	* src/sh/sysv.S: New file.
+	* src/types.c: Add SH support.
+
+2002-07-16  Bo Thorsen  <bo at suse.de>
+
+	* src/x86/ffi64.c: New file that adds x86-64 support.
+	* src/x86/unix64.S: New file that handles argument setup for
+	x86-64.
+	* src/x86/sysv.S: Don't use this on x86-64.
+	* src/x86/ffi.c: Don't use this on x86-64.
+	Remove unused vars.
+	* src/prep_cif.c (ffi_prep_cif): Don't do stack size calculation
+	for x86-64.
+	* src/ffitest.c (struct6): New test that tests a special case in
+	the x86-64 ABI.
+	(struct7): Likewise.
+	(struct8): Likewise.
+	(struct9): Likewise.
+	(closure_test_fn): Silence warning about this when it's not used.
+	(main): Add the new tests.
+	(main): Fix a couple of wrong casts and silence some compiler warnings.
+	* include/ffi.h.in: Add x86-64 ABI definition.
+	* fficonfig.h.in: Regenerate.
+	* Makefile.am: Add x86-64 support.
+	* configure.in: Likewise.
+	* Makefile.in: Regenerate.
+	* configure: Likewise.
+
+2002-06-24  Bo Thorsen  <bo at suse.de>
+
+	* src/types.c: Merge settings for similar architectures.
+	Add x86-64 sizes and alignments.
+
+2002-06-23  Bo Thorsen  <bo at suse.de>
+
+	* src/arm/ffi.c (ffi_prep_args): Remove unused vars.
+	* src/sparc/ffi.c (ffi_prep_args_v8): Likewise.
+	* src/mips/ffi.c (ffi_prep_args): Likewise.
+	* src/m68k/ffi.c (ffi_prep_args): Likewise.
+
+2002-07-18  H.J. Lu  (hjl at gnu.org)
+
+	* Makefile.am (TARGET_SRC_MIPS_LINUX): New.
+	(libffi_la_SOURCES): Support MIPS_LINUX.
+	(libffi_convenience_la_SOURCES): Likewise.
+	* Makefile.in: Regenerated.
+
+	* configure.in (mips64*-*): Skip.
+	(mips*-*-linux*): New.
+	* configure: Regenerated.
+
+	* src/mips/ffi.c: Include <sgidefs.h>.
+
+2002-06-06  Ulrich Weigand  <uweigand at de.ibm.com>
+
+	* src/s390/sysv.S: Save/restore %r6.  Add DWARF-2 unwind info.
+
+2002-05-27  Roger Sayle  <roger at eyesopen.com>
+
+	* src/x86/ffi.c (ffi_prep_args): Remove reference to avn.
+
+2002-05-27  Bo Thorsen  <bo at suse.de>
+
+	* src/x86/ffi.c (ffi_prep_args): Remove unused variable and
+	fix formatting.
+
+2002-05-13  Andreas Tobler  <a.tobler at schweiz.ch>
+
+	* src/powerpc/ffi_darwin.c (ffi_prep_closure): Declare fd at
+	beginning of function (for older apple cc).
+
+2002-05-08  Alexandre Oliva  <aoliva at redhat.com>
+
+	* configure.in (ORIGINAL_LD_FOR_MULTILIBS): Preserve LD at
+	script entry, and set LD to it when configuring multilibs.
+	* configure: Rebuilt.
+
+2002-05-05  Jason Thorpe  <thorpej at wasabisystems.com>
+
+	* configure.in (sparc64-*-netbsd*): Add target.
+	(sparc-*-netbsdelf*): Likewise.
+	* configure: Regenerate.
+
+2002-04-28  David S. Miller  <davem at redhat.com>
+
+	* configure.in, configure: Fix SPARC test in previous change.
+
+2002-04-29  Gerhard Tonn  <GerhardTonn at swol.de>
+
+	* Makefile.am: Add Linux for S/390 support.
+	* Makefile.in: Regenerate.
+	* configure.in: Add Linux for S/390 support.
+	* configure: Regenerate.
+	* include/ffi.h.in: Add Linux for S/390 support.
+	* src/s390/ffi.c: New file from libffi CVS tree.
+	* src/s390/sysv.S: New file from libffi CVS tree.
+
+2002-04-28  Jakub Jelinek  <jakub at redhat.com>
+
+	* configure.in (HAVE_AS_SPARC_UA_PCREL): Check for working
+	%r_disp32().
+	* src/sparc/v8.S: Use it.
+	* src/sparc/v9.S: Likewise.
+	* fficonfig.h.in: Rebuilt.
+	* configure: Rebuilt.
+
+2002-04-08  Hans Boehm  <Hans_Boehm at hp.com>
+
+	* src/java_raw_api.c (ffi_java_raw_size): Handle FFI_TYPE_DOUBLE
+	correctly.
+	* src/ia64/unix.S: Add unwind information. Fix comments.
+	Save sp in a way that's compatible with unwind info.
+	(ffi_call_unix): Correctly restore sp in all cases.
+	* src/ia64/ffi.c: Add, fix comments.
+
+2002-04-08  Jakub Jelinek  <jakub at redhat.com>
+
+	* src/sparc/v8.S: Make .eh_frame dependent on target word size.
+
+2002-04-06  Jason Thorpe  <thorpej at wasabisystems.com>
+
+	* configure.in (alpha*-*-netbsd*): Add target.
+	* configure: Regenerate.
+
+2002-04-04  Jeff Sturm  <jsturm at one-point.com>
+
+	* src/sparc/v8.S: Add unwind info.
+	* src/sparc/v9.S: Likewise.
+
+2002-03-30  Krister Walfridsson  <cato at df.lth.se>
+
+	* configure.in: Enable i*86-*-netbsdelf*.
+	* configure: Rebuilt.
+
+2002-03-29  David Billinghurst <David.Billinghurst at riotinto.com>
+
+	PR other/2620
+	* src/mips/n32.s: Delete
+	* src/mips/o32.s: Delete
+
+2002-03-21  Loren J. Rittle  <ljrittle at acm.org>
+
+	* configure.in: Enable alpha*-*-freebsd*.
+	* configure: Rebuilt.
+
+2002-03-17  Bryce McKinlay  <bryce at waitaki.otago.ac.nz>
+
+	* Makefile.am: libfficonvenience -> libffi_convenience.
+	* Makefile.in: Rebuilt.
+
+	* Makefile.am: Define ffitest_OBJECTS.
+	* Makefile.in: Rebuilt.
+
+2002-03-07  Andreas Tobler  <toa at pop.agri.ch>
+	    David Edelsohn  <edelsohn at gnu.org>
+
+	* Makefile.am (EXTRA_DIST): Add Darwin and AIX closure files.
+	(TARGET_SRC_POWERPC_AIX): Add aix_closure.S.
+	(TARGET_SRC_POWERPC_DARWIN): Add darwin_closure.S.
+	* Makefile.in: Regenerate.
+	* include/ffi.h.in: Add AIX and Darwin closure definitions.
+	* src/powerpc/ffi_darwin.c (ffi_prep_closure): New function.
+	(flush_icache, flush_range): New functions.
+	(ffi_closure_helper_DARWIN): New function.
+	* src/powerpc/aix_closure.S: New file.
+	* src/powerpc/darwin_closure.S: New file.
+
+2002-02-24  Jeff Sturm  <jsturm at one-point.com>
+
+	* include/ffi.h.in: Add typedef for ffi_arg.
+	* src/ffitest.c (main): Declare rint with ffi_arg.
+
+2002-02-21  Andreas Tobler  <toa at pop.agri.ch>
+
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Skip appropriate
+	number of GPRs for floating-point arguments.
+
+2002-01-31  Anthony Green  <green at redhat.com>
+
+	* configure: Rebuilt.
+	* configure.in: Replace CHECK_SIZEOF and endian tests with
+	cross-compiler friendly macros.
+	* aclocal.m4 (AC_COMPILE_CHECK_SIZEOF, AC_C_BIGENDIAN_CROSS): New
+	macros.
+
+2002-01-18  David Edelsohn  <edelsohn at gnu.org>
+
+	* src/powerpc/darwin.S (_ffi_call_AIX): New.
+	* src/powerpc/aix.S (ffi_call_DARWIN): New.
+
+2002-01-17  David Edelsohn  <edelsohn at gnu.org>
+
+	* Makefile.am (EXTRA_DIST): Add Darwin and AIX files.
+	(TARGET_SRC_POWERPC_AIX): New.
+	(POWERPC_AIX): New stanza.
+	* Makefile.in: Regenerate.
+	* configure.in: Add AIX case.
+	* configure: Regenerate.
+	* include/ffi.h.in (ffi_abi): Add FFI_AIX.
+	* src/powerpc/ffi_darwin.c (ffi_status): Use "long" to scale frame
+	size.  Fix "long double" support.
+	(ffi_call): Add FFI_AIX case.
+	* src/powerpc/aix.S: New.
+
+2001-10-09  John Hornkvist  <john at toastedmarshmallow.com>
+
+	Implement Darwin PowerPC ABI.
+	* configure.in: Handle powerpc-*-darwin*.
+	* Makefile.am: Set source files for POWERPC_DARWIN.
+	* configure: Rebuilt.
+	* Makefile.in: Rebuilt.
+	* include/ffi.h.in: Define FFI_DARWIN and FFI_DEFAULT_ABI for
+	POWERPC_DARWIN.
+	* src/powerpc/darwin.S: New file.
+	* src/powerpc/ffi_darwin.c: New file.
+
+2001-10-07  Joseph S. Myers  <jsm28 at cam.ac.uk>
+
+	* src/x86/ffi.c: Fix spelling error of "separate" as "seperate".
+
+2001-07-16  Rainer Orth  <ro at TechFak.Uni-Bielefeld.DE>
+
+	* src/x86/sysv.S: Avoid gas-only .balign directive.
+	Use C style comments.
+
+2001-07-16  Rainer Orth  <ro at TechFak.Uni-Bielefeld.DE>
+
+	* src/alpha/ffi.c (ffi_prep_closure): Avoid gas-only mnemonic.
+	Fixes PR bootstrap/3563.
+
+2001-06-26  Rainer Orth  <ro at TechFak.Uni-Bielefeld.DE>
+
+	* src/alpha/osf.S (ffi_closure_osf): Use .rdata for ECOFF.
+
+2001-06-25  Rainer Orth  <ro at TechFak.Uni-Bielefeld.DE>
+
+	* configure.in: Recognize sparc*-sun-* host.
+	* configure: Regenerate.
+
+2001-06-06  Andrew Haley  <aph at redhat.com>
+
+	* src/alpha/osf.S (__FRAME_BEGIN__): Conditionalize for ELF.
+
+2001-06-03  Andrew Haley  <aph at redhat.com>
+
+	* src/alpha/osf.S: Add unwind info.
+	* src/powerpc/sysv.S: Add unwind info.
+	* src/powerpc/ppc_closure.S: Likewise.
+
+2000-05-31  Jeff Sturm  <jsturm at one-point.com>
+
+	* configure.in: Fix AC_ARG_ENABLE usage.
+	* configure: Rebuilt.
+
+2001-05-06  Bryce McKinlay  <bryce at waitaki.otago.ac.nz>
+
+	* configure.in: Remove warning about beta code.
+	* configure: Rebuilt.
+
+2001-04-25  Hans Boehm <Hans_Boehm at hp.com>
+
+	* src/ia64/unix.S: Restore stack pointer when returning from
+	ffi_closure_UNIX.
+	* src/ia64/ffi.c: Fix typo in comment.
+
+2001-04-18  Jim Wilson  <wilson at redhat.com>
+
+	* src/ia64/unix.S: Delete unnecessary increment and decrement of loc2
+	to eliminate RAW DV.
+
+2001-04-12  Bryce McKinlay  <bryce at albatross.co.nz>
+
+	* Makefile.am: Make a libtool convenience library.
+	* Makefile.in: Rebuilt.
+
+2001-03-29  Bryce McKinlay  <bryce at albatross.co.nz>
+
+	* configure.in: Use different syntax for subdirectory creation.
+	* configure: Rebuilt.
+
+2001-03-27  Jon Beniston  <jon at beniston.com>
+
+	* configure.in: Added X86_WIN32 target (Win32, CygWin, MingW).
+	* configure: Rebuilt.
+	* Makefile.am: Added X86_WIN32 target support.
+	* Makefile.in: Rebuilt.
+
+	* include/ffi.h.in: Added X86_WIN32 target support.
+
+	* src/ffitest.c: Doesn't run structure tests for X86_WIN32 targets.
+	* src/types.c: Added X86_WIN32 target support.
+
+	* src/x86/win32.S: New file. Based on sysv.S, but with EH
+	stuff removed and made to work with CygWin's gas.
+
+2001-03-26  Bryce McKinlay  <bryce at albatross.co.nz>
+
+	* configure.in: Make target subdirectory in build dir.
+	* Makefile.am: Override suffix based rules to specify correct output
+	subdirectory.
+	* Makefile.in: Rebuilt.
+	* configure: Rebuilt.
+
+2001-03-23  Kevin B Hendricks  <khendricks at ivey.uwo.ca>
+
+	* src/powerpc/ppc_closure.S: New file.
+	* src/powerpc/ffi.c (ffi_prep_args): Fixed ABI compatibility bug
+	involving long long and register pairs.
+	(ffi_prep_closure): New function.
+	(flush_icache): Likewise.
+	(ffi_closure_helper_SYSV): Likewise.
+	* include/ffi.h.in (FFI_CLOSURES): Define on PPC.
+	(FFI_TRAMPOLINE_SIZE): Likewise.
+	(FFI_NATIVE_RAW_API): Likewise.
+	* Makefile.in: Rebuilt.
+	* Makefile.am (EXTRA_DIST): Added src/powerpc/ppc_closure.S.
+	(TARGET_SRC_POWERPC): Likewise.
+
+2001-03-19  Tom Tromey  <tromey at redhat.com>
+
+	* Makefile.in: Rebuilt.
+	* Makefile.am (ffitest_LDFLAGS): New macro.
+
+2001-03-02  Nick Clifton  <nickc at redhat.com>
+
+	* include/ffi.h.in: Remove RCS ident string.
+	* include/ffi_mips.h: Remove RCS ident string.
+	* src/debug.c: Remove RCS ident string.
+	* src/ffitest.c: Remove RCS ident string.
+	* src/prep_cif.c: Remove RCS ident string.
+	* src/types.c: Remove RCS ident string.
+	* src/alpha/ffi.c: Remove RCS ident string.
+	* src/alpha/osf.S: Remove RCS ident string.
+	* src/arm/ffi.c: Remove RCS ident string.
+	* src/arm/sysv.S: Remove RCS ident string.
+	* src/mips/ffi.c: Remove RCS ident string.
+	* src/mips/n32.S: Remove RCS ident string.
+	* src/mips/o32.S: Remove RCS ident string.
+	* src/sparc/ffi.c: Remove RCS ident string.
+	* src/sparc/v8.S: Remove RCS ident string.
+	* src/sparc/v9.S: Remove RCS ident string.
+	* src/x86/ffi.c: Remove RCS ident string.
+	* src/x86/sysv.S: Remove RCS ident string.
+
+2001-02-08  Joseph S. Myers  <jsm28 at cam.ac.uk>
+
+	* include/ffi.h.in: Change sourceware.cygnus.com references to
+	gcc.gnu.org.
+
+2000-12-09  Richard Henderson  <rth at redhat.com>
+
+	* src/alpha/ffi.c (ffi_call): Simplify struct return test.
+	(ffi_closure_osf_inner): Index rather than increment avalue
+	and arg_types.  Give ffi_closure_osf the raw return value type.
+	* src/alpha/osf.S (ffi_closure_osf): Handle return value type
+	promotion.
+
+2000-12-07  Richard Henderson  <rth at redhat.com>
+
+	* src/raw_api.c (ffi_translate_args): Fix typo.
+	(ffi_prep_closure): Likewise.
+
+	* include/ffi.h.in [ALPHA]: Define FFI_CLOSURES and
+	FFI_TRAMPOLINE_SIZE.
+	* src/alpha/ffi.c (ffi_prep_cif_machdep): Adjust minimal
+	cif->bytes for new ffi_call_osf implementation.
+	(ffi_prep_args): Absorb into ...
+	(ffi_call): ... here.  Do all stack allocation here and
+	avoid a callback function.
+	(ffi_prep_closure, ffi_closure_osf_inner): New.
+	* src/alpha/osf.S (ffi_call_osf): Reimplement with no callback.
+	(ffi_closure_osf): New.
+
+2000-09-10  Alexandre Oliva  <aoliva at redhat.com>
+
+	* config.guess, config.sub, install-sh: Removed.
+	* ltconfig, ltmain.sh, missing, mkinstalldirs: Likewise.
+	* Makefile.in: Rebuilt.
+
+	* acinclude.m4: Include libtool macros from the top level.
+	* aclocal.m4, configure: Rebuilt.
+
+2000-08-22  Alexandre Oliva  <aoliva at redhat.com>
+
+	* configure.in [i*86-*-freebsd*] (TARGET, TARGETDIR): Set.
+	* configure: Rebuilt.
+
+2000-05-11  Scott Bambrough  <scottb at netwinder.org>
+
+	* libffi/src/arm/sysv.S (ffi_call_SYSV): Doubles are not saved to
+	memory correctly.  Use conditional instructions, not branches where
+	possible.
+
+2000-05-04  Tom Tromey  <tromey at cygnus.com>
+
+	* configure: Rebuilt.
+	* configure.in: Match `arm*-*-linux-*'.
+	From Chris Dornan <cdornan at arm.com>.
+
+2000-04-28  Jakub Jelinek  <jakub at redhat.com>
+
+	* Makefile.am (SUBDIRS): Define.
+	(AM_MAKEFLAGS): Likewise.
+	(Multilib support.): Add section.
+	* Makefile.in: Rebuilt.
+	* ltconfig (extra_compiler_flags, extra_compiler_flags_value):
+	New variables. Set for gcc using -print-multi-lib. Export them
+	to libtool.
+	(sparc64-*-linux-gnu*): Use libsuff 64 for search paths.
+	* ltmain.sh (B|b|V): Don't throw away gcc's -B, -b and -V options
+	for -shared links.
+	(extra_compiler_flags_value, extra_compiler_flags): Check these
+	for extra compiler options which need to be passed down in
+	compiler_flags.
+
+2000-04-16  Anthony Green  <green at redhat.com>
+
+	* configure: Rebuilt.
+	* configure.in: Change i*86-pc-linux* to i*86-*-linux*.
+
+2000-04-14  Jakub Jelinek  <jakub at redhat.com>
+
+	* include/ffi.h.in (SPARC64): Define for 64bit SPARC builds.
+	Set SPARC FFI_DEFAULT_ABI based on SPARC64 define.
+	* src/sparc/ffi.c (ffi_prep_args_v8): Renamed from ffi_prep_args.
+	Replace all void * sizeofs with sizeof(int).
+	Only compare type with FFI_TYPE_LONGDOUBLE if LONGDOUBLE is
+	different than DOUBLE.
+	Remove FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases (handled elsewhere).
+	(ffi_prep_args_v9): New function.
+	(ffi_prep_cif_machdep): Handle V9 ABI and long long on V8.
+	(ffi_V9_return_struct): New function.
+	(ffi_call): Handle FFI_V9 ABI from 64bit code and FFI_V8 ABI from
+	32bit code (not yet cross-arch calls).
+	* src/sparc/v8.S: Add struct return delay nop.
+	Handle long long.
+	* src/sparc/v9.S: New file.
+	* src/prep_cif.c (ffi_prep_cif): Return structure pointer
+	is used on sparc64 only for structures larger than 32 bytes.
+	Pass by reference for structures is done for structure arguments
+	larger than 16 bytes.
+	* src/ffitest.c (main): Use 64bit rint on sparc64.
+	Run long long tests on sparc.
+	* src/types.c (FFI_TYPE_POINTER): Pointer is 64bit on alpha and
+	sparc64.
+	(FFI_TYPE_LONGDOUBLE): long double is 128 bit aligned to 128 bits
+	on sparc64.
+	* configure.in (sparc-*-linux*): New supported target.
+	(sparc64-*-linux*): Likewise.
+	* configure: Rebuilt.
+	* Makefile.am: Add v9.S to SPARC files.
+	* Makefile.in: Likewise.
+	(LINK): Surround $(CCLD) into double quotes, so that multilib
+	compiles work correctly.
+
+2000-04-04  Alexandre Petit-Bianco  <apbianco at cygnus.com>
+
+	* configure: Rebuilt.
+	* configure.in: (i*86-*-solaris*): New libffi target. Patch
+	proposed by Bryce McKinlay.
+
+2000-03-20  Tom Tromey  <tromey at cygnus.com>
+
+	* Makefile.in: Hand edit for java_raw_api.lo.
+
+2000-03-08  Bryce McKinlay  <bryce at albatross.co.nz>
+
+	* config.guess, config.sub: Update from the gcc tree.
+	Fix for PR libgcj/168.
+
+2000-03-03  Tom Tromey  <tromey at cygnus.com>
+
+	* Makefile.in: Fixed ia64 by hand.
+
+	* configure: Rebuilt.
+	* configure.in (--enable-multilib): New option.
+	(libffi_basedir): New subst.
+	(AC_OUTPUT): Added multilib code.
+
+2000-03-02  Tom Tromey  <tromey at cygnus.com>
+
+	* Makefile.in: Rebuilt.
+	* Makefile.am (TARGET_SRC_IA64): Use `ia64', not `alpha', as
+	directory name.
+
+2000-02-25  Hans Boehm <boehm at acm.org>
+
+	* src/ia64/ffi.c, src/ia64/ia64_flags.h, src/ia64/unix.S: New
+	files.
+	* src/raw_api.c (ffi_translate_args): Fixed typo in argument
+	list.
+	(ffi_prep_raw_closure): Use ffi_translate_args, not
+	ffi_closure_translate.
+	* src/java_raw_api.c: New file.
+	* src/ffitest.c (closure_test_fn): New function.
+	(main): Define `rint' as long long on IA64.  Added new test when
+	FFI_CLOSURES is defined.
+	* include/ffi.h.in (ALIGN): Use size_t, not unsigned.
+	(ffi_abi): Recognize IA64.
+	(ffi_raw): Added `flt' field.
+	Added "Java raw API" code.
+	* configure.in: Recognize ia64.
+	* Makefile.am (TARGET_SRC_IA64): New macro.
+	(libffi_la_common_SOURCES): Added java_raw_api.c.
+	(libffi_la_SOURCES): Define in IA64 case.
+
+2000-01-04  Tom Tromey  <tromey at cygnus.com>
+
+	* Makefile.in: Rebuilt with newer automake.
+
+1999-12-31  Tom Tromey  <tromey at cygnus.com>
+
+	* Makefile.am (INCLUDES): Added -I$(top_srcdir)/src.
+
+1999-09-01  Tom Tromey  <tromey at cygnus.com>
+
+	* include/ffi.h.in: Removed PACKAGE and VERSION defines and
+	undefs.
+	* fficonfig.h.in: Rebuilt.
+	* configure: Rebuilt.
+	* configure.in: Pass 3rd argument to AM_INIT_AUTOMAKE.
+	Use AM_PROG_LIBTOOL (automake 1.4 compatibility).
+	* acconfig.h: Don't #undef PACKAGE or VERSION.
+
+1999-08-09  Anthony Green  <green at cygnus.com>
+
+	* include/ffi.h.in: Try to work around messy header problem
+	with PACKAGE and VERSION.
+
+	* configure: Rebuilt.
+	* configure.in: Change version to 2.00-beta.
+
+	* fficonfig.h.in: Rebuilt.
+	* acconfig.h (FFI_NO_STRUCTS, FFI_NO_RAW_API): Define.
+
+	* src/x86/ffi.c (ffi_raw_call): Rename.
+
+1999-08-02  Kresten Krab Thorup  <krab at dominiq.is.s.u-tokyo.ac.jp>
+
+	* src/x86/ffi.c (ffi_closure_SYSV): New function.
+	(ffi_prep_incoming_args_SYSV): Ditto.
+	(ffi_prep_closure): Ditto.
+	(ffi_closure_raw_SYSV): Ditto.
+	(ffi_prep_raw_closure): More ditto.
+	(ffi_call_raw): Final ditto.
+
+	* include/ffi.h.in: Add definitions for closure and raw API.
+
+	* src/x86/ffi.c (ffi_prep_cif_machdep): Added case for
+	FFI_TYPE_UINT64.
+
+	* Makefile.am (libffi_la_common_SOURCES): Added raw_api.c
+
+	* src/raw_api.c: New file.
+
+	* include/ffi.h.in (ffi_raw): New type.
+	(UINT_ARG, SINT_ARG): New defines.
+	(ffi_closure, ffi_raw_closure): New types.
+	(ffi_prep_closure, ffi_prep_raw_closure): New declarations.
+
+	* configure.in: Add check for endianness and sizeof void*.
+
+	* src/x86/sysv.S (ffi_call_SYSV): Call fixup routine via argument,
+	instead of directly.
+
+	* configure: Rebuilt.
+
+Thu Jul  8 14:28:42 1999  Anthony Green  <green at cygnus.com>
+
+	* configure.in: Add x86 and powerpc BeOS configurations.
+	From Makoto Kato <m_kato at ga2.so-net.ne.jp>.
+
+1999-05-09  Anthony Green  <green at cygnus.com>
+
+	* configure.in: Add warning about this being beta code.
+	Remove src/Makefile.am from the picture.
+	* configure: Rebuilt.
+
+	* Makefile.am: Move logic from src/Makefile.am.  Add changes
+	to support libffi as a target library.
+	* Makefile.in: Rebuilt.
+
+	* aclocal.m4, config.guess, config.sub, ltconfig, ltmain.sh:
+	Upgraded to new autoconf, automake, libtool.
+
+	* README: Tweaks.
+
+	* LICENSE: Update copyright date.
+
+	* src/Makefile.am, src/Makefile.in: Removed.
+
+1998-11-29  Anthony Green  <green at cygnus.com>
+
+	* include/ChangeLog: Removed.
+	* src/ChangeLog: Removed.
+	* src/mips/ChangeLog: Removed.
+	* src/sparc/ChangeLog: Remboved.
+	* src/x86/ChangeLog: Removed.
+
+	* ChangeLog.v1: Created.
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/ChangeLog.libffi b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/ChangeLog.libffi
new file mode 100755
index 0000000..f3ee8b0
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/ChangeLog.libffi
@@ -0,0 +1,584 @@
+2011-02-08  Andreas Tobler  <andreast at fgznet.ch>
+
+	* testsuite/lib/libffi.exp: Tweak for stand-alone mode.
+
+2009-12-25  Samuli Suominen  <ssuominen at gentoo.org>
+
+	* configure.ac: Undefine _AC_ARG_VAR_PRECIOUS for autoconf 2.64.
+	* configure: Rebuilt.
+	* fficonfig.h.in: Rebuilt.
+
+2009-06-16  Andrew Haley  <aph at redhat.com>
+
+	* testsuite/libffi.call/cls_align_sint64.c,
+	testsuite/libffi.call/cls_align_uint64.c,
+	testsuite/libffi.call/cls_longdouble_va.c,
+	testsuite/libffi.call/cls_ulonglong.c,
+	testsuite/libffi.call/return_ll1.c,
+	testsuite/libffi.call/stret_medium2.c: Fix printf format
+	specifiers.
+	* testsuite/libffi.call/huge_struct.c: Ad x86 XFAILs.
+	* testsuite/libffi.call/float2.c: Fix dg-excess-errors.
+	* testsuite/libffi.call/ffitest.h,
+	testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define.
+
+2009-06-12  Andrew Haley  <aph at redhat.com>
+
+	* testsuite/libffi.call/cls_align_sint64.c,
+	testsuite/libffi.call/cls_align_uint64.c,
+	testsuite/libffi.call/cls_ulonglong.c,
+	testsuite/libffi.call/return_ll1.c,
+	testsuite/libffi.call/stret_medium2.c: Fix printf format
+	specifiers.
+	testsuite/libffi.special/unwindtest.cc: include stdint.h.
+
+2009-06-11  Timothy Wall  <twall at users.sf.net>
+
+	* Makefile.am,
+        configure.ac,
+        include/ffi.h.in,
+        include/ffi_common.h,
+        src/closures.c,
+        src/dlmalloc.c,
+        src/x86/ffi.c,
+        src/x86/ffitarget.h,
+        src/x86/win64.S (new),
+	README: Added win64 support (mingw or MSVC)
+        * Makefile.in,
+        include/Makefile.in,
+        man/Makefile.in,
+        testsuite/Makefile.in,
+        configure,
+        aclocal.m4: Regenerated
+        * ltcf-c.sh: properly escape cygwin/w32 path
+        * man/ffi_call.3: Clarify size requirements for return value.
+        * src/x86/ffi64.c: Fix filename in comment.
+        * src/x86/win32.S: Remove unused extern.
+
+        * testsuite/libffi.call/closure_fn0.c,
+        testsuite/libffi.call/closure_fn1.c,
+        testsuite/libffi.call/closure_fn2.c,
+        testsuite/libffi.call/closure_fn3.c,
+        testsuite/libffi.call/closure_fn4.c,
+        testsuite/libffi.call/closure_fn5.c,
+        testsuite/libffi.call/closure_fn6.c,
+	testsuite/libffi.call/closure_stdcall.c,
+	testsuite/libffi.call/cls_12byte.c,
+	testsuite/libffi.call/cls_16byte.c,
+	testsuite/libffi.call/cls_18byte.c,
+	testsuite/libffi.call/cls_19byte.c,
+	testsuite/libffi.call/cls_1_1byte.c,
+	testsuite/libffi.call/cls_20byte.c,
+	testsuite/libffi.call/cls_20byte1.c,
+	testsuite/libffi.call/cls_24byte.c,
+	testsuite/libffi.call/cls_2byte.c,
+	testsuite/libffi.call/cls_3_1byte.c,
+	testsuite/libffi.call/cls_3byte1.c,
+ 	testsuite/libffi.call/cls_3byte2.c,
+ 	testsuite/libffi.call/cls_4_1byte.c,
+ 	testsuite/libffi.call/cls_4byte.c,
+ 	testsuite/libffi.call/cls_5_1_byte.c,
+ 	testsuite/libffi.call/cls_5byte.c,
+ 	testsuite/libffi.call/cls_64byte.c,
+ 	testsuite/libffi.call/cls_6_1_byte.c,
+ 	testsuite/libffi.call/cls_6byte.c,
+ 	testsuite/libffi.call/cls_7_1_byte.c,
+ 	testsuite/libffi.call/cls_7byte.c,
+ 	testsuite/libffi.call/cls_8byte.c,
+ 	testsuite/libffi.call/cls_9byte1.c,
+ 	testsuite/libffi.call/cls_9byte2.c,
+ 	testsuite/libffi.call/cls_align_double.c,
+ 	testsuite/libffi.call/cls_align_float.c,
+ 	testsuite/libffi.call/cls_align_longdouble.c,
+ 	testsuite/libffi.call/cls_align_longdouble_split.c,
+ 	testsuite/libffi.call/cls_align_longdouble_split2.c,
+ 	testsuite/libffi.call/cls_align_pointer.c,
+ 	testsuite/libffi.call/cls_align_sint16.c,
+ 	testsuite/libffi.call/cls_align_sint32.c,
+ 	testsuite/libffi.call/cls_align_sint64.c,
+ 	testsuite/libffi.call/cls_align_uint16.c,
+ 	testsuite/libffi.call/cls_align_uint32.c,
+ 	testsuite/libffi.call/cls_align_uint64.c,
+ 	testsuite/libffi.call/cls_dbls_struct.c,
+ 	testsuite/libffi.call/cls_double.c,
+ 	testsuite/libffi.call/cls_double_va.c,
+ 	testsuite/libffi.call/cls_float.c,
+ 	testsuite/libffi.call/cls_longdouble.c,
+ 	testsuite/libffi.call/cls_longdouble_va.c,
+ 	testsuite/libffi.call/cls_multi_schar.c,
+ 	testsuite/libffi.call/cls_multi_sshort.c,
+ 	testsuite/libffi.call/cls_multi_sshortchar.c,
+ 	testsuite/libffi.call/cls_multi_uchar.c,
+ 	testsuite/libffi.call/cls_multi_ushort.c,
+ 	testsuite/libffi.call/cls_multi_ushortchar.c,
+ 	testsuite/libffi.call/cls_pointer.c,
+ 	testsuite/libffi.call/cls_pointer_stack.c,
+ 	testsuite/libffi.call/cls_schar.c,
+ 	testsuite/libffi.call/cls_sint.c,
+ 	testsuite/libffi.call/cls_sshort.c,
+ 	testsuite/libffi.call/cls_uchar.c,
+ 	testsuite/libffi.call/cls_uint.c,
+ 	testsuite/libffi.call/cls_ulonglong.c,
+ 	testsuite/libffi.call/cls_ushort.c,
+ 	testsuite/libffi.call/err_bad_abi.c,
+ 	testsuite/libffi.call/err_bad_typedef.c,
+ 	testsuite/libffi.call/float2.c,
+ 	testsuite/libffi.call/huge_struct.c,
+ 	testsuite/libffi.call/nested_struct.c,
+ 	testsuite/libffi.call/nested_struct1.c,
+ 	testsuite/libffi.call/nested_struct10.c,
+ 	testsuite/libffi.call/nested_struct2.c,
+ 	testsuite/libffi.call/nested_struct3.c,
+ 	testsuite/libffi.call/nested_struct4.c,
+ 	testsuite/libffi.call/nested_struct5.c,
+ 	testsuite/libffi.call/nested_struct6.c,
+ 	testsuite/libffi.call/nested_struct7.c,
+ 	testsuite/libffi.call/nested_struct8.c,
+ 	testsuite/libffi.call/nested_struct9.c,
+ 	testsuite/libffi.call/problem1.c,
+ 	testsuite/libffi.call/return_ldl.c,
+ 	testsuite/libffi.call/return_ll1.c,
+ 	testsuite/libffi.call/stret_large.c,
+ 	testsuite/libffi.call/stret_large2.c,
+ 	testsuite/libffi.call/stret_medium.c,
+ 	testsuite/libffi.call/stret_medium2.c,
+        testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead
+        of checking for MMAP.  Use intptr_t instead of long casts.
+
+2009-06-04  Andrew Haley  <aph at redhat.com>
+
+	* src/powerpc/ffitarget.h: Fix misapplied merge from gcc.
+
+2009-06-04  Andrew Haley  <aph at redhat.com>
+
+	* src/mips/o32.S,
+	src/mips/n32.S: Fix licence formatting.
+
+2009-06-04  Andrew Haley  <aph at redhat.com>
+
+	* src/x86/darwin.S: Fix licence formatting.
+	src/x86/win32.S: Likewise.
+	src/sh64/sysv.S: Likewise.
+	src/sh/sysv.S: Likewise.
+
+2009-06-04  Andrew Haley  <aph at redhat.com>
+
+	* src/sh64/ffi.c: Remove lint directives.  Was missing from merge
+	of Andreas Tobler's patch from 2006-04-22.
+	
+2009-06-04  Andrew Haley  <aph at redhat.com>
+
+	* src/sh/ffi.c: Apply missing hunk from Alexandre Oliva's patch of
+	2007-03-07.
+
+2008-12-26  Timothy Wall  <twall at users.sf.net>
+
+	* testsuite/libffi.call/cls_longdouble.c,
+        testsuite/libffi.call/cls_longdouble_va.c,
+        testsuite/libffi.call/cls_align_longdouble.c,
+        testsuite/libffi.call/cls_align_longdouble_split.c,
+        testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected
+        failures on x86_64 cygwin/mingw.
+
+2008-12-22  Timothy Wall  <twall at users.sf.net>
+
+	* testsuite/libffi.call/closure_fn0.c,
+        testsuite/libffi.call/closure_fn1.c,    
+        testsuite/libffi.call/closure_fn2.c,    
+        testsuite/libffi.call/closure_fn3.c,    
+        testsuite/libffi.call/closure_fn4.c,    
+        testsuite/libffi.call/closure_fn5.c,    
+        testsuite/libffi.call/closure_fn6.c,    
+        testsuite/libffi.call/closure_loc_fn0.c,    
+        testsuite/libffi.call/closure_stdcall.c,    
+        testsuite/libffi.call/cls_align_pointer.c,    
+        testsuite/libffi.call/cls_pointer.c,    
+        testsuite/libffi.call/cls_pointer_stack.c: use portable cast from
+        pointer to integer (intptr_t).
+        * testsuite/libffi.call/cls_longdouble.c: disable for win64.
+	
+2008-12-19  Anthony Green  <green at redhat.com>
+
+	* configure.ac: Bump version to 3.0.8.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.
+	* README: Update for new release.
+
+2008-11-11  Anthony Green  <green at redhat.com>
+
+	* configure.ac: Bump version to 3.0.7.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.
+	* README: Update for new release.
+
+2008-08-25  Andreas Tobler  <a.tobler at schweiz.org>
+
+	* src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and
+	FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum.
+	Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT.
+	Adjust copyright notice.
+	* src/powerpc/ffi.c: Add two new flags to indicate if we have one
+	register or two register to use for FFI_SYSV structs.
+	(ffi_prep_cif_machdep): Pass the right register flag introduced above.
+	(ffi_closure_helper_SYSV): Fix the return type for
+	FFI_SYSV_TYPE_SMALL_STRUCT. Comment.
+	Adjust copyright notice.
+
+2008-07-24  Anthony Green  <green at redhat.com>
+
+	* testsuite/libffi.call/cls_dbls_struct.c,
+	testsuite/libffi.call/cls_double_va.c,
+	testsuite/libffi.call/cls_longdouble.c,
+	testsuite/libffi.call/cls_longdouble_va.c,
+	testsuite/libffi.call/cls_pointer.c,
+	testsuite/libffi.call/cls_pointer_stack.c,
+	testsuite/libffi.call/err_bad_abi.c: Clean up failures from
+	compiler warnings.
+
+2008-07-17  Anthony Green  <green at redhat.com>
+
+	* configure.ac: Bump version to 3.0.6.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.  Add documentation.
+	* README: Update for new release.
+
+2008-07-16  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned
+	int.
+
+2008-07-16  Kaz Kojima  <kkojima at gcc.gnu.org>
+
+	* src/sh/sysv.S: Add .note.GNU-stack on Linux.
+	* src/sh64/sysv.S: Likewise.
+
+2008-04-03  Anthony Green  <green at redhat.com>
+
+	* libffi.pc.in (Libs): Add -L${libdir}.
+	* configure.ac: Bump version to 3.0.5.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.
+	* README: Update for new release.
+
+2008-04-03  Anthony Green  <green at redhat.com>
+	    Xerces Ranby  <xerxes at zafena.se>
+
+	* include/ffi.h.in: Wrap definition of target architecture to
+	protect from double definitions.
+
+2008-03-22  Moriyoshi Koizumi  <moriyoshi at gmail.com>
+
+	* src/x86/ffi.c (ffi_prep_closure_loc): Fix for bug revealed in
+	closure_loc_fn0.c.
+	* testsuite/libffi.call/closure_loc_fn0.c (closure_loc_test_fn0):
+	New test.
+
+2008-03-04  Anthony Green  <green at redhat.com>
+	    Blake Chaffin
+	    hos at tamanegi.org
+
+	* testsuite/libffi.call/cls_align_longdouble_split2.c
+          testsuite/libffi.call/cls_align_longdouble_split.c
+          testsuite/libffi.call/cls_dbls_struct.c
+          testsuite/libffi.call/cls_double_va.c
+          testsuite/libffi.call/cls_longdouble.c
+          testsuite/libffi.call/cls_longdouble_va.c
+          testsuite/libffi.call/cls_pointer.c
+          testsuite/libffi.call/cls_pointer_stack.c
+          testsuite/libffi.call/err_bad_abi.c
+          testsuite/libffi.call/err_bad_typedef.c
+          testsuite/libffi.call/huge_struct.c
+          testsuite/libffi.call/stret_large2.c
+          testsuite/libffi.call/stret_large.c
+          testsuite/libffi.call/stret_medium2.c
+          testsuite/libffi.call/stret_medium.c: New tests from Apple.
+
+2008-02-26  Jakub Jelinek  <jakub at redhat.com>
+            Anthony Green  <green at redhat.com>
+
+	* src/alpha/osf.S: Add .note.GNU-stack on Linux.
+	* src/s390/sysv.S: Likewise.
+	* src/powerpc/linux64.S: Likewise.
+	* src/powerpc/linux64_closure.S: Likewise.
+	* src/powerpc/ppc_closure.S: Likewise.
+	* src/powerpc/sysv.S: Likewise.
+	* src/x86/unix64.S: Likewise.
+	* src/x86/sysv.S: Likewise.
+	* src/sparc/v8.S: Likewise.
+	* src/sparc/v9.S: Likewise.
+	* src/m68k/sysv.S: Likewise.
+	* src/ia64/unix.S: Likewise.
+	* src/arm/sysv.S: Likewise.
+
+2008-02-26  Anthony Green  <green at redhat.com>
+            Thomas Heller  <theller at ctypes.org>
+
+	* src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C
+	comment.
+
+2008-02-26  Anthony Green  <green at redhat.org>
+            Thomas Heller  <theller at ctypes.org>
+
+	* include/ffi.h.in: Change void (*)() to void (*)(void).
+
+2008-02-26  Anthony Green  <green at redhat.org>
+            Thomas Heller  <theller at ctypes.org>
+
+	* src/alpha/ffi.c: Change void (*)() to void (*)(void).
+	src/alpha/osf.S, src/arm/ffi.c, src/frv/ffi.c, src/ia64/ffi.c,
+	src/ia64/unix.S, src/java_raw_api.c, src/m32r/ffi.c,
+	src/mips/ffi.c, src/pa/ffi.c, src/pa/hpux32.S, src/pa/linux.S,
+	src/powerpc/ffi.c, src/powerpc/ffi_darwin.c, src/raw_api.c,
+	src/s390/ffi.c, src/sh/ffi.c, src/sh64/ffi.c, src/sparc/ffi.c,
+	src/x86/ffi.c, src/x86/unix64.S, src/x86/darwin64.S,
+	src/x86/ffi64.c: Ditto.
+
+2008-02-24  Anthony Green  <green at redhat.org>
+
+	* configure.ac: Accept openbsd*, not just openbsd.
+	Bump version to 3.0.4.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.
+	* README: Update for new release.
+
+2008-02-22  Anthony Green  <green at redhat.com>
+
+	* README: Clean up list of tested platforms.
+
+2008-02-22  Anthony Green  <green at redhat.com>
+
+	* configure.ac: Bump version to 3.0.3.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.
+	* README: Update for new release.  Clean up test docs.
+
+2008-02-22  Bjoern Koenig  <bkoenig at alpha-tierchen.de>
+	    Andreas Tobler  <a.tobler at schweiz.org>
+
+	* configure.ac: Add amd64-*-freebsd* target.
+	* configure: Regenerate.
+
+2008-02-22  Thomas Heller <theller at ctypes.org>
+
+	* configure.ac: Add x86 OpenBSD support.
+	* configure: Rebuilt.
+
+2008-02-21  Thomas Heller <theller at ctypes.org>
+
+	* README: Change "make test" to "make check".
+
+2008-02-21  Anthony Green  <green at redhat.com>
+
+	* configure.ac: Bump version to 3.0.2.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.
+	* README: Update for new release.
+
+2008-02-21  Björn König <bkoenig at alpha-tierchen.de>
+
+	* src/x86/freebsd.S: New file.
+	* configure.ac: Add x86 FreeBSD support.
+	* Makefile.am: Ditto.
+
+2008-02-15  Anthony Green  <green at redhat.com>
+
+	* configure.ac: Bump version to 3.0.1.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.
+	* README: Update for new release.
+
+2008-02-15  David Daney	 <ddaney at avtrex.com>
+
+	* src/mips/ffi.c: Remove extra '>' from include directive.
+	(ffi_prep_closure_loc): Use clear_location instead of tramp.
+
+2008-02-15  Anthony Green  <green at redhat.com>
+
+	* configure.ac: Bump version to 3.0.0.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+
+2008-02-15  David Daney	 <ddaney at avtrex.com>
+
+	* src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE):
+	Define (conditionally), and use it to include cachectl.h.
+	(ffi_prep_closure_loc): Fix cache flushing.
+	* src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define.
+
+2008-02-15  Anthony Green  <green at redhat.com>
+
+        * man/ffi_call.3, man/ffi_prep_cif.3, man/ffi.3:
+	Update dates and remove all references to ffi_prep_closure.
+	* configure.ac: Bump version to 2.99.9.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+
+2008-02-15  Anthony Green  <green at redhat.com>
+
+	* man/ffi_prep_closure.3: Delete.
+	* man/Makefile.am (EXTRA_DIST): Remove ffi_prep_closure.3.
+	(man_MANS): Ditto.
+	* man/Makefile.in: Rebuilt.
+	* configure.ac: Bump version to 2.99.8.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+
+2008-02-14  Anthony Green  <green at redhat.com>
+
+	* configure.ac: Bump version to 2.99.7.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* include/ffi.h.in LICENSE src/debug.c src/closures.c
+          src/ffitest.c src/s390/sysv.S src/s390/ffitarget.h
+          src/types.c src/m68k/ffitarget.h src/raw_api.c src/frv/ffi.c
+          src/frv/ffitarget.h src/sh/ffi.c src/sh/sysv.S
+          src/sh/ffitarget.h src/powerpc/ffitarget.h src/pa/ffi.c
+          src/pa/ffitarget.h src/pa/linux.S src/java_raw_api.c
+          src/cris/ffitarget.h src/x86/ffi.c src/x86/sysv.S
+          src/x86/unix64.S src/x86/win32.S src/x86/ffitarget.h
+          src/x86/ffi64.c src/x86/darwin.S src/ia64/ffi.c
+          src/ia64/ffitarget.h src/ia64/ia64_flags.h src/ia64/unix.S
+          src/sparc/ffi.c src/sparc/v9.S src/sparc/ffitarget.h
+          src/sparc/v8.S src/alpha/ffi.c src/alpha/ffitarget.h
+          src/alpha/osf.S src/sh64/ffi.c src/sh64/sysv.S
+          src/sh64/ffitarget.h src/mips/ffi.c src/mips/ffitarget.h
+          src/mips/n32.S src/mips/o32.S src/arm/ffi.c src/arm/sysv.S
+          src/arm/ffitarget.h src/prep_cif.c: Update license text.
+
+2008-02-14  Anthony Green  <green at redhat.com>
+
+	* README: Update tested platforms.
+	* configure.ac: Bump version to 2.99.6.
+	* configure: Rebuilt.
+
+2008-02-14  Anthony Green  <green at redhat.com>
+
+	* configure.ac: Bump version to 2.99.5.
+	* configure: Rebuilt.
+	* Makefile.am (EXTRA_DIST): Add darwin64.S
+	* Makefile.in: Rebuilt.
+	* testsuite/lib/libffi-dg.exp: Remove libstdc++ bits from GCC tree.
+	* LICENSE: Update WARRANTY.
+
+2008-02-14  Anthony Green  <green at redhat.com>
+
+	* libffi.pc.in (libdir): Fix libdir definition.
+	* configure.ac: Bump version to 2.99.4.
+	* configure: Rebuilt.
+
+2008-02-14  Anthony Green  <green at redhat.com>
+
+	* README: Update.
+	* libffi.info: New file.
+	* doc/stamp-vti: New file.
+	* configure.ac: Bump version to 2.99.3.
+	* configure: Rebuilt.
+
+2008-02-14  Anthony Green  <green at redhat.com>
+
+	* Makefile.am (SUBDIRS): Add man dir.
+	* Makefile.in: Rebuilt.
+	* configure.ac: Create Makefile.
+	* configure: Rebuilt.
+        * man/ffi_call.3 man/ffi_prep_cif.3 man/ffi_prep_closure.3
+          man/Makefile.am man/Makefile.in: New files.
+
+2008-02-14  Tom Tromey  <tromey at redhat.com>
+
+	* aclocal.m4, Makefile.in, configure, fficonfig.h.in: Rebuilt.
+	* mdate-sh, texinfo.tex: New files.
+	* Makefile.am (info_TEXINFOS): New variable.
+	* doc/libffi.texi: New file.
+	* doc/version.texi: Likewise.
+
+2008-02-14  Anthony Green  <green at redhat.com>
+
+	* Makefile.am (AM_CFLAGS): Don't compile with -D$(TARGET).
+	(lib_LTLIBRARIES): Define.
+	(toolexeclib_LIBRARIES): Undefine.
+	* Makefile.in: Rebuilt.
+	* configure.ac: Reset version to 2.99.1.
+	* configure.in: Rebuilt.
+
+2008-02-14  Anthony Green  <green at redhat.com>
+
+	* libffi.pc.in: Use @PACKAGE_NAME@ and @PACKAGE_VERSION at .
+	* configure.ac: Reset version to 2.99.1.
+	* configure.in: Rebuilt.
+	* Makefile.am (EXTRA_DIST): Add ChangeLog.libffi.
+	* Makefile.in: Rebuilt.
+	* LICENSE: Update copyright notice.
+
+2008-02-14  Anthony Green  <green at redhat.com>
+
+	* include/Makefile.am (nodist_includes_HEADERS): Define.  Don't
+	distribute ffitarget.h or ffi.h from the build include dir.
+	* Makefile.in: Rebuilt.
+
+2008-02-14  Anthony Green  <green at redhat.com>
+
+	* include/Makefile.am (includesdir): Install headers under libdir.
+	(pkgconfigdir): Define. Install libffi.pc.
+	* include/Makefile.in: Rebuilt.
+	* libffi.pc.in: Create.
+	* libtool-version: Increment CURRENT
+	* configure.ac: Add libffi.pc.in
+	* configure: Rebuilt.
+
+2008-02-03  Anthony Green  <green at redhat.com>
+
+	* include/Makefile.am (includesdir): Fix header install with
+	DESTDIR.
+	* include/Makefile.in: Rebuilt.
+
+2008-02-03  Timothy Wall  <twall at users.sf.net>
+
+	* src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return
+          offset based on code pointer, not data pointer.
+
+2008-02-01  Anthony Green  <green at redhat.com>
+
+	* include/Makefile.am: Fix header installs.
+	* Makefile.am: Ditto.
+	* include/Makefile.in: Rebuilt.
+	* Makefile.in: Ditto.
+
+2008-02-01  Anthony Green  <green at redhat.com>
+
+	* src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL,
+	FFI_INIT_TRAMPOLINE): Revert my broken changes to twall's last
+	patch.
+
+2008-01-31  Anthony Green  <green at redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add missing files.
+	* testsuite/Makefile.am: Ditto.
+	* Makefile.in, testsuite/Makefile.in: Rebuilt.
+
+2008-01-31  Timothy Wall <twall at users.sf.net>
+
+	* testsuite/libffi.call/closure_stdcall.c: Add test for stdcall
+	closures.
+	* src/x86/ffitarget.h: Increase size of trampoline for stdcall
+	closures.
+	* src/x86/win32.S: Add assembly for stdcall closure.
+	* src/x86/ffi.c: Initialize stdcall closure trampoline.
+
+2008-01-30  H.J. Lu <hongjiu.lu at intel.com>
+
+	PR libffi/34612
+	* src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when
+	returning struct.
+
+	* testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer"
+	tests.
+
+2008-01-30  Anthony Green  <green at redhat.com>
+
+	* Makefile.am, include/Makefile.am: Move headers to
+	libffi_la_SOURCES for new automake.
+	* Makefile.in, include/Makefile.in: Rebuilt.
+	
+	* testsuite/lib/wrapper.exp: Copied from gcc tree to allow for 
+	execution outside of gcc tree.
+	* testsuite/lib/target-libpath.exp: Ditto.
+
+	* testsuite/lib/libffi-dg.exp: Many changes to allow for execution
+	outside of gcc tree.
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/ChangeLog.libgcj b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/ChangeLog.libgcj
new file mode 100755
index 0000000..ea5d02f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/ChangeLog.libgcj
@@ -0,0 +1,40 @@
+2004-01-14  Kelley Cook  <kcook at gcc.gnu.org>
+
+	* configure.in: Add in AC_PREREQ(2.13)
+
+2003-02-20  Alexandre Oliva  <aoliva at redhat.com>
+
+	* configure.in: Propagate ORIGINAL_LD_FOR_MULTILIBS to
+	config.status.
+	* configure: Rebuilt.
+
+2002-01-27  Alexandre Oliva  <aoliva at redhat.com>
+
+	* configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST.
+	Remove USE_LIBDIR conditional.
+	* Makefile.am (toolexecdir, toolexeclibdir): Don't override.
+	* Makefile.in, configure: Rebuilt.
+
+Mon Aug  9 18:33:38 1999  Rainer Orth  <ro at TechFak.Uni-Bielefeld.DE>
+
+	* include/Makefile.in: Rebuilt.
+	* Makefile.in: Rebuilt
+	* Makefile.am (toolexeclibdir): Add $(MULTISUBDIR) even for native
+	builds.
+	Use USE_LIBDIR.
+
+	* configure: Rebuilt.
+	* configure.in (USE_LIBDIR): Define for native builds.
+	Use lowercase in configure --help explanations.
+
+1999-08-08  Anthony Green  <green at cygnus.com>
+
+	* include/ffi.h.in (FFI_FN): Remove `...'.
+
+1999-08-08  Anthony Green  <green at cygnus.com>
+
+	* Makefile.in: Rebuilt.
+	* Makefile.am (AM_CFLAGS): Compile with -fexceptions.
+
+	* src/x86/sysv.S: Add exception handling metadata.
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/ChangeLog.v1 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/ChangeLog.v1
new file mode 100755
index 0000000..369820c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/ChangeLog.v1
@@ -0,0 +1,764 @@
+The libffi version 1 ChangeLog archive.
+
+Version 1 of libffi had per-directory ChangeLogs.  Current and future
+versions have a single ChangeLog file in the root directory.  The
+version 1 ChangeLogs have all been concatonated into this file for
+future reference only.
+
+--- libffi ----------------------------------------------------------------
+
+Mon Oct  5 02:17:50 1998  Anthony Green  <green at cygnus.com>
+
+	* configure.in: Boosted rev.
+	* configure, Makefile.in, aclocal.m4: Rebuilt.
+	* README: Boosted rev and updated release notes.
+
+Mon Oct  5 01:03:03 1998  Anthony Green  <green at cygnus.com>
+
+	* configure.in: Boosted rev.
+	* configure, Makefile.in, aclocal.m4: Rebuilt.
+	* README: Boosted rev and updated release notes.
+
+1998-07-25  Andreas Schwab  <schwab at issan.informatik.uni-dortmund.de>
+
+	* m68k/ffi.c (ffi_prep_cif_machdep): Use bitmask for cif->flags.
+	Correctly handle small structures.
+	(ffi_prep_args): Also handle small structures.
+	(ffi_call): Pass size of return type to ffi_call_SYSV.
+	* m68k/sysv.S: Adjust for above changes.  Correctly align small
+	structures in the return value.
+
+	* types.c (uint64, sint64) [M68K]: Change alignment to 4.
+
+Fri Apr 17 17:26:58 1998  Anthony Green  <green at hoser.cygnus.com>
+
+	* configure.in: Boosted rev.
+	* configure,Makefile.in,aclocal.m4: Rebuilt.
+	* README: Boosted rev and added release notes.
+
+Sun Feb 22 00:50:41 1998  Geoff Keating  <geoffk at ozemail.com.au>
+
+	* configure.in: Add PowerPC config bits.
+
+1998-02-14  Andreas Schwab  <schwab at issan.informatik.uni-dortmund.de>
+
+	* configure.in: Add m68k config bits.  Change AC_CANONICAL_SYSTEM
+	to AC_CANONICAL_HOST, this is not a compiler.  Use $host instead
+	of $target.  Remove AC_CHECK_SIZEOF(char), we already know the
+	result.  Fix argument of AC_ARG_ENABLE.
+	* configure, fficonfig.h.in: Rebuilt.
+
+Tue Feb 10 20:53:40 1998  Richard Henderson  <rth at cygnus.com>
+
+	* configure.in: Add Alpha config bits.
+
+Tue May 13 13:39:20 1997  Anthony Green  <green at hoser.cygnus.com>
+
+	* README: Updated dates and reworded Irix comments.
+
+	* configure.in: Removed AC_PROG_RANLIB.
+
+	* Makefile.in, aclocal.m4, config.guess, config.sub, configure,
+	ltmain.sh, */Makefile.in: libtoolized again and	rebuilt with 
+	automake and autoconf.
+	
+Sat May 10 18:44:50 1997  Tom Tromey  <tromey at cygnus.com>
+
+	* configure, aclocal.m4: Rebuilt.
+	* configure.in: Don't compute EXTRADIST; now handled in
+	src/Makefile.in.  Removed macros implied by AM_INIT_AUTOMAKE.
+	Don't run AM_MAINTAINER_MODE.
+
+Thu May  8 14:34:05 1997  Anthony Green  <green at hoser.cygnus.com>
+
+	* missing, ltmain.sh, ltconfig.sh: Created. These are new files
+	required by automake and libtool.
+
+	* README: Boosted rev to 1.14. Added notes.
+
+	* acconfig.h: Moved PACKAGE and VERSION for new automake.
+	
+	* configure.in: Changes for libtool.
+	
+	* Makefile.am (check): make test now make check. Uses libtool now.
+
+	* Makefile.in, configure.in, aclocal.h, fficonfig.h.in: Rebuilt.
+
+Thu May  1 16:27:07 1997  Anthony Green  <green at hoser.cygnus.com>
+
+	* missing: Added file required by new automake.
+
+Tue Nov 26 14:10:42 1996  Anthony Green  <green at csk3.cygnus.com>
+
+	* acconfig.h: Added USING_PURIFY flag. This is defined when
+	--enable-purify-safety was used at configure time.
+
+	* configure.in (allsources): Added --enable-purify-safety switch.
+	(VERSION): Boosted rev to 1.13.
+	* configure: Rebuilt.
+
+Fri Nov 22 06:46:12 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* configure.in (VERSION): Boosted rev to 1.12.
+	Removed special CFLAGS hack for gcc.
+	* configure: Rebuilt.
+
+	* README: Boosted rev to 1.12. Added notes.
+
+	* Many files: Cygnus Support changed to Cygnus Solutions.
+
+Wed Oct 30 11:15:25 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* configure.in (VERSION): Boosted rev to 1.11.
+	* configure: Rebuilt.
+
+	* README: Boosted rev to 1.11. Added notes about GNU make.
+
+Tue Oct 29 12:25:12 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* configure.in: Fixed -Wall trick.
+	(VERSION): Boosted rev.
+	* configure: Rebuilt
+
+	* acconfig.h: Needed for --enable-debug configure switch.
+
+	* README: Boosted rev to 1.09. Added more notes on building
+	libffi, and LCLint.
+
+	* configure.in: Added --enable-debug switch. Boosted rev to
+	1.09.
+	* configure: Rebuilt
+
+Tue Oct 15 13:11:28 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* configure.in (VERSION): Boosted rev to 1.08
+	* configure: Rebuilt.
+
+	* README: Added n32 bug fix notes.
+
+	* Makefile.am: Added "make lint" production. 
+	* Makefile.in: Rebuilt.
+
+Mon Oct 14 10:54:46 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* README: Added web page reference.
+
+	* configure.in, README: Boosted rev to 1.05
+	* configure: Rebuilt.
+
+	* README: Fixed n32 sample code.
+
+Fri Oct 11 17:09:28 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* README: Added sparc notes.
+
+	* configure.in, README: Boosted rev to 1.04.
+	* configure: Rebuilt.
+
+Thu Oct 10 10:31:03 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* configure.in, README: Boosted rev to 1.03.
+	* configure: Rebuilt.
+
+	* README: Added struct notes. 
+
+	* Makefile.am (EXTRA_DIST): Added LICENSE to distribution.
+	* Makefile.in: Rebuilt.
+
+	* README: Removed Linux section. No special notes now
+	because aggregates arg/return types work.
+
+Wed Oct  9 16:16:42 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* README, configure.in (VERSION): Boosted rev to 1.02
+	* configure: Rebuilt.
+
+Tue Oct  8 11:56:33 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* README (NOTE): Added n32 notes.
+
+	* Makefile.am: Added test production.
+	* Makefile: Rebuilt
+
+	* README: spell checked!
+
+	* configure.in (VERSION): Boosted rev to 1.01
+	* configure: Rebuilt.
+
+Mon Oct  7 15:50:22 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* configure.in: Added nasty bit to support SGI tools.
+	* configure: Rebuilt.
+	
+	* README: Added SGI notes. Added note about automake bug.
+
+Mon Oct  7 11:00:28 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* README: Rewrote intro, and fixed examples.
+
+Fri Oct  4 10:19:55 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* configure.in: -D$TARGET is no longer used as a compiler switch.
+	It is now inserted into ffi.h at configure time.
+	* configure: Rebuilt.
+
+	* FFI_ABI and FFI_STATUS are now ffi_abi and ffi_status.
+
+Thu Oct  3 13:47:34 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* README, LICENSE: Created. Wrote some docs.
+
+	* configure.in: Don't barf on i586-unknown-linuxaout.
+	Added EXTRADIST code for "make dist".
+	* configure: Rebuilt.
+
+	* */Makefile.in: Rebuilt with patched automake. 
+
+Tue Oct  1 17:12:25 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* Makefile.am, aclocal.m4, config.guess, config.sub,
+	configure.in, fficonfig.h.in, install-sh, mkinstalldirs, 
+	stamp-h.in: Created
+	* Makefile.in, configure: Generated
+
+--- libffi/include --------------------------------------------------------
+
+Tue Feb 24 13:09:36 1998  Anthony Green  <green at gerbil.cygnus.com>
+
+	* ffi_mips.h: Updated FFI_TYPE_STRUCT_* values based on
+	ffi.h.in changes.  This is a work-around for SGI's "simple"
+	assembler.
+
+Sun Feb 22 00:51:55 1998  Geoff Keating  <geoffk at ozemail.com.au>
+
+	* ffi.h.in: PowerPC support.
+
+1998-02-14  Andreas Schwab  <schwab at issan.informatik.uni-dortmund.de>
+
+	* ffi.h.in: Add m68k support.
+	(FFI_TYPE_LONGDOUBLE): Make it a separate value.
+
+Tue Feb 10 20:55:16 1998  Richard Henderson  <rth at cygnus.com>
+
+	* ffi.h.in (SIZEOF_ARG): Use a pointer type by default.
+
+	* ffi.h.in: Alpha support.
+
+Fri Nov 22 06:48:45 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi.h.in, ffi_common.h: Cygnus Support -> Cygnus Solutions.
+
+Wed Nov 20 22:31:01 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* ffi.h.in: Added ffi_type_void definition.
+
+Tue Oct 29 12:22:40 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* Makefile.am (hack_DATA): Always install ffi_mips.h.
+
+	* ffi.h.in: Removed FFI_DEBUG. It's now in the correct
+	place (acconfig.h).
+	Added #include <stddef.h> for size_t definition.
+
+Tue Oct 15 17:23:35 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* ffi.h.in, ffi_common.h, ffi_mips.h: More clean up.
+	Commented out #define of FFI_DEBUG.
+
+Tue Oct 15 13:01:06 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi_common.h: Added bool definition.
+
+	* ffi.h.in, ffi_common.h: Clean up based on LCLint output.
+	Added funny /*@...@*/ comments to annotate source.
+
+Mon Oct 14 12:29:23 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi.h.in: Interface changes based on feedback from Jim
+	Blandy.
+
+Fri Oct 11 16:49:35 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi.h.in: Small change for sparc support.
+
+Thu Oct 10 14:53:37 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi_mips.h: Added FFI_TYPE_STRUCT_* definitions for 
+	special structure return types.
+
+Wed Oct  9 13:55:57 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi.h.in: Added SIZEOF_ARG definition for X86
+
+Tue Oct  8 11:40:36 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi.h.in (FFI_FN): Added macro for eliminating compiler warnings.
+	Use it to case your function pointers to the proper type.
+
+	* ffi_mips.h (SIZEOF_ARG): Added magic to fix type promotion bug.
+
+	* Makefile.am (EXTRA_DIST): Added ffi_mips.h to EXTRA_DIST.
+	* Makefile: Rebuilt.
+
+	* ffi_mips.h: Created. Moved all common mips definitions here.
+
+Mon Oct  7 10:58:12 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* ffi.h.in: The SGI assember is very picky about parens. Redefined
+ 	some macros to avoid problems.
+
+	* ffi.h.in: Added FFI_DEFAULT_ABI definitions. Also added
+	externs for pointer, and 64bit integral ffi_types.
+
+Fri Oct  4 09:51:37 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* ffi.h.in: Added FFI_ABI member to ffi_cif and changed
+	function prototypes accordingly.
+	Added #define @TARGET at . Now programs including ffi.h don't 
+	have to specify this themselves.
+
+Thu Oct  3 15:36:44 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* ffi.h.in: Changed ffi_prep_cif's values from void* to void**
+
+	* Makefile.am (EXTRA_DIST): Added EXTRA_DIST for "make dist"
+	to work.
+	* Makefile.in: Regenerated.
+
+Wed Oct  2 10:16:59 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* Makefile.am: Created
+	* Makefile.in: Generated
+
+	* ffi_common.h: Added rcsid comment
+
+Tue Oct  1 17:13:51 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi.h.in, ffi_common.h: Created
+
+--- libffi/src ------------------------------------------------------------
+
+Mon Oct  5 02:17:50 1998  Anthony Green  <green at cygnus.com>
+
+	* arm/ffi.c, arm/sysv.S: Created.
+
+	* Makefile.am: Added arm files.
+	* Makefile.in: Rebuilt.
+
+Mon Oct  5 01:41:38 1998  Anthony Green  <green at rtl.cygnus.com>
+
+	* Makefile.am (libffi_la_LDFLAGS): Incremented revision.
+
+Sun Oct  4 16:27:17 1998  Anthony Green  <green at cygnus.com>
+
+	* alpha/osf.S (ffi_call_osf): Patch for DU assembler.
+
+	* ffitest.c (main): long long and long double return values work
+	for x86.
+
+Fri Apr 17 11:50:58 1998  Anthony Green  <green at hoser.cygnus.com>
+
+	* Makefile.in: Rebuilt.
+
+	* ffitest.c (main): Floating point tests not executed for systems
+ 	with broken lond double (SunOS 4 w/ GCC).
+
+	* types.c: Fixed x86 alignment info for long long types.
+
+Thu Apr 16 07:15:28 1998  Anthony Green  <green at ada.cygnus.com>
+
+	* ffitest.c: Added more notes about GCC bugs under Irix 6.
+
+Wed Apr 15 08:42:22 1998  Anthony Green  <green at hoser.cygnus.com>
+
+	* ffitest.c (struct5): New test function.
+	(main): New test with struct5.
+
+Thu Mar  5 10:48:11 1998  Anthony Green  <green at tootie.to.cygnus.com>
+
+	* prep_cif.c (initialize_aggregate): Fix assertion for
+	nested structures.
+
+Tue Feb 24 16:33:41 1998  Anthony Green  <green at hoser.cygnus.com>
+
+	* prep_cif.c (ffi_prep_cif): Added long double support for sparc.
+
+Sun Feb 22 00:52:18 1998  Geoff Keating  <geoffk at ozemail.com.au>
+
+	* powerpc/asm.h: New file.
+	* powerpc/ffi.c: New file.
+	* powerpc/sysv.S: New file.
+	* Makefile.am: PowerPC port.
+	* ffitest.c (main): Allow all tests to run even in presence of gcc
+ 	bug on PowerPC.
+
+1998-02-17  Anthony Green  <green at hoser.cygnus.com>
+
+	* mips/ffi.c: Fixed comment typo.
+
+	* x86/ffi.c (ffi_prep_cif_machdep), x86/sysv.S (retfloat): 
+	Fixed x86 long double return handling.
+
+	* types.c: Fixed x86 long double alignment info.
+
+1998-02-14  Andreas Schwab  <schwab at issan.informatik.uni-dortmund.de>
+
+	* types.c: Add m68k support.
+
+	* ffitest.c (floating): Add long double parameter.
+	(return_ll, ldblit): New functions to test long long and long
+	double return value.
+	(main): Fix type error in assignment of ts[1-4]_type.elements.
+	Add tests for long long and long double arguments and return
+	values.
+
+	* prep_cif.c (ffi_prep_cif) [M68K]: Don't allocate argument for
+	struct value pointer.
+
+	* m68k/ffi.c, m68k/sysv.S: New files.
+	* Makefile.am: Add bits for m68k port.  Add kludge to work around
+	automake deficiency.
+	(test): Don't require "." in $PATH.
+	* Makefile.in: Rebuilt.
+
+Wed Feb 11 07:36:50 1998  Anthony Green  <green at hoser.cygnus.com>
+
+	* Makefile.in: Rebuilt.
+
+Tue Feb 10 20:56:00 1998  Richard Henderson  <rth at cygnus.com>
+
+	* alpha/ffi.c, alpha/osf.S: New files.
+	* Makefile.am: Alpha port.
+
+Tue Nov 18 14:12:07 1997  Anthony Green  <green at hoser.cygnus.com>
+
+	* mips/ffi.c (ffi_prep_cif_machdep): Initialize rstruct_flag
+	for n32.
+
+Tue Jun  3 17:18:20 1997  Anthony Green  <green at hoser.cygnus.com>
+
+	* ffitest.c (main): Added hack to get structure tests working
+	correctly.
+
+Sat May 10 19:06:42 1997  Tom Tromey  <tromey at cygnus.com>
+
+	* Makefile.in: Rebuilt.
+	* Makefile.am (EXTRA_DIST): Explicitly list all distributable
+	files in subdirs.
+	(VERSION, CC): Removed.
+
+Thu May  8 17:19:01 1997  Anthony Green  <green at hoser.cygnus.com>
+
+	* Makefile.am: Many changes for new automake and libtool.
+	* Makefile.in: Rebuilt.
+
+Fri Nov 22 06:57:56 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffitest.c (main): Fixed test case for non mips machines.
+
+Wed Nov 20 22:31:59 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* types.c: Added ffi_type_void declaration.
+
+Tue Oct 29 13:07:19 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffitest.c (main): Fixed character constants.
+	(main): Emit warning for structure test 3 failure on Sun.
+
+	* Makefile.am (VPATH): Fixed VPATH def'n so automake won't
+	strip it out. 
+	Moved distdir hack from libffi to automake. 
+	(ffitest): Added missing -c for $(COMPILE) (change in automake).
+	* Makefile.in: Rebuilt.
+	
+Tue Oct 15 13:08:20 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* Makefile.am: Added "make lint" production. 
+	* Makefile.in: Rebuilt.
+
+	* prep_cif.c (STACK_ARG_SIZE): Improved STACK_ARG_SIZE macro.
+  	Clean up based on LCLint output. Added funny /*@...@*/ comments to
+ 	annotate source.
+
+	* ffitest.c, debug.c: Cleaned up code.
+
+Mon Oct 14 12:26:56 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffitest.c: Changes based on interface changes.
+
+	* prep_cif.c (ffi_prep_cif): Cleaned up interface based on
+	feedback from Jim Blandy.
+
+Fri Oct 11 15:53:18 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffitest.c: Reordered tests while porting to sparc.
+	Made changes to handle lame structure passing for sparc.
+	Removed calls to fflush().
+
+	* prep_cif.c (ffi_prep_cif): Added special case for sparc
+	aggregate type arguments.
+
+Thu Oct 10 09:56:51 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffitest.c (main): Added structure passing/returning tests.
+
+	* prep_cif.c (ffi_prep_cif): Perform proper initialization
+	of structure return types if needed.
+	(initialize_aggregate): Bug fix
+
+Wed Oct  9 16:04:20 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* types.c: Added special definitions for x86 (double doesn't
+	need double word alignment).
+
+	* ffitest.c: Added many tests
+
+Tue Oct  8 09:19:22 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* prep_cif.c (ffi_prep_cif): Fixed assertion.
+
+	* debug.c (ffi_assert): Must return a non void now.
+
+	* Makefile.am: Added test production.
+	* Makefile: Rebuilt.
+
+	* ffitest.c (main): Created. 
+
+	* types.c: Created. Stripped common code out of */ffi.c.
+
+	* prep_cif.c: Added missing stdlib.h include.
+
+	* debug.c (ffi_type_test): Used "a" to eliminate compiler
+	warnings in non-debug builds. Included ffi_common.h.
+
+Mon Oct  7 15:36:42 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* Makefile.am: Added a rule for .s -> .o
+	This is required by the SGI compiler.
+	* Makefile: Rebuilt.
+
+Fri Oct  4 09:51:08 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* prep_cif.c (initialize_aggregate): Moved abi specification
+	to ffi_prep_cif().
+
+Thu Oct  3 15:37:37 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* prep_cif.c (ffi_prep_cif): Changed values from void* to void**.
+	(initialize_aggregate): Fixed aggregate type initialization.
+
+	* Makefile.am (EXTRA_DIST): Added support code for "make dist".
+	* Makefile.in: Regenerated.
+
+Wed Oct  2 11:41:57 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* debug.c, prep_cif: Created.
+
+	* Makefile.am: Added debug.o and prep_cif.o to OBJ.
+	* Makefile.in: Regenerated.
+
+	* Makefile.am (INCLUDES): Added missing -I../include
+	* Makefile.in: Regenerated.
+
+Tue Oct  1 17:11:51 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* error.c, Makefile.am: Created.
+	* Makefile.in: Generated.
+
+--- libffi/src/x86 --------------------------------------------------------
+
+Sun Oct  4 16:27:17 1998  Anthony Green  <green at cygnus.com>
+
+	* sysv.S (retlongdouble): Fixed long long return value support.
+	* ffi.c (ffi_prep_cif_machdep): Ditto.
+
+Wed May 13 04:30:33 1998  Anthony Green  <green at raft.ppp.tsoft.net>
+
+	* ffi.c (ffi_prep_cif_machdep): Fixed long double return value
+	support.
+
+Wed Apr 15 08:43:20 1998  Anthony Green  <green at hoser.cygnus.com>
+
+	* ffi.c (ffi_prep_args): small struct support was missing.
+
+Thu May  8 16:53:58 1997  Anthony Green  <green at hoser.cygnus.com>
+
+	* objects.mak: Removed.
+
+Mon Dec  2 15:12:58 1996  Tom Tromey  <tromey at cygnus.com>
+
+	* sysv.S: Use .balign, for a.out Linux boxes.
+
+Tue Oct 15 13:06:50 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* ffi.c: Clean up based on LCLint output.
+	Added funny /*@...@*/ comments to annotate source.
+
+Fri Oct 11 16:43:38 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi.c (ffi_call): Added assertion for bad ABIs.
+
+Wed Oct  9 13:57:27 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* sysv.S (retdouble): Fixed double return problems.
+
+	* ffi.c	(ffi_call): Corrected fn arg definition.
+	(ffi_prep_cif_machdep): Fixed double return problems
+
+Tue Oct  8 12:12:49 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi.c: Moved ffi_type definitions to types.c.
+	(ffi_prep_args): Fixed type promotion bug.
+
+Mon Oct  7 15:53:06 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi.c (FFI_*_TYPEDEF): Removed redundant ';'
+
+Fri Oct  4 09:54:53 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* ffi.c (ffi_call): Removed FFI_ABI arg, and swapped
+	remaining args.
+
+Wed Oct  2 10:07:05 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* ffi.c, sysv.S, objects.mak: Created.
+	(ffi_prep_cif): cif->rvalue no longer initialized to NULL.
+	(ffi_prep_cif_machdep): Moved machine independent cif processing
+	to src/prep_cif.c. Introduced ffi_prep_cif_machdep().
+
+--- libffi/src/mips -------------------------------------------------------
+
+Tue Feb 17 17:18:07 1998  Anthony Green  <green at hoser.cygnus.com>
+
+	* o32.S: Fixed typo in comment.
+
+	* ffi.c (ffi_prep_cif_machdep): Fixed argument processing.
+
+Thu May  8 16:53:58 1997  Anthony Green  <green at hoser.cygnus.com>
+
+	* o32.s, n32.s: Wrappers for SGI tool support.
+
+	* objects.mak: Removed.
+
+Tue Oct 29 14:37:45 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi.c (ffi_prep_args): Changed int z to size_t z.
+
+Tue Oct 15 13:17:25 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* n32.S: Fixed bad stack munging. 
+
+	* ffi.c: Moved prototypes for ffi_call_?32() to here from
+	ffi_mips.h because extended_cif is not defined in ffi_mips.h.
+
+Mon Oct 14 12:42:02 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi.c: Interface changes based on feedback from Jim Blandy.
+
+Thu Oct 10 11:22:16 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* n32.S, ffi.c: Lots of changes to support passing and 
+	returning structures with the n32 calling convention.
+
+	* n32.S: Fixed fn pointer bug.
+
+	* ffi.c (ffi_prep_cif_machdep): Fix for o32 structure
+	return values.
+	(ffi_prep_args): Fixed n32 structure passing when structures
+	partially fit in registers.
+
+Wed Oct  9 13:49:25 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* objects.mak: Added n32.o.
+
+	* n32.S: Created.
+
+	* ffi.c (ffi_prep_args): Added magic to support proper
+	n32 processing.
+
+Tue Oct  8 10:37:35 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi.c: Moved ffi_type definitions to types.c.
+	(ffi_prep_args): Fixed type promotion bug.
+
+	* o32.S: This code is only built for o32 compiles.
+	A lot of the #define cruft has moved to ffi_mips.h.
+
+	* ffi.c (ffi_prep_cif_machdep): Fixed arg flags. Second arg
+	is only processed if the first is either a float or double.
+
+Mon Oct  7 15:33:59 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* o32.S: Modified to compile under each of o32, n32 and n64.
+
+	* ffi.c (FFI_*_TYPEDEF): Removed redundant ';'
+
+Fri Oct  4 09:53:25 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* ffi.c (ffi_call): Removed FFI_ABI arg, and swapped
+	remaining args.
+
+Wed Oct  2 17:41:22 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* o32.S: Removed crufty definitions.
+
+Wed Oct  2 12:53:42 1996  Anthony Green  <green at hoser.cygnus.com>
+
+	* ffi.c (ffi_prep_cif): cif->rvalue no longer initialized to NULL.
+	(ffi_prep_cif_machdep): Moved all machine independent cif processing
+	to src/prep_cif.c. Introduced ffi_prep_cif_machdep. Return types
+	of FFI_TYPE_STRUCT are no different than FFI_TYPE_INT.
+
+Tue Oct  1 17:11:02 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi.c, o32.S, object.mak: Created
+	
+--- libffi/src/sparc ------------------------------------------------------
+
+Tue Feb 24 16:33:18 1998  Anthony Green  <green at hoser.cygnus.com>
+
+	* ffi.c (ffi_prep_args): Added long double support.
+
+Thu May  8 16:53:58 1997  Anthony Green  <green at hoser.cygnus.com>
+
+	* objects.mak: Removed.
+
+Thu May  1 16:07:56 1997  Anthony Green  <green at hoser.cygnus.com>
+
+	* v8.S: Fixed minor portability problem reported by 
+	Russ McManus <mcmanr at eq.gs.com>.
+
+Tue Nov 26 14:12:43 1996  Anthony Green  <green at csk3.cygnus.com>
+
+	* v8.S: Used STACKFRAME define elsewhere. 
+
+	* ffi.c (ffi_prep_args): Zero out space when USING_PURIFY
+	is set.
+	(ffi_prep_cif_machdep): Allocate the correct stack frame 
+	space for functions with < 6 args.
+
+Tue Oct 29 15:08:55 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi.c (ffi_prep_args): int z is now size_t z.
+
+Mon Oct 14 13:31:24 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* v8.S (ffi_call_V8): Gordon rewrites this again. It looks
+	great now.
+
+	* ffi.c (ffi_call): The comment about hijacked registers
+	is no longer valid after gordoni hacked v8.S.
+
+        * v8.S (ffi_call_V8): Rewrote with gordoni. Much simpler.
+	
+	* v8.S, ffi.c: ffi_call() had changed to accept more than
+	two args, so v8.S had to change (because it hijacks incoming
+	arg registers).
+
+	* ffi.c: Interface changes based on feedback from Jim Blandy.
+
+Thu Oct 10 17:48:16 1996  Anthony Green  <green at rtl.cygnus.com>
+
+	* ffi.c, v8.S, objects.mak: Created.
+	
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/LICENSE b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/LICENSE
new file mode 100755
index 0000000..7d12666
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/LICENSE
@@ -0,0 +1,21 @@
+libffi - Copyright (c) 1996-2011  Anthony Green, Red Hat, Inc and others.
+See source files for details.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+``Software''), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/Makefile.am b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/Makefile.am
new file mode 100755
index 0000000..86119d8
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/Makefile.am
@@ -0,0 +1,196 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign subdir-objects
+
+SUBDIRS = include testsuite man
+
+EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host	\
+	src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h		\
+	src/arm/ffi.c src/arm/sysv.S src/arm/trampoline.S		\
+	src/arm/ffitarget.h src/avr32/ffi.c src/avr32/sysv.S		\
+	src/avr32/ffitarget.h src/cris/ffi.c src/cris/sysv.S		\
+	src/cris/ffitarget.h src/ia64/ffi.c src/ia64/ffitarget.h	\
+	src/ia64/ia64_flags.h src/ia64/unix.S src/mips/ffi.c		\
+	src/mips/n32.S src/mips/o32.S src/mips/ffitarget.h		\
+	src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h		\
+	src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h		\
+	src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/linux64.S	\
+	src/powerpc/linux64_closure.S src/powerpc/ppc_closure.S		\
+	src/powerpc/asm.h src/powerpc/aix.S src/powerpc/darwin.S	\
+	src/powerpc/aix_closure.S src/powerpc/darwin_closure.S		\
+	src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h		\
+	src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h		\
+	src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h src/sh64/ffi.c	\
+	src/sh64/sysv.S src/sh64/ffitarget.h src/sparc/v8.S		\
+	src/sparc/v9.S src/sparc/ffitarget.h src/sparc/ffi.c		\
+	src/x86/darwin64.S src/x86/ffi.c src/x86/sysv.S			\
+	src/x86/win32.S src/x86/win64.S src/x86/darwin.S		\
+	src/x86/freebsd.S src/x86/ffi64.c src/x86/unix64.S		\
+	src/x86/ffitarget.h src/pa/ffitarget.h src/pa/ffi.c		\
+	src/pa/linux.S src/pa/hpux32.S src/frv/ffi.c src/frv/eabi.S	\
+	src/frv/ffitarget.h src/dlmalloc.c src/moxie/ffi.c		\
+	src/moxie/eabi.S libtool-version ChangeLog.libffi		\
+	m4/libtool.m4 m4/lt~obsolete.m4 m4/ltoptions.m4 m4/ltsugar.m4	\
+	m4/ltversion.m4 build-ios.sh src/arm/gentramp.sh src/debug.c    \
+	msvcc.sh
+
+
+info_TEXINFOS = doc/libffi.texi
+
+## ################################################################
+
+##
+## This section is for make and multilib madness.
+##
+
+# Work around what appears to be a GNU make bug handling MAKEFLAGS
+# values defined in terms of make variables, as is the case for CC and
+# friends when we are called from the top level Makefile.
+AM_MAKEFLAGS = \
+	"AR_FLAGS=$(AR_FLAGS)" \
+	"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+	"CFLAGS=$(CFLAGS)" \
+	"CXXFLAGS=$(CXXFLAGS)" \
+	"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+	"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+	"INSTALL=$(INSTALL)" \
+	"INSTALL_DATA=$(INSTALL_DATA)" \
+	"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+	"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+	"JC1FLAGS=$(JC1FLAGS)" \
+	"LDFLAGS=$(LDFLAGS)" \
+	"LIBCFLAGS=$(LIBCFLAGS)" \
+	"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+	"MAKE=$(MAKE)" \
+	"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+	"PICFLAG=$(PICFLAG)" \
+	"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
+	"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
+	"SHELL=$(SHELL)" \
+	"exec_prefix=$(exec_prefix)" \
+	"infodir=$(infodir)" \
+	"libdir=$(libdir)" \
+	"mandir=$(mandir)" \
+	"prefix=$(prefix)" \
+	"AR=$(AR)" \
+	"AS=$(AS)" \
+	"CC=$(CC)" \
+	"CXX=$(CXX)" \
+	"LD=$(LD)" \
+	"NM=$(NM)" \
+	"RANLIB=$(RANLIB)" \
+	"DESTDIR=$(DESTDIR)"
+
+MAKEOVERRIDES=
+
+ACLOCAL_AMFLAGS=$(ACLOCAL_AMFLAGS) -I m4
+
+lib_LTLIBRARIES = libffi.la
+noinst_LTLIBRARIES = libffi_convenience.la
+
+libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \
+		src/raw_api.c src/java_raw_api.c src/closures.c
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libffi.pc
+
+nodist_libffi_la_SOURCES =
+
+if MIPS
+nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S
+endif
+if X86
+nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S
+endif
+if X86_FREEBSD
+nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S
+endif
+if X86_WIN32
+nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win32.S
+endif
+if X86_WIN64
+nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win64.S
+endif
+if X86_DARWIN
+nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
+endif
+if SPARC
+nodist_libffi_la_SOURCES += src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
+endif
+if ALPHA
+nodist_libffi_la_SOURCES += src/alpha/ffi.c src/alpha/osf.S
+endif
+if IA64
+nodist_libffi_la_SOURCES += src/ia64/ffi.c src/ia64/unix.S
+endif
+if M32R
+nodist_libffi_la_SOURCES += src/m32r/sysv.S src/m32r/ffi.c
+endif
+if M68K
+nodist_libffi_la_SOURCES += src/m68k/ffi.c src/m68k/sysv.S
+endif
+if POWERPC
+nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
+endif
+if POWERPC_AIX
+nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
+endif
+if POWERPC_DARWIN
+nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
+endif
+if POWERPC_FREEBSD
+nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
+endif
+if ARM
+nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c
+if FFI_EXEC_TRAMPOLINE_TABLE
+nodist_libffi_la_SOURCES += src/arm/trampoline.S
+endif
+endif
+if AVR32
+nodist_libffi_la_SOURCES += src/avr32/sysv.S src/avr32/ffi.c
+endif
+if LIBFFI_CRIS
+nodist_libffi_la_SOURCES += src/cris/sysv.S src/cris/ffi.c
+endif
+if FRV
+nodist_libffi_la_SOURCES += src/frv/eabi.S src/frv/ffi.c
+endif
+if S390
+nodist_libffi_la_SOURCES += src/s390/sysv.S src/s390/ffi.c
+endif
+if X86_64
+nodist_libffi_la_SOURCES += src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
+endif
+if SH
+nodist_libffi_la_SOURCES += src/sh/sysv.S src/sh/ffi.c
+endif
+if SH64
+nodist_libffi_la_SOURCES += src/sh64/sysv.S src/sh64/ffi.c
+endif
+if PA_LINUX
+nodist_libffi_la_SOURCES += src/pa/linux.S src/pa/ffi.c
+endif
+if PA_HPUX
+nodist_libffi_la_SOURCES += src/pa/hpux32.S src/pa/ffi.c
+endif
+
+libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
+nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
+
+AM_CFLAGS = -g
+if FFI_DEBUG
+# Build debug. Define FFI_DEBUG on the commandline so that, when building with
+# MSVC, it can link against the debug CRT.
+AM_CFLAGS += -DFFI_DEBUG
+endif
+
+libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS)
+
+AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
+AM_CCASFLAGS = $(AM_CPPFLAGS)
+
+# No install-html or install-pdf support in automake yet
+.PHONY: install-html install-pdf
+install-html:
+install-pdf:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/Makefile.in b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/Makefile.in
new file mode 100755
index 0000000..cbe1589
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/Makefile.in
@@ -0,0 +1,1820 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+ at MIPS_TRUE@am__append_1 = src/mips/ffi.c src/mips/o32.S src/mips/n32.S
+ at X86_TRUE@am__append_2 = src/x86/ffi.c src/x86/sysv.S
+ at X86_FREEBSD_TRUE@am__append_3 = src/x86/ffi.c src/x86/freebsd.S
+ at X86_WIN32_TRUE@am__append_4 = src/x86/ffi.c src/x86/win32.S
+ at X86_WIN64_TRUE@am__append_5 = src/x86/ffi.c src/x86/win64.S
+ at X86_DARWIN_TRUE@am__append_6 = src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
+ at SPARC_TRUE@am__append_7 = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
+ at ALPHA_TRUE@am__append_8 = src/alpha/ffi.c src/alpha/osf.S
+ at IA64_TRUE@am__append_9 = src/ia64/ffi.c src/ia64/unix.S
+ at M32R_TRUE@am__append_10 = src/m32r/sysv.S src/m32r/ffi.c
+ at M68K_TRUE@am__append_11 = src/m68k/ffi.c src/m68k/sysv.S
+ at POWERPC_TRUE@am__append_12 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
+ at POWERPC_AIX_TRUE@am__append_13 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
+ at POWERPC_DARWIN_TRUE@am__append_14 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
+ at POWERPC_FREEBSD_TRUE@am__append_15 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
+ at ARM_TRUE@am__append_16 = src/arm/sysv.S src/arm/ffi.c
+ at ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE at am__append_17 = src/arm/trampoline.S
+ at AVR32_TRUE@am__append_18 = src/avr32/sysv.S src/avr32/ffi.c
+ at LIBFFI_CRIS_TRUE@am__append_19 = src/cris/sysv.S src/cris/ffi.c
+ at FRV_TRUE@am__append_20 = src/frv/eabi.S src/frv/ffi.c
+ at S390_TRUE@am__append_21 = src/s390/sysv.S src/s390/ffi.c
+ at X86_64_TRUE@am__append_22 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
+ at SH_TRUE@am__append_23 = src/sh/sysv.S src/sh/ffi.c
+ at SH64_TRUE@am__append_24 = src/sh64/sysv.S src/sh64/ffi.c
+ at PA_LINUX_TRUE@am__append_25 = src/pa/linux.S src/pa/ffi.c
+ at PA_HPUX_TRUE@am__append_26 = src/pa/hpux32.S src/pa/ffi.c
+# Build debug. Define FFI_DEBUG on the commandline so that, when building with
+# MSVC, it can link against the debug CRT.
+ at FFI_DEBUG_TRUE@am__append_27 = -DFFI_DEBUG
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in $(srcdir)/doc/stamp-vti \
+	$(srcdir)/doc/version.texi $(srcdir)/fficonfig.h.in \
+	$(srcdir)/libffi.pc.in $(top_srcdir)/configure ChangeLog \
+	compile config.guess config.sub depcomp install-sh ltmain.sh \
+	mdate-sh missing texinfo.tex
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_maxopt.m4 \
+	$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
+	$(top_srcdir)/m4/ax_check_compiler_flags.m4 \
+	$(top_srcdir)/m4/ax_compiler_vendor.m4 \
+	$(top_srcdir)/m4/ax_configure_args.m4 \
+	$(top_srcdir)/m4/ax_enable_builddir.m4 \
+	$(top_srcdir)/m4/ax_gcc_archflag.m4 \
+	$(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = fficonfig.h
+CONFIG_CLEAN_FILES = libffi.pc
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(infodir)" \
+	"$(DESTDIR)$(pkgconfigdir)"
+LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
+libffi_la_LIBADD =
+am__dirstamp = $(am__leading_dot)dirstamp
+am_libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo src/types.lo \
+	src/raw_api.lo src/java_raw_api.lo src/closures.lo
+ at MIPS_TRUE@am__objects_1 = src/mips/ffi.lo src/mips/o32.lo \
+ at MIPS_TRUE@	src/mips/n32.lo
+ at X86_TRUE@am__objects_2 = src/x86/ffi.lo src/x86/sysv.lo
+ at X86_FREEBSD_TRUE@am__objects_3 = src/x86/ffi.lo src/x86/freebsd.lo
+ at X86_WIN32_TRUE@am__objects_4 = src/x86/ffi.lo src/x86/win32.lo
+ at X86_WIN64_TRUE@am__objects_5 = src/x86/ffi.lo src/x86/win64.lo
+ at X86_DARWIN_TRUE@am__objects_6 = src/x86/ffi.lo src/x86/darwin.lo \
+ at X86_DARWIN_TRUE@	src/x86/ffi64.lo src/x86/darwin64.lo
+ at SPARC_TRUE@am__objects_7 = src/sparc/ffi.lo src/sparc/v8.lo \
+ at SPARC_TRUE@	src/sparc/v9.lo
+ at ALPHA_TRUE@am__objects_8 = src/alpha/ffi.lo src/alpha/osf.lo
+ at IA64_TRUE@am__objects_9 = src/ia64/ffi.lo src/ia64/unix.lo
+ at M32R_TRUE@am__objects_10 = src/m32r/sysv.lo src/m32r/ffi.lo
+ at M68K_TRUE@am__objects_11 = src/m68k/ffi.lo src/m68k/sysv.lo
+ at POWERPC_TRUE@am__objects_12 = src/powerpc/ffi.lo src/powerpc/sysv.lo \
+ at POWERPC_TRUE@	src/powerpc/ppc_closure.lo \
+ at POWERPC_TRUE@	src/powerpc/linux64.lo \
+ at POWERPC_TRUE@	src/powerpc/linux64_closure.lo
+ at POWERPC_AIX_TRUE@am__objects_13 = src/powerpc/ffi_darwin.lo \
+ at POWERPC_AIX_TRUE@	src/powerpc/aix.lo \
+ at POWERPC_AIX_TRUE@	src/powerpc/aix_closure.lo
+ at POWERPC_DARWIN_TRUE@am__objects_14 = src/powerpc/ffi_darwin.lo \
+ at POWERPC_DARWIN_TRUE@	src/powerpc/darwin.lo \
+ at POWERPC_DARWIN_TRUE@	src/powerpc/darwin_closure.lo
+ at POWERPC_FREEBSD_TRUE@am__objects_15 = src/powerpc/ffi.lo \
+ at POWERPC_FREEBSD_TRUE@	src/powerpc/sysv.lo \
+ at POWERPC_FREEBSD_TRUE@	src/powerpc/ppc_closure.lo
+ at ARM_TRUE@am__objects_16 = src/arm/sysv.lo src/arm/ffi.lo
+ at ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE at am__objects_17 = src/arm/trampoline.lo
+ at AVR32_TRUE@am__objects_18 = src/avr32/sysv.lo src/avr32/ffi.lo
+ at LIBFFI_CRIS_TRUE@am__objects_19 = src/cris/sysv.lo src/cris/ffi.lo
+ at FRV_TRUE@am__objects_20 = src/frv/eabi.lo src/frv/ffi.lo
+ at S390_TRUE@am__objects_21 = src/s390/sysv.lo src/s390/ffi.lo
+ at X86_64_TRUE@am__objects_22 = src/x86/ffi64.lo src/x86/unix64.lo \
+ at X86_64_TRUE@	src/x86/ffi.lo src/x86/sysv.lo
+ at SH_TRUE@am__objects_23 = src/sh/sysv.lo src/sh/ffi.lo
+ at SH64_TRUE@am__objects_24 = src/sh64/sysv.lo src/sh64/ffi.lo
+ at PA_LINUX_TRUE@am__objects_25 = src/pa/linux.lo src/pa/ffi.lo
+ at PA_HPUX_TRUE@am__objects_26 = src/pa/hpux32.lo src/pa/ffi.lo
+nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
+	$(am__objects_3) $(am__objects_4) $(am__objects_5) \
+	$(am__objects_6) $(am__objects_7) $(am__objects_8) \
+	$(am__objects_9) $(am__objects_10) $(am__objects_11) \
+	$(am__objects_12) $(am__objects_13) $(am__objects_14) \
+	$(am__objects_15) $(am__objects_16) $(am__objects_17) \
+	$(am__objects_18) $(am__objects_19) $(am__objects_20) \
+	$(am__objects_21) $(am__objects_22) $(am__objects_23) \
+	$(am__objects_24) $(am__objects_25) $(am__objects_26)
+libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \
+	$(nodist_libffi_la_OBJECTS)
+libffi_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(libffi_la_LDFLAGS) $(LDFLAGS) -o $@
+libffi_convenience_la_LIBADD =
+am__objects_27 = src/debug.lo src/prep_cif.lo src/types.lo \
+	src/raw_api.lo src/java_raw_api.lo src/closures.lo
+am_libffi_convenience_la_OBJECTS = $(am__objects_27)
+am__objects_28 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
+	$(am__objects_4) $(am__objects_5) $(am__objects_6) \
+	$(am__objects_7) $(am__objects_8) $(am__objects_9) \
+	$(am__objects_10) $(am__objects_11) $(am__objects_12) \
+	$(am__objects_13) $(am__objects_14) $(am__objects_15) \
+	$(am__objects_16) $(am__objects_17) $(am__objects_18) \
+	$(am__objects_19) $(am__objects_20) $(am__objects_21) \
+	$(am__objects_22) $(am__objects_23) $(am__objects_24) \
+	$(am__objects_25) $(am__objects_26)
+nodist_libffi_convenience_la_OBJECTS = $(am__objects_28)
+libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \
+	$(nodist_libffi_convenience_la_OBJECTS)
+DEFAULT_INCLUDES = -I. at am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
+LTCPPASCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+SOURCES = $(libffi_la_SOURCES) $(nodist_libffi_la_SOURCES) \
+	$(libffi_convenience_la_SOURCES) \
+	$(nodist_libffi_convenience_la_SOURCES)
+DIST_SOURCES = $(libffi_la_SOURCES) $(libffi_convenience_la_SOURCES)
+INFO_DEPS = $(srcdir)/doc/libffi.info
+am__TEXINFO_TEX_DIR = $(srcdir)
+DVIS = doc/libffi.dvi
+PDFS = doc/libffi.pdf
+PSS = doc/libffi.ps
+HTMLS = doc/libffi.html
+TEXINFOS = doc/libffi.texi
+TEXI2DVI = texi2dvi
+TEXI2PDF = $(TEXI2DVI) --pdf --batch
+MAKEINFOHTML = $(MAKEINFO) --html
+AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
+DVIPS = dvips
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-dvi-recursive install-exec-recursive \
+	install-html-recursive install-info-recursive \
+	install-pdf-recursive install-ps-recursive install-recursive \
+	installcheck-recursive installdirs-recursive pdf-recursive \
+	ps-recursive uninstall-recursive
+DATA = $(pkgconfig_DATA)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+	$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+	distdir dist dist-all distcheck
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  { test ! -d "$(distdir)" \
+    || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+         && rm -fr "$(distdir)"; }; }
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_LTLDFLAGS = @AM_LTLDFLAGS@
+AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PRTDIAG = @PRTDIAG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TARGET = @TARGET@
+TARGETDIR = @TARGETDIR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_enable_builddir_sed = @ax_enable_builddir_sed@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sys_symbol_underscore = @sys_symbol_underscore@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+toolexecdir = @toolexecdir@
+toolexeclibdir = @toolexeclibdir@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign subdir-objects
+SUBDIRS = include testsuite man
+EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host	\
+	src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h		\
+	src/arm/ffi.c src/arm/sysv.S src/arm/trampoline.S		\
+	src/arm/ffitarget.h src/avr32/ffi.c src/avr32/sysv.S		\
+	src/avr32/ffitarget.h src/cris/ffi.c src/cris/sysv.S		\
+	src/cris/ffitarget.h src/ia64/ffi.c src/ia64/ffitarget.h	\
+	src/ia64/ia64_flags.h src/ia64/unix.S src/mips/ffi.c		\
+	src/mips/n32.S src/mips/o32.S src/mips/ffitarget.h		\
+	src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h		\
+	src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h		\
+	src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/linux64.S	\
+	src/powerpc/linux64_closure.S src/powerpc/ppc_closure.S		\
+	src/powerpc/asm.h src/powerpc/aix.S src/powerpc/darwin.S	\
+	src/powerpc/aix_closure.S src/powerpc/darwin_closure.S		\
+	src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h		\
+	src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h		\
+	src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h src/sh64/ffi.c	\
+	src/sh64/sysv.S src/sh64/ffitarget.h src/sparc/v8.S		\
+	src/sparc/v9.S src/sparc/ffitarget.h src/sparc/ffi.c		\
+	src/x86/darwin64.S src/x86/ffi.c src/x86/sysv.S			\
+	src/x86/win32.S src/x86/win64.S src/x86/darwin.S		\
+	src/x86/freebsd.S src/x86/ffi64.c src/x86/unix64.S		\
+	src/x86/ffitarget.h src/pa/ffitarget.h src/pa/ffi.c		\
+	src/pa/linux.S src/pa/hpux32.S src/frv/ffi.c src/frv/eabi.S	\
+	src/frv/ffitarget.h src/dlmalloc.c src/moxie/ffi.c		\
+	src/moxie/eabi.S libtool-version ChangeLog.libffi		\
+	m4/libtool.m4 m4/lt~obsolete.m4 m4/ltoptions.m4 m4/ltsugar.m4	\
+	m4/ltversion.m4 build-ios.sh src/arm/gentramp.sh src/debug.c    \
+	msvcc.sh
+
+info_TEXINFOS = doc/libffi.texi
+
+# Work around what appears to be a GNU make bug handling MAKEFLAGS
+# values defined in terms of make variables, as is the case for CC and
+# friends when we are called from the top level Makefile.
+AM_MAKEFLAGS = \
+	"AR_FLAGS=$(AR_FLAGS)" \
+	"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+	"CFLAGS=$(CFLAGS)" \
+	"CXXFLAGS=$(CXXFLAGS)" \
+	"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+	"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+	"INSTALL=$(INSTALL)" \
+	"INSTALL_DATA=$(INSTALL_DATA)" \
+	"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+	"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+	"JC1FLAGS=$(JC1FLAGS)" \
+	"LDFLAGS=$(LDFLAGS)" \
+	"LIBCFLAGS=$(LIBCFLAGS)" \
+	"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+	"MAKE=$(MAKE)" \
+	"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+	"PICFLAG=$(PICFLAG)" \
+	"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
+	"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
+	"SHELL=$(SHELL)" \
+	"exec_prefix=$(exec_prefix)" \
+	"infodir=$(infodir)" \
+	"libdir=$(libdir)" \
+	"mandir=$(mandir)" \
+	"prefix=$(prefix)" \
+	"AR=$(AR)" \
+	"AS=$(AS)" \
+	"CC=$(CC)" \
+	"CXX=$(CXX)" \
+	"LD=$(LD)" \
+	"NM=$(NM)" \
+	"RANLIB=$(RANLIB)" \
+	"DESTDIR=$(DESTDIR)"
+
+MAKEOVERRIDES = 
+ACLOCAL_AMFLAGS = $(ACLOCAL_AMFLAGS) -I m4
+lib_LTLIBRARIES = libffi.la
+noinst_LTLIBRARIES = libffi_convenience.la
+libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \
+		src/raw_api.c src/java_raw_api.c src/closures.c
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libffi.pc
+nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \
+	$(am__append_3) $(am__append_4) $(am__append_5) \
+	$(am__append_6) $(am__append_7) $(am__append_8) \
+	$(am__append_9) $(am__append_10) $(am__append_11) \
+	$(am__append_12) $(am__append_13) $(am__append_14) \
+	$(am__append_15) $(am__append_16) $(am__append_17) \
+	$(am__append_18) $(am__append_19) $(am__append_20) \
+	$(am__append_21) $(am__append_22) $(am__append_23) \
+	$(am__append_24) $(am__append_25) $(am__append_26)
+libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
+nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
+AM_CFLAGS = -g $(am__append_27)
+libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS)
+AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
+AM_CCASFLAGS = $(AM_CPPFLAGS)
+all: fficonfig.h
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .S .c .dvi .lo .o .obj .ps
+am--refresh:
+	@:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    echo ' $(SHELL) ./config.status'; \
+	    $(SHELL) ./config.status;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	$(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+fficonfig.h: stamp-h1
+	@if test ! -f $@; then \
+	  rm -f stamp-h1; \
+	  $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
+	else :; fi
+
+stamp-h1: $(srcdir)/fficonfig.h.in $(top_builddir)/config.status
+	@rm -f stamp-h1
+	cd $(top_builddir) && $(SHELL) ./config.status fficonfig.h
+$(srcdir)/fficonfig.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) 
+	($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+	rm -f stamp-h1
+	touch $@
+
+distclean-hdr:
+	-rm -f fficonfig.h stamp-h1
+libffi.pc: $(top_builddir)/config.status $(srcdir)/libffi.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+	}
+
+uninstall-libLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+	done
+
+clean-libLTLIBRARIES:
+	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+	  test "$$dir" != "$$p" || dir=.; \
+	  echo "rm -f \"$${dir}/so_locations\""; \
+	  rm -f "$${dir}/so_locations"; \
+	done
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+	  test "$$dir" != "$$p" || dir=.; \
+	  echo "rm -f \"$${dir}/so_locations\""; \
+	  rm -f "$${dir}/so_locations"; \
+	done
+src/$(am__dirstamp):
+	@$(MKDIR_P) src
+	@: > src/$(am__dirstamp)
+src/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/$(DEPDIR)
+	@: > src/$(DEPDIR)/$(am__dirstamp)
+src/debug.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
+src/prep_cif.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
+src/types.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
+src/raw_api.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
+src/java_raw_api.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
+src/closures.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
+src/mips/$(am__dirstamp):
+	@$(MKDIR_P) src/mips
+	@: > src/mips/$(am__dirstamp)
+src/mips/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/mips/$(DEPDIR)
+	@: > src/mips/$(DEPDIR)/$(am__dirstamp)
+src/mips/ffi.lo: src/mips/$(am__dirstamp) \
+	src/mips/$(DEPDIR)/$(am__dirstamp)
+src/mips/o32.lo: src/mips/$(am__dirstamp) \
+	src/mips/$(DEPDIR)/$(am__dirstamp)
+src/mips/n32.lo: src/mips/$(am__dirstamp) \
+	src/mips/$(DEPDIR)/$(am__dirstamp)
+src/x86/$(am__dirstamp):
+	@$(MKDIR_P) src/x86
+	@: > src/x86/$(am__dirstamp)
+src/x86/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/x86/$(DEPDIR)
+	@: > src/x86/$(DEPDIR)/$(am__dirstamp)
+src/x86/ffi.lo: src/x86/$(am__dirstamp) \
+	src/x86/$(DEPDIR)/$(am__dirstamp)
+src/x86/sysv.lo: src/x86/$(am__dirstamp) \
+	src/x86/$(DEPDIR)/$(am__dirstamp)
+src/x86/freebsd.lo: src/x86/$(am__dirstamp) \
+	src/x86/$(DEPDIR)/$(am__dirstamp)
+src/x86/win32.lo: src/x86/$(am__dirstamp) \
+	src/x86/$(DEPDIR)/$(am__dirstamp)
+src/x86/win64.lo: src/x86/$(am__dirstamp) \
+	src/x86/$(DEPDIR)/$(am__dirstamp)
+src/x86/darwin.lo: src/x86/$(am__dirstamp) \
+	src/x86/$(DEPDIR)/$(am__dirstamp)
+src/x86/ffi64.lo: src/x86/$(am__dirstamp) \
+	src/x86/$(DEPDIR)/$(am__dirstamp)
+src/x86/darwin64.lo: src/x86/$(am__dirstamp) \
+	src/x86/$(DEPDIR)/$(am__dirstamp)
+src/sparc/$(am__dirstamp):
+	@$(MKDIR_P) src/sparc
+	@: > src/sparc/$(am__dirstamp)
+src/sparc/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/sparc/$(DEPDIR)
+	@: > src/sparc/$(DEPDIR)/$(am__dirstamp)
+src/sparc/ffi.lo: src/sparc/$(am__dirstamp) \
+	src/sparc/$(DEPDIR)/$(am__dirstamp)
+src/sparc/v8.lo: src/sparc/$(am__dirstamp) \
+	src/sparc/$(DEPDIR)/$(am__dirstamp)
+src/sparc/v9.lo: src/sparc/$(am__dirstamp) \
+	src/sparc/$(DEPDIR)/$(am__dirstamp)
+src/alpha/$(am__dirstamp):
+	@$(MKDIR_P) src/alpha
+	@: > src/alpha/$(am__dirstamp)
+src/alpha/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/alpha/$(DEPDIR)
+	@: > src/alpha/$(DEPDIR)/$(am__dirstamp)
+src/alpha/ffi.lo: src/alpha/$(am__dirstamp) \
+	src/alpha/$(DEPDIR)/$(am__dirstamp)
+src/alpha/osf.lo: src/alpha/$(am__dirstamp) \
+	src/alpha/$(DEPDIR)/$(am__dirstamp)
+src/ia64/$(am__dirstamp):
+	@$(MKDIR_P) src/ia64
+	@: > src/ia64/$(am__dirstamp)
+src/ia64/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/ia64/$(DEPDIR)
+	@: > src/ia64/$(DEPDIR)/$(am__dirstamp)
+src/ia64/ffi.lo: src/ia64/$(am__dirstamp) \
+	src/ia64/$(DEPDIR)/$(am__dirstamp)
+src/ia64/unix.lo: src/ia64/$(am__dirstamp) \
+	src/ia64/$(DEPDIR)/$(am__dirstamp)
+src/m32r/$(am__dirstamp):
+	@$(MKDIR_P) src/m32r
+	@: > src/m32r/$(am__dirstamp)
+src/m32r/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/m32r/$(DEPDIR)
+	@: > src/m32r/$(DEPDIR)/$(am__dirstamp)
+src/m32r/sysv.lo: src/m32r/$(am__dirstamp) \
+	src/m32r/$(DEPDIR)/$(am__dirstamp)
+src/m32r/ffi.lo: src/m32r/$(am__dirstamp) \
+	src/m32r/$(DEPDIR)/$(am__dirstamp)
+src/m68k/$(am__dirstamp):
+	@$(MKDIR_P) src/m68k
+	@: > src/m68k/$(am__dirstamp)
+src/m68k/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/m68k/$(DEPDIR)
+	@: > src/m68k/$(DEPDIR)/$(am__dirstamp)
+src/m68k/ffi.lo: src/m68k/$(am__dirstamp) \
+	src/m68k/$(DEPDIR)/$(am__dirstamp)
+src/m68k/sysv.lo: src/m68k/$(am__dirstamp) \
+	src/m68k/$(DEPDIR)/$(am__dirstamp)
+src/powerpc/$(am__dirstamp):
+	@$(MKDIR_P) src/powerpc
+	@: > src/powerpc/$(am__dirstamp)
+src/powerpc/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/powerpc/$(DEPDIR)
+	@: > src/powerpc/$(DEPDIR)/$(am__dirstamp)
+src/powerpc/ffi.lo: src/powerpc/$(am__dirstamp) \
+	src/powerpc/$(DEPDIR)/$(am__dirstamp)
+src/powerpc/sysv.lo: src/powerpc/$(am__dirstamp) \
+	src/powerpc/$(DEPDIR)/$(am__dirstamp)
+src/powerpc/ppc_closure.lo: src/powerpc/$(am__dirstamp) \
+	src/powerpc/$(DEPDIR)/$(am__dirstamp)
+src/powerpc/linux64.lo: src/powerpc/$(am__dirstamp) \
+	src/powerpc/$(DEPDIR)/$(am__dirstamp)
+src/powerpc/linux64_closure.lo: src/powerpc/$(am__dirstamp) \
+	src/powerpc/$(DEPDIR)/$(am__dirstamp)
+src/powerpc/ffi_darwin.lo: src/powerpc/$(am__dirstamp) \
+	src/powerpc/$(DEPDIR)/$(am__dirstamp)
+src/powerpc/aix.lo: src/powerpc/$(am__dirstamp) \
+	src/powerpc/$(DEPDIR)/$(am__dirstamp)
+src/powerpc/aix_closure.lo: src/powerpc/$(am__dirstamp) \
+	src/powerpc/$(DEPDIR)/$(am__dirstamp)
+src/powerpc/darwin.lo: src/powerpc/$(am__dirstamp) \
+	src/powerpc/$(DEPDIR)/$(am__dirstamp)
+src/powerpc/darwin_closure.lo: src/powerpc/$(am__dirstamp) \
+	src/powerpc/$(DEPDIR)/$(am__dirstamp)
+src/arm/$(am__dirstamp):
+	@$(MKDIR_P) src/arm
+	@: > src/arm/$(am__dirstamp)
+src/arm/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/arm/$(DEPDIR)
+	@: > src/arm/$(DEPDIR)/$(am__dirstamp)
+src/arm/sysv.lo: src/arm/$(am__dirstamp) \
+	src/arm/$(DEPDIR)/$(am__dirstamp)
+src/arm/ffi.lo: src/arm/$(am__dirstamp) \
+	src/arm/$(DEPDIR)/$(am__dirstamp)
+src/arm/trampoline.lo: src/arm/$(am__dirstamp) \
+	src/arm/$(DEPDIR)/$(am__dirstamp)
+src/avr32/$(am__dirstamp):
+	@$(MKDIR_P) src/avr32
+	@: > src/avr32/$(am__dirstamp)
+src/avr32/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/avr32/$(DEPDIR)
+	@: > src/avr32/$(DEPDIR)/$(am__dirstamp)
+src/avr32/sysv.lo: src/avr32/$(am__dirstamp) \
+	src/avr32/$(DEPDIR)/$(am__dirstamp)
+src/avr32/ffi.lo: src/avr32/$(am__dirstamp) \
+	src/avr32/$(DEPDIR)/$(am__dirstamp)
+src/cris/$(am__dirstamp):
+	@$(MKDIR_P) src/cris
+	@: > src/cris/$(am__dirstamp)
+src/cris/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/cris/$(DEPDIR)
+	@: > src/cris/$(DEPDIR)/$(am__dirstamp)
+src/cris/sysv.lo: src/cris/$(am__dirstamp) \
+	src/cris/$(DEPDIR)/$(am__dirstamp)
+src/cris/ffi.lo: src/cris/$(am__dirstamp) \
+	src/cris/$(DEPDIR)/$(am__dirstamp)
+src/frv/$(am__dirstamp):
+	@$(MKDIR_P) src/frv
+	@: > src/frv/$(am__dirstamp)
+src/frv/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/frv/$(DEPDIR)
+	@: > src/frv/$(DEPDIR)/$(am__dirstamp)
+src/frv/eabi.lo: src/frv/$(am__dirstamp) \
+	src/frv/$(DEPDIR)/$(am__dirstamp)
+src/frv/ffi.lo: src/frv/$(am__dirstamp) \
+	src/frv/$(DEPDIR)/$(am__dirstamp)
+src/s390/$(am__dirstamp):
+	@$(MKDIR_P) src/s390
+	@: > src/s390/$(am__dirstamp)
+src/s390/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/s390/$(DEPDIR)
+	@: > src/s390/$(DEPDIR)/$(am__dirstamp)
+src/s390/sysv.lo: src/s390/$(am__dirstamp) \
+	src/s390/$(DEPDIR)/$(am__dirstamp)
+src/s390/ffi.lo: src/s390/$(am__dirstamp) \
+	src/s390/$(DEPDIR)/$(am__dirstamp)
+src/x86/unix64.lo: src/x86/$(am__dirstamp) \
+	src/x86/$(DEPDIR)/$(am__dirstamp)
+src/sh/$(am__dirstamp):
+	@$(MKDIR_P) src/sh
+	@: > src/sh/$(am__dirstamp)
+src/sh/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/sh/$(DEPDIR)
+	@: > src/sh/$(DEPDIR)/$(am__dirstamp)
+src/sh/sysv.lo: src/sh/$(am__dirstamp) \
+	src/sh/$(DEPDIR)/$(am__dirstamp)
+src/sh/ffi.lo: src/sh/$(am__dirstamp) src/sh/$(DEPDIR)/$(am__dirstamp)
+src/sh64/$(am__dirstamp):
+	@$(MKDIR_P) src/sh64
+	@: > src/sh64/$(am__dirstamp)
+src/sh64/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/sh64/$(DEPDIR)
+	@: > src/sh64/$(DEPDIR)/$(am__dirstamp)
+src/sh64/sysv.lo: src/sh64/$(am__dirstamp) \
+	src/sh64/$(DEPDIR)/$(am__dirstamp)
+src/sh64/ffi.lo: src/sh64/$(am__dirstamp) \
+	src/sh64/$(DEPDIR)/$(am__dirstamp)
+src/pa/$(am__dirstamp):
+	@$(MKDIR_P) src/pa
+	@: > src/pa/$(am__dirstamp)
+src/pa/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/pa/$(DEPDIR)
+	@: > src/pa/$(DEPDIR)/$(am__dirstamp)
+src/pa/linux.lo: src/pa/$(am__dirstamp) \
+	src/pa/$(DEPDIR)/$(am__dirstamp)
+src/pa/ffi.lo: src/pa/$(am__dirstamp) src/pa/$(DEPDIR)/$(am__dirstamp)
+src/pa/hpux32.lo: src/pa/$(am__dirstamp) \
+	src/pa/$(DEPDIR)/$(am__dirstamp)
+libffi.la: $(libffi_la_OBJECTS) $(libffi_la_DEPENDENCIES) 
+	$(libffi_la_LINK) -rpath $(libdir) $(libffi_la_OBJECTS) $(libffi_la_LIBADD) $(LIBS)
+libffi_convenience.la: $(libffi_convenience_la_OBJECTS) $(libffi_convenience_la_DEPENDENCIES) 
+	$(LINK)  $(libffi_convenience_la_OBJECTS) $(libffi_convenience_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+	-rm -f src/alpha/ffi.$(OBJEXT)
+	-rm -f src/alpha/ffi.lo
+	-rm -f src/alpha/osf.$(OBJEXT)
+	-rm -f src/alpha/osf.lo
+	-rm -f src/arm/ffi.$(OBJEXT)
+	-rm -f src/arm/ffi.lo
+	-rm -f src/arm/sysv.$(OBJEXT)
+	-rm -f src/arm/sysv.lo
+	-rm -f src/arm/trampoline.$(OBJEXT)
+	-rm -f src/arm/trampoline.lo
+	-rm -f src/avr32/ffi.$(OBJEXT)
+	-rm -f src/avr32/ffi.lo
+	-rm -f src/avr32/sysv.$(OBJEXT)
+	-rm -f src/avr32/sysv.lo
+	-rm -f src/closures.$(OBJEXT)
+	-rm -f src/closures.lo
+	-rm -f src/cris/ffi.$(OBJEXT)
+	-rm -f src/cris/ffi.lo
+	-rm -f src/cris/sysv.$(OBJEXT)
+	-rm -f src/cris/sysv.lo
+	-rm -f src/debug.$(OBJEXT)
+	-rm -f src/debug.lo
+	-rm -f src/frv/eabi.$(OBJEXT)
+	-rm -f src/frv/eabi.lo
+	-rm -f src/frv/ffi.$(OBJEXT)
+	-rm -f src/frv/ffi.lo
+	-rm -f src/ia64/ffi.$(OBJEXT)
+	-rm -f src/ia64/ffi.lo
+	-rm -f src/ia64/unix.$(OBJEXT)
+	-rm -f src/ia64/unix.lo
+	-rm -f src/java_raw_api.$(OBJEXT)
+	-rm -f src/java_raw_api.lo
+	-rm -f src/m32r/ffi.$(OBJEXT)
+	-rm -f src/m32r/ffi.lo
+	-rm -f src/m32r/sysv.$(OBJEXT)
+	-rm -f src/m32r/sysv.lo
+	-rm -f src/m68k/ffi.$(OBJEXT)
+	-rm -f src/m68k/ffi.lo
+	-rm -f src/m68k/sysv.$(OBJEXT)
+	-rm -f src/m68k/sysv.lo
+	-rm -f src/mips/ffi.$(OBJEXT)
+	-rm -f src/mips/ffi.lo
+	-rm -f src/mips/n32.$(OBJEXT)
+	-rm -f src/mips/n32.lo
+	-rm -f src/mips/o32.$(OBJEXT)
+	-rm -f src/mips/o32.lo
+	-rm -f src/pa/ffi.$(OBJEXT)
+	-rm -f src/pa/ffi.lo
+	-rm -f src/pa/hpux32.$(OBJEXT)
+	-rm -f src/pa/hpux32.lo
+	-rm -f src/pa/linux.$(OBJEXT)
+	-rm -f src/pa/linux.lo
+	-rm -f src/powerpc/aix.$(OBJEXT)
+	-rm -f src/powerpc/aix.lo
+	-rm -f src/powerpc/aix_closure.$(OBJEXT)
+	-rm -f src/powerpc/aix_closure.lo
+	-rm -f src/powerpc/darwin.$(OBJEXT)
+	-rm -f src/powerpc/darwin.lo
+	-rm -f src/powerpc/darwin_closure.$(OBJEXT)
+	-rm -f src/powerpc/darwin_closure.lo
+	-rm -f src/powerpc/ffi.$(OBJEXT)
+	-rm -f src/powerpc/ffi.lo
+	-rm -f src/powerpc/ffi_darwin.$(OBJEXT)
+	-rm -f src/powerpc/ffi_darwin.lo
+	-rm -f src/powerpc/linux64.$(OBJEXT)
+	-rm -f src/powerpc/linux64.lo
+	-rm -f src/powerpc/linux64_closure.$(OBJEXT)
+	-rm -f src/powerpc/linux64_closure.lo
+	-rm -f src/powerpc/ppc_closure.$(OBJEXT)
+	-rm -f src/powerpc/ppc_closure.lo
+	-rm -f src/powerpc/sysv.$(OBJEXT)
+	-rm -f src/powerpc/sysv.lo
+	-rm -f src/prep_cif.$(OBJEXT)
+	-rm -f src/prep_cif.lo
+	-rm -f src/raw_api.$(OBJEXT)
+	-rm -f src/raw_api.lo
+	-rm -f src/s390/ffi.$(OBJEXT)
+	-rm -f src/s390/ffi.lo
+	-rm -f src/s390/sysv.$(OBJEXT)
+	-rm -f src/s390/sysv.lo
+	-rm -f src/sh/ffi.$(OBJEXT)
+	-rm -f src/sh/ffi.lo
+	-rm -f src/sh/sysv.$(OBJEXT)
+	-rm -f src/sh/sysv.lo
+	-rm -f src/sh64/ffi.$(OBJEXT)
+	-rm -f src/sh64/ffi.lo
+	-rm -f src/sh64/sysv.$(OBJEXT)
+	-rm -f src/sh64/sysv.lo
+	-rm -f src/sparc/ffi.$(OBJEXT)
+	-rm -f src/sparc/ffi.lo
+	-rm -f src/sparc/v8.$(OBJEXT)
+	-rm -f src/sparc/v8.lo
+	-rm -f src/sparc/v9.$(OBJEXT)
+	-rm -f src/sparc/v9.lo
+	-rm -f src/types.$(OBJEXT)
+	-rm -f src/types.lo
+	-rm -f src/x86/darwin.$(OBJEXT)
+	-rm -f src/x86/darwin.lo
+	-rm -f src/x86/darwin64.$(OBJEXT)
+	-rm -f src/x86/darwin64.lo
+	-rm -f src/x86/ffi.$(OBJEXT)
+	-rm -f src/x86/ffi.lo
+	-rm -f src/x86/ffi64.$(OBJEXT)
+	-rm -f src/x86/ffi64.lo
+	-rm -f src/x86/freebsd.$(OBJEXT)
+	-rm -f src/x86/freebsd.lo
+	-rm -f src/x86/sysv.$(OBJEXT)
+	-rm -f src/x86/sysv.lo
+	-rm -f src/x86/unix64.$(OBJEXT)
+	-rm -f src/x86/unix64.lo
+	-rm -f src/x86/win32.$(OBJEXT)
+	-rm -f src/x86/win32.lo
+	-rm -f src/x86/win64.$(OBJEXT)
+	-rm -f src/x86/win64.lo
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at src/$(DEPDIR)/closures.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/$(DEPDIR)/debug.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/$(DEPDIR)/java_raw_api.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/$(DEPDIR)/prep_cif.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/$(DEPDIR)/raw_api.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/$(DEPDIR)/types.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/alpha/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/alpha/$(DEPDIR)/osf.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/arm/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/arm/$(DEPDIR)/sysv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/arm/$(DEPDIR)/trampoline.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/avr32/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/avr32/$(DEPDIR)/sysv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/cris/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/cris/$(DEPDIR)/sysv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/frv/$(DEPDIR)/eabi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/frv/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/ia64/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/ia64/$(DEPDIR)/unix.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/m32r/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/m32r/$(DEPDIR)/sysv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/m68k/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/m68k/$(DEPDIR)/sysv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/mips/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/mips/$(DEPDIR)/n32.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/mips/$(DEPDIR)/o32.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/pa/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/pa/$(DEPDIR)/hpux32.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/pa/$(DEPDIR)/linux.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/powerpc/$(DEPDIR)/aix.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/powerpc/$(DEPDIR)/aix_closure.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/powerpc/$(DEPDIR)/darwin.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/powerpc/$(DEPDIR)/darwin_closure.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/powerpc/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/powerpc/$(DEPDIR)/ffi_darwin.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/powerpc/$(DEPDIR)/linux64.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/powerpc/$(DEPDIR)/linux64_closure.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/powerpc/$(DEPDIR)/ppc_closure.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/powerpc/$(DEPDIR)/sysv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/s390/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/s390/$(DEPDIR)/sysv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/sh/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/sh/$(DEPDIR)/sysv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/sh64/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/sh64/$(DEPDIR)/sysv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/sparc/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/sparc/$(DEPDIR)/v8.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/sparc/$(DEPDIR)/v9.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/x86/$(DEPDIR)/darwin.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/x86/$(DEPDIR)/darwin64.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/x86/$(DEPDIR)/ffi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/x86/$(DEPDIR)/ffi64.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/x86/$(DEPDIR)/freebsd.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/x86/$(DEPDIR)/sysv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/x86/$(DEPDIR)/unix64.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/x86/$(DEPDIR)/win32.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at src/x86/$(DEPDIR)/win64.Plo at am__quote@
+
+.S.o:
+ at am__fastdepCCAS_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCCAS_TRUE@	$(CPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCCAS_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCCAS_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCCAS_FALSE@	DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCCAS_FALSE@	$(CPPASCOMPILE) -c -o $@ $<
+
+.S.obj:
+ at am__fastdepCCAS_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCCAS_TRUE@	$(CPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCCAS_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCCAS_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCCAS_FALSE@	DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCCAS_FALSE@	$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.S.lo:
+ at am__fastdepCCAS_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCCAS_TRUE@	$(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCCAS_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCCAS_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCCAS_FALSE@	DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCCAS_FALSE@	$(LTCPPASCOMPILE) -c -o $@ $<
+
+.c.o:
+ at am__fastdepCC_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+	-rm -rf src/.libs src/_libs
+	-rm -rf src/alpha/.libs src/alpha/_libs
+	-rm -rf src/arm/.libs src/arm/_libs
+	-rm -rf src/avr32/.libs src/avr32/_libs
+	-rm -rf src/cris/.libs src/cris/_libs
+	-rm -rf src/frv/.libs src/frv/_libs
+	-rm -rf src/ia64/.libs src/ia64/_libs
+	-rm -rf src/m32r/.libs src/m32r/_libs
+	-rm -rf src/m68k/.libs src/m68k/_libs
+	-rm -rf src/mips/.libs src/mips/_libs
+	-rm -rf src/pa/.libs src/pa/_libs
+	-rm -rf src/powerpc/.libs src/powerpc/_libs
+	-rm -rf src/s390/.libs src/s390/_libs
+	-rm -rf src/sh/.libs src/sh/_libs
+	-rm -rf src/sh64/.libs src/sh64/_libs
+	-rm -rf src/sparc/.libs src/sparc/_libs
+	-rm -rf src/x86/.libs src/x86/_libs
+
+distclean-libtool:
+	-rm -f libtool config.lt
+doc/$(am__dirstamp):
+	@$(MKDIR_P) doc
+	@: > doc/$(am__dirstamp)
+
+$(srcdir)/doc/libffi.info: doc/libffi.texi $(srcdir)/doc/version.texi
+	restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+	am__cwd=`pwd` && $(am__cd) $(srcdir) && \
+	rm -rf $$backupdir && mkdir $$backupdir && \
+	if ($(MAKEINFO) --version) >/dev/null 2>&1; then \
+	  for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
+	    if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
+	  done; \
+	else :; fi && \
+	cd "$$am__cwd"; \
+	if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc \
+	 -o $@ $(srcdir)/doc/libffi.texi; \
+	then \
+	  rc=0; \
+	  $(am__cd) $(srcdir); \
+	else \
+	  rc=$$?; \
+	  $(am__cd) $(srcdir) && \
+	  $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
+	fi; \
+	rm -rf $$backupdir; exit $$rc
+
+doc/libffi.dvi: doc/libffi.texi $(srcdir)/doc/version.texi doc/$(am__dirstamp)
+	TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+	MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc' \
+	$(TEXI2DVI) -o $@ `test -f 'doc/libffi.texi' || echo '$(srcdir)/'`doc/libffi.texi
+
+doc/libffi.pdf: doc/libffi.texi $(srcdir)/doc/version.texi doc/$(am__dirstamp)
+	TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+	MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc' \
+	$(TEXI2PDF) -o $@ `test -f 'doc/libffi.texi' || echo '$(srcdir)/'`doc/libffi.texi
+
+doc/libffi.html: doc/libffi.texi $(srcdir)/doc/version.texi doc/$(am__dirstamp)
+	rm -rf $(@:.html=.htp)
+	if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc \
+	 -o $(@:.html=.htp) `test -f 'doc/libffi.texi' || echo '$(srcdir)/'`doc/libffi.texi; \
+	then \
+	  rm -rf $@; \
+	  if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+	    mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
+	else \
+	  if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+	    rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
+	  exit 1; \
+	fi
+$(srcdir)/doc/version.texi: @MAINTAINER_MODE_TRUE@ $(srcdir)/doc/stamp-vti
+$(srcdir)/doc/stamp-vti: doc/libffi.texi $(top_srcdir)/configure
+	test -f doc/$(am__dirstamp) || $(MAKE) $(AM_MAKEFLAGS) doc/$(am__dirstamp)
+	@(dir=.; test -f ./doc/libffi.texi || dir=$(srcdir); \
+	set `$(SHELL) $(srcdir)/mdate-sh $$dir/doc/libffi.texi`; \
+	echo "@set UPDATED $$1 $$2 $$3"; \
+	echo "@set UPDATED-MONTH $$2 $$3"; \
+	echo "@set EDITION $(VERSION)"; \
+	echo "@set VERSION $(VERSION)") > vti.tmp
+	@cmp -s vti.tmp $(srcdir)/doc/version.texi \
+	  || (echo "Updating $(srcdir)/doc/version.texi"; \
+	      cp vti.tmp $(srcdir)/doc/version.texi)
+	- at rm -f vti.tmp
+	@cp $(srcdir)/doc/version.texi $@
+
+mostlyclean-vti:
+	-rm -f vti.tmp
+
+maintainer-clean-vti:
+ at MAINTAINER_MODE_TRUE@	-rm -f $(srcdir)/doc/stamp-vti $(srcdir)/doc/version.texi
+.dvi.ps:
+	TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+	$(DVIPS) -o $@ $<
+
+uninstall-dvi-am:
+	@$(NORMAL_UNINSTALL)
+	@list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(dvidir)/$$f"; \
+	done
+
+uninstall-html-am:
+	@$(NORMAL_UNINSTALL)
+	@list='$(HTMLS)'; test -n "$(htmldir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \
+	  rm -rf "$(DESTDIR)$(htmldir)/$$f"; \
+	done
+
+uninstall-info-am:
+	@$(PRE_UNINSTALL)
+	@if test -d '$(DESTDIR)$(infodir)' && \
+	    (install-info --version && \
+	     install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+	  list='$(INFO_DEPS)'; \
+	  for file in $$list; do \
+	    relfile=`echo "$$file" | sed 's|^.*/||'`; \
+	    echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
+	    if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
+	    then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \
+	  done; \
+	else :; fi
+	@$(NORMAL_UNINSTALL)
+	@list='$(INFO_DEPS)'; \
+	for file in $$list; do \
+	  relfile=`echo "$$file" | sed 's|^.*/||'`; \
+	  relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
+	  (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \
+	     echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \
+	     rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
+	   else :; fi); \
+	done
+
+uninstall-pdf-am:
+	@$(NORMAL_UNINSTALL)
+	@list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(pdfdir)/$$f"; \
+	done
+
+uninstall-ps-am:
+	@$(NORMAL_UNINSTALL)
+	@list='$(PSS)'; test -n "$(psdir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(psdir)/$$f"; \
+	done
+
+dist-info: $(INFO_DEPS)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	list='$(INFO_DEPS)'; \
+	for base in $$list; do \
+	  case $$base in \
+	    $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
+	  esac; \
+	  if test -f $$base; then d=.; else d=$(srcdir); fi; \
+	  base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \
+	  for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \
+	    if test -f $$file; then \
+	      relfile=`expr "$$file" : "$$d/\(.*\)"`; \
+	      test -f "$(distdir)/$$relfile" || \
+		cp -p $$file "$(distdir)/$$relfile"; \
+	    else :; fi; \
+	  done; \
+	done
+
+mostlyclean-aminfo:
+	-rm -rf libffi.aux libffi.cp libffi.cps libffi.fn libffi.ky libffi.log \
+	  libffi.pg libffi.tmp libffi.toc libffi.tp libffi.vr
+
+clean-aminfo:
+	-test -z "doc/libffi.dvi doc/libffi.pdf doc/libffi.ps doc/libffi.html" \
+	|| rm -rf doc/libffi.dvi doc/libffi.pdf doc/libffi.ps doc/libffi.html
+
+maintainer-clean-aminfo:
+	@list='$(INFO_DEPS)'; for i in $$list; do \
+	  i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
+	  echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
+	  rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
+	done
+install-pkgconfigDATA: $(pkgconfig_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
+	done
+
+uninstall-pkgconfigDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@fail= failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+	@fail= failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) fficonfig.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS) fficonfig.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) fficonfig.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS) fficonfig.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	$(am__remove_distdir)
+	test -d "$(distdir)" || mkdir "$(distdir)"
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(MKDIR_P) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+	$(MAKE) $(AM_MAKEFLAGS) \
+	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
+	  dist-info
+	-test -n "$(am__skip_mode_fix)" \
+	|| find "$(distdir)" -type d ! -perm -755 \
+		-exec chmod u+rwx,go+rx {} \; -o \
+	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+	|| chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+	$(am__remove_distdir)
+
+dist-lzma: distdir
+	tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+	$(am__remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
+	$(am__remove_distdir)
+
+dist-tarZ: distdir
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__remove_distdir)
+
+dist-shar: distdir
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__remove_distdir)
+
+dist dist-all: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	case '$(DIST_ARCHIVES)' in \
+	*.tar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lzma*) \
+	  lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+	*.tar.xz*) \
+	  xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+	*.shar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir); chmod a+w $(distdir)
+	mkdir $(distdir)/_build
+	mkdir $(distdir)/_inst
+	chmod a-w $(distdir)
+	test -d $(distdir)/_build || exit 0; \
+	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+	  && am__cwd=`pwd` \
+	  && $(am__cd) $(distdir)/_build \
+	  && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+	        distuninstallcheck \
+	  && chmod -R a-w "$$dc_install_base" \
+	  && ({ \
+	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
+	  && rm -rf "$$dc_destdir" \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist \
+	  && rm -rf $(DIST_ARCHIVES) \
+	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+	  && cd "$$am__cwd" \
+	  || exit 1
+	$(am__remove_distdir)
+	@(echo "$(distdir) archives ready for distribution: "; \
+	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+	  sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+	@$(am__cd) '$(distuninstallcheck_dir)' \
+	&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+	   || { echo "ERROR: files left after uninstall:" ; \
+	        if test -n "$(DESTDIR)"; then \
+	          echo "  (check DESTDIR support)"; \
+	        fi ; \
+	        $(distuninstallcheck_listfiles) ; \
+	        exit 1; } >&2
+distcleancheck: distclean
+	@if test '$(srcdir)' = . ; then \
+	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+	  exit 1 ; \
+	fi
+	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+	  || { echo "ERROR: files left in build directory after distclean:" ; \
+	       $(distcleancheck_listfiles) ; \
+	       exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(INFO_DEPS) $(LTLIBRARIES) $(DATA) fficonfig.h
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(infodir)" "$(DESTDIR)$(pkgconfigdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-rm -f doc/$(am__dirstamp)
+	-rm -f src/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/$(am__dirstamp)
+	-rm -f src/alpha/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/alpha/$(am__dirstamp)
+	-rm -f src/arm/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/arm/$(am__dirstamp)
+	-rm -f src/avr32/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/avr32/$(am__dirstamp)
+	-rm -f src/cris/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/cris/$(am__dirstamp)
+	-rm -f src/frv/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/frv/$(am__dirstamp)
+	-rm -f src/ia64/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/ia64/$(am__dirstamp)
+	-rm -f src/m32r/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/m32r/$(am__dirstamp)
+	-rm -f src/m68k/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/m68k/$(am__dirstamp)
+	-rm -f src/mips/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/mips/$(am__dirstamp)
+	-rm -f src/pa/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/pa/$(am__dirstamp)
+	-rm -f src/powerpc/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/powerpc/$(am__dirstamp)
+	-rm -f src/s390/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/s390/$(am__dirstamp)
+	-rm -f src/sh/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/sh/$(am__dirstamp)
+	-rm -f src/sh64/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/sh64/$(am__dirstamp)
+	-rm -f src/sparc/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/sparc/$(am__dirstamp)
+	-rm -f src/x86/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/x86/$(am__dirstamp)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-aminfo clean-generic clean-libLTLIBRARIES \
+	clean-libtool clean-noinstLTLIBRARIES mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf src/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-hdr distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am: $(DVIS)
+
+html: html-recursive
+
+html-am: $(HTMLS)
+
+info: info-recursive
+
+info-am: $(INFO_DEPS)
+
+install-data-am: install-info-am install-pkgconfigDATA
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am: $(DVIS)
+	@$(NORMAL_INSTALL)
+	test -z "$(dvidir)" || $(MKDIR_P) "$(DESTDIR)$(dvidir)"
+	@list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \
+	done
+install-exec-am: install-libLTLIBRARIES
+
+install-html-am: $(HTMLS)
+	@$(NORMAL_INSTALL)
+	test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)"
+	@list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  $(am__strip_dir) \
+	  if test -d "$$d$$p"; then \
+	    echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \
+	    $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
+	    echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \
+	    $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \
+	  else \
+	    list2="$$list2 $$d$$p"; \
+	  fi; \
+	done; \
+	test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \
+	done; }
+install-info: install-info-recursive
+
+install-info-am: $(INFO_DEPS)
+	@$(NORMAL_INSTALL)
+	test -z "$(infodir)" || $(MKDIR_P) "$(DESTDIR)$(infodir)"
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+	for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	  esac; \
+	  if test -f $$file; then d=.; else d=$(srcdir); fi; \
+	  file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
+	  for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
+	               $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
+	    if test -f $$ifile; then \
+	      echo "$$ifile"; \
+	    else : ; fi; \
+	  done; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done
+	@$(POST_INSTALL)
+	@if (install-info --version && \
+	     install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+	  list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+	  for file in $$list; do \
+	    relfile=`echo "$$file" | sed 's|^.*/||'`; \
+	    echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
+	    install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
+	  done; \
+	else : ; fi
+install-man:
+
+install-pdf-am: $(PDFS)
+	@$(NORMAL_INSTALL)
+	test -z "$(pdfdir)" || $(MKDIR_P) "$(DESTDIR)$(pdfdir)"
+	@list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done
+install-ps: install-ps-recursive
+
+install-ps-am: $(PSS)
+	@$(NORMAL_INSTALL)
+	test -z "$(psdir)" || $(MKDIR_P) "$(DESTDIR)$(psdir)"
+	@list='$(PSS)'; test -n "$(psdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-rm -rf src/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-aminfo \
+	maintainer-clean-generic maintainer-clean-vti
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-aminfo mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool mostlyclean-vti
+
+pdf: pdf-recursive
+
+pdf-am: $(PDFS)
+
+ps: ps-recursive
+
+ps-am: $(PSS)
+
+uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \
+	uninstall-libLTLIBRARIES uninstall-pdf-am \
+	uninstall-pkgconfigDATA uninstall-ps-am
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \
+	ctags-recursive install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+	all all-am am--refresh check check-am clean clean-aminfo \
+	clean-generic clean-libLTLIBRARIES clean-libtool \
+	clean-noinstLTLIBRARIES ctags ctags-recursive dist dist-all \
+	dist-bzip2 dist-gzip dist-info dist-lzma dist-shar dist-tarZ \
+	dist-xz dist-zip distcheck distclean distclean-compile \
+	distclean-generic distclean-hdr distclean-libtool \
+	distclean-tags distcleancheck distdir distuninstallcheck dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-libLTLIBRARIES \
+	install-man install-pdf install-pdf-am install-pkgconfigDATA \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs installdirs-am maintainer-clean \
+	maintainer-clean-aminfo maintainer-clean-generic \
+	maintainer-clean-vti mostlyclean mostlyclean-aminfo \
+	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+	mostlyclean-vti pdf pdf-am ps ps-am tags tags-recursive \
+	uninstall uninstall-am uninstall-dvi-am uninstall-html-am \
+	uninstall-info-am uninstall-libLTLIBRARIES uninstall-pdf-am \
+	uninstall-pkgconfigDATA uninstall-ps-am
+
+
+# No install-html or install-pdf support in automake yet
+.PHONY: install-html install-pdf
+install-html:
+install-pdf:
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/Makefile.vc b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/Makefile.vc
new file mode 100755
index 0000000..c22c895
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/Makefile.vc
@@ -0,0 +1,141 @@
+#
+# ====================================================================
+#
+# libffi Windows Makefile
+#
+#
+# ====================================================================
+#
+
+NAME=ffi-3
+VERSION=3.0.10
+TARGET=X86_WIN32
+CC=cl.exe
+AS=ml.exe
+RC=rc.exe
+MT=mt.exe
+AR="link.exe"
+SO=.dll
+OBJ=.obj
+EXE=.exe
+LA=.lib
+LINK="link.exe"
+PREFIX=
+TOPDIR=.
+CPP=cl.exe -EP
+CFLAGS=-nologo -Zi -D_MD -W3 -DWIN32 -DWINNT -D_WIN32 -D_WINDOWS -D_WINNT -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0600 -D_X86_=1 -DNDEBUG -MD -O2 -Ob2 -Oy-
+LDFLAGS=/NOLOGO /MACHINE:X86
+SHFLAGS=/DLL /INCREMENTAL:NO /DEBUG /SUBSYSTEM:WINDOWS /OPT:REF
+ARFLAGS=/LIB
+ASFLAGS=-coff -W3 -Cx -Zm -Di386 -DQUIET -D?QUIET
+RCFLAGS=/l 0x409 -DNDEBUG
+INCLUDES=-I . -I .\include -I .\src\x86 
+LIBS=kernel32.lib advapi32.lib shell32.lib user32.lib gdi32.lib
+
+VERSION_MAJOR=3
+VERSION_MINOR=1
+VERSION_PATCH=10rc
+
+DESTDIR=$(PREFIX)
+DESTBIN=$(PREFIX)\bin
+DESTLIB=$(PREFIX)\lib
+DESTINC=$(PREFIX)\include
+SRCDIR=$(TOPDIR)\src
+
+WORKDIR=$(TOPDIR)\.libs
+SOLIBNAME=lib$(NAME)
+LALIBNAME=libffi_convenience
+STATICLIB=$(WORKDIR)\$(LALIBNAME)$(LA)
+
+BUILDPDB = $(WORKDIR)\$(SOLIBNAME).pdb
+
+HEADERS = \
+	$(TOPDIR)\fficonfig.h
+
+FFI_HEADERS = \
+	$(TOPDIR)\include\ffi.h
+	
+OBJECTS = \
+	$(SRCDIR)\closures.obj \
+	$(SRCDIR)\debug.obj \
+	$(SRCDIR)\java_raw_api.obj \
+	$(SRCDIR)\prep_cif.obj \
+	$(SRCDIR)\raw_api.obj \
+	$(SRCDIR)\types.obj \
+	$(SRCDIR)\x86\ffi.obj
+
+!IF "$(TARGET)" == "X86_WIN32"
+OBJECTS = $(OBJECTS) \
+	$(SRCDIR)\x86\win32.obj
+ASMSRCS = \
+    $(SRCDIR)\x86\win32.asm
+    
+!ENDIF
+!IF "$(TARGET)" == "X86_WIN64"
+OBJECTS = $(OBJECTS) \
+	$(SRCDIR)\x86\win64.obj
+ASMSRCS = \
+    $(SRCDIR)\x86\win64.asm
+
+!ENDIF
+
+.SUFFIXES : .S .asm
+
+all: $(WORKDIR) $(STATICLIB)
+
+.c$(OBJ):
+	$(CC) -c $(CFLAGS) $(INCLUDES) -Fo$@ -Fd$(WORKDIR)\$(NAME)-src $<
+
+.asm$(OBJ):
+	$(AS) -c $(ASFLAGS) /Fo $@ $<
+
+.S.asm:
+	$(CPP) $(CFLAGS) $(INCLUDES) $< >$@
+
+.rc.res:
+	$(RC) $(RCFLAGS) /fo $@ $<
+
+$(WORKDIR) :
+	- at if not exist "$(WORKDIR)\$(NULL)" mkdir $(WORKDIR)
+
+$(HEADERS) :
+	- at if not exist $(HEADERS) copy $(HEADERS)w $(HEADERS)
+
+$(FFI_HEADERS) :
+	- at if not exist $(FFI_HEADERS) copy $(FFI_HEADERS).vc $(FFI_HEADERS)
+	
+$(STATICLIB): $(WORKDIR) $(FFI_HEADERS) $(HEADERS) $(ASMSRCS) $(OBJECTS)
+	$(AR) $(ARFLAGS) $(LDFLAGS) /out:$(STATICLIB) @<<
+	$(OBJECTS)
+<<
+
+
+!IF !DEFINED(PREFIX) || "$(PREFIX)" == ""
+
+install:
+	@echo ERROR: You must define installation PREFIX=destination
+
+!ELSE
+
+install: all
+	- at xcopy "$(TOPDIR)\include\*.h" "$(DESTINC)\" /Y /Q
+	- at xcopy "$(SRCDIR)\x86\ffitarget.h" "$(DESTINC)\" /Y /Q
+	- at xcopy "$(WORKDIR)\$(LALIBNAME)$(LA)" "$(DESTLIB)\" /Y /Q
+	- at xcopy "$(WORKDIR)\$(SOLIBNAME)$(LA)" "$(DESTLIB)\" /Y /Q
+	- at xcopy "$(WORKDIR)\$(SOLIBNAME)$(SO)" "$(DESTBIN)\" /Y /Q
+	- at xcopy "$(WORKDIR)\$(SOLIBNAME).pdb" "$(DESTLIB)\" /Y /Q
+
+!ENDIF
+
+clean:
+	- at del /Q $(OBJECTS) 2>NUL
+	- at del /Q $(RESOURCES) 2>NUL
+	- at del /Q $(ASMSRCS) 2>NUL
+	- at del /Q /S $(WORKDIR) 2>NUL
+
+distclean: clean
+	- at del /Q $(HEADERS) 2>NUL
+	- at del /Q $(TOPDIR)\include\ffi.h 2>NUL
+	- at del /Q $(TOPDIR)\fficonfig.h 2>NUL
+	- at del /Q $(TOPDIR)\Makefile.vc 2>NUL
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/Makefile.vc64 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/Makefile.vc64
new file mode 100755
index 0000000..3e99baa
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/Makefile.vc64
@@ -0,0 +1,141 @@
+#
+# ====================================================================
+#
+# libffi Windows Makefile
+#
+#
+# ====================================================================
+#
+
+NAME=ffi-3
+VERSION=3.0.10
+TARGET=X86_WIN64
+CC=cl.exe
+AS=ml64.exe
+RC=rc.exe
+MT=mt.exe
+AR="link.exe"
+SO=.dll
+OBJ=.obj
+EXE=.exe
+LA=.lib
+LINK="link.exe"
+PREFIX=
+TOPDIR=.
+CPP=cl.exe -EP
+CFLAGS=-nologo -Zi -D_MD -W3 -DWIN64 -DWINNT -D_WIN32 -D_WINDOWS -D_WINNT -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0600 -D_AMD64_=1 -DNDEBUG -MD -O2 -Ob2 -Oy-
+LDFLAGS=/NOLOGO /MACHINE:X64
+SHFLAGS=/DLL /INCREMENTAL:NO /DEBUG /SUBSYSTEM:WINDOWS /OPT:REF
+ARFLAGS=/LIB
+ASFLAGS=-coff -W3 -Cx -Zm -Di386 -DQUIET -D?QUIET
+RCFLAGS=/l 0x409 -DNDEBUG
+INCLUDES=-I . -I .\include -I .\src\x86 
+LIBS=kernel32.lib advapi32.lib shell32.lib user32.lib gdi32.lib
+
+VERSION_MAJOR=3
+VERSION_MINOR=1
+VERSION_PATCH=10rc
+
+DESTDIR=$(PREFIX)
+DESTBIN=$(PREFIX)\bin
+DESTLIB=$(PREFIX)\lib
+DESTINC=$(PREFIX)\include
+SRCDIR=$(TOPDIR)\src
+
+WORKDIR=$(TOPDIR)\.libs
+SOLIBNAME=lib$(NAME)
+LALIBNAME=libffi_convenience
+STATICLIB=$(WORKDIR)\$(LALIBNAME)$(LA)
+
+BUILDPDB = $(WORKDIR)\$(SOLIBNAME).pdb
+
+HEADERS = \
+	$(TOPDIR)\fficonfig.h
+
+FFI_HEADERS = \
+	$(TOPDIR)\include\ffi.h
+	
+OBJECTS = \
+	$(SRCDIR)\closures.obj \
+	$(SRCDIR)\debug.obj \
+	$(SRCDIR)\java_raw_api.obj \
+	$(SRCDIR)\prep_cif.obj \
+	$(SRCDIR)\raw_api.obj \
+	$(SRCDIR)\types.obj \
+	$(SRCDIR)\x86\ffi.obj
+
+!IF "$(TARGET)" == "X86_WIN32"
+OBJECTS = $(OBJECTS) \
+	$(SRCDIR)\x86\win32.obj
+ASMSRCS = \
+    $(SRCDIR)\x86\win32.asm
+    
+!ENDIF
+!IF "$(TARGET)" == "X86_WIN64"
+OBJECTS = $(OBJECTS) \
+	$(SRCDIR)\x86\win64.obj
+ASMSRCS = \
+    $(SRCDIR)\x86\win64.asm
+
+!ENDIF
+
+.SUFFIXES : .S .asm
+
+all: $(WORKDIR) $(STATICLIB)
+
+.c$(OBJ):
+	$(CC) -c $(CFLAGS) $(INCLUDES) -Fo$@ -Fd$(WORKDIR)\$(NAME)-src $<
+
+.asm$(OBJ):
+	$(AS) -c $(ASFLAGS) /Fo $@ $<
+
+.S.asm:
+	$(CPP) $(CFLAGS) $(INCLUDES) $< >$@
+
+.rc.res:
+	$(RC) $(RCFLAGS) /fo $@ $<
+
+$(WORKDIR) :
+	- at if not exist "$(WORKDIR)\$(NULL)" mkdir $(WORKDIR)
+
+$(HEADERS) :
+	- at if not exist $(HEADERS) copy $(HEADERS)w $(HEADERS)
+
+$(FFI_HEADERS) :
+	- at if not exist $(FFI_HEADERS) copy $(FFI_HEADERS).vc64 $(FFI_HEADERS)
+	
+$(STATICLIB): $(WORKDIR) $(FFI_HEADERS) $(HEADERS) $(ASMSRCS) $(OBJECTS)
+	$(AR) $(ARFLAGS) $(LDFLAGS) /out:$(STATICLIB) @<<
+	$(OBJECTS)
+<<
+
+
+!IF !DEFINED(PREFIX) || "$(PREFIX)" == ""
+
+install:
+	@echo ERROR: You must define installation PREFIX=destination
+
+!ELSE
+
+install: all
+	- at xcopy "$(TOPDIR)\include\*.h" "$(DESTINC)\" /Y /Q
+	- at xcopy "$(SRCDIR)\x86\ffitarget.h" "$(DESTINC)\" /Y /Q
+	- at xcopy "$(WORKDIR)\$(LALIBNAME)$(LA)" "$(DESTLIB)\" /Y /Q
+	- at xcopy "$(WORKDIR)\$(SOLIBNAME)$(LA)" "$(DESTLIB)\" /Y /Q
+	- at xcopy "$(WORKDIR)\$(SOLIBNAME)$(SO)" "$(DESTBIN)\" /Y /Q
+	- at xcopy "$(WORKDIR)\$(SOLIBNAME).pdb" "$(DESTLIB)\" /Y /Q
+
+!ENDIF
+
+clean:
+	- at del /Q $(OBJECTS) 2>NUL
+	- at del /Q $(RESOURCES) 2>NUL
+	- at del /Q $(ASMSRCS) 2>NUL
+	- at del /Q /S $(WORKDIR) 2>NUL
+
+distclean: clean
+	- at del /Q $(HEADERS) 2>NUL
+	- at del /Q $(TOPDIR)\include\ffi.h 2>NUL
+	- at del /Q $(TOPDIR)\fficonfig.h 2>NUL
+	- at del /Q $(TOPDIR)\Makefile.vc 2>NUL
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/README b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/README
new file mode 100755
index 0000000..297c044
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/README
@@ -0,0 +1,342 @@
+Status
+======
+
+libffi-3.0.10 was released on August 23, 2011. Check the libffi web
+page for updates: <URL:http://sourceware.org/libffi/>.
+
+
+What is libffi?
+===============
+
+Compilers for high level languages generate code that follow certain
+conventions. These conventions are necessary, in part, for separate
+compilation to work. One such convention is the "calling
+convention". The "calling convention" is essentially a set of
+assumptions made by the compiler about where function arguments will
+be found on entry to a function. A "calling convention" also specifies
+where the return value for a function is found.
+
+Some programs may not know at the time of compilation what arguments
+are to be passed to a function. For instance, an interpreter may be
+told at run-time about the number and types of arguments used to call
+a given function. Libffi can be used in such programs to provide a
+bridge from the interpreter program to compiled code.
+
+The libffi library provides a portable, high level programming
+interface to various calling conventions. This allows a programmer to
+call any function specified by a call interface description at run
+time.  
+
+FFI stands for Foreign Function Interface.  A foreign function
+interface is the popular name for the interface that allows code
+written in one language to call code written in another language. The
+libffi library really only provides the lowest, machine dependent
+layer of a fully featured foreign function interface. A layer must
+exist above libffi that handles type conversions for values passed
+between the two languages.
+
+
+Supported Platforms
+===================
+
+Libffi has been ported to many different platforms.
+For specific configuration details and testing status, please
+refer to the wiki page here:
+
+ http://www.moxielogic.org/wiki/index.php?title=Libffi_3.0.10
+
+At the time of release, the following basic configurations have been
+tested:
+
+|--------------+------------------|
+| Architecture | Operating System |
+|--------------+------------------|
+| Alpha        | Linux            |
+| Alpha        | Tru64            |
+| ARM          | Linux            |
+| ARM          | iOS              |
+| AVR32        | Linux            |
+| HPPA         | HPUX             |
+| IA-64        | Linux            |
+| M68K         | RTEMS            |
+| MIPS         | IRIX             |
+| MIPS         | Linux            |
+| MIPS         | RTEMS            |
+| MIPS64       | Linux            |
+| PowerPC      | Linux            |
+| PowerPC      | Mac OSX          |
+| PowerPC      | FreeBSD          |
+| PowerPC64    | Linux            |
+| S390         | Linux            |
+| S390X        | Linux            |
+| SPARC        | Linux            |
+| SPARC        | Solaris          |
+| SPARC64      | Linux            |
+| SPARC64      | FreeBSD          |
+| X86          | FreeBSD          |
+| X86          | Interix          |
+| X86          | kFreeBSD         |
+| X86          | Linux            |
+| X86          | Mac OSX          |
+| X86          | OpenBSD          |
+| X86          | OS/2             |
+| X86          | Solaris          |
+| X86          | Windows/Cygwin   |
+| X86          | Windows/MingW    |
+| X86-64       | FreeBSD          |
+| X86-64       | Linux            |
+| X86-64       | OpenBSD          |
+| X86-64       | Windows/MingW    |
+|--------------+------------------|
+
+Please send additional platform test results to
+libffi-discuss at sourceware.org and feel free to update the wiki page
+above.
+
+Installing libffi
+=================
+
+First you must configure the distribution for your particular
+system. Go to the directory you wish to build libffi in and run the
+"configure" program found in the root directory of the libffi source
+distribution.
+
+You may want to tell configure where to install the libffi library and
+header files. To do that, use the --prefix configure switch.  Libffi
+will install under /usr/local by default. 
+
+If you want to enable extra run-time debugging checks use the the
+--enable-debug configure switch. This is useful when your program dies
+mysteriously while using libffi. 
+
+Another useful configure switch is --enable-purify-safety. Using this
+will add some extra code which will suppress certain warnings when you
+are using Purify with libffi. Only use this switch when using 
+Purify, as it will slow down the library.
+
+It's also possible to build libffi on Windows platforms with
+Microsoft's Visual C++ compiler.  In this case, use the msvcc.sh
+wrapper script during configuration like so:
+
+path/to/configure CC=path/to/msvcc.sh LD=link CPP=\"cl -nologo -EP\"
+
+For 64-bit Windows builds, use CC="path/to/msvcc.sh -m64".
+You may also need to specify --build appropriately. When building with MSVC
+under a MingW environment, you may need to remove the line in configure
+that sets 'fix_srcfile_path' to a 'cygpath' command. ('cygpath' is not
+present in MingW, and is not required when using MingW-style paths.)
+
+For iOS builds, refer to the build-ios.sh script for guidance.
+
+Configure has many other options. Use "configure --help" to see them all.
+
+Once configure has finished, type "make". Note that you must be using
+GNU make.  You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
+
+To ensure that libffi is working as advertised, type "make check".
+This will require that you have DejaGNU installed.
+
+To install the library and header files, type "make install".
+
+
+History
+=======
+
+See the ChangeLog files for details.
+
+3.0.10 Aug-23-11
+        Add support for Apple's iOS.
+	Add support for ARM VFP ABI.
+        Add RTEMS support for MIPS and M68K.
+	Fix instruction cache clearing problems on
+	  ARM and SPARC.
+	Fix the N64 build on mips-sgi-irix6.5.
+	Enable builds with Microsoft's compiler.
+	Enable x86 builds with Oracle's Solaris compiler.
+	Fix support for calling code compiled with Oracle's Sparc
+	  Solaris compiler.
+	Testsuite fixes for Tru64 Unix.
+	Additional platform support.
+
+3.0.9 Dec-31-09
+        Add AVR32 and win64 ports.  Add ARM softfp support.
+	Many fixes for AIX, Solaris, HP-UX, *BSD.
+	Several PowerPC and x86-64 bug fixes.
+	Build DLL for windows.
+
+3.0.8 Dec-19-08
+        Add *BSD, BeOS, and PA-Linux support.
+
+3.0.7 Nov-11-08
+        Fix for ppc FreeBSD.
+	(thanks to Andreas Tobler)
+
+3.0.6 Jul-17-08
+        Fix for closures on sh.
+	Mark the sh/sh64 stack as non-executable.
+	(both thanks to Kaz Kojima)
+
+3.0.5 Apr-3-08
+        Fix libffi.pc file.
+	Fix #define ARM for IcedTea users.
+	Fix x86 closure bug.
+
+3.0.4 Feb-24-08
+        Fix x86 OpenBSD configury.
+
+3.0.3 Feb-22-08
+        Enable x86 OpenBSD thanks to Thomas Heller, and
+	x86-64 FreeBSD thanks to Björn König and Andreas Tobler.
+	Clean up test instruction in README.
+
+3.0.2 Feb-21-08
+        Improved x86 FreeBSD support.
+	Thanks to Björn König.
+
+3.0.1 Feb-15-08
+        Fix instruction cache flushing bug on MIPS.
+	Thanks to David Daney.
+
+3.0.0 Feb-15-08
+        Many changes, mostly thanks to the GCC project.
+	Cygnus Solutions is now Red Hat.
+
+  [10 years go by...]
+
+1.20 Oct-5-98
+	Raffaele Sena produces ARM port.
+
+1.19 Oct-5-98
+	Fixed x86 long double and long long return support.
+	m68k bug fixes from Andreas Schwab.
+	Patch for DU assembler compatibility for the Alpha from Richard
+	Henderson.
+
+1.18 Apr-17-98
+	Bug fixes and MIPS configuration changes.
+
+1.17 Feb-24-98
+	Bug fixes and m68k port from Andreas Schwab. PowerPC port from
+	Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes.
+
+1.16 Feb-11-98
+	Richard Henderson produces Alpha port.
+
+1.15 Dec-4-97
+	Fixed an n32 ABI bug. New libtool, auto* support.
+
+1.14 May-13-97
+	libtool is now used to generate shared and static libraries.
+	Fixed a minor portability problem reported by Russ McManus
+	<mcmanr at eq.gs.com>.
+
+1.13 Dec-2-96
+	Added --enable-purify-safety to keep Purify from complaining
+	about certain low level code.
+	Sparc fix for calling functions with < 6 args.
+	Linux x86 a.out fix.
+
+1.12 Nov-22-96
+	Added missing ffi_type_void, needed for supporting void return 
+	types. Fixed test case for non MIPS machines. Cygnus Support 
+	is now Cygnus Solutions. 
+
+1.11 Oct-30-96
+	Added notes about GNU make.
+
+1.10 Oct-29-96
+	Added configuration fix for non GNU compilers.
+
+1.09 Oct-29-96
+	Added --enable-debug configure switch. Clean-ups based on LCLint 
+	feedback. ffi_mips.h is always installed. Many configuration 
+	fixes. Fixed ffitest.c for sparc builds.
+
+1.08 Oct-15-96
+	Fixed n32 problem. Many clean-ups.
+
+1.07 Oct-14-96
+	Gordon Irlam rewrites v8.S again. Bug fixes.
+
+1.06 Oct-14-96
+	Gordon Irlam improved the sparc port. 
+
+1.05 Oct-14-96
+	Interface changes based on feedback.
+
+1.04 Oct-11-96
+	Sparc port complete (modulo struct passing bug).
+
+1.03 Oct-10-96
+	Passing struct args, and returning struct values works for
+	all architectures/calling conventions. Expanded tests.
+
+1.02 Oct-9-96
+	Added SGI n32 support. Fixed bugs in both o32 and Linux support.
+	Added "make test".
+
+1.01 Oct-8-96
+	Fixed float passing bug in mips version. Restructured some
+	of the code. Builds cleanly with SGI tools.
+
+1.00 Oct-7-96
+	First release. No public announcement.
+
+
+Authors & Credits
+=================
+
+libffi was originally written by Anthony Green <green at redhat.com>.
+
+The developers of the GNU Compiler Collection project have made
+innumerable valuable contributions.  See the ChangeLog file for
+details.
+
+Some of the ideas behind libffi were inspired by Gianni Mariani's free
+gencall library for Silicon Graphics machines.
+
+The closure mechanism was designed and implemented by Kresten Krab
+Thorup.
+
+Major processor architecture ports were contributed by the following
+developers:
+
+alpha		Richard Henderson
+arm		Raffaele Sena
+cris		Simon Posnjak, Hans-Peter Nilsson
+frv		Anthony Green
+ia64		Hans Boehm
+m32r		Kazuhiro Inaoka
+m68k		Andreas Schwab
+mips		Anthony Green, Casey Marshall
+mips64		David Daney
+pa		Randolph Chung, Dave Anglin, Andreas Tobler
+powerpc		Geoffrey Keating, Andreas Tobler, 
+			 David Edelsohn, John Hornkvist
+powerpc64	Jakub Jelinek
+s390		Gerhard Tonn, Ulrich Weigand
+sh		Kaz Kojima
+sh64		Kaz Kojima
+sparc		Anthony Green, Gordon Irlam
+x86		Anthony Green, Jon Beniston
+x86-64		Bo Thorsen
+
+Jesper Skov and Andrew Haley both did more than their fair share of
+stepping through the code and tracking down bugs.
+
+Thanks also to Tom Tromey for bug fixes, documentation and
+configuration help.
+
+Thanks to Jim Blandy, who provided some useful feedback on the libffi
+interface.
+
+Andreas Tobler has done a tremendous amount of work on the testsuite.
+
+Alex Oliva solved the executable page problem for SElinux.
+
+The list above is almost certainly incomplete and inaccurate.  I'm
+happy to make corrections or additions upon request.
+
+If you have a problem, or have found a bug, please send a note to the
+author at green at moxielogic.com, or the project mailing list at
+libffi-discuss at sourceware.org.
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/acinclude.m4 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/acinclude.m4
new file mode 100755
index 0000000..3e8f8ba
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/acinclude.m4
@@ -0,0 +1,92 @@
+# mmap(2) blacklisting.  Some platforms provide the mmap library routine
+# but don't support all of the features we need from it.
+AC_DEFUN([AC_FUNC_MMAP_BLACKLIST],
+[
+AC_CHECK_HEADER([sys/mman.h],
+		[libffi_header_sys_mman_h=yes], [libffi_header_sys_mman_h=no])
+AC_CHECK_FUNC([mmap], [libffi_func_mmap=yes], [libffi_func_mmap=no])
+if test "$libffi_header_sys_mman_h" != yes \
+ || test "$libffi_func_mmap" != yes; then
+   ac_cv_func_mmap_file=no
+   ac_cv_func_mmap_dev_zero=no
+   ac_cv_func_mmap_anon=no
+else
+   AC_CACHE_CHECK([whether read-only mmap of a plain file works],
+  ac_cv_func_mmap_file,
+  [# Add a system to this blacklist if
+   # mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a
+   # memory area containing the same data that you'd get if you applied
+   # read() to the same fd.  The only system known to have a problem here
+   # is VMS, where text files have record structure.
+   case "$host_os" in
+     vms* | ultrix*)
+	ac_cv_func_mmap_file=no ;;
+     *)
+	ac_cv_func_mmap_file=yes;;
+   esac])
+   AC_CACHE_CHECK([whether mmap from /dev/zero works],
+  ac_cv_func_mmap_dev_zero,
+  [# Add a system to this blacklist if it has mmap() but /dev/zero
+   # does not exist, or if mmapping /dev/zero does not give anonymous
+   # zeroed pages with both the following properties:
+   # 1. If you map N consecutive pages in with one call, and then
+   #    unmap any subset of those pages, the pages that were not
+   #    explicitly unmapped remain accessible.
+   # 2. If you map two adjacent blocks of memory and then unmap them
+   #    both at once, they must both go away.
+   # Systems known to be in this category are Windows (all variants),
+   # VMS, and Darwin.
+   case "$host_os" in
+     vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
+	ac_cv_func_mmap_dev_zero=no ;;
+     *)
+	ac_cv_func_mmap_dev_zero=yes;;
+   esac])
+
+   # Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for.
+   AC_CACHE_CHECK([for MAP_ANON(YMOUS)], ac_cv_decl_map_anon,
+    [AC_TRY_COMPILE(
+[#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+],
+[int n = MAP_ANONYMOUS;],
+    ac_cv_decl_map_anon=yes,
+    ac_cv_decl_map_anon=no)])
+
+   if test $ac_cv_decl_map_anon = no; then
+     ac_cv_func_mmap_anon=no
+   else
+     AC_CACHE_CHECK([whether mmap with MAP_ANON(YMOUS) works],
+     ac_cv_func_mmap_anon,
+  [# Add a system to this blacklist if it has mmap() and MAP_ANON or
+   # MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
+   # doesn't give anonymous zeroed pages with the same properties listed
+   # above for use of /dev/zero.
+   # Systems known to be in this category are Windows, VMS, and SCO Unix.
+   case "$host_os" in
+     vms* | cygwin* | pe | mingw* | sco* | udk* )
+	ac_cv_func_mmap_anon=no ;;
+     *)
+	ac_cv_func_mmap_anon=yes;;
+   esac])
+   fi
+fi
+
+if test $ac_cv_func_mmap_file = yes; then
+  AC_DEFINE(HAVE_MMAP_FILE, 1,
+	    [Define if read-only mmap of a plain file works.])
+fi
+if test $ac_cv_func_mmap_dev_zero = yes; then
+  AC_DEFINE(HAVE_MMAP_DEV_ZERO, 1,
+	    [Define if mmap of /dev/zero works.])
+fi
+if test $ac_cv_func_mmap_anon = yes; then
+  AC_DEFINE(HAVE_MMAP_ANON, 1,
+	    [Define if mmap with MAP_ANON(YMOUS) works.])
+fi
+])
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/aclocal.m4 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/aclocal.m4
new file mode 100755
index 0000000..6132c39
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/aclocal.m4
@@ -0,0 +1,1873 @@
+# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],,
+[m4_warning([this file was generated for autoconf 2.68.
+You have another version of autoconf.  It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# ltdl.m4 - Configure ltdl for the target system. -*-Autoconf-*-
+#
+#   Copyright (C) 1999-2006, 2007, 2008 Free Software Foundation, Inc.
+#   Written by Thomas Tanner, 1999
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 18 LTDL_INIT
+
+# LT_CONFIG_LTDL_DIR(DIRECTORY, [LTDL-MODE])
+# ------------------------------------------
+# DIRECTORY contains the libltdl sources.  It is okay to call this
+# function multiple times, as long as the same DIRECTORY is always given.
+AC_DEFUN([LT_CONFIG_LTDL_DIR],
+[AC_BEFORE([$0], [LTDL_INIT])
+_$0($*)
+])# LT_CONFIG_LTDL_DIR
+
+# We break this out into a separate macro, so that we can call it safely
+# internally without being caught accidentally by the sed scan in libtoolize.
+m4_defun([_LT_CONFIG_LTDL_DIR],
+[dnl remove trailing slashes
+m4_pushdef([_ARG_DIR], m4_bpatsubst([$1], [/*$]))
+m4_case(_LTDL_DIR,
+	[], [dnl only set lt_ltdl_dir if _ARG_DIR is not simply `.'
+	     m4_if(_ARG_DIR, [.],
+	             [],
+		 [m4_define([_LTDL_DIR], _ARG_DIR)
+	          _LT_SHELL_INIT([lt_ltdl_dir=']_ARG_DIR['])])],
+    [m4_if(_ARG_DIR, _LTDL_DIR,
+	    [],
+	[m4_fatal([multiple libltdl directories: `]_LTDL_DIR[', `]_ARG_DIR['])])])
+m4_popdef([_ARG_DIR])
+])# _LT_CONFIG_LTDL_DIR
+
+# Initialise:
+m4_define([_LTDL_DIR], [])
+
+
+# _LT_BUILD_PREFIX
+# ----------------
+# If Autoconf is new enough, expand to `${top_build_prefix}', otherwise
+# to `${top_builddir}/'.
+m4_define([_LT_BUILD_PREFIX],
+[m4_ifdef([AC_AUTOCONF_VERSION],
+   [m4_if(m4_version_compare(m4_defn([AC_AUTOCONF_VERSION]), [2.62]),
+	  [-1], [m4_ifdef([_AC_HAVE_TOP_BUILD_PREFIX],
+			  [${top_build_prefix}],
+			  [${top_builddir}/])],
+	  [${top_build_prefix}])],
+   [${top_builddir}/])[]dnl
+])
+
+
+# LTDL_CONVENIENCE
+# ----------------
+# sets LIBLTDL to the link flags for the libltdl convenience library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-convenience to the configure arguments.  Note that
+# AC_CONFIG_SUBDIRS is not called here.  LIBLTDL will be prefixed with
+# '${top_build_prefix}' if available, otherwise with '${top_builddir}/',
+# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single
+# quotes!).  If your package is not flat and you're not using automake,
+# define top_build_prefix, top_builddir, and top_srcdir appropriately
+# in your Makefiles.
+AC_DEFUN([LTDL_CONVENIENCE],
+[AC_BEFORE([$0], [LTDL_INIT])dnl
+dnl Although the argument is deprecated and no longer documented,
+dnl LTDL_CONVENIENCE used to take a DIRECTORY orgument, if we have one
+dnl here make sure it is the same as any other declaration of libltdl's
+dnl location!  This also ensures lt_ltdl_dir is set when configure.ac is
+dnl not yet using an explicit LT_CONFIG_LTDL_DIR.
+m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl
+_$0()
+])# LTDL_CONVENIENCE
+
+# AC_LIBLTDL_CONVENIENCE accepted a directory argument in older libtools,
+# now we have LT_CONFIG_LTDL_DIR:
+AU_DEFUN([AC_LIBLTDL_CONVENIENCE],
+[_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])])
+_LTDL_CONVENIENCE])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBLTDL_CONVENIENCE], [])
+
+
+# _LTDL_CONVENIENCE
+# -----------------
+# Code shared by LTDL_CONVENIENCE and LTDL_INIT([convenience]).
+m4_defun([_LTDL_CONVENIENCE],
+[case $enable_ltdl_convenience in
+  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+  "") enable_ltdl_convenience=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+esac
+LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdlc.la"
+LTDLDEPS=$LIBLTDL
+LTDLINCL='-I${top_srcdir}'"${lt_ltdl_dir+/$lt_ltdl_dir}"
+
+AC_SUBST([LIBLTDL])
+AC_SUBST([LTDLDEPS])
+AC_SUBST([LTDLINCL])
+
+# For backwards non-gettext consistent compatibility...
+INCLTDL="$LTDLINCL"
+AC_SUBST([INCLTDL])
+])# _LTDL_CONVENIENCE
+
+
+# LTDL_INSTALLABLE
+# ----------------
+# sets LIBLTDL to the link flags for the libltdl installable library
+# and LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-install to the configure arguments.  Note that
+# AC_CONFIG_SUBDIRS is not called from here.  If an installed libltdl
+# is not found, LIBLTDL will be prefixed with '${top_build_prefix}' if
+# available, otherwise with '${top_builddir}/', and LTDLINCL will be
+# prefixed with '${top_srcdir}/' (note the single quotes!).  If your
+# package is not flat and you're not using automake, define top_build_prefix,
+# top_builddir, and top_srcdir appropriately in your Makefiles.
+# In the future, this macro may have to be called after LT_INIT.
+AC_DEFUN([LTDL_INSTALLABLE],
+[AC_BEFORE([$0], [LTDL_INIT])dnl
+dnl Although the argument is deprecated and no longer documented,
+dnl LTDL_INSTALLABLE used to take a DIRECTORY orgument, if we have one
+dnl here make sure it is the same as any other declaration of libltdl's
+dnl location!  This also ensures lt_ltdl_dir is set when configure.ac is
+dnl not yet using an explicit LT_CONFIG_LTDL_DIR.
+m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl
+_$0()
+])# LTDL_INSTALLABLE
+
+# AC_LIBLTDL_INSTALLABLE accepted a directory argument in older libtools,
+# now we have LT_CONFIG_LTDL_DIR:
+AU_DEFUN([AC_LIBLTDL_INSTALLABLE],
+[_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])])
+_LTDL_INSTALLABLE])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBLTDL_INSTALLABLE], [])
+
+
+# _LTDL_INSTALLABLE
+# -----------------
+# Code shared by LTDL_INSTALLABLE and LTDL_INIT([installable]).
+m4_defun([_LTDL_INSTALLABLE],
+[if test -f $prefix/lib/libltdl.la; then
+  lt_save_LDFLAGS="$LDFLAGS"
+  LDFLAGS="-L$prefix/lib $LDFLAGS"
+  AC_CHECK_LIB([ltdl], [lt_dlinit], [lt_lib_ltdl=yes])
+  LDFLAGS="$lt_save_LDFLAGS"
+  if test x"${lt_lib_ltdl-no}" = xyes; then
+    if test x"$enable_ltdl_install" != xyes; then
+      # Don't overwrite $prefix/lib/libltdl.la without --enable-ltdl-install
+      AC_MSG_WARN([not overwriting libltdl at $prefix, force with `--enable-ltdl-install'])
+      enable_ltdl_install=no
+    fi
+  elif test x"$enable_ltdl_install" = xno; then
+    AC_MSG_WARN([libltdl not installed, but installation disabled])
+  fi
+fi
+
+# If configure.ac declared an installable ltdl, and the user didn't override
+# with --disable-ltdl-install, we will install the shipped libltdl.
+case $enable_ltdl_install in
+  no) ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+      LIBLTDL="-lltdl"
+      LTDLDEPS=
+      LTDLINCL=
+      ;;
+  *)  enable_ltdl_install=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-install"
+      LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdl.la"
+      LTDLDEPS=$LIBLTDL
+      LTDLINCL='-I${top_srcdir}'"${lt_ltdl_dir+/$lt_ltdl_dir}"
+      ;;
+esac
+
+AC_SUBST([LIBLTDL])
+AC_SUBST([LTDLDEPS])
+AC_SUBST([LTDLINCL])
+
+# For backwards non-gettext consistent compatibility...
+INCLTDL="$LTDLINCL"
+AC_SUBST([INCLTDL])
+])# LTDL_INSTALLABLE
+
+
+# _LTDL_MODE_DISPATCH
+# -------------------
+m4_define([_LTDL_MODE_DISPATCH],
+[dnl If _LTDL_DIR is `.', then we are configuring libltdl itself:
+m4_if(_LTDL_DIR, [],
+	[],
+    dnl if _LTDL_MODE was not set already, the default value is `subproject':
+    [m4_case(m4_default(_LTDL_MODE, [subproject]),
+	  [subproject], [AC_CONFIG_SUBDIRS(_LTDL_DIR)
+			  _LT_SHELL_INIT([lt_dlopen_dir="$lt_ltdl_dir"])],
+	  [nonrecursive], [_LT_SHELL_INIT([lt_dlopen_dir="$lt_ltdl_dir"; lt_libobj_prefix="$lt_ltdl_dir/"])],
+	  [recursive], [],
+	[m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])])dnl
+dnl Be careful not to expand twice:
+m4_define([$0], [])
+])# _LTDL_MODE_DISPATCH
+
+
+# _LT_LIBOBJ(MODULE_NAME)
+# -----------------------
+# Like AC_LIBOBJ, except that MODULE_NAME goes into _LT_LIBOBJS instead
+# of into LIBOBJS.
+AC_DEFUN([_LT_LIBOBJ], [
+  m4_pattern_allow([^_LT_LIBOBJS$])
+  _LT_LIBOBJS="$_LT_LIBOBJS $1.$ac_objext"
+])# _LT_LIBOBJS
+
+
+# LTDL_INIT([OPTIONS])
+# --------------------
+# Clients of libltdl can use this macro to allow the installer to
+# choose between a shipped copy of the ltdl sources or a preinstalled
+# version of the library.  If the shipped ltdl sources are not in a
+# subdirectory named libltdl, the directory name must be given by
+# LT_CONFIG_LTDL_DIR.
+AC_DEFUN([LTDL_INIT],
+[dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+dnl We need to keep our own list of libobjs separate from our parent project,
+dnl and the easiest way to do that is redefine the AC_LIBOBJs macro while
+dnl we look for our own LIBOBJs.
+m4_pushdef([AC_LIBOBJ], m4_defn([_LT_LIBOBJ]))
+m4_pushdef([AC_LIBSOURCES])
+
+dnl If not otherwise defined, default to the 1.5.x compatible subproject mode:
+m4_if(_LTDL_MODE, [],
+        [m4_define([_LTDL_MODE], m4_default([$2], [subproject]))
+        m4_if([-1], [m4_bregexp(_LTDL_MODE, [\(subproject\|\(non\)?recursive\)])],
+                [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])])
+
+AC_ARG_WITH([included_ltdl],
+    [AS_HELP_STRING([--with-included-ltdl],
+                    [use the GNU ltdl sources included here])])
+
+if test "x$with_included_ltdl" != xyes; then
+  # We are not being forced to use the included libltdl sources, so
+  # decide whether there is a useful installed version we can use.
+  AC_CHECK_HEADER([ltdl.h],
+      [AC_CHECK_DECL([lt_dlinterface_register],
+	   [AC_CHECK_LIB([ltdl], [lt_dladvise_preload],
+	       [with_included_ltdl=no],
+	       [with_included_ltdl=yes])],
+	   [with_included_ltdl=yes],
+	   [AC_INCLUDES_DEFAULT
+	    #include <ltdl.h>])],
+      [with_included_ltdl=yes],
+      [AC_INCLUDES_DEFAULT]
+  )
+fi
+
+dnl If neither LT_CONFIG_LTDL_DIR, LTDL_CONVENIENCE nor LTDL_INSTALLABLE
+dnl was called yet, then for old times' sake, we assume libltdl is in an
+dnl eponymous directory:
+AC_PROVIDE_IFELSE([LT_CONFIG_LTDL_DIR], [], [_LT_CONFIG_LTDL_DIR([libltdl])])
+
+AC_ARG_WITH([ltdl_include],
+    [AS_HELP_STRING([--with-ltdl-include=DIR],
+                    [use the ltdl headers installed in DIR])])
+
+if test -n "$with_ltdl_include"; then
+  if test -f "$with_ltdl_include/ltdl.h"; then :
+  else
+    AC_MSG_ERROR([invalid ltdl include directory: `$with_ltdl_include'])
+  fi
+else
+  with_ltdl_include=no
+fi
+
+AC_ARG_WITH([ltdl_lib],
+    [AS_HELP_STRING([--with-ltdl-lib=DIR],
+                    [use the libltdl.la installed in DIR])])
+
+if test -n "$with_ltdl_lib"; then
+  if test -f "$with_ltdl_lib/libltdl.la"; then :
+  else
+    AC_MSG_ERROR([invalid ltdl library directory: `$with_ltdl_lib'])
+  fi
+else
+  with_ltdl_lib=no
+fi
+
+case ,$with_included_ltdl,$with_ltdl_include,$with_ltdl_lib, in
+  ,yes,no,no,)
+	m4_case(m4_default(_LTDL_TYPE, [convenience]),
+	    [convenience], [_LTDL_CONVENIENCE],
+	    [installable], [_LTDL_INSTALLABLE],
+	  [m4_fatal([unknown libltdl build type: ]_LTDL_TYPE)])
+	;;
+  ,no,no,no,)
+	# If the included ltdl is not to be used, then use the
+	# preinstalled libltdl we found.
+	AC_DEFINE([HAVE_LTDL], [1],
+	  [Define this if a modern libltdl is already installed])
+	LIBLTDL=-lltdl
+	LTDLDEPS=
+	LTDLINCL=
+	;;
+  ,no*,no,*)
+	AC_MSG_ERROR([`--with-ltdl-include' and `--with-ltdl-lib' options must be used together])
+	;;
+  *)	with_included_ltdl=no
+	LIBLTDL="-L$with_ltdl_lib -lltdl"
+	LTDLDEPS=
+	LTDLINCL="-I$with_ltdl_include"
+	;;
+esac
+INCLTDL="$LTDLINCL"
+
+# Report our decision...
+AC_MSG_CHECKING([where to find libltdl headers])
+AC_MSG_RESULT([$LTDLINCL])
+AC_MSG_CHECKING([where to find libltdl library])
+AC_MSG_RESULT([$LIBLTDL])
+
+_LTDL_SETUP
+
+dnl restore autoconf definition.
+m4_popdef([AC_LIBOBJ])
+m4_popdef([AC_LIBSOURCES])
+
+AC_CONFIG_COMMANDS_PRE([
+    _ltdl_libobjs=
+    _ltdl_ltlibobjs=
+    if test -n "$_LT_LIBOBJS"; then
+      # Remove the extension.
+      _lt_sed_drop_objext='s/\.o$//;s/\.obj$//'
+      for i in `for i in $_LT_LIBOBJS; do echo "$i"; done | sed "$_lt_sed_drop_objext" | sort -u`; do
+        _ltdl_libobjs="$_ltdl_libobjs $lt_libobj_prefix$i.$ac_objext"
+        _ltdl_ltlibobjs="$_ltdl_ltlibobjs $lt_libobj_prefix$i.lo"
+      done
+    fi
+    AC_SUBST([ltdl_LIBOBJS], [$_ltdl_libobjs])
+    AC_SUBST([ltdl_LTLIBOBJS], [$_ltdl_ltlibobjs])
+])
+
+# Only expand once:
+m4_define([LTDL_INIT])
+])# LTDL_INIT
+
+# Old names:
+AU_DEFUN([AC_LIB_LTDL], [LTDL_INIT($@)])
+AU_DEFUN([AC_WITH_LTDL], [LTDL_INIT($@)])
+AU_DEFUN([LT_WITH_LTDL], [LTDL_INIT($@)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIB_LTDL], [])
+dnl AC_DEFUN([AC_WITH_LTDL], [])
+dnl AC_DEFUN([LT_WITH_LTDL], [])
+
+
+# _LTDL_SETUP
+# -----------
+# Perform all the checks necessary for compilation of the ltdl objects
+#  -- including compiler checks and header checks.  This is a public
+# interface  mainly for the benefit of libltdl's own configure.ac, most
+# other users should call LTDL_INIT instead.
+AC_DEFUN([_LTDL_SETUP],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_SYS_MODULE_EXT])dnl
+AC_REQUIRE([LT_SYS_MODULE_PATH])dnl
+AC_REQUIRE([LT_SYS_DLSEARCH_PATH])dnl
+AC_REQUIRE([LT_LIB_DLLOAD])dnl
+AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl
+AC_REQUIRE([LT_FUNC_DLSYM_USCORE])dnl
+AC_REQUIRE([LT_SYS_DLOPEN_DEPLIBS])dnl
+AC_REQUIRE([gl_FUNC_ARGZ])dnl
+
+m4_require([_LT_CHECK_OBJDIR])dnl
+m4_require([_LT_HEADER_DLFCN])dnl
+m4_require([_LT_CHECK_DLPREOPEN])dnl
+m4_require([_LT_DECL_SED])dnl
+
+dnl Don't require this, or it will be expanded earlier than the code
+dnl that sets the variables it relies on:
+_LT_ENABLE_INSTALL
+
+dnl _LTDL_MODE specific code must be called at least once:
+_LTDL_MODE_DISPATCH
+
+# In order that ltdl.c can compile, find out the first AC_CONFIG_HEADERS
+# the user used.  This is so that ltdl.h can pick up the parent projects
+# config.h file, The first file in AC_CONFIG_HEADERS must contain the
+# definitions required by ltdl.c.
+# FIXME: Remove use of undocumented AC_LIST_HEADERS (2.59 compatibility).
+AC_CONFIG_COMMANDS_PRE([dnl
+m4_pattern_allow([^LT_CONFIG_H$])dnl
+m4_ifset([AH_HEADER],
+    [LT_CONFIG_H=AH_HEADER],
+    [m4_ifset([AC_LIST_HEADERS],
+	    [LT_CONFIG_H=`echo "AC_LIST_HEADERS" | $SED 's,^[[      ]]*,,;s,[[ :]].*$,,'`],
+	[])])])
+AC_SUBST([LT_CONFIG_H])
+
+AC_CHECK_HEADERS([unistd.h dl.h sys/dl.h dld.h mach-o/dyld.h dirent.h],
+	[], [], [AC_INCLUDES_DEFAULT])
+
+AC_CHECK_FUNCS([closedir opendir readdir], [], [AC_LIBOBJ([lt__dirent])])
+AC_CHECK_FUNCS([strlcat strlcpy], [], [AC_LIBOBJ([lt__strl])])
+
+m4_pattern_allow([LT_LIBEXT])dnl
+AC_DEFINE_UNQUOTED([LT_LIBEXT],["$libext"],[The archive extension])
+
+name=
+eval "lt_libprefix=\"$libname_spec\""
+m4_pattern_allow([LT_LIBPREFIX])dnl
+AC_DEFINE_UNQUOTED([LT_LIBPREFIX],["$lt_libprefix"],[The archive prefix])
+
+name=ltdl
+eval "LTDLOPEN=\"$libname_spec\""
+AC_SUBST([LTDLOPEN])
+])# _LTDL_SETUP
+
+
+# _LT_ENABLE_INSTALL
+# ------------------
+m4_define([_LT_ENABLE_INSTALL],
+[AC_ARG_ENABLE([ltdl-install],
+    [AS_HELP_STRING([--enable-ltdl-install], [install libltdl])])
+
+case ,${enable_ltdl_install},${enable_ltdl_convenience} in
+  *yes*) ;;
+  *) enable_ltdl_convenience=yes ;;
+esac
+
+m4_ifdef([AM_CONDITIONAL],
+[AM_CONDITIONAL(INSTALL_LTDL, test x"${enable_ltdl_install-no}" != xno)
+ AM_CONDITIONAL(CONVENIENCE_LTDL, test x"${enable_ltdl_convenience-no}" != xno)])
+])# _LT_ENABLE_INSTALL
+
+
+# LT_SYS_DLOPEN_DEPLIBS
+# ---------------------
+AC_DEFUN([LT_SYS_DLOPEN_DEPLIBS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_CACHE_CHECK([whether deplibs are loaded by dlopen],
+  [lt_cv_sys_dlopen_deplibs],
+  [# PORTME does your system automatically load deplibs for dlopen?
+  # or its logical equivalent (e.g. shl_load for HP-UX < 11)
+  # For now, we just catch OSes we know something about -- in the
+  # future, we'll try test this programmatically.
+  lt_cv_sys_dlopen_deplibs=unknown
+  case $host_os in
+  aix3*|aix4.1.*|aix4.2.*)
+    # Unknown whether this is true for these versions of AIX, but
+    # we want this `case' here to explicitly catch those versions.
+    lt_cv_sys_dlopen_deplibs=unknown
+    ;;
+  aix[[4-9]]*)
+    lt_cv_sys_dlopen_deplibs=yes
+    ;;
+  amigaos*)
+    case $host_cpu in
+    powerpc)
+      lt_cv_sys_dlopen_deplibs=no
+      ;;
+    esac
+    ;;
+  darwin*)
+    # Assuming the user has installed a libdl from somewhere, this is true
+    # If you are looking for one http://www.opendarwin.org/projects/dlcompat
+    lt_cv_sys_dlopen_deplibs=yes
+    ;;
+  freebsd* | dragonfly*)
+    lt_cv_sys_dlopen_deplibs=yes
+    ;;
+  gnu* | linux* | k*bsd*-gnu | kopensolaris*-gnu)
+    # GNU and its variants, using gnu ld.so (Glibc)
+    lt_cv_sys_dlopen_deplibs=yes
+    ;;
+  hpux10*|hpux11*)
+    lt_cv_sys_dlopen_deplibs=yes
+    ;;
+  interix*)
+    lt_cv_sys_dlopen_deplibs=yes
+    ;;
+  irix[[12345]]*|irix6.[[01]]*)
+    # Catch all versions of IRIX before 6.2, and indicate that we don't
+    # know how it worked for any of those versions.
+    lt_cv_sys_dlopen_deplibs=unknown
+    ;;
+  irix*)
+    # The case above catches anything before 6.2, and it's known that
+    # at 6.2 and later dlopen does load deplibs.
+    lt_cv_sys_dlopen_deplibs=yes
+    ;;
+  netbsd*)
+    lt_cv_sys_dlopen_deplibs=yes
+    ;;
+  openbsd*)
+    lt_cv_sys_dlopen_deplibs=yes
+    ;;
+  osf[[1234]]*)
+    # dlopen did load deplibs (at least at 4.x), but until the 5.x series,
+    # it did *not* use an RPATH in a shared library to find objects the
+    # library depends on, so we explicitly say `no'.
+    lt_cv_sys_dlopen_deplibs=no
+    ;;
+  osf5.0|osf5.0a|osf5.1)
+    # dlopen *does* load deplibs and with the right loader patch applied
+    # it even uses RPATH in a shared library to search for shared objects
+    # that the library depends on, but there's no easy way to know if that
+    # patch is installed.  Since this is the case, all we can really
+    # say is unknown -- it depends on the patch being installed.  If
+    # it is, this changes to `yes'.  Without it, it would be `no'.
+    lt_cv_sys_dlopen_deplibs=unknown
+    ;;
+  osf*)
+    # the two cases above should catch all versions of osf <= 5.1.  Read
+    # the comments above for what we know about them.
+    # At > 5.1, deplibs are loaded *and* any RPATH in a shared library
+    # is used to find them so we can finally say `yes'.
+    lt_cv_sys_dlopen_deplibs=yes
+    ;;
+  qnx*)
+    lt_cv_sys_dlopen_deplibs=yes
+    ;;
+  solaris*)
+    lt_cv_sys_dlopen_deplibs=yes
+    ;;
+  sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+    libltdl_cv_sys_dlopen_deplibs=yes
+    ;;
+  esac
+  ])
+if test "$lt_cv_sys_dlopen_deplibs" != yes; then
+ AC_DEFINE([LTDL_DLOPEN_DEPLIBS], [1],
+    [Define if the OS needs help to load dependent libraries for dlopen().])
+fi
+])# LT_SYS_DLOPEN_DEPLIBS
+
+# Old name:
+AU_ALIAS([AC_LTDL_SYS_DLOPEN_DEPLIBS], [LT_SYS_DLOPEN_DEPLIBS])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], [])
+
+
+# LT_SYS_MODULE_EXT
+# -----------------
+AC_DEFUN([LT_SYS_MODULE_EXT],
+[m4_require([_LT_SYS_DYNAMIC_LINKER])dnl
+AC_CACHE_CHECK([which extension is used for runtime loadable modules],
+  [libltdl_cv_shlibext],
+[
+module=yes
+eval libltdl_cv_shlibext=$shrext_cmds
+  ])
+if test -n "$libltdl_cv_shlibext"; then
+  m4_pattern_allow([LT_MODULE_EXT])dnl
+  AC_DEFINE_UNQUOTED([LT_MODULE_EXT], ["$libltdl_cv_shlibext"],
+    [Define to the extension used for runtime loadable modules, say, ".so".])
+fi
+])# LT_SYS_MODULE_EXT
+
+# Old name:
+AU_ALIAS([AC_LTDL_SHLIBEXT], [LT_SYS_MODULE_EXT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LTDL_SHLIBEXT], [])
+
+
+# LT_SYS_MODULE_PATH
+# ------------------
+AC_DEFUN([LT_SYS_MODULE_PATH],
+[m4_require([_LT_SYS_DYNAMIC_LINKER])dnl
+AC_CACHE_CHECK([which variable specifies run-time module search path],
+  [lt_cv_module_path_var], [lt_cv_module_path_var="$shlibpath_var"])
+if test -n "$lt_cv_module_path_var"; then
+  m4_pattern_allow([LT_MODULE_PATH_VAR])dnl
+  AC_DEFINE_UNQUOTED([LT_MODULE_PATH_VAR], ["$lt_cv_module_path_var"],
+    [Define to the name of the environment variable that determines the run-time module search path.])
+fi
+])# LT_SYS_MODULE_PATH
+
+# Old name:
+AU_ALIAS([AC_LTDL_SHLIBPATH], [LT_SYS_MODULE_PATH])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LTDL_SHLIBPATH], [])
+
+
+# LT_SYS_DLSEARCH_PATH
+# --------------------
+AC_DEFUN([LT_SYS_DLSEARCH_PATH],
+[m4_require([_LT_SYS_DYNAMIC_LINKER])dnl
+AC_CACHE_CHECK([for the default library search path],
+  [lt_cv_sys_dlsearch_path],
+  [lt_cv_sys_dlsearch_path="$sys_lib_dlsearch_path_spec"])
+if test -n "$lt_cv_sys_dlsearch_path"; then
+  sys_dlsearch_path=
+  for dir in $lt_cv_sys_dlsearch_path; do
+    if test -z "$sys_dlsearch_path"; then
+      sys_dlsearch_path="$dir"
+    else
+      sys_dlsearch_path="$sys_dlsearch_path$PATH_SEPARATOR$dir"
+    fi
+  done
+  m4_pattern_allow([LT_DLSEARCH_PATH])dnl
+  AC_DEFINE_UNQUOTED([LT_DLSEARCH_PATH], ["$sys_dlsearch_path"],
+    [Define to the system default library search path.])
+fi
+])# LT_SYS_DLSEARCH_PATH
+
+# Old name:
+AU_ALIAS([AC_LTDL_SYSSEARCHPATH], [LT_SYS_DLSEARCH_PATH])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LTDL_SYSSEARCHPATH], [])
+
+
+# _LT_CHECK_DLPREOPEN
+# -------------------
+m4_defun([_LT_CHECK_DLPREOPEN],
+[m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen],
+  [libltdl_cv_preloaded_symbols],
+  [if test -n "$lt_cv_sys_global_symbol_pipe"; then
+    libltdl_cv_preloaded_symbols=yes
+  else
+    libltdl_cv_preloaded_symbols=no
+  fi
+  ])
+if test x"$libltdl_cv_preloaded_symbols" = xyes; then
+  AC_DEFINE([HAVE_PRELOADED_SYMBOLS], [1],
+    [Define if libtool can extract symbol lists from object files.])
+fi
+])# _LT_CHECK_DLPREOPEN
+
+
+# LT_LIB_DLLOAD
+# -------------
+AC_DEFUN([LT_LIB_DLLOAD],
+[m4_pattern_allow([^LT_DLLOADERS$])
+LT_DLLOADERS=
+AC_SUBST([LT_DLLOADERS])
+
+AC_LANG_PUSH([C])
+
+LIBADD_DLOPEN=
+AC_SEARCH_LIBS([dlopen], [dl],
+	[AC_DEFINE([HAVE_LIBDL], [1],
+		   [Define if you have the libdl library or equivalent.])
+	if test "$ac_cv_search_dlopen" != "none required" ; then
+	  LIBADD_DLOPEN="-ldl"
+	fi
+	libltdl_cv_lib_dl_dlopen="yes"
+	LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"],
+    [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#if HAVE_DLFCN_H
+#  include <dlfcn.h>
+#endif
+    ]], [[dlopen(0, 0);]])],
+	    [AC_DEFINE([HAVE_LIBDL], [1],
+		       [Define if you have the libdl library or equivalent.])
+	    libltdl_cv_func_dlopen="yes"
+	    LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"],
+	[AC_CHECK_LIB([svld], [dlopen],
+		[AC_DEFINE([HAVE_LIBDL], [1],
+			 [Define if you have the libdl library or equivalent.])
+	        LIBADD_DLOPEN="-lsvld" libltdl_cv_func_dlopen="yes"
+		LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"])])])
+if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes
+then
+  lt_save_LIBS="$LIBS"
+  LIBS="$LIBS $LIBADD_DLOPEN"
+  AC_CHECK_FUNCS([dlerror])
+  LIBS="$lt_save_LIBS"
+fi
+AC_SUBST([LIBADD_DLOPEN])
+
+LIBADD_SHL_LOAD=
+AC_CHECK_FUNC([shl_load],
+	[AC_DEFINE([HAVE_SHL_LOAD], [1],
+		   [Define if you have the shl_load function.])
+	LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la"],
+    [AC_CHECK_LIB([dld], [shl_load],
+	    [AC_DEFINE([HAVE_SHL_LOAD], [1],
+		       [Define if you have the shl_load function.])
+	    LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la"
+	    LIBADD_SHL_LOAD="-ldld"])])
+AC_SUBST([LIBADD_SHL_LOAD])
+
+case $host_os in
+darwin[[1567]].*)
+# We only want this for pre-Mac OS X 10.4.
+  AC_CHECK_FUNC([_dyld_func_lookup],
+	[AC_DEFINE([HAVE_DYLD], [1],
+		   [Define if you have the _dyld_func_lookup function.])
+	LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dyld.la"])
+  ;;
+beos*)
+  LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}load_add_on.la"
+  ;;
+cygwin* | mingw* | os2* | pw32*)
+  AC_CHECK_DECLS([cygwin_conv_path], [], [], [[#include <sys/cygwin.h>]])
+  LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}loadlibrary.la"
+  ;;
+esac
+
+AC_CHECK_LIB([dld], [dld_link],
+	[AC_DEFINE([HAVE_DLD], [1],
+		   [Define if you have the GNU dld library.])
+		LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dld_link.la"])
+AC_SUBST([LIBADD_DLD_LINK])
+
+m4_pattern_allow([^LT_DLPREOPEN$])
+LT_DLPREOPEN=
+if test -n "$LT_DLLOADERS"
+then
+  for lt_loader in $LT_DLLOADERS; do
+    LT_DLPREOPEN="$LT_DLPREOPEN-dlpreopen $lt_loader "
+  done
+  AC_DEFINE([HAVE_LIBDLLOADER], [1],
+            [Define if libdlloader will be built on this platform])
+fi
+AC_SUBST([LT_DLPREOPEN])
+
+dnl This isn't used anymore, but set it for backwards compatibility
+LIBADD_DL="$LIBADD_DLOPEN $LIBADD_SHL_LOAD"
+AC_SUBST([LIBADD_DL])
+
+AC_LANG_POP
+])# LT_LIB_DLLOAD
+
+# Old name:
+AU_ALIAS([AC_LTDL_DLLIB], [LT_LIB_DLLOAD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LTDL_DLLIB], [])
+
+
+# LT_SYS_SYMBOL_USCORE
+# --------------------
+# does the compiler prefix global symbols with an underscore?
+AC_DEFUN([LT_SYS_SYMBOL_USCORE],
+[m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+AC_CACHE_CHECK([for _ prefix in compiled symbols],
+  [lt_cv_sys_symbol_underscore],
+  [lt_cv_sys_symbol_underscore=no
+  cat > conftest.$ac_ext <<_LT_EOF
+void nm_test_func(){}
+int main(){nm_test_func;return 0;}
+_LT_EOF
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    ac_nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+      # See whether the symbols have a leading underscore.
+      if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
+        lt_cv_sys_symbol_underscore=yes
+      else
+        if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
+	  :
+        else
+	  echo "configure: cannot find nm_test_func in $ac_nlist" >&AS_MESSAGE_LOG_FD
+        fi
+      fi
+    else
+      echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.c >&AS_MESSAGE_LOG_FD
+  fi
+  rm -rf conftest*
+  ])
+  sys_symbol_underscore=$lt_cv_sys_symbol_underscore
+  AC_SUBST([sys_symbol_underscore])
+])# LT_SYS_SYMBOL_USCORE
+
+# Old name:
+AU_ALIAS([AC_LTDL_SYMBOL_USCORE], [LT_SYS_SYMBOL_USCORE])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LTDL_SYMBOL_USCORE], [])
+
+
+# LT_FUNC_DLSYM_USCORE
+# --------------------
+AC_DEFUN([LT_FUNC_DLSYM_USCORE],
+[AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl
+if test x"$lt_cv_sys_symbol_underscore" = xyes; then
+  if test x"$libltdl_cv_func_dlopen" = xyes ||
+     test x"$libltdl_cv_lib_dl_dlopen" = xyes ; then
+	AC_CACHE_CHECK([whether we have to add an underscore for dlsym],
+	  [libltdl_cv_need_uscore],
+	  [libltdl_cv_need_uscore=unknown
+          save_LIBS="$LIBS"
+          LIBS="$LIBS $LIBADD_DLOPEN"
+	  _LT_TRY_DLOPEN_SELF(
+	    [libltdl_cv_need_uscore=no], [libltdl_cv_need_uscore=yes],
+	    [],				 [libltdl_cv_need_uscore=cross])
+	  LIBS="$save_LIBS"
+	])
+  fi
+fi
+
+if test x"$libltdl_cv_need_uscore" = xyes; then
+  AC_DEFINE([NEED_USCORE], [1],
+    [Define if dlsym() requires a leading underscore in symbol names.])
+fi
+])# LT_FUNC_DLSYM_USCORE
+
+# Old name:
+AU_ALIAS([AC_LTDL_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LTDL_DLSYM_USCORE], [])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version.  Point them to the right macro.
+m4_if([$1], [1.11.1], [],
+      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too.  Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# Figure out how to run the assembler.                      -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_PROG_AS
+# ----------
+AC_DEFUN([AM_PROG_AS],
+[# By default we simply use the C compiler to build assembly code.
+AC_REQUIRE([AC_PROG_CC])
+test "${CCAS+set}" = set || CCAS=$CC
+test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS
+AC_ARG_VAR([CCAS],      [assembler compiler command (defaults to CC)])
+AC_ARG_VAR([CCASFLAGS], [assembler compiler flags (defaults to CFLAGS)])
+_AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl
+])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL                                            -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+	[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 10
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
+       [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
+       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+       [$1], UPC,  [depcc="$UPC"  am_compiler_list=],
+       [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                   [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  am__universal=false
+  m4_case([$1], [CC],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac],
+    [CXX],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac])
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 5
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named `Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`AS_DIRNAME("$mf")`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running `make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # When using ansi2knr, U may be empty or an underscore; expand it
+    U=`sed -n 's/^U = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`AS_DIRNAME(["$file"])`
+      AS_MKDIR_P([$dirpart/$fdir])
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 16
+
+# This macro actually does too much.  Some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+	      [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+			     [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+		  [_AM_DEPENDENCIES(CC)],
+		  [define([AC_PROG_CC],
+			  defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES(CXX)],
+		  [define([AC_PROG_CXX],
+			  defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES(OBJC)],
+		  [define([AC_PROG_OBJC],
+			  defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+  [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless `enable' is passed literally.
+# For symmetry, `disable' may be passed as well.  Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+       [enable], [m4_define([am_maintainer_other], [disable])],
+       [disable], [m4_define([am_maintainer_other], [enable])],
+       [m4_define([am_maintainer_other], [enable])
+        m4_warn([syntax], [unexpected argument to AM@&t at _MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
+  dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+  AC_ARG_ENABLE([maintainer-mode],
+[  --][am_maintainer_other][-maintainer-mode  am_maintainer_other make rules and dependencies not useful
+			  (and sometimes confusing) to the casual installer],
+      [USE_MAINTAINER_MODE=$enableval],
+      [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+  AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+  AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+  MAINT=$MAINTAINER_MODE_TRUE
+  AC_SUBST([MAINT])dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2009  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_PROG_CC_C_O
+# --------------
+# Like AC_PROG_CC_C_O, but changed for automake.
+AC_DEFUN([AM_PROG_CC_C_O],
+[AC_REQUIRE([AC_PROG_CC_C_O])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+dnl Make sure AC_PROG_CC is never called again, or it will override our
+dnl setting of CC.
+m4_define([AC_PROG_CC],
+          [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p.  We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+  [[\\/$]]* | ?:[[\\/]]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[[\\\"\#\$\&\'\`$am_lf]]*)
+    AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+  *[[\\\"\#\$\&\'\`$am_lf\ \	]]*)
+    AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+   if test "$[*]" = "X"; then
+      # -L didn't work.
+      set X `ls -t "$srcdir/configure" conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$[*]" != "X $srcdir/configure conftest.file" \
+      && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball.                            -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+     [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+     [m4_case([$1], [ustar],, [pax],,
+              [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+  case $_am_tool in
+  gnutar)
+    for _am_tar in tar gnutar gtar;
+    do
+      AM_RUN_LOG([$_am_tar --version]) && break
+    done
+    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+    am__untar="$_am_tar -xf -"
+    ;;
+  plaintar)
+    # Must skip GNU tar: if it does not support --format= it doesn't create
+    # ustar tarball either.
+    (tar --version) >/dev/null 2>&1 && continue
+    am__tar='tar chf - "$$tardir"'
+    am__tar_='tar chf - "$tardir"'
+    am__untar='tar xf -'
+    ;;
+  pax)
+    am__tar='pax -L -x $1 -w "$$tardir"'
+    am__tar_='pax -L -x $1 -w "$tardir"'
+    am__untar='pax -r'
+    ;;
+  cpio)
+    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+    am__untar='cpio -i -H $1 -d'
+    ;;
+  none)
+    am__tar=false
+    am__tar_=false
+    am__untar=false
+    ;;
+  esac
+
+  # If the value was cached, stop now.  We just wanted to have am__tar
+  # and am__untar set.
+  test -n "${am_cv_prog_tar_$1}" && break
+
+  # tar/untar a dummy directory, and stop if the command works
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  echo GrepMe > conftest.dir/file
+  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+  rm -rf conftest.dir
+  if test -s conftest.tar; then
+    AM_RUN_LOG([$am__untar <conftest.tar])
+    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+  fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([m4/ax_cc_maxopt.m4])
+m4_include([m4/ax_cflags_warn_all.m4])
+m4_include([m4/ax_check_compiler_flags.m4])
+m4_include([m4/ax_compiler_vendor.m4])
+m4_include([m4/ax_configure_args.m4])
+m4_include([m4/ax_enable_builddir.m4])
+m4_include([m4/ax_gcc_archflag.m4])
+m4_include([m4/ax_gcc_x86_cpuid.m4])
+m4_include([m4/libtool.m4])
+m4_include([m4/ltoptions.m4])
+m4_include([m4/ltsugar.m4])
+m4_include([m4/ltversion.m4])
+m4_include([m4/lt~obsolete.m4])
+m4_include([acinclude.m4])
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/build-ios.sh b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/build-ios.sh
new file mode 100755
index 0000000..3dea242
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/build-ios.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+PLATFORM_IOS=/Developer/Platforms/iPhoneOS.platform/
+PLATFORM_IOS_SIM=/Developer/Platforms/iPhoneSimulator.platform/
+SDK_IOS_VERSION="4.2"
+MIN_IOS_VERSION="3.0"
+OUTPUT_DIR="universal-ios"
+
+build_target () {
+    local platform=$1
+    local sdk=$2
+    local arch=$3
+    local triple=$4
+    local builddir=$5
+
+    mkdir -p "${builddir}"
+    pushd "${builddir}"
+    export CC="${platform}"/Developer/usr/bin/gcc-4.2
+    export CFLAGS="-arch ${arch} -isysroot ${sdk} -miphoneos-version-min=${MIN_IOS_VERSION}"
+    ../configure --host=${triple} && make
+    popd
+}
+
+# Build all targets
+build_target "${PLATFORM_IOS}" "${PLATFORM_IOS}/Developer/SDKs/iPhoneOS${SDK_IOS_VERSION}.sdk/" armv6 arm-apple-darwin10 armv6-ios
+build_target "${PLATFORM_IOS}" "${PLATFORM_IOS}/Developer/SDKs/iPhoneOS${SDK_IOS_VERSION}.sdk/" armv7 arm-apple-darwin10 armv7-ios
+build_target "${PLATFORM_IOS_SIM}" "${PLATFORM_IOS_SIM}/Developer/SDKs/iPhoneSimulator${SDK_IOS_VERSION}.sdk/" i386 i386-apple-darwin10 i386-ios-sim
+
+# Create universal output directories
+mkdir -p "${OUTPUT_DIR}"
+mkdir -p "${OUTPUT_DIR}/include"
+mkdir -p "${OUTPUT_DIR}/include/armv6"
+mkdir -p "${OUTPUT_DIR}/include/armv7"
+mkdir -p "${OUTPUT_DIR}/include/i386"
+
+# Create the universal binary
+lipo -create armv6-ios/.libs/libffi.a armv7-ios/.libs/libffi.a i386-ios-sim/.libs/libffi.a -output "${OUTPUT_DIR}/libffi.a"
+
+# Copy in the headers
+copy_headers () {
+    local src=$1
+    local dest=$2
+
+    # Fix non-relative header reference
+    sed 's/<ffitarget.h>/"ffitarget.h"/' < "${src}/include/ffi.h" > "${dest}/ffi.h"
+    cp "${src}/include/ffitarget.h" "${dest}"
+}
+
+copy_headers armv6-ios "${OUTPUT_DIR}/include/armv6"
+copy_headers armv7-ios "${OUTPUT_DIR}/include/armv7"
+copy_headers i386-ios-sim "${OUTPUT_DIR}/include/i386"
+
+# Create top-level header
+(
+cat << EOF
+#ifdef __arm__
+  #include <arm/arch.h>
+  #ifdef _ARM_ARCH_6
+    #include "include/armv6/ffi.h"
+  #elif _ARM_ARCH_7
+    #include "include/armv7/ffi.h"
+  #endif
+#elif defined(__i386__)
+  #include "include/i386/ffi.h"
+#endif
+EOF
+) > "${OUTPUT_DIR}/ffi.h"
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/compile b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/compile
new file mode 100755
index 0000000..c0096a7
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/compile
@@ -0,0 +1,143 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand `-c -o'.
+
+scriptversion=2009-10-06.20; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009  Free Software
+# Foundation, Inc.
+# Written by Tom Tromey <tromey at cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake at gnu.org> or send patches to
+# <automake-patches at gnu.org>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand `-c -o'.
+Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file `INSTALL'.
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+esac
+
+ofile=
+cfile=
+eat=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+	# configure might choose to run compile as `compile cc -o foo foo.c'.
+	# So we strip `-o arg' only if arg is an object.
+	eat=1
+	case $2 in
+	  *.o | *.obj)
+	    ofile=$2
+	    ;;
+	  *)
+	    set x "$@" -o "$2"
+	    shift
+	    ;;
+	esac
+	;;
+      *.c)
+	cfile=$1
+	set x "$@" "$1"
+	shift
+	;;
+      *)
+	set x "$@" "$1"
+	shift
+	;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no `-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # `.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use `[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/config.guess b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/config.guess
new file mode 100755
index 0000000..dc84c68
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/config.guess
@@ -0,0 +1,1501 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   Free Software Foundation, Inc.
+
+timestamp='2009-11-20'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner.  Please send patches (context
+# diff format) to <config-patches at gnu.org> and include a ChangeLog
+# entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi at noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep -q __ELF__
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[456])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep -q __LP64__
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	case ${UNAME_MACHINE} in
+	    pc98)
+		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:*)
+    	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep -q ld.so.1
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-gnu
+	else
+	    echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	LIBC=gnu
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+	echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=${UNAME_MACHINE}el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=${UNAME_MACHINE}
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-gnu
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit ;;
+    xtensa*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel at ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes at openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf at swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    i386)
+		eval $set_cc_for_build
+		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		      grep IS_64BIT_ARCH >/dev/null
+		  then
+		      UNAME_PROCESSOR="x86_64"
+		  fi
+		fi ;;
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches at gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/config.sub b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/config.sub
new file mode 100755
index 0000000..2a55a50
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/config.sub
@@ -0,0 +1,1705 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   Free Software Foundation, Inc.
+
+timestamp='2009-11-20'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray | -microblaze)
+		os=
+		basic_machine=$1
+		;;
+        -bluegene*)
+	        os=-cnk
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu | strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| ubicom32 \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
+	| tron-* \
+	| ubicom32-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+        cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+        microblaze)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tile*)
+		basic_machine=tile-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+        -auroraux)
+	        os=-auroraux
+		;;
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+        score-*)
+		os=-elf
+		;;
+        spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        c4x-* | tic4x-*)
+        	os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+        mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-cnk*|-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/configure b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/configure
new file mode 100755
index 0000000..231c83a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/configure
@@ -0,0 +1,17191 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.68 for libffi 3.0.10.
+#
+# Report bugs to <http://sourceware.org/libffi.html>.
+#
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+
+  test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  # We cannot yet assume a decent shell, so we have to provide a
+	# neutralization value for shells without unset; and this also
+	# works around shells that cannot unset nonexistent variables.
+	# Preserve -v and -x to the replacement shell.
+	BASH_ENV=/dev/null
+	ENV=/dev/null
+	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+	export CONFIG_SHELL
+	case $- in # ((((
+	  *v*x* | *x*v* ) as_opts=-vx ;;
+	  *v* ) as_opts=-v ;;
+	  *x* ) as_opts=-x ;;
+	  * ) as_opts= ;;
+	esac
+	exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org and
+$0: http://sourceware.org/libffi.html about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='libffi'
+PACKAGE_TARNAME='libffi'
+PACKAGE_VERSION='3.0.10'
+PACKAGE_STRING='libffi 3.0.10'
+PACKAGE_BUGREPORT='http://sourceware.org/libffi.html'
+PACKAGE_URL=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+toolexeclibdir
+toolexecdir
+FFI_DEBUG_FALSE
+FFI_DEBUG_TRUE
+TARGETDIR
+TARGET
+FFI_EXEC_TRAMPOLINE_TABLE
+FFI_EXEC_TRAMPOLINE_TABLE_FALSE
+FFI_EXEC_TRAMPOLINE_TABLE_TRUE
+sys_symbol_underscore
+HAVE_LONG_DOUBLE
+ALLOCA
+PA64_HPUX_FALSE
+PA64_HPUX_TRUE
+PA_HPUX_FALSE
+PA_HPUX_TRUE
+PA_LINUX_FALSE
+PA_LINUX_TRUE
+SH64_FALSE
+SH64_TRUE
+SH_FALSE
+SH_TRUE
+X86_64_FALSE
+X86_64_TRUE
+S390_FALSE
+S390_TRUE
+FRV_FALSE
+FRV_TRUE
+LIBFFI_CRIS_FALSE
+LIBFFI_CRIS_TRUE
+AVR32_FALSE
+AVR32_TRUE
+ARM_FALSE
+ARM_TRUE
+POWERPC_FREEBSD_FALSE
+POWERPC_FREEBSD_TRUE
+POWERPC_DARWIN_FALSE
+POWERPC_DARWIN_TRUE
+POWERPC_AIX_FALSE
+POWERPC_AIX_TRUE
+POWERPC_FALSE
+POWERPC_TRUE
+MOXIE_FALSE
+MOXIE_TRUE
+M68K_FALSE
+M68K_TRUE
+M32R_FALSE
+M32R_TRUE
+IA64_FALSE
+IA64_TRUE
+ALPHA_FALSE
+ALPHA_TRUE
+X86_DARWIN_FALSE
+X86_DARWIN_TRUE
+X86_WIN64_FALSE
+X86_WIN64_TRUE
+X86_WIN32_FALSE
+X86_WIN32_TRUE
+X86_FREEBSD_FALSE
+X86_FREEBSD_TRUE
+X86_FALSE
+X86_TRUE
+SPARC_FALSE
+SPARC_TRUE
+MIPS_FALSE
+MIPS_TRUE
+AM_LTLDFLAGS
+AM_RUNTESTFLAGS
+TESTSUBDIR_FALSE
+TESTSUBDIR_TRUE
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+PRTDIAG
+CPP
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+ac_ct_AR
+AR
+DLLTOOL
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+LIBTOOL
+am__fastdepCCAS_FALSE
+am__fastdepCCAS_TRUE
+CCASDEPMODE
+CCASFLAGS
+CCAS
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+ax_enable_builddir_sed
+target_os
+target_vendor
+target_cpu
+target
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_builddir
+enable_dependency_tracking
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+enable_portable_binary
+with_gcc_arch
+enable_maintainer_mode
+enable_debug
+enable_structs
+enable_raw_api
+enable_purify_safety
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CCAS
+CCASFLAGS
+CPP
+CPPFLAGS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used" >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures libffi 3.0.10 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/libffi]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of libffi 3.0.10:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --disable-builddir      disable automatic build in subdir of sources
+
+  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors
+  --enable-shared[=PKGS]  build shared libraries [default=yes]
+  --enable-static[=PKGS]  build static libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+  --enable-portable-binary
+                          disable compiler optimizations that would produce
+                          unportable binaries
+  --enable-maintainer-mode  enable make rules and dependencies not useful
+			  (and sometimes confusing) to the casual installer
+  --enable-debug          debugging mode
+  --disable-structs       omit code for struct support
+  --disable-raw-api       make the raw api unavailable
+  --enable-purify-safety  purify-safe mode
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-pic              try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-sysroot=DIR Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).
+  --with-gcc-arch=<arch>  use architecture <arch> for gcc -march/-mtune,
+                          instead of guessing
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CCAS        assembler compiler command (defaults to CC)
+  CCASFLAGS   assembler compiler flags (defaults to CFLAGS)
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <http://sourceware.org/libffi.html>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+libffi configure 3.0.10
+generated by GNU Autoconf 2.68
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ------------------------------------------------ ##
+## Report this to http://sourceware.org/libffi.html ##
+## ------------------------------------------------ ##"
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+	 return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+	    return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if test "$cross_compiling" = yes; then
+    # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid; break
+else
+  as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+			if test $ac_lo -le $ac_mid; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=$ac_mid; break
+else
+  as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+			if test $ac_mid -le $ac_hi; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid
+else
+  as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+  else
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    return 1;
+  if (($2) < 0)
+    {
+      long int i = longval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%ld", i);
+    }
+  else
+    {
+      unsigned long int i = ulongval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%lu", i);
+    }
+  /* Do not output a trailing newline, as this causes \r\n confusion
+     on some platforms.  */
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+  ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+  fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by libffi $as_me 3.0.10, which was
+generated by GNU Autoconf 2.68.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_config_headers="$ac_config_headers fficonfig.h"
+
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
+$as_echo_n "checking target system type... " >&6; }
+if ${ac_cv_target+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$target_alias" = x; then
+  ac_cv_target=$ac_cv_host
+else
+  ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
+$as_echo "$ac_cv_target" >&6; }
+case $ac_cv_target in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
+esac
+target=$ac_cv_target
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_target
+shift
+target_cpu=$1
+target_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+target_os=$*
+IFS=$ac_save_IFS
+case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+target_alias=${target_alias-$host_alias}
+
+. ${srcdir}/configure.host
+
+
+   # [$]@ is unsable in 2.60+ but earlier autoconf had no ac_configure_args
+   if test "${ac_configure_args+set}" != "set" ; then
+      ac_configure_args=
+      for ac_arg in ${1+"$@"}; do
+         ac_configure_args="$ac_configure_args '$ac_arg'"
+      done
+   fi
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+
+ax_enable_builddir="."
+# Check whether --enable-builddir was given.
+if test "${enable_builddir+set}" = set; then :
+  enableval=$enable_builddir; ax_enable_builddir="$enableval"
+else
+  ax_enable_builddir="auto"
+fi
+
+if test ".$ac_srcdir_defaulted" != ".no" ; then
+if test ".$srcdir" = ".." ; then
+  if test -f config.status ; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: toplevel srcdir already configured... skipping subdir build" >&5
+$as_echo "$as_me: toplevel srcdir already configured... skipping subdir build" >&6;}
+  else
+    test ".$ax_enable_builddir" = "."  && ax_enable_builddir="."
+    test ".$ax_enable_builddir" = ".no"  && ax_enable_builddir="."
+    test ".$TARGET" = "." && TARGET="$target"
+    test ".$ax_enable_builddir" = ".auto" && ax_enable_builddir="$TARGET"
+    if test ".$ax_enable_builddir" != ".." ; then    # we know where to go and
+      as_dir=$ax_enable_builddir; as_fn_mkdir_p
+      echo __.$ax_enable_builddir.__ > $ax_enable_builddir/conftest.tmp
+      cd $ax_enable_builddir
+      if grep __.$ax_enable_builddir.__ conftest.tmp >/dev/null 2>/dev/null ; then
+        rm conftest.tmp
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: continue configure in default builddir \"./$ax_enable_builddir\"" >&5
+$as_echo "continue configure in default builddir \"./$ax_enable_builddir\"" >&6; }
+      else
+        as_fn_error $? "could not change to default builddir \"./$ax_enable_builddir\"" "$LINENO" 5
+      fi
+      srcdir=`echo "$ax_enable_builddir" |
+              sed -e 's,^\./,,;s,[^/]$,&/,;s,[^/]*/,../,g;s,[/]$,,;'`
+      # going to restart from subdirectory location
+      test -f $srcdir/config.log   && mv $srcdir/config.log   .
+      test -f $srcdir/confdefs.h   && mv $srcdir/confdefs.h   .
+      test -f $srcdir/conftest.log && mv $srcdir/conftest.log .
+      test -f $srcdir/$cache_file  && mv $srcdir/$cache_file  .
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: ....exec $SHELL $srcdir/$0 \"--srcdir=$srcdir\" \"--enable-builddir=$ax_enable_builddir\" ${1+\"$@\"}" >&5
+$as_echo "....exec $SHELL $srcdir/$0 \"--srcdir=$srcdir\" \"--enable-builddir=$ax_enable_builddir\" ${1+\"$@\"}" >&6; }
+      case "$0" in # restart
+       /\\*) eval $SHELL "'$0'" "'--srcdir=$srcdir'" "'--enable-builddir=$ax_enable_builddir'" $ac_configure_args ;;
+       *) eval $SHELL "'$srcdir/$0'" "'--srcdir=$srcdir'" "'--enable-builddir=$ax_enable_builddir'" $ac_configure_args ;;
+      esac ; exit $?
+    fi
+  fi
+fi fi
+test ".$ax_enable_builddir" = ".auto" && ax_enable_builddir="."
+# Extract the first word of "gsed sed", so it can be a program name with args.
+set dummy gsed sed; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ax_enable_builddir_sed+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ax_enable_builddir_sed in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ax_enable_builddir_sed="$ax_enable_builddir_sed" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_ax_enable_builddir_sed="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_ax_enable_builddir_sed" && ac_cv_path_ax_enable_builddir_sed="sed"
+  ;;
+esac
+fi
+ax_enable_builddir_sed=$ac_cv_path_ax_enable_builddir_sed
+if test -n "$ax_enable_builddir_sed"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_enable_builddir_sed" >&5
+$as_echo "$ax_enable_builddir_sed" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ax_enable_builddir_auxdir="$am_aux_dir"
+ac_config_commands="$ac_config_commands buildir"
+
+
+am__api_version='1.11'
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[\\\"\#\$\&\'\`$am_lf]*)
+    as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+  *[\\\"\#\$\&\'\`$am_lf\ \	]*)
+    as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t "$srcdir/configure" conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$*" != "X $srcdir/configure conftest.file" \
+      && test "$*" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      as_fn_error $? "ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" "$LINENO" 5
+   fi
+
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+  if ${ac_cv_path_mkdir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in mkdir gmkdir; do
+	 for ac_exec_ext in '' $ac_executable_extensions; do
+	   { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+	   case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+	     'mkdir (GNU coreutils) '* | \
+	     'mkdir (coreutils) '* | \
+	     'mkdir (fileutils) '4.1*)
+	       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+	       break 3;;
+	   esac
+	 done
+       done
+  done
+IFS=$as_save_IFS
+
+fi
+
+  test -d ./--version && rmdir ./--version
+  if test "${ac_cv_path_mkdir+set}" = set; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+  [\\/$]* | ?:[\\/]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  am__isrc=' -I$(srcdir)'
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='libffi'
+ VERSION='3.0.10'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+
+# The same as in boehm-gc and libstdc++. Have to borrow it from there.
+# We must force CC to /not/ be precious variables; otherwise
+# the wrong, non-multilib-adjusted value will be used in multilibs.
+# As a side effect, we have to subst CFLAGS ourselves.
+# Also save and restore CFLAGS, since AC_PROG_CC will come up with
+# defaults of its own if none are provided.
+
+
+
+save_CFLAGS=$CFLAGS
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+  enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+CFLAGS=$save_CFLAGS
+
+
+
+
+
+# By default we simply use the C compiler to build assembly code.
+
+test "${CCAS+set}" = set || CCAS=$CC
+test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS
+
+
+
+depcc="$CCAS"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CCAS_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CCAS_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CCAS_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CCAS_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CCAS_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CCAS_dependencies_compiler_type" >&6; }
+CCASDEPMODE=depmode=$am_cv_CCAS_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CCAS_dependencies_compiler_type" = gcc3; then
+  am__fastdepCCAS_TRUE=
+  am__fastdepCCAS_FALSE='#'
+else
+  am__fastdepCCAS_TRUE='#'
+  am__fastdepCCAS_FALSE=
+fi
+
+
+if test "x$CC" != xcc; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
+$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5
+$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
+fi
+set dummy $CC; ac_cc=`$as_echo "$2" |
+		      sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+rm -f conftest2.*
+if { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } &&
+   test -f conftest2.$ac_objext && { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; };
+then
+  eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+  if test "x$CC" != xcc; then
+    # Test first that cc exists at all.
+    if { ac_try='cc -c conftest.$ac_ext >&5'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+      ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+      rm -f conftest2.*
+      if { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } &&
+	 test -f conftest2.$ac_objext && { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; };
+      then
+	# cc works too.
+	:
+      else
+	# cc exists but doesn't like -o.
+	eval ac_cv_prog_cc_${ac_cc}_c_o=no
+      fi
+    fi
+  fi
+else
+  eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f core conftest*
+
+fi
+if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h
+
+fi
+
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+
+
+case `pwd` in
+  *\ * | *\	*)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4'
+macro_revision='1.3293'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case "$ECHO" in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+     for ac_i in 1 2 3 4 5 6 7; do
+       ac_script="$ac_script$as_nl$ac_script"
+     done
+     echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+     { ac_script=; unset ac_script;}
+     if test -z "$SED"; then
+  ac_path_SED_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+# Check for GNU ac_path_SED and select it if it is found.
+  # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+  ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo '' >> "conftest.nl"
+    "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_SED_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_SED="$ac_path_SED"
+      ac_path_SED_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_SED_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_SED"; then
+    as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+  fi
+else
+  ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+  rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+   then ac_cv_path_FGREP="$GREP -F"
+   else
+     if test -z "$FGREP"; then
+  ac_path_FGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in fgrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+  # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'FGREP' >> "conftest.nl"
+    "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_FGREP="$ac_path_FGREP"
+      ac_path_FGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_FGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_FGREP"; then
+    as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_FGREP=$FGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in dumpbin "link -dump"
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DUMPBIN"; then
+  ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$DUMPBIN" && break
+  done
+fi
+if test -z "$DUMPBIN"; then
+  ac_ct_DUMPBIN=$DUMPBIN
+  for ac_prog in dumpbin "link -dump"
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DUMPBIN"; then
+  ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_DUMPBIN" && break
+done
+
+  if test "x$ac_ct_DUMPBIN" = x; then
+    DUMPBIN=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DUMPBIN=$ac_ct_DUMPBIN
+  fi
+fi
+
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+  cat conftest.out >&5
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+    i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[	 ]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+  ac_ct_OBJDUMP=$OBJDUMP
+  # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OBJDUMP"; then
+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OBJDUMP="objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJDUMP" = x; then
+    OBJDUMP="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OBJDUMP=$ac_ct_OBJDUMP
+  fi
+else
+  OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[45]*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc*)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[3-9]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DLLTOOL"; then
+  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+  ac_ct_DLLTOOL=$DLLTOOL
+  # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DLLTOOL"; then
+  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DLLTOOL" = x; then
+    DLLTOOL="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DLLTOOL=$ac_ct_DLLTOOL
+  fi
+else
+  DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_AR="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ar_at_file=no
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[ABCDEGRST]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[BCDEGRST]'
+  ;;
+osf*)
+  symcode='[BCDEGQRST]'
+  ;;
+solaris*)
+  symcode='[BDRT]'
+  ;;
+sco3.2v5*)
+  symcode='[DT]'
+  ;;
+sysv4.2uw2*)
+  symcode='[DT]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[ABDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK '"\
+"     {last_section=section; section=\$ 3};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+LT_DLSYM_CONST struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_globsym_save_LIBS=$LIBS
+	  lt_globsym_save_CFLAGS=$CFLAGS
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS=$lt_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_save_CFLAGS
+	else
+	  echo "cannot find nm_test_func in $nlist" >&5
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+  withval=$with_sysroot;
+else
+  with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+   as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+   ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+  enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_i386"
+	    ;;
+	  ppc64-*linux*|powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  ppc*-*linux*|powerpc*-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_cc_needs_belf=yes
+else
+  lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MANIFEST_TOOL"; then
+  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+  # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_MANIFEST_TOOL"; then
+  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_MANIFEST_TOOL" = x; then
+    MANIFEST_TOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+  fi
+else
+  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&5
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+  case $host_os in
+    rhapsody* | darwin*)
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DSYMUTIL"; then
+  ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+  ac_ct_DSYMUTIL=$DSYMUTIL
+  # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DSYMUTIL"; then
+  ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DSYMUTIL" = x; then
+    DSYMUTIL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DSYMUTIL=$ac_ct_DSYMUTIL
+  fi
+else
+  DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NMEDIT"; then
+  ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+  ac_ct_NMEDIT=$NMEDIT
+  # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_NMEDIT"; then
+  ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_NMEDIT="nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_NMEDIT" = x; then
+    NMEDIT=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    NMEDIT=$ac_ct_NMEDIT
+  fi
+else
+  NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$LIPO"; then
+  ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+  ac_ct_LIPO=$LIPO
+  # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_LIPO"; then
+  ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_LIPO="lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_LIPO" = x; then
+    LIPO=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    LIPO=$ac_ct_LIPO
+  fi
+else
+  LIPO="$ac_cv_prog_LIPO"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL"; then
+  ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+  ac_ct_OTOOL=$OTOOL
+  # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL"; then
+  ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OTOOL="otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL" = x; then
+    OTOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL=$ac_ct_OTOOL
+  fi
+else
+  OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL64"; then
+  ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+  ac_ct_OTOOL64=$OTOOL64
+  # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL64"; then
+  ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OTOOL64="otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL64" = x; then
+    OTOOL64=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL64=$ac_ct_OTOOL64
+  fi
+else
+  OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&5
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_ld_exported_symbols_list=yes
+else
+  lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
+      echo "$RANLIB libconftest.a" >&5
+      $RANLIB libconftest.a 2>&5
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&5
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+    case $host_os in
+    rhapsody* | darwin1.[012])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[012]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if ${ac_cv_prog_CPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in dlfcn.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+  enable_win32_dll=no
+
+
+            # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+  enableval=$enable_shared; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+  # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+  enableval=$enable_static; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+  withval=$with_pic; pic_mode="$withval"
+else
+  pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+  # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+  enableval=$enable_fast_install; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+  *)
+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+  esac
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+
+
+
+
+
+  lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl='-Wl,'
+    lt_prog_compiler_static='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static=
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+    esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      lt_prog_compiler_wl='-Xlinker '
+      lt_prog_compiler_pic='-Xcompiler -fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      else
+	lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-KPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='--shared'
+	lt_prog_compiler_static='--static'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	lt_prog_compiler_wl='-Wl,-Wl,,'
+	lt_prog_compiler_pic='-PIC'
+	lt_prog_compiler_static='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fpic'
+	lt_prog_compiler_static='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static='-non_shared'
+        ;;
+      xl* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ F* | *Sun*Fortran*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl=''
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    rdos*)
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+	lt_prog_compiler_wl='-Qoption ld ';;
+      *)
+	lt_prog_compiler_wl='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl='-Qoption ld '
+      lt_prog_compiler_pic='-PIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_prog_compiler_pic='-Kconform_pic'
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_can_build_shared=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic='-pic'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared=no
+      ;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic=
+    ;;
+  *)
+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+    ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+    case $lt_prog_compiler_pic in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+     esac
+else
+    lt_prog_compiler_pic=
+     lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  runpath_var=
+  allow_undefined_flag=
+  always_export_symbols=no
+  archive_cmds=
+  archive_expsym_cmds=
+  compiler_needs_object=no
+  enable_shared_with_static_runtimes=no
+  export_dynamic_flag_spec=
+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  hardcode_automatic=no
+  hardcode_direct=no
+  hardcode_direct_absolute=no
+  hardcode_libdir_flag_spec=
+  hardcode_libdir_flag_spec_ld=
+  hardcode_libdir_separator=
+  hardcode_minus_L=no
+  hardcode_shlibpath_var=unsupported
+  inherit_rpath=no
+  link_all_deplibs=unknown
+  module_cmds=
+  module_expsym_cmds=
+  old_archive_from_new_cmds=
+  old_archive_from_expsyms_cmds=
+  thread_safe_flag_spec=
+  whole_archive_flag_spec=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+	  *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      whole_archive_flag_spec=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[3-9]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag=unsupported
+	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
+      allow_undefined_flag=unsupported
+      always_export_symbols=no
+      enable_shared_with_static_runtimes=yes
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    haiku*)
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      link_all_deplibs=yes
+      ;;
+
+    interix[3-9]*)
+      hardcode_direct=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=' $pic_flag'
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  whole_archive_flag_spec=
+	  tmp_sharedflag='--shared' ;;
+	xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf* | bgf* | bgxlf* | mpixlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+	  hardcode_libdir_flag_spec=
+	  hardcode_libdir_flag_spec_ld='-rpath $libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    ld_shlibs=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec=
+      export_dynamic_flag_spec=
+      whole_archive_flag_spec=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag=unsupported
+      always_export_symbols=yes
+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct=unsupported
+      fi
+      ;;
+
+    aix[4-9]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds=''
+      hardcode_direct=yes
+      hardcode_direct_absolute=yes
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      file_list_spec='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[012]|aix4.[012].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  hardcode_direct=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  hardcode_minus_L=yes
+	  hardcode_libdir_flag_spec='-L$libdir'
+	  hardcode_libdir_separator=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      export_dynamic_flag_spec='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
+
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag="-z nodefs"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
+
+	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag=' ${wl}-bernotok'
+	  allow_undefined_flag=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    whole_archive_flag_spec='$convenience'
+	  fi
+	  archive_cmds_need_lc=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	always_export_symbols=yes
+	file_list_spec='@'
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+	enable_shared_with_static_runtimes=yes
+	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	old_postinstall_cmds='chmod 644 $oldlib'
+	postlink_cmds='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+	# The linker will automatically build a .lib file if we build a DLL.
+	old_archive_from_new_cmds='true'
+	# FIXME: Should let the user specify the lib program.
+	old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+	enable_shared_with_static_runtimes=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  else
+    whole_archive_flag_spec=''
+  fi
+  link_all_deplibs=yes
+  allow_undefined_flag="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=func_echo_all
+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+  else
+  ld_shlibs=no
+  fi
+
+      ;;
+
+    dgux*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      export_dynamic_flag_spec='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_flag_spec_ld='+b $libdir'
+	hardcode_libdir_separator=:
+	hardcode_direct=yes
+	hardcode_direct_absolute=yes
+	export_dynamic_flag_spec='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler__b=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS -b"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler__b=yes
+       fi
+     else
+       lt_cv_prog_compiler__b=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+    archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  hardcode_direct=no
+	  hardcode_shlibpath_var=no
+	  ;;
+	*)
+	  hardcode_direct=yes
+	  hardcode_direct_absolute=yes
+	  export_dynamic_flag_spec='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+	# This should be the same for all languages, so no per-tag cache variable.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_irix_exported_symbol=yes
+else
+  lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+           LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      inherit_rpath=yes
+      link_all_deplibs=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    newsos6)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_shlibpath_var=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	hardcode_direct=yes
+	hardcode_shlibpath_var=no
+	hardcode_direct_absolute=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	  export_dynamic_flag_spec='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	     archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     hardcode_libdir_flag_spec='-R$libdir'
+	     ;;
+	   *)
+	     archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_separator=:
+      ;;
+
+    solaris*)
+      no_undefined_flag=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_shlibpath_var=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      link_all_deplibs=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds='$CC -r -o $output$reload_objs'
+	  hardcode_direct=no
+        ;;
+	motorola)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag='${wl}-z,text'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag='${wl}-z,text'
+      allow_undefined_flag='${wl}-z,nodefs'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-R,$libdir'
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      export_dynamic_flag_spec='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      ld_shlibs=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	export_dynamic_flag_spec='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$lt_prog_compiler_wl
+	  pic_flag=$lt_prog_compiler_pic
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$allow_undefined_flag
+	  allow_undefined_flag=
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	  then
+	    lt_cv_archive_cmds_need_lc=no
+	  else
+	    lt_cv_archive_cmds_need_lc=yes
+	  fi
+	  allow_undefined_flag=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[lt_foo]++; }
+  if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+haiku*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+   test -n "$runpath_var" ||
+   test "X$hardcode_automatic" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+   test "$inherit_rpath" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+  if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+    ;;
+
+  *)
+    ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+  lt_cv_dlopen="shl_load"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_shl_load=yes
+else
+  ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_svld_dlopen=yes
+else
+  ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_dld_link=yes
+else
+  ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    fi
+    ;;
+  *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+  # Report which library types will actually be built
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[4-9]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+
+
+
+
+
+
+
+
+
+
+
+        ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler vendor" >&5
+$as_echo_n "checking for C compiler vendor... " >&6; }
+if ${ax_cv_c_compiler_vendor+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ax_cv_c_compiler_vendor=unknown
+  # note: don't check for gcc first since some other compilers define __GNUC__
+  for ventest in intel:__ICC,__ECC,__INTEL_COMPILER ibm:__xlc__,__xlC__,__IBMC__,__IBMCPP__ pathscale:__PATHCC__,__PATHSCALE__ clang:__clang__ gnu:__GNUC__ sun:__SUNPRO_C,__SUNPRO_CC hp:__HP_cc,__HP_aCC dec:__DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland:__BORLANDC__,__TURBOC__ comeau:__COMO__ cray:_CRAYC kai:__KCC lcc:__LCC__ metrowerks:__MWERKS__ sgi:__sgi,sgi microsoft:_MSC_VER watcom:__WATCOMC__ portland:__PGI; do
+    vencpp="defined("`echo $ventest | cut -d: -f2 | sed 's/,/) || defined(/g'`")"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#if !($vencpp)
+      thisisanerror;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ax_cv_c_compiler_vendor=`echo $ventest | cut -d: -f1`; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_c_compiler_vendor" >&5
+$as_echo "$ax_cv_c_compiler_vendor" >&6; }
+
+
+
+
+
+
+# Check whether --enable-portable-binary was given.
+if test "${enable_portable_binary+set}" = set; then :
+  enableval=$enable_portable_binary; acx_maxopt_portable=$withval
+else
+  acx_maxopt_portable=no
+fi
+
+
+# Try to determine "good" native compiler flags if none specified via CFLAGS
+if test "$ac_test_CFLAGS" != "set"; then
+  CFLAGS=""
+  case $ax_cv_c_compiler_vendor in
+    dec) CFLAGS="-newc -w0 -O5 -ansi_alias -ansi_args -fp_reorder -tune host"
+	 if test "x$acx_maxopt_portable" = xno; then
+           CFLAGS="$CFLAGS -arch host"
+         fi;;
+
+    sun) CFLAGS="-native -fast -xO5 -dalign"
+	 if test "x$acx_maxopt_portable" = xyes; then
+	   CFLAGS="$CFLAGS -xarch=generic"
+         fi;;
+
+    hp)  CFLAGS="+Oall +Optrs_ansi +DSnative"
+	 if test "x$acx_maxopt_portable" = xyes; then
+	   CFLAGS="$CFLAGS +DAportable"
+	 fi;;
+
+    ibm) if test "x$acx_maxopt_portable" = xno; then
+           xlc_opt="-qarch=auto -qtune=auto"
+	 else
+           xlc_opt="-qtune=auto"
+	 fi
+          { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $xlc_opt" >&5
+$as_echo_n "checking whether C compiler accepts $xlc_opt... " >&6; }
+ax_save_FLAGS=$CFLAGS
+   CFLAGS="$xlc_opt"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval `$as_echo "ax_cv_c_flags_$xlc_opt" | $as_tr_sh`=yes
+else
+  eval `$as_echo "ax_cv_c_flags_$xlc_opt" | $as_tr_sh`=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   CFLAGS=$ax_save_FLAGS
+eval ax_check_compiler_flags=$`$as_echo "ax_cv_c_flags_$xlc_opt" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_check_compiler_flags" >&5
+$as_echo "$ax_check_compiler_flags" >&6; }
+if test "x$ax_check_compiler_flags" = xyes; then
+	CFLAGS="-O3 -qansialias -w $xlc_opt"
+else
+	CFLAGS="-O3 -qansialias -w"
+                echo "******************************************************"
+                echo "*  You seem to have the IBM  C compiler.  It is      *"
+                echo "*  recommended for best performance that you use:    *"
+                echo "*                                                    *"
+                echo "*    CFLAGS=-O3 -qarch=xxx -qtune=xxx -qansialias -w *"
+                echo "*                      ^^^        ^^^                *"
+                echo "*  where xxx is pwr2, pwr3, 604, or whatever kind of *"
+                echo "*  CPU you have.  (Set the CFLAGS environment var.   *"
+                echo "*  and re-run configure.)  For more info, man cc.    *"
+                echo "******************************************************"
+fi
+
+         ;;
+
+    intel) CFLAGS="-O3 -ansi_alias"
+	if test "x$acx_maxopt_portable" = xno; then
+	  icc_archflag=unknown
+	  icc_flags=""
+	  case $host_cpu in
+	    i686*|x86_64*)
+              # icc accepts gcc assembly syntax, so these should work:
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for x86 cpuid 0 output" >&5
+$as_echo_n "checking for x86 cpuid 0 output... " >&6; }
+if ${ax_cv_gcc_x86_cpuid_0+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ax_cv_gcc_x86_cpuid_0=unknown
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+
+     int op = 0, eax, ebx, ecx, edx;
+     FILE *f;
+      __asm__("cpuid"
+        : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+        : "a" (op));
+     f = fopen("conftest_cpuid", "w"); if (!f) return 1;
+     fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
+     fclose(f);
+     return 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ax_cv_gcc_x86_cpuid_0=`cat conftest_cpuid`; rm -f conftest_cpuid
+else
+  ax_cv_gcc_x86_cpuid_0=unknown; rm -f conftest_cpuid
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_x86_cpuid_0" >&5
+$as_echo "$ax_cv_gcc_x86_cpuid_0" >&6; }
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for x86 cpuid 1 output" >&5
+$as_echo_n "checking for x86 cpuid 1 output... " >&6; }
+if ${ax_cv_gcc_x86_cpuid_1+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ax_cv_gcc_x86_cpuid_1=unknown
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+
+     int op = 1, eax, ebx, ecx, edx;
+     FILE *f;
+      __asm__("cpuid"
+        : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+        : "a" (op));
+     f = fopen("conftest_cpuid", "w"); if (!f) return 1;
+     fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
+     fclose(f);
+     return 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ax_cv_gcc_x86_cpuid_1=`cat conftest_cpuid`; rm -f conftest_cpuid
+else
+  ax_cv_gcc_x86_cpuid_1=unknown; rm -f conftest_cpuid
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_x86_cpuid_1" >&5
+$as_echo "$ax_cv_gcc_x86_cpuid_1" >&6; }
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+	      case $ax_cv_gcc_x86_cpuid_0 in # see AX_GCC_ARCHFLAG
+                *:756e6547:*:*) # Intel
+                  case $ax_cv_gcc_x86_cpuid_1 in
+                    *6a?:*[234]:*:*|*6[789b]?:*:*:*) icc_flags="-xK";;
+                    *f3[347]:*:*:*|*f41347:*:*:*) icc_flags="-xP -xN -xW -xK";;
+                    *f??:*:*:*) icc_flags="-xN -xW -xK";;
+                  esac ;;
+              esac ;;
+          esac
+          if test "x$icc_flags" != x; then
+            for flag in $icc_flags; do
+               { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+ax_save_FLAGS=$CFLAGS
+   CFLAGS="$flag"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval `$as_echo "ax_cv_c_flags_$flag" | $as_tr_sh`=yes
+else
+  eval `$as_echo "ax_cv_c_flags_$flag" | $as_tr_sh`=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   CFLAGS=$ax_save_FLAGS
+eval ax_check_compiler_flags=$`$as_echo "ax_cv_c_flags_$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_check_compiler_flags" >&5
+$as_echo "$ax_check_compiler_flags" >&6; }
+if test "x$ax_check_compiler_flags" = xyes; then
+	icc_archflag=$flag; break
+else
+	:
+fi
+
+            done
+          fi
+          { $as_echo "$as_me:${as_lineno-$LINENO}: checking for icc architecture flag" >&5
+$as_echo_n "checking for icc architecture flag... " >&6; }
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $icc_archflag" >&5
+$as_echo "$icc_archflag" >&6; }
+          if test "x$icc_archflag" != xunknown; then
+            CFLAGS="$CFLAGS $icc_archflag"
+          fi
+        fi
+	;;
+
+    gnu)
+     # default optimization flags for gcc on all systems
+     CFLAGS="-O3 -fomit-frame-pointer"
+
+     #  -fstrict-aliasing for gcc-2.95+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fstrict-aliasing" >&5
+$as_echo_n "checking whether C compiler accepts -fstrict-aliasing... " >&6; }
+if ${ax_cv_c_flags__fstrict_aliasing+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+      ax_save_FLAGS=$CFLAGS
+      CFLAGS="-fstrict-aliasing"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ax_cv_c_flags__fstrict_aliasing=yes
+else
+  ax_cv_c_flags__fstrict_aliasing=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+      CFLAGS=$ax_save_FLAGS
+fi
+
+eval ax_check_compiler_flags=$ax_cv_c_flags__fstrict_aliasing
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_check_compiler_flags" >&5
+$as_echo "$ax_check_compiler_flags" >&6; }
+if test "x$ax_check_compiler_flags" = xyes; then
+	CFLAGS="$CFLAGS -fstrict-aliasing"
+else
+	:
+fi
+
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -ffast-math" >&5
+$as_echo_n "checking whether C compiler accepts -ffast-math... " >&6; }
+if ${ax_cv_c_flags__ffast_math+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+      ax_save_FLAGS=$CFLAGS
+      CFLAGS="-ffast-math"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ax_cv_c_flags__ffast_math=yes
+else
+  ax_cv_c_flags__ffast_math=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+      CFLAGS=$ax_save_FLAGS
+fi
+
+eval ax_check_compiler_flags=$ax_cv_c_flags__ffast_math
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_check_compiler_flags" >&5
+$as_echo "$ax_check_compiler_flags" >&6; }
+if test "x$ax_check_compiler_flags" = xyes; then
+	CFLAGS="$CFLAGS -ffast-math"
+else
+	:
+fi
+
+
+
+
+
+
+# Check whether --with-gcc-arch was given.
+if test "${with_gcc_arch+set}" = set; then :
+  withval=$with_gcc_arch; ax_gcc_arch=$withval
+else
+  ax_gcc_arch=yes
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc architecture flag" >&5
+$as_echo_n "checking for gcc architecture flag... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+if ${ax_cv_gcc_archflag+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+ax_cv_gcc_archflag="unknown"
+
+if test "$GCC" = yes; then
+
+if test "x$ax_gcc_arch" = xyes; then
+ax_gcc_arch=""
+if test "$cross_compiling" = no; then
+case $host_cpu in
+  i[3456]86*|x86_64*) # use cpuid codes, in part from x86info-1.7 by D. Jones
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for x86 cpuid 0 output" >&5
+$as_echo_n "checking for x86 cpuid 0 output... " >&6; }
+if ${ax_cv_gcc_x86_cpuid_0+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ax_cv_gcc_x86_cpuid_0=unknown
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+
+     int op = 0, eax, ebx, ecx, edx;
+     FILE *f;
+      __asm__("cpuid"
+        : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+        : "a" (op));
+     f = fopen("conftest_cpuid", "w"); if (!f) return 1;
+     fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
+     fclose(f);
+     return 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ax_cv_gcc_x86_cpuid_0=`cat conftest_cpuid`; rm -f conftest_cpuid
+else
+  ax_cv_gcc_x86_cpuid_0=unknown; rm -f conftest_cpuid
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_x86_cpuid_0" >&5
+$as_echo "$ax_cv_gcc_x86_cpuid_0" >&6; }
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for x86 cpuid 1 output" >&5
+$as_echo_n "checking for x86 cpuid 1 output... " >&6; }
+if ${ax_cv_gcc_x86_cpuid_1+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ax_cv_gcc_x86_cpuid_1=unknown
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+
+     int op = 1, eax, ebx, ecx, edx;
+     FILE *f;
+      __asm__("cpuid"
+        : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+        : "a" (op));
+     f = fopen("conftest_cpuid", "w"); if (!f) return 1;
+     fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
+     fclose(f);
+     return 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ax_cv_gcc_x86_cpuid_1=`cat conftest_cpuid`; rm -f conftest_cpuid
+else
+  ax_cv_gcc_x86_cpuid_1=unknown; rm -f conftest_cpuid
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_x86_cpuid_1" >&5
+$as_echo "$ax_cv_gcc_x86_cpuid_1" >&6; }
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+     case $ax_cv_gcc_x86_cpuid_0 in
+       *:756e6547:*:*) # Intel
+          case $ax_cv_gcc_x86_cpuid_1 in
+	    *5[48]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;;
+	    *5??:*:*:*) ax_gcc_arch=pentium ;;
+	    *6[3456]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
+	    *6a?:*[01]:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
+	    *6a?:*[234]:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
+	    *6[9d]?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;;
+	    *6[78b]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
+	    *6??:*:*:*) ax_gcc_arch=pentiumpro ;;
+            *f3[347]:*:*:*|*f41347:*:*:*)
+		case $host_cpu in
+                  x86_64*) ax_gcc_arch="nocona pentium4 pentiumpro" ;;
+                  *) ax_gcc_arch="prescott pentium4 pentiumpro" ;;
+                esac ;;
+            *f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro";;
+          esac ;;
+       *:68747541:*:*) # AMD
+          case $ax_cv_gcc_x86_cpuid_1 in
+	    *5[67]?:*:*:*) ax_gcc_arch=k6 ;;
+	    *5[8d]?:*:*:*) ax_gcc_arch="k6-2 k6" ;;
+	    *5[9]?:*:*:*) ax_gcc_arch="k6-3 k6" ;;
+	    *60?:*:*:*) ax_gcc_arch=k7 ;;
+	    *6[12]?:*:*:*) ax_gcc_arch="athlon k7" ;;
+	    *6[34]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;;
+	    *67?:*:*:*) ax_gcc_arch="athlon-4 athlon k7" ;;
+	    *6[68a]?:*:*:*)
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for x86 cpuid 0x80000006 output" >&5
+$as_echo_n "checking for x86 cpuid 0x80000006 output... " >&6; }
+if ${ax_cv_gcc_x86_cpuid_0x80000006+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ax_cv_gcc_x86_cpuid_0x80000006=unknown
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+
+     int op = 0x80000006, eax, ebx, ecx, edx;
+     FILE *f;
+      __asm__("cpuid"
+        : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+        : "a" (op));
+     f = fopen("conftest_cpuid", "w"); if (!f) return 1;
+     fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
+     fclose(f);
+     return 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ax_cv_gcc_x86_cpuid_0x80000006=`cat conftest_cpuid`; rm -f conftest_cpuid
+else
+  ax_cv_gcc_x86_cpuid_0x80000006=unknown; rm -f conftest_cpuid
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_x86_cpuid_0x80000006" >&5
+$as_echo "$ax_cv_gcc_x86_cpuid_0x80000006" >&6; }
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ # L2 cache size
+	       case $ax_cv_gcc_x86_cpuid_0x80000006 in
+                 *:*:*[1-9a-f]??????:*) # (L2 = ecx >> 16) >= 256
+			ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;;
+                 *) ax_gcc_arch="athlon-4 athlon k7" ;;
+	       esac ;;
+	    *f[4cef8b]?:*:*:*) ax_gcc_arch="athlon64 k8" ;;
+	    *f5?:*:*:*) ax_gcc_arch="opteron k8" ;;
+	    *f7?:*:*:*) ax_gcc_arch="athlon-fx opteron k8" ;;
+	    *f??:*:*:*) ax_gcc_arch="k8" ;;
+          esac ;;
+	*:746e6543:*:*) # IDT
+	   case $ax_cv_gcc_x86_cpuid_1 in
+	     *54?:*:*:*) ax_gcc_arch=winchip-c6 ;;
+	     *58?:*:*:*) ax_gcc_arch=winchip2 ;;
+	     *6[78]?:*:*:*) ax_gcc_arch=c3 ;;
+	     *69?:*:*:*) ax_gcc_arch="c3-2 c3" ;;
+	   esac ;;
+     esac
+     if test x"$ax_gcc_arch" = x; then # fallback
+	case $host_cpu in
+	  i586*) ax_gcc_arch=pentium ;;
+	  i686*) ax_gcc_arch=pentiumpro ;;
+        esac
+     fi
+     ;;
+
+  sparc*)
+     # Extract the first word of "prtdiag", so it can be a program name with args.
+set dummy prtdiag; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PRTDIAG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PRTDIAG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PRTDIAG="$PRTDIAG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_dummy="$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/"
+for as_dir in $as_dummy
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_PRTDIAG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_PRTDIAG" && ac_cv_path_PRTDIAG="prtdiag"
+  ;;
+esac
+fi
+PRTDIAG=$ac_cv_path_PRTDIAG
+if test -n "$PRTDIAG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PRTDIAG" >&5
+$as_echo "$PRTDIAG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+     cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null`
+     cputype=`echo "$cputype" | tr -d ' -' |tr $as_cr_LETTERS $as_cr_letters`
+     case $cputype in
+         *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;;
+         *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;;
+         *ultrasparc*) ax_gcc_arch="ultrasparc v9" ;;
+         *supersparc*|*tms390z5[05]*) ax_gcc_arch="supersparc v8" ;;
+         *hypersparc*|*rt62[056]*) ax_gcc_arch="hypersparc v8" ;;
+         *cypress*) ax_gcc_arch=cypress ;;
+     esac ;;
+
+  alphaev5) ax_gcc_arch=ev5 ;;
+  alphaev56) ax_gcc_arch=ev56 ;;
+  alphapca56) ax_gcc_arch="pca56 ev56" ;;
+  alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;;
+  alphaev6) ax_gcc_arch=ev6 ;;
+  alphaev67) ax_gcc_arch=ev67 ;;
+  alphaev68) ax_gcc_arch="ev68 ev67" ;;
+  alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;;
+  alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;;
+  alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;;
+
+  powerpc*)
+     cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | sed 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null`
+     cputype=`echo $cputype | sed -e 's/ppc//g;s/ *//g'`
+     case $cputype in
+       *750*) ax_gcc_arch="750 G3" ;;
+       *740[0-9]*) ax_gcc_arch="$cputype 7400 G4" ;;
+       *74[4-5][0-9]*) ax_gcc_arch="$cputype 7450 G4" ;;
+       *74[0-9][0-9]*) ax_gcc_arch="$cputype G4" ;;
+       *970*) ax_gcc_arch="970 G5 power4";;
+       *POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";;
+       *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";;
+       603ev|8240) ax_gcc_arch="$cputype 603e 603";;
+       *) ax_gcc_arch=$cputype ;;
+     esac
+     ax_gcc_arch="$ax_gcc_arch powerpc"
+     ;;
+esac
+fi # not cross-compiling
+fi # guess arch
+
+if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then
+for arch in $ax_gcc_arch; do
+  if test "x$acx_maxopt_portable" = xyes; then # if we require portable code
+    flags="-mtune=$arch"
+    # -mcpu=$arch and m$arch generate nonportable code on every arch except
+    # x86.  And some other arches (e.g. Alpha) don't accept -mtune.  Grrr.
+    case $host_cpu in i*86|x86_64*) flags="$flags -mcpu=$arch -m$arch";; esac
+  else
+    flags="-march=$arch -mcpu=$arch -m$arch"
+  fi
+  for flag in $flags; do
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
+$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
+ax_save_FLAGS=$CFLAGS
+   CFLAGS="$flag"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval `$as_echo "ax_cv_c_flags_$flag" | $as_tr_sh`=yes
+else
+  eval `$as_echo "ax_cv_c_flags_$flag" | $as_tr_sh`=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   CFLAGS=$ax_save_FLAGS
+eval ax_check_compiler_flags=$`$as_echo "ax_cv_c_flags_$flag" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_check_compiler_flags" >&5
+$as_echo "$ax_check_compiler_flags" >&6; }
+if test "x$ax_check_compiler_flags" = xyes; then
+	ax_cv_gcc_archflag=$flag; break
+else
+	:
+fi
+
+  done
+  test "x$ax_cv_gcc_archflag" = xunknown || break
+done
+fi
+
+fi # $GCC=yes
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc architecture flag" >&5
+$as_echo_n "checking for gcc architecture flag... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_archflag" >&5
+$as_echo "$ax_cv_gcc_archflag" >&6; }
+if test "x$ax_cv_gcc_archflag" = xunknown; then
+  :
+else
+  CFLAGS="$CFLAGS $ax_cv_gcc_archflag"
+fi
+
+     ;;
+  esac
+
+  if test -z "$CFLAGS"; then
+	echo ""
+	echo "********************************************************"
+        echo "* WARNING: Don't know the best CFLAGS for this system  *"
+        echo "* Use ./configure CFLAGS=... to specify your own flags *"
+	echo "* (otherwise, a default of CFLAGS=-O3 will be used)    *"
+	echo "********************************************************"
+	echo ""
+        CFLAGS="-O3"
+  fi
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $CFLAGS" >&5
+$as_echo_n "checking whether C compiler accepts $CFLAGS... " >&6; }
+ax_save_FLAGS=$CFLAGS
+   CFLAGS="$CFLAGS"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval `$as_echo "ax_cv_c_flags_$CFLAGS" | $as_tr_sh`=yes
+else
+  eval `$as_echo "ax_cv_c_flags_$CFLAGS" | $as_tr_sh`=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   CFLAGS=$ax_save_FLAGS
+eval ax_check_compiler_flags=$`$as_echo "ax_cv_c_flags_$CFLAGS" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_check_compiler_flags" >&5
+$as_echo "$ax_check_compiler_flags" >&6; }
+if test "x$ax_check_compiler_flags" = xyes; then
+	:
+else
+
+	echo ""
+        echo "********************************************************"
+        echo "* WARNING: The guessed CFLAGS don't seem to work with  *"
+        echo "* your compiler.                                       *"
+        echo "* Use ./configure CFLAGS=... to specify your own flags *"
+        echo "********************************************************"
+        echo ""
+        CFLAGS=""
+
+fi
+
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS for maximum warnings" >&5
+$as_echo_n "checking CFLAGS for maximum warnings... " >&6; }
+if ${ac_cv_cflags_warn_all+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_cflags_warn_all="no, unknown"
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ ac_save_CFLAGS="$CFLAGS"
+for ac_arg in "-pedantic  % -Wall"          "-xstrconst % -v"             "-std1      % -verbose -w0 -warnprotos"    "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd"    "-ansi -ansiE % -fullwarn"    "+ESlit     % +w1"            "-Xc        % -pvctl,fullmsg"    "-h conform % -h msglevel 2"    #
+do CFLAGS="$ac_save_CFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_cflags_warn_all=`echo $ac_arg | sed -e 's,.*% *,,'` ; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+ CFLAGS="$ac_save_CFLAGS"
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags_warn_all" >&5
+$as_echo "$ac_cv_cflags_warn_all" >&6; }
+case ".$ac_cv_cflags_warn_all" in
+     .ok|.ok,*)  ;;
+   .|.no|.no,*)
+ ;;
+   *)
+   if echo " $CFLAGS " | grep " $ac_cv_cflags_warn_all " 2>&1 >/dev/null
+   then { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS does contain \$ac_cv_cflags_warn_all"; } >&5
+  (: CFLAGS does contain $ac_cv_cflags_warn_all) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+   else { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$ac_cv_cflags_warn_all\""; } >&5
+  (: CFLAGS="$CFLAGS $ac_cv_cflags_warn_all") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+                      CFLAGS="$CFLAGS $ac_cv_cflags_warn_all"
+   fi
+ ;;
+esac
+
+if test "x$GCC" = "xyes"; then
+  CFLAGS="$CFLAGS -fexceptions"
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+    # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+  enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+  USE_MAINTAINER_MODE=no
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+   if test $USE_MAINTAINER_MODE = yes; then
+  MAINTAINER_MODE_TRUE=
+  MAINTAINER_MODE_FALSE='#'
+else
+  MAINTAINER_MODE_TRUE='#'
+  MAINTAINER_MODE_FALSE=
+fi
+
+  MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+for ac_header in sys/mman.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_mman_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_MMAN_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_func in mmap
+do :
+  ac_fn_c_check_func "$LINENO" "mmap" "ac_cv_func_mmap"
+if test "x$ac_cv_func_mmap" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_MMAP 1
+_ACEOF
+
+fi
+done
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_mman_h" = xyes; then :
+  libffi_header_sys_mman_h=yes
+else
+  libffi_header_sys_mman_h=no
+fi
+
+
+ac_fn_c_check_func "$LINENO" "mmap" "ac_cv_func_mmap"
+if test "x$ac_cv_func_mmap" = xyes; then :
+  libffi_func_mmap=yes
+else
+  libffi_func_mmap=no
+fi
+
+if test "$libffi_header_sys_mman_h" != yes \
+ || test "$libffi_func_mmap" != yes; then
+   ac_cv_func_mmap_file=no
+   ac_cv_func_mmap_dev_zero=no
+   ac_cv_func_mmap_anon=no
+else
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether read-only mmap of a plain file works" >&5
+$as_echo_n "checking whether read-only mmap of a plain file works... " >&6; }
+if ${ac_cv_func_mmap_file+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # Add a system to this blacklist if
+   # mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a
+   # memory area containing the same data that you'd get if you applied
+   # read() to the same fd.  The only system known to have a problem here
+   # is VMS, where text files have record structure.
+   case "$host_os" in
+     vms* | ultrix*)
+	ac_cv_func_mmap_file=no ;;
+     *)
+	ac_cv_func_mmap_file=yes;;
+   esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_file" >&5
+$as_echo "$ac_cv_func_mmap_file" >&6; }
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mmap from /dev/zero works" >&5
+$as_echo_n "checking whether mmap from /dev/zero works... " >&6; }
+if ${ac_cv_func_mmap_dev_zero+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # Add a system to this blacklist if it has mmap() but /dev/zero
+   # does not exist, or if mmapping /dev/zero does not give anonymous
+   # zeroed pages with both the following properties:
+   # 1. If you map N consecutive pages in with one call, and then
+   #    unmap any subset of those pages, the pages that were not
+   #    explicitly unmapped remain accessible.
+   # 2. If you map two adjacent blocks of memory and then unmap them
+   #    both at once, they must both go away.
+   # Systems known to be in this category are Windows (all variants),
+   # VMS, and Darwin.
+   case "$host_os" in
+     vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
+	ac_cv_func_mmap_dev_zero=no ;;
+     *)
+	ac_cv_func_mmap_dev_zero=yes;;
+   esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_dev_zero" >&5
+$as_echo "$ac_cv_func_mmap_dev_zero" >&6; }
+
+   # Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for.
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MAP_ANON(YMOUS)" >&5
+$as_echo_n "checking for MAP_ANON(YMOUS)... " >&6; }
+if ${ac_cv_decl_map_anon+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+int
+main ()
+{
+int n = MAP_ANONYMOUS;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_decl_map_anon=yes
+else
+  ac_cv_decl_map_anon=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_decl_map_anon" >&5
+$as_echo "$ac_cv_decl_map_anon" >&6; }
+
+   if test $ac_cv_decl_map_anon = no; then
+     ac_cv_func_mmap_anon=no
+   else
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mmap with MAP_ANON(YMOUS) works" >&5
+$as_echo_n "checking whether mmap with MAP_ANON(YMOUS) works... " >&6; }
+if ${ac_cv_func_mmap_anon+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # Add a system to this blacklist if it has mmap() and MAP_ANON or
+   # MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
+   # doesn't give anonymous zeroed pages with the same properties listed
+   # above for use of /dev/zero.
+   # Systems known to be in this category are Windows, VMS, and SCO Unix.
+   case "$host_os" in
+     vms* | cygwin* | pe | mingw* | sco* | udk* )
+	ac_cv_func_mmap_anon=no ;;
+     *)
+	ac_cv_func_mmap_anon=yes;;
+   esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_anon" >&5
+$as_echo "$ac_cv_func_mmap_anon" >&6; }
+   fi
+fi
+
+if test $ac_cv_func_mmap_file = yes; then
+
+$as_echo "#define HAVE_MMAP_FILE 1" >>confdefs.h
+
+fi
+if test $ac_cv_func_mmap_dev_zero = yes; then
+
+$as_echo "#define HAVE_MMAP_DEV_ZERO 1" >>confdefs.h
+
+fi
+if test $ac_cv_func_mmap_anon = yes; then
+
+$as_echo "#define HAVE_MMAP_ANON 1" >>confdefs.h
+
+fi
+
+
+ if test -d $srcdir/testsuite; then
+  TESTSUBDIR_TRUE=
+  TESTSUBDIR_FALSE='#'
+else
+  TESTSUBDIR_TRUE='#'
+  TESTSUBDIR_FALSE=
+fi
+
+
+TARGETDIR="unknown"
+case "$host" in
+  alpha*-*-*)
+	TARGET=ALPHA; TARGETDIR=alpha;
+	# Support 128-bit long double, changeable via command-line switch.
+	HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
+	;;
+
+  arm*-*-*)
+	TARGET=ARM; TARGETDIR=arm
+	;;
+
+  amd64-*-freebsd* | amd64-*-openbsd*)
+	TARGET=X86_64; TARGETDIR=x86
+  	;;
+
+  amd64-*-freebsd*)
+	TARGET=X86_64; TARGETDIR=x86
+	;;
+
+  avr32*-*-*)
+	TARGET=AVR32; TARGETDIR=avr32
+	;;
+
+  cris-*-*)
+	TARGET=LIBFFI_CRIS; TARGETDIR=cris
+	;;
+
+  frv-*-*)
+	TARGET=FRV; TARGETDIR=frv
+	;;
+
+  hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)
+	TARGET=PA_LINUX; TARGETDIR=pa
+	;;
+  hppa*64-*-hpux*)
+	TARGET=PA64_HPUX; TARGETDIR=pa
+	;;
+  hppa*-*-hpux*)
+	TARGET=PA_HPUX; TARGETDIR=pa
+	;;
+
+  i?86-*-freebsd* | i?86-*-openbsd*)
+	TARGET=X86_FREEBSD; TARGETDIR=x86
+	;;
+  i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2* | i?86-*-interix*)
+	TARGET=X86_WIN32; TARGETDIR=x86
+	# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
+	# We must also check with_cross_host to decide if this is a native
+	# or cross-build and select where to install dlls appropriately.
+	if test -n "$with_cross_host" &&
+	   test x"$with_cross_host" != x"no"; then
+	  AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
+	else
+	  AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
+	fi
+	;;
+  i?86-*-darwin*)
+	TARGET=X86_DARWIN; TARGETDIR=x86
+	;;
+  i?86-*-solaris2.1[0-9]*)
+	TARGET=X86_64; TARGETDIR=x86
+	;;
+  i?86-*-*)
+	TARGET=X86; TARGETDIR=x86
+	;;
+
+  ia64*-*-*)
+	TARGET=IA64; TARGETDIR=ia64
+	;;
+
+  m32r*-*-*)
+	TARGET=M32R; TARGETDIR=m32r
+	;;
+
+  m68k-*-*)
+	TARGET=M68K; TARGETDIR=m68k
+	;;
+
+  mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
+	TARGET=MIPS; TARGETDIR=mips
+	;;
+  mips*-*-linux* | mips*-*-openbsd*)
+	# Support 128-bit long double for NewABI.
+	HAVE_LONG_DOUBLE='defined(__mips64)'
+	TARGET=MIPS; TARGETDIR=mips
+	;;
+
+  powerpc*-*-linux* | powerpc-*-sysv*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+  powerpc-*-beos*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+  powerpc-*-darwin* | powerpc64-*-darwin*)
+	TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
+	;;
+  powerpc-*-aix* | rs6000-*-aix*)
+	TARGET=POWERPC_AIX; TARGETDIR=powerpc
+	;;
+  powerpc-*-freebsd* | powerpc-*-openbsd*)
+	TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
+	;;
+  powerpc64-*-freebsd*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+  powerpc*-*-rtems*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+
+  s390-*-* | s390x-*-*)
+	TARGET=S390; TARGETDIR=s390
+	;;
+
+  sh-*-* | sh[34]*-*-*)
+	TARGET=SH; TARGETDIR=sh
+	;;
+  sh64-*-* | sh5*-*-*)
+	TARGET=SH64; TARGETDIR=sh64
+	;;
+
+  sparc*-*-*)
+	TARGET=SPARC; TARGETDIR=sparc
+	;;
+
+  x86_64-*-darwin*)
+	TARGET=X86_DARWIN; TARGETDIR=x86
+	;;
+
+  x86_64-*-cygwin* | x86_64-*-mingw*)
+	TARGET=X86_WIN64; TARGETDIR=x86
+	;;
+
+  x86_64-*-*)
+	TARGET=X86_64; TARGETDIR=x86
+	;;
+esac
+
+
+
+
+if test $TARGETDIR = unknown; then
+  as_fn_error $? "\"libffi has not been ported to $host.\"" "$LINENO" 5
+fi
+
+ if test x$TARGET = xMIPS; then
+  MIPS_TRUE=
+  MIPS_FALSE='#'
+else
+  MIPS_TRUE='#'
+  MIPS_FALSE=
+fi
+
+ if test x$TARGET = xSPARC; then
+  SPARC_TRUE=
+  SPARC_FALSE='#'
+else
+  SPARC_TRUE='#'
+  SPARC_FALSE=
+fi
+
+ if test x$TARGET = xX86; then
+  X86_TRUE=
+  X86_FALSE='#'
+else
+  X86_TRUE='#'
+  X86_FALSE=
+fi
+
+ if test x$TARGET = xX86_FREEBSD; then
+  X86_FREEBSD_TRUE=
+  X86_FREEBSD_FALSE='#'
+else
+  X86_FREEBSD_TRUE='#'
+  X86_FREEBSD_FALSE=
+fi
+
+ if test x$TARGET = xX86_WIN32; then
+  X86_WIN32_TRUE=
+  X86_WIN32_FALSE='#'
+else
+  X86_WIN32_TRUE='#'
+  X86_WIN32_FALSE=
+fi
+
+ if test x$TARGET = xX86_WIN64; then
+  X86_WIN64_TRUE=
+  X86_WIN64_FALSE='#'
+else
+  X86_WIN64_TRUE='#'
+  X86_WIN64_FALSE=
+fi
+
+ if test x$TARGET = xX86_DARWIN; then
+  X86_DARWIN_TRUE=
+  X86_DARWIN_FALSE='#'
+else
+  X86_DARWIN_TRUE='#'
+  X86_DARWIN_FALSE=
+fi
+
+ if test x$TARGET = xALPHA; then
+  ALPHA_TRUE=
+  ALPHA_FALSE='#'
+else
+  ALPHA_TRUE='#'
+  ALPHA_FALSE=
+fi
+
+ if test x$TARGET = xIA64; then
+  IA64_TRUE=
+  IA64_FALSE='#'
+else
+  IA64_TRUE='#'
+  IA64_FALSE=
+fi
+
+ if test x$TARGET = xM32R; then
+  M32R_TRUE=
+  M32R_FALSE='#'
+else
+  M32R_TRUE='#'
+  M32R_FALSE=
+fi
+
+ if test x$TARGET = xM68K; then
+  M68K_TRUE=
+  M68K_FALSE='#'
+else
+  M68K_TRUE='#'
+  M68K_FALSE=
+fi
+
+ if test x$TARGET = xMOXIE; then
+  MOXIE_TRUE=
+  MOXIE_FALSE='#'
+else
+  MOXIE_TRUE='#'
+  MOXIE_FALSE=
+fi
+
+ if test x$TARGET = xPOWERPC; then
+  POWERPC_TRUE=
+  POWERPC_FALSE='#'
+else
+  POWERPC_TRUE='#'
+  POWERPC_FALSE=
+fi
+
+ if test x$TARGET = xPOWERPC_AIX; then
+  POWERPC_AIX_TRUE=
+  POWERPC_AIX_FALSE='#'
+else
+  POWERPC_AIX_TRUE='#'
+  POWERPC_AIX_FALSE=
+fi
+
+ if test x$TARGET = xPOWERPC_DARWIN; then
+  POWERPC_DARWIN_TRUE=
+  POWERPC_DARWIN_FALSE='#'
+else
+  POWERPC_DARWIN_TRUE='#'
+  POWERPC_DARWIN_FALSE=
+fi
+
+ if test x$TARGET = xPOWERPC_FREEBSD; then
+  POWERPC_FREEBSD_TRUE=
+  POWERPC_FREEBSD_FALSE='#'
+else
+  POWERPC_FREEBSD_TRUE='#'
+  POWERPC_FREEBSD_FALSE=
+fi
+
+ if test x$TARGET = xARM; then
+  ARM_TRUE=
+  ARM_FALSE='#'
+else
+  ARM_TRUE='#'
+  ARM_FALSE=
+fi
+
+ if test x$TARGET = xAVR32; then
+  AVR32_TRUE=
+  AVR32_FALSE='#'
+else
+  AVR32_TRUE='#'
+  AVR32_FALSE=
+fi
+
+ if test x$TARGET = xLIBFFI_CRIS; then
+  LIBFFI_CRIS_TRUE=
+  LIBFFI_CRIS_FALSE='#'
+else
+  LIBFFI_CRIS_TRUE='#'
+  LIBFFI_CRIS_FALSE=
+fi
+
+ if test x$TARGET = xFRV; then
+  FRV_TRUE=
+  FRV_FALSE='#'
+else
+  FRV_TRUE='#'
+  FRV_FALSE=
+fi
+
+ if test x$TARGET = xS390; then
+  S390_TRUE=
+  S390_FALSE='#'
+else
+  S390_TRUE='#'
+  S390_FALSE=
+fi
+
+ if test x$TARGET = xX86_64; then
+  X86_64_TRUE=
+  X86_64_FALSE='#'
+else
+  X86_64_TRUE='#'
+  X86_64_FALSE=
+fi
+
+ if test x$TARGET = xSH; then
+  SH_TRUE=
+  SH_FALSE='#'
+else
+  SH_TRUE='#'
+  SH_FALSE=
+fi
+
+ if test x$TARGET = xSH64; then
+  SH64_TRUE=
+  SH64_FALSE='#'
+else
+  SH64_TRUE='#'
+  SH64_FALSE=
+fi
+
+ if test x$TARGET = xPA_LINUX; then
+  PA_LINUX_TRUE=
+  PA_LINUX_FALSE='#'
+else
+  PA_LINUX_TRUE='#'
+  PA_LINUX_FALSE=
+fi
+
+ if test x$TARGET = xPA_HPUX; then
+  PA_HPUX_TRUE=
+  PA_HPUX_FALSE='#'
+else
+  PA_HPUX_TRUE='#'
+  PA_HPUX_FALSE=
+fi
+
+ if test x$TARGET = xPA64_HPUX; then
+  PA64_HPUX_TRUE=
+  PA64_HPUX_FALSE='#'
+else
+  PA64_HPUX_TRUE='#'
+  PA64_HPUX_FALSE=
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+for ac_func in memcpy
+do :
+  ac_fn_c_check_func "$LINENO" "memcpy" "ac_cv_func_memcpy"
+if test "x$ac_cv_func_memcpy" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_MEMCPY 1
+_ACEOF
+
+fi
+done
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments.  Useless!
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
+$as_echo_n "checking for working alloca.h... " >&6; }
+if ${ac_cv_working_alloca_h+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+			  if (p) return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_working_alloca_h=yes
+else
+  ac_cv_working_alloca_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5
+$as_echo "$ac_cv_working_alloca_h" >&6; }
+if test $ac_cv_working_alloca_h = yes; then
+
+$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5
+$as_echo_n "checking for alloca... " >&6; }
+if ${ac_cv_func_alloca_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# else
+#  ifdef HAVE_ALLOCA_H
+#   include <alloca.h>
+#  else
+#   ifdef _AIX
+ #pragma alloca
+#   else
+#    ifndef alloca /* predefined by HP cc +Olibcalls */
+void *alloca (size_t);
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+				    if (p) return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_func_alloca_works=yes
+else
+  ac_cv_func_alloca_works=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5
+$as_echo "$ac_cv_func_alloca_works" >&6; }
+
+if test $ac_cv_func_alloca_works = yes; then
+
+$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h
+
+else
+  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble.  Some versions do not even contain alloca or
+# contain a buggy version.  If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=\${LIBOBJDIR}alloca.$ac_objext
+
+$as_echo "#define C_ALLOCA 1" >>confdefs.h
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5
+$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; }
+if ${ac_cv_os_cray+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined CRAY && ! defined CRAY2
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "webecray" >/dev/null 2>&1; then :
+  ac_cv_os_cray=yes
+else
+  ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5
+$as_echo "$ac_cv_os_cray" >&6; }
+if test $ac_cv_os_cray = yes; then
+  for ac_func in _getb67 GETB67 getb67; do
+    as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+    break
+fi
+
+  done
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5
+$as_echo_n "checking stack direction for C alloca... " >&6; }
+if ${ac_cv_c_stack_direction+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_c_stack_direction=0
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+find_stack_direction ()
+{
+  static char *addr = 0;
+  auto char dummy;
+  if (addr == 0)
+    {
+      addr = &dummy;
+      return find_stack_direction ();
+    }
+  else
+    return (&dummy > addr) ? 1 : -1;
+}
+
+int
+main ()
+{
+  return find_stack_direction () < 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_c_stack_direction=1
+else
+  ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5
+$as_echo "$ac_cv_c_stack_direction" >&6; }
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of double" >&5
+$as_echo_n "checking size of double... " >&6; }
+if ${ac_cv_sizeof_double+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (double))" "ac_cv_sizeof_double"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_double" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (double)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_double=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_double" >&5
+$as_echo "$ac_cv_sizeof_double" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_DOUBLE $ac_cv_sizeof_double
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long double" >&5
+$as_echo_n "checking size of long double... " >&6; }
+if ${ac_cv_sizeof_long_double+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long double))" "ac_cv_sizeof_long_double"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long_double" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long double)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_long_double=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_double" >&5
+$as_echo "$ac_cv_sizeof_long_double" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_DOUBLE $ac_cv_sizeof_long_double
+_ACEOF
+
+
+
+# Also AC_SUBST this variable for ffi.h.
+if test -z "$HAVE_LONG_DOUBLE"; then
+  HAVE_LONG_DOUBLE=0
+  if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
+    if test $ac_cv_sizeof_long_double != 0; then
+      HAVE_LONG_DOUBLE=1
+
+$as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h
+
+    fi
+  fi
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_bigendian=unknown
+    # See if we're dealing with a universal compiler.
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __APPLE_CC__
+	       not a universal capable compiler
+	     #endif
+	     typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+	# Check for potential -arch flags.  It is not universal unless
+	# there are at least two -arch flags with different values.
+	ac_arch=
+	ac_prev=
+	for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+	 if test -n "$ac_prev"; then
+	   case $ac_word in
+	     i?86 | x86_64 | ppc | ppc64)
+	       if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+		 ac_arch=$ac_word
+	       else
+		 ac_cv_c_bigendian=universal
+		 break
+	       fi
+	       ;;
+	   esac
+	   ac_prev=
+	 elif test "x$ac_word" = "x-arch"; then
+	   ac_prev=arch
+	 fi
+       done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if sys/param.h defines the BYTE_ORDER macro.
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+	     #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+		     && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+		     && LITTLE_ENDIAN)
+	      bogus endian macros
+	     #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+		#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+		 not big endian
+		#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+	      bogus endian macros
+	     #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to _BIG_ENDIAN or not.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+		 not big endian
+		#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # Compile a test program.
+      if test "$cross_compiling" = yes; then :
+  # Try to guess by grepping values from an object file.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+short int ascii_mm[] =
+		  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+		short int ascii_ii[] =
+		  { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+		int use_ascii (int i) {
+		  return ascii_mm[i] + ascii_ii[i];
+		}
+		short int ebcdic_ii[] =
+		  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+		short int ebcdic_mm[] =
+		  { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+		int use_ebcdic (int i) {
+		  return ebcdic_mm[i] + ebcdic_ii[i];
+		}
+		extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+	      ac_cv_c_bigendian=yes
+	    fi
+	    if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+	      if test "$ac_cv_c_bigendian" = unknown; then
+		ac_cv_c_bigendian=no
+	      else
+		# finding both strings is unlikely to happen, but who knows?
+		ac_cv_c_bigendian=unknown
+	      fi
+	    fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+
+	     /* Are we little or big endian?  From Harbison&Steele.  */
+	     union
+	     {
+	       long int l;
+	       char c[sizeof (long int)];
+	     } u;
+	     u.l = 1;
+	     return u.c[sizeof (long int) - 1] == 1;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_c_bigendian=no
+else
+  ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+    fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+   yes)
+     $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+   no)
+      ;; #(
+   universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+     ;; #(
+   *)
+     as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler .cfi pseudo-op support" >&5
+$as_echo_n "checking assembler .cfi pseudo-op support... " >&6; }
+if ${libffi_cv_as_cfi_pseudo_op+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    libffi_cv_as_cfi_pseudo_op=unknown
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+asm (".cfi_startproc\n\t.cfi_endproc");
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  libffi_cv_as_cfi_pseudo_op=yes
+else
+  libffi_cv_as_cfi_pseudo_op=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_as_cfi_pseudo_op" >&5
+$as_echo "$libffi_cv_as_cfi_pseudo_op" >&6; }
+if test "x$libffi_cv_as_cfi_pseudo_op" = xyes; then
+
+$as_echo "#define HAVE_AS_CFI_PSEUDO_OP 1" >>confdefs.h
+
+fi
+
+if test x$TARGET = xSPARC; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler and linker support unaligned pc related relocs" >&5
+$as_echo_n "checking assembler and linker support unaligned pc related relocs... " >&6; }
+if ${libffi_cv_as_sparc_ua_pcrel+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	save_CFLAGS="$CFLAGS"
+	save_LDFLAGS="$LDFLAGS"
+	CFLAGS="$CFLAGS -fpic"
+	LDFLAGS="$LDFLAGS -shared"
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  libffi_cv_as_sparc_ua_pcrel=yes
+else
+  libffi_cv_as_sparc_ua_pcrel=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	CFLAGS="$save_CFLAGS"
+	LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_as_sparc_ua_pcrel" >&5
+$as_echo "$libffi_cv_as_sparc_ua_pcrel" >&6; }
+    if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then
+
+$as_echo "#define HAVE_AS_SPARC_UA_PCREL 1" >>confdefs.h
+
+    fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler .register pseudo-op support" >&5
+$as_echo_n "checking assembler .register pseudo-op support... " >&6; }
+if ${libffi_cv_as_register_pseudo_op+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+       libffi_cv_as_register_pseudo_op=unknown
+       # Check if we have .register
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+asm (".register %g2, #scratch");
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  libffi_cv_as_register_pseudo_op=yes
+else
+  libffi_cv_as_register_pseudo_op=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_as_register_pseudo_op" >&5
+$as_echo "$libffi_cv_as_register_pseudo_op" >&6; }
+    if test "x$libffi_cv_as_register_pseudo_op" = xyes; then
+
+$as_echo "#define HAVE_AS_REGISTER_PSEUDO_OP 1" >>confdefs.h
+
+    fi
+fi
+
+if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler supports pc related relocs" >&5
+$as_echo_n "checking assembler supports pc related relocs... " >&6; }
+if ${libffi_cv_as_x86_pcrel+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	libffi_cv_as_x86_pcrel=no
+	echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s
+	if $CC $CFLAGS -c conftest.s > /dev/null; then
+	   libffi_cv_as_x86_pcrel=yes
+	fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_as_x86_pcrel" >&5
+$as_echo "$libffi_cv_as_x86_pcrel" >&6; }
+    if test "x$libffi_cv_as_x86_pcrel" = xyes; then
+
+$as_echo "#define HAVE_AS_X86_PCREL 1" >>confdefs.h
+
+    fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler .ascii pseudo-op support" >&5
+$as_echo_n "checking assembler .ascii pseudo-op support... " >&6; }
+if ${libffi_cv_as_ascii_pseudo_op+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+       libffi_cv_as_ascii_pseudo_op=unknown
+       # Check if we have .ascii
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+asm (".ascii \\"string\\"");
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  libffi_cv_as_ascii_pseudo_op=yes
+else
+  libffi_cv_as_ascii_pseudo_op=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_as_ascii_pseudo_op" >&5
+$as_echo "$libffi_cv_as_ascii_pseudo_op" >&6; }
+    if test "x$libffi_cv_as_ascii_pseudo_op" = xyes; then
+
+$as_echo "#define HAVE_AS_ASCII_PSEUDO_OP 1" >>confdefs.h
+
+    fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler .string pseudo-op support" >&5
+$as_echo_n "checking assembler .string pseudo-op support... " >&6; }
+if ${libffi_cv_as_string_pseudo_op+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+       libffi_cv_as_string_pseudo_op=unknown
+       # Check if we have .string
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+asm (".string \\"string\\"");
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  libffi_cv_as_string_pseudo_op=yes
+else
+  libffi_cv_as_string_pseudo_op=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_as_string_pseudo_op" >&5
+$as_echo "$libffi_cv_as_string_pseudo_op" >&6; }
+    if test "x$libffi_cv_as_string_pseudo_op" = xyes; then
+
+$as_echo "#define HAVE_AS_STRING_PSEUDO_OP 1" >>confdefs.h
+
+    fi
+fi
+
+if test x$TARGET = xX86_WIN64; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ prefix in compiled symbols" >&5
+$as_echo_n "checking for _ prefix in compiled symbols... " >&6; }
+if ${lt_cv_sys_symbol_underscore+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_sys_symbol_underscore=no
+  cat > conftest.$ac_ext <<_LT_EOF
+void nm_test_func(){}
+int main(){nm_test_func;return 0;}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    # Now try to grab the symbols.
+    ac_nlist=conftest.nm
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$ac_nlist"; then
+      # See whether the symbols have a leading underscore.
+      if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
+        lt_cv_sys_symbol_underscore=yes
+      else
+        if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
+	  :
+        else
+	  echo "configure: cannot find nm_test_func in $ac_nlist" >&5
+        fi
+      fi
+    else
+      echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "configure: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  rm -rf conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_symbol_underscore" >&5
+$as_echo "$lt_cv_sys_symbol_underscore" >&6; }
+  sys_symbol_underscore=$lt_cv_sys_symbol_underscore
+
+
+    if test "x$sys_symbol_underscore" = xyes; then
+
+$as_echo "#define SYMBOL_UNDERSCORE 1" >>confdefs.h
+
+    fi
+fi
+
+
+FFI_EXEC_TRAMPOLINE_TABLE=0
+case "$target" in
+     *arm*-apple-darwin*)
+       FFI_EXEC_TRAMPOLINE_TABLE=1
+
+$as_echo "#define FFI_EXEC_TRAMPOLINE_TABLE 1" >>confdefs.h
+
+     ;;
+     *-apple-darwin10* | *-*-freebsd* | *-*-openbsd* | *-pc-solaris*)
+
+$as_echo "#define FFI_MMAP_EXEC_WRIT 1" >>confdefs.h
+
+     ;;
+esac
+ if test x$FFI_EXEC_TRAMPOLINE_TABLE = x1; then
+  FFI_EXEC_TRAMPOLINE_TABLE_TRUE=
+  FFI_EXEC_TRAMPOLINE_TABLE_FALSE='#'
+else
+  FFI_EXEC_TRAMPOLINE_TABLE_TRUE='#'
+  FFI_EXEC_TRAMPOLINE_TABLE_FALSE=
+fi
+
+
+
+if test x$TARGET = xX86_64; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler supports unwind section type" >&5
+$as_echo_n "checking assembler supports unwind section type... " >&6; }
+if ${libffi_cv_as_x86_64_unwind_section_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	libffi_cv_as_x86_64_unwind_section_type=yes
+	echo '.section .eh_frame,"a", at unwind' > conftest.s
+	if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
+	    libffi_cv_as_x86_64_unwind_section_type=no
+	fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_as_x86_64_unwind_section_type" >&5
+$as_echo "$libffi_cv_as_x86_64_unwind_section_type" >&6; }
+    if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then
+
+$as_echo "#define HAVE_AS_X86_64_UNWIND_SECTION_TYPE 1" >>confdefs.h
+
+    fi
+fi
+
+if test "x$GCC" = "xyes"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether .eh_frame section should be read-only" >&5
+$as_echo_n "checking whether .eh_frame section should be read-only... " >&6; }
+if ${libffi_cv_ro_eh_frame+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  	libffi_cv_ro_eh_frame=no
+  	echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
+  	if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
+  	    if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
+  		libffi_cv_ro_eh_frame=yes
+  	    elif grep '.section.*eh_frame.*#alloc' conftest.c \
+  		 | grep -v '#write' > /dev/null; then
+  		libffi_cv_ro_eh_frame=yes
+  	    fi
+  	fi
+  	rm -f conftest.*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_ro_eh_frame" >&5
+$as_echo "$libffi_cv_ro_eh_frame" >&6; }
+  if test "x$libffi_cv_ro_eh_frame" = xyes; then
+
+$as_echo "#define HAVE_RO_EH_FRAME 1" >>confdefs.h
+
+
+$as_echo "#define EH_FRAME_FLAGS \"a\"" >>confdefs.h
+
+  else
+
+$as_echo "#define EH_FRAME_FLAGS \"aw\"" >>confdefs.h
+
+  fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__((visibility(\"hidden\")))" >&5
+$as_echo_n "checking for __attribute__((visibility(\"hidden\")))... " >&6; }
+if ${libffi_cv_hidden_visibility_attribute+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  	echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1  ; }' > conftest.c
+  	libffi_cv_hidden_visibility_attribute=no
+  	if { ac_try='${CC-cc} -Werror -S conftest.c -o conftest.s 1>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+  	    if grep '\.hidden.*foo' conftest.s >/dev/null; then
+  		libffi_cv_hidden_visibility_attribute=yes
+  	    fi
+  	fi
+  	rm -f conftest.*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_hidden_visibility_attribute" >&5
+$as_echo "$libffi_cv_hidden_visibility_attribute" >&6; }
+  if test $libffi_cv_hidden_visibility_attribute = yes; then
+
+$as_echo "#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1" >>confdefs.h
+
+  fi
+fi
+
+
+
+
+
+
+
+
+# Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+  enableval=$enable_debug; if test "$enable_debug" = "yes"; then
+
+$as_echo "#define FFI_DEBUG 1" >>confdefs.h
+
+  fi
+fi
+
+ if test "$enable_debug" = "yes"; then
+  FFI_DEBUG_TRUE=
+  FFI_DEBUG_FALSE='#'
+else
+  FFI_DEBUG_TRUE='#'
+  FFI_DEBUG_FALSE=
+fi
+
+
+# Check whether --enable-structs was given.
+if test "${enable_structs+set}" = set; then :
+  enableval=$enable_structs; if test "$enable_structs" = "no"; then
+
+$as_echo "#define FFI_NO_STRUCTS 1" >>confdefs.h
+
+  fi
+fi
+
+
+# Check whether --enable-raw-api was given.
+if test "${enable_raw_api+set}" = set; then :
+  enableval=$enable_raw_api; if test "$enable_raw_api" = "no"; then
+
+$as_echo "#define FFI_NO_RAW_API 1" >>confdefs.h
+
+  fi
+fi
+
+
+# Check whether --enable-purify-safety was given.
+if test "${enable_purify_safety+set}" = set; then :
+  enableval=$enable_purify_safety; if test "$enable_purify_safety" = "yes"; then
+
+$as_echo "#define USING_PURIFY 1" >>confdefs.h
+
+  fi
+fi
+
+
+# These variables are only ever used when we cross-build to X86_WIN32.
+# And we only support this with GCC, so...
+if test x"$GCC" != x"no"; then
+  if test -n "$with_cross_host" &&
+     test x"$with_cross_host" != x"no"; then
+    toolexecdir='$(exec_prefix)/$(target_alias)'
+    toolexeclibdir='$(toolexecdir)/lib'
+  else
+    toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
+    toolexeclibdir='$(libdir)'
+  fi
+  multi_os_directory=`$CC -print-multi-os-directory`
+  case $multi_os_directory in
+    .) ;; # Avoid trailing /.
+    *) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
+  esac
+
+
+fi
+
+if test "${multilib}" = "yes"; then
+  multilib_arg="--enable-multilib"
+else
+  multilib_arg=
+fi
+
+ac_config_commands="$ac_config_commands include"
+
+ac_config_commands="$ac_config_commands src"
+
+
+ac_config_links="$ac_config_links include/ffitarget.h:src/$TARGETDIR/ffitarget.h"
+
+
+ac_config_files="$ac_config_files include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile libffi.pc"
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+fi
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+  as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${TESTSUBDIR_TRUE}" && test -z "${TESTSUBDIR_FALSE}"; then
+  as_fn_error $? "conditional \"TESTSUBDIR\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MIPS_TRUE}" && test -z "${MIPS_FALSE}"; then
+  as_fn_error $? "conditional \"MIPS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SPARC_TRUE}" && test -z "${SPARC_FALSE}"; then
+  as_fn_error $? "conditional \"SPARC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${X86_TRUE}" && test -z "${X86_FALSE}"; then
+  as_fn_error $? "conditional \"X86\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${X86_FREEBSD_TRUE}" && test -z "${X86_FREEBSD_FALSE}"; then
+  as_fn_error $? "conditional \"X86_FREEBSD\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${X86_WIN32_TRUE}" && test -z "${X86_WIN32_FALSE}"; then
+  as_fn_error $? "conditional \"X86_WIN32\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${X86_WIN64_TRUE}" && test -z "${X86_WIN64_FALSE}"; then
+  as_fn_error $? "conditional \"X86_WIN64\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${X86_DARWIN_TRUE}" && test -z "${X86_DARWIN_FALSE}"; then
+  as_fn_error $? "conditional \"X86_DARWIN\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ALPHA_TRUE}" && test -z "${ALPHA_FALSE}"; then
+  as_fn_error $? "conditional \"ALPHA\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${IA64_TRUE}" && test -z "${IA64_FALSE}"; then
+  as_fn_error $? "conditional \"IA64\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${M32R_TRUE}" && test -z "${M32R_FALSE}"; then
+  as_fn_error $? "conditional \"M32R\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${M68K_TRUE}" && test -z "${M68K_FALSE}"; then
+  as_fn_error $? "conditional \"M68K\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MOXIE_TRUE}" && test -z "${MOXIE_FALSE}"; then
+  as_fn_error $? "conditional \"MOXIE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${POWERPC_TRUE}" && test -z "${POWERPC_FALSE}"; then
+  as_fn_error $? "conditional \"POWERPC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${POWERPC_AIX_TRUE}" && test -z "${POWERPC_AIX_FALSE}"; then
+  as_fn_error $? "conditional \"POWERPC_AIX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${POWERPC_DARWIN_TRUE}" && test -z "${POWERPC_DARWIN_FALSE}"; then
+  as_fn_error $? "conditional \"POWERPC_DARWIN\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${POWERPC_FREEBSD_TRUE}" && test -z "${POWERPC_FREEBSD_FALSE}"; then
+  as_fn_error $? "conditional \"POWERPC_FREEBSD\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ARM_TRUE}" && test -z "${ARM_FALSE}"; then
+  as_fn_error $? "conditional \"ARM\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${AVR32_TRUE}" && test -z "${AVR32_FALSE}"; then
+  as_fn_error $? "conditional \"AVR32\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${LIBFFI_CRIS_TRUE}" && test -z "${LIBFFI_CRIS_FALSE}"; then
+  as_fn_error $? "conditional \"LIBFFI_CRIS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${FRV_TRUE}" && test -z "${FRV_FALSE}"; then
+  as_fn_error $? "conditional \"FRV\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${S390_TRUE}" && test -z "${S390_FALSE}"; then
+  as_fn_error $? "conditional \"S390\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${X86_64_TRUE}" && test -z "${X86_64_FALSE}"; then
+  as_fn_error $? "conditional \"X86_64\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SH_TRUE}" && test -z "${SH_FALSE}"; then
+  as_fn_error $? "conditional \"SH\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${SH64_TRUE}" && test -z "${SH64_FALSE}"; then
+  as_fn_error $? "conditional \"SH64\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${PA_LINUX_TRUE}" && test -z "${PA_LINUX_FALSE}"; then
+  as_fn_error $? "conditional \"PA_LINUX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${PA_HPUX_TRUE}" && test -z "${PA_HPUX_FALSE}"; then
+  as_fn_error $? "conditional \"PA_HPUX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${PA64_HPUX_TRUE}" && test -z "${PA64_HPUX_FALSE}"; then
+  as_fn_error $? "conditional \"PA64_HPUX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+if test -z "${FFI_EXEC_TRAMPOLINE_TABLE_TRUE}" && test -z "${FFI_EXEC_TRAMPOLINE_TABLE_FALSE}"; then
+  as_fn_error $? "conditional \"FFI_EXEC_TRAMPOLINE_TABLE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${FFI_DEBUG_TRUE}" && test -z "${FFI_DEBUG_FALSE}"; then
+  as_fn_error $? "conditional \"FFI_DEBUG\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by libffi $as_me 3.0.10, which was
+generated by GNU Autoconf 2.68.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_links="$ac_config_links"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration links:
+$config_links
+
+Configuration commands:
+$config_commands
+
+Report bugs to <http://sourceware.org/libffi.html>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+libffi config.status 3.0.10
+configured by $0, generated by GNU Autoconf 2.68,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+ax_enable_builddir_srcdir="$srcdir"                    # $srcdir
+ax_enable_builddir_host="$HOST"                        # $HOST / $host
+ax_enable_builddir_version="$VERSION"                  # $VERSION
+ax_enable_builddir_package="$PACKAGE"                  # $PACKAGE
+ax_enable_builddir_auxdir="$ax_enable_builddir_auxdir" # $AUX
+ax_enable_builddir_sed="$ax_enable_builddir_sed"       # $SED
+ax_enable_builddir="$ax_enable_builddir"               # $SUB
+
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_flag_spec_ld \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'
+
+
+
+TARGETDIR="$TARGETDIR"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "fficonfig.h") CONFIG_HEADERS="$CONFIG_HEADERS fficonfig.h" ;;
+    "buildir") CONFIG_COMMANDS="$CONFIG_COMMANDS buildir" ;;
+    "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+    "include") CONFIG_COMMANDS="$CONFIG_COMMANDS include" ;;
+    "src") CONFIG_COMMANDS="$CONFIG_COMMANDS src" ;;
+    "include/ffitarget.h") CONFIG_LINKS="$CONFIG_LINKS include/ffitarget.h:src/$TARGETDIR/ffitarget.h" ;;
+    "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;;
+    "include/ffi.h") CONFIG_FILES="$CONFIG_FILES include/ffi.h" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;;
+    "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
+    "libffi.pc") CONFIG_FILES="$CONFIG_FILES libffi.pc" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS  :L $CONFIG_LINKS  :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
+  fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$_am_arg" : 'X\(//\)[^/]' \| \
+	 X"$_am_arg" : 'X\(//\)$' \| \
+	 X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+  :L)
+  #
+  # CONFIG_LINK
+  #
+
+  if test "$ac_source" = "$ac_file" && test "$srcdir" = '.'; then
+    :
+  else
+    # Prefer the file from the source tree if names are identical.
+    if test "$ac_source" = "$ac_file" || test ! -r "$ac_source"; then
+      ac_source=$srcdir/$ac_source
+    fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: linking $ac_source to $ac_file" >&5
+$as_echo "$as_me: linking $ac_source to $ac_file" >&6;}
+
+    if test ! -r "$ac_source"; then
+      as_fn_error $? "$ac_source: file not found" "$LINENO" 5
+    fi
+    rm -f "$ac_file"
+
+    # Try a relative symlink, then a hard link, then a copy.
+    case $ac_source in
+    [\\/$]* | ?:[\\/]* ) ac_rel_source=$ac_source ;;
+	*) ac_rel_source=$ac_top_build_prefix$ac_source ;;
+    esac
+    ln -s "$ac_rel_source" "$ac_file" 2>/dev/null ||
+      ln "$ac_source" "$ac_file" 2>/dev/null ||
+      cp -p "$ac_source" "$ac_file" ||
+      as_fn_error $? "cannot link or copy $ac_source to $ac_file" "$LINENO" 5
+  fi
+ ;;
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "buildir":C)   ac_top_srcdir="$ax_enable_builddir_srcdir"
+  if test ".$ax_enable_builddir" = ".." ; then
+    if test -f "$top_srcdir/Makefile" ; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: skipping top_srcdir/Makefile - left untouched" >&5
+$as_echo "$as_me: skipping top_srcdir/Makefile - left untouched" >&6;}
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: skipping top_srcdir/Makefile - not created" >&5
+$as_echo "$as_me: skipping top_srcdir/Makefile - not created" >&6;}
+    fi
+  else
+    if test -f "$ac_top_srcdir/Makefile" ; then
+      a=`grep "^VERSION " "$ac_top_srcdir/Makefile"` ; b=`grep "^VERSION " Makefile`
+      test "$a" != "$b" && rm "$ac_top_srcdir/Makefile"
+    fi
+    if test -f "$ac_top_srcdir/Makefile" ; then
+	echo "$ac_top_srcdir/Makefile : $ac_top_srcdir/Makefile.in" > $tmp/conftemp.mk
+	echo "	@ echo 'REMOVED,,,' >\$@" >> $tmp/conftemp.mk
+      eval "${MAKE-make} -f $tmp/conftemp.mk 2>/dev/null >/dev/null"
+      if grep '^REMOVED,,,' "$ac_top_srcdir/Makefile" >/dev/null
+      then rm $ac_top_srcdir/Makefile ; fi
+      cp $tmp/conftemp.mk $ac_top_srcdir/makefiles.mk~      ## DEBUGGING
+    fi
+    if test ! -f "$ac_top_srcdir/Makefile" ; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: create top_srcdir/Makefile guessed from local Makefile" >&5
+$as_echo "$as_me: create top_srcdir/Makefile guessed from local Makefile" >&6;}
+      x='`' ; cat >$tmp/conftemp.sed <<_EOF
+/^\$/n
+x
+/^\$/bS
+x
+/\\\\\$/{H;d;}
+{H;s/.*//;x;}
+bM
+:S
+x
+/\\\\\$/{h;d;}
+{h;s/.*//;x;}
+:M
+s/\\(\\n\\)	/\\1 /g
+/^	/d
+/^[	 ]*[\\#]/d
+/^VPATH *=/d
+s/^srcdir *=.*/srcdir = ./
+s/^top_srcdir *=.*/top_srcdir = ./
+/[:=]/!d
+/^\\./d
+/ = /b
+/ .= /b
+/:/!b
+s/:.*/:/
+s/ /  /g
+s/ \\([a-z][a-z-]*[a-zA-Z0-9]\\)\\([ :]\\)/ \\1 \\1-all\\2/g
+s/^\\([a-z][a-z-]*[a-zA-Z0-9]\\)\\([ :]\\)/\\1 \\1-all\\2/
+s/  / /g
+/^all all-all[ :]/i\\
+all-configured : all-all
+s/ [a-zA-Z0-9-]*-all [a-zA-Z0-9-]*-all-all//g
+/-all-all/d
+a\\
+	@ HOST="\$(HOST)\" \\\\\\
+	; test ".\$\$HOST" = "." && HOST=$x sh $ax_enable_builddir_auxdir/config.guess $x \\\\\\
+	; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\
+	; use=$x basename "\$\@" -all $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\
+	; echo "MAKE \$\$HOST : \$\$n * \$\@"; if test "\$\$n" = "0" ; then : \\\\\\
+	; BUILD=$x grep "^####.*|" Makefile |tail -1| sed -e 's/.*|//' $x ; fi \\\\\\
+	; test ".\$\$BUILD" = "." && BUILD="." \\\\\\
+	; test "\$\$use" = "\$\@" && BUILD=$x echo "\$\$BUILD" | tail -1 $x \\\\\\
+	; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
+	; (cd "\$\$i" && test ! -f configure && \$(MAKE) \$\$use) || exit; done
+/dist-all *:/a\\
+	@ HOST="\$(HOST)\" \\\\\\
+	; test ".\$\$HOST" = "." && HOST=$x sh $ax_enable_builddir_auxdir/config.guess $x \\\\\\
+	; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\
+	; found=$x echo \$\$BUILD | wc -w $x \\\\\\
+	; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).tar.*" \\\\\\
+	; if test "\$\$found" = "0" ; then : \\\\\\
+	; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\
+	; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
+	; for f in \$\$i/\$(PACKAGE)-\$(VERSION).tar.* \\\\\\
+	; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done
+/dist-[a-zA-Z0-9]*-all *:/a\\
+	@ HOST="\$(HOST)\" \\\\\\
+	; test ".\$\$HOST" = "." && HOST=$x sh ./config.guess $x \\\\\\
+	; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\
+	; found=$x echo \$\$BUILD | wc -w $x \\\\\\
+	; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).*" \\\\\\
+	; if test "\$\$found" = "0" ; then : \\\\\\
+	; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\
+	; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
+	; for f in \$\$i/\$(PACKAGE)-\$(VERSION).* \\\\\\
+	; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done
+/distclean-all *:/a\\
+	@ HOST="\$(HOST)\" \\\\\\
+	; test ".\$\$HOST" = "." && HOST=$x sh $ax_enable_builddir_auxdir/config.guess $x \\\\\\
+	; BUILD=$x grep "^#### .*|" Makefile | sed -e 's/.*|//' $x \\\\\\
+	; use=$x basename "\$\@" -all $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\
+	; echo "MAKE \$\$HOST : \$\$n * \$\@ (all local builds)" \\\\\\
+	; test ".\$\$BUILD" = "." && BUILD="." \\\\\\
+	; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
+	; echo "# rm -r \$\$i"; done ; echo "# (sleep 3)" ; sleep 3 \\\\\\
+	; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
+	; echo "\$\$i" | grep "^/" > /dev/null && continue \\\\\\
+	; echo "\$\$i" | grep "^../" > /dev/null && continue \\\\\\
+	; echo "rm -r \$\$i"; (rm -r "\$\$i") ; done ; rm Makefile
+_EOF
+      cp "$tmp/conftemp.sed" "$ac_top_srcdir/makefile.sed~"            ## DEBUGGING
+      $ax_enable_builddir_sed -f $tmp/conftemp.sed Makefile >$ac_top_srcdir/Makefile
+      if test -f "$ac_top_srcdir/Makefile.mk" ; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: extend top_srcdir/Makefile with top_srcdir/Makefile.mk" >&5
+$as_echo "$as_me: extend top_srcdir/Makefile with top_srcdir/Makefile.mk" >&6;}
+        cat $ac_top_srcdir/Makefile.mk >>$ac_top_srcdir/Makefile
+      fi ; xxxx="####"
+      echo "$xxxx CONFIGURATIONS FOR TOPLEVEL MAKEFILE: " >>$ac_top_srcdir/Makefile
+      # sanity check
+      if grep '^; echo "MAKE ' $ac_top_srcdir/Makefile >/dev/null ; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: buggy sed found - it deletes tab in \"a\" text parts" >&5
+$as_echo "$as_me: buggy sed found - it deletes tab in \"a\" text parts" >&6;}
+        $ax_enable_builddir_sed -e '/^@ HOST=/s/^/	/' -e '/^; /s/^/	/' $ac_top_srcdir/Makefile \
+          >$ac_top_srcdir/Makefile~
+        (test -s $ac_top_srcdir/Makefile~ && mv $ac_top_srcdir/Makefile~ $ac_top_srcdir/Makefile) 2>/dev/null
+      fi
+    else
+      xxxx="\\#\\#\\#\\#"
+      # echo "/^$xxxx *$ax_enable_builddir_host /d" >$tmp/conftemp.sed
+      echo "s!^$xxxx [^|]* | *$ax_enable_builddir *\$!$xxxx ...... $ax_enable_builddir!" >$tmp/conftemp.sed
+      $ax_enable_builddir_sed -f "$tmp/conftemp.sed" "$ac_top_srcdir/Makefile" >$tmp/mkfile.tmp
+        cp "$tmp/conftemp.sed" "$ac_top_srcdir/makefiles.sed~"         ## DEBUGGING
+        cp "$tmp/mkfile.tmp"   "$ac_top_srcdir/makefiles.out~"         ## DEBUGGING
+      if cmp -s "$ac_top_srcdir/Makefile" "$tmp/mkfile.tmp" 2>/dev/null ; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: keeping top_srcdir/Makefile from earlier configure" >&5
+$as_echo "$as_me: keeping top_srcdir/Makefile from earlier configure" >&6;}
+        rm "$tmp/mkfile.tmp"
+      else
+        { $as_echo "$as_me:${as_lineno-$LINENO}: reusing top_srcdir/Makefile from earlier configure" >&5
+$as_echo "$as_me: reusing top_srcdir/Makefile from earlier configure" >&6;}
+        mv "$tmp/mkfile.tmp" "$ac_top_srcdir/Makefile"
+      fi
+    fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: build in $ax_enable_builddir (HOST=$ax_enable_builddir_host)" >&5
+$as_echo "$as_me: build in $ax_enable_builddir (HOST=$ax_enable_builddir_host)" >&6;}
+    xxxx="####"
+    echo "$xxxx" "$ax_enable_builddir_host" "|$ax_enable_builddir" >>$ac_top_srcdir/Makefile
+  fi
+ ;;
+    "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named `Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$mf" : 'X\(//\)[^/]' \| \
+	 X"$mf" : 'X\(//\)$' \| \
+	 X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running `make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # When using ansi2knr, U may be empty or an underscore; expand it
+    U=`sed -n 's/^U = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$file" : 'X\(//\)[^/]' \| \
+	 X"$file" : 'X\(//\)$' \| \
+	 X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      as_dir=$dirpart/$fdir; as_fn_mkdir_p
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+ ;;
+    "libtool":C)
+
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
+#                 Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=""
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking.  This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  if test x"$xsi_shell" = xyes; then
+  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\    # positional parameters, so assign one to ordinary parameter first.\
+\    func_stripname_result=${3}\
+\    func_stripname_result=${func_stripname_result#"${1}"}\
+\    func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\    func_split_long_opt_name=${1%%=*}\
+\    func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\    func_split_short_opt_arg=${1#??}\
+\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\    case ${1} in\
+\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\      *)    func_lo2o_result=${1} ;;\
+\    esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+    func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+    func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+    func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+    eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\    func_quote_for_eval "${2}"\
+\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+ ;;
+    "include":C) test -d include || mkdir include ;;
+    "src":C)
+test -d src || mkdir src
+test -d src/$TARGETDIR || mkdir src/$TARGETDIR
+ ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/configure.ac b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/configure.ac
new file mode 100755
index 0000000..2d92d33
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/configure.ac
@@ -0,0 +1,496 @@
+dnl Process this with autoconf to create configure
+
+AC_PREREQ(2.63)
+
+AC_INIT([libffi], [3.0.10], [http://sourceware.org/libffi.html])
+AC_CONFIG_HEADERS([fficonfig.h])
+
+AC_CANONICAL_SYSTEM
+target_alias=${target_alias-$host_alias}
+
+. ${srcdir}/configure.host
+
+AX_ENABLE_BUILDDIR
+
+AM_INIT_AUTOMAKE
+
+# The same as in boehm-gc and libstdc++. Have to borrow it from there.
+# We must force CC to /not/ be precious variables; otherwise
+# the wrong, non-multilib-adjusted value will be used in multilibs.
+# As a side effect, we have to subst CFLAGS ourselves.
+# Also save and restore CFLAGS, since AC_PROG_CC will come up with
+# defaults of its own if none are provided.
+
+m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
+m4_define([_AC_ARG_VAR_PRECIOUS],[])
+save_CFLAGS=$CFLAGS
+AC_PROG_CC
+CFLAGS=$save_CFLAGS
+m4_undefine([_AC_ARG_VAR_PRECIOUS])
+m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
+
+AC_SUBST(CFLAGS)
+
+AM_PROG_AS
+AM_PROG_CC_C_O
+AC_PROG_LIBTOOL
+AC_CONFIG_MACRO_DIR([m4])
+
+AX_CC_MAXOPT
+AX_CFLAGS_WARN_ALL
+if test "x$GCC" = "xyes"; then
+  CFLAGS="$CFLAGS -fexceptions"
+fi
+
+AM_MAINTAINER_MODE
+
+AC_CHECK_HEADERS(sys/mman.h)
+AC_CHECK_FUNCS(mmap)
+AC_FUNC_MMAP_BLACKLIST
+
+dnl The -no-testsuite modules omit the test subdir.
+AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
+
+TARGETDIR="unknown"
+case "$host" in
+  alpha*-*-*)
+	TARGET=ALPHA; TARGETDIR=alpha;
+	# Support 128-bit long double, changeable via command-line switch.
+	HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
+	;;
+
+  arm*-*-*)
+	TARGET=ARM; TARGETDIR=arm
+	;;
+
+  amd64-*-freebsd* | amd64-*-openbsd*)
+	TARGET=X86_64; TARGETDIR=x86
+  	;;
+
+  amd64-*-freebsd*)
+	TARGET=X86_64; TARGETDIR=x86
+	;;
+
+  avr32*-*-*)
+	TARGET=AVR32; TARGETDIR=avr32
+	;;
+
+  cris-*-*)
+	TARGET=LIBFFI_CRIS; TARGETDIR=cris
+	;;
+
+  frv-*-*)
+	TARGET=FRV; TARGETDIR=frv
+	;;
+
+  hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)
+	TARGET=PA_LINUX; TARGETDIR=pa
+	;;
+  hppa*64-*-hpux*)
+	TARGET=PA64_HPUX; TARGETDIR=pa
+	;;
+  hppa*-*-hpux*)
+	TARGET=PA_HPUX; TARGETDIR=pa
+	;;
+
+  i?86-*-freebsd* | i?86-*-openbsd*)
+	TARGET=X86_FREEBSD; TARGETDIR=x86
+	;;
+  i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2* | i?86-*-interix*)
+	TARGET=X86_WIN32; TARGETDIR=x86
+	# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
+	# We must also check with_cross_host to decide if this is a native
+	# or cross-build and select where to install dlls appropriately.
+	if test -n "$with_cross_host" &&
+	   test x"$with_cross_host" != x"no"; then
+	  AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
+	else
+	  AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
+	fi
+	;;
+  i?86-*-darwin*)
+	TARGET=X86_DARWIN; TARGETDIR=x86
+	;;
+  i?86-*-solaris2.1[[0-9]]*)
+	TARGET=X86_64; TARGETDIR=x86
+	;;
+  i?86-*-*)
+	TARGET=X86; TARGETDIR=x86
+	;;
+
+  ia64*-*-*)
+	TARGET=IA64; TARGETDIR=ia64
+	;;
+
+  m32r*-*-*)
+	TARGET=M32R; TARGETDIR=m32r
+	;;
+
+  m68k-*-*)
+	TARGET=M68K; TARGETDIR=m68k
+	;;
+
+  mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
+	TARGET=MIPS; TARGETDIR=mips
+	;;
+  mips*-*-linux* | mips*-*-openbsd*)
+	# Support 128-bit long double for NewABI.
+	HAVE_LONG_DOUBLE='defined(__mips64)'
+	TARGET=MIPS; TARGETDIR=mips
+	;;
+
+  powerpc*-*-linux* | powerpc-*-sysv*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+  powerpc-*-beos*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+  powerpc-*-darwin* | powerpc64-*-darwin*)
+	TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
+	;;
+  powerpc-*-aix* | rs6000-*-aix*)
+	TARGET=POWERPC_AIX; TARGETDIR=powerpc
+	;;
+  powerpc-*-freebsd* | powerpc-*-openbsd*)
+	TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
+	;;
+  powerpc64-*-freebsd*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+  powerpc*-*-rtems*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+
+  s390-*-* | s390x-*-*)
+	TARGET=S390; TARGETDIR=s390
+	;;
+
+  sh-*-* | sh[[34]]*-*-*)
+	TARGET=SH; TARGETDIR=sh
+	;;
+  sh64-*-* | sh5*-*-*)
+	TARGET=SH64; TARGETDIR=sh64
+	;;
+
+  sparc*-*-*)
+	TARGET=SPARC; TARGETDIR=sparc
+	;;
+
+  x86_64-*-darwin*)
+	TARGET=X86_DARWIN; TARGETDIR=x86
+	;;
+
+  x86_64-*-cygwin* | x86_64-*-mingw*)
+	TARGET=X86_WIN64; TARGETDIR=x86
+	;;
+
+  x86_64-*-*)
+	TARGET=X86_64; TARGETDIR=x86
+	;;
+esac
+
+AC_SUBST(AM_RUNTESTFLAGS)
+AC_SUBST(AM_LTLDFLAGS)
+
+if test $TARGETDIR = unknown; then
+  AC_MSG_ERROR(["libffi has not been ported to $host."])
+fi
+
+AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS)
+AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC)
+AM_CONDITIONAL(X86, test x$TARGET = xX86)
+AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD)
+AM_CONDITIONAL(X86_WIN32, test x$TARGET = xX86_WIN32)
+AM_CONDITIONAL(X86_WIN64, test x$TARGET = xX86_WIN64)
+AM_CONDITIONAL(X86_DARWIN, test x$TARGET = xX86_DARWIN)
+AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
+AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
+AM_CONDITIONAL(M32R, test x$TARGET = xM32R)
+AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
+AM_CONDITIONAL(MOXIE, test x$TARGET = xMOXIE)
+AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
+AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
+AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
+AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
+AM_CONDITIONAL(ARM, test x$TARGET = xARM)
+AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32)
+AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
+AM_CONDITIONAL(FRV, test x$TARGET = xFRV)
+AM_CONDITIONAL(S390, test x$TARGET = xS390)
+AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
+AM_CONDITIONAL(SH, test x$TARGET = xSH)
+AM_CONDITIONAL(SH64, test x$TARGET = xSH64)
+AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX)
+AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX)
+AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX)
+
+AC_HEADER_STDC
+AC_CHECK_FUNCS(memcpy)
+AC_FUNC_ALLOCA
+
+AC_CHECK_SIZEOF(double)
+AC_CHECK_SIZEOF(long double)
+
+# Also AC_SUBST this variable for ffi.h.
+if test -z "$HAVE_LONG_DOUBLE"; then
+  HAVE_LONG_DOUBLE=0
+  if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
+    if test $ac_cv_sizeof_long_double != 0; then
+      HAVE_LONG_DOUBLE=1
+      AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double])
+    fi
+  fi
+fi
+AC_SUBST(HAVE_LONG_DOUBLE)
+
+AC_C_BIGENDIAN
+
+AC_CACHE_CHECK([assembler .cfi pseudo-op support],
+    libffi_cv_as_cfi_pseudo_op, [
+    libffi_cv_as_cfi_pseudo_op=unknown
+    AC_TRY_COMPILE([asm (".cfi_startproc\n\t.cfi_endproc");],,
+		   [libffi_cv_as_cfi_pseudo_op=yes],
+		   [libffi_cv_as_cfi_pseudo_op=no])
+])
+if test "x$libffi_cv_as_cfi_pseudo_op" = xyes; then
+    AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1,
+	      [Define if your assembler supports .cfi_* directives.])
+fi
+
+if test x$TARGET = xSPARC; then
+    AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
+	libffi_cv_as_sparc_ua_pcrel, [
+	save_CFLAGS="$CFLAGS"
+	save_LDFLAGS="$LDFLAGS"
+	CFLAGS="$CFLAGS -fpic"
+	LDFLAGS="$LDFLAGS -shared"
+	AC_TRY_LINK([asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");],,
+		    [libffi_cv_as_sparc_ua_pcrel=yes],
+		    [libffi_cv_as_sparc_ua_pcrel=no])
+	CFLAGS="$save_CFLAGS"
+	LDFLAGS="$save_LDFLAGS"])
+    if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then
+	AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
+		  [Define if your assembler and linker support unaligned PC relative relocs.])
+    fi
+
+    AC_CACHE_CHECK([assembler .register pseudo-op support],
+       libffi_cv_as_register_pseudo_op, [
+       libffi_cv_as_register_pseudo_op=unknown
+       # Check if we have .register
+       AC_TRY_COMPILE([asm (".register %g2, #scratch");],,
+		       [libffi_cv_as_register_pseudo_op=yes],
+		       [libffi_cv_as_register_pseudo_op=no])
+    ])
+    if test "x$libffi_cv_as_register_pseudo_op" = xyes; then
+       AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
+	       [Define if your assembler supports .register.])
+    fi
+fi
+
+if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64; then
+    AC_CACHE_CHECK([assembler supports pc related relocs],
+	libffi_cv_as_x86_pcrel, [
+	libffi_cv_as_x86_pcrel=no
+	echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s
+	if $CC $CFLAGS -c conftest.s > /dev/null; then
+	   libffi_cv_as_x86_pcrel=yes
+	fi
+	])
+    if test "x$libffi_cv_as_x86_pcrel" = xyes; then
+	AC_DEFINE(HAVE_AS_X86_PCREL, 1,
+		  [Define if your assembler supports PC relative relocs.])
+    fi
+
+    AC_CACHE_CHECK([assembler .ascii pseudo-op support],
+       libffi_cv_as_ascii_pseudo_op, [
+       libffi_cv_as_ascii_pseudo_op=unknown
+       # Check if we have .ascii
+       AC_TRY_COMPILE([asm (".ascii \\"string\\"");],,
+		       [libffi_cv_as_ascii_pseudo_op=yes],
+		       [libffi_cv_as_ascii_pseudo_op=no])
+    ])
+    if test "x$libffi_cv_as_ascii_pseudo_op" = xyes; then
+       AC_DEFINE(HAVE_AS_ASCII_PSEUDO_OP, 1,
+	       [Define if your assembler supports .ascii.])
+    fi
+
+    AC_CACHE_CHECK([assembler .string pseudo-op support],
+       libffi_cv_as_string_pseudo_op, [
+       libffi_cv_as_string_pseudo_op=unknown
+       # Check if we have .string
+       AC_TRY_COMPILE([asm (".string \\"string\\"");],,
+		       [libffi_cv_as_string_pseudo_op=yes],
+		       [libffi_cv_as_string_pseudo_op=no])
+    ])
+    if test "x$libffi_cv_as_string_pseudo_op" = xyes; then
+       AC_DEFINE(HAVE_AS_STRING_PSEUDO_OP, 1,
+	       [Define if your assembler supports .string.])
+    fi
+fi
+
+if test x$TARGET = xX86_WIN64; then
+    LT_SYS_SYMBOL_USCORE
+    if test "x$sys_symbol_underscore" = xyes; then
+        AC_DEFINE(SYMBOL_UNDERSCORE, 1, [Define if symbols are underscored.])
+    fi
+fi
+
+
+FFI_EXEC_TRAMPOLINE_TABLE=0
+case "$target" in
+     *arm*-apple-darwin*)
+       FFI_EXEC_TRAMPOLINE_TABLE=1
+       AC_DEFINE(FFI_EXEC_TRAMPOLINE_TABLE, 1,
+                 [Cannot use PROT_EXEC on this target, so, we revert to
+                   alternative means])
+     ;;
+     *-apple-darwin10* | *-*-freebsd* | *-*-openbsd* | *-pc-solaris*)
+       AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
+                 [Cannot use malloc on this target, so, we revert to
+                   alternative means])
+     ;;
+esac
+AM_CONDITIONAL(FFI_EXEC_TRAMPOLINE_TABLE, test x$FFI_EXEC_TRAMPOLINE_TABLE = x1)
+AC_SUBST(FFI_EXEC_TRAMPOLINE_TABLE)
+
+if test x$TARGET = xX86_64; then
+    AC_CACHE_CHECK([assembler supports unwind section type],
+	libffi_cv_as_x86_64_unwind_section_type, [
+	libffi_cv_as_x86_64_unwind_section_type=yes
+	echo '.section .eh_frame,"a", at unwind' > conftest.s
+	if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
+	    libffi_cv_as_x86_64_unwind_section_type=no
+	fi
+	])
+    if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then
+	AC_DEFINE(HAVE_AS_X86_64_UNWIND_SECTION_TYPE, 1,
+		  [Define if your assembler supports unwind section type.])
+    fi
+fi
+
+if test "x$GCC" = "xyes"; then
+  AC_CACHE_CHECK([whether .eh_frame section should be read-only],
+      libffi_cv_ro_eh_frame, [
+  	libffi_cv_ro_eh_frame=no
+  	echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
+  	if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
+  	    if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
+  		libffi_cv_ro_eh_frame=yes
+  	    elif grep '.section.*eh_frame.*#alloc' conftest.c \
+  		 | grep -v '#write' > /dev/null; then
+  		libffi_cv_ro_eh_frame=yes
+  	    fi
+  	fi
+  	rm -f conftest.*
+      ])
+  if test "x$libffi_cv_ro_eh_frame" = xyes; then
+      AC_DEFINE(HAVE_RO_EH_FRAME, 1,
+  	      [Define if .eh_frame sections should be read-only.])
+      AC_DEFINE(EH_FRAME_FLAGS, "a",
+  	      [Define to the flags needed for the .section .eh_frame directive.  ])
+  else
+      AC_DEFINE(EH_FRAME_FLAGS, "aw",
+  	      [Define to the flags needed for the .section .eh_frame directive.  ])
+  fi
+
+  AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
+      libffi_cv_hidden_visibility_attribute, [
+  	echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1  ; }' > conftest.c
+  	libffi_cv_hidden_visibility_attribute=no
+  	if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
+  	    if grep '\.hidden.*foo' conftest.s >/dev/null; then
+  		libffi_cv_hidden_visibility_attribute=yes
+  	    fi
+  	fi
+  	rm -f conftest.*
+      ])
+  if test $libffi_cv_hidden_visibility_attribute = yes; then
+      AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,
+  	      [Define if __attribute__((visibility("hidden"))) is supported.])
+  fi
+fi
+
+AH_BOTTOM([
+#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name) .hidden name
+#else
+#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
+#endif
+#else
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name)
+#else
+#define FFI_HIDDEN
+#endif
+#endif
+])
+
+AC_SUBST(TARGET)
+AC_SUBST(TARGETDIR)
+
+AC_SUBST(SHELL)
+
+AC_ARG_ENABLE(debug,
+[  --enable-debug          debugging mode],
+  if test "$enable_debug" = "yes"; then
+    AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.])
+  fi)
+AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")
+
+AC_ARG_ENABLE(structs,
+[  --disable-structs       omit code for struct support],
+  if test "$enable_structs" = "no"; then
+    AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this is you do not want support for aggregate types.])
+  fi)
+
+AC_ARG_ENABLE(raw-api,
+[  --disable-raw-api       make the raw api unavailable],
+  if test "$enable_raw_api" = "no"; then
+    AC_DEFINE(FFI_NO_RAW_API, 1, [Define this is you do not want support for the raw API.])
+  fi)
+
+AC_ARG_ENABLE(purify-safety,
+[  --enable-purify-safety  purify-safe mode],
+  if test "$enable_purify_safety" = "yes"; then
+    AC_DEFINE(USING_PURIFY, 1, [Define this if you are using Purify and want to suppress spurious messages.])
+  fi)
+
+# These variables are only ever used when we cross-build to X86_WIN32.
+# And we only support this with GCC, so...
+if test x"$GCC" != x"no"; then
+  if test -n "$with_cross_host" &&
+     test x"$with_cross_host" != x"no"; then
+    toolexecdir='$(exec_prefix)/$(target_alias)'
+    toolexeclibdir='$(toolexecdir)/lib'
+  else
+    toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
+    toolexeclibdir='$(libdir)'
+  fi
+  multi_os_directory=`$CC -print-multi-os-directory`
+  case $multi_os_directory in
+    .) ;; # Avoid trailing /.
+    *) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
+  esac
+  AC_SUBST(toolexecdir)
+  AC_SUBST(toolexeclibdir)
+fi
+
+if test "${multilib}" = "yes"; then
+  multilib_arg="--enable-multilib"
+else
+  multilib_arg=
+fi
+
+AC_CONFIG_COMMANDS(include, [test -d include || mkdir include])
+AC_CONFIG_COMMANDS(src, [
+test -d src || mkdir src
+test -d src/$TARGETDIR || mkdir src/$TARGETDIR
+], [TARGETDIR="$TARGETDIR"])
+
+AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h)
+
+AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile libffi.pc)
+
+AC_OUTPUT
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/configure.host b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/configure.host
new file mode 100755
index 0000000..f52457b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/configure.host
@@ -0,0 +1,11 @@
+# configure.host
+#
+# This shell script handles all host based configuration for libffi.
+# 
+
+# THIS TABLE IS SORTED.  KEEP IT THAT WAY.
+case "${host}" in
+  frv*-elf)
+    LDFLAGS=`echo $LDFLAGS | sed "s/\-B[^ ]*libgloss\/frv\///"`\ -B`pwd`/../libgloss/frv/
+    ;;
+esac
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/depcomp b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/depcomp
new file mode 100755
index 0000000..df8eea7
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/depcomp
@@ -0,0 +1,630 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
+# Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva at dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+   # This is just like msvisualcpp but w/o cygpath translation.
+   # Just convert the backslash-escaped backslashes to single forward
+   # slashes to satisfy depend.m4
+   cygpath_u="sed s,\\\\\\\\,/,g"
+   depmode=msvisualcpp
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> "$depfile"
+    echo >> "$depfile"
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
+    "$@" -Wc,-M
+  else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
+    "$@" -M
+  fi
+  stat=$?
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+    # That's a tab and a space in the [].
+    sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add `dependent.h:' lines.
+    sed -ne '2,${
+	       s/^ *//
+	       s/ \\*$//
+	       s/$/:/
+	       p
+	     }' "$tmpdepfile" >> "$depfile"
+  else
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mechanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+      exit $stat
+   fi
+
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" && break
+   done
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no eat=no
+  for arg
+  do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    if test $eat = yes; then
+      eat=no
+      continue
+    fi
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -arch)
+      eat=yes ;;
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix=`echo "$object" | sed 's/^.*\././'`
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+	set fnord "$@"
+	shift
+	shift
+	;;
+    *)
+	set fnord "$@" "$arg"
+	shift
+	shift
+	;;
+    esac
+  done
+  "$@" -E 2>/dev/null |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
+  echo "	" >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvcmsys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/fficonfig.h.in b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/fficonfig.h.in
new file mode 100755
index 0000000..6c92c56
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/fficonfig.h.in
@@ -0,0 +1,199 @@
+/* fficonfig.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+   systems. This function is required for `alloca.c' support on those systems.
+   */
+#undef CRAY_STACKSEG_END
+
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define to the flags needed for the .section .eh_frame directive. */
+#undef EH_FRAME_FLAGS
+
+/* Define this if you want extra debugging. */
+#undef FFI_DEBUG
+
+/* Cannot use PROT_EXEC on this target, so, we revert to alternative means */
+#undef FFI_EXEC_TRAMPOLINE_TABLE
+
+/* Cannot use malloc on this target, so, we revert to alternative means */
+#undef FFI_MMAP_EXEC_WRIT
+
+/* Define this is you do not want support for the raw API. */
+#undef FFI_NO_RAW_API
+
+/* Define this is you do not want support for aggregate types. */
+#undef FFI_NO_STRUCTS
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+   */
+#undef HAVE_ALLOCA_H
+
+/* Define if your assembler supports .ascii. */
+#undef HAVE_AS_ASCII_PSEUDO_OP
+
+/* Define if your assembler supports .cfi_* directives. */
+#undef HAVE_AS_CFI_PSEUDO_OP
+
+/* Define if your assembler supports .register. */
+#undef HAVE_AS_REGISTER_PSEUDO_OP
+
+/* Define if your assembler and linker support unaligned PC relative relocs.
+   */
+#undef HAVE_AS_SPARC_UA_PCREL
+
+/* Define if your assembler supports .string. */
+#undef HAVE_AS_STRING_PSEUDO_OP
+
+/* Define if your assembler supports unwind section type. */
+#undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE
+
+/* Define if your assembler supports PC relative relocs. */
+#undef HAVE_AS_X86_PCREL
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define if __attribute__((visibility("hidden"))) is supported. */
+#undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if you have the long double type and it is bigger than a double */
+#undef HAVE_LONG_DOUBLE
+
+/* Define to 1 if you have the `memcpy' function. */
+#undef HAVE_MEMCPY
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
+/* Define if mmap with MAP_ANON(YMOUS) works. */
+#undef HAVE_MMAP_ANON
+
+/* Define if mmap of /dev/zero works. */
+#undef HAVE_MMAP_DEV_ZERO
+
+/* Define if read-only mmap of a plain file works. */
+#undef HAVE_MMAP_FILE
+
+/* Define if .eh_frame sections should be read-only. */
+#undef HAVE_RO_EH_FRAME
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* The size of `double', as computed by sizeof. */
+#undef SIZEOF_DOUBLE
+
+/* The size of `long double', as computed by sizeof. */
+#undef SIZEOF_LONG_DOUBLE
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at runtime.
+	STACK_DIRECTION > 0 => grows toward higher addresses
+	STACK_DIRECTION < 0 => grows toward lower addresses
+	STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define this if you are using Purify and want to suppress spurious messages.
+   */
+#undef USING_PURIFY
+
+/* Version number of package */
+#undef VERSION
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+#  undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+
+#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name) .hidden name
+#else
+#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
+#endif
+#else
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name)
+#else
+#define FFI_HIDDEN
+#endif
+#endif
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/fficonfig.hw b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/fficonfig.hw
new file mode 100755
index 0000000..4d7506a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/fficonfig.hw
@@ -0,0 +1,57 @@
+/* -----------------------------------------------------------------*-C-*-
+   libffi - Copyright (c) 1996-2003, 2007, 2008  Red Hat, Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+
+   -------------------------------------------------------------------- */
+
+#ifndef LIBFFICONFIG_H
+#define LIBFFICONFIG_H
+
+#define HAVE_ALLOCA         1
+#define HAVE_MEMCPY         1
+#define HAVE_MEMORY_H       1
+#define HAVE_STDLIB_H       1
+#define HAVE_STRING_H       1
+#define HAVE_SYS_STAT_H     1
+#define HAVE_SYS_TYPES_H    1
+#define STDC_HEADERS        1
+
+#if defined(X86_WIN64)
+#define SIZEOF_DOUBLE       8
+#define SIZEOF_LONG_DOUBLE  0
+#else
+#define SIZEOF_DOUBLE       8
+#define SIZEOF_LONG_DOUBLE  0
+#endif
+
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name)
+#else
+#define FFI_HIDDEN
+#endif
+
+#endif /* LIBFFICONFIG_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/Makefile.am b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/Makefile.am
new file mode 100755
index 0000000..fd28024
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/Makefile.am
@@ -0,0 +1,9 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS=foreign
+
+DISTCLEANFILES=ffitarget.h
+EXTRA_DIST=ffi.h.in ffi_common.h
+
+includesdir = $(libdir)/@PACKAGE_NAME at -@PACKAGE_VERSION@/include
+nodist_includes_HEADERS = ffi.h ffitarget.h
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/Makefile.in b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/Makefile.in
new file mode 100755
index 0000000..f3d3ef2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/Makefile.in
@@ -0,0 +1,487 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = include
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+	$(srcdir)/ffi.h.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_maxopt.m4 \
+	$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
+	$(top_srcdir)/m4/ax_check_compiler_flags.m4 \
+	$(top_srcdir)/m4/ax_compiler_vendor.m4 \
+	$(top_srcdir)/m4/ax_configure_args.m4 \
+	$(top_srcdir)/m4/ax_enable_builddir.m4 \
+	$(top_srcdir)/m4/ax_gcc_archflag.m4 \
+	$(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/fficonfig.h
+CONFIG_CLEAN_FILES = ffi.h ffitarget.h
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(includesdir)"
+HEADERS = $(nodist_includes_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_LTLDFLAGS = @AM_LTLDFLAGS@
+AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PRTDIAG = @PRTDIAG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TARGET = @TARGET@
+TARGETDIR = @TARGETDIR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_enable_builddir_sed = @ax_enable_builddir_sed@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sys_symbol_underscore = @sys_symbol_underscore@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+toolexecdir = @toolexecdir@
+toolexeclibdir = @toolexeclibdir@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign
+DISTCLEANFILES = ffitarget.h
+EXTRA_DIST = ffi.h.in ffi_common.h
+includesdir = $(libdir)/@PACKAGE_NAME at -@PACKAGE_VERSION@/include
+nodist_includes_HEADERS = ffi.h ffitarget.h
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign include/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+ffi.h: $(top_builddir)/config.status $(srcdir)/ffi.h.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-nodist_includesHEADERS: $(nodist_includes_HEADERS)
+	@$(NORMAL_INSTALL)
+	test -z "$(includesdir)" || $(MKDIR_P) "$(DESTDIR)$(includesdir)"
+	@list='$(nodist_includes_HEADERS)'; test -n "$(includesdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includesdir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(includesdir)" || exit $$?; \
+	done
+
+uninstall-nodist_includesHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nodist_includes_HEADERS)'; test -n "$(includesdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(includesdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(includesdir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(includesdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-nodist_includesHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-nodist_includesHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-libtool ctags distclean distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-nodist_includesHEADERS \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags uninstall uninstall-am uninstall-nodist_includesHEADERS
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/ffi.h.in b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/ffi.h.in
new file mode 100755
index 0000000..f5a29b0
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/ffi.h.in
@@ -0,0 +1,427 @@
+/* -----------------------------------------------------------------*-C-*-
+   libffi @VERSION@ - Copyright (c) 2011 Anthony Green
+                    - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
+
+   Permission is hereby granted, free of charge, to any person
+   obtaining a copy of this software and associated documentation
+   files (the ``Software''), to deal in the Software without
+   restriction, including without limitation the rights to use, copy,
+   modify, merge, publish, distribute, sublicense, and/or sell copies
+   of the Software, and to permit persons to whom the Software is
+   furnished to do so, subject to the following conditions:
+
+   The above copyright notice and this permission notice shall be
+   included in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+   The basic API is described in the README file.
+
+   The raw API is designed to bypass some of the argument packing
+   and unpacking on architectures for which it can be avoided.
+
+   The closure API allows interpreted functions to be packaged up
+   inside a C function pointer, so that they can be called as C functions,
+   with no understanding on the client side that they are interpreted.
+   It can also be used in other cases in which it is necessary to package
+   up a user specified parameter and a function pointer as a single
+   function pointer.
+
+   The closure API must be implemented in order to get its functionality,
+   e.g. for use by gij.  Routines are provided to emulate the raw API
+   if the underlying platform doesn't allow faster implementation.
+
+   More details on the raw and cloure API can be found in:
+
+   http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
+
+   and
+
+   http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
+   -------------------------------------------------------------------- */
+
+#ifndef LIBFFI_H
+#define LIBFFI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Specify which architecture libffi is configured for. */
+#ifndef @TARGET@
+#define @TARGET@
+#endif
+
+/* ---- System configuration information --------------------------------- */
+
+#include <ffitarget.h>
+
+#ifndef LIBFFI_ASM
+
+#ifdef _MSC_VER
+#define __attribute__(X)
+#endif
+
+#include <stddef.h>
+#include <limits.h>
+
+/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
+   But we can find it either under the correct ANSI name, or under GNU
+   C's internal name.  */
+
+#define FFI_64_BIT_MAX 9223372036854775807
+
+#ifdef LONG_LONG_MAX
+# define FFI_LONG_LONG_MAX LONG_LONG_MAX
+#else
+# ifdef LLONG_MAX
+#  define FFI_LONG_LONG_MAX LLONG_MAX
+#  ifdef _AIX52 /* or newer has C99 LLONG_MAX */
+#   undef FFI_64_BIT_MAX
+#   define FFI_64_BIT_MAX 9223372036854775807LL
+#  endif /* _AIX52 or newer */
+# else
+#  ifdef __GNUC__
+#   define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
+#  endif
+#  ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
+#   ifndef __PPC64__
+#    if defined (__IBMC__) || defined (__IBMCPP__)
+#     define FFI_LONG_LONG_MAX LONGLONG_MAX
+#    endif
+#   endif /* __PPC64__ */
+#   undef  FFI_64_BIT_MAX
+#   define FFI_64_BIT_MAX 9223372036854775807LL
+#  endif
+# endif
+#endif
+
+/* The closure code assumes that this works on pointers, i.e. a size_t	*/
+/* can hold a pointer.							*/
+
+typedef struct _ffi_type
+{
+  size_t size;
+  unsigned short alignment;
+  unsigned short type;
+  struct _ffi_type **elements;
+} ffi_type;
+
+#ifndef LIBFFI_HIDE_BASIC_TYPES
+#if SCHAR_MAX == 127
+# define ffi_type_uchar                ffi_type_uint8
+# define ffi_type_schar                ffi_type_sint8
+#else
+ #error "char size not supported"
+#endif
+
+#if SHRT_MAX == 32767
+# define ffi_type_ushort       ffi_type_uint16
+# define ffi_type_sshort       ffi_type_sint16
+#elif SHRT_MAX == 2147483647
+# define ffi_type_ushort       ffi_type_uint32
+# define ffi_type_sshort       ffi_type_sint32
+#else
+ #error "short size not supported"
+#endif
+
+#if INT_MAX == 32767
+# define ffi_type_uint         ffi_type_uint16
+# define ffi_type_sint         ffi_type_sint16
+#elif INT_MAX == 2147483647
+# define ffi_type_uint         ffi_type_uint32
+# define ffi_type_sint         ffi_type_sint32
+#elif INT_MAX == 9223372036854775807
+# define ffi_type_uint         ffi_type_uint64
+# define ffi_type_sint         ffi_type_sint64
+#else
+ #error "int size not supported"
+#endif
+
+#if LONG_MAX == 2147483647
+# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
+ #error "no 64-bit data type supported"
+# endif
+#elif LONG_MAX != FFI_64_BIT_MAX
+ #error "long size not supported"
+#endif
+
+#if LONG_MAX == 2147483647
+# define ffi_type_ulong        ffi_type_uint32
+# define ffi_type_slong        ffi_type_sint32
+#elif LONG_MAX == FFI_64_BIT_MAX
+# define ffi_type_ulong        ffi_type_uint64
+# define ffi_type_slong        ffi_type_sint64
+#else
+ #error "long size not supported"
+#endif
+
+/* These are defined in types.c */
+extern ffi_type ffi_type_void;
+extern ffi_type ffi_type_uint8;
+extern ffi_type ffi_type_sint8;
+extern ffi_type ffi_type_uint16;
+extern ffi_type ffi_type_sint16;
+extern ffi_type ffi_type_uint32;
+extern ffi_type ffi_type_sint32;
+extern ffi_type ffi_type_uint64;
+extern ffi_type ffi_type_sint64;
+extern ffi_type ffi_type_float;
+extern ffi_type ffi_type_double;
+extern ffi_type ffi_type_pointer;
+
+#if @HAVE_LONG_DOUBLE@
+extern ffi_type ffi_type_longdouble;
+#else
+#define ffi_type_longdouble ffi_type_double
+#endif
+#endif /* LIBFFI_HIDE_BASIC_TYPES */
+
+typedef enum {
+  FFI_OK = 0,
+  FFI_BAD_TYPEDEF,
+  FFI_BAD_ABI
+} ffi_status;
+
+typedef unsigned FFI_TYPE;
+
+typedef struct {
+  ffi_abi abi;
+  unsigned nargs;
+  ffi_type **arg_types;
+  ffi_type *rtype;
+  unsigned bytes;
+  unsigned flags;
+#ifdef FFI_EXTRA_CIF_FIELDS
+  FFI_EXTRA_CIF_FIELDS;
+#endif
+} ffi_cif;
+
+/* ---- Definitions for the raw API -------------------------------------- */
+
+#ifndef FFI_SIZEOF_ARG
+# if LONG_MAX == 2147483647
+#  define FFI_SIZEOF_ARG        4
+# elif LONG_MAX == FFI_64_BIT_MAX
+#  define FFI_SIZEOF_ARG        8
+# endif
+#endif
+
+#ifndef FFI_SIZEOF_JAVA_RAW
+#  define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
+#endif
+
+typedef union {
+  ffi_sarg  sint;
+  ffi_arg   uint;
+  float	    flt;
+  char      data[FFI_SIZEOF_ARG];
+  void*     ptr;
+} ffi_raw;
+
+#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
+/* This is a special case for mips64/n32 ABI (and perhaps others) where
+   sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8.  */
+typedef union {
+  signed int	sint;
+  unsigned int	uint;
+  float		flt;
+  char		data[FFI_SIZEOF_JAVA_RAW];
+  void*		ptr;
+} ffi_java_raw;
+#else
+typedef ffi_raw ffi_java_raw;
+#endif
+
+
+void ffi_raw_call (ffi_cif *cif,
+		   void (*fn)(void),
+		   void *rvalue,
+		   ffi_raw *avalue);
+
+void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_raw_size (ffi_cif *cif);
+
+/* This is analogous to the raw API, except it uses Java parameter	*/
+/* packing, even on 64-bit machines.  I.e. on 64-bit machines		*/
+/* longs and doubles are followed by an empty 64-bit word.		*/
+
+void ffi_java_raw_call (ffi_cif *cif,
+			void (*fn)(void),
+			void *rvalue,
+			ffi_java_raw *avalue);
+
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
+size_t ffi_java_raw_size (ffi_cif *cif);
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if FFI_CLOSURES
+
+#ifdef _MSC_VER
+__declspec(align(8))
+#endif
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+  ffi_cif   *cif;
+  void     (*fun)(ffi_cif*,void*,void**,void*);
+  void      *user_data;
+#ifdef __GNUC__
+} ffi_closure __attribute__((aligned (8)));
+#else
+} ffi_closure;
+# ifdef __sgi
+#  pragma pack 0
+# endif
+#endif
+
+void *ffi_closure_alloc (size_t size, void **code);
+void ffi_closure_free (void *);
+
+ffi_status
+ffi_prep_closure (ffi_closure*,
+		  ffi_cif *,
+		  void (*fun)(ffi_cif*,void*,void**,void*),
+		  void *user_data);
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure*,
+		      ffi_cif *,
+		      void (*fun)(ffi_cif*,void*,void**,void*),
+		      void *user_data,
+		      void*codeloc);
+
+#ifdef __sgi
+# pragma pack 8
+#endif
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+
+  ffi_cif   *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+  /* if this is enabled, then a raw closure has the same layout 
+     as a regular closure.  We use this to install an intermediate 
+     handler to do the transaltion, void** -> ffi_raw*. */
+
+  void     (*translate_args)(ffi_cif*,void*,void**,void*);
+  void      *this_closure;
+
+#endif
+
+  void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
+  void      *user_data;
+
+} ffi_raw_closure;
+
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+
+  ffi_cif   *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+  /* if this is enabled, then a raw closure has the same layout 
+     as a regular closure.  We use this to install an intermediate 
+     handler to do the transaltion, void** -> ffi_raw*. */
+
+  void     (*translate_args)(ffi_cif*,void*,void**,void*);
+  void      *this_closure;
+
+#endif
+
+  void     (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
+  void      *user_data;
+
+} ffi_java_raw_closure;
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure*,
+		      ffi_cif *cif,
+		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+		      void *user_data);
+
+ffi_status
+ffi_prep_raw_closure_loc (ffi_raw_closure*,
+			  ffi_cif *cif,
+			  void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+			  void *user_data,
+			  void *codeloc);
+
+ffi_status
+ffi_prep_java_raw_closure (ffi_java_raw_closure*,
+		           ffi_cif *cif,
+		           void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
+		           void *user_data);
+
+ffi_status
+ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
+			       ffi_cif *cif,
+			       void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
+			       void *user_data,
+			       void *codeloc);
+
+#endif /* FFI_CLOSURES */
+
+/* ---- Public interface definition -------------------------------------- */
+
+ffi_status ffi_prep_cif(ffi_cif *cif,
+			ffi_abi abi,
+			unsigned int nargs,
+			ffi_type *rtype,
+			ffi_type **atypes);
+
+void ffi_call(ffi_cif *cif,
+	      void (*fn)(void),
+	      void *rvalue,
+	      void **avalue);
+
+/* Useful for eliminating compiler warnings */
+#define FFI_FN(f) ((void (*)(void))f)
+
+/* ---- Definitions shared with assembly code ---------------------------- */
+
+#endif
+
+/* If these change, update src/mips/ffitarget.h. */
+#define FFI_TYPE_VOID       0    
+#define FFI_TYPE_INT        1
+#define FFI_TYPE_FLOAT      2    
+#define FFI_TYPE_DOUBLE     3
+#if @HAVE_LONG_DOUBLE@
+#define FFI_TYPE_LONGDOUBLE 4
+#else
+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
+#endif
+#define FFI_TYPE_UINT8      5   
+#define FFI_TYPE_SINT8      6
+#define FFI_TYPE_UINT16     7 
+#define FFI_TYPE_SINT16     8
+#define FFI_TYPE_UINT32     9
+#define FFI_TYPE_SINT32     10
+#define FFI_TYPE_UINT64     11
+#define FFI_TYPE_SINT64     12
+#define FFI_TYPE_STRUCT     13
+#define FFI_TYPE_POINTER    14
+
+/* This should always refer to the last type code (for sanity checks) */
+#define FFI_TYPE_LAST       FFI_TYPE_POINTER
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/ffi.h.vc b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/ffi.h.vc
new file mode 100755
index 0000000..7ba954c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/ffi.h.vc
@@ -0,0 +1,427 @@
+/* -----------------------------------------------------------------*-C-*-
+   libffi 3.0.10 - Copyright (c) 2011 Anthony Green
+                    - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
+
+   Permission is hereby granted, free of charge, to any person
+   obtaining a copy of this software and associated documentation
+   files (the ``Software''), to deal in the Software without
+   restriction, including without limitation the rights to use, copy,
+   modify, merge, publish, distribute, sublicense, and/or sell copies
+   of the Software, and to permit persons to whom the Software is
+   furnished to do so, subject to the following conditions:
+
+   The above copyright notice and this permission notice shall be
+   included in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+   The basic API is described in the README file.
+
+   The raw API is designed to bypass some of the argument packing
+   and unpacking on architectures for which it can be avoided.
+
+   The closure API allows interpreted functions to be packaged up
+   inside a C function pointer, so that they can be called as C functions,
+   with no understanding on the client side that they are interpreted.
+   It can also be used in other cases in which it is necessary to package
+   up a user specified parameter and a function pointer as a single
+   function pointer.
+
+   The closure API must be implemented in order to get its functionality,
+   e.g. for use by gij.  Routines are provided to emulate the raw API
+   if the underlying platform doesn't allow faster implementation.
+
+   More details on the raw and cloure API can be found in:
+
+   http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
+
+   and
+
+   http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
+   -------------------------------------------------------------------- */
+
+#ifndef LIBFFI_H
+#define LIBFFI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Specify which architecture libffi is configured for. */
+#ifndef X86_WIN32
+#define X86_WIN32
+#endif
+
+/* ---- System configuration information --------------------------------- */
+
+#include <ffitarget.h>
+
+#ifndef LIBFFI_ASM
+
+#ifdef _MSC_VER
+#define __attribute__(X)
+#endif
+
+#include <stddef.h>
+#include <limits.h>
+
+/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
+   But we can find it either under the correct ANSI name, or under GNU
+   C's internal name.  */
+
+#define FFI_64_BIT_MAX 9223372036854775807
+
+#ifdef LONG_LONG_MAX
+# define FFI_LONG_LONG_MAX LONG_LONG_MAX
+#else
+# ifdef LLONG_MAX
+#  define FFI_LONG_LONG_MAX LLONG_MAX
+#  ifdef _AIX52 /* or newer has C99 LLONG_MAX */
+#   undef FFI_64_BIT_MAX
+#   define FFI_64_BIT_MAX 9223372036854775807LL
+#  endif /* _AIX52 or newer */
+# else
+#  ifdef __GNUC__
+#   define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
+#  endif
+#  ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
+#   ifndef __PPC64__
+#    if defined (__IBMC__) || defined (__IBMCPP__)
+#     define FFI_LONG_LONG_MAX LONGLONG_MAX
+#    endif
+#   endif /* __PPC64__ */
+#   undef  FFI_64_BIT_MAX
+#   define FFI_64_BIT_MAX 9223372036854775807LL
+#  endif
+# endif
+#endif
+
+/* The closure code assumes that this works on pointers, i.e. a size_t	*/
+/* can hold a pointer.							*/
+
+typedef struct _ffi_type
+{
+  size_t size;
+  unsigned short alignment;
+  unsigned short type;
+  struct _ffi_type **elements;
+} ffi_type;
+
+#ifndef LIBFFI_HIDE_BASIC_TYPES
+#if SCHAR_MAX == 127
+# define ffi_type_uchar                ffi_type_uint8
+# define ffi_type_schar                ffi_type_sint8
+#else
+ #error "char size not supported"
+#endif
+
+#if SHRT_MAX == 32767
+# define ffi_type_ushort       ffi_type_uint16
+# define ffi_type_sshort       ffi_type_sint16
+#elif SHRT_MAX == 2147483647
+# define ffi_type_ushort       ffi_type_uint32
+# define ffi_type_sshort       ffi_type_sint32
+#else
+ #error "short size not supported"
+#endif
+
+#if INT_MAX == 32767
+# define ffi_type_uint         ffi_type_uint16
+# define ffi_type_sint         ffi_type_sint16
+#elif INT_MAX == 2147483647
+# define ffi_type_uint         ffi_type_uint32
+# define ffi_type_sint         ffi_type_sint32
+#elif INT_MAX == 9223372036854775807
+# define ffi_type_uint         ffi_type_uint64
+# define ffi_type_sint         ffi_type_sint64
+#else
+ #error "int size not supported"
+#endif
+
+#if LONG_MAX == 2147483647
+# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
+ #error "no 64-bit data type supported"
+# endif
+#elif LONG_MAX != FFI_64_BIT_MAX
+ #error "long size not supported"
+#endif
+
+#if LONG_MAX == 2147483647
+# define ffi_type_ulong        ffi_type_uint32
+# define ffi_type_slong        ffi_type_sint32
+#elif LONG_MAX == FFI_64_BIT_MAX
+# define ffi_type_ulong        ffi_type_uint64
+# define ffi_type_slong        ffi_type_sint64
+#else
+ #error "long size not supported"
+#endif
+
+/* These are defined in types.c */
+extern ffi_type ffi_type_void;
+extern ffi_type ffi_type_uint8;
+extern ffi_type ffi_type_sint8;
+extern ffi_type ffi_type_uint16;
+extern ffi_type ffi_type_sint16;
+extern ffi_type ffi_type_uint32;
+extern ffi_type ffi_type_sint32;
+extern ffi_type ffi_type_uint64;
+extern ffi_type ffi_type_sint64;
+extern ffi_type ffi_type_float;
+extern ffi_type ffi_type_double;
+extern ffi_type ffi_type_pointer;
+
+#if 0
+extern ffi_type ffi_type_longdouble;
+#else
+#define ffi_type_longdouble ffi_type_double
+#endif
+#endif /* LIBFFI_HIDE_BASIC_TYPES */
+
+typedef enum {
+  FFI_OK = 0,
+  FFI_BAD_TYPEDEF,
+  FFI_BAD_ABI
+} ffi_status;
+
+typedef unsigned FFI_TYPE;
+
+typedef struct {
+  ffi_abi abi;
+  unsigned nargs;
+  ffi_type **arg_types;
+  ffi_type *rtype;
+  unsigned bytes;
+  unsigned flags;
+#ifdef FFI_EXTRA_CIF_FIELDS
+  FFI_EXTRA_CIF_FIELDS;
+#endif
+} ffi_cif;
+
+/* ---- Definitions for the raw API -------------------------------------- */
+
+#ifndef FFI_SIZEOF_ARG
+# if LONG_MAX == 2147483647
+#  define FFI_SIZEOF_ARG        4
+# elif LONG_MAX == FFI_64_BIT_MAX
+#  define FFI_SIZEOF_ARG        8
+# endif
+#endif
+
+#ifndef FFI_SIZEOF_JAVA_RAW
+#  define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
+#endif
+
+typedef union {
+  ffi_sarg  sint;
+  ffi_arg   uint;
+  float	    flt;
+  char      data[FFI_SIZEOF_ARG];
+  void*     ptr;
+} ffi_raw;
+
+#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
+/* This is a special case for mips64/n32 ABI (and perhaps others) where
+   sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8.  */
+typedef union {
+  signed int	sint;
+  unsigned int	uint;
+  float		flt;
+  char		data[FFI_SIZEOF_JAVA_RAW];
+  void*		ptr;
+} ffi_java_raw;
+#else
+typedef ffi_raw ffi_java_raw;
+#endif
+
+
+void ffi_raw_call (ffi_cif *cif,
+		   void (*fn)(void),
+		   void *rvalue,
+		   ffi_raw *avalue);
+
+void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_raw_size (ffi_cif *cif);
+
+/* This is analogous to the raw API, except it uses Java parameter	*/
+/* packing, even on 64-bit machines.  I.e. on 64-bit machines		*/
+/* longs and doubles are followed by an empty 64-bit word.		*/
+
+void ffi_java_raw_call (ffi_cif *cif,
+			void (*fn)(void),
+			void *rvalue,
+			ffi_java_raw *avalue);
+
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
+size_t ffi_java_raw_size (ffi_cif *cif);
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if FFI_CLOSURES
+
+#ifdef _MSC_VER
+__declspec(align(8))
+#endif
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+  ffi_cif   *cif;
+  void     (*fun)(ffi_cif*,void*,void**,void*);
+  void      *user_data;
+#ifdef __GNUC__
+} ffi_closure __attribute__((aligned (8)));
+#else
+} ffi_closure;
+# ifdef __sgi
+#  pragma pack 0
+# endif
+#endif
+
+void *ffi_closure_alloc (size_t size, void **code);
+void ffi_closure_free (void *);
+
+ffi_status
+ffi_prep_closure (ffi_closure*,
+		  ffi_cif *,
+		  void (*fun)(ffi_cif*,void*,void**,void*),
+		  void *user_data);
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure*,
+		      ffi_cif *,
+		      void (*fun)(ffi_cif*,void*,void**,void*),
+		      void *user_data,
+		      void*codeloc);
+
+#ifdef __sgi
+# pragma pack 8
+#endif
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+
+  ffi_cif   *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+  /* if this is enabled, then a raw closure has the same layout 
+     as a regular closure.  We use this to install an intermediate 
+     handler to do the transaltion, void** -> ffi_raw*. */
+
+  void     (*translate_args)(ffi_cif*,void*,void**,void*);
+  void      *this_closure;
+
+#endif
+
+  void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
+  void      *user_data;
+
+} ffi_raw_closure;
+
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+
+  ffi_cif   *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+  /* if this is enabled, then a raw closure has the same layout 
+     as a regular closure.  We use this to install an intermediate 
+     handler to do the transaltion, void** -> ffi_raw*. */
+
+  void     (*translate_args)(ffi_cif*,void*,void**,void*);
+  void      *this_closure;
+
+#endif
+
+  void     (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
+  void      *user_data;
+
+} ffi_java_raw_closure;
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure*,
+		      ffi_cif *cif,
+		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+		      void *user_data);
+
+ffi_status
+ffi_prep_raw_closure_loc (ffi_raw_closure*,
+			  ffi_cif *cif,
+			  void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+			  void *user_data,
+			  void *codeloc);
+
+ffi_status
+ffi_prep_java_raw_closure (ffi_java_raw_closure*,
+		           ffi_cif *cif,
+		           void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
+		           void *user_data);
+
+ffi_status
+ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
+			       ffi_cif *cif,
+			       void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
+			       void *user_data,
+			       void *codeloc);
+
+#endif /* FFI_CLOSURES */
+
+/* ---- Public interface definition -------------------------------------- */
+
+ffi_status ffi_prep_cif(ffi_cif *cif,
+			ffi_abi abi,
+			unsigned int nargs,
+			ffi_type *rtype,
+			ffi_type **atypes);
+
+void ffi_call(ffi_cif *cif,
+	      void (*fn)(void),
+	      void *rvalue,
+	      void **avalue);
+
+/* Useful for eliminating compiler warnings */
+#define FFI_FN(f) ((void (*)(void))f)
+
+/* ---- Definitions shared with assembly code ---------------------------- */
+
+#endif
+
+/* If these change, update src/mips/ffitarget.h. */
+#define FFI_TYPE_VOID       0    
+#define FFI_TYPE_INT        1
+#define FFI_TYPE_FLOAT      2    
+#define FFI_TYPE_DOUBLE     3
+#if 0
+#define FFI_TYPE_LONGDOUBLE 4
+#else
+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
+#endif
+#define FFI_TYPE_UINT8      5   
+#define FFI_TYPE_SINT8      6
+#define FFI_TYPE_UINT16     7 
+#define FFI_TYPE_SINT16     8
+#define FFI_TYPE_UINT32     9
+#define FFI_TYPE_SINT32     10
+#define FFI_TYPE_UINT64     11
+#define FFI_TYPE_SINT64     12
+#define FFI_TYPE_STRUCT     13
+#define FFI_TYPE_POINTER    14
+
+/* This should always refer to the last type code (for sanity checks) */
+#define FFI_TYPE_LAST       FFI_TYPE_POINTER
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif 
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/ffi.h.vc64 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/ffi.h.vc64
new file mode 100755
index 0000000..6489c9f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/ffi.h.vc64
@@ -0,0 +1,427 @@
+/* -----------------------------------------------------------------*-C-*-
+   libffi 3.0.10 - Copyright (c) 2011 Anthony Green
+                    - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
+
+   Permission is hereby granted, free of charge, to any person
+   obtaining a copy of this software and associated documentation
+   files (the ``Software''), to deal in the Software without
+   restriction, including without limitation the rights to use, copy,
+   modify, merge, publish, distribute, sublicense, and/or sell copies
+   of the Software, and to permit persons to whom the Software is
+   furnished to do so, subject to the following conditions:
+
+   The above copyright notice and this permission notice shall be
+   included in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+   The basic API is described in the README file.
+
+   The raw API is designed to bypass some of the argument packing
+   and unpacking on architectures for which it can be avoided.
+
+   The closure API allows interpreted functions to be packaged up
+   inside a C function pointer, so that they can be called as C functions,
+   with no understanding on the client side that they are interpreted.
+   It can also be used in other cases in which it is necessary to package
+   up a user specified parameter and a function pointer as a single
+   function pointer.
+
+   The closure API must be implemented in order to get its functionality,
+   e.g. for use by gij.  Routines are provided to emulate the raw API
+   if the underlying platform doesn't allow faster implementation.
+
+   More details on the raw and cloure API can be found in:
+
+   http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
+
+   and
+
+   http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
+   -------------------------------------------------------------------- */
+
+#ifndef LIBFFI_H
+#define LIBFFI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Specify which architecture libffi is configured for. */
+#ifndef X86_WIN64
+#define X86_WIN64
+#endif
+
+/* ---- System configuration information --------------------------------- */
+
+#include <ffitarget.h>
+
+#ifndef LIBFFI_ASM
+
+#ifdef _MSC_VER
+#define __attribute__(X)
+#endif
+
+#include <stddef.h>
+#include <limits.h>
+
+/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
+   But we can find it either under the correct ANSI name, or under GNU
+   C's internal name.  */
+
+#define FFI_64_BIT_MAX 9223372036854775807
+
+#ifdef LONG_LONG_MAX
+# define FFI_LONG_LONG_MAX LONG_LONG_MAX
+#else
+# ifdef LLONG_MAX
+#  define FFI_LONG_LONG_MAX LLONG_MAX
+#  ifdef _AIX52 /* or newer has C99 LLONG_MAX */
+#   undef FFI_64_BIT_MAX
+#   define FFI_64_BIT_MAX 9223372036854775807LL
+#  endif /* _AIX52 or newer */
+# else
+#  ifdef __GNUC__
+#   define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
+#  endif
+#  ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
+#   ifndef __PPC64__
+#    if defined (__IBMC__) || defined (__IBMCPP__)
+#     define FFI_LONG_LONG_MAX LONGLONG_MAX
+#    endif
+#   endif /* __PPC64__ */
+#   undef  FFI_64_BIT_MAX
+#   define FFI_64_BIT_MAX 9223372036854775807LL
+#  endif
+# endif
+#endif
+
+/* The closure code assumes that this works on pointers, i.e. a size_t	*/
+/* can hold a pointer.							*/
+
+typedef struct _ffi_type
+{
+  size_t size;
+  unsigned short alignment;
+  unsigned short type;
+  struct _ffi_type **elements;
+} ffi_type;
+
+#ifndef LIBFFI_HIDE_BASIC_TYPES
+#if SCHAR_MAX == 127
+# define ffi_type_uchar                ffi_type_uint8
+# define ffi_type_schar                ffi_type_sint8
+#else
+ #error "char size not supported"
+#endif
+
+#if SHRT_MAX == 32767
+# define ffi_type_ushort       ffi_type_uint16
+# define ffi_type_sshort       ffi_type_sint16
+#elif SHRT_MAX == 2147483647
+# define ffi_type_ushort       ffi_type_uint32
+# define ffi_type_sshort       ffi_type_sint32
+#else
+ #error "short size not supported"
+#endif
+
+#if INT_MAX == 32767
+# define ffi_type_uint         ffi_type_uint16
+# define ffi_type_sint         ffi_type_sint16
+#elif INT_MAX == 2147483647
+# define ffi_type_uint         ffi_type_uint32
+# define ffi_type_sint         ffi_type_sint32
+#elif INT_MAX == 9223372036854775807
+# define ffi_type_uint         ffi_type_uint64
+# define ffi_type_sint         ffi_type_sint64
+#else
+ #error "int size not supported"
+#endif
+
+#if LONG_MAX == 2147483647
+# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
+ #error "no 64-bit data type supported"
+# endif
+#elif LONG_MAX != FFI_64_BIT_MAX
+ #error "long size not supported"
+#endif
+
+#if LONG_MAX == 2147483647
+# define ffi_type_ulong        ffi_type_uint32
+# define ffi_type_slong        ffi_type_sint32
+#elif LONG_MAX == FFI_64_BIT_MAX
+# define ffi_type_ulong        ffi_type_uint64
+# define ffi_type_slong        ffi_type_sint64
+#else
+ #error "long size not supported"
+#endif
+
+/* These are defined in types.c */
+extern ffi_type ffi_type_void;
+extern ffi_type ffi_type_uint8;
+extern ffi_type ffi_type_sint8;
+extern ffi_type ffi_type_uint16;
+extern ffi_type ffi_type_sint16;
+extern ffi_type ffi_type_uint32;
+extern ffi_type ffi_type_sint32;
+extern ffi_type ffi_type_uint64;
+extern ffi_type ffi_type_sint64;
+extern ffi_type ffi_type_float;
+extern ffi_type ffi_type_double;
+extern ffi_type ffi_type_pointer;
+
+#if 0
+extern ffi_type ffi_type_longdouble;
+#else
+#define ffi_type_longdouble ffi_type_double
+#endif
+#endif /* LIBFFI_HIDE_BASIC_TYPES */
+
+typedef enum {
+  FFI_OK = 0,
+  FFI_BAD_TYPEDEF,
+  FFI_BAD_ABI
+} ffi_status;
+
+typedef unsigned FFI_TYPE;
+
+typedef struct {
+  ffi_abi abi;
+  unsigned nargs;
+  ffi_type **arg_types;
+  ffi_type *rtype;
+  unsigned bytes;
+  unsigned flags;
+#ifdef FFI_EXTRA_CIF_FIELDS
+  FFI_EXTRA_CIF_FIELDS;
+#endif
+} ffi_cif;
+
+/* ---- Definitions for the raw API -------------------------------------- */
+
+#ifndef FFI_SIZEOF_ARG
+# if LONG_MAX == 2147483647
+#  define FFI_SIZEOF_ARG        4
+# elif LONG_MAX == FFI_64_BIT_MAX
+#  define FFI_SIZEOF_ARG        8
+# endif
+#endif
+
+#ifndef FFI_SIZEOF_JAVA_RAW
+#  define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
+#endif
+
+typedef union {
+  ffi_sarg  sint;
+  ffi_arg   uint;
+  float	    flt;
+  char      data[FFI_SIZEOF_ARG];
+  void*     ptr;
+} ffi_raw;
+
+#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
+/* This is a special case for mips64/n32 ABI (and perhaps others) where
+   sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8.  */
+typedef union {
+  signed int	sint;
+  unsigned int	uint;
+  float		flt;
+  char		data[FFI_SIZEOF_JAVA_RAW];
+  void*		ptr;
+} ffi_java_raw;
+#else
+typedef ffi_raw ffi_java_raw;
+#endif
+
+
+void ffi_raw_call (ffi_cif *cif,
+		   void (*fn)(void),
+		   void *rvalue,
+		   ffi_raw *avalue);
+
+void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_raw_size (ffi_cif *cif);
+
+/* This is analogous to the raw API, except it uses Java parameter	*/
+/* packing, even on 64-bit machines.  I.e. on 64-bit machines		*/
+/* longs and doubles are followed by an empty 64-bit word.		*/
+
+void ffi_java_raw_call (ffi_cif *cif,
+			void (*fn)(void),
+			void *rvalue,
+			ffi_java_raw *avalue);
+
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
+size_t ffi_java_raw_size (ffi_cif *cif);
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if FFI_CLOSURES
+
+#ifdef _MSC_VER
+__declspec(align(8))
+#endif
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+  ffi_cif   *cif;
+  void     (*fun)(ffi_cif*,void*,void**,void*);
+  void      *user_data;
+#ifdef __GNUC__
+} ffi_closure __attribute__((aligned (8)));
+#else
+} ffi_closure;
+# ifdef __sgi
+#  pragma pack 0
+# endif
+#endif
+
+void *ffi_closure_alloc (size_t size, void **code);
+void ffi_closure_free (void *);
+
+ffi_status
+ffi_prep_closure (ffi_closure*,
+		  ffi_cif *,
+		  void (*fun)(ffi_cif*,void*,void**,void*),
+		  void *user_data);
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure*,
+		      ffi_cif *,
+		      void (*fun)(ffi_cif*,void*,void**,void*),
+		      void *user_data,
+		      void*codeloc);
+
+#ifdef __sgi
+# pragma pack 8
+#endif
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+
+  ffi_cif   *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+  /* if this is enabled, then a raw closure has the same layout 
+     as a regular closure.  We use this to install an intermediate 
+     handler to do the transaltion, void** -> ffi_raw*. */
+
+  void     (*translate_args)(ffi_cif*,void*,void**,void*);
+  void      *this_closure;
+
+#endif
+
+  void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
+  void      *user_data;
+
+} ffi_raw_closure;
+
+typedef struct {
+  char tramp[FFI_TRAMPOLINE_SIZE];
+
+  ffi_cif   *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+  /* if this is enabled, then a raw closure has the same layout 
+     as a regular closure.  We use this to install an intermediate 
+     handler to do the transaltion, void** -> ffi_raw*. */
+
+  void     (*translate_args)(ffi_cif*,void*,void**,void*);
+  void      *this_closure;
+
+#endif
+
+  void     (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
+  void      *user_data;
+
+} ffi_java_raw_closure;
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure*,
+		      ffi_cif *cif,
+		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+		      void *user_data);
+
+ffi_status
+ffi_prep_raw_closure_loc (ffi_raw_closure*,
+			  ffi_cif *cif,
+			  void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+			  void *user_data,
+			  void *codeloc);
+
+ffi_status
+ffi_prep_java_raw_closure (ffi_java_raw_closure*,
+		           ffi_cif *cif,
+		           void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
+		           void *user_data);
+
+ffi_status
+ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
+			       ffi_cif *cif,
+			       void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
+			       void *user_data,
+			       void *codeloc);
+
+#endif /* FFI_CLOSURES */
+
+/* ---- Public interface definition -------------------------------------- */
+
+ffi_status ffi_prep_cif(ffi_cif *cif,
+			ffi_abi abi,
+			unsigned int nargs,
+			ffi_type *rtype,
+			ffi_type **atypes);
+
+void ffi_call(ffi_cif *cif,
+	      void (*fn)(void),
+	      void *rvalue,
+	      void **avalue);
+
+/* Useful for eliminating compiler warnings */
+#define FFI_FN(f) ((void (*)(void))f)
+
+/* ---- Definitions shared with assembly code ---------------------------- */
+
+#endif
+
+/* If these change, update src/mips/ffitarget.h. */
+#define FFI_TYPE_VOID       0    
+#define FFI_TYPE_INT        1
+#define FFI_TYPE_FLOAT      2    
+#define FFI_TYPE_DOUBLE     3
+#if 0
+#define FFI_TYPE_LONGDOUBLE 4
+#else
+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
+#endif
+#define FFI_TYPE_UINT8      5   
+#define FFI_TYPE_SINT8      6
+#define FFI_TYPE_UINT16     7 
+#define FFI_TYPE_SINT16     8
+#define FFI_TYPE_UINT32     9
+#define FFI_TYPE_SINT32     10
+#define FFI_TYPE_UINT64     11
+#define FFI_TYPE_SINT64     12
+#define FFI_TYPE_STRUCT     13
+#define FFI_TYPE_POINTER    14
+
+/* This should always refer to the last type code (for sanity checks) */
+#define FFI_TYPE_LAST       FFI_TYPE_POINTER
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif 
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/ffi_common.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/ffi_common.h
new file mode 100755
index 0000000..d953762
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/include/ffi_common.h
@@ -0,0 +1,126 @@
+/* -----------------------------------------------------------------------
+   ffi_common.h - Copyright (C) 2011  Anthony Green
+                  Copyright (C) 2007  Free Software Foundation, Inc
+                  Copyright (c) 1996  Red Hat, Inc.
+                  
+   Common internal definitions and macros. Only necessary for building
+   libffi.
+   ----------------------------------------------------------------------- */
+
+#ifndef FFI_COMMON_H
+#define FFI_COMMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <fficonfig.h>
+
+/* Do not move this. Some versions of AIX are very picky about where
+   this is positioned. */
+#ifdef __GNUC__
+/* mingw64 defines this already in malloc.h. */
+#ifndef alloca
+# define alloca __builtin_alloca
+#endif
+# define MAYBE_UNUSED __attribute__((__unused__))
+#else
+# define MAYBE_UNUSED
+# if HAVE_ALLOCA_H
+#  include <alloca.h>
+# else
+#  ifdef _AIX
+ #pragma alloca
+#  else
+#   ifndef alloca /* predefined by HP cc +Olibcalls */
+#    ifdef _MSC_VER
+#     define alloca _alloca
+#    else
+char *alloca ();
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+/* Check for the existence of memcpy. */
+#if STDC_HEADERS
+# include <string.h>
+#else
+# ifndef HAVE_MEMCPY
+#  define memcpy(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#if defined(FFI_DEBUG)
+#include <stdio.h>
+#endif
+
+#ifdef FFI_DEBUG
+void ffi_assert(char *expr, char *file, int line);
+void ffi_stop_here(void);
+void ffi_type_test(ffi_type *a, char *file, int line);
+
+#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
+#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
+#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__)
+#else
+#define FFI_ASSERT(x)
+#define FFI_ASSERT_AT(x, f, l)
+#define FFI_ASSERT_VALID_TYPE(x)
+#endif
+
+#define ALIGN(v, a)  (((((size_t) (v))-1) | ((a)-1))+1)
+#define ALIGN_DOWN(v, a) (((size_t) (v)) & -a)
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
+
+/* Extended cif, used in callback from assembly routine */
+typedef struct
+{
+  ffi_cif *cif;
+  void *rvalue;
+  void **avalue;
+} extended_cif;
+
+/* Terse sized type definitions.  */
+#if defined(_MSC_VER) || defined(__sgi)
+typedef unsigned char UINT8;
+typedef signed char   SINT8;
+typedef unsigned short UINT16;
+typedef signed short   SINT16;
+typedef unsigned int UINT32;
+typedef signed int   SINT32;
+# ifdef _MSC_VER
+typedef unsigned __int64 UINT64;
+typedef signed __int64   SINT64;
+# else
+# include <inttypes.h>
+typedef uint64_t UINT64;
+typedef int64_t  SINT64;
+# endif
+#else
+typedef unsigned int UINT8  __attribute__((__mode__(__QI__)));
+typedef signed int   SINT8  __attribute__((__mode__(__QI__)));
+typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
+typedef signed int   SINT16 __attribute__((__mode__(__HI__)));
+typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
+typedef signed int   SINT32 __attribute__((__mode__(__SI__)));
+typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
+typedef signed int   SINT64 __attribute__((__mode__(__DI__)));
+#endif
+
+typedef float FLOAT32;
+
+#ifndef __GNUC__
+#define __builtin_expect(x, expected_value) (x)
+#endif
+#define LIKELY(x)    __builtin_expect((x),1)
+#define UNLIKELY(x)  __builtin_expect((x),1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/install-sh b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/install-sh
new file mode 100755
index 0000000..6781b98
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/install-sh
@@ -0,0 +1,520 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2009-04-28.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" ""	$nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+	shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
+
+    -o) chowncmd="$chownprog $2"
+	shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t) dst_arg=$2
+	shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)	shift
+	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  trap '(exit $?); exit' 1 2 13 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dst_arg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writeable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+	/*) prefix='/';;
+	-*) prefix='./';;
+	*)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test -z "$d" && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/libffi.pc.in b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/libffi.pc.in
new file mode 100755
index 0000000..c2e1c7b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/libffi.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=${libdir}/@PACKAGE_NAME at -@PACKAGE_VERSION@/include
+
+Name: @PACKAGE_NAME@
+Description: Library supporting Foreign Function Interfaces
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lffi
+Cflags: -I${includedir}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/libtool-version b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/libtool-version
new file mode 100755
index 0000000..b8b80e0
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/libtool-version
@@ -0,0 +1,29 @@
+# This file is used to maintain libtool version info for libffi.  See
+# the libtool manual to understand the meaning of the fields.  This is
+# a separate file so that version updates don't involve re-running
+# automake.
+#
+# Here are a set of rules to help you update your library version
+# information:
+# 
+# 1. Start with version information of `0:0:0' for each libtool library.
+#
+# 2. Update the version information only immediately before a public
+#    release of your software. More frequent updates are unnecessary,
+#    and only guarantee that the current interface number gets larger
+#    faster.
+#
+# 3. If the library source code has changed at all since the last
+#    update, then increment revision (`c:r:a' becomes `c:r+1:a').
+#
+# 4. If any interfaces have been added, removed, or changed since the
+#    last update, increment current, and set revision to 0.
+#
+# 5. If any interfaces have been added since the last public release,
+#    then increment age.
+#
+# 6. If any interfaces have been removed since the last public
+#    release, then set age to 0.
+#
+# CURRENT:REVISION:AGE
+5:10:0
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/ltmain.sh b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/ltmain.sh
new file mode 100755
index 0000000..aa5624c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/ltmain.sh
@@ -0,0 +1,9636 @@
+
+# libtool (GNU libtool) 2.4
+# Written by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+#       --config             show all configuration variables
+#       --debug              enable verbose shell tracing
+#   -n, --dry-run            display commands without modifying any files
+#       --features           display basic configuration information and exit
+#       --mode=MODE          use operation mode MODE
+#       --preserve-dup-deps  don't remove duplicate dependency libraries
+#       --quiet, --silent    don't print informational messages
+#       --no-quiet, --no-silent
+#                            print informational messages (default)
+#       --tag=TAG            use configuration variables from tag TAG
+#   -v, --verbose            print more informational messages than default
+#       --no-verbose         don't print the extra informational messages
+#       --version            print version information
+#   -h, --help, --help-all   print short, long, or detailed help message
+#
+# MODE must be one of the following:
+#
+#         clean              remove files from the build directory
+#         compile            compile a source file into a libtool object
+#         execute            automatically set library path, then run a program
+#         finish             complete the installation of libtool libraries
+#         install            install libraries or executables
+#         link               create a library or an executable
+#         uninstall          remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE.  When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+#         host-triplet:	$host
+#         shell:		$SHELL
+#         compiler:		$LTCC
+#         compiler flags:		$LTCFLAGS
+#         linker:		$LD (gnu? $with_gnu_ld)
+#         $progname:	(GNU libtool) 2.4
+#         automake:	$automake_version
+#         autoconf:	$autoconf_version
+#
+# Report bugs to <bug-libtool at gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION=2.4
+TIMESTAMP=""
+package_revision=1.3293
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+  eval "if test \"\${$lt_var+set}\" = set; then
+          save_$lt_var=\$$lt_var
+          $lt_var=C
+	  export $lt_var
+	  lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+	  lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+	fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
+
+$lt_unset CDPATH
+
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+
+
+: ${CP="cp -f"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+: ${EGREP="/bin/grep -E"}
+: ${FGREP="/bin/grep -F"}
+: ${GREP="/bin/grep"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SED="/bin/sed"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" 	$lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+    func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+    func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+    # Extract subdirectory from the argument.
+    func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+    func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+    case ${2} in
+      .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+      *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+    esac
+} # func_stripname may be replaced by extended shell implementation
+
+
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+		s@/\./@/@g
+		t dotsl
+		s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
+
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+#             value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+  # Start from root dir and reassemble the path.
+  func_normal_abspath_result=
+  func_normal_abspath_tpath=$1
+  func_normal_abspath_altnamespace=
+  case $func_normal_abspath_tpath in
+    "")
+      # Empty path, that just means $cwd.
+      func_stripname '' '/' "`pwd`"
+      func_normal_abspath_result=$func_stripname_result
+      return
+    ;;
+    # The next three entries are used to spot a run of precisely
+    # two leading slashes without using negated character classes;
+    # we take advantage of case's first-match behaviour.
+    ///*)
+      # Unusual form of absolute path, do nothing.
+    ;;
+    //*)
+      # Not necessarily an ordinary path; POSIX reserves leading '//'
+      # and for example Cygwin uses it to access remote file shares
+      # over CIFS/SMB, so we conserve a leading double slash if found.
+      func_normal_abspath_altnamespace=/
+    ;;
+    /*)
+      # Absolute path, do nothing.
+    ;;
+    *)
+      # Relative path, prepend $cwd.
+      func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+    ;;
+  esac
+  # Cancel out all the simple stuff to save iterations.  We also want
+  # the path to end with a slash for ease of parsing, so make sure
+  # there is one (and only one) here.
+  func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+  while :; do
+    # Processed it all yet?
+    if test "$func_normal_abspath_tpath" = / ; then
+      # If we ascended to the root using ".." the result may be empty now.
+      if test -z "$func_normal_abspath_result" ; then
+        func_normal_abspath_result=/
+      fi
+      break
+    fi
+    func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcar"`
+    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcdr"`
+    # Figure out what to do with it
+    case $func_normal_abspath_tcomponent in
+      "")
+        # Trailing empty path component, ignore it.
+      ;;
+      ..)
+        # Parent dir; strip last assembled component from result.
+        func_dirname "$func_normal_abspath_result"
+        func_normal_abspath_result=$func_dirname_result
+      ;;
+      *)
+        # Actual path component, append it.
+        func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+      ;;
+    esac
+  done
+  # Restore leading double-slash if one was found on entry.
+  func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+#             value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+  func_relative_path_result=
+  func_normal_abspath "$1"
+  func_relative_path_tlibdir=$func_normal_abspath_result
+  func_normal_abspath "$2"
+  func_relative_path_tbindir=$func_normal_abspath_result
+
+  # Ascend the tree starting from libdir
+  while :; do
+    # check if we have found a prefix of bindir
+    case $func_relative_path_tbindir in
+      $func_relative_path_tlibdir)
+        # found an exact match
+        func_relative_path_tcancelled=
+        break
+        ;;
+      $func_relative_path_tlibdir*)
+        # found a matching prefix
+        func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+        func_relative_path_tcancelled=$func_stripname_result
+        if test -z "$func_relative_path_result"; then
+          func_relative_path_result=.
+        fi
+        break
+        ;;
+      *)
+        func_dirname $func_relative_path_tlibdir
+        func_relative_path_tlibdir=${func_dirname_result}
+        if test "x$func_relative_path_tlibdir" = x ; then
+          # Have to descend all the way to the root!
+          func_relative_path_result=../$func_relative_path_result
+          func_relative_path_tcancelled=$func_relative_path_tbindir
+          break
+        fi
+        func_relative_path_result=../$func_relative_path_result
+        ;;
+    esac
+  done
+
+  # Now calculate path; take care to avoid doubling-up slashes.
+  func_stripname '' '/' "$func_relative_path_result"
+  func_relative_path_result=$func_stripname_result
+  func_stripname '/' '/' "$func_relative_path_tcancelled"
+  if test "x$func_stripname_result" != x ; then
+    func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+  fi
+
+  # Normalisation. If bindir is libdir, return empty string,
+  # else relative path ending with a slash; either way, target
+  # file name can be directly appended.
+  if test ! -z "$func_relative_path_result"; then
+    func_stripname './' '' "$func_relative_path_result/"
+    func_relative_path_result=$func_stripname_result
+  fi
+}
+
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+  [\\/]*|[A-Za-z]:\\*) ;;
+  *[\\/]*)
+     progdir=$func_dirname_result
+     progdir=`cd "$progdir" && pwd`
+     progpath="$progdir/$progname"
+     ;;
+  *)
+     save_IFS="$IFS"
+     IFS=:
+     for progdir in $PATH; do
+       IFS="$save_IFS"
+       test -x "$progdir/$progname" && break
+     done
+     IFS="$save_IFS"
+     test -n "$progdir" || progdir=`pwd`
+     progpath="$progdir/$progname"
+     ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes.  A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same.  If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'.  `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+  s/$bs4/&\\
+/g
+  s/^$bs2$dollar/$bs&/
+  s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+  s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+    $opt_verbose && func_echo ${1+"$@"}
+
+    # A bug in bash halts the script if the last line of a function
+    # fails when set -e is in force, so we need another command to
+    # work around that:
+    :
+}
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+    $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
+
+    # bash bug again:
+    :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+    func_error ${1+"$@"}
+    exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+    func_error ${1+"$@"}
+    func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information."  ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+    $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+    my_directory_path="$1"
+    my_dir_list=
+
+    if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+      # Protect directory names starting with `-'
+      case $my_directory_path in
+        -*) my_directory_path="./$my_directory_path" ;;
+      esac
+
+      # While some portion of DIR does not yet exist...
+      while test ! -d "$my_directory_path"; do
+        # ...make a list in topmost first order.  Use a colon delimited
+	# list incase some portion of path contains whitespace.
+        my_dir_list="$my_directory_path:$my_dir_list"
+
+        # If the last portion added has no slash in it, the list is done
+        case $my_directory_path in */*) ;; *) break ;; esac
+
+        # ...otherwise throw away the child directory and loop
+        my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
+      done
+      my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
+
+      save_mkdir_p_IFS="$IFS"; IFS=':'
+      for my_dir in $my_dir_list; do
+	IFS="$save_mkdir_p_IFS"
+        # mkdir can fail with a `File exist' error if two processes
+        # try to create one of the directories concurrently.  Don't
+        # stop in that case!
+        $MKDIR "$my_dir" 2>/dev/null || :
+      done
+      IFS="$save_mkdir_p_IFS"
+
+      # Bail out if we (or some other process) failed to create a directory.
+      test -d "$my_directory_path" || \
+        func_fatal_error "Failed to create \`$1'"
+    fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+    if test "$opt_dry_run" = ":"; then
+      # Return a directory name, but don't create it in dry-run mode
+      my_tmpdir="${my_template}-$$"
+    else
+
+      # If mktemp works, use that first and foremost
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+      if test ! -d "$my_tmpdir"; then
+        # Failing that, at least try and use $RANDOM to avoid a race
+        my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+        save_mktempdir_umask=`umask`
+        umask 0077
+        $MKDIR "$my_tmpdir"
+        umask $save_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$my_tmpdir" || \
+        func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+    fi
+
+    $ECHO "$my_tmpdir"
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+    case $1 in
+      *[\\\`\"\$]*)
+	func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+      *)
+        func_quote_for_eval_unquoted_result="$1" ;;
+    esac
+
+    case $func_quote_for_eval_unquoted_result in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and and variable
+      # expansion for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+        ;;
+      *)
+        func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+    esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+    case $1 in
+      *[\\\`\"]*)
+	my_arg=`$ECHO "$1" | $SED \
+	    -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        my_arg="$1" ;;
+    esac
+
+    case $my_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        my_arg="\"$my_arg\""
+        ;;
+    esac
+
+    func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$my_cmd"
+      my_status=$?
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.  Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$lt_user_locale
+	    $my_cmd"
+      my_status=$?
+      eval "$lt_safe_locale"
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result.  All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+  case $1 in
+  [0-9]* | *[!a-zA-Z0-9_]*)
+    func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+    ;;
+  * )
+    func_tr_sh_result=$1
+    ;;
+  esac
+}
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+    $opt_debug
+
+    $SED -n '/(C)/!b go
+	:more
+	/\./!{
+	  N
+	  s/\n# / /
+	  b more
+	}
+	:go
+	/^# '$PROGRAM' (GNU /,/# warranty; / {
+        s/^# //
+	s/^# *$//
+        s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+        p
+     }' < "$progpath"
+     exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/^#  *.*--help/ {
+        s/^# //
+	s/^# *$//
+	s/\$progname/'$progname'/
+	p
+    }' < "$progpath"
+    echo
+    $ECHO "run \`$progname --help | more' for full usage"
+    exit $?
+}
+
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
+func_help ()
+{
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/# Report bugs to/ {
+	:print
+        s/^# //
+	s/^# *$//
+	s*\$progname*'$progname'*
+	s*\$host*'"$host"'*
+	s*\$SHELL*'"$SHELL"'*
+	s*\$LTCC*'"$LTCC"'*
+	s*\$LTCFLAGS*'"$LTCFLAGS"'*
+	s*\$LD*'"$LD"'*
+	s/\$with_gnu_ld/'"$with_gnu_ld"'/
+	s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/
+	s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/
+	p
+	d
+     }
+     /^# .* home page:/b print
+     /^# General help using/b print
+     ' < "$progpath"
+    ret=$?
+    if test -z "$1"; then
+      exit $ret
+    fi
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+    $opt_debug
+
+    func_error "missing argument for $1."
+    exit_cmd=exit
+}
+
+
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+    my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+    my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
+
+    func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+    func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
+
+
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+    my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+    my_sed_long_arg='1s/^--[^=]*=//'
+
+    func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+    func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+
+exit_cmd=:
+
+
+
+
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+    eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+    func_quote_for_eval "${2}"
+    eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+    func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+    func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+    func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+    func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+    func_error ${1+"$@"}
+    func_error "See the $PACKAGE documentation for more information."
+    func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+    re_begincf='^# ### BEGIN LIBTOOL'
+    re_endcf='^# ### END LIBTOOL'
+
+    # Default configuration.
+    $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+    done
+
+    exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+    echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
+
+    exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+  # Global variable:
+  tagname="$1"
+
+  re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+  re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+  sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+  # Validate tagname.
+  case $tagname in
+    *[!-_A-Za-z0-9,/]*)
+      func_fatal_error "invalid tag name: $tagname"
+      ;;
+  esac
+
+  # Don't test for the "default" C tag, as we know it's
+  # there but not specially marked.
+  case $tagname in
+    CC) ;;
+    *)
+      if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+	taglist="$taglist $tagname"
+
+	# Evaluate the configuration.  Be careful to quote the path
+	# and the sed script, to avoid splitting on whitespace, but
+	# also don't use non-portable quotes within backquotes within
+	# quotes we have to do it in 2 steps:
+	extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+	eval "$extractedcf"
+      else
+	func_error "ignoring unknown tag $tagname"
+      fi
+      ;;
+  esac
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+  if test "$package_revision" != "$macro_revision"; then
+    if test "$VERSION" != "$macro_version"; then
+      if test -z "$macro_version"; then
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      else
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      fi
+    else
+      cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+    fi
+
+    exit $EXIT_MISMATCH
+  fi
+}
+
+
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+  shift; set dummy --mode clean ${1+"$@"}; shift
+  ;;
+compile|compil|compi|comp|com|co|c)
+  shift; set dummy --mode compile ${1+"$@"}; shift
+  ;;
+execute|execut|execu|exec|exe|ex|e)
+  shift; set dummy --mode execute ${1+"$@"}; shift
+  ;;
+finish|finis|fini|fin|fi|f)
+  shift; set dummy --mode finish ${1+"$@"}; shift
+  ;;
+install|instal|insta|inst|ins|in|i)
+  shift; set dummy --mode install ${1+"$@"}; shift
+  ;;
+link|lin|li|l)
+  shift; set dummy --mode link ${1+"$@"}; shift
+  ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+  shift; set dummy --mode uninstall ${1+"$@"}; shift
+  ;;
+esac
+
+
+
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
+
+
+# Parse options once, thoroughly.  This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+  # this just eases exit handling
+  while test $# -gt 0; do
+    opt="$1"
+    shift
+    case $opt in
+      --debug|-x)	opt_debug='set -x'
+			func_echo "enabling shell trace mode"
+			$opt_debug
+			;;
+      --dry-run|--dryrun|-n)
+			opt_dry_run=:
+			;;
+      --config)
+			opt_config=:
+func_config
+			;;
+      --dlopen|-dlopen)
+			optarg="$1"
+			opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+			shift
+			;;
+      --preserve-dup-deps)
+			opt_preserve_dup_deps=:
+			;;
+      --features)
+			opt_features=:
+func_features
+			;;
+      --finish)
+			opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+			;;
+      --help)
+			opt_help=:
+			;;
+      --help-all)
+			opt_help_all=:
+opt_help=': help-all'
+			;;
+      --mode)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_mode="$optarg"
+case $optarg in
+  # Valid mode arguments:
+  clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+  # Catch anything else as an error
+  *) func_error "invalid argument for $opt"
+     exit_cmd=exit
+     break
+     ;;
+esac
+			shift
+			;;
+      --no-silent|--no-quiet)
+			opt_silent=false
+func_append preserve_args " $opt"
+			;;
+      --no-verbose)
+			opt_verbose=false
+func_append preserve_args " $opt"
+			;;
+      --silent|--quiet)
+			opt_silent=:
+func_append preserve_args " $opt"
+        opt_verbose=false
+			;;
+      --verbose|-v)
+			opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+			;;
+      --tag)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+			shift
+			;;
+
+      -\?|-h)		func_usage				;;
+      --help)		func_help				;;
+      --version)	func_version				;;
+
+      # Separate optargs to long options:
+      --*=*)
+			func_split_long_opt "$opt"
+			set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      # Separate non-argument short options:
+      -\?*|-h*|-n*|-v*)
+			func_split_short_opt "$opt"
+			set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      --)		break					;;
+      -*)		func_fatal_help "unrecognized option \`$opt'" ;;
+      *)		set dummy "$opt" ${1+"$@"};	shift; break  ;;
+    esac
+  done
+
+  # Validate options:
+
+  # save first non-option argument
+  if test "$#" -gt 0; then
+    nonopt="$opt"
+    shift
+  fi
+
+  # preserve --debug
+  test "$opt_debug" = : || func_append preserve_args " --debug"
+
+  case $host in
+    *cygwin* | *mingw* | *pw32* | *cegcc*)
+      # don't eliminate duplications in $postdeps and $predeps
+      opt_duplicate_compiler_generated_deps=:
+      ;;
+    *)
+      opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+      ;;
+  esac
+
+  $opt_help || {
+    # Sanity checks first:
+    func_check_version_match
+
+    if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+      func_fatal_configuration "not configured to build any kind of library"
+    fi
+
+    # Darwin sucks
+    eval std_shrext=\"$shrext_cmds\"
+
+    # Only execute mode is allowed to have -dlopen flags.
+    if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+      func_error "unrecognized option \`-dlopen'"
+      $ECHO "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Change the help message to a mode-specific one.
+    generic_help="$help"
+    help="Try \`$progname --help --mode=$opt_mode' for more information."
+  }
+
+
+  # Bail if the options were screwed
+  $exit_cmd $EXIT_FAILURE
+}
+
+
+
+
+## ----------- ##
+##    Main.    ##
+## ----------- ##
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+    test -f "$1" &&
+      $SED -e 4q "$1" 2>/dev/null \
+        | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs.  To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway.  Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+    lalib_p=no
+    if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+	for lalib_p_l in 1 2 3 4
+	do
+	    read lalib_p_line
+	    case "$lalib_p_line" in
+		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+	    esac
+	done
+	exec 0<&5 5<&-
+    fi
+    test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+    func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+    func_ltwrapper_exec_suffix=
+    case $1 in
+    *.exe) ;;
+    *) func_ltwrapper_exec_suffix=.exe ;;
+    esac
+    $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+    func_dirname_and_basename "$1" "" "."
+    func_stripname '' '.exe' "$func_basename_result"
+    func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+    func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+    $opt_debug
+    save_ifs=$IFS; IFS='~'
+    for cmd in $1; do
+      IFS=$save_ifs
+      eval cmd=\"$cmd\"
+      func_show_eval "$cmd" "${2-:}"
+    done
+    IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)!  Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+    $opt_debug
+    case $1 in
+    */* | *\\*)	. "$1" ;;
+    *)		. "./$1" ;;
+    esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot.  Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+  func_resolve_sysroot_result=$1
+  case $func_resolve_sysroot_result in
+  =*)
+    func_stripname '=' '' "$func_resolve_sysroot_result"
+    func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+    ;;
+  esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+  case "$lt_sysroot:$1" in
+  ?*:"$lt_sysroot"*)
+    func_stripname "$lt_sysroot" '' "$1"
+    func_replace_sysroot_result="=$func_stripname_result"
+    ;;
+  *)
+    # Including no sysroot.
+    func_replace_sysroot_result=$1
+    ;;
+  esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    $opt_debug
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+	func_append_quoted CC_quoted "$arg"
+      done
+      CC_expanded=`func_echo_all $CC`
+      CC_quoted_expanded=`func_echo_all $CC_quoted`
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+      " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+	for z in $available_tags; do
+	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+	    # Evaluate the configuration.
+	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    CC_quoted=
+	    for arg in $CC; do
+	      # Double-quote args containing other shell metacharacters.
+	      func_append_quoted CC_quoted "$arg"
+	    done
+	    CC_expanded=`func_echo_all $CC`
+	    CC_quoted_expanded=`func_echo_all $CC_quoted`
+	    case "$@ " in
+	    " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+	    " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+	      # The compiler in the base compile command matches
+	      # the one in the tagged configuration.
+	      # Assume this is the tagged configuration we want.
+	      tagname=$z
+	      break
+	      ;;
+	    esac
+	  fi
+	done
+	# If $tagname still isn't set, then no tagged configuration
+	# was found and let the user know that the "--tag" command
+	# line option must be used.
+	if test -z "$tagname"; then
+	  func_echo "unable to infer tagged configuration"
+	  func_fatal_error "specify a tag with \`--tag'"
+#	else
+#	  func_verbose "using $tagname tagged configuration"
+	fi
+	;;
+      esac
+    fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+    write_libobj=${1}
+    if test "$build_libtool_libs" = yes; then
+      write_lobj=\'${2}\'
+    else
+      write_lobj=none
+    fi
+
+    if test "$build_old_libs" = yes; then
+      write_oldobj=\'${3}\'
+    else
+      write_oldobj=none
+    fi
+
+    $opt_dry_run || {
+      cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+      $MV "${write_libobj}T" "${write_libobj}"
+    }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+  $opt_debug
+  func_convert_core_file_wine_to_w32_result="$1"
+  if test -n "$1"; then
+    # Unfortunately, winepath does not exit with a non-zero error code, so we
+    # are forced to check the contents of stdout. On the other hand, if the
+    # command is not found, the shell will set an exit code of 127 and print
+    # *an error message* to stdout. So we must check for both error code of
+    # zero AND non-empty stdout, which explains the odd construction:
+    func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+    if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+      func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+        $SED -e "$lt_sed_naive_backslashify"`
+    else
+      func_convert_core_file_wine_to_w32_result=
+    fi
+  fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+  $opt_debug
+  # unfortunately, winepath doesn't convert paths, only file names
+  func_convert_core_path_wine_to_w32_result=""
+  if test -n "$1"; then
+    oldIFS=$IFS
+    IFS=:
+    for func_convert_core_path_wine_to_w32_f in $1; do
+      IFS=$oldIFS
+      func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+      if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+        if test -z "$func_convert_core_path_wine_to_w32_result"; then
+          func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+        else
+          func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+        fi
+      fi
+    done
+    IFS=$oldIFS
+  fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+  $opt_debug
+  if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+    func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+    if test "$?" -ne 0; then
+      # on failure, ensure result is empty
+      func_cygpath_result=
+    fi
+  else
+    func_cygpath_result=
+    func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+  fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format.  Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+  $opt_debug
+  # awkward: cmd appends spaces to result
+  func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+    $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+  $opt_debug
+  if test -z "$2" && test -n "$1" ; then
+    func_error "Could not determine host file name corresponding to"
+    func_error "  \`$1'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback:
+    func_to_host_file_result="$1"
+  fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+  $opt_debug
+  if test -z "$4" && test -n "$3"; then
+    func_error "Could not determine the host path corresponding to"
+    func_error "  \`$3'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback.  This is a deliberately simplistic "conversion" and
+    # should not be "improved".  See libtool.info.
+    if test "x$1" != "x$2"; then
+      lt_replace_pathsep_chars="s|$1|$2|g"
+      func_to_host_path_result=`echo "$3" |
+        $SED -e "$lt_replace_pathsep_chars"`
+    else
+      func_to_host_path_result="$3"
+    fi
+  fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+  $opt_debug
+  case $4 in
+  $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+    ;;
+  esac
+  case $4 in
+  $2 ) func_append func_to_host_path_result "$3"
+    ;;
+  esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+  $opt_debug
+  $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result.  If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+  $opt_debug
+  case ,$2, in
+    *,"$to_tool_file_cmd",*)
+      func_to_tool_file_result=$1
+      ;;
+    *)
+      $to_tool_file_cmd "$1"
+      func_to_tool_file_result=$func_to_host_file_result
+      ;;
+  esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+  func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+    # LT_CYGPATH in this case.
+    func_to_host_file_result=`cygpath -m "$1"`
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format.  Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_file_wine_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_msys_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set.  Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+    func_convert_core_file_wine_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format.  If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+#   file name conversion function    : func_convert_file_X_to_Y ()
+#   path conversion function         : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same.  If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+  $opt_debug
+  if test -z "$to_host_path_cmd"; then
+    func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+    to_host_path_cmd="func_convert_path_${func_stripname_result}"
+  fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+  $opt_debug
+  func_init_to_host_path_cmd
+  $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+  func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from ARG.  MSYS
+    # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+    # and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_msys_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format.  Requires a wine environment and
+# a working winepath.  Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set.  Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+    $opt_debug
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+    pie_flag=
+
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+	# do not "continue".  Instead, add this to base_compile
+	lastarg="$arg"
+	arg_mode=normal
+	;;
+
+      target )
+	libobj="$arg"
+	arg_mode=normal
+	continue
+	;;
+
+      normal )
+	# Accept any command-line options.
+	case $arg in
+	-o)
+	  test -n "$libobj" && \
+	    func_fatal_error "you cannot specify \`-o' more than once"
+	  arg_mode=target
+	  continue
+	  ;;
+
+	-pie | -fpie | -fPIE)
+          func_append pie_flag " $arg"
+	  continue
+	  ;;
+
+	-shared | -static | -prefer-pic | -prefer-non-pic)
+	  func_append later " $arg"
+	  continue
+	  ;;
+
+	-no-suppress)
+	  suppress_opt=no
+	  continue
+	  ;;
+
+	-Xcompiler)
+	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
+	  continue      #  The current "srcfile" will either be retained or
+	  ;;            #  replaced later.  I would guess that would be a bug.
+
+	-Wc,*)
+	  func_stripname '-Wc,' '' "$arg"
+	  args=$func_stripname_result
+	  lastarg=
+	  save_ifs="$IFS"; IFS=','
+	  for arg in $args; do
+	    IFS="$save_ifs"
+	    func_append_quoted lastarg "$arg"
+	  done
+	  IFS="$save_ifs"
+	  func_stripname ' ' '' "$lastarg"
+	  lastarg=$func_stripname_result
+
+	  # Add the arguments to base_compile.
+	  func_append base_compile " $lastarg"
+	  continue
+	  ;;
+
+	*)
+	  # Accept the current argument as the source file.
+	  # The previous "srcfile" becomes the current argument.
+	  #
+	  lastarg="$srcfile"
+	  srcfile="$arg"
+	  ;;
+	esac  #  case $arg
+	;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      func_append_quoted base_compile "$lastarg"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      func_fatal_error "you must specify an argument for -Xcompile"
+      ;;
+    target)
+      func_fatal_error "you must specify a target with \`-o'"
+      ;;
+    *)
+      # Get the name of the library object.
+      test -z "$libobj" && {
+	func_basename "$srcfile"
+	libobj="$func_basename_result"
+      }
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    case $libobj in
+    *.[cCFSifmso] | \
+    *.ada | *.adb | *.ads | *.asm | \
+    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+    *.[fF][09]? | *.for | *.java | *.obj | *.sx | *.cu | *.cup)
+      func_xform "$libobj"
+      libobj=$func_xform_result
+      ;;
+    esac
+
+    case $libobj in
+    *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+    *)
+      func_fatal_error "cannot determine name of library object from \`$libobj'"
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
+	continue
+	;;
+
+      -static)
+	build_libtool_libs=no
+	build_old_libs=yes
+	continue
+	;;
+
+      -prefer-pic)
+	pic_mode=yes
+	continue
+	;;
+
+      -prefer-non-pic)
+	pic_mode=no
+	continue
+	;;
+      esac
+    done
+
+    func_quote_for_eval "$libobj"
+    test "X$libobj" != "X$func_quote_for_eval_result" \
+      && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
+      && func_warning "libobj name \`$libobj' may not contain shell special characters."
+    func_dirname_and_basename "$obj" "/" ""
+    objname="$func_basename_result"
+    xdir="$func_dirname_result"
+    lobj=${xdir}$objdir/$objname
+
+    test -z "$base_compile" && \
+      func_fatal_help "you must specify a compilation command"
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2* | cegcc*)
+      pic_mode=default
+      ;;
+    esac
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+	$ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+      func_append removelist " $output_obj"
+      $ECHO "$srcfile" > "$lockfile"
+    fi
+
+    $opt_dry_run || $RM $removelist
+    func_append removelist " $lockfile"
+    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+    func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+    srcfile=$func_to_tool_file_result
+    func_quote_for_eval "$srcfile"
+    qsrcfile=$func_quote_for_eval_result
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test "$pic_mode" != no; then
+	command="$base_compile $qsrcfile $pic_flag"
+      else
+	# Don't build PIC code
+	command="$base_compile $qsrcfile"
+      fi
+
+      func_mkdir_p "$xdir$objdir"
+
+      if test -z "$output_obj"; then
+	# Place PIC objects in $objdir
+	func_append command " -o $lobj"
+      fi
+
+      func_show_eval_locale "$command"	\
+          'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+	func_show_eval '$MV "$output_obj" "$lobj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+
+      # Allow error messages only from the first compilation.
+      if test "$suppress_opt" = yes; then
+	suppress_output=' >/dev/null 2>&1'
+      fi
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+	# Don't build PIC code
+	command="$base_compile $qsrcfile$pie_flag"
+      else
+	command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+	func_append command " -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      func_append command "$suppress_output"
+      func_show_eval_locale "$command" \
+        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+	func_show_eval '$MV "$output_obj" "$obj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+    fi
+
+    $opt_dry_run || {
+      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+      # Unlock the critical section if it was locked
+      if test "$need_locks" != no; then
+	removelist=$lockfile
+        $RM "$lockfile"
+      fi
+    }
+
+    exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+  test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+    # We need to display help for each of the modes.
+    case $opt_mode in
+      "")
+        # Generic help is extracted from the usage comments
+        # at the start of this file.
+        func_help
+        ;;
+
+      clean)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      compile)
+      $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -no-suppress      do not suppress compiler output for multiple passes
+  -prefer-pic       try to build PIC objects only
+  -prefer-non-pic   try to build non-PIC objects only
+  -shared           do not build a \`.o' file suitable for static linking
+  -static           only build a \`.o' file suitable for static linking
+  -Wc,FLAG          pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+        ;;
+
+      execute)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+        ;;
+
+      finish)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+        ;;
+
+      install)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+  -inst-prefix-dir PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+        ;;
+
+      link)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -bindir BINDIR    specify path to binaries directory (for systems where
+                    libraries must be found in the PATH setting at runtime)
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -shared           only do dynamic linking of libtool libraries
+  -shrext SUFFIX    override the standard shared library file extension
+  -static           do not do any dynamic linking of uninstalled libtool libraries
+  -static-libtool-libs
+                    do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+  -weak LIBNAME     declare that the target provides the LIBNAME interface
+  -Wc,FLAG
+  -Xcompiler FLAG   pass linker-specific FLAG directly to the compiler
+  -Wl,FLAG
+  -Xlinker FLAG     pass linker-specific FLAG directly to the linker
+  -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+        ;;
+
+      uninstall)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      *)
+        func_fatal_help "invalid operation mode \`$opt_mode'"
+        ;;
+    esac
+
+    echo
+    $ECHO "Try \`$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+  if test "$opt_help" = :; then
+    func_mode_help
+  else
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	func_mode_help
+      done
+    } | sed -n '1p; 2,$s/^Usage:/  or: /p'
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	echo
+	func_mode_help
+      done
+    } |
+    sed '1d
+      /^When reporting/,/^Report/{
+	H
+	d
+      }
+      $x
+      /information about other modes/d
+      /more detailed .*MODE/d
+      s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+  fi
+  exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+    $opt_debug
+    # The first argument is the command name.
+    cmd="$nonopt"
+    test -z "$cmd" && \
+      func_fatal_help "you must specify a COMMAND"
+
+    # Handle -dlopen flags immediately.
+    for file in $opt_dlopen; do
+      test -f "$file" \
+	|| func_fatal_help "\`$file' is not a file"
+
+      dir=
+      case $file in
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+	func_source "$file"
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && \
+	    func_warning "\`$file' was not linked with \`-export-dynamic'"
+	  continue
+	fi
+
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  func_append dir "/$objdir"
+	else
+	  if test ! -f "$dir/$dlname"; then
+	    func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+	  fi
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
+	;;
+
+      *)
+	func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+	continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -* | *.la | *.lo ) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if func_ltwrapper_script_p "$file"; then
+	  func_source "$file"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	elif func_ltwrapper_executable_p "$file"; then
+	  func_ltwrapper_scriptname "$file"
+	  func_source "$func_ltwrapper_scriptname_result"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      func_append_quoted args "$file"
+    done
+
+    if test "X$opt_dry_run" = Xfalse; then
+      if test -n "$shlibpath_var"; then
+	# Export the shlibpath_var.
+	eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+      do
+	eval "if test \"\${save_$lt_var+set}\" = set; then
+                $lt_var=\$save_$lt_var; export $lt_var
+	      else
+		$lt_unset $lt_var
+	      fi"
+      done
+
+      # Now prepare to actually exec the command.
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+	echo "export $shlibpath_var"
+      fi
+      $ECHO "$cmd$args"
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+    $opt_debug
+    libs=
+    libdirs=
+    admincmds=
+
+    for opt in "$nonopt" ${1+"$@"}
+    do
+      if test -d "$opt"; then
+	func_append libdirs " $opt"
+
+      elif test -f "$opt"; then
+	if func_lalib_unsafe_p "$opt"; then
+	  func_append libs " $opt"
+	else
+	  func_warning "\`$opt' is not a valid libtool archive"
+	fi
+
+      else
+	func_fatal_error "invalid argument \`$opt'"
+      fi
+    done
+
+    if test -n "$libs"; then
+      if test -n "$lt_sysroot"; then
+        sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+        sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+      else
+        sysroot_cmd=
+      fi
+
+      # Remove sysroot references
+      if $opt_dry_run; then
+        for lib in $libs; do
+          echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+        done
+      else
+        tmpdir=`func_mktempdir`
+        for lib in $libs; do
+	  sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+	    > $tmpdir/tmp-la
+	  mv -f $tmpdir/tmp-la $lib
+	done
+        ${RM}r "$tmpdir"
+      fi
+    fi
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $opt_dry_run || eval "$cmds" || func_append admincmds "
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    $opt_silent && exit $EXIT_SUCCESS
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      echo "----------------------------------------------------------------------"
+      echo "Libraries have been installed in:"
+      for libdir in $libdirs; do
+	$ECHO "   $libdir"
+      done
+      echo
+      echo "If you ever happen to want to link against installed libraries"
+      echo "in a given directory, LIBDIR, you must either use libtool, and"
+      echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+      echo "flag during linking and do at least one of the following:"
+      if test -n "$shlibpath_var"; then
+	echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+	echo "     during execution"
+      fi
+      if test -n "$runpath_var"; then
+	echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+	echo "     during linking"
+      fi
+      if test -n "$hardcode_libdir_flag_spec"; then
+	libdir=LIBDIR
+	eval flag=\"$hardcode_libdir_flag_spec\"
+
+	$ECHO "   - use the \`$flag' linker flag"
+      fi
+      if test -n "$admincmds"; then
+	$ECHO "   - have your system administrator run these commands:$admincmds"
+      fi
+      if test -f /etc/ld.so.conf; then
+	echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+      fi
+      echo
+
+      echo "See any operating system documentation about shared libraries for"
+      case $host in
+	solaris2.[6789]|solaris2.1[0-9])
+	  echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+	  echo "pages."
+	  ;;
+	*)
+	  echo "more information, such as the ld(1) and ld.so(8) manual pages."
+	  ;;
+      esac
+      echo "----------------------------------------------------------------------"
+    fi
+    exit $EXIT_SUCCESS
+}
+
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+    $opt_debug
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+       # Allow the use of GNU shtool's install command.
+       case $nonopt in *shtool*) :;; *) false;; esac; then
+      # Aesthetically quote it.
+      func_quote_for_eval "$nonopt"
+      install_prog="$func_quote_for_eval_result "
+      arg=$1
+      shift
+    else
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    func_quote_for_eval "$arg"
+    func_append install_prog "$func_quote_for_eval_result"
+    install_shared_prog=$install_prog
+    case " $install_prog " in
+      *[\\\ /]cp\ *) install_cp=: ;;
+      *) install_cp=false ;;
+    esac
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    no_mode=:
+    for arg
+    do
+      arg2=
+      if test -n "$dest"; then
+	func_append files " $dest"
+	dest=$arg
+	continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f)
+	if $install_cp; then :; else
+	  prev=$arg
+	fi
+	;;
+      -g | -m | -o)
+	prev=$arg
+	;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*)
+	;;
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  if test "x$prev" = x-m && test -n "$install_override_mode"; then
+	    arg2=$install_override_mode
+	    no_mode=false
+	  fi
+	  prev=
+	else
+	  dest=$arg
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      func_quote_for_eval "$arg"
+      func_append install_prog " $func_quote_for_eval_result"
+      if test -n "$arg2"; then
+	func_quote_for_eval "$arg2"
+      fi
+      func_append install_shared_prog " $func_quote_for_eval_result"
+    done
+
+    test -z "$install_prog" && \
+      func_fatal_help "you must specify an install program"
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prev' option requires an argument"
+
+    if test -n "$install_override_mode" && $no_mode; then
+      if $install_cp; then :; else
+	func_quote_for_eval "$install_override_mode"
+	func_append install_shared_prog " -m $func_quote_for_eval_result"
+      fi
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	func_fatal_help "no file or destination specified"
+      else
+	func_fatal_help "you must specify a destination"
+      fi
+    fi
+
+    # Strip any trailing slash from the destination.
+    func_stripname '' '/' "$dest"
+    dest=$func_stripname_result
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      func_dirname_and_basename "$dest" "" "."
+      destdir="$func_dirname_result"
+      destname="$func_basename_result"
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files; shift
+      test "$#" -gt 1 && \
+	func_fatal_help "\`$dest' is not a directory"
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case $file in
+	*.lo) ;;
+	*)
+	  func_fatal_help "\`$destdir' must be an absolute directory name"
+	  ;;
+	esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+	# Do the static libraries later.
+	func_append staticlibs " $file"
+	;;
+
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$file' is not a valid libtool archive"
+
+	library_names=
+	old_library=
+	relink_command=
+	func_source "$file"
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append current_libdirs " $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append future_libdirs " $libdir" ;;
+	  esac
+	fi
+
+	func_dirname "$file" "/" ""
+	dir="$func_dirname_result"
+	func_append dir "$objdir"
+
+	if test -n "$relink_command"; then
+	  # Determine the prefix the user has applied to our future dir.
+	  inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+	  # Don't allow the user to place us outside of our expected
+	  # location b/c this prevents finding dependent libraries that
+	  # are installed to the same prefix.
+	  # At present, this check doesn't affect windows .dll's that
+	  # are installed into $libdir/../bin (currently, that works fine)
+	  # but it's something to keep an eye on.
+	  test "$inst_prefix_dir" = "$destdir" && \
+	    func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+	  if test -n "$inst_prefix_dir"; then
+	    # Stick the inst_prefix_dir data into the link command.
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+	  else
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+	  fi
+
+	  func_warning "relinking \`$file'"
+	  func_show_eval "$relink_command" \
+	    'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+	fi
+
+	# See the names of the shared library.
+	set dummy $library_names; shift
+	if test -n "$1"; then
+	  realname="$1"
+	  shift
+
+	  srcname="$realname"
+	  test -n "$relink_command" && srcname="$realname"T
+
+	  # Install the shared library and build the symlinks.
+	  func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+	      'exit $?'
+	  tstripme="$stripme"
+	  case $host_os in
+	  cygwin* | mingw* | pw32* | cegcc*)
+	    case $realname in
+	    *.dll.a)
+	      tstripme=""
+	      ;;
+	    esac
+	    ;;
+	  esac
+	  if test -n "$tstripme" && test -n "$striplib"; then
+	    func_show_eval "$striplib $destdir/$realname" 'exit $?'
+	  fi
+
+	  if test "$#" -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    # Try `ln -sf' first, because the `ln' binary might depend on
+	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
+	    # so we also need to try rm && ln -s.
+	    for linkname
+	    do
+	      test "$linkname" != "$realname" \
+		&& func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+	    done
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib="$destdir/$realname"
+	  func_execute_cmds "$postinstall_cmds" 'exit $?'
+	fi
+
+	# Install the pseudo-library for information purposes.
+	func_basename "$file"
+	name="$func_basename_result"
+	instname="$dir/$name"i
+	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case $destfile in
+	*.lo)
+	  func_lo2o "$destfile"
+	  staticdest=$func_lo2o_result
+	  ;;
+	*.$objext)
+	  staticdest="$destfile"
+	  destfile=
+	  ;;
+	*)
+	  func_fatal_help "cannot copy a libtool object to \`$destfile'"
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	test -n "$destfile" && \
+	  func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+	# Install the old object if enabled.
+	if test "$build_old_libs" = yes; then
+	  # Deduce the name of the old-style object file.
+	  func_lo2o "$file"
+	  staticobj=$func_lo2o_result
+	  func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+	fi
+	exit $EXIT_SUCCESS
+	;;
+
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
+	fi
+
+	# If the file is missing, and there is a .exe on the end, strip it
+	# because it is most likely a libtool script we actually want to
+	# install
+	stripped_ext=""
+	case $file in
+	  *.exe)
+	    if test ! -f "$file"; then
+	      func_stripname '' '.exe' "$file"
+	      file=$func_stripname_result
+	      stripped_ext=".exe"
+	    fi
+	    ;;
+	esac
+
+	# Do a test to see if this is really a libtool program.
+	case $host in
+	*cygwin* | *mingw*)
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      wrapper=$func_ltwrapper_scriptname_result
+	    else
+	      func_stripname '' '.exe' "$file"
+	      wrapper=$func_stripname_result
+	    fi
+	    ;;
+	*)
+	    wrapper=$file
+	    ;;
+	esac
+	if func_ltwrapper_script_p "$wrapper"; then
+	  notinst_deplibs=
+	  relink_command=
+
+	  func_source "$wrapper"
+
+	  # Check the variables that should have been set.
+	  test -z "$generated_by_libtool_version" && \
+	    func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+	  finalize=yes
+	  for lib in $notinst_deplibs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      func_source "$lib"
+	    fi
+	    libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      func_warning "\`$lib' has not been installed in \`$libdir'"
+	      finalize=no
+	    fi
+	  done
+
+	  relink_command=
+	  func_source "$wrapper"
+
+	  outputname=
+	  if test "$fast_install" = no && test -n "$relink_command"; then
+	    $opt_dry_run || {
+	      if test "$finalize" = yes; then
+	        tmpdir=`func_mktempdir`
+		func_basename "$file$stripped_ext"
+		file="$func_basename_result"
+	        outputname="$tmpdir/$file"
+	        # Replace the output file specification.
+	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+	        $opt_silent || {
+	          func_quote_for_expand "$relink_command"
+		  eval "func_echo $func_quote_for_expand_result"
+	        }
+	        if eval "$relink_command"; then :
+	          else
+		  func_error "error: relink \`$file' with the above command before installing it"
+		  $opt_dry_run || ${RM}r "$tmpdir"
+		  continue
+	        fi
+	        file="$outputname"
+	      else
+	        func_warning "cannot relink \`$file'"
+	      fi
+	    }
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
+	fi
+
+	# remove .exe since cygwin /usr/bin/install will append another
+	# one anyway
+	case $install_prog,$host in
+	*/usr/bin/install*,*cygwin*)
+	  case $file:$destfile in
+	  *.exe:*.exe)
+	    # this is ok
+	    ;;
+	  *.exe:*)
+	    destfile=$destfile.exe
+	    ;;
+	  *:*.exe)
+	    func_stripname '' '.exe' "$destfile"
+	    destfile=$func_stripname_result
+	    ;;
+	  esac
+	  ;;
+	esac
+	func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+	$opt_dry_run || if test -n "$outputname"; then
+	  ${RM}r "$tmpdir"
+	fi
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      func_basename "$file"
+      name="$func_basename_result"
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+	func_show_eval "$old_striplib $oldlib" 'exit $?'
+      fi
+
+      # Do each command in the postinstall commands.
+      func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+    done
+
+    test -n "$future_libdirs" && \
+      func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      $opt_dry_run && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+    $opt_debug
+    my_outputname="$1"
+    my_originator="$2"
+    my_pic_p="${3-no}"
+    my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+    my_dlsyms=
+
+    if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+      if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	my_dlsyms="${my_outputname}S.c"
+      else
+	func_error "not configured to extract global symbols from dlpreopened files"
+      fi
+    fi
+
+    if test -n "$my_dlsyms"; then
+      case $my_dlsyms in
+      "") ;;
+      *.c)
+	# Discover the nlist of each of the dlfiles.
+	nlist="$output_objdir/${my_outputname}.nm"
+
+	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+	# Parse the name list into a source file.
+	func_verbose "creating $output_objdir/$my_dlsyms"
+
+	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+	if test "$dlself" = yes; then
+	  func_verbose "generating symbol list for \`$output'"
+
+	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+	  # Add our own program objects to the symbol list.
+	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	  for progfile in $progfiles; do
+	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+	    func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -n "$exclude_expsyms"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  if test -n "$export_symbols_regex"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  # Prepare the list of exported symbols
+	  if test -z "$export_symbols"; then
+	    export_symbols="$output_objdir/$outputname.exp"
+	    $opt_dry_run || {
+	      $RM $export_symbols
+	      eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	      case $host in
+	      *cygwin* | *mingw* | *cegcc* )
+                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+	        ;;
+	      esac
+	    }
+	  else
+	    $opt_dry_run || {
+	      eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	      case $host in
+	        *cygwin* | *mingw* | *cegcc* )
+	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+	          ;;
+	      esac
+	    }
+	  fi
+	fi
+
+	for dlprefile in $dlprefiles; do
+	  func_verbose "extracting global C symbols from \`$dlprefile'"
+	  func_basename "$dlprefile"
+	  name="$func_basename_result"
+          case $host in
+	    *cygwin* | *mingw* | *cegcc* )
+	      # if an import library, we need to obtain dlname
+	      if func_win32_import_lib_p "$dlprefile"; then
+	        func_tr_sh "$dlprefile"
+	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
+	        dlprefile_dlbasename=""
+	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+	          # Use subshell, to avoid clobbering current variable values
+	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+	          if test -n "$dlprefile_dlname" ; then
+	            func_basename "$dlprefile_dlname"
+	            dlprefile_dlbasename="$func_basename_result"
+	          else
+	            # no lafile. user explicitly requested -dlpreopen <import library>.
+	            $sharedlib_from_linklib_cmd "$dlprefile"
+	            dlprefile_dlbasename=$sharedlib_from_linklib_result
+	          fi
+	        fi
+	        $opt_dry_run || {
+	          if test -n "$dlprefile_dlbasename" ; then
+	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+	          else
+	            func_warning "Could not compute DLL name from $name"
+	            eval '$ECHO ": $name " >> "$nlist"'
+	          fi
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+	            $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+	        }
+	      else # not an import lib
+	        $opt_dry_run || {
+	          eval '$ECHO ": $name " >> "$nlist"'
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	        }
+	      fi
+	    ;;
+	    *)
+	      $opt_dry_run || {
+	        eval '$ECHO ": $name " >> "$nlist"'
+	        func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	        eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	      }
+	    ;;
+          esac
+	done
+
+	$opt_dry_run || {
+	  # Make sure we have at least an empty file.
+	  test -f "$nlist" || : > "$nlist"
+
+	  if test -n "$exclude_expsyms"; then
+	    $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	    $MV "$nlist"T "$nlist"
+	  fi
+
+	  # Try sorting and uniquifying the output.
+	  if $GREP -v "^: " < "$nlist" |
+	      if sort -k 3 </dev/null >/dev/null 2>&1; then
+		sort -k 3
+	      else
+		sort +2
+	      fi |
+	      uniq > "$nlist"S; then
+	    :
+	  else
+	    $GREP -v "^: " < "$nlist" > "$nlist"S
+	  fi
+
+	  if test -f "$nlist"S; then
+	    eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+	  else
+	    echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+	  fi
+
+	  echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols.  */
+typedef struct {
+  const char *name;
+  void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+  { \"$my_originator\", (void *) 0 },"
+
+	  case $need_lib_prefix in
+	  no)
+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  *)
+	    eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  esac
+	  echo >> "$output_objdir/$my_dlsyms" "\
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	} # !$opt_dry_run
+
+	pic_flag_for_symtable=
+	case "$compile_command " in
+	*" -static "*) ;;
+	*)
+	  case $host in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+	    pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+	  *-*-hpux*)
+	    pic_flag_for_symtable=" $pic_flag"  ;;
+	  *)
+	    if test "X$my_pic_p" != Xno; then
+	      pic_flag_for_symtable=" $pic_flag"
+	    fi
+	    ;;
+	  esac
+	  ;;
+	esac
+	symtab_cflags=
+	for arg in $LTCFLAGS; do
+	  case $arg in
+	  -pie | -fpie | -fPIE) ;;
+	  *) func_append symtab_cflags " $arg" ;;
+	  esac
+	done
+
+	# Now compile the dynamic symbol file.
+	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+	# Clean up the generated files.
+	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+	# Transform the symbol file into the correct name.
+	symfileobj="$output_objdir/${my_outputname}S.$objext"
+	case $host in
+	*cygwin* | *mingw* | *cegcc* )
+	  if test -f "$output_objdir/$my_outputname.def"; then
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	  else
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  fi
+	  ;;
+	*)
+	  compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  ;;
+	esac
+	;;
+      *)
+	func_fatal_error "unknown suffix for \`$my_dlsyms'"
+	;;
+      esac
+    else
+      # We keep going just in case the user didn't refer to
+      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+      # really was required.
+
+      # Nullify the symbol file.
+      compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+      finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+    fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+  $opt_debug
+  win32_libid_type="unknown"
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+      func_to_tool_file "$1" func_convert_file_msys_to_w32
+      win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+	$SED -n -e '
+	    1,100{
+		/ I /{
+		    s,.*,import,
+		    p
+		    q
+		}
+	    }'`
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+  $opt_debug
+  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+  $opt_debug
+  match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+  $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+    $SED '/^Contents of section '"$match_literal"':/{
+      # Place marker at beginning of archive member dllname section
+      s/.*/====MARK====/
+      p
+      d
+    }
+    # These lines can sometimes be longer than 43 characters, but
+    # are always uninteresting
+    /:[	 ]*file format pe[i]\{,1\}-/d
+    /^In archive [^:]*:/d
+    # Ensure marker is printed
+    /^====MARK====/p
+    # Remove all lines with less than 43 characters
+    /^.\{43\}/!d
+    # From remaining lines, remove first 43 characters
+    s/^.\{43\}//' |
+    $SED -n '
+      # Join marker and all lines until next marker into a single line
+      /^====MARK====/ b para
+      H
+      $ b para
+      b
+      :para
+      x
+      s/\n//g
+      # Remove the marker
+      s/^====MARK====//
+      # Remove trailing dots and whitespace
+      s/[\. \t]*$//
+      # Print
+      /./p' |
+    # we now have a list, one entry per line, of the stringified
+    # contents of the appropriate section of all members of the
+    # archive which possess that section. Heuristic: eliminate
+    # all those which have a first or second character that is
+    # a '.' (that is, objdump's representation of an unprintable
+    # character.) This should work for all archives with less than
+    # 0x302f exports -- but will fail for DLLs whose name actually
+    # begins with a literal '.' or a single character followed by
+    # a '.'.
+    #
+    # Of those that remain, print the first one.
+    $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+  test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+  test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+  $opt_debug
+  if func_cygming_gnu_implib_p "$1" ; then
+    # binutils import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+  elif func_cygming_ms_implib_p "$1" ; then
+    # ms-generated import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+  else
+    # unknown
+    sharedlib_from_linklib_result=""
+  fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    $opt_debug
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+    if test "$lock_old_archive_extraction" = yes; then
+      lockfile=$f_ex_an_ar_oldlib.lock
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    fi
+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+		   'stat=$?; rm -f "$lockfile"; exit $stat'
+    if test "$lock_old_archive_extraction" = yes; then
+      $opt_dry_run || rm -f "$lockfile"
+    fi
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+    fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    $opt_debug
+    my_gentop="$1"; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+	*) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      func_basename "$my_xlib"
+      my_xlib="$func_basename_result"
+      my_xlib_u=$my_xlib
+      while :; do
+        case " $extracted_archives " in
+	*" $my_xlib_u "*)
+	  func_arith $extracted_serial + 1
+	  extracted_serial=$func_arith_result
+	  my_xlib_u=lt$extracted_serial-$my_xlib ;;
+	*) break ;;
+	esac
+      done
+      extracted_archives="$extracted_archives $my_xlib_u"
+      my_xdir="$my_gentop/$my_xlib_u"
+
+      func_mkdir_p "$my_xdir"
+
+      case $host in
+      *-darwin*)
+	func_verbose "Extracting $my_xabs"
+	# Do not bother doing anything if just a dry run
+	$opt_dry_run || {
+	  darwin_orig_dir=`pwd`
+	  cd $my_xdir || exit $?
+	  darwin_archive=$my_xabs
+	  darwin_curdir=`pwd`
+	  darwin_base_archive=`basename "$darwin_archive"`
+	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+	  if test -n "$darwin_arches"; then
+	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+	    darwin_arch=
+	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+	    for darwin_arch in  $darwin_arches ; do
+	      func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+	      cd "$darwin_curdir"
+	      $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+	    done # $darwin_arches
+            ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+	    darwin_file=
+	    darwin_files=
+	    for darwin_file in $darwin_filelist; do
+	      darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+	      $LIPO -create -output "$darwin_file" $darwin_files
+	    done # $darwin_filelist
+	    $RM -rf unfat-$$
+	    cd "$darwin_orig_dir"
+	  else
+	    cd $darwin_orig_dir
+	    func_extract_an_archive "$my_xdir" "$my_xabs"
+	  fi # $darwin_arches
+	} # !$opt_dry_run
+	;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+	;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+    done
+
+    func_extract_archives_result="$my_oldobjs"
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable.  Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take.  If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory.  This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+	func_emit_wrapper_arg1=${1-no}
+
+	$ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variables:
+  generated_by_libtool_version='$macro_version'
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$ECHO are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    file=\"\$0\""
+
+    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+    $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+    ECHO=\"$qECHO\"
+  fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+  lt_script_arg0=\$0
+  shift
+  for lt_opt
+  do
+    case \"\$lt_opt\" in
+    --lt-debug) lt_option_debug=1 ;;
+    --lt-dump-script)
+        lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+        test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+        lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+        cat \"\$lt_dump_D/\$lt_dump_F\"
+        exit 0
+      ;;
+    --lt-*)
+        \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+        exit 1
+      ;;
+    esac
+  done
+
+  # Print the debug banner immediately:
+  if test -n \"\$lt_option_debug\"; then
+    echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
+  fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+  lt_dump_args_N=1;
+  for lt_arg
+  do
+    \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
+    lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+  done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+  case $host in
+  # Backslashes separate directories on plain windows
+  *-*-mingw | *-*-os2* | *-cegcc*)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+    ;;
+
+  *)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+    ;;
+  esac
+  $ECHO "\
+      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+      exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+  for lt_wr_arg
+  do
+    case \$lt_wr_arg in
+    --lt-*) ;;
+    *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+    esac
+    shift
+  done
+  func_exec_program_core \${1+\"\$@\"}
+}
+
+  # Parse options
+  func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+  done
+
+  # Usually 'no', except on cygwin/mingw when embedded into
+  # the cwrapper.
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+  if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+    # special case for '.'
+    if test \"\$thisdir\" = \".\"; then
+      thisdir=\`pwd\`
+    fi
+    # remove .libs from thisdir
+    case \"\$thisdir\" in
+    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+    $objdir )   thisdir=. ;;
+    esac
+  fi
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test "$fast_install" = yes; then
+	  $ECHO "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" ||
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $MKDIR \"\$progdir\"
+    else
+      $RM \"\$progdir/\$file\"
+    fi"
+
+	  $ECHO "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+	$ECHO \"\$relink_command_output\" >&2
+	$RM \"\$progdir/\$file\"
+	exit 1
+      fi
+    fi
+
+    $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $RM \"\$progdir/\$program\";
+      $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $RM \"\$progdir/\$file\"
+  fi"
+	else
+	  $ECHO "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	$ECHO "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# fixup the dll searchpath if we need to.
+	#
+	# Fix the DLL searchpath if we need to.  Do this before prepending
+	# to shlibpath, because on Windows, both are PATH and uninstalled
+	# libraries must come first.
+	if test -n "$dllsearchpath"; then
+	  $ECHO "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	# Export our shlibpath_var if we have one.
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $ECHO "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	$ECHO "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+      func_exec_program \${1+\"\$@\"}
+    fi
+  else
+    # The program doesn't exist.
+    \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+    \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+    \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+	cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
+
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+*/
+EOF
+	    cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+#  include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* declarations of non-ANSI functions */
+#if defined(__MINGW32__)
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined(__CYGWIN__)
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined (other platforms) ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined(_MSC_VER)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+# define S_IXUSR _S_IEXEC
+# ifndef _INTPTR_T_DEFINED
+#  define _INTPTR_T_DEFINED
+#  define intptr_t int
+# endif
+#elif defined(__MINGW32__)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+#elif defined(__CYGWIN__)
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined (other platforms) ... */
+#endif
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#if defined(LT_DEBUGWRAPPER)
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+	    cat <<EOF
+volatile const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+	    if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+              func_to_host_path "$temp_rpath"
+	      cat <<EOF
+const char * LIB_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * LIB_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test -n "$dllsearchpath"; then
+              func_to_host_path "$dllsearchpath:"
+	      cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test "$fast_install" = yes; then
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+	    else
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+	    fi
+
+
+	    cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX         "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt            = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int  newargc;
+  char *tmp_pathspec;
+  char *actual_cwrapper_path;
+  char *actual_cwrapper_name;
+  char *target_name;
+  char *lt_argv_zero;
+  intptr_t rval = 127;
+
+  int i;
+
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  newargz = XMALLOC (char *, argc + 1);
+
+  /* very simple arg parsing; don't want to rely on getopt
+   * also, copy all non cwrapper options to newargz, except
+   * argz[0], which is handled differently
+   */
+  newargc=0;
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], dumpscript_opt) == 0)
+	{
+EOF
+	    case "$host" in
+	      *mingw* | *cygwin* )
+		# make stdout use "unix" line endings
+		echo "          setmode(1,_O_BINARY);"
+		;;
+	      esac
+
+	    cat <<"EOF"
+	  lt_dump_script (stdout);
+	  return 0;
+	}
+      if (strcmp (argv[i], debug_opt) == 0)
+	{
+          lt_debug = 1;
+          continue;
+	}
+      if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
+        {
+          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+             namespace, but it is not one of the ones we know about and
+             have already dealt with, above (inluding dump-script), then
+             report an error. Otherwise, targets might begin to believe
+             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+             namespace. The first time any user complains about this, we'll
+             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+             or a configure.ac-settable value.
+           */
+          lt_fatal (__FILE__, __LINE__,
+		    "unrecognized %s option: '%s'",
+                    ltwrapper_option_prefix, argv[i]);
+        }
+      /* otherwise ... */
+      newargz[++newargc] = xstrdup (argv[i]);
+    }
+  newargz[++newargc] = NULL;
+
+EOF
+	    cat <<EOF
+  /* The GNU banner must be the first non-error debug message */
+  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
+EOF
+	    cat <<"EOF"
+  lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+  tmp_pathspec = find_executable (argv[0]);
+  if (tmp_pathspec == NULL)
+    lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (before symlink chase) at: %s\n",
+		  tmp_pathspec);
+
+  actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (after symlink chase) at: %s\n",
+		  actual_cwrapper_path);
+  XFREE (tmp_pathspec);
+
+  actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+  strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+  /* wrapper name transforms */
+  strendzap (actual_cwrapper_name, ".exe");
+  tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+  XFREE (actual_cwrapper_name);
+  actual_cwrapper_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  /* target_name transforms -- use actual target program name; might have lt- prefix */
+  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+  strendzap (target_name, ".exe");
+  tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+  XFREE (target_name);
+  target_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(main) libtool target name: %s\n",
+		  target_name);
+EOF
+
+	    cat <<EOF
+  newargz[0] =
+    XMALLOC (char, (strlen (actual_cwrapper_path) +
+		    strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+  strcpy (newargz[0], actual_cwrapper_path);
+  strcat (newargz[0], "$objdir");
+  strcat (newargz[0], "/");
+EOF
+
+	    cat <<"EOF"
+  /* stop here, and copy so we don't have to do this twice */
+  tmp_pathspec = xstrdup (newargz[0]);
+
+  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+  strcat (newargz[0], actual_cwrapper_name);
+
+  /* DO want the lt- prefix here if it exists, so use target_name */
+  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+  XFREE (tmp_pathspec);
+  tmp_pathspec = NULL;
+EOF
+
+	    case $host_os in
+	      mingw*)
+	    cat <<"EOF"
+  {
+    char* p;
+    while ((p = strchr (newargz[0], '\\')) != NULL)
+      {
+	*p = '/';
+      }
+    while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+      {
+	*p = '/';
+      }
+  }
+EOF
+	    ;;
+	    esac
+
+	    cat <<"EOF"
+  XFREE (target_name);
+  XFREE (actual_cwrapper_path);
+  XFREE (actual_cwrapper_name);
+
+  lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+  lt_setenv ("DUALCASE", "1");  /* for MSK sh */
+  /* Update the DLL searchpath.  EXE_PATH_VALUE ($dllsearchpath) must
+     be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+     because on Windows, both *_VARNAMEs are PATH but uninstalled
+     libraries must come first. */
+  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+  lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+		  nonnull (lt_argv_zero));
+  for (i = 0; i < newargc; i++)
+    {
+      lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+		      i, nonnull (newargz[i]));
+    }
+
+EOF
+
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+  /* execv doesn't actually work on mingw as expected on unix */
+  newargz = prepare_spawn (newargz);
+  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+  if (rval == -1)
+    {
+      /* failed to start process */
+      lt_debugprintf (__FILE__, __LINE__,
+		      "(main) failed to launch target \"%s\": %s\n",
+		      lt_argv_zero, nonnull (strerror (errno)));
+      return 127;
+    }
+  return rval;
+EOF
+		;;
+	      *)
+		cat <<"EOF"
+  execv (lt_argv_zero, newargz);
+  return rval; /* =127, but avoids unused variable warning */
+EOF
+		;;
+	    esac
+
+	    cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+  void *p = (void *) malloc (num);
+  if (!p)
+    lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+  return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+			  string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+  const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+    name += 2;
+#endif
+
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return base;
+}
+
+int
+check_executable (const char *path)
+{
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0)
+      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+    return 1;
+  else
+    return 0;
+}
+
+int
+make_executable (const char *path)
+{
+  int rval = 0;
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if (stat (path, &st) >= 0)
+    {
+      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+    }
+  return rval;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise
+   Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+  int has_slash = 0;
+  const char *p;
+  const char *p_next;
+  /* static buffer for getcwd */
+  char tmp[LT_PATHMAX + 1];
+  int tmp_len;
+  char *concat_name;
+
+  lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+                  nonempty (wrapper));
+
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
+
+  /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable (concat_name))
+	return concat_name;
+      XFREE (concat_name);
+    }
+  else
+    {
+#endif
+      if (IS_DIR_SEPARATOR (wrapper[0]))
+	{
+	  concat_name = xstrdup (wrapper);
+	  if (check_executable (concat_name))
+	    return concat_name;
+	  XFREE (concat_name);
+	}
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+    }
+#endif
+
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+      {
+	has_slash = 1;
+	break;
+      }
+  if (!has_slash)
+    {
+      /* no slashes; search PATH */
+      const char *path = getenv ("PATH");
+      if (path != NULL)
+	{
+	  for (p = path; *p; p = p_next)
+	    {
+	      const char *q;
+	      size_t p_len;
+	      for (q = p; *q; q++)
+		if (IS_PATH_SEPARATOR (*q))
+		  break;
+	      p_len = q - p;
+	      p_next = (*q == '\0' ? q : q + 1);
+	      if (p_len == 0)
+		{
+		  /* empty path: current directory */
+		  if (getcwd (tmp, LT_PATHMAX) == NULL)
+		    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+                              nonnull (strerror (errno)));
+		  tmp_len = strlen (tmp);
+		  concat_name =
+		    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, tmp, tmp_len);
+		  concat_name[tmp_len] = '/';
+		  strcpy (concat_name + tmp_len + 1, wrapper);
+		}
+	      else
+		{
+		  concat_name =
+		    XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, p, p_len);
+		  concat_name[p_len] = '/';
+		  strcpy (concat_name + p_len + 1, wrapper);
+		}
+	      if (check_executable (concat_name))
+		return concat_name;
+	      XFREE (concat_name);
+	    }
+	}
+      /* not found in PATH; assume curdir */
+    }
+  /* Relative path | not found in path: prepend cwd */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+              nonnull (strerror (errno)));
+  tmp_len = strlen (tmp);
+  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable (concat_name))
+    return concat_name;
+  XFREE (concat_name);
+  return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+  return xstrdup (pathspec);
+#else
+  char buf[LT_PATHMAX];
+  struct stat s;
+  char *tmp_pathspec = xstrdup (pathspec);
+  char *p;
+  int has_symlinks = 0;
+  while (strlen (tmp_pathspec) && !has_symlinks)
+    {
+      lt_debugprintf (__FILE__, __LINE__,
+		      "checking path component for symlinks: %s\n",
+		      tmp_pathspec);
+      if (lstat (tmp_pathspec, &s) == 0)
+	{
+	  if (S_ISLNK (s.st_mode) != 0)
+	    {
+	      has_symlinks = 1;
+	      break;
+	    }
+
+	  /* search backwards for last DIR_SEPARATOR */
+	  p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+	  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    p--;
+	  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    {
+	      /* no more DIR_SEPARATORS left */
+	      break;
+	    }
+	  *p = '\0';
+	}
+      else
+	{
+	  lt_fatal (__FILE__, __LINE__,
+		    "error accessing file \"%s\": %s",
+		    tmp_pathspec, nonnull (strerror (errno)));
+	}
+    }
+  XFREE (tmp_pathspec);
+
+  if (!has_symlinks)
+    {
+      return xstrdup (pathspec);
+    }
+
+  tmp_pathspec = realpath (pathspec, buf);
+  if (tmp_pathspec == 0)
+    {
+      lt_fatal (__FILE__, __LINE__,
+		"could not follow symlinks for %s", pathspec);
+    }
+  return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+  size_t len, patlen;
+
+  assert (str != NULL);
+  assert (pat != NULL);
+
+  len = strlen (str);
+  patlen = strlen (pat);
+
+  if (patlen <= len)
+    {
+      str += len - patlen;
+      if (strcmp (str, pat) == 0)
+	*str = '\0';
+    }
+  return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+  va_list args;
+  if (lt_debug)
+    {
+      (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+      va_start (args, fmt);
+      (void) vfprintf (stderr, fmt, args);
+      va_end (args);
+    }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+	       int line, const char *mode,
+	       const char *message, va_list ap)
+{
+  fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+  va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+  return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+  return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_setenv) setting '%s' to '%s'\n",
+                  nonnull (name), nonnull (value));
+  {
+#ifdef HAVE_SETENV
+    /* always make a copy, for consistency with !HAVE_SETENV */
+    char *str = xstrdup (value);
+    setenv (name, str, 1);
+#else
+    int len = strlen (name) + 1 + strlen (value) + 1;
+    char *str = XMALLOC (char, len);
+    sprintf (str, "%s=%s", name, value);
+    if (putenv (str) != EXIT_SUCCESS)
+      {
+        XFREE (str);
+      }
+#endif
+  }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+  char *new_value;
+  if (orig_value && *orig_value)
+    {
+      int orig_value_len = strlen (orig_value);
+      int add_len = strlen (add);
+      new_value = XMALLOC (char, add_len + orig_value_len + 1);
+      if (to_end)
+        {
+          strcpy (new_value, orig_value);
+          strcpy (new_value + orig_value_len, add);
+        }
+      else
+        {
+          strcpy (new_value, add);
+          strcpy (new_value + add_len, orig_value);
+        }
+    }
+  else
+    {
+      new_value = xstrdup (add);
+    }
+  return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      /* some systems can't cope with a ':'-terminated path #' */
+      int len = strlen (new_value);
+      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+        {
+          new_value[len-1] = '\0';
+        }
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+EOF
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+   Note that spawn() does not by itself call the command interpreter
+     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+         GetVersionEx(&v);
+         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+      }) ? "cmd.exe" : "command.com").
+   Instead it simply concatenates the arguments, separated by ' ', and calls
+   CreateProcess().  We must quote the arguments since Win32 CreateProcess()
+   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+   special way:
+   - Space and tab are interpreted as delimiters. They are not treated as
+     delimiters if they are surrounded by double quotes: "...".
+   - Unescaped double quotes are removed from the input. Their only effect is
+     that within double quotes, space and tab are treated like normal
+     characters.
+   - Backslashes not followed by double quotes are not special.
+   - But 2*n+1 backslashes followed by a double quote become
+     n backslashes followed by a double quote (n >= 0):
+       \" -> "
+       \\\" -> \"
+       \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+  size_t argc;
+  char **new_argv;
+  size_t i;
+
+  /* Count number of arguments.  */
+  for (argc = 0; argv[argc] != NULL; argc++)
+    ;
+
+  /* Allocate new argument vector.  */
+  new_argv = XMALLOC (char *, argc + 1);
+
+  /* Put quoted arguments into the new argument vector.  */
+  for (i = 0; i < argc; i++)
+    {
+      const char *string = argv[i];
+
+      if (string[0] == '\0')
+	new_argv[i] = xstrdup ("\"\"");
+      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+	{
+	  int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+	  size_t length;
+	  unsigned int backslashes;
+	  const char *s;
+	  char *quoted_string;
+	  char *p;
+
+	  length = 0;
+	  backslashes = 0;
+	  if (quote_around)
+	    length++;
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		length += backslashes + 1;
+	      length++;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    length += backslashes + 1;
+
+	  quoted_string = XMALLOC (char, length + 1);
+
+	  p = quoted_string;
+	  backslashes = 0;
+	  if (quote_around)
+	    *p++ = '"';
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		{
+		  unsigned int j;
+		  for (j = backslashes + 1; j > 0; j--)
+		    *p++ = '\\';
+		}
+	      *p++ = c;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    {
+	      unsigned int j;
+	      for (j = backslashes; j > 0; j--)
+		*p++ = '\\';
+	      *p++ = '"';
+	    }
+	  *p = '\0';
+
+	  new_argv[i] = quoted_string;
+	}
+      else
+	new_argv[i] = (char *) string;
+    }
+  new_argv[argc] = NULL;
+
+  return new_argv;
+}
+EOF
+		;;
+	    esac
+
+            cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+	    func_emit_wrapper yes |
+              $SED -e 's/\([\\"]\)/\\\1/g' \
+	           -e 's/^/  fputs ("/' -e 's/$/\\n", f);/'
+
+            cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+    $opt_debug
+    case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+    *import*) : ;;
+    *) false ;;
+    esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+    $opt_debug
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args=$nonopt
+    base_compile="$nonopt $@"
+    compile_command=$nonopt
+    finalize_command=$nonopt
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+    new_inherited_linker_flags=
+
+    avoid_version=no
+    bindir=
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+    weak_libs=
+    single_module="${wl}-single_module"
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
+	break
+	;;
+      -all-static | -static | -static-libtool-libs)
+	case $arg in
+	-all-static)
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    func_warning "complete static linking is impossible in this configuration"
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	-static)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=built
+	  ;;
+	-static-libtool-libs)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	esac
+	build_libtool_libs=no
+	build_old_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg="$1"
+      shift
+      func_quote_for_eval "$arg"
+      qarg=$func_quote_for_eval_unquoted_result
+      func_append libtool_args " $func_quote_for_eval_result"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  func_append compile_command " @OUTPUT@"
+	  func_append finalize_command " @OUTPUT@"
+	  ;;
+	esac
+
+	case $prev in
+	bindir)
+	  bindir="$arg"
+	  prev=
+	  continue
+	  ;;
+	dlfiles|dlprefiles)
+	  if test "$preload" = no; then
+	    # Add the symbol object into the linking commands.
+	    func_append compile_command " @SYMFILE@"
+	    func_append finalize_command " @SYMFILE@"
+	    preload=yes
+	  fi
+	  case $arg in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test "$dlself" = no; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test "$prev" = dlprefiles; then
+	      dlself=yes
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test "$prev" = dlfiles; then
+	      func_append dlfiles " $arg"
+	    else
+	      func_append dlprefiles " $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols="$arg"
+	  test -f "$arg" \
+	    || func_fatal_error "symbol file \`$arg' does not exist"
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	framework)
+	  case $host in
+	    *-*-darwin*)
+	      case "$deplibs " in
+		*" $qarg.ltframework "*) ;;
+		*) func_append deplibs " $qarg.ltframework" # this is fixed later
+		   ;;
+	      esac
+	      ;;
+	  esac
+	  prev=
+	  continue
+	  ;;
+	inst_prefix)
+	  inst_prefix_dir="$arg"
+	  prev=
+	  continue
+	  ;;
+	objectlist)
+	  if test -f "$arg"; then
+	    save_arg=$arg
+	    moreargs=
+	    for fil in `cat "$save_arg"`
+	    do
+#	      func_append moreargs " $fil"
+	      arg=$fil
+	      # A libtool-controlled object.
+
+	      # Check to see that this really is a libtool object.
+	      if func_lalib_unsafe_p "$arg"; then
+		pic_object=
+		non_pic_object=
+
+		# Read the .lo file
+		func_source "$arg"
+
+		if test -z "$pic_object" ||
+		   test -z "$non_pic_object" ||
+		   test "$pic_object" = none &&
+		   test "$non_pic_object" = none; then
+		  func_fatal_error "cannot find name of object for \`$arg'"
+		fi
+
+		# Extract subdirectory from the argument.
+		func_dirname "$arg" "/" ""
+		xdir="$func_dirname_result"
+
+		if test "$pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  pic_object="$xdir$pic_object"
+
+		  if test "$prev" = dlfiles; then
+		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		      func_append dlfiles " $pic_object"
+		      prev=
+		      continue
+		    else
+		      # If libtool objects are unsupported, then we need to preload.
+		      prev=dlprefiles
+		    fi
+		  fi
+
+		  # CHECK ME:  I think I busted this.  -Ossama
+		  if test "$prev" = dlprefiles; then
+		    # Preload the old-style object.
+		    func_append dlprefiles " $pic_object"
+		    prev=
+		  fi
+
+		  # A PIC object.
+		  func_append libobjs " $pic_object"
+		  arg="$pic_object"
+		fi
+
+		# Non-PIC object.
+		if test "$non_pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  non_pic_object="$xdir$non_pic_object"
+
+		  # A standard non-PIC object
+		  func_append non_pic_objects " $non_pic_object"
+		  if test -z "$pic_object" || test "$pic_object" = none ; then
+		    arg="$non_pic_object"
+		  fi
+		else
+		  # If the PIC object exists, use it instead.
+		  # $xdir was prepended to $pic_object above.
+		  non_pic_object="$pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+		fi
+	      else
+		# Only an error if not doing a dry-run.
+		if $opt_dry_run; then
+		  # Extract subdirectory from the argument.
+		  func_dirname "$arg" "/" ""
+		  xdir="$func_dirname_result"
+
+		  func_lo2o "$arg"
+		  pic_object=$xdir$objdir/$func_lo2o_result
+		  non_pic_object=$xdir$func_lo2o_result
+		  func_append libobjs " $pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+	        else
+		  func_fatal_error "\`$arg' is not a valid libtool object"
+		fi
+	      fi
+	    done
+	  else
+	    func_fatal_error "link input file \`$arg' does not exist"
+	  fi
+	  arg=$save_arg
+	  prev=
+	  continue
+	  ;;
+	precious_regex)
+	  precious_files_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release="-$arg"
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    func_fatal_error "only absolute run-paths are allowed"
+	    ;;
+	  esac
+	  if test "$prev" = rpath; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) func_append rpath " $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) func_append xrpath " $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	shrext)
+	  shrext_cmds="$arg"
+	  prev=
+	  continue
+	  ;;
+	weak)
+	  func_append weak_libs " $arg"
+	  prev=
+	  continue
+	  ;;
+	xcclinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xcompiler)
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $wl$qarg"
+	  prev=
+	  func_append compile_command " $wl$qarg"
+	  func_append finalize_command " $wl$qarg"
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi # test -n "$prev"
+
+      prevarg="$arg"
+
+      case $arg in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  # See comment for -static flag below, for more details.
+	  func_append compile_command " $link_static_flag"
+	  func_append finalize_command " $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -bindir)
+	prev=bindir
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  func_fatal_error "more than one -exported-symbols argument is not allowed"
+	fi
+	if test "X$arg" = "X-export-symbols"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -framework)
+	prev=framework
+	continue
+	;;
+
+      -inst-prefix-dir)
+	prev=inst_prefix
+	continue
+	;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+	case $with_gcc/$host in
+	no/*-*-irix* | /*-*-irix*)
+	  func_append compile_command " $arg"
+	  func_append finalize_command " $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	func_stripname "-L" '' "$arg"
+	if test -z "$func_stripname_result"; then
+	  if test "$#" -gt 0; then
+	    func_fatal_error "require no space between \`-L' and \`$1'"
+	  else
+	    func_fatal_error "need path for \`-L' option"
+	  fi
+	fi
+	func_resolve_sysroot "$func_stripname_result"
+	dir=$func_resolve_sysroot_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  test -z "$absdir" && \
+	    func_fatal_error "cannot determine absolute directory name of \`$dir'"
+	  dir="$absdir"
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "* | *" $arg "*)
+	  # Will only happen for absolute or sysroot arguments
+	  ;;
+	*)
+	  # Preserve sysroot, but never include relative directories
+	  case $dir in
+	    [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+	    *) func_append deplibs " -L$dir" ;;
+	  esac
+	  func_append lib_search_path " $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  ::) dllsearchpath=$dir;;
+	  *) func_append dllsearchpath ":$dir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append dllsearchpath ":$testbindir";;
+	  esac
+	  ;;
+	esac
+	continue
+	;;
+
+      -l*)
+	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # These systems don't actually have a C or math library (as such)
+	    continue
+	    ;;
+	  *-*-os2*)
+	    # These systems don't actually have a C library (as such)
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C and math libraries are in the System framework
+	    func_append deplibs " System.ltframework"
+	    continue
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  esac
+	elif test "X$arg" = "X-lc_r"; then
+	 case $host in
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	   # Do not include libc_r directly, use -pthread flag.
+	   continue
+	   ;;
+	 esac
+	fi
+	func_append deplibs " $arg"
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      # Darwin uses the -arch flag to determine output architecture.
+      -model|-arch|-isysroot|--sysroot)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	prev=xcompiler
+	continue
+	;;
+
+      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	case "$new_inherited_linker_flags " in
+	    *" $arg "*) ;;
+	    * ) func_append new_inherited_linker_flags " $arg" ;;
+	esac
+	continue
+	;;
+
+      -multi_module)
+	single_module="${wl}-multi_module"
+	continue
+	;;
+
+      -no-fast-install)
+	fast_install=no
+	continue
+	;;
+
+      -no-install)
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+	  # The PATH hackery in wrapper scripts is required on Windows
+	  # and Darwin in order for the loader to find any dlls it needs.
+	  func_warning "\`-no-install' is ignored for $host"
+	  func_warning "assuming \`-no-fast-install' instead"
+	  fast_install=no
+	  ;;
+	*) no_install=yes ;;
+	esac
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -objectlist)
+	prev=objectlist
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+	prev=precious_regex
+	continue
+	;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	func_stripname '-R' '' "$arg"
+	dir=$func_stripname_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	=*)
+	  func_stripname '=' '' "$dir"
+	  dir=$lt_sysroot$func_stripname_result
+	  ;;
+	*)
+	  func_fatal_error "only absolute run-paths are allowed"
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) func_append xrpath " $dir" ;;
+	esac
+	continue
+	;;
+
+      -shared)
+	# The effects of -shared are defined in a previous loop.
+	continue
+	;;
+
+      -shrext)
+	prev=shrext
+	continue
+	;;
+
+      -static | -static-libtool-libs)
+	# The effects of -static are defined in a previous loop.
+	# We used to do the same as -all-static on platforms that
+	# didn't have a PIC flag, but the assumption that the effects
+	# would be equivalent was wrong.  It would break on at least
+	# Digital Unix and AIX.
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+
+      -version-number)
+	prev=vinfo
+	vinfo_number=yes
+	continue
+	;;
+
+      -weak)
+        prev=weak
+	continue
+	;;
+
+      -Wc,*)
+	func_stripname '-Wc,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  func_append arg " $func_quote_for_eval_result"
+	  func_append compiler_flags " $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Wl,*)
+	func_stripname '-Wl,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  func_append arg " $wl$func_quote_for_eval_result"
+	  func_append compiler_flags " $wl$func_quote_for_eval_result"
+	  func_append linker_flags " $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Xlinker)
+	prev=xlinker
+	continue
+	;;
+
+      -XCClinker)
+	prev=xcclinker
+	continue
+	;;
+
+      # -msg_* for osf cc
+      -msg_*)
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      # Flags to be passed through unchanged, with rationale:
+      # -64, -mips[0-9]      enable 64-bit mode for the SGI compiler
+      # -r[0-9][0-9]*        specify processor for the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+      # +DA*, +DD*           enable 64-bit mode for the HP compiler
+      # -q*                  compiler args for the IBM compiler
+      # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+      # -F/path              path to uninstalled frameworks, gcc on darwin
+      # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
+      # @file                GCC response files
+      # -tp=*                Portland pgcc target processor selection
+      # --sysroot=*          for sysroot support
+      # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+      -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+        func_append compile_command " $arg"
+        func_append finalize_command " $arg"
+        func_append compiler_flags " $arg"
+        continue
+        ;;
+
+      # Some other compiler flag.
+      -* | +*)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      *.$objext)
+	# A standard object.
+	func_append objs " $arg"
+	;;
+
+      *.lo)
+	# A libtool-controlled object.
+
+	# Check to see that this really is a libtool object.
+	if func_lalib_unsafe_p "$arg"; then
+	  pic_object=
+	  non_pic_object=
+
+	  # Read the .lo file
+	  func_source "$arg"
+
+	  if test -z "$pic_object" ||
+	     test -z "$non_pic_object" ||
+	     test "$pic_object" = none &&
+	     test "$non_pic_object" = none; then
+	    func_fatal_error "cannot find name of object for \`$arg'"
+	  fi
+
+	  # Extract subdirectory from the argument.
+	  func_dirname "$arg" "/" ""
+	  xdir="$func_dirname_result"
+
+	  if test "$pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    pic_object="$xdir$pic_object"
+
+	    if test "$prev" = dlfiles; then
+	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		func_append dlfiles " $pic_object"
+		prev=
+		continue
+	      else
+		# If libtool objects are unsupported, then we need to preload.
+		prev=dlprefiles
+	      fi
+	    fi
+
+	    # CHECK ME:  I think I busted this.  -Ossama
+	    if test "$prev" = dlprefiles; then
+	      # Preload the old-style object.
+	      func_append dlprefiles " $pic_object"
+	      prev=
+	    fi
+
+	    # A PIC object.
+	    func_append libobjs " $pic_object"
+	    arg="$pic_object"
+	  fi
+
+	  # Non-PIC object.
+	  if test "$non_pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    non_pic_object="$xdir$non_pic_object"
+
+	    # A standard non-PIC object
+	    func_append non_pic_objects " $non_pic_object"
+	    if test -z "$pic_object" || test "$pic_object" = none ; then
+	      arg="$non_pic_object"
+	    fi
+	  else
+	    # If the PIC object exists, use it instead.
+	    # $xdir was prepended to $pic_object above.
+	    non_pic_object="$pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  fi
+	else
+	  # Only an error if not doing a dry-run.
+	  if $opt_dry_run; then
+	    # Extract subdirectory from the argument.
+	    func_dirname "$arg" "/" ""
+	    xdir="$func_dirname_result"
+
+	    func_lo2o "$arg"
+	    pic_object=$xdir$objdir/$func_lo2o_result
+	    non_pic_object=$xdir$func_lo2o_result
+	    func_append libobjs " $pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  else
+	    func_fatal_error "\`$arg' is not a valid libtool object"
+	  fi
+	fi
+	;;
+
+      *.$libext)
+	# An archive.
+	func_append deplibs " $arg"
+	func_append old_deplibs " $arg"
+	continue
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	func_resolve_sysroot "$arg"
+	if test "$prev" = dlfiles; then
+	  # This library was specified with -dlopen.
+	  func_append dlfiles " $func_resolve_sysroot_result"
+	  prev=
+	elif test "$prev" = dlprefiles; then
+	  # The library was specified with -dlpreopen.
+	  func_append dlprefiles " $func_resolve_sysroot_result"
+	  prev=
+	else
+	  func_append deplibs " $func_resolve_sysroot_result"
+	fi
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+      fi
+    done # argument parsing loop
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prevarg' option requires an argument"
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      func_append compile_command " $arg"
+      func_append finalize_command " $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    func_basename "$output"
+    outputname="$func_basename_result"
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    func_dirname "$output" "/" ""
+    output_objdir="$func_dirname_result$objdir"
+    func_to_tool_file "$output_objdir/"
+    tool_output_objdir=$func_to_tool_file_result
+    # Create the object directory.
+    func_mkdir_p "$output_objdir"
+
+    # Determine the type of output
+    case $output in
+    "")
+      func_fatal_help "you must specify an output file"
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if $opt_preserve_dup_deps ; then
+	case "$libs " in
+	*" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	esac
+      fi
+      func_append libs " $deplib"
+    done
+
+    if test "$linkmode" = lib; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if $opt_duplicate_compiler_generated_deps; then
+	for pre_post_dep in $predeps $postdeps; do
+	  case "$pre_post_deps " in
+	  *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+	  esac
+	  func_append pre_post_deps " $pre_post_dep"
+	done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    notinst_path= # paths that contain not-installed libtool libraries
+
+    case $linkmode in
+    lib)
+	passes="conv dlpreopen link"
+	for file in $dlfiles $dlprefiles; do
+	  case $file in
+	  *.la) ;;
+	  *)
+	    func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+	    ;;
+	  esac
+	done
+	;;
+    prog)
+	compile_deplibs=
+	finalize_deplibs=
+	alldeplibs=no
+	newdlfiles=
+	newdlprefiles=
+	passes="conv scan dlopen dlpreopen link"
+	;;
+    *)  passes="conv"
+	;;
+    esac
+
+    for pass in $passes; do
+      # The preopen pass in lib mode reverses $deplibs; put it back here
+      # so that -L comes before libs that need it for instance...
+      if test "$linkmode,$pass" = "lib,link"; then
+	## FIXME: Find the place where the list is rebuilt in the wrong
+	##        order, and fix it there properly
+        tmp_deplibs=
+	for deplib in $deplibs; do
+	  tmp_deplibs="$deplib $tmp_deplibs"
+	done
+	deplibs="$tmp_deplibs"
+      fi
+
+      if test "$linkmode,$pass" = "lib,link" ||
+	 test "$linkmode,$pass" = "prog,scan"; then
+	libs="$deplibs"
+	deplibs=
+      fi
+      if test "$linkmode" = prog; then
+	case $pass in
+	dlopen) libs="$dlfiles" ;;
+	dlpreopen) libs="$dlprefiles" ;;
+	link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+	esac
+      fi
+      if test "$linkmode,$pass" = "lib,dlpreopen"; then
+	# Collect and forward deplibs of preopened libtool libs
+	for lib in $dlprefiles; do
+	  # Ignore non-libtool-libs
+	  dependency_libs=
+	  func_resolve_sysroot "$lib"
+	  case $lib in
+	  *.la)	func_source "$func_resolve_sysroot_result" ;;
+	  esac
+
+	  # Collect preopened libtool deplibs, except any this library
+	  # has declared as weak libs
+	  for deplib in $dependency_libs; do
+	    func_basename "$deplib"
+            deplib_base=$func_basename_result
+	    case " $weak_libs " in
+	    *" $deplib_base "*) ;;
+	    *) func_append deplibs " $deplib" ;;
+	    esac
+	  done
+	done
+	libs="$dlprefiles"
+      fi
+      if test "$pass" = dlopen; then
+	# Collect dlpreopened libraries
+	save_deplibs="$deplibs"
+	deplibs=
+      fi
+
+      for deplib in $libs; do
+	lib=
+	found=no
+	case $deplib in
+	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    func_append compiler_flags " $deplib"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-l*)
+	  if test "$linkmode" != lib && test "$linkmode" != prog; then
+	    func_warning "\`-l' is ignored for archives/objects"
+	    continue
+	  fi
+	  func_stripname '-l' '' "$deplib"
+	  name=$func_stripname_result
+	  if test "$linkmode" = lib; then
+	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+	  else
+	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+	  fi
+	  for searchdir in $searchdirs; do
+	    for search_ext in .la $std_shrext .so .a; do
+	      # Search the libtool library
+	      lib="$searchdir/lib${name}${search_ext}"
+	      if test -f "$lib"; then
+		if test "$search_ext" = ".la"; then
+		  found=yes
+		else
+		  found=no
+		fi
+		break 2
+	      fi
+	    done
+	  done
+	  if test "$found" != yes; then
+	    # deplib doesn't seem to be a libtool library
+	    if test "$linkmode,$pass" = "prog,link"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  else # deplib is a libtool library
+	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+	    # We need to do some special things here, and not later.
+	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	      case " $predeps $postdeps " in
+	      *" $deplib "*)
+		if func_lalib_p "$lib"; then
+		  library_names=
+		  old_library=
+		  func_source "$lib"
+		  for l in $old_library $library_names; do
+		    ll="$l"
+		  done
+		  if test "X$ll" = "X$old_library" ; then # only static version available
+		    found=no
+		    func_dirname "$lib" "" "."
+		    ladir="$func_dirname_result"
+		    lib=$ladir/$old_library
+		    if test "$linkmode,$pass" = "prog,link"; then
+		      compile_deplibs="$deplib $compile_deplibs"
+		      finalize_deplibs="$deplib $finalize_deplibs"
+		    else
+		      deplibs="$deplib $deplibs"
+		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+		    fi
+		    continue
+		  fi
+		fi
+		;;
+	      *) ;;
+	      esac
+	    fi
+	  fi
+	  ;; # -l
+	*.ltframework)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    deplibs="$deplib $deplibs"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-L*)
+	  case $linkmode in
+	  lib)
+	    deplibs="$deplib $deplibs"
+	    test "$pass" = conv && continue
+	    newdependency_libs="$deplib $newdependency_libs"
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  prog)
+	    if test "$pass" = conv; then
+	      deplibs="$deplib $deplibs"
+	      continue
+	    fi
+	    if test "$pass" = scan; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  *)
+	    func_warning "\`-L' is ignored for archives/objects"
+	    ;;
+	  esac # linkmode
+	  continue
+	  ;; # -L
+	-R*)
+	  if test "$pass" = link; then
+	    func_stripname '-R' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    dir=$func_resolve_sysroot_result
+	    # Make sure the xrpath contains only unique directories.
+	    case "$xrpath " in
+	    *" $dir "*) ;;
+	    *) func_append xrpath " $dir" ;;
+	    esac
+	  fi
+	  deplibs="$deplib $deplibs"
+	  continue
+	  ;;
+	*.la)
+	  func_resolve_sysroot "$deplib"
+	  lib=$func_resolve_sysroot_result
+	  ;;
+	*.$libext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  case $linkmode in
+	  lib)
+	    # Linking convenience modules into shared libraries is allowed,
+	    # but linking other static libraries is non-portable.
+	    case " $dlpreconveniencelibs " in
+	    *" $deplib "*) ;;
+	    *)
+	      valid_a_lib=no
+	      case $deplibs_check_method in
+		match_pattern*)
+		  set dummy $deplibs_check_method; shift
+		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+		  if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+		    | $EGREP "$match_pattern_regex" > /dev/null; then
+		    valid_a_lib=yes
+		  fi
+		;;
+		pass_all)
+		  valid_a_lib=yes
+		;;
+	      esac
+	      if test "$valid_a_lib" != yes; then
+		echo
+		$ECHO "*** Warning: Trying to link with static lib archive $deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because the file extensions .$libext of this argument makes me believe"
+		echo "*** that it is just a static archive that I should not use here."
+	      else
+		echo
+		$ECHO "*** Warning: Linking the shared library $output against the"
+		$ECHO "*** static library $deplib is not portable!"
+		deplibs="$deplib $deplibs"
+	      fi
+	      ;;
+	    esac
+	    continue
+	    ;;
+	  prog)
+	    if test "$pass" != link; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    continue
+	    ;;
+	  esac # linkmode
+	  ;; # *.$libext
+	*.lo | *.$objext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	  elif test "$linkmode" = prog; then
+	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+	      # If there is no dlopen support or we're linking statically,
+	      # we need to preload.
+	      func_append newdlprefiles " $deplib"
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      func_append newdlfiles " $deplib"
+	    fi
+	  fi
+	  continue
+	  ;;
+	%DEPLIBS%)
+	  alldeplibs=yes
+	  continue
+	  ;;
+	esac # case $deplib
+
+	if test "$found" = yes || test -f "$lib"; then :
+	else
+	  func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+	fi
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$lib" \
+	  || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+	func_dirname "$lib" "" "."
+	ladir="$func_dirname_result"
+
+	dlname=
+	dlopen=
+	dlpreopen=
+	libdir=
+	library_names=
+	old_library=
+	inherited_linker_flags=
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variables installed, or shouldnotlink
+	installed=yes
+	shouldnotlink=no
+	avoidtemprpath=
+
+
+	# Read the .la file
+	func_source "$lib"
+
+	# Convert "-framework foo" to "foo.ltframework"
+	if test -n "$inherited_linker_flags"; then
+	  tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+	  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+	    case " $new_inherited_linker_flags " in
+	      *" $tmp_inherited_linker_flag "*) ;;
+	      *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+	    esac
+	  done
+	fi
+	dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+	  test -n "$dlopen" && func_append dlfiles " $dlopen"
+	  test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+	fi
+
+	if test "$pass" = conv; then
+	  # Only check for convenience libraries
+	  deplibs="$lib $deplibs"
+	  if test -z "$libdir"; then
+	    if test -z "$old_library"; then
+	      func_fatal_error "cannot find name of link library for \`$lib'"
+	    fi
+	    # It is a libtool convenience library, so add in its objects.
+	    func_append convenience " $ladir/$objdir/$old_library"
+	    func_append old_convenience " $ladir/$objdir/$old_library"
+	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+	    func_fatal_error "\`$lib' is not a convenience library"
+	  fi
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    deplibs="$deplib $deplibs"
+	    if $opt_preserve_dup_deps ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $deplib"
+	  done
+	  continue
+	fi # $pass = conv
+
+
+	# Get the name of the library we link against.
+	linklib=
+	if test -n "$old_library" &&
+	   { test "$prefer_static_libs" = yes ||
+	     test "$prefer_static_libs,$installed" = "built,no"; }; then
+	  linklib=$old_library
+	else
+	  for l in $old_library $library_names; do
+	    linklib="$l"
+	  done
+	fi
+	if test -z "$linklib"; then
+	  func_fatal_error "cannot find name of link library for \`$lib'"
+	fi
+
+	# This library was specified with -dlopen.
+	if test "$pass" = dlopen; then
+	  if test -z "$libdir"; then
+	    func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+	  fi
+	  if test -z "$dlname" ||
+	     test "$dlopen_support" != yes ||
+	     test "$build_libtool_libs" = no; then
+	    # If there is no dlname, no dlopen support or we're linking
+	    # statically, we need to preload.  We also need to preload any
+	    # dependent libraries so libltdl's deplib preloader doesn't
+	    # bomb out in the load deplibs phase.
+	    func_append dlprefiles " $lib $dependency_libs"
+	  else
+	    func_append newdlfiles " $lib"
+	  fi
+	  continue
+	fi # $pass = dlopen
+
+	# We need an absolute path.
+	case $ladir in
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+	*)
+	  abs_ladir=`cd "$ladir" && pwd`
+	  if test -z "$abs_ladir"; then
+	    func_warning "cannot determine absolute directory name of \`$ladir'"
+	    func_warning "passing it literally to the linker, although it might fail"
+	    abs_ladir="$ladir"
+	  fi
+	  ;;
+	esac
+	func_basename "$lib"
+	laname="$func_basename_result"
+
+	# Find the relevant object directory and library name.
+	if test "X$installed" = Xyes; then
+	  if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    func_warning "library \`$lib' was moved."
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
+	  else
+	    dir="$lt_sysroot$libdir"
+	    absdir="$lt_sysroot$libdir"
+	  fi
+	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+	else
+	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    # Remove this search path later
+	    func_append notinst_path " $abs_ladir"
+	  else
+	    dir="$ladir/$objdir"
+	    absdir="$abs_ladir/$objdir"
+	    # Remove this search path later
+	    func_append notinst_path " $abs_ladir"
+	  fi
+	fi # $installed = yes
+	func_stripname 'lib' '.la' "$laname"
+	name=$func_stripname_result
+
+	# This library was specified with -dlpreopen.
+	if test "$pass" = dlpreopen; then
+	  if test -z "$libdir" && test "$linkmode" = prog; then
+	    func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+	  fi
+	  case "$host" in
+	    # special handling for platforms with PE-DLLs.
+	    *cygwin* | *mingw* | *cegcc* )
+	      # Linker will automatically link against shared library if both
+	      # static and shared are present.  Therefore, ensure we extract
+	      # symbols from the import library if a shared library is present
+	      # (otherwise, the dlopen module name will be incorrect).  We do
+	      # this by putting the import library name into $newdlprefiles.
+	      # We recover the dlopen module name by 'saving' the la file
+	      # name in a special purpose variable, and (later) extracting the
+	      # dlname from the la file.
+	      if test -n "$dlname"; then
+	        func_tr_sh "$dir/$linklib"
+	        eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+	        func_append newdlprefiles " $dir/$linklib"
+	      else
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      fi
+	    ;;
+	    * )
+	      # Prefer using a static library (so that no silly _DYNAMIC symbols
+	      # are required to link).
+	      if test -n "$old_library"; then
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      # Otherwise, use the dlname, so that lt_dlopen finds it.
+	      elif test -n "$dlname"; then
+	        func_append newdlprefiles " $dir/$dlname"
+	      else
+	        func_append newdlprefiles " $dir/$linklib"
+	      fi
+	    ;;
+	  esac
+	fi # $pass = dlpreopen
+
+	if test -z "$libdir"; then
+	  # Link the convenience library
+	  if test "$linkmode" = lib; then
+	    deplibs="$dir/$old_library $deplibs"
+	  elif test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$dir/$old_library $compile_deplibs"
+	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
+	  else
+	    deplibs="$lib $deplibs" # used for prog,scan pass
+	  fi
+	  continue
+	fi
+
+
+	if test "$linkmode" = prog && test "$pass" != link; then
+	  func_append newlib_search_path " $ladir"
+	  deplibs="$lib $deplibs"
+
+	  linkalldeplibs=no
+	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
+	     test "$build_libtool_libs" = no; then
+	    linkalldeplibs=yes
+	  fi
+
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    case $deplib in
+	    -L*) func_stripname '-L' '' "$deplib"
+	         func_resolve_sysroot "$func_stripname_result"
+	         func_append newlib_search_path " $func_resolve_sysroot_result"
+		 ;;
+	    esac
+	    # Need to link against all dependency_libs?
+	    if test "$linkalldeplibs" = yes; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      # Need to hardcode shared library paths
+	      # or/and link against static libraries
+	      newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    if $opt_preserve_dup_deps ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $deplib"
+	  done # for deplib
+	  continue
+	fi # $linkmode = prog...
+
+	if test "$linkmode,$pass" = "prog,link"; then
+	  if test -n "$library_names" &&
+	     { { test "$prefer_static_libs" = no ||
+	         test "$prefer_static_libs,$installed" = "built,yes"; } ||
+	       test -z "$old_library"; }; then
+	    # We need to hardcode the library path
+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+	      # Make sure the rpath contains only unique directories.
+	      case "$temp_rpath:" in
+	      *"$absdir:"*) ;;
+	      *) func_append temp_rpath "$absdir:" ;;
+	      esac
+	    fi
+
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append finalize_rpath " $libdir" ;;
+	      esac
+	      ;;
+	    esac
+	  fi # $linkmode,$pass = prog,link...
+
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
+		 test -n "$library_names"; }; }; then
+	    # We only need to search for static libraries
+	    continue
+	  fi
+	fi
+
+	link_static=no # Whether the deplib will be linked statically
+	use_static_libs=$prefer_static_libs
+	if test "$use_static_libs" = built && test "$installed" = yes; then
+	  use_static_libs=no
+	fi
+	if test -n "$library_names" &&
+	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
+	  case $host in
+	  *cygwin* | *mingw* | *cegcc*)
+	      # No point in relinking DLLs because paths are not encoded
+	      func_append notinst_deplibs " $lib"
+	      need_relink=no
+	    ;;
+	  *)
+	    if test "$installed" = no; then
+	      func_append notinst_deplibs " $lib"
+	      need_relink=yes
+	    fi
+	    ;;
+	  esac
+	  # This is a shared library
+
+	  # Warn about portability, can't link against -module's on some
+	  # systems (darwin).  Don't bleat about dlopened modules though!
+	  dlopenmodule=""
+	  for dlpremoduletest in $dlprefiles; do
+	    if test "X$dlpremoduletest" = "X$lib"; then
+	      dlopenmodule="$dlpremoduletest"
+	      break
+	    fi
+	  done
+	  if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+	    echo
+	    if test "$linkmode" = prog; then
+	      $ECHO "*** Warning: Linking the executable $output against the loadable module"
+	    else
+	      $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+	    fi
+	    $ECHO "*** $linklib is not portable!"
+	  fi
+	  if test "$linkmode" = lib &&
+	     test "$hardcode_into_libs" = yes; then
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append finalize_rpath " $libdir" ;;
+	      esac
+	      ;;
+	    esac
+	  fi
+
+	  if test -n "$old_archive_from_expsyms_cmds"; then
+	    # figure out the soname
+	    set dummy $library_names
+	    shift
+	    realname="$1"
+	    shift
+	    libname=`eval "\\$ECHO \"$libname_spec\""`
+	    # use dlname if we got it. it's perfectly good, no?
+	    if test -n "$dlname"; then
+	      soname="$dlname"
+	    elif test -n "$soname_spec"; then
+	      # bleh windows
+	      case $host in
+	      *cygwin* | mingw* | *cegcc*)
+	        func_arith $current - $age
+		major=$func_arith_result
+		versuffix="-$major"
+		;;
+	      esac
+	      eval soname=\"$soname_spec\"
+	    else
+	      soname="$realname"
+	    fi
+
+	    # Make a new name for the extract_expsyms_cmds to use
+	    soroot="$soname"
+	    func_basename "$soroot"
+	    soname="$func_basename_result"
+	    func_stripname 'lib' '.dll' "$soname"
+	    newlib=libimp-$func_stripname_result.a
+
+	    # If the library has no export list, then create one now
+	    if test -f "$output_objdir/$soname-def"; then :
+	    else
+	      func_verbose "extracting exported symbol list from \`$soname'"
+	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+	    fi
+
+	    # Create $newlib
+	    if test -f "$output_objdir/$newlib"; then :; else
+	      func_verbose "generating import library for \`$soname'"
+	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+	    fi
+	    # make sure the library variables are pointing to the new library
+	    dir=$output_objdir
+	    linklib=$newlib
+	  fi # test -n "$old_archive_from_expsyms_cmds"
+
+	  if test "$linkmode" = prog || test "$opt_mode" != relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    lib_linked=yes
+	    case $hardcode_action in
+	    immediate | unsupported)
+	      if test "$hardcode_direct" = no; then
+		add="$dir/$linklib"
+		case $host in
+		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+		    *-*-unixware7*) add_dir="-L$dir" ;;
+		  *-*-darwin* )
+		    # if the lib is a (non-dlopened) module then we can not
+		    # link against it, someone is ignoring the earlier warnings
+		    if /usr/bin/file -L $add 2> /dev/null |
+			 $GREP ": [^:]* bundle" >/dev/null ; then
+		      if test "X$dlopenmodule" != "X$lib"; then
+			$ECHO "*** Warning: lib $linklib is a module, not a shared library"
+			if test -z "$old_library" ; then
+			  echo
+			  echo "*** And there doesn't seem to be a static archive available"
+			  echo "*** The link will probably fail, sorry"
+			else
+			  add="$dir/$old_library"
+			fi
+		      elif test -n "$old_library"; then
+			add="$dir/$old_library"
+		      fi
+		    fi
+		esac
+	      elif test "$hardcode_minus_L" = no; then
+		case $host in
+		*-*-sunos*) add_shlibpath="$dir" ;;
+		esac
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = no; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    relink)
+	      if test "$hardcode_direct" = yes &&
+	         test "$hardcode_direct_absolute" = no; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$dir"
+		# Try looking first in the location we're being installed to.
+		if test -n "$inst_prefix_dir"; then
+		  case $libdir in
+		    [\\/]*)
+		      func_append add_dir " -L$inst_prefix_dir$libdir"
+		      ;;
+		  esac
+		fi
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = yes; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    *) lib_linked=no ;;
+	    esac
+
+	    if test "$lib_linked" != yes; then
+	      func_fatal_configuration "unsupported hardcode properties"
+	    fi
+
+	    if test -n "$add_shlibpath"; then
+	      case :$compile_shlibpath: in
+	      *":$add_shlibpath:"*) ;;
+	      *) func_append compile_shlibpath "$add_shlibpath:" ;;
+	      esac
+	    fi
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	      if test "$hardcode_direct" != yes &&
+		 test "$hardcode_minus_L" != yes &&
+		 test "$hardcode_shlibpath_var" = yes; then
+		case :$finalize_shlibpath: in
+		*":$libdir:"*) ;;
+		*) func_append finalize_shlibpath "$libdir:" ;;
+		esac
+	      fi
+	    fi
+	  fi
+
+	  if test "$linkmode" = prog || test "$opt_mode" = relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    # Finalize command for both is simple: just hardcode it.
+	    if test "$hardcode_direct" = yes &&
+	       test "$hardcode_direct_absolute" = no; then
+	      add="$libdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
+	      case :$finalize_shlibpath: in
+	      *":$libdir:"*) ;;
+	      *) func_append finalize_shlibpath "$libdir:" ;;
+	      esac
+	      add="-l$name"
+	    elif test "$hardcode_automatic" = yes; then
+	      if test -n "$inst_prefix_dir" &&
+		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
+		add="$inst_prefix_dir$libdir/$linklib"
+	      else
+		add="$libdir/$linklib"
+	      fi
+	    else
+	      # We cannot seem to hardcode it, guess we'll fake it.
+	      add_dir="-L$libdir"
+	      # Try looking first in the location we're being installed to.
+	      if test -n "$inst_prefix_dir"; then
+		case $libdir in
+		  [\\/]*)
+		    func_append add_dir " -L$inst_prefix_dir$libdir"
+		    ;;
+		esac
+	      fi
+	      add="-l$name"
+	    fi
+
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	    fi
+	  fi
+	elif test "$linkmode" = prog; then
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
+	    compile_deplibs="$dir/$linklib $compile_deplibs"
+	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
+	  else
+	    compile_deplibs="-l$name -L$dir $compile_deplibs"
+	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+	  fi
+	elif test "$build_libtool_libs" = yes; then
+	  # Not a shared library
+	  if test "$deplibs_check_method" != pass_all; then
+	    # We're trying link a shared library against a static one
+	    # but the system doesn't support it.
+
+	    # Just print a warning and add the library to dependency_libs so
+	    # that the program can be linked against the static library.
+	    echo
+	    $ECHO "*** Warning: This system can not link to static lib archive $lib."
+	    echo "*** I have the capability to make that library automatically link in when"
+	    echo "*** you link to this library.  But I can only do this if you have a"
+	    echo "*** shared version of the library, which you do not appear to have."
+	    if test "$module" = yes; then
+	      echo "*** But as you try to build a module library, libtool will still create "
+	      echo "*** a static module, that should work as long as the dlopening application"
+	      echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+	      if test -z "$global_symbol_pipe"; then
+		echo
+		echo "*** However, this would only work if libtool was able to extract symbol"
+		echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+		echo "*** not find such a program.  So, this module is probably useless."
+		echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	      fi
+	      if test "$build_old_libs" = no; then
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  else
+	    deplibs="$dir/$old_library $deplibs"
+	    link_static=yes
+	  fi
+	fi # link shared/static library?
+
+	if test "$linkmode" = lib; then
+	  if test -n "$dependency_libs" &&
+	     { test "$hardcode_into_libs" != yes ||
+	       test "$build_old_libs" = yes ||
+	       test "$link_static" = yes; }; then
+	    # Extract -R from dependency_libs
+	    temp_deplibs=
+	    for libdir in $dependency_libs; do
+	      case $libdir in
+	      -R*) func_stripname '-R' '' "$libdir"
+	           temp_xrpath=$func_stripname_result
+		   case " $xrpath " in
+		   *" $temp_xrpath "*) ;;
+		   *) func_append xrpath " $temp_xrpath";;
+		   esac;;
+	      *) func_append temp_deplibs " $libdir";;
+	      esac
+	    done
+	    dependency_libs="$temp_deplibs"
+	  fi
+
+	  func_append newlib_search_path " $absdir"
+	  # Link against this library
+	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  # ... and its dependency_libs
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    newdependency_libs="$deplib $newdependency_libs"
+	    case $deplib in
+              -L*) func_stripname '-L' '' "$deplib"
+                   func_resolve_sysroot "$func_stripname_result";;
+              *) func_resolve_sysroot "$deplib" ;;
+            esac
+	    if $opt_preserve_dup_deps ; then
+	      case "$tmp_libs " in
+	      *" $func_resolve_sysroot_result "*)
+                func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $func_resolve_sysroot_result"
+	  done
+
+	  if test "$link_all_deplibs" != no; then
+	    # Add the search paths of all dependency libraries
+	    for deplib in $dependency_libs; do
+	      path=
+	      case $deplib in
+	      -L*) path="$deplib" ;;
+	      *.la)
+	        func_resolve_sysroot "$deplib"
+	        deplib=$func_resolve_sysroot_result
+	        func_dirname "$deplib" "" "."
+		dir=$func_dirname_result
+		# We need an absolute path.
+		case $dir in
+		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+		*)
+		  absdir=`cd "$dir" && pwd`
+		  if test -z "$absdir"; then
+		    func_warning "cannot determine absolute directory name of \`$dir'"
+		    absdir="$dir"
+		  fi
+		  ;;
+		esac
+		if $GREP "^installed=no" $deplib > /dev/null; then
+		case $host in
+		*-*-darwin*)
+		  depdepl=
+		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names" ; then
+		    for tmp in $deplibrary_names ; do
+		      depdepl=$tmp
+		    done
+		    if test -f "$absdir/$objdir/$depdepl" ; then
+		      depdepl="$absdir/$objdir/$depdepl"
+		      darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+                      if test -z "$darwin_install_name"; then
+                          darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
+                      fi
+		      func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+		      func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
+		      path=
+		    fi
+		  fi
+		  ;;
+		*)
+		  path="-L$absdir/$objdir"
+		  ;;
+		esac
+		else
+		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  test -z "$libdir" && \
+		    func_fatal_error "\`$deplib' is not a valid libtool archive"
+		  test "$absdir" != "$libdir" && \
+		    func_warning "\`$deplib' seems to be moved"
+
+		  path="-L$absdir"
+		fi
+		;;
+	      esac
+	      case " $deplibs " in
+	      *" $path "*) ;;
+	      *) deplibs="$path $deplibs" ;;
+	      esac
+	    done
+	  fi # link_all_deplibs != no
+	fi # linkmode = lib
+      done # for deplib in $libs
+      if test "$pass" = link; then
+	if test "$linkmode" = "prog"; then
+	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+	else
+	  compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	fi
+      fi
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
+	# Link the dlpreopened libraries before other libraries
+	for deplib in $save_deplibs; do
+	  deplibs="$deplib $deplibs"
+	done
+      fi
+      if test "$pass" != dlopen; then
+	if test "$pass" != conv; then
+	  # Make sure lib_search_path contains only unique directories.
+	  lib_search_path=
+	  for dir in $newlib_search_path; do
+	    case "$lib_search_path " in
+	    *" $dir "*) ;;
+	    *) func_append lib_search_path " $dir" ;;
+	    esac
+	  done
+	  newlib_search_path=
+	fi
+
+	if test "$linkmode,$pass" != "prog,link"; then
+	  vars="deplibs"
+	else
+	  vars="compile_deplibs finalize_deplibs"
+	fi
+	for var in $vars dependency_libs; do
+	  # Add libraries to $var in reverse order
+	  eval tmp_libs=\"\$$var\"
+	  new_libs=
+	  for deplib in $tmp_libs; do
+	    # FIXME: Pedantically, this is the right thing to do, so
+	    #        that some nasty dependency loop isn't accidentally
+	    #        broken:
+	    #new_libs="$deplib $new_libs"
+	    # Pragmatically, this seems to cause very few problems in
+	    # practice:
+	    case $deplib in
+	    -L*) new_libs="$deplib $new_libs" ;;
+	    -R*) ;;
+	    *)
+	      # And here is the reason: when a library appears more
+	      # than once as an explicit dependence of a library, or
+	      # is implicitly linked in more than once by the
+	      # compiler, it is considered special, and multiple
+	      # occurrences thereof are not removed.  Compare this
+	      # with having the same library being listed as a
+	      # dependency of multiple other libraries: in this case,
+	      # we know (pedantically, we assume) the library does not
+	      # need to be listed more than once, so we keep only the
+	      # last copy.  This is not always right, but it is rare
+	      # enough that we require users that really mean to play
+	      # such unportable linking tricks to link the library
+	      # using -Wl,-lname, so that libtool does not consider it
+	      # for duplicate removal.
+	      case " $specialdeplibs " in
+	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
+	      *)
+		case " $new_libs " in
+		*" $deplib "*) ;;
+		*) new_libs="$deplib $new_libs" ;;
+		esac
+		;;
+	      esac
+	      ;;
+	    esac
+	  done
+	  tmp_libs=
+	  for deplib in $new_libs; do
+	    case $deplib in
+	    -L*)
+	      case " $tmp_libs " in
+	      *" $deplib "*) ;;
+	      *) func_append tmp_libs " $deplib" ;;
+	      esac
+	      ;;
+	    *) func_append tmp_libs " $deplib" ;;
+	    esac
+	  done
+	  eval $var=\"$tmp_libs\"
+	done # for var
+      fi
+      # Last step: remove runtime libs from dependency_libs
+      # (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs ; do
+	case " $predeps $postdeps $compiler_lib_search_path " in
+	*" $i "*)
+	  i=""
+	  ;;
+	esac
+	if test -n "$i" ; then
+	  func_append tmp_libs " $i"
+	fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
+    fi
+    if test "$linkmode" = prog || test "$linkmode" = lib; then
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for archives"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for archives" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for archives"
+
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for archives"
+
+      test -n "$vinfo" && \
+	func_warning "\`-version-info/-version-number' is ignored for archives"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for archives"
+
+      test -n "$export_symbols$export_symbols_regex" && \
+	func_warning "\`-export-symbols' is ignored for archives"
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      func_append objs "$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+	func_stripname 'lib' '.la' "$outputname"
+	name=$func_stripname_result
+	eval shared_ext=\"$shrext_cmds\"
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	test "$module" = no && \
+	  func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+	if test "$need_lib_prefix" != no; then
+	  # Add the "lib" prefix for modules if required
+	  func_stripname '' '.la' "$outputname"
+	  name=$func_stripname_result
+	  eval shared_ext=\"$shrext_cmds\"
+	  eval libname=\"$libname_spec\"
+	else
+	  func_stripname '' '.la' "$outputname"
+	  libname=$func_stripname_result
+	fi
+	;;
+      esac
+
+      if test -n "$objs"; then
+	if test "$deplibs_check_method" != pass_all; then
+	  func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+	else
+	  echo
+	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+	  $ECHO "*** objects $objs is not portable!"
+	  func_append libobjs " $objs"
+	fi
+      fi
+
+      test "$dlself" != no && \
+	func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+      set dummy $rpath
+      shift
+      test "$#" -gt 1 && \
+	func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+      install_libdir="$1"
+
+      oldlibs=
+      if test -z "$rpath"; then
+	if test "$build_libtool_libs" = yes; then
+	  # Building a libtool convenience library.
+	  # Some compilers have problems with a `.al' extension so
+	  # convenience libraries should have the same extension an
+	  # archive normally would.
+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
+	  build_libtool_libs=convenience
+	  build_old_libs=yes
+	fi
+
+	test -n "$vinfo" && \
+	  func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+	test -n "$release" && \
+	  func_warning "\`-release' is ignored for convenience libraries"
+      else
+
+	# Parse the version information argument.
+	save_ifs="$IFS"; IFS=':'
+	set dummy $vinfo 0 0 0
+	shift
+	IFS="$save_ifs"
+
+	test -n "$7" && \
+	  func_fatal_help "too many parameters to \`-version-info'"
+
+	# convert absolute version numbers to libtool ages
+	# this retains compatibility with .la files and attempts
+	# to make the code below a bit more comprehensible
+
+	case $vinfo_number in
+	yes)
+	  number_major="$1"
+	  number_minor="$2"
+	  number_revision="$3"
+	  #
+	  # There are really only two kinds -- those that
+	  # use the current revision as the major version
+	  # and those that subtract age and use age as
+	  # a minor version.  But, then there is irix
+	  # which has an extra 1 added just for fun
+	  #
+	  case $version_type in
+	  darwin|linux|osf|windows|none)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_revision"
+	    ;;
+	  freebsd-aout|freebsd-elf|qnx|sunos)
+	    current="$number_major"
+	    revision="$number_minor"
+	    age="0"
+	    ;;
+	  irix|nonstopux)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_minor"
+	    lt_irix_increment=no
+	    ;;
+	  esac
+	  ;;
+	no)
+	  current="$1"
+	  revision="$2"
+	  age="$3"
+	  ;;
+	esac
+
+	# Check that each of the things are valid numbers.
+	case $current in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "CURRENT \`$current' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $revision in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "REVISION \`$revision' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $age in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "AGE \`$age' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	if test "$age" -gt "$current"; then
+	  func_error "AGE \`$age' is greater than the current interface number \`$current'"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	fi
+
+	# Calculate the version variables.
+	major=
+	versuffix=
+	verstring=
+	case $version_type in
+	none) ;;
+
+	darwin)
+	  # Like Linux, but with the current version available in
+	  # verstring for coding it into the library header
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  # Darwin ld doesn't like 0 for these options...
+	  func_arith $current + 1
+	  minor_current=$func_arith_result
+	  xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+	  ;;
+
+	freebsd-aout)
+	  major=".$current"
+	  versuffix=".$current.$revision";
+	  ;;
+
+	freebsd-elf)
+	  major=".$current"
+	  versuffix=".$current"
+	  ;;
+
+	irix | nonstopux)
+	  if test "X$lt_irix_increment" = "Xno"; then
+	    func_arith $current - $age
+	  else
+	    func_arith $current - $age + 1
+	  fi
+	  major=$func_arith_result
+
+	  case $version_type in
+	    nonstopux) verstring_prefix=nonstopux ;;
+	    *)         verstring_prefix=sgi ;;
+	  esac
+	  verstring="$verstring_prefix$major.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$revision
+	  while test "$loop" -ne 0; do
+	    func_arith $revision - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring_prefix$major.$iface:$verstring"
+	  done
+
+	  # Before this point, $major must not contain `.'.
+	  major=.$major
+	  versuffix="$major.$revision"
+	  ;;
+
+	linux)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  ;;
+
+	osf)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$age
+	  while test "$loop" -ne 0; do
+	    func_arith $current - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring:${iface}.0"
+	  done
+
+	  # Make executables depend on our current version.
+	  func_append verstring ":${current}.0"
+	  ;;
+
+	qnx)
+	  major=".$current"
+	  versuffix=".$current"
+	  ;;
+
+	sunos)
+	  major=".$current"
+	  versuffix=".$current.$revision"
+	  ;;
+
+	windows)
+	  # Use '-' rather than '.', since we only want one
+	  # extension on DOS 8.3 filesystems.
+	  func_arith $current - $age
+	  major=$func_arith_result
+	  versuffix="-$major"
+	  ;;
+
+	*)
+	  func_fatal_configuration "unknown library version type \`$version_type'"
+	  ;;
+	esac
+
+	# Clear the version info if we defaulted, and they specified a release.
+	if test -z "$vinfo" && test -n "$release"; then
+	  major=
+	  case $version_type in
+	  darwin)
+	    # we can't check for "0.0" in archive_cmds due to quoting
+	    # problems, so we reset it completely
+	    verstring=
+	    ;;
+	  *)
+	    verstring="0.0"
+	    ;;
+	  esac
+	  if test "$need_version" = no; then
+	    versuffix=
+	  else
+	    versuffix=".0.0"
+	  fi
+	fi
+
+	# Remove version info from name if versioning should be avoided
+	if test "$avoid_version" = yes && test "$need_version" = no; then
+	  major=
+	  versuffix=
+	  verstring=""
+	fi
+
+	# Check to see if the archive will have undefined symbols.
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    func_warning "undefined symbols not allowed in $host shared libraries"
+	    build_libtool_libs=no
+	    build_old_libs=yes
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag="$no_undefined_flag"
+	fi
+
+      fi
+
+      func_generate_dlsyms "$libname" "$libname" "yes"
+      func_append libobjs " $symfileobj"
+      test "X$libobjs" = "X " && libobjs=
+
+      if test "$opt_mode" != relink; then
+	# Remove our outputs, but don't remove object files since they
+	# may have been created when compiling PIC objects.
+	removelist=
+	tempremovelist=`$ECHO "$output_objdir/*"`
+	for p in $tempremovelist; do
+	  case $p in
+	    *.$objext | *.gcno)
+	       ;;
+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+	       if test "X$precious_files_regex" != "X"; then
+		 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+		 then
+		   continue
+		 fi
+	       fi
+	       func_append removelist " $p"
+	       ;;
+	    *) ;;
+	  esac
+	done
+	test -n "$removelist" && \
+	  func_show_eval "${RM}r \$removelist"
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+	func_append oldlibs " $output_objdir/$libname.$libext"
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      #for path in $notinst_path; do
+      #	lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+      #	deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+      #	dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+      #done
+
+      if test -n "$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	temp_xrpath=
+	for libdir in $xrpath; do
+	  func_replace_sysroot "$libdir"
+	  func_append temp_xrpath " -R$func_replace_sysroot_result"
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_rpath " $libdir" ;;
+	  esac
+	done
+	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+	  dependency_libs="$temp_xrpath $dependency_libs"
+	fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles="$dlfiles"
+      dlfiles=
+      for lib in $old_dlfiles; do
+	case " $dlprefiles $dlfiles " in
+	*" $lib "*) ;;
+	*) func_append dlfiles " $lib" ;;
+	esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles="$dlprefiles"
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+	case "$dlprefiles " in
+	*" $lib "*) ;;
+	*) func_append dlprefiles " $lib" ;;
+	esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+	if test -n "$rpath"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # these systems don't actually have a c library (as such)!
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C library is in the System framework
+	    func_append deplibs " System.ltframework"
+	    ;;
+	  *-*-netbsd*)
+	    # Don't link with libc until the a.out ld.so is fixed.
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    ;;
+	  *)
+	    # Add libc to deplibs on all other systems if necessary.
+	    if test "$build_libtool_need_lc" = "yes"; then
+	      func_append deplibs " -lc"
+	    fi
+	    ;;
+	  esac
+	fi
+
+	# Transform deplibs into only deplibs that can be linked in shared.
+	name_save=$name
+	libname_save=$libname
+	release_save=$release
+	versuffix_save=$versuffix
+	major_save=$major
+	# I'm not sure if I'm treating the release correctly.  I think
+	# release should show up in the -l (ie -lgmp5) so we don't want to
+	# add it in twice.  Is that correct?
+	release=""
+	versuffix=""
+	major=""
+	newdeplibs=
+	droppeddeps=no
+	case $deplibs_check_method in
+	pass_all)
+	  # Don't check for shared/static.  Everything works.
+	  # This might be a little naive.  We might want to check
+	  # whether the library exists or not.  But this is on
+	  # osf3 & osf4 and I'm not really sure... Just
+	  # implementing what was already the behavior.
+	  newdeplibs=$deplibs
+	  ;;
+	test_compile)
+	  # This code stresses the "libraries are programs" paradigm to its
+	  # limits. Maybe even breaks it.  We compile a program, linking it
+	  # against the deplibs as a proxy for the library.  Then we can check
+	  # whether they linked in statically or dynamically with ldd.
+	  $opt_dry_run || $RM conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $opt_dry_run || $RM conftest
+	  if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		  case " $predeps $postdeps " in
+		  *" $i "*)
+		    func_append newdeplibs " $i"
+		    i=""
+		    ;;
+		  esac
+		fi
+		if test -n "$i" ; then
+		  libname=`eval "\\$ECHO \"$libname_spec\""`
+		  deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		  set dummy $deplib_matches; shift
+		  deplib_match=$1
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		    func_append newdeplibs " $i"
+		  else
+		    droppeddeps=yes
+		    echo
+		    $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		    echo "*** I have the capability to make that library automatically link in when"
+		    echo "*** you link to this library.  But I can only do this if you have a"
+		    echo "*** shared version of the library, which I believe you do not have"
+		    echo "*** because a test_compile did reveal that the linker did not use it for"
+		    echo "*** its dynamic dependency list that programs get resolved with at runtime."
+		  fi
+		fi
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    done
+	  else
+	    # Error occurred in the first compile.  Let's try to salvage
+	    # the situation: Compile a separate program for each library.
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		$opt_dry_run || $RM conftest
+		if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+		  ldd_output=`ldd conftest`
+		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		    case " $predeps $postdeps " in
+		    *" $i "*)
+		      func_append newdeplibs " $i"
+		      i=""
+		      ;;
+		    esac
+		  fi
+		  if test -n "$i" ; then
+		    libname=`eval "\\$ECHO \"$libname_spec\""`
+		    deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		    set dummy $deplib_matches; shift
+		    deplib_match=$1
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		      func_append newdeplibs " $i"
+		    else
+		      droppeddeps=yes
+		      echo
+		      $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		      echo "*** I have the capability to make that library automatically link in when"
+		      echo "*** you link to this library.  But I can only do this if you have a"
+		      echo "*** shared version of the library, which you do not appear to have"
+		      echo "*** because a test_compile did reveal that the linker did not use this one"
+		      echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+		    fi
+		  fi
+		else
+		  droppeddeps=yes
+		  echo
+		  $ECHO "*** Warning!  Library $i is needed by this library but I was not able to"
+		  echo "*** make it link in!  You will probably need to install it or some"
+		  echo "*** library that it depends on before this library will be fully"
+		  echo "*** functional.  Installing it before continuing would be even better."
+		fi
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method; shift
+	  file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append newdeplibs " $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		if test -n "$file_magic_glob"; then
+		  libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+		else
+		  libnameglob=$libname
+		fi
+		test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  if test "$want_nocaseglob" = yes; then
+		    shopt -s nocaseglob
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		    $nocaseglob
+		  else
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		  fi
+		  for potent_lib in $potential_libs; do
+		      # Follow soft links.
+		      if ls -lLd "$potent_lib" 2>/dev/null |
+			 $GREP " -> " >/dev/null; then
+			continue
+		      fi
+		      # The statement above tries to avoid entering an
+		      # endless loop below, in case of cyclic links.
+		      # We might still enter an endless loop, since a link
+		      # loop can be closed while we follow links,
+		      # but so what?
+		      potlib="$potent_lib"
+		      while test -h "$potlib" 2>/dev/null; do
+			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+			case $potliblink in
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+			 $SED -e 10q |
+			 $EGREP "$file_magic_regex" > /dev/null; then
+			func_append newdeplibs " $a_deplib"
+			a_deplib=""
+			break 2
+		      fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		echo
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a file magic. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	match_pattern*)
+	  set dummy $deplibs_check_method; shift
+	  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append newdeplibs " $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		    potlib="$potent_lib" # see symlink-check above in file_magic test
+		    if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+		       $EGREP "$match_pattern_regex" > /dev/null; then
+		      func_append newdeplibs " $a_deplib"
+		      a_deplib=""
+		      break 2
+		    fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		echo
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a regex pattern. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=""
+	  tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	    for i in $predeps $postdeps ; do
+	      # can't use Xsed below, because $i might contain '/'
+	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
+	    done
+	  fi
+	  case $tmp_deplibs in
+	  *[!\	\ ]*)
+	    echo
+	    if test "X$deplibs_check_method" = "Xnone"; then
+	      echo "*** Warning: inter-library dependencies are not supported in this platform."
+	    else
+	      echo "*** Warning: inter-library dependencies are not known to be supported."
+	    fi
+	    echo "*** All declared inter-library dependencies are being dropped."
+	    droppeddeps=yes
+	    ;;
+	  esac
+	  ;;
+	esac
+	versuffix=$versuffix_save
+	major=$major_save
+	release=$release_save
+	libname=$libname_save
+	name=$name_save
+
+	case $host in
+	*-*-rhapsody* | *-*-darwin1.[012])
+	  # On Rhapsody replace the C library with the System framework
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+	  ;;
+	esac
+
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
+	    echo
+	    echo "*** Warning: libtool could not satisfy all declared inter-library"
+	    $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
+	    echo "*** a static module, that should work as long as the dlopening"
+	    echo "*** application is linked with the -dlopen flag."
+	    if test -z "$global_symbol_pipe"; then
+	      echo
+	      echo "*** However, this would only work if libtool was able to extract symbol"
+	      echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+	      echo "*** not find such a program.  So, this module is probably useless."
+	      echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	    fi
+	    if test "$build_old_libs" = no; then
+	      oldlibs="$output_objdir/$libname.$libext"
+	      build_libtool_libs=module
+	      build_old_libs=yes
+	    else
+	      build_libtool_libs=no
+	    fi
+	  else
+	    echo "*** The inter-library dependencies that have been dropped here will be"
+	    echo "*** automatically added whenever a program is linked with this library"
+	    echo "*** or is declared to -dlopen it."
+
+	    if test "$allow_undefined" = no; then
+	      echo
+	      echo "*** Since this library must not contain undefined symbols,"
+	      echo "*** because either the platform does not support them or"
+	      echo "*** it was explicitly requested with -no-undefined,"
+	      echo "*** libtool will only create a static version of it."
+	      if test "$build_old_libs" = no; then
+		oldlibs="$output_objdir/$libname.$libext"
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  fi
+	fi
+	# Done checking deplibs!
+	deplibs=$newdeplibs
+      fi
+      # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+      case $host in
+	*-*-darwin*)
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  ;;
+      esac
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $deplibs " in
+	  *" -L$path/$objdir "*)
+	    func_append new_libs " -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
+	  esac
+	  ;;
+	*) func_append new_libs " $deplib" ;;
+	esac
+      done
+      deplibs="$new_libs"
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+	if test "$hardcode_into_libs" = yes; then
+	  # Hardcode the library paths
+	  hardcode_libdirs=
+	  dep_rpath=
+	  rpath="$finalize_rpath"
+	  test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
+	  for libdir in $rpath; do
+	    if test -n "$hardcode_libdir_flag_spec"; then
+	      if test -n "$hardcode_libdir_separator"; then
+		func_replace_sysroot "$libdir"
+		libdir=$func_replace_sysroot_result
+		if test -z "$hardcode_libdirs"; then
+		  hardcode_libdirs="$libdir"
+		else
+		  # Just accumulate the unique libdirs.
+		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		    ;;
+		  *)
+		    func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		    ;;
+		  esac
+		fi
+	      else
+		eval flag=\"$hardcode_libdir_flag_spec\"
+		func_append dep_rpath " $flag"
+	      fi
+	    elif test -n "$runpath_var"; then
+	      case "$perm_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_apped perm_rpath " $libdir" ;;
+	      esac
+	    fi
+	  done
+	  # Substitute the hardcoded libdirs into the rpath.
+	  if test -n "$hardcode_libdir_separator" &&
+	     test -n "$hardcode_libdirs"; then
+	    libdir="$hardcode_libdirs"
+	    if test -n "$hardcode_libdir_flag_spec_ld"; then
+	      eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+	    else
+	      eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+	    fi
+	  fi
+	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
+	    # We should set the runpath_var.
+	    rpath=
+	    for dir in $perm_rpath; do
+	      func_append rpath "$dir:"
+	    done
+	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+	  fi
+	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+	fi
+
+	shlibpath="$finalize_shlibpath"
+	test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+	if test -n "$shlibpath"; then
+	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+	fi
+
+	# Get the real and link names of the library.
+	eval shared_ext=\"$shrext_cmds\"
+	eval library_names=\"$library_names_spec\"
+	set dummy $library_names
+	shift
+	realname="$1"
+	shift
+
+	if test -n "$soname_spec"; then
+	  eval soname=\"$soname_spec\"
+	else
+	  soname="$realname"
+	fi
+	if test -z "$dlname"; then
+	  dlname=$soname
+	fi
+
+	lib="$output_objdir/$realname"
+	linknames=
+	for link
+	do
+	  func_append linknames " $link"
+	done
+
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	test "X$libobjs" = "X " && libobjs=
+
+	delfiles=
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+	  export_symbols="$output_objdir/$libname.uexp"
+	  func_append delfiles " $export_symbols"
+	fi
+
+	orig_export_symbols=
+	case $host_os in
+	cygwin* | mingw* | cegcc*)
+	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+	    # exporting using user supplied symfile
+	    if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+	      # and it's NOT already a .def file. Must figure out
+	      # which of the given symbols are data symbols and tag
+	      # them as such. So, trigger use of export_symbols_cmds.
+	      # export_symbols gets reassigned inside the "prepare
+	      # the list of exported symbols" if statement, so the
+	      # include_expsyms logic still works.
+	      orig_export_symbols="$export_symbols"
+	      export_symbols=
+	      always_export_symbols=yes
+	    fi
+	  fi
+	  ;;
+	esac
+
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    func_verbose "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $opt_dry_run || $RM $export_symbols
+	    cmds=$export_symbols_cmds
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd1 in $cmds; do
+	      IFS="$save_ifs"
+	      # Take the normal branch if the nm_file_list_spec branch
+	      # doesn't work or if tool conversion is not needed.
+	      case $nm_file_list_spec~$to_tool_file_cmd in
+		*~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+		  try_normal_branch=yes
+		  eval cmd=\"$cmd1\"
+		  func_len " $cmd"
+		  len=$func_len_result
+		  ;;
+		*)
+		  try_normal_branch=no
+		  ;;
+	      esac
+	      if test "$try_normal_branch" = yes \
+		 && { test "$len" -lt "$max_cmd_len" \
+		      || test "$max_cmd_len" -le -1; }
+	      then
+		func_show_eval "$cmd" 'exit $?'
+		skipped_export=false
+	      elif test -n "$nm_file_list_spec"; then
+		func_basename "$output"
+		output_la=$func_basename_result
+		save_libobjs=$libobjs
+		save_output=$output
+		output=${output_objdir}/${output_la}.nm
+		func_to_tool_file "$output"
+		libobjs=$nm_file_list_spec$func_to_tool_file_result
+		func_append delfiles " $output"
+		func_verbose "creating $NM input file list: $output"
+		for obj in $save_libobjs; do
+		  func_to_tool_file "$obj"
+		  $ECHO "$func_to_tool_file_result"
+		done > "$output"
+		eval cmd=\"$cmd1\"
+		func_show_eval "$cmd" 'exit $?'
+		output=$save_output
+		libobjs=$save_libobjs
+		skipped_export=false
+	      else
+		# The command line is too long to execute in one step.
+		func_verbose "using reloadable object file for export list..."
+		skipped_export=:
+		# Break out early, otherwise skipped_export may be
+		# set to false by a later but shorter cmd.
+		break
+	      fi
+	    done
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  tmp_export_symbols="$export_symbols"
+	  test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	  $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+	fi
+
+	if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+	  # The given exports_symbols file has to be filtered, so filter it.
+	  func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	  # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	  # 's' commands which not all seds can handle. GNU sed should be fine
+	  # though. Also, the filter scales superlinearly with the number of
+	  # global variables. join(1) would be nice here, but unfortunately
+	  # isn't a blessed tool.
+	  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	  func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	  export_symbols=$output_objdir/$libname.def
+	  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	fi
+
+	tmp_deplibs=
+	for test_deplib in $deplibs; do
+	  case " $convenience " in
+	  *" $test_deplib "*) ;;
+	  *)
+	    func_append tmp_deplibs " $test_deplib"
+	    ;;
+	  esac
+	done
+	deplibs="$tmp_deplibs"
+
+	if test -n "$convenience"; then
+	  if test -n "$whole_archive_flag_spec" &&
+	    test "$compiler_needs_object" = yes &&
+	    test -z "$libobjs"; then
+	    # extract the archives, so we have objects to list.
+	    # TODO: could optimize this to just extract one archive.
+	    whole_archive_flag_spec=
+	  fi
+	  if test -n "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  else
+	    gentop="$output_objdir/${outputname}x"
+	    func_append generated " $gentop"
+
+	    func_extract_archives $gentop $convenience
+	    func_append libobjs " $func_extract_archives_result"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	fi
+
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  func_append linker_flags " $flag"
+	fi
+
+	# Make a backup of the uninstalled library when relinking
+	if test "$opt_mode" = relink; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+	fi
+
+	# Do each of the archive commands.
+	if test "$module" = yes && test -n "$module_cmds" ; then
+	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	    eval test_cmds=\"$module_expsym_cmds\"
+	    cmds=$module_expsym_cmds
+	  else
+	    eval test_cmds=\"$module_cmds\"
+	    cmds=$module_cmds
+	  fi
+	else
+	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	    eval test_cmds=\"$archive_expsym_cmds\"
+	    cmds=$archive_expsym_cmds
+	  else
+	    eval test_cmds=\"$archive_cmds\"
+	    cmds=$archive_cmds
+	  fi
+	fi
+
+	if test "X$skipped_export" != "X:" &&
+	   func_len " $test_cmds" &&
+	   len=$func_len_result &&
+	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  :
+	else
+	  # The command line is too long to link in one step, link piecewise
+	  # or, if using GNU ld and skipped_export is not :, use a linker
+	  # script.
+
+	  # Save the value of $output and $libobjs because we want to
+	  # use them later.  If we have whole_archive_flag_spec, we
+	  # want to use save_libobjs as it was before
+	  # whole_archive_flag_spec was expanded, because we can't
+	  # assume the linker understands whole_archive_flag_spec.
+	  # This may have to be revisited, in case too many
+	  # convenience libraries get linked in and end up exceeding
+	  # the spec.
+	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	  fi
+	  save_output=$output
+	  func_basename "$output"
+	  output_la=$func_basename_result
+
+	  # Clear the reloadable object creation command queue and
+	  # initialize k to one.
+	  test_cmds=
+	  concat_cmds=
+	  objlist=
+	  last_robj=
+	  k=1
+
+	  if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+	    output=${output_objdir}/${output_la}.lnkscript
+	    func_verbose "creating GNU ld script: $output"
+	    echo 'INPUT (' > $output
+	    for obj in $save_libobjs
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    echo ')' >> $output
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$func_to_tool_file_result
+	  elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+	    output=${output_objdir}/${output_la}.lnk
+	    func_verbose "creating linker input file list: $output"
+	    : > $output
+	    set x $save_libobjs
+	    shift
+	    firstobj=
+	    if test "$compiler_needs_object" = yes; then
+	      firstobj="$1 "
+	      shift
+	    fi
+	    for obj
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+	  else
+	    if test -n "$save_libobjs"; then
+	      func_verbose "creating reloadable object files..."
+	      output=$output_objdir/$output_la-${k}.$objext
+	      eval test_cmds=\"$reload_cmds\"
+	      func_len " $test_cmds"
+	      len0=$func_len_result
+	      len=$len0
+
+	      # Loop over the list of objects to be linked.
+	      for obj in $save_libobjs
+	      do
+		func_len " $obj"
+		func_arith $len + $func_len_result
+		len=$func_arith_result
+		if test "X$objlist" = X ||
+		   test "$len" -lt "$max_cmd_len"; then
+		  func_append objlist " $obj"
+		else
+		  # The command $test_cmds is almost too long, add a
+		  # command to the queue.
+		  if test "$k" -eq 1 ; then
+		    # The first file doesn't have a previous command to add.
+		    reload_objs=$objlist
+		    eval concat_cmds=\"$reload_cmds\"
+		  else
+		    # All subsequent reloadable object files will link in
+		    # the last one created.
+		    reload_objs="$objlist $last_robj"
+		    eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+		  fi
+		  last_robj=$output_objdir/$output_la-${k}.$objext
+		  func_arith $k + 1
+		  k=$func_arith_result
+		  output=$output_objdir/$output_la-${k}.$objext
+		  objlist=" $obj"
+		  func_len " $last_robj"
+		  func_arith $len0 + $func_len_result
+		  len=$func_arith_result
+		fi
+	      done
+	      # Handle the remaining objects by creating one last
+	      # reloadable object file.  All subsequent reloadable object
+	      # files will link in the last one created.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      reload_objs="$objlist $last_robj"
+	      eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
+	      if test -n "$last_robj"; then
+	        eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+	      fi
+	      func_append delfiles " $output"
+
+	    else
+	      output=
+	    fi
+
+	    if ${skipped_export-false}; then
+	      func_verbose "generating symbol list for \`$libname.la'"
+	      export_symbols="$output_objdir/$libname.exp"
+	      $opt_dry_run || $RM $export_symbols
+	      libobjs=$output
+	      # Append the command to create the export file.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+	      if test -n "$last_robj"; then
+		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+	      fi
+	    fi
+
+	    test -n "$save_libobjs" &&
+	      func_verbose "creating a temporary reloadable object file: $output"
+
+	    # Loop through the commands generated above and execute them.
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd in $concat_cmds; do
+	      IFS="$save_ifs"
+	      $opt_silent || {
+		  func_quote_for_expand "$cmd"
+		  eval "func_echo $func_quote_for_expand_result"
+	      }
+	      $opt_dry_run || eval "$cmd" || {
+		lt_exit=$?
+
+		# Restore the uninstalled library and exit
+		if test "$opt_mode" = relink; then
+		  ( cd "$output_objdir" && \
+		    $RM "${realname}T" && \
+		    $MV "${realname}U" "$realname" )
+		fi
+
+		exit $lt_exit
+	      }
+	    done
+	    IFS="$save_ifs"
+
+	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+
+          if ${skipped_export-false}; then
+	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	      tmp_export_symbols="$export_symbols"
+	      test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	      $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+	    fi
+
+	    if test -n "$orig_export_symbols"; then
+	      # The given exports_symbols file has to be filtered, so filter it.
+	      func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	      # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	      # 's' commands which not all seds can handle. GNU sed should be fine
+	      # though. Also, the filter scales superlinearly with the number of
+	      # global variables. join(1) would be nice here, but unfortunately
+	      # isn't a blessed tool.
+	      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	      func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	      export_symbols=$output_objdir/$libname.def
+	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	    fi
+	  fi
+
+	  libobjs=$output
+	  # Restore the value of output.
+	  output=$save_output
+
+	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	  # Expand the library linking commands again to reset the
+	  # value of $libobjs for piecewise linking.
+
+	  # Do each of the archive commands.
+	  if test "$module" = yes && test -n "$module_cmds" ; then
+	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	      cmds=$module_expsym_cmds
+	    else
+	      cmds=$module_cmds
+	    fi
+	  else
+	    if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	      cmds=$archive_expsym_cmds
+	    else
+	      cmds=$archive_cmds
+	    fi
+	  fi
+	fi
+
+	if test -n "$delfiles"; then
+	  # Append the command to remove temporary files to $cmds.
+	  eval cmds=\"\$cmds~\$RM $delfiles\"
+	fi
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  func_append libobjs " $func_extract_archives_result"
+	  test "X$libobjs" = "X " && libobjs=
+	fi
+
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  eval cmd=\"$cmd\"
+	  $opt_silent || {
+	    func_quote_for_expand "$cmd"
+	    eval "func_echo $func_quote_for_expand_result"
+	  }
+	  $opt_dry_run || eval "$cmd" || {
+	    lt_exit=$?
+
+	    # Restore the uninstalled library and exit
+	    if test "$opt_mode" = relink; then
+	      ( cd "$output_objdir" && \
+	        $RM "${realname}T" && \
+		$MV "${realname}U" "$realname" )
+	    fi
+
+	    exit $lt_exit
+	  }
+	done
+	IFS="$save_ifs"
+
+	# Restore the uninstalled library and exit
+	if test "$opt_mode" = relink; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+	  if test -n "$convenience"; then
+	    if test -z "$whole_archive_flag_spec"; then
+	      func_show_eval '${RM}r "$gentop"'
+	    fi
+	  fi
+
+	  exit $EXIT_SUCCESS
+	fi
+
+	# Create links to the real library.
+	for linkname in $linknames; do
+	  if test "$realname" != "$linkname"; then
+	    func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+	  fi
+	done
+
+	# If -module or -export-dynamic was specified, set the dlname.
+	if test "$module" = yes || test "$export_dynamic" = yes; then
+	  # On all known operating systems, these are identical.
+	  dlname="$soname"
+	fi
+      fi
+      ;;
+
+    obj)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for objects"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for objects" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for objects"
+
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for objects"
+
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for objects"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for objects"
+
+      case $output in
+      *.lo)
+	test -n "$objs$old_deplibs" && \
+	  func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+	libobj=$output
+	func_lo2o "$libobj"
+	obj=$func_lo2o_result
+	;;
+      *)
+	libobj=
+	obj="$output"
+	;;
+      esac
+
+      # Delete the old objects.
+      $opt_dry_run || $RM $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec and hope we can get by with
+      # turning comma into space..
+      wl=
+
+      if test -n "$convenience"; then
+	if test -n "$whole_archive_flag_spec"; then
+	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+	  reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+	else
+	  gentop="$output_objdir/${obj}x"
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $convenience
+	  reload_conv_objs="$reload_objs $func_extract_archives_result"
+	fi
+      fi
+
+      # If we're not building shared, we need to use non_pic_objs
+      test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
+
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+      output="$obj"
+      func_execute_cmds "$reload_cmds" 'exit $?'
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	# Create an invalid libtool object if no PIC, so that we don't
+	# accidentally link it into a program.
+	# $show "echo timestamp > $libobj"
+	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+	exit $EXIT_SUCCESS
+      fi
+
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
+	# Only do commands if we really have different PIC objects.
+	reload_objs="$libobjs $reload_conv_objs"
+	output="$libobj"
+	func_execute_cmds "$reload_cmds" 'exit $?'
+      fi
+
+      if test -n "$gentop"; then
+	func_show_eval '${RM}r "$gentop"'
+      fi
+
+      exit $EXIT_SUCCESS
+      ;;
+
+    prog)
+      case $host in
+	*cygwin*) func_stripname '' '.exe' "$output"
+	          output=$func_stripname_result.exe;;
+      esac
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for programs"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for programs"
+
+      test "$preload" = yes \
+        && test "$dlopen_support" = unknown \
+	&& test "$dlopen_self" = unknown \
+	&& test "$dlopen_self_static" = unknown && \
+	  func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+	# On Rhapsody replace the C library is the System framework
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+	;;
+      esac
+
+      case $host in
+      *-*-darwin*)
+	# Don't allow lazy linking, it breaks C++ global constructors
+	# But is supposedly fixed on 10.4 or later (yay!).
+	if test "$tagname" = CXX ; then
+	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+	    10.[0123])
+	      func_append compile_command " ${wl}-bind_at_load"
+	      func_append finalize_command " ${wl}-bind_at_load"
+	    ;;
+	  esac
+	fi
+	# Time to change all our "foo.ltframework" stuff back to "-framework foo"
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	;;
+      esac
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $compile_deplibs " in
+	  *" -L$path/$objdir "*)
+	    func_append new_libs " -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $compile_deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
+	  esac
+	  ;;
+	*) func_append new_libs " $deplib" ;;
+	esac
+      done
+      compile_deplibs="$new_libs"
+
+
+      func_append compile_command " $compile_deplibs"
+      func_append finalize_command " $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_rpath " $libdir" ;;
+	  esac
+	done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append perm_rpath " $libdir" ;;
+	  esac
+	fi
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$libdir:"*) ;;
+	  ::) dllsearchpath=$libdir;;
+	  *) func_append dllsearchpath ":$libdir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append dllsearchpath ":$testbindir";;
+	  esac
+	  ;;
+	esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_perm_rpath " $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+	# Transform all the library objects into standard objects.
+	compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+      fi
+
+      func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+      # template prelinking step
+      if test -n "$prelink_cmds"; then
+	func_execute_cmds "$prelink_cmds" 'exit $?'
+      fi
+
+      wrappers_required=yes
+      case $host in
+      *cegcc* | *mingw32ce*)
+        # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+        wrappers_required=no
+        ;;
+      *cygwin* | *mingw* )
+        if test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      *)
+        if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      esac
+      if test "$wrappers_required" = no; then
+	# Replace the output file specification.
+	compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	link_command="$compile_command$compile_rpath"
+
+	# We have no uninstalled library dependencies, so finalize right now.
+	exit_status=0
+	func_show_eval "$link_command" 'exit_status=$?'
+
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
+	fi
+
+	# Delete the generated files.
+	if test -f "$output_objdir/${outputname}S.${objext}"; then
+	  func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+	fi
+
+	exit $exit_status
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+	if test -n "$perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $perm_rpath; do
+	    func_append rpath "$dir:"
+	  done
+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+	if test -n "$finalize_perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $finalize_perm_rpath; do
+	    func_append rpath "$dir:"
+	  done
+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+      fi
+
+      if test "$no_install" = yes; then
+	# We don't need to create a wrapper script.
+	link_command="$compile_var$compile_command$compile_rpath"
+	# Replace the output file specification.
+	link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	# Delete the old output file.
+	$opt_dry_run || $RM $output
+	# Link the executable and exit
+	func_show_eval "$link_command" 'exit $?'
+
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+	func_warning "this platform does not like uninstalled shared libraries"
+	func_warning "\`$output' will be relinked during installation"
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
+	else
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
+	fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      func_show_eval "$link_command" 'exit $?'
+
+      if test -n "$postlink_cmds"; then
+	func_to_tool_file "$output_objdir/$outputname"
+	postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	func_execute_cmds "$postlink_cmds" 'exit $?'
+      fi
+
+      # Now create the wrapper script.
+      func_verbose "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+	# Preserve any variables that may affect compiler behavior
+	for var in $variables_saved_for_relink; do
+	  if eval test -z \"\${$var+set}\"; then
+	    relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	  elif eval var_value=\$$var; test -z "$var_value"; then
+	    relink_command="$var=; export $var; $relink_command"
+	  else
+	    func_quote_for_eval "$var_value"
+	    relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	  fi
+	done
+	relink_command="(cd `pwd`; $relink_command)"
+	relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if not in dry run mode.
+      $opt_dry_run || {
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) func_stripname '' '.exe' "$output"
+	         output=$func_stripname_result ;;
+	esac
+	# test for cygwin because mv fails w/o .exe extensions
+	case $host in
+	  *cygwin*)
+	    exeext=.exe
+	    func_stripname '' '.exe' "$outputname"
+	    outputname=$func_stripname_result ;;
+	  *) exeext= ;;
+	esac
+	case $host in
+	  *cygwin* | *mingw* )
+	    func_dirname_and_basename "$output" "" "."
+	    output_name=$func_basename_result
+	    output_path=$func_dirname_result
+	    cwrappersource="$output_path/$objdir/lt-$output_name.c"
+	    cwrapper="$output_path/$output_name.exe"
+	    $RM $cwrappersource $cwrapper
+	    trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_cwrapperexe_src > $cwrappersource
+
+	    # The wrapper executable is built using the $host compiler,
+	    # because it contains $host paths and files. If cross-
+	    # compiling, it, like the target executable, must be
+	    # executed on the $host or under an emulation environment.
+	    $opt_dry_run || {
+	      $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+	      $STRIP $cwrapper
+	    }
+
+	    # Now, create the wrapper script for func_source use:
+	    func_ltwrapper_scriptname $cwrapper
+	    $RM $func_ltwrapper_scriptname_result
+	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+	    $opt_dry_run || {
+	      # note: this script will not be executed, so do not chmod.
+	      if test "x$build" = "x$host" ; then
+		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+	      else
+		func_emit_wrapper no > $func_ltwrapper_scriptname_result
+	      fi
+	    }
+	  ;;
+	  * )
+	    $RM $output
+	    trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_wrapper no > $output
+	    chmod +x $output
+	  ;;
+	esac
+      }
+      exit $EXIT_SUCCESS
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save $symfileobj"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
+	  build_libtool_libs=no
+	else
+	  oldobjs="$old_deplibs $non_pic_objects"
+	  if test "$preload" = yes && test -f "$symfileobj"; then
+	    func_append oldobjs " $symfileobj"
+	  fi
+	fi
+	addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+	gentop="$output_objdir/${outputname}x"
+	func_append generated " $gentop"
+
+	func_extract_archives $gentop $addlibs
+	func_append oldobjs " $func_extract_archives_result"
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+	cmds=$old_archive_from_new_cmds
+      else
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  func_append oldobjs " $func_extract_archives_result"
+	fi
+
+	# POSIX demands no paths to be encoded in archives.  We have
+	# to avoid creating archives with duplicate basenames if we
+	# might have to extract them afterwards, e.g., when creating a
+	# static archive out of a convenience library, or when linking
+	# the entirety of a libtool archive into another (currently
+	# not supported by libtool).
+	if (for obj in $oldobjs
+	    do
+	      func_basename "$obj"
+	      $ECHO "$func_basename_result"
+	    done | sort | sort -uc >/dev/null 2>&1); then
+	  :
+	else
+	  echo "copying selected object files to avoid basename conflicts..."
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+	  func_mkdir_p "$gentop"
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  counter=1
+	  for obj in $save_oldobjs
+	  do
+	    func_basename "$obj"
+	    objbase="$func_basename_result"
+	    case " $oldobjs " in
+	    " ") oldobjs=$obj ;;
+	    *[\ /]"$objbase "*)
+	      while :; do
+		# Make sure we don't pick an alternate name that also
+		# overlaps.
+		newobj=lt$counter-$objbase
+		func_arith $counter + 1
+		counter=$func_arith_result
+		case " $oldobjs " in
+		*[\ /]"$newobj "*) ;;
+		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
+		esac
+	      done
+	      func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+	      func_append oldobjs " $gentop/$newobj"
+	      ;;
+	    *) func_append oldobjs " $obj" ;;
+	    esac
+	  done
+	fi
+	eval cmds=\"$old_archive_cmds\"
+
+	func_len " $cmds"
+	len=$func_len_result
+	if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  cmds=$old_archive_cmds
+	elif test -n "$archiver_list_spec"; then
+	  func_verbose "using command file archive linking..."
+	  for obj in $oldobjs
+	  do
+	    func_to_tool_file "$obj"
+	    $ECHO "$func_to_tool_file_result"
+	  done > $output_objdir/$libname.libcmd
+	  func_to_tool_file "$output_objdir/$libname.libcmd"
+	  oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+	  cmds=$old_archive_cmds
+	else
+	  # the command line is too long to link in one step, link in parts
+	  func_verbose "using piecewise archive linking..."
+	  save_RANLIB=$RANLIB
+	  RANLIB=:
+	  objlist=
+	  concat_cmds=
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  # Is there a better way of finding the last object in the list?
+	  for obj in $save_oldobjs
+	  do
+	    last_oldobj=$obj
+	  done
+	  eval test_cmds=\"$old_archive_cmds\"
+	  func_len " $test_cmds"
+	  len0=$func_len_result
+	  len=$len0
+	  for obj in $save_oldobjs
+	  do
+	    func_len " $obj"
+	    func_arith $len + $func_len_result
+	    len=$func_arith_result
+	    func_append objlist " $obj"
+	    if test "$len" -lt "$max_cmd_len"; then
+	      :
+	    else
+	      # the above command should be used before it gets too long
+	      oldobjs=$objlist
+	      if test "$obj" = "$last_oldobj" ; then
+		RANLIB=$save_RANLIB
+	      fi
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+	      objlist=
+	      len=$len0
+	    fi
+	  done
+	  RANLIB=$save_RANLIB
+	  oldobjs=$objlist
+	  if test "X$oldobjs" = "X" ; then
+	    eval cmds=\"\$concat_cmds\"
+	  else
+	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+	  fi
+	fi
+      fi
+      func_execute_cmds "$cmds" 'exit $?'
+    done
+
+    test -n "$generated" && \
+      func_show_eval "${RM}r$generated"
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      func_verbose "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+	if eval test -z \"\${$var+set}\"; then
+	  relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	elif eval var_value=\$$var; test -z "$var_value"; then
+	  relink_command="$var=; export $var; $relink_command"
+	else
+	  func_quote_for_eval "$var_value"
+	  relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      if test "$hardcode_automatic" = yes ; then
+	relink_command=
+      fi
+
+      # Only create the output if not a dry run.
+      $opt_dry_run || {
+	for installed in no yes; do
+	  if test "$installed" = yes; then
+	    if test -z "$install_libdir"; then
+	      break
+	    fi
+	    output="$output_objdir/$outputname"i
+	    # Replace all uninstalled libtool libraries with the installed ones
+	    newdependency_libs=
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      *.la)
+		func_basename "$deplib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$deplib' is not a valid libtool archive"
+		func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      -L*)
+		func_stripname -L '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -L$func_replace_sysroot_result"
+		;;
+	      -R*)
+		func_stripname -R '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -R$func_replace_sysroot_result"
+		;;
+	      *) func_append newdependency_libs " $deplib" ;;
+	      esac
+	    done
+	    dependency_libs="$newdependency_libs"
+	    newdlfiles=
+
+	    for lib in $dlfiles; do
+	      case $lib in
+	      *.la)
+	        func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      *) func_append newdlfiles " $lib" ;;
+	      esac
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+	      *.la)
+		# Only pass preopened files to the pseudo-archive (for
+		# eventual linking with the app. that links it) if we
+		# didn't already link the preopened objects directly into
+		# the library:
+		func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      esac
+	    done
+	    dlprefiles="$newdlprefiles"
+	  else
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlfiles " $abs"
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlprefiles " $abs"
+	    done
+	    dlprefiles="$newdlprefiles"
+	  fi
+	  $RM $output
+	  # place dlname in correct position for cygwin
+	  # In fact, it would be nice if we could use this code for all target
+	  # systems that can't hard-code library paths into their executables
+	  # and that have no shared library path variable independent of PATH,
+	  # but it turns out we can't easily determine that from inspecting
+	  # libtool variables, so we have to hard-code the OSs to which it
+	  # applies here; at the moment, that means platforms that use the PE
+	  # object format with DLL files.  See the long comment at the top of
+	  # tests/bindir.at for full details.
+	  tdlname=$dlname
+	  case $host,$output,$installed,$module,$dlname in
+	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+	      # If a -bindir argument was supplied, place the dll there.
+	      if test "x$bindir" != x ;
+	      then
+		func_relative_path "$install_libdir" "$bindir"
+		tdlname=$func_relative_path_result$dlname
+	      else
+		# Otherwise fall back on heuristic.
+		tdlname=../bin/$dlname
+	      fi
+	      ;;
+	  esac
+	  $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+	  if test "$installed" = no && test "$need_relink" = yes; then
+	    $ECHO >> $output "\
+relink_command=\"$relink_command\""
+	  fi
+	done
+      }
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+}
+
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+    func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+    $opt_debug
+    RM="$nonopt"
+    files=
+    rmforce=
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    for arg
+    do
+      case $arg in
+      -f) func_append RM " $arg"; rmforce=yes ;;
+      -*) func_append RM " $arg" ;;
+      *) func_append files " $arg" ;;
+      esac
+    done
+
+    test -z "$RM" && \
+      func_fatal_help "you must specify an RM program"
+
+    rmdirs=
+
+    for file in $files; do
+      func_dirname "$file" "" "."
+      dir="$func_dirname_result"
+      if test "X$dir" = X.; then
+	odir="$objdir"
+      else
+	odir="$dir/$objdir"
+      fi
+      func_basename "$file"
+      name="$func_basename_result"
+      test "$opt_mode" = uninstall && odir="$dir"
+
+      # Remember odir for removal later, being careful to avoid duplicates
+      if test "$opt_mode" = clean; then
+	case " $rmdirs " in
+	  *" $odir "*) ;;
+	  *) func_append rmdirs " $odir" ;;
+	esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if { test -L "$file"; } >/dev/null 2>&1 ||
+	 { test -h "$file"; } >/dev/null 2>&1 ||
+	 test -f "$file"; then
+	:
+      elif test -d "$file"; then
+	exit_status=1
+	continue
+      elif test "$rmforce" = yes; then
+	continue
+      fi
+
+      rmfiles="$file"
+
+      case $name in
+      *.la)
+	# Possibly a libtool archive, so verify it.
+	if func_lalib_p "$file"; then
+	  func_source $dir/$name
+
+	  # Delete the libtool libraries and symlinks.
+	  for n in $library_names; do
+	    func_append rmfiles " $odir/$n"
+	  done
+	  test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+	  case "$opt_mode" in
+	  clean)
+	    case " $library_names " in
+	    *" $dlname "*) ;;
+	    *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+	    esac
+	    test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+	    ;;
+	  uninstall)
+	    if test -n "$library_names"; then
+	      # Do each command in the postuninstall commands.
+	      func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+	    fi
+
+	    if test -n "$old_library"; then
+	      # Do each command in the old_postuninstall commands.
+	      func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+	    fi
+	    # FIXME: should reinstall the best remaining shared library.
+	    ;;
+	  esac
+	fi
+	;;
+
+      *.lo)
+	# Possibly a libtool object, so verify it.
+	if func_lalib_p "$file"; then
+
+	  # Read the .lo file
+	  func_source $dir/$name
+
+	  # Add PIC object to the list of files to remove.
+	  if test -n "$pic_object" &&
+	     test "$pic_object" != none; then
+	    func_append rmfiles " $dir/$pic_object"
+	  fi
+
+	  # Add non-PIC object to the list of files to remove.
+	  if test -n "$non_pic_object" &&
+	     test "$non_pic_object" != none; then
+	    func_append rmfiles " $dir/$non_pic_object"
+	  fi
+	fi
+	;;
+
+      *)
+	if test "$opt_mode" = clean ; then
+	  noexename=$name
+	  case $file in
+	  *.exe)
+	    func_stripname '' '.exe' "$file"
+	    file=$func_stripname_result
+	    func_stripname '' '.exe' "$name"
+	    noexename=$func_stripname_result
+	    # $file with .exe has already been added to rmfiles,
+	    # add $file without .exe
+	    func_append rmfiles " $file"
+	    ;;
+	  esac
+	  # Do a test to see if this is a libtool program.
+	  if func_ltwrapper_p "$file"; then
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      relink_command=
+	      func_source $func_ltwrapper_scriptname_result
+	      func_append rmfiles " $func_ltwrapper_scriptname_result"
+	    else
+	      relink_command=
+	      func_source $dir/$noexename
+	    fi
+
+	    # note $name still contains .exe if it was in $file originally
+	    # as does the version of $file that was added into $rmfiles
+	    func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+	    if test "$fast_install" = yes && test -n "$relink_command"; then
+	      func_append rmfiles " $odir/lt-$name"
+	    fi
+	    if test "X$noexename" != "X$name" ; then
+	      func_append rmfiles " $odir/lt-${noexename}.c"
+	    fi
+	  fi
+	fi
+	;;
+      esac
+      func_show_eval "$RM $rmfiles" 'exit_status=1'
+    done
+
+    # Try to remove the ${objdir}s in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+	func_show_eval "rmdir $dir >/dev/null 2>&1"
+      fi
+    done
+
+    exit $exit_status
+}
+
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+    func_mode_uninstall ${1+"$@"}
+
+test -z "$opt_mode" && {
+  help="$generic_help"
+  func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+  func_fatal_help "invalid operation mode \`$opt_mode'"
+
+if test -n "$exec_cmd"; then
+  eval exec "$exec_cmd"
+  exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries.  Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them.  This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration.  But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4
new file mode 100755
index 0000000..2957da7
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4
@@ -0,0 +1,176 @@
+# ===========================================================================
+#       http://www.gnu.org/software/autoconf-archive/ax_cc_maxopt.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CC_MAXOPT
+#
+# DESCRIPTION
+#
+#   Try to turn on "good" C optimization flags for various compilers and
+#   architectures, for some definition of "good". (In our case, good for
+#   FFTW and hopefully for other scientific codes. Modify as needed.)
+#
+#   The user can override the flags by setting the CFLAGS environment
+#   variable. The user can also specify --enable-portable-binary in order to
+#   disable any optimization flags that might result in a binary that only
+#   runs on the host architecture.
+#
+#   Note also that the flags assume that ANSI C aliasing rules are followed
+#   by the code (e.g. for gcc's -fstrict-aliasing), and that floating-point
+#   computations can be re-ordered as needed.
+#
+#   Requires macros: AX_CHECK_COMPILER_FLAGS, AX_COMPILER_VENDOR,
+#   AX_GCC_ARCHFLAG, AX_GCC_X86_CPUID.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj at alum.mit.edu>
+#   Copyright (c) 2008 Matteo Frigo
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 11
+
+AC_DEFUN([AX_CC_MAXOPT],
+[
+AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AX_COMPILER_VENDOR])
+AC_REQUIRE([AC_CANONICAL_HOST])
+
+AC_ARG_ENABLE(portable-binary, [AS_HELP_STRING([--enable-portable-binary], [disable compiler optimizations that would produce unportable binaries])],
+	acx_maxopt_portable=$withval, acx_maxopt_portable=no)
+
+# Try to determine "good" native compiler flags if none specified via CFLAGS
+if test "$ac_test_CFLAGS" != "set"; then
+  CFLAGS=""
+  case $ax_cv_c_compiler_vendor in
+    dec) CFLAGS="-newc -w0 -O5 -ansi_alias -ansi_args -fp_reorder -tune host"
+	 if test "x$acx_maxopt_portable" = xno; then
+           CFLAGS="$CFLAGS -arch host"
+         fi;;
+
+    sun) CFLAGS="-native -fast -xO5 -dalign"
+	 if test "x$acx_maxopt_portable" = xyes; then
+	   CFLAGS="$CFLAGS -xarch=generic"
+         fi;;
+
+    hp)  CFLAGS="+Oall +Optrs_ansi +DSnative"
+	 if test "x$acx_maxopt_portable" = xyes; then
+	   CFLAGS="$CFLAGS +DAportable"
+	 fi;;
+
+    ibm) if test "x$acx_maxopt_portable" = xno; then
+           xlc_opt="-qarch=auto -qtune=auto"
+	 else
+           xlc_opt="-qtune=auto"
+	 fi
+         AX_CHECK_COMPILER_FLAGS($xlc_opt,
+		CFLAGS="-O3 -qansialias -w $xlc_opt",
+               [CFLAGS="-O3 -qansialias -w"
+                echo "******************************************************"
+                echo "*  You seem to have the IBM  C compiler.  It is      *"
+                echo "*  recommended for best performance that you use:    *"
+                echo "*                                                    *"
+                echo "*    CFLAGS=-O3 -qarch=xxx -qtune=xxx -qansialias -w *"
+                echo "*                      ^^^        ^^^                *"
+                echo "*  where xxx is pwr2, pwr3, 604, or whatever kind of *"
+                echo "*  CPU you have.  (Set the CFLAGS environment var.   *"
+                echo "*  and re-run configure.)  For more info, man cc.    *"
+                echo "******************************************************"])
+         ;;
+
+    intel) CFLAGS="-O3 -ansi_alias"
+	if test "x$acx_maxopt_portable" = xno; then
+	  icc_archflag=unknown
+	  icc_flags=""
+	  case $host_cpu in
+	    i686*|x86_64*)
+              # icc accepts gcc assembly syntax, so these should work:
+	      AX_GCC_X86_CPUID(0)
+              AX_GCC_X86_CPUID(1)
+	      case $ax_cv_gcc_x86_cpuid_0 in # see AX_GCC_ARCHFLAG
+                *:756e6547:*:*) # Intel
+                  case $ax_cv_gcc_x86_cpuid_1 in
+                    *6a?:*[[234]]:*:*|*6[[789b]]?:*:*:*) icc_flags="-xK";;
+                    *f3[[347]]:*:*:*|*f4[1347]:*:*:*) icc_flags="-xP -xN -xW -xK";;
+                    *f??:*:*:*) icc_flags="-xN -xW -xK";;
+                  esac ;;
+              esac ;;
+          esac
+          if test "x$icc_flags" != x; then
+            for flag in $icc_flags; do
+              AX_CHECK_COMPILER_FLAGS($flag, [icc_archflag=$flag; break])
+            done
+          fi
+          AC_MSG_CHECKING([for icc architecture flag])
+	  AC_MSG_RESULT($icc_archflag)
+          if test "x$icc_archflag" != xunknown; then
+            CFLAGS="$CFLAGS $icc_archflag"
+          fi
+        fi
+	;;
+
+    gnu)
+     # default optimization flags for gcc on all systems
+     CFLAGS="-O3 -fomit-frame-pointer"
+
+     #  -fstrict-aliasing for gcc-2.95+
+     AX_CHECK_COMPILER_FLAGS(-fstrict-aliasing,
+	CFLAGS="$CFLAGS -fstrict-aliasing")
+
+     AX_CHECK_COMPILER_FLAGS(-ffast-math, CFLAGS="$CFLAGS -ffast-math")
+
+     AX_GCC_ARCHFLAG($acx_maxopt_portable)
+     ;;
+  esac
+
+  if test -z "$CFLAGS"; then
+	echo ""
+	echo "********************************************************"
+        echo "* WARNING: Don't know the best CFLAGS for this system  *"
+        echo "* Use ./configure CFLAGS=... to specify your own flags *"
+	echo "* (otherwise, a default of CFLAGS=-O3 will be used)    *"
+	echo "********************************************************"
+	echo ""
+        CFLAGS="-O3"
+  fi
+
+  AX_CHECK_COMPILER_FLAGS($CFLAGS, [], [
+	echo ""
+        echo "********************************************************"
+        echo "* WARNING: The guessed CFLAGS don't seem to work with  *"
+        echo "* your compiler.                                       *"
+        echo "* Use ./configure CFLAGS=... to specify your own flags *"
+        echo "********************************************************"
+        echo ""
+        CFLAGS=""
+  ])
+
+fi
+])
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4
new file mode 100755
index 0000000..7625580
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4
@@ -0,0 +1,195 @@
+# ===========================================================================
+#    http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CFLAGS_WARN_ALL   [(shellvar [,default, [A/NA]])]
+#   AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
+#   AX_FCFLAGS_WARN_ALL  [(shellvar [,default, [A/NA]])]
+#
+# DESCRIPTION
+#
+#   Try to find a compiler option that enables most reasonable warnings.
+#
+#   For the GNU compiler it will be -Wall (and -ansi -pedantic) The result
+#   is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default.
+#
+#   Currently this macro knows about the GCC, Solaris, Digital Unix, AIX,
+#   HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and
+#   Intel compilers.  For a given compiler, the Fortran flags are much more
+#   experimental than their C equivalents.
+#
+#    - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS
+#    - $2 add-value-if-not-found : nothing
+#    - $3 action-if-found : add value to shellvariable
+#    - $4 action-if-not-found : nothing
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod at gmx.de>
+#   Copyright (c) 2010 Rhys Ulerich <rhys.ulerich at gmail.com>
+#
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation; either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 10
+
+AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
+AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl
+AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_warn_all])dnl
+AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
+VAR,[VAR="no, unknown"
+ AC_LANG_PUSH([C])
+ ac_save_[]FLAGS="$[]FLAGS"
+for ac_arg dnl
+in "-pedantic  % -Wall"       dnl   GCC
+   "-xstrconst % -v"          dnl Solaris C
+   "-std1      % -verbose -w0 -warnprotos" dnl Digital Unix
+   "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
+   "-ansi -ansiE % -fullwarn" dnl IRIX
+   "+ESlit     % +w1"         dnl HP-UX C
+   "-Xc        % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
+   "-h conform % -h msglevel 2" dnl Cray C (Unicos)
+   #
+do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+                     [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
+done
+ FLAGS="$ac_save_[]FLAGS"
+ AC_LANG_POP([C])
+])
+case ".$VAR" in
+     .ok|.ok,*) m4_ifvaln($3,$3) ;;
+   .|.no|.no,*) m4_ifvaln($4,$4,[m4_ifval($2,[
+        AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])
+                      m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])]) ;;
+   *) m4_ifvaln($3,$3,[
+   if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
+   then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR])
+   else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"])
+                      m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"
+   fi ]) ;;
+esac
+AS_VAR_POPDEF([VAR])dnl
+AS_VAR_POPDEF([FLAGS])dnl
+])
+
+dnl the only difference - the LANG selection... and the default FLAGS
+
+AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
+AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl
+AS_VAR_PUSHDEF([VAR],[ax_cv_cxxflags_warn_all])dnl
+AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
+VAR,[VAR="no, unknown"
+ AC_LANG_PUSH([C++])
+ ac_save_[]FLAGS="$[]FLAGS"
+for ac_arg dnl
+in "-pedantic  % -Wall"       dnl   GCC
+   "-xstrconst % -v"          dnl Solaris C
+   "-std1      % -verbose -w0 -warnprotos" dnl Digital Unix
+   "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
+   "-ansi -ansiE % -fullwarn" dnl IRIX
+   "+ESlit     % +w1"         dnl HP-UX C
+   "-Xc        % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
+   "-h conform % -h msglevel 2" dnl Cray C (Unicos)
+   #
+do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+                     [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
+done
+ FLAGS="$ac_save_[]FLAGS"
+ AC_LANG_POP([C++])
+])
+case ".$VAR" in
+     .ok|.ok,*) m4_ifvaln($3,$3) ;;
+   .|.no|.no,*) m4_ifvaln($4,$4,[m4_ifval($2,[
+        AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])
+                      m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])]) ;;
+   *) m4_ifvaln($3,$3,[
+   if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
+   then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR])
+   else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"])
+                      m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"
+   fi ]) ;;
+esac
+AS_VAR_POPDEF([VAR])dnl
+AS_VAR_POPDEF([FLAGS])dnl
+])
+
+dnl the only difference - the LANG selection... and the default FLAGS
+
+AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl
+AS_VAR_PUSHDEF([FLAGS],[FCFLAGS])dnl
+AS_VAR_PUSHDEF([VAR],[ax_cv_fcflags_warn_all])dnl
+AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
+VAR,[VAR="no, unknown"
+ AC_LANG_PUSH([Fortran])
+ ac_save_[]FLAGS="$[]FLAGS"
+for ac_arg dnl
+in "-warn all  % -warn all"   dnl Intel
+   "-pedantic  % -Wall"       dnl GCC
+   "-xstrconst % -v"          dnl Solaris C
+   "-std1      % -verbose -w0 -warnprotos" dnl Digital Unix
+   "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
+   "-ansi -ansiE % -fullwarn" dnl IRIX
+   "+ESlit     % +w1"         dnl HP-UX C
+   "-Xc        % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
+   "-h conform % -h msglevel 2" dnl Cray C (Unicos)
+   #
+do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+                     [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
+done
+ FLAGS="$ac_save_[]FLAGS"
+ AC_LANG_POP([Fortran])
+])
+case ".$VAR" in
+     .ok|.ok,*) m4_ifvaln($3,$3) ;;
+   .|.no|.no,*) m4_ifvaln($4,$4,[m4_ifval($2,[
+        AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])
+                      m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])]) ;;
+   *) m4_ifvaln($3,$3,[
+   if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
+   then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR])
+   else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"])
+                      m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"
+   fi ]) ;;
+esac
+AS_VAR_POPDEF([VAR])dnl
+AS_VAR_POPDEF([FLAGS])dnl
+])
+
+dnl  implementation tactics:
+dnl   the for-argument contains a list of options. The first part of
+dnl   these does only exist to detect the compiler - usually it is
+dnl   a global option to enable -ansi or -extrawarnings. All other
+dnl   compilers will fail about it. That was needed since a lot of
+dnl   compilers will give false positives for some option-syntax
+dnl   like -Woption or -Xoption as they think of it is a pass-through
+dnl   to later compile stages or something. The "%" is used as a
+dnl   delimiter. A non-option comment can be given after "%%" marks
+dnl   which will be shown but not added to the respective C/CXXFLAGS.
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_check_compiler_flags.m4 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_check_compiler_flags.m4
new file mode 100755
index 0000000..35bfd2a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_check_compiler_flags.m4
@@ -0,0 +1,76 @@
+# ===========================================================================
+#  http://www.gnu.org/software/autoconf-archive/ax_check_compiler_flags.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_COMPILER_FLAGS(FLAGS, [ACTION-SUCCESS], [ACTION-FAILURE])
+#
+# DESCRIPTION
+#
+#   Check whether the given compiler FLAGS work with the current language's
+#   compiler, or whether they give an error. (Warnings, however, are
+#   ignored.)
+#
+#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+#   success/failure.
+#
+# LICENSE
+#
+#   Copyright (c) 2009 Steven G. Johnson <stevenj at alum.mit.edu>
+#   Copyright (c) 2009 Matteo Frigo
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 9
+
+AC_DEFUN([AX_CHECK_COMPILER_FLAGS],
+[AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX
+AC_MSG_CHECKING([whether _AC_LANG compiler accepts $1])
+dnl Some hackery here since AC_CACHE_VAL can't handle a non-literal varname:
+AS_LITERAL_IF([$1],
+  [AC_CACHE_VAL(AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1]), [
+      ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS
+      _AC_LANG_PREFIX[]FLAGS="$1"
+      AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
+        AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1])=yes,
+        AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1])=no)
+      _AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS])],
+  [ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS
+   _AC_LANG_PREFIX[]FLAGS="$1"
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
+     eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1])=yes,
+     eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1])=no)
+   _AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS])
+eval ax_check_compiler_flags=$AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1])
+AC_MSG_RESULT($ax_check_compiler_flags)
+if test "x$ax_check_compiler_flags" = xyes; then
+	m4_default([$2], :)
+else
+	m4_default([$3], :)
+fi
+])dnl AX_CHECK_COMPILER_FLAGS
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4
new file mode 100755
index 0000000..3214706
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4
@@ -0,0 +1,63 @@
+# ===========================================================================
+#    http://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_COMPILER_VENDOR
+#
+# DESCRIPTION
+#
+#   Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, sun,
+#   hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, microsoft,
+#   watcom, etc. The vendor is returned in the cache variable
+#   $ax_cv_c_compiler_vendor for C and $ax_cv_cxx_compiler_vendor for C++.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj at alum.mit.edu>
+#   Copyright (c) 2008 Matteo Frigo
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 9
+
+AC_DEFUN([AX_COMPILER_VENDOR],
+[
+AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor,
+ [ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=unknown
+  # note: don't check for gcc first since some other compilers define __GNUC__
+  for ventest in intel:__ICC,__ECC,__INTEL_COMPILER ibm:__xlc__,__xlC__,__IBMC__,__IBMCPP__ pathscale:__PATHCC__,__PATHSCALE__ clang:__clang__ gnu:__GNUC__ sun:__SUNPRO_C,__SUNPRO_CC hp:__HP_cc,__HP_aCC dec:__DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland:__BORLANDC__,__TURBOC__ comeau:__COMO__ cray:_CRAYC kai:__KCC lcc:__LCC__ metrowerks:__MWERKS__ sgi:__sgi,sgi microsoft:_MSC_VER watcom:__WATCOMC__ portland:__PGI; do
+    vencpp="defined("`echo $ventest | cut -d: -f2 | sed 's/,/) || defined(/g'`")"
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[
+#if !($vencpp)
+      thisisanerror;
+#endif
+])], [ax_cv_]_AC_LANG_ABBREV[_compiler_vendor=`echo $ventest | cut -d: -f1`; break])
+  done
+ ])
+])
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_configure_args.m4 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_configure_args.m4
new file mode 100755
index 0000000..0726b1b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_configure_args.m4
@@ -0,0 +1,70 @@
+# ===========================================================================
+#     http://www.gnu.org/software/autoconf-archive/ax_configure_args.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CONFIGURE_ARGS
+#
+# DESCRIPTION
+#
+#   Helper macro for AX_ENABLE_BUILDDIR.
+#
+#   The traditional way of starting a subdir-configure is running the script
+#   with ${1+"$@"} but since autoconf 2.60 this is broken. Instead we have
+#   to rely on eval'ing $ac_configure_args however some old autoconf
+#   versions do not provide that. To ensure maximum portability of autoconf
+#   extension macros this helper can be AC_REQUIRE'd so that
+#   $ac_configure_args will alsways be present.
+#
+#   Sadly, the traditional "exec $SHELL" of the enable_builddir macros is
+#   spoiled now and must be replaced by "eval + exit $?".
+#
+#   Example:
+#
+#     AC_DEFUN([AX_ENABLE_SUBDIR],[dnl
+#       AC_REQUIRE([AX_CONFIGURE_ARGS])dnl
+#       eval $SHELL $ac_configure_args || exit $?
+#       ...])
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod at gmx.de>
+#
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation; either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 9
+
+AC_DEFUN([AX_CONFIGURE_ARGS],[
+   # [$]@ is unsable in 2.60+ but earlier autoconf had no ac_configure_args
+   if test "${ac_configure_args+set}" != "set" ; then
+      ac_configure_args=
+      for ac_arg in ${1+"[$]@"}; do
+         ac_configure_args="$ac_configure_args '$ac_arg'"
+      done
+   fi
+])
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_enable_builddir.m4
new file mode 100755
index 0000000..959dec3
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_enable_builddir.m4
@@ -0,0 +1,300 @@
+# ===========================================================================
+#    http://www.gnu.org/software/autoconf-archive/ax_enable_builddir.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_ENABLE_BUILDDIR [(dirstring-or-command [,Makefile.mk [,-all]])]
+#
+# DESCRIPTION
+#
+#   If the current configure was run within the srcdir then we move all
+#   configure-files into a subdir and let the configure steps continue
+#   there. We provide an option --disable-builddir to suppress the move into
+#   a separate builddir.
+#
+#   Defaults:
+#
+#     $1 = $host (overridden with $HOST)
+#     $2 = Makefile.mk
+#     $3 = -all
+#
+#   This macro must be called before AM_INIT_AUTOMAKE. It creates a default
+#   toplevel srcdir Makefile from the information found in the created
+#   toplevel builddir Makefile. It just copies the variables and
+#   rule-targets, each extended with a default rule-execution that recurses
+#   into the build directory of the current "HOST". You can override the
+#   auto-dection through `config.guess` and build-time of course, as in
+#
+#     make HOST=i386-mingw-cross
+#
+#   which can of course set at configure time as well using
+#
+#     configure --host=i386-mingw-cross
+#
+#   After the default has been created, additional rules can be appended
+#   that will not just recurse into the subdirectories and only ever exist
+#   in the srcdir toplevel makefile - these parts are read from the $2 =
+#   Makefile.mk file
+#
+#   The automatic rules are usually scanning the toplevel Makefile for lines
+#   like '#### $host |$builddir' to recognize the place where to recurse
+#   into. Usually, the last one is the only one used. However, almost all
+#   targets have an additional "*-all" rule which makes the script to
+#   recurse into _all_ variants of the current HOST (!!) setting. The "-all"
+#   suffix can be overriden for the macro as well.
+#
+#   a special rule is only given for things like "dist" that will copy the
+#   tarball from the builddir to the sourcedir (or $(PUB)) for reason of
+#   convenience.
+#
+# LICENSE
+#
+#   Copyright (c) 2009 Guido U. Draheim <guidod at gmx.de>
+#   Copyright (c) 2009 Alan Jenkins <alan-jenkins at tuffmail.co.uk>
+#
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation; either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 22
+
+AC_DEFUN([AX_ENABLE_BUILDDIR],[
+AC_REQUIRE([AC_CANONICAL_HOST])[]dnl
+AC_REQUIRE([AX_CONFIGURE_ARGS])[]dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])[]dnl
+AC_BEFORE([$0],[AM_INIT_AUTOMAKE])dnl
+AS_VAR_PUSHDEF([SUB],[ax_enable_builddir])dnl
+AS_VAR_PUSHDEF([AUX],[ax_enable_builddir_auxdir])dnl
+AS_VAR_PUSHDEF([SED],[ax_enable_builddir_sed])dnl
+SUB="."
+AC_ARG_ENABLE([builddir], AS_HELP_STRING(
+  [--disable-builddir],[disable automatic build in subdir of sources])
+  ,[SUB="$enableval"], [SUB="auto"])
+if test ".$ac_srcdir_defaulted" != ".no" ; then
+if test ".$srcdir" = ".." ; then
+  if test -f config.status ; then
+    AC_MSG_NOTICE(toplevel srcdir already configured... skipping subdir build)
+  else
+    test ".$SUB" = "."  && SUB="."
+    test ".$SUB" = ".no"  && SUB="."
+    test ".$TARGET" = "." && TARGET="$target"
+    test ".$SUB" = ".auto" && SUB="m4_ifval([$1], [$1],[$TARGET])"
+    if test ".$SUB" != ".." ; then    # we know where to go and
+      AS_MKDIR_P([$SUB])
+      echo __.$SUB.__ > $SUB/conftest.tmp
+      cd $SUB
+      if grep __.$SUB.__ conftest.tmp >/dev/null 2>/dev/null ; then
+        rm conftest.tmp
+        AC_MSG_RESULT([continue configure in default builddir "./$SUB"])
+      else
+        AC_MSG_ERROR([could not change to default builddir "./$SUB"])
+      fi
+      srcdir=`echo "$SUB" |
+              sed -e 's,^\./,,;s,[[^/]]$,&/,;s,[[^/]]*/,../,g;s,[[/]]$,,;'`
+      # going to restart from subdirectory location
+      test -f $srcdir/config.log   && mv $srcdir/config.log   .
+      test -f $srcdir/confdefs.h   && mv $srcdir/confdefs.h   .
+      test -f $srcdir/conftest.log && mv $srcdir/conftest.log .
+      test -f $srcdir/$cache_file  && mv $srcdir/$cache_file  .
+      AC_MSG_RESULT(....exec $SHELL $srcdir/[$]0 "--srcdir=$srcdir" "--enable-builddir=$SUB" ${1+"[$]@"})
+      case "[$]0" in # restart
+       [/\\]*) eval $SHELL "'[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;;
+       *) eval $SHELL "'$srcdir/[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;;
+      esac ; exit $?
+    fi
+  fi
+fi fi
+test ".$SUB" = ".auto" && SUB="."
+dnl ac_path_prog uses "set dummy" to override $@ which would defeat the "exec"
+AC_PATH_PROG(SED,gsed sed, sed)
+AUX="$am_aux_dir"
+AS_VAR_POPDEF([SED])dnl
+AS_VAR_POPDEF([AUX])dnl
+AS_VAR_POPDEF([SUB])dnl
+AC_CONFIG_COMMANDS([buildir],[dnl .............. config.status ..............
+AS_VAR_PUSHDEF([SUB],[ax_enable_builddir])dnl
+AS_VAR_PUSHDEF([TOP],[top_srcdir])dnl
+AS_VAR_PUSHDEF([SRC],[ac_top_srcdir])dnl
+AS_VAR_PUSHDEF([AUX],[ax_enable_builddir_auxdir])dnl
+AS_VAR_PUSHDEF([SED],[ax_enable_builddir_sed])dnl
+pushdef([END],[Makefile.mk])dnl
+pushdef([_ALL],[ifelse([$3],,[-all],[$3])])dnl
+  SRC="$ax_enable_builddir_srcdir"
+  if test ".$SUB" = ".." ; then
+    if test -f "$TOP/Makefile" ; then
+      AC_MSG_NOTICE([skipping TOP/Makefile - left untouched])
+    else
+      AC_MSG_NOTICE([skipping TOP/Makefile - not created])
+    fi
+  else
+    if test -f "$SRC/Makefile" ; then
+      a=`grep "^VERSION " "$SRC/Makefile"` ; b=`grep "^VERSION " Makefile`
+      test "$a" != "$b" && rm "$SRC/Makefile"
+    fi
+    if test -f "$SRC/Makefile" ; then
+	echo "$SRC/Makefile : $SRC/Makefile.in" > $tmp/conftemp.mk
+	echo "	[]@ echo 'REMOVED,,,' >\$[]@" >> $tmp/conftemp.mk
+      eval "${MAKE-make} -f $tmp/conftemp.mk 2>/dev/null >/dev/null"
+      if grep '^REMOVED,,,' "$SRC/Makefile" >/dev/null
+      then rm $SRC/Makefile ; fi
+      cp $tmp/conftemp.mk $SRC/makefiles.mk~      ## DEBUGGING
+    fi
+    if test ! -f "$SRC/Makefile" ; then
+      AC_MSG_NOTICE([create TOP/Makefile guessed from local Makefile])
+      x='`' ; cat >$tmp/conftemp.sed <<_EOF
+/^\$/n
+x
+/^\$/bS
+x
+/\\\\\$/{H;d;}
+{H;s/.*//;x;}
+bM
+:S
+x
+/\\\\\$/{h;d;}
+{h;s/.*//;x;}
+:M
+s/\\(\\n\\)	/\\1 /g
+/^	/d
+/^[[	 ]]*[[\\#]]/d
+/^VPATH *=/d
+s/^srcdir *=.*/srcdir = ./
+s/^top_srcdir *=.*/top_srcdir = ./
+/[[:=]]/!d
+/^\\./d
+dnl Now handle rules (i.e. lines containing ":" but not " = ").
+/ = /b
+/ .= /b
+/:/!b
+s/:.*/:/
+s/ /  /g
+s/ \\([[a-z]][[a-z-]]*[[a-zA-Z0-9]]\\)\\([[ :]]\\)/ \\1 \\1[]_ALL\\2/g
+s/^\\([[a-z]][[a-z-]]*[[a-zA-Z0-9]]\\)\\([[ :]]\\)/\\1 \\1[]_ALL\\2/
+s/  / /g
+/^all all[]_ALL[[ :]]/i\\
+all-configured : all[]_ALL
+dnl dist-all exists... and would make for dist-all-all
+s/ [[a-zA-Z0-9-]]*[]_ALL [[a-zA-Z0-9-]]*[]_ALL[]_ALL//g
+/[]_ALL[]_ALL/d
+a\\
+	@ HOST="\$(HOST)\" \\\\\\
+	; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\
+	; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\
+	; use=$x basename "\$\@" _ALL $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\
+	; echo "MAKE \$\$HOST : \$\$n * \$\@"; if test "\$\$n" = "0" ; then : \\\\\\
+	; BUILD=$x grep "^####.*|" Makefile |tail -1| sed -e 's/.*|//' $x ; fi \\\\\\
+	; test ".\$\$BUILD" = "." && BUILD="." \\\\\\
+	; test "\$\$use" = "\$\@" && BUILD=$x echo "\$\$BUILD" | tail -1 $x \\\\\\
+	; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
+	; (cd "\$\$i" && test ! -f configure && \$(MAKE) \$\$use) || exit; done
+dnl special rule add-on: "dist" copies the tarball to $(PUB). (source tree)
+/dist[]_ALL *:/a\\
+	@ HOST="\$(HOST)\" \\\\\\
+	; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\
+	; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\
+	; found=$x echo \$\$BUILD | wc -w $x \\\\\\
+	; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).tar.*" \\\\\\
+	; if test "\$\$found" = "0" ; then : \\\\\\
+	; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\
+	; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
+	; for f in \$\$i/\$(PACKAGE)-\$(VERSION).tar.* \\\\\\
+	; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done
+dnl special rule add-on: "dist-foo" copies all the archives to $(PUB). (source tree)
+/dist-[[a-zA-Z0-9]]*[]_ALL *:/a\\
+	@ HOST="\$(HOST)\" \\\\\\
+	; test ".\$\$HOST" = "." && HOST=$x sh ./config.guess $x \\\\\\
+	; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\
+	; found=$x echo \$\$BUILD | wc -w $x \\\\\\
+	; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).*" \\\\\\
+	; if test "\$\$found" = "0" ; then : \\\\\\
+	; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\
+	; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
+	; for f in \$\$i/\$(PACKAGE)-\$(VERSION).* \\\\\\
+	; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done
+dnl special rule add-on: "distclean" removes all local builddirs completely
+/distclean[]_ALL *:/a\\
+	@ HOST="\$(HOST)\" \\\\\\
+	; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\
+	; BUILD=$x grep "^#### .*|" Makefile | sed -e 's/.*|//' $x \\\\\\
+	; use=$x basename "\$\@" _ALL $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\
+	; echo "MAKE \$\$HOST : \$\$n * \$\@ (all local builds)" \\\\\\
+	; test ".\$\$BUILD" = "." && BUILD="." \\\\\\
+	; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
+	; echo "# rm -r \$\$i"; done ; echo "# (sleep 3)" ; sleep 3 \\\\\\
+	; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
+	; echo "\$\$i" | grep "^/" > /dev/null && continue \\\\\\
+	; echo "\$\$i" | grep "^../" > /dev/null && continue \\\\\\
+	; echo "rm -r \$\$i"; (rm -r "\$\$i") ; done ; rm Makefile
+_EOF
+      cp "$tmp/conftemp.sed" "$SRC/makefile.sed~"            ## DEBUGGING
+      $SED -f $tmp/conftemp.sed Makefile >$SRC/Makefile
+      if test -f "$SRC/m4_ifval([$2],[$2],[END])" ; then
+        AC_MSG_NOTICE([extend TOP/Makefile with TOP/m4_ifval([$2],[$2],[END])])
+        cat $SRC/END >>$SRC/Makefile
+      fi ; xxxx="####"
+      echo "$xxxx CONFIGURATIONS FOR TOPLEVEL MAKEFILE: " >>$SRC/Makefile
+      # sanity check
+      if grep '^; echo "MAKE ' $SRC/Makefile >/dev/null ; then
+        AC_MSG_NOTICE([buggy sed found - it deletes tab in "a" text parts])
+        $SED -e '/^@ HOST=/s/^/	/' -e '/^; /s/^/	/' $SRC/Makefile \
+          >$SRC/Makefile~
+        (test -s $SRC/Makefile~ && mv $SRC/Makefile~ $SRC/Makefile) 2>/dev/null
+      fi
+    else
+      xxxx="\\#\\#\\#\\#"
+      # echo "/^$xxxx *$ax_enable_builddir_host /d" >$tmp/conftemp.sed
+      echo "s!^$xxxx [[^|]]* | *$SUB *\$!$xxxx ...... $SUB!" >$tmp/conftemp.sed
+      $SED -f "$tmp/conftemp.sed" "$SRC/Makefile" >$tmp/mkfile.tmp
+        cp "$tmp/conftemp.sed" "$SRC/makefiles.sed~"         ## DEBUGGING
+        cp "$tmp/mkfile.tmp"   "$SRC/makefiles.out~"         ## DEBUGGING
+      if cmp -s "$SRC/Makefile" "$tmp/mkfile.tmp" 2>/dev/null ; then
+        AC_MSG_NOTICE([keeping TOP/Makefile from earlier configure])
+        rm "$tmp/mkfile.tmp"
+      else
+        AC_MSG_NOTICE([reusing TOP/Makefile from earlier configure])
+        mv "$tmp/mkfile.tmp" "$SRC/Makefile"
+      fi
+    fi
+    AC_MSG_NOTICE([build in $SUB (HOST=$ax_enable_builddir_host)])
+    xxxx="####"
+    echo "$xxxx" "$ax_enable_builddir_host" "|$SUB" >>$SRC/Makefile
+  fi
+popdef([END])dnl
+AS_VAR_POPDEF([SED])dnl
+AS_VAR_POPDEF([AUX])dnl
+AS_VAR_POPDEF([SRC])dnl
+AS_VAR_POPDEF([TOP])dnl
+AS_VAR_POPDEF([SUB])dnl
+],[dnl
+ax_enable_builddir_srcdir="$srcdir"                    # $srcdir
+ax_enable_builddir_host="$HOST"                        # $HOST / $host
+ax_enable_builddir_version="$VERSION"                  # $VERSION
+ax_enable_builddir_package="$PACKAGE"                  # $PACKAGE
+ax_enable_builddir_auxdir="$ax_enable_builddir_auxdir" # $AUX
+ax_enable_builddir_sed="$ax_enable_builddir_sed"       # $SED
+ax_enable_builddir="$ax_enable_builddir"               # $SUB
+])dnl
+])
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4
new file mode 100755
index 0000000..d37a913
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4
@@ -0,0 +1,215 @@
+# ===========================================================================
+#      http://www.gnu.org/software/autoconf-archive/ax_gcc_archflag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_GCC_ARCHFLAG([PORTABLE?], [ACTION-SUCCESS], [ACTION-FAILURE])
+#
+# DESCRIPTION
+#
+#   This macro tries to guess the "native" arch corresponding to the target
+#   architecture for use with gcc's -march=arch or -mtune=arch flags. If
+#   found, the cache variable $ax_cv_gcc_archflag is set to this flag and
+#   ACTION-SUCCESS is executed; otherwise $ax_cv_gcc_archflag is is set to
+#   "unknown" and ACTION-FAILURE is executed. The default ACTION-SUCCESS is
+#   to add $ax_cv_gcc_archflag to the end of $CFLAGS.
+#
+#   PORTABLE? should be either [yes] (default) or [no]. In the former case,
+#   the flag is set to -mtune (or equivalent) so that the architecture is
+#   only used for tuning, but the instruction set used is still portable. In
+#   the latter case, the flag is set to -march (or equivalent) so that
+#   architecture-specific instructions are enabled.
+#
+#   The user can specify --with-gcc-arch=<arch> in order to override the
+#   macro's choice of architecture, or --without-gcc-arch to disable this.
+#
+#   When cross-compiling, or if $CC is not gcc, then ACTION-FAILURE is
+#   called unless the user specified --with-gcc-arch manually.
+#
+#   Requires macros: AX_CHECK_COMPILER_FLAGS, AX_GCC_X86_CPUID
+#
+#   (The main emphasis here is on recent CPUs, on the principle that doing
+#   high-performance computing on old hardware is uncommon.)
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj at alum.mit.edu>
+#   Copyright (c) 2008 Matteo Frigo
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 8
+
+AC_DEFUN([AX_GCC_ARCHFLAG],
+[AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AC_CANONICAL_HOST])
+
+AC_ARG_WITH(gcc-arch, [AS_HELP_STRING([--with-gcc-arch=<arch>], [use architecture <arch> for gcc -march/-mtune, instead of guessing])],
+	ax_gcc_arch=$withval, ax_gcc_arch=yes)
+
+AC_MSG_CHECKING([for gcc architecture flag])
+AC_MSG_RESULT([])
+AC_CACHE_VAL(ax_cv_gcc_archflag,
+[
+ax_cv_gcc_archflag="unknown"
+
+if test "$GCC" = yes; then
+
+if test "x$ax_gcc_arch" = xyes; then
+ax_gcc_arch=""
+if test "$cross_compiling" = no; then
+case $host_cpu in
+  i[[3456]]86*|x86_64*) # use cpuid codes, in part from x86info-1.7 by D. Jones
+     AX_GCC_X86_CPUID(0)
+     AX_GCC_X86_CPUID(1)
+     case $ax_cv_gcc_x86_cpuid_0 in
+       *:756e6547:*:*) # Intel
+          case $ax_cv_gcc_x86_cpuid_1 in
+	    *5[[48]]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;;
+	    *5??:*:*:*) ax_gcc_arch=pentium ;;
+	    *6[[3456]]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
+	    *6a?:*[[01]]:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
+	    *6a?:*[[234]]:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
+	    *6[[9d]]?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;;
+	    *6[[78b]]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
+	    *6??:*:*:*) ax_gcc_arch=pentiumpro ;;
+            *f3[[347]]:*:*:*|*f4[1347]:*:*:*)
+		case $host_cpu in
+                  x86_64*) ax_gcc_arch="nocona pentium4 pentiumpro" ;;
+                  *) ax_gcc_arch="prescott pentium4 pentiumpro" ;;
+                esac ;;
+            *f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro";;
+          esac ;;
+       *:68747541:*:*) # AMD
+          case $ax_cv_gcc_x86_cpuid_1 in
+	    *5[[67]]?:*:*:*) ax_gcc_arch=k6 ;;
+	    *5[[8d]]?:*:*:*) ax_gcc_arch="k6-2 k6" ;;
+	    *5[[9]]?:*:*:*) ax_gcc_arch="k6-3 k6" ;;
+	    *60?:*:*:*) ax_gcc_arch=k7 ;;
+	    *6[[12]]?:*:*:*) ax_gcc_arch="athlon k7" ;;
+	    *6[[34]]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;;
+	    *67?:*:*:*) ax_gcc_arch="athlon-4 athlon k7" ;;
+	    *6[[68a]]?:*:*:*)
+	       AX_GCC_X86_CPUID(0x80000006) # L2 cache size
+	       case $ax_cv_gcc_x86_cpuid_0x80000006 in
+                 *:*:*[[1-9a-f]]??????:*) # (L2 = ecx >> 16) >= 256
+			ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;;
+                 *) ax_gcc_arch="athlon-4 athlon k7" ;;
+	       esac ;;
+	    *f[[4cef8b]]?:*:*:*) ax_gcc_arch="athlon64 k8" ;;
+	    *f5?:*:*:*) ax_gcc_arch="opteron k8" ;;
+	    *f7?:*:*:*) ax_gcc_arch="athlon-fx opteron k8" ;;
+	    *f??:*:*:*) ax_gcc_arch="k8" ;;
+          esac ;;
+	*:746e6543:*:*) # IDT
+	   case $ax_cv_gcc_x86_cpuid_1 in
+	     *54?:*:*:*) ax_gcc_arch=winchip-c6 ;;
+	     *58?:*:*:*) ax_gcc_arch=winchip2 ;;
+	     *6[[78]]?:*:*:*) ax_gcc_arch=c3 ;;
+	     *69?:*:*:*) ax_gcc_arch="c3-2 c3" ;;
+	   esac ;;
+     esac
+     if test x"$ax_gcc_arch" = x; then # fallback
+	case $host_cpu in
+	  i586*) ax_gcc_arch=pentium ;;
+	  i686*) ax_gcc_arch=pentiumpro ;;
+        esac
+     fi
+     ;;
+
+  sparc*)
+     AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/])
+     cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null`
+     cputype=`echo "$cputype" | tr -d ' -' |tr $as_cr_LETTERS $as_cr_letters`
+     case $cputype in
+         *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;;
+         *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;;
+         *ultrasparc*) ax_gcc_arch="ultrasparc v9" ;;
+         *supersparc*|*tms390z5[[05]]*) ax_gcc_arch="supersparc v8" ;;
+         *hypersparc*|*rt62[[056]]*) ax_gcc_arch="hypersparc v8" ;;
+         *cypress*) ax_gcc_arch=cypress ;;
+     esac ;;
+
+  alphaev5) ax_gcc_arch=ev5 ;;
+  alphaev56) ax_gcc_arch=ev56 ;;
+  alphapca56) ax_gcc_arch="pca56 ev56" ;;
+  alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;;
+  alphaev6) ax_gcc_arch=ev6 ;;
+  alphaev67) ax_gcc_arch=ev67 ;;
+  alphaev68) ax_gcc_arch="ev68 ev67" ;;
+  alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;;
+  alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;;
+  alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;;
+
+  powerpc*)
+     cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | sed 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null`
+     cputype=`echo $cputype | sed -e 's/ppc//g;s/ *//g'`
+     case $cputype in
+       *750*) ax_gcc_arch="750 G3" ;;
+       *740[[0-9]]*) ax_gcc_arch="$cputype 7400 G4" ;;
+       *74[[4-5]][[0-9]]*) ax_gcc_arch="$cputype 7450 G4" ;;
+       *74[[0-9]][[0-9]]*) ax_gcc_arch="$cputype G4" ;;
+       *970*) ax_gcc_arch="970 G5 power4";;
+       *POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";;
+       *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";;
+       603ev|8240) ax_gcc_arch="$cputype 603e 603";;
+       *) ax_gcc_arch=$cputype ;;
+     esac
+     ax_gcc_arch="$ax_gcc_arch powerpc"
+     ;;
+esac
+fi # not cross-compiling
+fi # guess arch
+
+if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then
+for arch in $ax_gcc_arch; do
+  if test "x[]m4_default([$1],yes)" = xyes; then # if we require portable code
+    flags="-mtune=$arch"
+    # -mcpu=$arch and m$arch generate nonportable code on every arch except
+    # x86.  And some other arches (e.g. Alpha) don't accept -mtune.  Grrr.
+    case $host_cpu in i*86|x86_64*) flags="$flags -mcpu=$arch -m$arch";; esac
+  else
+    flags="-march=$arch -mcpu=$arch -m$arch"
+  fi
+  for flag in $flags; do
+    AX_CHECK_COMPILER_FLAGS($flag, [ax_cv_gcc_archflag=$flag; break])
+  done
+  test "x$ax_cv_gcc_archflag" = xunknown || break
+done
+fi
+
+fi # $GCC=yes
+])
+AC_MSG_CHECKING([for gcc architecture flag])
+AC_MSG_RESULT($ax_cv_gcc_archflag)
+if test "x$ax_cv_gcc_archflag" = xunknown; then
+  m4_default([$3],:)
+else
+  m4_default([$2], [CFLAGS="$CFLAGS $ax_cv_gcc_archflag"])
+fi
+])
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_gcc_x86_cpuid.m4 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_gcc_x86_cpuid.m4
new file mode 100755
index 0000000..7d46fee
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ax_gcc_x86_cpuid.m4
@@ -0,0 +1,79 @@
+# ===========================================================================
+#     http://www.gnu.org/software/autoconf-archive/ax_gcc_x86_cpuid.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_GCC_X86_CPUID(OP)
+#
+# DESCRIPTION
+#
+#   On Pentium and later x86 processors, with gcc or a compiler that has a
+#   compatible syntax for inline assembly instructions, run a small program
+#   that executes the cpuid instruction with input OP. This can be used to
+#   detect the CPU type.
+#
+#   On output, the values of the eax, ebx, ecx, and edx registers are stored
+#   as hexadecimal strings as "eax:ebx:ecx:edx" in the cache variable
+#   ax_cv_gcc_x86_cpuid_OP.
+#
+#   If the cpuid instruction fails (because you are running a
+#   cross-compiler, or because you are not using gcc, or because you are on
+#   a processor that doesn't have this instruction), ax_cv_gcc_x86_cpuid_OP
+#   is set to the string "unknown".
+#
+#   This macro mainly exists to be used in AX_GCC_ARCHFLAG.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj at alum.mit.edu>
+#   Copyright (c) 2008 Matteo Frigo
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 7
+
+AC_DEFUN([AX_GCC_X86_CPUID],
+[AC_REQUIRE([AC_PROG_CC])
+AC_LANG_PUSH([C])
+AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1,
+ [AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [
+     int op = $1, eax, ebx, ecx, edx;
+     FILE *f;
+      __asm__("cpuid"
+        : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+        : "a" (op));
+     f = fopen("conftest_cpuid", "w"); if (!f) return 1;
+     fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
+     fclose(f);
+     return 0;
+])],
+     [ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid],
+     [ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid],
+     [ax_cv_gcc_x86_cpuid_$1=unknown])])
+AC_LANG_POP([C])
+])
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/libtool.m4 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/libtool.m4
new file mode 100755
index 0000000..d812584
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/libtool.m4
@@ -0,0 +1,7831 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
+#                 Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
+#                 Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 57 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+       [m4_default([$3],
+		   [m4_fatal([Libtool version $1 or higher is required],
+		             63)])],
+       [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+  *\ * | *\	*)
+    AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+  case $cc_temp in
+    compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+    distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    _LT_PATH_MAGIC
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+              [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME.  Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+    [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+	[m4_ifval([$1], [$1], [$2])])
+    lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+    m4_ifval([$4],
+	[lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+    lt_dict_add_subkey([lt_decl_dict], [$2],
+	[tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+  [0], [m4_fatal([$0: too few arguments: $#])],
+  [1], [m4_fatal([$0: too few arguments: $#: $1])],
+  [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+  [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+  [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+    m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+    m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+     m4_if([$2], [],
+	   m4_quote(lt_decl_varnames),
+	m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+			lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'.  VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly.  In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+#    <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+    [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+#    # Some comment about what VAR is for.
+#    visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+					   [description])))[]dnl
+m4_pushdef([_libtool_name],
+    m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+    [0], [_libtool_name=[$]$1],
+    [1], [_libtool_name=$lt_[]$1],
+    [2], [_libtool_name=$lt_[]$1],
+    [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script.  Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+    m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'.  Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+	dnl If the libtool generation code has been placed in $CONFIG_LT,
+	dnl instead of duplicating it all over again into config.status,
+	dnl then we will have config.status run $CONFIG_LT later, so it
+	dnl needs to know what name is stored there:
+        [AC_CONFIG_COMMANDS([libtool],
+            [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+    dnl If the libtool generation code is destined for config.status,
+    dnl expand the accumulated commands and init code now:
+    [AC_CONFIG_COMMANDS([libtool],
+        [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable.  If COMMENT is supplied, it is inserted after the
+# `#!' sequence but before initialization text begins.  After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script.  The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test $lt_write_fail = 0 && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+  echo
+  AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+  -h, --help      print this help, then exit
+  -V, --version   print version number, then exit
+  -q, --quiet     do not print progress messages
+  -d, --debug     don't remove temporary files
+
+Report bugs to <bug-libtool at gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+  case $[1] in
+    --version | --v* | -V )
+      echo "$lt_cl_version"; exit 0 ;;
+    --help | --h* | -h )
+      echo "$lt_cl_help"; exit 0 ;;
+    --debug | --d* | -d )
+      debug=: ;;
+    --quiet | --q* | --silent | --s* | -q )
+      lt_cl_silent=: ;;
+
+    -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+    *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+  esac
+  shift
+done
+
+if $lt_cl_silent; then
+  exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure.  Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test "$silent" = yes &&
+  lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars.  Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+  m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+  m4_if(_LT_TAG, [C], [
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+  _LT_PROG_LTMAIN
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  _LT_PROG_REPLACE_SHELLFNS
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+#    autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+  [C],			[_LT_LANG(C)],
+  [C++],		[_LT_LANG(CXX)],
+  [Java],		[_LT_LANG(GCJ)],
+  [Fortran 77],		[_LT_LANG(F77)],
+  [Fortran],		[_LT_LANG(FC)],
+  [Windows Resource],	[_LT_LANG(RC)],
+  [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+    [_LT_LANG($1)],
+    [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+  [LT_SUPPORTED_TAG([$1])dnl
+  m4_append([_LT_TAGS], [$1 ])dnl
+  m4_define([_LT_LANG_]$1[_enabled], [])dnl
+  _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+  [LT_LANG(CXX)],
+  [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+  [LT_LANG(F77)],
+  [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+  [LT_LANG(FC)],
+  [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+  [LT_LANG(GCJ)],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+    [LT_LANG(GCJ)],
+    [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+      [LT_LANG(GCJ)],
+      [m4_ifdef([AC_PROG_GCJ],
+	[m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([A][M_PROG_GCJ],
+	[m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([LT_PROG_GCJ],
+	[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+  [LT_LANG(RC)],
+  [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+  case $host_os in
+    rhapsody* | darwin*)
+    AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+    AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+    AC_CHECK_TOOL([LIPO], [lipo], [:])
+    AC_CHECK_TOOL([OTOOL], [otool], [:])
+    AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+    _LT_DECL([], [DSYMUTIL], [1],
+      [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+    _LT_DECL([], [NMEDIT], [1],
+      [Tool to change global to local symbols on Mac OS X])
+    _LT_DECL([], [LIPO], [1],
+      [Tool to manipulate fat objects and archives on Mac OS X])
+    _LT_DECL([], [OTOOL], [1],
+      [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+    _LT_DECL([], [OTOOL64], [1],
+      [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+    AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+      [lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi])
+    AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+      [lt_cv_ld_exported_symbols_list],
+      [lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+	[lt_cv_ld_exported_symbols_list=yes],
+	[lt_cv_ld_exported_symbols_list=no])
+	LDFLAGS="$save_LDFLAGS"
+    ])
+    AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+      [lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+      echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+      $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+      echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+      $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&AS_MESSAGE_LOG_FD
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+    ])
+    case $host_os in
+    rhapsody* | darwin1.[[012]])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[[012]]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES
+# --------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+  m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_automatic, $1)=yes
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  else
+    _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+  fi
+  _LT_TAGVAR(link_all_deplibs, $1)=yes
+  _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=func_echo_all
+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+    m4_if([$1], [CXX],
+[   if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+    fi
+],[])
+  else
+  _LT_TAGVAR(ld_shlibs, $1)=no
+  fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+  [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+  lt_aix_libpath_sed='[
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }]'
+  _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi],[])
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
+  fi
+  ])
+  aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*" 
+}
+
+case "$ECHO" in
+  printf*) AC_MSG_RESULT([printf]) ;;
+  print*) AC_MSG_RESULT([print -r]) ;;
+  *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+  test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test "X`printf %s $ECHO`" = "X$ECHO" \
+      || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[  --with-sysroot[=DIR] Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted.  We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   AC_MSG_RESULT([${with_sysroot}])
+   AC_MSG_ERROR([The sysroot must be an absolute path.])
+   ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and in which our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+  [AS_HELP_STRING([--disable-libtool-lock],
+    [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_i386"
+	    ;;
+	  ppc64-*linux*|powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  ppc*-*linux*|powerpc*-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+  [lt_cv_ar_at_file=no
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+     [echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([lt_ar_try])
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	AC_TRY_EVAL([lt_ar_try])
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+     ])
+  ])
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+  [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+    [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+    [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+    [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       $2=yes
+     fi
+   fi
+   $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$5], , :, [$5])
+else
+    m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                  [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $3"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         $2=yes
+       fi
+     else
+       $2=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$4], , :, [$4])
+else
+    m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[	 ]]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+    [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                      ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}]
+_LT_EOF
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_dlunknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+    ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+	  [lt_cv_dlopen="shl_load"],
+      [AC_CHECK_LIB([dld], [shl_load],
+	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+	[AC_CHECK_FUNC([dlopen],
+	      [lt_cv_dlopen="dlopen"],
+	  [AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+	    [AC_CHECK_LIB([svld], [dlopen],
+		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+	      [AC_CHECK_LIB([dld], [dld_link],
+		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+	      ])
+	    ])
+	  ])
+	])
+      ])
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+	  lt_cv_dlopen_self, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+	  lt_cv_dlopen_self_static, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+	 [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+	 [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+	 [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w . 2>&AS_MESSAGE_LOG_FD
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+	[Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+         [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+  [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+   test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+   test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+    # Linking always hardcodes the temporary library directory.
+    _LT_TAGVAR(hardcode_action, $1)=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    _LT_TAGVAR(hardcode_action, $1)=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+   test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+    [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      AC_MSG_RESULT([yes])
+    else
+      AC_MSG_RESULT([no])
+    fi
+    ;;
+  *)
+    AC_MSG_RESULT([no])
+    ;;
+  esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+	[], [
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+  if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[[4-9]]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[[45]]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+m4_if([$1], [],[
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[[123]]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+haiku*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[[3-9]]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+    [lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+	 LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+      [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+	 [lt_cv_shlibpath_overrides_runpath=yes])])
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+    ])
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+    [Variables whose values should be saved in libtool wrapper scripts and
+    restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+    [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0],  [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+    [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+    [[List of archive names.  First name is the real one, the rest are links.
+    The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+    [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+    [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+    [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+    [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+    [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+    [[As "finish_cmds", except a single script fragment to be evaled but
+    not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+    [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+    [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+    [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] |  ?:[\\/]*])
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="m4_if([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+	 [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+    [AS_HELP_STRING([--with-gnu-ld],
+	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test "$withval" = no || with_gnu_ld=yes],
+    [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+  lt_cv_ld_reload_flag,
+  [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[[45]]*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc*)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[[3-9]]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+    [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+    [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+    [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+    [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+  AC_SUBST([DUMPBIN])
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+  [lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+  cat conftest.out >&AS_MESSAGE_LOG_FD
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+    [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+  [lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*])
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+  # These system don't have libm, or don't need it
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
+  ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+  esac
+
+  _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+	[Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[[ABCDEGRST]]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris*)
+  symcode='[[BDRT]]'
+  ;;
+sco3.2v5*)
+  symcode='[[DT]]'
+  ;;
+sysv4.2uw2*)
+  symcode='[[DT]]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[[ABDT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK ['"\
+"     {last_section=section; section=\$ 3};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx]"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT@&t at _DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT@&t at _DLSYM_CONST
+#else
+# define LT@&t at _DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+LT@&t at _DLSYM_CONST struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_globsym_save_LIBS=$LIBS
+	  lt_globsym_save_CFLAGS=$CFLAGS
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS=$lt_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_save_CFLAGS
+	else
+	  echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+    [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+    [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+    [lt_cv_sys_global_symbol_to_c_name_address], [1],
+    [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+    [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+    [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([], [nm_file_list_spec], [1],
+    [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[[4-9]]*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	else
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      mingw* | cygwin* | os2* | pw32* | cegcc*)
+	# This hack is so that the source file can tell whether it is being
+	# built for inclusion in a dll (and should export symbols for example).
+	m4_if([$1], [GCJ], [],
+	  [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd*)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+	;;
+    esac
+  fi
+],
+[
+  if test "$GCC" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Xcompiler -fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      ccc*)
+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      xl* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ F* | *Sun*Fortran*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    rdos*)
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    unicos*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t at m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+    [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+    [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t at m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+	[Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+	[How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+  _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+  $lt_tmp_static_flag,
+  [],
+  [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+	[Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  case $host_os in
+  aix[[4-9]]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+    ;;
+  cygwin* | mingw* | cegcc*)
+    case $cc_basename in
+    cl*) ;;
+    *)
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+      ;;
+    esac
+    ;;
+  *)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+], [
+  runpath_var=
+  _LT_TAGVAR(allow_undefined_flag, $1)=
+  _LT_TAGVAR(always_export_symbols, $1)=no
+  _LT_TAGVAR(archive_cmds, $1)=
+  _LT_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_TAGVAR(compiler_needs_object, $1)=no
+  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(hardcode_automatic, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(inherit_rpath, $1)=no
+  _LT_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_TAGVAR(module_cmds, $1)=
+  _LT_TAGVAR(module_expsym_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  _LT_TAGVAR(ld_shlibs, $1)=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+	  *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[[3-9]]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=no
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    haiku*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    interix[[3-9]]*)
+      _LT_TAGVAR(hardcode_direct, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=' $pic_flag'
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# Portland Group f77 and f90 compilers
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+	  tmp_sharedflag='--shared' ;;
+	xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf* | bgf* | bgxlf* | mpixlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        _LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+
+    if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+      runpath_var=
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	_LT_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
+
+    aix[[4-9]]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      _LT_TAGVAR(archive_cmds, $1)=''
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[[012]]|aix4.[[012]].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        _LT_SYS_MODULE_PATH_AIX([$1])
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 _LT_SYS_MODULE_PATH_AIX([$1])
+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	  fi
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[[45]]*)
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	_LT_TAGVAR(always_export_symbols, $1)=yes
+	_LT_TAGVAR(file_list_spec, $1)='@'
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+	# The linker will automatically build a .lib file if we build a DLL.
+	_LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	# FIXME: Should let the user specify the lib program.
+	_LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+      _LT_DARWIN_LINKER_FEATURES($1)
+      ;;
+
+    dgux*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    freebsd1*)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	_LT_TAGVAR(hardcode_minus_L, $1)=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	m4_if($1, [], [
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  _LT_LINKER_OPTION([if $CC understands -b],
+	    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+	    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  ;;
+	*)
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+	# This should be the same for all languages, so no per-tag cache variable.
+	AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+	  [lt_cv_irix_exported_symbol],
+	  [save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+	   AC_LINK_IFELSE(
+	     [AC_LANG_SOURCE(
+	        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+			      [C++], [[int foo (void) { return 0; }]],
+			      [Fortran 77], [[
+      subroutine foo
+      end]],
+			      [Fortran], [[
+      subroutine foo
+      end]])])],
+	      [lt_cv_irix_exported_symbol=yes],
+	      [lt_cv_irix_exported_symbol=no])
+           LDFLAGS="$save_LDFLAGS"])
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(inherit_rpath, $1)=yes
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	     _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	     ;;
+	   *)
+	     _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    os2*)
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+        ;;
+	motorola)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4.3*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	_LT_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+    [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $_LT_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+	[lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+	[$RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+	  pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+	  _LT_TAGVAR(allow_undefined_flag, $1)=
+	  if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+	  then
+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	  else
+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  fi
+	  _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+	])
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+    [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+    [enable_shared_with_static_runtimes], [0],
+    [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+    [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+    [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+    [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+    [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+    [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+    [Commands used to build a loadable module if different from building
+    a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+    [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+    [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+    [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+    [Flag to hardcode $libdir into a binary during linking.
+    This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1],
+    [[If ld is used when linking, flag to hardcode $libdir into a binary
+    during linking.  This must work even if $libdir does not exist]])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+    [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary and the resulting library dependency is
+    "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+    library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+    [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+    [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+    [Set to "yes" if building a shared library automatically hardcodes DIR
+    into the library and all subsequent libraries and executables linked
+    against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+    [Set to yes if linker adds runtime paths of dependent libraries
+    to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+    [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+    [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+    [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+    [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+    [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+    [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+    [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+    [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl    [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_SYS_DYNAMIC_LINKER($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+  LT_SYS_DLOPEN_SELF
+  _LT_CMD_STRIPLIB
+
+  # Report which library types will actually be built
+  AC_MSG_CHECKING([if libtool supports shared libraries])
+  AC_MSG_RESULT([$can_build_shared])
+
+  AC_MSG_CHECKING([whether to build shared libraries])
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[[4-9]]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  AC_MSG_RESULT([$enable_shared])
+
+  AC_MSG_CHECKING([whether to build static libraries])
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  AC_MSG_RESULT([$enable_static])
+
+  _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  AC_PROG_CXXCPP
+else
+  _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_CFLAGS=$CFLAGS
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
+  fi
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
+  fi
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  CFLAGS=$CXXFLAGS
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test "$GXX" = yes; then
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+    else
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+      LT_PATH_LD
+
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test "$with_gnu_ld" = yes; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+        # If archive_cmds runs LD, not CC, wlarc should be empty
+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+        #     investigate it a little bit more. (MM)
+        wlarc='${wl}'
+
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+	  $GREP 'no-whole-archive' > /dev/null; then
+          _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          _LT_TAGVAR(whole_archive_flag_spec, $1)=
+        fi
+      else
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      fi
+
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+    _LT_TAGVAR(ld_shlibs, $1)=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+      aix[[4-9]]*)
+        if test "$host_cpu" = ia64; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=""
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # need to do runtime linking.
+          case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	    for ld_flag in $LDFLAGS; do
+	      case $ld_flag in
+	      *-brtl*)
+	        aix_use_runtimelinking=yes
+	        break
+	        ;;
+	      esac
+	    done
+	    ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        _LT_TAGVAR(archive_cmds, $1)=''
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+        if test "$GXX" = yes; then
+          case $host_os in aix4.[[012]]|aix4.[[012]].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	    # We have reworked collect2
+	    :
+	  else
+	    # We have old collect2
+	    _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	    # It fails to find uninstalled libraries when the uninstalled
+	    # path is not listed in the libpath.  Setting hardcode_minus_L
+	    # to unsupported forces relinking
+	    _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+          esac
+          shared_flag='-shared'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
+	  fi
+        else
+          # not using gcc
+          if test "$host_cpu" = ia64; then
+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	  # chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+          else
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
+	    else
+	      shared_flag='${wl}-bM:SRE'
+	    fi
+          fi
+        fi
+
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+	# export.
+        _LT_TAGVAR(always_export_symbols, $1)=yes
+        if test "$aix_use_runtimelinking" = yes; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          _LT_SYS_MODULE_PATH_AIX([$1])
+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+          else
+	    # Determine the default libpath from the value encoded in an
+	    # empty executable.
+	    _LT_SYS_MODULE_PATH_AIX([$1])
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	    # Warning - without using the other run time loading flags,
+	    # -berok will link without error, but may produce a broken library.
+	    _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	    _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	    fi
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+          fi
+        fi
+        ;;
+
+      beos*)
+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl*)
+	  # Native MSVC
+	  # hardcode_libdir_flag_spec is actually meaningless, as there is
+	  # no search path for DLLs.
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  _LT_TAGVAR(always_export_symbols, $1)=yes
+	  _LT_TAGVAR(file_list_spec, $1)='@'
+	  # Tell ltmain to make .lib files, not .a files.
+	  libext=lib
+	  # Tell ltmain to make .dll files, not .so files.
+	  shrext_cmds=".dll"
+	  # FIXME: Setting linknames here is a bad hack.
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	  # Don't use ranlib
+	  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
+	  ;;
+	*)
+	  # g++
+	  # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+	  # as there is no search path for DLLs.
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  _LT_TAGVAR(always_export_symbols, $1)=no
+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file (1st line
+	    # is EXPORTS), use it as is; otherwise, prepend...
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      cp $export_symbols $output_objdir/$soname.def;
+	    else
+	      echo EXPORTS > $output_objdir/$soname.def;
+	      cat $export_symbols >> $output_objdir/$soname.def;
+	    fi~
+	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	  ;;
+	esac
+	;;
+      darwin* | rhapsody*)
+        _LT_DARWIN_LINKER_FEATURES($1)
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      freebsd[[12]]*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      freebsd-elf*)
+        _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+        ;;
+
+      gnu*)
+        ;;
+
+      haiku*)
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        ;;
+
+      hpux9*)
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+				             # but as the default
+				             # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            _LT_TAGVAR(ld_shlibs, $1)=no
+            ;;
+          aCC*)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              _LT_TAGVAR(ld_shlibs, $1)=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            _LT_TAGVAR(hardcode_direct, $1)=no
+            _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+            ;;
+          *)
+            _LT_TAGVAR(hardcode_direct, $1)=yes
+            _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+					         # but as the default
+					         # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	    esac
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	        esac
+	      fi
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[[3-9]]*)
+	_LT_TAGVAR(hardcode_direct, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+	# Instead, shared libraries are loaded at an image base (0x10000000 by
+	# default) and relocated if they conflict, which is a slow very memory
+	# consuming and fragmenting process.  To avoid this, we pick a random,
+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	;;
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+	    # SGI C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+	      fi
+	    fi
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+	    ;;
+        esac
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(inherit_rpath, $1)=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+	    ;;
+	  icpc* | ecpc* )
+	    # Intel C++
+	    with_gnu_ld=yes
+	    # version 8.0 and above of icpc choke on multiply defined symbols
+	    # if we add $predep_objects and $postdep_objects, however 7.1 and
+	    # earlier do not add the objects themselves.
+	    case `$CC -V 2>&1` in
+	      *"Version 7."*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	      *)  # Version 8.0 or newer
+	        tmp_idyn=
+	        case $host_cpu in
+		  ia64*) tmp_idyn=' -i_dynamic';;
+		esac
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+		$RANLIB $oldlib'
+	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above use weak symbols
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	    runpath_var=LD_RUN_PATH
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	    fi
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	      _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+	      # Not sure whether something based on
+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	      # would be better.
+	      output_verbose_link_cmd='func_echo_all'
+
+	      # Archives containing C++ object files must be created using
+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	      # necessary to make sure instantiated templates are included
+	      # in the archive.
+	      _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	fi
+	# Workaround some broken pre-1.5 toolchains
+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+	;;
+
+      *nto* | *qnx*)
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=func_echo_all
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      osf3* | osf4* | osf5*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+		;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	      # Commands to make compiler produce verbose output that lists
+	      # what "hidden" libraries, object files and flags are used when
+	      # linking a shared library.
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	    case $host_os in
+	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+	      *)
+		# The compiler driver will combine and reorder linker options,
+		# but understands `-z linker_flag'.
+	        # Supported since Solaris 2.6 (maybe 2.5.1?)
+		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+	    output_verbose_link_cmd='func_echo_all'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	    # The C++ compiler must be used to create the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      fi
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+		*)
+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+      esac
+      ;;
+
+      sysv5* | sco3.2v5* | sco5v6*)
+	# Note: We can NOT use -z defs as we might desire, because we do not
+	# link with -lc, and that would cause any symbols used from libc to
+	# always be unresolved, which means just about no library would
+	# ever link correctly.  If we're not using GNU ld we use -z text
+	# though, which does catch some bad symbols but isn't as heavy-handed
+	# as -z defs.
+	_LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+	_LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+	_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+	_LT_TAGVAR(link_all_deplibs, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+	      '"$_LT_TAGVAR(old_archive_cmds, $1)"
+	    _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+	      '"$_LT_TAGVAR(reload_cmds, $1)"
+	    ;;
+	  *)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	esac
+      ;;
+
+      tandem*)
+        case $cc_basename in
+          NCC*)
+	    # NonStop-UX NCC 3.20
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+    esac
+
+    AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+    test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+    _LT_TAGVAR(GCC, $1)="$GXX"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+  esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case ${prev}${p} in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" ||
+          test $p = "-R"; then
+	 prev=$p
+	 continue
+       fi
+
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} in
+	 -L | -R)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+	   else
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+	   _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+	 else
+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+	 fi
+       fi
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+	   _LT_TAGVAR(predep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+	 fi
+       else
+	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+	   _LT_TAGVAR(postdep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  _LT_TAGVAR(predep_objects,$1)=
+  _LT_TAGVAR(postdep_objects,$1)=
+  _LT_TAGVAR(postdeps,$1)=
+  ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+    [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+    [Dependencies to place before and after the objects being linked to
+    create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+    [The library search path used internally by the compiler when linking
+    a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test "X$F77" = "Xno"; then
+  _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
+  CC=${F77-"f77"}
+  CFLAGS=$FFLAGS
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+  GCC=$G77
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$G77"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC="$lt_save_CC"
+  CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test "X$FC" = "Xno"; then
+  _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
+  CC=${FC-"f95"}
+  CFLAGS=$FCFLAGS
+  compiler=$CC
+  GCC=$ac_cv_fc_compiler_gnu
+
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+  :
+  _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+  [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+    [AC_CHECK_TOOL(GCJ, gcj,)
+      test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+      AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+    [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && continue
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([	 ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+    # positional parameters, so assign one to ordinary parameter first.
+    func_stripname_result=${3}
+    func_stripname_result=${func_stripname_result#"${1}"}
+    func_stripname_result=${func_stripname_result%"${2}"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+    func_split_long_opt_name=${1%%=*}
+    func_split_long_opt_arg=${1#*=}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+    func_split_short_opt_arg=${1#??}
+    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+    case ${1} in
+      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+      *)    func_lo2o_result=${1} ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_xform], [    func_xform_result=${1%.*}.lo])
+
+  _LT_PROG_FUNCTION_REPLACE([func_arith], [    func_arith_result=$(( $[*] ))])
+
+  _LT_PROG_FUNCTION_REPLACE([func_len], [    func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_append], [    eval "${1}+=\\${2}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+    func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+    eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine which file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path).  These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+         [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+         [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ltoptions.m4 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ltoptions.m4
new file mode 100755
index 0000000..17cfd51
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ltoptions.m4
@@ -0,0 +1,369 @@
+# Helper functions for option handling.                    -*- Autoconf -*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+#   Inc.
+#   Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 7 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it.  Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+        _LT_MANGLE_DEFUN([$1], [$2]),
+    [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+	    [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+		      [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME.  If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+    [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+  dnl
+  dnl Simply set some default values (i.e off) if boolean options were not
+  dnl specified:
+  _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+  ])
+  _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+  ])
+  dnl
+  dnl If no reference was made to various pairs of opposing options, then
+  dnl we run the default mode handler for the pair.  For example, if neither
+  dnl `shared' nor `disable-shared' was passed, we enable building of shared
+  dnl archives by default:
+  _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+  _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+  		   [_LT_ENABLE_FAST_INSTALL])
+  ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS],      [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+    [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+	[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+    _LT_DECL([build_libtool_libs], [enable_shared], [0],
+	[Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+    [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+	[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+    _LT_DECL([build_old_libs], [enable_static], [0],
+	[Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+    [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+    [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+	 [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+    [AS_HELP_STRING([--with-pic],
+	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [pic_mode="$withval"],
+    [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+		 [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+		 [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+		 [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+		 [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+		 [m4_define([_LTDL_TYPE], [convenience])])
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ltsugar.m4 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ltsugar.m4
new file mode 100755
index 0000000..9000a05
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ltsugar.m4
@@ -0,0 +1,123 @@
+# ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+       [$#], [2], [[$2]],
+       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+       [$#], 1, [],
+       [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+	   m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn.  Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+       [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+	     [m4_foreach([_Lt_suffix],
+		]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+	[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+	  [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+		 [lt_append([$1], [$2], [$3])$4],
+		 [$5])],
+	  [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+	m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+    m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+	[$5],
+    [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+  [lt_join(m4_quote(m4_default([$4], [[, ]])),
+           lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+		      [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ltversion.m4 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ltversion.m4
new file mode 100755
index 0000000..9c7b5d4
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers			-*- Autoconf -*-
+#
+#   Copyright (C) 2004 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# @configure_input@
+
+# serial 3293 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4])
+m4_define([LT_PACKAGE_REVISION], [1.3293])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4'
+macro_revision='1.3293'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/lt~obsolete.m4 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/lt~obsolete.m4
new file mode 100755
index 0000000..c573da9
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/m4/lt~obsolete.m4
@@ -0,0 +1,98 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else.  This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION],	[AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP],		[AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT],		[AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX],	[AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN],		[AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR],		[AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL],	[AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN],		[AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER],	[AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK],		[AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],	[AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF],	[AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O],	[AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR],		[AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR],		[AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],	[AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC],		[AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU],		[AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG],	[AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD],	[AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS],	[AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP],	[AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP],		[AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED],		[AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME],		[AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE],	[AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE],	[AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL],		[AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP],		[AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN],		[AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],	[AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG],		[AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL],	[AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX],		[AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77],		[AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ],		[AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG],	[AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG],	[AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG],	[AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG],	[AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG],	[AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG],		[AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C],	[AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS],	[AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP],		[AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS],	[AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77],		[AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC],		[AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX],		[AC_DEFUN([_LT_PROG_CXX])])
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/man/Makefile.am b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/man/Makefile.am
new file mode 100755
index 0000000..2519277
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/man/Makefile.am
@@ -0,0 +1,8 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS=foreign
+
+EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3
+
+man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/man/Makefile.in b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/man/Makefile.in
new file mode 100755
index 0000000..2cb5ea8
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/man/Makefile.in
@@ -0,0 +1,466 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = man
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_maxopt.m4 \
+	$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
+	$(top_srcdir)/m4/ax_check_compiler_flags.m4 \
+	$(top_srcdir)/m4/ax_compiler_vendor.m4 \
+	$(top_srcdir)/m4/ax_configure_args.m4 \
+	$(top_srcdir)/m4/ax_enable_builddir.m4 \
+	$(top_srcdir)/m4/ax_gcc_archflag.m4 \
+	$(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/fficonfig.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+man3dir = $(mandir)/man3
+am__installdirs = "$(DESTDIR)$(man3dir)"
+NROFF = nroff
+MANS = $(man_MANS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_LTLDFLAGS = @AM_LTLDFLAGS@
+AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PRTDIAG = @PRTDIAG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TARGET = @TARGET@
+TARGETDIR = @TARGETDIR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_enable_builddir_sed = @ax_enable_builddir_sed@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sys_symbol_underscore = @sys_symbol_underscore@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+toolexecdir = @toolexecdir@
+toolexeclibdir = @toolexeclibdir@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign
+EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3
+man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign man/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign man/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-man3: $(man_MANS)
+	@$(NORMAL_INSTALL)
+	test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)"
+	@list=''; test -n "$(man3dir)" || exit 0; \
+	{ for i in $$list; do echo "$$i"; done; \
+	l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+	  sed -n '/\.3[a-z]*$$/p'; \
+	} | while read p; do \
+	  if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; echo "$$p"; \
+	done | \
+	sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
+	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+	sed 'N;N;s,\n, ,g' | { \
+	list=; while read file base inst; do \
+	  if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+	    echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
+	    $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \
+	  fi; \
+	done; \
+	for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+	while read files; do \
+	  test -z "$$files" || { \
+	    echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \
+	    $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \
+	done; }
+
+uninstall-man3:
+	@$(NORMAL_UNINSTALL)
+	@list=''; test -n "$(man3dir)" || exit 0; \
+	files=`{ for i in $$list; do echo "$$i"; done; \
+	l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+	  sed -n '/\.3[a-z]*$$/p'; \
+	} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
+	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+	test -z "$$files" || { \
+	  echo " ( cd '$(DESTDIR)$(man3dir)' && rm -f" $$files ")"; \
+	  cd "$(DESTDIR)$(man3dir)" && rm -f $$files; }
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@list='$(MANS)'; if test -n "$$list"; then \
+	  list=`for p in $$list; do \
+	    if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+	    if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
+	  if test -n "$$list" && \
+	    grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
+	    echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
+	    grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/         /' >&2; \
+	    echo "       to fix them, install help2man, remove and regenerate the man pages;" >&2; \
+	    echo "       typically \`make maintainer-clean' will remove them" >&2; \
+	    exit 1; \
+	  else :; fi; \
+	else :; fi
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(MANS)
+installdirs:
+	for dir in "$(DESTDIR)$(man3dir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man3
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man
+
+uninstall-man: uninstall-man3
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-man3 \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am uninstall-man uninstall-man3
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/man/ffi.3 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/man/ffi.3
new file mode 100755
index 0000000..18b5d5d
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/man/ffi.3
@@ -0,0 +1,31 @@
+.Dd February 15, 2008
+.Dt FFI 3
+.Sh NAME
+.Nm FFI
+.Nd Foreign Function Interface
+.Sh LIBRARY
+libffi, -lffi
+.Sh SYNOPSIS
+.In ffi.h
+.Ft ffi_status
+.Fo ffi_prep_cif
+.Fa "ffi_cif *cif"
+.Fa "ffi_abi abi"
+.Fa "unsigned int nargs"
+.Fa "ffi_type *rtype"
+.Fa "ffi_type **atypes"
+.Fc
+.Ft void
+.Fo ffi_call
+.Fa "ffi_cif *cif"
+.Fa "void (*fn)(void)"
+.Fa "void *rvalue"
+.Fa "void **avalue"
+.Fc
+.Sh DESCRIPTION
+The foreign function interface provides a mechanism by which a function can
+generate a call to another function at runtime without requiring knowledge of
+the called function's interface at compile time.
+.Sh SEE ALSO
+.Xr ffi_prep_cif 3 ,
+.Xr ffi_call 3
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/man/ffi_call.3 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/man/ffi_call.3
new file mode 100755
index 0000000..5351513
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/man/ffi_call.3
@@ -0,0 +1,103 @@
+.Dd February 15, 2008
+.Dt ffi_call 3
+.Sh NAME
+.Nm ffi_call
+.Nd Invoke a foreign function.
+.Sh SYNOPSIS
+.In ffi.h
+.Ft void
+.Fo ffi_call
+.Fa "ffi_cif *cif"
+.Fa "void (*fn)(void)"
+.Fa "void *rvalue"
+.Fa "void **avalue"
+.Fc
+.Sh DESCRIPTION
+The
+.Nm ffi_call
+function provides a simple mechanism for invoking a function without
+requiring knowledge of the function's interface at compile time.
+.Fa fn
+is called with the values retrieved from the pointers in the
+.Fa avalue
+array. The return value from
+.Fa fn
+is placed in storage pointed to by
+.Fa rvalue .
+.Fa cif
+contains information describing the data types, sizes and alignments of the
+arguments to and return value from
+.Fa fn ,
+and must be initialized with
+.Nm ffi_prep_cif
+before it is used with
+.Nm ffi_call .
+.Pp
+.Fa rvalue
+must point to storage that is sizeof(ffi_arg) or larger for non-floating point
+types. For smaller-sized return value types, the
+.Nm ffi_arg
+or
+.Nm ffi_sarg
+integral type must be used to hold
+the return value.
+.Sh EXAMPLES
+.Bd -literal
+#include <ffi.h>
+#include <stdio.h>
+
+unsigned char
+foo(unsigned int, float);
+
+int
+main(int argc, const char **argv)
+{
+    ffi_cif cif;
+    ffi_type *arg_types[2];
+    void *arg_values[2];
+    ffi_status status;
+
+    // Because the return value from foo() is smaller than sizeof(long), it
+    // must be passed as ffi_arg or ffi_sarg.
+    ffi_arg result;
+
+    // Specify the data type of each argument. Available types are defined
+    // in <ffi/ffi.h>.
+    arg_types[0] = &ffi_type_uint;
+    arg_types[1] = &ffi_type_float;
+
+    // Prepare the ffi_cif structure.
+    if ((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
+        2, &ffi_type_uint8, arg_types)) != FFI_OK)
+    {
+        // Handle the ffi_status error.
+    }
+
+    // Specify the values of each argument.
+    unsigned int arg1 = 42;
+    float arg2 = 5.1;
+
+    arg_values[0] = &arg1;
+    arg_values[1] = &arg2;
+
+    // Invoke the function.
+    ffi_call(&cif, FFI_FN(foo), &result, arg_values);
+
+    // The ffi_arg 'result' now contains the unsigned char returned from foo(),
+    // which can be accessed by a typecast.
+    printf("result is %hhu", (unsigned char)result);
+
+    return 0;
+}
+
+// The target function.
+unsigned char
+foo(unsigned int x, float y)
+{
+    unsigned char result = x - y;
+    return result;
+}
+.Ed
+.Sh SEE ALSO
+.Xr ffi 3 ,
+.Xr ffi_prep_cif 3
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/man/ffi_prep_cif.3 b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/man/ffi_prep_cif.3
new file mode 100755
index 0000000..9436b31
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/man/ffi_prep_cif.3
@@ -0,0 +1,66 @@
+.Dd February 15, 2008
+.Dt ffi_prep_cif 3
+.Sh NAME
+.Nm ffi_prep_cif
+.Nd Prepare a
+.Nm ffi_cif
+structure for use with
+.Nm ffi_call 
+.
+.Sh SYNOPSIS
+.In ffi.h
+.Ft ffi_status
+.Fo ffi_prep_cif
+.Fa "ffi_cif *cif"
+.Fa "ffi_abi abi"
+.Fa "unsigned int nargs"
+.Fa "ffi_type *rtype"
+.Fa "ffi_type **atypes"
+.Fc
+.Sh DESCRIPTION
+The
+.Nm ffi_prep_cif
+function prepares a
+.Nm ffi_cif
+structure for use with 
+.Nm ffi_call
+.
+.Fa abi
+specifies a set of calling conventions to use.
+.Fa atypes
+is an array of
+.Fa nargs
+pointers to
+.Nm ffi_type
+structs that describe the data type, size and alignment of each argument.
+.Fa rtype
+points to an
+.Nm ffi_type
+that describes the data type, size and alignment of the
+return value.
+.Sh RETURN VALUES
+Upon successful completion,
+.Nm ffi_prep_cif
+returns
+.Nm FFI_OK .
+It will return
+.Nm FFI_BAD_TYPEDEF
+if
+.Fa cif
+is
+.Nm NULL
+or
+.Fa atypes
+or
+.Fa rtype
+is malformed. If
+.Fa abi
+does not refer to a valid ABI,
+.Nm FFI_BAD_ABI
+will be returned. Available ABIs are
+defined in
+.Nm <ffitarget.h>
+.
+.Sh SEE ALSO
+.Xr ffi 3 ,
+.Xr ffi_call 3 
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/mdate-sh b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/mdate-sh
new file mode 100755
index 0000000..cd916c0
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/mdate-sh
@@ -0,0 +1,201 @@
+#!/bin/sh
+# Get modification time of a file or directory and pretty-print it.
+
+scriptversion=2005-06-29.22
+
+# Copyright (C) 1995, 1996, 1997, 2003, 2004, 2005 Free Software
+# Foundation, Inc.
+# written by Ulrich Drepper <drepper at gnu.ai.mit.edu>, June 1995
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake at gnu.org> or send patches to
+# <automake-patches at gnu.org>.
+
+case $1 in
+  '')
+     echo "$0: No file.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: mdate-sh [--help] [--version] FILE
+
+Pretty-print the modification time of FILE.
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "mdate-sh $scriptversion"
+    exit $?
+    ;;
+esac
+
+# Prevent date giving response in another language.
+LANG=C
+export LANG
+LC_ALL=C
+export LC_ALL
+LC_TIME=C
+export LC_TIME
+
+# GNU ls changes its time format in response to the TIME_STYLE
+# variable.  Since we cannot assume `unset' works, revert this
+# variable to its documented default.
+if test "${TIME_STYLE+set}" = set; then
+  TIME_STYLE=posix-long-iso
+  export TIME_STYLE
+fi
+
+save_arg1=$1
+
+# Find out how to get the extended ls output of a file or directory.
+if ls -L /dev/null 1>/dev/null 2>&1; then
+  ls_command='ls -L -l -d'
+else
+  ls_command='ls -l -d'
+fi
+
+# A `ls -l' line looks as follows on OS/2.
+#  drwxrwx---        0 Aug 11  2001 foo
+# This differs from Unix, which adds ownership information.
+#  drwxrwx---   2 root  root      4096 Aug 11  2001 foo
+#
+# To find the date, we split the line on spaces and iterate on words
+# until we find a month.  This cannot work with files whose owner is a
+# user named `Jan', or `Feb', etc.  However, it's unlikely that `/'
+# will be owned by a user whose name is a month.  So we first look at
+# the extended ls output of the root directory to decide how many
+# words should be skipped to get the date.
+
+# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
+set x`ls -l -d /`
+
+# Find which argument is the month.
+month=
+command=
+until test $month
+do
+  shift
+  # Add another shift to the command.
+  command="$command shift;"
+  case $1 in
+    Jan) month=January; nummonth=1;;
+    Feb) month=February; nummonth=2;;
+    Mar) month=March; nummonth=3;;
+    Apr) month=April; nummonth=4;;
+    May) month=May; nummonth=5;;
+    Jun) month=June; nummonth=6;;
+    Jul) month=July; nummonth=7;;
+    Aug) month=August; nummonth=8;;
+    Sep) month=September; nummonth=9;;
+    Oct) month=October; nummonth=10;;
+    Nov) month=November; nummonth=11;;
+    Dec) month=December; nummonth=12;;
+  esac
+done
+
+# Get the extended ls output of the file or directory.
+set dummy x`eval "$ls_command \"\$save_arg1\""`
+
+# Remove all preceding arguments
+eval $command
+
+# Because of the dummy argument above, month is in $2.
+#
+# On a POSIX system, we should have
+#
+# $# = 5
+# $1 = file size
+# $2 = month
+# $3 = day
+# $4 = year or time
+# $5 = filename
+#
+# On Darwin 7.7.0 and 7.6.0, we have
+#
+# $# = 4
+# $1 = day
+# $2 = month
+# $3 = year or time
+# $4 = filename
+
+# Get the month.
+case $2 in
+  Jan) month=January; nummonth=1;;
+  Feb) month=February; nummonth=2;;
+  Mar) month=March; nummonth=3;;
+  Apr) month=April; nummonth=4;;
+  May) month=May; nummonth=5;;
+  Jun) month=June; nummonth=6;;
+  Jul) month=July; nummonth=7;;
+  Aug) month=August; nummonth=8;;
+  Sep) month=September; nummonth=9;;
+  Oct) month=October; nummonth=10;;
+  Nov) month=November; nummonth=11;;
+  Dec) month=December; nummonth=12;;
+esac
+
+case $3 in
+  ???*) day=$1;;
+  *) day=$3; shift;;
+esac
+
+# Here we have to deal with the problem that the ls output gives either
+# the time of day or the year.
+case $3 in
+  *:*) set `date`; eval year=\$$#
+       case $2 in
+	 Jan) nummonthtod=1;;
+	 Feb) nummonthtod=2;;
+	 Mar) nummonthtod=3;;
+	 Apr) nummonthtod=4;;
+	 May) nummonthtod=5;;
+	 Jun) nummonthtod=6;;
+	 Jul) nummonthtod=7;;
+	 Aug) nummonthtod=8;;
+	 Sep) nummonthtod=9;;
+	 Oct) nummonthtod=10;;
+	 Nov) nummonthtod=11;;
+	 Dec) nummonthtod=12;;
+       esac
+       # For the first six month of the year the time notation can also
+       # be used for files modified in the last year.
+       if (expr $nummonth \> $nummonthtod) > /dev/null;
+       then
+	 year=`expr $year - 1`
+       fi;;
+  *) year=$3;;
+esac
+
+# The result.
+echo $day $month $year
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/missing b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/missing
new file mode 100755
index 0000000..28055d2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/missing
@@ -0,0 +1,376 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+# 2008, 2009 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard at iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  autom4te     touch the output file, or create a stub one
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
+\`g' are ignored when checking the name.
+
+Send bug reports to <bug-automake at gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# normalize program name to check for.
+program=`echo "$1" | sed '
+  s/^gnu-//; t
+  s/^gnu//; t
+  s/^g//; t'`
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).  This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+  lex*|yacc*)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar*)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $program in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case $f in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te*)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison*|yacc*)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+	case $LASTARG in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f y.tab.h; then
+	echo >y.tab.h
+    fi
+    if test ! -f y.tab.c; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex*|flex*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+	case $LASTARG in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f lex.yy.c; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit $?
+    fi
+    ;;
+
+  makeinfo*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '
+	/^@setfilename/{
+	  s/.* \([^ ]*\) *$/\1/
+	  p
+	  q
+	}' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    # If the file does not exist, the user really needs makeinfo;
+    # let's fail without touching anything.
+    test -f $file || exit 1
+    touch $file
+    ;;
+
+  tar*)
+    shift
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case $firstarg in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+	case $firstarg in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/msvcc.sh b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/msvcc.sh
new file mode 100755
index 0000000..dcdbeab
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/msvcc.sh
@@ -0,0 +1,197 @@
+#!/bin/sh
+
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the MSVC wrappificator.
+#
+# The Initial Developer of the Original Code is
+# Timothy Wall <twalljava at dev.java.net>.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Daniel Witte <dwitte at mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#
+# GCC-compatible wrapper for cl.exe and ml.exe. Arguments are given in GCC
+# format and translated into something sensible for cl or ml.
+#
+
+args="-nologo -W3"
+md=-MD
+cl="cl"
+ml="ml"
+safeseh="-safeseh"
+output=
+
+while [ $# -gt 0 ]
+do
+  case $1
+  in
+    -fexceptions)
+      # Don't enable exceptions for now.
+      #args="$args -EHac"
+      shift 1
+    ;;
+    -m32)
+      shift 1
+    ;;
+    -m64)
+      cl="cl"   # "$MSVC/x86_amd64/cl"
+      ml="ml64" # "$MSVC/x86_amd64/ml64"
+      safeseh=
+      shift 1
+    ;;
+    -O0)
+      args="$args -Od"
+      shift 1
+    ;;
+    -O*)
+      # If we're optimizing, make sure we explicitly turn on some optimizations
+      # that are implicitly disabled by debug symbols (-Zi).
+      args="$args $1 -OPT:REF -OPT:ICF -INCREMENTAL:NO"
+      shift 1
+    ;;
+    -g)
+      # Enable debug symbol generation.
+      args="$args -Zi -DEBUG"
+      shift 1
+    ;;
+    -DFFI_DEBUG)
+      # Link against debug CRT and enable runtime error checks.
+      args="$args -RTC1"
+      defines="$defines $1"
+      md=-MDd
+      shift 1
+    ;;
+    -c)
+      args="$args -c"
+      args="$(echo $args | sed 's%/Fe%/Fo%g')"
+      single="-c"
+      shift 1
+    ;;
+    -D*=*)
+      name="$(echo $1|sed 's/-D\([^=][^=]*\)=.*/\1/g')"
+      value="$(echo $1|sed 's/-D[^=][^=]*=//g')"
+      args="$args -D${name}='$value'"
+      defines="$defines -D${name}='$value'"
+      shift 1
+    ;;
+    -D*)
+      args="$args $1"
+      defines="$defines $1"
+      shift 1
+    ;;
+    -I)
+      args="$args -I$2"
+      includes="$includes -I$2"
+      shift 2
+    ;;
+    -I*)
+      args="$args $1"
+      includes="$includes $1"
+      shift 1
+    ;;
+    -W|-Wextra)
+      # TODO map extra warnings
+      shift 1
+    ;;
+    -Wall)
+      # -Wall on MSVC is overzealous, and we already build with -W3. Nothing
+      # to do here.
+      shift 1
+    ;;
+    -Werror)
+      args="$args -WX"
+      shift 1
+    ;;
+    -W*)
+      # TODO map specific warnings
+      shift 1
+    ;;
+    -S)
+      args="$args -FAs"
+      shift 1
+    ;;
+    -o)
+      outdir="$(dirname $2)"
+      base="$(basename $2|sed 's/\.[^.]*//g')"
+      if [ -n "$single" ]; then 
+        output="-Fo$2"
+      else
+        output="-Fe$2"
+      fi
+      if [ -n "$assembly" ]; then
+        args="$args $output"
+      else
+        args="$args $output -Fd$outdir/$base -Fp$outdir/$base -Fa$outdir/$base"
+      fi
+      shift 2
+    ;;
+    *.S)
+      src=$1
+      assembly="true"
+      shift 1
+    ;;
+    *.c)
+      args="$args $1"
+      shift 1
+    ;;
+    *)
+      # Assume it's an MSVC argument, and pass it through.
+      args="$args $1"
+      shift 1
+    ;;
+  esac
+done
+
+if [ -n "$assembly" ]; then
+    if [ -z "$outdir" ]; then
+      outdir="."
+    fi
+    ppsrc="$outdir/$(basename $src|sed 's/.S$/.asm/g')"
+    echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
+    "$cl" -nologo -EP $includes $defines $src > $ppsrc || exit $?
+    output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')"
+    args="-nologo $safeseh $single $output $ppsrc"
+
+    echo "$ml $args"
+    eval "\"$ml\" $args"
+    result=$?
+
+    # required to fix ml64 broken output?
+    #mv *.obj $outdir
+else
+    args="$md $args"
+    echo "$cl $args"
+    eval "\"$cl\" $args"
+    result=$?
+fi
+
+exit $result
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/alpha/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/alpha/ffi.c
new file mode 100755
index 0000000..8d6b2ba
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/alpha/ffi.c
@@ -0,0 +1,284 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 1998, 2001, 2007, 2008  Red Hat, Inc.
+   
+   Alpha Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+#include <stdlib.h>
+
+/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
+   all further uses in this file will refer to the 128-bit type.  */
+#if defined(__LONG_DOUBLE_128__)
+# if FFI_TYPE_LONGDOUBLE != 4
+#  error FFI_TYPE_LONGDOUBLE out of date
+# endif
+#else
+# undef FFI_TYPE_LONGDOUBLE
+# define FFI_TYPE_LONGDOUBLE 4
+#endif
+
+extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)(void))
+  FFI_HIDDEN;
+extern void ffi_closure_osf(void) FFI_HIDDEN;
+
+
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  /* Adjust cif->bytes to represent a minimum 6 words for the temporary
+     register argument loading area.  */
+  if (cif->bytes < 6*FFI_SIZEOF_ARG)
+    cif->bytes = 6*FFI_SIZEOF_ARG;
+
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_STRUCT:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+      cif->flags = cif->rtype->type;
+      break;
+
+    case FFI_TYPE_LONGDOUBLE:
+      /* 128-bit long double is returned in memory, like a struct.  */
+      cif->flags = FFI_TYPE_STRUCT;
+      break;
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+  
+  return FFI_OK;
+}
+
+
+void
+ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  unsigned long *stack, *argp;
+  long i, avn;
+  ffi_type **arg_types;
+  
+  /* If the return value is a struct and we don't have a return
+     value address then we need to make one.  */
+  if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT)
+    rvalue = alloca(cif->rtype->size);
+
+  /* Allocate the space for the arguments, plus 4 words of temp
+     space for ffi_call_osf.  */
+  argp = stack = alloca(cif->bytes + 4*FFI_SIZEOF_ARG);
+
+  if (cif->flags == FFI_TYPE_STRUCT)
+    *(void **) argp++ = rvalue;
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+
+  while (i < avn)
+    {
+      size_t size = (*arg_types)->size;
+
+      switch ((*arg_types)->type)
+	{
+	case FFI_TYPE_SINT8:
+	  *(SINT64 *) argp = *(SINT8 *)(* avalue);
+	  break;
+		  
+	case FFI_TYPE_UINT8:
+	  *(SINT64 *) argp = *(UINT8 *)(* avalue);
+	  break;
+		  
+	case FFI_TYPE_SINT16:
+	  *(SINT64 *) argp = *(SINT16 *)(* avalue);
+	  break;
+		  
+	case FFI_TYPE_UINT16:
+	  *(SINT64 *) argp = *(UINT16 *)(* avalue);
+	  break;
+		  
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	  /* Note that unsigned 32-bit quantities are sign extended.  */
+	  *(SINT64 *) argp = *(SINT32 *)(* avalue);
+	  break;
+		  
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_POINTER:
+	  *(UINT64 *) argp = *(UINT64 *)(* avalue);
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  if (argp - stack < 6)
+	    {
+	      /* Note the conversion -- all the fp regs are loaded as
+		 doubles.  The in-register format is the same.  */
+	      *(double *) argp = *(float *)(* avalue);
+	    }
+	  else
+	    *(float *) argp = *(float *)(* avalue);
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  *(double *) argp = *(double *)(* avalue);
+	  break;
+
+	case FFI_TYPE_LONGDOUBLE:
+	  /* 128-bit long double is passed by reference.  */
+	  *(long double **) argp = (long double *)(* avalue);
+	  size = sizeof (long double *);
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  memcpy(argp, *avalue, (*arg_types)->size);
+	  break;
+
+	default:
+	  FFI_ASSERT(0);
+	}
+
+      argp += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+      i++, arg_types++, avalue++;
+    }
+
+  ffi_call_osf(stack, cif->bytes, cif->flags, rvalue, fn);
+}
+
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif*, void*, void**, void*),
+		      void *user_data,
+		      void *codeloc)
+{
+  unsigned int *tramp;
+
+  tramp = (unsigned int *) &closure->tramp[0];
+  tramp[0] = 0x47fb0401;	/* mov $27,$1		*/
+  tramp[1] = 0xa77b0010;	/* ldq $27,16($27)	*/
+  tramp[2] = 0x6bfb0000;	/* jmp $31,($27),0	*/
+  tramp[3] = 0x47ff041f;	/* nop			*/
+  *(void **) &tramp[4] = ffi_closure_osf;
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  /* Flush the Icache.
+
+     Tru64 UNIX as doesn't understand the imb mnemonic, so use call_pal
+     instead, since both Compaq as and gas can handle it.
+
+     0x86 is PAL_imb in Tru64 UNIX <alpha/pal.h>.  */
+  asm volatile ("call_pal 0x86" : : : "memory");
+
+  return FFI_OK;
+}
+
+
+long FFI_HIDDEN
+ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
+{
+  ffi_cif *cif;
+  void **avalue;
+  ffi_type **arg_types;
+  long i, avn, argn;
+
+  cif = closure->cif;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  argn = 0;
+
+  /* Copy the caller's structure return address to that the closure
+     returns the data directly to the caller.  */
+  if (cif->flags == FFI_TYPE_STRUCT)
+    {
+      rvalue = (void *) argp[0];
+      argn = 1;
+    }
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+  
+  /* Grab the addresses of the arguments from the stack frame.  */
+  while (i < avn)
+    {
+      size_t size = arg_types[i]->size;
+
+      switch (arg_types[i]->type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_POINTER:
+	case FFI_TYPE_STRUCT:
+	  avalue[i] = &argp[argn];
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  if (argn < 6)
+	    {
+	      /* Floats coming from registers need conversion from double
+	         back to float format.  */
+	      *(float *)&argp[argn - 6] = *(double *)&argp[argn - 6];
+	      avalue[i] = &argp[argn - 6];
+	    }
+	  else
+	    avalue[i] = &argp[argn];
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)];
+	  break;
+
+	case FFI_TYPE_LONGDOUBLE:
+	  /* 128-bit long double is passed by reference.  */
+	  avalue[i] = (long double *) argp[argn];
+	  size = sizeof (long double *);
+	  break;
+
+	default:
+	  abort ();
+	}
+
+      argn += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+      i++;
+    }
+
+  /* Invoke the closure.  */
+  closure->fun (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_osf how to perform return type promotions.  */
+  return cif->rtype->type;
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/alpha/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/alpha/ffitarget.h
new file mode 100755
index 0000000..7d06eb0
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/alpha/ffitarget.h
@@ -0,0 +1,48 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for Alpha.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_OSF,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_OSF
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 24
+#define FFI_NATIVE_RAW_API 0
+
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/alpha/osf.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/alpha/osf.S
new file mode 100755
index 0000000..6b9f4df
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/alpha/osf.S
@@ -0,0 +1,387 @@
+/* -----------------------------------------------------------------------
+   osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011 Red Hat
+   
+   Alpha/OSF Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+	.arch ev6
+	.text
+
+/* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
+		 void *raddr, void (*fnaddr)(void));
+
+   Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
+   for this function.  This has been allocated by ffi_call.  We also
+   deallocate some of the stack that has been alloca'd.  */
+
+	.align	3
+	.globl	ffi_call_osf
+	.ent	ffi_call_osf
+	FFI_HIDDEN(ffi_call_osf)
+
+ffi_call_osf:
+	.frame	$15, 32, $26, 0
+	.mask   0x4008000, -32
+$LFB1:
+	addq	$16,$17,$1
+	mov	$16, $30
+	stq	$26, 0($1)
+	stq	$15, 8($1)
+	stq	$18, 16($1)
+	mov	$1, $15
+$LCFI1:
+	.prologue 0
+
+	stq	$19, 24($1)
+	mov	$20, $27
+
+	# Load up all of the (potential) argument registers.
+	ldq	$16, 0($30)
+	ldt	$f16, 0($30)
+	ldt	$f17, 8($30)
+	ldq	$17, 8($30)
+	ldt	$f18, 16($30)
+	ldq	$18, 16($30)
+	ldt	$f19, 24($30)
+	ldq	$19, 24($30)
+	ldt	$f20, 32($30)
+	ldq	$20, 32($30)
+	ldt	$f21, 40($30)
+	ldq	$21, 40($30)
+
+	# Deallocate the register argument area.
+	lda	$30, 48($30)
+
+	jsr	$26, ($27), 0
+	ldgp	$29, 0($26)
+
+	# If the return value pointer is NULL, assume no return value.
+	ldq	$19, 24($15)
+	ldq	$18, 16($15)
+	ldq	$26, 0($15)
+$LCFI2:
+	beq	$19, $noretval
+
+	# Store the return value out in the proper type.
+	cmpeq	$18, FFI_TYPE_INT, $1
+	bne	$1, $retint
+	cmpeq	$18, FFI_TYPE_FLOAT, $2
+	bne	$2, $retfloat
+	cmpeq	$18, FFI_TYPE_DOUBLE, $3
+	bne	$3, $retdouble
+
+	.align	3
+$noretval:
+	ldq	$15, 8($15)
+	ret
+
+	.align	4
+$retint:
+	stq	$0, 0($19)
+	nop
+	ldq	$15, 8($15)
+	ret
+
+	.align	4
+$retfloat:
+	sts	$f0, 0($19)
+	nop
+	ldq	$15, 8($15)
+	ret
+
+	.align	4
+$retdouble:
+	stt	$f0, 0($19)
+	nop
+	ldq	$15, 8($15)
+	ret
+$LFE1:
+
+	.end	ffi_call_osf
+
+/* ffi_closure_osf(...)
+
+   Receives the closure argument in $1.   */
+
+	.align	3
+	.globl	ffi_closure_osf
+	.ent	ffi_closure_osf
+	FFI_HIDDEN(ffi_closure_osf)
+
+ffi_closure_osf:
+	.frame	$30, 16*8, $26, 0
+	.mask	0x4000000, -16*8
+$LFB2:
+	ldgp	$29, 0($27)
+	subq	$30, 16*8, $30
+$LCFI5:
+	stq	$26, 0($30)
+$LCFI6:
+	.prologue 1
+
+	# Store all of the potential argument registers in va_list format.
+	stt	$f16, 4*8($30)
+	stt	$f17, 5*8($30)
+	stt	$f18, 6*8($30)
+	stt	$f19, 7*8($30)
+	stt	$f20, 8*8($30)
+	stt	$f21, 9*8($30)
+	stq	$16, 10*8($30)
+	stq	$17, 11*8($30)
+	stq	$18, 12*8($30)
+	stq	$19, 13*8($30)
+	stq	$20, 14*8($30)
+	stq	$21, 15*8($30)
+
+	# Call ffi_closure_osf_inner to do the bulk of the work.
+	mov	$1, $16
+	lda	$17, 2*8($30)
+	lda	$18, 10*8($30)
+	jsr	$26, ffi_closure_osf_inner
+	ldgp	$29, 0($26)
+	ldq	$26, 0($30)
+
+	# Load up the return value in the proper type.
+	lda	$1, $load_table
+	s4addq	$0, $1, $1
+	ldl	$1, 0($1)
+	addq	$1, $29, $1
+	jmp	$31, ($1), $load_32
+
+	.align 4
+$load_none:
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_float:
+	lds	$f0, 16($30)
+	nop
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_double:
+	ldt	$f0, 16($30)
+	nop
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_u8:
+#ifdef __alpha_bwx__
+	ldbu	$0, 16($30)
+	nop
+#else
+	ldq	$0, 16($30)
+	and	$0, 255, $0
+#endif
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_s8:
+#ifdef __alpha_bwx__
+	ldbu	$0, 16($30)
+	sextb	$0, $0
+#else
+	ldq	$0, 16($30)
+	sll	$0, 56, $0
+	sra	$0, 56, $0
+#endif
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_u16:
+#ifdef __alpha_bwx__
+	ldwu	$0, 16($30)
+	nop
+#else
+	ldq	$0, 16($30)
+	zapnot	$0, 3, $0
+#endif
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_s16:
+#ifdef __alpha_bwx__
+	ldwu	$0, 16($30)
+	sextw	$0, $0
+#else
+	ldq	$0, 16($30)
+	sll	$0, 48, $0
+	sra	$0, 48, $0
+#endif
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_32:
+	ldl	$0, 16($30)
+	nop
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_64:
+	ldq	$0, 16($30)
+	nop
+	addq	$30, 16*8, $30
+	ret
+$LFE2:
+
+	.end	ffi_closure_osf
+
+#ifdef __ELF__
+.section .rodata
+#else
+.rdata
+#endif
+$load_table:
+	.gprel32 $load_none	# FFI_TYPE_VOID
+	.gprel32 $load_32	# FFI_TYPE_INT
+	.gprel32 $load_float	# FFI_TYPE_FLOAT
+	.gprel32 $load_double	# FFI_TYPE_DOUBLE
+	.gprel32 $load_none	# FFI_TYPE_LONGDOUBLE
+	.gprel32 $load_u8	# FFI_TYPE_UINT8
+	.gprel32 $load_s8	# FFI_TYPE_SINT8
+	.gprel32 $load_u16	# FFI_TYPE_UINT16
+	.gprel32 $load_s16	# FFI_TYPE_SINT16
+	.gprel32 $load_32	# FFI_TYPE_UINT32
+	.gprel32 $load_32	# FFI_TYPE_SINT32
+	.gprel32 $load_64	# FFI_TYPE_UINT64
+	.gprel32 $load_64	# FFI_TYPE_SINT64
+	.gprel32 $load_none	# FFI_TYPE_STRUCT
+	.gprel32 $load_64	# FFI_TYPE_POINTER
+
+/* Assert that the table above is in sync with ffi.h.  */
+
+#if	   FFI_TYPE_FLOAT != 2		\
+	|| FFI_TYPE_DOUBLE != 3		\
+	|| FFI_TYPE_UINT8 != 5		\
+	|| FFI_TYPE_SINT8 != 6		\
+	|| FFI_TYPE_UINT16 != 7		\
+	|| FFI_TYPE_SINT16 != 8		\
+	|| FFI_TYPE_UINT32 != 9		\
+	|| FFI_TYPE_SINT32 != 10	\
+	|| FFI_TYPE_UINT64 != 11	\
+	|| FFI_TYPE_SINT64 != 12	\
+	|| FFI_TYPE_STRUCT != 13	\
+	|| FFI_TYPE_POINTER != 14	\
+	|| FFI_TYPE_LAST != 14
+#error "osf.S out of sync with ffi.h"
+#endif
+
+#ifdef __ELF__
+# define UA_SI		.4byte
+# define FDE_ENCODING	0x1b	/* pcrel sdata4 */
+# define FDE_ENCODE(X)	.4byte X-.
+# define FDE_ARANGE(X)	.4byte X
+#elif defined __osf__
+# define UA_SI		.align 0; .long
+# define FDE_ENCODING	0x50	/* aligned absolute */
+# define FDE_ENCODE(X)	.align 3; .quad X
+# define FDE_ARANGE(X)	.align 0; .quad X
+#endif
+
+#ifdef __ELF__
+	.section	.eh_frame,EH_FRAME_FLAGS, at progbits
+#elif defined __osf__
+	.data
+	.align 3
+	.globl _GLOBAL__F_ffi_call_osf
+_GLOBAL__F_ffi_call_osf:
+#endif
+__FRAME_BEGIN__:
+	UA_SI	$LECIE1-$LSCIE1	# Length of Common Information Entry
+$LSCIE1:
+	UA_SI	0x0		# CIE Identifier Tag
+	.byte	0x1		# CIE Version
+	.ascii "zR\0"		# CIE Augmentation
+	.byte	0x1		# uleb128 0x1; CIE Code Alignment Factor
+	.byte	0x78		# sleb128 -8; CIE Data Alignment Factor
+	.byte	26		# CIE RA Column
+	.byte	0x1		# uleb128 0x1; Augmentation size
+	.byte	FDE_ENCODING	# FDE Encoding
+	.byte	0xc		# DW_CFA_def_cfa
+	.byte	30		# uleb128 column 30
+	.byte	0		# uleb128 offset 0
+	.align 3
+$LECIE1:
+$LSFDE1:
+	UA_SI	$LEFDE1-$LASFDE1		# FDE Length
+$LASFDE1:
+	UA_SI	$LASFDE1-__FRAME_BEGIN__	# FDE CIE offset
+	FDE_ENCODE($LFB1)			# FDE initial location
+	FDE_ARANGE($LFE1-$LFB1)			# FDE address range
+	.byte	0x0		# uleb128 0x0; Augmentation size
+
+	.byte	0x4		# DW_CFA_advance_loc4
+	UA_SI	$LCFI1-$LFB1
+	.byte	0x9a		# DW_CFA_offset, column 26
+	.byte	4		# uleb128 4*-8
+	.byte	0x8f		# DW_CFA_offset, column 15
+	.byte	0x3		# uleb128 3*-8
+	.byte	0xc		# DW_CFA_def_cfa
+	.byte	15		# uleb128 column 15
+	.byte	32		# uleb128 offset 32
+
+	.byte	0x4		# DW_CFA_advance_loc4
+	UA_SI	$LCFI2-$LCFI1
+	.byte	0xda		# DW_CFA_restore, column 26
+	.align 3
+$LEFDE1:
+
+$LSFDE3:
+	UA_SI	$LEFDE3-$LASFDE3		# FDE Length
+$LASFDE3:
+	UA_SI	$LASFDE3-__FRAME_BEGIN__	# FDE CIE offset
+	FDE_ENCODE($LFB2)			# FDE initial location
+	FDE_ARANGE($LFE2-$LFB2)			# FDE address range
+	.byte	0x0		# uleb128 0x0; Augmentation size
+
+	.byte	0x4		# DW_CFA_advance_loc4
+	UA_SI	$LCFI5-$LFB2
+	.byte	0xe		# DW_CFA_def_cfa_offset
+	.byte	0x80,0x1	# uleb128 128
+
+	.byte	0x4		# DW_CFA_advance_loc4
+	UA_SI	$LCFI6-$LCFI5
+	.byte	0x9a		# DW_CFA_offset, column 26
+	.byte	16		# uleb128 offset 16*-8
+	.align 3
+$LEFDE3:
+#if defined __osf__
+	.align 0
+	.long	0		# End of Table
+#endif
+
+#if defined __ELF__ && defined __linux__
+	.section	.note.GNU-stack,"", at progbits
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/arm/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/arm/ffi.c
new file mode 100755
index 0000000..b2e7667
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/arm/ffi.c
@@ -0,0 +1,728 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2011 Plausible Labs Cooperative, Inc.
+           Copyright (c) 2011 Anthony Green
+	   Copyright (c) 2011 Free Software Foundation
+           Copyright (c) 1998, 2008, 2011  Red Hat, Inc.
+	   
+   ARM Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* Forward declares. */
+static int vfp_type_p (ffi_type *);
+static void layout_vfp_args (ffi_cif *);
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments
+   
+   The vfp_space parameter is the load area for VFP regs, the return
+   value is cif->vfp_used (word bitset of VFP regs used for passing
+   arguments). These are only used for the VFP hard-float ABI.
+*/
+int ffi_prep_args(char *stack, extended_cif *ecif, float *vfp_space)
+{
+  register unsigned int i, vi = 0;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+
+  argp = stack;
+
+  if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {
+    *(void **) argp = ecif->rvalue;
+    argp += 4;
+  }
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       (i != 0);
+       i--, p_arg++)
+    {
+      size_t z;
+
+      /* Allocated in VFP registers. */
+      if (ecif->cif->abi == FFI_VFP
+	  && vi < ecif->cif->vfp_nargs && vfp_type_p (*p_arg))
+	{
+	  float* vfp_slot = vfp_space + ecif->cif->vfp_args[vi++];
+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	    *((float*)vfp_slot) = *((float*)*p_argv);
+	  else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+	    *((double*)vfp_slot) = *((double*)*p_argv);
+	  else
+	    memcpy(vfp_slot, *p_argv, (*p_arg)->size);
+	  p_argv++;
+	  continue;
+	}
+
+      /* Align if necessary */
+      if (((*p_arg)->alignment - 1) & (unsigned) argp) {
+	argp = (char *) ALIGN(argp, (*p_arg)->alignment);
+      }
+
+      if ((*p_arg)->type == FFI_TYPE_STRUCT)
+	argp = (char *) ALIGN(argp, 4);
+
+	  z = (*p_arg)->size;
+	  if (z < sizeof(int))
+	    {
+	      z = sizeof(int);
+	      switch ((*p_arg)->type)
+		{
+		case FFI_TYPE_SINT8:
+		  *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_UINT8:
+		  *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_SINT16:
+		  *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_UINT16:
+		  *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_STRUCT:
+		  memcpy(argp, *p_argv, (*p_arg)->size);
+		  break;
+
+		default:
+		  FFI_ASSERT(0);
+		}
+	    }
+	  else if (z == sizeof(int))
+	    {
+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	    }
+	  else
+	    {
+	      memcpy(argp, *p_argv, z);
+	    }
+	  p_argv++;
+	  argp += z;
+    }
+
+  /* Indicate the VFP registers used. */
+  return ecif->cif->vfp_used;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  int type_code;
+  /* Round the stack up to a multiple of 8 bytes.  This isn't needed 
+     everywhere, but it is on some platforms, and it doesn't harm anything
+     when it isn't needed.  */
+  cif->bytes = (cif->bytes + 7) & ~7;
+
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+      cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      cif->flags = (unsigned) FFI_TYPE_SINT64;
+      break;
+
+    case FFI_TYPE_STRUCT:
+      if (cif->abi == FFI_VFP
+	  && (type_code = vfp_type_p (cif->rtype)) != 0)
+	{
+	  /* A Composite Type passed in VFP registers, either
+	     FFI_TYPE_STRUCT_VFP_FLOAT or FFI_TYPE_STRUCT_VFP_DOUBLE. */
+	  cif->flags = (unsigned) type_code;
+	}
+      else if (cif->rtype->size <= 4)
+	/* A Composite Type not larger than 4 bytes is returned in r0.  */
+	cif->flags = (unsigned)FFI_TYPE_INT;
+      else
+	/* A Composite Type larger than 4 bytes, or whose size cannot
+	   be determined statically ... is stored in memory at an
+	   address passed [in r0].  */
+	cif->flags = (unsigned)FFI_TYPE_STRUCT;
+      break;
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+
+  /* Map out the register placements of VFP register args.
+     The VFP hard-float calling conventions are slightly more sophisticated than
+     the base calling conventions, so we do it here instead of in ffi_prep_args(). */
+  if (cif->abi == FFI_VFP)
+    layout_vfp_args (cif);
+
+  return FFI_OK;
+}
+
+/* Prototypes for assembly functions, in sysv.S */
+extern void ffi_call_SYSV (void (*fn)(void), extended_cif *, unsigned, unsigned, unsigned *);
+extern void ffi_call_VFP (void (*fn)(void), extended_cif *, unsigned, unsigned, unsigned *);
+
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+
+  int small_struct = (cif->flags == FFI_TYPE_INT 
+		      && cif->rtype->type == FFI_TYPE_STRUCT);
+  int vfp_struct = (cif->flags == FFI_TYPE_STRUCT_VFP_FLOAT
+		    || cif->flags == FFI_TYPE_STRUCT_VFP_DOUBLE);
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+
+  unsigned int temp;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if ((rvalue == NULL) && 
+      (cif->flags == FFI_TYPE_STRUCT))
+    {
+      ecif.rvalue = alloca(cif->rtype->size);
+    }
+  else if (small_struct)
+    ecif.rvalue = &temp;
+  else if (vfp_struct)
+    {
+      /* Largest case is double x 4. */
+      ecif.rvalue = alloca(32);
+    }
+  else
+    ecif.rvalue = rvalue;
+
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      ffi_call_SYSV (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);
+      break;
+
+    case FFI_VFP:
+      ffi_call_VFP (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);
+      break;
+
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+  if (small_struct)
+    memcpy (rvalue, &temp, cif->rtype->size);
+  else if (vfp_struct)
+    memcpy (rvalue, ecif.rvalue, cif->rtype->size);
+}
+
+/** private members **/
+
+static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
+					 void** args, ffi_cif* cif, float *vfp_stack);
+
+void ffi_closure_SYSV (ffi_closure *);
+
+void ffi_closure_VFP (ffi_closure *);
+
+/* This function is jumped to by the trampoline */
+
+unsigned int
+ffi_closure_SYSV_inner (closure, respp, args, vfp_args)
+     ffi_closure *closure;
+     void **respp;
+     void *args;
+     void *vfp_args;
+{
+  // our various things...
+  ffi_cif       *cif;
+  void         **arg_area;
+
+  cif         = closure->cif;
+  arg_area    = (void**) alloca (cif->nargs * sizeof (void*));  
+
+  /* this call will initialize ARG_AREA, such that each
+   * element in that array points to the corresponding 
+   * value on the stack; and if the function returns
+   * a structure, it will re-set RESP to point to the
+   * structure return address.  */
+
+  ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif, vfp_args);
+
+  (closure->fun) (cif, *respp, arg_area, closure->user_data);
+
+  return cif->flags;
+}
+
+/*@-exportheader@*/
+static void 
+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+			    void **avalue, ffi_cif *cif,
+			    /* Used only under VFP hard-float ABI. */
+			    float *vfp_stack)
+/*@=exportheader@*/
+{
+  register unsigned int i, vi = 0;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+
+  argp = stack;
+
+  if ( cif->flags == FFI_TYPE_STRUCT ) {
+    *rvalue = *(void **) argp;
+    argp += 4;
+  }
+
+  p_argv = avalue;
+
+  for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+    {
+      size_t z;
+      size_t alignment;
+  
+      if (cif->abi == FFI_VFP
+	  && vi < cif->vfp_nargs && vfp_type_p (*p_arg))
+	{
+	  *p_argv++ = (void*)(vfp_stack + cif->vfp_args[vi++]);
+	  continue;
+	}
+
+      alignment = (*p_arg)->alignment;
+      if (alignment < 4)
+	alignment = 4;
+      /* Align if necessary */
+      if ((alignment - 1) & (unsigned) argp) {
+	argp = (char *) ALIGN(argp, alignment);
+      }
+
+      z = (*p_arg)->size;
+
+      /* because we're little endian, this is what it turns into.   */
+
+      *p_argv = (void*) argp;
+
+      p_argv++;
+      argp += z;
+    }
+  
+  return;
+}
+
+/* How to make a trampoline.  */
+
+#if FFI_EXEC_TRAMPOLINE_TABLE
+
+#include <mach/mach.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+extern void *ffi_closure_trampoline_table_page;
+
+typedef struct ffi_trampoline_table ffi_trampoline_table;
+typedef struct ffi_trampoline_table_entry ffi_trampoline_table_entry;
+
+struct ffi_trampoline_table {
+  /* contigious writable and executable pages */
+  vm_address_t config_page;
+  vm_address_t trampoline_page;
+
+  /* free list tracking */
+  uint16_t free_count;
+  ffi_trampoline_table_entry *free_list;
+  ffi_trampoline_table_entry *free_list_pool;
+
+  ffi_trampoline_table *prev;
+  ffi_trampoline_table *next;
+};
+
+struct ffi_trampoline_table_entry {
+  void *(*trampoline)();
+  ffi_trampoline_table_entry *next;
+};
+
+/* Override the standard architecture trampoline size */
+// XXX TODO - Fix
+#undef FFI_TRAMPOLINE_SIZE
+#define FFI_TRAMPOLINE_SIZE 12
+
+/* The trampoline configuration is placed at 4080 bytes prior to the trampoline's entry point */
+#define FFI_TRAMPOLINE_CODELOC_CONFIG(codeloc) ((void **) (((uint8_t *) codeloc) - 4080));
+
+/* The first 16 bytes of the config page are unused, as they are unaddressable from the trampoline page. */
+#define FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET 16
+
+/* Total number of trampolines that fit in one trampoline table */
+#define FFI_TRAMPOLINE_COUNT ((PAGE_SIZE - FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET) / FFI_TRAMPOLINE_SIZE)
+
+static pthread_mutex_t ffi_trampoline_lock = PTHREAD_MUTEX_INITIALIZER;
+static ffi_trampoline_table *ffi_trampoline_tables = NULL;
+
+static ffi_trampoline_table *
+ffi_trampoline_table_alloc ()
+{
+  ffi_trampoline_table *table = NULL;
+
+  /* Loop until we can allocate two contigious pages */
+  while (table == NULL) {
+    vm_address_t config_page = 0x0;
+    kern_return_t kt;
+
+    /* Try to allocate two pages */
+    kt = vm_allocate (mach_task_self (), &config_page, PAGE_SIZE*2, VM_FLAGS_ANYWHERE);
+    if (kt != KERN_SUCCESS) {
+      fprintf(stderr, "vm_allocate() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
+      break;
+    }
+
+    /* Now drop the second half of the allocation to make room for the trampoline table */
+    vm_address_t trampoline_page = config_page+PAGE_SIZE;
+    kt = vm_deallocate (mach_task_self (), trampoline_page, PAGE_SIZE);
+    if (kt != KERN_SUCCESS) {
+      fprintf(stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
+      break;
+    }
+
+    /* Remap the trampoline table to directly follow the config page */
+    vm_prot_t cur_prot;
+    vm_prot_t max_prot;
+
+    kt = vm_remap (mach_task_self (), &trampoline_page, PAGE_SIZE, 0x0, FALSE, mach_task_self (), (vm_address_t) &ffi_closure_trampoline_table_page, FALSE, &cur_prot, &max_prot, VM_INHERIT_SHARE);
+
+    /* If we lost access to the destination trampoline page, drop our config allocation mapping and retry */
+    if (kt != KERN_SUCCESS) {
+      /* Log unexpected failures */
+      if (kt != KERN_NO_SPACE) {
+        fprintf(stderr, "vm_remap() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
+      }
+
+      vm_deallocate (mach_task_self (), config_page, PAGE_SIZE);
+      continue;
+    }
+
+    /* We have valid trampoline and config pages */
+    table = calloc (1, sizeof(ffi_trampoline_table));
+    table->free_count = FFI_TRAMPOLINE_COUNT;
+    table->config_page = config_page;
+    table->trampoline_page = trampoline_page;
+
+    /* Create and initialize the free list */
+    table->free_list_pool = calloc(FFI_TRAMPOLINE_COUNT, sizeof(ffi_trampoline_table_entry));
+
+    uint16_t i;
+    for (i = 0; i < table->free_count; i++) {
+      ffi_trampoline_table_entry *entry = &table->free_list_pool[i];
+      entry->trampoline = (void *) (table->trampoline_page + (i * FFI_TRAMPOLINE_SIZE));
+
+      if (i < table->free_count - 1)
+        entry->next = &table->free_list_pool[i+1];
+    }
+
+    table->free_list = table->free_list_pool;
+  }
+
+  return table;
+}
+
+void *
+ffi_closure_alloc (size_t size, void **code)
+{
+  /* Create the closure */
+  ffi_closure *closure = malloc(size);
+  if (closure == NULL)
+    return NULL;
+
+  pthread_mutex_lock(&ffi_trampoline_lock);
+
+  /* Check for an active trampoline table with available entries. */
+  ffi_trampoline_table *table = ffi_trampoline_tables;
+  if (table == NULL || table->free_list == NULL) {
+    table = ffi_trampoline_table_alloc ();
+    if (table == NULL) {
+      free(closure);
+      return NULL;
+    }
+
+    /* Insert the new table at the top of the list */
+    table->next = ffi_trampoline_tables;
+    if (table->next != NULL)
+        table->next->prev = table;
+
+    ffi_trampoline_tables = table;
+  }
+
+  /* Claim the free entry */
+  ffi_trampoline_table_entry *entry = ffi_trampoline_tables->free_list;
+  ffi_trampoline_tables->free_list = entry->next;
+  ffi_trampoline_tables->free_count--;
+  entry->next = NULL;
+
+  pthread_mutex_unlock(&ffi_trampoline_lock);
+
+  /* Initialize the return values */
+  *code = entry->trampoline;
+  closure->trampoline_table = table;
+  closure->trampoline_table_entry = entry;
+
+  return closure;
+}
+
+void
+ffi_closure_free (void *ptr)
+{
+  ffi_closure *closure = ptr;
+
+  pthread_mutex_lock(&ffi_trampoline_lock);
+
+  /* Fetch the table and entry references */
+  ffi_trampoline_table *table = closure->trampoline_table;
+  ffi_trampoline_table_entry *entry = closure->trampoline_table_entry;
+
+  /* Return the entry to the free list */
+  entry->next = table->free_list;
+  table->free_list = entry;
+  table->free_count++;
+
+  /* If all trampolines within this table are free, and at least one other table exists, deallocate
+   * the table */
+  if (table->free_count == FFI_TRAMPOLINE_COUNT && ffi_trampoline_tables != table) {
+    /* Remove from the list */
+    if (table->prev != NULL)
+      table->prev->next = table->next;
+
+    if (table->next != NULL)
+      table->next->prev = table->prev;
+
+    /* Deallocate pages */
+    kern_return_t kt;
+    kt = vm_deallocate (mach_task_self (), table->config_page, PAGE_SIZE);
+    if (kt != KERN_SUCCESS)
+      fprintf(stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
+
+    kt = vm_deallocate (mach_task_self (), table->trampoline_page, PAGE_SIZE);
+    if (kt != KERN_SUCCESS)
+      fprintf(stderr, "vm_deallocate() failure: %d at %s:%d\n", kt, __FILE__, __LINE__);
+
+    /* Deallocate free list */
+    free (table->free_list_pool);
+    free (table);
+  } else if (ffi_trampoline_tables != table) {
+    /* Otherwise, bump this table to the top of the list */
+    table->prev = NULL;
+    table->next = ffi_trampoline_tables;
+    if (ffi_trampoline_tables != NULL)
+      ffi_trampoline_tables->prev = table;
+
+    ffi_trampoline_tables = table;
+  }
+
+  pthread_mutex_unlock (&ffi_trampoline_lock);
+
+  /* Free the closure */
+  free (closure);
+}
+
+#else
+
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX)				\
+({ unsigned char *__tramp = (unsigned char*)(TRAMP);			\
+   unsigned int  __fun = (unsigned int)(FUN);				\
+   unsigned int  __ctx = (unsigned int)(CTX);				\
+   unsigned char *insns = (unsigned char *)(CTX);                       \
+   *(unsigned int*) &__tramp[0] = 0xe92d000f; /* stmfd sp!, {r0-r3} */	\
+   *(unsigned int*) &__tramp[4] = 0xe59f0000; /* ldr r0, [pc] */	\
+   *(unsigned int*) &__tramp[8] = 0xe59ff000; /* ldr pc, [pc] */	\
+   *(unsigned int*) &__tramp[12] = __ctx;				\
+   *(unsigned int*) &__tramp[16] = __fun;				\
+   __clear_cache((&__tramp[0]), (&__tramp[19])); /* Clear data mapping.  */ \
+   __clear_cache(insns, insns + 3 * sizeof (unsigned int));             \
+                                                 /* Clear instruction   \
+                                                    mapping.  */        \
+ })
+
+#endif
+
+/* the cif must already be prep'ed */
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif*,void*,void**,void*),
+		      void *user_data,
+		      void *codeloc)
+{
+  void (*closure_func)(ffi_closure*) = NULL;
+
+  if (cif->abi == FFI_SYSV)
+    closure_func = &ffi_closure_SYSV;
+  else if (cif->abi == FFI_VFP)
+    closure_func = &ffi_closure_VFP;
+  else
+    return FFI_BAD_ABI;
+    
+#if FFI_EXEC_TRAMPOLINE_TABLE
+  void **config = FFI_TRAMPOLINE_CODELOC_CONFIG(codeloc);
+  config[0] = closure;
+  config[1] = closure_func;
+#else
+  FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
+		       closure_func,  \
+		       codeloc);
+#endif
+
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+
+  return FFI_OK;
+}
+
+/* Below are routines for VFP hard-float support. */
+
+static int rec_vfp_type_p (ffi_type *t, int *elt, int *elnum)
+{
+  switch (t->type)
+    {
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+      *elt = (int) t->type;
+      *elnum = 1;
+      return 1;
+
+    case FFI_TYPE_STRUCT_VFP_FLOAT:
+      *elt = FFI_TYPE_FLOAT;
+      *elnum = t->size / sizeof (float);
+      return 1;
+
+    case FFI_TYPE_STRUCT_VFP_DOUBLE:
+      *elt = FFI_TYPE_DOUBLE;
+      *elnum = t->size / sizeof (double);
+      return 1;
+
+    case FFI_TYPE_STRUCT:;
+      {
+	int base_elt = 0, total_elnum = 0;
+	ffi_type **el = t->elements;
+	while (*el)
+	  {
+	    int el_elt = 0, el_elnum = 0;
+	    if (! rec_vfp_type_p (*el, &el_elt, &el_elnum)
+		|| (base_elt && base_elt != el_elt)
+		|| total_elnum + el_elnum > 4)
+	      return 0;
+	    base_elt = el_elt;
+	    total_elnum += el_elnum;
+	    el++;
+	  }
+	*elnum = total_elnum;
+	*elt = base_elt;
+	return 1;
+      }
+    default: ;
+    }
+  return 0;
+}
+
+static int vfp_type_p (ffi_type *t)
+{
+  int elt, elnum;
+  if (rec_vfp_type_p (t, &elt, &elnum))
+    {
+      if (t->type == FFI_TYPE_STRUCT)
+	{
+	  if (elnum == 1)
+	    t->type = elt;
+	  else
+	    t->type = (elt == FFI_TYPE_FLOAT
+		       ? FFI_TYPE_STRUCT_VFP_FLOAT
+		       : FFI_TYPE_STRUCT_VFP_DOUBLE);
+	}
+      return (int) t->type;
+    }
+  return 0;
+}
+
+static void place_vfp_arg (ffi_cif *cif, ffi_type *t)
+{
+  int reg = cif->vfp_reg_free;
+  int nregs = t->size / sizeof (float);
+  int align = ((t->type == FFI_TYPE_STRUCT_VFP_FLOAT
+		|| t->type == FFI_TYPE_FLOAT) ? 1 : 2);
+  /* Align register number. */
+  if ((reg & 1) && align == 2)
+    reg++;
+  while (reg + nregs <= 16)
+    {
+      int s, new_used = 0;
+      for (s = reg; s < reg + nregs; s++)
+	{
+	  new_used |= (1 << s);
+	  if (cif->vfp_used & (1 << s))
+	    {
+	      reg += align;
+	      goto next_reg;
+	    }
+	}
+      /* Found regs to allocate. */
+      cif->vfp_used |= new_used;
+      cif->vfp_args[cif->vfp_nargs++] = reg;
+
+      /* Update vfp_reg_free. */
+      if (cif->vfp_used & (1 << cif->vfp_reg_free))
+	{
+	  reg += nregs;
+	  while (cif->vfp_used & (1 << reg))
+	    reg += 1;
+	  cif->vfp_reg_free = reg;
+	}
+      return;
+    next_reg: ;
+    }
+}
+
+static void layout_vfp_args (ffi_cif *cif)
+{
+  int i;
+  /* Init VFP fields */
+  cif->vfp_used = 0;
+  cif->vfp_nargs = 0;
+  cif->vfp_reg_free = 0;
+  memset (cif->vfp_args, -1, 16); /* Init to -1. */
+
+  for (i = 0; i < cif->nargs; i++)
+    {
+      ffi_type *t = cif->arg_types[i];
+      if (vfp_type_p (t))
+	place_vfp_arg (cif, t);
+    }
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/arm/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/arm/ffitarget.h
new file mode 100755
index 0000000..ce25b23
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/arm/ffitarget.h
@@ -0,0 +1,65 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+                 Copyright (c) 2010 CodeSourcery
+
+   Target configuration macros for ARM.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_VFP,
+  FFI_LAST_ABI,
+#ifdef __ARM_PCS_VFP
+  FFI_DEFAULT_ABI = FFI_VFP,
+#else
+  FFI_DEFAULT_ABI = FFI_SYSV,
+#endif
+} ffi_abi;
+#endif
+
+#define FFI_EXTRA_CIF_FIELDS			\
+  int vfp_used;					\
+  short vfp_reg_free, vfp_nargs;		\
+  signed char vfp_args[16]			\
+
+/* Internally used. */
+#define FFI_TYPE_STRUCT_VFP_FLOAT  (FFI_TYPE_LAST + 1)
+#define FFI_TYPE_STRUCT_VFP_DOUBLE (FFI_TYPE_LAST + 2)
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 20
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/arm/gentramp.sh b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/arm/gentramp.sh
new file mode 100755
index 0000000..74f0b86
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/arm/gentramp.sh
@@ -0,0 +1,118 @@
+#!/bin/sh
+
+# -----------------------------------------------------------------------
+#  gentramp.sh - Copyright (c) 2010, Plausible Labs Cooperative, Inc.
+#  
+#  ARM Trampoline Page Generator
+#
+#  Permission is hereby granted, free of charge, to any person obtaining
+#  a copy of this software and associated documentation files (the
+#  ``Software''), to deal in the Software without restriction, including
+#  without limitation the rights to use, copy, modify, merge, publish,
+#  distribute, sublicense, and/or sell copies of the Software, and to
+#  permit persons to whom the Software is furnished to do so, subject to
+#  the following conditions:
+#
+#  The above copyright notice and this permission notice shall be included
+#  in all copies or substantial portions of the Software.
+#
+#  THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+#  NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+#  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+#  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+#  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#  DEALINGS IN THE SOFTWARE.
+#  -----------------------------------------------------------------------
+
+PROGNAME=$0
+
+# Each trampoline is exactly 3 instructions, or 12 bytes. If any of these values change,
+# the entire arm trampoline implementation must be updated to match, too.
+
+# Size of an individual trampoline, in bytes
+TRAMPOLINE_SIZE=12
+
+# Page size, in bytes
+PAGE_SIZE=4096
+
+# Compute the size of the reachable config page; The first 16 bytes of the config page
+# are unreachable due to our maximum pc-relative ldr offset.
+PAGE_AVAIL=`expr $PAGE_SIZE - 16`
+
+# Compute the number of of available trampolines. 
+TRAMPOLINE_COUNT=`expr $PAGE_AVAIL / $TRAMPOLINE_SIZE`
+
+header () {
+    echo "# GENERATED CODE - DO NOT EDIT"
+    echo "# This file was generated by $PROGNAME"
+    echo ""
+
+    # Write out the license header
+cat << EOF
+#  Copyright (c) 2010, Plausible Labs Cooperative, Inc.
+#  
+#  Permission is hereby granted, free of charge, to any person obtaining
+#  a copy of this software and associated documentation files (the
+#  ``Software''), to deal in the Software without restriction, including
+#  without limitation the rights to use, copy, modify, merge, publish,
+#  distribute, sublicense, and/or sell copies of the Software, and to
+#  permit persons to whom the Software is furnished to do so, subject to
+#  the following conditions:
+#
+#  The above copyright notice and this permission notice shall be included
+#  in all copies or substantial portions of the Software.
+#
+#  THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+#  NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+#  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+#  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+#  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#  DEALINGS IN THE SOFTWARE.
+#  -----------------------------------------------------------------------
+
+EOF
+
+    # Write out the trampoline table, aligned to the page boundary
+    echo ".text"
+    echo ".align 12"
+    echo ".globl _ffi_closure_trampoline_table_page"
+    echo "_ffi_closure_trampoline_table_page:"
+}
+
+
+# WARNING - Don't modify the trampoline code size without also updating the relevent libffi code
+trampoline () {
+    cat << END
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+END
+}
+
+main () {
+    # Write out the header
+    header
+
+    # Write out the trampolines
+    local i=0
+    while [ $i -lt ${TRAMPOLINE_COUNT} ]; do
+        trampoline
+        local i=`expr $i + 1`
+    done
+}
+
+main
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/arm/sysv.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/arm/sysv.S
new file mode 100755
index 0000000..14a7f03
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/arm/sysv.S
@@ -0,0 +1,497 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
+	    Copyright (c) 2011 Plausible Labs Cooperative, Inc.
+   
+   ARM Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+#ifdef __USER_LABEL_PREFIX__
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+/* Use the right prefix for global labels.  */
+#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+#else
+#define CNAME(x) x
+#endif
+#ifdef __APPLE__
+#define ENTRY(x) .globl CNAME(x); CNAME(x):
+#else
+#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
+#endif /* __APPLE__ */
+#endif
+
+#ifdef __ELF__
+#define LSYM(x) .x
+#else
+#define LSYM(x) x
+#endif
+
+/* Use the SOFTFP return value ABI on Mac OS X, as per the iOS ABI
+  Function Call Guide */
+#ifdef __APPLE__
+#define __SOFTFP__
+#endif
+
+/* We need a better way of testing for this, but for now, this is all 
+   we can do.  */
+@ This selects the minimum architecture level required.
+#define __ARM_ARCH__ 3
+
+#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 4
+#endif
+        
+#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
+	|| defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
+	|| defined(__ARM_ARCH_5TEJ__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 5
+#endif
+
+#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+        || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
+        || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
+	|| defined(__ARM_ARCH_6M__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 6
+#endif
+
+#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+        || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
+	|| defined(__ARM_ARCH_7EM__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 7
+#endif
+
+#if __ARM_ARCH__ >= 5
+# define call_reg(x)	blx	x
+#elif defined (__ARM_ARCH_4T__)
+# define call_reg(x)	mov	lr, pc ; bx	x
+# if defined(__thumb__) || defined(__THUMB_INTERWORK__)
+#  define __INTERWORKING__
+# endif
+#else
+# define call_reg(x)	mov	lr, pc ; mov	pc, x
+#endif
+
+/* Conditionally compile unwinder directives.  */
+#ifdef __ARM_EABI__
+#define UNWIND
+#else
+#define UNWIND @
+#endif	
+
+	
+#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
+.macro	ARM_FUNC_START name
+	.text
+	.align 0
+	.thumb
+	.thumb_func
+#ifdef __APPLE__
+	ENTRY($0)
+#else
+	ENTRY(\name)
+#endif
+	bx	pc
+	nop
+	.arm
+	UNWIND .fnstart
+/* A hook to tell gdb that we've switched to ARM mode.  Also used to call
+   directly from other local arm routines.  */
+#ifdef __APPLE__
+_L__$0:
+#else
+_L__\name:
+#endif
+.endm
+#else
+.macro	ARM_FUNC_START name
+	.text
+	.align 0
+	.arm
+#ifdef __APPLE__
+	ENTRY($0)
+#else
+	ENTRY(\name)
+#endif
+	UNWIND .fnstart
+.endm
+#endif
+
+.macro	RETLDM	regs=, cond=, dirn=ia
+#if defined (__INTERWORKING__)
+	.ifc "\regs",""
+	ldr\cond	lr, [sp], #4
+	.else
+	ldm\cond\dirn	sp!, {\regs, lr}
+	.endif
+	bx\cond	lr
+#else
+	.ifc "\regs",""
+	ldr\cond	pc, [sp], #4
+	.else
+	ldm\cond\dirn	sp!, {\regs, pc}
+	.endif
+#endif
+.endm
+
+	@ r0:   ffi_prep_args
+	@ r1:   &ecif
+	@ r2:   cif->bytes
+	@ r3:   fig->flags
+	@ sp+0: ecif.rvalue
+
+	@ This assumes we are using gas.
+ARM_FUNC_START ffi_call_SYSV
+	@ Save registers
+        stmfd	sp!, {r0-r3, fp, lr}
+	UNWIND .save	{r0-r3, fp, lr}
+	mov	fp, sp
+
+	UNWIND .setfp	fp, sp
+
+	@ Make room for all of the new args.
+	sub	sp, fp, r2
+
+	@ Place all of the ffi_prep_args in position
+	mov	r0, sp
+	@     r1 already set
+
+	@ Call ffi_prep_args(stack, &ecif)
+	bl	ffi_prep_args
+
+	@ move first 4 parameters in registers
+	ldmia	sp, {r0-r3}
+
+	@ and adjust stack
+	sub	lr, fp, sp	@ cif->bytes == fp - sp
+	ldr	ip, [fp]	@ load fn() in advance
+	cmp	lr, #16
+	movhs	lr, #16
+	add	sp, sp, lr
+
+	@ call (fn) (...)
+	call_reg(ip)
+	
+	@ Remove the space we pushed for the args
+	mov	sp, fp
+
+	@ Load r2 with the pointer to storage for the return value
+	ldr	r2, [sp, #24]
+
+	@ Load r3 with the return type code 
+	ldr	r3, [sp, #12]
+
+	@ If the return value pointer is NULL, assume no return value.
+	cmp	r2, #0
+	beq	LSYM(Lepilogue)
+
+@ return INT
+	cmp	r3, #FFI_TYPE_INT
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
+	cmpne	r3, #FFI_TYPE_FLOAT
+#endif
+	streq	r0, [r2]
+	beq	LSYM(Lepilogue)
+
+	@ return INT64
+	cmp	r3, #FFI_TYPE_SINT64
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
+	cmpne	r3, #FFI_TYPE_DOUBLE
+#endif
+	stmeqia	r2, {r0, r1}
+
+#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
+	beq	LSYM(Lepilogue)
+
+@ return FLOAT
+	cmp	r3, #FFI_TYPE_FLOAT
+	stfeqs	f0, [r2]
+	beq	LSYM(Lepilogue)
+
+@ return DOUBLE or LONGDOUBLE
+	cmp	r3, #FFI_TYPE_DOUBLE
+	stfeqd	f0, [r2]
+#endif
+
+LSYM(Lepilogue):
+#if defined (__INTERWORKING__)
+	ldmia   sp!, {r0-r3,fp, lr}
+	bx	lr
+#else
+	ldmia   sp!, {r0-r3,fp, pc}
+#endif
+
+.ffi_call_SYSV_end:
+	UNWIND .fnend
+#ifdef __ELF__
+        .size    CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+#endif
+
+
+/*
+	unsigned int FFI_HIDDEN
+	ffi_closure_SYSV_inner (closure, respp, args)
+	     ffi_closure *closure;
+	     void **respp;
+  	     void *args;
+*/
+
+ARM_FUNC_START ffi_closure_SYSV
+	UNWIND .pad #16
+	add	ip, sp, #16
+	stmfd	sp!, {ip, lr}
+	UNWIND .save	{r0, lr}
+	add	r2, sp, #8
+	UNWIND .pad #16
+	sub	sp, sp, #16
+	str	sp, [sp, #8]
+	add	r1, sp, #8
+	bl	CNAME(ffi_closure_SYSV_inner)
+	cmp	r0, #FFI_TYPE_INT
+	beq	.Lretint
+
+	cmp	r0, #FFI_TYPE_FLOAT
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
+	beq	.Lretint
+#else
+	beq	.Lretfloat
+#endif
+
+	cmp	r0, #FFI_TYPE_DOUBLE
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
+	beq	.Lretlonglong
+#else
+	beq	.Lretdouble
+#endif
+
+	cmp	r0, #FFI_TYPE_LONGDOUBLE
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
+	beq	.Lretlonglong
+#else
+	beq	.Lretlongdouble
+#endif
+
+	cmp	r0, #FFI_TYPE_SINT64
+	beq	.Lretlonglong
+.Lclosure_epilogue:
+	add	sp, sp, #16
+	ldmfd	sp, {sp, pc}
+.Lretint:
+	ldr	r0, [sp]
+	b	.Lclosure_epilogue
+.Lretlonglong:
+	ldr	r0, [sp]
+	ldr	r1, [sp, #4]
+	b	.Lclosure_epilogue
+
+#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
+.Lretfloat:
+	ldfs	f0, [sp]
+	b	.Lclosure_epilogue
+.Lretdouble:
+	ldfd	f0, [sp]
+	b	.Lclosure_epilogue
+.Lretlongdouble:
+	ldfd	f0, [sp]
+	b	.Lclosure_epilogue
+#endif
+
+.ffi_closure_SYSV_end:
+	UNWIND .fnend
+#ifdef __ELF__
+        .size    CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
+#endif
+
+
+/* Below are VFP hard-float ABI call and closure implementations.
+   Add VFP FPU directive here. */
+	.fpu	vfp
+
+	@ r0:   fn
+	@ r1:   &ecif
+	@ r2:   cif->bytes
+	@ r3:   fig->flags
+	@ sp+0: ecif.rvalue
+
+ARM_FUNC_START ffi_call_VFP
+	@ Save registers
+        stmfd	sp!, {r0-r3, fp, lr}
+	UNWIND .save	{r0-r3, fp, lr}
+	mov	fp, sp
+	UNWIND .setfp	fp, sp
+
+	@ Make room for all of the new args.
+	sub	sp, sp, r2
+
+	@ Make room for loading VFP args
+	sub	sp, sp, #64
+
+	@ Place all of the ffi_prep_args in position
+	mov	r0, sp
+	@     r1 already set
+	sub	r2, fp, #64   @ VFP scratch space
+
+	@ Call ffi_prep_args(stack, &ecif, vfp_space)
+	bl	ffi_prep_args
+
+	@ Load VFP register args if needed
+	cmp	r0, #0
+	beq	LSYM(Lbase_args)
+
+	@ Load only d0 if possible
+	cmp	r0, #3
+	sub	ip, fp, #64
+	flddle	d0, [ip]
+	fldmiadgt	ip, {d0-d7}
+
+LSYM(Lbase_args):
+	@ move first 4 parameters in registers
+	ldmia	sp, {r0-r3}
+
+	@ and adjust stack
+	sub	lr, ip, sp	@ cif->bytes == (fp - 64) - sp
+	ldr	ip, [fp]	@ load fn() in advance
+        cmp	lr, #16
+	movhs	lr, #16
+        add	sp, sp, lr
+
+	@ call (fn) (...)
+	call_reg(ip)
+
+	@ Remove the space we pushed for the args
+	mov	sp, fp
+
+	@ Load r2 with the pointer to storage for
+	@ the return value
+	ldr	r2, [sp, #24]
+
+	@ Load r3 with the return type code 
+	ldr	r3, [sp, #12]
+
+	@ If the return value pointer is NULL,
+	@ assume no return value.
+	cmp	r2, #0
+	beq	LSYM(Lepilogue_vfp)
+
+	cmp	r3, #FFI_TYPE_INT
+	streq	r0, [r2]
+	beq	LSYM(Lepilogue_vfp)
+
+	cmp	r3, #FFI_TYPE_SINT64
+	stmeqia	r2, {r0, r1}
+	beq	LSYM(Lepilogue_vfp)
+
+	cmp	r3, #FFI_TYPE_FLOAT
+	fstseq	s0, [r2]
+	beq	LSYM(Lepilogue_vfp)
+	
+	cmp	r3, #FFI_TYPE_DOUBLE
+	fstdeq	d0, [r2]
+	beq	LSYM(Lepilogue_vfp)
+
+	cmp	r3, #FFI_TYPE_STRUCT_VFP_FLOAT
+	cmpne	r3, #FFI_TYPE_STRUCT_VFP_DOUBLE
+	fstmiadeq	r2, {d0-d3}
+
+LSYM(Lepilogue_vfp):
+	RETLDM	"r0-r3,fp"
+
+.ffi_call_VFP_end:
+	UNWIND .fnend
+        .size    CNAME(ffi_call_VFP),.ffi_call_VFP_end-CNAME(ffi_call_VFP)
+
+
+ARM_FUNC_START ffi_closure_VFP
+	fstmfdd	sp!, {d0-d7}
+	@ r0-r3, then d0-d7
+	UNWIND .pad #80
+	add	ip, sp, #80
+	stmfd	sp!, {ip, lr}
+	UNWIND .save	{r0, lr}
+	add	r2, sp, #72
+	add	r3, sp, #8
+	UNWIND .pad #72
+	sub	sp, sp, #72
+	str	sp, [sp, #64]
+	add	r1, sp, #64
+	bl	ffi_closure_SYSV_inner
+
+	cmp	r0, #FFI_TYPE_INT
+	beq	.Lretint_vfp
+
+	cmp	r0, #FFI_TYPE_FLOAT
+	beq	.Lretfloat_vfp
+
+	cmp	r0, #FFI_TYPE_DOUBLE
+	cmpne	r0, #FFI_TYPE_LONGDOUBLE
+	beq	.Lretdouble_vfp
+
+	cmp	r0, #FFI_TYPE_SINT64
+	beq	.Lretlonglong_vfp
+
+	cmp	r0, #FFI_TYPE_STRUCT_VFP_FLOAT
+	beq	.Lretfloat_struct_vfp
+
+	cmp	r0, #FFI_TYPE_STRUCT_VFP_DOUBLE
+	beq	.Lretdouble_struct_vfp
+	
+.Lclosure_epilogue_vfp:
+	add	sp, sp, #72
+	ldmfd	sp, {sp, pc}
+
+.Lretfloat_vfp:
+	flds	s0, [sp]
+	b	.Lclosure_epilogue_vfp
+.Lretdouble_vfp:
+	fldd	d0, [sp]
+	b	.Lclosure_epilogue_vfp
+.Lretint_vfp:
+	ldr	r0, [sp]
+	b	.Lclosure_epilogue_vfp
+.Lretlonglong_vfp:
+	ldmia	sp, {r0, r1}
+	b	.Lclosure_epilogue_vfp
+.Lretfloat_struct_vfp:
+	fldmiad	sp, {d0-d1}
+	b	.Lclosure_epilogue_vfp
+.Lretdouble_struct_vfp:
+	fldmiad	sp, {d0-d3}
+	b	.Lclosure_epilogue_vfp
+
+.ffi_closure_VFP_end:
+	UNWIND .fnend
+        .size    CNAME(ffi_closure_VFP),.ffi_closure_VFP_end-CNAME(ffi_closure_VFP)
+
+#if defined __ELF__ && defined __linux__
+	.section	.note.GNU-stack,"",%progbits
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/arm/trampoline.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/arm/trampoline.S
new file mode 100755
index 0000000..7b47429
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/arm/trampoline.S
@@ -0,0 +1,4450 @@
+# GENERATED CODE - DO NOT EDIT
+# This file was generated by ./gentramp.sh
+
+#  Copyright (c) 2010, Plausible Labs Cooperative, Inc.
+#  
+#  Permission is hereby granted, free of charge, to any person obtaining
+#  a copy of this software and associated documentation files (the
+#  Software''), to deal in the Software without restriction, including
+#  without limitation the rights to use, copy, modify, merge, publish,
+#  distribute, sublicense, and/or sell copies of the Software, and to
+#  permit persons to whom the Software is furnished to do so, subject to
+#  the following conditions:
+#
+#  The above copyright notice and this permission notice shall be included
+#  in all copies or substantial portions of the Software.
+#
+#  THE SOFTWARE IS PROVIDED AS IS'', WITHOUT WARRANTY OF ANY KIND,
+#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+#  NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+#  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+#  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+#  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#  DEALINGS IN THE SOFTWARE.
+#  -----------------------------------------------------------------------
+
+.text
+.align 12
+.globl _ffi_closure_trampoline_table_page
+_ffi_closure_trampoline_table_page:
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
+
+    // trampoline
+    // Save to stack
+    stmfd sp!, {r0-r3}
+
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/avr32/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/avr32/ffi.c
new file mode 100755
index 0000000..3d43397
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/avr32/ffi.c
@@ -0,0 +1,423 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2011  Anthony Green
+           Copyright (c) 2009  Bradley Smith <brad at brad-smith.co.uk>
+
+   AVR32 Foreign Function Interface
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <asm/unistd.h>
+
+/* #define DEBUG */
+
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
+    unsigned int, unsigned int, unsigned int*, unsigned int,
+    void (*fn)(void));
+extern void ffi_closure_SYSV (ffi_closure *);
+
+unsigned int pass_struct_on_stack(ffi_type *type)
+{
+    if(type->type != FFI_TYPE_STRUCT)
+        return 0;
+
+    if(type->alignment < type->size &&
+        !(type->size == 4 || type->size == 8) &&
+        !(type->size == 8 && type->alignment >= 4))
+        return 1;
+
+    if(type->size == 3 || type->size == 5 || type->size == 6 ||
+        type->size == 7)
+        return 1;
+
+    return 0;
+}
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ * has been allocated for the function's arguments
+ *
+ * This is annoyingly complex since we need to keep track of used
+ * registers.
+ */
+
+void ffi_prep_args(char *stack, extended_cif *ecif)
+{
+    unsigned int i;
+    void **p_argv;
+    ffi_type **p_arg;
+    char *reg_base = stack;
+    char *stack_base = stack + 20;
+    unsigned int stack_offset = 0;
+    unsigned int reg_mask = 0;
+
+    p_argv = ecif->avalue;
+
+    /* If cif->flags is struct then we know it's not passed in registers */
+    if(ecif->cif->flags == FFI_TYPE_STRUCT)
+    {
+        *(void**)reg_base = ecif->rvalue;
+        reg_mask |= 1;
+    }
+
+    for(i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
+        i++, p_arg++)
+    {
+        size_t z = (*p_arg)->size;
+        int alignment = (*p_arg)->alignment;
+        int type = (*p_arg)->type;
+        char *addr = 0;
+
+        if(z % 4 != 0)
+            z += (4 - z % 4);
+
+        if(reg_mask != 0x1f)
+        {
+            if(pass_struct_on_stack(*p_arg))
+            {
+                addr = stack_base + stack_offset;
+                stack_offset += z;
+            }
+            else if(z == sizeof(int))
+            {
+                char index = 0;
+
+                while((reg_mask >> index) & 1)
+                    index++;
+
+                addr = reg_base + (index * 4);
+                reg_mask |= (1 << index);
+            }
+            else if(z == 2 * sizeof(int))
+            {
+                if(!((reg_mask >> 1) & 1))
+                {
+                    addr = reg_base + 4;
+                    reg_mask |= (3 << 1);
+                }
+                else if(!((reg_mask >> 3) & 1))
+                {
+                    addr = reg_base + 12;
+                    reg_mask |= (3 << 3);
+                }
+            }
+        }
+
+        if(!addr)
+        {
+            addr = stack_base + stack_offset;
+            stack_offset += z;
+        }
+
+        if(type == FFI_TYPE_STRUCT && (*p_arg)->elements[1] == NULL)
+            type = (*p_arg)->elements[0]->type;
+
+        switch(type)
+        {
+        case FFI_TYPE_UINT8:
+            *(unsigned int *)addr = (unsigned int)*(UINT8 *)(*p_argv);
+            break;
+        case FFI_TYPE_SINT8:
+            *(signed int *)addr = (signed int)*(SINT8 *)(*p_argv);
+            break;
+        case FFI_TYPE_UINT16:
+            *(unsigned int *)addr = (unsigned int)*(UINT16 *)(*p_argv);
+            break;
+        case FFI_TYPE_SINT16:
+            *(signed int *)addr = (signed int)*(SINT16 *)(*p_argv);
+            break;
+        default:
+            memcpy(addr, *p_argv, z);
+        }
+
+        p_argv++;
+    }
+
+#ifdef DEBUG
+    /* Debugging */
+    for(i = 0; i < 5; i++)
+    {
+        if((reg_mask & (1 << i)) == 0)
+            printf("r%d: (unused)\n", 12 - i);
+        else
+            printf("r%d: 0x%08x\n", 12 - i, ((unsigned int*)reg_base)[i]);
+    }
+
+    for(i = 0; i < stack_offset / 4; i++)
+    {
+        printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack_base)[i]);
+    }
+#endif
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+    /* Round the stack up to a multiple of 8 bytes.  This isn't needed
+     * everywhere, but it is on some platforms, and it doesn't harm
+     * anything when it isn't needed. */
+    cif->bytes = (cif->bytes + 7) & ~7;
+
+    /* Flag to indicate that he return value is in fact a struct */
+    cif->rstruct_flag = 0;
+
+    /* Set the return type flag */
+    switch(cif->rtype->type)
+    {
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_UINT8:
+        cif->flags = (unsigned)FFI_TYPE_UINT8;
+        break;
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_UINT16:
+        cif->flags = (unsigned)FFI_TYPE_UINT16;
+        break;
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_UINT32:
+    case FFI_TYPE_POINTER:
+        cif->flags = (unsigned)FFI_TYPE_UINT32;
+        break;
+    case FFI_TYPE_DOUBLE:
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+        cif->flags = (unsigned)FFI_TYPE_UINT64;
+        break;
+    case FFI_TYPE_STRUCT:
+        cif->rstruct_flag = 1;
+        if(!pass_struct_on_stack(cif->rtype))
+        {
+            if(cif->rtype->size <= 1)
+                cif->flags = (unsigned)FFI_TYPE_UINT8;
+            else if(cif->rtype->size <= 2)
+                cif->flags = (unsigned)FFI_TYPE_UINT16;
+            else if(cif->rtype->size <= 4)
+                cif->flags = (unsigned)FFI_TYPE_UINT32;
+            else if(cif->rtype->size <= 8)
+                cif->flags = (unsigned)FFI_TYPE_UINT64;
+            else
+                cif->flags = (unsigned)cif->rtype->type;
+        }
+        else
+            cif->flags = (unsigned)cif->rtype->type;
+        break;
+    default:
+        cif->flags = (unsigned)cif->rtype->type;
+        break;
+    }
+
+    return FFI_OK;
+}
+
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+    extended_cif ecif;
+
+    unsigned int size = 0, i = 0;
+    ffi_type **p_arg;
+
+    ecif.cif = cif;
+    ecif.avalue = avalue;
+
+    for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
+        size += (*p_arg)->size + (4 - (*p_arg)->size % 4);
+
+    /* If the return value is a struct and we don't have a return value
+     * address then we need to make one */
+
+    /* If cif->flags is struct then it's not suitable for registers */
+    if((rvalue == NULL) && (cif->flags == FFI_TYPE_STRUCT))
+        ecif.rvalue = alloca(cif->rtype->size);
+    else
+        ecif.rvalue = rvalue;
+
+    switch(cif->abi)
+    {
+    case FFI_SYSV:
+        ffi_call_SYSV(ffi_prep_args, &ecif, size, cif->flags,
+            ecif.rvalue, cif->rstruct_flag, fn);
+        break;
+    default:
+        FFI_ASSERT(0);
+        break;
+    }
+}
+
+static void ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+    void **avalue, ffi_cif *cif)
+{
+    register unsigned int i, reg_mask = 0;
+    register void **p_argv;
+    register ffi_type **p_arg;
+    register char *reg_base = stack;
+    register char *stack_base = stack + 20;
+    register unsigned int stack_offset = 0;
+
+#ifdef DEBUG
+    /* Debugging */
+    for(i = 0; i < cif->nargs + 7; i++)
+    {
+        printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack)[i]);
+    }
+#endif
+
+    /* If cif->flags is struct then we know it's not passed in registers */
+    if(cif->flags == FFI_TYPE_STRUCT)
+    {
+        *rvalue = *(void **)reg_base;
+        reg_mask |= 1;
+    }
+
+    p_argv = avalue;
+
+    for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
+    {
+        size_t z = (*p_arg)->size;
+        int alignment = (*p_arg)->alignment;
+
+        *p_argv = 0;
+
+        if(z % 4 != 0)
+            z += (4 - z % 4);
+
+        if(reg_mask != 0x1f)
+        {
+            if(pass_struct_on_stack(*p_arg))
+            {
+                *p_argv = (void*)stack_base + stack_offset;
+                stack_offset += z;
+            }
+            else if(z <= sizeof(int))
+            {
+                char index = 0;
+
+                while((reg_mask >> index) & 1)
+                    index++;
+
+                *p_argv = (void*)reg_base + (index * 4);
+                reg_mask |= (1 << index);
+            }
+            else if(z == 2 * sizeof(int))
+            {
+                if(!((reg_mask >> 1) & 1))
+                {
+                    *p_argv = (void*)reg_base + 4;
+                    reg_mask |= (3 << 1);
+                }
+                else if(!((reg_mask >> 3) & 1))
+                {
+                    *p_argv = (void*)reg_base + 12;
+                    reg_mask |= (3 << 3);
+                }
+            }
+        }
+
+        if(!*p_argv)
+        {
+            *p_argv = (void*)stack_base + stack_offset;
+            stack_offset += z;
+        }
+
+        if((*p_arg)->type != FFI_TYPE_STRUCT ||
+            (*p_arg)->elements[1] == NULL)
+        {
+            if(alignment == 1)
+                **(unsigned int**)p_argv <<= 24;
+            else if(alignment == 2)
+                **(unsigned int**)p_argv <<= 16;
+        }
+
+        p_argv++;
+    }
+
+#ifdef DEBUG
+    /* Debugging */
+    for(i = 0; i < cif->nargs; i++)
+    {
+        printf("sp+%d: 0x%08x\n", i*4, *(((unsigned int**)avalue)[i]));
+    }
+#endif
+}
+
+/* This function is jumped to by the trampoline */
+
+unsigned int ffi_closure_SYSV_inner(ffi_closure *closure, void **respp,
+    void *args)
+{
+    ffi_cif *cif;
+    void **arg_area;
+    unsigned int i, size = 0;
+    ffi_type **p_arg;
+
+    cif = closure->cif;
+
+    for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
+        size += (*p_arg)->size + (4 - (*p_arg)->size % 4);
+
+    arg_area = (void **)alloca(size);
+
+    /* this call will initialize ARG_AREA, such that each element in that
+     * array points to the corresponding value on the stack; and if the
+     * function returns a structure, it will re-set RESP to point to the
+     * structure return address. */
+
+    ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
+
+    (closure->fun)(cif, *respp, arg_area, closure->user_data);
+
+    return cif->flags;
+}
+
+ffi_status ffi_prep_closure_loc(ffi_closure* closure, ffi_cif* cif,
+    void (*fun)(ffi_cif*, void*, void**, void*), void *user_data,
+    void *codeloc)
+{
+    if (cif->abi != FFI_SYSV)
+      return FFI_BAD_ABI;
+
+    unsigned char *__tramp = (unsigned char*)(&closure->tramp[0]);
+    unsigned int  __fun = (unsigned int)(&ffi_closure_SYSV);
+    unsigned int  __ctx = (unsigned int)(codeloc);
+    unsigned int  __rstruct_flag = (unsigned int)(cif->rstruct_flag);
+    unsigned int  __inner = (unsigned int)(&ffi_closure_SYSV_inner);
+    *(unsigned int*) &__tramp[0] = 0xebcd1f00;    /* pushm  r8-r12 */
+    *(unsigned int*) &__tramp[4] = 0xfefc0010;    /* ld.w   r12, pc[16] */
+    *(unsigned int*) &__tramp[8] = 0xfefb0010;    /* ld.w   r11, pc[16] */
+    *(unsigned int*) &__tramp[12] = 0xfefa0010;   /* ld.w   r10, pc[16] */
+    *(unsigned int*) &__tramp[16] = 0xfeff0010;   /* ld.w   pc, pc[16] */
+    *(unsigned int*) &__tramp[20] = __ctx;
+    *(unsigned int*) &__tramp[24] = __rstruct_flag;
+    *(unsigned int*) &__tramp[28] = __inner;
+    *(unsigned int*) &__tramp[32] = __fun;
+    syscall(__NR_cacheflush, 0, (&__tramp[0]), 36);
+
+    closure->cif = cif;
+    closure->user_data = user_data;
+    closure->fun  = fun;
+
+    return FFI_OK;
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/avr32/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/avr32/ffitarget.h
new file mode 100755
index 0000000..b85d062
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/avr32/ffitarget.h
@@ -0,0 +1,50 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 2009  Bradley Smith <brad at brad-smith.co.uk>
+   Target configuration macros for AVR32.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_SYSV
+} ffi_abi;
+#endif
+
+#define FFI_EXTRA_CIF_FIELDS unsigned int rstruct_flag
+
+/* Definitions for closures */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 36
+#define FFI_NATIVE_RAW_API 0
+
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/avr32/sysv.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/avr32/sysv.S
new file mode 100755
index 0000000..a984b3c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/avr32/sysv.S
@@ -0,0 +1,208 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2009  Bradley Smith <brad at brad-smith.co.uk>
+
+   AVR32 Foreign Function Interface
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+   --------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+    /* r12:  ffi_prep_args
+     * r11:  &ecif
+     * r10:  size
+     * r9:   cif->flags
+     * r8:   ecif.rvalue
+     * sp+0: cif->rstruct_flag
+     * sp+4: fn */
+
+    .text
+    .align  1
+    .globl  ffi_call_SYSV
+    .type   ffi_call_SYSV, @function
+ffi_call_SYSV:
+    stm     --sp, r0,r1,lr
+    stm     --sp, r8-r12
+    mov     r0, sp
+
+    /* Make room for all of the new args. */
+    sub     sp, r10
+    /* Pad to make way for potential skipped registers */
+    sub     sp, 20
+
+    /* Call ffi_prep_args(stack, &ecif). */
+    /* r11 already set */
+    mov     r1, r12
+    mov     r12, sp
+    icall   r1
+
+    /* Save new argument size */
+    mov     r1, r12
+
+    /* Move first 5 parameters in registers. */
+    ldm     sp++, r8-r12
+
+    /* call (fn) (...). */
+    ld.w    r1, r0[36]
+    icall   r1
+
+    /* Remove the space we pushed for the args. */
+    mov     sp, r0
+
+    /* Load r1 with the rstruct flag. */
+    ld.w    r1, sp[32]
+
+    /* Load r9 with the return type code. */
+    ld.w    r9, sp[12]
+
+    /* Load r8 with the return value pointer. */
+    ld.w    r8, sp[16]
+
+    /* If the return value pointer is NULL, assume no return value. */
+    cp.w    r8, 0
+    breq    .Lend
+
+    /* Check if return type is actually a struct */
+    cp.w    r1, 0
+    breq    1f
+
+    /* Return 8bit */
+    cp.w    r9, FFI_TYPE_UINT8
+    breq    .Lstore8
+
+    /* Return 16bit */
+    cp.w    r9, FFI_TYPE_UINT16
+    breq    .Lstore16
+
+1:
+    /* Return 32bit */
+    cp.w    r9, FFI_TYPE_UINT32
+    breq    .Lstore32
+    cp.w    r9, FFI_TYPE_UINT16
+    breq    .Lstore32
+    cp.w    r9, FFI_TYPE_UINT8
+    breq    .Lstore32
+
+    /* Return 64bit */
+    cp.w    r9, FFI_TYPE_UINT64
+    breq    .Lstore64
+
+    /* Didn't match anything */
+    bral    .Lend
+
+.Lstore64:
+    st.w    r8[0], r11
+    st.w    r8[4], r10
+    bral    .Lend
+
+.Lstore32:
+    st.w    r8[0], r12
+    bral    .Lend
+
+.Lstore16:
+    st.h    r8[0], r12
+    bral    .Lend
+
+.Lstore8:
+    st.b    r8[0], r12
+    bral    .Lend
+
+.Lend:
+    sub     sp, -20
+    ldm     sp++, r0,r1,pc
+
+    .size   ffi_call_SYSV, . - ffi_call_SYSV
+
+
+    /* r12:  __ctx
+     * r11:  __rstruct_flag
+     * r10:  __inner */
+
+    .align  1
+    .globl  ffi_closure_SYSV
+    .type   ffi_closure_SYSV, @function
+ffi_closure_SYSV:
+    stm     --sp, r0,lr
+    mov     r0, r11
+    mov     r8, r10
+    sub     r10, sp, -8
+    sub     sp, 12
+    st.w    sp[8], sp
+    sub     r11, sp, -8
+    icall   r8
+
+    /* Check if return type is actually a struct */
+    cp.w    r0, 0
+    breq    1f
+
+    /* Return 8bit */
+    cp.w    r12, FFI_TYPE_UINT8
+    breq    .Lget8
+
+    /* Return 16bit */
+    cp.w    r12, FFI_TYPE_UINT16
+    breq    .Lget16
+
+1:
+    /* Return 32bit */
+    cp.w    r12, FFI_TYPE_UINT32
+    breq    .Lget32
+    cp.w    r12, FFI_TYPE_UINT16
+    breq    .Lget32
+    cp.w    r12, FFI_TYPE_UINT8
+    breq    .Lget32
+
+    /* Return 64bit */
+    cp.w    r12, FFI_TYPE_UINT64
+    breq    .Lget64
+
+    /* Didn't match anything */
+    bral    .Lclend
+
+.Lget64:
+    ld.w    r11, sp[0]
+    ld.w    r10, sp[4]
+    bral    .Lclend
+
+.Lget32:
+    ld.w    r12, sp[0]
+    bral    .Lclend
+
+.Lget16:
+    ld.uh   r12, sp[0]
+    bral    .Lclend
+
+.Lget8:
+    ld.ub   r12, sp[0]
+    bral    .Lclend
+
+.Lclend:
+    sub     sp, -12
+    ldm     sp++, r0,lr
+    sub     sp, -20
+    mov     pc, lr
+
+    .size   ffi_closure_SYSV, . - ffi_closure_SYSV
+
+#if defined __ELF__ && defined __linux__
+    .section    .note.GNU-stack,"", at progbits
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/closures.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/closures.c
new file mode 100755
index 0000000..1b37827
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/closures.c
@@ -0,0 +1,615 @@
+/* -----------------------------------------------------------------------
+   closures.c - Copyright (c) 2007, 2009, 2010  Red Hat, Inc.
+                Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc
+                Copyright (c) 2011 Plausible Labs Cooperative, Inc.
+
+   Code to allocate and deallocate memory for closures.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#if defined __linux__ && !defined _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE
+# if __gnu_linux__
+/* This macro indicates it may be forbidden to map anonymous memory
+   with both write and execute permission.  Code compiled when this
+   option is defined will attempt to map such pages once, but if it
+   fails, it falls back to creating a temporary file in a writable and
+   executable filesystem and mapping pages from it into separate
+   locations in the virtual memory space, one location writable and
+   another executable.  */
+#  define FFI_MMAP_EXEC_WRIT 1
+#  define HAVE_MNTENT 1
+# endif
+# if defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)
+/* Windows systems may have Data Execution Protection (DEP) enabled, 
+   which requires the use of VirtualMalloc/VirtualFree to alloc/free
+   executable memory. */
+#  define FFI_MMAP_EXEC_WRIT 1
+# endif
+#endif
+
+#if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX
+# ifdef __linux__
+/* When defined to 1 check for SELinux and if SELinux is active,
+   don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that
+   might cause audit messages.  */
+#  define FFI_MMAP_EXEC_SELINUX 1
+# endif
+#endif
+
+#if FFI_CLOSURES
+
+# if FFI_EXEC_TRAMPOLINE_TABLE
+
+// Per-target implementation; It's unclear what can reasonable be shared between two OS/architecture implementations.
+
+# elif FFI_MMAP_EXEC_WRIT /* !FFI_EXEC_TRAMPOLINE_TABLE */
+
+#define USE_LOCKS 1
+#define USE_DL_PREFIX 1
+#ifdef __GNUC__
+#ifndef USE_BUILTIN_FFS
+#define USE_BUILTIN_FFS 1
+#endif
+#endif
+
+/* We need to use mmap, not sbrk.  */
+#define HAVE_MORECORE 0
+
+/* We could, in theory, support mremap, but it wouldn't buy us anything.  */
+#define HAVE_MREMAP 0
+
+/* We have no use for this, so save some code and data.  */
+#define NO_MALLINFO 1
+
+/* We need all allocations to be in regular segments, otherwise we
+   lose track of the corresponding code address.  */
+#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
+
+/* Don't allocate more than a page unless needed.  */
+#define DEFAULT_GRANULARITY ((size_t)malloc_getpagesize)
+
+#if FFI_CLOSURE_TEST
+/* Don't release single pages, to avoid a worst-case scenario of
+   continuously allocating and releasing single pages, but release
+   pairs of pages, which should do just as well given that allocations
+   are likely to be small.  */
+#define DEFAULT_TRIM_THRESHOLD ((size_t)malloc_getpagesize)
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <stdio.h>
+#if !defined(X86_WIN32) && !defined(X86_WIN64)
+#ifdef HAVE_MNTENT
+#include <mntent.h>
+#endif /* HAVE_MNTENT */
+#include <sys/param.h>
+#include <pthread.h>
+
+/* We don't want sys/mman.h to be included after we redefine mmap and
+   dlmunmap.  */
+#include <sys/mman.h>
+#define LACKS_SYS_MMAN_H 1
+
+#if FFI_MMAP_EXEC_SELINUX
+#include <sys/statfs.h>
+#include <stdlib.h>
+
+static int selinux_enabled = -1;
+
+static int
+selinux_enabled_check (void)
+{
+  struct statfs sfs;
+  FILE *f;
+  char *buf = NULL;
+  size_t len = 0;
+
+  if (statfs ("/selinux", &sfs) >= 0
+      && (unsigned int) sfs.f_type == 0xf97cff8cU)
+    return 1;
+  f = fopen ("/proc/mounts", "r");
+  if (f == NULL)
+    return 0;
+  while (getline (&buf, &len, f) >= 0)
+    {
+      char *p = strchr (buf, ' ');
+      if (p == NULL)
+        break;
+      p = strchr (p + 1, ' ');
+      if (p == NULL)
+        break;
+      if (strncmp (p + 1, "selinuxfs ", 10) == 0)
+        {
+          free (buf);
+          fclose (f);
+          return 1;
+        }
+    }
+  free (buf);
+  fclose (f);
+  return 0;
+}
+
+#define is_selinux_enabled() (selinux_enabled >= 0 ? selinux_enabled \
+			      : (selinux_enabled = selinux_enabled_check ()))
+
+#else
+
+#define is_selinux_enabled() 0
+
+#endif /* !FFI_MMAP_EXEC_SELINUX */
+
+#elif defined (__CYGWIN__) || defined(__INTERIX)
+
+#include <sys/mman.h>
+
+/* Cygwin is Linux-like, but not quite that Linux-like.  */
+#define is_selinux_enabled() 0
+
+#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
+
+/* Declare all functions defined in dlmalloc.c as static.  */
+static void *dlmalloc(size_t);
+static void dlfree(void*);
+static void *dlcalloc(size_t, size_t) MAYBE_UNUSED;
+static void *dlrealloc(void *, size_t) MAYBE_UNUSED;
+static void *dlmemalign(size_t, size_t) MAYBE_UNUSED;
+static void *dlvalloc(size_t) MAYBE_UNUSED;
+static int dlmallopt(int, int) MAYBE_UNUSED;
+static size_t dlmalloc_footprint(void) MAYBE_UNUSED;
+static size_t dlmalloc_max_footprint(void) MAYBE_UNUSED;
+static void** dlindependent_calloc(size_t, size_t, void**) MAYBE_UNUSED;
+static void** dlindependent_comalloc(size_t, size_t*, void**) MAYBE_UNUSED;
+static void *dlpvalloc(size_t) MAYBE_UNUSED;
+static int dlmalloc_trim(size_t) MAYBE_UNUSED;
+static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
+static void dlmalloc_stats(void) MAYBE_UNUSED;
+
+#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
+/* Use these for mmap and munmap within dlmalloc.c.  */
+static void *dlmmap(void *, size_t, int, int, int, off_t);
+static int dlmunmap(void *, size_t);
+#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
+
+#define mmap dlmmap
+#define munmap dlmunmap
+
+#include "dlmalloc.c"
+
+#undef mmap
+#undef munmap
+
+#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
+
+/* A mutex used to synchronize access to *exec* variables in this file.  */
+static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/* A file descriptor of a temporary file from which we'll map
+   executable pages.  */
+static int execfd = -1;
+
+/* The amount of space already allocated from the temporary file.  */
+static size_t execsize = 0;
+
+/* Open a temporary file name, and immediately unlink it.  */
+static int
+open_temp_exec_file_name (char *name)
+{
+  int fd = mkstemp (name);
+
+  if (fd != -1)
+    unlink (name);
+
+  return fd;
+}
+
+/* Open a temporary file in the named directory.  */
+static int
+open_temp_exec_file_dir (const char *dir)
+{
+  static const char suffix[] = "/ffiXXXXXX";
+  int lendir = strlen (dir);
+  char *tempname = __builtin_alloca (lendir + sizeof (suffix));
+
+  if (!tempname)
+    return -1;
+
+  memcpy (tempname, dir, lendir);
+  memcpy (tempname + lendir, suffix, sizeof (suffix));
+
+  return open_temp_exec_file_name (tempname);
+}
+
+/* Open a temporary file in the directory in the named environment
+   variable.  */
+static int
+open_temp_exec_file_env (const char *envvar)
+{
+  const char *value = getenv (envvar);
+
+  if (!value)
+    return -1;
+
+  return open_temp_exec_file_dir (value);
+}
+
+#ifdef HAVE_MNTENT
+/* Open a temporary file in an executable and writable mount point
+   listed in the mounts file.  Subsequent calls with the same mounts
+   keep searching for mount points in the same file.  Providing NULL
+   as the mounts file closes the file.  */
+static int
+open_temp_exec_file_mnt (const char *mounts)
+{
+  static const char *last_mounts;
+  static FILE *last_mntent;
+
+  if (mounts != last_mounts)
+    {
+      if (last_mntent)
+	endmntent (last_mntent);
+
+      last_mounts = mounts;
+
+      if (mounts)
+	last_mntent = setmntent (mounts, "r");
+      else
+	last_mntent = NULL;
+    }
+
+  if (!last_mntent)
+    return -1;
+
+  for (;;)
+    {
+      int fd;
+      struct mntent mnt;
+      char buf[MAXPATHLEN * 3];
+
+      if (getmntent_r (last_mntent, &mnt, buf, sizeof (buf)) == NULL)
+	return -1;
+
+      if (hasmntopt (&mnt, "ro")
+	  || hasmntopt (&mnt, "noexec")
+	  || access (mnt.mnt_dir, W_OK))
+	continue;
+
+      fd = open_temp_exec_file_dir (mnt.mnt_dir);
+
+      if (fd != -1)
+	return fd;
+    }
+}
+#endif /* HAVE_MNTENT */
+
+/* Instructions to look for a location to hold a temporary file that
+   can be mapped in for execution.  */
+static struct
+{
+  int (*func)(const char *);
+  const char *arg;
+  int repeat;
+} open_temp_exec_file_opts[] = {
+  { open_temp_exec_file_env, "TMPDIR", 0 },
+  { open_temp_exec_file_dir, "/tmp", 0 },
+  { open_temp_exec_file_dir, "/var/tmp", 0 },
+  { open_temp_exec_file_dir, "/dev/shm", 0 },
+  { open_temp_exec_file_env, "HOME", 0 },
+#ifdef HAVE_MNTENT
+  { open_temp_exec_file_mnt, "/etc/mtab", 1 },
+  { open_temp_exec_file_mnt, "/proc/mounts", 1 },
+#endif /* HAVE_MNTENT */
+};
+
+/* Current index into open_temp_exec_file_opts.  */
+static int open_temp_exec_file_opts_idx = 0;
+
+/* Reset a current multi-call func, then advances to the next entry.
+   If we're at the last, go back to the first and return nonzero,
+   otherwise return zero.  */
+static int
+open_temp_exec_file_opts_next (void)
+{
+  if (open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)
+    open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func (NULL);
+
+  open_temp_exec_file_opts_idx++;
+  if (open_temp_exec_file_opts_idx
+      == (sizeof (open_temp_exec_file_opts)
+	  / sizeof (*open_temp_exec_file_opts)))
+    {
+      open_temp_exec_file_opts_idx = 0;
+      return 1;
+    }
+
+  return 0;
+}
+
+/* Return a file descriptor of a temporary zero-sized file in a
+   writable and exexutable filesystem.  */
+static int
+open_temp_exec_file (void)
+{
+  int fd;
+
+  do
+    {
+      fd = open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func
+	(open_temp_exec_file_opts[open_temp_exec_file_opts_idx].arg);
+
+      if (!open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat
+	  || fd == -1)
+	{
+	  if (open_temp_exec_file_opts_next ())
+	    break;
+	}
+    }
+  while (fd == -1);
+
+  return fd;
+}
+
+/* Map in a chunk of memory from the temporary exec file into separate
+   locations in the virtual memory address space, one writable and one
+   executable.  Returns the address of the writable portion, after
+   storing an offset to the corresponding executable portion at the
+   last word of the requested chunk.  */
+static void *
+dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)
+{
+  void *ptr;
+
+  if (execfd == -1)
+    {
+      open_temp_exec_file_opts_idx = 0;
+    retry_open:
+      execfd = open_temp_exec_file ();
+      if (execfd == -1)
+	return MFAIL;
+    }
+
+  offset = execsize;
+
+  if (ftruncate (execfd, offset + length))
+    return MFAIL;
+
+  flags &= ~(MAP_PRIVATE | MAP_ANONYMOUS);
+  flags |= MAP_SHARED;
+
+  ptr = mmap (NULL, length, (prot & ~PROT_WRITE) | PROT_EXEC,
+	      flags, execfd, offset);
+  if (ptr == MFAIL)
+    {
+      if (!offset)
+	{
+	  close (execfd);
+	  goto retry_open;
+	}
+      ftruncate (execfd, offset);
+      return MFAIL;
+    }
+  else if (!offset
+	   && open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)
+    open_temp_exec_file_opts_next ();
+
+  start = mmap (start, length, prot, flags, execfd, offset);
+
+  if (start == MFAIL)
+    {
+      munmap (ptr, length);
+      ftruncate (execfd, offset);
+      return start;
+    }
+
+  mmap_exec_offset ((char *)start, length) = (char*)ptr - (char*)start;
+
+  execsize += length;
+
+  return start;
+}
+
+/* Map in a writable and executable chunk of memory if possible.
+   Failing that, fall back to dlmmap_locked.  */
+static void *
+dlmmap (void *start, size_t length, int prot,
+	int flags, int fd, off_t offset)
+{
+  void *ptr;
+
+  assert (start == NULL && length % malloc_getpagesize == 0
+	  && prot == (PROT_READ | PROT_WRITE)
+	  && flags == (MAP_PRIVATE | MAP_ANONYMOUS)
+	  && fd == -1 && offset == 0);
+
+#if FFI_CLOSURE_TEST
+  printf ("mapping in %zi\n", length);
+#endif
+
+  if (execfd == -1 && !is_selinux_enabled ())
+    {
+      ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
+
+      if (ptr != MFAIL || (errno != EPERM && errno != EACCES))
+	/* Cool, no need to mess with separate segments.  */
+	return ptr;
+
+      /* If MREMAP_DUP is ever introduced and implemented, try mmap
+	 with ((prot & ~PROT_WRITE) | PROT_EXEC) and mremap with
+	 MREMAP_DUP and prot at this point.  */
+    }
+
+  if (execsize == 0 || execfd == -1)
+    {
+      pthread_mutex_lock (&open_temp_exec_file_mutex);
+      ptr = dlmmap_locked (start, length, prot, flags, offset);
+      pthread_mutex_unlock (&open_temp_exec_file_mutex);
+
+      return ptr;
+    }
+
+  return dlmmap_locked (start, length, prot, flags, offset);
+}
+
+/* Release memory at the given address, as well as the corresponding
+   executable page if it's separate.  */
+static int
+dlmunmap (void *start, size_t length)
+{
+  /* We don't bother decreasing execsize or truncating the file, since
+     we can't quite tell whether we're unmapping the end of the file.
+     We don't expect frequent deallocation anyway.  If we did, we
+     could locate pages in the file by writing to the pages being
+     deallocated and checking that the file contents change.
+     Yuck.  */
+  msegmentptr seg = segment_holding (gm, start);
+  void *code;
+
+#if FFI_CLOSURE_TEST
+  printf ("unmapping %zi\n", length);
+#endif
+
+  if (seg && (code = add_segment_exec_offset (start, seg)) != start)
+    {
+      int ret = munmap (code, length);
+      if (ret)
+	return ret;
+    }
+
+  return munmap (start, length);
+}
+
+#if FFI_CLOSURE_FREE_CODE
+/* Return segment holding given code address.  */
+static msegmentptr
+segment_holding_code (mstate m, char* addr)
+{
+  msegmentptr sp = &m->seg;
+  for (;;) {
+    if (addr >= add_segment_exec_offset (sp->base, sp)
+	&& addr < add_segment_exec_offset (sp->base, sp) + sp->size)
+      return sp;
+    if ((sp = sp->next) == 0)
+      return 0;
+  }
+}
+#endif
+
+#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
+
+/* Allocate a chunk of memory with the given size.  Returns a pointer
+   to the writable address, and sets *CODE to the executable
+   corresponding virtual address.  */
+void *
+ffi_closure_alloc (size_t size, void **code)
+{
+  void *ptr;
+
+  if (!code)
+    return NULL;
+
+  ptr = dlmalloc (size);
+
+  if (ptr)
+    {
+      msegmentptr seg = segment_holding (gm, ptr);
+
+      *code = add_segment_exec_offset (ptr, seg);
+    }
+
+  return ptr;
+}
+
+/* Release a chunk of memory allocated with ffi_closure_alloc.  If
+   FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the
+   writable or the executable address given.  Otherwise, only the
+   writable address can be provided here.  */
+void
+ffi_closure_free (void *ptr)
+{
+#if FFI_CLOSURE_FREE_CODE
+  msegmentptr seg = segment_holding_code (gm, ptr);
+
+  if (seg)
+    ptr = sub_segment_exec_offset (ptr, seg);
+#endif
+
+  dlfree (ptr);
+}
+
+
+#if FFI_CLOSURE_TEST
+/* Do some internal sanity testing to make sure allocation and
+   deallocation of pages are working as intended.  */
+int main ()
+{
+  void *p[3];
+#define GET(idx, len) do { p[idx] = dlmalloc (len); printf ("allocated %zi for p[%i]\n", (len), (idx)); } while (0)
+#define PUT(idx) do { printf ("freeing p[%i]\n", (idx)); dlfree (p[idx]); } while (0)
+  GET (0, malloc_getpagesize / 2);
+  GET (1, 2 * malloc_getpagesize - 64 * sizeof (void*));
+  PUT (1);
+  GET (1, 2 * malloc_getpagesize);
+  GET (2, malloc_getpagesize / 2);
+  PUT (1);
+  PUT (0);
+  PUT (2);
+  return 0;
+}
+#endif /* FFI_CLOSURE_TEST */
+# else /* ! FFI_MMAP_EXEC_WRIT */
+
+/* On many systems, memory returned by malloc is writable and
+   executable, so just use it.  */
+
+#include <stdlib.h>
+
+void *
+ffi_closure_alloc (size_t size, void **code)
+{
+  if (!code)
+    return NULL;
+
+  return *code = malloc (size);
+}
+
+void
+ffi_closure_free (void *ptr)
+{
+  free (ptr);
+}
+
+# endif /* ! FFI_MMAP_EXEC_WRIT */
+#endif /* FFI_CLOSURES */
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/cris/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/cris/ffi.c
new file mode 100755
index 0000000..f25d7b4
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/cris/ffi.c
@@ -0,0 +1,383 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 1998 Cygnus Solutions
+           Copyright (c) 2004 Simon Posnjak
+	   Copyright (c) 2005 Axis Communications AB
+	   Copyright (C) 2007 Free Software Foundation, Inc.
+
+   CRIS Foreign Function Interface
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
+
+static ffi_status
+initialize_aggregate_packed_struct (ffi_type * arg)
+{
+  ffi_type **ptr;
+
+  FFI_ASSERT (arg != NULL);
+
+  FFI_ASSERT (arg->elements != NULL);
+  FFI_ASSERT (arg->size == 0);
+  FFI_ASSERT (arg->alignment == 0);
+
+  ptr = &(arg->elements[0]);
+
+  while ((*ptr) != NULL)
+    {
+      if (((*ptr)->size == 0)
+	  && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
+	return FFI_BAD_TYPEDEF;
+
+      FFI_ASSERT (ffi_type_test ((*ptr)));
+
+      arg->size += (*ptr)->size;
+
+      arg->alignment = (arg->alignment > (*ptr)->alignment) ?
+	arg->alignment : (*ptr)->alignment;
+
+      ptr++;
+    }
+
+  if (arg->size == 0)
+    return FFI_BAD_TYPEDEF;
+  else
+    return FFI_OK;
+}
+
+int
+ffi_prep_args (char *stack, extended_cif * ecif)
+{
+  unsigned int i;
+  unsigned int struct_count = 0;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+  argp = stack;
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       (i != 0); i--, p_arg++)
+    {
+      size_t z;
+
+      switch ((*p_arg)->type)
+	{
+	case FFI_TYPE_STRUCT:
+	  {
+	    z = (*p_arg)->size;
+	    if (z <= 4)
+	      {
+		memcpy (argp, *p_argv, z);
+		z = 4;
+	      }
+	    else if (z <= 8)
+	      {
+		memcpy (argp, *p_argv, z);
+		z = 8;
+	      }
+	    else
+	      {
+		unsigned int uiLocOnStack;
+		z = sizeof (void *);
+		uiLocOnStack = 4 * ecif->cif->nargs + struct_count;
+		struct_count = struct_count + (*p_arg)->size;
+		*(unsigned int *) argp =
+		  (unsigned int) (UINT32 *) (stack + uiLocOnStack);
+		memcpy ((stack + uiLocOnStack), *p_argv, (*p_arg)->size);
+	      }
+	    break;
+	  }
+	default:
+	  z = (*p_arg)->size;
+	  if (z < sizeof (int))
+	    {
+	      switch ((*p_arg)->type)
+		{
+		case FFI_TYPE_SINT8:
+		  *(signed int *) argp = (signed int) *(SINT8 *) (*p_argv);
+		  break;
+
+		case FFI_TYPE_UINT8:
+		  *(unsigned int *) argp =
+		    (unsigned int) *(UINT8 *) (*p_argv);
+		  break;
+
+		case FFI_TYPE_SINT16:
+		  *(signed int *) argp = (signed int) *(SINT16 *) (*p_argv);
+		  break;
+
+		case FFI_TYPE_UINT16:
+		  *(unsigned int *) argp =
+		    (unsigned int) *(UINT16 *) (*p_argv);
+		  break;
+
+		default:
+		  FFI_ASSERT (0);
+		}
+	      z = sizeof (int);
+	    }
+	  else if (z == sizeof (int))
+	    *(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv);
+	  else
+	    memcpy (argp, *p_argv, z);
+	  break;
+	}
+      p_argv++;
+      argp += z;
+    }
+
+  return (struct_count);
+}
+
+ffi_status
+ffi_prep_cif (ffi_cif * cif,
+	      ffi_abi abi, unsigned int nargs,
+	      ffi_type * rtype, ffi_type ** atypes)
+{
+  unsigned bytes = 0;
+  unsigned int i;
+  ffi_type **ptr;
+
+  FFI_ASSERT (cif != NULL);
+  FFI_ASSERT (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI);
+
+  cif->abi = abi;
+  cif->arg_types = atypes;
+  cif->nargs = nargs;
+  cif->rtype = rtype;
+
+  cif->flags = 0;
+
+  if ((cif->rtype->size == 0)
+      && (initialize_aggregate_packed_struct (cif->rtype) != FFI_OK))
+    return FFI_BAD_TYPEDEF;
+
+  FFI_ASSERT_VALID_TYPE (cif->rtype);
+
+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+    {
+      if (((*ptr)->size == 0)
+	  && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
+	return FFI_BAD_TYPEDEF;
+
+      FFI_ASSERT_VALID_TYPE (*ptr);
+
+      if (((*ptr)->alignment - 1) & bytes)
+	bytes = ALIGN (bytes, (*ptr)->alignment);
+      if ((*ptr)->type == FFI_TYPE_STRUCT)
+	{
+	  if ((*ptr)->size > 8)
+	    {
+	      bytes += (*ptr)->size;
+	      bytes += sizeof (void *);
+	    }
+	  else
+	    {
+	      if ((*ptr)->size > 4)
+		bytes += 8;
+	      else
+		bytes += 4;
+	    }
+	}
+      else
+	bytes += STACK_ARG_SIZE ((*ptr)->size);
+    }
+
+  cif->bytes = bytes;
+
+  return ffi_prep_cif_machdep (cif);
+}
+
+ffi_status
+ffi_prep_cif_machdep (ffi_cif * cif)
+{
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_STRUCT:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+extern void ffi_call_SYSV (int (*)(char *, extended_cif *),
+			   extended_cif *,
+			   unsigned, unsigned, unsigned *, void (*fn) ())
+     __attribute__ ((__visibility__ ("hidden")));
+
+void
+ffi_call (ffi_cif * cif, void (*fn) (), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+
+  if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      ecif.rvalue = alloca (cif->rtype->size);
+    }
+  else
+    ecif.rvalue = rvalue;
+
+  switch (cif->abi)
+    {
+    case FFI_SYSV:
+      ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes,
+		     cif->flags, ecif.rvalue, fn);
+      break;
+    default:
+      FFI_ASSERT (0);
+      break;
+    }
+}
+
+/* Because the following variables are not exported outside libffi, we
+   mark them hidden.  */
+
+/* Assembly code for the jump stub.  */
+extern const char ffi_cris_trampoline_template[]
+ __attribute__ ((__visibility__ ("hidden")));
+
+/* Offset into ffi_cris_trampoline_template of where to put the
+   ffi_prep_closure_inner function.  */
+extern const int ffi_cris_trampoline_fn_offset
+ __attribute__ ((__visibility__ ("hidden")));
+
+/* Offset into ffi_cris_trampoline_template of where to put the
+   closure data.  */
+extern const int ffi_cris_trampoline_closure_offset
+ __attribute__ ((__visibility__ ("hidden")));
+
+/* This function is sibling-called (jumped to) by the closure
+   trampoline.  We get R10..R13 at PARAMS[0..3] and a copy of [SP] at
+   PARAMS[4] to simplify handling of a straddling parameter.  A copy
+   of R9 is at PARAMS[5] and SP at PARAMS[6].  These parameters are
+   put at the appropriate place in CLOSURE which is then executed and
+   the return value is passed back to the caller.  */
+
+static unsigned long long
+ffi_prep_closure_inner (void **params, ffi_closure* closure)
+{
+  char *register_args = (char *) params;
+  void *struct_ret = params[5];
+  char *stack_args = params[6];
+  char *ptr = register_args;
+  ffi_cif *cif = closure->cif;
+  ffi_type **arg_types = cif->arg_types;
+
+  /* Max room needed is number of arguments as 64-bit values.  */
+  void **avalue = alloca (closure->cif->nargs * sizeof(void *));
+  int i;
+  int doing_regs;
+  long long llret = 0;
+
+  /* Find the address of each argument.  */
+  for (i = 0, doing_regs = 1; i < cif->nargs; i++)
+    {
+      /* Types up to and including 8 bytes go by-value.  */
+      if (arg_types[i]->size <= 4)
+	{
+	  avalue[i] = ptr;
+	  ptr += 4;
+	}
+      else if (arg_types[i]->size <= 8)
+	{
+	  avalue[i] = ptr;
+	  ptr += 8;
+	}
+      else
+	{
+	  FFI_ASSERT (arg_types[i]->type == FFI_TYPE_STRUCT);
+
+	  /* Passed by-reference, so copy the pointer.  */
+	  avalue[i] = *(void **) ptr;
+	  ptr += 4;
+	}
+
+      /* If we've handled more arguments than fit in registers, start
+	 looking at the those passed on the stack.  Step over the
+	 first one if we had a straddling parameter.  */
+      if (doing_regs && ptr >= register_args + 4*4)
+	{
+	  ptr = stack_args + ((ptr > register_args + 4*4) ? 4 : 0);
+	  doing_regs = 0;
+	}
+    }
+
+  /* Invoke the closure.  */
+  (closure->fun) (cif,
+
+		  cif->rtype->type == FFI_TYPE_STRUCT
+		  /* The caller allocated space for the return
+		     structure, and passed a pointer to this space in
+		     R9.  */
+		  ? struct_ret
+
+		  /* We take advantage of being able to ignore that
+		     the high part isn't set if the return value is
+		     not in R10:R11, but in R10 only.  */
+		  : (void *) &llret,
+
+		  avalue, closure->user_data);
+
+  return llret;
+}
+
+/* API function: Prepare the trampoline.  */
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif *, void *, void **, void*),
+		      void *user_data,
+		      void *codeloc)
+{
+  void *innerfn = ffi_prep_closure_inner;
+  FFI_ASSERT (cif->abi == FFI_SYSV);
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+  memcpy (closure->tramp, ffi_cris_trampoline_template,
+	  FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE);
+  memcpy (closure->tramp + ffi_cris_trampoline_fn_offset,
+	  &innerfn, sizeof (void *));
+  memcpy (closure->tramp + ffi_cris_trampoline_closure_offset,
+	  &codeloc, sizeof (void *));
+
+  return FFI_OK;
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/cris/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/cris/ffitarget.h
new file mode 100755
index 0000000..0e3705d
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/cris/ffitarget.h
@@ -0,0 +1,51 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for CRIS.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_SYSV
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE 36
+#define FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE (7*4)
+#define FFI_TRAMPOLINE_SIZE \
+ (FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE + FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE)
+#define FFI_NATIVE_RAW_API 0
+
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/cris/sysv.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/cris/sysv.S
new file mode 100755
index 0000000..79abaee
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/cris/sysv.S
@@ -0,0 +1,215 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2004 Simon Posnjak
+	    Copyright (c) 2005 Axis Communications AB
+
+   CRIS Foreign Function Interface
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <ffi.h>
+#define CONCAT(x,y) x ## y
+#define XCONCAT(x,y) CONCAT (x, y)
+#define L(x) XCONCAT (__USER_LABEL_PREFIX__, x)
+
+	.text
+
+	;; OK, when we get called we should have this (according to
+	;; AXIS ETRAX 100LX Programmer's Manual chapter 6.3).
+	;;
+	;; R10:	 ffi_prep_args (func. pointer)
+	;; R11:  &ecif
+	;; R12:  cif->bytes
+	;; R13:  fig->flags
+	;; sp+0: ecif.rvalue
+	;; sp+4: fn (function pointer to the function that we need to call)
+
+	.globl  L(ffi_call_SYSV)
+	.type   L(ffi_call_SYSV), at function
+	.hidden	L(ffi_call_SYSV)
+
+L(ffi_call_SYSV):
+	;; Save the regs to the stack.
+	push $srp
+	;; Used for stack pointer saving.
+	push $r6
+	;; Used for function address pointer.
+	push $r7
+	;; Used for stack pointer saving.
+	push $r8
+	;; We save fig->flags to stack we will need them after we
+	;; call The Function.
+	push $r13
+
+	;; Saving current stack pointer.
+	move.d $sp,$r8
+	move.d $sp,$r6
+
+	;; Move address of ffi_prep_args to r13.
+	move.d $r10,$r13
+
+	;; Make room on the stack for the args of fn.
+	sub.d  $r12,$sp
+
+	;; Function void ffi_prep_args(char *stack, extended_cif *ecif) parameters are:
+	;; 	r10 <-- stack pointer
+	;; 	r11 <-- &ecif (already there)
+	move.d $sp,$r10
+
+	;; Call the function.
+	jsr $r13
+
+	;; Save the size of the structures which are passed on stack.
+	move.d $r10,$r7
+
+	;; Move first four args in to r10..r13.
+	move.d [$sp+0],$r10
+	move.d [$sp+4],$r11
+	move.d [$sp+8],$r12
+	move.d [$sp+12],$r13
+
+	;; Adjust the stack and check if any parameters are given on stack.
+	addq 16,$sp
+	sub.d $r7,$r6
+	cmp.d $sp,$r6
+
+	bpl go_on
+	nop
+
+go_on_no_params_on_stack:
+	move.d $r6,$sp
+
+go_on:
+	;; Discover if we need to put rval address in to r9.
+	move.d [$r8+0],$r7
+	cmpq FFI_TYPE_STRUCT,$r7
+	bne call_now
+	nop
+
+	;; Move rval address to $r9.
+	move.d [$r8+20],$r9
+
+call_now:
+	;; Move address of The Function in to r7.
+	move.d [$r8+24],$r7
+
+	;; Call The Function.
+	jsr $r7
+
+	;; Reset stack.
+	move.d $r8,$sp
+
+	;; Load rval type (fig->flags) in to r13.
+	pop $r13
+
+	;; Detect rval type.
+	cmpq FFI_TYPE_VOID,$r13
+	beq epilogue
+
+	cmpq FFI_TYPE_STRUCT,$r13
+	beq epilogue
+
+	cmpq FFI_TYPE_DOUBLE,$r13
+	beq return_double_or_longlong
+
+	cmpq FFI_TYPE_UINT64,$r13
+	beq return_double_or_longlong
+
+	cmpq FFI_TYPE_SINT64,$r13
+	beq return_double_or_longlong
+	nop
+
+	;; Just return the 32 bit value.
+	ba return
+	nop
+
+return_double_or_longlong:
+	;; Load half of the rval to r10 and the other half to r11.
+	move.d [$sp+16],$r13
+	move.d $r10,[$r13]
+	addq 4,$r13
+	move.d $r11,[$r13]
+	ba epilogue
+	nop
+
+return:
+	;; Load the rval to r10.
+	move.d [$sp+16],$r13
+	move.d $r10,[$r13]
+
+epilogue:
+	pop $r8
+	pop $r7
+	pop $r6
+	Jump [$sp+]
+
+	.size   ffi_call_SYSV,.-ffi_call_SYSV
+
+/* Save R10..R13 into an array, somewhat like varargs.  Copy the next
+   argument too, to simplify handling of any straddling parameter.
+   Save R9 and SP after those.  Jump to function handling the rest.
+   Since this is a template, copied and the main function filled in by
+   the user.  */
+
+	.globl	L(ffi_cris_trampoline_template)
+	.type	L(ffi_cris_trampoline_template), at function
+	.hidden	L(ffi_cris_trampoline_template)
+
+L(ffi_cris_trampoline_template):
+0:
+	/* The value we get for "PC" is right after the prefix instruction,
+	   two bytes from the beginning, i.e. 0b+2. */
+	move.d $r10,[$pc+2f-(0b+2)]
+	move.d $pc,$r10
+1:
+	addq 2f-1b+4,$r10
+	move.d $r11,[$r10+]
+	move.d $r12,[$r10+]
+	move.d $r13,[$r10+]
+	move.d [$sp],$r11
+	move.d $r11,[$r10+]
+	move.d $r9,[$r10+]
+	move.d $sp,[$r10+]
+	subq FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE,$r10
+	move.d 0,$r11
+3:
+        jump 0
+2:
+	.size	ffi_cris_trampoline_template,.-0b
+
+/* This macro create a constant usable as "extern const int \name" in
+   C from within libffi, when \name has no prefix decoration.  */
+
+	.macro const name,value
+	.globl	\name
+	.type	\name, at object
+	.hidden	\name
+\name:
+	.dword  \value
+	.size	\name,4
+	.endm
+
+/* Constants for offsets within the trampoline.  We could do this with
+   just symbols, avoiding memory contents and memory accesses, but the
+   C usage code would look a bit stranger.  */
+
+	const L(ffi_cris_trampoline_fn_offset),2b-4-0b
+	const L(ffi_cris_trampoline_closure_offset),3b-4-0b
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/debug.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/debug.c
new file mode 100755
index 0000000..51dcfcf
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/debug.c
@@ -0,0 +1,59 @@
+/* -----------------------------------------------------------------------
+   debug.c - Copyright (c) 1996 Red Hat, Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/* General debugging routines */
+
+void ffi_stop_here(void)
+{
+  /* This function is only useful for debugging purposes.
+     Place a breakpoint on ffi_stop_here to be notified of
+     significant events. */
+}
+
+/* This function should only be called via the FFI_ASSERT() macro */
+
+void ffi_assert(char *expr, char *file, int line)
+{
+  fprintf(stderr, "ASSERTION FAILURE: %s at %s:%d\n", expr, file, line);
+  ffi_stop_here();
+  abort();
+}
+
+/* Perform a sanity check on an ffi_type structure */
+
+void ffi_type_test(ffi_type *a, char *file, int line)
+{
+  FFI_ASSERT_AT(a != NULL, file, line);
+
+  FFI_ASSERT_AT(a->type <= FFI_TYPE_LAST, file, line);
+  FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->size > 0, file, line);
+  FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->alignment > 0, file, line);
+  FFI_ASSERT_AT(a->type != FFI_TYPE_STRUCT || a->elements != NULL, file, line);
+
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/dlmalloc.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/dlmalloc.c
new file mode 100755
index 0000000..5c9f9c2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/dlmalloc.c
@@ -0,0 +1,5161 @@
+/*
+  This is a version (aka dlmalloc) of malloc/free/realloc written by
+  Doug Lea and released to the public domain, as explained at
+  http://creativecommons.org/licenses/publicdomain.  Send questions,
+  comments, complaints, performance data, etc to dl at cs.oswego.edu
+
+* Version 2.8.3 Thu Sep 22 11:16:15 2005  Doug Lea  (dl at gee)
+
+   Note: There may be an updated version of this malloc obtainable at
+           ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+         Check before installing!
+
+* Quickstart
+
+  This library is all in one file to simplify the most common usage:
+  ftp it, compile it (-O3), and link it into another program. All of
+  the compile-time options default to reasonable values for use on
+  most platforms.  You might later want to step through various
+  compile-time and dynamic tuning options.
+
+  For convenience, an include file for code using this malloc is at:
+     ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.3.h
+  You don't really need this .h file unless you call functions not
+  defined in your system include files.  The .h file contains only the
+  excerpts from this file needed for using this malloc on ANSI C/C++
+  systems, so long as you haven't changed compile-time options about
+  naming and tuning parameters.  If you do, then you can create your
+  own malloc.h that does include all settings by cutting at the point
+  indicated below. Note that you may already by default be using a C
+  library containing a malloc that is based on some version of this
+  malloc (for example in linux). You might still want to use the one
+  in this file to customize settings or to avoid overheads associated
+  with library versions.
+
+* Vital statistics:
+
+  Supported pointer/size_t representation:       4 or 8 bytes
+       size_t MUST be an unsigned type of the same width as
+       pointers. (If you are using an ancient system that declares
+       size_t as a signed type, or need it to be a different width
+       than pointers, you can use a previous release of this malloc
+       (e.g. 2.7.2) supporting these.)
+
+  Alignment:                                     8 bytes (default)
+       This suffices for nearly all current machines and C compilers.
+       However, you can define MALLOC_ALIGNMENT to be wider than this
+       if necessary (up to 128bytes), at the expense of using more space.
+
+  Minimum overhead per allocated chunk:   4 or  8 bytes (if 4byte sizes)
+                                          8 or 16 bytes (if 8byte sizes)
+       Each malloced chunk has a hidden word of overhead holding size
+       and status information, and additional cross-check word
+       if FOOTERS is defined.
+
+  Minimum allocated size: 4-byte ptrs:  16 bytes    (including overhead)
+                          8-byte ptrs:  32 bytes    (including overhead)
+
+       Even a request for zero bytes (i.e., malloc(0)) returns a
+       pointer to something of the minimum allocatable size.
+       The maximum overhead wastage (i.e., number of extra bytes
+       allocated than were requested in malloc) is less than or equal
+       to the minimum size, except for requests >= mmap_threshold that
+       are serviced via mmap(), where the worst case wastage is about
+       32 bytes plus the remainder from a system page (the minimal
+       mmap unit); typically 4096 or 8192 bytes.
+
+  Security: static-safe; optionally more or less
+       The "security" of malloc refers to the ability of malicious
+       code to accentuate the effects of errors (for example, freeing
+       space that is not currently malloc'ed or overwriting past the
+       ends of chunks) in code that calls malloc.  This malloc
+       guarantees not to modify any memory locations below the base of
+       heap, i.e., static variables, even in the presence of usage
+       errors.  The routines additionally detect most improper frees
+       and reallocs.  All this holds as long as the static bookkeeping
+       for malloc itself is not corrupted by some other means.  This
+       is only one aspect of security -- these checks do not, and
+       cannot, detect all possible programming errors.
+
+       If FOOTERS is defined nonzero, then each allocated chunk
+       carries an additional check word to verify that it was malloced
+       from its space.  These check words are the same within each
+       execution of a program using malloc, but differ across
+       executions, so externally crafted fake chunks cannot be
+       freed. This improves security by rejecting frees/reallocs that
+       could corrupt heap memory, in addition to the checks preventing
+       writes to statics that are always on.  This may further improve
+       security at the expense of time and space overhead.  (Note that
+       FOOTERS may also be worth using with MSPACES.)
+
+       By default detected errors cause the program to abort (calling
+       "abort()"). You can override this to instead proceed past
+       errors by defining PROCEED_ON_ERROR.  In this case, a bad free
+       has no effect, and a malloc that encounters a bad address
+       caused by user overwrites will ignore the bad address by
+       dropping pointers and indices to all known memory. This may
+       be appropriate for programs that should continue if at all
+       possible in the face of programming errors, although they may
+       run out of memory because dropped memory is never reclaimed.
+
+       If you don't like either of these options, you can define
+       CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything
+       else. And if if you are sure that your program using malloc has
+       no errors or vulnerabilities, you can define INSECURE to 1,
+       which might (or might not) provide a small performance improvement.
+
+  Thread-safety: NOT thread-safe unless USE_LOCKS defined
+       When USE_LOCKS is defined, each public call to malloc, free,
+       etc is surrounded with either a pthread mutex or a win32
+       spinlock (depending on WIN32). This is not especially fast, and
+       can be a major bottleneck.  It is designed only to provide
+       minimal protection in concurrent environments, and to provide a
+       basis for extensions.  If you are using malloc in a concurrent
+       program, consider instead using ptmalloc, which is derived from
+       a version of this malloc. (See http://www.malloc.de).
+
+  System requirements: Any combination of MORECORE and/or MMAP/MUNMAP
+       This malloc can use unix sbrk or any emulation (invoked using
+       the CALL_MORECORE macro) and/or mmap/munmap or any emulation
+       (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system
+       memory.  On most unix systems, it tends to work best if both
+       MORECORE and MMAP are enabled.  On Win32, it uses emulations
+       based on VirtualAlloc. It also uses common C library functions
+       like memset.
+
+  Compliance: I believe it is compliant with the Single Unix Specification
+       (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably
+       others as well.
+
+* Overview of algorithms
+
+  This is not the fastest, most space-conserving, most portable, or
+  most tunable malloc ever written. However it is among the fastest
+  while also being among the most space-conserving, portable and
+  tunable.  Consistent balance across these factors results in a good
+  general-purpose allocator for malloc-intensive programs.
+
+  In most ways, this malloc is a best-fit allocator. Generally, it
+  chooses the best-fitting existing chunk for a request, with ties
+  broken in approximately least-recently-used order. (This strategy
+  normally maintains low fragmentation.) However, for requests less
+  than 256bytes, it deviates from best-fit when there is not an
+  exactly fitting available chunk by preferring to use space adjacent
+  to that used for the previous small request, as well as by breaking
+  ties in approximately most-recently-used order. (These enhance
+  locality of series of small allocations.)  And for very large requests
+  (>= 256Kb by default), it relies on system memory mapping
+  facilities, if supported.  (This helps avoid carrying around and
+  possibly fragmenting memory used only for large chunks.)
+
+  All operations (except malloc_stats and mallinfo) have execution
+  times that are bounded by a constant factor of the number of bits in
+  a size_t, not counting any clearing in calloc or copying in realloc,
+  or actions surrounding MORECORE and MMAP that have times
+  proportional to the number of non-contiguous regions returned by
+  system allocation routines, which is often just 1.
+
+  The implementation is not very modular and seriously overuses
+  macros. Perhaps someday all C compilers will do as good a job
+  inlining modular code as can now be done by brute-force expansion,
+  but now, enough of them seem not to.
+
+  Some compilers issue a lot of warnings about code that is
+  dead/unreachable only on some platforms, and also about intentional
+  uses of negation on unsigned types. All known cases of each can be
+  ignored.
+
+  For a longer but out of date high-level description, see
+     http://gee.cs.oswego.edu/dl/html/malloc.html
+
+* MSPACES
+  If MSPACES is defined, then in addition to malloc, free, etc.,
+  this file also defines mspace_malloc, mspace_free, etc. These
+  are versions of malloc routines that take an "mspace" argument
+  obtained using create_mspace, to control all internal bookkeeping.
+  If ONLY_MSPACES is defined, only these versions are compiled.
+  So if you would like to use this allocator for only some allocations,
+  and your system malloc for others, you can compile with
+  ONLY_MSPACES and then do something like...
+    static mspace mymspace = create_mspace(0,0); // for example
+    #define mymalloc(bytes)  mspace_malloc(mymspace, bytes)
+
+  (Note: If you only need one instance of an mspace, you can instead
+  use "USE_DL_PREFIX" to relabel the global malloc.)
+
+  You can similarly create thread-local allocators by storing
+  mspaces as thread-locals. For example:
+    static __thread mspace tlms = 0;
+    void*  tlmalloc(size_t bytes) {
+      if (tlms == 0) tlms = create_mspace(0, 0);
+      return mspace_malloc(tlms, bytes);
+    }
+    void  tlfree(void* mem) { mspace_free(tlms, mem); }
+
+  Unless FOOTERS is defined, each mspace is completely independent.
+  You cannot allocate from one and free to another (although
+  conformance is only weakly checked, so usage errors are not always
+  caught). If FOOTERS is defined, then each chunk carries around a tag
+  indicating its originating mspace, and frees are directed to their
+  originating spaces.
+
+ -------------------------  Compile-time options ---------------------------
+
+Be careful in setting #define values for numerical constants of type
+size_t. On some systems, literal values are not automatically extended
+to size_t precision unless they are explicitly casted.
+
+WIN32                    default: defined if _WIN32 defined
+  Defining WIN32 sets up defaults for MS environment and compilers.
+  Otherwise defaults are for unix.
+
+MALLOC_ALIGNMENT         default: (size_t)8
+  Controls the minimum alignment for malloc'ed chunks.  It must be a
+  power of two and at least 8, even on machines for which smaller
+  alignments would suffice. It may be defined as larger than this
+  though. Note however that code and data structures are optimized for
+  the case of 8-byte alignment.
+
+MSPACES                  default: 0 (false)
+  If true, compile in support for independent allocation spaces.
+  This is only supported if HAVE_MMAP is true.
+
+ONLY_MSPACES             default: 0 (false)
+  If true, only compile in mspace versions, not regular versions.
+
+USE_LOCKS                default: 0 (false)
+  Causes each call to each public routine to be surrounded with
+  pthread or WIN32 mutex lock/unlock. (If set true, this can be
+  overridden on a per-mspace basis for mspace versions.)
+
+FOOTERS                  default: 0
+  If true, provide extra checking and dispatching by placing
+  information in the footers of allocated chunks. This adds
+  space and time overhead.
+
+INSECURE                 default: 0
+  If true, omit checks for usage errors and heap space overwrites.
+
+USE_DL_PREFIX            default: NOT defined
+  Causes compiler to prefix all public routines with the string 'dl'.
+  This can be useful when you only want to use this malloc in one part
+  of a program, using your regular system malloc elsewhere.
+
+ABORT                    default: defined as abort()
+  Defines how to abort on failed checks.  On most systems, a failed
+  check cannot die with an "assert" or even print an informative
+  message, because the underlying print routines in turn call malloc,
+  which will fail again.  Generally, the best policy is to simply call
+  abort(). It's not very useful to do more than this because many
+  errors due to overwriting will show up as address faults (null, odd
+  addresses etc) rather than malloc-triggered checks, so will also
+  abort.  Also, most compilers know that abort() does not return, so
+  can better optimize code conditionally calling it.
+
+PROCEED_ON_ERROR           default: defined as 0 (false)
+  Controls whether detected bad addresses cause them to bypassed
+  rather than aborting. If set, detected bad arguments to free and
+  realloc are ignored. And all bookkeeping information is zeroed out
+  upon a detected overwrite of freed heap space, thus losing the
+  ability to ever return it from malloc again, but enabling the
+  application to proceed. If PROCEED_ON_ERROR is defined, the
+  static variable malloc_corruption_error_count is compiled in
+  and can be examined to see if errors have occurred. This option
+  generates slower code than the default abort policy.
+
+DEBUG                    default: NOT defined
+  The DEBUG setting is mainly intended for people trying to modify
+  this code or diagnose problems when porting to new platforms.
+  However, it may also be able to better isolate user errors than just
+  using runtime checks.  The assertions in the check routines spell
+  out in more detail the assumptions and invariants underlying the
+  algorithms.  The checking is fairly extensive, and will slow down
+  execution noticeably. Calling malloc_stats or mallinfo with DEBUG
+  set will attempt to check every non-mmapped allocated and free chunk
+  in the course of computing the summaries.
+
+ABORT_ON_ASSERT_FAILURE   default: defined as 1 (true)
+  Debugging assertion failures can be nearly impossible if your
+  version of the assert macro causes malloc to be called, which will
+  lead to a cascade of further failures, blowing the runtime stack.
+  ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(),
+  which will usually make debugging easier.
+
+MALLOC_FAILURE_ACTION     default: sets errno to ENOMEM, or no-op on win32
+  The action to take before "return 0" when malloc fails to be able to
+  return memory because there is none available.
+
+HAVE_MORECORE             default: 1 (true) unless win32 or ONLY_MSPACES
+  True if this system supports sbrk or an emulation of it.
+
+MORECORE                  default: sbrk
+  The name of the sbrk-style system routine to call to obtain more
+  memory.  See below for guidance on writing custom MORECORE
+  functions. The type of the argument to sbrk/MORECORE varies across
+  systems.  It cannot be size_t, because it supports negative
+  arguments, so it is normally the signed type of the same width as
+  size_t (sometimes declared as "intptr_t").  It doesn't much matter
+  though. Internally, we only call it with arguments less than half
+  the max value of a size_t, which should work across all reasonable
+  possibilities, although sometimes generating compiler warnings.  See
+  near the end of this file for guidelines for creating a custom
+  version of MORECORE.
+
+MORECORE_CONTIGUOUS       default: 1 (true)
+  If true, take advantage of fact that consecutive calls to MORECORE
+  with positive arguments always return contiguous increasing
+  addresses.  This is true of unix sbrk. It does not hurt too much to
+  set it true anyway, since malloc copes with non-contiguities.
+  Setting it false when definitely non-contiguous saves time
+  and possibly wasted space it would take to discover this though.
+
+MORECORE_CANNOT_TRIM      default: NOT defined
+  True if MORECORE cannot release space back to the system when given
+  negative arguments. This is generally necessary only if you are
+  using a hand-crafted MORECORE function that cannot handle negative
+  arguments.
+
+HAVE_MMAP                 default: 1 (true)
+  True if this system supports mmap or an emulation of it.  If so, and
+  HAVE_MORECORE is not true, MMAP is used for all system
+  allocation. If set and HAVE_MORECORE is true as well, MMAP is
+  primarily used to directly allocate very large blocks. It is also
+  used as a backup strategy in cases where MORECORE fails to provide
+  space from system. Note: A single call to MUNMAP is assumed to be
+  able to unmap memory that may have be allocated using multiple calls
+  to MMAP, so long as they are adjacent.
+
+HAVE_MREMAP               default: 1 on linux, else 0
+  If true realloc() uses mremap() to re-allocate large blocks and
+  extend or shrink allocation spaces.
+
+MMAP_CLEARS               default: 1 on unix
+  True if mmap clears memory so calloc doesn't need to. This is true
+  for standard unix mmap using /dev/zero.
+
+USE_BUILTIN_FFS            default: 0 (i.e., not used)
+  Causes malloc to use the builtin ffs() function to compute indices.
+  Some compilers may recognize and intrinsify ffs to be faster than the
+  supplied C version. Also, the case of x86 using gcc is special-cased
+  to an asm instruction, so is already as fast as it can be, and so
+  this setting has no effect. (On most x86s, the asm version is only
+  slightly faster than the C version.)
+
+malloc_getpagesize         default: derive from system includes, or 4096.
+  The system page size. To the extent possible, this malloc manages
+  memory from the system in page-size units.  This may be (and
+  usually is) a function rather than a constant. This is ignored
+  if WIN32, where page size is determined using getSystemInfo during
+  initialization.
+
+USE_DEV_RANDOM             default: 0 (i.e., not used)
+  Causes malloc to use /dev/random to initialize secure magic seed for
+  stamping footers. Otherwise, the current time is used.
+
+NO_MALLINFO                default: 0
+  If defined, don't compile "mallinfo". This can be a simple way
+  of dealing with mismatches between system declarations and
+  those in this file.
+
+MALLINFO_FIELD_TYPE        default: size_t
+  The type of the fields in the mallinfo struct. This was originally
+  defined as "int" in SVID etc, but is more usefully defined as
+  size_t. The value is used only if  HAVE_USR_INCLUDE_MALLOC_H is not set
+
+REALLOC_ZERO_BYTES_FREES    default: not defined
+  This should be set if a call to realloc with zero bytes should 
+  be the same as a call to free. Some people think it should. Otherwise, 
+  since this malloc returns a unique pointer for malloc(0), so does 
+  realloc(p, 0).
+
+LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H
+LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H,  LACKS_ERRNO_H
+LACKS_STDLIB_H                default: NOT defined unless on WIN32
+  Define these if your system does not have these header files.
+  You might need to manually insert some of the declarations they provide.
+
+DEFAULT_GRANULARITY        default: page size if MORECORE_CONTIGUOUS,
+                                system_info.dwAllocationGranularity in WIN32,
+                                otherwise 64K.
+      Also settable using mallopt(M_GRANULARITY, x)
+  The unit for allocating and deallocating memory from the system.  On
+  most systems with contiguous MORECORE, there is no reason to
+  make this more than a page. However, systems with MMAP tend to
+  either require or encourage larger granularities.  You can increase
+  this value to prevent system allocation functions to be called so
+  often, especially if they are slow.  The value must be at least one
+  page and must be a power of two.  Setting to 0 causes initialization
+  to either page size or win32 region size.  (Note: In previous
+  versions of malloc, the equivalent of this option was called
+  "TOP_PAD")
+
+DEFAULT_TRIM_THRESHOLD    default: 2MB
+      Also settable using mallopt(M_TRIM_THRESHOLD, x)
+  The maximum amount of unused top-most memory to keep before
+  releasing via malloc_trim in free().  Automatic trimming is mainly
+  useful in long-lived programs using contiguous MORECORE.  Because
+  trimming via sbrk can be slow on some systems, and can sometimes be
+  wasteful (in cases where programs immediately afterward allocate
+  more large chunks) the value should be high enough so that your
+  overall system performance would improve by releasing this much
+  memory.  As a rough guide, you might set to a value close to the
+  average size of a process (program) running on your system.
+  Releasing this much memory would allow such a process to run in
+  memory.  Generally, it is worth tuning trim thresholds when a
+  program undergoes phases where several large chunks are allocated
+  and released in ways that can reuse each other's storage, perhaps
+  mixed with phases where there are no such chunks at all. The trim
+  value must be greater than page size to have any useful effect.  To
+  disable trimming completely, you can set to MAX_SIZE_T. Note that the trick
+  some people use of mallocing a huge space and then freeing it at
+  program startup, in an attempt to reserve system memory, doesn't
+  have the intended effect under automatic trimming, since that memory
+  will immediately be returned to the system.
+
+DEFAULT_MMAP_THRESHOLD       default: 256K
+      Also settable using mallopt(M_MMAP_THRESHOLD, x)
+  The request size threshold for using MMAP to directly service a
+  request. Requests of at least this size that cannot be allocated
+  using already-existing space will be serviced via mmap.  (If enough
+  normal freed space already exists it is used instead.)  Using mmap
+  segregates relatively large chunks of memory so that they can be
+  individually obtained and released from the host system. A request
+  serviced through mmap is never reused by any other request (at least
+  not directly; the system may just so happen to remap successive
+  requests to the same locations).  Segregating space in this way has
+  the benefits that: Mmapped space can always be individually released
+  back to the system, which helps keep the system level memory demands
+  of a long-lived program low.  Also, mapped memory doesn't become
+  `locked' between other chunks, as can happen with normally allocated
+  chunks, which means that even trimming via malloc_trim would not
+  release them.  However, it has the disadvantage that the space
+  cannot be reclaimed, consolidated, and then used to service later
+  requests, as happens with normal chunks.  The advantages of mmap
+  nearly always outweigh disadvantages for "large" chunks, but the
+  value of "large" may vary across systems.  The default is an
+  empirically derived value that works well in most systems. You can
+  disable mmap by setting to MAX_SIZE_T.
+
+*/
+
+#ifndef WIN32
+#ifdef _WIN32
+#define WIN32 1
+#endif  /* _WIN32 */
+#endif  /* WIN32 */
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#define HAVE_MMAP 1
+#define HAVE_MORECORE 0
+#define LACKS_UNISTD_H
+#define LACKS_SYS_PARAM_H
+#define LACKS_SYS_MMAN_H
+#define LACKS_STRING_H
+#define LACKS_STRINGS_H
+#define LACKS_SYS_TYPES_H
+#define LACKS_ERRNO_H
+#define MALLOC_FAILURE_ACTION
+#define MMAP_CLEARS 0 /* WINCE and some others apparently don't clear */
+#endif  /* WIN32 */
+
+#ifdef __OS2__
+#define INCL_DOS
+#include <os2.h>
+#define HAVE_MMAP 1
+#define HAVE_MORECORE 0
+#define LACKS_SYS_MMAN_H
+#endif  /* __OS2__ */
+
+#if defined(DARWIN) || defined(_DARWIN)
+/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */
+#ifndef HAVE_MORECORE
+#define HAVE_MORECORE 0
+#define HAVE_MMAP 1
+#endif  /* HAVE_MORECORE */
+#endif  /* DARWIN */
+
+#ifndef LACKS_SYS_TYPES_H
+#include <sys/types.h>  /* For size_t */
+#endif  /* LACKS_SYS_TYPES_H */
+
+/* The maximum possible size_t value has all bits set */
+#define MAX_SIZE_T           (~(size_t)0)
+
+#ifndef ONLY_MSPACES
+#define ONLY_MSPACES 0
+#endif  /* ONLY_MSPACES */
+#ifndef MSPACES
+#if ONLY_MSPACES
+#define MSPACES 1
+#else   /* ONLY_MSPACES */
+#define MSPACES 0
+#endif  /* ONLY_MSPACES */
+#endif  /* MSPACES */
+#ifndef MALLOC_ALIGNMENT
+#define MALLOC_ALIGNMENT ((size_t)8U)
+#endif  /* MALLOC_ALIGNMENT */
+#ifndef FOOTERS
+#define FOOTERS 0
+#endif  /* FOOTERS */
+#ifndef ABORT
+#define ABORT  abort()
+#endif  /* ABORT */
+#ifndef ABORT_ON_ASSERT_FAILURE
+#define ABORT_ON_ASSERT_FAILURE 1
+#endif  /* ABORT_ON_ASSERT_FAILURE */
+#ifndef PROCEED_ON_ERROR
+#define PROCEED_ON_ERROR 0
+#endif  /* PROCEED_ON_ERROR */
+#ifndef USE_LOCKS
+#define USE_LOCKS 0
+#endif  /* USE_LOCKS */
+#ifndef INSECURE
+#define INSECURE 0
+#endif  /* INSECURE */
+#ifndef HAVE_MMAP
+#define HAVE_MMAP 1
+#endif  /* HAVE_MMAP */
+#ifndef MMAP_CLEARS
+#define MMAP_CLEARS 1
+#endif  /* MMAP_CLEARS */
+#ifndef HAVE_MREMAP
+#ifdef linux
+#define HAVE_MREMAP 1
+#else   /* linux */
+#define HAVE_MREMAP 0
+#endif  /* linux */
+#endif  /* HAVE_MREMAP */
+#ifndef MALLOC_FAILURE_ACTION
+#define MALLOC_FAILURE_ACTION  errno = ENOMEM;
+#endif  /* MALLOC_FAILURE_ACTION */
+#ifndef HAVE_MORECORE
+#if ONLY_MSPACES
+#define HAVE_MORECORE 0
+#else   /* ONLY_MSPACES */
+#define HAVE_MORECORE 1
+#endif  /* ONLY_MSPACES */
+#endif  /* HAVE_MORECORE */
+#if !HAVE_MORECORE
+#define MORECORE_CONTIGUOUS 0
+#else   /* !HAVE_MORECORE */
+#ifndef MORECORE
+#define MORECORE sbrk
+#endif  /* MORECORE */
+#ifndef MORECORE_CONTIGUOUS
+#define MORECORE_CONTIGUOUS 1
+#endif  /* MORECORE_CONTIGUOUS */
+#endif  /* HAVE_MORECORE */
+#ifndef DEFAULT_GRANULARITY
+#if MORECORE_CONTIGUOUS
+#define DEFAULT_GRANULARITY (0)  /* 0 means to compute in init_mparams */
+#else   /* MORECORE_CONTIGUOUS */
+#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U)
+#endif  /* MORECORE_CONTIGUOUS */
+#endif  /* DEFAULT_GRANULARITY */
+#ifndef DEFAULT_TRIM_THRESHOLD
+#ifndef MORECORE_CANNOT_TRIM
+#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U)
+#else   /* MORECORE_CANNOT_TRIM */
+#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T
+#endif  /* MORECORE_CANNOT_TRIM */
+#endif  /* DEFAULT_TRIM_THRESHOLD */
+#ifndef DEFAULT_MMAP_THRESHOLD
+#if HAVE_MMAP
+#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U)
+#else   /* HAVE_MMAP */
+#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
+#endif  /* HAVE_MMAP */
+#endif  /* DEFAULT_MMAP_THRESHOLD */
+#ifndef USE_BUILTIN_FFS
+#define USE_BUILTIN_FFS 0
+#endif  /* USE_BUILTIN_FFS */
+#ifndef USE_DEV_RANDOM
+#define USE_DEV_RANDOM 0
+#endif  /* USE_DEV_RANDOM */
+#ifndef NO_MALLINFO
+#define NO_MALLINFO 0
+#endif  /* NO_MALLINFO */
+#ifndef MALLINFO_FIELD_TYPE
+#define MALLINFO_FIELD_TYPE size_t
+#endif  /* MALLINFO_FIELD_TYPE */
+
+/*
+  mallopt tuning options.  SVID/XPG defines four standard parameter
+  numbers for mallopt, normally defined in malloc.h.  None of these
+  are used in this malloc, so setting them has no effect. But this
+  malloc does support the following options.
+*/
+
+#define M_TRIM_THRESHOLD     (-1)
+#define M_GRANULARITY        (-2)
+#define M_MMAP_THRESHOLD     (-3)
+
+/* ------------------------ Mallinfo declarations ------------------------ */
+
+#if !NO_MALLINFO
+/*
+  This version of malloc supports the standard SVID/XPG mallinfo
+  routine that returns a struct containing usage properties and
+  statistics. It should work on any system that has a
+  /usr/include/malloc.h defining struct mallinfo.  The main
+  declaration needed is the mallinfo struct that is returned (by-copy)
+  by mallinfo().  The malloinfo struct contains a bunch of fields that
+  are not even meaningful in this version of malloc.  These fields are
+  are instead filled by mallinfo() with other numbers that might be of
+  interest.
+
+  HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
+  /usr/include/malloc.h file that includes a declaration of struct
+  mallinfo.  If so, it is included; else a compliant version is
+  declared below.  These must be precisely the same for mallinfo() to
+  work.  The original SVID version of this struct, defined on most
+  systems with mallinfo, declares all fields as ints. But some others
+  define as unsigned long. If your system defines the fields using a
+  type of different width than listed here, you MUST #include your
+  system version and #define HAVE_USR_INCLUDE_MALLOC_H.
+*/
+
+/* #define HAVE_USR_INCLUDE_MALLOC_H */
+
+#ifdef HAVE_USR_INCLUDE_MALLOC_H
+#include "/usr/include/malloc.h"
+#else /* HAVE_USR_INCLUDE_MALLOC_H */
+
+/* HP-UX's stdlib.h redefines mallinfo unless _STRUCT_MALLINFO is defined */
+#define _STRUCT_MALLINFO
+
+struct mallinfo {
+  MALLINFO_FIELD_TYPE arena;    /* non-mmapped space allocated from system */
+  MALLINFO_FIELD_TYPE ordblks;  /* number of free chunks */
+  MALLINFO_FIELD_TYPE smblks;   /* always 0 */
+  MALLINFO_FIELD_TYPE hblks;    /* always 0 */
+  MALLINFO_FIELD_TYPE hblkhd;   /* space in mmapped regions */
+  MALLINFO_FIELD_TYPE usmblks;  /* maximum total allocated space */
+  MALLINFO_FIELD_TYPE fsmblks;  /* always 0 */
+  MALLINFO_FIELD_TYPE uordblks; /* total allocated space */
+  MALLINFO_FIELD_TYPE fordblks; /* total free space */
+  MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */
+};
+
+#endif /* HAVE_USR_INCLUDE_MALLOC_H */
+#endif /* NO_MALLINFO */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#if !ONLY_MSPACES
+
+/* ------------------- Declarations of public routines ------------------- */
+
+#ifndef USE_DL_PREFIX
+#define dlcalloc               calloc
+#define dlfree                 free
+#define dlmalloc               malloc
+#define dlmemalign             memalign
+#define dlrealloc              realloc
+#define dlvalloc               valloc
+#define dlpvalloc              pvalloc
+#define dlmallinfo             mallinfo
+#define dlmallopt              mallopt
+#define dlmalloc_trim          malloc_trim
+#define dlmalloc_stats         malloc_stats
+#define dlmalloc_usable_size   malloc_usable_size
+#define dlmalloc_footprint     malloc_footprint
+#define dlmalloc_max_footprint malloc_max_footprint
+#define dlindependent_calloc   independent_calloc
+#define dlindependent_comalloc independent_comalloc
+#endif /* USE_DL_PREFIX */
+
+
+/*
+  malloc(size_t n)
+  Returns a pointer to a newly allocated chunk of at least n bytes, or
+  null if no space is available, in which case errno is set to ENOMEM
+  on ANSI C systems.
+
+  If n is zero, malloc returns a minimum-sized chunk. (The minimum
+  size is 16 bytes on most 32bit systems, and 32 bytes on 64bit
+  systems.)  Note that size_t is an unsigned type, so calls with
+  arguments that would be negative if signed are interpreted as
+  requests for huge amounts of space, which will often fail. The
+  maximum supported value of n differs across systems, but is in all
+  cases less than the maximum representable value of a size_t.
+*/
+void* dlmalloc(size_t);
+
+/*
+  free(void* p)
+  Releases the chunk of memory pointed to by p, that had been previously
+  allocated using malloc or a related routine such as realloc.
+  It has no effect if p is null. If p was not malloced or already
+  freed, free(p) will by default cause the current program to abort.
+*/
+void  dlfree(void*);
+
+/*
+  calloc(size_t n_elements, size_t element_size);
+  Returns a pointer to n_elements * element_size bytes, with all locations
+  set to zero.
+*/
+void* dlcalloc(size_t, size_t);
+
+/*
+  realloc(void* p, size_t n)
+  Returns a pointer to a chunk of size n that contains the same data
+  as does chunk p up to the minimum of (n, p's size) bytes, or null
+  if no space is available.
+
+  The returned pointer may or may not be the same as p. The algorithm
+  prefers extending p in most cases when possible, otherwise it
+  employs the equivalent of a malloc-copy-free sequence.
+
+  If p is null, realloc is equivalent to malloc.
+
+  If space is not available, realloc returns null, errno is set (if on
+  ANSI) and p is NOT freed.
+
+  if n is for fewer bytes than already held by p, the newly unused
+  space is lopped off and freed if possible.  realloc with a size
+  argument of zero (re)allocates a minimum-sized chunk.
+
+  The old unix realloc convention of allowing the last-free'd chunk
+  to be used as an argument to realloc is not supported.
+*/
+
+void* dlrealloc(void*, size_t);
+
+/*
+  memalign(size_t alignment, size_t n);
+  Returns a pointer to a newly allocated chunk of n bytes, aligned
+  in accord with the alignment argument.
+
+  The alignment argument should be a power of two. If the argument is
+  not a power of two, the nearest greater power is used.
+  8-byte alignment is guaranteed by normal malloc calls, so don't
+  bother calling memalign with an argument of 8 or less.
+
+  Overreliance on memalign is a sure way to fragment space.
+*/
+void* dlmemalign(size_t, size_t);
+
+/*
+  valloc(size_t n);
+  Equivalent to memalign(pagesize, n), where pagesize is the page
+  size of the system. If the pagesize is unknown, 4096 is used.
+*/
+void* dlvalloc(size_t);
+
+/*
+  mallopt(int parameter_number, int parameter_value)
+  Sets tunable parameters The format is to provide a
+  (parameter-number, parameter-value) pair.  mallopt then sets the
+  corresponding parameter to the argument value if it can (i.e., so
+  long as the value is meaningful), and returns 1 if successful else
+  0.  SVID/XPG/ANSI defines four standard param numbers for mallopt,
+  normally defined in malloc.h.  None of these are use in this malloc,
+  so setting them has no effect. But this malloc also supports other
+  options in mallopt. See below for details.  Briefly, supported
+  parameters are as follows (listed defaults are for "typical"
+  configurations).
+
+  Symbol            param #  default    allowed param values
+  M_TRIM_THRESHOLD     -1   2*1024*1024   any   (MAX_SIZE_T disables)
+  M_GRANULARITY        -2     page size   any power of 2 >= page size
+  M_MMAP_THRESHOLD     -3      256*1024   any   (or 0 if no MMAP support)
+*/
+int dlmallopt(int, int);
+
+/*
+  malloc_footprint();
+  Returns the number of bytes obtained from the system.  The total
+  number of bytes allocated by malloc, realloc etc., is less than this
+  value. Unlike mallinfo, this function returns only a precomputed
+  result, so can be called frequently to monitor memory consumption.
+  Even if locks are otherwise defined, this function does not use them,
+  so results might not be up to date.
+*/
+size_t dlmalloc_footprint(void);
+
+/*
+  malloc_max_footprint();
+  Returns the maximum number of bytes obtained from the system. This
+  value will be greater than current footprint if deallocated space
+  has been reclaimed by the system. The peak number of bytes allocated
+  by malloc, realloc etc., is less than this value. Unlike mallinfo,
+  this function returns only a precomputed result, so can be called
+  frequently to monitor memory consumption.  Even if locks are
+  otherwise defined, this function does not use them, so results might
+  not be up to date.
+*/
+size_t dlmalloc_max_footprint(void);
+
+#if !NO_MALLINFO
+/*
+  mallinfo()
+  Returns (by copy) a struct containing various summary statistics:
+
+  arena:     current total non-mmapped bytes allocated from system
+  ordblks:   the number of free chunks
+  smblks:    always zero.
+  hblks:     current number of mmapped regions
+  hblkhd:    total bytes held in mmapped regions
+  usmblks:   the maximum total allocated space. This will be greater
+                than current total if trimming has occurred.
+  fsmblks:   always zero
+  uordblks:  current total allocated space (normal or mmapped)
+  fordblks:  total free space
+  keepcost:  the maximum number of bytes that could ideally be released
+               back to system via malloc_trim. ("ideally" means that
+               it ignores page restrictions etc.)
+
+  Because these fields are ints, but internal bookkeeping may
+  be kept as longs, the reported values may wrap around zero and
+  thus be inaccurate.
+*/
+struct mallinfo dlmallinfo(void);
+#endif /* NO_MALLINFO */
+
+/*
+  independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);
+
+  independent_calloc is similar to calloc, but instead of returning a
+  single cleared space, it returns an array of pointers to n_elements
+  independent elements that can hold contents of size elem_size, each
+  of which starts out cleared, and can be independently freed,
+  realloc'ed etc. The elements are guaranteed to be adjacently
+  allocated (this is not guaranteed to occur with multiple callocs or
+  mallocs), which may also improve cache locality in some
+  applications.
+
+  The "chunks" argument is optional (i.e., may be null, which is
+  probably the most typical usage). If it is null, the returned array
+  is itself dynamically allocated and should also be freed when it is
+  no longer needed. Otherwise, the chunks array must be of at least
+  n_elements in length. It is filled in with the pointers to the
+  chunks.
+
+  In either case, independent_calloc returns this pointer array, or
+  null if the allocation failed.  If n_elements is zero and "chunks"
+  is null, it returns a chunk representing an array with zero elements
+  (which should be freed if not wanted).
+
+  Each element must be individually freed when it is no longer
+  needed. If you'd like to instead be able to free all at once, you
+  should instead use regular calloc and assign pointers into this
+  space to represent elements.  (In this case though, you cannot
+  independently free elements.)
+
+  independent_calloc simplifies and speeds up implementations of many
+  kinds of pools.  It may also be useful when constructing large data
+  structures that initially have a fixed number of fixed-sized nodes,
+  but the number is not known at compile time, and some of the nodes
+  may later need to be freed. For example:
+
+  struct Node { int item; struct Node* next; };
+
+  struct Node* build_list() {
+    struct Node** pool;
+    int n = read_number_of_nodes_needed();
+    if (n <= 0) return 0;
+    pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);
+    if (pool == 0) die();
+    // organize into a linked list...
+    struct Node* first = pool[0];
+    for (i = 0; i < n-1; ++i)
+      pool[i]->next = pool[i+1];
+    free(pool);     // Can now free the array (or not, if it is needed later)
+    return first;
+  }
+*/
+void** dlindependent_calloc(size_t, size_t, void**);
+
+/*
+  independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);
+
+  independent_comalloc allocates, all at once, a set of n_elements
+  chunks with sizes indicated in the "sizes" array.    It returns
+  an array of pointers to these elements, each of which can be
+  independently freed, realloc'ed etc. The elements are guaranteed to
+  be adjacently allocated (this is not guaranteed to occur with
+  multiple callocs or mallocs), which may also improve cache locality
+  in some applications.
+
+  The "chunks" argument is optional (i.e., may be null). If it is null
+  the returned array is itself dynamically allocated and should also
+  be freed when it is no longer needed. Otherwise, the chunks array
+  must be of at least n_elements in length. It is filled in with the
+  pointers to the chunks.
+
+  In either case, independent_comalloc returns this pointer array, or
+  null if the allocation failed.  If n_elements is zero and chunks is
+  null, it returns a chunk representing an array with zero elements
+  (which should be freed if not wanted).
+
+  Each element must be individually freed when it is no longer
+  needed. If you'd like to instead be able to free all at once, you
+  should instead use a single regular malloc, and assign pointers at
+  particular offsets in the aggregate space. (In this case though, you
+  cannot independently free elements.)
+
+  independent_comallac differs from independent_calloc in that each
+  element may have a different size, and also that it does not
+  automatically clear elements.
+
+  independent_comalloc can be used to speed up allocation in cases
+  where several structs or objects must always be allocated at the
+  same time.  For example:
+
+  struct Head { ... }
+  struct Foot { ... }
+
+  void send_message(char* msg) {
+    int msglen = strlen(msg);
+    size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };
+    void* chunks[3];
+    if (independent_comalloc(3, sizes, chunks) == 0)
+      die();
+    struct Head* head = (struct Head*)(chunks[0]);
+    char*        body = (char*)(chunks[1]);
+    struct Foot* foot = (struct Foot*)(chunks[2]);
+    // ...
+  }
+
+  In general though, independent_comalloc is worth using only for
+  larger values of n_elements. For small values, you probably won't
+  detect enough difference from series of malloc calls to bother.
+
+  Overuse of independent_comalloc can increase overall memory usage,
+  since it cannot reuse existing noncontiguous small chunks that
+  might be available for some of the elements.
+*/
+void** dlindependent_comalloc(size_t, size_t*, void**);
+
+
+/*
+  pvalloc(size_t n);
+  Equivalent to valloc(minimum-page-that-holds(n)), that is,
+  round up n to nearest pagesize.
+ */
+void*  dlpvalloc(size_t);
+
+/*
+  malloc_trim(size_t pad);
+
+  If possible, gives memory back to the system (via negative arguments
+  to sbrk) if there is unused memory at the `high' end of the malloc
+  pool or in unused MMAP segments. You can call this after freeing
+  large blocks of memory to potentially reduce the system-level memory
+  requirements of a program. However, it cannot guarantee to reduce
+  memory. Under some allocation patterns, some large free blocks of
+  memory will be locked between two used chunks, so they cannot be
+  given back to the system.
+
+  The `pad' argument to malloc_trim represents the amount of free
+  trailing space to leave untrimmed. If this argument is zero, only
+  the minimum amount of memory to maintain internal data structures
+  will be left. Non-zero arguments can be supplied to maintain enough
+  trailing space to service future expected allocations without having
+  to re-obtain memory from the system.
+
+  Malloc_trim returns 1 if it actually released any memory, else 0.
+*/
+int  dlmalloc_trim(size_t);
+
+/*
+  malloc_usable_size(void* p);
+
+  Returns the number of bytes you can actually use in
+  an allocated chunk, which may be more than you requested (although
+  often not) due to alignment and minimum size constraints.
+  You can use this many bytes without worrying about
+  overwriting other allocated objects. This is not a particularly great
+  programming practice. malloc_usable_size can be more useful in
+  debugging and assertions, for example:
+
+  p = malloc(n);
+  assert(malloc_usable_size(p) >= 256);
+*/
+size_t dlmalloc_usable_size(void*);
+
+/*
+  malloc_stats();
+  Prints on stderr the amount of space obtained from the system (both
+  via sbrk and mmap), the maximum amount (which may be more than
+  current if malloc_trim and/or munmap got called), and the current
+  number of bytes allocated via malloc (or realloc, etc) but not yet
+  freed. Note that this is the number of bytes allocated, not the
+  number requested. It will be larger than the number requested
+  because of alignment and bookkeeping overhead. Because it includes
+  alignment wastage as being in use, this figure may be greater than
+  zero even when no user-level chunks are allocated.
+
+  The reported current and maximum system memory can be inaccurate if
+  a program makes other calls to system memory allocation functions
+  (normally sbrk) outside of malloc.
+
+  malloc_stats prints only the most commonly interesting statistics.
+  More information can be obtained by calling mallinfo.
+*/
+void  dlmalloc_stats(void);
+
+#endif /* ONLY_MSPACES */
+
+#if MSPACES
+
+/*
+  mspace is an opaque type representing an independent
+  region of space that supports mspace_malloc, etc.
+*/
+typedef void* mspace;
+
+/*
+  create_mspace creates and returns a new independent space with the
+  given initial capacity, or, if 0, the default granularity size.  It
+  returns null if there is no system memory available to create the
+  space.  If argument locked is non-zero, the space uses a separate
+  lock to control access. The capacity of the space will grow
+  dynamically as needed to service mspace_malloc requests.  You can
+  control the sizes of incremental increases of this space by
+  compiling with a different DEFAULT_GRANULARITY or dynamically
+  setting with mallopt(M_GRANULARITY, value).
+*/
+mspace create_mspace(size_t capacity, int locked);
+
+/*
+  destroy_mspace destroys the given space, and attempts to return all
+  of its memory back to the system, returning the total number of
+  bytes freed. After destruction, the results of access to all memory
+  used by the space become undefined.
+*/
+size_t destroy_mspace(mspace msp);
+
+/*
+  create_mspace_with_base uses the memory supplied as the initial base
+  of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this
+  space is used for bookkeeping, so the capacity must be at least this
+  large. (Otherwise 0 is returned.) When this initial space is
+  exhausted, additional memory will be obtained from the system.
+  Destroying this space will deallocate all additionally allocated
+  space (if possible) but not the initial base.
+*/
+mspace create_mspace_with_base(void* base, size_t capacity, int locked);
+
+/*
+  mspace_malloc behaves as malloc, but operates within
+  the given space.
+*/
+void* mspace_malloc(mspace msp, size_t bytes);
+
+/*
+  mspace_free behaves as free, but operates within
+  the given space.
+
+  If compiled with FOOTERS==1, mspace_free is not actually needed.
+  free may be called instead of mspace_free because freed chunks from
+  any space are handled by their originating spaces.
+*/
+void mspace_free(mspace msp, void* mem);
+
+/*
+  mspace_realloc behaves as realloc, but operates within
+  the given space.
+
+  If compiled with FOOTERS==1, mspace_realloc is not actually
+  needed.  realloc may be called instead of mspace_realloc because
+  realloced chunks from any space are handled by their originating
+  spaces.
+*/
+void* mspace_realloc(mspace msp, void* mem, size_t newsize);
+
+/*
+  mspace_calloc behaves as calloc, but operates within
+  the given space.
+*/
+void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);
+
+/*
+  mspace_memalign behaves as memalign, but operates within
+  the given space.
+*/
+void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);
+
+/*
+  mspace_independent_calloc behaves as independent_calloc, but
+  operates within the given space.
+*/
+void** mspace_independent_calloc(mspace msp, size_t n_elements,
+                                 size_t elem_size, void* chunks[]);
+
+/*
+  mspace_independent_comalloc behaves as independent_comalloc, but
+  operates within the given space.
+*/
+void** mspace_independent_comalloc(mspace msp, size_t n_elements,
+                                   size_t sizes[], void* chunks[]);
+
+/*
+  mspace_footprint() returns the number of bytes obtained from the
+  system for this space.
+*/
+size_t mspace_footprint(mspace msp);
+
+/*
+  mspace_max_footprint() returns the peak number of bytes obtained from the
+  system for this space.
+*/
+size_t mspace_max_footprint(mspace msp);
+
+
+#if !NO_MALLINFO
+/*
+  mspace_mallinfo behaves as mallinfo, but reports properties of
+  the given space.
+*/
+struct mallinfo mspace_mallinfo(mspace msp);
+#endif /* NO_MALLINFO */
+
+/*
+  mspace_malloc_stats behaves as malloc_stats, but reports
+  properties of the given space.
+*/
+void mspace_malloc_stats(mspace msp);
+
+/*
+  mspace_trim behaves as malloc_trim, but
+  operates within the given space.
+*/
+int mspace_trim(mspace msp, size_t pad);
+
+/*
+  An alias for mallopt.
+*/
+int mspace_mallopt(int, int);
+
+#endif /* MSPACES */
+
+#ifdef __cplusplus
+};  /* end of extern "C" */
+#endif /* __cplusplus */
+
+/*
+  ========================================================================
+  To make a fully customizable malloc.h header file, cut everything
+  above this line, put into file malloc.h, edit to suit, and #include it
+  on the next line, as well as in programs that use this malloc.
+  ========================================================================
+*/
+
+/* #include "malloc.h" */
+
+/*------------------------------ internal #includes ---------------------- */
+
+#ifdef _MSC_VER
+#pragma warning( disable : 4146 ) /* no "unsigned" warnings */
+#endif /* _MSC_VER */
+
+#include <stdio.h>       /* for printing in malloc_stats */
+
+#ifndef LACKS_ERRNO_H
+#include <errno.h>       /* for MALLOC_FAILURE_ACTION */
+#endif /* LACKS_ERRNO_H */
+#if FOOTERS
+#include <time.h>        /* for magic initialization */
+#endif /* FOOTERS */
+#ifndef LACKS_STDLIB_H
+#include <stdlib.h>      /* for abort() */
+#endif /* LACKS_STDLIB_H */
+#ifdef DEBUG
+#if ABORT_ON_ASSERT_FAILURE
+#define assert(x) if(!(x)) ABORT
+#else /* ABORT_ON_ASSERT_FAILURE */
+#include <assert.h>
+#endif /* ABORT_ON_ASSERT_FAILURE */
+#else  /* DEBUG */
+#define assert(x)
+#endif /* DEBUG */
+#ifndef LACKS_STRING_H
+#include <string.h>      /* for memset etc */
+#endif  /* LACKS_STRING_H */
+#if USE_BUILTIN_FFS
+#ifndef LACKS_STRINGS_H
+#include <strings.h>     /* for ffs */
+#endif /* LACKS_STRINGS_H */
+#endif /* USE_BUILTIN_FFS */
+#if HAVE_MMAP
+#ifndef LACKS_SYS_MMAN_H
+#include <sys/mman.h>    /* for mmap */
+#endif /* LACKS_SYS_MMAN_H */
+#ifndef LACKS_FCNTL_H
+#include <fcntl.h>
+#endif /* LACKS_FCNTL_H */
+#endif /* HAVE_MMAP */
+#if HAVE_MORECORE
+#ifndef LACKS_UNISTD_H
+#include <unistd.h>     /* for sbrk */
+#else /* LACKS_UNISTD_H */
+#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
+extern void*     sbrk(ptrdiff_t);
+#endif /* FreeBSD etc */
+#endif /* LACKS_UNISTD_H */
+#endif /* HAVE_MMAP */
+
+#ifndef WIN32
+#ifndef malloc_getpagesize
+#  ifdef _SC_PAGESIZE         /* some SVR4 systems omit an underscore */
+#    ifndef _SC_PAGE_SIZE
+#      define _SC_PAGE_SIZE _SC_PAGESIZE
+#    endif
+#  endif
+#  ifdef _SC_PAGE_SIZE
+#    define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
+#  else
+#    if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
+       extern size_t getpagesize();
+#      define malloc_getpagesize getpagesize()
+#    else
+#      ifdef WIN32 /* use supplied emulation of getpagesize */
+#        define malloc_getpagesize getpagesize()
+#      else
+#        ifndef LACKS_SYS_PARAM_H
+#          include <sys/param.h>
+#        endif
+#        ifdef EXEC_PAGESIZE
+#          define malloc_getpagesize EXEC_PAGESIZE
+#        else
+#          ifdef NBPG
+#            ifndef CLSIZE
+#              define malloc_getpagesize NBPG
+#            else
+#              define malloc_getpagesize (NBPG * CLSIZE)
+#            endif
+#          else
+#            ifdef NBPC
+#              define malloc_getpagesize NBPC
+#            else
+#              ifdef PAGESIZE
+#                define malloc_getpagesize PAGESIZE
+#              else /* just guess */
+#                define malloc_getpagesize ((size_t)4096U)
+#              endif
+#            endif
+#          endif
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+#endif
+
+/* ------------------- size_t and alignment properties -------------------- */
+
+/* The byte and bit size of a size_t */
+#define SIZE_T_SIZE         (sizeof(size_t))
+#define SIZE_T_BITSIZE      (sizeof(size_t) << 3)
+
+/* Some constants coerced to size_t */
+/* Annoying but necessary to avoid errors on some plaftorms */
+#define SIZE_T_ZERO         ((size_t)0)
+#define SIZE_T_ONE          ((size_t)1)
+#define SIZE_T_TWO          ((size_t)2)
+#define TWO_SIZE_T_SIZES    (SIZE_T_SIZE<<1)
+#define FOUR_SIZE_T_SIZES   (SIZE_T_SIZE<<2)
+#define SIX_SIZE_T_SIZES    (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES)
+#define HALF_MAX_SIZE_T     (MAX_SIZE_T / 2U)
+
+/* The bit mask value corresponding to MALLOC_ALIGNMENT */
+#define CHUNK_ALIGN_MASK    (MALLOC_ALIGNMENT - SIZE_T_ONE)
+
+/* True if address a has acceptable alignment */
+#define is_aligned(A)       (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0)
+
+/* the number of bytes to offset an address to align it */
+#define align_offset(A)\
+ ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\
+  ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK))
+
+/* -------------------------- MMAP preliminaries ------------------------- */
+
+/*
+   If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and
+   checks to fail so compiler optimizer can delete code rather than
+   using so many "#if"s.
+*/
+
+
+/* MORECORE and MMAP must return MFAIL on failure */
+#define MFAIL                ((void*)(MAX_SIZE_T))
+#define CMFAIL               ((char*)(MFAIL)) /* defined for convenience */
+
+#if !HAVE_MMAP
+#define IS_MMAPPED_BIT       (SIZE_T_ZERO)
+#define USE_MMAP_BIT         (SIZE_T_ZERO)
+#define CALL_MMAP(s)         MFAIL
+#define CALL_MUNMAP(a, s)    (-1)
+#define DIRECT_MMAP(s)       MFAIL
+
+#else /* HAVE_MMAP */
+#define IS_MMAPPED_BIT       (SIZE_T_ONE)
+#define USE_MMAP_BIT         (SIZE_T_ONE)
+
+#if !defined(WIN32) && !defined (__OS2__)
+#define CALL_MUNMAP(a, s)    munmap((a), (s))
+#define MMAP_PROT            (PROT_READ|PROT_WRITE)
+#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
+#define MAP_ANONYMOUS        MAP_ANON
+#endif /* MAP_ANON */
+#ifdef MAP_ANONYMOUS
+#define MMAP_FLAGS           (MAP_PRIVATE|MAP_ANONYMOUS)
+#define CALL_MMAP(s)         mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0)
+#else /* MAP_ANONYMOUS */
+/*
+   Nearly all versions of mmap support MAP_ANONYMOUS, so the following
+   is unlikely to be needed, but is supplied just in case.
+*/
+#define MMAP_FLAGS           (MAP_PRIVATE)
+static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */
+#define CALL_MMAP(s) ((dev_zero_fd < 0) ? \
+           (dev_zero_fd = open("/dev/zero", O_RDWR), \
+            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \
+            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0))
+#endif /* MAP_ANONYMOUS */
+
+#define DIRECT_MMAP(s)       CALL_MMAP(s)
+
+#elif defined(__OS2__)
+
+/* OS/2 MMAP via DosAllocMem */
+static void* os2mmap(size_t size) {
+  void* ptr;
+  if (DosAllocMem(&ptr, size, OBJ_ANY|PAG_COMMIT|PAG_READ|PAG_WRITE) &&
+      DosAllocMem(&ptr, size, PAG_COMMIT|PAG_READ|PAG_WRITE))
+    return MFAIL;
+  return ptr;
+}
+
+#define os2direct_mmap(n)     os2mmap(n)
+
+/* This function supports releasing coalesed segments */
+static int os2munmap(void* ptr, size_t size) {
+  while (size) {
+    ULONG ulSize = size;
+    ULONG ulFlags = 0;
+    if (DosQueryMem(ptr, &ulSize, &ulFlags) != 0)
+      return -1;
+    if ((ulFlags & PAG_BASE) == 0 ||(ulFlags & PAG_COMMIT) == 0 ||
+        ulSize > size)
+      return -1;
+    if (DosFreeMem(ptr) != 0)
+      return -1;
+    ptr = ( void * ) ( ( char * ) ptr + ulSize );
+    size -= ulSize;
+  }
+  return 0;
+}
+
+#define CALL_MMAP(s)         os2mmap(s)
+#define CALL_MUNMAP(a, s)    os2munmap((a), (s))
+#define DIRECT_MMAP(s)       os2direct_mmap(s)
+
+#else /* WIN32 */
+
+/* Win32 MMAP via VirtualAlloc */
+static void* win32mmap(size_t size) {
+  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+  return (ptr != 0)? ptr: MFAIL;
+}
+
+/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
+static void* win32direct_mmap(size_t size) {
+  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
+                           PAGE_EXECUTE_READWRITE);
+  return (ptr != 0)? ptr: MFAIL;
+}
+
+/* This function supports releasing coalesed segments */
+static int win32munmap(void* ptr, size_t size) {
+  MEMORY_BASIC_INFORMATION minfo;
+  char* cptr = ptr;
+  while (size) {
+    if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0)
+      return -1;
+    if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr ||
+        minfo.State != MEM_COMMIT || minfo.RegionSize > size)
+      return -1;
+    if (VirtualFree(cptr, 0, MEM_RELEASE) == 0)
+      return -1;
+    cptr += minfo.RegionSize;
+    size -= minfo.RegionSize;
+  }
+  return 0;
+}
+
+#define CALL_MMAP(s)         win32mmap(s)
+#define CALL_MUNMAP(a, s)    win32munmap((a), (s))
+#define DIRECT_MMAP(s)       win32direct_mmap(s)
+#endif /* WIN32 */
+#endif /* HAVE_MMAP */
+
+#if HAVE_MMAP && HAVE_MREMAP
+#define CALL_MREMAP(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv))
+#else  /* HAVE_MMAP && HAVE_MREMAP */
+#define CALL_MREMAP(addr, osz, nsz, mv) MFAIL
+#endif /* HAVE_MMAP && HAVE_MREMAP */
+
+#if HAVE_MORECORE
+#define CALL_MORECORE(S)     MORECORE(S)
+#else  /* HAVE_MORECORE */
+#define CALL_MORECORE(S)     MFAIL
+#endif /* HAVE_MORECORE */
+
+/* mstate bit set if continguous morecore disabled or failed */
+#define USE_NONCONTIGUOUS_BIT (4U)
+
+/* segment bit set in create_mspace_with_base */
+#define EXTERN_BIT            (8U)
+
+
+/* --------------------------- Lock preliminaries ------------------------ */
+
+#if USE_LOCKS
+
+/*
+  When locks are defined, there are up to two global locks:
+
+  * If HAVE_MORECORE, morecore_mutex protects sequences of calls to
+    MORECORE.  In many cases sys_alloc requires two calls, that should
+    not be interleaved with calls by other threads.  This does not
+    protect against direct calls to MORECORE by other threads not
+    using this lock, so there is still code to cope the best we can on
+    interference.
+
+  * magic_init_mutex ensures that mparams.magic and other
+    unique mparams values are initialized only once.
+*/
+
+#if !defined(WIN32) && !defined(__OS2__)
+/* By default use posix locks */
+#include <pthread.h>
+#define MLOCK_T pthread_mutex_t
+#define INITIAL_LOCK(l)      pthread_mutex_init(l, NULL)
+#define ACQUIRE_LOCK(l)      pthread_mutex_lock(l)
+#define RELEASE_LOCK(l)      pthread_mutex_unlock(l)
+
+#if HAVE_MORECORE
+static MLOCK_T morecore_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif /* HAVE_MORECORE */
+
+static MLOCK_T magic_init_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+#elif defined(__OS2__)
+#define MLOCK_T HMTX
+#define INITIAL_LOCK(l)      DosCreateMutexSem(0, l, 0, FALSE)
+#define ACQUIRE_LOCK(l)      DosRequestMutexSem(*l, SEM_INDEFINITE_WAIT)
+#define RELEASE_LOCK(l)      DosReleaseMutexSem(*l)
+#if HAVE_MORECORE
+static MLOCK_T morecore_mutex;
+#endif /* HAVE_MORECORE */
+static MLOCK_T magic_init_mutex;
+
+#else /* WIN32 */
+/*
+   Because lock-protected regions have bounded times, and there
+   are no recursive lock calls, we can use simple spinlocks.
+*/
+
+#define MLOCK_T long
+static int win32_acquire_lock (MLOCK_T *sl) {
+  for (;;) {
+#ifdef InterlockedCompareExchangePointer
+    if (!InterlockedCompareExchange(sl, 1, 0))
+      return 0;
+#else  /* Use older void* version */
+    if (!InterlockedCompareExchange((void**)sl, (void*)1, (void*)0))
+      return 0;
+#endif /* InterlockedCompareExchangePointer */
+    Sleep (0);
+  }
+}
+
+static void win32_release_lock (MLOCK_T *sl) {
+  InterlockedExchange (sl, 0);
+}
+
+#define INITIAL_LOCK(l)      *(l)=0
+#define ACQUIRE_LOCK(l)      win32_acquire_lock(l)
+#define RELEASE_LOCK(l)      win32_release_lock(l)
+#if HAVE_MORECORE
+static MLOCK_T morecore_mutex;
+#endif /* HAVE_MORECORE */
+static MLOCK_T magic_init_mutex;
+#endif /* WIN32 */
+
+#define USE_LOCK_BIT               (2U)
+#else  /* USE_LOCKS */
+#define USE_LOCK_BIT               (0U)
+#define INITIAL_LOCK(l)
+#endif /* USE_LOCKS */
+
+#if USE_LOCKS && HAVE_MORECORE
+#define ACQUIRE_MORECORE_LOCK()    ACQUIRE_LOCK(&morecore_mutex);
+#define RELEASE_MORECORE_LOCK()    RELEASE_LOCK(&morecore_mutex);
+#else /* USE_LOCKS && HAVE_MORECORE */
+#define ACQUIRE_MORECORE_LOCK()
+#define RELEASE_MORECORE_LOCK()
+#endif /* USE_LOCKS && HAVE_MORECORE */
+
+#if USE_LOCKS
+#define ACQUIRE_MAGIC_INIT_LOCK()  ACQUIRE_LOCK(&magic_init_mutex);
+#define RELEASE_MAGIC_INIT_LOCK()  RELEASE_LOCK(&magic_init_mutex);
+#else  /* USE_LOCKS */
+#define ACQUIRE_MAGIC_INIT_LOCK()
+#define RELEASE_MAGIC_INIT_LOCK()
+#endif /* USE_LOCKS */
+
+
+/* -----------------------  Chunk representations ------------------------ */
+
+/*
+  (The following includes lightly edited explanations by Colin Plumb.)
+
+  The malloc_chunk declaration below is misleading (but accurate and
+  necessary).  It declares a "view" into memory allowing access to
+  necessary fields at known offsets from a given base.
+
+  Chunks of memory are maintained using a `boundary tag' method as
+  originally described by Knuth.  (See the paper by Paul Wilson
+  ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such
+  techniques.)  Sizes of free chunks are stored both in the front of
+  each chunk and at the end.  This makes consolidating fragmented
+  chunks into bigger chunks fast.  The head fields also hold bits
+  representing whether chunks are free or in use.
+
+  Here are some pictures to make it clearer.  They are "exploded" to
+  show that the state of a chunk can be thought of as extending from
+  the high 31 bits of the head field of its header through the
+  prev_foot and PINUSE_BIT bit of the following chunk header.
+
+  A chunk that's in use looks like:
+
+   chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           | Size of previous chunk (if P = 1)                             |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
+         | Size of this chunk                                         1| +-+
+   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |                                                               |
+         +-                                                             -+
+         |                                                               |
+         +-                                                             -+
+         |                                                               :
+         +-      size - sizeof(size_t) available payload bytes          -+
+         :                                                               |
+ chunk-> +-                                                             -+
+         |                                                               |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1|
+       | Size of next chunk (may or may not be in use)               | +-+
+ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+    And if it's free, it looks like this:
+
+   chunk-> +-                                                             -+
+           | User payload (must be in use, or we would have merged!)       |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
+         | Size of this chunk                                         0| +-+
+   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         | Next pointer                                                  |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         | Prev pointer                                                  |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |                                                               :
+         +-      size - sizeof(struct chunk) unused bytes               -+
+         :                                                               |
+ chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         | Size of this chunk                                            |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0|
+       | Size of next chunk (must be in use, or we would have merged)| +-+
+ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                                                               :
+       +- User payload                                                -+
+       :                                                               |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+                                                                     |0|
+                                                                     +-+
+  Note that since we always merge adjacent free chunks, the chunks
+  adjacent to a free chunk must be in use.
+
+  Given a pointer to a chunk (which can be derived trivially from the
+  payload pointer) we can, in O(1) time, find out whether the adjacent
+  chunks are free, and if so, unlink them from the lists that they
+  are on and merge them with the current chunk.
+
+  Chunks always begin on even word boundaries, so the mem portion
+  (which is returned to the user) is also on an even word boundary, and
+  thus at least double-word aligned.
+
+  The P (PINUSE_BIT) bit, stored in the unused low-order bit of the
+  chunk size (which is always a multiple of two words), is an in-use
+  bit for the *previous* chunk.  If that bit is *clear*, then the
+  word before the current chunk size contains the previous chunk
+  size, and can be used to find the front of the previous chunk.
+  The very first chunk allocated always has this bit set, preventing
+  access to non-existent (or non-owned) memory. If pinuse is set for
+  any given chunk, then you CANNOT determine the size of the
+  previous chunk, and might even get a memory addressing fault when
+  trying to do so.
+
+  The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of
+  the chunk size redundantly records whether the current chunk is
+  inuse. This redundancy enables usage checks within free and realloc,
+  and reduces indirection when freeing and consolidating chunks.
+
+  Each freshly allocated chunk must have both cinuse and pinuse set.
+  That is, each allocated chunk borders either a previously allocated
+  and still in-use chunk, or the base of its memory arena. This is
+  ensured by making all allocations from the the `lowest' part of any
+  found chunk.  Further, no free chunk physically borders another one,
+  so each free chunk is known to be preceded and followed by either
+  inuse chunks or the ends of memory.
+
+  Note that the `foot' of the current chunk is actually represented
+  as the prev_foot of the NEXT chunk. This makes it easier to
+  deal with alignments etc but can be very confusing when trying
+  to extend or adapt this code.
+
+  The exceptions to all this are
+
+     1. The special chunk `top' is the top-most available chunk (i.e.,
+        the one bordering the end of available memory). It is treated
+        specially.  Top is never included in any bin, is used only if
+        no other chunk is available, and is released back to the
+        system if it is very large (see M_TRIM_THRESHOLD).  In effect,
+        the top chunk is treated as larger (and thus less well
+        fitting) than any other available chunk.  The top chunk
+        doesn't update its trailing size field since there is no next
+        contiguous chunk that would have to index off it. However,
+        space is still allocated for it (TOP_FOOT_SIZE) to enable
+        separation or merging when space is extended.
+
+     3. Chunks allocated via mmap, which have the lowest-order bit
+        (IS_MMAPPED_BIT) set in their prev_foot fields, and do not set
+        PINUSE_BIT in their head fields.  Because they are allocated
+        one-by-one, each must carry its own prev_foot field, which is
+        also used to hold the offset this chunk has within its mmapped
+        region, which is needed to preserve alignment. Each mmapped
+        chunk is trailed by the first two fields of a fake next-chunk
+        for sake of usage checks.
+
+*/
+
+struct malloc_chunk {
+  size_t               prev_foot;  /* Size of previous chunk (if free).  */
+  size_t               head;       /* Size and inuse bits. */
+  struct malloc_chunk* fd;         /* double links -- used only if free. */
+  struct malloc_chunk* bk;
+};
+
+typedef struct malloc_chunk  mchunk;
+typedef struct malloc_chunk* mchunkptr;
+typedef struct malloc_chunk* sbinptr;  /* The type of bins of chunks */
+typedef unsigned int bindex_t;         /* Described below */
+typedef unsigned int binmap_t;         /* Described below */
+typedef unsigned int flag_t;           /* The type of various bit flag sets */
+
+/* ------------------- Chunks sizes and alignments ----------------------- */
+
+#define MCHUNK_SIZE         (sizeof(mchunk))
+
+#if FOOTERS
+#define CHUNK_OVERHEAD      (TWO_SIZE_T_SIZES)
+#else /* FOOTERS */
+#define CHUNK_OVERHEAD      (SIZE_T_SIZE)
+#endif /* FOOTERS */
+
+/* MMapped chunks need a second word of overhead ... */
+#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES)
+/* ... and additional padding for fake next-chunk at foot */
+#define MMAP_FOOT_PAD       (FOUR_SIZE_T_SIZES)
+
+/* The smallest size we can malloc is an aligned minimal chunk */
+#define MIN_CHUNK_SIZE\
+  ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
+
+/* conversion from malloc headers to user pointers, and back */
+#define chunk2mem(p)        ((void*)((char*)(p)       + TWO_SIZE_T_SIZES))
+#define mem2chunk(mem)      ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES))
+/* chunk associated with aligned address A */
+#define align_as_chunk(A)   (mchunkptr)((A) + align_offset(chunk2mem(A)))
+
+/* Bounds on request (not chunk) sizes. */
+#define MAX_REQUEST         ((-MIN_CHUNK_SIZE) << 2)
+#define MIN_REQUEST         (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE)
+
+/* pad request bytes into a usable size */
+#define pad_request(req) \
+   (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
+
+/* pad request, checking for minimum (but not maximum) */
+#define request2size(req) \
+  (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req))
+
+
+/* ------------------ Operations on head and foot fields ----------------- */
+
+/*
+  The head field of a chunk is or'ed with PINUSE_BIT when previous
+  adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in
+  use. If the chunk was obtained with mmap, the prev_foot field has
+  IS_MMAPPED_BIT set, otherwise holding the offset of the base of the
+  mmapped region to the base of the chunk.
+*/
+
+#define PINUSE_BIT          (SIZE_T_ONE)
+#define CINUSE_BIT          (SIZE_T_TWO)
+#define INUSE_BITS          (PINUSE_BIT|CINUSE_BIT)
+
+/* Head value for fenceposts */
+#define FENCEPOST_HEAD      (INUSE_BITS|SIZE_T_SIZE)
+
+/* extraction of fields from head words */
+#define cinuse(p)           ((p)->head & CINUSE_BIT)
+#define pinuse(p)           ((p)->head & PINUSE_BIT)
+#define chunksize(p)        ((p)->head & ~(INUSE_BITS))
+
+#define clear_pinuse(p)     ((p)->head &= ~PINUSE_BIT)
+#define clear_cinuse(p)     ((p)->head &= ~CINUSE_BIT)
+
+/* Treat space at ptr +/- offset as a chunk */
+#define chunk_plus_offset(p, s)  ((mchunkptr)(((char*)(p)) + (s)))
+#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s)))
+
+/* Ptr to next or previous physical malloc_chunk. */
+#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~INUSE_BITS)))
+#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) ))
+
+/* extract next chunk's pinuse bit */
+#define next_pinuse(p)  ((next_chunk(p)->head) & PINUSE_BIT)
+
+/* Get/set size at footer */
+#define get_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot)
+#define set_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s))
+
+/* Set size, pinuse bit, and foot */
+#define set_size_and_pinuse_of_free_chunk(p, s)\
+  ((p)->head = (s|PINUSE_BIT), set_foot(p, s))
+
+/* Set size, pinuse bit, foot, and clear next pinuse */
+#define set_free_with_pinuse(p, s, n)\
+  (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s))
+
+#define is_mmapped(p)\
+  (!((p)->head & PINUSE_BIT) && ((p)->prev_foot & IS_MMAPPED_BIT))
+
+/* Get the internal overhead associated with chunk p */
+#define overhead_for(p)\
+ (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD)
+
+/* Return true if malloced space is not necessarily cleared */
+#if MMAP_CLEARS
+#define calloc_must_clear(p) (!is_mmapped(p))
+#else /* MMAP_CLEARS */
+#define calloc_must_clear(p) (1)
+#endif /* MMAP_CLEARS */
+
+/* ---------------------- Overlaid data structures ----------------------- */
+
+/*
+  When chunks are not in use, they are treated as nodes of either
+  lists or trees.
+
+  "Small"  chunks are stored in circular doubly-linked lists, and look
+  like this:
+
+    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Size of previous chunk                            |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    `head:' |             Size of chunk, in bytes                         |P|
+      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Forward pointer to next chunk in list             |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Back pointer to previous chunk in list            |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Unused space (may be 0 bytes long)                .
+            .                                                               .
+            .                                                               |
+nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    `foot:' |             Size of chunk, in bytes                           |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+  Larger chunks are kept in a form of bitwise digital trees (aka
+  tries) keyed on chunksizes.  Because malloc_tree_chunks are only for
+  free chunks greater than 256 bytes, their size doesn't impose any
+  constraints on user chunk sizes.  Each node looks like:
+
+    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Size of previous chunk                            |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    `head:' |             Size of chunk, in bytes                         |P|
+      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Forward pointer to next chunk of same size        |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Back pointer to previous chunk of same size       |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Pointer to left child (child[0])                  |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Pointer to right child (child[1])                 |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Pointer to parent                                 |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             bin index of this chunk                           |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Unused space                                      .
+            .                                                               |
+nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    `foot:' |             Size of chunk, in bytes                           |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+  Each tree holding treenodes is a tree of unique chunk sizes.  Chunks
+  of the same size are arranged in a circularly-linked list, with only
+  the oldest chunk (the next to be used, in our FIFO ordering)
+  actually in the tree.  (Tree members are distinguished by a non-null
+  parent pointer.)  If a chunk with the same size an an existing node
+  is inserted, it is linked off the existing node using pointers that
+  work in the same way as fd/bk pointers of small chunks.
+
+  Each tree contains a power of 2 sized range of chunk sizes (the
+  smallest is 0x100 <= x < 0x180), which is is divided in half at each
+  tree level, with the chunks in the smaller half of the range (0x100
+  <= x < 0x140 for the top nose) in the left subtree and the larger
+  half (0x140 <= x < 0x180) in the right subtree.  This is, of course,
+  done by inspecting individual bits.
+
+  Using these rules, each node's left subtree contains all smaller
+  sizes than its right subtree.  However, the node at the root of each
+  subtree has no particular ordering relationship to either.  (The
+  dividing line between the subtree sizes is based on trie relation.)
+  If we remove the last chunk of a given size from the interior of the
+  tree, we need to replace it with a leaf node.  The tree ordering
+  rules permit a node to be replaced by any leaf below it.
+
+  The smallest chunk in a tree (a common operation in a best-fit
+  allocator) can be found by walking a path to the leftmost leaf in
+  the tree.  Unlike a usual binary tree, where we follow left child
+  pointers until we reach a null, here we follow the right child
+  pointer any time the left one is null, until we reach a leaf with
+  both child pointers null. The smallest chunk in the tree will be
+  somewhere along that path.
+
+  The worst case number of steps to add, find, or remove a node is
+  bounded by the number of bits differentiating chunks within
+  bins. Under current bin calculations, this ranges from 6 up to 21
+  (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case
+  is of course much better.
+*/
+
+struct malloc_tree_chunk {
+  /* The first four fields must be compatible with malloc_chunk */
+  size_t                    prev_foot;
+  size_t                    head;
+  struct malloc_tree_chunk* fd;
+  struct malloc_tree_chunk* bk;
+
+  struct malloc_tree_chunk* child[2];
+  struct malloc_tree_chunk* parent;
+  bindex_t                  index;
+};
+
+typedef struct malloc_tree_chunk  tchunk;
+typedef struct malloc_tree_chunk* tchunkptr;
+typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */
+
+/* A little helper macro for trees */
+#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1])
+
+/* ----------------------------- Segments -------------------------------- */
+
+/*
+  Each malloc space may include non-contiguous segments, held in a
+  list headed by an embedded malloc_segment record representing the
+  top-most space. Segments also include flags holding properties of
+  the space. Large chunks that are directly allocated by mmap are not
+  included in this list. They are instead independently created and
+  destroyed without otherwise keeping track of them.
+
+  Segment management mainly comes into play for spaces allocated by
+  MMAP.  Any call to MMAP might or might not return memory that is
+  adjacent to an existing segment.  MORECORE normally contiguously
+  extends the current space, so this space is almost always adjacent,
+  which is simpler and faster to deal with. (This is why MORECORE is
+  used preferentially to MMAP when both are available -- see
+  sys_alloc.)  When allocating using MMAP, we don't use any of the
+  hinting mechanisms (inconsistently) supported in various
+  implementations of unix mmap, or distinguish reserving from
+  committing memory. Instead, we just ask for space, and exploit
+  contiguity when we get it.  It is probably possible to do
+  better than this on some systems, but no general scheme seems
+  to be significantly better.
+
+  Management entails a simpler variant of the consolidation scheme
+  used for chunks to reduce fragmentation -- new adjacent memory is
+  normally prepended or appended to an existing segment. However,
+  there are limitations compared to chunk consolidation that mostly
+  reflect the fact that segment processing is relatively infrequent
+  (occurring only when getting memory from system) and that we
+  don't expect to have huge numbers of segments:
+
+  * Segments are not indexed, so traversal requires linear scans.  (It
+    would be possible to index these, but is not worth the extra
+    overhead and complexity for most programs on most platforms.)
+  * New segments are only appended to old ones when holding top-most
+    memory; if they cannot be prepended to others, they are held in
+    different segments.
+
+  Except for the top-most segment of an mstate, each segment record
+  is kept at the tail of its segment. Segments are added by pushing
+  segment records onto the list headed by &mstate.seg for the
+  containing mstate.
+
+  Segment flags control allocation/merge/deallocation policies:
+  * If EXTERN_BIT set, then we did not allocate this segment,
+    and so should not try to deallocate or merge with others.
+    (This currently holds only for the initial segment passed
+    into create_mspace_with_base.)
+  * If IS_MMAPPED_BIT set, the segment may be merged with
+    other surrounding mmapped segments and trimmed/de-allocated
+    using munmap.
+  * If neither bit is set, then the segment was obtained using
+    MORECORE so can be merged with surrounding MORECORE'd segments
+    and deallocated/trimmed using MORECORE with negative arguments.
+*/
+
+struct malloc_segment {
+  char*        base;             /* base address */
+  size_t       size;             /* allocated size */
+  struct malloc_segment* next;   /* ptr to next segment */
+#if FFI_MMAP_EXEC_WRIT
+  /* The mmap magic is supposed to store the address of the executable
+     segment at the very end of the requested block.  */
+
+# define mmap_exec_offset(b,s) (*(ptrdiff_t*)((b)+(s)-sizeof(ptrdiff_t)))
+
+  /* We can only merge segments if their corresponding executable
+     segments are at identical offsets.  */
+# define check_segment_merge(S,b,s) \
+  (mmap_exec_offset((b),(s)) == (S)->exec_offset)
+
+# define add_segment_exec_offset(p,S) ((char*)(p) + (S)->exec_offset)
+# define sub_segment_exec_offset(p,S) ((char*)(p) - (S)->exec_offset)
+
+  /* The removal of sflags only works with HAVE_MORECORE == 0.  */
+
+# define get_segment_flags(S)   (IS_MMAPPED_BIT)
+# define set_segment_flags(S,v) \
+  (((v) != IS_MMAPPED_BIT) ? (ABORT, (v)) :				\
+   (((S)->exec_offset =							\
+     mmap_exec_offset((S)->base, (S)->size)),				\
+    (mmap_exec_offset((S)->base + (S)->exec_offset, (S)->size) !=	\
+     (S)->exec_offset) ? (ABORT, (v)) :					\
+   (mmap_exec_offset((S)->base, (S)->size) = 0), (v)))
+
+  /* We use an offset here, instead of a pointer, because then, when
+     base changes, we don't have to modify this.  On architectures
+     with segmented addresses, this might not work.  */
+  ptrdiff_t    exec_offset;
+#else
+
+# define get_segment_flags(S)   ((S)->sflags)
+# define set_segment_flags(S,v) ((S)->sflags = (v))
+# define check_segment_merge(S,b,s) (1)
+
+  flag_t       sflags;           /* mmap and extern flag */
+#endif
+};
+
+#define is_mmapped_segment(S)  (get_segment_flags(S) & IS_MMAPPED_BIT)
+#define is_extern_segment(S)   (get_segment_flags(S) & EXTERN_BIT)
+
+typedef struct malloc_segment  msegment;
+typedef struct malloc_segment* msegmentptr;
+
+/* ---------------------------- malloc_state ----------------------------- */
+
+/*
+   A malloc_state holds all of the bookkeeping for a space.
+   The main fields are:
+
+  Top
+    The topmost chunk of the currently active segment. Its size is
+    cached in topsize.  The actual size of topmost space is
+    topsize+TOP_FOOT_SIZE, which includes space reserved for adding
+    fenceposts and segment records if necessary when getting more
+    space from the system.  The size at which to autotrim top is
+    cached from mparams in trim_check, except that it is disabled if
+    an autotrim fails.
+
+  Designated victim (dv)
+    This is the preferred chunk for servicing small requests that
+    don't have exact fits.  It is normally the chunk split off most
+    recently to service another small request.  Its size is cached in
+    dvsize. The link fields of this chunk are not maintained since it
+    is not kept in a bin.
+
+  SmallBins
+    An array of bin headers for free chunks.  These bins hold chunks
+    with sizes less than MIN_LARGE_SIZE bytes. Each bin contains
+    chunks of all the same size, spaced 8 bytes apart.  To simplify
+    use in double-linked lists, each bin header acts as a malloc_chunk
+    pointing to the real first node, if it exists (else pointing to
+    itself).  This avoids special-casing for headers.  But to avoid
+    waste, we allocate only the fd/bk pointers of bins, and then use
+    repositioning tricks to treat these as the fields of a chunk.
+
+  TreeBins
+    Treebins are pointers to the roots of trees holding a range of
+    sizes. There are 2 equally spaced treebins for each power of two
+    from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything
+    larger.
+
+  Bin maps
+    There is one bit map for small bins ("smallmap") and one for
+    treebins ("treemap).  Each bin sets its bit when non-empty, and
+    clears the bit when empty.  Bit operations are then used to avoid
+    bin-by-bin searching -- nearly all "search" is done without ever
+    looking at bins that won't be selected.  The bit maps
+    conservatively use 32 bits per map word, even if on 64bit system.
+    For a good description of some of the bit-based techniques used
+    here, see Henry S. Warren Jr's book "Hacker's Delight" (and
+    supplement at http://hackersdelight.org/). Many of these are
+    intended to reduce the branchiness of paths through malloc etc, as
+    well as to reduce the number of memory locations read or written.
+
+  Segments
+    A list of segments headed by an embedded malloc_segment record
+    representing the initial space.
+
+  Address check support
+    The least_addr field is the least address ever obtained from
+    MORECORE or MMAP. Attempted frees and reallocs of any address less
+    than this are trapped (unless INSECURE is defined).
+
+  Magic tag
+    A cross-check field that should always hold same value as mparams.magic.
+
+  Flags
+    Bits recording whether to use MMAP, locks, or contiguous MORECORE
+
+  Statistics
+    Each space keeps track of current and maximum system memory
+    obtained via MORECORE or MMAP.
+
+  Locking
+    If USE_LOCKS is defined, the "mutex" lock is acquired and released
+    around every public call using this mspace.
+*/
+
+/* Bin types, widths and sizes */
+#define NSMALLBINS        (32U)
+#define NTREEBINS         (32U)
+#define SMALLBIN_SHIFT    (3U)
+#define SMALLBIN_WIDTH    (SIZE_T_ONE << SMALLBIN_SHIFT)
+#define TREEBIN_SHIFT     (8U)
+#define MIN_LARGE_SIZE    (SIZE_T_ONE << TREEBIN_SHIFT)
+#define MAX_SMALL_SIZE    (MIN_LARGE_SIZE - SIZE_T_ONE)
+#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD)
+
+struct malloc_state {
+  binmap_t   smallmap;
+  binmap_t   treemap;
+  size_t     dvsize;
+  size_t     topsize;
+  char*      least_addr;
+  mchunkptr  dv;
+  mchunkptr  top;
+  size_t     trim_check;
+  size_t     magic;
+  mchunkptr  smallbins[(NSMALLBINS+1)*2];
+  tbinptr    treebins[NTREEBINS];
+  size_t     footprint;
+  size_t     max_footprint;
+  flag_t     mflags;
+#if USE_LOCKS
+  MLOCK_T    mutex;     /* locate lock among fields that rarely change */
+#endif /* USE_LOCKS */
+  msegment   seg;
+};
+
+typedef struct malloc_state*    mstate;
+
+/* ------------- Global malloc_state and malloc_params ------------------- */
+
+/*
+  malloc_params holds global properties, including those that can be
+  dynamically set using mallopt. There is a single instance, mparams,
+  initialized in init_mparams.
+*/
+
+struct malloc_params {
+  size_t magic;
+  size_t page_size;
+  size_t granularity;
+  size_t mmap_threshold;
+  size_t trim_threshold;
+  flag_t default_mflags;
+};
+
+static struct malloc_params mparams;
+
+/* The global malloc_state used for all non-"mspace" calls */
+static struct malloc_state _gm_;
+#define gm                 (&_gm_)
+#define is_global(M)       ((M) == &_gm_)
+#define is_initialized(M)  ((M)->top != 0)
+
+/* -------------------------- system alloc setup ------------------------- */
+
+/* Operations on mflags */
+
+#define use_lock(M)           ((M)->mflags &   USE_LOCK_BIT)
+#define enable_lock(M)        ((M)->mflags |=  USE_LOCK_BIT)
+#define disable_lock(M)       ((M)->mflags &= ~USE_LOCK_BIT)
+
+#define use_mmap(M)           ((M)->mflags &   USE_MMAP_BIT)
+#define enable_mmap(M)        ((M)->mflags |=  USE_MMAP_BIT)
+#define disable_mmap(M)       ((M)->mflags &= ~USE_MMAP_BIT)
+
+#define use_noncontiguous(M)  ((M)->mflags &   USE_NONCONTIGUOUS_BIT)
+#define disable_contiguous(M) ((M)->mflags |=  USE_NONCONTIGUOUS_BIT)
+
+#define set_lock(M,L)\
+ ((M)->mflags = (L)?\
+  ((M)->mflags | USE_LOCK_BIT) :\
+  ((M)->mflags & ~USE_LOCK_BIT))
+
+/* page-align a size */
+#define page_align(S)\
+ (((S) + (mparams.page_size)) & ~(mparams.page_size - SIZE_T_ONE))
+
+/* granularity-align a size */
+#define granularity_align(S)\
+  (((S) + (mparams.granularity)) & ~(mparams.granularity - SIZE_T_ONE))
+
+#define is_page_aligned(S)\
+   (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0)
+#define is_granularity_aligned(S)\
+   (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0)
+
+/*  True if segment S holds address A */
+#define segment_holds(S, A)\
+  ((char*)(A) >= S->base && (char*)(A) < S->base + S->size)
+
+/* Return segment holding given address */
+static msegmentptr segment_holding(mstate m, char* addr) {
+  msegmentptr sp = &m->seg;
+  for (;;) {
+    if (addr >= sp->base && addr < sp->base + sp->size)
+      return sp;
+    if ((sp = sp->next) == 0)
+      return 0;
+  }
+}
+
+/* Return true if segment contains a segment link */
+static int has_segment_link(mstate m, msegmentptr ss) {
+  msegmentptr sp = &m->seg;
+  for (;;) {
+    if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size)
+      return 1;
+    if ((sp = sp->next) == 0)
+      return 0;
+  }
+}
+
+#ifndef MORECORE_CANNOT_TRIM
+#define should_trim(M,s)  ((s) > (M)->trim_check)
+#else  /* MORECORE_CANNOT_TRIM */
+#define should_trim(M,s)  (0)
+#endif /* MORECORE_CANNOT_TRIM */
+
+/*
+  TOP_FOOT_SIZE is padding at the end of a segment, including space
+  that may be needed to place segment records and fenceposts when new
+  noncontiguous segments are added.
+*/
+#define TOP_FOOT_SIZE\
+  (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE)
+
+
+/* -------------------------------  Hooks -------------------------------- */
+
+/*
+  PREACTION should be defined to return 0 on success, and nonzero on
+  failure. If you are not using locking, you can redefine these to do
+  anything you like.
+*/
+
+#if USE_LOCKS
+
+/* Ensure locks are initialized */
+#define GLOBALLY_INITIALIZE() (mparams.page_size == 0 && init_mparams())
+
+#define PREACTION(M)  ((GLOBALLY_INITIALIZE() || use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0)
+#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); }
+#else /* USE_LOCKS */
+
+#ifndef PREACTION
+#define PREACTION(M) (0)
+#endif  /* PREACTION */
+
+#ifndef POSTACTION
+#define POSTACTION(M)
+#endif  /* POSTACTION */
+
+#endif /* USE_LOCKS */
+
+/*
+  CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses.
+  USAGE_ERROR_ACTION is triggered on detected bad frees and
+  reallocs. The argument p is an address that might have triggered the
+  fault. It is ignored by the two predefined actions, but might be
+  useful in custom actions that try to help diagnose errors.
+*/
+
+#if PROCEED_ON_ERROR
+
+/* A count of the number of corruption errors causing resets */
+int malloc_corruption_error_count;
+
+/* default corruption action */
+static void reset_on_error(mstate m);
+
+#define CORRUPTION_ERROR_ACTION(m)  reset_on_error(m)
+#define USAGE_ERROR_ACTION(m, p)
+
+#else /* PROCEED_ON_ERROR */
+
+#ifndef CORRUPTION_ERROR_ACTION
+#define CORRUPTION_ERROR_ACTION(m) ABORT
+#endif /* CORRUPTION_ERROR_ACTION */
+
+#ifndef USAGE_ERROR_ACTION
+#define USAGE_ERROR_ACTION(m,p) ABORT
+#endif /* USAGE_ERROR_ACTION */
+
+#endif /* PROCEED_ON_ERROR */
+
+/* -------------------------- Debugging setup ---------------------------- */
+
+#if ! DEBUG
+
+#define check_free_chunk(M,P)
+#define check_inuse_chunk(M,P)
+#define check_malloced_chunk(M,P,N)
+#define check_mmapped_chunk(M,P)
+#define check_malloc_state(M)
+#define check_top_chunk(M,P)
+
+#else /* DEBUG */
+#define check_free_chunk(M,P)       do_check_free_chunk(M,P)
+#define check_inuse_chunk(M,P)      do_check_inuse_chunk(M,P)
+#define check_top_chunk(M,P)        do_check_top_chunk(M,P)
+#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N)
+#define check_mmapped_chunk(M,P)    do_check_mmapped_chunk(M,P)
+#define check_malloc_state(M)       do_check_malloc_state(M)
+
+static void   do_check_any_chunk(mstate m, mchunkptr p);
+static void   do_check_top_chunk(mstate m, mchunkptr p);
+static void   do_check_mmapped_chunk(mstate m, mchunkptr p);
+static void   do_check_inuse_chunk(mstate m, mchunkptr p);
+static void   do_check_free_chunk(mstate m, mchunkptr p);
+static void   do_check_malloced_chunk(mstate m, void* mem, size_t s);
+static void   do_check_tree(mstate m, tchunkptr t);
+static void   do_check_treebin(mstate m, bindex_t i);
+static void   do_check_smallbin(mstate m, bindex_t i);
+static void   do_check_malloc_state(mstate m);
+static int    bin_find(mstate m, mchunkptr x);
+static size_t traverse_and_check(mstate m);
+#endif /* DEBUG */
+
+/* ---------------------------- Indexing Bins ---------------------------- */
+
+#define is_small(s)         (((s) >> SMALLBIN_SHIFT) < NSMALLBINS)
+#define small_index(s)      ((s)  >> SMALLBIN_SHIFT)
+#define small_index2size(i) ((i)  << SMALLBIN_SHIFT)
+#define MIN_SMALL_INDEX     (small_index(MIN_CHUNK_SIZE))
+
+/* addressing by index. See above about smallbin repositioning */
+#define smallbin_at(M, i)   ((sbinptr)((char*)&((M)->smallbins[(i)<<1])))
+#define treebin_at(M,i)     (&((M)->treebins[i]))
+
+/* assign tree index for size S to variable I */
+#if defined(__GNUC__) && defined(i386)
+#define compute_tree_index(S, I)\
+{\
+  size_t X = S >> TREEBIN_SHIFT;\
+  if (X == 0)\
+    I = 0;\
+  else if (X > 0xFFFF)\
+    I = NTREEBINS-1;\
+  else {\
+    unsigned int K;\
+    __asm__("bsrl %1,%0\n\t" : "=r" (K) : "rm"  (X));\
+    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
+  }\
+}
+#else /* GNUC */
+#define compute_tree_index(S, I)\
+{\
+  size_t X = S >> TREEBIN_SHIFT;\
+  if (X == 0)\
+    I = 0;\
+  else if (X > 0xFFFF)\
+    I = NTREEBINS-1;\
+  else {\
+    unsigned int Y = (unsigned int)X;\
+    unsigned int N = ((Y - 0x100) >> 16) & 8;\
+    unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\
+    N += K;\
+    N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\
+    K = 14 - N + ((Y <<= K) >> 15);\
+    I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\
+  }\
+}
+#endif /* GNUC */
+
+/* Bit representing maximum resolved size in a treebin at i */
+#define bit_for_tree_index(i) \
+   (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2)
+
+/* Shift placing maximum resolved bit in a treebin at i as sign bit */
+#define leftshift_for_tree_index(i) \
+   ((i == NTREEBINS-1)? 0 : \
+    ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2)))
+
+/* The size of the smallest chunk held in bin with index i */
+#define minsize_for_tree_index(i) \
+   ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) |  \
+   (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1)))
+
+
+/* ------------------------ Operations on bin maps ----------------------- */
+
+/* bit corresponding to given index */
+#define idx2bit(i)              ((binmap_t)(1) << (i))
+
+/* Mark/Clear bits with given index */
+#define mark_smallmap(M,i)      ((M)->smallmap |=  idx2bit(i))
+#define clear_smallmap(M,i)     ((M)->smallmap &= ~idx2bit(i))
+#define smallmap_is_marked(M,i) ((M)->smallmap &   idx2bit(i))
+
+#define mark_treemap(M,i)       ((M)->treemap  |=  idx2bit(i))
+#define clear_treemap(M,i)      ((M)->treemap  &= ~idx2bit(i))
+#define treemap_is_marked(M,i)  ((M)->treemap  &   idx2bit(i))
+
+/* index corresponding to given bit */
+
+#if defined(__GNUC__) && defined(i386)
+#define compute_bit2idx(X, I)\
+{\
+  unsigned int J;\
+  __asm__("bsfl %1,%0\n\t" : "=r" (J) : "rm" (X));\
+  I = (bindex_t)J;\
+}
+
+#else /* GNUC */
+#if  USE_BUILTIN_FFS
+#define compute_bit2idx(X, I) I = ffs(X)-1
+
+#else /* USE_BUILTIN_FFS */
+#define compute_bit2idx(X, I)\
+{\
+  unsigned int Y = X - 1;\
+  unsigned int K = Y >> (16-4) & 16;\
+  unsigned int N = K;        Y >>= K;\
+  N += K = Y >> (8-3) &  8;  Y >>= K;\
+  N += K = Y >> (4-2) &  4;  Y >>= K;\
+  N += K = Y >> (2-1) &  2;  Y >>= K;\
+  N += K = Y >> (1-0) &  1;  Y >>= K;\
+  I = (bindex_t)(N + Y);\
+}
+#endif /* USE_BUILTIN_FFS */
+#endif /* GNUC */
+
+/* isolate the least set bit of a bitmap */
+#define least_bit(x)         ((x) & -(x))
+
+/* mask with all bits to left of least bit of x on */
+#define left_bits(x)         ((x<<1) | -(x<<1))
+
+/* mask with all bits to left of or equal to least bit of x on */
+#define same_or_left_bits(x) ((x) | -(x))
+
+
+/* ----------------------- Runtime Check Support ------------------------- */
+
+/*
+  For security, the main invariant is that malloc/free/etc never
+  writes to a static address other than malloc_state, unless static
+  malloc_state itself has been corrupted, which cannot occur via
+  malloc (because of these checks). In essence this means that we
+  believe all pointers, sizes, maps etc held in malloc_state, but
+  check all of those linked or offsetted from other embedded data
+  structures.  These checks are interspersed with main code in a way
+  that tends to minimize their run-time cost.
+
+  When FOOTERS is defined, in addition to range checking, we also
+  verify footer fields of inuse chunks, which can be used guarantee
+  that the mstate controlling malloc/free is intact.  This is a
+  streamlined version of the approach described by William Robertson
+  et al in "Run-time Detection of Heap-based Overflows" LISA'03
+  http://www.usenix.org/events/lisa03/tech/robertson.html The footer
+  of an inuse chunk holds the xor of its mstate and a random seed,
+  that is checked upon calls to free() and realloc().  This is
+  (probablistically) unguessable from outside the program, but can be
+  computed by any code successfully malloc'ing any chunk, so does not
+  itself provide protection against code that has already broken
+  security through some other means.  Unlike Robertson et al, we
+  always dynamically check addresses of all offset chunks (previous,
+  next, etc). This turns out to be cheaper than relying on hashes.
+*/
+
+#if !INSECURE
+/* Check if address a is at least as high as any from MORECORE or MMAP */
+#define ok_address(M, a) ((char*)(a) >= (M)->least_addr)
+/* Check if address of next chunk n is higher than base chunk p */
+#define ok_next(p, n)    ((char*)(p) < (char*)(n))
+/* Check if p has its cinuse bit on */
+#define ok_cinuse(p)     cinuse(p)
+/* Check if p has its pinuse bit on */
+#define ok_pinuse(p)     pinuse(p)
+
+#else /* !INSECURE */
+#define ok_address(M, a) (1)
+#define ok_next(b, n)    (1)
+#define ok_cinuse(p)     (1)
+#define ok_pinuse(p)     (1)
+#endif /* !INSECURE */
+
+#if (FOOTERS && !INSECURE)
+/* Check if (alleged) mstate m has expected magic field */
+#define ok_magic(M)      ((M)->magic == mparams.magic)
+#else  /* (FOOTERS && !INSECURE) */
+#define ok_magic(M)      (1)
+#endif /* (FOOTERS && !INSECURE) */
+
+
+/* In gcc, use __builtin_expect to minimize impact of checks */
+#if !INSECURE
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define RTCHECK(e)  __builtin_expect(e, 1)
+#else /* GNUC */
+#define RTCHECK(e)  (e)
+#endif /* GNUC */
+#else /* !INSECURE */
+#define RTCHECK(e)  (1)
+#endif /* !INSECURE */
+
+/* macros to set up inuse chunks with or without footers */
+
+#if !FOOTERS
+
+#define mark_inuse_foot(M,p,s)
+
+/* Set cinuse bit and pinuse bit of next chunk */
+#define set_inuse(M,p,s)\
+  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
+  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
+
+/* Set cinuse and pinuse of this chunk and pinuse of next chunk */
+#define set_inuse_and_pinuse(M,p,s)\
+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
+  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
+
+/* Set size, cinuse and pinuse bit of this chunk */
+#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT))
+
+#else /* FOOTERS */
+
+/* Set foot of inuse chunk to be xor of mstate and seed */
+#define mark_inuse_foot(M,p,s)\
+  (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic))
+
+#define get_mstate_for(p)\
+  ((mstate)(((mchunkptr)((char*)(p) +\
+    (chunksize(p))))->prev_foot ^ mparams.magic))
+
+#define set_inuse(M,p,s)\
+  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
+  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \
+  mark_inuse_foot(M,p,s))
+
+#define set_inuse_and_pinuse(M,p,s)\
+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
+  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\
+ mark_inuse_foot(M,p,s))
+
+#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
+  mark_inuse_foot(M, p, s))
+
+#endif /* !FOOTERS */
+
+/* ---------------------------- setting mparams -------------------------- */
+
+/* Initialize mparams */
+static int init_mparams(void) {
+  if (mparams.page_size == 0) {
+    size_t s;
+
+    mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
+    mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD;
+#if MORECORE_CONTIGUOUS
+    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT;
+#else  /* MORECORE_CONTIGUOUS */
+    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT;
+#endif /* MORECORE_CONTIGUOUS */
+
+#if (FOOTERS && !INSECURE)
+    {
+#if USE_DEV_RANDOM
+      int fd;
+      unsigned char buf[sizeof(size_t)];
+      /* Try to use /dev/urandom, else fall back on using time */
+      if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 &&
+          read(fd, buf, sizeof(buf)) == sizeof(buf)) {
+        s = *((size_t *) buf);
+        close(fd);
+      }
+      else
+#endif /* USE_DEV_RANDOM */
+        s = (size_t)(time(0) ^ (size_t)0x55555555U);
+
+      s |= (size_t)8U;    /* ensure nonzero */
+      s &= ~(size_t)7U;   /* improve chances of fault for bad values */
+
+    }
+#else /* (FOOTERS && !INSECURE) */
+    s = (size_t)0x58585858U;
+#endif /* (FOOTERS && !INSECURE) */
+    ACQUIRE_MAGIC_INIT_LOCK();
+    if (mparams.magic == 0) {
+      mparams.magic = s;
+      /* Set up lock for main malloc area */
+      INITIAL_LOCK(&gm->mutex);
+      gm->mflags = mparams.default_mflags;
+    }
+    RELEASE_MAGIC_INIT_LOCK();
+
+#if !defined(WIN32) && !defined(__OS2__)
+    mparams.page_size = malloc_getpagesize;
+    mparams.granularity = ((DEFAULT_GRANULARITY != 0)?
+                           DEFAULT_GRANULARITY : mparams.page_size);
+#elif defined (__OS2__)
+ /* if low-memory is used, os2munmap() would break
+    if it were anything other than 64k */
+    mparams.page_size = 4096u;
+    mparams.granularity = 65536u;
+#else /* WIN32 */
+    {
+      SYSTEM_INFO system_info;
+      GetSystemInfo(&system_info);
+      mparams.page_size = system_info.dwPageSize;
+      mparams.granularity = system_info.dwAllocationGranularity;
+    }
+#endif /* WIN32 */
+
+    /* Sanity-check configuration:
+       size_t must be unsigned and as wide as pointer type.
+       ints must be at least 4 bytes.
+       alignment must be at least 8.
+       Alignment, min chunk size, and page size must all be powers of 2.
+    */
+    if ((sizeof(size_t) != sizeof(char*)) ||
+        (MAX_SIZE_T < MIN_CHUNK_SIZE)  ||
+        (sizeof(int) < 4)  ||
+        (MALLOC_ALIGNMENT < (size_t)8U) ||
+        ((MALLOC_ALIGNMENT    & (MALLOC_ALIGNMENT-SIZE_T_ONE))    != 0) ||
+        ((MCHUNK_SIZE         & (MCHUNK_SIZE-SIZE_T_ONE))         != 0) ||
+        ((mparams.granularity & (mparams.granularity-SIZE_T_ONE)) != 0) ||
+        ((mparams.page_size   & (mparams.page_size-SIZE_T_ONE))   != 0))
+      ABORT;
+  }
+  return 0;
+}
+
+/* support for mallopt */
+static int change_mparam(int param_number, int value) {
+  size_t val = (size_t)value;
+  init_mparams();
+  switch(param_number) {
+  case M_TRIM_THRESHOLD:
+    mparams.trim_threshold = val;
+    return 1;
+  case M_GRANULARITY:
+    if (val >= mparams.page_size && ((val & (val-1)) == 0)) {
+      mparams.granularity = val;
+      return 1;
+    }
+    else
+      return 0;
+  case M_MMAP_THRESHOLD:
+    mparams.mmap_threshold = val;
+    return 1;
+  default:
+    return 0;
+  }
+}
+
+#if DEBUG
+/* ------------------------- Debugging Support --------------------------- */
+
+/* Check properties of any chunk, whether free, inuse, mmapped etc  */
+static void do_check_any_chunk(mstate m, mchunkptr p) {
+  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
+  assert(ok_address(m, p));
+}
+
+/* Check properties of top chunk */
+static void do_check_top_chunk(mstate m, mchunkptr p) {
+  msegmentptr sp = segment_holding(m, (char*)p);
+  size_t  sz = chunksize(p);
+  assert(sp != 0);
+  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
+  assert(ok_address(m, p));
+  assert(sz == m->topsize);
+  assert(sz > 0);
+  assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE);
+  assert(pinuse(p));
+  assert(!next_pinuse(p));
+}
+
+/* Check properties of (inuse) mmapped chunks */
+static void do_check_mmapped_chunk(mstate m, mchunkptr p) {
+  size_t  sz = chunksize(p);
+  size_t len = (sz + (p->prev_foot & ~IS_MMAPPED_BIT) + MMAP_FOOT_PAD);
+  assert(is_mmapped(p));
+  assert(use_mmap(m));
+  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
+  assert(ok_address(m, p));
+  assert(!is_small(sz));
+  assert((len & (mparams.page_size-SIZE_T_ONE)) == 0);
+  assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD);
+  assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0);
+}
+
+/* Check properties of inuse chunks */
+static void do_check_inuse_chunk(mstate m, mchunkptr p) {
+  do_check_any_chunk(m, p);
+  assert(cinuse(p));
+  assert(next_pinuse(p));
+  /* If not pinuse and not mmapped, previous chunk has OK offset */
+  assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p);
+  if (is_mmapped(p))
+    do_check_mmapped_chunk(m, p);
+}
+
+/* Check properties of free chunks */
+static void do_check_free_chunk(mstate m, mchunkptr p) {
+  size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT);
+  mchunkptr next = chunk_plus_offset(p, sz);
+  do_check_any_chunk(m, p);
+  assert(!cinuse(p));
+  assert(!next_pinuse(p));
+  assert (!is_mmapped(p));
+  if (p != m->dv && p != m->top) {
+    if (sz >= MIN_CHUNK_SIZE) {
+      assert((sz & CHUNK_ALIGN_MASK) == 0);
+      assert(is_aligned(chunk2mem(p)));
+      assert(next->prev_foot == sz);
+      assert(pinuse(p));
+      assert (next == m->top || cinuse(next));
+      assert(p->fd->bk == p);
+      assert(p->bk->fd == p);
+    }
+    else  /* markers are always of size SIZE_T_SIZE */
+      assert(sz == SIZE_T_SIZE);
+  }
+}
+
+/* Check properties of malloced chunks at the point they are malloced */
+static void do_check_malloced_chunk(mstate m, void* mem, size_t s) {
+  if (mem != 0) {
+    mchunkptr p = mem2chunk(mem);
+    size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT);
+    do_check_inuse_chunk(m, p);
+    assert((sz & CHUNK_ALIGN_MASK) == 0);
+    assert(sz >= MIN_CHUNK_SIZE);
+    assert(sz >= s);
+    /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */
+    assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE));
+  }
+}
+
+/* Check a tree and its subtrees.  */
+static void do_check_tree(mstate m, tchunkptr t) {
+  tchunkptr head = 0;
+  tchunkptr u = t;
+  bindex_t tindex = t->index;
+  size_t tsize = chunksize(t);
+  bindex_t idx;
+  compute_tree_index(tsize, idx);
+  assert(tindex == idx);
+  assert(tsize >= MIN_LARGE_SIZE);
+  assert(tsize >= minsize_for_tree_index(idx));
+  assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1))));
+
+  do { /* traverse through chain of same-sized nodes */
+    do_check_any_chunk(m, ((mchunkptr)u));
+    assert(u->index == tindex);
+    assert(chunksize(u) == tsize);
+    assert(!cinuse(u));
+    assert(!next_pinuse(u));
+    assert(u->fd->bk == u);
+    assert(u->bk->fd == u);
+    if (u->parent == 0) {
+      assert(u->child[0] == 0);
+      assert(u->child[1] == 0);
+    }
+    else {
+      assert(head == 0); /* only one node on chain has parent */
+      head = u;
+      assert(u->parent != u);
+      assert (u->parent->child[0] == u ||
+              u->parent->child[1] == u ||
+              *((tbinptr*)(u->parent)) == u);
+      if (u->child[0] != 0) {
+        assert(u->child[0]->parent == u);
+        assert(u->child[0] != u);
+        do_check_tree(m, u->child[0]);
+      }
+      if (u->child[1] != 0) {
+        assert(u->child[1]->parent == u);
+        assert(u->child[1] != u);
+        do_check_tree(m, u->child[1]);
+      }
+      if (u->child[0] != 0 && u->child[1] != 0) {
+        assert(chunksize(u->child[0]) < chunksize(u->child[1]));
+      }
+    }
+    u = u->fd;
+  } while (u != t);
+  assert(head != 0);
+}
+
+/*  Check all the chunks in a treebin.  */
+static void do_check_treebin(mstate m, bindex_t i) {
+  tbinptr* tb = treebin_at(m, i);
+  tchunkptr t = *tb;
+  int empty = (m->treemap & (1U << i)) == 0;
+  if (t == 0)
+    assert(empty);
+  if (!empty)
+    do_check_tree(m, t);
+}
+
+/*  Check all the chunks in a smallbin.  */
+static void do_check_smallbin(mstate m, bindex_t i) {
+  sbinptr b = smallbin_at(m, i);
+  mchunkptr p = b->bk;
+  unsigned int empty = (m->smallmap & (1U << i)) == 0;
+  if (p == b)
+    assert(empty);
+  if (!empty) {
+    for (; p != b; p = p->bk) {
+      size_t size = chunksize(p);
+      mchunkptr q;
+      /* each chunk claims to be free */
+      do_check_free_chunk(m, p);
+      /* chunk belongs in bin */
+      assert(small_index(size) == i);
+      assert(p->bk == b || chunksize(p->bk) == chunksize(p));
+      /* chunk is followed by an inuse chunk */
+      q = next_chunk(p);
+      if (q->head != FENCEPOST_HEAD)
+        do_check_inuse_chunk(m, q);
+    }
+  }
+}
+
+/* Find x in a bin. Used in other check functions. */
+static int bin_find(mstate m, mchunkptr x) {
+  size_t size = chunksize(x);
+  if (is_small(size)) {
+    bindex_t sidx = small_index(size);
+    sbinptr b = smallbin_at(m, sidx);
+    if (smallmap_is_marked(m, sidx)) {
+      mchunkptr p = b;
+      do {
+        if (p == x)
+          return 1;
+      } while ((p = p->fd) != b);
+    }
+  }
+  else {
+    bindex_t tidx;
+    compute_tree_index(size, tidx);
+    if (treemap_is_marked(m, tidx)) {
+      tchunkptr t = *treebin_at(m, tidx);
+      size_t sizebits = size << leftshift_for_tree_index(tidx);
+      while (t != 0 && chunksize(t) != size) {
+        t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
+        sizebits <<= 1;
+      }
+      if (t != 0) {
+        tchunkptr u = t;
+        do {
+          if (u == (tchunkptr)x)
+            return 1;
+        } while ((u = u->fd) != t);
+      }
+    }
+  }
+  return 0;
+}
+
+/* Traverse each chunk and check it; return total */
+static size_t traverse_and_check(mstate m) {
+  size_t sum = 0;
+  if (is_initialized(m)) {
+    msegmentptr s = &m->seg;
+    sum += m->topsize + TOP_FOOT_SIZE;
+    while (s != 0) {
+      mchunkptr q = align_as_chunk(s->base);
+      mchunkptr lastq = 0;
+      assert(pinuse(q));
+      while (segment_holds(s, q) &&
+             q != m->top && q->head != FENCEPOST_HEAD) {
+        sum += chunksize(q);
+        if (cinuse(q)) {
+          assert(!bin_find(m, q));
+          do_check_inuse_chunk(m, q);
+        }
+        else {
+          assert(q == m->dv || bin_find(m, q));
+          assert(lastq == 0 || cinuse(lastq)); /* Not 2 consecutive free */
+          do_check_free_chunk(m, q);
+        }
+        lastq = q;
+        q = next_chunk(q);
+      }
+      s = s->next;
+    }
+  }
+  return sum;
+}
+
+/* Check all properties of malloc_state. */
+static void do_check_malloc_state(mstate m) {
+  bindex_t i;
+  size_t total;
+  /* check bins */
+  for (i = 0; i < NSMALLBINS; ++i)
+    do_check_smallbin(m, i);
+  for (i = 0; i < NTREEBINS; ++i)
+    do_check_treebin(m, i);
+
+  if (m->dvsize != 0) { /* check dv chunk */
+    do_check_any_chunk(m, m->dv);
+    assert(m->dvsize == chunksize(m->dv));
+    assert(m->dvsize >= MIN_CHUNK_SIZE);
+    assert(bin_find(m, m->dv) == 0);
+  }
+
+  if (m->top != 0) {   /* check top chunk */
+    do_check_top_chunk(m, m->top);
+    assert(m->topsize == chunksize(m->top));
+    assert(m->topsize > 0);
+    assert(bin_find(m, m->top) == 0);
+  }
+
+  total = traverse_and_check(m);
+  assert(total <= m->footprint);
+  assert(m->footprint <= m->max_footprint);
+}
+#endif /* DEBUG */
+
+/* ----------------------------- statistics ------------------------------ */
+
+#if !NO_MALLINFO
+static struct mallinfo internal_mallinfo(mstate m) {
+  struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+  if (!PREACTION(m)) {
+    check_malloc_state(m);
+    if (is_initialized(m)) {
+      size_t nfree = SIZE_T_ONE; /* top always free */
+      size_t mfree = m->topsize + TOP_FOOT_SIZE;
+      size_t sum = mfree;
+      msegmentptr s = &m->seg;
+      while (s != 0) {
+        mchunkptr q = align_as_chunk(s->base);
+        while (segment_holds(s, q) &&
+               q != m->top && q->head != FENCEPOST_HEAD) {
+          size_t sz = chunksize(q);
+          sum += sz;
+          if (!cinuse(q)) {
+            mfree += sz;
+            ++nfree;
+          }
+          q = next_chunk(q);
+        }
+        s = s->next;
+      }
+
+      nm.arena    = sum;
+      nm.ordblks  = nfree;
+      nm.hblkhd   = m->footprint - sum;
+      nm.usmblks  = m->max_footprint;
+      nm.uordblks = m->footprint - mfree;
+      nm.fordblks = mfree;
+      nm.keepcost = m->topsize;
+    }
+
+    POSTACTION(m);
+  }
+  return nm;
+}
+#endif /* !NO_MALLINFO */
+
+static void internal_malloc_stats(mstate m) {
+  if (!PREACTION(m)) {
+    size_t maxfp = 0;
+    size_t fp = 0;
+    size_t used = 0;
+    check_malloc_state(m);
+    if (is_initialized(m)) {
+      msegmentptr s = &m->seg;
+      maxfp = m->max_footprint;
+      fp = m->footprint;
+      used = fp - (m->topsize + TOP_FOOT_SIZE);
+
+      while (s != 0) {
+        mchunkptr q = align_as_chunk(s->base);
+        while (segment_holds(s, q) &&
+               q != m->top && q->head != FENCEPOST_HEAD) {
+          if (!cinuse(q))
+            used -= chunksize(q);
+          q = next_chunk(q);
+        }
+        s = s->next;
+      }
+    }
+
+    fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp));
+    fprintf(stderr, "system bytes     = %10lu\n", (unsigned long)(fp));
+    fprintf(stderr, "in use bytes     = %10lu\n", (unsigned long)(used));
+
+    POSTACTION(m);
+  }
+}
+
+/* ----------------------- Operations on smallbins ----------------------- */
+
+/*
+  Various forms of linking and unlinking are defined as macros.  Even
+  the ones for trees, which are very long but have very short typical
+  paths.  This is ugly but reduces reliance on inlining support of
+  compilers.
+*/
+
+/* Link a free chunk into a smallbin  */
+#define insert_small_chunk(M, P, S) {\
+  bindex_t I  = small_index(S);\
+  mchunkptr B = smallbin_at(M, I);\
+  mchunkptr F = B;\
+  assert(S >= MIN_CHUNK_SIZE);\
+  if (!smallmap_is_marked(M, I))\
+    mark_smallmap(M, I);\
+  else if (RTCHECK(ok_address(M, B->fd)))\
+    F = B->fd;\
+  else {\
+    CORRUPTION_ERROR_ACTION(M);\
+  }\
+  B->fd = P;\
+  F->bk = P;\
+  P->fd = F;\
+  P->bk = B;\
+}
+
+/* Unlink a chunk from a smallbin  */
+#define unlink_small_chunk(M, P, S) {\
+  mchunkptr F = P->fd;\
+  mchunkptr B = P->bk;\
+  bindex_t I = small_index(S);\
+  assert(P != B);\
+  assert(P != F);\
+  assert(chunksize(P) == small_index2size(I));\
+  if (F == B)\
+    clear_smallmap(M, I);\
+  else if (RTCHECK((F == smallbin_at(M,I) || ok_address(M, F)) &&\
+                   (B == smallbin_at(M,I) || ok_address(M, B)))) {\
+    F->bk = B;\
+    B->fd = F;\
+  }\
+  else {\
+    CORRUPTION_ERROR_ACTION(M);\
+  }\
+}
+
+/* Unlink the first chunk from a smallbin */
+#define unlink_first_small_chunk(M, B, P, I) {\
+  mchunkptr F = P->fd;\
+  assert(P != B);\
+  assert(P != F);\
+  assert(chunksize(P) == small_index2size(I));\
+  if (B == F)\
+    clear_smallmap(M, I);\
+  else if (RTCHECK(ok_address(M, F))) {\
+    B->fd = F;\
+    F->bk = B;\
+  }\
+  else {\
+    CORRUPTION_ERROR_ACTION(M);\
+  }\
+}
+
+/* Replace dv node, binning the old one */
+/* Used only when dvsize known to be small */
+#define replace_dv(M, P, S) {\
+  size_t DVS = M->dvsize;\
+  if (DVS != 0) {\
+    mchunkptr DV = M->dv;\
+    assert(is_small(DVS));\
+    insert_small_chunk(M, DV, DVS);\
+  }\
+  M->dvsize = S;\
+  M->dv = P;\
+}
+
+/* ------------------------- Operations on trees ------------------------- */
+
+/* Insert chunk into tree */
+#define insert_large_chunk(M, X, S) {\
+  tbinptr* H;\
+  bindex_t I;\
+  compute_tree_index(S, I);\
+  H = treebin_at(M, I);\
+  X->index = I;\
+  X->child[0] = X->child[1] = 0;\
+  if (!treemap_is_marked(M, I)) {\
+    mark_treemap(M, I);\
+    *H = X;\
+    X->parent = (tchunkptr)H;\
+    X->fd = X->bk = X;\
+  }\
+  else {\
+    tchunkptr T = *H;\
+    size_t K = S << leftshift_for_tree_index(I);\
+    for (;;) {\
+      if (chunksize(T) != S) {\
+        tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\
+        K <<= 1;\
+        if (*C != 0)\
+          T = *C;\
+        else if (RTCHECK(ok_address(M, C))) {\
+          *C = X;\
+          X->parent = T;\
+          X->fd = X->bk = X;\
+          break;\
+        }\
+        else {\
+          CORRUPTION_ERROR_ACTION(M);\
+          break;\
+        }\
+      }\
+      else {\
+        tchunkptr F = T->fd;\
+        if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\
+          T->fd = F->bk = X;\
+          X->fd = F;\
+          X->bk = T;\
+          X->parent = 0;\
+          break;\
+        }\
+        else {\
+          CORRUPTION_ERROR_ACTION(M);\
+          break;\
+        }\
+      }\
+    }\
+  }\
+}
+
+/*
+  Unlink steps:
+
+  1. If x is a chained node, unlink it from its same-sized fd/bk links
+     and choose its bk node as its replacement.
+  2. If x was the last node of its size, but not a leaf node, it must
+     be replaced with a leaf node (not merely one with an open left or
+     right), to make sure that lefts and rights of descendents
+     correspond properly to bit masks.  We use the rightmost descendent
+     of x.  We could use any other leaf, but this is easy to locate and
+     tends to counteract removal of leftmosts elsewhere, and so keeps
+     paths shorter than minimally guaranteed.  This doesn't loop much
+     because on average a node in a tree is near the bottom.
+  3. If x is the base of a chain (i.e., has parent links) relink
+     x's parent and children to x's replacement (or null if none).
+*/
+
+#define unlink_large_chunk(M, X) {\
+  tchunkptr XP = X->parent;\
+  tchunkptr R;\
+  if (X->bk != X) {\
+    tchunkptr F = X->fd;\
+    R = X->bk;\
+    if (RTCHECK(ok_address(M, F))) {\
+      F->bk = R;\
+      R->fd = F;\
+    }\
+    else {\
+      CORRUPTION_ERROR_ACTION(M);\
+    }\
+  }\
+  else {\
+    tchunkptr* RP;\
+    if (((R = *(RP = &(X->child[1]))) != 0) ||\
+        ((R = *(RP = &(X->child[0]))) != 0)) {\
+      tchunkptr* CP;\
+      while ((*(CP = &(R->child[1])) != 0) ||\
+             (*(CP = &(R->child[0])) != 0)) {\
+        R = *(RP = CP);\
+      }\
+      if (RTCHECK(ok_address(M, RP)))\
+        *RP = 0;\
+      else {\
+        CORRUPTION_ERROR_ACTION(M);\
+      }\
+    }\
+  }\
+  if (XP != 0) {\
+    tbinptr* H = treebin_at(M, X->index);\
+    if (X == *H) {\
+      if ((*H = R) == 0) \
+        clear_treemap(M, X->index);\
+    }\
+    else if (RTCHECK(ok_address(M, XP))) {\
+      if (XP->child[0] == X) \
+        XP->child[0] = R;\
+      else \
+        XP->child[1] = R;\
+    }\
+    else\
+      CORRUPTION_ERROR_ACTION(M);\
+    if (R != 0) {\
+      if (RTCHECK(ok_address(M, R))) {\
+        tchunkptr C0, C1;\
+        R->parent = XP;\
+        if ((C0 = X->child[0]) != 0) {\
+          if (RTCHECK(ok_address(M, C0))) {\
+            R->child[0] = C0;\
+            C0->parent = R;\
+          }\
+          else\
+            CORRUPTION_ERROR_ACTION(M);\
+        }\
+        if ((C1 = X->child[1]) != 0) {\
+          if (RTCHECK(ok_address(M, C1))) {\
+            R->child[1] = C1;\
+            C1->parent = R;\
+          }\
+          else\
+            CORRUPTION_ERROR_ACTION(M);\
+        }\
+      }\
+      else\
+        CORRUPTION_ERROR_ACTION(M);\
+    }\
+  }\
+}
+
+/* Relays to large vs small bin operations */
+
+#define insert_chunk(M, P, S)\
+  if (is_small(S)) insert_small_chunk(M, P, S)\
+  else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); }
+
+#define unlink_chunk(M, P, S)\
+  if (is_small(S)) unlink_small_chunk(M, P, S)\
+  else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); }
+
+
+/* Relays to internal calls to malloc/free from realloc, memalign etc */
+
+#if ONLY_MSPACES
+#define internal_malloc(m, b) mspace_malloc(m, b)
+#define internal_free(m, mem) mspace_free(m,mem);
+#else /* ONLY_MSPACES */
+#if MSPACES
+#define internal_malloc(m, b)\
+   (m == gm)? dlmalloc(b) : mspace_malloc(m, b)
+#define internal_free(m, mem)\
+   if (m == gm) dlfree(mem); else mspace_free(m,mem);
+#else /* MSPACES */
+#define internal_malloc(m, b) dlmalloc(b)
+#define internal_free(m, mem) dlfree(mem)
+#endif /* MSPACES */
+#endif /* ONLY_MSPACES */
+
+/* -----------------------  Direct-mmapping chunks ----------------------- */
+
+/*
+  Directly mmapped chunks are set up with an offset to the start of
+  the mmapped region stored in the prev_foot field of the chunk. This
+  allows reconstruction of the required argument to MUNMAP when freed,
+  and also allows adjustment of the returned chunk to meet alignment
+  requirements (especially in memalign).  There is also enough space
+  allocated to hold a fake next chunk of size SIZE_T_SIZE to maintain
+  the PINUSE bit so frees can be checked.
+*/
+
+/* Malloc using mmap */
+static void* mmap_alloc(mstate m, size_t nb) {
+  size_t mmsize = granularity_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
+  if (mmsize > nb) {     /* Check for wrap around 0 */
+    char* mm = (char*)(DIRECT_MMAP(mmsize));
+    if (mm != CMFAIL) {
+      size_t offset = align_offset(chunk2mem(mm));
+      size_t psize = mmsize - offset - MMAP_FOOT_PAD;
+      mchunkptr p = (mchunkptr)(mm + offset);
+      p->prev_foot = offset | IS_MMAPPED_BIT;
+      (p)->head = (psize|CINUSE_BIT);
+      mark_inuse_foot(m, p, psize);
+      chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD;
+      chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0;
+
+      if (mm < m->least_addr)
+        m->least_addr = mm;
+      if ((m->footprint += mmsize) > m->max_footprint)
+        m->max_footprint = m->footprint;
+      assert(is_aligned(chunk2mem(p)));
+      check_mmapped_chunk(m, p);
+      return chunk2mem(p);
+    }
+  }
+  return 0;
+}
+
+/* Realloc using mmap */
+static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb) {
+  size_t oldsize = chunksize(oldp);
+  if (is_small(nb)) /* Can't shrink mmap regions below small size */
+    return 0;
+  /* Keep old chunk if big enough but not too big */
+  if (oldsize >= nb + SIZE_T_SIZE &&
+      (oldsize - nb) <= (mparams.granularity << 1))
+    return oldp;
+  else {
+    size_t offset = oldp->prev_foot & ~IS_MMAPPED_BIT;
+    size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD;
+    size_t newmmsize = granularity_align(nb + SIX_SIZE_T_SIZES +
+                                         CHUNK_ALIGN_MASK);
+    char* cp = (char*)CALL_MREMAP((char*)oldp - offset,
+                                  oldmmsize, newmmsize, 1);
+    if (cp != CMFAIL) {
+      mchunkptr newp = (mchunkptr)(cp + offset);
+      size_t psize = newmmsize - offset - MMAP_FOOT_PAD;
+      newp->head = (psize|CINUSE_BIT);
+      mark_inuse_foot(m, newp, psize);
+      chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD;
+      chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0;
+
+      if (cp < m->least_addr)
+        m->least_addr = cp;
+      if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint)
+        m->max_footprint = m->footprint;
+      check_mmapped_chunk(m, newp);
+      return newp;
+    }
+  }
+  return 0;
+}
+
+/* -------------------------- mspace management -------------------------- */
+
+/* Initialize top chunk and its size */
+static void init_top(mstate m, mchunkptr p, size_t psize) {
+  /* Ensure alignment */
+  size_t offset = align_offset(chunk2mem(p));
+  p = (mchunkptr)((char*)p + offset);
+  psize -= offset;
+
+  m->top = p;
+  m->topsize = psize;
+  p->head = psize | PINUSE_BIT;
+  /* set size of fake trailing chunk holding overhead space only once */
+  chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE;
+  m->trim_check = mparams.trim_threshold; /* reset on each update */
+}
+
+/* Initialize bins for a new mstate that is otherwise zeroed out */
+static void init_bins(mstate m) {
+  /* Establish circular links for smallbins */
+  bindex_t i;
+  for (i = 0; i < NSMALLBINS; ++i) {
+    sbinptr bin = smallbin_at(m,i);
+    bin->fd = bin->bk = bin;
+  }
+}
+
+#if PROCEED_ON_ERROR
+
+/* default corruption action */
+static void reset_on_error(mstate m) {
+  int i;
+  ++malloc_corruption_error_count;
+  /* Reinitialize fields to forget about all memory */
+  m->smallbins = m->treebins = 0;
+  m->dvsize = m->topsize = 0;
+  m->seg.base = 0;
+  m->seg.size = 0;
+  m->seg.next = 0;
+  m->top = m->dv = 0;
+  for (i = 0; i < NTREEBINS; ++i)
+    *treebin_at(m, i) = 0;
+  init_bins(m);
+}
+#endif /* PROCEED_ON_ERROR */
+
+/* Allocate chunk and prepend remainder with chunk in successor base. */
+static void* prepend_alloc(mstate m, char* newbase, char* oldbase,
+                           size_t nb) {
+  mchunkptr p = align_as_chunk(newbase);
+  mchunkptr oldfirst = align_as_chunk(oldbase);
+  size_t psize = (char*)oldfirst - (char*)p;
+  mchunkptr q = chunk_plus_offset(p, nb);
+  size_t qsize = psize - nb;
+  set_size_and_pinuse_of_inuse_chunk(m, p, nb);
+
+  assert((char*)oldfirst > (char*)q);
+  assert(pinuse(oldfirst));
+  assert(qsize >= MIN_CHUNK_SIZE);
+
+  /* consolidate remainder with first chunk of old base */
+  if (oldfirst == m->top) {
+    size_t tsize = m->topsize += qsize;
+    m->top = q;
+    q->head = tsize | PINUSE_BIT;
+    check_top_chunk(m, q);
+  }
+  else if (oldfirst == m->dv) {
+    size_t dsize = m->dvsize += qsize;
+    m->dv = q;
+    set_size_and_pinuse_of_free_chunk(q, dsize);
+  }
+  else {
+    if (!cinuse(oldfirst)) {
+      size_t nsize = chunksize(oldfirst);
+      unlink_chunk(m, oldfirst, nsize);
+      oldfirst = chunk_plus_offset(oldfirst, nsize);
+      qsize += nsize;
+    }
+    set_free_with_pinuse(q, qsize, oldfirst);
+    insert_chunk(m, q, qsize);
+    check_free_chunk(m, q);
+  }
+
+  check_malloced_chunk(m, chunk2mem(p), nb);
+  return chunk2mem(p);
+}
+
+
+/* Add a segment to hold a new noncontiguous region */
+static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) {
+  /* Determine locations and sizes of segment, fenceposts, old top */
+  char* old_top = (char*)m->top;
+  msegmentptr oldsp = segment_holding(m, old_top);
+  char* old_end = oldsp->base + oldsp->size;
+  size_t ssize = pad_request(sizeof(struct malloc_segment));
+  char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
+  size_t offset = align_offset(chunk2mem(rawsp));
+  char* asp = rawsp + offset;
+  char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp;
+  mchunkptr sp = (mchunkptr)csp;
+  msegmentptr ss = (msegmentptr)(chunk2mem(sp));
+  mchunkptr tnext = chunk_plus_offset(sp, ssize);
+  mchunkptr p = tnext;
+  int nfences = 0;
+
+  /* reset top to new space */
+  init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
+
+  /* Set up segment record */
+  assert(is_aligned(ss));
+  set_size_and_pinuse_of_inuse_chunk(m, sp, ssize);
+  *ss = m->seg; /* Push current record */
+  m->seg.base = tbase;
+  m->seg.size = tsize;
+  set_segment_flags(&m->seg, mmapped);
+  m->seg.next = ss;
+
+  /* Insert trailing fenceposts */
+  for (;;) {
+    mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE);
+    p->head = FENCEPOST_HEAD;
+    ++nfences;
+    if ((char*)(&(nextp->head)) < old_end)
+      p = nextp;
+    else
+      break;
+  }
+  assert(nfences >= 2);
+
+  /* Insert the rest of old top into a bin as an ordinary free chunk */
+  if (csp != old_top) {
+    mchunkptr q = (mchunkptr)old_top;
+    size_t psize = csp - old_top;
+    mchunkptr tn = chunk_plus_offset(q, psize);
+    set_free_with_pinuse(q, psize, tn);
+    insert_chunk(m, q, psize);
+  }
+
+  check_top_chunk(m, m->top);
+}
+
+/* -------------------------- System allocation -------------------------- */
+
+/* Get memory from system using MORECORE or MMAP */
+static void* sys_alloc(mstate m, size_t nb) {
+  char* tbase = CMFAIL;
+  size_t tsize = 0;
+  flag_t mmap_flag = 0;
+
+  init_mparams();
+
+  /* Directly map large chunks */
+  if (use_mmap(m) && nb >= mparams.mmap_threshold) {
+    void* mem = mmap_alloc(m, nb);
+    if (mem != 0)
+      return mem;
+  }
+
+  /*
+    Try getting memory in any of three ways (in most-preferred to
+    least-preferred order):
+    1. A call to MORECORE that can normally contiguously extend memory.
+       (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or
+       or main space is mmapped or a previous contiguous call failed)
+    2. A call to MMAP new space (disabled if not HAVE_MMAP).
+       Note that under the default settings, if MORECORE is unable to
+       fulfill a request, and HAVE_MMAP is true, then mmap is
+       used as a noncontiguous system allocator. This is a useful backup
+       strategy for systems with holes in address spaces -- in this case
+       sbrk cannot contiguously expand the heap, but mmap may be able to
+       find space.
+    3. A call to MORECORE that cannot usually contiguously extend memory.
+       (disabled if not HAVE_MORECORE)
+  */
+
+  if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) {
+    char* br = CMFAIL;
+    msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top);
+    size_t asize = 0;
+    ACQUIRE_MORECORE_LOCK();
+
+    if (ss == 0) {  /* First time through or recovery */
+      char* base = (char*)CALL_MORECORE(0);
+      if (base != CMFAIL) {
+        asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE);
+        /* Adjust to end on a page boundary */
+        if (!is_page_aligned(base))
+          asize += (page_align((size_t)base) - (size_t)base);
+        /* Can't call MORECORE if size is negative when treated as signed */
+        if (asize < HALF_MAX_SIZE_T &&
+            (br = (char*)(CALL_MORECORE(asize))) == base) {
+          tbase = base;
+          tsize = asize;
+        }
+      }
+    }
+    else {
+      /* Subtract out existing available top space from MORECORE request. */
+      asize = granularity_align(nb - m->topsize + TOP_FOOT_SIZE + SIZE_T_ONE);
+      /* Use mem here only if it did continuously extend old space */
+      if (asize < HALF_MAX_SIZE_T &&
+          (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) {
+        tbase = br;
+        tsize = asize;
+      }
+    }
+
+    if (tbase == CMFAIL) {    /* Cope with partial failure */
+      if (br != CMFAIL) {    /* Try to use/extend the space we did get */
+        if (asize < HALF_MAX_SIZE_T &&
+            asize < nb + TOP_FOOT_SIZE + SIZE_T_ONE) {
+          size_t esize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE - asize);
+          if (esize < HALF_MAX_SIZE_T) {
+            char* end = (char*)CALL_MORECORE(esize);
+            if (end != CMFAIL)
+              asize += esize;
+            else {            /* Can't use; try to release */
+              (void)CALL_MORECORE(-asize);
+              br = CMFAIL;
+            }
+          }
+        }
+      }
+      if (br != CMFAIL) {    /* Use the space we did get */
+        tbase = br;
+        tsize = asize;
+      }
+      else
+        disable_contiguous(m); /* Don't try contiguous path in the future */
+    }
+
+    RELEASE_MORECORE_LOCK();
+  }
+
+  if (HAVE_MMAP && tbase == CMFAIL) {  /* Try MMAP */
+    size_t req = nb + TOP_FOOT_SIZE + SIZE_T_ONE;
+    size_t rsize = granularity_align(req);
+    if (rsize > nb) { /* Fail if wraps around zero */
+      char* mp = (char*)(CALL_MMAP(rsize));
+      if (mp != CMFAIL) {
+        tbase = mp;
+        tsize = rsize;
+        mmap_flag = IS_MMAPPED_BIT;
+      }
+    }
+  }
+
+  if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */
+    size_t asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE);
+    if (asize < HALF_MAX_SIZE_T) {
+      char* br = CMFAIL;
+      char* end = CMFAIL;
+      ACQUIRE_MORECORE_LOCK();
+      br = (char*)(CALL_MORECORE(asize));
+      end = (char*)(CALL_MORECORE(0));
+      RELEASE_MORECORE_LOCK();
+      if (br != CMFAIL && end != CMFAIL && br < end) {
+        size_t ssize = end - br;
+        if (ssize > nb + TOP_FOOT_SIZE) {
+          tbase = br;
+          tsize = ssize;
+        }
+      }
+    }
+  }
+
+  if (tbase != CMFAIL) {
+
+    if ((m->footprint += tsize) > m->max_footprint)
+      m->max_footprint = m->footprint;
+
+    if (!is_initialized(m)) { /* first-time initialization */
+      m->seg.base = m->least_addr = tbase;
+      m->seg.size = tsize;
+      set_segment_flags(&m->seg, mmap_flag);
+      m->magic = mparams.magic;
+      init_bins(m);
+      if (is_global(m)) 
+        init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
+      else {
+        /* Offset top by embedded malloc_state */
+        mchunkptr mn = next_chunk(mem2chunk(m));
+        init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE);
+      }
+    }
+
+    else {
+      /* Try to merge with an existing segment */
+      msegmentptr sp = &m->seg;
+      while (sp != 0 && tbase != sp->base + sp->size)
+        sp = sp->next;
+      if (sp != 0 &&
+          !is_extern_segment(sp) &&
+	  check_segment_merge(sp, tbase, tsize) &&
+          (get_segment_flags(sp) & IS_MMAPPED_BIT) == mmap_flag &&
+          segment_holds(sp, m->top)) { /* append */
+        sp->size += tsize;
+        init_top(m, m->top, m->topsize + tsize);
+      }
+      else {
+        if (tbase < m->least_addr)
+          m->least_addr = tbase;
+        sp = &m->seg;
+        while (sp != 0 && sp->base != tbase + tsize)
+          sp = sp->next;
+        if (sp != 0 &&
+            !is_extern_segment(sp) &&
+	    check_segment_merge(sp, tbase, tsize) &&
+            (get_segment_flags(sp) & IS_MMAPPED_BIT) == mmap_flag) {
+          char* oldbase = sp->base;
+          sp->base = tbase;
+          sp->size += tsize;
+          return prepend_alloc(m, tbase, oldbase, nb);
+        }
+        else
+          add_segment(m, tbase, tsize, mmap_flag);
+      }
+    }
+
+    if (nb < m->topsize) { /* Allocate from new or extended top space */
+      size_t rsize = m->topsize -= nb;
+      mchunkptr p = m->top;
+      mchunkptr r = m->top = chunk_plus_offset(p, nb);
+      r->head = rsize | PINUSE_BIT;
+      set_size_and_pinuse_of_inuse_chunk(m, p, nb);
+      check_top_chunk(m, m->top);
+      check_malloced_chunk(m, chunk2mem(p), nb);
+      return chunk2mem(p);
+    }
+  }
+
+  MALLOC_FAILURE_ACTION;
+  return 0;
+}
+
+/* -----------------------  system deallocation -------------------------- */
+
+/* Unmap and unlink any mmapped segments that don't contain used chunks */
+static size_t release_unused_segments(mstate m) {
+  size_t released = 0;
+  msegmentptr pred = &m->seg;
+  msegmentptr sp = pred->next;
+  while (sp != 0) {
+    char* base = sp->base;
+    size_t size = sp->size;
+    msegmentptr next = sp->next;
+    if (is_mmapped_segment(sp) && !is_extern_segment(sp)) {
+      mchunkptr p = align_as_chunk(base);
+      size_t psize = chunksize(p);
+      /* Can unmap if first chunk holds entire segment and not pinned */
+      if (!cinuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) {
+        tchunkptr tp = (tchunkptr)p;
+        assert(segment_holds(sp, (char*)sp));
+        if (p == m->dv) {
+          m->dv = 0;
+          m->dvsize = 0;
+        }
+        else {
+          unlink_large_chunk(m, tp);
+        }
+        if (CALL_MUNMAP(base, size) == 0) {
+          released += size;
+          m->footprint -= size;
+          /* unlink obsoleted record */
+          sp = pred;
+          sp->next = next;
+        }
+        else { /* back out if cannot unmap */
+          insert_large_chunk(m, tp, psize);
+        }
+      }
+    }
+    pred = sp;
+    sp = next;
+  }
+  return released;
+}
+
+static int sys_trim(mstate m, size_t pad) {
+  size_t released = 0;
+  if (pad < MAX_REQUEST && is_initialized(m)) {
+    pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */
+
+    if (m->topsize > pad) {
+      /* Shrink top space in granularity-size units, keeping at least one */
+      size_t unit = mparams.granularity;
+      size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit -
+                      SIZE_T_ONE) * unit;
+      msegmentptr sp = segment_holding(m, (char*)m->top);
+
+      if (!is_extern_segment(sp)) {
+        if (is_mmapped_segment(sp)) {
+          if (HAVE_MMAP &&
+              sp->size >= extra &&
+              !has_segment_link(m, sp)) { /* can't shrink if pinned */
+            size_t newsize = sp->size - extra;
+            /* Prefer mremap, fall back to munmap */
+            if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) ||
+                (CALL_MUNMAP(sp->base + newsize, extra) == 0)) {
+              released = extra;
+            }
+          }
+        }
+        else if (HAVE_MORECORE) {
+          if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */
+            extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit;
+          ACQUIRE_MORECORE_LOCK();
+          {
+            /* Make sure end of memory is where we last set it. */
+            char* old_br = (char*)(CALL_MORECORE(0));
+            if (old_br == sp->base + sp->size) {
+              char* rel_br = (char*)(CALL_MORECORE(-extra));
+              char* new_br = (char*)(CALL_MORECORE(0));
+              if (rel_br != CMFAIL && new_br < old_br)
+                released = old_br - new_br;
+            }
+          }
+          RELEASE_MORECORE_LOCK();
+        }
+      }
+
+      if (released != 0) {
+        sp->size -= released;
+        m->footprint -= released;
+        init_top(m, m->top, m->topsize - released);
+        check_top_chunk(m, m->top);
+      }
+    }
+
+    /* Unmap any unused mmapped segments */
+    if (HAVE_MMAP) 
+      released += release_unused_segments(m);
+
+    /* On failure, disable autotrim to avoid repeated failed future calls */
+    if (released == 0)
+      m->trim_check = MAX_SIZE_T;
+  }
+
+  return (released != 0)? 1 : 0;
+}
+
+/* ---------------------------- malloc support --------------------------- */
+
+/* allocate a large request from the best fitting chunk in a treebin */
+static void* tmalloc_large(mstate m, size_t nb) {
+  tchunkptr v = 0;
+  size_t rsize = -nb; /* Unsigned negation */
+  tchunkptr t;
+  bindex_t idx;
+  compute_tree_index(nb, idx);
+
+  if ((t = *treebin_at(m, idx)) != 0) {
+    /* Traverse tree for this bin looking for node with size == nb */
+    size_t sizebits = nb << leftshift_for_tree_index(idx);
+    tchunkptr rst = 0;  /* The deepest untaken right subtree */
+    for (;;) {
+      tchunkptr rt;
+      size_t trem = chunksize(t) - nb;
+      if (trem < rsize) {
+        v = t;
+        if ((rsize = trem) == 0)
+          break;
+      }
+      rt = t->child[1];
+      t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
+      if (rt != 0 && rt != t)
+        rst = rt;
+      if (t == 0) {
+        t = rst; /* set t to least subtree holding sizes > nb */
+        break;
+      }
+      sizebits <<= 1;
+    }
+  }
+
+  if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */
+    binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap;
+    if (leftbits != 0) {
+      bindex_t i;
+      binmap_t leastbit = least_bit(leftbits);
+      compute_bit2idx(leastbit, i);
+      t = *treebin_at(m, i);
+    }
+  }
+
+  while (t != 0) { /* find smallest of tree or subtree */
+    size_t trem = chunksize(t) - nb;
+    if (trem < rsize) {
+      rsize = trem;
+      v = t;
+    }
+    t = leftmost_child(t);
+  }
+
+  /*  If dv is a better fit, return 0 so malloc will use it */
+  if (v != 0 && rsize < (size_t)(m->dvsize - nb)) {
+    if (RTCHECK(ok_address(m, v))) { /* split */
+      mchunkptr r = chunk_plus_offset(v, nb);
+      assert(chunksize(v) == rsize + nb);
+      if (RTCHECK(ok_next(v, r))) {
+        unlink_large_chunk(m, v);
+        if (rsize < MIN_CHUNK_SIZE)
+          set_inuse_and_pinuse(m, v, (rsize + nb));
+        else {
+          set_size_and_pinuse_of_inuse_chunk(m, v, nb);
+          set_size_and_pinuse_of_free_chunk(r, rsize);
+          insert_chunk(m, r, rsize);
+        }
+        return chunk2mem(v);
+      }
+    }
+    CORRUPTION_ERROR_ACTION(m);
+  }
+  return 0;
+}
+
+/* allocate a small request from the best fitting chunk in a treebin */
+static void* tmalloc_small(mstate m, size_t nb) {
+  tchunkptr t, v;
+  size_t rsize;
+  bindex_t i;
+  binmap_t leastbit = least_bit(m->treemap);
+  compute_bit2idx(leastbit, i);
+
+  v = t = *treebin_at(m, i);
+  rsize = chunksize(t) - nb;
+
+  while ((t = leftmost_child(t)) != 0) {
+    size_t trem = chunksize(t) - nb;
+    if (trem < rsize) {
+      rsize = trem;
+      v = t;
+    }
+  }
+
+  if (RTCHECK(ok_address(m, v))) {
+    mchunkptr r = chunk_plus_offset(v, nb);
+    assert(chunksize(v) == rsize + nb);
+    if (RTCHECK(ok_next(v, r))) {
+      unlink_large_chunk(m, v);
+      if (rsize < MIN_CHUNK_SIZE)
+        set_inuse_and_pinuse(m, v, (rsize + nb));
+      else {
+        set_size_and_pinuse_of_inuse_chunk(m, v, nb);
+        set_size_and_pinuse_of_free_chunk(r, rsize);
+        replace_dv(m, r, rsize);
+      }
+      return chunk2mem(v);
+    }
+  }
+
+  CORRUPTION_ERROR_ACTION(m);
+  return 0;
+}
+
+/* --------------------------- realloc support --------------------------- */
+
+static void* internal_realloc(mstate m, void* oldmem, size_t bytes) {
+  if (bytes >= MAX_REQUEST) {
+    MALLOC_FAILURE_ACTION;
+    return 0;
+  }
+  if (!PREACTION(m)) {
+    mchunkptr oldp = mem2chunk(oldmem);
+    size_t oldsize = chunksize(oldp);
+    mchunkptr next = chunk_plus_offset(oldp, oldsize);
+    mchunkptr newp = 0;
+    void* extra = 0;
+
+    /* Try to either shrink or extend into top. Else malloc-copy-free */
+
+    if (RTCHECK(ok_address(m, oldp) && ok_cinuse(oldp) &&
+                ok_next(oldp, next) && ok_pinuse(next))) {
+      size_t nb = request2size(bytes);
+      if (is_mmapped(oldp))
+        newp = mmap_resize(m, oldp, nb);
+      else if (oldsize >= nb) { /* already big enough */
+        size_t rsize = oldsize - nb;
+        newp = oldp;
+        if (rsize >= MIN_CHUNK_SIZE) {
+          mchunkptr remainder = chunk_plus_offset(newp, nb);
+          set_inuse(m, newp, nb);
+          set_inuse(m, remainder, rsize);
+          extra = chunk2mem(remainder);
+        }
+      }
+      else if (next == m->top && oldsize + m->topsize > nb) {
+        /* Expand into top */
+        size_t newsize = oldsize + m->topsize;
+        size_t newtopsize = newsize - nb;
+        mchunkptr newtop = chunk_plus_offset(oldp, nb);
+        set_inuse(m, oldp, nb);
+        newtop->head = newtopsize |PINUSE_BIT;
+        m->top = newtop;
+        m->topsize = newtopsize;
+        newp = oldp;
+      }
+    }
+    else {
+      USAGE_ERROR_ACTION(m, oldmem);
+      POSTACTION(m);
+      return 0;
+    }
+
+    POSTACTION(m);
+
+    if (newp != 0) {
+      if (extra != 0) {
+        internal_free(m, extra);
+      }
+      check_inuse_chunk(m, newp);
+      return chunk2mem(newp);
+    }
+    else {
+      void* newmem = internal_malloc(m, bytes);
+      if (newmem != 0) {
+        size_t oc = oldsize - overhead_for(oldp);
+        memcpy(newmem, oldmem, (oc < bytes)? oc : bytes);
+        internal_free(m, oldmem);
+      }
+      return newmem;
+    }
+  }
+  return 0;
+}
+
+/* --------------------------- memalign support -------------------------- */
+
+static void* internal_memalign(mstate m, size_t alignment, size_t bytes) {
+  if (alignment <= MALLOC_ALIGNMENT)    /* Can just use malloc */
+    return internal_malloc(m, bytes);
+  if (alignment <  MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */
+    alignment = MIN_CHUNK_SIZE;
+  if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */
+    size_t a = MALLOC_ALIGNMENT << 1;
+    while (a < alignment) a <<= 1;
+    alignment = a;
+  }
+  
+  if (bytes >= MAX_REQUEST - alignment) {
+    if (m != 0)  { /* Test isn't needed but avoids compiler warning */
+      MALLOC_FAILURE_ACTION;
+    }
+  }
+  else {
+    size_t nb = request2size(bytes);
+    size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD;
+    char* mem = (char*)internal_malloc(m, req);
+    if (mem != 0) {
+      void* leader = 0;
+      void* trailer = 0;
+      mchunkptr p = mem2chunk(mem);
+
+      if (PREACTION(m)) return 0;
+      if ((((size_t)(mem)) % alignment) != 0) { /* misaligned */
+        /*
+          Find an aligned spot inside chunk.  Since we need to give
+          back leading space in a chunk of at least MIN_CHUNK_SIZE, if
+          the first calculation places us at a spot with less than
+          MIN_CHUNK_SIZE leader, we can move to the next aligned spot.
+          We've allocated enough total room so that this is always
+          possible.
+        */
+        char* br = (char*)mem2chunk((size_t)(((size_t)(mem +
+                                                       alignment -
+                                                       SIZE_T_ONE)) &
+                                             -alignment));
+        char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)?
+          br : br+alignment;
+        mchunkptr newp = (mchunkptr)pos;
+        size_t leadsize = pos - (char*)(p);
+        size_t newsize = chunksize(p) - leadsize;
+
+        if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */
+          newp->prev_foot = p->prev_foot + leadsize;
+          newp->head = (newsize|CINUSE_BIT);
+        }
+        else { /* Otherwise, give back leader, use the rest */
+          set_inuse(m, newp, newsize);
+          set_inuse(m, p, leadsize);
+          leader = chunk2mem(p);
+        }
+        p = newp;
+      }
+
+      /* Give back spare room at the end */
+      if (!is_mmapped(p)) {
+        size_t size = chunksize(p);
+        if (size > nb + MIN_CHUNK_SIZE) {
+          size_t remainder_size = size - nb;
+          mchunkptr remainder = chunk_plus_offset(p, nb);
+          set_inuse(m, p, nb);
+          set_inuse(m, remainder, remainder_size);
+          trailer = chunk2mem(remainder);
+        }
+      }
+
+      assert (chunksize(p) >= nb);
+      assert((((size_t)(chunk2mem(p))) % alignment) == 0);
+      check_inuse_chunk(m, p);
+      POSTACTION(m);
+      if (leader != 0) {
+        internal_free(m, leader);
+      }
+      if (trailer != 0) {
+        internal_free(m, trailer);
+      }
+      return chunk2mem(p);
+    }
+  }
+  return 0;
+}
+
+/* ------------------------ comalloc/coalloc support --------------------- */
+
+static void** ialloc(mstate m,
+                     size_t n_elements,
+                     size_t* sizes,
+                     int opts,
+                     void* chunks[]) {
+  /*
+    This provides common support for independent_X routines, handling
+    all of the combinations that can result.
+
+    The opts arg has:
+    bit 0 set if all elements are same size (using sizes[0])
+    bit 1 set if elements should be zeroed
+  */
+
+  size_t    element_size;   /* chunksize of each element, if all same */
+  size_t    contents_size;  /* total size of elements */
+  size_t    array_size;     /* request size of pointer array */
+  void*     mem;            /* malloced aggregate space */
+  mchunkptr p;              /* corresponding chunk */
+  size_t    remainder_size; /* remaining bytes while splitting */
+  void**    marray;         /* either "chunks" or malloced ptr array */
+  mchunkptr array_chunk;    /* chunk for malloced ptr array */
+  flag_t    was_enabled;    /* to disable mmap */
+  size_t    size;
+  size_t    i;
+
+  /* compute array length, if needed */
+  if (chunks != 0) {
+    if (n_elements == 0)
+      return chunks; /* nothing to do */
+    marray = chunks;
+    array_size = 0;
+  }
+  else {
+    /* if empty req, must still return chunk representing empty array */
+    if (n_elements == 0)
+      return (void**)internal_malloc(m, 0);
+    marray = 0;
+    array_size = request2size(n_elements * (sizeof(void*)));
+  }
+
+  /* compute total element size */
+  if (opts & 0x1) { /* all-same-size */
+    element_size = request2size(*sizes);
+    contents_size = n_elements * element_size;
+  }
+  else { /* add up all the sizes */
+    element_size = 0;
+    contents_size = 0;
+    for (i = 0; i != n_elements; ++i)
+      contents_size += request2size(sizes[i]);
+  }
+
+  size = contents_size + array_size;
+
+  /*
+     Allocate the aggregate chunk.  First disable direct-mmapping so
+     malloc won't use it, since we would not be able to later
+     free/realloc space internal to a segregated mmap region.
+  */
+  was_enabled = use_mmap(m);
+  disable_mmap(m);
+  mem = internal_malloc(m, size - CHUNK_OVERHEAD);
+  if (was_enabled)
+    enable_mmap(m);
+  if (mem == 0)
+    return 0;
+
+  if (PREACTION(m)) return 0;
+  p = mem2chunk(mem);
+  remainder_size = chunksize(p);
+
+  assert(!is_mmapped(p));
+
+  if (opts & 0x2) {       /* optionally clear the elements */
+    memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size);
+  }
+
+  /* If not provided, allocate the pointer array as final part of chunk */
+  if (marray == 0) {
+    size_t  array_chunk_size;
+    array_chunk = chunk_plus_offset(p, contents_size);
+    array_chunk_size = remainder_size - contents_size;
+    marray = (void**) (chunk2mem(array_chunk));
+    set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size);
+    remainder_size = contents_size;
+  }
+
+  /* split out elements */
+  for (i = 0; ; ++i) {
+    marray[i] = chunk2mem(p);
+    if (i != n_elements-1) {
+      if (element_size != 0)
+        size = element_size;
+      else
+        size = request2size(sizes[i]);
+      remainder_size -= size;
+      set_size_and_pinuse_of_inuse_chunk(m, p, size);
+      p = chunk_plus_offset(p, size);
+    }
+    else { /* the final element absorbs any overallocation slop */
+      set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size);
+      break;
+    }
+  }
+
+#if DEBUG
+  if (marray != chunks) {
+    /* final element must have exactly exhausted chunk */
+    if (element_size != 0) {
+      assert(remainder_size == element_size);
+    }
+    else {
+      assert(remainder_size == request2size(sizes[i]));
+    }
+    check_inuse_chunk(m, mem2chunk(marray));
+  }
+  for (i = 0; i != n_elements; ++i)
+    check_inuse_chunk(m, mem2chunk(marray[i]));
+
+#endif /* DEBUG */
+
+  POSTACTION(m);
+  return marray;
+}
+
+
+/* -------------------------- public routines ---------------------------- */
+
+#if !ONLY_MSPACES
+
+void* dlmalloc(size_t bytes) {
+  /*
+     Basic algorithm:
+     If a small request (< 256 bytes minus per-chunk overhead):
+       1. If one exists, use a remainderless chunk in associated smallbin.
+          (Remainderless means that there are too few excess bytes to
+          represent as a chunk.)
+       2. If it is big enough, use the dv chunk, which is normally the
+          chunk adjacent to the one used for the most recent small request.
+       3. If one exists, split the smallest available chunk in a bin,
+          saving remainder in dv.
+       4. If it is big enough, use the top chunk.
+       5. If available, get memory from system and use it
+     Otherwise, for a large request:
+       1. Find the smallest available binned chunk that fits, and use it
+          if it is better fitting than dv chunk, splitting if necessary.
+       2. If better fitting than any binned chunk, use the dv chunk.
+       3. If it is big enough, use the top chunk.
+       4. If request size >= mmap threshold, try to directly mmap this chunk.
+       5. If available, get memory from system and use it
+
+     The ugly goto's here ensure that postaction occurs along all paths.
+  */
+
+  if (!PREACTION(gm)) {
+    void* mem;
+    size_t nb;
+    if (bytes <= MAX_SMALL_REQUEST) {
+      bindex_t idx;
+      binmap_t smallbits;
+      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
+      idx = small_index(nb);
+      smallbits = gm->smallmap >> idx;
+
+      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
+        mchunkptr b, p;
+        idx += ~smallbits & 1;       /* Uses next bin if idx empty */
+        b = smallbin_at(gm, idx);
+        p = b->fd;
+        assert(chunksize(p) == small_index2size(idx));
+        unlink_first_small_chunk(gm, b, p, idx);
+        set_inuse_and_pinuse(gm, p, small_index2size(idx));
+        mem = chunk2mem(p);
+        check_malloced_chunk(gm, mem, nb);
+        goto postaction;
+      }
+
+      else if (nb > gm->dvsize) {
+        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
+          mchunkptr b, p, r;
+          size_t rsize;
+          bindex_t i;
+          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
+          binmap_t leastbit = least_bit(leftbits);
+          compute_bit2idx(leastbit, i);
+          b = smallbin_at(gm, i);
+          p = b->fd;
+          assert(chunksize(p) == small_index2size(i));
+          unlink_first_small_chunk(gm, b, p, i);
+          rsize = small_index2size(i) - nb;
+          /* Fit here cannot be remainderless if 4byte sizes */
+          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
+            set_inuse_and_pinuse(gm, p, small_index2size(i));
+          else {
+            set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
+            r = chunk_plus_offset(p, nb);
+            set_size_and_pinuse_of_free_chunk(r, rsize);
+            replace_dv(gm, r, rsize);
+          }
+          mem = chunk2mem(p);
+          check_malloced_chunk(gm, mem, nb);
+          goto postaction;
+        }
+
+        else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) {
+          check_malloced_chunk(gm, mem, nb);
+          goto postaction;
+        }
+      }
+    }
+    else if (bytes >= MAX_REQUEST)
+      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
+    else {
+      nb = pad_request(bytes);
+      if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) {
+        check_malloced_chunk(gm, mem, nb);
+        goto postaction;
+      }
+    }
+
+    if (nb <= gm->dvsize) {
+      size_t rsize = gm->dvsize - nb;
+      mchunkptr p = gm->dv;
+      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
+        mchunkptr r = gm->dv = chunk_plus_offset(p, nb);
+        gm->dvsize = rsize;
+        set_size_and_pinuse_of_free_chunk(r, rsize);
+        set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
+      }
+      else { /* exhaust dv */
+        size_t dvs = gm->dvsize;
+        gm->dvsize = 0;
+        gm->dv = 0;
+        set_inuse_and_pinuse(gm, p, dvs);
+      }
+      mem = chunk2mem(p);
+      check_malloced_chunk(gm, mem, nb);
+      goto postaction;
+    }
+
+    else if (nb < gm->topsize) { /* Split top */
+      size_t rsize = gm->topsize -= nb;
+      mchunkptr p = gm->top;
+      mchunkptr r = gm->top = chunk_plus_offset(p, nb);
+      r->head = rsize | PINUSE_BIT;
+      set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
+      mem = chunk2mem(p);
+      check_top_chunk(gm, gm->top);
+      check_malloced_chunk(gm, mem, nb);
+      goto postaction;
+    }
+
+    mem = sys_alloc(gm, nb);
+
+  postaction:
+    POSTACTION(gm);
+    return mem;
+  }
+
+  return 0;
+}
+
+void dlfree(void* mem) {
+  /*
+     Consolidate freed chunks with preceding or succeeding bordering
+     free chunks, if they exist, and then place in a bin.  Intermixed
+     with special cases for top, dv, mmapped chunks, and usage errors.
+  */
+
+  if (mem != 0) {
+    mchunkptr p  = mem2chunk(mem);
+#if FOOTERS
+    mstate fm = get_mstate_for(p);
+    if (!ok_magic(fm)) {
+      USAGE_ERROR_ACTION(fm, p);
+      return;
+    }
+#else /* FOOTERS */
+#define fm gm
+#endif /* FOOTERS */
+    if (!PREACTION(fm)) {
+      check_inuse_chunk(fm, p);
+      if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) {
+        size_t psize = chunksize(p);
+        mchunkptr next = chunk_plus_offset(p, psize);
+        if (!pinuse(p)) {
+          size_t prevsize = p->prev_foot;
+          if ((prevsize & IS_MMAPPED_BIT) != 0) {
+            prevsize &= ~IS_MMAPPED_BIT;
+            psize += prevsize + MMAP_FOOT_PAD;
+            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
+              fm->footprint -= psize;
+            goto postaction;
+          }
+          else {
+            mchunkptr prev = chunk_minus_offset(p, prevsize);
+            psize += prevsize;
+            p = prev;
+            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
+              if (p != fm->dv) {
+                unlink_chunk(fm, p, prevsize);
+              }
+              else if ((next->head & INUSE_BITS) == INUSE_BITS) {
+                fm->dvsize = psize;
+                set_free_with_pinuse(p, psize, next);
+                goto postaction;
+              }
+            }
+            else
+              goto erroraction;
+          }
+        }
+
+        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
+          if (!cinuse(next)) {  /* consolidate forward */
+            if (next == fm->top) {
+              size_t tsize = fm->topsize += psize;
+              fm->top = p;
+              p->head = tsize | PINUSE_BIT;
+              if (p == fm->dv) {
+                fm->dv = 0;
+                fm->dvsize = 0;
+              }
+              if (should_trim(fm, tsize))
+                sys_trim(fm, 0);
+              goto postaction;
+            }
+            else if (next == fm->dv) {
+              size_t dsize = fm->dvsize += psize;
+              fm->dv = p;
+              set_size_and_pinuse_of_free_chunk(p, dsize);
+              goto postaction;
+            }
+            else {
+              size_t nsize = chunksize(next);
+              psize += nsize;
+              unlink_chunk(fm, next, nsize);
+              set_size_and_pinuse_of_free_chunk(p, psize);
+              if (p == fm->dv) {
+                fm->dvsize = psize;
+                goto postaction;
+              }
+            }
+          }
+          else
+            set_free_with_pinuse(p, psize, next);
+          insert_chunk(fm, p, psize);
+          check_free_chunk(fm, p);
+          goto postaction;
+        }
+      }
+    erroraction:
+      USAGE_ERROR_ACTION(fm, p);
+    postaction:
+      POSTACTION(fm);
+    }
+  }
+#if !FOOTERS
+#undef fm
+#endif /* FOOTERS */
+}
+
+void* dlcalloc(size_t n_elements, size_t elem_size) {
+  void* mem;
+  size_t req = 0;
+  if (n_elements != 0) {
+    req = n_elements * elem_size;
+    if (((n_elements | elem_size) & ~(size_t)0xffff) &&
+        (req / n_elements != elem_size))
+      req = MAX_SIZE_T; /* force downstream failure on overflow */
+  }
+  mem = dlmalloc(req);
+  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
+    memset(mem, 0, req);
+  return mem;
+}
+
+void* dlrealloc(void* oldmem, size_t bytes) {
+  if (oldmem == 0)
+    return dlmalloc(bytes);
+#ifdef REALLOC_ZERO_BYTES_FREES
+  if (bytes == 0) {
+    dlfree(oldmem);
+    return 0;
+  }
+#endif /* REALLOC_ZERO_BYTES_FREES */
+  else {
+#if ! FOOTERS
+    mstate m = gm;
+#else /* FOOTERS */
+    mstate m = get_mstate_for(mem2chunk(oldmem));
+    if (!ok_magic(m)) {
+      USAGE_ERROR_ACTION(m, oldmem);
+      return 0;
+    }
+#endif /* FOOTERS */
+    return internal_realloc(m, oldmem, bytes);
+  }
+}
+
+void* dlmemalign(size_t alignment, size_t bytes) {
+  return internal_memalign(gm, alignment, bytes);
+}
+
+void** dlindependent_calloc(size_t n_elements, size_t elem_size,
+                                 void* chunks[]) {
+  size_t sz = elem_size; /* serves as 1-element array */
+  return ialloc(gm, n_elements, &sz, 3, chunks);
+}
+
+void** dlindependent_comalloc(size_t n_elements, size_t sizes[],
+                                   void* chunks[]) {
+  return ialloc(gm, n_elements, sizes, 0, chunks);
+}
+
+void* dlvalloc(size_t bytes) {
+  size_t pagesz;
+  init_mparams();
+  pagesz = mparams.page_size;
+  return dlmemalign(pagesz, bytes);
+}
+
+void* dlpvalloc(size_t bytes) {
+  size_t pagesz;
+  init_mparams();
+  pagesz = mparams.page_size;
+  return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE));
+}
+
+int dlmalloc_trim(size_t pad) {
+  int result = 0;
+  if (!PREACTION(gm)) {
+    result = sys_trim(gm, pad);
+    POSTACTION(gm);
+  }
+  return result;
+}
+
+size_t dlmalloc_footprint(void) {
+  return gm->footprint;
+}
+
+size_t dlmalloc_max_footprint(void) {
+  return gm->max_footprint;
+}
+
+#if !NO_MALLINFO
+struct mallinfo dlmallinfo(void) {
+  return internal_mallinfo(gm);
+}
+#endif /* NO_MALLINFO */
+
+void dlmalloc_stats() {
+  internal_malloc_stats(gm);
+}
+
+size_t dlmalloc_usable_size(void* mem) {
+  if (mem != 0) {
+    mchunkptr p = mem2chunk(mem);
+    if (cinuse(p))
+      return chunksize(p) - overhead_for(p);
+  }
+  return 0;
+}
+
+int dlmallopt(int param_number, int value) {
+  return change_mparam(param_number, value);
+}
+
+#endif /* !ONLY_MSPACES */
+
+/* ----------------------------- user mspaces ---------------------------- */
+
+#if MSPACES
+
+static mstate init_user_mstate(char* tbase, size_t tsize) {
+  size_t msize = pad_request(sizeof(struct malloc_state));
+  mchunkptr mn;
+  mchunkptr msp = align_as_chunk(tbase);
+  mstate m = (mstate)(chunk2mem(msp));
+  memset(m, 0, msize);
+  INITIAL_LOCK(&m->mutex);
+  msp->head = (msize|PINUSE_BIT|CINUSE_BIT);
+  m->seg.base = m->least_addr = tbase;
+  m->seg.size = m->footprint = m->max_footprint = tsize;
+  m->magic = mparams.magic;
+  m->mflags = mparams.default_mflags;
+  disable_contiguous(m);
+  init_bins(m);
+  mn = next_chunk(mem2chunk(m));
+  init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE);
+  check_top_chunk(m, m->top);
+  return m;
+}
+
+mspace create_mspace(size_t capacity, int locked) {
+  mstate m = 0;
+  size_t msize = pad_request(sizeof(struct malloc_state));
+  init_mparams(); /* Ensure pagesize etc initialized */
+
+  if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
+    size_t rs = ((capacity == 0)? mparams.granularity :
+                 (capacity + TOP_FOOT_SIZE + msize));
+    size_t tsize = granularity_align(rs);
+    char* tbase = (char*)(CALL_MMAP(tsize));
+    if (tbase != CMFAIL) {
+      m = init_user_mstate(tbase, tsize);
+      set_segment_flags(&m->seg, IS_MMAPPED_BIT);
+      set_lock(m, locked);
+    }
+  }
+  return (mspace)m;
+}
+
+mspace create_mspace_with_base(void* base, size_t capacity, int locked) {
+  mstate m = 0;
+  size_t msize = pad_request(sizeof(struct malloc_state));
+  init_mparams(); /* Ensure pagesize etc initialized */
+
+  if (capacity > msize + TOP_FOOT_SIZE &&
+      capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
+    m = init_user_mstate((char*)base, capacity);
+    set_segment_flags(&m->seg, EXTERN_BIT);
+    set_lock(m, locked);
+  }
+  return (mspace)m;
+}
+
+size_t destroy_mspace(mspace msp) {
+  size_t freed = 0;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    msegmentptr sp = &ms->seg;
+    while (sp != 0) {
+      char* base = sp->base;
+      size_t size = sp->size;
+      flag_t flag = get_segment_flags(sp);
+      sp = sp->next;
+      if ((flag & IS_MMAPPED_BIT) && !(flag & EXTERN_BIT) &&
+          CALL_MUNMAP(base, size) == 0)
+        freed += size;
+    }
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return freed;
+}
+
+/*
+  mspace versions of routines are near-clones of the global
+  versions. This is not so nice but better than the alternatives.
+*/
+
+
+void* mspace_malloc(mspace msp, size_t bytes) {
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+    return 0;
+  }
+  if (!PREACTION(ms)) {
+    void* mem;
+    size_t nb;
+    if (bytes <= MAX_SMALL_REQUEST) {
+      bindex_t idx;
+      binmap_t smallbits;
+      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
+      idx = small_index(nb);
+      smallbits = ms->smallmap >> idx;
+
+      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
+        mchunkptr b, p;
+        idx += ~smallbits & 1;       /* Uses next bin if idx empty */
+        b = smallbin_at(ms, idx);
+        p = b->fd;
+        assert(chunksize(p) == small_index2size(idx));
+        unlink_first_small_chunk(ms, b, p, idx);
+        set_inuse_and_pinuse(ms, p, small_index2size(idx));
+        mem = chunk2mem(p);
+        check_malloced_chunk(ms, mem, nb);
+        goto postaction;
+      }
+
+      else if (nb > ms->dvsize) {
+        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
+          mchunkptr b, p, r;
+          size_t rsize;
+          bindex_t i;
+          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
+          binmap_t leastbit = least_bit(leftbits);
+          compute_bit2idx(leastbit, i);
+          b = smallbin_at(ms, i);
+          p = b->fd;
+          assert(chunksize(p) == small_index2size(i));
+          unlink_first_small_chunk(ms, b, p, i);
+          rsize = small_index2size(i) - nb;
+          /* Fit here cannot be remainderless if 4byte sizes */
+          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
+            set_inuse_and_pinuse(ms, p, small_index2size(i));
+          else {
+            set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
+            r = chunk_plus_offset(p, nb);
+            set_size_and_pinuse_of_free_chunk(r, rsize);
+            replace_dv(ms, r, rsize);
+          }
+          mem = chunk2mem(p);
+          check_malloced_chunk(ms, mem, nb);
+          goto postaction;
+        }
+
+        else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) {
+          check_malloced_chunk(ms, mem, nb);
+          goto postaction;
+        }
+      }
+    }
+    else if (bytes >= MAX_REQUEST)
+      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
+    else {
+      nb = pad_request(bytes);
+      if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) {
+        check_malloced_chunk(ms, mem, nb);
+        goto postaction;
+      }
+    }
+
+    if (nb <= ms->dvsize) {
+      size_t rsize = ms->dvsize - nb;
+      mchunkptr p = ms->dv;
+      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
+        mchunkptr r = ms->dv = chunk_plus_offset(p, nb);
+        ms->dvsize = rsize;
+        set_size_and_pinuse_of_free_chunk(r, rsize);
+        set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
+      }
+      else { /* exhaust dv */
+        size_t dvs = ms->dvsize;
+        ms->dvsize = 0;
+        ms->dv = 0;
+        set_inuse_and_pinuse(ms, p, dvs);
+      }
+      mem = chunk2mem(p);
+      check_malloced_chunk(ms, mem, nb);
+      goto postaction;
+    }
+
+    else if (nb < ms->topsize) { /* Split top */
+      size_t rsize = ms->topsize -= nb;
+      mchunkptr p = ms->top;
+      mchunkptr r = ms->top = chunk_plus_offset(p, nb);
+      r->head = rsize | PINUSE_BIT;
+      set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
+      mem = chunk2mem(p);
+      check_top_chunk(ms, ms->top);
+      check_malloced_chunk(ms, mem, nb);
+      goto postaction;
+    }
+
+    mem = sys_alloc(ms, nb);
+
+  postaction:
+    POSTACTION(ms);
+    return mem;
+  }
+
+  return 0;
+}
+
+void mspace_free(mspace msp, void* mem) {
+  if (mem != 0) {
+    mchunkptr p  = mem2chunk(mem);
+#if FOOTERS
+    mstate fm = get_mstate_for(p);
+#else /* FOOTERS */
+    mstate fm = (mstate)msp;
+#endif /* FOOTERS */
+    if (!ok_magic(fm)) {
+      USAGE_ERROR_ACTION(fm, p);
+      return;
+    }
+    if (!PREACTION(fm)) {
+      check_inuse_chunk(fm, p);
+      if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) {
+        size_t psize = chunksize(p);
+        mchunkptr next = chunk_plus_offset(p, psize);
+        if (!pinuse(p)) {
+          size_t prevsize = p->prev_foot;
+          if ((prevsize & IS_MMAPPED_BIT) != 0) {
+            prevsize &= ~IS_MMAPPED_BIT;
+            psize += prevsize + MMAP_FOOT_PAD;
+            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
+              fm->footprint -= psize;
+            goto postaction;
+          }
+          else {
+            mchunkptr prev = chunk_minus_offset(p, prevsize);
+            psize += prevsize;
+            p = prev;
+            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
+              if (p != fm->dv) {
+                unlink_chunk(fm, p, prevsize);
+              }
+              else if ((next->head & INUSE_BITS) == INUSE_BITS) {
+                fm->dvsize = psize;
+                set_free_with_pinuse(p, psize, next);
+                goto postaction;
+              }
+            }
+            else
+              goto erroraction;
+          }
+        }
+
+        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
+          if (!cinuse(next)) {  /* consolidate forward */
+            if (next == fm->top) {
+              size_t tsize = fm->topsize += psize;
+              fm->top = p;
+              p->head = tsize | PINUSE_BIT;
+              if (p == fm->dv) {
+                fm->dv = 0;
+                fm->dvsize = 0;
+              }
+              if (should_trim(fm, tsize))
+                sys_trim(fm, 0);
+              goto postaction;
+            }
+            else if (next == fm->dv) {
+              size_t dsize = fm->dvsize += psize;
+              fm->dv = p;
+              set_size_and_pinuse_of_free_chunk(p, dsize);
+              goto postaction;
+            }
+            else {
+              size_t nsize = chunksize(next);
+              psize += nsize;
+              unlink_chunk(fm, next, nsize);
+              set_size_and_pinuse_of_free_chunk(p, psize);
+              if (p == fm->dv) {
+                fm->dvsize = psize;
+                goto postaction;
+              }
+            }
+          }
+          else
+            set_free_with_pinuse(p, psize, next);
+          insert_chunk(fm, p, psize);
+          check_free_chunk(fm, p);
+          goto postaction;
+        }
+      }
+    erroraction:
+      USAGE_ERROR_ACTION(fm, p);
+    postaction:
+      POSTACTION(fm);
+    }
+  }
+}
+
+void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) {
+  void* mem;
+  size_t req = 0;
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+    return 0;
+  }
+  if (n_elements != 0) {
+    req = n_elements * elem_size;
+    if (((n_elements | elem_size) & ~(size_t)0xffff) &&
+        (req / n_elements != elem_size))
+      req = MAX_SIZE_T; /* force downstream failure on overflow */
+  }
+  mem = internal_malloc(ms, req);
+  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
+    memset(mem, 0, req);
+  return mem;
+}
+
+void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) {
+  if (oldmem == 0)
+    return mspace_malloc(msp, bytes);
+#ifdef REALLOC_ZERO_BYTES_FREES
+  if (bytes == 0) {
+    mspace_free(msp, oldmem);
+    return 0;
+  }
+#endif /* REALLOC_ZERO_BYTES_FREES */
+  else {
+#if FOOTERS
+    mchunkptr p  = mem2chunk(oldmem);
+    mstate ms = get_mstate_for(p);
+#else /* FOOTERS */
+    mstate ms = (mstate)msp;
+#endif /* FOOTERS */
+    if (!ok_magic(ms)) {
+      USAGE_ERROR_ACTION(ms,ms);
+      return 0;
+    }
+    return internal_realloc(ms, oldmem, bytes);
+  }
+}
+
+void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) {
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+    return 0;
+  }
+  return internal_memalign(ms, alignment, bytes);
+}
+
+void** mspace_independent_calloc(mspace msp, size_t n_elements,
+                                 size_t elem_size, void* chunks[]) {
+  size_t sz = elem_size; /* serves as 1-element array */
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+    return 0;
+  }
+  return ialloc(ms, n_elements, &sz, 3, chunks);
+}
+
+void** mspace_independent_comalloc(mspace msp, size_t n_elements,
+                                   size_t sizes[], void* chunks[]) {
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+    return 0;
+  }
+  return ialloc(ms, n_elements, sizes, 0, chunks);
+}
+
+int mspace_trim(mspace msp, size_t pad) {
+  int result = 0;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    if (!PREACTION(ms)) {
+      result = sys_trim(ms, pad);
+      POSTACTION(ms);
+    }
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return result;
+}
+
+void mspace_malloc_stats(mspace msp) {
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    internal_malloc_stats(ms);
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+}
+
+size_t mspace_footprint(mspace msp) {
+  size_t result;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    result = ms->footprint;
+  }
+  USAGE_ERROR_ACTION(ms,ms);
+  return result;
+}
+
+
+size_t mspace_max_footprint(mspace msp) {
+  size_t result;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    result = ms->max_footprint;
+  }
+  USAGE_ERROR_ACTION(ms,ms);
+  return result;
+}
+
+
+#if !NO_MALLINFO
+struct mallinfo mspace_mallinfo(mspace msp) {
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return internal_mallinfo(ms);
+}
+#endif /* NO_MALLINFO */
+
+int mspace_mallopt(int param_number, int value) {
+  return change_mparam(param_number, value);
+}
+
+#endif /* MSPACES */
+
+/* -------------------- Alternative MORECORE functions ------------------- */
+
+/*
+  Guidelines for creating a custom version of MORECORE:
+
+  * For best performance, MORECORE should allocate in multiples of pagesize.
+  * MORECORE may allocate more memory than requested. (Or even less,
+      but this will usually result in a malloc failure.)
+  * MORECORE must not allocate memory when given argument zero, but
+      instead return one past the end address of memory from previous
+      nonzero call.
+  * For best performance, consecutive calls to MORECORE with positive
+      arguments should return increasing addresses, indicating that
+      space has been contiguously extended.
+  * Even though consecutive calls to MORECORE need not return contiguous
+      addresses, it must be OK for malloc'ed chunks to span multiple
+      regions in those cases where they do happen to be contiguous.
+  * MORECORE need not handle negative arguments -- it may instead
+      just return MFAIL when given negative arguments.
+      Negative arguments are always multiples of pagesize. MORECORE
+      must not misinterpret negative args as large positive unsigned
+      args. You can suppress all such calls from even occurring by defining
+      MORECORE_CANNOT_TRIM,
+
+  As an example alternative MORECORE, here is a custom allocator
+  kindly contributed for pre-OSX macOS.  It uses virtually but not
+  necessarily physically contiguous non-paged memory (locked in,
+  present and won't get swapped out).  You can use it by uncommenting
+  this section, adding some #includes, and setting up the appropriate
+  defines above:
+
+      #define MORECORE osMoreCore
+
+  There is also a shutdown routine that should somehow be called for
+  cleanup upon program exit.
+
+  #define MAX_POOL_ENTRIES 100
+  #define MINIMUM_MORECORE_SIZE  (64 * 1024U)
+  static int next_os_pool;
+  void *our_os_pools[MAX_POOL_ENTRIES];
+
+  void *osMoreCore(int size)
+  {
+    void *ptr = 0;
+    static void *sbrk_top = 0;
+
+    if (size > 0)
+    {
+      if (size < MINIMUM_MORECORE_SIZE)
+         size = MINIMUM_MORECORE_SIZE;
+      if (CurrentExecutionLevel() == kTaskLevel)
+         ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0);
+      if (ptr == 0)
+      {
+        return (void *) MFAIL;
+      }
+      // save ptrs so they can be freed during cleanup
+      our_os_pools[next_os_pool] = ptr;
+      next_os_pool++;
+      ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK);
+      sbrk_top = (char *) ptr + size;
+      return ptr;
+    }
+    else if (size < 0)
+    {
+      // we don't currently support shrink behavior
+      return (void *) MFAIL;
+    }
+    else
+    {
+      return sbrk_top;
+    }
+  }
+
+  // cleanup any allocated memory pools
+  // called as last thing before shutting down driver
+
+  void osCleanupMem(void)
+  {
+    void **ptr;
+
+    for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++)
+      if (*ptr)
+      {
+         PoolDeallocate(*ptr);
+         *ptr = 0;
+      }
+  }
+
+*/
+
+
+/* -----------------------------------------------------------------------
+History:
+    V2.8.3 Thu Sep 22 11:16:32 2005  Doug Lea  (dl at gee)
+      * Add max_footprint functions
+      * Ensure all appropriate literals are size_t
+      * Fix conditional compilation problem for some #define settings
+      * Avoid concatenating segments with the one provided
+        in create_mspace_with_base
+      * Rename some variables to avoid compiler shadowing warnings
+      * Use explicit lock initialization.
+      * Better handling of sbrk interference.
+      * Simplify and fix segment insertion, trimming and mspace_destroy
+      * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x
+      * Thanks especially to Dennis Flanagan for help on these.
+
+    V2.8.2 Sun Jun 12 16:01:10 2005  Doug Lea  (dl at gee)
+      * Fix memalign brace error.
+
+    V2.8.1 Wed Jun  8 16:11:46 2005  Doug Lea  (dl at gee)
+      * Fix improper #endif nesting in C++
+      * Add explicit casts needed for C++
+
+    V2.8.0 Mon May 30 14:09:02 2005  Doug Lea  (dl at gee)
+      * Use trees for large bins
+      * Support mspaces
+      * Use segments to unify sbrk-based and mmap-based system allocation,
+        removing need for emulation on most platforms without sbrk.
+      * Default safety checks
+      * Optional footer checks. Thanks to William Robertson for the idea.
+      * Internal code refactoring
+      * Incorporate suggestions and platform-specific changes.
+        Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas,
+        Aaron Bachmann,  Emery Berger, and others.
+      * Speed up non-fastbin processing enough to remove fastbins.
+      * Remove useless cfree() to avoid conflicts with other apps.
+      * Remove internal memcpy, memset. Compilers handle builtins better.
+      * Remove some options that no one ever used and rename others.
+
+    V2.7.2 Sat Aug 17 09:07:30 2002  Doug Lea  (dl at gee)
+      * Fix malloc_state bitmap array misdeclaration
+
+    V2.7.1 Thu Jul 25 10:58:03 2002  Doug Lea  (dl at gee)
+      * Allow tuning of FIRST_SORTED_BIN_SIZE
+      * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte.
+      * Better detection and support for non-contiguousness of MORECORE.
+        Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger
+      * Bypass most of malloc if no frees. Thanks To Emery Berger.
+      * Fix freeing of old top non-contiguous chunk im sysmalloc.
+      * Raised default trim and map thresholds to 256K.
+      * Fix mmap-related #defines. Thanks to Lubos Lunak.
+      * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield.
+      * Branch-free bin calculation
+      * Default trim and mmap thresholds now 256K.
+
+    V2.7.0 Sun Mar 11 14:14:06 2001  Doug Lea  (dl at gee)
+      * Introduce independent_comalloc and independent_calloc.
+        Thanks to Michael Pachos for motivation and help.
+      * Make optional .h file available
+      * Allow > 2GB requests on 32bit systems.
+      * new WIN32 sbrk, mmap, munmap, lock code from <Walter at GeNeSys-e.de>.
+        Thanks also to Andreas Mueller <a.mueller at paradatec.de>,
+        and Anonymous.
+      * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for
+        helping test this.)
+      * memalign: check alignment arg
+      * realloc: don't try to shift chunks backwards, since this
+        leads to  more fragmentation in some programs and doesn't
+        seem to help in any others.
+      * Collect all cases in malloc requiring system memory into sysmalloc
+      * Use mmap as backup to sbrk
+      * Place all internal state in malloc_state
+      * Introduce fastbins (although similar to 2.5.1)
+      * Many minor tunings and cosmetic improvements
+      * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK
+      * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS
+        Thanks to Tony E. Bennett <tbennett at nvidia.com> and others.
+      * Include errno.h to support default failure action.
+
+    V2.6.6 Sun Dec  5 07:42:19 1999  Doug Lea  (dl at gee)
+      * return null for negative arguments
+      * Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com>
+         * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'
+          (e.g. WIN32 platforms)
+         * Cleanup header file inclusion for WIN32 platforms
+         * Cleanup code to avoid Microsoft Visual C++ compiler complaints
+         * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing
+           memory allocation routines
+         * Set 'malloc_getpagesize' for WIN32 platforms (needs more work)
+         * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to
+           usage of 'assert' in non-WIN32 code
+         * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to
+           avoid infinite loop
+      * Always call 'fREe()' rather than 'free()'
+
+    V2.6.5 Wed Jun 17 15:57:31 1998  Doug Lea  (dl at gee)
+      * Fixed ordering problem with boundary-stamping
+
+    V2.6.3 Sun May 19 08:17:58 1996  Doug Lea  (dl at gee)
+      * Added pvalloc, as recommended by H.J. Liu
+      * Added 64bit pointer support mainly from Wolfram Gloger
+      * Added anonymously donated WIN32 sbrk emulation
+      * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen
+      * malloc_extend_top: fix mask error that caused wastage after
+        foreign sbrks
+      * Add linux mremap support code from HJ Liu
+
+    V2.6.2 Tue Dec  5 06:52:55 1995  Doug Lea  (dl at gee)
+      * Integrated most documentation with the code.
+      * Add support for mmap, with help from
+        Wolfram Gloger (Gloger at lrz.uni-muenchen.de).
+      * Use last_remainder in more cases.
+      * Pack bins using idea from  colin at nyx10.cs.du.edu
+      * Use ordered bins instead of best-fit threshhold
+      * Eliminate block-local decls to simplify tracing and debugging.
+      * Support another case of realloc via move into top
+      * Fix error occuring when initial sbrk_base not word-aligned.
+      * Rely on page size for units instead of SBRK_UNIT to
+        avoid surprises about sbrk alignment conventions.
+      * Add mallinfo, mallopt. Thanks to Raymond Nijssen
+        (raymond at es.ele.tue.nl) for the suggestion.
+      * Add `pad' argument to malloc_trim and top_pad mallopt parameter.
+      * More precautions for cases where other routines call sbrk,
+        courtesy of Wolfram Gloger (Gloger at lrz.uni-muenchen.de).
+      * Added macros etc., allowing use in linux libc from
+        H.J. Lu (hjl at gnu.ai.mit.edu)
+      * Inverted this history list
+
+    V2.6.1 Sat Dec  2 14:10:57 1995  Doug Lea  (dl at gee)
+      * Re-tuned and fixed to behave more nicely with V2.6.0 changes.
+      * Removed all preallocation code since under current scheme
+        the work required to undo bad preallocations exceeds
+        the work saved in good cases for most test programs.
+      * No longer use return list or unconsolidated bins since
+        no scheme using them consistently outperforms those that don't
+        given above changes.
+      * Use best fit for very large chunks to prevent some worst-cases.
+      * Added some support for debugging
+
+    V2.6.0 Sat Nov  4 07:05:23 1995  Doug Lea  (dl at gee)
+      * Removed footers when chunks are in use. Thanks to
+        Paul Wilson (wilson at cs.texas.edu) for the suggestion.
+
+    V2.5.4 Wed Nov  1 07:54:51 1995  Doug Lea  (dl at gee)
+      * Added malloc_trim, with help from Wolfram Gloger
+        (wmglo at Dent.MED.Uni-Muenchen.DE).
+
+    V2.5.3 Tue Apr 26 10:16:01 1994  Doug Lea  (dl at g)
+
+    V2.5.2 Tue Apr  5 16:20:40 1994  Doug Lea  (dl at g)
+      * realloc: try to expand in both directions
+      * malloc: swap order of clean-bin strategy;
+      * realloc: only conditionally expand backwards
+      * Try not to scavenge used bins
+      * Use bin counts as a guide to preallocation
+      * Occasionally bin return list chunks in first scan
+      * Add a few optimizations from colin at nyx10.cs.du.edu
+
+    V2.5.1 Sat Aug 14 15:40:43 1993  Doug Lea  (dl at g)
+      * faster bin computation & slightly different binning
+      * merged all consolidations to one part of malloc proper
+         (eliminating old malloc_find_space & malloc_clean_bin)
+      * Scan 2 returns chunks (not just 1)
+      * Propagate failure in realloc if malloc returns 0
+      * Add stuff to allow compilation on non-ANSI compilers
+          from kpv at research.att.com
+
+    V2.5 Sat Aug  7 07:41:59 1993  Doug Lea  (dl at g.oswego.edu)
+      * removed potential for odd address access in prev_chunk
+      * removed dependency on getpagesize.h
+      * misc cosmetics and a bit more internal documentation
+      * anticosmetics: mangled names in macros to evade debugger strangeness
+      * tested on sparc, hp-700, dec-mips, rs6000
+          with gcc & native cc (hp, dec only) allowing
+          Detlefs & Zorn comparison study (in SIGPLAN Notices.)
+
+    Trial version Fri Aug 28 13:14:29 1992  Doug Lea  (dl at g.oswego.edu)
+      * Based loosely on libg++-1.2X malloc. (It retains some of the overall
+         structure of old version,  but most details differ.)
+ 
+*/
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/frv/eabi.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/frv/eabi.S
new file mode 100755
index 0000000..379ea4b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/frv/eabi.S
@@ -0,0 +1,128 @@
+/* -----------------------------------------------------------------------
+   eabi.S - Copyright (c) 2004  Anthony Green
+   
+   FR-V Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+	.globl ffi_prep_args_EABI
+
+	.text
+	.p2align 4
+	.globl ffi_call_EABI
+	.type ffi_call_EABI, @function
+
+	# gr8 :   ffi_prep_args
+	# gr9 :   &ecif
+	# gr10:   cif->bytes
+	# gr11:   fig->flags
+	# gr12:   ecif.rvalue
+	# gr13:   fn
+	
+ffi_call_EABI:	
+	addi	sp, #-80, sp
+	sti	fp, @(sp, #24)
+	addi	sp, #24, fp
+	movsg	lr, gr5
+
+	/* Make room for the new arguments.  */
+	/* subi	sp, fp, gr10 */
+	
+	/* Store return address and incoming args on stack.  */
+	sti	gr5, @(fp, #8)
+	sti	gr8, @(fp, #-4)
+	sti	gr9, @(fp, #-8)
+	sti	gr10, @(fp, #-12)
+	sti	gr11, @(fp, #-16)
+	sti	gr12, @(fp, #-20)
+	sti	gr13, @(fp, #-24)
+
+	sub     sp, gr10, sp
+	
+	/* Call ffi_prep_args.  */
+	ldi	@(fp, #-4), gr4
+	addi	sp, #0, gr8
+	ldi	@(fp, #-8), gr9
+#ifdef __FRV_FDPIC__
+	ldd	@(gr4, gr0), gr14
+	calll	@(gr14, gr0)
+#else
+	calll	@(gr4, gr0)
+#endif	
+
+	/* ffi_prep_args returns the new stack pointer.  */
+	mov	gr8, gr4
+		
+	ldi	@(sp, #0), gr8
+	ldi	@(sp, #4), gr9
+	ldi	@(sp, #8), gr10
+	ldi	@(sp, #12), gr11
+	ldi	@(sp, #16), gr12
+	ldi	@(sp, #20), gr13
+
+	/* Always copy the return value pointer into the hidden
+	   parameter register.  This is only strictly necessary
+	   when we're returning an aggregate type, but it doesn't
+	   hurt to do this all the time, and it saves a branch.  */
+	ldi	@(fp, #-20), gr3
+
+	/* Use the ffi_prep_args return value for the new sp.  */
+	mov	gr4, sp
+	
+	/* Call the target function.  */
+	ldi	@(fp, -24), gr4
+#ifdef __FRV_FDPIC__
+	ldd	@(gr4, gr0), gr14
+	calll	@(gr14, gr0)
+#else
+	calll	@(gr4, gr0)
+#endif	
+
+	/* Store the result. */
+	ldi	@(fp, #-16), gr10  /* fig->flags */
+	ldi	@(fp, #-20), gr4   /* ecif.rvalue */
+
+	/* Is the return value stored in two registers?  */
+	cmpi	gr10, #8, icc0
+	bne	icc0, 0, .L2
+	/*   Yes, save them.  */
+	sti	gr8, @(gr4, #0)
+	sti	gr9, @(gr4, #4)
+	bra	.L3
+.L2:
+	/* Is the return value a structure?  */
+	cmpi	gr10, #-1, icc0
+	beq	icc0, 0, .L3
+	/*   No, save a 4 byte return value.  */
+	sti	gr8, @(gr4, #0)
+.L3:	
+
+	/* Restore the stack, and return.  */
+	ldi	@(fp, 8), gr5
+	ld	@(fp, gr0), fp
+	addi	sp,#80,sp
+	jmpl	@(gr5,gr0)
+	.size ffi_call_EABI, .-ffi_call_EABI
+	
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/frv/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/frv/ffi.c
new file mode 100755
index 0000000..5698c89
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/frv/ffi.c
@@ -0,0 +1,292 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (C) 2004  Anthony Green
+   Copyright (C) 2007  Free Software Foundation, Inc.
+	   Copyright (C) 2008  Red Hat, Inc.
+   
+   FR-V Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+void *ffi_prep_args(char *stack, extended_cif *ecif)
+{
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+  register int count = 0;
+
+  p_argv = ecif->avalue;
+  argp = stack;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       (i != 0);
+       i--, p_arg++)
+    {
+      size_t z;
+      
+      z = (*p_arg)->size;
+
+      if ((*p_arg)->type == FFI_TYPE_STRUCT)
+	{
+	  z = sizeof(void*);
+	  *(void **) argp = *p_argv;
+	} 
+      /*      if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	{
+	  if (count > 24)
+	    {
+	      // This is going on the stack.  Turn it into a double.  
+	      *(double *) argp = (double) *(float*)(* p_argv);
+	      z = sizeof(double);
+	    }
+	  else
+	    *(void **) argp = *(void **)(* p_argv);
+	}  */
+      else if (z < sizeof(int))
+	{
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+	      break;
+	      
+	    case FFI_TYPE_UINT8:
+	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+	      break;
+	      
+	    case FFI_TYPE_SINT16:
+	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+	      break;
+		  
+	    case FFI_TYPE_UINT16:
+	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+	      break;
+		  
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	}
+      else if (z == sizeof(int))
+	{
+	  *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	}
+      else
+	{
+	  memcpy(argp, *p_argv, z);
+	}
+      p_argv++;
+      argp += z;
+      count += z;
+    }
+
+  return (stack + ((count > 24) ? 24 : ALIGN_DOWN(count, 8)));
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    cif->flags = -1;
+  else
+    cif->flags = cif->rtype->size;
+
+  cif->bytes = ALIGN (cif->bytes, 8);
+
+  return FFI_OK;
+}
+
+extern void ffi_call_EABI(void *(*)(char *, extended_cif *), 
+			  extended_cif *, 
+			  unsigned, unsigned, 
+			  unsigned *, 
+			  void (*fn)(void));
+
+void ffi_call(ffi_cif *cif, 
+	      void (*fn)(void), 
+	      void *rvalue, 
+	      void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      ecif.rvalue = alloca(cif->rtype->size);
+    }
+  else
+    ecif.rvalue = rvalue;
+    
+  
+  switch (cif->abi) 
+    {
+    case FFI_EABI:
+      ffi_call_EABI(ffi_prep_args, &ecif, cif->bytes, 
+		    cif->flags, ecif.rvalue, fn);
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3,
+		       unsigned arg4, unsigned arg5, unsigned arg6)
+{
+  /* This function is called by a trampoline.  The trampoline stows a
+     pointer to the ffi_closure object in gr7.  We must save this
+     pointer in a place that will persist while we do our work.  */
+  register ffi_closure *creg __asm__ ("gr7");
+  ffi_closure *closure = creg;
+
+  /* Arguments that don't fit in registers are found on the stack
+     at a fixed offset above the current frame pointer.  */
+  register char *frame_pointer __asm__ ("fp");
+  char *stack_args = frame_pointer + 16;
+
+  /* Lay the register arguments down in a continuous chunk of memory.  */
+  unsigned register_args[6] =
+    { arg1, arg2, arg3, arg4, arg5, arg6 };
+
+  ffi_cif *cif = closure->cif;
+  ffi_type **arg_types = cif->arg_types;
+  void **avalue = alloca (cif->nargs * sizeof(void *));
+  char *ptr = (char *) register_args;
+  int i;
+
+  /* Find the address of each argument.  */
+  for (i = 0; i < cif->nargs; i++)
+    {
+      switch (arg_types[i]->type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	  avalue[i] = ptr + 3;
+	  break;
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	  avalue[i] = ptr + 2;
+	  break;
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_FLOAT:
+	  avalue[i] = ptr;
+	  break;
+	case FFI_TYPE_STRUCT:
+	  avalue[i] = *(void**)ptr;
+	  break;
+	default:
+	  /* This is an 8-byte value.  */
+	  avalue[i] = ptr;
+	  ptr += 4;
+	  break;
+	}
+      ptr += 4;
+
+      /* If we've handled more arguments than fit in registers,
+	 start looking at the those passed on the stack.  */
+      if (ptr == ((char *)register_args + (6*4)))
+	ptr = stack_args;
+    }
+
+  /* Invoke the closure.  */
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      /* The caller allocates space for the return structure, and
+       passes a pointer to this space in gr3.  Use this value directly
+       as the return value.  */
+      register void *return_struct_ptr __asm__("gr3");
+      (closure->fun) (cif, return_struct_ptr, avalue, closure->user_data);
+    }
+  else
+    {
+      /* Allocate space for the return value and call the function.  */
+      long long rvalue;
+      (closure->fun) (cif, &rvalue, avalue, closure->user_data);
+
+      /* Functions return 4-byte or smaller results in gr8.  8-byte
+	 values also use gr9.  We fill the both, even for small return
+	 values, just to avoid a branch.  */ 
+      asm ("ldi  @(%0, #0), gr8" : : "r" (&rvalue));
+      asm ("ldi  @(%0, #0), gr9" : : "r" (&((int *) &rvalue)[1]));
+    }
+}
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif*, void*, void**, void*),
+		      void *user_data,
+		      void *codeloc)
+{
+  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
+  unsigned long fn = (long) ffi_closure_eabi;
+  unsigned long cls = (long) codeloc;
+#ifdef __FRV_FDPIC__
+  register void *got __asm__("gr15");
+#endif
+  int i;
+
+  fn = (unsigned long) ffi_closure_eabi;
+
+#ifdef __FRV_FDPIC__
+  tramp[0] = &((unsigned int *)codeloc)[2];
+  tramp[1] = got;
+  tramp[2] = 0x8cfc0000 + (fn  & 0xffff); /* setlos lo(fn), gr6    */
+  tramp[3] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7   */
+  tramp[4] = 0x8cf80000 + (fn  >> 16);	  /* sethi hi(fn), gr6     */
+  tramp[5] = 0x8ef80000 + (cls >> 16);    /* sethi hi(cls), gr7    */
+  tramp[6] = 0x9cc86000;                  /* ldi @(gr6, #0), gr14  */
+  tramp[7] = 0x8030e000;                  /* jmpl @(gr14, gr0)     */
+#else
+  tramp[0] = 0x8cfc0000 + (fn  & 0xffff); /* setlos lo(fn), gr6    */
+  tramp[1] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7   */
+  tramp[2] = 0x8cf80000 + (fn  >> 16);	  /* sethi hi(fn), gr6     */
+  tramp[3] = 0x8ef80000 + (cls >> 16);    /* sethi hi(cls), gr7    */
+  tramp[4] = 0x80300006;                  /* jmpl @(gr0, gr6)      */
+#endif
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  /* Cache flushing.  */
+  for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++)
+    __asm__ volatile ("dcf @(%0,%1)\n\tici @(%2,%1)" :: "r" (tramp), "r" (i),
+		      "r" (codeloc));
+
+  return FFI_OK;
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/frv/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/frv/ffitarget.h
new file mode 100755
index 0000000..4839069
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/frv/ffitarget.h
@@ -0,0 +1,57 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2004  Red Hat, Inc.
+   Target configuration macros for FR-V
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_EABI,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_EABI
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_NATIVE_RAW_API 0
+
+#ifdef __FRV_FDPIC__
+/* Trampolines are 8 4-byte instructions long.  */
+#define FFI_TRAMPOLINE_SIZE (8*4)
+#else
+/* Trampolines are 5 4-byte instructions long.  */
+#define FFI_TRAMPOLINE_SIZE (5*4)
+#endif
+
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/ia64/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/ia64/ffi.c
new file mode 100755
index 0000000..60120ed
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/ia64/ffi.c
@@ -0,0 +1,582 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2011 Anthony Green
+           Copyright (c) 2000 Hewlett Packard Company
+           Copyright (c) 1998, 2007, 2008 Red Hat, Inc.
+	   
+   IA64 Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <float.h>
+
+#include "ia64_flags.h"
+
+/* A 64-bit pointer value.  In LP64 mode, this is effectively a plain
+   pointer.  In ILP32 mode, it's a pointer that's been extended to 
+   64 bits by "addp4".  */
+typedef void *PTR64 __attribute__((mode(DI)));
+
+/* Memory image of fp register contents.  This is the implementation
+   specific format used by ldf.fill/stf.spill.  All we care about is
+   that it wants a 16 byte aligned slot.  */
+typedef struct
+{
+  UINT64 x[2] __attribute__((aligned(16)));
+} fpreg;
+
+
+/* The stack layout given to ffi_call_unix and ffi_closure_unix_inner.  */
+
+struct ia64_args
+{
+  fpreg fp_regs[8];	/* Contents of 8 fp arg registers.  */
+  UINT64 gp_regs[8];	/* Contents of 8 gp arg registers.  */
+  UINT64 other_args[];	/* Arguments passed on stack, variable size.  */
+};
+
+
+/* Adjust ADDR, a pointer to an 8 byte slot, to point to the low LEN bytes.  */
+
+static inline void *
+endian_adjust (void *addr, size_t len)
+{
+#ifdef __BIG_ENDIAN__
+  return addr + (8 - len);
+#else
+  return addr;
+#endif
+}
+
+/* Store VALUE to ADDR in the current cpu implementation's fp spill format.
+   This is a macro instead of a function, so that it works for all 3 floating
+   point types without type conversions.  Type conversion to long double breaks
+   the denorm support.  */
+
+#define stf_spill(addr, value)	\
+  asm ("stf.spill %0 = %1%P0" : "=m" (*addr) : "f"(value));
+
+/* Load a value from ADDR, which is in the current cpu implementation's
+   fp spill format.  As above, this must also be a macro.  */
+
+#define ldf_fill(result, addr)	\
+  asm ("ldf.fill %0 = %1%P1" : "=f"(result) : "m"(*addr));
+
+/* Return the size of the C type associated with with TYPE.  Which will
+   be one of the FFI_IA64_TYPE_HFA_* values.  */
+
+static size_t
+hfa_type_size (int type)
+{
+  switch (type)
+    {
+    case FFI_IA64_TYPE_HFA_FLOAT:
+      return sizeof(float);
+    case FFI_IA64_TYPE_HFA_DOUBLE:
+      return sizeof(double);
+    case FFI_IA64_TYPE_HFA_LDOUBLE:
+      return sizeof(__float80);
+    default:
+      abort ();
+    }
+}
+
+/* Load from ADDR a value indicated by TYPE.  Which will be one of
+   the FFI_IA64_TYPE_HFA_* values.  */
+
+static void
+hfa_type_load (fpreg *fpaddr, int type, void *addr)
+{
+  switch (type)
+    {
+    case FFI_IA64_TYPE_HFA_FLOAT:
+      stf_spill (fpaddr, *(float *) addr);
+      return;
+    case FFI_IA64_TYPE_HFA_DOUBLE:
+      stf_spill (fpaddr, *(double *) addr);
+      return;
+    case FFI_IA64_TYPE_HFA_LDOUBLE:
+      stf_spill (fpaddr, *(__float80 *) addr);
+      return;
+    default:
+      abort ();
+    }
+}
+
+/* Load VALUE into ADDR as indicated by TYPE.  Which will be one of
+   the FFI_IA64_TYPE_HFA_* values.  */
+
+static void
+hfa_type_store (int type, void *addr, fpreg *fpaddr)
+{
+  switch (type)
+    {
+    case FFI_IA64_TYPE_HFA_FLOAT:
+      {
+	float result;
+	ldf_fill (result, fpaddr);
+	*(float *) addr = result;
+	break;
+      }
+    case FFI_IA64_TYPE_HFA_DOUBLE:
+      {
+	double result;
+	ldf_fill (result, fpaddr);
+	*(double *) addr = result;
+	break;
+      }
+    case FFI_IA64_TYPE_HFA_LDOUBLE:
+      {
+	__float80 result;
+	ldf_fill (result, fpaddr);
+	*(__float80 *) addr = result;
+	break;
+      }
+    default:
+      abort ();
+    }
+}
+
+/* Is TYPE a struct containing floats, doubles, or extended doubles,
+   all of the same fp type?  If so, return the element type.  Return
+   FFI_TYPE_VOID if not.  */
+
+static int
+hfa_element_type (ffi_type *type, int nested)
+{
+  int element = FFI_TYPE_VOID;
+
+  switch (type->type)
+    {
+    case FFI_TYPE_FLOAT:
+      /* We want to return VOID for raw floating-point types, but the
+	 synthetic HFA type if we're nested within an aggregate.  */
+      if (nested)
+	element = FFI_IA64_TYPE_HFA_FLOAT;
+      break;
+
+    case FFI_TYPE_DOUBLE:
+      /* Similarly.  */
+      if (nested)
+	element = FFI_IA64_TYPE_HFA_DOUBLE;
+      break;
+
+    case FFI_TYPE_LONGDOUBLE:
+      /* Similarly, except that that HFA is true for double extended,
+	 but not quad precision.  Both have sizeof == 16, so tell the
+	 difference based on the precision.  */
+      if (LDBL_MANT_DIG == 64 && nested)
+	element = FFI_IA64_TYPE_HFA_LDOUBLE;
+      break;
+
+    case FFI_TYPE_STRUCT:
+      {
+	ffi_type **ptr = &type->elements[0];
+
+	for (ptr = &type->elements[0]; *ptr ; ptr++)
+	  {
+	    int sub_element = hfa_element_type (*ptr, 1);
+	    if (sub_element == FFI_TYPE_VOID)
+	      return FFI_TYPE_VOID;
+
+	    if (element == FFI_TYPE_VOID)
+	      element = sub_element;
+	    else if (element != sub_element)
+	      return FFI_TYPE_VOID;
+	  }
+      }
+      break;
+
+    default:
+      return FFI_TYPE_VOID;
+    }
+
+  return element;
+}
+
+
+/* Perform machine dependent cif processing. */
+
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  int flags;
+
+  /* Adjust cif->bytes to include space for the bits of the ia64_args frame
+     that precedes the integer register portion.  The estimate that the
+     generic bits did for the argument space required is good enough for the
+     integer component.  */
+  cif->bytes += offsetof(struct ia64_args, gp_regs[0]);
+  if (cif->bytes < sizeof(struct ia64_args))
+    cif->bytes = sizeof(struct ia64_args);
+
+  /* Set the return type flag. */
+  flags = cif->rtype->type;
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_LONGDOUBLE:
+      /* Leave FFI_TYPE_LONGDOUBLE as meaning double extended precision,
+	 and encode quad precision as a two-word integer structure.  */
+      if (LDBL_MANT_DIG != 64)
+	flags = FFI_IA64_TYPE_SMALL_STRUCT | (16 << 8);
+      break;
+
+    case FFI_TYPE_STRUCT:
+      {
+        size_t size = cif->rtype->size;
+  	int hfa_type = hfa_element_type (cif->rtype, 0);
+
+	if (hfa_type != FFI_TYPE_VOID)
+	  {
+	    size_t nelts = size / hfa_type_size (hfa_type);
+	    if (nelts <= 8)
+	      flags = hfa_type | (size << 8);
+	  }
+	else
+	  {
+	    if (size <= 32)
+	      flags = FFI_IA64_TYPE_SMALL_STRUCT | (size << 8);
+	  }
+      }
+      break;
+
+    default:
+      break;
+    }
+  cif->flags = flags;
+
+  return FFI_OK;
+}
+
+extern int ffi_call_unix (struct ia64_args *, PTR64, void (*)(void), UINT64);
+
+void
+ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  struct ia64_args *stack;
+  long i, avn, gpcount, fpcount;
+  ffi_type **p_arg;
+
+  FFI_ASSERT (cif->abi == FFI_UNIX);
+
+  /* If we have no spot for a return value, make one.  */
+  if (rvalue == NULL && cif->rtype->type != FFI_TYPE_VOID)
+    rvalue = alloca (cif->rtype->size);
+    
+  /* Allocate the stack frame.  */
+  stack = alloca (cif->bytes);
+
+  gpcount = fpcount = 0;
+  avn = cif->nargs;
+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+    {
+      switch ((*p_arg)->type)
+	{
+	case FFI_TYPE_SINT8:
+	  stack->gp_regs[gpcount++] = *(SINT8 *)avalue[i];
+	  break;
+	case FFI_TYPE_UINT8:
+	  stack->gp_regs[gpcount++] = *(UINT8 *)avalue[i];
+	  break;
+	case FFI_TYPE_SINT16:
+	  stack->gp_regs[gpcount++] = *(SINT16 *)avalue[i];
+	  break;
+	case FFI_TYPE_UINT16:
+	  stack->gp_regs[gpcount++] = *(UINT16 *)avalue[i];
+	  break;
+	case FFI_TYPE_SINT32:
+	  stack->gp_regs[gpcount++] = *(SINT32 *)avalue[i];
+	  break;
+	case FFI_TYPE_UINT32:
+	  stack->gp_regs[gpcount++] = *(UINT32 *)avalue[i];
+	  break;
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	  stack->gp_regs[gpcount++] = *(UINT64 *)avalue[i];
+	  break;
+
+	case FFI_TYPE_POINTER:
+	  stack->gp_regs[gpcount++] = (UINT64)(PTR64) *(void **)avalue[i];
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  if (gpcount < 8 && fpcount < 8)
+	    stf_spill (&stack->fp_regs[fpcount++], *(float *)avalue[i]);
+	  stack->gp_regs[gpcount++] = *(UINT32 *)avalue[i];
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  if (gpcount < 8 && fpcount < 8)
+	    stf_spill (&stack->fp_regs[fpcount++], *(double *)avalue[i]);
+	  stack->gp_regs[gpcount++] = *(UINT64 *)avalue[i];
+	  break;
+
+	case FFI_TYPE_LONGDOUBLE:
+	  if (gpcount & 1)
+	    gpcount++;
+	  if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8)
+	    stf_spill (&stack->fp_regs[fpcount++], *(__float80 *)avalue[i]);
+	  memcpy (&stack->gp_regs[gpcount], avalue[i], 16);
+	  gpcount += 2;
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  {
+	    size_t size = (*p_arg)->size;
+	    size_t align = (*p_arg)->alignment;
+	    int hfa_type = hfa_element_type (*p_arg, 0);
+
+	    FFI_ASSERT (align <= 16);
+	    if (align == 16 && (gpcount & 1))
+	      gpcount++;
+
+	    if (hfa_type != FFI_TYPE_VOID)
+	      {
+		size_t hfa_size = hfa_type_size (hfa_type);
+		size_t offset = 0;
+		size_t gp_offset = gpcount * 8;
+
+		while (fpcount < 8
+		       && offset < size
+		       && gp_offset < 8 * 8)
+		  {
+		    hfa_type_load (&stack->fp_regs[fpcount], hfa_type,
+				   avalue[i] + offset);
+		    offset += hfa_size;
+		    gp_offset += hfa_size;
+		    fpcount += 1;
+		  }
+	      }
+
+	    memcpy (&stack->gp_regs[gpcount], avalue[i], size);
+	    gpcount += (size + 7) / 8;
+	  }
+	  break;
+
+	default:
+	  abort ();
+	}
+    }
+
+  ffi_call_unix (stack, rvalue, fn, cif->flags);
+}
+
+/* Closures represent a pair consisting of a function pointer, and
+   some user data.  A closure is invoked by reinterpreting the closure
+   as a function pointer, and branching to it.  Thus we can make an
+   interpreted function callable as a C function: We turn the
+   interpreter itself, together with a pointer specifying the
+   interpreted procedure, into a closure.
+
+   For IA64, function pointer are already pairs consisting of a code
+   pointer, and a gp pointer.  The latter is needed to access global
+   variables.  Here we set up such a pair as the first two words of
+   the closure (in the "trampoline" area), but we replace the gp
+   pointer with a pointer to the closure itself.  We also add the real
+   gp pointer to the closure.  This allows the function entry code to
+   both retrieve the user data, and to restire the correct gp pointer.  */
+
+extern void ffi_closure_unix ();
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif*,void*,void**,void*),
+		      void *user_data,
+		      void *codeloc)
+{
+  /* The layout of a function descriptor.  A C function pointer really 
+     points to one of these.  */
+  struct ia64_fd
+  {
+    UINT64 code_pointer;
+    UINT64 gp;
+  };
+
+  struct ffi_ia64_trampoline_struct
+  {
+    UINT64 code_pointer;	/* Pointer to ffi_closure_unix.  */
+    UINT64 fake_gp;		/* Pointer to closure, installed as gp.  */
+    UINT64 real_gp;		/* Real gp value.  */
+  };
+
+  struct ffi_ia64_trampoline_struct *tramp;
+  struct ia64_fd *fd;
+
+  if (cif->abi != FFI_UNIX)
+    return FFI_BAD_ABI;
+
+  tramp = (struct ffi_ia64_trampoline_struct *)closure->tramp;
+  fd = (struct ia64_fd *)(void *)ffi_closure_unix;
+
+  tramp->code_pointer = fd->code_pointer;
+  tramp->real_gp = fd->gp;
+  tramp->fake_gp = (UINT64)(PTR64)codeloc;
+  closure->cif = cif;
+  closure->user_data = user_data;
+  closure->fun = fun;
+
+  return FFI_OK;
+}
+
+
+UINT64
+ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
+			void *rvalue, void *r8)
+{
+  ffi_cif *cif;
+  void **avalue;
+  ffi_type **p_arg;
+  long i, avn, gpcount, fpcount;
+
+  cif = closure->cif;
+  avn = cif->nargs;
+  avalue = alloca (avn * sizeof (void *));
+
+  /* If the structure return value is passed in memory get that location
+     from r8 so as to pass the value directly back to the caller.  */
+  if (cif->flags == FFI_TYPE_STRUCT)
+    rvalue = r8;
+
+  gpcount = fpcount = 0;
+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+    {
+      switch ((*p_arg)->type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	  avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 1);
+	  break;
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	  avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 2);
+	  break;
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	  avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 4);
+	  break;
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	  avalue[i] = &stack->gp_regs[gpcount++];
+	  break;
+	case FFI_TYPE_POINTER:
+	  avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], sizeof(void*));
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  if (gpcount < 8 && fpcount < 8)
+	    {
+	      fpreg *addr = &stack->fp_regs[fpcount++];
+	      float result;
+	      avalue[i] = addr;
+	      ldf_fill (result, addr);
+	      *(float *)addr = result;
+	    }
+	  else
+	    avalue[i] = endian_adjust(&stack->gp_regs[gpcount], 4);
+	  gpcount++;
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  if (gpcount < 8 && fpcount < 8)
+	    {
+	      fpreg *addr = &stack->fp_regs[fpcount++];
+	      double result;
+	      avalue[i] = addr;
+	      ldf_fill (result, addr);
+	      *(double *)addr = result;
+	    }
+	  else
+	    avalue[i] = &stack->gp_regs[gpcount];
+	  gpcount++;
+	  break;
+
+	case FFI_TYPE_LONGDOUBLE:
+	  if (gpcount & 1)
+	    gpcount++;
+	  if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8)
+	    {
+	      fpreg *addr = &stack->fp_regs[fpcount++];
+	      __float80 result;
+	      avalue[i] = addr;
+	      ldf_fill (result, addr);
+	      *(__float80 *)addr = result;
+	    }
+	  else
+	    avalue[i] = &stack->gp_regs[gpcount];
+	  gpcount += 2;
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  {
+	    size_t size = (*p_arg)->size;
+	    size_t align = (*p_arg)->alignment;
+	    int hfa_type = hfa_element_type (*p_arg, 0);
+
+	    FFI_ASSERT (align <= 16);
+	    if (align == 16 && (gpcount & 1))
+	      gpcount++;
+
+	    if (hfa_type != FFI_TYPE_VOID)
+	      {
+		size_t hfa_size = hfa_type_size (hfa_type);
+		size_t offset = 0;
+		size_t gp_offset = gpcount * 8;
+		void *addr = alloca (size);
+
+		avalue[i] = addr;
+
+		while (fpcount < 8
+		       && offset < size
+		       && gp_offset < 8 * 8)
+		  {
+		    hfa_type_store (hfa_type, addr + offset,
+				    &stack->fp_regs[fpcount]);
+		    offset += hfa_size;
+		    gp_offset += hfa_size;
+		    fpcount += 1;
+		  }
+
+		if (offset < size)
+		  memcpy (addr + offset, (char *)stack->gp_regs + gp_offset,
+			  size - offset);
+	      }
+	    else
+	      avalue[i] = &stack->gp_regs[gpcount];
+
+	    gpcount += (size + 7) / 8;
+	  }
+	  break;
+
+	default:
+	  abort ();
+	}
+    }
+
+  closure->fun (cif, rvalue, avalue, closure->user_data);
+
+  return cif->flags;
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/ia64/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/ia64/ffitarget.h
new file mode 100755
index 0000000..0d2001d
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/ia64/ffitarget.h
@@ -0,0 +1,50 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for IA-64.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long long          ffi_arg;
+typedef signed long long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_UNIX,   	/* Linux and all Unix variants use the same conventions	*/
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_UNIX
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 24  /* Really the following struct, which 	*/
+				/* can be interpreted as a C function	*/
+				/* descriptor:				*/
+
+#endif
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/ia64/ia64_flags.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/ia64/ia64_flags.h
new file mode 100755
index 0000000..9d652ce
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/ia64/ia64_flags.h
@@ -0,0 +1,40 @@
+/* -----------------------------------------------------------------------
+   ia64_flags.h - Copyright (c) 2000 Hewlett Packard Company
+   
+   IA64/unix Foreign Function Interface 
+
+   Original author: Hans Boehm, HP Labs
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+/* "Type" codes used between assembly and C.  When used as a part of
+   a cfi->flags value, the low byte will be these extra type codes,
+   and bits 8-31 will be the actual size of the type.  */
+
+/* Small structures containing N words in integer registers.  */
+#define FFI_IA64_TYPE_SMALL_STRUCT	(FFI_TYPE_LAST + 1)
+
+/* Homogeneous Floating Point Aggregates (HFAs) which are returned
+   in FP registers.  */
+#define FFI_IA64_TYPE_HFA_FLOAT		(FFI_TYPE_LAST + 2)
+#define FFI_IA64_TYPE_HFA_DOUBLE	(FFI_TYPE_LAST + 3)
+#define FFI_IA64_TYPE_HFA_LDOUBLE	(FFI_TYPE_LAST + 4)
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/ia64/unix.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/ia64/unix.S
new file mode 100755
index 0000000..4d2a86d
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/ia64/unix.S
@@ -0,0 +1,560 @@
+/* -----------------------------------------------------------------------
+   unix.S - Copyright (c) 1998, 2008 Red Hat, Inc.
+            Copyright (c) 2000 Hewlett Packard Company
+   
+   IA64/unix Foreign Function Interface 
+
+   Primary author: Hans Boehm, HP Labs
+
+   Loosely modeled on Cygnus code for other platforms.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+#include "ia64_flags.h"
+
+	.pred.safe_across_calls p1-p5,p16-p63
+.text
+
+/* int ffi_call_unix (struct ia64_args *stack, PTR64 rvalue,
+		      void (*fn)(void), int flags);
+ */
+
+        .align 16
+        .global	ffi_call_unix
+        .proc	ffi_call_unix
+ffi_call_unix:
+	.prologue
+	/* Bit o trickiness.  We actually share a stack frame with ffi_call.
+	   Rely on the fact that ffi_call uses a vframe and don't bother
+	   tracking one here at all.  */
+	.fframe	0
+	.save	ar.pfs, r36 // loc0
+	alloc   loc0 = ar.pfs, 4, 3, 8, 0
+	.save	rp, loc1
+	mov 	loc1 = b0
+	.body
+	add	r16 = 16, in0
+	mov	loc2 = gp
+	mov	r8 = in1
+	;;
+
+	/* Load up all of the argument registers.  */
+	ldf.fill f8 = [in0], 32
+	ldf.fill f9 = [r16], 32
+	;;
+	ldf.fill f10 = [in0], 32
+	ldf.fill f11 = [r16], 32
+	;;
+	ldf.fill f12 = [in0], 32
+	ldf.fill f13 = [r16], 32
+	;;
+	ldf.fill f14 = [in0], 32
+	ldf.fill f15 = [r16], 24
+	;;
+	ld8	out0 = [in0], 16
+	ld8	out1 = [r16], 16
+	;;
+	ld8	out2 = [in0], 16
+	ld8	out3 = [r16], 16
+	;;
+	ld8	out4 = [in0], 16
+	ld8	out5 = [r16], 16
+	;;
+	ld8	out6 = [in0]
+	ld8	out7 = [r16]
+	;;
+
+	/* Deallocate the register save area from the stack frame.  */
+	mov	sp = in0
+
+	/* Call the target function.  */
+	ld8	r16 = [in2], 8
+	;;
+	ld8	gp = [in2]
+	mov	b6 = r16
+	br.call.sptk.many b0 = b6
+	;;
+
+	/* Dispatch to handle return value.  */
+	mov	gp = loc2
+	zxt1	r16 = in3
+	;;
+	mov	ar.pfs = loc0
+	addl	r18 = @ltoffx(.Lst_table), gp
+	;;
+	ld8.mov	r18 = [r18], .Lst_table
+	mov	b0 = loc1
+	;;
+	shladd	r18 = r16, 3, r18
+	;;
+	ld8	r17 = [r18]
+	shr	in3 = in3, 8
+	;;
+	add	r17 = r17, r18
+	;;
+	mov	b6 = r17
+	br	b6
+	;;
+
+.Lst_void:
+	br.ret.sptk.many b0
+	;;
+.Lst_uint8:
+	zxt1	r8 = r8
+	;;
+	st8	[in1] = r8
+	br.ret.sptk.many b0
+	;;
+.Lst_sint8:
+	sxt1	r8 = r8
+	;;
+	st8	[in1] = r8
+	br.ret.sptk.many b0
+	;;
+.Lst_uint16:
+	zxt2	r8 = r8
+	;;
+	st8	[in1] = r8
+	br.ret.sptk.many b0
+	;;
+.Lst_sint16:
+	sxt2	r8 = r8
+	;;
+	st8	[in1] = r8
+	br.ret.sptk.many b0
+	;;
+.Lst_uint32:
+	zxt4	r8 = r8
+	;;
+	st8	[in1] = r8
+	br.ret.sptk.many b0
+	;;
+.Lst_sint32:
+	sxt4	r8 = r8
+	;;
+	st8	[in1] = r8
+	br.ret.sptk.many b0
+	;;
+.Lst_int64:
+	st8	[in1] = r8
+	br.ret.sptk.many b0
+	;;
+.Lst_float:
+	stfs	[in1] = f8
+	br.ret.sptk.many b0
+	;;
+.Lst_double:
+	stfd	[in1] = f8
+	br.ret.sptk.many b0
+	;;
+.Lst_ldouble:
+	stfe	[in1] = f8
+	br.ret.sptk.many b0
+	;;
+
+.Lst_small_struct:
+	add	sp = -16, sp
+	cmp.lt	p6, p0 = 8, in3
+	cmp.lt	p7, p0 = 16, in3
+	cmp.lt	p8, p0 = 24, in3
+	;;
+	add	r16 = 8, sp
+	add	r17 = 16, sp
+	add	r18 = 24, sp
+	;;
+	st8	[sp] = r8
+(p6)	st8	[r16] = r9
+	mov	out0 = in1
+(p7)	st8	[r17] = r10
+(p8)	st8	[r18] = r11
+	mov	out1 = sp
+	mov	out2 = in3
+	br.call.sptk.many b0 = memcpy#
+	;;
+	mov	ar.pfs = loc0
+	mov	b0 = loc1
+	mov	gp = loc2
+	br.ret.sptk.many b0
+
+.Lst_hfa_float:
+	add	r16 = 4, in1
+	cmp.lt	p6, p0 = 4, in3
+	;;
+	stfs	[in1] = f8, 8
+(p6)	stfs	[r16] = f9, 8
+	cmp.lt	p7, p0 = 8, in3
+	cmp.lt	p8, p0 = 12, in3
+	;;
+(p7)	stfs	[in1] = f10, 8
+(p8)	stfs	[r16] = f11, 8
+	cmp.lt	p9, p0 = 16, in3
+	cmp.lt	p10, p0 = 20, in3
+	;;
+(p9)	stfs	[in1] = f12, 8
+(p10)	stfs	[r16] = f13, 8
+	cmp.lt	p6, p0 = 24, in3
+	cmp.lt	p7, p0 = 28, in3
+	;;
+(p6)	stfs	[in1] = f14
+(p7)	stfs	[r16] = f15
+	br.ret.sptk.many b0
+	;;
+
+.Lst_hfa_double:
+	add	r16 = 8, in1
+	cmp.lt	p6, p0 = 8, in3
+	;;
+	stfd	[in1] = f8, 16
+(p6)	stfd	[r16] = f9, 16
+	cmp.lt	p7, p0 = 16, in3
+	cmp.lt	p8, p0 = 24, in3
+	;;
+(p7)	stfd	[in1] = f10, 16
+(p8)	stfd	[r16] = f11, 16
+	cmp.lt	p9, p0 = 32, in3
+	cmp.lt	p10, p0 = 40, in3
+	;;
+(p9)	stfd	[in1] = f12, 16
+(p10)	stfd	[r16] = f13, 16
+	cmp.lt	p6, p0 = 48, in3
+	cmp.lt	p7, p0 = 56, in3
+	;;
+(p6)	stfd	[in1] = f14
+(p7)	stfd	[r16] = f15
+	br.ret.sptk.many b0
+	;;
+
+.Lst_hfa_ldouble:
+	add	r16 = 16, in1
+	cmp.lt	p6, p0 = 16, in3
+	;;
+	stfe	[in1] = f8, 32
+(p6)	stfe	[r16] = f9, 32
+	cmp.lt	p7, p0 = 32, in3
+	cmp.lt	p8, p0 = 48, in3
+	;;
+(p7)	stfe	[in1] = f10, 32
+(p8)	stfe	[r16] = f11, 32
+	cmp.lt	p9, p0 = 64, in3
+	cmp.lt	p10, p0 = 80, in3
+	;;
+(p9)	stfe	[in1] = f12, 32
+(p10)	stfe	[r16] = f13, 32
+	cmp.lt	p6, p0 = 96, in3
+	cmp.lt	p7, p0 = 112, in3
+	;;
+(p6)	stfe	[in1] = f14
+(p7)	stfe	[r16] = f15
+	br.ret.sptk.many b0
+	;;
+
+        .endp ffi_call_unix
+
+        .align 16
+        .global ffi_closure_unix
+        .proc ffi_closure_unix
+
+#define FRAME_SIZE	(8*16 + 8*8 + 8*16)
+
+ffi_closure_unix:
+	.prologue
+	.save	ar.pfs, r40 // loc0
+	alloc   loc0 = ar.pfs, 8, 4, 4, 0
+	.fframe	FRAME_SIZE
+	add	r12 = -FRAME_SIZE, r12
+	.save	rp, loc1
+	mov	loc1 = b0
+	.save	ar.unat, loc2
+	mov	loc2 = ar.unat
+	.body
+
+	/* Retrieve closure pointer and real gp.  */
+#ifdef _ILP32
+	addp4	out0 = 0, gp
+	addp4	gp = 16, gp
+#else
+	mov	out0 = gp
+	add	gp = 16, gp
+#endif
+	;;
+	ld8	gp = [gp]
+
+	/* Spill all of the possible argument registers.  */
+	add	r16 = 16 + 8*16, sp
+	add	r17 = 16 + 8*16 + 16, sp
+	;;
+	stf.spill [r16] = f8, 32
+	stf.spill [r17] = f9, 32
+	mov	loc3 = gp
+	;;
+	stf.spill [r16] = f10, 32
+	stf.spill [r17] = f11, 32
+	;;
+	stf.spill [r16] = f12, 32
+	stf.spill [r17] = f13, 32
+	;;
+	stf.spill [r16] = f14, 32
+	stf.spill [r17] = f15, 24
+	;;
+	.mem.offset 0, 0
+	st8.spill [r16] = in0, 16
+	.mem.offset 8, 0
+	st8.spill [r17] = in1, 16
+	add	out1 = 16 + 8*16, sp
+	;;
+	.mem.offset 0, 0
+	st8.spill [r16] = in2, 16
+	.mem.offset 8, 0
+	st8.spill [r17] = in3, 16
+	add	out2 = 16, sp
+	;;
+	.mem.offset 0, 0
+	st8.spill [r16] = in4, 16
+	.mem.offset 8, 0
+	st8.spill [r17] = in5, 16
+	mov	out3 = r8
+	;;
+	.mem.offset 0, 0
+	st8.spill [r16] = in6
+	.mem.offset 8, 0
+	st8.spill [r17] = in7
+
+	/* Invoke ffi_closure_unix_inner for the hard work.  */
+	br.call.sptk.many b0 = ffi_closure_unix_inner
+	;;
+
+	/* Dispatch to handle return value.  */
+	mov	gp = loc3
+	zxt1	r16 = r8
+	;;
+	addl	r18 = @ltoffx(.Lld_table), gp
+	mov	ar.pfs = loc0
+	;;
+	ld8.mov	r18 = [r18], .Lld_table
+	mov	b0 = loc1
+	;;
+	shladd	r18 = r16, 3, r18
+	mov	ar.unat = loc2
+	;;
+	ld8	r17 = [r18]
+	shr	r8 = r8, 8
+	;;
+	add	r17 = r17, r18
+	add	r16 = 16, sp
+	;;
+	mov	b6 = r17
+	br	b6
+	;;
+	.label_state 1
+
+.Lld_void:
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+.Lld_int:
+	.body
+	.copy_state 1
+	ld8	r8 = [r16]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+.Lld_float:
+	.body
+	.copy_state 1
+	ldfs	f8 = [r16]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+.Lld_double:
+	.body
+	.copy_state 1
+	ldfd	f8 = [r16]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+.Lld_ldouble:
+	.body
+	.copy_state 1
+	ldfe	f8 = [r16]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+
+.Lld_small_struct:
+	.body
+	.copy_state 1
+	add	r17 = 8, r16
+	cmp.lt	p6, p0 = 8, r8
+	cmp.lt	p7, p0 = 16, r8
+	cmp.lt	p8, p0 = 24, r8
+	;;
+	ld8	r8 = [r16], 16
+(p6)	ld8	r9 = [r17], 16
+	;;
+(p7)	ld8	r10 = [r16]
+(p8)	ld8	r11 = [r17]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+
+.Lld_hfa_float:
+	.body
+	.copy_state 1
+	add	r17 = 4, r16
+	cmp.lt	p6, p0 = 4, r8
+	;;
+	ldfs	f8 = [r16], 8
+(p6)	ldfs	f9 = [r17], 8
+	cmp.lt	p7, p0 = 8, r8
+	cmp.lt	p8, p0 = 12, r8
+	;;
+(p7)	ldfs	f10 = [r16], 8
+(p8)	ldfs	f11 = [r17], 8
+	cmp.lt	p9, p0 = 16, r8
+	cmp.lt	p10, p0 = 20, r8
+	;;
+(p9)	ldfs	f12 = [r16], 8
+(p10)	ldfs	f13 = [r17], 8
+	cmp.lt	p6, p0 = 24, r8
+	cmp.lt	p7, p0 = 28, r8
+	;;
+(p6)	ldfs	f14 = [r16]
+(p7)	ldfs	f15 = [r17]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+
+.Lld_hfa_double:
+	.body
+	.copy_state 1
+	add	r17 = 8, r16
+	cmp.lt	p6, p0 = 8, r8
+	;;
+	ldfd	f8 = [r16], 16
+(p6)	ldfd	f9 = [r17], 16
+	cmp.lt	p7, p0 = 16, r8
+	cmp.lt	p8, p0 = 24, r8
+	;;
+(p7)	ldfd	f10 = [r16], 16
+(p8)	ldfd	f11 = [r17], 16
+	cmp.lt	p9, p0 = 32, r8
+	cmp.lt	p10, p0 = 40, r8
+	;;
+(p9)	ldfd	f12 = [r16], 16
+(p10)	ldfd	f13 = [r17], 16
+	cmp.lt	p6, p0 = 48, r8
+	cmp.lt	p7, p0 = 56, r8
+	;;
+(p6)	ldfd	f14 = [r16]
+(p7)	ldfd	f15 = [r17]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+
+.Lld_hfa_ldouble:
+	.body
+	.copy_state 1
+	add	r17 = 16, r16
+	cmp.lt	p6, p0 = 16, r8
+	;;
+	ldfe	f8 = [r16], 32
+(p6)	ldfe	f9 = [r17], 32
+	cmp.lt	p7, p0 = 32, r8
+	cmp.lt	p8, p0 = 48, r8
+	;;
+(p7)	ldfe	f10 = [r16], 32
+(p8)	ldfe	f11 = [r17], 32
+	cmp.lt	p9, p0 = 64, r8
+	cmp.lt	p10, p0 = 80, r8
+	;;
+(p9)	ldfe	f12 = [r16], 32
+(p10)	ldfe	f13 = [r17], 32
+	cmp.lt	p6, p0 = 96, r8
+	cmp.lt	p7, p0 = 112, r8
+	;;
+(p6)	ldfe	f14 = [r16]
+(p7)	ldfe	f15 = [r17]
+	.restore sp
+	add	sp = FRAME_SIZE, sp
+	br.ret.sptk.many b0
+	;;
+
+	.endp	ffi_closure_unix
+
+	.section .rodata
+	.align	8
+.Lst_table:
+	data8	@pcrel(.Lst_void)		// FFI_TYPE_VOID
+	data8	@pcrel(.Lst_sint32)		// FFI_TYPE_INT
+	data8	@pcrel(.Lst_float)		// FFI_TYPE_FLOAT
+	data8	@pcrel(.Lst_double)		// FFI_TYPE_DOUBLE
+	data8	@pcrel(.Lst_ldouble)		// FFI_TYPE_LONGDOUBLE
+	data8	@pcrel(.Lst_uint8)		// FFI_TYPE_UINT8
+	data8	@pcrel(.Lst_sint8)		// FFI_TYPE_SINT8
+	data8	@pcrel(.Lst_uint16)		// FFI_TYPE_UINT16
+	data8	@pcrel(.Lst_sint16)		// FFI_TYPE_SINT16
+	data8	@pcrel(.Lst_uint32)		// FFI_TYPE_UINT32
+	data8	@pcrel(.Lst_sint32)		// FFI_TYPE_SINT32
+	data8	@pcrel(.Lst_int64)		// FFI_TYPE_UINT64
+	data8	@pcrel(.Lst_int64)		// FFI_TYPE_SINT64
+	data8	@pcrel(.Lst_void)		// FFI_TYPE_STRUCT
+	data8	@pcrel(.Lst_int64)		// FFI_TYPE_POINTER
+	data8 	@pcrel(.Lst_small_struct)	// FFI_IA64_TYPE_SMALL_STRUCT
+	data8	@pcrel(.Lst_hfa_float)		// FFI_IA64_TYPE_HFA_FLOAT
+	data8	@pcrel(.Lst_hfa_double)		// FFI_IA64_TYPE_HFA_DOUBLE
+	data8	@pcrel(.Lst_hfa_ldouble)	// FFI_IA64_TYPE_HFA_LDOUBLE
+
+.Lld_table:
+	data8	@pcrel(.Lld_void)		// FFI_TYPE_VOID
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_INT
+	data8	@pcrel(.Lld_float)		// FFI_TYPE_FLOAT
+	data8	@pcrel(.Lld_double)		// FFI_TYPE_DOUBLE
+	data8	@pcrel(.Lld_ldouble)		// FFI_TYPE_LONGDOUBLE
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT8
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT8
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT16
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT16
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT32
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT32
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT64
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT64
+	data8	@pcrel(.Lld_void)		// FFI_TYPE_STRUCT
+	data8	@pcrel(.Lld_int)		// FFI_TYPE_POINTER
+	data8 	@pcrel(.Lld_small_struct)	// FFI_IA64_TYPE_SMALL_STRUCT
+	data8	@pcrel(.Lld_hfa_float)		// FFI_IA64_TYPE_HFA_FLOAT
+	data8	@pcrel(.Lld_hfa_double)		// FFI_IA64_TYPE_HFA_DOUBLE
+	data8	@pcrel(.Lld_hfa_ldouble)	// FFI_IA64_TYPE_HFA_LDOUBLE
+
+#if defined __ELF__ && defined __linux__
+	.section	.note.GNU-stack,"", at progbits
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/java_raw_api.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/java_raw_api.c
new file mode 100755
index 0000000..522c8bf
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/java_raw_api.c
@@ -0,0 +1,356 @@
+/* -----------------------------------------------------------------------
+   java_raw_api.c - Copyright (c) 1999, 2007, 2008  Red Hat, Inc.
+
+   Cloned from raw_api.c
+
+   Raw_api.c author: Kresten Krab Thorup <krab at gnu.org>
+   Java_raw_api.c author: Hans-J. Boehm <hboehm at hpl.hp.com>
+
+   $Id $
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+/* This defines a Java- and 64-bit specific variant of the raw API.	*/
+/* It assumes that "raw" argument blocks look like Java stacks on a	*/
+/* 64-bit machine.  Arguments that can be stored in a single stack	*/
+/* stack slots (longs, doubles) occupy 128 bits, but only the first	*/
+/* 64 bits are actually used.						*/
+
+#include <ffi.h>
+#include <ffi_common.h>
+#include <stdlib.h>
+
+#if !defined(NO_JAVA_RAW_API) && !defined(FFI_NO_RAW_API)
+
+size_t
+ffi_java_raw_size (ffi_cif *cif)
+{
+  size_t result = 0;
+  int i;
+
+  ffi_type **at = cif->arg_types;
+
+  for (i = cif->nargs-1; i >= 0; i--, at++)
+    {
+      switch((*at) -> type) {
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_DOUBLE:
+	  result += 2 * FFI_SIZEOF_JAVA_RAW;
+	  break;
+	case FFI_TYPE_STRUCT:
+	  /* No structure parameters in Java.	*/
+	  abort();
+	default:
+	  result += FFI_SIZEOF_JAVA_RAW;
+      }
+    }
+
+  return result;
+}
+
+
+void
+ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args)
+{
+  unsigned i;
+  ffi_type **tp = cif->arg_types;
+
+#if WORDS_BIGENDIAN
+
+  for (i = 0; i < cif->nargs; i++, tp++, args++)
+    {
+      switch ((*tp)->type)
+	{
+	case FFI_TYPE_UINT8:
+	case FFI_TYPE_SINT8:
+	  *args = (void*) ((char*)(raw++) + 3);
+	  break;
+
+	case FFI_TYPE_UINT16:
+	case FFI_TYPE_SINT16:
+	  *args = (void*) ((char*)(raw++) + 2);
+	  break;
+
+#if FFI_SIZEOF_JAVA_RAW == 8
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_DOUBLE:
+	  *args = (void *)raw;
+	  raw += 2;
+	  break;
+#endif
+
+	case FFI_TYPE_POINTER:
+	  *args = (void*) &(raw++)->ptr;
+	  break;
+
+	default:
+	  *args = raw;
+	  raw +=
+	    ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
+	}
+    }
+
+#else /* WORDS_BIGENDIAN */
+
+#if !PDP
+
+  /* then assume little endian */
+  for (i = 0; i < cif->nargs; i++, tp++, args++)
+    {
+#if FFI_SIZEOF_JAVA_RAW == 8
+      switch((*tp)->type) {
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_DOUBLE:
+	  *args = (void*) raw;
+	  raw += 2;
+	  break;
+	default:
+	  *args = (void*) raw++;
+      }
+#else /* FFI_SIZEOF_JAVA_RAW != 8 */
+	*args = (void*) raw;
+	raw +=
+	  ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
+#endif /* FFI_SIZEOF_JAVA_RAW == 8 */
+    }
+
+#else
+#error "pdp endian not supported"
+#endif /* ! PDP */
+
+#endif /* WORDS_BIGENDIAN */
+}
+
+void
+ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw)
+{
+  unsigned i;
+  ffi_type **tp = cif->arg_types;
+
+  for (i = 0; i < cif->nargs; i++, tp++, args++)
+    {
+      switch ((*tp)->type)
+	{
+	case FFI_TYPE_UINT8:
+#if WORDS_BIGENDIAN
+	  *(UINT32*)(raw++) = *(UINT8*) (*args);
+#else
+	  (raw++)->uint = *(UINT8*) (*args);
+#endif
+	  break;
+
+	case FFI_TYPE_SINT8:
+#if WORDS_BIGENDIAN
+	  *(SINT32*)(raw++) = *(SINT8*) (*args);
+#else
+	  (raw++)->sint = *(SINT8*) (*args);
+#endif
+	  break;
+
+	case FFI_TYPE_UINT16:
+#if WORDS_BIGENDIAN
+	  *(UINT32*)(raw++) = *(UINT16*) (*args);
+#else
+	  (raw++)->uint = *(UINT16*) (*args);
+#endif
+	  break;
+
+	case FFI_TYPE_SINT16:
+#if WORDS_BIGENDIAN
+	  *(SINT32*)(raw++) = *(SINT16*) (*args);
+#else
+	  (raw++)->sint = *(SINT16*) (*args);
+#endif
+	  break;
+
+	case FFI_TYPE_UINT32:
+#if WORDS_BIGENDIAN
+	  *(UINT32*)(raw++) = *(UINT32*) (*args);
+#else
+	  (raw++)->uint = *(UINT32*) (*args);
+#endif
+	  break;
+
+	case FFI_TYPE_SINT32:
+#if WORDS_BIGENDIAN
+	  *(SINT32*)(raw++) = *(SINT32*) (*args);
+#else
+	  (raw++)->sint = *(SINT32*) (*args);
+#endif
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  (raw++)->flt = *(FLOAT32*) (*args);
+	  break;
+
+#if FFI_SIZEOF_JAVA_RAW == 8
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_DOUBLE:
+	  raw->uint = *(UINT64*) (*args);
+	  raw += 2;
+	  break;
+#endif
+
+	case FFI_TYPE_POINTER:
+	  (raw++)->ptr = **(void***) args;
+	  break;
+
+	default:
+#if FFI_SIZEOF_JAVA_RAW == 8
+	  FFI_ASSERT(0);	/* Should have covered all cases */
+#else
+	  memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
+	  raw +=
+	    ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
+#endif
+	}
+    }
+}
+
+#if !FFI_NATIVE_RAW_API
+
+static void
+ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue)
+{
+#if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_UINT32:
+      *(UINT64 *)rvalue <<= 32;
+      break;
+
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_INT:
+#if FFI_SIZEOF_JAVA_RAW == 4
+    case FFI_TYPE_POINTER:
+#endif
+      *(SINT64 *)rvalue <<= 32;
+      break;
+
+    default:
+      break;
+    }
+#endif
+}
+
+static void
+ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
+{
+#if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_UINT32:
+      *(UINT64 *)rvalue >>= 32;
+      break;
+
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_INT:
+      *(SINT64 *)rvalue >>= 32;
+      break;
+
+    default:
+      break;
+    }
+#endif
+}
+
+/* This is a generic definition of ffi_raw_call, to be used if the
+ * native system does not provide a machine-specific implementation.
+ * Having this, allows code to be written for the raw API, without
+ * the need for system-specific code to handle input in that format;
+ * these following couple of functions will handle the translation forth
+ * and back automatically. */
+
+void ffi_java_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue,
+			ffi_java_raw *raw)
+{
+  void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
+  ffi_java_raw_to_ptrarray (cif, raw, avalue);
+  ffi_call (cif, fn, rvalue, avalue);
+  ffi_java_rvalue_to_raw (cif, rvalue);
+}
+
+#if FFI_CLOSURES		/* base system provides closures */
+
+static void
+ffi_java_translate_args (ffi_cif *cif, void *rvalue,
+		    void **avalue, void *user_data)
+{
+  ffi_java_raw *raw = (ffi_java_raw*)alloca (ffi_java_raw_size (cif));
+  ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
+
+  ffi_java_ptrarray_to_raw (cif, avalue, raw);
+  (*cl->fun) (cif, rvalue, (ffi_raw*)raw, cl->user_data);
+  ffi_java_raw_to_rvalue (cif, rvalue);
+}
+
+ffi_status
+ffi_prep_java_raw_closure_loc (ffi_java_raw_closure* cl,
+			       ffi_cif *cif,
+			       void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
+			       void *user_data,
+			       void *codeloc)
+{
+  ffi_status status;
+
+  status = ffi_prep_closure_loc ((ffi_closure*) cl,
+				 cif,
+				 &ffi_java_translate_args,
+				 codeloc,
+				 codeloc);
+  if (status == FFI_OK)
+    {
+      cl->fun       = fun;
+      cl->user_data = user_data;
+    }
+
+  return status;
+}
+
+/* Again, here is the generic version of ffi_prep_raw_closure, which
+ * will install an intermediate "hub" for translation of arguments from
+ * the pointer-array format, to the raw format */
+
+ffi_status
+ffi_prep_java_raw_closure (ffi_java_raw_closure* cl,
+			   ffi_cif *cif,
+			   void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
+			   void *user_data)
+{
+  return ffi_prep_java_raw_closure_loc (cl, cif, fun, user_data, cl);
+}
+
+#endif /* FFI_CLOSURES */
+#endif /* !FFI_NATIVE_RAW_API */
+#endif /* !FFI_NO_RAW_API */
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m32r/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m32r/ffi.c
new file mode 100755
index 0000000..3000063
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m32r/ffi.c
@@ -0,0 +1,232 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2004  Renesas Technology
+           Copyright (c) 2008  Red Hat, Inc.
+   
+   M32R Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack
+   space has been allocated for the function's arguments.  */
+
+void ffi_prep_args(char *stack, extended_cif *ecif)
+{
+  unsigned int i;
+  int tmp;
+  unsigned int avn;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+  tmp = 0;
+  argp = stack;
+
+  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT && ecif->cif->rtype->size > 8)
+    {
+      *(void **) argp = ecif->rvalue;
+      argp += 4;
+    }
+
+  avn = ecif->cif->nargs;
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       (i != 0) && (avn != 0);
+       i--, p_arg++)
+    {
+      size_t z;
+
+      /* Align if necessary.  */
+      if (((*p_arg)->alignment - 1) & (unsigned) argp)
+	argp = (char *) ALIGN (argp, (*p_arg)->alignment);
+
+      if (avn != 0) 
+	{
+	  avn--;
+	  z = (*p_arg)->size;
+	  if (z < sizeof (int))
+	    {
+	      z = sizeof (int);
+
+	      switch ((*p_arg)->type)
+		{
+		case FFI_TYPE_SINT8:
+		  *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_UINT8:
+		  *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_SINT16:
+		  *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_UINT16:
+		  *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+		  break;
+		  
+		case FFI_TYPE_STRUCT:
+	  	  z = (*p_arg)->size;
+	  	  if ((*p_arg)->alignment != 1)
+		    memcpy (argp, *p_argv, z);
+		  else
+		    memcpy (argp + 4 - z, *p_argv, z);
+	  	  z = sizeof (int);
+		  break;
+
+		default:
+		  FFI_ASSERT(0);
+		}
+	    }
+	  else if (z == sizeof (int))
+	    {
+	       *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	    }
+	  else
+	    {
+	      if ((*p_arg)->type == FFI_TYPE_STRUCT)
+	        {
+		  if (z > 8)
+		    {
+		      *(unsigned int *) argp = (unsigned int)(void *)(* p_argv);
+		      z = sizeof(void *);
+		    }
+		  else
+		    {
+	              memcpy(argp, *p_argv, z);
+		      z = 8;
+		    }
+	        }
+	      else
+	        {
+		  /* Double or long long 64bit.  */
+	          memcpy (argp, *p_argv, z);
+	        }
+	    }
+	  p_argv++;
+	  argp += z;
+	}
+    }
+  
+  return;
+}
+
+/* Perform machine dependent cif processing.  */
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  /* Set the return type flag.  */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+      cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+    case FFI_TYPE_STRUCT:
+      if (cif->rtype->size <= 4)
+	cif->flags = FFI_TYPE_INT;
+
+      else if (cif->rtype->size <= 8)
+	cif->flags = FFI_TYPE_DOUBLE;
+
+      else
+	cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_DOUBLE:
+      cif->flags = FFI_TYPE_DOUBLE;
+      break;
+
+    case FFI_TYPE_FLOAT:
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
+			  unsigned, unsigned, unsigned *, void (*fn)(void));
+
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have
+     a return value address then we need to make one.  */
+  if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      ecif.rvalue = alloca (cif->rtype->size);
+    }
+  else
+    ecif.rvalue = rvalue;    
+  
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, 
+		    cif->flags, ecif.rvalue, fn);
+      if (cif->rtype->type == FFI_TYPE_STRUCT)
+	{
+	  int size = cif->rtype->size;
+	  int align = cif->rtype->alignment;
+
+	  if (size < 4)
+	    {
+	      if (align == 1)
+	        *(unsigned long *)(ecif.rvalue) <<= (4 - size) * 8;
+	    }
+	  else if (4 < size && size < 8)
+	    {
+	      if (align == 1)
+		{
+		  memcpy (ecif.rvalue, ecif.rvalue + 8-size, size);
+		}
+	      else if (align == 2)
+		{
+		  if (size & 1)
+		    size += 1;
+
+		  if (size != 8)
+		    memcpy (ecif.rvalue, ecif.rvalue + 8-size, size);
+		}
+	    }
+	}
+      break;
+
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m32r/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m32r/ffitarget.h
new file mode 100755
index 0000000..2e2ea48
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m32r/ffitarget.h
@@ -0,0 +1,48 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 2004  Renesas Technology.
+   Target configuration macros for M32R.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi
+  {
+    FFI_FIRST_ABI = 0,
+    FFI_SYSV,
+    FFI_LAST_ABI,
+    FFI_DEFAULT_ABI = FFI_SYSV
+  } ffi_abi;
+#endif
+
+#define FFI_CLOSURES 		0
+#define FFI_TRAMPOLINE_SIZE	24
+#define FFI_NATIVE_RAW_API 	0
+
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m32r/sysv.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m32r/sysv.S
new file mode 100755
index 0000000..06b75c2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m32r/sysv.S
@@ -0,0 +1,121 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2004 Renesas Technology
+   
+   M32R Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+/* XXX these lose for some platforms, I'm sure.  */
+#define CNAME(x) x
+#define ENTRY(x) .globl CNAME(x)! .type CNAME(x),%function! CNAME(x):
+#endif
+
+.text
+
+	/* R0:   ffi_prep_args */
+	/* R1:   &ecif */
+	/* R2:   cif->bytes */
+	/* R3:   fig->flags */
+	/* sp+0: ecif.rvalue */
+	/* sp+4: fn */
+
+	/* This assumes we are using gas.  */
+ENTRY(ffi_call_SYSV)
+	/* Save registers.  */
+	push	fp
+	push	lr
+	push	r3
+	push	r2
+	push	r1
+	push	r0
+	mv	fp, sp
+
+	/* Make room for all of the new args.  */
+	sub	sp, r2
+
+	/* Place all of the ffi_prep_args in position.  */
+	mv	lr, r0	
+	mv	r0, sp
+	/* R1 already set.  */
+
+	/* And call.  */
+	jl	lr
+
+	/* Move first 4 parameters in registers...  */
+	ld	r0, @(0,sp)
+	ld	r1, @(4,sp)
+	ld	r2, @(8,sp)
+        ld	r3, @(12,sp)
+
+	/* ...and adjust the stack.  */
+	ld	lr, @(8,fp)
+        cmpi	lr, #16
+	bc	adjust_stack
+	ldi	lr, #16
+adjust_stack:
+        add	sp, lr
+
+	/* Call the function.  */
+	ld	lr, @(28,fp)
+	jl	lr	
+
+	/* Remove the space we pushed for the args.  */
+	mv	sp, fp	
+
+	/* Load R2 with the pointer to storage for the return value.  */
+	ld	r2, @(24,sp)
+
+	/* Load R3 with the return type code.  */
+	ld	r3, @(12,sp)
+
+	/* If the return value pointer is NULL, assume no return value.  */
+	beqz	r2, epilogue
+
+	/* Return INT.  */
+	ldi	r4, #FFI_TYPE_INT
+	bne	r3, r4, return_double
+	st	r0, @r2	
+	bra	epilogue
+
+return_double:
+	/* Return DOUBLE or LONGDOUBLE.  */
+	ldi	r4, #FFI_TYPE_DOUBLE
+	bne	r3, r4, epilogue
+	st	r0, @r2	
+	st	r1, @(4,r2)
+
+epilogue:
+	pop	r0
+	pop	r1
+	pop	r2
+	pop	r3
+	pop	lr
+	pop	fp
+        jmp lr
+
+.ffi_call_SYSV_end:
+        .size    CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m68k/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m68k/ffi.c
new file mode 100755
index 0000000..0d4df1e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m68k/ffi.c
@@ -0,0 +1,288 @@
+/* -----------------------------------------------------------------------
+   ffi.c
+   
+   m68k Foreign Function Interface 
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#ifdef __rtems__
+void rtems_cache_flush_multiple_data_lines( const void *, size_t );
+#else
+#include <sys/syscall.h>
+#include <asm/cachectl.h>
+#endif
+
+void ffi_call_SYSV (extended_cif *,
+		    unsigned, unsigned,
+		    void *, void (*fn) ());
+void *ffi_prep_args (void *stack, extended_cif *ecif);
+void ffi_closure_SYSV (ffi_closure *);
+void ffi_closure_struct_SYSV (ffi_closure *);
+unsigned int ffi_closure_SYSV_inner (ffi_closure *closure,
+				     void *resp, void *args);
+
+/* ffi_prep_args is called by the assembly routine once stack space has
+   been allocated for the function's arguments.  */
+
+void *
+ffi_prep_args (void *stack, extended_cif *ecif)
+{
+  unsigned int i;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+  void *struct_value_ptr;
+
+  argp = stack;
+
+  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
+      && !ecif->cif->flags)
+    struct_value_ptr = ecif->rvalue;
+  else
+    struct_value_ptr = NULL;
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       i != 0;
+       i--, p_arg++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z < sizeof (int))
+	{
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;
+	      break;
+
+	    case FFI_TYPE_UINT8:
+	      *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv;
+	      break;
+
+	    case FFI_TYPE_SINT16:
+	      *(signed int *) argp = (signed int) *(SINT16 *) *p_argv;
+	      break;
+
+	    case FFI_TYPE_UINT16:
+	      *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv;
+	      break;
+
+	    case FFI_TYPE_STRUCT:
+	      memcpy (argp + sizeof (int) - z, *p_argv, z);
+	      break;
+
+	    default:
+	      FFI_ASSERT (0);
+	    }
+	  z = sizeof (int);
+	}
+      else
+	{
+	  memcpy (argp, *p_argv, z);
+
+	  /* Align if necessary.  */
+	  if ((sizeof(int) - 1) & z)
+	    z = ALIGN(z, sizeof(int));
+	}
+
+      p_argv++;
+      argp += z;
+    }
+
+  return struct_value_ptr;
+}
+
+#define CIF_FLAGS_INT		1
+#define CIF_FLAGS_DINT		2
+#define CIF_FLAGS_FLOAT		4
+#define CIF_FLAGS_DOUBLE	8
+#define CIF_FLAGS_LDOUBLE	16
+#define CIF_FLAGS_POINTER	32
+#define CIF_FLAGS_STRUCT1	64
+#define CIF_FLAGS_STRUCT2	128
+
+/* Perform machine dependent cif processing */
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+      cif->flags = 0;
+      break;
+
+    case FFI_TYPE_STRUCT:
+      switch (cif->rtype->size)
+	{
+	case 1:
+	  cif->flags = CIF_FLAGS_STRUCT1;
+	  break;
+	case 2:
+	  cif->flags = CIF_FLAGS_STRUCT2;
+	  break;
+	case 4:
+	  cif->flags = CIF_FLAGS_INT;
+	  break;
+	case 8:
+	  cif->flags = CIF_FLAGS_DINT;
+	  break;
+	default:
+	  cif->flags = 0;
+	  break;
+	}
+      break;
+
+    case FFI_TYPE_FLOAT:
+      cif->flags = CIF_FLAGS_FLOAT;
+      break;
+
+    case FFI_TYPE_DOUBLE:
+      cif->flags = CIF_FLAGS_DOUBLE;
+      break;
+
+#if (FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE)
+    case FFI_TYPE_LONGDOUBLE:
+      cif->flags = CIF_FLAGS_LDOUBLE;
+      break;
+#endif
+
+    case FFI_TYPE_POINTER:
+      cif->flags = CIF_FLAGS_POINTER;
+      break;
+
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      cif->flags = CIF_FLAGS_DINT;
+      break;
+
+    default:
+      cif->flags = CIF_FLAGS_INT;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+void
+ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+
+  /* If the return value is a struct and we don't have a return value
+     address then we need to make one.  */
+
+  if (rvalue == NULL
+      && cif->rtype->type == FFI_TYPE_STRUCT
+      && cif->rtype->size > 8)
+    ecif.rvalue = alloca (cif->rtype->size);
+  else
+    ecif.rvalue = rvalue;
+
+  switch (cif->abi)
+    {
+    case FFI_SYSV:
+      ffi_call_SYSV (&ecif, cif->bytes, cif->flags,
+		     ecif.rvalue, fn);
+      break;
+
+    default:
+      FFI_ASSERT (0);
+      break;
+    }
+}
+
+static void
+ffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif)
+{
+  unsigned int i;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+  argp = stack;
+  p_argv = avalue;
+
+  for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z <= 4)
+	{
+	  *p_argv = (void *) (argp + 4 - z);
+
+	  z = 4;
+	}
+      else
+	{
+	  *p_argv = (void *) argp;
+
+	  /* Align if necessary */
+	  if ((sizeof(int) - 1) & z)
+	    z = ALIGN(z, sizeof(int));
+	}
+
+      p_argv++;
+      argp += z;
+    }
+}
+
+unsigned int
+ffi_closure_SYSV_inner (ffi_closure *closure, void *resp, void *args)
+{
+  ffi_cif *cif;
+  void **arg_area;
+
+  cif = closure->cif;
+  arg_area = (void**) alloca (cif->nargs * sizeof (void *));
+
+  ffi_prep_incoming_args_SYSV(args, arg_area, cif);
+
+  (closure->fun) (cif, resp, arg_area, closure->user_data);
+
+  return cif->flags;
+}
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif*,void*,void**,void*),
+		      void *user_data,
+		      void *codeloc)
+{
+  FFI_ASSERT (cif->abi == FFI_SYSV);
+
+  *(unsigned short *)closure->tramp = 0x207c;
+  *(void **)(closure->tramp + 2) = codeloc;
+  *(unsigned short *)(closure->tramp + 6) = 0x4ef9;
+  if (cif->rtype->type == FFI_TYPE_STRUCT
+      && !cif->flags)
+    *(void **)(closure->tramp + 8) = ffi_closure_struct_SYSV;
+  else
+    *(void **)(closure->tramp + 8) = ffi_closure_SYSV;
+
+#ifdef __rtems__
+  rtems_cache_flush_multiple_data_lines( codeloc, FFI_TRAMPOLINE_SIZE );
+#else
+  syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE,
+	  FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE);
+#endif
+
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+
+  return FFI_OK;
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m68k/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m68k/ffitarget.h
new file mode 100755
index 0000000..3b777ed
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m68k/ffitarget.h
@@ -0,0 +1,49 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for Motorola 68K.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_SYSV
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 16
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m68k/sysv.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m68k/sysv.S
new file mode 100755
index 0000000..c782f51
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/m68k/sysv.S
@@ -0,0 +1,270 @@
+/* -----------------------------------------------------------------------
+	
+   sysv.S - Copyright (c) 1998 Andreas Schwab
+	    Copyright (c) 2008 Red Hat, Inc. 
+   
+   m68k Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+#ifdef HAVE_AS_CFI_PSEUDO_OP
+#define CFI_STARTPROC()		.cfi_startproc
+#define CFI_OFFSET(reg,off)	.cfi_offset	reg,off
+#define CFI_DEF_CFA(reg,off)	.cfi_def_cfa	reg,off
+#define CFI_ENDPROC()		.cfi_endproc
+#else
+#define CFI_STARTPROC()
+#define CFI_OFFSET(reg,off)
+#define CFI_DEF_CFA(reg,off)
+#define CFI_ENDPROC()
+#endif
+
+	.text
+
+	.globl	ffi_call_SYSV
+	.type	ffi_call_SYSV, at function
+	.align	4
+
+ffi_call_SYSV:
+	CFI_STARTPROC()
+	link	%fp,#0
+	CFI_OFFSET(14,-8)
+	CFI_DEF_CFA(14,8)
+	move.l	%d2,-(%sp)
+	CFI_OFFSET(2,-12)
+
+	| Make room for all of the new args.
+	sub.l	12(%fp),%sp
+
+	| Call ffi_prep_args
+	move.l	8(%fp),-(%sp)
+	pea	4(%sp)
+#if !defined __PIC__
+	jsr	ffi_prep_args
+#else
+	bsr.l	ffi_prep_args at PLTPC
+#endif
+	addq.l	#8,%sp	
+
+	| Pass pointer to struct value, if any
+	move.l	%a0,%a1
+
+	| Call the function
+	move.l	24(%fp),%a0
+	jsr	(%a0)
+
+	| Remove the space we pushed for the args
+	add.l	12(%fp),%sp
+
+	| Load the pointer to storage for the return value
+	move.l	20(%fp),%a1
+
+	| Load the return type code 
+	move.l	16(%fp),%d2
+
+	| If the return value pointer is NULL, assume no return value.
+	| NOTE: On the mc68000, tst on an address register is not supported.
+#if defined(__mc68000__) && !defined(__mcoldfire__)
+	cmp.w	#0, %a1
+#else
+	tst.l	%a1
+#endif
+	jbeq	noretval
+
+	btst	#0,%d2
+	jbeq	retlongint
+	move.l	%d0,(%a1)
+	jbra	epilogue
+
+retlongint:
+	btst	#1,%d2
+	jbeq	retfloat
+	move.l	%d0,(%a1)
+	move.l	%d1,4(%a1)
+	jbra	epilogue
+
+retfloat:
+	btst	#2,%d2
+	jbeq	retdouble
+#if defined(__MC68881__)
+	fmove.s	%fp0,(%a1)
+#else
+	move.l	%d0,(%a1)
+#endif
+	jbra	epilogue
+
+retdouble:
+	btst	#3,%d2
+	jbeq	retlongdouble
+#if defined(__MC68881__)
+	fmove.d	%fp0,(%a1)
+#else
+	move.l	%d0,(%a1)+
+	move.l	%d1,(%a1)
+#endif
+	jbra	epilogue
+
+retlongdouble:
+	btst	#4,%d2
+	jbeq	retpointer
+#if defined(__MC68881__)
+	fmove.x	%fp0,(%a1)
+#else
+	move.l	%d0,(%a1)+
+	move.l	%d1,(%a1)+
+	move.l	%d2,(%a1)
+#endif
+	jbra	epilogue
+
+retpointer:
+	btst	#5,%d2
+	jbeq	retstruct1
+	move.l	%a0,(%a1)
+	jbra	epilogue
+
+retstruct1:
+	btst	#6,%d2
+	jbeq	retstruct2
+	move.b	%d0,(%a1)
+	jbra	epilogue
+
+retstruct2:
+	btst	#7,%d2
+	jbeq	noretval
+	move.w	%d0,(%a1)
+
+noretval:
+epilogue:
+	move.l	(%sp)+,%d2
+	unlk	%fp
+	rts
+	CFI_ENDPROC()
+	.size	ffi_call_SYSV,.-ffi_call_SYSV
+
+	.globl	ffi_closure_SYSV
+	.type	ffi_closure_SYSV, @function
+	.align	4
+
+ffi_closure_SYSV:
+	CFI_STARTPROC()
+	link	%fp,#-12
+	CFI_OFFSET(14,-8)
+	CFI_DEF_CFA(14,8)
+	move.l	%sp,-12(%fp)
+	pea	8(%fp)
+	pea	-12(%fp)
+	move.l	%a0,-(%sp)
+#if !defined __PIC__
+	jsr	ffi_closure_SYSV_inner
+#else
+	bsr.l	ffi_closure_SYSV_inner at PLTPC
+#endif
+
+	lsr.l	#1,%d0
+	jne	1f
+	jcc	.Lcls_epilogue
+	move.l	-12(%fp),%d0
+.Lcls_epilogue:
+	unlk	%fp
+	rts
+1:
+	lea	-12(%fp),%a0
+	lsr.l	#2,%d0
+	jne	1f
+	jcs	.Lcls_ret_float
+	move.l	(%a0)+,%d0
+	move.l	(%a0),%d1
+	jra	.Lcls_epilogue
+.Lcls_ret_float:
+#if defined(__MC68881__)
+	fmove.s	(%a0),%fp0
+#else
+	move.l	(%a0),%d0
+#endif
+	jra	.Lcls_epilogue
+1:
+	lsr.l	#2,%d0
+	jne	1f
+	jcs	.Lcls_ret_ldouble
+#if defined(__MC68881__)
+	fmove.d	(%a0),%fp0
+#else
+	move.l	(%a0)+,%d0
+	move.l	(%a0),%d1
+#endif
+	jra	.Lcls_epilogue
+.Lcls_ret_ldouble:
+#if defined(__MC68881__)
+	fmove.x	(%a0),%fp0
+#else
+	move.l	(%a0)+,%d0
+	move.l	(%a0)+,%d1
+	move.l	(%a0),%d2
+#endif
+	jra	.Lcls_epilogue
+1:
+	lsr.l	#2,%d0
+	jne	.Lcls_ret_struct2
+	jcs	.Lcls_ret_struct1
+	move.l	(%a0),%a0
+	move.l	%a0,%d0
+	jra	.Lcls_epilogue
+.Lcls_ret_struct1:
+	move.b	(%a0),%d0
+	jra	.Lcls_epilogue
+.Lcls_ret_struct2:
+	move.w	(%a0),%d0
+	jra	.Lcls_epilogue
+	CFI_ENDPROC()
+
+	.size	ffi_closure_SYSV,.-ffi_closure_SYSV
+
+	.globl	ffi_closure_struct_SYSV
+	.type	ffi_closure_struct_SYSV, @function
+	.align	4
+
+ffi_closure_struct_SYSV:
+	CFI_STARTPROC()
+	link	%fp,#0
+	CFI_OFFSET(14,-8)
+	CFI_DEF_CFA(14,8)
+	move.l	%sp,-12(%fp)
+	pea	8(%fp)
+	move.l	%a1,-(%sp)
+	move.l	%a0,-(%sp)
+#if !defined __PIC__
+	jsr	ffi_closure_SYSV_inner
+#else
+	bsr.l	ffi_closure_SYSV_inner at PLTPC
+#endif
+	unlk	%fp
+	rts
+	CFI_ENDPROC()
+	.size	ffi_closure_struct_SYSV,.-ffi_closure_struct_SYSV
+
+#if defined __ELF__ && defined __linux__
+	.section	.note.GNU-stack,"", at progbits
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/mips/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/mips/ffi.c
new file mode 100755
index 0000000..79cff9b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/mips/ffi.c
@@ -0,0 +1,1036 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2011  Anthony Green
+           Copyright (c) 2008  David Daney
+           Copyright (c) 1996, 2007, 2008, 2011  Red Hat, Inc.
+   
+   MIPS Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+#ifdef __GNUC__
+#  if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))
+#    define USE__BUILTIN___CLEAR_CACHE 1
+#  endif
+#endif
+
+#ifndef USE__BUILTIN___CLEAR_CACHE
+#  if defined(__OpenBSD__)
+#    include <mips64/sysarch.h>
+#  else
+#    include <sys/cachectl.h>
+#  endif
+#endif
+
+#ifdef FFI_DEBUG
+# define FFI_MIPS_STOP_HERE() ffi_stop_here()
+#else
+# define FFI_MIPS_STOP_HERE() do {} while(0)
+#endif
+
+#ifdef FFI_MIPS_N32
+#define FIX_ARGP \
+FFI_ASSERT(argp <= &stack[bytes]); \
+if (argp == &stack[bytes]) \
+{ \
+  argp = stack; \
+  FFI_MIPS_STOP_HERE(); \
+}
+#else
+#define FIX_ARGP 
+#endif
+
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+static void ffi_prep_args(char *stack, 
+			  extended_cif *ecif,
+			  int bytes,
+			  int flags)
+{
+  int i;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+#ifdef FFI_MIPS_N32
+  /* If more than 8 double words are used, the remainder go
+     on the stack. We reorder stuff on the stack here to 
+     support this easily. */
+  if (bytes > 8 * sizeof(ffi_arg))
+    argp = &stack[bytes - (8 * sizeof(ffi_arg))];
+  else
+    argp = stack;
+#else
+  argp = stack;
+#endif
+
+  memset(stack, 0, bytes);
+
+#ifdef FFI_MIPS_N32
+  if ( ecif->cif->rstruct_flag != 0 )
+#else
+  if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )
+#endif  
+    {
+      *(ffi_arg *) argp = (ffi_arg) ecif->rvalue;
+      argp += sizeof(ffi_arg);
+      FIX_ARGP;
+    }
+
+  p_argv = ecif->avalue;
+
+  for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; i++, p_arg++)
+    {
+      size_t z;
+      unsigned int a;
+
+      /* Align if necessary.  */
+      a = (*p_arg)->alignment;
+      if (a < sizeof(ffi_arg))
+        a = sizeof(ffi_arg);
+      
+      if ((a - 1) & (unsigned long) argp)
+	{
+	  argp = (char *) ALIGN(argp, a);
+	  FIX_ARGP;
+	}
+
+      z = (*p_arg)->size;
+      if (z <= sizeof(ffi_arg))
+	{
+          int type = (*p_arg)->type;
+	  z = sizeof(ffi_arg);
+
+          /* The size of a pointer depends on the ABI */
+          if (type == FFI_TYPE_POINTER)
+            type = (ecif->cif->abi == FFI_N64
+		    || ecif->cif->abi == FFI_N64_SOFT_FLOAT)
+	      ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
+
+	if (i < 8 && (ecif->cif->abi == FFI_N32_SOFT_FLOAT
+		      || ecif->cif->abi == FFI_N64_SOFT_FLOAT))
+	  {
+	    switch (type)
+	      {
+	      case FFI_TYPE_FLOAT:
+		type = FFI_TYPE_UINT32;
+		break;
+	      case FFI_TYPE_DOUBLE:
+		type = FFI_TYPE_UINT64;
+		break;
+	      default:
+		break;
+	      }
+	  }
+	  switch (type)
+	    {
+	      case FFI_TYPE_SINT8:
+		*(ffi_arg *)argp = *(SINT8 *)(* p_argv);
+		break;
+
+	      case FFI_TYPE_UINT8:
+		*(ffi_arg *)argp = *(UINT8 *)(* p_argv);
+		break;
+		  
+	      case FFI_TYPE_SINT16:
+		*(ffi_arg *)argp = *(SINT16 *)(* p_argv);
+		break;
+		  
+	      case FFI_TYPE_UINT16:
+		*(ffi_arg *)argp = *(UINT16 *)(* p_argv);
+		break;
+		  
+	      case FFI_TYPE_SINT32:
+		*(ffi_arg *)argp = *(SINT32 *)(* p_argv);
+		break;
+		  
+	      case FFI_TYPE_UINT32:
+		*(ffi_arg *)argp = *(UINT32 *)(* p_argv);
+		break;
+
+	      /* This can only happen with 64bit slots.  */
+	      case FFI_TYPE_FLOAT:
+		*(float *) argp = *(float *)(* p_argv);
+		break;
+
+	      /* Handle structures.  */
+	      default:
+		memcpy(argp, *p_argv, (*p_arg)->size);
+		break;
+	    }
+	}
+      else
+	{
+#ifdef FFI_MIPS_O32
+	  memcpy(argp, *p_argv, z);
+#else
+	  {
+	    unsigned long end = (unsigned long) argp + z;
+	    unsigned long cap = (unsigned long) stack + bytes;
+
+	    /* Check if the data will fit within the register space.
+	       Handle it if it doesn't.  */
+
+	    if (end <= cap)
+	      memcpy(argp, *p_argv, z);
+	    else
+	      {
+		unsigned long portion = cap - (unsigned long)argp;
+
+		memcpy(argp, *p_argv, portion);
+		argp = stack;
+                z -= portion;
+		memcpy(argp, (void*)((unsigned long)(*p_argv) + portion),
+                       z);
+	      }
+	  }
+#endif
+      }
+      p_argv++;
+      argp += z;
+      FIX_ARGP;
+    }
+}
+
+#ifdef FFI_MIPS_N32
+
+/* The n32 spec says that if "a chunk consists solely of a double 
+   float field (but not a double, which is part of a union), it
+   is passed in a floating point register. Any other chunk is
+   passed in an integer register". This code traverses structure
+   definitions and generates the appropriate flags. */
+
+static unsigned
+calc_n32_struct_flags(int soft_float, ffi_type *arg,
+		      unsigned *loc, unsigned *arg_reg)
+{
+  unsigned flags = 0;
+  unsigned index = 0;
+
+  ffi_type *e;
+
+  if (soft_float)
+    return 0;
+
+  while ((e = arg->elements[index]))
+    {
+      /* Align this object.  */
+      *loc = ALIGN(*loc, e->alignment);
+      if (e->type == FFI_TYPE_DOUBLE)
+	{
+          /* Already aligned to FFI_SIZEOF_ARG.  */
+          *arg_reg = *loc / FFI_SIZEOF_ARG;
+          if (*arg_reg > 7)
+            break;
+	  flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS));
+          *loc += e->size;
+	}
+      else
+        *loc += e->size;
+      index++;
+    }
+  /* Next Argument register at alignment of FFI_SIZEOF_ARG.  */
+  *arg_reg = ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+
+  return flags;
+}
+
+static unsigned
+calc_n32_return_struct_flags(int soft_float, ffi_type *arg)
+{
+  unsigned flags = 0;
+  unsigned small = FFI_TYPE_SMALLSTRUCT;
+  ffi_type *e;
+
+  /* Returning structures under n32 is a tricky thing.
+     A struct with only one or two floating point fields 
+     is returned in $f0 (and $f2 if necessary). Any other
+     struct results at most 128 bits are returned in $2
+     (the first 64 bits) and $3 (remainder, if necessary).
+     Larger structs are handled normally. */
+  
+  if (arg->size > 16)
+    return 0;
+
+  if (arg->size > 8)
+    small = FFI_TYPE_SMALLSTRUCT2;
+
+  e = arg->elements[0];
+
+  if (e->type == FFI_TYPE_DOUBLE)
+    flags = FFI_TYPE_DOUBLE;
+  else if (e->type == FFI_TYPE_FLOAT)
+    flags = FFI_TYPE_FLOAT;
+
+  if (flags && (e = arg->elements[1]))
+    {
+      if (e->type == FFI_TYPE_DOUBLE)
+	flags += FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
+      else if (e->type == FFI_TYPE_FLOAT)
+	flags += FFI_TYPE_FLOAT << FFI_FLAG_BITS;
+      else 
+	return small;
+
+      if (flags && (arg->elements[2]))
+	{
+	  /* There are three arguments and the first two are 
+	     floats! This must be passed the old way. */
+	  return small;
+	}
+      if (soft_float)
+	flags += FFI_TYPE_STRUCT_SOFT;
+    }
+  else
+    if (!flags)
+      return small;
+
+  return flags;
+}
+
+#endif
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  cif->flags = 0;
+
+#ifdef FFI_MIPS_O32
+  /* Set the flags necessary for O32 processing.  FFI_O32_SOFT_FLOAT
+   * does not have special handling for floating point args.
+   */
+
+  if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
+    {
+      if (cif->nargs > 0)
+	{
+	  switch ((cif->arg_types)[0]->type)
+	    {
+	    case FFI_TYPE_FLOAT:
+	    case FFI_TYPE_DOUBLE:
+	      cif->flags += (cif->arg_types)[0]->type;
+	      break;
+	      
+	    default:
+	      break;
+	    }
+
+	  if (cif->nargs > 1)
+	    {
+	      /* Only handle the second argument if the first
+		 is a float or double. */
+	      if (cif->flags)
+		{
+		  switch ((cif->arg_types)[1]->type)
+		    {
+		    case FFI_TYPE_FLOAT:
+		    case FFI_TYPE_DOUBLE:
+		      cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
+		      break;
+		      
+		    default:
+		      break;
+		    }
+		}
+	    }
+	}
+    }
+      
+  /* Set the return type flag */
+
+  if (cif->abi == FFI_O32_SOFT_FLOAT)
+    {
+      switch (cif->rtype->type)
+        {
+        case FFI_TYPE_VOID:
+        case FFI_TYPE_STRUCT:
+          cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
+          break;
+
+        case FFI_TYPE_SINT64:
+        case FFI_TYPE_UINT64:
+        case FFI_TYPE_DOUBLE:
+          cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
+          break;
+      
+        case FFI_TYPE_FLOAT:
+        default:
+          cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
+          break;
+        }
+    }
+  else
+    {
+      /* FFI_O32 */      
+      switch (cif->rtype->type)
+        {
+        case FFI_TYPE_VOID:
+        case FFI_TYPE_STRUCT:
+        case FFI_TYPE_FLOAT:
+        case FFI_TYPE_DOUBLE:
+          cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
+          break;
+
+        case FFI_TYPE_SINT64:
+        case FFI_TYPE_UINT64:
+          cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
+          break;
+      
+        default:
+          cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
+          break;
+        }
+    }
+#endif
+
+#ifdef FFI_MIPS_N32
+  /* Set the flags necessary for N32 processing */
+  {
+    int type;
+    unsigned arg_reg = 0;
+    unsigned loc = 0;
+    unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
+    unsigned index = 0;
+
+    unsigned struct_flags = 0;
+    int soft_float = (cif->abi == FFI_N32_SOFT_FLOAT
+		      || cif->abi == FFI_N64_SOFT_FLOAT);
+
+    if (cif->rtype->type == FFI_TYPE_STRUCT)
+      {
+	struct_flags = calc_n32_return_struct_flags(soft_float, cif->rtype);
+
+	if (struct_flags == 0)
+	  {
+	    /* This means that the structure is being passed as
+	       a hidden argument */
+
+	    arg_reg = 1;
+	    count = (cif->nargs < 7) ? cif->nargs : 7;
+
+	    cif->rstruct_flag = !0;
+	  }
+	else
+	    cif->rstruct_flag = 0;
+      }
+    else
+      cif->rstruct_flag = 0;
+
+    while (count-- > 0 && arg_reg < 8)
+      {
+	type = (cif->arg_types)[index]->type;
+	if (soft_float)
+	  {
+	    switch (type)
+	      {
+	      case FFI_TYPE_FLOAT:
+		type = FFI_TYPE_UINT32;
+		break;
+	      case FFI_TYPE_DOUBLE:
+		type = FFI_TYPE_UINT64;
+		break;
+	      default:
+		break;
+	      }
+	  }
+	switch (type)
+	  {
+	  case FFI_TYPE_FLOAT:
+	  case FFI_TYPE_DOUBLE:
+	    cif->flags +=
+              ((cif->arg_types)[index]->type << (arg_reg * FFI_FLAG_BITS));
+	    arg_reg++;
+	    break;
+          case FFI_TYPE_LONGDOUBLE:
+            /* Align it.  */
+            arg_reg = ALIGN(arg_reg, 2);
+            /* Treat it as two adjacent doubles.  */
+	    if (soft_float) 
+	      {
+		arg_reg += 2;
+	      }
+	    else
+	      {
+		cif->flags +=
+		  (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
+		arg_reg++;
+		cif->flags +=
+		  (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
+		arg_reg++;
+	      }
+            break;
+
+	  case FFI_TYPE_STRUCT:
+            loc = arg_reg * FFI_SIZEOF_ARG;
+	    cif->flags += calc_n32_struct_flags(soft_float,
+						(cif->arg_types)[index],
+						&loc, &arg_reg);
+	    break;
+
+	  default:
+	    arg_reg++;
+            break;
+	  }
+
+	index++;
+      }
+
+  /* Set the return type flag */
+    switch (cif->rtype->type)
+      {
+      case FFI_TYPE_STRUCT:
+	{
+	  if (struct_flags == 0)
+	    {
+	      /* The structure is returned through a hidden
+		 first argument. Do nothing, 'cause FFI_TYPE_VOID 
+		 is 0 */
+	    }
+	  else
+	    {
+	      /* The structure is returned via some tricky
+		 mechanism */
+	      cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
+	      cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
+	    }
+	  break;
+	}
+      
+      case FFI_TYPE_VOID:
+	/* Do nothing, 'cause FFI_TYPE_VOID is 0 */
+	break;
+
+      case FFI_TYPE_POINTER:
+	if (cif->abi == FFI_N32_SOFT_FLOAT || cif->abi == FFI_N32)
+	  cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
+	else
+	  cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
+	break;
+
+      case FFI_TYPE_FLOAT:
+	if (soft_float)
+	  {
+	    cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
+	    break;
+	  }
+	/* else fall through */
+      case FFI_TYPE_DOUBLE:
+	if (soft_float)
+	  cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
+	else
+	  cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
+	break;
+
+      case FFI_TYPE_LONGDOUBLE:
+	/* Long double is returned as if it were a struct containing
+	   two doubles.  */
+	if (soft_float)
+	  {
+	    cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
+	    cif->flags += FFI_TYPE_SMALLSTRUCT2 << (4 + (FFI_FLAG_BITS * 8));
+ 	  }
+	else
+	  {
+	    cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
+	    cif->flags += (FFI_TYPE_DOUBLE
+			   + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS))
+					      << (4 + (FFI_FLAG_BITS * 8));
+	  }
+	break;
+      default:
+	cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
+	break;
+      }
+  }
+#endif
+  
+  return FFI_OK;
+}
+
+/* Low level routine for calling O32 functions */
+extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), 
+			extended_cif *, unsigned, 
+			unsigned, unsigned *, void (*)(void));
+
+/* Low level routine for calling N32 functions */
+extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), 
+			extended_cif *, unsigned, 
+			unsigned, void *, void (*)(void));
+
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+  
+  if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    ecif.rvalue = alloca(cif->rtype->size);
+  else
+    ecif.rvalue = rvalue;
+    
+  switch (cif->abi) 
+    {
+#ifdef FFI_MIPS_O32
+    case FFI_O32:
+    case FFI_O32_SOFT_FLOAT:
+      ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, 
+		   cif->flags, ecif.rvalue, fn);
+      break;
+#endif
+
+#ifdef FFI_MIPS_N32
+    case FFI_N32:
+    case FFI_N32_SOFT_FLOAT:
+    case FFI_N64:
+    case FFI_N64_SOFT_FLOAT:
+      {
+        int copy_rvalue = 0;
+	int copy_offset = 0;
+        char *rvalue_copy = ecif.rvalue;
+        if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)
+          {
+            /* For structures smaller than 16 bytes we clobber memory
+               in 8 byte increments.  Make a copy so we don't clobber
+               the callers memory outside of the struct bounds.  */
+            rvalue_copy = alloca(16);
+            copy_rvalue = 1;
+          }
+	else if (cif->rtype->type == FFI_TYPE_FLOAT
+		 && (cif->abi == FFI_N64_SOFT_FLOAT
+		     || cif->abi == FFI_N32_SOFT_FLOAT))
+	  {
+	    rvalue_copy = alloca (8);
+	    copy_rvalue = 1;
+#if defined(__MIPSEB__) || defined(_MIPSEB)
+	    copy_offset = 4;
+#endif
+	  }
+        ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
+                     cif->flags, rvalue_copy, fn);
+        if (copy_rvalue)
+          memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size);
+      }
+      break;
+#endif
+
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+#if FFI_CLOSURES
+#if defined(FFI_MIPS_O32)
+extern void ffi_closure_O32(void);
+#else
+extern void ffi_closure_N32(void);
+#endif /* FFI_MIPS_O32 */
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure *closure,
+		      ffi_cif *cif,
+		      void (*fun)(ffi_cif*,void*,void**,void*),
+		      void *user_data,
+		      void *codeloc)
+{
+  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
+  void * fn;
+  char *clear_location = (char *) codeloc;
+
+#if defined(FFI_MIPS_O32)
+  if (cif->abi != FFI_O32 && cif->abi != FFI_O32_SOFT_FLOAT)
+    return FFI_BAD_ABI;
+  fn = ffi_closure_O32;
+#else /* FFI_MIPS_N32 */
+  if (cif->abi != FFI_N32 && cif->abi != FFI_N64)
+    return FFI_BAD_ABI;
+  fn = ffi_closure_N32;
+#endif /* FFI_MIPS_O32 */
+
+#if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)
+  /* lui  $25,high(fn) */
+  tramp[0] = 0x3c190000 | ((unsigned)fn >> 16);
+  /* ori  $25,low(fn)  */
+  tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff);
+  /* lui  $12,high(codeloc) */
+  tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16);
+  /* jr   $25          */
+  tramp[3] = 0x03200008;
+  /* ori  $12,low(codeloc)  */
+  tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff);
+#else
+  /* N64 has a somewhat larger trampoline.  */
+  /* lui  $25,high(fn) */
+  tramp[0] = 0x3c190000 | ((unsigned long)fn >> 48);
+  /* lui  $12,high(codeloc) */
+  tramp[1] = 0x3c0c0000 | ((unsigned long)codeloc >> 48);
+  /* ori  $25,mid-high(fn)  */
+  tramp[2] = 0x37390000 | (((unsigned long)fn >> 32 ) & 0xffff);
+  /* ori  $12,mid-high(codeloc)  */
+  tramp[3] = 0x358c0000 | (((unsigned long)codeloc >> 32) & 0xffff);
+  /* dsll $25,$25,16 */
+  tramp[4] = 0x0019cc38;
+  /* dsll $12,$12,16 */
+  tramp[5] = 0x000c6438;
+  /* ori  $25,mid-low(fn)  */
+  tramp[6] = 0x37390000 | (((unsigned long)fn >> 16 ) & 0xffff);
+  /* ori  $12,mid-low(codeloc)  */
+  tramp[7] = 0x358c0000 | (((unsigned long)codeloc >> 16) & 0xffff);
+  /* dsll $25,$25,16 */
+  tramp[8] = 0x0019cc38;
+  /* dsll $12,$12,16 */
+  tramp[9] = 0x000c6438;
+  /* ori  $25,low(fn)  */
+  tramp[10] = 0x37390000 | ((unsigned long)fn  & 0xffff);
+  /* jr   $25          */
+  tramp[11] = 0x03200008;
+  /* ori  $12,low(codeloc)  */
+  tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff);
+
+#endif
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+#ifdef USE__BUILTIN___CLEAR_CACHE
+  __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE);
+#else
+  cacheflush (clear_location, FFI_TRAMPOLINE_SIZE, ICACHE);
+#endif
+  return FFI_OK;
+}
+
+/*
+ * Decodes the arguments to a function, which will be stored on the
+ * stack. AR is the pointer to the beginning of the integer arguments
+ * (and, depending upon the arguments, some floating-point arguments
+ * as well). FPR is a pointer to the area where floating point
+ * registers have been saved, if any.
+ *
+ * RVALUE is the location where the function return value will be
+ * stored. CLOSURE is the prepared closure to invoke.
+ *
+ * This function should only be called from assembly, which is in
+ * turn called from a trampoline.
+ *
+ * Returns the function return type.
+ *
+ * Based on the similar routine for sparc.
+ */
+int
+ffi_closure_mips_inner_O32 (ffi_closure *closure,
+			    void *rvalue, ffi_arg *ar,
+			    double *fpr)
+{
+  ffi_cif *cif;
+  void **avaluep;
+  ffi_arg *avalue;
+  ffi_type **arg_types;
+  int i, avn, argn, seen_int;
+
+  cif = closure->cif;
+  avalue = alloca (cif->nargs * sizeof (ffi_arg));
+  avaluep = alloca (cif->nargs * sizeof (ffi_arg));
+
+  seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
+  argn = 0;
+
+  if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
+    {
+      rvalue = (void *)(UINT32)ar[0];
+      argn = 1;
+    }
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+
+  while (i < avn)
+    {
+      if (i < 2 && !seen_int &&
+	  (arg_types[i]->type == FFI_TYPE_FLOAT ||
+	   arg_types[i]->type == FFI_TYPE_DOUBLE ||
+	   arg_types[i]->type == FFI_TYPE_LONGDOUBLE))
+	{
+#if defined(__MIPSEB__) || defined(_MIPSEB)
+	  if (arg_types[i]->type == FFI_TYPE_FLOAT)
+	    avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
+	  else
+#endif
+	    avaluep[i] = (char *) &fpr[i];
+	}
+      else
+	{
+	  if (arg_types[i]->alignment == 8 && (argn & 0x1))
+	    argn++;
+	  switch (arg_types[i]->type)
+	    {
+	      case FFI_TYPE_SINT8:
+		avaluep[i] = &avalue[i];
+		*(SINT8 *) &avalue[i] = (SINT8) ar[argn];
+		break;
+
+	      case FFI_TYPE_UINT8:
+		avaluep[i] = &avalue[i];
+		*(UINT8 *) &avalue[i] = (UINT8) ar[argn];
+		break;
+		  
+	      case FFI_TYPE_SINT16:
+		avaluep[i] = &avalue[i];
+		*(SINT16 *) &avalue[i] = (SINT16) ar[argn];
+		break;
+		  
+	      case FFI_TYPE_UINT16:
+		avaluep[i] = &avalue[i];
+		*(UINT16 *) &avalue[i] = (UINT16) ar[argn];
+		break;
+
+	      default:
+		avaluep[i] = (char *) &ar[argn];
+		break;
+	    }
+	  seen_int = 1;
+	}
+      argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+      i++;
+    }
+
+  /* Invoke the closure. */
+  (closure->fun) (cif, rvalue, avaluep, closure->user_data);
+
+  if (cif->abi == FFI_O32_SOFT_FLOAT)
+    {
+      switch (cif->rtype->type)
+        {
+        case FFI_TYPE_FLOAT:
+          return FFI_TYPE_INT;
+        case FFI_TYPE_DOUBLE:
+          return FFI_TYPE_UINT64;
+        default:
+          return cif->rtype->type;
+        }
+    }
+  else
+    {
+      return cif->rtype->type;
+    }
+}
+
+#if defined(FFI_MIPS_N32)
+
+static void
+copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
+                int argn, unsigned arg_offset, ffi_arg *ar,
+                ffi_arg *fpr, int soft_float)
+{
+  ffi_type **elt_typep = type->elements;
+  while(*elt_typep)
+    {
+      ffi_type *elt_type = *elt_typep;
+      unsigned o;
+      char *tp;
+      char *argp;
+      char *fpp;
+
+      o = ALIGN(offset, elt_type->alignment);
+      arg_offset += o - offset;
+      offset = o;
+      argn += arg_offset / sizeof(ffi_arg);
+      arg_offset = arg_offset % sizeof(ffi_arg);
+
+      argp = (char *)(ar + argn);
+      fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn);
+
+      tp = target + offset;
+
+      if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float)
+        *(double *)tp = *(double *)fpp;
+      else
+        memcpy(tp, argp + arg_offset, elt_type->size);
+
+      offset += elt_type->size;
+      arg_offset += elt_type->size;
+      elt_typep++;
+      argn += arg_offset / sizeof(ffi_arg);
+      arg_offset = arg_offset % sizeof(ffi_arg);
+    }
+}
+
+/*
+ * Decodes the arguments to a function, which will be stored on the
+ * stack. AR is the pointer to the beginning of the integer
+ * arguments. FPR is a pointer to the area where floating point
+ * registers have been saved.
+ *
+ * RVALUE is the location where the function return value will be
+ * stored. CLOSURE is the prepared closure to invoke.
+ *
+ * This function should only be called from assembly, which is in
+ * turn called from a trampoline.
+ *
+ * Returns the function return flags.
+ *
+ */
+int
+ffi_closure_mips_inner_N32 (ffi_closure *closure,
+			    void *rvalue, ffi_arg *ar,
+			    ffi_arg *fpr)
+{
+  ffi_cif *cif;
+  void **avaluep;
+  ffi_arg *avalue;
+  ffi_type **arg_types;
+  int i, avn, argn;
+  int soft_float;
+  ffi_arg *argp;
+
+  cif = closure->cif;
+  soft_float = cif->abi == FFI_N64_SOFT_FLOAT
+    || cif->abi == FFI_N32_SOFT_FLOAT;
+  avalue = alloca (cif->nargs * sizeof (ffi_arg));
+  avaluep = alloca (cif->nargs * sizeof (ffi_arg));
+
+  argn = 0;
+
+  if (cif->rstruct_flag)
+    {
+#if _MIPS_SIM==_ABIN32
+      rvalue = (void *)(UINT32)ar[0];
+#else /* N64 */
+      rvalue = (void *)ar[0];
+#endif
+      argn = 1;
+    }
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+
+  while (i < avn)
+    {
+      if (arg_types[i]->type == FFI_TYPE_FLOAT
+	  || arg_types[i]->type == FFI_TYPE_DOUBLE
+	  || arg_types[i]->type == FFI_TYPE_LONGDOUBLE)
+        {
+          argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn;
+          if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((unsigned)argp & (arg_types[i]->alignment-1)))
+            {
+              argp=(ffi_arg*)ALIGN(argp,arg_types[i]->alignment);
+              argn++;
+            }
+#if defined(__MIPSEB__) || defined(_MIPSEB)
+          if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
+            avaluep[i] = ((char *) argp) + sizeof (float);
+          else
+#endif
+            avaluep[i] = (char *) argp;
+        }
+      else
+        {
+          unsigned type = arg_types[i]->type;
+
+          if (arg_types[i]->alignment > sizeof(ffi_arg))
+            argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
+
+          argp = ar + argn;
+
+          /* The size of a pointer depends on the ABI */
+          if (type == FFI_TYPE_POINTER)
+            type = (cif->abi == FFI_N64 || cif->abi == FFI_N64_SOFT_FLOAT)
+	      ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
+
+	  if (soft_float && type ==  FFI_TYPE_FLOAT)
+	    type = FFI_TYPE_UINT32;
+
+          switch (type)
+            {
+            case FFI_TYPE_SINT8:
+              avaluep[i] = &avalue[i];
+              *(SINT8 *) &avalue[i] = (SINT8) *argp;
+              break;
+
+            case FFI_TYPE_UINT8:
+              avaluep[i] = &avalue[i];
+              *(UINT8 *) &avalue[i] = (UINT8) *argp;
+              break;
+
+            case FFI_TYPE_SINT16:
+              avaluep[i] = &avalue[i];
+              *(SINT16 *) &avalue[i] = (SINT16) *argp;
+              break;
+
+            case FFI_TYPE_UINT16:
+              avaluep[i] = &avalue[i];
+              *(UINT16 *) &avalue[i] = (UINT16) *argp;
+              break;
+
+            case FFI_TYPE_SINT32:
+              avaluep[i] = &avalue[i];
+              *(SINT32 *) &avalue[i] = (SINT32) *argp;
+              break;
+
+            case FFI_TYPE_UINT32:
+              avaluep[i] = &avalue[i];
+              *(UINT32 *) &avalue[i] = (UINT32) *argp;
+              break;
+
+            case FFI_TYPE_STRUCT:
+              if (argn < 8)
+                {
+                  /* Allocate space for the struct as at least part of
+                     it was passed in registers.  */
+                  avaluep[i] = alloca(arg_types[i]->size);
+                  copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
+                                  argn, 0, ar, fpr, soft_float);
+
+                  break;
+                }
+              /* Else fall through.  */
+            default:
+              avaluep[i] = (char *) argp;
+              break;
+            }
+        }
+      argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg);
+      i++;
+    }
+
+  /* Invoke the closure. */
+  (closure->fun) (cif, rvalue, avaluep, closure->user_data);
+
+  return cif->flags >> (FFI_FLAG_BITS * 8);
+}
+
+#endif /* FFI_MIPS_N32 */
+
+#endif /* FFI_CLOSURES */
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/mips/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/mips/ffitarget.h
new file mode 100755
index 0000000..637adbf
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/mips/ffitarget.h
@@ -0,0 +1,242 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for MIPS.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifdef linux
+# include <asm/sgidefs.h>
+#elif defined(__rtems__)
+/*
+ * Subprogram calling convention - copied from sgidefs.h
+ */
+#define _MIPS_SIM_ABI32		1
+#define _MIPS_SIM_NABI32	2
+#define _MIPS_SIM_ABI64		3
+#elif !defined(__OpenBSD__)
+# include <sgidefs.h>
+#endif
+
+#  ifndef _ABIN32
+#    define _ABIN32 _MIPS_SIM_NABI32
+#  endif
+#  ifndef _ABI64
+#    define _ABI64 _MIPS_SIM_ABI64
+#  endif
+#  ifndef _ABIO32
+#    define _ABIO32 _MIPS_SIM_ABI32
+#  endif
+
+#if !defined(_MIPS_SIM)
+# error -- something is very wrong --
+#else
+#  if (_MIPS_SIM==_ABIN32 && defined(_ABIN32)) || (_MIPS_SIM==_ABI64 && defined(_ABI64))
+#    define FFI_MIPS_N32
+#  else
+#    if (_MIPS_SIM==_ABIO32 && defined(_ABIO32))
+#      define FFI_MIPS_O32
+#    else
+#     error -- this is an unsupported platform --
+#    endif
+#  endif
+#endif
+
+#ifdef FFI_MIPS_O32
+/* O32 stack frames have 32bit integer args */
+#  define FFI_SIZEOF_ARG    4
+#else
+/* N32 and N64 frames have 64bit integer args */
+#  define FFI_SIZEOF_ARG    8
+#  if _MIPS_SIM == _ABIN32
+#    define FFI_SIZEOF_JAVA_RAW  4
+#  endif
+#endif
+
+#define FFI_FLAG_BITS 2
+
+/* SGI's strange assembler requires that we multiply by 4 rather 
+   than shift left by FFI_FLAG_BITS */
+
+#define FFI_ARGS_D   FFI_TYPE_DOUBLE
+#define FFI_ARGS_F   FFI_TYPE_FLOAT
+#define FFI_ARGS_DD  FFI_TYPE_DOUBLE * 4 + FFI_TYPE_DOUBLE
+#define FFI_ARGS_FF  FFI_TYPE_FLOAT * 4 +  FFI_TYPE_FLOAT
+#define FFI_ARGS_FD  FFI_TYPE_DOUBLE * 4 + FFI_TYPE_FLOAT
+#define FFI_ARGS_DF  FFI_TYPE_FLOAT * 4 + FFI_TYPE_DOUBLE
+
+/* Needed for N32 structure returns */
+#define FFI_TYPE_SMALLSTRUCT  FFI_TYPE_UINT8
+#define FFI_TYPE_SMALLSTRUCT2 FFI_TYPE_SINT8
+
+#if 0
+/* The SGI assembler can't handle this.. */
+#define FFI_TYPE_STRUCT_DD (( FFI_ARGS_DD ) << 4) + FFI_TYPE_STRUCT
+/* (and so on) */
+#else
+/* ...so we calculate these by hand! */
+#define FFI_TYPE_STRUCT_D      61
+#define FFI_TYPE_STRUCT_F      45
+#define FFI_TYPE_STRUCT_DD     253
+#define FFI_TYPE_STRUCT_FF     173
+#define FFI_TYPE_STRUCT_FD     237
+#define FFI_TYPE_STRUCT_DF     189
+#define FFI_TYPE_STRUCT_SMALL  93
+#define FFI_TYPE_STRUCT_SMALL2 109
+
+/* and for n32 soft float, add 16 * 2^4 */
+#define FFI_TYPE_STRUCT_D_SOFT      317
+#define FFI_TYPE_STRUCT_F_SOFT      301
+#define FFI_TYPE_STRUCT_DD_SOFT     509
+#define FFI_TYPE_STRUCT_FF_SOFT     429
+#define FFI_TYPE_STRUCT_FD_SOFT     493
+#define FFI_TYPE_STRUCT_DF_SOFT     445
+#define FFI_TYPE_STRUCT_SOFT        16
+#endif
+
+#ifdef LIBFFI_ASM
+#define v0 $2
+#define v1 $3
+#define a0 $4
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define a4 $8		
+#define a5 $9		
+#define a6 $10		
+#define a7 $11		
+#define t0 $8
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12		
+#define t5 $13
+#define t6 $14	
+#define t7 $15
+#define t8 $24
+#define t9 $25
+#define ra $31		
+
+#ifdef FFI_MIPS_O32
+# define REG_L	lw
+# define REG_S	sw
+# define SUBU	subu
+# define ADDU	addu
+# define SRL	srl
+# define LI	li
+#else /* !FFI_MIPS_O32 */
+# define REG_L	ld
+# define REG_S	sd
+# define SUBU	dsubu
+# define ADDU	daddu
+# define SRL	dsrl
+# define LI 	dli
+# if (_MIPS_SIM==_ABI64)
+#  define LA dla
+#  define EH_FRAME_ALIGN 3
+#  define FDE_ADDR_BYTES .8byte
+# else
+#  define LA la
+#  define EH_FRAME_ALIGN 2
+#  define FDE_ADDR_BYTES .4byte
+# endif /* _MIPS_SIM==_ABI64 */
+#endif /* !FFI_MIPS_O32 */
+#else /* !LIBFFI_ASM */
+# ifdef __GNUC__
+#  ifdef FFI_MIPS_O32
+/* O32 stack frames have 32bit integer args */
+typedef unsigned int     ffi_arg __attribute__((__mode__(__SI__)));
+typedef signed   int     ffi_sarg __attribute__((__mode__(__SI__)));
+#else
+/* N32 and N64 frames have 64bit integer args */
+typedef unsigned int     ffi_arg __attribute__((__mode__(__DI__)));
+typedef signed   int     ffi_sarg __attribute__((__mode__(__DI__)));
+#  endif
+# else
+#  ifdef FFI_MIPS_O32
+/* O32 stack frames have 32bit integer args */
+typedef __uint32_t ffi_arg;
+typedef __int32_t ffi_sarg;
+#  else
+/* N32 and N64 frames have 64bit integer args */
+typedef __uint64_t ffi_arg;
+typedef __int64_t ffi_sarg;
+#  endif
+# endif /* __GNUC__ */
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_O32,
+  FFI_N32,
+  FFI_N64,
+  FFI_O32_SOFT_FLOAT,
+  FFI_N32_SOFT_FLOAT,
+  FFI_N64_SOFT_FLOAT,
+  FFI_LAST_ABI,
+
+#ifdef FFI_MIPS_O32
+#ifdef __mips_soft_float
+  FFI_DEFAULT_ABI = FFI_O32_SOFT_FLOAT
+#else
+  FFI_DEFAULT_ABI = FFI_O32
+#endif
+#else
+# if _MIPS_SIM==_ABI64
+#  ifdef __mips_soft_float
+  FFI_DEFAULT_ABI = FFI_N64_SOFT_FLOAT
+#  else
+  FFI_DEFAULT_ABI = FFI_N64
+#  endif
+# else
+#  ifdef __mips_soft_float
+  FFI_DEFAULT_ABI = FFI_N32_SOFT_FLOAT
+#  else
+  FFI_DEFAULT_ABI = FFI_N32
+#  endif
+# endif
+#endif
+} ffi_abi;
+
+#define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag
+#endif /* !LIBFFI_ASM */
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if defined(FFI_MIPS_O32)
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 20
+#else
+/* N32/N64. */
+# define FFI_CLOSURES 1
+#if _MIPS_SIM==_ABI64
+#define FFI_TRAMPOLINE_SIZE 52
+#else
+#define FFI_TRAMPOLINE_SIZE 20
+#endif
+#endif /* FFI_MIPS_O32 */
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/mips/n32.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/mips/n32.S
new file mode 100755
index 0000000..ae23094
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/mips/n32.S
@@ -0,0 +1,591 @@
+/* -----------------------------------------------------------------------
+   n32.S - Copyright (c) 1996, 1998, 2005, 2007, 2009, 2010  Red Hat, Inc.
+   
+   MIPS Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+/* Only build this code if we are compiling for n32 */	
+
+#if defined(FFI_MIPS_N32)
+
+#define callback a0
+#define bytes	 a2
+#define flags	 a3
+#define raddr    a4
+#define fn       a5
+
+#define SIZEOF_FRAME	( 8 * FFI_SIZEOF_ARG )
+
+#ifdef __GNUC__
+	.abicalls
+#endif
+	.text
+	.align	2
+	.globl	ffi_call_N32
+	.ent	ffi_call_N32
+ffi_call_N32:	
+.LFB3:
+	.frame	$fp, SIZEOF_FRAME, ra
+	.mask	0xc0000000,-FFI_SIZEOF_ARG
+	.fmask	0x00000000,0
+
+	# Prologue
+	SUBU	$sp, SIZEOF_FRAME			# Frame size
+.LCFI0:
+	REG_S	$fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp)	# Save frame pointer
+	REG_S	ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp)	# Save return address
+.LCFI1:
+	move	$fp, $sp
+.LCFI3:
+	move	t9, callback	# callback function pointer
+	REG_S	bytes, 2*FFI_SIZEOF_ARG($fp) # bytes
+	REG_S	flags, 3*FFI_SIZEOF_ARG($fp) # flags
+	REG_S	raddr, 4*FFI_SIZEOF_ARG($fp) # raddr
+	REG_S	fn,    5*FFI_SIZEOF_ARG($fp) # fn
+
+	# Allocate at least 4 words in the argstack
+	move	v0, bytes
+	bge	bytes, 4 * FFI_SIZEOF_ARG, bigger	
+	LI	v0, 4 * FFI_SIZEOF_ARG
+	b	sixteen
+
+	bigger:	
+	ADDU	t4, v0, 2 * FFI_SIZEOF_ARG -1	# make sure it is aligned 
+	and	v0, t4, -2 * FFI_SIZEOF_ARG		# to a proper boundry.
+
+sixteen:
+	SUBU	$sp, $sp, v0	# move the stack pointer to reflect the
+				# arg space
+
+	move	a0, $sp         # 4 * FFI_SIZEOF_ARG
+	ADDU	a3, $fp, 3 * FFI_SIZEOF_ARG
+
+	# Call ffi_prep_args
+	jal	t9
+	
+	# Copy the stack pointer to t9
+	move	t9, $sp
+	
+	# Fix the stack if there are more than 8 64bit slots worth
+	# of arguments.
+
+	# Load the number of bytes
+	REG_L	t6, 2*FFI_SIZEOF_ARG($fp)
+
+	# Is it bigger than 8 * FFI_SIZEOF_ARG?
+	daddiu	t8, t6, -(8 * FFI_SIZEOF_ARG)
+	bltz	t8, loadregs
+
+	ADDU	t9, t9, t8
+	
+loadregs:	
+
+	REG_L	t6, 3*FFI_SIZEOF_ARG($fp)  # load the flags word into t6.
+
+	and	t4, t6, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg1_floatp
+	REG_L	a0, 0*FFI_SIZEOF_ARG(t9)
+	b	arg1_next
+arg1_floatp:	
+	bne	t4, FFI_TYPE_FLOAT, arg1_doublep
+	l.s	$f12, 0*FFI_SIZEOF_ARG(t9)
+	b	arg1_next
+arg1_doublep:	
+	l.d	$f12, 0*FFI_SIZEOF_ARG(t9)
+arg1_next:	
+	
+	SRL	t4, t6, 1*FFI_FLAG_BITS
+	and	t4, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg2_floatp
+	REG_L	a1, 1*FFI_SIZEOF_ARG(t9)
+	b	arg2_next
+arg2_floatp:
+	bne	t4, FFI_TYPE_FLOAT, arg2_doublep
+	l.s	$f13, 1*FFI_SIZEOF_ARG(t9)	
+	b	arg2_next
+arg2_doublep:	
+	l.d	$f13, 1*FFI_SIZEOF_ARG(t9)	
+arg2_next:	
+	
+	SRL	t4, t6, 2*FFI_FLAG_BITS
+	and	t4, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg3_floatp
+	REG_L	a2, 2*FFI_SIZEOF_ARG(t9)
+	b	arg3_next
+arg3_floatp:
+	bne	t4, FFI_TYPE_FLOAT, arg3_doublep
+	l.s	$f14, 2*FFI_SIZEOF_ARG(t9)	
+	b	arg3_next
+arg3_doublep:	
+	l.d	$f14, 2*FFI_SIZEOF_ARG(t9)	
+arg3_next:	
+	
+	SRL	t4, t6, 3*FFI_FLAG_BITS
+	and	t4, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg4_floatp
+	REG_L	a3, 3*FFI_SIZEOF_ARG(t9)
+	b	arg4_next
+arg4_floatp:
+	bne	t4, FFI_TYPE_FLOAT, arg4_doublep
+	l.s	$f15, 3*FFI_SIZEOF_ARG(t9)	
+	b	arg4_next
+arg4_doublep:	
+	l.d	$f15, 3*FFI_SIZEOF_ARG(t9)	
+arg4_next:	
+	
+	SRL	t4, t6, 4*FFI_FLAG_BITS
+	and	t4, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg5_floatp
+	REG_L	a4, 4*FFI_SIZEOF_ARG(t9)
+	b	arg5_next
+arg5_floatp:
+	bne	t4, FFI_TYPE_FLOAT, arg5_doublep
+	l.s	$f16, 4*FFI_SIZEOF_ARG(t9)	
+	b	arg5_next
+arg5_doublep:	
+	l.d	$f16, 4*FFI_SIZEOF_ARG(t9)	
+arg5_next:	
+	
+	SRL	t4, t6, 5*FFI_FLAG_BITS
+	and	t4, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg6_floatp
+	REG_L	a5, 5*FFI_SIZEOF_ARG(t9)
+	b	arg6_next
+arg6_floatp:
+	bne	t4, FFI_TYPE_FLOAT, arg6_doublep
+	l.s	$f17, 5*FFI_SIZEOF_ARG(t9)	
+	b	arg6_next
+arg6_doublep:	
+	l.d	$f17, 5*FFI_SIZEOF_ARG(t9)	
+arg6_next:	
+	
+	SRL	t4, t6, 6*FFI_FLAG_BITS
+	and	t4, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg7_floatp
+	REG_L	a6, 6*FFI_SIZEOF_ARG(t9)
+	b	arg7_next
+arg7_floatp:
+	bne	t4, FFI_TYPE_FLOAT, arg7_doublep
+	l.s	$f18, 6*FFI_SIZEOF_ARG(t9)	
+	b	arg7_next
+arg7_doublep:	
+	l.d	$f18, 6*FFI_SIZEOF_ARG(t9)	
+arg7_next:	
+	
+	SRL	t4, t6, 7*FFI_FLAG_BITS
+	and	t4, ((1<<FFI_FLAG_BITS)-1)
+	bnez	t4, arg8_floatp
+	REG_L	a7, 7*FFI_SIZEOF_ARG(t9)
+	b	arg8_next
+arg8_floatp:
+	bne	t4, FFI_TYPE_FLOAT, arg8_doublep
+ 	l.s	$f19, 7*FFI_SIZEOF_ARG(t9)	
+	b	arg8_next
+arg8_doublep:	
+ 	l.d	$f19, 7*FFI_SIZEOF_ARG(t9)	
+arg8_next:	
+
+callit:		
+	# Load the function pointer
+	REG_L	t9, 5*FFI_SIZEOF_ARG($fp)
+
+	# If the return value pointer is NULL, assume no return value.
+	REG_L	t5, 4*FFI_SIZEOF_ARG($fp)
+	beqz	t5, noretval
+
+	# Shift the return type flag over
+	SRL	t6, 8*FFI_FLAG_BITS
+
+	beq	t6, FFI_TYPE_SINT32, retint	
+	bne     t6, FFI_TYPE_INT, retfloat
+retint:
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	REG_S	v0, 0(t4)
+	b	epilogue
+
+retfloat:
+	bne     t6, FFI_TYPE_FLOAT, retdouble
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.s	$f0, 0(t4)
+	b	epilogue
+
+retdouble:	
+	bne	t6, FFI_TYPE_DOUBLE, retstruct_d
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.d	$f0, 0(t4)
+	b	epilogue
+
+retstruct_d:	
+	bne	t6, FFI_TYPE_STRUCT_D, retstruct_f
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.d	$f0, 0(t4)
+	b	epilogue
+	
+retstruct_f:	
+	bne	t6, FFI_TYPE_STRUCT_F, retstruct_d_d
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.s	$f0, 0(t4)
+	b	epilogue
+	
+retstruct_d_d:	
+	bne	t6, FFI_TYPE_STRUCT_DD, retstruct_f_f
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.d	$f0, 0(t4)
+	s.d	$f2, 8(t4)
+	b	epilogue
+	
+retstruct_f_f:	
+	bne	t6, FFI_TYPE_STRUCT_FF, retstruct_d_f
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.s	$f0, 0(t4)
+	s.s	$f2, 4(t4)
+	b	epilogue
+	
+retstruct_d_f:	
+	bne	t6, FFI_TYPE_STRUCT_DF, retstruct_f_d
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.d	$f0, 0(t4)
+	s.s	$f2, 8(t4)
+	b	epilogue
+	
+retstruct_f_d:	
+	bne	t6, FFI_TYPE_STRUCT_FD, retstruct_d_soft
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	s.s	$f0, 0(t4)
+	s.d	$f2, 8(t4)
+	b	epilogue
+
+retstruct_d_soft:
+	bne	t6, FFI_TYPE_STRUCT_D_SOFT, retstruct_f_soft
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	sd	v0, 0(t4)
+	b	epilogue
+	
+retstruct_f_soft:	
+	bne	t6, FFI_TYPE_STRUCT_F_SOFT, retstruct_d_d_soft
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	sw	v0, 0(t4)
+	b	epilogue
+	
+retstruct_d_d_soft:	
+	bne	t6, FFI_TYPE_STRUCT_DD_SOFT, retstruct_f_f_soft
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	sd	v0, 0(t4)
+	sd	v1, 8(t4)
+	b	epilogue
+	
+retstruct_f_f_soft:	
+	bne	t6, FFI_TYPE_STRUCT_FF_SOFT, retstruct_d_f_soft
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	sw	v0, 0(t4)
+	sw	v1, 4(t4)
+	b	epilogue
+	
+retstruct_d_f_soft:	
+	bne	t6, FFI_TYPE_STRUCT_DF_SOFT, retstruct_f_d_soft
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	sd	v0, 0(t4)
+	sw	v1, 8(t4)
+	b	epilogue
+	
+retstruct_f_d_soft:	
+	bne	t6, FFI_TYPE_STRUCT_FD_SOFT, retstruct_small
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	sw	v0, 0(t4)
+	sd	v1, 8(t4)
+	b	epilogue
+	
+retstruct_small:	
+	bne	t6, FFI_TYPE_STRUCT_SMALL, retstruct_small2
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	REG_S	v0, 0(t4)
+	b	epilogue
+	
+retstruct_small2:	
+	bne	t6, FFI_TYPE_STRUCT_SMALL2, retstruct
+	jal	t9
+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)
+	REG_S	v0, 0(t4)
+	REG_S	v1, 8(t4)
+	b	epilogue
+	
+retstruct:	
+noretval:	
+	jal	t9
+	
+	# Epilogue
+epilogue:	
+	move	$sp, $fp	
+	REG_L	$fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Restore frame pointer
+	REG_L	ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp)  # Restore return address
+	ADDU	$sp, SIZEOF_FRAME		      # Fix stack pointer
+	j	ra
+
+.LFE3:
+	.end	ffi_call_N32
+
+/* ffi_closure_N32. Expects address of the passed-in ffi_closure in t0
+   ($12). Stores any arguments passed in registers onto the stack,
+   then calls ffi_closure_mips_inner_N32, which then decodes
+   them.
+	
+	Stack layout:
+
+	20 - Start of parameters, original sp
+	19 - Called function a7 save
+	18 - Called function a6 save
+	17 - Called function a5 save
+	16 - Called function a4 save
+	15 - Called function a3 save
+	14 - Called function a2 save
+	13 - Called function a1 save
+	12 - Called function a0 save
+	11 - Called function f19
+	10 - Called function f18
+	 9 - Called function f17
+	 8 - Called function f16
+	 7 - Called function f15
+         6 - Called function f14
+         5 - Called function f13
+         4 - Called function f12
+	 3 - return value high (v1 or $f2)
+	 2 - return value low (v0 or $f0)
+	 1 - ra save
+	 0 - gp save our sp  points here
+	 */
+
+#define SIZEOF_FRAME2	(20 * FFI_SIZEOF_ARG)
+	
+#define A7_OFF2		(19 * FFI_SIZEOF_ARG)
+#define A6_OFF2		(18 * FFI_SIZEOF_ARG)
+#define A5_OFF2		(17 * FFI_SIZEOF_ARG)
+#define A4_OFF2		(16 * FFI_SIZEOF_ARG)
+#define A3_OFF2		(15 * FFI_SIZEOF_ARG)
+#define A2_OFF2		(14 * FFI_SIZEOF_ARG)
+#define A1_OFF2		(13 * FFI_SIZEOF_ARG)
+#define A0_OFF2		(12 * FFI_SIZEOF_ARG)	
+
+#define F19_OFF2	(11 * FFI_SIZEOF_ARG)
+#define F18_OFF2	(10 * FFI_SIZEOF_ARG)
+#define F17_OFF2	(9  * FFI_SIZEOF_ARG)
+#define F16_OFF2	(8  * FFI_SIZEOF_ARG)
+#define F15_OFF2	(7  * FFI_SIZEOF_ARG)
+#define F14_OFF2	(6  * FFI_SIZEOF_ARG)
+#define F13_OFF2	(5  * FFI_SIZEOF_ARG)
+#define F12_OFF2	(4  * FFI_SIZEOF_ARG)
+
+#define V1_OFF2		(3  * FFI_SIZEOF_ARG)
+#define V0_OFF2		(2  * FFI_SIZEOF_ARG)
+
+#define RA_OFF2		(1  * FFI_SIZEOF_ARG)
+#define GP_OFF2		(0  * FFI_SIZEOF_ARG)
+
+	.align	2
+	.globl	ffi_closure_N32
+	.ent	ffi_closure_N32
+ffi_closure_N32:
+.LFB2:
+	.frame	$sp, SIZEOF_FRAME2, ra
+	.mask	0x90000000,-(SIZEOF_FRAME2 - RA_OFF2)
+	.fmask	0x00000000,0
+	SUBU	$sp, SIZEOF_FRAME2
+.LCFI5:
+	.cpsetup t9, GP_OFF2, ffi_closure_N32
+	REG_S	ra, RA_OFF2($sp)	# Save return address
+.LCFI6:
+	# Store all possible argument registers. If there are more than
+	# fit in registers, then they were stored on the stack.
+	REG_S	a0, A0_OFF2($sp)
+	REG_S	a1, A1_OFF2($sp)
+	REG_S	a2, A2_OFF2($sp)
+	REG_S	a3, A3_OFF2($sp)
+	REG_S	a4, A4_OFF2($sp)
+	REG_S	a5, A5_OFF2($sp)
+	REG_S	a6, A6_OFF2($sp)
+	REG_S	a7, A7_OFF2($sp)
+
+	# Store all possible float/double registers.
+	s.d	$f12, F12_OFF2($sp)
+	s.d	$f13, F13_OFF2($sp)
+	s.d	$f14, F14_OFF2($sp)
+	s.d	$f15, F15_OFF2($sp)
+	s.d	$f16, F16_OFF2($sp)
+	s.d	$f17, F17_OFF2($sp)
+	s.d	$f18, F18_OFF2($sp)
+	s.d	$f19, F19_OFF2($sp)
+
+	# Call ffi_closure_mips_inner_N32 to do the real work.
+	LA	t9, ffi_closure_mips_inner_N32
+	move	a0, $12	 # Pointer to the ffi_closure
+	ADDU	a1, $sp, V0_OFF2
+	ADDU	a2, $sp, A0_OFF2
+	ADDU	a3, $sp, F12_OFF2
+	jalr	t9
+
+	# Return flags are in v0
+	bne     v0, FFI_TYPE_SINT32, cls_retint
+	lw	v0, V0_OFF2($sp)
+	b	cls_epilogue
+
+cls_retint:
+	bne     v0, FFI_TYPE_INT, cls_retfloat
+	REG_L	v0, V0_OFF2($sp)
+	b	cls_epilogue
+
+cls_retfloat:
+	bne     v0, FFI_TYPE_FLOAT, cls_retdouble
+	l.s	$f0, V0_OFF2($sp)
+	b	cls_epilogue
+
+cls_retdouble:	
+	bne	v0, FFI_TYPE_DOUBLE, cls_retstruct_d
+	l.d	$f0, V0_OFF2($sp)
+	b	cls_epilogue
+
+cls_retstruct_d:	
+	bne	v0, FFI_TYPE_STRUCT_D, cls_retstruct_f
+	l.d	$f0, V0_OFF2($sp)
+	b	cls_epilogue
+	
+cls_retstruct_f:	
+	bne	v0, FFI_TYPE_STRUCT_F, cls_retstruct_d_d
+	l.s	$f0, V0_OFF2($sp)
+	b	cls_epilogue
+	
+cls_retstruct_d_d:	
+	bne	v0, FFI_TYPE_STRUCT_DD, cls_retstruct_f_f
+	l.d	$f0, V0_OFF2($sp)
+	l.d	$f2, V1_OFF2($sp)
+	b	cls_epilogue
+	
+cls_retstruct_f_f:	
+	bne	v0, FFI_TYPE_STRUCT_FF, cls_retstruct_d_f
+	l.s	$f0, V0_OFF2($sp)
+	l.s	$f2, V1_OFF2($sp)
+	b	cls_epilogue
+	
+cls_retstruct_d_f:	
+	bne	v0, FFI_TYPE_STRUCT_DF, cls_retstruct_f_d
+	l.d	$f0, V0_OFF2($sp)
+	l.s	$f2, V1_OFF2($sp)
+	b	cls_epilogue
+	
+cls_retstruct_f_d:	
+	bne	v0, FFI_TYPE_STRUCT_FD, cls_retstruct_small2
+	l.s	$f0, V0_OFF2($sp)
+	l.d	$f2, V1_OFF2($sp)
+	b	cls_epilogue
+	
+cls_retstruct_small2:	
+	REG_L	v0, V0_OFF2($sp)
+	REG_L	v1, V1_OFF2($sp)
+	
+	# Epilogue
+cls_epilogue:	
+	REG_L	ra,  RA_OFF2($sp)	 # Restore return address
+	.cpreturn
+	ADDU	$sp, SIZEOF_FRAME2
+	j	ra
+.LFE2:	
+	.end	ffi_closure_N32
+
+#ifdef __GNUC__
+        .section        .eh_frame,"aw", at progbits
+.Lframe1:
+        .4byte  .LECIE1-.LSCIE1		# length
+.LSCIE1:
+        .4byte  0x0			# CIE
+        .byte   0x1			# Version 1
+        .ascii  "\000"			# Augmentation
+        .uleb128 0x1			# Code alignment 1
+        .sleb128 -4			# Data alignment -4
+        .byte   0x1f			# Return Address $31
+        .byte   0xc			# DW_CFA_def_cfa
+        .uleb128 0x1d			# in $sp
+        .uleb128 0x0			# offset 0
+        .align  EH_FRAME_ALIGN
+.LECIE1:
+
+.LSFDE1:
+        .4byte  .LEFDE1-.LASFDE1	# length.
+.LASFDE1:
+        .4byte  .LASFDE1-.Lframe1	# CIE_pointer.
+        FDE_ADDR_BYTES  .LFB3		# initial_location.
+        FDE_ADDR_BYTES  .LFE3-.LFB3	# address_range.
+        .byte   0x4			# DW_CFA_advance_loc4
+        .4byte  .LCFI0-.LFB3		# to .LCFI0
+        .byte   0xe			# DW_CFA_def_cfa_offset
+        .uleb128 SIZEOF_FRAME		# adjust stack.by SIZEOF_FRAME
+        .byte   0x4			# DW_CFA_advance_loc4
+        .4byte  .LCFI1-.LCFI0		# to .LCFI1
+        .byte   0x9e			# DW_CFA_offset of $fp
+        .uleb128 2*FFI_SIZEOF_ARG/4	# 
+        .byte   0x9f			# DW_CFA_offset of ra
+        .uleb128 1*FFI_SIZEOF_ARG/4	# 
+        .byte   0x4			# DW_CFA_advance_loc4
+        .4byte  .LCFI3-.LCFI1		# to .LCFI3
+        .byte   0xd			# DW_CFA_def_cfa_register
+        .uleb128 0x1e			# in $fp
+        .align  EH_FRAME_ALIGN
+.LEFDE1:
+.LSFDE3:
+	.4byte	.LEFDE3-.LASFDE3	# length
+.LASFDE3:
+	.4byte	.LASFDE3-.Lframe1	# CIE_pointer.
+	FDE_ADDR_BYTES	.LFB2		# initial_location.
+	FDE_ADDR_BYTES	.LFE2-.LFB2	# address_range.
+	.byte	0x4			# DW_CFA_advance_loc4
+	.4byte	.LCFI5-.LFB2		# to .LCFI5
+	.byte	0xe			# DW_CFA_def_cfa_offset
+	.uleb128 SIZEOF_FRAME2		# adjust stack.by SIZEOF_FRAME
+	.byte	0x4			# DW_CFA_advance_loc4
+	.4byte	.LCFI6-.LCFI5		# to .LCFI6
+	.byte	0x9c			# DW_CFA_offset of $gp ($28)
+	.uleb128 (SIZEOF_FRAME2 - GP_OFF2)/4
+	.byte	0x9f			# DW_CFA_offset of ra ($31)
+	.uleb128 (SIZEOF_FRAME2 - RA_OFF2)/4
+	.align	EH_FRAME_ALIGN
+.LEFDE3:
+#endif /* __GNUC__ */	
+	
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/mips/o32.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/mips/o32.S
new file mode 100755
index 0000000..eb27981
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/mips/o32.S
@@ -0,0 +1,381 @@
+/* -----------------------------------------------------------------------
+   o32.S - Copyright (c) 1996, 1998, 2005  Red Hat, Inc.
+   
+   MIPS Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+/* Only build this code if we are compiling for o32 */	
+
+#if defined(FFI_MIPS_O32)
+	
+#define callback a0
+#define bytes	 a2
+#define flags	 a3
+		
+#define SIZEOF_FRAME	(4 * FFI_SIZEOF_ARG + 2 * FFI_SIZEOF_ARG)
+#define A3_OFF		(SIZEOF_FRAME + 3 * FFI_SIZEOF_ARG)
+#define FP_OFF		(SIZEOF_FRAME - 2 * FFI_SIZEOF_ARG)
+#define RA_OFF		(SIZEOF_FRAME - 1 * FFI_SIZEOF_ARG)
+
+	.abicalls
+	.text
+	.align	2
+	.globl	ffi_call_O32
+	.ent	ffi_call_O32
+ffi_call_O32:	
+$LFB0:
+	# Prologue
+	SUBU	$sp, SIZEOF_FRAME	# Frame size
+$LCFI0:
+	REG_S	$fp, FP_OFF($sp)	# Save frame pointer
+$LCFI1:
+	REG_S	ra, RA_OFF($sp)		# Save return address
+$LCFI2:
+	move	$fp, $sp
+
+$LCFI3:
+	move	t9, callback		# callback function pointer
+	REG_S	flags, A3_OFF($fp)	# flags
+
+	# Allocate at least 4 words in the argstack
+	LI	v0, 4 * FFI_SIZEOF_ARG
+	blt	bytes, v0, sixteen
+
+	ADDU	v0, bytes, 7	# make sure it is aligned 
+	and	v0, -8		# to an 8 byte boundry
+
+sixteen:
+	SUBU	$sp, v0		# move the stack pointer to reflect the
+				# arg space
+
+	ADDU	a0, $sp, 4 * FFI_SIZEOF_ARG
+
+	jalr	t9
+	
+	REG_L	t0, A3_OFF($fp)		# load the flags word
+	SRL	t2, t0, 4		# shift our arg info
+	and     t0, ((1<<4)-1)          # mask out the return type
+		
+	ADDU	$sp, 4 * FFI_SIZEOF_ARG		# adjust $sp to new args
+
+	bnez	t0, pass_d			# make it quick for int
+	REG_L	a0, 0*FFI_SIZEOF_ARG($sp)	# just go ahead and load the
+	REG_L	a1, 1*FFI_SIZEOF_ARG($sp)	# four regs.
+	REG_L	a2, 2*FFI_SIZEOF_ARG($sp)
+	REG_L	a3, 3*FFI_SIZEOF_ARG($sp)
+	b	call_it
+
+pass_d:
+	bne	t0, FFI_ARGS_D, pass_f
+	l.d	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args
+	REG_L	a2,   2*FFI_SIZEOF_ARG($sp)	# passing a double
+	REG_L	a3,   3*FFI_SIZEOF_ARG($sp)
+	b	call_it
+
+pass_f:	
+	bne	t0, FFI_ARGS_F, pass_d_d
+	l.s	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args
+	REG_L	a1,   1*FFI_SIZEOF_ARG($sp)	# passing a float
+	REG_L	a2,   2*FFI_SIZEOF_ARG($sp)
+	REG_L	a3,   3*FFI_SIZEOF_ARG($sp)
+	b	call_it		
+
+pass_d_d:		
+	bne	t0, FFI_ARGS_DD, pass_f_f
+	l.d	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args
+	l.d	$f14, 2*FFI_SIZEOF_ARG($sp)	# passing two doubles
+	b	call_it
+
+pass_f_f:	
+	bne	t0, FFI_ARGS_FF, pass_d_f
+	l.s	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args
+	l.s	$f14, 1*FFI_SIZEOF_ARG($sp)	# passing two floats
+	REG_L	a2,   2*FFI_SIZEOF_ARG($sp)
+	REG_L	a3,   3*FFI_SIZEOF_ARG($sp)
+	b	call_it
+
+pass_d_f:		
+	bne	t0, FFI_ARGS_DF, pass_f_d
+	l.d	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args
+	l.s	$f14, 2*FFI_SIZEOF_ARG($sp)	# passing double and float
+	REG_L	a3,   3*FFI_SIZEOF_ARG($sp)
+	b	call_it
+
+pass_f_d:		
+ # assume that the only other combination must be float then double
+ #	bne	t0, FFI_ARGS_F_D, call_it
+	l.s	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args
+	l.d	$f14, 2*FFI_SIZEOF_ARG($sp)	# passing double and float
+
+call_it:	
+	# Load the function pointer
+	REG_L	t9, SIZEOF_FRAME + 5*FFI_SIZEOF_ARG($fp)
+
+	# If the return value pointer is NULL, assume no return value.
+	REG_L	t1, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+	beqz	t1, noretval
+
+	bne     t2, FFI_TYPE_INT, retlonglong
+	jalr	t9
+	REG_L	t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+	REG_S	v0, 0(t0)
+	b	epilogue
+
+retlonglong:
+	# Really any 64-bit int, signed or not.
+	bne	t2, FFI_TYPE_UINT64, retfloat
+	jalr	t9
+	REG_L	t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+	REG_S	v1, 4(t0)
+	REG_S	v0, 0(t0)
+	b	epilogue
+
+retfloat:
+	bne     t2, FFI_TYPE_FLOAT, retdouble
+	jalr	t9
+	REG_L	t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+	s.s	$f0, 0(t0)
+	b	epilogue
+
+retdouble:	
+	bne	t2, FFI_TYPE_DOUBLE, noretval
+	jalr	t9
+	REG_L	t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+	s.d	$f0, 0(t0)
+	b	epilogue
+	
+noretval:	
+	jalr	t9
+	
+	# Epilogue
+epilogue:	
+	move	$sp, $fp	
+	REG_L	$fp, FP_OFF($sp)	# Restore frame pointer
+	REG_L	ra, RA_OFF($sp)		# Restore return address
+	ADDU	$sp, SIZEOF_FRAME	# Fix stack pointer
+	j	ra
+
+$LFE0:
+	.end	ffi_call_O32
+
+
+/* ffi_closure_O32. Expects address of the passed-in ffi_closure
+	in t4 ($12). Stores any arguments passed in registers onto the
+	stack, then calls ffi_closure_mips_inner_O32, which
+	then decodes them.
+	
+	Stack layout:
+
+	 3 - a3 save
+	 2 - a2 save
+	 1 - a1 save
+	 0 - a0 save, original sp
+	-1 - ra save
+	-2 - fp save
+	-3 - $16 (s0) save
+	-4 - cprestore
+	-5 - return value high (v1)
+	-6 - return value low (v0)
+	-7 - f14 (le high, be low)
+	-8 - f14 (le low, be high)
+	-9 - f12 (le high, be low)
+       -10 - f12 (le low, be high)
+       -11 - Called function a3 save
+       -12 - Called function a2 save
+       -13 - Called function a1 save
+       -14 - Called function a0 save, our sp and fp point here
+	 */
+	
+#define SIZEOF_FRAME2	(14 * FFI_SIZEOF_ARG)
+#define A3_OFF2		(SIZEOF_FRAME2 + 3 * FFI_SIZEOF_ARG)
+#define A2_OFF2		(SIZEOF_FRAME2 + 2 * FFI_SIZEOF_ARG)
+#define A1_OFF2		(SIZEOF_FRAME2 + 1 * FFI_SIZEOF_ARG)
+#define A0_OFF2		(SIZEOF_FRAME2 + 0 * FFI_SIZEOF_ARG)
+#define RA_OFF2		(SIZEOF_FRAME2 - 1 * FFI_SIZEOF_ARG)
+#define FP_OFF2		(SIZEOF_FRAME2 - 2 * FFI_SIZEOF_ARG)
+#define S0_OFF2		(SIZEOF_FRAME2 - 3 * FFI_SIZEOF_ARG)
+#define GP_OFF2		(SIZEOF_FRAME2 - 4 * FFI_SIZEOF_ARG)
+#define V1_OFF2		(SIZEOF_FRAME2 - 5 * FFI_SIZEOF_ARG)
+#define V0_OFF2		(SIZEOF_FRAME2 - 6 * FFI_SIZEOF_ARG)
+#define FA_1_1_OFF2	(SIZEOF_FRAME2 - 7 * FFI_SIZEOF_ARG)
+#define FA_1_0_OFF2	(SIZEOF_FRAME2 - 8 * FFI_SIZEOF_ARG)
+#define FA_0_1_OFF2	(SIZEOF_FRAME2 - 9 * FFI_SIZEOF_ARG)
+#define FA_0_0_OFF2	(SIZEOF_FRAME2 - 10 * FFI_SIZEOF_ARG)
+
+	.text
+	.align	2
+	.globl	ffi_closure_O32
+	.ent	ffi_closure_O32
+ffi_closure_O32:
+$LFB1:
+	# Prologue
+	.frame	$fp, SIZEOF_FRAME2, ra
+	.set	noreorder
+	.cpload	t9
+	.set	reorder
+	SUBU	$sp, SIZEOF_FRAME2
+	.cprestore GP_OFF2
+$LCFI4:
+	REG_S	$16, S0_OFF2($sp)	 # Save s0
+	REG_S	$fp, FP_OFF2($sp)	 # Save frame pointer
+	REG_S	ra, RA_OFF2($sp)	 # Save return address
+$LCFI6:
+	move	$fp, $sp
+
+$LCFI7:
+	# Store all possible argument registers. If there are more than
+	# four arguments, then they are stored above where we put a3.
+	REG_S	a0, A0_OFF2($fp)
+	REG_S	a1, A1_OFF2($fp)
+	REG_S	a2, A2_OFF2($fp)
+	REG_S	a3, A3_OFF2($fp)
+
+	# Load ABI enum to s0
+	REG_L	$16, 20($12)	# cif pointer follows tramp.
+	REG_L	$16, 0($16)	# abi is first member.
+
+	li	$13, 1		# FFI_O32
+	bne	$16, $13, 1f	# Skip fp save if FFI_O32_SOFT_FLOAT
+	
+	# Store all possible float/double registers.
+	s.d	$f12, FA_0_0_OFF2($fp)
+	s.d	$f14, FA_1_0_OFF2($fp)
+1:	
+	# Call ffi_closure_mips_inner_O32 to do the work.
+	la	t9, ffi_closure_mips_inner_O32
+	move	a0, $12	 # Pointer to the ffi_closure
+	addu	a1, $fp, V0_OFF2
+	addu	a2, $fp, A0_OFF2
+	addu	a3, $fp, FA_0_0_OFF2
+	jalr	t9
+
+	# Load the return value into the appropriate register.
+	move	$8, $2
+	li	$9, FFI_TYPE_VOID
+	beq	$8, $9, closure_done
+
+	li	$13, 1		# FFI_O32
+	bne	$16, $13, 1f	# Skip fp restore if FFI_O32_SOFT_FLOAT
+
+	li	$9, FFI_TYPE_FLOAT
+	l.s	$f0, V0_OFF2($fp)
+	beq	$8, $9, closure_done
+
+	li	$9, FFI_TYPE_DOUBLE
+	l.d	$f0, V0_OFF2($fp)
+	beq	$8, $9, closure_done
+1:	
+	REG_L	$3, V1_OFF2($fp)
+	REG_L	$2, V0_OFF2($fp)
+
+closure_done:
+	# Epilogue
+	move	$sp, $fp
+	REG_L	$16, S0_OFF2($sp)	 # Restore s0
+	REG_L	$fp, FP_OFF2($sp)	 # Restore frame pointer
+	REG_L	ra,  RA_OFF2($sp)	 # Restore return address
+	ADDU	$sp, SIZEOF_FRAME2
+	j	ra
+$LFE1:
+	.end	ffi_closure_O32
+
+/* DWARF-2 unwind info. */
+
+	.section	.eh_frame,"a", at progbits
+$Lframe0:
+	.4byte	$LECIE0-$LSCIE0	 # Length of Common Information Entry
+$LSCIE0:
+	.4byte	0x0	 # CIE Identifier Tag
+	.byte	0x1	 # CIE Version
+	.ascii "zR\0"	 # CIE Augmentation
+	.uleb128 0x1	 # CIE Code Alignment Factor
+	.sleb128 4	 # CIE Data Alignment Factor
+	.byte	0x1f	 # CIE RA Column
+	.uleb128 0x1	 # Augmentation size
+	.byte	0x00	 # FDE Encoding (absptr)
+	.byte	0xc	 # DW_CFA_def_cfa
+	.uleb128 0x1d
+	.uleb128 0x0
+	.align	2
+$LECIE0:
+$LSFDE0:
+	.4byte	$LEFDE0-$LASFDE0	 # FDE Length
+$LASFDE0:
+	.4byte	$LASFDE0-$Lframe0	 # FDE CIE offset
+	.4byte	$LFB0	 # FDE initial location
+	.4byte	$LFE0-$LFB0	 # FDE address range
+	.uleb128 0x0	 # Augmentation size
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	$LCFI0-$LFB0
+	.byte	0xe	 # DW_CFA_def_cfa_offset
+	.uleb128 0x18
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	$LCFI2-$LCFI0
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x1e	 # $fp
+	.sleb128 -2	 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp)
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x1f	 # $ra
+	.sleb128 -1	 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp)
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	$LCFI3-$LCFI2
+	.byte	0xc	 # DW_CFA_def_cfa
+	.uleb128 0x1e
+	.uleb128 0x18
+	.align	2
+$LEFDE0:
+$LSFDE1:
+	.4byte	$LEFDE1-$LASFDE1	 # FDE Length
+$LASFDE1:
+	.4byte	$LASFDE1-$Lframe0	 # FDE CIE offset
+	.4byte	$LFB1	 # FDE initial location
+	.4byte	$LFE1-$LFB1	 # FDE address range
+	.uleb128 0x0	 # Augmentation size
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	$LCFI4-$LFB1
+	.byte	0xe	 # DW_CFA_def_cfa_offset
+	.uleb128 0x38
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	$LCFI6-$LCFI4
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x10	 # $16
+	.sleb128 -3	 # SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp)
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x1e	 # $fp
+	.sleb128 -2	 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp)
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x1f	 # $ra
+	.sleb128 -1	 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp)
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	$LCFI7-$LCFI6
+	.byte	0xc	 # DW_CFA_def_cfa
+	.uleb128 0x1e
+	.uleb128 0x38
+	.align	2
+$LEFDE1:
+
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/moxie/eabi.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/moxie/eabi.S
new file mode 100755
index 0000000..379ea4b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/moxie/eabi.S
@@ -0,0 +1,128 @@
+/* -----------------------------------------------------------------------
+   eabi.S - Copyright (c) 2004  Anthony Green
+   
+   FR-V Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+	.globl ffi_prep_args_EABI
+
+	.text
+	.p2align 4
+	.globl ffi_call_EABI
+	.type ffi_call_EABI, @function
+
+	# gr8 :   ffi_prep_args
+	# gr9 :   &ecif
+	# gr10:   cif->bytes
+	# gr11:   fig->flags
+	# gr12:   ecif.rvalue
+	# gr13:   fn
+	
+ffi_call_EABI:	
+	addi	sp, #-80, sp
+	sti	fp, @(sp, #24)
+	addi	sp, #24, fp
+	movsg	lr, gr5
+
+	/* Make room for the new arguments.  */
+	/* subi	sp, fp, gr10 */
+	
+	/* Store return address and incoming args on stack.  */
+	sti	gr5, @(fp, #8)
+	sti	gr8, @(fp, #-4)
+	sti	gr9, @(fp, #-8)
+	sti	gr10, @(fp, #-12)
+	sti	gr11, @(fp, #-16)
+	sti	gr12, @(fp, #-20)
+	sti	gr13, @(fp, #-24)
+
+	sub     sp, gr10, sp
+	
+	/* Call ffi_prep_args.  */
+	ldi	@(fp, #-4), gr4
+	addi	sp, #0, gr8
+	ldi	@(fp, #-8), gr9
+#ifdef __FRV_FDPIC__
+	ldd	@(gr4, gr0), gr14
+	calll	@(gr14, gr0)
+#else
+	calll	@(gr4, gr0)
+#endif	
+
+	/* ffi_prep_args returns the new stack pointer.  */
+	mov	gr8, gr4
+		
+	ldi	@(sp, #0), gr8
+	ldi	@(sp, #4), gr9
+	ldi	@(sp, #8), gr10
+	ldi	@(sp, #12), gr11
+	ldi	@(sp, #16), gr12
+	ldi	@(sp, #20), gr13
+
+	/* Always copy the return value pointer into the hidden
+	   parameter register.  This is only strictly necessary
+	   when we're returning an aggregate type, but it doesn't
+	   hurt to do this all the time, and it saves a branch.  */
+	ldi	@(fp, #-20), gr3
+
+	/* Use the ffi_prep_args return value for the new sp.  */
+	mov	gr4, sp
+	
+	/* Call the target function.  */
+	ldi	@(fp, -24), gr4
+#ifdef __FRV_FDPIC__
+	ldd	@(gr4, gr0), gr14
+	calll	@(gr14, gr0)
+#else
+	calll	@(gr4, gr0)
+#endif	
+
+	/* Store the result. */
+	ldi	@(fp, #-16), gr10  /* fig->flags */
+	ldi	@(fp, #-20), gr4   /* ecif.rvalue */
+
+	/* Is the return value stored in two registers?  */
+	cmpi	gr10, #8, icc0
+	bne	icc0, 0, .L2
+	/*   Yes, save them.  */
+	sti	gr8, @(gr4, #0)
+	sti	gr9, @(gr4, #4)
+	bra	.L3
+.L2:
+	/* Is the return value a structure?  */
+	cmpi	gr10, #-1, icc0
+	beq	icc0, 0, .L3
+	/*   No, save a 4 byte return value.  */
+	sti	gr8, @(gr4, #0)
+.L3:	
+
+	/* Restore the stack, and return.  */
+	ldi	@(fp, 8), gr5
+	ld	@(fp, gr0), fp
+	addi	sp,#80,sp
+	jmpl	@(gr5,gr0)
+	.size ffi_call_EABI, .-ffi_call_EABI
+	
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/moxie/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/moxie/ffi.c
new file mode 100755
index 0000000..54cbbb9
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/moxie/ffi.c
@@ -0,0 +1,276 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (C) 2009  Anthony Green
+   
+   Moxie Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+void *ffi_prep_args(char *stack, extended_cif *ecif)
+{
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+  register int count = 0;
+
+  p_argv = ecif->avalue;
+  argp = stack;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       (i != 0);
+       i--, p_arg++)
+    {
+      size_t z;
+      
+      z = (*p_arg)->size;
+
+      if ((*p_arg)->type == FFI_TYPE_STRUCT)
+	{
+	  z = sizeof(void*);
+	  *(void **) argp = *p_argv;
+	} 
+      /*      if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	{
+	  if (count > 24)
+	    {
+	      // This is going on the stack.  Turn it into a double.  
+	      *(double *) argp = (double) *(float*)(* p_argv);
+	      z = sizeof(double);
+	    }
+	  else
+	    *(void **) argp = *(void **)(* p_argv);
+	}  */
+      else if (z < sizeof(int))
+	{
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+	      break;
+	      
+	    case FFI_TYPE_UINT8:
+	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+	      break;
+	      
+	    case FFI_TYPE_SINT16:
+	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+	      break;
+		  
+	    case FFI_TYPE_UINT16:
+	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+	      break;
+		  
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	}
+      else if (z == sizeof(int))
+	{
+	  *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	}
+      else
+	{
+	  memcpy(argp, *p_argv, z);
+	}
+      p_argv++;
+      argp += z;
+      count += z;
+    }
+
+  return (stack + ((count > 24) ? 24 : ALIGN_DOWN(count, 8)));
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    cif->flags = -1;
+  else
+    cif->flags = cif->rtype->size;
+
+  cif->bytes = ALIGN (cif->bytes, 8);
+
+  return FFI_OK;
+}
+
+extern void ffi_call_EABI(void *(*)(char *, extended_cif *), 
+			  extended_cif *, 
+			  unsigned, unsigned, 
+			  unsigned *, 
+			  void (*fn)(void));
+
+void ffi_call(ffi_cif *cif, 
+	      void (*fn)(void), 
+	      void *rvalue, 
+	      void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      ecif.rvalue = alloca(cif->rtype->size);
+    }
+  else
+    ecif.rvalue = rvalue;
+    
+  
+  switch (cif->abi) 
+    {
+    case FFI_EABI:
+      ffi_call_EABI(ffi_prep_args, &ecif, cif->bytes, 
+		    cif->flags, ecif.rvalue, fn);
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3,
+		       unsigned arg4, unsigned arg5, unsigned arg6)
+{
+  /* This function is called by a trampoline.  The trampoline stows a
+     pointer to the ffi_closure object in gr7.  We must save this
+     pointer in a place that will persist while we do our work.  */
+  register ffi_closure *creg __asm__ ("gr7");
+  ffi_closure *closure = creg;
+
+  /* Arguments that don't fit in registers are found on the stack
+     at a fixed offset above the current frame pointer.  */
+  register char *frame_pointer __asm__ ("fp");
+  char *stack_args = frame_pointer + 16;
+
+  /* Lay the register arguments down in a continuous chunk of memory.  */
+  unsigned register_args[6] =
+    { arg1, arg2, arg3, arg4, arg5, arg6 };
+
+  ffi_cif *cif = closure->cif;
+  ffi_type **arg_types = cif->arg_types;
+  void **avalue = alloca (cif->nargs * sizeof(void *));
+  char *ptr = (char *) register_args;
+  int i;
+
+  /* Find the address of each argument.  */
+  for (i = 0; i < cif->nargs; i++)
+    {
+      switch (arg_types[i]->type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	  avalue[i] = ptr + 3;
+	  break;
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	  avalue[i] = ptr + 2;
+	  break;
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_FLOAT:
+	  avalue[i] = ptr;
+	  break;
+	case FFI_TYPE_STRUCT:
+	  avalue[i] = *(void**)ptr;
+	  break;
+	default:
+	  /* This is an 8-byte value.  */
+	  avalue[i] = ptr;
+	  ptr += 4;
+	  break;
+	}
+      ptr += 4;
+
+      /* If we've handled more arguments than fit in registers,
+	 start looking at the those passed on the stack.  */
+      if (ptr == ((char *)register_args + (6*4)))
+	ptr = stack_args;
+    }
+
+  /* Invoke the closure.  */
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      /* The caller allocates space for the return structure, and
+       passes a pointer to this space in gr3.  Use this value directly
+       as the return value.  */
+      register void *return_struct_ptr __asm__("gr3");
+      (closure->fun) (cif, return_struct_ptr, avalue, closure->user_data);
+    }
+  else
+    {
+      /* Allocate space for the return value and call the function.  */
+      long long rvalue;
+      (closure->fun) (cif, &rvalue, avalue, closure->user_data);
+
+      /* Functions return 4-byte or smaller results in gr8.  8-byte
+	 values also use gr9.  We fill the both, even for small return
+	 values, just to avoid a branch.  */ 
+      asm ("ldi  @(%0, #0), gr8" : : "r" (&rvalue));
+      asm ("ldi  @(%0, #0), gr9" : : "r" (&((int *) &rvalue)[1]));
+    }
+}
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif*, void*, void**, void*),
+		      void *user_data,
+		      void *codeloc)
+{
+  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
+  unsigned long fn = (long) ffi_closure_eabi;
+  unsigned long cls = (long) codeloc;
+  int i;
+
+  fn = (unsigned long) ffi_closure_eabi;
+
+  tramp[0] = 0x8cfc0000 + (fn  & 0xffff); /* setlos lo(fn), gr6    */
+  tramp[1] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7   */
+  tramp[2] = 0x8cf80000 + (fn  >> 16);	  /* sethi hi(fn), gr6     */
+  tramp[3] = 0x8ef80000 + (cls >> 16);    /* sethi hi(cls), gr7    */
+  tramp[4] = 0x80300006;                  /* jmpl @(gr0, gr6)      */
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  /* Cache flushing.  */
+  for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++)
+    __asm__ volatile ("dcf @(%0,%1)\n\tici @(%2,%1)" :: "r" (tramp), "r" (i),
+		      "r" (codeloc));
+
+  return FFI_OK;
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/pa/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/pa/ffi.c
new file mode 100755
index 0000000..4ce2bc6
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/pa/ffi.c
@@ -0,0 +1,719 @@
+/* -----------------------------------------------------------------------
+   ffi.c - (c) 2011 Anthony Green
+           (c) 2008 Red Hat, Inc.
+	   (c) 2006 Free Software Foundation, Inc.
+           (c) 2003-2004 Randolph Chung <tausq at debian.org>
+           
+   HPPA Foreign Function Interface
+   HP-UX PA ABI support 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define ROUND_UP(v, a)  (((size_t)(v) + (a) - 1) & ~((a) - 1))
+
+#define MIN_STACK_SIZE  64
+#define FIRST_ARG_SLOT  9
+#define DEBUG_LEVEL   0
+
+#define fldw(addr, fpreg) \
+  __asm__ volatile ("fldw 0(%0), %%" #fpreg "L" : : "r"(addr) : #fpreg)
+#define fstw(fpreg, addr) \
+  __asm__ volatile ("fstw %%" #fpreg "L, 0(%0)" : : "r"(addr))
+#define fldd(addr, fpreg) \
+  __asm__ volatile ("fldd 0(%0), %%" #fpreg : : "r"(addr) : #fpreg)
+#define fstd(fpreg, addr) \
+  __asm__ volatile ("fstd %%" #fpreg "L, 0(%0)" : : "r"(addr))
+
+#define debug(lvl, x...) do { if (lvl <= DEBUG_LEVEL) { printf(x); } } while (0)
+
+static inline int ffi_struct_type(ffi_type *t)
+{
+  size_t sz = t->size;
+
+  /* Small structure results are passed in registers,
+     larger ones are passed by pointer.  Note that
+     small structures of size 2, 4 and 8 differ from
+     the corresponding integer types in that they have
+     different alignment requirements.  */
+
+  if (sz <= 1)
+    return FFI_TYPE_UINT8;
+  else if (sz == 2)
+    return FFI_TYPE_SMALL_STRUCT2;
+  else if (sz == 3)
+    return FFI_TYPE_SMALL_STRUCT3;
+  else if (sz == 4)
+    return FFI_TYPE_SMALL_STRUCT4;
+  else if (sz == 5)
+    return FFI_TYPE_SMALL_STRUCT5;
+  else if (sz == 6)
+    return FFI_TYPE_SMALL_STRUCT6;
+  else if (sz == 7)
+    return FFI_TYPE_SMALL_STRUCT7;
+  else if (sz <= 8)
+    return FFI_TYPE_SMALL_STRUCT8;
+  else
+    return FFI_TYPE_STRUCT; /* else, we pass it by pointer.  */
+}
+
+/* PA has a downward growing stack, which looks like this:
+
+   Offset
+	[ Variable args ]
+   SP = (4*(n+9))       arg word N
+   ...
+   SP-52                arg word 4
+	[ Fixed args ]
+   SP-48                arg word 3
+   SP-44                arg word 2
+   SP-40                arg word 1
+   SP-36                arg word 0
+	[ Frame marker ]
+   ...
+   SP-20                RP
+   SP-4                 previous SP
+
+   The first four argument words on the stack are reserved for use by
+   the callee.  Instead, the general and floating registers replace
+   the first four argument slots.  Non FP arguments are passed solely
+   in the general registers.  FP arguments are passed in both general
+   and floating registers when using libffi.
+
+   Non-FP 32-bit args are passed in gr26, gr25, gr24 and gr23.
+   Non-FP 64-bit args are passed in register pairs, starting
+   on an odd numbered register (i.e. r25+r26 and r23+r24).
+   FP 32-bit arguments are passed in fr4L, fr5L, fr6L and fr7L.
+   FP 64-bit arguments are passed in fr5 and fr7.
+
+   The registers are allocated in the same manner as stack slots.
+   This allows the callee to save its arguments on the stack if
+   necessary:
+
+   arg word 3 -> gr23 or fr7L
+   arg word 2 -> gr24 or fr6L or fr7R
+   arg word 1 -> gr25 or fr5L
+   arg word 0 -> gr26 or fr4L or fr5R
+
+   Note that fr4R and fr6R are never used for arguments (i.e.,
+   doubles are not passed in fr4 or fr6).
+
+   The rest of the arguments are passed on the stack starting at SP-52,
+   but 64-bit arguments need to be aligned to an 8-byte boundary
+
+   This means we can have holes either in the register allocation,
+   or in the stack.  */
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments
+
+   The following code will put everything into the stack frame
+   (which was allocated by the asm routine), and on return
+   the asm routine will load the arguments that should be
+   passed by register into the appropriate registers
+
+   NOTE: We load floating point args in this function... that means we
+   assume gcc will not mess with fp regs in here.  */
+
+void ffi_prep_args_pa32(UINT32 *stack, extended_cif *ecif, unsigned bytes)
+{
+  register unsigned int i;
+  register ffi_type **p_arg;
+  register void **p_argv;
+  unsigned int slot = FIRST_ARG_SLOT;
+  char *dest_cpy;
+  size_t len;
+
+  debug(1, "%s: stack = %p, ecif = %p, bytes = %u\n", __FUNCTION__, stack,
+	ecif, bytes);
+
+  p_arg = ecif->cif->arg_types;
+  p_argv = ecif->avalue;
+
+  for (i = 0; i < ecif->cif->nargs; i++)
+    {
+      int type = (*p_arg)->type;
+
+      switch (type)
+	{
+	case FFI_TYPE_SINT8:
+	  *(SINT32 *)(stack - slot) = *(SINT8 *)(*p_argv);
+	  break;
+
+	case FFI_TYPE_UINT8:
+	  *(UINT32 *)(stack - slot) = *(UINT8 *)(*p_argv);
+	  break;
+
+	case FFI_TYPE_SINT16:
+	  *(SINT32 *)(stack - slot) = *(SINT16 *)(*p_argv);
+	  break;
+
+	case FFI_TYPE_UINT16:
+	  *(UINT32 *)(stack - slot) = *(UINT16 *)(*p_argv);
+	  break;
+
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_POINTER:
+	  debug(3, "Storing UINT32 %u in slot %u\n", *(UINT32 *)(*p_argv),
+		slot);
+	  *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv);
+	  break;
+
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	  /* Align slot for 64-bit type.  */
+	  slot += (slot & 1) ? 1 : 2;
+	  *(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv);
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  /* First 4 args go in fr4L - fr7L.  */
+	  debug(3, "Storing UINT32(float) in slot %u\n", slot);
+	  *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv);
+	  switch (slot - FIRST_ARG_SLOT)
+	    {
+	    /* First 4 args go in fr4L - fr7L.  */
+	    case 0: fldw(stack - slot, fr4); break;
+	    case 1: fldw(stack - slot, fr5); break;
+	    case 2: fldw(stack - slot, fr6); break;
+	    case 3: fldw(stack - slot, fr7); break;
+	    }
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  /* Align slot for 64-bit type.  */
+	  slot += (slot & 1) ? 1 : 2;
+	  debug(3, "Storing UINT64(double) at slot %u\n", slot);
+	  *(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv);
+	  switch (slot - FIRST_ARG_SLOT)
+	    {
+	      /* First 2 args go in fr5, fr7.  */
+	      case 1: fldd(stack - slot, fr5); break;
+	      case 3: fldd(stack - slot, fr7); break;
+	    }
+	  break;
+
+#ifdef PA_HPUX
+	case FFI_TYPE_LONGDOUBLE:
+	  /* Long doubles are passed in the same manner as structures
+	     larger than 8 bytes.  */
+	  *(UINT32 *)(stack - slot) = (UINT32)(*p_argv);
+	  break;
+#endif
+
+	case FFI_TYPE_STRUCT:
+
+	  /* Structs smaller or equal than 4 bytes are passed in one
+	     register. Structs smaller or equal 8 bytes are passed in two
+	     registers. Larger structures are passed by pointer.  */
+
+	  len = (*p_arg)->size;
+	  if (len <= 4)
+	    {
+	      dest_cpy = (char *)(stack - slot) + 4 - len;
+	      memcpy(dest_cpy, (char *)*p_argv, len);
+	    }
+	  else if (len <= 8)
+	    {
+	      slot += (slot & 1) ? 1 : 2;
+	      dest_cpy = (char *)(stack - slot) + 8 - len;
+	      memcpy(dest_cpy, (char *)*p_argv, len);
+	    }
+	  else
+	    *(UINT32 *)(stack - slot) = (UINT32)(*p_argv);
+	  break;
+
+	default:
+	  FFI_ASSERT(0);
+	}
+
+      slot++;
+      p_arg++;
+      p_argv++;
+    }
+
+  /* Make sure we didn't mess up and scribble on the stack.  */
+  {
+    unsigned int n;
+
+    debug(5, "Stack setup:\n");
+    for (n = 0; n < (bytes + 3) / 4; n++)
+      {
+	if ((n%4) == 0) { debug(5, "\n%08x: ", (unsigned int)(stack - n)); }
+	debug(5, "%08x ", *(stack - n));
+      }
+    debug(5, "\n");
+  }
+
+  FFI_ASSERT(slot * 4 <= bytes);
+
+  return;
+}
+
+static void ffi_size_stack_pa32(ffi_cif *cif)
+{
+  ffi_type **ptr;
+  int i;
+  int z = 0; /* # stack slots */
+
+  for (ptr = cif->arg_types, i = 0; i < cif->nargs; ptr++, i++)
+    {
+      int type = (*ptr)->type;
+
+      switch (type)
+	{
+	case FFI_TYPE_DOUBLE:
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	  z += 2 + (z & 1); /* must start on even regs, so we may waste one */
+	  break;
+
+#ifdef PA_HPUX
+	case FFI_TYPE_LONGDOUBLE:
+#endif
+	case FFI_TYPE_STRUCT:
+	  z += 1; /* pass by ptr, callee will copy */
+	  break;
+
+	default: /* <= 32-bit values */
+	  z++;
+	}
+    }
+
+  /* We can fit up to 6 args in the default 64-byte stack frame,
+     if we need more, we need more stack.  */
+  if (z <= 6)
+    cif->bytes = MIN_STACK_SIZE; /* min stack size */
+  else
+    cif->bytes = 64 + ROUND_UP((z - 6) * sizeof(UINT32), MIN_STACK_SIZE);
+
+  debug(3, "Calculated stack size is %u bytes\n", cif->bytes);
+}
+
+/* Perform machine dependent cif processing.  */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+      cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+#ifdef PA_HPUX
+    case FFI_TYPE_LONGDOUBLE:
+      /* Long doubles are treated like a structure.  */
+      cif->flags = FFI_TYPE_STRUCT;
+      break;
+#endif
+
+    case FFI_TYPE_STRUCT:
+      /* For the return type we have to check the size of the structures.
+	 If the size is smaller or equal 4 bytes, the result is given back
+	 in one register. If the size is smaller or equal 8 bytes than we
+	 return the result in two registers. But if the size is bigger than
+	 8 bytes, we work with pointers.  */
+      cif->flags = ffi_struct_type(cif->rtype);
+      break;
+
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+      cif->flags = FFI_TYPE_UINT64;
+      break;
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+
+  /* Lucky us, because of the unique PA ABI we get to do our
+     own stack sizing.  */
+  switch (cif->abi)
+    {
+    case FFI_PA32:
+      ffi_size_stack_pa32(cif);
+      break;
+
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+
+  return FFI_OK;
+}
+
+extern void ffi_call_pa32(void (*)(UINT32 *, extended_cif *, unsigned),
+			  extended_cif *, unsigned, unsigned, unsigned *,
+			  void (*fn)(void));
+
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+
+  /* If the return value is a struct and we don't have a return
+     value address then we need to make one.  */
+
+  if (rvalue == NULL
+#ifdef PA_HPUX
+      && (cif->rtype->type == FFI_TYPE_STRUCT
+	  || cif->rtype->type == FFI_TYPE_LONGDOUBLE))
+#else
+      && cif->rtype->type == FFI_TYPE_STRUCT)
+#endif
+    {
+      ecif.rvalue = alloca(cif->rtype->size);
+    }
+  else
+    ecif.rvalue = rvalue;
+
+
+  switch (cif->abi)
+    {
+    case FFI_PA32:
+      debug(3, "Calling ffi_call_pa32: ecif=%p, bytes=%u, flags=%u, rvalue=%p, fn=%p\n", &ecif, cif->bytes, cif->flags, ecif.rvalue, (void *)fn);
+      ffi_call_pa32(ffi_prep_args_pa32, &ecif, cif->bytes,
+		     cif->flags, ecif.rvalue, fn);
+      break;
+
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+#if FFI_CLOSURES
+/* This is more-or-less an inverse of ffi_call -- we have arguments on
+   the stack, and we need to fill them into a cif structure and invoke
+   the user function. This really ought to be in asm to make sure
+   the compiler doesn't do things we don't expect.  */
+ffi_status ffi_closure_inner_pa32(ffi_closure *closure, UINT32 *stack)
+{
+  ffi_cif *cif;
+  void **avalue;
+  void *rvalue;
+  UINT32 ret[2]; /* function can return up to 64-bits in registers */
+  ffi_type **p_arg;
+  char *tmp;
+  int i, avn;
+  unsigned int slot = FIRST_ARG_SLOT;
+  register UINT32 r28 asm("r28");
+
+  cif = closure->cif;
+
+  /* If returning via structure, callee will write to our pointer.  */
+  if (cif->flags == FFI_TYPE_STRUCT)
+    rvalue = (void *)r28;
+  else
+    rvalue = &ret[0];
+
+  avalue = (void **)alloca(cif->nargs * FFI_SIZEOF_ARG);
+  avn = cif->nargs;
+  p_arg = cif->arg_types;
+
+  for (i = 0; i < avn; i++)
+    {
+      int type = (*p_arg)->type;
+
+      switch (type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_POINTER:
+	  avalue[i] = (char *)(stack - slot) + sizeof(UINT32) - (*p_arg)->size;
+	  break;
+
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	  slot += (slot & 1) ? 1 : 2;
+	  avalue[i] = (void *)(stack - slot);
+	  break;
+
+	case FFI_TYPE_FLOAT:
+#ifdef PA_LINUX
+	  /* The closure call is indirect.  In Linux, floating point
+	     arguments in indirect calls with a prototype are passed
+	     in the floating point registers instead of the general
+	     registers.  So, we need to replace what was previously
+	     stored in the current slot with the value in the
+	     corresponding floating point register.  */
+	  switch (slot - FIRST_ARG_SLOT)
+	    {
+	    case 0: fstw(fr4, (void *)(stack - slot)); break;
+	    case 1: fstw(fr5, (void *)(stack - slot)); break;
+	    case 2: fstw(fr6, (void *)(stack - slot)); break;
+	    case 3: fstw(fr7, (void *)(stack - slot)); break;
+	    }
+#endif
+	  avalue[i] = (void *)(stack - slot);
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  slot += (slot & 1) ? 1 : 2;
+#ifdef PA_LINUX
+	  /* See previous comment for FFI_TYPE_FLOAT.  */
+	  switch (slot - FIRST_ARG_SLOT)
+	    {
+	    case 1: fstd(fr5, (void *)(stack - slot)); break;
+	    case 3: fstd(fr7, (void *)(stack - slot)); break;
+	    }
+#endif
+	  avalue[i] = (void *)(stack - slot);
+	  break;
+
+#ifdef PA_HPUX
+	case FFI_TYPE_LONGDOUBLE:
+	  /* Long doubles are treated like a big structure.  */
+	  avalue[i] = (void *) *(stack - slot);
+	  break;
+#endif
+
+	case FFI_TYPE_STRUCT:
+	  /* Structs smaller or equal than 4 bytes are passed in one
+	     register. Structs smaller or equal 8 bytes are passed in two
+	     registers. Larger structures are passed by pointer.  */
+	  if((*p_arg)->size <= 4)
+	    {
+	      avalue[i] = (void *)(stack - slot) + sizeof(UINT32) -
+		(*p_arg)->size;
+	    }
+	  else if ((*p_arg)->size <= 8)
+	    {
+	      slot += (slot & 1) ? 1 : 2;
+	      avalue[i] = (void *)(stack - slot) + sizeof(UINT64) -
+		(*p_arg)->size;
+	    }
+	  else
+	    avalue[i] = (void *) *(stack - slot);
+	  break;
+
+	default:
+	  FFI_ASSERT(0);
+	}
+
+      slot++;
+      p_arg++;
+    }
+
+  /* Invoke the closure.  */
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  debug(3, "after calling function, ret[0] = %08x, ret[1] = %08x\n", ret[0],
+	ret[1]);
+
+  /* Store the result using the lower 2 bytes of the flags.  */
+  switch (cif->flags)
+    {
+    case FFI_TYPE_UINT8:
+      *(stack - FIRST_ARG_SLOT) = (UINT8)(ret[0] >> 24);
+      break;
+    case FFI_TYPE_SINT8:
+      *(stack - FIRST_ARG_SLOT) = (SINT8)(ret[0] >> 24);
+      break;
+    case FFI_TYPE_UINT16:
+      *(stack - FIRST_ARG_SLOT) = (UINT16)(ret[0] >> 16);
+      break;
+    case FFI_TYPE_SINT16:
+      *(stack - FIRST_ARG_SLOT) = (SINT16)(ret[0] >> 16);
+      break;
+    case FFI_TYPE_INT:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_UINT32:
+      *(stack - FIRST_ARG_SLOT) = ret[0];
+      break;
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      *(stack - FIRST_ARG_SLOT) = ret[0];
+      *(stack - FIRST_ARG_SLOT - 1) = ret[1];
+      break;
+
+    case FFI_TYPE_DOUBLE:
+      fldd(rvalue, fr4);
+      break;
+
+    case FFI_TYPE_FLOAT:
+      fldw(rvalue, fr4);
+      break;
+
+    case FFI_TYPE_STRUCT:
+      /* Don't need a return value, done by caller.  */
+      break;
+
+    case FFI_TYPE_SMALL_STRUCT2:
+    case FFI_TYPE_SMALL_STRUCT3:
+    case FFI_TYPE_SMALL_STRUCT4:
+      tmp = (void*)(stack -  FIRST_ARG_SLOT);
+      tmp += 4 - cif->rtype->size;
+      memcpy((void*)tmp, &ret[0], cif->rtype->size);
+      break;
+
+    case FFI_TYPE_SMALL_STRUCT5:
+    case FFI_TYPE_SMALL_STRUCT6:
+    case FFI_TYPE_SMALL_STRUCT7:
+    case FFI_TYPE_SMALL_STRUCT8:
+      {
+	unsigned int ret2[2];
+	int off;
+
+	/* Right justify ret[0] and ret[1] */
+	switch (cif->flags)
+	  {
+	    case FFI_TYPE_SMALL_STRUCT5: off = 3; break;
+	    case FFI_TYPE_SMALL_STRUCT6: off = 2; break;
+	    case FFI_TYPE_SMALL_STRUCT7: off = 1; break;
+	    default: off = 0; break;
+	  }
+
+	memset (ret2, 0, sizeof (ret2));
+	memcpy ((char *)ret2 + off, ret, 8 - off);
+
+	*(stack - FIRST_ARG_SLOT) = ret2[0];
+	*(stack - FIRST_ARG_SLOT - 1) = ret2[1];
+      }
+      break;
+
+    case FFI_TYPE_POINTER:
+    case FFI_TYPE_VOID:
+      break;
+
+    default:
+      debug(0, "assert with cif->flags: %d\n",cif->flags);
+      FFI_ASSERT(0);
+      break;
+    }
+  return FFI_OK;
+}
+
+/* Fill in a closure to refer to the specified fun and user_data.
+   cif specifies the argument and result types for fun.
+   The cif must already be prep'ed.  */
+
+extern void ffi_closure_pa32(void);
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif*,void*,void**,void*),
+		      void *user_data,
+		      void *codeloc)
+{
+  UINT32 *tramp = (UINT32 *)(closure->tramp);
+#ifdef PA_HPUX
+  UINT32 *tmp;
+#endif
+
+  if (cif->abi != FFI_PA32)
+    return FFI_BAD_ABI;
+
+  /* Make a small trampoline that will branch to our
+     handler function. Use PC-relative addressing.  */
+
+#ifdef PA_LINUX
+  tramp[0] = 0xeaa00000; /* b,l .+8,%r21        ; %r21 <- pc+8 */
+  tramp[1] = 0xd6a01c1e; /* depi 0,31,2,%r21    ; mask priv bits */
+  tramp[2] = 0x4aa10028; /* ldw 20(%r21),%r1    ; load plabel */
+  tramp[3] = 0x36b53ff1; /* ldo -8(%r21),%r21   ; get closure addr */
+  tramp[4] = 0x0c201096; /* ldw 0(%r1),%r22     ; address of handler */
+  tramp[5] = 0xeac0c000; /* bv%r0(%r22)         ; branch to handler */
+  tramp[6] = 0x0c281093; /* ldw 4(%r1),%r19     ; GP of handler */
+  tramp[7] = ((UINT32)(ffi_closure_pa32) & ~2);
+
+  /* Flush d/icache -- have to flush up 2 two lines because of
+     alignment.  */
+  __asm__ volatile(
+		   "fdc 0(%0)\n\t"
+		   "fdc %1(%0)\n\t"
+		   "fic 0(%%sr4, %0)\n\t"
+		   "fic %1(%%sr4, %0)\n\t"
+		   "sync\n\t"
+		   "nop\n\t"
+		   "nop\n\t"
+		   "nop\n\t"
+		   "nop\n\t"
+		   "nop\n\t"
+		   "nop\n\t"
+		   "nop\n"
+		   :
+		   : "r"((unsigned long)tramp & ~31),
+		     "r"(32 /* stride */)
+		   : "memory");
+#endif
+
+#ifdef PA_HPUX
+  tramp[0] = 0xeaa00000; /* b,l .+8,%r21        ; %r21 <- pc+8  */
+  tramp[1] = 0xd6a01c1e; /* depi 0,31,2,%r21    ; mask priv bits  */
+  tramp[2] = 0x4aa10038; /* ldw 28(%r21),%r1    ; load plabel  */
+  tramp[3] = 0x36b53ff1; /* ldo -8(%r21),%r21   ; get closure addr  */
+  tramp[4] = 0x0c201096; /* ldw 0(%r1),%r22     ; address of handler  */
+  tramp[5] = 0x02c010b4; /* ldsid (%r22),%r20   ; load space id  */
+  tramp[6] = 0x00141820; /* mtsp %r20,%sr0      ; into %sr0  */
+  tramp[7] = 0xe2c00000; /* be 0(%sr0,%r22)     ; branch to handler  */
+  tramp[8] = 0x0c281093; /* ldw 4(%r1),%r19     ; GP of handler  */
+  tramp[9] = ((UINT32)(ffi_closure_pa32) & ~2);
+
+  /* Flush d/icache -- have to flush three lines because of alignment.  */
+  __asm__ volatile(
+		   "copy %1,%0\n\t"
+		   "fdc,m %2(%0)\n\t"
+		   "fdc,m %2(%0)\n\t"
+		   "fdc,m %2(%0)\n\t"
+		   "ldsid (%1),%0\n\t"
+		   "mtsp %0,%%sr0\n\t"
+		   "copy %1,%0\n\t"
+		   "fic,m %2(%%sr0,%0)\n\t"
+		   "fic,m %2(%%sr0,%0)\n\t"
+		   "fic,m %2(%%sr0,%0)\n\t"
+		   "sync\n\t"
+		   "nop\n\t"
+		   "nop\n\t"
+		   "nop\n\t"
+		   "nop\n\t"
+		   "nop\n\t"
+		   "nop\n\t"
+		   "nop\n"
+		   : "=&r" ((unsigned long)tmp)
+		   : "r" ((unsigned long)tramp & ~31),
+		     "r" (32/* stride */)
+		   : "memory");
+#endif
+
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+
+  return FFI_OK;
+}
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/pa/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/pa/ffitarget.h
new file mode 100755
index 0000000..efa2f4e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/pa/ffitarget.h
@@ -0,0 +1,78 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for hppa.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+
+#ifdef PA_LINUX
+  FFI_PA32,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_PA32
+#endif
+
+#ifdef PA_HPUX
+  FFI_PA32,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_PA32
+#endif
+
+#ifdef PA64_HPUX
+#error "PA64_HPUX FFI is not yet implemented"
+  FFI_PA64,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_PA64
+#endif
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_NATIVE_RAW_API 0
+
+#ifdef PA_LINUX
+#define FFI_TRAMPOLINE_SIZE 32
+#else
+#define FFI_TRAMPOLINE_SIZE 40
+#endif
+
+#define FFI_TYPE_SMALL_STRUCT2 -1
+#define FFI_TYPE_SMALL_STRUCT3 -2
+#define FFI_TYPE_SMALL_STRUCT4 -3
+#define FFI_TYPE_SMALL_STRUCT5 -4
+#define FFI_TYPE_SMALL_STRUCT6 -5
+#define FFI_TYPE_SMALL_STRUCT7 -6
+#define FFI_TYPE_SMALL_STRUCT8 -7
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/pa/hpux32.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/pa/hpux32.S
new file mode 100755
index 0000000..40528ba
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/pa/hpux32.S
@@ -0,0 +1,368 @@
+/* -----------------------------------------------------------------------
+   hpux32.S - Copyright (c) 2006 Free Software Foundation, Inc.
+	                (c) 2008 Red Hat, Inc.
+   based on src/pa/linux.S
+
+   HP-UX PA Foreign Function Interface
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+	.LEVEL 1.1
+	.SPACE	$PRIVATE$
+	.IMPORT	$global$,DATA
+	.IMPORT	$$dyncall,MILLICODE
+	.SUBSPA	$DATA$
+	.align	4
+
+	/* void ffi_call_pa32(void (*)(char *, extended_cif *),
+			       extended_cif *ecif,
+			       unsigned bytes,
+			       unsigned flags,
+			       unsigned *rvalue,
+			       void (*fn)(void));
+	 */
+
+	.export	ffi_call_pa32,ENTRY,PRIV_LEV=3
+	.import	ffi_prep_args_pa32,CODE
+
+	.SPACE	$TEXT$
+	.SUBSPA $CODE$
+	.align	4
+
+L$FB1
+ffi_call_pa32
+	.proc
+	.callinfo	FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4
+	.entry
+	stw	%rp, -20(%sp)
+	copy	%r3, %r1
+L$CFI11
+	copy	%sp, %r3
+L$CFI12
+
+	/* Setup the stack for calling prep_args...
+	   We want the stack to look like this:
+
+	   [ Previous stack                            ] <- %r3
+
+	   [ 64-bytes register save area               ] <- %r4
+
+	   [ Stack space for actual call, passed as    ] <- %arg0
+	   [     arg0 to ffi_prep_args_pa32           ]
+
+	   [ Stack for calling prep_args               ] <- %sp
+	 */
+
+	stwm	%r1, 64(%sp)
+	stw	%r4, 12(%r3)
+L$CFI13
+	copy	%sp, %r4
+
+	addl	%arg2, %r4, %arg0	; arg stack
+	stw	%arg3, -48(%r3)		; save flags we need it later
+
+	/* Call prep_args:
+	   %arg0(stack) -- set up above
+	   %arg1(ecif)  -- same as incoming param
+	   %arg2(bytes) -- same as incoming param */
+	bl	ffi_prep_args_pa32,%r2
+	ldo	64(%arg0), %sp
+	ldo	-64(%sp), %sp
+
+	/* now %sp should point where %arg0 was pointing.  */
+
+	/* Load the arguments that should be passed in registers
+	   The fp args are loaded by the prep_args function.  */
+	ldw	-36(%sp), %arg0
+	ldw	-40(%sp), %arg1
+	ldw	-44(%sp), %arg2
+	ldw	-48(%sp), %arg3
+
+	/* in case the function is going to return a structure
+	   we need to give it a place to put the result.  */
+	ldw	-52(%r3), %ret0		; %ret0 <- rvalue
+	ldw	-56(%r3), %r22		; %r22 <- function to call
+	bl	$$dyncall, %r31		; Call the user function
+	copy	%r31, %rp
+
+	/* Prepare to store the result; we need to recover flags and rvalue.  */
+	ldw	-48(%r3), %r21		; r21 <- flags
+	ldw	-52(%r3), %r20		; r20 <- rvalue
+
+	/* Store the result according to the return type.  The most
+	   likely types should come first.  */
+
+L$checkint
+	comib,<>,n FFI_TYPE_INT, %r21, L$checkint8
+	b	L$done
+	stw	%ret0, 0(%r20)
+
+L$checkint8
+	comib,<>,n FFI_TYPE_UINT8, %r21, L$checkint16
+	b	L$done
+	stb	%ret0, 0(%r20)
+
+L$checkint16
+	comib,<>,n FFI_TYPE_UINT16, %r21, L$checkdbl
+	b	L$done
+	sth	%ret0, 0(%r20)
+
+L$checkdbl
+	comib,<>,n FFI_TYPE_DOUBLE, %r21, L$checkfloat
+	b	L$done
+	fstd	%fr4,0(%r20)
+
+L$checkfloat
+	comib,<>,n FFI_TYPE_FLOAT, %r21, L$checkll
+	b	L$done
+	fstw	%fr4L,0(%r20)
+
+L$checkll
+	comib,<>,n FFI_TYPE_UINT64, %r21, L$checksmst2
+	stw	%ret0, 0(%r20)
+	b	L$done
+	stw	%ret1, 4(%r20)
+
+L$checksmst2
+	comib,<>,n FFI_TYPE_SMALL_STRUCT2, %r21, L$checksmst3
+	/* 2-byte structs are returned in ret0 as ????xxyy.  */
+	extru	%ret0, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	b	L$done
+	stb	%ret0, 0(%r20)
+
+L$checksmst3
+	comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, L$checksmst4
+	/* 3-byte structs are returned in ret0 as ??xxyyzz.  */
+	extru	%ret0, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret0, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	b	L$done
+	stb	%ret0, 0(%r20)
+
+L$checksmst4
+	comib,<>,n FFI_TYPE_SMALL_STRUCT4, %r21, L$checksmst5
+	/* 4-byte structs are returned in ret0 as wwxxyyzz.  */
+	extru	%ret0, 7, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret0, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret0, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	b	L$done
+	stb	%ret0, 0(%r20)
+
+L$checksmst5
+	comib,<>,n FFI_TYPE_SMALL_STRUCT5, %r21, L$checksmst6
+	/* 5 byte values are returned right justified:
+	      ret0     ret1
+	   5: ??????aa bbccddee */
+	stbs,ma	%ret0, 1(%r20)
+	extru	%ret1, 7, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	b	L$done
+	stb	%ret1, 0(%r20)
+
+L$checksmst6
+	comib,<>,n FFI_TYPE_SMALL_STRUCT6, %r21, L$checksmst7
+	/* 6 byte values are returned right justified:
+	      ret0     ret1
+	   6: ????aabb ccddeeff */
+	extru	%ret0, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	stbs,ma	%ret0, 1(%r20)
+	extru	%ret1, 7, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	b	L$done
+	stb	%ret1, 0(%r20)
+
+L$checksmst7
+	comib,<>,n FFI_TYPE_SMALL_STRUCT7, %r21, L$checksmst8
+	/* 7 byte values are returned right justified:
+	      ret0     ret1
+	   7: ??aabbcc ddeeffgg */
+	extru	%ret0, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret0, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	stbs,ma	%ret0, 1(%r20)
+	extru	%ret1, 7, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	b	L$done
+	stb	%ret1, 0(%r20)
+
+L$checksmst8
+	comib,<>,n FFI_TYPE_SMALL_STRUCT8, %r21, L$done
+	/* 8 byte values are returned right justified:
+	      ret0     ret1
+	   8: aabbccdd eeffgghh */
+	extru	%ret0, 7, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret0, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret0, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	stbs,ma	%ret0, 1(%r20)
+	extru	%ret1, 7, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	stb	%ret1, 0(%r20)
+
+L$done
+	/* all done, return */
+	copy	%r4, %sp	; pop arg stack
+	ldw	12(%r3), %r4
+	ldwm	-64(%sp), %r3	; .. and pop stack
+	ldw	-20(%sp), %rp
+	bv	%r0(%rp)
+	nop
+	.exit
+	.procend
+L$FE1
+
+	/* void ffi_closure_pa32(void);
+	   Called with closure argument in %r21 */
+
+	.SPACE $TEXT$
+	.SUBSPA $CODE$
+	.export ffi_closure_pa32,ENTRY,PRIV_LEV=3,RTNVAL=GR
+	.import ffi_closure_inner_pa32,CODE
+	.align 4
+L$FB2
+ffi_closure_pa32
+	.proc
+	.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
+	.entry
+
+	stw	%rp, -20(%sp)
+	copy	%r3, %r1
+L$CFI21
+	copy	%sp, %r3
+L$CFI22
+	stwm	%r1, 64(%sp)
+
+	/* Put arguments onto the stack and call ffi_closure_inner.  */
+	stw	%arg0, -36(%r3)
+	stw	%arg1, -40(%r3)
+	stw	%arg2, -44(%r3)
+	stw	%arg3, -48(%r3)
+
+	copy	%r21, %arg0
+	bl	ffi_closure_inner_pa32, %r2
+	copy    %r3, %arg1
+	ldwm	-64(%sp), %r3
+	ldw	-20(%sp), %rp
+	ldw	-36(%sp), %ret0
+	bv	%r0(%rp)
+	ldw	-40(%sp), %ret1
+	.exit
+	.procend
+L$FE2:
+
+	.SPACE $PRIVATE$
+	.SUBSPA $DATA$
+
+	.align 4
+	.EXPORT _GLOBAL__F_ffi_call_pa32,DATA
+_GLOBAL__F_ffi_call_pa32
+L$frame1:
+	.word   L$ECIE1-L$SCIE1 ;# Length of Common Information Entry
+L$SCIE1:
+	.word   0x0     ;# CIE Identifier Tag
+	.byte   0x1     ;# CIE Version
+	.ascii "\0"     ;# CIE Augmentation
+	.uleb128 0x1    ;# CIE Code Alignment Factor
+	.sleb128 4      ;# CIE Data Alignment Factor
+	.byte   0x2     ;# CIE RA Column
+	.byte   0xc     ;# DW_CFA_def_cfa
+	.uleb128 0x1e
+	.uleb128 0x0
+	.align 4
+L$ECIE1:
+L$SFDE1:
+	.word   L$EFDE1-L$ASFDE1        ;# FDE Length
+L$ASFDE1:
+	.word   L$ASFDE1-L$frame1       ;# FDE CIE offset
+	.word   L$FB1   ;# FDE initial location
+	.word   L$FE1-L$FB1     ;# FDE address range
+
+	.byte   0x4     ;# DW_CFA_advance_loc4
+	.word   L$CFI11-L$FB1
+	.byte	0x83	;# DW_CFA_offset, column 0x3
+	.uleb128 0x0
+	.byte   0x11    ;# DW_CFA_offset_extended_sf; save r2 at [r30-20]
+	.uleb128 0x2
+	.sleb128 -5
+
+	.byte   0x4     ;# DW_CFA_advance_loc4
+	.word   L$CFI12-L$CFI11
+	.byte   0xd     ;# DW_CFA_def_cfa_register = r3
+	.uleb128 0x3
+
+	.byte   0x4     ;# DW_CFA_advance_loc4
+	.word   L$CFI13-L$CFI12
+	.byte	0x84	;# DW_CFA_offset, column 0x4
+	.uleb128 0x3
+
+	.align 4
+L$EFDE1:
+
+L$SFDE2:
+	.word   L$EFDE2-L$ASFDE2        ;# FDE Length
+L$ASFDE2:
+	.word   L$ASFDE2-L$frame1       ;# FDE CIE offset
+	.word   L$FB2   ;# FDE initial location
+	.word   L$FE2-L$FB2     ;# FDE address range
+	.byte   0x4     ;# DW_CFA_advance_loc4
+	.word   L$CFI21-L$FB2
+	.byte   0x83    ;# DW_CFA_offset, column 0x3
+	.uleb128 0x0
+	.byte   0x11    ;# DW_CFA_offset_extended_sf
+	.uleb128 0x2
+	.sleb128 -5
+
+	.byte   0x4     ;# DW_CFA_advance_loc4
+	.word   L$CFI22-L$CFI21
+	.byte   0xd     ;# DW_CFA_def_cfa_register = r3
+	.uleb128 0x3
+
+	.align 4
+L$EFDE2:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/pa/linux.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/pa/linux.S
new file mode 100755
index 0000000..f11ae76
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/pa/linux.S
@@ -0,0 +1,357 @@
+/* -----------------------------------------------------------------------
+   linux.S - (c) 2003-2004 Randolph Chung <tausq at debian.org>
+	     (c) 2008 Red Hat, Inc.
+
+   HPPA Foreign Function Interface
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+	.text
+	.level 1.1
+	.align 4
+
+	/* void ffi_call_pa32(void (*)(char *, extended_cif *),
+			       extended_cif *ecif,
+			       unsigned bytes,
+			       unsigned flags,
+			       unsigned *rvalue,
+			       void (*fn)(void));
+	 */
+
+	.export ffi_call_pa32,code
+	.import ffi_prep_args_pa32,code
+
+	.type ffi_call_pa32, @function
+.LFB1:
+ffi_call_pa32:
+	.proc
+	.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4
+	.entry
+	stw %rp, -20(%sp)
+	copy %r3, %r1
+.LCFI11:
+
+	copy %sp, %r3
+.LCFI12:
+
+	/* Setup the stack for calling prep_args...
+	   We want the stack to look like this:
+
+	   [ Previous stack                            ] <- %r3
+
+	   [ 64-bytes register save area               ] <- %r4
+
+	   [ Stack space for actual call, passed as    ] <- %arg0
+	   [     arg0 to ffi_prep_args_pa32           ]
+
+	   [ Stack for calling prep_args               ] <- %sp
+	 */
+
+	stwm %r1, 64(%sp)
+	stw %r4, 12(%r3)
+.LCFI13:
+	copy %sp, %r4
+
+	addl %arg2, %r4, %arg0      /* arg stack */
+	stw %arg3, -48(%r3)         /* save flags; we need it later */
+
+	/* Call prep_args:
+	   %arg0(stack) -- set up above
+	   %arg1(ecif) -- same as incoming param
+	   %arg2(bytes) -- same as incoming param */
+	bl ffi_prep_args_pa32,%r2
+	ldo 64(%arg0), %sp
+	ldo -64(%sp), %sp
+
+	/* now %sp should point where %arg0 was pointing.  */
+
+	/* Load the arguments that should be passed in registers
+	   The fp args were loaded by the prep_args function.  */
+	ldw -36(%sp), %arg0
+	ldw -40(%sp), %arg1
+	ldw -44(%sp), %arg2
+	ldw -48(%sp), %arg3
+
+	/* in case the function is going to return a structure
+	   we need to give it a place to put the result.  */
+	ldw -52(%r3), %ret0                     /* %ret0 <- rvalue */
+	ldw -56(%r3), %r22                      /* %r22 <- function to call */
+	bl $$dyncall, %r31                      /* Call the user function */
+	copy %r31, %rp
+
+	/* Prepare to store the result; we need to recover flags and rvalue.  */
+	ldw -48(%r3), %r21                      /* r21 <- flags */
+	ldw -52(%r3), %r20                      /* r20 <- rvalue */
+
+	/* Store the result according to the return type.  */
+
+.Lcheckint:
+	comib,<>,n FFI_TYPE_INT, %r21, .Lcheckint8
+	b	.Ldone
+	stw	%ret0, 0(%r20)
+
+.Lcheckint8:
+	comib,<>,n FFI_TYPE_UINT8, %r21, .Lcheckint16
+	b	.Ldone
+	stb	%ret0, 0(%r20)
+
+.Lcheckint16:
+	comib,<>,n FFI_TYPE_UINT16, %r21, .Lcheckdbl
+	b	.Ldone
+	sth	%ret0, 0(%r20)
+
+.Lcheckdbl:
+	comib,<>,n FFI_TYPE_DOUBLE, %r21, .Lcheckfloat
+	b	.Ldone
+	fstd	%fr4,0(%r20)
+
+.Lcheckfloat:
+	comib,<>,n FFI_TYPE_FLOAT, %r21, .Lcheckll
+	b	.Ldone
+	fstw	%fr4L,0(%r20)
+
+.Lcheckll:
+	comib,<>,n FFI_TYPE_UINT64, %r21, .Lchecksmst2
+	stw	%ret0, 0(%r20)
+	b	.Ldone
+	stw	%ret1, 4(%r20)
+
+.Lchecksmst2:
+	comib,<>,n FFI_TYPE_SMALL_STRUCT2, %r21, .Lchecksmst3
+	/* 2-byte structs are returned in ret0 as ????xxyy.  */
+	extru	%ret0, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	b	.Ldone
+	stb	%ret0, 0(%r20)
+
+.Lchecksmst3:
+	comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, .Lchecksmst4
+	/* 3-byte structs are returned in ret0 as ??xxyyzz.  */
+	extru	%ret0, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret0, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	b	.Ldone
+	stb	%ret0, 0(%r20)
+
+.Lchecksmst4:
+	comib,<>,n FFI_TYPE_SMALL_STRUCT4, %r21, .Lchecksmst5
+	/* 4-byte structs are returned in ret0 as wwxxyyzz.  */
+	extru	%ret0, 7, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret0, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret0, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	b	.Ldone
+	stb	%ret0, 0(%r20)
+
+.Lchecksmst5:
+	comib,<>,n FFI_TYPE_SMALL_STRUCT5, %r21, .Lchecksmst6
+	/* 5 byte values are returned right justified:
+	      ret0     ret1
+	   5: ??????aa bbccddee */
+	stbs,ma	%ret0, 1(%r20)
+	extru	%ret1, 7, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	b	.Ldone
+	stb	%ret1, 0(%r20)
+
+.Lchecksmst6:
+	comib,<>,n FFI_TYPE_SMALL_STRUCT6, %r21, .Lchecksmst7
+	/* 6 byte values are returned right justified:
+	      ret0     ret1
+	   6: ????aabb ccddeeff */
+	extru	%ret0, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	stbs,ma	%ret0, 1(%r20)
+	extru	%ret1, 7, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	b	.Ldone
+	stb	%ret1, 0(%r20)
+
+.Lchecksmst7:
+	comib,<>,n FFI_TYPE_SMALL_STRUCT7, %r21, .Lchecksmst8
+	/* 7 byte values are returned right justified:
+	      ret0     ret1
+	   7: ??aabbcc ddeeffgg */
+	extru	%ret0, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret0, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	stbs,ma	%ret0, 1(%r20)
+	extru	%ret1, 7, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	b	.Ldone
+	stb	%ret1, 0(%r20)
+
+.Lchecksmst8:
+	comib,<>,n FFI_TYPE_SMALL_STRUCT8, %r21, .Ldone
+	/* 8 byte values are returned right justified:
+	      ret0     ret1
+	   8: aabbccdd eeffgghh */
+	extru	%ret0, 7, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret0, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret0, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	stbs,ma	%ret0, 1(%r20)
+	extru	%ret1, 7, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 15, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	extru	%ret1, 23, 8, %r22
+	stbs,ma	%r22, 1(%r20)
+	stb	%ret1, 0(%r20)
+
+.Ldone:
+	/* all done, return */
+	copy %r4, %sp                           /* pop arg stack */
+	ldw 12(%r3), %r4
+	ldwm -64(%sp), %r3                      /* .. and pop stack */
+	ldw -20(%sp), %rp
+	bv %r0(%rp)
+	nop
+	.exit
+	.procend
+.LFE1:
+
+	/* void ffi_closure_pa32(void);
+	   Called with closure argument in %r21 */
+	.export ffi_closure_pa32,code
+	.import ffi_closure_inner_pa32,code
+
+	.type ffi_closure_pa32, @function
+.LFB2:
+ffi_closure_pa32:
+	.proc
+	.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
+	.entry
+
+	stw %rp, -20(%sp)
+.LCFI20:
+	copy %r3, %r1
+.LCFI21:
+	copy %sp, %r3
+.LCFI22:
+	stwm %r1, 64(%sp)
+
+	/* Put arguments onto the stack and call ffi_closure_inner.  */
+	stw %arg0, -36(%r3)
+	stw %arg1, -40(%r3)
+	stw %arg2, -44(%r3)
+	stw %arg3, -48(%r3)
+
+	copy %r21, %arg0
+	bl ffi_closure_inner_pa32, %r2
+	copy %r3, %arg1
+
+	ldwm -64(%sp), %r3
+	ldw -20(%sp), %rp
+	ldw -36(%sp), %ret0
+	bv %r0(%r2)
+	ldw -40(%sp), %ret1
+
+	.exit
+	.procend
+.LFE2:
+
+	.section        ".eh_frame",EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.word   .LECIE1-.LSCIE1 ;# Length of Common Information Entry
+.LSCIE1:
+	.word   0x0     ;# CIE Identifier Tag
+	.byte   0x1     ;# CIE Version
+	.ascii "\0"     ;# CIE Augmentation
+	.uleb128 0x1    ;# CIE Code Alignment Factor
+	.sleb128 4      ;# CIE Data Alignment Factor
+	.byte   0x2     ;# CIE RA Column
+	.byte   0xc     ;# DW_CFA_def_cfa
+	.uleb128 0x1e
+	.uleb128 0x0
+	.align 4
+.LECIE1:
+.LSFDE1:
+	.word   .LEFDE1-.LASFDE1        ;# FDE Length
+.LASFDE1:
+	.word   .LASFDE1-.Lframe1       ;# FDE CIE offset
+	.word   .LFB1   ;# FDE initial location
+	.word   .LFE1-.LFB1     ;# FDE address range
+
+	.byte   0x4     ;# DW_CFA_advance_loc4
+	.word   .LCFI11-.LFB1
+	.byte	0x83	;# DW_CFA_offset, column 0x3
+	.uleb128 0x0
+	.byte   0x11    ;# DW_CFA_offset_extended_sf; save r2 at [r30-20]
+	.uleb128 0x2
+	.sleb128 -5
+
+	.byte   0x4     ;# DW_CFA_advance_loc4
+	.word   .LCFI12-.LCFI11
+	.byte   0xd     ;# DW_CFA_def_cfa_register = r3
+	.uleb128 0x3
+
+	.byte   0x4     ;# DW_CFA_advance_loc4
+	.word   .LCFI13-.LCFI12
+	.byte	0x84	;# DW_CFA_offset, column 0x4
+	.uleb128 0x3
+
+	.align 4
+.LEFDE1:
+
+.LSFDE2:
+	.word   .LEFDE2-.LASFDE2        ;# FDE Length
+.LASFDE2:
+	.word   .LASFDE2-.Lframe1       ;# FDE CIE offset
+	.word   .LFB2   ;# FDE initial location
+	.word   .LFE2-.LFB2     ;# FDE address range
+	.byte   0x4     ;# DW_CFA_advance_loc4
+	.word   .LCFI21-.LFB2
+	.byte   0x83    ;# DW_CFA_offset, column 0x3
+	.uleb128 0x0
+	.byte   0x11    ;# DW_CFA_offset_extended_sf
+	.uleb128 0x2
+	.sleb128 -5
+
+	.byte   0x4     ;# DW_CFA_advance_loc4
+	.word   .LCFI22-.LCFI21
+	.byte   0xd     ;# DW_CFA_def_cfa_register = r3
+	.uleb128 0x3
+
+	.align 4
+.LEFDE2:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/aix.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/aix.S
new file mode 100755
index 0000000..213f2db
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/aix.S
@@ -0,0 +1,328 @@
+/* -----------------------------------------------------------------------
+   aix.S - Copyright (c) 2002, 2009 Free Software Foundation, Inc.
+   based on darwin.S by John Hornkvist
+
+   PowerPC Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+	.set r0,0
+	.set r1,1
+	.set r2,2
+	.set r3,3
+	.set r4,4
+	.set r5,5
+	.set r6,6
+	.set r7,7
+	.set r8,8
+	.set r9,9
+	.set r10,10
+	.set r11,11
+	.set r12,12
+	.set r13,13
+	.set r14,14
+	.set r15,15
+	.set r16,16
+	.set r17,17
+	.set r18,18
+	.set r19,19
+	.set r20,20
+	.set r21,21
+	.set r22,22
+	.set r23,23
+	.set r24,24
+	.set r25,25
+	.set r26,26
+	.set r27,27
+	.set r28,28
+	.set r29,29
+	.set r30,30
+	.set r31,31
+	.set f0,0
+	.set f1,1
+	.set f2,2
+	.set f3,3
+	.set f4,4
+	.set f5,5
+	.set f6,6
+	.set f7,7
+	.set f8,8
+	.set f9,9
+	.set f10,10
+	.set f11,11
+	.set f12,12
+	.set f13,13
+	.set f14,14
+	.set f15,15
+	.set f16,16
+	.set f17,17
+	.set f18,18
+	.set f19,19
+	.set f20,20
+	.set f21,21
+
+	.extern .ffi_prep_args
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#define JUMPTARGET(name) name
+#define L(x) x
+	.file "aix.S"
+	.toc
+
+	/* void ffi_call_AIX(extended_cif *ecif, unsigned long bytes,
+	 *		     unsigned int flags, unsigned int *rvalue,
+	 *		     void (*fn)(),
+	 *		     void (*prep_args)(extended_cif*, unsigned *const));
+	 * r3=ecif, r4=bytes, r5=flags, r6=rvalue, r7=fn, r8=prep_args
+	 */
+
+.csect .text[PR]
+	.align 2
+	.globl ffi_call_AIX
+	.globl .ffi_call_AIX
+.csect ffi_call_AIX[DS]
+ffi_call_AIX:
+#ifdef __64BIT__
+	.llong .ffi_call_AIX, TOC[tc0], 0
+	.csect .text[PR]
+.ffi_call_AIX:
+	/* Save registers we use.  */
+	mflr	r0
+
+	std	r28,-32(r1)
+	std	r29,-24(r1)
+	std	r30,-16(r1)
+	std	r31, -8(r1)
+
+	std	r0, 16(r1)
+	mr	r28, r1		/* our AP.  */
+	stdux	r1, r1, r4
+
+	/* Save arguments over call...  */
+	mr	r31, r5	/* flags, */
+	mr	r30, r6	/* rvalue, */
+	mr	r29, r7	/* function address.  */
+	std	r2, 40(r1)
+
+	/* Call ffi_prep_args.  */
+	mr	r4, r1
+	bl	.ffi_prep_args
+	nop
+
+	/* Now do the call.  */
+	ld	r0, 0(r29)
+	ld	r2, 8(r29)
+	ld	r11, 16(r29)
+	/* Set up cr1 with bits 4-7 of the flags.  */
+	mtcrf	0x40, r31
+	mtctr	r0
+	/* Load all those argument registers.  */
+	// We have set up a nice stack frame, just load it into registers.
+	ld	r3, 40+(1*8)(r1)
+	ld	r4, 40+(2*8)(r1)
+	ld	r5, 40+(3*8)(r1)
+	ld	r6, 40+(4*8)(r1)
+	nop
+	ld	r7, 40+(5*8)(r1)
+	ld	r8, 40+(6*8)(r1)
+	ld	r9, 40+(7*8)(r1)
+	ld	r10,40+(8*8)(r1)
+
+L1:
+	/* Load all the FP registers.  */
+	bf	6,L2 // 2f + 0x18
+	lfd	f1,-32-(13*8)(r28)
+	lfd	f2,-32-(12*8)(r28)
+	lfd	f3,-32-(11*8)(r28)
+	lfd	f4,-32-(10*8)(r28)
+	nop
+	lfd	f5,-32-(9*8)(r28)
+	lfd	f6,-32-(8*8)(r28)
+	lfd	f7,-32-(7*8)(r28)
+	lfd	f8,-32-(6*8)(r28)
+	nop
+	lfd	f9,-32-(5*8)(r28)
+	lfd	f10,-32-(4*8)(r28)
+	lfd	f11,-32-(3*8)(r28)
+	lfd	f12,-32-(2*8)(r28)
+	nop
+	lfd	f13,-32-(1*8)(r28)
+
+L2:
+	/* Make the call.  */
+	bctrl
+	ld	r2, 40(r1)
+
+	/* Now, deal with the return value.  */
+	mtcrf	0x01, r31
+
+	bt	30, L(done_return_value)
+	bt	29, L(fp_return_value)
+	std	r3, 0(r30)
+
+	/* Fall through...  */
+
+L(done_return_value):
+	/* Restore the registers we used and return.  */
+	mr	r1, r28
+	ld	r0, 16(r28)
+	ld	r28, -32(r1)
+	mtlr	r0
+	ld	r29, -24(r1)
+	ld	r30, -16(r1)
+	ld	r31, -8(r1)
+	blr
+
+L(fp_return_value):
+	bf	28, L(float_return_value)
+	stfd	f1, 0(r30)
+	bf	31, L(done_return_value)
+	stfd	f2, 8(r30)
+	b	L(done_return_value)
+L(float_return_value):
+	stfs	f1, 0(r30)
+	b	L(done_return_value)
+
+#else /* ! __64BIT__ */
+	
+	.long .ffi_call_AIX, TOC[tc0], 0
+	.csect .text[PR]
+.ffi_call_AIX:
+	/* Save registers we use.  */
+	mflr	r0
+
+	stw	r28,-16(r1)
+	stw	r29,-12(r1)
+	stw	r30, -8(r1)
+	stw	r31, -4(r1)
+
+	stw	r0, 8(r1)
+	mr	r28, r1		/* out AP.  */
+	stwux	r1, r1, r4
+
+	/* Save arguments over call...  */
+	mr	r31, r5	/* flags, */
+	mr	r30, r6	/* rvalue, */
+	mr	r29, r7	/* function address, */
+	stw	r2, 20(r1)
+
+	/* Call ffi_prep_args.  */
+	mr	r4, r1
+	bl	.ffi_prep_args
+	nop
+
+	/* Now do the call.  */
+	lwz	r0, 0(r29)
+	lwz	r2, 4(r29)
+	lwz	r11, 8(r29)
+	/* Set up cr1 with bits 4-7 of the flags.  */
+	mtcrf	0x40, r31
+	mtctr	r0
+	/* Load all those argument registers.  */
+	// We have set up a nice stack frame, just load it into registers.
+	lwz	r3, 20+(1*4)(r1)
+	lwz	r4, 20+(2*4)(r1)
+	lwz	r5, 20+(3*4)(r1)
+	lwz	r6, 20+(4*4)(r1)
+	nop
+	lwz	r7, 20+(5*4)(r1)
+	lwz	r8, 20+(6*4)(r1)
+	lwz	r9, 20+(7*4)(r1)
+	lwz	r10,20+(8*4)(r1)
+
+L1:
+	/* Load all the FP registers.  */
+	bf	6,L2 // 2f + 0x18
+	lfd	f1,-16-(13*8)(r28)
+	lfd	f2,-16-(12*8)(r28)
+	lfd	f3,-16-(11*8)(r28)
+	lfd	f4,-16-(10*8)(r28)
+	nop
+	lfd	f5,-16-(9*8)(r28)
+	lfd	f6,-16-(8*8)(r28)
+	lfd	f7,-16-(7*8)(r28)
+	lfd	f8,-16-(6*8)(r28)
+	nop
+	lfd	f9,-16-(5*8)(r28)
+	lfd	f10,-16-(4*8)(r28)
+	lfd	f11,-16-(3*8)(r28)
+	lfd	f12,-16-(2*8)(r28)
+	nop
+	lfd	f13,-16-(1*8)(r28)
+
+L2:
+	/* Make the call.  */
+	bctrl
+	lwz	r2, 20(r1)
+
+	/* Now, deal with the return value.  */
+	mtcrf	0x01, r31
+
+	bt	30, L(done_return_value)
+	bt	29, L(fp_return_value)
+	stw	r3, 0(r30)
+	bf	28, L(done_return_value)
+	stw	r4, 4(r30)
+
+	/* Fall through...  */
+
+L(done_return_value):
+	/* Restore the registers we used and return.  */
+	mr	r1, r28
+	lwz	r0, 8(r28)
+	lwz	r28,-16(r1)
+	mtlr	r0
+	lwz	r29,-12(r1)
+	lwz	r30, -8(r1)
+	lwz	r31, -4(r1)
+	blr
+
+L(fp_return_value):
+	bf	28, L(float_return_value)
+	stfd	f1, 0(r30)
+	b	L(done_return_value)
+L(float_return_value):
+	stfs	f1, 0(r30)
+	b	L(done_return_value)
+#endif
+	.long 0
+	.byte 0,0,0,1,128,4,0,0
+//END(ffi_call_AIX)
+
+.csect .text[PR]
+	.align 2
+	.globl ffi_call_DARWIN
+	.globl .ffi_call_DARWIN
+.csect ffi_call_DARWIN[DS]
+ffi_call_DARWIN:
+#ifdef __64BIT__
+	.llong .ffi_call_DARWIN, TOC[tc0], 0
+#else
+	.long .ffi_call_DARWIN, TOC[tc0], 0
+#endif
+	.csect .text[PR]
+.ffi_call_DARWIN:
+	blr
+	.long 0
+	.byte 0,0,0,0,0,0,0,0
+//END(ffi_call_DARWIN)
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/aix_closure.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/aix_closure.S
new file mode 100755
index 0000000..c906017
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/aix_closure.S
@@ -0,0 +1,445 @@
+/* -----------------------------------------------------------------------
+   aix_closure.S - Copyright (c) 2002, 2003, 2009 Free Software Foundation, Inc.
+   based on darwin_closure.S
+
+   PowerPC Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+	.set r0,0
+	.set r1,1
+	.set r2,2
+	.set r3,3
+	.set r4,4
+	.set r5,5
+	.set r6,6
+	.set r7,7
+	.set r8,8
+	.set r9,9
+	.set r10,10
+	.set r11,11
+	.set r12,12
+	.set r13,13
+	.set r14,14
+	.set r15,15
+	.set r16,16
+	.set r17,17
+	.set r18,18
+	.set r19,19
+	.set r20,20
+	.set r21,21
+	.set r22,22
+	.set r23,23
+	.set r24,24
+	.set r25,25
+	.set r26,26
+	.set r27,27
+	.set r28,28
+	.set r29,29
+	.set r30,30
+	.set r31,31
+	.set f0,0
+	.set f1,1
+	.set f2,2
+	.set f3,3
+	.set f4,4
+	.set f5,5
+	.set f6,6
+	.set f7,7
+	.set f8,8
+	.set f9,9
+	.set f10,10
+	.set f11,11
+	.set f12,12
+	.set f13,13
+	.set f14,14
+	.set f15,15
+	.set f16,16
+	.set f17,17
+	.set f18,18
+	.set f19,19
+	.set f20,20
+	.set f21,21
+
+	.extern .ffi_closure_helper_DARWIN
+
+#define LIBFFI_ASM
+#define JUMPTARGET(name) name
+#define L(x) x
+	.file "aix_closure.S"
+	.toc
+LC..60:
+	.tc L..60[TC],L..60
+	.csect .text[PR]
+	.align 2
+
+.csect .text[PR]
+	.align 2
+	.globl ffi_closure_ASM
+	.globl .ffi_closure_ASM
+.csect ffi_closure_ASM[DS]
+ffi_closure_ASM:
+#ifdef __64BIT__
+	.llong .ffi_closure_ASM, TOC[tc0], 0
+	.csect .text[PR]
+.ffi_closure_ASM:
+/* we want to build up an area for the parameters passed */
+/* in registers (both floating point and integer) */
+
+	/* we store gpr 3 to gpr 10 (aligned to 4)
+	in the parents outgoing area  */
+	std   r3, 48+(0*8)(r1)
+	std   r4, 48+(1*8)(r1)
+	std   r5, 48+(2*8)(r1)
+	std   r6, 48+(3*8)(r1)
+	mflr  r0
+
+	std   r7, 48+(4*8)(r1)
+	std   r8, 48+(5*8)(r1)
+	std   r9, 48+(6*8)(r1)
+	std   r10, 48+(7*8)(r1)
+	std   r0, 16(r1)	/* save the return address */
+
+
+	/* 48  Bytes (Linkage Area) */
+	/* 64  Bytes (params) */
+	/* 16  Bytes (result) */
+	/* 104 Bytes (13*8 from FPR) */
+	/* 8   Bytes (alignment) */
+	/* 240 Bytes */
+
+	stdu  r1, -240(r1)	/* skip over caller save area
+				   keep stack aligned to 16  */
+
+	/* next save fpr 1 to fpr 13 (aligned to 8) */
+	stfd  f1, 128+(0*8)(r1)
+	stfd  f2, 128+(1*8)(r1)
+	stfd  f3, 128+(2*8)(r1)
+	stfd  f4, 128+(3*8)(r1)
+	stfd  f5, 128+(4*8)(r1)
+	stfd  f6, 128+(5*8)(r1)
+	stfd  f7, 128+(6*8)(r1)
+	stfd  f8, 128+(7*8)(r1)
+	stfd  f9, 128+(8*8)(r1)
+	stfd  f10, 128+(9*8)(r1)
+	stfd  f11, 128+(10*8)(r1)
+	stfd  f12, 128+(11*8)(r1)
+	stfd  f13, 128+(12*8)(r1)
+
+	/* set up registers for the routine that actually does the work */
+	/* get the context pointer from the trampoline */
+	mr r3, r11
+
+	/* now load up the pointer to the result storage */
+	addi r4, r1, 112
+
+	/* now load up the pointer to the saved gpr registers */
+	addi r5, r1, 288
+
+	/* now load up the pointer to the saved fpr registers */
+	addi r6, r1, 128
+
+	/* make the call */
+	bl .ffi_closure_helper_DARWIN
+	nop
+
+	/* now r3 contains the return type */
+	/* so use it to look up in a table */
+	/* so we know how to deal with each type */
+
+	/* look up the proper starting point in table  */
+	/* by using return type as offset */
+	ld	r4, LC..60(2)	/* get address of jump table */
+	sldi	r3, r3, 4	/* now multiply return type by 16 */
+	ld	r0, 240+16(r1)	/* load return address */
+	add	r3, r3, r4	/* add contents of table to table address */
+	mtctr	r3
+	bctr			/* jump to it */
+
+/* Each fragment must be exactly 16 bytes long (4 instructions).
+   Align to 16 byte boundary for cache and dispatch efficiency.  */
+	.align 4
+
+L..60:
+/* case FFI_TYPE_VOID */
+	mtlr r0
+	addi r1, r1, 240
+	blr
+	nop
+
+/* case FFI_TYPE_INT */
+	lwa r3, 112+4(r1)
+	mtlr r0
+	addi r1, r1, 240
+	blr
+
+/* case FFI_TYPE_FLOAT */
+	lfs f1, 112+0(r1)
+	mtlr r0
+	addi r1, r1, 240
+	blr
+
+/* case FFI_TYPE_DOUBLE */
+	lfd f1, 112+0(r1)
+	mtlr r0
+	addi r1, r1, 240
+	blr
+
+/* case FFI_TYPE_LONGDOUBLE */
+	lfd f1, 112+0(r1)
+	mtlr r0
+	lfd f2, 112+8(r1)
+	b L..finish
+
+/* case FFI_TYPE_UINT8 */
+	lbz r3, 112+7(r1)
+	mtlr r0
+	addi r1, r1, 240
+	blr
+
+/* case FFI_TYPE_SINT8 */
+	lbz r3, 112+7(r1)
+	mtlr r0
+	extsb r3, r3
+	b L..finish
+
+/* case FFI_TYPE_UINT16 */
+	lhz r3, 112+6(r1)
+	mtlr r0
+L..finish:
+	addi r1, r1, 240
+	blr
+
+/* case FFI_TYPE_SINT16 */
+	lha r3, 112+6(r1)
+	mtlr r0
+	addi r1, r1, 240
+	blr
+
+/* case FFI_TYPE_UINT32 */
+	lwz r3, 112+4(r1)
+	mtlr r0
+	addi r1, r1, 240
+	blr
+
+/* case FFI_TYPE_SINT32 */
+	lwa r3, 112+4(r1)
+	mtlr r0
+	addi r1, r1, 240
+	blr
+
+/* case FFI_TYPE_UINT64 */
+	ld r3, 112+0(r1)
+	mtlr r0
+	addi r1, r1, 240
+	blr
+
+/* case FFI_TYPE_SINT64 */
+	ld r3, 112+0(r1)
+	mtlr r0
+	addi r1, r1, 240
+	blr
+
+/* case FFI_TYPE_STRUCT */
+	mtlr r0
+	addi r1, r1, 240
+	blr
+	nop
+
+/* case FFI_TYPE_POINTER */
+	ld r3, 112+0(r1)
+	mtlr r0
+	addi r1, r1, 240
+	blr
+
+#else /* ! __64BIT__ */
+	
+	.long .ffi_closure_ASM, TOC[tc0], 0
+	.csect .text[PR]
+.ffi_closure_ASM:
+/* we want to build up an area for the parameters passed */
+/* in registers (both floating point and integer) */
+
+	/* we store gpr 3 to gpr 10 (aligned to 4)
+	in the parents outgoing area  */
+	stw   r3, 24+(0*4)(r1)
+	stw   r4, 24+(1*4)(r1)
+	stw   r5, 24+(2*4)(r1)
+	stw   r6, 24+(3*4)(r1)
+	mflr  r0
+
+	stw   r7, 24+(4*4)(r1)
+	stw   r8, 24+(5*4)(r1)
+	stw   r9, 24+(6*4)(r1)
+	stw   r10, 24+(7*4)(r1)
+	stw   r0, 8(r1)
+
+	/* 24 Bytes (Linkage Area) */
+	/* 32 Bytes (params) */
+	/* 16  Bytes (result) */
+	/* 104 Bytes (13*8 from FPR) */
+	/* 176 Bytes */
+
+	stwu  r1, -176(r1)	/* skip over caller save area
+				   keep stack aligned to 16  */
+
+	/* next save fpr 1 to fpr 13 (aligned to 8) */
+	stfd  f1, 72+(0*8)(r1)
+	stfd  f2, 72+(1*8)(r1)
+	stfd  f3, 72+(2*8)(r1)
+	stfd  f4, 72+(3*8)(r1)
+	stfd  f5, 72+(4*8)(r1)
+	stfd  f6, 72+(5*8)(r1)
+	stfd  f7, 72+(6*8)(r1)
+	stfd  f8, 72+(7*8)(r1)
+	stfd  f9, 72+(8*8)(r1)
+	stfd  f10, 72+(9*8)(r1)
+	stfd  f11, 72+(10*8)(r1)
+	stfd  f12, 72+(11*8)(r1)
+	stfd  f13, 72+(12*8)(r1)
+
+	/* set up registers for the routine that actually does the work */
+	/* get the context pointer from the trampoline */
+	mr r3, r11
+
+	/* now load up the pointer to the result storage */
+	addi r4, r1, 56
+
+	/* now load up the pointer to the saved gpr registers */
+	addi r5, r1, 200
+
+	/* now load up the pointer to the saved fpr registers */
+	addi r6, r1, 72
+
+	/* make the call */
+	bl .ffi_closure_helper_DARWIN
+	nop
+
+	/* now r3 contains the return type */
+	/* so use it to look up in a table */
+	/* so we know how to deal with each type */
+
+	/* look up the proper starting point in table  */
+	/* by using return type as offset */
+	lwz	r4, LC..60(2)	/* get address of jump table */
+	slwi	r3, r3, 4	/* now multiply return type by 4 */
+	lwz	r0, 176+8(r1)	/* load return address */
+	add	r3, r3, r4	/* add contents of table to table address */
+	mtctr	r3
+	bctr			/* jump to it */
+
+/* Each fragment must be exactly 16 bytes long (4 instructions).
+   Align to 16 byte boundary for cache and dispatch efficiency.  */
+	.align 4
+
+L..60:
+/* case FFI_TYPE_VOID */
+	mtlr r0
+	addi r1, r1, 176
+	blr
+	nop
+
+/* case FFI_TYPE_INT */
+	lwz r3, 56+0(r1)
+	mtlr r0
+	addi r1, r1, 176
+	blr
+
+/* case FFI_TYPE_FLOAT */
+	lfs f1, 56+0(r1)
+	mtlr r0
+	addi r1, r1, 176
+	blr
+
+/* case FFI_TYPE_DOUBLE */
+	lfd f1, 56+0(r1)
+	mtlr r0
+	addi r1, r1, 176
+	blr
+
+/* case FFI_TYPE_LONGDOUBLE */
+	lfd f1, 56+0(r1)
+	mtlr r0
+	lfd f2, 56+8(r1)
+	b L..finish
+
+/* case FFI_TYPE_UINT8 */
+	lbz r3, 56+3(r1)
+	mtlr r0
+	addi r1, r1, 176
+	blr
+
+/* case FFI_TYPE_SINT8 */
+	lbz r3, 56+3(r1)
+	mtlr r0
+	extsb r3, r3
+	b L..finish
+
+/* case FFI_TYPE_UINT16 */
+	lhz r3, 56+2(r1)
+	mtlr r0
+	addi r1, r1, 176
+	blr
+
+/* case FFI_TYPE_SINT16 */
+	lha r3, 56+2(r1)
+	mtlr r0
+	addi r1, r1, 176
+	blr
+
+/* case FFI_TYPE_UINT32 */
+	lwz r3, 56+0(r1)
+	mtlr r0
+	addi r1, r1, 176
+	blr
+
+/* case FFI_TYPE_SINT32 */
+	lwz r3, 56+0(r1)
+	mtlr r0
+	addi r1, r1, 176
+	blr
+
+/* case FFI_TYPE_UINT64 */
+	lwz r3, 56+0(r1)
+	mtlr r0
+	lwz r4, 56+4(r1)
+	b L..finish
+
+/* case FFI_TYPE_SINT64 */
+	lwz r3, 56+0(r1)
+	mtlr r0
+	lwz r4, 56+4(r1)
+	b L..finish
+
+/* case FFI_TYPE_STRUCT */
+	mtlr r0
+	addi r1, r1, 176
+	blr
+	nop
+
+/* case FFI_TYPE_POINTER */
+	lwz r3, 56+0(r1)
+	mtlr r0
+L..finish:
+	addi r1, r1, 176
+	blr
+#endif
+/* END(ffi_closure_ASM) */
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/asm.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/asm.h
new file mode 100755
index 0000000..994f62d
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/asm.h
@@ -0,0 +1,125 @@
+/* -----------------------------------------------------------------------
+   asm.h - Copyright (c) 1998 Geoffrey Keating
+
+   PowerPC Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define ASM_GLOBAL_DIRECTIVE .globl
+
+
+#define C_SYMBOL_NAME(name) name
+/* Macro for a label.  */
+#ifdef	__STDC__
+#define C_LABEL(name)		name##:
+#else
+#define C_LABEL(name)		name/**/:
+#endif
+
+/* This seems to always be the case on PPC.  */
+#define ALIGNARG(log2) log2
+/* For ELF we need the `.type' directive to make shared libs work right.  */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+
+/* If compiled for profiling, call `_mcount' at the start of each function.  */
+#ifdef	PROF
+/* The mcount code relies on the return address being on the stack
+   to locate our caller and so it can restore it; so store one just
+   for its benefit.  */
+#ifdef PIC
+#define CALL_MCOUNT							      \
+  .pushsection;								      \
+  .section ".data";							      \
+  .align ALIGNARG(2);							      \
+0:.long 0;								      \
+  .previous;								      \
+  mflr  %r0;								      \
+  stw   %r0,4(%r1);							      \
+  bl    _GLOBAL_OFFSET_TABLE_ at local-4;					      \
+  mflr  %r11;								      \
+  lwz   %r0,0b at got(%r11);						      \
+  bl    JUMPTARGET(_mcount);
+#else  /* PIC */
+#define CALL_MCOUNT							      \
+  .section ".data";							      \
+  .align ALIGNARG(2);							      \
+0:.long 0;								      \
+  .previous;								      \
+  mflr  %r0;								      \
+  lis   %r11,0b at ha;							      \
+  stw   %r0,4(%r1);							      \
+  addi  %r0,%r11,0b at l;							      \
+  bl    JUMPTARGET(_mcount);
+#endif /* PIC */
+#else  /* PROF */
+#define CALL_MCOUNT		/* Do nothing.  */
+#endif /* PROF */
+
+#define	ENTRY(name)							      \
+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), at function)			      \
+  .align ALIGNARG(2);							      \
+  C_LABEL(name)								      \
+  CALL_MCOUNT
+
+#define EALIGN_W_0  /* No words to insert.  */
+#define EALIGN_W_1  nop
+#define EALIGN_W_2  nop;nop
+#define EALIGN_W_3  nop;nop;nop
+#define EALIGN_W_4  EALIGN_W_3;nop
+#define EALIGN_W_5  EALIGN_W_4;nop
+#define EALIGN_W_6  EALIGN_W_5;nop
+#define EALIGN_W_7  EALIGN_W_6;nop
+
+/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
+   past a 2^align boundary.  */
+#ifdef PROF
+#define EALIGN(name, alignt, words)					      \
+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), at function)			      \
+  .align ALIGNARG(2);							      \
+  C_LABEL(name)								      \
+  CALL_MCOUNT								      \
+  b 0f;									      \
+  .align ALIGNARG(alignt);						      \
+  EALIGN_W_##words;							      \
+  0:
+#else /* PROF */
+#define EALIGN(name, alignt, words)					      \
+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), at function)			      \
+  .align ALIGNARG(alignt);						      \
+  EALIGN_W_##words;							      \
+  C_LABEL(name)
+#endif
+
+#define END(name)							      \
+  ASM_SIZE_DIRECTIVE(name)
+
+#ifdef PIC
+#define JUMPTARGET(name) name##@plt
+#else
+#define JUMPTARGET(name) name
+#endif
+
+/* Local labels stripped out by the linker.  */
+#define L(x) .L##x
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/darwin.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/darwin.S
new file mode 100755
index 0000000..4f987dc
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/darwin.S
@@ -0,0 +1,383 @@
+/* -----------------------------------------------------------------------
+   darwin.S - Copyright (c) 2000 John Hornkvist
+	      Copyright (c) 2004, 2010 Free Software Foundation, Inc.
+
+   PowerPC Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#if defined(__ppc64__)
+#define MODE_CHOICE(x, y) y
+#else
+#define MODE_CHOICE(x, y) x
+#endif
+
+#define machine_choice	MODE_CHOICE(ppc7400,ppc64)
+
+; Define some pseudo-opcodes for size-independent load & store of GPRs ...
+#define lgu		MODE_CHOICE(lwzu, ldu)
+#define lg		MODE_CHOICE(lwz,ld)
+#define sg		MODE_CHOICE(stw,std)
+#define sgu		MODE_CHOICE(stwu,stdu)
+#define sgux		MODE_CHOICE(stwux,stdux)
+
+; ... and the size of GPRs and their storage indicator.
+#define GPR_BYTES	MODE_CHOICE(4,8)
+#define LOG2_GPR_BYTES	MODE_CHOICE(2,3)	/* log2(GPR_BYTES) */
+#define g_long		MODE_CHOICE(long, quad)	/* usage is ".g_long" */
+
+; From the ABI doc: "Mac OS X ABI Function Call Guide" Version 2009-02-04.
+#define LINKAGE_SIZE	MODE_CHOICE(24,48)
+#define PARAM_AREA	MODE_CHOICE(32,64)
+#define SAVED_LR_OFFSET	MODE_CHOICE(8,16)	/* save position for lr */
+
+/* If there is any FP stuff we make space for all of the regs.  */
+#define SAVED_FPR_COUNT 13
+#define FPR_SIZE	8
+#define RESULT_BYTES	16
+
+/* This should be kept in step with the same value in ffi_darwin.c.  */
+#define ASM_NEEDS_REGISTERS 4
+#define SAVE_REGS_SIZE (ASM_NEEDS_REGISTERS * GPR_BYTES)
+
+#include <fficonfig.h>
+#include <ffi.h>
+
+#define JUMPTARGET(name) name
+#define L(x) x
+
+	.text
+	.align 2
+	.globl _ffi_prep_args
+
+	.align 2
+	.globl _ffi_call_DARWIN
+
+	/* We arrive here with:
+	   r3 = ptr to extended cif.
+	   r4 = -bytes.
+	   r5 = cif flags.
+	   r6 = ptr to return value.
+	   r7 = fn pointer (user func).
+	   r8 = fn pointer (ffi_prep_args).
+	   r9 = ffi_type* for the ret val.  */
+
+_ffi_call_DARWIN:
+Lstartcode:
+	mr   	r12,r8	/* We only need r12 until the call,
+			   so it does not have to be saved.  */
+LFB1:
+	/* Save the old stack pointer as AP.  */
+	mr	r8,r1
+LCFI0:
+	
+	/* Save the retval type in parents frame.  */
+	sg	r9,(LINKAGE_SIZE+6*GPR_BYTES)(r8)
+
+	/* Allocate the stack space we need.  */
+	sgux	r1,r1,r4
+
+	/* Save registers we use.  */
+	mflr	r9
+	sg	r9,SAVED_LR_OFFSET(r8)
+
+	sg	r28,-(4 * GPR_BYTES)(r8)	
+	sg	r29,-(3 * GPR_BYTES)(r8)
+	sg	r30,-(2 * GPR_BYTES)(r8)
+	sg	r31,-(    GPR_BYTES)(r8)
+
+#if !defined(POWERPC_DARWIN)
+	/* The TOC slot is reserved in the Darwin ABI and r2 is volatile.  */
+	sg	r2,(5 * GPR_BYTES)(r1)
+#endif
+
+LCFI1:
+
+	/* Save arguments over call.  */
+	mr	r31,r5	/* flags,  */
+	mr	r30,r6	/* rvalue,  */
+	mr	r29,r7	/* function address,  */
+	mr	r28,r8	/* our AP.  */
+LCFI2:
+	/* Call ffi_prep_args. r3 = extended cif, r4 = stack ptr copy.  */
+	mr	r4,r1
+	li	r9,0
+
+	mtctr	r12 /* r12 holds address of _ffi_prep_args.  */
+	bctrl
+
+#if !defined(POWERPC_DARWIN)
+	/* The TOC slot is reserved in the Darwin ABI and r2 is volatile.  */
+	lg     r2,(5 * GPR_BYTES)(r1)
+#endif
+	/* Now do the call.
+	   Set up cr1 with bits 4-7 of the flags.  */
+	mtcrf	0x40,r31
+	/* Get the address to call into CTR.  */
+	mtctr	r29
+	/* Load all those argument registers.
+	   We have set up a nice stack frame, just load it into registers.  */
+	lg     r3, (LINKAGE_SIZE                )(r1)
+	lg     r4, (LINKAGE_SIZE +     GPR_BYTES)(r1)
+	lg     r5, (LINKAGE_SIZE + 2 * GPR_BYTES)(r1)
+	lg     r6, (LINKAGE_SIZE + 3 * GPR_BYTES)(r1)
+	nop
+	lg     r7, (LINKAGE_SIZE + 4 * GPR_BYTES)(r1)
+	lg     r8, (LINKAGE_SIZE + 5 * GPR_BYTES)(r1)
+	lg     r9, (LINKAGE_SIZE + 6 * GPR_BYTES)(r1)
+	lg     r10,(LINKAGE_SIZE + 7 * GPR_BYTES)(r1)
+
+L1:
+	/* ... Load all the FP registers.  */
+	bf	6,L2	/* No floats to load.  */
+	lfd	f1, -SAVE_REGS_SIZE-(13*FPR_SIZE)(r28)
+	lfd	f2, -SAVE_REGS_SIZE-(12*FPR_SIZE)(r28)
+	lfd	f3, -SAVE_REGS_SIZE-(11*FPR_SIZE)(r28)
+	lfd	f4, -SAVE_REGS_SIZE-(10*FPR_SIZE)(r28)
+	nop
+	lfd	f5, -SAVE_REGS_SIZE-( 9*FPR_SIZE)(r28)
+	lfd	f6, -SAVE_REGS_SIZE-( 8*FPR_SIZE)(r28)
+	lfd	f7, -SAVE_REGS_SIZE-( 7*FPR_SIZE)(r28)
+	lfd	f8, -SAVE_REGS_SIZE-( 6*FPR_SIZE)(r28)
+	nop
+	lfd     f9, -SAVE_REGS_SIZE-( 5*FPR_SIZE)(r28)
+	lfd     f10,-SAVE_REGS_SIZE-( 4*FPR_SIZE)(r28)
+	lfd     f11,-SAVE_REGS_SIZE-( 3*FPR_SIZE)(r28)
+	lfd     f12,-SAVE_REGS_SIZE-( 2*FPR_SIZE)(r28)
+	nop
+	lfd     f13,-SAVE_REGS_SIZE-( 1*FPR_SIZE)(r28)
+
+L2:
+	mr	r12,r29	/* Put the target address in r12 as specified.  */
+	mtctr  	r12
+	nop
+	nop
+
+	/* Make the call.  */
+	bctrl
+
+	/* Now, deal with the return value.  */
+
+	/* m64 structure returns can occupy the same set of registers as
+	   would be used to pass such a structure as arg0 - so take care 
+	   not to step on any possibly hot regs.  */
+
+	/* Get the flags.. */
+	mtcrf	0x03,r31 ; we need c6 & cr7 now.
+	; FLAG_RETURNS_NOTHING also covers struct ret-by-ref.
+	bt	30,L(done_return_value)	  ; FLAG_RETURNS_NOTHING
+	bf	27,L(scalar_return_value) ; not FLAG_RETURNS_STRUCT
+	
+	/* OK, so we have a struct.  */
+#if defined(__ppc64__)
+	bt	31,L(maybe_return_128) ; FLAG_RETURNS_128BITS, special case 
+
+	/* OK, we have to map the return back to a mem struct.
+	   We are about to trample the parents param area, so recover the
+	   return type.  r29 is free, since the call is done.  */
+	lg	r29,(LINKAGE_SIZE + 6 * GPR_BYTES)(r28)
+
+	sg	r3, (LINKAGE_SIZE                )(r28)
+	sg	r4, (LINKAGE_SIZE +     GPR_BYTES)(r28)
+	sg	r5, (LINKAGE_SIZE + 2 * GPR_BYTES)(r28)
+	sg	r6, (LINKAGE_SIZE + 3 * GPR_BYTES)(r28)
+	nop
+	sg	r7, (LINKAGE_SIZE + 4 * GPR_BYTES)(r28)
+	sg	r8, (LINKAGE_SIZE + 5 * GPR_BYTES)(r28)
+	sg	r9, (LINKAGE_SIZE + 6 * GPR_BYTES)(r28)
+	sg	r10,(LINKAGE_SIZE + 7 * GPR_BYTES)(r28)
+	/* OK, so do the block move - we trust that memcpy will not trample
+	   the fprs...  */
+	mr 	r3,r30 ; dest
+	addi	r4,r28,LINKAGE_SIZE ; source
+	/* The size is a size_t, should be long.  */
+	lg	r5,0(r29)
+	/* Figure out small structs */
+	cmpi	0,r5,4
+	bgt	L3	; 1, 2 and 4 bytes have special rules.
+	cmpi	0,r5,3
+	beq	L3	; not 3
+	addi	r4,r4,8
+	subf	r4,r5,r4
+L3:
+	bl	_memcpy
+	
+	/* ... do we need the FP registers? - recover the flags.. */
+	mtcrf	0x03,r31 ; we need c6 & cr7 now.
+	bf	29,L(done_return_value)	/* No floats in the struct.  */
+	stfd	f1, -SAVE_REGS_SIZE-(13*FPR_SIZE)(r28)
+	stfd	f2, -SAVE_REGS_SIZE-(12*FPR_SIZE)(r28)
+	stfd	f3, -SAVE_REGS_SIZE-(11*FPR_SIZE)(r28)
+	stfd	f4, -SAVE_REGS_SIZE-(10*FPR_SIZE)(r28)
+	nop
+	stfd	f5, -SAVE_REGS_SIZE-( 9*FPR_SIZE)(r28)
+	stfd	f6, -SAVE_REGS_SIZE-( 8*FPR_SIZE)(r28)
+	stfd	f7, -SAVE_REGS_SIZE-( 7*FPR_SIZE)(r28)
+	stfd	f8, -SAVE_REGS_SIZE-( 6*FPR_SIZE)(r28)
+	nop
+	stfd	f9, -SAVE_REGS_SIZE-( 5*FPR_SIZE)(r28)
+	stfd	f10,-SAVE_REGS_SIZE-( 4*FPR_SIZE)(r28)
+	stfd	f11,-SAVE_REGS_SIZE-( 3*FPR_SIZE)(r28)
+	stfd	f12,-SAVE_REGS_SIZE-( 2*FPR_SIZE)(r28)
+	nop
+	stfd	f13,-SAVE_REGS_SIZE-( 1*FPR_SIZE)(r28)
+
+	mr	r3,r29	; ffi_type *
+	mr	r4,r30	; dest
+	addi	r5,r28,-SAVE_REGS_SIZE-(13*FPR_SIZE) ; fprs
+	xor	r6,r6,r6
+	sg	r6,(LINKAGE_SIZE + 7 * GPR_BYTES)(r28)
+	addi	r6,r28,(LINKAGE_SIZE + 7 * GPR_BYTES) ; point to a zeroed counter.
+	bl 	_darwin64_struct_floats_to_mem
+
+	b L(done_return_value)
+#else
+	stw	r3,0(r30) ; m32 the only struct return in reg is 4 bytes.
+#endif
+	b L(done_return_value)
+
+L(fp_return_value):
+	/* Do we have long double to store?  */
+	bf	31,L(fd_return_value) ; FLAG_RETURNS_128BITS
+	stfd	f1,0(r30)
+	stfd	f2,FPR_SIZE(r30)
+	b	L(done_return_value)
+
+L(fd_return_value):
+	/* Do we have double to store?  */
+	bf	28,L(float_return_value)
+	stfd	f1,0(r30)
+	b	L(done_return_value)
+
+L(float_return_value):
+	/* We only have a float to store.  */
+	stfs	f1,0(r30)
+	b	L(done_return_value)
+
+L(scalar_return_value):
+	bt	29,L(fp_return_value)	; FLAG_RETURNS_FP
+	; ffi_arg is defined as unsigned long. 
+	sg	r3,0(r30)		; Save the reg.
+	bf	28,L(done_return_value) ; not FLAG_RETURNS_64BITS 
+
+#if defined(__ppc64__)
+L(maybe_return_128):
+	std	r3,0(r30)
+	bf	31,L(done_return_value) ; not FLAG_RETURNS_128BITS 
+	std	r4,8(r30)
+#else
+	stw	r4,4(r30)
+#endif
+
+	/* Fall through.  */
+	/* We want this at the end to simplify eh epilog computation.  */
+
+L(done_return_value):
+	/* Restore the registers we used and return.  */
+	lg	r29,SAVED_LR_OFFSET(r28)
+	; epilog
+	lg	r31,-(1 * GPR_BYTES)(r28)
+	mtlr	r29
+	lg	r30,-(2 * GPR_BYTES)(r28)
+	lg	r29,-(3 * GPR_BYTES)(r28)
+	lg	r28,-(4 * GPR_BYTES)(r28)
+	lg	r1,0(r1)
+	blr
+LFE1:
+	.align	1
+/* END(_ffi_call_DARWIN)  */
+
+/* Provide a null definition of _ffi_call_AIX.  */
+	.text
+	.globl _ffi_call_AIX
+	.align 2
+_ffi_call_AIX:
+	blr
+/* END(_ffi_call_AIX)  */
+
+/* EH stuff.  */
+
+#define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78)
+
+	.static_data
+	.align LOG2_GPR_BYTES
+LLFB0$non_lazy_ptr:
+	.g_long Lstartcode
+
+	.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
+EH_frame1:
+	.set	L$set$0,LECIE1-LSCIE1
+	.long	L$set$0	; Length of Common Information Entry
+LSCIE1:
+	.long	0x0	; CIE Identifier Tag
+	.byte	0x1	; CIE Version
+	.ascii	"zR\0"	; CIE Augmentation
+	.byte	0x1	; uleb128 0x1; CIE Code Alignment Factor
+	.byte	EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor
+	.byte	0x41	; CIE RA Column
+	.byte	0x1	; uleb128 0x1; Augmentation size
+	.byte	0x10	; FDE Encoding (indirect pcrel)
+	.byte	0xc	; DW_CFA_def_cfa
+	.byte	0x1	; uleb128 0x1
+	.byte	0x0	; uleb128 0x0
+	.align	LOG2_GPR_BYTES
+LECIE1:
+
+	.globl _ffi_call_DARWIN.eh
+_ffi_call_DARWIN.eh:
+LSFDE1:
+	.set	L$set$1,LEFDE1-LASFDE1
+	.long	L$set$1	; FDE Length
+LASFDE1:
+	.long	LASFDE1-EH_frame1 ; FDE CIE offset
+	.g_long	LLFB0$non_lazy_ptr-.	; FDE initial location
+	.set	L$set$3,LFE1-Lstartcode
+	.g_long	L$set$3	; FDE address range
+	.byte   0x0     ; uleb128 0x0; Augmentation size
+	.byte	0x4	; DW_CFA_advance_loc4
+	.set	L$set$4,LCFI0-Lstartcode
+	.long	L$set$4
+	.byte	0xd	; DW_CFA_def_cfa_register
+	.byte	0x08	; uleb128 0x08
+	.byte	0x4	; DW_CFA_advance_loc4
+	.set	L$set$5,LCFI1-LCFI0
+	.long	L$set$5
+	.byte   0x11    ; DW_CFA_offset_extended_sf
+	.byte	0x41	; uleb128 0x41
+	.byte   0x7e    ; sleb128 -2
+	.byte	0x9f	; DW_CFA_offset, column 0x1f
+	.byte	0x1	; uleb128 0x1
+	.byte	0x9e	; DW_CFA_offset, column 0x1e
+	.byte	0x2	; uleb128 0x2
+	.byte	0x9d	; DW_CFA_offset, column 0x1d
+	.byte	0x3	; uleb128 0x3
+	.byte	0x9c	; DW_CFA_offset, column 0x1c
+	.byte	0x4	; uleb128 0x4
+	.byte	0x4	; DW_CFA_advance_loc4
+	.set	L$set$6,LCFI2-LCFI1
+	.long	L$set$6
+	.byte	0xd	; DW_CFA_def_cfa_register
+	.byte	0x1c	; uleb128 0x1c
+	.align LOG2_GPR_BYTES
+LEFDE1:
+	.align 1
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/darwin_closure.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/darwin_closure.S
new file mode 100755
index 0000000..db20cf6
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/darwin_closure.S
@@ -0,0 +1,575 @@
+/* -----------------------------------------------------------------------
+   darwin_closure.S - Copyright (c) 2002, 2003, 2004, 2010, 
+   Free Software Foundation, Inc. 
+   based on ppc_closure.S
+
+   PowerPC Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#define L(x) x
+
+#if defined(__ppc64__)
+#define MODE_CHOICE(x, y) y
+#else
+#define MODE_CHOICE(x, y) x
+#endif
+
+#define machine_choice	MODE_CHOICE(ppc7400,ppc64)
+
+; Define some pseudo-opcodes for size-independent load & store of GPRs ...
+#define lgu		MODE_CHOICE(lwzu, ldu)
+#define lg		MODE_CHOICE(lwz,ld)
+#define sg		MODE_CHOICE(stw,std)
+#define sgu		MODE_CHOICE(stwu,stdu)
+
+; ... and the size of GPRs and their storage indicator.
+#define GPR_BYTES	MODE_CHOICE(4,8)
+#define LOG2_GPR_BYTES	MODE_CHOICE(2,3)	/* log2(GPR_BYTES) */
+#define g_long		MODE_CHOICE(long, quad)	/* usage is ".g_long" */
+
+; From the ABI doc: "Mac OS X ABI Function Call Guide" Version 2009-02-04.
+#define LINKAGE_SIZE	MODE_CHOICE(24,48)
+#define PARAM_AREA	MODE_CHOICE(32,64)
+
+#define SAVED_CR_OFFSET	MODE_CHOICE(4,8)	/* save position for CR */
+#define SAVED_LR_OFFSET	MODE_CHOICE(8,16)	/* save position for lr */
+
+/* WARNING: if ffi_type is changed... here be monsters.  
+   Offsets of items within the result type.  */
+#define FFI_TYPE_TYPE	MODE_CHOICE(6,10)
+#define FFI_TYPE_ELEM	MODE_CHOICE(8,16)
+
+#define SAVED_FPR_COUNT 13
+#define FPR_SIZE	8
+/* biggest m64 struct ret is 8GPRS + 13FPRS = 168 bytes - rounded to 16bytes = 176. */
+#define RESULT_BYTES	MODE_CHOICE(16,176)
+
+; The whole stack frame **MUST** be 16byte-aligned.
+#define SAVE_SIZE (((LINKAGE_SIZE+PARAM_AREA+SAVED_FPR_COUNT*FPR_SIZE+RESULT_BYTES)+15) & -16LL)
+#define PAD_SIZE (SAVE_SIZE-(LINKAGE_SIZE+PARAM_AREA+SAVED_FPR_COUNT*FPR_SIZE+RESULT_BYTES))
+
+#define PARENT_PARM_BASE (SAVE_SIZE+LINKAGE_SIZE)
+#define FP_SAVE_BASE (LINKAGE_SIZE+PARAM_AREA)
+
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
+; We no longer need the pic symbol stub for Darwin >= 9.
+#define BLCLS_HELP _ffi_closure_helper_DARWIN
+#define STRUCT_RETVALUE_P _darwin64_struct_ret_by_value_p
+#define PASS_STR_FLOATS _darwin64_pass_struct_floats
+#undef WANT_STUB
+#else
+#define BLCLS_HELP L_ffi_closure_helper_DARWIN$stub
+#define STRUCT_RETVALUE_P L_darwin64_struct_ret_by_value_p$stub
+#define PASS_STR_FLOATS L_darwin64_pass_struct_floats$stub
+#define WANT_STUB
+#endif
+
+/* m32/m64
+
+   The stack layout looks like this:
+
+   |   Additional params...			| |     Higher address
+   ~						~ ~
+   |   Parameters      (at least 8*4/8=32/64)	| | NUM_GPR_ARG_REGISTERS
+   |--------------------------------------------| |
+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |
+   |--------------------------------------------| |
+   |   Reserved                       2*4/8	| |
+   |--------------------------------------------| |
+   |   Space for callee`s LR		4/8	| |
+   |--------------------------------------------| |
+   |   Saved CR [low word for m64]      4/8	| |
+   |--------------------------------------------| |
+   |   Current backchain pointer	4/8	|-/ Parent`s frame.
+   |--------------------------------------------| <+ <<< on entry to
+   |   Result Bytes		       16/176	| |
+   |--------------------------------------------| |
+   ~   padding to 16-byte alignment		~ ~
+   |--------------------------------------------| |
+   |   NUM_FPR_ARG_REGISTERS slots		| |
+   |   here fp13 .. fp1		       13*8	| |
+   |--------------------------------------------| |
+   |   R3..R10			  8*4/8=32/64	| | NUM_GPR_ARG_REGISTERS
+   |--------------------------------------------| |
+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |
+   |--------------------------------------------| |	stack	|
+   |   Reserved [compiler,binder]     2*4/8	| |	grows	|
+   |--------------------------------------------| |	down	V
+   |   Space for callees LR		4/8	| |
+   |--------------------------------------------| |	lower addresses
+   |   Saved CR [low word for m64]      4/8	| |
+   |--------------------------------------------| |     stack pointer here
+   |   Current backchain pointer	4/8	|-/	during
+   |--------------------------------------------|   <<<	call.
+
+*/
+
+	.file	"darwin_closure.S"
+
+	.machine machine_choice
+
+	.text
+	.globl _ffi_closure_ASM
+	.align LOG2_GPR_BYTES
+_ffi_closure_ASM:
+LFB1:
+Lstartcode:
+	mflr	r0			/* extract return address  */
+	sg	r0,SAVED_LR_OFFSET(r1)	/* save the return address  */
+LCFI0:
+	sgu	r1,-SAVE_SIZE(r1)	/* skip over caller save area
+					keep stack aligned to 16.  */
+LCFI1:
+	/* We want to build up an area for the parameters passed
+	   in registers. (both floating point and integer)  */
+
+	/* Put gpr 3 to gpr 10 in the parents outgoing area...
+	   ... the remainder of any params that overflowed the regs will
+	   follow here.  */
+	sg	r3, (PARENT_PARM_BASE                )(r1)
+	sg	r4, (PARENT_PARM_BASE + GPR_BYTES    )(r1)
+	sg	r5, (PARENT_PARM_BASE + GPR_BYTES * 2)(r1)
+	sg	r6, (PARENT_PARM_BASE + GPR_BYTES * 3)(r1)
+	sg	r7, (PARENT_PARM_BASE + GPR_BYTES * 4)(r1)
+	sg	r8, (PARENT_PARM_BASE + GPR_BYTES * 5)(r1)
+	sg	r9, (PARENT_PARM_BASE + GPR_BYTES * 6)(r1)
+	sg	r10,(PARENT_PARM_BASE + GPR_BYTES * 7)(r1)
+
+	/* We save fpr 1 to fpr 14 in our own save frame.  */
+	stfd	f1, (FP_SAVE_BASE                 )(r1)
+	stfd	f2, (FP_SAVE_BASE +  FPR_SIZE     )(r1)
+	stfd	f3, (FP_SAVE_BASE +  FPR_SIZE * 2 )(r1)
+	stfd	f4, (FP_SAVE_BASE +  FPR_SIZE * 3 )(r1)
+	stfd	f5, (FP_SAVE_BASE +  FPR_SIZE * 4 )(r1)
+	stfd	f6, (FP_SAVE_BASE +  FPR_SIZE * 5 )(r1)
+	stfd	f7, (FP_SAVE_BASE +  FPR_SIZE * 6 )(r1)
+	stfd	f8, (FP_SAVE_BASE +  FPR_SIZE * 7 )(r1)
+	stfd	f9, (FP_SAVE_BASE +  FPR_SIZE * 8 )(r1)
+	stfd	f10,(FP_SAVE_BASE +  FPR_SIZE * 9 )(r1)
+	stfd	f11,(FP_SAVE_BASE +  FPR_SIZE * 10)(r1)
+	stfd	f12,(FP_SAVE_BASE +  FPR_SIZE * 11)(r1)
+	stfd	f13,(FP_SAVE_BASE +  FPR_SIZE * 12)(r1)
+
+	/* Set up registers for the routine that actually does the work
+	   get the context pointer from the trampoline.  */
+	mr	r3,r11
+
+	/* Now load up the pointer to the result storage.  */
+	addi	r4,r1,(SAVE_SIZE-RESULT_BYTES)
+
+	/* Now load up the pointer to the saved gpr registers.  */
+	addi	r5,r1,PARENT_PARM_BASE
+
+	/* Now load up the pointer to the saved fpr registers.  */
+	addi	r6,r1,FP_SAVE_BASE
+
+	/* Make the call.  */
+	bl	BLCLS_HELP
+
+	/* r3 contains the rtype pointer... save it since we will need
+	   it later.  */
+	sg	r3,LINKAGE_SIZE(r1)	; ffi_type * result_type
+	lg	r0,0(r3)		; size => r0
+	lhz	r3,FFI_TYPE_TYPE(r3)	; type => r3
+
+	/* The helper will have intercepted struture returns and inserted
+	   the caller`s destination address for structs returned by ref.  */
+
+	/* r3 contains the return type  so use it to look up in a table
+	   so we know how to deal with each type.  */
+
+	addi	r5,r1,(SAVE_SIZE-RESULT_BYTES) /* Otherwise, our return is here.  */
+	bl	Lget_ret_type0_addr	/* Get pointer to Lret_type0 into LR.  */
+	mflr	r4			/* Move to r4.  */
+	slwi	r3,r3,4			/* Now multiply return type by 16.  */
+	add	r3,r3,r4		/* Add contents of table to table address.  */
+	mtctr	r3
+	bctr			 	 /* Jump to it.  */
+LFE1:
+/* Each of the ret_typeX code fragments has to be exactly 16 bytes long
+   (4 instructions). For cache effectiveness we align to a 16 byte boundary
+   first.  */
+
+	.align 4
+
+	nop
+	nop
+	nop
+Lget_ret_type0_addr:
+	blrl
+
+/* case FFI_TYPE_VOID  */
+Lret_type0:
+	b	Lfinish
+	nop
+	nop
+	nop
+
+/* case FFI_TYPE_INT  */
+Lret_type1:
+	lg	r3,0(r5)
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_FLOAT  */
+Lret_type2:
+	lfs	f1,0(r5)
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_DOUBLE  */
+Lret_type3:
+	lfd	f1,0(r5)
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_LONGDOUBLE  */
+Lret_type4:
+	lfd	f1,0(r5)
+	lfd	f2,8(r5)
+	b	Lfinish
+	nop
+
+/* case FFI_TYPE_UINT8  */
+Lret_type5:
+#if defined(__ppc64__)
+	lbz	r3,7(r5)
+#else
+	lbz	r3,3(r5)
+#endif
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_SINT8  */
+Lret_type6:
+#if defined(__ppc64__)
+	lbz	r3,7(r5)
+#else
+	lbz	r3,3(r5)
+#endif
+	extsb	r3,r3
+	b	Lfinish
+	nop
+
+/* case FFI_TYPE_UINT16  */
+Lret_type7:
+#if defined(__ppc64__)
+	lhz	r3,6(r5)
+#else
+	lhz	r3,2(r5)
+#endif
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_SINT16  */
+Lret_type8:
+#if defined(__ppc64__)
+	lha	r3,6(r5)
+#else
+	lha	r3,2(r5)
+#endif
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_UINT32  */
+Lret_type9:
+#if defined(__ppc64__)
+	lwz	r3,4(r5)
+#else
+	lwz	r3,0(r5)
+#endif
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_SINT32  */
+Lret_type10:
+#if defined(__ppc64__)
+	lwz	r3,4(r5)
+#else
+	lwz	r3,0(r5)
+#endif
+	b	Lfinish
+	nop
+	nop
+
+/* case FFI_TYPE_UINT64  */
+Lret_type11:
+#if defined(__ppc64__)
+	lg	r3,0(r5)
+	b	Lfinish
+	nop
+#else
+	lwz	r3,0(r5)
+	lwz	r4,4(r5)
+	b	Lfinish
+#endif
+	nop
+
+/* case FFI_TYPE_SINT64  */
+Lret_type12:
+#if defined(__ppc64__)
+	lg	r3,0(r5)
+	b	Lfinish
+	nop
+#else
+	lwz	r3,0(r5)
+	lwz	r4,4(r5)
+	b	Lfinish
+#endif
+	nop
+
+/* case FFI_TYPE_STRUCT  */
+Lret_type13:
+#if defined(__ppc64__)
+	lg	r3,0(r5)		; we need at least this...
+	cmpi	0,r0,4
+	bgt	Lstructend		; not a special small case
+	b	Lsmallstruct		; see if we need more.
+#else
+	cmpi	0,r0,4
+	bgt	Lfinish		; not by value
+	lg	r3,0(r5)
+	b	Lfinish
+#endif
+/* case FFI_TYPE_POINTER  */
+Lret_type14:
+	lg	r3,0(r5)
+	b	Lfinish
+	nop
+	nop
+
+#if defined(__ppc64__)
+Lsmallstruct:
+	beq	Lfour			; continuation of Lret13.
+	cmpi	0,r0,3
+	beq	Lfinish			; don`t adjust this - can`t be any floats here...
+	srdi	r3,r3,48
+	cmpi	0,r0,2
+	beq	Lfinish			; .. or here ..
+	srdi	r3,r3,8
+	b 	Lfinish			; .. or here.
+
+Lfour:
+	lg	r6,LINKAGE_SIZE(r1)	; get the result type
+	lg	r6,FFI_TYPE_ELEM(r6)	; elements array pointer
+	lg	r6,0(r6)		; first element
+	lhz	r0,FFI_TYPE_TYPE(r6)	; OK go the type
+	cmpi	0,r0,2			; FFI_TYPE_FLOAT
+	bne	Lfourint
+	lfs	f1,0(r5)		; just one float in the struct.
+	b 	Lfinish
+
+Lfourint:
+	srdi	r3,r3,32		; four bytes.
+	b 	Lfinish
+
+Lstructend:
+	lg	r3,LINKAGE_SIZE(r1)	; get the result type
+	bl	STRUCT_RETVALUE_P
+	cmpi	0,r3,0
+	beq	Lfinish			; nope.
+	/* Recover a pointer to the results.  */
+	addi	r11,r1,(SAVE_SIZE-RESULT_BYTES)
+	lg	r3,0(r11)		; we need at least this...
+	lg	r4,8(r11)
+	cmpi	0,r0,16
+	beq	Lfinish		; special case 16 bytes we don't consider floats.
+
+	/* OK, frustratingly, the process of saving the struct to mem might have
+	   messed with the FPRs, so we have to re-load them :(.
+	   We`ll use our FPRs space again - calling: 
+	   void darwin64_pass_struct_floats (ffi_type *s, char *src, 
+					     unsigned *nfpr, double **fprs) 
+	   We`ll temporarily pinch the first two slots of the param area for local
+	   vars used by the routine.  */
+	xor	r6,r6,r6
+	addi	r5,r1,PARENT_PARM_BASE		; some space
+	sg	r6,0(r5)			; *nfpr zeroed.
+	addi	r6,r5,8				; **fprs
+	addi	r3,r1,FP_SAVE_BASE		; pointer to FPRs space
+	sg	r3,0(r6)
+	mr	r4,r11				; the struct is here...
+	lg	r3,LINKAGE_SIZE(r1)		; ffi_type * result_type.
+	bl	PASS_STR_FLOATS			; get struct floats into FPR save space.
+	/* See if we used any floats  */
+	lwz	r0,(SAVE_SIZE-RESULT_BYTES)(r1)	
+	cmpi	0,r0,0
+	beq	Lstructints			; nope.
+	/* OK load `em up... */
+	lfd	f1, (FP_SAVE_BASE                 )(r1)
+	lfd	f2, (FP_SAVE_BASE +  FPR_SIZE     )(r1)
+	lfd	f3, (FP_SAVE_BASE +  FPR_SIZE * 2 )(r1)
+	lfd	f4, (FP_SAVE_BASE +  FPR_SIZE * 3 )(r1)
+	lfd	f5, (FP_SAVE_BASE +  FPR_SIZE * 4 )(r1)
+	lfd	f6, (FP_SAVE_BASE +  FPR_SIZE * 5 )(r1)
+	lfd	f7, (FP_SAVE_BASE +  FPR_SIZE * 6 )(r1)
+	lfd	f8, (FP_SAVE_BASE +  FPR_SIZE * 7 )(r1)
+	lfd	f9, (FP_SAVE_BASE +  FPR_SIZE * 8 )(r1)
+	lfd	f10,(FP_SAVE_BASE +  FPR_SIZE * 9 )(r1)
+	lfd	f11,(FP_SAVE_BASE +  FPR_SIZE * 10)(r1)
+	lfd	f12,(FP_SAVE_BASE +  FPR_SIZE * 11)(r1)
+	lfd	f13,(FP_SAVE_BASE +  FPR_SIZE * 12)(r1)
+
+	/* point back at our saved struct.  */
+Lstructints:
+	addi	r11,r1,(SAVE_SIZE-RESULT_BYTES)
+	lg	r3,0(r11)			; we end up picking the
+	lg	r4,8(r11)			; first two again.
+	lg	r5,16(r11)
+	lg	r6,24(r11)
+	lg	r7,32(r11)
+	lg	r8,40(r11)
+	lg	r9,48(r11)
+	lg	r10,56(r11)
+#endif
+
+/* case done  */
+Lfinish:
+	addi	r1,r1,SAVE_SIZE		/* Restore stack pointer.  */
+	lg	r0,SAVED_LR_OFFSET(r1)	/* Get return address.  */
+	mtlr	r0			/* Reset link register.  */
+	blr
+Lendcode:
+	.align 1
+	
+/* END(ffi_closure_ASM)  */
+
+/* EH frame stuff.  */
+#define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78)
+/* 176, 400 */
+#define EH_FRAME_OFFSETA MODE_CHOICE(176,0x90)
+#define EH_FRAME_OFFSETB MODE_CHOICE(1,3)
+
+	.static_data
+	.align LOG2_GPR_BYTES
+LLFB1$non_lazy_ptr:
+	.g_long Lstartcode
+
+	.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
+EH_frame1:
+	.set	L$set$0,LECIE1-LSCIE1
+	.long	L$set$0	; Length of Common Information Entry
+LSCIE1:
+	.long	0x0	; CIE Identifier Tag
+	.byte	0x1	; CIE Version
+	.ascii	"zR\0"	; CIE Augmentation
+	.byte	0x1	; uleb128 0x1; CIE Code Alignment Factor
+	.byte	EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor
+	.byte	0x41	; CIE RA Column
+	.byte	0x1	; uleb128 0x1; Augmentation size
+	.byte	0x10	; FDE Encoding (indirect pcrel)
+	.byte	0xc	; DW_CFA_def_cfa
+	.byte	0x1	; uleb128 0x1
+	.byte	0x0	; uleb128 0x0
+	.align	LOG2_GPR_BYTES
+LECIE1:
+	.globl _ffi_closure_ASM.eh
+_ffi_closure_ASM.eh:
+LSFDE1:
+	.set	L$set$1,LEFDE1-LASFDE1
+	.long	L$set$1	; FDE Length
+
+LASFDE1:
+	.long	LASFDE1-EH_frame1	; FDE CIE offset
+	.g_long	LLFB1$non_lazy_ptr-.	; FDE initial location
+	.set	L$set$3,LFE1-Lstartcode
+	.g_long	L$set$3	; FDE address range
+	.byte   0x0     ; uleb128 0x0; Augmentation size
+	.byte	0x4	; DW_CFA_advance_loc4
+	.set	L$set$3,LCFI1-LCFI0
+	.long	L$set$3
+	.byte	0xe	; DW_CFA_def_cfa_offset
+	.byte	EH_FRAME_OFFSETA,EH_FRAME_OFFSETB	; uleb128 176,1/190,3
+	.byte	0x4	; DW_CFA_advance_loc4
+	.set	L$set$4,LCFI0-Lstartcode
+	.long	L$set$4
+	.byte   0x11    ; DW_CFA_offset_extended_sf
+	.byte	0x41	; uleb128 0x41
+	.byte   0x7e    ; sleb128 -2
+	.align	LOG2_GPR_BYTES
+LEFDE1:
+	.align 	1
+
+#ifdef WANT_STUB
+	.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
+	.align 5
+L_ffi_closure_helper_DARWIN$stub:
+	.indirect_symbol _ffi_closure_helper_DARWIN
+	mflr r0
+	bcl 20,31,"L00000000001$spb"
+"L00000000001$spb":
+	mflr r11
+	addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L00000000001$spb")
+	mtlr r0
+	lwzu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L00000000001$spb")(r11)
+	mtctr r12
+	bctr
+	.lazy_symbol_pointer
+L_ffi_closure_helper_DARWIN$lazy_ptr:
+	.indirect_symbol _ffi_closure_helper_DARWIN
+	.long	dyld_stub_binding_helper
+
+#if defined(__ppc64__)
+	.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
+	.align 5
+L_darwin64_struct_ret_by_value_p$stub:
+	.indirect_symbol _darwin64_struct_ret_by_value_p
+	mflr r0
+	bcl 20,31,"L00000000002$spb"
+"L00000000002$spb":
+	mflr r11
+	addis r11,r11,ha16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L00000000002$spb")
+	mtlr r0
+	lwzu r12,lo16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L00000000002$spb")(r11)
+	mtctr r12
+	bctr
+	.lazy_symbol_pointer
+L_darwin64_struct_ret_by_value_p$lazy_ptr:
+	.indirect_symbol _darwin64_struct_ret_by_value_p
+	.long	dyld_stub_binding_helper
+	.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
+	.align 5
+L_darwin64_pass_struct_floats$stub:
+	.indirect_symbol _darwin64_pass_struct_floats
+	mflr r0
+	bcl 20,31,"L00000000003$spb"
+"L00000000003$spb":
+	mflr r11
+	addis r11,r11,ha16(L_darwin64_pass_struct_floats$lazy_ptr-"L00000000003$spb")
+	mtlr r0
+	lwzu r12,lo16(L_darwin64_pass_struct_floats$lazy_ptr-"L00000000003$spb")(r11)
+	mtctr r12
+	bctr
+	.lazy_symbol_pointer
+L_darwin64_pass_struct_floats$lazy_ptr:
+	.indirect_symbol _darwin64_pass_struct_floats
+	.long	dyld_stub_binding_helper
+#  endif
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/ffi.c
new file mode 100755
index 0000000..fb2a39f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/ffi.c
@@ -0,0 +1,1448 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (C) 2011 Anthony Green
+           Copyright (C) 2008 Red Hat, Inc
+           Copyright (C) 2007, 2008 Free Software Foundation, Inc
+	   Copyright (c) 1998 Geoffrey Keating
+
+   PowerPC Foreign Function Interface
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+
+extern void ffi_closure_SYSV (void);
+extern void FFI_HIDDEN ffi_closure_LINUX64 (void);
+
+enum {
+  /* The assembly depends on these exact flags.  */
+  FLAG_RETURNS_SMST	= 1 << (31-31), /* Used for FFI_SYSV small structs.  */
+  FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7 */
+  FLAG_RETURNS_FP       = 1 << (31-29),
+  FLAG_RETURNS_64BITS   = 1 << (31-28),
+
+  FLAG_RETURNS_128BITS  = 1 << (31-27), /* cr6  */
+  FLAG_SYSV_SMST_R4     = 1 << (31-26), /* use r4 for FFI_SYSV 8 byte
+					   structs.  */
+  FLAG_SYSV_SMST_R3     = 1 << (31-25), /* use r3 for FFI_SYSV 4 byte
+					   structs.  */
+  /* Bits (31-24) through (31-19) store shift value for SMST */
+
+  FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
+  FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
+  FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
+  FLAG_RETVAL_REFERENCE = 1 << (31- 4)
+};
+
+/* About the SYSV ABI.  */
+unsigned int NUM_GPR_ARG_REGISTERS = 8;
+#ifndef __NO_FPRS__
+unsigned int NUM_FPR_ARG_REGISTERS = 8;
+#else
+unsigned int NUM_FPR_ARG_REGISTERS = 0;
+#endif
+
+enum { ASM_NEEDS_REGISTERS = 4 };
+
+/* ffi_prep_args_SYSV is called by the assembly routine once stack space
+   has been allocated for the function's arguments.
+
+   The stack layout we want looks like this:
+
+   |   Return address from ffi_call_SYSV 4bytes	|	higher addresses
+   |--------------------------------------------|
+   |   Previous backchain pointer	4	|       stack pointer here
+   |--------------------------------------------|<+ <<<	on entry to
+   |   Saved r28-r31			4*4	| |	ffi_call_SYSV
+   |--------------------------------------------| |
+   |   GPR registers r3-r10		8*4	| |	ffi_call_SYSV
+   |--------------------------------------------| |
+   |   FPR registers f1-f8 (optional)	8*8	| |
+   |--------------------------------------------| |	stack	|
+   |   Space for copied structures		| |	grows	|
+   |--------------------------------------------| |	down    V
+   |   Parameters that didn't fit in registers  | |
+   |--------------------------------------------| |	lower addresses
+   |   Space for callee's LR		4	| |
+   |--------------------------------------------| |	stack pointer here
+   |   Current backchain pointer	4	|-/	during
+   |--------------------------------------------|   <<<	ffi_call_SYSV
+
+*/
+
+void
+ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
+{
+  const unsigned bytes = ecif->cif->bytes;
+  const unsigned flags = ecif->cif->flags;
+
+  typedef union {
+    char *c;
+    unsigned *u;
+    long long *ll;
+    float *f;
+    double *d;
+  } valp;
+
+  /* 'stacktop' points at the previous backchain pointer.  */
+  valp stacktop;
+
+  /* 'gpr_base' points at the space for gpr3, and grows upwards as
+     we use GPR registers.  */
+  valp gpr_base;
+  int intarg_count;
+
+  /* 'fpr_base' points at the space for fpr1, and grows upwards as
+     we use FPR registers.  */
+  valp fpr_base;
+  int fparg_count;
+
+  /* 'copy_space' grows down as we put structures in it.  It should
+     stay 16-byte aligned.  */
+  valp copy_space;
+
+  /* 'next_arg' grows up as we put parameters in it.  */
+  valp next_arg;
+
+  int i, ii MAYBE_UNUSED;
+  ffi_type **ptr;
+  double double_tmp;
+  union {
+    void **v;
+    char **c;
+    signed char **sc;
+    unsigned char **uc;
+    signed short **ss;
+    unsigned short **us;
+    unsigned int **ui;
+    long long **ll;
+    float **f;
+    double **d;
+  } p_argv;
+  size_t struct_copy_size;
+  unsigned gprvalue;
+
+  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
+    NUM_FPR_ARG_REGISTERS = 0;
+
+  stacktop.c = (char *) stack + bytes;
+  gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
+  intarg_count = 0;
+  fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
+  fparg_count = 0;
+  copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
+  next_arg.u = stack + 2;
+
+  /* Check that everything starts aligned properly.  */
+  FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0);
+  FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0);
+  FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0);
+  FFI_ASSERT ((bytes & 0xF) == 0);
+  FFI_ASSERT (copy_space.c >= next_arg.c);
+
+  /* Deal with return values that are actually pass-by-reference.  */
+  if (flags & FLAG_RETVAL_REFERENCE)
+    {
+      *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue;
+      intarg_count++;
+    }
+
+  /* Now for the arguments.  */
+  p_argv.v = ecif->avalue;
+  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+       i > 0;
+       i--, ptr++, p_argv.v++)
+    {
+      switch ((*ptr)->type)
+	{
+	case FFI_TYPE_FLOAT:
+	  /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
+	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
+	    goto soft_float_prep;
+	  double_tmp = **p_argv.f;
+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+	    {
+	      *next_arg.f = (float) double_tmp;
+	      next_arg.u += 1;
+	      intarg_count++;
+	    }
+	  else
+	    *fpr_base.d++ = double_tmp;
+	  fparg_count++;
+	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
+	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
+	    goto soft_double_prep;
+	  double_tmp = **p_argv.d;
+
+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+	    {
+	      if (intarg_count >= NUM_GPR_ARG_REGISTERS
+		  && intarg_count % 2 != 0)
+		{
+		  intarg_count++;
+		  next_arg.u++;
+		}
+	      *next_arg.d = double_tmp;
+	      next_arg.u += 2;
+	    }
+	  else
+	    *fpr_base.d++ = double_tmp;
+	  fparg_count++;
+	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+	  break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+	  if ((ecif->cif->abi != FFI_LINUX)
+		&& (ecif->cif->abi != FFI_LINUX_SOFT_FLOAT))
+	    goto do_struct;
+	  /* The soft float ABI for long doubles works like this,
+	     a long double is passed in four consecutive gprs if available.
+	     A maximum of 2 long doubles can be passed in gprs.
+	     If we do not have 4 gprs left, the long double is passed on the
+	     stack, 4-byte aligned.  */
+	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
+	    {
+	      unsigned int int_tmp = (*p_argv.ui)[0];
+	      if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3)
+		{
+		  if (intarg_count < NUM_GPR_ARG_REGISTERS)
+		    intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
+		  *next_arg.u = int_tmp;
+		  next_arg.u++;
+		  for (ii = 1; ii < 4; ii++)
+		    {
+		      int_tmp = (*p_argv.ui)[ii];
+		      *next_arg.u = int_tmp;
+		      next_arg.u++;
+		    }
+		}
+	      else
+		{
+		  *gpr_base.u++ = int_tmp;
+		  for (ii = 1; ii < 4; ii++)
+		    {
+		      int_tmp = (*p_argv.ui)[ii];
+		      *gpr_base.u++ = int_tmp;
+		    }
+		}
+	      intarg_count +=4;
+	    }
+	  else
+	    {
+	      double_tmp = (*p_argv.d)[0];
+
+	      if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1)
+		{
+		  if (intarg_count >= NUM_GPR_ARG_REGISTERS
+		      && intarg_count % 2 != 0)
+		    {
+		      intarg_count++;
+		      next_arg.u++;
+		    }
+		  *next_arg.d = double_tmp;
+		  next_arg.u += 2;
+		  double_tmp = (*p_argv.d)[1];
+		  *next_arg.d = double_tmp;
+		  next_arg.u += 2;
+		}
+	      else
+		{
+		  *fpr_base.d++ = double_tmp;
+		  double_tmp = (*p_argv.d)[1];
+		  *fpr_base.d++ = double_tmp;
+		}
+
+	      fparg_count += 2;
+	      FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+	    }
+	  break;
+#endif
+
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	soft_double_prep:
+	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
+	    intarg_count++;
+	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
+	    {
+	      if (intarg_count % 2 != 0)
+		{
+		  intarg_count++;
+		  next_arg.u++;
+		}
+	      *next_arg.ll = **p_argv.ll;
+	      next_arg.u += 2;
+	    }
+	  else
+	    {
+	      /* whoops: abi states only certain register pairs
+	       * can be used for passing long long int
+	       * specifically (r3,r4), (r5,r6), (r7,r8),
+	       * (r9,r10) and if next arg is long long but
+	       * not correct starting register of pair then skip
+	       * until the proper starting register
+	       */
+	      if (intarg_count % 2 != 0)
+		{
+		  intarg_count ++;
+		  gpr_base.u++;
+		}
+	      *gpr_base.ll++ = **p_argv.ll;
+	    }
+	  intarg_count += 2;
+	  break;
+
+	case FFI_TYPE_STRUCT:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	do_struct:
+#endif
+	  struct_copy_size = ((*ptr)->size + 15) & ~0xF;
+	  copy_space.c -= struct_copy_size;
+	  memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
+
+	  gprvalue = (unsigned long) copy_space.c;
+
+	  FFI_ASSERT (copy_space.c > next_arg.c);
+	  FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
+	  goto putgpr;
+
+	case FFI_TYPE_UINT8:
+	  gprvalue = **p_argv.uc;
+	  goto putgpr;
+	case FFI_TYPE_SINT8:
+	  gprvalue = **p_argv.sc;
+	  goto putgpr;
+	case FFI_TYPE_UINT16:
+	  gprvalue = **p_argv.us;
+	  goto putgpr;
+	case FFI_TYPE_SINT16:
+	  gprvalue = **p_argv.ss;
+	  goto putgpr;
+
+	case FFI_TYPE_INT:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_POINTER:
+	soft_float_prep:
+
+	  gprvalue = **p_argv.ui;
+
+	putgpr:
+	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
+	    *next_arg.u++ = gprvalue;
+	  else
+	    *gpr_base.u++ = gprvalue;
+	  intarg_count++;
+	  break;
+	}
+    }
+
+  /* Check that we didn't overrun the stack...  */
+  FFI_ASSERT (copy_space.c >= next_arg.c);
+  FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
+  FFI_ASSERT (fpr_base.u
+	      <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
+  FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
+}
+
+/* About the LINUX64 ABI.  */
+enum {
+  NUM_GPR_ARG_REGISTERS64 = 8,
+  NUM_FPR_ARG_REGISTERS64 = 13
+};
+enum { ASM_NEEDS_REGISTERS64 = 4 };
+
+/* ffi_prep_args64 is called by the assembly routine once stack space
+   has been allocated for the function's arguments.
+
+   The stack layout we want looks like this:
+
+   |   Ret addr from ffi_call_LINUX64	8bytes	|	higher addresses
+   |--------------------------------------------|
+   |   CR save area			8bytes	|
+   |--------------------------------------------|
+   |   Previous backchain pointer	8	|	stack pointer here
+   |--------------------------------------------|<+ <<<	on entry to
+   |   Saved r28-r31			4*8	| |	ffi_call_LINUX64
+   |--------------------------------------------| |
+   |   GPR registers r3-r10		8*8	| |
+   |--------------------------------------------| |
+   |   FPR registers f1-f13 (optional)	13*8	| |
+   |--------------------------------------------| |
+   |   Parameter save area		        | |
+   |--------------------------------------------| |
+   |   TOC save area			8	| |
+   |--------------------------------------------| |	stack	|
+   |   Linker doubleword		8	| |	grows	|
+   |--------------------------------------------| |	down	V
+   |   Compiler doubleword		8	| |
+   |--------------------------------------------| |	lower addresses
+   |   Space for callee's LR		8	| |
+   |--------------------------------------------| |
+   |   CR save area			8	| |
+   |--------------------------------------------| |	stack pointer here
+   |   Current backchain pointer	8	|-/	during
+   |--------------------------------------------|   <<<	ffi_call_LINUX64
+
+*/
+
+void FFI_HIDDEN
+ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
+{
+  const unsigned long bytes = ecif->cif->bytes;
+  const unsigned long flags = ecif->cif->flags;
+
+  typedef union {
+    char *c;
+    unsigned long *ul;
+    float *f;
+    double *d;
+  } valp;
+
+  /* 'stacktop' points at the previous backchain pointer.  */
+  valp stacktop;
+
+  /* 'next_arg' points at the space for gpr3, and grows upwards as
+     we use GPR registers, then continues at rest.  */
+  valp gpr_base;
+  valp gpr_end;
+  valp rest;
+  valp next_arg;
+
+  /* 'fpr_base' points at the space for fpr3, and grows upwards as
+     we use FPR registers.  */
+  valp fpr_base;
+  int fparg_count;
+
+  int i, words;
+  ffi_type **ptr;
+  double double_tmp;
+  union {
+    void **v;
+    char **c;
+    signed char **sc;
+    unsigned char **uc;
+    signed short **ss;
+    unsigned short **us;
+    signed int **si;
+    unsigned int **ui;
+    unsigned long **ul;
+    float **f;
+    double **d;
+  } p_argv;
+  unsigned long gprvalue;
+
+  stacktop.c = (char *) stack + bytes;
+  gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;
+  gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64;
+  rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64;
+  fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;
+  fparg_count = 0;
+  next_arg.ul = gpr_base.ul;
+
+  /* Check that everything starts aligned properly.  */
+  FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
+  FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
+  FFI_ASSERT ((bytes & 0xF) == 0);
+
+  /* Deal with return values that are actually pass-by-reference.  */
+  if (flags & FLAG_RETVAL_REFERENCE)
+    *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue;
+
+  /* Now for the arguments.  */
+  p_argv.v = ecif->avalue;
+  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+       i > 0;
+       i--, ptr++, p_argv.v++)
+    {
+      switch ((*ptr)->type)
+	{
+	case FFI_TYPE_FLOAT:
+	  double_tmp = **p_argv.f;
+	  *next_arg.f = (float) double_tmp;
+	  if (++next_arg.ul == gpr_end.ul)
+	    next_arg.ul = rest.ul;
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+	    *fpr_base.d++ = double_tmp;
+	  fparg_count++;
+	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  double_tmp = **p_argv.d;
+	  *next_arg.d = double_tmp;
+	  if (++next_arg.ul == gpr_end.ul)
+	    next_arg.ul = rest.ul;
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+	    *fpr_base.d++ = double_tmp;
+	  fparg_count++;
+	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+	  break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+	  double_tmp = (*p_argv.d)[0];
+	  *next_arg.d = double_tmp;
+	  if (++next_arg.ul == gpr_end.ul)
+	    next_arg.ul = rest.ul;
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+	    *fpr_base.d++ = double_tmp;
+	  fparg_count++;
+	  double_tmp = (*p_argv.d)[1];
+	  *next_arg.d = double_tmp;
+	  if (++next_arg.ul == gpr_end.ul)
+	    next_arg.ul = rest.ul;
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+	    *fpr_base.d++ = double_tmp;
+	  fparg_count++;
+	  FFI_ASSERT (__LDBL_MANT_DIG__ == 106);
+	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+	  break;
+#endif
+
+	case FFI_TYPE_STRUCT:
+	  words = ((*ptr)->size + 7) / 8;
+	  if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
+	    {
+	      size_t first = gpr_end.c - next_arg.c;
+	      memcpy (next_arg.c, *p_argv.c, first);
+	      memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
+	      next_arg.c = rest.c + words * 8 - first;
+	    }
+	  else
+	    {
+	      char *where = next_arg.c;
+
+	      /* Structures with size less than eight bytes are passed
+		 left-padded.  */
+	      if ((*ptr)->size < 8)
+		where += 8 - (*ptr)->size;
+
+	      memcpy (where, *p_argv.c, (*ptr)->size);
+	      next_arg.ul += words;
+	      if (next_arg.ul == gpr_end.ul)
+		next_arg.ul = rest.ul;
+	    }
+	  break;
+
+	case FFI_TYPE_UINT8:
+	  gprvalue = **p_argv.uc;
+	  goto putgpr;
+	case FFI_TYPE_SINT8:
+	  gprvalue = **p_argv.sc;
+	  goto putgpr;
+	case FFI_TYPE_UINT16:
+	  gprvalue = **p_argv.us;
+	  goto putgpr;
+	case FFI_TYPE_SINT16:
+	  gprvalue = **p_argv.ss;
+	  goto putgpr;
+	case FFI_TYPE_UINT32:
+	  gprvalue = **p_argv.ui;
+	  goto putgpr;
+	case FFI_TYPE_INT:
+	case FFI_TYPE_SINT32:
+	  gprvalue = **p_argv.si;
+	  goto putgpr;
+
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_POINTER:
+	  gprvalue = **p_argv.ul;
+	putgpr:
+	  *next_arg.ul++ = gprvalue;
+	  if (next_arg.ul == gpr_end.ul)
+	    next_arg.ul = rest.ul;
+	  break;
+	}
+    }
+
+  FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS
+	      || (next_arg.ul >= gpr_base.ul
+		  && next_arg.ul <= gpr_base.ul + 4));
+}
+
+
+
+/* Perform machine dependent cif processing */
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+  /* All this is for the SYSV and LINUX64 ABI.  */
+  int i;
+  ffi_type **ptr;
+  unsigned bytes;
+  int fparg_count = 0, intarg_count = 0;
+  unsigned flags = 0;
+  unsigned struct_copy_size = 0;
+  unsigned type = cif->rtype->type;
+  unsigned size = cif->rtype->size;
+
+  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+    NUM_FPR_ARG_REGISTERS = 0;
+
+  if (cif->abi != FFI_LINUX64)
+    {
+      /* All the machine-independent calculation of cif->bytes will be wrong.
+	 Redo the calculation for SYSV.  */
+
+      /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
+      bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);
+
+      /* Space for the GPR registers.  */
+      bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);
+    }
+  else
+    {
+      /* 64-bit ABI.  */
+
+      /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
+	 regs.  */
+      bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long);
+
+      /* Space for the mandatory parm save area and general registers.  */
+      bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long);
+    }
+
+  /* Return value handling.  The rules for SYSV are as follows:
+     - 32-bit (or less) integer values are returned in gpr3;
+     - Structures of size <= 4 bytes also returned in gpr3;
+     - 64-bit integer values and structures between 5 and 8 bytes are returned
+     in gpr3 and gpr4;
+     - Single/double FP values are returned in fpr1;
+     - Larger structures are allocated space and a pointer is passed as
+     the first argument.
+     - long doubles (if not equivalent to double) are returned in
+     fpr1,fpr2 for Linux and as for large structs for SysV.
+     For LINUX64:
+     - integer values in gpr3;
+     - Structures/Unions by reference;
+     - Single/double FP values in fpr1, long double in fpr1,fpr2.
+     - soft-float float/doubles are treated as UINT32/UINT64 respectivley.
+     - soft-float long doubles are returned in gpr3-gpr6.  */
+  switch (type)
+    {
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+    case FFI_TYPE_LONGDOUBLE:
+      if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64
+	&& cif->abi != FFI_LINUX_SOFT_FLOAT)
+	goto byref;
+      flags |= FLAG_RETURNS_128BITS;
+      /* Fall through.  */
+#endif
+    case FFI_TYPE_DOUBLE:
+      flags |= FLAG_RETURNS_64BITS;
+      /* Fall through.  */
+    case FFI_TYPE_FLOAT:
+      /* With FFI_LINUX_SOFT_FLOAT no fp registers are used.  */
+      if (cif->abi != FFI_LINUX_SOFT_FLOAT)
+	flags |= FLAG_RETURNS_FP;
+      break;
+
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+      flags |= FLAG_RETURNS_64BITS;
+      break;
+
+    case FFI_TYPE_STRUCT:
+      if (cif->abi == FFI_SYSV)
+	{
+	  /* The final SYSV ABI says that structures smaller or equal 8 bytes
+	     are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
+	     in memory.  */
+
+	  /* Treat structs with size <= 8 bytes.  */
+	  if (size <= 8)
+	    {
+	      flags |= FLAG_RETURNS_SMST;
+	      /* These structs are returned in r3. We pack the type and the
+		 precalculated shift value (needed in the sysv.S) into flags.
+		 The same applies for the structs returned in r3/r4.  */
+	      if (size <= 4)
+		{
+		  flags |= FLAG_SYSV_SMST_R3;
+		  flags |= 8 * (4 - size) << 8;
+		  break;
+		}
+	      /* These structs are returned in r3 and r4. See above.   */
+	      if  (size <= 8)
+		{
+		  flags |= FLAG_SYSV_SMST_R3 | FLAG_SYSV_SMST_R4;
+		  flags |= 8 * (8 - size) << 8;
+		  break;
+		}
+	    }
+	}
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+    byref:
+#endif
+      intarg_count++;
+      flags |= FLAG_RETVAL_REFERENCE;
+      /* Fall through.  */
+    case FFI_TYPE_VOID:
+      flags |= FLAG_RETURNS_NOTHING;
+      break;
+
+    default:
+      /* Returns 32-bit integer, or similar.  Nothing to do here.  */
+      break;
+    }
+
+  if (cif->abi != FFI_LINUX64)
+    /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
+       first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
+       goes on the stack.  Structures and long doubles (if not equivalent
+       to double) are passed as a pointer to a copy of the structure.
+       Stuff on the stack needs to keep proper alignment.  */
+    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+      {
+	switch ((*ptr)->type)
+	  {
+	  case FFI_TYPE_FLOAT:
+	    /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
+	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+	      goto soft_float_cif;
+	    fparg_count++;
+	    /* floating singles are not 8-aligned on stack */
+	    break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	  case FFI_TYPE_LONGDOUBLE:
+	    if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
+	      goto do_struct;
+	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+	      {
+		if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
+		  || intarg_count < NUM_GPR_ARG_REGISTERS)
+		  /* A long double in FFI_LINUX_SOFT_FLOAT can use only
+		     a set of four consecutive gprs. If we have not enough,
+		     we have to adjust the intarg_count value.  */
+		  intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
+		intarg_count += 4;
+		break;
+	      }
+	    else
+	      fparg_count++;
+	    /* Fall thru */
+#endif
+	  case FFI_TYPE_DOUBLE:
+	    /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
+	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+	      goto soft_double_cif;
+	    fparg_count++;
+	    /* If this FP arg is going on the stack, it must be
+	       8-byte-aligned.  */
+	    if (fparg_count > NUM_FPR_ARG_REGISTERS
+		&& intarg_count >= NUM_GPR_ARG_REGISTERS
+		&& intarg_count % 2 != 0)
+	      intarg_count++;
+	    break;
+
+	  case FFI_TYPE_UINT64:
+	  case FFI_TYPE_SINT64:
+	  soft_double_cif:
+	    /* 'long long' arguments are passed as two words, but
+	       either both words must fit in registers or both go
+	       on the stack.  If they go on the stack, they must
+	       be 8-byte-aligned.
+
+	       Also, only certain register pairs can be used for
+	       passing long long int -- specifically (r3,r4), (r5,r6),
+	       (r7,r8), (r9,r10).
+	    */
+	    if (intarg_count == NUM_GPR_ARG_REGISTERS-1
+		|| intarg_count % 2 != 0)
+	      intarg_count++;
+	    intarg_count += 2;
+	    break;
+
+	  case FFI_TYPE_STRUCT:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	  do_struct:
+#endif
+	    /* We must allocate space for a copy of these to enforce
+	       pass-by-value.  Pad the space up to a multiple of 16
+	       bytes (the maximum alignment required for anything under
+	       the SYSV ABI).  */
+	    struct_copy_size += ((*ptr)->size + 15) & ~0xF;
+	    /* Fall through (allocate space for the pointer).  */
+
+	  default:
+	  soft_float_cif:
+	    /* Everything else is passed as a 4-byte word in a GPR, either
+	       the object itself or a pointer to it.  */
+	    intarg_count++;
+	    break;
+	  }
+      }
+  else
+    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+      {
+	switch ((*ptr)->type)
+	  {
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	  case FFI_TYPE_LONGDOUBLE:
+	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+	      intarg_count += 4;
+	    else
+	      {
+		fparg_count += 2;
+		intarg_count += 2;
+	      }
+	    break;
+#endif
+	  case FFI_TYPE_FLOAT:
+	  case FFI_TYPE_DOUBLE:
+	    fparg_count++;
+	    intarg_count++;
+	    break;
+
+	  case FFI_TYPE_STRUCT:
+	    intarg_count += ((*ptr)->size + 7) / 8;
+	    break;
+
+	  default:
+	    /* Everything else is passed as a 8-byte word in a GPR, either
+	       the object itself or a pointer to it.  */
+	    intarg_count++;
+	    break;
+	  }
+      }
+
+  if (fparg_count != 0)
+    flags |= FLAG_FP_ARGUMENTS;
+  if (intarg_count > 4)
+    flags |= FLAG_4_GPR_ARGUMENTS;
+  if (struct_copy_size != 0)
+    flags |= FLAG_ARG_NEEDS_COPY;
+
+  if (cif->abi != FFI_LINUX64)
+    {
+      /* Space for the FPR registers, if needed.  */
+      if (fparg_count != 0)
+	bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
+
+      /* Stack space.  */
+      if (intarg_count > NUM_GPR_ARG_REGISTERS)
+	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
+      if (fparg_count > NUM_FPR_ARG_REGISTERS)
+	bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
+    }
+  else
+    {
+      /* Space for the FPR registers, if needed.  */
+      if (fparg_count != 0)
+	bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);
+
+      /* Stack space.  */
+      if (intarg_count > NUM_GPR_ARG_REGISTERS64)
+	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long);
+    }
+
+  /* The stack space allocated needs to be a multiple of 16 bytes.  */
+  bytes = (bytes + 15) & ~0xF;
+
+  /* Add in the space for the copied structures.  */
+  bytes += struct_copy_size;
+
+  cif->flags = flags;
+  cif->bytes = bytes;
+
+  return FFI_OK;
+}
+
+extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *,
+			  void (*fn)(void));
+extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long,
+					unsigned long, unsigned long *,
+					void (*fn)(void));
+
+void
+ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      ecif.rvalue = alloca(cif->rtype->size);
+    }
+  else
+    ecif.rvalue = rvalue;
+
+
+  switch (cif->abi)
+    {
+#ifndef POWERPC64
+    case FFI_SYSV:
+    case FFI_GCC_SYSV:
+    case FFI_LINUX:
+    case FFI_LINUX_SOFT_FLOAT:
+      ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn);
+      break;
+#else
+    case FFI_LINUX64:
+      ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn);
+      break;
+#endif
+    default:
+      FFI_ASSERT (0);
+      break;
+    }
+}
+
+
+#ifndef POWERPC64
+#define MIN_CACHE_LINE_SIZE 8
+
+static void
+flush_icache (char *wraddr, char *xaddr, int size)
+{
+  int i;
+  for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
+    __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;"
+		      : : "r" (xaddr + i), "r" (wraddr + i) : "memory");
+  __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;"
+		    : : "r"(xaddr + size - 1), "r"(wraddr + size - 1)
+		    : "memory");
+}
+#endif
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure *closure,
+		      ffi_cif *cif,
+		      void (*fun) (ffi_cif *, void *, void **, void *),
+		      void *user_data,
+		      void *codeloc)
+{
+#ifdef POWERPC64
+  void **tramp = (void **) &closure->tramp[0];
+
+  if (cif->abi != FFI_LINUX64)
+    return FFI_BAD_ABI;
+  /* Copy function address and TOC from ffi_closure_LINUX64.  */
+  memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
+  tramp[2] = codeloc;
+#else
+  unsigned int *tramp;
+
+  if (! (cif->abi == FFI_GCC_SYSV 
+	 || cif->abi == FFI_SYSV
+	 || cif->abi == FFI_LINUX
+	 || cif->abi == FFI_LINUX_SOFT_FLOAT))
+    return FFI_BAD_ABI;
+
+  tramp = (unsigned int *) &closure->tramp[0];
+  tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
+  tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
+  tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
+  tramp[5] = 0x7c0803a6;  /*   mtlr    r0 */
+  tramp[6] = 0x800b0000;  /*   lwz     r0,0(r11) */
+  tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
+  tramp[8] = 0x7c0903a6;  /*   mtctr   r0 */
+  tramp[9] = 0x4e800420;  /*   bctr */
+  *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */
+  *(void **) &tramp[3] = codeloc;                   /* context */
+
+  /* Flush the icache.  */
+  flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE);
+#endif
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  return FFI_OK;
+}
+
+typedef union
+{
+  float f;
+  double d;
+} ffi_dblfl;
+
+int ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *,
+			     ffi_dblfl *, unsigned long *);
+
+/* Basically the trampoline invokes ffi_closure_SYSV, and on
+ * entry, r11 holds the address of the closure.
+ * After storing the registers that could possibly contain
+ * parameters to be passed into the stack frame and setting
+ * up space for a return value, ffi_closure_SYSV invokes the
+ * following helper function to do most of the work
+ */
+
+int
+ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
+			 unsigned long *pgr, ffi_dblfl *pfr,
+			 unsigned long *pst)
+{
+  /* rvalue is the pointer to space for return value in closure assembly */
+  /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
+  /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
+  /* pst is the pointer to outgoing parameter stack in original caller */
+
+  void **          avalue;
+  ffi_type **      arg_types;
+  long             i, avn;
+  long             nf;   /* number of floating registers already used */
+  long             ng;   /* number of general registers already used */
+  ffi_cif *        cif;
+  double           temp;
+  unsigned         size;
+
+  cif = closure->cif;
+  avalue = alloca (cif->nargs * sizeof (void *));
+  size = cif->rtype->size;
+
+  nf = 0;
+  ng = 0;
+
+  /* Copy the caller's structure return value address so that the closure
+     returns the data directly to the caller.
+     For FFI_SYSV the result is passed in r3/r4 if the struct size is less
+     or equal 8 bytes.  */
+
+  if ((cif->rtype->type == FFI_TYPE_STRUCT
+       && !((cif->abi == FFI_SYSV) && (size <= 8)))
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+      || (cif->rtype->type == FFI_TYPE_LONGDOUBLE
+	  && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
+#endif
+      )
+    {
+      rvalue = (void *) *pgr;
+      ng++;
+      pgr++;
+    }
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  while (i < avn)
+    {
+      switch (arg_types[i]->type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	  /* there are 8 gpr registers used to pass values */
+	  if (ng < 8)
+	    {
+	      avalue[i] = (char *) pgr + 3;
+	      ng++;
+	      pgr++;
+	    }
+	  else
+	    {
+	      avalue[i] = (char *) pst + 3;
+	      pst++;
+	    }
+	  break;
+
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	  /* there are 8 gpr registers used to pass values */
+	  if (ng < 8)
+	    {
+	      avalue[i] = (char *) pgr + 2;
+	      ng++;
+	      pgr++;
+	    }
+	  else
+	    {
+	      avalue[i] = (char *) pst + 2;
+	      pst++;
+	    }
+	  break;
+
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_POINTER:
+	soft_float_closure:
+	  /* there are 8 gpr registers used to pass values */
+	  if (ng < 8)
+	    {
+	      avalue[i] = pgr;
+	      ng++;
+	      pgr++;
+	    }
+	  else
+	    {
+	      avalue[i] = pst;
+	      pst++;
+	    }
+	  break;
+
+	case FFI_TYPE_STRUCT:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	do_struct:
+#endif
+	  /* Structs are passed by reference. The address will appear in a
+	     gpr if it is one of the first 8 arguments.  */
+	  if (ng < 8)
+	    {
+	      avalue[i] = (void *) *pgr;
+	      ng++;
+	      pgr++;
+	    }
+	  else
+	    {
+	      avalue[i] = (void *) *pst;
+	      pst++;
+	    }
+	  break;
+
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	soft_double_closure:
+	  /* passing long long ints are complex, they must
+	   * be passed in suitable register pairs such as
+	   * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
+	   * and if the entire pair aren't available then the outgoing
+	   * parameter stack is used for both but an alignment of 8
+	   * must will be kept.  So we must either look in pgr
+	   * or pst to find the correct address for this type
+	   * of parameter.
+	   */
+	  if (ng < 7)
+	    {
+	      if (ng & 0x01)
+		{
+		  /* skip r4, r6, r8 as starting points */
+		  ng++;
+		  pgr++;
+		}
+	      avalue[i] = pgr;
+	      ng += 2;
+	      pgr += 2;
+	    }
+	  else
+	    {
+	      if (((long) pst) & 4)
+		pst++;
+	      avalue[i] = pst;
+	      pst += 2;
+	      ng = 8;
+	    }
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
+	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+	    goto soft_float_closure;
+	  /* unfortunately float values are stored as doubles
+	   * in the ffi_closure_SYSV code (since we don't check
+	   * the type in that routine).
+	   */
+
+	  /* there are 8 64bit floating point registers */
+
+	  if (nf < 8)
+	    {
+	      temp = pfr->d;
+	      pfr->f = (float) temp;
+	      avalue[i] = pfr;
+	      nf++;
+	      pfr++;
+	    }
+	  else
+	    {
+	      /* FIXME? here we are really changing the values
+	       * stored in the original calling routines outgoing
+	       * parameter stack.  This is probably a really
+	       * naughty thing to do but...
+	       */
+	      avalue[i] = pst;
+	      pst += 1;
+	    }
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
+	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+	    goto soft_double_closure;
+	  /* On the outgoing stack all values are aligned to 8 */
+	  /* there are 8 64bit floating point registers */
+
+	  if (nf < 8)
+	    {
+	      avalue[i] = pfr;
+	      nf++;
+	      pfr++;
+	    }
+	  else
+	    {
+	      if (((long) pst) & 4)
+		pst++;
+	      avalue[i] = pst;
+	      pst += 2;
+	    }
+	  break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+	  if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
+	    goto do_struct;
+	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+	    { /* Test if for the whole long double, 4 gprs are available.
+		 otherwise the stuff ends up on the stack.  */
+	      if (ng < 5)
+		{
+		  avalue[i] = pgr;
+		  pgr += 4;
+		  ng += 4;
+		}
+	      else
+		{
+		  avalue[i] = pst;
+		  pst += 4;
+		  ng = 8;
+		}
+	      break;
+	    }
+	  if (nf < 7)
+	    {
+	      avalue[i] = pfr;
+	      pfr += 2;
+	      nf += 2;
+	    }
+	  else
+	    {
+	      if (((long) pst) & 4)
+		pst++;
+	      avalue[i] = pst;
+	      pst += 4;
+	      nf = 8;
+	    }
+	  break;
+#endif
+
+	default:
+	  FFI_ASSERT (0);
+	}
+
+      i++;
+    }
+
+
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_SYSV how to perform return type promotions.
+     Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
+     we have to tell ffi_closure_SYSV how to treat them. We combine the base
+     type FFI_SYSV_TYPE_SMALL_STRUCT - 1  with the size of the struct.
+     So a one byte struct gets the return type 16. Return type 1 to 15 are
+     already used and we never have a struct with size zero. That is the reason
+     for the subtraction of 1. See the comment in ffitarget.h about ordering.
+  */
+  if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT
+      && size <= 8)
+    return (FFI_SYSV_TYPE_SMALL_STRUCT - 1) + size;
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+  else if (cif->rtype->type == FFI_TYPE_LONGDOUBLE
+	   && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
+    return FFI_TYPE_STRUCT;
+#endif
+  /* With FFI_LINUX_SOFT_FLOAT floats and doubles are handled like UINT32
+     respectivley UINT64.  */
+  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+    {
+      switch (cif->rtype->type)
+	{
+	case FFI_TYPE_FLOAT:
+	  return FFI_TYPE_UINT32;
+	  break;
+	case FFI_TYPE_DOUBLE:
+	  return FFI_TYPE_UINT64;
+	  break;
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+	  return FFI_TYPE_UINT128;
+	  break;
+#endif
+	default:
+	  return cif->rtype->type;
+	}
+    }
+  else
+    {
+      return cif->rtype->type;
+    }
+}
+
+int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
+					   unsigned long *, ffi_dblfl *);
+
+int FFI_HIDDEN
+ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
+			    unsigned long *pst, ffi_dblfl *pfr)
+{
+  /* rvalue is the pointer to space for return value in closure assembly */
+  /* pst is the pointer to parameter save area
+     (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
+  /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
+
+  void **avalue;
+  ffi_type **arg_types;
+  long i, avn;
+  ffi_cif *cif;
+  ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
+
+  cif = closure->cif;
+  avalue = alloca (cif->nargs * sizeof (void *));
+
+  /* Copy the caller's structure return value address so that the closure
+     returns the data directly to the caller.  */
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      rvalue = (void *) *pst;
+      pst++;
+    }
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  while (i < avn)
+    {
+      switch (arg_types[i]->type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	  avalue[i] = (char *) pst + 7;
+	  pst++;
+	  break;
+
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	  avalue[i] = (char *) pst + 6;
+	  pst++;
+	  break;
+
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	  avalue[i] = (char *) pst + 4;
+	  pst++;
+	  break;
+
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_POINTER:
+	  avalue[i] = pst;
+	  pst++;
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  /* Structures with size less than eight bytes are passed
+	     left-padded.  */
+	  if (arg_types[i]->size < 8)
+	    avalue[i] = (char *) pst + 8 - arg_types[i]->size;
+	  else
+	    avalue[i] = pst;
+	  pst += (arg_types[i]->size + 7) / 8;
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  /* unfortunately float values are stored as doubles
+	   * in the ffi_closure_LINUX64 code (since we don't check
+	   * the type in that routine).
+	   */
+
+	  /* there are 13 64bit floating point registers */
+
+	  if (pfr < end_pfr)
+	    {
+	      double temp = pfr->d;
+	      pfr->f = (float) temp;
+	      avalue[i] = pfr;
+	      pfr++;
+	    }
+	  else
+	    avalue[i] = pst;
+	  pst++;
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  /* On the outgoing stack all values are aligned to 8 */
+	  /* there are 13 64bit floating point registers */
+
+	  if (pfr < end_pfr)
+	    {
+	      avalue[i] = pfr;
+	      pfr++;
+	    }
+	  else
+	    avalue[i] = pst;
+	  pst++;
+	  break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+	  if (pfr + 1 < end_pfr)
+	    {
+	      avalue[i] = pfr;
+	      pfr += 2;
+	    }
+	  else
+	    {
+	      if (pfr < end_pfr)
+		{
+		  /* Passed partly in f13 and partly on the stack.
+		     Move it all to the stack.  */
+		  *pst = *(unsigned long *) pfr;
+		  pfr++;
+		}
+	      avalue[i] = pst;
+	    }
+	  pst += 2;
+	  break;
+#endif
+
+	default:
+	  FFI_ASSERT (0);
+	}
+
+      i++;
+    }
+
+
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_LINUX64 how to perform return type promotions.  */
+  return cif->rtype->type;
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c
new file mode 100755
index 0000000..ee03dab
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c
@@ -0,0 +1,1359 @@
+/* -----------------------------------------------------------------------
+   ffi_darwin.c
+
+   Copyright (C) 1998 Geoffrey Keating
+   Copyright (C) 2001 John Hornkvist
+   Copyright (C) 2002, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
+
+   FFI support for Darwin and AIX.
+   
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+extern void ffi_closure_ASM (void);
+
+enum {
+  /* The assembly depends on these exact flags.  
+     For Darwin64 (when FLAG_RETURNS_STRUCT is set):
+       FLAG_RETURNS_FP indicates that the structure embeds FP data.
+       FLAG_RETURNS_128BITS signals a special struct size that is not
+       expanded for float content.  */
+  FLAG_RETURNS_128BITS	= 1 << (31-31), /* These go in cr7  */
+  FLAG_RETURNS_NOTHING	= 1 << (31-30),
+  FLAG_RETURNS_FP	= 1 << (31-29),
+  FLAG_RETURNS_64BITS	= 1 << (31-28),
+
+  FLAG_RETURNS_STRUCT	= 1 << (31-27), /* This goes in cr6  */
+
+  FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
+  FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI  */
+  FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
+  FLAG_RETVAL_REFERENCE = 1 << (31- 4)
+};
+
+/* About the DARWIN ABI.  */
+enum {
+  NUM_GPR_ARG_REGISTERS = 8,
+  NUM_FPR_ARG_REGISTERS = 13,
+  LINKAGE_AREA_GPRS = 6
+};
+
+enum { ASM_NEEDS_REGISTERS = 4 }; /* r28-r31 */
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments.
+   
+   m32/m64
+
+   The stack layout we want looks like this:
+
+   |   Return address from ffi_call_DARWIN      |	higher addresses
+   |--------------------------------------------|
+   |   Previous backchain pointer	4/8	|	stack pointer here
+   |--------------------------------------------|<+ <<<	on entry to
+   |   ASM_NEEDS_REGISTERS=r28-r31   4*(4/8)	| |	ffi_call_DARWIN
+   |--------------------------------------------| |
+   |   When we have any FP activity... the	| |
+   |   FPRs occupy NUM_FPR_ARG_REGISTERS slots	| |
+   |   here fp13 .. fp1 from high to low addr.	| |
+   ~						~ ~
+   |   Parameters      (at least 8*4/8=32/64)	| | NUM_GPR_ARG_REGISTERS
+   |--------------------------------------------| |
+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |
+   |--------------------------------------------| |	stack	|
+   |   Reserved                       2*4/8	| |	grows	|
+   |--------------------------------------------| |	down	V
+   |   Space for callee's LR		4/8	| |
+   |--------------------------------------------| |	lower addresses
+   |   Saved CR [low word for m64]      4/8	| |
+   |--------------------------------------------| |     stack pointer here
+   |   Current backchain pointer	4/8	|-/	during
+   |--------------------------------------------|   <<<	ffi_call_DARWIN
+
+   */
+
+#if defined(POWERPC_DARWIN64)
+static void
+darwin64_pass_struct_by_value 
+  (ffi_type *, char *, unsigned, unsigned *, double **, unsigned long **);
+#endif
+
+/* This depends on GPR_SIZE = sizeof (unsigned long) */
+
+void
+ffi_prep_args (extended_cif *ecif, unsigned long *const stack)
+{
+  const unsigned bytes = ecif->cif->bytes;
+  const unsigned flags = ecif->cif->flags;
+  const unsigned nargs = ecif->cif->nargs;
+#if !defined(POWERPC_DARWIN64) 
+  const ffi_abi abi = ecif->cif->abi;
+#endif
+
+  /* 'stacktop' points at the previous backchain pointer.  */
+  unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long));
+
+  /* 'fpr_base' points at the space for fpr1, and grows upwards as
+     we use FPR registers.  */
+  double *fpr_base = (double *) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS;
+  int gp_count = 0, fparg_count = 0;
+
+  /* 'next_arg' grows up as we put parameters in it.  */
+  unsigned long *next_arg = stack + LINKAGE_AREA_GPRS; /* 6 reserved positions.  */
+
+  int i;
+  double double_tmp;
+  void **p_argv = ecif->avalue;
+  unsigned long gprvalue;
+  ffi_type** ptr = ecif->cif->arg_types;
+#if !defined(POWERPC_DARWIN64) 
+  char *dest_cpy;
+#endif
+  unsigned size_al = 0;
+
+  /* Check that everything starts aligned properly.  */
+  FFI_ASSERT(((unsigned) (char *) stack & 0xF) == 0);
+  FFI_ASSERT(((unsigned) (char *) stacktop & 0xF) == 0);
+  FFI_ASSERT((bytes & 0xF) == 0);
+
+  /* Deal with return values that are actually pass-by-reference.
+     Rule:
+     Return values are referenced by r3, so r4 is the first parameter.  */
+
+  if (flags & FLAG_RETVAL_REFERENCE)
+    *next_arg++ = (unsigned long) (char *) ecif->rvalue;
+
+  /* Now for the arguments.  */
+  for (i = nargs; i > 0; i--, ptr++, p_argv++)
+    {
+      switch ((*ptr)->type)
+	{
+	/* If a floating-point parameter appears before all of the general-
+	   purpose registers are filled, the corresponding GPRs that match
+	   the size of the floating-point parameter are skipped.  */
+	case FFI_TYPE_FLOAT:
+	  double_tmp = *(float *) *p_argv;
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
+	    *fpr_base++ = double_tmp;
+#if defined(POWERPC_DARWIN)
+	  *(float *)next_arg = *(float *) *p_argv;
+#else
+	  *(double *)next_arg = double_tmp;
+#endif
+	  next_arg++;
+	  gp_count++;
+	  fparg_count++;
+	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  double_tmp = *(double *) *p_argv;
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
+	    *fpr_base++ = double_tmp;
+	  *(double *)next_arg = double_tmp;
+#ifdef POWERPC64
+	  next_arg++;
+	  gp_count++;
+#else
+	  next_arg += 2;
+	  gp_count += 2;
+#endif
+	  fparg_count++;
+	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+	  break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+
+	case FFI_TYPE_LONGDOUBLE:
+#  if defined(POWERPC64) && !defined(POWERPC_DARWIN64)
+	  /* ??? This will exceed the regs count when the value starts at fp13
+	     and it will not put the extra bit on the stack.  */
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
+	    *(long double *) fpr_base++ = *(long double *) *p_argv;
+	  else
+	    *(long double *) next_arg = *(long double *) *p_argv;
+	  next_arg += 2;
+	  fparg_count += 2;
+#  else
+	  double_tmp = ((double *) *p_argv)[0];
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
+	    *fpr_base++ = double_tmp;
+	  *(double *) next_arg = double_tmp;
+#    if defined(POWERPC_DARWIN64)
+	  next_arg++;
+	  gp_count++;
+#    else
+	  next_arg += 2;
+	  gp_count += 2;
+#    endif
+	  fparg_count++;
+	  double_tmp = ((double *) *p_argv)[1];
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
+	    *fpr_base++ = double_tmp;
+	  *(double *) next_arg = double_tmp;
+#    if defined(POWERPC_DARWIN64)
+	  next_arg++;
+	  gp_count++;
+#    else
+	  next_arg += 2;
+	  gp_count += 2;
+#    endif
+	  fparg_count++;
+#  endif
+	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+	  break;
+#endif
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+#ifdef POWERPC64
+	  gprvalue = *(long long *) *p_argv;
+	  goto putgpr;
+#else
+	  *(long long *) next_arg = *(long long *) *p_argv;
+	  next_arg += 2;
+	  gp_count += 2;
+#endif
+	  break;
+	case FFI_TYPE_POINTER:
+	  gprvalue = *(unsigned long *) *p_argv;
+	  goto putgpr;
+	case FFI_TYPE_UINT8:
+	  gprvalue = *(unsigned char *) *p_argv;
+	  goto putgpr;
+	case FFI_TYPE_SINT8:
+	  gprvalue = *(signed char *) *p_argv;
+	  goto putgpr;
+	case FFI_TYPE_UINT16:
+	  gprvalue = *(unsigned short *) *p_argv;
+	  goto putgpr;
+	case FFI_TYPE_SINT16:
+	  gprvalue = *(signed short *) *p_argv;
+	  goto putgpr;
+
+	case FFI_TYPE_STRUCT:
+	  size_al = (*ptr)->size;
+#if defined(POWERPC_DARWIN64)
+	  next_arg = (unsigned long *)ALIGN((char *)next_arg, (*ptr)->alignment);
+	  darwin64_pass_struct_by_value (*ptr, (char *) *p_argv, 
+					 (unsigned) size_al,
+					 (unsigned int *) &fparg_count,
+					 &fpr_base, &next_arg);
+#else
+	  dest_cpy = (char *) next_arg;
+
+	  /* If the first member of the struct is a double, then include enough
+	     padding in the struct size to align it to double-word.  */
+	  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
+	    size_al = ALIGN((*ptr)->size, 8);
+
+#  if defined(POWERPC64) 
+	  FFI_ASSERT (abi != FFI_DARWIN);
+	  memcpy ((char *) dest_cpy, (char *) *p_argv, size_al);
+	  next_arg += (size_al + 7) / 8;
+#  else
+	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
+	     SI 4 bytes) are aligned as if they were those modes.
+	     Structures with 3 byte in size are padded upwards.  */
+	  if (size_al < 3 && abi == FFI_DARWIN)
+	    dest_cpy += 4 - size_al;
+
+	  memcpy((char *) dest_cpy, (char *) *p_argv, size_al);
+	  next_arg += (size_al + 3) / 4;
+#  endif
+#endif
+	  break;
+
+	case FFI_TYPE_INT:
+	case FFI_TYPE_SINT32:
+	  gprvalue = *(signed int *) *p_argv;
+	  goto putgpr;
+
+	case FFI_TYPE_UINT32:
+	  gprvalue = *(unsigned int *) *p_argv;
+	putgpr:
+	  *next_arg++ = gprvalue;
+	  gp_count++;
+	  break;
+	default:
+	  break;
+	}
+    }
+
+  /* Check that we didn't overrun the stack...  */
+  //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
+  //FFI_ASSERT((unsigned *)fpr_base
+  //	     <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
+  //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
+}
+
+#if defined(POWERPC_DARWIN64)
+
+/* See if we can put some of the struct into fprs.
+   This should not be called for structures of size 16 bytes, since these are not
+   broken out this way.  */
+static void
+darwin64_scan_struct_for_floats (ffi_type *s, unsigned *nfpr)
+{
+  int i;
+
+  FFI_ASSERT (s->type == FFI_TYPE_STRUCT)
+
+  for (i = 0; s->elements[i] != NULL; i++)
+    {
+      ffi_type *p = s->elements[i];
+      switch (p->type)
+	{
+	  case FFI_TYPE_STRUCT:
+	    darwin64_scan_struct_for_floats (p, nfpr);
+	    break;
+	  case FFI_TYPE_LONGDOUBLE:
+	    (*nfpr) += 2;
+	    break;
+	  case FFI_TYPE_DOUBLE:
+	  case FFI_TYPE_FLOAT:
+	    (*nfpr) += 1;
+	    break;
+	  default:
+	    break;    
+	}
+    }
+}
+
+static int
+darwin64_struct_size_exceeds_gprs_p (ffi_type *s, char *src, unsigned *nfpr)
+{
+  unsigned struct_offset=0, i;
+
+  for (i = 0; s->elements[i] != NULL; i++)
+    {
+      char *item_base;
+      ffi_type *p = s->elements[i];
+      /* Find the start of this item (0 for the first one).  */
+      if (i > 0)
+        struct_offset = ALIGN(struct_offset, p->alignment);
+
+      item_base = src + struct_offset;
+
+      switch (p->type)
+	{
+	  case FFI_TYPE_STRUCT:
+	    if (darwin64_struct_size_exceeds_gprs_p (p, item_base, nfpr))
+	      return 1;
+	    break;
+	  case FFI_TYPE_LONGDOUBLE:
+	    if (*nfpr >= NUM_FPR_ARG_REGISTERS)
+	      return 1;
+	    (*nfpr) += 1;
+	    item_base += 8;
+	  /* FALL THROUGH */
+	  case FFI_TYPE_DOUBLE:
+	    if (*nfpr >= NUM_FPR_ARG_REGISTERS)
+	      return 1;
+	    (*nfpr) += 1;
+	    break;
+	  case FFI_TYPE_FLOAT:
+	    if (*nfpr >= NUM_FPR_ARG_REGISTERS)
+	      return 1;
+	    (*nfpr) += 1;
+	    break;
+	  default:
+	    /* If we try and place any item, that is non-float, once we've
+	       exceeded the 8 GPR mark, then we can't fit the struct.  */
+	    if ((unsigned long)item_base >= 8*8) 
+	      return 1;
+	    break;    
+	}
+      /* now count the size of what we just used.  */
+      struct_offset += p->size;
+    }
+  return 0;
+}
+
+/* Can this struct be returned by value?  */
+int 
+darwin64_struct_ret_by_value_p (ffi_type *s)
+{
+  unsigned nfp = 0;
+
+  FFI_ASSERT (s && s->type == FFI_TYPE_STRUCT);
+  
+  /* The largest structure we can return is 8long + 13 doubles.  */
+  if (s->size > 168)
+    return 0;
+  
+  /* We can't pass more than 13 floats.  */
+  darwin64_scan_struct_for_floats (s, &nfp);
+  if (nfp > 13)
+    return 0;
+  
+  /* If there are not too many floats, and the struct is
+     small enough to accommodate in the GPRs, then it must be OK.  */
+  if (s->size <= 64)
+    return 1;
+  
+  /* Well, we have to look harder.  */
+  nfp = 0;
+  if (darwin64_struct_size_exceeds_gprs_p (s, NULL, &nfp))
+    return 0;
+  
+  return 1;
+}
+
+void
+darwin64_pass_struct_floats (ffi_type *s, char *src, 
+			     unsigned *nfpr, double **fprs)
+{
+  int i;
+  double *fpr_base = *fprs;
+  unsigned struct_offset = 0;
+
+  /* We don't assume anything about the alignment of the source.  */
+  for (i = 0; s->elements[i] != NULL; i++)
+    {
+      char *item_base;
+      ffi_type *p = s->elements[i];
+      /* Find the start of this item (0 for the first one).  */
+      if (i > 0)
+        struct_offset = ALIGN(struct_offset, p->alignment);
+      item_base = src + struct_offset;
+
+      switch (p->type)
+	{
+	  case FFI_TYPE_STRUCT:
+	    darwin64_pass_struct_floats (p, item_base, nfpr,
+					   &fpr_base);
+	    break;
+	  case FFI_TYPE_LONGDOUBLE:
+	    if (*nfpr < NUM_FPR_ARG_REGISTERS)
+	      *fpr_base++ = *(double *)item_base;
+	    (*nfpr) += 1;
+	    item_base += 8;
+	  /* FALL THROUGH */
+	  case FFI_TYPE_DOUBLE:
+	    if (*nfpr < NUM_FPR_ARG_REGISTERS)
+	      *fpr_base++ = *(double *)item_base;
+	    (*nfpr) += 1;
+	    break;
+	  case FFI_TYPE_FLOAT:
+	    if (*nfpr < NUM_FPR_ARG_REGISTERS)
+	      *fpr_base++ = (double) *(float *)item_base;
+	    (*nfpr) += 1;
+	    break;
+	  default:
+	    break;    
+	}
+      /* now count the size of what we just used.  */
+      struct_offset += p->size;
+    }
+  /* Update the scores.  */
+  *fprs = fpr_base;
+}
+
+/* Darwin64 special rules.
+   Break out a struct into params and float registers.  */
+static void
+darwin64_pass_struct_by_value (ffi_type *s, char *src, unsigned size,
+			       unsigned *nfpr, double **fprs, unsigned long **arg)
+{
+  unsigned long *next_arg = *arg;
+  char *dest_cpy = (char *)next_arg;
+
+  FFI_ASSERT (s->type == FFI_TYPE_STRUCT)
+
+  if (!size)
+    return;
+
+  /* First... special cases.  */
+  if (size < 3
+      || (size == 4 
+	  && s->elements[0] 
+	  && s->elements[0]->type != FFI_TYPE_FLOAT))
+    {
+      /* Must be at least one GPR, padding is unspecified in value, 
+	 let's make it zero.  */
+      *next_arg = 0UL; 
+      dest_cpy += 8 - size;
+      memcpy ((char *) dest_cpy, src, size);
+      next_arg++;
+    }
+  else if (size == 16)
+    {
+      memcpy ((char *) dest_cpy, src, size);
+      next_arg += 2;
+    }
+  else
+    {
+      /* now the general case, we consider embedded floats.  */
+      memcpy ((char *) dest_cpy, src, size);
+      darwin64_pass_struct_floats (s, src, nfpr, fprs);
+      next_arg += (size+7)/8;
+    }
+    
+  *arg = next_arg;
+}
+
+double *
+darwin64_struct_floats_to_mem (ffi_type *s, char *dest, double *fprs, unsigned *nf)
+{
+  int i;
+  unsigned struct_offset = 0;
+
+  /* We don't assume anything about the alignment of the source.  */
+  for (i = 0; s->elements[i] != NULL; i++)
+    {
+      char *item_base;
+      ffi_type *p = s->elements[i];
+      /* Find the start of this item (0 for the first one).  */
+      if (i > 0)
+        struct_offset = ALIGN(struct_offset, p->alignment);
+      item_base = dest + struct_offset;
+
+      switch (p->type)
+	{
+	  case FFI_TYPE_STRUCT:
+	    fprs = darwin64_struct_floats_to_mem (p, item_base, fprs, nf);
+	    break;
+	  case FFI_TYPE_LONGDOUBLE:
+	    if (*nf < NUM_FPR_ARG_REGISTERS)
+	      {
+		*(double *)item_base = *fprs++ ;
+		(*nf) += 1;
+	      }
+	    item_base += 8;
+	  /* FALL THROUGH */
+	  case FFI_TYPE_DOUBLE:
+	    if (*nf < NUM_FPR_ARG_REGISTERS)
+	      {
+		*(double *)item_base = *fprs++ ;
+		(*nf) += 1;
+	      }
+	    break;
+	  case FFI_TYPE_FLOAT:
+	    if (*nf < NUM_FPR_ARG_REGISTERS)
+	      {
+		*(float *)item_base = (float) *fprs++ ;
+		(*nf) += 1;
+	      }
+	    break;
+	  default:
+	    break;    
+	}
+      /* now count the size of what we just used.  */
+      struct_offset += p->size;
+    }
+  return fprs;
+}
+
+#endif
+
+/* Adjust the size of S to be correct for Darwin.
+   On Darwin m32, the first field of a structure has natural alignment.  
+   On Darwin m64, all fields have natural alignment.  */
+
+static void
+darwin_adjust_aggregate_sizes (ffi_type *s)
+{
+  int i;
+
+  if (s->type != FFI_TYPE_STRUCT)
+    return;
+
+  s->size = 0;
+  for (i = 0; s->elements[i] != NULL; i++)
+    {
+      ffi_type *p;
+      int align;
+      
+      p = s->elements[i];
+      if (p->type == FFI_TYPE_STRUCT)
+	darwin_adjust_aggregate_sizes (p);
+#if defined(POWERPC_DARWIN64)
+      /* Natural alignment for all items.  */
+      align = p->alignment;
+#else
+      /* Natrual alignment for the first item... */
+      if (i == 0)
+	align = p->alignment;
+      else if (p->alignment == 16 || p->alignment < 4)
+	/* .. subsequent items with vector or align < 4 have natural align.  */
+	align = p->alignment;
+      else
+	/* .. or align is 4.  */
+	align = 4;
+#endif
+      /* Pad, if necessary, before adding the current item.  */
+      s->size = ALIGN(s->size, align) + p->size;
+    }
+  
+  s->size = ALIGN(s->size, s->alignment);
+  
+  /* This should not be necessary on m64, but harmless.  */
+  if (s->elements[0]->type == FFI_TYPE_UINT64
+      || s->elements[0]->type == FFI_TYPE_SINT64
+      || s->elements[0]->type == FFI_TYPE_DOUBLE
+      || s->elements[0]->alignment == 8)
+    s->alignment = s->alignment > 8 ? s->alignment : 8;
+  /* Do not add additional tail padding.  */
+}
+
+/* Adjust the size of S to be correct for AIX.
+   Word-align double unless it is the first member of a structure.  */
+
+static void
+aix_adjust_aggregate_sizes (ffi_type *s)
+{
+  int i;
+
+  if (s->type != FFI_TYPE_STRUCT)
+    return;
+
+  s->size = 0;
+  for (i = 0; s->elements[i] != NULL; i++)
+    {
+      ffi_type *p;
+      int align;
+      
+      p = s->elements[i];
+      aix_adjust_aggregate_sizes (p);
+      align = p->alignment;
+      if (i != 0 && p->type == FFI_TYPE_DOUBLE)
+	align = 4;
+      s->size = ALIGN(s->size, align) + p->size;
+    }
+  
+  s->size = ALIGN(s->size, s->alignment);
+  
+  if (s->elements[0]->type == FFI_TYPE_UINT64
+      || s->elements[0]->type == FFI_TYPE_SINT64
+      || s->elements[0]->type == FFI_TYPE_DOUBLE
+      || s->elements[0]->alignment == 8)
+    s->alignment = s->alignment > 8 ? s->alignment : 8;
+  /* Do not add additional tail padding.  */
+}
+
+/* Perform machine dependent cif processing.  */
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+  /* All this is for the DARWIN ABI.  */
+  unsigned i;
+  ffi_type **ptr;
+  unsigned bytes;
+  unsigned fparg_count = 0, intarg_count = 0;
+  unsigned flags = 0;
+  unsigned size_al = 0;
+
+  /* All the machine-independent calculation of cif->bytes will be wrong.
+     All the calculation of structure sizes will also be wrong.
+     Redo the calculation for DARWIN.  */
+
+  if (cif->abi == FFI_DARWIN)
+    {
+      darwin_adjust_aggregate_sizes (cif->rtype);
+      for (i = 0; i < cif->nargs; i++)
+	darwin_adjust_aggregate_sizes (cif->arg_types[i]);
+    }
+
+  if (cif->abi == FFI_AIX)
+    {
+      aix_adjust_aggregate_sizes (cif->rtype);
+      for (i = 0; i < cif->nargs; i++)
+	aix_adjust_aggregate_sizes (cif->arg_types[i]);
+    }
+
+  /* Space for the frame pointer, callee's LR, CR, etc, and for
+     the asm's temp regs.  */
+
+  bytes = (LINKAGE_AREA_GPRS + ASM_NEEDS_REGISTERS) * sizeof(unsigned long);
+
+  /* Return value handling.  
+    The rules m32 are as follows:
+     - 32-bit (or less) integer values are returned in gpr3;
+     - structures of size <= 4 bytes also returned in gpr3;
+     - 64-bit integer values [??? and structures between 5 and 8 bytes] are
+       returned in gpr3 and gpr4;
+     - Single/double FP values are returned in fpr1;
+     - Long double FP (if not equivalent to double) values are returned in
+       fpr1 and fpr2;
+     m64:
+     - 64-bit or smaller integral values are returned in GPR3
+     - Single/double FP values are returned in fpr1;
+     - Long double FP values are returned in fpr1 and fpr2;
+     m64 Structures:
+     - If the structure could be accommodated in registers were it to be the
+       first argument to a routine, then it is returned in those registers.
+     m32/m64 structures otherwise:
+     - Larger structures values are allocated space and a pointer is passed
+       as the first argument.  */
+  switch (cif->rtype->type)
+    {
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+    case FFI_TYPE_LONGDOUBLE:
+      flags |= FLAG_RETURNS_128BITS;
+      flags |= FLAG_RETURNS_FP;
+      break;
+#endif
+
+    case FFI_TYPE_DOUBLE:
+      flags |= FLAG_RETURNS_64BITS;
+      /* Fall through.  */
+    case FFI_TYPE_FLOAT:
+      flags |= FLAG_RETURNS_FP;
+      break;
+
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+#ifdef POWERPC64
+    case FFI_TYPE_POINTER:
+#endif
+      flags |= FLAG_RETURNS_64BITS;
+      break;
+
+    case FFI_TYPE_STRUCT:
+#if defined(POWERPC_DARWIN64)
+      {
+	/* Can we fit the struct into regs?  */
+	if (darwin64_struct_ret_by_value_p (cif->rtype))
+	  {
+	    unsigned nfpr = 0;
+	    flags |= FLAG_RETURNS_STRUCT;
+	    if (cif->rtype->size != 16)
+	      darwin64_scan_struct_for_floats (cif->rtype, &nfpr) ;
+	    else
+	      flags |= FLAG_RETURNS_128BITS;
+	    /* Will be 0 for 16byte struct.  */
+	    if (nfpr)
+	      flags |= FLAG_RETURNS_FP;
+	  }
+	else /* By ref. */
+	  {
+	    flags |= FLAG_RETVAL_REFERENCE;
+	    flags |= FLAG_RETURNS_NOTHING;
+	    intarg_count++;
+	  }
+      }
+#elif defined(DARWIN_PPC)
+      if (cif->rtype->size <= 4)
+	flags |= FLAG_RETURNS_STRUCT;
+      else /* else by reference.  */
+	{
+	  flags |= FLAG_RETVAL_REFERENCE;
+	  flags |= FLAG_RETURNS_NOTHING;
+	  intarg_count++;
+	}
+#else /* assume we pass by ref.  */
+      flags |= FLAG_RETVAL_REFERENCE;
+      flags |= FLAG_RETURNS_NOTHING;
+      intarg_count++;
+#endif
+      break;
+    case FFI_TYPE_VOID:
+      flags |= FLAG_RETURNS_NOTHING;
+      break;
+
+    default:
+      /* Returns 32-bit integer, or similar.  Nothing to do here.  */
+      break;
+    }
+
+  /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
+     first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
+     goes on the stack.  
+     ??? Structures are passed as a pointer to a copy of the structure. 
+     Stuff on the stack needs to keep proper alignment.  
+     For m64 the count is effectively of half-GPRs.  */
+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+    {
+      unsigned align_words;
+      switch ((*ptr)->type)
+	{
+	case FFI_TYPE_FLOAT:
+	case FFI_TYPE_DOUBLE:
+	  fparg_count++;
+#if !defined(POWERPC_DARWIN64)
+	  /* If this FP arg is going on the stack, it must be
+	     8-byte-aligned.  */
+	  if (fparg_count > NUM_FPR_ARG_REGISTERS
+	      && (intarg_count & 0x01) != 0)
+	    intarg_count++;
+#endif
+	  break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+	  fparg_count += 2;
+	  /* If this FP arg is going on the stack, it must be
+	     16-byte-aligned.  */
+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+#if defined (POWERPC64)
+	    intarg_count = ALIGN(intarg_count, 2);
+#else
+	    intarg_count = ALIGN(intarg_count, 4);
+#endif
+	  break;
+#endif
+
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_SINT64:
+#if defined(POWERPC64)
+	  intarg_count++;
+#else
+	  /* 'long long' arguments are passed as two words, but
+	     either both words must fit in registers or both go
+	     on the stack.  If they go on the stack, they must
+	     be 8-byte-aligned.  */
+	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1
+	      || (intarg_count >= NUM_GPR_ARG_REGISTERS 
+	          && (intarg_count & 0x01) != 0))
+	    intarg_count++;
+	  intarg_count += 2;
+#endif
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  size_al = (*ptr)->size;
+#if defined(POWERPC_DARWIN64)
+	  align_words = (*ptr)->alignment >> 3;
+	  if (align_words)
+	    intarg_count = ALIGN(intarg_count, align_words);
+	  /* Base size of the struct.  */
+	  intarg_count += (size_al + 7) / 8;
+	  /* If 16 bytes then don't worry about floats.  */
+	  if (size_al != 16)
+	    /* Scan through for floats to be placed in regs.  */
+	    darwin64_scan_struct_for_floats (*ptr, &fparg_count) ;
+#else
+	  align_words = (*ptr)->alignment >> 2;
+	  if (align_words)
+	    intarg_count = ALIGN(intarg_count, align_words);
+	  /* If the first member of the struct is a double, then align
+	     the struct to double-word. 
+	  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
+	    size_al = ALIGN((*ptr)->size, 8); */
+#  ifdef POWERPC64
+	  intarg_count += (size_al + 7) / 8;
+#  else
+	  intarg_count += (size_al + 3) / 4;
+#  endif
+#endif
+	  break;
+
+	default:
+	  /* Everything else is passed as a 4-byte word in a GPR, either
+	     the object itself or a pointer to it.  */
+	  intarg_count++;
+	  break;
+	}
+    }
+
+  if (fparg_count != 0)
+    flags |= FLAG_FP_ARGUMENTS;
+
+#if defined(POWERPC_DARWIN64)
+  /* Space to image the FPR registers, if needed - which includes when they might be
+     used in a struct return.  */
+  if (fparg_count != 0 
+      || ((flags & FLAG_RETURNS_STRUCT)
+	   && (flags & FLAG_RETURNS_FP)))
+    bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
+#else
+  /* Space for the FPR registers, if needed.  */
+  if (fparg_count != 0)
+    bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
+#endif
+
+  /* Stack space.  */
+#ifdef POWERPC64
+  if ((intarg_count + fparg_count) > NUM_GPR_ARG_REGISTERS)
+    bytes += (intarg_count + fparg_count) * sizeof(long);
+#else
+  if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
+    bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
+#endif
+  else
+    bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
+
+  /* The stack space allocated needs to be a multiple of 16 bytes.  */
+  bytes = ALIGN(bytes, 16) ;
+
+  cif->flags = flags;
+  cif->bytes = bytes;
+
+  return FFI_OK;
+}
+
+extern void ffi_call_AIX(extended_cif *, long, unsigned, unsigned *,
+			 void (*fn)(void), void (*fn2)(void));
+
+extern void ffi_call_DARWIN(extended_cif *, long, unsigned, unsigned *,
+			    void (*fn)(void), void (*fn2)(void), ffi_type*);
+
+void
+ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+
+  /* If the return value is a struct and we don't have a return
+     value address then we need to make one.  */
+
+  if ((rvalue == NULL) &&
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      ecif.rvalue = alloca (cif->rtype->size);
+    }
+  else
+    ecif.rvalue = rvalue;
+
+  switch (cif->abi)
+    {
+    case FFI_AIX:
+      ffi_call_AIX(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
+		   FFI_FN(ffi_prep_args));
+      break;
+    case FFI_DARWIN:
+      ffi_call_DARWIN(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
+		      FFI_FN(ffi_prep_args), cif->rtype);
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+static void flush_icache(char *);
+static void flush_range(char *, int);
+
+/* The layout of a function descriptor.  A C function pointer really
+   points to one of these.  */
+
+typedef struct aix_fd_struct {
+  void *code_pointer;
+  void *toc;
+} aix_fd;
+
+/* here I'd like to add the stack frame layout we use in darwin_closure.S
+   and aix_closure.S
+
+   m32/m64
+
+   The stack layout looks like this:
+
+   |   Additional params...			| |     Higher address
+   ~						~ ~
+   |   Parameters      (at least 8*4/8=32/64)	| | NUM_GPR_ARG_REGISTERS
+   |--------------------------------------------| |
+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |
+   |--------------------------------------------| |
+   |   Reserved                       2*4/8	| |
+   |--------------------------------------------| |
+   |   Space for callee's LR		4/8	| |
+   |--------------------------------------------| |
+   |   Saved CR [low word for m64]      4/8	| |
+   |--------------------------------------------| |
+   |   Current backchain pointer	4/8	|-/ Parent's frame.
+   |--------------------------------------------| <+ <<< on entry to ffi_closure_ASM
+   |   Result Bytes			16	| |
+   |--------------------------------------------| |
+   ~   padding to 16-byte alignment		~ ~
+   |--------------------------------------------| |
+   |   NUM_FPR_ARG_REGISTERS slots		| |
+   |   here fp13 .. fp1		       13*8	| |
+   |--------------------------------------------| |
+   |   R3..R10			  8*4/8=32/64	| | NUM_GPR_ARG_REGISTERS
+   |--------------------------------------------| |
+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |
+   |--------------------------------------------| |	stack	|
+   |   Reserved [compiler,binder]     2*4/8	| |	grows	|
+   |--------------------------------------------| |	down	V
+   |   Space for callee's LR		4/8	| |
+   |--------------------------------------------| |	lower addresses
+   |   Saved CR [low word for m64]      4/8	| |
+   |--------------------------------------------| |     stack pointer here
+   |   Current backchain pointer	4/8	|-/	during
+   |--------------------------------------------|   <<<	ffi_closure_ASM.
+
+*/
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif*, void*, void**, void*),
+		      void *user_data,
+		      void *codeloc)
+{
+  unsigned int *tramp;
+  struct ffi_aix_trampoline_struct *tramp_aix;
+  aix_fd *fd;
+
+  switch (cif->abi)
+    {
+      case FFI_DARWIN:
+
+	FFI_ASSERT (cif->abi == FFI_DARWIN);
+
+	tramp = (unsigned int *) &closure->tramp[0];
+#if defined(POWERPC_DARWIN64)
+	tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
+	tramp[1] = 0x429f0015;  /*   bcl-    20,4*cr7+so,  +0x18 (L1)  */
+	/* We put the addresses here.  */
+	tramp[6] = 0x7d6802a6;  /*L1:   mflr    r11  */
+	tramp[7] = 0xe98b0000;  /*   ld     r12,0(r11) function address  */
+	tramp[8] = 0x7c0803a6;  /*   mtlr    r0   */
+	tramp[9] = 0x7d8903a6;  /*   mtctr   r12  */
+	tramp[10] = 0xe96b0008;  /*   lwz     r11,8(r11) static chain  */
+	tramp[11] = 0x4e800420;  /*   bctr  */
+
+	*((unsigned long *)&tramp[2]) = (unsigned long) ffi_closure_ASM; /* function  */
+	*((unsigned long *)&tramp[4]) = (unsigned long) codeloc; /* context  */
+#else
+	tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
+	tramp[1] = 0x429f000d;  /*   bcl-    20,4*cr7+so,0x10  */
+	tramp[4] = 0x7d6802a6;  /*   mflr    r11  */
+	tramp[5] = 0x818b0000;  /*   lwz     r12,0(r11) function address  */
+	tramp[6] = 0x7c0803a6;  /*   mtlr    r0   */
+	tramp[7] = 0x7d8903a6;  /*   mtctr   r12  */
+	tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11) static chain  */
+	tramp[9] = 0x4e800420;  /*   bctr  */
+	tramp[2] = (unsigned long) ffi_closure_ASM; /* function  */
+	tramp[3] = (unsigned long) codeloc; /* context  */
+#endif
+	closure->cif = cif;
+	closure->fun = fun;
+	closure->user_data = user_data;
+
+	/* Flush the icache. Only necessary on Darwin.  */
+	flush_range(codeloc, FFI_TRAMPOLINE_SIZE);
+
+	break;
+
+    case FFI_AIX:
+
+      tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp);
+      fd = (aix_fd *)(void *)ffi_closure_ASM;
+
+      FFI_ASSERT (cif->abi == FFI_AIX);
+
+      tramp_aix->code_pointer = fd->code_pointer;
+      tramp_aix->toc = fd->toc;
+      tramp_aix->static_chain = codeloc;
+      closure->cif = cif;
+      closure->fun = fun;
+      closure->user_data = user_data;
+
+    default:
+
+      FFI_ASSERT(0);
+      break;
+    }
+  return FFI_OK;
+}
+
+static void
+flush_icache(char *addr)
+{
+#ifndef _AIX
+  __asm__ volatile (
+		"dcbf 0,%0\n"
+		"\tsync\n"
+		"\ticbi 0,%0\n"
+		"\tsync\n"
+		"\tisync"
+		: : "r"(addr) : "memory");
+#endif
+}
+
+static void
+flush_range(char * addr1, int size)
+{
+#define MIN_LINE_SIZE 32
+  int i;
+  for (i = 0; i < size; i += MIN_LINE_SIZE)
+    flush_icache(addr1+i);
+  flush_icache(addr1+size-1);
+}
+
+typedef union
+{
+  float f;
+  double d;
+} ffi_dblfl;
+
+ffi_type *
+ffi_closure_helper_DARWIN (ffi_closure *, void *,
+			   unsigned long *, ffi_dblfl *);
+
+/* Basically the trampoline invokes ffi_closure_ASM, and on
+   entry, r11 holds the address of the closure.
+   After storing the registers that could possibly contain
+   parameters to be passed into the stack frame and setting
+   up space for a return value, ffi_closure_ASM invokes the
+   following helper function to do most of the work.  */
+
+ffi_type *
+ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
+			   unsigned long *pgr, ffi_dblfl *pfr)
+{
+  /* rvalue is the pointer to space for return value in closure assembly
+     pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM
+     pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM.  */
+
+  typedef double ldbits[2];
+
+  union ldu
+  {
+    ldbits lb;
+    long double ld;
+  };
+
+  void **          avalue;
+  ffi_type **      arg_types;
+  long             i, avn;
+  ffi_cif *        cif;
+  ffi_dblfl *      end_pfr = pfr + NUM_FPR_ARG_REGISTERS;
+  unsigned         size_al;
+#if defined(POWERPC_DARWIN64)
+  unsigned 	   fpsused = 0;
+#endif
+
+  cif = closure->cif;
+  avalue = alloca (cif->nargs * sizeof(void *));
+
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+#if defined(POWERPC_DARWIN64)
+      if (!darwin64_struct_ret_by_value_p (cif->rtype))
+	{
+    	  /* Won't fit into the regs - return by ref.  */
+	  rvalue = (void *) *pgr;
+	  pgr++;
+	}
+#elif defined(DARWIN_PPC)
+      if (cif->rtype->size > 4)
+	{
+	  rvalue = (void *) *pgr;
+	  pgr++;
+	}
+#else /* assume we return by ref.  */
+      rvalue = (void *) *pgr;
+      pgr++;
+#endif
+    }
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  while (i < avn)
+    {
+      switch (arg_types[i]->type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+#if  defined(POWERPC64)
+	  avalue[i] = (char *) pgr + 7;
+#else
+	  avalue[i] = (char *) pgr + 3;
+#endif
+	  pgr++;
+	  break;
+
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+#if  defined(POWERPC64)
+	  avalue[i] = (char *) pgr + 6;
+#else
+	  avalue[i] = (char *) pgr + 2;
+#endif
+	  pgr++;
+	  break;
+
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+#if  defined(POWERPC64)
+	  avalue[i] = (char *) pgr + 4;
+#else
+	case FFI_TYPE_POINTER:
+	  avalue[i] = pgr;
+#endif
+	  pgr++;
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  size_al = arg_types[i]->size;
+#if defined(POWERPC_DARWIN64)
+	  pgr = (unsigned long *)ALIGN((char *)pgr, arg_types[i]->alignment);
+	  if (size_al < 3 || size_al == 4)
+	    {
+	      avalue[i] = ((char *)pgr)+8-size_al;
+	      if (arg_types[i]->elements[0]->type == FFI_TYPE_FLOAT
+		  && fpsused < NUM_FPR_ARG_REGISTERS)
+		{
+		  *(float *)pgr = (float) *(double *)pfr;
+		  pfr++;
+		  fpsused++;
+		}
+	    }
+	  else 
+	    {
+	      if (size_al != 16)
+		pfr = (ffi_dblfl *) 
+		    darwin64_struct_floats_to_mem (arg_types[i], (char *)pgr,
+						   (double *)pfr, &fpsused);
+	      avalue[i] = pgr;
+	    }
+	  pgr += (size_al + 7) / 8;
+#else
+	  /* If the first member of the struct is a double, then align
+	     the struct to double-word.  */
+	  if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
+	    size_al = ALIGN(arg_types[i]->size, 8);
+#  if defined(POWERPC64)
+	  FFI_ASSERT (cif->abi != FFI_DARWIN)
+	  avalue[i] = pgr;
+	  pgr += (size_al + 7) / 8;
+#  else
+	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
+	     SI 4 bytes) are aligned as if they were those modes.  */
+	  if (size_al < 3 && cif->abi == FFI_DARWIN)
+	    avalue[i] = (char*) pgr + 4 - size_al;
+	  else
+	    avalue[i] = pgr;
+	  pgr += (size_al + 3) / 4;
+#  endif
+#endif
+	  break;
+
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+#if  defined(POWERPC64)
+	case FFI_TYPE_POINTER:
+	  avalue[i] = pgr;
+	  pgr++;
+	  break;
+#else
+	  /* Long long ints are passed in two gpr's.  */
+	  avalue[i] = pgr;
+	  pgr += 2;
+	  break;
+#endif
+
+	case FFI_TYPE_FLOAT:
+	  /* A float value consumes a GPR.
+	     There are 13 64bit floating point registers.  */
+	  if (pfr < end_pfr)
+	    {
+	      double temp = pfr->d;
+	      pfr->f = (float) temp;
+	      avalue[i] = pfr;
+	      pfr++;
+	    }
+	  else
+	    {
+	      avalue[i] = pgr;
+	    }
+	  pgr++;
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  /* A double value consumes two GPRs.
+	     There are 13 64bit floating point registers.  */
+	  if (pfr < end_pfr)
+	    {
+	      avalue[i] = pfr;
+	      pfr++;
+	    }
+	  else
+	    {
+	      avalue[i] = pgr;
+	    }
+#ifdef POWERPC64
+	  pgr++;
+#else
+	  pgr += 2;
+#endif
+	  break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+
+	case FFI_TYPE_LONGDOUBLE:
+#ifdef POWERPC64
+	  if (pfr + 1 < end_pfr)
+	    {
+	      avalue[i] = pfr;
+	      pfr += 2;
+	    }
+	  else
+	    {
+	      if (pfr < end_pfr)
+		{
+		  *pgr = *(unsigned long *) pfr;
+		  pfr++;
+		}
+	      avalue[i] = pgr;
+	    }
+	  pgr += 2;
+#else  /* POWERPC64 */
+	  /* A long double value consumes four GPRs and two FPRs.
+	     There are 13 64bit floating point registers.  */
+	  if (pfr + 1 < end_pfr)
+	    {
+	      avalue[i] = pfr;
+	      pfr += 2;
+	    }
+	  /* Here we have the situation where one part of the long double
+	     is stored in fpr13 and the other part is already on the stack.
+	     We use a union to pass the long double to avalue[i].  */
+	  else if (pfr + 1 == end_pfr)
+	    {
+	      union ldu temp_ld;
+	      memcpy (&temp_ld.lb[0], pfr, sizeof(ldbits));
+	      memcpy (&temp_ld.lb[1], pgr + 2, sizeof(ldbits));
+	      avalue[i] = &temp_ld.ld;
+	      pfr++;
+	    }
+	  else
+	    {
+	      avalue[i] = pgr;
+	    }
+	  pgr += 4;
+#endif  /* POWERPC64 */
+	  break;
+#endif
+	default:
+	  FFI_ASSERT(0);
+	}
+      i++;
+    }
+
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_ASM to perform return type promotions.  */
+  return cif->rtype;
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/ffitarget.h
new file mode 100755
index 0000000..d17f731
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/ffitarget.h
@@ -0,0 +1,139 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc
+   Target configuration macros for PowerPC.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#if defined (POWERPC) && defined (__powerpc64__)	/* linux64 */
+#ifndef POWERPC64
+#define POWERPC64
+#endif
+#elif defined (POWERPC_DARWIN) && defined (__ppc64__)	/* Darwin64 */
+#ifndef POWERPC64
+#define POWERPC64
+#endif
+#ifndef POWERPC_DARWIN64
+#define POWERPC_DARWIN64
+#endif
+#elif defined (POWERPC_AIX) && defined (__64BIT__)	/* AIX64 */
+#ifndef POWERPC64
+#define POWERPC64
+#endif
+#endif
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+
+#ifdef POWERPC
+  FFI_SYSV,
+  FFI_GCC_SYSV,
+  FFI_LINUX64,
+  FFI_LINUX,
+  FFI_LINUX_SOFT_FLOAT,
+# ifdef POWERPC64
+  FFI_DEFAULT_ABI = FFI_LINUX64,
+# else
+#  if (!defined(__NO_FPRS__) && (__LDBL_MANT_DIG__ == 106))
+  FFI_DEFAULT_ABI = FFI_LINUX,
+#  else
+#   ifdef __NO_FPRS__
+  FFI_DEFAULT_ABI = FFI_LINUX_SOFT_FLOAT,
+#   else
+  FFI_DEFAULT_ABI = FFI_GCC_SYSV,
+#   endif
+#  endif
+# endif
+#endif
+
+#ifdef POWERPC_AIX
+  FFI_AIX,
+  FFI_DARWIN,
+  FFI_DEFAULT_ABI = FFI_AIX,
+#endif
+
+#ifdef POWERPC_DARWIN
+  FFI_AIX,
+  FFI_DARWIN,
+  FFI_DEFAULT_ABI = FFI_DARWIN,
+#endif
+
+#ifdef POWERPC_FREEBSD
+  FFI_SYSV,
+  FFI_GCC_SYSV,
+  FFI_LINUX64,
+  FFI_LINUX,
+  FFI_LINUX_SOFT_FLOAT,
+  FFI_DEFAULT_ABI = FFI_SYSV,
+#endif
+
+  FFI_LAST_ABI
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_NATIVE_RAW_API 0
+
+/* For additional types like the below, take care about the order in
+   ppc_closures.S. They must follow after the FFI_TYPE_LAST.  */
+
+/* Needed for soft-float long-double-128 support.  */
+#define FFI_TYPE_UINT128 (FFI_TYPE_LAST + 1)
+
+/* Needed for FFI_SYSV small structure returns.
+   We use two flag bits, (FLAG_SYSV_SMST_R3, FLAG_SYSV_SMST_R4) which are
+   defined in ffi.c, to determine the exact return type and its size.  */
+#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 2)
+
+#if defined(POWERPC64) || defined(POWERPC_AIX)
+#  if defined(POWERPC_DARWIN64)
+#    define FFI_TRAMPOLINE_SIZE 48
+#  else
+#    define FFI_TRAMPOLINE_SIZE 24
+#  endif
+#else /* POWERPC || POWERPC_AIX */
+#  define FFI_TRAMPOLINE_SIZE 40
+#endif
+
+#ifndef LIBFFI_ASM
+#if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
+struct ffi_aix_trampoline_struct {
+    void * code_pointer;	/* Pointer to ffi_closure_ASM */
+    void * toc;			/* TOC */
+    void * static_chain;	/* Pointer to closure */
+};
+#endif
+#endif
+
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/linux64.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/linux64.S
new file mode 100755
index 0000000..57b56cb
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/linux64.S
@@ -0,0 +1,187 @@
+/* -----------------------------------------------------------------------
+   sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub at redhat.com>
+	    Copyright (c) 2008 Red Hat, Inc.
+
+   PowerPC64 Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+#ifdef __powerpc64__
+	.hidden	ffi_call_LINUX64, .ffi_call_LINUX64
+	.globl	ffi_call_LINUX64, .ffi_call_LINUX64
+	.section	".opd","aw"
+	.align	3
+ffi_call_LINUX64:
+	.quad	.ffi_call_LINUX64,.TOC. at tocbase,0
+	.size	ffi_call_LINUX64,24
+	.type	.ffi_call_LINUX64, at function
+	.text
+.ffi_call_LINUX64:
+.LFB1:
+	mflr	%r0
+	std	%r28, -32(%r1)
+	std	%r29, -24(%r1)
+	std	%r30, -16(%r1)
+	std	%r31, -8(%r1)
+	std	%r0, 16(%r1)
+
+	mr	%r28, %r1	/* our AP.  */
+.LCFI0:
+	stdux	%r1, %r1, %r4
+	mr	%r31, %r5	/* flags, */
+	mr	%r30, %r6	/* rvalue, */
+	mr	%r29, %r7	/* function address.  */
+	std	%r2, 40(%r1)
+
+	/* Call ffi_prep_args64.  */
+	mr	%r4, %r1
+	bl	.ffi_prep_args64
+
+	ld	%r0, 0(%r29)
+	ld	%r2, 8(%r29)
+	ld	%r11, 16(%r29)
+
+	/* Now do the call.  */
+	/* Set up cr1 with bits 4-7 of the flags.  */
+	mtcrf	0x40, %r31
+
+	/* Get the address to call into CTR.  */
+	mtctr	%r0
+	/* Load all those argument registers.  */
+	ld	%r3, -32-(8*8)(%r28)
+	ld	%r4, -32-(7*8)(%r28)
+	ld	%r5, -32-(6*8)(%r28)
+	ld	%r6, -32-(5*8)(%r28)
+	bf-	5, 1f
+	ld	%r7, -32-(4*8)(%r28)
+	ld	%r8, -32-(3*8)(%r28)
+	ld	%r9, -32-(2*8)(%r28)
+	ld	%r10, -32-(1*8)(%r28)
+1:
+
+	/* Load all the FP registers.  */
+	bf-	6, 2f
+	lfd	%f1, -32-(21*8)(%r28)
+	lfd	%f2, -32-(20*8)(%r28)
+	lfd	%f3, -32-(19*8)(%r28)
+	lfd	%f4, -32-(18*8)(%r28)
+	lfd	%f5, -32-(17*8)(%r28)
+	lfd	%f6, -32-(16*8)(%r28)
+	lfd	%f7, -32-(15*8)(%r28)
+	lfd	%f8, -32-(14*8)(%r28)
+	lfd	%f9, -32-(13*8)(%r28)
+	lfd	%f10, -32-(12*8)(%r28)
+	lfd	%f11, -32-(11*8)(%r28)
+	lfd	%f12, -32-(10*8)(%r28)
+	lfd	%f13, -32-(9*8)(%r28)
+2:
+
+	/* Make the call.  */
+	bctrl
+
+	/* This must follow the call immediately, the unwinder
+	   uses this to find out if r2 has been saved or not.  */
+	ld	%r2, 40(%r1)
+
+	/* Now, deal with the return value.  */
+	mtcrf	0x01, %r31
+	bt-	30, .Ldone_return_value
+	bt-	29, .Lfp_return_value
+	std	%r3, 0(%r30)
+	/* Fall through...  */
+
+.Ldone_return_value:
+	/* Restore the registers we used and return.  */
+	mr	%r1, %r28
+	ld	%r0, 16(%r28)
+	ld	%r28, -32(%r1)
+	mtlr	%r0
+	ld	%r29, -24(%r1)
+	ld	%r30, -16(%r1)
+	ld	%r31, -8(%r1)
+	blr
+
+.Lfp_return_value:
+	bf	28, .Lfloat_return_value
+	stfd	%f1, 0(%r30)
+	mtcrf	0x02, %r31 /* cr6  */
+	bf	27, .Ldone_return_value
+	stfd	%f2, 8(%r30)
+	b	.Ldone_return_value
+.Lfloat_return_value:
+	stfs	%f1, 0(%r30)
+	b	.Ldone_return_value
+.LFE1:
+	.long	0
+	.byte	0,12,0,1,128,4,0,0
+	.size	.ffi_call_LINUX64,.-.ffi_call_LINUX64
+
+	.section	.eh_frame,EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.4byte	.LECIE1-.LSCIE1	 # Length of Common Information Entry
+.LSCIE1:
+	.4byte	0x0	 # CIE Identifier Tag
+	.byte	0x1	 # CIE Version
+	.ascii "zR\0"	 # CIE Augmentation
+	.uleb128 0x1	 # CIE Code Alignment Factor
+	.sleb128 -8	 # CIE Data Alignment Factor
+	.byte	0x41	 # CIE RA Column
+	.uleb128 0x1	 # Augmentation size
+	.byte	0x14	 # FDE Encoding (pcrel udata8)
+	.byte	0xc	 # DW_CFA_def_cfa
+	.uleb128 0x1
+	.uleb128 0x0
+	.align 3
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	 # FDE Length
+.LASFDE1:
+	.4byte	.LASFDE1-.Lframe1	 # FDE CIE offset
+	.8byte	.LFB1-.	 # FDE initial location
+	.8byte	.LFE1-.LFB1	 # FDE address range
+	.uleb128 0x0	 # Augmentation size
+	.byte	0x2	 # DW_CFA_advance_loc1
+	.byte	.LCFI0-.LFB1
+	.byte	0xd	 # DW_CFA_def_cfa_register
+	.uleb128 0x1c
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x41
+	.sleb128 -2
+	.byte	0x9f	 # DW_CFA_offset, column 0x1f
+	.uleb128 0x1
+	.byte	0x9e	 # DW_CFA_offset, column 0x1e
+	.uleb128 0x2
+	.byte	0x9d	 # DW_CFA_offset, column 0x1d
+	.uleb128 0x3
+	.byte	0x9c	 # DW_CFA_offset, column 0x1c
+	.uleb128 0x4
+	.align 3
+.LEFDE1:
+#endif
+
+#if defined __ELF__ && defined __linux__
+	.section	.note.GNU-stack,"", at progbits
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/linux64_closure.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/linux64_closure.S
new file mode 100755
index 0000000..f7aa2c9
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/linux64_closure.S
@@ -0,0 +1,236 @@
+/* -----------------------------------------------------------------------
+   sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub at redhat.com>
+	    Copyright (c) 2008 Red Hat, Inc.
+
+   PowerPC64 Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+	.file	"linux64_closure.S"
+
+#ifdef __powerpc64__
+	FFI_HIDDEN (ffi_closure_LINUX64)
+	FFI_HIDDEN (.ffi_closure_LINUX64)
+	.globl  ffi_closure_LINUX64, .ffi_closure_LINUX64
+	.section        ".opd","aw"
+	.align  3
+ffi_closure_LINUX64:
+	.quad   .ffi_closure_LINUX64,.TOC. at tocbase,0
+	.size   ffi_closure_LINUX64,24
+	.type   .ffi_closure_LINUX64, at function
+	.text
+.ffi_closure_LINUX64:
+.LFB1:
+	# save general regs into parm save area
+	std	%r3, 48(%r1)
+	std	%r4, 56(%r1)
+	std	%r5, 64(%r1)
+	std	%r6, 72(%r1)
+	mflr	%r0
+
+	std	%r7, 80(%r1)
+	std	%r8, 88(%r1)
+	std	%r9, 96(%r1)
+	std	%r10, 104(%r1)
+	std	%r0, 16(%r1)
+
+	# mandatory 48 bytes special reg save area + 64 bytes parm save area
+	# + 16 bytes retval area + 13*8 bytes fpr save area + round to 16
+	stdu	%r1, -240(%r1)
+.LCFI0:
+
+	# next save fpr 1 to fpr 13
+	stfd  %f1, 128+(0*8)(%r1)
+	stfd  %f2, 128+(1*8)(%r1)
+	stfd  %f3, 128+(2*8)(%r1)
+	stfd  %f4, 128+(3*8)(%r1)
+	stfd  %f5, 128+(4*8)(%r1)
+	stfd  %f6, 128+(5*8)(%r1)
+	stfd  %f7, 128+(6*8)(%r1)
+	stfd  %f8, 128+(7*8)(%r1)
+	stfd  %f9, 128+(8*8)(%r1)
+	stfd  %f10, 128+(9*8)(%r1)
+	stfd  %f11, 128+(10*8)(%r1)
+	stfd  %f12, 128+(11*8)(%r1)
+	stfd  %f13, 128+(12*8)(%r1)
+
+	# set up registers for the routine that actually does the work
+	# get the context pointer from the trampoline
+	mr %r3, %r11
+
+	# now load up the pointer to the result storage
+	addi %r4, %r1, 112
+
+	# now load up the pointer to the parameter save area
+	# in the previous frame
+	addi %r5, %r1, 240 + 48
+
+	# now load up the pointer to the saved fpr registers */
+	addi %r6, %r1, 128
+
+	# make the call
+	bl .ffi_closure_helper_LINUX64
+.Lret:
+
+	# now r3 contains the return type
+	# so use it to look up in a table
+	# so we know how to deal with each type
+
+	# look up the proper starting point in table
+	# by using return type as offset
+	mflr %r4		# move address of .Lret to r4
+	sldi %r3, %r3, 4	# now multiply return type by 16
+	addi %r4, %r4, .Lret_type0 - .Lret
+	ld %r0, 240+16(%r1)
+	add %r3, %r3, %r4	# add contents of table to table address
+	mtctr %r3
+	bctr			# jump to it
+
+# Each of the ret_typeX code fragments has to be exactly 16 bytes long
+# (4 instructions). For cache effectiveness we align to a 16 byte boundary
+# first.
+	.align 4
+
+.Lret_type0:
+# case FFI_TYPE_VOID
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+	nop
+# case FFI_TYPE_INT
+	lwa %r3, 112+4(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_FLOAT
+	lfs %f1, 112+0(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_DOUBLE
+	lfd %f1, 112+0(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_LONGDOUBLE
+	lfd %f1, 112+0(%r1)
+	mtlr %r0
+	lfd %f2, 112+8(%r1)
+	b .Lfinish
+# case FFI_TYPE_UINT8
+	lbz %r3, 112+7(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_SINT8
+	lbz %r3, 112+7(%r1)
+	extsb %r3,%r3
+	mtlr %r0
+	b .Lfinish
+# case FFI_TYPE_UINT16
+	lhz %r3, 112+6(%r1)
+	mtlr %r0
+.Lfinish:
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_SINT16
+	lha %r3, 112+6(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_UINT32
+	lwz %r3, 112+4(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_SINT32
+	lwa %r3, 112+4(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_UINT64
+	ld %r3, 112+0(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_SINT64
+	ld %r3, 112+0(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# case FFI_TYPE_STRUCT
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+	nop
+# case FFI_TYPE_POINTER
+	ld %r3, 112+0(%r1)
+	mtlr %r0
+	addi %r1, %r1, 240
+	blr
+# esac
+.LFE1:
+	.long	0
+	.byte	0,12,0,1,128,0,0,0
+	.size	.ffi_closure_LINUX64,.-.ffi_closure_LINUX64
+
+	.section	.eh_frame,EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.4byte	.LECIE1-.LSCIE1	 # Length of Common Information Entry
+.LSCIE1:
+	.4byte	0x0	 # CIE Identifier Tag
+	.byte	0x1	 # CIE Version
+	.ascii "zR\0"	 # CIE Augmentation
+	.uleb128 0x1	 # CIE Code Alignment Factor
+	.sleb128 -8	 # CIE Data Alignment Factor
+	.byte	0x41	 # CIE RA Column
+	.uleb128 0x1	 # Augmentation size
+	.byte	0x14	 # FDE Encoding (pcrel udata8)
+	.byte	0xc	 # DW_CFA_def_cfa
+	.uleb128 0x1
+	.uleb128 0x0
+	.align 3
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	 # FDE Length
+.LASFDE1:
+	.4byte	.LASFDE1-.Lframe1	 # FDE CIE offset
+	.8byte	.LFB1-.	 # FDE initial location
+	.8byte	.LFE1-.LFB1	 # FDE address range
+	.uleb128 0x0	 # Augmentation size
+	.byte	0x2	 # DW_CFA_advance_loc1
+	.byte	.LCFI0-.LFB1
+	.byte	0xe	 # DW_CFA_def_cfa_offset
+	.uleb128 240
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x41
+	.sleb128 -2
+	.align 3
+.LEFDE1:
+#endif
+
+#if defined __ELF__ && defined __linux__
+	.section	.note.GNU-stack,"", at progbits
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/ppc_closure.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/ppc_closure.S
new file mode 100755
index 0000000..56f7d1a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/ppc_closure.S
@@ -0,0 +1,327 @@
+/* -----------------------------------------------------------------------
+   sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub at redhat.com>
+	    Copyright (c) 2008 Red Hat, Inc.
+
+   PowerPC Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#include <powerpc/asm.h>
+
+	.file   "ppc_closure.S"
+
+#ifndef __powerpc64__
+
+ENTRY(ffi_closure_SYSV)
+.LFB1:
+	stwu %r1,-144(%r1)
+.LCFI0:
+	mflr %r0
+.LCFI1:
+	stw %r0,148(%r1)
+
+# we want to build up an areas for the parameters passed
+# in registers (both floating point and integer)
+
+	# so first save gpr 3 to gpr 10 (aligned to 4)
+	stw   %r3, 16(%r1)
+	stw   %r4, 20(%r1)
+	stw   %r5, 24(%r1)
+	stw   %r6, 28(%r1)
+	stw   %r7, 32(%r1)
+	stw   %r8, 36(%r1)
+	stw   %r9, 40(%r1)
+	stw   %r10,44(%r1)
+
+#ifndef __NO_FPRS__
+	# next save fpr 1 to fpr 8 (aligned to 8)
+	stfd  %f1, 48(%r1)
+	stfd  %f2, 56(%r1)
+	stfd  %f3, 64(%r1)
+	stfd  %f4, 72(%r1)
+	stfd  %f5, 80(%r1)
+	stfd  %f6, 88(%r1)
+	stfd  %f7, 96(%r1)
+	stfd  %f8, 104(%r1)
+#endif
+
+	# set up registers for the routine that actually does the work
+	# get the context pointer from the trampoline
+	mr %r3,%r11
+
+	# now load up the pointer to the result storage
+	addi %r4,%r1,112
+
+	# now load up the pointer to the saved gpr registers
+	addi %r5,%r1,16
+
+	# now load up the pointer to the saved fpr registers */
+	addi %r6,%r1,48
+
+	# now load up the pointer to the outgoing parameter
+	# stack in the previous frame
+	# i.e. the previous frame pointer + 8
+	addi %r7,%r1,152
+
+	# make the call
+	bl ffi_closure_helper_SYSV at local
+.Lret:
+	# now r3 contains the return type
+	# so use it to look up in a table
+	# so we know how to deal with each type
+
+	# look up the proper starting point in table
+	# by using return type as offset
+
+	mflr %r4		# move address of .Lret to r4
+	slwi %r3,%r3,4		# now multiply return type by 16
+	addi %r4, %r4, .Lret_type0 - .Lret
+	lwz %r0,148(%r1)
+	add %r3,%r3,%r4		# add contents of table to table address
+	mtctr %r3
+	bctr			# jump to it
+.LFE1:
+
+# Each of the ret_typeX code fragments has to be exactly 16 bytes long
+# (4 instructions). For cache effectiveness we align to a 16 byte boundary
+# first.
+	.align 4
+# case FFI_TYPE_VOID
+.Lret_type0:
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+	nop
+
+# case FFI_TYPE_INT
+	lwz %r3,112+0(%r1)
+	mtlr %r0
+.Lfinish:
+	addi %r1,%r1,144
+	blr
+
+# case FFI_TYPE_FLOAT
+	lfs %f1,112+0(%r1)
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+
+# case FFI_TYPE_DOUBLE
+	lfd %f1,112+0(%r1)
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+
+# case FFI_TYPE_LONGDOUBLE
+	lfd %f1,112+0(%r1)
+	lfd %f2,112+8(%r1)
+	mtlr %r0
+	b .Lfinish
+
+# case FFI_TYPE_UINT8
+	lbz %r3,112+3(%r1)
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+
+# case FFI_TYPE_SINT8
+	lbz %r3,112+3(%r1)
+	extsb %r3,%r3
+	mtlr %r0
+	b .Lfinish
+
+# case FFI_TYPE_UINT16
+	lhz %r3,112+2(%r1)
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+
+# case FFI_TYPE_SINT16
+	lha %r3,112+2(%r1)
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+
+# case FFI_TYPE_UINT32
+	lwz %r3,112+0(%r1)
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+
+# case FFI_TYPE_SINT32
+	lwz %r3,112+0(%r1)
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+
+# case FFI_TYPE_UINT64
+	lwz %r3,112+0(%r1)
+	lwz %r4,112+4(%r1)
+	mtlr %r0
+	b .Lfinish
+
+# case FFI_TYPE_SINT64
+	lwz %r3,112+0(%r1)
+	lwz %r4,112+4(%r1)
+	mtlr %r0
+	b .Lfinish
+
+# case FFI_TYPE_STRUCT
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+	nop
+
+# case FFI_TYPE_POINTER
+	lwz %r3,112+0(%r1)
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+
+# case FFI_TYPE_UINT128
+	lwz %r3,112+0(%r1)
+	lwz %r4,112+4(%r1)
+	lwz %r5,112+8(%r1)
+	bl .Luint128
+
+# The return types below are only used when the ABI type is FFI_SYSV.
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
+	lbz %r3,112+0(%r1)
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
+	lhz %r3,112+0(%r1)
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
+	lwz %r3,112+0(%r1)
+	srwi %r3,%r3,8
+	mtlr %r0
+	b .Lfinish
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
+	lwz %r3,112+0(%r1)
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
+	lwz %r3,112+0(%r1)
+	lwz %r4,112+4(%r1)
+	li %r5,24
+	b .Lstruct567
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
+	lwz %r3,112+0(%r1)
+	lwz %r4,112+4(%r1)
+	li %r5,16
+	b .Lstruct567
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
+	lwz %r3,112+0(%r1)
+	lwz %r4,112+4(%r1)
+	li %r5,8
+	b .Lstruct567
+
+# case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
+	lwz %r3,112+0(%r1)
+	lwz %r4,112+4(%r1)
+	mtlr %r0
+	b .Lfinish
+
+.Lstruct567:
+	subfic %r6,%r5,32
+	srw %r4,%r4,%r5
+	slw %r6,%r3,%r6
+	srw %r3,%r3,%r5
+	or %r4,%r6,%r4
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+
+.Luint128:
+	lwz %r6,112+12(%r1)
+	mtlr %r0
+	addi %r1,%r1,144
+	blr
+
+END(ffi_closure_SYSV)
+
+	.section	".eh_frame",EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.4byte	.LECIE1-.LSCIE1	 # Length of Common Information Entry
+.LSCIE1:
+	.4byte	0x0	 # CIE Identifier Tag
+	.byte	0x1	 # CIE Version
+#if defined _RELOCATABLE || defined __PIC__
+	.ascii "zR\0"	 # CIE Augmentation
+#else
+	.ascii "\0"	 # CIE Augmentation
+#endif
+	.uleb128 0x1	 # CIE Code Alignment Factor
+	.sleb128 -4	 # CIE Data Alignment Factor
+	.byte	0x41	 # CIE RA Column
+#if defined _RELOCATABLE || defined __PIC__
+	.uleb128 0x1	 # Augmentation size
+	.byte	0x1b	 # FDE Encoding (pcrel sdata4)
+#endif
+	.byte	0xc	 # DW_CFA_def_cfa
+	.uleb128 0x1
+	.uleb128 0x0
+	.align 2
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	 # FDE Length
+.LASFDE1:
+	.4byte	.LASFDE1-.Lframe1	 # FDE CIE offset
+#if defined _RELOCATABLE || defined __PIC__
+	.4byte	.LFB1-.	 # FDE initial location
+#else
+	.4byte	.LFB1	 # FDE initial location
+#endif
+	.4byte	.LFE1-.LFB1	 # FDE address range
+#if defined _RELOCATABLE || defined __PIC__
+	.uleb128 0x0	 # Augmentation size
+#endif
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	.LCFI0-.LFB1
+	.byte	0xe	 # DW_CFA_def_cfa_offset
+	.uleb128 144
+	.byte	0x4	 # DW_CFA_advance_loc4
+	.4byte	.LCFI1-.LCFI0
+	.byte	0x11	 # DW_CFA_offset_extended_sf
+	.uleb128 0x41
+	.sleb128 -1
+	.align 2
+.LEFDE1:
+
+#endif
+
+#if defined __ELF__ && defined __linux__
+	.section	.note.GNU-stack,"", at progbits
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/sysv.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/sysv.S
new file mode 100755
index 0000000..96ea22b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/powerpc/sysv.S
@@ -0,0 +1,219 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 1998 Geoffrey Keating
+   Copyright (C) 2007 Free Software Foundation, Inc
+
+   PowerPC Assembly glue.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#include <powerpc/asm.h>
+
+#ifndef __powerpc64__
+	.globl ffi_prep_args_SYSV
+ENTRY(ffi_call_SYSV)
+.LFB1:
+	/* Save the old stack pointer as AP.  */
+	mr	%r8,%r1
+
+.LCFI0:
+	/* Allocate the stack space we need.  */
+	stwux	%r1,%r1,%r4
+	/* Save registers we use.  */
+	mflr	%r9
+	stw	%r28,-16(%r8)
+.LCFI1:
+	stw	%r29,-12(%r8)
+.LCFI2:
+	stw	%r30, -8(%r8)
+.LCFI3:
+	stw	%r31, -4(%r8)
+.LCFI4:
+	stw	%r9,   4(%r8)
+.LCFI5:
+
+	/* Save arguments over call...  */
+	mr	%r31,%r5	/* flags, */
+	mr	%r30,%r6	/* rvalue, */
+	mr	%r29,%r7	/* function address, */
+	mr	%r28,%r8	/* our AP. */
+.LCFI6:
+
+	/* Call ffi_prep_args_SYSV.  */
+	mr	%r4,%r1
+	bl	ffi_prep_args_SYSV at local
+
+	/* Now do the call.  */
+	/* Set up cr1 with bits 4-7 of the flags.  */
+	mtcrf	0x40,%r31
+	/* Get the address to call into CTR.  */
+	mtctr	%r29
+	/* Load all those argument registers.  */
+	lwz	%r3,-16-(8*4)(%r28)
+	lwz	%r4,-16-(7*4)(%r28)
+	lwz	%r5,-16-(6*4)(%r28)
+	lwz	%r6,-16-(5*4)(%r28)
+	bf-	5,1f
+	nop
+	lwz	%r7,-16-(4*4)(%r28)
+	lwz	%r8,-16-(3*4)(%r28)
+	lwz	%r9,-16-(2*4)(%r28)
+	lwz	%r10,-16-(1*4)(%r28)
+	nop
+1:
+
+	/* Load all the FP registers.  */
+	bf-	6,2f
+	lfd	%f1,-16-(8*4)-(8*8)(%r28)
+	lfd	%f2,-16-(8*4)-(7*8)(%r28)
+	lfd	%f3,-16-(8*4)-(6*8)(%r28)
+	lfd	%f4,-16-(8*4)-(5*8)(%r28)
+	nop
+	lfd	%f5,-16-(8*4)-(4*8)(%r28)
+	lfd	%f6,-16-(8*4)-(3*8)(%r28)
+	lfd	%f7,-16-(8*4)-(2*8)(%r28)
+	lfd	%f8,-16-(8*4)-(1*8)(%r28)
+2:
+
+	/* Make the call.  */
+	bctrl
+
+	/* Now, deal with the return value.  */
+	mtcrf	0x01,%r31 /* cr7  */
+	bt-	31,L(small_struct_return_value)
+	bt-	30,L(done_return_value)
+	bt-	29,L(fp_return_value)
+	stw	%r3,0(%r30)
+	bf+	28,L(done_return_value)
+	stw	%r4,4(%r30)
+	mtcrf	0x02,%r31 /* cr6  */
+	bf	27,L(done_return_value)
+	stw     %r5,8(%r30)
+	stw	%r6,12(%r30)
+	/* Fall through...  */
+
+L(done_return_value):
+	/* Restore the registers we used and return.  */
+	lwz	%r9,   4(%r28)
+	lwz	%r31, -4(%r28)
+	mtlr	%r9
+	lwz	%r30, -8(%r28)
+	lwz	%r29,-12(%r28)
+	lwz	%r28,-16(%r28)
+	lwz	%r1,0(%r1)
+	blr
+
+L(fp_return_value):
+	bf	28,L(float_return_value)
+	stfd	%f1,0(%r30)
+	mtcrf   0x02,%r31 /* cr6  */
+	bf	27,L(done_return_value)
+	stfd	%f2,8(%r30)
+	b	L(done_return_value)
+L(float_return_value):
+	stfs	%f1,0(%r30)
+	b	L(done_return_value)
+
+L(small_struct_return_value):
+	extrwi	%r6,%r31,2,19         /* number of bytes padding = shift/8 */
+	mtcrf	0x02,%r31	      /* copy flags to cr[24:27] (cr6) */
+	extrwi	%r5,%r31,5,19         /* r5 <- number of bits of padding */
+	subfic  %r6,%r6,4             /* r6 <- number of useful bytes in r3 */
+	bf-	25,L(done_return_value) /* struct in r3 ? if not, done. */
+/* smst_one_register: */
+	slw	%r3,%r3,%r5           /* Left-justify value in r3 */
+	mtxer	%r6                   /* move byte count to XER ... */
+	stswx	%r3,0,%r30            /* ... and store that many bytes */
+	bf+	26,L(done_return_value)  /* struct in r3:r4 ? */
+	add	%r6,%r6,%r30          /* adjust pointer */
+	stswi	%r4,%r6,4             /* store last four bytes */
+	b	L(done_return_value)
+
+.LFE1:
+END(ffi_call_SYSV)
+
+      .section	".eh_frame",EH_FRAME_FLAGS, at progbits
+.Lframe1:
+      .4byte    .LECIE1-.LSCIE1  /*  Length of Common Information Entry */
+.LSCIE1:
+      .4byte    0x0      /*  CIE Identifier Tag */
+      .byte     0x1      /*  CIE Version */
+#if defined _RELOCATABLE || defined __PIC__
+      .ascii	"zR\0"   /*  CIE Augmentation */
+#else
+      .ascii	"\0"	 /*  CIE Augmentation */
+#endif
+      .uleb128  0x1      /*  CIE Code Alignment Factor */
+      .sleb128  -4	 /*  CIE Data Alignment Factor */
+      .byte     0x41     /*  CIE RA Column */
+#if defined _RELOCATABLE || defined __PIC__
+      .uleb128  0x1      /*  Augmentation size */
+      .byte	0x1b	 /*  FDE Encoding (pcrel sdata4) */
+#endif
+      .byte     0xc      /*  DW_CFA_def_cfa */
+      .uleb128  0x1
+      .uleb128  0x0
+      .align 2
+.LECIE1:
+.LSFDE1:
+      .4byte    .LEFDE1-.LASFDE1         /*  FDE Length */
+.LASFDE1:
+      .4byte    .LASFDE1-.Lframe1         /*  FDE CIE offset */
+#if defined _RELOCATABLE || defined __PIC__
+      .4byte    .LFB1-.  /*  FDE initial location */
+#else
+      .4byte    .LFB1    /*  FDE initial location */
+#endif
+      .4byte    .LFE1-.LFB1      /*  FDE address range */
+#if defined _RELOCATABLE || defined __PIC__
+      .uleb128  0x0	 /*  Augmentation size */
+#endif
+      .byte     0x4      /*  DW_CFA_advance_loc4 */
+      .4byte    .LCFI0-.LFB1
+      .byte     0xd      /*  DW_CFA_def_cfa_register */
+      .uleb128  0x08
+      .byte     0x4      /*  DW_CFA_advance_loc4 */
+      .4byte    .LCFI5-.LCFI0
+      .byte     0x11     /*  DW_CFA_offset_extended_sf */
+      .uleb128  0x41
+      .sleb128  -1
+      .byte     0x9f     /*  DW_CFA_offset, column 0x1f */
+      .uleb128  0x1
+      .byte     0x9e     /*  DW_CFA_offset, column 0x1e */
+      .uleb128  0x2
+      .byte     0x9d     /*  DW_CFA_offset, column 0x1d */
+      .uleb128  0x3
+      .byte     0x9c     /*  DW_CFA_offset, column 0x1c */
+      .uleb128  0x4
+      .byte     0x4      /*  DW_CFA_advance_loc4 */
+      .4byte    .LCFI6-.LCFI5
+      .byte     0xd      /*  DW_CFA_def_cfa_register */
+      .uleb128  0x1c
+      .align 2
+.LEFDE1:
+#endif
+
+#if defined __ELF__ && defined __linux__
+	.section	.note.GNU-stack,"", at progbits
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/prep_cif.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/prep_cif.c
new file mode 100755
index 0000000..8548cfd
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/prep_cif.c
@@ -0,0 +1,177 @@
+/* -----------------------------------------------------------------------
+   prep_cif.c - Copyright (c) 2011  Anthony Green
+                Copyright (c) 1996, 1998, 2007  Red Hat, Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+#include <stdlib.h>
+
+/* Round up to FFI_SIZEOF_ARG. */
+
+#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
+
+/* Perform machine independent initialization of aggregate type
+   specifications. */
+
+static ffi_status initialize_aggregate(ffi_type *arg)
+{
+  ffi_type **ptr;
+
+  if (UNLIKELY(arg == NULL || arg->elements == NULL))
+    return FFI_BAD_TYPEDEF;
+
+  arg->size = 0;
+  arg->alignment = 0;
+
+  ptr = &(arg->elements[0]);
+
+  if (UNLIKELY(ptr == 0))
+    return FFI_BAD_TYPEDEF;
+
+  while ((*ptr) != NULL)
+    {
+      if (UNLIKELY(((*ptr)->size == 0)
+		    && (initialize_aggregate((*ptr)) != FFI_OK)))
+	return FFI_BAD_TYPEDEF;
+
+      /* Perform a sanity check on the argument type */
+      FFI_ASSERT_VALID_TYPE(*ptr);
+
+      arg->size = ALIGN(arg->size, (*ptr)->alignment);
+      arg->size += (*ptr)->size;
+
+      arg->alignment = (arg->alignment > (*ptr)->alignment) ?
+	arg->alignment : (*ptr)->alignment;
+
+      ptr++;
+    }
+
+  /* Structure size includes tail padding.  This is important for
+     structures that fit in one register on ABIs like the PowerPC64
+     Linux ABI that right justify small structs in a register.
+     It's also needed for nested structure layout, for example
+     struct A { long a; char b; }; struct B { struct A x; char y; };
+     should find y at an offset of 2*sizeof(long) and result in a
+     total size of 3*sizeof(long).  */
+  arg->size = ALIGN (arg->size, arg->alignment);
+
+  if (arg->size == 0)
+    return FFI_BAD_TYPEDEF;
+  else
+    return FFI_OK;
+}
+
+#ifndef __CRIS__
+/* The CRIS ABI specifies structure elements to have byte
+   alignment only, so it completely overrides this functions,
+   which assumes "natural" alignment and padding.  */
+
+/* Perform machine independent ffi_cif preparation, then call
+   machine dependent routine. */
+
+ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
+			ffi_type *rtype, ffi_type **atypes)
+{
+  unsigned bytes = 0;
+  unsigned int i;
+  ffi_type **ptr;
+
+  FFI_ASSERT(cif != NULL);
+  if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))
+    return FFI_BAD_ABI;
+
+  cif->abi = abi;
+  cif->arg_types = atypes;
+  cif->nargs = nargs;
+  cif->rtype = rtype;
+
+  cif->flags = 0;
+
+  /* Initialize the return type if necessary */
+  if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
+    return FFI_BAD_TYPEDEF;
+
+  /* Perform a sanity check on the return type */
+  FFI_ASSERT_VALID_TYPE(cif->rtype);
+
+  /* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
+#if !defined M68K && !defined X86_ANY && !defined S390 && !defined PA
+  /* Make space for the return structure pointer */
+  if (cif->rtype->type == FFI_TYPE_STRUCT
+#ifdef SPARC
+      && (cif->abi != FFI_V9 || cif->rtype->size > 32)
+#endif
+     )
+    bytes = STACK_ARG_SIZE(sizeof(void*));
+#endif
+
+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+    {
+
+      /* Initialize any uninitialized aggregate type definitions */
+      if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+	return FFI_BAD_TYPEDEF;
+
+      /* Perform a sanity check on the argument type, do this
+	 check after the initialization.  */
+      FFI_ASSERT_VALID_TYPE(*ptr);
+
+#if !defined X86_ANY && !defined S390 && !defined PA
+#ifdef SPARC
+      if (((*ptr)->type == FFI_TYPE_STRUCT
+	   && ((*ptr)->size > 16 || cif->abi != FFI_V9))
+	  || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
+	      && cif->abi != FFI_V9))
+	bytes += sizeof(void*);
+      else
+#endif
+	{
+	  /* Add any padding if necessary */
+	  if (((*ptr)->alignment - 1) & bytes)
+	    bytes = ALIGN(bytes, (*ptr)->alignment);
+
+	  bytes += STACK_ARG_SIZE((*ptr)->size);
+	}
+#endif
+    }
+
+  cif->bytes = bytes;
+
+  /* Perform machine dependent cif processing */
+  return ffi_prep_cif_machdep(cif);
+}
+#endif /* not __CRIS__ */
+
+#if FFI_CLOSURES
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*,void*,void**,void*),
+		  void *user_data)
+{
+  return ffi_prep_closure_loc (closure, cif, fun, user_data, closure);
+}
+
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/raw_api.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/raw_api.c
new file mode 100755
index 0000000..ce21372
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/raw_api.c
@@ -0,0 +1,254 @@
+/* -----------------------------------------------------------------------
+   raw_api.c - Copyright (c) 1999, 2008  Red Hat, Inc.
+
+   Author: Kresten Krab Thorup <krab at gnu.org>
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+/* This file defines generic functions for use with the raw api. */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#if !FFI_NO_RAW_API
+
+size_t
+ffi_raw_size (ffi_cif *cif)
+{
+  size_t result = 0;
+  int i;
+
+  ffi_type **at = cif->arg_types;
+
+  for (i = cif->nargs-1; i >= 0; i--, at++)
+    {
+#if !FFI_NO_STRUCTS
+      if ((*at)->type == FFI_TYPE_STRUCT)
+	result += ALIGN (sizeof (void*), FFI_SIZEOF_ARG);
+      else
+#endif
+	result += ALIGN ((*at)->size, FFI_SIZEOF_ARG);
+    }
+
+  return result;
+}
+
+
+void
+ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
+{
+  unsigned i;
+  ffi_type **tp = cif->arg_types;
+
+#if WORDS_BIGENDIAN
+
+  for (i = 0; i < cif->nargs; i++, tp++, args++)
+    {	  
+      switch ((*tp)->type)
+	{
+	case FFI_TYPE_UINT8:
+	case FFI_TYPE_SINT8:
+	  *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 1);
+	  break;
+	  
+	case FFI_TYPE_UINT16:
+	case FFI_TYPE_SINT16:
+	  *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 2);
+	  break;
+
+#if FFI_SIZEOF_ARG >= 4	  
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_SINT32:
+	  *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 4);
+	  break;
+#endif
+	
+#if !FFI_NO_STRUCTS  
+	case FFI_TYPE_STRUCT:
+	  *args = (raw++)->ptr;
+	  break;
+#endif
+
+	case FFI_TYPE_POINTER:
+	  *args = (void*) &(raw++)->ptr;
+	  break;
+	  
+	default:
+	  *args = raw;
+	  raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+	}
+    }
+
+#else /* WORDS_BIGENDIAN */
+
+#if !PDP
+
+  /* then assume little endian */
+  for (i = 0; i < cif->nargs; i++, tp++, args++)
+    {	  
+#if !FFI_NO_STRUCTS
+      if ((*tp)->type == FFI_TYPE_STRUCT)
+	{
+	  *args = (raw++)->ptr;
+	}
+      else
+#endif
+	{
+	  *args = (void*) raw;
+	  raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
+	}
+    }
+
+#else
+#error "pdp endian not supported"
+#endif /* ! PDP */
+
+#endif /* WORDS_BIGENDIAN */
+}
+
+void
+ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
+{
+  unsigned i;
+  ffi_type **tp = cif->arg_types;
+
+  for (i = 0; i < cif->nargs; i++, tp++, args++)
+    {	  
+      switch ((*tp)->type)
+	{
+	case FFI_TYPE_UINT8:
+	  (raw++)->uint = *(UINT8*) (*args);
+	  break;
+
+	case FFI_TYPE_SINT8:
+	  (raw++)->sint = *(SINT8*) (*args);
+	  break;
+
+	case FFI_TYPE_UINT16:
+	  (raw++)->uint = *(UINT16*) (*args);
+	  break;
+
+	case FFI_TYPE_SINT16:
+	  (raw++)->sint = *(SINT16*) (*args);
+	  break;
+
+#if FFI_SIZEOF_ARG >= 4
+	case FFI_TYPE_UINT32:
+	  (raw++)->uint = *(UINT32*) (*args);
+	  break;
+
+	case FFI_TYPE_SINT32:
+	  (raw++)->sint = *(SINT32*) (*args);
+	  break;
+#endif
+
+#if !FFI_NO_STRUCTS
+	case FFI_TYPE_STRUCT:
+	  (raw++)->ptr = *args;
+	  break;
+#endif
+
+	case FFI_TYPE_POINTER:
+	  (raw++)->ptr = **(void***) args;
+	  break;
+
+	default:
+	  memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
+	  raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+	}
+    }
+}
+
+#if !FFI_NATIVE_RAW_API
+
+
+/* This is a generic definition of ffi_raw_call, to be used if the
+ * native system does not provide a machine-specific implementation.
+ * Having this, allows code to be written for the raw API, without
+ * the need for system-specific code to handle input in that format;
+ * these following couple of functions will handle the translation forth
+ * and back automatically. */
+
+void ffi_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *raw)
+{
+  void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
+  ffi_raw_to_ptrarray (cif, raw, avalue);
+  ffi_call (cif, fn, rvalue, avalue);
+}
+
+#if FFI_CLOSURES		/* base system provides closures */
+
+static void
+ffi_translate_args (ffi_cif *cif, void *rvalue,
+		    void **avalue, void *user_data)
+{
+  ffi_raw *raw = (ffi_raw*)alloca (ffi_raw_size (cif));
+  ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
+
+  ffi_ptrarray_to_raw (cif, avalue, raw);
+  (*cl->fun) (cif, rvalue, raw, cl->user_data);
+}
+
+ffi_status
+ffi_prep_raw_closure_loc (ffi_raw_closure* cl,
+			  ffi_cif *cif,
+			  void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+			  void *user_data,
+			  void *codeloc)
+{
+  ffi_status status;
+
+  status = ffi_prep_closure_loc ((ffi_closure*) cl,
+				 cif,
+				 &ffi_translate_args,
+				 codeloc,
+				 codeloc);
+  if (status == FFI_OK)
+    {
+      cl->fun       = fun;
+      cl->user_data = user_data;
+    }
+
+  return status;
+}
+
+#endif /* FFI_CLOSURES */
+#endif /* !FFI_NATIVE_RAW_API */
+
+#if FFI_CLOSURES
+
+/* Again, here is the generic version of ffi_prep_raw_closure, which
+ * will install an intermediate "hub" for translation of arguments from
+ * the pointer-array format, to the raw format */
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure* cl,
+		      ffi_cif *cif,
+		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+		      void *user_data)
+{
+  return ffi_prep_raw_closure_loc (cl, cif, fun, user_data, cl);
+}
+
+#endif /* FFI_CLOSURES */
+
+#endif /* !FFI_NO_RAW_API */
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/s390/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/s390/ffi.c
new file mode 100755
index 0000000..ca2675b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/s390/ffi.c
@@ -0,0 +1,780 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2000, 2007 Software AG
+           Copyright (c) 2008 Red Hat, Inc
+ 
+   S390 Foreign Function Interface
+ 
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+ 
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+ 
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+/*====================================================================*/
+/*                          Includes                                  */
+/*                          --------                                  */
+/*====================================================================*/
+ 
+#include <ffi.h>
+#include <ffi_common.h>
+ 
+#include <stdlib.h>
+#include <stdio.h>
+ 
+/*====================== End of Includes =============================*/
+ 
+/*====================================================================*/
+/*                           Defines                                  */
+/*                           -------                                  */
+/*====================================================================*/
+
+/* Maximum number of GPRs available for argument passing.  */ 
+#define MAX_GPRARGS 5
+
+/* Maximum number of FPRs available for argument passing.  */ 
+#ifdef __s390x__
+#define MAX_FPRARGS 4
+#else
+#define MAX_FPRARGS 2
+#endif
+
+/* Round to multiple of 16.  */
+#define ROUND_SIZE(size) (((size) + 15) & ~15)
+
+/* If these values change, sysv.S must be adapted!  */
+#define FFI390_RET_VOID		0
+#define FFI390_RET_STRUCT	1
+#define FFI390_RET_FLOAT	2
+#define FFI390_RET_DOUBLE	3
+#define FFI390_RET_INT32	4
+#define FFI390_RET_INT64	5
+
+/*===================== End of Defines ===============================*/
+ 
+/*====================================================================*/
+/*                          Prototypes                                */
+/*                          ----------                                */
+/*====================================================================*/
+ 
+static void ffi_prep_args (unsigned char *, extended_cif *);
+void
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
+__attribute__ ((visibility ("hidden")))
+#endif
+ffi_closure_helper_SYSV (ffi_closure *, unsigned long *, 
+			 unsigned long long *, unsigned long *);
+
+/*====================== End of Prototypes ===========================*/
+ 
+/*====================================================================*/
+/*                          Externals                                 */
+/*                          ---------                                 */
+/*====================================================================*/
+ 
+extern void ffi_call_SYSV(unsigned,
+			  extended_cif *,
+			  void (*)(unsigned char *, extended_cif *),
+			  unsigned,
+			  void *,
+			  void (*fn)(void));
+
+extern void ffi_closure_SYSV(void);
+ 
+/*====================== End of Externals ============================*/
+ 
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_check_struct_type.                                  */
+/*                                                                    */
+/* Function - Determine if a structure can be passed within a         */
+/*            general purpose or floating point register.             */
+/*                                                                    */
+/*====================================================================*/
+ 
+static int
+ffi_check_struct_type (ffi_type *arg)
+{
+  size_t size = arg->size;
+
+  /* If the struct has just one element, look at that element
+     to find out whether to consider the struct as floating point.  */
+  while (arg->type == FFI_TYPE_STRUCT 
+         && arg->elements[0] && !arg->elements[1])
+    arg = arg->elements[0];
+
+  /* Structs of size 1, 2, 4, and 8 are passed in registers,
+     just like the corresponding int/float types.  */
+  switch (size)
+    {
+      case 1:
+        return FFI_TYPE_UINT8;
+
+      case 2:
+        return FFI_TYPE_UINT16;
+
+      case 4:
+	if (arg->type == FFI_TYPE_FLOAT)
+          return FFI_TYPE_FLOAT;
+	else
+	  return FFI_TYPE_UINT32;
+
+      case 8:
+	if (arg->type == FFI_TYPE_DOUBLE)
+          return FFI_TYPE_DOUBLE;
+	else
+	  return FFI_TYPE_UINT64;
+
+      default:
+	break;
+    }
+
+  /* Other structs are passed via a pointer to the data.  */
+  return FFI_TYPE_POINTER;
+}
+ 
+/*======================== End of Routine ============================*/
+ 
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_prep_args.                                          */
+/*                                                                    */
+/* Function - Prepare parameters for call to function.                */
+/*                                                                    */
+/* ffi_prep_args is called by the assembly routine once stack space   */
+/* has been allocated for the function's arguments.                   */
+/*                                                                    */
+/*====================================================================*/
+ 
+static void
+ffi_prep_args (unsigned char *stack, extended_cif *ecif)
+{
+  /* The stack space will be filled with those areas:
+
+	FPR argument register save area     (highest addresses)
+	GPR argument register save area
+	temporary struct copies
+	overflow argument area              (lowest addresses)
+
+     We set up the following pointers:
+
+        p_fpr: bottom of the FPR area (growing upwards)
+	p_gpr: bottom of the GPR area (growing upwards)
+	p_ov: bottom of the overflow area (growing upwards)
+	p_struct: top of the struct copy area (growing downwards)
+
+     All areas are kept aligned to twice the word size.  */
+
+  int gpr_off = ecif->cif->bytes;
+  int fpr_off = gpr_off + ROUND_SIZE (MAX_GPRARGS * sizeof (long));
+
+  unsigned long long *p_fpr = (unsigned long long *)(stack + fpr_off);
+  unsigned long *p_gpr = (unsigned long *)(stack + gpr_off);
+  unsigned char *p_struct = (unsigned char *)p_gpr;
+  unsigned long *p_ov = (unsigned long *)stack;
+
+  int n_fpr = 0;
+  int n_gpr = 0;
+  int n_ov = 0;
+
+  ffi_type **ptr;
+  void **p_argv = ecif->avalue;
+  int i;
+ 
+  /* If we returning a structure then we set the first parameter register
+     to the address of where we are returning this structure.  */
+
+  if (ecif->cif->flags == FFI390_RET_STRUCT)
+    p_gpr[n_gpr++] = (unsigned long) ecif->rvalue;
+
+  /* Now for the arguments.  */
+ 
+  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+       i > 0;
+       i--, ptr++, p_argv++)
+    {
+      void *arg = *p_argv;
+      int type = (*ptr)->type;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+      /* 16-byte long double is passed like a struct.  */
+      if (type == FFI_TYPE_LONGDOUBLE)
+	type = FFI_TYPE_STRUCT;
+#endif
+
+      /* Check how a structure type is passed.  */
+      if (type == FFI_TYPE_STRUCT)
+	{
+	  type = ffi_check_struct_type (*ptr);
+
+	  /* If we pass the struct via pointer, copy the data.  */
+	  if (type == FFI_TYPE_POINTER)
+	    {
+	      p_struct -= ROUND_SIZE ((*ptr)->size);
+	      memcpy (p_struct, (char *)arg, (*ptr)->size);
+	      arg = &p_struct;
+	    }
+	}
+
+      /* Now handle all primitive int/pointer/float data types.  */
+      switch (type) 
+	{
+	  case FFI_TYPE_DOUBLE:
+	    if (n_fpr < MAX_FPRARGS)
+	      p_fpr[n_fpr++] = *(unsigned long long *) arg;
+	    else
+#ifdef __s390x__
+	      p_ov[n_ov++] = *(unsigned long *) arg;
+#else
+	      p_ov[n_ov++] = ((unsigned long *) arg)[0],
+	      p_ov[n_ov++] = ((unsigned long *) arg)[1];
+#endif
+	    break;
+	
+	  case FFI_TYPE_FLOAT:
+	    if (n_fpr < MAX_FPRARGS)
+	      p_fpr[n_fpr++] = (long long) *(unsigned int *) arg << 32;
+	    else
+	      p_ov[n_ov++] = *(unsigned int *) arg;
+	    break;
+
+	  case FFI_TYPE_POINTER:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = (unsigned long)*(unsigned char **) arg;
+	    else
+	      p_ov[n_ov++] = (unsigned long)*(unsigned char **) arg;
+	    break;
+ 
+	  case FFI_TYPE_UINT64:
+	  case FFI_TYPE_SINT64:
+#ifdef __s390x__
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(unsigned long *) arg;
+	    else
+	      p_ov[n_ov++] = *(unsigned long *) arg;
+#else
+	    if (n_gpr == MAX_GPRARGS-1)
+	      n_gpr = MAX_GPRARGS;
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = ((unsigned long *) arg)[0],
+	      p_gpr[n_gpr++] = ((unsigned long *) arg)[1];
+	    else
+	      p_ov[n_ov++] = ((unsigned long *) arg)[0],
+	      p_ov[n_ov++] = ((unsigned long *) arg)[1];
+#endif
+	    break;
+ 
+	  case FFI_TYPE_UINT32:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(unsigned int *) arg;
+	    else
+	      p_ov[n_ov++] = *(unsigned int *) arg;
+	    break;
+ 
+	  case FFI_TYPE_INT:
+	  case FFI_TYPE_SINT32:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(signed int *) arg;
+	    else
+	      p_ov[n_ov++] = *(signed int *) arg;
+	    break;
+ 
+	  case FFI_TYPE_UINT16:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(unsigned short *) arg;
+	    else
+	      p_ov[n_ov++] = *(unsigned short *) arg;
+	    break;
+ 
+	  case FFI_TYPE_SINT16:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(signed short *) arg;
+	    else
+	      p_ov[n_ov++] = *(signed short *) arg;
+	    break;
+
+	  case FFI_TYPE_UINT8:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(unsigned char *) arg;
+	    else
+	      p_ov[n_ov++] = *(unsigned char *) arg;
+	    break;
+ 
+	  case FFI_TYPE_SINT8:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(signed char *) arg;
+	    else
+	      p_ov[n_ov++] = *(signed char *) arg;
+	    break;
+ 
+	  default:
+	    FFI_ASSERT (0);
+	    break;
+        }
+    }
+}
+
+/*======================== End of Routine ============================*/
+ 
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_prep_cif_machdep.                                   */
+/*                                                                    */
+/* Function - Perform machine dependent CIF processing.               */
+/*                                                                    */
+/*====================================================================*/
+ 
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  size_t struct_size = 0;
+  int n_gpr = 0;
+  int n_fpr = 0;
+  int n_ov = 0;
+
+  ffi_type **ptr;
+  int i;
+
+  /* Determine return value handling.  */ 
+
+  switch (cif->rtype->type)
+    {
+      /* Void is easy.  */
+      case FFI_TYPE_VOID:
+	cif->flags = FFI390_RET_VOID;
+	break;
+
+      /* Structures are returned via a hidden pointer.  */
+      case FFI_TYPE_STRUCT:
+	cif->flags = FFI390_RET_STRUCT;
+	n_gpr++;  /* We need one GPR to pass the pointer.  */
+	break; 
+
+      /* Floating point values are returned in fpr 0.  */
+      case FFI_TYPE_FLOAT:
+	cif->flags = FFI390_RET_FLOAT;
+	break;
+
+      case FFI_TYPE_DOUBLE:
+	cif->flags = FFI390_RET_DOUBLE;
+	break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+      case FFI_TYPE_LONGDOUBLE:
+	cif->flags = FFI390_RET_STRUCT;
+	n_gpr++;
+	break;
+#endif
+      /* Integer values are returned in gpr 2 (and gpr 3
+	 for 64-bit values on 31-bit machines).  */
+      case FFI_TYPE_UINT64:
+      case FFI_TYPE_SINT64:
+	cif->flags = FFI390_RET_INT64;
+	break;
+
+      case FFI_TYPE_POINTER:
+      case FFI_TYPE_INT:
+      case FFI_TYPE_UINT32:
+      case FFI_TYPE_SINT32:
+      case FFI_TYPE_UINT16:
+      case FFI_TYPE_SINT16:
+      case FFI_TYPE_UINT8:
+      case FFI_TYPE_SINT8:
+	/* These are to be extended to word size.  */
+#ifdef __s390x__
+	cif->flags = FFI390_RET_INT64;
+#else
+	cif->flags = FFI390_RET_INT32;
+#endif
+	break;
+ 
+      default:
+        FFI_ASSERT (0);
+        break;
+    }
+
+  /* Now for the arguments.  */
+ 
+  for (ptr = cif->arg_types, i = cif->nargs;
+       i > 0;
+       i--, ptr++)
+    {
+      int type = (*ptr)->type;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+      /* 16-byte long double is passed like a struct.  */
+      if (type == FFI_TYPE_LONGDOUBLE)
+	type = FFI_TYPE_STRUCT;
+#endif
+
+      /* Check how a structure type is passed.  */
+      if (type == FFI_TYPE_STRUCT)
+	{
+	  type = ffi_check_struct_type (*ptr);
+
+	  /* If we pass the struct via pointer, we must reserve space
+	     to copy its data for proper call-by-value semantics.  */
+	  if (type == FFI_TYPE_POINTER)
+	    struct_size += ROUND_SIZE ((*ptr)->size);
+	}
+
+      /* Now handle all primitive int/float data types.  */
+      switch (type) 
+	{
+	  /* The first MAX_FPRARGS floating point arguments
+	     go in FPRs, the rest overflow to the stack.  */
+
+	  case FFI_TYPE_DOUBLE:
+	    if (n_fpr < MAX_FPRARGS)
+	      n_fpr++;
+	    else
+	      n_ov += sizeof (double) / sizeof (long);
+	    break;
+	
+	  case FFI_TYPE_FLOAT:
+	    if (n_fpr < MAX_FPRARGS)
+	      n_fpr++;
+	    else
+	      n_ov++;
+	    break;
+
+	  /* On 31-bit machines, 64-bit integers are passed in GPR pairs,
+	     if one is still available, or else on the stack.  If only one
+	     register is free, skip the register (it won't be used for any 
+	     subsequent argument either).  */
+	      
+#ifndef __s390x__
+	  case FFI_TYPE_UINT64:
+	  case FFI_TYPE_SINT64:
+	    if (n_gpr == MAX_GPRARGS-1)
+	      n_gpr = MAX_GPRARGS;
+	    if (n_gpr < MAX_GPRARGS)
+	      n_gpr += 2;
+	    else
+	      n_ov += 2;
+	    break;
+#endif
+
+	  /* Everything else is passed in GPRs (until MAX_GPRARGS
+	     have been used) or overflows to the stack.  */
+
+	  default: 
+	    if (n_gpr < MAX_GPRARGS)
+	      n_gpr++;
+	    else
+	      n_ov++;
+	    break;
+        }
+    }
+
+  /* Total stack space as required for overflow arguments
+     and temporary structure copies.  */
+
+  cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size;
+ 
+  return FFI_OK;
+}
+ 
+/*======================== End of Routine ============================*/
+ 
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_call.                                               */
+/*                                                                    */
+/* Function - Call the FFI routine.                                   */
+/*                                                                    */
+/*====================================================================*/
+ 
+void
+ffi_call(ffi_cif *cif,
+	 void (*fn)(void),
+	 void *rvalue,
+	 void **avalue)
+{
+  int ret_type = cif->flags;
+  extended_cif ecif;
+ 
+  ecif.cif    = cif;
+  ecif.avalue = avalue;
+  ecif.rvalue = rvalue;
+
+  /* If we don't have a return value, we need to fake one.  */
+  if (rvalue == NULL)
+    {
+      if (ret_type == FFI390_RET_STRUCT)
+	ecif.rvalue = alloca (cif->rtype->size);
+      else
+	ret_type = FFI390_RET_VOID;
+    } 
+
+  switch (cif->abi)
+    {
+      case FFI_SYSV:
+        ffi_call_SYSV (cif->bytes, &ecif, ffi_prep_args,
+		       ret_type, ecif.rvalue, fn);
+        break;
+ 
+      default:
+        FFI_ASSERT (0);
+        break;
+    }
+}
+ 
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_closure_helper_SYSV.                                */
+/*                                                                    */
+/* Function - Call a FFI closure target function.                     */
+/*                                                                    */
+/*====================================================================*/
+ 
+void
+ffi_closure_helper_SYSV (ffi_closure *closure,
+			 unsigned long *p_gpr,
+			 unsigned long long *p_fpr,
+			 unsigned long *p_ov)
+{
+  unsigned long long ret_buffer;
+
+  void *rvalue = &ret_buffer;
+  void **avalue;
+  void **p_arg;
+
+  int n_gpr = 0;
+  int n_fpr = 0;
+  int n_ov = 0;
+
+  ffi_type **ptr;
+  int i;
+
+  /* Allocate buffer for argument list pointers.  */
+
+  p_arg = avalue = alloca (closure->cif->nargs * sizeof (void *));
+
+  /* If we returning a structure, pass the structure address 
+     directly to the target function.  Otherwise, have the target 
+     function store the return value to the GPR save area.  */
+
+  if (closure->cif->flags == FFI390_RET_STRUCT)
+    rvalue = (void *) p_gpr[n_gpr++];
+
+  /* Now for the arguments.  */
+
+  for (ptr = closure->cif->arg_types, i = closure->cif->nargs;
+       i > 0;
+       i--, p_arg++, ptr++)
+    {
+      int deref_struct_pointer = 0;
+      int type = (*ptr)->type;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+      /* 16-byte long double is passed like a struct.  */
+      if (type == FFI_TYPE_LONGDOUBLE)
+	type = FFI_TYPE_STRUCT;
+#endif
+
+      /* Check how a structure type is passed.  */
+      if (type == FFI_TYPE_STRUCT)
+	{
+	  type = ffi_check_struct_type (*ptr);
+
+	  /* If we pass the struct via pointer, remember to 
+	     retrieve the pointer later.  */
+	  if (type == FFI_TYPE_POINTER)
+	    deref_struct_pointer = 1;
+	}
+
+      /* Pointers are passed like UINTs of the same size.  */
+      if (type == FFI_TYPE_POINTER)
+#ifdef __s390x__
+	type = FFI_TYPE_UINT64;
+#else
+	type = FFI_TYPE_UINT32;
+#endif
+
+      /* Now handle all primitive int/float data types.  */
+      switch (type) 
+	{
+	  case FFI_TYPE_DOUBLE:
+	    if (n_fpr < MAX_FPRARGS)
+	      *p_arg = &p_fpr[n_fpr++];
+	    else
+	      *p_arg = &p_ov[n_ov], 
+	      n_ov += sizeof (double) / sizeof (long);
+	    break;
+	
+	  case FFI_TYPE_FLOAT:
+	    if (n_fpr < MAX_FPRARGS)
+	      *p_arg = &p_fpr[n_fpr++];
+	    else
+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
+	    break;
+ 
+	  case FFI_TYPE_UINT64:
+	  case FFI_TYPE_SINT64:
+#ifdef __s390x__
+	    if (n_gpr < MAX_GPRARGS)
+	      *p_arg = &p_gpr[n_gpr++];
+	    else
+	      *p_arg = &p_ov[n_ov++];
+#else
+	    if (n_gpr == MAX_GPRARGS-1)
+	      n_gpr = MAX_GPRARGS;
+	    if (n_gpr < MAX_GPRARGS)
+	      *p_arg = &p_gpr[n_gpr], n_gpr += 2;
+	    else
+	      *p_arg = &p_ov[n_ov], n_ov += 2;
+#endif
+	    break;
+ 
+	  case FFI_TYPE_INT:
+	  case FFI_TYPE_UINT32:
+	  case FFI_TYPE_SINT32:
+	    if (n_gpr < MAX_GPRARGS)
+	      *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 4;
+	    else
+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
+	    break;
+ 
+	  case FFI_TYPE_UINT16:
+	  case FFI_TYPE_SINT16:
+	    if (n_gpr < MAX_GPRARGS)
+	      *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 2;
+	    else
+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 2;
+	    break;
+
+	  case FFI_TYPE_UINT8:
+	  case FFI_TYPE_SINT8:
+	    if (n_gpr < MAX_GPRARGS)
+	      *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 1;
+	    else
+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;
+	    break;
+ 
+	  default:
+	    FFI_ASSERT (0);
+	    break;
+        }
+
+      /* If this is a struct passed via pointer, we need to
+	 actually retrieve that pointer.  */
+      if (deref_struct_pointer)
+	*p_arg = *(void **)*p_arg;
+    }
+
+
+  /* Call the target function.  */
+  (closure->fun) (closure->cif, rvalue, avalue, closure->user_data);
+
+  /* Convert the return value.  */
+  switch (closure->cif->rtype->type)
+    {
+      /* Void is easy, and so is struct.  */
+      case FFI_TYPE_VOID:
+      case FFI_TYPE_STRUCT:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+      case FFI_TYPE_LONGDOUBLE:
+#endif
+	break;
+
+      /* Floating point values are returned in fpr 0.  */
+      case FFI_TYPE_FLOAT:
+	p_fpr[0] = (long long) *(unsigned int *) rvalue << 32;
+	break;
+
+      case FFI_TYPE_DOUBLE:
+	p_fpr[0] = *(unsigned long long *) rvalue;
+	break;
+
+      /* Integer values are returned in gpr 2 (and gpr 3
+	 for 64-bit values on 31-bit machines).  */
+      case FFI_TYPE_UINT64:
+      case FFI_TYPE_SINT64:
+#ifdef __s390x__
+	p_gpr[0] = *(unsigned long *) rvalue;
+#else
+	p_gpr[0] = ((unsigned long *) rvalue)[0],
+	p_gpr[1] = ((unsigned long *) rvalue)[1];
+#endif
+	break;
+
+      case FFI_TYPE_POINTER:
+      case FFI_TYPE_UINT32:
+      case FFI_TYPE_UINT16:
+      case FFI_TYPE_UINT8:
+	p_gpr[0] = *(unsigned long *) rvalue;
+	break;
+
+      case FFI_TYPE_INT:
+      case FFI_TYPE_SINT32:
+      case FFI_TYPE_SINT16:
+      case FFI_TYPE_SINT8:
+	p_gpr[0] = *(signed long *) rvalue;
+	break;
+
+      default:
+        FFI_ASSERT (0);
+        break;
+    }
+}
+ 
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_prep_closure_loc.                                   */
+/*                                                                    */
+/* Function - Prepare a FFI closure.                                  */
+/*                                                                    */
+/*====================================================================*/
+ 
+ffi_status
+ffi_prep_closure_loc (ffi_closure *closure,
+		      ffi_cif *cif,
+		      void (*fun) (ffi_cif *, void *, void **, void *),
+		      void *user_data,
+		      void *codeloc)
+{
+  FFI_ASSERT (cif->abi == FFI_SYSV);
+
+#ifndef __s390x__
+  *(short *)&closure->tramp [0] = 0x0d10;   /* basr %r1,0 */
+  *(short *)&closure->tramp [2] = 0x9801;   /* lm %r0,%r1,6(%r1) */
+  *(short *)&closure->tramp [4] = 0x1006;
+  *(short *)&closure->tramp [6] = 0x07f1;   /* br %r1 */
+  *(long  *)&closure->tramp [8] = (long)codeloc;
+  *(long  *)&closure->tramp[12] = (long)&ffi_closure_SYSV;
+#else
+  *(short *)&closure->tramp [0] = 0x0d10;   /* basr %r1,0 */
+  *(short *)&closure->tramp [2] = 0xeb01;   /* lmg %r0,%r1,14(%r1) */
+  *(short *)&closure->tramp [4] = 0x100e;
+  *(short *)&closure->tramp [6] = 0x0004;
+  *(short *)&closure->tramp [8] = 0x07f1;   /* br %r1 */
+  *(long  *)&closure->tramp[16] = (long)codeloc;
+  *(long  *)&closure->tramp[24] = (long)&ffi_closure_SYSV;
+#endif 
+ 
+  closure->cif = cif;
+  closure->user_data = user_data;
+  closure->fun = fun;
+ 
+  return FFI_OK;
+}
+
+/*======================== End of Routine ============================*/
+ 
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/s390/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/s390/ffitarget.h
new file mode 100755
index 0000000..a262691
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/s390/ffitarget.h
@@ -0,0 +1,62 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for S390.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#if defined (__s390x__)
+#ifndef S390X
+#define S390X
+#endif
+#endif
+
+/* ---- System specific configurations ----------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_SYSV
+} ffi_abi;
+#endif
+
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#ifdef S390X
+#define FFI_TRAMPOLINE_SIZE 32
+#else
+#define FFI_TRAMPOLINE_SIZE 16
+#endif
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/s390/sysv.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/s390/sysv.S
new file mode 100755
index 0000000..4731a31
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/s390/sysv.S
@@ -0,0 +1,434 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2000 Software AG
+            Copyright (c) 2008 Red Hat, Inc.
+ 
+   S390 Foreign Function Interface
+ 
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+ 
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+ 
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+#ifndef __s390x__
+ 
+.text
+
+	# r2:	cif->bytes
+	# r3:	&ecif
+	# r4:	ffi_prep_args
+	# r5:	ret_type
+	# r6:	ecif.rvalue
+	# ov:	fn 
+ 
+	# This assumes we are using gas.
+	.globl	ffi_call_SYSV
+	.type	ffi_call_SYSV,%function
+ffi_call_SYSV:
+.LFB1:
+	stm	%r6,%r15,24(%r15)		# Save registers
+.LCFI0:
+	basr	%r13,0				# Set up base register
+.Lbase:
+	lr	%r11,%r15			# Set up frame pointer
+.LCFI1:
+	sr	%r15,%r2
+	ahi	%r15,-96-48			# Allocate stack
+	lr	%r8,%r6				# Save ecif.rvalue
+	sr	%r9,%r9
+	ic	%r9,.Ltable-.Lbase(%r13,%r5)	# Load epilog address
+	l	%r7,96(%r11)			# Load function address
+	st	%r11,0(%r15)			# Set up back chain
+	ahi	%r11,-48			# Register save area
+.LCFI2:
+
+	la	%r2,96(%r15)			# Save area
+						# r3 already holds &ecif
+	basr	%r14,%r4			# Call ffi_prep_args
+
+	lm	%r2,%r6,0(%r11)			# Load arguments
+	ld	%f0,32(%r11)
+	ld	%f2,40(%r11)
+	la	%r14,0(%r13,%r9)		# Set return address
+	br	%r7				# ... and call function
+
+.LretNone:					# Return void
+	l	%r4,48+56(%r11)
+	lm	%r6,%r15,48+24(%r11)
+	br	%r4
+
+.LretFloat:
+	l	%r4,48+56(%r11)
+	ste	%f0,0(%r8)			# Return float
+	lm	%r6,%r15,48+24(%r11)
+	br	%r4
+ 
+.LretDouble:
+	l	%r4,48+56(%r11)
+	std	%f0,0(%r8)			# Return double
+	lm	%r6,%r15,48+24(%r11)
+	br	%r4
+
+.LretInt32:
+	l	%r4,48+56(%r11)
+	st	%r2,0(%r8)			# Return int
+	lm	%r6,%r15,48+24(%r11)
+	br	%r4
+ 
+.LretInt64:
+	l	%r4,48+56(%r11)
+	stm	%r2,%r3,0(%r8)			# Return long long
+	lm	%r6,%r15,48+24(%r11)
+	br	%r4
+ 
+.Ltable:
+	.byte	.LretNone-.Lbase		# FFI390_RET_VOID
+	.byte	.LretNone-.Lbase		# FFI390_RET_STRUCT
+	.byte	.LretFloat-.Lbase		# FFI390_RET_FLOAT
+	.byte	.LretDouble-.Lbase		# FFI390_RET_DOUBLE
+	.byte	.LretInt32-.Lbase		# FFI390_RET_INT32
+	.byte	.LretInt64-.Lbase		# FFI390_RET_INT64
+
+.LFE1: 
+.ffi_call_SYSV_end:
+	.size	 ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+
+
+	.globl	ffi_closure_SYSV
+	.type	ffi_closure_SYSV,%function
+ffi_closure_SYSV:
+.LFB2:
+	stm	%r12,%r15,48(%r15)		# Save registers
+.LCFI10:
+	basr	%r13,0				# Set up base register
+.Lcbase:
+	stm	%r2,%r6,8(%r15)			# Save arguments
+	std	%f0,64(%r15)
+	std	%f2,72(%r15)
+	lr	%r1,%r15			# Set up stack frame
+	ahi	%r15,-96
+.LCFI11:
+	l	%r12,.Lchelper-.Lcbase(%r13)	# Get helper function
+	lr	%r2,%r0				# Closure
+	la	%r3,8(%r1)			# GPRs
+	la	%r4,64(%r1)			# FPRs
+	la	%r5,96(%r1)			# Overflow
+	st	%r1,0(%r15)			# Set up back chain
+
+	bas	%r14,0(%r12,%r13)		# Call helper
+
+	l	%r4,96+56(%r15)
+	ld	%f0,96+64(%r15)			# Load return registers
+	lm	%r2,%r3,96+8(%r15)
+	lm	%r12,%r15,96+48(%r15)
+	br	%r4
+
+	.align 4
+.Lchelper:
+	.long	ffi_closure_helper_SYSV-.Lcbase
+
+.LFE2: 
+
+.ffi_closure_SYSV_end:
+	.size	 ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
+
+
+	.section	.eh_frame,EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.4byte	.LECIE1-.LSCIE1	# Length of Common Information Entry
+.LSCIE1:
+	.4byte	0x0	# CIE Identifier Tag
+	.byte	0x1	# CIE Version
+	.ascii "zR\0"	# CIE Augmentation
+	.uleb128 0x1	# CIE Code Alignment Factor
+	.sleb128 -4	# CIE Data Alignment Factor
+	.byte	0xe	# CIE RA Column
+	.uleb128 0x1	# Augmentation size
+	.byte	0x1b	# FDE Encoding (pcrel sdata4)
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0xf
+	.uleb128 0x60
+	.align	4
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	# FDE Length
+.LASFDE1:
+	.4byte	.LASFDE1-.Lframe1	# FDE CIE offset
+	.4byte	.LFB1-.	# FDE initial location
+	.4byte	.LFE1-.LFB1	# FDE address range
+	.uleb128 0x0	# Augmentation size
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI0-.LFB1
+	.byte	0x8f	# DW_CFA_offset, column 0xf
+	.uleb128 0x9
+	.byte	0x8e	# DW_CFA_offset, column 0xe
+	.uleb128 0xa
+	.byte	0x8d	# DW_CFA_offset, column 0xd
+	.uleb128 0xb
+	.byte	0x8c	# DW_CFA_offset, column 0xc
+	.uleb128 0xc
+	.byte	0x8b	# DW_CFA_offset, column 0xb
+	.uleb128 0xd
+	.byte	0x8a	# DW_CFA_offset, column 0xa
+	.uleb128 0xe
+	.byte	0x89	# DW_CFA_offset, column 0x9
+	.uleb128 0xf
+	.byte	0x88	# DW_CFA_offset, column 0x8
+	.uleb128 0x10
+	.byte	0x87	# DW_CFA_offset, column 0x7
+	.uleb128 0x11
+	.byte	0x86	# DW_CFA_offset, column 0x6
+	.uleb128 0x12
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI1-.LCFI0
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0xb
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI2-.LCFI1
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x90
+	.align	4
+.LEFDE1:
+.LSFDE2:
+	.4byte	.LEFDE2-.LASFDE2	# FDE Length
+.LASFDE2:
+	.4byte	.LASFDE2-.Lframe1	# FDE CIE offset
+	.4byte	.LFB2-.	# FDE initial location
+	.4byte	.LFE2-.LFB2	# FDE address range
+	.uleb128 0x0	# Augmentation size
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI10-.LFB2
+	.byte	0x8f	# DW_CFA_offset, column 0xf
+	.uleb128 0x9
+	.byte	0x8e	# DW_CFA_offset, column 0xe
+	.uleb128 0xa
+	.byte	0x8d	# DW_CFA_offset, column 0xd
+	.uleb128 0xb
+	.byte	0x8c	# DW_CFA_offset, column 0xc
+	.uleb128 0xc
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI11-.LCFI10
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0xc0
+	.align	4
+.LEFDE2:
+
+#else
+ 
+.text
+ 
+	# r2:	cif->bytes
+	# r3:	&ecif
+	# r4:	ffi_prep_args
+	# r5:	ret_type
+	# r6:	ecif.rvalue
+	# ov:	fn 
+ 
+	# This assumes we are using gas.
+	.globl	ffi_call_SYSV
+	.type	ffi_call_SYSV,%function
+ffi_call_SYSV:
+.LFB1:
+	stmg	%r6,%r15,48(%r15)		# Save registers
+.LCFI0:
+	larl	%r13,.Lbase			# Set up base register
+	lgr	%r11,%r15			# Set up frame pointer
+.LCFI1:
+	sgr	%r15,%r2
+	aghi	%r15,-160-80			# Allocate stack
+	lgr	%r8,%r6				# Save ecif.rvalue
+	llgc	%r9,.Ltable-.Lbase(%r13,%r5)	# Load epilog address
+	lg	%r7,160(%r11)			# Load function address
+	stg	%r11,0(%r15)			# Set up back chain
+	aghi	%r11,-80			# Register save area
+.LCFI2:
+
+	la	%r2,160(%r15)			# Save area
+						# r3 already holds &ecif
+	basr	%r14,%r4			# Call ffi_prep_args
+
+	lmg	%r2,%r6,0(%r11)			# Load arguments
+	ld	%f0,48(%r11)
+	ld	%f2,56(%r11)
+	ld	%f4,64(%r11)
+	ld	%f6,72(%r11)
+	la	%r14,0(%r13,%r9)		# Set return address
+	br	%r7				# ... and call function
+
+.Lbase:
+.LretNone:					# Return void
+	lg	%r4,80+112(%r11)
+	lmg	%r6,%r15,80+48(%r11)
+	br	%r4
+
+.LretFloat:
+	lg	%r4,80+112(%r11)
+	ste	%f0,0(%r8)			# Return float
+	lmg	%r6,%r15,80+48(%r11)
+	br	%r4
+ 
+.LretDouble:
+	lg	%r4,80+112(%r11)
+	std	%f0,0(%r8)			# Return double
+	lmg	%r6,%r15,80+48(%r11)
+	br	%r4
+
+.LretInt32:
+	lg	%r4,80+112(%r11)
+	st	%r2,0(%r8)			# Return int
+	lmg	%r6,%r15,80+48(%r11)
+	br	%r4
+ 
+.LretInt64:
+	lg	%r4,80+112(%r11)
+	stg	%r2,0(%r8)			# Return long
+	lmg	%r6,%r15,80+48(%r11)
+	br	%r4
+ 
+.Ltable:
+	.byte	.LretNone-.Lbase		# FFI390_RET_VOID
+	.byte	.LretNone-.Lbase		# FFI390_RET_STRUCT
+	.byte	.LretFloat-.Lbase		# FFI390_RET_FLOAT
+	.byte	.LretDouble-.Lbase		# FFI390_RET_DOUBLE
+	.byte	.LretInt32-.Lbase		# FFI390_RET_INT32
+	.byte	.LretInt64-.Lbase		# FFI390_RET_INT64
+
+.LFE1: 
+.ffi_call_SYSV_end:
+	.size	 ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+
+
+	.globl	ffi_closure_SYSV
+	.type	ffi_closure_SYSV,%function
+ffi_closure_SYSV:
+.LFB2:
+	stmg	%r14,%r15,112(%r15)		# Save registers
+.LCFI10:
+	stmg	%r2,%r6,16(%r15)		# Save arguments
+	std	%f0,128(%r15)
+	std	%f2,136(%r15)
+	std	%f4,144(%r15)
+	std	%f6,152(%r15)
+	lgr	%r1,%r15			# Set up stack frame
+	aghi	%r15,-160
+.LCFI11:
+	lgr	%r2,%r0				# Closure
+	la	%r3,16(%r1)			# GPRs
+	la	%r4,128(%r1)			# FPRs
+	la	%r5,160(%r1)			# Overflow
+	stg	%r1,0(%r15)			# Set up back chain
+
+	brasl	%r14,ffi_closure_helper_SYSV	# Call helper
+
+	lg	%r14,160+112(%r15)
+	ld	%f0,160+128(%r15)		# Load return registers
+	lg	%r2,160+16(%r15)
+	la	%r15,160(%r15)
+	br	%r14
+.LFE2: 
+
+.ffi_closure_SYSV_end:
+	.size	 ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
+
+
+
+	.section	.eh_frame,EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.4byte	.LECIE1-.LSCIE1	# Length of Common Information Entry
+.LSCIE1:
+	.4byte	0x0	# CIE Identifier Tag
+	.byte	0x1	# CIE Version
+	.ascii "zR\0"	# CIE Augmentation
+	.uleb128 0x1	# CIE Code Alignment Factor
+	.sleb128 -8	# CIE Data Alignment Factor
+	.byte	0xe	# CIE RA Column
+	.uleb128 0x1	# Augmentation size
+	.byte	0x1b	# FDE Encoding (pcrel sdata4)
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0xf
+	.uleb128 0xa0
+	.align	8
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	# FDE Length
+.LASFDE1:
+	.4byte	.LASFDE1-.Lframe1	# FDE CIE offset
+	.4byte	.LFB1-.	# FDE initial location
+	.4byte	.LFE1-.LFB1	# FDE address range
+	.uleb128 0x0	# Augmentation size
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI0-.LFB1
+	.byte	0x8f	# DW_CFA_offset, column 0xf
+	.uleb128 0x5
+	.byte	0x8e	# DW_CFA_offset, column 0xe
+	.uleb128 0x6
+	.byte	0x8d	# DW_CFA_offset, column 0xd
+	.uleb128 0x7
+	.byte	0x8c	# DW_CFA_offset, column 0xc
+	.uleb128 0x8
+	.byte	0x8b	# DW_CFA_offset, column 0xb
+	.uleb128 0x9
+	.byte	0x8a	# DW_CFA_offset, column 0xa
+	.uleb128 0xa
+	.byte	0x89	# DW_CFA_offset, column 0x9
+	.uleb128 0xb
+	.byte	0x88	# DW_CFA_offset, column 0x8
+	.uleb128 0xc
+	.byte	0x87	# DW_CFA_offset, column 0x7
+	.uleb128 0xd
+	.byte	0x86	# DW_CFA_offset, column 0x6
+	.uleb128 0xe
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI1-.LCFI0
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0xb
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI2-.LCFI1
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0xf0
+	.align	8
+.LEFDE1:
+.LSFDE2:
+	.4byte	.LEFDE2-.LASFDE2	# FDE Length
+.LASFDE2:
+	.4byte	.LASFDE2-.Lframe1	# FDE CIE offset
+	.4byte	.LFB2-.	# FDE initial location
+	.4byte	.LFE2-.LFB2	# FDE address range
+	.uleb128 0x0	# Augmentation size
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI10-.LFB2
+	.byte	0x8f	# DW_CFA_offset, column 0xf
+	.uleb128 0x5
+	.byte	0x8e	# DW_CFA_offset, column 0xe
+	.uleb128 0x6
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI11-.LCFI10
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x140
+	.align	8
+.LEFDE2:
+
+#endif
+
+#if defined __ELF__ && defined __linux__
+	.section	.note.GNU-stack,"", at progbits
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh/ffi.c
new file mode 100755
index 0000000..69bd025
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh/ffi.c
@@ -0,0 +1,716 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Kaz Kojima
+           Copyright (c) 2008 Red Hat, Inc.
+   
+   SuperH Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+#define NGREGARG 4
+#if defined(__SH4__)
+#define NFREGARG 8
+#endif
+
+#if defined(__HITACHI__)
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 1
+#else
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 0
+#endif
+
+/* If the structure has essentialy an unique element, return its type.  */
+static int
+simple_type (ffi_type *arg)
+{
+  if (arg->type != FFI_TYPE_STRUCT)
+    return arg->type;
+  else if (arg->elements[1])
+    return FFI_TYPE_STRUCT;
+
+  return simple_type (arg->elements[0]);
+}
+
+static int
+return_type (ffi_type *arg)
+{
+  unsigned short type;
+
+  if (arg->type != FFI_TYPE_STRUCT)
+    return arg->type;
+
+  type = simple_type (arg->elements[0]);
+  if (! arg->elements[1])
+    {
+      switch (type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	  return FFI_TYPE_INT;
+
+	default:
+	  return type;
+	}
+    }
+
+  /* gcc uses r0/r1 pair for some kind of structures.  */
+  if (arg->size <= 2 * sizeof (int))
+    {
+      int i = 0;
+      ffi_type *e;
+
+      while ((e = arg->elements[i++]))
+	{
+	  type = simple_type (e);
+	  switch (type)
+	    {
+	    case FFI_TYPE_SINT32:
+	    case FFI_TYPE_UINT32:
+	    case FFI_TYPE_INT:
+	    case FFI_TYPE_FLOAT:
+	      return FFI_TYPE_UINT64;
+
+	    default:
+	      break;
+	    }
+	}
+    }
+
+  return FFI_TYPE_STRUCT;
+}
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+void ffi_prep_args(char *stack, extended_cif *ecif)
+{
+  register unsigned int i;
+  register int tmp;
+  register unsigned int avn;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+  int greg, ireg;
+#if defined(__SH4__)
+  int freg = 0;
+#endif
+
+  tmp = 0;
+  argp = stack;
+
+  if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT)
+    {
+      *(void **) argp = ecif->rvalue;
+      argp += 4;
+      ireg = STRUCT_VALUE_ADDRESS_WITH_ARG ? 1 : 0;
+    }
+  else
+    ireg = 0;
+
+  /* Set arguments for registers.  */
+  greg = ireg;
+  avn = ecif->cif->nargs;
+  p_argv = ecif->avalue;
+
+  for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+	{
+	  if (greg++ >= NGREGARG)
+	    continue;
+
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT8:
+	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_SINT16:
+	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT16:
+	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_STRUCT:
+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  argp += z;
+	}
+      else if (z == sizeof(int))
+	{
+#if defined(__SH4__)
+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	    {
+	      if (freg++ >= NFREGARG)
+		continue;
+	    }
+	  else
+#endif
+	    {
+	      if (greg++ >= NGREGARG)
+		continue;
+	    }
+	  *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	  argp += z;
+	}
+#if defined(__SH4__)
+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+	{
+	  if (freg + 1 >= NFREGARG)
+	    continue;
+	  freg = (freg + 1) & ~1;
+	  freg += 2;
+	  memcpy (argp, *p_argv, z);
+	  argp += z;
+	}
+#endif
+      else
+	{
+	  int n = (z + sizeof (int) - 1) / sizeof (int);
+#if defined(__SH4__)
+	  if (greg + n - 1 >= NGREGARG)
+	    continue;
+#else
+	  if (greg >= NGREGARG)
+	    continue;
+#endif
+	  greg += n;
+	  memcpy (argp, *p_argv, z);
+	  argp += n * sizeof (int);
+	}
+    }
+
+  /* Set arguments on stack.  */
+  greg = ireg;
+#if defined(__SH4__)
+  freg = 0;
+#endif
+  p_argv = ecif->avalue;
+
+  for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+	{
+	  if (greg++ < NGREGARG)
+	    continue;
+
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT8:
+	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_SINT16:
+	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT16:
+	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_STRUCT:
+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  argp += z;
+	}
+      else if (z == sizeof(int))
+	{
+#if defined(__SH4__)
+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	    {
+	      if (freg++ < NFREGARG)
+		continue;
+	    }
+	  else
+#endif
+	    {
+	      if (greg++ < NGREGARG)
+		continue;
+	    }
+	  *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	  argp += z;
+	}
+#if defined(__SH4__)
+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+	{
+	  if (freg + 1 < NFREGARG)
+	    {
+	      freg = (freg + 1) & ~1;
+	      freg += 2;
+	      continue;
+	    }
+	  memcpy (argp, *p_argv, z);
+	  argp += z;
+	}
+#endif
+      else
+	{
+	  int n = (z + sizeof (int) - 1) / sizeof (int);
+	  if (greg + n - 1 < NGREGARG)
+	    {
+	      greg += n;
+	      continue;
+	    }
+#if (! defined(__SH4__))
+	  else if (greg < NGREGARG)
+	    {
+	      greg = NGREGARG;
+	      continue;
+	    }
+#endif
+	  memcpy (argp, *p_argv, z);
+	  argp += n * sizeof (int);
+	}
+    }
+
+  return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  int i, j;
+  int size, type;
+  int n, m;
+  int greg;
+#if defined(__SH4__)
+  int freg = 0;
+#endif
+
+  cif->flags = 0;
+
+  greg = ((return_type (cif->rtype) == FFI_TYPE_STRUCT) &&
+	  STRUCT_VALUE_ADDRESS_WITH_ARG) ? 1 : 0;
+
+#if defined(__SH4__)
+  for (i = j = 0; i < cif->nargs && j < 12; i++)
+    {
+      type = (cif->arg_types)[i]->type;
+      switch (type)
+	{
+	case FFI_TYPE_FLOAT:
+	  if (freg >= NFREGARG)
+	    continue;
+	  freg++;
+	  cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
+	  j++;
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  if ((freg + 1) >= NFREGARG)
+	    continue;
+	  freg = (freg + 1) & ~1;
+	  freg += 2;
+	  cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
+	  j++;
+	  break;
+	      
+	default:
+	  size = (cif->arg_types)[i]->size;
+	  n = (size + sizeof (int) - 1) / sizeof (int);
+	  if (greg + n - 1 >= NGREGARG)
+		continue;
+	  greg += n;
+	  for (m = 0; m < n; m++)
+	    cif->flags += FFI_TYPE_INT << (2 * j++);
+	  break;
+	}
+    }
+#else
+  for (i = j = 0; i < cif->nargs && j < 4; i++)
+    {
+      size = (cif->arg_types)[i]->size;
+      n = (size + sizeof (int) - 1) / sizeof (int);
+      if (greg >= NGREGARG)
+	continue;
+      else if (greg + n - 1 >= NGREGARG)
+	n = NGREGARG - greg;
+      greg += n;
+      for (m = 0; m < n; m++)
+        cif->flags += FFI_TYPE_INT << (2 * j++);
+    }
+#endif
+
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_STRUCT:
+      cif->flags += (unsigned) (return_type (cif->rtype)) << 24;
+      break;
+
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      cif->flags += (unsigned) cif->rtype->type << 24;
+      break;
+
+    default:
+      cif->flags += FFI_TYPE_INT << 24;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
+			  unsigned, unsigned, unsigned *, void (*fn)(void));
+
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+  UINT64 trvalue;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if (cif->rtype->type == FFI_TYPE_STRUCT
+      && return_type (cif->rtype) != FFI_TYPE_STRUCT)
+    ecif.rvalue = &trvalue;
+  else if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      ecif.rvalue = alloca(cif->rtype->size);
+    }
+  else
+    ecif.rvalue = rvalue;
+
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
+		    fn);
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+
+  if (rvalue
+      && cif->rtype->type == FFI_TYPE_STRUCT
+      && return_type (cif->rtype) != FFI_TYPE_STRUCT)
+    memcpy (rvalue, &trvalue, cif->rtype->size);
+}
+
+extern void ffi_closure_SYSV (void);
+#if defined(__SH4__)
+extern void __ic_invalidate (void *line);
+#endif
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif*, void*, void**, void*),
+		      void *user_data,
+		      void *codeloc)
+{
+  unsigned int *tramp;
+  unsigned int insn;
+
+  FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
+
+  tramp = (unsigned int *) &closure->tramp[0];
+  /* Set T bit if the function returns a struct pointed with R2.  */
+  insn = (return_type (cif->rtype) == FFI_TYPE_STRUCT
+	  ? 0x0018 /* sett */
+	  : 0x0008 /* clrt */);
+
+#ifdef __LITTLE_ENDIAN__
+  tramp[0] = 0xd301d102;
+  tramp[1] = 0x0000412b | (insn << 16);
+#else
+  tramp[0] = 0xd102d301;
+  tramp[1] = 0x412b0000 | insn;
+#endif
+  *(void **) &tramp[2] = (void *)codeloc;          /* ctx */
+  *(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+#if defined(__SH4__)
+  /* Flush the icache.  */
+  __ic_invalidate(codeloc);
+#endif
+
+  return FFI_OK;
+}
+
+/* Basically the trampoline invokes ffi_closure_SYSV, and on 
+ * entry, r3 holds the address of the closure.
+ * After storing the registers that could possibly contain
+ * parameters to be passed into the stack frame and setting
+ * up space for a return value, ffi_closure_SYSV invokes the 
+ * following helper function to do most of the work.
+ */
+
+#ifdef __LITTLE_ENDIAN__
+#define OFS_INT8	0
+#define OFS_INT16	0
+#else
+#define OFS_INT8	3
+#define OFS_INT16	2
+#endif
+
+int
+ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, 
+			 unsigned long *pgr, unsigned long *pfr, 
+			 unsigned long *pst)
+{
+  void **avalue;
+  ffi_type **p_arg;
+  int i, avn;
+  int ireg, greg = 0;
+#if defined(__SH4__)
+  int freg = 0;
+#endif
+  ffi_cif *cif; 
+
+  cif = closure->cif;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  /* Copy the caller's structure return value address so that the closure
+     returns the data directly to the caller.  */
+  if (cif->rtype->type == FFI_TYPE_STRUCT && STRUCT_VALUE_ADDRESS_WITH_ARG)
+    {
+      rvalue = (void *) *pgr++;
+      ireg = 1;
+    }
+  else
+    ireg = 0;
+
+  cif = closure->cif;
+  greg = ireg;
+  avn = cif->nargs;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+	{
+	  if (greg++ >= NGREGARG)
+	    continue;
+
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	    case FFI_TYPE_UINT8:
+	      avalue[i] = (((char *)pgr) + OFS_INT8);
+	      break;
+  
+	    case FFI_TYPE_SINT16:
+	    case FFI_TYPE_UINT16:
+	      avalue[i] = (((char *)pgr) + OFS_INT16);
+	      break;
+  
+	    case FFI_TYPE_STRUCT:
+	      avalue[i] = pgr;
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  pgr++;
+	}
+      else if (z == sizeof(int))
+	{
+#if defined(__SH4__)
+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	    {
+	      if (freg++ >= NFREGARG)
+		continue;
+	      avalue[i] = pfr;
+	      pfr++;
+	    }
+	  else
+#endif
+	    {
+	      if (greg++ >= NGREGARG)
+		continue;
+	      avalue[i] = pgr;
+	      pgr++;
+	    }
+	}
+#if defined(__SH4__)
+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+	{
+	  if (freg + 1 >= NFREGARG)
+	    continue;
+	  if (freg & 1)
+	    pfr++;
+	  freg = (freg + 1) & ~1;
+	  freg += 2;
+	  avalue[i] = pfr;
+	  pfr += 2;
+	}
+#endif
+      else
+	{
+	  int n = (z + sizeof (int) - 1) / sizeof (int);
+#if defined(__SH4__)
+	  if (greg + n - 1 >= NGREGARG)
+	    continue;
+#else
+	  if (greg >= NGREGARG)
+	    continue;
+#endif
+	  greg += n;
+	  avalue[i] = pgr;
+	  pgr += n;
+	}
+    }
+
+  greg = ireg;
+#if defined(__SH4__)
+  freg = 0;
+#endif
+
+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+	{
+	  if (greg++ < NGREGARG)
+	    continue;
+
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	    case FFI_TYPE_UINT8:
+	      avalue[i] = (((char *)pst) + OFS_INT8);
+	      break;
+  
+	    case FFI_TYPE_SINT16:
+	    case FFI_TYPE_UINT16:
+	      avalue[i] = (((char *)pst) + OFS_INT16);
+	      break;
+  
+	    case FFI_TYPE_STRUCT:
+	      avalue[i] = pst;
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  pst++;
+	}
+      else if (z == sizeof(int))
+	{
+#if defined(__SH4__)
+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	    {
+	      if (freg++ < NFREGARG)
+		continue;
+	    }
+	  else
+#endif
+	    {
+	      if (greg++ < NGREGARG)
+		continue;
+	    }
+	  avalue[i] = pst;
+	  pst++;
+	}
+#if defined(__SH4__)
+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+	{
+	  if (freg + 1 < NFREGARG)
+	    {
+	      freg = (freg + 1) & ~1;
+	      freg += 2;
+	      continue;
+	    }
+	  avalue[i] = pst;
+	  pst += 2;
+	}
+#endif
+      else
+	{
+	  int n = (z + sizeof (int) - 1) / sizeof (int);
+	  if (greg + n - 1 < NGREGARG)
+	    {
+	      greg += n;
+	      continue;
+	    }
+#if (! defined(__SH4__))
+	  else if (greg < NGREGARG)
+	    {
+	      greg += n;
+	      pst += greg - NGREGARG;
+	      continue;
+	    }
+#endif
+	  avalue[i] = pst;
+	  pst += n;
+	}
+    }
+
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_SYSV how to perform return type promotions.  */
+  return return_type (cif->rtype);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh/ffitarget.h
new file mode 100755
index 0000000..4f1f639
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh/ffitarget.h
@@ -0,0 +1,49 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for SuperH.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_SYSV
+} ffi_abi;
+#endif
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 16
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh/sysv.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh/sysv.S
new file mode 100755
index 0000000..5be7516
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh/sysv.S
@@ -0,0 +1,850 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2002, 2003, 2004, 2006, 2008 Kaz Kojima
+   
+   SuperH Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+/* XXX these lose for some platforms, I'm sure. */
+#define CNAME(x) x
+#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
+#endif
+
+#if defined(__HITACHI__)
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 1
+#else
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 0
+#endif
+
+.text
+
+	# r4:	ffi_prep_args
+	# r5:	&ecif
+	# r6:	bytes
+	# r7:	flags
+	# sp+0: rvalue
+	# sp+4: fn
+
+	# This assumes we are using gas.
+ENTRY(ffi_call_SYSV)
+	# Save registers
+.LFB1:
+	mov.l	r8, at -r15
+.LCFI0:
+	mov.l	r9, at -r15
+.LCFI1:
+	mov.l	r10, at -r15
+.LCFI2:
+	mov.l	r12, at -r15
+.LCFI3:
+	mov.l	r14, at -r15
+.LCFI4:
+	sts.l	pr, at -r15
+.LCFI5:
+	mov	r15,r14
+.LCFI6:
+#if defined(__SH4__)
+	mov	r6,r8
+	mov	r7,r9
+
+	sub	r6,r15
+	add	#-16,r15
+	mov	#~7,r0
+	and	r0,r15
+
+	mov	r4,r0
+	jsr	@r0
+	 mov	r15,r4
+
+	mov	r9,r1
+	shlr8	r9
+	shlr8	r9
+	shlr8	r9
+
+	mov	#FFI_TYPE_STRUCT,r2
+	cmp/eq	r2,r9
+	bf	1f
+#if STRUCT_VALUE_ADDRESS_WITH_ARG
+ 	mov.l	@r15+,r4
+	bra	2f
+	 mov	#5,r2
+#else
+ 	mov.l	@r15+,r10
+#endif
+1:
+	mov	#4,r2
+2:
+	mov	#4,r3
+
+L_pass:
+	cmp/pl	r8
+	bf	L_call_it
+
+	mov	r1,r0
+	and	#3,r0
+
+L_pass_d:
+	cmp/eq	#FFI_TYPE_DOUBLE,r0
+	bf	L_pass_f
+
+	mov	r3,r0
+	and	#1,r0
+	tst	r0,r0
+	bt	1f
+	add	#1,r3
+1:
+	mov	#12,r0
+	cmp/hs	r0,r3
+	bt/s	3f
+	 shlr2	r1
+	bsr	L_pop_d
+	 nop
+3:
+	add	#2,r3
+	bra	L_pass
+	 add	#-8,r8
+
+L_pop_d:
+	mov	r3,r0
+	add	r0,r0
+	add	r3,r0
+	add	#-12,r0
+	braf	r0
+	 nop
+#ifdef __LITTLE_ENDIAN__
+	fmov.s	@r15+,fr5
+	rts
+	 fmov.s	@r15+,fr4
+	fmov.s	@r15+,fr7
+	rts
+	 fmov.s	@r15+,fr6
+	fmov.s	@r15+,fr9
+	rts
+	 fmov.s	@r15+,fr8
+	fmov.s	@r15+,fr11
+	rts
+	 fmov.s	@r15+,fr10
+#else
+	fmov.s	@r15+,fr4
+	rts
+	 fmov.s	@r15+,fr5
+	fmov.s	@r15+,fr6
+	rts
+	 fmov.s	@r15+,fr7
+	fmov.s	@r15+,fr8
+	rts
+	 fmov.s	@r15+,fr9
+	fmov.s	@r15+,fr10
+	rts
+	 fmov.s	@r15+,fr11
+#endif
+
+L_pass_f:
+	cmp/eq	#FFI_TYPE_FLOAT,r0
+	bf	L_pass_i
+
+	mov	#12,r0
+	cmp/hs	r0,r3
+	bt/s	2f
+	 shlr2	r1
+	bsr	L_pop_f
+	 nop
+2:
+	add	#1,r3
+	bra	L_pass
+	 add	#-4,r8
+
+L_pop_f:
+	mov	r3,r0
+	shll2	r0
+	add	#-16,r0
+	braf	r0
+	 nop
+#ifdef __LITTLE_ENDIAN__
+	rts
+	 fmov.s	@r15+,fr5
+	rts
+	 fmov.s	@r15+,fr4
+	rts
+	 fmov.s	@r15+,fr7
+	rts
+	 fmov.s	@r15+,fr6
+	rts
+	 fmov.s	@r15+,fr9
+	rts
+	 fmov.s	@r15+,fr8
+	rts
+	 fmov.s	@r15+,fr11
+	rts
+	 fmov.s	@r15+,fr10
+#else
+	rts
+	 fmov.s	@r15+,fr4
+	rts
+	 fmov.s	@r15+,fr5
+	rts
+	 fmov.s	@r15+,fr6
+	rts
+	 fmov.s	@r15+,fr7
+	rts
+	 fmov.s	@r15+,fr8
+	rts
+	 fmov.s	@r15+,fr9
+	rts
+	 fmov.s	@r15+,fr10
+	rts
+	 fmov.s	@r15+,fr11
+#endif
+
+L_pass_i:
+	cmp/eq	#FFI_TYPE_INT,r0
+	bf	L_call_it
+
+	mov	#8,r0
+	cmp/hs	r0,r2
+	bt/s	2f
+	 shlr2	r1
+	bsr	L_pop_i
+	 nop
+2:
+	add	#1,r2
+	bra	L_pass
+	 add	#-4,r8
+
+L_pop_i:
+	mov	r2,r0
+	shll2	r0
+	add	#-16,r0
+	braf	r0
+	 nop
+	rts
+	 mov.l	@r15+,r4
+	rts
+	 mov.l	@r15+,r5
+	rts
+	 mov.l	@r15+,r6
+	rts
+	 mov.l	@r15+,r7
+
+L_call_it:
+	# call function
+#if (! STRUCT_VALUE_ADDRESS_WITH_ARG)
+	mov	r10, r2
+#endif
+	mov.l  @(28,r14),r1
+	jsr    @r1
+	 nop
+
+L_ret_d:
+	mov	#FFI_TYPE_DOUBLE,r2
+	cmp/eq	r2,r9
+	bf	L_ret_ll
+
+	mov.l	@(24,r14),r1
+#ifdef __LITTLE_ENDIAN__
+	fmov.s	fr1, at r1
+	add	#4,r1
+	bra	L_epilogue
+	 fmov.s	fr0, at r1
+#else
+	fmov.s	fr0, at r1
+	add	#4,r1
+	bra	L_epilogue
+	 fmov.s	fr1, at r1
+#endif
+
+L_ret_ll:
+	mov	#FFI_TYPE_SINT64,r2
+	cmp/eq	r2,r9
+	bt/s	1f
+	 mov	#FFI_TYPE_UINT64,r2
+	cmp/eq	r2,r9
+	bf	L_ret_f
+
+1:
+	mov.l	@(24,r14),r2
+	mov.l	r0, at r2
+	bra	L_epilogue
+	 mov.l	r1,@(4,r2)
+
+L_ret_f:
+	mov	#FFI_TYPE_FLOAT,r2
+	cmp/eq	r2,r9
+	bf	L_ret_i
+
+	mov.l	@(24,r14),r1
+	bra	L_epilogue
+	 fmov.s	fr0, at r1
+
+L_ret_i:
+	mov	#FFI_TYPE_INT,r2
+	cmp/eq	r2,r9
+	bf	L_epilogue
+
+	mov.l	@(24,r14),r1
+	bra	L_epilogue
+	 mov.l	r0, at r1
+
+L_epilogue:
+	# Remove the space we pushed for the args
+	mov   r14,r15
+
+	lds.l  @r15+,pr
+	mov.l  @r15+,r14
+	mov.l  @r15+,r12
+	mov.l  @r15+,r10
+	mov.l  @r15+,r9
+	rts
+	 mov.l  @r15+,r8
+#else
+	mov	r6,r8
+	mov	r7,r9
+
+	sub	r6,r15
+	add	#-16,r15
+	mov	#~7,r0
+	and	r0,r15
+
+	mov	r4,r0
+	jsr	@r0
+	 mov	r15,r4
+
+	mov	r9,r3
+	shlr8	r9
+	shlr8	r9
+	shlr8	r9
+
+	mov	#FFI_TYPE_STRUCT,r2
+	cmp/eq	r2,r9
+	bf	1f
+#if STRUCT_VALUE_ADDRESS_WITH_ARG
+	mov.l	@r15+,r4
+	bra	2f
+	 mov	#5,r2
+#else
+	mov.l	@r15+,r10
+#endif
+1:
+	mov	#4,r2
+2:
+
+L_pass:
+	cmp/pl	r8
+	bf	L_call_it
+
+	mov	r3,r0
+	and	#3,r0
+
+L_pass_d:
+	cmp/eq	#FFI_TYPE_DOUBLE,r0
+	bf	L_pass_i
+
+	mov	r15,r0
+	and	#7,r0
+	tst	r0,r0
+	bt	1f
+	add	#4,r15
+1:
+	mov	#8,r0
+	cmp/hs	r0,r2
+	bt/s	2f
+	 shlr2	r3
+	bsr	L_pop_d
+	 nop
+2:
+	add	#2,r2
+	bra	L_pass
+	 add	#-8,r8
+
+L_pop_d:
+	mov	r2,r0
+	add	r0,r0
+	add	r2,r0
+	add	#-12,r0
+	add	r0,r0
+	braf	r0
+	 nop
+	mov.l	@r15+,r4
+	rts
+	 mov.l	@r15+,r5
+	mov.l	@r15+,r5
+	rts
+	 mov.l	@r15+,r6
+	mov.l	@r15+,r6
+	rts
+	 mov.l	@r15+,r7
+	rts
+	 mov.l	@r15+,r7
+
+L_pass_i:
+	cmp/eq	#FFI_TYPE_INT,r0
+	bf	L_call_it
+
+	mov	#8,r0
+	cmp/hs	r0,r2
+	bt/s	2f
+	 shlr2	r3
+	bsr	L_pop_i
+	 nop
+2:
+	add	#1,r2
+	bra	L_pass
+	 add	#-4,r8
+
+L_pop_i:
+	mov	r2,r0
+	shll2	r0
+	add	#-16,r0
+	braf	r0
+	 nop
+	rts
+	 mov.l	@r15+,r4
+	rts
+	 mov.l	@r15+,r5
+	rts
+	 mov.l	@r15+,r6
+	rts
+	 mov.l	@r15+,r7
+
+L_call_it:
+	# call function
+#if (! STRUCT_VALUE_ADDRESS_WITH_ARG)
+	mov	r10, r2
+#endif
+	mov.l  @(28,r14),r1
+	jsr    @r1
+	 nop
+
+L_ret_d:
+	mov	#FFI_TYPE_DOUBLE,r2
+	cmp/eq	r2,r9
+	bf	L_ret_ll
+
+	mov.l	@(24,r14),r2
+	mov.l	r0, at r2
+	bra	L_epilogue
+	 mov.l	r1,@(4,r2)
+
+L_ret_ll:
+	mov	#FFI_TYPE_SINT64,r2
+	cmp/eq	r2,r9
+	bt/s	1f
+	 mov	#FFI_TYPE_UINT64,r2
+	cmp/eq	r2,r9
+	bf	L_ret_i
+
+1:
+	mov.l	@(24,r14),r2
+	mov.l	r0, at r2
+	bra	L_epilogue
+	 mov.l	r1,@(4,r2)
+
+L_ret_i:
+	mov	#FFI_TYPE_FLOAT,r2
+	cmp/eq	r2,r9
+	bt	1f
+	mov	#FFI_TYPE_INT,r2
+	cmp/eq	r2,r9
+	bf	L_epilogue
+1:
+	mov.l	@(24,r14),r1
+	bra	L_epilogue
+	 mov.l	r0, at r1
+
+L_epilogue:
+	# Remove the space we pushed for the args
+	mov   r14,r15
+
+	lds.l  @r15+,pr
+	mov.l  @r15+,r14
+	mov.l  @r15+,r12
+	mov.l  @r15+,r10
+	mov.l  @r15+,r9
+	rts
+	 mov.l  @r15+,r8
+#endif
+.LFE1:
+.ffi_call_SYSV_end:
+        .size    CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+
+.globl	ffi_closure_helper_SYSV
+
+ENTRY(ffi_closure_SYSV)
+.LFB2:
+	mov.l	r7, at -r15
+.LCFI7:
+	mov.l	r6, at -r15
+.LCFI8:
+	mov.l	r5, at -r15
+.LCFI9:
+	mov.l	r4, at -r15
+.LCFIA:
+	mov.l	r14, at -r15
+.LCFIB:
+	sts.l	pr, at -r15
+
+	/* Stack layout:	
+	   xx bytes (on stack parameters)
+	   16 bytes (register parameters)
+	    4 bytes (saved frame pointer)
+	    4 bytes (saved return address)
+	   32 bytes (floating register parameters, SH-4 only)
+	    8 bytes (result)
+	    4 bytes (pad)
+	    4 bytes (5th arg)
+	   <- new stack pointer
+	*/
+.LCFIC:
+#if defined(__SH4__)
+	add	#-48,r15
+#else
+	add	#-16,r15
+#endif
+.LCFID:
+	mov	r15,r14
+.LCFIE:
+
+#if defined(__SH4__)
+	mov	r14,r1
+	add	#48,r1
+#ifdef __LITTLE_ENDIAN__
+	fmov.s	fr10, at -r1
+	fmov.s	fr11, at -r1
+	fmov.s	fr8, at -r1
+	fmov.s	fr9, at -r1
+	fmov.s	fr6, at -r1
+	fmov.s	fr7, at -r1
+	fmov.s	fr4, at -r1
+	fmov.s	fr5, at -r1
+#else
+	fmov.s	fr11, at -r1
+	fmov.s	fr10, at -r1
+	fmov.s	fr9, at -r1
+	fmov.s	fr8, at -r1
+	fmov.s	fr7, at -r1
+	fmov.s	fr6, at -r1
+	fmov.s	fr5, at -r1
+	fmov.s	fr4, at -r1
+#endif
+	mov	r1,r7
+	mov	r14,r6
+	add	#56,r6
+#else
+	mov	r14,r6
+	add	#24,r6
+#endif
+
+	bt/s	10f
+	 mov	r2, r5
+	mov	r14,r1
+	add	#8,r1
+	mov	r1,r5
+10:
+
+	mov	r14,r1
+#if defined(__SH4__)
+	add	#72,r1
+#else
+	add	#40,r1
+#endif
+	mov.l	r1, at r14
+
+#ifdef PIC
+	mov.l	L_got,r1
+	mova	L_got,r0
+	add	r0,r1
+	mov.l	L_helper,r0
+	add	r1,r0
+#else
+	mov.l	L_helper,r0
+#endif
+	jsr	@r0
+	 mov	r3,r4
+
+	shll	r0
+	mov	r0,r1
+	mova	L_table,r0
+	add	r1,r0
+	mov.w	@r0,r0
+	mov	r14,r2
+	braf	r0
+	 add	#8,r2
+0:
+	.align 2
+#ifdef PIC
+L_got:
+	.long	_GLOBAL_OFFSET_TABLE_
+L_helper:
+	.long	ffi_closure_helper_SYSV at GOTOFF
+#else
+L_helper:
+	.long	ffi_closure_helper_SYSV
+#endif
+L_table:
+	.short L_case_v - 0b	/* FFI_TYPE_VOID */
+	.short L_case_i - 0b	/* FFI_TYPE_INT */
+#if defined(__SH4__)
+	.short L_case_f - 0b	/* FFI_TYPE_FLOAT */
+	.short L_case_d - 0b	/* FFI_TYPE_DOUBLE */
+	.short L_case_d - 0b	/* FFI_TYPE_LONGDOUBLE */
+#else
+	.short L_case_i - 0b	/* FFI_TYPE_FLOAT */
+	.short L_case_ll - 0b	/* FFI_TYPE_DOUBLE */
+	.short L_case_ll - 0b	/* FFI_TYPE_LONGDOUBLE */
+#endif
+	.short L_case_uq - 0b	/* FFI_TYPE_UINT8 */
+	.short L_case_q - 0b	/* FFI_TYPE_SINT8 */
+	.short L_case_uh - 0b	/* FFI_TYPE_UINT16 */
+	.short L_case_h - 0b	/* FFI_TYPE_SINT16 */
+	.short L_case_i - 0b	/* FFI_TYPE_UINT32 */
+	.short L_case_i - 0b	/* FFI_TYPE_SINT32 */
+	.short L_case_ll - 0b	/* FFI_TYPE_UINT64 */
+	.short L_case_ll - 0b	/* FFI_TYPE_SINT64 */
+	.short L_case_v - 0b	/* FFI_TYPE_STRUCT */
+	.short L_case_i - 0b	/* FFI_TYPE_POINTER */
+
+#if defined(__SH4__)
+L_case_d:
+#ifdef __LITTLE_ENDIAN__
+	fmov.s	@r2+,fr1
+	bra	L_case_v
+	 fmov.s	@r2,fr0
+#else
+	fmov.s	@r2+,fr0
+	bra	L_case_v
+	 fmov.s	@r2,fr1
+#endif
+
+L_case_f:
+	bra	L_case_v
+	 fmov.s	@r2,fr0
+#endif
+	
+L_case_ll:
+	mov.l	@r2+,r0
+	bra	L_case_v
+	 mov.l	@r2,r1
+	
+L_case_i:
+	bra	L_case_v
+	 mov.l	@r2,r0
+	
+L_case_q:
+#ifdef __LITTLE_ENDIAN__
+#else
+	add	#3,r2
+#endif
+	bra	L_case_v
+	 mov.b	@r2,r0
+
+L_case_uq:
+#ifdef __LITTLE_ENDIAN__
+#else
+	add	#3,r2
+#endif
+	mov.b	@r2,r0
+	bra	L_case_v
+	 extu.b r0,r0
+
+L_case_h:
+#ifdef __LITTLE_ENDIAN__
+#else
+	add	#2,r2
+#endif
+	bra	L_case_v
+	 mov.w	@r2,r0
+
+L_case_uh:
+#ifdef __LITTLE_ENDIAN__
+#else
+	add	#2,r2
+#endif
+	mov.w	@r2,r0
+	extu.w	r0,r0
+	/* fall through */
+
+L_case_v:
+#if defined(__SH4__)
+	add	#48,r15
+#else
+	add	#16,r15
+#endif
+	lds.l	@r15+,pr
+	mov.l	@r15+,r14
+	rts
+	 add	#16,r15
+.LFE2:
+.ffi_closure_SYSV_end:
+        .size    CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
+
+#if defined __ELF__ && defined __linux__
+	.section	.note.GNU-stack,"", at progbits
+#endif
+
+	.section	".eh_frame","aw", at progbits
+__FRAME_BEGIN__:
+	.4byte	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
+.LSCIE1:
+	.4byte	0x0	/* CIE Identifier Tag */
+	.byte	0x1	/* CIE Version */
+#ifdef PIC
+	.ascii "zR\0"	/* CIE Augmentation */
+#else
+	.byte	0x0	/* CIE Augmentation */
+#endif
+	.byte	0x1	/* uleb128 0x1; CIE Code Alignment Factor */
+	.byte	0x7c	/* sleb128 -4; CIE Data Alignment Factor */
+	.byte	0x11	/* CIE RA Column */
+#ifdef PIC
+	.uleb128 0x1	/* Augmentation size */
+	.byte	0x10	/* FDE Encoding (pcrel) */
+#endif
+	.byte	0xc	/* DW_CFA_def_cfa */
+	.byte	0xf	/* uleb128 0xf */
+	.byte	0x0	/* uleb128 0x0 */
+	.align	2
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	/* FDE Length */
+.LASFDE1:
+	.4byte	.LASFDE1-__FRAME_BEGIN__	/* FDE CIE offset */
+#ifdef PIC
+	.4byte	.LFB1-.	/* FDE initial location */
+#else
+	.4byte	.LFB1	/* FDE initial location */
+#endif
+	.4byte	.LFE1-.LFB1	 /* FDE address range */
+#ifdef PIC
+	.uleb128 0x0	/* Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI0-.LFB1
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x4	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI1-.LCFI0
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI2-.LCFI1
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0xc	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI3-.LCFI2
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x10	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI4-.LCFI3
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x14	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI5-.LCFI4
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x18	/* uleb128 0x4 */
+	.byte	0x91	/* DW_CFA_offset, column 0x11 */
+	.byte	0x6	/* uleb128 0x6 */
+	.byte	0x8e	/* DW_CFA_offset, column 0xe */
+	.byte	0x5	/* uleb128 0x5 */
+	.byte	0x8c	/* DW_CFA_offset, column 0xc */
+	.byte	0x4	/* uleb128 0x4 */
+	.byte	0x8a	/* DW_CFA_offset, column 0xa */
+	.byte	0x3	/* uleb128 0x3 */
+	.byte	0x89	/* DW_CFA_offset, column 0x9 */
+	.byte	0x2	/* uleb128 0x2 */
+	.byte	0x88	/* DW_CFA_offset, column 0x8 */
+	.byte	0x1	/* uleb128 0x1 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI6-.LCFI5
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0xe	/* uleb128 0xe */
+	.align	2
+.LEFDE1:
+
+.LSFDE3:
+	.4byte	.LEFDE3-.LASFDE3	/* FDE Length */
+.LASFDE3:
+	.4byte	.LASFDE3-__FRAME_BEGIN__	/* FDE CIE offset */
+#ifdef PIC
+	.4byte	.LFB2-.	/* FDE initial location */
+#else
+	.4byte	.LFB2	/* FDE initial location */
+#endif
+	.4byte	.LFE2-.LFB2	 /* FDE address range */
+#ifdef PIC
+	.uleb128 0x0	/* Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI7-.LFB2
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x4	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI8-.LCFI7
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI9-.LCFI8
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0xc	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFIA-.LCFI9
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x10	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFIB-.LCFIA
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x14	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFIC-.LCFIB
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x18	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFID-.LCFIC
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+#if defined(__SH4__)
+	.byte	24+48	/* uleb128 24+48 */
+#else
+	.byte	24+16	/* uleb128 24+16 */
+#endif
+	.byte	0x91	/* DW_CFA_offset, column 0x11 */
+	.byte	0x6	/* uleb128 0x6 */
+	.byte	0x8e	/* DW_CFA_offset, column 0xe */
+	.byte	0x5	/* uleb128 0x5 */
+	.byte	0x84	/* DW_CFA_offset, column 0x4 */
+	.byte	0x4	/* uleb128 0x4 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 */
+	.byte	0x3	/* uleb128 0x3 */
+	.byte	0x86	/* DW_CFA_offset, column 0x6 */
+	.byte	0x2	/* uleb128 0x2 */
+	.byte	0x87	/* DW_CFA_offset, column 0x7 */
+	.byte	0x1	/* uleb128 0x1 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFIE-.LCFID
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0xe	/* uleb128 0xe */
+	.align	2
+.LEFDE3:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh64/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh64/ffi.c
new file mode 100755
index 0000000..8fbc05c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh64/ffi.c
@@ -0,0 +1,468 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2003, 2004, 2006, 2007 Kaz Kojima
+           Copyright (c) 2008 Anthony Green
+   
+   SuperH SHmedia Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+#define NGREGARG 8
+#define NFREGARG 12
+
+static int
+return_type (ffi_type *arg)
+{
+
+  if (arg->type != FFI_TYPE_STRUCT)
+    return arg->type;
+
+  /* gcc uses r2 if the result can be packed in on register.  */
+  if (arg->size <= sizeof (UINT8))
+    return FFI_TYPE_UINT8;
+  else if (arg->size <= sizeof (UINT16))
+    return FFI_TYPE_UINT16;
+  else if (arg->size <= sizeof (UINT32))
+    return FFI_TYPE_UINT32;
+  else if (arg->size <= sizeof (UINT64))
+    return FFI_TYPE_UINT64;
+
+  return FFI_TYPE_STRUCT;
+}
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+void ffi_prep_args(char *stack, extended_cif *ecif)
+{
+  register unsigned int i;
+  register unsigned int avn;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+
+  argp = stack;
+
+  if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT)
+    {
+      *(void **) argp = ecif->rvalue;
+      argp += sizeof (UINT64);
+    }
+
+  avn = ecif->cif->nargs;
+  p_argv = ecif->avalue;
+
+  for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
+    {
+      size_t z;
+      int align;
+
+      z = (*p_arg)->size;
+      align = (*p_arg)->alignment;
+      if (z < sizeof (UINT32))
+	{
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(SINT64 *) argp = (SINT64) *(SINT8 *)(*p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT8:
+	      *(UINT64 *) argp = (UINT64) *(UINT8 *)(*p_argv);
+	      break;
+  
+	    case FFI_TYPE_SINT16:
+	      *(SINT64 *) argp = (SINT64) *(SINT16 *)(*p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT16:
+	      *(UINT64 *) argp = (UINT64) *(UINT16 *)(*p_argv);
+	      break;
+  
+	    case FFI_TYPE_STRUCT:
+	      memcpy (argp, *p_argv, z);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  argp += sizeof (UINT64);
+	}
+      else if (z == sizeof (UINT32) && align == sizeof (UINT32))
+	{
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_INT:
+	    case FFI_TYPE_SINT32:
+	      *(SINT64 *) argp = (SINT64) *(SINT32 *) (*p_argv);
+	      break;
+
+	    case FFI_TYPE_FLOAT:
+	    case FFI_TYPE_POINTER:
+	    case FFI_TYPE_UINT32:
+	    case FFI_TYPE_STRUCT:
+	      *(UINT64 *) argp = (UINT64) *(UINT32 *) (*p_argv);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	      break;
+	    }
+	  argp += sizeof (UINT64);
+	}
+      else if (z == sizeof (UINT64)
+	       && align == sizeof (UINT64)
+	       && ((int) *p_argv & (sizeof (UINT64) - 1)) == 0)
+	{
+	  *(UINT64 *) argp = *(UINT64 *) (*p_argv);
+	  argp += sizeof (UINT64);
+	}
+      else
+	{
+	  int n = (z + sizeof (UINT64) - 1) / sizeof (UINT64);
+
+	  memcpy (argp, *p_argv, z);
+	  argp += n * sizeof (UINT64);
+	}
+    }
+
+  return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  int i, j;
+  int size, type;
+  int n, m;
+  int greg;
+  int freg;
+  int fpair = -1;
+
+  greg = (return_type (cif->rtype) == FFI_TYPE_STRUCT ? 1 : 0);
+  freg = 0;
+  cif->flags2 = 0;
+
+  for (i = j = 0; i < cif->nargs; i++)
+    {
+      type = (cif->arg_types)[i]->type;
+      switch (type)
+	{
+	case FFI_TYPE_FLOAT:
+	  greg++;
+	  cif->bytes += sizeof (UINT64) - sizeof (float);
+	  if (freg >= NFREGARG - 1)
+	    continue;
+	  if (fpair < 0)
+	    {
+	      fpair = freg;
+	      freg += 2;
+	    }
+	  else
+	    fpair = -1;
+	  cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++);
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  if (greg++ >= NGREGARG && (freg + 1) >= NFREGARG)
+	    continue;
+	  if ((freg + 1) < NFREGARG)
+	    {
+	      freg += 2;
+	      cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++);
+	    }
+	  else
+	    cif->flags2 += FFI_TYPE_INT << (2 * j++);
+	  break;
+	      
+	default:
+	  size = (cif->arg_types)[i]->size;
+	  if (size < sizeof (UINT64))
+	    cif->bytes += sizeof (UINT64) - size;
+	  n = (size + sizeof (UINT64) - 1) / sizeof (UINT64);
+	  if (greg >= NGREGARG)
+	    continue;
+	  else if (greg + n - 1 >= NGREGARG)
+	    greg = NGREGARG;
+	  else
+	    greg += n;
+	  for (m = 0; m < n; m++)
+	    cif->flags2 += FFI_TYPE_INT << (2 * j++);
+	  break;
+	}
+    }
+
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_STRUCT:
+      cif->flags = return_type (cif->rtype);
+      break;
+
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      cif->flags = cif->rtype->type;
+      break;
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), 
+			  /*@out@*/ extended_cif *, 
+			  unsigned, unsigned, long long,
+			  /*@out@*/ unsigned *, 
+			  void (*fn)(void));
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif, 
+	      void (*fn)(void), 
+	      /*@out@*/ void *rvalue, 
+	      /*@dependent@*/ void **avalue)
+{
+  extended_cif ecif;
+  UINT64 trvalue;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if (cif->rtype->type == FFI_TYPE_STRUCT
+      && return_type (cif->rtype) != FFI_TYPE_STRUCT)
+    ecif.rvalue = &trvalue;
+  else if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      ecif.rvalue = alloca(cif->rtype->size);
+    }
+  else
+    ecif.rvalue = rvalue;
+
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, cif->flags2,
+		    ecif.rvalue, fn);
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+
+  if (rvalue
+      && cif->rtype->type == FFI_TYPE_STRUCT
+      && return_type (cif->rtype) != FFI_TYPE_STRUCT)
+    memcpy (rvalue, &trvalue, cif->rtype->size);
+}
+
+extern void ffi_closure_SYSV (void);
+extern void __ic_invalidate (void *line);
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure *closure,
+		      ffi_cif *cif,
+		      void (*fun)(ffi_cif*, void*, void**, void*),
+		      void *user_data,
+		      void *codeloc)
+{
+  unsigned int *tramp;
+
+  FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
+
+  tramp = (unsigned int *) &closure->tramp[0];
+  /* Since ffi_closure is an aligned object, the ffi trampoline is
+     called as an SHcompact code.  Sigh.
+     SHcompact part:
+     mova @(1,pc),r0; add #1,r0; jmp @r0; nop;
+     SHmedia part:
+     movi fnaddr >> 16,r1; shori fnaddr,r1; ptabs/l r1,tr0
+     movi cxt >> 16,r1; shori cxt,r1; blink tr0,r63  */
+#ifdef __LITTLE_ENDIAN__
+  tramp[0] = 0x7001c701;
+  tramp[1] = 0x0009402b;
+#else
+  tramp[0] = 0xc7017001;
+  tramp[1] = 0x402b0009;
+#endif
+  tramp[2] = 0xcc000010 | (((UINT32) ffi_closure_SYSV) >> 16) << 10;
+  tramp[3] = 0xc8000010 | (((UINT32) ffi_closure_SYSV) & 0xffff) << 10;
+  tramp[4] = 0x6bf10600;
+  tramp[5] = 0xcc000010 | (((UINT32) codeloc) >> 16) << 10;
+  tramp[6] = 0xc8000010 | (((UINT32) codeloc) & 0xffff) << 10;
+  tramp[7] = 0x4401fff0;
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  /* Flush the icache.  */
+  asm volatile ("ocbwb %0,0; synco; icbi %1,0; synci" : : "r" (tramp),
+		"r"(codeloc));
+
+  return FFI_OK;
+}
+
+/* Basically the trampoline invokes ffi_closure_SYSV, and on 
+ * entry, r3 holds the address of the closure.
+ * After storing the registers that could possibly contain
+ * parameters to be passed into the stack frame and setting
+ * up space for a return value, ffi_closure_SYSV invokes the 
+ * following helper function to do most of the work.
+ */
+
+int
+ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue, 
+			 UINT64 *pgr, UINT64 *pfr, UINT64 *pst)
+{
+  void **avalue;
+  ffi_type **p_arg;
+  int i, avn;
+  int greg, freg;
+  ffi_cif *cif;
+  int fpair = -1;
+
+  cif = closure->cif;
+  avalue = alloca (cif->nargs * sizeof (void *));
+
+  /* Copy the caller's structure return value address so that the closure
+     returns the data directly to the caller.  */
+  if (return_type (cif->rtype) == FFI_TYPE_STRUCT)
+    {
+      rvalue = (UINT64 *) *pgr;
+      greg = 1;
+    }
+  else
+    greg = 0;
+
+  freg = 0;
+  cif = closure->cif;
+  avn = cif->nargs;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+    {
+      size_t z;
+      void *p;
+
+      z = (*p_arg)->size;
+      if (z < sizeof (UINT32))
+	{
+	  p = pgr + greg++;
+
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	    case FFI_TYPE_UINT8:
+	    case FFI_TYPE_SINT16:
+	    case FFI_TYPE_UINT16:
+	    case FFI_TYPE_STRUCT:
+#ifdef __LITTLE_ENDIAN__
+	      avalue[i] = p;
+#else
+	      avalue[i] = ((char *) p) + sizeof (UINT32) - z;
+#endif
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	}
+      else if (z == sizeof (UINT32))
+	{
+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	    {
+	      if (freg < NFREGARG - 1)
+		{
+		  if (fpair >= 0)
+		    {
+		      avalue[i] = (UINT32 *) pfr + fpair;
+		      fpair = -1;
+		    }
+		  else
+		    {
+#ifdef __LITTLE_ENDIAN__
+		      fpair = freg;
+		      avalue[i] = (UINT32 *) pfr + (1 ^ freg);
+#else
+		      fpair = 1 ^ freg;
+		      avalue[i] = (UINT32 *) pfr + freg;
+#endif
+		      freg += 2;
+		    }
+		}
+	      else
+#ifdef __LITTLE_ENDIAN__
+		avalue[i] = pgr + greg;
+#else
+		avalue[i] = (UINT32 *) (pgr + greg) + 1;
+#endif
+	    }
+	  else
+#ifdef __LITTLE_ENDIAN__
+	    avalue[i] = pgr + greg;
+#else
+	    avalue[i] = (UINT32 *) (pgr + greg) + 1;
+#endif
+	  greg++;
+	}
+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+	{
+	  if (freg + 1 >= NFREGARG)
+	    avalue[i] = pgr + greg;
+	  else
+	    {
+	      avalue[i] = pfr + (freg >> 1);
+	      freg += 2;
+	    }
+	  greg++;
+	}
+      else
+	{
+	  int n = (z + sizeof (UINT64) - 1) / sizeof (UINT64);
+
+	  avalue[i] = pgr + greg;
+	  greg += n;
+	}
+    }
+
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_SYSV how to perform return type promotions.  */
+  return return_type (cif->rtype);
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh64/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh64/ffitarget.h
new file mode 100755
index 0000000..d935b89
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh64/ffitarget.h
@@ -0,0 +1,53 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for SuperH - SHmedia.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_SYSV
+} ffi_abi;
+
+#define FFI_EXTRA_CIF_FIELDS long long flags2
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 32
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh64/sysv.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh64/sysv.S
new file mode 100755
index 0000000..c4587d5
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sh64/sysv.S
@@ -0,0 +1,539 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2003, 2004, 2006, 2008 Kaz Kojima
+   
+   SuperH SHmedia Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+ 
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+/* XXX these lose for some platforms, I'm sure. */
+#define CNAME(x) x
+#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define OFS_FLT	0
+#else
+#define OFS_FLT	4
+#endif
+
+	.section	.text..SHmedia32,"ax"
+
+	# r2:	ffi_prep_args
+	# r3:	&ecif
+	# r4:	bytes
+	# r5:	flags
+	# r6:	flags2
+	# r7:	rvalue
+	# r8:	fn
+
+	# This assumes we are using gas.
+	.align	5
+ENTRY(ffi_call_SYSV)
+	# Save registers
+.LFB1:
+	addi.l	r15, -48, r15
+.LCFI0:
+	st.q	r15, 40, r32
+	st.q	r15, 32, r31
+	st.q	r15, 24, r30
+	st.q	r15, 16, r29
+	st.q	r15, 8, r28
+	st.l	r15, 4, r18
+	st.l	r15, 0, r14
+.LCFI1:
+	add.l	r15, r63, r14
+.LCFI2:
+#	add	r4, r63, r28
+	add	r5, r63, r29
+	add	r6, r63, r30
+	add	r7, r63, r31
+	add	r8, r63, r32
+
+	addi	r4, (64 + 7), r4
+	andi	r4, ~7, r4
+	sub.l	r15, r4, r15
+
+	ptabs/l	r2, tr0
+	add	r15, r63, r2
+	blink	tr0, r18
+
+	addi	r15, 64, r22
+	movi	0, r0
+	movi	0, r1
+	movi	-1, r23
+
+	pt/l	1f, tr1
+	bnei/l	r29, FFI_TYPE_STRUCT, tr1
+	ld.l	r15, 0, r19
+	addi	r15, 8, r15
+	addi	r0, 1, r0
+1:
+
+.L_pass:
+	andi	r30, 3, r20
+	shlri	r30, 2, r30
+
+	pt/l	.L_call_it, tr0
+	pt/l	.L_pass_i, tr1
+	pt/l	.L_pass_f, tr2
+
+	beqi/l	r20, FFI_TYPE_VOID, tr0
+	beqi/l	r20, FFI_TYPE_INT, tr1
+	beqi/l	r20, FFI_TYPE_FLOAT, tr2
+
+.L_pass_d:
+	addi	r0, 1, r0
+	pt/l	3f, tr0
+	movi	12, r20
+	bge/l	r1, r20, tr0
+
+	pt/l	.L_pop_d, tr1
+	pt/l	2f, tr0
+	blink	tr1, r63
+2:
+	addi.l	r15, 8, r15
+3:
+	pt/l	.L_pass, tr0
+	addi	r1, 2, r1
+	blink	tr0, r63
+
+.L_pop_d:
+	pt/l	.L_pop_d_tbl, tr1
+	gettr	tr1, r20
+	shlli	r1, 2, r21
+	add	r20, r21, r20
+	ptabs/l	r20, tr1
+	blink	tr1, r63
+
+.L_pop_d_tbl:
+	fld.d	r15, 0, dr0
+	blink	tr0, r63
+	fld.d	r15, 0, dr2
+	blink	tr0, r63
+	fld.d	r15, 0, dr4
+	blink	tr0, r63
+	fld.d	r15, 0, dr6
+	blink	tr0, r63
+	fld.d	r15, 0, dr8
+	blink	tr0, r63
+	fld.d	r15, 0, dr10
+	blink	tr0, r63
+
+.L_pass_f:
+	addi	r0, 1, r0
+	pt/l	3f, tr0
+	movi	12, r20
+	bge/l	r1, r20, tr0
+
+	pt/l	.L_pop_f, tr1
+	pt/l	2f, tr0
+	blink	tr1, r63
+2:
+	addi.l	r15, 8, r15
+3:
+	pt/l	.L_pass, tr0
+	blink	tr0, r63
+
+.L_pop_f:
+	pt/l	.L_pop_f_tbl, tr1
+	pt/l	5f, tr2
+	gettr	tr1, r20
+	bge/l	r23, r63, tr2
+	add	r1, r63, r23 
+	shlli	r1, 3, r21
+	addi	r1, 2, r1
+	add	r20, r21, r20
+	ptabs/l	r20, tr1
+	blink	tr1, r63
+5:
+	addi	r23, 1, r21
+	movi	-1, r23
+	shlli	r21, 3, r21
+	add	r20, r21, r20
+	ptabs/l	r20, tr1
+	blink	tr1, r63
+
+.L_pop_f_tbl:
+	fld.s	r15, OFS_FLT, fr0
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr1
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr2
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr3
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr4
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr5
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr6
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr7
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr8
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr9
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr10
+	blink	tr0, r63
+	fld.s	r15, OFS_FLT, fr11
+	blink	tr0, r63
+
+.L_pass_i:
+	pt/l	3f, tr0
+	movi	8, r20
+	bge/l	r0, r20, tr0
+
+	pt/l	.L_pop_i, tr1
+	pt/l	2f, tr0
+	blink	tr1, r63
+2:
+	addi.l	r15, 8, r15
+3:
+	pt/l	.L_pass, tr0
+	addi	r0, 1, r0
+	blink	tr0, r63
+
+.L_pop_i:
+	pt/l	.L_pop_i_tbl, tr1
+	gettr	tr1, r20
+	shlli	r0, 3, r21
+	add	r20, r21, r20
+	ptabs/l	r20, tr1
+	blink	tr1, r63
+
+.L_pop_i_tbl:
+	ld.q	r15, 0, r2
+	blink	tr0, r63
+	ld.q	r15, 0, r3
+	blink	tr0, r63
+	ld.q	r15, 0, r4
+	blink	tr0, r63
+	ld.q	r15, 0, r5
+	blink	tr0, r63
+	ld.q	r15, 0, r6
+	blink	tr0, r63
+	ld.q	r15, 0, r7
+	blink	tr0, r63
+	ld.q	r15, 0, r8
+	blink	tr0, r63
+	ld.q	r15, 0, r9
+	blink	tr0, r63
+
+.L_call_it:
+	# call function
+	pt/l	1f, tr1
+	bnei/l	r29, FFI_TYPE_STRUCT, tr1
+	add	r19, r63, r2
+1:
+	add	r22, r63, r15
+	ptabs/l	r32, tr0
+	blink	tr0, r18
+
+	pt/l	.L_ret_i, tr0
+	pt/l	.L_ret_ll, tr1
+	pt/l	.L_ret_d, tr2
+	pt/l	.L_ret_f, tr3
+	pt/l	.L_epilogue, tr4
+
+	beqi/l	r29, FFI_TYPE_INT, tr0
+	beqi/l	r29, FFI_TYPE_UINT32, tr0
+	beqi/l	r29, FFI_TYPE_SINT64, tr1
+	beqi/l	r29, FFI_TYPE_UINT64, tr1
+	beqi/l	r29, FFI_TYPE_DOUBLE, tr2
+	beqi/l	r29, FFI_TYPE_FLOAT, tr3
+
+	pt/l	.L_ret_q, tr0
+	pt/l	.L_ret_h, tr1
+
+	beqi/l	r29, FFI_TYPE_UINT8, tr0
+	beqi/l	r29, FFI_TYPE_UINT16, tr1
+	blink	tr4, r63
+
+.L_ret_d:
+	fst.d	r31, 0, dr0
+	blink	tr4, r63
+
+.L_ret_ll:
+	st.q	r31, 0, r2
+	blink	tr4, r63
+
+.L_ret_f:
+	fst.s	r31, OFS_FLT, fr0
+	blink	tr4, r63
+
+.L_ret_q:
+	st.b	r31, 0, r2
+	blink	tr4, r63
+
+.L_ret_h:
+	st.w	r31, 0, r2
+	blink	tr4, r63
+
+.L_ret_i:
+	st.l	r31, 0, r2
+	# Fall
+
+.L_epilogue:
+	# Remove the space we pushed for the args
+	add	r14, r63, r15
+
+	ld.l	r15, 0, r14
+	ld.l	r15, 4, r18
+	ld.q	r15, 8, r28
+	ld.q	r15, 16, r29
+	ld.q	r15, 24, r30
+	ld.q	r15, 32, r31
+	ld.q	r15, 40, r32
+	addi.l	r15, 48, r15
+	ptabs	r18, tr0
+	blink	tr0, r63
+
+.LFE1:
+.ffi_call_SYSV_end:
+	.size	 CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+
+	.align	5
+ENTRY(ffi_closure_SYSV)
+.LFB2:
+	addi.l	r15, -136, r15
+.LCFI3:
+	st.l	r15, 12, r18
+	st.l	r15, 8, r14
+	st.l	r15, 4, r12
+.LCFI4:
+	add	r15, r63, r14
+.LCFI5:
+	/* Stack layout:	
+	   ...
+	   64 bytes (register parameters)
+	   48 bytes (floating register parameters)
+	    8 bytes (result)
+	    4 bytes (r18)
+	    4 bytes (r14)
+	    4 bytes (r12)
+	    4 bytes (for align)
+	   <- new stack pointer
+	*/
+	fst.d	r14, 24, dr0
+	fst.d	r14, 32, dr2
+	fst.d	r14, 40, dr4
+	fst.d	r14, 48, dr6
+	fst.d	r14, 56, dr8
+	fst.d	r14, 64, dr10
+	st.q	r14, 72, r2
+	st.q	r14, 80, r3
+	st.q	r14, 88, r4
+	st.q	r14, 96, r5
+	st.q	r14, 104, r6
+	st.q	r14, 112, r7
+	st.q	r14, 120, r8
+	st.q	r14, 128, r9
+
+	add	r1, r63, r2
+	addi	r14, 16, r3
+	addi	r14, 72, r4
+	addi	r14, 24, r5
+	addi	r14, 136, r6
+#ifdef PIC
+	movi	(((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) >> 16) & 65535), r12
+        shori	((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) & 65535), r12
+.LPCS0:	ptrel/u r12, tr0
+	movi	((ffi_closure_helper_SYSV at GOTPLT) & 65535), r1
+	gettr	tr0, r12
+	ldx.l	r1, r12, r1
+	ptabs	r1, tr0
+#else
+	pt/l	ffi_closure_helper_SYSV, tr0
+#endif
+	blink	tr0, r18
+
+	shlli	r2, 1, r1
+        movi    (((datalabel .L_table) >> 16) & 65535), r2
+        shori   ((datalabel .L_table) & 65535), r2
+        ldx.w   r2, r1, r1
+        add     r1, r2, r1
+	pt/l	.L_case_v, tr1
+        ptabs   r1, tr0
+        blink   tr0, r63
+
+        .align 2
+.L_table:
+	.word	.L_case_v - datalabel .L_table	/* FFI_TYPE_VOID */
+	.word	.L_case_i - datalabel .L_table	/* FFI_TYPE_INT */
+	.word	.L_case_f - datalabel .L_table	/* FFI_TYPE_FLOAT */
+	.word	.L_case_d - datalabel .L_table	/* FFI_TYPE_DOUBLE */
+	.word	.L_case_d - datalabel .L_table	/* FFI_TYPE_LONGDOUBLE */
+	.word	.L_case_uq - datalabel .L_table	/* FFI_TYPE_UINT8 */
+	.word	.L_case_q - datalabel .L_table	/* FFI_TYPE_SINT8 */
+	.word	.L_case_uh - datalabel .L_table	/* FFI_TYPE_UINT16 */
+	.word	.L_case_h - datalabel .L_table	/* FFI_TYPE_SINT16 */
+	.word	.L_case_i - datalabel .L_table	/* FFI_TYPE_UINT32 */
+	.word	.L_case_i - datalabel .L_table	/* FFI_TYPE_SINT32 */
+	.word	.L_case_ll - datalabel .L_table	/* FFI_TYPE_UINT64 */
+	.word	.L_case_ll - datalabel .L_table	/* FFI_TYPE_SINT64 */
+	.word	.L_case_v - datalabel .L_table	/* FFI_TYPE_STRUCT */
+	.word	.L_case_i - datalabel .L_table	/* FFI_TYPE_POINTER */
+
+        .align 2
+.L_case_d:
+	fld.d	r14, 16, dr0
+	blink	tr1, r63
+.L_case_f:
+	fld.s	r14, 16, fr0
+	blink	tr1, r63
+.L_case_ll:
+	ld.q	r14, 16, r2
+	blink	tr1, r63
+.L_case_i:
+	ld.l	r14, 16, r2
+	blink	tr1, r63
+.L_case_q:
+	ld.b	r14, 16, r2
+	blink	tr1, r63
+.L_case_uq:
+	ld.ub	r14, 16, r2
+	blink	tr1, r63
+.L_case_h:
+	ld.w	r14, 16, r2
+	blink	tr1, r63
+.L_case_uh:
+	ld.uw	r14, 16, r2
+	blink	tr1, r63
+.L_case_v:
+	add.l	r14, r63, r15
+	ld.l	r15, 4, r12
+	ld.l	r15, 8, r14
+	ld.l	r15, 12, r18
+	addi.l	r15, 136, r15
+	ptabs	r18, tr0
+	blink	tr0, r63
+
+.LFE2:
+.ffi_closure_SYSV_end:
+	.size	 CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
+
+#if defined __ELF__ && defined __linux__
+	.section	.note.GNU-stack,"", at progbits
+#endif
+
+	.section	".eh_frame","aw", at progbits
+__FRAME_BEGIN__:
+	.4byte	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
+.LSCIE1:
+	.4byte	0x0	/* CIE Identifier Tag */
+	.byte	0x1	/* CIE Version */
+#ifdef PIC
+	.ascii "zR\0"	/* CIE Augmentation */
+#else
+	.byte	0x0	/* CIE Augmentation */
+#endif
+	.uleb128 0x1	/* CIE Code Alignment Factor */
+	.sleb128 -4	/* CIE Data Alignment Factor */
+	.byte	0x12	/* CIE RA Column */
+#ifdef PIC
+	.uleb128 0x1	/* Augmentation size */
+	.byte	0x10	/* FDE Encoding (pcrel) */
+#endif
+	.byte	0xc	/* DW_CFA_def_cfa */
+	.uleb128 0xf
+	.uleb128 0x0
+	.align	2
+.LECIE1:
+.LSFDE1:
+	.4byte	datalabel .LEFDE1-datalabel .LASFDE1	/* FDE Length */
+.LASFDE1:
+	.4byte	datalabel .LASFDE1-datalabel __FRAME_BEGIN__
+#ifdef PIC
+	.4byte	.LFB1-.	/* FDE initial location */
+#else
+	.4byte	.LFB1	/* FDE initial location */
+#endif
+	.4byte	datalabel .LFE1-datalabel .LFB1	/* FDE address range */
+#ifdef PIC
+	.uleb128 0x0	/* Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	datalabel .LCFI0-datalabel .LFB1
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.uleb128 0x30
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	datalabel .LCFI1-datalabel .LCFI0
+	.byte   0x8e	/* DW_CFA_offset, column 0xe */
+	.uleb128 0xc
+	.byte   0x92	/* DW_CFA_offset, column 0x12 */
+	.uleb128 0xb
+	.byte   0x9c	/* DW_CFA_offset, column 0x1c */
+	.uleb128 0xa
+	.byte   0x9d	/* DW_CFA_offset, column 0x1d */
+	.uleb128 0x8
+	.byte   0x9e	/* DW_CFA_offset, column 0x1e */
+	.uleb128 0x6
+	.byte   0x9f	/* DW_CFA_offset, column 0x1f */
+	.uleb128 0x4
+	.byte   0xa0	/* DW_CFA_offset, column 0x20 */
+	.uleb128 0x2
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	datalabel .LCFI2-datalabel .LCFI1
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.uleb128 0xe
+	.align	2
+.LEFDE1:
+
+.LSFDE3:
+	.4byte	datalabel .LEFDE3-datalabel .LASFDE3	/* FDE Length */
+.LASFDE3:
+	.4byte	datalabel .LASFDE3-datalabel __FRAME_BEGIN__
+#ifdef PIC
+	.4byte	.LFB2-.	/* FDE initial location */
+#else
+	.4byte	.LFB2	/* FDE initial location */
+#endif
+	.4byte	datalabel .LFE2-datalabel .LFB2	/* FDE address range */
+#ifdef PIC
+	.uleb128 0x0	/* Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	datalabel .LCFI3-datalabel .LFB2
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.uleb128 0x88
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	datalabel .LCFI4-datalabel .LCFI3
+	.byte   0x8c	/* DW_CFA_offset, column 0xc */
+	.uleb128 0x21
+	.byte   0x8e	/* DW_CFA_offset, column 0xe */
+	.uleb128 0x20
+	.byte   0x92	/* DW_CFA_offset, column 0x12 */
+	.uleb128 0x1f
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	datalabel .LCFI5-datalabel .LCFI4
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.uleb128 0xe
+	.align	2
+.LEFDE3:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sparc/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sparc/ffi.c
new file mode 100755
index 0000000..1ac5d46
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sparc/ffi.c
@@ -0,0 +1,669 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2011 Anthony Green
+           Copyright (c) 1996, 2003-2004, 2007-2008 Red Hat, Inc.
+   
+   SPARC Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+void ffi_prep_args_v8(char *stack, extended_cif *ecif)
+{
+  int i;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+  /* Skip 16 words for the window save area */
+  argp = stack + 16*sizeof(int);
+
+  /* This should only really be done when we are returning a structure,
+     however, it's faster just to do it all the time...
+
+  if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */
+  *(int *) argp = (long)ecif->rvalue;
+
+  /* And 1 word for the  structure return value. */
+  argp += sizeof(int);
+
+#ifdef USING_PURIFY
+  /* Purify will probably complain in our assembly routine, unless we
+     zero out this memory. */
+
+  ((int*)argp)[0] = 0;
+  ((int*)argp)[1] = 0;
+  ((int*)argp)[2] = 0;
+  ((int*)argp)[3] = 0;
+  ((int*)argp)[4] = 0;
+  ((int*)argp)[5] = 0;
+#endif
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
+    {
+      size_t z;
+
+	  if ((*p_arg)->type == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	      || (*p_arg)->type == FFI_TYPE_LONGDOUBLE
+#endif
+	      )
+	    {
+	      *(unsigned int *) argp = (unsigned long)(* p_argv);
+	      z = sizeof(int);
+	    }
+	  else
+	    {
+	      z = (*p_arg)->size;
+	      if (z < sizeof(int))
+		{
+		  z = sizeof(int);
+		  switch ((*p_arg)->type)
+		    {
+		    case FFI_TYPE_SINT8:
+		      *(signed int *) argp = *(SINT8 *)(* p_argv);
+		      break;
+		      
+		    case FFI_TYPE_UINT8:
+		      *(unsigned int *) argp = *(UINT8 *)(* p_argv);
+		      break;
+		      
+		    case FFI_TYPE_SINT16:
+		      *(signed int *) argp = *(SINT16 *)(* p_argv);
+		      break;
+		      
+		    case FFI_TYPE_UINT16:
+		      *(unsigned int *) argp = *(UINT16 *)(* p_argv);
+		      break;
+
+		    default:
+		      FFI_ASSERT(0);
+		    }
+		}
+	      else
+		{
+		  memcpy(argp, *p_argv, z);
+		}
+	    }
+	  p_argv++;
+	  argp += z;
+    }
+  
+  return;
+}
+
+int ffi_prep_args_v9(char *stack, extended_cif *ecif)
+{
+  int i, ret = 0;
+  int tmp;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+  tmp = 0;
+
+  /* Skip 16 words for the window save area */
+  argp = stack + 16*sizeof(long long);
+
+#ifdef USING_PURIFY
+  /* Purify will probably complain in our assembly routine, unless we
+     zero out this memory. */
+
+  ((long long*)argp)[0] = 0;
+  ((long long*)argp)[1] = 0;
+  ((long long*)argp)[2] = 0;
+  ((long long*)argp)[3] = 0;
+  ((long long*)argp)[4] = 0;
+  ((long long*)argp)[5] = 0;
+#endif
+
+  p_argv = ecif->avalue;
+
+  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT &&
+      ecif->cif->rtype->size > 32)
+    {
+      *(unsigned long long *) argp = (unsigned long)ecif->rvalue;
+      argp += sizeof(long long);
+      tmp = 1;
+    }
+
+  for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
+       i++, p_arg++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      switch ((*p_arg)->type)
+	{
+	case FFI_TYPE_STRUCT:
+	  if (z > 16)
+	    {
+	      /* For structures larger than 16 bytes we pass reference.  */
+	      *(unsigned long long *) argp = (unsigned long)* p_argv;
+	      argp += sizeof(long long);
+	      tmp++;
+	      p_argv++;
+	      continue;
+	    }
+	  /* FALLTHROUGH */
+	case FFI_TYPE_FLOAT:
+	case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+#endif
+	  ret = 1; /* We should promote into FP regs as well as integer.  */
+	  break;
+	}
+      if (z < sizeof(long long))
+	{
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed long long *) argp = *(SINT8 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT8:
+	      *(unsigned long long *) argp = *(UINT8 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_SINT16:
+	      *(signed long long *) argp = *(SINT16 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT16:
+	      *(unsigned long long *) argp = *(UINT16 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_SINT32:
+	      *(signed long long *) argp = *(SINT32 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_UINT32:
+	      *(unsigned long long *) argp = *(UINT32 *)(* p_argv);
+	      break;
+
+	    case FFI_TYPE_FLOAT:
+	      *(float *) (argp + 4) = *(FLOAT32 *)(* p_argv); /* Right justify */
+	      break;
+
+	    case FFI_TYPE_STRUCT:
+	      memcpy(argp, *p_argv, z);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  z = sizeof(long long);
+	  tmp++;
+	}
+      else if (z == sizeof(long long))
+	{
+	  memcpy(argp, *p_argv, z);
+	  z = sizeof(long long);
+	  tmp++;
+	}
+      else
+	{
+	  if ((tmp & 1) && (*p_arg)->alignment > 8)
+	    {
+	      tmp++;
+	      argp += sizeof(long long);
+	    }
+	  memcpy(argp, *p_argv, z);
+	  z = 2 * sizeof(long long);
+	  tmp += 2;
+	}
+      p_argv++;
+      argp += z;
+    }
+
+  return ret;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  int wordsize;
+
+  if (cif->abi != FFI_V9)
+    {
+      wordsize = 4;
+
+      /* If we are returning a struct, this will already have been added.
+	 Otherwise we need to add it because it's always got to be there! */
+
+      if (cif->rtype->type != FFI_TYPE_STRUCT)
+	cif->bytes += wordsize;
+
+      /* sparc call frames require that space is allocated for 6 args,
+	 even if they aren't used. Make that space if necessary. */
+  
+      if (cif->bytes < 4*6+4)
+	cif->bytes = 4*6+4;
+    }
+  else
+    {
+      wordsize = 8;
+
+      /* sparc call frames require that space is allocated for 6 args,
+	 even if they aren't used. Make that space if necessary. */
+  
+      if (cif->bytes < 8*6)
+	cif->bytes = 8*6;
+    }
+
+  /* Adjust cif->bytes. to include 16 words for the window save area,
+     and maybe the struct/union return pointer area, */
+
+  cif->bytes += 16 * wordsize;
+
+  /* The stack must be 2 word aligned, so round bytes up
+     appropriately. */
+
+  cif->bytes = ALIGN(cif->bytes, 2 * wordsize);
+
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+    case FFI_TYPE_LONGDOUBLE:
+#endif
+      cif->flags = cif->rtype->type;
+      break;
+
+    case FFI_TYPE_STRUCT:
+      if (cif->abi == FFI_V9 && cif->rtype->size > 32)
+	cif->flags = FFI_TYPE_VOID;
+      else
+	cif->flags = FFI_TYPE_STRUCT;
+      break;
+
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_UINT16:
+      if (cif->abi == FFI_V9)
+	cif->flags = FFI_TYPE_INT;
+      else
+	cif->flags = cif->rtype->type;
+      break;
+
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      if (cif->abi == FFI_V9)
+	cif->flags = FFI_TYPE_INT;
+      else
+	cif->flags = FFI_TYPE_SINT64;
+      break;
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+  return FFI_OK;
+}
+
+int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
+{
+  ffi_type **ptr = &arg->elements[0];
+
+  while (*ptr != NULL)
+    {
+      if (off & ((*ptr)->alignment - 1))
+	off = ALIGN(off, (*ptr)->alignment);
+
+      switch ((*ptr)->type)
+	{
+	case FFI_TYPE_STRUCT:
+	  off = ffi_v9_layout_struct(*ptr, off, ret, intg, flt);
+	  off = ALIGN(off, FFI_SIZEOF_ARG);
+	  break;
+	case FFI_TYPE_FLOAT:
+	case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+#endif
+	  memmove(ret + off, flt + off, (*ptr)->size);
+	  off += (*ptr)->size;
+	  break;
+	default:
+	  memmove(ret + off, intg + off, (*ptr)->size);
+	  off += (*ptr)->size;
+	  break;
+	}
+      ptr++;
+    }
+  return off;
+}
+
+
+#ifdef SPARC64
+extern int ffi_call_v9(void *, extended_cif *, unsigned, 
+		       unsigned, unsigned *, void (*fn)(void));
+#else
+extern int ffi_call_v8(void *, extended_cif *, unsigned, 
+		       unsigned, unsigned *, void (*fn)(void));
+#endif
+
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+  void *rval = rvalue;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  ecif.rvalue = rvalue;
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      if (cif->rtype->size <= 32)
+	rval = alloca(64);
+      else
+	{
+	  rval = NULL;
+	  if (rvalue == NULL)
+	    ecif.rvalue = alloca(cif->rtype->size);
+	}
+    }
+
+  switch (cif->abi) 
+    {
+    case FFI_V8:
+#ifdef SPARC64
+      /* We don't yet support calling 32bit code from 64bit */
+      FFI_ASSERT(0);
+#else
+      if (rvalue && (cif->rtype->type == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	  || cif->flags == FFI_TYPE_LONGDOUBLE
+#endif
+	  ))
+	{
+	  /* For v8, we need an "unimp" with size of returning struct */
+	  /* behind "call", so we alloc some executable space for it. */
+	  /* l7 is used, we need to make sure v8.S doesn't use %l7.   */
+	  unsigned int *call_struct = NULL;
+	  ffi_closure_alloc(32, &call_struct);
+	  if (call_struct)
+	    {
+	      unsigned long f = (unsigned long)fn;
+	      call_struct[0] = 0xae10001f;		 /* mov   %i7, %l7	 */
+	      call_struct[1] = 0xbe10000f;		 /* mov   %o7, %i7	 */
+	      call_struct[2] = 0x03000000 | f >> 10;     /* sethi %hi(fn), %g1	 */
+	      call_struct[3] = 0x9fc06000 | (f & 0x3ff); /* jmp %g1+%lo(fn), %o7 */
+	      call_struct[4] = 0x01000000;		 /* nop			 */
+	      if (cif->rtype->size < 0x7f)
+		call_struct[5] = cif->rtype->size;	 /* unimp		 */
+	      else
+		call_struct[5] = 0x01000000;	     	 /* nop			 */
+	      call_struct[6] = 0x81c7e008;		 /* ret			 */
+	      call_struct[7] = 0xbe100017;		 /* mov   %l7, %i7	 */
+	      asm volatile ("iflush %0; iflush %0+8; iflush %0+16; iflush %0+24" : :
+			    "r" (call_struct) : "memory");
+	      /* SPARC v8 requires 5 instructions for flush to be visible */
+	      asm volatile ("nop; nop; nop; nop; nop");
+	      ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
+			  cif->flags, rvalue, call_struct);
+	      ffi_closure_free(call_struct);
+	    }
+	  else
+	    {
+	      ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
+			  cif->flags, rvalue, fn);
+	    }
+	}
+      else
+	{
+	  ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
+		      cif->flags, rvalue, fn);
+	}
+#endif
+      break;
+    case FFI_V9:
+#ifdef SPARC64
+      ffi_call_v9(ffi_prep_args_v9, &ecif, cif->bytes,
+		  cif->flags, rval, fn);
+      if (rvalue && rval && cif->rtype->type == FFI_TYPE_STRUCT)
+	ffi_v9_layout_struct(cif->rtype, 0, (char *)rvalue, (char *)rval, ((char *)rval)+32);
+#else
+      /* And vice versa */
+      FFI_ASSERT(0);
+#endif
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+
+#ifdef SPARC64
+extern void ffi_closure_v9(void);
+#else
+extern void ffi_closure_v8(void);
+#endif
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif*, void*, void**, void*),
+		      void *user_data,
+		      void *codeloc)
+{
+  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
+  unsigned long fn;
+#ifdef SPARC64
+  /* Trampoline address is equal to the closure address.  We take advantage
+     of that to reduce the trampoline size by 8 bytes. */
+  if (cif->abi != FFI_V9)
+    return FFI_BAD_ABI;
+  fn = (unsigned long) ffi_closure_v9;
+  tramp[0] = 0x83414000;	/* rd	%pc, %g1	*/
+  tramp[1] = 0xca586010;	/* ldx	[%g1+16], %g5	*/
+  tramp[2] = 0x81c14000;	/* jmp	%g5		*/
+  tramp[3] = 0x01000000;	/* nop			*/
+  *((unsigned long *) &tramp[4]) = fn;
+#else
+  unsigned long ctx = (unsigned long) codeloc;
+  if (cif->abi != FFI_V8)
+    return FFI_BAD_ABI;
+  fn = (unsigned long) ffi_closure_v8;
+  tramp[0] = 0x03000000 | fn >> 10;	/* sethi %hi(fn), %g1	*/
+  tramp[1] = 0x05000000 | ctx >> 10;	/* sethi %hi(ctx), %g2	*/
+  tramp[2] = 0x81c06000 | (fn & 0x3ff);	/* jmp   %g1+%lo(fn)	*/
+  tramp[3] = 0x8410a000 | (ctx & 0x3ff);/* or    %g2, %lo(ctx)	*/
+#endif
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  /* Flush the Icache.  closure is 8 bytes aligned.  */
+#ifdef SPARC64
+  asm volatile ("flush	%0; flush %0+8" : : "r" (closure) : "memory");
+#else
+  asm volatile ("iflush	%0; iflush %0+8" : : "r" (closure) : "memory");
+  /* SPARC v8 requires 5 instructions for flush to be visible */
+  asm volatile ("nop; nop; nop; nop; nop");
+#endif
+
+  return FFI_OK;
+}
+
+int
+ffi_closure_sparc_inner_v8(ffi_closure *closure,
+  void *rvalue, unsigned long *gpr, unsigned long *scratch)
+{
+  ffi_cif *cif;
+  ffi_type **arg_types;
+  void **avalue;
+  int i, argn;
+
+  cif = closure->cif;
+  arg_types = cif->arg_types;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  /* Copy the caller's structure return address so that the closure
+     returns the data directly to the caller.  */
+  if (cif->flags == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE  
+      || cif->flags == FFI_TYPE_LONGDOUBLE
+#endif
+     )
+    rvalue = (void *) gpr[0];
+
+  /* Always skip the structure return address.  */
+  argn = 1;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  for (i = 0; i < cif->nargs; i++)
+    {
+      if (arg_types[i]->type == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	  || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
+#endif
+         )
+	{
+	  /* Straight copy of invisible reference.  */
+	  avalue[i] = (void *)gpr[argn++];
+	}
+      else if ((arg_types[i]->type == FFI_TYPE_DOUBLE
+	       || arg_types[i]->type == FFI_TYPE_SINT64
+	       || arg_types[i]->type == FFI_TYPE_UINT64)
+	       /* gpr is 8-byte aligned.  */
+	       && (argn % 2) != 0)
+	{
+	  /* Align on a 8-byte boundary.  */
+	  scratch[0] = gpr[argn];
+	  scratch[1] = gpr[argn+1];
+	  avalue[i] = scratch;
+	  scratch -= 2;
+	  argn += 2;
+	}
+      else
+	{
+	  /* Always right-justify.  */
+	  argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+	  avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
+	}
+    }
+
+  /* Invoke the closure.  */
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_sparc how to perform return type promotions.  */
+  return cif->rtype->type;
+}
+
+int
+ffi_closure_sparc_inner_v9(ffi_closure *closure,
+  void *rvalue, unsigned long *gpr, double *fpr)
+{
+  ffi_cif *cif;
+  ffi_type **arg_types;
+  void **avalue;
+  int i, argn, fp_slot_max;
+
+  cif = closure->cif;
+  arg_types = cif->arg_types;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  /* Copy the caller's structure return address so that the closure
+     returns the data directly to the caller.  */
+  if (cif->flags == FFI_TYPE_VOID
+      && cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      rvalue = (void *) gpr[0];
+      /* Skip the structure return address.  */
+      argn = 1;
+    }
+  else
+    argn = 0;
+
+  fp_slot_max = 16 - argn;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  for (i = 0; i < cif->nargs; i++)
+    {
+      if (arg_types[i]->type == FFI_TYPE_STRUCT)
+	{
+	  if (arg_types[i]->size > 16)
+	    {
+	      /* Straight copy of invisible reference.  */
+	      avalue[i] = (void *)gpr[argn++];
+	    }
+	  else
+	    {
+	      /* Left-justify.  */
+	      ffi_v9_layout_struct(arg_types[i],
+				   0,
+				   (char *) &gpr[argn],
+				   (char *) &gpr[argn],
+				   (char *) &fpr[argn]);
+	      avalue[i] = &gpr[argn];
+	      argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+	    }
+	}
+      else
+	{
+	  /* Right-justify.  */
+	  argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
+
+	  /* Align on a 16-byte boundary.  */
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	  if (arg_types[i]->type == FFI_TYPE_LONGDOUBLE && (argn % 2) != 0)
+	    argn++;
+#endif
+	  if (i < fp_slot_max
+	      && (arg_types[i]->type == FFI_TYPE_FLOAT
+		  || arg_types[i]->type == FFI_TYPE_DOUBLE
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+		  || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
+#endif
+		  ))
+	    avalue[i] = ((char *) &fpr[argn]) - arg_types[i]->size;
+	  else
+	    avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
+	}
+    }
+
+  /* Invoke the closure.  */
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_sparc how to perform return type promotions.  */
+  return cif->rtype->type;
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sparc/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sparc/ffitarget.h
new file mode 100755
index 0000000..51275cb
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sparc/ffitarget.h
@@ -0,0 +1,68 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+   Target configuration macros for SPARC.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+#if defined(__arch64__) || defined(__sparcv9)
+#ifndef SPARC64
+#define SPARC64
+#endif
+#endif
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_V8,
+  FFI_V8PLUS,
+  FFI_V9,
+  FFI_LAST_ABI,
+#ifdef SPARC64
+  FFI_DEFAULT_ABI = FFI_V9
+#else
+  FFI_DEFAULT_ABI = FFI_V8
+#endif
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_NATIVE_RAW_API 0
+
+#ifdef SPARC64
+#define FFI_TRAMPOLINE_SIZE 24
+#else
+#define FFI_TRAMPOLINE_SIZE 16
+#endif
+
+#endif
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sparc/v8.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sparc/v8.S
new file mode 100755
index 0000000..2c4eb60
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sparc/v8.S
@@ -0,0 +1,313 @@
+/* -----------------------------------------------------------------------
+   v8.S - Copyright (c) 1996, 1997, 2003, 2004, 2008 Red Hat, Inc.
+   
+   SPARC Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+#define STACKFRAME 96		/* Minimum stack framesize for SPARC */
+#define ARGS (64+4)		/* Offset of register area in frame */
+
+.text
+        .align 8
+.globl ffi_call_v8
+.globl _ffi_call_v8
+
+ffi_call_v8:
+_ffi_call_v8:
+.LLFB1:
+	save	%sp, -STACKFRAME, %sp
+.LLCFI0:
+	
+	sub	%sp, %i2, %sp	! alloca() space in stack for frame to set up
+	add	%sp, STACKFRAME, %l0	! %l0 has start of 
+					! frame to set up
+
+	mov	%l0, %o0	! call routine to set up frame
+	call	%i0
+	mov	%i1, %o1	! (delay)
+
+	ld	[%l0+ARGS], %o0	! call foreign function
+	ld	[%l0+ARGS+4], %o1
+	ld	[%l0+ARGS+8], %o2
+	ld	[%l0+ARGS+12], %o3
+	ld	[%l0+ARGS+16], %o4
+	ld	[%l0+ARGS+20], %o5
+	call	%i5
+	mov	%l0, %sp	! (delay) switch to frame
+	nop			! STRUCT returning functions skip 12 instead of 8 bytes
+
+	! If the return value pointer is NULL, assume no return value.
+	tst	%i4
+	bz	done
+	nop
+
+	cmp	%i3, FFI_TYPE_INT
+	be,a	done
+	st	%o0, [%i4]	! (delay)
+
+	cmp	%i3, FFI_TYPE_FLOAT
+	be,a	done
+	st	%f0, [%i4+0]	! (delay)
+
+	cmp	%i3, FFI_TYPE_DOUBLE
+	be,a	double
+	st	%f0, [%i4+0]	! (delay)
+
+	cmp	%i3, FFI_TYPE_SINT8
+	be,a	sint8
+	sll	%o0, 24, %o0	! (delay)
+
+	cmp	%i3, FFI_TYPE_UINT8
+	be,a	uint8
+	sll	%o0, 24, %o0	! (delay)
+
+	cmp	%i3, FFI_TYPE_SINT16
+	be,a	sint16
+	sll	%o0, 16, %o0	! (delay)
+
+	cmp	%i3, FFI_TYPE_UINT16
+	be,a	uint16
+	sll	%o0, 16, %o0	! (delay)
+
+	cmp	%i3, FFI_TYPE_SINT64
+	be,a	longlong
+	st	%o0, [%i4+0]	! (delay)
+done:
+	ret
+	restore
+
+double:
+	st	%f1, [%i4+4]
+	ret
+	restore
+
+sint8:
+	sra	%o0, 24, %o0
+	st	%o0, [%i4+0]
+	ret
+	restore
+
+uint8:
+	srl	%o0, 24, %o0
+	st	%o0, [%i4+0]
+	ret
+	restore
+
+sint16:
+	sra	%o0, 16, %o0
+	st	%o0, [%i4+0]
+	ret
+	restore
+
+uint16:
+	srl	%o0, 16, %o0
+	st	%o0, [%i4+0]
+	ret
+	restore
+
+longlong:
+	st	%o1, [%i4+4]
+	ret
+	restore
+.LLFE1:
+
+.ffi_call_v8_end:
+	.size	ffi_call_v8,.ffi_call_v8_end-ffi_call_v8
+
+
+#undef STACKFRAME
+#define	STACKFRAME	104	/* 16*4 register window +
+				   1*4 struct return +	
+				   6*4 args backing store +
+				   3*4 locals */
+
+/* ffi_closure_v8(...)
+
+   Receives the closure argument in %g2.   */
+
+	.text
+	.align 8
+	.globl ffi_closure_v8
+
+ffi_closure_v8:
+#ifdef HAVE_AS_REGISTER_PSEUDO_OP
+		.register	%g2, #scratch
+#endif
+.LLFB2:
+	! Reserve frame space for all arguments in case
+	! we need to align them on a 8-byte boundary.
+	ld	[%g2+FFI_TRAMPOLINE_SIZE], %g1
+	ld	[%g1+4], %g1
+	sll	%g1, 3, %g1
+	add	%g1, STACKFRAME, %g1
+	! %g1 == STACKFRAME + 8*nargs
+	neg	%g1
+	save	%sp, %g1, %sp
+.LLCFI1:
+
+	! Store all of the potential argument registers in va_list format.
+	st	%i0, [%fp+68+0]
+	st	%i1, [%fp+68+4]
+	st	%i2, [%fp+68+8]
+	st	%i3, [%fp+68+12]
+	st	%i4, [%fp+68+16]
+	st	%i5, [%fp+68+20]
+
+	! Call ffi_closure_sparc_inner to do the bulk of the work.
+	mov	%g2, %o0
+	add	%fp, -8, %o1
+	add	%fp,  64, %o2
+	call	ffi_closure_sparc_inner_v8
+	 add	%fp, -16, %o3
+
+	! Load up the return value in the proper type.
+	! See ffi_prep_cif_machdep for the list of cases.
+	cmp	%o0, FFI_TYPE_VOID
+	be	done1
+
+	cmp	%o0, FFI_TYPE_INT
+	be	done1
+	 ld	[%fp-8], %i0
+
+	cmp	%o0, FFI_TYPE_FLOAT
+	be,a	done1
+	 ld	[%fp-8], %f0
+
+	cmp	%o0, FFI_TYPE_DOUBLE
+	be,a	done1
+	 ldd	[%fp-8], %f0
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	cmp	%o0, FFI_TYPE_LONGDOUBLE
+	be	done2
+#endif
+
+	cmp	%o0, FFI_TYPE_STRUCT
+	be	done2
+
+	cmp	%o0, FFI_TYPE_SINT64
+	be,a	done1
+	 ldd	[%fp-8], %i0
+
+	ld	[%fp-8], %i0
+done1:
+	jmp	%i7+8
+	 restore
+done2:
+	! Skip 'unimp'.
+	jmp	%i7+12
+	 restore
+.LLFE2:
+
+.ffi_closure_v8_end:
+	.size	ffi_closure_v8,.ffi_closure_v8_end-ffi_closure_v8
+
+#ifdef SPARC64
+#define WS 8
+#define nword	xword
+#define uanword	uaxword
+#else
+#define WS 4
+#define nword	long
+#define uanword	uaword
+#endif
+
+#ifdef HAVE_RO_EH_FRAME
+	.section	".eh_frame",#alloc
+#else
+	.section	".eh_frame",#alloc,#write
+#endif
+.LLframe1:
+	.uaword	.LLECIE1-.LLSCIE1	! Length of Common Information Entry
+.LLSCIE1:
+	.uaword	0x0	! CIE Identifier Tag
+	.byte	0x1	! CIE Version
+	.ascii "zR\0"	! CIE Augmentation
+	.byte	0x1	! uleb128 0x1; CIE Code Alignment Factor
+	.byte	0x80-WS	! sleb128 -WS; CIE Data Alignment Factor
+	.byte	0xf	! CIE RA Column
+	.byte	0x1	! uleb128 0x1; Augmentation size
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.byte	0x1b	! FDE Encoding (pcrel sdata4)
+#else
+	.byte	0x50	! FDE Encoding (aligned absolute)
+#endif
+	.byte	0xc	! DW_CFA_def_cfa
+	.byte	0xe	! uleb128 0xe
+	.byte	0x0	! uleb128 0x0
+	.align	WS
+.LLECIE1:
+.LLSFDE1:
+	.uaword	.LLEFDE1-.LLASFDE1	! FDE Length
+.LLASFDE1:
+	.uaword	.LLASFDE1-.LLframe1	! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.uaword	%r_disp32(.LLFB1)
+	.uaword	.LLFE1-.LLFB1	! FDE address range
+#else
+	.align	WS
+	.nword	.LLFB1
+	.uanword .LLFE1-.LLFB1	! FDE address range
+#endif
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI0-.LLFB1
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align	WS
+.LLEFDE1:
+.LLSFDE2:
+	.uaword	.LLEFDE2-.LLASFDE2	! FDE Length
+.LLASFDE2:
+	.uaword	.LLASFDE2-.LLframe1	! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.uaword	%r_disp32(.LLFB2)
+	.uaword	.LLFE2-.LLFB2	! FDE address range
+#else
+	.align	WS
+	.nword	.LLFB2
+	.uanword .LLFE2-.LLFB2	! FDE address range
+#endif
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI1-.LLFB2
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align	WS
+.LLEFDE2:
+
+#if defined __ELF__ && defined __linux__
+	.section	.note.GNU-stack,"", at progbits
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sparc/v9.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sparc/v9.S
new file mode 100755
index 0000000..489ff02
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/sparc/v9.S
@@ -0,0 +1,307 @@
+/* -----------------------------------------------------------------------
+   v9.S - Copyright (c) 2000, 2003, 2004, 2008 Red Hat, Inc.
+   
+   SPARC 64-bit Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+#ifdef SPARC64
+/* Only compile this in for 64bit builds, because otherwise the object file
+   will have inproper architecture due to used instructions.  */
+
+#define STACKFRAME 128		/* Minimum stack framesize for SPARC */
+#define STACK_BIAS 2047
+#define ARGS (128)		/* Offset of register area in frame */
+
+.text
+        .align 8
+.globl ffi_call_v9
+.globl _ffi_call_v9
+
+ffi_call_v9:
+_ffi_call_v9:
+.LLFB1:
+	save	%sp, -STACKFRAME, %sp
+.LLCFI0:
+	
+	sub	%sp, %i2, %sp	! alloca() space in stack for frame to set up
+	add	%sp, STACKFRAME+STACK_BIAS, %l0	! %l0 has start of 
+						! frame to set up
+
+	mov	%l0, %o0	! call routine to set up frame
+	call	%i0
+	 mov	%i1, %o1	! (delay)
+	brz,pt	%o0, 1f
+	 ldx	[%l0+ARGS], %o0	! call foreign function
+
+	ldd	[%l0+ARGS], %f0
+	ldd	[%l0+ARGS+8], %f2
+	ldd	[%l0+ARGS+16], %f4
+	ldd	[%l0+ARGS+24], %f6
+	ldd	[%l0+ARGS+32], %f8
+	ldd	[%l0+ARGS+40], %f10
+	ldd	[%l0+ARGS+48], %f12
+	ldd	[%l0+ARGS+56], %f14
+	ldd	[%l0+ARGS+64], %f16
+	ldd	[%l0+ARGS+72], %f18
+	ldd	[%l0+ARGS+80], %f20
+	ldd	[%l0+ARGS+88], %f22
+	ldd	[%l0+ARGS+96], %f24
+	ldd	[%l0+ARGS+104], %f26
+	ldd	[%l0+ARGS+112], %f28
+	ldd	[%l0+ARGS+120], %f30
+
+1:	ldx	[%l0+ARGS+8], %o1
+	ldx	[%l0+ARGS+16], %o2
+	ldx	[%l0+ARGS+24], %o3
+	ldx	[%l0+ARGS+32], %o4
+	ldx	[%l0+ARGS+40], %o5
+	call	%i5
+	 sub	%l0, STACK_BIAS, %sp	! (delay) switch to frame
+
+	! If the return value pointer is NULL, assume no return value.
+	brz,pn	%i4, done
+	 nop
+
+	cmp	%i3, FFI_TYPE_INT
+	be,a,pt	%icc, done
+	 stx	%o0, [%i4+0]	! (delay)
+
+	cmp	%i3, FFI_TYPE_FLOAT
+	be,a,pn	%icc, done
+	 st	%f0, [%i4+0]	! (delay)
+
+	cmp	%i3, FFI_TYPE_DOUBLE
+	be,a,pn	%icc, done
+	 std	%f0, [%i4+0]	! (delay)
+
+	cmp	%i3, FFI_TYPE_STRUCT
+	be,pn	%icc, dostruct
+
+	cmp	%i3, FFI_TYPE_LONGDOUBLE
+	bne,pt	%icc, done
+	 nop
+	std	%f0, [%i4+0]
+	std	%f2, [%i4+8]
+
+done:	ret
+	 restore
+
+dostruct:
+	/* This will not work correctly for unions. */
+	stx	%o0, [%i4+0]
+	stx	%o1, [%i4+8]
+	stx	%o2, [%i4+16]
+	stx	%o3, [%i4+24]
+	std	%f0, [%i4+32]
+	std	%f2, [%i4+40]
+	std	%f4, [%i4+48]
+	std	%f6, [%i4+56]
+	ret
+	 restore
+.LLFE1:
+
+.ffi_call_v9_end:
+	.size	ffi_call_v9,.ffi_call_v9_end-ffi_call_v9
+
+
+#undef STACKFRAME
+#define	STACKFRAME	 336	/* 16*8 register window +
+				   6*8 args backing store +
+				   20*8 locals */
+#define	FP		%fp+STACK_BIAS
+
+/* ffi_closure_v9(...)
+
+   Receives the closure argument in %g1.   */
+
+	.text
+	.align 8
+	.globl ffi_closure_v9
+
+ffi_closure_v9:
+.LLFB2:
+	save	%sp, -STACKFRAME, %sp
+.LLCFI1:
+
+	! Store all of the potential argument registers in va_list format.
+	stx	%i0, [FP+128+0]
+	stx	%i1, [FP+128+8]
+	stx	%i2, [FP+128+16]
+	stx	%i3, [FP+128+24]
+	stx	%i4, [FP+128+32]
+	stx	%i5, [FP+128+40]
+
+	! Store possible floating point argument registers too.
+	std	%f0,  [FP-128]
+	std	%f2,  [FP-120]
+	std	%f4,  [FP-112]
+	std	%f6,  [FP-104]
+	std	%f8,  [FP-96]
+	std	%f10, [FP-88]
+	std     %f12, [FP-80]
+	std     %f14, [FP-72]
+	std     %f16, [FP-64]
+	std     %f18, [FP-56]
+	std     %f20, [FP-48]
+	std     %f22, [FP-40]
+	std     %f24, [FP-32]
+	std     %f26, [FP-24]
+	std     %f28, [FP-16]
+	std     %f30, [FP-8]
+
+	! Call ffi_closure_sparc_inner to do the bulk of the work.
+	mov	%g1, %o0
+	add	%fp, STACK_BIAS-160, %o1
+	add	%fp, STACK_BIAS+128, %o2
+	call	ffi_closure_sparc_inner_v9
+	 add	%fp, STACK_BIAS-128, %o3
+
+	! Load up the return value in the proper type.
+	! See ffi_prep_cif_machdep for the list of cases.
+	cmp	%o0, FFI_TYPE_VOID
+	be,pn	%icc, done1
+
+	cmp	%o0, FFI_TYPE_INT
+	be,pn	%icc, integer
+
+	cmp	%o0, FFI_TYPE_FLOAT
+	be,a,pn	%icc, done1
+	 ld	[FP-160], %f0
+
+	cmp	%o0, FFI_TYPE_DOUBLE
+	be,a,pn	%icc, done1
+	 ldd	[FP-160], %f0
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	cmp	%o0, FFI_TYPE_LONGDOUBLE
+	be,a,pn	%icc, longdouble1
+	 ldd	[FP-160], %f0
+#endif
+
+	! FFI_TYPE_STRUCT
+	ldx	[FP-152], %i1
+	ldx	[FP-144], %i2
+	ldx	[FP-136], %i3
+	ldd	[FP-160], %f0
+	ldd	[FP-152], %f2
+	ldd	[FP-144], %f4
+	ldd	[FP-136], %f6
+
+integer:
+	ldx	[FP-160], %i0
+
+done1:
+	ret
+	 restore
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+longdouble1:
+	ldd	[FP-152], %f2
+	ret
+	 restore
+#endif
+.LLFE2:
+
+.ffi_closure_v9_end:
+	.size	ffi_closure_v9,.ffi_closure_v9_end-ffi_closure_v9
+
+#ifdef HAVE_RO_EH_FRAME
+	.section	".eh_frame",#alloc
+#else
+	.section	".eh_frame",#alloc,#write
+#endif
+.LLframe1:
+	.uaword	.LLECIE1-.LLSCIE1	! Length of Common Information Entry
+.LLSCIE1:
+	.uaword	0x0	! CIE Identifier Tag
+	.byte	0x1	! CIE Version
+	.ascii "zR\0"	! CIE Augmentation
+	.byte	0x1	! uleb128 0x1; CIE Code Alignment Factor
+	.byte	0x78	! sleb128 -8; CIE Data Alignment Factor
+	.byte	0xf	! CIE RA Column
+	.byte	0x1	! uleb128 0x1; Augmentation size
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.byte	0x1b	! FDE Encoding (pcrel sdata4)
+#else
+	.byte	0x50	! FDE Encoding (aligned absolute)
+#endif
+	.byte	0xc	! DW_CFA_def_cfa
+	.byte	0xe	! uleb128 0xe
+	.byte	0xff,0xf	! uleb128 0x7ff
+	.align 8
+.LLECIE1:
+.LLSFDE1:
+	.uaword	.LLEFDE1-.LLASFDE1	! FDE Length
+.LLASFDE1:
+	.uaword	.LLASFDE1-.LLframe1	! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.uaword	%r_disp32(.LLFB1)
+	.uaword	.LLFE1-.LLFB1		! FDE address range
+#else
+	.align 8
+	.xword	.LLFB1
+	.uaxword	.LLFE1-.LLFB1	! FDE address range
+#endif
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI0-.LLFB1
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align 8
+.LLEFDE1:
+.LLSFDE2:
+	.uaword	.LLEFDE2-.LLASFDE2	! FDE Length
+.LLASFDE2:
+	.uaword	.LLASFDE2-.LLframe1	! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.uaword	%r_disp32(.LLFB2)
+	.uaword	.LLFE2-.LLFB2		! FDE address range
+#else
+	.align 8
+	.xword	.LLFB2
+	.uaxword	.LLFE2-.LLFB2	! FDE address range
+#endif
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI1-.LLFB2
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align 8
+.LLEFDE2:
+#endif
+
+#ifdef __linux__
+	.section	.note.GNU-stack,"", at progbits
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/types.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/types.c
new file mode 100755
index 0000000..0a11eb0
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/types.c
@@ -0,0 +1,77 @@
+/* -----------------------------------------------------------------------
+   types.c - Copyright (c) 1996, 1998  Red Hat, Inc.
+   
+   Predefined ffi_types needed by libffi.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+/* Hide the basic type definitions from the header file, so that we
+   can redefine them here as "const".  */
+#define LIBFFI_HIDE_BASIC_TYPES
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+/* Type definitions */
+
+#define FFI_TYPEDEF(name, type, id)		\
+struct struct_align_##name {			\
+  char c;					\
+  type x;					\
+};						\
+const ffi_type ffi_type_##name = {		\
+  sizeof(type),					\
+  offsetof(struct struct_align_##name, x),	\
+  id, NULL					\
+}
+
+/* Size and alignment are fake here. They must not be 0. */
+const ffi_type ffi_type_void = {
+  1, 1, FFI_TYPE_VOID, NULL
+};
+
+FFI_TYPEDEF(uint8, UINT8, FFI_TYPE_UINT8);
+FFI_TYPEDEF(sint8, SINT8, FFI_TYPE_SINT8);
+FFI_TYPEDEF(uint16, UINT16, FFI_TYPE_UINT16);
+FFI_TYPEDEF(sint16, SINT16, FFI_TYPE_SINT16);
+FFI_TYPEDEF(uint32, UINT32, FFI_TYPE_UINT32);
+FFI_TYPEDEF(sint32, SINT32, FFI_TYPE_SINT32);
+FFI_TYPEDEF(uint64, UINT64, FFI_TYPE_UINT64);
+FFI_TYPEDEF(sint64, SINT64, FFI_TYPE_SINT64);
+
+FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER);
+
+FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT);
+FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE);
+
+#ifdef __alpha__
+/* Even if we're not configured to default to 128-bit long double, 
+   maintain binary compatibility, as -mlong-double-128 can be used
+   at any time.  */
+/* Validate the hard-coded number below.  */
+# if defined(__LONG_DOUBLE_128__) && FFI_TYPE_LONGDOUBLE != 4
+#  error FFI_TYPE_LONGDOUBLE out of date
+# endif
+const ffi_type ffi_type_longdouble = { 16, 16, 4, NULL };
+#elif FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE);
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/darwin.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/darwin.S
new file mode 100755
index 0000000..8f0f070
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/darwin.S
@@ -0,0 +1,444 @@
+/* -----------------------------------------------------------------------
+   darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005  Red Hat, Inc.
+	Copyright (C) 2008  Free Software Foundation, Inc.
+
+   X86 Foreign Function Interface
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   -----------------------------------------------------------------------
+   */
+
+#ifndef __x86_64__
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+
+.globl _ffi_prep_args
+
+	.align 4
+.globl _ffi_call_SYSV
+
+_ffi_call_SYSV:
+.LFB1:
+        pushl %ebp
+.LCFI0:
+        movl  %esp,%ebp
+.LCFI1:
+        subl $8,%esp
+	/* Make room for all of the new args.  */
+	movl  16(%ebp),%ecx
+	subl  %ecx,%esp
+
+	movl  %esp,%eax
+
+	/* Place all of the ffi_prep_args in position  */
+	subl  $8,%esp
+	pushl 12(%ebp)
+	pushl %eax
+	call  *8(%ebp)
+
+	/* Return stack to previous state and call the function  */
+	addl  $16,%esp	
+
+	call  *28(%ebp)
+
+	/* Load %ecx with the return type code  */
+	movl  20(%ebp),%ecx	
+
+	/* Protect %esi.  We're going to pop it in the epilogue.  */
+	pushl %esi
+
+	/* If the return value pointer is NULL, assume no return value.  */
+	cmpl  $0,24(%ebp)
+	jne  0f
+
+	/* Even if there is no space for the return value, we are 
+	   obliged to handle floating-point values.  */
+	cmpl  $FFI_TYPE_FLOAT,%ecx
+	jne   noretval
+	fstp  %st(0)
+
+	jmp   epilogue
+0:
+	.align 4
+	call 1f
+.Lstore_table:
+	.long   noretval-.Lstore_table		/* FFI_TYPE_VOID */
+	.long   retint-.Lstore_table		/* FFI_TYPE_INT */
+	.long   retfloat-.Lstore_table		/* FFI_TYPE_FLOAT */
+	.long   retdouble-.Lstore_table		/* FFI_TYPE_DOUBLE */
+	.long   retlongdouble-.Lstore_table     /* FFI_TYPE_LONGDOUBLE */
+	.long   retuint8-.Lstore_table		/* FFI_TYPE_UINT8 */
+	.long   retsint8-.Lstore_table		/* FFI_TYPE_SINT8 */
+	.long   retuint16-.Lstore_table		/* FFI_TYPE_UINT16 */
+	.long   retsint16-.Lstore_table		/* FFI_TYPE_SINT16 */
+	.long   retint-.Lstore_table		/* FFI_TYPE_UINT32 */
+	.long   retint-.Lstore_table		/* FFI_TYPE_SINT32 */
+	.long   retint64-.Lstore_table		/* FFI_TYPE_UINT64 */
+	.long   retint64-.Lstore_table		/* FFI_TYPE_SINT64 */
+	.long   retstruct-.Lstore_table		/* FFI_TYPE_STRUCT */
+	.long   retint-.Lstore_table		/* FFI_TYPE_POINTER */
+	.long   retstruct1b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_1B */
+	.long   retstruct2b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_2B */
+1:
+	pop  %esi
+	add  (%esi, %ecx, 4), %esi
+	jmp  *%esi
+
+	/* Sign/zero extend as appropriate.  */
+retsint8:
+	movsbl  %al, %eax
+	jmp  retint
+
+retsint16:
+	movswl  %ax, %eax
+	jmp  retint
+
+retuint8:
+	movzbl  %al, %eax
+	jmp  retint
+
+retuint16:
+	movzwl  %ax, %eax
+	jmp  retint
+
+retfloat:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	fstps (%ecx)
+	jmp   epilogue
+
+retdouble:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	fstpl (%ecx)
+	jmp   epilogue
+
+retlongdouble:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	fstpt (%ecx)
+	jmp   epilogue
+
+retint64:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	movl  %eax,0(%ecx)
+	movl  %edx,4(%ecx)
+	jmp   epilogue
+
+retstruct1b:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	movb  %al,0(%ecx)
+	jmp   epilogue
+
+retstruct2b:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	movw  %ax,0(%ecx)
+	jmp   epilogue
+
+retint:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	movl  %eax,0(%ecx)
+
+retstruct:
+	/* Nothing to do!  */
+
+noretval:
+epilogue:
+	popl %esi
+	movl %ebp,%esp
+	popl %ebp
+	ret
+
+.LFE1:
+.ffi_call_SYSV_end:
+
+	.align	4
+FFI_HIDDEN (ffi_closure_SYSV)
+.globl _ffi_closure_SYSV
+
+_ffi_closure_SYSV:
+.LFB2:
+	pushl	%ebp
+.LCFI2:
+	movl	%esp, %ebp
+.LCFI3:
+	subl	$40, %esp
+	leal	-24(%ebp), %edx
+	movl	%edx, -12(%ebp)	/* resp */
+	leal	8(%ebp), %edx
+	movl	%edx, 4(%esp)	/* args = __builtin_dwarf_cfa () */
+	leal	-12(%ebp), %edx
+	movl	%edx, (%esp)	/* &resp */
+	movl	%ebx, 8(%esp)
+.LCFI7:
+	call	L_ffi_closure_SYSV_inner$stub
+	movl	8(%esp), %ebx
+	movl	-12(%ebp), %ecx
+	cmpl	$FFI_TYPE_INT, %eax
+	je	.Lcls_retint
+
+	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
+	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
+	cmpl	$FFI_TYPE_UINT64, %eax
+	jge	0f
+	cmpl	$FFI_TYPE_UINT8, %eax
+	jge	.Lcls_retint
+
+0:	cmpl	$FFI_TYPE_FLOAT, %eax
+	je	.Lcls_retfloat
+	cmpl	$FFI_TYPE_DOUBLE, %eax
+	je	.Lcls_retdouble
+	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
+	je	.Lcls_retldouble
+	cmpl	$FFI_TYPE_SINT64, %eax
+	je	.Lcls_retllong
+	cmpl	$FFI_TYPE_SMALL_STRUCT_1B, %eax
+	je	.Lcls_retstruct1b
+	cmpl	$FFI_TYPE_SMALL_STRUCT_2B, %eax
+	je	.Lcls_retstruct2b
+	cmpl	$FFI_TYPE_STRUCT, %eax
+	je	.Lcls_retstruct
+.Lcls_epilogue:
+	movl	%ebp, %esp
+	popl	%ebp
+	ret
+.Lcls_retint:
+	movl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+.Lcls_retfloat:
+	flds	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retdouble:
+	fldl	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retldouble:
+	fldt	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retllong:
+	movl	(%ecx), %eax
+	movl	4(%ecx), %edx
+	jmp	.Lcls_epilogue
+.Lcls_retstruct1b:
+	movsbl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+.Lcls_retstruct2b:
+	movswl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+.Lcls_retstruct:
+	lea -8(%ebp),%esp
+	movl	%ebp, %esp
+	popl	%ebp
+	ret $4
+.LFE2:
+
+#if !FFI_NO_RAW_API
+
+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+#define CIF_FLAGS_OFFSET 20
+
+	.align	4
+FFI_HIDDEN (ffi_closure_raw_SYSV)
+.globl _ffi_closure_raw_SYSV
+
+_ffi_closure_raw_SYSV:
+.LFB3:
+	pushl	%ebp
+.LCFI4:
+	movl	%esp, %ebp
+.LCFI5:
+	pushl	%esi
+.LCFI6:
+	subl	$36, %esp
+	movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
+	movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
+	movl	%edx, 12(%esp)	/* user_data */
+	leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
+	movl	%edx, 8(%esp)	/* raw_args */
+	leal	-24(%ebp), %edx
+	movl	%edx, 4(%esp)	/* &res */
+	movl	%esi, (%esp)	/* cif */
+	call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
+	movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
+	cmpl	$FFI_TYPE_INT, %eax
+	je	.Lrcls_retint
+
+	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
+	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
+	cmpl	$FFI_TYPE_UINT64, %eax
+	jge	0f
+	cmpl	$FFI_TYPE_UINT8, %eax
+	jge	.Lrcls_retint
+0:
+	cmpl	$FFI_TYPE_FLOAT, %eax
+	je	.Lrcls_retfloat
+	cmpl	$FFI_TYPE_DOUBLE, %eax
+	je	.Lrcls_retdouble
+	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
+	je	.Lrcls_retldouble
+	cmpl	$FFI_TYPE_SINT64, %eax
+	je	.Lrcls_retllong
+.Lrcls_epilogue:
+	addl	$36, %esp
+	popl	%esi
+	popl	%ebp
+	ret
+.Lrcls_retint:
+	movl	-24(%ebp), %eax
+	jmp	.Lrcls_epilogue
+.Lrcls_retfloat:
+	flds	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retdouble:
+	fldl	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retldouble:
+	fldt	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retllong:
+	movl	-24(%ebp), %eax
+	movl	-20(%ebp), %edx
+	jmp	.Lrcls_epilogue
+.LFE3:
+#endif
+
+.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
+L_ffi_closure_SYSV_inner$stub:
+	.indirect_symbol _ffi_closure_SYSV_inner
+	hlt ; hlt ; hlt ; hlt ; hlt
+
+
+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
+EH_frame1:
+	.set	L$set$0,LECIE1-LSCIE1
+	.long	L$set$0
+LSCIE1:
+	.long	0x0
+	.byte	0x1
+	.ascii "zR\0"
+	.byte	0x1
+	.byte	0x7c
+	.byte	0x8
+	.byte	0x1
+	.byte	0x10
+	.byte	0xc
+	.byte	0x5
+	.byte	0x4
+	.byte	0x88
+	.byte	0x1
+	.align 2
+LECIE1:
+.globl _ffi_call_SYSV.eh
+_ffi_call_SYSV.eh:
+LSFDE1:
+	.set	L$set$1,LEFDE1-LASFDE1
+	.long	L$set$1
+LASFDE1:
+	.long	LASFDE1-EH_frame1
+	.long	.LFB1-.
+	.set L$set$2,.LFE1-.LFB1
+	.long L$set$2
+	.byte	0x0
+	.byte	0x4
+	.set L$set$3,.LCFI0-.LFB1
+	.long L$set$3
+	.byte	0xe
+	.byte	0x8
+	.byte	0x84
+	.byte	0x2
+	.byte	0x4
+	.set L$set$4,.LCFI1-.LCFI0
+	.long L$set$4
+	.byte	0xd
+	.byte	0x4
+	.align 2
+LEFDE1:
+.globl _ffi_closure_SYSV.eh
+_ffi_closure_SYSV.eh:
+LSFDE2:
+	.set	L$set$5,LEFDE2-LASFDE2
+	.long	L$set$5
+LASFDE2:
+	.long	LASFDE2-EH_frame1
+	.long	.LFB2-.
+	.set L$set$6,.LFE2-.LFB2
+	.long L$set$6
+	.byte	0x0
+	.byte	0x4
+	.set L$set$7,.LCFI2-.LFB2
+	.long L$set$7
+	.byte	0xe
+	.byte	0x8
+	.byte	0x84
+	.byte	0x2
+	.byte	0x4
+	.set L$set$8,.LCFI3-.LCFI2
+	.long L$set$8
+	.byte	0xd
+	.byte	0x4
+	.align 2
+LEFDE2:
+
+#if !FFI_NO_RAW_API
+
+.globl _ffi_closure_raw_SYSV.eh
+_ffi_closure_raw_SYSV.eh:
+LSFDE3:
+	.set	L$set$10,LEFDE3-LASFDE3
+	.long	L$set$10
+LASFDE3:
+	.long	LASFDE3-EH_frame1
+	.long	.LFB3-.
+	.set L$set$11,.LFE3-.LFB3
+	.long L$set$11
+	.byte	0x0
+	.byte	0x4
+	.set L$set$12,.LCFI4-.LFB3
+	.long L$set$12
+	.byte	0xe
+	.byte	0x8
+	.byte	0x84
+	.byte	0x2
+	.byte	0x4
+	.set L$set$13,.LCFI5-.LCFI4
+	.long L$set$13
+	.byte	0xd
+	.byte	0x4
+	.byte	0x4
+	.set L$set$14,.LCFI6-.LCFI5
+	.long L$set$14
+	.byte	0x85
+	.byte	0x3
+	.align 2
+LEFDE3:
+
+#endif
+
+#endif /* ifndef __x86_64__ */
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/darwin64.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/darwin64.S
new file mode 100755
index 0000000..2f7394e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/darwin64.S
@@ -0,0 +1,416 @@
+/* -----------------------------------------------------------------------
+   darwin64.S - Copyright (c) 2006 Free Software Foundation, Inc.
+	        Copyright (c) 2008 Red Hat, Inc.
+   derived from unix64.S
+
+   x86-64 Foreign Function Interface for Darwin.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#ifdef __x86_64__
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+	.file "darwin64.S"
+.text
+
+/* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
+		    void *raddr, void (*fnaddr)(void));
+
+   Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
+   for this function.  This has been allocated by ffi_call.  We also
+   deallocate some of the stack that has been alloca'd.  */
+
+	.align	3
+	.globl	_ffi_call_unix64
+
+_ffi_call_unix64:
+LUW0:
+	movq	(%rsp), %r10		/* Load return address.  */
+	leaq	(%rdi, %rsi), %rax	/* Find local stack base.  */
+	movq	%rdx, (%rax)		/* Save flags.  */
+	movq	%rcx, 8(%rax)		/* Save raddr.  */
+	movq	%rbp, 16(%rax)		/* Save old frame pointer.  */
+	movq	%r10, 24(%rax)		/* Relocate return address.  */
+	movq	%rax, %rbp		/* Finalize local stack frame.  */
+LUW1:
+	movq	%rdi, %r10		/* Save a copy of the register area. */
+	movq	%r8, %r11		/* Save a copy of the target fn.  */
+	movl	%r9d, %eax		/* Set number of SSE registers.  */
+
+	/* Load up all argument registers.  */
+	movq	(%r10), %rdi
+	movq	8(%r10), %rsi
+	movq	16(%r10), %rdx
+	movq	24(%r10), %rcx
+	movq	32(%r10), %r8
+	movq	40(%r10), %r9
+	testl	%eax, %eax
+	jnz	Lload_sse
+Lret_from_load_sse:
+
+	/* Deallocate the reg arg area.  */
+	leaq	176(%r10), %rsp
+
+	/* Call the user function.  */
+	call	*%r11
+
+	/* Deallocate stack arg area; local stack frame in redzone.  */
+	leaq	24(%rbp), %rsp
+
+	movq	0(%rbp), %rcx		/* Reload flags.  */
+	movq	8(%rbp), %rdi		/* Reload raddr.  */
+	movq	16(%rbp), %rbp		/* Reload old frame pointer.  */
+LUW2:
+
+	/* The first byte of the flags contains the FFI_TYPE.  */
+	movzbl	%cl, %r10d
+	leaq	Lstore_table(%rip), %r11
+	movslq	(%r11, %r10, 4), %r10
+	addq	%r11, %r10
+	jmp	*%r10
+
+Lstore_table:
+	.long	Lst_void-Lstore_table		/* FFI_TYPE_VOID */
+	.long	Lst_sint32-Lstore_table		/* FFI_TYPE_INT */
+	.long	Lst_float-Lstore_table		/* FFI_TYPE_FLOAT */
+	.long	Lst_double-Lstore_table		/* FFI_TYPE_DOUBLE */
+	.long	Lst_ldouble-Lstore_table	/* FFI_TYPE_LONGDOUBLE */
+	.long	Lst_uint8-Lstore_table		/* FFI_TYPE_UINT8 */
+	.long	Lst_sint8-Lstore_table		/* FFI_TYPE_SINT8 */
+	.long	Lst_uint16-Lstore_table		/* FFI_TYPE_UINT16 */
+	.long	Lst_sint16-Lstore_table		/* FFI_TYPE_SINT16 */
+	.long	Lst_uint32-Lstore_table		/* FFI_TYPE_UINT32 */
+	.long	Lst_sint32-Lstore_table		/* FFI_TYPE_SINT32 */
+	.long	Lst_int64-Lstore_table		/* FFI_TYPE_UINT64 */
+	.long	Lst_int64-Lstore_table		/* FFI_TYPE_SINT64 */
+	.long	Lst_struct-Lstore_table		/* FFI_TYPE_STRUCT */
+	.long	Lst_int64-Lstore_table		/* FFI_TYPE_POINTER */
+
+	.text
+	.align	3
+Lst_void:
+	ret
+	.align	3
+Lst_uint8:
+	movzbq	%al, %rax
+	movq	%rax, (%rdi)
+	ret
+	.align	3
+Lst_sint8:
+	movsbq	%al, %rax
+	movq	%rax, (%rdi)
+	ret
+	.align	3
+Lst_uint16:
+	movzwq	%ax, %rax
+	movq	%rax, (%rdi)
+	.align	3
+Lst_sint16:
+	movswq	%ax, %rax
+	movq	%rax, (%rdi)
+	ret
+	.align	3
+Lst_uint32:
+	movl	%eax, %eax
+	movq	%rax, (%rdi)
+	.align	3
+Lst_sint32:
+	cltq
+	movq	%rax, (%rdi)
+	ret
+	.align	3
+Lst_int64:
+	movq	%rax, (%rdi)
+	ret
+	.align	3
+Lst_float:
+	movss	%xmm0, (%rdi)
+	ret
+	.align	3
+Lst_double:
+	movsd	%xmm0, (%rdi)
+	ret
+Lst_ldouble:
+	fstpt	(%rdi)
+	ret
+	.align	3
+Lst_struct:
+	leaq	-20(%rsp), %rsi		/* Scratch area in redzone.  */
+
+	/* We have to locate the values now, and since we don't want to
+	   write too much data into the user's return value, we spill the
+	   value to a 16 byte scratch area first.  Bits 8, 9, and 10
+	   control where the values are located.  Only one of the three
+	   bits will be set; see ffi_prep_cif_machdep for the pattern.  */
+	movd	%xmm0, %r10
+	movd	%xmm1, %r11
+	testl	$0x100, %ecx
+	cmovnz	%rax, %rdx
+	cmovnz	%r10, %rax
+	testl	$0x200, %ecx
+	cmovnz	%r10, %rdx
+	testl	$0x400, %ecx
+	cmovnz	%r10, %rax
+	cmovnz	%r11, %rdx
+	movq	%rax, (%rsi)
+	movq	%rdx, 8(%rsi)
+
+	/* Bits 12-31 contain the true size of the structure.  Copy from
+	   the scratch area to the true destination.  */
+	shrl	$12, %ecx
+	rep movsb
+	ret
+
+	/* Many times we can avoid loading any SSE registers at all.
+	   It's not worth an indirect jump to load the exact set of
+	   SSE registers needed; zero or all is a good compromise.  */
+	.align	3
+LUW3:
+Lload_sse:
+	movdqa	48(%r10), %xmm0
+	movdqa	64(%r10), %xmm1
+	movdqa	80(%r10), %xmm2
+	movdqa	96(%r10), %xmm3
+	movdqa	112(%r10), %xmm4
+	movdqa	128(%r10), %xmm5
+	movdqa	144(%r10), %xmm6
+	movdqa	160(%r10), %xmm7
+	jmp	Lret_from_load_sse
+
+LUW4:
+	.align	3
+	.globl	_ffi_closure_unix64
+
+_ffi_closure_unix64:
+LUW5:
+	/* The carry flag is set by the trampoline iff SSE registers
+	   are used.  Don't clobber it before the branch instruction.  */
+	leaq    -200(%rsp), %rsp
+LUW6:
+	movq	%rdi, (%rsp)
+	movq    %rsi, 8(%rsp)
+	movq    %rdx, 16(%rsp)
+	movq    %rcx, 24(%rsp)
+	movq    %r8, 32(%rsp)
+	movq    %r9, 40(%rsp)
+	jc      Lsave_sse
+Lret_from_save_sse:
+
+	movq	%r10, %rdi
+	leaq	176(%rsp), %rsi
+	movq	%rsp, %rdx
+	leaq	208(%rsp), %rcx
+	call	_ffi_closure_unix64_inner
+
+	/* Deallocate stack frame early; return value is now in redzone.  */
+	addq	$200, %rsp
+LUW7:
+
+	/* The first byte of the return value contains the FFI_TYPE.  */
+	movzbl	%al, %r10d
+	leaq	Lload_table(%rip), %r11
+	movslq	(%r11, %r10, 4), %r10
+	addq	%r11, %r10
+	jmp	*%r10
+
+Lload_table:
+	.long	Lld_void-Lload_table		/* FFI_TYPE_VOID */
+	.long	Lld_int32-Lload_table		/* FFI_TYPE_INT */
+	.long	Lld_float-Lload_table		/* FFI_TYPE_FLOAT */
+	.long	Lld_double-Lload_table		/* FFI_TYPE_DOUBLE */
+	.long	Lld_ldouble-Lload_table		/* FFI_TYPE_LONGDOUBLE */
+	.long	Lld_int8-Lload_table		/* FFI_TYPE_UINT8 */
+	.long	Lld_int8-Lload_table		/* FFI_TYPE_SINT8 */
+	.long	Lld_int16-Lload_table		/* FFI_TYPE_UINT16 */
+	.long	Lld_int16-Lload_table		/* FFI_TYPE_SINT16 */
+	.long	Lld_int32-Lload_table		/* FFI_TYPE_UINT32 */
+	.long	Lld_int32-Lload_table		/* FFI_TYPE_SINT32 */
+	.long	Lld_int64-Lload_table		/* FFI_TYPE_UINT64 */
+	.long	Lld_int64-Lload_table		/* FFI_TYPE_SINT64 */
+	.long	Lld_struct-Lload_table		/* FFI_TYPE_STRUCT */
+	.long	Lld_int64-Lload_table		/* FFI_TYPE_POINTER */
+
+	.text
+	.align	3
+Lld_void:
+	ret
+	.align	3
+Lld_int8:
+	movzbl	-24(%rsp), %eax
+	ret
+	.align	3
+Lld_int16:
+	movzwl	-24(%rsp), %eax
+	ret
+	.align	3
+Lld_int32:
+	movl	-24(%rsp), %eax
+	ret
+	.align	3
+Lld_int64:
+	movq	-24(%rsp), %rax
+	ret
+	.align	3
+Lld_float:
+	movss	-24(%rsp), %xmm0
+	ret
+	.align	3
+Lld_double:
+	movsd	-24(%rsp), %xmm0
+	ret
+	.align	3
+Lld_ldouble:
+	fldt	-24(%rsp)
+	ret
+	.align	3
+Lld_struct:
+	/* There are four possibilities here, %rax/%rdx, %xmm0/%rax,
+	   %rax/%xmm0, %xmm0/%xmm1.  We collapse two by always loading
+	   both rdx and xmm1 with the second word.  For the remaining,
+	   bit 8 set means xmm0 gets the second word, and bit 9 means
+	   that rax gets the second word.  */
+	movq	-24(%rsp), %rcx
+	movq	-16(%rsp), %rdx
+	movq	-16(%rsp), %xmm1
+	testl	$0x100, %eax
+	cmovnz	%rdx, %rcx
+	movd	%rcx, %xmm0
+	testl	$0x200, %eax
+	movq	-24(%rsp), %rax
+	cmovnz	%rdx, %rax
+	ret
+
+	/* See the comment above Lload_sse; the same logic applies here.  */
+	.align	3
+LUW8:
+Lsave_sse:
+	movdqa	%xmm0, 48(%rsp)
+	movdqa	%xmm1, 64(%rsp)
+	movdqa	%xmm2, 80(%rsp)
+	movdqa	%xmm3, 96(%rsp)
+	movdqa	%xmm4, 112(%rsp)
+	movdqa	%xmm5, 128(%rsp)
+	movdqa	%xmm6, 144(%rsp)
+	movdqa	%xmm7, 160(%rsp)
+	jmp	Lret_from_save_sse
+
+LUW9:
+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
+EH_frame1:
+	.set	L$set$0,LECIE1-LSCIE1		/* CIE Length */
+	.long	L$set$0
+LSCIE1:
+	.long	0x0		/* CIE Identifier Tag */
+	.byte	0x1		/* CIE Version */
+	.ascii	"zR\0"		/* CIE Augmentation */
+	.byte	0x1		/* uleb128 0x1; CIE Code Alignment Factor */
+	.byte	0x78		/* sleb128 -8; CIE Data Alignment Factor */
+	.byte	0x10		/* CIE RA Column */
+	.byte	0x1		/* uleb128 0x1; Augmentation size */
+	.byte	0x10		/* FDE Encoding (pcrel sdata4) */
+	.byte	0xc		/* DW_CFA_def_cfa, %rsp offset 8 */
+	.byte	0x7		/* uleb128 0x7 */
+	.byte	0x8		/* uleb128 0x8 */
+	.byte	0x90		/* DW_CFA_offset, column 0x10 */
+	.byte	0x1
+	.align	3
+LECIE1:
+	.globl _ffi_call_unix64.eh
+_ffi_call_unix64.eh:
+LSFDE1:
+	.set	L$set$1,LEFDE1-LASFDE1	/* FDE Length */
+	.long	L$set$1
+LASFDE1:
+	.long	LASFDE1-EH_frame1	/* FDE CIE offset */
+	.quad	LUW0-.			/* FDE initial location */
+	.set	L$set$2,LUW4-LUW0	/* FDE address range */
+	.quad	L$set$2
+	.byte	0x0			/* Augmentation size */
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.set	L$set$3,LUW1-LUW0
+	.long	L$set$3
+
+	/* New stack frame based off rbp.  This is a itty bit of unwind
+	   trickery in that the CFA *has* changed.  There is no easy way
+	   to describe it correctly on entry to the function.  Fortunately,
+	   it doesn't matter too much since at all points we can correctly
+	   unwind back to ffi_call.  Note that the location to which we
+	   moved the return address is (the new) CFA-8, so from the
+	   perspective of the unwind info, it hasn't moved.  */
+	.byte	0xc			/* DW_CFA_def_cfa, %rbp offset 32 */
+	.byte	0x6
+	.byte	0x20
+	.byte	0x80+6			/* DW_CFA_offset, %rbp offset 2*-8 */
+	.byte	0x2
+	.byte	0xa			/* DW_CFA_remember_state */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.set	L$set$4,LUW2-LUW1
+	.long	L$set$4
+	.byte	0xc			/* DW_CFA_def_cfa, %rsp offset 8 */
+	.byte	0x7
+	.byte	0x8
+	.byte	0xc0+6			/* DW_CFA_restore, %rbp */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.set	L$set$5,LUW3-LUW2
+	.long	L$set$5
+	.byte	0xb			/* DW_CFA_restore_state */
+
+	.align	3
+LEFDE1:
+	.globl _ffi_closure_unix64.eh
+_ffi_closure_unix64.eh:
+LSFDE3:
+	.set	L$set$6,LEFDE3-LASFDE3	/* FDE Length */
+	.long	L$set$6
+LASFDE3:
+	.long	LASFDE3-EH_frame1	/* FDE CIE offset */
+	.quad	LUW5-.			/* FDE initial location */
+	.set	L$set$7,LUW9-LUW5	/* FDE address range */
+	.quad	L$set$7
+	.byte	0x0			/* Augmentation size */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.set	L$set$8,LUW6-LUW5
+	.long	L$set$8
+	.byte	0xe			/* DW_CFA_def_cfa_offset */
+	.byte	208,1			/* uleb128 208 */
+	.byte	0xa			/* DW_CFA_remember_state */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.set	L$set$9,LUW7-LUW6
+	.long	L$set$9
+	.byte	0xe			/* DW_CFA_def_cfa_offset */
+	.byte	0x8
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.set	L$set$10,LUW8-LUW7
+	.long	L$set$10
+	.byte	0xb			/* DW_CFA_restore_state */
+
+	.align	3
+LEFDE3:
+	.subsections_via_symbols
+
+#endif /* __x86_64__ */
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/ffi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/ffi.c
new file mode 100755
index 0000000..34f9c66
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/ffi.c
@@ -0,0 +1,644 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008  Red Hat, Inc.
+           Copyright (c) 2002  Ranjit Mathew
+           Copyright (c) 2002  Bo Thorsen
+           Copyright (c) 2002  Roger Sayle
+           Copyright (C) 2008, 2010  Free Software Foundation, Inc.
+
+   x86 Foreign Function Interface
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#if !defined(__x86_64__) || defined(_WIN64)
+
+#ifdef _WIN64
+#include <windows.h>
+#endif
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+void ffi_prep_args(char *stack, extended_cif *ecif)
+{
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+
+  argp = stack;
+
+  if (ecif->cif->flags == FFI_TYPE_STRUCT
+#ifdef X86_WIN64
+      && (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2
+          && ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8)
+#endif
+      )
+    {
+      *(void **) argp = ecif->rvalue;
+      argp += sizeof(void*);
+    }
+
+  p_argv = ecif->avalue;
+
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+       i != 0;
+       i--, p_arg++)
+    {
+      size_t z;
+
+      /* Align if necessary */
+      if ((sizeof(void*) - 1) & (size_t) argp)
+        argp = (char *) ALIGN(argp, sizeof(void*));
+
+      z = (*p_arg)->size;
+#ifdef X86_WIN64
+      if (z > sizeof(ffi_arg)
+          || ((*p_arg)->type == FFI_TYPE_STRUCT
+              && (z != 1 && z != 2 && z != 4 && z != 8))
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
+          || ((*p_arg)->type == FFI_TYPE_LONGDOUBLE)
+#endif
+          )
+        {
+          z = sizeof(ffi_arg);
+          *(void **)argp = *p_argv;
+        }
+      else if ((*p_arg)->type == FFI_TYPE_FLOAT)
+        {
+          memcpy(argp, *p_argv, z);
+        }
+      else
+#endif
+      if (z < sizeof(ffi_arg))
+        {
+          z = sizeof(ffi_arg);
+          switch ((*p_arg)->type)
+            {
+            case FFI_TYPE_SINT8:
+              *(ffi_sarg *) argp = (ffi_sarg)*(SINT8 *)(* p_argv);
+              break;
+
+            case FFI_TYPE_UINT8:
+              *(ffi_arg *) argp = (ffi_arg)*(UINT8 *)(* p_argv);
+              break;
+
+            case FFI_TYPE_SINT16:
+              *(ffi_sarg *) argp = (ffi_sarg)*(SINT16 *)(* p_argv);
+              break;
+
+            case FFI_TYPE_UINT16:
+              *(ffi_arg *) argp = (ffi_arg)*(UINT16 *)(* p_argv);
+              break;
+
+            case FFI_TYPE_SINT32:
+              *(ffi_sarg *) argp = (ffi_sarg)*(SINT32 *)(* p_argv);
+              break;
+
+            case FFI_TYPE_UINT32:
+              *(ffi_arg *) argp = (ffi_arg)*(UINT32 *)(* p_argv);
+              break;
+
+            case FFI_TYPE_STRUCT:
+              *(ffi_arg *) argp = *(ffi_arg *)(* p_argv);
+              break;
+
+            default:
+              FFI_ASSERT(0);
+            }
+        }
+      else
+        {
+          memcpy(argp, *p_argv, z);
+        }
+      p_argv++;
+#ifdef X86_WIN64
+      argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
+#else
+      argp += z;
+#endif
+    }
+  
+  return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  unsigned int i;
+  ffi_type **ptr;
+
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_SINT16:
+#ifdef X86_WIN64
+    case FFI_TYPE_UINT32:
+    case FFI_TYPE_SINT32:
+#endif
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+#ifndef X86_WIN64
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
+    case FFI_TYPE_LONGDOUBLE:
+#endif
+#endif
+      cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+    case FFI_TYPE_UINT64:
+#ifdef X86_WIN64
+    case FFI_TYPE_POINTER:
+#endif
+      cif->flags = FFI_TYPE_SINT64;
+      break;
+
+    case FFI_TYPE_STRUCT:
+#ifndef X86
+      if (cif->rtype->size == 1)
+        {
+          cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
+        }
+      else if (cif->rtype->size == 2)
+        {
+          cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */
+        }
+      else if (cif->rtype->size == 4)
+        {
+#ifdef X86_WIN64
+          cif->flags = FFI_TYPE_SMALL_STRUCT_4B;
+#else
+          cif->flags = FFI_TYPE_INT; /* same as int type */
+#endif
+        }
+      else if (cif->rtype->size == 8)
+        {
+          cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
+        }
+      else
+#endif
+        {
+          cif->flags = FFI_TYPE_STRUCT;
+          /* allocate space for return value pointer */
+          cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
+        }
+      break;
+
+    default:
+#ifdef X86_WIN64
+      cif->flags = FFI_TYPE_SINT64;
+      break;
+    case FFI_TYPE_INT:
+      cif->flags = FFI_TYPE_SINT32;
+#else
+      cif->flags = FFI_TYPE_INT;
+#endif
+      break;
+    }
+
+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+    {
+      if (((*ptr)->alignment - 1) & cif->bytes)
+        cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
+      cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
+    }
+
+#ifdef X86_WIN64
+  /* ensure space for storing four registers */
+  cif->bytes += 4 * sizeof(ffi_arg);
+#endif
+
+#ifdef X86_DARWIN
+  cif->bytes = (cif->bytes + 15) & ~0xF;
+#endif
+
+  return FFI_OK;
+}
+
+#ifdef X86_WIN64
+extern int
+ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
+               unsigned, unsigned, unsigned *, void (*fn)(void));
+#elif defined(X86_WIN32)
+extern void
+ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
+               unsigned, unsigned, unsigned *, void (*fn)(void));
+#else
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
+                          unsigned, unsigned, unsigned *, void (*fn)(void));
+#endif
+
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return */
+  /* value address then we need to make one                     */
+
+#ifdef X86_WIN64
+  if (rvalue == NULL
+      && cif->flags == FFI_TYPE_STRUCT
+      && cif->rtype->size != 1 && cif->rtype->size != 2
+      && cif->rtype->size != 4 && cif->rtype->size != 8)
+    {
+      ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF);
+    }
+#else
+  if (rvalue == NULL
+      && cif->flags == FFI_TYPE_STRUCT)
+    {
+      ecif.rvalue = alloca(cif->rtype->size);
+    }
+#endif
+  else
+    ecif.rvalue = rvalue;
+    
+  
+  switch (cif->abi) 
+    {
+#ifdef X86_WIN64
+    case FFI_WIN64:
+      ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
+                     cif->flags, ecif.rvalue, fn);
+      break;
+#elif defined(X86_WIN32)
+    case FFI_SYSV:
+    case FFI_STDCALL:
+      ffi_call_win32(ffi_prep_args, &ecif, cif->bytes, cif->flags,
+                     ecif.rvalue, fn);
+      break;
+#else
+    case FFI_SYSV:
+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
+                    fn);
+      break;
+#endif
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+
+/** private members **/
+
+/* The following __attribute__((regparm(1))) decorations will have no effect
+   on MSVC - standard cdecl convention applies. */
+static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
+                                         void** args, ffi_cif* cif);
+void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
+     __attribute__ ((regparm(1)));
+unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
+     __attribute__ ((regparm(1)));
+void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
+     __attribute__ ((regparm(1)));
+#ifdef X86_WIN32
+void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
+     __attribute__ ((regparm(1)));
+#endif
+#ifdef X86_WIN64
+void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
+#endif
+
+/* This function is jumped to by the trampoline */
+
+#ifdef X86_WIN64
+void * FFI_HIDDEN
+ffi_closure_win64_inner (ffi_closure *closure, void *args) {
+  ffi_cif       *cif;
+  void         **arg_area;
+  void          *result;
+  void          *resp = &result;
+
+  cif         = closure->cif;
+  arg_area    = (void**) alloca (cif->nargs * sizeof (void*));  
+
+  /* this call will initialize ARG_AREA, such that each
+   * element in that array points to the corresponding 
+   * value on the stack; and if the function returns
+   * a structure, it will change RESP to point to the
+   * structure return address.  */
+
+  ffi_prep_incoming_args_SYSV(args, &resp, arg_area, cif);
+  
+  (closure->fun) (cif, resp, arg_area, closure->user_data);
+
+  /* The result is returned in rax.  This does the right thing for
+     result types except for floats; we have to 'mov xmm0, rax' in the
+     caller to correct this.
+     TODO: structure sizes of 3 5 6 7 are returned by reference, too!!!
+  */
+  return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp;
+}
+
+#else
+unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
+ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
+{
+  /* our various things...  */
+  ffi_cif       *cif;
+  void         **arg_area;
+
+  cif         = closure->cif;
+  arg_area    = (void**) alloca (cif->nargs * sizeof (void*));  
+
+  /* this call will initialize ARG_AREA, such that each
+   * element in that array points to the corresponding 
+   * value on the stack; and if the function returns
+   * a structure, it will change RESP to point to the
+   * structure return address.  */
+
+  ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
+
+  (closure->fun) (cif, *respp, arg_area, closure->user_data);
+
+  return cif->flags;
+}
+#endif /* !X86_WIN64 */
+
+static void
+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
+                            ffi_cif *cif)
+{
+  register unsigned int i;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+
+  argp = stack;
+
+#ifdef X86_WIN64
+  if (cif->rtype->size > sizeof(ffi_arg)
+      || (cif->flags == FFI_TYPE_STRUCT
+          && (cif->rtype->size != 1 && cif->rtype->size != 2
+              && cif->rtype->size != 4 && cif->rtype->size != 8))) {
+    *rvalue = *(void **) argp;
+    argp += sizeof(void *);
+  }
+#else
+  if ( cif->flags == FFI_TYPE_STRUCT ) {
+    *rvalue = *(void **) argp;
+    argp += sizeof(void *);
+  }
+#endif
+
+  p_argv = avalue;
+
+  for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+    {
+      size_t z;
+
+      /* Align if necessary */
+      if ((sizeof(void*) - 1) & (size_t) argp) {
+        argp = (char *) ALIGN(argp, sizeof(void*));
+      }
+
+#ifdef X86_WIN64
+      if ((*p_arg)->size > sizeof(ffi_arg)
+          || ((*p_arg)->type == FFI_TYPE_STRUCT
+              && ((*p_arg)->size != 1 && (*p_arg)->size != 2
+                  && (*p_arg)->size != 4 && (*p_arg)->size != 8)))
+        {
+          z = sizeof(void *);
+          *p_argv = *(void **)argp;
+        }
+      else
+#endif
+        {
+          z = (*p_arg)->size;
+          
+          /* because we're little endian, this is what it turns into.   */
+          
+          *p_argv = (void*) argp;
+        }
+          
+      p_argv++;
+#ifdef X86_WIN64
+      argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
+#else
+      argp += z;
+#endif
+    }
+  
+  return;
+}
+
+#define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \
+{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+   void*  __fun = (void*)(FUN); \
+   void*  __ctx = (void*)(CTX); \
+   *(unsigned char*) &__tramp[0] = 0x41; \
+   *(unsigned char*) &__tramp[1] = 0xbb; \
+   *(unsigned int*) &__tramp[2] = MASK; /* mov $mask, %r11 */ \
+   *(unsigned char*) &__tramp[6] = 0x48; \
+   *(unsigned char*) &__tramp[7] = 0xb8; \
+   *(void**) &__tramp[8] = __ctx; /* mov __ctx, %rax */ \
+   *(unsigned char *)  &__tramp[16] = 0x49; \
+   *(unsigned char *)  &__tramp[17] = 0xba; \
+   *(void**) &__tramp[18] = __fun; /* mov __fun, %r10 */ \
+   *(unsigned char *)  &__tramp[26] = 0x41; \
+   *(unsigned char *)  &__tramp[27] = 0xff; \
+   *(unsigned char *)  &__tramp[28] = 0xe2; /* jmp %r10 */ \
+ }
+
+/* How to make a trampoline.  Derived from gcc/config/i386/i386.c. */
+
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
+{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+   unsigned int  __fun = (unsigned int)(FUN); \
+   unsigned int  __ctx = (unsigned int)(CTX); \
+   unsigned int  __dis = __fun - (__ctx + 10);  \
+   *(unsigned char*) &__tramp[0] = 0xb8; \
+   *(unsigned int*)  &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
+   *(unsigned char *)  &__tramp[5] = 0xe9; \
+   *(unsigned int*)  &__tramp[6] = __dis; /* jmp __fun  */ \
+ }
+
+#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE)  \
+{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+   unsigned int  __fun = (unsigned int)(FUN); \
+   unsigned int  __ctx = (unsigned int)(CTX); \
+   unsigned int  __dis = __fun - (__ctx + 10); \
+   unsigned short __size = (unsigned short)(SIZE); \
+   *(unsigned char*) &__tramp[0] = 0xb8; \
+   *(unsigned int*)  &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
+   *(unsigned char *)  &__tramp[5] = 0xe8; \
+   *(unsigned int*)  &__tramp[6] = __dis; /* call __fun  */ \
+   *(unsigned char *)  &__tramp[10] = 0xc2; \
+   *(unsigned short*)  &__tramp[11] = __size; /* ret __size  */ \
+ }
+
+/* the cif must already be prep'ed */
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+                      ffi_cif* cif,
+                      void (*fun)(ffi_cif*,void*,void**,void*),
+                      void *user_data,
+                      void *codeloc)
+{
+#ifdef X86_WIN64
+#define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE)
+#define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0)
+  if (cif->abi == FFI_WIN64) 
+    {
+      int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
+      FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0],
+                                 &ffi_closure_win64,
+                                 codeloc, mask);
+      /* make sure we can execute here */
+    }
+#else
+  if (cif->abi == FFI_SYSV)
+    {
+      FFI_INIT_TRAMPOLINE (&closure->tramp[0],
+                           &ffi_closure_SYSV,
+                           (void*)codeloc);
+    }
+#ifdef X86_WIN32
+  else if (cif->abi == FFI_STDCALL)
+    {
+      FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
+                                   &ffi_closure_STDCALL,
+                                   (void*)codeloc, cif->bytes);
+    }
+#endif /* X86_WIN32 */
+#endif /* !X86_WIN64 */
+  else
+    {
+      return FFI_BAD_ABI;
+    }
+    
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+
+  return FFI_OK;
+}
+
+/* ------- Native raw API support -------------------------------- */
+
+#if !FFI_NO_RAW_API
+
+ffi_status
+ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
+                          ffi_cif* cif,
+                          void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+                          void *user_data,
+                          void *codeloc)
+{
+  int i;
+
+  if (cif->abi != FFI_SYSV) {
+    return FFI_BAD_ABI;
+  }
+
+  /* we currently don't support certain kinds of arguments for raw
+     closures.  This should be implemented by a separate assembly
+     language routine, since it would require argument processing,
+     something we don't do now for performance.  */
+
+  for (i = cif->nargs-1; i >= 0; i--)
+    {
+      FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
+      FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
+    }
+  
+
+  FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
+                       codeloc);
+    
+  closure->cif  = cif;
+  closure->user_data = user_data;
+  closure->fun  = fun;
+
+  return FFI_OK;
+}
+
+static void 
+ffi_prep_args_raw(char *stack, extended_cif *ecif)
+{
+  memcpy (stack, ecif->avalue, ecif->cif->bytes);
+}
+
+/* we borrow this routine from libffi (it must be changed, though, to
+ * actually call the function passed in the first argument.  as of
+ * libffi-1.20, this is not the case.)
+ */
+
+void
+ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
+{
+  extended_cif ecif;
+  void **avalue = (void **)fake_avalue;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return */
+  /* value address then we need to make one                     */
+
+  if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      ecif.rvalue = alloca(cif->rtype->size);
+    }
+  else
+    ecif.rvalue = rvalue;
+    
+  
+  switch (cif->abi) 
+    {
+#ifdef X86_WIN32
+    case FFI_SYSV:
+    case FFI_STDCALL:
+      ffi_call_win32(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
+                     ecif.rvalue, fn);
+      break;
+#else
+    case FFI_SYSV:
+      ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
+                    ecif.rvalue, fn);
+      break;
+#endif
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+#endif
+
+#endif /* !__x86_64__  || X86_WIN64 */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/ffi64.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/ffi64.c
new file mode 100755
index 0000000..c8eb455
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/ffi64.c
@@ -0,0 +1,635 @@
+/* -----------------------------------------------------------------------
+   ffi64.c - Copyright (c) 20011  Anthony Green
+             Copyright (c) 2008, 2010  Red Hat, Inc.
+             Copyright (c) 2002, 2007  Bo Thorsen <bo at suse.de>
+             
+   x86-64 Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#ifdef __x86_64__
+
+#define MAX_GPR_REGS 6
+#define MAX_SSE_REGS 8
+
+struct register_args
+{
+  /* Registers for argument passing.  */
+  UINT64 gpr[MAX_GPR_REGS];
+  __int128_t sse[MAX_SSE_REGS];
+};
+
+extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
+			     void *raddr, void (*fnaddr)(void), unsigned ssecount);
+
+/* All reference to register classes here is identical to the code in
+   gcc/config/i386/i386.c. Do *not* change one without the other.  */
+
+/* Register class used for passing given 64bit part of the argument.
+   These represent classes as documented by the PS ABI, with the
+   exception of SSESF, SSEDF classes, that are basically SSE class,
+   just gcc will use SF or DFmode move instead of DImode to avoid
+   reformatting penalties.
+
+   Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
+   whenever possible (upper half does contain padding).  */
+enum x86_64_reg_class
+  {
+    X86_64_NO_CLASS,
+    X86_64_INTEGER_CLASS,
+    X86_64_INTEGERSI_CLASS,
+    X86_64_SSE_CLASS,
+    X86_64_SSESF_CLASS,
+    X86_64_SSEDF_CLASS,
+    X86_64_SSEUP_CLASS,
+    X86_64_X87_CLASS,
+    X86_64_X87UP_CLASS,
+    X86_64_COMPLEX_X87_CLASS,
+    X86_64_MEMORY_CLASS
+  };
+
+#define MAX_CLASSES 4
+
+#define SSE_CLASS_P(X)	((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS)
+
+/* x86-64 register passing implementation.  See x86-64 ABI for details.  Goal
+   of this code is to classify each 8bytes of incoming argument by the register
+   class and assign registers accordingly.  */
+
+/* Return the union class of CLASS1 and CLASS2.
+   See the x86-64 PS ABI for details.  */
+
+static enum x86_64_reg_class
+merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
+{
+  /* Rule #1: If both classes are equal, this is the resulting class.  */
+  if (class1 == class2)
+    return class1;
+
+  /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
+     the other class.  */
+  if (class1 == X86_64_NO_CLASS)
+    return class2;
+  if (class2 == X86_64_NO_CLASS)
+    return class1;
+
+  /* Rule #3: If one of the classes is MEMORY, the result is MEMORY.  */
+  if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
+    return X86_64_MEMORY_CLASS;
+
+  /* Rule #4: If one of the classes is INTEGER, the result is INTEGER.  */
+  if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
+      || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
+    return X86_64_INTEGERSI_CLASS;
+  if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
+      || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
+    return X86_64_INTEGER_CLASS;
+
+  /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
+     MEMORY is used.  */
+  if (class1 == X86_64_X87_CLASS
+      || class1 == X86_64_X87UP_CLASS
+      || class1 == X86_64_COMPLEX_X87_CLASS
+      || class2 == X86_64_X87_CLASS
+      || class2 == X86_64_X87UP_CLASS
+      || class2 == X86_64_COMPLEX_X87_CLASS)
+    return X86_64_MEMORY_CLASS;
+
+  /* Rule #6: Otherwise class SSE is used.  */
+  return X86_64_SSE_CLASS;
+}
+
+/* Classify the argument of type TYPE and mode MODE.
+   CLASSES will be filled by the register class used to pass each word
+   of the operand.  The number of words is returned.  In case the parameter
+   should be passed in memory, 0 is returned. As a special case for zero
+   sized containers, classes[0] will be NO_CLASS and 1 is returned.
+
+   See the x86-64 PS ABI for details.
+*/
+static int
+classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
+		   size_t byte_offset)
+{
+  switch (type->type)
+    {
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_UINT32:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_POINTER:
+      {
+	int size = byte_offset + type->size;
+
+	if (size <= 4)
+	  {
+	    classes[0] = X86_64_INTEGERSI_CLASS;
+	    return 1;
+	  }
+	else if (size <= 8)
+	  {
+	    classes[0] = X86_64_INTEGER_CLASS;
+	    return 1;
+	  }
+	else if (size <= 12)
+	  {
+	    classes[0] = X86_64_INTEGER_CLASS;
+	    classes[1] = X86_64_INTEGERSI_CLASS;
+	    return 2;
+	  }
+	else if (size <= 16)
+	  {
+	    classes[0] = classes[1] = X86_64_INTEGERSI_CLASS;
+	    return 2;
+	  }
+	else
+	  FFI_ASSERT (0);
+      }
+    case FFI_TYPE_FLOAT:
+      if (!(byte_offset % 8))
+	classes[0] = X86_64_SSESF_CLASS;
+      else
+	classes[0] = X86_64_SSE_CLASS;
+      return 1;
+    case FFI_TYPE_DOUBLE:
+      classes[0] = X86_64_SSEDF_CLASS;
+      return 1;
+    case FFI_TYPE_LONGDOUBLE:
+      classes[0] = X86_64_X87_CLASS;
+      classes[1] = X86_64_X87UP_CLASS;
+      return 2;
+    case FFI_TYPE_STRUCT:
+      {
+	const int UNITS_PER_WORD = 8;
+	int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+	ffi_type **ptr; 
+	int i;
+	enum x86_64_reg_class subclasses[MAX_CLASSES];
+
+	/* If the struct is larger than 32 bytes, pass it on the stack.  */
+	if (type->size > 32)
+	  return 0;
+
+	for (i = 0; i < words; i++)
+	  classes[i] = X86_64_NO_CLASS;
+
+	/* Zero sized arrays or structures are NO_CLASS.  We return 0 to
+	   signalize memory class, so handle it as special case.  */
+	if (!words)
+	  {
+	    classes[0] = X86_64_NO_CLASS;
+	    return 1;
+	  }
+
+	/* Merge the fields of structure.  */
+	for (ptr = type->elements; *ptr != NULL; ptr++)
+	  {
+	    int num;
+
+	    byte_offset = ALIGN (byte_offset, (*ptr)->alignment);
+
+	    num = classify_argument (*ptr, subclasses, byte_offset % 8);
+	    if (num == 0)
+	      return 0;
+	    for (i = 0; i < num; i++)
+	      {
+		int pos = byte_offset / 8;
+		classes[i + pos] =
+		  merge_classes (subclasses[i], classes[i + pos]);
+	      }
+
+	    byte_offset += (*ptr)->size;
+	  }
+
+	if (words > 2)
+	  {
+	    /* When size > 16 bytes, if the first one isn't
+	       X86_64_SSE_CLASS or any other ones aren't
+	       X86_64_SSEUP_CLASS, everything should be passed in
+	       memory.  */
+	    if (classes[0] != X86_64_SSE_CLASS)
+	      return 0;
+
+	    for (i = 1; i < words; i++)
+	      if (classes[i] != X86_64_SSEUP_CLASS)
+		return 0;
+	  }
+
+	/* Final merger cleanup.  */
+	for (i = 0; i < words; i++)
+	  {
+	    /* If one class is MEMORY, everything should be passed in
+	       memory.  */
+	    if (classes[i] == X86_64_MEMORY_CLASS)
+	      return 0;
+
+	    /* The X86_64_SSEUP_CLASS should be always preceded by
+	       X86_64_SSE_CLASS or X86_64_SSEUP_CLASS.  */
+	    if (classes[i] == X86_64_SSEUP_CLASS
+		&& classes[i - 1] != X86_64_SSE_CLASS
+		&& classes[i - 1] != X86_64_SSEUP_CLASS)
+	      {
+		/* The first one should never be X86_64_SSEUP_CLASS.  */
+		FFI_ASSERT (i != 0);
+		classes[i] = X86_64_SSE_CLASS;
+	      }
+
+	    /*  If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
+		everything should be passed in memory.  */
+	    if (classes[i] == X86_64_X87UP_CLASS
+		&& (classes[i - 1] != X86_64_X87_CLASS))
+	      {
+		/* The first one should never be X86_64_X87UP_CLASS.  */
+		FFI_ASSERT (i != 0);
+		return 0;
+	      }
+	  }
+	return words;
+      }
+
+    default:
+      FFI_ASSERT(0);
+    }
+  return 0; /* Never reached.  */
+}
+
+/* Examine the argument and return set number of register required in each
+   class.  Return zero iff parameter should be passed in memory, otherwise
+   the number of registers.  */
+
+static int
+examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES],
+		  _Bool in_return, int *pngpr, int *pnsse)
+{
+  int i, n, ngpr, nsse;
+
+  n = classify_argument (type, classes, 0);
+  if (n == 0)
+    return 0;
+
+  ngpr = nsse = 0;
+  for (i = 0; i < n; ++i)
+    switch (classes[i])
+      {
+      case X86_64_INTEGER_CLASS:
+      case X86_64_INTEGERSI_CLASS:
+	ngpr++;
+	break;
+      case X86_64_SSE_CLASS:
+      case X86_64_SSESF_CLASS:
+      case X86_64_SSEDF_CLASS:
+	nsse++;
+	break;
+      case X86_64_NO_CLASS:
+      case X86_64_SSEUP_CLASS:
+	break;
+      case X86_64_X87_CLASS:
+      case X86_64_X87UP_CLASS:
+      case X86_64_COMPLEX_X87_CLASS:
+	return in_return != 0;
+      default:
+	abort ();
+      }
+
+  *pngpr = ngpr;
+  *pnsse = nsse;
+
+  return n;
+}
+
+/* Perform machine dependent cif processing.  */
+
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+  int gprcount, ssecount, i, avn, n, ngpr, nsse, flags;
+  enum x86_64_reg_class classes[MAX_CLASSES];
+  size_t bytes;
+
+  gprcount = ssecount = 0;
+
+  flags = cif->rtype->type;
+  if (flags != FFI_TYPE_VOID)
+    {
+      n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
+      if (n == 0)
+	{
+	  /* The return value is passed in memory.  A pointer to that
+	     memory is the first argument.  Allocate a register for it.  */
+	  gprcount++;
+	  /* We don't have to do anything in asm for the return.  */
+	  flags = FFI_TYPE_VOID;
+	}
+      else if (flags == FFI_TYPE_STRUCT)
+	{
+	  /* Mark which registers the result appears in.  */
+	  _Bool sse0 = SSE_CLASS_P (classes[0]);
+	  _Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]);
+	  if (sse0 && !sse1)
+	    flags |= 1 << 8;
+	  else if (!sse0 && sse1)
+	    flags |= 1 << 9;
+	  else if (sse0 && sse1)
+	    flags |= 1 << 10;
+	  /* Mark the true size of the structure.  */
+	  flags |= cif->rtype->size << 12;
+	}
+    }
+
+  /* Go over all arguments and determine the way they should be passed.
+     If it's in a register and there is space for it, let that be so. If
+     not, add it's size to the stack byte count.  */
+  for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++)
+    {
+      if (examine_argument (cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0
+	  || gprcount + ngpr > MAX_GPR_REGS
+	  || ssecount + nsse > MAX_SSE_REGS)
+	{
+	  long align = cif->arg_types[i]->alignment;
+
+	  if (align < 8)
+	    align = 8;
+
+	  bytes = ALIGN (bytes, align);
+	  bytes += cif->arg_types[i]->size;
+	}
+      else
+	{
+	  gprcount += ngpr;
+	  ssecount += nsse;
+	}
+    }
+  if (ssecount)
+    flags |= 1 << 11;
+  cif->flags = flags;
+  cif->bytes = ALIGN (bytes, 8);
+
+  return FFI_OK;
+}
+
+void
+ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  enum x86_64_reg_class classes[MAX_CLASSES];
+  char *stack, *argp;
+  ffi_type **arg_types;
+  int gprcount, ssecount, ngpr, nsse, i, avn;
+  _Bool ret_in_memory;
+  struct register_args *reg_args;
+
+  /* Can't call 32-bit mode from 64-bit mode.  */
+  FFI_ASSERT (cif->abi == FFI_UNIX64);
+
+  /* If the return value is a struct and we don't have a return value
+     address then we need to make one.  Note the setting of flags to
+     VOID above in ffi_prep_cif_machdep.  */
+  ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT
+		   && (cif->flags & 0xff) == FFI_TYPE_VOID);
+  if (rvalue == NULL && ret_in_memory)
+    rvalue = alloca (cif->rtype->size);
+
+  /* Allocate the space for the arguments, plus 4 words of temp space.  */
+  stack = alloca (sizeof (struct register_args) + cif->bytes + 4*8);
+  reg_args = (struct register_args *) stack;
+  argp = stack + sizeof (struct register_args);
+
+  gprcount = ssecount = 0;
+
+  /* If the return value is passed in memory, add the pointer as the
+     first integer argument.  */
+  if (ret_in_memory)
+    reg_args->gpr[gprcount++] = (long) rvalue;
+
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+
+  for (i = 0; i < avn; ++i)
+    {
+      size_t size = arg_types[i]->size;
+      int n;
+
+      n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
+      if (n == 0
+	  || gprcount + ngpr > MAX_GPR_REGS
+	  || ssecount + nsse > MAX_SSE_REGS)
+	{
+	  long align = arg_types[i]->alignment;
+
+	  /* Stack arguments are *always* at least 8 byte aligned.  */
+	  if (align < 8)
+	    align = 8;
+
+	  /* Pass this argument in memory.  */
+	  argp = (void *) ALIGN (argp, align);
+	  memcpy (argp, avalue[i], size);
+	  argp += size;
+	}
+      else
+	{
+	  /* The argument is passed entirely in registers.  */
+	  char *a = (char *) avalue[i];
+	  int j;
+
+	  for (j = 0; j < n; j++, a += 8, size -= 8)
+	    {
+	      switch (classes[j])
+		{
+		case X86_64_INTEGER_CLASS:
+		case X86_64_INTEGERSI_CLASS:
+		  reg_args->gpr[gprcount] = 0;
+		  memcpy (&reg_args->gpr[gprcount], a, size < 8 ? size : 8);
+		  gprcount++;
+		  break;
+		case X86_64_SSE_CLASS:
+		case X86_64_SSEDF_CLASS:
+		  reg_args->sse[ssecount++] = *(UINT64 *) a;
+		  break;
+		case X86_64_SSESF_CLASS:
+		  reg_args->sse[ssecount++] = *(UINT32 *) a;
+		  break;
+		default:
+		  abort();
+		}
+	    }
+	}
+    }
+
+  ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args),
+		   cif->flags, rvalue, fn, ssecount);
+}
+
+
+extern void ffi_closure_unix64(void);
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif*, void*, void**, void*),
+		      void *user_data,
+		      void *codeloc)
+{
+  volatile unsigned short *tramp;
+
+  /* Sanity check on the cif ABI.  */
+  {
+    int abi = cif->abi;
+    if (UNLIKELY (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)))
+      return FFI_BAD_ABI;
+  }
+
+  tramp = (volatile unsigned short *) &closure->tramp[0];
+
+  tramp[0] = 0xbb49;		/* mov <code>, %r11	*/
+  *(void * volatile *) &tramp[1] = ffi_closure_unix64;
+  tramp[5] = 0xba49;		/* mov <data>, %r10	*/
+  *(void * volatile *) &tramp[6] = codeloc;
+
+  /* Set the carry bit iff the function uses any sse registers.
+     This is clc or stc, together with the first byte of the jmp.  */
+  tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8;
+
+  tramp[11] = 0xe3ff;			/* jmp *%r11    */
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  return FFI_OK;
+}
+
+int
+ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue,
+			 struct register_args *reg_args, char *argp)
+{
+  ffi_cif *cif;
+  void **avalue;
+  ffi_type **arg_types;
+  long i, avn;
+  int gprcount, ssecount, ngpr, nsse;
+  int ret;
+
+  cif = closure->cif;
+  avalue = alloca(cif->nargs * sizeof(void *));
+  gprcount = ssecount = 0;
+
+  ret = cif->rtype->type;
+  if (ret != FFI_TYPE_VOID)
+    {
+      enum x86_64_reg_class classes[MAX_CLASSES];
+      int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
+      if (n == 0)
+	{
+	  /* The return value goes in memory.  Arrange for the closure
+	     return value to go directly back to the original caller.  */
+	  rvalue = (void *) reg_args->gpr[gprcount++];
+	  /* We don't have to do anything in asm for the return.  */
+	  ret = FFI_TYPE_VOID;
+	}
+      else if (ret == FFI_TYPE_STRUCT && n == 2)
+	{
+	  /* Mark which register the second word of the structure goes in.  */
+	  _Bool sse0 = SSE_CLASS_P (classes[0]);
+	  _Bool sse1 = SSE_CLASS_P (classes[1]);
+	  if (!sse0 && sse1)
+	    ret |= 1 << 8;
+	  else if (sse0 && !sse1)
+	    ret |= 1 << 9;
+	}
+    }
+
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+  
+  for (i = 0; i < avn; ++i)
+    {
+      enum x86_64_reg_class classes[MAX_CLASSES];
+      int n;
+
+      n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
+      if (n == 0
+	  || gprcount + ngpr > MAX_GPR_REGS
+	  || ssecount + nsse > MAX_SSE_REGS)
+	{
+	  long align = arg_types[i]->alignment;
+
+	  /* Stack arguments are *always* at least 8 byte aligned.  */
+	  if (align < 8)
+	    align = 8;
+
+	  /* Pass this argument in memory.  */
+	  argp = (void *) ALIGN (argp, align);
+	  avalue[i] = argp;
+	  argp += arg_types[i]->size;
+	}
+      /* If the argument is in a single register, or two consecutive
+	 integer registers, then we can use that address directly.  */
+      else if (n == 1
+	       || (n == 2 && !(SSE_CLASS_P (classes[0])
+			       || SSE_CLASS_P (classes[1]))))
+	{
+	  /* The argument is in a single register.  */
+	  if (SSE_CLASS_P (classes[0]))
+	    {
+	      avalue[i] = &reg_args->sse[ssecount];
+	      ssecount += n;
+	    }
+	  else
+	    {
+	      avalue[i] = &reg_args->gpr[gprcount];
+	      gprcount += n;
+	    }
+	}
+      /* Otherwise, allocate space to make them consecutive.  */
+      else
+	{
+	  char *a = alloca (16);
+	  int j;
+
+	  avalue[i] = a;
+	  for (j = 0; j < n; j++, a += 8)
+	    {
+	      if (SSE_CLASS_P (classes[j]))
+		memcpy (a, &reg_args->sse[ssecount++], 8);
+	      else
+		memcpy (a, &reg_args->gpr[gprcount++], 8);
+	    }
+	}
+    }
+
+  /* Invoke the closure.  */
+  closure->fun (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell assembly how to perform return type promotions.  */
+  return ret;
+}
+
+#endif /* __x86_64__ */
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/ffitarget.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/ffitarget.h
new file mode 100755
index 0000000..542e6d4
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/ffitarget.h
@@ -0,0 +1,121 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 1996-2003, 2010  Red Hat, Inc.
+   Copyright (C) 2008  Free Software Foundation, Inc.
+
+   Target configuration macros for x86 and x86-64.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+
+   ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+/* ---- System specific configurations ----------------------------------- */
+
+/* For code common to all platforms on x86 and x86_64. */
+#define X86_ANY
+
+#if defined (X86_64) && defined (__i386__)
+#undef X86_64
+#define X86
+#endif
+
+#ifdef X86_WIN64
+#define FFI_SIZEOF_ARG 8
+#define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
+#endif
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#ifndef LIBFFI_ASM
+#ifdef X86_WIN64
+#ifdef _MSC_VER
+typedef unsigned __int64       ffi_arg;
+typedef __int64                ffi_sarg;
+#else
+typedef unsigned long long     ffi_arg;
+typedef long long              ffi_sarg;
+#endif
+#else
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+#endif
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+
+  /* ---- Intel x86 Win32 ---------- */
+#ifdef X86_WIN32
+  FFI_SYSV,
+  FFI_STDCALL,
+  FFI_LAST_ABI,
+  /* TODO: Add fastcall support for the sake of completeness */
+  FFI_DEFAULT_ABI = FFI_SYSV
+
+#elif defined(X86_WIN64)
+  FFI_WIN64,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_WIN64
+
+#else
+  /* ---- Intel x86 and AMD x86-64 - */
+  FFI_SYSV,
+  FFI_UNIX64,   /* Unix variants all use the same ABI for x86-64  */
+  FFI_LAST_ABI,
+#if defined(__i386__) || defined(__i386)
+  FFI_DEFAULT_ABI = FFI_SYSV
+#else
+  FFI_DEFAULT_ABI = FFI_UNIX64
+#endif
+#endif
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
+#define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
+#define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
+
+#if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
+#define FFI_TRAMPOLINE_SIZE 24
+#define FFI_NATIVE_RAW_API 0
+#else
+#ifdef X86_WIN32
+#define FFI_TRAMPOLINE_SIZE 13
+#else
+#ifdef X86_WIN64
+#define FFI_TRAMPOLINE_SIZE 29
+#define FFI_NATIVE_RAW_API 0
+#define FFI_NO_RAW_API 1
+#else
+#define FFI_TRAMPOLINE_SIZE 10
+#endif
+#endif
+#ifndef X86_WIN64
+#define FFI_NATIVE_RAW_API 1	/* x86 has native raw api support */
+#endif
+#endif
+
+#endif
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/freebsd.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/freebsd.S
new file mode 100755
index 0000000..afde513
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/freebsd.S
@@ -0,0 +1,458 @@
+/* -----------------------------------------------------------------------
+   freebsd.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005  Red Hat, Inc.
+	       Copyright (c) 2008  Björn König
+	
+   X86 Foreign Function Interface for FreeBSD
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+----------------------------------------------------------------------- */
+
+#ifndef __x86_64__
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+
+.globl ffi_prep_args
+
+	.align 4
+.globl ffi_call_SYSV
+        .type    ffi_call_SYSV, at function
+
+ffi_call_SYSV:
+.LFB1:
+        pushl %ebp
+.LCFI0:
+        movl  %esp,%ebp
+.LCFI1:
+	/* Make room for all of the new args.  */
+	movl  16(%ebp),%ecx
+	subl  %ecx,%esp
+
+	movl  %esp,%eax
+
+	/* Place all of the ffi_prep_args in position  */
+	pushl 12(%ebp)
+	pushl %eax
+	call  *8(%ebp)
+
+	/* Return stack to previous state and call the function  */
+	addl  $8,%esp	
+
+	call  *28(%ebp)
+
+	/* Load %ecx with the return type code  */
+	movl  20(%ebp),%ecx	
+
+	/* Protect %esi.  We're going to pop it in the epilogue.  */
+	pushl %esi
+
+	/* If the return value pointer is NULL, assume no return value.  */
+	cmpl  $0,24(%ebp)
+	jne  0f
+
+	/* Even if there is no space for the return value, we are 
+	   obliged to handle floating-point values.  */
+	cmpl  $FFI_TYPE_FLOAT,%ecx
+	jne   noretval
+	fstp  %st(0)
+
+        jmp   epilogue
+
+0:
+	call  1f
+
+.Lstore_table:
+	.long	noretval-.Lstore_table	/* FFI_TYPE_VOID */
+	.long	retint-.Lstore_table	/* FFI_TYPE_INT */
+	.long	retfloat-.Lstore_table	/* FFI_TYPE_FLOAT */
+	.long	retdouble-.Lstore_table	/* FFI_TYPE_DOUBLE */
+	.long	retlongdouble-.Lstore_table	/* FFI_TYPE_LONGDOUBLE */
+	.long	retuint8-.Lstore_table	/* FFI_TYPE_UINT8 */
+	.long	retsint8-.Lstore_table	/* FFI_TYPE_SINT8 */
+	.long	retuint16-.Lstore_table	/* FFI_TYPE_UINT16 */
+	.long	retsint16-.Lstore_table	/* FFI_TYPE_SINT16 */
+	.long	retint-.Lstore_table	/* FFI_TYPE_UINT32 */
+	.long	retint-.Lstore_table	/* FFI_TYPE_SINT32 */
+	.long	retint64-.Lstore_table	/* FFI_TYPE_UINT64 */
+	.long	retint64-.Lstore_table	/* FFI_TYPE_SINT64 */
+	.long	retstruct-.Lstore_table	/* FFI_TYPE_STRUCT */
+	.long	retint-.Lstore_table	/* FFI_TYPE_POINTER */
+	.long   retstruct1b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_1B */
+	.long   retstruct2b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_2B */
+
+1:
+	pop  %esi
+	add  (%esi, %ecx, 4), %esi
+	jmp  *%esi
+
+	/* Sign/zero extend as appropriate.  */
+retsint8:
+	movsbl  %al, %eax
+	jmp  retint
+
+retsint16:
+	movswl  %ax, %eax
+	jmp  retint
+
+retuint8:
+	movzbl  %al, %eax
+	jmp  retint
+
+retuint16:
+	movzwl  %ax, %eax
+	jmp  retint
+
+retfloat:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	fstps (%ecx)
+	jmp   epilogue
+
+retdouble:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	fstpl (%ecx)
+	jmp   epilogue
+
+retlongdouble:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	fstpt (%ecx)
+	jmp   epilogue
+	
+retint64:	
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	movl  %eax,0(%ecx)
+	movl  %edx,4(%ecx)
+	jmp   epilogue
+	
+retstruct1b:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	movb  %al,0(%ecx)
+	jmp   epilogue
+
+retstruct2b:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx
+	movw  %ax,0(%ecx)
+	jmp   epilogue
+
+retint:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	movl  %eax,0(%ecx)
+
+retstruct:
+	/* Nothing to do!  */
+
+noretval:
+epilogue:
+        popl %esi
+        movl %ebp,%esp
+        popl %ebp
+        ret
+.LFE1:
+.ffi_call_SYSV_end:
+        .size    ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+
+	.align	4
+FFI_HIDDEN (ffi_closure_SYSV)
+.globl ffi_closure_SYSV
+	.type	ffi_closure_SYSV, @function
+
+ffi_closure_SYSV:
+.LFB2:
+	pushl	%ebp
+.LCFI2:
+	movl	%esp, %ebp
+.LCFI3:
+	subl	$40, %esp
+	leal	-24(%ebp), %edx
+	movl	%edx, -12(%ebp)	/* resp */
+	leal	8(%ebp), %edx
+	movl	%edx, 4(%esp)	/* args = __builtin_dwarf_cfa () */
+	leal	-12(%ebp), %edx
+	movl	%edx, (%esp)	/* &resp */
+#if defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE || !defined __PIC__
+	call	ffi_closure_SYSV_inner
+#else
+	movl	%ebx, 8(%esp)
+.LCFI7:
+	call	1f
+1:	popl	%ebx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+	call	ffi_closure_SYSV_inner at PLT
+	movl	8(%esp), %ebx
+#endif
+	movl	-12(%ebp), %ecx
+	cmpl	$FFI_TYPE_INT, %eax
+	je	.Lcls_retint
+
+	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
+	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
+	cmpl	$FFI_TYPE_UINT64, %eax
+	jge	0f
+	cmpl	$FFI_TYPE_UINT8, %eax
+	jge	.Lcls_retint
+	
+0:	cmpl	$FFI_TYPE_FLOAT, %eax
+	je	.Lcls_retfloat
+	cmpl	$FFI_TYPE_DOUBLE, %eax
+	je	.Lcls_retdouble
+	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
+	je	.Lcls_retldouble
+	cmpl	$FFI_TYPE_SINT64, %eax
+	je	.Lcls_retllong
+	cmpl	$FFI_TYPE_SMALL_STRUCT_1B, %eax
+	je	.Lcls_retstruct1b
+	cmpl	$FFI_TYPE_SMALL_STRUCT_2B, %eax
+	je	.Lcls_retstruct2b
+	cmpl	$FFI_TYPE_STRUCT, %eax
+	je	.Lcls_retstruct
+.Lcls_epilogue:
+	movl	%ebp, %esp
+	popl	%ebp
+	ret
+.Lcls_retint:
+	movl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+.Lcls_retfloat:
+	flds	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retdouble:
+	fldl	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retldouble:
+	fldt	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retllong:
+	movl	(%ecx), %eax
+	movl	4(%ecx), %edx
+	jmp	.Lcls_epilogue
+.Lcls_retstruct1b:
+	movsbl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+.Lcls_retstruct2b:
+	movswl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+.Lcls_retstruct:
+	movl	%ebp, %esp
+	popl	%ebp
+	ret	$4
+.LFE2:
+	.size	ffi_closure_SYSV, .-ffi_closure_SYSV
+
+#if !FFI_NO_RAW_API
+
+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+#define CIF_FLAGS_OFFSET 20
+
+	.align	4
+FFI_HIDDEN (ffi_closure_raw_SYSV)
+.globl ffi_closure_raw_SYSV
+	.type	ffi_closure_raw_SYSV, @function
+
+ffi_closure_raw_SYSV:
+.LFB3:
+	pushl	%ebp
+.LCFI4:
+	movl	%esp, %ebp
+.LCFI5:
+	pushl	%esi
+.LCFI6:
+	subl	$36, %esp
+	movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
+	movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
+	movl	%edx, 12(%esp)	/* user_data */
+	leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
+	movl	%edx, 8(%esp)	/* raw_args */
+	leal	-24(%ebp), %edx
+	movl	%edx, 4(%esp)	/* &res */
+	movl	%esi, (%esp)	/* cif */
+	call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
+	movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
+	cmpl	$FFI_TYPE_INT, %eax
+	je	.Lrcls_retint
+
+	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
+	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
+	cmpl	$FFI_TYPE_UINT64, %eax
+	jge	0f
+	cmpl	$FFI_TYPE_UINT8, %eax
+	jge	.Lrcls_retint
+0:
+	cmpl	$FFI_TYPE_FLOAT, %eax
+	je	.Lrcls_retfloat
+	cmpl	$FFI_TYPE_DOUBLE, %eax
+	je	.Lrcls_retdouble
+	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
+	je	.Lrcls_retldouble
+	cmpl	$FFI_TYPE_SINT64, %eax
+	je	.Lrcls_retllong
+.Lrcls_epilogue:
+	addl	$36, %esp
+	popl	%esi
+	popl	%ebp
+	ret
+.Lrcls_retint:
+	movl	-24(%ebp), %eax
+	jmp	.Lrcls_epilogue
+.Lrcls_retfloat:
+	flds	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retdouble:
+	fldl	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retldouble:
+	fldt	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retllong:
+	movl	-24(%ebp), %eax
+	movl	-20(%ebp), %edx
+	jmp	.Lrcls_epilogue
+.LFE3:
+	.size	ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV
+#endif
+
+	.section	.eh_frame,EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.long	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
+.LSCIE1:
+	.long	0x0	/* CIE Identifier Tag */
+	.byte	0x1	/* CIE Version */
+#ifdef __PIC__
+	.ascii "zR\0"	/* CIE Augmentation */
+#else
+	.ascii "\0"	/* CIE Augmentation */
+#endif
+	.byte	0x1	/* .uleb128 0x1; CIE Code Alignment Factor */
+	.byte	0x7c	/* .sleb128 -4; CIE Data Alignment Factor */
+	.byte	0x8	/* CIE RA Column */
+#ifdef __PIC__
+	.byte	0x1	/* .uleb128 0x1; Augmentation size */
+	.byte	0x1b	/* FDE Encoding (pcrel sdata4) */
+#endif
+	.byte	0xc	/* DW_CFA_def_cfa */
+	.byte	0x4	/* .uleb128 0x4 */
+	.byte	0x4	/* .uleb128 0x4 */
+	.byte	0x88	/* DW_CFA_offset, column 0x8 */
+	.byte	0x1	/* .uleb128 0x1 */
+	.align 4
+.LECIE1:
+.LSFDE1:
+	.long	.LEFDE1-.LASFDE1	/* FDE Length */
+.LASFDE1:
+	.long	.LASFDE1-.Lframe1	/* FDE CIE offset */
+#ifdef __PIC__
+	.long	.LFB1-.	/* FDE initial location */
+#else
+	.long	.LFB1	/* FDE initial location */
+#endif
+	.long	.LFE1-.LFB1	/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI0-.LFB1
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 */
+	.byte	0x2	/* .uleb128 0x2 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI1-.LCFI0
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0x5	/* .uleb128 0x5 */
+	.align 4
+.LEFDE1:
+.LSFDE2:
+	.long	.LEFDE2-.LASFDE2	/* FDE Length */
+.LASFDE2:
+	.long	.LASFDE2-.Lframe1	/* FDE CIE offset */
+#ifdef __PIC__
+	.long	.LFB2-.	/* FDE initial location */
+#else
+	.long	.LFB2
+#endif
+	.long	.LFE2-.LFB2	/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI2-.LFB2
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 */
+	.byte	0x2	/* .uleb128 0x2 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI3-.LCFI2
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0x5	/* .uleb128 0x5 */
+#if !defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE && defined __PIC__
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI7-.LCFI3
+	.byte	0x83	/* DW_CFA_offset, column 0x3 */
+	.byte	0xa	/* .uleb128 0xa */
+#endif
+	.align 4
+.LEFDE2:
+
+#if !FFI_NO_RAW_API
+
+.LSFDE3:
+	.long	.LEFDE3-.LASFDE3	/* FDE Length */
+.LASFDE3:
+	.long	.LASFDE3-.Lframe1	/* FDE CIE offset */
+#ifdef __PIC__
+	.long	.LFB3-.	/* FDE initial location */
+#else
+	.long	.LFB3
+#endif
+	.long	.LFE3-.LFB3	/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI4-.LFB3
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 */
+	.byte	0x2	/* .uleb128 0x2 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI5-.LCFI4
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0x5	/* .uleb128 0x5 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI6-.LCFI5
+	.byte	0x86	/* DW_CFA_offset, column 0x6 */
+	.byte	0x3	/* .uleb128 0x3 */
+	.align 4
+.LEFDE3:
+
+#endif
+
+#endif /* ifndef __x86_64__ */
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/sysv.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/sysv.S
new file mode 100755
index 0000000..f108dd8
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/sysv.S
@@ -0,0 +1,468 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 1996, 1998, 2001-2003, 2005, 2008, 2010  Red Hat, Inc.
+   
+   X86 Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#ifndef __x86_64__
+
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+
+.globl ffi_prep_args
+
+	.align 4
+.globl ffi_call_SYSV
+        .type    ffi_call_SYSV, at function
+
+ffi_call_SYSV:
+.LFB1:
+        pushl %ebp
+.LCFI0:
+        movl  %esp,%ebp
+.LCFI1:
+	/* Make room for all of the new args.  */
+	movl  16(%ebp),%ecx
+	subl  %ecx,%esp
+
+        /* Align the stack pointer to 16-bytes */
+        andl  $0xfffffff0, %esp
+
+	movl  %esp,%eax
+
+	/* Place all of the ffi_prep_args in position  */
+	pushl 12(%ebp)
+	pushl %eax
+	call  *8(%ebp)
+
+	/* Return stack to previous state and call the function  */
+	addl  $8,%esp	
+
+	call  *28(%ebp)
+
+	/* Load %ecx with the return type code  */
+	movl  20(%ebp),%ecx	
+
+	/* Protect %esi.  We're going to pop it in the epilogue.  */
+	pushl %esi
+
+	/* If the return value pointer is NULL, assume no return value.  */
+	cmpl  $0,24(%ebp)
+	jne  0f
+
+	/* Even if there is no space for the return value, we are 
+	   obliged to handle floating-point values.  */
+	cmpl  $FFI_TYPE_FLOAT,%ecx
+	jne   noretval
+	fstp  %st(0)
+
+        jmp   epilogue
+
+0:
+	call  1f
+
+.Lstore_table:
+	.long	noretval-.Lstore_table	/* FFI_TYPE_VOID */
+	.long	retint-.Lstore_table	/* FFI_TYPE_INT */
+	.long	retfloat-.Lstore_table	/* FFI_TYPE_FLOAT */
+	.long	retdouble-.Lstore_table	/* FFI_TYPE_DOUBLE */
+	.long	retlongdouble-.Lstore_table	/* FFI_TYPE_LONGDOUBLE */
+	.long	retuint8-.Lstore_table	/* FFI_TYPE_UINT8 */
+	.long	retsint8-.Lstore_table	/* FFI_TYPE_SINT8 */
+	.long	retuint16-.Lstore_table	/* FFI_TYPE_UINT16 */
+	.long	retsint16-.Lstore_table	/* FFI_TYPE_SINT16 */
+	.long	retint-.Lstore_table	/* FFI_TYPE_UINT32 */
+	.long	retint-.Lstore_table	/* FFI_TYPE_SINT32 */
+	.long	retint64-.Lstore_table	/* FFI_TYPE_UINT64 */
+	.long	retint64-.Lstore_table	/* FFI_TYPE_SINT64 */
+	.long	retstruct-.Lstore_table	/* FFI_TYPE_STRUCT */
+	.long	retint-.Lstore_table	/* FFI_TYPE_POINTER */
+
+1:
+	pop  %esi
+	add  (%esi, %ecx, 4), %esi
+	jmp  *%esi
+
+	/* Sign/zero extend as appropriate.  */
+retsint8:
+	movsbl  %al, %eax
+	jmp  retint
+
+retsint16:
+	movswl  %ax, %eax
+	jmp  retint
+
+retuint8:
+	movzbl  %al, %eax
+	jmp  retint
+
+retuint16:
+	movzwl  %ax, %eax
+	jmp  retint
+
+retfloat:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	fstps (%ecx)
+	jmp   epilogue
+
+retdouble:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	fstpl (%ecx)
+	jmp   epilogue
+
+retlongdouble:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	fstpt (%ecx)
+	jmp   epilogue
+	
+retint64:	
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	movl  %eax,0(%ecx)
+	movl  %edx,4(%ecx)
+	jmp   epilogue
+	
+retint:
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	movl  %eax,0(%ecx)
+
+retstruct:
+	/* Nothing to do!  */
+
+noretval:
+epilogue:
+        popl %esi
+        movl %ebp,%esp
+        popl %ebp
+        ret
+.LFE1:
+.ffi_call_SYSV_end:
+        .size    ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+
+	.align	4
+FFI_HIDDEN (ffi_closure_SYSV)
+.globl ffi_closure_SYSV
+	.type	ffi_closure_SYSV, @function
+
+ffi_closure_SYSV:
+.LFB2:
+	pushl	%ebp
+.LCFI2:
+	movl	%esp, %ebp
+.LCFI3:
+	subl	$40, %esp
+	leal	-24(%ebp), %edx
+	movl	%edx, -12(%ebp)	/* resp */
+	leal	8(%ebp), %edx
+	movl	%edx, 4(%esp)	/* args = __builtin_dwarf_cfa () */
+	leal	-12(%ebp), %edx
+	movl	%edx, (%esp)	/* &resp */
+#if defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE || !defined __PIC__
+	call	ffi_closure_SYSV_inner
+#else
+	movl	%ebx, 8(%esp)
+.LCFI7:
+	call	1f
+1:	popl	%ebx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+	call	ffi_closure_SYSV_inner at PLT
+	movl	8(%esp), %ebx
+#endif
+	movl	-12(%ebp), %ecx
+	cmpl	$FFI_TYPE_INT, %eax
+	je	.Lcls_retint
+
+	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
+	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
+	cmpl	$FFI_TYPE_UINT64, %eax
+	jge	0f
+	cmpl	$FFI_TYPE_UINT8, %eax
+	jge	.Lcls_retint
+	
+0:	cmpl	$FFI_TYPE_FLOAT, %eax
+	je	.Lcls_retfloat
+	cmpl	$FFI_TYPE_DOUBLE, %eax
+	je	.Lcls_retdouble
+	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
+	je	.Lcls_retldouble
+	cmpl	$FFI_TYPE_SINT64, %eax
+	je	.Lcls_retllong
+	cmpl	$FFI_TYPE_STRUCT, %eax
+	je	.Lcls_retstruct
+.Lcls_epilogue:
+	movl	%ebp, %esp
+	popl	%ebp
+	ret
+.Lcls_retint:
+	movl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+.Lcls_retfloat:
+	flds	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retdouble:
+	fldl	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retldouble:
+	fldt	(%ecx)
+	jmp	.Lcls_epilogue
+.Lcls_retllong:
+	movl	(%ecx), %eax
+	movl	4(%ecx), %edx
+	jmp	.Lcls_epilogue
+.Lcls_retstruct:
+	movl	%ebp, %esp
+	popl	%ebp
+	ret	$4
+.LFE2:
+	.size	ffi_closure_SYSV, .-ffi_closure_SYSV
+
+#if !FFI_NO_RAW_API
+
+/* Precalculate for e.g. the Solaris 10/x86 assembler.  */
+#if FFI_TRAMPOLINE_SIZE == 10
+#define RAW_CLOSURE_CIF_OFFSET 12
+#define RAW_CLOSURE_FUN_OFFSET 16
+#define RAW_CLOSURE_USER_DATA_OFFSET 20
+#elif FFI_TRAMPOLINE_SIZE == 24
+#define RAW_CLOSURE_CIF_OFFSET 24
+#define RAW_CLOSURE_FUN_OFFSET 28
+#define RAW_CLOSURE_USER_DATA_OFFSET 32
+#else
+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+#endif
+#define CIF_FLAGS_OFFSET 20
+
+	.align	4
+FFI_HIDDEN (ffi_closure_raw_SYSV)
+.globl ffi_closure_raw_SYSV
+	.type	ffi_closure_raw_SYSV, @function
+
+ffi_closure_raw_SYSV:
+.LFB3:
+	pushl	%ebp
+.LCFI4:
+	movl	%esp, %ebp
+.LCFI5:
+	pushl	%esi
+.LCFI6:
+	subl	$36, %esp
+	movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
+	movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
+	movl	%edx, 12(%esp)	/* user_data */
+	leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
+	movl	%edx, 8(%esp)	/* raw_args */
+	leal	-24(%ebp), %edx
+	movl	%edx, 4(%esp)	/* &res */
+	movl	%esi, (%esp)	/* cif */
+	call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
+	movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
+	cmpl	$FFI_TYPE_INT, %eax
+	je	.Lrcls_retint
+
+	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
+	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
+	cmpl	$FFI_TYPE_UINT64, %eax
+	jge	0f
+	cmpl	$FFI_TYPE_UINT8, %eax
+	jge	.Lrcls_retint
+0:
+	cmpl	$FFI_TYPE_FLOAT, %eax
+	je	.Lrcls_retfloat
+	cmpl	$FFI_TYPE_DOUBLE, %eax
+	je	.Lrcls_retdouble
+	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
+	je	.Lrcls_retldouble
+	cmpl	$FFI_TYPE_SINT64, %eax
+	je	.Lrcls_retllong
+.Lrcls_epilogue:
+	addl	$36, %esp
+	popl	%esi
+	popl	%ebp
+	ret
+.Lrcls_retint:
+	movl	-24(%ebp), %eax
+	jmp	.Lrcls_epilogue
+.Lrcls_retfloat:
+	flds	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retdouble:
+	fldl	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retldouble:
+	fldt	-24(%ebp)
+	jmp	.Lrcls_epilogue
+.Lrcls_retllong:
+	movl	-24(%ebp), %eax
+	movl	-20(%ebp), %edx
+	jmp	.Lrcls_epilogue
+.LFE3:
+	.size	ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV
+#endif
+
+#if defined __PIC__
+# if defined __sun__ && defined __svr4__
+/* 32-bit Solaris 2/x86 uses datarel encoding for PIC.  GNU ld before 2.22
+   doesn't correctly sort .eh_frame_hdr with mixed encodings, so match this.  */
+#  define FDE_ENCODING		0x30	/* datarel */
+#  define FDE_ENCODE(X)		X at GOTOFF
+# else
+#  define FDE_ENCODING		0x1b	/* pcrel sdata4 */
+#  if defined HAVE_AS_X86_PCREL
+#   define FDE_ENCODE(X)	X-.
+#  else
+#   define FDE_ENCODE(X)	X at rel
+#  endif
+# endif
+#else
+# define FDE_ENCODING		0	/* absolute */
+# define FDE_ENCODE(X)		X
+#endif
+
+	.section	.eh_frame,EH_FRAME_FLAGS, at progbits
+.Lframe1:
+	.long	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
+.LSCIE1:
+	.long	0x0	/* CIE Identifier Tag */
+	.byte	0x1	/* CIE Version */
+#ifdef HAVE_AS_ASCII_PSEUDO_OP
+#ifdef __PIC__
+	.ascii "zR\0"	/* CIE Augmentation */
+#else
+	.ascii "\0"	/* CIE Augmentation */
+#endif
+#elif defined HAVE_AS_STRING_PSEUDO_OP
+#ifdef __PIC__
+	.string "zR"	/* CIE Augmentation */
+#else
+	.string ""	/* CIE Augmentation */
+#endif
+#else
+#error missing .ascii/.string
+#endif
+	.byte	0x1	/* .uleb128 0x1; CIE Code Alignment Factor */
+	.byte	0x7c	/* .sleb128 -4; CIE Data Alignment Factor */
+	.byte	0x8	/* CIE RA Column */
+#ifdef __PIC__
+	.byte	0x1	/* .uleb128 0x1; Augmentation size */
+	.byte	FDE_ENCODING
+#endif
+	.byte	0xc	/* DW_CFA_def_cfa */
+	.byte	0x4	/* .uleb128 0x4 */
+	.byte	0x4	/* .uleb128 0x4 */
+	.byte	0x88	/* DW_CFA_offset, column 0x8 */
+	.byte	0x1	/* .uleb128 0x1 */
+	.align 4
+.LECIE1:
+.LSFDE1:
+	.long	.LEFDE1-.LASFDE1	/* FDE Length */
+.LASFDE1:
+	.long	.LASFDE1-.Lframe1	/* FDE CIE offset */
+	.long	FDE_ENCODE(.LFB1)	/* FDE initial location */
+	.long	.LFE1-.LFB1		/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI0-.LFB1
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 */
+	.byte	0x2	/* .uleb128 0x2 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI1-.LCFI0
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0x5	/* .uleb128 0x5 */
+	.align 4
+.LEFDE1:
+.LSFDE2:
+	.long	.LEFDE2-.LASFDE2	/* FDE Length */
+.LASFDE2:
+	.long	.LASFDE2-.Lframe1	/* FDE CIE offset */
+	.long	FDE_ENCODE(.LFB2)	/* FDE initial location */
+	.long	.LFE2-.LFB2		/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI2-.LFB2
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 */
+	.byte	0x2	/* .uleb128 0x2 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI3-.LCFI2
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0x5	/* .uleb128 0x5 */
+#if !defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE && defined __PIC__
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI7-.LCFI3
+	.byte	0x83	/* DW_CFA_offset, column 0x3 */
+	.byte	0xa	/* .uleb128 0xa */
+#endif
+	.align 4
+.LEFDE2:
+
+#if !FFI_NO_RAW_API
+
+.LSFDE3:
+	.long	.LEFDE3-.LASFDE3	/* FDE Length */
+.LASFDE3:
+	.long	.LASFDE3-.Lframe1	/* FDE CIE offset */
+	.long	FDE_ENCODE(.LFB3)	/* FDE initial location */
+	.long	.LFE3-.LFB3		/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI4-.LFB3
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 */
+	.byte	0x2	/* .uleb128 0x2 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI5-.LCFI4
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0x5	/* .uleb128 0x5 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI6-.LCFI5
+	.byte	0x86	/* DW_CFA_offset, column 0x6 */
+	.byte	0x3	/* .uleb128 0x3 */
+	.align 4
+.LEFDE3:
+
+#endif
+
+#endif /* ifndef __x86_64__ */
+
+#if defined __ELF__ && defined __linux__
+	.section	.note.GNU-stack,"", at progbits
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/unix64.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/unix64.S
new file mode 100755
index 0000000..7a6619a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/unix64.S
@@ -0,0 +1,426 @@
+/* -----------------------------------------------------------------------
+   unix64.S - Copyright (c) 2002  Bo Thorsen <bo at suse.de>
+	      Copyright (c) 2008  Red Hat, Inc
+
+   x86-64 Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#ifdef __x86_64__
+#define LIBFFI_ASM	
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+
+/* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
+	            void *raddr, void (*fnaddr)(void));
+
+   Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
+   for this function.  This has been allocated by ffi_call.  We also
+   deallocate some of the stack that has been alloca'd.  */
+
+	.align	2
+	.globl	ffi_call_unix64
+	.type	ffi_call_unix64, at function
+
+ffi_call_unix64:
+.LUW0:
+	movq	(%rsp), %r10		/* Load return address.  */
+	leaq	(%rdi, %rsi), %rax	/* Find local stack base.  */
+	movq	%rdx, (%rax)		/* Save flags.  */
+	movq	%rcx, 8(%rax)		/* Save raddr.  */
+	movq	%rbp, 16(%rax)		/* Save old frame pointer.  */
+	movq	%r10, 24(%rax)		/* Relocate return address.  */
+	movq	%rax, %rbp		/* Finalize local stack frame.  */
+.LUW1:
+	movq	%rdi, %r10		/* Save a copy of the register area. */
+	movq	%r8, %r11		/* Save a copy of the target fn.  */
+	movl	%r9d, %eax		/* Set number of SSE registers.  */
+
+	/* Load up all argument registers.  */
+	movq	(%r10), %rdi
+	movq	8(%r10), %rsi
+	movq	16(%r10), %rdx
+	movq	24(%r10), %rcx
+	movq	32(%r10), %r8
+	movq	40(%r10), %r9
+	testl	%eax, %eax
+	jnz	.Lload_sse
+.Lret_from_load_sse:
+
+	/* Deallocate the reg arg area.  */
+	leaq	176(%r10), %rsp
+
+	/* Call the user function.  */
+	call	*%r11
+
+	/* Deallocate stack arg area; local stack frame in redzone.  */
+	leaq	24(%rbp), %rsp
+
+	movq	0(%rbp), %rcx		/* Reload flags.  */
+	movq	8(%rbp), %rdi		/* Reload raddr.  */
+	movq	16(%rbp), %rbp		/* Reload old frame pointer.  */
+.LUW2:
+
+	/* The first byte of the flags contains the FFI_TYPE.  */
+	movzbl	%cl, %r10d
+	leaq	.Lstore_table(%rip), %r11
+	movslq	(%r11, %r10, 4), %r10
+	addq	%r11, %r10
+	jmp	*%r10
+
+.Lstore_table:
+	.long	.Lst_void-.Lstore_table		/* FFI_TYPE_VOID */
+	.long	.Lst_sint32-.Lstore_table	/* FFI_TYPE_INT */
+	.long	.Lst_float-.Lstore_table	/* FFI_TYPE_FLOAT */
+	.long	.Lst_double-.Lstore_table	/* FFI_TYPE_DOUBLE */
+	.long	.Lst_ldouble-.Lstore_table	/* FFI_TYPE_LONGDOUBLE */
+	.long	.Lst_uint8-.Lstore_table	/* FFI_TYPE_UINT8 */
+	.long	.Lst_sint8-.Lstore_table	/* FFI_TYPE_SINT8 */
+	.long	.Lst_uint16-.Lstore_table	/* FFI_TYPE_UINT16 */
+	.long	.Lst_sint16-.Lstore_table	/* FFI_TYPE_SINT16 */
+	.long	.Lst_uint32-.Lstore_table	/* FFI_TYPE_UINT32 */
+	.long	.Lst_sint32-.Lstore_table	/* FFI_TYPE_SINT32 */
+	.long	.Lst_int64-.Lstore_table	/* FFI_TYPE_UINT64 */
+	.long	.Lst_int64-.Lstore_table	/* FFI_TYPE_SINT64 */
+	.long	.Lst_struct-.Lstore_table	/* FFI_TYPE_STRUCT */
+	.long	.Lst_int64-.Lstore_table	/* FFI_TYPE_POINTER */
+
+	.align 2
+.Lst_void:
+	ret
+	.align 2
+
+.Lst_uint8:
+	movzbq	%al, %rax
+	movq	%rax, (%rdi)
+	ret
+	.align 2
+.Lst_sint8:
+	movsbq	%al, %rax
+	movq	%rax, (%rdi)
+	ret
+	.align 2
+.Lst_uint16:
+	movzwq	%ax, %rax
+	movq	%rax, (%rdi)
+	.align 2
+.Lst_sint16:
+	movswq	%ax, %rax
+	movq	%rax, (%rdi)
+	ret
+	.align 2
+.Lst_uint32:
+	movl	%eax, %eax
+	movq	%rax, (%rdi)
+	.align 2
+.Lst_sint32:
+	cltq
+	movq	%rax, (%rdi)
+	ret
+	.align 2
+.Lst_int64:
+	movq	%rax, (%rdi)
+	ret
+
+	.align 2
+.Lst_float:
+	movss	%xmm0, (%rdi)
+	ret
+	.align 2
+.Lst_double:
+	movsd	%xmm0, (%rdi)
+	ret
+.Lst_ldouble:
+	fstpt	(%rdi)
+	ret
+
+	.align 2
+.Lst_struct:
+	leaq	-20(%rsp), %rsi		/* Scratch area in redzone.  */
+
+	/* We have to locate the values now, and since we don't want to
+	   write too much data into the user's return value, we spill the
+	   value to a 16 byte scratch area first.  Bits 8, 9, and 10
+	   control where the values are located.  Only one of the three
+	   bits will be set; see ffi_prep_cif_machdep for the pattern.  */
+	movd	%xmm0, %r10
+	movd	%xmm1, %r11
+	testl	$0x100, %ecx
+	cmovnz	%rax, %rdx
+	cmovnz	%r10, %rax
+	testl	$0x200, %ecx
+	cmovnz	%r10, %rdx
+	testl	$0x400, %ecx
+	cmovnz	%r10, %rax
+	cmovnz	%r11, %rdx
+	movq	%rax, (%rsi)
+	movq	%rdx, 8(%rsi)
+
+	/* Bits 12-31 contain the true size of the structure.  Copy from
+	   the scratch area to the true destination.  */
+	shrl	$12, %ecx
+	rep movsb
+	ret
+
+	/* Many times we can avoid loading any SSE registers at all.
+	   It's not worth an indirect jump to load the exact set of
+	   SSE registers needed; zero or all is a good compromise.  */
+	.align 2
+.LUW3:
+.Lload_sse:
+	movdqa	48(%r10), %xmm0
+	movdqa	64(%r10), %xmm1
+	movdqa	80(%r10), %xmm2
+	movdqa	96(%r10), %xmm3
+	movdqa	112(%r10), %xmm4
+	movdqa	128(%r10), %xmm5
+	movdqa	144(%r10), %xmm6
+	movdqa	160(%r10), %xmm7
+	jmp	.Lret_from_load_sse
+
+.LUW4:
+	.size    ffi_call_unix64,.-ffi_call_unix64
+
+	.align	2
+	.globl ffi_closure_unix64
+	.type	ffi_closure_unix64, at function
+
+ffi_closure_unix64:
+.LUW5:
+	/* The carry flag is set by the trampoline iff SSE registers
+	   are used.  Don't clobber it before the branch instruction.  */
+	leaq    -200(%rsp), %rsp
+.LUW6:
+	movq	%rdi, (%rsp)
+	movq    %rsi, 8(%rsp)
+	movq    %rdx, 16(%rsp)
+	movq    %rcx, 24(%rsp)
+	movq    %r8, 32(%rsp)
+	movq    %r9, 40(%rsp)
+	jc      .Lsave_sse
+.Lret_from_save_sse:
+
+	movq	%r10, %rdi
+	leaq	176(%rsp), %rsi
+	movq	%rsp, %rdx
+	leaq	208(%rsp), %rcx
+	call	ffi_closure_unix64_inner at PLT
+
+	/* Deallocate stack frame early; return value is now in redzone.  */
+	addq	$200, %rsp
+.LUW7:
+
+	/* The first byte of the return value contains the FFI_TYPE.  */
+	movzbl	%al, %r10d
+	leaq	.Lload_table(%rip), %r11
+	movslq	(%r11, %r10, 4), %r10
+	addq	%r11, %r10
+	jmp	*%r10
+
+.Lload_table:
+	.long	.Lld_void-.Lload_table		/* FFI_TYPE_VOID */
+	.long	.Lld_int32-.Lload_table		/* FFI_TYPE_INT */
+	.long	.Lld_float-.Lload_table		/* FFI_TYPE_FLOAT */
+	.long	.Lld_double-.Lload_table	/* FFI_TYPE_DOUBLE */
+	.long	.Lld_ldouble-.Lload_table	/* FFI_TYPE_LONGDOUBLE */
+	.long	.Lld_int8-.Lload_table		/* FFI_TYPE_UINT8 */
+	.long	.Lld_int8-.Lload_table		/* FFI_TYPE_SINT8 */
+	.long	.Lld_int16-.Lload_table		/* FFI_TYPE_UINT16 */
+	.long	.Lld_int16-.Lload_table		/* FFI_TYPE_SINT16 */
+	.long	.Lld_int32-.Lload_table		/* FFI_TYPE_UINT32 */
+	.long	.Lld_int32-.Lload_table		/* FFI_TYPE_SINT32 */
+	.long	.Lld_int64-.Lload_table		/* FFI_TYPE_UINT64 */
+	.long	.Lld_int64-.Lload_table		/* FFI_TYPE_SINT64 */
+	.long	.Lld_struct-.Lload_table	/* FFI_TYPE_STRUCT */
+	.long	.Lld_int64-.Lload_table		/* FFI_TYPE_POINTER */
+
+	.align 2
+.Lld_void:
+	ret
+
+	.align 2
+.Lld_int8:
+	movzbl	-24(%rsp), %eax
+	ret
+	.align 2
+.Lld_int16:
+	movzwl	-24(%rsp), %eax
+	ret
+	.align 2
+.Lld_int32:
+	movl	-24(%rsp), %eax
+	ret
+	.align 2
+.Lld_int64:
+	movq	-24(%rsp), %rax
+	ret
+
+	.align 2
+.Lld_float:
+	movss	-24(%rsp), %xmm0
+	ret
+	.align 2
+.Lld_double:
+	movsd	-24(%rsp), %xmm0
+	ret
+	.align 2
+.Lld_ldouble:
+	fldt	-24(%rsp)
+	ret
+
+	.align 2
+.Lld_struct:
+	/* There are four possibilities here, %rax/%rdx, %xmm0/%rax,
+	   %rax/%xmm0, %xmm0/%xmm1.  We collapse two by always loading
+	   both rdx and xmm1 with the second word.  For the remaining,
+	   bit 8 set means xmm0 gets the second word, and bit 9 means
+	   that rax gets the second word.  */
+	movq	-24(%rsp), %rcx
+	movq	-16(%rsp), %rdx
+	movq	-16(%rsp), %xmm1
+	testl	$0x100, %eax
+	cmovnz	%rdx, %rcx
+	movd	%rcx, %xmm0
+	testl	$0x200, %eax
+	movq	-24(%rsp), %rax
+	cmovnz	%rdx, %rax
+	ret
+
+	/* See the comment above .Lload_sse; the same logic applies here.  */
+	.align 2
+.LUW8:
+.Lsave_sse:
+	movdqa	%xmm0, 48(%rsp)
+	movdqa	%xmm1, 64(%rsp)
+	movdqa	%xmm2, 80(%rsp)
+	movdqa	%xmm3, 96(%rsp)
+	movdqa	%xmm4, 112(%rsp)
+	movdqa	%xmm5, 128(%rsp)
+	movdqa	%xmm6, 144(%rsp)
+	movdqa	%xmm7, 160(%rsp)
+	jmp	.Lret_from_save_sse
+
+.LUW9:
+	.size	ffi_closure_unix64,.-ffi_closure_unix64
+
+#ifdef HAVE_AS_X86_64_UNWIND_SECTION_TYPE
+	.section	.eh_frame,"a", at unwind
+#else
+	.section	.eh_frame,"a", at progbits
+#endif
+.Lframe1:
+	.long	.LECIE1-.LSCIE1		/* CIE Length */
+.LSCIE1:
+	.long	0			/* CIE Identifier Tag */
+	.byte	1			/* CIE Version */
+	.ascii "zR\0"			/* CIE Augmentation */
+	.uleb128 1			/* CIE Code Alignment Factor */
+	.sleb128 -8			/* CIE Data Alignment Factor */
+	.byte	0x10			/* CIE RA Column */
+	.uleb128 1			/* Augmentation size */
+	.byte	0x1b			/* FDE Encoding (pcrel sdata4) */
+	.byte	0xc			/* DW_CFA_def_cfa, %rsp offset 8 */
+	.uleb128 7
+	.uleb128 8
+	.byte	0x80+16			/* DW_CFA_offset, %rip offset 1*-8 */
+	.uleb128 1
+	.align 8
+.LECIE1:
+.LSFDE1:
+	.long	.LEFDE1-.LASFDE1	/* FDE Length */
+.LASFDE1:
+	.long	.LASFDE1-.Lframe1	/* FDE CIE offset */
+#if HAVE_AS_X86_PCREL
+	.long	.LUW0-.			/* FDE initial location */
+#else
+	.long	.LUW0 at rel
+#endif
+	.long	.LUW4-.LUW0		/* FDE address range */
+	.uleb128 0x0			/* Augmentation size */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW1-.LUW0
+
+	/* New stack frame based off rbp.  This is a itty bit of unwind
+	   trickery in that the CFA *has* changed.  There is no easy way
+	   to describe it correctly on entry to the function.  Fortunately,
+	   it doesn't matter too much since at all points we can correctly
+	   unwind back to ffi_call.  Note that the location to which we
+	   moved the return address is (the new) CFA-8, so from the
+	   perspective of the unwind info, it hasn't moved.  */
+	.byte	0xc			/* DW_CFA_def_cfa, %rbp offset 32 */
+	.uleb128 6
+	.uleb128 32
+	.byte	0x80+6			/* DW_CFA_offset, %rbp offset 2*-8 */
+	.uleb128 2
+	.byte	0xa			/* DW_CFA_remember_state */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW2-.LUW1
+	.byte	0xc			/* DW_CFA_def_cfa, %rsp offset 8 */
+	.uleb128 7
+	.uleb128 8
+	.byte	0xc0+6			/* DW_CFA_restore, %rbp */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW3-.LUW2
+	.byte	0xb			/* DW_CFA_restore_state */
+
+	.align 8
+.LEFDE1:
+.LSFDE3:
+	.long	.LEFDE3-.LASFDE3	/* FDE Length */
+.LASFDE3:
+	.long	.LASFDE3-.Lframe1	/* FDE CIE offset */
+#if HAVE_AS_X86_PCREL
+	.long	.LUW5-.			/* FDE initial location */
+#else
+	.long	.LUW5 at rel
+#endif
+	.long	.LUW9-.LUW5		/* FDE address range */
+	.uleb128 0x0			/* Augmentation size */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW6-.LUW5
+	.byte	0xe			/* DW_CFA_def_cfa_offset */
+	.uleb128 208
+	.byte	0xa			/* DW_CFA_remember_state */
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW7-.LUW6
+	.byte	0xe			/* DW_CFA_def_cfa_offset */
+	.uleb128 8
+
+	.byte	0x4			/* DW_CFA_advance_loc4 */
+	.long	.LUW8-.LUW7
+	.byte	0xb			/* DW_CFA_restore_state */
+
+	.align 8
+.LEFDE3:
+
+#endif /* __x86_64__ */
+
+#if defined __ELF__ && defined __linux__
+	.section	.note.GNU-stack,"", at progbits
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/win32.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/win32.S
new file mode 100755
index 0000000..06c893f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/win32.S
@@ -0,0 +1,1065 @@
+/* -----------------------------------------------------------------------
+   win32.S - Copyright (c) 1996, 1998, 2001, 2002, 2009  Red Hat, Inc.
+	     Copyright (c) 2001  John Beniton
+	     Copyright (c) 2002  Ranjit Mathew
+	     Copyright (c) 2009  Daniel Witte
+			
+ 
+   X86 Foreign Function Interface
+ 
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+ 
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+ 
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   -----------------------------------------------------------------------
+   */
+ 
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+#ifdef _MSC_VER
+
+.386
+.MODEL FLAT, C
+
+EXTRN ffi_closure_SYSV_inner:NEAR
+
+_TEXT SEGMENT
+
+ffi_call_win32 PROC NEAR,
+    ffi_prep_args : NEAR PTR DWORD,
+    ecif          : NEAR PTR DWORD,
+    cif_bytes     : DWORD,
+    cif_flags     : DWORD,
+    rvalue        : NEAR PTR DWORD,
+    fn            : NEAR PTR DWORD
+
+        ;; Make room for all of the new args.
+        mov  ecx, cif_bytes
+        sub  esp, ecx
+
+        mov  eax, esp
+
+        ;; Place all of the ffi_prep_args in position
+        push ecif
+        push eax
+        call ffi_prep_args
+
+        ;; Return stack to previous state and call the function
+        add  esp, 8
+
+        call fn
+
+        ;; cdecl:   we restore esp in the epilogue, so there's no need to
+        ;;          remove the space we pushed for the args.
+        ;; stdcall: the callee has already cleaned the stack.
+
+        ;; Load ecx with the return type code
+        mov  ecx, cif_flags
+
+        ;; If the return value pointer is NULL, assume no return value.
+        cmp  rvalue, 0
+        jne  ca_jumptable
+
+        ;; Even if there is no space for the return value, we are
+        ;; obliged to handle floating-point values.
+        cmp  ecx, FFI_TYPE_FLOAT
+        jne  ca_epilogue
+        fstp st(0)
+
+        jmp  ca_epilogue
+
+ca_jumptable:
+        jmp  [ca_jumpdata + 4 * ecx]
+ca_jumpdata:
+        ;; Do not insert anything here between label and jump table.
+        dd offset ca_epilogue       ;; FFI_TYPE_VOID
+        dd offset ca_retint         ;; FFI_TYPE_INT
+        dd offset ca_retfloat       ;; FFI_TYPE_FLOAT
+        dd offset ca_retdouble      ;; FFI_TYPE_DOUBLE
+        dd offset ca_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
+        dd offset ca_retint8        ;; FFI_TYPE_UINT8
+        dd offset ca_retint8        ;; FFI_TYPE_SINT8
+        dd offset ca_retint16       ;; FFI_TYPE_UINT16
+        dd offset ca_retint16       ;; FFI_TYPE_SINT16
+        dd offset ca_retint         ;; FFI_TYPE_UINT32
+        dd offset ca_retint         ;; FFI_TYPE_SINT32
+        dd offset ca_retint64       ;; FFI_TYPE_UINT64
+        dd offset ca_retint64       ;; FFI_TYPE_SINT64
+        dd offset ca_epilogue       ;; FFI_TYPE_STRUCT
+        dd offset ca_retint         ;; FFI_TYPE_POINTER
+        dd offset ca_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset ca_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset ca_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+
+ca_retint8:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        mov   [ecx + 0], al
+        jmp   ca_epilogue
+
+ca_retint16:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        mov   [ecx + 0], ax
+        jmp   ca_epilogue
+
+ca_retint:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        mov   [ecx + 0], eax
+        jmp   ca_epilogue
+
+ca_retint64:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        mov   [ecx + 0], eax
+        mov   [ecx + 4], edx
+        jmp   ca_epilogue
+
+ca_retfloat:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        fstp  DWORD PTR [ecx]
+        jmp   ca_epilogue
+
+ca_retdouble:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        fstp  QWORD PTR [ecx]
+        jmp   ca_epilogue
+
+ca_retlongdouble:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        fstp  TBYTE PTR [ecx]
+        jmp   ca_epilogue
+
+ca_epilogue:
+        ;; Epilogue code is autogenerated.
+        ret
+ffi_call_win32 ENDP
+
+ffi_closure_SYSV PROC NEAR <FORCEFRAME>
+    ;; the ffi_closure ctx is passed in eax by the trampoline.
+
+        sub  esp, 40
+        lea  edx, [ebp - 24]
+        mov  [ebp - 12], edx         ;; resp
+        lea  edx, [ebp + 8]
+        mov  [esp + 8], edx          ;; args
+        lea  edx, [ebp - 12]
+        mov  [esp + 4], edx          ;; &resp
+        mov  [esp], eax              ;; closure
+        call ffi_closure_SYSV_inner
+        mov  ecx, [ebp - 12]
+
+cs_jumptable:
+        jmp  [cs_jumpdata + 4 * eax]
+cs_jumpdata:
+        ;; Do not insert anything here between the label and jump table.
+        dd offset cs_epilogue       ;; FFI_TYPE_VOID
+        dd offset cs_retint         ;; FFI_TYPE_INT
+        dd offset cs_retfloat       ;; FFI_TYPE_FLOAT
+        dd offset cs_retdouble      ;; FFI_TYPE_DOUBLE
+        dd offset cs_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
+        dd offset cs_retint8        ;; FFI_TYPE_UINT8
+        dd offset cs_retint8        ;; FFI_TYPE_SINT8
+        dd offset cs_retint16       ;; FFI_TYPE_UINT16
+        dd offset cs_retint16       ;; FFI_TYPE_SINT16
+        dd offset cs_retint         ;; FFI_TYPE_UINT32
+        dd offset cs_retint         ;; FFI_TYPE_SINT32
+        dd offset cs_retint64       ;; FFI_TYPE_UINT64
+        dd offset cs_retint64       ;; FFI_TYPE_SINT64
+        dd offset cs_retstruct      ;; FFI_TYPE_STRUCT
+        dd offset cs_retint         ;; FFI_TYPE_POINTER
+        dd offset cs_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset cs_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset cs_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+
+cs_retint8:
+        mov   al, [ecx]
+        jmp   cs_epilogue
+
+cs_retint16:
+        mov   ax, [ecx]
+        jmp   cs_epilogue
+
+cs_retint:
+        mov   eax, [ecx]
+        jmp   cs_epilogue
+
+cs_retint64:
+        mov   eax, [ecx + 0]
+        mov   edx, [ecx + 4]
+        jmp   cs_epilogue
+
+cs_retfloat:
+        fld   DWORD PTR [ecx]
+        jmp   cs_epilogue
+
+cs_retdouble:
+        fld   QWORD PTR [ecx]
+        jmp   cs_epilogue
+
+cs_retlongdouble:
+        fld   TBYTE PTR [ecx]
+        jmp   cs_epilogue
+
+cs_retstruct:
+        ;; Caller expects us to pop struct return value pointer hidden arg.
+        ;; Epilogue code is autogenerated.
+        ret	4
+
+cs_epilogue:
+        ;; Epilogue code is autogenerated.
+        ret
+ffi_closure_SYSV ENDP
+
+#if !FFI_NO_RAW_API
+
+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3)
+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+#define CIF_FLAGS_OFFSET 20
+
+ffi_closure_raw_SYSV PROC NEAR USES esi
+    ;; the ffi_closure ctx is passed in eax by the trampoline.
+
+        sub  esp, 40
+        mov  esi, [eax + RAW_CLOSURE_CIF_OFFSET]        ;; closure->cif
+        mov  edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET]  ;; closure->user_data
+        mov  [esp + 12], edx                            ;; user_data
+        lea  edx, [ebp + 8]
+        mov  [esp + 8], edx                             ;; raw_args
+        lea  edx, [ebp - 24]
+        mov  [esp + 4], edx                             ;; &res
+        mov  [esp], esi                                 ;; cif
+        call DWORD PTR [eax + RAW_CLOSURE_FUN_OFFSET]   ;; closure->fun
+        mov  eax, [esi + CIF_FLAGS_OFFSET]              ;; cif->flags
+        lea  ecx, [ebp - 24]
+
+cr_jumptable:
+        jmp  [cr_jumpdata + 4 * eax]
+cr_jumpdata:
+        ;; Do not insert anything here between the label and jump table.
+        dd offset cr_epilogue       ;; FFI_TYPE_VOID
+        dd offset cr_retint         ;; FFI_TYPE_INT
+        dd offset cr_retfloat       ;; FFI_TYPE_FLOAT
+        dd offset cr_retdouble      ;; FFI_TYPE_DOUBLE
+        dd offset cr_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
+        dd offset cr_retint8        ;; FFI_TYPE_UINT8
+        dd offset cr_retint8        ;; FFI_TYPE_SINT8
+        dd offset cr_retint16       ;; FFI_TYPE_UINT16
+        dd offset cr_retint16       ;; FFI_TYPE_SINT16
+        dd offset cr_retint         ;; FFI_TYPE_UINT32
+        dd offset cr_retint         ;; FFI_TYPE_SINT32
+        dd offset cr_retint64       ;; FFI_TYPE_UINT64
+        dd offset cr_retint64       ;; FFI_TYPE_SINT64
+        dd offset cr_epilogue       ;; FFI_TYPE_STRUCT
+        dd offset cr_retint         ;; FFI_TYPE_POINTER
+        dd offset cr_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset cr_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset cr_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+
+cr_retint8:
+        mov   al, [ecx]
+        jmp   cr_epilogue
+
+cr_retint16:
+        mov   ax, [ecx]
+        jmp   cr_epilogue
+
+cr_retint:
+        mov   eax, [ecx]
+        jmp   cr_epilogue
+
+cr_retint64:
+        mov   eax, [ecx + 0]
+        mov   edx, [ecx + 4]
+        jmp   cr_epilogue
+
+cr_retfloat:
+        fld   DWORD PTR [ecx]
+        jmp   cr_epilogue
+
+cr_retdouble:
+        fld   QWORD PTR [ecx]
+        jmp   cr_epilogue
+
+cr_retlongdouble:
+        fld   TBYTE PTR [ecx]
+        jmp   cr_epilogue
+
+cr_epilogue:
+        ;; Epilogue code is autogenerated.
+        ret
+ffi_closure_raw_SYSV ENDP
+
+#endif /* !FFI_NO_RAW_API */
+
+ffi_closure_STDCALL PROC NEAR <FORCEFRAME>
+    ;; the ffi_closure ctx is passed in eax by the trampoline.
+
+        sub  esp, 40
+        lea  edx, [ebp - 24]
+        mov  [ebp - 12], edx         ;; resp
+        lea  edx, [ebp + 12]         ;; account for stub return address on stack
+        mov  [esp + 8], edx          ;; args
+        lea  edx, [ebp - 12]
+        mov  [esp + 4], edx          ;; &resp
+        mov  [esp], eax              ;; closure
+        call ffi_closure_SYSV_inner
+        mov  ecx, [ebp - 12]
+
+cd_jumptable:
+        jmp  [cd_jumpdata + 4 * eax]
+cd_jumpdata:
+        ;; Do not insert anything here between the label and jump table.
+        dd offset cd_epilogue       ;; FFI_TYPE_VOID
+        dd offset cd_retint         ;; FFI_TYPE_INT
+        dd offset cd_retfloat       ;; FFI_TYPE_FLOAT
+        dd offset cd_retdouble      ;; FFI_TYPE_DOUBLE
+        dd offset cd_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
+        dd offset cd_retint8        ;; FFI_TYPE_UINT8
+        dd offset cd_retint8        ;; FFI_TYPE_SINT8
+        dd offset cd_retint16       ;; FFI_TYPE_UINT16
+        dd offset cd_retint16       ;; FFI_TYPE_SINT16
+        dd offset cd_retint         ;; FFI_TYPE_UINT32
+        dd offset cd_retint         ;; FFI_TYPE_SINT32
+        dd offset cd_retint64       ;; FFI_TYPE_UINT64
+        dd offset cd_retint64       ;; FFI_TYPE_SINT64
+        dd offset cd_epilogue       ;; FFI_TYPE_STRUCT
+        dd offset cd_retint         ;; FFI_TYPE_POINTER
+        dd offset cd_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset cd_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset cd_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+
+cd_retint8:
+        mov   al, [ecx]
+        jmp   cd_epilogue
+
+cd_retint16:
+        mov   ax, [ecx]
+        jmp   cd_epilogue
+
+cd_retint:
+        mov   eax, [ecx]
+        jmp   cd_epilogue
+
+cd_retint64:
+        mov   eax, [ecx + 0]
+        mov   edx, [ecx + 4]
+        jmp   cd_epilogue
+
+cd_retfloat:
+        fld   DWORD PTR [ecx]
+        jmp   cd_epilogue
+
+cd_retdouble:
+        fld   QWORD PTR [ecx]
+        jmp   cd_epilogue
+
+cd_retlongdouble:
+        fld   TBYTE PTR [ecx]
+        jmp   cd_epilogue
+
+cd_epilogue:
+        ;; Epilogue code is autogenerated.
+        ret
+ffi_closure_STDCALL ENDP
+
+_TEXT ENDS
+END
+
+#else
+
+	.text
+ 
+        # This assumes we are using gas.
+        .balign 16
+	.globl	_ffi_call_win32
+#ifndef __OS2__
+	.def	_ffi_call_win32;	.scl	2;	.type	32;	.endef
+#endif
+_ffi_call_win32:
+.LFB1:
+        pushl %ebp
+.LCFI0:
+        movl  %esp,%ebp
+.LCFI1:
+        # Make room for all of the new args.
+        movl  16(%ebp),%ecx                                                     
+        subl  %ecx,%esp
+ 
+        movl  %esp,%eax
+ 
+        # Place all of the ffi_prep_args in position
+        pushl 12(%ebp)
+        pushl %eax
+        call  *8(%ebp)
+ 
+        # Return stack to previous state and call the function
+        addl  $8,%esp
+ 
+        # FIXME: Align the stack to a 128-bit boundary to avoid
+        # potential performance hits.
+
+        call  *28(%ebp)
+ 
+        # stdcall functions pop arguments off the stack themselves
+
+        # Load %ecx with the return type code
+        movl  20(%ebp),%ecx
+ 
+        # If the return value pointer is NULL, assume no return value.
+        cmpl  $0,24(%ebp)
+        jne   0f
+ 
+        # Even if there is no space for the return value, we are
+        # obliged to handle floating-point values.
+        cmpl  $FFI_TYPE_FLOAT,%ecx
+        jne   .Lnoretval
+        fstp  %st(0)
+ 
+        jmp   .Lepilogue
+
+0:
+	call	1f
+	# Do not insert anything here between the call and the jump table.
+.Lstore_table:
+	.long	.Lnoretval		/* FFI_TYPE_VOID */
+	.long	.Lretint		/* FFI_TYPE_INT */
+	.long	.Lretfloat		/* FFI_TYPE_FLOAT */
+	.long	.Lretdouble		/* FFI_TYPE_DOUBLE */
+	.long	.Lretlongdouble		/* FFI_TYPE_LONGDOUBLE */
+	.long	.Lretuint8		/* FFI_TYPE_UINT8 */
+	.long	.Lretsint8		/* FFI_TYPE_SINT8 */
+	.long	.Lretuint16		/* FFI_TYPE_UINT16 */
+	.long	.Lretsint16		/* FFI_TYPE_SINT16 */
+	.long	.Lretint		/* FFI_TYPE_UINT32 */
+	.long	.Lretint		/* FFI_TYPE_SINT32 */
+	.long	.Lretint64		/* FFI_TYPE_UINT64 */
+	.long	.Lretint64		/* FFI_TYPE_SINT64 */
+	.long	.Lretstruct		/* FFI_TYPE_STRUCT */
+	.long	.Lretint		/* FFI_TYPE_POINTER */
+	.long	.Lretstruct1b		/* FFI_TYPE_SMALL_STRUCT_1B */
+	.long	.Lretstruct2b		/* FFI_TYPE_SMALL_STRUCT_2B */
+	.long	.Lretstruct4b		/* FFI_TYPE_SMALL_STRUCT_4B */
+1:
+	add	%ecx, %ecx
+	add	%ecx, %ecx
+	add	(%esp),%ecx
+	add	$4, %esp
+	jmp	*(%ecx)
+
+	/* Sign/zero extend as appropriate.  */
+.Lretsint8:
+	movsbl	%al, %eax
+	jmp	.Lretint
+
+.Lretsint16:
+	movswl	%ax, %eax
+	jmp	.Lretint
+
+.Lretuint8:
+	movzbl	%al, %eax
+	jmp	.Lretint
+
+.Lretuint16:
+	movzwl	%ax, %eax
+	jmp	.Lretint
+
+.Lretint:
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        jmp   .Lepilogue
+ 
+.Lretfloat:
+         # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstps (%ecx)
+        jmp   .Lepilogue
+ 
+.Lretdouble:
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstpl (%ecx)
+        jmp   .Lepilogue
+ 
+.Lretlongdouble:
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstpt (%ecx)
+        jmp   .Lepilogue
+ 
+.Lretint64:
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        movl  %edx,4(%ecx)
+	jmp   .Lepilogue
+
+.Lretstruct1b:
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movb  %al,0(%ecx)
+        jmp   .Lepilogue
+ 
+.Lretstruct2b:
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movw  %ax,0(%ecx)
+        jmp   .Lepilogue
+
+.Lretstruct4b:
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        jmp   .Lepilogue
+
+.Lretstruct:
+        # Nothing to do!
+ 
+.Lnoretval:
+.Lepilogue:
+        movl %ebp,%esp
+        popl %ebp
+        ret
+.ffi_call_win32_end:
+.LFE1:
+
+        # This assumes we are using gas.
+        .balign 16
+	.globl	_ffi_closure_SYSV
+#ifndef __OS2__
+	.def	_ffi_closure_SYSV;	.scl	2;	.type	32;	.endef
+#endif
+_ffi_closure_SYSV:
+.LFB3:
+	pushl	%ebp
+.LCFI4:
+	movl	%esp, %ebp
+.LCFI5:
+	subl	$40, %esp
+	leal	-24(%ebp), %edx
+	movl	%edx, -12(%ebp)	/* resp */
+	leal	8(%ebp), %edx
+	movl	%edx, 4(%esp)	/* args = __builtin_dwarf_cfa () */
+	leal	-12(%ebp), %edx
+	movl	%edx, (%esp)	/* &resp */
+	call	_ffi_closure_SYSV_inner
+	movl	-12(%ebp), %ecx
+
+0:
+	call	1f
+	# Do not insert anything here between the call and the jump table.
+.Lcls_store_table:
+	.long	.Lcls_noretval		/* FFI_TYPE_VOID */
+	.long	.Lcls_retint		/* FFI_TYPE_INT */
+	.long	.Lcls_retfloat		/* FFI_TYPE_FLOAT */
+	.long	.Lcls_retdouble		/* FFI_TYPE_DOUBLE */
+	.long	.Lcls_retldouble	/* FFI_TYPE_LONGDOUBLE */
+	.long	.Lcls_retuint8		/* FFI_TYPE_UINT8 */
+	.long	.Lcls_retsint8		/* FFI_TYPE_SINT8 */
+	.long	.Lcls_retuint16		/* FFI_TYPE_UINT16 */
+	.long	.Lcls_retsint16		/* FFI_TYPE_SINT16 */
+	.long	.Lcls_retint		/* FFI_TYPE_UINT32 */
+	.long	.Lcls_retint		/* FFI_TYPE_SINT32 */
+	.long	.Lcls_retllong		/* FFI_TYPE_UINT64 */
+	.long	.Lcls_retllong		/* FFI_TYPE_SINT64 */
+	.long	.Lcls_retstruct		/* FFI_TYPE_STRUCT */
+	.long	.Lcls_retint		/* FFI_TYPE_POINTER */
+	.long	.Lcls_retstruct1	/* FFI_TYPE_SMALL_STRUCT_1B */
+	.long	.Lcls_retstruct2	/* FFI_TYPE_SMALL_STRUCT_2B */
+	.long	.Lcls_retstruct4	/* FFI_TYPE_SMALL_STRUCT_4B */
+
+1:
+	add	%eax, %eax
+	add	%eax, %eax
+	add	(%esp),%eax
+	add	$4, %esp
+	jmp	*(%eax)
+
+	/* Sign/zero extend as appropriate.  */
+.Lcls_retsint8:
+	movsbl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+
+.Lcls_retsint16:
+	movswl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+
+.Lcls_retuint8:
+	movzbl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+
+.Lcls_retuint16:
+	movzwl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+
+.Lcls_retint:
+	movl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+
+.Lcls_retfloat:
+	flds	(%ecx)
+	jmp	.Lcls_epilogue
+
+.Lcls_retdouble:
+	fldl	(%ecx)
+	jmp	.Lcls_epilogue
+
+.Lcls_retldouble:
+	fldt	(%ecx)
+	jmp	.Lcls_epilogue
+
+.Lcls_retllong:
+	movl	(%ecx), %eax
+	movl	4(%ecx), %edx
+	jmp	.Lcls_epilogue
+
+.Lcls_retstruct1:
+	movsbl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+
+.Lcls_retstruct2:
+	movswl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+
+.Lcls_retstruct4:
+	movl	(%ecx), %eax
+	jmp	.Lcls_epilogue
+
+.Lcls_retstruct:
+        # Caller expects us to pop struct return value pointer hidden arg.
+	movl	%ebp, %esp
+	popl	%ebp
+	ret	$0x4
+
+.Lcls_noretval:
+.Lcls_epilogue:
+	movl	%ebp, %esp
+	popl	%ebp
+	ret
+.ffi_closure_SYSV_end:
+.LFE3:
+
+#if !FFI_NO_RAW_API
+
+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+#define CIF_FLAGS_OFFSET 20
+
+        # This assumes we are using gas.
+        .balign 16
+	.globl	_ffi_closure_raw_SYSV
+#ifndef __OS2__
+	.def	_ffi_closure_raw_SYSV;	.scl	2;	.type	32;	.endef
+#endif
+_ffi_closure_raw_SYSV:
+.LFB4:
+	pushl	%ebp
+.LCFI6:
+	movl	%esp, %ebp
+.LCFI7:
+	pushl	%esi
+.LCFI8:
+	subl	$36, %esp
+	movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
+	movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
+	movl	%edx, 12(%esp)	/* user_data */
+	leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
+	movl	%edx, 8(%esp)	/* raw_args */
+	leal	-24(%ebp), %edx
+	movl	%edx, 4(%esp)	/* &res */
+	movl	%esi, (%esp)	/* cif */
+	call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
+	movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
+0:
+	call	1f
+	# Do not insert anything here between the call and the jump table.
+.Lrcls_store_table:
+	.long	.Lrcls_noretval		/* FFI_TYPE_VOID */
+	.long	.Lrcls_retint		/* FFI_TYPE_INT */
+	.long	.Lrcls_retfloat		/* FFI_TYPE_FLOAT */
+	.long	.Lrcls_retdouble	/* FFI_TYPE_DOUBLE */
+	.long	.Lrcls_retldouble	/* FFI_TYPE_LONGDOUBLE */
+	.long	.Lrcls_retuint8		/* FFI_TYPE_UINT8 */
+	.long	.Lrcls_retsint8		/* FFI_TYPE_SINT8 */
+	.long	.Lrcls_retuint16	/* FFI_TYPE_UINT16 */
+	.long	.Lrcls_retsint16	/* FFI_TYPE_SINT16 */
+	.long	.Lrcls_retint		/* FFI_TYPE_UINT32 */
+	.long	.Lrcls_retint		/* FFI_TYPE_SINT32 */
+	.long	.Lrcls_retllong		/* FFI_TYPE_UINT64 */
+	.long	.Lrcls_retllong		/* FFI_TYPE_SINT64 */
+	.long	.Lrcls_retstruct	/* FFI_TYPE_STRUCT */
+	.long	.Lrcls_retint		/* FFI_TYPE_POINTER */
+	.long	.Lrcls_retstruct1	/* FFI_TYPE_SMALL_STRUCT_1B */
+	.long	.Lrcls_retstruct2	/* FFI_TYPE_SMALL_STRUCT_2B */
+	.long	.Lrcls_retstruct4	/* FFI_TYPE_SMALL_STRUCT_4B */
+1:
+	add	%eax, %eax
+	add	%eax, %eax
+	add	(%esp),%eax
+	add	$4, %esp
+	jmp	*(%eax)
+
+	/* Sign/zero extend as appropriate.  */
+.Lrcls_retsint8:
+	movsbl	-24(%ebp), %eax
+	jmp	.Lrcls_epilogue
+
+.Lrcls_retsint16:
+	movswl	-24(%ebp), %eax
+	jmp	.Lrcls_epilogue
+
+.Lrcls_retuint8:
+	movzbl	-24(%ebp), %eax
+	jmp	.Lrcls_epilogue
+
+.Lrcls_retuint16:
+	movzwl	-24(%ebp), %eax
+	jmp	.Lrcls_epilogue
+
+.Lrcls_retint:
+	movl	-24(%ebp), %eax
+	jmp	.Lrcls_epilogue
+
+.Lrcls_retfloat:
+	flds	-24(%ebp)
+	jmp	.Lrcls_epilogue
+
+.Lrcls_retdouble:
+	fldl	-24(%ebp)
+	jmp	.Lrcls_epilogue
+
+.Lrcls_retldouble:
+	fldt	-24(%ebp)
+	jmp	.Lrcls_epilogue
+
+.Lrcls_retllong:
+	movl	-24(%ebp), %eax
+	movl	-20(%ebp), %edx
+	jmp	.Lrcls_epilogue
+
+.Lrcls_retstruct1:
+	movsbl	-24(%ebp), %eax
+	jmp	.Lrcls_epilogue
+
+.Lrcls_retstruct2:
+	movswl	-24(%ebp), %eax
+	jmp	.Lrcls_epilogue
+
+.Lrcls_retstruct4:
+	movl	-24(%ebp), %eax
+	jmp	.Lrcls_epilogue
+
+.Lrcls_retstruct:
+	# Nothing to do!
+
+.Lrcls_noretval:
+.Lrcls_epilogue:
+	addl	$36, %esp
+	popl	%esi
+	popl	%ebp
+	ret
+.ffi_closure_raw_SYSV_end:
+.LFE4:
+
+#endif /* !FFI_NO_RAW_API */
+
+        # This assumes we are using gas.
+	.balign	16
+	.globl	_ffi_closure_STDCALL
+#ifndef __OS2__
+	.def	_ffi_closure_STDCALL;	.scl	2;	.type	32;	.endef
+#endif
+_ffi_closure_STDCALL:
+.LFB5:
+	pushl	%ebp
+.LCFI9:
+	movl	%esp, %ebp
+.LCFI10:
+	subl	$40, %esp
+	leal	-24(%ebp), %edx
+	movl	%edx, -12(%ebp)	/* resp */
+	leal	12(%ebp), %edx  /* account for stub return address on stack */
+	movl	%edx, 4(%esp)	/* args */
+	leal	-12(%ebp), %edx
+	movl	%edx, (%esp)	/* &resp */
+	call	_ffi_closure_SYSV_inner
+	movl	-12(%ebp), %ecx
+0:
+	call	1f
+	# Do not insert anything here between the call and the jump table.
+.Lscls_store_table:
+	.long	.Lscls_noretval		/* FFI_TYPE_VOID */
+	.long	.Lscls_retint		/* FFI_TYPE_INT */
+	.long	.Lscls_retfloat		/* FFI_TYPE_FLOAT */
+	.long	.Lscls_retdouble	/* FFI_TYPE_DOUBLE */
+	.long	.Lscls_retldouble	/* FFI_TYPE_LONGDOUBLE */
+	.long	.Lscls_retuint8		/* FFI_TYPE_UINT8 */
+	.long	.Lscls_retsint8		/* FFI_TYPE_SINT8 */
+	.long	.Lscls_retuint16	/* FFI_TYPE_UINT16 */
+	.long	.Lscls_retsint16	/* FFI_TYPE_SINT16 */
+	.long	.Lscls_retint		/* FFI_TYPE_UINT32 */
+	.long	.Lscls_retint		/* FFI_TYPE_SINT32 */
+	.long	.Lscls_retllong		/* FFI_TYPE_UINT64 */
+	.long	.Lscls_retllong		/* FFI_TYPE_SINT64 */
+	.long	.Lscls_retstruct	/* FFI_TYPE_STRUCT */
+	.long	.Lscls_retint		/* FFI_TYPE_POINTER */
+	.long	.Lscls_retstruct1	/* FFI_TYPE_SMALL_STRUCT_1B */
+	.long	.Lscls_retstruct2	/* FFI_TYPE_SMALL_STRUCT_2B */
+	.long	.Lscls_retstruct4	/* FFI_TYPE_SMALL_STRUCT_4B */
+1:
+	add	%eax, %eax
+	add	%eax, %eax
+	add	(%esp),%eax
+	add	$4, %esp
+	jmp	*(%eax)
+
+	/* Sign/zero extend as appropriate.  */
+.Lscls_retsint8:
+	movsbl	(%ecx), %eax
+	jmp	.Lscls_epilogue
+
+.Lscls_retsint16:
+	movswl	(%ecx), %eax
+	jmp	.Lscls_epilogue
+
+.Lscls_retuint8:
+	movzbl	(%ecx), %eax
+	jmp	.Lscls_epilogue
+
+.Lscls_retuint16:
+	movzwl	(%ecx), %eax
+	jmp	.Lscls_epilogue
+
+.Lscls_retint:
+	movl	(%ecx), %eax
+	jmp	.Lscls_epilogue
+
+.Lscls_retfloat:
+	flds	(%ecx)
+	jmp	.Lscls_epilogue
+
+.Lscls_retdouble:
+	fldl	(%ecx)
+	jmp	.Lscls_epilogue
+
+.Lscls_retldouble:
+	fldt	(%ecx)
+	jmp	.Lscls_epilogue
+
+.Lscls_retllong:
+	movl	(%ecx), %eax
+	movl	4(%ecx), %edx
+	jmp	.Lscls_epilogue
+
+.Lscls_retstruct1:
+	movsbl	(%ecx), %eax
+	jmp	.Lscls_epilogue
+
+.Lscls_retstruct2:
+	movswl	(%ecx), %eax
+	jmp	.Lscls_epilogue
+
+.Lscls_retstruct4:
+	movl	(%ecx), %eax
+	jmp	.Lscls_epilogue
+
+.Lscls_retstruct:
+	# Nothing to do!
+
+.Lscls_noretval:
+.Lscls_epilogue:
+	movl	%ebp, %esp
+	popl	%ebp
+	ret
+.ffi_closure_STDCALL_end:
+.LFE5:
+
+#ifndef __OS2__
+	.section	.eh_frame,"w"
+#endif
+.Lframe1:
+.LSCIE1:
+	.long	.LECIE1-.LASCIE1  /* Length of Common Information Entry */
+.LASCIE1:
+	.long	0x0	/* CIE Identifier Tag */
+	.byte	0x1	/* CIE Version */
+#ifdef __PIC__
+	.ascii "zR\0"	/* CIE Augmentation */
+#else
+	.ascii "\0"	/* CIE Augmentation */
+#endif
+	.byte	0x1	/* .uleb128 0x1; CIE Code Alignment Factor */
+	.byte	0x7c	/* .sleb128 -4; CIE Data Alignment Factor */
+	.byte	0x8	/* CIE RA Column */
+#ifdef __PIC__
+	.byte	0x1	/* .uleb128 0x1; Augmentation size */
+	.byte	0x1b	/* FDE Encoding (pcrel sdata4) */
+#endif
+	.byte	0xc	/* DW_CFA_def_cfa CFA = r4 + 4 = 4(%esp) */
+	.byte	0x4	/* .uleb128 0x4 */
+	.byte	0x4	/* .uleb128 0x4 */
+	.byte	0x88	/* DW_CFA_offset, column 0x8 %eip at CFA + 1 * -4 */
+	.byte	0x1	/* .uleb128 0x1 */
+	.align 4
+.LECIE1:
+
+.LSFDE1:
+	.long	.LEFDE1-.LASFDE1	/* FDE Length */
+.LASFDE1:
+	.long	.LASFDE1-.Lframe1	/* FDE CIE offset */
+#if defined __PIC__ && defined HAVE_AS_X86_PCREL
+	.long	.LFB1-.	/* FDE initial location */
+#else
+	.long	.LFB1
+#endif
+	.long	.LFE1-.LFB1	/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	/* DW_CFA_xxx CFI instructions go here.  */
+
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI0-.LFB1
+	.byte	0xe	/* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
+	.byte	0x2	/* .uleb128 0x2 */
+
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI1-.LCFI0
+	.byte	0xd	/* DW_CFA_def_cfa_register CFA = r5 = %ebp */
+	.byte	0x5	/* .uleb128 0x5 */
+
+	/* End of DW_CFA_xxx CFI instructions.  */
+	.align 4
+.LEFDE1:
+
+
+.LSFDE3:
+	.long	.LEFDE3-.LASFDE3	/* FDE Length */
+.LASFDE3:
+	.long	.LASFDE3-.Lframe1	/* FDE CIE offset */
+#if defined __PIC__ && defined HAVE_AS_X86_PCREL
+	.long	.LFB3-.	/* FDE initial location */
+#else
+	.long	.LFB3
+#endif
+	.long	.LFE3-.LFB3	/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	/* DW_CFA_xxx CFI instructions go here.  */
+
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI4-.LFB3
+	.byte	0xe	/* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
+	.byte	0x2	/* .uleb128 0x2 */
+
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI5-.LCFI4
+	.byte	0xd	/* DW_CFA_def_cfa_register CFA = r5 = %ebp */
+	.byte	0x5	/* .uleb128 0x5 */
+
+	/* End of DW_CFA_xxx CFI instructions.  */
+	.align 4
+.LEFDE3:
+
+#if !FFI_NO_RAW_API
+
+.LSFDE4:
+	.long	.LEFDE4-.LASFDE4	/* FDE Length */
+.LASFDE4:
+	.long	.LASFDE4-.Lframe1	/* FDE CIE offset */
+#if defined __PIC__ && defined HAVE_AS_X86_PCREL
+	.long	.LFB4-.	/* FDE initial location */
+#else
+	.long	.LFB4
+#endif
+	.long	.LFE4-.LFB4	/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	/* DW_CFA_xxx CFI instructions go here.  */
+
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI6-.LFB4
+	.byte	0xe	/* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
+	.byte	0x2	/* .uleb128 0x2 */
+
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI7-.LCFI6
+	.byte	0xd	/* DW_CFA_def_cfa_register CFA = r5 = %ebp */
+	.byte	0x5	/* .uleb128 0x5 */
+
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI8-.LCFI7
+	.byte	0x86	/* DW_CFA_offset, column 0x6 %esi at CFA + 3 * -4 */
+	.byte	0x3	/* .uleb128 0x3 */
+
+	/* End of DW_CFA_xxx CFI instructions.  */
+	.align 4
+.LEFDE4:
+
+#endif /* !FFI_NO_RAW_API */
+
+.LSFDE5:
+	.long	.LEFDE5-.LASFDE5	/* FDE Length */
+.LASFDE5:
+	.long	.LASFDE5-.Lframe1	/* FDE CIE offset */
+#if defined __PIC__ && defined HAVE_AS_X86_PCREL
+	.long	.LFB5-.	/* FDE initial location */
+#else
+	.long	.LFB5
+#endif
+	.long	.LFE5-.LFB5	/* FDE address range */
+#ifdef __PIC__
+	.byte	0x0	/* .uleb128 0x0; Augmentation size */
+#endif
+	/* DW_CFA_xxx CFI instructions go here.  */
+
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI9-.LFB5
+	.byte	0xe	/* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
+	.byte	0x8	/* .uleb128 0x8 */
+	.byte	0x85	/* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
+	.byte	0x2	/* .uleb128 0x2 */
+
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.long	.LCFI10-.LCFI9
+	.byte	0xd	/* DW_CFA_def_cfa_register CFA = r5 = %ebp */
+	.byte	0x5	/* .uleb128 0x5 */
+
+	/* End of DW_CFA_xxx CFI instructions.  */
+	.align 4
+.LEFDE5:
+
+#endif /* !_MSC_VER */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/win64.S b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/win64.S
new file mode 100755
index 0000000..fcdb270
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/src/x86/win64.S
@@ -0,0 +1,468 @@
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+	
+/* Constants for ffi_call_win64 */	
+#define STACK 0
+#define PREP_ARGS_FN 32
+#define ECIF 40
+#define CIF_BYTES 48
+#define CIF_FLAGS 56
+#define RVALUE 64
+#define FN 72
+
+/* ffi_call_win64 (void (*prep_args_fn)(char *, extended_cif *),
+                   extended_cif *ecif, unsigned bytes, unsigned flags,
+                   unsigned *rvalue, void (*fn)());
+ */
+
+#ifdef _MSC_VER
+PUBLIC	ffi_call_win64
+
+EXTRN	__chkstk:NEAR
+EXTRN	ffi_closure_win64_inner:NEAR
+
+_TEXT	SEGMENT
+
+;;; ffi_closure_win64 will be called with these registers set:
+;;;    rax points to 'closure'
+;;;    r11 contains a bit mask that specifies which of the
+;;;    first four parameters are float or double
+;;;
+;;; It must move the parameters passed in registers to their stack location,
+;;; call ffi_closure_win64_inner for the actual work, then return the result.
+;;; 
+ffi_closure_win64 PROC FRAME
+	;; copy register arguments onto stack
+	test	r11, 1
+	jne	first_is_float	
+	mov	QWORD PTR [rsp+8], rcx
+	jmp	second
+first_is_float:
+	movlpd	QWORD PTR [rsp+8], xmm0
+
+second:
+	test	r11, 2
+	jne	second_is_float	
+	mov	QWORD PTR [rsp+16], rdx
+	jmp	third
+second_is_float:
+	movlpd	QWORD PTR [rsp+16], xmm1
+
+third:
+	test	r11, 4
+	jne	third_is_float	
+	mov	QWORD PTR [rsp+24], r8
+	jmp	fourth
+third_is_float:
+	movlpd	QWORD PTR [rsp+24], xmm2
+
+fourth:
+	test	r11, 8
+	jne	fourth_is_float	
+	mov	QWORD PTR [rsp+32], r9
+	jmp	done
+fourth_is_float:
+	movlpd	QWORD PTR [rsp+32], xmm3
+
+done:
+        .ALLOCSTACK 40
+	sub	rsp, 40
+        .ENDPROLOG
+	mov	rcx, rax	; context is first parameter
+	mov	rdx, rsp	; stack is second parameter
+	add	rdx, 48		; point to start of arguments
+	mov	rax, ffi_closure_win64_inner
+	call	rax		; call the real closure function
+	add	rsp, 40
+	movd	xmm0, rax	; If the closure returned a float,
+                                ; ffi_closure_win64_inner wrote it to rax
+	ret	0
+ffi_closure_win64 ENDP
+
+ffi_call_win64 PROC FRAME
+        ;; copy registers onto stack
+	mov	QWORD PTR [rsp+32], r9
+	mov	QWORD PTR [rsp+24], r8
+	mov	QWORD PTR [rsp+16], rdx
+	mov	QWORD PTR [rsp+8], rcx
+        .PUSHREG rbp
+	push	rbp
+        .ALLOCSTACK 48
+	sub	rsp, 48					; 00000030H
+        .SETFRAME rbp, 32
+	lea	rbp, QWORD PTR [rsp+32]
+        .ENDPROLOG
+
+	mov	eax, DWORD PTR CIF_BYTES[rbp]
+	add	rax, 15
+	and	rax, -16
+	call	__chkstk
+	sub	rsp, rax
+	lea	rax, QWORD PTR [rsp+32]
+	mov	QWORD PTR STACK[rbp], rax
+
+	mov	rdx, QWORD PTR ECIF[rbp]
+	mov	rcx, QWORD PTR STACK[rbp]
+	call	QWORD PTR PREP_ARGS_FN[rbp]
+
+	mov	rsp, QWORD PTR STACK[rbp]
+
+	movlpd	xmm3, QWORD PTR [rsp+24]
+	movd	r9, xmm3
+
+	movlpd	xmm2, QWORD PTR [rsp+16]
+	movd	r8, xmm2
+
+	movlpd	xmm1, QWORD PTR [rsp+8]
+	movd	rdx, xmm1
+
+	movlpd	xmm0, QWORD PTR [rsp]
+	movd	rcx, xmm0
+
+	call	QWORD PTR FN[rbp]
+ret_struct4b$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_4B
+ 	jne	ret_struct2b$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	mov	DWORD PTR [rcx], eax
+	jmp	ret_void$
+
+ret_struct2b$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_2B
+ 	jne	ret_struct1b$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	mov	WORD PTR [rcx], ax
+	jmp	ret_void$
+
+ret_struct1b$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_1B
+ 	jne	ret_uint8$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	mov	BYTE PTR [rcx], al
+	jmp	ret_void$
+
+ret_uint8$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT8
+ 	jne	ret_sint8$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	movzx   rax, al
+	mov	QWORD PTR [rcx], rax
+	jmp	ret_void$
+
+ret_sint8$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT8
+ 	jne	ret_uint16$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	movsx   rax, al
+	mov	QWORD PTR [rcx], rax
+	jmp	ret_void$
+
+ret_uint16$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT16
+ 	jne	ret_sint16$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	movzx   rax, ax
+	mov	QWORD PTR [rcx], rax
+	jmp	SHORT ret_void$
+
+ret_sint16$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT16
+ 	jne	ret_uint32$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	movsx   rax, ax
+	mov	QWORD PTR [rcx], rax
+	jmp	SHORT ret_void$
+
+ret_uint32$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT32
+ 	jne	ret_sint32$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	mov     eax, eax
+	mov	QWORD PTR [rcx], rax
+	jmp	SHORT ret_void$
+
+ret_sint32$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT32
+ 	jne	ret_float$
+
+	mov	rcx, QWORD PTR RVALUE[rbp]
+	cdqe
+	mov	QWORD PTR [rcx], rax
+	jmp	SHORT ret_void$
+
+ret_float$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_FLOAT
+ 	jne	SHORT ret_double$
+
+ 	mov	rax, QWORD PTR RVALUE[rbp]
+ 	movss	DWORD PTR [rax], xmm0
+ 	jmp	SHORT ret_void$
+
+ret_double$:
+ 	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_DOUBLE
+ 	jne	SHORT ret_sint64$
+
+ 	mov	rax, QWORD PTR RVALUE[rbp]
+ 	movlpd	QWORD PTR [rax], xmm0
+ 	jmp	SHORT ret_void$
+
+ret_sint64$:
+  	cmp	DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT64
+  	jne	ret_void$
+
+ 	mov	rcx, QWORD PTR RVALUE[rbp]
+ 	mov	QWORD PTR [rcx], rax
+ 	jmp	SHORT ret_void$
+	
+ret_void$:
+	xor	rax, rax
+
+	lea	rsp, QWORD PTR [rbp+16]
+	pop	rbp
+	ret	0
+ffi_call_win64 ENDP
+_TEXT	ENDS
+END
+
+#else
+
+#ifdef SYMBOL_UNDERSCORE
+#define SYMBOL_NAME(name) _##name
+#else
+#define SYMBOL_NAME(name) name
+#endif
+
+.text
+
+.extern SYMBOL_NAME(ffi_closure_win64_inner)
+
+# ffi_closure_win64 will be called with these registers set:
+#    rax points to 'closure'
+#    r11 contains a bit mask that specifies which of the
+#    first four parameters are float or double
+#
+# It must move the parameters passed in registers to their stack location,
+# call ffi_closure_win64_inner for the actual work, then return the result.
+# 
+	.balign 16
+        .globl SYMBOL_NAME(ffi_closure_win64)
+SYMBOL_NAME(ffi_closure_win64):
+	# copy register arguments onto stack
+	test	$1,%r11
+	jne	.Lfirst_is_float	
+	mov	%rcx, 8(%rsp)
+	jmp	.Lsecond
+.Lfirst_is_float:
+	movlpd	%xmm0, 8(%rsp)
+
+.Lsecond:
+	test	$2, %r11
+	jne	.Lsecond_is_float	
+	mov	%rdx, 16(%rsp)
+	jmp	.Lthird
+.Lsecond_is_float:
+	movlpd	%xmm1, 16(%rsp)
+
+.Lthird:
+	test	$4, %r11
+	jne	.Lthird_is_float	
+	mov	%r8,24(%rsp)
+	jmp	.Lfourth
+.Lthird_is_float:
+	movlpd	%xmm2, 24(%rsp)
+
+.Lfourth:
+	test	$8, %r11
+	jne	.Lfourth_is_float	
+	mov	%r9, 32(%rsp)
+	jmp	.Ldone
+.Lfourth_is_float:
+	movlpd	%xmm3, 32(%rsp)
+
+.Ldone:
+#.ALLOCSTACK 40
+	sub	$40, %rsp
+#.ENDPROLOG
+	mov	%rax, %rcx	# context is first parameter
+	mov	%rsp, %rdx	# stack is second parameter
+	add	$48, %rdx	# point to start of arguments
+	mov	$SYMBOL_NAME(ffi_closure_win64_inner), %rax
+	callq	*%rax		# call the real closure function
+	add	$40, %rsp
+	movq	%rax, %xmm0	# If the closure returned a float,
+                                # ffi_closure_win64_inner wrote it to rax
+	retq
+.ffi_closure_win64_end:
+
+	.balign 16
+        .globl	SYMBOL_NAME(ffi_call_win64)
+SYMBOL_NAME(ffi_call_win64):
+        # copy registers onto stack
+	mov	%r9,32(%rsp)
+	mov	%r8,24(%rsp)
+	mov	%rdx,16(%rsp)
+	mov	%rcx,8(%rsp)
+        #.PUSHREG rbp
+	push	%rbp
+        #.ALLOCSTACK 48
+	sub	$48,%rsp
+        #.SETFRAME rbp, 32
+	lea	32(%rsp),%rbp
+        #.ENDPROLOG
+
+	mov	CIF_BYTES(%rbp),%eax
+	add	$15, %rax
+	and	$-16, %rax
+	cmpq	$0x1000, %rax
+	jb	Lch_done
+Lch_probe:
+	subq	$0x1000,%rsp
+	orl	$0x0, (%rsp)
+	subq	$0x1000,%rax
+	cmpq	$0x1000,%rax
+	ja	Lch_probe
+Lch_done:
+	subq	%rax, %rsp
+	orl	$0x0, (%rsp)
+	lea	32(%rsp), %rax
+	mov	%rax, STACK(%rbp)
+
+	mov	ECIF(%rbp), %rdx
+	mov	STACK(%rbp), %rcx
+	callq	*PREP_ARGS_FN(%rbp)
+
+	mov	STACK(%rbp), %rsp
+
+	movlpd	24(%rsp), %xmm3
+	movd	%xmm3, %r9
+
+	movlpd	16(%rsp), %xmm2
+	movd	%xmm2, %r8
+
+	movlpd	8(%rsp), %xmm1
+	movd	%xmm1, %rdx
+
+	movlpd	(%rsp), %xmm0
+	movd	%xmm0, %rcx
+
+	callq	*FN(%rbp)
+.Lret_struct4b:
+ 	cmpl	$FFI_TYPE_SMALL_STRUCT_4B, CIF_FLAGS(%rbp)
+ 	jne .Lret_struct2b
+
+	mov	RVALUE(%rbp), %rcx
+	mov	%eax, (%rcx)
+	jmp	.Lret_void
+
+.Lret_struct2b:
+	cmpl	$FFI_TYPE_SMALL_STRUCT_2B, CIF_FLAGS(%rbp)
+	jne .Lret_struct1b
+	
+	mov	RVALUE(%rbp), %rcx
+	mov	%ax, (%rcx)
+	jmp .Lret_void
+	
+.Lret_struct1b:
+	cmpl	$FFI_TYPE_SMALL_STRUCT_1B, CIF_FLAGS(%rbp)
+	jne .Lret_uint8
+	
+	mov	RVALUE(%rbp), %rcx
+	mov	%al, (%rcx)
+	jmp .Lret_void
+
+.Lret_uint8:
+	cmpl	$FFI_TYPE_UINT8, CIF_FLAGS(%rbp)
+	jne .Lret_sint8
+	
+        mov     RVALUE(%rbp), %rcx
+        movzbq  %al, %rax
+	movq    %rax, (%rcx)
+	jmp .Lret_void
+
+.Lret_sint8:
+	cmpl	$FFI_TYPE_SINT8, CIF_FLAGS(%rbp)
+	jne .Lret_uint16
+	
+        mov     RVALUE(%rbp), %rcx
+        movsbq  %al, %rax
+	movq    %rax, (%rcx)
+	jmp .Lret_void
+
+.Lret_uint16:
+	cmpl	$FFI_TYPE_UINT16, CIF_FLAGS(%rbp)
+	jne .Lret_sint16
+	
+        mov     RVALUE(%rbp), %rcx
+        movzwq  %ax, %rax
+	movq    %rax, (%rcx)
+	jmp .Lret_void
+
+.Lret_sint16:
+	cmpl	$FFI_TYPE_SINT16, CIF_FLAGS(%rbp)
+	jne .Lret_uint32
+	
+        mov     RVALUE(%rbp), %rcx
+        movswq  %ax, %rax
+	movq    %rax, (%rcx)
+	jmp .Lret_void
+
+.Lret_uint32:
+	cmpl	$FFI_TYPE_UINT32, CIF_FLAGS(%rbp)
+	jne .Lret_sint32
+	
+        mov     RVALUE(%rbp), %rcx
+        movl    %eax, %eax
+	movq    %rax, (%rcx)
+	jmp .Lret_void
+
+.Lret_sint32:
+ 	cmpl	$FFI_TYPE_SINT32, CIF_FLAGS(%rbp)
+ 	jne	.Lret_float
+
+	mov	RVALUE(%rbp), %rcx
+	cltq
+	movq	%rax, (%rcx)
+	jmp	.Lret_void
+
+.Lret_float:
+ 	cmpl	$FFI_TYPE_FLOAT, CIF_FLAGS(%rbp)
+ 	jne	.Lret_double
+
+ 	mov	RVALUE(%rbp), %rax
+ 	movss	%xmm0, (%rax)
+ 	jmp	.Lret_void
+
+.Lret_double:
+ 	cmpl	$FFI_TYPE_DOUBLE, CIF_FLAGS(%rbp)
+ 	jne	.Lret_sint64
+
+ 	mov	RVALUE(%rbp), %rax
+ 	movlpd	%xmm0, (%rax)
+ 	jmp	.Lret_void
+
+.Lret_sint64:
+  	cmpl	$FFI_TYPE_SINT64, CIF_FLAGS(%rbp)
+  	jne	.Lret_void
+
+ 	mov	RVALUE(%rbp), %rcx
+ 	mov	%rax, (%rcx)
+ 	jmp	.Lret_void
+	
+.Lret_void:
+	xor	%rax, %rax
+
+	lea	16(%rbp), %rsp
+	pop	%rbp
+	retq
+.ffi_call_win64_end:
+#endif /* !_MSC_VER */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/Makefile.am b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/Makefile.am
new file mode 100755
index 0000000..cfd1df4
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/Makefile.am
@@ -0,0 +1,80 @@
+## Process this file with automake to produce Makefile.in.
+
+AUTOMAKE_OPTIONS = foreign dejagnu
+
+# Setup the testing framework, if you have one
+EXPECT = `if [ -f $(top_builddir)/../expect/expect ] ; then \
+            echo $(top_builddir)/../expect/expect ; \
+          else echo expect ; fi`
+
+RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \
+	       echo $(top_srcdir)/../dejagnu/runtest ; \
+	    else echo runtest; fi`
+
+AM_RUNTESTFLAGS =
+
+CLEANFILES = *.exe core* *.log *.sum
+
+EXTRA_DIST = libffi.special/special.exp	\
+libffi.special/unwindtest_ffi_call.cc libffi.special/unwindtest.cc \
+libffi.special/ffitestcxx.h config/default.exp lib/target-libpath.exp \
+lib/libffi.exp lib/wrapper.exp libffi.call/float.c \
+libffi.call/cls_multi_schar.c libffi.call/float3.c \
+libffi.call/cls_3_1byte.c libffi.call/stret_large2.c \
+libffi.call/cls_5_1_byte.c libffi.call/stret_medium.c \
+libffi.call/promotion.c libffi.call/cls_dbls_struct.c \
+libffi.call/nested_struct.c libffi.call/closure_fn1.c \
+libffi.call/cls_4_1byte.c libffi.call/cls_float.c \
+libffi.call/cls_2byte.c libffi.call/closure_fn4.c \
+libffi.call/return_fl2.c libffi.call/nested_struct7.c \
+libffi.call/cls_uint.c libffi.call/cls_align_sint64.c \
+libffi.call/float1.c libffi.call/cls_19byte.c \
+libffi.call/nested_struct1.c libffi.call/cls_4byte.c \
+libffi.call/return_fl1.c libffi.call/cls_align_pointer.c \
+libffi.call/nested_struct4.c libffi.call/nested_struct3.c \
+libffi.call/struct7.c libffi.call/nested_struct9.c \
+libffi.call/cls_sshort.c libffi.call/cls_ulonglong.c \
+libffi.call/cls_pointer_stack.c libffi.call/cls_multi_uchar.c \
+libffi.call/testclosure.c libffi.call/cls_3byte1.c \
+libffi.call/struct6.c libffi.call/return_uc.c libffi.call/return_ll1.c \
+libffi.call/cls_ushort.c libffi.call/stret_medium2.c \
+libffi.call/cls_multi_ushortchar.c libffi.call/return_dbl2.c \
+libffi.call/closure_loc_fn0.c libffi.call/return_sc.c \
+libffi.call/nested_struct8.c libffi.call/cls_7_1_byte.c	\
+libffi.call/return_ll.c libffi.call/cls_pointer.c \
+libffi.call/err_bad_abi.c libffi.call/return_dbl1.c \
+libffi.call/call.exp libffi.call/ffitest.h libffi.call/strlen.c	\
+libffi.call/return_sl.c libffi.call/cls_1_1byte.c \
+libffi.call/struct1.c libffi.call/cls_64byte.c libffi.call/return_ul.c \
+libffi.call/cls_double.c libffi.call/many_win32.c \
+libffi.call/cls_16byte.c libffi.call/cls_align_double.c	\
+libffi.call/cls_align_uint16.c libffi.call/cls_9byte1.c	\
+libffi.call/cls_multi_sshortchar.c libffi.call/cls_multi_ushort.c \
+libffi.call/closure_stdcall.c libffi.call/return_fl.c \
+libffi.call/strlen_win32.c libffi.call/return_ldl.c \
+libffi.call/cls_align_float.c libffi.call/struct3.c \
+libffi.call/cls_uchar.c libffi.call/cls_sint.c libffi.call/float2.c \
+libffi.call/cls_align_longdouble_split.c \
+libffi.call/cls_longdouble_va.c libffi.call/cls_multi_sshort.c \
+libffi.call/stret_large.c libffi.call/cls_align_sint16.c \
+libffi.call/nested_struct6.c libffi.call/cls_5byte.c \
+libffi.call/return_dbl.c libffi.call/cls_20byte.c \
+libffi.call/cls_8byte.c libffi.call/pyobjc-tc.c	\
+libffi.call/cls_24byte.c libffi.call/cls_align_longdouble_split2.c \
+libffi.call/cls_6_1_byte.c libffi.call/cls_schar.c \
+libffi.call/cls_18byte.c libffi.call/closure_fn3.c \
+libffi.call/err_bad_typedef.c libffi.call/closure_fn2.c	\
+libffi.call/struct2.c libffi.call/cls_3byte2.c \
+libffi.call/cls_align_longdouble.c libffi.call/cls_20byte1.c \
+libffi.call/return_fl3.c libffi.call/cls_align_uint32.c	\
+libffi.call/problem1.c libffi.call/float4.c \
+libffi.call/cls_align_uint64.c libffi.call/struct9.c \
+libffi.call/closure_fn5.c libffi.call/cls_align_sint32.c \
+libffi.call/closure_fn0.c libffi.call/closure_fn6.c \
+libffi.call/struct4.c libffi.call/nested_struct2.c \
+libffi.call/cls_6byte.c libffi.call/cls_7byte.c libffi.call/many.c \
+libffi.call/struct8.c libffi.call/negint.c libffi.call/struct5.c \
+libffi.call/cls_12byte.c libffi.call/cls_double_va.c \
+libffi.call/cls_longdouble.c libffi.call/cls_9byte2.c \
+libffi.call/nested_struct10.c libffi.call/nested_struct5.c \
+libffi.call/huge_struct.c
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/Makefile.in b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/Makefile.in
new file mode 100755
index 0000000..53de9c0
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/Makefile.in
@@ -0,0 +1,500 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = testsuite
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_maxopt.m4 \
+	$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
+	$(top_srcdir)/m4/ax_check_compiler_flags.m4 \
+	$(top_srcdir)/m4/ax_compiler_vendor.m4 \
+	$(top_srcdir)/m4/ax_configure_args.m4 \
+	$(top_srcdir)/m4/ax_enable_builddir.m4 \
+	$(top_srcdir)/m4/ax_gcc_archflag.m4 \
+	$(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/fficonfig.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+DEJATOOL = $(PACKAGE)
+RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_LTLDFLAGS = @AM_LTLDFLAGS@
+AM_RUNTESTFLAGS = 
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PRTDIAG = @PRTDIAG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TARGET = @TARGET@
+TARGETDIR = @TARGETDIR@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_enable_builddir_sed = @ax_enable_builddir_sed@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sys_symbol_underscore = @sys_symbol_underscore@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+toolexecdir = @toolexecdir@
+toolexeclibdir = @toolexeclibdir@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign dejagnu
+
+# Setup the testing framework, if you have one
+EXPECT = `if [ -f $(top_builddir)/../expect/expect ] ; then \
+            echo $(top_builddir)/../expect/expect ; \
+          else echo expect ; fi`
+
+RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \
+	       echo $(top_srcdir)/../dejagnu/runtest ; \
+	    else echo runtest; fi`
+
+CLEANFILES = *.exe core* *.log *.sum
+EXTRA_DIST = libffi.special/special.exp	\
+libffi.special/unwindtest_ffi_call.cc libffi.special/unwindtest.cc \
+libffi.special/ffitestcxx.h config/default.exp lib/target-libpath.exp \
+lib/libffi.exp lib/wrapper.exp libffi.call/float.c \
+libffi.call/cls_multi_schar.c libffi.call/float3.c \
+libffi.call/cls_3_1byte.c libffi.call/stret_large2.c \
+libffi.call/cls_5_1_byte.c libffi.call/stret_medium.c \
+libffi.call/promotion.c libffi.call/cls_dbls_struct.c \
+libffi.call/nested_struct.c libffi.call/closure_fn1.c \
+libffi.call/cls_4_1byte.c libffi.call/cls_float.c \
+libffi.call/cls_2byte.c libffi.call/closure_fn4.c \
+libffi.call/return_fl2.c libffi.call/nested_struct7.c \
+libffi.call/cls_uint.c libffi.call/cls_align_sint64.c \
+libffi.call/float1.c libffi.call/cls_19byte.c \
+libffi.call/nested_struct1.c libffi.call/cls_4byte.c \
+libffi.call/return_fl1.c libffi.call/cls_align_pointer.c \
+libffi.call/nested_struct4.c libffi.call/nested_struct3.c \
+libffi.call/struct7.c libffi.call/nested_struct9.c \
+libffi.call/cls_sshort.c libffi.call/cls_ulonglong.c \
+libffi.call/cls_pointer_stack.c libffi.call/cls_multi_uchar.c \
+libffi.call/testclosure.c libffi.call/cls_3byte1.c \
+libffi.call/struct6.c libffi.call/return_uc.c libffi.call/return_ll1.c \
+libffi.call/cls_ushort.c libffi.call/stret_medium2.c \
+libffi.call/cls_multi_ushortchar.c libffi.call/return_dbl2.c \
+libffi.call/closure_loc_fn0.c libffi.call/return_sc.c \
+libffi.call/nested_struct8.c libffi.call/cls_7_1_byte.c	\
+libffi.call/return_ll.c libffi.call/cls_pointer.c \
+libffi.call/err_bad_abi.c libffi.call/return_dbl1.c \
+libffi.call/call.exp libffi.call/ffitest.h libffi.call/strlen.c	\
+libffi.call/return_sl.c libffi.call/cls_1_1byte.c \
+libffi.call/struct1.c libffi.call/cls_64byte.c libffi.call/return_ul.c \
+libffi.call/cls_double.c libffi.call/many_win32.c \
+libffi.call/cls_16byte.c libffi.call/cls_align_double.c	\
+libffi.call/cls_align_uint16.c libffi.call/cls_9byte1.c	\
+libffi.call/cls_multi_sshortchar.c libffi.call/cls_multi_ushort.c \
+libffi.call/closure_stdcall.c libffi.call/return_fl.c \
+libffi.call/strlen_win32.c libffi.call/return_ldl.c \
+libffi.call/cls_align_float.c libffi.call/struct3.c \
+libffi.call/cls_uchar.c libffi.call/cls_sint.c libffi.call/float2.c \
+libffi.call/cls_align_longdouble_split.c \
+libffi.call/cls_longdouble_va.c libffi.call/cls_multi_sshort.c \
+libffi.call/stret_large.c libffi.call/cls_align_sint16.c \
+libffi.call/nested_struct6.c libffi.call/cls_5byte.c \
+libffi.call/return_dbl.c libffi.call/cls_20byte.c \
+libffi.call/cls_8byte.c libffi.call/pyobjc-tc.c	\
+libffi.call/cls_24byte.c libffi.call/cls_align_longdouble_split2.c \
+libffi.call/cls_6_1_byte.c libffi.call/cls_schar.c \
+libffi.call/cls_18byte.c libffi.call/closure_fn3.c \
+libffi.call/err_bad_typedef.c libffi.call/closure_fn2.c	\
+libffi.call/struct2.c libffi.call/cls_3byte2.c \
+libffi.call/cls_align_longdouble.c libffi.call/cls_20byte1.c \
+libffi.call/return_fl3.c libffi.call/cls_align_uint32.c	\
+libffi.call/problem1.c libffi.call/float4.c \
+libffi.call/cls_align_uint64.c libffi.call/struct9.c \
+libffi.call/closure_fn5.c libffi.call/cls_align_sint32.c \
+libffi.call/closure_fn0.c libffi.call/closure_fn6.c \
+libffi.call/struct4.c libffi.call/nested_struct2.c \
+libffi.call/cls_6byte.c libffi.call/cls_7byte.c libffi.call/many.c \
+libffi.call/struct8.c libffi.call/negint.c libffi.call/struct5.c \
+libffi.call/cls_12byte.c libffi.call/cls_double_va.c \
+libffi.call/cls_longdouble.c libffi.call/cls_9byte2.c \
+libffi.call/nested_struct10.c libffi.call/nested_struct5.c \
+libffi.call/huge_struct.c
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign testsuite/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+check-DEJAGNU: site.exp
+	srcdir=`$(am__cd) $(srcdir) && pwd`; export srcdir; \
+	EXPECT=$(EXPECT); export EXPECT; \
+	runtest=$(RUNTEST); \
+	if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+	  exit_status=0; l='$(DEJATOOL)'; for tool in $$l; do \
+	    if $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \
+	    then :; else exit_status=1; fi; \
+	  done; \
+	else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+	fi; \
+	exit $$exit_status
+site.exp: Makefile
+	@echo 'Making a new site.exp file...'
+	@echo '## these variables are automatically generated by make ##' >site.tmp
+	@echo '# Do not edit here.  If you wish to override these values' >>site.tmp
+	@echo '# edit the last section' >>site.tmp
+	@echo 'set srcdir $(srcdir)' >>site.tmp
+	@echo "set objdir `pwd`" >>site.tmp
+	@echo 'set build_alias "$(build_alias)"' >>site.tmp
+	@echo 'set build_triplet $(build_triplet)' >>site.tmp
+	@echo 'set host_alias "$(host_alias)"' >>site.tmp
+	@echo 'set host_triplet $(host_triplet)' >>site.tmp
+	@echo 'set target_alias "$(target_alias)"' >>site.tmp
+	@echo 'set target_triplet $(target_triplet)' >>site.tmp
+	@echo '## All variables above are generated by configure. Do Not Edit ##' >>site.tmp
+	@test ! -f site.exp || \
+	  sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp
+	@-rm -f site.bak
+	@test ! -f site.exp || mv site.exp site.bak
+	@mv site.tmp site.exp
+
+distclean-DEJAGNU:
+	-rm -f site.exp site.bak
+	-l='$(DEJATOOL)'; for tool in $$l; do \
+	  rm -f $$tool.sum $$tool.log; \
+	done
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-DEJAGNU distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: all all-am check check-DEJAGNU check-am clean clean-generic \
+	clean-libtool distclean distclean-DEJAGNU distclean-generic \
+	distclean-libtool distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/config/default.exp b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/config/default.exp
new file mode 100755
index 0000000..90967cc
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/config/default.exp
@@ -0,0 +1 @@
+load_lib "standard.exp"
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp
new file mode 100755
index 0000000..304d2f5
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp
@@ -0,0 +1,300 @@
+#   Copyright (C) 2003, 2005, 2008, 2009 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+proc load_gcc_lib { filename } {
+    global srcdir
+    load_file $srcdir/lib/$filename
+}
+
+load_lib dg.exp
+load_lib libgloss.exp
+load_gcc_lib target-libpath.exp
+load_gcc_lib wrapper.exp
+
+
+# Define libffi callbacks for dg.exp.
+
+proc libffi-dg-test-1 { target_compile prog do_what extra_tool_flags } {
+
+    # To get all \n in dg-output test strings to match printf output
+    # in a system that outputs it as \015\012 (i.e. not just \012), we
+    # need to change all \n into \r?\n.  As there is no dejagnu flag
+    # or hook to do that, we simply change the text being tested.
+    # Unfortunately, we have to know that the variable is called
+    # dg-output-text and lives in the caller of libffi-dg-test, which
+    # is two calls up.  Overriding proc dg-output would be longer and
+    # would necessarily have the same assumption.
+    upvar 2 dg-output-text output_match
+
+    if { [llength $output_match] > 1 } {
+	regsub -all "\n" [lindex $output_match 1] "\r?\n" x
+	set output_match [lreplace $output_match 1 1 $x]
+    }
+
+    # Set up the compiler flags, based on what we're going to do.
+
+    set options [list]
+    switch $do_what {
+	"compile" {
+	    set compile_type "assembly"
+	    set output_file "[file rootname [file tail $prog]].s"
+	}
+	"link" {
+	    set compile_type "executable"
+	    set output_file "[file rootname [file tail $prog]].exe"
+	    # The following line is needed for targets like the i960 where
+	    # the default output file is b.out.  Sigh.
+	}
+	"run" {
+	    set compile_type "executable"
+	    # FIXME: "./" is to cope with "." not being in $PATH.
+	    # Should this be handled elsewhere?
+	    # YES.
+	    set output_file "./[file rootname [file tail $prog]].exe"
+	    # This is the only place where we care if an executable was
+	    # created or not.  If it was, dg.exp will try to run it.
+	    remote_file build delete $output_file;
+	}
+	default {
+	    perror "$do_what: not a valid dg-do keyword"
+	    return ""
+	}
+    }
+
+    if { $extra_tool_flags != "" } {
+	lappend options "additional_flags=$extra_tool_flags"
+    }
+
+    set comp_output [libffi_target_compile "$prog" "$output_file" "$compile_type" $options];
+
+
+    return [list $comp_output $output_file]
+}
+
+
+proc libffi-dg-test { prog do_what extra_tool_flags } {
+    return [libffi-dg-test-1 target_compile $prog $do_what $extra_tool_flags]
+}
+
+proc libffi-init { args } {
+    global gluefile wrap_flags;
+    global srcdir
+    global blddirffi
+    global objdir
+    global TOOL_OPTIONS
+    global tool
+    global libffi_include
+    global libffi_link_flags
+    global tool_root_dir
+    global ld_library_path
+
+    set blddirffi [pwd]/..
+    verbose "libffi $blddirffi"
+
+    set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
+    if {$gccdir != ""} {
+	set gccdir [file dirname $gccdir]
+    }
+    verbose "gccdir $gccdir"
+
+    set ld_library_path "."
+    append ld_library_path ":${gccdir}"
+
+    set compiler "${gccdir}/xgcc"
+    if { [is_remote host] == 0 && [which $compiler] != 0 } {
+	foreach i "[exec $compiler --print-multi-lib]" {
+	    set mldir ""
+	    regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
+	    set mldir [string trimright $mldir "\;@"]
+	    if { "$mldir" == "." } {
+		continue
+	    }
+	    if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } {
+		append ld_library_path ":${gccdir}/${mldir}"
+	    }
+	}
+    }
+    # add the library path for libffi.
+    append ld_library_path ":${blddirffi}/.libs"
+
+    verbose "ld_library_path: $ld_library_path"
+
+    # Point to the Libffi headers in libffi.
+    set libffi_include "${blddirffi}/include"
+    verbose "libffi_include $libffi_include"
+
+    set libffi_dir  "${blddirffi}/.libs"
+    verbose "libffi_dir $libffi_dir"
+    if { $libffi_dir != "" } {
+	set libffi_dir [file dirname ${libffi_dir}]
+	set libffi_link_flags "-L${libffi_dir}/.libs"
+    }
+
+    set_ld_library_path_env_vars
+    libffi_maybe_build_wrapper "${objdir}/testglue.o"
+}
+
+proc libffi_exit { } {
+    global gluefile;
+
+    if [info exists gluefile] {
+	file_on_build delete $gluefile;
+	unset gluefile;
+    }
+}
+
+proc libffi_target_compile { source dest type options } {
+    global gluefile wrap_flags;
+    global srcdir
+    global blddirffi
+    global TOOL_OPTIONS
+    global libffi_link_flags
+    global libffi_include
+    global target_triplet
+
+
+    if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } {
+	lappend options "libs=${gluefile}"
+	lappend options "ldflags=$wrap_flags"
+    }
+
+    # TOOL_OPTIONS must come first, so that it doesn't override testcase
+    # specific options.
+    if [info exists TOOL_OPTIONS] {
+	lappend  options [concat "additional_flags=$TOOL_OPTIONS" $options];
+    }
+
+    # search for ffi_mips.h in srcdir, too
+    lappend options "additional_flags=-I${libffi_include} -I${srcdir}/../include  -I${libffi_include}/.."
+    lappend options "additional_flags=${libffi_link_flags}"
+
+    # Darwin needs a stack execution allowed flag.
+
+    if { [istarget "*-*-darwin9*"] || [istarget "*-*-darwin1*"]
+	 || [istarget "*-*-darwin2*"] } {
+	lappend options "additional_flags=-Wl,-allow_stack_execute"
+    }
+
+    # If you're building the compiler with --prefix set to a place
+    # where it's not yet installed, then the linker won't be able to
+    # find the libgcc used by libffi.dylib.  We could pass the
+    # -dylib_file option, but that's complicated, and it's much easier
+    # to just make the linker find libgcc using -L options.
+    if { [string match "*-*-darwin*" $target_triplet] } {
+	lappend options "libs= -shared-libgcc"
+    }
+
+    if { [string match "*-*-openbsd*" $target_triplet] } {
+	lappend options "libs= -lpthread"
+    }
+
+    lappend options "libs= -lffi"
+
+    verbose "options: $options"
+    return [target_compile $source $dest $type $options]
+}
+
+# Utility routines.
+
+#
+# search_for -- looks for a string match in a file
+#
+proc search_for { file pattern } {
+    set fd [open $file r]
+    while { [gets $fd cur_line]>=0 } {
+	if [string match "*$pattern*" $cur_line] then {
+	    close $fd
+	    return 1
+	}
+    }
+    close $fd
+    return 0
+}
+
+# Modified dg-runtest that can cycle through a list of optimization options
+# as c-torture does.
+proc libffi-dg-runtest { testcases default-extra-flags } {
+    global runtests
+
+    foreach test $testcases {
+	# If we're only testing specific files and this isn't one of
+	# them, skip it.
+	if ![runtest_file_p $runtests $test] {
+	    continue
+	}
+
+	# Look for a loop within the source code - if we don't find one,
+	# don't pass -funroll[-all]-loops.
+	global torture_with_loops torture_without_loops
+	if [expr [search_for $test "for*("]+[search_for $test "while*("]] {
+	    set option_list $torture_with_loops
+	} else {
+	    set option_list $torture_without_loops
+	}
+
+	set nshort [file tail [file dirname $test]]/[file tail $test]
+
+	foreach flags $option_list {
+	    verbose "Testing $nshort, $flags" 1
+	    dg-test $test $flags ${default-extra-flags}
+	}
+    }
+}
+
+
+# Like check_conditional_xfail, but callable from a dg test.
+
+proc dg-xfail-if { args } {
+    set args [lreplace $args 0 0]
+    set selector "target [join [lindex $args 1]]"
+    if { [dg-process-target $selector] == "S" } {
+	global compiler_conditional_xfail_data
+	set compiler_conditional_xfail_data $args
+    }
+}
+
+
+# We need to make sure that additional_files and additional_sources
+# are both cleared out after every test.  It is not enough to clear
+# them out *before* the next test run because gcc-target-compile gets
+# run directly from some .exp files (outside of any test).  (Those
+# uses should eventually be eliminated.)
+
+# Because the DG framework doesn't provide a hook that is run at the
+# end of a test, we must replace dg-test with a wrapper.
+
+if { [info procs saved-dg-test] == [list] } {
+    rename dg-test saved-dg-test
+
+    proc dg-test { args } {
+	global additional_files
+	global additional_sources
+	global errorInfo
+
+	if { [ catch { eval saved-dg-test $args } errmsg ] } {
+	    set saved_info $errorInfo
+	    set additional_files ""
+	    set additional_sources ""
+	    error $errmsg $saved_info
+	}
+	set additional_files ""
+	set additional_sources ""
+    }
+}
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/lib/libffi.exp b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/lib/libffi.exp
new file mode 100755
index 0000000..4a65ed1
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/lib/libffi.exp
@@ -0,0 +1,350 @@
+#   Copyright (C) 2003, 2005, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+proc load_gcc_lib { filename } {
+    global srcdir
+    load_file $srcdir/lib/$filename
+}
+
+load_lib dg.exp
+load_lib libgloss.exp
+load_gcc_lib target-libpath.exp
+load_gcc_lib wrapper.exp
+
+
+# Define libffi callbacks for dg.exp.
+
+proc libffi-dg-test-1 { target_compile prog do_what extra_tool_flags } {
+
+    # To get all \n in dg-output test strings to match printf output
+    # in a system that outputs it as \015\012 (i.e. not just \012), we
+    # need to change all \n into \r?\n.  As there is no dejagnu flag
+    # or hook to do that, we simply change the text being tested.
+    # Unfortunately, we have to know that the variable is called
+    # dg-output-text and lives in the caller of libffi-dg-test, which
+    # is two calls up.  Overriding proc dg-output would be longer and
+    # would necessarily have the same assumption.
+    upvar 2 dg-output-text output_match
+
+    if { [llength $output_match] > 1 } {
+	regsub -all "\n" [lindex $output_match 1] "\r?\n" x
+	set output_match [lreplace $output_match 1 1 $x]
+    }
+
+    # Set up the compiler flags, based on what we're going to do.
+
+    set options [list]
+    switch $do_what {
+	"compile" {
+	    set compile_type "assembly"
+	    set output_file "[file rootname [file tail $prog]].s"
+	}
+	"link" {
+	    set compile_type "executable"
+	    set output_file "[file rootname [file tail $prog]].exe"
+	    # The following line is needed for targets like the i960 where
+	    # the default output file is b.out.  Sigh.
+	}
+	"run" {
+	    set compile_type "executable"
+	    # FIXME: "./" is to cope with "." not being in $PATH.
+	    # Should this be handled elsewhere?
+	    # YES.
+	    set output_file "./[file rootname [file tail $prog]].exe"
+	    # This is the only place where we care if an executable was
+	    # created or not.  If it was, dg.exp will try to run it.
+	    remote_file build delete $output_file;
+	}
+	default {
+	    perror "$do_what: not a valid dg-do keyword"
+	    return ""
+	}
+    }
+
+    if { $extra_tool_flags != "" } {
+	lappend options "additional_flags=$extra_tool_flags"
+    }
+
+    set comp_output [libffi_target_compile "$prog" "$output_file" "$compile_type" $options];
+
+
+    return [list $comp_output $output_file]
+}
+
+
+proc libffi-dg-test { prog do_what extra_tool_flags } {
+    return [libffi-dg-test-1 target_compile $prog $do_what $extra_tool_flags]
+}
+
+proc libffi-init { args } {
+    global gluefile wrap_flags;
+    global srcdir
+    global blddirffi
+    global objdir
+    global TOOL_OPTIONS
+    global tool
+    global libffi_include
+    global libffi_link_flags
+    global tool_root_dir
+    global ld_library_path
+
+    set blddirffi [pwd]/.. 
+    verbose "libffi $blddirffi"
+
+    set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
+    if {$gccdir != ""} {
+	set gccdir [file dirname $gccdir]
+    }
+    verbose "gccdir $gccdir"
+
+    set ld_library_path "."
+    append ld_library_path ":${gccdir}"
+
+    set compiler "${gccdir}/xgcc"
+    if { [is_remote host] == 0 && [which $compiler] != 0 } {
+	foreach i "[exec $compiler --print-multi-lib]" {
+	    set mldir ""
+	    regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
+	    set mldir [string trimright $mldir "\;@"]
+	    if { "$mldir" == "." } {
+		continue
+	    }
+	    if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } {
+		append ld_library_path ":${gccdir}/${mldir}"
+	    }
+	}
+    }
+    # add the library path for libffi.
+    append ld_library_path ":${blddirffi}/.libs"
+
+    verbose "ld_library_path: $ld_library_path"
+
+    # Point to the Libffi headers in libffi.
+    set libffi_include "${blddirffi}/include"
+    verbose "libffi_include $libffi_include"
+
+    set libffi_dir  "${blddirffi}/.libs"
+    verbose "libffi_dir $libffi_dir"
+    if { $libffi_dir != "" } {
+	set libffi_dir [file dirname ${libffi_dir}]
+	set libffi_link_flags "-L${libffi_dir}/.libs"
+    }
+
+    set_ld_library_path_env_vars
+    libffi_maybe_build_wrapper "${objdir}/testglue.o"
+}
+
+proc libffi_exit { } {
+    global gluefile;
+
+    if [info exists gluefile] {
+	file_on_build delete $gluefile;
+	unset gluefile;
+    }
+}
+
+proc libffi_target_compile { source dest type options } {
+    global gluefile wrap_flags;
+    global srcdir
+    global blddirffi
+    global TOOL_OPTIONS
+    global libffi_link_flags
+    global libffi_include
+    global target_triplet
+
+
+    if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } {
+	lappend options "libs=${gluefile}"
+	lappend options "ldflags=$wrap_flags"
+    }
+
+    # TOOL_OPTIONS must come first, so that it doesn't override testcase
+    # specific options.
+    if [info exists TOOL_OPTIONS] {
+	lappend  options [concat "additional_flags=$TOOL_OPTIONS" $options];
+    }
+
+    # search for ffi_mips.h in srcdir, too
+    lappend options "additional_flags=-I${libffi_include} -I${srcdir}/../include  -I${libffi_include}/.."
+    lappend options "additional_flags=${libffi_link_flags}"
+
+    # Darwin needs a stack execution allowed flag.
+
+    if { [istarget "*-*-darwin9*"] || [istarget "*-*-darwin1*"]
+	 || [istarget "*-*-darwin2*"] } {
+	lappend options "additional_flags=-Wl,-allow_stack_execute"
+    }
+
+    # If you're building the compiler with --prefix set to a place
+    # where it's not yet installed, then the linker won't be able to
+    # find the libgcc used by libffi.dylib.  We could pass the
+    # -dylib_file option, but that's complicated, and it's much easier
+    # to just make the linker find libgcc using -L options.
+    if { [string match "*-*-darwin*" $target_triplet] } {
+	lappend options "libs= -shared-libgcc"
+    }
+
+    if { [string match "*-*-openbsd*" $target_triplet] } {
+	lappend options "libs= -lpthread"
+    }
+
+    lappend options "libs= -lffi"
+
+    verbose "options: $options"
+    return [target_compile $source $dest $type $options]
+}
+
+# Utility routines.
+
+#
+# search_for -- looks for a string match in a file
+#
+proc search_for { file pattern } {
+    set fd [open $file r]
+    while { [gets $fd cur_line]>=0 } {
+	if [string match "*$pattern*" $cur_line] then {
+	    close $fd
+	    return 1
+	}
+    }
+    close $fd
+    return 0
+}
+
+# Modified dg-runtest that can cycle through a list of optimization options
+# as c-torture does.
+proc libffi-dg-runtest { testcases default-extra-flags } {
+    global runtests
+
+    foreach test $testcases {
+	# If we're only testing specific files and this isn't one of
+	# them, skip it.
+	if ![runtest_file_p $runtests $test] {
+	    continue
+	}
+
+	# Look for a loop within the source code - if we don't find one,
+	# don't pass -funroll[-all]-loops.
+	global torture_with_loops torture_without_loops
+	if [expr [search_for $test "for*("]+[search_for $test "while*("]] {
+	    set option_list $torture_with_loops
+	} else {
+	    set option_list $torture_without_loops
+	}
+
+	set nshort [file tail [file dirname $test]]/[file tail $test]
+
+	foreach flags $option_list {
+	    verbose "Testing $nshort, $flags" 1
+	    dg-test $test $flags ${default-extra-flags}
+	}
+    }
+}
+
+
+# Like check_conditional_xfail, but callable from a dg test.
+
+proc dg-xfail-if { args } {
+    set args [lreplace $args 0 0]
+    set selector "target [join [lindex $args 1]]"
+    if { [dg-process-target $selector] == "S" } {
+	global compiler_conditional_xfail_data
+	set compiler_conditional_xfail_data $args
+    }
+}
+
+proc check-flags { args } {
+
+    # The args are within another list; pull them out.
+    set args [lindex $args 0]
+
+    # The next two arguments are optional.  If they were not specified,
+    # use the defaults.
+    if { [llength $args] == 2 } {
+	lappend $args [list "*"]
+    }
+    if { [llength $args] == 3 } {
+	lappend $args [list ""]
+    }
+
+    # If the option strings are the defaults, or the same as the
+    # defaults, there is no need to call check_conditional_xfail to
+    # compare them to the actual options.
+    if { [string compare [lindex $args 2] "*"] == 0
+	 && [string compare [lindex $args 3] "" ] == 0 } {
+	set result 1    
+    } else {
+	# The target list might be an effective-target keyword, so replace
+	# the original list with "*-*-*", since we already know it matches.
+	set result [check_conditional_xfail [lreplace $args 1 1 "*-*-*"]]
+    }
+
+    return $result
+}
+
+proc dg-skip-if { args } {
+    # Verify the number of arguments.  The last two are optional.
+    set args [lreplace $args 0 0]
+    if { [llength $args] < 2 || [llength $args] > 4 } {
+        error "dg-skip-if 2: need 2, 3, or 4 arguments"
+    }
+
+    # Don't bother if we're already skipping the test.
+    upvar dg-do-what dg-do-what
+    if { [lindex ${dg-do-what} 1] == "N" } {
+      return
+    }
+
+    set selector [list target [lindex $args 1]]
+    if { [dg-process-target $selector] == "S" } {
+        if [check-flags $args] {
+            upvar dg-do-what dg-do-what
+            set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
+        }
+    }
+}
+
+# We need to make sure that additional_files and additional_sources
+# are both cleared out after every test.  It is not enough to clear
+# them out *before* the next test run because gcc-target-compile gets
+# run directly from some .exp files (outside of any test).  (Those
+# uses should eventually be eliminated.)
+
+# Because the DG framework doesn't provide a hook that is run at the
+# end of a test, we must replace dg-test with a wrapper.
+
+if { [info procs saved-dg-test] == [list] } {
+    rename dg-test saved-dg-test
+
+    proc dg-test { args } {
+	global additional_files
+	global additional_sources
+	global errorInfo
+
+	if { [ catch { eval saved-dg-test $args } errmsg ] } {
+	    set saved_info $errorInfo
+	    set additional_files ""
+	    set additional_sources ""
+	    error $errmsg $saved_info
+	}
+	set additional_files ""
+	set additional_sources ""
+    }
+}
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp
new file mode 100755
index 0000000..8999aa4
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp
@@ -0,0 +1,263 @@
+# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# This file was contributed by John David Anglin (dave.anglin at nrc-cnrc.gc.ca)
+
+set orig_environment_saved 0
+set orig_ld_library_path_saved 0
+set orig_ld_run_path_saved 0
+set orig_shlib_path_saved 0
+set orig_ld_libraryn32_path_saved 0
+set orig_ld_library64_path_saved 0
+set orig_ld_library_path_32_saved 0
+set orig_ld_library_path_64_saved 0
+set orig_dyld_library_path_saved 0
+
+
+#######################################
+# proc set_ld_library_path_env_vars { }
+#######################################
+
+proc set_ld_library_path_env_vars { } {
+  global ld_library_path
+  global orig_environment_saved
+  global orig_ld_library_path_saved
+  global orig_ld_run_path_saved
+  global orig_shlib_path_saved
+  global orig_ld_libraryn32_path_saved
+  global orig_ld_library64_path_saved
+  global orig_ld_library_path_32_saved
+  global orig_ld_library_path_64_saved
+  global orig_dyld_library_path_saved
+  global orig_ld_library_path
+  global orig_ld_run_path
+  global orig_shlib_path
+  global orig_ld_libraryn32_path
+  global orig_ld_library64_path
+  global orig_ld_library_path_32
+  global orig_ld_library_path_64
+  global orig_dyld_library_path
+  global GCC_EXEC_PREFIX
+
+  # Set the relocated compiler prefix, but only if the user hasn't specified one.
+  if { [info exists GCC_EXEC_PREFIX] && ![info exists env(GCC_EXEC_PREFIX)] } {
+    setenv GCC_EXEC_PREFIX "$GCC_EXEC_PREFIX"
+  }
+
+  # Setting the ld library path causes trouble when testing cross-compilers.
+  if { [is_remote target] } {
+    return
+  }
+
+  if { $orig_environment_saved == 0 } {
+    global env
+
+    set orig_environment_saved 1
+
+    # Save the original environment.
+    if [info exists env(LD_LIBRARY_PATH)] {
+      set orig_ld_library_path "$env(LD_LIBRARY_PATH)"
+      set orig_ld_library_path_saved 1
+    }
+    if [info exists env(LD_RUN_PATH)] {
+      set orig_ld_run_path "$env(LD_RUN_PATH)"
+      set orig_ld_run_path_saved 1
+    }
+    if [info exists env(SHLIB_PATH)] {
+      set orig_shlib_path "$env(SHLIB_PATH)"
+      set orig_shlib_path_saved 1
+    }
+    if [info exists env(LD_LIBRARYN32_PATH)] {
+      set orig_ld_libraryn32_path "$env(LD_LIBRARYN32_PATH)"
+      set orig_ld_libraryn32_path_saved 1
+    }
+    if [info exists env(LD_LIBRARY64_PATH)] {
+      set orig_ld_library64_path "$env(LD_LIBRARY64_PATH)"
+      set orig_ld_library64_path_saved 1
+    }
+    if [info exists env(LD_LIBRARY_PATH_32)] {
+      set orig_ld_library_path_32 "$env(LD_LIBRARY_PATH_32)"
+      set orig_ld_library_path_32_saved 1
+    }
+    if [info exists env(LD_LIBRARY_PATH_64)] {
+      set orig_ld_library_path_64 "$env(LD_LIBRARY_PATH_64)"
+      set orig_ld_library_path_64_saved 1
+    }
+    if [info exists env(DYLD_LIBRARY_PATH)] {
+      set orig_dyld_library_path "$env(DYLD_LIBRARY_PATH)"
+      set orig_dyld_library_path_saved 1
+    }
+  }
+
+  # We need to set ld library path in the environment.  Currently,
+  # unix.exp doesn't set the environment correctly for all systems.
+  # It only sets SHLIB_PATH and LD_LIBRARY_PATH when it executes a
+  # program.  We also need the environment set for compilations, etc.
+  #
+  # On IRIX 6, we have to set variables akin to LD_LIBRARY_PATH, but
+  # called LD_LIBRARYN32_PATH (for the N32 ABI) and LD_LIBRARY64_PATH
+  # (for the 64-bit ABI).  The same applies to Darwin (DYLD_LIBRARY_PATH),
+  # Solaris 32 bit (LD_LIBRARY_PATH_32), Solaris 64 bit (LD_LIBRARY_PATH_64),
+  # and HP-UX (SHLIB_PATH).  In some cases, the variables are independent
+  # of LD_LIBRARY_PATH, and in other cases LD_LIBRARY_PATH is used if the
+  # variable is not defined.
+  #
+  # Doing this is somewhat of a hack as ld_library_path gets repeated in
+  # SHLIB_PATH and LD_LIBRARY_PATH when unix_load sets these variables.
+  if { $orig_ld_library_path_saved } {
+    setenv LD_LIBRARY_PATH "$ld_library_path:$orig_ld_library_path"
+  } else {
+    setenv LD_LIBRARY_PATH "$ld_library_path"
+  }
+  if { $orig_ld_run_path_saved } {
+    setenv LD_RUN_PATH "$ld_library_path:$orig_ld_run_path"
+  } else {
+    setenv LD_RUN_PATH "$ld_library_path"
+  }
+  # The default shared library dynamic path search for 64-bit
+  # HP-UX executables searches LD_LIBRARY_PATH before SHLIB_PATH.
+  # LD_LIBRARY_PATH isn't used for 32-bit executables.  Thus, we
+  # set LD_LIBRARY_PATH and SHLIB_PATH as if they were independent.
+  if { $orig_shlib_path_saved } {
+    setenv SHLIB_PATH "$ld_library_path:$orig_shlib_path"
+  } else {
+    setenv SHLIB_PATH "$ld_library_path"
+  }
+  if { $orig_ld_libraryn32_path_saved } {
+    setenv LD_LIBRARYN32_PATH "$ld_library_path:$orig_ld_libraryn32_path"
+  } elseif { $orig_ld_library_path_saved } {
+    setenv LD_LIBRARYN32_PATH "$ld_library_path:$orig_ld_library_path"
+  } else {
+    setenv LD_LIBRARYN32_PATH "$ld_library_path"
+  }
+  if { $orig_ld_library64_path_saved } {
+    setenv LD_LIBRARY64_PATH "$ld_library_path:$orig_ld_library64_path"
+  } elseif { $orig_ld_library_path_saved } {
+    setenv LD_LIBRARY64_PATH "$ld_library_path:$orig_ld_library_path"
+  } else {
+    setenv LD_LIBRARY64_PATH "$ld_library_path"
+  }
+  if { $orig_ld_library_path_32_saved } {
+    setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path_32"
+  } elseif { $orig_ld_library_path_saved } {
+    setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path"
+  } else {
+    setenv LD_LIBRARY_PATH_32 "$ld_library_path"
+  }
+  if { $orig_ld_library_path_64_saved } {
+    setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path_64"
+  } elseif { $orig_ld_library_path_saved } {
+    setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path"
+  } else {
+    setenv LD_LIBRARY_PATH_64 "$ld_library_path"
+  }
+  if { $orig_dyld_library_path_saved } {
+    setenv DYLD_LIBRARY_PATH "$ld_library_path:$orig_dyld_library_path"
+  } else {
+    setenv DYLD_LIBRARY_PATH "$ld_library_path"
+  }
+
+  verbose -log "set_ld_library_path_env_vars: ld_library_path=$ld_library_path"
+}
+
+#######################################
+# proc restore_ld_library_path_env_vars { }
+#######################################
+
+proc restore_ld_library_path_env_vars { } {
+  global orig_environment_saved
+  global orig_ld_library_path_saved
+  global orig_ld_run_path_saved
+  global orig_shlib_path_saved
+  global orig_ld_libraryn32_path_saved
+  global orig_ld_library64_path_saved
+  global orig_ld_library_path_32_saved
+  global orig_ld_library_path_64_saved
+  global orig_dyld_library_path_saved
+  global orig_ld_library_path
+  global orig_ld_run_path
+  global orig_shlib_path
+  global orig_ld_libraryn32_path
+  global orig_ld_library64_path
+  global orig_ld_library_path_32
+  global orig_ld_library_path_64
+  global orig_dyld_library_path
+
+  if { $orig_environment_saved == 0 } {
+    return
+  }
+
+  if { $orig_ld_library_path_saved } {
+    setenv LD_LIBRARY_PATH "$orig_ld_library_path"
+  } elseif [info exists env(LD_LIBRARY_PATH)] {
+    unsetenv LD_LIBRARY_PATH
+  }
+  if { $orig_ld_run_path_saved } {
+    setenv LD_RUN_PATH "$orig_ld_run_path"
+  } elseif [info exists env(LD_RUN_PATH)] {
+    unsetenv LD_RUN_PATH
+  }
+  if { $orig_shlib_path_saved } {
+    setenv SHLIB_PATH "$orig_shlib_path"
+  } elseif [info exists env(SHLIB_PATH)] {
+    unsetenv SHLIB_PATH
+  }
+  if { $orig_ld_libraryn32_path_saved } {
+    setenv LD_LIBRARYN32_PATH "$orig_ld_libraryn32_path"
+  } elseif [info exists env(LD_LIBRARYN32_PATH)] {
+    unsetenv LD_LIBRARYN32_PATH
+  }
+  if { $orig_ld_library64_path_saved } {
+    setenv LD_LIBRARY64_PATH "$orig_ld_library64_path"
+  } elseif [info exists env(LD_LIBRARY64_PATH)] {
+    unsetenv LD_LIBRARY64_PATH
+  }
+  if { $orig_ld_library_path_32_saved } {
+    setenv LD_LIBRARY_PATH_32 "$orig_ld_library_path_32"
+  } elseif [info exists env(LD_LIBRARY_PATH_32)] {
+    unsetenv LD_LIBRARY_PATH_32
+  }
+  if { $orig_ld_library_path_64_saved } {
+    setenv LD_LIBRARY_PATH_64 "$orig_ld_library_path_64"
+  } elseif [info exists env(LD_LIBRARY_PATH_64)] {
+    unsetenv LD_LIBRARY_PATH_64
+  }
+  if { $orig_dyld_library_path_saved } {
+    setenv DYLD_LIBRARY_PATH "$orig_dyld_library_path"
+  } elseif [info exists env(DYLD_LIBRARY_PATH)] {
+    unsetenv DYLD_LIBRARY_PATH
+  }
+}
+
+#######################################
+# proc get_shlib_extension { }
+#######################################
+
+proc get_shlib_extension { } {
+    global shlib_ext
+
+    if { [ istarget *-*-darwin* ] } {
+	set shlib_ext "dylib"
+    } elseif { [ istarget *-*-cygwin* ] || [ istarget *-*-mingw* ] } {
+	set shlib_ext "dll"
+    } elseif { [ istarget hppa*-*-hpux* ] } {
+	set shlib_ext "sl"
+    } else {
+	set shlib_ext "so"
+    }
+    return $shlib_ext
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/lib/wrapper.exp b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/lib/wrapper.exp
new file mode 100755
index 0000000..4e5ae43
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/lib/wrapper.exp
@@ -0,0 +1,45 @@
+#   Copyright (C) 2004, 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# This file contains GCC-specifics for status wrappers for test programs.
+
+# ${tool}_maybe_build_wrapper -- Build wrapper object if the target
+# needs it.  FILENAME is the path to the wrapper file.  If there are
+# additional arguments, they are command-line options to provide to
+# the compiler when compiling FILENAME.
+
+proc ${tool}_maybe_build_wrapper { filename args } {
+    global gluefile wrap_flags
+
+    if { [target_info needs_status_wrapper] != "" \
+ 	 && [target_info needs_status_wrapper] != "0" \
+	 && ![info exists gluefile] } {
+	set saved_wrap_compile_flags [target_info wrap_compile_flags]
+	set flags [join $args " "]
+	# The wrapper code may contain code that gcc objects on.  This
+	# became true for dejagnu-1.4.4.  The set of warnings and code
+	# that gcc objects on may change, so just make sure -w is always
+	# passed to turn off all warnings.
+	set_currtarget_info wrap_compile_flags \
+	    "$saved_wrap_compile_flags -w $flags"
+	set result [build_wrapper $filename]
+	set_currtarget_info wrap_compile_flags "$saved_wrap_compile_flags"
+	if { $result != "" } {
+	    set gluefile [lindex $result 0]
+	    set wrap_flags [lindex $result 1]
+	}
+    }
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/call.exp b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/call.exp
new file mode 100755
index 0000000..26acd81
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/call.exp
@@ -0,0 +1,32 @@
+# Copyright (C) 2003, 2006, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+dg-init
+libffi-init
+
+global srcdir subdir
+
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O0 -W -Wall" ""
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O2" ""
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O3" ""
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-Os" ""
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O2 -fomit-frame-pointer" ""
+
+dg-finish
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn0.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn0.c
new file mode 100755
index 0000000..a579ff6
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn0.c
@@ -0,0 +1,89 @@
+/* Area:	closure_call
+   Purpose:	Check multiple values passing from different type.
+		Also, exceed the limit of gpr and fpr registers on PowerPC
+		Darwin.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void
+closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		 void* userdata)
+{
+  *(ffi_arg*)resp =
+    (int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) +
+    (int)(*(unsigned long long *)args[2]) + (int)*(int *)args[3] +
+    (int)(*(signed short *)args[4]) +
+    (int)(*(unsigned long long *)args[5]) +
+    (int)*(int *)args[6] + (int)(*(int *)args[7]) +
+    (int)(*(double *)args[8]) + (int)*(int *)args[9] +
+    (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
+    (int)*(int *)args[12] + (int)(*(int *)args[13]) +
+    (int)(*(int *)args[14]) +  *(int *)args[15] + (intptr_t)userdata;
+
+  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+	 (int)*(unsigned long long *)args[0], (int)(*(int *)args[1]),
+	 (int)(*(unsigned long long *)args[2]),
+	 (int)*(int *)args[3], (int)(*(signed short *)args[4]),
+	 (int)(*(unsigned long long *)args[5]),
+	 (int)*(int *)args[6], (int)(*(int *)args[7]),
+	 (int)(*(double *)args[8]), (int)*(int *)args[9],
+	 (int)(*(int *)args[10]), (int)(*(float *)args[11]),
+	 (int)*(int *)args[12], (int)(*(int *)args[13]),
+	 (int)(*(int *)args[14]),*(int *)args[15],
+	 (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (*closure_test_type0)(unsigned long long, int, unsigned long long,
+				  int, signed short, unsigned long long, int,
+				  int, double, int, int, float, int, int,
+				  int, int);
+
+int main (void)
+{
+  ffi_cif cif;
+  void * code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[17];
+  int res;
+
+  cl_arg_types[0] = &ffi_type_uint64;
+  cl_arg_types[1] = &ffi_type_sint;
+  cl_arg_types[2] = &ffi_type_uint64;
+  cl_arg_types[3] = &ffi_type_sint;
+  cl_arg_types[4] = &ffi_type_sshort;
+  cl_arg_types[5] = &ffi_type_uint64;
+  cl_arg_types[6] = &ffi_type_sint;
+  cl_arg_types[7] = &ffi_type_sint;
+  cl_arg_types[8] = &ffi_type_double;
+  cl_arg_types[9] = &ffi_type_sint;
+  cl_arg_types[10] = &ffi_type_sint;
+  cl_arg_types[11] = &ffi_type_float;
+  cl_arg_types[12] = &ffi_type_sint;
+  cl_arg_types[13] = &ffi_type_sint;
+  cl_arg_types[14] = &ffi_type_sint;
+  cl_arg_types[15] = &ffi_type_sint;
+  cl_arg_types[16] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+		     &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
+                             (void *) 3 /* userdata */, code) == FFI_OK);
+
+  res = (*((closure_test_type0)code))
+    (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
+     19, 21, 1);
+  /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
+  printf("res: %d\n",res);
+  /* { dg-output "\nres: 680" } */
+     exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn1.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn1.c
new file mode 100755
index 0000000..9123173
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn1.c
@@ -0,0 +1,81 @@
+/* Area:	closure_call.
+   Purpose:	Check multiple values passing from different type.
+		Also, exceed the limit of gpr and fpr registers on PowerPC
+		Darwin.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+
+static void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
+			     void* userdata)
+{
+  *(ffi_arg*)resp =
+    (int)*(float *)args[0] +(int)(*(float *)args[1]) +
+    (int)(*(float *)args[2]) + (int)*(float *)args[3] +
+    (int)(*(signed short *)args[4]) + (int)(*(float *)args[5]) +
+    (int)*(float *)args[6] + (int)(*(int *)args[7]) +
+    (int)(*(double*)args[8]) + (int)*(int *)args[9] +
+    (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
+    (int)*(int *)args[12] + (int)(*(int *)args[13]) +
+    (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
+
+  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+	 (int)*(float *)args[0], (int)(*(float *)args[1]),
+	 (int)(*(float *)args[2]), (int)*(float *)args[3],
+	 (int)(*(signed short *)args[4]), (int)(*(float *)args[5]),
+	 (int)*(float *)args[6], (int)(*(int *)args[7]),
+	 (int)(*(double *)args[8]), (int)*(int *)args[9],
+	 (int)(*(int *)args[10]), (int)(*(float *)args[11]),
+	 (int)*(int *)args[12], (int)(*(int *)args[13]),
+	 (int)(*(int *)args[14]), *(int *)args[15],
+	 (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
+}
+
+typedef int (*closure_test_type1)(float, float, float, float, signed short,
+				  float, float, int, double, int, int, float,
+				  int, int, int, int);
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[17];
+  int res;
+
+  cl_arg_types[0] = &ffi_type_float;
+  cl_arg_types[1] = &ffi_type_float;
+  cl_arg_types[2] = &ffi_type_float;
+  cl_arg_types[3] = &ffi_type_float;
+  cl_arg_types[4] = &ffi_type_sshort;
+  cl_arg_types[5] = &ffi_type_float;
+  cl_arg_types[6] = &ffi_type_float;
+  cl_arg_types[7] = &ffi_type_sint;
+  cl_arg_types[8] = &ffi_type_double;
+  cl_arg_types[9] = &ffi_type_sint;
+  cl_arg_types[10] = &ffi_type_sint;
+  cl_arg_types[11] = &ffi_type_float;
+  cl_arg_types[12] = &ffi_type_sint;
+  cl_arg_types[13] = &ffi_type_sint;
+  cl_arg_types[14] = &ffi_type_sint;
+  cl_arg_types[15] = &ffi_type_sint;
+  cl_arg_types[16] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+		     &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn1,
+                             (void *) 3 /* userdata */, code)  == FFI_OK);
+
+  res = (*((closure_test_type1)code))
+    (1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13,
+     19, 21, 1);
+  /* { dg-output "1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
+  printf("res: %d\n",res);
+  /* { dg-output "\nres: 255" } */
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn2.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn2.c
new file mode 100755
index 0000000..08ff9d9
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn2.c
@@ -0,0 +1,81 @@
+/* Area:	closure_call
+   Purpose:	Check multiple values passing from different type.
+		Also, exceed the limit of gpr and fpr registers on PowerPC
+		Darwin.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void closure_test_fn2(ffi_cif* cif __UNUSED__, void* resp, void** args,
+			     void* userdata)
+{
+  *(ffi_arg*)resp =
+    (int)*(double *)args[0] +(int)(*(double *)args[1]) +
+    (int)(*(double *)args[2]) + (int)*(double *)args[3] +
+    (int)(*(signed short *)args[4]) + (int)(*(double *)args[5]) +
+    (int)*(double *)args[6] + (int)(*(int *)args[7]) +
+    (int)(*(double *)args[8]) + (int)*(int *)args[9] +
+    (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
+    (int)*(int *)args[12] + (int)(*(float *)args[13]) +
+    (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
+
+  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+	 (int)*(double *)args[0], (int)(*(double *)args[1]),
+	 (int)(*(double *)args[2]), (int)*(double *)args[3],
+	 (int)(*(signed short *)args[4]), (int)(*(double *)args[5]),
+	 (int)*(double *)args[6], (int)(*(int *)args[7]),
+	 (int)(*(double*)args[8]), (int)*(int *)args[9],
+	 (int)(*(int *)args[10]), (int)(*(float *)args[11]),
+	 (int)*(int *)args[12], (int)(*(float *)args[13]),
+	 (int)(*(int *)args[14]), *(int *)args[15], (int)(intptr_t)userdata,
+	 (int)*(ffi_arg *)resp);
+}
+
+typedef int (*closure_test_type2)(double, double, double, double, signed short,
+				  double, double, int, double, int, int, float,
+				  int, float, int, int);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[17];
+  int res;
+
+  cl_arg_types[0] = &ffi_type_double;
+  cl_arg_types[1] = &ffi_type_double;
+  cl_arg_types[2] = &ffi_type_double;
+  cl_arg_types[3] = &ffi_type_double;
+  cl_arg_types[4] = &ffi_type_sshort;
+  cl_arg_types[5] = &ffi_type_double;
+  cl_arg_types[6] = &ffi_type_double;
+  cl_arg_types[7] = &ffi_type_sint;
+  cl_arg_types[8] = &ffi_type_double;
+  cl_arg_types[9] = &ffi_type_sint;
+  cl_arg_types[10] = &ffi_type_sint;
+  cl_arg_types[11] = &ffi_type_float;
+  cl_arg_types[12] = &ffi_type_sint;
+  cl_arg_types[13] = &ffi_type_float;
+  cl_arg_types[14] = &ffi_type_sint;
+  cl_arg_types[15] = &ffi_type_sint;
+  cl_arg_types[16] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+		     &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn2,
+                             (void *) 3 /* userdata */, code) == FFI_OK);
+
+  res = (*((closure_test_type2)code))
+    (1, 2, 3, 4, 127, 5, 6, 8, 9, 10, 11, 12.0, 13,
+     19.0, 21, 1);
+  /* { dg-output "1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
+  printf("res: %d\n",res);
+  /* { dg-output "\nres: 255" } */
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn3.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn3.c
new file mode 100755
index 0000000..9b54d80
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn3.c
@@ -0,0 +1,82 @@
+/* Area:	closure_call
+   Purpose:	Check multiple values passing from different type.
+		Also, exceed the limit of gpr and fpr registers on PowerPC
+		Darwin.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void closure_test_fn3(ffi_cif* cif __UNUSED__, void* resp, void** args,
+			     void* userdata)
+ {
+   *(ffi_arg*)resp =
+     (int)*(float *)args[0] +(int)(*(float *)args[1]) +
+     (int)(*(float *)args[2]) + (int)*(float *)args[3] +
+     (int)(*(float *)args[4]) + (int)(*(float *)args[5]) +
+     (int)*(float *)args[6] + (int)(*(float *)args[7]) +
+     (int)(*(double *)args[8]) + (int)*(int *)args[9] +
+     (int)(*(float *)args[10]) + (int)(*(float *)args[11]) +
+     (int)*(int *)args[12] + (int)(*(float *)args[13]) +
+     (int)(*(float *)args[14]) +  *(int *)args[15] + (intptr_t)userdata;
+
+   printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+	  (int)*(float *)args[0], (int)(*(float *)args[1]),
+	  (int)(*(float *)args[2]), (int)*(float *)args[3],
+	  (int)(*(float *)args[4]), (int)(*(float *)args[5]),
+	  (int)*(float *)args[6], (int)(*(float *)args[7]),
+	  (int)(*(double *)args[8]), (int)*(int *)args[9],
+	  (int)(*(float *)args[10]), (int)(*(float *)args[11]),
+	  (int)*(int *)args[12], (int)(*(float *)args[13]),
+	  (int)(*(float *)args[14]), *(int *)args[15], (int)(intptr_t)userdata,
+	  (int)*(ffi_arg *)resp);
+
+ }
+
+typedef int (*closure_test_type3)(float, float, float, float, float, float,
+				  float, float, double, int, float, float, int,
+				  float, float, int);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[17];
+  int res;
+
+  cl_arg_types[0] = &ffi_type_float;
+  cl_arg_types[1] = &ffi_type_float;
+  cl_arg_types[2] = &ffi_type_float;
+  cl_arg_types[3] = &ffi_type_float;
+  cl_arg_types[4] = &ffi_type_float;
+  cl_arg_types[5] = &ffi_type_float;
+  cl_arg_types[6] = &ffi_type_float;
+  cl_arg_types[7] = &ffi_type_float;
+  cl_arg_types[8] = &ffi_type_double;
+  cl_arg_types[9] = &ffi_type_sint;
+  cl_arg_types[10] = &ffi_type_float;
+  cl_arg_types[11] = &ffi_type_float;
+  cl_arg_types[12] = &ffi_type_sint;
+  cl_arg_types[13] = &ffi_type_float;
+  cl_arg_types[14] = &ffi_type_float;
+  cl_arg_types[15] = &ffi_type_sint;
+  cl_arg_types[16] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+		     &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn3,
+                             (void *) 3 /* userdata */, code)  == FFI_OK);
+
+  res = (*((closure_test_type3)code))
+    (1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9, 10, 11.11, 12.0, 13,
+     19.19, 21.21, 1);
+  /* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 19 21 1 3: 135" } */
+  printf("res: %d\n",res);
+  /* { dg-output "\nres: 135" } */
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn4.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn4.c
new file mode 100755
index 0000000..d4a1530
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn4.c
@@ -0,0 +1,89 @@
+/* Area:	closure_call
+   Purpose:	Check multiple long long values passing.
+		Also, exceed the limit of gpr and fpr registers on PowerPC
+		Darwin.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20031026	 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+static void
+closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		 void* userdata)
+{
+  *(ffi_arg*)resp =
+    (int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] +
+    (int)*(unsigned long long *)args[2] + (int)*(unsigned long long *)args[3] +
+    (int)*(unsigned long long *)args[4] + (int)*(unsigned long long *)args[5] +
+    (int)*(unsigned long long *)args[6] + (int)*(unsigned long long *)args[7] +
+    (int)*(unsigned long long *)args[8] + (int)*(unsigned long long *)args[9] +
+    (int)*(unsigned long long *)args[10] +
+    (int)*(unsigned long long *)args[11] +
+    (int)*(unsigned long long *)args[12] +
+    (int)*(unsigned long long *)args[13] +
+    (int)*(unsigned long long *)args[14] +
+    *(int *)args[15] + (intptr_t)userdata;
+
+  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+	 (int)*(unsigned long long *)args[0],
+	 (int)*(unsigned long long *)args[1],
+	 (int)*(unsigned long long *)args[2],
+	 (int)*(unsigned long long *)args[3],
+	 (int)*(unsigned long long *)args[4],
+	 (int)*(unsigned long long *)args[5],
+	 (int)*(unsigned long long *)args[6],
+	 (int)*(unsigned long long *)args[7],
+	 (int)*(unsigned long long *)args[8],
+	 (int)*(unsigned long long *)args[9],
+	 (int)*(unsigned long long *)args[10],
+	 (int)*(unsigned long long *)args[11],
+	 (int)*(unsigned long long *)args[12],
+	 (int)*(unsigned long long *)args[13],
+	 (int)*(unsigned long long *)args[14],
+	 *(int *)args[15],
+	 (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (*closure_test_type0)(unsigned long long, unsigned long long,
+				  unsigned long long, unsigned long long,
+				  unsigned long long, unsigned long long,
+				  unsigned long long, unsigned long long,
+				  unsigned long long, unsigned long long,
+				  unsigned long long, unsigned long long,
+				  unsigned long long, unsigned long long,
+				  unsigned long long, int);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[17];
+  int i, res;
+
+  for (i = 0; i < 15; i++) {
+    cl_arg_types[i] = &ffi_type_uint64;
+  }
+  cl_arg_types[15] = &ffi_type_sint;
+  cl_arg_types[16] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+		     &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
+                             (void *) 3 /* userdata */, code) == FFI_OK);
+
+  res = (*((closure_test_type0)code))
+    (1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11LL, 12LL,
+     13LL, 19LL, 21LL, 1);
+  /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
+  printf("res: %d\n",res);
+  /* { dg-output "\nres: 680" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn5.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn5.c
new file mode 100755
index 0000000..9907442
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn5.c
@@ -0,0 +1,92 @@
+/* Area:	closure_call
+   Purpose:	Check multiple long long values passing.
+		Exceed the limit of gpr registers on PowerPC
+		Darwin.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20031026	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void
+closure_test_fn5(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		 void* userdata)
+{
+  *(ffi_arg*)resp =
+    (int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] +
+    (int)*(unsigned long long *)args[2] + (int)*(unsigned long long *)args[3] +
+    (int)*(unsigned long long *)args[4] + (int)*(unsigned long long *)args[5] +
+    (int)*(unsigned long long *)args[6] + (int)*(unsigned long long *)args[7] +
+    (int)*(unsigned long long *)args[8] + (int)*(unsigned long long *)args[9] +
+    (int)*(int *)args[10] +
+    (int)*(unsigned long long *)args[11] +
+    (int)*(unsigned long long *)args[12] +
+    (int)*(unsigned long long *)args[13] +
+    (int)*(unsigned long long *)args[14] +
+    *(int *)args[15] + (intptr_t)userdata;
+
+  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+	 (int)*(unsigned long long *)args[0],
+	 (int)*(unsigned long long *)args[1],
+	 (int)*(unsigned long long *)args[2],
+	 (int)*(unsigned long long *)args[3],
+	 (int)*(unsigned long long *)args[4],
+	 (int)*(unsigned long long *)args[5],
+	 (int)*(unsigned long long *)args[6],
+	 (int)*(unsigned long long *)args[7],
+	 (int)*(unsigned long long *)args[8],
+	 (int)*(unsigned long long *)args[9],
+	 (int)*(int *)args[10],
+	 (int)*(unsigned long long *)args[11],
+	 (int)*(unsigned long long *)args[12],
+	 (int)*(unsigned long long *)args[13],
+	 (int)*(unsigned long long *)args[14],
+	 *(int *)args[15],
+	 (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (*closure_test_type0)(unsigned long long, unsigned long long,
+				  unsigned long long, unsigned long long,
+				  unsigned long long, unsigned long long,
+				  unsigned long long, unsigned long long,
+				  unsigned long long, unsigned long long,
+				  int, unsigned long long,
+				  unsigned long long, unsigned long long,
+				  unsigned long long, int);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[17];
+  int i, res;
+
+  for (i = 0; i < 10; i++) {
+    cl_arg_types[i] = &ffi_type_uint64;
+  }
+  cl_arg_types[10] = &ffi_type_sint;
+  for (i = 11; i < 15; i++) {
+    cl_arg_types[i] = &ffi_type_uint64;
+  }
+  cl_arg_types[15] = &ffi_type_sint;
+  cl_arg_types[16] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+		     &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn5,
+                             (void *) 3 /* userdata */, code) == FFI_OK);
+
+  res = (*((closure_test_type0)code))
+    (1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11, 12LL,
+     13LL, 19LL, 21LL, 1);
+  /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
+  printf("res: %d\n",res);
+  /* { dg-output "\nres: 680" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn6.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn6.c
new file mode 100755
index 0000000..73c54fd
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn6.c
@@ -0,0 +1,90 @@
+/* Area:	closure_call
+   Purpose:	Check multiple values passing from different type.
+		Also, exceed the limit of gpr and fpr registers on PowerPC.
+   Limitations:	none.
+   PR:		PR23404
+   Originator:	<andreast at gcc.gnu.org> 20050830	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void
+closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		 void* userdata)
+{
+  *(ffi_arg*)resp =
+    (int)*(unsigned long long *)args[0] +
+    (int)(*(unsigned long long *)args[1]) +
+    (int)(*(unsigned long long *)args[2]) +
+    (int)*(unsigned long long *)args[3] +
+    (int)(*(int *)args[4]) + (int)(*(double *)args[5]) +
+    (int)*(double *)args[6] + (int)(*(float *)args[7]) +
+    (int)(*(double *)args[8]) + (int)*(double *)args[9] +
+    (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
+    (int)*(int *)args[12] + (int)(*(int *)args[13]) +
+    (int)(*(double *)args[14]) +  (int)*(double *)args[15] +
+    (intptr_t)userdata;
+
+  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+	 (int)*(unsigned long long  *)args[0],
+	 (int)(*(unsigned long long  *)args[1]),
+	 (int)(*(unsigned long long  *)args[2]),
+	 (int)*(unsigned long long  *)args[3],
+	 (int)(*(int *)args[4]), (int)(*(double *)args[5]),
+	 (int)*(double *)args[6], (int)(*(float *)args[7]),
+	 (int)(*(double *)args[8]), (int)*(double *)args[9],
+	 (int)(*(int *)args[10]), (int)(*(float *)args[11]),
+	 (int)*(int *)args[12], (int)(*(int *)args[13]),
+	 (int)(*(double *)args[14]), (int)(*(double *)args[15]),
+	 (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (*closure_test_type0)(unsigned long long,
+				  unsigned long long,
+				  unsigned long long,
+				  unsigned long long,
+				  int, double, double, float, double, double,
+				  int, float, int, int, double, double);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[17];
+  int res;
+
+  cl_arg_types[0] = &ffi_type_uint64;
+  cl_arg_types[1] = &ffi_type_uint64;
+  cl_arg_types[2] = &ffi_type_uint64;
+  cl_arg_types[3] = &ffi_type_uint64;
+  cl_arg_types[4] = &ffi_type_sint;
+  cl_arg_types[5] = &ffi_type_double;
+  cl_arg_types[6] = &ffi_type_double;
+  cl_arg_types[7] = &ffi_type_float;
+  cl_arg_types[8] = &ffi_type_double;
+  cl_arg_types[9] = &ffi_type_double;
+  cl_arg_types[10] = &ffi_type_sint;
+  cl_arg_types[11] = &ffi_type_float;
+  cl_arg_types[12] = &ffi_type_sint;
+  cl_arg_types[13] = &ffi_type_sint;
+  cl_arg_types[14] = &ffi_type_double;
+  cl_arg_types[15] = &ffi_type_double;
+  cl_arg_types[16] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+		     &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
+                             (void *) 3 /* userdata */, code) == FFI_OK);
+
+  res = (*((closure_test_type0)code))
+    (1, 2, 3, 4, 127, 429., 7., 8., 9.5, 10., 11, 12., 13,
+     19, 21., 1.);
+  /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
+  printf("res: %d\n",res);
+  /* { dg-output "\nres: 680" } */
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_loc_fn0.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_loc_fn0.c
new file mode 100755
index 0000000..b3afa0b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_loc_fn0.c
@@ -0,0 +1,95 @@
+/* Area:	closure_call
+   Purpose:	Check multiple values passing from different type.
+		Also, exceed the limit of gpr and fpr registers on PowerPC
+		Darwin.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void
+closure_loc_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		 void* userdata)
+{
+  *(ffi_arg*)resp =
+    (int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) +
+    (int)(*(unsigned long long *)args[2]) + (int)*(int *)args[3] +
+    (int)(*(signed short *)args[4]) +
+    (int)(*(unsigned long long *)args[5]) +
+    (int)*(int *)args[6] + (int)(*(int *)args[7]) +
+    (int)(*(double *)args[8]) + (int)*(int *)args[9] +
+    (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
+    (int)*(int *)args[12] + (int)(*(int *)args[13]) +
+    (int)(*(int *)args[14]) +  *(int *)args[15] + (intptr_t)userdata;
+
+  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+	 (int)*(unsigned long long *)args[0], (int)(*(int *)args[1]),
+	 (int)(*(unsigned long long *)args[2]),
+	 (int)*(int *)args[3], (int)(*(signed short *)args[4]),
+	 (int)(*(unsigned long long *)args[5]),
+	 (int)*(int *)args[6], (int)(*(int *)args[7]),
+	 (int)(*(double *)args[8]), (int)*(int *)args[9],
+	 (int)(*(int *)args[10]), (int)(*(float *)args[11]),
+	 (int)*(int *)args[12], (int)(*(int *)args[13]),
+	 (int)(*(int *)args[14]),*(int *)args[15],
+	 (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (*closure_loc_test_type0)(unsigned long long, int, unsigned long long,
+				  int, signed short, unsigned long long, int,
+				  int, double, int, int, float, int, int,
+				  int, int);
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_closure *pcl;
+  ffi_type * cl_arg_types[17];
+  int res;
+  void *codeloc;
+
+  cl_arg_types[0] = &ffi_type_uint64;
+  cl_arg_types[1] = &ffi_type_sint;
+  cl_arg_types[2] = &ffi_type_uint64;
+  cl_arg_types[3] = &ffi_type_sint;
+  cl_arg_types[4] = &ffi_type_sshort;
+  cl_arg_types[5] = &ffi_type_uint64;
+  cl_arg_types[6] = &ffi_type_sint;
+  cl_arg_types[7] = &ffi_type_sint;
+  cl_arg_types[8] = &ffi_type_double;
+  cl_arg_types[9] = &ffi_type_sint;
+  cl_arg_types[10] = &ffi_type_sint;
+  cl_arg_types[11] = &ffi_type_float;
+  cl_arg_types[12] = &ffi_type_sint;
+  cl_arg_types[13] = &ffi_type_sint;
+  cl_arg_types[14] = &ffi_type_sint;
+  cl_arg_types[15] = &ffi_type_sint;
+  cl_arg_types[16] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+		     &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+  pcl = ffi_closure_alloc(sizeof(ffi_closure), &codeloc);
+  CHECK(pcl != NULL);
+  CHECK(codeloc != NULL);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_loc_test_fn0,
+			 (void *) 3 /* userdata */, codeloc) == FFI_OK);
+  
+  CHECK(memcmp(pcl, codeloc, sizeof(*pcl)) == 0);
+
+  res = (*((closure_loc_test_type0)codeloc))
+    (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
+     19, 21, 1);
+  /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
+  printf("res: %d\n",res);
+  /* { dg-output "\nres: 680" } */
+     exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_stdcall.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_stdcall.c
new file mode 100755
index 0000000..6bfcc1f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/closure_stdcall.c
@@ -0,0 +1,64 @@
+/* Area:	closure_call (stdcall convention)
+   Purpose:	Check handling when caller expects stdcall callee
+   Limitations:	none.
+   PR:		none.
+   Originator:	<twalljava at dev.java.net> */
+
+/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
+#include "ffitest.h"
+
+static void
+closure_test_stdcall(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		 void* userdata)
+{
+  *(ffi_arg*)resp =
+    (int)*(int *)args[0] + (int)(*(int *)args[1])
+    + (int)(*(int *)args[2])  + (int)(*(int *)args[3])
+    + (int)(intptr_t)userdata;
+
+  printf("%d %d %d %d: %d\n",
+	 (int)*(int *)args[0], (int)(*(int *)args[1]),
+	 (int)(*(int *)args[2]), (int)(*(int *)args[3]),
+         (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (__stdcall *closure_test_type0)(int, int, int, int);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[17];
+  int res;
+  void* sp_pre;
+  void* sp_post;
+  char buf[1024];
+
+  cl_arg_types[0] = &ffi_type_uint;
+  cl_arg_types[1] = &ffi_type_uint;
+  cl_arg_types[2] = &ffi_type_uint;
+  cl_arg_types[3] = &ffi_type_uint;
+  cl_arg_types[4] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 4,
+		     &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_stdcall,
+                             (void *) 3 /* userdata */, code) == FFI_OK);
+
+  asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
+  res = (*(closure_test_type0)code)(0, 1, 2, 3);
+  asm volatile (" movl %%esp,%0" : "=g" (sp_post));
+  /* { dg-output "0 1 2 3: 9" } */
+
+  printf("res: %d\n",res);
+  /* { dg-output "\nres: 9" } */
+
+  sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post);
+  printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf));
+  /* { dg-output "\nstack pointer match" } */
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c
new file mode 100755
index 0000000..f0a334f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c
@@ -0,0 +1,94 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_12byte {
+  int a;
+  int b;
+  int c;
+} cls_struct_12byte;
+
+cls_struct_12byte cls_struct_12byte_fn(struct cls_struct_12byte b1,
+			    struct cls_struct_12byte b2)
+{
+  struct cls_struct_12byte result;
+
+  result.a = b1.a + b2.a;
+  result.b = b1.b + b2.b;
+  result.c = b1.c + b2.c;
+
+  printf("%d %d %d %d %d %d: %d %d %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c,
+	 result.a, result.b, result.c);
+
+  return result;
+}
+
+static void cls_struct_12byte_gn(ffi_cif* cif __UNUSED__, void* resp,
+				 void** args , void* userdata __UNUSED__)
+{
+  struct cls_struct_12byte b1, b2;
+
+  b1 = *(struct cls_struct_12byte*)(args[0]);
+  b2 = *(struct cls_struct_12byte*)(args[1]);
+
+  *(cls_struct_12byte*)resp = cls_struct_12byte_fn(b1, b2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_12byte h_dbl = { 7, 4, 9 };
+  struct cls_struct_12byte j_dbl = { 1, 5, 3 };
+  struct cls_struct_12byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_sint;
+  cls_struct_fields[1] = &ffi_type_sint;
+  cls_struct_fields[2] = &ffi_type_sint;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &h_dbl;
+  args_dbl[1] = &j_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_12byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "7 4 9 1 5 3: 8 9 12" } */
+  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 8 9 12" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_12byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl.a = 0;
+  res_dbl.b = 0;
+  res_dbl.c = 0;
+
+  res_dbl = ((cls_struct_12byte(*)(cls_struct_12byte, cls_struct_12byte))(code))(h_dbl, j_dbl);
+  /* { dg-output "\n7 4 9 1 5 3: 8 9 12" } */
+  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 8 9 12" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c
new file mode 100755
index 0000000..9b9292a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c
@@ -0,0 +1,95 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Check overlapping.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_16byte {
+  int a;
+  double b;
+  int c;
+} cls_struct_16byte;
+
+cls_struct_16byte cls_struct_16byte_fn(struct cls_struct_16byte b1,
+			    struct cls_struct_16byte b2)
+{
+  struct cls_struct_16byte result;
+
+  result.a = b1.a + b2.a;
+  result.b = b1.b + b2.b;
+  result.c = b1.c + b2.c;
+
+  printf("%d %g %d %d %g %d: %d %g %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c,
+	 result.a, result.b, result.c);
+
+  return result;
+}
+
+static void cls_struct_16byte_gn(ffi_cif* cif __UNUSED__, void* resp,
+				 void** args, void* userdata __UNUSED__)
+{
+  struct cls_struct_16byte b1, b2;
+
+  b1 = *(struct cls_struct_16byte*)(args[0]);
+  b2 = *(struct cls_struct_16byte*)(args[1]);
+
+  *(cls_struct_16byte*)resp = cls_struct_16byte_fn(b1, b2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_16byte h_dbl = { 7, 8.0, 9 };
+  struct cls_struct_16byte j_dbl = { 1, 9.0, 3 };
+  struct cls_struct_16byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_sint;
+  cls_struct_fields[1] = &ffi_type_double;
+  cls_struct_fields[2] = &ffi_type_sint;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &h_dbl;
+  args_dbl[1] = &j_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_16byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "7 8 9 1 9 3: 8 17 12" } */
+  printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 8 17 12" } */
+
+  res_dbl.a = 0;
+  res_dbl.b = 0.0;
+  res_dbl.c = 0;
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_16byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_16byte(*)(cls_struct_16byte, cls_struct_16byte))(code))(h_dbl, j_dbl);
+  /* { dg-output "\n7 8 9 1 9 3: 8 17 12" } */
+  printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 8 17 12" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c
new file mode 100755
index 0000000..40c8c6d
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c
@@ -0,0 +1,96 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Double alignment check on darwin.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030915	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_18byte {
+  double a;
+  unsigned char b;
+  unsigned char c;
+  double d;
+} cls_struct_18byte;
+
+cls_struct_18byte cls_struct_18byte_fn(struct cls_struct_18byte a1,
+			    struct cls_struct_18byte a2)
+{
+  struct cls_struct_18byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+  result.d = a1.d + a2.d;
+
+
+  printf("%g %d %d %g %g %d %d %g: %g %d %d %g\n", a1.a, a1.b, a1.c, a1.d,
+	 a2.a, a2.b, a2.c, a2.d,
+	 result.a, result.b, result.c, result.d);
+  return result;
+}
+
+static void
+cls_struct_18byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		     void* userdata __UNUSED__)
+{
+  struct cls_struct_18byte a1, a2;
+
+  a1 = *(struct cls_struct_18byte*)(args[0]);
+  a2 = *(struct cls_struct_18byte*)(args[1]);
+
+  *(cls_struct_18byte*)resp = cls_struct_18byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[3];
+  ffi_type* cls_struct_fields[5];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[3];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_18byte g_dbl = { 1.0, 127, 126, 3.0 };
+  struct cls_struct_18byte f_dbl = { 4.0, 125, 124, 5.0 };
+  struct cls_struct_18byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_double;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = &ffi_type_double;
+  cls_struct_fields[4] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_18byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "1 127 126 3 4 125 124 5: 5 252 250 8" } */
+  printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+  /* { dg-output "\nres: 5 252 250 8" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_18byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_18byte(*)(cls_struct_18byte, cls_struct_18byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n1 127 126 3 4 125 124 5: 5 252 250 8" } */
+  printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+  /* { dg-output "\nres: 5 252 250 8" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c
new file mode 100755
index 0000000..aa64248
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c
@@ -0,0 +1,102 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Double alignment check on darwin.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030915	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_19byte {
+  double a;
+  unsigned char b;
+  unsigned char c;
+  double d;
+  unsigned char e;
+} cls_struct_19byte;
+
+cls_struct_19byte cls_struct_19byte_fn(struct cls_struct_19byte a1,
+			    struct cls_struct_19byte a2)
+{
+  struct cls_struct_19byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+  result.d = a1.d + a2.d;
+  result.e = a1.e + a2.e;
+
+
+  printf("%g %d %d %g %d %g %d %d %g %d: %g %d %d %g %d\n",
+	 a1.a, a1.b, a1.c, a1.d, a1.e,
+	 a2.a, a2.b, a2.c, a2.d, a2.e,
+	 result.a, result.b, result.c, result.d, result.e);
+  return result;
+}
+
+static void
+cls_struct_19byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		     void* userdata __UNUSED__)
+{
+  struct cls_struct_19byte a1, a2;
+
+  a1 = *(struct cls_struct_19byte*)(args[0]);
+  a2 = *(struct cls_struct_19byte*)(args[1]);
+
+  *(cls_struct_19byte*)resp = cls_struct_19byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[3];
+  ffi_type* cls_struct_fields[6];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[3];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_19byte g_dbl = { 1.0, 127, 126, 3.0, 120 };
+  struct cls_struct_19byte f_dbl = { 4.0, 125, 124, 5.0, 119 };
+  struct cls_struct_19byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_double;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = &ffi_type_double;
+  cls_struct_fields[4] = &ffi_type_uchar;
+  cls_struct_fields[5] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_19byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */
+  printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+	 res_dbl.d, res_dbl.e);
+  /* { dg-output "\nres: 5 252 250 8 239" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_19byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_19byte(*)(cls_struct_19byte, cls_struct_19byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */
+  printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+	 res_dbl.d, res_dbl.e);
+  /* { dg-output "\nres: 5 252 250 8 239" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c
new file mode 100755
index 0000000..b9402d6
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c
@@ -0,0 +1,89 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Especially with small structures which may fit in one
+		register. Depending on the ABI.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030902	 */
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_1_1byte {
+  unsigned char a;
+} cls_struct_1_1byte;
+
+cls_struct_1_1byte cls_struct_1_1byte_fn(struct cls_struct_1_1byte a1,
+			    struct cls_struct_1_1byte a2)
+{
+  struct cls_struct_1_1byte result;
+
+  result.a = a1.a + a2.a;
+
+  printf("%d %d: %d\n", a1.a, a2.a, result.a);
+
+  return  result;
+}
+
+static void
+cls_struct_1_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		      void* userdata __UNUSED__)
+{
+
+  struct cls_struct_1_1byte a1, a2;
+
+  a1 = *(struct cls_struct_1_1byte*)(args[0]);
+  a2 = *(struct cls_struct_1_1byte*)(args[1]);
+
+  *(cls_struct_1_1byte*)resp = cls_struct_1_1byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[2];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_1_1byte g_dbl = { 12 };
+  struct cls_struct_1_1byte f_dbl = { 178 };
+  struct cls_struct_1_1byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_1_1byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "12 178: 190" } */
+  printf("res: %d\n", res_dbl.a);
+  /* { dg-output "\nres: 190" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_1_1byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_1_1byte(*)(cls_struct_1_1byte, cls_struct_1_1byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n12 178: 190" } */
+  printf("res: %d\n", res_dbl.a);
+  /* { dg-output "\nres: 190" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c
new file mode 100755
index 0000000..80dd7ac
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c
@@ -0,0 +1,91 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Check overlapping.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_20byte {
+  double a;
+  double b;
+  int c;
+} cls_struct_20byte;
+
+cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
+			    struct cls_struct_20byte a2)
+{
+  struct cls_struct_20byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+
+  printf("%g %g %d %g %g %d: %g %g %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c,
+	 result.a, result.b, result.c);
+  return result;
+}
+
+static void
+cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		     void* userdata __UNUSED__)
+{
+  struct cls_struct_20byte a1, a2;
+
+  a1 = *(struct cls_struct_20byte*)(args[0]);
+  a2 = *(struct cls_struct_20byte*)(args[1]);
+
+  *(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_20byte g_dbl = { 1.0, 2.0, 3 };
+  struct cls_struct_20byte f_dbl = { 4.0, 5.0, 7 };
+  struct cls_struct_20byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_double;
+  cls_struct_fields[1] = &ffi_type_double;
+  cls_struct_fields[2] = &ffi_type_sint;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "1 2 3 4 5 7: 5 7 10" } */
+  printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 5 7 10" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
+  printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 5 7 10" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c
new file mode 100755
index 0000000..50bcbbf
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c
@@ -0,0 +1,93 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Check overlapping.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_20byte {
+  int a;
+  double b;
+  double c;
+} cls_struct_20byte;
+
+cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
+			    struct cls_struct_20byte a2)
+{
+  struct cls_struct_20byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+
+  printf("%d %g %g %d %g %g: %d %g %g\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c,
+	 result.a, result.b, result.c);
+  return result;
+}
+
+static void
+cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		     void* userdata __UNUSED__)
+{
+  struct cls_struct_20byte a1, a2;
+
+  a1 = *(struct cls_struct_20byte*)(args[0]);
+  a2 = *(struct cls_struct_20byte*)(args[1]);
+
+  *(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[3];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[3];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 };
+  struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 };
+  struct cls_struct_20byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_sint;
+  cls_struct_fields[1] = &ffi_type_double;
+  cls_struct_fields[2] = &ffi_type_double;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "1 2 3 4 5 7: 5 7 10" } */
+  printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 5 7 10" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
+  printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 5 7 10" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c
new file mode 100755
index 0000000..46a6eb4
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c
@@ -0,0 +1,113 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Check overlapping.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_24byte {
+  double a;
+  double b;
+  int c;
+  float d;
+} cls_struct_24byte;
+
+cls_struct_24byte cls_struct_24byte_fn(struct cls_struct_24byte b0,
+			    struct cls_struct_24byte b1,
+			    struct cls_struct_24byte b2,
+			    struct cls_struct_24byte b3)
+{
+  struct cls_struct_24byte result;
+
+  result.a = b0.a + b1.a + b2.a + b3.a;
+  result.b = b0.b + b1.b + b2.b + b3.b;
+  result.c = b0.c + b1.c + b2.c + b3.c;
+  result.d = b0.d + b1.d + b2.d + b3.d;
+
+  printf("%g %g %d %g %g %g %d %g %g %g %d %g %g %g %d %g: %g %g %d %g\n",
+	 b0.a, b0.b, b0.c, b0.d,
+	 b1.a, b1.b, b1.c, b1.d,
+	 b2.a, b2.b, b2.c, b2.d,
+	 b3.a, b3.b, b3.c, b2.d,
+	 result.a, result.b, result.c, result.d);
+
+  return result;
+}
+
+static void
+cls_struct_24byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		     void* userdata __UNUSED__)
+{
+  struct cls_struct_24byte b0, b1, b2, b3;
+
+  b0 = *(struct cls_struct_24byte*)(args[0]);
+  b1 = *(struct cls_struct_24byte*)(args[1]);
+  b2 = *(struct cls_struct_24byte*)(args[2]);
+  b3 = *(struct cls_struct_24byte*)(args[3]);
+
+  *(cls_struct_24byte*)resp = cls_struct_24byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[5];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_24byte e_dbl = { 9.0, 2.0, 6, 5.0 };
+  struct cls_struct_24byte f_dbl = { 1.0, 2.0, 3, 7.0 };
+  struct cls_struct_24byte g_dbl = { 4.0, 5.0, 7, 9.0 };
+  struct cls_struct_24byte h_dbl = { 8.0, 6.0, 1, 4.0 };
+  struct cls_struct_24byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_double;
+  cls_struct_fields[1] = &ffi_type_double;
+  cls_struct_fields[2] = &ffi_type_sint;
+  cls_struct_fields[3] = &ffi_type_float;
+  cls_struct_fields[4] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = &cls_struct_type;
+  dbl_arg_types[3] = &cls_struct_type;
+  dbl_arg_types[4] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &e_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = &g_dbl;
+  args_dbl[3] = &h_dbl;
+  args_dbl[4] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_24byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */
+  printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+  /* { dg-output "\nres: 22 15 17 25" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_24byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_24byte(*)(cls_struct_24byte,
+				   cls_struct_24byte,
+				   cls_struct_24byte,
+				   cls_struct_24byte))
+	     (code))(e_dbl, f_dbl, g_dbl, h_dbl);
+  /* { dg-output "\n9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */
+  printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+  /* { dg-output "\nres: 22 15 17 25" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c
new file mode 100755
index 0000000..101e130
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c
@@ -0,0 +1,90 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Especially with small structures which may fit in one
+		register. Depending on the ABI.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_2byte {
+  unsigned char a;
+  unsigned char b;
+} cls_struct_2byte;
+
+cls_struct_2byte cls_struct_2byte_fn(struct cls_struct_2byte a1,
+			    struct cls_struct_2byte a2)
+{
+  struct cls_struct_2byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+
+  printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
+
+  return  result;
+}
+
+static void
+cls_struct_2byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_2byte a1, a2;
+
+  a1 = *(struct cls_struct_2byte*)(args[0]);
+  a2 = *(struct cls_struct_2byte*)(args[1]);
+
+  *(cls_struct_2byte*)resp = cls_struct_2byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_2byte g_dbl = { 12, 127 };
+  struct cls_struct_2byte f_dbl = { 1, 13 };
+  struct cls_struct_2byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_2byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "12 127 1 13: 13 140" } */
+  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+  /* { dg-output "\nres: 13 140" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_2byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_2byte(*)(cls_struct_2byte, cls_struct_2byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n12 127 1 13: 13 140" } */
+  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+  /* { dg-output "\nres: 13 140" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c
new file mode 100755
index 0000000..fc780c3
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c
@@ -0,0 +1,95 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Especially with small structures which may fit in one
+		register. Depending on the ABI.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030902	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_3_1byte {
+  unsigned char a;
+  unsigned char b;
+  unsigned char c;
+} cls_struct_3_1byte;
+
+cls_struct_3_1byte cls_struct_3_1byte_fn(struct cls_struct_3_1byte a1,
+			    struct cls_struct_3_1byte a2)
+{
+  struct cls_struct_3_1byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+
+  printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c,
+	 a2.a, a2.b, a2.c,
+	 result.a, result.b, result.c);
+
+  return  result;
+}
+
+static void
+cls_struct_3_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		      void* userdata __UNUSED__)
+{
+
+  struct cls_struct_3_1byte a1, a2;
+
+  a1 = *(struct cls_struct_3_1byte*)(args[0]);
+  a2 = *(struct cls_struct_3_1byte*)(args[1]);
+
+  *(cls_struct_3_1byte*)resp = cls_struct_3_1byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_3_1byte g_dbl = { 12, 13, 14 };
+  struct cls_struct_3_1byte f_dbl = { 178, 179, 180 };
+  struct cls_struct_3_1byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_3_1byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "12 13 14 178 179 180: 190 192 194" } */
+  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 190 192 194" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3_1byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_3_1byte(*)(cls_struct_3_1byte, cls_struct_3_1byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n12 13 14 178 179 180: 190 192 194" } */
+  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 190 192 194" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c
new file mode 100755
index 0000000..5705ce3
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c
@@ -0,0 +1,90 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Especially with small structures which may fit in one
+		register. Depending on the ABI. Check overlapping.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_3byte {
+  unsigned short a;
+  unsigned char b;
+} cls_struct_3byte;
+
+cls_struct_3byte cls_struct_3byte_fn(struct cls_struct_3byte a1,
+			    struct cls_struct_3byte a2)
+{
+  struct cls_struct_3byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+
+  printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
+
+  return  result;
+}
+
+static void
+cls_struct_3byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_3byte a1, a2;
+
+  a1 = *(struct cls_struct_3byte*)(args[0]);
+  a2 = *(struct cls_struct_3byte*)(args[1]);
+
+  *(cls_struct_3byte*)resp = cls_struct_3byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_3byte g_dbl = { 12, 119 };
+  struct cls_struct_3byte f_dbl = { 1, 15 };
+  struct cls_struct_3byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_ushort;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_3byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "12 119 1 15: 13 134" } */
+  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+  /* { dg-output "\nres: 13 134" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_3byte(*)(cls_struct_3byte, cls_struct_3byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n12 119 1 15: 13 134" } */
+  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+  /* { dg-output "\nres: 13 134" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c
new file mode 100755
index 0000000..01770a0
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c
@@ -0,0 +1,90 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Especially with small structures which may fit in one
+		register. Depending on the ABI. Check overlapping.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_3byte_1 {
+  unsigned char a;
+  unsigned short b;
+} cls_struct_3byte_1;
+
+cls_struct_3byte_1 cls_struct_3byte_fn1(struct cls_struct_3byte_1 a1,
+			    struct cls_struct_3byte_1 a2)
+{
+  struct cls_struct_3byte_1 result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+
+  printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
+
+  return  result;
+}
+
+static void
+cls_struct_3byte_gn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		     void* userdata __UNUSED__)
+{
+
+  struct cls_struct_3byte_1 a1, a2;
+
+  a1 = *(struct cls_struct_3byte_1*)(args[0]);
+  a2 = *(struct cls_struct_3byte_1*)(args[1]);
+
+  *(cls_struct_3byte_1*)resp = cls_struct_3byte_fn1(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_3byte_1 g_dbl = { 15, 125 };
+  struct cls_struct_3byte_1 f_dbl = { 9, 19 };
+  struct cls_struct_3byte_1 res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_ushort;
+  cls_struct_fields[2] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_3byte_fn1), &res_dbl, args_dbl);
+  /* { dg-output "15 125 9 19: 24 144" } */
+  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+  /* { dg-output "\nres: 24 144" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3byte_gn1, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_3byte_1(*)(cls_struct_3byte_1, cls_struct_3byte_1))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n15 125 9 19: 24 144" } */
+  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+  /* { dg-output "\nres: 24 144" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c
new file mode 100755
index 0000000..f3806d7
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c
@@ -0,0 +1,98 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Especially with small structures which may fit in one
+		register. Depending on the ABI.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030902	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_4_1byte {
+  unsigned char a;
+  unsigned char b;
+  unsigned char c;
+  unsigned char d;
+} cls_struct_4_1byte;
+
+cls_struct_4_1byte cls_struct_4_1byte_fn(struct cls_struct_4_1byte a1,
+			    struct cls_struct_4_1byte a2)
+{
+  struct cls_struct_4_1byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+  result.d = a1.d + a2.d;
+
+  printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
+	 a2.a, a2.b, a2.c, a2.d,
+	 result.a, result.b, result.c, result.d);
+
+  return  result;
+}
+
+static void
+cls_struct_4_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		      void* userdata __UNUSED__)
+{
+
+  struct cls_struct_4_1byte a1, a2;
+
+  a1 = *(struct cls_struct_4_1byte*)(args[0]);
+  a2 = *(struct cls_struct_4_1byte*)(args[1]);
+
+  *(cls_struct_4_1byte*)resp = cls_struct_4_1byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[5];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_4_1byte g_dbl = { 12, 13, 14, 15 };
+  struct cls_struct_4_1byte f_dbl = { 178, 179, 180, 181 };
+  struct cls_struct_4_1byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = &ffi_type_uchar;
+  cls_struct_fields[4] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_4_1byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "12 13 14 15 178 179 180 181: 190 192 194 196" } */
+  printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+  /* { dg-output "\nres: 190 192 194 196" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_4_1byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_4_1byte(*)(cls_struct_4_1byte, cls_struct_4_1byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n12 13 14 15 178 179 180 181: 190 192 194 196" } */
+  printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+  /* { dg-output "\nres: 190 192 194 196" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c
new file mode 100755
index 0000000..a1aba3c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c
@@ -0,0 +1,90 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Check overlapping.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+typedef struct cls_struct_4byte {
+  unsigned short a;
+  unsigned short b;
+} cls_struct_4byte;
+
+cls_struct_4byte cls_struct_4byte_fn(struct cls_struct_4byte a1,
+			    struct cls_struct_4byte a2)
+{
+  struct cls_struct_4byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+
+  printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
+
+  return  result;
+}
+
+static void
+cls_struct_4byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_4byte a1, a2;
+
+  a1 = *(struct cls_struct_4byte*)(args[0]);
+  a2 = *(struct cls_struct_4byte*)(args[1]);
+
+  *(cls_struct_4byte*)resp = cls_struct_4byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_4byte g_dbl = { 127, 120 };
+  struct cls_struct_4byte f_dbl = { 12, 128 };
+  struct cls_struct_4byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_ushort;
+  cls_struct_fields[1] = &ffi_type_ushort;
+  cls_struct_fields[2] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_4byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "127 120 12 128: 139 248" } */
+  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+  /* { dg-output "\nres: 139 248" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_4byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_4byte(*)(cls_struct_4byte, cls_struct_4byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n127 120 12 128: 139 248" } */
+  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
+  /* { dg-output "\nres: 139 248" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c
new file mode 100755
index 0000000..2ceba3d
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c
@@ -0,0 +1,109 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Check overlapping.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20050708	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_5byte {
+  unsigned char a;
+  unsigned char b;
+  unsigned char c;
+  unsigned char d;
+  unsigned char e;
+} cls_struct_5byte;
+
+cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1,
+			    struct cls_struct_5byte a2)
+{
+  struct cls_struct_5byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+  result.d = a1.d + a2.d;
+  result.e = a1.e + a2.e;
+
+  printf("%d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d\n",
+	 a1.a, a1.b, a1.c, a1.d, a1.e,
+	 a2.a, a2.b, a2.c, a2.d, a2.e,
+	 result.a, result.b, result.c, result.d, result.e);
+
+  return  result;
+}
+
+static void
+cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_5byte a1, a2;
+
+  a1 = *(struct cls_struct_5byte*)(args[0]);
+  a2 = *(struct cls_struct_5byte*)(args[1]);
+
+  *(cls_struct_5byte*)resp = cls_struct_5byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[6];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_5byte g_dbl = { 127, 120, 1, 3, 4 };
+  struct cls_struct_5byte f_dbl = { 12, 128, 9, 3, 4 };
+  struct cls_struct_5byte res_dbl = { 0, 0, 0, 0, 0 };
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = &ffi_type_uchar;
+  cls_struct_fields[4] = &ffi_type_uchar;
+  cls_struct_fields[5] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_5byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "127 120 1 3 4 12 128 9 3 4: 139 248 10 6 8" } */
+  printf("res: %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+	 res_dbl.d, res_dbl.e);
+  /* { dg-output "\nres: 139 248 10 6 8" } */
+
+  res_dbl.a = 0;
+  res_dbl.b = 0;
+  res_dbl.c = 0;
+  res_dbl.d = 0;
+  res_dbl.e = 0;
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_5byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n127 120 1 3 4 12 128 9 3 4: 139 248 10 6 8" } */
+  printf("res: %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+	 res_dbl.d, res_dbl.e);
+  /* { dg-output "\nres: 139 248 10 6 8" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c
new file mode 100755
index 0000000..61d595c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c
@@ -0,0 +1,98 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Check overlapping.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_5byte {
+  unsigned short a;
+  unsigned short b;
+  unsigned char c;
+} cls_struct_5byte;
+
+cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1,
+			    struct cls_struct_5byte a2)
+{
+  struct cls_struct_5byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+
+  printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c,
+	 a2.a, a2.b, a2.c,
+	 result.a, result.b, result.c);
+
+  return  result;
+}
+
+static void
+cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_5byte a1, a2;
+
+  a1 = *(struct cls_struct_5byte*)(args[0]);
+  a2 = *(struct cls_struct_5byte*)(args[1]);
+
+  *(cls_struct_5byte*)resp = cls_struct_5byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_5byte g_dbl = { 127, 120, 1 };
+  struct cls_struct_5byte f_dbl = { 12, 128, 9 };
+  struct cls_struct_5byte res_dbl = { 0, 0, 0 };
+
+  cls_struct_fields[0] = &ffi_type_ushort;
+  cls_struct_fields[1] = &ffi_type_ushort;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_5byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "127 120 1 12 128 9: 139 248 10" } */
+  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 139 248 10" } */
+
+  res_dbl.a = 0;
+  res_dbl.b = 0;
+  res_dbl.c = 0;
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_5byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n127 120 1 12 128 9: 139 248 10" } */
+  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 139 248 10" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c
new file mode 100755
index 0000000..576ebe0
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c
@@ -0,0 +1,124 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Check bigger struct which overlaps
+		the gp and fp register count on Darwin/AIX/ppc64.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_64byte {
+  double a;
+  double b;
+  double c;
+  double d;
+  double e;
+  double f;
+  double g;
+  double h;
+} cls_struct_64byte;
+
+cls_struct_64byte cls_struct_64byte_fn(struct cls_struct_64byte b0,
+			    struct cls_struct_64byte b1,
+			    struct cls_struct_64byte b2,
+			    struct cls_struct_64byte b3)
+{
+  struct cls_struct_64byte result;
+
+  result.a = b0.a + b1.a + b2.a + b3.a;
+  result.b = b0.b + b1.b + b2.b + b3.b;
+  result.c = b0.c + b1.c + b2.c + b3.c;
+  result.d = b0.d + b1.d + b2.d + b3.d;
+  result.e = b0.e + b1.e + b2.e + b3.e;
+  result.f = b0.f + b1.f + b2.f + b3.f;
+  result.g = b0.g + b1.g + b2.g + b3.g;
+  result.h = b0.h + b1.h + b2.h + b3.h;
+
+  printf("%g %g %g %g %g %g %g %g\n", result.a, result.b, result.c,
+	 result.d, result.e, result.f, result.g, result.h);
+
+  return result;
+}
+
+static void
+cls_struct_64byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		     void* userdata __UNUSED__)
+{
+  struct cls_struct_64byte b0, b1, b2, b3;
+
+  b0 = *(struct cls_struct_64byte*)(args[0]);
+  b1 = *(struct cls_struct_64byte*)(args[1]);
+  b2 = *(struct cls_struct_64byte*)(args[2]);
+  b3 = *(struct cls_struct_64byte*)(args[3]);
+
+  *(cls_struct_64byte*)resp = cls_struct_64byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[9];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_64byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0 };
+  struct cls_struct_64byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0 };
+  struct cls_struct_64byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0 };
+  struct cls_struct_64byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0 };
+  struct cls_struct_64byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_double;
+  cls_struct_fields[1] = &ffi_type_double;
+  cls_struct_fields[2] = &ffi_type_double;
+  cls_struct_fields[3] = &ffi_type_double;
+  cls_struct_fields[4] = &ffi_type_double;
+  cls_struct_fields[5] = &ffi_type_double;
+  cls_struct_fields[6] = &ffi_type_double;
+  cls_struct_fields[7] = &ffi_type_double;
+  cls_struct_fields[8] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = &cls_struct_type;
+  dbl_arg_types[3] = &cls_struct_type;
+  dbl_arg_types[4] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &e_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = &g_dbl;
+  args_dbl[3] = &h_dbl;
+  args_dbl[4] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_64byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "22 15 17 25 6 13 19 18" } */
+  printf("res: %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
+	 res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h);
+  /* { dg-output "\nres: 22 15 17 25 6 13 19 18" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_64byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_64byte(*)(cls_struct_64byte,
+				   cls_struct_64byte,
+				   cls_struct_64byte,
+				   cls_struct_64byte))
+	     (code))(e_dbl, f_dbl, g_dbl, h_dbl);
+  /* { dg-output "\n22 15 17 25 6 13 19 18" } */
+  printf("res: %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
+	 res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h);
+  /* { dg-output "\nres: 22 15 17 25 6 13 19 18" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c
new file mode 100755
index 0000000..9f2eff6
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c
@@ -0,0 +1,113 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Check overlapping.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20050708	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_6byte {
+  unsigned char a;
+  unsigned char b;
+  unsigned char c;
+  unsigned char d;
+  unsigned char e;
+  unsigned char f;
+} cls_struct_6byte;
+
+cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1,
+			    struct cls_struct_6byte a2)
+{
+  struct cls_struct_6byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+  result.d = a1.d + a2.d;
+  result.e = a1.e + a2.e;
+  result.f = a1.f + a2.f;
+
+  printf("%d %d %d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d %d\n",
+	 a1.a, a1.b, a1.c, a1.d, a1.e, a1.f,
+	 a2.a, a2.b, a2.c, a2.d, a2.e, a2.f,
+	 result.a, result.b, result.c, result.d, result.e, result.f);
+
+  return  result;
+}
+
+static void
+cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_6byte a1, a2;
+
+  a1 = *(struct cls_struct_6byte*)(args[0]);
+  a2 = *(struct cls_struct_6byte*)(args[1]);
+
+  *(cls_struct_6byte*)resp = cls_struct_6byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[7];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_6byte g_dbl = { 127, 120, 1, 3, 4, 5 };
+  struct cls_struct_6byte f_dbl = { 12, 128, 9, 3, 4, 5 };
+  struct cls_struct_6byte res_dbl = { 0, 0, 0, 0, 0, 0 };
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = &ffi_type_uchar;
+  cls_struct_fields[4] = &ffi_type_uchar;
+  cls_struct_fields[5] = &ffi_type_uchar;
+  cls_struct_fields[6] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_6byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "127 120 1 3 4 5 12 128 9 3 4 5: 139 248 10 6 8 10" } */
+  printf("res: %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+	 res_dbl.d, res_dbl.e, res_dbl.f);
+  /* { dg-output "\nres: 139 248 10 6 8 10" } */
+
+  res_dbl.a = 0;
+  res_dbl.b = 0;
+  res_dbl.c = 0;
+  res_dbl.d = 0;
+  res_dbl.e = 0;
+  res_dbl.f = 0;
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_6byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n127 120 1 3 4 5 12 128 9 3 4 5: 139 248 10 6 8 10" } */
+  printf("res: %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+	 res_dbl.d, res_dbl.e, res_dbl.f);
+  /* { dg-output "\nres: 139 248 10 6 8 10" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c
new file mode 100755
index 0000000..73257b0
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c
@@ -0,0 +1,99 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Check overlapping.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_6byte {
+  unsigned short a;
+  unsigned short b;
+  unsigned char c;
+  unsigned char d;
+} cls_struct_6byte;
+
+cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1,
+			    struct cls_struct_6byte a2)
+{
+  struct cls_struct_6byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+  result.d = a1.d + a2.d;
+
+  printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
+	 a2.a, a2.b, a2.c, a2.d,
+	 result.a, result.b, result.c, result.d);
+
+  return  result;
+}
+
+static void
+cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_6byte a1, a2;
+
+  a1 = *(struct cls_struct_6byte*)(args[0]);
+  a2 = *(struct cls_struct_6byte*)(args[1]);
+
+  *(cls_struct_6byte*)resp = cls_struct_6byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[5];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_6byte g_dbl = { 127, 120, 1, 128 };
+  struct cls_struct_6byte f_dbl = { 12, 128, 9, 127 };
+  struct cls_struct_6byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_ushort;
+  cls_struct_fields[1] = &ffi_type_ushort;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = &ffi_type_uchar;
+  cls_struct_fields[4] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_6byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "127 120 1 128 12 128 9 127: 139 248 10 255" } */
+  printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+  /* { dg-output "\nres: 139 248 10 255" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_6byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n127 120 1 128 12 128 9 127: 139 248 10 255" } */
+  printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+  /* { dg-output "\nres: 139 248 10 255" } */
+
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c
new file mode 100755
index 0000000..50d09c9
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c
@@ -0,0 +1,117 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Check overlapping.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20050708	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_7byte {
+  unsigned char a;
+  unsigned char b;
+  unsigned char c;
+  unsigned char d;
+  unsigned char e;
+  unsigned char f;
+  unsigned char g;
+} cls_struct_7byte;
+
+cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1,
+			    struct cls_struct_7byte a2)
+{
+  struct cls_struct_7byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+  result.d = a1.d + a2.d;
+  result.e = a1.e + a2.e;
+  result.f = a1.f + a2.f;
+  result.g = a1.g + a2.g;
+
+  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d %d %d\n",
+	 a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
+	 a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
+	 result.a, result.b, result.c, result.d, result.e, result.f, result.g);
+
+  return  result;
+}
+
+static void
+cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_7byte a1, a2;
+
+  a1 = *(struct cls_struct_7byte*)(args[0]);
+  a2 = *(struct cls_struct_7byte*)(args[1]);
+
+  *(cls_struct_7byte*)resp = cls_struct_7byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[8];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_7byte g_dbl = { 127, 120, 1, 3, 4, 5, 6 };
+  struct cls_struct_7byte f_dbl = { 12, 128, 9, 3, 4, 5, 6 };
+  struct cls_struct_7byte res_dbl = { 0, 0, 0, 0, 0, 0, 0 };
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = &ffi_type_uchar;
+  cls_struct_fields[4] = &ffi_type_uchar;
+  cls_struct_fields[5] = &ffi_type_uchar;
+  cls_struct_fields[6] = &ffi_type_uchar;
+  cls_struct_fields[7] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "127 120 1 3 4 5 6 12 128 9 3 4 5 6: 139 248 10 6 8 10 12" } */
+  printf("res: %d %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+	 res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+  /* { dg-output "\nres: 139 248 10 6 8 10 12" } */
+
+  res_dbl.a = 0;
+  res_dbl.b = 0;
+  res_dbl.c = 0;
+  res_dbl.d = 0;
+  res_dbl.e = 0;
+  res_dbl.f = 0;
+  res_dbl.g = 0;
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_7byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n127 120 1 3 4 5 6 12 128 9 3 4 5 6: 139 248 10 6 8 10 12" } */
+  printf("res: %d %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
+	 res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+  /* { dg-output "\nres: 139 248 10 6 8 10 12" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c
new file mode 100755
index 0000000..f5c0000
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c
@@ -0,0 +1,97 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Check overlapping.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_7byte {
+  unsigned short a;
+  unsigned short b;
+  unsigned char c;
+  unsigned short d;
+} cls_struct_7byte;
+
+cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1,
+			    struct cls_struct_7byte a2)
+{
+  struct cls_struct_7byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+  result.d = a1.d + a2.d;
+
+  printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
+	 a2.a, a2.b, a2.c, a2.d,
+	 result.a, result.b, result.c, result.d);
+
+  return  result;
+}
+
+static void
+cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_7byte a1, a2;
+
+  a1 = *(struct cls_struct_7byte*)(args[0]);
+  a2 = *(struct cls_struct_7byte*)(args[1]);
+
+  *(cls_struct_7byte*)resp = cls_struct_7byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[5];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_7byte g_dbl = { 127, 120, 1, 254 };
+  struct cls_struct_7byte f_dbl = { 12, 128, 9, 255 };
+  struct cls_struct_7byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_ushort;
+  cls_struct_fields[1] = &ffi_type_ushort;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = &ffi_type_ushort;
+  cls_struct_fields[4] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "127 120 1 254 12 128 9 255: 139 248 10 509" } */
+  printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+  /* { dg-output "\nres: 139 248 10 509" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_7byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n127 120 1 254 12 128 9 255: 139 248 10 509" } */
+  printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
+  /* { dg-output "\nres: 139 248 10 509" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c
new file mode 100755
index 0000000..4aa99d1
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c
@@ -0,0 +1,88 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Check overlapping.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_8byte {
+  int a;
+  float b;
+} cls_struct_8byte;
+
+cls_struct_8byte cls_struct_8byte_fn(struct cls_struct_8byte a1,
+			    struct cls_struct_8byte a2)
+{
+  struct cls_struct_8byte result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+
+  printf("%d %g %d %g: %d %g\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
+
+  return  result;
+}
+
+static void
+cls_struct_8byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_8byte a1, a2;
+
+  a1 = *(struct cls_struct_8byte*)(args[0]);
+  a2 = *(struct cls_struct_8byte*)(args[1]);
+
+  *(cls_struct_8byte*)resp = cls_struct_8byte_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_8byte g_dbl = { 1, 2.0 };
+  struct cls_struct_8byte f_dbl = { 4, 5.0 };
+  struct cls_struct_8byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_sint;
+  cls_struct_fields[1] = &ffi_type_float;
+  cls_struct_fields[2] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_8byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "1 2 4 5: 5 7" } */
+  printf("res: %d %g\n", res_dbl.a, res_dbl.b);
+  /* { dg-output "\nres: 5 7" } */
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_8byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_8byte(*)(cls_struct_8byte, cls_struct_8byte))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n1 2 4 5: 5 7" } */
+  printf("res: %d %g\n", res_dbl.a, res_dbl.b);
+  /* { dg-output "\nres: 5 7" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c
new file mode 100755
index 0000000..cc5e9d6
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c
@@ -0,0 +1,90 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Darwin/AIX do double-word
+		alignment of the struct if the first element is a double.
+		Check that it does not here.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030914	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_9byte {
+  int a;
+  double b;
+} cls_struct_9byte;
+
+cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1,
+			    struct cls_struct_9byte b2)
+{
+  struct cls_struct_9byte result;
+
+  result.a = b1.a + b2.a;
+  result.b = b1.b + b2.b;
+
+  printf("%d %g %d %g: %d %g\n", b1.a, b1.b,  b2.a, b2.b,
+	 result.a, result.b);
+
+  return result;
+}
+
+static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
+				void** args, void* userdata __UNUSED__)
+{
+  struct cls_struct_9byte b1, b2;
+
+  b1 = *(struct cls_struct_9byte*)(args[0]);
+  b2 = *(struct cls_struct_9byte*)(args[1]);
+
+  *(cls_struct_9byte*)resp = cls_struct_9byte_fn(b1, b2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[3];
+  ffi_type* cls_struct_fields[3];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[3];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_9byte h_dbl = { 7, 8.0};
+  struct cls_struct_9byte j_dbl = { 1, 9.0};
+  struct cls_struct_9byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_sint;
+  cls_struct_fields[1] = &ffi_type_double;
+  cls_struct_fields[2] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &h_dbl;
+  args_dbl[1] = &j_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_9byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "7 8 1 9: 8 17" } */
+  printf("res: %d %g\n", res_dbl.a, res_dbl.b);
+  /* { dg-output "\nres: 8 17" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_9byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(code))(h_dbl, j_dbl);
+  /* { dg-output "\n7 8 1 9: 8 17" } */
+  printf("res: %d %g\n", res_dbl.a, res_dbl.b);
+  /* { dg-output "\nres: 8 17" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c
new file mode 100755
index 0000000..5c0ba0d
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c
@@ -0,0 +1,91 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Depending on the ABI. Darwin/AIX do double-word
+		alignment of the struct if the first element is a double.
+		Check that it does here.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030914	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_9byte {
+  double a;
+  int b;
+} cls_struct_9byte;
+
+cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1,
+			    struct cls_struct_9byte b2)
+{
+  struct cls_struct_9byte result;
+
+  result.a = b1.a + b2.a;
+  result.b = b1.b + b2.b;
+
+  printf("%g %d %g %d: %g %d\n", b1.a, b1.b,  b2.a, b2.b,
+	 result.a, result.b);
+
+  return result;
+}
+
+static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
+				void** args, void* userdata __UNUSED__)
+{
+  struct cls_struct_9byte b1, b2;
+
+  b1 = *(struct cls_struct_9byte*)(args[0]);
+  b2 = *(struct cls_struct_9byte*)(args[1]);
+
+  *(cls_struct_9byte*)resp = cls_struct_9byte_fn(b1, b2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[3];
+  ffi_type* cls_struct_fields[3];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[3];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_9byte h_dbl = { 7.0, 8};
+  struct cls_struct_9byte j_dbl = { 1.0, 9};
+  struct cls_struct_9byte res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_double;
+  cls_struct_fields[1] = &ffi_type_sint;
+  cls_struct_fields[2] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &h_dbl;
+  args_dbl[1] = &j_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_9byte_fn), &res_dbl, args_dbl);
+  /* { dg-output "7 8 1 9: 8 17" } */
+  printf("res: %g %d\n", res_dbl.a, res_dbl.b);
+  /* { dg-output "\nres: 8 17" } */
+
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_9byte_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(code))(h_dbl, j_dbl);
+  /* { dg-output "\n7 8 1 9: 8 17" } */
+  printf("res: %g %d\n", res_dbl.a, res_dbl.b);
+  /* { dg-output "\nres: 8 17" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c
new file mode 100755
index 0000000..22b94d5
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c
@@ -0,0 +1,93 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure alignment of double.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<hos at tamanegi.org> 20031203	 */
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+  unsigned char a;
+  double b;
+  unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+			    struct cls_struct_align a2)
+{
+  struct cls_struct_align result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+
+  printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+  return  result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_align a1, a2;
+
+  a1 = *(struct cls_struct_align*)(args[0]);
+  a2 = *(struct cls_struct_align*)(args[1]);
+
+  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_double;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c
new file mode 100755
index 0000000..62637f2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c
@@ -0,0 +1,91 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure alignment of float.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<hos at tamanegi.org> 20031203	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+  unsigned char a;
+  float b;
+  unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+			    struct cls_struct_align a2)
+{
+  struct cls_struct_align result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+
+  printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, (double)a1.b, a1.c, a2.a, (double)a2.b, a2.c, result.a, (double)result.b, result.c);
+
+  return  result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_align a1, a2;
+
+  a1 = *(struct cls_struct_align*)(args[0]);
+  a2 = *(struct cls_struct_align*)(args[1]);
+
+  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_float;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c
new file mode 100755
index 0000000..af38060
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c
@@ -0,0 +1,92 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure alignment of long double.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<hos at tamanegi.org> 20031203	 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+  unsigned char a;
+  long double b;
+  unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+			    struct cls_struct_align a2)
+{
+  struct cls_struct_align result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+
+  printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, (double)a1.b, a1.c, a2.a, (double)a2.b, a2.c, result.a, (double)result.b, result.c);
+
+  return  result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_align a1, a2;
+
+  a1 = *(struct cls_struct_align*)(args[0]);
+  a2 = *(struct cls_struct_align*)(args[1]);
+
+  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_longdouble;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c
new file mode 100755
index 0000000..a3732bd
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c
@@ -0,0 +1,134 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure alignment of long double.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<hos at tamanegi.org> 20031203	 */
+
+/* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
+/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
+
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+  long double a;
+  long double b;
+  long double c;
+  long double d;
+  long double e;
+  long double f;
+  long double g;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(
+	cls_struct_align	a1,
+	cls_struct_align	a2)
+{
+	struct cls_struct_align r;
+
+	r.a = a1.a + a2.a;
+	r.b = a1.b + a2.b;
+	r.c = a1.c + a2.c;
+	r.d = a1.d + a2.d;
+	r.e = a1.e + a2.e;
+	r.f = a1.f + a2.f;
+	r.g = a1.g + a2.g;
+
+	printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg: "
+		"%Lg %Lg %Lg %Lg %Lg %Lg %Lg\n",
+		a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
+		a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
+		r.a, r.b, r.c, r.d, r.e, r.f, r.g);
+
+	return r;
+}
+
+cls_struct_align cls_struct_align_fn2(
+	cls_struct_align	a1)
+{
+	struct cls_struct_align r;
+
+	r.a = a1.a + 1;
+	r.b = a1.b + 1;
+	r.c = a1.c + 1;
+	r.d = a1.d + 1;
+	r.e = a1.e + 1;
+	r.f = a1.f + 1;
+	r.g = a1.g + 1;
+
+	printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg: "
+		"%Lg %Lg %Lg %Lg %Lg %Lg %Lg\n",
+		a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
+		r.a, r.b, r.c, r.d, r.e, r.f, r.g);
+
+	return r;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, 
+		    void* userdata __UNUSED__)
+{
+	struct cls_struct_align a1, a2;
+
+	a1 = *(struct cls_struct_align*)(args[0]);
+	a2 = *(struct cls_struct_align*)(args[1]);
+
+	*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+	ffi_cif cif;
+        void *code;
+	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+	void* args_dbl[3];
+	ffi_type* cls_struct_fields[8];
+	ffi_type cls_struct_type;
+	ffi_type* dbl_arg_types[3];
+
+	cls_struct_type.size = 0;
+	cls_struct_type.alignment = 0;
+	cls_struct_type.type = FFI_TYPE_STRUCT;
+	cls_struct_type.elements = cls_struct_fields;
+
+	struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
+	struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
+	struct cls_struct_align res_dbl;
+
+	cls_struct_fields[0] = &ffi_type_longdouble;
+	cls_struct_fields[1] = &ffi_type_longdouble;
+	cls_struct_fields[2] = &ffi_type_longdouble;
+	cls_struct_fields[3] = &ffi_type_longdouble;
+	cls_struct_fields[4] = &ffi_type_longdouble;
+	cls_struct_fields[5] = &ffi_type_longdouble;
+	cls_struct_fields[6] = &ffi_type_longdouble;
+	cls_struct_fields[7] = NULL;
+
+	dbl_arg_types[0] = &cls_struct_type;
+	dbl_arg_types[1] = &cls_struct_type;
+	dbl_arg_types[2] = NULL;
+
+	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		dbl_arg_types) == FFI_OK);
+
+	args_dbl[0] = &g_dbl;
+	args_dbl[1] = &f_dbl;
+	args_dbl[2] = NULL;
+
+	ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+	/* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
+	printf("res: %Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", res_dbl.a, res_dbl.b,
+		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+	/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
+
+	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+	res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+	/* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
+	printf("res: %Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", res_dbl.a, res_dbl.b,
+		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+	/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c
new file mode 100755
index 0000000..63a0f76
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c
@@ -0,0 +1,117 @@
+/*	Area:			ffi_call, closure_call
+	Purpose:		Check structure alignment of long double.
+	Limitations:	none.
+	PR:				none.
+	Originator:		Blake Chaffin	6/18/2007
+*/
+
+/* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
+/* { dg-do run { xfail strongarm*-*-* } } */
+/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
+/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
+
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+  long double a;
+  long double b;
+  long double c;
+  long double d;
+  long double e;
+  double f;
+  long double g;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(
+	cls_struct_align	a1,
+	cls_struct_align	a2)
+{
+	struct cls_struct_align r;
+
+	r.a = a1.a + a2.a;
+	r.b = a1.b + a2.b;
+	r.c = a1.c + a2.c;
+	r.d = a1.d + a2.d;
+	r.e = a1.e + a2.e;
+	r.f = a1.f + a2.f;
+	r.g = a1.g + a2.g;
+
+	printf("%Lg %Lg %Lg %Lg %Lg %g %Lg %Lg %Lg %Lg %Lg %Lg %g %Lg: "
+		"%Lg %Lg %Lg %Lg %Lg %g %Lg\n",
+		a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
+		a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
+		r.a, r.b, r.c, r.d, r.e, r.f, r.g);
+
+	return r;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, 
+		    void* userdata __UNUSED__)
+{
+	struct cls_struct_align a1, a2;
+
+	a1 = *(struct cls_struct_align*)(args[0]);
+	a2 = *(struct cls_struct_align*)(args[1]);
+
+	*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+	ffi_cif cif;
+        void *code;
+	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+	void* args_dbl[3];
+	ffi_type* cls_struct_fields[8];
+	ffi_type cls_struct_type;
+	ffi_type* dbl_arg_types[3];
+
+	cls_struct_type.size = 0;
+	cls_struct_type.alignment = 0;
+	cls_struct_type.type = FFI_TYPE_STRUCT;
+	cls_struct_type.elements = cls_struct_fields;
+
+	struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
+	struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
+	struct cls_struct_align res_dbl;
+
+	cls_struct_fields[0] = &ffi_type_longdouble;
+	cls_struct_fields[1] = &ffi_type_longdouble;
+	cls_struct_fields[2] = &ffi_type_longdouble;
+	cls_struct_fields[3] = &ffi_type_longdouble;
+	cls_struct_fields[4] = &ffi_type_longdouble;
+	cls_struct_fields[5] = &ffi_type_double;
+	cls_struct_fields[6] = &ffi_type_longdouble;
+	cls_struct_fields[7] = NULL;
+
+	dbl_arg_types[0] = &cls_struct_type;
+	dbl_arg_types[1] = &cls_struct_type;
+	dbl_arg_types[2] = NULL;
+
+	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		dbl_arg_types) == FFI_OK);
+
+	args_dbl[0] = &g_dbl;
+	args_dbl[1] = &f_dbl;
+	args_dbl[2] = NULL;
+
+	ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+	/* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
+	printf("res: %Lg %Lg %Lg %Lg %Lg %g %Lg\n", res_dbl.a, res_dbl.b,
+		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+	/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
+
+	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+	res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+	/* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
+	printf("res: %Lg %Lg %Lg %Lg %Lg %g %Lg\n", res_dbl.a, res_dbl.b,
+		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+	/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
+
+  exit(0);
+}
+
+
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c
new file mode 100755
index 0000000..cbc4f95
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c
@@ -0,0 +1,95 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure alignment of pointer.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<hos at tamanegi.org> 20031203	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+  unsigned char a;
+  void *b;
+  unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+			    struct cls_struct_align a2)
+{
+  struct cls_struct_align result;
+
+  result.a = a1.a + a2.a;
+  result.b = (void *)((uintptr_t)a1.b + (uintptr_t)a2.b);
+  result.c = a1.c + a2.c;
+
+  printf("%d %" PRIuPTR " %d %d %" PRIuPTR " %d: %d %" PRIuPTR " %d\n", 
+         a1.a, (uintptr_t)a1.b, a1.c,
+	 a2.a, (uintptr_t)a2.b, a2.c,
+         result.a, (uintptr_t)result.b,
+	 result.c);
+
+  return result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_align a1, a2;
+
+  a1 = *(struct cls_struct_align*)(args[0]);
+  a2 = *(struct cls_struct_align*)(args[1]);
+
+  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_align g_dbl = { 12, (void *)4951, 127 };
+  struct cls_struct_align f_dbl = { 1, (void *)9320, 13 };
+  struct cls_struct_align res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_pointer;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %" PRIuPTR " %d\n", res_dbl.a, (uintptr_t)res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %" PRIuPTR " %d\n", res_dbl.a, (uintptr_t)res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c
new file mode 100755
index 0000000..383ea41
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c
@@ -0,0 +1,91 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure alignment of sint16.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<hos at tamanegi.org> 20031203	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+  unsigned char a;
+  signed short b;
+  unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+			    struct cls_struct_align a2)
+{
+  struct cls_struct_align result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+
+  printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+  return  result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_align a1, a2;
+
+  a1 = *(struct cls_struct_align*)(args[0]);
+  a2 = *(struct cls_struct_align*)(args[1]);
+
+  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_sshort;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c
new file mode 100755
index 0000000..705d78c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c
@@ -0,0 +1,91 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure alignment of sint32.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<hos at tamanegi.org> 20031203	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+  unsigned char a;
+  signed int b;
+  unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+			    struct cls_struct_align a2)
+{
+  struct cls_struct_align result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+
+  printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+  return  result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_align a1, a2;
+
+  a1 = *(struct cls_struct_align*)(args[0]);
+  a2 = *(struct cls_struct_align*)(args[1]);
+
+  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_sint;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c
new file mode 100755
index 0000000..31d53af
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c
@@ -0,0 +1,92 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure alignment of sint64.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<hos at tamanegi.org> 20031203	 */
+
+/* { dg-do run } */
+/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+  unsigned char a;
+  signed long long b;
+  unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+			    struct cls_struct_align a2)
+{
+  struct cls_struct_align result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+
+  printf("%d %" PRIdLL " %d %d %" PRIdLL " %d: %d %" PRIdLL " %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+  return  result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_align a1, a2;
+
+  a1 = *(struct cls_struct_align*)(args[0]);
+  a2 = *(struct cls_struct_align*)(args[1]);
+
+  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_sint64;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c
new file mode 100755
index 0000000..cb6b748
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c
@@ -0,0 +1,91 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure alignment of uint16.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<hos at tamanegi.org> 20031203	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+  unsigned char a;
+  unsigned short b;
+  unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+			    struct cls_struct_align a2)
+{
+  struct cls_struct_align result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+
+  printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+  return  result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_align a1, a2;
+
+  a1 = *(struct cls_struct_align*)(args[0]);
+  a2 = *(struct cls_struct_align*)(args[1]);
+
+  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_ushort;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c
new file mode 100755
index 0000000..e453d3e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c
@@ -0,0 +1,91 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure alignment of uint32.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<hos at tamanegi.org> 20031203	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+  unsigned char a;
+  unsigned int b;
+  unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+			    struct cls_struct_align a2)
+{
+  struct cls_struct_align result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+
+  printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+  return  result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_align a1, a2;
+
+  a1 = *(struct cls_struct_align*)(args[0]);
+  a2 = *(struct cls_struct_align*)(args[1]);
+
+  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_uint;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c
new file mode 100755
index 0000000..495c79f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c
@@ -0,0 +1,93 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure alignment of uint64.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<hos at tamanegi.org> 20031203	 */
+
+
+/* { dg-do run } */
+/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+  unsigned char a;
+  unsigned long long b;
+  unsigned char c;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
+			    struct cls_struct_align a2)
+{
+  struct cls_struct_align result;
+
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+
+  printf("%d %" PRIdLL " %d %d %" PRIdLL " %d: %d %" PRIdLL " %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+  return  result;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		    void* userdata __UNUSED__)
+{
+
+  struct cls_struct_align a1, a2;
+
+  a1 = *(struct cls_struct_align*)(args[0]);
+  a2 = *(struct cls_struct_align*)(args[1]);
+
+  *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[4];
+  ffi_type cls_struct_type;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_uint64;
+  cls_struct_fields[2] = &ffi_type_uchar;
+  cls_struct_fields[3] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &g_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
+  printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+  /* { dg-output "\nres: 13 14271 140" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_dbls_struct.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_dbls_struct.c
new file mode 100755
index 0000000..660dabb
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_dbls_struct.c
@@ -0,0 +1,66 @@
+/* Area:		ffi_call, closure_call
+   Purpose:		Check double arguments in structs.
+   Limitations:	none.
+   PR:			none.
+   Originator:	Blake Chaffin 6/23/2007	*/
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+typedef struct Dbls {
+	double x;
+	double y;
+} Dbls;
+
+void
+closure_test_fn(Dbls p)
+{
+	printf("%.1f %.1f\n", p.x, p.y);
+}
+
+void
+closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
+		void** args, void* userdata __UNUSED__)
+{
+	closure_test_fn(*(Dbls*)args[0]);
+}
+
+int main(int argc __UNUSED__, char** argv __UNUSED__)
+{
+	ffi_cif cif;
+
+        void *code;
+	ffi_closure*	pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+	ffi_type*		cl_arg_types[1];
+
+	ffi_type	ts1_type;
+	ffi_type*	ts1_type_elements[4];
+
+	ts1_type.size = 0;
+	ts1_type.alignment = 0;
+	ts1_type.type = FFI_TYPE_STRUCT;
+	ts1_type.elements = ts1_type_elements;
+
+	ts1_type_elements[0] = &ffi_type_double;
+	ts1_type_elements[1] = &ffi_type_double;
+	ts1_type_elements[2] = NULL;
+
+	cl_arg_types[0] = &ts1_type;
+
+	Dbls arg = { 1.0, 2.0 };
+
+	/* Initialize the cif */
+	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+				 &ffi_type_void, cl_arg_types) == FFI_OK);
+
+	CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK);
+
+	((void*(*)(Dbls))(code))(arg);
+	/* { dg-output "1.0 2.0\n" } */
+
+	closure_test_fn(arg);
+	/* { dg-output "1.0 2.0\n" } */
+
+	return 0;
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_double.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_double.c
new file mode 100755
index 0000000..84ad4cb
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_double.c
@@ -0,0 +1,43 @@
+/* Area:	closure_call
+   Purpose:	Check return value double.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+			      void* userdata __UNUSED__)
+ {
+   *(double *)resp = *(double *)args[0];
+
+   printf("%f: %f\n",*(double *)args[0],
+	  *(double *)resp);
+ }
+typedef double (*cls_ret_double)(double);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[2];
+  double res;
+
+  cl_arg_types[0] = &ffi_type_double;
+  cl_arg_types[1] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_double, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code)  == FFI_OK);
+
+  res = (*((cls_ret_double)code))(21474.789);
+  /* { dg-output "21474.789000: 21474.789000" } */
+  printf("res: %.6f\n", res);
+  /* { dg-output "\nres: 21474.789000" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c
new file mode 100755
index 0000000..e769caf
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c
@@ -0,0 +1,60 @@
+/* Area:		ffi_call, closure_call
+   Purpose:		Test doubles passed in variable argument lists.
+   Limitations:	none.
+   PR:			none.
+   Originator:	Blake Chaffin 6/6/2007	 */
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+/* { dg-output "" { xfail avr32*-*-* } } */
+/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
+/* { dg-skip-if "" arm*-*-* { "-mfloat-abi=hard" } { "" } } */
+
+#include "ffitest.h"
+
+static void
+cls_double_va_fn(ffi_cif* cif __UNUSED__, void* resp, 
+		 void** args, void* userdata __UNUSED__)
+{
+	char*	format		= *(char**)args[0];
+	double	doubleValue	= *(double*)args[1];
+
+	*(ffi_arg*)resp = printf(format, doubleValue);
+}
+
+int main (void)
+{
+	ffi_cif cif;
+        void *code;
+	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+	void* args[3];
+	ffi_type* arg_types[3];
+
+	char*	format		= "%.1f\n";
+	double	doubleArg	= 7;
+	ffi_arg	res			= 0;
+
+	arg_types[0] = &ffi_type_pointer;
+	arg_types[1] = &ffi_type_double;
+	arg_types[2] = NULL;
+
+	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint,
+		arg_types) == FFI_OK);
+
+	args[0] = &format;
+	args[1] = &doubleArg;
+	args[2] = NULL;
+
+	ffi_call(&cif, FFI_FN(printf), &res, args);
+	// { dg-output "7.0" }
+	printf("res: %d\n", (int) res);
+	// { dg-output "\nres: 4" }
+
+	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL, code) == FFI_OK);
+
+	res	= ((int(*)(char*, double))(code))(format, doubleArg);
+	// { dg-output "\n7.0" }
+	printf("res: %d\n", (int) res);
+	// { dg-output "\nres: 4" }
+
+	exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_float.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_float.c
new file mode 100755
index 0000000..0090fed
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_float.c
@@ -0,0 +1,42 @@
+/* Area:	closure_call
+   Purpose:	Check return value float.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_float_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+			     void* userdata __UNUSED__)
+ {
+   *(float *)resp = *(float *)args[0];
+
+   printf("%g: %g\n",*(float *)args[0],
+	  *(float *)resp);
+ }
+
+typedef float (*cls_ret_float)(float);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[2];
+  float res;
+
+  cl_arg_types[0] = &ffi_type_float;
+  cl_arg_types[1] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_float, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_float_fn, NULL, code)  == FFI_OK);
+  res = ((((cls_ret_float)code)(-2122.12)));
+  /* { dg-output "\\-2122.12: \\-2122.12" } */
+  printf("res: %.6f\n", res);
+  /* { dg-output "\nres: \-2122.120117" } */
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c
new file mode 100755
index 0000000..e6bac1f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c
@@ -0,0 +1,105 @@
+/* Area:		ffi_call, closure_call
+   Purpose:		Check long double arguments.
+   Limitations:	none.
+   PR:			none.
+   Originator:	Blake Chaffin	*/
+
+/* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
+/* { dg-do run { xfail arm*-*-* strongarm*-*-* xscale*-*-* } } */
+/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
+/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
+
+#include "ffitest.h"
+
+long double cls_ldouble_fn(
+	long double	a1,
+	long double	a2,
+	long double	a3,
+	long double	a4,
+	long double	a5,
+	long double	a6,
+	long double	a7,
+	long double	a8)
+{
+	long double	r = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
+
+	printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg: %Lg\n",
+		a1, a2, a3, a4, a5, a6, a7, a8, r);
+
+	return r;
+}
+
+static void
+cls_ldouble_gn(ffi_cif* cif __UNUSED__, void* resp, 
+	       void** args, void* userdata __UNUSED__)
+{
+	long double	a1	= *(long double*)args[0];
+	long double	a2	= *(long double*)args[1];
+	long double	a3	= *(long double*)args[2];
+	long double	a4	= *(long double*)args[3];
+	long double	a5	= *(long double*)args[4];
+	long double	a6	= *(long double*)args[5];
+	long double	a7	= *(long double*)args[6];
+	long double	a8	= *(long double*)args[7];
+
+	*(long double*)resp = cls_ldouble_fn(
+		a1, a2, a3, a4, a5, a6, a7, a8);
+}
+
+int main(void)
+{
+	ffi_cif	cif;
+        void* code;
+	ffi_closure*	pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+	void*			args[9];
+	ffi_type*		arg_types[9];
+	long double		res	= 0;
+
+	long double	arg1	= 1;
+	long double	arg2	= 2;
+	long double	arg3	= 3;
+	long double	arg4	= 4;
+	long double	arg5	= 5;
+	long double	arg6	= 6;
+	long double	arg7	= 7;
+	long double	arg8	= 8;
+
+	arg_types[0] = &ffi_type_longdouble;
+	arg_types[1] = &ffi_type_longdouble;
+	arg_types[2] = &ffi_type_longdouble;
+	arg_types[3] = &ffi_type_longdouble;
+	arg_types[4] = &ffi_type_longdouble;
+	arg_types[5] = &ffi_type_longdouble;
+	arg_types[6] = &ffi_type_longdouble;
+	arg_types[7] = &ffi_type_longdouble;
+	arg_types[8] = NULL;
+
+	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 8, &ffi_type_longdouble,
+		arg_types) == FFI_OK);
+
+	args[0] = &arg1;
+	args[1] = &arg2;
+	args[2] = &arg3;
+	args[3] = &arg4;
+	args[4] = &arg5;
+	args[5] = &arg6;
+	args[6] = &arg7;
+	args[7] = &arg8;
+	args[8] = NULL;
+
+	ffi_call(&cif, FFI_FN(cls_ldouble_fn), &res, args);
+	/* { dg-output "1 2 3 4 5 6 7 8: 36" } */
+	printf("res: %Lg\n", res);
+	/* { dg-output "\nres: 36" } */
+
+	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ldouble_gn, NULL, code) == FFI_OK);
+
+	res = ((long double(*)(long double, long double, long double, long double,
+		long double, long double, long double, long double))(code))(arg1, arg2,
+		arg3, arg4, arg5, arg6, arg7, arg8);
+	/* { dg-output "\n1 2 3 4 5 6 7 8: 36" } */
+	printf("res: %Lg\n", res);
+	/* { dg-output "\nres: 36" } */
+
+	return 0;
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c
new file mode 100755
index 0000000..07780ed
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c
@@ -0,0 +1,60 @@
+/* Area:		ffi_call, closure_call
+   Purpose:		Test long doubles passed in variable argument lists.
+   Limitations:	none.
+   PR:			none.
+   Originator:	Blake Chaffin 6/6/2007	 */
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+/* { dg-output "" { xfail avr32*-*-* x86_64-*-mingw* } } */
+/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
+/* { dg-skip-if "" arm*-*-* { "-mfloat-abi=hard" } { "" } } */
+
+#include "ffitest.h"
+
+static void
+cls_longdouble_va_fn(ffi_cif* cif __UNUSED__, void* resp, 
+		     void** args, void* userdata __UNUSED__)
+{
+	char*		format	= *(char**)args[0];
+	long double	ldValue	= *(long double*)args[1];
+
+	*(ffi_arg*)resp = printf(format, ldValue);
+}
+
+int main (void)
+{
+	ffi_cif cif;
+        void *code;
+	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+	void* args[3];
+	ffi_type* arg_types[3];
+
+	char*		format	= "%.1Lf\n";
+	long double	ldArg	= 7;
+	ffi_arg		res		= 0;
+
+	arg_types[0] = &ffi_type_pointer;
+	arg_types[1] = &ffi_type_longdouble;
+	arg_types[2] = NULL;
+
+	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint,
+		arg_types) == FFI_OK);
+
+	args[0] = &format;
+	args[1] = &ldArg;
+	args[2] = NULL;
+
+	ffi_call(&cif, FFI_FN(printf), &res, args);
+	// { dg-output "7.0" }
+	printf("res: %d\n", (int) res);
+	// { dg-output "\nres: 4" }
+
+	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL, code) == FFI_OK);
+
+	res	= ((int(*)(char*, long double))(code))(format, ldArg);
+	// { dg-output "\n7.0" }
+	printf("res: %d\n", (int) res);
+	// { dg-output "\nres: 4" }
+
+	exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_schar.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_schar.c
new file mode 100755
index 0000000..71df7b6
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_schar.c
@@ -0,0 +1,74 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check passing of multiple signed char values.
+   Limitations:	none.
+   PR:		PR13221.
+   Originator:	<hos at tamanegi.org> 20031129  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+signed char test_func_fn(signed char a1, signed char a2)
+{
+  signed char result;
+
+  result = a1 + a2;
+
+  printf("%d %d: %d\n", a1, a2, result);
+
+  return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+			 void *data __UNUSED__)
+{
+  signed char a1, a2;
+
+  a1 = *(signed char *)avals[0];
+  a2 = *(signed char *)avals[1];
+
+  *(ffi_arg *)rval = test_func_fn(a1, a2);
+
+}
+
+typedef signed char (*test_type)(signed char, signed char);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void * args_dbl[3];
+  ffi_type * cl_arg_types[3];
+  ffi_arg res_call;
+  signed char a, b, res_closure;
+
+  a = 2;
+  b = 125;
+
+  args_dbl[0] = &a;
+  args_dbl[1] = &b;
+  args_dbl[2] = NULL;
+
+  cl_arg_types[0] = &ffi_type_schar;
+  cl_arg_types[1] = &ffi_type_schar;
+  cl_arg_types[2] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+		     &ffi_type_schar, cl_arg_types) == FFI_OK);
+
+  ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+  /* { dg-output "2 125: 127" } */
+  printf("res: %d\n", (signed char)res_call);
+  /* { dg-output "\nres: 127" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code)  == FFI_OK);
+
+  res_closure = (*((test_type)code))(2, 125);
+  /* { dg-output "\n2 125: 127" } */
+  printf("res: %d\n", res_closure);
+  /* { dg-output "\nres: 127" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshort.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshort.c
new file mode 100755
index 0000000..4c39153
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshort.c
@@ -0,0 +1,74 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check passing of multiple signed short values.
+   Limitations:	none.
+   PR:		PR13221.
+   Originator:	<andreast at gcc.gnu.org> 20031129  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+signed short test_func_fn(signed short a1, signed short a2)
+{
+  signed short result;
+
+  result = a1 + a2;
+
+  printf("%d %d: %d\n", a1, a2, result);
+
+  return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+			 void *data __UNUSED__)
+{
+  signed short a1, a2;
+
+  a1 = *(signed short *)avals[0];
+  a2 = *(signed short *)avals[1];
+
+  *(ffi_arg *)rval = test_func_fn(a1, a2);
+
+}
+
+typedef signed short (*test_type)(signed short, signed short);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void * args_dbl[3];
+  ffi_type * cl_arg_types[3];
+  ffi_arg res_call;
+  unsigned short a, b, res_closure;
+
+  a = 2;
+  b = 32765;
+
+  args_dbl[0] = &a;
+  args_dbl[1] = &b;
+  args_dbl[2] = NULL;
+
+  cl_arg_types[0] = &ffi_type_sshort;
+  cl_arg_types[1] = &ffi_type_sshort;
+  cl_arg_types[2] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+		     &ffi_type_sshort, cl_arg_types) == FFI_OK);
+
+  ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+  /* { dg-output "2 32765: 32767" } */
+  printf("res: %d\n", (unsigned short)res_call);
+  /* { dg-output "\nres: 32767" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code)  == FFI_OK);
+
+  res_closure = (*((test_type)code))(2, 32765);
+  /* { dg-output "\n2 32765: 32767" } */
+  printf("res: %d\n", res_closure);
+  /* { dg-output "\nres: 32767" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshortchar.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshortchar.c
new file mode 100755
index 0000000..1c3aeb5
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshortchar.c
@@ -0,0 +1,86 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check passing of multiple signed short/char values.
+   Limitations:	none.
+   PR:		PR13221.
+   Originator:	<andreast at gcc.gnu.org> 20031129  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+signed short test_func_fn(signed char a1, signed short a2,
+			  signed char a3, signed short a4)
+{
+  signed short result;
+
+  result = a1 + a2 + a3 + a4;
+
+  printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result);
+
+  return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+			 void *data __UNUSED__)
+{
+  signed char a1, a3;
+  signed short a2, a4;
+
+  a1 = *(signed char *)avals[0];
+  a2 = *(signed short *)avals[1];
+  a3 = *(signed char *)avals[2];
+  a4 = *(signed short *)avals[3];
+
+  *(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4);
+
+}
+
+typedef signed short (*test_type)(signed char, signed short,
+				  signed char, signed short);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void * args_dbl[5];
+  ffi_type * cl_arg_types[5];
+  ffi_arg res_call;
+  signed char a, c;
+  signed short b, d, res_closure;
+
+  a = 1;
+  b = 32765;
+  c = 127;
+  d = -128;
+
+  args_dbl[0] = &a;
+  args_dbl[1] = &b;
+  args_dbl[2] = &c;
+  args_dbl[3] = &d;
+  args_dbl[4] = NULL;
+
+  cl_arg_types[0] = &ffi_type_schar;
+  cl_arg_types[1] = &ffi_type_sshort;
+  cl_arg_types[2] = &ffi_type_schar;
+  cl_arg_types[3] = &ffi_type_sshort;
+  cl_arg_types[4] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+		     &ffi_type_sshort, cl_arg_types) == FFI_OK);
+
+  ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+  /* { dg-output "1 32765 127 -128: 32765" } */
+  printf("res: %d\n", (signed short)res_call);
+  /* { dg-output "\nres: 32765" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code)  == FFI_OK);
+
+  res_closure = (*((test_type)code))(1, 32765, 127, -128);
+  /* { dg-output "\n1 32765 127 -128: 32765" } */
+  printf("res: %d\n", res_closure);
+  /* { dg-output "\nres: 32765" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_uchar.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_uchar.c
new file mode 100755
index 0000000..009c02c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_uchar.c
@@ -0,0 +1,91 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check passing of multiple unsigned char values.
+   Limitations:	none.
+   PR:		PR13221.
+   Originator:	<andreast at gcc.gnu.org> 20031129  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+unsigned char test_func_fn(unsigned char a1, unsigned char a2,
+			   unsigned char a3, unsigned char a4)
+{
+  unsigned char result;
+
+  result = a1 + a2 + a3 + a4;
+
+  printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result);
+
+  return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+			 void *data __UNUSED__)
+{
+  unsigned char a1, a2, a3, a4;
+
+  a1 = *(unsigned char *)avals[0];
+  a2 = *(unsigned char *)avals[1];
+  a3 = *(unsigned char *)avals[2];
+  a4 = *(unsigned char *)avals[3];
+
+  *(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4);
+
+}
+
+typedef unsigned char (*test_type)(unsigned char, unsigned char,
+				   unsigned char, unsigned char);
+
+void test_func(ffi_cif *cif __UNUSED__, void *rval __UNUSED__, void **avals,
+	       void *data __UNUSED__)
+{
+  printf("%d %d %d %d\n", *(unsigned char *)avals[0],
+	 *(unsigned char *)avals[1], *(unsigned char *)avals[2],
+	 *(unsigned char *)avals[3]);
+}
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void * args_dbl[5];
+  ffi_type * cl_arg_types[5];
+  ffi_arg res_call;
+  unsigned char a, b, c, d, res_closure;
+
+  a = 1;
+  b = 2;
+  c = 127;
+  d = 125;
+
+  args_dbl[0] = &a;
+  args_dbl[1] = &b;
+  args_dbl[2] = &c;
+  args_dbl[3] = &d;
+  args_dbl[4] = NULL;
+
+  cl_arg_types[0] = &ffi_type_uchar;
+  cl_arg_types[1] = &ffi_type_uchar;
+  cl_arg_types[2] = &ffi_type_uchar;
+  cl_arg_types[3] = &ffi_type_uchar;
+  cl_arg_types[4] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+		     &ffi_type_uchar, cl_arg_types) == FFI_OK);
+
+  ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+  /* { dg-output "1 2 127 125: 255" } */
+  printf("res: %d\n", (unsigned char)res_call);
+  /* { dg-output "\nres: 255" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code)  == FFI_OK);
+
+  res_closure = (*((test_type)code))(1, 2, 127, 125);
+  /* { dg-output "\n1 2 127 125: 255" } */
+  printf("res: %d\n", res_closure);
+  /* { dg-output "\nres: 255" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushort.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushort.c
new file mode 100755
index 0000000..dd10ca7
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushort.c
@@ -0,0 +1,74 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check passing of multiple unsigned short values.
+   Limitations:	none.
+   PR:		PR13221.
+   Originator:	<andreast at gcc.gnu.org> 20031129  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+unsigned short test_func_fn(unsigned short a1, unsigned short a2)
+{
+  unsigned short result;
+
+  result = a1 + a2;
+
+  printf("%d %d: %d\n", a1, a2, result);
+
+  return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+			 void *data __UNUSED__)
+{
+  unsigned short a1, a2;
+
+  a1 = *(unsigned short *)avals[0];
+  a2 = *(unsigned short *)avals[1];
+
+  *(ffi_arg *)rval = test_func_fn(a1, a2);
+
+}
+
+typedef unsigned short (*test_type)(unsigned short, unsigned short);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void * args_dbl[3];
+  ffi_type * cl_arg_types[3];
+  ffi_arg res_call;
+  unsigned short a, b, res_closure;
+
+  a = 2;
+  b = 32765;
+
+  args_dbl[0] = &a;
+  args_dbl[1] = &b;
+  args_dbl[2] = NULL;
+
+  cl_arg_types[0] = &ffi_type_ushort;
+  cl_arg_types[1] = &ffi_type_ushort;
+  cl_arg_types[2] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+		     &ffi_type_ushort, cl_arg_types) == FFI_OK);
+
+  ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+  /* { dg-output "2 32765: 32767" } */
+  printf("res: %d\n", (unsigned short)res_call);
+  /* { dg-output "\nres: 32767" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code)  == FFI_OK);
+
+  res_closure = (*((test_type)code))(2, 32765);
+  /* { dg-output "\n2 32765: 32767" } */
+  printf("res: %d\n", res_closure);
+  /* { dg-output "\nres: 32767" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushortchar.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushortchar.c
new file mode 100755
index 0000000..2588e97
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushortchar.c
@@ -0,0 +1,86 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check passing of multiple unsigned short/char values.
+   Limitations:	none.
+   PR:		PR13221.
+   Originator:	<andreast at gcc.gnu.org> 20031129  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+unsigned short test_func_fn(unsigned char a1, unsigned short a2,
+			    unsigned char a3, unsigned short a4)
+{
+  unsigned short result;
+
+  result = a1 + a2 + a3 + a4;
+
+  printf("%d %d %d %d: %d\n", a1, a2, a3, a4, result);
+
+  return result;
+
+}
+
+static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
+			 void *data __UNUSED__)
+{
+  unsigned char a1, a3;
+  unsigned short a2, a4;
+
+  a1 = *(unsigned char *)avals[0];
+  a2 = *(unsigned short *)avals[1];
+  a3 = *(unsigned char *)avals[2];
+  a4 = *(unsigned short *)avals[3];
+
+  *(ffi_arg *)rval = test_func_fn(a1, a2, a3, a4);
+
+}
+
+typedef unsigned short (*test_type)(unsigned char, unsigned short,
+				   unsigned char, unsigned short);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void * args_dbl[5];
+  ffi_type * cl_arg_types[5];
+  ffi_arg res_call;
+  unsigned char a, c;
+  unsigned short b, d, res_closure;
+
+  a = 1;
+  b = 2;
+  c = 127;
+  d = 128;
+
+  args_dbl[0] = &a;
+  args_dbl[1] = &b;
+  args_dbl[2] = &c;
+  args_dbl[3] = &d;
+  args_dbl[4] = NULL;
+
+  cl_arg_types[0] = &ffi_type_uchar;
+  cl_arg_types[1] = &ffi_type_ushort;
+  cl_arg_types[2] = &ffi_type_uchar;
+  cl_arg_types[3] = &ffi_type_ushort;
+  cl_arg_types[4] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+		     &ffi_type_ushort, cl_arg_types) == FFI_OK);
+
+  ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
+  /* { dg-output "1 2 127 128: 258" } */
+  printf("res: %d\n", (unsigned short)res_call);
+  /* { dg-output "\nres: 258" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code)  == FFI_OK);
+
+  res_closure = (*((test_type)code))(1, 2, 127, 128);
+  /* { dg-output "\n1 2 127 128: 258" } */
+  printf("res: %d\n", res_closure);
+  /* { dg-output "\nres: 258" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c
new file mode 100755
index 0000000..cf03993
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c
@@ -0,0 +1,74 @@
+/* Area:		ffi_call, closure_call
+   Purpose:		Check pointer arguments.
+   Limitations:	none.
+   PR:			none.
+   Originator:	Blake Chaffin 6/6/2007	*/
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+#include "ffitest.h"
+
+void* cls_pointer_fn(void* a1, void* a2)
+{
+	void*	result	= (void*)((intptr_t)a1 + (intptr_t)a2);
+
+	printf("0x%08x 0x%08x: 0x%08x\n", 
+	       (unsigned int)(uintptr_t) a1,
+               (unsigned int)(uintptr_t) a2,
+               (unsigned int)(uintptr_t) result);
+
+	return result;
+}
+
+static void
+cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp, 
+	       void** args, void* userdata __UNUSED__)
+{
+	void*	a1	= *(void**)(args[0]);
+	void*	a2	= *(void**)(args[1]);
+
+	*(void**)resp = cls_pointer_fn(a1, a2);
+}
+
+int main (void)
+{
+	ffi_cif	cif;
+        void *code;
+	ffi_closure*	pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+	void*			args[3];
+//	ffi_type		cls_pointer_type;
+	ffi_type*		arg_types[3];
+
+/*	cls_pointer_type.size = sizeof(void*);
+	cls_pointer_type.alignment = 0;
+	cls_pointer_type.type = FFI_TYPE_POINTER;
+	cls_pointer_type.elements = NULL;*/
+
+	void*	arg1	= (void*)0x12345678;
+	void*	arg2	= (void*)0x89abcdef;
+	ffi_arg	res		= 0;
+
+	arg_types[0] = &ffi_type_pointer;
+	arg_types[1] = &ffi_type_pointer;
+	arg_types[2] = NULL;
+
+	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer,
+		arg_types) == FFI_OK);
+
+	args[0] = &arg1;
+	args[1] = &arg2;
+	args[2] = NULL;
+
+	ffi_call(&cif, FFI_FN(cls_pointer_fn), &res, args);
+	/* { dg-output "0x12345678 0x89abcdef: 0x9be02467" } */
+	printf("res: 0x%08x\n", (unsigned int) res);
+	/* { dg-output "\nres: 0x9be02467" } */
+
+	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK);
+
+	res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2);
+	/* { dg-output "\n0x12345678 0x89abcdef: 0x9be02467" } */
+	printf("res: 0x%08x\n", (unsigned int) res);
+	/* { dg-output "\nres: 0x9be02467" } */
+
+	exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c
new file mode 100755
index 0000000..d631cf8
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c
@@ -0,0 +1,140 @@
+/* Area:		ffi_call, closure_call
+   Purpose:		Check pointer arguments across multiple hideous stack frames.
+   Limitations:	none.
+   PR:			none.
+   Originator:	Blake Chaffin 6/7/2007	*/
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+#include "ffitest.h"
+
+static	long dummyVar;
+
+long dummy_func(
+	long double a1, char b1,
+	long double a2, char b2,
+	long double a3, char b3,
+	long double a4, char b4)
+{
+	return a1 + b1 + a2 + b2 + a3 + b3 + a4 + b4;
+}
+
+void* cls_pointer_fn2(void* a1, void* a2)
+{
+	long double	trample1	= (intptr_t)a1 + (intptr_t)a2;
+	char		trample2	= ((char*)&a1)[0] + ((char*)&a2)[0];
+	long double	trample3	= (intptr_t)trample1 + (intptr_t)a1;
+	char		trample4	= trample2 + ((char*)&a1)[1];
+	long double	trample5	= (intptr_t)trample3 + (intptr_t)a2;
+	char		trample6	= trample4 + ((char*)&a2)[1];
+	long double	trample7	= (intptr_t)trample5 + (intptr_t)trample1;
+	char		trample8	= trample6 + trample2;
+
+	dummyVar	= dummy_func(trample1, trample2, trample3, trample4,
+		trample5, trample6, trample7, trample8);
+
+	void*	result	= (void*)((intptr_t)a1 + (intptr_t)a2);
+
+	printf("0x%08x 0x%08x: 0x%08x\n", 
+	       (unsigned int)(uintptr_t) a1,
+               (unsigned int)(uintptr_t) a2,
+               (unsigned int)(uintptr_t) result);
+
+	return result;
+}
+
+void* cls_pointer_fn1(void* a1, void* a2)
+{
+	long double	trample1	= (intptr_t)a1 + (intptr_t)a2;
+	char		trample2	= ((char*)&a1)[0] + ((char*)&a2)[0];
+	long double	trample3	= (intptr_t)trample1 + (intptr_t)a1;
+	char		trample4	= trample2 + ((char*)&a1)[1];
+	long double	trample5	= (intptr_t)trample3 + (intptr_t)a2;
+	char		trample6	= trample4 + ((char*)&a2)[1];
+	long double	trample7	= (intptr_t)trample5 + (intptr_t)trample1;
+	char		trample8	= trample6 + trample2;
+
+	dummyVar	= dummy_func(trample1, trample2, trample3, trample4,
+		trample5, trample6, trample7, trample8);
+
+	void*	result	= (void*)((intptr_t)a1 + (intptr_t)a2);
+
+	printf("0x%08x 0x%08x: 0x%08x\n",
+               (unsigned int)(intptr_t) a1,
+               (unsigned int)(intptr_t) a2,
+               (unsigned int)(intptr_t) result);
+
+	result	= cls_pointer_fn2(result, a1);
+
+	return result;
+}
+
+static void
+cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp, 
+	       void** args, void* userdata __UNUSED__)
+{
+	void*	a1	= *(void**)(args[0]);
+	void*	a2	= *(void**)(args[1]);
+
+	long double	trample1	= (intptr_t)a1 + (intptr_t)a2;
+	char		trample2	= ((char*)&a1)[0] + ((char*)&a2)[0];
+	long double	trample3	= (intptr_t)trample1 + (intptr_t)a1;
+	char		trample4	= trample2 + ((char*)&a1)[1];
+	long double	trample5	= (intptr_t)trample3 + (intptr_t)a2;
+	char		trample6	= trample4 + ((char*)&a2)[1];
+	long double	trample7	= (intptr_t)trample5 + (intptr_t)trample1;
+	char		trample8	= trample6 + trample2;
+
+	dummyVar	= dummy_func(trample1, trample2, trample3, trample4,
+		trample5, trample6, trample7, trample8);
+
+	*(void**)resp = cls_pointer_fn1(a1, a2);
+}
+
+int main (void)
+{
+	ffi_cif	cif;
+        void *code;
+	ffi_closure*	pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+	void*			args[3];
+//	ffi_type		cls_pointer_type;
+	ffi_type*		arg_types[3];
+
+/*	cls_pointer_type.size = sizeof(void*);
+	cls_pointer_type.alignment = 0;
+	cls_pointer_type.type = FFI_TYPE_POINTER;
+	cls_pointer_type.elements = NULL;*/
+
+	void*	arg1	= (void*)0x01234567;
+	void*	arg2	= (void*)0x89abcdef;
+	ffi_arg	res		= 0;
+
+	arg_types[0] = &ffi_type_pointer;
+	arg_types[1] = &ffi_type_pointer;
+	arg_types[2] = NULL;
+
+	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer,
+		arg_types) == FFI_OK);
+
+	args[0] = &arg1;
+	args[1] = &arg2;
+	args[2] = NULL;
+
+	printf("\n");
+	ffi_call(&cif, FFI_FN(cls_pointer_fn1), &res, args);
+
+	printf("res: 0x%08x\n", (unsigned int) res);
+	// { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" }
+	// { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" }
+	// { dg-output "\nres: 0x8bf258bd" }
+
+	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK);
+
+	res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2);
+
+	printf("res: 0x%08x\n", (unsigned int) res);
+	// { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" }
+	// { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" }
+	// { dg-output "\nres: 0x8bf258bd" }
+
+	exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_schar.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_schar.c
new file mode 100755
index 0000000..82986b1
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_schar.c
@@ -0,0 +1,44 @@
+/* Area:	closure_call
+   Purpose:	Check return value schar.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20031108	 */
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_schar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+			     void* userdata __UNUSED__)
+{
+  *(ffi_arg*)resp = *(signed char *)args[0];
+  printf("%d: %d\n",*(signed char *)args[0],
+	 (int)*(ffi_arg *)(resp));
+}
+typedef signed char (*cls_ret_schar)(signed char);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[2];
+  signed char res;
+
+  cl_arg_types[0] = &ffi_type_schar;
+  cl_arg_types[1] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_schar, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_schar_fn, NULL, code)  == FFI_OK);
+
+  res = (*((cls_ret_schar)code))(127);
+  /* { dg-output "127: 127" } */
+  printf("res: %d\n", res);
+  /* { dg-output "\nres: 127" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_sint.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_sint.c
new file mode 100755
index 0000000..c7e13b7
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_sint.c
@@ -0,0 +1,42 @@
+/* Area:	closure_call
+   Purpose:	Check return value sint32.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20031108	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_sint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+			    void* userdata __UNUSED__)
+{
+  *(ffi_arg*)resp = *(signed int *)args[0];
+  printf("%d: %d\n",*(signed int *)args[0],
+	 (int)*(ffi_arg *)(resp));
+}
+typedef signed int (*cls_ret_sint)(signed int);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[2];
+  signed int res;
+
+  cl_arg_types[0] = &ffi_type_sint;
+  cl_arg_types[1] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sint_fn, NULL, code)  == FFI_OK);
+
+  res = (*((cls_ret_sint)code))(65534);
+  /* { dg-output "65534: 65534" } */
+  printf("res: %d\n",res);
+  /* { dg-output "\nres: 65534" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_sshort.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_sshort.c
new file mode 100755
index 0000000..846d57e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_sshort.c
@@ -0,0 +1,42 @@
+/* Area:	closure_call
+   Purpose:	Check return value sshort.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20031108	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_sshort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+			      void* userdata __UNUSED__)
+{
+  *(ffi_arg*)resp = *(signed short *)args[0];
+  printf("%d: %d\n",*(signed short *)args[0],
+	 (int)*(ffi_arg *)(resp));
+}
+typedef signed short (*cls_ret_sshort)(signed short);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[2];
+  signed short res;
+
+  cl_arg_types[0] = &ffi_type_sshort;
+  cl_arg_types[1] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_sshort, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sshort_fn, NULL, code)  == FFI_OK);
+
+  res = (*((cls_ret_sshort)code))(255);
+  /* { dg-output "255: 255" } */
+  printf("res: %d\n",res);
+  /* { dg-output "\nres: 255" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar.c
new file mode 100755
index 0000000..c1317e7
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar.c
@@ -0,0 +1,42 @@
+/* Area:	closure_call
+   Purpose:	Check return value uchar.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_uchar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+			     void* userdata __UNUSED__)
+{
+  *(ffi_arg*)resp = *(unsigned char *)args[0];
+  printf("%d: %d\n",*(unsigned char *)args[0],
+	 (int)*(ffi_arg *)(resp));
+}
+typedef unsigned char (*cls_ret_uchar)(unsigned char);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[2];
+  unsigned char res;
+
+  cl_arg_types[0] = &ffi_type_uchar;
+  cl_arg_types[1] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_uchar, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uchar_fn, NULL, code)  == FFI_OK);
+
+  res = (*((cls_ret_uchar)code))(127);
+  /* { dg-output "127: 127" } */
+  printf("res: %d\n",res);
+  /* { dg-output "\nres: 127" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint.c
new file mode 100755
index 0000000..885cff5
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint.c
@@ -0,0 +1,43 @@
+/* Area:	closure_call
+   Purpose:	Check return value uint.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_uint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+			    void* userdata __UNUSED__)
+{
+  *(ffi_arg *)resp = *(unsigned int *)args[0];
+
+  printf("%d: %d\n",*(unsigned int *)args[0],
+	 (int)*(ffi_arg *)(resp));
+}
+typedef unsigned int (*cls_ret_uint)(unsigned int);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[2];
+  unsigned int res;
+
+  cl_arg_types[0] = &ffi_type_uint;
+  cl_arg_types[1] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_uint, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uint_fn, NULL, code)  == FFI_OK);
+
+  res = (*((cls_ret_uint)code))(2147483647);
+  /* { dg-output "2147483647: 2147483647" } */
+  printf("res: %d\n",res);
+  /* { dg-output "\nres: 2147483647" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c
new file mode 100755
index 0000000..235ab44
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c
@@ -0,0 +1,47 @@
+/* Area:	closure_call
+   Purpose:	Check return value long long.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
+#include "ffitest.h"
+
+static void cls_ret_ulonglong_fn(ffi_cif* cif __UNUSED__, void* resp,
+				 void** args, void* userdata __UNUSED__)
+{
+  *(unsigned long long *)resp=  *(unsigned long long *)args[0];
+
+  printf("%" PRIuLL ": %" PRIuLL "\n",*(unsigned long long *)args[0],
+	 *(unsigned long long *)(resp));
+}
+typedef unsigned long long (*cls_ret_ulonglong)(unsigned long long);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[2];
+  unsigned long long res;
+
+  cl_arg_types[0] = &ffi_type_uint64;
+  cl_arg_types[1] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_uint64, cl_arg_types) == FFI_OK);
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ulonglong_fn, NULL, code)  == FFI_OK);
+  res = (*((cls_ret_ulonglong)code))(214LL);
+  /* { dg-output "214: 214" } */
+  printf("res: %" PRIdLL "\n", res);
+  /* { dg-output "\nres: 214" } */
+
+  res = (*((cls_ret_ulonglong)code))(9223372035854775808LL);
+  /* { dg-output "\n9223372035854775808: 9223372035854775808" } */
+  printf("res: %" PRIdLL "\n", res);
+  /* { dg-output "\nres: 9223372035854775808" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort.c
new file mode 100755
index 0000000..a00100e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort.c
@@ -0,0 +1,43 @@
+/* Area:	closure_call
+   Purpose:	Check return value ushort.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void cls_ret_ushort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+			      void* userdata __UNUSED__)
+{
+  *(ffi_arg*)resp = *(unsigned short *)args[0];
+
+  printf("%d: %d\n",*(unsigned short *)args[0],
+	 (int)*(ffi_arg *)(resp));
+}
+typedef unsigned short (*cls_ret_ushort)(unsigned short);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[2];
+  unsigned short res;
+
+  cl_arg_types[0] = &ffi_type_ushort;
+  cl_arg_types[1] = NULL;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_ushort, cl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ushort_fn, NULL, code)  == FFI_OK);
+
+  res = (*((cls_ret_ushort)code))(65535);
+  /* { dg-output "65535: 65535" } */
+  printf("res: %d\n",res);
+  /* { dg-output "\nres: 65535" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_abi.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_abi.c
new file mode 100755
index 0000000..f5a7317
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_abi.c
@@ -0,0 +1,36 @@
+/* Area:		ffi_prep_cif, ffi_prep_closure
+   Purpose:		Test error return for bad ABIs.
+   Limitations:	none.
+   PR:			none.
+   Originator:	Blake Chaffin 6/6/2007	 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+static void
+dummy_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, 
+	 void** args __UNUSED__, void* userdata __UNUSED__)
+{}
+
+int main (void)
+{
+	ffi_cif cif;
+        void *code;
+	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+	ffi_type* arg_types[1];
+
+	arg_types[0] = NULL;
+
+	CHECK(ffi_prep_cif(&cif, 255, 0, &ffi_type_void,
+		arg_types) == FFI_BAD_ABI);
+
+	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_void,
+		arg_types) == FFI_OK);
+
+	cif.abi= 255;
+
+	CHECK(ffi_prep_closure_loc(pcl, &cif, dummy_fn, NULL, code) == FFI_BAD_ABI);
+
+	exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c
new file mode 100755
index 0000000..2539273
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c
@@ -0,0 +1,26 @@
+/* Area:		ffi_prep_cif
+   Purpose:		Test error return for bad typedefs.
+   Limitations:	none.
+   PR:			none.
+   Originator:	Blake Chaffin 6/6/2007	 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+int main (void)
+{
+	ffi_cif cif;
+	ffi_type* arg_types[1];
+
+	arg_types[0] = NULL;
+
+	ffi_type	badType	= ffi_type_void;
+
+	badType.size = 0;
+
+	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &badType,
+		arg_types) == FFI_BAD_TYPEDEF);
+
+	exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h
new file mode 100755
index 0000000..0e95e16
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h
@@ -0,0 +1,153 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <ffi.h>
+#include "fficonfig.h"
+
+#if defined HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#if defined HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#define MAX_ARGS 256
+
+#define CHECK(x) !(x) ? abort() : 0
+
+/* Define __UNUSED__ that also other compilers than gcc can run the tests.  */
+#undef __UNUSED__
+#if defined(__GNUC__)
+#define __UNUSED__ __attribute__((__unused__))
+#else
+#define __UNUSED__
+#endif
+
+/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
+   file open.  */
+#ifdef HAVE_MMAP_ANON
+# undef HAVE_MMAP_DEV_ZERO
+
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+#  define MAP_FAILED -1
+# endif
+# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
+#  define MAP_ANONYMOUS MAP_ANON
+# endif
+# define USING_MMAP
+
+#endif
+
+#ifdef HAVE_MMAP_DEV_ZERO
+
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+#  define MAP_FAILED -1
+# endif
+# define USING_MMAP
+
+#endif
+
+/* MinGW kludge.  */
+#ifdef _WIN64
+#define PRIdLL "I64d"
+#define PRIuLL "I64u"
+#else
+#define PRIdLL "lld"
+#define PRIuLL "llu"
+#endif
+
+/* Tru64 UNIX kludge.  */
+#if defined(__alpha__) && defined(__osf__)
+/* Tru64 UNIX V4.0 doesn't support %lld/%lld, but long is 64-bit.  */
+#undef PRIdLL
+#define PRIdLL "ld"
+#undef PRIuLL
+#define PRIuLL "lu"
+#define PRId8 "hd"
+#define PRIu8 "hu"
+#define PRId64 "ld"
+#define PRIu64 "lu"
+#define PRIuPTR "lu"
+#endif
+
+/* PA HP-UX kludge.  */
+#if defined(__hppa__) && defined(__hpux__) && !defined(PRIuPTR)
+#define PRIuPTR "lu"
+#endif
+
+/* IRIX kludge.  */
+#if defined(__sgi)
+/* IRIX 6.5 <inttypes.h> provides all definitions, but only for C99
+   compilations.  */
+#define PRId8 "hhd"
+#define PRIu8 "hhu"
+#if (_MIPS_SZLONG == 32)
+#define PRId64 "lld"
+#define PRIu64 "llu"
+#endif
+/* This doesn't match <inttypes.h>, which always has "lld" here, but the
+   arguments are uint64_t, int64_t, which are unsigned long, long for
+   64-bit in <sgidefs.h>.  */
+#if (_MIPS_SZLONG == 64)
+#define PRId64 "ld"
+#define PRIu64 "lu"
+#endif
+/* This doesn't match <inttypes.h>, which has "u" here, but the arguments
+   are uintptr_t, which is always unsigned long.  */
+#define PRIuPTR "lu"
+#endif
+
+/* Solaris < 10 kludge.  */
+#if defined(__sun__) && defined(__svr4__) && !defined(PRIuPTR)
+#if defined(__arch64__) || defined (__x86_64__)
+#define PRIuPTR "lu"
+#else
+#define PRIuPTR "u"
+#endif
+#endif
+
+#ifdef USING_MMAP
+static inline void *
+allocate_mmap (size_t size)
+{
+  void *page;
+#if defined (HAVE_MMAP_DEV_ZERO)
+  static int dev_zero_fd = -1;
+#endif
+
+#ifdef HAVE_MMAP_DEV_ZERO
+  if (dev_zero_fd == -1)
+    {
+      dev_zero_fd = open ("/dev/zero", O_RDONLY);
+      if (dev_zero_fd == -1)
+	{
+	  perror ("open /dev/zero: %m");
+	  exit (1);
+	}
+    }
+#endif
+
+
+#ifdef HAVE_MMAP_ANON
+  page = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+	       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+#endif
+#ifdef HAVE_MMAP_DEV_ZERO
+  page = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+	       MAP_PRIVATE, dev_zero_fd, 0);
+#endif
+
+  if (page == (void *) MAP_FAILED)
+    {
+      perror ("virtual memory exhausted");
+      exit (1);
+    }
+
+  return page;
+}
+
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/float.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/float.c
new file mode 100755
index 0000000..fbc272d
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/float.c
@@ -0,0 +1,59 @@
+/* Area:	ffi_call
+   Purpose:	Check return value float.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+static int floating(int a, float b, double c, long double d)
+{
+  int i;
+
+  i = (int) ((float)a/b + ((float)c/(float)d));
+
+  return i;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_arg rint;
+
+  float f;
+  signed int si1;
+  double d;
+  long double ld;
+
+  args[0] = &ffi_type_sint;
+  values[0] = &si1;
+  args[1] = &ffi_type_float;
+  values[1] = &f;
+  args[2] = &ffi_type_double;
+  values[2] = &d;
+  args[3] = &ffi_type_longdouble;
+  values[3] = &ld;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+		     &ffi_type_sint, args) == FFI_OK);
+
+  si1 = 6;
+  f = 3.14159;
+  d = (double)1.0/(double)3.0;
+  ld = 2.71828182846L;
+
+  floating (si1, f, d, ld);
+
+  ffi_call(&cif, FFI_FN(floating), &rint, values);
+
+  printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld));
+
+  CHECK((int)rint == floating(si1, f, d, ld));
+
+  exit (0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/float1.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/float1.c
new file mode 100755
index 0000000..991d059
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/float1.c
@@ -0,0 +1,58 @@
+/* Area:	ffi_call
+   Purpose:	Check return value double.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+#include "float.h"
+
+typedef union
+{
+  double d;
+  unsigned char c[sizeof (double)];
+} value_type;
+
+#define CANARY 0xba
+
+static double dblit(float f)
+{
+  return f/3.0;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  float f;
+  value_type result[2];
+  unsigned int i;
+
+  args[0] = &ffi_type_float;
+  values[0] = &f;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_double, args) == FFI_OK);
+
+  f = 3.14159;
+
+  /* Put a canary in the return array.  This is a regression test for
+     a buffer overrun.  */
+  memset(result[1].c, CANARY, sizeof (double));
+
+  ffi_call(&cif, FFI_FN(dblit), &result[0].d, values);
+
+  /* These are not always the same!! Check for a reasonable delta */
+
+  CHECK(result[0].d - dblit(f) < DBL_EPSILON);
+
+  /* Check the canary.  */
+  for (i = 0; i < sizeof (double); ++i)
+    CHECK(result[1].c[i] == CANARY);
+
+  exit(0);
+
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/float2.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/float2.c
new file mode 100755
index 0000000..a0b296c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/float2.c
@@ -0,0 +1,58 @@
+/* Area:	ffi_call
+   Purpose:	Check return value long double.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-excess-errors "fails" { target x86_64-*-mingw* x86_64-*-cygwin* } } */
+/* { dg-do run { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
+
+#include "ffitest.h"
+#include "float.h"
+
+static long double ldblit(float f)
+{
+  return (long double) (((long double) f)/ (long double) 3.0);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  float f;
+  long double ld;
+
+  args[0] = &ffi_type_float;
+  values[0] = &f;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_longdouble, args) == FFI_OK);
+
+  f = 3.14159;
+
+#if 1
+  /* This is ifdef'd out for now. long double support under SunOS/gcc
+     is pretty much non-existent.  You'll get the odd bus error in library
+     routines like printf().  */
+  printf ("%Lf\n", ldblit(f));
+#endif
+  ld = 666;
+  ffi_call(&cif, FFI_FN(ldblit), &ld, values);
+
+#if 1
+  /* This is ifdef'd out for now. long double support under SunOS/gcc
+     is pretty much non-existent.  You'll get the odd bus error in library
+     routines like printf().  */
+  printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
+#endif
+
+  /* These are not always the same!! Check for a reasonable delta */
+  if (ld - ldblit(f) < LDBL_EPSILON)
+    puts("long double return value tests ok!");
+  else
+    CHECK(0);
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/float3.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/float3.c
new file mode 100755
index 0000000..76bd5f2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/float3.c
@@ -0,0 +1,72 @@
+/* Area:	ffi_call
+   Purpose:	Check float arguments with different orders.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+#include "float.h"
+
+static double floating_1(float a, double b, long double c)
+{
+  return (double) a + b + (double) c;
+}
+
+static double floating_2(long double a, double b, float c)
+{
+  return (double) a + b + (double) c;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  double rd;
+
+  float f;
+  double d;
+  long double ld;
+
+  args[0] = &ffi_type_float;
+  values[0] = &f;
+  args[1] = &ffi_type_double;
+  values[1] = &d;
+  args[2] = &ffi_type_longdouble;
+  values[2] = &ld;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+		     &ffi_type_double, args) == FFI_OK);
+
+  f = 3.14159;
+  d = (double)1.0/(double)3.0;
+  ld = 2.71828182846L;
+
+  floating_1 (f, d, ld);
+
+  ffi_call(&cif, FFI_FN(floating_1), &rd, values);
+
+  CHECK(rd - floating_1(f, d, ld) < DBL_EPSILON);
+
+  args[0] = &ffi_type_longdouble;
+  values[0] = &ld;
+  args[1] = &ffi_type_double;
+  values[1] = &d;
+  args[2] = &ffi_type_float;
+  values[2] = &f;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+		     &ffi_type_double, args) == FFI_OK);
+
+  floating_2 (ld, d, f);
+
+  ffi_call(&cif, FFI_FN(floating_2), &rd, values);
+
+  CHECK(rd - floating_2(ld, d, f) < DBL_EPSILON);
+
+  exit (0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/float4.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/float4.c
new file mode 100755
index 0000000..0dd6d85
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/float4.c
@@ -0,0 +1,62 @@
+/* Area:	ffi_call
+   Purpose:	Check denorm double value.
+   Limitations:	none.
+   PR:		PR26483.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+/* { dg-options "-mieee" { target alpha*-*-* } } */
+
+#include "ffitest.h"
+#include "float.h"
+
+typedef union
+{
+  double d;
+  unsigned char c[sizeof (double)];
+} value_type;
+
+#define CANARY 0xba
+
+static double dblit(double d)
+{
+  return d;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  double d;
+  value_type result[2];
+  unsigned int i;
+
+  args[0] = &ffi_type_double;
+  values[0] = &d;
+  
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_double, args) == FFI_OK);
+  
+  d = DBL_MIN / 2;
+  
+  /* Put a canary in the return array.  This is a regression test for
+     a buffer overrun.  */
+  memset(result[1].c, CANARY, sizeof (double));
+
+  ffi_call(&cif, FFI_FN(dblit), &result[0].d, values);
+  
+  /* The standard delta check doesn't work for denorms.  Since we didn't do
+     any arithmetic, we should get the original result back, and hence an
+     exact check should be OK here.  */
+ 
+  CHECK(result[0].d == dblit(d));
+
+  /* Check the canary.  */
+  for (i = 0; i < sizeof (double); ++i)
+    CHECK(result[1].c[i] == CANARY);
+
+  exit(0);
+
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c
new file mode 100755
index 0000000..e04e1d5
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c
@@ -0,0 +1,342 @@
+/*	Area:			ffi_call, closure_call
+	Purpose:		Check large structure returns.
+	Limitations:	none.
+	PR:				none.
+	Originator:		Blake Chaffin	6/18/2007
+*/
+
+/* { dg-excess-errors "" { target x86_64-*-mingw* x86_64-*-cygwin* } } */
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
+/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
+/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
+
+#include "ffitest.h"
+
+typedef	struct BigStruct{
+	uint8_t		a;
+	int8_t		b;
+	uint16_t	c;
+	int16_t		d;
+	uint32_t	e;
+	int32_t		f;
+	uint64_t	g;
+	int64_t		h;
+	float		i;
+	double		j;
+	long double	k;
+	char*		l;
+	uint8_t		m;
+	int8_t		n;
+	uint16_t	o;
+	int16_t		p;
+	uint32_t	q;
+	int32_t		r;
+	uint64_t	s;
+	int64_t		t;
+	float		u;
+	double		v;
+	long double	w;
+	char*		x;
+	uint8_t		y;
+	int8_t		z;
+	uint16_t	aa;
+	int16_t		bb;
+	uint32_t	cc;
+	int32_t		dd;
+	uint64_t	ee;
+	int64_t		ff;
+	float		gg;
+	double		hh;
+	long double	ii;
+	char*		jj;
+	uint8_t		kk;
+	int8_t		ll;
+	uint16_t	mm;
+	int16_t		nn;
+	uint32_t	oo;
+	int32_t		pp;
+	uint64_t	qq;
+	int64_t		rr;
+	float		ss;
+	double		tt;
+	long double	uu;
+	char*		vv;
+	uint8_t		ww;
+	int8_t		xx;
+} BigStruct;
+
+BigStruct
+test_large_fn(
+	uint8_t		ui8_1,
+	int8_t		si8_1,
+	uint16_t	ui16_1,
+	int16_t		si16_1,
+	uint32_t	ui32_1,
+	int32_t		si32_1,
+	uint64_t	ui64_1,
+	int64_t		si64_1,
+	float		f_1,
+	double		d_1,
+	long double	ld_1,
+	char*		p_1,
+	uint8_t		ui8_2,
+	int8_t		si8_2,
+	uint16_t	ui16_2,
+	int16_t		si16_2,
+	uint32_t	ui32_2,
+	int32_t		si32_2,
+	uint64_t	ui64_2,
+	int64_t		si64_2,
+	float		f_2,
+	double		d_2,
+	long double	ld_2,
+	char*		p_2,
+	uint8_t		ui8_3,
+	int8_t		si8_3,
+	uint16_t	ui16_3,
+	int16_t		si16_3,
+	uint32_t	ui32_3,
+	int32_t		si32_3,
+	uint64_t	ui64_3,
+	int64_t		si64_3,
+	float		f_3,
+	double		d_3,
+	long double	ld_3,
+	char*		p_3,
+	uint8_t		ui8_4,
+	int8_t		si8_4,
+	uint16_t	ui16_4,
+	int16_t		si16_4,
+	uint32_t	ui32_4,
+	int32_t		si32_4,
+	uint64_t	ui64_4,
+	int64_t		si64_4,
+	float		f_4,
+	double		d_4,
+	long double	ld_4,
+	char*		p_4,
+	uint8_t		ui8_5,
+	int8_t		si8_5)
+{
+	BigStruct	retVal	= {
+		ui8_1 + 1, si8_1 + 1, ui16_1 + 1, si16_1 + 1, ui32_1 + 1, si32_1 + 1,
+			ui64_1 + 1, si64_1 + 1, f_1 + 1, d_1 + 1, ld_1 + 1, (char*)((intptr_t)p_1 + 1), 
+		ui8_2 + 2, si8_2 + 2, ui16_2 + 2, si16_2 + 2, ui32_2 + 2, si32_2 + 2,
+			ui64_2 + 2, si64_2 + 2, f_2 + 2, d_2 + 2, ld_2 + 2, (char*)((intptr_t)p_2 + 2), 
+		ui8_3 + 3, si8_3 + 3, ui16_3 + 3, si16_3 + 3, ui32_3 + 3, si32_3 + 3,
+			ui64_3 + 3, si64_3 + 3, f_3 + 3, d_3 + 3, ld_3 + 3, (char*)((intptr_t)p_3 + 3), 
+		ui8_4 + 4, si8_4 + 4, ui16_4 + 4, si16_4 + 4, ui32_4 + 4, si32_4 + 4,
+			ui64_4 + 4, si64_4 + 4, f_4 + 4, d_4 + 4, ld_4 + 4, (char*)((intptr_t)p_4 + 4), 
+		ui8_5 + 5, si8_5 + 5};
+
+	printf("%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 ": "
+		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
+	       ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, (unsigned long)p_1,
+		ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, (unsigned long)p_2,
+		ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, (unsigned long)p_3,
+		ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, (unsigned long)p_4, ui8_5, si8_5,
+		retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
+	       retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
+		retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
+	       retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
+		retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
+	       retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
+		retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
+	       retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
+
+	return	retVal;
+}
+
+static void
+cls_large_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
+{
+	uint8_t		ui8_1	= *(uint8_t*)args[0];
+	int8_t		si8_1	= *(int8_t*)args[1];
+	uint16_t	ui16_1	= *(uint16_t*)args[2];
+	int16_t		si16_1	= *(int16_t*)args[3];
+	uint32_t	ui32_1	= *(uint32_t*)args[4];
+	int32_t		si32_1	= *(int32_t*)args[5];
+	uint64_t	ui64_1	= *(uint64_t*)args[6];
+	int64_t		si64_1	= *(int64_t*)args[7];
+	float		f_1		= *(float*)args[8];
+	double		d_1		= *(double*)args[9];
+	long double	ld_1	= *(long double*)args[10];
+	char*		p_1		= *(char**)args[11];
+	uint8_t		ui8_2	= *(uint8_t*)args[12];
+	int8_t		si8_2	= *(int8_t*)args[13];
+	uint16_t	ui16_2	= *(uint16_t*)args[14];
+	int16_t		si16_2	= *(int16_t*)args[15];
+	uint32_t	ui32_2	= *(uint32_t*)args[16];
+	int32_t		si32_2	= *(int32_t*)args[17];
+	uint64_t	ui64_2	= *(uint64_t*)args[18];
+	int64_t		si64_2	= *(int64_t*)args[19];
+	float		f_2		= *(float*)args[20];
+	double		d_2		= *(double*)args[21];
+	long double	ld_2	= *(long double*)args[22];
+	char*		p_2		= *(char**)args[23];
+	uint8_t		ui8_3	= *(uint8_t*)args[24];
+	int8_t		si8_3	= *(int8_t*)args[25];
+	uint16_t	ui16_3	= *(uint16_t*)args[26];
+	int16_t		si16_3	= *(int16_t*)args[27];
+	uint32_t	ui32_3	= *(uint32_t*)args[28];
+	int32_t		si32_3	= *(int32_t*)args[29];
+	uint64_t	ui64_3	= *(uint64_t*)args[30];
+	int64_t		si64_3	= *(int64_t*)args[31];
+	float		f_3		= *(float*)args[32];
+	double		d_3		= *(double*)args[33];
+	long double	ld_3	= *(long double*)args[34];
+	char*		p_3		= *(char**)args[35];
+	uint8_t		ui8_4	= *(uint8_t*)args[36];
+	int8_t		si8_4	= *(int8_t*)args[37];
+	uint16_t	ui16_4	= *(uint16_t*)args[38];
+	int16_t		si16_4	= *(int16_t*)args[39];
+	uint32_t	ui32_4	= *(uint32_t*)args[40];
+	int32_t		si32_4	= *(int32_t*)args[41];
+	uint64_t	ui64_4	= *(uint64_t*)args[42];
+	int64_t		si64_4	= *(int64_t*)args[43];
+	float		f_4		= *(float*)args[44];
+	double		d_4		= *(double*)args[45];
+	long double	ld_4	= *(long double*)args[46];
+	char*		p_4		= *(char**)args[47];
+	uint8_t		ui8_5	= *(uint8_t*)args[48];
+	int8_t		si8_5	= *(int8_t*)args[49];
+
+	*(BigStruct*)resp = test_large_fn(
+		ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, p_1,
+		ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, p_2,
+		ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, p_3,
+		ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, p_4,
+		ui8_5, si8_5);
+}
+
+int
+main(int argc __UNUSED__, const char** argv __UNUSED__)
+{
+        void *code;
+	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+
+	ffi_cif		cif;
+	ffi_type*	argTypes[51];
+	void*		argValues[51];
+
+	ffi_type	ret_struct_type;
+	ffi_type*	st_fields[51];
+	BigStruct	retVal;
+
+	memset (&retVal, 0, sizeof(retVal));
+
+	ret_struct_type.size = 0;
+	ret_struct_type.alignment = 0;
+	ret_struct_type.type = FFI_TYPE_STRUCT;
+	ret_struct_type.elements = st_fields;
+
+	st_fields[0]	= st_fields[12]	= st_fields[24]	= st_fields[36]	= st_fields[48]	= &ffi_type_uint8;
+	st_fields[1]	= st_fields[13]	= st_fields[25]	= st_fields[37]	= st_fields[49]	= &ffi_type_sint8;
+	st_fields[2]	= st_fields[14]	= st_fields[26]	= st_fields[38]	= &ffi_type_uint16;
+	st_fields[3]	= st_fields[15]	= st_fields[27]	= st_fields[39]	= &ffi_type_sint16;
+	st_fields[4]	= st_fields[16]	= st_fields[28]	= st_fields[40]	= &ffi_type_uint32;
+	st_fields[5]	= st_fields[17]	= st_fields[29]	= st_fields[41]	= &ffi_type_sint32;
+	st_fields[6]	= st_fields[18]	= st_fields[30]	= st_fields[42]	= &ffi_type_uint64;
+	st_fields[7]	= st_fields[19]	= st_fields[31]	= st_fields[43]	= &ffi_type_sint64;
+	st_fields[8]	= st_fields[20]	= st_fields[32]	= st_fields[44]	= &ffi_type_float;
+	st_fields[9]	= st_fields[21]	= st_fields[33]	= st_fields[45]	= &ffi_type_double;
+	st_fields[10]	= st_fields[22]	= st_fields[34]	= st_fields[46]	= &ffi_type_longdouble;
+	st_fields[11]	= st_fields[23]	= st_fields[35]	= st_fields[47]	= &ffi_type_pointer;
+
+	st_fields[50] = NULL;
+
+	uint8_t		ui8		= 1;
+	int8_t		si8		= 2;
+	uint16_t	ui16	= 3;
+	int16_t		si16	= 4;
+	uint32_t	ui32	= 5;
+	int32_t		si32	= 6;
+	uint64_t	ui64	= 7;
+	int64_t		si64	= 8;
+	float		f		= 9;
+	double		d		= 10;
+	long double	ld		= 11;
+	char*		p		= (char*)0x12345678;
+
+	argTypes[0]		= argTypes[12]	= argTypes[24]	= argTypes[36]	= argTypes[48]	= &ffi_type_uint8;
+	argValues[0]	= argValues[12]	= argValues[24]	= argValues[36]	= argValues[48]	= &ui8;
+	argTypes[1]		= argTypes[13]	= argTypes[25]	= argTypes[37]	= argTypes[49]	= &ffi_type_sint8;
+	argValues[1]	= argValues[13]	= argValues[25]	= argValues[37]	= argValues[49]	= &si8;
+	argTypes[2]		= argTypes[14]	= argTypes[26]	= argTypes[38]	= &ffi_type_uint16;
+	argValues[2]	= argValues[14]	= argValues[26]	= argValues[38]	= &ui16;
+	argTypes[3]		= argTypes[15]	= argTypes[27]	= argTypes[39]	= &ffi_type_sint16;
+	argValues[3]	= argValues[15]	= argValues[27]	= argValues[39]	= &si16;
+	argTypes[4]		= argTypes[16]	= argTypes[28]	= argTypes[40]	= &ffi_type_uint32;
+	argValues[4]	= argValues[16]	= argValues[28]	= argValues[40]	= &ui32;
+	argTypes[5]		= argTypes[17]	= argTypes[29]	= argTypes[41]	= &ffi_type_sint32;
+	argValues[5]	= argValues[17]	= argValues[29]	= argValues[41]	= &si32;
+	argTypes[6]		= argTypes[18]	= argTypes[30]	= argTypes[42]	= &ffi_type_uint64;
+	argValues[6]	= argValues[18]	= argValues[30]	= argValues[42]	= &ui64;
+	argTypes[7]		= argTypes[19]	= argTypes[31]	= argTypes[43]	= &ffi_type_sint64;
+	argValues[7]	= argValues[19]	= argValues[31]	= argValues[43]	= &si64;
+	argTypes[8]		= argTypes[20]	= argTypes[32]	= argTypes[44]	= &ffi_type_float;
+	argValues[8]	= argValues[20]	= argValues[32]	= argValues[44]	= &f;
+	argTypes[9]		= argTypes[21]	= argTypes[33]	= argTypes[45]	= &ffi_type_double;
+	argValues[9]	= argValues[21]	= argValues[33]	= argValues[45]	= &d;
+	argTypes[10]	= argTypes[22]	= argTypes[34]	= argTypes[46]	= &ffi_type_longdouble;
+	argValues[10]	= argValues[22]	= argValues[34]	= argValues[46]	= &ld;
+	argTypes[11]	= argTypes[23]	= argTypes[35]	= argTypes[47]	= &ffi_type_pointer;
+	argValues[11]	= argValues[23]	= argValues[35]	= argValues[47]	= &p;
+
+	argTypes[50]	= NULL;
+	argValues[50]	= NULL;
+
+	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 50, &ret_struct_type, argTypes) == FFI_OK);
+
+	ffi_call(&cif, FFI_FN(test_large_fn), &retVal, argValues);
+	// { dg-output "1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" }
+	printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
+		retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
+	       retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
+		retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
+	       retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
+		retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
+	       retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
+		retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
+	       retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
+	// { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" }
+
+	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_large_fn, NULL, code) == FFI_OK);
+
+	retVal	= ((BigStruct(*)(
+		uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
+		uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
+		uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
+		uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
+		uint8_t, int8_t))(code))(
+		ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
+		ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
+		ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
+		ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
+		ui8, si8);
+	// { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" }
+	printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
+		"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
+		retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
+	       retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
+		retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
+	       retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
+		retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
+	       retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
+		retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
+	       retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
+	// { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" }
+
+    return 0;
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/many.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/many.c
new file mode 100755
index 0000000..4869ba9
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/many.c
@@ -0,0 +1,69 @@
+/* Area:	ffi_call
+   Purpose:	Check return value float, with many arguments
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+#include <float.h>
+
+static float many(float f1,
+		  float f2,
+		  float f3,
+		  float f4,
+		  float f5,
+		  float f6,
+		  float f7,
+		  float f8,
+		  float f9,
+		  float f10,
+		  float f11,
+		  float f12,
+		  float f13)
+{
+#if 0
+  printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n",
+	 (double) f1, (double) f2, (double) f3, (double) f4, (double) f5, 
+	 (double) f6, (double) f7, (double) f8, (double) f9, (double) f10,
+	 (double) f11, (double) f12, (double) f13);
+#endif
+
+  return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[13];
+  void *values[13];
+  float fa[13];
+  float f, ff;
+  int i;
+
+  for (i = 0; i < 13; i++)
+    {
+      args[i] = &ffi_type_float;
+      values[i] = &fa[i];
+      fa[i] = (float) i;
+    }
+
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, 
+		       &ffi_type_float, args) == FFI_OK);
+
+    ffi_call(&cif, FFI_FN(many), &f, values);
+
+    ff =  many(fa[0], fa[1],
+	       fa[2], fa[3],
+	       fa[4], fa[5],
+	       fa[6], fa[7],
+	       fa[8], fa[9],
+	       fa[10],fa[11],fa[12]);
+
+    if (f - ff < FLT_EPSILON)
+      exit(0);
+    else
+      abort();
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c
new file mode 100755
index 0000000..1b26332
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c
@@ -0,0 +1,63 @@
+/* Area:	ffi_call
+   Purpose:	Check stdcall many call on X86_WIN32 systems.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
+
+#include "ffitest.h"
+#include <float.h>
+
+static float __attribute__((stdcall)) stdcall_many(float f1,
+						   float f2,
+						   float f3,
+						   float f4,
+						   float f5,
+						   float f6,
+						   float f7,
+						   float f8,
+						   float f9,
+						   float f10,
+						   float f11,
+						   float f12,
+						   float f13)
+{
+  return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[13];
+  void *values[13];
+  float fa[13];
+  float f, ff;
+  unsigned long ul;
+
+  for (ul = 0; ul < 13; ul++)
+    {
+      args[ul] = &ffi_type_float;
+      values[ul] = &fa[ul];
+	fa[ul] = (float) ul;
+    }
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 13,
+		     &ffi_type_float, args) == FFI_OK);
+
+  ff =  stdcall_many(fa[0], fa[1],
+		     fa[2], fa[3],
+		     fa[4], fa[5],
+		     fa[6], fa[7],
+		     fa[8], fa[9],
+		     fa[10], fa[11], fa[12]);
+
+  ffi_call(&cif, FFI_FN(stdcall_many), &f, values);
+
+  if (f - ff < FLT_EPSILON)
+    printf("stdcall many arg tests ok!\n");
+  else
+    CHECK(0);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/negint.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/negint.c
new file mode 100755
index 0000000..3168113
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/negint.c
@@ -0,0 +1,53 @@
+/* Area:	ffi_call
+   Purpose:	Check that negative integers are passed correctly.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+/* { dg-options -O2 } */
+
+#include "ffitest.h"
+
+static int checking(int a, short b, signed char c)
+{
+
+  return (a < 0 && b < 0 && c < 0);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_arg rint;
+
+  signed int si;
+  signed short ss;
+  signed char sc;
+
+  args[0] = &ffi_type_sint;
+  values[0] = &si;
+  args[1] = &ffi_type_sshort;
+  values[1] = &ss;
+  args[2] = &ffi_type_schar;
+  values[2] = ≻
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+		     &ffi_type_sint, args) == FFI_OK);
+
+  si = -6;
+  ss = -12;
+  sc = -1;
+
+  checking (si, ss, sc);
+
+  ffi_call(&cif, FFI_FN(checking), &rint, values);
+
+  printf ("%d vs %d\n", (int)rint, checking (si, ss, sc));
+
+  CHECK(rint != 0);
+
+  exit (0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c
new file mode 100755
index 0000000..8aa527e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c
@@ -0,0 +1,152 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Contains structs as parameter of the struct itself.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_16byte1 {
+  double a;
+  float b;
+  int c;
+} cls_struct_16byte1;
+
+typedef struct cls_struct_16byte2 {
+  int ii;
+  double dd;
+  float ff;
+} cls_struct_16byte2;
+
+typedef struct cls_struct_combined {
+  cls_struct_16byte1 d;
+  cls_struct_16byte2 e;
+} cls_struct_combined;
+
+cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0,
+			    struct cls_struct_16byte2 b1,
+			    struct cls_struct_combined b2)
+{
+  struct cls_struct_combined result;
+
+  result.d.a = b0.a + b1.dd + b2.d.a;
+  result.d.b = b0.b + b1.ff + b2.d.b;
+  result.d.c = b0.c + b1.ii + b2.d.c;
+  result.e.ii = b0.c + b1.ii + b2.e.ii;
+  result.e.dd = b0.a + b1.dd + b2.e.dd;
+  result.e.ff = b0.b + b1.ff + b2.e.ff;
+
+  printf("%g %g %d %d %g %g %g %g %d %d %g %g: %g %g %d %d %g %g\n",
+	 b0.a, b0.b, b0.c,
+	 b1.ii, b1.dd, b1.ff,
+	 b2.d.a, b2.d.b, b2.d.c,
+	 b2.e.ii, b2.e.dd, b2.e.ff,
+	 result.d.a, result.d.b, result.d.c,
+	 result.e.ii, result.e.dd, result.e.ff);
+
+  return result;
+}
+
+static void
+cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		       void* userdata __UNUSED__)
+{
+  struct cls_struct_16byte1 b0;
+  struct cls_struct_16byte2 b1;
+  struct cls_struct_combined b2;
+
+  b0 = *(struct cls_struct_16byte1*)(args[0]);
+  b1 = *(struct cls_struct_16byte2*)(args[1]);
+  b2 = *(struct cls_struct_combined*)(args[2]);
+
+
+  *(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[5];
+  ffi_type* cls_struct_fields1[5];
+  ffi_type* cls_struct_fields2[5];
+  ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  cls_struct_type1.size = 0;
+  cls_struct_type1.alignment = 0;
+  cls_struct_type1.type = FFI_TYPE_STRUCT;
+  cls_struct_type1.elements = cls_struct_fields1;
+
+  cls_struct_type2.size = 0;
+  cls_struct_type2.alignment = 0;
+  cls_struct_type2.type = FFI_TYPE_STRUCT;
+  cls_struct_type2.elements = cls_struct_fields2;
+
+  struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
+  struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
+  struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
+				      {3, 1.0, 8.0}};
+  struct cls_struct_combined res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_double;
+  cls_struct_fields[1] = &ffi_type_float;
+  cls_struct_fields[2] = &ffi_type_sint;
+  cls_struct_fields[3] = NULL;
+
+  cls_struct_fields1[0] = &ffi_type_sint;
+  cls_struct_fields1[1] = &ffi_type_double;
+  cls_struct_fields1[2] = &ffi_type_float;
+  cls_struct_fields1[3] = NULL;
+
+  cls_struct_fields2[0] = &cls_struct_type;
+  cls_struct_fields2[1] = &cls_struct_type1;
+  cls_struct_fields2[2] = NULL;
+
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type1;
+  dbl_arg_types[2] = &cls_struct_type2;
+  dbl_arg_types[3] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type2,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &e_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = &g_dbl;
+  args_dbl[3] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl);
+  /* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */
+  CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
+  CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
+  CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
+  CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
+  CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
+  CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
+				     cls_struct_16byte2,
+				     cls_struct_combined))
+	     (code))(e_dbl, f_dbl, g_dbl);
+  /* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */
+  CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
+  CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
+  CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
+  CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
+  CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
+  CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c
new file mode 100755
index 0000000..2a9f515
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c
@@ -0,0 +1,161 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Contains structs as parameter of the struct itself.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_16byte1 {
+  double a;
+  float b;
+  int c;
+} cls_struct_16byte1;
+
+typedef struct cls_struct_16byte2 {
+  int ii;
+  double dd;
+  float ff;
+} cls_struct_16byte2;
+
+typedef struct cls_struct_combined {
+  cls_struct_16byte1 d;
+  cls_struct_16byte2 e;
+} cls_struct_combined;
+
+cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0,
+					   struct cls_struct_16byte2 b1,
+					   struct cls_struct_combined b2,
+					   struct cls_struct_16byte1 b3)
+{
+  struct cls_struct_combined result;
+
+  result.d.a = b0.a + b1.dd + b2.d.a;
+  result.d.b = b0.b + b1.ff + b2.d.b;
+  result.d.c = b0.c + b1.ii + b2.d.c;
+  result.e.ii = b0.c + b1.ii + b2.e.ii;
+  result.e.dd = b0.a + b1.dd + b2.e.dd;
+  result.e.ff = b0.b + b1.ff + b2.e.ff;
+
+  printf("%g %g %d %d %g %g %g %g %d %d %g %g %g %g %d: %g %g %d %d %g %g\n",
+	 b0.a, b0.b, b0.c,
+	 b1.ii, b1.dd, b1.ff,
+	 b2.d.a, b2.d.b, b2.d.c,
+	 b2.e.ii, b2.e.dd, b2.e.ff,
+	 b3.a, b3.b, b3.c,
+	 result.d.a, result.d.b, result.d.c,
+	 result.e.ii, result.e.dd, result.e.ff);
+
+  return result;
+}
+
+static void
+cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+		       void* userdata __UNUSED__)
+{
+  struct cls_struct_16byte1 b0;
+  struct cls_struct_16byte2 b1;
+  struct cls_struct_combined b2;
+  struct cls_struct_16byte1 b3;
+
+  b0 = *(struct cls_struct_16byte1*)(args[0]);
+  b1 = *(struct cls_struct_16byte2*)(args[1]);
+  b2 = *(struct cls_struct_combined*)(args[2]);
+  b3 = *(struct cls_struct_16byte1*)(args[3]);
+
+
+  *(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[5];
+  ffi_type* cls_struct_fields[5];
+  ffi_type* cls_struct_fields1[5];
+  ffi_type* cls_struct_fields2[5];
+  ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  cls_struct_type1.size = 0;
+  cls_struct_type1.alignment = 0;
+  cls_struct_type1.type = FFI_TYPE_STRUCT;
+  cls_struct_type1.elements = cls_struct_fields1;
+
+  cls_struct_type2.size = 0;
+  cls_struct_type2.alignment = 0;
+  cls_struct_type2.type = FFI_TYPE_STRUCT;
+  cls_struct_type2.elements = cls_struct_fields2;
+
+  struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
+  struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
+  struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
+				      {3, 1.0, 8.0}};
+  struct cls_struct_16byte1 h_dbl = { 3.0, 2.0, 4};
+  struct cls_struct_combined res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_double;
+  cls_struct_fields[1] = &ffi_type_float;
+  cls_struct_fields[2] = &ffi_type_sint;
+  cls_struct_fields[3] = NULL;
+
+  cls_struct_fields1[0] = &ffi_type_sint;
+  cls_struct_fields1[1] = &ffi_type_double;
+  cls_struct_fields1[2] = &ffi_type_float;
+  cls_struct_fields1[3] = NULL;
+
+  cls_struct_fields2[0] = &cls_struct_type;
+  cls_struct_fields2[1] = &cls_struct_type1;
+  cls_struct_fields2[2] = NULL;
+
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type1;
+  dbl_arg_types[2] = &cls_struct_type2;
+  dbl_arg_types[3] = &cls_struct_type;
+  dbl_arg_types[4] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type2,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &e_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = &g_dbl;
+  args_dbl[3] = &h_dbl;
+  args_dbl[4] = NULL;
+
+  ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl);
+  /* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */
+  CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
+  CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
+  CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
+  CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
+  CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
+  CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
+				     cls_struct_16byte2,
+				     cls_struct_combined,
+				     cls_struct_16byte1))
+	     (code))(e_dbl, f_dbl, g_dbl, h_dbl);
+  /* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */
+  CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
+  CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
+  CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
+  CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
+  CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
+  CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
+  //  CHECK( 1 == 0);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c
new file mode 100755
index 0000000..d6a718b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c
@@ -0,0 +1,133 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Contains structs as parameter of the struct itself.
+		Sample taken from Alan Modras patch to src/prep_cif.c.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20051010	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+  unsigned long long a;
+  unsigned char b;
+} A;
+
+typedef struct B {
+  unsigned char y;
+  struct A x;
+  unsigned int z;
+} B;
+
+typedef struct C {
+  unsigned long long d;
+  unsigned char e;
+} C;
+
+static B B_fn(struct A b2, struct B b3, struct C b4)
+{
+  struct B result;
+
+  result.x.a = b2.a + b3.x.a + b3.z + b4.d;
+  result.x.b = b2.b + b3.x.b + b3.y + b4.e;
+  result.y = b2.b + b3.x.b + b4.e;
+
+  printf("%d %d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
+	 (int)b3.x.a, b3.x.b, b3.y, b3.z, (int)b4.d, b4.e,
+	 (int)result.x.a, result.x.b, result.y);
+
+  return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+     void* userdata __UNUSED__)
+{
+  struct A b0;
+  struct B b1;
+  struct C b2;
+
+  b0 = *(struct A*)(args[0]);
+  b1 = *(struct B*)(args[1]);
+  b2 = *(struct C*)(args[2]);
+
+  *(B*)resp = B_fn(b0, b1, b2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[4];
+  ffi_type* cls_struct_fields[3];
+  ffi_type* cls_struct_fields1[4];
+  ffi_type* cls_struct_fields2[3];
+  ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
+  ffi_type* dbl_arg_types[4];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  cls_struct_type1.size = 0;
+  cls_struct_type1.alignment = 0;
+  cls_struct_type1.type = FFI_TYPE_STRUCT;
+  cls_struct_type1.elements = cls_struct_fields1;
+
+  cls_struct_type2.size = 0;
+  cls_struct_type2.alignment = 0;
+  cls_struct_type2.type = FFI_TYPE_STRUCT;
+  cls_struct_type2.elements = cls_struct_fields2;
+
+  struct A e_dbl = { 1LL, 7};
+  struct B f_dbl = { 99, {12LL , 127}, 255};
+  struct C g_dbl = { 2LL, 9};
+
+  struct B res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uint64;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = NULL;
+
+  cls_struct_fields1[0] = &ffi_type_uchar;
+  cls_struct_fields1[1] = &cls_struct_type;
+  cls_struct_fields1[2] = &ffi_type_uint;
+  cls_struct_fields1[3] = NULL;
+
+  cls_struct_fields2[0] = &ffi_type_uint64;
+  cls_struct_fields2[1] = &ffi_type_uchar;
+  cls_struct_fields2[2] = NULL;
+
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type1;
+  dbl_arg_types[2] = &cls_struct_type2;
+  dbl_arg_types[3] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &e_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = &g_dbl;
+  args_dbl[3] = NULL;
+
+  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+  /* { dg-output "1 7 12 127 99 255 2 9: 270 242 143" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
+  /* { dg-output "\n1 7 12 127 99 255 2 9: 270 242 143" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c
new file mode 100755
index 0000000..de1584c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c
@@ -0,0 +1,110 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Contains structs as parameter of the struct itself.
+		Sample taken from Alan Modras patch to src/prep_cif.c.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030911	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+  unsigned long a;
+  unsigned char b;
+} A;
+
+typedef struct B {
+  struct A x;
+  unsigned char y;
+} B;
+
+B B_fn(struct A b0, struct B b1)
+{
+  struct B result;
+
+  result.x.a = b0.a + b1.x.a;
+  result.x.b = b0.b + b1.x.b + b1.y;
+  result.y = b0.b + b1.x.b;
+
+  printf("%lu %d %lu %d %d: %lu %d %d\n", b0.a, b0.b, b1.x.a, b1.x.b, b1.y,
+	 result.x.a, result.x.b, result.y);
+
+  return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+     void* userdata __UNUSED__)
+{
+  struct A b0;
+  struct B b1;
+
+  b0 = *(struct A*)(args[0]);
+  b1 = *(struct B*)(args[1]);
+
+  *(B*)resp = B_fn(b0, b1);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[3];
+  ffi_type* cls_struct_fields[3];
+  ffi_type* cls_struct_fields1[3];
+  ffi_type cls_struct_type, cls_struct_type1;
+  ffi_type* dbl_arg_types[3];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  cls_struct_type1.size = 0;
+  cls_struct_type1.alignment = 0;
+  cls_struct_type1.type = FFI_TYPE_STRUCT;
+  cls_struct_type1.elements = cls_struct_fields1;
+
+  struct A e_dbl = { 1, 7};
+  struct B f_dbl = {{12 , 127}, 99};
+
+  struct B res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_ulong;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = NULL;
+
+  cls_struct_fields1[0] = &cls_struct_type;
+  cls_struct_fields1[1] = &ffi_type_uchar;
+  cls_struct_fields1[2] = NULL;
+
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type1;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &e_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+  /* { dg-output "1 7 12 127 99: 13 233 134" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
+  /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c
new file mode 100755
index 0000000..58aa853
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c
@@ -0,0 +1,111 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Contains structs as parameter of the struct itself.
+		Sample taken from Alan Modras patch to src/prep_cif.c.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030911	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+  unsigned long long a;
+  unsigned char b;
+} A;
+
+typedef struct B {
+  struct A x;
+  unsigned char y;
+} B;
+
+B B_fn(struct A b0, struct B b1)
+{
+  struct B result;
+
+  result.x.a = b0.a + b1.x.a;
+  result.x.b = b0.b + b1.x.b + b1.y;
+  result.y = b0.b + b1.x.b;
+
+  printf("%d %d %d %d %d: %d %d %d\n", (int)b0.a, b0.b,
+	 (int)b1.x.a, b1.x.b, b1.y,
+	 (int)result.x.a, result.x.b, result.y);
+
+  return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+     void* userdata __UNUSED__)
+{
+  struct A b0;
+  struct B b1;
+
+  b0 = *(struct A*)(args[0]);
+  b1 = *(struct B*)(args[1]);
+
+  *(B*)resp = B_fn(b0, b1);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[3];
+  ffi_type* cls_struct_fields[3];
+  ffi_type* cls_struct_fields1[3];
+  ffi_type cls_struct_type, cls_struct_type1;
+  ffi_type* dbl_arg_types[3];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  cls_struct_type1.size = 0;
+  cls_struct_type1.alignment = 0;
+  cls_struct_type1.type = FFI_TYPE_STRUCT;
+  cls_struct_type1.elements = cls_struct_fields1;
+
+  struct A e_dbl = { 1LL, 7};
+  struct B f_dbl = {{12LL , 127}, 99};
+
+  struct B res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uint64;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = NULL;
+
+  cls_struct_fields1[0] = &cls_struct_type;
+  cls_struct_fields1[1] = &ffi_type_uchar;
+  cls_struct_fields1[2] = NULL;
+
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type1;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &e_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+  /* { dg-output "1 7 12 127 99: 13 233 134" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
+  /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c
new file mode 100755
index 0000000..98e491e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c
@@ -0,0 +1,111 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Contains structs as parameter of the struct itself.
+		Sample taken from Alan Modras patch to src/prep_cif.c.
+   Limitations:	none.
+   PR:		PR 25630.
+   Originator:	<andreast at gcc.gnu.org> 20051010	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+  double a;
+  unsigned char b;
+} A;
+
+typedef struct B {
+  struct A x;
+  unsigned char y;
+} B;
+
+static B B_fn(struct A b2, struct B b3)
+{
+  struct B result;
+
+  result.x.a = b2.a + b3.x.a;
+  result.x.b = b2.b + b3.x.b + b3.y;
+  result.y = b2.b + b3.x.b;
+
+  printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
+	 (int)b3.x.a, b3.x.b, b3.y,
+	 (int)result.x.a, result.x.b, result.y);
+
+  return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+     void* userdata __UNUSED__)
+{
+  struct A b0;
+  struct B b1;
+
+  b0 = *(struct A*)(args[0]);
+  b1 = *(struct B*)(args[1]);
+
+  *(B*)resp = B_fn(b0, b1);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[3];
+  ffi_type* cls_struct_fields[3];
+  ffi_type* cls_struct_fields1[3];
+  ffi_type cls_struct_type, cls_struct_type1;
+  ffi_type* dbl_arg_types[3];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  cls_struct_type1.size = 0;
+  cls_struct_type1.alignment = 0;
+  cls_struct_type1.type = FFI_TYPE_STRUCT;
+  cls_struct_type1.elements = cls_struct_fields1;
+
+  struct A e_dbl = { 1.0, 7};
+  struct B f_dbl = {{12.0 , 127}, 99};
+
+  struct B res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_double;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = NULL;
+
+  cls_struct_fields1[0] = &cls_struct_type;
+  cls_struct_fields1[1] = &ffi_type_uchar;
+  cls_struct_fields1[2] = NULL;
+
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type1;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &e_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+  /* { dg-output "1 7 12 127 99: 13 233 134" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
+  /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c
new file mode 100755
index 0000000..d8e3537
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c
@@ -0,0 +1,112 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Contains structs as parameter of the struct itself.
+		Sample taken from Alan Modras patch to src/prep_cif.c.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20051010	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+  long double a;
+  unsigned char b;
+} A;
+
+typedef struct B {
+  struct A x;
+  unsigned char y;
+} B;
+
+static B B_fn(struct A b2, struct B b3)
+{
+  struct B result;
+
+  result.x.a = b2.a + b3.x.a;
+  result.x.b = b2.b + b3.x.b + b3.y;
+  result.y = b2.b + b3.x.b;
+
+  printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
+	 (int)b3.x.a, b3.x.b, b3.y,
+	 (int)result.x.a, result.x.b, result.y);
+
+  return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+     void* userdata __UNUSED__)
+{
+  struct A b0;
+  struct B b1;
+
+  b0 = *(struct A*)(args[0]);
+  b1 = *(struct B*)(args[1]);
+
+  *(B*)resp = B_fn(b0, b1);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[3];
+  ffi_type* cls_struct_fields[3];
+  ffi_type* cls_struct_fields1[3];
+  ffi_type cls_struct_type, cls_struct_type1;
+  ffi_type* dbl_arg_types[3];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  cls_struct_type1.size = 0;
+  cls_struct_type1.alignment = 0;
+  cls_struct_type1.type = FFI_TYPE_STRUCT;
+  cls_struct_type1.elements = cls_struct_fields1;
+
+  struct A e_dbl = { 1.0, 7};
+  struct B f_dbl = {{12.0 , 127}, 99};
+
+  struct B res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_longdouble;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = NULL;
+
+  cls_struct_fields1[0] = &cls_struct_type;
+  cls_struct_fields1[1] = &ffi_type_uchar;
+  cls_struct_fields1[2] = NULL;
+
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type1;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &e_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+  /* { dg-output "1 7 12 127 99: 13 233 134" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
+  /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c
new file mode 100755
index 0000000..2f2b25a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c
@@ -0,0 +1,131 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Contains structs as parameter of the struct itself.
+		Sample taken from Alan Modras patch to src/prep_cif.c.
+   Limitations:	none.
+   PR:		PR 25630.
+   Originator:	<andreast at gcc.gnu.org> 20051010	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+  double a;
+  unsigned char b;
+} A;
+
+typedef struct B {
+  struct A x;
+  unsigned char y;
+} B;
+
+typedef struct C {
+  long d;
+  unsigned char e;
+} C;
+
+static B B_fn(struct A b2, struct B b3, struct C b4)
+{
+  struct B result;
+
+  result.x.a = b2.a + b3.x.a + b4.d;
+  result.x.b = b2.b + b3.x.b + b3.y + b4.e;
+  result.y = b2.b + b3.x.b + b4.e;
+
+  printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
+	 (int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e,
+	 (int)result.x.a, result.x.b, result.y);
+
+  return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+     void* userdata __UNUSED__)
+{
+  struct A b0;
+  struct B b1;
+  struct C b2;
+
+  b0 = *(struct A*)(args[0]);
+  b1 = *(struct B*)(args[1]);
+  b2 = *(struct C*)(args[2]);
+
+  *(B*)resp = B_fn(b0, b1, b2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[4];
+  ffi_type* cls_struct_fields[3];
+  ffi_type* cls_struct_fields1[3];
+  ffi_type* cls_struct_fields2[3];
+  ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
+  ffi_type* dbl_arg_types[4];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  cls_struct_type1.size = 0;
+  cls_struct_type1.alignment = 0;
+  cls_struct_type1.type = FFI_TYPE_STRUCT;
+  cls_struct_type1.elements = cls_struct_fields1;
+
+  cls_struct_type2.size = 0;
+  cls_struct_type2.alignment = 0;
+  cls_struct_type2.type = FFI_TYPE_STRUCT;
+  cls_struct_type2.elements = cls_struct_fields2;
+
+  struct A e_dbl = { 1.0, 7};
+  struct B f_dbl = {{12.0 , 127}, 99};
+  struct C g_dbl = { 2, 9};
+
+  struct B res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_double;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = NULL;
+
+  cls_struct_fields1[0] = &cls_struct_type;
+  cls_struct_fields1[1] = &ffi_type_uchar;
+  cls_struct_fields1[2] = NULL;
+
+  cls_struct_fields2[0] = &ffi_type_slong;
+  cls_struct_fields2[1] = &ffi_type_uchar;
+  cls_struct_fields2[2] = NULL;
+
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type1;
+  dbl_arg_types[2] = &cls_struct_type2;
+  dbl_arg_types[3] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &e_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = &g_dbl;
+  args_dbl[3] = NULL;
+
+  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+  /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
+  /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c
new file mode 100755
index 0000000..14c7023
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c
@@ -0,0 +1,111 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Contains structs as parameter of the struct itself.
+		Sample taken from Alan Modras patch to src/prep_cif.c.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20051010	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+  unsigned long long a;
+  unsigned char b;
+} A;
+
+typedef struct B {
+  struct A x;
+  unsigned char y;
+} B;
+
+static B B_fn(struct A b2, struct B b3)
+{
+  struct B result;
+
+  result.x.a = b2.a + b3.x.a;
+  result.x.b = b2.b + b3.x.b + b3.y;
+  result.y = b2.b + b3.x.b;
+
+  printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
+	 (int)b3.x.a, b3.x.b, b3.y,
+	 (int)result.x.a, result.x.b, result.y);
+
+  return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+     void* userdata __UNUSED__)
+{
+  struct A b0;
+  struct B b1;
+
+  b0 = *(struct A*)(args[0]);
+  b1 = *(struct B*)(args[1]);
+
+  *(B*)resp = B_fn(b0, b1);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[3];
+  ffi_type* cls_struct_fields[3];
+  ffi_type* cls_struct_fields1[3];
+  ffi_type cls_struct_type, cls_struct_type1;
+  ffi_type* dbl_arg_types[3];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  cls_struct_type1.size = 0;
+  cls_struct_type1.alignment = 0;
+  cls_struct_type1.type = FFI_TYPE_STRUCT;
+  cls_struct_type1.elements = cls_struct_fields1;
+
+  struct A e_dbl = { 1LL, 7};
+  struct B f_dbl = {{12.0 , 127}, 99};
+
+  struct B res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uint64;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = NULL;
+
+  cls_struct_fields1[0] = &cls_struct_type;
+  cls_struct_fields1[1] = &ffi_type_uchar;
+  cls_struct_fields1[2] = NULL;
+
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type1;
+  dbl_arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &e_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = NULL;
+
+  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+  /* { dg-output "1 7 12 127 99: 13 233 134" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
+  /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c
new file mode 100755
index 0000000..bb77ead
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c
@@ -0,0 +1,131 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Contains structs as parameter of the struct itself.
+		Sample taken from Alan Modras patch to src/prep_cif.c.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20051010	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+  unsigned long long a;
+  unsigned char b;
+} A;
+
+typedef struct B {
+  struct A x;
+  unsigned char y;
+} B;
+
+typedef struct C {
+  unsigned long long d;
+  unsigned char e;
+} C;
+
+static B B_fn(struct A b2, struct B b3, struct C b4)
+{
+  struct B result;
+
+  result.x.a = b2.a + b3.x.a + b4.d;
+  result.x.b = b2.b + b3.x.b + b3.y + b4.e;
+  result.y = b2.b + b3.x.b + b4.e;
+
+  printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
+	 (int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e,
+	 (int)result.x.a, result.x.b, result.y);
+
+  return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+     void* userdata __UNUSED__)
+{
+  struct A b0;
+  struct B b1;
+  struct C b2;
+
+  b0 = *(struct A*)(args[0]);
+  b1 = *(struct B*)(args[1]);
+  b2 = *(struct C*)(args[2]);
+
+  *(B*)resp = B_fn(b0, b1, b2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[4];
+  ffi_type* cls_struct_fields[3];
+  ffi_type* cls_struct_fields1[3];
+  ffi_type* cls_struct_fields2[3];
+  ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
+  ffi_type* dbl_arg_types[4];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  cls_struct_type1.size = 0;
+  cls_struct_type1.alignment = 0;
+  cls_struct_type1.type = FFI_TYPE_STRUCT;
+  cls_struct_type1.elements = cls_struct_fields1;
+
+  cls_struct_type2.size = 0;
+  cls_struct_type2.alignment = 0;
+  cls_struct_type2.type = FFI_TYPE_STRUCT;
+  cls_struct_type2.elements = cls_struct_fields2;
+
+  struct A e_dbl = { 1LL, 7};
+  struct B f_dbl = {{12LL , 127}, 99};
+  struct C g_dbl = { 2LL, 9};
+
+  struct B res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uint64;
+  cls_struct_fields[1] = &ffi_type_uchar;
+  cls_struct_fields[2] = NULL;
+
+  cls_struct_fields1[0] = &cls_struct_type;
+  cls_struct_fields1[1] = &ffi_type_uchar;
+  cls_struct_fields1[2] = NULL;
+
+  cls_struct_fields2[0] = &ffi_type_uint64;
+  cls_struct_fields2[1] = &ffi_type_uchar;
+  cls_struct_fields2[2] = NULL;
+
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type1;
+  dbl_arg_types[2] = &cls_struct_type2;
+  dbl_arg_types[3] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &e_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = &g_dbl;
+  args_dbl[3] = NULL;
+
+  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+  /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
+  /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c
new file mode 100755
index 0000000..e9f541c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c
@@ -0,0 +1,131 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+		Contains structs as parameter of the struct itself.
+		Sample taken from Alan Modras patch to src/prep_cif.c.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20051010	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+  unsigned char a;
+  unsigned long long b;
+} A;
+
+typedef struct B {
+  struct A x;
+  unsigned char y;
+} B;
+
+typedef struct C {
+  unsigned long d;
+  unsigned char e;
+} C;
+
+static B B_fn(struct A b2, struct B b3, struct C b4)
+{
+  struct B result;
+
+  result.x.a = b2.a + b3.x.a + b4.d;
+  result.x.b = b2.b + b3.x.b + b3.y + b4.e;
+  result.y = b2.b + b3.x.b + b4.e;
+
+  printf("%d %d %d %d %d %d %d: %d %d %d\n", b2.a, (int)b2.b,
+	 b3.x.a, (int)b3.x.b, b3.y, (int)b4.d, b4.e,
+	 result.x.a, (int)result.x.b, result.y);
+
+  return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+     void* userdata __UNUSED__)
+{
+  struct A b0;
+  struct B b1;
+  struct C b2;
+
+  b0 = *(struct A*)(args[0]);
+  b1 = *(struct B*)(args[1]);
+  b2 = *(struct C*)(args[2]);
+
+  *(B*)resp = B_fn(b0, b1, b2);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args_dbl[4];
+  ffi_type* cls_struct_fields[3];
+  ffi_type* cls_struct_fields1[3];
+  ffi_type* cls_struct_fields2[3];
+  ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
+  ffi_type* dbl_arg_types[4];
+
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
+  cls_struct_type1.size = 0;
+  cls_struct_type1.alignment = 0;
+  cls_struct_type1.type = FFI_TYPE_STRUCT;
+  cls_struct_type1.elements = cls_struct_fields1;
+
+  cls_struct_type2.size = 0;
+  cls_struct_type2.alignment = 0;
+  cls_struct_type2.type = FFI_TYPE_STRUCT;
+  cls_struct_type2.elements = cls_struct_fields2;
+
+  struct A e_dbl = { 1, 7LL};
+  struct B f_dbl = {{12.0 , 127}, 99};
+  struct C g_dbl = { 2, 9};
+
+  struct B res_dbl;
+
+  cls_struct_fields[0] = &ffi_type_uchar;
+  cls_struct_fields[1] = &ffi_type_uint64;
+  cls_struct_fields[2] = NULL;
+
+  cls_struct_fields1[0] = &cls_struct_type;
+  cls_struct_fields1[1] = &ffi_type_uchar;
+  cls_struct_fields1[2] = NULL;
+
+  cls_struct_fields2[0] = &ffi_type_ulong;
+  cls_struct_fields2[1] = &ffi_type_uchar;
+  cls_struct_fields2[2] = NULL;
+
+
+  dbl_arg_types[0] = &cls_struct_type;
+  dbl_arg_types[1] = &cls_struct_type1;
+  dbl_arg_types[2] = &cls_struct_type2;
+  dbl_arg_types[3] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
+		     dbl_arg_types) == FFI_OK);
+
+  args_dbl[0] = &e_dbl;
+  args_dbl[1] = &f_dbl;
+  args_dbl[2] = &g_dbl;
+  args_dbl[3] = NULL;
+
+  ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+  /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+  res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
+  /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
+  CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
+  CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
+  CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/problem1.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/problem1.c
new file mode 100755
index 0000000..6a91555
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/problem1.c
@@ -0,0 +1,90 @@
+/* Area:	ffi_call, closure_call
+   Purpose:	Check structure passing with different structure size.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20030828	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct my_ffi_struct {
+  double a;
+  double b;
+  double c;
+} my_ffi_struct;
+
+my_ffi_struct callee(struct my_ffi_struct a1, struct my_ffi_struct a2)
+{
+  struct my_ffi_struct result;
+  result.a = a1.a + a2.a;
+  result.b = a1.b + a2.b;
+  result.c = a1.c + a2.c;
+
+
+  printf("%g %g %g %g %g %g: %g %g %g\n", a1.a, a1.b, a1.c,
+	 a2.a, a2.b, a2.c, result.a, result.b, result.c);
+
+  return result;
+}
+
+void stub(ffi_cif* cif __UNUSED__, void* resp, void** args,
+	  void* userdata __UNUSED__)
+{
+  struct my_ffi_struct a1;
+  struct my_ffi_struct a2;
+
+  a1 = *(struct my_ffi_struct*)(args[0]);
+  a2 = *(struct my_ffi_struct*)(args[1]);
+
+  *(my_ffi_struct *)resp = callee(a1, a2);
+}
+
+
+int main(void)
+{
+  ffi_type* my_ffi_struct_fields[4];
+  ffi_type my_ffi_struct_type;
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  void* args[4];
+  ffi_type* arg_types[3];
+
+  struct my_ffi_struct g = { 1.0, 2.0, 3.0 };
+  struct my_ffi_struct f = { 1.0, 2.0, 3.0 };
+  struct my_ffi_struct res;
+
+  my_ffi_struct_type.size = 0;
+  my_ffi_struct_type.alignment = 0;
+  my_ffi_struct_type.type = FFI_TYPE_STRUCT;
+  my_ffi_struct_type.elements = my_ffi_struct_fields;
+
+  my_ffi_struct_fields[0] = &ffi_type_double;
+  my_ffi_struct_fields[1] = &ffi_type_double;
+  my_ffi_struct_fields[2] = &ffi_type_double;
+  my_ffi_struct_fields[3] = NULL;
+
+  arg_types[0] = &my_ffi_struct_type;
+  arg_types[1] = &my_ffi_struct_type;
+  arg_types[2] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &my_ffi_struct_type,
+		     arg_types) == FFI_OK);
+
+  args[0] = &g;
+  args[1] = &f;
+  args[2] = NULL;
+  ffi_call(&cif, FFI_FN(callee), &res, args);
+  /* { dg-output "1 2 3 1 2 3: 2 4 6" } */
+  printf("res: %g %g %g\n", res.a, res.b, res.c);
+  /* { dg-output "\nres: 2 4 6" } */
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, stub, NULL, code) == FFI_OK);
+
+  res = ((my_ffi_struct(*)(struct my_ffi_struct, struct my_ffi_struct))(code))(g, f);
+  /* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */
+  printf("res: %g %g %g\n", res.a, res.b, res.c);
+  /* { dg-output "\nres: 2 4 6" } */
+
+  exit(0);;
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/promotion.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/promotion.c
new file mode 100755
index 0000000..4456161
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/promotion.c
@@ -0,0 +1,59 @@
+/* Area:	ffi_call
+   Purpose:	Promotion test.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+static int promotion(signed char sc, signed short ss,
+		     unsigned char uc, unsigned short us)
+{
+  int r = (int) sc + (int) ss + (int) uc + (int) us;
+
+  return r;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_arg rint;
+  signed char sc;
+  unsigned char uc;
+  signed short ss;
+  unsigned short us;
+  unsigned long ul;
+
+  args[0] = &ffi_type_schar;
+  args[1] = &ffi_type_sshort;
+  args[2] = &ffi_type_uchar;
+  args[3] = &ffi_type_ushort;
+  values[0] = ≻
+  values[1] = &ss;
+  values[2] = &uc;
+  values[3] = &us;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+		     &ffi_type_sint, args) == FFI_OK);
+
+  us = 0;
+  ul = 0;
+
+  for (sc = (signed char) -127;
+       sc <= (signed char) 120; sc += 1)
+    for (ss = -30000; ss <= 30000; ss += 10000)
+      for (uc = (unsigned char) 0;
+	   uc <= (unsigned char) 200; uc += 20)
+	for (us = 0; us <= 60000; us += 10000)
+	  {
+	    ul++;
+	    ffi_call(&cif, FFI_FN(promotion), &rint, values);
+	    CHECK((int)rint == (signed char) sc + (signed short) ss +
+		  (unsigned char) uc + (unsigned short) us);
+	  }
+  printf("%lu promotion tests run\n", ul);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/pyobjc-tc.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/pyobjc-tc.c
new file mode 100755
index 0000000..e29bd6c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/pyobjc-tc.c
@@ -0,0 +1,114 @@
+/* Area:	ffi_call
+   Purpose:	Check different structures.
+   Limitations:	none.
+   PR:		none.
+   Originator:	Ronald Oussoren <oussoren at cistron.nl> 20030824	*/
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct Point {
+	float x;
+	float y;
+} Point;
+
+typedef struct Size {
+	float h;
+	float w;
+} Size;
+
+typedef struct Rect {
+	Point o;
+	Size  s;
+} Rect;
+
+int doit(int o, char* s, Point p, Rect r, int last)
+{
+	printf("CALLED WITH %d %s {%f %f} {{%f %f} {%f %f}} %d\n",
+		o, s, p.x, p.y, r.o.x, r.o.y, r.s.h, r.s.w, last);
+	return 42;
+}
+
+
+int main(void)
+{
+	ffi_type point_type;
+	ffi_type size_type;
+	ffi_type rect_type;
+	ffi_cif cif;
+	ffi_type* arglist[6];
+	void* values[6];
+	int r;
+
+	/*
+	 *  First set up FFI types for the 3 struct types
+	 */
+
+	point_type.size = 0; /*sizeof(Point);*/
+	point_type.alignment = 0; /*__alignof__(Point);*/
+	point_type.type = FFI_TYPE_STRUCT;
+	point_type.elements = malloc(3 * sizeof(ffi_type*));
+	point_type.elements[0] = &ffi_type_float;
+	point_type.elements[1] = &ffi_type_float;
+	point_type.elements[2] = NULL;
+
+	size_type.size = 0;/* sizeof(Size);*/
+	size_type.alignment = 0;/* __alignof__(Size);*/
+	size_type.type = FFI_TYPE_STRUCT;
+	size_type.elements = malloc(3 * sizeof(ffi_type*));
+	size_type.elements[0] = &ffi_type_float;
+	size_type.elements[1] = &ffi_type_float;
+	size_type.elements[2] = NULL;
+
+	rect_type.size = 0;/*sizeof(Rect);*/
+	rect_type.alignment =0;/* __alignof__(Rect);*/
+	rect_type.type = FFI_TYPE_STRUCT;
+	rect_type.elements = malloc(3 * sizeof(ffi_type*));
+	rect_type.elements[0] = &point_type;
+	rect_type.elements[1] = &size_type;
+	rect_type.elements[2] = NULL;
+
+	/*
+	 * Create a CIF
+	 */
+	arglist[0] = &ffi_type_sint;
+	arglist[1] = &ffi_type_pointer;
+	arglist[2] = &point_type;
+	arglist[3] = &rect_type;
+	arglist[4] = &ffi_type_sint;
+	arglist[5] = NULL;
+
+	r = ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
+			5, &ffi_type_sint, arglist);
+	if (r != FFI_OK) {
+		abort();
+	}
+
+
+	/* And call the function through the CIF */
+
+	{
+	Point p = { 1.0, 2.0 };
+	Rect  r = { { 9.0, 10.0}, { -1.0, -2.0 } };
+	int   o = 0;
+	int   l = 42;
+	char* m = "myMethod";
+	ffi_arg result;
+
+	values[0] = &o;
+	values[1] = &m;
+	values[2] = &p;
+	values[3] = &r;
+	values[4] = &l;
+	values[5] = NULL;
+
+	printf("CALLING WITH %d %s {%f %f} {{%f %f} {%f %f}} %d\n",
+		o, m, p.x, p.y, r.o.x, r.o.y, r.s.h, r.s.w, l);
+
+	ffi_call(&cif, FFI_FN(doit), &result, values);
+
+	printf ("The result is %d\n", (int)result);
+
+	}
+	exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c
new file mode 100755
index 0000000..1aab403
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c
@@ -0,0 +1,35 @@
+/* Area:	ffi_call
+   Purpose:	Check return value double.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20050212  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static double return_dbl(double dbl)
+{
+  return 2 * dbl;
+}
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  double dbl, rdbl;
+
+  args[0] = &ffi_type_double;
+  values[0] = &dbl;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_double, args) == FFI_OK);
+
+  for (dbl = -127.3; dbl <  127; dbl++)
+    {
+      ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values);
+      printf ("%f vs %f\n", rdbl, return_dbl(dbl));
+      CHECK(rdbl == 2 * dbl);
+    }
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl1.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl1.c
new file mode 100755
index 0000000..0ea5d50
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl1.c
@@ -0,0 +1,43 @@
+/* Area:	ffi_call
+   Purpose:	Check return value double.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20050212  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static double return_dbl(double dbl1, float fl2, unsigned int in3, double dbl4)
+{
+  return dbl1 + fl2 + in3 + dbl4;
+}
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  double dbl1, dbl4, rdbl;
+  float fl2;
+  unsigned int in3;
+  args[0] = &ffi_type_double;
+  args[1] = &ffi_type_float;
+  args[2] = &ffi_type_uint;
+  args[3] = &ffi_type_double;
+  values[0] = &dbl1;
+  values[1] = &fl2;
+  values[2] = &in3;
+  values[3] = &dbl4;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+		     &ffi_type_double, args) == FFI_OK);
+  dbl1 = 127.0;
+  fl2 = 128.0;
+  in3 = 255;
+  dbl4 = 512.7;
+
+  ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values);
+  printf ("%f vs %f\n", rdbl, return_dbl(dbl1, fl2, in3, dbl4));
+  CHECK(rdbl ==  dbl1 + fl2 + in3 + dbl4);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl2.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl2.c
new file mode 100755
index 0000000..b3818f8
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl2.c
@@ -0,0 +1,42 @@
+/* Area:	ffi_call
+   Purpose:	Check return value double.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20050212  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static double return_dbl(double dbl1, double dbl2, unsigned int in3, double dbl4)
+{
+  return dbl1 + dbl2 + in3 + dbl4;
+}
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  double dbl1, dbl2, dbl4, rdbl;
+  unsigned int in3;
+  args[0] = &ffi_type_double;
+  args[1] = &ffi_type_double;
+  args[2] = &ffi_type_uint;
+  args[3] = &ffi_type_double;
+  values[0] = &dbl1;
+  values[1] = &dbl2;
+  values[2] = &in3;
+  values[3] = &dbl4;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+		     &ffi_type_double, args) == FFI_OK);
+  dbl1 = 127.0;
+  dbl2 = 128.0;
+  in3 = 255;
+  dbl4 = 512.7;
+
+  ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values);
+  printf ("%f vs %f\n", rdbl, return_dbl(dbl1, dbl2, in3, dbl4));
+  CHECK(rdbl ==  dbl1 + dbl2 + in3 + dbl4);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_fl.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_fl.c
new file mode 100755
index 0000000..fb8a09e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_fl.c
@@ -0,0 +1,35 @@
+/* Area:	ffi_call
+   Purpose:	Check return value float.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20050212  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static float return_fl(float fl)
+{
+  return 2 * fl;
+}
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  float fl, rfl;
+
+  args[0] = &ffi_type_float;
+  values[0] = &fl;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_float, args) == FFI_OK);
+
+  for (fl = -127.0; fl <  127; fl++)
+    {
+      ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
+      printf ("%f vs %f\n", rfl, return_fl(fl));
+      CHECK(rfl ==  2 * fl);
+    }
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_fl1.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_fl1.c
new file mode 100755
index 0000000..c3d92c2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_fl1.c
@@ -0,0 +1,36 @@
+/* Area:	ffi_call
+   Purpose:	Check return value float.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20050212  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static float return_fl(float fl1, float fl2)
+{
+  return fl1 + fl2;
+}
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  float fl1, fl2, rfl;
+
+  args[0] = &ffi_type_float;
+  args[1] = &ffi_type_float;
+  values[0] = &fl1;
+  values[1] = &fl2;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+		     &ffi_type_float, args) == FFI_OK);
+  fl1 = 127.0;
+  fl2 = 128.0;
+
+  ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
+  printf ("%f vs %f\n", rfl, return_fl(fl1, fl2));
+  CHECK(rfl ==  fl1 + fl2);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_fl2.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_fl2.c
new file mode 100755
index 0000000..ddb976c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_fl2.c
@@ -0,0 +1,49 @@
+/* Area:	ffi_call
+   Purpose:	Check return value float.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20050212  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+/* Use volatile float to avoid false negative on ix86.  See PR target/323.  */
+static float return_fl(float fl1, float fl2, float fl3, float fl4)
+{
+  volatile float sum;
+
+  sum = fl1 + fl2 + fl3 + fl4;
+  return sum;
+}
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  float fl1, fl2, fl3, fl4, rfl;
+  volatile float sum;
+
+  args[0] = &ffi_type_float;
+  args[1] = &ffi_type_float;
+  args[2] = &ffi_type_float;
+  args[3] = &ffi_type_float;
+  values[0] = &fl1;
+  values[1] = &fl2;
+  values[2] = &fl3;
+  values[3] = &fl4;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+		     &ffi_type_float, args) == FFI_OK);
+  fl1 = 127.0;
+  fl2 = 128.0;
+  fl3 = 255.1;
+  fl4 = 512.7;
+
+  ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
+  printf ("%f vs %f\n", rfl, return_fl(fl1, fl2, fl3, fl4));
+
+  sum = fl1 + fl2 + fl3 + fl4;
+  CHECK(rfl == sum);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_fl3.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_fl3.c
new file mode 100755
index 0000000..c37877b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_fl3.c
@@ -0,0 +1,42 @@
+/* Area:	ffi_call
+   Purpose:	Check return value float.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20050212  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static float return_fl(float fl1, float fl2, unsigned int in3, float fl4)
+{
+  return fl1 + fl2 + in3 + fl4;
+}
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  float fl1, fl2, fl4, rfl;
+  unsigned int in3;
+  args[0] = &ffi_type_float;
+  args[1] = &ffi_type_float;
+  args[2] = &ffi_type_uint;
+  args[3] = &ffi_type_float;
+  values[0] = &fl1;
+  values[1] = &fl2;
+  values[2] = &in3;
+  values[3] = &fl4;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+		     &ffi_type_float, args) == FFI_OK);
+  fl1 = 127.0;
+  fl2 = 128.0;
+  in3 = 255;
+  fl4 = 512.7;
+
+  ffi_call(&cif, FFI_FN(return_fl), &rfl, values);
+  printf ("%f vs %f\n", rfl, return_fl(fl1, fl2, in3, fl4));
+  CHECK(rfl ==  fl1 + fl2 + in3 + fl4);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c
new file mode 100755
index 0000000..5c2fe65
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c
@@ -0,0 +1,34 @@
+/* Area:	ffi_call
+   Purpose:	Check return value long double.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast at gcc.gnu.org> 20071113  */
+
+/* { dg-do run { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
+#include "ffitest.h"
+
+static long double return_ldl(long double ldl)
+{
+  return 2*ldl;
+}
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  long double ldl, rldl;
+
+  args[0] = &ffi_type_longdouble;
+  values[0] = &ldl;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_longdouble, args) == FFI_OK);
+
+  for (ldl = -127.0; ldl <  127.0; ldl++)
+    {
+      ffi_call(&cif, FFI_FN(return_ldl), &rldl, values);
+      CHECK(rldl ==  2 * ldl);
+    }
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_ll.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_ll.c
new file mode 100755
index 0000000..ea4a1e4
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_ll.c
@@ -0,0 +1,41 @@
+/* Area:	ffi_call
+   Purpose:	Check return value long long.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+static long long return_ll(long long ll)
+{
+  return ll;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  long long rlonglong;
+  long long ll;
+
+  args[0] = &ffi_type_sint64;
+  values[0] = ≪
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_sint64, args) == FFI_OK);
+
+  for (ll = 0LL; ll < 100LL; ll++)
+    {
+      ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
+      CHECK(rlonglong == ll);
+    }
+
+  for (ll = 55555555555000LL; ll < 55555555555100LL; ll++)
+    {
+      ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
+      CHECK(rlonglong == ll);
+    }
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c
new file mode 100755
index 0000000..593e8a3
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c
@@ -0,0 +1,43 @@
+/* Area:	ffi_call
+   Purpose:	Check if long long are passed in the corresponding regs on ppc.
+   Limitations:	none.
+   PR:		20104.
+   Originator:	<andreast at gcc.gnu.org> 20050222  */
+
+/* { dg-do run } */
+/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
+#include "ffitest.h"
+static long long return_ll(int ll0, long long ll1, int ll2)
+{
+  return ll0 + ll1 + ll2;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  long long rlonglong;
+  long long ll1;
+  unsigned ll0, ll2;
+
+  args[0] = &ffi_type_sint;
+  args[1] = &ffi_type_sint64;
+  args[2] = &ffi_type_sint;
+  values[0] = &ll0;
+  values[1] = &ll1;
+  values[2] = &ll2;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+		     &ffi_type_sint64, args) == FFI_OK);
+
+  ll0 = 11111111;
+  ll1 = 11111111111000LL;
+  ll2 = 11111111;
+
+  ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
+  printf("res: %" PRIdLL ", %" PRIdLL "\n", rlonglong, ll0 + ll1 + ll2);
+  /* { dg-output "res: 11111133333222, 11111133333222" } */
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c
new file mode 100755
index 0000000..19608ee
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c
@@ -0,0 +1,36 @@
+/* Area:	ffi_call
+   Purpose:	Check return value signed char.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static signed char return_sc(signed char sc)
+{
+  return sc;
+}
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_arg rint;
+  signed char sc;
+
+  args[0] = &ffi_type_schar;
+  values[0] = ≻
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_schar, args) == FFI_OK);
+
+  for (sc = (signed char) -127;
+       sc < (signed char) 127; sc++)
+    {
+      ffi_call(&cif, FFI_FN(return_sc), &rint, values);
+      CHECK(rint == (ffi_arg) sc);
+    }
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c
new file mode 100755
index 0000000..f0fd345
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c
@@ -0,0 +1,38 @@
+/* Area:	ffi_call
+   Purpose:	Check if long as return type is handled correctly.
+   Limitations:	none.
+   PR:		none.
+ */
+
+/* { dg-do run } */
+#include "ffitest.h"
+static long return_sl(long l1, long l2)
+{
+  return l1 - l2;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_arg res;
+  unsigned long l1, l2;
+
+  args[0] = &ffi_type_slong;
+  args[1] = &ffi_type_slong;
+  values[0] = &l1;
+  values[1] = &l2;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+		     &ffi_type_slong, args) == FFI_OK);
+
+  l1 = 1073741823L;
+  l2 = 1073741824L;
+
+  ffi_call(&cif, FFI_FN(return_sl), &res, values);
+  printf("res: %ld, %ld\n", (long)res, l1 - l2);
+  /* { dg-output "res: -1, -1" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c
new file mode 100755
index 0000000..07c45de
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c
@@ -0,0 +1,38 @@
+/* Area:	ffi_call
+   Purpose:	Check return value unsigned char.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static unsigned char return_uc(unsigned char uc)
+{
+  return uc;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_arg rint;
+
+  unsigned char uc;
+
+  args[0] = &ffi_type_uchar;
+  values[0] = &uc;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_uchar, args) == FFI_OK);
+
+  for (uc = (unsigned char) '\x00';
+       uc < (unsigned char) '\xff'; uc++)
+    {
+      ffi_call(&cif, FFI_FN(return_uc), &rint, values);
+      CHECK(rint == (signed int) uc);
+    }
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c
new file mode 100755
index 0000000..12b266f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c
@@ -0,0 +1,38 @@
+/* Area:	ffi_call
+   Purpose:	Check if unsigned long as return type is handled correctly.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<kaffeetisch at gmx dot de> 20060724  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+static unsigned long return_ul(unsigned long ul1, unsigned long ul2)
+{
+  return ul1 + ul2;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_arg res;
+  unsigned long ul1, ul2;
+
+  args[0] = &ffi_type_ulong;
+  args[1] = &ffi_type_ulong;
+  values[0] = &ul1;
+  values[1] = &ul2;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+		     &ffi_type_ulong, args) == FFI_OK);
+
+  ul1 = 1073741823L;
+  ul2 = 1073741824L;
+
+  ffi_call(&cif, FFI_FN(return_ul), &res, values);
+  printf("res: %lu, %lu\n", (unsigned long)res, ul1 + ul2);
+  /* { dg-output "res: 2147483647, 2147483647" } */
+
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/stret_large.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/stret_large.c
new file mode 100755
index 0000000..23a93b9
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/stret_large.c
@@ -0,0 +1,145 @@
+/* Area:		ffi_call, closure_call
+   Purpose:		Check structure returning with different structure size.
+				Depending on the ABI. Check bigger struct which overlaps
+				the gp and fp register count on Darwin/AIX/ppc64.
+   Limitations:	none.
+   PR:			none.
+   Originator:	Blake Chaffin	6/21/2007	*/
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-*  } } */
+#include "ffitest.h"
+
+// 13 FPRs: 104 bytes
+// 14 FPRs: 112 bytes
+
+typedef struct struct_108byte {
+	double a;
+	double b;
+	double c;
+	double d;
+	double e;
+	double f;
+	double g;
+	double h;
+	double i;
+	double j;
+	double k;
+	double l;
+	double m;
+	int n;
+} struct_108byte;
+
+struct_108byte cls_struct_108byte_fn(
+	struct_108byte b0,
+	struct_108byte b1,
+	struct_108byte b2,
+	struct_108byte b3)
+{
+	struct_108byte	result;
+
+	result.a = b0.a + b1.a + b2.a + b3.a;
+	result.b = b0.b + b1.b + b2.b + b3.b;
+	result.c = b0.c + b1.c + b2.c + b3.c;
+	result.d = b0.d + b1.d + b2.d + b3.d;
+	result.e = b0.e + b1.e + b2.e + b3.e;
+	result.f = b0.f + b1.f + b2.f + b3.f;
+	result.g = b0.g + b1.g + b2.g + b3.g;
+	result.h = b0.h + b1.h + b2.h + b3.h;
+	result.i = b0.i + b1.i + b2.i + b3.i;
+	result.j = b0.j + b1.j + b2.j + b3.j;
+	result.k = b0.k + b1.k + b2.k + b3.k;
+	result.l = b0.l + b1.l + b2.l + b3.l;
+	result.m = b0.m + b1.m + b2.m + b3.m;
+	result.n = b0.n + b1.n + b2.n + b3.n;
+
+	printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c,
+		result.d, result.e, result.f, result.g, result.h, result.i,
+		result.j, result.k, result.l, result.m, result.n);
+
+	return result;
+}
+
+static void
+cls_struct_108byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
+{
+	struct_108byte	b0, b1, b2, b3;
+
+	b0 = *(struct_108byte*)(args[0]);
+	b1 = *(struct_108byte*)(args[1]);
+	b2 = *(struct_108byte*)(args[2]);
+	b3 = *(struct_108byte*)(args[3]);
+
+	*(struct_108byte*)resp = cls_struct_108byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+	ffi_cif cif;
+        void *code;
+	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+	void* args_dbl[5];
+	ffi_type* cls_struct_fields[15];
+	ffi_type cls_struct_type;
+	ffi_type* dbl_arg_types[5];
+
+	cls_struct_type.size = 0;
+	cls_struct_type.alignment = 0;
+	cls_struct_type.type = FFI_TYPE_STRUCT;
+	cls_struct_type.elements = cls_struct_fields;
+
+	struct_108byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 7 };
+	struct_108byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 4 };
+	struct_108byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 3 };
+	struct_108byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 2 };
+	struct_108byte res_dbl;
+
+	cls_struct_fields[0] = &ffi_type_double;
+	cls_struct_fields[1] = &ffi_type_double;
+	cls_struct_fields[2] = &ffi_type_double;
+	cls_struct_fields[3] = &ffi_type_double;
+	cls_struct_fields[4] = &ffi_type_double;
+	cls_struct_fields[5] = &ffi_type_double;
+	cls_struct_fields[6] = &ffi_type_double;
+	cls_struct_fields[7] = &ffi_type_double;
+	cls_struct_fields[8] = &ffi_type_double;
+	cls_struct_fields[9] = &ffi_type_double;
+	cls_struct_fields[10] = &ffi_type_double;
+	cls_struct_fields[11] = &ffi_type_double;
+	cls_struct_fields[12] = &ffi_type_double;
+	cls_struct_fields[13] = &ffi_type_sint32;
+	cls_struct_fields[14] = NULL;
+
+	dbl_arg_types[0] = &cls_struct_type;
+	dbl_arg_types[1] = &cls_struct_type;
+	dbl_arg_types[2] = &cls_struct_type;
+	dbl_arg_types[3] = &cls_struct_type;
+	dbl_arg_types[4] = NULL;
+
+	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+		dbl_arg_types) == FFI_OK);
+
+	args_dbl[0] = &e_dbl;
+	args_dbl[1] = &f_dbl;
+	args_dbl[2] = &g_dbl;
+	args_dbl[3] = &h_dbl;
+	args_dbl[4] = NULL;
+
+	ffi_call(&cif, FFI_FN(cls_struct_108byte_fn), &res_dbl, args_dbl);
+	/* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
+	printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
+		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
+		res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n);
+	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
+
+	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_108byte_gn, NULL, code) == FFI_OK);
+
+	res_dbl = ((struct_108byte(*)(struct_108byte, struct_108byte,
+		struct_108byte, struct_108byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
+	/* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
+	printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
+		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
+		res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n);
+	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
+
+	exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/stret_large2.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/stret_large2.c
new file mode 100755
index 0000000..e2599d2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/stret_large2.c
@@ -0,0 +1,148 @@
+/* Area:		ffi_call, closure_call
+   Purpose:		Check structure returning with different structure size.
+				Depending on the ABI. Check bigger struct which overlaps
+				the gp and fp register count on Darwin/AIX/ppc64.
+   Limitations:	none.
+   PR:			none.
+   Originator:	Blake Chaffin	6/21/2007	*/
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-*  } } */
+#include "ffitest.h"
+
+// 13 FPRs: 104 bytes
+// 14 FPRs: 112 bytes
+
+typedef struct struct_116byte {
+	double a;
+	double b;
+	double c;
+	double d;
+	double e;
+	double f;
+	double g;
+	double h;
+	double i;
+	double j;
+	double k;
+	double l;
+	double m;
+	double n;
+	int o;
+} struct_116byte;
+
+struct_116byte cls_struct_116byte_fn(
+	struct_116byte b0,
+	struct_116byte b1,
+	struct_116byte b2,
+	struct_116byte b3)
+{
+	struct_116byte	result;
+
+	result.a = b0.a + b1.a + b2.a + b3.a;
+	result.b = b0.b + b1.b + b2.b + b3.b;
+	result.c = b0.c + b1.c + b2.c + b3.c;
+	result.d = b0.d + b1.d + b2.d + b3.d;
+	result.e = b0.e + b1.e + b2.e + b3.e;
+	result.f = b0.f + b1.f + b2.f + b3.f;
+	result.g = b0.g + b1.g + b2.g + b3.g;
+	result.h = b0.h + b1.h + b2.h + b3.h;
+	result.i = b0.i + b1.i + b2.i + b3.i;
+	result.j = b0.j + b1.j + b2.j + b3.j;
+	result.k = b0.k + b1.k + b2.k + b3.k;
+	result.l = b0.l + b1.l + b2.l + b3.l;
+	result.m = b0.m + b1.m + b2.m + b3.m;
+	result.n = b0.n + b1.n + b2.n + b3.n;
+	result.o = b0.o + b1.o + b2.o + b3.o;
+
+	printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c,
+		result.d, result.e, result.f, result.g, result.h, result.i,
+		result.j, result.k, result.l, result.m, result.n, result.o);
+
+	return result;
+}
+
+static void
+cls_struct_116byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
+{
+	struct_116byte	b0, b1, b2, b3;
+
+	b0 = *(struct_116byte*)(args[0]);
+	b1 = *(struct_116byte*)(args[1]);
+	b2 = *(struct_116byte*)(args[2]);
+	b3 = *(struct_116byte*)(args[3]);
+
+	*(struct_116byte*)resp = cls_struct_116byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+	ffi_cif cif;
+        void *code;
+	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+	void* args_dbl[5];
+	ffi_type* cls_struct_fields[16];
+	ffi_type cls_struct_type;
+	ffi_type* dbl_arg_types[5];
+
+	cls_struct_type.size = 0;
+	cls_struct_type.alignment = 0;
+	cls_struct_type.type = FFI_TYPE_STRUCT;
+	cls_struct_type.elements = cls_struct_fields;
+
+	struct_116byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 7 };
+	struct_116byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 6.0, 4 };
+	struct_116byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 7.0, 3 };
+	struct_116byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 8.0, 2 };
+	struct_116byte res_dbl;
+
+	cls_struct_fields[0] = &ffi_type_double;
+	cls_struct_fields[1] = &ffi_type_double;
+	cls_struct_fields[2] = &ffi_type_double;
+	cls_struct_fields[3] = &ffi_type_double;
+	cls_struct_fields[4] = &ffi_type_double;
+	cls_struct_fields[5] = &ffi_type_double;
+	cls_struct_fields[6] = &ffi_type_double;
+	cls_struct_fields[7] = &ffi_type_double;
+	cls_struct_fields[8] = &ffi_type_double;
+	cls_struct_fields[9] = &ffi_type_double;
+	cls_struct_fields[10] = &ffi_type_double;
+	cls_struct_fields[11] = &ffi_type_double;
+	cls_struct_fields[12] = &ffi_type_double;
+	cls_struct_fields[13] = &ffi_type_double;
+	cls_struct_fields[14] = &ffi_type_sint32;
+	cls_struct_fields[15] = NULL;
+
+	dbl_arg_types[0] = &cls_struct_type;
+	dbl_arg_types[1] = &cls_struct_type;
+	dbl_arg_types[2] = &cls_struct_type;
+	dbl_arg_types[3] = &cls_struct_type;
+	dbl_arg_types[4] = NULL;
+
+	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+		dbl_arg_types) == FFI_OK);
+
+	args_dbl[0] = &e_dbl;
+	args_dbl[1] = &f_dbl;
+	args_dbl[2] = &g_dbl;
+	args_dbl[3] = &h_dbl;
+	args_dbl[4] = NULL;
+
+	ffi_call(&cif, FFI_FN(cls_struct_116byte_fn), &res_dbl, args_dbl);
+	/* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
+	printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
+		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
+		res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o);
+	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
+
+	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_116byte_gn, NULL, code) == FFI_OK);
+
+	res_dbl = ((struct_116byte(*)(struct_116byte, struct_116byte,
+		struct_116byte, struct_116byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
+	/* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
+	printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
+		res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
+		res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o);
+	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
+
+	exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium.c
new file mode 100755
index 0000000..1fc6a9e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium.c
@@ -0,0 +1,124 @@
+/* Area:		ffi_call, closure_call
+   Purpose:		Check structure returning with different structure size.
+				Depending on the ABI. Check bigger struct which overlaps
+				the gp and fp register count on Darwin/AIX/ppc64.
+   Limitations:	none.
+   PR:			none.
+   Originator:	Blake Chaffin	6/21/2007	*/
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-*  } } */
+#include "ffitest.h"
+
+typedef struct struct_72byte {
+	double a;
+	double b;
+	double c;
+	double d;
+	double e;
+	double f;
+	double g;
+	double h;
+	double i;
+} struct_72byte;
+
+struct_72byte cls_struct_72byte_fn(
+	struct_72byte b0,
+	struct_72byte b1,
+	struct_72byte b2,
+	struct_72byte b3)
+{
+	struct_72byte	result;
+
+	result.a = b0.a + b1.a + b2.a + b3.a;
+	result.b = b0.b + b1.b + b2.b + b3.b;
+	result.c = b0.c + b1.c + b2.c + b3.c;
+	result.d = b0.d + b1.d + b2.d + b3.d;
+	result.e = b0.e + b1.e + b2.e + b3.e;
+	result.f = b0.f + b1.f + b2.f + b3.f;
+	result.g = b0.g + b1.g + b2.g + b3.g;
+	result.h = b0.h + b1.h + b2.h + b3.h;
+	result.i = b0.i + b1.i + b2.i + b3.i;
+
+	printf("%g %g %g %g %g %g %g %g %g\n", result.a, result.b, result.c,
+		result.d, result.e, result.f, result.g, result.h, result.i);
+
+	return result;
+}
+
+static void
+cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
+{
+	struct_72byte	b0, b1, b2, b3;
+
+	b0 = *(struct_72byte*)(args[0]);
+	b1 = *(struct_72byte*)(args[1]);
+	b2 = *(struct_72byte*)(args[2]);
+	b3 = *(struct_72byte*)(args[3]);
+
+	*(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+	ffi_cif cif;
+        void *code;
+	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+	void* args_dbl[5];
+	ffi_type* cls_struct_fields[10];
+	ffi_type cls_struct_type;
+	ffi_type* dbl_arg_types[5];
+
+	cls_struct_type.size = 0;
+	cls_struct_type.alignment = 0;
+	cls_struct_type.type = FFI_TYPE_STRUCT;
+	cls_struct_type.elements = cls_struct_fields;
+
+	struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7.0 };
+	struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0 };
+	struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3.0 };
+	struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2.0 };
+	struct_72byte res_dbl;
+
+	cls_struct_fields[0] = &ffi_type_double;
+	cls_struct_fields[1] = &ffi_type_double;
+	cls_struct_fields[2] = &ffi_type_double;
+	cls_struct_fields[3] = &ffi_type_double;
+	cls_struct_fields[4] = &ffi_type_double;
+	cls_struct_fields[5] = &ffi_type_double;
+	cls_struct_fields[6] = &ffi_type_double;
+	cls_struct_fields[7] = &ffi_type_double;
+	cls_struct_fields[8] = &ffi_type_double;
+	cls_struct_fields[9] = NULL;
+
+	dbl_arg_types[0] = &cls_struct_type;
+	dbl_arg_types[1] = &cls_struct_type;
+	dbl_arg_types[2] = &cls_struct_type;
+	dbl_arg_types[3] = &cls_struct_type;
+	dbl_arg_types[4] = NULL;
+
+	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+		dbl_arg_types) == FFI_OK);
+
+	args_dbl[0] = &e_dbl;
+	args_dbl[1] = &f_dbl;
+	args_dbl[2] = &g_dbl;
+	args_dbl[3] = &h_dbl;
+	args_dbl[4] = NULL;
+
+	ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl);
+	/* { dg-output "22 15 17 25 6 13 19 18 16" } */
+	printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
+		res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
+	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
+
+	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK);
+
+	res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte,
+		struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
+	/* { dg-output "\n22 15 17 25 6 13 19 18 16" } */
+	printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
+		res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
+	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
+
+	exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c
new file mode 100755
index 0000000..cb2f2fb
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c
@@ -0,0 +1,125 @@
+/* Area:		ffi_call, closure_call
+   Purpose:		Check structure returning with different structure size.
+				Depending on the ABI. Check bigger struct which overlaps
+				the gp and fp register count on Darwin/AIX/ppc64.
+   Limitations:	none.
+   PR:			none.
+   Originator:	Blake Chaffin	6/21/2007	*/
+
+/* { dg-do run { xfail strongarm*-*-* xscale*-*-*  } } */
+/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
+#include "ffitest.h"
+
+typedef struct struct_72byte {
+	double a;
+	double b;
+	double c;
+	double d;
+	double e;
+	double f;
+	double g;
+	double h;
+	long long i;
+} struct_72byte;
+
+struct_72byte cls_struct_72byte_fn(
+	struct_72byte b0,
+	struct_72byte b1,
+	struct_72byte b2,
+	struct_72byte b3)
+{
+	struct_72byte	result;
+
+	result.a = b0.a + b1.a + b2.a + b3.a;
+	result.b = b0.b + b1.b + b2.b + b3.b;
+	result.c = b0.c + b1.c + b2.c + b3.c;
+	result.d = b0.d + b1.d + b2.d + b3.d;
+	result.e = b0.e + b1.e + b2.e + b3.e;
+	result.f = b0.f + b1.f + b2.f + b3.f;
+	result.g = b0.g + b1.g + b2.g + b3.g;
+	result.h = b0.h + b1.h + b2.h + b3.h;
+	result.i = b0.i + b1.i + b2.i + b3.i;
+
+	printf("%g %g %g %g %g %g %g %g %" PRIdLL "\n", result.a, result.b, result.c,
+		result.d, result.e, result.f, result.g, result.h, result.i);
+
+	return result;
+}
+
+static void
+cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
+{
+	struct_72byte	b0, b1, b2, b3;
+
+	b0 = *(struct_72byte*)(args[0]);
+	b1 = *(struct_72byte*)(args[1]);
+	b2 = *(struct_72byte*)(args[2]);
+	b3 = *(struct_72byte*)(args[3]);
+
+	*(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+	ffi_cif cif;
+        void *code;
+	ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+	void* args_dbl[5];
+	ffi_type* cls_struct_fields[10];
+	ffi_type cls_struct_type;
+	ffi_type* dbl_arg_types[5];
+
+	cls_struct_type.size = 0;
+	cls_struct_type.alignment = 0;
+	cls_struct_type.type = FFI_TYPE_STRUCT;
+	cls_struct_type.elements = cls_struct_fields;
+
+	struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7 };
+	struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4 };
+	struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3 };
+	struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2 };
+	struct_72byte res_dbl;
+
+	cls_struct_fields[0] = &ffi_type_double;
+	cls_struct_fields[1] = &ffi_type_double;
+	cls_struct_fields[2] = &ffi_type_double;
+	cls_struct_fields[3] = &ffi_type_double;
+	cls_struct_fields[4] = &ffi_type_double;
+	cls_struct_fields[5] = &ffi_type_double;
+	cls_struct_fields[6] = &ffi_type_double;
+	cls_struct_fields[7] = &ffi_type_double;
+	cls_struct_fields[8] = &ffi_type_sint64;
+	cls_struct_fields[9] = NULL;
+
+	dbl_arg_types[0] = &cls_struct_type;
+	dbl_arg_types[1] = &cls_struct_type;
+	dbl_arg_types[2] = &cls_struct_type;
+	dbl_arg_types[3] = &cls_struct_type;
+	dbl_arg_types[4] = NULL;
+
+	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+		dbl_arg_types) == FFI_OK);
+
+	args_dbl[0] = &e_dbl;
+	args_dbl[1] = &f_dbl;
+	args_dbl[2] = &g_dbl;
+	args_dbl[3] = &h_dbl;
+	args_dbl[4] = NULL;
+
+	ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl);
+	/* { dg-output "22 15 17 25 6 13 19 18 16" } */
+	printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c,
+		res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
+	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
+
+	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK);
+
+	res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte,
+		struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
+	/* { dg-output "\n22 15 17 25 6 13 19 18 16" } */
+	printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c,
+		res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
+	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
+
+	exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c
new file mode 100755
index 0000000..3de45de
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c
@@ -0,0 +1,44 @@
+/* Area:	ffi_call
+   Purpose:	Check strlen function call.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static size_t my_strlen(char *s)
+{
+  return (strlen(s));
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_arg rint;
+  char *s;
+
+  args[0] = &ffi_type_pointer;
+  values[0] = (void*) &s;
+  
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+		     &ffi_type_sint, args) == FFI_OK);
+  
+  s = "a";
+  ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+  CHECK(rint == 1);
+  
+  s = "1234567";
+  ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+  CHECK(rint == 7);
+  
+  s = "1234567890123456789012345";
+  ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+  CHECK(rint == 25);
+  
+  exit (0);
+}
+  
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c
new file mode 100755
index 0000000..6fbcc87
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c
@@ -0,0 +1,44 @@
+/* Area:	ffi_call
+   Purpose:	Check stdcall strlen call on X86_WIN32 systems.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
+
+#include "ffitest.h"
+
+static size_t __attribute__((stdcall)) my_stdcall_strlen(char *s)
+{
+  return (strlen(s));
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_arg rint;
+  char *s;
+  args[0] = &ffi_type_pointer;
+  values[0] = (void*) &s;
+  
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 1,
+		       &ffi_type_sint, args) == FFI_OK);
+  
+  s = "a";
+  ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
+  CHECK(rint == 1);
+  
+  s = "1234567";
+  ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
+  CHECK(rint == 7);
+  
+  s = "1234567890123456789012345";
+  ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
+  CHECK(rint == 25);
+  
+  printf("stdcall strlen tests passed\n");
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c
new file mode 100755
index 0000000..ea76c85
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c
@@ -0,0 +1,65 @@
+/* Area:	ffi_call
+   Purpose:	Check structures.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+  unsigned char uc;
+  double d;
+  unsigned int ui;
+} test_structure_1;
+
+static test_structure_1 struct1(test_structure_1 ts)
+{
+  ts.uc++;
+  ts.d--;
+  ts.ui++;
+
+  return ts;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_type ts1_type;
+  ffi_type *ts1_type_elements[4];
+  ts1_type.size = 0;
+  ts1_type.alignment = 0;
+  ts1_type.type = FFI_TYPE_STRUCT;
+  ts1_type.elements = ts1_type_elements;
+  ts1_type_elements[0] = &ffi_type_uchar;
+  ts1_type_elements[1] = &ffi_type_double;
+  ts1_type_elements[2] = &ffi_type_uint;
+  ts1_type_elements[3] = NULL;
+  
+  test_structure_1 ts1_arg;
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_1 *ts1_result = 
+    (test_structure_1 *) malloc (sizeof(test_structure_1));
+  
+  args[0] = &ts1_type;
+  values[0] = &ts1_arg;
+  
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+		     &ts1_type, args) == FFI_OK);
+  
+  ts1_arg.uc = '\x01';
+  ts1_arg.d = 3.14159;
+  ts1_arg.ui = 555;
+
+  ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
+  
+  CHECK(ts1_result->ui == 556);
+  CHECK(ts1_result->d == 3.14159 - 1);
+ 
+  free (ts1_result);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c
new file mode 100755
index 0000000..14bc9fd
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c
@@ -0,0 +1,67 @@
+/* Area:	ffi_call
+   Purpose:	Check structures.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+  double d1;
+  double d2;
+} test_structure_2;
+
+static test_structure_2 struct2(test_structure_2 ts)
+{
+  ts.d1--;
+  ts.d2--;
+
+  return ts;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  test_structure_2 ts2_arg;
+  ffi_type ts2_type;
+  ffi_type *ts2_type_elements[3];
+  ts2_type.size = 0;
+  ts2_type.alignment = 0;
+  ts2_type.type = FFI_TYPE_STRUCT;
+  ts2_type.elements = ts2_type_elements;
+  ts2_type_elements[0] = &ffi_type_double;
+  ts2_type_elements[1] = &ffi_type_double;
+  ts2_type_elements[2] = NULL;
+
+  
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_2 *ts2_result = 
+    (test_structure_2 *) malloc (sizeof(test_structure_2));
+  
+  args[0] = &ts2_type;
+  values[0] = &ts2_arg;
+  
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts2_type, args) == FFI_OK);
+  
+  ts2_arg.d1 = 5.55;
+  ts2_arg.d2 = 6.66;
+  
+  printf ("%g\n", ts2_arg.d1);
+  printf ("%g\n", ts2_arg.d2);
+  
+  ffi_call(&cif, FFI_FN(struct2), ts2_result, values);
+  
+  printf ("%g\n", ts2_result->d1);
+  printf ("%g\n", ts2_result->d2);
+  
+  CHECK(ts2_result->d1 == 5.55 - 1);
+  CHECK(ts2_result->d2 == 6.66 - 1);
+  
+  free (ts2_result);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c
new file mode 100755
index 0000000..e0bb09b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c
@@ -0,0 +1,59 @@
+/* Area:	ffi_call
+   Purpose:	Check structures.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+  int si;
+} test_structure_3;
+
+static test_structure_3 struct3(test_structure_3 ts)
+{
+  ts.si = -(ts.si*2);
+
+  return ts;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  int compare_value;
+  ffi_type ts3_type;
+  ffi_type *ts3_type_elements[2];
+  ts3_type.size = 0;
+  ts3_type.alignment = 0;
+  ts3_type.type = FFI_TYPE_STRUCT;
+  ts3_type.elements = ts3_type_elements;
+  ts3_type_elements[0] = &ffi_type_sint;
+  ts3_type_elements[1] = NULL;
+
+  test_structure_3 ts3_arg;
+  test_structure_3 *ts3_result = 
+    (test_structure_3 *) malloc (sizeof(test_structure_3));
+  
+  args[0] = &ts3_type;
+  values[0] = &ts3_arg;
+  
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+		     &ts3_type, args) == FFI_OK);
+  
+  ts3_arg.si = -123;
+  compare_value = ts3_arg.si;
+  
+  ffi_call(&cif, FFI_FN(struct3), ts3_result, values);
+  
+  printf ("%d %d\n", ts3_result->si, -(compare_value*2));
+  
+  CHECK(ts3_result->si == -(compare_value*2));
+ 
+  free (ts3_result);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c
new file mode 100755
index 0000000..0ad0a83
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c
@@ -0,0 +1,63 @@
+/* Area:	ffi_call
+   Purpose:	Check structures.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+  unsigned ui1;
+  unsigned ui2;
+  unsigned ui3;
+} test_structure_4;
+
+static test_structure_4 struct4(test_structure_4 ts)
+{
+  ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3;
+
+  return ts;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_type ts4_type;
+  ffi_type *ts4_type_elements[4];  
+  ts4_type.size = 0;
+  ts4_type.alignment = 0;
+  ts4_type.type = FFI_TYPE_STRUCT;
+  test_structure_4 ts4_arg;
+  ts4_type.elements = ts4_type_elements;
+  ts4_type_elements[0] = &ffi_type_uint;
+  ts4_type_elements[1] = &ffi_type_uint;
+  ts4_type_elements[2] = &ffi_type_uint;
+  ts4_type_elements[3] = NULL;
+
+  
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_4 *ts4_result = 
+    (test_structure_4 *) malloc (sizeof(test_structure_4));
+  
+  args[0] = &ts4_type;
+  values[0] = &ts4_arg;
+  
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK);
+  
+  ts4_arg.ui1 = 2;
+  ts4_arg.ui2 = 3;
+  ts4_arg.ui3 = 4;
+  
+  ffi_call (&cif, FFI_FN(struct4), ts4_result, values);
+  
+  CHECK(ts4_result->ui3 == 2U * 3U * 4U);
+ 
+  
+  free (ts4_result);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c
new file mode 100755
index 0000000..c03cc97
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c
@@ -0,0 +1,65 @@
+/* Area:	ffi_call
+   Purpose:	Check structures.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+typedef struct
+{
+  char c1;
+  char c2;
+} test_structure_5;
+
+static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2)
+{
+  ts1.c1 += ts2.c1;
+  ts1.c2 -= ts2.c2;
+  
+  return ts1;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_type ts5_type;
+  ffi_type *ts5_type_elements[3];
+  ts5_type.size = 0;
+  ts5_type.alignment = 0;
+  ts5_type.type = FFI_TYPE_STRUCT;
+  ts5_type.elements = ts5_type_elements;
+  ts5_type_elements[0] = &ffi_type_schar;
+  ts5_type_elements[1] = &ffi_type_schar;
+  ts5_type_elements[2] = NULL;
+
+  test_structure_5 ts5_arg1, ts5_arg2;
+  
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_5 *ts5_result = 
+    (test_structure_5 *) malloc (sizeof(test_structure_5));
+  
+  args[0] = &ts5_type;
+  args[1] = &ts5_type;
+  values[0] = &ts5_arg1;
+  values[1] = &ts5_arg2;
+  
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ts5_type, args) == FFI_OK);
+  
+  ts5_arg1.c1 = 2;
+  ts5_arg1.c2 = 6;
+  ts5_arg2.c1 = 5;
+  ts5_arg2.c2 = 3;
+  
+  ffi_call (&cif, FFI_FN(struct5), ts5_result, values);
+  
+  CHECK(ts5_result->c1 == 7); 
+  CHECK(ts5_result->c2 == 3);
+  
+  
+  free (ts5_result);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c
new file mode 100755
index 0000000..83db9af
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c
@@ -0,0 +1,64 @@
+/* Area:	ffi_call
+   Purpose:	Check structures.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+typedef struct
+{
+  float f;
+  double d;
+} test_structure_6;
+
+static test_structure_6 struct6 (test_structure_6 ts)
+{
+  ts.f += 1;
+  ts.d += 1;
+  
+  return ts;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_type ts6_type;
+  ffi_type *ts6_type_elements[3];
+  ts6_type.size = 0;
+  ts6_type.alignment = 0;
+  ts6_type.type = FFI_TYPE_STRUCT;
+  ts6_type.elements = ts6_type_elements;
+  ts6_type_elements[0] = &ffi_type_float;
+  ts6_type_elements[1] = &ffi_type_double;
+  ts6_type_elements[2] = NULL;
+
+
+  test_structure_6 ts6_arg;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_6 *ts6_result = 
+    (test_structure_6 *) malloc (sizeof(test_structure_6));
+  
+  args[0] = &ts6_type;
+  values[0] = &ts6_arg;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts6_type, args) == FFI_OK);
+  
+  ts6_arg.f = 5.55f;
+  ts6_arg.d = 6.66;
+  
+  printf ("%g\n", ts6_arg.f);
+  printf ("%g\n", ts6_arg.d);
+
+  ffi_call(&cif, FFI_FN(struct6), ts6_result, values);
+    
+  CHECK(ts6_result->f == 5.55f + 1);
+  CHECK(ts6_result->d == 6.66 + 1);
+    
+  free (ts6_result);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c
new file mode 100755
index 0000000..58aac4c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c
@@ -0,0 +1,74 @@
+/* Area:	ffi_call
+   Purpose:	Check structures.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+typedef struct
+{
+  float f1;
+  float f2;
+  double d;
+} test_structure_7;
+
+static test_structure_7 struct7 (test_structure_7 ts)
+{
+  ts.f1 += 1;
+  ts.f2 += 1;
+  ts.d += 1;
+
+  return ts;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_type ts7_type;
+  ffi_type *ts7_type_elements[4];
+  ts7_type.size = 0;
+  ts7_type.alignment = 0;
+  ts7_type.type = FFI_TYPE_STRUCT;
+  ts7_type.elements = ts7_type_elements;
+  ts7_type_elements[0] = &ffi_type_float;
+  ts7_type_elements[1] = &ffi_type_float;
+  ts7_type_elements[2] = &ffi_type_double;
+  ts7_type_elements[3] = NULL;
+
+
+  test_structure_7 ts7_arg;
+  
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_7 *ts7_result = 
+    (test_structure_7 *) malloc (sizeof(test_structure_7));
+  
+  args[0] = &ts7_type;
+  values[0] = &ts7_arg;
+  
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts7_type, args) == FFI_OK);
+  
+  ts7_arg.f1 = 5.55f;
+  ts7_arg.f2 = 55.5f;
+  ts7_arg.d = 6.66;
+
+  printf ("%g\n", ts7_arg.f1);
+  printf ("%g\n", ts7_arg.f2);
+  printf ("%g\n", ts7_arg.d);
+  
+  ffi_call(&cif, FFI_FN(struct7), ts7_result, values);
+
+  printf ("%g\n", ts7_result->f1);
+  printf ("%g\n", ts7_result->f2);
+  printf ("%g\n", ts7_result->d);
+  
+  CHECK(ts7_result->f1 == 5.55f + 1);
+  CHECK(ts7_result->f2 == 55.5f + 1);
+  CHECK(ts7_result->d == 6.66 + 1);
+  
+  free (ts7_result);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c
new file mode 100755
index 0000000..c773ac7
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c
@@ -0,0 +1,80 @@
+/* Area:	ffi_call
+   Purpose:	Check structures.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+typedef struct
+{
+  float f1;
+  float f2;
+  float f3;
+  float f4;
+} test_structure_8;
+
+static test_structure_8 struct8 (test_structure_8 ts)
+{
+  ts.f1 += 1;
+  ts.f2 += 1;
+  ts.f3 += 1;
+  ts.f4 += 1;
+
+  return ts;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_type ts8_type;
+  ffi_type *ts8_type_elements[5];
+  ts8_type.size = 0;
+  ts8_type.alignment = 0;
+  ts8_type.type = FFI_TYPE_STRUCT;
+  ts8_type.elements = ts8_type_elements;
+  ts8_type_elements[0] = &ffi_type_float;
+  ts8_type_elements[1] = &ffi_type_float;
+  ts8_type_elements[2] = &ffi_type_float;
+  ts8_type_elements[3] = &ffi_type_float;
+  ts8_type_elements[4] = NULL;
+
+  test_structure_8 ts8_arg;
+  
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_8 *ts8_result = 
+    (test_structure_8 *) malloc (sizeof(test_structure_8));
+  
+  args[0] = &ts8_type;
+  values[0] = &ts8_arg;
+  
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts8_type, args) == FFI_OK);
+  
+  ts8_arg.f1 = 5.55f;
+  ts8_arg.f2 = 55.5f;
+  ts8_arg.f3 = -5.55f;
+  ts8_arg.f4 = -55.5f;
+
+  printf ("%g\n", ts8_arg.f1);
+  printf ("%g\n", ts8_arg.f2);
+  printf ("%g\n", ts8_arg.f3);
+  printf ("%g\n", ts8_arg.f4);
+  
+  ffi_call(&cif, FFI_FN(struct8), ts8_result, values);
+
+  printf ("%g\n", ts8_result->f1);
+  printf ("%g\n", ts8_result->f2);
+  printf ("%g\n", ts8_result->f3);
+  printf ("%g\n", ts8_result->f4);
+  
+  CHECK(ts8_result->f1 == 5.55f + 1);
+  CHECK(ts8_result->f2 == 55.5f + 1);
+  CHECK(ts8_result->f3 == -5.55f + 1);
+  CHECK(ts8_result->f4 == -55.5f + 1);
+  
+  free (ts8_result);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c
new file mode 100755
index 0000000..f30091f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c
@@ -0,0 +1,67 @@
+/* Area:	ffi_call
+   Purpose:	Check structures.
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct
+{
+  float f;
+  int i;
+} test_structure_9;
+
+static test_structure_9 struct9 (test_structure_9 ts)
+{
+  ts.f += 1;
+  ts.i += 1;
+
+  return ts;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_type ts9_type;
+  ffi_type *ts9_type_elements[3];
+  ts9_type.size = 0;
+  ts9_type.alignment = 0;
+  ts9_type.type = FFI_TYPE_STRUCT;
+  ts9_type.elements = ts9_type_elements;
+  ts9_type_elements[0] = &ffi_type_float;
+  ts9_type_elements[1] = &ffi_type_sint;
+  ts9_type_elements[2] = NULL;
+
+  test_structure_9 ts9_arg;
+  
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_9 *ts9_result = 
+    (test_structure_9 *) malloc (sizeof(test_structure_9));
+  
+  args[0] = &ts9_type;
+  values[0] = &ts9_arg;
+  
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK);
+  
+  ts9_arg.f = 5.55f;
+  ts9_arg.i = 5;
+  
+  printf ("%g\n", ts9_arg.f);
+  printf ("%d\n", ts9_arg.i);
+  
+  ffi_call(&cif, FFI_FN(struct9), ts9_result, values);
+
+  printf ("%g\n", ts9_result->f);
+  printf ("%d\n", ts9_result->i);
+  
+  CHECK(ts9_result->f == 5.55f + 1);
+  CHECK(ts9_result->i == 5 + 1);
+
+  free (ts9_result);
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/testclosure.c b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/testclosure.c
new file mode 100755
index 0000000..161cc89
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.call/testclosure.c
@@ -0,0 +1,70 @@
+/* Area:	closure_call
+   Purpose:	Check return value float.
+   Limitations:	none.
+   PR:		41908.
+   Originator:	<rfm at gnu.org> 20091102	 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct cls_struct_combined {
+  float a;
+  float b;
+  float c;
+  float d;
+} cls_struct_combined;
+
+void cls_struct_combined_fn(struct cls_struct_combined arg)
+{
+  printf("%g %g %g %g\n",
+	 arg.a, arg.b,
+	 arg.c, arg.d);
+  fflush(stdout);
+}
+
+static void
+cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
+        void** args, void* userdata __UNUSED__)
+{
+  struct cls_struct_combined a0;
+
+  a0 = *(struct cls_struct_combined*)(args[0]);
+
+  cls_struct_combined_fn(a0);
+}
+
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type* cls_struct_fields0[5];
+  ffi_type cls_struct_type0;
+  ffi_type* dbl_arg_types[5];
+
+  cls_struct_type0.size = 0;
+  cls_struct_type0.alignment = 0;
+  cls_struct_type0.type = FFI_TYPE_STRUCT;
+  cls_struct_type0.elements = cls_struct_fields0;
+
+  struct cls_struct_combined g_dbl = {4.0, 5.0, 1.0, 8.0};
+
+  cls_struct_fields0[0] = &ffi_type_float;
+  cls_struct_fields0[1] = &ffi_type_float;
+  cls_struct_fields0[2] = &ffi_type_float;
+  cls_struct_fields0[3] = &ffi_type_float;
+  cls_struct_fields0[4] = NULL;
+
+  dbl_arg_types[0] = &cls_struct_type0;
+  dbl_arg_types[1] = NULL;
+
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void,
+		     dbl_arg_types) == FFI_OK);
+
+  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
+
+  ((void(*)(cls_struct_combined)) (code))(g_dbl);
+  /* { dg-output "4 5 1 8" } */
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h
new file mode 100755
index 0000000..83f5442
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h
@@ -0,0 +1,96 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <ffi.h>
+#include "fficonfig.h"
+
+#define MAX_ARGS 256
+
+
+/* Define __UNUSED__ that also other compilers than gcc can run the tests.  */
+#undef __UNUSED__
+#if defined(__GNUC__)
+#define __UNUSED__ __attribute__((__unused__))
+#else
+#define __UNUSED__
+#endif
+
+#define CHECK(x) (!(x) ? abort() : (void)0)
+
+/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
+   file open.  */
+#ifdef HAVE_MMAP_ANON
+# undef HAVE_MMAP_DEV_ZERO
+
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+#  define MAP_FAILED -1
+# endif
+# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
+#  define MAP_ANONYMOUS MAP_ANON
+# endif
+# define USING_MMAP
+
+#endif
+
+#ifdef HAVE_MMAP_DEV_ZERO
+
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+#  define MAP_FAILED -1
+# endif
+# define USING_MMAP
+
+#endif
+
+
+/* MinGW kludge.  */
+#ifdef _WIN64
+#define PRIdLL "I64d"
+#define PRIuLL "I64u"
+#else
+#define PRIdLL "lld"
+#define PRIuLL "llu"
+#endif
+
+#ifdef USING_MMAP
+static inline void *
+allocate_mmap (size_t size)
+{
+  void *page;
+#if defined (HAVE_MMAP_DEV_ZERO)
+  static int dev_zero_fd = -1;
+#endif
+
+#ifdef HAVE_MMAP_DEV_ZERO
+  if (dev_zero_fd == -1)
+    {
+      dev_zero_fd = open ("/dev/zero", O_RDONLY);
+      if (dev_zero_fd == -1)
+	{
+	  perror ("open /dev/zero: %m");
+	  exit (1);
+	}
+    }
+#endif
+
+
+#ifdef HAVE_MMAP_ANON
+  page = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+	       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+#endif
+#ifdef HAVE_MMAP_DEV_ZERO
+  page = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+	       MAP_PRIVATE, dev_zero_fd, 0);
+#endif
+
+  if (page == (char *) MAP_FAILED)
+    {
+      perror ("virtual memory exhausted");
+      exit (1);
+    }
+
+  return page;
+}
+
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.special/special.exp b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.special/special.exp
new file mode 100755
index 0000000..74671b1
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.special/special.exp
@@ -0,0 +1,35 @@
+# Copyright (C) 2003, 2006, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+dg-init
+libffi-init
+
+global srcdir subdir
+
+global cxx_options
+
+set cxx_options " -shared-libgcc -lstdc++"
+
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-O0 -W -Wall"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-O2"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-O3"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-Os"
+
+dg-finish
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest.cc b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest.cc
new file mode 100755
index 0000000..d7ffd4a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest.cc
@@ -0,0 +1,124 @@
+/* Area:	ffi_closure, unwind info
+   Purpose:	Check if the unwind information is passed correctly.
+   Limitations:	none.
+   PR:		none.
+   Originator:	Jeff Sturm <jsturm at one-point.com>  */
+
+/* { dg-do run } */
+#include "ffitestcxx.h"
+
+#if defined HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#if defined HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+void
+closure_test_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
+		void** args __UNUSED__, void* userdata __UNUSED__)
+{
+  throw 9;
+}
+
+typedef void (*closure_test_type)();
+
+void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp,
+		      void** args, void* userdata __UNUSED__)
+ {
+    *(ffi_arg*)resp =
+      (int)*(float *)args[0] +(int)(*(float *)args[1]) +
+      (int)(*(float *)args[2]) + (int)*(float *)args[3] +
+      (int)(*(signed short *)args[4]) + (int)(*(float *)args[5]) +
+      (int)*(float *)args[6] + (int)(*(int *)args[7]) +
+      (int)(*(double*)args[8]) + (int)*(int *)args[9] +
+      (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
+      (int)*(int *)args[12] + (int)(*(int *)args[13]) +
+      (int)(*(int *)args[14]) + *(int *)args[15] + (int)(intptr_t)userdata;
+
+    printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+	   (int)*(float *)args[0], (int)(*(float *)args[1]),
+	   (int)(*(float *)args[2]), (int)*(float *)args[3],
+	   (int)(*(signed short *)args[4]), (int)(*(float *)args[5]),
+	   (int)*(float *)args[6], (int)(*(int *)args[7]),
+	   (int)(*(double *)args[8]), (int)*(int *)args[9],
+	   (int)(*(int *)args[10]), (int)(*(float *)args[11]),
+	   (int)*(int *)args[12], (int)(*(int *)args[13]),
+	   (int)(*(int *)args[14]), *(int *)args[15],
+	   (int)(intptr_t)userdata, (int)*(ffi_arg*)resp);
+
+    throw (int)*(ffi_arg*)resp;
+}
+
+typedef int (*closure_test_type1)(float, float, float, float, signed short,
+				  float, float, int, double, int, int, float,
+				  int, int, int, int);
+
+int main (void)
+{
+  ffi_cif cif;
+  void *code;
+  ffi_closure *pcl = (ffi_closure *)ffi_closure_alloc(sizeof(ffi_closure), &code);
+  ffi_type * cl_arg_types[17];
+
+  {
+    cl_arg_types[1] = NULL;
+
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0,
+		       &ffi_type_void, cl_arg_types) == FFI_OK);
+    CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn, NULL, code) == FFI_OK);
+
+    try
+      {
+	(*((closure_test_type)(code)))();
+      } catch (int exception_code)
+      {
+	CHECK(exception_code == 9);
+      }
+
+    printf("part one OK\n");
+    /* { dg-output "part one OK" } */
+    }
+
+    {
+
+      cl_arg_types[0] = &ffi_type_float;
+      cl_arg_types[1] = &ffi_type_float;
+      cl_arg_types[2] = &ffi_type_float;
+      cl_arg_types[3] = &ffi_type_float;
+      cl_arg_types[4] = &ffi_type_sshort;
+      cl_arg_types[5] = &ffi_type_float;
+      cl_arg_types[6] = &ffi_type_float;
+      cl_arg_types[7] = &ffi_type_uint;
+      cl_arg_types[8] = &ffi_type_double;
+      cl_arg_types[9] = &ffi_type_uint;
+      cl_arg_types[10] = &ffi_type_uint;
+      cl_arg_types[11] = &ffi_type_float;
+      cl_arg_types[12] = &ffi_type_uint;
+      cl_arg_types[13] = &ffi_type_uint;
+      cl_arg_types[14] = &ffi_type_uint;
+      cl_arg_types[15] = &ffi_type_uint;
+      cl_arg_types[16] = NULL;
+
+      /* Initialize the cif */
+      CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+			 &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+      CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn1,
+                                 (void *) 3 /* userdata */, code)  == FFI_OK);
+      try
+	{
+	  (*((closure_test_type1)code))
+	    (1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13,
+	     19, 21, 1);
+	  /* { dg-output "\n1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
+	} catch (int exception_code)
+	{
+	  CHECK(exception_code == 255);
+	}
+      printf("part two OK\n");
+      /* { dg-output "\npart two OK" } */
+    }
+    exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc
new file mode 100755
index 0000000..29739cd
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc
@@ -0,0 +1,53 @@
+/* Area:	ffi_call, unwind info
+   Purpose:	Check if the unwind information is passed correctly.
+   Limitations:	none.
+   PR:		none.
+   Originator:	Andreas Tobler <andreast at gcc.gnu.org> 20061213  */
+
+/* { dg-do run } */
+#include "ffitestcxx.h"
+
+static int checking(int a __UNUSED__, short b __UNUSED__,
+		    signed char c __UNUSED__)
+{
+  throw 9;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_arg rint;
+
+  signed int si;
+  signed short ss;
+  signed char sc;
+
+  args[0] = &ffi_type_sint;
+  values[0] = &si;
+  args[1] = &ffi_type_sshort;
+  values[1] = &ss;
+  args[2] = &ffi_type_schar;
+  values[2] = ≻
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+		     &ffi_type_sint, args) == FFI_OK);
+
+  si = -6;
+  ss = -12;
+  sc = -1;
+  {
+    try
+      {
+	ffi_call(&cif, FFI_FN(checking), &rint, values);
+      } catch (int exception_code)
+      {
+	CHECK(exception_code == 9);
+      }
+    printf("part one OK\n");
+    /* { dg-output "part one OK" } */
+  }
+  exit(0);
+}
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/texinfo.tex b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/texinfo.tex
new file mode 100755
index 0000000..ff2c406
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/libffi/texinfo.tex
@@ -0,0 +1,7210 @@
+% texinfo.tex -- TeX macros to handle Texinfo files.
+%
+% Load plain if necessary, i.e., if running under initex.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+%
+\def\texinfoversion{2005-07-05.19}
+%
+% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software
+% Foundation, Inc.
+%
+% This texinfo.tex file is free software; you can redistribute it and/or
+% modify it under the terms of the GNU General Public License as
+% published by the Free Software Foundation; either version 2, or (at
+% your option) any later version.
+%
+% This texinfo.tex file is distributed in the hope that it will be
+% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+% General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this texinfo.tex file; see the file COPYING.  If not, write
+% to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+% Boston, MA 02110-1301, USA.
+%
+% As a special exception, when this file is read by TeX when processing
+% a Texinfo source document, you may use the result without
+% restriction.  (This has been our intent since Texinfo was invented.)
+%
+% Please try the latest version of texinfo.tex before submitting bug
+% reports; you can get the latest version from:
+%   http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
+%   ftp://tug.org/tex/texinfo.tex
+%     (and all CTAN mirrors, see http://www.ctan.org).
+% The texinfo.tex in any given distribution could well be out
+% of date, so if that's what you're using, please check.
+%
+% Send bug reports to bug-texinfo at gnu.org.  Please include including a
+% complete document in each bug report with which we can reproduce the
+% problem.  Patches are, of course, greatly appreciated.
+%
+% To process a Texinfo manual with TeX, it's most reliable to use the
+% texi2dvi shell script that comes with the distribution.  For a simple
+% manual foo.texi, however, you can get away with this:
+%   tex foo.texi
+%   texindex foo.??
+%   tex foo.texi
+%   tex foo.texi
+%   dvips foo.dvi -o  # or whatever; this makes foo.ps.
+% The extra TeX runs get the cross-reference information correct.
+% Sometimes one run after texindex suffices, and sometimes you need more
+% than two; texi2dvi does it as many times as necessary.
+%
+% It is possible to adapt texinfo.tex for other languages, to some
+% extent.  You can get the existing language-specific files from the
+% full Texinfo distribution.
+%
+% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
+
+
+\message{Loading texinfo [version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}%
+  \catcode`+=\active \catcode`\_=\active}
+
+\message{Basics,}
+\chardef\other=12
+
+% We never want plain's \outer definition of \+ in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+
+% Save some plain tex macros whose names we will redefine.
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv=\equiv
+\let\ptexexclam=\!
+\let\ptexfootnote=\footnote
+\let\ptexgtr=>
+\let\ptexhat=^
+\let\ptexi=\i
+\let\ptexindent=\indent
+\let\ptexinsert=\insert
+\let\ptexlbrace=\{
+\let\ptexless=<
+\let\ptexnewwrite\newwrite
+\let\ptexnoindent=\noindent
+\let\ptexplus=+
+\let\ptexrbrace=\}
+\let\ptexslash=\/
+\let\ptexstar=\*
+\let\ptext=\t
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+  \let\linenumber = \empty % Pre-3.0.
+\else
+  \def\linenumber{l.\the\inputlineno:\space}
+\fi
+
+% Set up fixed words for English if not already set.
+\ifx\putwordAppendix\undefined  \gdef\putwordAppendix{Appendix}\fi
+\ifx\putwordChapter\undefined   \gdef\putwordChapter{Chapter}\fi
+\ifx\putwordfile\undefined      \gdef\putwordfile{file}\fi
+\ifx\putwordin\undefined        \gdef\putwordin{in}\fi
+\ifx\putwordIndexIsEmpty\undefined     \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordInfo\undefined      \gdef\putwordInfo{Info}\fi
+\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
+\ifx\putwordMethodon\undefined  \gdef\putwordMethodon{Method on}\fi
+\ifx\putwordNoTitle\undefined   \gdef\putwordNoTitle{No Title}\fi
+\ifx\putwordof\undefined        \gdef\putwordof{of}\fi
+\ifx\putwordon\undefined        \gdef\putwordon{on}\fi
+\ifx\putwordpage\undefined      \gdef\putwordpage{page}\fi
+\ifx\putwordsection\undefined   \gdef\putwordsection{section}\fi
+\ifx\putwordSection\undefined   \gdef\putwordSection{Section}\fi
+\ifx\putwordsee\undefined       \gdef\putwordsee{see}\fi
+\ifx\putwordSee\undefined       \gdef\putwordSee{See}\fi
+\ifx\putwordShortTOC\undefined  \gdef\putwordShortTOC{Short Contents}\fi
+\ifx\putwordTOC\undefined       \gdef\putwordTOC{Table of Contents}\fi
+%
+\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
+\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
+\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
+\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
+\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
+\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
+\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
+\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
+\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
+\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
+\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
+\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
+%
+\ifx\putwordDefmac\undefined    \gdef\putwordDefmac{Macro}\fi
+\ifx\putwordDefspec\undefined   \gdef\putwordDefspec{Special Form}\fi
+\ifx\putwordDefvar\undefined    \gdef\putwordDefvar{Variable}\fi
+\ifx\putwordDefopt\undefined    \gdef\putwordDefopt{User Option}\fi
+\ifx\putwordDeffunc\undefined   \gdef\putwordDeffunc{Function}\fi
+
+% In some macros, we cannot use the `\? notation---the left quote is
+% in some cases the escape char.
+\chardef\backChar  = `\\
+\chardef\colonChar = `\:
+\chardef\commaChar = `\,
+\chardef\dotChar   = `\.
+\chardef\exclamChar= `\!
+\chardef\plusChar  = `\+
+\chardef\questChar = `\?
+\chardef\semiChar  = `\;
+\chardef\underChar = `\_
+
+\chardef\spaceChar = `\ %
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode\spaceChar=\spacecat}
+
+{% for help with debugging.
+ % example usage: \expandafter\show\activebackslash
+ \catcode`\! = 0 \catcode`\\ = \active
+ !global!def!activebackslash{\}
+}
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+% The following is used inside several \edef's.
+\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
+
+% Hyphenation fixes.
+\hyphenation{
+  Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script
+  ap-pen-dix bit-map bit-maps
+  data-base data-bases eshell fall-ing half-way long-est man-u-script
+  man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
+  par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
+  spell-ing spell-ings
+  stand-alone strong-est time-stamp time-stamps which-ever white-space
+  wide-spread wrap-around
+}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen\bindingoffset
+\newdimen\normaloffset
+\newdimen\pagewidth \newdimen\pageheight
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt}
+
+% @| inserts a changebar to the left of the current line.  It should
+% surround any changed text.  This approach does *not* work if the
+% change spans more than two lines of output.  To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change).
+%
+\def\|{%
+  % \vadjust can only be used in horizontal mode.
+  \leavevmode
+  %
+  % Append this vertical mode material after the current line in the output.
+  \vadjust{%
+    % We want to insert a rule with the height and depth of the current
+    % leading; that is exactly what \strutbox is supposed to record.
+    \vskip-\baselineskip
+    %
+    % \vadjust-items are inserted at the left edge of the type.  So
+    % the \llap here moves out into the left-hand margin.
+    \llap{%
+      %
+      % For a thicker or thinner bar, change the `1pt'.
+      \vrule height\baselineskip width1pt
+      %
+      % This is the space between the bar and the text.
+      \hskip 12pt
+    }%
+  }%
+}
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal.  We don't just call \tracingall here,
+% since that produces some useless output on the terminal.  We also make
+% some effort to order the tracing commands to reduce output in the log
+% file; cf. trace.sty in LaTeX.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{%
+  \tracingstats2
+  \tracingpages1
+  \tracinglostchars2  % 2 gives us more in etex
+  \tracingparagraphs1
+  \tracingoutput1
+  \tracingmacros2
+  \tracingrestores1
+  \showboxbreadth\maxdimen \showboxdepth\maxdimen
+  \ifx\eTeXversion\undefined\else % etex gives us more logging
+    \tracingscantokens1
+    \tracingifs1
+    \tracinggroups1
+    \tracingnesting2
+    \tracingassigns1
+  \fi
+  \tracingcommands3  % 3 gives us more in etex
+  \errorcontextlines16
+}%
+
+% add check for \lastpenalty to plain's definitions.  If the last thing
+% we did was a \nobreak, we don't want to insert more space.
+%
+\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
+  \removelastskip\penalty-50\smallskip\fi\fi}
+\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
+  \removelastskip\penalty-100\medskip\fi\fi}
+\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
+  \removelastskip\penalty-200\bigskip\fi\fi}
+
+% For @cropmarks command.
+% Do @cropmarks to get crop marks.
+%
+\newif\ifcropmarks
+\let\cropmarks = \cropmarkstrue
+%
+% Dimensions to add cropmarks at corners.
+% Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
+\newdimen\cornerlong  \cornerlong=1pc
+\newdimen\cornerthick \cornerthick=.3pt
+\newdimen\topandbottommargin \topandbottommargin=.75in
+
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox
+\newbox\footlinebox
+
+% \onepageout takes a vbox as an argument.  Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+  \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+  %
+  \ifodd\pageno  \advance\hoffset by \bindingoffset
+  \else \advance\hoffset by -\bindingoffset\fi
+  %
+  % Do this outside of the \shipout so @code etc. will be expanded in
+  % the headline as they should be, not taken literally (outputting ''code).
+  \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+  \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+  %
+  {%
+    % Have to do this stuff outside the \shipout because we want it to
+    % take effect in \write's, yet the group defined by the \vbox ends
+    % before the \shipout runs.
+    %
+    \indexdummies         % don't expand commands in the output.
+    \shipout\vbox{%
+      % Do this early so pdf references go to the beginning of the page.
+      \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
+      %
+      \ifcropmarks \vbox to \outervsize\bgroup
+        \hsize = \outerhsize
+        \vskip-\topandbottommargin
+        \vtop to0pt{%
+          \line{\ewtop\hfil\ewtop}%
+          \nointerlineskip
+          \line{%
+            \vbox{\moveleft\cornerthick\nstop}%
+            \hfill
+            \vbox{\moveright\cornerthick\nstop}%
+          }%
+          \vss}%
+        \vskip\topandbottommargin
+        \line\bgroup
+          \hfil % center the page within the outer (page) hsize.
+          \ifodd\pageno\hskip\bindingoffset\fi
+          \vbox\bgroup
+      \fi
+      %
+      \unvbox\headlinebox
+      \pagebody{#1}%
+      \ifdim\ht\footlinebox > 0pt
+        % Only leave this space if the footline is nonempty.
+        % (We lessened \vsize for it in \oddfootingxxx.)
+        % The \baselineskip=24pt in plain's \makefootline has no effect.
+        \vskip 2\baselineskip
+        \unvbox\footlinebox
+      \fi
+      %
+      \ifcropmarks
+          \egroup % end of \vbox\bgroup
+        \hfil\egroup % end of (centering) \line\bgroup
+        \vskip\topandbottommargin plus1fill minus1fill
+        \boxmaxdepth = \cornerthick
+        \vbox to0pt{\vss
+          \line{%
+            \vbox{\moveleft\cornerthick\nsbot}%
+            \hfill
+            \vbox{\moveright\cornerthick\nsbot}%
+          }%
+          \nointerlineskip
+          \line{\ewbot\hfil\ewbot}%
+        }%
+      \egroup % \vbox from first cropmarks clause
+      \fi
+    }% end of \shipout\vbox
+  }% end of group with \indexdummies
+  \advancepageno
+  \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha at viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+  \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1 \unvbox#1
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr at ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+% Here are the rules for the cropmarks.  Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+  {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+  {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1.  The argument is the rest of
+% the input line (except we remove a trailing comment).  #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg{\parseargusing{}}
+\def\parseargusing#1#2{%
+  \def\next{#2}%
+  \begingroup
+    \obeylines
+    \spaceisspace
+    #1%
+    \parseargline\empty% Insert the \empty token, see \finishparsearg below.
+}
+
+{\obeylines %
+  \gdef\parseargline#1^^M{%
+    \endgroup % End of the group started in \parsearg.
+    \argremovecomment #1\comment\ArgTerm%
+  }%
+}
+
+% First remove any @comment, then any @c comment.
+\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
+\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
+
+% Each occurence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% \argremovec might leave us with trailing space, e.g.,
+%    @end itemize  @c foo
+% This space token undergoes the same procedure and is eventually removed
+% by \finishparsearg.
+%
+\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
+\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
+\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
+  \def\temp{#3}%
+  \ifx\temp\empty
+    % We cannot use \next here, as it holds the macro to run;
+    % thus we reuse \temp.
+    \let\temp\finishparsearg
+  \else
+    \let\temp\argcheckspaces
+  \fi
+  % Put the space token in:
+  \temp#1 #3\ArgTerm
+}
+
+% If a _delimited_ argument is enclosed in braces, they get stripped; so
+% to get _exactly_ the rest of the line, we had to prevent such situation.
+% We prepended an \empty token at the very beginning and we expand it now,
+% just before passing the control to \next.
+% (Similarily, we have to think about #3 of \argcheckspacesY above: it is
+% either the null string, or it ends with \^^M---thus there is no danger
+% that a pair of braces would be stripped.
+%
+% But first, we have to remove the trailing space token.
+%
+\def\finishparsearg#1 \ArgTerm{\expandafter\next\expandafter{#1}}
+
+% \parseargdef\foo{...}
+%	is roughly equivalent to
+% \def\foo{\parsearg\Xfoo}
+% \def\Xfoo#1{...}
+%
+% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
+% favourite TeX trick.  --kasal, 16nov03
+
+\def\parseargdef#1{%
+  \expandafter \doparseargdef \csname\string#1\endcsname #1%
+}
+\def\doparseargdef#1#2{%
+  \def#2{\parsearg#1}%
+  \def#1##1%
+}
+
+% Several utility definitions with active space:
+{
+  \obeyspaces
+  \gdef\obeyedspace{ }
+
+  % Make each space character in the input produce a normal interword
+  % space in the output.  Don't allow a line break at this space, as this
+  % is used only in environments like @example, where each line of input
+  % should produce a line of output anyway.
+  %
+  \gdef\sepspaces{\obeyspaces\let =\tie}
+
+  % If an index command is used in an @example environment, any spaces
+  % therein should become regular spaces in the raw index file, not the
+  % expansion of \tie (\leavevmode \penalty \@M \ ).
+  \gdef\unsepspaces{\let =\space}
+}
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+% Define the framework for environments in texinfo.tex.  It's used like this:
+%
+%   \envdef\foo{...}
+%   \def\Efoo{...}
+%
+% It's the responsibility of \envdef to insert \begingroup before the
+% actual body; @end closes the group after calling \Efoo.  \envdef also
+% defines \thisenv, so the current environment is known; @end checks
+% whether the environment name matches.  The \checkenv macro can also be
+% used to check whether the current environment is the one expected.
+%
+% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
+% are not treated as enviroments; they don't open a group.  (The
+% implementation of @end takes care not to call \endgroup in this
+% special case.)
+
+
+% At runtime, environments start with this:
+\def\startenvironment#1{\begingroup\def\thisenv{#1}}
+% initialize
+\let\thisenv\empty
+
+% ... but they get defined via ``\envdef\foo{...}'':
+\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
+\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
+
+% Check whether we're in the right environment:
+\def\checkenv#1{%
+  \def\temp{#1}%
+  \ifx\thisenv\temp
+  \else
+    \badenverr
+  \fi
+}
+
+% Evironment mismatch, #1 expected:
+\def\badenverr{%
+  \errhelp = \EMsimple
+  \errmessage{This command can appear only \inenvironment\temp,
+    not \inenvironment\thisenv}%
+}
+\def\inenvironment#1{%
+  \ifx#1\empty
+    out of any environment%
+  \else
+    in environment \expandafter\string#1%
+  \fi
+}
+
+% @end foo executes the definition of \Efoo.
+% But first, it executes a specialized version of \checkenv
+%
+\parseargdef\end{%
+  \if 1\csname iscond.#1\endcsname
+  \else
+    % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
+    \expandafter\checkenv\csname#1\endcsname
+    \csname E#1\endcsname
+    \endgroup
+  \fi
+}
+
+\newhelp\EMsimple{Press RETURN to continue.}
+
+
+%% Simple single-character @ commands
+
+% @@ prints an @
+% Kludge this until the fonts are right (grr).
+\def\@{{\tt\char64}}
+
+% This is turned off because it was never documented
+% and you can use @w{...} around a quote to suppress ligatures.
+%% Define @` and @' to be the same as ` and '
+%% but suppressing ligatures.
+%\def\`{{`}}
+%\def\'{{'}}
+
+% Used to generate quoted braces.
+\def\mylbrace {{\tt\char123}}
+\def\myrbrace {{\tt\char125}}
+\let\{=\mylbrace
+\let\}=\myrbrace
+\begingroup
+  % Definitions to produce \{ and \} commands for indices,
+  % and @{ and @} for the aux/toc files.
+  \catcode`\{ = \other \catcode`\} = \other
+  \catcode`\[ = 1 \catcode`\] = 2
+  \catcode`\! = 0 \catcode`\\ = \other
+  !gdef!lbracecmd[\{]%
+  !gdef!rbracecmd[\}]%
+  !gdef!lbraceatcmd[@{]%
+  !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \c
+\let\dotaccent = \.
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \t
+\let\ubaraccent = \b
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+  \def\temp{#1}%
+  \ifx\temp\imacro \ptexi
+  \else\ifx\temp\jmacro \j
+  \else \errmessage{@dotless can be used only with i or j}%
+  \fi\fi
+}
+
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence.  (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo.  Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+  L\kern-.36em
+  {\setbox0=\hbox{T}%
+   \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}%
+  \kern-.15em
+  \TeX
+}
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\hfil\break\hbox{}\ignorespaces}
+
+% @/ allows a line break.
+\let\/=\allowbreak
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=\endofsentencespacefactor\space}
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=\endofsentencespacefactor\space}
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=\endofsentencespacefactor\space}
+
+% @frenchspacing on|off  says whether to put extra space after punctuation.
+% 
+\def\onword{on}
+\def\offword{off}
+%
+\parseargdef\frenchspacing{%
+  \def\temp{#1}%
+  \ifx\temp\onword \plainfrenchspacing
+  \else\ifx\temp\offword \plainnonfrenchspacing
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @frenchspacing option `\temp', must be on/off}%
+  \fi\fi
+}
+
+% @w prevents a word break.  Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox.  We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line.  According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0).  If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+% Another complication is that the group might be very large.  This can
+% cause the glue on the previous page to be unduly stretched, because it
+% does not have much material.  In this case, it's better to add an
+% explicit \vfill so that the extra space is at the bottom.  The
+% threshold for doing this is if the group is more than \vfilllimit
+% percent of a page (\vfilllimit can be changed inside of @tex).
+%
+\newbox\groupbox
+\def\vfilllimit{0.7}
+%
+\envdef\group{%
+  \ifnum\catcode`\^^M=\active \else
+    \errhelp = \groupinvalidhelp
+    \errmessage{@group invalid in context where filling is enabled}%
+  \fi
+  \startsavinginserts
+  %
+  \setbox\groupbox = \vtop\bgroup
+    % Do @comment since we are called inside an environment such as
+    % @example, where each end-of-line in the input causes an
+    % end-of-line in the output.  We don't want the end-of-line after
+    % the `@group' to put extra space in the output.  Since @group
+    % should appear on a line by itself (according to the Texinfo
+    % manual), we don't worry about eating any user text.
+    \comment
+}
+%
+% The \vtop produces a box with normal height and large depth; thus, TeX puts
+% \baselineskip glue before it, and (when the next line of text is done)
+% \lineskip glue after it.  Thus, space below is not quite equal to space
+% above.  But it's pretty close.
+\def\Egroup{%
+    % To get correct interline space between the last line of the group
+    % and the first line afterwards, we have to propagate \prevdepth.
+    \endgraf % Not \par, as it may have been set to \lisppar.
+    \global\dimen1 = \prevdepth
+  \egroup           % End the \vtop.
+  % \dimen0 is the vertical size of the group's box.
+  \dimen0 = \ht\groupbox  \advance\dimen0 by \dp\groupbox
+  % \dimen2 is how much space is left on the page (more or less).
+  \dimen2 = \pageheight   \advance\dimen2 by -\pagetotal
+  % if the group doesn't fit on the current page, and it's a big big
+  % group, force a page break.
+  \ifdim \dimen0 > \dimen2
+    \ifdim \pagetotal < \vfilllimit\pageheight
+      \page
+    \fi
+  \fi
+  \box\groupbox
+  \prevdepth = \dimen1
+  \checkinserts
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil  \mil=0.001in
+
+% Old definition--didn't work.
+%\parseargdef\need{\par %
+%% This method tries to make TeX break the page naturally
+%% if the depth of the box does not fit.
+%{\baselineskip=0pt%
+%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
+%\prevdepth=-1000pt
+%}}
+
+\parseargdef\need{%
+  % Ensure vertical mode, so we don't make a big box in the middle of a
+  % paragraph.
+  \par
+  %
+  % If the @need value is less than one line space, it's useless.
+  \dimen0 = #1\mil
+  \dimen2 = \ht\strutbox
+  \advance\dimen2 by \dp\strutbox
+  \ifdim\dimen0 > \dimen2
+    %
+    % Do a \strut just to make the height of this box be normal, so the
+    % normal leading is inserted relative to the preceding line.
+    % And a page break here is fine.
+    \vtop to #1\mil{\strut\vfil}%
+    %
+    % TeX does not even consider page breaks if a penalty added to the
+    % main vertical list is 10000 or more.  But in order to see if the
+    % empty box we just added fits on the page, we must make it consider
+    % page breaks.  On the other hand, we don't want to actually break the
+    % page after the empty box.  So we use a penalty of 9999.
+    %
+    % There is an extremely small chance that TeX will actually break the
+    % page at this \penalty, if there are no other feasible breakpoints in
+    % sight.  (If the user is using lots of big @group commands, which
+    % almost-but-not-quite fill up a page, TeX will have a hard time doing
+    % good page breaking, for example.)  However, I could not construct an
+    % example where a page broke at this \penalty; if it happens in a real
+    % document, then we can reconsider our strategy.
+    \penalty9999
+    %
+    % Back up by the size of the box, whether we did a page break or not.
+    \kern -#1\mil
+    %
+    % Do not allow a page break right after this kern.
+    \nobreak
+  \fi
+}
+
+% @br   forces paragraph break (and is undocumented).
+
+\let\br = \par
+
+% @page forces the start of a new page.
+%
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
+
+% This defn is used inside nofill environments such as @example.
+\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
+  \leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
+% paragraph.  For more general purposes, use the \margin insertion
+% class.  WHICH is `l' or `r'.
+%
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+%
+\def\doinmargin#1#2{\strut\vadjust{%
+  \nobreak
+  \kern-\strutdepth
+  \vtop to \strutdepth{%
+    \baselineskip=\strutdepth
+    \vss
+    % if you have multiple lines of stuff to put here, you'll need to
+    % make the vbox yourself of the appropriate size.
+    \ifx#1l%
+      \llap{\ignorespaces #2\hskip\inmarginspacing}%
+    \else
+      \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
+    \fi
+    \null
+  }%
+}}
+\def\inleftmargin{\doinmargin l}
+\def\inrightmargin{\doinmargin r}
+%
+% @inmargin{TEXT [, RIGHT-TEXT]}
+% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
+% else use TEXT for both).
+%
+\def\inmargin#1{\parseinmargin #1,,\finish}
+\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
+  \setbox0 = \hbox{\ignorespaces #2}%
+  \ifdim\wd0 > 0pt
+    \def\lefttext{#1}%  have both texts
+    \def\righttext{#2}%
+  \else
+    \def\lefttext{#1}%  have only one text
+    \def\righttext{#1}%
+  \fi
+  %
+  \ifodd\pageno
+    \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
+  \else
+    \def\temp{\inleftmargin\lefttext}%
+  \fi
+  \temp
+}
+
+% @include file    insert text of that file as input.
+%
+\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\includezzz#1{%
+  \pushthisfilestack
+  \def\thisfile{#1}%
+  {%
+    \makevalueexpandable
+    \def\temp{\input #1 }%
+    \expandafter
+  }\temp
+  \popthisfilestack
+}
+\def\filenamecatcodes{%
+  \catcode`\\=\other
+  \catcode`~=\other
+  \catcode`^=\other
+  \catcode`_=\other
+  \catcode`|=\other
+  \catcode`<=\other
+  \catcode`>=\other
+  \catcode`+=\other
+  \catcode`-=\other
+}
+
+\def\pushthisfilestack{%
+  \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
+}
+\def\pushthisfilestackX{%
+  \expandafter\pushthisfilestackY\thisfile\StackTerm
+}
+\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
+  \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
+}
+
+\def\popthisfilestack{\errthisfilestackempty}
+\def\errthisfilestackempty{\errmessage{Internal error:
+  the stack of filenames is empty.}}
+
+\def\thisfile{}
+
+% @center line
+% outputs that line, centered.
+%
+\parseargdef\center{%
+  \ifhmode
+    \let\next\centerH
+  \else
+    \let\next\centerV
+  \fi
+  \next{\hfil \ignorespaces#1\unskip \hfil}%
+}
+\def\centerH#1{%
+  {%
+    \hfil\break
+    \advance\hsize by -\leftskip
+    \advance\hsize by -\rightskip
+    \line{#1}%
+    \break
+  }%
+}
+\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
+
+% @sp n   outputs n lines of vertical space
+
+\parseargdef\sp{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore  is another way to write a comment
+
+\def\comment{\begingroup \catcode`\^^M=\other%
+\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+\commentxxx}
+{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+
+\let\c=\comment
+
+% @paragraphindent NCHARS
+% We'll use ems for NCHARS, close enough.
+% NCHARS can also be the word `asis' or `none'.
+% We cannot feasibly implement @paragraphindent asis, though.
+%
+\def\asisword{asis} % no translation, these are keywords
+\def\noneword{none}
+%
+\parseargdef\paragraphindent{%
+  \def\temp{#1}%
+  \ifx\temp\asisword
+  \else
+    \ifx\temp\noneword
+      \defaultparindent = 0pt
+    \else
+      \defaultparindent = #1em
+    \fi
+  \fi
+  \parindent = \defaultparindent
+}
+
+% @exampleindent NCHARS
+% We'll use ems for NCHARS like @paragraphindent.
+% It seems @exampleindent asis isn't necessary, but
+% I preserve it to make it similar to @paragraphindent.
+\parseargdef\exampleindent{%
+  \def\temp{#1}%
+  \ifx\temp\asisword
+  \else
+    \ifx\temp\noneword
+      \lispnarrowing = 0pt
+    \else
+      \lispnarrowing = #1em
+    \fi
+  \fi
+}
+
+% @firstparagraphindent WORD
+% If WORD is `none', then suppress indentation of the first paragraph
+% after a section heading.  If WORD is `insert', then do indent at such
+% paragraphs.
+%
+% The paragraph indentation is suppressed or not by calling
+% \suppressfirstparagraphindent, which the sectioning commands do.
+% We switch the definition of this back and forth according to WORD.
+% By default, we suppress indentation.
+%
+\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
+\def\insertword{insert}
+%
+\parseargdef\firstparagraphindent{%
+  \def\temp{#1}%
+  \ifx\temp\noneword
+    \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
+  \else\ifx\temp\insertword
+    \let\suppressfirstparagraphindent = \relax
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @firstparagraphindent option `\temp'}%
+  \fi\fi
+}
+
+% Here is how we actually suppress indentation.  Redefine \everypar to
+% \kern backwards by \parindent, and then reset itself to empty.
+%
+% We also make \indent itself not actually do anything until the next
+% paragraph.
+%
+\gdef\dosuppressfirstparagraphindent{%
+  \gdef\indent{%
+    \restorefirstparagraphindent
+    \indent
+  }%
+  \gdef\noindent{%
+    \restorefirstparagraphindent
+    \noindent
+  }%
+  \global\everypar = {%
+    \kern -\parindent
+    \restorefirstparagraphindent
+  }%
+}
+
+\gdef\restorefirstparagraphindent{%
+  \global \let \indent = \ptexindent
+  \global \let \noindent = \ptexnoindent
+  \global \everypar = {}%
+}
+
+
+% @asis just yields its argument.  Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}.  So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+  \catcode\underChar = \active
+  \gdef\mathunderscore{%
+    \catcode\underChar=\active
+    \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+  }
+}
+% Another complication: we want \\ (and @\) to output a \ character.
+% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
+% this is not advertised and we don't care.  Texinfo does not
+% otherwise define @\.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+  \tex
+  \mathunderscore
+  \let\\ = \mathbackslash
+  \mathactive
+  $\finishmath
+}
+\def\finishmath#1{#1$\endgroup}  % Close the group opened by \tex.
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+  \catcode`^ = \active
+  \catcode`< = \active
+  \catcode`> = \active
+  \catcode`+ = \active
+  \gdef\mathactive{%
+    \let^ = \ptexhat
+    \let< = \ptexless
+    \let> = \ptexgtr
+    \let+ = \ptexplus
+  }
+}
+
+% @bullet and @minus need the same treatment as @math, just above.
+\def\bullet{$\ptexbullet$}
+\def\minus{$-$}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in a typewriter
+% font as three actual period characters.
+%
+\def\dots{%
+  \leavevmode
+  \hbox to 1.5em{%
+    \hskip 0pt plus 0.25fil
+    .\hfil.\hfil.%
+    \hskip 0pt plus 0.5fil
+  }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+  \dots
+  \spacefactor=\endofsentencespacefactor
+}
+
+% @comma{} is so commas can be inserted into text without messing up
+% Texinfo's parsing.
+%
+\let\comma = ,
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% If working on a large document in chapters, it is convenient to
+% be able to disable indexing, cross-referencing, and contents, for test runs.
+% This is done with @novalidate (before @setfilename).
+%
+\newif\iflinks \linkstrue % by default we want the aux files.
+\let\novalidate = \linksfalse
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+   \fixbackslash  % Turn off hack to swallow `\input texinfo'.
+   \iflinks
+     \tryauxfile
+     % Open the new aux file.  TeX will close it automatically at exit.
+     \immediate\openout\auxfile=\jobname.aux
+   \fi % \openindices needs to do some work in any case.
+   \openindices
+   \let\setfilename=\comment % Ignore extra @setfilename cmds.
+   %
+   % If texinfo.cnf is present on the system, read it.
+   % Useful for site-wide @afourpaper, etc.
+   \openin 1 texinfo.cnf
+   \ifeof 1 \else \input texinfo.cnf \fi
+   \closein 1
+   %
+   \comment % Ignore the actual filename.
+}
+
+% Called from \setfilename.
+%
+\def\openindices{%
+  \newindex{cp}%
+  \newcodeindex{fn}%
+  \newcodeindex{vr}%
+  \newcodeindex{tp}%
+  \newcodeindex{ky}%
+  \newcodeindex{pg}%
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+
+\message{pdf,}
+% adobe `portable' document format
+\newcount\tempnum
+\newcount\lnkcount
+\newtoks\filename
+\newcount\filenamelength
+\newcount\pgn
+\newtoks\toksA
+\newtoks\toksB
+\newtoks\toksC
+\newtoks\toksD
+\newbox\boxA
+\newcount\countA
+\newif\ifpdf
+\newif\ifpdfmakepagedest
+
+% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
+% can be set).  So we test for \relax and 0 as well as \undefined,
+% borrowed from ifpdf.sty.
+\ifx\pdfoutput\undefined
+\else
+  \ifx\pdfoutput\relax
+  \else
+    \ifcase\pdfoutput
+    \else
+      \pdftrue
+    \fi
+  \fi
+\fi
+
+% PDF uses PostScript string constants for the names of xref targets, to
+% for display in the outlines, and in other places.  Thus, we have to
+% double any backslashes.  Otherwise, a name like "\node" will be
+% interpreted as a newline (\n), followed by o, d, e.  Not good.
+% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html
+% (and related messages, the final outcome is that it is up to the TeX
+% user to double the backslashes and otherwise make the string valid, so
+% that's we do).
+
+% double active backslashes.
+% 
+{\catcode`\@=0 \catcode`\\=\active
+ @gdef at activebackslash{@catcode`@\=@active @otherbackslash}
+ @gdef at activebackslashdouble{%
+   @catcode at backChar=@active
+   @let\=@doublebackslash}
+}
+
+% To handle parens, we must adopt a different approach, since parens are
+% not active characters.  hyperref.dtx (which has the same problem as
+% us) handles it with this amazing macro to replace tokens.  I've
+% tinkered with it a little for texinfo, but it's definitely from there.
+% 
+% #1 is the tokens to replace.
+% #2 is the replacement.
+% #3 is the control sequence with the string.
+% 
+\def\HyPsdSubst#1#2#3{%
+  \def\HyPsdReplace##1#1##2\END{%
+    ##1%
+    \ifx\\##2\\%
+    \else
+      #2%
+      \HyReturnAfterFi{%
+        \HyPsdReplace##2\END
+      }%
+    \fi
+  }%
+  \xdef#3{\expandafter\HyPsdReplace#3#1\END}%
+}
+\long\def\HyReturnAfterFi#1\fi{\fi#1}
+
+% #1 is a control sequence in which to do the replacements.
+\def\backslashparens#1{%
+  \xdef#1{#1}% redefine it as its expansion; the definition is simply
+             % \lastnode when called from \setref -> \pdfmkdest.
+  \HyPsdSubst{(}{\backslashlparen}{#1}%
+  \HyPsdSubst{)}{\backslashrparen}{#1}%
+}
+
+{\catcode\exclamChar = 0 \catcode\backChar = \other
+ !gdef!backslashlparen{\(}%
+ !gdef!backslashrparen{\)}%
+}
+
+\ifpdf
+  \input pdfcolor
+  \pdfcatalog{/PageMode /UseOutlines}%
+  \def\dopdfimage#1#2#3{%
+    \def\imagewidth{#2}%
+    \def\imageheight{#3}%
+    % without \immediate, pdftex seg faults when the same image is
+    % included twice.  (Version 3.14159-pre-1.0-unofficial-20010704.)
+    \ifnum\pdftexversion < 14
+      \immediate\pdfimage
+    \else
+      \immediate\pdfximage
+    \fi
+      \ifx\empty\imagewidth\else width \imagewidth \fi
+      \ifx\empty\imageheight\else height \imageheight \fi
+      \ifnum\pdftexversion<13
+         #1.pdf%
+       \else
+         {#1.pdf}%
+       \fi
+    \ifnum\pdftexversion < 14 \else
+      \pdfrefximage \pdflastximage
+    \fi}
+  \def\pdfmkdest#1{{%
+    % We have to set dummies so commands such as @code, and characters
+    % such as \, aren't expanded when present in a section title.
+    \atdummies
+    \activebackslashdouble
+    \def\pdfdestname{#1}%
+    \backslashparens\pdfdestname
+    \pdfdest name{\pdfdestname} xyz%
+  }}%
+  %
+  % used to mark target names; must be expandable.
+  \def\pdfmkpgn#1{#1}%
+  %
+  \let\linkcolor = \Blue  % was Cyan, but that seems light?
+  \def\endlink{\Black\pdfendlink}
+  % Adding outlines to PDF; macros for calculating structure of outlines
+  % come from Petr Olsak
+  \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+    \else \csname#1\endcsname \fi}
+  \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
+    \advance\tempnum by 1
+    \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
+  %
+  % #1 is the section text, which is what will be displayed in the
+  % outline by the pdf viewer.  #2 is the pdf expression for the number
+  % of subentries (or empty, for subsubsections).  #3 is the node text,
+  % which might be empty if this toc entry had no corresponding node.
+  % #4 is the page number
+  %
+  \def\dopdfoutline#1#2#3#4{%
+    % Generate a link to the node text if that exists; else, use the
+    % page number.  We could generate a destination for the section
+    % text in the case where a section has no node, but it doesn't
+    % seem worth the trouble, since most documents are normally structured.
+    \def\pdfoutlinedest{#3}%
+    \ifx\pdfoutlinedest\empty
+      \def\pdfoutlinedest{#4}%
+    \else
+      % Doubled backslashes in the name.
+      {\activebackslashdouble \xdef\pdfoutlinedest{#3}%
+       \backslashparens\pdfoutlinedest}%
+    \fi
+    %
+    % Also double the backslashes in the display string.
+    {\activebackslashdouble \xdef\pdfoutlinetext{#1}%
+     \backslashparens\pdfoutlinetext}%
+    %
+    \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
+  }
+  %
+  \def\pdfmakeoutlines{%
+    \begingroup
+      % Thanh's hack / proper braces in bookmarks
+      \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
+      \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace
+      %
+      % Read toc silently, to get counts of subentries for \pdfoutline.
+      \def\numchapentry##1##2##3##4{%
+	\def\thischapnum{##2}%
+	\def\thissecnum{0}%
+	\def\thissubsecnum{0}%
+      }%
+      \def\numsecentry##1##2##3##4{%
+	\advancenumber{chap\thischapnum}%
+	\def\thissecnum{##2}%
+	\def\thissubsecnum{0}%
+      }%
+      \def\numsubsecentry##1##2##3##4{%
+	\advancenumber{sec\thissecnum}%
+	\def\thissubsecnum{##2}%
+      }%
+      \def\numsubsubsecentry##1##2##3##4{%
+	\advancenumber{subsec\thissubsecnum}%
+      }%
+      \def\thischapnum{0}%
+      \def\thissecnum{0}%
+      \def\thissubsecnum{0}%
+      %
+      % use \def rather than \let here because we redefine \chapentry et
+      % al. a second time, below.
+      \def\appentry{\numchapentry}%
+      \def\appsecentry{\numsecentry}%
+      \def\appsubsecentry{\numsubsecentry}%
+      \def\appsubsubsecentry{\numsubsubsecentry}%
+      \def\unnchapentry{\numchapentry}%
+      \def\unnsecentry{\numsecentry}%
+      \def\unnsubsecentry{\numsubsecentry}%
+      \def\unnsubsubsecentry{\numsubsubsecentry}%
+      \readdatafile{toc}%
+      %
+      % Read toc second time, this time actually producing the outlines.
+      % The `-' means take the \expnumber as the absolute number of
+      % subentries, which we calculated on our first read of the .toc above.
+      %
+      % We use the node names as the destinations.
+      \def\numchapentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
+      \def\numsecentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
+      \def\numsubsecentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
+      \def\numsubsubsecentry##1##2##3##4{% count is always zero
+        \dopdfoutline{##1}{}{##3}{##4}}%
+      %
+      % PDF outlines are displayed using system fonts, instead of
+      % document fonts.  Therefore we cannot use special characters,
+      % since the encoding is unknown.  For example, the eogonek from
+      % Latin 2 (0xea) gets translated to a | character.  Info from
+      % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
+      %
+      % xx to do this right, we have to translate 8-bit characters to
+      % their "best" equivalent, based on the @documentencoding.  Right
+      % now, I guess we'll just let the pdf reader have its way.
+      \indexnofonts
+      \setupdatafile
+      \activebackslash
+      \input \jobname.toc
+    \endgroup
+  }
+  %
+  \def\skipspaces#1{\def\PP{#1}\def\D{|}%
+    \ifx\PP\D\let\nextsp\relax
+    \else\let\nextsp\skipspaces
+      \ifx\p\space\else\addtokens{\filename}{\PP}%
+        \advance\filenamelength by 1
+      \fi
+    \fi
+    \nextsp}
+  \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
+  \ifnum\pdftexversion < 14
+    \let \startlink \pdfannotlink
+  \else
+    \let \startlink \pdfstartlink
+  \fi
+  \def\pdfurl#1{%
+    \begingroup
+      \normalturnoffactive\def\@{@}%
+      \makevalueexpandable
+      \leavevmode\Red
+      \startlink attr{/Border [0 0 0]}%
+        user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
+    \endgroup}
+  \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
+  \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+  \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
+  \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
+  \def\maketoks{%
+    \expandafter\poptoks\the\toksA|ENDTOKS|\relax
+    \ifx\first0\adn0
+    \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
+    \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
+    \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
+    \else
+      \ifnum0=\countA\else\makelink\fi
+      \ifx\first.\let\next=\done\else
+        \let\next=\maketoks
+        \addtokens{\toksB}{\the\toksD}
+        \ifx\first,\addtokens{\toksB}{\space}\fi
+      \fi
+    \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+    \next}
+  \def\makelink{\addtokens{\toksB}%
+    {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
+  \def\pdflink#1{%
+    \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
+    \linkcolor #1\endlink}
+  \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\else
+  \let\pdfmkdest = \gobble
+  \let\pdfurl = \gobble
+  \let\endlink = \relax
+  \let\linkcolor = \relax
+  \let\pdfmakeoutlines = \relax
+\fi  % \ifx\pdfoutput
+
+
+\message{fonts,}
+
+% Change the current font style to #1, remembering it in \curfontstyle.
+% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
+% italics, not bold italics.
+%
+\def\setfontstyle#1{%
+  \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
+  \csname ten#1\endcsname  % change the current font
+}
+
+% Select #1 fonts with the current style.
+%
+\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
+
+\def\rm{\fam=0 \setfontstyle{rm}}
+\def\it{\fam=\itfam \setfontstyle{it}}
+\def\sl{\fam=\slfam \setfontstyle{sl}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
+
+% Texinfo sort of supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf.
+\newfam\sffam
+\def\sf{\fam=\sffam \setfontstyle{sf}}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this font style.
+\def\ttsl{\setfontstyle{ttsl}}
+
+% Default leading.
+\newdimen\textleading  \textleading = 13.2pt
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly.  There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+\def\setleading#1{%
+  \normalbaselineskip = #1\relax
+  \normallineskip = \lineskipfactor\normalbaselineskip
+  \normalbaselines
+  \setbox\strutbox =\hbox{%
+    \vrule width0pt height\strutheightpercent\baselineskip
+                    depth \strutdepthpercent \baselineskip
+  }%
+}
+
+% Set the font macro #1 to the font named #2, adding on the
+% specified font prefix (normally `cm').
+% #3 is the font's design size, #4 is a scale factor
+\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
+
+% Use cm as the default font prefix.
+% To specify the font prefix, you must define \fontprefix
+% before you read in texinfo.tex.
+\ifx\fontprefix\undefined
+\def\fontprefix{cm}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx}               %where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
+
+% Text fonts (11.2pt, magstep1).
+\def\textnominalsize{11pt}
+\edef\mainmagstep{\magstephalf}
+\setfont\textrm\rmshape{10}{\mainmagstep}
+\setfont\texttt\ttshape{10}{\mainmagstep}
+\setfont\textbf\bfshape{10}{\mainmagstep}
+\setfont\textit\itshape{10}{\mainmagstep}
+\setfont\textsl\slshape{10}{\mainmagstep}
+\setfont\textsf\sfshape{10}{\mainmagstep}
+\setfont\textsc\scshape{10}{\mainmagstep}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstep1}
+\setfont\deftt\ttshape{10}{\magstep1}
+\setfont\defttsl\ttslshape{10}{\magstep1}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}
+\setfont\smalltt\ttshape{9}{1000}
+\setfont\smallbf\bfshape{10}{900}
+\setfont\smallit\itshape{9}{1000}
+\setfont\smallsl\slshape{9}{1000}
+\setfont\smallsf\sfshape{9}{1000}
+\setfont\smallsc\scshape{10}{900}
+\setfont\smallttsl\ttslshape{10}{900}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}
+\setfont\smallertt\ttshape{8}{1000}
+\setfont\smallerbf\bfshape{10}{800}
+\setfont\smallerit\itshape{8}{1000}
+\setfont\smallersl\slshape{8}{1000}
+\setfont\smallersf\sfshape{8}{1000}
+\setfont\smallersc\scshape{10}{800}
+\setfont\smallerttsl\ttslshape{10}{800}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}
+\setfont\titleit\itbshape{10}{\magstep4}
+\setfont\titlesl\slbshape{10}{\magstep4}
+\setfont\titlett\ttbshape{12}{\magstep3}
+\setfont\titlettsl\ttslshape{10}{\magstep4}
+\setfont\titlesf\sfbshape{17}{\magstep1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\authorrm{\secrm}
+\def\authortt{\sectt}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\def\chapnominalsize{17pt}
+\setfont\chaprm\rmbshape{12}{\magstep2}
+\setfont\chapit\itbshape{10}{\magstep3}
+\setfont\chapsl\slbshape{10}{\magstep3}
+\setfont\chaptt\ttbshape{12}{\magstep2}
+\setfont\chapttsl\ttslshape{10}{\magstep3}
+\setfont\chapsf\sfbshape{17}{1000}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+
+% Section fonts (14.4pt).
+\def\secnominalsize{14pt}
+\setfont\secrm\rmbshape{12}{\magstep1}
+\setfont\secit\itbshape{10}{\magstep2}
+\setfont\secsl\slbshape{10}{\magstep2}
+\setfont\sectt\ttbshape{12}{\magstep1}
+\setfont\secttsl\ttslshape{10}{\magstep2}
+\setfont\secsf\sfbshape{12}{\magstep1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+
+% Subsection fonts (13.15pt).
+\def\ssecnominalsize{13pt}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}
+\setfont\ssecit\itbshape{10}{1315}
+\setfont\ssecsl\slbshape{10}{1315}
+\setfont\ssectt\ttbshape{12}{\magstephalf}
+\setfont\ssecttsl\ttslshape{10}{1315}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1315}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled 1315
+
+% Reduced fonts for @acro in text (10pt).
+\def\reducednominalsize{10pt}
+\setfont\reducedrm\rmshape{10}{1000}
+\setfont\reducedtt\ttshape{10}{1000}
+\setfont\reducedbf\bfshape{10}{1000}
+\setfont\reducedit\itshape{10}{1000}
+\setfont\reducedsl\slshape{10}{1000}
+\setfont\reducedsf\sfshape{10}{1000}
+\setfont\reducedsc\scshape{10}{1000}
+\setfont\reducedttsl\ttslshape{10}{1000}
+\font\reducedi=cmmi10
+\font\reducedsy=cmsy10
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families.  Since
+% texinfo doesn't allow for producing subscripts and superscripts except
+% in the main text, we don't bother to reset \scriptfont and
+% \scriptscriptfont (which would also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+  \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
+  \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
+  \textfont\ttfam=\tentt \textfont\sffam=\tensf
+}
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE.  We do this because \STYLE needs to also set the
+% current \fam for math mode.  Our \STYLE (e.g., \rm) commands hardwire
+% \tenSTYLE to set the current font.
+%
+% Each font-changing command also sets the names \lsize (one size lower)
+% and \lllsize (three sizes lower).  These relative commands are used in
+% the LaTeX logo and acronyms.
+%
+% This all needs generalizing, badly.
+%
+\def\textfonts{%
+  \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+  \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+  \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+  \let\tenttsl=\textttsl
+  \def\curfontsize{text}%
+  \def\lsize{reduced}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{\textleading}}
+\def\titlefonts{%
+  \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+  \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+  \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+  \let\tenttsl=\titlettsl
+  \def\curfontsize{title}%
+  \def\lsize{chap}\def\lllsize{subsec}%
+  \resetmathfonts \setleading{25pt}}
+\def\titlefont#1{{\titlefonts\rm #1}}
+\def\chapfonts{%
+  \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+  \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+  \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+  \let\tenttsl=\chapttsl
+  \def\curfontsize{chap}%
+  \def\lsize{sec}\def\lllsize{text}%
+  \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+  \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+  \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+  \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+  \let\tenttsl=\secttsl
+  \def\curfontsize{sec}%
+  \def\lsize{subsec}\def\lllsize{reduced}%
+  \resetmathfonts \setleading{16pt}}
+\def\subsecfonts{%
+  \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+  \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+  \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+  \let\tenttsl=\ssecttsl
+  \def\curfontsize{ssec}%
+  \def\lsize{text}\def\lllsize{small}%
+  \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts
+\def\reducedfonts{%
+  \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
+  \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
+  \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
+  \let\tenttsl=\reducedttsl
+  \def\curfontsize{reduced}%
+  \def\lsize{small}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{10.5pt}}
+\def\smallfonts{%
+  \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
+  \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
+  \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
+  \let\tenttsl=\smallttsl
+  \def\curfontsize{small}%
+  \def\lsize{smaller}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{10.5pt}}
+\def\smallerfonts{%
+  \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
+  \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
+  \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
+  \let\tenttsl=\smallerttsl
+  \def\curfontsize{smaller}%
+  \def\lsize{smaller}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{9.5pt}}
+
+% Set the fonts to use with the @small... environments.
+\let\smallexamplefonts = \smallfonts
+
+% About \smallexamplefonts.  If we use \smallfonts (9pt), @smallexample
+% can fit this many characters:
+%   8.5x11=86   smallbook=72  a4=90  a5=69
+% If we use \scriptfonts (8pt), then we can fit this many characters:
+%   8.5x11=90+  smallbook=80  a4=90+  a5=77
+% For me, subjectively, the few extra characters that fit aren't worth
+% the additional smallness of 8pt.  So I'm making the default 9pt.
+%
+% By the way, for comparison, here's what fits with @example (10pt):
+%   8.5x11=71  smallbook=60  a4=75  a5=58
+%
+% I wish the USA used A4 paper.
+% --karl, 24jan03.
+
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\textfonts \rm
+
+% Define these so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}
+\setfont\shortcontbf\bfshape{10}{\magstep1}  % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}
+\setfont\shortconttt\ttshape{12}{1000}
+
+%% Add scribe-like font environments, plus @l for inline lisp (usually sans
+%% serif) and @ii for TeX italic
+
+% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
+% unless the following character is such as not to need one.
+\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else
+                    \ptexslash\fi\fi\fi}
+\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx}
+\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally uses \ttsl.
+% @var is set to this for defun arguments.
+\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally use \sl.  We never want
+% ttsl for book titles, do we?
+\def\cite#1{{\sl #1}\futurelet\next\smartitalicx}
+
+\let\i=\smartitalic
+\let\slanted=\smartslanted
+\let\var=\smartslanted
+\let\dfn=\smartslanted
+\let\emph=\smartitalic
+
+% @b, explicit bold.
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% @sansserif, explicit sans.
+\def\sansserif#1{{\sf #1}}
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph.  Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1  \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+% Set sfcode to normal for the chars that usually have another value.
+% Can't use plain's \frenchspacing because it uses the `\x notation, and
+% sometimes \x has an active definition that messes things up.
+%
+\catcode`@=11
+  \def\plainfrenchspacing{%
+    \sfcode\dotChar  =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
+    \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+    \def\endofsentencespacefactor{1000}% for @. and friends
+  }
+  \def\plainnonfrenchspacing{%
+    \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000
+    \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250
+    \def\endofsentencespacefactor{3000}% for @. and friends
+  }
+\catcode`@=\other
+\def\endofsentencespacefactor{3000}% default
+
+\def\t#1{%
+  {\tt \rawbackslash \plainfrenchspacing #1}%
+  \null
+}
+\def\samp#1{`\tclose{#1}'\null}
+\setfont\keyrm\rmshape{8}{1000}
+\font\keysy=cmsy9
+\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+  \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+    \vbox{\hrule\kern-0.4pt
+     \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+    \kern-0.4pt\hrule}%
+  \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+% The old definition, with no lozenge:
+%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @file, @option are the same as @samp.
+\let\file=\samp
+\let\option=\samp
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
+\def\tclose#1{%
+  {%
+    % Change normal interword space to be same as for the current font.
+    \spaceskip = \fontdimen2\font
+    %
+    % Switch to typewriter.
+    \tt
+    %
+    % But `\ ' produces the large typewriter interword space.
+    \def\ {{\spaceskip = 0pt{} }}%
+    %
+    % Turn off hyphenation.
+    \nohyphenation
+    %
+    \rawbackslash
+    \plainfrenchspacing
+    #1%
+  }%
+  \null
+}
+
+% We *must* turn on hyphenation at `-' and `_' in @code.
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash.
+%  -- rms.
+{
+  \catcode`\-=\active
+  \catcode`\_=\active
+  %
+  \global\def\code{\begingroup
+    \catcode`\-=\active  \catcode`\_=\active
+    \ifallowcodebreaks
+     \let-\codedash
+     \let_\codeunder
+    \else
+     \let-\realdash
+     \let_\realunder
+    \fi
+    \codex
+  }
+}
+
+\def\realdash{-}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{%
+  % this is all so @math{@code{var_name}+1} can work.  In math mode, _
+  % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
+  % will therefore expand the active definition of _, which is us
+  % (inside @code that is), therefore an endless loop.
+  \ifusingtt{\ifmmode
+               \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
+             \else\normalunderscore \fi
+             \discretionary{}{}{}}%
+            {\_}%
+}
+\def\codex #1{\tclose{#1}\endgroup}
+
+% An additional complication: the above will allow breaks after, e.g.,
+% each of the four underscores in __typeof__.  This is undesirable in
+% some manuals, especially if they don't have long identifiers in
+% general.  @allowcodebreaks provides a way to control this.
+% 
+\newif\ifallowcodebreaks  \allowcodebreakstrue
+
+\def\keywordtrue{true}
+\def\keywordfalse{false}
+
+\parseargdef\allowcodebreaks{%
+  \def\txiarg{#1}%
+  \ifx\txiarg\keywordtrue
+    \allowcodebreakstrue
+  \else\ifx\txiarg\keywordfalse
+    \allowcodebreaksfalse
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @allowcodebreaks option `\txiarg'}%
+  \fi\fi
+}
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+%   `example' (@kbd uses ttsl only inside of @example and friends),
+%   or `code' (@kbd uses normal tty font always).
+\parseargdef\kbdinputstyle{%
+  \def\txiarg{#1}%
+  \ifx\txiarg\worddistinct
+    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+  \else\ifx\txiarg\wordexample
+    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+  \else\ifx\txiarg\wordcode
+    \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @kbdinputstyle option `\txiarg'}%
+  \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct.'
+\kbdinputstyle distinct
+
+\def\xkey{\key}
+\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+\ifx\one\xkey\ifx\threex\three \key{#2}%
+\else{\tclose{\kbdfont\look}}\fi
+\else{\tclose{\kbdfont\look}}\fi}
+
+% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
+\let\indicateurl=\code
+\let\env=\code
+\let\command=\code
+
+% @uref (abbreviation for `urlref') takes an optional (comma-separated)
+% second argument specifying the text to display and an optional third
+% arg as text to display instead of (rather than in addition to) the url
+% itself.  First (mandatory) arg is the url.  Perhaps eventually put in
+% a hypertex \special here.
+%
+\def\uref#1{\douref #1,,,\finish}
+\def\douref#1,#2,#3,#4\finish{\begingroup
+  \unsepspaces
+  \pdfurl{#1}%
+  \setbox0 = \hbox{\ignorespaces #3}%
+  \ifdim\wd0 > 0pt
+    \unhbox0 % third arg given, show only that
+  \else
+    \setbox0 = \hbox{\ignorespaces #2}%
+    \ifdim\wd0 > 0pt
+      \ifpdf
+        \unhbox0             % PDF: 2nd arg given, show only it
+      \else
+        \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
+      \fi
+    \else
+      \code{#1}% only url given, so show it
+    \fi
+  \fi
+  \endlink
+\endgroup}
+
+% @url synonym for @uref, since that's how everyone uses it.
+%
+\let\url=\uref
+
+% rms does not like angle brackets --karl, 17may97.
+% So now @email is just like @uref, unless we are pdf.
+%
+%\def\email#1{\angleleft{\tt #1}\angleright}
+\ifpdf
+  \def\email#1{\doemail#1,,\finish}
+  \def\doemail#1,#2,#3\finish{\begingroup
+    \unsepspaces
+    \pdfurl{mailto:#1}%
+    \setbox0 = \hbox{\ignorespaces #2}%
+    \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
+    \endlink
+  \endgroup}
+\else
+  \let\email=\uref
+\fi
+
+% Check if we are currently using a typewriter font.  Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Typeset a dimension, e.g., `in' or `pt'.  The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find.  We need it for
+% Polish suppressed-l.  --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}}              % roman font
+\def\sc#1{{\smallcaps#1}}       % smallcaps font
+\def\ii#1{{\it #1}}             % italic font
+
+% @acronym for "FBI", "NATO", and the like.
+% We print this one point size smaller, since it's intended for
+% all-uppercase.
+% 
+\def\acronym#1{\doacronym #1,,\finish}
+\def\doacronym#1,#2,#3\finish{%
+  {\selectfonts\lsize #1}%
+  \def\temp{#2}%
+  \ifx\temp\empty \else
+    \space ({\unsepspaces \ignorespaces \temp \unskip})%
+  \fi
+}
+
+% @abbr for "Comput. J." and the like.
+% No font change, but don't do end-of-sentence spacing.
+% 
+\def\abbr#1{\doabbr #1,,\finish}
+\def\doabbr#1,#2,#3\finish{%
+  {\plainfrenchspacing #1}%
+  \def\temp{#2}%
+  \ifx\temp\empty \else
+    \space ({\unsepspaces \ignorespaces \temp \unskip})%
+  \fi
+}
+
+% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
+%
+\def\pounds{{\it\$}}
+
+% @euro{} comes from a separate font, depending on the current style.
+% We use the free feym* fonts from the eurosym package by Henrik
+% Theiling, which support regular, slanted, bold and bold slanted (and
+% "outlined" (blackboard board, sort of) versions, which we don't need).
+% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
+% 
+% Although only regular is the truly official Euro symbol, we ignore
+% that.  The Euro is designed to be slightly taller than the regular
+% font height.
+% 
+% feymr - regular
+% feymo - slanted
+% feybr - bold
+% feybo - bold slanted
+% 
+% There is no good (free) typewriter version, to my knowledge.
+% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
+% Hmm.
+% 
+% Also doesn't work in math.  Do we need to do math with euro symbols?
+% Hope not.
+% 
+% 
+\def\euro{{\eurofont e}}
+\def\eurofont{%
+  % We set the font at each command, rather than predefining it in
+  % \textfonts and the other font-switching commands, so that
+  % installations which never need the symbol don't have to have the
+  % font installed.
+  % 
+  % There is only one designed size (nominal 10pt), so we always scale
+  % that to the current nominal size.
+  % 
+  % By the way, simply using "at 1em" works for cmr10 and the like, but
+  % does not work for cmbx10 and other extended/shrunken fonts.
+  % 
+  \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
+  %
+  \ifx\curfontstyle\bfstylename 
+    % bold:
+    \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
+  \else 
+    % regular:
+    \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
+  \fi
+  \thiseurofont
+}
+
+% @registeredsymbol - R in a circle.  The font for the R should really
+% be smaller yet, but lllsize is the best we can do for now.
+% Adapted from the plain.tex definition of \copyright.
+%
+\def\registeredsymbol{%
+  $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
+               \hfil\crcr\Orb}}%
+    }$%
+}
+
+% Laurent Siebenmann reports \Orb undefined with:
+%  Textures 1.7.7 (preloaded format=plain 93.10.14)  (68K)  16 APR 2004 02:38
+% so we'll define it if necessary.
+% 
+\ifx\Orb\undefined
+\def\Orb{\mathhexbox20D}
+\fi
+
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page.  Must do @settitle before @titlepage.
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+% Do an implicit @contents or @shortcontents after @end titlepage if the
+% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
+%
+\newif\ifsetcontentsaftertitlepage
+ \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
+\newif\ifsetshortcontentsaftertitlepage
+ \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
+
+\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+        \endgroup\page\hbox{}\page}
+
+\envdef\titlepage{%
+  % Open one extra group, as we want to close it in the middle of \Etitlepage.
+  \begingroup
+    \parindent=0pt \textfonts
+    % Leave some space at the very top of the page.
+    \vglue\titlepagetopglue
+    % No rule at page bottom unless we print one at the top with @title.
+    \finishedtitlepagetrue
+    %
+    % Most title ``pages'' are actually two pages long, with space
+    % at the top of the second.  We don't want the ragged left on the second.
+    \let\oldpage = \page
+    \def\page{%
+      \iffinishedtitlepage\else
+	 \finishtitlepage
+      \fi
+      \let\page = \oldpage
+      \page
+      \null
+    }%
+}
+
+\def\Etitlepage{%
+    \iffinishedtitlepage\else
+	\finishtitlepage
+    \fi
+    % It is important to do the page break before ending the group,
+    % because the headline and footline are only empty inside the group.
+    % If we use the new definition of \page, we always get a blank page
+    % after the title page, which we certainly don't want.
+    \oldpage
+  \endgroup
+  %
+  % Need this before the \...aftertitlepage checks so that if they are
+  % in effect the toc pages will come out with page numbers.
+  \HEADINGSon
+  %
+  % If they want short, they certainly want long too.
+  \ifsetshortcontentsaftertitlepage
+    \shortcontents
+    \contents
+    \global\let\shortcontents = \relax
+    \global\let\contents = \relax
+  \fi
+  %
+  \ifsetcontentsaftertitlepage
+    \contents
+    \global\let\contents = \relax
+    \global\let\shortcontents = \relax
+  \fi
+}
+
+\def\finishtitlepage{%
+  \vskip4pt \hrule height 2pt width \hsize
+  \vskip\titlepagebottomglue
+  \finishedtitlepagetrue
+}
+
+%%% Macros to be used within @titlepage:
+
+\let\subtitlerm=\tenrm
+\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
+
+\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines
+		\let\tt=\authortt}
+
+\parseargdef\title{%
+  \checkenv\titlepage
+  \leftline{\titlefonts\rm #1}
+  % print a rule at the page bottom also.
+  \finishedtitlepagefalse
+  \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+}
+
+\parseargdef\subtitle{%
+  \checkenv\titlepage
+  {\subtitlefont \rightline{#1}}%
+}
+
+% @author should come last, but may come many times.
+% It can also be used inside @quotation.
+%
+\parseargdef\author{%
+  \def\temp{\quotation}%
+  \ifx\thisenv\temp
+    \def\quotationauthor{#1}% printed in \Equotation.
+  \else
+    \checkenv\titlepage
+    \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
+    {\authorfont \leftline{#1}}%
+  \fi
+}
+
+
+%%% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks\evenheadline    % headline on even pages
+\newtoks\oddheadline     % headline on odd pages
+\newtoks\evenfootline    % footline on even pages
+\newtoks\oddfootline     % footline on odd pages
+
+% Now make TeX use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+                            \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+                            \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what  @headings on  does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
+\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
+\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
+\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
+\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
+  \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+  %
+  % Leave some space for the footline.  Hopefully ok to assume
+  % @evenfooting will not be used by itself.
+  \global\advance\pageheight by -\baselineskip
+  \global\advance\vsize by -\baselineskip
+}
+
+\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
+
+% @headings double      turns headings on for double-sided printing.
+% @headings single      turns headings on for single-sided printing.
+% @headings off         turns them off.
+% @headings on          same as @headings double, retained for compatibility.
+% @headings after       turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\HEADINGSoff{%
+\global\evenheadline={\hfil} \global\evenfootline={\hfil}
+\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
+\HEADINGSoff
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% This produces Day Month Year style of output.
+% Only define if not already defined, in case a txi-??.tex file has set
+% up a different format (e.g., txi-cs.tex does this).
+\ifx\today\undefined
+\def\today{%
+  \number\day\space
+  \ifcase\month
+  \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
+  \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
+  \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
+  \fi
+  \space\number\year}
+\fi
+
+% @settitle line...  specifies the title of the document, for headings.
+% It generates no output of its own.
+\def\thistitle{\putwordNoTitle}
+\def\settitle{\parsearg{\gdef\thistitle}}
+
+
+\message{tables,}
+% Tables -- @table, @ftable, @vtable, @item(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent  \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin  \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\itemzzz #1{\begingroup %
+  \advance\hsize by -\rightskip
+  \advance\hsize by -\tableindent
+  \setbox0=\hbox{\itemindicate{#1}}%
+  \itemindex{#1}%
+  \nobreak % This prevents a break before @itemx.
+  %
+  % If the item text does not fit in the space we have, put it on a line
+  % by itself, and do not allow a page break either before or after that
+  % line.  We do not start a paragraph here because then if the next
+  % command is, e.g., @kindex, the whatsit would get put into the
+  % horizontal list on a line by itself, resulting in extra blank space.
+  \ifdim \wd0>\itemmax
+    %
+    % Make this a paragraph so we get the \parskip glue and wrapping,
+    % but leave it ragged-right.
+    \begingroup
+      \advance\leftskip by-\tableindent
+      \advance\hsize by\tableindent
+      \advance\rightskip by0pt plus1fil
+      \leavevmode\unhbox0\par
+    \endgroup
+    %
+    % We're going to be starting a paragraph, but we don't want the
+    % \parskip glue -- logically it's part of the @item we just started.
+    \nobreak \vskip-\parskip
+    %
+    % Stop a page break at the \parskip glue coming up.  However, if
+    % what follows is an environment such as @example, there will be no
+    % \parskip glue; then the negative vskip we just inserted would
+    % cause the example and the item to crash together.  So we use this
+    % bizarre value of 10001 as a signal to \aboveenvbreak to insert
+    % \parskip glue after all.  Section titles are handled this way also.
+    % 
+    \penalty 10001
+    \endgroup
+    \itemxneedsnegativevskipfalse
+  \else
+    % The item text fits into the space.  Start a paragraph, so that the
+    % following text (if any) will end up on the same line.
+    \noindent
+    % Do this with kerns and \unhbox so that if there is a footnote in
+    % the item text, it can migrate to the main vertical list and
+    % eventually be printed.
+    \nobreak\kern-\tableindent
+    \dimen0 = \itemmax  \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
+    \unhbox0
+    \nobreak\kern\dimen0
+    \endgroup
+    \itemxneedsnegativevskiptrue
+  \fi
+}
+
+\def\item{\errmessage{@item while not in a list environment}}
+\def\itemx{\errmessage{@itemx while not in a list environment}}
+
+% @table, @ftable, @vtable.
+\envdef\table{%
+  \let\itemindex\gobble
+  \tablecheck{table}%
+}
+\envdef\ftable{%
+  \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+  \tablecheck{ftable}%
+}
+\envdef\vtable{%
+  \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+  \tablecheck{vtable}%
+}
+\def\tablecheck#1{%
+  \ifnum \the\catcode`\^^M=\active
+    \endgroup
+    \errmessage{This command won't work in this context; perhaps the problem is
+      that we are \inenvironment\thisenv}%
+    \def\next{\doignore{#1}}%
+  \else
+    \let\next\tablex
+  \fi
+  \next
+}
+\def\tablex#1{%
+  \def\itemindicate{#1}%
+  \parsearg\tabley
+}
+\def\tabley#1{%
+  {%
+    \makevalueexpandable
+    \edef\temp{\noexpand\tablez #1\space\space\space}%
+    \expandafter
+  }\temp \endtablez
+}
+\def\tablez #1 #2 #3 #4\endtablez{%
+  \aboveenvbreak
+  \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
+  \ifnum 0#2>0 \tableindent=#2\mil \fi
+  \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
+  \itemmax=\tableindent
+  \advance \itemmax by -\itemmargin
+  \advance \leftskip by \tableindent
+  \exdentamount=\tableindent
+  \parindent = 0pt
+  \parskip = \smallskipamount
+  \ifdim \parskip=0pt \parskip=2pt \fi
+  \let\item = \internalBitem
+  \let\itemx = \internalBitemx
+}
+\def\Etable{\endgraf\afterenvbreak}
+\let\Eftable\Etable
+\let\Evtable\Etable
+\let\Eitemize\Etable
+\let\Eenumerate\Etable
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\envdef\itemize{\parsearg\doitemize}
+
+\def\doitemize#1{%
+  \aboveenvbreak
+  \itemmax=\itemindent
+  \advance\itemmax by -\itemmargin
+  \advance\leftskip by \itemindent
+  \exdentamount=\itemindent
+  \parindent=0pt
+  \parskip=\smallskipamount
+  \ifdim\parskip=0pt \parskip=2pt \fi
+  \def\itemcontents{#1}%
+  % @itemize with no arg is equivalent to @itemize @bullet.
+  \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+  \let\item=\itemizeitem
+}
+
+% Definition of @item while inside @itemize and @enumerate.
+%
+\def\itemizeitem{%
+  \advance\itemno by 1  % for enumerations
+  {\let\par=\endgraf \smallbreak}% reasonable place to break
+  {%
+   % If the document has an @itemize directly after a section title, a
+   % \nobreak will be last on the list, and \sectionheading will have
+   % done a \vskip-\parskip.  In that case, we don't want to zero
+   % parskip, or the item text will crash with the heading.  On the
+   % other hand, when there is normal text preceding the item (as there
+   % usually is), we do want to zero parskip, or there would be too much
+   % space.  In that case, we won't have a \nobreak before.  At least
+   % that's the theory.
+   \ifnum\lastpenalty<10000 \parskip=0in \fi
+   \noindent
+   \hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+   \vadjust{\penalty 1200}}% not good to break after first line of item.
+  \flushcr
+}
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list.  No
+% argument is the same as `1'.
+%
+\envparseargdef\enumerate{\enumeratey #1  \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+  % If we were given no argument, pretend we were given `1'.
+  \def\thearg{#1}%
+  \ifx\thearg\empty \def\thearg{1}\fi
+  %
+  % Detect if the argument is a single token.  If so, it might be a
+  % letter.  Otherwise, the only valid thing it can be is a number.
+  % (We will always have one token, because of the test we just made.
+  % This is a good thing, since \splitoff doesn't work given nothing at
+  % all -- the first parameter is undelimited.)
+  \expandafter\splitoff\thearg\endmark
+  \ifx\rest\empty
+    % Only one token in the argument.  It could still be anything.
+    % A ``lowercase letter'' is one whose \lccode is nonzero.
+    % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+    %   not equal to itself.
+    % Otherwise, we assume it's a number.
+    %
+    % We need the \relax at the end of the \ifnum lines to stop TeX from
+    % continuing to look for a <number>.
+    %
+    \ifnum\lccode\expandafter`\thearg=0\relax
+      \numericenumerate % a number (we hope)
+    \else
+      % It's a letter.
+      \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+        \lowercaseenumerate % lowercase letter
+      \else
+        \uppercaseenumerate % uppercase letter
+      \fi
+    \fi
+  \else
+    % Multiple tokens in the argument.  We hope it's a number.
+    \numericenumerate
+  \fi
+}
+
+% An @enumerate whose labels are integers.  The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+  \itemno = \thearg
+  \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+  \itemno = \expandafter`\thearg
+  \startenumeration{%
+    % Be sure we're not beyond the end of the alphabet.
+    \ifnum\itemno=0
+      \errmessage{No more lowercase letters in @enumerate; get a bigger
+                  alphabet}%
+    \fi
+    \char\lccode\itemno
+  }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+  \itemno = \expandafter`\thearg
+  \startenumeration{%
+    % Be sure we're not beyond the end of the alphabet.
+    \ifnum\itemno=0
+      \errmessage{No more uppercase letters in @enumerate; get a bigger
+                  alphabet}
+    \fi
+    \char\uccode\itemno
+  }%
+}
+
+% Call \doitemize, adding a period to the first argument and supplying the
+% common last two arguments.  Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+  \advance\itemno by -1
+  \doitemize{#1.}\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble.  Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+%   @multitable @columnfractions .25 .3 .45
+%   @item ...
+%
+%   Numbers following @columnfractions are the percent of the total
+%   current hsize to be used for each column. You may use as many
+%   columns as desired.
+
+
+% Or use a template:
+%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+%   @item ...
+%   using the widest term desired in each column.
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab at tab@tab will produce two empty columns.
+
+% @item, @tab do not need to be on their own lines, but it will not hurt
+% if they are.
+
+% Sample multitable:
+
+%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+%   @item first col stuff @tab second col stuff @tab third col
+%   @item
+%   first col stuff
+%   @tab
+%   second col stuff
+%   @tab
+%   third col
+%   @item first col stuff @tab second col stuff
+%   @tab Many paragraphs of text may be used in any column.
+%
+%         They will wrap at the width determined by the template.
+%   @item at tab@tab This will be in third column.
+%   @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+%                                                            to baseline.
+%   0pt means it depends on current normal line spacing.
+%
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+% Macros used to set up halign preamble:
+%
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+% #1 is the @columnfraction, usually a decimal number like .5, but might
+% be just 1.  We just use it, whatever it is.
+%
+\def\pickupwholefraction#1 {%
+  \global\advance\colcount by 1
+  \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}%
+  \setuptable
+}
+
+\newcount\colcount
+\def\setuptable#1{%
+  \def\firstarg{#1}%
+  \ifx\firstarg\xendsetuptable
+    \let\go = \relax
+  \else
+    \ifx\firstarg\xcolumnfractions
+      \global\setpercenttrue
+    \else
+      \ifsetpercent
+         \let\go\pickupwholefraction
+      \else
+         \global\advance\colcount by 1
+         \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
+                   % separator; typically that is always in the input, anyway.
+         \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+      \fi
+    \fi
+    \ifx\go\pickupwholefraction
+      % Put the argument back for the \pickupwholefraction call, so
+      % we'll always have a period there to be parsed.
+      \def\go{\pickupwholefraction#1}%
+    \else
+      \let\go = \setuptable
+    \fi%
+  \fi
+  \go
+}
+
+% multitable-only commands.
+%
+% @headitem starts a heading row, which we typeset in bold.
+% Assignments have to be global since we are inside the implicit group
+% of an alignment entry.  Note that \everycr resets \everytab.
+\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\everytab}%
+%
+% A \tab used to include \hskip1sp.  But then the space in a template
+% line is not enough.  That is bad.  So let's go back to just `&' until
+% we encounter the problem it was intended to solve again.
+%					--karl, nathan at acm.org, 20apr99.
+\def\tab{\checkenv\multitable &\the\everytab}%
+
+% @multitable ... @end multitable definitions:
+%
+\newtoks\everytab  % insert after every tab.
+%
+\envdef\multitable{%
+  \vskip\parskip
+  \startsavinginserts
+  %
+  % @item within a multitable starts a normal row.
+  % We use \def instead of \let so that if one of the multitable entries
+  % contains an @itemize, we don't choke on the \item (seen as \crcr aka
+  % \endtemplate) expanding \doitemize.
+  \def\item{\crcr}%
+  %
+  \tolerance=9500
+  \hbadness=9500
+  \setmultitablespacing
+  \parskip=\multitableparskip
+  \parindent=\multitableparindent
+  \overfullrule=0pt
+  \global\colcount=0
+  %
+  \everycr = {%
+    \noalign{%
+      \global\everytab={}%
+      \global\colcount=0 % Reset the column counter.
+      % Check for saved footnotes, etc.
+      \checkinserts
+      % Keeps underfull box messages off when table breaks over pages.
+      %\filbreak
+	% Maybe so, but it also creates really weird page breaks when the
+	% table breaks over pages. Wouldn't \vfil be better?  Wait until the
+	% problem manifests itself, so it can be fixed for real --karl.
+    }%
+  }%
+  %
+  \parsearg\domultitable
+}
+\def\domultitable#1{%
+  % To parse everything between @multitable and @item:
+  \setuptable#1 \endsetuptable
+  %
+  % This preamble sets up a generic column definition, which will
+  % be used as many times as user calls for columns.
+  % \vtop will set a single line and will also let text wrap and
+  % continue for many paragraphs if desired.
+  \halign\bgroup &%
+    \global\advance\colcount by 1
+    \multistrut
+    \vtop{%
+      % Use the current \colcount to find the correct column width:
+      \hsize=\expandafter\csname col\the\colcount\endcsname
+      %
+      % In order to keep entries from bumping into each other
+      % we will add a \leftskip of \multitablecolspace to all columns after
+      % the first one.
+      %
+      % If a template has been used, we will add \multitablecolspace
+      % to the width of each template entry.
+      %
+      % If the user has set preamble in terms of percent of \hsize we will
+      % use that dimension as the width of the column, and the \leftskip
+      % will keep entries from bumping into each other.  Table will start at
+      % left margin and final column will justify at right margin.
+      %
+      % Make sure we don't inherit \rightskip from the outer environment.
+      \rightskip=0pt
+      \ifnum\colcount=1
+	% The first column will be indented with the surrounding text.
+	\advance\hsize by\leftskip
+      \else
+	\ifsetpercent \else
+	  % If user has not set preamble in terms of percent of \hsize
+	  % we will advance \hsize by \multitablecolspace.
+	  \advance\hsize by \multitablecolspace
+	\fi
+       % In either case we will make \leftskip=\multitablecolspace:
+      \leftskip=\multitablecolspace
+      \fi
+      % Ignoring space at the beginning and end avoids an occasional spurious
+      % blank line, when TeX decides to break the line at the space before the
+      % box from the multistrut, so the strut ends up on a line by itself.
+      % For example:
+      % @multitable @columnfractions .11 .89
+      % @item @code{#}
+      % @tab Legal holiday which is valid in major parts of the whole country.
+      % Is automatically provided with highlighting sequences respectively
+      % marking characters.
+      \noindent\ignorespaces##\unskip\multistrut
+    }\cr
+}
+\def\Emultitable{%
+  \crcr
+  \egroup % end the \halign
+  \global\setpercentfalse
+}
+
+\def\setmultitablespacing{%
+  \def\multistrut{\strut}% just use the standard line spacing
+  %
+  % Compute \multitablelinespace (if not defined by user) for use in
+  % \multitableparskip calculation.  We used define \multistrut based on
+  % this, but (ironically) that caused the spacing to be off.
+  % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
+\ifdim\multitablelinespace=0pt
+\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
+\global\advance\multitablelinespace by-\ht0
+\fi
+%% Test to see if parskip is larger than space between lines of
+%% table. If not, do nothing.
+%%        If so, set to same dimension as multitablelinespace.
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                      %% than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                      %% than skip between lines in the table.
+\fi}
+
+
+\message{conditionals,}
+
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @ifnotxml always succeed.  They currently do nothing; we don't
+% attempt to check whether the conditionals are properly nested.  But we
+% have to remember that they are conditionals, so that @end doesn't
+% attempt to close an environment group.
+%
+\def\makecond#1{%
+  \expandafter\let\csname #1\endcsname = \relax
+  \expandafter\let\csname iscond.#1\endcsname = 1
+}
+\makecond{iftex}
+\makecond{ifnotdocbook}
+\makecond{ifnothtml}
+\makecond{ifnotinfo}
+\makecond{ifnotplaintext}
+\makecond{ifnotxml}
+
+% Ignore @ignore, @ifhtml, @ifinfo, and the like.
+%
+\def\direntry{\doignore{direntry}}
+\def\documentdescription{\doignore{documentdescription}}
+\def\docbook{\doignore{docbook}}
+\def\html{\doignore{html}}
+\def\ifdocbook{\doignore{ifdocbook}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifnottex{\doignore{ifnottex}}
+\def\ifplaintext{\doignore{ifplaintext}}
+\def\ifxml{\doignore{ifxml}}
+\def\ignore{\doignore{ignore}}
+\def\menu{\doignore{menu}}
+\def\xml{\doignore{xml}}
+
+% Ignore text until a line `@end #1', keeping track of nested conditionals.
+%
+% A count to remember the depth of nesting.
+\newcount\doignorecount
+
+\def\doignore#1{\begingroup
+  % Scan in ``verbatim'' mode:
+  \catcode`\@ = \other
+  \catcode`\{ = \other
+  \catcode`\} = \other
+  %
+  % Make sure that spaces turn into tokens that match what \doignoretext wants.
+  \spaceisspace
+  %
+  % Count number of #1's that we've seen.
+  \doignorecount = 0
+  %
+  % Swallow text until we reach the matching `@end #1'.
+  \dodoignore{#1}%
+}
+
+{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
+  \obeylines %
+  %
+  \gdef\dodoignore#1{%
+    % #1 contains the command name as a string, e.g., `ifinfo'.
+    %
+    % Define a command to find the next `@end #1', which must be on a line
+    % by itself.
+    \long\def\doignoretext##1^^M at end #1{\doignoretextyyy##1^^M@#1\_STOP_}%
+    % And this command to find another #1 command, at the beginning of a
+    % line.  (Otherwise, we would consider a line `@c @ifset', for
+    % example, to count as an @ifset for nesting.)
+    \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
+    %
+    % And now expand that command.
+    \obeylines %
+    \doignoretext ^^M%
+  }%
+}
+
+\def\doignoreyyy#1{%
+  \def\temp{#1}%
+  \ifx\temp\empty			% Nothing found.
+    \let\next\doignoretextzzz
+  \else					% Found a nested condition, ...
+    \advance\doignorecount by 1
+    \let\next\doignoretextyyy		% ..., look for another.
+    % If we're here, #1 ends with ^^M\ifinfo (for example).
+  \fi
+  \next #1% the token \_STOP_ is present just after this macro.
+}
+
+% We have to swallow the remaining "\_STOP_".
+%
+\def\doignoretextzzz#1{%
+  \ifnum\doignorecount = 0	% We have just found the outermost @end.
+    \let\next\enddoignore
+  \else				% Still inside a nested condition.
+    \advance\doignorecount by -1
+    \let\next\doignoretext      % Look for the next @end.
+  \fi
+  \next
+}
+
+% Finish off ignored text.
+\def\enddoignore{\endgroup\ignorespaces}
+
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+% We rely on the fact that \parsearg sets \catcode`\ =10.
+%
+\parseargdef\set{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+  {%
+    \makevalueexpandable
+    \def\temp{#2}%
+    \edef\next{\gdef\makecsname{SET#1}}%
+    \ifx\temp\empty
+      \next{}%
+    \else
+      \setzzz#2\endsetzzz
+    \fi
+  }%
+}
+% Remove the trailing space \setxxx inserted.
+\def\setzzz#1 \endsetzzz{\next{#1}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\parseargdef\clear{%
+  {%
+    \makevalueexpandable
+    \global\expandafter\let\csname SET#1\endcsname=\relax
+  }%
+}
+
+% @value{foo} gets the text saved in variable foo.
+\def\value{\begingroup\makevalueexpandable\valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
+{
+  \catcode`\- = \active \catcode`\_ = \active
+  %
+  \gdef\makevalueexpandable{%
+    \let\value = \expandablevalue
+    % We don't want these characters active, ...
+    \catcode`\-=\other \catcode`\_=\other
+    % ..., but we might end up with active ones in the argument if
+    % we're called from @code, as @code{@value{foo-bar_}}, though.
+    % So \let them to their normal equivalents.
+    \let-\realdash \let_\normalunderscore
+  }
+}
+
+% We have this subroutine so that we can handle at least some @value's
+% properly in indexes (we call \makevalueexpandable in \indexdummies).
+% The command has to be fully expandable (if the variable is set), since
+% the result winds up in the index file.  This means that if the
+% variable's value contains other Texinfo commands, it's almost certain
+% it will fail (although perhaps we could fix that with sufficient work
+% to do a one-level expansion on the result, instead of complete).
+%
+\def\expandablevalue#1{%
+  \expandafter\ifx\csname SET#1\endcsname\relax
+    {[No value for ``#1'']}%
+    \message{Variable `#1', used in @value, is not set.}%
+  \else
+    \csname SET#1\endcsname
+  \fi
+}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+% To get special treatment of `@end ifset,' call \makeond and the redefine.
+%
+\makecond{ifset}
+\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+\def\doifset#1#2{%
+  {%
+    \makevalueexpandable
+    \let\next=\empty
+    \expandafter\ifx\csname SET#2\endcsname\relax
+      #1% If not set, redefine \next.
+    \fi
+    \expandafter
+  }\next
+}
+\def\ifsetfail{\doignore{ifset}}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+% The `\else' inside the `\doifset' parameter is a trick to reuse the
+% above code: if the variable is not set, do nothing, if it is set,
+% then redefine \next to \ifclearfail.
+%
+\makecond{ifclear}
+\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+\def\ifclearfail{\doignore{ifclear}}
+
+% @dircategory CATEGORY  -- specify a category of the dir file
+% which this file should belong to.  Ignore this in TeX.
+\let\dircategory=\comment
+
+% @defininfoenclose.
+\let\definfoenclose=\comment
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within macros and \if's.
+\edef\newwrite{\makecsname{ptexnewwrite}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index.  The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+%
+\def\newindex#1{%
+  \iflinks
+    \expandafter\newwrite \csname#1indfile\endcsname
+    \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+  \fi
+  \expandafter\xdef\csname#1index\endcsname{%     % Define @#1index
+    \noexpand\doindex{#1}}
+}
+
+% @defindex foo  ==  \newindex{foo}
+%
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+%
+\def\defcodeindex{\parsearg\newcodeindex}
+%
+\def\newcodeindex#1{%
+  \iflinks
+    \expandafter\newwrite \csname#1indfile\endcsname
+    \openout \csname#1indfile\endcsname \jobname.#1
+  \fi
+  \expandafter\xdef\csname#1index\endcsname{%
+    \noexpand\docodeindex{#1}}%
+}
+
+
+% @synindex foo bar    makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+%
+% @syncodeindex foo bar   similar, but put all entries made for index foo
+% inside @code.
+%
+\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
+\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
+
+% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
+% #3 the target index (bar).
+\def\dosynindex#1#2#3{%
+  % Only do \closeout if we haven't already done it, else we'll end up
+  % closing the target index.
+  \expandafter \ifx\csname donesynindex#2\endcsname \undefined
+    % The \closeout helps reduce unnecessary open files; the limit on the
+    % Acorn RISC OS is a mere 16 files.
+    \expandafter\closeout\csname#2indfile\endcsname
+    \expandafter\let\csname\donesynindex#2\endcsname = 1
+  \fi
+  % redefine \fooindfile:
+  \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
+  \expandafter\let\csname#2indfile\endcsname=\temp
+  % redefine \fooindex:
+  \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+%  and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+% Take care of Texinfo commands that can appear in an index entry.
+% Since there are some commands we want to expand, and others we don't,
+% we have to laboriously prevent expansion for those that we don't.
+%
+\def\indexdummies{%
+  \escapechar = `\\     % use backslash in output files.
+  \def\@{@}% change to @@ when we switch to @ as escape char in index files.
+  \def\ {\realbackslash\space }%
+  % Need these in case \tex is in effect and \{ is a \delimiter again.
+  % But can't use \lbracecmd and \rbracecmd because texindex assumes
+  % braces and backslashes are used only as delimiters.
+  \let\{ = \mylbrace
+  \let\} = \myrbrace
+  %
+  % Do the redefinitions.
+  \commondummies
+}
+
+% For the aux and toc files, @ is the escape character.  So we want to
+% redefine everything using @ as the escape character (instead of
+% \realbackslash, still used for index files).  When everything uses @,
+% this will be simpler.
+%
+\def\atdummies{%
+  \def\@{@@}%
+  \def\ {@ }%
+  \let\{ = \lbraceatcmd
+  \let\} = \rbraceatcmd
+  %
+  % Do the redefinitions.
+  \commondummies
+}
+
+% Called from \indexdummies and \atdummies.
+%
+\def\commondummies{%
+  %
+  % \definedummyword defines \#1 as \string\#1\space, thus effectively
+  % preventing its expansion.  This is used only for control% words,
+  % not control letters, because the \space would be incorrect for
+  % control characters, but is needed to separate the control word
+  % from whatever follows.
+  %
+  % For control letters, we have \definedummyletter, which omits the
+  % space.
+  %
+  % These can be used both for control words that take an argument and
+  % those that do not.  If it is followed by {arg} in the input, then
+  % that will dutifully get written to the index (or wherever).
+  %
+  \def\definedummyword  ##1{\def##1{\string##1\space}}%
+  \def\definedummyletter##1{\def##1{\string##1}}%
+  \let\definedummyaccent\definedummyletter
+  %
+  \commondummiesnofonts
+  %
+  \definedummyletter\_%
+  %
+  % Non-English letters.
+  \definedummyword\AA
+  \definedummyword\AE
+  \definedummyword\L
+  \definedummyword\OE
+  \definedummyword\O
+  \definedummyword\aa
+  \definedummyword\ae
+  \definedummyword\l
+  \definedummyword\oe
+  \definedummyword\o
+  \definedummyword\ss
+  \definedummyword\exclamdown
+  \definedummyword\questiondown
+  \definedummyword\ordf
+  \definedummyword\ordm
+  %
+  % Although these internal commands shouldn't show up, sometimes they do.
+  \definedummyword\bf
+  \definedummyword\gtr
+  \definedummyword\hat
+  \definedummyword\less
+  \definedummyword\sf
+  \definedummyword\sl
+  \definedummyword\tclose
+  \definedummyword\tt
+  %
+  \definedummyword\LaTeX
+  \definedummyword\TeX
+  %
+  % Assorted special characters.
+  \definedummyword\bullet
+  \definedummyword\comma
+  \definedummyword\copyright
+  \definedummyword\registeredsymbol
+  \definedummyword\dots
+  \definedummyword\enddots
+  \definedummyword\equiv
+  \definedummyword\error
+  \definedummyword\euro
+  \definedummyword\expansion
+  \definedummyword\minus
+  \definedummyword\pounds
+  \definedummyword\point
+  \definedummyword\print
+  \definedummyword\result
+  %
+  % We want to disable all macros so that they are not expanded by \write.
+  \macrolist
+  %
+  \normalturnoffactive
+  %
+  % Handle some cases of @value -- where it does not contain any
+  % (non-fully-expandable) commands.
+  \makevalueexpandable
+}
+
+% \commondummiesnofonts: common to \commondummies and \indexnofonts.
+%
+% Better have this without active chars.
+{
+  \catcode`\~=\other
+  \gdef\commondummiesnofonts{%
+    % Control letters and accents.
+    \definedummyletter\!%
+    \definedummyaccent\"%
+    \definedummyaccent\'%
+    \definedummyletter\*%
+    \definedummyaccent\,%
+    \definedummyletter\.%
+    \definedummyletter\/%
+    \definedummyletter\:%
+    \definedummyaccent\=%
+    \definedummyletter\?%
+    \definedummyaccent\^%
+    \definedummyaccent\`%
+    \definedummyaccent\~%
+    \definedummyword\u
+    \definedummyword\v
+    \definedummyword\H
+    \definedummyword\dotaccent
+    \definedummyword\ringaccent
+    \definedummyword\tieaccent
+    \definedummyword\ubaraccent
+    \definedummyword\udotaccent
+    \definedummyword\dotless
+    %
+    % Texinfo font commands.
+    \definedummyword\b
+    \definedummyword\i
+    \definedummyword\r
+    \definedummyword\sc
+    \definedummyword\t
+    %
+    % Commands that take arguments.
+    \definedummyword\acronym
+    \definedummyword\cite
+    \definedummyword\code
+    \definedummyword\command
+    \definedummyword\dfn
+    \definedummyword\emph
+    \definedummyword\env
+    \definedummyword\file
+    \definedummyword\kbd
+    \definedummyword\key
+    \definedummyword\math
+    \definedummyword\option
+    \definedummyword\samp
+    \definedummyword\strong
+    \definedummyword\tie
+    \definedummyword\uref
+    \definedummyword\url
+    \definedummyword\var
+    \definedummyword\verb
+    \definedummyword\w
+  }
+}
+
+% \indexnofonts is used when outputting the strings to sort the index
+% by, and when constructing control sequence names.  It eliminates all
+% control sequences and just writes whatever the best ASCII sort string
+% would be for a given command (usually its argument).
+%
+\def\indexnofonts{%
+  % Accent commands should become @asis.
+  \def\definedummyaccent##1{\let##1\asis}%
+  % We can just ignore other control letters.
+  \def\definedummyletter##1{\let##1\empty}%
+  % Hopefully, all control words can become @asis.
+  \let\definedummyword\definedummyaccent
+  %
+  \commondummiesnofonts
+  %
+  % Don't no-op \tt, since it isn't a user-level command
+  % and is used in the definitions of the active chars like <, >, |, etc.
+  % Likewise with the other plain tex font commands.
+  %\let\tt=\asis
+  %
+  \def\ { }%
+  \def\@{@}%
+  % how to handle braces?
+  \def\_{\normalunderscore}%
+  %
+  % Non-English letters.
+  \def\AA{AA}%
+  \def\AE{AE}%
+  \def\L{L}%
+  \def\OE{OE}%
+  \def\O{O}%
+  \def\aa{aa}%
+  \def\ae{ae}%
+  \def\l{l}%
+  \def\oe{oe}%
+  \def\o{o}%
+  \def\ss{ss}%
+  \def\exclamdown{!}%
+  \def\questiondown{?}%
+  \def\ordf{a}%
+  \def\ordm{o}%
+  %
+  \def\LaTeX{LaTeX}%
+  \def\TeX{TeX}%
+  %
+  % Assorted special characters.
+  % (The following {} will end up in the sort string, but that's ok.)
+  \def\bullet{bullet}%
+  \def\comma{,}%
+  \def\copyright{copyright}%
+  \def\registeredsymbol{R}%
+  \def\dots{...}%
+  \def\enddots{...}%
+  \def\equiv{==}%
+  \def\error{error}%
+  \def\euro{euro}%
+  \def\expansion{==>}%
+  \def\minus{-}%
+  \def\pounds{pounds}%
+  \def\point{.}%
+  \def\print{-|}%
+  \def\result{=>}%
+  %
+  % We need to get rid of all macros, leaving only the arguments (if present).
+  % Of course this is not nearly correct, but it is the best we can do for now.
+  % makeinfo does not expand macros in the argument to @deffn, which ends up
+  % writing an index entry, and texindex isn't prepared for an index sort entry
+  % that starts with \.
+  % 
+  % Since macro invocations are followed by braces, we can just redefine them
+  % to take a single TeX argument.  The case of a macro invocation that
+  % goes to end-of-line is not handled.
+  % 
+  \macrolist
+}
+
+\let\indexbackslash=0  %overridden during \printindex.
+\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+
+% Most index entries go through here, but \dosubind is the general case.
+% #1 is the index name, #2 is the entry text.
+\def\doind#1#2{\dosubind{#1}{#2}{}}
+
+% Workhorse for all \fooindexes.
+% #1 is name of index, #2 is stuff to put there, #3 is subentry --
+% empty if called from \doind, as we usually are (the main exception
+% is with most defuns, which call us directly).
+%
+\def\dosubind#1#2#3{%
+  \iflinks
+  {%
+    % Store the main index entry text (including the third arg).
+    \toks0 = {#2}%
+    % If third arg is present, precede it with a space.
+    \def\thirdarg{#3}%
+    \ifx\thirdarg\empty \else
+      \toks0 = \expandafter{\the\toks0 \space #3}%
+    \fi
+    %
+    \edef\writeto{\csname#1indfile\endcsname}%
+    %
+    \ifvmode
+      \dosubindsanitize
+    \else
+      \dosubindwrite
+    \fi
+  }%
+  \fi
+}
+
+% Write the entry in \toks0 to the index file:
+%
+\def\dosubindwrite{%
+  % Put the index entry in the margin if desired.
+  \ifx\SETmarginindex\relax\else
+    \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
+  \fi
+  %
+  % Remember, we are within a group.
+  \indexdummies % Must do this here, since \bf, etc expand at this stage
+  \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now
+      % so it will be output as is; and it will print as backslash.
+  %
+  % Process the index entry with all font commands turned off, to
+  % get the string to sort by.
+  {\indexnofonts
+   \edef\temp{\the\toks0}% need full expansion
+   \xdef\indexsorttmp{\temp}%
+  }%
+  %
+  % Set up the complete index entry, with both the sort key and
+  % the original text, including any font commands.  We write
+  % three arguments to \entry to the .?? file (four in the
+  % subentry case), texindex reduces to two when writing the .??s
+  % sorted result.
+  \edef\temp{%
+    \write\writeto{%
+      \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
+  }%
+  \temp
+}
+
+% Take care of unwanted page breaks:
+%
+% If a skip is the last thing on the list now, preserve it
+% by backing up by \lastskip, doing the \write, then inserting
+% the skip again.  Otherwise, the whatsit generated by the
+% \write will make \lastskip zero.  The result is that sequences
+% like this:
+% @end defun
+% @tindex whatever
+% @defun ...
+% will have extra space inserted, because the \medbreak in the
+% start of the @defun won't see the skip inserted by the @end of
+% the previous defun.
+%
+% But don't do any of this if we're not in vertical mode.  We
+% don't want to do a \vskip and prematurely end a paragraph.
+%
+% Avoid page breaks due to these extra skips, too.
+%
+% But wait, there is a catch there:
+% We'll have to check whether \lastskip is zero skip.  \ifdim is not
+% sufficient for this purpose, as it ignores stretch and shrink parts
+% of the skip.  The only way seems to be to check the textual
+% representation of the skip.
+%
+% The following is almost like \def\zeroskipmacro{0.0pt} except that
+% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
+%
+\edef\zeroskipmacro{\expandafter\the\csname z at skip\endcsname}
+%
+% ..., ready, GO:
+%
+\def\dosubindsanitize{%
+  % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+  \skip0 = \lastskip
+  \edef\lastskipmacro{\the\lastskip}%
+  \count255 = \lastpenalty
+  %
+  % If \lastskip is nonzero, that means the last item was a
+  % skip.  And since a skip is discardable, that means this
+  % -\skip0 glue we're inserting is preceded by a
+  % non-discardable item, therefore it is not a potential
+  % breakpoint, therefore no \nobreak needed.
+  \ifx\lastskipmacro\zeroskipmacro
+  \else
+    \vskip-\skip0
+  \fi
+  %
+  \dosubindwrite
+  %
+  \ifx\lastskipmacro\zeroskipmacro
+    % If \lastskip was zero, perhaps the last item was a penalty, and
+    % perhaps it was >=10000, e.g., a \nobreak.  In that case, we want
+    % to re-insert the same penalty (values >10000 are used for various
+    % signals); since we just inserted a non-discardable item, any
+    % following glue (such as a \parskip) would be a breakpoint.  For example:
+    % 
+    %   @deffn deffn-whatever
+    %   @vindex index-whatever
+    %   Description.
+    % would allow a break between the index-whatever whatsit
+    % and the "Description." paragraph.
+    \ifnum\count255>9999 \penalty\count255 \fi
+  \else
+    % On the other hand, if we had a nonzero \lastskip,
+    % this make-up glue would be preceded by a non-discardable item
+    % (the whatsit from the \write), so we must insert a \nobreak.
+    \nobreak\vskip\skip0
+  \fi
+}
+
+% The index entry written in the file actually looks like
+%  \entry {sortstring}{page}{topic}
+% or
+%  \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+%  \initial {c}
+%     before the first topic whose initial is c
+%  \entry {topic}{pagelist}
+%     for a topic that is used without subtopics
+%  \primary {topic}
+%     for the beginning of a topic that is used with subtopics
+%  \secondary {subtopic}{pagelist}
+%     for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% @printindex causes a particular index (the ??s file) to get printed.
+% It does not print any chapter heading (usually an @unnumbered).
+%
+\parseargdef\printindex{\begingroup
+  \dobreak \chapheadingskip{10000}%
+  %
+  \smallfonts \rm
+  \tolerance = 9500
+  \everypar = {}% don't want the \kern\-parindent from indentation suppression.
+  %
+  % See if the index file exists and is nonempty.
+  % Change catcode of @ here so that if the index file contains
+  % \initial {@}
+  % as its first line, TeX doesn't complain about mismatched braces
+  % (because it thinks @} is a control sequence).
+  \catcode`\@ = 11
+  \openin 1 \jobname.#1s
+  \ifeof 1
+    % \enddoublecolumns gets confused if there is no text in the index,
+    % and it loses the chapter title and the aux file entries for the
+    % index.  The easiest way to prevent this problem is to make sure
+    % there is some text.
+    \putwordIndexNonexistent
+  \else
+    %
+    % If the index file exists but is empty, then \openin leaves \ifeof
+    % false.  We have to make TeX try to read something from the file, so
+    % it can discover if there is anything in it.
+    \read 1 to \temp
+    \ifeof 1
+      \putwordIndexIsEmpty
+    \else
+      % Index files are almost Texinfo source, but we use \ as the escape
+      % character.  It would be better to use @, but that's too big a change
+      % to make right now.
+      \def\indexbackslash{\backslashcurfont}%
+      \catcode`\\ = 0
+      \escapechar = `\\
+      \begindoublecolumns
+      \input \jobname.#1s
+      \enddoublecolumns
+    \fi
+  \fi
+  \closein 1
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+\def\initial#1{{%
+  % Some minor font changes for the special characters.
+  \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+  %
+  % Remove any glue we may have, we'll be inserting our own.
+  \removelastskip
+  %
+  % We like breaks before the index initials, so insert a bonus.
+  \nobreak
+  \vskip 0pt plus 3\baselineskip
+  \penalty 0
+  \vskip 0pt plus -3\baselineskip
+  %
+  % Typeset the initial.  Making this add up to a whole number of
+  % baselineskips increases the chance of the dots lining up from column
+  % to column.  It still won't often be perfect, because of the stretch
+  % we need before each entry, but it's better.
+  %
+  % No shrink because it confuses \balancecolumns.
+  \vskip 1.67\baselineskip plus .5\baselineskip
+  \leftline{\secbf #1}%
+  % Do our best not to break after the initial.
+  \nobreak
+  \vskip .33\baselineskip plus .1\baselineskip
+}}
+
+% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
+% then page number (#2) flushed to the right margin.  It is used for index
+% and table of contents entries.  The paragraph is indented by \leftskip.
+%
+% A straightforward implementation would start like this:
+%	\def\entry#1#2{...
+% But this frozes the catcodes in the argument, and can cause problems to
+% @code, which sets - active.  This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't really right.
+%
+% The right solution is to prevent \entry from swallowing the whole text.
+%                                 --kasal, 21nov03
+\def\entry{%
+  \begingroup
+    %
+    % Start a new paragraph if necessary, so our assignments below can't
+    % affect previous text.
+    \par
+    %
+    % Do not fill out the last line with white space.
+    \parfillskip = 0in
+    %
+    % No extra space above this paragraph.
+    \parskip = 0in
+    %
+    % Do not prefer a separate line ending with a hyphen to fewer lines.
+    \finalhyphendemerits = 0
+    %
+    % \hangindent is only relevant when the entry text and page number
+    % don't both fit on one line.  In that case, bob suggests starting the
+    % dots pretty far over on the line.  Unfortunately, a large
+    % indentation looks wrong when the entry text itself is broken across
+    % lines.  So we use a small indentation and put up with long leaders.
+    %
+    % \hangafter is reset to 1 (which is the value we want) at the start
+    % of each paragraph, so we need not do anything with that.
+    \hangindent = 2em
+    %
+    % When the entry text needs to be broken, just fill out the first line
+    % with blank space.
+    \rightskip = 0pt plus1fil
+    %
+    % A bit of stretch before each entry for the benefit of balancing
+    % columns.
+    \vskip 0pt plus1pt
+    %
+    % Swallow the left brace of the text (first parameter):
+    \afterassignment\doentry
+    \let\temp =
+}
+\def\doentry{%
+    \bgroup % Instead of the swallowed brace.
+      \noindent
+      \aftergroup\finishentry
+      % And now comes the text of the entry.
+}
+\def\finishentry#1{%
+    % #1 is the page number.
+    %
+    % The following is kludged to not output a line of dots in the index if
+    % there are no page numbers.  The next person who breaks this will be
+    % cursed by a Unix daemon.
+    \def\tempa{{\rm }}%
+    \def\tempb{#1}%
+    \edef\tempc{\tempa}%
+    \edef\tempd{\tempb}%
+    \ifx\tempc\tempd
+      \ %
+    \else
+      %
+      % If we must, put the page number on a line of its own, and fill out
+      % this line with blank space.  (The \hfil is overwhelmed with the
+      % fill leaders glue in \indexdotfill if the page number does fit.)
+      \hfil\penalty50
+      \null\nobreak\indexdotfill % Have leaders before the page number.
+      %
+      % The `\ ' here is removed by the implicit \unskip that TeX does as
+      % part of (the primitive) \par.  Without it, a spurious underfull
+      % \hbox ensues.
+      \ifpdf
+	\pdfgettoks#1.%
+	\ \the\toksA
+      \else
+	\ #1%
+      \fi
+    \fi
+    \par
+  \endgroup
+}
+
+% Like \dotfill except takes at least 1 em.
+\def\indexdotfill{\cleaders
+  \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+\def\secondary#1#2{{%
+  \parfillskip=0in
+  \parskip=0in
+  \hangindent=1in
+  \hangafter=1
+  \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
+  \ifpdf
+    \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
+  \else
+    #2
+  \fi
+  \par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+  % Grab any single-column material above us.
+  \output = {%
+    %
+    % Here is a possibility not foreseen in manmac: if we accumulate a
+    % whole lot of material, we might end up calling this \output
+    % routine twice in a row (see the doublecol-lose test, which is
+    % essentially a couple of indexes with @setchapternewpage off).  In
+    % that case we just ship out what is in \partialpage with the normal
+    % output routine.  Generally, \partialpage will be empty when this
+    % runs and this will be a no-op.  See the indexspread.tex test case.
+    \ifvoid\partialpage \else
+      \onepageout{\pagecontents\partialpage}%
+    \fi
+    %
+    \global\setbox\partialpage = \vbox{%
+      % Unvbox the main output page.
+      \unvbox\PAGE
+      \kern-\topskip \kern\baselineskip
+    }%
+  }%
+  \eject % run that output routine to set \partialpage
+  %
+  % Use the double-column output routine for subsequent pages.
+  \output = {\doublecolumnout}%
+  %
+  % Change the page size parameters.  We could do this once outside this
+  % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+  % format, but then we repeat the same computation.  Repeating a couple
+  % of assignments once per index is clearly meaningless for the
+  % execution time, so we may as well do it in one place.
+  %
+  % First we halve the line length, less a little for the gutter between
+  % the columns.  We compute the gutter based on the line length, so it
+  % changes automatically with the paper format.  The magic constant
+  % below is chosen so that the gutter has the same value (well, +-<1pt)
+  % as it did when we hard-coded it.
+  %
+  % We put the result in a separate register, \doublecolumhsize, so we
+  % can restore it in \pagesofar, after \hsize itself has (potentially)
+  % been clobbered.
+  %
+  \doublecolumnhsize = \hsize
+    \advance\doublecolumnhsize by -.04154\hsize
+    \divide\doublecolumnhsize by 2
+  \hsize = \doublecolumnhsize
+  %
+  % Double the \vsize as well.  (We don't need a separate register here,
+  % since nobody clobbers \vsize.)
+  \vsize = 2\vsize
+}
+
+% The double-column output routine for all double-column pages except
+% the last.
+%
+\def\doublecolumnout{%
+  \splittopskip=\topskip \splitmaxdepth=\maxdepth
+  % Get the available space for the double columns -- the normal
+  % (undoubled) page height minus any material left over from the
+  % previous page.
+  \dimen@ = \vsize
+  \divide\dimen@ by 2
+  \advance\dimen@ by -\ht\partialpage
+  %
+  % box0 will be the left-hand column, box2 the right.
+  \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+  \onepageout\pagesofar
+  \unvbox255
+  \penalty\outputpenalty
+}
+%
+% Re-output the contents of the output page -- any previous material,
+% followed by the two boxes we just split, in box0 and box2.
+\def\pagesofar{%
+  \unvbox\partialpage
+  %
+  \hsize = \doublecolumnhsize
+  \wd0=\hsize \wd2=\hsize
+  \hbox to\pagewidth{\box0\hfil\box2}%
+}
+%
+% All done with double columns.
+\def\enddoublecolumns{%
+  \output = {%
+    % Split the last of the double-column material.  Leave it on the
+    % current page, no automatic page break.
+    \balancecolumns
+    %
+    % If we end up splitting too much material for the current page,
+    % though, there will be another page break right after this \output
+    % invocation ends.  Having called \balancecolumns once, we do not
+    % want to call it again.  Therefore, reset \output to its normal
+    % definition right away.  (We hope \balancecolumns will never be
+    % called on to balance too much material, but if it is, this makes
+    % the output somewhat more palatable.)
+    \global\output = {\onepageout{\pagecontents\PAGE}}%
+  }%
+  \eject
+  \endgroup % started in \begindoublecolumns
+  %
+  % \pagegoal was set to the doubled \vsize above, since we restarted
+  % the current page.  We're now back to normal single-column
+  % typesetting, so reset \pagegoal to the normal \vsize (after the
+  % \endgroup where \vsize got restored).
+  \pagegoal = \vsize
+}
+%
+% Called at the end of the double column material.
+\def\balancecolumns{%
+  \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
+  \dimen@ = \ht0
+  \advance\dimen@ by \topskip
+  \advance\dimen@ by-\baselineskip
+  \divide\dimen@ by 2 % target to split to
+  %debug\message{final 2-column material height=\the\ht0, target=\the\dimen at .}%
+  \splittopskip = \topskip
+  % Loop until we get a decent breakpoint.
+  {%
+    \vbadness = 10000
+    \loop
+      \global\setbox3 = \copy0
+      \global\setbox1 = \vsplit3 to \dimen@
+    \ifdim\ht3>\dimen@
+      \global\advance\dimen@ by 1pt
+    \repeat
+  }%
+  %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
+  \setbox0=\vbox to\dimen@{\unvbox1}%
+  \setbox2=\vbox to\dimen@{\unvbox3}%
+  %
+  \pagesofar
+}
+\catcode`\@ = \other
+
+
+\message{sectioning,}
+% Chapters, sections, etc.
+
+% \unnumberedno is an oxymoron, of course.  But we count the unnumbered
+% sections so that we can refer to them unambiguously in the pdf
+% outlines by their "section number".  We avoid collisions with chapter
+% numbers by starting them at 10000.  (If a document ever has 10000
+% chapters, we're in trouble anyway, I'm sure.)
+\newcount\unnumberedno \unnumberedno = 10000
+\newcount\chapno
+\newcount\secno        \secno=0
+\newcount\subsecno     \subsecno=0
+\newcount\subsubsecno  \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount\appendixno  \appendixno = `\@
+%
+% \def\appendixletter{\char\the\appendixno}
+% We do the following ugly conditional instead of the above simple
+% construct for the sake of pdftex, which needs the actual
+% letter in the expansion, not just typeset.
+%
+\def\appendixletter{%
+  \ifnum\appendixno=`A A%
+  \else\ifnum\appendixno=`B B%
+  \else\ifnum\appendixno=`C C%
+  \else\ifnum\appendixno=`D D%
+  \else\ifnum\appendixno=`E E%
+  \else\ifnum\appendixno=`F F%
+  \else\ifnum\appendixno=`G G%
+  \else\ifnum\appendixno=`H H%
+  \else\ifnum\appendixno=`I I%
+  \else\ifnum\appendixno=`J J%
+  \else\ifnum\appendixno=`K K%
+  \else\ifnum\appendixno=`L L%
+  \else\ifnum\appendixno=`M M%
+  \else\ifnum\appendixno=`N N%
+  \else\ifnum\appendixno=`O O%
+  \else\ifnum\appendixno=`P P%
+  \else\ifnum\appendixno=`Q Q%
+  \else\ifnum\appendixno=`R R%
+  \else\ifnum\appendixno=`S S%
+  \else\ifnum\appendixno=`T T%
+  \else\ifnum\appendixno=`U U%
+  \else\ifnum\appendixno=`V V%
+  \else\ifnum\appendixno=`W W%
+  \else\ifnum\appendixno=`X X%
+  \else\ifnum\appendixno=`Y Y%
+  \else\ifnum\appendixno=`Z Z%
+  % The \the is necessary, despite appearances, because \appendixletter is
+  % expanded while writing the .toc file.  \char\appendixno is not
+  % expandable, thus it is written literally, thus all appendixes come out
+  % with the same letter (or @) in the toc without it.
+  \else\char\the\appendixno
+  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% Each @chapter defines this as the name of the chapter.
+% page headings and footings can use it.  @section does likewise.
+% However, they are not reliable, because we don't use marks.
+\def\thischapter{}
+\def\thissection{}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% we only have subsub.
+\chardef\maxseclevel = 3
+%
+% A numbered section within an unnumbered changes to unnumbered too.
+% To achive this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unmlevel = \maxseclevel
+%
+% Trace whether the current chapter is an appendix or not:
+% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
+\def\chapheadtype{N}
+
+% Choose a heading macro
+% #1 is heading type
+% #2 is heading level
+% #3 is text for heading
+\def\genhead#1#2#3{%
+  % Compute the abs. sec. level:
+  \absseclevel=#2
+  \advance\absseclevel by \secbase
+  % Make sure \absseclevel doesn't fall outside the range:
+  \ifnum \absseclevel < 0
+    \absseclevel = 0
+  \else
+    \ifnum \absseclevel > 3
+      \absseclevel = 3
+    \fi
+  \fi
+  % The heading type:
+  \def\headtype{#1}%
+  \if \headtype U%
+    \ifnum \absseclevel < \unmlevel
+      \chardef\unmlevel = \absseclevel
+    \fi
+  \else
+    % Check for appendix sections:
+    \ifnum \absseclevel = 0
+      \edef\chapheadtype{\headtype}%
+    \else
+      \if \headtype A\if \chapheadtype N%
+	\errmessage{@appendix... within a non-appendix chapter}%
+      \fi\fi
+    \fi
+    % Check for numbered within unnumbered:
+    \ifnum \absseclevel > \unmlevel
+      \def\headtype{U}%
+    \else
+      \chardef\unmlevel = 3
+    \fi
+  \fi
+  % Now print the heading:
+  \if \headtype U%
+    \ifcase\absseclevel
+	\unnumberedzzz{#3}%
+    \or \unnumberedseczzz{#3}%
+    \or \unnumberedsubseczzz{#3}%
+    \or \unnumberedsubsubseczzz{#3}%
+    \fi
+  \else
+    \if \headtype A%
+      \ifcase\absseclevel
+	  \appendixzzz{#3}%
+      \or \appendixsectionzzz{#3}%
+      \or \appendixsubseczzz{#3}%
+      \or \appendixsubsubseczzz{#3}%
+      \fi
+    \else
+      \ifcase\absseclevel
+	  \chapterzzz{#3}%
+      \or \seczzz{#3}%
+      \or \numberedsubseczzz{#3}%
+      \or \numberedsubsubseczzz{#3}%
+      \fi
+    \fi
+  \fi
+  \suppressfirstparagraphindent
+}
+
+% an interface:
+\def\numhead{\genhead N}
+\def\apphead{\genhead A}
+\def\unnmhead{\genhead U}
+
+% @chapter, @appendix, @unnumbered.  Increment top-level counter, reset
+% all lower-level sectioning counters to zero.
+%
+% Also set \chaplevelprefix, which we prepend to @float sequence numbers
+% (e.g., figures), q.v.  By default (before any chapter), that is empty.
+\let\chaplevelprefix = \empty
+%
+\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz#1{%
+  % section resetting is \global in case the chapter is in a group, such
+  % as an @include file.
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\chapno by 1
+  %
+  % Used for \float.
+  \gdef\chaplevelprefix{\the\chapno.}%
+  \resetallfloatnos
+  %
+  \message{\putwordChapter\space \the\chapno}%
+  %
+  % Write the actual heading.
+  \chapmacro{#1}{Ynumbered}{\the\chapno}%
+  %
+  % So @section and the like are numbered underneath this chapter.
+  \global\let\section = \numberedsec
+  \global\let\subsection = \numberedsubsec
+  \global\let\subsubsection = \numberedsubsubsec
+}
+
+\outer\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\def\appendixzzz#1{%
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\appendixno by 1
+  \gdef\chaplevelprefix{\appendixletter.}%
+  \resetallfloatnos
+  %
+  \def\appendixnum{\putwordAppendix\space \appendixletter}%
+  \message{\appendixnum}%
+  %
+  \chapmacro{#1}{Yappendix}{\appendixletter}%
+  %
+  \global\let\section = \appendixsec
+  \global\let\subsection = \appendixsubsec
+  \global\let\subsubsection = \appendixsubsubsec
+}
+
+\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz#1{%
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\unnumberedno by 1
+  %
+  % Since an unnumbered has no number, no prefix for figures.
+  \global\let\chaplevelprefix = \empty
+  \resetallfloatnos
+  %
+  % This used to be simply \message{#1}, but TeX fully expands the
+  % argument to \message.  Therefore, if #1 contained @-commands, TeX
+  % expanded them.  For example, in `@unnumbered The @cite{Book}', TeX
+  % expanded @cite (which turns out to cause errors because \cite is meant
+  % to be executed, not expanded).
+  %
+  % Anyway, we don't want the fully-expanded definition of @cite to appear
+  % as a result of the \message, we just want `@cite' itself.  We use
+  % \the<toks register> to achieve this: TeX expands \the<toks> only once,
+  % simply yielding the contents of <toks register>.  (We also do this for
+  % the toc entries.)
+  \toks0 = {#1}%
+  \message{(\the\toks0)}%
+  %
+  \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
+  %
+  \global\let\section = \unnumberedsec
+  \global\let\subsection = \unnumberedsubsec
+  \global\let\subsubsection = \unnumberedsubsubsec
+}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\parseargdef\centerchap{%
+  % Well, we could do the following in a group, but that would break
+  % an assumption that \chapmacro is called at the outermost level.
+  % Thus we are safer this way:		--kasal, 24feb04
+  \let\centerparametersmaybe = \centerparameters
+  \unnmhead0{#1}%
+  \let\centerparametersmaybe = \relax
+}
+
+% @top is like @unnumbered.
+\let\top\unnumbered
+
+% Sections.
+\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
+\def\seczzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
+}
+
+\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
+}
+\let\appendixsec\appendixsection
+
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
+}
+
+% Subsections.
+\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Yappendix}%
+                 {\appendixletter.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Ynothing}%
+                 {\the\unnumberedno.\the\secno.\the\subsecno}%
+}
+
+% Subsubsections.
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Ynumbered}%
+                 {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Yappendix}%
+                 {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Ynothing}%
+                 {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\let\section = \numberedsec
+\let\subsection = \numberedsubsec
+\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+% NOTE on use of \vbox for chapter headings, section headings, and such:
+%       1) We use \vbox rather than the earlier \line to permit
+%          overlong headings to fold.
+%       2) \hyphenpenalty is set to 10000 because hyphenation in a
+%          heading is obnoxious; this forbids it.
+%       3) Likewise, headings look best if no \parindent is used, and
+%          if justification is not attempted.  Hence \raggedright.
+
+
+\def\majorheading{%
+  {\advance\chapheadingskip by 10pt \chapbreak }%
+  \parsearg\chapheadingzzz
+}
+
+\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+\def\chapheadingzzz#1{%
+  {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                    \parindent=0pt\raggedright
+                    \rm #1\hfill}}%
+  \bigskip \par\penalty 200\relax
+  \suppressfirstparagraphindent
+}
+
+% @heading, @subheading, @subsubheading.
+\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+%%% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+%%% Define plain chapter starts, and page on/off switching for it
+% Parameter controlling skip before chapter headings (if needed)
+
+\newskip\chapheadingskip
+
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{%
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+% Chapter opening.
+%
+% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
+% Yappendix, Yomitfromtoc), #3 the chapter number.
+%
+% To test against our argument.
+\def\Ynothingkeyword{Ynothing}
+\def\Yomitfromtockeyword{Yomitfromtoc}
+\def\Yappendixkeyword{Yappendix}
+%
+\def\chapmacro#1#2#3{%
+  \pchapsepmacro
+  {%
+    \chapfonts \rm
+    %
+    % Have to define \thissection before calling \donoderef, because the
+    % xref code eventually uses it.  On the other hand, it has to be called
+    % after \pchapsepmacro, or the headline will change too soon.
+    \gdef\thissection{#1}%
+    \gdef\thischaptername{#1}%
+    %
+    % Only insert the separating space if we have a chapter/appendix
+    % number, and don't print the unnumbered ``number''.
+    \def\temptype{#2}%
+    \ifx\temptype\Ynothingkeyword
+      \setbox0 = \hbox{}%
+      \def\toctype{unnchap}%
+      \gdef\thischapter{#1}%
+    \else\ifx\temptype\Yomitfromtockeyword
+      \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+      \def\toctype{omit}%
+      \gdef\thischapter{}%
+    \else\ifx\temptype\Yappendixkeyword
+      \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+      \def\toctype{app}%
+      % We don't substitute the actual chapter name into \thischapter
+      % because we don't want its macros evaluated now.  And we don't
+      % use \thissection because that changes with each section.
+      %
+      \xdef\thischapter{\putwordAppendix{} \appendixletter:
+                        \noexpand\thischaptername}%
+    \else
+      \setbox0 = \hbox{#3\enspace}%
+      \def\toctype{numchap}%
+      \xdef\thischapter{\putwordChapter{} \the\chapno:
+                        \noexpand\thischaptername}%
+    \fi\fi\fi
+    %
+    % Write the toc entry for this chapter.  Must come before the
+    % \donoderef, because we include the current node name in the toc
+    % entry, and \donoderef resets it to empty.
+    \writetocentry{\toctype}{#1}{#3}%
+    %
+    % For pdftex, we have to write out the node definition (aka, make
+    % the pdfdest) after any page break, but before the actual text has
+    % been typeset.  If the destination for the pdf outline is after the
+    % text, then jumping from the outline may wind up with the text not
+    % being visible, for instance under high magnification.
+    \donoderef{#2}%
+    %
+    % Typeset the actual heading.
+    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+          \hangindent=\wd0 \centerparametersmaybe
+          \unhbox0 #1\par}%
+  }%
+  \nobreak\bigskip % no page break after a chapter title
+  \nobreak
+}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerparameters{%
+  \advance\rightskip by 3\rightskip
+  \leftskip = \rightskip
+  \parfillskip = 0pt
+}
+
+
+% I don't think this chapter style is supported any more, so I'm not
+% updating it with the new noderef stuff.  We'll see.  --karl, 11aug03.
+%
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+%
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt\raggedright
+                       \rm #1\hfill}}\bigskip \par\nobreak
+}
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+\def\centerchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt
+                       \hfill {\rm #1}\hfill}}\bigskip \par\nobreak
+}
+\def\CHAPFopen{%
+  \global\let\chapmacro=\chfopen
+  \global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles.  These macros combine the section number parts and
+% call the generic \sectionheading to do the printing.
+%
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
+
+% Subsection titles.
+\newskip\subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
+
+% Subsubsection titles.
+\def\subsubsecheadingskip{\subsecheadingskip}
+\def\subsubsecheadingbreak{\subsecheadingbreak}
+
+
+% Print any size, any type, section title.
+%
+% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
+% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
+% section number.
+%
+\def\sectionheading#1#2#3#4{%
+  {%
+    % Switch to the right set of fonts.
+    \csname #2fonts\endcsname \rm
+    %
+    % Insert space above the heading.
+    \csname #2headingbreak\endcsname
+    %
+    % Only insert the space after the number if we have a section number.
+    \def\sectionlevel{#2}%
+    \def\temptype{#3}%
+    %
+    \ifx\temptype\Ynothingkeyword
+      \setbox0 = \hbox{}%
+      \def\toctype{unn}%
+      \gdef\thissection{#1}%
+    \else\ifx\temptype\Yomitfromtockeyword
+      % for @headings -- no section number, don't include in toc,
+      % and don't redefine \thissection.
+      \setbox0 = \hbox{}%
+      \def\toctype{omit}%
+      \let\sectionlevel=\empty
+    \else\ifx\temptype\Yappendixkeyword
+      \setbox0 = \hbox{#4\enspace}%
+      \def\toctype{app}%
+      \gdef\thissection{#1}%
+    \else
+      \setbox0 = \hbox{#4\enspace}%
+      \def\toctype{num}%
+      \gdef\thissection{#1}%
+    \fi\fi\fi
+    %
+    % Write the toc entry (before \donoderef).  See comments in \chfplain.
+    \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+    %
+    % Write the node reference (= pdf destination for pdftex).
+    % Again, see comments in \chfplain.
+    \donoderef{#3}%
+    %
+    % Output the actual section heading.
+    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+          \hangindent=\wd0  % zero if no section number
+          \unhbox0 #1}%
+  }%
+  % Add extra space after the heading -- half of whatever came above it.
+  % Don't allow stretch, though.
+  \kern .5 \csname #2headingskip\endcsname
+  %
+  % Do not let the kern be a potential breakpoint, as it would be if it
+  % was followed by glue.
+  \nobreak
+  %
+  % We'll almost certainly start a paragraph next, so don't let that
+  % glue accumulate.  (Not a breakpoint because it's preceded by a
+  % discardable item.)
+  \vskip-\parskip
+  % 
+  % This is purely so the last item on the list is a known \penalty >
+  % 10000.  This is so \startdefun can avoid allowing breakpoints after
+  % section headings.  Otherwise, it would insert a valid breakpoint between:
+  % 
+  %   @section sec-whatever
+  %   @deffn def-whatever
+  \penalty 10001
+}
+
+
+\message{toc,}
+% Table of contents.
+\newwrite\tocfile
+
+% Write an entry to the toc file, opening it if necessary.
+% Called from @chapter, etc.
+%
+% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
+% We append the current node name (if any) and page number as additional
+% arguments for the \{chap,sec,...}entry macros which will eventually
+% read this.  The node name is used in the pdf outlines as the
+% destination to jump to.
+%
+% We open the .toc file for writing here instead of at @setfilename (or
+% any other fixed time) so that @contents can be anywhere in the document.
+% But if #1 is `omit', then we don't do anything.  This is used for the
+% table of contents chapter openings themselves.
+%
+\newif\iftocfileopened
+\def\omitkeyword{omit}%
+%
+\def\writetocentry#1#2#3{%
+  \edef\writetoctype{#1}%
+  \ifx\writetoctype\omitkeyword \else
+    \iftocfileopened\else
+      \immediate\openout\tocfile = \jobname.toc
+      \global\tocfileopenedtrue
+    \fi
+    %
+    \iflinks
+      {\atdummies
+       \edef\temp{%
+         \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}%
+       \temp
+      }
+    \fi
+  \fi
+  %
+  % Tell \shipout to create a pdf destination on each page, if we're
+  % writing pdf.  These are used in the table of contents.  We can't
+  % just write one on every page because the title pages are numbered
+  % 1 and 2 (the page numbers aren't printed), and so are the first
+  % two pages of the document.  Thus, we'd have two destinations named
+  % `1', and two named `2'.
+  \ifpdf \global\pdfmakepagedesttrue \fi
+}
+
+
+% These characters do not print properly in the Computer Modern roman
+% fonts, so we must take special care.  This is more or less redundant
+% with the Texinfo input format setup at the end of this file.
+% 
+\def\activecatcodes{%
+  \catcode`\"=\active
+  \catcode`\$=\active
+  \catcode`\<=\active
+  \catcode`\>=\active
+  \catcode`\\=\active
+  \catcode`\^=\active
+  \catcode`\_=\active
+  \catcode`\|=\active
+  \catcode`\~=\active
+}
+
+
+% Read the toc file, which is essentially Texinfo input.
+\def\readtocfile{%
+  \setupdatafile
+  \activecatcodes
+  \input \jobname.toc
+}
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\newcount\savepageno
+\newcount\lastnegativepageno \lastnegativepageno = -1
+
+% Prepare to read what we've written to \tocfile.
+%
+\def\startcontents#1{%
+  % If @setchapternewpage on, and @headings double, the contents should
+  % start on an odd page, unlike chapters.  Thus, we maintain
+  % \contentsalignmacro in parallel with \pagealignmacro.
+  % From: Torbjorn Granlund <tege at matematik.su.se>
+  \contentsalignmacro
+  \immediate\closeout\tocfile
+  %
+  % Don't need to put `Contents' or `Short Contents' in the headline.
+  % It is abundantly clear what they are.
+  \def\thischapter{}%
+  \chapmacro{#1}{Yomitfromtoc}{}%
+  %
+  \savepageno = \pageno
+  \begingroup                  % Set up to handle contents files properly.
+    \raggedbottom              % Worry more about breakpoints than the bottom.
+    \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+    %
+    % Roman numerals for page numbers.
+    \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
+}
+
+
+% Normal (long) toc.
+\def\contents{%
+  \startcontents{\putwordTOC}%
+    \openin 1 \jobname.toc
+    \ifeof 1 \else
+      \readtocfile
+    \fi
+    \vfill \eject
+    \contentsalignmacro % in case @setchapternewpage odd is in effect
+    \ifeof 1 \else
+      \pdfmakeoutlines
+    \fi
+    \closein 1
+  \endgroup
+  \lastnegativepageno = \pageno
+  \global\pageno = \savepageno
+}
+
+% And just the chapters.
+\def\summarycontents{%
+  \startcontents{\putwordShortTOC}%
+    %
+    \let\numchapentry = \shortchapentry
+    \let\appentry = \shortchapentry
+    \let\unnchapentry = \shortunnchapentry
+    % We want a true roman here for the page numbers.
+    \secfonts
+    \let\rm=\shortcontrm \let\bf=\shortcontbf
+    \let\sl=\shortcontsl \let\tt=\shortconttt
+    \rm
+    \hyphenpenalty = 10000
+    \advance\baselineskip by 1pt % Open it up a little.
+    \def\numsecentry##1##2##3##4{}
+    \let\appsecentry = \numsecentry
+    \let\unnsecentry = \numsecentry
+    \let\numsubsecentry = \numsecentry
+    \let\appsubsecentry = \numsecentry
+    \let\unnsubsecentry = \numsecentry
+    \let\numsubsubsecentry = \numsecentry
+    \let\appsubsubsecentry = \numsecentry
+    \let\unnsubsubsecentry = \numsecentry
+    \openin 1 \jobname.toc
+    \ifeof 1 \else
+      \readtocfile
+    \fi
+    \closein 1
+    \vfill \eject
+    \contentsalignmacro % in case @setchapternewpage odd is in effect
+  \endgroup
+  \lastnegativepageno = \pageno
+  \global\pageno = \savepageno
+}
+\let\shortcontents = \summarycontents
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
+%
+\def\shortchaplabel#1{%
+  % This space should be enough, since a single number is .5em, and the
+  % widest letter (M) is 1em, at least in the Computer Modern fonts.
+  % But use \hss just in case.
+  % (This space doesn't include the extra space that gets added after
+  % the label; that gets put in by \shortchapentry above.)
+  %
+  % We'd like to right-justify chapter numbers, but that looks strange
+  % with appendix letters.  And right-justifying numbers and
+  % left-justifying letters looks strange when there is less than 10
+  % chapters.  Have to read the whole toc once to know how many chapters
+  % there are before deciding ...
+  \hbox to 1em{#1\hss}%
+}
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Chapters, in the main contents.
+\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+%
+% Chapters, in the short toc.
+% See comments in \dochapentry re vbox and related settings.
+\def\shortchapentry#1#2#3#4{%
+  \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
+}
+
+% Appendices, in the main contents.
+% Need the word Appendix, and a fixed-size box.
+%
+\def\appendixbox#1{%
+  % We use M since it's probably the widest letter.
+  \setbox0 = \hbox{\putwordAppendix{} M}%
+  \hbox to \wd0{\putwordAppendix{} #1\hss}}
+%
+\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
+
+% Unnumbered chapters.
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
+
+% Sections.
+\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\let\appsecentry=\numsecentry
+\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+
+% Subsections.
+\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsecentry=\numsubsecentry
+\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+
+% And subsubsections.
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsubsecentry=\numsubsubsecentry
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+
+% This parameter controls the indentation of the various levels.
+% Same as \defaultparindent.
+\newdimen\tocindent \tocindent = 15pt
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+   \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+   \begingroup
+     \chapentryfonts
+     \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+   \endgroup
+   \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+  \secentryfonts \leftskip=\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+  \subsecentryfonts \leftskip=2\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+  \subsubsecentryfonts \leftskip=3\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+% We use the same \entry macro as for the index entries.
+\let\tocentry = \entry
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\def\subsecentryfonts{\textfonts}
+\def\subsubsecentryfonts{\textfonts}
+
+
+\message{environments,}
+% @foo ... @end foo.
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, it should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+   \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+   \advance\hsize by -2\dimen2 % Rules.
+   \vbox{%
+      \hrule height\dimen2
+      \hbox{\vrule width\dimen2 \kern3pt          % Space to left of text.
+         \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+         \kern3pt\vrule width\dimen2}% Space to right.
+      \hrule height\dimen2}
+    \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @tex ... @end tex    escapes into raw Tex temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain tex @ character.
+
+\envdef\tex{%
+  \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+  \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+  \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
+  \catcode `\%=14
+  \catcode `\+=\other
+  \catcode `\"=\other
+  \catcode `\|=\other
+  \catcode `\<=\other
+  \catcode `\>=\other
+  \escapechar=`\\
+  %
+  \let\b=\ptexb
+  \let\bullet=\ptexbullet
+  \let\c=\ptexc
+  \let\,=\ptexcomma
+  \let\.=\ptexdot
+  \let\dots=\ptexdots
+  \let\equiv=\ptexequiv
+  \let\!=\ptexexclam
+  \let\i=\ptexi
+  \let\indent=\ptexindent
+  \let\noindent=\ptexnoindent
+  \let\{=\ptexlbrace
+  \let\+=\tabalign
+  \let\}=\ptexrbrace
+  \let\/=\ptexslash
+  \let\*=\ptexstar
+  \let\t=\ptext
+  \let\frenchspacing=\plainfrenchspacing
+  %
+  \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+  \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+  \def\@{@}%
+}
+% There is no need to define \Etex.
+
+% Define @lisp ... @end lisp.
+% @lisp environment forms a group so it can rebind things,
+% including the definition of @end lisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments.  \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical.  We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip.
+%
+\def\aboveenvbreak{{%
+  % =10000 instead of <10000 because of a special case in \itemzzz and
+  % \sectionheading, q.v.
+  \ifnum \lastpenalty=10000 \else
+    \advance\envskipamount by \parskip
+    \endgraf
+    \ifdim\lastskip<\envskipamount
+      \removelastskip
+      % it's not a good place to break if the last penalty was \nobreak
+      % or better ...
+      \ifnum\lastpenalty<10000 \penalty-50 \fi
+      \vskip\envskipamount
+    \fi
+  \fi
+}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag.  If "set", @lisp etc don't narrow margins; it will
+% also clear it, so that its embedded environments do the narrowing again.
+\let\nonarrowing=\relax
+
+% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+% environment contents.
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+        \ctl\leaders\hrule height\circthick\hfil\ctr
+        \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+        \cbl\leaders\hrule height\circthick\hfil\cbr
+        \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\envdef\cartouche{%
+  \ifhmode\par\fi  % can't be in the midst of a paragraph.
+  \startsavinginserts
+  \lskip=\leftskip \rskip=\rightskip
+  \leftskip=0pt\rightskip=0pt % we want these *outside*.
+  \cartinner=\hsize \advance\cartinner by-\lskip
+  \advance\cartinner by-\rskip
+  \cartouter=\hsize
+  \advance\cartouter by 18.4pt	% allow for 3pt kerns on either
+				% side, and for 6pt waste from
+				% each corner char, and rule thickness
+  \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+  % Flag to tell @lisp, etc., not to narrow margin.
+  \let\nonarrowing = t%
+  \vbox\bgroup
+      \baselineskip=0pt\parskip=0pt\lineskip=0pt
+      \carttop
+      \hbox\bgroup
+	  \hskip\lskip
+	  \vrule\kern3pt
+	  \vbox\bgroup
+	      \kern3pt
+	      \hsize=\cartinner
+	      \baselineskip=\normbskip
+	      \lineskip=\normlskip
+	      \parskip=\normpskip
+	      \vskip -\parskip
+	      \comment % For explanation, see the end of \def\group.
+}
+\def\Ecartouche{%
+              \ifhmode\par\fi
+	      \kern3pt
+	  \egroup
+	  \kern3pt\vrule
+	  \hskip\rskip
+      \egroup
+      \cartbot
+  \egroup
+  \checkinserts
+}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\def\nonfillstart{%
+  \aboveenvbreak
+  \hfuzz = 12pt % Don't be fussy
+  \sepspaces % Make spaces be word-separators rather than space tokens.
+  \let\par = \lisppar % don't ignore blank lines
+  \obeylines % each line of input is a line of output
+  \parskip = 0pt
+  \parindent = 0pt
+  \emergencystretch = 0pt % don't try to avoid overfull boxes
+  \ifx\nonarrowing\relax
+    \advance \leftskip by \lispnarrowing
+    \exdentamount=\lispnarrowing
+  \else
+    \let\nonarrowing = \relax
+  \fi
+  \let\exdent=\nofillexdent
+}
+
+% If you want all examples etc. small: @set dispenvsize small.
+% If you want even small examples the full size: @set dispenvsize nosmall.
+% This affects the following displayed environments:
+%    @example, @display, @format, @lisp
+%
+\def\smallword{small}
+\def\nosmallword{nosmall}
+\let\SETdispenvsize\relax
+\def\setnormaldispenv{%
+  \ifx\SETdispenvsize\smallword
+    \smallexamplefonts \rm
+  \fi
+}
+\def\setsmalldispenv{%
+  \ifx\SETdispenvsize\nosmallword
+  \else
+    \smallexamplefonts \rm
+  \fi
+}
+
+% We often define two environments, @foo and @smallfoo.
+% Let's do it by one command:
+\def\makedispenv #1#2{
+  \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}
+  \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}
+  \expandafter\let\csname E#1\endcsname \afterenvbreak
+  \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
+}
+
+% Define two synonyms:
+\def\maketwodispenvs #1#2#3{
+  \makedispenv{#1}{#3}
+  \makedispenv{#2}{#3}
+}
+
+% @lisp: indented, narrowed, typewriter font; @example: same as @lisp.
+%
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel at xerox.
+%
+\maketwodispenvs {lisp}{example}{%
+  \nonfillstart
+  \tt
+  \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+  \gobble       % eat return
+}
+
+% @display/@smalldisplay: same as @lisp except keep current font.
+%
+\makedispenv {display}{%
+  \nonfillstart
+  \gobble
+}
+
+% @format/@smallformat: same as @display except don't narrow margins.
+%
+\makedispenv{format}{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \gobble
+}
+
+% @flushleft: same as @format, but doesn't obey \SETdispenvsize.
+\envdef\flushleft{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \gobble
+}
+\let\Eflushleft = \afterenvbreak
+
+% @flushright.
+%
+\envdef\flushright{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \advance\leftskip by 0pt plus 1fill
+  \gobble
+}
+\let\Eflushright = \afterenvbreak
+
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins.  We keep \parskip nonzero in general, since
+% we're doing normal filling.  So, when using \aboveenvbreak and
+% \afterenvbreak, temporarily make \parskip 0.
+%
+\envdef\quotation{%
+  {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+  \parindent=0pt
+  %
+  % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+  \ifx\nonarrowing\relax
+    \advance\leftskip by \lispnarrowing
+    \advance\rightskip by \lispnarrowing
+    \exdentamount = \lispnarrowing
+  \else
+    \let\nonarrowing = \relax
+  \fi
+  \parsearg\quotationlabel
+}
+
+% We have retained a nonzero parskip for the environment, since we're
+% doing normal filling.
+%
+\def\Equotation{%
+  \par
+  \ifx\quotationauthor\undefined\else
+    % indent a bit.
+    \leftline{\kern 2\leftskip \sl ---\quotationauthor}%
+  \fi
+  {\parskip=0pt \afterenvbreak}%
+}
+
+% If we're given an argument, typeset it in bold with a colon after.
+\def\quotationlabel#1{%
+  \def\temp{#1}%
+  \ifx\temp\empty \else
+    {\bf #1: }%
+  \fi
+}
+
+
+% LaTeX-like @verbatim... at end verbatim and @verb{<char>...<char>}
+% If we want to allow any <char> as delimiter,
+% we need the curly braces so that makeinfo sees the @verb command, eg:
+% `@verbx...x' would look like the '@verbx' command.  --janneke at gnu.org
+%
+% [Knuth]: Donald Ervin Knuth, 1996.  The TeXbook.
+%
+% [Knuth] p.344; only we need to do the other characters Texinfo sets
+% active too.  Otherwise, they get lost as the first character on a
+% verbatim line.
+\def\dospecials{%
+  \do\ \do\\\do\{\do\}\do\$\do\&%
+  \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
+  \do\<\do\>\do\|\do\@\do+\do\"%
+}
+%
+% [Knuth] p. 380
+\def\uncatcodespecials{%
+  \def\do##1{\catcode`##1=\other}\dospecials}
+%
+% [Knuth] pp. 380,381,391
+% Disable Spanish ligatures ?` and !` of \tt font
+\begingroup
+  \catcode`\`=\active\gdef`{\relax\lq}
+\endgroup
+%
+% Setup for the @verb command.
+%
+% Eight spaces for a tab
+\begingroup
+  \catcode`\^^I=\active
+  \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
+\endgroup
+%
+\def\setupverb{%
+  \tt  % easiest (and conventionally used) font for verbatim
+  \def\par{\leavevmode\endgraf}%
+  \catcode`\`=\active
+  \tabeightspaces
+  % Respect line breaks,
+  % print special symbols as themselves, and
+  % make each space count
+  % must do in this order:
+  \obeylines \uncatcodespecials \sepspaces
+}
+
+% Setup for the @verbatim environment
+%
+% Real tab expansion
+\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
+%
+\def\starttabbox{\setbox0=\hbox\bgroup}
+\begingroup
+  \catcode`\^^I=\active
+  \gdef\tabexpand{%
+    \catcode`\^^I=\active
+    \def^^I{\leavevmode\egroup
+      \dimen0=\wd0 % the width so far, or since the previous tab
+      \divide\dimen0 by\tabw
+      \multiply\dimen0 by\tabw % compute previous multiple of \tabw
+      \advance\dimen0 by\tabw  % advance to next multiple of \tabw
+      \wd0=\dimen0 \box0 \starttabbox
+    }%
+  }
+\endgroup
+\def\setupverbatim{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  % Easiest (and conventionally used) font for verbatim
+  \tt
+  \def\par{\leavevmode\egroup\box0\endgraf}%
+  \catcode`\`=\active
+  \tabexpand
+  % Respect line breaks,
+  % print special symbols as themselves, and
+  % make each space count
+  % must do in this order:
+  \obeylines \uncatcodespecials \sepspaces
+  \everypar{\starttabbox}%
+}
+
+% Do the @verb magic: verbatim text is quoted by unique
+% delimiter characters.  Before first delimiter expect a
+% right brace, after last delimiter expect closing brace:
+%
+%    \def\doverb'{'<char>#1<char>'}'{#1}
+%
+% [Knuth] p. 382; only eat outer {}
+\begingroup
+  \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
+  \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
+\endgroup
+%
+\def\verb{\begingroup\setupverb\doverb}
+%
+%
+% Do the @verbatim magic: define the macro \doverbatim so that
+% the (first) argument ends when '@end verbatim' is reached, ie:
+%
+%     \def\doverbatim#1 at end verbatim{#1}
+%
+% For Texinfo it's a lot easier than for LaTeX,
+% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
+% we need not redefine '\', '{' and '}'.
+%
+% Inspired by LaTeX's verbatim command set [latex.ltx]
+%
+\begingroup
+  \catcode`\ =\active
+  \obeylines %
+  % ignore everything up to the first ^^M, that's the newline at the end
+  % of the @verbatim input line itself.  Otherwise we get an extra blank
+  % line in the output.
+  \xdef\doverbatim#1^^M#2 at end verbatim{#2\noexpand\end\gobble verbatim}%
+  % We really want {...\end verbatim} in the body of the macro, but
+  % without the active space; thus we have to use \xdef and \gobble.
+\endgroup
+%
+\envdef\verbatim{%
+    \setupverbatim\doverbatim
+}
+\let\Everbatim = \afterenvbreak
+
+
+% @verbatiminclude FILE - insert text of file in verbatim environment.
+%
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
+%
+\def\doverbatiminclude#1{%
+  {%
+    \makevalueexpandable
+    \setupverbatim
+    \input #1
+    \afterenvbreak
+  }%
+}
+
+% @copying ... @end copying.
+% Save the text away for @insertcopying later.
+%
+% We save the uninterpreted tokens, rather than creating a box.
+% Saving the text in a box would be much easier, but then all the
+% typesetting commands (@smallbook, font changes, etc.) have to be done
+% beforehand -- and a) we want @copying to be done first in the source
+% file; b) letting users define the frontmatter in as flexible order as
+% possible is very desirable.
+%
+\def\copying{\checkenv{}\begingroup\scanargctxt\docopying}
+\def\docopying#1 at end copying{\endgroup\def\copyingtext{#1}}
+%
+\def\insertcopying{%
+  \begingroup
+    \parindent = 0pt  % paragraph indentation looks wrong on title page
+    \scanexp\copyingtext
+  \endgroup
+}
+
+\message{defuns,}
+% @defun etc.
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+
+% Start the processing of @deffn:
+\def\startdefun{%
+  \ifnum\lastpenalty<10000
+    \medbreak
+  \else
+    % If there are two @def commands in a row, we'll have a \nobreak,
+    % which is there to keep the function description together with its
+    % header.  But if there's nothing but headers, we need to allow a
+    % break somewhere.  Check specifically for penalty 10002, inserted
+    % by \defargscommonending, instead of 10000, since the sectioning
+    % commands also insert a nobreak penalty, and we don't want to allow
+    % a break between a section heading and a defun.
+    % 
+    \ifnum\lastpenalty=10002 \penalty2000 \fi
+    %
+    % Similarly, after a section heading, do not allow a break.
+    % But do insert the glue.
+    \medskip  % preceded by discardable penalty, so not a breakpoint
+  \fi
+  %
+  \parindent=0in
+  \advance\leftskip by \defbodyindent
+  \exdentamount=\defbodyindent
+}
+
+\def\dodefunx#1{%
+  % First, check whether we are in the right environment:
+  \checkenv#1%
+  %
+  % As above, allow line break if we have multiple x headers in a row.
+  % It's not a great place, though.
+  \ifnum\lastpenalty=10002 \penalty3000 \fi
+  %
+  % And now, it's time to reuse the body of the original defun:
+  \expandafter\gobbledefun#1%
+}
+\def\gobbledefun#1\startdefun{}
+
+% \printdefunline \deffnheader{text}
+%
+\def\printdefunline#1#2{%
+  \begingroup
+    % call \deffnheader:
+    #1#2 \endheader
+    % common ending:
+    \interlinepenalty = 10000
+    \advance\rightskip by 0pt plus 1fil
+    \endgraf
+    \nobreak\vskip -\parskip
+    \penalty 10002  % signal to \startdefun and \dodefunx
+    % Some of the @defun-type tags do not enable magic parentheses,
+    % rendering the following check redundant.  But we don't optimize.
+    \checkparencounts
+  \endgroup
+}
+
+\def\Edefun{\endgraf\medbreak}
+
+% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
+% the only thing remainnig is to define \deffnheader.
+%
+\def\makedefun#1{%
+  \expandafter\let\csname E#1\endcsname = \Edefun
+  \edef\temp{\noexpand\domakedefun
+    \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
+  \temp
+}
+
+% \domakedefun \deffn \deffnx \deffnheader
+%
+% Define \deffn and \deffnx, without parameters.
+% \deffnheader has to be defined explicitly.
+%
+\def\domakedefun#1#2#3{%
+  \envdef#1{%
+    \startdefun
+    \parseargusing\activeparens{\printdefunline#3}%
+  }%
+  \def#2{\dodefunx#1}%
+  \def#3%
+}
+
+%%% Untyped functions:
+
+% @deffn category name args
+\makedefun{deffn}{\deffngeneral{}}
+
+% @deffn category class name args
+\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
+
+% \defopon {category on}class name args
+\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deffngeneral {subind}category name args
+%
+\def\deffngeneral#1#2 #3 #4\endheader{%
+  % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}.
+  \dosubind{fn}{\code{#3}}{#1}%
+  \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
+}
+
+%%% Typed functions:
+
+% @deftypefn category type name args
+\makedefun{deftypefn}{\deftypefngeneral{}}
+
+% @deftypeop category class type name args
+\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
+
+% \deftypeopon {category on}class type name args
+\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypefngeneral {subind}category type name args
+%
+\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
+  \dosubind{fn}{\code{#4}}{#1}%
+  \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Typed variables:
+
+% @deftypevr category type var args
+\makedefun{deftypevr}{\deftypecvgeneral{}}
+
+% @deftypecv category class type var args
+\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
+
+% \deftypecvof {category of}class type var args
+\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypecvgeneral {subind}category type var args
+%
+\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
+  \dosubind{vr}{\code{#4}}{#1}%
+  \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Untyped variables:
+
+% @defvr category var args
+\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
+
+% @defcv category class var args
+\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
+
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+
+%%% Type:
+% @deftp category name args
+\makedefun{deftp}#1 #2 #3\endheader{%
+  \doind{tp}{\code{#2}}%
+  \defname{#1}{}{#2}\defunargs{#3\unskip}%
+}
+
+% Remaining @defun-like shortcuts:
+\makedefun{defun}{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac}{\deffnheader{\putwordDefmac} }
+\makedefun{defspec}{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar}{\defvrheader{\putwordDefvar} }
+\makedefun{defopt}{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod}{\defopon\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
+\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
+
+% \defname, which formats the name of the @def (not the args).
+% #1 is the category, such as "Function".
+% #2 is the return type, if any.
+% #3 is the function name.
+%
+% We are followed by (but not passed) the arguments, if any.
+%
+\def\defname#1#2#3{%
+  % Get the values of \leftskip and \rightskip as they were outside the @def...
+  \advance\leftskip by -\defbodyindent
+  %
+  % How we'll format the type name.  Putting it in brackets helps
+  % distinguish it from the body text that may end up on the next line
+  % just below it.
+  \def\temp{#1}%
+  \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
+  %
+  % Figure out line sizes for the paragraph shape.
+  % The first line needs space for \box0; but if \rightskip is nonzero,
+  % we need only space for the part of \box0 which exceeds it:
+  \dimen0=\hsize  \advance\dimen0 by -\wd0  \advance\dimen0 by \rightskip
+  % The continuations:
+  \dimen2=\hsize  \advance\dimen2 by -\defargsindent
+  % (plain.tex says that \dimen1 should be used only as global.)
+  \parshape 2 0in \dimen0 \defargsindent \dimen2
+  %
+  % Put the type name to the right margin.
+  \noindent
+  \hbox to 0pt{%
+    \hfil\box0 \kern-\hsize
+    % \hsize has to be shortened this way:
+    \kern\leftskip
+    % Intentionally do not respect \rightskip, since we need the space.
+  }%
+  %
+  % Allow all lines to be underfull without complaint:
+  \tolerance=10000 \hbadness=10000
+  \exdentamount=\defbodyindent
+  {%
+    % defun fonts. We use typewriter by default (used to be bold) because:
+    % . we're printing identifiers, they should be in tt in principle.
+    % . in languages with many accents, such as Czech or French, it's
+    %   common to leave accents off identifiers.  The result looks ok in
+    %   tt, but exceedingly strange in rm.
+    % . we don't want -- and --- to be treated as ligatures.
+    % . this still does not fix the ?` and !` ligatures, but so far no
+    %   one has made identifiers using them :).
+    \df \tt
+    \def\temp{#2}% return value type
+    \ifx\temp\empty\else \tclose{\temp} \fi
+    #3% output function name
+  }%
+  {\rm\enskip}% hskip 0.5 em of \tenrm
+  %
+  \boldbrax
+  % arguments will be output next, if any.
+}
+
+% Print arguments in slanted roman (not ttsl), inconsistently with using
+% tt for the name.  This is because literal text is sometimes needed in
+% the argument list (groff manual), and ttsl and tt are not very
+% distinguishable.  Prevent hyphenation at `-' chars.
+%
+\def\defunargs#1{%
+  % use sl by default (not ttsl),
+  % tt for the names.
+  \df \sl \hyphenchar\font=0
+  %
+  % On the other hand, if an argument has two dashes (for instance), we
+  % want a way to get ttsl.  Let's try @var for that.
+  \let\var=\ttslanted
+  #1%
+  \sl\hyphenchar\font=45
+}
+
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+  \catcode`\(=\active \catcode`\)=\active
+  \catcode`\[=\active \catcode`\]=\active
+  \catcode`\&=\active
+}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+% Be sure that we always have a definition for `(', etc.  For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+  \activeparens
+  \global\let(=\lparen \global\let)=\rparen
+  \global\let[=\lbrack \global\let]=\rbrack
+  \global\let& = \&
+
+  \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+  \gdef\magicamp{\let&=\amprm}
+}
+
+\newcount\parencount
+
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\&#1 }}
+
+\def\parenfont{%
+  \ifampseen
+    % At the first level, print parens in roman,
+    % otherwise use the default font.
+    \ifnum \parencount=1 \rm \fi
+  \else
+    % The \sf parens (in \boldbrax) actually are a little bolder than
+    % the contained text.  This is especially needed for [ and ] .
+    \sf
+  \fi
+}
+\def\infirstlevel#1{%
+  \ifampseen
+    \ifnum\parencount=1
+      #1%
+    \fi
+  \fi
+}
+\def\bfafterword#1 {#1 \bf}
+
+\def\opnr{%
+  \global\advance\parencount by 1
+  {\parenfont(}%
+  \infirstlevel \bfafterword
+}
+\def\clnr{%
+  {\parenfont)}%
+  \infirstlevel \sl
+  \global\advance\parencount by -1
+}
+
+\newcount\brackcount
+\def\lbrb{%
+  \global\advance\brackcount by 1
+  {\bf[}%
+}
+\def\rbrb{%
+  {\bf]}%
+  \global\advance\brackcount by -1
+}
+
+\def\checkparencounts{%
+  \ifnum\parencount=0 \else \badparencount \fi
+  \ifnum\brackcount=0 \else \badbrackcount \fi
+}
+\def\badparencount{%
+  \errmessage{Unbalanced parentheses in @def}%
+  \global\parencount=0
+}
+\def\badbrackcount{%
+  \errmessage{Unbalanced square braces in @def}%
+  \global\brackcount=0
+}
+
+
+\message{macros,}
+% @macro.
+
+% To do this right we need a feature of e-TeX, \scantokens,
+% which we arrange to emulate with a temporary file in ordinary TeX.
+\ifx\eTeXversion\undefined
+  \newwrite\macscribble
+  \def\scantokens#1{%
+    \toks0={#1}%
+    \immediate\openout\macscribble=\jobname.tmp
+    \immediate\write\macscribble{\the\toks0}%
+    \immediate\closeout\macscribble
+    \input \jobname.tmp
+  }
+\fi
+
+\def\scanmacro#1{%
+  \begingroup
+    \newlinechar`\^^M
+    \let\xeatspaces\eatspaces
+    % Undo catcode changes of \startcontents and \doprintindex
+    % When called from @insertcopying or (short)caption, we need active
+    % backslash to get it printed correctly.  Previously, we had
+    % \catcode`\\=\other instead.  We'll see whether a problem appears
+    % with macro expansion.				--kasal, 19aug04
+    \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+    % ... and \example
+    \spaceisspace
+    %
+    % Append \endinput to make sure that TeX does not see the ending newline.
+    %
+    % I've verified that it is necessary both for e-TeX and for ordinary TeX
+    %							--kasal, 29nov03
+    \scantokens{#1\endinput}%
+  \endgroup
+}
+
+\def\scanexp#1{%
+  \edef\temp{\noexpand\scanmacro{#1}}%
+  \temp
+}
+
+\newcount\paramno   % Count of parameters
+\newtoks\macname    % Macro name
+\newif\ifrecursive  % Is it recursive?
+
+% List of all defined macros in the form
+%    \definedummyword\macro1\definedummyword\macro2...
+% Currently is also contains all @aliases; the list can be split
+% if there is a need.
+\def\macrolist{}
+
+% Add the macro to \macrolist
+\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname}
+\def\addtomacrolistxxx#1{%
+     \toks0 = \expandafter{\macrolist\definedummyword#1}%
+     \xdef\macrolist{\the\toks0}%
+}
+
+% Utility routines.
+% This does \let #1 = #2, with \csnames; that is,
+%   \let \csname#1\endcsname = \csname#2\endcsname
+% (except of course we have to play expansion games).
+% 
+\def\cslet#1#2{%
+  \expandafter\let
+  \csname#1\expandafter\endcsname
+  \csname#2\endcsname
+}
+
+% Trim leading and trailing spaces off a string.
+% Concepts from aro-bend problem 15 (see CTAN).
+{\catcode`\@=11
+\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
+\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
+\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
+\def\unbrace#1{#1}
+\unbrace{\gdef\trim@@@ #1 } #2@{#1}
+}
+
+% Trim a single trailing ^^M off a string.
+{\catcode`\^^M=\other \catcode`\Q=3%
+\gdef\eatcr #1{\eatcra #1Q^^MQ}%
+\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
+\gdef\eatcrb#1Q#2Q{#1}%
+}
+
+% Macro bodies are absorbed as an argument in a context where
+% all characters are catcode 10, 11 or 12, except \ which is active
+% (as in normal texinfo). It is necessary to change the definition of \.
+
+% It's necessary to have hard CRs when the macro is executed. This is
+% done by  making ^^M (\endlinechar) catcode 12 when reading the macro
+% body, and then making it the \newlinechar in \scanmacro.
+
+\def\scanctxt{%
+  \catcode`\"=\other
+  \catcode`\+=\other
+  \catcode`\<=\other
+  \catcode`\>=\other
+  \catcode`\@=\other
+  \catcode`\^=\other
+  \catcode`\_=\other
+  \catcode`\|=\other
+  \catcode`\~=\other
+}
+
+\def\scanargctxt{%
+  \scanctxt
+  \catcode`\\=\other
+  \catcode`\^^M=\other
+}
+
+\def\macrobodyctxt{%
+  \scanctxt
+  \catcode`\{=\other
+  \catcode`\}=\other
+  \catcode`\^^M=\other
+  \usembodybackslash
+}
+
+\def\macroargctxt{%
+  \scanctxt
+  \catcode`\\=\other
+}
+
+% \mbodybackslash is the definition of \ in @macro bodies.
+% It maps \foo\ => \csname macarg.foo\endcsname => #N
+% where N is the macro parameter number.
+% We define \csname macarg.\endcsname to be \realbackslash, so
+% \\ in macro replacement text gets you a backslash.
+
+{\catcode`@=0 @catcode`@\=@active
+ @gdef at usembodybackslash{@let\=@mbodybackslash}
+ @gdef at mbodybackslash#1\{@csname macarg.#1 at endcsname}
+}
+\expandafter\def\csname macarg.\endcsname{\realbackslash}
+
+\def\macro{\recursivefalse\parsearg\macroxxx}
+\def\rmacro{\recursivetrue\parsearg\macroxxx}
+
+\def\macroxxx#1{%
+  \getargs{#1}%           now \macname is the macname and \argl the arglist
+  \ifx\argl\empty       % no arguments
+     \paramno=0%
+  \else
+     \expandafter\parsemargdef \argl;%
+  \fi
+  \if1\csname ismacro.\the\macname\endcsname
+     \message{Warning: redefining \the\macname}%
+  \else
+     \expandafter\ifx\csname \the\macname\endcsname \relax
+     \else \errmessage{Macro name \the\macname\space already defined}\fi
+     \global\cslet{macsave.\the\macname}{\the\macname}%
+     \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
+     \addtomacrolist{\the\macname}%
+  \fi
+  \begingroup \macrobodyctxt
+  \ifrecursive \expandafter\parsermacbody
+  \else \expandafter\parsemacbody
+  \fi}
+
+\parseargdef\unmacro{%
+  \if1\csname ismacro.#1\endcsname
+    \global\cslet{#1}{macsave.#1}%
+    \global\expandafter\let \csname ismacro.#1\endcsname=0%
+    % Remove the macro name from \macrolist:
+    \begingroup
+      \expandafter\let\csname#1\endcsname \relax
+      \let\definedummyword\unmacrodo
+      \xdef\macrolist{\macrolist}%
+    \endgroup
+  \else
+    \errmessage{Macro #1 not defined}%
+  \fi
+}
+
+% Called by \do from \dounmacro on each macro.  The idea is to omit any
+% macro definitions that have been changed to \relax.
+%
+\def\unmacrodo#1{%
+  \ifx #1\relax
+    % remove this
+  \else
+    \noexpand\definedummyword \noexpand#1%
+  \fi
+}
+
+% This makes use of the obscure feature that if the last token of a
+% <parameter list> is #, then the preceding argument is delimited by
+% an opening brace, and that opening brace is not consumed.
+\def\getargs#1{\getargsxxx#1{}}
+\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
+\def\getmacname #1 #2\relax{\macname={#1}}
+\def\getmacargs#1{\def\argl{#1}}
+
+% Parse the optional {params} list.  Set up \paramno and \paramlist
+% so \defmacro knows what to do.  Define \macarg.blah for each blah
+% in the params list, to be ##N where N is the position in that list.
+% That gets used by \mbodybackslash (above).
+
+% We need to get `macro parameter char #' into several definitions.
+% The technique used is stolen from LaTeX:  let \hash be something
+% unexpandable, insert that wherever you need a #, and then redefine
+% it to # just before using the token list produced.
+%
+% The same technique is used to protect \eatspaces till just before
+% the macro is used.
+
+\def\parsemargdef#1;{\paramno=0\def\paramlist{}%
+        \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,}
+\def\parsemargdefxxx#1,{%
+  \if#1;\let\next=\relax
+  \else \let\next=\parsemargdefxxx
+    \advance\paramno by 1%
+    \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
+        {\xeatspaces{\hash\the\paramno}}%
+    \edef\paramlist{\paramlist\hash\the\paramno,}%
+  \fi\next}
+
+% These two commands read recursive and nonrecursive macro bodies.
+% (They're different since rec and nonrec macros end differently.)
+
+\long\def\parsemacbody#1 at end macro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\long\def\parsermacbody#1 at end rmacro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+
+% This defines the macro itself. There are six cases: recursive and
+% nonrecursive macros of zero, one, and many arguments.
+% Much magic with \expandafter here.
+% \xdef is used so that macro definitions will survive the file
+% they're defined in; @include reads the file inside a group.
+\def\defmacro{%
+  \let\hash=##% convert placeholders to macro parameter chars
+  \ifrecursive
+    \ifcase\paramno
+    % 0
+      \expandafter\xdef\csname\the\macname\endcsname{%
+        \noexpand\scanmacro{\temp}}%
+    \or % 1
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\braceorline
+         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+         \egroup\noexpand\scanmacro{\temp}}%
+    \else % many
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\csname\the\macname xx\endcsname}%
+      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+      \expandafter\expandafter
+      \expandafter\xdef
+      \expandafter\expandafter
+        \csname\the\macname xxx\endcsname
+          \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+    \fi
+  \else
+    \ifcase\paramno
+    % 0
+      \expandafter\xdef\csname\the\macname\endcsname{%
+        \noexpand\norecurse{\the\macname}%
+        \noexpand\scanmacro{\temp}\egroup}%
+    \or % 1
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\braceorline
+         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+        \egroup
+        \noexpand\norecurse{\the\macname}%
+        \noexpand\scanmacro{\temp}\egroup}%
+    \else % many
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \expandafter\noexpand\csname\the\macname xx\endcsname}%
+      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+      \expandafter\expandafter
+      \expandafter\xdef
+      \expandafter\expandafter
+      \csname\the\macname xxx\endcsname
+      \paramlist{%
+          \egroup
+          \noexpand\norecurse{\the\macname}%
+          \noexpand\scanmacro{\temp}\egroup}%
+    \fi
+  \fi}
+
+\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+
+% \braceorline decides whether the next nonwhitespace character is a
+% {.  If so it reads up to the closing }, if not, it reads the whole
+% line.  Whatever was read is then fed to the next control sequence
+% as an argument (by \parsebrace or \parsearg)
+\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorlinexxx{%
+  \ifx\nchar\bgroup\else
+    \expandafter\parsearg
+  \fi \next}
+
+
+% @alias.
+% We need some trickery to remove the optional spaces around the equal
+% sign.  Just make them active and then expand them all to nothing.
+\def\alias{\parseargusing\obeyspaces\aliasxxx}
+\def\aliasxxx #1{\aliasyyy#1\relax}
+\def\aliasyyy #1=#2\relax{%
+  {%
+    \expandafter\let\obeyedspace=\empty
+    \addtomacrolist{#1}%
+    \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
+  }%
+  \next
+}
+
+
+\message{cross references,}
+
+\newwrite\auxfile
+
+\newif\ifhavexrefs    % True if xref values are known.
+\newif\ifwarnedxrefs  % True if we warned once that they aren't known.
+
+% @inforef is relatively simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+  node \samp{\ignorespaces#1{}}}
+
+% @node's only job in TeX is to define \lastnode, which is used in
+% cross-references.  The @node line might or might not have commas, and
+% might or might not have spaces before the first comma, like:
+% @node foo , bar , ...
+% We don't want such trailing spaces in the node name.
+%
+\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse}
+%
+% also remove a trailing comma, in case of something like this:
+% @node Help-Cross,  ,  , Cross-refs
+\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse}
+\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}}
+
+\let\nwnode=\node
+\let\lastnode=\empty
+
+% Write a cross-reference definition for the current node.  #1 is the
+% type (Ynumbered, Yappendix, Ynothing).
+%
+\def\donoderef#1{%
+  \ifx\lastnode\empty\else
+    \setref{\lastnode}{#1}%
+    \global\let\lastnode=\empty
+  \fi
+}
+
+% @anchor{NAME} -- define xref target at arbitrary point.
+%
+\newcount\savesfregister
+%
+\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+
+% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
+% anchor), which consists of three parts:
+% 1) NAME-title - the current sectioning name taken from \thissection,
+%                 or the anchor name.
+% 2) NAME-snt   - section number and type, passed as the SNT arg, or
+%                 empty for anchors.
+% 3) NAME-pg    - the page number.
+%
+% This is called from \donoderef, \anchor, and \dofloat.  In the case of
+% floats, there is an additional part, which is not written here:
+% 4) NAME-lof   - the text as it should appear in a @listoffloats.
+%
+\def\setref#1#2{%
+  \pdfmkdest{#1}%
+  \iflinks
+    {%
+      \atdummies  % preserve commands, but don't expand them
+      \edef\writexrdef##1##2{%
+	\write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+	  ##1}{##2}}% these are parameters of \writexrdef
+      }%
+      \toks0 = \expandafter{\thissection}%
+      \immediate \writexrdef{title}{\the\toks0 }%
+      \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+      \writexrdef{pg}{\folio}% will be written later, during \shipout
+    }%
+  \fi
+}
+
+% @xref, @pxref, and @ref generate cross-references.  For \xrefX, #1 is
+% the node name, #2 the name of the Info cross-reference, #3 the printed
+% node name, #4 the name of the Info file, #5 the name of the printed
+% manual.  All but the node name can be omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+  \unsepspaces
+  \def\printedmanual{\ignorespaces #5}%
+  \def\printedrefname{\ignorespaces #3}%
+  \setbox1=\hbox{\printedmanual\unskip}%
+  \setbox0=\hbox{\printedrefname\unskip}%
+  \ifdim \wd0 = 0pt
+    % No printed node name was explicitly given.
+    \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
+      % Use the node name inside the square brackets.
+      \def\printedrefname{\ignorespaces #1}%
+    \else
+      % Use the actual chapter/section title appear inside
+      % the square brackets.  Use the real section title if we have it.
+      \ifdim \wd1 > 0pt
+        % It is in another manual, so we don't have it.
+        \def\printedrefname{\ignorespaces #1}%
+      \else
+        \ifhavexrefs
+          % We know the real title if we have the xref values.
+          \def\printedrefname{\refx{#1-title}{}}%
+        \else
+          % Otherwise just copy the Info node name.
+          \def\printedrefname{\ignorespaces #1}%
+        \fi%
+      \fi
+    \fi
+  \fi
+  %
+  % Make link in pdf output.
+  \ifpdf
+    \leavevmode
+    \getfilename{#4}%
+    {\turnoffactive
+     % See comments at \activebackslashdouble.
+     {\activebackslashdouble \xdef\pdfxrefdest{#1}%
+      \backslashparens\pdfxrefdest}%
+     %
+     \ifnum\filenamelength>0
+       \startlink attr{/Border [0 0 0]}%
+         goto file{\the\filename.pdf} name{\pdfxrefdest}%
+     \else
+       \startlink attr{/Border [0 0 0]}%
+         goto name{\pdfmkpgn{\pdfxrefdest}}%
+     \fi
+    }%
+    \linkcolor
+  \fi
+  %
+  % Float references are printed completely differently: "Figure 1.2"
+  % instead of "[somenode], p.3".  We distinguish them by the
+  % LABEL-title being set to a magic string.
+  {%
+    % Have to otherify everything special to allow the \csname to
+    % include an _ in the xref name, etc.
+    \indexnofonts
+    \turnoffactive
+    \expandafter\global\expandafter\let\expandafter\Xthisreftitle
+      \csname XR#1-title\endcsname
+  }%
+  \iffloat\Xthisreftitle
+    % If the user specified the print name (third arg) to the ref,
+    % print it instead of our usual "Figure 1.2".
+    \ifdim\wd0 = 0pt
+      \refx{#1-snt}%
+    \else
+      \printedrefname
+    \fi
+    %
+    % if the user also gave the printed manual name (fifth arg), append
+    % "in MANUALNAME".
+    \ifdim \wd1 > 0pt
+      \space \putwordin{} \cite{\printedmanual}%
+    \fi
+  \else
+    % node/anchor (non-float) references.
+    %
+    % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+    % insert empty discretionaries after hyphens, which means that it will
+    % not find a line break at a hyphen in a node names.  Since some manuals
+    % are best written with fairly long node names, containing hyphens, this
+    % is a loss.  Therefore, we give the text of the node name again, so it
+    % is as if TeX is seeing it for the first time.
+    \ifdim \wd1 > 0pt
+      \putwordsection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}%
+    \else
+      % _ (for example) has to be the character _ for the purposes of the
+      % control sequence corresponding to the node, but it has to expand
+      % into the usual \leavevmode...\vrule stuff for purposes of
+      % printing. So we \turnoffactive for the \refx-snt, back on for the
+      % printing, back off for the \refx-pg.
+      {\turnoffactive
+       % Only output a following space if the -snt ref is nonempty; for
+       % @unnumbered and @anchor, it won't be.
+       \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+       \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+      }%
+      % output the `[mynode]' via a macro so it can be overridden.
+      \xrefprintnodename\printedrefname
+      %
+      % But we always want a comma and a space:
+      ,\space
+      %
+      % output the `page 3'.
+      \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+    \fi
+  \fi
+  \endlink
+\endgroup}
+
+% This macro is called from \xrefX for the `[nodename]' part of xref
+% output.  It's a separate macro only so it can be changed more easily,
+% since square brackets don't work well in some documents.  Particularly
+% one that Bob is working on :).
+%
+\def\xrefprintnodename#1{[#1]}
+
+% Things referred to by \setref.
+%
+\def\Ynothing{}
+\def\Yomitfromtoc{}
+\def\Ynumbered{%
+  \ifnum\secno=0
+    \putwordChapter at tie \the\chapno
+  \else \ifnum\subsecno=0
+    \putwordSection at tie \the\chapno.\the\secno
+  \else \ifnum\subsubsecno=0
+    \putwordSection at tie \the\chapno.\the\secno.\the\subsecno
+  \else
+    \putwordSection at tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
+  \fi\fi\fi
+}
+\def\Yappendix{%
+  \ifnum\secno=0
+     \putwordAppendix at tie @char\the\appendixno{}%
+  \else \ifnum\subsecno=0
+     \putwordSection at tie @char\the\appendixno.\the\secno
+  \else \ifnum\subsubsecno=0
+    \putwordSection at tie @char\the\appendixno.\the\secno.\the\subsecno
+  \else
+    \putwordSection at tie
+      @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
+  \fi\fi\fi
+}
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+%
+\def\refx#1#2{%
+  {%
+    \indexnofonts
+    \otherbackslash
+    \expandafter\global\expandafter\let\expandafter\thisrefX
+      \csname XR#1\endcsname
+  }%
+  \ifx\thisrefX\relax
+    % If not defined, say something at least.
+    \angleleft un\-de\-fined\angleright
+    \iflinks
+      \ifhavexrefs
+        \message{\linenumber Undefined cross reference `#1'.}%
+      \else
+        \ifwarnedxrefs\else
+          \global\warnedxrefstrue
+          \message{Cross reference values unknown; you must run TeX again.}%
+        \fi
+      \fi
+    \fi
+  \else
+    % It's defined, so just use it.
+    \thisrefX
+  \fi
+  #2% Output the suffix in any case.
+}
+
+% This is the macro invoked by entries in the aux file.  Usually it's
+% just a \def (we prepend XR to the control sequence name to avoid
+% collisions).  But if this is a float type, we have more work to do.
+%
+\def\xrdef#1#2{%
+  \expandafter\gdef\csname XR#1\endcsname{#2}% remember this xref value.
+  %
+  % Was that xref control sequence that we just defined for a float?
+  \expandafter\iffloat\csname XR#1\endcsname
+    % it was a float, and we have the (safe) float type in \iffloattype.
+    \expandafter\let\expandafter\floatlist
+      \csname floatlist\iffloattype\endcsname
+    %
+    % Is this the first time we've seen this float type?
+    \expandafter\ifx\floatlist\relax
+      \toks0 = {\do}% yes, so just \do
+    \else
+      % had it before, so preserve previous elements in list.
+      \toks0 = \expandafter{\floatlist\do}%
+    \fi
+    %
+    % Remember this xref in the control sequence \floatlistFLOATTYPE,
+    % for later use in \listoffloats.
+    \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0{#1}}%
+  \fi
+}
+
+% Read the last existing aux file, if any.  No error if none exists.
+%
+\def\tryauxfile{%
+  \openin 1 \jobname.aux
+  \ifeof 1 \else
+    \readdatafile{aux}%
+    \global\havexrefstrue
+  \fi
+  \closein 1
+}
+
+\def\setupdatafile{%
+  \catcode`\^^@=\other
+  \catcode`\^^A=\other
+  \catcode`\^^B=\other
+  \catcode`\^^C=\other
+  \catcode`\^^D=\other
+  \catcode`\^^E=\other
+  \catcode`\^^F=\other
+  \catcode`\^^G=\other
+  \catcode`\^^H=\other
+  \catcode`\^^K=\other
+  \catcode`\^^L=\other
+  \catcode`\^^N=\other
+  \catcode`\^^P=\other
+  \catcode`\^^Q=\other
+  \catcode`\^^R=\other
+  \catcode`\^^S=\other
+  \catcode`\^^T=\other
+  \catcode`\^^U=\other
+  \catcode`\^^V=\other
+  \catcode`\^^W=\other
+  \catcode`\^^X=\other
+  \catcode`\^^Z=\other
+  \catcode`\^^[=\other
+  \catcode`\^^\=\other
+  \catcode`\^^]=\other
+  \catcode`\^^^=\other
+  \catcode`\^^_=\other
+  % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
+  % in xref tags, i.e., node names.  But since ^^e4 notation isn't
+  % supported in the main text, it doesn't seem desirable.  Furthermore,
+  % that is not enough: for node names that actually contain a ^
+  % character, we would end up writing a line like this: 'xrdef {'hat
+  % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+  % argument, and \hat is not an expandable control sequence.  It could
+  % all be worked out, but why?  Either we support ^^ or we don't.
+  %
+  % The other change necessary for this was to define \auxhat:
+  % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+  % and then to call \auxhat in \setq.
+  %
+  \catcode`\^=\other
+  %
+  % Special characters.  Should be turned off anyway, but...
+  \catcode`\~=\other
+  \catcode`\[=\other
+  \catcode`\]=\other
+  \catcode`\"=\other
+  \catcode`\_=\other
+  \catcode`\|=\other
+  \catcode`\<=\other
+  \catcode`\>=\other
+  \catcode`\$=\other
+  \catcode`\#=\other
+  \catcode`\&=\other
+  \catcode`\%=\other
+  \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+  %
+  % This is to support \ in node names and titles, since the \
+  % characters end up in a \csname.  It's easier than
+  % leaving it active and making its active definition an actual \
+  % character.  What I don't understand is why it works in the *value*
+  % of the xrdef.  Seems like it should be a catcode12 \, and that
+  % should not typeset properly.  But it works, so I'm moving on for
+  % now.  --karl, 15jan04.
+  \catcode`\\=\other
+  %
+  % Make the characters 128-255 be printing characters.
+  {%
+    \count1=128
+    \def\loop{%
+      \catcode\count1=\other
+      \advance\count1 by 1
+      \ifnum \count1<256 \loop \fi
+    }%
+  }%
+  %
+  % @ is our escape character in .aux files, and we need braces.
+  \catcode`\{=1
+  \catcode`\}=2
+  \catcode`\@=0
+}
+
+\def\readdatafile#1{%
+\begingroup
+  \setupdatafile
+  \input\jobname.#1
+\endgroup}
+
+\message{insertions,}
+% including footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for info output only.
+\let\footnotestyle=\comment
+
+{\catcode `\@=11
+%
+% Auto-number footnotes.  Otherwise like plain.
+\gdef\footnote{%
+  \let\indent=\ptexindent
+  \let\noindent=\ptexnoindent
+  \global\advance\footnoteno by \@ne
+  \edef\thisfootno{$^{\the\footnoteno}$}%
+  %
+  % In case the footnote comes at the end of a sentence, preserve the
+  % extra spacing after we do the footnote number.
+  \let\@sf\empty
+  \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
+  %
+  % Remove inadvertent blank space before typesetting the footnote number.
+  \unskip
+  \thisfootno\@sf
+  \dofootnote
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter.  Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset (and anything else that uses
+% \parseargline) fails inside footnotes because the tokens are fixed when
+% the footnote is read.  --karl, 16nov96.
+%
+\gdef\dofootnote{%
+  \insert\footins\bgroup
+  % We want to typeset this text as a normal paragraph, even if the
+  % footnote reference occurs in (for example) a display environment.
+  % So reset some parameters.
+  \hsize=\pagewidth
+  \interlinepenalty\interfootnotelinepenalty
+  \splittopskip\ht\strutbox % top baseline for broken footnotes
+  \splitmaxdepth\dp\strutbox
+  \floatingpenalty\@MM
+  \leftskip\z at skip
+  \rightskip\z at skip
+  \spaceskip\z at skip
+  \xspaceskip\z at skip
+  \parindent\defaultparindent
+  %
+  \smallfonts \rm
+  %
+  % Because we use hanging indentation in footnotes, a @noindent appears
+  % to exdent this text, so make it be a no-op.  makeinfo does not use
+  % hanging indentation so @noindent can still be needed within footnote
+  % text after an @example or the like (not that this is good style).
+  \let\noindent = \relax
+  %
+  % Hang the footnote text off the number.  Use \everypar in case the
+  % footnote extends for more than one paragraph.
+  \everypar = {\hang}%
+  \textindent{\thisfootno}%
+  %
+  % Don't crash into the line above the footnote text.  Since this
+  % expands into a box, it must come within the paragraph, lest it
+  % provide a place where TeX can split the footnote.
+  \footstrut
+  \futurelet\next\fo at t
+}
+}%end \catcode `\@=11
+
+% In case a @footnote appears in a vbox, save the footnote text and create
+% the real \insert just after the vbox finished.  Otherwise, the insertion
+% would be lost.
+% Similarily, if a @footnote appears inside an alignment, save the footnote
+% text to a box and make the \insert when a row of the table is finished.
+% And the same can be done for other insert classes.  --kasal, 16nov03.
+
+% Replace the \insert primitive by a cheating macro.
+% Deeper inside, just make sure that the saved insertions are not spilled
+% out prematurely.
+%
+\def\startsavinginserts{%
+  \ifx \insert\ptexinsert
+    \let\insert\saveinsert
+  \else
+    \let\checkinserts\relax
+  \fi
+}
+
+% This \insert replacement works for both \insert\footins{foo} and
+% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}.
+%
+\def\saveinsert#1{%
+  \edef\next{\noexpand\savetobox \makeSAVEname#1}%
+  \afterassignment\next
+  % swallow the left brace
+  \let\temp =
+}
+\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
+\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
+
+\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
+
+\def\placesaveins#1{%
+  \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
+    {\box#1}%
+}
+
+% eat @SAVE -- beware, all of them have catcode \other:
+{
+  \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials  %  ;-)
+  \gdef\gobblesave @SAVE{}
+}
+
+% initialization:
+\def\newsaveins #1{%
+  \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
+  \next
+}
+\def\newsaveinsX #1{%
+  \csname newbox\endcsname #1%
+  \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
+    \checksaveins #1}%
+}
+
+% initialize:
+\let\checkinserts\empty
+\newsaveins\footins
+\newsaveins\margin
+
+
+% @image.  We use the macros from epsf.tex to support this.
+% If epsf.tex is not installed and @image is used, we complain.
+%
+% Check for and read epsf.tex up front.  If we read it only at @image
+% time, we might be inside a group, and then its definitions would get
+% undone and the next image would fail.
+\openin 1 = epsf.tex
+\ifeof 1 \else
+  % Do not bother showing banner with epsf.tex v2.7k (available in
+  % doc/epsf.tex and on ctan).
+  \def\epsfannounce{\toks0 = }%
+  \input epsf.tex
+\fi
+\closein 1
+%
+% We will only complain once about lack of epsf.tex.
+\newif\ifwarnednoepsf
+\newhelp\noepsfhelp{epsf.tex must be installed for images to
+  work.  It is also included in the Texinfo distribution, or you can get
+  it from ftp://tug.org/tex/epsf.tex.}
+%
+\def\image#1{%
+  \ifx\epsfbox\undefined
+    \ifwarnednoepsf \else
+      \errhelp = \noepsfhelp
+      \errmessage{epsf.tex not found, images will be ignored}%
+      \global\warnednoepsftrue
+    \fi
+  \else
+    \imagexxx #1,,,,,\finish
+  \fi
+}
+%
+% Arguments to @image:
+% #1 is (mandatory) image filename; we tack on .eps extension.
+% #2 is (optional) width, #3 is (optional) height.
+% #4 is (ignored optional) html alt text.
+% #5 is (ignored optional) extension.
+% #6 is just the usual extra ignored arg for parsing this stuff.
+\newif\ifimagevmode
+\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
+  \catcode`\^^M = 5     % in case we're inside an example
+  \normalturnoffactive  % allow _ et al. in names
+  % If the image is by itself, center it.
+  \ifvmode
+    \imagevmodetrue
+    \nobreak\bigskip
+    % Usually we'll have text after the image which will insert
+    % \parskip glue, so insert it here too to equalize the space
+    % above and below.
+    \nobreak\vskip\parskip
+    \nobreak
+    \line\bgroup\hss
+  \fi
+  %
+  % Output the image.
+  \ifpdf
+    \dopdfimage{#1}{#2}{#3}%
+  \else
+    % \epsfbox itself resets \epsf?size at each figure.
+    \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+    \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+    \epsfbox{#1.eps}%
+  \fi
+  %
+  \ifimagevmode \hss \egroup \bigbreak \fi  % space after the image
+\endgroup}
+
+
+% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables,
+% etc.  We don't actually implement floating yet, we always include the
+% float "here".  But it seemed the best name for the future.
+%
+\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish}
+
+% There may be a space before second and/or third parameter; delete it.
+\def\eatcommaspace#1, {#1,}
+
+% #1 is the optional FLOATTYPE, the text label for this float, typically
+% "Figure", "Table", "Example", etc.  Can't contain commas.  If omitted,
+% this float will not be numbered and cannot be referred to.
+%
+% #2 is the optional xref label.  Also must be present for the float to
+% be referable.
+%
+% #3 is the optional positioning argument; for now, it is ignored.  It
+% will somehow specify the positions allowed to float to (here, top, bottom).
+%
+% We keep a separate counter for each FLOATTYPE, which we reset at each
+% chapter-level command.
+\let\resetallfloatnos=\empty
+%
+\def\dofloat#1,#2,#3,#4\finish{%
+  \let\thiscaption=\empty
+  \let\thisshortcaption=\empty
+  %
+  % don't lose footnotes inside @float.
+  %
+  % BEWARE: when the floats start float, we have to issue warning whenever an
+  % insert appears inside a float which could possibly float. --kasal, 26may04
+  %
+  \startsavinginserts
+  %
+  % We can't be used inside a paragraph.
+  \par
+  %
+  \vtop\bgroup
+    \def\floattype{#1}%
+    \def\floatlabel{#2}%
+    \def\floatloc{#3}% we do nothing with this yet.
+    %
+    \ifx\floattype\empty
+      \let\safefloattype=\empty
+    \else
+      {%
+        % the floattype might have accents or other special characters,
+        % but we need to use it in a control sequence name.
+        \indexnofonts
+        \turnoffactive
+        \xdef\safefloattype{\floattype}%
+      }%
+    \fi
+    %
+    % If label is given but no type, we handle that as the empty type.
+    \ifx\floatlabel\empty \else
+      % We want each FLOATTYPE to be numbered separately (Figure 1,
+      % Table 1, Figure 2, ...).  (And if no label, no number.)
+      %
+      \expandafter\getfloatno\csname\safefloattype floatno\endcsname
+      \global\advance\floatno by 1
+      %
+      {%
+        % This magic value for \thissection is output by \setref as the
+        % XREFLABEL-title value.  \xrefX uses it to distinguish float
+        % labels (which have a completely different output format) from
+        % node and anchor labels.  And \xrdef uses it to construct the
+        % lists of floats.
+        %
+        \edef\thissection{\floatmagic=\safefloattype}%
+        \setref{\floatlabel}{Yfloat}%
+      }%
+    \fi
+    %
+    % start with \parskip glue, I guess.
+    \vskip\parskip
+    %
+    % Don't suppress indentation if a float happens to start a section.
+    \restorefirstparagraphindent
+}
+
+% we have these possibilities:
+% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap
+% @float Foo,lbl & no caption:    Foo 1.1
+% @float Foo & @caption{Cap}:     Foo: Cap
+% @float Foo & no caption:        Foo
+% @float ,lbl & Caption{Cap}:     1.1: Cap
+% @float ,lbl & no caption:       1.1
+% @float & @caption{Cap}:         Cap
+% @float & no caption:
+%
+\def\Efloat{%
+    \let\floatident = \empty
+    %
+    % In all cases, if we have a float type, it comes first.
+    \ifx\floattype\empty \else \def\floatident{\floattype}\fi
+    %
+    % If we have an xref label, the number comes next.
+    \ifx\floatlabel\empty \else
+      \ifx\floattype\empty \else % if also had float type, need tie first.
+        \appendtomacro\floatident{\tie}%
+      \fi
+      % the number.
+      \appendtomacro\floatident{\chaplevelprefix\the\floatno}%
+    \fi
+    %
+    % Start the printed caption with what we've constructed in
+    % \floatident, but keep it separate; we need \floatident again.
+    \let\captionline = \floatident
+    %
+    \ifx\thiscaption\empty \else
+      \ifx\floatident\empty \else
+	\appendtomacro\captionline{: }% had ident, so need a colon between
+      \fi
+      %
+      % caption text.
+      \appendtomacro\captionline{\scanexp\thiscaption}%
+    \fi
+    %
+    % If we have anything to print, print it, with space before.
+    % Eventually this needs to become an \insert.
+    \ifx\captionline\empty \else
+      \vskip.5\parskip
+      \captionline
+      %
+      % Space below caption.
+      \vskip\parskip
+    \fi
+    %
+    % If have an xref label, write the list of floats info.  Do this
+    % after the caption, to avoid chance of it being a breakpoint.
+    \ifx\floatlabel\empty \else
+      % Write the text that goes in the lof to the aux file as
+      % \floatlabel-lof.  Besides \floatident, we include the short
+      % caption if specified, else the full caption if specified, else nothing.
+      {%
+        \atdummies
+        % since we read the caption text in the macro world, where ^^M
+        % is turned into a normal character, we have to scan it back, so
+        % we don't write the literal three characters "^^M" into the aux file.
+	\scanexp{%
+	  \xdef\noexpand\gtemp{%
+	    \ifx\thisshortcaption\empty
+	      \thiscaption
+	    \else
+	      \thisshortcaption
+	    \fi
+	  }%
+	}%
+        \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident
+	  \ifx\gtemp\empty \else : \gtemp \fi}}%
+      }%
+    \fi
+  \egroup  % end of \vtop
+  %
+  % place the captured inserts
+  %
+  % BEWARE: when the floats start float, we have to issue warning whenever an
+  % insert appears inside a float which could possibly float. --kasal, 26may04
+  %
+  \checkinserts
+}
+
+% Append the tokens #2 to the definition of macro #1, not expanding either.
+%
+\def\appendtomacro#1#2{%
+  \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+
+% @caption, @shortcaption
+%
+\def\caption{\docaption\thiscaption}
+\def\shortcaption{\docaption\thisshortcaption}
+\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
+\def\defcaption#1#2{\egroup \def#1{#2}}
+
+% The parameter is the control sequence identifying the counter we are
+% going to use.  Create it if it doesn't exist and assign it to \floatno.
+\def\getfloatno#1{%
+  \ifx#1\relax
+      % Haven't seen this figure type before.
+      \csname newcount\endcsname #1%
+      %
+      % Remember to reset this floatno at the next chap.
+      \expandafter\gdef\expandafter\resetallfloatnos
+        \expandafter{\resetallfloatnos #1=0 }%
+  \fi
+  \let\floatno#1%
+}
+
+% \setref calls this to get the XREFLABEL-snt value.  We want an @xref
+% to the FLOATLABEL to expand to "Figure 3.1".  We call \setref when we
+% first read the @float command.
+%
+\def\Yfloat{\floattype at tie \chaplevelprefix\the\floatno}%
+
+% Magic string used for the XREFLABEL-title value, so \xrefX can
+% distinguish floats from other xref types.
+\def\floatmagic{!!float!!}
+
+% #1 is the control sequence we are passed; we expand into a conditional
+% which is true if #1 represents a float ref.  That is, the magic
+% \thissection value which we \setref above.
+%
+\def\iffloat#1{\expandafter\doiffloat#1==\finish}
+%
+% #1 is (maybe) the \floatmagic string.  If so, #2 will be the
+% (safe) float type for this float.  We set \iffloattype to #2.
+%
+\def\doiffloat#1=#2=#3\finish{%
+  \def\temp{#1}%
+  \def\iffloattype{#2}%
+  \ifx\temp\floatmagic
+}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+%
+\parseargdef\listoffloats{%
+  \def\floattype{#1}% floattype
+  {%
+    % the floattype might have accents or other special characters,
+    % but we need to use it in a control sequence name.
+    \indexnofonts
+    \turnoffactive
+    \xdef\safefloattype{\floattype}%
+  }%
+  %
+  % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE.
+  \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax
+    \ifhavexrefs
+      % if the user said @listoffloats foo but never @float foo.
+      \message{\linenumber No `\safefloattype' floats to list.}%
+    \fi
+  \else
+    \begingroup
+      \leftskip=\tocindent  % indent these entries like a toc
+      \let\do=\listoffloatsdo
+      \csname floatlist\safefloattype\endcsname
+    \endgroup
+  \fi
+}
+
+% This is called on each entry in a list of floats.  We're passed the
+% xref label, in the form LABEL-title, which is how we save it in the
+% aux file.  We strip off the -title and look up \XRLABEL-lof, which
+% has the text we're supposed to typeset here.
+%
+% Figures without xref labels will not be included in the list (since
+% they won't appear in the aux file).
+%
+\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish}
+\def\listoffloatsdoentry#1-title\finish{{%
+  % Can't fully expand XR#1-lof because it can contain anything.  Just
+  % pass the control sequence.  On the other hand, XR#1-pg is just the
+  % page number, and we want to fully expand that so we can get a link
+  % in pdf output.
+  \toksA = \expandafter{\csname XR#1-lof\endcsname}%
+  %
+  % use the same \entry macro we use to generate the TOC and index.
+  \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
+  \writeentry
+}}
+
+\message{localization,}
+% and i18n.
+
+% @documentlanguage is usually given very early, just after
+% @setfilename.  If done too late, it may not override everything
+% properly.  Single argument is the language abbreviation.
+% It would be nice if we could set up a hyphenation file here.
+%
+\parseargdef\documentlanguage{%
+  \tex % read txi-??.tex file in plain TeX.
+    % Read the file if it exists.
+    \openin 1 txi-#1.tex
+    \ifeof 1
+      \errhelp = \nolanghelp
+      \errmessage{Cannot read language file txi-#1.tex}%
+    \else
+      \input txi-#1.tex
+    \fi
+    \closein 1
+  \endgroup
+}
+\newhelp\nolanghelp{The given language definition file cannot be found or
+is empty.  Maybe you need to install it?  In the current directory
+should work if nowhere else does.}
+
+
+% @documentencoding should change something in TeX eventually, most
+% likely, but for now just recognize it.
+\let\documentencoding = \comment
+
+
+% Page size parameters.
+%
+\newdimen\defaultparindent \defaultparindent = 15pt
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness = 10000
+
+% Don't be so finicky about underfull hboxes, either.
+\hbadness = 2000
+
+% Following George Bush, just get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything.  We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize.  We call this whenever the paper size is set.
+%
+\def\setemergencystretch{%
+  \ifx\emergencystretch\thisisundefined
+    % Allow us to assign to \emergencystretch anyway.
+    \def\emergencystretch{\dimen0}%
+  \else
+    \emergencystretch = .15\hsize
+  \fi
+}
+
+% Parameters in order: 1) textheight; 2) textwidth;
+% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip;
+% 7) physical page height; 8) physical page width.
+%
+% We also call \setleading{\textleading}, so the caller should define
+% \textleading.  The caller should also set \parskip.
+%
+\def\internalpagesizes#1#2#3#4#5#6#7#8{%
+  \voffset = #3\relax
+  \topskip = #6\relax
+  \splittopskip = \topskip
+  %
+  \vsize = #1\relax
+  \advance\vsize by \topskip
+  \outervsize = \vsize
+  \advance\outervsize by 2\topandbottommargin
+  \pageheight = \vsize
+  %
+  \hsize = #2\relax
+  \outerhsize = \hsize
+  \advance\outerhsize by 0.5in
+  \pagewidth = \hsize
+  %
+  \normaloffset = #4\relax
+  \bindingoffset = #5\relax
+  %
+  \ifpdf
+    \pdfpageheight #7\relax
+    \pdfpagewidth #8\relax
+  \fi
+  %
+  \setleading{\textleading}
+  %
+  \parindent = \defaultparindent
+  \setemergencystretch
+}
+
+% @letterpaper (the default).
+\def\letterpaper{{\globaldefs = 1
+  \parskip = 3pt plus 2pt minus 1pt
+  \textleading = 13.2pt
+  %
+  % If page is nothing but text, make it come out even.
+  \internalpagesizes{46\baselineskip}{6in}%
+                    {\voffset}{.25in}%
+                    {\bindingoffset}{36pt}%
+                    {11in}{8.5in}%
+}}
+
+% Use @smallbook to reset parameters for 7x9.25 trim size.
+\def\smallbook{{\globaldefs = 1
+  \parskip = 2pt plus 1pt
+  \textleading = 12pt
+  %
+  \internalpagesizes{7.5in}{5in}%
+                    {\voffset}{.25in}%
+                    {\bindingoffset}{16pt}%
+                    {9.25in}{7in}%
+  %
+  \lispnarrowing = 0.3in
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = .5cm
+}}
+
+% Use @smallerbook to reset parameters for 6x9 trim size.
+% (Just testing, parameters still in flux.)
+\def\smallerbook{{\globaldefs = 1
+  \parskip = 1.5pt plus 1pt
+  \textleading = 12pt
+  %
+  \internalpagesizes{7.4in}{4.8in}%
+                    {-.2in}{-.4in}%
+                    {0pt}{14pt}%
+                    {9in}{6in}%
+  %
+  \lispnarrowing = 0.25in
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = .4cm
+}}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{{\globaldefs = 1
+  \parskip = 3pt plus 2pt minus 1pt
+  \textleading = 13.2pt
+  %
+  % Double-side printing via postscript on Laserjet 4050
+  % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
+  % To change the settings for a different printer or situation, adjust
+  % \normaloffset until the front-side and back-side texts align.  Then
+  % do the same for \bindingoffset.  You can set these for testing in
+  % your texinfo source file like this:
+  % @tex
+  % \global\normaloffset = -6mm
+  % \global\bindingoffset = 10mm
+  % @end tex
+  \internalpagesizes{51\baselineskip}{160mm}
+                    {\voffset}{\hoffset}%
+                    {\bindingoffset}{44pt}%
+                    {297mm}{210mm}%
+  %
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = 5mm
+}}
+
+% Use @afivepaper to print on European A5 paper.
+% From romildo at urano.iceb.ufop.br, 2 July 2000.
+% He also recommends making @example and @lisp be small.
+\def\afivepaper{{\globaldefs = 1
+  \parskip = 2pt plus 1pt minus 0.1pt
+  \textleading = 12.5pt
+  %
+  \internalpagesizes{160mm}{120mm}%
+                    {\voffset}{\hoffset}%
+                    {\bindingoffset}{8pt}%
+                    {210mm}{148mm}%
+  %
+  \lispnarrowing = 0.2in
+  \tolerance = 800
+  \hfuzz = 1.2pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = 2mm
+  \tableindent = 12mm
+}}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper.
+\def\afourlatex{{\globaldefs = 1
+  \afourpaper
+  \internalpagesizes{237mm}{150mm}%
+                    {\voffset}{4.6mm}%
+                    {\bindingoffset}{7mm}%
+                    {297mm}{210mm}%
+  %
+  % Must explicitly reset to 0 because we call \afourpaper.
+  \globaldefs = 0
+}}
+
+% Use @afourwide to print on A4 paper in landscape format.
+\def\afourwide{{\globaldefs = 1
+  \afourpaper
+  \internalpagesizes{241mm}{165mm}%
+                    {\voffset}{-2.95mm}%
+                    {\bindingoffset}{7mm}%
+                    {297mm}{210mm}%
+  \globaldefs = 0
+}}
+
+% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
+% Perhaps we should allow setting the margins, \topskip, \parskip,
+% and/or leading, also. Or perhaps we should compute them somehow.
+%
+\parseargdef\pagesizes{\pagesizesyyy #1,,\finish}
+\def\pagesizesyyy#1,#2,#3\finish{{%
+  \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
+  \globaldefs = 1
+  %
+  \parskip = 3pt plus 2pt minus 1pt
+  \setleading{\textleading}%
+  %
+  \dimen0 = #1
+  \advance\dimen0 by \voffset
+  %
+  \dimen2 = \hsize
+  \advance\dimen2 by \normaloffset
+  %
+  \internalpagesizes{#1}{\hsize}%
+                    {\voffset}{\normaloffset}%
+                    {\bindingoffset}{44pt}%
+                    {\dimen0}{\dimen2}%
+}}
+
+% Set default to letter.
+%
+\letterpaper
+
+
+\message{and turning on texinfo input format.}
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other
+\catcode`\~=\other
+\catcode`\^=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode`\+=\other
+\catcode`\$=\other
+\def\normaldoublequote{"}
+\def\normaltilde{~}
+\def\normalcaret{^}
+\def\normalunderscore{_}
+\def\normalverticalbar{|}
+\def\normalless{<}
+\def\normalgreater{>}
+\def\normalplus{+}
+\def\normaldollar{$}%$ font-lock fix
+
+% This macro is used to make a character print one way in \tt
+% (where it can probably be output as-is), and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise.  Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
+
+% Same as above, but check for italic font.  Actually this also catches
+% non-italic slanted fonts since it is impossible to distinguish them from
+% italic fonts.  But since this is only used by $ and it uses \sl anyway
+% this is not a problem.
+\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt\char34}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt\char126}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+\let\realunder=_
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
+
+\catcode`\|=\active
+\def|{{\tt\char124}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+\catcode`\$=\active
+\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+\catcode`\@=0
+
+% \backslashcurfont outputs one backslash character in current font,
+% as in \char`\\.
+\global\chardef\backslashcurfont=`\\
+\global\let\rawbackslashxx=\backslashcurfont  % let existing .??s files work
+
+% \rawbackslash defines an active \ to do \backslashcurfont.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other.
+{\catcode`\\=\active
+ @gdef at rawbackslash{@let\=@backslashcurfont}
+ @gdef at otherbackslash{@let\=@realbackslash}
+}
+
+% \realbackslash is an actual character `\' with catcode other, and
+% \doublebackslash is two of them (for the pdf outlines).
+{\catcode`\\=\other @gdef at realbackslash{\} @gdef at doublebackslash{\\}}
+
+% \normalbackslash outputs one backslash in fixed width font.
+\def\normalbackslash{{\tt\backslashcurfont}}
+
+\catcode`\\=\active
+
+% Used sometimes to turn off (effectively) the active characters
+% even after parsing them.
+ at def@turnoffactive{%
+  @let"=@normaldoublequote
+  @let\=@realbackslash
+  @let~=@normaltilde
+  @let^=@normalcaret
+  @let_=@normalunderscore
+  @let|=@normalverticalbar
+  @let<=@normalless
+  @let>=@normalgreater
+  @let+=@normalplus
+  @let$=@normaldollar %$ font-lock fix
+  @unsepspaces
+}
+
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'.  (Thus, \ is not expandable when this is in
+% effect.)
+%
+ at def@normalturnoffactive{@turnoffactive @let\=@normalbackslash}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+ at otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+ at gdef@eatinput input texinfo{@fixbackslash}
+ at global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\{ in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also turn back on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+ at gdef@fixbackslash{%
+  @ifx\@eatinput @let\ = @normalbackslash @fi
+  @catcode`+=@active
+  @catcode`@_=@active
+}
+
+% Say @foo, not \foo, in error messages.
+ at escapechar = `@@
+
+% These look ok in all fonts, so just make them not special.
+ at catcode`@& = @other
+ at catcode`@# = @other
+ at catcode`@% = @other
+
+
+ at c Local variables:
+ at c eval: (add-hook 'write-file-hooks 'time-stamp)
+ at c page-delimiter: "^\\\\message"
+ at c time-stamp-start: "def\\\\texinfoversion{"
+ at c time-stamp-format: "%:y-%02m-%02d.%02H"
+ at c time-stamp-end: "}"
+ at c End:
+
+ at c vim:sw=2:
+
+ at ignore
+   arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+ at end ignore
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/rbffi.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/rbffi.h
new file mode 100755
index 0000000..b6fe477
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/rbffi.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2008, 2009, Wayne Meissner
+ *
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Ruby FFI project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RBFFI_RBFFI_H
+#define	RBFFI_RBFFI_H
+
+#include <ruby.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#define MAX_PARAMETERS (32)
+
+extern VALUE rbffi_FFIModule;
+    
+extern void rbffi_Type_Init(VALUE ffiModule);
+extern void rbffi_Buffer_Init(VALUE ffiModule);
+extern void rbffi_Invoker_Init(VALUE ffiModule);
+extern void rbffi_Variadic_Init(VALUE ffiModule);
+extern void rbffi_DataConverter_Init(VALUE ffiModule);
+extern VALUE rbffi_AbstractMemoryClass, rbffi_InvokerClass;
+extern int rbffi_type_size(VALUE type);
+extern void rbffi_Thread_Init(VALUE moduleFFI);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* RBFFI_RBFFI_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/rbffi_endian.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/rbffi_endian.h
new file mode 100755
index 0000000..c108020
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/rbffi_endian.h
@@ -0,0 +1,59 @@
+#ifndef JFFI_ENDIAN_H
+#define JFFI_ENDIAN_H
+
+#ifndef _MSC_VER
+#include <sys/param.h>
+#endif
+
+#include <sys/types.h>
+
+#if defined(__linux__) || defined(__CYGWIN__) || defined(__GNU__) || defined(__GLIBC__)
+# include <endian.h>
+# if !defined(LITTLE_ENDIAN) && defined(__LITTLE_ENDIAN)
+#  define LITTLE_ENDIAN __LITTLE_ENDIAN
+# endif
+# if !defined(BIG_ENDIAN) && defined(__BIG_ENDIAN)
+#  define BIG_ENDIAN __BIG_ENDIAN
+# endif
+# if !defined(BYTE_ORDER) && defined(__BYTE_ORDER)
+#  define BYTE_ORDER __BYTE_ORDER
+# endif
+#endif
+
+#ifdef __sun
+# include <sys/byteorder.h>
+# define LITTLE_ENDIAN 1234
+# define BIG_ENDIAN 4321
+# if defined(_BIG_ENDIAN)
+#  define BYTE_ORDER BIG_ENDIAN
+# elif defined(_LITTLE_ENDIAN)
+#  define BYTE_ORDER LITTLE_ENDIAN
+# else
+#  error "Cannot determine endian-ness"
+# endif
+#endif
+
+#if defined(_AIX) && !defined(BYTE_ORDER)
+# define LITTLE_ENDIAN 1234
+# define BIG_ENDIAN 4321
+# if defined(__BIG_ENDIAN__)
+#  define BYTE_ORDER BIG_ENDIAN
+# elif defined(__LITTLE_ENDIAN__)
+#  define BYTE_ORDER LITTLE_ENDIAN
+# else
+#  error "Cannot determine endian-ness"
+# endif
+#endif
+
+#if defined(_WIN32)
+# define LITTLE_ENDIAN 1234
+# define BIG_ENDIAN 4321
+# define BYTE_ORDER LITTLE_ENDIAN
+#endif
+
+#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN)
+#  error "Cannot determine the endian-ness of this platform"
+#endif
+
+#endif /* JFFI_ENDIAN_H */
+
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/win32/stdbool.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/win32/stdbool.h
new file mode 100755
index 0000000..9130a8b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/win32/stdbool.h
@@ -0,0 +1,8 @@
+#ifndef FFI_STDBOOL_H
+#define FFI_STDBOOL_H
+
+typedef int bool;
+#define true 1
+#define false 0
+
+#endif /* FFI_STDBOOL_H */
\ No newline at end of file
diff --git a/app/server/vendor/ffi-1.9.10/ext/ffi_c/win32/stdint.h b/app/server/vendor/ffi-1.9.10/ext/ffi_c/win32/stdint.h
new file mode 100755
index 0000000..6ce7457
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ext/ffi_c/win32/stdint.h
@@ -0,0 +1,201 @@
+/* stdint.h standard header */
+#if !defined(_MSC_VER) && !defined(INT8_MIN)
+#pragma once
+#ifndef _STDINT
+#define _STDINT
+#ifndef RC_INVOKED
+#include <yvals.h>
+
+/* NB: assumes
+	byte has 8 bits
+	long is 32 bits
+	pointer can convert to and from long long
+	long long is longest type
+ */
+
+_C_STD_BEGIN
+		/* TYPE DEFINITIONS */
+typedef signed char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+
+typedef signed char int_least8_t;
+typedef short int_least16_t;
+typedef int int_least32_t;
+
+typedef unsigned char uint_least8_t;
+typedef unsigned short uint_least16_t;
+typedef unsigned int uint_least32_t;
+
+typedef char int_fast8_t;
+typedef int int_fast16_t;
+typedef int int_fast32_t;
+
+typedef unsigned char uint_fast8_t;
+typedef unsigned int uint_fast16_t;
+typedef unsigned int uint_fast32_t;
+
+#ifndef _INTPTR_T_DEFINED
+ #define _INTPTR_T_DEFINED
+ #ifdef _WIN64
+typedef __int64 intptr_t;
+ #else /* _WIN64 */
+typedef _W64 int intptr_t;
+ #endif /* _WIN64 */
+#endif /* _INTPTR_T_DEFINED */
+
+#ifndef _UINTPTR_T_DEFINED
+ #define _UINTPTR_T_DEFINED
+ #ifdef _WIN64
+typedef unsigned __int64 uintptr_t;
+ #else /* _WIN64 */
+typedef _W64 unsigned int uintptr_t;
+ #endif /* _WIN64 */
+#endif /* _UINTPTR_T_DEFINED */
+
+typedef _Longlong int64_t;
+typedef _ULonglong uint64_t;
+
+typedef _Longlong int_least64_t;
+typedef _ULonglong uint_least64_t;
+
+typedef _Longlong int_fast64_t;
+typedef _ULonglong uint_fast64_t;
+
+typedef _Longlong intmax_t;
+typedef _ULonglong uintmax_t;
+
+		/* LIMIT MACROS */
+#define INT8_MIN	(-0x7f - _C2)
+#define INT16_MIN	(-0x7fff - _C2)
+#define INT32_MIN	(-0x7fffffff - _C2)
+
+#define INT8_MAX	0x7f
+#define INT16_MAX	0x7fff
+#define INT32_MAX	0x7fffffff
+#define UINT8_MAX	0xff
+#define UINT16_MAX	0xffff
+#define UINT32_MAX	0xffffffff
+
+#define INT_LEAST8_MIN		(-0x7f - _C2)
+#define INT_LEAST16_MIN		(-0x7fff - _C2)
+#define INT_LEAST32_MIN		(-0x7fffffff - _C2)
+
+#define INT_LEAST8_MAX		0x7f
+#define INT_LEAST16_MAX		0x7fff
+#define INT_LEAST32_MAX		0x7fffffff
+#define UINT_LEAST8_MAX		0xff
+#define UINT_LEAST16_MAX	0xffff
+#define UINT_LEAST32_MAX	0xffffffff
+
+#define INT_FAST8_MIN		(-0x7f - _C2)
+#define INT_FAST16_MIN		(-0x7fff - _C2)
+#define INT_FAST32_MIN		(-0x7fffffff - _C2)
+
+#define INT_FAST8_MAX		0x7f
+#define INT_FAST16_MAX		0x7fff
+#define INT_FAST32_MAX		0x7fffffff
+#define UINT_FAST8_MAX		0xff
+#define UINT_FAST16_MAX		0xffff
+#define UINT_FAST32_MAX		0xffffffff
+
+ #if _INTPTR == 0 || _INTPTR == 1
+#define INTPTR_MAX			0x7fffffff
+#define INTPTR_MIN			(-INTPTR_MAX - _C2)
+#define UINTPTR_MAX			0xffffffff
+
+ #else /* _INTPTR == 2 */
+#define INTPTR_MIN			(-_LLONG_MAX - _C2)
+#define INTPTR_MAX			_LLONG_MAX
+#define UINTPTR_MAX			_ULLONG_MAX
+#endif /* _INTPTR */
+
+#define INT8_C(x)	(x)
+#define INT16_C(x)	(x)
+#define INT32_C(x)	((x) + (INT32_MAX - INT32_MAX))
+
+#define UINT8_C(x)	(x)
+#define UINT16_C(x)	(x)
+#define UINT32_C(x)	((x) + (UINT32_MAX - UINT32_MAX))
+
+#ifdef _WIN64
+ #define PTRDIFF_MIN		INT64_MIN
+ #define PTRDIFF_MAX		INT64_MAX
+#else /* _WIN64 */
+ #define PTRDIFF_MIN		INT32_MIN
+ #define PTRDIFF_MAX		INT32_MAX
+#endif /* _WIN64 */
+
+#define SIG_ATOMIC_MIN	INT32_MIN
+#define SIG_ATOMIC_MAX	INT32_MAX
+
+#ifndef SIZE_MAX
+ #ifdef _WIN64
+  #define SIZE_MAX		UINT64_MAX
+ #else /* _WIN64 */
+  #define SIZE_MAX		UINT32_MAX
+ #endif /* _WIN64 */
+#endif /* SIZE_MAX */
+
+#define WCHAR_MIN	0x0000
+#define WCHAR_MAX	0xffff
+
+#define WINT_MIN	0x0000
+#define WINT_MAX	0xffff
+
+ #define INT64_MIN	(-0x7fffffffffffffff - _C2)
+ #define INT64_MAX	0x7fffffffffffffff
+ #define UINT64_MAX	0xffffffffffffffffU
+
+ #define INT_LEAST64_MIN	(-0x7fffffffffffffff - _C2)
+ #define INT_LEAST64_MAX	0x7fffffffffffffff
+ #define UINT_LEAST64_MAX	0xffffffffffffffffU
+
+ #define INT_FAST64_MIN		(-0x7fffffffffffffff - _C2)
+ #define INT_FAST64_MAX		0x7fffffffffffffff
+ #define UINT_FAST64_MAX	0xffffffffffffffffU
+
+ #define INTMAX_MIN		(-0x7fffffffffffffff - _C2)
+ #define INTMAX_MAX		0x7fffffffffffffff
+ #define UINTMAX_MAX	0xffffffffffffffffU
+
+#define INT64_C(x)		((x) + (INT64_MAX - INT64_MAX))
+#define UINT64_C(x)		((x) + (UINT64_MAX - UINT64_MAX))
+#define INTMAX_C(x)		INT64_C(x)
+#define UINTMAX_C(x)	UINT64_C(x)
+_C_STD_END
+#endif /* RC_INVOKED */
+#endif /* _STDINT */
+
+ #if defined(_STD_USING)
+using _CSTD int8_t; using _CSTD int16_t;
+using _CSTD int32_t; using _CSTD int64_t;
+
+using _CSTD uint8_t; using _CSTD uint16_t;
+using _CSTD uint32_t; using _CSTD uint64_t;
+
+using _CSTD int_least8_t; using _CSTD int_least16_t;
+using _CSTD int_least32_t;  using _CSTD int_least64_t;
+using _CSTD uint_least8_t; using _CSTD uint_least16_t;
+using _CSTD uint_least32_t; using _CSTD uint_least64_t;
+
+using _CSTD intmax_t; using _CSTD uintmax_t;
+
+using _CSTD uintptr_t;
+using _CSTD intptr_t;
+
+using _CSTD int_fast8_t; using _CSTD int_fast16_t;
+using _CSTD int_fast32_t; using _CSTD int_fast64_t;
+using _CSTD uint_fast8_t; using _CSTD uint_fast16_t;
+using _CSTD uint_fast32_t; using _CSTD uint_fast64_t;
+ #endif /* defined(_STD_USING) */
+
+/*
+ * Copyright (c) 1992-2009 by P.J. Plauger.  ALL RIGHTS RESERVED.
+ * Consult your license regarding permissions and restrictions.
+V5.20:0009 */
+#endif /* !defined(_MSC_VER) && !defined(INT8_MIN) */
\ No newline at end of file
diff --git a/app/server/vendor/ffi-1.9.10/ffi.gemspec b/app/server/vendor/ffi-1.9.10/ffi.gemspec
new file mode 100755
index 0000000..957d75b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/ffi.gemspec
@@ -0,0 +1,23 @@
+require File.expand_path("../lib/#{File.basename(__FILE__, '.gemspec')}/version", __FILE__)
+
+Gem::Specification.new do |s|
+  s.name = 'ffi'
+  s.version = FFI::VERSION
+  s.author = 'Wayne Meissner'
+  s.email = 'wmeissner at gmail.com'
+  s.homepage = 'http://wiki.github.com/ffi/ffi'
+  s.summary = 'Ruby FFI'
+  s.description = 'Ruby FFI library'
+  s.files = %w(ffi.gemspec LICENSE COPYING README.md Rakefile) + Dir.glob("{ext,gen,lib,spec,libtest}/**/*").reject { |f| f =~ /(lib\/[12]\.[089]|\.s?[ao]$|\.bundle|\.dylib$)/ }
+  s.extensions << 'ext/ffi_c/extconf.rb'
+  s.has_rdoc = false
+  s.rdoc_options = %w[--exclude=ext/ffi_c/.*\.o$ --exclude=ffi_c\.(bundle|so)$]
+  s.license = 'BSD'
+  s.require_paths << 'ext/ffi_c'
+  s.required_ruby_version = '>= 1.8.7'
+  s.add_development_dependency 'rake', '~> 10.1'
+  s.add_development_dependency 'rake-compiler', '~> 0.9'
+  s.add_development_dependency 'rake-compiler-dock', '~> 0.4.0'
+  s.add_development_dependency 'rspec', '~> 2.14.1'
+  s.add_development_dependency 'rubygems-tasks', "~> 0.2.4"
+end
diff --git a/app/server/vendor/ffi-1.9.10/gen/Rakefile b/app/server/vendor/ffi-1.9.10/gen/Rakefile
new file mode 100755
index 0000000..f71a1da
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/gen/Rakefile
@@ -0,0 +1,30 @@
+$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
+require 'fileutils'
+require 'ffi'
+require 'ffi/platform'
+require 'ffi/tools/types_generator'
+types_conf = File.expand_path(File.join(FFI::Platform::CONF_DIR, 'types.conf'))
+
+logfile = File.join(File.dirname(__FILE__), 'log')
+
+file types_conf do |task|
+  options = {}
+  FileUtils.mkdir_p(File.dirname(task.name), { :mode => 0755 })
+  File.open(task.name, File::CREAT|File::TRUNC|File::RDWR, 0644) do |f|
+    f.puts FFI::TypesGenerator.generate(options)
+  end
+  File.open(logfile, 'w') do |log|
+    log.puts(types_conf)
+  end
+end
+
+task :default => types_conf do
+end
+
+task :clean do
+  File.readlines(logfile).each do |file|
+    file.strip!
+    rm_f file
+  end
+  rm_f logfile
+end
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi.rb b/app/server/vendor/ffi-1.9.10/lib/ffi.rb
new file mode 100755
index 0000000..361e53d
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi.rb
@@ -0,0 +1,20 @@
+if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
+  Object.send(:remove_const, :FFI) if defined?(::FFI)
+  begin
+    require RUBY_VERSION.split('.')[0, 2].join('.') + '/ffi_c'
+  rescue Exception
+    require 'ffi_c'
+  end
+
+  require 'ffi/ffi'
+
+elsif defined?(RUBY_ENGINE)
+  # Remove the ffi gem dir from the load path, then reload the internal ffi implementation
+  $LOAD_PATH.delete(File.dirname(__FILE__))
+  $LOAD_PATH.delete(File.join(File.dirname(__FILE__), 'ffi'))
+  unless $LOADED_FEATURES.nil?
+    $LOADED_FEATURES.delete(__FILE__)
+    $LOADED_FEATURES.delete('ffi.rb')
+  end
+  require 'ffi.rb'
+end
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/autopointer.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/autopointer.rb
new file mode 100755
index 0000000..e6946d8
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/autopointer.rb
@@ -0,0 +1,194 @@
+#
+# Copyright (C) 2008-2010 Wayne Meissner
+# Copyright (C) 2008 Mike Dalessio
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+#   may be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+module FFI
+  class AutoPointer < Pointer
+    extend DataConverter
+
+    # @overload initialize(pointer, method)
+    #  @param [Pointer] pointer
+    #  @param [Method] method
+    #  @return [self]
+    #  The passed Method will be invoked at GC time.
+    # @overload initialize(pointer, proc)
+    #  @param [Pointer] pointer
+    #  @return [self]
+    #  The passed Proc will be invoked at GC time (SEE WARNING BELOW!)
+    #  @note WARNING: passing a proc _may_ cause your pointer to never be GC'd, unless you're 
+    #   careful to avoid trapping a reference to the pointer in the proc. See the test 
+    #   specs for examples.
+    # @overload initialize(pointer) { |p| ... }
+    #  @param [Pointer] pointer
+    #  @yieldparam [Pointer] p +pointer+ passed to the block
+    #  @return [self]
+    #  The passed block will be invoked at GC time.
+    #  @note WARNING: passing a block will cause your pointer to never be GC'd. This is bad.
+    # @overload initialize(pointer)
+    #  @param [Pointer] pointer
+    #  @return [self]
+    #  The pointer's release() class method will be invoked at GC time.
+    #
+    # @note The safest, and therefore preferred, calling
+    #  idiom is to pass a Method as the second parameter. Example usage:
+    #
+    #   class PointerHelper
+    #     def self.release(pointer)
+    #       ...
+    #     end
+    #   end
+    #
+    #   p = AutoPointer.new(other_pointer, PointerHelper.method(:release))
+    #
+    #  The above code will cause PointerHelper#release to be invoked at GC time.
+    #
+    # @note
+    #  The last calling idiom (only one parameter) is generally only
+    #  going to be useful if you subclass {AutoPointer}, and override
+    #  #release, which by default does nothing.
+    def initialize(ptr, proc=nil, &block)
+      super(ptr.type_size, ptr)
+      raise TypeError, "Invalid pointer" if ptr.nil? || !ptr.kind_of?(Pointer) \
+        || ptr.kind_of?(MemoryPointer) || ptr.kind_of?(AutoPointer)
+
+      @releaser = if proc
+                    raise RuntimeError.new("proc must be callable") unless proc.respond_to?(:call)
+                    CallableReleaser.new(ptr, proc)
+
+                  else
+                    raise RuntimeError.new("no release method defined") unless self.class.respond_to?(:release)
+                    DefaultReleaser.new(ptr, self.class)
+                  end
+
+      ObjectSpace.define_finalizer(self, @releaser)
+      self
+    end
+
+    # @return [nil]
+    # Free the pointer.
+    def free
+      @releaser.free
+    end
+
+    # @param [Boolean] autorelease
+    # @return [Boolean] +autorelease+
+    # Set +autorelease+ property. See {Pointer Autorelease section at Pointer}.
+    def autorelease=(autorelease)
+      @releaser.autorelease=(autorelease)
+    end
+
+    # @return [Boolean] +autorelease+
+    # Get +autorelease+ property. See {Pointer Autorelease section at Pointer}.
+    def autorelease?
+      @releaser.autorelease
+    end
+
+    # @abstract Base class for {AutoPointer}'s releasers.
+    #  
+    #  All subclasses of Releaser should define a +#release(ptr)+ method.
+    # A releaser is an object in charge of release an {AutoPointer}.
+    class Releaser
+      attr_accessor :autorelease
+
+      # @param [Pointer] ptr
+      # @param [#call] proc
+      # @return [nil]
+      # A new instance of Releaser.
+      def initialize(ptr, proc)
+        @ptr = ptr
+        @proc = proc
+        @autorelease = true
+      end
+
+      # @return [nil]
+      # Free pointer.
+      def free
+        if @ptr
+          release(@ptr)
+          @autorelease = false
+          @ptr = nil
+          @proc = nil
+        end
+      end
+
+      # @param args
+      # Release pointer if +autorelease+ is set.
+      def call(*args)
+        release(@ptr) if @autorelease && @ptr
+      end
+      
+    end
+
+    # DefaultReleaser is a {Releaser} used when an {AutoPointer} is defined without Proc
+    # or Method. In this case, the pointer to release must be of a class derived from 
+    # AutoPointer with a +#release+ class method.
+    class DefaultReleaser < Releaser
+      # @param [Pointer] ptr
+      # @return [nil]
+      # Release +ptr+ by using his #release class method.
+      def release(ptr)
+        @proc.release(ptr)
+      end
+    end
+
+    # CallableReleaser is a {Releaser} used when an {AutoPointer} is defined with a
+    # Proc or a Method.
+    class CallableReleaser < Releaser
+      # Release +ptr+ by using Proc or Method defined at +ptr+ {AutoPointer#initialize initialization}.
+      # @param [Pointer] ptr
+      # @return [nil]
+      def release(ptr)
+        @proc.call(ptr)
+      end
+    end
+
+    # Return native type of AutoPointer.
+    #
+    # Override {DataConverter#native_type}.
+    # @return [Type::POINTER]
+    # @raise {RuntimeError} if class does not implement a +#release+ method
+    def self.native_type
+      raise RuntimeError.new("no release method defined for #{self.inspect}") unless self.respond_to?(:release)
+      Type::POINTER
+    end
+
+    # Create a new AutoPointer.
+    #
+    # Override {DataConverter#from_native}.
+    # @overload self.from_native(ptr, ctx)
+    #   @param [Pointer] ptr
+    #   @param ctx not used. Please set +nil+.
+    # @return [AutoPointer]
+    def self.from_native(val, ctx)
+      self.new(val)
+    end
+  end
+
+end
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/buffer.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/buffer.rb
new file mode 100755
index 0000000..449e45b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/buffer.rb
@@ -0,0 +1,4 @@
+#
+# All the code from this file is now implemented in C.  This file remains
+# to satisfy any leftover require 'ffi/buffer' in user code
+#
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/callback.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/callback.rb
new file mode 100755
index 0000000..32d52f7
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/callback.rb
@@ -0,0 +1,4 @@
+#
+# All the code from this file is now implemented in C.  This file remains
+# to satisfy any leftover require 'ffi/callback' in user code
+#
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/enum.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/enum.rb
new file mode 100755
index 0000000..0e84ba7
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/enum.rb
@@ -0,0 +1,174 @@
+#
+# Copyright (C) 2009, 2010 Wayne Meissner
+# Copyright (C) 2009 Luc Heinrich
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+#   may be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+module FFI
+
+  # An instance of this class permits to manage {Enum}s. In fact, Enums is a collection of {Enum}s.
+  class Enums
+
+    # @return [nil]
+    def initialize
+      @all_enums = Array.new
+      @tagged_enums = Hash.new
+      @symbol_map = Hash.new
+    end
+
+    # @param [Enum] enum
+    # Add an {Enum} to the collection.
+    def <<(enum)
+      @all_enums << enum
+      @tagged_enums[enum.tag] = enum unless enum.tag.nil?
+      @symbol_map.merge!(enum.symbol_map)
+    end
+
+    # @param query enum tag or part of an enum name
+    # @return [Enum]
+    # Find a {Enum} in collection.
+    def find(query)
+      if @tagged_enums.has_key?(query)
+        @tagged_enums[query]
+      else
+        @all_enums.detect { |enum| enum.symbols.include?(query) }
+      end
+    end
+
+    # @param symbol a symbol to find in merge symbol maps of all enums.
+    # @return a symbol
+    def __map_symbol(symbol)
+      @symbol_map[symbol]
+    end
+
+  end
+
+  # Represents a C enum.
+  #
+  # For a C enum:
+  #  enum fruits {
+  #    apple,
+  #    banana,
+  #    orange,
+  #    pineapple
+  #  };
+  # are defined this vocabulary:
+  # * a _symbol_ is a word from the enumeration (ie. _apple_, by example);
+  # * a _value_ is the value of a symbol in the enumeration (by example, apple has value _0_ and banana _1_).
+  class Enum
+    include DataConverter
+
+    attr_reader :tag
+    attr_reader :native_type
+
+    # @overload initialize(info, tag=nil)
+    #   @param [nil, Enumerable] info
+    #   @param [nil, Symbol] tag enum tag
+    # @overload initialize(native_type, info, tag=nil)
+    #   @param [FFI::Type] native_type Native type for new Enum
+    #   @param [nil, Enumerable] info symbols and values for new Enum
+    #   @param [nil, Symbol] tag name of new Enum
+    def initialize(*args)
+      @native_type = args.first.kind_of?(FFI::Type) ? args.shift : Type::INT
+      info, @tag = *args
+      @kv_map = Hash.new
+      unless info.nil?
+        last_cst = nil
+        value = 0
+        info.each do |i|
+          case i
+          when Symbol
+            raise ArgumentError, "duplicate enum key" if @kv_map.has_key?(i)
+            @kv_map[i] = value
+            last_cst = i
+            value += 1
+          when Integer
+            @kv_map[last_cst] = i
+            value = i+1
+          end
+        end
+      end
+      @vk_map = @kv_map.invert
+    end
+
+    # @return [Array] enum symbol names
+    def symbols
+      @kv_map.keys
+    end
+
+    # Get a symbol or a value from the enum.
+    # @overload [](query)
+    #  Get enum value from symbol.
+    #  @param [Symbol] query
+    #  @return [Integer]
+    # @overload [](query)
+    #  Get enum symbol from value.
+    #  @param [Integer] query
+    #  @return [Symbol]
+    def [](query)
+      case query
+      when Symbol
+        @kv_map[query]
+      when Integer
+        @vk_map[query]
+      end
+    end
+    alias find []
+
+    # Get the symbol map.
+    # @return [Hash]
+    def symbol_map
+      @kv_map
+    end
+    
+    alias to_h symbol_map
+    alias to_hash symbol_map
+
+    # @param [Symbol, Integer, #to_int] val
+    # @param ctx unused
+    # @return [Integer] value of a enum symbol
+    def to_native(val, ctx)
+      @kv_map[val] || if val.is_a?(Integer)
+        val
+      elsif val.respond_to?(:to_int)
+        val.to_int
+      else
+        raise ArgumentError, "invalid enum value, #{val.inspect}"
+      end
+    end
+
+    # @param val
+    # @return symbol name if it exists for +val+.
+    def from_native(val, ctx)
+      @vk_map[val] || val
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/errno.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/errno.rb
new file mode 100755
index 0000000..de82d89
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/errno.rb
@@ -0,0 +1,43 @@
+#
+# Copyright (C) 2008-2010 Wayne Meissner
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+#   may be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
+
+module FFI
+  # @return (see FFI::LastError.error)
+  # @see FFI::LastError.error
+  def self.errno
+    FFI::LastError.error
+  end
+  # @param error (see FFI::LastError.error=)
+  # @return (see FFI::LastError.error=)
+  # @see FFI::LastError.error=
+  def self.errno=(error)
+    FFI::LastError.error = error
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/ffi.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/ffi.rb
new file mode 100755
index 0000000..11d451f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/ffi.rb
@@ -0,0 +1,44 @@
+#
+# Copyright (C) 2008-2010 JRuby project
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+#   may be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+require 'ffi/platform'
+require 'ffi/types'
+require 'ffi/library'
+require 'ffi/errno'
+require 'ffi/pointer'
+require 'ffi/memorypointer'
+require 'ffi/struct'
+require 'ffi/union'
+require 'ffi/managedstruct'
+require 'ffi/callback'
+require 'ffi/io'
+require 'ffi/autopointer'
+require 'ffi/variadic'
+require 'ffi/enum'
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/io.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/io.rb
new file mode 100755
index 0000000..7fa1cf7
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/io.rb
@@ -0,0 +1,62 @@
+#
+# Copyright (C) 2008, 2009 Wayne Meissner
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+#   may be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
+
+module FFI
+  
+  # This module implements a couple of class methods to play with IO.
+  module IO
+    # @param [Integer] fd file decriptor
+    # @param [String] mode mode string
+    # @return [::IO]
+    # Synonym for IO::for_fd.
+    def self.for_fd(fd, mode = "r")
+      ::IO.for_fd(fd, mode)
+    end
+
+    # @param [#read] io io to read from
+    # @param [AbstractMemory] buf destination for data read from +io+
+    # @param [nil, Numeric] len maximul number of bytes to read from +io+. If +nil+, 
+    #  read until end of file.
+    # @return [Numeric] length really read, in bytes
+    #
+    # A version of IO#read that reads data from an IO and put then into a native buffer.
+    # 
+    # This will be optimized at some future time to eliminate the double copy.
+    #
+    def self.native_read(io, buf, len)
+      tmp = io.read(len)
+      return -1 unless tmp
+      buf.put_bytes(0, tmp)
+      tmp.length
+    end
+
+  end
+end
+
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/library.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/library.rb
new file mode 100755
index 0000000..9849a3a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/library.rb
@@ -0,0 +1,524 @@
+#
+# Copyright (C) 2008-2010 Wayne Meissner
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+#   may be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
+
+module FFI
+  CURRENT_PROCESS = USE_THIS_PROCESS_AS_LIBRARY = Object.new
+
+  # @param [#to_s] lib library name
+  # @return [String] library name formatted for current platform
+  # Transform a generic library name to a platform library name
+  # @example
+  #  # Linux
+  #  FFI.map_library_name 'c'     # -> "libc.so.6"
+  #  FFI.map_library_name 'jpeg'  # -> "libjpeg.so"
+  #  # Windows
+  #  FFI.map_library_name 'c'     # -> "msvcrt.dll"
+  #  FFI.map_library_name 'jpeg'  # -> "jpeg.dll"
+  def self.map_library_name(lib)
+    # Mangle the library name to reflect the native library naming conventions
+    lib = lib.to_s unless lib.kind_of?(String)
+    lib = Library::LIBC if lib == 'c'
+
+    if lib && File.basename(lib) == lib
+      lib = Platform::LIBPREFIX + lib unless lib =~ /^#{Platform::LIBPREFIX}/
+      r = Platform::IS_GNU ? "\\.so($|\\.[1234567890]+)" : "\\.#{Platform::LIBSUFFIX}$"
+      lib += ".#{Platform::LIBSUFFIX}" unless lib =~ /#{r}/
+    end
+
+    lib
+  end
+
+  # Exception raised when a function is not found in libraries
+  class NotFoundError < LoadError
+    def initialize(function, *libraries)
+      super("Function '#{function}' not found in [#{libraries[0].nil? ? 'current process' : libraries.join(", ")}]")
+    end
+  end
+
+  # This module is the base to use native functions.
+  #
+  # A basic usage may be:
+  #  require 'ffi'
+  #  
+  #  module Hello
+  #    extend FFI::Library
+  #    ffi_lib FFI::Library::LIBC
+  #    attach_function 'puts', [ :string ], :int
+  #  end
+  #  
+  #  Hello.puts("Hello, World")
+  #
+  # 
+  module Library
+    CURRENT_PROCESS = FFI::CURRENT_PROCESS
+    LIBC = FFI::Platform::LIBC
+
+    # @param mod extended object
+    # @return [nil]
+    # @raise {RuntimeError} if +mod+ is not a Module
+    # Test if extended object is a Module. If not, raise RuntimeError.
+    def self.extended(mod)
+      raise RuntimeError.new("must only be extended by module") unless mod.kind_of?(Module)
+    end
+
+    
+    # @param [Array] names names of libraries to load
+    # @return [Array<DynamicLibrary>]
+    # @raise {LoadError} if a library cannot be opened
+    # Load native libraries.
+    def ffi_lib(*names)
+      raise LoadError.new("library names list must not be empty") if names.empty?
+
+      lib_flags = defined?(@ffi_lib_flags) ? @ffi_lib_flags : FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL
+      ffi_libs = names.map do |name|
+
+        if name == FFI::CURRENT_PROCESS
+          FFI::DynamicLibrary.open(nil, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL)
+
+        else
+          libnames = (name.is_a?(::Array) ? name : [ name ]).map { |n| [ n, FFI.map_library_name(n) ].uniq }.flatten.compact
+          lib = nil
+          errors = {}
+
+          libnames.each do |libname|
+            begin
+              lib = FFI::DynamicLibrary.open(libname, lib_flags)
+              break if lib
+
+            rescue Exception => ex
+              ldscript = false
+              if ex.message =~ /(([^ \t()])+\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short|invalid file format)/
+                if File.read($1) =~ /(?:GROUP|INPUT) *\( *([^ \)]+)/
+                  libname = $1
+                  ldscript = true
+                end
+              end
+
+              if ldscript
+                retry
+              else
+                errors[libname] = ex
+              end
+            end
+          end
+
+          if lib.nil?
+            raise LoadError.new(errors.values.join(".\n"))
+          end
+
+          # return the found lib
+          lib
+        end
+      end
+
+      @ffi_libs = ffi_libs
+    end
+
+    # Set the calling convention for {#attach_function} and {#callback}
+    #
+    # @see http://en.wikipedia.org/wiki/Stdcall#stdcall
+    # @note +:stdcall+ is typically used for attaching Windows API functions
+    #
+    # @param [Symbol] convention one of +:default+, +:stdcall+
+    # @return [Symbol] the new calling convention
+    def ffi_convention(convention = nil)
+      @ffi_convention ||= :default
+      @ffi_convention = convention if convention
+      @ffi_convention
+    end
+
+    # @see #ffi_lib
+    # @return [Array<FFI::DynamicLibrary>] array of currently loaded FFI libraries
+    # @raise [LoadError] if no libraries have been loaded (using {#ffi_lib})
+    # Get FFI libraries loaded using {#ffi_lib}.
+    def ffi_libraries
+      raise LoadError.new("no library specified") if !defined?(@ffi_libs) || @ffi_libs.empty?
+      @ffi_libs
+    end
+
+    # Flags used in {#ffi_lib}.
+    #
+    # This map allows you to supply symbols to {#ffi_lib_flags} instead of
+    # the actual constants.
+    FlagsMap = {
+      :global => DynamicLibrary::RTLD_GLOBAL,
+      :local => DynamicLibrary::RTLD_LOCAL,
+      :lazy => DynamicLibrary::RTLD_LAZY,
+      :now => DynamicLibrary::RTLD_NOW
+    }
+
+    # Sets library flags for {#ffi_lib}.
+    #
+    # @example
+    #   ffi_lib_flags(:lazy, :local) # => 5
+    #
+    # @param [Symbol, …] flags (see {FlagsMap})
+    # @return [Fixnum] the new value
+    def ffi_lib_flags(*flags)
+      @ffi_lib_flags = flags.inject(0) { |result, f| result | FlagsMap[f] }
+    end
+
+
+    ##
+    # @overload attach_function(func, args, returns, options = {})
+    #  @example attach function without an explicit name
+    #    module Foo
+    #      extend FFI::Library
+    #      ffi_lib FFI::Library::LIBC
+    #      attach_function :malloc, [:size_t], :pointer
+    #    end
+    #    # now callable via Foo.malloc
+    # @overload attach_function(name, func, args, returns, options = {})
+    #  @example attach function with an explicit name
+    #    module Bar
+    #      extend FFI::Library
+    #      ffi_lib FFI::Library::LIBC
+    #      attach_function :c_malloc, :malloc, [:size_t], :pointer
+    #    end
+    #    # now callable via Bar.c_malloc
+    #
+    # Attach C function +func+ to this module.
+    #
+    #
+    # @param [#to_s] name name of ruby method to attach as
+    # @param [#to_s] func name of C function to attach
+    # @param [Array<Symbol>] args an array of types
+    # @param [Symbol] returns type of return value
+    # @option options [Boolean] :blocking (@blocking) set to true if the C function is a blocking call
+    # @option options [Symbol] :convention (:default) calling convention (see {#ffi_convention})
+    # @option options [FFI::Enums] :enums
+    # @option options [Hash] :type_map
+    #
+    # @return [FFI::VariadicInvoker]
+    #
+    # @raise [FFI::NotFoundError] if +func+ cannot be found in the attached libraries (see {#ffi_lib})
+    def attach_function(name, func, args, returns = nil, options = nil)
+      mname, a2, a3, a4, a5 = name, func, args, returns, options
+      cname, arg_types, ret_type, opts = (a4 && (a2.is_a?(String) || a2.is_a?(Symbol))) ? [ a2, a3, a4, a5 ] : [ mname.to_s, a2, a3, a4 ]
+
+      # Convert :foo to the native type
+      arg_types = arg_types.map { |e| find_type(e) }
+      options = {
+        :convention => ffi_convention,
+        :type_map => defined?(@ffi_typedefs) ? @ffi_typedefs : nil,
+        :blocking => defined?(@blocking) && @blocking,
+        :enums => defined?(@ffi_enums) ? @ffi_enums : nil,
+      }
+
+      @blocking = false
+      options.merge!(opts) if opts && opts.is_a?(Hash)
+
+      # Try to locate the function in any of the libraries
+      invokers = []
+      ffi_libraries.each do |lib|
+        if invokers.empty?
+          begin
+            function = nil
+            function_names(cname, arg_types).find do |fname|
+              function = lib.find_function(fname)
+            end
+            raise LoadError unless function
+
+            invokers << if arg_types.length > 0 && arg_types[arg_types.length - 1] == FFI::NativeType::VARARGS
+              VariadicInvoker.new(function, arg_types, find_type(ret_type), options)
+
+            else
+              Function.new(find_type(ret_type), arg_types, function, options)
+            end
+
+          rescue LoadError
+          end
+        end
+      end
+      invoker = invokers.compact.shift
+      raise FFI::NotFoundError.new(cname.to_s, ffi_libraries.map { |lib| lib.name }) unless invoker
+
+      invoker.attach(self, mname.to_s)
+      invoker
+    end
+
+    # @param [#to_s] name function name
+    # @param [Array] arg_types function's argument types
+    # @return [Array<String>]
+    # This function returns a list of possible names to lookup.
+    # @note Function names on windows may be decorated if they are using stdcall. See
+    #   * http://en.wikipedia.org/wiki/Name_mangling#C_name_decoration_in_Microsoft_Windows
+    #   * http://msdn.microsoft.com/en-us/library/zxk0tw93%28v=VS.100%29.aspx
+    #   * http://en.wikibooks.org/wiki/X86_Disassembly/Calling_Conventions#STDCALL
+    #   Note that decorated names can be overridden via def files.  Also note that the
+    #   windows api, although using, doesn't have decorated names.
+    def function_names(name, arg_types)
+      result = [name.to_s]
+      if ffi_convention == :stdcall
+        # Get the size of each parameter
+        size = arg_types.inject(0) do |mem, arg|
+          size = arg.size
+          # The size must be a multiple of 4
+          size += (4 - size) % 4
+          mem + size
+        end
+
+        result << "_#{name.to_s}@#{size}" # win32
+        result << "#{name.to_s}@#{size}" # win64
+      end
+      result
+    end
+
+    # @overload attach_variable(mname, cname, type)
+    #   @param [#to_s] mname name of ruby method to attach as
+    #   @param [#to_s] cname name of C variable to attach
+    #   @param [DataConverter, Struct, Symbol, Type] type C variable's type
+    #   @example
+    #     module Bar
+    #       extend FFI::Library
+    #       ffi_lib 'my_lib'
+    #       attach_variable :c_myvar, :myvar, :long
+    #     end
+    #     # now callable via Bar.c_myvar
+    # @overload attach_variable(cname, type)
+    #   @param [#to_s] mname name of ruby method to attach as
+    #   @param [DataConverter, Struct, Symbol, Type] type C variable's type
+    #   @example
+    #     module Bar
+    #       extend FFI::Library
+    #       ffi_lib 'my_lib'
+    #       attach_variable :myvar, :long
+    #     end
+    #     # now callable via Bar.myvar
+    # @return [DynamicLibrary::Symbol]
+    # @raise {FFI::NotFoundError} if +cname+ cannot be found in libraries
+    #
+    # Attach C variable +cname+ to this module.
+    def attach_variable(mname, a1, a2 = nil)
+      cname, type = a2 ? [ a1, a2 ] : [ mname.to_s, a1 ]
+      address = nil
+      ffi_libraries.each do |lib|
+        begin
+          address = lib.find_variable(cname.to_s)
+          break unless address.nil?
+        rescue LoadError
+        end
+      end
+
+      raise FFI::NotFoundError.new(cname, ffi_libraries) if address.nil? || address.null?
+      if type.is_a?(Class) && type < FFI::Struct
+        # If it is a global struct, just attach directly to the pointer
+        s = type.new(address)
+        self.module_eval <<-code, __FILE__, __LINE__
+          @@ffi_gvar_#{mname} = s
+          def self.#{mname}
+            @@ffi_gvar_#{mname}
+          end
+        code
+
+      else
+        sc = Class.new(FFI::Struct)
+        sc.layout :gvar, find_type(type)
+        s = sc.new(address)
+        #
+        # Attach to this module as mname/mname=
+        #
+        self.module_eval <<-code, __FILE__, __LINE__
+          @@ffi_gvar_#{mname} = s
+          def self.#{mname}
+            @@ffi_gvar_#{mname}[:gvar]
+          end
+          def self.#{mname}=(value)
+            @@ffi_gvar_#{mname}[:gvar] = value
+          end
+        code
+
+      end
+
+      address
+    end
+
+
+    # @overload callback(name, params, ret)
+    #   @param name callback name to add to type map
+    #   @param [Array] params array of parameters' types
+    #   @param [DataConverter, Struct, Symbol, Type] ret callback return type
+    # @overload callback(params, ret)
+    #   @param [Array] params array of parameters' types
+    #   @param [DataConverter, Struct, Symbol, Type] ret callback return type
+    # @return [FFI::CallbackInfo]
+    def callback(*args)
+      raise ArgumentError, "wrong number of arguments" if args.length < 2 || args.length > 3
+      name, params, ret = if args.length == 3
+        args
+      else
+        [ nil, args[0], args[1] ]
+      end
+
+      native_params = params.map { |e| find_type(e) }
+      raise ArgumentError, "callbacks cannot have variadic parameters" if native_params.include?(FFI::Type::VARARGS)
+      options = Hash.new
+      options[:convention] = ffi_convention
+      options[:enums] = @ffi_enums if defined?(@ffi_enums)
+      cb = FFI::CallbackInfo.new(find_type(ret), native_params, options)
+
+      # Add to the symbol -> type map (unless there was no name)
+      unless name.nil?
+        typedef cb, name
+      end
+
+      cb
+    end
+
+    # Register or get an already registered type definition.
+    #
+    # To register a new type definition, +old+ should be a {FFI::Type}. +add+
+    # is in this case the type definition.
+    #
+    # If +old+ is a {DataConverter}, a {Type::Mapped} is returned.
+    #
+    # If +old+ is +:enum+
+    # * and +add+ is an +Array+, a call to {#enum} is made with +add+ as single parameter;
+    # * in others cases, +info+ is used to create a named enum.
+    #
+    # If +old+ is a key for type map, #typedef get +old+ type definition.
+    #
+    # @param [DataConverter, Symbol, Type] old
+    # @param [Symbol] add
+    # @param [Symbol] info
+    # @return [FFI::Enum, FFI::Type]
+    def typedef(old, add, info=nil)
+      @ffi_typedefs = Hash.new unless defined?(@ffi_typedefs)
+
+      @ffi_typedefs[add] = if old.kind_of?(FFI::Type)
+        old
+
+      elsif @ffi_typedefs.has_key?(old)
+        @ffi_typedefs[old]
+
+      elsif old.is_a?(DataConverter)
+        FFI::Type::Mapped.new(old)
+
+      elsif old == :enum
+        if add.kind_of?(Array)
+          self.enum(add)
+        else
+          self.enum(info, add)
+        end
+
+      else
+        FFI.find_type(old)
+      end
+    end
+
+    # @overload enum(name, values)
+    #  Create a named enum.
+    #  @example
+    #   enum :foo, [:zero, :one, :two]  # named enum
+    #  @param [Symbol] name name for new enum
+    #  @param [Array] values values for enum
+    # @overload enum(*args)
+    #  Create an unnamed enum.
+    #  @example
+    #   enum :zero, :one, :two  # unnamed enum
+    #  @param args values for enum
+    # @overload enum(values)
+    #  Create an unnamed enum.
+    #  @example
+    #   enum [:zero, :one, :two]  # unnamed enum, equivalent to above example
+    #  @param [Array] values values for enum
+    # @overload enum(native_type, name, values)
+    #  Create a named enum and specify the native type.
+    #  @example
+    #   enum FFI::Type::UINT64, :foo, [:zero, :one, :two]  # named enum
+    #  @param [FFI::Type] native_type native type for new enum
+    #  @param [Symbol] name name for new enum
+    #  @param [Array] values values for enum
+    # @overload enum(native_type, *args)
+    #  Create an unnamed enum and specify the native type.
+    #  @example
+    #   enum FFI::Type::UINT64, :zero, :one, :two  # unnamed enum
+    #  @param [FFI::Type] native_type native type for new enum
+    #  @param args values for enum
+    # @overload enum(native_type, values)
+    #  Create an unnamed enum and specify the native type.
+    #  @example
+    #   enum Type::UINT64, [:zero, :one, :two]  # unnamed enum, equivalent to above example
+    #  @param [FFI::Type] native_type native type for new enum
+    #  @param [Array] values values for enum
+    # @return [FFI::Enum]
+    # Create a new {FFI::Enum}.
+    def enum(*args)
+      native_type = args.first.kind_of?(FFI::Type) ? args.shift : nil
+      name, values = if args[0].kind_of?(Symbol) && args[1].kind_of?(Array)
+        [ args[0], args[1] ]
+      elsif args[0].kind_of?(Array)
+        [ nil, args[0] ]
+      else
+        [ nil, args ]
+      end
+      @ffi_enums = FFI::Enums.new unless defined?(@ffi_enums)
+      @ffi_enums << (e = native_type ? FFI::Enum.new(native_type, values, name) : FFI::Enum.new(values, name))
+
+      # If called as enum :foo, [ :zero, :one, :two ], add a typedef alias
+      typedef(e, name) if name
+      e
+    end
+
+    # @param name
+    # @return [FFI::Enum]
+    # Find an enum by name.
+    def enum_type(name)
+      @ffi_enums.find(name) if defined?(@ffi_enums)
+    end
+
+    # @param symbol
+    # @return [FFI::Enum]
+    # Find an enum by a symbol it contains.
+    def enum_value(symbol)
+      @ffi_enums.__map_symbol(symbol)
+    end
+
+    # @param [DataConverter, Type, Struct, Symbol] t type to find
+    # @return [Type]
+    # Find a type definition.
+    def find_type(t)
+      if t.kind_of?(Type)
+        t
+
+      elsif defined?(@ffi_typedefs) && @ffi_typedefs.has_key?(t)
+        @ffi_typedefs[t]
+
+      elsif t.is_a?(Class) && t < Struct
+        Type::POINTER
+
+      elsif t.is_a?(DataConverter)
+        # Add a typedef so next time the converter is used, it hits the cache
+        typedef Type::Mapped.new(t), t
+
+      end || FFI.find_type(t)
+    end
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/managedstruct.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/managedstruct.rb
new file mode 100755
index 0000000..0536280
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/managedstruct.rb
@@ -0,0 +1,84 @@
+# Copyright (C) 2008 Mike Dalessio
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+#   may be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+module FFI
+  #
+  # FFI::ManagedStruct allows custom garbage-collection of your FFI::Structs.
+  #
+  # The typical use case would be when interacting with a library
+  # that has a nontrivial memory management design, such as a linked
+  # list or a binary tree.
+  #
+  # When the {Struct} instance is garbage collected, FFI::ManagedStruct will
+  # invoke the class's release() method during object finalization.
+  #
+  # @example Example usage:
+  #  module MyLibrary
+  #    ffi_lib "libmylibrary"
+  #    attach_function :new_dlist, [], :pointer
+  #    attach_function :destroy_dlist, [:pointer], :void
+  #  end
+  #  
+  #  class DoublyLinkedList < FFI::ManagedStruct
+  #    @@@
+  #    struct do |s|
+  #      s.name 'struct dlist'
+  #      s.include 'dlist.h'
+  #      s.field :head, :pointer
+  #      s.field :tail, :pointer
+  #    end
+  #    @@@
+  #
+  #    def self.release ptr
+  #      MyLibrary.destroy_dlist(ptr)
+  #    end
+  #  end
+  #
+  #  begin
+  #    ptr = DoublyLinkedList.new(MyLibrary.new_dlist)
+  #    #  do something with the list
+  #  end
+  #  # struct is out of scope, and will be GC'd using DoublyLinkedList#release
+  #
+  #
+  class ManagedStruct < FFI::Struct
+
+    # @overload initialize(pointer)
+    #  @param [Pointer] pointer
+    #  Create a new ManagedStruct which will invoke the class method #release on 
+    # @overload initialize
+    # A new instance of FFI::ManagedStruct.
+    def initialize(pointer=nil)
+      raise NoMethodError, "release() not implemented for class #{self}" unless self.class.respond_to? :release
+      raise ArgumentError, "Must supply a pointer to memory for the Struct" unless pointer
+      super AutoPointer.new(pointer, self.class.method(:release))
+    end
+
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/memorypointer.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/memorypointer.rb
new file mode 100755
index 0000000..9f07bc6
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/memorypointer.rb
@@ -0,0 +1 @@
+# This class is now implemented in C
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/platform.rb
new file mode 100755
index 0000000..7393459
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform.rb
@@ -0,0 +1,159 @@
+#
+# Copyright (C) 2008, 2009 Wayne Meissner
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+#   may be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
+
+require 'rbconfig'
+module FFI
+  class PlatformError < LoadError; end
+
+  # This module defines different constants and class methods to play with
+  # various platforms.
+  module Platform
+    OS = case RbConfig::CONFIG['host_os'].downcase
+    when /linux/
+      "linux"
+    when /darwin/
+      "darwin"
+    when /freebsd/
+      "freebsd"
+    when /netbsd/
+      "netbsd"
+    when /openbsd/
+      "openbsd"
+    when /sunos|solaris/
+      "solaris"
+    when /mingw|mswin/
+      "windows"
+    else
+      RbConfig::CONFIG['host_os'].downcase
+    end
+
+    ARCH = case CPU.downcase
+    when /amd64|x86_64/
+      "x86_64"
+    when /i?86|x86|i86pc/
+      "i386"
+    when /ppc64|powerpc64/
+      "powerpc64"
+    when /ppc|powerpc/
+      "powerpc"
+    else
+      case RbConfig::CONFIG['host_cpu']
+      when /^arm/
+        "arm"
+      else
+        RbConfig::CONFIG['host_cpu']
+      end
+    end
+
+    private
+    # @param [String) os
+    # @return [Boolean]
+    # Test if current OS is +os+.
+    def self.is_os(os)
+      OS == os
+    end
+
+    NAME = "#{ARCH}-#{OS}"
+    IS_GNU = defined?(GNU_LIBC)
+    IS_LINUX = is_os("linux")
+    IS_MAC = is_os("darwin")
+    IS_FREEBSD = is_os("freebsd")
+    IS_NETBSD = is_os("netbsd")
+    IS_OPENBSD = is_os("openbsd")
+    IS_SOLARIS = is_os("solaris")
+    IS_WINDOWS = is_os("windows")
+    IS_BSD = IS_MAC || IS_FREEBSD || IS_NETBSD || IS_OPENBSD
+    CONF_DIR = File.join(File.dirname(__FILE__), 'platform', NAME)
+
+    public
+
+    LIBPREFIX = case OS
+    when /windows/
+      ''
+    when /cygwin/
+      'cyg'
+    else
+      'lib'
+    end
+
+    LIBSUFFIX = case OS
+    when /darwin/
+      'dylib'
+    when /linux|bsd|solaris/
+      'so'
+    when /windows|cygwin/
+      'dll'
+    else
+      # Punt and just assume a sane unix (i.e. anything but AIX)
+      'so'
+    end
+
+    LIBC = if IS_WINDOWS
+      RbConfig::CONFIG['RUBY_SO_NAME'].split('-')[-2] + '.dll'
+    elsif IS_GNU
+      GNU_LIBC
+    elsif OS == 'cygwin'
+      "cygwin1.dll"
+    else
+      "#{LIBPREFIX}c.#{LIBSUFFIX}"
+    end
+
+    # Test if current OS is a *BSD (include MAC)
+    # @return [Boolean]
+    def self.bsd?
+      IS_BSD
+    end
+
+    # Test if current OS is Windows
+    # @return [Boolean]
+    def self.windows?
+      IS_WINDOWS
+    end
+
+    # Test if current OS is Mac OS
+    # @return [Boolean]
+    def self.mac?
+      IS_MAC
+    end
+
+    # Test if current OS is Solaris (Sun OS)
+    # @return [Boolean]
+    def self.solaris?
+      IS_SOLARIS
+    end
+
+    # Test if current OS is a unix OS
+    # @return [Boolean]
+    def self.unix?
+      !IS_WINDOWS
+    end
+  end
+end
+
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/aarch64-linux/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/aarch64-linux/types.conf
new file mode 100755
index 0000000..072c419
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/aarch64-linux/types.conf
@@ -0,0 +1,104 @@
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long
+rbx.platform.typedef.__uint64_t = ulong
+rbx.platform.typedef.__quad_t = long
+rbx.platform.typedef.__u_quad_t = ulong
+rbx.platform.typedef.__dev_t = ulong
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__ino64_t = ulong
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__off64_t = long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlim64_t = ulong
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.__blksize_t = int
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blkcnt64_t = long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsblkcnt64_t = ulong
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong
+rbx.platform.typedef.__fsword_t = long
+rbx.platform.typedef.__ssize_t = long
+rbx.platform.typedef.__syscall_slong_t = long
+rbx.platform.typedef.__syscall_ulong_t = ulong
+rbx.platform.typedef.__loff_t = long
+rbx.platform.typedef.*__qaddr_t = long
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__intptr_t = long
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.quad_t = long
+rbx.platform.typedef.u_quad_t = ulong
+rbx.platform.typedef.loff_t = long
+rbx.platform.typedef.ino_t = ulong
+rbx.platform.typedef.dev_t = ulong
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.off_t = long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.blksize_t = int
+rbx.platform.typedef.blkcnt_t = long
+rbx.platform.typedef.fsblkcnt_t = ulong
+rbx.platform.typedef.fsfilcnt_t = ulong
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.rlim_t = ulong
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__priority_which_t = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/arm-linux/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/arm-linux/types.conf
new file mode 100755
index 0000000..e9a923b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/arm-linux/types.conf
@@ -0,0 +1,104 @@
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__quad_t = long_long
+rbx.platform.typedef.__u_quad_t = ulong_long
+rbx.platform.typedef.__dev_t = ulong_long
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__in_addr_t = uint
+rbx.platform.typedef.__in_port_t = ushort
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__ino64_t = ulong_long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__off64_t = long_long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlim64_t = ulong_long
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__swblk_t = long
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.__blksize_t = long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blkcnt64_t = long_long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsblkcnt64_t = ulong_long
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong_long
+rbx.platform.typedef.__ssize_t = int
+rbx.platform.typedef.__loff_t = long_long
+rbx.platform.typedef.*__qaddr_t = long_long
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__intptr_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.loff_t = long_long
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.dev_t = ulong_long
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ssize_t = int
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.size_t = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.fsblkcnt_t = ulong_long
+rbx.platform.typedef.fsfilcnt_t = ulong_long
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__priority_which_t = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-cygwin/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-cygwin/types.conf
new file mode 100755
index 0000000..cd3cc38
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-cygwin/types.conf
@@ -0,0 +1,3 @@
+rbx.platform.typedef.size_t = uint
+rbx.platform.typedef.ptrdiff_t = int
+rbx.platform.typedef.ssize_t = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-darwin/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-darwin/types.conf
new file mode 100755
index 0000000..6b9313e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-darwin/types.conf
@@ -0,0 +1,100 @@
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__darwin_intptr_t = long
+rbx.platform.typedef.__darwin_natural_t = uint
+rbx.platform.typedef.__darwin_ct_rune_t = int
+rbx.platform.typedef.__darwin_ptrdiff_t = int
+rbx.platform.typedef.__darwin_size_t = ulong
+rbx.platform.typedef.__darwin_wchar_t = int
+rbx.platform.typedef.__darwin_rune_t = int
+rbx.platform.typedef.__darwin_wint_t = int
+rbx.platform.typedef.__darwin_clock_t = ulong
+rbx.platform.typedef.__darwin_socklen_t = uint
+rbx.platform.typedef.__darwin_ssize_t = long
+rbx.platform.typedef.__darwin_time_t = long
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = int
+rbx.platform.typedef.intptr_t = long
+rbx.platform.typedef.uintptr_t = ulong
+rbx.platform.typedef.user_addr_t = ulong_long
+rbx.platform.typedef.user_size_t = ulong_long
+rbx.platform.typedef.user_ssize_t = long_long
+rbx.platform.typedef.user_long_t = long_long
+rbx.platform.typedef.user_ulong_t = ulong_long
+rbx.platform.typedef.user_time_t = long_long
+rbx.platform.typedef.syscall_arg_t = ulong_long
+rbx.platform.typedef.__darwin_blkcnt_t = long_long
+rbx.platform.typedef.__darwin_blksize_t = int
+rbx.platform.typedef.__darwin_dev_t = int
+rbx.platform.typedef.__darwin_fsblkcnt_t = uint
+rbx.platform.typedef.__darwin_fsfilcnt_t = uint
+rbx.platform.typedef.__darwin_gid_t = uint
+rbx.platform.typedef.__darwin_id_t = uint
+rbx.platform.typedef.__darwin_ino64_t = ulong_long
+rbx.platform.typedef.__darwin_ino_t = ulong_long
+rbx.platform.typedef.__darwin_mach_port_name_t = uint
+rbx.platform.typedef.__darwin_mach_port_t = uint
+rbx.platform.typedef.__darwin_mode_t = ushort
+rbx.platform.typedef.__darwin_off_t = long_long
+rbx.platform.typedef.__darwin_pid_t = int
+rbx.platform.typedef.__darwin_pthread_key_t = ulong
+rbx.platform.typedef.__darwin_sigset_t = uint
+rbx.platform.typedef.__darwin_suseconds_t = int
+rbx.platform.typedef.__darwin_uid_t = uint
+rbx.platform.typedef.__darwin_useconds_t = uint
+rbx.platform.typedef.__darwin_uuid_t[16] = uchar
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.qaddr_t = pointer
+rbx.platform.typedef.caddr_t = string
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.dev_t = int
+rbx.platform.typedef.fixpt_t = uint
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.blksize_t = int
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.ino64_t = ulong_long
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.mode_t = ushort
+rbx.platform.typedef.nlink_t = ushort
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.segsz_t = int
+rbx.platform.typedef.swblk_t = int
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.clock_t = ulong
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.useconds_t = uint
+rbx.platform.typedef.suseconds_t = int
+rbx.platform.typedef.fd_mask = int
+rbx.platform.typedef.pthread_key_t = ulong
+rbx.platform.typedef.fsblkcnt_t = uint
+rbx.platform.typedef.fsfilcnt_t = uint
+rbx.platform.typedef.sa_family_t = uchar
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.rlim_t = ulong_long
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-freebsd/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-freebsd/types.conf
new file mode 100755
index 0000000..3e7b20d
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-freebsd/types.conf
@@ -0,0 +1,152 @@
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__clock_t = ulong
+rbx.platform.typedef.__cpumask_t = uint
+rbx.platform.typedef.__critical_t = int
+rbx.platform.typedef.__intfptr_t = int
+rbx.platform.typedef.__intmax_t = long_long
+rbx.platform.typedef.__intptr_t = int
+rbx.platform.typedef.__int_fast8_t = int
+rbx.platform.typedef.__int_fast16_t = int
+rbx.platform.typedef.__int_fast32_t = int
+rbx.platform.typedef.__int_fast64_t = long_long
+rbx.platform.typedef.__int_least8_t = char
+rbx.platform.typedef.__int_least16_t = short
+rbx.platform.typedef.__int_least32_t = int
+rbx.platform.typedef.__int_least64_t = long_long
+rbx.platform.typedef.__ptrdiff_t = int
+rbx.platform.typedef.__register_t = int
+rbx.platform.typedef.__segsz_t = int
+rbx.platform.typedef.__size_t = uint
+rbx.platform.typedef.__ssize_t = int
+rbx.platform.typedef.__time_t = int
+rbx.platform.typedef.__uintfptr_t = uint
+rbx.platform.typedef.__uintmax_t = ulong_long
+rbx.platform.typedef.__uintptr_t = uint
+rbx.platform.typedef.__uint_fast8_t = uint
+rbx.platform.typedef.__uint_fast16_t = uint
+rbx.platform.typedef.__uint_fast32_t = uint
+rbx.platform.typedef.__uint_fast64_t = ulong_long
+rbx.platform.typedef.__uint_least8_t = uchar
+rbx.platform.typedef.__uint_least16_t = ushort
+rbx.platform.typedef.__uint_least32_t = uint
+rbx.platform.typedef.__uint_least64_t = ulong_long
+rbx.platform.typedef.__u_register_t = uint
+rbx.platform.typedef.__vm_offset_t = uint
+rbx.platform.typedef.__vm_ooffset_t = long_long
+rbx.platform.typedef.__vm_paddr_t = uint
+rbx.platform.typedef.__vm_pindex_t = ulong_long
+rbx.platform.typedef.__vm_size_t = uint
+rbx.platform.typedef.__blksize_t = uint
+rbx.platform.typedef.__blkcnt_t = long_long
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__fflags_t = uint
+rbx.platform.typedef.__fsblkcnt_t = ulong_long
+rbx.platform.typedef.__fsfilcnt_t = ulong_long
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__id_t = long_long
+rbx.platform.typedef.__ino_t = uint
+rbx.platform.typedef.__key_t = long
+rbx.platform.typedef.__lwpid_t = int
+rbx.platform.typedef.__mode_t = ushort
+rbx.platform.typedef.__accmode_t = int
+rbx.platform.typedef.__nl_item = int
+rbx.platform.typedef.__nlink_t = ushort
+rbx.platform.typedef.__off_t = long_long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__rlim_t = long_long
+rbx.platform.typedef.__sa_family_t = uchar
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__cpuwhich_t = int
+rbx.platform.typedef.__cpulevel_t = int
+rbx.platform.typedef.__cpusetid_t = int
+rbx.platform.typedef.__ct_rune_t = int
+rbx.platform.typedef.__rune_t = int
+rbx.platform.typedef.__wchar_t = int
+rbx.platform.typedef.__wint_t = int
+rbx.platform.typedef.__wint_t = int
+rbx.platform.typedef.__dev_t = uint
+rbx.platform.typedef.__fixpt_t = uint
+rbx.platform.typedef.pthread_key_t = int
+rbx.platform.typedef.*) = pointer
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.uint32_t = uint
+rbx.platform.typedef.uint64_t = ulong_long
+rbx.platform.typedef.intptr_t = int
+rbx.platform.typedef.uintptr_t = uint
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.qaddr_t = pointer
+rbx.platform.typedef.caddr_t = string
+rbx.platform.typedef.c_caddr_t = pointer
+rbx.platform.typedef.blksize_t = uint
+rbx.platform.typedef.cpuwhich_t = int
+rbx.platform.typedef.cpulevel_t = int
+rbx.platform.typedef.cpusetid_t = int
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.clock_t = ulong
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.cpumask_t = uint
+rbx.platform.typedef.critical_t = int
+rbx.platform.typedef.daddr_t = long_long
+rbx.platform.typedef.dev_t = uint
+rbx.platform.typedef.fflags_t = uint
+rbx.platform.typedef.fixpt_t = uint
+rbx.platform.typedef.fsblkcnt_t = ulong_long
+rbx.platform.typedef.fsfilcnt_t = ulong_long
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.id_t = long_long
+rbx.platform.typedef.ino_t = uint
+rbx.platform.typedef.key_t = long
+rbx.platform.typedef.lwpid_t = int
+rbx.platform.typedef.mode_t = ushort
+rbx.platform.typedef.accmode_t = int
+rbx.platform.typedef.nlink_t = ushort
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.register_t = int
+rbx.platform.typedef.rlim_t = long_long
+rbx.platform.typedef.segsz_t = int
+rbx.platform.typedef.size_t = uint
+rbx.platform.typedef.ssize_t = int
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.time_t = int
+rbx.platform.typedef.u_register_t = uint
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.useconds_t = uint
+rbx.platform.typedef.vm_offset_t = uint
+rbx.platform.typedef.vm_ooffset_t = long_long
+rbx.platform.typedef.vm_paddr_t = uint
+rbx.platform.typedef.vm_pindex_t = ulong_long
+rbx.platform.typedef.vm_size_t = uint
+rbx.platform.typedef.__fd_mask = ulong
+rbx.platform.typedef.fd_mask = ulong
+rbx.platform.typedef.sa_family_t = uchar
+rbx.platform.typedef.socklen_t = uint
+
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-gnu/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-gnu/types.conf
new file mode 100755
index 0000000..f9169c2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-gnu/types.conf
@@ -0,0 +1,107 @@
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__quad_t = long_long
+rbx.platform.typedef.__u_quad_t = ulong_long
+rbx.platform.typedef.__dev_t = uint
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__ino64_t = ulong_long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__off64_t = long_long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__fsid_t = ulong_long
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlim64_t = ulong_long
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__swblk_t = long
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__timer_t = int
+rbx.platform.typedef.__blksize_t = long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blkcnt64_t = long_long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsblkcnt64_t = ulong_long
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong_long
+rbx.platform.typedef.__ssize_t = int
+rbx.platform.typedef.__loff_t = long_long
+rbx.platform.typedef.*__qaddr_t = long_long
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__intptr_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.fsid_t = ulong_long
+rbx.platform.typedef.loff_t = long_long
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.dev_t = uint
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ssize_t = int
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = int
+rbx.platform.typedef.size_t = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.__sigset_t = ulong
+rbx.platform.typedef.sigset_t = ulong
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.fsblkcnt_t = ulong_long
+rbx.platform.typedef.fsfilcnt_t = ulong_long
+rbx.platform.typedef.__pthread_t = int
+rbx.platform.typedef.pthread_t = int
+rbx.platform.typedef.__pthread_key = int
+rbx.platform.typedef.pthread_key_t = int
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.sa_family_t = uchar
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__priority_which_t = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-linux/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-linux/types.conf
new file mode 100755
index 0000000..c46a134
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-linux/types.conf
@@ -0,0 +1,103 @@
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__quad_t = long_long
+rbx.platform.typedef.__u_quad_t = ulong_long
+rbx.platform.typedef.__dev_t = ulong_long
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__ino64_t = ulong_long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__off64_t = long_long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlim64_t = ulong_long
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__swblk_t = long
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.__blksize_t = long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blkcnt64_t = long_long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsblkcnt64_t = ulong_long
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong_long
+rbx.platform.typedef.__ssize_t = int
+rbx.platform.typedef.__loff_t = long_long
+rbx.platform.typedef.*__qaddr_t = long_long
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__intptr_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.loff_t = long_long
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.dev_t = ulong_long
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ssize_t = int
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.size_t = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.fsblkcnt_t = ulong_long
+rbx.platform.typedef.fsfilcnt_t = ulong_long
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__priority_which_t = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-netbsd/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-netbsd/types.conf
new file mode 100755
index 0000000..33bd12b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-netbsd/types.conf
@@ -0,0 +1,126 @@
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__int_least8_t = char
+rbx.platform.typedef.__uint_least8_t = uchar
+rbx.platform.typedef.__int_least16_t = short
+rbx.platform.typedef.__uint_least16_t = ushort
+rbx.platform.typedef.__int_least32_t = int
+rbx.platform.typedef.__uint_least32_t = uint
+rbx.platform.typedef.__int_least64_t = long_long
+rbx.platform.typedef.__uint_least64_t = ulong_long
+rbx.platform.typedef.__int_fast8_t = int
+rbx.platform.typedef.__uint_fast8_t = uint
+rbx.platform.typedef.__int_fast16_t = int
+rbx.platform.typedef.__uint_fast16_t = uint
+rbx.platform.typedef.__int_fast32_t = int
+rbx.platform.typedef.__uint_fast32_t = uint
+rbx.platform.typedef.__int_fast64_t = long_long
+rbx.platform.typedef.__uint_fast64_t = ulong_long
+rbx.platform.typedef.__intptr_t = long
+rbx.platform.typedef.__uintptr_t = ulong
+rbx.platform.typedef.__intmax_t = long_long
+rbx.platform.typedef.__uintmax_t = ulong_long
+rbx.platform.typedef.__register_t = int
+rbx.platform.typedef.__vaddr_t = ulong
+rbx.platform.typedef.__paddr_t = ulong
+rbx.platform.typedef.__vsize_t = ulong
+rbx.platform.typedef.__psize_t = ulong
+rbx.platform.typedef.__clock_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__off_t = long_long
+rbx.platform.typedef.__ptrdiff_t = long
+rbx.platform.typedef.__size_t = ulong
+rbx.platform.typedef.__ssize_t = long
+rbx.platform.typedef.__time_t = int
+rbx.platform.typedef.__timer_t = int
+rbx.platform.typedef.__wchar_t = int
+rbx.platform.typedef.__wint_t = int
+rbx.platform.typedef.__rune_t = int
+rbx.platform.typedef.__wctrans_t = pointer
+rbx.platform.typedef.__wctype_t = pointer
+rbx.platform.typedef.__cpuid_t = ulong
+rbx.platform.typedef.__dev_t = int
+rbx.platform.typedef.__fixpt_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__in_addr_t = uint
+rbx.platform.typedef.__in_port_t = ushort
+rbx.platform.typedef.__ino_t = uint
+rbx.platform.typedef.__key_t = long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__rlim_t = ulong_long
+rbx.platform.typedef.__sa_family_t = uchar
+rbx.platform.typedef.__segsz_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.__swblk_t = int
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = int
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.unchar = uchar
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.cpuid_t = ulong
+rbx.platform.typedef.register_t = int
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.uint32_t = uint
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.uint64_t = ulong_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.qaddr_t = pointer
+rbx.platform.typedef.vaddr_t = ulong
+rbx.platform.typedef.paddr_t = ulong
+rbx.platform.typedef.vsize_t = ulong
+rbx.platform.typedef.psize_t = ulong
+rbx.platform.typedef.caddr_t = string
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.daddr32_t = int
+rbx.platform.typedef.daddr64_t = long_long
+rbx.platform.typedef.dev_t = int
+rbx.platform.typedef.fixpt_t = uint
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ino_t = uint
+rbx.platform.typedef.key_t = long
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.segsz_t = int
+rbx.platform.typedef.swblk_t = int
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.useconds_t = uint
+rbx.platform.typedef.suseconds_t = int
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.sa_family_t = uchar
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.clock_t = int
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.time_t = int
+rbx.platform.typedef.timer_t = int
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.__fd_mask = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-openbsd/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-openbsd/types.conf
new file mode 100755
index 0000000..c4df68a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-openbsd/types.conf
@@ -0,0 +1,128 @@
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__int_least8_t = char
+rbx.platform.typedef.__uint_least8_t = uchar
+rbx.platform.typedef.__int_least16_t = short
+rbx.platform.typedef.__uint_least16_t = ushort
+rbx.platform.typedef.__int_least32_t = int
+rbx.platform.typedef.__uint_least32_t = uint
+rbx.platform.typedef.__int_least64_t = long_long
+rbx.platform.typedef.__uint_least64_t = ulong_long
+rbx.platform.typedef.__int_fast8_t = int
+rbx.platform.typedef.__uint_fast8_t = uint
+rbx.platform.typedef.__int_fast16_t = int
+rbx.platform.typedef.__uint_fast16_t = uint
+rbx.platform.typedef.__int_fast32_t = int
+rbx.platform.typedef.__uint_fast32_t = uint
+rbx.platform.typedef.__int_fast64_t = long_long
+rbx.platform.typedef.__uint_fast64_t = ulong_long
+rbx.platform.typedef.__intptr_t = long
+rbx.platform.typedef.__uintptr_t = ulong
+rbx.platform.typedef.__intmax_t = long_long
+rbx.platform.typedef.__uintmax_t = ulong_long
+rbx.platform.typedef.__register_t = int
+rbx.platform.typedef.__vaddr_t = ulong
+rbx.platform.typedef.__paddr_t = ulong
+rbx.platform.typedef.__vsize_t = ulong
+rbx.platform.typedef.__psize_t = ulong
+rbx.platform.typedef.__clock_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__off_t = long_long
+rbx.platform.typedef.__ptrdiff_t = long
+rbx.platform.typedef.__size_t = ulong
+rbx.platform.typedef.__ssize_t = long
+rbx.platform.typedef.__time_t = int
+rbx.platform.typedef.__timer_t = int
+rbx.platform.typedef.__wchar_t = int
+rbx.platform.typedef.__wint_t = int
+rbx.platform.typedef.__rune_t = int
+rbx.platform.typedef.__wctrans_t = pointer
+rbx.platform.typedef.__wctype_t = pointer
+rbx.platform.typedef.__cpuid_t = ulong
+rbx.platform.typedef.__dev_t = int
+rbx.platform.typedef.__fixpt_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__in_addr_t = uint
+rbx.platform.typedef.__in_port_t = ushort
+rbx.platform.typedef.__ino_t = uint
+rbx.platform.typedef.__key_t = long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__rlim_t = ulong_long
+rbx.platform.typedef.__sa_family_t = uchar
+rbx.platform.typedef.__segsz_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.__swblk_t = int
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = int
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.unchar = uchar
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.cpuid_t = ulong
+rbx.platform.typedef.register_t = int
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.uint32_t = uint
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.uint64_t = ulong_long
+rbx.platform.typedef.intptr_t = long
+rbx.platform.typedef.uintptr_t = ulong
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.qaddr_t = pointer
+rbx.platform.typedef.vaddr_t = ulong
+rbx.platform.typedef.paddr_t = ulong
+rbx.platform.typedef.vsize_t = ulong
+rbx.platform.typedef.psize_t = ulong
+rbx.platform.typedef.caddr_t = string
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.daddr32_t = int
+rbx.platform.typedef.daddr64_t = long_long
+rbx.platform.typedef.dev_t = int
+rbx.platform.typedef.fixpt_t = uint
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ino_t = uint
+rbx.platform.typedef.key_t = long
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.segsz_t = int
+rbx.platform.typedef.swblk_t = int
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.useconds_t = uint
+rbx.platform.typedef.suseconds_t = int
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.sa_family_t = uchar
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.clock_t = int
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.time_t = int
+rbx.platform.typedef.timer_t = int
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.__fd_mask = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-solaris/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-solaris/types.conf
new file mode 100755
index 0000000..a585100
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-solaris/types.conf
@@ -0,0 +1,122 @@
+rbx.platform.typedef.lock_t = uchar
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.uint32_t = uint
+rbx.platform.typedef.uint64_t = ulong_long
+rbx.platform.typedef.intmax_t = long_long
+rbx.platform.typedef.uintmax_t = ulong_long
+rbx.platform.typedef.intptr_t = int
+rbx.platform.typedef.uintptr_t = uint
+rbx.platform.typedef.int_fast8_t = char
+rbx.platform.typedef.int_fast16_t = int
+rbx.platform.typedef.int_fast32_t = int
+rbx.platform.typedef.int_fast64_t = long_long
+rbx.platform.typedef.uint_fast8_t = uchar
+rbx.platform.typedef.uint_fast16_t = uint
+rbx.platform.typedef.uint_fast32_t = uint
+rbx.platform.typedef.uint_fast64_t = ulong_long
+rbx.platform.typedef.int_least8_t = char
+rbx.platform.typedef.int_least16_t = short
+rbx.platform.typedef.int_least32_t = int
+rbx.platform.typedef.int_least64_t = long_long
+rbx.platform.typedef.uint_least8_t = uchar
+rbx.platform.typedef.uint_least16_t = ushort
+rbx.platform.typedef.uint_least32_t = uint
+rbx.platform.typedef.uint_least64_t = ulong_long
+rbx.platform.typedef.longlong_t = long_long
+rbx.platform.typedef.u_longlong_t = ulong_long
+rbx.platform.typedef.t_scalar_t = long
+rbx.platform.typedef.t_uscalar_t = ulong
+rbx.platform.typedef.uchar_t = uchar
+rbx.platform.typedef.ushort_t = ushort
+rbx.platform.typedef.uint_t = uint
+rbx.platform.typedef.ulong_t = ulong
+rbx.platform.typedef.*caddr_t = char
+rbx.platform.typedef.daddr_t = long
+rbx.platform.typedef.cnt_t = short
+rbx.platform.typedef.ptrdiff_t = int
+rbx.platform.typedef.pfn_t = ulong
+rbx.platform.typedef.pgcnt_t = ulong
+rbx.platform.typedef.spgcnt_t = long
+rbx.platform.typedef.use_t = uchar
+rbx.platform.typedef.sysid_t = short
+rbx.platform.typedef.index_t = short
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.off64_t = long_long
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.fsblkcnt_t = ulong_long
+rbx.platform.typedef.fsfilcnt_t = ulong_long
+rbx.platform.typedef.ino64_t = ulong_long
+rbx.platform.typedef.blkcnt64_t = long_long
+rbx.platform.typedef.fsblkcnt64_t = ulong_long
+rbx.platform.typedef.fsfilcnt64_t = ulong_long
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.pad64_t = long_long
+rbx.platform.typedef.upad64_t = ulong_long
+rbx.platform.typedef.offset_t = long_long
+rbx.platform.typedef.u_offset_t = ulong_long
+rbx.platform.typedef.len_t = ulong_long
+rbx.platform.typedef.diskaddr_t = ulong_long
+rbx.platform.typedef.k_fltset_t = uint
+rbx.platform.typedef.id_t = long
+rbx.platform.typedef.lgrp_id_t = long
+rbx.platform.typedef.useconds_t = uint
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.major_t = ulong
+rbx.platform.typedef.minor_t = ulong
+rbx.platform.typedef.pri_t = short
+rbx.platform.typedef.cpu_flag_t = ushort
+rbx.platform.typedef.o_mode_t = ushort
+rbx.platform.typedef.o_dev_t = short
+rbx.platform.typedef.o_uid_t = ushort
+rbx.platform.typedef.o_gid_t = ushort
+rbx.platform.typedef.o_nlink_t = short
+rbx.platform.typedef.o_pid_t = short
+rbx.platform.typedef.o_ino_t = ushort
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.mode_t = ulong
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.datalink_id_t = uint
+rbx.platform.typedef.taskid_t = long
+rbx.platform.typedef.projid_t = long
+rbx.platform.typedef.poolid_t = long
+rbx.platform.typedef.zoneid_t = long
+rbx.platform.typedef.ctid_t = long
+rbx.platform.typedef.pthread_t = uint
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.dev_t = ulong
+rbx.platform.typedef.nlink_t = ulong
+rbx.platform.typedef.pid_t = long
+rbx.platform.typedef.size_t = uint
+rbx.platform.typedef.ssize_t = int
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = int
+rbx.platform.typedef.unchar = uchar
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.hrtime_t = long_long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.fds_mask = long
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.nfds_t = ulong
+rbx.platform.typedef.disp_lock_t = uchar
+rbx.platform.typedef.model_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.ipaddr_t = uint
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.rlim64_t = ulong_long
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-windows/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-windows/types.conf
new file mode 100755
index 0000000..38168be
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/i386-windows/types.conf
@@ -0,0 +1,105 @@
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int_least16_t = short
+rbx.platform.typedef.__uint_least16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int_least32_t = int
+rbx.platform.typedef.__uint_least32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef._off_t = long
+rbx.platform.typedef._off64_t = long_long
+rbx.platform.typedef._ssize_t = int
+rbx.platform.typedef.wint_t = uint
+rbx.platform.typedef.ptrdiff_t = int
+rbx.platform.typedef.size_t = uint
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__loff_t = long_long
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.clock_t = ulong
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.daddr_t = long
+rbx.platform.typedef.caddr_t = string
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.ssize_t = int
+rbx.platform.typedef.nlink_t = ushort
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.clockid_t = ulong
+rbx.platform.typedef.timer_t = ulong
+rbx.platform.typedef.useconds_t = ulong
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = long
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.uint32_t = ulong
+rbx.platform.typedef.uint64_t = ulong_long
+rbx.platform.typedef.int_least8_t = char
+rbx.platform.typedef.int_least16_t = short
+rbx.platform.typedef.int_least32_t = long
+rbx.platform.typedef.int_least64_t = long_long
+rbx.platform.typedef.uint_least8_t = uchar
+rbx.platform.typedef.uint_least16_t = ushort
+rbx.platform.typedef.uint_least32_t = ulong
+rbx.platform.typedef.uint_least64_t = ulong_long
+rbx.platform.typedef.int_fast8_t = char
+rbx.platform.typedef.int_fast16_t = long
+rbx.platform.typedef.int_fast32_t = long
+rbx.platform.typedef.int_fast64_t = long_long
+rbx.platform.typedef.uint_fast8_t = uchar
+rbx.platform.typedef.uint_fast16_t = ulong
+rbx.platform.typedef.uint_fast32_t = ulong
+rbx.platform.typedef.uint_fast64_t = ulong_long
+rbx.platform.typedef.intptr_t = long
+rbx.platform.typedef.uintptr_t = ulong
+rbx.platform.typedef.intmax_t = long_long
+rbx.platform.typedef.uintmax_t = ulong_long
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.loff_t = long_long
+rbx.platform.typedef.__dev16_t = short
+rbx.platform.typedef.__dev32_t = ulong
+rbx.platform.typedef.dev_t = ulong
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.__blkcnt32_t = long
+rbx.platform.typedef.__blkcnt64_t = long_long
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.fsblkcnt_t = ulong
+rbx.platform.typedef.fsfilcnt_t = ulong
+rbx.platform.typedef.__uid16_t = ushort
+rbx.platform.typedef.__uid32_t = ulong
+rbx.platform.typedef.uid_t = ulong
+rbx.platform.typedef.__gid16_t = ushort
+rbx.platform.typedef.__gid32_t = ulong
+rbx.platform.typedef.gid_t = ulong
+rbx.platform.typedef.__ino32_t = ulong
+rbx.platform.typedef.__ino64_t = ulong_long
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.id_t = ulong
+rbx.platform.typedef.key_t = long_long
+rbx.platform.typedef.vm_offset_t = ulong
+rbx.platform.typedef.vm_size_t = ulong
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = int
+rbx.platform.typedef.*addr_t = char
+rbx.platform.typedef.socklen_t = int
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.__ULong = ulong
+rbx.platform.typedef._fpos_t = long
+rbx.platform.typedef._fpos64_t = long_long
+rbx.platform.typedef.sigset_t = ulong
+rbx.platform.typedef.sig_atomic_t = int
+rbx.platform.typedef.rlim_t = ulong
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/ia64-linux/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/ia64-linux/types.conf
new file mode 100755
index 0000000..70e44e8
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/ia64-linux/types.conf
@@ -0,0 +1,104 @@
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long
+rbx.platform.typedef.__uint64_t = ulong
+rbx.platform.typedef.__quad_t = long
+rbx.platform.typedef.__u_quad_t = ulong
+rbx.platform.typedef.__dev_t = ulong
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__in_addr_t = uint
+rbx.platform.typedef.__in_port_t = ushort
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__ino64_t = ulong
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = ulong
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__off64_t = long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlim64_t = ulong
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__swblk_t = long
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.__blksize_t = long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blkcnt64_t = long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsblkcnt64_t = ulong
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong
+rbx.platform.typedef.__ssize_t = long
+rbx.platform.typedef.__loff_t = long
+rbx.platform.typedef.*__qaddr_t = long
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__intptr_t = long
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.quad_t = long
+rbx.platform.typedef.u_quad_t = ulong
+rbx.platform.typedef.loff_t = long
+rbx.platform.typedef.ino_t = ulong
+rbx.platform.typedef.dev_t = ulong
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = ulong
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.off_t = long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.blkcnt_t = long
+rbx.platform.typedef.fsblkcnt_t = ulong
+rbx.platform.typedef.fsfilcnt_t = ulong
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.rlim_t = ulong
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__priority_which_t = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/mips-linux/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/mips-linux/types.conf
new file mode 100755
index 0000000..ad4ced0
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/mips-linux/types.conf
@@ -0,0 +1,102 @@
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__quad_t = long_long
+rbx.platform.typedef.__u_quad_t = ulong_long
+rbx.platform.typedef.__dev_t = ulong_long
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__ino64_t = ulong_long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__off64_t = long_long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlim64_t = ulong_long
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__swblk_t = long
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.__blksize_t = long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blkcnt64_t = long_long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsblkcnt64_t = ulong_long
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong_long
+rbx.platform.typedef.__ssize_t = int
+rbx.platform.typedef.__loff_t = long_long
+rbx.platform.typedef.*__qaddr_t = long_long
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__intptr_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.loff_t = long_long
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.dev_t = ulong_long
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ssize_t = int
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.size_t = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.fsblkcnt_t = ulong_long
+rbx.platform.typedef.fsfilcnt_t = ulong_long
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__priority_which_t = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/mips64el-linux/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/mips64el-linux/types.conf
new file mode 100755
index 0000000..3feb704
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/mips64el-linux/types.conf
@@ -0,0 +1,104 @@
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long
+rbx.platform.typedef.__uint64_t = ulong
+rbx.platform.typedef.__quad_t = long
+rbx.platform.typedef.__u_quad_t = ulong
+rbx.platform.typedef.__dev_t = ulong
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__ino64_t = ulong
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = ulong
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__off64_t = long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlim64_t = ulong
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.__blksize_t = long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blkcnt64_t = long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsblkcnt64_t = ulong
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong
+rbx.platform.typedef.__fsword_t = long
+rbx.platform.typedef.__ssize_t = long
+rbx.platform.typedef.__syscall_slong_t = long
+rbx.platform.typedef.__syscall_ulong_t = ulong
+rbx.platform.typedef.__loff_t = long
+rbx.platform.typedef.*__qaddr_t = long
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__intptr_t = long
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.quad_t = long
+rbx.platform.typedef.u_quad_t = ulong
+rbx.platform.typedef.loff_t = long
+rbx.platform.typedef.ino_t = ulong
+rbx.platform.typedef.dev_t = ulong
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = ulong
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.off_t = long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.blkcnt_t = long
+rbx.platform.typedef.fsblkcnt_t = ulong
+rbx.platform.typedef.fsfilcnt_t = ulong
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.rlim_t = ulong
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__priority_which_t = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/mipsel-linux/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/mipsel-linux/types.conf
new file mode 100755
index 0000000..ad4ced0
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/mipsel-linux/types.conf
@@ -0,0 +1,102 @@
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__quad_t = long_long
+rbx.platform.typedef.__u_quad_t = ulong_long
+rbx.platform.typedef.__dev_t = ulong_long
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__ino64_t = ulong_long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__off64_t = long_long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlim64_t = ulong_long
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__swblk_t = long
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.__blksize_t = long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blkcnt64_t = long_long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsblkcnt64_t = ulong_long
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong_long
+rbx.platform.typedef.__ssize_t = int
+rbx.platform.typedef.__loff_t = long_long
+rbx.platform.typedef.*__qaddr_t = long_long
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__intptr_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.loff_t = long_long
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.dev_t = ulong_long
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ssize_t = int
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.size_t = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.fsblkcnt_t = ulong_long
+rbx.platform.typedef.fsfilcnt_t = ulong_long
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__priority_which_t = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/powerpc-aix/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/powerpc-aix/types.conf
new file mode 100755
index 0000000..30ee66b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/powerpc-aix/types.conf
@@ -0,0 +1,180 @@
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.uint32_t = uint
+rbx.platform.typedef.uint64_t = ulong_long
+rbx.platform.typedef.intmax_t = long_long
+rbx.platform.typedef.uintmax_t = ulong_long
+rbx.platform.typedef.intptr_t = long
+rbx.platform.typedef.uintptr_t = ulong
+rbx.platform.typedef.int_least8_t = char
+rbx.platform.typedef.int_least16_t = short
+rbx.platform.typedef.int_least32_t = int
+rbx.platform.typedef.int_least64_t = long_long
+rbx.platform.typedef.uint_least8_t = uchar
+rbx.platform.typedef.uint_least16_t = ushort
+rbx.platform.typedef.uint_least32_t = uint
+rbx.platform.typedef.uint_least64_t = ulong_long
+rbx.platform.typedef.int_fast8_t = char
+rbx.platform.typedef.int_fast16_t = short
+rbx.platform.typedef.int_fast32_t = int
+rbx.platform.typedef.uint_fast8_t = uchar
+rbx.platform.typedef.uint_fast16_t = ushort
+rbx.platform.typedef.uint_fast32_t = uint
+rbx.platform.typedef.int_fast64_t = long_long
+rbx.platform.typedef.uint_fast64_t = ulong_long
+rbx.platform.typedef.wchar_t = ushort
+rbx.platform.typedef.intfast_t = int
+rbx.platform.typedef.uintfast_t = uint
+rbx.platform.typedef.__long32_t = long
+rbx.platform.typedef.__ulong32_t = ulong
+rbx.platform.typedef.__long64_t = int
+rbx.platform.typedef.__ulong64_t = uint
+rbx.platform.typedef.int32long64_t = int
+rbx.platform.typedef.uint32long64_t = uint
+rbx.platform.typedef.long32int64_t = long
+rbx.platform.typedef.ulong32int64_t = ulong
+rbx.platform.typedef.int8 = char
+rbx.platform.typedef.int16 = short
+rbx.platform.typedef.int32 = int
+rbx.platform.typedef.int64 = long_long
+rbx.platform.typedef.u_int8 = uchar
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16 = ushort
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32 = uint
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64 = ulong_long
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.ptrdiff_t = long
+rbx.platform.typedef.wctype_t = uint
+rbx.platform.typedef.fpos_t = long
+rbx.platform.typedef.fpos64_t = long_long
+rbx.platform.typedef.time_t = int
+rbx.platform.typedef.clock_t = int
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.uchar_t = uchar
+rbx.platform.typedef.ushort_t = ushort
+rbx.platform.typedef.uint_t = uint
+rbx.platform.typedef.ulong_t = ulong
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.level_t = int
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.daddr32_t = int
+rbx.platform.typedef.daddr64_t = long_long
+rbx.platform.typedef.caddr_t = string
+rbx.platform.typedef.ino_t = uint
+rbx.platform.typedef.ino32_t = uint
+rbx.platform.typedef.ino64_t = ulong_long
+rbx.platform.typedef.cnt_t = short
+rbx.platform.typedef.dev_t = uint
+rbx.platform.typedef.dev32_t = uint
+rbx.platform.typedef.dev64_t = ulong_long
+rbx.platform.typedef.chan_t = int
+rbx.platform.typedef.time32_t = int
+rbx.platform.typedef.pid32_t = int
+rbx.platform.typedef.tid32_t = int
+rbx.platform.typedef.pid64_t = ulong_long
+rbx.platform.typedef.tid64_t = ulong_long
+rbx.platform.typedef.time64_t = long_long
+rbx.platform.typedef.__ptr32 = pointer
+rbx.platform.typedef.__cptr32 = string
+rbx.platform.typedef.soff_t = int
+rbx.platform.typedef.off_t = long
+rbx.platform.typedef.off64_t = long_long
+rbx.platform.typedef.paddr_t = long
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.timer_t = int
+rbx.platform.typedef.timer32_t = int
+rbx.platform.typedef.timer64_t = long_long
+rbx.platform.typedef.nlink_t = short
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.mid_t = pointer
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.tid_t = int
+rbx.platform.typedef.slab_t[12] = char
+rbx.platform.typedef.mtyp_t = long
+rbx.platform.typedef.boolean_t = int
+rbx.platform.typedef.crid_t = int
+rbx.platform.typedef.blkcnt_t = int
+rbx.platform.typedef.blksize_t = int
+rbx.platform.typedef.blkcnt32_t = int
+rbx.platform.typedef.blksize32_t = int
+rbx.platform.typedef.blkcnt64_t = ulong_long
+rbx.platform.typedef.blksize64_t = ulong_long
+rbx.platform.typedef.fsblkcnt_t = ulong
+rbx.platform.typedef.fsfilcnt_t = ulong
+rbx.platform.typedef.wint_t = int
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.useconds_t = uint
+rbx.platform.typedef.suseconds_t = int
+rbx.platform.typedef.clockid_t = long_long
+rbx.platform.typedef.signal_t = int
+rbx.platform.typedef.pthread_t = uint
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.vmid_t = long
+rbx.platform.typedef.vmhandle_t = ulong
+rbx.platform.typedef.vmid32_t = int
+rbx.platform.typedef.vmhandle32_t = uint
+rbx.platform.typedef.kvmid_t = long
+rbx.platform.typedef.kvmhandle_t = ulong
+rbx.platform.typedef.vmid64_t = long_long
+rbx.platform.typedef.rpn64_t = long_long
+rbx.platform.typedef.cnt64_t = long_long
+rbx.platform.typedef.psize_t = long_long
+rbx.platform.typedef.vmidx_t = int
+rbx.platform.typedef.vmfkey_t = uint
+rbx.platform.typedef.vmprkey_t = uint
+rbx.platform.typedef.vmkey_t = int
+rbx.platform.typedef.vmhwkey_t = int
+rbx.platform.typedef.vpn_t = int
+rbx.platform.typedef.rpn_t = int
+rbx.platform.typedef.ptex_t = ulong
+rbx.platform.typedef.swhatx_t = ulong
+rbx.platform.typedef.esid_t = uint
+rbx.platform.typedef.aptx_t = ushort
+rbx.platform.typedef.pdtx_t = int
+rbx.platform.typedef.psx_t = short
+rbx.platform.typedef.pshift_t = ushort
+rbx.platform.typedef.sshift_t = ushort
+rbx.platform.typedef.unidx_t = int
+rbx.platform.typedef.snidx_t = int
+rbx.platform.typedef.vmnodeidx_t = int
+rbx.platform.typedef.kvpn_t = int
+rbx.platform.typedef.krpn_t = int
+rbx.platform.typedef.vmsize_t = int
+rbx.platform.typedef.vmm_lock_t = int
+rbx.platform.typedef.ureg_t = ulong
+rbx.platform.typedef.vmlpghandle_t = ulong
+rbx.platform.typedef.ext_t = int
+rbx.platform.typedef.va_list = string
+rbx.platform.typedef.__ptr64 = ulong_long
+rbx.platform.typedef.__cptr64 = ulong_long
+rbx.platform.typedef.UniChar = ushort
+rbx.platform.typedef.UTF32Char = uint
+rbx.platform.typedef.uchar = uchar
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.swblk_t = int
+rbx.platform.typedef.offset_t = long_long
+rbx.platform.typedef.ssize64_t = long_long
+rbx.platform.typedef.longlong_t = long_long
+rbx.platform.typedef.u_longlong_t = ulong_long
+rbx.platform.typedef.class_id_t = uint
+rbx.platform.typedef.liobn_t = uint
+rbx.platform.typedef.unit_addr_t = ulong_long
+rbx.platform.typedef.size64_t = ulong_long
+rbx.platform.typedef.socklen_t = ulong
+rbx.platform.typedef.sa_family_t = uchar
+rbx.platform.typedef.rlim_t = ulong
+rbx.platform.typedef.rlim64_t = ulong_long
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/powerpc-darwin/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/powerpc-darwin/types.conf
new file mode 100755
index 0000000..6b9313e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/powerpc-darwin/types.conf
@@ -0,0 +1,100 @@
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__darwin_intptr_t = long
+rbx.platform.typedef.__darwin_natural_t = uint
+rbx.platform.typedef.__darwin_ct_rune_t = int
+rbx.platform.typedef.__darwin_ptrdiff_t = int
+rbx.platform.typedef.__darwin_size_t = ulong
+rbx.platform.typedef.__darwin_wchar_t = int
+rbx.platform.typedef.__darwin_rune_t = int
+rbx.platform.typedef.__darwin_wint_t = int
+rbx.platform.typedef.__darwin_clock_t = ulong
+rbx.platform.typedef.__darwin_socklen_t = uint
+rbx.platform.typedef.__darwin_ssize_t = long
+rbx.platform.typedef.__darwin_time_t = long
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = int
+rbx.platform.typedef.intptr_t = long
+rbx.platform.typedef.uintptr_t = ulong
+rbx.platform.typedef.user_addr_t = ulong_long
+rbx.platform.typedef.user_size_t = ulong_long
+rbx.platform.typedef.user_ssize_t = long_long
+rbx.platform.typedef.user_long_t = long_long
+rbx.platform.typedef.user_ulong_t = ulong_long
+rbx.platform.typedef.user_time_t = long_long
+rbx.platform.typedef.syscall_arg_t = ulong_long
+rbx.platform.typedef.__darwin_blkcnt_t = long_long
+rbx.platform.typedef.__darwin_blksize_t = int
+rbx.platform.typedef.__darwin_dev_t = int
+rbx.platform.typedef.__darwin_fsblkcnt_t = uint
+rbx.platform.typedef.__darwin_fsfilcnt_t = uint
+rbx.platform.typedef.__darwin_gid_t = uint
+rbx.platform.typedef.__darwin_id_t = uint
+rbx.platform.typedef.__darwin_ino64_t = ulong_long
+rbx.platform.typedef.__darwin_ino_t = ulong_long
+rbx.platform.typedef.__darwin_mach_port_name_t = uint
+rbx.platform.typedef.__darwin_mach_port_t = uint
+rbx.platform.typedef.__darwin_mode_t = ushort
+rbx.platform.typedef.__darwin_off_t = long_long
+rbx.platform.typedef.__darwin_pid_t = int
+rbx.platform.typedef.__darwin_pthread_key_t = ulong
+rbx.platform.typedef.__darwin_sigset_t = uint
+rbx.platform.typedef.__darwin_suseconds_t = int
+rbx.platform.typedef.__darwin_uid_t = uint
+rbx.platform.typedef.__darwin_useconds_t = uint
+rbx.platform.typedef.__darwin_uuid_t[16] = uchar
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.qaddr_t = pointer
+rbx.platform.typedef.caddr_t = string
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.dev_t = int
+rbx.platform.typedef.fixpt_t = uint
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.blksize_t = int
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.ino64_t = ulong_long
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.mode_t = ushort
+rbx.platform.typedef.nlink_t = ushort
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.segsz_t = int
+rbx.platform.typedef.swblk_t = int
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.clock_t = ulong
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.useconds_t = uint
+rbx.platform.typedef.suseconds_t = int
+rbx.platform.typedef.fd_mask = int
+rbx.platform.typedef.pthread_key_t = ulong
+rbx.platform.typedef.fsblkcnt_t = uint
+rbx.platform.typedef.fsfilcnt_t = uint
+rbx.platform.typedef.sa_family_t = uchar
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.rlim_t = ulong_long
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/powerpc-linux/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/powerpc-linux/types.conf
new file mode 100755
index 0000000..76014cd
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/powerpc-linux/types.conf
@@ -0,0 +1,100 @@
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__quad_t = long_long
+rbx.platform.typedef.__u_quad_t = ulong_long
+rbx.platform.typedef.__dev_t = ulong_long
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__ino64_t = ulong_long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__off64_t = long_long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlim64_t = ulong_long
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__swblk_t = long
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.__blksize_t = long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blkcnt64_t = long_long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsblkcnt64_t = ulong_long
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong_long
+rbx.platform.typedef.__ssize_t = int
+rbx.platform.typedef.__loff_t = long_long
+rbx.platform.typedef.*__qaddr_t = long_long
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__intptr_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.loff_t = long_long
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.dev_t = ulong_long
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ssize_t = int
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.size_t = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.fsblkcnt_t = ulong_long
+rbx.platform.typedef.fsfilcnt_t = ulong_long
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__priority_which_t = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/powerpc64-linux/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/powerpc64-linux/types.conf
new file mode 100755
index 0000000..3feb704
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/powerpc64-linux/types.conf
@@ -0,0 +1,104 @@
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long
+rbx.platform.typedef.__uint64_t = ulong
+rbx.platform.typedef.__quad_t = long
+rbx.platform.typedef.__u_quad_t = ulong
+rbx.platform.typedef.__dev_t = ulong
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__ino64_t = ulong
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = ulong
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__off64_t = long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlim64_t = ulong
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.__blksize_t = long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blkcnt64_t = long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsblkcnt64_t = ulong
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong
+rbx.platform.typedef.__fsword_t = long
+rbx.platform.typedef.__ssize_t = long
+rbx.platform.typedef.__syscall_slong_t = long
+rbx.platform.typedef.__syscall_ulong_t = ulong
+rbx.platform.typedef.__loff_t = long
+rbx.platform.typedef.*__qaddr_t = long
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__intptr_t = long
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.quad_t = long
+rbx.platform.typedef.u_quad_t = ulong
+rbx.platform.typedef.loff_t = long
+rbx.platform.typedef.ino_t = ulong
+rbx.platform.typedef.dev_t = ulong
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = ulong
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.off_t = long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.blkcnt_t = long
+rbx.platform.typedef.fsblkcnt_t = ulong
+rbx.platform.typedef.fsfilcnt_t = ulong
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.rlim_t = ulong
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__priority_which_t = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/s390-linux/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/s390-linux/types.conf
new file mode 100755
index 0000000..1cc79ee
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/s390-linux/types.conf
@@ -0,0 +1,102 @@
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__quad_t = long_long
+rbx.platform.typedef.__u_quad_t = ulong_long
+rbx.platform.typedef.__dev_t = ulong_long
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__ino64_t = ulong_long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__off64_t = long_long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlim64_t = ulong_long
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__swblk_t = long
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.__blksize_t = long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blkcnt64_t = long_long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsblkcnt64_t = ulong_long
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong_long
+rbx.platform.typedef.__ssize_t = long
+rbx.platform.typedef.__loff_t = long_long
+rbx.platform.typedef.*__qaddr_t = long_long
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__intptr_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.loff_t = long_long
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.dev_t = ulong_long
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.fsblkcnt_t = ulong_long
+rbx.platform.typedef.fsfilcnt_t = ulong_long
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__priority_which_t = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/s390x-linux/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/s390x-linux/types.conf
new file mode 100755
index 0000000..f4c8cec
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/s390x-linux/types.conf
@@ -0,0 +1,102 @@
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long
+rbx.platform.typedef.__uint64_t = ulong
+rbx.platform.typedef.__quad_t = long
+rbx.platform.typedef.__u_quad_t = ulong
+rbx.platform.typedef.__dev_t = ulong
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__ino64_t = ulong
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = ulong
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__off64_t = long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlim64_t = ulong
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__swblk_t = long
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.__blksize_t = long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blkcnt64_t = long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsblkcnt64_t = ulong
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong
+rbx.platform.typedef.__ssize_t = long
+rbx.platform.typedef.__loff_t = long
+rbx.platform.typedef.*__qaddr_t = long
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__intptr_t = long
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.quad_t = long
+rbx.platform.typedef.u_quad_t = ulong
+rbx.platform.typedef.loff_t = long
+rbx.platform.typedef.ino_t = ulong
+rbx.platform.typedef.dev_t = ulong
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = ulong
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.off_t = long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.blkcnt_t = long
+rbx.platform.typedef.fsblkcnt_t = ulong
+rbx.platform.typedef.fsfilcnt_t = ulong
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.rlim_t = ulong
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__priority_which_t = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/sparc-linux/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/sparc-linux/types.conf
new file mode 100755
index 0000000..1882298
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/sparc-linux/types.conf
@@ -0,0 +1,102 @@
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__quad_t = long_long
+rbx.platform.typedef.__u_quad_t = ulong_long
+rbx.platform.typedef.__dev_t = ulong_long
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__ino64_t = ulong_long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__off64_t = long_long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlim64_t = ulong_long
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = int
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__swblk_t = long
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.__blksize_t = long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blkcnt64_t = long_long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsblkcnt64_t = ulong_long
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong_long
+rbx.platform.typedef.__ssize_t = int
+rbx.platform.typedef.__loff_t = long_long
+rbx.platform.typedef.*__qaddr_t = long_long
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__intptr_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.loff_t = long_long
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.dev_t = ulong_long
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ssize_t = int
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.size_t = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.suseconds_t = int
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.fsblkcnt_t = ulong_long
+rbx.platform.typedef.fsfilcnt_t = ulong_long
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__priority_which_t = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/sparc-solaris/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/sparc-solaris/types.conf
new file mode 100755
index 0000000..c03c144
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/sparc-solaris/types.conf
@@ -0,0 +1,128 @@
+rbx.platform.typedef.lock_t = uchar
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.uint32_t = uint
+rbx.platform.typedef.uint64_t = ulong_long
+rbx.platform.typedef.intmax_t = long_long
+rbx.platform.typedef.uintmax_t = ulong_long
+rbx.platform.typedef.intptr_t = int
+rbx.platform.typedef.uintptr_t = uint
+rbx.platform.typedef.int_fast8_t = char
+rbx.platform.typedef.int_fast16_t = int
+rbx.platform.typedef.int_fast32_t = int
+rbx.platform.typedef.int_fast64_t = long_long
+rbx.platform.typedef.uint_fast8_t = uchar
+rbx.platform.typedef.uint_fast16_t = uint
+rbx.platform.typedef.uint_fast32_t = uint
+rbx.platform.typedef.uint_fast64_t = ulong_long
+rbx.platform.typedef.int_least8_t = char
+rbx.platform.typedef.int_least16_t = short
+rbx.platform.typedef.int_least32_t = int
+rbx.platform.typedef.int_least64_t = long_long
+rbx.platform.typedef.uint_least8_t = uchar
+rbx.platform.typedef.uint_least16_t = ushort
+rbx.platform.typedef.uint_least32_t = uint
+rbx.platform.typedef.uint_least64_t = ulong_long
+rbx.platform.typedef.longlong_t = long_long
+rbx.platform.typedef.u_longlong_t = ulong_long
+rbx.platform.typedef.t_scalar_t = long
+rbx.platform.typedef.t_uscalar_t = ulong
+rbx.platform.typedef.uchar_t = uchar
+rbx.platform.typedef.ushort_t = ushort
+rbx.platform.typedef.uint_t = uint
+rbx.platform.typedef.ulong_t = ulong
+rbx.platform.typedef.*caddr_t = char
+rbx.platform.typedef.daddr_t = long
+rbx.platform.typedef.cnt_t = short
+rbx.platform.typedef.ptrdiff_t = int
+rbx.platform.typedef.pfn_t = ulong
+rbx.platform.typedef.pgcnt_t = ulong
+rbx.platform.typedef.spgcnt_t = long
+rbx.platform.typedef.use_t = uchar
+rbx.platform.typedef.sysid_t = short
+rbx.platform.typedef.index_t = short
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.off64_t = long_long
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.fsblkcnt_t = ulong_long
+rbx.platform.typedef.fsfilcnt_t = ulong_long
+rbx.platform.typedef.ino64_t = ulong_long
+rbx.platform.typedef.blkcnt64_t = long_long
+rbx.platform.typedef.fsblkcnt64_t = ulong_long
+rbx.platform.typedef.fsfilcnt64_t = ulong_long
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.pad64_t = long_long
+rbx.platform.typedef.upad64_t = ulong_long
+rbx.platform.typedef.offset_t = long_long
+rbx.platform.typedef.u_offset_t = ulong_long
+rbx.platform.typedef.len_t = ulong_long
+rbx.platform.typedef.diskaddr_t = ulong_long
+rbx.platform.typedef.k_fltset_t = uint
+rbx.platform.typedef.id_t = long
+rbx.platform.typedef.useconds_t = uint
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.major_t = ulong
+rbx.platform.typedef.minor_t = ulong
+rbx.platform.typedef.pri_t = short
+rbx.platform.typedef.cpu_flag_t = ushort
+rbx.platform.typedef.o_mode_t = ushort
+rbx.platform.typedef.o_dev_t = short
+rbx.platform.typedef.o_uid_t = ushort
+rbx.platform.typedef.o_gid_t = ushort
+rbx.platform.typedef.o_nlink_t = short
+rbx.platform.typedef.o_pid_t = short
+rbx.platform.typedef.o_ino_t = ushort
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.mode_t = ulong
+rbx.platform.typedef.uid_t = long
+rbx.platform.typedef.gid_t = long
+rbx.platform.typedef.taskid_t = long
+rbx.platform.typedef.projid_t = long
+rbx.platform.typedef.poolid_t = long
+rbx.platform.typedef.zoneid_t = long
+rbx.platform.typedef.ctid_t = long
+rbx.platform.typedef.pthread_t = uint
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.dev_t = ulong
+rbx.platform.typedef.nlink_t = ulong
+rbx.platform.typedef.pid_t = long
+rbx.platform.typedef.size_t = uint
+rbx.platform.typedef.ssize_t = int
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = int
+rbx.platform.typedef.unchar = uchar
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.hrtime_t = long_long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.fds_mask = long
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.Psocklen_t = pointer
+rbx.platform.typedef.disp_lock_t = uchar
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.rlim64_t = ulong_long
+rbx.platform.typedef.kid_t = int
+rbx.platform.typedef.int) = pointer
+rbx.platform.typedef.size_t) = pointer
+rbx.platform.typedef.int) = pointer
+rbx.platform.typedef.avl_index_t = uint
+rbx.platform.typedef.() = pointer
+rbx.platform.typedef.nfds_t = ulong
+rbx.platform.typedef.model_t = uint
+rbx.platform.typedef.ts_t = long_long
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.ipaddr_t = uint
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/sparcv9-solaris/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/sparcv9-solaris/types.conf
new file mode 100755
index 0000000..c03c144
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/sparcv9-solaris/types.conf
@@ -0,0 +1,128 @@
+rbx.platform.typedef.lock_t = uchar
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.uint32_t = uint
+rbx.platform.typedef.uint64_t = ulong_long
+rbx.platform.typedef.intmax_t = long_long
+rbx.platform.typedef.uintmax_t = ulong_long
+rbx.platform.typedef.intptr_t = int
+rbx.platform.typedef.uintptr_t = uint
+rbx.platform.typedef.int_fast8_t = char
+rbx.platform.typedef.int_fast16_t = int
+rbx.platform.typedef.int_fast32_t = int
+rbx.platform.typedef.int_fast64_t = long_long
+rbx.platform.typedef.uint_fast8_t = uchar
+rbx.platform.typedef.uint_fast16_t = uint
+rbx.platform.typedef.uint_fast32_t = uint
+rbx.platform.typedef.uint_fast64_t = ulong_long
+rbx.platform.typedef.int_least8_t = char
+rbx.platform.typedef.int_least16_t = short
+rbx.platform.typedef.int_least32_t = int
+rbx.platform.typedef.int_least64_t = long_long
+rbx.platform.typedef.uint_least8_t = uchar
+rbx.platform.typedef.uint_least16_t = ushort
+rbx.platform.typedef.uint_least32_t = uint
+rbx.platform.typedef.uint_least64_t = ulong_long
+rbx.platform.typedef.longlong_t = long_long
+rbx.platform.typedef.u_longlong_t = ulong_long
+rbx.platform.typedef.t_scalar_t = long
+rbx.platform.typedef.t_uscalar_t = ulong
+rbx.platform.typedef.uchar_t = uchar
+rbx.platform.typedef.ushort_t = ushort
+rbx.platform.typedef.uint_t = uint
+rbx.platform.typedef.ulong_t = ulong
+rbx.platform.typedef.*caddr_t = char
+rbx.platform.typedef.daddr_t = long
+rbx.platform.typedef.cnt_t = short
+rbx.platform.typedef.ptrdiff_t = int
+rbx.platform.typedef.pfn_t = ulong
+rbx.platform.typedef.pgcnt_t = ulong
+rbx.platform.typedef.spgcnt_t = long
+rbx.platform.typedef.use_t = uchar
+rbx.platform.typedef.sysid_t = short
+rbx.platform.typedef.index_t = short
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.off64_t = long_long
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.fsblkcnt_t = ulong_long
+rbx.platform.typedef.fsfilcnt_t = ulong_long
+rbx.platform.typedef.ino64_t = ulong_long
+rbx.platform.typedef.blkcnt64_t = long_long
+rbx.platform.typedef.fsblkcnt64_t = ulong_long
+rbx.platform.typedef.fsfilcnt64_t = ulong_long
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.pad64_t = long_long
+rbx.platform.typedef.upad64_t = ulong_long
+rbx.platform.typedef.offset_t = long_long
+rbx.platform.typedef.u_offset_t = ulong_long
+rbx.platform.typedef.len_t = ulong_long
+rbx.platform.typedef.diskaddr_t = ulong_long
+rbx.platform.typedef.k_fltset_t = uint
+rbx.platform.typedef.id_t = long
+rbx.platform.typedef.useconds_t = uint
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.major_t = ulong
+rbx.platform.typedef.minor_t = ulong
+rbx.platform.typedef.pri_t = short
+rbx.platform.typedef.cpu_flag_t = ushort
+rbx.platform.typedef.o_mode_t = ushort
+rbx.platform.typedef.o_dev_t = short
+rbx.platform.typedef.o_uid_t = ushort
+rbx.platform.typedef.o_gid_t = ushort
+rbx.platform.typedef.o_nlink_t = short
+rbx.platform.typedef.o_pid_t = short
+rbx.platform.typedef.o_ino_t = ushort
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.mode_t = ulong
+rbx.platform.typedef.uid_t = long
+rbx.platform.typedef.gid_t = long
+rbx.platform.typedef.taskid_t = long
+rbx.platform.typedef.projid_t = long
+rbx.platform.typedef.poolid_t = long
+rbx.platform.typedef.zoneid_t = long
+rbx.platform.typedef.ctid_t = long
+rbx.platform.typedef.pthread_t = uint
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.dev_t = ulong
+rbx.platform.typedef.nlink_t = ulong
+rbx.platform.typedef.pid_t = long
+rbx.platform.typedef.size_t = uint
+rbx.platform.typedef.ssize_t = int
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = int
+rbx.platform.typedef.unchar = uchar
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.hrtime_t = long_long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.fds_mask = long
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.Psocklen_t = pointer
+rbx.platform.typedef.disp_lock_t = uchar
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.rlim64_t = ulong_long
+rbx.platform.typedef.kid_t = int
+rbx.platform.typedef.int) = pointer
+rbx.platform.typedef.size_t) = pointer
+rbx.platform.typedef.int) = pointer
+rbx.platform.typedef.avl_index_t = uint
+rbx.platform.typedef.() = pointer
+rbx.platform.typedef.nfds_t = ulong
+rbx.platform.typedef.model_t = uint
+rbx.platform.typedef.ts_t = long_long
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.ipaddr_t = uint
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-cygwin/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-cygwin/types.conf
new file mode 100755
index 0000000..5dadc7f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-cygwin/types.conf
@@ -0,0 +1,3 @@
+rbx.platform.typedef.size_t = uint64
+rbx.platform.typedef.ptrdiff_t = int64
+rbx.platform.typedef.ssize_t = int64
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-darwin/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-darwin/types.conf
new file mode 100755
index 0000000..51637ee
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-darwin/types.conf
@@ -0,0 +1,126 @@
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__darwin_intptr_t = long
+rbx.platform.typedef.__darwin_natural_t = uint
+rbx.platform.typedef.__darwin_ct_rune_t = int
+rbx.platform.typedef.__darwin_ptrdiff_t = long
+rbx.platform.typedef.__darwin_size_t = ulong
+rbx.platform.typedef.__darwin_wchar_t = int
+rbx.platform.typedef.__darwin_rune_t = int
+rbx.platform.typedef.__darwin_wint_t = int
+rbx.platform.typedef.__darwin_clock_t = ulong
+rbx.platform.typedef.__darwin_socklen_t = uint
+rbx.platform.typedef.__darwin_ssize_t = long
+rbx.platform.typedef.__darwin_time_t = long
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = long_long
+rbx.platform.typedef.intptr_t = long
+rbx.platform.typedef.uintptr_t = ulong
+rbx.platform.typedef.user_addr_t = ulong_long
+rbx.platform.typedef.user_size_t = ulong_long
+rbx.platform.typedef.user_ssize_t = long_long
+rbx.platform.typedef.user_long_t = long_long
+rbx.platform.typedef.user_ulong_t = ulong_long
+rbx.platform.typedef.user_time_t = long_long
+rbx.platform.typedef.user_off_t = long_long
+rbx.platform.typedef.syscall_arg_t = ulong_long
+rbx.platform.typedef.__darwin_blkcnt_t = long_long
+rbx.platform.typedef.__darwin_blksize_t = int
+rbx.platform.typedef.__darwin_dev_t = int
+rbx.platform.typedef.__darwin_fsblkcnt_t = uint
+rbx.platform.typedef.__darwin_fsfilcnt_t = uint
+rbx.platform.typedef.__darwin_gid_t = uint
+rbx.platform.typedef.__darwin_id_t = uint
+rbx.platform.typedef.__darwin_ino64_t = ulong_long
+rbx.platform.typedef.__darwin_ino_t = ulong_long
+rbx.platform.typedef.__darwin_mach_port_name_t = uint
+rbx.platform.typedef.__darwin_mach_port_t = uint
+rbx.platform.typedef.__darwin_mode_t = ushort
+rbx.platform.typedef.__darwin_off_t = long_long
+rbx.platform.typedef.__darwin_pid_t = int
+rbx.platform.typedef.__darwin_sigset_t = uint
+rbx.platform.typedef.__darwin_suseconds_t = int
+rbx.platform.typedef.__darwin_uid_t = uint
+rbx.platform.typedef.__darwin_useconds_t = uint
+rbx.platform.typedef.__darwin_uuid_t[16] = uchar
+rbx.platform.typedef.__darwin_uuid_string_t[37] = char
+rbx.platform.typedef.__darwin_pthread_key_t = ulong
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.qaddr_t = pointer
+rbx.platform.typedef.caddr_t = string
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.dev_t = int
+rbx.platform.typedef.fixpt_t = uint
+rbx.platform.typedef.blkcnt_t = long_long
+rbx.platform.typedef.blksize_t = int
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.ino_t = ulong_long
+rbx.platform.typedef.ino64_t = ulong_long
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.mode_t = ushort
+rbx.platform.typedef.nlink_t = ushort
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.segsz_t = int
+rbx.platform.typedef.swblk_t = int
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.clock_t = ulong
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.useconds_t = uint
+rbx.platform.typedef.suseconds_t = int
+rbx.platform.typedef.rsize_t = ulong
+rbx.platform.typedef.errno_t = int
+rbx.platform.typedef.fd_mask = int
+rbx.platform.typedef.pthread_key_t = ulong
+rbx.platform.typedef.fsblkcnt_t = uint
+rbx.platform.typedef.fsfilcnt_t = uint
+rbx.platform.typedef.sa_family_t = uchar
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.uint32_t = uint
+rbx.platform.typedef.uint64_t = ulong_long
+rbx.platform.typedef.int_least8_t = char
+rbx.platform.typedef.int_least16_t = short
+rbx.platform.typedef.int_least32_t = int
+rbx.platform.typedef.int_least64_t = long_long
+rbx.platform.typedef.uint_least8_t = uchar
+rbx.platform.typedef.uint_least16_t = ushort
+rbx.platform.typedef.uint_least32_t = uint
+rbx.platform.typedef.uint_least64_t = ulong_long
+rbx.platform.typedef.int_fast8_t = char
+rbx.platform.typedef.int_fast16_t = short
+rbx.platform.typedef.int_fast32_t = int
+rbx.platform.typedef.int_fast64_t = long_long
+rbx.platform.typedef.uint_fast8_t = uchar
+rbx.platform.typedef.uint_fast16_t = ushort
+rbx.platform.typedef.uint_fast32_t = uint
+rbx.platform.typedef.uint_fast64_t = ulong_long
+rbx.platform.typedef.intmax_t = long
+rbx.platform.typedef.uintmax_t = ulong
+rbx.platform.typedef.rlim_t = ulong_long
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-freebsd/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-freebsd/types.conf
new file mode 100755
index 0000000..c4df68a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-freebsd/types.conf
@@ -0,0 +1,128 @@
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__int_least8_t = char
+rbx.platform.typedef.__uint_least8_t = uchar
+rbx.platform.typedef.__int_least16_t = short
+rbx.platform.typedef.__uint_least16_t = ushort
+rbx.platform.typedef.__int_least32_t = int
+rbx.platform.typedef.__uint_least32_t = uint
+rbx.platform.typedef.__int_least64_t = long_long
+rbx.platform.typedef.__uint_least64_t = ulong_long
+rbx.platform.typedef.__int_fast8_t = int
+rbx.platform.typedef.__uint_fast8_t = uint
+rbx.platform.typedef.__int_fast16_t = int
+rbx.platform.typedef.__uint_fast16_t = uint
+rbx.platform.typedef.__int_fast32_t = int
+rbx.platform.typedef.__uint_fast32_t = uint
+rbx.platform.typedef.__int_fast64_t = long_long
+rbx.platform.typedef.__uint_fast64_t = ulong_long
+rbx.platform.typedef.__intptr_t = long
+rbx.platform.typedef.__uintptr_t = ulong
+rbx.platform.typedef.__intmax_t = long_long
+rbx.platform.typedef.__uintmax_t = ulong_long
+rbx.platform.typedef.__register_t = int
+rbx.platform.typedef.__vaddr_t = ulong
+rbx.platform.typedef.__paddr_t = ulong
+rbx.platform.typedef.__vsize_t = ulong
+rbx.platform.typedef.__psize_t = ulong
+rbx.platform.typedef.__clock_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__off_t = long_long
+rbx.platform.typedef.__ptrdiff_t = long
+rbx.platform.typedef.__size_t = ulong
+rbx.platform.typedef.__ssize_t = long
+rbx.platform.typedef.__time_t = int
+rbx.platform.typedef.__timer_t = int
+rbx.platform.typedef.__wchar_t = int
+rbx.platform.typedef.__wint_t = int
+rbx.platform.typedef.__rune_t = int
+rbx.platform.typedef.__wctrans_t = pointer
+rbx.platform.typedef.__wctype_t = pointer
+rbx.platform.typedef.__cpuid_t = ulong
+rbx.platform.typedef.__dev_t = int
+rbx.platform.typedef.__fixpt_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__in_addr_t = uint
+rbx.platform.typedef.__in_port_t = ushort
+rbx.platform.typedef.__ino_t = uint
+rbx.platform.typedef.__key_t = long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__rlim_t = ulong_long
+rbx.platform.typedef.__sa_family_t = uchar
+rbx.platform.typedef.__segsz_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.__swblk_t = int
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = int
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.unchar = uchar
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.cpuid_t = ulong
+rbx.platform.typedef.register_t = int
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.uint32_t = uint
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.uint64_t = ulong_long
+rbx.platform.typedef.intptr_t = long
+rbx.platform.typedef.uintptr_t = ulong
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.qaddr_t = pointer
+rbx.platform.typedef.vaddr_t = ulong
+rbx.platform.typedef.paddr_t = ulong
+rbx.platform.typedef.vsize_t = ulong
+rbx.platform.typedef.psize_t = ulong
+rbx.platform.typedef.caddr_t = string
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.daddr32_t = int
+rbx.platform.typedef.daddr64_t = long_long
+rbx.platform.typedef.dev_t = int
+rbx.platform.typedef.fixpt_t = uint
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ino_t = uint
+rbx.platform.typedef.key_t = long
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.segsz_t = int
+rbx.platform.typedef.swblk_t = int
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.useconds_t = uint
+rbx.platform.typedef.suseconds_t = int
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.sa_family_t = uchar
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.clock_t = int
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.time_t = int
+rbx.platform.typedef.timer_t = int
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.__fd_mask = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-linux/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-linux/types.conf
new file mode 100755
index 0000000..f319c0b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-linux/types.conf
@@ -0,0 +1,102 @@
+rbx.platform.typedef.__u_char = uchar
+rbx.platform.typedef.__u_short = ushort
+rbx.platform.typedef.__u_int = uint
+rbx.platform.typedef.__u_long = ulong
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long
+rbx.platform.typedef.__uint64_t = ulong
+rbx.platform.typedef.__quad_t = long
+rbx.platform.typedef.__u_quad_t = ulong
+rbx.platform.typedef.__dev_t = ulong
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__ino_t = ulong
+rbx.platform.typedef.__ino64_t = ulong
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = ulong
+rbx.platform.typedef.__off_t = long
+rbx.platform.typedef.__off64_t = long
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__clock_t = long
+rbx.platform.typedef.__rlim_t = ulong
+rbx.platform.typedef.__rlim64_t = ulong
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__time_t = long
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = long
+rbx.platform.typedef.__daddr_t = int
+rbx.platform.typedef.__swblk_t = long
+rbx.platform.typedef.__key_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__timer_t = pointer
+rbx.platform.typedef.blksize_t = long
+rbx.platform.typedef.__blkcnt_t = long
+rbx.platform.typedef.__blkcnt64_t = long
+rbx.platform.typedef.__fsblkcnt_t = ulong
+rbx.platform.typedef.__fsblkcnt64_t = ulong
+rbx.platform.typedef.__fsfilcnt_t = ulong
+rbx.platform.typedef.__fsfilcnt64_t = ulong
+rbx.platform.typedef.__ssize_t = long
+rbx.platform.typedef.__loff_t = long
+rbx.platform.typedef.*__qaddr_t = long
+rbx.platform.typedef.*__caddr_t = char
+rbx.platform.typedef.__intptr_t = long
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.quad_t = long
+rbx.platform.typedef.u_quad_t = ulong
+rbx.platform.typedef.loff_t = long
+rbx.platform.typedef.ino_t = ulong
+rbx.platform.typedef.dev_t = ulong
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = ulong
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.off_t = long
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = pointer
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.register_t = long
+rbx.platform.typedef.__sig_atomic_t = int
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.__fd_mask = long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.blkcnt_t = long
+rbx.platform.typedef.fsblkcnt_t = ulong
+rbx.platform.typedef.fsfilcnt_t = ulong
+rbx.platform.typedef.pthread_t = ulong
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.pthread_once_t = int
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.rlim_t = ulong
+rbx.platform.typedef.__rlimit_resource_t = int
+rbx.platform.typedef.__rusage_who_t = int
+rbx.platform.typedef.__priority_which_t = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-netbsd/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-netbsd/types.conf
new file mode 100755
index 0000000..c4df68a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-netbsd/types.conf
@@ -0,0 +1,128 @@
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__int_least8_t = char
+rbx.platform.typedef.__uint_least8_t = uchar
+rbx.platform.typedef.__int_least16_t = short
+rbx.platform.typedef.__uint_least16_t = ushort
+rbx.platform.typedef.__int_least32_t = int
+rbx.platform.typedef.__uint_least32_t = uint
+rbx.platform.typedef.__int_least64_t = long_long
+rbx.platform.typedef.__uint_least64_t = ulong_long
+rbx.platform.typedef.__int_fast8_t = int
+rbx.platform.typedef.__uint_fast8_t = uint
+rbx.platform.typedef.__int_fast16_t = int
+rbx.platform.typedef.__uint_fast16_t = uint
+rbx.platform.typedef.__int_fast32_t = int
+rbx.platform.typedef.__uint_fast32_t = uint
+rbx.platform.typedef.__int_fast64_t = long_long
+rbx.platform.typedef.__uint_fast64_t = ulong_long
+rbx.platform.typedef.__intptr_t = long
+rbx.platform.typedef.__uintptr_t = ulong
+rbx.platform.typedef.__intmax_t = long_long
+rbx.platform.typedef.__uintmax_t = ulong_long
+rbx.platform.typedef.__register_t = int
+rbx.platform.typedef.__vaddr_t = ulong
+rbx.platform.typedef.__paddr_t = ulong
+rbx.platform.typedef.__vsize_t = ulong
+rbx.platform.typedef.__psize_t = ulong
+rbx.platform.typedef.__clock_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__off_t = long_long
+rbx.platform.typedef.__ptrdiff_t = long
+rbx.platform.typedef.__size_t = ulong
+rbx.platform.typedef.__ssize_t = long
+rbx.platform.typedef.__time_t = int
+rbx.platform.typedef.__timer_t = int
+rbx.platform.typedef.__wchar_t = int
+rbx.platform.typedef.__wint_t = int
+rbx.platform.typedef.__rune_t = int
+rbx.platform.typedef.__wctrans_t = pointer
+rbx.platform.typedef.__wctype_t = pointer
+rbx.platform.typedef.__cpuid_t = ulong
+rbx.platform.typedef.__dev_t = int
+rbx.platform.typedef.__fixpt_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__in_addr_t = uint
+rbx.platform.typedef.__in_port_t = ushort
+rbx.platform.typedef.__ino_t = uint
+rbx.platform.typedef.__key_t = long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__rlim_t = ulong_long
+rbx.platform.typedef.__sa_family_t = uchar
+rbx.platform.typedef.__segsz_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.__swblk_t = int
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = int
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.unchar = uchar
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.cpuid_t = ulong
+rbx.platform.typedef.register_t = int
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.uint32_t = uint
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.uint64_t = ulong_long
+rbx.platform.typedef.intptr_t = long
+rbx.platform.typedef.uintptr_t = ulong
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.qaddr_t = pointer
+rbx.platform.typedef.vaddr_t = ulong
+rbx.platform.typedef.paddr_t = ulong
+rbx.platform.typedef.vsize_t = ulong
+rbx.platform.typedef.psize_t = ulong
+rbx.platform.typedef.caddr_t = string
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.daddr32_t = int
+rbx.platform.typedef.daddr64_t = long_long
+rbx.platform.typedef.dev_t = int
+rbx.platform.typedef.fixpt_t = uint
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ino_t = uint
+rbx.platform.typedef.key_t = long
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.segsz_t = int
+rbx.platform.typedef.swblk_t = int
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.useconds_t = uint
+rbx.platform.typedef.suseconds_t = int
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.sa_family_t = uchar
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.clock_t = int
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.time_t = int
+rbx.platform.typedef.timer_t = int
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.__fd_mask = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-openbsd/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-openbsd/types.conf
new file mode 100755
index 0000000..c4df68a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-openbsd/types.conf
@@ -0,0 +1,128 @@
+rbx.platform.typedef.__int8_t = char
+rbx.platform.typedef.__uint8_t = uchar
+rbx.platform.typedef.__int16_t = short
+rbx.platform.typedef.__uint16_t = ushort
+rbx.platform.typedef.__int32_t = int
+rbx.platform.typedef.__uint32_t = uint
+rbx.platform.typedef.__int64_t = long_long
+rbx.platform.typedef.__uint64_t = ulong_long
+rbx.platform.typedef.__int_least8_t = char
+rbx.platform.typedef.__uint_least8_t = uchar
+rbx.platform.typedef.__int_least16_t = short
+rbx.platform.typedef.__uint_least16_t = ushort
+rbx.platform.typedef.__int_least32_t = int
+rbx.platform.typedef.__uint_least32_t = uint
+rbx.platform.typedef.__int_least64_t = long_long
+rbx.platform.typedef.__uint_least64_t = ulong_long
+rbx.platform.typedef.__int_fast8_t = int
+rbx.platform.typedef.__uint_fast8_t = uint
+rbx.platform.typedef.__int_fast16_t = int
+rbx.platform.typedef.__uint_fast16_t = uint
+rbx.platform.typedef.__int_fast32_t = int
+rbx.platform.typedef.__uint_fast32_t = uint
+rbx.platform.typedef.__int_fast64_t = long_long
+rbx.platform.typedef.__uint_fast64_t = ulong_long
+rbx.platform.typedef.__intptr_t = long
+rbx.platform.typedef.__uintptr_t = ulong
+rbx.platform.typedef.__intmax_t = long_long
+rbx.platform.typedef.__uintmax_t = ulong_long
+rbx.platform.typedef.__register_t = int
+rbx.platform.typedef.__vaddr_t = ulong
+rbx.platform.typedef.__paddr_t = ulong
+rbx.platform.typedef.__vsize_t = ulong
+rbx.platform.typedef.__psize_t = ulong
+rbx.platform.typedef.__clock_t = int
+rbx.platform.typedef.__clockid_t = int
+rbx.platform.typedef.__off_t = long_long
+rbx.platform.typedef.__ptrdiff_t = long
+rbx.platform.typedef.__size_t = ulong
+rbx.platform.typedef.__ssize_t = long
+rbx.platform.typedef.__time_t = int
+rbx.platform.typedef.__timer_t = int
+rbx.platform.typedef.__wchar_t = int
+rbx.platform.typedef.__wint_t = int
+rbx.platform.typedef.__rune_t = int
+rbx.platform.typedef.__wctrans_t = pointer
+rbx.platform.typedef.__wctype_t = pointer
+rbx.platform.typedef.__cpuid_t = ulong
+rbx.platform.typedef.__dev_t = int
+rbx.platform.typedef.__fixpt_t = uint
+rbx.platform.typedef.__gid_t = uint
+rbx.platform.typedef.__id_t = uint
+rbx.platform.typedef.__in_addr_t = uint
+rbx.platform.typedef.__in_port_t = ushort
+rbx.platform.typedef.__ino_t = uint
+rbx.platform.typedef.__key_t = long
+rbx.platform.typedef.__mode_t = uint
+rbx.platform.typedef.__nlink_t = uint
+rbx.platform.typedef.__pid_t = int
+rbx.platform.typedef.__rlim_t = ulong_long
+rbx.platform.typedef.__sa_family_t = uchar
+rbx.platform.typedef.__segsz_t = int
+rbx.platform.typedef.__socklen_t = uint
+rbx.platform.typedef.__swblk_t = int
+rbx.platform.typedef.__uid_t = uint
+rbx.platform.typedef.__useconds_t = uint
+rbx.platform.typedef.__suseconds_t = int
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.unchar = uchar
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.cpuid_t = ulong
+rbx.platform.typedef.register_t = int
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.uint32_t = uint
+rbx.platform.typedef.int64_t = long_long
+rbx.platform.typedef.uint64_t = ulong_long
+rbx.platform.typedef.intptr_t = long
+rbx.platform.typedef.uintptr_t = ulong
+rbx.platform.typedef.u_int8_t = uchar
+rbx.platform.typedef.u_int16_t = ushort
+rbx.platform.typedef.u_int32_t = uint
+rbx.platform.typedef.u_int64_t = ulong_long
+rbx.platform.typedef.quad_t = long_long
+rbx.platform.typedef.u_quad_t = ulong_long
+rbx.platform.typedef.qaddr_t = pointer
+rbx.platform.typedef.vaddr_t = ulong
+rbx.platform.typedef.paddr_t = ulong
+rbx.platform.typedef.vsize_t = ulong
+rbx.platform.typedef.psize_t = ulong
+rbx.platform.typedef.caddr_t = string
+rbx.platform.typedef.daddr_t = int
+rbx.platform.typedef.daddr32_t = int
+rbx.platform.typedef.daddr64_t = long_long
+rbx.platform.typedef.dev_t = int
+rbx.platform.typedef.fixpt_t = uint
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.id_t = uint
+rbx.platform.typedef.ino_t = uint
+rbx.platform.typedef.key_t = long
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.rlim_t = ulong_long
+rbx.platform.typedef.segsz_t = int
+rbx.platform.typedef.swblk_t = int
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.useconds_t = uint
+rbx.platform.typedef.suseconds_t = int
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.sa_family_t = uchar
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.clock_t = int
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.time_t = int
+rbx.platform.typedef.timer_t = int
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.__fd_mask = int
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-solaris/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-solaris/types.conf
new file mode 100755
index 0000000..f461b7e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-solaris/types.conf
@@ -0,0 +1,122 @@
+rbx.platform.typedef.lock_t = uchar
+rbx.platform.typedef.int8_t = char
+rbx.platform.typedef.int16_t = short
+rbx.platform.typedef.int32_t = int
+rbx.platform.typedef.int64_t = long
+rbx.platform.typedef.uint8_t = uchar
+rbx.platform.typedef.uint16_t = ushort
+rbx.platform.typedef.uint32_t = uint
+rbx.platform.typedef.uint64_t = ulong
+rbx.platform.typedef.intmax_t = long
+rbx.platform.typedef.uintmax_t = ulong
+rbx.platform.typedef.intptr_t = long
+rbx.platform.typedef.uintptr_t = ulong
+rbx.platform.typedef.int_fast8_t = char
+rbx.platform.typedef.int_fast16_t = int
+rbx.platform.typedef.int_fast32_t = int
+rbx.platform.typedef.int_fast64_t = long
+rbx.platform.typedef.uint_fast8_t = uchar
+rbx.platform.typedef.uint_fast16_t = uint
+rbx.platform.typedef.uint_fast32_t = uint
+rbx.platform.typedef.uint_fast64_t = ulong
+rbx.platform.typedef.int_least8_t = char
+rbx.platform.typedef.int_least16_t = short
+rbx.platform.typedef.int_least32_t = int
+rbx.platform.typedef.int_least64_t = long
+rbx.platform.typedef.uint_least8_t = uchar
+rbx.platform.typedef.uint_least16_t = ushort
+rbx.platform.typedef.uint_least32_t = uint
+rbx.platform.typedef.uint_least64_t = ulong
+rbx.platform.typedef.longlong_t = long_long
+rbx.platform.typedef.u_longlong_t = ulong_long
+rbx.platform.typedef.t_scalar_t = int
+rbx.platform.typedef.t_uscalar_t = uint
+rbx.platform.typedef.uchar_t = uchar
+rbx.platform.typedef.ushort_t = ushort
+rbx.platform.typedef.uint_t = uint
+rbx.platform.typedef.ulong_t = ulong
+rbx.platform.typedef.*caddr_t = char
+rbx.platform.typedef.daddr_t = long
+rbx.platform.typedef.cnt_t = short
+rbx.platform.typedef.ptrdiff_t = long
+rbx.platform.typedef.pfn_t = ulong
+rbx.platform.typedef.pgcnt_t = ulong
+rbx.platform.typedef.spgcnt_t = long
+rbx.platform.typedef.use_t = uchar
+rbx.platform.typedef.sysid_t = short
+rbx.platform.typedef.index_t = short
+rbx.platform.typedef.off_t = long
+rbx.platform.typedef.off64_t = long
+rbx.platform.typedef.ino_t = ulong
+rbx.platform.typedef.blkcnt_t = long
+rbx.platform.typedef.fsblkcnt_t = ulong
+rbx.platform.typedef.fsfilcnt_t = ulong
+rbx.platform.typedef.ino64_t = ulong
+rbx.platform.typedef.blkcnt64_t = long
+rbx.platform.typedef.fsblkcnt64_t = ulong
+rbx.platform.typedef.fsfilcnt64_t = ulong
+rbx.platform.typedef.blksize_t = int
+rbx.platform.typedef.pad64_t = long
+rbx.platform.typedef.upad64_t = ulong
+rbx.platform.typedef.offset_t = long_long
+rbx.platform.typedef.u_offset_t = ulong_long
+rbx.platform.typedef.len_t = ulong_long
+rbx.platform.typedef.diskaddr_t = ulong_long
+rbx.platform.typedef.k_fltset_t = uint
+rbx.platform.typedef.id_t = int
+rbx.platform.typedef.lgrp_id_t = int
+rbx.platform.typedef.useconds_t = uint
+rbx.platform.typedef.suseconds_t = long
+rbx.platform.typedef.major_t = uint
+rbx.platform.typedef.minor_t = uint
+rbx.platform.typedef.pri_t = short
+rbx.platform.typedef.cpu_flag_t = ushort
+rbx.platform.typedef.o_mode_t = ushort
+rbx.platform.typedef.o_dev_t = short
+rbx.platform.typedef.o_uid_t = ushort
+rbx.platform.typedef.o_gid_t = ushort
+rbx.platform.typedef.o_nlink_t = short
+rbx.platform.typedef.o_pid_t = short
+rbx.platform.typedef.o_ino_t = ushort
+rbx.platform.typedef.key_t = int
+rbx.platform.typedef.mode_t = uint
+rbx.platform.typedef.uid_t = uint
+rbx.platform.typedef.gid_t = uint
+rbx.platform.typedef.datalink_id_t = uint
+rbx.platform.typedef.taskid_t = int
+rbx.platform.typedef.projid_t = int
+rbx.platform.typedef.poolid_t = int
+rbx.platform.typedef.zoneid_t = int
+rbx.platform.typedef.ctid_t = int
+rbx.platform.typedef.pthread_t = uint
+rbx.platform.typedef.pthread_key_t = uint
+rbx.platform.typedef.dev_t = ulong
+rbx.platform.typedef.nlink_t = uint
+rbx.platform.typedef.pid_t = int
+rbx.platform.typedef.size_t = ulong
+rbx.platform.typedef.ssize_t = long
+rbx.platform.typedef.time_t = long
+rbx.platform.typedef.clock_t = long
+rbx.platform.typedef.clockid_t = int
+rbx.platform.typedef.timer_t = int
+rbx.platform.typedef.unchar = uchar
+rbx.platform.typedef.ushort = ushort
+rbx.platform.typedef.uint = uint
+rbx.platform.typedef.ulong = ulong
+rbx.platform.typedef.u_char = uchar
+rbx.platform.typedef.u_short = ushort
+rbx.platform.typedef.u_int = uint
+rbx.platform.typedef.u_long = ulong
+rbx.platform.typedef.hrtime_t = long_long
+rbx.platform.typedef.fd_mask = long
+rbx.platform.typedef.fds_mask = long
+rbx.platform.typedef.sa_family_t = ushort
+rbx.platform.typedef.socklen_t = uint
+rbx.platform.typedef.nfds_t = ulong
+rbx.platform.typedef.disp_lock_t = uchar
+rbx.platform.typedef.model_t = uint
+rbx.platform.typedef.in_port_t = ushort
+rbx.platform.typedef.in_addr_t = uint
+rbx.platform.typedef.ipaddr_t = uint
+rbx.platform.typedef.rlim_t = ulong
+rbx.platform.typedef.rlim64_t = ulong_long
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-windows/types.conf b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-windows/types.conf
new file mode 100755
index 0000000..0909c19
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/platform/x86_64-windows/types.conf
@@ -0,0 +1,27 @@
+rbx.platform.typedef.size_t = ulong_long
+rbx.platform.typedef.ssize_t = long_long
+rbx.platform.typedef.intptr_t = long_long
+rbx.platform.typedef.uintptr_t = ulong_long
+rbx.platform.typedef.ptrdiff_t = long_long
+rbx.platform.typedef.wchar_t = ushort
+rbx.platform.typedef.wint_t = ushort
+rbx.platform.typedef.wctype_t = ushort
+rbx.platform.typedef.errno_t = int
+rbx.platform.typedef.__time32_t = long
+rbx.platform.typedef.__time64_t = long_long
+rbx.platform.typedef.time_t = long_long
+rbx.platform.typedef._ino_t = ushort
+rbx.platform.typedef.ino_t = ushort
+rbx.platform.typedef._dev_t = uint
+rbx.platform.typedef.dev_t = uint
+rbx.platform.typedef._pid_t = long_long
+rbx.platform.typedef.pid_t = long_long
+rbx.platform.typedef._mode_t = ushort
+rbx.platform.typedef.mode_t = ushort
+rbx.platform.typedef._off_t = long
+rbx.platform.typedef.off32_t = long
+rbx.platform.typedef._off64_t = long_long
+rbx.platform.typedef.off64_t = long_long
+rbx.platform.typedef.off_t = long_long
+rbx.platform.typedef.useconds_t = uint
+rbx.platform.typedef._sigset_t = ulong_long
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/pointer.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/pointer.rb
new file mode 100755
index 0000000..fec7671
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/pointer.rb
@@ -0,0 +1,134 @@
+#
+# Copyright (C) 2008, 2009 Wayne Meissner
+# Copyright (c) 2007, 2008 Evan Phoenix
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+#   may be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+require 'ffi/platform'
+module FFI
+  class Pointer
+    
+    # Pointer size
+    SIZE = Platform::ADDRESS_SIZE / 8
+
+    # Return the size of a pointer on the current platform, in bytes
+    # @return [Numeric]
+    def self.size
+      SIZE
+    end
+
+    # @param [nil,Numeric] len length of string to return
+    # @return [String]
+    # Read pointer's contents as a string, or the first +len+ bytes of the 
+    # equivalent string if +len+ is not +nil+.
+    def read_string(len=nil)
+      if len
+        get_bytes(0, len)
+      else
+        get_string(0)
+      end
+    end
+
+    # @param [Numeric] len length of string to return
+    # @return [String]
+    # Read the first +len+ bytes of pointer's contents as a string.
+    #
+    # Same as:
+    #  ptr.read_string(len)  # with len not nil
+    def read_string_length(len)
+      get_bytes(0, len)
+    end
+
+    # @return [String]
+    # Read pointer's contents as a string.
+    #
+    # Same as:
+    #  ptr.read_string  # with no len
+    def read_string_to_null
+      get_string(0)
+    end
+
+    # @param [String] str string to write
+    # @param [Numeric] len length of string to return
+    # @return [self]
+    # Write +len+ first bytes of +str+ in pointer's contents.
+    #
+    # Same as:
+    #  ptr.write_string(str, len)   # with len not nil
+    def write_string_length(str, len)
+      put_bytes(0, str, 0, len)
+    end
+
+    # @param [String] str string to write
+    # @param [Numeric] len length of string to return
+    # @return [self]
+    # Write +str+ in pointer's contents, or first +len+ bytes if 
+    # +len+ is not +nil+.
+    def write_string(str, len=nil)
+      len = str.bytesize unless len
+      # Write the string data without NUL termination
+      put_bytes(0, str, 0, len)
+    end
+
+    # @param [Type] type type of data to read from pointer's contents
+    # @param [Symbol] reader method to send to +self+ to read +type+
+    # @param [Numeric] length
+    # @return [Array]
+    # Read an array of +type+ of length +length+.
+    # @example
+    #  ptr.read_array_of_type(TYPE_UINT8, :get_uint8, 4) # -> [1, 2, 3, 4]
+    def read_array_of_type(type, reader, length)
+      ary = []
+      size = FFI.type_size(type)
+      tmp = self
+      length.times { |j|
+        ary << tmp.send(reader)
+        tmp += size unless j == length-1 # avoid OOB
+      }
+      ary
+    end
+
+    # @param [Type] type type of data to write to pointer's contents
+    # @param [Symbol] writer method to send to +self+ to write +type+
+    # @param [Array] ary
+    # @return [self]
+    # Write +ary+ in pointer's contents as +type+.
+    # @example
+    #  ptr.write_array_of_type(TYPE_UINT8, :put_uint8, [1, 2, 3 ,4])
+    def write_array_of_type(type, writer, ary)
+      size = FFI.type_size(type)
+      tmp = self
+      ary.each_with_index {|i, j|
+        tmp.send(writer, i)
+        tmp += size unless j == ary.length-1 # avoid OOB
+      }
+      self
+    end
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/struct.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/struct.rb
new file mode 100755
index 0000000..89231ba
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/struct.rb
@@ -0,0 +1,373 @@
+#
+# Copyright (C) 2008-2010 Wayne Meissner
+# Copyright (C) 2008, 2009 Andrea Fazzi
+# Copyright (C) 2008, 2009 Luc Heinrich
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+#   may be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+require 'ffi/platform'
+require 'ffi/struct_layout_builder'
+
+module FFI
+
+  class StructLayout
+
+    # @return [Array<Array(Symbol, Numeric)>
+    # Get an array of tuples (field name, offset of the field).
+    def offsets
+      members.map { |m| [ m, self[m].offset ] }
+    end
+
+    # @return [Numeric]
+    # Get the offset of a field.
+    def offset_of(field_name)
+      self[field_name].offset
+    end
+
+    # An enum {Field} in a {StructLayout}.
+    class Enum < Field
+
+      # @param [AbstractMemory] ptr pointer on a {Struct}
+      # @return [Object]
+      # Get an object of type {#type} from memory pointed by +ptr+.
+      def get(ptr)
+        type.find(ptr.get_int(offset))
+      end
+
+      # @param [AbstractMemory] ptr pointer on a {Struct}
+      # @param  value
+      # @return [nil]
+      # Set +value+ into memory pointed by +ptr+.
+      def put(ptr, value)
+        ptr.put_int(offset, type.find(value))
+      end
+
+    end
+
+    class InnerStruct < Field
+      def get(ptr)
+        type.struct_class.new(ptr.slice(self.offset, self.size))
+      end
+
+     def put(ptr, value)
+       raise TypeError, "wrong value type (expected #{type.struct_class})" unless value.is_a?(type.struct_class)
+       ptr.slice(self.offset, self.size).__copy_from__(value.pointer, self.size)
+     end
+    end
+
+    class Mapped < Field
+      def initialize(name, offset, type, orig_field)
+        super(name, offset, type)
+        @orig_field = orig_field
+      end
+
+      def get(ptr)
+        type.from_native(@orig_field.get(ptr), nil)
+      end
+
+      def put(ptr, value)
+        @orig_field.put(ptr, type.to_native(value, nil))
+      end
+    end
+  end
+
+  
+  class Struct
+
+    # Get struct size
+    # @return [Numeric]
+    def size
+      self.class.size
+    end
+
+    # @return [Fixnum] Struct alignment
+    def alignment
+      self.class.alignment
+    end
+    alias_method :align, :alignment
+
+    # (see FFI::StructLayout#offset_of)
+    def offset_of(name)
+      self.class.offset_of(name)
+    end
+
+    # (see FFI::StructLayout#members)
+    def members
+      self.class.members
+    end
+
+    # @return [Array]
+    # Get array of values from Struct fields.
+    def values
+      members.map { |m| self[m] }
+    end
+
+    # (see FFI::StructLayout#offsets)
+    def offsets
+      self.class.offsets
+    end
+
+    # Clear the struct content.
+    # @return [self]
+    def clear
+      pointer.clear
+      self
+    end
+
+    # Get {Pointer} to struct content.
+    # @return [AbstractMemory]
+    def to_ptr
+      pointer
+    end
+
+    # Get struct size
+    # @return [Numeric]
+    def self.size
+      defined?(@layout) ? @layout.size : defined?(@size) ? @size : 0
+    end
+
+    # set struct size
+    # @param [Numeric] size
+    # @return [size]
+    def self.size=(size)
+      raise ArgumentError, "Size already set" if defined?(@size) || defined?(@layout)
+      @size = size
+    end
+
+    # @return (see Struct#alignment)
+    def self.alignment
+      @layout.alignment
+    end
+
+    # (see FFI::Type#members)
+    def self.members
+      @layout.members
+    end
+
+    # (see FFI::StructLayout#offsets)
+    def self.offsets
+      @layout.offsets
+    end
+
+    # (see FFI::StructLayout#offset_of)
+    def self.offset_of(name)
+      @layout.offset_of(name)
+    end
+
+    def self.in
+      ptr(:in)
+    end
+
+    def self.out
+      ptr(:out)
+    end
+
+    def self.ptr(flags = :inout)
+      @ref_data_type ||= Type::Mapped.new(StructByReference.new(self))
+    end
+
+    def self.val
+      @val_data_type ||= StructByValue.new(self)
+    end
+
+    def self.by_value
+      self.val
+    end
+
+    def self.by_ref(flags = :inout)
+      self.ptr(flags)
+    end
+
+    class ManagedStructConverter < StructByReference
+
+      # @param [Struct] struct_class
+      def initialize(struct_class)
+        super(struct_class)
+
+        raise NoMethodError, "release() not implemented for class #{struct_class}" unless struct_class.respond_to? :release
+        @method = struct_class.method(:release)
+      end
+
+      # @param [Pointer] ptr
+      # @param [nil] ctx
+      # @return [Struct]
+      def from_native(ptr, ctx)
+        struct_class.new(AutoPointer.new(ptr, @method))
+      end
+    end
+
+    def self.auto_ptr
+      @managed_type ||= Type::Mapped.new(ManagedStructConverter.new(self))
+    end
+
+
+    class << self
+      public
+
+      # @return [StructLayout]
+      # @overload layout
+      #  @return [StructLayout]
+      #  Get struct layout.
+      # @overload layout(*spec)
+      #  @param [Array<Symbol, Integer>,Array(Hash)] spec
+      #  @return [StructLayout]
+      #  Create struct layout from +spec+.
+      #  @example Creating a layout from an array +spec+
+      #    class MyStruct < Struct
+      #      layout :field1, :int,
+      #             :field2, :pointer,
+      #             :field3, :string
+      #    end
+      #  @example Creating a layout from an array +spec+ with offset
+      #    class MyStructWithOffset < Struct
+      #      layout :field1, :int,
+      #             :field2, :pointer, 6,  # set offset to 6 for this field
+      #             :field3, :string
+      #    end
+      #  @example Creating a layout from a hash +spec+ (Ruby 1.9 only)
+      #    class MyStructFromHash < Struct
+      #      layout :field1 => :int,
+      #             :field2 => :pointer,
+      #             :field3 => :string
+      #    end
+      #  @example Creating a layout with pointers to functions
+      #    class MyFunctionTable < Struct
+      #      layout :function1, callback([:int, :int], :int),
+      #             :function2, callback([:pointer], :void),
+      #             :field3, :string
+      #    end
+      #  @note Creating a layout from a hash +spec+ is supported only for Ruby 1.9.
+      def layout(*spec)
+        #raise RuntimeError, "struct layout already defined for #{self.inspect}" if defined?(@layout)
+        return @layout if spec.size == 0
+
+        builder = StructLayoutBuilder.new
+        builder.union = self < Union
+        builder.packed = @packed if defined?(@packed)
+        builder.alignment = @min_alignment if defined?(@min_alignment)
+
+        if spec[0].kind_of?(Hash)
+          hash_layout(builder, spec)
+        else
+          array_layout(builder, spec)
+        end
+        builder.size = @size if defined?(@size) && @size > builder.size
+        cspec = builder.build
+        @layout = cspec unless self == Struct
+        @size = cspec.size
+        return cspec
+      end
+
+
+      protected
+
+      def callback(params, ret)
+        mod = enclosing_module
+        FFI::CallbackInfo.new(find_type(ret, mod), params.map { |e| find_type(e, mod) })
+      end
+
+      def packed(packed = 1)
+        @packed = packed
+      end
+      alias :pack :packed
+      
+      def aligned(alignment = 1)
+        @min_alignment = alignment
+      end
+      alias :align :aligned
+
+      def enclosing_module
+        begin
+          mod = self.name.split("::")[0..-2].inject(Object) { |obj, c| obj.const_get(c) }
+          (mod < FFI::Library || mod < FFI::Struct || mod.respond_to?(:find_type)) ? mod : nil
+        rescue Exception
+          nil
+        end
+      end
+
+
+      def find_field_type(type, mod = enclosing_module)
+        if type.kind_of?(Class) && type < Struct
+          FFI::Type::Struct.new(type)
+
+        elsif type.kind_of?(Class) && type < FFI::StructLayout::Field
+          type
+
+        elsif type.kind_of?(::Array)
+          FFI::Type::Array.new(find_field_type(type[0]), type[1])
+
+        else
+          find_type(type, mod)
+        end
+      end
+
+      def find_type(type, mod = enclosing_module)
+        if mod
+          mod.find_type(type)
+        end || FFI.find_type(type)
+      end
+
+      private
+
+      # @param [StructLayoutBuilder] builder
+      # @param [Hash] spec
+      # @return [builder]
+      # @raise if Ruby 1.8
+      # Add hash +spec+ to +builder+.
+      def hash_layout(builder, spec)
+        raise "Ruby version not supported" if RUBY_VERSION =~ /1\.8\.*/
+        spec[0].each do |name, type|
+          builder.add name, find_field_type(type), nil
+        end
+      end
+
+      # @param [StructLayoutBuilder] builder
+      # @param [Array<Symbol, Integer>] spec
+      # @return [builder]
+      # Add array +spec+ to +builder+.
+      def array_layout(builder, spec)
+        i = 0
+        while i < spec.size
+          name, type = spec[i, 2]
+          i += 2
+
+          # If the next param is a Integer, it specifies the offset
+          if spec[i].kind_of?(Integer)
+            offset = spec[i]
+            i += 1
+          else
+            offset = nil
+          end
+
+          builder.add name, find_field_type(type), offset
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/struct_layout_builder.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/struct_layout_builder.rb
new file mode 100755
index 0000000..918c790
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/struct_layout_builder.rb
@@ -0,0 +1,227 @@
+#
+# Copyright (C) 2008-2010 Wayne Meissner
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+#   may be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+module FFI
+
+  # Build a {StructLayout struct layout}.
+  class StructLayoutBuilder
+    attr_reader :size
+    attr_reader :alignment
+
+    def initialize
+      @size = 0
+      @alignment = 1
+      @min_alignment = 1
+      @packed = false
+      @union = false
+      @fields = Array.new
+    end
+
+    # Set size attribute with +size+ only if +size+ is greater than attribute value.
+    # @param [Numeric] size
+    def size=(size)
+      @size = size if size > @size
+    end
+
+    # Set alignment attribute with +align+ only if it is greater than attribute value.
+    # @param [Numeric] align
+    def alignment=(align)
+      @alignment = align if align > @alignment
+      @min_alignment = align
+    end
+
+    # Set union attribute.
+    # Set to +true+ to build a {Union} instead of a {Struct}.
+    # @param [Boolean] is_union
+    # @return [is_union]
+    def union=(is_union)
+      @union = is_union
+    end
+
+    # Building a {Union} or a {Struct} ?
+    #
+    # @return [Boolean]
+    #
+    def union?
+      @union
+    end
+
+    # Set packed attribute
+    # @overload packed=(packed) Set alignment and packed attributes to
+    #   +packed+.
+    #
+    #   @param [Fixnum] packed
+    #
+    #   @return [packed]
+    # @overload packed=(packed) Set packed attribute.
+    #   @param packed
+    #
+    #   @return [0,1]
+    #
+    def packed=(packed)
+      if packed.is_a?(Fixnum)
+        @alignment = packed
+        @packed = packed
+      else
+        @packed = packed ? 1 : 0
+      end
+    end
+
+
+    # List of number types
+    NUMBER_TYPES = [
+      Type::INT8,
+      Type::UINT8,
+      Type::INT16,
+      Type::UINT16,
+      Type::INT32,
+      Type::UINT32,
+      Type::LONG,
+      Type::ULONG,
+      Type::INT64,
+      Type::UINT64,
+      Type::FLOAT32,
+      Type::FLOAT64,
+      Type::LONGDOUBLE,
+      Type::BOOL,
+    ]
+
+    # @param [String, Symbol] name name of the field
+    # @param [Array, DataConverter, Struct, StructLayout::Field, Symbol, Type] type type of the field
+    # @param [Numeric, nil] offset
+    # @return [self]
+    # Add a field to the builder.
+    # @note Setting +offset+ to +nil+ or +-1+ is equivalent to +0+.
+    def add(name, type, offset = nil)
+
+      if offset.nil? || offset == -1
+        offset = @union ? 0 : align(@size, @packed ? [ @packed, type.alignment ].min : [ @min_alignment, type.alignment ].max)
+      end
+
+      #
+      # If a FFI::Type type was passed in as the field arg, try and convert to a StructLayout::Field instance
+      #
+      field = type.is_a?(StructLayout::Field) ? type : field_for_type(name, offset, type)
+      @fields << field
+      @alignment = [ @alignment, field.alignment ].max unless @packed
+      @size = [ @size, field.size + (@union ? 0 : field.offset) ].max
+
+      return self
+    end
+
+    # @param (see #add)
+    # @return (see #add)
+    # Same as {#add}.
+    # @see #add
+    def add_field(name, type, offset = nil)
+      add(name, type, offset)
+    end
+
+    # @param (see #add)
+    # @return (see #add)
+    # Add a struct as a field to the builder.
+    def add_struct(name, type, offset = nil)
+      add(name, Type::Struct.new(type), offset)
+    end
+
+    # @param name (see #add)
+    # @param type (see #add)
+    # @param [Numeric] count array length
+    # @param offset (see #add)
+    # @return (see #add)
+    # Add an array as a field to the builder.
+    def add_array(name, type, count, offset = nil)
+      add(name, Type::Array.new(type, count), offset)
+    end
+
+    # @return [StructLayout]
+    # Build and return the struct layout.
+    def build
+      # Add tail padding if the struct is not packed
+      size = @packed ? @size : align(@size, @alignment)
+
+      layout = StructLayout.new(@fields, size, @alignment)
+      layout.__union! if @union
+      layout
+    end
+
+    private
+
+    # @param [Numeric] offset
+    # @param [Numeric] align
+    # @return [Numeric]
+    def align(offset, align)
+      align + ((offset - 1) & ~(align - 1));
+    end
+
+    # @param (see #add)
+    # @return [StructLayout::Field]
+    def field_for_type(name, offset, type)
+      field_class = case
+      when type.is_a?(Type::Function)
+        StructLayout::Function
+
+      when type.is_a?(Type::Struct)
+        StructLayout::InnerStruct
+
+      when type.is_a?(Type::Array)
+        StructLayout::Array
+
+      when type.is_a?(FFI::Enum)
+        StructLayout::Enum
+
+      when NUMBER_TYPES.include?(type)
+        StructLayout::Number
+
+      when type == Type::POINTER
+        StructLayout::Pointer
+
+      when type == Type::STRING
+        StructLayout::String
+
+      when type.is_a?(Class) && type < StructLayout::Field
+        type
+
+      when type.is_a?(DataConverter)
+        return StructLayout::Mapped.new(name, offset, Type::Mapped.new(type), field_for_type(name, offset, type.native_type))
+
+      when type.is_a?(Type::Mapped)
+        return StructLayout::Mapped.new(name, offset, type, field_for_type(name, offset, type.native_type))
+
+      else
+        raise TypeError, "invalid struct field type #{type.inspect}"
+      end
+
+      field_class.new(name, offset, type)
+    end
+  end
+
+end
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/tools/const_generator.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/tools/const_generator.rb
new file mode 100755
index 0000000..dfc622e
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/tools/const_generator.rb
@@ -0,0 +1,229 @@
+require 'tempfile'
+require 'open3'
+
+module FFI
+
+  # ConstGenerator turns C constants into ruby values.
+  #
+  # @example a simple example for stdio
+  #  cg = FFI::ConstGenerator.new('stdio') do |gen|
+  #    gen.const(:SEEK_SET)
+  #    gen.const('SEEK_CUR')
+  #    gen.const('seek_end')   # this constant does not exist
+  #  end            # #calculate called automatically at the end of the block
+  #
+  #  cg['SEEK_SET'] # => 0
+  #  cg['SEEK_CUR'] # => 1
+  #  cg['seek_end'] # => nil
+  #  cg.to_ruby     # => "SEEK_SET = 0\nSEEK_CUR = 1\n# seek_end not available"
+  class ConstGenerator
+    @options = {}
+    attr_reader :constants
+
+    # Creates a new constant generator that uses +prefix+ as a name, and an
+    # options hash.
+    #
+    # The only option is +:required+, which if set to +true+ raises an error if a
+    # constant you have requested was not found.
+    # 
+    # @param [#to_s] prefix
+    # @param [Hash] options
+    # @return 
+    # @option options [Boolean] :required
+    # @overload initialize(prefix, options)
+    # @overload initialize(prefix, options) { |gen| ... }
+    #  @yieldparam [ConstGenerator] gen new generator is passed to the block
+    #  When passed a block, {#calculate} is automatically called at the end of
+    #  the block, otherwise you must call it yourself.
+    def initialize(prefix = nil, options = {})
+      @includes = ['stdio.h', 'stddef.h']
+      @constants = {}
+      @prefix = prefix
+
+      @required = options[:required]
+      @options = options
+
+      if block_given? then
+        yield self
+        calculate self.class.options.merge(options)
+      end
+    end
+    # Set class options
+    # These options are merged with {#initialize} options when it is called with a block.
+    # @param [Hash] options
+    # @return [Hash] class options
+    def self.options=(options)
+      @options = options
+    end
+    # Get class options.
+    # @return [Hash] class options
+    def self.options
+      @options
+    end
+    # @param [String] name
+    # @return constant value (converted if a +converter+ was defined).
+    # Access a constant by name.
+    def [](name)
+      @constants[name].converted_value
+    end
+
+    # Request the value for C constant +name+.
+    #
+    # @param [#to_s] name C constant name
+    # @param [String] format a printf format string to print the value out
+    # @param [String] cast a C cast for the value
+    # @param ruby_name alternate ruby name for {#to_ruby}
+    #
+    # @overload const(name, format=nil, cast='', ruby_name=nil, converter=nil)
+    #  +converter+ is a Method or a Proc.
+    #  @param [#call] converter convert the value from a string to the appropriate
+    #   type for {#to_ruby}.
+    # @overload const(name, format=nil, cast='', ruby_name=nil) { |value| ... }
+    #  Use a converter block. This block convert the value from a string to the 
+    #  appropriate type for {#to_ruby}.
+    #  @yieldparam value constant value
+    def const(name, format = nil, cast = '', ruby_name = nil, converter = nil,
+              &converter_proc)
+      format ||= '%d'
+      cast ||= ''
+
+      if converter_proc and converter then
+        raise ArgumentError, "Supply only converter or converter block"
+      end
+
+      converter = converter_proc if converter.nil?
+
+      const = Constant.new name, format, cast, ruby_name, converter
+      @constants[name.to_s] = const
+      return const
+    end
+
+    # Calculate constants values.
+    # @param [Hash] options
+    # @option options [String] :cppflags flags for C compiler
+    # @return [nil]
+    # @raise if a constant is missing and +:required+ was set to +true+ (see {#initialize})
+    def calculate(options = {})
+      binary = File.join Dir.tmpdir, "rb_const_gen_bin_#{Process.pid}"
+
+      Tempfile.open("#{@prefix}.const_generator") do |f|
+        @includes.each do |inc|
+          f.puts "#include <#{inc}>"
+        end
+        f.puts "\nint main(int argc, char **argv)\n{"
+
+        @constants.each_value do |const|
+          f.puts <<-EOF
+  #ifdef #{const.name}
+  printf("#{const.name} #{const.format}\\n", #{const.cast}#{const.name});
+  #endif
+          EOF
+        end
+
+        f.puts "\n\treturn 0;\n}"
+        f.flush
+
+        output = `gcc #{options[:cppflags]} -D_DARWIN_USE_64_BIT_INODE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -x c -Wall -Werror #{f.path} -o #{binary} 2>&1`
+
+        unless $?.success? then
+          output = output.split("\n").map { |l| "\t#{l}" }.join "\n"
+          raise "Compilation error generating constants #{@prefix}:\n#{output}"
+        end
+      end
+
+      output = `#{binary}`
+      File.unlink(binary + (FFI::Platform.windows? ? ".exe" : ""))
+      output.each_line do |line|
+        line =~ /^(\S+)\s(.*)$/
+        const = @constants[$1]
+        const.value = $2
+      end
+
+      missing_constants = @constants.select do |name, constant|
+        constant.value.nil?
+      end.map { |name,| name }
+
+      if @required and not missing_constants.empty? then
+        raise "Missing required constants for #{@prefix}: #{missing_constants.join ', '}"
+      end
+    end
+
+    # Dump constants to +io+.
+    # @param [#puts] io
+    # @return [nil]
+    def dump_constants(io)
+      @constants.each do |name, constant|
+        name = [@prefix, name].join '.' if @prefix
+        io.puts "#{name} = #{constant.converted_value}"
+      end
+    end
+
+    # Outputs values for discovered constants.  If the constant's value was
+    # not discovered it is not omitted.
+    # @return [String]
+    def to_ruby
+      @constants.sort_by { |name,| name }.map do |name, constant|
+        if constant.value.nil? then
+          "# #{name} not available"
+        else
+          constant.to_ruby
+        end
+      end.join "\n"
+    end
+
+    # Add additional C include file(s) to calculate constants from.
+    # @note +stdio.h+ and +stddef.h+ automatically included
+    # @param [List<String>, Array<String>] i include file(s)
+    # @return [Array<String>] array of include files
+    def include(*i)
+      @includes |= i.flatten
+    end
+
+  end
+
+  # This class hold constants for {ConstGenerator}
+  class ConstGenerator::Constant
+
+    attr_reader :name, :format, :cast
+    attr_accessor :value
+
+    # @param [#to_s] name
+    # @param [String] format a printf format string to print the value out
+    # @param [String] cast a C cast for the value
+    # @param ruby_name alternate ruby name for {#to_ruby}
+    # @param [#call] converter convert the value from a string to the appropriate
+    #  type for {#to_ruby}.
+    def initialize(name, format, cast, ruby_name = nil, converter=nil)
+      @name = name
+      @format = format
+      @cast = cast
+      @ruby_name = ruby_name
+      @converter = converter
+      @value = nil
+    end
+
+    # Return constant value (converted if a +converter+ was defined).
+    # @return constant value.
+    def converted_value
+      if @converter
+        @converter.call(@value)
+      else
+        @value
+      end
+    end
+
+    # get constant ruby name
+    # @return [String]
+    def ruby_name
+      @ruby_name || @name
+    end
+
+    # Get an evaluable string from constant.
+    # @return [String]
+    def to_ruby
+      "#{ruby_name} = #{converted_value}"
+    end
+
+  end  
+
+end
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/tools/generator.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/tools/generator.rb
new file mode 100755
index 0000000..29b59e1
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/tools/generator.rb
@@ -0,0 +1,60 @@
+module FFI
+
+  # @private
+  class Generator
+
+    def initialize(ffi_name, rb_name, options = {})
+      @ffi_name = ffi_name
+      @rb_name = rb_name
+      @options = options
+      @name = File.basename rb_name, '.rb'
+
+      file = File.read @ffi_name
+
+      new_file = file.gsub(/^( *)@@@(.*?)@@@/m) do
+        @constants = []
+        @structs = []
+
+        indent = $1
+        original_lines = $2.count "\n"
+
+        instance_eval $2, @ffi_name, $`.count("\n")
+
+        new_lines = []
+        @constants.each { |c| new_lines << c.to_ruby }
+        @structs.each { |s| new_lines << s.generate_layout }
+
+        new_lines = new_lines.join("\n").split "\n" # expand multiline blocks
+        new_lines = new_lines.map { |line| indent + line }
+
+        padding = original_lines - new_lines.length
+        new_lines += [nil] * padding if padding >= 0
+
+        new_lines.join "\n"
+      end
+
+      open @rb_name, 'w' do |f|
+        f.puts "# This file is generated by rake. Do not edit."
+        f.puts
+        f.puts new_file
+      end
+    end
+
+    def constants(options = {}, &block)
+      @constants << FFI::ConstGenerator.new(@name, @options.merge(options), &block)
+    end
+
+    def struct(options = {}, &block)
+      @structs << FFI::StructGenerator.new(@name, @options.merge(options), &block)
+    end
+
+    ##
+    # Utility converter for constants
+
+    def to_s
+      proc { |obj| obj.to_s.inspect }
+    end
+
+  end
+end
+
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/tools/generator_task.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/tools/generator_task.rb
new file mode 100755
index 0000000..9e39519
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/tools/generator_task.rb
@@ -0,0 +1,36 @@
+begin
+  require 'ffi/struct_generator'
+  require 'ffi/const_generator'
+  require 'ffi/generator'
+rescue LoadError
+  # from Rakefile
+  require 'lib/ffi/struct_generator'
+  require 'lib/ffi/const_generator'
+  require 'lib/ffi/generator'
+end
+
+require 'rake'
+require 'rake/tasklib'
+require 'tempfile'
+
+##
+# Rake task that calculates C structs for FFI::Struct.
+
+# @private
+class FFI::Generator::Task < Rake::TaskLib
+
+  def initialize(rb_names)
+    task :clean do rm_f rb_names end
+
+    rb_names.each do |rb_name|
+      ffi_name = "#{rb_name}.ffi"
+
+      file rb_name => ffi_name do |t|
+        puts "Generating #{rb_name}..." if Rake.application.options.trace
+
+        FFI::Generator.new ffi_name, rb_name
+      end
+    end
+  end
+
+end
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/tools/struct_generator.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/tools/struct_generator.rb
new file mode 100755
index 0000000..e892e65
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/tools/struct_generator.rb
@@ -0,0 +1,194 @@
+require 'tempfile'
+
+module FFI
+
+  ##
+  # Generates an FFI Struct layout.
+  #
+  # Given the @@@ portion in:
+  #
+  #   module Zlib::ZStream < FFI::Struct
+  #     @@@
+  #     name "struct z_stream_s"
+  #     include "zlib.h"
+  #   
+  #     field :next_in,   :pointer
+  #     field :avail_in,  :uint
+  #     field :total_in,  :ulong
+  #   
+  #     # ...
+  #     @@@
+  #   end
+  #
+  # StructGenerator will create the layout:
+  #
+  #   layout :next_in, :pointer, 0,
+  #          :avail_in, :uint, 4,
+  #          :total_in, :ulong, 8,
+  #          # ...
+  #
+  # StructGenerator does its best to pad the layout it produces to preserve
+  # line numbers.  Place the struct definition as close to the top of the file
+  # for best results.
+
+  class StructGenerator
+    @options = {}
+    attr_accessor :size
+    attr_reader   :fields
+
+    def initialize(name, options = {})
+      @name = name
+      @struct_name = nil
+      @includes = []
+      @fields = []
+      @found = false
+      @size = nil
+
+      if block_given? then
+        yield self
+        calculate self.class.options.merge(options)
+      end
+    end
+    def self.options=(options)
+      @options = options
+    end
+    def self.options
+      @options
+    end
+    def calculate(options = {})
+      binary = File.join Dir.tmpdir, "rb_struct_gen_bin_#{Process.pid}"
+
+      raise "struct name not set" if @struct_name.nil?
+
+      Tempfile.open("#{@name}.struct_generator") do |f|
+        f.puts "#include <stdio.h>"
+
+        @includes.each do |inc|
+          f.puts "#include <#{inc}>"
+        end
+
+        f.puts "#include <stddef.h>\n\n"
+        f.puts "int main(int argc, char **argv)\n{"
+        f.puts "  #{@struct_name} s;"
+        f.puts %[  printf("sizeof(#{@struct_name}) %u\\n", (unsigned int) sizeof(#{@struct_name}));]
+
+        @fields.each do |field|
+          f.puts <<-EOF
+    printf("#{field.name} %u %u\\n", (unsigned int) offsetof(#{@struct_name}, #{field.name}),
+           (unsigned int) sizeof(s.#{field.name}));
+  EOF
+        end
+
+        f.puts "\n  return 0;\n}"
+        f.flush
+
+        output = `gcc #{options[:cppflags]} #{options[:cflags]} -D_DARWIN_USE_64_BIT_INODE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -x c -Wall -Werror #{f.path} -o #{binary} 2>&1`
+
+        unless $?.success? then
+          @found = false
+          output = output.split("\n").map { |l| "\t#{l}" }.join "\n"
+          raise "Compilation error generating struct #{@name} (#{@struct_name}):\n#{output}"
+        end
+      end
+      
+      output = `#{binary}`.split "\n"
+      File.unlink(binary + (FFI::Platform.windows? ? ".exe" : ""))
+      sizeof = output.shift
+      unless @size
+        m = /\s*sizeof\([^)]+\) (\d+)/.match sizeof
+        @size = m[1]
+      end
+
+      line_no = 0
+      output.each do |line|
+        md = line.match(/.+ (\d+) (\d+)/)
+        @fields[line_no].offset = md[1].to_i
+        @fields[line_no].size   = md[2].to_i
+
+        line_no += 1
+      end
+
+      @found = true
+    end
+
+    def field(name, type=nil)
+      field = Field.new(name, type)
+      @fields << field
+      return field
+    end
+
+    def found?
+      @found
+    end
+
+    def dump_config(io)
+      io.puts "rbx.platform.#{@name}.sizeof = #{@size}"
+
+      @fields.each { |field| io.puts field.to_config(@name) }
+    end
+
+    def generate_layout
+      buf = ""
+
+      @fields.each_with_index do |field, i|
+        if buf.empty?
+          buf << "layout :#{field.name}, :#{field.type}, #{field.offset}"
+        else
+          buf << "       :#{field.name}, :#{field.type}, #{field.offset}"
+        end
+
+        if i < @fields.length - 1
+          buf << ",\n"
+        end
+      end
+
+      buf
+    end
+
+    def get_field(name)
+      @fields.find { |f| name == f.name }
+    end
+
+    def include(i)
+      @includes << i
+    end
+
+    def name(n)
+      @struct_name = n
+    end
+
+  end
+
+  ##
+  # A field in a Struct.
+
+  class StructGenerator::Field
+
+    attr_reader :name
+    attr_reader :type
+    attr_reader :offset
+    attr_accessor :size
+
+    def initialize(name, type)
+      @name = name
+      @type = type
+      @offset = nil
+      @size = nil
+    end
+
+    def offset=(o)
+      @offset = o
+    end
+
+    def to_config(name)
+      buf = []
+      buf << "rbx.platform.#{name}.#{@name}.offset = #{@offset}"
+      buf << "rbx.platform.#{name}.#{@name}.size = #{@size}"
+      buf << "rbx.platform.#{name}.#{@name}.type = #{@type}" if @type
+      buf
+    end
+
+  end
+
+end
+
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/tools/types_generator.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/tools/types_generator.rb
new file mode 100755
index 0000000..125a1a0
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/tools/types_generator.rb
@@ -0,0 +1,135 @@
+require 'tempfile'
+
+module FFI
+  
+  # @private
+  class TypesGenerator
+
+    ##
+    # Maps different C types to the C type representations we use
+
+    TYPE_MAP = {
+               "char" => :char,
+        "signed char" => :char,
+      "__signed char" => :char,
+      "unsigned char" => :uchar,
+
+               "short"     => :short,
+        "signed short"     => :short,
+        "signed short int" => :short,
+      "unsigned short"     => :ushort,
+      "unsigned short int" => :ushort,
+
+               "int" => :int,
+        "signed int" => :int,
+      "unsigned int" => :uint,
+
+               "long" => :long,
+               "long int" => :long,
+        "signed long" => :long,
+        "signed long int" => :long,
+      "unsigned long" => :ulong,
+      "unsigned long int" => :ulong,
+      "long unsigned int" => :ulong,
+
+               "long long"     => :long_long,
+               "long long int" => :long_long,
+        "signed long long"     => :long_long,
+        "signed long long int" => :long_long,
+      "unsigned long long"     => :ulong_long,
+      "unsigned long long int" => :ulong_long,
+
+      "char *" => :string,
+      "void *" => :pointer,
+    }
+
+    def self.generate(options = {})
+      typedefs = nil
+      Tempfile.open 'ffi_types_generator' do |io|
+        io.puts <<-C
+#include <sys/types.h>
+#if !(defined(WIN32))
+#include <sys/socket.h>
+#include <sys/resource.h>
+#endif
+        C
+
+        io.close
+        cc = ENV['CC'] || 'gcc'
+        cmd = "#{cc} -E -x c #{options[:cppflags]} -D_DARWIN_USE_64_BIT_INODE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -c"
+        if options[:input]
+          typedefs = File.read(options[:input])
+        elsif options[:remote]
+          typedefs = `ssh #{options[:remote]} #{cmd} - < #{io.path}`
+        else
+          typedefs = `#{cmd} #{io.path}`
+        end
+      end
+      
+      code = ""
+
+      typedefs.each_line do |type|
+        # We only care about single line typedef
+        next unless type =~ /typedef/
+        # Ignore unions or structs
+        next if type =~ /union|struct/
+        
+        # strip off the starting typedef and ending ;
+        type.gsub!(/^(.*typedef\s*)/, "")
+        type.gsub!(/\s*;\s*$/, "")
+    
+        parts = type.split(/\s+/)
+        def_type   = parts.join(" ")
+
+        # GCC does mapping with __attribute__ stuf, also see
+        # http://hal.cs.berkeley.edu/cil/cil016.html section 16.2.7.  Problem
+        # with this is that the __attribute__ stuff can either occur before or
+        # after the new type that is defined...
+        if type =~ /__attribute__/
+          if parts.last =~ /__QI__|__HI__|__SI__|__DI__|__word__/
+
+            # In this case, the new type is BEFORE __attribute__ we need to
+            # find the final_type as the type before the part that starts with
+            # __attribute__
+            final_type = ""
+            parts.each do |p|
+              break if p =~ /__attribute__/
+              final_type = p
+            end
+          else
+            final_type = parts.pop
+          end
+          
+          def_type = case type
+                     when /__QI__/   then "char"
+                     when /__HI__/   then "short"
+                     when /__SI__/   then "int"
+                     when /__DI__/   then "long long"
+                     when /__word__/ then "long"
+                     else                 "int"
+                     end
+
+          def_type = "unsigned #{def_type}" if type =~ /unsigned/
+        else
+          final_type = parts.pop
+          def_type   = parts.join(" ")
+        end
+        
+        if type = TYPE_MAP[def_type]
+          code << "rbx.platform.typedef.#{final_type} = #{type}\n"
+          TYPE_MAP[final_type] = TYPE_MAP[def_type]
+        else
+          # Fallback to an ordinary pointer if we don't know the type
+          if def_type =~ /\*/
+            code << "rbx.platform.typedef.#{final_type} = pointer\n"
+            TYPE_MAP[final_type] = :pointer
+          end
+        end
+      end
+
+      code
+    end
+
+  end
+end
+
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/types.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/types.rb
new file mode 100755
index 0000000..4e48a2c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/types.rb
@@ -0,0 +1,190 @@
+#
+# Copyright (C) 2008-2010 Wayne Meissner
+# Copyright (c) 2007, 2008 Evan Phoenix
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+#   may be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+# see {file:README}
+module FFI
+
+  # @param [Type, DataConverter, Symbol] old type definition used by {FFI.find_type}
+  # @param [Symbol] add new type definition's name to add
+  # @return [Type]
+  # Add a definition type to type definitions.
+  def self.typedef(old, add)
+    TypeDefs[add] = self.find_type(old)
+  end
+
+  # (see FFI.typedef)
+  def self.add_typedef(old, add)
+    typedef old, add
+  end
+
+
+  # @param [Type, DataConverter, Symbol] name
+  # @param [Hash] type_map if nil, {FFI::TypeDefs} is used
+  # @return [Type]
+  # Find a type in +type_map+ ({FFI::TypeDefs}, by default) from
+  # a type objet, a type name (symbol). If +name+ is a {DataConverter},
+  # a new {Type::Mapped} is created.
+  def self.find_type(name, type_map = nil)
+    if name.is_a?(Type)
+      name
+
+    elsif type_map && type_map.has_key?(name)
+      type_map[name]
+
+    elsif TypeDefs.has_key?(name)
+      TypeDefs[name]
+
+    elsif name.is_a?(DataConverter)
+      (type_map || TypeDefs)[name] = Type::Mapped.new(name)
+    
+    else
+      raise TypeError, "unable to resolve type '#{name}'"
+    end
+  end
+
+  # List of type definitions
+  TypeDefs.merge!({
+      # The C void type; only useful for function return types
+      :void => Type::VOID,
+
+      # C boolean type
+      :bool => Type::BOOL,
+
+      # C nul-terminated string
+      :string => Type::STRING,
+
+      # C signed char
+      :char => Type::CHAR,
+      # C unsigned char
+      :uchar => Type::UCHAR,
+
+      # C signed short
+      :short => Type::SHORT,
+      # C unsigned short
+      :ushort => Type::USHORT,
+
+      # C signed int
+      :int => Type::INT,
+      # C unsigned int
+      :uint => Type::UINT,
+
+      # C signed long
+      :long => Type::LONG,
+
+      # C unsigned long
+      :ulong => Type::ULONG,
+
+      # C signed long long integer
+      :long_long => Type::LONG_LONG,
+
+      # C unsigned long long integer
+      :ulong_long => Type::ULONG_LONG,
+
+      # C single precision float
+      :float => Type::FLOAT,
+
+      # C double precision float
+      :double => Type::DOUBLE,
+
+      # C long double
+      :long_double => Type::LONGDOUBLE,
+
+      # Native memory address
+      :pointer => Type::POINTER,
+
+      # 8 bit signed integer
+      :int8 => Type::INT8,
+      # 8 bit unsigned integer
+      :uint8 => Type::UINT8,
+
+      # 16 bit signed integer
+      :int16 => Type::INT16,
+      # 16 bit unsigned integer
+      :uint16 => Type::UINT16,
+
+      # 32 bit signed integer
+      :int32 => Type::INT32,
+      # 32 bit unsigned integer
+      :uint32 => Type::UINT32,
+
+      # 64 bit signed integer
+      :int64 => Type::INT64,
+      # 64 bit unsigned integer
+      :uint64 => Type::UINT64,
+
+      :buffer_in => Type::BUFFER_IN,
+      :buffer_out => Type::BUFFER_OUT,
+      :buffer_inout => Type::BUFFER_INOUT,
+
+      # Used in function prototypes to indicate the arguments are variadic
+      :varargs => Type::VARARGS,
+  })
+
+  
+  class StrPtrConverter
+    extend DataConverter
+    native_type Type::POINTER
+
+    # @param [Pointer] val
+    # @param ctx
+    # @return [Array(String, Pointer)]
+    # Returns a [ String, Pointer ] tuple so the C memory for the string can be freed
+    def self.from_native(val, ctx)
+      [ val.null? ? nil : val.get_string(0), val ]
+    end
+
+  end
+
+  typedef(StrPtrConverter, :strptr)
+
+  # @param type +type+ is an instance of class accepted by {FFI.find_type}
+  # @return [Numeric]
+  # Get +type+ size, in bytes.
+  def self.type_size(type)
+    find_type(type).size
+  end
+
+  # Load all the platform dependent types
+  begin
+    File.open(File.join(Platform::CONF_DIR, 'types.conf'), "r") do |f|
+      prefix = "rbx.platform.typedef."
+      f.each_line { |line|
+        if line.index(prefix) == 0
+          new_type, orig_type = line.chomp.slice(prefix.length..-1).split(/\s*=\s*/)
+          typedef(orig_type.to_sym, new_type.to_sym)
+        end
+      }
+    end
+    typedef :pointer, :caddr_t
+  rescue Errno::ENOENT
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/union.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/union.rb
new file mode 100755
index 0000000..38414ab
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/union.rb
@@ -0,0 +1,43 @@
+#
+# Copyright (C) 2009 Andrea Fazzi <andrea.fazzi at alcacoop.it>
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+#   may be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+require 'ffi/struct'
+
+module FFI
+
+  class Union < FFI::Struct
+    def self.builder
+      b = StructLayoutBuilder.new
+      b.union = true
+      b
+    end
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/variadic.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/variadic.rb
new file mode 100755
index 0000000..2414055
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/variadic.rb
@@ -0,0 +1,78 @@
+#
+# Copyright (C) 2008, 2009 Wayne Meissner
+# Copyright (C) 2009 Luc Heinrich
+#
+# This file is part of ruby-ffi.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# * Neither the name of the Ruby FFI project nor the names of its contributors
+#   may be used to endorse or promote products derived from this software
+#   without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+module FFI
+  class VariadicInvoker    
+    def init(arg_types, type_map)
+      @fixed = Array.new
+      @type_map = type_map
+      arg_types.each_with_index do |type, i|
+        @fixed << type unless type == Type::VARARGS
+      end
+    end
+
+
+    def call(*args, &block)
+      param_types = Array.new(@fixed)
+      param_values = Array.new
+      @fixed.each_with_index do |t, i|
+        param_values << args[i]
+      end
+      i = @fixed.length
+      while i < args.length
+        param_types << FFI.find_type(args[i], @type_map)
+        param_values << args[i + 1]
+        i += 2
+      end
+      invoke(param_types, param_values, &block)
+    end
+
+    #
+    # Attach the invoker to module +mod+ as +mname+
+    #
+    def attach(mod, mname)
+      invoker = self
+      params = "*args"
+      call = "call"
+      mod.module_eval <<-code
+      @@#{mname} = invoker
+      def self.#{mname}(#{params})
+        @@#{mname}.#{call}(#{params})
+      end
+      def #{mname}(#{params})
+        @@#{mname}.#{call}(#{params})
+      end
+      code
+      invoker
+    end
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/lib/ffi/version.rb b/app/server/vendor/ffi-1.9.10/lib/ffi/version.rb
new file mode 100755
index 0000000..3a66ef8
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/lib/ffi/version.rb
@@ -0,0 +1,4 @@
+module FFI
+  VERSION = '1.9.10'
+end
+
diff --git a/app/server/vendor/ffi-1.9.10/libtest/Benchmark.c b/app/server/vendor/ffi-1.9.10/libtest/Benchmark.c
new file mode 100755
index 0000000..55a7380
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/Benchmark.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+#include <sys/types.h>
+#include <stdint.h>
+
+void returnVoid() {
+    
+}
+
+void returnVoidI(int arg) {
+    
+}
+int returnInt() {
+    return 0;
+}
+
+int returnIntI(int arg) {
+    return arg;
+}
+
+typedef int8_t s8;
+typedef uint8_t u8;
+typedef int16_t s16;
+typedef uint16_t u16;
+typedef int32_t s32;
+typedef uint32_t u32;
+typedef int64_t s64;
+typedef uint64_t u64;
+typedef float f32;
+typedef double f64;
+typedef void v;
+typedef char* S;
+typedef void* P;
+
+#define B6(R, T1, T2, T3, T4, T5, T6) R bench_##T1##T2##T3##T4##T5##T6##_##R(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) {}
+#define B5(R, T1, T2, T3, T4, T5) R bench_##T1##T2##T3##T4##T5##_##R(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {}
+#define B4(R, T1, T2, T3, T4) R bench_##T1##T2##T3##T4##_##R(T1 a1, T2 a2, T3 a3, T4 a4) {}
+#define B3(R, T1, T2, T3) R bench_##T1##T2##T3##_##R(T1 a1, T2 a2, T3 a3) {}
+#define B2(R, T1, T2) R bench_##T1##T2##_##R(T1 a1, T2 a2) {}
+#define B1(R, T1) R bench_##T1##_##R(T1 a1) {}
+#define BrV(T) B1(v, T); B2(v, T, T); B3(v, T, T, T); B4(v, T, T, T, T); B5(v, T, T, T, T, T); B6(v, T, T, T, T, T, T);
+BrV(u32);
+BrV(s32);
+BrV(s64);
+BrV(u64);
+BrV(f32);
+BrV(f64);
+BrV(S);
+BrV(P);
diff --git a/app/server/vendor/ffi-1.9.10/libtest/BoolTest.c b/app/server/vendor/ffi-1.9.10/libtest/BoolTest.c
new file mode 100755
index 0000000..04cb6c6
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/BoolTest.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner.
+ * Copyright (c) 2009 Aman Gupta.
+ *
+ * All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <stdbool.h>
+
+bool
+bool_return_true()
+{
+    return true;
+}
+
+bool
+bool_return_false()
+{
+    return false;
+}
+
+bool
+bool_return_val(bool value)
+{
+    return value;
+}
+
+bool
+bool_reverse_val(bool value)
+{
+    return value ? false : true;
+}
diff --git a/app/server/vendor/ffi-1.9.10/libtest/BufferTest.c b/app/server/vendor/ffi-1.9.10/libtest/BufferTest.c
new file mode 100755
index 0000000..3e95ebc
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/BufferTest.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+
+#define MEMSET(buf, value, size) do { \
+    int i; for (i = 0; i < size; ++i) buf[i] = value; \
+} while(0)
+#define MEMCPY(dst, src, size) do { \
+    int i; for (i = 0; i < size; ++i) dst[i] = src[i]; \
+} while(0)
+
+#define FILL(JTYPE, CTYPE) \
+void fill##JTYPE##Buffer(CTYPE* buf, CTYPE value, int size) { MEMSET(buf, value, size); }
+
+#define COPY(JTYPE, CTYPE) \
+void copy##JTYPE##Buffer(CTYPE* dst, CTYPE* src, int size) { MEMCPY(dst, src, size); }
+
+#define FUNC(JTYPE, CTYPE) \
+    FILL(JTYPE, CTYPE); \
+    COPY(JTYPE, CTYPE)
+            
+FUNC(Byte, char);
+FUNC(Short, short);
+FUNC(Int, int);
+FUNC(Long, long long);
+FUNC(Float, float);
+FUNC(Double, double);
+
diff --git a/app/server/vendor/ffi-1.9.10/libtest/ClosureTest.c b/app/server/vendor/ffi-1.9.10/libtest/ClosureTest.c
new file mode 100755
index 0000000..dfeabde
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/ClosureTest.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#ifndef _WIN32
+# include <pthread.h>
+#else
+# include <windows.h>
+# include <process.h>
+#endif
+
+#define R(T, rtype) rtype testClosureVr##T(rtype (*closure)(void)) { \
+    return closure != NULL ? (*closure)() : (rtype) 0; \
+}
+
+#define P(T, ptype) void testClosure##T##rV(void (*closure)(ptype), ptype a1) { \
+    if (closure != NULL) (*closure)(a1); \
+}
+
+void testClosureVrV(void (*closure)(void))
+{
+    (*closure)();
+}
+
+R(Z, bool);
+R(B, char);
+R(S, short);
+R(I, int);
+R(L, long);
+R(J, long long);
+R(LL, long long);
+R(F, float);
+R(D, double);
+R(P, const void*);
+
+
+P(Z, bool);
+P(B, char);
+P(S, short);
+P(I, int);
+P(L, long);
+P(J, long long);
+P(LL, long long);
+P(F, float);
+P(D, double);
+P(P, const void*);
+P(UL, unsigned long);
+
+#if defined(_WIN32) && !defined(_WIN64)
+bool __stdcall testClosureStdcall(long *a1, void __stdcall(*closure)(void *, long), long a2) { \
+    void* sp_pre;
+    void* sp_post;
+
+    asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
+    (*closure)(a1, a2);
+    asm volatile (" movl %%esp,%0" : "=g" (sp_post));
+
+    /* %esp before pushing parameters on the stack and after the call returns
+     * should be equal, if both sides respects the stdcall convention */
+    return sp_pre == sp_post;
+}
+#endif
+
+void testOptionalClosureBrV(void (*closure)(char), char a1)
+{
+    if (closure) {
+        (*closure)(a1);
+    }
+}
+
+
+struct ThreadVrV {
+    void (*closure)(void);
+    int count;
+};
+
+static void *
+threadVrV(void *arg)
+{
+    struct ThreadVrV* t = (struct ThreadVrV *) arg;
+    
+    int i;
+    for (i = 0; i < t->count; i++) {
+        (*t->closure)();
+    }
+    
+    return NULL;
+}
+
+void testThreadedClosureVrV(void (*closure)(void), int n)
+{
+	struct ThreadVrV arg = {closure, n};
+#ifndef _WIN32
+    pthread_t t;
+    pthread_create(&t, NULL, threadVrV, &arg);
+    pthread_join(t, NULL);
+#else
+    HANDLE hThread = (HANDLE) _beginthread((void (*)(void *))threadVrV, 0, &arg);
+    WaitForSingleObject(hThread, INFINITE);	
+#endif
+}
+
+struct s8f32s32 {
+    char s8;
+    float f32;
+    int s32;
+};
+
+// Takes a struct argument
+void testClosureTrV(void (*closure)(struct s8f32s32 s), struct s8f32s32* s)
+{
+    (*closure)(*s);
+}
+
+// Returns a struct value
+struct s8f32s32 testClosureVrT(struct s8f32s32 (*closure)())
+{
+    return (*closure)();
+}
+
+typedef int (*returnTypeClosure_t)(int) ;
+typedef returnTypeClosure_t (*lookupClosure_t)();
+
+int testReturnsClosure(lookupClosure_t lookup, int val)
+{
+    returnTypeClosure_t func = lookup ? (*lookup)() : NULL;
+    return func ? (*func)(val) : 0;
+}
+
+static int multiplyByTwo(int value)
+{
+    return value * 2;
+}
+
+returnTypeClosure_t testReturnsFunctionPointer()
+{
+    return multiplyByTwo;
+}
+
+typedef int (*argumentClosure_t)(int);
+typedef int (*withArgumentClosure_t)(argumentClosure_t, int);
+
+int testArgumentClosure(withArgumentClosure_t closure_with, argumentClosure_t closure_arg, int val)
+{
+    return (*closure_with)(closure_arg, val);
+}
+
+
+//
+// These macros produce functions of the form:
+// testClosureBIrV(void (*closure)(char, int), char a1, int a2) {}
+//
+#define C2_(J1, J2, N1, N2) \
+void testClosure##J1##J2##rV(void (*closure)(N1, N2), N1 a1, N2 a2) \
+{ \
+    if (closure != NULL) (*closure)(a1, a2); \
+}
+
+#define C2(J, N) \
+    C2_(B, J, char, N) \
+    C2_(S, J, short, N) \
+    C2_(I, J, int, N) \
+    C2_(LL, J, long long, N) \
+    C2_(F, J, float, N) \
+    C2_(D, J, double, N) \
+
+
+C2(B, char);
+C2(S, short);
+C2(I, int);
+C2(LL, long long);
+C2(F, float);
+C2(D, double);
+
+#define C3_(J1, J2, J3, N1, N2, N3) \
+void testClosure##J1##J2##J3##rV(void (*closure)(N1, N2, N3), N1 a1, N2 a2, N3 a3) \
+{ \
+    (*closure)(a1, a2, a3); \
+}
+
+
+#define C3(J, N) \
+    C3_(B, J, B, char, N, char) \
+    C3_(S, J, S, short, N, short) \
+    C3_(I, J, I, int, N, int) \
+    C3_(LL, J, LL, long long, N, long long) \
+    C3_(F, J, F, float, N, float) \
+    C3_(D, J, D, double, N, double) \
+
+C3(B, char);
+C3(S, short);
+C3(I, int);
+C3(LL, long long);
+C3(F, float);
+C3(D, double);
+C3_(B, S, I, char, short, int);
+C3_(B, S, LL, char, short, long long);
+C3_(LL, S, B, long long, short, char);
+C3_(LL, B, S, long long, char, short);
+
+
diff --git a/app/server/vendor/ffi-1.9.10/libtest/EnumTest.c b/app/server/vendor/ffi-1.9.10/libtest/EnumTest.c
new file mode 100755
index 0000000..4bf8d23
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/EnumTest.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+#include <stdint.h>
+
+int test_untagged_enum(int val) {
+    return val;
+}
+
+int test_untagged_typedef_enum(int val) {
+    return val;
+}
+
+uint8_t test_untagged_nonint_enum(uint8_t val) {
+    return val;
+}
+
+uint16_t test_tagged_nonint_enum1(uint16_t val) {
+    return val;
+}
+
+uint32_t test_tagged_nonint_enum2(uint32_t val) {
+    return val;
+}
+
+uint64_t test_tagged_nonint_enum3(uint64_t val) {
+    return val;
+}
+
+typedef enum {c1, c2, c3, c4} enum_type1;
+enum_type1 test_tagged_typedef_enum1(enum_type1 val) {
+    return val;
+}
+
+typedef enum {c5 = 42, c6, c7, c8} enum_type2;
+enum_type2 test_tagged_typedef_enum2(enum_type2 val) {
+    return val;
+}
+
+typedef enum {c9 = 42, c10, c11 = 4242, c12} enum_type3;
+enum_type3 test_tagged_typedef_enum3(enum_type3 val) {
+    return val;
+}
+
+typedef enum {c13 = 42, c14 = 4242, c15 = 424242, c16 = 42424242} enum_type4;
+enum_type4 test_tagged_typedef_enum4(enum_type4 val) {
+    return val;
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/libtest/FunctionTest.c b/app/server/vendor/ffi-1.9.10/libtest/FunctionTest.c
new file mode 100755
index 0000000..eafad89
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/FunctionTest.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#ifdef _WIN32
+#include <windows.h>
+#define sleep(x) Sleep(x)
+#endif
+
+#ifndef _WIN32
+#include <unistd.h>
+#include <pthread.h>
+#endif
+
+int testAdd(int a, int b)
+{
+    return a + b;
+};
+
+int testFunctionAdd(int a, int b, int (*f)(int, int))
+{
+    return f(a, b);
+};
+
+void testBlocking(int seconds) {
+    sleep(seconds);
+};
+
+struct async_data {
+    void (*fn)(int);
+    int value;
+};
+
+static void* asyncThreadCall(void *data)
+{
+    struct async_data* d = (struct async_data *) data;
+    if (d != NULL && d->fn != NULL) {
+        (*d->fn)(d->value);
+    }
+
+    return NULL;
+}
+
+void testAsyncCallback(void (*fn)(int), int value)
+{
+#ifndef _WIN32
+    pthread_t t;
+    struct async_data d;
+    d.fn = fn;
+    d.value = value;
+    pthread_create(&t, NULL, asyncThreadCall, &d);
+    pthread_join(t, NULL);
+#else
+    (*fn)(value);
+#endif
+} 
+
+#if defined(_WIN32) && !defined(_WIN64)
+struct StructUCDP {
+  unsigned char a1;
+  double a2;
+  void *a3;
+};
+
+void __stdcall testStdcallManyParams(long *a1, char a2, short int a3, int a4, __int64 a5,
+            struct StructUCDP a6, struct StructUCDP *a7, float a8, double a9) {
+}
+#endif
diff --git a/app/server/vendor/ffi-1.9.10/libtest/GNUmakefile b/app/server/vendor/ffi-1.9.10/libtest/GNUmakefile
new file mode 100755
index 0000000..a7ba9e6
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/GNUmakefile
@@ -0,0 +1,149 @@
+# -*- makefile -*-
+
+ifeq ($(OS),)
+  BUILD_OS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
+  OS := $(BUILD_OS)
+endif
+
+ifeq ($(CPU),)
+  CPU := $(shell uname -m | sed -e 's/i[345678]86/i386/')
+endif
+
+PLATFORM = $(CPU)-$(OS)
+
+ifeq ($(OS), sunos)
+  OS = solaris
+endif
+
+SRC_DIR = libtest
+BUILD_DIR ?= build
+TEST_BUILD_DIR = $(BUILD_DIR)/libtest
+# Set defaults to unix (linux/solaris/bsd)
+PREFIX = lib
+LIBEXT ?= so
+LIBNAME = $(PREFIX)test.$(LIBEXT)
+
+export MACOSX_DEPLOYMENT_TARGET=10.4
+
+CCACHE := $(strip $(realpath $(shell which ccache 2> /dev/null)))
+
+TEST_SRCS = $(wildcard $(SRC_DIR)/*.c)
+TEST_OBJS := $(patsubst $(SRC_DIR)/%.c, $(TEST_BUILD_DIR)/%.o, $(TEST_SRCS))
+
+#
+# Compiler/linker flags from:
+#   http://weblogs.java.net/blog/kellyohair/archive/2006/01/compilation_of_1.html
+JFLAGS = -fno-omit-frame-pointer -fno-strict-aliasing
+OFLAGS = -O2 $(JFLAGS)
+WFLAGS = -W -Wall -Wno-unused -Wno-parentheses
+PICFLAGS = -fPIC
+SOFLAGS = -shared
+LDFLAGS += $(SOFLAGS)
+
+IFLAGS = -I"$(BUILD_DIR)"
+CFLAGS = $(OFLAGS) $(WFLAGS) $(IFLAGS) $(PICFLAGS) -D_REENTRANT
+
+ifneq ($(strip $(findstring $(OS), win32, mingw, cygwin)),)
+  # For cygwin => win32-native builds, strip out cygwin deps
+  ifneq ($(findstring cygwin, $(BUILD_OS)),)
+    CC += -mno-cygwin -mwin32
+    LDFLAGS += -mno-cygwin -Wl,--add-stdcall-alias
+  endif
+  PICFLAGS=
+  LIBEXT=dll
+  CC = gcc
+endif
+
+ifeq ($(OS), darwin)
+  ifneq ($(findstring $(CPU),ppc),)
+    ARCHFLAGS += -arch ppc
+  endif
+  ifneq ($(findstring $(CPU),i386 x86_64),)
+    ARCHFLAGS += -arch i386 -arch x86_64
+  endif
+  CFLAGS += $(ARCHFLAGS) -DTARGET_RT_MAC_CFM=0
+  CFLAGS += -fno-common
+  LDFLAGS = $(ARCHFLAGS) -dynamiclib
+  # link against the universal libraries on ppc machines
+  LDFLAGS += -L$(MACSDK)/usr/lib
+  LIBEXT = dylib
+  FFI_CFLAGS += -isysroot $(MACSDK)
+  PICFLAGS =
+  SOFLAGS =
+endif
+
+ifeq ($(OS), linux)
+  SOFLAGS += -Wl,-soname,$(LIBNAME)
+endif
+
+ifeq ($(OS), solaris)
+  CC = /usr/sfw/bin/gcc -std=c99
+  LD = /usr/ccs/bin/ld
+  SOFLAGS = -shared -static-libgcc 
+endif
+
+ifeq ($(OS), aix)
+  LIBEXT = a
+  SOFLAGS = -shared -static-libgcc
+  PICFLAGS += -pthread
+endif
+
+ifneq ($(findstring bsd, $(OS)),)
+  SOFLAGS = -shared -static-libgcc
+  CFLAGS += -pthread
+  LDFLAGS += -pthread
+endif
+
+ifeq ($(CPU), i386)
+  MODEL = 32
+endif
+
+ifeq ($(CPU), sparcv9)
+  MODEL = 64
+endif
+
+ifeq ($(CPU), amd64)
+  MODEL = 64
+endif
+
+ifeq ($(CPU), x86_64)
+  MODEL = 64
+endif
+
+ifeq ($(CPU), ppc64)
+  MODEL = 64
+endif
+
+ifeq ($(CPU), powerpc64)
+  MODEL = 64
+endif
+
+MODELFLAG =
+ifneq ($(MODEL),)
+  MODELFLAG = -m$(MODEL)
+endif
+
+# On platforms (linux, solaris) that support both 32bit and 64bit, force building for one or the other
+ifneq ($(or $(findstring linux, $(OS)), $(findstring solaris, $(OS))),)
+  # Change the CC/LD instead of CFLAGS/LDFLAGS, incase other things in the flags
+  # makes the libffi build choke
+  CC += $(MODELFLAG)
+  LD += $(MODELFLAG)
+endif
+
+LIBTEST = $(BUILD_DIR)/$(LIBNAME)
+
+all:	$(LIBTEST)
+
+$(TEST_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
+	@mkdir -p $(@D)
+	$(CCACHE) $(CC) $(CFLAGS) -c $< -o $@
+
+$(LIBTEST):  $(TEST_OBJS)
+	$(CC) -o $@ $(LDFLAGS) $(TEST_OBJS) -lm
+
+clean::
+	# nothing to do - ant will delete the build dir
+
+debug::
+	@echo "SRCS=$(TEST_SRCS)"
diff --git a/app/server/vendor/ffi-1.9.10/libtest/GlobalVariable.c b/app/server/vendor/ffi-1.9.10/libtest/GlobalVariable.c
new file mode 100755
index 0000000..39c12a2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/GlobalVariable.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <sys/types.h>
+#include <stdint.h>
+
+typedef int8_t s8;
+typedef uint8_t u8;
+typedef int16_t s16;
+typedef uint16_t u16;
+typedef int32_t s32;
+typedef uint32_t u32;
+typedef int64_t s64;
+typedef uint64_t u64;
+typedef signed long sL;
+typedef unsigned long uL;
+typedef float f32;
+typedef double f64;
+#if !defined(__OpenBSD__)
+typedef unsigned long ulong;
+#endif
+typedef void* pointer;
+typedef void* P;
+
+#define GVAR(T) \
+    extern T gvar_##T; \
+    T gvar_##T = (T) -1; \
+    T gvar_##T##_get() { return gvar_##T; }; \
+    void gvar_##T##_set(T v) { gvar_##T = v; }
+
+GVAR(s8);
+GVAR(u8);
+GVAR(s16);
+GVAR(u16);
+GVAR(s32);
+GVAR(u32);
+GVAR(s64);
+GVAR(u64);
+GVAR(long);
+GVAR(ulong);
+GVAR(pointer);
+
+struct gstruct {
+    long data;
+};
+
+struct gstruct gvar_gstruct = { -1 };
+
+struct gstruct*
+gvar_gstruct_get(void)
+{
+    return &gvar_gstruct;
+}
+
+void
+gvar_gstruct_set(const struct gstruct* val)
+{ 
+    gvar_gstruct = *val;
+}
diff --git a/app/server/vendor/ffi-1.9.10/libtest/LastErrorTest.c b/app/server/vendor/ffi-1.9.10/libtest/LastErrorTest.c
new file mode 100755
index 0000000..02ce4a8
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/LastErrorTest.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#if defined(_WIN32) || defined(__WIN32__)
+# include <windows.h>
+#else
+# include <errno.h>
+#endif
+
+int setLastError(int error) {
+#if defined(_WIN32) || defined(__WIN32__)
+    SetLastError(error);
+#else
+    errno = error;
+#endif
+    return -1;
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/libtest/NumberTest.c b/app/server/vendor/ffi-1.9.10/libtest/NumberTest.c
new file mode 100755
index 0000000..3fa25a8
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/NumberTest.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#if defined(__sparc) && defined(__sun__)
+    #define fix_mem_access __asm("ta 6")
+#else
+    #define fix_mem_access
+#endif
+
+typedef int8_t s8;
+typedef uint8_t u8;
+typedef int16_t s16;
+typedef uint16_t u16;
+typedef int32_t s32;
+typedef uint32_t u32;
+typedef int64_t s64;
+typedef uint64_t u64;
+typedef signed long sL;
+typedef unsigned long uL;
+typedef float f32;
+typedef double f64;
+typedef long double f128;
+#if !defined(__OpenBSD__)
+typedef unsigned long ulong;
+#endif
+
+#define ADD(T) T add_##T(T arg1, T arg2) { return arg1 + arg2; }
+#define SUB(T) T sub_##T(T arg1, T arg2) { return arg1 - arg2; }
+#define MUL(T) T mul_##T(T arg1, T arg2) { return arg1 * arg2; }
+#define DIV(T) T div_##T(T arg1, T arg2) { return arg1 / arg2; }
+#define RET(T) T ret_##T(T arg1) { return arg1; }
+#define SET(T) static T T##_;void set_##T(T arg1) { T##_ = arg1; }
+#define GET(T) T get_##T() { return T##_; }
+typedef char* ptr;
+#define TEST(T) ADD(T) SUB(T) MUL(T) DIV(T) RET(T) SET(T) GET(T)
+TEST(s8);
+TEST(u8);
+TEST(s16);
+TEST(u16);
+TEST(s32);
+TEST(u32);
+TEST(s64);
+TEST(u64);
+TEST(float);
+TEST(double);
+TEST(long);
+TEST(ulong);
+TEST(f128);
+
+#define ADD2(R, T1, T2) R add_##T1##T2##_##R(T1 arg1, T2 arg2) { return arg1 + arg2; }
+#define SUB2(R, T1, T2) R sub_##T1##T2##_##R(T1 arg1, T2 arg2) { return arg1 - arg2; }
+#define MUL2(R, T1, T2) R mul_##T1##T2##_##R(T1 arg1, T2 arg2) { return arg1 * arg2; }
+#define DIV2(R, T1, T2) R div_##T1##T2##_##R(T1 arg1, T2 arg2) { return arg1 / arg2; }
+
+#define T2__(R, T1, T2) ADD2(R, T1, T2) SUB2(R, T1, T2) MUL2(R, T1, T2) DIV2(R, T1, T2)
+#define T2_(R, T1) \
+    T2__(R, T1, s8) T2__(R, T1, u8) \
+    T2__(R, T1, s16) T2__(R, T1, u16) \
+    T2__(R, T1, s32) T2__(R, T1, u32) \
+    T2__(R, T1, sL) T2__(R, T1, uL) \
+    T2__(R, T1, s64) T2__(R, T1, u64) \
+
+#define TEST2(R) \
+    T2_(R, s8) T2_(R, u8) T2_(R, s16) T2_(R, u16) T2_(R, s32) T2_(R, u32) \
+    T2_(R, sL) T2_(R, uL) T2_(R, s64) T2_(R, u64)
+
+#ifdef notyet
+TEST2(s32)
+TEST2(u32)
+TEST2(s64)
+TEST2(u64)
+#endif
+
+#define ADD3(R, T1, T2, T3) R add_##T1##T2##T3##_##R(T1 arg1, T2 arg2, T3 arg3) { return arg1 + arg2 + arg3; }
+#define pack_f32(buf, v) do { float f = v; memcpy((buf), &f, sizeof(f)); } while(0)
+#define pack_f64(buf, v) do { double f = v; memcpy((buf), &f, sizeof(f)); } while(0)
+#define pack_int(buf, v) do { *(buf) = v; } while(0)
+#define pack_s8 pack_int
+#define pack_u8 pack_int
+#define pack_s16 pack_int
+#define pack_u16 pack_int
+#define pack_s32 pack_int
+#define pack_u32 pack_int
+#define pack_s64 pack_int
+#define pack_u64 pack_int
+#define pack_sL pack_int
+#define pack_uL pack_int
+
+#define PACK3(R, T1, T2, T3) void pack_##T1##T2##T3##_##R(T1 arg1, T2 arg2, T3 arg3, R* r) { \
+    fix_mem_access; \
+    pack_##T1(&r[0], arg1); \
+    pack_##T2(&r[1], arg2); \
+    pack_##T3(&r[2], arg3); \
+}
+
+#define T3___(R, T1, T2, T3) PACK3(R, T1, T2, T3) /* SUB2(R, T1, T2) MUL2(R, T1, T2) DIV2(R, T1, T2) */
+#define T3__(R, T1, T2) \
+    T3___(R, T1, T2, s8) T3___(R, T1, T2, u8) \
+    T3___(R, T1, T2, s16) T3___(R, T1, T2, u16) \
+    T3___(R, T1, T2, s32) T3___(R, T1, T2, u32) \
+    T3___(R, T1, T2, sL) T3___(R, T1, T2, uL) \
+    T3___(R, T1, T2, s64) T3___(R, T1, T2, u64) \
+    T3___(R, T1, T2, f32) T3___(R, T1, T2, f64) \
+
+#define T3_(R, T1) \
+    T3__(R, T1, s8) T3__(R, T1, u8) \
+    T3__(R, T1, s16) T3__(R, T1, u16) \
+    T3__(R, T1, s32) T3__(R, T1, u32) \
+    T3__(R, T1, sL) T3__(R, T1, uL) \
+    T3__(R, T1, s64) T3__(R, T1, u64) \
+    T3__(R, T1, f32) T3__(R, T1, f64) \
+
+#define TEST3(R) \
+    T3_(R, s8) T3_(R, u8) T3_(R, s16) T3_(R, u16) T3_(R, s32) T3_(R, u32) \
+    T3_(R, sL) T3_(R, uL) T3_(R, s64) T3_(R, u64) T3_(R, f32) T3_(R, f64)
+
+TEST3(s64)
+
+void 
+foo6(intptr_t i1, intptr_t i2, intptr_t i3, intptr_t i4, intptr_t i5, intptr_t i6) { }
+
+void 
+foo5(intptr_t i1, intptr_t i2, intptr_t i3, intptr_t i4, intptr_t i5) { }
+
diff --git a/app/server/vendor/ffi-1.9.10/libtest/PointerTest.c b/app/server/vendor/ffi-1.9.10/libtest/PointerTest.c
new file mode 100755
index 0000000..7237ab2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/PointerTest.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+typedef void* ptr;
+typedef void* pointer;
+#ifdef _WIN32
+typedef char* caddr_t;
+#endif
+
+#define RET(T) T ptr_ret_##T(void* arg1, int offset) { \
+    T tmp; memcpy(&tmp, (caddr_t) arg1 + offset, sizeof(tmp)); return tmp; \
+}
+#define SET(T) void ptr_set_##T(void* arg1, int offset, T value) { \
+    memcpy((caddr_t) arg1 + offset, &value, sizeof(value)); \
+}
+#define TEST(T) SET(T) RET(T)
+
+TEST(int8_t);
+TEST(int16_t);
+TEST(int32_t);
+TEST(int64_t);
+TEST(float);
+TEST(double);
+TEST(pointer);
+
+void*
+ptr_return_array_element(void **ptrArray, int arrayIndex) 
+{
+    return ptrArray[arrayIndex];
+}
+
+void
+ptr_set_array_element(void **ptrArray, int arrayIndex, void *value)
+{    
+    ptrArray[arrayIndex] = value;
+}
+
+void*
+ptr_malloc(int size) 
+{
+    return calloc(1, size);
+}
+void
+ptr_free(void* ptr)
+{
+    free(ptr);
+}
+
+void*
+ptr_from_address(uintptr_t addr)
+{
+    return (void *) addr;
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/libtest/ReferenceTest.c b/app/server/vendor/ffi-1.9.10/libtest/ReferenceTest.c
new file mode 100755
index 0000000..d1dd88b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/ReferenceTest.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <stdint.h>
+
+#define REF(T) void ref_##T(T arg, T* result) { *result = arg; }
+#define ADD(T) void ref_add_##T(T arg1, T arg2, T* result) { *result = arg1 + arg2; }
+#define SUB(T) void ref_sub_##T(T arg1, T arg2, T* result) { *result = arg1 - arg2; }
+#define MUL(T) void ref_mul_##T(T arg1, T arg2, T* result) { *result = arg1 * arg2; }
+#define DIV(T) void ref_div_##T(T arg1, T arg2, T* result) { *result = arg1 / arg2; }
+#define TEST(T) ADD(T) SUB(T) MUL(T) DIV(T) REF(T)
+
+TEST(int8_t);
+TEST(int16_t);
+TEST(int32_t);
+TEST(int64_t);
+TEST(float);
+TEST(double);
+
+
diff --git a/app/server/vendor/ffi-1.9.10/libtest/StringTest.c b/app/server/vendor/ffi-1.9.10/libtest/StringTest.c
new file mode 100755
index 0000000..292242b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/StringTest.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <string.h>
+
+int 
+string_equals(const char* s1, const char* s2)
+{
+    return strcmp(s1, s2) == 0;
+}
+
+void 
+string_set(char* s1, const char* s2)
+{
+    strcpy(s1, s2);
+}
+void
+string_concat(char* dst, const char* src)
+{
+    strcat(dst, src);
+}
+void
+string_dummy(char* dummy)
+{
+}
+const char*
+string_null(void)
+{
+    return NULL;
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/libtest/StructTest.c b/app/server/vendor/ffi-1.9.10/libtest/StructTest.c
new file mode 100755
index 0000000..25683d3
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/StructTest.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner.
+ * Copyright (c) 2009 Andrea Fazzi <andrea.fazzi at alcacoop.it>.
+ *
+ * All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdarg.h>
+
+typedef char s8;
+typedef short s16;
+typedef int s32;
+typedef long long s64;
+typedef float f32;
+typedef double f64;
+
+typedef struct bugged_struct {
+  unsigned char visible;
+  unsigned int x;
+  unsigned int y;
+  short rx;
+  short ry;
+  unsigned char order;
+  unsigned char size;
+} bugged_struct_t;
+
+unsigned int
+bugged_struct_size() {
+    return sizeof(bugged_struct_t);
+}
+
+struct test1 {
+    char b;
+    short s;
+    int i;
+    long long j;
+    long l;
+    float f;
+    double d;
+    char string[32];
+};
+
+struct struct_with_array {
+    char c;
+    int a[5];
+};
+
+struct nested {
+    int i;
+};
+
+struct container {
+    char first;
+    struct nested s;
+};
+
+int
+struct_align_nested_struct(struct container* a) { return a->s.i; }
+
+void*
+struct_field_array(struct struct_with_array* s) { return &s->a; }
+
+struct container*
+struct_make_container_struct(int i)
+{
+    static struct container cs;
+    memset(&cs, 0, sizeof(cs));
+    cs.first = 1;
+    cs.s.i = i;
+    return &cs;
+}
+
+#define T(x, type) \
+    type struct_field_##type(struct test1* t) { return t->x; } \
+    struct type##_align { char first; type value; }; \
+    type struct_align_##type(struct type##_align* a) { return a->value; }
+
+T(b, s8);
+T(s, s16);
+T(i, s32);
+T(j, s64);
+T(f, f32);
+T(d, f64);
+T(l, long);
+
+void
+struct_set_string(struct test1* t, char* s)
+{
+    strcpy(t->string, s);
+}
+
+struct test1*
+struct_make_struct(char b, short s, int i, long long ll, float f, double d)
+{
+    static struct test1 t;
+    memset(&t, 0, sizeof(t));
+    t.b = b;
+    t.s = s;
+    t.i = i;
+    t.j = ll;
+    t.f = f;
+    t.d = d;
+    return &t;
+}
+
+typedef int (*add_cb)(int a1, int a2);
+typedef int (*sub_cb)(int a1, int a2);
+struct test2 {
+    add_cb  add_callback;
+    sub_cb  sub_callback;
+};
+
+int
+struct_call_add_cb(struct test2* t, int a1, int a2)
+{
+    return t->add_callback(a1, a2);
+}
+
+int
+struct_call_sub_cb(struct test2* t, int a1, int a2)
+{
+    return t->sub_callback(a1, a2);
+}
+
+
+struct struct_with_array*
+struct_make_struct_with_array(int a_0, int a_1, int a_2, int a_3, int a_4)
+{
+    static struct struct_with_array s;
+
+    memset(&s, 0, sizeof(s));
+
+    s.a[0] = a_0;
+    s.a[1] = a_1;
+    s.a[2] = a_2;
+    s.a[3] = a_3;
+    s.a[4] = a_4;
+
+    return &s;
+
+}
+
+struct s8s32 {
+    char s8;
+    int s32;
+};
+
+struct s8s32
+struct_return_s8s32()
+{
+    struct s8s32 s;
+    s.s8 = 0x7f;
+    s.s32 = 0x12345678;
+
+    return s;
+}
+
+struct s8s32
+struct_s8s32_set(char s8, int s32)
+{
+    struct s8s32 s;
+
+    s.s8 = s8;
+    s.s32 = s32;
+
+    return s;
+}
+
+int
+struct_s8s32_get_s8(struct s8s32 s)
+{
+    return s.s8;
+}
+
+int
+struct_s8s32_get_s32(struct s8s32 s)
+{
+    return s.s32;
+}
+
+struct s8s32
+struct_s8s32_ret_s8s32(struct s8s32 s)
+{
+    return s;
+}
+
+// Pass a struct and an int arg, ensure the int arg is passed correctly
+int
+struct_s8s32_s32_ret_s32(struct s8s32 s, int s32)
+{
+    return s32;
+}
+
+// Pass a struct and a long long arg, ensure the long long arg is passed correctly
+long long
+struct_s8s32_s64_ret_s64(struct s8s32 s, long long s64)
+{
+    return s64;
+}
+
+// Pass a struct and a long long arg, ensure the long long arg is passed correctly
+int
+struct_s32_ptr_s32_s8s32_ret_s32(int s32a, void *ptr, int s32b, struct s8s32 s)
+{
+    if (ptr != NULL) *(struct s8s32 *) ptr = s;
+    return s.s32;
+}
+
+// Pass a char *, copy into buffer length struct
+struct struct_string {
+    char *bytes;
+    int len;
+};
+
+struct struct_string
+struct_varargs_ret_struct_string(int len, ...)
+{
+    struct struct_string ss;
+    va_list vl;
+    char* cp = NULL;
+
+    va_start(vl, len);
+
+    ss.len = len;
+    ss.bytes = va_arg(vl, char *);
+    if (ss.bytes != NULL) {
+        cp = malloc(strlen(ss.bytes) + 1);
+        strcpy(cp, ss.bytes);
+        ss.bytes = cp;
+    }
+
+    va_end(vl);
+
+    return ss;
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/libtest/UnionTest.c b/app/server/vendor/ffi-1.9.10/libtest/UnionTest.c
new file mode 100755
index 0000000..0929a31
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/UnionTest.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+typedef char s8;
+typedef short s16;
+typedef int s32;
+typedef long long s64;
+typedef float f32;
+typedef double f64;
+
+typedef union union_test {
+    char b;
+    short s;
+    int i;
+    long long j;
+    long l;
+    float f;
+    double d;
+    s8 a[10];
+} union_test_t;
+
+#define T(x, type) \
+  type union_align_##type(union_test_t* u) { return u->x; } \
+  union_test_t* union_make_union_with_##type(type value) { static union_test_t u; u.x = value; return &u; }
+
+T(b, s8);
+T(s, s16);
+T(i, s32);
+T(j, s64);
+T(f, f32);
+T(d, f64);
+T(l, long);
+
+unsigned int union_size() { return sizeof(union_test_t); }
diff --git a/app/server/vendor/ffi-1.9.10/libtest/VariadicTest.c b/app/server/vendor/ffi-1.9.10/libtest/VariadicTest.c
new file mode 100755
index 0000000..fea6c3b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/libtest/VariadicTest.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdarg.h>
+
+typedef int8_t s8;
+typedef uint8_t u8;
+typedef int16_t s16;
+typedef uint16_t u16;
+typedef int32_t s32;
+typedef uint32_t u32;
+typedef int64_t s64;
+typedef uint64_t u64;
+typedef signed long sL;
+typedef unsigned long uL;
+typedef float F;
+typedef double D;
+
+void pack_varargs(s64* buf, const char* fmt, ...)
+{
+    va_list ap;
+    int c;
+    double d;
+    va_start(ap, fmt);
+    while ((c = *fmt++)) {
+        switch (c) {
+            case 'c':
+            case 's':
+            case 'i':
+                *buf++ = va_arg(ap, s32);
+                break;
+            case 'l':
+                *buf++ = va_arg(ap, long);
+                break;
+            case 'j':
+                *buf++ = va_arg(ap, s64);
+                break;
+            case 'f':
+            case 'd':
+                d = va_arg(ap, double);
+                memcpy(buf++, &d, sizeof(d));
+                break;
+            case 'C':
+            case 'S':
+            case 'I':
+                *buf++ = va_arg(ap, u32);
+                break;
+            case 'L':
+                *buf++ = va_arg(ap, unsigned long);
+                break;
+        }
+    }
+    va_end(ap);
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/nbproject/Makefile-impl.mk b/app/server/vendor/ffi-1.9.10/nbproject/Makefile-impl.mk
new file mode 100755
index 0000000..d6a7947
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/nbproject/Makefile-impl.mk
@@ -0,0 +1,123 @@
+# 
+# Generated Makefile - do not edit! 
+# 
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a pre- and a post- target defined where you can add customization code.
+#
+# This makefile implements macros and targets common to all configurations.
+#
+# NOCDDL
+
+
+# Building and Cleaning subprojects are done by default, but can be controlled with the SUB
+# macro. If SUB=no, subprojects will not be built or cleaned. The following macro
+# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf
+# and .clean-reqprojects-conf unless SUB has the value 'no'
+SUB_no=NO
+SUBPROJECTS=${SUB_${SUB}}
+BUILD_SUBPROJECTS_=.build-subprojects
+BUILD_SUBPROJECTS_NO=
+BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}}
+CLEAN_SUBPROJECTS_=.clean-subprojects
+CLEAN_SUBPROJECTS_NO=
+CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}}
+
+
+# Project Name
+PROJECTNAME=ruby-ffi.git
+
+# Active Configuration
+DEFAULTCONF=x86_64-Linux
+CONF=${DEFAULTCONF}
+
+# All Configurations
+ALLCONFS=x86_64-Linux 
+
+
+# build
+.build-impl: .build-pre .validate-impl .depcheck-impl
+	@#echo "=> Running $@... Configuration=$(CONF)"
+	${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf
+
+
+# clean
+.clean-impl: .clean-pre .validate-impl .depcheck-impl
+	@#echo "=> Running $@... Configuration=$(CONF)"
+	${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .clean-conf
+
+
+# clobber 
+.clobber-impl: .clobber-pre .depcheck-impl
+	@#echo "=> Running $@..."
+	for CONF in ${ALLCONFS}; \
+	do \
+	    ${MAKE} -f nbproject/Makefile-$${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .clean-conf; \
+	done
+
+# all 
+.all-impl: .all-pre .depcheck-impl
+	@#echo "=> Running $@..."
+	for CONF in ${ALLCONFS}; \
+	do \
+	    ${MAKE} -f nbproject/Makefile-$${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf; \
+	done
+
+# dependency checking support
+.depcheck-impl:
+	@echo "# This code depends on make tool being used" >.dep.inc
+	@if [ -n "${MAKE_VERSION}" ]; then \
+	    echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \
+	    echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \
+	    echo "include \$${DEPFILES}" >>.dep.inc; \
+	    echo "endif" >>.dep.inc; \
+	else \
+	    echo ".KEEP_STATE:" >>.dep.inc; \
+	    echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \
+	fi
+
+# configuration validation
+.validate-impl:
+	@if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
+	then \
+	    echo ""; \
+	    echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \
+	    echo "See 'make help' for details."; \
+	    echo "Current directory: " `pwd`; \
+	    echo ""; \
+	fi
+	@if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
+	then \
+	    exit 1; \
+	fi
+
+
+# help
+.help-impl: .help-pre
+	@echo "This makefile supports the following configurations:"
+	@echo "    ${ALLCONFS}"
+	@echo ""
+	@echo "and the following targets:"
+	@echo "    build  (default target)"
+	@echo "    clean"
+	@echo "    clobber"
+	@echo "    all"
+	@echo "    help"
+	@echo ""
+	@echo "Makefile Usage:"
+	@echo "    make [CONF=<CONFIGURATION>] [SUB=no] build"
+	@echo "    make [CONF=<CONFIGURATION>] [SUB=no] clean"
+	@echo "    make [SUB=no] clobber"
+	@echo "    make [SUB=no] all"
+	@echo "    make help"
+	@echo ""
+	@echo "Target 'build' will build a specific configuration and, unless 'SUB=no',"
+	@echo "    also build subprojects."
+	@echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no',"
+	@echo "    also clean subprojects."
+	@echo "Target 'clobber' will remove all built files from all configurations and,"
+	@echo "    unless 'SUB=no', also from subprojects."
+	@echo "Target 'all' will will build all configurations and, unless 'SUB=no',"
+	@echo "    also build subprojects."
+	@echo "Target 'help' prints this message."
+	@echo ""
+
diff --git a/app/server/vendor/ffi-1.9.10/nbproject/Makefile-variables.mk b/app/server/vendor/ffi-1.9.10/nbproject/Makefile-variables.mk
new file mode 100755
index 0000000..9ee818c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/nbproject/Makefile-variables.mk
@@ -0,0 +1,16 @@
+#
+# Generated - do not edit!
+#
+# NOCDDL
+#
+CND_BASEDIR=`pwd`
+CND_BUILDDIR=build
+CND_DISTDIR=dist
+# x86_64-Linux configuration
+CND_PLATFORM_x86_64-Linux=GNU-Linux-x86
+CND_ARTIFACT_DIR_x86_64-Linux=
+CND_ARTIFACT_NAME_x86_64-Linux=
+CND_ARTIFACT_PATH_x86_64-Linux=
+CND_PACKAGE_DIR_x86_64-Linux=dist/x86_64-Linux/GNU-Linux-x86/package
+CND_PACKAGE_NAME_x86_64-Linux=ruby-ffi.git.tar
+CND_PACKAGE_PATH_x86_64-Linux=dist/x86_64-Linux/GNU-Linux-x86/package/ruby-ffi.git.tar
diff --git a/app/server/vendor/ffi-1.9.10/nbproject/Makefile-x86_64-Linux.mk b/app/server/vendor/ffi-1.9.10/nbproject/Makefile-x86_64-Linux.mk
new file mode 100755
index 0000000..b9a4959
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/nbproject/Makefile-x86_64-Linux.mk
@@ -0,0 +1,63 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a -pre and a -post target defined where you can add customized code.
+#
+# This makefile implements configuration specific macros and targets.
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+RANLIB=ranlib
+CC=gcc
+CCC=g++
+CXX=g++
+FC=
+AS=as
+
+# Macros
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=x86_64-Linux
+CND_DISTDIR=dist
+
+# Include project Makefile
+include ruby-ffi-Makefile.mk
+
+# Object Directory
+OBJECTDIR=build/${CND_CONF}/${CND_PLATFORM}
+
+# Object Files
+OBJECTFILES=
+
+# C Compiler Flags
+CFLAGS=
+
+# CC Compiler Flags
+CCFLAGS=
+CXXFLAGS=
+
+# Fortran Compiler Flags
+FFLAGS=
+
+# Assembler Flags
+ASFLAGS=
+
+# Link Libraries and Options
+LDLIBSOPTIONS=
+
+# Build Targets
+.build-conf: ${BUILD_SUBPROJECTS}
+	cd . && ${MAKE}
+
+# Subprojects
+.build-subprojects:
+
+# Clean Targets
+.clean-conf: ${CLEAN_SUBPROJECTS}
+	cd . && ${MAKE} clean
+
+# Subprojects
+.clean-subprojects:
diff --git a/app/server/vendor/ffi-1.9.10/nbproject/Package-x86_64-Linux.bash b/app/server/vendor/ffi-1.9.10/nbproject/Package-x86_64-Linux.bash
new file mode 100755
index 0000000..6c40a8d
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/nbproject/Package-x86_64-Linux.bash
@@ -0,0 +1,74 @@
+#!/bin/bash -x
+
+#
+# Generated - do not edit!
+#
+
+# Macros
+TOP=`pwd`
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=x86_64-Linux
+CND_DISTDIR=dist
+TMPDIR=build/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
+TMPDIRNAME=tmp-packaging
+OUTPUT_PATH=MissingOutputInProject
+OUTPUT_BASENAME=MissingOutputInProject
+PACKAGE_TOP_DIR=ruby-ffi.git/
+
+# Functions
+function checkReturnCode
+{
+    rc=$?
+    if [ $rc != 0 ]
+    then
+        exit $rc
+    fi
+}
+function makeDirectory
+# $1 directory path
+# $2 permission (optional)
+{
+    mkdir -p "$1"
+    checkReturnCode
+    if [ "$2" != "" ]
+    then
+      chmod $2 "$1"
+      checkReturnCode
+    fi
+}
+function copyFileToTmpDir
+# $1 from-file path
+# $2 to-file path
+# $3 permission
+{
+    cp "$1" "$2"
+    checkReturnCode
+    if [ "$3" != "" ]
+    then
+        chmod $3 "$2"
+        checkReturnCode
+    fi
+}
+
+# Setup
+cd "${TOP}"
+mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
+rm -rf ${TMPDIR}
+mkdir -p ${TMPDIR}
+
+# Copy files and create directories and links
+cd "${TOP}"
+makeDirectory ${TMPDIR}/ruby-ffi.git/bin
+copyFileToTmpDir "${OUTPUT_PATH}" "${TMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755
+
+
+# Generate tar file
+cd "${TOP}"
+rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/ruby-ffi.git.tar
+cd ${TMPDIR}
+tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/ruby-ffi.git.tar *
+checkReturnCode
+
+# Cleanup
+cd "${TOP}"
+rm -rf ${TMPDIR}
diff --git a/app/server/vendor/ffi-1.9.10/nbproject/configurations.xml b/app/server/vendor/ffi-1.9.10/nbproject/configurations.xml
new file mode 100755
index 0000000..b91a709
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/nbproject/configurations.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configurationDescriptor version="62">
+  <logicalFolder name="root" displayName="root" projectFiles="true">
+    <logicalFolder name="ruby-ffi" displayName="ruby-ffi" projectFiles="true">
+      <logicalFolder name="ext" displayName="ext" projectFiles="true">
+        <itemPath>ext/ffi_c/AbstractMemory.c</itemPath>
+        <itemPath>ext/ffi_c/AbstractMemory.h</itemPath>
+        <itemPath>ext/ffi_c/ArrayType.c</itemPath>
+        <itemPath>ext/ffi_c/ArrayType.h</itemPath>
+        <itemPath>ext/ffi_c/AutoPointer.c</itemPath>
+        <itemPath>ext/ffi_c/AutoPointer.h</itemPath>
+        <itemPath>ext/ffi_c/Buffer.c</itemPath>
+        <itemPath>ext/ffi_c/Call.c</itemPath>
+        <itemPath>ext/ffi_c/Call.h</itemPath>
+        <itemPath>ext/ffi_c/ClosurePool.c</itemPath>
+        <itemPath>ext/ffi_c/ClosurePool.h</itemPath>
+        <itemPath>ext/ffi_c/DynamicLibrary.c</itemPath>
+        <itemPath>ext/ffi_c/DynamicLibrary.h</itemPath>
+        <itemPath>ext/ffi_c/Function.c</itemPath>
+        <itemPath>ext/ffi_c/Function.h</itemPath>
+        <itemPath>ext/ffi_c/FunctionInfo.c</itemPath>
+        <itemPath>ext/ffi_c/LastError.c</itemPath>
+        <itemPath>ext/ffi_c/LastError.h</itemPath>
+        <itemPath>ext/ffi_c/MappedType.c</itemPath>
+        <itemPath>ext/ffi_c/MappedType.h</itemPath>
+        <itemPath>ext/ffi_c/MemoryPointer.c</itemPath>
+        <itemPath>ext/ffi_c/MemoryPointer.h</itemPath>
+        <itemPath>ext/ffi_c/MethodHandle.c</itemPath>
+        <itemPath>ext/ffi_c/MethodHandle.h</itemPath>
+        <itemPath>ext/ffi_c/Platform.c</itemPath>
+        <itemPath>ext/ffi_c/Platform.h</itemPath>
+        <itemPath>ext/ffi_c/Pointer.c</itemPath>
+        <itemPath>ext/ffi_c/Pointer.h</itemPath>
+        <itemPath>ext/ffi_c/Struct.c</itemPath>
+        <itemPath>ext/ffi_c/Struct.h</itemPath>
+        <itemPath>ext/ffi_c/StructByValue.c</itemPath>
+        <itemPath>ext/ffi_c/StructByValue.h</itemPath>
+        <itemPath>ext/ffi_c/StructLayout.c</itemPath>
+        <itemPath>ext/ffi_c/Type.c</itemPath>
+        <itemPath>ext/ffi_c/Type.h</itemPath>
+        <itemPath>ext/ffi_c/Types.c</itemPath>
+        <itemPath>ext/ffi_c/Types.h</itemPath>
+        <itemPath>ext/ffi_c/Variadic.c</itemPath>
+        <itemPath>ext/ffi_c/compat.h</itemPath>
+        <itemPath>ext/ffi_c/extconf.rb</itemPath>
+        <itemPath>ext/ffi_c/ffi.c</itemPath>
+        <itemPath>ext/ffi_c/rbffi.h</itemPath>
+      </logicalFolder>
+      <logicalFolder name="f1" displayName="lib" projectFiles="true">
+        <logicalFolder name="ffi" displayName="ffi" projectFiles="true">
+          <itemPath>lib/ffi/autopointer.rb</itemPath>
+          <itemPath>lib/ffi/callback.rb</itemPath>
+          <itemPath>lib/ffi/enum.rb</itemPath>
+          <itemPath>lib/ffi/ffi.rb</itemPath>
+          <itemPath>lib/ffi/io.rb</itemPath>
+          <itemPath>lib/ffi/library.rb</itemPath>
+          <itemPath>lib/ffi/memorypointer.rb</itemPath>
+          <itemPath>lib/ffi/platform.rb</itemPath>
+          <itemPath>lib/ffi/pointer.rb</itemPath>
+          <itemPath>lib/ffi/struct.rb</itemPath>
+          <itemPath>lib/ffi/struct_layout_builder.rb</itemPath>
+          <itemPath>lib/ffi/types.rb</itemPath>
+          <itemPath>lib/ffi/variadic.rb</itemPath>
+        </logicalFolder>
+        <itemPath>lib/ffi.rb</itemPath>
+      </logicalFolder>
+      <logicalFolder name="libtest" displayName="libtest" projectFiles="true">
+        <itemPath>libtest/Benchmark.c</itemPath>
+        <itemPath>libtest/BufferTest.c</itemPath>
+        <itemPath>libtest/ClosureTest.c</itemPath>
+        <itemPath>libtest/GlobalVariable.c</itemPath>
+        <itemPath>libtest/LastErrorTest.c</itemPath>
+        <itemPath>libtest/NumberTest.c</itemPath>
+        <itemPath>libtest/PointerTest.c</itemPath>
+        <itemPath>libtest/ReferenceTest.c</itemPath>
+        <itemPath>libtest/StringTest.c</itemPath>
+        <itemPath>libtest/StructTest.c</itemPath>
+        <itemPath>libtest/VariadicTest.c</itemPath>
+      </logicalFolder>
+      <logicalFolder name="f2" displayName="spec" projectFiles="true">
+        <itemPath>spec/ffi/buffer_spec.rb</itemPath>
+        <itemPath>spec/ffi/callback_spec.rb</itemPath>
+        <itemPath>spec/ffi/custom_param_type.rb</itemPath>
+        <itemPath>spec/ffi/custom_type_spec.rb</itemPath>
+        <itemPath>spec/ffi/enum_spec.rb</itemPath>
+        <itemPath>spec/ffi/errno_spec.rb</itemPath>
+        <itemPath>spec/ffi/library_spec.rb</itemPath>
+        <itemPath>spec/ffi/managed_struct_spec.rb</itemPath>
+        <itemPath>spec/ffi/number_spec.rb</itemPath>
+        <itemPath>spec/ffi/pointer_spec.rb</itemPath>
+        <itemPath>spec/ffi/spec_helper.rb</itemPath>
+        <itemPath>spec/ffi/string_spec.rb</itemPath>
+        <itemPath>spec/ffi/strptr_spec.rb</itemPath>
+        <itemPath>spec/ffi/struct_callback_spec.rb</itemPath>
+        <itemPath>spec/ffi/struct_packed_spec.rb</itemPath>
+        <itemPath>spec/ffi/struct_spec.rb</itemPath>
+        <itemPath>spec/ffi/typedef_spec.rb</itemPath>
+        <itemPath>spec/ffi/union_spec.rb</itemPath>
+        <itemPath>spec/ffi/variadic_spec.rb</itemPath>
+      </logicalFolder>
+    </logicalFolder>
+    <logicalFolder name="ExternalFiles"
+                   displayName="Important Files"
+                   projectFiles="false">
+      <itemPath>Makefile</itemPath>
+      <itemPath>Rakefile</itemPath>
+      <itemPath>ext/ffi_c/extconf.rb</itemPath>
+      <itemPath>ruby-ffi-Makefile.mk</itemPath>
+    </logicalFolder>
+  </logicalFolder>
+  <projectmakefile>ruby-ffi-Makefile.mk</projectmakefile>
+  <confs>
+    <conf name="x86_64-Linux" type="0">
+      <toolsSet>
+        <developmentServer>localhost</developmentServer>
+        <compilerSet>GNU|GNU</compilerSet>
+        <platform>2</platform>
+      </toolsSet>
+      <makefileType>
+        <makeTool>
+          <buildCommandWorkingDir>.</buildCommandWorkingDir>
+          <buildCommand>${MAKE}</buildCommand>
+          <cleanCommand>${MAKE} clean</cleanCommand>
+          <executablePath></executablePath>
+          <cTool>
+            <incDir>
+              <pElem>/usr/local/ruby-trunk/include/ruby-1.9.1/ruby</pElem>
+              <pElem>/usr/local/ruby-trunk/include/ruby-1.9.1</pElem>
+              <pElem>/usr/include/x86_64-linux-gnu</pElem>
+            </incDir>
+          </cTool>
+        </makeTool>
+      </makefileType>
+    </conf>
+  </confs>
+</configurationDescriptor>
diff --git a/app/server/vendor/ffi-1.9.10/nbproject/project.properties b/app/server/vendor/ffi-1.9.10/nbproject/project.properties
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/ffi-1.9.10/nbproject/project.xml b/app/server/vendor/ffi-1.9.10/nbproject/project.xml
new file mode 100755
index 0000000..5fc72e1
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/nbproject/project.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.cnd.makeproject</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/make-project/1">
+            <name>ruby-ffi</name>
+            <make-project-type>0</make-project-type>
+            <c-extensions>c</c-extensions>
+            <cpp-extensions/>
+            <header-extensions>h</header-extensions>
+            <sourceEncoding>UTF-8</sourceEncoding>
+            <make-dep-projects/>
+        </data>
+    </configuration>
+</project>
diff --git a/app/server/vendor/ffi-1.9.10/samples/getlogin.rb b/app/server/vendor/ffi-1.9.10/samples/getlogin.rb
new file mode 100755
index 0000000..de47cac
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/samples/getlogin.rb
@@ -0,0 +1,8 @@
+require 'rubygems'
+require 'ffi'
+module Foo
+  extend FFI::Library
+  ffi_lib FFI::Library::LIBC
+  attach_function :getlogin, [ ], :string
+end
+puts "getlogin=#{Foo.getlogin}"
diff --git a/app/server/vendor/ffi-1.9.10/samples/getpid.rb b/app/server/vendor/ffi-1.9.10/samples/getpid.rb
new file mode 100755
index 0000000..e44534c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/samples/getpid.rb
@@ -0,0 +1,8 @@
+require 'rubygems'
+require 'ffi'
+module Foo
+  extend FFI::Library
+  ffi_lib FFI::Library::LIBC
+  attach_function :getpid, [ ], :int
+end
+puts "My pid=#{Foo.getpid}"
diff --git a/app/server/vendor/ffi-1.9.10/samples/gettimeofday.rb b/app/server/vendor/ffi-1.9.10/samples/gettimeofday.rb
new file mode 100755
index 0000000..34b2668
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/samples/gettimeofday.rb
@@ -0,0 +1,18 @@
+require 'rubygems'
+require 'ffi'
+class Timeval < FFI::Struct
+  rb_maj, rb_min, rb_micro = RUBY_VERSION.split('.')
+  if rb_maj.to_i >= 1 && rb_min.to_i >= 9 || RUBY_PLATFORM =~ /java/
+    layout :tv_sec => :ulong, :tv_usec => :ulong
+  else
+    layout :tv_sec, :ulong, 0, :tv_usec, :ulong, 4
+  end
+end
+module LibC
+  extend FFI::Library
+  ffi_lib FFI::Library::LIBC
+  attach_function :gettimeofday, [ :pointer, :pointer ], :int
+end
+t = Timeval.new
+LibC.gettimeofday(t.pointer, nil)
+puts "t.tv_sec=#{t[:tv_sec]} t.tv_usec=#{t[:tv_usec]}"
diff --git a/app/server/vendor/ffi-1.9.10/samples/hello.rb b/app/server/vendor/ffi-1.9.10/samples/hello.rb
new file mode 100755
index 0000000..11d5285
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/samples/hello.rb
@@ -0,0 +1,7 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "sample_helper"))
+module Foo
+  extend FFI::Library
+  ffi_lib FFI::Library::LIBC
+  attach_function("cputs", "puts", [ :string ], :int)
+end
+Foo.cputs("Hello, World via libc puts using FFI on MRI ruby")
diff --git a/app/server/vendor/ffi-1.9.10/samples/inotify.rb b/app/server/vendor/ffi-1.9.10/samples/inotify.rb
new file mode 100755
index 0000000..e615f7b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/samples/inotify.rb
@@ -0,0 +1,60 @@
+require 'rubygems'
+require 'ffi'
+module Inotify
+  extend FFI::Library
+  ffi_lib FFI::Library::LIBC
+  class Event < FFI::Struct
+    layout \
+      :wd, :int,
+      :mask, :uint,
+      :cookie, :uint,
+      :len, :uint
+  end
+  attach_function :init, :inotify_init, [ ], :int
+  attach_function :add_watch, :inotify_add_watch, [ :int, :string, :uint ], :int
+  attach_function :rm_watch, :inotify_rm_watch, [ :int, :uint ], :int
+  attach_function :read, [ :int, :buffer_out, :uint ], :int
+  IN_ACCESS=0x00000001
+  IN_MODIFY=0x00000002
+  IN_ATTRIB=0x00000004
+  IN_CLOSE_WRITE=0x00000008
+  IN_CLOSE_NOWRITE=0x00000010
+  IN_CLOSE=(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
+  IN_OPEN=0x00000020
+  IN_MOVED_FROM=0x00000040
+  IN_MOVED_TO=0x00000080
+  IN_MOVE= (IN_MOVED_FROM | IN_MOVED_TO)
+  IN_CREATE=0x00000100
+  IN_DELETE=0x00000200
+  IN_DELETE_SELF=0x00000400
+  IN_MOVE_SELF=0x00000800
+  # Events sent by the kernel.
+  IN_UNMOUNT=0x00002000
+  IN_Q_OVERFLOW=0x00004000
+  IN_IGNORED=0x00008000
+  IN_ONLYDIR=0x01000000
+  IN_DONT_FOLLOW=0x02000000
+  IN_MASK_ADD=0x20000000
+  IN_ISDIR=0x40000000
+  IN_ONESHOT=0x80000000
+  IN_ALL_EVENTS=(IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE \
+                          | IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM \
+                          | IN_MOVED_TO | IN_CREATE | IN_DELETE \
+                          | IN_DELETE_SELF | IN_MOVE_SELF)
+
+end
+if $0 == __FILE__
+  fd = Inotify.init
+  puts "fd=#{fd}"
+  wd = Inotify.add_watch(fd, "/tmp/", Inotify::IN_ALL_EVENTS)
+  fp = FFI::IO.for_fd(fd)
+  puts "wfp=#{fp}"
+  while true
+    buf = FFI::Buffer.alloc_out(Inotify::Event.size + 4096, 1, false)
+    ev = Inotify::Event.new buf
+    ready = IO.select([ fp ], nil, nil, nil)
+    n = Inotify.read(fd, buf, buf.total)
+    puts "Read #{n} bytes from inotify fd"
+    puts "event.wd=#{ev[:wd]} mask=#{ev[:mask]} len=#{ev[:len]} name=#{ev[:len] > 0 ? buf.get_string(16) : 'unknown'}"
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/samples/pty.rb b/app/server/vendor/ffi-1.9.10/samples/pty.rb
new file mode 100755
index 0000000..45c5a19
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/samples/pty.rb
@@ -0,0 +1,76 @@
+require 'ffi'
+
+
+module PTY
+  private
+  module LibC
+    extend FFI::Library
+    ffi_lib FFI::Library::LIBC
+    attach_function :forkpty, [ :buffer_out, :buffer_out, :buffer_in, :buffer_in ], :int
+    attach_function :openpty, [ :buffer_out, :buffer_out, :buffer_out, :buffer_in, :buffer_in ], :int
+    attach_function :login_tty, [ :int ], :int
+    attach_function :close, [ :int ], :int
+    attach_function :strerror, [ :int ], :string
+    attach_function :fork, [], :int
+    attach_function :execv, [ :string, :buffer_in ], :int
+    attach_function :execvp, [ :string, :buffer_in ], :int
+    attach_function :dup2, [ :int, :int ], :int
+    attach_function :dup, [ :int ], :int
+  end
+  Buffer = FFI::Buffer
+  def self.build_args(args)
+    cmd = args.shift
+    cmd_args = args.map do |arg|
+      MemoryPointer.from_string(arg)
+    end
+    exec_args = MemoryPointer.new(:pointer, 1 + cmd_args.length + 1)
+    exec_cmd = MemoryPointer.from_string(cmd)
+    exec_args[0].put_pointer(0, exec_cmd)
+    cmd_args.each_with_index do |arg, i|
+      exec_args[i + 1].put_pointer(0, arg)
+    end
+    [ cmd, exec_args ]
+  end
+  public
+  def self.getpty(*args)
+    mfdp = Buffer.new :int
+    name = Buffer.new 1024
+    #
+    # All the execv setup is done in the parent, since doing anything other than
+    # execv in the child after fork is really flakey
+    #
+    exec_cmd, exec_args = build_args(args)
+    pid = LibC.forkpty(mfdp, name, nil, nil)
+    raise "forkpty failed: #{LibC.strerror(FFI.errno)}" if pid < 0    
+    if pid == 0
+      LibC.execvp(exec_cmd, exec_args)
+      exit 1
+    end
+    masterfd = mfdp.get_int(0)
+    rfp = FFI::IO.for_fd(masterfd, "r")
+    wfp = FFI::IO.for_fd(LibC.dup(masterfd), "w")
+    if block_given?
+      yield rfp, wfp, pid
+      rfp.close unless rfp.closed?
+      wfp.close unless wfp.closed?
+    else
+      [ rfp, wfp, pid ]
+    end
+  end
+  def self.spawn(*args, &block)
+    self.getpty("/bin/sh", "-c", args[0], &block)
+  end
+end
+module LibC
+  extend FFI::Library
+  attach_function :close, [ :int ], :int
+  attach_function :write, [ :int, :buffer_in, :ulong ], :long
+  attach_function :read, [ :int, :buffer_out, :ulong ], :long
+end
+PTY.getpty("/bin/ls", "-alR", "/") { |rfd, wfd, pid|
+#PTY.spawn("ls -laR /") { |rfd, wfd, pid|
+  puts "child pid=#{pid}"
+  while !rfd.eof? && (buf = rfd.gets)
+    puts "child: '#{buf.strip}'"
+  end
+}
diff --git a/app/server/vendor/ffi-1.9.10/samples/qsort.rb b/app/server/vendor/ffi-1.9.10/samples/qsort.rb
new file mode 100755
index 0000000..5d4ab6c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/samples/qsort.rb
@@ -0,0 +1,21 @@
+require 'rubygems'
+require 'ffi'
+
+module LibC
+  extend FFI::Library
+  ffi_lib FFI::Library::LIBC
+  callback :qsort_cmp, [ :pointer, :pointer ], :int
+  attach_function :qsort, [ :pointer, :ulong, :ulong, :qsort_cmp ], :int
+end
+
+p = FFI::MemoryPointer.new(:int, 2)
+p.put_array_of_int32(0, [ 2, 1 ])
+puts "ptr=#{p.inspect}"
+puts "Before qsort #{p.get_array_of_int32(0, 2).join(', ')}"
+LibC.qsort(p, 2, 4) do |p1, p2|
+  i1 = p1.get_int32(0)
+  i2 = p2.get_int32(0)
+  puts "In block: comparing #{i1} and #{i2}"
+  i1 < i2 ? -1 : i1 > i2 ? 1 : 0
+end
+puts "After qsort #{p.get_array_of_int32(0, 2).join(', ')}"
diff --git a/app/server/vendor/ffi-1.9.10/samples/sample_helper.rb b/app/server/vendor/ffi-1.9.10/samples/sample_helper.rb
new file mode 100755
index 0000000..2bac44f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/samples/sample_helper.rb
@@ -0,0 +1,6 @@
+require 'rubygems'
+require 'spec'
+
+$:.unshift File.join(File.dirname(__FILE__), "..", "lib"), File.join(File.dirname(__FILE__), "..", "build", RUBY_VERSION) unless RUBY_PLATFORM =~ /java/
+require "ffi"
+
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/LICENSE.SPECS b/app/server/vendor/ffi-1.9.10/spec/ffi/LICENSE.SPECS
new file mode 100755
index 0000000..561dd8c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/LICENSE.SPECS
@@ -0,0 +1,22 @@
+Copyright (c) 2008-2014 Ruby-FFI contributors
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/async_callback_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/async_callback_spec.rb
new file mode 100755
index 0000000..87950cc
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/async_callback_spec.rb
@@ -0,0 +1,35 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "async callback" do
+  module LibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    AsyncIntCallback = callback [ :int ], :void
+
+    @blocking = true
+    attach_function :testAsyncCallback, [ AsyncIntCallback, :int ], :void
+  end
+
+  it ":int (0x7fffffff) argument" do
+    v = 0xdeadbeef
+    called = false
+    cb = Proc.new {|i| v = i; called = true }
+    LibTest.testAsyncCallback(cb, 0x7fffffff) 
+    expect(called).to be true
+    expect(v).to eq(0x7fffffff)
+  end
+  
+  it "called a second time" do
+    v = 0xdeadbeef
+    called = false
+    cb = Proc.new {|i| v = i; called = true }
+    LibTest.testAsyncCallback(cb, 0x7fffffff) 
+    expect(called).to be true
+    expect(v).to eq(0x7fffffff)
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/bool_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/bool_spec.rb
new file mode 100755
index 0000000..6cd1d6f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/bool_spec.rb
@@ -0,0 +1,32 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "Function with primitive boolean arguments and return values" do
+  module LibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    attach_function :bool_return_true, [ ], :bool
+    attach_function :bool_return_false, [ ], :bool
+    attach_function :bool_return_val, [ :bool ], :bool
+    attach_function :bool_reverse_val, [ :bool ], :bool
+  end
+
+  it "bools" do
+    expect(LibTest.bool_return_true).to be true
+    expect(LibTest.bool_return_false).to be false
+
+    expect(LibTest.bool_return_val(true)).to be true
+    expect(LibTest.bool_return_val(false)).to be false
+
+    expect(LibTest.bool_reverse_val(true)).to be false
+    expect(LibTest.bool_reverse_val(false)).to be true
+  end
+
+  it "raise error on invalid types" do
+    expect { LibTest.bool_return_val(nil) }.to raise_error(::TypeError)
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/buffer_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/buffer_spec.rb
new file mode 100755
index 0000000..5f22a62
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/buffer_spec.rb
@@ -0,0 +1,279 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "Buffer#total" do
+  [1,2,3].each do |i|
+    { :char => 1, :uchar => 1, :short => 2, :ushort => 2, :int => 4, 
+      :uint => 4, :long => FFI::Type::LONG.size, :ulong => FFI::Type::ULONG.size, 
+      :long_long => 8, :ulong_long => 8, :float => 4, :double => 8
+    }.each_pair do |t, s|
+
+      it "Buffer.alloc_in(#{t}, #{i}).total == #{i * s}" do
+        expect(FFI::Buffer.alloc_in(t, i).total).to eq(i * s)
+      end
+
+      it "Buffer.alloc_out(#{t}, #{i}).total == #{i * s}" do
+        expect(FFI::Buffer.alloc_out(t, i).total).to eq(i * s)
+      end
+
+      it "Buffer.alloc_inout(#{t}, #{i}).total == #{i * s}" do
+        expect(FFI::Buffer.alloc_inout(t, i).total).to eq(i * s)
+      end
+    end
+  end
+end
+
+describe "Buffer#put_char" do
+  bufsize = 4
+  (0..127).each do |i|
+    (0..bufsize-1).each do |offset|
+      it "put_char(#{offset}, #{i}).get_char(#{offset}) == #{i}" do
+        expect(FFI::Buffer.alloc_in(bufsize).put_char(offset, i).get_char(offset)).to eq(i)
+      end
+    end
+  end
+end
+
+describe "Buffer#put_uchar" do
+  bufsize = 4
+  (0..255).each do |i|
+    (0..bufsize-1).each do |offset|
+      it "Buffer.put_uchar(#{offset}, #{i}).get_uchar(#{offset}) == #{i}" do
+        expect(FFI::Buffer.alloc_in(bufsize).put_uchar(offset, i).get_uchar(offset)).to eq(i)
+      end
+    end
+  end 
+end
+
+describe "Buffer#put_short" do
+  bufsize = 4
+  [0, 1, 128, 32767].each do |i|
+    (0..bufsize-2).each do |offset|
+      it "put_short(#{offset}, #{i}).get_short(#{offset}) == #{i}" do
+        expect(FFI::Buffer.alloc_in(bufsize).put_short(offset, i).get_short(offset)).to eq(i)
+      end
+    end
+  end
+end
+
+describe "Buffer#put_ushort" do
+  bufsize = 4
+  [ 0, 1, 128, 32767, 65535, 0xfee1, 0xdead, 0xbeef, 0xcafe ].each do |i|
+    (0..bufsize-2).each do |offset|
+      it "put_ushort(#{offset}, #{i}).get_ushort(#{offset}) == #{i}" do
+        expect(FFI::Buffer.alloc_in(bufsize).put_ushort(offset, i).get_ushort(offset)).to eq(i)
+      end
+    end
+  end
+end
+
+describe "Buffer#put_int" do
+  bufsize = 8
+  [0, 1, 128, 32767, 0x7ffffff ].each do |i|
+    (0..bufsize-4).each do |offset|
+      it "put_int(#{offset}, #{i}).get_int(#{offset}) == #{i}" do
+        expect(FFI::Buffer.alloc_in(bufsize).put_int(offset, i).get_int(offset)).to eq(i)
+      end
+    end
+  end
+end
+
+describe "Buffer#put_uint" do
+  bufsize = 8
+  [ 0, 1, 128, 32767, 65535, 0xfee1dead, 0xcafebabe, 0xffffffff ].each do |i|
+    (0..bufsize-4).each do |offset|
+      it "put_uint(#{offset}, #{i}).get_uint(#{offset}) == #{i}" do
+        expect(FFI::Buffer.alloc_in(bufsize).put_uint(offset, i).get_uint(offset)).to eq(i)
+      end
+    end
+  end
+end
+
+describe "Buffer#put_long" do
+  bufsize = 16
+  [0, 1, 128, 32767, 0x7ffffff ].each do |i|
+    (0..bufsize-FFI::Type::LONG.size).each do |offset|
+      it "put_long(#{offset}, #{i}).get_long(#{offset}) == #{i}" do
+        expect(FFI::Buffer.alloc_in(bufsize).put_long(offset, i).get_long(offset)).to eq(i)
+      end
+    end
+  end
+end
+
+describe "Buffer#put_ulong" do
+  bufsize = 16
+  [ 0, 1, 128, 32767, 65535, 0xfee1dead, 0xcafebabe, 0xffffffff ].each do |i|
+    (0..bufsize-FFI::Type::LONG.size).each do |offset|
+      it "put_ulong(#{offset}, #{i}).get_ulong(#{offset}) == #{i}" do
+        expect(FFI::Buffer.alloc_in(bufsize).put_ulong(offset, i).get_ulong(offset)).to eq(i)
+      end
+    end
+  end
+end
+
+describe "Buffer#put_long_long" do
+  bufsize = 16
+  [0, 1, 128, 32767, 0x7ffffffffffffff ].each do |i|
+    (0..bufsize-8).each do |offset|
+      it "put_long_long(#{offset}, #{i}).get_long_long(#{offset}) == #{i}" do
+        expect(FFI::Buffer.alloc_in(bufsize).put_long_long(offset, i).get_long_long(offset)).to eq(i)
+      end
+    end
+  end
+end
+
+describe "Buffer#put_ulong_long" do
+  bufsize = 16
+  [ 0, 1, 128, 32767, 65535, 0xdeadcafebabe, 0x7fffffffffffffff ].each do |i|
+    (0..bufsize-8).each do |offset|
+      it "put_ulong_long(#{offset}, #{i}).get_ulong_long(#{offset}) == #{i}" do
+        expect(FFI::Buffer.alloc_in(bufsize).put_ulong_long(offset, i).get_ulong_long(offset)).to eq(i)
+      end
+    end
+  end
+end
+
+describe "Reading/Writing binary strings" do
+  it "Buffer#put_bytes" do
+    str = "hello\0world"
+    buf = FFI::Buffer.new 1024
+    buf.put_bytes(0, str);
+    s2 = buf.get_bytes(0, 11);
+    expect(s2).to eq(str)
+  end
+
+  it "Buffer#put_bytes with index and length" do
+    str = "hello\0world"
+    buf = FFI::Buffer.new 1024
+    buf.put_bytes(0, str, 5, 6);
+    s2 = buf.get_bytes(0, 6);
+    expect(s2).to eq(str[5..-1])
+  end
+
+  it "Buffer#put_bytes with only index" do
+    str = "hello\0world"
+    buf = FFI::Buffer.new 1024
+    buf.put_bytes(0, str, 5);
+    s2 = buf.get_bytes(0, 6);
+    expect(s2).to eq(str[5..-1])
+  end
+
+  it "Buffer#put_bytes with index > str.length" do
+    str = "hello\0world"
+    buf = FFI::Buffer.new 1024
+    expect { buf.put_bytes(0, str, 12); }.to raise_error
+  end
+
+  it "Buffer#put_bytes with length > str.length" do
+    str = "hello\0world"
+    buf = FFI::Buffer.new 1024
+    expect { buf.put_bytes(0, str, 0, 12); }.to raise_error
+  end
+
+  it "Buffer#put_bytes with negative index" do
+    str = "hello\0world"
+    buf = FFI::Buffer.new 1024
+    expect { buf.put_bytes(0, str, -1, 12); }.to raise_error
+  end
+
+  it "Buffer#write_bytes" do
+    str = "hello\0world"
+    buf = FFI::Buffer.new 1024
+    buf.write_bytes(str)
+    s2 = buf.get_bytes(0, 11)
+    expect(s2).to eq(str)
+  end
+
+  it "Buffer#write_bytes with index and length" do
+    str = "hello\0world"
+    buf = FFI::Buffer.new 1024
+    buf.write_bytes(str, 5, 6)
+    s2 = buf.get_bytes(0, 6)
+    expect(s2).to eq(str[5..-1])
+  end
+
+  it "Buffer#write_bytes with only index" do
+    str = "hello\0world"
+    buf = FFI::Buffer.new 1024
+    buf.write_bytes(str, 5)
+    s2 = buf.get_bytes(0, 6)
+    expect(s2).to eq(str[5..-1])
+  end
+
+  it "Buffer#write_bytes with index > str.length" do
+    str = "hello\0world"
+    buf = FFI::Buffer.new 1024
+    expect { buf.write_bytes(str, 12) }.to raise_error
+  end
+
+  it "Buffer#put_bytes with length > str.length" do
+    str = "hello\0world"
+    buf = FFI::Buffer.new 1024
+    expect { buf.put_bytes(0, str, 0, 12) }.to raise_error
+  end
+
+  it "Buffer#write_bytes with negative index" do
+    str = "hello\0world"
+    buf = FFI::Buffer.new 1024
+    expect { buf.write_bytes(str, -1, 12) }.to raise_error
+  end
+end
+
+describe "Reading/Writing ascii strings" do
+  it "Buffer#put_string with string containing zero byte" do
+    str = "hello\0world"
+    buf = FFI::Buffer.new 1024
+    buf.put_string(0, str);
+    s2 = buf.get_bytes(0, 11);
+    expect(s2).to eq(str)
+  end
+
+  it "Buffer#get_string with string containing zero byte" do
+    str = "hello\0world"
+    buf = FFI::Buffer.new 1024
+    buf.put_bytes(0, str);
+    s2 = buf.get_string(0, 11);
+    expect(s2).to eq("hello")
+  end
+
+  it "Buffer#put_string without length should NUL terminate" do
+    str = "hello"
+    buf = FFI::Buffer.new 1024
+    buf.put_string(0, str);
+    s2 = buf.get_bytes(0, 6);
+    expect(s2).to eq("hello\0")
+  end
+end
+
+describe "Buffer#put_pointer" do
+  it "put_pointer(0, p).get_pointer(0) == p" do
+    p = FFI::MemoryPointer.new :ulong_long
+    p.put_uint(0, 0xdeadbeef)
+    buf = FFI::Buffer.alloc_inout 8
+    p2 = buf.put_pointer(0, p).get_pointer(0)
+    expect(p2).not_to be_nil
+    expect(p2).to eq(p)
+    expect(p2.get_uint(0)).to eq(0xdeadbeef)
+  end
+end
+
+describe "Buffer#size" do
+  it "should return size" do
+    buf = FFI::Buffer.new 14
+    expect(buf.size).to eq(14)
+  end
+end
+
+describe "Buffer#initialize" do
+  it "with block should execute block" do
+    block_executed = false
+    FFI::Buffer.new(:pointer) do |ptr|
+      block_executed = true
+    end
+    expect(block_executed).to be true
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/callback_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/callback_spec.rb
new file mode 100755
index 0000000..bc9b55a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/callback_spec.rb
@@ -0,0 +1,773 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "Callback" do
+#  module LibC
+#    extend FFI::Library
+#    callback :qsort_cmp, [ :pointer, :pointer ], :int
+#    attach_function :qsort, [ :pointer, :int, :int, :qsort_cmp ], :int
+#  end
+#  it "arguments get passed correctly" do
+#    p = MemoryPointer.new(:int, 2)
+#    p.put_array_of_int32(0, [ 1 , 2 ])
+#    args = []
+#    cmp = proc do |p1, p2| args.push(p1.get_int(0)); args.push(p2.get_int(0)); 0; end
+#    # this is a bit dodgey, as it relies on qsort passing the args in order
+#    LibC.qsort(p, 2, 4, cmp)
+#    args.should == [ 1, 2 ]
+#  end
+#
+#  it "Block can be substituted for Callback as last argument" do
+#    p = MemoryPointer.new(:int, 2)
+#    p.put_array_of_int32(0, [ 1 , 2 ])
+#    args = []
+#    # this is a bit dodgey, as it relies on qsort passing the args in order
+#    LibC.qsort(p, 2, 4) do |p1, p2|
+#      args.push(p1.get_int(0))
+#      args.push(p2.get_int(0))
+#      0
+#    end
+#    args.should == [ 1, 2 ]
+#  end
+  module LibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    class S8F32S32 < FFI::Struct
+      layout :s8, :char, :f32, :float, :s32, :int
+    end
+
+    callback :cbVrS8, [ ], :char
+    callback :cbVrU8, [ ], :uchar
+    callback :cbVrS16, [ ], :short
+    callback :cbVrU16, [ ], :ushort
+    callback :cbVrS32, [ ], :int
+    callback :cbVrU32, [ ], :uint
+    callback :cbVrL, [ ], :long
+    callback :cbVrUL, [ ], :ulong
+    callback :cbVrS64, [ ], :long_long
+    callback :cbVrU64, [ ], :ulong_long
+    callback :cbVrP, [], :pointer
+    callback :cbVrZ, [], :bool
+    callback :cbCrV, [ :char ], :void
+    callback :cbSrV, [ :short ], :void
+    callback :cbIrV, [ :int ], :void
+    callback :cbLrV, [ :long ], :void
+    callback :cbULrV, [ :ulong ], :void
+    callback :cbLrV, [ :long_long ], :void
+    callback :cbVrT, [ ], S8F32S32.by_value
+    callback :cbTrV, [ S8F32S32.by_value ], :void
+    callback :cbYrV, [ S8F32S32.ptr ], :void
+    callback :cbVrY, [ ], S8F32S32.ptr
+
+    attach_function :testCallbackVrS8, :testClosureVrB, [ :cbVrS8 ], :char
+    attach_function :testCallbackVrU8, :testClosureVrB, [ :cbVrU8 ], :uchar
+    attach_function :testCallbackVrS16, :testClosureVrS, [ :cbVrS16 ], :short
+    attach_function :testCallbackVrU16, :testClosureVrS, [ :cbVrU16 ], :ushort
+    attach_function :testCallbackVrS32, :testClosureVrI, [ :cbVrS32 ], :int
+    attach_function :testCallbackVrU32, :testClosureVrI, [ :cbVrU32 ], :uint
+    attach_function :testCallbackVrL, :testClosureVrL, [ :cbVrL ], :long
+    attach_function :testCallbackVrZ, :testClosureVrZ, [ :cbVrZ ], :bool
+    attach_function :testCallbackVrUL, :testClosureVrL, [ :cbVrUL ], :ulong
+    attach_function :testCallbackVrS64, :testClosureVrLL, [ :cbVrS64 ], :long_long
+    attach_function :testCallbackVrU64, :testClosureVrLL, [ :cbVrU64 ], :ulong_long
+    attach_function :testCallbackVrP, :testClosureVrP, [ :cbVrP ], :pointer
+    attach_function :testCallbackVrY, :testClosureVrP, [ :cbVrY ], S8F32S32.ptr
+    attach_function :testCallbackVrT, :testClosureVrT, [ :cbVrT ], S8F32S32.by_value
+    attach_function :testCallbackTrV, :testClosureTrV, [ :cbTrV, S8F32S32.ptr ], :void
+    attach_variable :cbVrS8, :gvar_pointer, :cbVrS8
+    attach_variable :pVrS8, :gvar_pointer, :pointer
+    attach_function :testGVarCallbackVrS8, :testClosureVrB, [ :pointer ], :char
+    attach_function :testOptionalCallbackCrV, :testOptionalClosureBrV, [ :cbCrV, :char ], :void
+
+  end
+
+  it "returning :char (0)" do
+    expect(LibTest.testCallbackVrS8 { 0 }).to eq(0)
+  end
+
+  it "returning :char (127)" do
+    expect(LibTest.testCallbackVrS8 { 127 }).to eq(127)
+  end
+
+  it "returning :char (-128)" do
+    expect(LibTest.testCallbackVrS8 { -128 }).to eq(-128)
+  end
+  # test wrap around
+  it "returning :char (128)" do
+    expect(LibTest.testCallbackVrS8 { 128 }).to eq(-128)
+  end
+
+  it "returning :char (255)" do
+    expect(LibTest.testCallbackVrS8 { 0xff }).to eq(-1)
+  end
+
+  it "returning :uchar (0)" do
+    expect(LibTest.testCallbackVrU8 { 0 }).to eq(0)
+  end
+
+  it "returning :uchar (0xff)" do
+    expect(LibTest.testCallbackVrU8 { 0xff }).to eq(0xff)
+  end
+
+  it "returning :uchar (-1)" do
+    expect(LibTest.testCallbackVrU8 { -1 }).to eq(0xff)
+  end
+
+  it "returning :uchar (128)" do
+    expect(LibTest.testCallbackVrU8 { 128 }).to eq(128)
+  end
+
+  it "returning :uchar (-128)" do
+    expect(LibTest.testCallbackVrU8 { -128 }).to eq(128)
+  end
+
+  it "returning :short (0)" do
+    expect(LibTest.testCallbackVrS16 { 0 }).to eq(0)
+  end
+
+  it "returning :short (0x7fff)" do
+    expect(LibTest.testCallbackVrS16 { 0x7fff }).to eq(0x7fff)
+  end
+  # test wrap around
+  it "returning :short (0x8000)" do
+    expect(LibTest.testCallbackVrS16 { 0x8000 }).to eq(-0x8000)
+  end
+
+  it "returning :short (0xffff)" do
+    expect(LibTest.testCallbackVrS16 { 0xffff }).to eq(-1)
+  end
+
+  it "returning :ushort (0)" do
+    expect(LibTest.testCallbackVrU16 { 0 }).to eq(0)
+  end
+
+  it "returning :ushort (0x7fff)" do
+    expect(LibTest.testCallbackVrU16 { 0x7fff }).to eq(0x7fff)
+  end
+
+  it "returning :ushort (0x8000)" do
+    expect(LibTest.testCallbackVrU16 { 0x8000 }).to eq(0x8000)
+  end
+
+  it "returning :ushort (0xffff)" do
+    expect(LibTest.testCallbackVrU16 { 0xffff }).to eq(0xffff)
+  end
+
+  it "returning :ushort (-1)" do
+    expect(LibTest.testCallbackVrU16 { -1 }).to eq(0xffff)
+  end
+
+  it "returning :int (0)" do
+    expect(LibTest.testCallbackVrS32 { 0 }).to eq(0)
+  end
+
+  it "returning :int (0x7fffffff)" do
+    expect(LibTest.testCallbackVrS32 { 0x7fffffff }).to eq(0x7fffffff)
+  end
+  # test wrap around
+  it "returning :int (-0x80000000)" do
+    expect(LibTest.testCallbackVrS32 { -0x80000000 }).to eq(-0x80000000)
+  end
+
+  it "returning :int (-1)" do
+    expect(LibTest.testCallbackVrS32 { -1 }).to eq(-1)
+  end
+
+  it "returning :uint (0)" do
+    expect(LibTest.testCallbackVrU32 { 0 }).to eq(0)
+  end
+
+  it "returning :uint (0x7fffffff)" do
+    expect(LibTest.testCallbackVrU32 { 0x7fffffff }).to eq(0x7fffffff)
+  end
+  # test wrap around
+  it "returning :uint (0x80000000)" do
+    expect(LibTest.testCallbackVrU32 { 0x80000000 }).to eq(0x80000000)
+  end
+
+  it "returning :uint (0xffffffff)" do
+    expect(LibTest.testCallbackVrU32 { 0xffffffff }).to eq(0xffffffff)
+  end
+
+  it "returning :uint (-1)" do
+    expect(LibTest.testCallbackVrU32 { -1 }).to eq(0xffffffff)
+  end
+
+  it "returning :long (0)" do
+    expect(LibTest.testCallbackVrL { 0 }).to eq(0)
+  end
+
+  it "returning :long (0x7fffffff)" do
+    expect(LibTest.testCallbackVrL { 0x7fffffff }).to eq(0x7fffffff)
+  end
+  # test wrap around
+  it "returning :long (-0x80000000)" do
+    expect(LibTest.testCallbackVrL { -0x80000000 }).to eq(-0x80000000)
+  end
+
+  it "returning :long (-1)" do
+    expect(LibTest.testCallbackVrL { -1 }).to eq(-1)
+  end
+
+  it "returning :ulong (0)" do
+    expect(LibTest.testCallbackVrUL { 0 }).to eq(0)
+  end
+
+  it "returning :ulong (0x7fffffff)" do
+    expect(LibTest.testCallbackVrUL { 0x7fffffff }).to eq(0x7fffffff)
+  end
+  # test wrap around
+  it "returning :ulong (0x80000000)" do
+    expect(LibTest.testCallbackVrUL { 0x80000000 }).to eq(0x80000000)
+  end
+
+  it "returning :ulong (0xffffffff)" do
+    expect(LibTest.testCallbackVrUL { 0xffffffff }).to eq(0xffffffff)
+  end
+
+  it "Callback returning :ulong (-1)" do
+    if FFI::Platform::LONG_SIZE == 32
+      expect(LibTest.testCallbackVrUL { -1 }).to eq(0xffffffff)
+    else
+      expect(LibTest.testCallbackVrUL { -1 }).to eq(0xffffffffffffffff)
+    end
+  end
+
+  it "returning :long_long (0)" do
+    expect(LibTest.testCallbackVrS64 { 0 }).to eq(0)
+  end
+
+  it "returning :long_long (0x7fffffffffffffff)" do
+    expect(LibTest.testCallbackVrS64 { 0x7fffffffffffffff }).to eq(0x7fffffffffffffff)
+  end
+  # test wrap around
+  it "returning :long_long (-0x8000000000000000)" do
+    expect(LibTest.testCallbackVrS64 { -0x8000000000000000 }).to eq(-0x8000000000000000)
+  end
+
+  it "returning :long_long (-1)" do
+    expect(LibTest.testCallbackVrS64 { -1 }).to eq(-1)
+  end
+
+  it "returning bool" do
+    expect(LibTest.testCallbackVrZ { true }).to be true
+  end
+
+  it "returning :pointer (nil)" do
+    expect(LibTest.testCallbackVrP { nil }).to be_null
+  end
+
+  it "returning :pointer (MemoryPointer)" do
+    p = FFI::MemoryPointer.new :long
+    expect(LibTest.testCallbackVrP { p }).to eq(p)
+  end
+
+  it "returning struct by value" do
+    s = LibTest::S8F32S32.new
+    s[:s8] = 0x12
+    s[:s32] = 0x1eefbeef
+    s[:f32] = 1.234567
+    ret = LibTest.testCallbackVrT { s }
+    expect(ret[:s8]).to eq(s[:s8])
+    expect(ret[:f32]).to eq(s[:f32])
+    expect(ret[:s32]).to eq(s[:s32])
+
+  end
+
+  it "struct by value parameter" do
+    s = LibTest::S8F32S32.new
+    s[:s8] = 0x12
+    s[:s32] = 0x1eefbeef
+    s[:f32] = 1.234567
+    s2 = LibTest::S8F32S32.new
+
+    LibTest.testCallbackTrV(s) do |struct|
+      s2[:s8] = struct[:s8]
+      s2[:f32] = struct[:f32]
+      s2[:s32] = struct[:s32]
+    end
+
+    expect(s2[:s8]).to eql 0x12
+    expect(s2[:s32]).to eql 0x1eefbeef
+    expect(s2[:f32]).to be_within(0.0000001).of 1.234567
+  end
+
+  
+  it "global variable" do
+    proc = Proc.new { 0x1e }
+    LibTest.cbVrS8 = proc
+    expect(LibTest.testGVarCallbackVrS8(LibTest.pVrS8)).to eq(0x1e)
+  end
+
+  describe "When the callback is considered optional by the underlying library" do
+    it "should handle receiving 'nil' in place of the closure" do
+      expect(LibTest.testOptionalCallbackCrV(nil, 13)).to be_nil
+    end
+  end
+
+  describe 'when inlined' do
+    it 'could be anonymous' do
+      module LibTest
+        extend FFI::Library
+        ffi_lib TestLibrary::PATH
+        attach_function :testAnonymousCallbackVrS8, :testClosureVrB, [ callback([ ], :char) ], :char
+      end
+      expect(LibTest.testAnonymousCallbackVrS8 { 0 }).to eq(0)
+    end
+  end
+
+  describe "as return value" do
+
+    it "should not blow up when a callback is defined that returns a callback" do
+      expect(module LibTest
+        extend FFI::Library
+        ffi_lib TestLibrary::PATH
+        callback :cb_return_type_1, [ :short ], :short
+        callback :cb_lookup_1, [ :short ], :cb_return_type_1
+        attach_function :testReturnsCallback_1, :testReturnsClosure, [ :cb_lookup_1, :short ], :cb_return_type_1
+      end).to be_an_instance_of FFI::Function
+    end
+
+    it "should return a callback" do
+      module LibTest
+        extend FFI::Library
+        ffi_lib TestLibrary::PATH
+        callback :cb_return_type, [ :int ], :int
+        callback :cb_lookup, [ ], :cb_return_type
+        attach_function :testReturnsCallback, :testReturnsClosure, [ :cb_lookup, :int ], :int
+      end      
+
+      lookup_proc_called = false
+      return_proc_called = false
+
+      return_proc = Proc.new do |a|
+        return_proc_called = true
+        a * 2
+      end
+      lookup_proc = Proc.new do
+        lookup_proc_called = true
+        return_proc
+      end
+
+      val = LibTest.testReturnsCallback(lookup_proc, 0x1234)
+      expect(val).to eq(0x1234 * 2)
+      expect(lookup_proc_called).to be true
+      expect(return_proc_called).to be true
+    end
+
+    it "should return a method callback" do
+      module LibTest
+        extend FFI::Library
+        ffi_lib TestLibrary::PATH
+        callback :cb_return_type, [ :int ], :int
+        callback :cb_lookup, [ ], :cb_return_type
+        attach_function :testReturnsCallback_2, :testReturnsClosure, [ :cb_lookup, :int ], :int
+      end
+      module MethodCallback
+        def self.lookup
+          method(:perform)
+        end
+        def self.perform num
+          num * 2
+        end
+      end
+
+      expect(LibTest.testReturnsCallback_2(MethodCallback.method(:lookup), 0x1234)).to eq(0x2468)
+    end
+
+    it 'should not blow up when a callback takes a callback as argument' do
+      expect(module LibTest
+        extend FFI::Library
+        ffi_lib TestLibrary::PATH
+        callback :cb_argument, [ :int ], :int
+        callback :cb_with_cb_argument, [ :cb_argument, :int ], :int
+        attach_function :testCallbackAsArgument_2, :testArgumentClosure, [ :cb_with_cb_argument, :int ], :int
+      end).to be_an_instance_of FFI::Function
+    end
+    it 'should be able to use the callback argument' do
+      module LibTest
+        extend FFI::Library
+        ffi_lib TestLibrary::PATH
+        callback :cb_argument, [ :int ], :int
+        callback :cb_with_cb_argument, [ :cb_argument, :int ], :int
+        attach_function :testCallbackAsArgument, :testArgumentClosure, [ :cb_with_cb_argument, :cb_argument, :int ], :int
+      end   
+      callback_arg_called = false
+      callback_with_callback_arg_called = false
+      callback_arg = Proc.new do |val|
+        callback_arg_called = true
+        val * 2
+      end
+      callback_with_callback_arg = Proc.new do |cb, val|
+        callback_with_callback_arg_called = true
+        cb.call(val)
+      end
+      val = LibTest.testCallbackAsArgument(callback_with_callback_arg, callback_arg, 0xff1)
+      expect(val).to eq(0xff1 * 2)
+      expect(callback_arg_called).to be true
+      expect(callback_with_callback_arg_called).to be true
+    end
+    it 'function returns callable object' do
+      module LibTest
+        extend FFI::Library
+        ffi_lib TestLibrary::PATH
+        callback :funcptr, [ :int ], :int
+        attach_function :testReturnsFunctionPointer, [  ], :funcptr
+      end
+      f = LibTest.testReturnsFunctionPointer
+      expect(f.call(3)).to eq(6)
+    end
+  end
+
+end
+
+
+describe "Callback with " do
+  #
+  # Test callbacks that take an argument, returning void
+  #
+  module LibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+
+    class S8F32S32 < FFI::Struct
+      layout :s8, :char, :f32, :float, :s32, :int
+    end
+
+    callback :cbS8rV, [ :char ], :void
+    callback :cbU8rV, [ :uchar ], :void
+    callback :cbS16rV, [ :short ], :void
+    callback :cbU16rV, [ :ushort ], :void
+
+    callback :cbZrV, [ :bool ], :void
+    callback :cbS32rV, [ :int ], :void
+    callback :cbU32rV, [ :uint ], :void
+
+    callback :cbLrV, [ :long ], :void
+    callback :cbULrV, [ :ulong ], :void
+    callback :cbArV, [ :string ], :void
+    callback :cbPrV, [ :pointer], :void
+    callback :cbYrV, [ S8F32S32.ptr ], :void
+
+    callback :cbS64rV, [ :long_long ], :void
+    attach_function :testCallbackCrV, :testClosureBrV, [ :cbS8rV, :char ], :void
+    attach_function :testCallbackU8rV, :testClosureBrV, [ :cbU8rV, :uchar ], :void
+    attach_function :testCallbackSrV, :testClosureSrV, [ :cbS16rV, :short ], :void
+    attach_function :testCallbackU16rV, :testClosureSrV, [ :cbU16rV, :ushort ], :void
+    attach_function :testCallbackZrV, :testClosureZrV, [ :cbZrV, :bool ], :void
+    attach_function :testCallbackIrV, :testClosureIrV, [ :cbS32rV, :int ], :void
+    attach_function :testCallbackU32rV, :testClosureIrV, [ :cbU32rV, :uint ], :void
+
+    attach_function :testCallbackLrV, :testClosureLrV, [ :cbLrV, :long ], :void
+    attach_function :testCallbackULrV, :testClosureULrV, [ :cbULrV, :ulong ], :void
+
+    attach_function :testCallbackLLrV, :testClosureLLrV, [ :cbS64rV, :long_long ], :void
+    attach_function :testCallbackArV, :testClosurePrV, [ :cbArV, :string ], :void
+    attach_function :testCallbackPrV, :testClosurePrV, [ :cbPrV, :pointer], :void
+    attach_function :testCallbackYrV, :testClosurePrV, [ :cbYrV, S8F32S32.in ], :void
+  end
+
+  it "function with Callback plus another arg should raise error if no arg given" do
+    expect { LibTest.testCallbackCrV { |*a| }}.to raise_error
+  end
+
+  it ":char (0) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackCrV(0) { |i| v = i }
+    expect(v).to eq(0)
+  end
+
+  it ":char (127) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackCrV(127) { |i| v = i }
+    expect(v).to eq(127)
+  end
+
+  it ":char (-128) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackCrV(-128) { |i| v = i }
+    expect(v).to eq(-128)
+  end
+
+  it ":char (-1) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackCrV(-1) { |i| v = i }
+    expect(v).to eq(-1)
+  end
+
+  it ":uchar (0) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackU8rV(0) { |i| v = i }
+    expect(v).to eq(0)
+  end
+
+  it ":uchar (127) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackU8rV(127) { |i| v = i }
+    expect(v).to eq(127)
+  end
+
+  it ":uchar (128) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackU8rV(128) { |i| v = i }
+    expect(v).to eq(128)
+  end
+
+  it ":uchar (255) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackU8rV(255) { |i| v = i }
+    expect(v).to eq(255)
+  end
+
+  it ":short (0) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackSrV(0) { |i| v = i }
+    expect(v).to eq(0)
+  end
+
+  it ":short (0x7fff) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackSrV(0x7fff) { |i| v = i }
+    expect(v).to eq(0x7fff)
+  end
+
+  it ":short (-0x8000) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackSrV(-0x8000) { |i| v = i }
+    expect(v).to eq(-0x8000)
+  end
+
+  it ":short (-1) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackSrV(-1) { |i| v = i }
+    expect(v).to eq(-1)
+  end
+
+  it ":ushort (0) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackU16rV(0) { |i| v = i }
+    expect(v).to eq(0)
+  end
+
+  it ":ushort (0x7fff) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackU16rV(0x7fff) { |i| v = i }
+    expect(v).to eq(0x7fff)
+  end
+
+  it ":ushort (0x8000) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackU16rV(0x8000) { |i| v = i }
+    expect(v).to eq(0x8000)
+  end
+
+  it ":ushort (0xffff) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackU16rV(0xffff) { |i| v = i }
+    expect(v).to eq(0xffff)
+  end
+
+  it ":bool (true) argument" do
+    v = false
+    LibTest.testCallbackZrV(true) { |i| v = i }
+    expect(v).to be true
+  end
+
+  it ":int (0) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackIrV(0) { |i| v = i }
+    expect(v).to eq(0)
+  end
+
+  it ":int (0x7fffffff) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackIrV(0x7fffffff) { |i| v = i }
+    expect(v).to eq(0x7fffffff)
+  end
+
+  it ":int (-0x80000000) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackIrV(-0x80000000) { |i| v = i }
+    expect(v).to eq(-0x80000000)
+  end
+
+  it ":int (-1) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackIrV(-1) { |i| v = i }
+    expect(v).to eq(-1)
+  end
+
+  it ":uint (0) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackU32rV(0) { |i| v = i }
+    expect(v).to eq(0)
+  end
+
+  it ":uint (0x7fffffff) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackU32rV(0x7fffffff) { |i| v = i }
+    expect(v).to eq(0x7fffffff)
+  end
+
+  it ":uint (0x80000000) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackU32rV(0x80000000) { |i| v = i }
+    expect(v).to eq(0x80000000)
+  end
+
+  it ":uint (0xffffffff) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackU32rV(0xffffffff) { |i| v = i }
+    expect(v).to eq(0xffffffff)
+  end
+
+  it ":long (0) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackLrV(0) { |i| v = i }
+    expect(v).to eq(0)
+  end
+
+  it ":long (0x7fffffff) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackLrV(0x7fffffff) { |i| v = i }
+    expect(v).to eq(0x7fffffff)
+  end
+
+  it ":long (-0x80000000) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackLrV(-0x80000000) { |i| v = i }
+    expect(v).to eq(-0x80000000)
+  end
+
+  it ":long (-1) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackLrV(-1) { |i| v = i }
+    expect(v).to eq(-1)
+  end
+
+  it ":ulong (0) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackULrV(0) { |i| v = i }
+    expect(v).to eq(0)
+  end
+
+  it ":ulong (0x7fffffff) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackULrV(0x7fffffff) { |i| v = i }
+    expect(v).to eq(0x7fffffff)
+  end
+
+  it ":ulong (0x80000000) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackULrV(0x80000000) { |i| v = i }
+    expect(v).to eq(0x80000000)
+  end
+
+  it ":ulong (0xffffffff) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackULrV(0xffffffff) { |i| v = i }
+    expect(v).to eq(0xffffffff)
+  end
+
+  it ":long_long (0) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackLLrV(0) { |i| v = i }
+    expect(v).to eq(0)
+  end
+
+  it ":long_long (0x7fffffffffffffff) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackLLrV(0x7fffffffffffffff) { |i| v = i }
+    expect(v).to eq(0x7fffffffffffffff)
+  end
+
+  it ":long_long (-0x8000000000000000) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackLLrV(-0x8000000000000000) { |i| v = i }
+    expect(v).to eq(-0x8000000000000000)
+  end
+
+  it ":long_long (-1) argument" do
+    v = 0xdeadbeef
+    LibTest.testCallbackLLrV(-1) { |i| v = i }
+    expect(v).to eq(-1)
+  end
+
+  it ":string argument" do
+    v = nil
+    LibTest.testCallbackArV("Hello, World") { |i| v = i }
+    expect(v).to eq("Hello, World")
+  end
+
+  it ":string (nil) argument" do
+    v = "Hello, World"
+    LibTest.testCallbackArV(nil) { |i| v = i }
+    expect(v).to be_nil
+  end
+
+  it ":pointer argument" do
+    v = nil
+    magic = FFI::Pointer.new(0xdeadbeef)
+    LibTest.testCallbackPrV(magic) { |i| v = i }
+    expect(v).to eq(magic)
+  end
+
+  it ":pointer (nil) argument" do
+    v = "Hello, World"
+    LibTest.testCallbackPrV(nil) { |i| v = i }
+    expect(v).to eq(FFI::Pointer::NULL)
+  end
+
+  it "struct by reference argument" do
+    v = nil
+    magic = LibTest::S8F32S32.new
+    LibTest.testCallbackYrV(magic) { |i| v = i }
+    expect(v.class).to eq(magic.class)
+    expect(v.pointer).to eq(magic.pointer)
+  end
+
+  it "struct by reference argument with nil value" do
+    v = LibTest::S8F32S32.new
+    LibTest.testCallbackYrV(nil) { |i| v = i }
+    expect(v.is_a?(FFI::Struct)).to be true
+    expect(v.pointer).to eq(FFI::Pointer::NULL)
+  end
+
+  it "varargs parameters are rejected" do
+    expect {
+      Module.new do
+        extend FFI::Library
+        ffi_lib TestLibrary::PATH
+        callback :cbVrL, [ :varargs ], :long
+      end
+    }.to raise_error(ArgumentError)
+  end
+
+  #
+  # Test stdcall convention with function and callback.
+  # This is Windows 32-bit only.
+  #
+  if FFI::Platform::OS =~ /windows|cygwin/ && FFI::Platform::ARCH == 'i386'
+    module LibTestStdcall
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      ffi_convention :stdcall
+
+      callback :cbStdcall, [ :pointer, :long ], :void
+      attach_function :testCallbackStdcall, 'testClosureStdcall', [ :pointer, :cbStdcall, :long ], :bool
+    end
+
+    it "stdcall convention" do
+      v = 0xdeadbeef
+      po = FFI::MemoryPointer.new :long
+      pr = proc{|a,i| v = a,i; i }
+      res = LibTestStdcall.testCallbackStdcall(po, pr, 0x7fffffff)
+      expect(v).to eq([po, 0x7fffffff])
+      expect(res).to be true
+    end
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/custom_param_type.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/custom_param_type.rb
new file mode 100755
index 0000000..7d9216b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/custom_param_type.rb
@@ -0,0 +1,37 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "functions with custom parameter types" do
+  before :each do
+
+    Custom_enum = Class.new do
+      extend FFI::DataConverter
+      ToNativeMap= { :a => 1, :b => 2 }
+      FromNativeMap = { 1 => :a, 2 => :b }
+
+      def self.native_type
+        @native_type_called = true
+        FFI::Type::INT32
+      end
+
+      def self.to_native(val, ctx)
+        @to_native_called = true
+        ToNativeMap[val]
+      end
+
+      def self.from_native(val, ctx)
+        @from_native_called = true
+        FromNativeMap[val]
+      end
+      def self.native_type_called?; @native_type_called; end
+      def self.from_native_called?; @from_native_called; end
+      def self.to_native_called?; @to_native_called; end
+    end
+
+    # FIXME add tests
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/custom_type_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/custom_type_spec.rb
new file mode 100755
index 0000000..d9ce2c1
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/custom_type_spec.rb
@@ -0,0 +1,74 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "functions with custom types" do
+  class Custom_enum
+    extend FFI::DataConverter
+    ToNativeMap= { :a => 1, :b => 2, :c => 3 }
+    FromNativeMap = { 1 => :a, 2 => :b, 3 => :c }
+
+    def self.native_type
+      @native_type_called = true
+      FFI::Type::INT32
+    end
+
+    def self.to_native(val, ctx)
+      @to_native_called = true
+      ToNativeMap[val]
+    end
+
+    def self.from_native(val, ctx)
+      @from_native_called = true
+      FromNativeMap[val]
+    end
+    def self.native_type_called?; @native_type_called; end
+    def self.from_native_called?; @from_native_called; end
+    def self.to_native_called?; @to_native_called; end
+  end
+
+  it "can attach with custom return type" do
+    expect do
+      Module.new do
+        extend FFI::Library
+        ffi_lib TestLibrary::PATH
+        attach_function :ret_s32, [ :int ], Custom_enum
+      end
+    end.not_to raise_error
+  end
+
+  it "should return object of correct type" do
+
+    m = Module.new do
+
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      attach_function :ret_s32, [ :int ], Custom_enum
+    end
+
+    expect(m.ret_s32(1).is_a?(Symbol)).to be true
+  end
+
+  it "from_native should be called for result" do
+    m = Module.new do
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      attach_function :ret_s32, [ :int ], Custom_enum
+    end
+    m.ret_s32(1)
+    expect(Custom_enum.from_native_called?).to be true
+  end
+
+  it "to_native should be called for parameter" do
+    m = Module.new do
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      attach_function :ret_s32, [ Custom_enum ], :int
+    end
+    m.ret_s32(:a)
+    expect(Custom_enum.to_native_called?).to be true
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/dup_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/dup_spec.rb
new file mode 100755
index 0000000..ae6e523
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/dup_spec.rb
@@ -0,0 +1,52 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "Pointer#dup" do 
+  it "clone should be independent" do
+    p1 = FFI::MemoryPointer.new(:char, 1024)
+    p1.put_string(0, "test123");
+    p2 = p1.dup
+    p1.put_string(0, "deadbeef")
+    
+    expect(p2.get_string(0)).to eq("test123")
+  end
+  
+  it "sliced pointer can be cloned" do
+    p1 = FFI::MemoryPointer.new(:char, 1024)
+    p1.put_string(0, "test123");
+    p2 = p1[1].dup
+    
+    # first char will be excised
+    expect(p2.get_string(0)).to eq("est123")
+    expect(p1.get_string(0)).to eq("test123")
+  end
+  
+  it "sliced pointer when cloned is independent" do
+    p1 = FFI::MemoryPointer.new(:char, 1024)
+    p1.put_string(0, "test123");
+    p2 = p1[1].dup
+    
+    p1.put_string(0, "deadbeef")
+    # first char will be excised
+    expect(p2.get_string(0)).to eq("est123")
+  end
+end
+
+
+describe "Struct#dup" do
+  it "clone should be independent" do
+    s = Class.new(FFI::Struct) do
+      layout :i, :int
+    end
+    s1 = s.new
+    s1[:i] = 0x12345
+    s2 = s1.dup
+    s1[:i] = 0x98765
+    expect(s2[:i]).to eq(0x12345)
+    expect(s1[:i]).to eq(0x98765)
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/enum_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/enum_spec.rb
new file mode 100755
index 0000000..55ff13a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/enum_spec.rb
@@ -0,0 +1,423 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+module TestEnum0
+  extend FFI::Library
+end
+
+module TestEnum1
+  extend FFI::Library
+  ffi_lib TestLibrary::PATH
+
+  enum [:c1, :c2, :c3, :c4]
+  enum [:c5, 42, :c6, :c7, :c8]
+  enum [:c9, 42, :c10, :c11, 4242, :c12]
+  enum [:c13, 42, :c14, 4242, :c15, 424242, :c16, 42424242]
+  
+  attach_function :test_untagged_enum, [:int], :int
+end
+
+module TestEnum3
+  extend FFI::Library
+  ffi_lib TestLibrary::PATH
+
+  enum :enum_type1, [:c1, :c2, :c3, :c4]
+  enum :enum_type2, [:c5, 42, :c6, :c7, :c8]
+  enum :enum_type3, [:c9, 42, :c10, :c11, 4242, :c12]
+  enum :enum_type4, [:c13, 42, :c14, 4242, :c15, 424242, :c16, 42424242]
+
+  attach_function :test_tagged_typedef_enum1, [:enum_type1], :enum_type1
+  attach_function :test_tagged_typedef_enum2, [:enum_type2], :enum_type2
+  attach_function :test_tagged_typedef_enum3, [:enum_type3], :enum_type3
+  attach_function :test_tagged_typedef_enum4, [:enum_type4], :enum_type4
+end
+
+module TestEnum4
+  extend FFI::Library
+  ffi_lib TestLibrary::PATH
+
+  enum [:c1, :c2, :c3, :c4]
+  enum :enum_type1, [:c5, 0x42, :c6, :c7, :c8]
+  enum :enum_type2, [:c9, 0x42, :c10, :c11, 0x4242, :c12]
+  enum :enum_type3, [:c13, 0x42, :c14, 0x4242, :c15, 0x42424242, :c16, 0x4242424242424242]
+  enum FFI::Type::UINT16, :enum_type4, [:c17, 0x42, :c18, :c19, :c20]
+  enum FFI::Type::UINT32, :enum_type5, [:c21, 0x42, :c22, :c23, 0x4242, :c24]
+  enum FFI::Type::UINT64, :enum_type6, [:c25, 0x42, :c26, 0x4242, :c27, 0x42424242, :c28, 0x4242424242424242]
+  enum FFI::Type::UINT64, [:c29, 0x4242424242424242, :c30, :c31, :c32]
+
+  attach_function :test_untagged_nonint_enum, [:uint8],  :uint8
+  attach_function :test_tagged_nonint_enum1,  [:uint16], :uint16
+  attach_function :test_tagged_nonint_enum2,  [:uint32], :uint32
+  attach_function :test_tagged_nonint_enum3,  [:uint64], :uint64
+  attach_function :test_tagged_nonint_enum4, :test_tagged_nonint_enum1,  [:enum_type4], :enum_type4
+  attach_function :test_tagged_nonint_enum5, :test_tagged_nonint_enum2,  [:enum_type5], :enum_type5
+  attach_function :test_tagged_nonint_enum6, :test_tagged_nonint_enum3,  [:enum_type6], :enum_type6
+end
+
+describe "A library with no enum defined" do
+  it "returns nil when asked for an enum" do
+    expect(TestEnum0.enum_type(:foo)).to be_nil
+  end
+end
+
+describe "An untagged enum" do
+  it "constants can be used as function parameters and return value" do
+    expect(TestEnum1.test_untagged_enum(:c1)).to eq(0)
+    expect(TestEnum1.test_untagged_enum(:c2)).to eq(1)
+    expect(TestEnum1.test_untagged_enum(:c3)).to eq(2)
+    expect(TestEnum1.test_untagged_enum(:c4)).to eq(3)
+    expect(TestEnum1.test_untagged_enum(:c5)).to eq(42)
+    expect(TestEnum1.test_untagged_enum(:c6)).to eq(43)
+    expect(TestEnum1.test_untagged_enum(:c7)).to eq(44)
+    expect(TestEnum1.test_untagged_enum(:c8)).to eq(45)
+    expect(TestEnum1.test_untagged_enum(:c9)).to eq(42)
+    expect(TestEnum1.test_untagged_enum(:c10)).to eq(43)
+    expect(TestEnum1.test_untagged_enum(:c11)).to eq(4242)
+    expect(TestEnum1.test_untagged_enum(:c12)).to eq(4243)
+    expect(TestEnum1.test_untagged_enum(:c13)).to eq(42)
+    expect(TestEnum1.test_untagged_enum(:c14)).to eq(4242)
+    expect(TestEnum1.test_untagged_enum(:c15)).to eq(424242)
+    expect(TestEnum1.test_untagged_enum(:c16)).to eq(42424242)
+    expect(TestEnum4.test_untagged_nonint_enum(:c1)).to eq(0)
+    expect(TestEnum4.test_untagged_nonint_enum(:c2)).to eq(1)
+    expect(TestEnum4.test_untagged_nonint_enum(:c3)).to eq(2)
+    expect(TestEnum4.test_untagged_nonint_enum(:c4)).to eq(3)
+    expect(TestEnum4.test_tagged_nonint_enum3(:c29)).to eq(0x4242424242424242)
+    expect(TestEnum4.test_tagged_nonint_enum3(:c30)).to eq(0x4242424242424243)
+    expect(TestEnum4.test_tagged_nonint_enum3(:c31)).to eq(0x4242424242424244)
+    expect(TestEnum4.test_tagged_nonint_enum3(:c32)).to eq(0x4242424242424245)
+  end
+end
+
+describe "A tagged typedef enum" do
+  it "is accessible through its tag" do
+    expect(TestEnum3.enum_type(:enum_type1)).not_to be_nil
+    expect(TestEnum3.enum_type(:enum_type2)).not_to be_nil
+    expect(TestEnum3.enum_type(:enum_type3)).not_to be_nil
+    expect(TestEnum3.enum_type(:enum_type4)).not_to be_nil
+    expect(TestEnum4.enum_type(:enum_type1)).not_to be_nil
+    expect(TestEnum4.enum_type(:enum_type2)).not_to be_nil
+    expect(TestEnum4.enum_type(:enum_type3)).not_to be_nil
+    expect(TestEnum4.enum_type(:enum_type4)).not_to be_nil
+    expect(TestEnum4.enum_type(:enum_type5)).not_to be_nil
+    expect(TestEnum4.enum_type(:enum_type6)).not_to be_nil
+  end
+
+  it "contains enum constants" do
+    expect(TestEnum3.enum_type(:enum_type1).symbols.length).to eq(4)
+    expect(TestEnum3.enum_type(:enum_type2).symbols.length).to eq(4)
+    expect(TestEnum3.enum_type(:enum_type3).symbols.length).to eq(4)
+    expect(TestEnum3.enum_type(:enum_type4).symbols.length).to eq(4)
+    expect(TestEnum4.enum_type(:enum_type1).symbols.length).to eq(4)
+    expect(TestEnum4.enum_type(:enum_type2).symbols.length).to eq(4)
+    expect(TestEnum4.enum_type(:enum_type3).symbols.length).to eq(4)
+    expect(TestEnum4.enum_type(:enum_type4).symbols.length).to eq(4)
+    expect(TestEnum4.enum_type(:enum_type5).symbols.length).to eq(4)
+    expect(TestEnum4.enum_type(:enum_type6).symbols.length).to eq(4)
+  end
+
+  it "constants can be used as function parameters and return value" do
+    expect(TestEnum3.test_tagged_typedef_enum1(:c1)).to be :c1
+    expect(TestEnum3.test_tagged_typedef_enum1(:c2)).to be :c2
+    expect(TestEnum3.test_tagged_typedef_enum1(:c3)).to be :c3
+    expect(TestEnum3.test_tagged_typedef_enum1(:c4)).to be :c4
+    expect(TestEnum3.test_tagged_typedef_enum2(:c5)).to be :c5
+    expect(TestEnum3.test_tagged_typedef_enum2(:c6)).to be :c6
+    expect(TestEnum3.test_tagged_typedef_enum2(:c7)).to be :c7
+    expect(TestEnum3.test_tagged_typedef_enum2(:c8)).to be :c8
+    expect(TestEnum3.test_tagged_typedef_enum3(:c9)).to be :c9
+    expect(TestEnum3.test_tagged_typedef_enum3(:c10)).to be :c10
+    expect(TestEnum3.test_tagged_typedef_enum3(:c11)).to be :c11
+    expect(TestEnum3.test_tagged_typedef_enum3(:c12)).to be :c12
+    expect(TestEnum3.test_tagged_typedef_enum4(:c13)).to be :c13
+    expect(TestEnum3.test_tagged_typedef_enum4(:c14)).to be :c14
+    expect(TestEnum3.test_tagged_typedef_enum4(:c15)).to be :c15
+    expect(TestEnum3.test_tagged_typedef_enum4(:c16)).to be :c16
+    expect(TestEnum4.test_tagged_nonint_enum1(:c5)).to eq(0x42)
+    expect(TestEnum4.test_tagged_nonint_enum1(:c6)).to eq(0x43)
+    expect(TestEnum4.test_tagged_nonint_enum1(:c7)).to eq(0x44)
+    expect(TestEnum4.test_tagged_nonint_enum1(:c8)).to eq(0x45)
+    expect(TestEnum4.test_tagged_nonint_enum2(:c9)).to eq(0x42)
+    expect(TestEnum4.test_tagged_nonint_enum2(:c10)).to eq(0x43)
+    expect(TestEnum4.test_tagged_nonint_enum2(:c11)).to eq(0x4242)
+    expect(TestEnum4.test_tagged_nonint_enum2(:c12)).to eq(0x4243)
+    expect(TestEnum4.test_tagged_nonint_enum3(:c13)).to eq(0x42)
+    expect(TestEnum4.test_tagged_nonint_enum3(:c14)).to eq(0x4242)
+    expect(TestEnum4.test_tagged_nonint_enum3(:c15)).to eq(0x42424242)
+    expect(TestEnum4.test_tagged_nonint_enum3(:c16)).to eq(0x4242424242424242)
+    expect(TestEnum4.test_tagged_nonint_enum4(:c17)).to eq(:c17)
+    expect(TestEnum4.test_tagged_nonint_enum4(:c18)).to eq(:c18)
+    expect(TestEnum4.test_tagged_nonint_enum4(:c19)).to eq(:c19)
+    expect(TestEnum4.test_tagged_nonint_enum4(:c20)).to eq(:c20)
+    expect(TestEnum4.test_tagged_nonint_enum5(:c21)).to eq(:c21)
+    expect(TestEnum4.test_tagged_nonint_enum5(:c22)).to eq(:c22)
+    expect(TestEnum4.test_tagged_nonint_enum5(:c23)).to eq(:c23)
+    expect(TestEnum4.test_tagged_nonint_enum5(:c24)).to eq(:c24)
+    expect(TestEnum4.test_tagged_nonint_enum6(:c25)).to eq(:c25)
+    expect(TestEnum4.test_tagged_nonint_enum6(:c26)).to eq(:c26)
+    expect(TestEnum4.test_tagged_nonint_enum6(:c27)).to eq(:c27)
+    expect(TestEnum4.test_tagged_nonint_enum6(:c28)).to eq(:c28)
+  end
+
+  it "integers can be used instead of constants" do
+    expect(TestEnum3.test_tagged_typedef_enum1(0)).to be :c1
+    expect(TestEnum3.test_tagged_typedef_enum1(1)).to be :c2
+    expect(TestEnum3.test_tagged_typedef_enum1(2)).to be :c3
+    expect(TestEnum3.test_tagged_typedef_enum1(3)).to be :c4
+    expect(TestEnum3.test_tagged_typedef_enum2(42)).to be :c5
+    expect(TestEnum3.test_tagged_typedef_enum2(43)).to be :c6
+    expect(TestEnum3.test_tagged_typedef_enum2(44)).to be :c7
+    expect(TestEnum3.test_tagged_typedef_enum2(45)).to be :c8
+    expect(TestEnum3.test_tagged_typedef_enum3(42)).to be :c9
+    expect(TestEnum3.test_tagged_typedef_enum3(43)).to be :c10
+    expect(TestEnum3.test_tagged_typedef_enum3(4242)).to be :c11
+    expect(TestEnum3.test_tagged_typedef_enum3(4243)).to be :c12
+    expect(TestEnum3.test_tagged_typedef_enum4(42)).to be :c13
+    expect(TestEnum3.test_tagged_typedef_enum4(4242)).to be :c14
+    expect(TestEnum3.test_tagged_typedef_enum4(424242)).to be :c15
+    expect(TestEnum3.test_tagged_typedef_enum4(42424242)).to be :c16
+    expect(TestEnum4.test_tagged_nonint_enum4(0x42)).to eq(:c17)
+    expect(TestEnum4.test_tagged_nonint_enum4(0x43)).to eq(:c18)
+    expect(TestEnum4.test_tagged_nonint_enum4(0x44)).to eq(:c19)
+    expect(TestEnum4.test_tagged_nonint_enum4(0x45)).to eq(:c20)
+    expect(TestEnum4.test_tagged_nonint_enum5(0x42)).to eq(:c21)
+    expect(TestEnum4.test_tagged_nonint_enum5(0x43)).to eq(:c22)
+    expect(TestEnum4.test_tagged_nonint_enum5(0x4242)).to eq(:c23)
+    expect(TestEnum4.test_tagged_nonint_enum5(0x4243)).to eq(:c24)
+    expect(TestEnum4.test_tagged_nonint_enum6(0x42)).to eq(:c25)
+    expect(TestEnum4.test_tagged_nonint_enum6(0x4242)).to eq(:c26)
+    expect(TestEnum4.test_tagged_nonint_enum6(0x42424242)).to eq(:c27)
+    expect(TestEnum4.test_tagged_nonint_enum6(0x4242424242424242)).to eq(:c28)
+  end
+end
+
+describe "All enums" do
+  it "have autonumbered constants when defined with names only" do
+    expect(TestEnum1.enum_value(:c1)).to eq(0)
+    expect(TestEnum1.enum_value(:c2)).to eq(1)
+    expect(TestEnum1.enum_value(:c3)).to eq(2)
+    expect(TestEnum1.enum_value(:c4)).to eq(3)
+
+    expect(TestEnum3.enum_value(:c1)).to eq(0)
+    expect(TestEnum3.enum_value(:c2)).to eq(1)
+    expect(TestEnum3.enum_value(:c3)).to eq(2)
+    expect(TestEnum3.enum_value(:c4)).to eq(3)
+
+    expect(TestEnum4.enum_value(:c1)).to eq(0)
+    expect(TestEnum4.enum_value(:c2)).to eq(1)
+    expect(TestEnum4.enum_value(:c3)).to eq(2)
+    expect(TestEnum4.enum_value(:c4)).to eq(3)
+  end
+
+  it "can have an explicit first constant and autonumbered subsequent constants" do
+    expect(TestEnum1.enum_value(:c5)).to eq(42)
+    expect(TestEnum1.enum_value(:c6)).to eq(43)
+    expect(TestEnum1.enum_value(:c7)).to eq(44)
+    expect(TestEnum1.enum_value(:c8)).to eq(45)
+
+    expect(TestEnum3.enum_value(:c5)).to eq(42)
+    expect(TestEnum3.enum_value(:c6)).to eq(43)
+    expect(TestEnum3.enum_value(:c7)).to eq(44)
+    expect(TestEnum3.enum_value(:c8)).to eq(45)
+
+    expect(TestEnum4.enum_value(:c5)).to eq(0x42)
+    expect(TestEnum4.enum_value(:c6)).to eq(0x43)
+    expect(TestEnum4.enum_value(:c7)).to eq(0x44)
+    expect(TestEnum4.enum_value(:c8)).to eq(0x45)
+
+    expect(TestEnum4.enum_value(:c29)).to eq(0x4242424242424242)
+    expect(TestEnum4.enum_value(:c30)).to eq(0x4242424242424243)
+    expect(TestEnum4.enum_value(:c31)).to eq(0x4242424242424244)
+    expect(TestEnum4.enum_value(:c32)).to eq(0x4242424242424245)
+  end
+
+  it "can have a mix of explicit and autonumbered constants" do
+    expect(TestEnum1.enum_value(:c9)).to eq(42)
+    expect(TestEnum1.enum_value(:c10)).to eq(43)
+    expect(TestEnum1.enum_value(:c11)).to eq(4242)
+    expect(TestEnum1.enum_value(:c12)).to eq(4243)
+
+    expect(TestEnum3.enum_value(:c9)).to eq(42)
+    expect(TestEnum3.enum_value(:c10)).to eq(43)
+    expect(TestEnum3.enum_value(:c11)).to eq(4242)
+    expect(TestEnum3.enum_value(:c12)).to eq(4243)
+
+    expect(TestEnum4.enum_value(:c9)).to eq(0x42)
+    expect(TestEnum4.enum_value(:c10)).to eq(0x43)
+    expect(TestEnum4.enum_value(:c11)).to eq(0x4242)
+    expect(TestEnum4.enum_value(:c12)).to eq(0x4243)
+
+    expect(TestEnum4.enum_value(:c21)).to eq(0x42)
+    expect(TestEnum4.enum_value(:c22)).to eq(0x43)
+    expect(TestEnum4.enum_value(:c23)).to eq(0x4242)
+    expect(TestEnum4.enum_value(:c24)).to eq(0x4243)
+  end
+
+  it "can have all its constants explicitely valued" do
+    expect(TestEnum1.enum_value(:c13)).to eq(42)
+    expect(TestEnum1.enum_value(:c14)).to eq(4242)
+    expect(TestEnum1.enum_value(:c15)).to eq(424242)
+    expect(TestEnum1.enum_value(:c16)).to eq(42424242)
+    
+    expect(TestEnum3.enum_value(:c13)).to eq(42)
+    expect(TestEnum3.enum_value(:c14)).to eq(4242)
+    expect(TestEnum3.enum_value(:c15)).to eq(424242)
+    expect(TestEnum3.enum_value(:c16)).to eq(42424242)
+
+    expect(TestEnum4.enum_value(:c13)).to eq(0x42)
+    expect(TestEnum4.enum_value(:c14)).to eq(0x4242)
+    expect(TestEnum4.enum_value(:c15)).to eq(0x42424242)
+    expect(TestEnum4.enum_value(:c16)).to eq(0x4242424242424242)
+
+    expect(TestEnum4.enum_value(:c25)).to eq(0x42)
+    expect(TestEnum4.enum_value(:c26)).to eq(0x4242)
+    expect(TestEnum4.enum_value(:c27)).to eq(0x42424242)
+    expect(TestEnum4.enum_value(:c28)).to eq(0x4242424242424242)
+  end
+
+  it "return the constant corresponding to a specific value" do
+    enum = TestEnum3.enum_type(:enum_type1)
+    expect(enum[0]).to be :c1
+    expect(enum[1]).to be :c2
+    expect(enum[2]).to be :c3
+    expect(enum[3]).to be :c4
+
+    enum = TestEnum3.enum_type(:enum_type2)
+    expect(enum[42]).to be :c5
+    expect(enum[43]).to be :c6
+    expect(enum[44]).to be :c7
+    expect(enum[45]).to be :c8
+
+    enum = TestEnum3.enum_type(:enum_type3)
+    expect(enum[42]).to be :c9
+    expect(enum[43]).to be :c10
+    expect(enum[4242]).to be :c11
+    expect(enum[4243]).to be :c12
+
+    enum = TestEnum3.enum_type(:enum_type4)
+    expect(enum[42]).to be :c13
+    expect(enum[4242]).to be :c14
+    expect(enum[424242]).to be :c15
+    expect(enum[42424242]).to be :c16
+
+    enum = TestEnum4.enum_type(:enum_type1)
+    expect(enum[0x42]).to eq(:c5)
+    expect(enum[0x43]).to eq(:c6)
+    expect(enum[0x44]).to eq(:c7)
+    expect(enum[0x45]).to eq(:c8)
+
+    enum = TestEnum4.enum_type(:enum_type2)
+    expect(enum[0x42]).to eq(:c9)
+    expect(enum[0x43]).to eq(:c10)
+    expect(enum[0x4242]).to eq(:c11)
+    expect(enum[0x4243]).to eq(:c12)
+
+    enum = TestEnum4.enum_type(:enum_type3)
+    expect(enum[0x42]).to eq(:c13)
+    expect(enum[0x4242]).to eq(:c14)
+    expect(enum[0x42424242]).to eq(:c15)
+    expect(enum[0x4242424242424242]).to eq(:c16)
+
+    enum = TestEnum4.enum_type(:enum_type4)
+    expect(enum[0x42]).to eq(:c17)
+    expect(enum[0x43]).to eq(:c18)
+    expect(enum[0x44]).to eq(:c19)
+    expect(enum[0x45]).to eq(:c20)
+
+    enum = TestEnum4.enum_type(:enum_type5)
+    expect(enum[0x42]).to eq(:c21)
+    expect(enum[0x43]).to eq(:c22)
+    expect(enum[0x4242]).to eq(:c23)
+    expect(enum[0x4243]).to eq(:c24)
+
+    enum = TestEnum4.enum_type(:enum_type6)
+    expect(enum[0x42]).to eq(:c25)
+    expect(enum[0x4242]).to eq(:c26)
+    expect(enum[0x42424242]).to eq(:c27)
+    expect(enum[0x4242424242424242]).to eq(:c28)
+  end
+
+  it "return nil for values that don't have a symbol" do
+    enum = TestEnum3.enum_type(:enum_type1)
+    expect(enum[-1]).to be_nil
+    expect(enum[4]).to be_nil
+
+    enum = TestEnum3.enum_type(:enum_type2)
+    expect(enum[0]).to be_nil
+    expect(enum[41]).to be_nil
+    expect(enum[46]).to be_nil
+
+    enum = TestEnum3.enum_type(:enum_type3)
+    expect(enum[0]).to be_nil
+    expect(enum[41]).to be_nil
+    expect(enum[44]).to be_nil
+    expect(enum[4241]).to be_nil
+    expect(enum[4244]).to be_nil
+
+    enum = TestEnum3.enum_type(:enum_type4)
+    expect(enum[0]).to be_nil
+    expect(enum[41]).to be_nil
+    expect(enum[43]).to be_nil
+    expect(enum[4241]).to be_nil
+    expect(enum[4243]).to be_nil
+    expect(enum[424241]).to be_nil
+    expect(enum[424243]).to be_nil
+    expect(enum[42424241]).to be_nil
+    expect(enum[42424243]).to be_nil
+
+    enum = TestEnum4.enum_type(:enum_type1)
+    expect(enum[0x0]).to be_nil
+    expect(enum[0x41]).to be_nil
+    expect(enum[0x46]).to be_nil
+
+    enum = TestEnum4.enum_type(:enum_type2)
+    expect(enum[0x0]).to be_nil
+    expect(enum[0x41]).to be_nil
+    expect(enum[0x44]).to be_nil
+    expect(enum[0x4241]).to be_nil
+    expect(enum[0x4244]).to be_nil
+
+    enum = TestEnum4.enum_type(:enum_type3)
+    expect(enum[0x0]).to be_nil
+    expect(enum[0x41]).to be_nil
+    expect(enum[0x43]).to be_nil
+    expect(enum[0x4241]).to be_nil
+    expect(enum[0x4243]).to be_nil
+    expect(enum[0x42424241]).to be_nil
+    expect(enum[0x42424243]).to be_nil
+    expect(enum[0x4242424242424241]).to be_nil
+    expect(enum[0x4242424242424243]).to be_nil
+
+    enum = TestEnum4.enum_type(:enum_type4)
+    expect(enum[0x0]).to be_nil
+    expect(enum[0x41]).to be_nil
+    expect(enum[0x46]).to be_nil
+
+    enum = TestEnum4.enum_type(:enum_type5)
+    expect(enum[0x0]).to be_nil
+    expect(enum[0x41]).to be_nil
+    expect(enum[0x44]).to be_nil
+    expect(enum[0x4241]).to be_nil
+    expect(enum[0x4244]).to be_nil
+
+    enum = TestEnum4.enum_type(:enum_type6)
+    expect(enum[0x0]).to be_nil
+    expect(enum[0x41]).to be_nil
+    expect(enum[0x43]).to be_nil
+    expect(enum[0x4241]).to be_nil
+    expect(enum[0x4243]).to be_nil
+    expect(enum[0x42424241]).to be_nil
+    expect(enum[0x42424243]).to be_nil
+    expect(enum[0x4242424242424241]).to be_nil
+    expect(enum[0x4242424242424243]).to be_nil
+  end
+
+  it "duplicate enum keys rejected" do
+    expect { enum [ :a, 0xfee1dead, :b, 0xdeadbeef, :a, 0 ] }.to raise_error
+    expect { enum FFI::Type::UINT64, [ :a, 0xfee1dead, :b, 0xdeadbeef, :a, 0 ] }.to raise_error
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/errno_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/errno_spec.rb
new file mode 100755
index 0000000..61cbda2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/errno_spec.rb
@@ -0,0 +1,20 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "FFI.errno" do
+  module LibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    attach_function :setLastError, [ :int ], :void
+  end
+
+  it "FFI.errno contains errno from last function" do
+    LibTest.setLastError(0)
+    LibTest.setLastError(0x12345678)
+    expect(FFI.errno).to eq(0x12345678)
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/ffi_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/ffi_spec.rb
new file mode 100755
index 0000000..bb93f37
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/ffi_spec.rb
@@ -0,0 +1,28 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "FFI" do
+
+  describe ".map_library_name" do
+
+    let(:prefix) { FFI::Platform::LIBPREFIX }
+    let(:suffix) { FFI::Platform::LIBSUFFIX }
+
+    it "should add platform library extension if not present" do
+      expect(FFI.map_library_name("#{prefix}dummy")).to eq("#{prefix}dummy.#{suffix}")
+    end
+
+    it "should add platform library extension even if lib suffix is present in name" do
+      expect(FFI.map_library_name("#{prefix}dummy_with_#{suffix}")).to eq("#{prefix}dummy_with_#{suffix}.#{suffix}")
+    end
+
+    it "should return Platform::LIBC when called with 'c'" do
+      expect(FFI.map_library_name('c')).to eq(FFI::Library::LIBC)
+    end
+
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/.gitignore b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/.gitignore
new file mode 100755
index 0000000..dfd9b3f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/.gitignore
@@ -0,0 +1,10 @@
+# signature of implementation that
+# last compiled an extension
+*.sig
+
+# build artifacts
+*.o
+*.so
+*.bundle
+*.dylib
+*.dll
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/Benchmark.c b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/Benchmark.c
new file mode 100755
index 0000000..55a7380
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/Benchmark.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+#include <sys/types.h>
+#include <stdint.h>
+
+void returnVoid() {
+    
+}
+
+void returnVoidI(int arg) {
+    
+}
+int returnInt() {
+    return 0;
+}
+
+int returnIntI(int arg) {
+    return arg;
+}
+
+typedef int8_t s8;
+typedef uint8_t u8;
+typedef int16_t s16;
+typedef uint16_t u16;
+typedef int32_t s32;
+typedef uint32_t u32;
+typedef int64_t s64;
+typedef uint64_t u64;
+typedef float f32;
+typedef double f64;
+typedef void v;
+typedef char* S;
+typedef void* P;
+
+#define B6(R, T1, T2, T3, T4, T5, T6) R bench_##T1##T2##T3##T4##T5##T6##_##R(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) {}
+#define B5(R, T1, T2, T3, T4, T5) R bench_##T1##T2##T3##T4##T5##_##R(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {}
+#define B4(R, T1, T2, T3, T4) R bench_##T1##T2##T3##T4##_##R(T1 a1, T2 a2, T3 a3, T4 a4) {}
+#define B3(R, T1, T2, T3) R bench_##T1##T2##T3##_##R(T1 a1, T2 a2, T3 a3) {}
+#define B2(R, T1, T2) R bench_##T1##T2##_##R(T1 a1, T2 a2) {}
+#define B1(R, T1) R bench_##T1##_##R(T1 a1) {}
+#define BrV(T) B1(v, T); B2(v, T, T); B3(v, T, T, T); B4(v, T, T, T, T); B5(v, T, T, T, T, T); B6(v, T, T, T, T, T, T);
+BrV(u32);
+BrV(s32);
+BrV(s64);
+BrV(u64);
+BrV(f32);
+BrV(f64);
+BrV(S);
+BrV(P);
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/BoolTest.c b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/BoolTest.c
new file mode 100755
index 0000000..04cb6c6
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/BoolTest.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner.
+ * Copyright (c) 2009 Aman Gupta.
+ *
+ * All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <stdbool.h>
+
+bool
+bool_return_true()
+{
+    return true;
+}
+
+bool
+bool_return_false()
+{
+    return false;
+}
+
+bool
+bool_return_val(bool value)
+{
+    return value;
+}
+
+bool
+bool_reverse_val(bool value)
+{
+    return value ? false : true;
+}
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/BufferTest.c b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/BufferTest.c
new file mode 100755
index 0000000..3e95ebc
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/BufferTest.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+
+#define MEMSET(buf, value, size) do { \
+    int i; for (i = 0; i < size; ++i) buf[i] = value; \
+} while(0)
+#define MEMCPY(dst, src, size) do { \
+    int i; for (i = 0; i < size; ++i) dst[i] = src[i]; \
+} while(0)
+
+#define FILL(JTYPE, CTYPE) \
+void fill##JTYPE##Buffer(CTYPE* buf, CTYPE value, int size) { MEMSET(buf, value, size); }
+
+#define COPY(JTYPE, CTYPE) \
+void copy##JTYPE##Buffer(CTYPE* dst, CTYPE* src, int size) { MEMCPY(dst, src, size); }
+
+#define FUNC(JTYPE, CTYPE) \
+    FILL(JTYPE, CTYPE); \
+    COPY(JTYPE, CTYPE)
+            
+FUNC(Byte, char);
+FUNC(Short, short);
+FUNC(Int, int);
+FUNC(Long, long long);
+FUNC(Float, float);
+FUNC(Double, double);
+
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/ClosureTest.c b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/ClosureTest.c
new file mode 100755
index 0000000..64ea2b4
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/ClosureTest.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#ifndef _WIN32
+# include <pthread.h>
+#else
+# include <windows.h>
+# include <process.h>
+#endif
+
+#define R(T, rtype) rtype testClosureVr##T(rtype (*closure)(void)) { \
+    return closure != NULL ? (*closure)() : (rtype) 0; \
+}
+
+#define P(T, ptype) void testClosure##T##rV(void (*closure)(ptype), ptype a1) { \
+    if (closure != NULL) (*closure)(a1); \
+}
+
+void testClosureVrV(void (*closure)(void))
+{
+    (*closure)();
+}
+
+R(Z, bool);
+R(B, char);
+R(S, short);
+R(I, int);
+R(L, long);
+R(J, long long);
+R(LL, long long);
+R(F, float);
+R(D, double);
+R(P, const void*);
+
+
+P(Z, bool);
+P(B, char);
+P(S, short);
+P(I, int);
+P(L, long);
+P(J, long long);
+P(LL, long long);
+P(F, float);
+P(D, double);
+P(P, const void*);
+P(UL, unsigned long);
+
+void testOptionalClosureBrV(void (*closure)(char), char a1)
+{
+    if (closure) {
+        (*closure)(a1);
+    }
+}
+
+
+struct ThreadVrV {
+    void (*closure)(void);
+    int count;
+};
+
+static void *
+threadVrV(void *arg)
+{
+    struct ThreadVrV* t = (struct ThreadVrV *) arg;
+    
+    int i;
+    for (i = 0; i < t->count; i++) {
+        (*t->closure)();
+    }
+    
+    return NULL;
+}
+
+void testThreadedClosureVrV(void (*closure)(void), int n)
+{
+	struct ThreadVrV arg = {closure, n};
+#ifndef _WIN32
+    pthread_t t;
+    pthread_create(&t, NULL, threadVrV, &arg);
+    pthread_join(t, NULL);
+#else
+    HANDLE hThread = (HANDLE) _beginthread((void (*)(void *))threadVrV, 0, &arg);
+    WaitForSingleObject(hThread, INFINITE);	
+#endif
+}
+
+struct s8f32s32 {
+    char s8;
+    float f32;
+    int s32;
+};
+
+// Takes a struct argument
+void testClosureTrV(void (*closure)(struct s8f32s32 s), struct s8f32s32* s)
+{
+    (*closure)(*s);
+}
+
+// Returns a struct value
+struct s8f32s32 testClosureVrT(struct s8f32s32 (*closure)())
+{
+    return (*closure)();
+}
+
+typedef int (*returnTypeClosure_t)(int) ;
+typedef returnTypeClosure_t (*lookupClosure_t)();
+
+int testReturnsClosure(lookupClosure_t lookup, int val)
+{
+    returnTypeClosure_t func = lookup ? (*lookup)() : NULL;
+    return func ? (*func)(val) : 0;
+}
+
+static int multiplyByTwo(int value)
+{
+    return value * 2;
+}
+
+returnTypeClosure_t testReturnsFunctionPointer()
+{
+    return multiplyByTwo;
+}
+
+typedef int (*argumentClosure_t)(int);
+typedef int (*withArgumentClosure_t)(argumentClosure_t, int);
+
+int testArgumentClosure(withArgumentClosure_t closure_with, argumentClosure_t closure_arg, int val)
+{
+    return (*closure_with)(closure_arg, val);
+}
+
+
+//
+// These macros produce functions of the form:
+// testClosureBIrV(void (*closure)(char, int), char a1, int a2) {}
+//
+#define C2_(J1, J2, N1, N2) \
+void testClosure##J1##J2##rV(void (*closure)(N1, N2), N1 a1, N2 a2) \
+{ \
+    if (closure != NULL) (*closure)(a1, a2); \
+}
+
+#define C2(J, N) \
+    C2_(B, J, char, N) \
+    C2_(S, J, short, N) \
+    C2_(I, J, int, N) \
+    C2_(LL, J, long long, N) \
+    C2_(F, J, float, N) \
+    C2_(D, J, double, N) \
+
+
+C2(B, char);
+C2(S, short);
+C2(I, int);
+C2(LL, long long);
+C2(F, float);
+C2(D, double);
+
+#define C3_(J1, J2, J3, N1, N2, N3) \
+void testClosure##J1##J2##J3##rV(void (*closure)(N1, N2, N3), N1 a1, N2 a2, N3 a3) \
+{ \
+    (*closure)(a1, a2, a3); \
+}
+
+
+#define C3(J, N) \
+    C3_(B, J, B, char, N, char) \
+    C3_(S, J, S, short, N, short) \
+    C3_(I, J, I, int, N, int) \
+    C3_(LL, J, LL, long long, N, long long) \
+    C3_(F, J, F, float, N, float) \
+    C3_(D, J, D, double, N, double) \
+
+C3(B, char);
+C3(S, short);
+C3(I, int);
+C3(LL, long long);
+C3(F, float);
+C3(D, double);
+C3_(B, S, I, char, short, int);
+C3_(B, S, LL, char, short, long long);
+C3_(LL, S, B, long long, short, char);
+C3_(LL, B, S, long long, char, short);
+
+
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/EnumTest.c b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/EnumTest.c
new file mode 100755
index 0000000..4bf8d23
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/EnumTest.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+#include <stdint.h>
+
+int test_untagged_enum(int val) {
+    return val;
+}
+
+int test_untagged_typedef_enum(int val) {
+    return val;
+}
+
+uint8_t test_untagged_nonint_enum(uint8_t val) {
+    return val;
+}
+
+uint16_t test_tagged_nonint_enum1(uint16_t val) {
+    return val;
+}
+
+uint32_t test_tagged_nonint_enum2(uint32_t val) {
+    return val;
+}
+
+uint64_t test_tagged_nonint_enum3(uint64_t val) {
+    return val;
+}
+
+typedef enum {c1, c2, c3, c4} enum_type1;
+enum_type1 test_tagged_typedef_enum1(enum_type1 val) {
+    return val;
+}
+
+typedef enum {c5 = 42, c6, c7, c8} enum_type2;
+enum_type2 test_tagged_typedef_enum2(enum_type2 val) {
+    return val;
+}
+
+typedef enum {c9 = 42, c10, c11 = 4242, c12} enum_type3;
+enum_type3 test_tagged_typedef_enum3(enum_type3 val) {
+    return val;
+}
+
+typedef enum {c13 = 42, c14 = 4242, c15 = 424242, c16 = 42424242} enum_type4;
+enum_type4 test_tagged_typedef_enum4(enum_type4 val) {
+    return val;
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/FunctionTest.c b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/FunctionTest.c
new file mode 100755
index 0000000..b4d45bb
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/FunctionTest.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#ifdef _WIN32
+#include <windows.h>
+#define sleep(x) Sleep(x)
+#endif
+
+#ifndef _WIN32
+#include <unistd.h>
+#include <pthread.h>
+#endif
+
+int testAdd(int a, int b)
+{
+    return a + b;
+};
+
+int testFunctionAdd(int a, int b, int (*f)(int, int))
+{
+    return f(a, b);
+};
+
+void testBlocking(int seconds) {
+    sleep(seconds);
+};
+
+struct async_data {
+    void (*fn)(int);
+    int value;
+};
+
+static void* asyncThreadCall(void *data)
+{
+    struct async_data* d = (struct async_data *) data;
+    if (d != NULL && d->fn != NULL) {
+        (*d->fn)(d->value);
+    }
+
+    return NULL;
+}
+
+void testAsyncCallback(void (*fn)(int), int value)
+{
+#ifndef _WIN32
+    pthread_t t;
+    struct async_data d;
+    d.fn = fn;
+    d.value = value;
+    pthread_create(&t, NULL, asyncThreadCall, &d);
+    pthread_join(t, NULL);
+#else
+    (*fn)(value);
+#endif
+} 
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/GNUmakefile b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/GNUmakefile
new file mode 100755
index 0000000..d730419
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/GNUmakefile
@@ -0,0 +1,149 @@
+# -*- makefile -*-
+
+ifeq ($(OS),)
+  BUILD_OS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
+  OS := $(BUILD_OS)
+endif
+
+ifeq ($(CPU),)
+  CPU := $(shell uname -m | sed -e 's/i[345678]86/i386/')
+endif
+
+PLATFORM = $(CPU)-$(OS)
+
+ifeq ($(OS), sunos)
+  OS = solaris
+endif
+
+SRC_DIR = .
+BUILD_DIR ?= .
+TEST_BUILD_DIR = .
+# Set defaults to unix (linux/solaris/bsd)
+PREFIX = lib
+LIBEXT ?= so
+LIBNAME = $(PREFIX)test.$(LIBEXT)
+
+export MACOSX_DEPLOYMENT_TARGET=10.4
+
+CCACHE := $(strip $(realpath $(shell which ccache 2> /dev/null)))
+
+TEST_SRCS = $(wildcard $(SRC_DIR)/*.c)
+TEST_OBJS := $(patsubst $(SRC_DIR)/%.c, $(TEST_BUILD_DIR)/%.o, $(TEST_SRCS))
+
+#
+# Compiler/linker flags from:
+#   http://weblogs.java.net/blog/kellyohair/archive/2006/01/compilation_of_1.html
+JFLAGS = -fno-omit-frame-pointer -fno-strict-aliasing
+OFLAGS = -O2 $(JFLAGS)
+WFLAGS = -W -Wall -Wno-unused -Wno-parentheses
+PICFLAGS = -fPIC
+SOFLAGS = -shared
+LDFLAGS += $(SOFLAGS)
+
+IFLAGS = -I"$(BUILD_DIR)"
+CFLAGS = $(OFLAGS) $(WFLAGS) $(IFLAGS) $(PICFLAGS) -D_REENTRANT
+
+ifneq ($(strip $(findstring $(OS), win32, mingw, cygwin)),)
+  # For cygwin => win32-native builds, strip out cygwin deps
+  ifneq ($(findstring cygwin, $(BUILD_OS)),)
+    CC += -mno-cygwin -mwin32
+    LDFLAGS += -mno-cygwin -Wl,--add-stdcall-alias
+  endif
+  PICFLAGS=
+  LIBEXT=dll
+  CC = gcc
+endif
+
+ifeq ($(OS), darwin)
+  ifneq ($(findstring $(CPU),ppc),)
+    ARCHFLAGS += -arch ppc
+  endif
+  ifneq ($(findstring $(CPU),i386 x86_64),)
+    ARCHFLAGS += -arch i386 -arch x86_64
+  endif
+  CFLAGS += $(ARCHFLAGS) -DTARGET_RT_MAC_CFM=0
+  CFLAGS += -fno-common
+  LDFLAGS = $(ARCHFLAGS) -dynamiclib
+  # link against the universal libraries on ppc machines
+  LDFLAGS += -L$(MACSDK)/usr/lib
+  LIBEXT = dylib
+  FFI_CFLAGS += -isysroot $(MACSDK)
+  PICFLAGS =
+  SOFLAGS =
+endif
+
+ifeq ($(OS), linux)
+  SOFLAGS += -Wl,-soname,$(LIBNAME)
+endif
+
+ifeq ($(OS), solaris)
+  CC = /usr/sfw/bin/gcc -std=c99
+  LD = /usr/ccs/bin/ld
+  SOFLAGS = -shared -static-libgcc
+endif
+
+ifeq ($(OS), aix)
+  LIBEXT = a
+  SOFLAGS = -shared -static-libgcc
+  PICFLAGS += -pthread
+endif
+
+ifneq ($(findstring bsd, $(OS)),)
+  SOFLAGS = -shared -static-libgcc
+  CFLAGS += -pthread
+  LDFLAGS += -pthread
+endif
+
+ifeq ($(CPU), i386)
+  MODEL = 32
+endif
+
+ifeq ($(CPU), sparcv9)
+  MODEL = 64
+endif
+
+ifeq ($(CPU), amd64)
+  MODEL = 64
+endif
+
+ifeq ($(CPU), x86_64)
+  MODEL = 64
+endif
+
+ifeq ($(CPU), ppc64)
+  MODEL = 64
+endif
+
+ifeq ($(CPU), powerpc64)
+  MODEL = 64
+endif
+
+MODELFLAG =
+ifneq ($(MODEL),)
+  MODELFLAG = -m$(MODEL)
+endif
+
+# On platforms (linux, solaris) that support both 32bit and 64bit, force building for one or the other
+ifneq ($(or $(findstring linux, $(OS)), $(findstring solaris, $(OS))),)
+  # Change the CC/LD instead of CFLAGS/LDFLAGS, incase other things in the flags
+  # makes the libffi build choke
+  CC += $(MODELFLAG)
+  LD += $(MODELFLAG)
+endif
+
+LIBTEST = $(LIBNAME)
+
+all:	$(LIBTEST)
+
+$(TEST_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
+	@mkdir -p $(@D)
+	$(CCACHE) $(CC) $(CFLAGS) -c $< -o $@
+
+$(LIBTEST):  $(TEST_OBJS)
+	$(CC) -o $@ $(LDFLAGS) $(TEST_OBJS) -lm
+
+clean::
+	# nothing to do - ant will delete the build dir
+
+debug::
+	@echo "SRCS=$(TEST_SRCS)"
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/GlobalVariable.c b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/GlobalVariable.c
new file mode 100755
index 0000000..39c12a2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/GlobalVariable.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <sys/types.h>
+#include <stdint.h>
+
+typedef int8_t s8;
+typedef uint8_t u8;
+typedef int16_t s16;
+typedef uint16_t u16;
+typedef int32_t s32;
+typedef uint32_t u32;
+typedef int64_t s64;
+typedef uint64_t u64;
+typedef signed long sL;
+typedef unsigned long uL;
+typedef float f32;
+typedef double f64;
+#if !defined(__OpenBSD__)
+typedef unsigned long ulong;
+#endif
+typedef void* pointer;
+typedef void* P;
+
+#define GVAR(T) \
+    extern T gvar_##T; \
+    T gvar_##T = (T) -1; \
+    T gvar_##T##_get() { return gvar_##T; }; \
+    void gvar_##T##_set(T v) { gvar_##T = v; }
+
+GVAR(s8);
+GVAR(u8);
+GVAR(s16);
+GVAR(u16);
+GVAR(s32);
+GVAR(u32);
+GVAR(s64);
+GVAR(u64);
+GVAR(long);
+GVAR(ulong);
+GVAR(pointer);
+
+struct gstruct {
+    long data;
+};
+
+struct gstruct gvar_gstruct = { -1 };
+
+struct gstruct*
+gvar_gstruct_get(void)
+{
+    return &gvar_gstruct;
+}
+
+void
+gvar_gstruct_set(const struct gstruct* val)
+{ 
+    gvar_gstruct = *val;
+}
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/LastErrorTest.c b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/LastErrorTest.c
new file mode 100755
index 0000000..02ce4a8
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/LastErrorTest.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#if defined(_WIN32) || defined(__WIN32__)
+# include <windows.h>
+#else
+# include <errno.h>
+#endif
+
+int setLastError(int error) {
+#if defined(_WIN32) || defined(__WIN32__)
+    SetLastError(error);
+#else
+    errno = error;
+#endif
+    return -1;
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/NumberTest.c b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/NumberTest.c
new file mode 100755
index 0000000..3fa25a8
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/NumberTest.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#if defined(__sparc) && defined(__sun__)
+    #define fix_mem_access __asm("ta 6")
+#else
+    #define fix_mem_access
+#endif
+
+typedef int8_t s8;
+typedef uint8_t u8;
+typedef int16_t s16;
+typedef uint16_t u16;
+typedef int32_t s32;
+typedef uint32_t u32;
+typedef int64_t s64;
+typedef uint64_t u64;
+typedef signed long sL;
+typedef unsigned long uL;
+typedef float f32;
+typedef double f64;
+typedef long double f128;
+#if !defined(__OpenBSD__)
+typedef unsigned long ulong;
+#endif
+
+#define ADD(T) T add_##T(T arg1, T arg2) { return arg1 + arg2; }
+#define SUB(T) T sub_##T(T arg1, T arg2) { return arg1 - arg2; }
+#define MUL(T) T mul_##T(T arg1, T arg2) { return arg1 * arg2; }
+#define DIV(T) T div_##T(T arg1, T arg2) { return arg1 / arg2; }
+#define RET(T) T ret_##T(T arg1) { return arg1; }
+#define SET(T) static T T##_;void set_##T(T arg1) { T##_ = arg1; }
+#define GET(T) T get_##T() { return T##_; }
+typedef char* ptr;
+#define TEST(T) ADD(T) SUB(T) MUL(T) DIV(T) RET(T) SET(T) GET(T)
+TEST(s8);
+TEST(u8);
+TEST(s16);
+TEST(u16);
+TEST(s32);
+TEST(u32);
+TEST(s64);
+TEST(u64);
+TEST(float);
+TEST(double);
+TEST(long);
+TEST(ulong);
+TEST(f128);
+
+#define ADD2(R, T1, T2) R add_##T1##T2##_##R(T1 arg1, T2 arg2) { return arg1 + arg2; }
+#define SUB2(R, T1, T2) R sub_##T1##T2##_##R(T1 arg1, T2 arg2) { return arg1 - arg2; }
+#define MUL2(R, T1, T2) R mul_##T1##T2##_##R(T1 arg1, T2 arg2) { return arg1 * arg2; }
+#define DIV2(R, T1, T2) R div_##T1##T2##_##R(T1 arg1, T2 arg2) { return arg1 / arg2; }
+
+#define T2__(R, T1, T2) ADD2(R, T1, T2) SUB2(R, T1, T2) MUL2(R, T1, T2) DIV2(R, T1, T2)
+#define T2_(R, T1) \
+    T2__(R, T1, s8) T2__(R, T1, u8) \
+    T2__(R, T1, s16) T2__(R, T1, u16) \
+    T2__(R, T1, s32) T2__(R, T1, u32) \
+    T2__(R, T1, sL) T2__(R, T1, uL) \
+    T2__(R, T1, s64) T2__(R, T1, u64) \
+
+#define TEST2(R) \
+    T2_(R, s8) T2_(R, u8) T2_(R, s16) T2_(R, u16) T2_(R, s32) T2_(R, u32) \
+    T2_(R, sL) T2_(R, uL) T2_(R, s64) T2_(R, u64)
+
+#ifdef notyet
+TEST2(s32)
+TEST2(u32)
+TEST2(s64)
+TEST2(u64)
+#endif
+
+#define ADD3(R, T1, T2, T3) R add_##T1##T2##T3##_##R(T1 arg1, T2 arg2, T3 arg3) { return arg1 + arg2 + arg3; }
+#define pack_f32(buf, v) do { float f = v; memcpy((buf), &f, sizeof(f)); } while(0)
+#define pack_f64(buf, v) do { double f = v; memcpy((buf), &f, sizeof(f)); } while(0)
+#define pack_int(buf, v) do { *(buf) = v; } while(0)
+#define pack_s8 pack_int
+#define pack_u8 pack_int
+#define pack_s16 pack_int
+#define pack_u16 pack_int
+#define pack_s32 pack_int
+#define pack_u32 pack_int
+#define pack_s64 pack_int
+#define pack_u64 pack_int
+#define pack_sL pack_int
+#define pack_uL pack_int
+
+#define PACK3(R, T1, T2, T3) void pack_##T1##T2##T3##_##R(T1 arg1, T2 arg2, T3 arg3, R* r) { \
+    fix_mem_access; \
+    pack_##T1(&r[0], arg1); \
+    pack_##T2(&r[1], arg2); \
+    pack_##T3(&r[2], arg3); \
+}
+
+#define T3___(R, T1, T2, T3) PACK3(R, T1, T2, T3) /* SUB2(R, T1, T2) MUL2(R, T1, T2) DIV2(R, T1, T2) */
+#define T3__(R, T1, T2) \
+    T3___(R, T1, T2, s8) T3___(R, T1, T2, u8) \
+    T3___(R, T1, T2, s16) T3___(R, T1, T2, u16) \
+    T3___(R, T1, T2, s32) T3___(R, T1, T2, u32) \
+    T3___(R, T1, T2, sL) T3___(R, T1, T2, uL) \
+    T3___(R, T1, T2, s64) T3___(R, T1, T2, u64) \
+    T3___(R, T1, T2, f32) T3___(R, T1, T2, f64) \
+
+#define T3_(R, T1) \
+    T3__(R, T1, s8) T3__(R, T1, u8) \
+    T3__(R, T1, s16) T3__(R, T1, u16) \
+    T3__(R, T1, s32) T3__(R, T1, u32) \
+    T3__(R, T1, sL) T3__(R, T1, uL) \
+    T3__(R, T1, s64) T3__(R, T1, u64) \
+    T3__(R, T1, f32) T3__(R, T1, f64) \
+
+#define TEST3(R) \
+    T3_(R, s8) T3_(R, u8) T3_(R, s16) T3_(R, u16) T3_(R, s32) T3_(R, u32) \
+    T3_(R, sL) T3_(R, uL) T3_(R, s64) T3_(R, u64) T3_(R, f32) T3_(R, f64)
+
+TEST3(s64)
+
+void 
+foo6(intptr_t i1, intptr_t i2, intptr_t i3, intptr_t i4, intptr_t i5, intptr_t i6) { }
+
+void 
+foo5(intptr_t i1, intptr_t i2, intptr_t i3, intptr_t i4, intptr_t i5) { }
+
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/PointerTest.c b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/PointerTest.c
new file mode 100755
index 0000000..7237ab2
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/PointerTest.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+typedef void* ptr;
+typedef void* pointer;
+#ifdef _WIN32
+typedef char* caddr_t;
+#endif
+
+#define RET(T) T ptr_ret_##T(void* arg1, int offset) { \
+    T tmp; memcpy(&tmp, (caddr_t) arg1 + offset, sizeof(tmp)); return tmp; \
+}
+#define SET(T) void ptr_set_##T(void* arg1, int offset, T value) { \
+    memcpy((caddr_t) arg1 + offset, &value, sizeof(value)); \
+}
+#define TEST(T) SET(T) RET(T)
+
+TEST(int8_t);
+TEST(int16_t);
+TEST(int32_t);
+TEST(int64_t);
+TEST(float);
+TEST(double);
+TEST(pointer);
+
+void*
+ptr_return_array_element(void **ptrArray, int arrayIndex) 
+{
+    return ptrArray[arrayIndex];
+}
+
+void
+ptr_set_array_element(void **ptrArray, int arrayIndex, void *value)
+{    
+    ptrArray[arrayIndex] = value;
+}
+
+void*
+ptr_malloc(int size) 
+{
+    return calloc(1, size);
+}
+void
+ptr_free(void* ptr)
+{
+    free(ptr);
+}
+
+void*
+ptr_from_address(uintptr_t addr)
+{
+    return (void *) addr;
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/ReferenceTest.c b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/ReferenceTest.c
new file mode 100755
index 0000000..d1dd88b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/ReferenceTest.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <stdint.h>
+
+#define REF(T) void ref_##T(T arg, T* result) { *result = arg; }
+#define ADD(T) void ref_add_##T(T arg1, T arg2, T* result) { *result = arg1 + arg2; }
+#define SUB(T) void ref_sub_##T(T arg1, T arg2, T* result) { *result = arg1 - arg2; }
+#define MUL(T) void ref_mul_##T(T arg1, T arg2, T* result) { *result = arg1 * arg2; }
+#define DIV(T) void ref_div_##T(T arg1, T arg2, T* result) { *result = arg1 / arg2; }
+#define TEST(T) ADD(T) SUB(T) MUL(T) DIV(T) REF(T)
+
+TEST(int8_t);
+TEST(int16_t);
+TEST(int32_t);
+TEST(int64_t);
+TEST(float);
+TEST(double);
+
+
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/StringTest.c b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/StringTest.c
new file mode 100755
index 0000000..292242b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/StringTest.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <string.h>
+
+int 
+string_equals(const char* s1, const char* s2)
+{
+    return strcmp(s1, s2) == 0;
+}
+
+void 
+string_set(char* s1, const char* s2)
+{
+    strcpy(s1, s2);
+}
+void
+string_concat(char* dst, const char* src)
+{
+    strcat(dst, src);
+}
+void
+string_dummy(char* dummy)
+{
+}
+const char*
+string_null(void)
+{
+    return NULL;
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/StructTest.c b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/StructTest.c
new file mode 100755
index 0000000..25683d3
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/StructTest.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner.
+ * Copyright (c) 2009 Andrea Fazzi <andrea.fazzi at alcacoop.it>.
+ *
+ * All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdarg.h>
+
+typedef char s8;
+typedef short s16;
+typedef int s32;
+typedef long long s64;
+typedef float f32;
+typedef double f64;
+
+typedef struct bugged_struct {
+  unsigned char visible;
+  unsigned int x;
+  unsigned int y;
+  short rx;
+  short ry;
+  unsigned char order;
+  unsigned char size;
+} bugged_struct_t;
+
+unsigned int
+bugged_struct_size() {
+    return sizeof(bugged_struct_t);
+}
+
+struct test1 {
+    char b;
+    short s;
+    int i;
+    long long j;
+    long l;
+    float f;
+    double d;
+    char string[32];
+};
+
+struct struct_with_array {
+    char c;
+    int a[5];
+};
+
+struct nested {
+    int i;
+};
+
+struct container {
+    char first;
+    struct nested s;
+};
+
+int
+struct_align_nested_struct(struct container* a) { return a->s.i; }
+
+void*
+struct_field_array(struct struct_with_array* s) { return &s->a; }
+
+struct container*
+struct_make_container_struct(int i)
+{
+    static struct container cs;
+    memset(&cs, 0, sizeof(cs));
+    cs.first = 1;
+    cs.s.i = i;
+    return &cs;
+}
+
+#define T(x, type) \
+    type struct_field_##type(struct test1* t) { return t->x; } \
+    struct type##_align { char first; type value; }; \
+    type struct_align_##type(struct type##_align* a) { return a->value; }
+
+T(b, s8);
+T(s, s16);
+T(i, s32);
+T(j, s64);
+T(f, f32);
+T(d, f64);
+T(l, long);
+
+void
+struct_set_string(struct test1* t, char* s)
+{
+    strcpy(t->string, s);
+}
+
+struct test1*
+struct_make_struct(char b, short s, int i, long long ll, float f, double d)
+{
+    static struct test1 t;
+    memset(&t, 0, sizeof(t));
+    t.b = b;
+    t.s = s;
+    t.i = i;
+    t.j = ll;
+    t.f = f;
+    t.d = d;
+    return &t;
+}
+
+typedef int (*add_cb)(int a1, int a2);
+typedef int (*sub_cb)(int a1, int a2);
+struct test2 {
+    add_cb  add_callback;
+    sub_cb  sub_callback;
+};
+
+int
+struct_call_add_cb(struct test2* t, int a1, int a2)
+{
+    return t->add_callback(a1, a2);
+}
+
+int
+struct_call_sub_cb(struct test2* t, int a1, int a2)
+{
+    return t->sub_callback(a1, a2);
+}
+
+
+struct struct_with_array*
+struct_make_struct_with_array(int a_0, int a_1, int a_2, int a_3, int a_4)
+{
+    static struct struct_with_array s;
+
+    memset(&s, 0, sizeof(s));
+
+    s.a[0] = a_0;
+    s.a[1] = a_1;
+    s.a[2] = a_2;
+    s.a[3] = a_3;
+    s.a[4] = a_4;
+
+    return &s;
+
+}
+
+struct s8s32 {
+    char s8;
+    int s32;
+};
+
+struct s8s32
+struct_return_s8s32()
+{
+    struct s8s32 s;
+    s.s8 = 0x7f;
+    s.s32 = 0x12345678;
+
+    return s;
+}
+
+struct s8s32
+struct_s8s32_set(char s8, int s32)
+{
+    struct s8s32 s;
+
+    s.s8 = s8;
+    s.s32 = s32;
+
+    return s;
+}
+
+int
+struct_s8s32_get_s8(struct s8s32 s)
+{
+    return s.s8;
+}
+
+int
+struct_s8s32_get_s32(struct s8s32 s)
+{
+    return s.s32;
+}
+
+struct s8s32
+struct_s8s32_ret_s8s32(struct s8s32 s)
+{
+    return s;
+}
+
+// Pass a struct and an int arg, ensure the int arg is passed correctly
+int
+struct_s8s32_s32_ret_s32(struct s8s32 s, int s32)
+{
+    return s32;
+}
+
+// Pass a struct and a long long arg, ensure the long long arg is passed correctly
+long long
+struct_s8s32_s64_ret_s64(struct s8s32 s, long long s64)
+{
+    return s64;
+}
+
+// Pass a struct and a long long arg, ensure the long long arg is passed correctly
+int
+struct_s32_ptr_s32_s8s32_ret_s32(int s32a, void *ptr, int s32b, struct s8s32 s)
+{
+    if (ptr != NULL) *(struct s8s32 *) ptr = s;
+    return s.s32;
+}
+
+// Pass a char *, copy into buffer length struct
+struct struct_string {
+    char *bytes;
+    int len;
+};
+
+struct struct_string
+struct_varargs_ret_struct_string(int len, ...)
+{
+    struct struct_string ss;
+    va_list vl;
+    char* cp = NULL;
+
+    va_start(vl, len);
+
+    ss.len = len;
+    ss.bytes = va_arg(vl, char *);
+    if (ss.bytes != NULL) {
+        cp = malloc(strlen(ss.bytes) + 1);
+        strcpy(cp, ss.bytes);
+        ss.bytes = cp;
+    }
+
+    va_end(vl);
+
+    return ss;
+}
+
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/UnionTest.c b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/UnionTest.c
new file mode 100755
index 0000000..0929a31
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/UnionTest.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+typedef char s8;
+typedef short s16;
+typedef int s32;
+typedef long long s64;
+typedef float f32;
+typedef double f64;
+
+typedef union union_test {
+    char b;
+    short s;
+    int i;
+    long long j;
+    long l;
+    float f;
+    double d;
+    s8 a[10];
+} union_test_t;
+
+#define T(x, type) \
+  type union_align_##type(union_test_t* u) { return u->x; } \
+  union_test_t* union_make_union_with_##type(type value) { static union_test_t u; u.x = value; return &u; }
+
+T(b, s8);
+T(s, s16);
+T(i, s32);
+T(j, s64);
+T(f, f32);
+T(d, f64);
+T(l, long);
+
+unsigned int union_size() { return sizeof(union_test_t); }
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/VariadicTest.c b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/VariadicTest.c
new file mode 100755
index 0000000..2f3d801
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/VariadicTest.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2007 Wayne Meissner. All rights reserved.
+ *
+ * For licensing, see LICENSE.SPECS
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdarg.h>
+
+typedef int8_t s8;
+typedef uint8_t u8;
+typedef int16_t s16;
+typedef uint16_t u16;
+typedef int32_t s32;
+typedef uint32_t u32;
+typedef int64_t s64;
+typedef uint64_t u64;
+typedef signed long sL;
+typedef unsigned long uL;
+typedef float F;
+typedef double D;
+
+void pack_varargs(s64* buf, const char* fmt, ...)
+{
+    va_list ap;
+    int c;
+    double d;
+    va_start(ap, fmt);
+    while ((c = *fmt++)) {
+        switch (c) {
+            case 'c':
+            case 's':
+            case 'i':
+                *buf++ = va_arg(ap, s32);
+                break;
+            case 'l':
+                *buf++ = va_arg(ap, long);
+                break;
+            case 'j':
+                *buf++ = va_arg(ap, s64);
+                break;
+            case 'f':
+            case 'd':
+                d = va_arg(ap, double);
+                memcpy(buf++, &d, sizeof(d));
+                break;
+            case 'C':
+            case 'S':
+            case 'I':
+                *buf++ = va_arg(ap, u32);
+                break;
+            case 'L':
+                *buf++ = va_arg(ap, unsigned long);
+                break;
+        }
+    }
+    va_end(ap);
+}
+
+int pack_varargs2(s64* buf, int retval, const char* fmt, ...)
+{
+    va_list ap;
+    int c;
+    double d;
+    va_start(ap, fmt);
+    while ((c = *fmt++)) {
+        switch (c) {
+            case 'c':
+            case 's':
+            case 'i':
+                *buf++ = va_arg(ap, s32);
+                break;
+            case 'l':
+                *buf++ = va_arg(ap, long);
+                break;
+            case 'j':
+                *buf++ = va_arg(ap, s64);
+                break;
+            case 'f':
+            case 'd':
+                d = va_arg(ap, double);
+                memcpy(buf++, &d, sizeof(d));
+                break;
+            case 'C':
+            case 'S':
+            case 'I':
+                *buf++ = va_arg(ap, u32);
+                break;
+            case 'L':
+                *buf++ = va_arg(ap, unsigned long);
+                break;
+        }
+    }
+    va_end(ap);
+    return retval + 1;
+}
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/classes.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/classes.rb
new file mode 100755
index 0000000..581768c
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/fixtures/classes.rb
@@ -0,0 +1,438 @@
+module FFISpecs
+  #
+  # Callback fixtures
+  #
+  module LibTest
+    callback :cbVrS8, [ ], :char
+    callback :cbVrU8, [ ], :uchar
+    callback :cbVrS16, [ ], :short
+    callback :cbVrU16, [ ], :ushort
+    callback :cbVrS32, [ ], :int
+    callback :cbVrU32, [ ], :uint
+    callback :cbVrL, [ ], :long
+    callback :cbVrUL, [ ], :ulong
+    callback :cbVrS64, [ ], :long_long
+    callback :cbVrU64, [ ], :ulong_long
+    callback :cbVrP, [], :pointer
+    callback :cbCrV, [ :char ], :void
+    callback :cbSrV, [ :short ], :void
+    callback :cbIrV, [ :int ], :void
+    callback :cbLrV, [ :long ], :void
+    callback :cbULrV, [ :ulong ], :void
+    callback :cbLrV, [ :long_long ], :void
+
+    attach_function :testCallbackVrS8, :testClosureVrB, [ :cbVrS8 ], :char
+    attach_function :testCallbackVrU8, :testClosureVrB, [ :cbVrU8 ], :uchar
+    attach_function :testCallbackVrS16, :testClosureVrS, [ :cbVrS16 ], :short
+    attach_function :testCallbackVrU16, :testClosureVrS, [ :cbVrU16 ], :ushort
+    attach_function :testCallbackVrS32, :testClosureVrI, [ :cbVrS32 ], :int
+    attach_function :testCallbackVrU32, :testClosureVrI, [ :cbVrU32 ], :uint
+    attach_function :testCallbackVrL, :testClosureVrL, [ :cbVrL ], :long
+    attach_function :testCallbackVrUL, :testClosureVrL, [ :cbVrUL ], :ulong
+    attach_function :testCallbackVrS64, :testClosureVrLL, [ :cbVrS64 ], :long_long
+    attach_function :testCallbackVrU64, :testClosureVrLL, [ :cbVrU64 ], :ulong_long
+    attach_function :testCallbackVrP, :testClosureVrP, [ :cbVrP ], :pointer
+    attach_function :testCallbackCrV, :testClosureBrV, [ :cbCrV, :char ], :void
+    attach_variable :cbVrS8, :gvar_pointer, :cbVrS8
+    attach_variable :pVrS8, :gvar_pointer, :pointer
+    attach_function :testGVarCallbackVrS8, :testClosureVrB, [ :pointer ], :char
+    attach_function :testOptionalCallbackCrV, :testOptionalClosureBrV, [ :cbCrV, :char ], :void
+
+    attach_function :testCallbackVrS8, :testClosureVrB, [ callback([ ], :char) ], :char
+
+    callback :cb_return_type, [ :int ], :int
+    callback :cb_lookup, [ ], :cb_return_type
+    attach_function :testReturnsCallback, :testReturnsClosure, [ :cb_lookup, :int ], :int
+
+    callback :funcptr, [ :int ], :int
+    attach_function :testReturnsFunctionPointer, [  ], :funcptr
+
+    callback :cbS8rV, [ :char ], :void
+    callback :cbU8rV, [ :uchar ], :void
+    callback :cbS16rV, [ :short ], :void
+    callback :cbU16rV, [ :ushort ], :void
+
+    callback :cbS32rV, [ :int ], :void
+    callback :cbU32rV, [ :uint ], :void
+
+    callback :cbLrV, [ :long ], :void
+    callback :cbULrV, [ :ulong ], :void
+
+    callback :cbS64rV, [ :long_long ], :void
+    attach_function :testCallbackCrV, :testClosureBrV, [ :cbS8rV, :char ], :void
+    attach_function :testCallbackU8rV, :testClosureBrV, [ :cbU8rV, :uchar ], :void
+    attach_function :testCallbackSrV, :testClosureSrV, [ :cbS16rV, :short ], :void
+    attach_function :testCallbackU16rV, :testClosureSrV, [ :cbU16rV, :ushort ], :void
+    attach_function :testCallbackIrV, :testClosureIrV, [ :cbS32rV, :int ], :void
+    attach_function :testCallbackU32rV, :testClosureIrV, [ :cbU32rV, :uint ], :void
+
+    attach_function :testCallbackLrV, :testClosureLrV, [ :cbLrV, :long ], :void
+    attach_function :testCallbackULrV, :testClosureULrV, [ :cbULrV, :ulong ], :void
+
+    attach_function :testCallbackLLrV, :testClosureLLrV, [ :cbS64rV, :long_long ], :void
+  end
+
+  #
+  # Enum fixtures
+  #
+  module TestEnum0
+    extend FFI::Library
+  end
+
+  module TestEnum1
+    extend FFI::Library
+    ffi_lib LIBRARY
+
+    enum [:c1, :c2, :c3, :c4]
+    enum [:c5, 42, :c6, :c7, :c8]
+    enum [:c9, 42, :c10, :c11, 4242, :c12]
+    enum [:c13, 42, :c14, 4242, :c15, 424242, :c16, 42424242]
+
+    attach_function :test_untagged_enum, [:int], :int
+  end
+
+  module TestEnum3
+    extend FFI::Library
+    ffi_lib LIBRARY
+
+    enum :enum_type1, [:c1, :c2, :c3, :c4]
+    enum :enum_type2, [:c5, 42, :c6, :c7, :c8]
+    enum :enum_type3, [:c9, 42, :c10, :c11, 4242, :c12]
+    enum :enum_type4, [:c13, 42, :c14, 4242, :c15, 424242, :c16, 42424242]
+
+    attach_function :test_tagged_typedef_enum1, [:enum_type1], :enum_type1
+    attach_function :test_tagged_typedef_enum2, [:enum_type2], :enum_type2
+    attach_function :test_tagged_typedef_enum3, [:enum_type3], :enum_type3
+    attach_function :test_tagged_typedef_enum4, [:enum_type4], :enum_type4
+  end
+
+  #
+  # Errno fixtures
+  #
+  module LibTest
+    attach_function :setLastError, [ :int ], :void
+  end
+
+  #
+  # ManagedStruct fixtures
+  #
+  module LibTest
+    attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], :pointer
+  end
+
+  class NoRelease < ManagedStruct
+    layout :i, :int
+  end
+
+  class WhatClassAmI < ManagedStruct
+    layout :i, :int
+    def self.release; end
+  end
+
+  class PleaseReleaseMe < ManagedStruct
+    layout :i, :int
+    @@count = 0
+    def self.release
+      @@count += 1
+    end
+    def self.wait_gc(count)
+      loop = 5
+      while loop > 0 && @@count < count
+        loop -= 1
+        if RUBY_PLATFORM =~ /java/
+          require 'java'
+          java.lang.System.gc
+        else
+          GC.start
+        end
+        sleep 0.05 if @@count < count
+      end
+    end
+  end
+
+  #
+  # Number fixtures
+  #
+  module LibTest
+    attach_function :ret_s8, [ :char ], :char
+    attach_function :ret_u8, [ :uchar ], :uchar
+    attach_function :ret_s16, [ :short ], :short
+    attach_function :ret_u16, [ :ushort ], :ushort
+    attach_function :ret_s32, [ :int ], :int
+    attach_function :ret_u32, [ :uint ], :uint
+    attach_function :ret_s64, [ :long_long ], :long_long
+    attach_function :ret_u64, [ :ulong_long ], :ulong_long
+    attach_function :ret_long, [ :long ], :long
+    attach_function :ret_ulong, [ :ulong ], :ulong
+    attach_function :set_s8, [ :char ], :void
+    attach_function :get_s8, [ ], :char
+    attach_function :set_float, [ :float ], :void
+    attach_function :get_float, [ ], :float
+    attach_function :set_double, [ :double ], :void
+    attach_function :get_double, [ ], :double
+  end
+
+  PACK_VALUES = {
+    's8' => [ 0x12  ],
+    'u8' => [ 0x34  ],
+    's16' => [ 0x5678 ],
+    'u16' => [ 0x9abc ],
+    's32' => [ 0x7654321f ],
+    'u32' => [ 0xfee1babe ],
+    'sL' => [ 0x1f2e3d4c ],
+    'uL' => [ 0xf7e8d9ca ],
+    's64' => [ 0x1eafdeadbeefa1b2 ],
+    #'f32' => [ 1.234567 ], # TODO: Why is this disabled?
+    'f64' => [ 9.87654321 ]
+  }
+
+  TYPE_MAP = {
+    's8' => :char, 'u8' => :uchar, 's16' => :short, 'u16' => :ushort,
+    's32' => :int, 'u32' => :uint, 's64' => :long_long, 'u64' => :ulong_long,
+    'sL' => :long, 'uL' => :ulong, 'f32' => :float, 'f64' => :double
+  }
+  TYPES = TYPE_MAP.keys
+
+  module LibTest
+    [ 's32', 'u32', 's64', 'u64' ].each do |rt|
+      TYPES.each do |t1|
+        TYPES.each do |t2|
+          TYPES.each do |t3|
+            begin
+              attach_function "pack_#{t1}#{t2}#{t3}_#{rt}",
+                [ TYPE_MAP[t1], TYPE_MAP[t2], TYPE_MAP[t3], :buffer_out ], :void
+            rescue FFI::NotFoundError
+            end
+          end
+        end
+      end
+    end
+  end
+
+  #
+  # Pointer fixtures
+  #
+  module LibTest
+    attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
+    attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], :pointer
+    attach_function :ptr_set_pointer, [ :pointer, :int, :pointer ], :void
+  end
+
+  class ToPtrTest
+    def initialize(ptr)
+      @ptr = ptr
+    end
+    def to_ptr
+      @ptr
+    end
+  end
+
+  require 'delegate'
+  class PointerDelegate < DelegateClass(FFI::Pointer)
+    def initialize(ptr)
+      super
+      @ptr = ptr
+    end
+    def to_ptr
+      @ptr
+    end
+  end
+
+  class AutoPointerTestHelper
+    @@count = 0
+    def self.release
+      @@count += 1 if @@count > 0
+    end
+    def self.reset
+      @@count = 0
+    end
+    def self.gc_everything(count)
+      loop = 5
+      while @@count < count && loop > 0
+        loop -= 1
+        if RUBY_PLATFORM =~ /java/
+          require "java"
+          java.lang.System.gc
+        else
+          GC.start
+        end
+        sleep 0.05 unless @@count == count
+      end
+      @@count = 0
+    end
+    def self.finalizer
+      self.method(:release).to_proc
+    end
+  end
+
+  #
+  # String fixtures
+  #
+  module LibTest
+    attach_function :ptr_ret_pointer, [ :pointer, :int], :string
+    attach_function :string_equals, [ :string, :string ], :int
+    attach_function :string_dummy, [ :string ], :void
+  end
+
+  #
+  # Struct initialize fixtures
+  #
+  class StructWithInitialize < FFI::Struct
+    layout :string, :string
+    attr_accessor :magic
+    def initialize
+      super
+      self.magic = 42
+    end
+  end
+
+  #
+  # Struct fixtures
+  #
+  StructTypes = {
+    's8' => :char,
+    's16' => :short,
+    's32' => :int,
+    's64' => :long_long,
+    'long' => :long,
+    'f32' => :float,
+    'f64' => :double
+  }
+
+  module LibTest
+    attach_function :ptr_ret_pointer, [ :pointer, :int], :string
+    attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
+    attach_function :ptr_from_address, [ :ulong ], :pointer
+    attach_function :string_equals, [ :string, :string ], :int
+    [ 's8', 's16', 's32', 's64', 'f32', 'f64', 'long' ].each do |t|
+      attach_function "struct_align_#{t}", [ :pointer ], StructTypes[t]
+    end
+  end
+
+  class PointerMember < FFI::Struct
+    layout :pointer, :pointer
+  end
+
+  class StringMember < FFI::Struct
+    layout :string, :string
+  end
+
+  module CallbackMember
+    extend FFI::Library
+    ffi_lib LIBRARY
+    callback :add, [ :int, :int ], :int
+    callback :sub, [ :int, :int ], :int
+
+    class TestStruct < FFI::Struct
+      layout :add, :add,
+        :sub, :sub
+    end
+
+    attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
+    attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
+  end
+
+  module LibTest
+    class NestedStruct < FFI::Struct
+      layout :i, :int
+    end
+
+    class ContainerStruct < FFI::Struct
+      layout :first, :char, :ns, NestedStruct
+    end
+
+    attach_function :struct_align_nested_struct, [ :pointer ], :int
+    attach_function :struct_make_container_struct, [ :int ], :pointer
+
+    class StructWithArray < FFI::Struct
+      layout :first, :char, :a, [:int, 5]
+    end
+
+    attach_function :struct_make_struct_with_array, [:int, :int, :int, :int, :int], :pointer
+    attach_function :struct_field_array, [:pointer], :pointer
+
+    class BuggedStruct < FFI::Struct
+      layout :visible, :uchar,
+              :x, :uint,
+              :y, :uint,
+              :rx, :short,
+              :ry, :short,
+              :order, :uchar,
+              :size, :uchar
+    end
+
+    attach_function :bugged_struct_size, [], :uint
+  end
+
+  module StructCustomTypedef
+    extend FFI::Library
+    ffi_lib LIBRARY
+    typedef :uint, :fubar3_t
+
+    class S < FFI::Struct
+      layout :a, :fubar3_t
+    end
+  end
+
+  #
+  # Union fixtures
+  #
+  module LibTest
+    Types = {
+      's8' => [:char, :c, 1],
+      's16' => [:short, :s, 0xff0],
+      's32' => [:int, :i, 0xff00],
+      's64' => [:long_long, :j, 0xffff00],
+      'long' => [:long, :l, 0xffff],
+      'f32' => [:float, :f, 1.0001],
+      'f64' => [:double, :d, 1.000000001]
+    }
+
+    class TestUnion < FFI::Union
+      layout( :a, [:char, 10],
+              :i, :int,
+              :f, :float,
+              :d, :double,
+              :s, :short,
+              :l, :long,
+              :j, :long_long,
+              :c, :char )
+    end
+
+    Types.keys.each do |k|
+      attach_function "union_align_#{k}", [ :pointer ], Types[k][0]
+      attach_function "union_make_union_with_#{k}", [ Types[k][0] ], :pointer
+    end
+
+    attach_function :union_size, [], :uint
+  end
+
+  #
+  # Variadic fixtures
+  #
+  module LibTest
+    attach_function :pack_varargs, [ :buffer_out, :string, :varargs ], :void
+  end
+
+  module Varargs
+    PACK_VALUES = {
+      'c' => [ 0x12  ],
+      'C' => [ 0x34  ],
+      's' => [ 0x5678 ],
+      'S' => [ 0x9abc ],
+      'i' => [ 0x7654321f ],
+      'I' => [ 0xfee1babe ],
+      'l' => [ 0x1f2e3d4c ],
+      'L' => [ 0xf7e8d9ca ],
+      'j' => [ 0x1eafdeadbeefa1b2 ],
+      'f' => [ 1.23456789 ],
+      'd' => [ 9.87654321 ]
+    }
+
+    TYPE_MAP = {
+      'c' => :char, 'C' => :uchar, 's' => :short, 'S' => :ushort,
+      'i' => :int, 'I' => :uint, 'j' => :long_long, 'J' => :ulong_long,
+      'l' => :long, 'L' => :ulong, 'f' => :float, 'd' => :double
+    }
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/function_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/function_spec.rb
new file mode 100755
index 0000000..ab08f35
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/function_spec.rb
@@ -0,0 +1,92 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe FFI::Function do
+  module LibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    attach_function :testFunctionAdd, [:int, :int, :pointer], :int
+  end
+  before do
+    @libtest = FFI::DynamicLibrary.open(TestLibrary::PATH, 
+                                        FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL)
+  end
+
+  it 'is initialized with a signature and a block' do
+    fn = FFI::Function.new(:int, []) { 5 }
+    expect(fn.call).to eql 5
+  end
+
+  it 'raises an error when passing a wrong signature' do
+    expect { FFI::Function.new([], :int).new { } }.to raise_error TypeError 
+  end
+
+  it 'returns a native pointer' do
+    expect(FFI::Function.new(:int, []) { }).to be_a_kind_of FFI::Pointer
+  end
+
+  it 'can be used as callback from C passing to it a block' do
+    function_add = FFI::Function.new(:int, [:int, :int]) { |a, b| a + b }
+    expect(LibTest.testFunctionAdd(10, 10, function_add)).to eq(20)
+  end
+
+  it 'can be used as callback from C passing to it a Proc object' do
+    function_add = FFI::Function.new(:int, [:int, :int], Proc.new { |a, b| a + b })
+    expect(LibTest.testFunctionAdd(10, 10, function_add)).to eq(20)
+  end
+
+  it 'can be used to wrap an existing function pointer' do
+    expect(FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd')).call(10, 10)).to eq(20)
+  end
+
+  it 'can be attached to a module' do
+    module Foo; end
+    fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
+    fp.attach(Foo, 'add')
+    expect(Foo.add(10, 10)).to eq(20)
+  end
+
+  it 'can be used to extend an object' do
+    fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
+    foo = Object.new
+    class << foo
+      def singleton_class
+        class << self; self; end
+      end
+    end
+    fp.attach(foo.singleton_class, 'add')
+    expect(foo.add(10, 10)).to eq(20)
+  end
+
+  it 'can wrap a blocking function' do
+    fp = FFI::Function.new(:void, [ :int ], @libtest.find_function('testBlocking'), :blocking => true)
+    threads = 10.times.map do |x|
+      Thread.new do
+        time = Time.now
+        fp.call(2)
+        expect(Time.now - time).to be >= 2
+      end
+    end
+    threads.each { |t| t.join }
+  end
+
+  it 'autorelease flag is set to true by default' do
+    fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
+    expect(fp.autorelease?).to be true
+  end
+
+  it 'can explicity free itself' do
+    fp = FFI::Function.new(:int, []) { }
+    fp.free
+    expect { fp.free }.to raise_error RuntimeError
+  end
+
+  it 'can\'t explicity free itself if not previously allocated' do
+    fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
+    expect { fp.free }.to raise_error RuntimeError
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/io_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/io_spec.rb
new file mode 100755
index 0000000..22c238a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/io_spec.rb
@@ -0,0 +1,16 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+if false # disabled for #390
+  describe "FFI::IO.for_fd" do
+    it "produces an IO wrapping the specified file descriptor" do
+      expect do
+        FFI::IO.for_fd(2, "r")
+      end.to_not raise_error
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/library_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/library_spec.rb
new file mode 100755
index 0000000..4359b93
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/library_spec.rb
@@ -0,0 +1,276 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "Library" do
+  describe ".enum_value" do
+    m = Module.new do
+      extend FFI::Library
+      enum :something, [:one, :two]
+    end
+
+    it "should return a value for a valid key" do
+      expect(m.enum_value(:one)).to eq(0)
+      expect(m.enum_value(:two)).to eq(1)
+    end
+
+    it "should return nil for an invalid key" do
+      expect(m.enum_value(:three)).to be nil
+    end
+  end
+
+  describe "#ffi_convention" do
+    it "defaults to :default" do
+      m = Module.new do
+        extend FFI::Library
+      end
+      expect(m.ffi_convention).to eq(:default)
+    end
+
+    it "should be settable" do
+      m = Module.new do
+        extend FFI::Library
+      end
+
+      expect(m.ffi_convention).to eq(:default)
+      m.ffi_convention :stdcall
+      expect(m.ffi_convention).to eq(:stdcall)
+    end
+  end
+
+  if FFI::Platform::OS =~ /windows|cygwin/ && FFI::Platform::ARCH == 'i386'
+    module LibTestStdcall
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      ffi_convention :stdcall
+
+      class StructUCDP < FFI::Struct
+        layout :a1, :uchar,
+          :a2, :double,
+          :a3, :pointer
+      end
+
+      attach_function :testStdcallManyParams, [ :pointer, :int8, :int16, :int32, :int64,
+              StructUCDP.by_value, StructUCDP.by_ref, :float, :double ], :void
+    end
+
+    it "adds stdcall decoration: testStdcallManyParams at 64" do
+      s = LibTestStdcall::StructUCDP.new
+      po = FFI::MemoryPointer.new :long
+      LibTestStdcall.testStdcallManyParams po, 1, 2, 3, 4, s, s, 1.0, 2.0
+    end
+  end
+
+  describe "ffi_lib" do
+    it "empty name list should raise error" do
+      expect {
+        Module.new do |m|
+          m.extend FFI::Library
+          ffi_lib
+        end
+      }.to raise_error(LoadError)
+    end
+    
+  end
+
+  unless RbConfig::CONFIG['target_os'] =~ /mswin|mingw/
+    it "attach_function with no library specified" do
+      expect {
+        Module.new do |m|
+          m.extend FFI::Library
+          attach_function :getpid, [ ], :uint
+        end
+      }.to raise_error
+    end
+
+    it "attach_function :getpid from this process" do
+      expect {
+        expect(Module.new do |m|
+          m.extend FFI::Library
+          ffi_lib FFI::Library::CURRENT_PROCESS
+          attach_function :getpid, [ ], :uint
+        end.getpid).to eq(Process.pid)
+      }.not_to raise_error
+    end
+
+    it "attach_function :getpid from [ 'c', 'libc.so.6'] " do
+      expect {
+        expect(Module.new do |m|
+          m.extend FFI::Library
+          ffi_lib [ 'c', 'libc.so.6' ]
+          attach_function :getpid, [ ], :uint
+        end.getpid).to eq(Process.pid)
+      }.not_to raise_error
+    end
+
+    it "attach_function :getpid from [ 'libc.so.6', 'c' ] " do
+      expect {
+        expect(Module.new do |m|
+          m.extend FFI::Library
+          ffi_lib [ 'libc.so.6', 'c' ]
+          attach_function :getpid, [ ], :uint
+        end.getpid).to eq(Process.pid)
+      }.not_to raise_error
+    end
+
+    it "attach_function :getpid from [ 'libfubar.so.0xdeadbeef', nil, 'c' ] " do
+      expect {
+        expect(Module.new do |m|
+          m.extend FFI::Library
+          ffi_lib [ 'libfubar.so.0xdeadbeef', nil, 'c' ]
+          attach_function :getpid, [ ], :uint
+        end.getpid).to eq(Process.pid)
+      }.not_to raise_error
+    end
+
+    it "attach_function :getpid from [ 'libfubar.so.0xdeadbeef' ] " do
+      expect {
+        expect(Module.new do |m|
+          m.extend FFI::Library
+          ffi_lib 'libfubar.so.0xdeadbeef'
+          attach_function :getpid, [ ], :uint
+        end.getpid).to eq(Process.pid)
+      }.to raise_error(LoadError)
+    end
+
+    it "attach_function :bool_return_true from [ File.expand_path(#{TestLibrary::PATH.inspect}) ]" do
+      mod = Module.new do |m|
+        m.extend FFI::Library
+        ffi_lib File.expand_path(TestLibrary::PATH)
+        attach_function :bool_return_true, [ ], :bool
+      end
+      expect(mod.bool_return_true).to be true
+    end
+  end
+
+  def gvar_lib(name, type)
+    Module.new do |m|
+      m.extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      attach_variable :gvar, "gvar_#{name}", type
+      attach_function :get, "gvar_#{name}_get", [], type
+      attach_function :set, "gvar_#{name}_set", [ type ], :void
+    end
+  end
+
+  def gvar_test(name, type, val)
+    lib = gvar_lib(name, type)
+    lib.set(val)
+    expect(lib.gvar).to eq(val)
+    lib.set(0)
+    lib.gvar = val
+    expect(lib.get).to eq(val)
+  end
+
+  [ 0, 127, -128, -1 ].each do |i|
+    it ":char variable" do
+      gvar_test("s8", :char, i)
+    end
+  end
+
+  [ 0, 0x7f, 0x80, 0xff ].each do |i|
+    it ":uchar variable" do
+      gvar_test("u8", :uchar, i)
+    end
+  end
+
+  [ 0, 0x7fff, -0x8000, -1 ].each do |i|
+    it ":short variable" do
+      gvar_test("s16", :short, i)
+    end
+  end
+
+  [ 0, 0x7fff, 0x8000, 0xffff ].each do |i|
+    it ":ushort variable" do
+      gvar_test("u16", :ushort, i)
+    end
+  end
+
+  [ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
+    it ":int variable" do
+      gvar_test("s32", :int, i)
+    end
+  end
+
+  [ 0, 0x7fffffff, 0x80000000, 0xffffffff ].each do |i|
+    it ":uint variable" do
+      gvar_test("u32", :uint, i)
+    end
+  end
+
+  [ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ].each do |i|
+    it ":long_long variable" do
+      gvar_test("s64", :long_long, i)
+    end
+  end
+
+  [ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ].each do |i|
+    it ":ulong_long variable" do
+      gvar_test("u64", :ulong_long, i)
+    end
+  end
+
+  if FFI::Platform::LONG_SIZE == 32
+    [ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
+      it ":long variable" do
+        gvar_test("long", :long, i)
+      end
+    end
+
+    [ 0, 0x7fffffff, 0x80000000, 0xffffffff ].each do |i|
+      it ":ulong variable" do
+        gvar_test("ulong", :ulong, i)
+      end
+    end
+  else
+    [ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ].each do |i|
+      it ":long variable" do
+        gvar_test("long", :long, i)
+      end
+    end
+
+    [ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ].each do |i|
+      it ":ulong variable" do
+        gvar_test("ulong", :ulong, i)
+      end
+    end
+  end
+
+  it "Pointer variable" do
+    lib = gvar_lib("pointer", :pointer)
+    val = FFI::MemoryPointer.new :long
+    lib.set(val)
+    expect(lib.gvar).to eq(val)
+    lib.set(nil)
+    lib.gvar = val
+    expect(lib.get).to eq(val)
+  end
+
+  [ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
+    it "structure" do
+      class GlobalStruct < FFI::Struct
+        layout :data, :long
+      end
+
+      lib = Module.new do |m|
+        m.extend FFI::Library
+        ffi_lib TestLibrary::PATH
+        attach_variable :gvar, "gvar_gstruct", GlobalStruct
+        attach_function :get, "gvar_gstruct_get", [], GlobalStruct
+        attach_function :set, "gvar_gstruct_set", [ GlobalStruct ], :void
+      end
+
+      val = GlobalStruct.new
+      val[:data] = i
+      lib.set(val)
+      expect(lib.gvar[:data]).to eq(i)
+      val[:data] = 0
+      lib.gvar[:data] = i
+      val = GlobalStruct.new(lib.get)
+      expect(val[:data]).to eq(i)
+    end
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/long_double.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/long_double.rb
new file mode 100755
index 0000000..b16613b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/long_double.rb
@@ -0,0 +1,30 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+require 'bigdecimal'
+
+describe ":long_double arguments and return values" do
+  module LibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    attach_function :add_f128, [ :long_double, :long_double ], :long_double
+    attach_function :ret_f128, [ :long_double ], :long_double
+  end
+
+  it "returns first parameter" do
+    expect(LibTest.ret_f128(0.1)).to be_within(0.01).of(0.1)
+  end
+
+  it "returns first parameter with high precision" do
+    ld =        BigDecimal.new("1.234567890123456789")
+    tolerance = BigDecimal.new("0.0000000000000000001")
+    expect(LibTest.ret_f128(ld)).to be_within(tolerance).of(ld)
+  end
+
+  it "add two long double numbers" do
+    expect(LibTest.add_f128(0.1, 0.2)).to be_within(0.01).of(0.3)
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/managed_struct_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/managed_struct_spec.rb
new file mode 100755
index 0000000..f11c67a
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/managed_struct_spec.rb
@@ -0,0 +1,68 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "Managed Struct" do
+  include FFI
+  module ManagedStructTestLib
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], :pointer
+  end
+
+  it "should raise an error if release() is not defined" do
+    class NoRelease < FFI::ManagedStruct ; layout :i, :int; end
+    expect { NoRelease.new(ManagedStructTestLib.ptr_from_address(0x12345678)) }.to raise_error(NoMethodError)
+  end
+
+  it "should be the right class" do
+    class WhatClassAmI < FFI::ManagedStruct
+      layout :i, :int
+      def self.release
+      end
+    end    
+
+    expect(WhatClassAmI.new(ManagedStructTestLib.ptr_from_address(0x12345678)).class).to eq(WhatClassAmI)
+  end
+
+  it "should build with self reference" do
+    class ClassWithSelfRef < FFI::ManagedStruct
+      layout :data, self.ptr
+      def self.release
+      end
+    end
+
+    expect(ClassWithSelfRef.new(ManagedStructTestLib.ptr_from_address(0x12345678)).class).to eq(ClassWithSelfRef)
+  end
+
+  # see #427
+  it "should release memory properly", :broken => true do
+    class PleaseReleaseMe < FFI::ManagedStruct
+      layout :i, :int
+      @@count = 0
+      def self.release
+        @@count += 1
+      end
+      def self.wait_gc(count)
+        loop = 5
+        while loop > 0 && @@count < count
+          loop -= 1
+          TestLibrary.force_gc
+          sleep 0.05 if @@count < count
+        end
+      end
+    end
+
+    loop_count = 30
+    wiggle_room = 5
+
+    expect(PleaseReleaseMe).to receive(:release).at_least(loop_count-wiggle_room).times
+    loop_count.times do
+      PleaseReleaseMe.new(ManagedStructTestLib.ptr_from_address(0x12345678))
+    end
+    PleaseReleaseMe.wait_gc loop_count
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/memorypointer_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/memorypointer_spec.rb
new file mode 100755
index 0000000..d819f35
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/memorypointer_spec.rb
@@ -0,0 +1,78 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+MemoryPointer = FFI::MemoryPointer
+
+describe "MemoryPointer#total" do
+  it "MemoryPointer.new(:char, 1).total == 1" do
+    expect(MemoryPointer.new(:char, 1).total).to eq 1
+  end
+
+  it "MemoryPointer.new(:short, 1).total == 2" do
+    expect(MemoryPointer.new(:short, 1).total).to eq 2
+  end
+
+  it "MemoryPointer.new(:int, 1).total == 4" do
+    expect(MemoryPointer.new(:int, 1).total).to eq 4
+  end
+
+  it "MemoryPointer.new(:long_long, 1).total == 8" do
+    expect(MemoryPointer.new(:long_long, 1).total).to eq 8
+  end
+
+  it "MemoryPointer.new(1024).total == 1024" do
+    expect(MemoryPointer.new(1024).total).to eq 1024
+  end
+end
+describe "MemoryPointer#read_array_of_long" do
+  it "foo" do
+    ptr = MemoryPointer.new(:long, 1024)
+    ptr[0].write_long 1234
+    ptr[1].write_long 5678
+    l = ptr.read_array_of_long(2)
+    expect(l[0]).to eq 1234
+    expect(l[1]).to eq 5678
+  end
+end
+describe "MemoryPointer argument" do
+  module Ptr
+    extend FFI::Library
+    ffi_lib FFI::Platform::LIBC
+    attach_function :memset, [ :pointer, :int, :ulong ], :pointer
+    attach_function :memcpy, [ :pointer, :pointer, :ulong ], :pointer
+  end
+
+  it "Pointer passed correctly" do
+    p = MemoryPointer.new :int, 1
+    ret = Ptr.memset(p, 0, p.total)
+    expect(ret).to eq p
+  end
+
+  it "Data passed to native function" do
+    p = MemoryPointer.new :int, 1
+    p2 = MemoryPointer.new :int, 1
+    p2.put_int(0, 0x5eadbeef)
+    Ptr.memcpy(p, p2, p.total)
+    expect(p.get_int(0)).to eq p2.get_int(0)
+    expect(p2.get_int(0)).not_to eql 0
+  end
+end
+describe "MemoryPointer return value" do
+  module Stdio
+    extend FFI::Library
+    ffi_lib FFI::Platform::LIBC
+    attach_function :fopen, [ :string, :string ], :pointer
+    attach_function :fclose, [ :pointer ], :int
+    attach_function :fwrite, [ :pointer, :ulong, :ulong, :string ], :ulong
+  end
+
+  it "fopen returns non-nil" do
+    fp = Stdio.fopen("/dev/null", "w")
+    expect(fp).to_not be_nil
+    expect(Stdio.fclose(fp)).to  eq 0 unless fp.nil? or fp.null? 
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/number_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/number_spec.rb
new file mode 100755
index 0000000..acb9562
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/number_spec.rb
@@ -0,0 +1,247 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "Function with primitive integer arguments" do
+  module LibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    attach_function :ret_s8, [ :char ], :char
+    attach_function :ret_u8, [ :uchar ], :uchar
+    attach_function :ret_s16, [ :short ], :short
+    attach_function :ret_u16, [ :ushort ], :ushort
+    attach_function :ret_s32, [ :int ], :int
+    attach_function :ret_u32, [ :uint ], :uint
+    attach_function :ret_s64, [ :long_long ], :long_long
+    attach_function :ret_u64, [ :ulong_long ], :ulong_long
+    attach_function :ret_long, [ :long ], :long
+    attach_function :ret_ulong, [ :ulong ], :ulong
+    attach_function :set_s8, [ :char ], :void
+    attach_function :get_s8, [ ], :char
+    attach_function :set_float, [ :float ], :void
+    attach_function :get_float, [ ], :float
+    attach_function :set_double, [ :double ], :void
+    attach_function :get_double, [ ], :double
+  end
+
+  it "int8.size" do
+    expect(FFI::TYPE_INT8.size).to eq(1)
+  end
+
+  it "uint8.size" do
+    expect(FFI::TYPE_UINT8.size).to eq(1)
+  end
+
+  it "int16.size" do
+    expect(FFI::TYPE_INT16.size).to eq(2)
+  end
+
+  it "uint16.size" do
+    expect(FFI::TYPE_UINT16.size).to eq(2)
+  end
+
+  it "int32.size" do
+    expect(FFI::TYPE_INT32.size).to eq(4)
+  end
+
+  it "uint32.size" do
+    expect(FFI::TYPE_UINT32.size).to eq(4)
+  end
+
+  it "int64.size" do
+    expect(FFI::TYPE_INT64.size).to eq(8)
+  end
+
+  it "uint64.size" do
+    expect(FFI::TYPE_UINT64.size).to eq(8)
+  end
+
+  it "float.size" do
+    expect(FFI::TYPE_FLOAT32.size).to eq(4)
+  end
+
+  it "double.size" do
+    expect(FFI::TYPE_FLOAT64.size).to eq(8)
+  end
+  [ 0, 127, -128, -1 ].each do |i|
+    it ":char call(:char (#{i}))" do
+      expect(LibTest.ret_s8(i)).to eq(i)
+    end
+  end
+  [ 0, 0x7f, 0x80, 0xff ].each do |i|
+    it ":uchar call(:uchar (#{i}))" do
+      expect(LibTest.ret_u8(i)).to eq(i)
+    end
+  end
+  [ 0, 0x7fff, -0x8000, -1 ].each do |i|
+    it ":short call(:short (#{i}))" do
+      expect(LibTest.ret_s16(i)).to eq(i)
+    end
+  end
+  [ 0, 0x7fff, 0x8000, 0xffff ].each do |i|
+    it ":ushort call(:ushort (#{i}))" do
+      expect(LibTest.ret_u16(i)).to eq(i)
+    end
+  end
+  [ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
+    it ":int call(:int (#{i}))" do
+      expect(LibTest.ret_s32(i)).to eq(i)
+    end
+  end
+  [ 0, 0x7fffffff, 0x80000000, 0xffffffff ].each do |i|
+    it ":uint call(:uint (#{i}))" do
+      expect(LibTest.ret_u32(i)).to eq(i)
+    end
+  end
+  [ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ].each do |i|
+    it ":long_long call(:long_long (#{i}))" do
+      expect(LibTest.ret_s64(i)).to eq(i)
+    end
+  end
+  [ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ].each do |i|
+    it ":ulong_long call(:ulong_long (#{i}))" do
+      expect(LibTest.ret_u64(i)).to eq(i)
+    end
+  end
+  if FFI::Platform::LONG_SIZE == 32
+    [ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
+      it ":long call(:long (#{i}))" do
+        expect(LibTest.ret_long(i)).to eq(i)
+      end
+    end
+    [ 0, 0x7fffffff, 0x80000000, 0xffffffff ].each do |i|
+      it ":ulong call(:ulong (#{i}))" do
+        expect(LibTest.ret_ulong(i)).to eq(i)
+      end
+    end
+  else
+    [ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ].each do |i|
+      it ":long call(:long (#{i}))" do
+        expect(LibTest.ret_long(i)).to eq(i)
+      end
+    end
+    [ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ].each do |i|
+      it ":ulong call(:ulong (#{i}))" do
+        expect(LibTest.ret_ulong(i)).to eq(i)
+      end
+    end
+    [ 0.0, 0.1, 1.1, 1.23 ].each do |f|
+      it ":float call(:double (#{f}))" do
+        LibTest.set_float(f)
+        expect((LibTest.get_float - f).abs).to be < 0.001
+      end
+    end
+    [ 0.0, 0.1, 1.1, 1.23 ].each do |f|
+      it ":double call(:double (#{f}))" do
+        LibTest.set_double(f)
+        expect((LibTest.get_double - f).abs).to be < 0.001
+      end
+    end
+  end
+end
+describe "Integer parameter range checking" do
+  [ 128, -129 ].each do |i|
+    it ":char call(:char (#{i}))" do
+      expect { expect(LibTest.ret_int8_t(i)).to eq(i) }.to raise_error
+    end
+  end
+  [ -1, 256 ].each do |i|
+    it ":uchar call(:uchar (#{i}))" do
+      expect { expect(LibTest.ret_u_int8_t(i)).to eq(i) }.to raise_error
+    end
+  end
+  [ 0x8000, -0x8001 ].each do |i|
+    it ":short call(:short (#{i}))" do
+      expect { expect(LibTest.ret_int16_t(i)).to eq(i) }.to raise_error
+    end
+  end
+  [ -1, 0x10000 ].each do |i|
+    it ":ushort call(:ushort (#{i}))" do
+      expect { expect(LibTest.ret_u_int16_t(i)).to eq(i) }.to raise_error
+    end
+  end
+  [ 0x80000000, -0x80000001 ].each do |i|
+    it ":int call(:int (#{i}))" do
+      expect { expect(LibTest.ret_int32_t(i)).to eq(i) }.to raise_error
+    end
+  end
+  [ -1, 0x100000000 ].each do |i|
+    it ":ushort call(:ushort (#{i}))" do
+      expect { expect(LibTest.ret_u_int32_t(i)).to eq(i) }.to raise_error
+    end
+  end
+end
+describe "Three different size Integer arguments" do
+  TYPE_MAP = {
+    's8' => :char, 'u8' => :uchar, 's16' => :short, 'u16' => :ushort,
+    's32' => :int, 'u32' => :uint, 's64' => :long_long, 'u64' => :ulong_long,
+    'sL' => :long, 'uL' => :ulong, 'f32' => :float, 'f64' => :double
+  }
+  TYPES = TYPE_MAP.keys
+  module LibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    
+    
+    [ 's32', 'u32', 's64', 'u64' ].each do |rt|
+      TYPES.each do |t1|
+        TYPES.each do |t2|
+          TYPES.each do |t3|
+            begin
+              attach_function "pack_#{t1}#{t2}#{t3}_#{rt}",
+                [ TYPE_MAP[t1], TYPE_MAP[t2], TYPE_MAP[t3], :buffer_out ], :void
+            rescue FFI::NotFoundError
+            end
+          end
+        end
+      end
+    end
+  end
+
+  PACK_VALUES = {
+    's8' => [ 0x12  ],
+    'u8' => [ 0x34  ],
+    's16' => [ 0x5678 ],
+    'u16' => [ 0x9abc ],
+    's32' => [ 0x7654321f ],
+    'u32' => [ 0xfee1babe ],
+    'sL' => [ 0x1f2e3d4c ],
+    'uL' => [ 0xf7e8d9ca ],
+    's64' => [ 0x1eafdeadbeefa1b2 ],
+#    'f32' => [ 1.234567 ],
+    'f64' => [ 9.87654321 ]
+  }
+
+  def verify(p, off, t, v)
+    if t == 'f32'
+      expect(p.get_float32(off)).to eq(v)
+    elsif t == 'f64'
+      expect(p.get_float64(off)).to eq(v)
+    else
+      expect(p.get_int64(off)).to eq(v)
+    end
+  end
+
+  PACK_VALUES.keys.each do |t1|
+    PACK_VALUES.keys.each do |t2|
+      PACK_VALUES.keys.each do |t3|
+        PACK_VALUES[t1].each do |v1|
+          PACK_VALUES[t2].each do |v2|
+            PACK_VALUES[t3].each do |v3|
+              it "call(#{TYPE_MAP[t1]} (#{v1}), #{TYPE_MAP[t2]} (#{v2}), #{TYPE_MAP[t3]} (#{v3}))" do
+                p = FFI::Buffer.new :long_long, 3
+                LibTest.send("pack_#{t1}#{t2}#{t3}_s64", v1, v2, v3, p)
+                verify(p, 0, t1, v1)
+                verify(p, 8, t2, v2)
+                verify(p, 16, t3, v3)
+              end
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/platform_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/platform_spec.rb
new file mode 100755
index 0000000..7c56719
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/platform_spec.rb
@@ -0,0 +1,114 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "FFI::Platform::LIBSUFFIX" do
+  case OS
+  when "linux"
+    it "returns 'so'" do
+      expect(FFI::Platform::LIBSUFFIX).to eq('so')
+    end
+  when "windows"
+    it "returns 'dll'" do
+      expect(FFI::Platform::LIBSUFFIX).to eq('dll')
+    end
+  when "darwin"
+    it "returns 'dylib'" do
+      expect(FFI::Platform::LIBSUFFIX).to eq('dylib')
+    end
+  end
+end
+
+describe "FFI::Platform::IS_WINDOWS" do
+  case OS
+  when "linux"
+    it "returns false" do
+      expect(FFI::Platform::IS_WINDOWS).to be false
+    end
+  when "windows"
+    it "returns true" do
+      expect(FFI::Platform::IS_WINDOWS).to be true
+    end
+  when "darwin"
+    it "returns false" do
+      expect(FFI::Platform::IS_WINDOWS).to be false
+    end
+  end
+end
+
+describe "FFI::Platform::ARCH" do
+  it "returns the architecture type" do
+    expect(FFI::Platform::ARCH).to eq(CPU)
+  end
+end
+
+describe "FFI::Platform::OS" do
+  case OS
+  when "linux"
+    it "returns 'linux' as a string" do
+      expect(FFI::Platform::OS).to eq('linux')
+    end
+  when "windows"
+    it "returns 'windows' as a string" do
+      expect(FFI::Platform::OS).to eq('windows')
+    end
+  when "darwin"
+    it "returns 'darwin' as a string" do
+      expect(FFI::Platform::OS).to eq('darwin')
+    end
+  end
+end
+
+describe "FFI::Platform.windows?" do
+  case OS
+  when "linux"
+    it "returns false" do
+      expect(FFI::Platform.windows?).to be false
+    end
+  when "windows"
+    it "returns true" do
+      expect(FFI::Platform.windows?).to be true
+    end
+  when "darwin"
+    it "returns false" do
+      expect(FFI::Platform.windows?).to be false
+    end
+  end
+end
+
+describe "FFI::Platform.mac?" do
+  case OS
+  when "linux"
+    it "returns false" do
+      expect(FFI::Platform.mac?).to be false
+    end
+  when "windows"
+    it "returns false" do
+      expect(FFI::Platform.mac?).to be false
+    end
+  when "darwin"
+    it "returns true" do
+      expect(FFI::Platform.mac?).to be true
+    end
+  end
+end
+
+describe "FFI::Platform.unix?" do
+  case OS
+  when "linux"
+    it "returns true" do
+      expect(FFI::Platform.unix?).to be true
+    end
+  when "windows"
+    it "returns false" do
+      expect(FFI::Platform.unix?).to be false
+    end
+  when "darwin"
+    it "returns true" do
+      expect(FFI::Platform.unix?).to be true
+    end
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/pointer_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/pointer_spec.rb
new file mode 100755
index 0000000..19c1953
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/pointer_spec.rb
@@ -0,0 +1,278 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+require 'delegate'
+
+module PointerTestLib
+  extend FFI::Library
+  ffi_lib TestLibrary::PATH
+  begin
+    attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
+  rescue FFI::NotFoundError
+    # NetBSD uses #define instead of typedef for these
+    attach_function :ptr_ret_int32_t, :ptr_ret___int32_t, [ :pointer, :int ], :int
+  end
+  attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], :pointer
+  attach_function :ptr_set_pointer, [ :pointer, :int, :pointer ], :void
+  attach_function :ptr_ret_pointer, [ :pointer, :int ], :pointer
+end
+describe "Pointer" do
+  include FFI
+  class ToPtrTest
+    def initialize(ptr)
+      @ptr = ptr
+    end
+    def to_ptr
+      @ptr
+    end
+  end
+
+  it "Any object implementing #to_ptr can be passed as a :pointer parameter" do
+    memory = FFI::MemoryPointer.new :long_long
+    magic = 0x12345678
+    memory.put_int32(0, magic)
+    tp = ToPtrTest.new(memory)
+    expect(PointerTestLib.ptr_ret_int32_t(tp, 0)).to eq(magic)
+  end
+  class PointerDelegate < DelegateClass(FFI::Pointer)
+    def initialize(ptr)
+      @ptr = ptr
+    end
+    def to_ptr
+      @ptr
+    end
+  end
+
+  it "A DelegateClass(Pointer) can be passed as a :pointer parameter" do
+    memory = FFI::MemoryPointer.new :long_long
+    magic = 0x12345678
+    memory.put_int32(0, magic)
+    ptr = PointerDelegate.new(memory)
+    expect(PointerTestLib.ptr_ret_int32_t(ptr, 0)).to eq(magic)
+  end
+
+  it "Fixnum cannot be used as a Pointer argument" do
+    expect { PointerTestLib.ptr_ret_int32(0, 0) }.to raise_error
+  end
+
+  it "Bignum cannot be used as a Pointer argument" do
+    expect { PointerTestLib.ptr_ret_int32(0xfee1deadbeefcafebabe, 0) }.to raise_error
+  end
+
+  describe "pointer type methods" do
+
+    it "#read_pointer" do
+      memory = FFI::MemoryPointer.new :pointer
+      PointerTestLib.ptr_set_pointer(memory, 0, PointerTestLib.ptr_from_address(0xdeadbeef))
+      expect(memory.read_pointer.address).to eq(0xdeadbeef)
+    end
+
+    it "#write_pointer" do
+      memory = FFI::MemoryPointer.new :pointer
+      memory.write_pointer(PointerTestLib.ptr_from_address(0xdeadbeef))
+      expect(PointerTestLib.ptr_ret_pointer(memory, 0).address).to eq(0xdeadbeef)
+    end
+
+    it "#read_array_of_pointer" do
+      values = [0x12345678, 0xfeedf00d, 0xdeadbeef]
+      memory = FFI::MemoryPointer.new :pointer, values.size
+      values.each_with_index do |address, j|
+        PointerTestLib.ptr_set_pointer(memory, j * FFI.type_size(:pointer), PointerTestLib.ptr_from_address(address))
+      end
+      array = memory.read_array_of_pointer(values.size)
+      values.each_with_index do |address, j|
+        expect(array[j].address).to eq(address)
+      end
+    end
+    
+  end
+
+  describe 'NULL' do
+    it 'should be obtained using Pointer::NULL constant' do
+      null_ptr = FFI::Pointer::NULL
+      expect(null_ptr).to be_null
+    end
+    it 'should be obtained passing address 0 to constructor' do
+      expect(FFI::Pointer.new(0)).to be_null
+    end
+    it 'should raise an error when attempting read/write operations on it' do
+      null_ptr = FFI::Pointer::NULL
+      expect { null_ptr.read_int }.to raise_error(FFI::NullPointerError)
+      expect { null_ptr.write_int(0xff1) }.to raise_error(FFI::NullPointerError)
+    end
+    it 'returns true when compared with nil' do
+      expect((FFI::Pointer::NULL == nil)).to be true
+    end
+  end
+
+  it "Pointer.size returns sizeof pointer on platform" do
+    expect(FFI::Pointer.size).to eq((FFI::Platform::ADDRESS_SIZE / 8))
+  end
+
+  describe "#slice" do
+    before(:each) do
+      @mptr = FFI::MemoryPointer.new(:char, 12)
+      @mptr.put_uint(0, 0x12345678)
+      @mptr.put_uint(4, 0xdeadbeef)
+    end
+
+    it "contents of sliced pointer matches original pointer at offset" do
+      expect(@mptr.slice(4, 4).get_uint(0)).to eq(0xdeadbeef)
+    end
+
+    it "modifying sliced pointer is reflected in original pointer" do
+      @mptr.slice(4, 4).put_uint(0, 0xfee1dead)
+      expect(@mptr.get_uint(4)).to eq(0xfee1dead)
+    end
+
+    it "access beyond bounds should raise IndexError" do
+      expect { @mptr.slice(4, 4).get_int(4) }.to raise_error(IndexError)
+    end
+  end
+
+  describe "#type_size" do
+    it "should be same as FFI.type_size(type)" do
+      expect(FFI::MemoryPointer.new(:int, 1).type_size).to eq(FFI.type_size(:int))
+    end
+  end
+end
+
+describe "AutoPointer" do
+  loop_count = 30
+  wiggle_room = 5 # GC rarely cleans up all objects. we can get most of them, and that's enough to determine if the basic functionality is working.
+  magic = 0x12345678
+
+  class AutoPointerTestHelper
+    @@count = 0
+    def self.release
+      @@count += 1 if @@count > 0
+    end
+    def self.reset
+      @@count = 0
+    end
+    def self.gc_everything(count)
+      loop = 5
+      while @@count < count && loop > 0
+        loop -= 1
+        TestLibrary.force_gc
+        sleep 0.05 unless @@count == count
+      end
+      @@count = 0
+    end
+    def self.finalizer
+      self.method(:release).to_proc
+    end
+  end
+  class AutoPointerSubclass < FFI::AutoPointer
+    def self.release(ptr); end
+  end
+
+  # see #427
+  it "cleanup via default release method", :broken => true do
+    expect(AutoPointerSubclass).to receive(:release).at_least(loop_count-wiggle_room).times
+    AutoPointerTestHelper.reset
+    loop_count.times do
+      # note that if we called
+      # AutoPointerTestHelper.method(:release).to_proc inline, we'd
+      # have a reference to the pointer and it would never get GC'd.
+      AutoPointerSubclass.new(PointerTestLib.ptr_from_address(magic))
+    end
+    AutoPointerTestHelper.gc_everything loop_count
+  end
+
+  # see #427
+  it "cleanup when passed a proc", :broken => true do
+    #  NOTE: passing a proc is touchy, because it's so easy to create a memory leak.
+    #
+    #  specifically, if we made an inline call to
+    #
+    #      AutoPointerTestHelper.method(:release).to_proc
+    #
+    #  we'd have a reference to the pointer and it would
+    #  never get GC'd.
+    expect(AutoPointerTestHelper).to receive(:release).at_least(loop_count-wiggle_room).times
+    AutoPointerTestHelper.reset
+    loop_count.times do
+      FFI::AutoPointer.new(PointerTestLib.ptr_from_address(magic),
+                           AutoPointerTestHelper.finalizer)
+    end
+    AutoPointerTestHelper.gc_everything loop_count
+  end
+
+  # see #427
+  it "cleanup when passed a method", :broken => true do
+    expect(AutoPointerTestHelper).to receive(:release).at_least(loop_count-wiggle_room).times
+    AutoPointerTestHelper.reset
+    loop_count.times do
+      FFI::AutoPointer.new(PointerTestLib.ptr_from_address(magic),
+                           AutoPointerTestHelper.method(:release))
+    end
+    AutoPointerTestHelper.gc_everything loop_count
+  end
+
+  it "can be used as the return type of a function" do
+    expect do
+      Module.new do
+        extend FFI::Library
+        ffi_lib TestLibrary::PATH
+        class CustomAutoPointer < FFI::AutoPointer
+          def self.release(ptr); end
+        end
+        attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], CustomAutoPointer
+      end
+    end.not_to raise_error
+  end
+
+  describe "#new" do
+    it "MemoryPointer argument raises TypeError" do
+      expect { FFI::AutoPointer.new(FFI::MemoryPointer.new(:int))}.to raise_error(::TypeError)
+    end
+    it "AutoPointer argument raises TypeError" do
+      expect { AutoPointerSubclass.new(AutoPointerSubclass.new(PointerTestLib.ptr_from_address(0))) }.to raise_error(::TypeError)
+    end
+    it "Buffer argument raises TypeError" do
+      expect { FFI::AutoPointer.new(FFI::Buffer.new(:int))}.to raise_error(::TypeError)
+    end
+
+  end
+
+  describe "#autorelease?" do
+    ptr_class = Class.new(FFI::AutoPointer) do
+      def self.release(ptr); end
+    end
+
+    it "should be true by default" do
+      expect(ptr_class.new(FFI::Pointer.new(0xdeadbeef)).autorelease?).to be true
+    end
+
+    it "should return false when autorelease=(false)" do
+      ptr = ptr_class.new(FFI::Pointer.new(0xdeadbeef))
+      ptr.autorelease = false
+      expect(ptr.autorelease?).to be false
+    end
+  end
+
+  describe "#type_size" do
+    ptr_class = Class.new(FFI::AutoPointer) do
+      def self.release(ptr); end
+    end
+
+    it "type_size of AutoPointer should match wrapped Pointer" do
+      aptr = ptr_class.new(FFI::Pointer.new(:int, 0xdeadbeef))
+      expect(aptr.type_size).to eq(FFI.type_size(:int))
+    end
+    
+    it "[] offset should match wrapped Pointer" do
+      mptr = FFI::MemoryPointer.new(:int, 1024)
+      aptr = ptr_class.new(FFI::Pointer.new(:int, mptr))
+      aptr[0].write_uint(0xfee1dead)
+      aptr[1].write_uint(0xcafebabe)
+      expect(mptr[0].read_uint).to eq(0xfee1dead)
+      expect(mptr[1].read_uint).to eq(0xcafebabe)
+    end
+  end
+end
+
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/rbx/attach_function_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/rbx/attach_function_spec.rb
new file mode 100755
index 0000000..e90f535
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/rbx/attach_function_spec.rb
@@ -0,0 +1,33 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+class Timeval < FFI::Struct
+  layout :tv_sec, :ulong, 0, :tv_usec, :ulong, 4  
+end
+
+module LibC
+  extend FFI::Library
+  ffi_lib FFI::Library::LIBC
+
+  attach_function :gettimeofday, [:pointer, :pointer], :int
+end
+
+describe FFI::Library, "#attach_function" do
+  it "correctly returns a value for gettimeofday" do
+    t = Timeval.new
+    time = LibC.gettimeofday(t.pointer, nil)
+    expect(time).to be_kind_of(Integer)
+  end
+  
+  it "correctly populates a struct for gettimeofday" do
+    t = Timeval.new
+    LibC.gettimeofday(t.pointer, nil)
+    expect(t[:tv_sec]).to be_kind_of(Numeric)
+    expect(t[:tv_usec]).to be_kind_of(Numeric)
+  end
+end
+
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/rbx/memory_pointer_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/rbx/memory_pointer_spec.rb
new file mode 100755
index 0000000..0fe3597
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/rbx/memory_pointer_spec.rb
@@ -0,0 +1,130 @@
+# coding: utf-8
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+module CTest
+  extend FFI::Library
+  ffi_lib FFI::Library::LIBC
+
+  attach_function :strcat, [:pointer, :pointer], :pointer
+end
+
+describe "MemoryPointer" do
+  it "makes a pointer from a string" do
+    m = FFI::MemoryPointer.from_string("FFI is Awesome")
+    expect(m.total).to eq(15)
+    expect(m.type_size).to eq(1)
+  end
+
+  it "does not make a pointer from non-strings" do
+    expect { FFI::MemoryPointer.from_string(nil) }.to raise_error(TypeError)
+  end
+
+  it "makes a pointer from a string with multibyte characters" do
+    m = FFI::MemoryPointer.from_string("ぱんだ")
+    expect(m.total).to eq(10)
+    expect(m.type_size).to eq(1)
+  end
+
+  it "reads back a string" do
+    m = FFI::MemoryPointer.from_string("FFI is Awesome")
+    expect(m.read_string).to eq("FFI is Awesome")
+  end
+  
+  it "makes a pointer for a certain number of bytes" do
+    m = FFI::MemoryPointer.new(8)
+    m.write_array_of_int([1,2])
+    expect(m.read_array_of_int(2)).to eq([1,2])
+  end
+
+  it "allows access to an element of the pointer (as an array)" do
+    m = FFI::MemoryPointer.new(:int, 2)
+    m.write_array_of_int([1,2])
+    expect(m[0].read_int).to eq(1)
+    expect(m[1].read_int).to eq(2)
+  end
+  
+  it "allows writing as an int" do
+    m = FFI::MemoryPointer.new(:int)
+    m.write_int(1)
+    expect(m.read_int).to eq(1)
+  end
+  
+  it "allows writing as a long" do
+    m = FFI::MemoryPointer.new(:long)
+    m.write_long(10)
+    expect(m.read_long).to eq(10)
+  end
+  
+  it "raises an error if you try putting a long into a pointer of size 1" do
+    m = FFI::MemoryPointer.new(1)
+    expect { m.write_long(10) }.to raise_error
+  end
+  
+  it "raises an error if you try putting an int into a pointer of size 1" do
+    m = FFI::MemoryPointer.new(1)
+    expect { m.write_int(10) }.to raise_error
+  end
+#  it "does not raise IndexError for opaque pointers" do
+#    m = FFI::MemoryPointer.new(8)
+#    p2 = FFI::MemoryPointer.new(1024)
+#    m.write_long(p2.address)
+#    p = m.read_pointer
+#    lambda { p.write_int(10) }.should_not raise_error
+#  end
+  
+  it "makes a pointer for a certain type" do
+    m = FFI::MemoryPointer.new(:int)
+    m.write_int(10)
+    expect(m.read_int).to eq(10)
+  end
+  
+  it "makes a memory pointer for a number of a certain type" do
+    m = FFI::MemoryPointer.new(:int, 2)
+    m.write_array_of_int([1,2])
+    expect(m.read_array_of_int(2)).to eq([1,2])
+  end
+  
+  it "makes a pointer for an object responding to #size" do
+    m = FFI::MemoryPointer.new(Struct.new(:size).new(8))
+    m.write_array_of_int([1,2])
+    expect(m.read_array_of_int(2)).to eq([1,2])
+  end
+
+  it "makes a pointer for a number of an object responding to #size" do
+    m = FFI::MemoryPointer.new(Struct.new(:size).new(4), 2)
+    m.write_array_of_int([1,2])
+    expect(m.read_array_of_int(2)).to eq([1,2])
+  end  
+
+  it "MemoryPointer#address returns correct value" do
+    m = FFI::MemoryPointer.new(:long_long)
+    magic = 0x12345678
+    m.write_long(magic)
+    expect(m.read_pointer.address).to eq(magic)
+  end
+
+  it "MemoryPointer#null? returns true for zero value" do
+    m = FFI::MemoryPointer.new(:long_long)
+    m.write_long(0)    
+    expect(m.read_pointer.null?).to be true
+  end
+
+  it "MemoryPointer#null? returns false for non-zero value" do
+    m = FFI::MemoryPointer.new(:long_long)
+    m.write_long(0x12345678)
+    expect(m.read_pointer.null?).to be false
+  end
+  
+  it "initialize with block should execute block" do
+    block_executed = false
+    FFI::MemoryPointer.new(:pointer) do |ptr|
+      block_executed = true
+    end
+    expect(block_executed).to be true
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/rbx/spec_helper.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/rbx/spec_helper.rb
new file mode 100755
index 0000000..6e009d8
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/rbx/spec_helper.rb
@@ -0,0 +1,6 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "../spec_helper"))
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/rbx/struct_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/rbx/struct_spec.rb
new file mode 100755
index 0000000..a7ed85b
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/rbx/struct_spec.rb
@@ -0,0 +1,18 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+class Timeval < FFI::Struct
+  layout :tv_sec, :ulong, 0, :tv_usec, :ulong, 4  
+end
+
+describe FFI::Struct do
+  it "allows setting fields" do
+    t = Timeval.new
+    t[:tv_sec] = 12
+    expect(t[:tv_sec]).to eq(12)
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/spec_helper.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/spec_helper.rb
new file mode 100755
index 0000000..0c173e4
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/spec_helper.rb
@@ -0,0 +1,93 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require 'rbconfig'
+require 'fileutils'
+require 'ffi'
+
+RSpec.configure do |c|
+  c.filter_run_excluding :broken => true
+end
+
+CPU = case RbConfig::CONFIG['host_cpu'].downcase
+  when /i[3456]86/
+    # Darwin always reports i686, even when running in 64bit mode
+    if RbConfig::CONFIG['host_os'] =~ /darwin/ && 0xfee1deadbeef.is_a?(Fixnum)
+      "x86_64"
+    else
+      "i386"
+    end
+
+  when /amd64|x86_64/
+    "x86_64"
+
+  when /ppc64|powerpc64/
+    "powerpc64"
+
+  when /ppc|powerpc/
+    "powerpc"
+
+  when /^arm/
+    "arm"
+
+  else
+    RbConfig::CONFIG['host_cpu']
+  end
+
+OS = case RbConfig::CONFIG['host_os'].downcase
+  when /linux/
+    "linux"
+  when /darwin/
+    "darwin"
+  when /freebsd/
+    "freebsd"
+  when /openbsd/
+    "openbsd"
+  when /sunos|solaris/
+    "solaris"
+  when /mswin|mingw/
+    "win32"
+  else
+    RbConfig::CONFIG['host_os'].downcase
+  end
+
+def compile_library(path, lib)
+
+  dir = File.expand_path(path, File.dirname(__FILE__))
+  lib = "#{dir}/#{lib}"
+  if !File.exist?(lib)
+    output = nil
+    FileUtils.cd(dir) do
+      output = system(*%{#{system('which gmake >/dev/null') && 'gmake' || 'make'} CPU=#{CPU} OS=#{OS} }.tap{|x| puts x.inspect})
+    end
+
+    if $?.exitstatus != 0
+      puts "ERROR:\n#{output}"
+      raise "Unable to compile \"#{lib}\""
+    end
+  end
+
+  lib
+end
+
+require "ffi"
+
+module TestLibrary
+  PATH = compile_library("fixtures", "libtest.#{FFI::Platform::LIBSUFFIX}")
+
+  def self.force_gc
+    if RUBY_PLATFORM =~ /java/
+      java.lang.System.gc
+    elsif defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
+      GC.run(true)
+    else
+      GC.start
+    end
+  end
+end
+module LibTest
+  extend FFI::Library
+  ffi_lib TestLibrary::PATH
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/string_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/string_spec.rb
new file mode 100755
index 0000000..fac11f0
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/string_spec.rb
@@ -0,0 +1,118 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+describe "String tests" do
+  include FFI
+  module StrLibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    attach_function :ptr_ret_pointer, [ :pointer, :int], :string
+    attach_function :string_equals, [ :string, :string ], :int
+    attach_function :string_dummy, [ :string ], :void
+    attach_function :string_null, [ ], :string
+  end
+
+  it "MemoryPointer#get_string returns a tainted string" do
+    mp = FFI::MemoryPointer.new 1024
+    mp.put_string(0, "test\0")
+    str = mp.get_string(0)
+    expect(str.tainted?).to be true
+  end
+
+  it "String returned by a method is tainted" do
+    mp = FFI::MemoryPointer.new :pointer
+    sp = FFI::MemoryPointer.new 1024
+    sp.put_string(0, "test")
+    mp.put_pointer(0, sp)
+    str = StrLibTest.ptr_ret_pointer(mp, 0)
+    expect(str).to eq("test")
+    expect(str).to be_tainted
+  end
+
+  it "Poison null byte raises error" do
+    s = "123\0abc"
+    expect { StrLibTest.string_equals(s, s) }.to raise_error
+  end
+
+  it "Tainted String parameter should throw a SecurityError" do
+    $SAFE = 1
+    str = "test"
+    str.taint
+    begin
+      expect(LibTest.string_equals(str, str)).to be false
+    rescue SecurityError
+    end
+  end if false
+  it "casts nil as NULL pointer" do
+    expect(StrLibTest.string_dummy(nil)).to be_nil
+  end
+
+  it "return nil for NULL char*" do
+    expect(StrLibTest.string_null).to be_nil
+  end
+
+  it "reads an array of strings until encountering a NULL pointer" do
+    strings = ["foo", "bar", "baz", "testing", "ffi"]
+    ptrary = FFI::MemoryPointer.new(:pointer, 6)
+    ary = strings.inject([]) do |a, str|
+      f = FFI::MemoryPointer.new(1024)
+      f.put_string(0, str)
+      a << f
+    end
+    ary.insert(3, nil)
+    ptrary.write_array_of_pointer(ary)
+    expect(ptrary.get_array_of_string(0)).to eq(["foo", "bar", "baz"])
+  end
+
+  it "reads an array of strings of the size specified, substituting nil when a pointer is NULL" do
+    strings = ["foo", "bar", "baz", "testing", "ffi"]
+    ptrary = FFI::MemoryPointer.new(:pointer, 6)
+    ary = strings.inject([]) do |a, str|
+      f = FFI::MemoryPointer.new(1024)
+      f.put_string(0, str)
+      a << f
+    end
+    ary.insert(2, nil)
+    ptrary.write_array_of_pointer(ary)
+    expect(ptrary.get_array_of_string(0, 4)).to eq(["foo", "bar", nil, "baz"])
+  end
+
+  it "reads an array of strings, taking a memory offset parameter" do
+    strings = ["foo", "bar", "baz", "testing", "ffi"]
+    ptrary = FFI::MemoryPointer.new(:pointer, 5)
+    ary = strings.inject([]) do |a, str|
+      f = FFI::MemoryPointer.new(1024)
+      f.put_string(0, str)
+      a << f
+    end
+    ptrary.write_array_of_pointer(ary)
+    expect(ptrary.get_array_of_string(2 * FFI.type_size(:pointer), 3)).to eq(["baz", "testing", "ffi"])
+  end
+
+  it "raises an IndexError when trying to read an array of strings out of bounds" do
+    strings = ["foo", "bar", "baz", "testing", "ffi"]
+    ptrary = FFI::MemoryPointer.new(:pointer, 5)
+    ary = strings.inject([]) do |a, str|
+      f = FFI::MemoryPointer.new(1024)
+      f.put_string(0, str)
+      a << f
+    end
+    ptrary.write_array_of_pointer(ary)
+    expect { ptrary.get_array_of_string(0, 6) }.to raise_error
+  end
+
+  it "raises an IndexError when trying to read an array of strings using a negative offset" do
+    strings = ["foo", "bar", "baz", "testing", "ffi"]
+    ptrary = FFI::MemoryPointer.new(:pointer, 5)
+    ary = strings.inject([]) do |a, str|
+      f = FFI::MemoryPointer.new(1024)
+      f.put_string(0, str)
+      a << f
+    end
+    ptrary.write_array_of_pointer(ary)
+    expect { ptrary.get_array_of_string(-1) }.to raise_error
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/strptr_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/strptr_spec.rb
new file mode 100755
index 0000000..a6400f4
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/strptr_spec.rb
@@ -0,0 +1,50 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "functions returning :strptr" do
+
+  it "can attach function with :strptr return type" do
+    expect do
+      Module.new do
+        extend FFI::Library
+        ffi_lib FFI::Library::LIBC
+        if !FFI::Platform.windows?
+          attach_function :strdup, [ :string ], :strptr
+        else
+          attach_function :_strdup, [ :string ], :strptr
+        end
+      end
+    end.not_to raise_error
+  end
+
+  module StrPtr
+    extend FFI::Library
+    ffi_lib FFI::Library::LIBC
+    attach_function :free, [ :pointer ], :void
+    if !FFI::Platform.windows?
+      attach_function :strdup, [ :string ], :strptr
+    else
+      attach_function :strdup, :_strdup, [ :string ], :strptr
+    end
+  end
+
+  it "should return [ String, Pointer ]" do
+    result = StrPtr.strdup("test")
+    expect(result[0].is_a?(String)).to be true
+    expect(result[1].is_a?(FFI::Pointer)).to be true
+  end
+
+  it "should return the correct value" do
+    result = StrPtr.strdup("test")
+    expect(result[0]).to eq("test")
+  end
+
+  it "should return non-NULL pointer" do
+    result = StrPtr.strdup("test")
+    expect(result[1]).not_to be_null
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/struct_by_ref_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/struct_by_ref_spec.rb
new file mode 100755
index 0000000..0858423
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/struct_by_ref_spec.rb
@@ -0,0 +1,43 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe FFI::Struct, ' by_ref' do
+  before :all do
+    @struct_class = struct_class = Class.new(FFI::Struct) do
+      layout :a, :pointer
+    end
+
+    @api = Module.new do
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      fn = FFI::Type::POINTER.size == FFI::Type::LONG.size ? :ret_ulong : :ret_u64
+      attach_function :struct_test, fn, [ struct_class.by_ref ], :pointer
+    end
+  end
+
+  it "should accept instances of exact struct class" do
+    s = @struct_class.new
+    expect(@api.struct_test(s)).to eq(s.pointer)
+  end
+
+  it "should accept nil" do
+    expect(@api.struct_test(nil)).to be_null
+  end
+
+  it "should reject other types" do
+    expect { expect(@api.struct_test('test')).to be_nil }.to raise_error(TypeError)
+  end
+
+  it "should reject instances of other struct classes" do
+    other_class = Class.new(FFI::Struct) do
+      layout :a, :pointer
+    end
+
+    expect { @api.struct_test(other_class.new) }.to raise_error(TypeError)
+  end
+end
+
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/struct_callback_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/struct_callback_spec.rb
new file mode 100755
index 0000000..7cab301
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/struct_callback_spec.rb
@@ -0,0 +1,69 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe FFI::Struct, ' with inline callback functions' do
+  it 'should be able to define inline callback field' do
+    expect(module CallbackMember1
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      DUMMY_CB = callback :dummy_cb, [ :int ], :int
+      class TestStruct < FFI::Struct
+        layout \
+          :add, callback([ :int, :int ], :int),
+          :sub, callback([ :int, :int ], :int),
+          :cb_with_cb_parameter, callback([ DUMMY_CB, :int ], :int)
+      end
+      attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
+      attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
+    end).to be_an_instance_of FFI::Function
+  end
+
+  it 'should take methods as callbacks' do
+    module CallbackMember2
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      class TestStruct < FFI::Struct
+        layout \
+          :add, callback([ :int, :int ], :int),
+          :sub, callback([ :int, :int ], :int)
+      end
+      attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
+      attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
+    end
+    module StructCallbacks
+      def self.add a, b
+        a+b
+      end
+    end
+
+    ts = CallbackMember2::TestStruct.new
+    ts[:add] = StructCallbacks.method(:add)
+
+    expect(CallbackMember2.struct_call_add_cb(ts, 1, 2)).to eq(3)
+  end
+
+  it 'should return callable object from []' do
+    module CallbackMember3
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      class TestStruct < FFI::Struct
+        layout \
+          :add, callback([ :int, :int ], :int),
+          :sub, callback([ :int, :int ], :int)
+      end
+      attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
+      attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
+    end
+
+    s = CallbackMember3::TestStruct.new
+    add = Proc.new { |a,b| a+b}
+    s[:add] = add
+    fn = s[:add]
+    expect(fn.respond_to?(:call)).to be true
+    expect(fn.call(1, 2)).to eq(3)
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/struct_initialize_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/struct_initialize_spec.rb
new file mode 100755
index 0000000..beb2477
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/struct_initialize_spec.rb
@@ -0,0 +1,35 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe FFI::Struct, ' with an initialize function' do
+  it "should call the initialize function" do
+    class StructWithInitialize < FFI::Struct
+      layout :string, :string
+      attr_accessor :magic
+      def initialize
+        super
+        self.magic = 42
+      end
+    end
+    expect(StructWithInitialize.new.magic).to eq(42)
+  end
+end
+
+describe FFI::ManagedStruct, ' with an initialize function' do
+  it "should call the initialize function" do
+    class ManagedStructWithInitialize < FFI::ManagedStruct
+      layout :string, :string
+      attr_accessor :magic
+      def initialize
+        super FFI::MemoryPointer.new(:pointer).put_int(0, 0x1234).get_pointer(0)
+        self.magic = 42
+      end
+      def self.release;end
+    end
+    expect(ManagedStructWithInitialize.new.magic).to eq(42)
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/struct_packed_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/struct_packed_spec.rb
new file mode 100755
index 0000000..8132be7
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/struct_packed_spec.rb
@@ -0,0 +1,50 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe FFI::Struct do
+  it "packed :char followed by :int should have size of 5" do
+    expect(Class.new(FFI::Struct) do
+      packed
+      layout :c, :char, :i, :int
+    end.size).to eq(5)
+  end
+
+  it "packed :char followed by :int should have alignment of 1" do
+    expect(Class.new(FFI::Struct) do
+      packed
+      layout :c, :char, :i, :int
+    end.alignment).to eq(1)
+  end
+
+  it "packed(2) :char followed by :int should have size of 6" do
+    expect(Class.new(FFI::Struct) do
+      packed 2
+      layout :c, :char, :i, :int
+    end.size).to eq(6)
+  end
+
+  it "packed(2)  :char followed by :int should have alignment of 2" do
+    expect(Class.new(FFI::Struct) do
+      packed 2
+      layout :c, :char, :i, :int
+    end.alignment).to eq(2)
+  end
+
+  it "packed :short followed by int should have size of 6" do
+    expect(Class.new(FFI::Struct) do
+      packed
+      layout :s, :short, :i, :int
+    end.size).to eq(6)
+  end
+
+  it "packed :short followed by int should have alignment of 1" do
+    expect(Class.new(FFI::Struct) do
+      packed
+      layout :s, :short, :i, :int
+    end.alignment).to eq(1)
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/struct_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/struct_spec.rb
new file mode 100755
index 0000000..1728758
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/struct_spec.rb
@@ -0,0 +1,886 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "Struct aligns fields correctly" do
+  it "char, followed by an int" do
+    pending("not supported in 1.8") if RUBY_VERSION =~ /1.8.*/
+    class CIStruct < FFI::Struct
+      layout :c => :char, :i => :int
+    end
+    expect(CIStruct.size).to eq(8)
+  end
+
+  it "short, followed by an int" do
+    pending("not supported in 1.8") if RUBY_VERSION =~ /1.8.*/
+    class SIStruct < FFI::Struct
+      layout :s => :short, :i => :int
+    end
+    expect(SIStruct.size).to eq(8)
+  end
+
+  it "int, followed by an int" do
+    pending("not supported in 1.8") if RUBY_VERSION =~ /1.8.*/
+    class IIStruct < FFI::Struct
+      layout :i1 => :int, :i => :int
+    end
+    expect(IIStruct.size).to eq(8)
+  end
+
+  it "long long, followed by an int" do
+    pending("not supported in 1.8") if RUBY_VERSION =~ /1.8.*/
+    class LLIStruct < FFI::Struct
+      layout :l => :long_long, :i => :int
+    end
+    expect(LLIStruct.size).to eq(FFI::TYPE_UINT64.alignment == 4 ? 12 : 16)
+  end
+end
+
+describe "Struct tests" do
+  StructTypes = {
+    's8' => :char,
+    's16' => :short,
+    's32' => :int,
+    's64' => :long_long,
+    'long' => :long,
+    'f32' => :float,
+    'f64' => :double
+  }
+  module LibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    attach_function :ptr_ret_pointer, [ :pointer, :int], :string
+    begin
+      attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
+    rescue FFI::NotFoundError
+      # NetBSD uses #define instead of typedef for these
+      attach_function :ptr_ret_int32_t, :ptr_ret___int32_t, [ :pointer, :int ], :int
+    end
+    attach_function :ptr_from_address, [ :ulong ], :pointer
+    attach_function :string_equals, [ :string, :string ], :int
+    [ 's8', 's16', 's32', 's64', 'f32', 'f64', 'long' ].each do |t|
+      attach_function "struct_align_#{t}", [ :pointer ], StructTypes[t]
+    end
+  end
+  class PointerMember < FFI::Struct
+    layout :pointer, :pointer
+  end
+  class StringMember < FFI::Struct
+    layout :string, :string
+  end
+
+  it "Struct#[:pointer]" do
+    magic = 0x12345678
+    mp = FFI::MemoryPointer.new :long
+    mp.put_long(0, magic)
+    smp = FFI::MemoryPointer.new :pointer
+    smp.put_pointer(0, mp)
+    s = PointerMember.new smp
+    expect(s[:pointer]).to eq(mp)
+  end
+
+  it "Struct#[:pointer].nil? for NULL value" do
+    magic = 0x12345678
+    mp = FFI::MemoryPointer.new :long
+    mp.put_long(0, magic)
+    smp = FFI::MemoryPointer.new :pointer
+    smp.put_pointer(0, nil)
+    s = PointerMember.new smp
+    expect(s[:pointer].null?).to be true
+  end
+
+  it "Struct#[:pointer]=" do
+    magic = 0x12345678
+    mp = FFI::MemoryPointer.new :long
+    mp.put_long(0, magic)
+    smp = FFI::MemoryPointer.new :pointer
+    s = PointerMember.new smp
+    s[:pointer] = mp
+    expect(smp.get_pointer(0)).to eq(mp)
+  end
+
+  it "Struct#[:pointer]=struct" do
+    smp = FFI::MemoryPointer.new :pointer
+    s = PointerMember.new smp
+    expect { s[:pointer] = s }.not_to raise_error Exception
+    expect { s[:pointer].nil? }.not_to raise_error Exception
+  end
+
+  it "Struct#[:pointer]=nil" do
+    smp = FFI::MemoryPointer.new :pointer
+    s = PointerMember.new smp
+    s[:pointer] = nil
+    expect(smp.get_pointer(0)).to be_null
+  end
+
+  it "Struct#[:string]" do
+    magic = "test"
+    mp = FFI::MemoryPointer.new 1024
+    mp.put_string(0, magic)
+    smp = FFI::MemoryPointer.new :pointer
+    smp.put_pointer(0, mp)
+    s = StringMember.new smp
+    expect(s[:string]).to eq(magic)
+  end
+
+  it "Struct#[:string].nil? for NULL value" do
+    smp = FFI::MemoryPointer.new :pointer
+    smp.put_pointer(0, nil)
+    s = StringMember.new smp
+    expect(s[:string]).to be_nil
+  end
+
+  it "Struct#layout works with :name, :type pairs" do
+    class PairLayout < FFI::Struct
+      layout :a, :int, :b, :long_long
+    end
+    ll_off = (FFI::TYPE_UINT64.alignment == 4 ? 4 : 8)
+    expect(PairLayout.size).to eq((ll_off + 8))
+    mp = FFI::MemoryPointer.new(PairLayout.size)
+    s = PairLayout.new mp
+    s[:a] = 0x12345678
+    expect(mp.get_int(0)).to eq(0x12345678)
+    s[:b] = 0xfee1deadbeef
+    expect(mp.get_int64(ll_off)).to eq(0xfee1deadbeef)
+  end
+
+  it "Struct#layout works with :name, :type, offset tuples" do
+    class PairLayout < FFI::Struct
+      layout :a, :int, 0, :b, :long_long, 4
+    end
+    expect(PairLayout.size).to eq((FFI::TYPE_UINT64.alignment == 4 ? 12 : 16))
+    mp = FFI::MemoryPointer.new(PairLayout.size)
+    s = PairLayout.new mp
+    s[:a] = 0x12345678
+    expect(mp.get_int(0)).to eq(0x12345678)
+    s[:b] = 0xfee1deadbeef
+    expect(mp.get_int64(4)).to eq(0xfee1deadbeef)
+  end
+
+  it "Struct#layout works with mixed :name,:type and :name,:type,offset" do
+    class MixedLayout < FFI::Struct
+      layout :a, :int, :b, :long_long, 4
+    end
+    expect(MixedLayout.size).to eq((FFI::TYPE_UINT64.alignment == 4 ? 12 : 16))
+    mp = FFI::MemoryPointer.new(MixedLayout.size)
+    s = MixedLayout.new mp
+    s[:a] = 0x12345678
+    expect(mp.get_int(0)).to eq(0x12345678)
+    s[:b] = 0xfee1deadbeef
+    expect(mp.get_int64(4)).to eq(0xfee1deadbeef)
+  end
+
+  rb_maj, rb_min = RUBY_VERSION.split('.')
+  if rb_maj.to_i >= 1 && rb_min.to_i >= 9 || RUBY_PLATFORM =~ /java/
+    it "Struct#layout withs with a hash of :name => type" do
+      class HashLayout < FFI::Struct
+        layout :a => :int, :b => :long_long
+      end
+      ll_off = (FFI::TYPE_UINT64.alignment == 4 ? 4 : 8)
+      expect(HashLayout.size).to eq(ll_off + 8)
+      mp = FFI::MemoryPointer.new(HashLayout.size)
+      s = HashLayout.new mp
+      s[:a] = 0x12345678
+      expect(mp.get_int(0)).to eq(0x12345678)
+      s[:b] = 0xfee1deadbeef
+      expect(mp.get_int64(ll_off)).to eq(0xfee1deadbeef)
+    end
+  end
+
+  it "subclass overrides initialize without calling super" do
+    class InitializeWithoutSuper < FFI::Struct
+      layout :a, :int, :b, :long_long, :d, [:double, 2]
+
+      def initialize(a, b)
+        self[:a] = a
+        self[:b] = b
+        self[:d][0] = 1.2
+        self[:d][1] = 3.4
+      end
+
+    end
+    s = InitializeWithoutSuper.new(0x1eefbeef, 0xdeadcafebabe)
+    expect(s[:a]).to eq(0x1eefbeef)
+    expect(s[:b]).to eq(0xdeadcafebabe)
+  end
+
+  it "Can use Struct subclass as parameter type" do
+    expect(module StructParam
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      class TestStruct < FFI::Struct
+        layout :c, :char
+      end
+      attach_function :struct_field_s8, [ TestStruct.in ], :char
+    end).to be_an_instance_of FFI::Function
+  end
+
+  it "Can use Struct subclass as IN parameter type" do
+    expect(module StructParam2
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      class TestStruct < FFI::Struct
+        layout :c, :char
+      end
+      attach_function :struct_field_s8, [ TestStruct.in ], :char
+    end).to be_an_instance_of FFI::Function
+  end
+
+  it "Can use Struct subclass as OUT parameter type" do
+    expect(module StructParam3
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      class TestStruct < FFI::Struct
+        layout :c, :char
+      end
+      attach_function :struct_field_s8, [ TestStruct.out ], :char
+    end).to be_an_instance_of FFI::Function
+  end
+
+  it "can be passed directly as a :pointer parameter" do
+    class TestStruct < FFI::Struct
+      layout :i, :int
+    end
+    s = TestStruct.new
+    s[:i] = 0x12
+    expect(LibTest.ptr_ret_int32_t(s, 0)).to eq(0x12)
+  end
+
+  it ":char member aligned correctly" do
+    class AlignChar < FFI::Struct
+      layout :c, :char, :v, :char
+    end
+    s = AlignChar.new
+    s[:v] = 0x12
+    expect(LibTest.struct_align_s8(s.pointer)).to eq(0x12)
+  end
+
+  it ":short member aligned correctly" do
+    class AlignShort < FFI::Struct
+      layout :c, :char, :v, :short
+    end
+    s = AlignShort.alloc_in
+    s[:v] = 0x1234
+    expect(LibTest.struct_align_s16(s.pointer)).to eq(0x1234)
+  end
+
+  it ":int member aligned correctly" do
+    class AlignInt < FFI::Struct
+      layout :c, :char, :v, :int
+    end
+    s = AlignInt.alloc_in
+    s[:v] = 0x12345678
+    expect(LibTest.struct_align_s32(s.pointer)).to eq(0x12345678)
+  end
+
+  it ":long_long member aligned correctly" do
+    class AlignLongLong < FFI::Struct
+      layout :c, :char, :v, :long_long
+    end
+    s = AlignLongLong.alloc_in
+    s[:v] = 0x123456789abcdef0
+    expect(LibTest.struct_align_s64(s.pointer)).to eq(0x123456789abcdef0)
+  end
+
+  it ":long member aligned correctly" do
+    class AlignLong < FFI::Struct
+      layout :c, :char, :v, :long
+    end
+    s = AlignLong.alloc_in
+    s[:v] = 0x12345678
+    expect(LibTest.struct_align_long(s.pointer)).to eq(0x12345678)
+  end
+
+  it ":float member aligned correctly" do
+    class AlignFloat < FFI::Struct
+      layout :c, :char, :v, :float
+    end
+    s = AlignFloat.alloc_in
+    s[:v] = 1.23456
+    expect((LibTest.struct_align_f32(s.pointer) - 1.23456).abs).to be < 0.00001
+  end
+
+  it ":double member aligned correctly" do
+    class AlignDouble < FFI::Struct
+      layout :c, :char, :v, :double
+    end
+    s = AlignDouble.alloc_in
+    s[:v] = 1.23456789
+    expect((LibTest.struct_align_f64(s.pointer) - 1.23456789).abs).to be < 0.00000001
+  end
+
+  it ":ulong, :pointer struct" do
+    class ULPStruct < FFI::Struct
+      layout :ul, :ulong, :p, :pointer
+    end
+    s = ULPStruct.alloc_in
+    s[:ul] = 0xdeadbeef
+    s[:p] = LibTest.ptr_from_address(0x12345678)
+    expect(s.pointer.get_ulong(0)).to eq(0xdeadbeef)
+  end
+  def test_num_field(type, v)
+    klass = Class.new(FFI::Struct)
+    klass.layout :v, type, :dummy, :long
+
+    s = klass.new
+    s[:v] = v
+    expect(s.pointer.send("get_#{type.to_s}", 0)).to eq(v)
+    s.pointer.send("put_#{type.to_s}", 0, 0)
+    expect(s[:v]).to eq(0)
+  end
+  def self.int_field_test(type, values)
+    values.each do |v|
+      it "#{type} field r/w (#{v.to_s(16)})" do
+        test_num_field(type, v)
+      end
+    end
+  end
+  int_field_test(:char, [ 0, 127, -128, -1 ])
+  int_field_test(:uchar, [ 0, 0x7f, 0x80, 0xff ])
+  int_field_test(:short, [ 0, 0x7fff, -0x8000, -1 ])
+  int_field_test(:ushort, [ 0, 0x7fff, 0x8000, 0xffff ])
+  int_field_test(:int, [ 0, 0x7fffffff, -0x80000000, -1 ])
+  int_field_test(:uint, [ 0, 0x7fffffff, 0x80000000, 0xffffffff ])
+  int_field_test(:long_long, [ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ])
+  int_field_test(:ulong_long, [ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ])
+  if FFI::Platform::LONG_SIZE == 32
+    int_field_test(:long, [ 0, 0x7fffffff, -0x80000000, -1 ])
+    int_field_test(:ulong, [ 0, 0x7fffffff, 0x80000000, 0xffffffff ])
+  else
+    int_field_test(:long, [ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ])
+    int_field_test(:ulong, [ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ])
+  end
+
+  it ":float field r/w" do
+    klass = Class.new(FFI::Struct)
+    klass.layout :v, :float, :dummy, :long
+
+    s = klass.new
+    value = 1.23456
+    s[:v] = value
+    expect((s.pointer.get_float(0) - value).abs).to be < 0.0001
+  end
+
+  it ":double field r/w" do
+    klass = Class.new(FFI::Struct)
+    klass.layout :v, :double, :dummy, :long
+
+    s = klass.new
+    value = 1.23456
+    s[:v] = value
+    expect((s.pointer.get_double(0) - value).abs).to be < 0.0001
+  end
+  module EnumFields
+    extend FFI::Library
+    TestEnum = enum :test_enum, [:c1, 10, :c2, 20, :c3, 30, :c4, 40]
+    class TestStruct < FFI::Struct
+      layout :a, :int, :c, :test_enum,
+        :d, [ TestEnum, TestEnum.symbols.length ]
+    end
+  end
+
+  it ":enum field r/w" do
+    s = EnumFields::TestStruct.new
+    s[:c] = :c3
+
+    expect(s.pointer.get_uint(FFI::Type::INT32.size)).to eq(30)
+    expect(s[:c]).to eq(:c3)
+  end
+
+  it "array of :enum field" do
+    s = EnumFields::TestStruct.new
+    EnumFields::TestEnum.symbols.each_with_index do |val, i|
+      s[:d][i] = val
+    end
+
+    EnumFields::TestEnum.symbols.each_with_index do |val, i|
+      expect(s.pointer.get_uint(FFI::Type::INT32.size * (2 + i))).to eq(EnumFields::TestEnum[val])
+    end
+
+    s[:d].each_with_index do |val, i|
+      expect(val).to eq(EnumFields::TestEnum.symbols[i])
+    end
+  end
+
+  module CallbackMember
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    callback :add, [ :int, :int ], :int
+    callback :sub, [ :int, :int ], :int
+    class TestStruct < FFI::Struct
+      layout :add, :add,
+        :sub, :sub
+    end
+    attach_function :struct_call_add_cb, [TestStruct.in, :int, :int], :int
+    attach_function :struct_call_sub_cb, [TestStruct.in, :int, :int], :int
+  end
+
+  it "Can have CallbackInfo struct field" do
+      s = CallbackMember::TestStruct.new
+      add_proc = lambda { |a, b| a+b }
+      sub_proc = lambda { |a, b| a-b }
+      s[:add] = add_proc
+      s[:sub] = sub_proc
+      expect(CallbackMember.struct_call_add_cb(s, 40, 2)).to eq(42)
+      expect(CallbackMember.struct_call_sub_cb(s, 44, 2)).to eq(42)
+  end
+
+  it "Can return its members as a list" do
+    class TestStruct < FFI::Struct
+      layout :a, :int, :b, :int, :c, :int
+    end
+    expect(TestStruct.members).to include(:a, :b, :c)
+  end
+
+  it "Can return its instance members and values as lists" do
+    class TestStruct < FFI::Struct
+      layout :a, :int, :b, :int, :c, :int
+    end
+    s = TestStruct.new
+    expect(s.members).to include(:a, :b, :c)
+    s[:a] = 1
+    s[:b] = 2
+    s[:c] = 3
+    expect(s.values).to include(1, 2, 3)
+  end
+
+  it 'should return an ordered field/offset pairs array' do
+    class TestStruct < FFI::Struct
+      layout :a, :int, :b, :int, :c, :int
+    end
+    s = TestStruct.new
+    expect(s.offsets).to eq([[:a, 0], [:b, 4], [:c, 8]])
+    expect(TestStruct.offsets).to eq([[:a, 0], [:b, 4], [:c, 8]])
+  end
+
+  it "Struct#offset_of returns offset of field within struct" do
+    class TestStruct < FFI::Struct
+      layout :a, :int, :b, :int, :c, :int
+    end
+    expect(TestStruct.offset_of(:a)).to eq(0)
+    expect(TestStruct.offset_of(:b)).to eq(4)
+    expect(TestStruct.offset_of(:c)).to eq(8)
+  end
+end
+
+describe FFI::Struct, ".layout" do
+  module FFISpecs
+    module LibTest
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      begin
+        attach_function :ptr_ret_int32_t, [ :pointer, :int ], :int
+      rescue FFI::NotFoundError
+        # NetBSD uses #define instead of typedef for these
+        attach_function :ptr_ret_int32_t, :ptr_ret___int32_t, [ :pointer, :int ], :int
+      end
+    end
+  end
+
+  describe "when derived class is not assigned to any constant" do
+    it "resolves a built-in type" do
+      klass = Class.new FFI::Struct
+      klass.layout :number, :int
+
+      instance = klass.new
+      instance[:number] = 0xA1
+      expect(FFISpecs::LibTest.ptr_ret_int32_t(instance, 0)).to eq(0xA1)
+    end
+  end
+
+  describe "when derived class is assigned to a constant" do
+    it "resolves a built-in type" do
+      class FFISpecs::TestStruct < FFI::Struct
+        layout :number, :int
+      end
+
+      instance = FFISpecs::TestStruct.new
+      instance[:number] = 0xA1
+      expect(FFISpecs::LibTest.ptr_ret_int32_t(instance, 0)).to eq(0xA1)
+    end
+
+    it "resolves a type from the enclosing module" do
+      module FFISpecs::LibTest
+        typedef :uint, :custom_int
+
+        class TestStruct < FFI::Struct
+          layout :number, :custom_int
+        end
+      end
+
+      instance = FFISpecs::LibTest::TestStruct.new
+      instance[:number] = 0xA1
+      expect(FFISpecs::LibTest.ptr_ret_int32_t(instance, 0)).to eq(0xA1)
+    end
+  end
+end
+
+describe FFI::Struct, ' with a nested struct field'  do
+  module LibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    class NestedStruct < FFI::Struct
+      layout :i, :int
+    end
+    class ContainerStruct < FFI::Struct
+      layout :first, :char, :ns, NestedStruct
+    end
+    attach_function :struct_align_nested_struct, [ :pointer ], :int
+    attach_function :struct_make_container_struct, [ :int ], :pointer
+  end
+  before do
+    @cs = LibTest::ContainerStruct.new
+  end
+
+  it 'should align correctly nested struct field' do
+    @cs[:ns][:i] = 123
+    expect(LibTest.struct_align_nested_struct(@cs.to_ptr)).to eq(123)
+  end
+
+  it 'should correctly calculate Container size (in bytes)' do
+    expect(LibTest::ContainerStruct.size).to eq(8)
+  end
+
+  it 'should return a Struct object when the field is accessed' do
+    expect(@cs[:ns].is_a?(FFI::Struct)).to be true
+  end
+
+  it 'should read a value from memory' do
+    @cs = LibTest::ContainerStruct.new(LibTest.struct_make_container_struct(123))
+    expect(@cs[:ns][:i]).to eq(123)
+  end
+
+  it 'should write a value to memory' do
+    @cs = LibTest::ContainerStruct.new(LibTest.struct_make_container_struct(123))
+    @cs[:ns][:i] = 456
+    expect(LibTest.struct_align_nested_struct(@cs.to_ptr)).to eq(456)
+  end
+
+  it 'should be able to assign struct instance to nested field' do
+    cs = LibTest::ContainerStruct.new(LibTest.struct_make_container_struct(123))
+    ns = LibTest::NestedStruct.new
+    ns[:i] = 567
+    cs[:ns] = ns
+    expect(cs[:ns][:i]).to eq(567)
+    expect(LibTest.struct_align_nested_struct(cs.to_ptr)).to eq(567)
+  end
+end
+
+describe FFI::Struct, ' with a nested array of structs'  do
+  module InlineArrayOfStructs
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    class NestedStruct < FFI::Struct
+      layout :i, :int
+    end
+    class ContainerStruct < FFI::Struct
+      layout :first, :char, :ns, [ NestedStruct, 1 ]
+    end
+    attach_function :struct_align_nested_struct, [ :pointer ], :int
+    attach_function :struct_make_container_struct, [ :int ], :pointer
+  end
+
+  before do
+    @cs = InlineArrayOfStructs::ContainerStruct.new
+  end
+
+  it 'should align correctly nested struct field' do
+    @cs[:ns][0][:i] = 123
+    expect(InlineArrayOfStructs.struct_align_nested_struct(@cs.to_ptr)).to eq(123)
+  end
+
+  it 'should correctly calculate Container size (in bytes)' do
+    expect(InlineArrayOfStructs::ContainerStruct.size).to eq(8)
+  end
+
+  it 'should return a Struct object when the field is accessed' do
+    expect(@cs[:ns][0].is_a?(FFI::Struct)).to be true
+  end
+
+  it 'should read a value from memory' do
+    @cs = InlineArrayOfStructs::ContainerStruct.new(InlineArrayOfStructs.struct_make_container_struct(123))
+    expect(@cs[:ns][0][:i]).to eq(123)
+  end
+
+  it 'should write a value to memory' do
+    @cs = InlineArrayOfStructs::ContainerStruct.new(InlineArrayOfStructs.struct_make_container_struct(123))
+    @cs[:ns][0][:i] = 456
+    expect(InlineArrayOfStructs.struct_align_nested_struct(@cs.to_ptr)).to eq(456)
+  end
+
+  it 'should support Enumerable#each' do
+    @cs = InlineArrayOfStructs::ContainerStruct.new(InlineArrayOfStructs.struct_make_container_struct(123))
+    ints = []
+    @cs[:ns].each { |s| ints << s[:i] }
+    expect(ints[0]).to eq(123)
+  end
+end
+
+describe FFI::Struct, ' by value'  do
+  module LibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+
+    class S8S32 < FFI::Struct
+      layout :s8, :char, :s32, :int
+    end
+
+    class StructString < FFI::Struct
+      layout :bytes, :string, :len, :int
+    end
+
+    attach_function :struct_return_s8s32, [ ], S8S32.by_value
+    attach_function :struct_s8s32_set, [ :char, :int ], S8S32.by_value
+    attach_function :struct_s8s32_get_s8, [ S8S32.by_value ], :char
+    attach_function :struct_s8s32_get_s32, [ S8S32.by_value ], :int
+    attach_function :struct_s8s32_s32_ret_s32, [ S8S32.by_value, :int ], :int
+    attach_function :struct_s8s32_s64_ret_s64, [ S8S32.by_value, :long_long ], :long_long
+    attach_function :struct_s8s32_ret_s8s32, [ S8S32.by_value ], S8S32.by_value
+    attach_function :struct_s32_ptr_s32_s8s32_ret_s32, [ :int, :pointer, :int, S8S32.by_value ], :int
+    attach_function :struct_varargs_ret_struct_string, [ :int, :varargs ], StructString.by_value
+  end
+
+  it 'return using pre-set values' do
+    s = LibTest.struct_return_s8s32
+    expect(s[:s8]).to eq(0x7f)
+    expect(s[:s32]).to eq(0x12345678)
+  end
+
+  it 'return using passed in values' do
+    s = LibTest.struct_s8s32_set(123, 456789)
+    expect(s[:s8]).to eq(123)
+    expect(s[:s32]).to eq(456789)
+  end
+
+  it 'parameter' do
+    s = LibTest::S8S32.new
+    s[:s8] = 0x12
+    s[:s32] = 0x34567890
+    expect(LibTest.struct_s8s32_get_s8(s)).to eq(0x12)
+    expect(LibTest.struct_s8s32_get_s32(s)).to eq(0x34567890)
+  end
+
+  it 'parameter with following s32' do
+    s = LibTest::S8S32.new
+    s[:s8] = 0x12
+    s[:s32] = 0x34567890
+
+    expect(LibTest.struct_s8s32_s32_ret_s32(s, 0x1eefdead)).to eq(0x1eefdead)
+  end
+
+  # it 'parameter with following s64' do
+  #   s = LibTest::S8S64.new
+  #   s[:s8] = 0x12
+  #   s[:s64] = 0x34567890
+  #
+  #
+  #   LibTest.struct_s8s64_s64_ret_s64(s, 0x1eefdead1eefdead).should == 0x1eefdead1eefdead
+  # end
+
+  it 'parameter with preceding s32,ptr,s32' do
+    s = LibTest::S8S32.new
+    s[:s8] = 0x12
+    s[:s32] = 0x34567890
+    out = LibTest::S8S32.new
+    expect(LibTest.struct_s32_ptr_s32_s8s32_ret_s32(0x1000000, out, 0x1eafbeef, s)).to eq(0x34567890)
+    expect(out[:s8]).to eq(s[:s8])
+    expect(out[:s32]).to eq(s[:s32])
+  end
+
+  it 'parameter with preceding s32,string,s32' do
+    s = LibTest::S8S32.new
+    s[:s8] = 0x12
+    s[:s32] = 0x34567890
+    out = 0.chr * 32
+    expect(LibTest.struct_s32_ptr_s32_s8s32_ret_s32(0x1000000, out, 0x1eafbeef, s)).to eq(0x34567890)
+  end
+
+  it 'parameter, returning struct by value' do
+    s = LibTest::S8S32.new
+    s[:s8] = 0x12
+    s[:s32] = 0x34567890
+
+    ret = LibTest.struct_s8s32_ret_s8s32(s)
+    expect(ret[:s8]).to eq(s[:s8])
+    expect(ret[:s32]).to eq(s[:s32])
+  end
+
+  it 'varargs returning a struct' do
+    string = "test"
+    s = LibTest.struct_varargs_ret_struct_string(4, :string, string)
+    expect(s[:len]).to eq(string.length)
+    expect(s[:bytes]).to eq(string)
+  end
+end
+
+describe FFI::Struct, ' with an array field'  do
+  module LibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    class StructWithArray < FFI::Struct
+      layout :first, :char, :a, [:int, 5]
+    end
+    attach_function :struct_make_struct_with_array, [:int, :int, :int, :int, :int], :pointer
+    attach_function :struct_field_array, [:pointer], :pointer
+  end
+  before do
+    @s = LibTest::StructWithArray.new
+  end
+
+  it 'should correctly calculate StructWithArray size (in bytes)' do
+    expect(LibTest::StructWithArray.size).to eq(24)
+  end
+
+  it 'should read values from memory' do
+    @s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
+    expect(@s[:a].to_a).to eq([0, 1, 2, 3, 4])
+  end
+#  it 'should cache array object for successive calls' do
+#    @s[:a].object_id.should == @s[:a].object_id
+#  end
+
+  it 'should return the number of elements in the array field' do
+    @s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
+    expect(@s[:a].size).to eq(5)
+  end
+
+  it 'should allow iteration through the array elements' do
+    @s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
+    @s[:a].each_with_index { |elem, i| expect(elem).to eq(i) }
+  end
+
+  it 'should return the pointer to the array' do
+    @s = LibTest::StructWithArray.new(LibTest.struct_make_struct_with_array(0, 1, 2, 3, 4))
+    expect(@s[:a].to_ptr).to eq(LibTest::struct_field_array(@s.to_ptr))
+  end
+end
+
+describe 'BuggedStruct' do
+  module LibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    class BuggedStruct < FFI::Struct
+      layout :visible, :uchar,
+              :x, :uint,
+              :y, :uint,
+              :rx, :short,
+              :ry, :short,
+              :order, :uchar,
+              :size, :uchar
+    end
+    attach_function :bugged_struct_size, [], :uint
+  end
+
+  it 'should return its correct size' do
+    expect(LibTest::BuggedStruct.size).to eq(LibTest.bugged_struct_size)
+  end
+
+  it "offsets within struct should be correct" do
+    expect(LibTest::BuggedStruct.offset_of(:visible)).to eq(0)
+    expect(LibTest::BuggedStruct.offset_of(:x)).to eq(4)
+    expect(LibTest::BuggedStruct.offset_of(:y)).to eq(8)
+    expect(LibTest::BuggedStruct.offset_of(:rx)).to eq(12)
+    expect(LibTest::BuggedStruct.offset_of(:ry)).to eq(14)
+    expect(LibTest::BuggedStruct.offset_of(:order)).to eq(16)
+    expect(LibTest::BuggedStruct.offset_of(:size)).to eq(17)
+  end
+
+  it 'should return correct field/offset pairs' do
+    expect(LibTest::BuggedStruct.offsets.sort do |a, b|
+      a[1] <=> b[1]
+    end).to eq([[:visible, 0], [:x, 4], [:y, 8], [:rx, 12], [:ry, 14], [:order, 16], [:size, 17]])
+  end
+end
+
+describe "Struct allocation" do
+  it "MemoryPointer.new(Struct, 2)" do
+    class S < FFI::Struct
+      layout :i, :uint
+    end
+    p = FFI::MemoryPointer.new(S, 2)
+    expect(p.total).to eq(8)
+    expect(p.type_size).to eq(4)
+    p.put_uint(4, 0xdeadbeef)
+    expect(S.new(p[1])[:i]).to eq(0xdeadbeef)
+    expect(p[1].address).to eq((p[0].address + 4))
+  end
+
+  it "Buffer.new(Struct, 2)" do
+    class S < FFI::Struct
+      layout :i, :uint
+    end
+    p = FFI::Buffer.new(S, 2)
+    expect(p.total).to eq(8)
+    expect(p.type_size).to eq(4)
+    p.put_uint(4, 0xdeadbeef)
+    expect(S.new(p[1])[:i]).to eq(0xdeadbeef)
+  end
+
+  it "null? should be true when initialized with NULL pointer" do
+    class S < FFI::Struct
+      layout :i, :uint
+    end
+    expect(S.new(FFI::Pointer::NULL)).to be_null
+  end
+
+  it "null? should be false when initialized with non-NULL pointer" do
+    class S < FFI::Struct
+      layout :i, :uint
+    end
+    expect(S.new(FFI::MemoryPointer.new(S))).not_to be_null
+  end
+
+  it "supports :bool as a struct member" do
+    expect do
+      c = Class.new(FFI::Struct) do
+        layout :b, :bool
+      end
+      struct = c.new
+      struct[:b] = ! struct[:b]
+    end.not_to raise_error Exception
+  end
+
+end
+
+describe "variable-length arrays" do
+  it "zero length array should be accepted as last field" do
+    expect {
+      Class.new(FFI::Struct) do
+        layout :count, :int, :data, [ :char, 0 ]
+      end
+    }.not_to raise_error Exception
+  end
+
+  it "zero length array before last element should raise error" do
+    expect {
+      Class.new(FFI::Struct) do
+        layout :data, [ :char, 0 ], :count, :int
+      end
+    }.to raise_error
+  end
+
+  it "can access elements of array" do
+    struct_class = Class.new(FFI::Struct) do
+      layout :count, :int, :data, [ :long, 0 ]
+    end
+    s = struct_class.new(FFI::MemoryPointer.new(1024))
+    s[:data][0] = 0x1eadbeef
+    s[:data][1] = 0x12345678
+    expect(s[:data][0]).to eq(0x1eadbeef)
+    expect(s[:data][1]).to eq(0x12345678)
+  end
+
+  it "non-variable length array is bounds checked" do
+    struct_class = Class.new(FFI::Struct) do
+      layout :count, :int, :data, [ :long, 1 ]
+    end
+    s = struct_class.new(FFI::MemoryPointer.new(1024))
+    s[:data][0] = 0x1eadbeef
+    expect { s[:data][1] = 0x12345678 }.to raise_error
+    expect(s[:data][0]).to eq(0x1eadbeef)
+    expect { expect(s[:data][1]).to == 0x12345678 }.to raise_error
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/typedef_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/typedef_spec.rb
new file mode 100755
index 0000000..d73247f
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/typedef_spec.rb
@@ -0,0 +1,91 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+describe "Custom type definitions" do
+  it "attach_function with custom typedef" do
+    module CustomTypedef
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      typedef :uint, :fubar_t
+      attach_function :ret_u32, [ :fubar_t ], :fubar_t
+    end
+    expect(CustomTypedef.ret_u32(0x12345678)).to eq(0x12345678)
+  end
+
+  it "variadic invoker with custom typedef" do
+    module VariadicCustomTypedef
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      typedef :uint, :fubar_t
+      attach_function :pack_varargs, [ :buffer_out, :string, :varargs ], :void
+    end
+    buf = FFI::Buffer.new :uint, 10
+    VariadicCustomTypedef.pack_varargs(buf, "i", :fubar_t, 0x12345678)
+    expect(buf.get_int64(0)).to eq(0x12345678)
+  end
+
+  it "Callback with custom typedef parameter" do
+    module CallbackCustomTypedef
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      typedef :uint, :fubar3_t
+      callback :cbIrV, [ :fubar3_t ], :void
+      attach_function :testCallbackU32rV, :testClosureIrV, [ :cbIrV, :fubar3_t ], :void
+    end
+    i = 0
+    CallbackCustomTypedef.testCallbackU32rV(0xdeadbeef) { |v| i = v }
+    expect(i).to eq(0xdeadbeef)
+  end
+    module StructCustomTypedef
+      extend FFI::Library
+      ffi_lib TestLibrary::PATH
+      typedef :uint, :fubar3_t
+      class S < FFI::Struct
+        layout :a, :fubar3_t
+      end
+    end
+
+  it "Struct with custom typedef field" do
+    s = StructCustomTypedef::S.new
+    s[:a] = 0x12345678
+    expect(s.pointer.get_uint(0)).to eq(0x12345678)
+  end
+
+  it "attach_function after a typedef should not reject normal types" do
+    expect do
+      Module.new do
+        extend FFI::Library
+        # enum() will insert a custom typedef called :foo for the enum
+        enum :foo, [ :a, :b ]
+        typedef :int, :bar
+        
+        ffi_lib TestLibrary::PATH
+        begin
+          attach_function :ptr_ret_int32_t, [ :string, :foo ], :bar
+        rescue FFI::NotFoundError
+          # NetBSD uses #define instead of typedef for these
+          attach_function :ptr_ret_int32_t, :ptr_ret___int32_t, [ :string, :foo ], :bar
+        end
+      end
+    end.not_to raise_error
+  end
+
+  it "detects the correct type for size_t" do
+    expect do
+      Module.new do
+        extend FFI::Library
+        ffi_lib "c"
+        if FFI::Platform.windows?
+          # _read() is a function of msvcrt.dll
+          attach_function :_read, [:int, :pointer, :uint], :int
+        else
+          # read(2) is a standard UNIX function
+          attach_function :read, [:int, :pointer, :size_t], :ssize_t
+        end
+      end
+    end.not_to raise_error
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/union_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/union_spec.rb
new file mode 100755
index 0000000..45bf7ec
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/union_spec.rb
@@ -0,0 +1,67 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+module LibTest
+  Types = {
+    's8' => [:char, :c, 1],
+    's16' => [:short, :s, 0xff0], 
+    's32' => [:int, :i, 0xff00],
+    's64' => [:long_long, :j, 0xffff00],
+    'long' => [:long, :l, 0xffff],
+    'f32' => [:float, :f, 1.0001],
+    'f64' => [:double, :d, 1.000000001]
+  }
+  class TestUnion < FFI::Union
+    layout( :a, [:char, 10], 
+            :i, :int, 
+            :f, :float,
+            :d, :double,
+            :s, :short,
+            :l, :long,
+            :j, :long_long,
+            :c, :char )
+  end
+  Types.keys.each do |k| 
+    attach_function "union_align_#{k}", [ :pointer ], Types[k][0]
+    attach_function "union_make_union_with_#{k}", [ Types[k][0] ], :pointer
+  end
+  attach_function :union_size, [], :uint
+end
+
+describe 'Union' do
+  before do
+    @u = LibTest::TestUnion.new
+  end
+
+  it 'should place all the fields at offset 0' do
+    expect(LibTest::TestUnion.members.all? { |m| LibTest::TestUnion.offset_of(m) == 0 }).to be true
+  end
+  LibTest::Types.each do |k, type|
+    it "should correctly align/write a #{type[0]} value" do
+      @u[type[1]] = type[2]
+      if k == 'f32' or k == 'f64'
+        expect((@u[type[1]] - LibTest.send("union_align_#{k}", @u.to_ptr)).abs).to be < 0.00001
+      else
+        expect(@u[type[1]]).to eq(LibTest.send("union_align_#{k}", @u.to_ptr))
+      end
+    end
+  end
+  LibTest::Types.each do |k, type|
+    it "should read a #{type[0]} value from memory" do
+      @u = LibTest::TestUnion.new(LibTest.send("union_make_union_with_#{k}", type[2]))
+      if k == 'f32' or k == 'f64'
+        expect((@u[type[1]] - type[2]).abs).to be < 0.00001
+      else
+        expect(@u[type[1]]).to eq(type[2])
+      end
+    end
+  end
+
+  it 'should return a size equals to the size of the biggest field' do
+    expect(LibTest::TestUnion.size).to eq(LibTest.union_size)
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/ffi/variadic_spec.rb b/app/server/vendor/ffi-1.9.10/spec/ffi/variadic_spec.rb
new file mode 100755
index 0000000..4138280
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/ffi/variadic_spec.rb
@@ -0,0 +1,113 @@
+#
+# This file is part of ruby-ffi.
+# For licensing, see LICENSE.SPECS
+#
+
+require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
+
+describe "Function with variadic arguments" do
+  module LibTest
+    extend FFI::Library
+    ffi_lib TestLibrary::PATH
+    enum :enum_type1, [:c1, :c2]
+    enum :enum_type2, [:c3, 42, :c4]
+    attach_function :pack_varargs, [ :buffer_out, :string, :varargs ], :void
+    attach_function :pack_varargs2, [ :buffer_out, :enum_type1, :string, :varargs ], :enum_type1
+  end
+
+  it "takes enum arguments" do
+    buf = FFI::Buffer.new :long_long, 2
+    LibTest.pack_varargs(buf, "ii", :int, :c3, :int, :c4)
+    expect(buf.get_int64(0)).to eq(42)
+    expect(buf.get_int64(8)).to eq(43)
+  end
+
+  it "returns symbols for enums" do
+    buf = FFI::Buffer.new :long_long, 2
+    expect(LibTest.pack_varargs2(buf, :c1, "ii", :int, :c3, :int, :c4)).to eq(:c2)
+  end
+
+  [ 0, 127, -128, -1 ].each do |i|
+    it "call variadic with (:char (#{i})) argument" do
+      buf = FFI::Buffer.new :long_long
+      LibTest.pack_varargs(buf, "c", :char, i)
+      expect(buf.get_int64(0)).to eq(i)
+    end
+  end
+
+  [ 0, 0x7f, 0x80, 0xff ].each do |i|
+    it "call variadic with (:uchar (#{i})) argument" do
+      buf = FFI::Buffer.new :long_long
+      LibTest.pack_varargs(buf, "C", :uchar, i)
+      expect(buf.get_int64(0)).to eq(i)
+    end
+  end
+
+  [ 0, 1.234567, 9.87654321 ].each do |v|
+    it "call variadic with (:float (#{v})) argument" do
+      buf = FFI::Buffer.new :long_long
+      LibTest.pack_varargs(buf, "f", :float, v.to_f)
+      expect(buf.get_float64(0)).to eq(v)
+    end
+  end
+
+  [ 0, 1.234567, 9.87654321 ].each do |v|
+    it "call variadic with (:double (#{v})) argument" do
+      buf = FFI::Buffer.new :long_long
+      LibTest.pack_varargs(buf, "f", :double, v.to_f)
+      expect(buf.get_float64(0)).to eq(v)
+    end
+  end
+
+  module Varargs
+    PACK_VALUES = {
+      'c' => [ 0x12  ],
+      'C' => [ 0x34  ],
+      's' => [ 0x5678 ],
+      'S' => [ 0x9abc ],
+      'i' => [ 0x7654321f ],
+      'I' => [ 0xfee1babe ],
+      'l' => [ 0x1f2e3d4c ],
+      'L' => [ 0xf7e8d9ca ],
+      'j' => [ 0x1eafdeadbeefa1b2 ],
+      'f' => [ 1.23456789 ],
+      'd' => [ 9.87654321 ]
+    }
+
+    TYPE_MAP = {
+      'c' => :char, 'C' => :uchar, 's' => :short, 'S' => :ushort,
+      'i' => :int, 'I' => :uint, 'j' => :long_long, 'J' => :ulong_long,
+      'l' => :long, 'L' => :ulong, 'f' => :float, 'd' => :double
+    }
+  end
+
+  def verify(p, off, v)
+    if v.kind_of?(Float)
+      expect(p.get_float64(off)).to eq(v)
+    else
+      expect(p.get_int64(off)).to eq(v)
+    end
+  end
+
+  Varargs::PACK_VALUES.keys.each do |t1|
+    Varargs::PACK_VALUES.keys.each do |t2|
+      Varargs::PACK_VALUES.keys.each do |t3|
+        Varargs::PACK_VALUES[t1].each do |v1|
+          Varargs::PACK_VALUES[t2].each do |v2|
+            Varargs::PACK_VALUES[t3].each do |v3|
+              fmt = "#{t1}#{t2}#{t3}"
+              params = [ Varargs::TYPE_MAP[t1], v1, Varargs::TYPE_MAP[t2], v2, Varargs::TYPE_MAP[t3], v3 ]
+              it "call(#{fmt}, #{params.join(',')})" do
+                buf = FFI::Buffer.new :long_long, 3
+                LibTest.pack_varargs(buf, fmt, *params)
+                verify(buf, 0, v1)
+                verify(buf, 8, v2)
+                verify(buf, 16, v3)
+              end
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/ffi-1.9.10/spec/spec.opts b/app/server/vendor/ffi-1.9.10/spec/spec.opts
new file mode 100755
index 0000000..60a0245
--- /dev/null
+++ b/app/server/vendor/ffi-1.9.10/spec/spec.opts
@@ -0,0 +1,4 @@
+--color
+-w
+--format
+documentation
diff --git a/app/server/vendor/hamster-3.0.0/.gitignore b/app/server/vendor/hamster-3.0.0/.gitignore
new file mode 100755
index 0000000..1590768
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/.gitignore
@@ -0,0 +1,29 @@
+# See http://help.github.com/ignore-files/ for more about ignoring files.
+#
+# If you find yourself ignoring temporary files generated by your text editor
+# or operating system, you probably want to add a global ignore instead:
+#   git config --global core.excludesfile ~/.gitignore
+
+# Ignore all of the generated gem stuff
+/pkg
+/*.gem
+
+# Ignore bundler config
+/.bundle
+/Gemfile.lock
+
+# Ignore all bundler caching
+/vendor/cache
+/vendor/ruby
+
+# Ignore all tempfiles
+/tmp
+
+# Ignores that should be in the global gitignore
+/coverage
+/doc
+.yardoc
+
+# Sublime Text
+*.sublime-project
+*.sublime-workspace
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/.rspec b/app/server/vendor/hamster-3.0.0/.rspec
new file mode 100755
index 0000000..f28bac1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/.rspec
@@ -0,0 +1,4 @@
+--colour
+--format documentation
+--fail-fast
+--profile
diff --git a/app/server/vendor/hamster-3.0.0/.ruby-gemset b/app/server/vendor/hamster-3.0.0/.ruby-gemset
new file mode 100755
index 0000000..be840dc
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/.ruby-gemset
@@ -0,0 +1 @@
+hamster
diff --git a/app/server/vendor/hamster-3.0.0/.ruby-version b/app/server/vendor/hamster-3.0.0/.ruby-version
new file mode 100755
index 0000000..8bbe6cf
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/.ruby-version
@@ -0,0 +1 @@
+2.2
diff --git a/app/server/vendor/hamster-3.0.0/.travis.yml b/app/server/vendor/hamster-3.0.0/.travis.yml
new file mode 100755
index 0000000..690246b
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/.travis.yml
@@ -0,0 +1,14 @@
+language: ruby
+rvm:
+  - 1.9.3
+  - 2.0
+  - 2.1
+  - 2.2
+  - ruby-head
+  - jruby-9.0.0.0
+  - jruby-head
+  - rbx
+matrix:
+  allow_failures:
+    - rvm: ruby-head
+    - rvm: jruby-head
diff --git a/app/server/vendor/hamster-3.0.0/.yardopts b/app/server/vendor/hamster-3.0.0/.yardopts
new file mode 100755
index 0000000..ae7d3ad
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/.yardopts
@@ -0,0 +1,8 @@
+--no-private
+--markup=markdown
+--readme=YARD-README.md
+-
+LICENSE
+CHANGELOG.md
+FAQ.md
+CONDUCT.md
diff --git a/app/server/vendor/hamster-3.0.0/CHANGELOG.md b/app/server/vendor/hamster-3.0.0/CHANGELOG.md
new file mode 100755
index 0000000..9113442
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/CHANGELOG.md
@@ -0,0 +1,25 @@
+Changelog
+=========
+
+  - 3.0.0
+    * [Changed] the behavior of Hamster::Hash#values_at
+    * [Added] Hamster::Hash#dig and Hamster::Enumerable#grep_v
+    * [Added] Hamster::Enumerable#grep_v
+    * [Added] Hamster::Hash#>
+    * [Added] Hamster::Hash#>=
+    * [Added] Hamster::Hash#<
+
+  - 2.0.0
+    * [Removing] Hamster.deque since talking to the classes should be the main entry point
+    * [Removing] Hamster.mutable_set
+    * [Removing] Hamster.mutable_queue
+    * [Removing] Hamster.hash
+    * [Adding] an module for association behavior
+    * [Changing] Enumerable#to_list to a more susinct behavior
+    * [Adding] the Struct#to_h method if Struct doesn't have that method [< 1.9.3]
+    * [Changing] Freezing the result of allocating a Hamster::Deque
+    * [Documenting] the Hamster::Empty constants as private interfaces
+  - 1.0.0
+    * Specified benchmark-ips version
+  - 0.X.Y
+    * ...?
diff --git a/app/server/vendor/hamster-3.0.0/CONDUCT.md b/app/server/vendor/hamster-3.0.0/CONDUCT.md
new file mode 100755
index 0000000..d8bd234
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/CONDUCT.md
@@ -0,0 +1,48 @@
+# Contributor Code of Conduct
+
+As contributors and maintainers of this project, and in the interest of
+fostering an open and welcoming community, we pledge to respect all people who
+contribute through reporting issues, posting feature requests, updating
+documentation, submitting pull requests or patches, and other activities.
+
+We are committed to making participation in this project a harassment-free
+experience for everyone, regardless of level of experience, gender, gender
+identity and expression, sexual orientation, disability, personal appearance,
+body size, race, ethnicity, age, religion, or nationality.
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery
+* Personal attacks
+* Trolling or insulting/derogatory comments
+* Public or private harassment
+* Publishing other's private information, such as physical or electronic
+  addresses, without explicit permission
+* Other unethical or unprofessional conduct
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+By adopting this Code of Conduct, project maintainers commit themselves to
+fairly and consistently applying these principles to every aspect of managing
+this project. Project maintainers who do not follow or enforce the Code of
+Conduct may be permanently removed from the project team.
+
+This code of conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community.
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting a project maintainer at [me at kurtisrainboltgreene.name]. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. Maintainers are
+obligated to maintain confidentiality with regard to the reporter of an
+incident.
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 1.3.0, available at [http://contributor-covenant.org/version/1/3/0/][version].
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/3/0/
diff --git a/app/server/vendor/hamster-3.0.0/FAQ.md b/app/server/vendor/hamster-3.0.0/FAQ.md
new file mode 100755
index 0000000..1a1c68e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/FAQ.md
@@ -0,0 +1,92 @@
+FAQ
+===
+
+**But I still don't understand why I should care?**
+
+As mentioned earlier, persistent data structures perform a
+copy whenever they are modified meaning there is never any
+chance that two threads could be modifying the same instance
+at any one time. And, because they are very efficient copies,
+you don't need to worry about using up gobs of memory in the
+process.
+
+Even if threading isn't a concern, because they're immutable,
+you can pass them around between objects, methods, and
+functions in the same thread and never worry about data
+corruption; no more defensive calls to `Object#dup`!
+
+
+**What's the downside--there's always a downside?**
+
+There's a potential performance hit when compared with MRI's
+built-in, native, hand-crafted C-code implementation of Hash.
+
+For example:
+
+``` ruby
+hash = Hamster::Hash.empty
+(1..10000).each { |i| hash = hash.put(i, i) }
+  # => 0.05s
+(1..10000).each { |i| hash.get(i) }
+  # => 0.008s
+```
+
+vs.
+
+``` ruby
+hash = {}
+(1..10000).each { |i| hash[i] = i }
+  # => 0.004s
+(1..10000).each { |i| hash[i] }
+  # => 0.001s
+```
+
+The previous comparison wasn't really fair. Sure, if all you
+want to do is replace your existing uses of `Hash` in single-
+threaded environments then don't even bother. However, if you
+need something that can be used efficiently in concurrent
+environments where multiple threads are accessing--reading AND
+writing--the contents things get much better.
+
+A more realistic comparison might look like:
+
+``` ruby
+hash = Hamster::Hash.empty
+(1..10000).each { |i| hash = hash.put(i, i) }
+  # => 0.05s
+(1..10000).each { |i| hash.get(i) }
+  # => 0.008s
+```
+
+versus
+
+``` ruby
+hash = {}
+(1..10000).each { |i| hash = hash.dup; hash[i] = i }
+  # => 19.8s
+
+(1..10000).each { |i| hash[i] }
+  # => 0.001s
+```
+
+What's even better -- or worse depending on your perspective
+-- is that after all that, the native `Hash` version still
+isn't thread-safe and still requires some synchronization
+around it slowing it down even further.
+
+The Hamster version on the other hand was unchanged from the
+original whilst remaining inherently thread-safe, and 3 orders
+of magnitude faster.
+
+**You still need synchronisation so why bother with the copying?**
+
+Well, I could show you one but I'd have to re-write/wrap most
+Hash methods to make them generic, or at the very least write
+some application-specific code that synchronized using a `
+Mutex` and ... well ... it's hard, I always make mistakes,
+I always end up with weird edge cases and race conditions so,
+I'll leave that as an exercise for you :)
+
+And don't forget that even if threading isn't a concern for
+you, the safety provided by immutability alone is worth it,
+not to mention the lazy implementations.
diff --git a/app/server/vendor/hamster-3.0.0/Gemfile b/app/server/vendor/hamster-3.0.0/Gemfile
new file mode 100755
index 0000000..d6ab769
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/Gemfile
@@ -0,0 +1,5 @@
+#!/usr/bin/env ruby
+source "https://rubygems.org/"
+
+# Specify your gem's dependencies in hamster.gemspec
+gemspec
diff --git a/app/server/vendor/hamster-3.0.0/History.rdoc b/app/server/vendor/hamster-3.0.0/History.rdoc
new file mode 100755
index 0000000..de68ad7
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/History.rdoc
@@ -0,0 +1,419 @@
+=== 0.4.3 / 2012-10-01
+
+* Track size on Tries for performance (fredericksgary)
+* Hash#values should not return a set as there is no guarantee of uniqueness (and worse it means you potentially lose duplicate values). (fredericksgary)
+* Add Hash#slice, Hash#except, Hash#fetch (misfo)
+* Implemented a public Hash#new for subclassing (misfo)
+* Some initial benchmarks (haedius)
+* Documentation corrections (harukizaemon, szajbus, rwfowler)
+
+=== 0.4.2 / 2011-04-07
+
+* Added List#merge/merge_by to merge sorted lists into a single stream.
+* Added Enumerator#to_list produces a lazy list.
+* Alias List/Set#group_by as #group.
+
+=== 0.4.0 / 2010-12-13
+
+* Added initial implementation of Vector for efficient indexed access.
+
+* Fix car/cdr so they work on Ruby 1.8.7 (tianyicui)
+* Fix specs when running under 1.8.7 (tianyicui, kef)
+* Fix bundler/rvm support (kef)
+
+=== 0.3.10 / 2010-10-22
+
+* Update to RSpec 2.
+
+=== 0.3.9 / 2010-06-02
+
+* Implement Hash#values.
+
+=== 0.3.8 / 2010-06-02
+
+* Hash now accepts a block for supplying default values.
+
+=== 0.3.7 / 2010-05-16
+
+* Initial Queue implementation complete.
+
+* Implement Stack#peek.
+
+* Add Stack#enqueue, #dequeue to reflect the fact that a Stack is also a LIFO Queue.
+
+* Fix incompatibilities with Ruby 1.8.7 syntax.
+
+=== 0.3.6 / 2010-05-03
+
+* Hash#put now supports returning a value from a block instead of passing an explicit value. Almost like a substitute for the non-functional []=
+
+=== 0.3.4 / 2010-04-29
+
+* Reduce garbage collection by keeping a singleton instance of an empty hash.
+
+* Added some VERY experimental Read-Copy-Update collections (no tests).
+
+* Slightly improve performance and greatly improve the readability of #eql?/#== methods.
+
+* Added some VERY experimental memoization for immutable objects.
+
+* Added Set#merge as an alias for Set#union.
+
+* Implemented Hash#merge (aliased as #+).
+
+=== 0.3.3 / 2010-04-09
+
+* Fixed: hash code generation had VERY poor distribution.
+
+=== 0.3.1 / 2010-04-04
+
+* Fixed: Immutable not required in hamster.rb
+
+=== 0.3.0 / 2010-03-28
+
+* Add Hamster::Immutable as general purpose module to facililate immutability.
+
+* List, Stack, Set, and Hash now all implement Hamster::Immutable.
+
+=== 0.2.13 / 2010-03-25
+
+* Implement Hash#hash.
+
+* Implement Set#hash.
+
+* Implement List#hash.
+
+* Implement Set#flatten.
+
+=== 0.2.12 / 2010-03-01
+
+* Fixed bug: List#join accidentally modifying head if it was a string.
+
+=== 0.2.11 / 2010-02-15
+
+* Implement Set#one?
+
+* Implement Set#minimum (aliased as #min).
+
+* Implement Set#maximum (aliased as #max).
+
+* Implement Set#reduce with an optional memo.
+
+* Fix List#reduce should return nil when given no block and no starting value.
+
+=== 0.2.10 / 2010-02-15
+
+* Fix a bunch of spec failures under 1.8.7.
+
+* Remove some redundant object construction.
+
+=== 0.2.9 / 2010-02-11
+
+* Fix #to_list not available in all Enumerables.
+
+=== 0.2.8 / 2010-02-10
+
+* Implement Set#exclusion (aliased as #^) as equivalent to ((a | b) - (a & b)).
+
+* Implement Set#subset?
+
+* Implement Set#superset?
+
+* Implement Set#difference (aliased as #diff, #subtract, and #-).
+
+* Implement Set#intersection (aliased as #intersect and #&).
+
+* Implement Set#union (aliased as #| and #+).
+
+* Implement Set#union (aliased as #| and #+).
+
+* Remove Hash#[]= as its useless.
+
+=== 0.2.7 / 2010-02-08
+
+* Fixed bug with Hamster.interval (and Hamster.range) not handling Strings correctly.
+
+=== 0.2.6 / 2010-01-29
+
+* Implement Array#to_list.
+
+* Simplify (and improve performance of) conversions from arrays to lists.
+
+* Speed up Set and List sorting.
+
+* Implement Hash#find (aliased as #detect).
+
+* Implement List#elem_indices, List#find_indices (aliased as #indices as appropriate).
+
+* Implement List#index as per MRI and alias as #elem_index, and #find_index as appropriate.
+
+* Remove some redundant construction of streams.
+
+=== 0.2.5 / 2010-01-19
+
+* Implement Set#clear.
+
+* Implement List#slice (also aliased as #[from, length]).
+
+* Implement List#at (aliased as #[index]).
+
+=== 0.2.4 / 2010-01-18
+
+* Fix List#cadr and friends under JRuby.
+
+* Remove redundant locking (speed up).
+
+* Make reverse "lazy" (ish).
+
+* Fixed: StackOverflow calling List#head and List#tail on very large lazy lists.
+
+* Alias #reduce as #foldr.
+
+=== 0.2.3 / 2010-01-18
+
+* Implement Set#group_by.
+
+* Implement List#group_by.
+
+* Implement Hash#inspect.
+
+* Tuples can now be implicitly converted to args and variables via #to_ary, meaning you can do:
+
+   integers = Hamster.iterate(1, &:succ)
+   odds, evens = integers.partition(&:odd?)
+
+=== 0.2.2 / 2010-01-15
+
+* Implement List#flatten.
+
+* Implement List#each_slice (aliased as #each_chunk).
+
+* Return a tuple rather than a list for #split_at, #partition, #break, and #span.
+
+* Implement List#chunk.
+
+* Implement Set#compact.
+
+* Implement List#compact.
+
+=== 0.2.1 / 2010-01-15
+
+* Fix bug: List#empty? would cause a stack overflow on very large streams.
+
+=== 0.2.0 / 2010-01-14
+
+* List methods that return lists are now all lazy. Not sure what, if any, negative impact this will have but the positives have so far been well worth it.
+
+* Ensure List#eql? (and #==) doesn't accidentally consider an empty list to be equal to an empty array!
+
+* Ensure List responds_to? cadr and friends.
+
+* Stream now releases the block for garbage collection once called.
+
+* Implement List#combinations.
+
+* Implement List#inits.
+
+* Implement List#tails.
+
+* Implement Hash#uniq.
+
+* Alias #uniq as #remove_duplicates.
+
+* Alias #all? as #forall?
+
+* Implement Set#product.
+
+* Implement Set#sum.
+
+=== 0.1.23 / 2010-01-11
+
+* Implement List#product.
+
+* Implement List#sum.
+
+* Implement List#last.
+
+* Implement List#init.
+
+* Alias #reject as #remove.
+
+* Alias #each as #foreach.
+
+* Rename Hash#remove as Hash#delete.
+
+* Rename Set#remove as Set#delete.
+
+=== 0.1.22 / 2010-01-10
+
+* Implement List#union (aliased as #|).
+
+* Implement List#uniq (aliased as #nub).
+
+* Implement List#intersperse.
+
+* Alias #include? as #elem?
+
+* Implement Stack#to_list.
+
+* Implement Stack#to_a.
+
+* Implement Set#join.
+
+* Implement Set#count.
+
+* Implement List#count.
+
+* Alias #include? as #contains?
+
+* #each now returns nil if you specify a block.
+
+* Implement Set#find (aliased as #detect).
+
+=== 0.1.21 / 2010-01-08
+
+* Implement List#sort. (Very, VERY inefficient implementation!)
+
+* Implement List#sort_by. (Very, VERY inefficient implementation!)
+
+* Implement Set#to_set.
+
+* Implement Set#inspect.
+
+* Implement Set#first (aliased as #head).
+
+* Implement Set#sort. (Very, VERY inefficient implementation!)
+
+* Implement Set#sort_by. (Very, VERY inefficient implementation!)
+
+* Implement List#join.
+
+=== 0.1.20 / 2010-01-07
+
+* Implement Stack#clear.
+
+* Implement List#clear and Stack#clear.
+
+* Implement List#break.
+
+* Implement List#span.
+
+=== 0.1.19 / 2010-01-03
+
+* Bump minimum Ruby version to 1.8.7. I mean really, c'mon!
+
+=== 0.1.18 / 2010-01-03
+
+* Added gem development dependency on RSpec.
+
+=== 0.1.17 / 2010-01-02
+
+* Alias #empty? as #null?
+
+* Implement List#split_at.
+
+* Implement List.iterate.
+
+* Implement List#cycle.
+
+* Implement List.replicate.
+
+* Implement List.repeat.
+
+* Simplify List#take.
+
+* Simplify any?, all?, and none?
+
+* Re-write List#one? to be less complex.
+
+* Add Set#to_list.
+
+* Implement List#zip.
+
+* Implement Set#grep.
+
+* Implement Set#uniq (aliased as #nub).
+
+* Implement List#grep.
+
+=== 0.1.16 / 2009-12-30
+
+* Ensure streams cache results.
+
+* Ensure lists don't blow the stack.
+
+* List#entries is now an alias for List#to_a.
+
+* Implement List#to_list.
+
+* Implement List#one?.
+
+* Set#to_a is now aliased as #entries.
+
+* Implement List#minimum (aliased as #min) and List#maximum (aliased as #max).
+
+=== 0.1.15 / 2009-12-15
+
+* Implemented IO#to_list.
+
+* Implemented Enumerable#to_list.
+
+=== 0.1.14 / 2009-12-14
+
+* List#reduce supports optional initial value.
+
+* Implemented List#to_ary for implicit conversion to arrays and call parameters.
+
+* Implemented Set#to_a.
+
+* Alias #filter as #find_all.
+
+* Alias #reject as #delete_if.
+
+* Alias #reduce as #fold.
+
+=== 0.1.13 / 2009-12-10
+
+* Stack now fully functional
+
+=== 0.1.12 / 2009-12-10
+
+* List methods are now lazy where feasible
+
+* Now works under Ruby >= 1.8.6
+
+=== 0.1.8 / 2009-11-29
+
+* Add convenience constructors: List[], Set[], and Hash[]
+
+=== 0.1.7 / 2009-11-27
+
+* Implemented #eql?/== for Hash and Set.
+
+=== 0.1.6 / 2009-11-23
+
+* First cut at finishing implementation of Hash.
+
+=== 0.1.5 / 2009-11-5
+
+* Add some examples
+
+=== 0.1.4 / 2009-10-26
+
+* Simplify and share Trie between Hash and Set
+
+=== 0.1.3 / 2009-10-26
+
+* All known issues fixed.
+
+=== 0.1.2 / 2009-10-25
+
+* Fixed all but one outstanding issue with #remove
+
+=== 0.1.1 / 2009-10-23
+
+* Added #remove
+
+=== 0.1.0 / 2009-10-21
+
+* Initial version
diff --git a/app/server/vendor/hamster-3.0.0/LICENSE b/app/server/vendor/hamster-3.0.0/LICENSE
new file mode 100755
index 0000000..690a1f8
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/LICENSE
@@ -0,0 +1,23 @@
+Licensing
+=========
+
+Copyright (c) 2009-2014 Simon Harris
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/hamster-3.0.0/README.md b/app/server/vendor/hamster-3.0.0/README.md
new file mode 100755
index 0000000..3430ab3
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/README.md
@@ -0,0 +1,433 @@
+Hamster
+=======
+
+  - [![Quality](http://img.shields.io/codeclimate/github/hamstergem/hamster.svg?style=flat-square)](https://codeclimate.com/github/hamstergem/hamster)
+  - [![Coverage](http://img.shields.io/codeclimate/coverage/github/hamstergem/hamster.svg?style=flat-square)](https://codeclimate.com/github/hamstergem/hamster)
+  - [![Build](http://img.shields.io/travis-ci/hamstergem/hamster.svg?style=flat-square)](https://travis-ci.org/hamstergem/hamster)
+  - [![Dependencies](http://img.shields.io/gemnasium/hamstergem/hamster.svg?style=flat-square)](https://gemnasium.com/hamstergem/hamster)
+  - [![Downloads](http://img.shields.io/gem/dtv/hamster.svg?style=flat-square)](https://rubygems.org/gems/hamster)
+  - [![Tags](http://img.shields.io/github/tag/hamstergem/hamster.svg?style=flat-square)](http://github.com/hamstergem/hamster/tags)
+  - [![Releases](http://img.shields.io/github/release/hamstergem/hamster.svg?style=flat-square)](http://github.com/hamstergem/hamster/releases)
+  - [![Issues](http://img.shields.io/github/issues/hamstergem/hamster.svg?style=flat-square)](http://github.com/hamstergem/hamster/issues)
+  - [![License](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](http://opensource.org/licenses/MIT)
+  - [![Version](http://img.shields.io/gem/v/hamster.svg?style=flat-square)](https://rubygems.org/gems/hamster)
+  - [![Discuss](http://img.shields.io/badge/discuss-join%20gitter-brightgreen.svg?style=flat-square)](https://gitter.im/hamstergem/hamster)
+
+Efficient, immutable, and thread-safe collection classes for Ruby.
+
+Hamster provides 6 [Persistent Data
+Structures][PDS]: [`Hash`][HASH-DOC], [`Vector`][VECTOR-DOC], [`Set`][SET-DOC], [`SortedSet`][SORTED-SET-DOC], [`List`][LIST-DOC], and [`Deque`][DEQUE-DOC] (which works as an immutable queue or stack).
+
+Hamster collections are **immutable**. Whenever you modify a Hamster
+collection, the original is preserved and a modified copy is returned. This
+makes them inherently thread-safe and shareable. At the same time, they remain
+CPU and memory-efficient by sharing between copies. 
+
+While Hamster collections are immutable, you can still mutate objects stored
+in them. We recommend that  you don't do this, unless you are sure you know 
+what you are doing. Hamster collections are thread-safe and can be freely 
+shared between threads, but you are responsible for making sure that the 
+objects stored in them are used in a thread-safe manner.
+
+Hamster collections are almost always closed under a given operation. That is,
+whereas Ruby's collection methods always return arrays, Hamster collections
+will return an instance of the same class wherever possible.
+
+Where possible, Hamster collections offer an interface compatible with Ruby's
+built-in `Hash`, `Array`, and `Enumerable`, to ease code migration. Also, Hamster methods accept regular Ruby collections as arguments, so code which uses `Hamster` can easily interoperate with your other Ruby code.
+
+And lastly, Hamster lists are lazy, making it possible to (among other things)
+process "infinitely large" lists.
+
+[PDS]: http://en.wikipedia.org/wiki/Persistent_data_structure
+[HASH-DOC]: http://rubydoc.info/github/hamstergem/hamster/master/Hamster/Hash
+[SET-DOC]: http://rubydoc.info/github/hamstergem/hamster/master/Hamster/Set
+[VECTOR-DOC]: http://rubydoc.info/github/hamstergem/hamster/master/Hamster/Vector
+[LIST-DOC]: http://rubydoc.info/github/hamstergem/hamster/master/Hamster/List
+[SORTED-SET-DOC]: http://rubydoc.info/github/hamstergem/hamster/master/Hamster/SortedSet
+[DEQUE-DOC]: http://rubydoc.info/github/hamstergem/hamster/master/Hamster/Deque
+
+
+Using
+=====
+
+To make the collection classes available in your code:
+
+``` ruby
+require "hamster"
+```
+
+Or if you prefer to only pull in certain collection types:
+
+``` ruby
+require "hamster/hash"
+require "hamster/vector"
+require "hamster/set"
+require "hamster/sorted_set"
+require "hamster/list"
+require "hamster/deque"
+```
+
+<h2>Hash <span style="font-size:0.7em">(<a href="http://rubydoc.info/github/hamstergem/hamster/master/Hamster/Hash">API Documentation</a>)</span></h2>
+
+Constructing a Hamster `Hash` is almost as simple as a regular one:
+
+``` ruby
+person = Hamster::Hash[name: "Simon", gender: :male]
+# => Hamster::Hash[:name => "Simon", :gender => :male]
+```
+
+Accessing the contents will be familiar to you:
+
+``` ruby
+person[:name]                       # => "Simon"
+person.get(:gender)                 # => :male
+```
+
+Updating the contents is a little different than you are used to:
+
+``` ruby
+friend = person.put(:name, "James") # => Hamster::Hash[:name => "James", :gender => :male]
+person                              # => Hamster::Hash[:name => "Simon", :gender => :male]
+friend[:name]                       # => "James"
+person[:name]                       # => "Simon"
+```
+
+As you can see, updating the hash returned a copy leaving
+the original intact. Similarly, deleting a key returns
+yet another copy:
+
+``` ruby
+male = person.delete(:name)         # => Hamster::Hash[:gender => :male]
+person                              # => Hamster::Hash[:name => "Simon", :gender => :male]
+male.key?(:name)                    # => false
+person.key?(:name)                  # => true
+```
+
+Since it is immutable, Hamster's `Hash` doesn't provide an assignment
+(`Hash#[]=`) method. However, `Hash#put` can accept a block which
+transforms the value associated with a given key:
+
+``` ruby
+counters.put(:odds) { |value| value + 1 } # => Hamster::Hash[:odds => 1, :evens => 0]
+```
+
+Or more succinctly:
+
+``` ruby
+counters.put(:odds, &:next)         # => {:odds => 1, :evens => 0}
+```
+
+This is just the beginning; see the [API documentation][HASH-DOC] for details on all `Hash` methods.
+
+
+<h2>Vector <span style="font-size:0.7em">(<a href="http://rubydoc.info/github/hamstergem/hamster/master/Hamster/Vector">API Documentation</a>)</span></h2>
+
+A `Vector` is an integer-indexed collection much like an immutable `Array`. Examples:
+
+``` ruby
+vector = Hamster::Vector[1, 2, 3, 4] # => Hamster::Vector[1, 2, 3, 4]
+vector[0]                            # => 1
+vector[-1]                           # => 4
+vector.put(1, :a)                    # => Hamster::Vector[1, :a, 3, 4]
+vector.add(:b)                       # => Hamster::Vector[1, 2, 3, 4, :b]
+vector.insert(2, :a, :b)             # => Hamster::Vector[1, 2, :a, :b, 3, 4]
+vector.delete_at(0)                  # => Hamster::Vector[2, 3, 4]
+```
+
+Other `Array`-like methods like `#select`, `#map`, `#shuffle`, `#uniq`, `#reverse`,
+`#rotate`, `#flatten`, `#sort`, `#sort_by`, `#take`, `#drop`, `#take_while`,
+`#drop_while`, `#fill`, `#product`, and `#transpose` are also supported. See the
+[API documentation][VECTOR-DOC] for details on all `Vector` methods.
+
+
+<h2>Set <span style="font-size:0.7em">(<a href="http://rubydoc.info/github/hamstergem/hamster/master/Hamster/Set">API Documentation</a>)</span></h2>
+
+A `Set` is an unordered collection of values with no duplicates. It is much like the Ruby standard library's `Set`, but immutable. Examples:
+
+``` ruby
+set = Hamster::Set[:red, :blue, :yellow] # => Hamster::Set[:red, :blue, :yellow]
+set.include? :red                        # => true
+set.add :green                           # => Hamster::Set[:red, :blue, :yellow, :green]
+set.delete :blue                         # => Hamster::Set[:red, :yellow]
+set.superset? Hamster::Set[:red, :blue]  # => true
+set.union([:red, :blue, :pink])          # => Hamster::Set[:red, :blue, :yellow, :pink]
+set.intersection([:red, :blue, :pink])   # => Hamster::Set[:red, :blue]
+```
+
+Like most Hamster methods, the set-theoretic methods `#union`, `#intersection`, `#difference`, and `#exclusion` (aliased as `#|`, `#&`, `#-`, and `#^`) all work with regular Ruby collections, or indeed any `Enumerable` object. So just like all the other Hamster collections, `Hamster::Set` can easily be used in combination with "ordinary" Ruby code.
+
+See the [API documentation][SET-DOC] for details on all `Set` methods.
+
+
+<h2>SortedSet <span style="font-size:0.7em">(<a href="http://rubydoc.info/github/hamstergem/hamster/master/Hamster/SortedSet">API Documentation</a>)</span></h2>
+
+A `SortedSet` is like a `Set`, but ordered. You can do everything with it that you can
+do with a `Set`. Additionally, you can get the `#first` and `#last` item, or retrieve
+an item using an integral index:
+
+``` ruby
+set = Hamster::SortedSet['toast', 'jam', 'bacon'] # => Hamster::SortedSet["bacon", "jam", "toast"]
+set.first                                         # => "bacon"
+set.last                                          # => "toast"
+set[1]                                            # => "jam"
+```
+
+You can also specify the sort order using a block:
+
+``` ruby
+Hamster::SortedSet.new(['toast', 'jam', 'bacon']) { |a,b| b <=> a }
+Hamster::SortedSet.new(['toast', 'jam', 'bacon']) { |str| str.chars.last }
+```
+
+See the [API documentation][SORTED-SET-DOC] for details on all `SortedSet` methods.
+
+
+<h2>List <span style="font-size:0.7em">(<a href="http://rubydoc.info/github/hamstergem/hamster/master/Hamster/List">API Documentation</a>)</span></h2>
+
+Hamster `List`s have a *head* (the value at the front of the list),
+and a *tail* (a list of the remaining items):
+
+``` ruby
+list = Hamster::List[1, 2, 3]
+list.head                    # => 1
+list.tail                    # => Hamster::List[2, 3]
+```
+
+Add to a list with `List#add`:
+
+``` ruby
+original = Hamster::List[1, 2, 3]
+copy = original.add(0)      # => Hamster::List[0, 1, 2, 3]
+```
+
+Notice how modifying a list actually returns a new list.
+That's because Hamster `List`s are immutable.
+
+### Laziness
+
+`List` is lazy where possible. It tries to defer processing items until
+absolutely necessary. For example, given a crude function to detect prime
+numbers:
+
+``` ruby
+def prime?(number)
+  2.upto(Math.sqrt(number).round) do |integer|
+    return false if (number % integer).zero?
+  end
+  true
+end
+```
+
+The following code will only call `#prime?` as many times as
+necessary to generate the first 3 prime numbers between 10,000
+and 1,000,000:
+
+``` ruby
+Hamster.interval(10_000, 1_000_000).select do |number|
+  prime?(number)
+end.take(3)
+  # => 0.0009s
+```
+
+Compare that to the conventional equivalent which needs to
+calculate all possible values in the range before taking the
+first three:
+
+``` ruby
+(10000..1000000).select do |number|
+  prime?(number)
+end.take(3)
+  # => 10s
+```
+
+### Construction
+
+Besides `Hamster::List[]` there are other ways to construct lists:
+
+  - `Hamster.interval(from, to)` creates a lazy list
+    equivalent to a list containing all the values between
+    `from` and `to` without actually creating a list that big.
+
+  - `Hamster.stream { ... }` allows you to creates infinite
+    lists. Each time a new value is required, the supplied
+    block is called. To generate a list of integers you
+    could do:
+
+    ``` ruby
+    count = 0
+    Hamster.stream { count += 1 }
+    ```
+
+  - `Hamster.repeat(x)` creates an infinite list with `x` the
+    value for every element.
+
+  - `Hamster.replicate(n, x)` creates a list of size `n` with
+    `x` the value for every element.
+
+  - `Hamster.iterate(x) { |x| ... }` creates an infinite
+    list where the first item is calculated by applying the
+    block on the initial argument, the second item by applying
+    the function on the previous result and so on. For
+    example, a simpler way to generate a list of integers
+    would be:
+
+    ``` ruby
+    Hamster.iterate(1) { |i| i + 1 }
+    ```
+
+    or even more succinctly:
+
+    ``` ruby
+    Hamster.iterate(1, &:next)
+    ```
+
+  - `Hamster::List.empty` returns an empty list, which you can
+    build up using repeated calls to `#add` or other `List` methods.
+
+### Core Extensions
+
+`Enumerable#to_list` will convert any existing `Enumerable` to a list, so you can
+slowly transition from built-in collection classes to Hamster.
+
+`IO#to_list` enables lazy processing of huge files. For example, imagine the
+following code to process a 100MB file:
+
+``` ruby
+require 'hamster/core_ext'
+
+File.open("my_100_mb_file.txt") do |file|
+  lines = []
+  file.each_line do |line|
+    break if lines.size == 10
+    lines << line.chomp.downcase.reverse
+  end
+end
+```
+
+Compare to the following more functional version:
+
+``` ruby
+File.open("my_100_mb_file.txt") do |file|
+  file.map(&:chomp).map(&:downcase).map(&:reverse).take(10)
+end
+```
+
+Unfortunately, though the second example reads nicely it
+takes many seconds to run (compared with milliseconds
+for the first) even though we're only interested in the first
+ten lines. Using `#to_list` we can get the running time back comparable to the
+imperative version.
+
+``` ruby
+File.open("my_100_mb_file.txt") do |file|
+  file.to_list.map(&:chomp).map(&:downcase).map(&:reverse).take(10)
+end
+```
+
+This is possible because `IO#to_list` creates a lazy list whereby each line is
+only ever read and processed as needed, in effect converting it to the first
+example.
+
+See the API documentation for details on all [`List`][LIST-DOC] methods.
+
+
+<h2>Deque <span style="font-size:0.7em">(<a href="http://rubydoc.info/github/hamstergem/hamster/master/Hamster/Deque">API Documentation</a>)</span></h2>
+
+A `Deque` (or "double-ended queue") is an ordered collection, which allows you to push and pop items from both front and back. This makes it perfect as an immutable stack *or* queue. Examples:
+
+``` ruby
+deque = Hamster::Deque[1, 2, 3] # => Hamster::Deque[1, 2, 3]
+deque.first                     # 1
+deque.last                      # 3
+deque.pop                       # => Hamster::Deque[1, 2]
+deque.push(:a)                  # => Hamster::Deque[1, 2, 3, :a]
+deque.shift                     # => Hamster::Deque[2, 3]
+deque.unshift(:a)               # => Hamster::Deque[:a, 1, 2, 3]
+```
+
+Of course, you can do the same thing with a `Vector`, but a `Deque` is more efficient. See the API documentation for details on all [`Deque`][DEQUE-DOC] methods.
+
+
+<h2>Transformations</h2>
+
+Hamster arrays, hashes, and nested structures of arrays and hashes may be transformed with the `update_in` method.
+
+``` ruby
+c = Hamster.from({
+  people: [{name: 'Chris', city: 'Lagos'}, {name: 'Pat', city: 'Madrid'}],
+  places: [{name: 'Lagos', population: 1}, {name: 'Madrid', population: 1}]})
+c2 = c.update_in(:people, 1, :city) { |old_city| 'Lagos' }
+c3 = c2.update_in(:places, 1, :population) { |old_population| old_population - 1 }
+c4 = c3.update_in(:places, 0, :population) { |old_population| old_population + 1 }
+Hamster.to_ruby(c4)
+# => {:places=>[{:population=>2, :name=>"Lagos"}, {:population=>0, :name=>"Madrid"}], :people=>[{:name=>"Chris", :city=>"Lagos"}, {:name=>"Pat", :city=>"Lagos"}]}
+```
+
+Naturally, `update_in` never mutates your collections.
+
+See `Hamster::Hash#update_in`, `Hamster::Vector#update_in`, and `Hamster::Associable#update_in` for details.
+
+
+Installing
+==========
+
+Add this line to your application's Gemfile:
+
+    gem "hamster", "2.0.0"
+
+And then execute:
+
+    $ bundle
+
+Or install it yourself as:
+
+    $ gem install hamster
+
+
+Contributing
+============
+
+  1. Read the [Code of Conduct](/CONDUCT.md)
+  2. Fork it
+  3. Create your feature branch (`git checkout -b my-new-feature`)
+  4. Commit your changes (`git commit -am "Add some feature"`)
+  5. Push to the branch (`git push origin my-new-feature`)
+  6. Create new Pull Request
+
+
+Other Reading
+=============
+
+- The structure which is used for Hamster's `Hash` and `Set`: [Hash Array Mapped Tries][HAMT]
+- An interesting perspective on why immutability itself is inherently a good thing: Matthias Felleisen's [Function Objects presentation][FO].
+- The Hamster [FAQ](FAQ.md)
+- [Changelog](CHANGELOG.md)
+
+[HAMT]: http://lampwww.epfl.ch/papers/idealhashtrees.pdf
+[FO]: http://www.ccs.neu.edu/home/matthias/Presentations/ecoop2004.pdf
+
+
+Licensing
+=========
+
+Copyright (c) 2009-2015 Simon Harris
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/hamster-3.0.0/Rakefile b/app/server/vendor/hamster-3.0.0/Rakefile
new file mode 100755
index 0000000..ca5ad14
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/Rakefile
@@ -0,0 +1,112 @@
+#!/usr/bin/env rake
+require "bundler/gem_tasks"
+require "rspec/core/rake_task"
+require "yard"
+require "pathname"
+
+HAMSTER_ROOT = Pathname.new(__FILE__).dirname
+
+desc "Run all the tests in spec/"
+RSpec::Core::RakeTask.new(:spec) do |config|
+  config.verbose = false
+end
+
+desc "Generate all of the docs"
+YARD::Rake::YardocTask.new do |config|
+  config.files = Dir["lib/**/*.rb"]
+end
+
+def bench_suites
+  Dir[HAMSTER_ROOT.join('bench/*')].map(&method(:Pathname)).select(&:directory?)
+end
+
+def bench_files(suite)
+  Dir[File.join(suite, '/**/*.rb')].map(&method(:Pathname))
+end
+
+def bench_task_name(file_name)
+  file_name.relative_path_from(HAMSTER_ROOT).sub(/\_bench.rb$/, '').to_s.tr('/', ':')
+end
+
+bench_suites.each do |suite|
+  bench_files(suite).each do |bench_file|
+    name = bench_task_name(bench_file)
+
+    desc "Benchmark #{name}"
+    task name do
+      begin
+        $LOAD_PATH.unshift HAMSTER_ROOT.join('lib')
+        load bench_file
+      rescue LoadError => e
+        if e.message == /benchmark\/ips/
+          $stderr.puts "Please install the benchmark-ips gem"
+        else
+          $stderr.puts e
+        end
+        exit 69
+      end
+    end
+  end
+
+  desc "Benchmark #{bench_task_name(suite)}"
+  task bench_task_name(suite) => bench_files(suite).map(&method(:bench_task_name))
+end
+
+desc "Run all benchmarks"
+task bench: bench_suites.map(&method(:bench_task_name))
+
+desc "Generate file dependency graph"
+task :dependency_graph do
+  if `which dot`.empty?
+    raise "dot is not installed or not on your system path"
+  end
+
+  dependencies = Hash.new { |h,k| h[k] = Set.new }
+  trim_fn = ->(fn) { fn.sub(/^lib\//, '').sub(/\.rb$/, '') }
+
+  Dir["lib/**/*.rb"].each do |path|
+    File.readlines(path).each do |line|
+      if line =~ /^\s*require\s+('|")([^'"]*)('|")/
+         dependency = $2
+         dependencies[trim_fn[path]] << dependency
+      end
+    end
+  end
+
+  require 'set'
+  cycles    = Set.new
+  reachable = Hash.new { |h,k| h[k] = Set.new }
+  find_reachable = ->(from, to, pathsofar) do
+    to.each do |t|
+      if t == from
+        reachable[from].add(t)
+        pathsofar.push(t).each_cons(2) { |vector| cycles << vector }
+      elsif reachable[from].add?(t) && dependencies.key?(t)
+        find_reachable[from, dependencies[t], pathsofar.dup.push(t)]
+      end
+    end
+  end
+  dependencies.each { |from,to| find_reachable[from,to,[from]] }
+
+  dot = %|digraph { graph [label="Hamster srcfile dependencies"]\n|
+  dependencies.each do |from,to|
+    dot << %|"#{from}" [color=red]\n| if reachable[from].include?(from)
+    to.each do |t|
+      dot << %|"#{from}" -> "#{t}" #{'[color=red]' if cycles.include?([from,t])}\n|
+    end
+  end
+  dot << "\n}"
+
+  require "tempfile"
+  Tempfile.open("hamster-depgraph") do |f|
+    f.write(dot)
+    f.flush
+    message = `dot -Tgif #{f.path} -o depgraph.gif`
+    f.unlink
+    puts message unless message.empty?
+    puts "Dependency graph is in depgraph.gif"
+  end
+end
+
+desc "Default: run tests and generate docs"
+task default: [ :spec, :yard ]
diff --git a/app/server/vendor/hamster-3.0.0/YARD-README.md b/app/server/vendor/hamster-3.0.0/YARD-README.md
new file mode 100755
index 0000000..4dd58e8
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/YARD-README.md
@@ -0,0 +1,372 @@
+Hamster
+=======
+
+Efficient, immutable, and thread-safe collection classes for Ruby.
+
+Hamster provides 6 [Persistent Data
+Structures][PDS]: {Hamster::Hash Hash}, {Hamster::Vector Vector}, {Hamster::Set Set}, {Hamster::SortedSet SortedSet}, {Hamster::List List}, and {Hamster::Deque Deque} (which works as an immutable queue or stack).
+
+Hamster collections are **immutable**. Whenever you modify a Hamster
+collection, the original is preserved and a modified copy is returned. This
+makes them inherently thread-safe and shareable. At the same time, they remain
+CPU and memory-efficient by sharing between copies.
+
+While Hamster collections are immutable, you can still mutate objects stored
+in them. We recommend that  you don't do this, unless you are sure you know
+what you are doing. Hamster collections are thread-safe and can be freely
+shared between threads, but you are responsible for making sure that the
+objects stored in them are used in a thread-safe manner.
+
+Hamster collections are almost always closed under a given operation. That is,
+whereas Ruby's collection methods always return arrays, Hamster collections
+will return an instance of the same class wherever possible.
+
+Where possible, Hamster collections offer an interface compatible with Ruby's
+built-in `Hash`, `Array`, and `Enumerable`, to ease code migration. Also, Hamster methods accept regular Ruby collections as arguments, so code which uses `Hamster` can easily interoperate with your other Ruby code.
+
+And lastly, Hamster lists are lazy, making it possible to (among other things)
+process "infinitely large" lists.
+
+[PDS]: http://en.wikipedia.org/wiki/Persistent_data_structure
+
+
+Using
+=====
+
+To make the collection classes available in your code:
+
+``` ruby
+require "hamster"
+```
+
+Or if you prefer to only pull in certain collection types:
+
+``` ruby
+require "hamster/hash"
+require "hamster/vector"
+require "hamster/set"
+require "hamster/sorted_set"
+require "hamster/list"
+require "hamster/deque"
+```
+
+<h2>Hash <span style="font-size:0.7em">({Hamster::Hash API Documentation}</a>)</span></h2>
+
+Constructing a Hamster `Hash` is almost as simple as a regular one:
+
+``` ruby
+person = Hamster::Hash[name: "Simon", gender: :male]
+# => Hamster::Hash[:name => "Simon", :gender => :male]
+```
+
+Accessing the contents will be familiar to you:
+
+``` ruby
+person[:name]                       # => "Simon"
+person.get(:gender)                 # => :male
+```
+
+Updating the contents is a little different than you are used to:
+
+``` ruby
+friend = person.put(:name, "James") # => Hamster::Hash[:name => "James", :gender => :male]
+person                              # => Hamster::Hash[:name => "Simon", :gender => :male]
+friend[:name]                       # => "James"
+person[:name]                       # => "Simon"
+```
+
+As you can see, updating the hash returned a copy leaving
+the original intact. Similarly, deleting a key returns
+yet another copy:
+
+``` ruby
+male = person.delete(:name)         # => Hamster::Hash[:gender => :male]
+person                              # => Hamster::Hash[:name => "Simon", :gender => :male]
+male.key?(:name)                    # => false
+person.key?(:name)                  # => true
+```
+
+Since it is immutable, Hamster's `Hash` doesn't provide an assignment
+(`Hash#[]=`) method. However, `Hash#put` can accept a block which
+transforms the value associated with a given key:
+
+``` ruby
+counters.put(:odds) { |value| value + 1 } # => Hamster::Hash[:odds => 1, :evens => 0]
+```
+
+Or more succinctly:
+
+``` ruby
+counters.put(:odds, &:next)         # => {:odds => 1, :evens => 0}
+```
+
+This is just the beginning; see the {Hamster::Hash API documentation} for details on all `Hash` methods.
+
+
+<h2>Vector <span style="font-size:0.7em">({Hamster::Vector API Documentation})</span></h2>
+
+A `Vector` is an integer-indexed collection much like an immutable `Array`. Examples:
+
+``` ruby
+vector = Hamster::Vector[1, 2, 3, 4] # => Hamster::Vector[1, 2, 3, 4]
+vector[0]                            # => 1
+vector[-1]                           # => 4
+vector.put(1, :a)                    # => Hamster::Vector[1, :a, 3, 4]
+vector.add(:b)                       # => Hamster::Vector[1, 2, 3, 4, :b]
+vector.insert(2, :a, :b)             # => Hamster::Vector[1, 2, :a, :b, 3, 4]
+vector.delete_at(0)                  # => Hamster::Vector[2, 3, 4]
+```
+
+Other `Array`-like methods like `#select`, `#map`, `#shuffle`, `#uniq`, `#reverse`,
+`#rotate`, `#flatten`, `#sort`, `#sort_by`, `#take`, `#drop`, `#take_while`,
+`#drop_while`, `#fill`, `#product`, and `#transpose` are also supported. See the
+{Hamster::Vector API documentation} for details on all `Vector` methods.
+
+
+<h2>Set <span style="font-size:0.7em">({Hamster::Set API Documentation})</span></h2>
+
+A `Set` is an unordered collection of values with no duplicates. It is much like the Ruby standard library's `Set`, but immutable. Examples:
+
+``` ruby
+set = Hamster::Set[:red, :blue, :yellow] # => Hamster::Set[:red, :blue, :yellow]
+set.include? :red                        # => true
+set.add :green                           # => Hamster::Set[:red, :blue, :yellow, :green]
+set.delete :blue                         # => Hamster::Set[:red, :yellow]
+set.superset? Hamster::Set[:red, :blue]  # => true
+set.union([:red, :blue, :pink])          # => Hamster::Set[:red, :blue, :yellow, :pink]
+set.intersection([:red, :blue, :pink])   # => Hamster::Set[:red, :blue]
+```
+
+Like most Hamster methods, the set-theoretic methods `#union`, `#intersection`, `#difference`, and `#exclusion` (aliased as `#|`, `#&`, `#-`, and `#^`) all work with regular Ruby collections, or indeed any `Enumerable` object. So just like all the other Hamster collections, `Hamster::Set` can easily be used in combination with "ordinary" Ruby code.
+
+See the {Hamster::Set API documentation} for details on all `Set` methods.
+
+
+<h2>SortedSet <span style="font-size:0.7em">({Hamster::SortedSet API Documentation})</span></h2>
+
+A `SortedSet` is like a `Set`, but ordered. You can do everything with it that you can
+do with a `Set`. Additionally, you can get the `#first` and `#last` item, or retrieve
+an item using an integral index:
+
+``` ruby
+set = Hamster::SortedSet['toast', 'jam', 'bacon'] # => Hamster::SortedSet["bacon", "jam", "toast"]
+set.first                                         # => "bacon"
+set.last                                          # => "toast"
+set[1]                                            # => "jam"
+```
+
+You can also specify the sort order using a block:
+
+``` ruby
+Hamster::SortedSet.new(['toast', 'jam', 'bacon']) { |a,b| b <=> a }
+Hamster::SortedSet.new(['toast', 'jam', 'bacon']) { |str| str.chars.last }
+```
+
+See the {Hamster::SortedSet API documentation} for details on all `SortedSet` methods.
+
+
+<h2>List <span style="font-size:0.7em">({Hamster::List API Documentation})</span></h2>
+
+Hamster `List`s have a *head* (the value at the front of the list),
+and a *tail* (a list of the remaining items):
+
+``` ruby
+list = Hamster::List[1, 2, 3]
+list.head                    # => 1
+list.tail                    # => Hamster::List[2, 3]
+```
+
+Add to a list with {Hamster::List#add}:
+
+``` ruby
+original = Hamster::List[1, 2, 3]
+copy = original.add(0)      # => Hamster::List[0, 1, 2, 3]
+```
+
+Notice how modifying a list actually returns a new list.
+That's because Hamster `List`s are immutable.
+
+### Laziness
+
+`List` is lazy where possible. It tries to defer processing items until
+absolutely necessary. For example, given a crude function to detect prime
+numbers:
+
+``` ruby
+def prime?(number)
+  2.upto(Math.sqrt(number).round) do |integer|
+    return false if (number % integer).zero?
+  end
+  true
+end
+```
+
+The following code will only call `#prime?` as many times as
+necessary to generate the first 3 prime numbers between 10,000
+and 1,000,000:
+
+``` ruby
+Hamster.interval(10_000, 1_000_000).select do |number|
+  prime?(number)
+end.take(3)
+  # => 0.0009s
+```
+
+Compare that to the conventional equivalent which needs to
+calculate all possible values in the range before taking the
+first three:
+
+``` ruby
+(10000..1000000).select do |number|
+  prime?(number)
+end.take(3)
+  # => 10s
+```
+
+### Construction
+
+Besides `Hamster::List[]` there are other ways to construct lists:
+
+  - {Hamster.interval Hamster.interval(from, to)} creates a lazy list
+    equivalent to a list containing all the values between
+    `from` and `to` without actually creating a list that big.
+
+  - {Hamster.stream Hamster.stream { ... }} allows you to creates infinite
+    lists. Each time a new value is required, the supplied
+    block is called. To generate a list of integers you
+    could do:
+
+    ``` ruby
+    count = 0
+    Hamster.stream { count += 1 }
+    ```
+
+  - {Hamster.repeat Hamster.repeat(x)} creates an infinite list with `x` the
+    value for every element.
+
+  - {Hamster.replicate Hamster.replicate(n, x)} creates a list of size `n` with
+    `x` the value for every element.
+
+  - {Hamster.iterate Hamster.iterate(x) { |x| ... }} creates an infinite
+    list where the first item is calculated by applying the
+    block on the initial argument, the second item by applying
+    the function on the previous result and so on. For
+    example, a simpler way to generate a list of integers
+    would be:
+
+    ``` ruby
+    Hamster.iterate(1) { |i| i + 1 }
+    ```
+
+    or even more succinctly:
+
+    ``` ruby
+    Hamster.iterate(1, &:next)
+    ```
+  - {Hamster::List.empty} returns an empty list, which you can
+    build up using repeated calls to {Hamster::List#add #add} or other `List` methods.
+
+### Core Extensions
+
+{Enumerable#to_list} will convert any existing `Enumerable` to a list, so you can
+slowly transition from built-in collection classes to Hamster.
+
+{IO#to_list} enables lazy processing of huge files. For example, imagine the
+following code to process a 100MB file:
+
+``` ruby
+require 'hamster/core_ext'
+
+File.open("my_100_mb_file.txt") do |file|
+  lines = []
+  file.each_line do |line|
+    break if lines.size == 10
+    lines << line.chomp.downcase.reverse
+  end
+end
+```
+
+Compare to the following more functional version:
+
+``` ruby
+File.open("my_100_mb_file.txt") do |file|
+  file.map(&:chomp).map(&:downcase).map(&:reverse).take(10)
+end
+```
+
+Unfortunately, though the second example reads nicely it
+takes many seconds to run (compared with milliseconds
+for the first) even though we're only interested in the first
+ten lines. Using `#to_list` we can get the running time back comparable to the
+imperative version.
+
+``` ruby
+File.open("my_100_mb_file.txt") do |file|
+  file.to_list.map(&:chomp).map(&:downcase).map(&:reverse).take(10)
+end
+```
+
+This is possible because `IO#to_list` creates a lazy list whereby each line is
+only ever read and processed as needed, in effect converting it to the first
+example.
+
+See the {Hamster::List API documentation} for details on all List methods.
+
+
+<h2>Deque <span style="font-size:0.7em">({Hamster::Deque API Documentation})</span></h2>
+
+A `Deque` (or "double-ended queue") is an ordered collection, which allows you to push and pop items from both front and back. This makes it perfect as an immutable stack *or* queue. Examples:
+
+``` ruby
+deque = Hamster::Deque[1, 2, 3] # => Hamster::Deque[1, 2, 3]
+deque.first                     # 1
+deque.last                      # 3
+deque.pop                       # => Hamster::Deque[1, 2]
+deque.push(:a)                  # => Hamster::Deque[1, 2, 3, :a]
+deque.shift                     # => Hamster::Deque[2, 3]
+deque.unshift(:a)               # => Hamster::Deque[:a, 1, 2, 3]
+```
+
+Of course, you can do the same thing with a `Vector`, but a `Deque` is more efficient. See the {Hamster::Deque API documentation} for details on all Deque methods.
+
+<h2>Transformations</h2>
+
+Hamster arrays, hashes, and nested structures of arrays and hashes may be transformed with the `update_in` method.
+
+``` ruby
+c = Hamster.from({
+  people: [{name: 'Chris', city: 'Lagos'}, {name: 'Pat', city: 'Madrid'}],
+  places: [{name: 'Lagos', population: 1}, {name: 'Madrid', population: 1}]})
+c2 = c.update_in(:people, 1, :city) { |old_city| 'Lagos' }
+c3 = c2.update_in(:places, 1, :population) { |old_population| old_population - 1 }
+c4 = c3.update_in(:places, 0, :population) { |old_population| old_population + 1 }
+Hamster.to_ruby(c4)
+# => {:places=>[{:population=>2, :name=>"Lagos"}, {:population=>0, :name=>"Madrid"}], :people=>[{:name=>"Chris", :city=>"Lagos"}, {:name=>"Pat", :city=>"Lagos"}]}
+```
+
+Naturally, `update_in` never mutates your collections.
+
+See {Hamster::Hash#update_in}, {Hamster::Vector#update_in}, and {Hamster::Associable#update_in} for details.
+
+Contributing
+============
+
+  1. Fork it
+  2. Create your feature branch (`git checkout -b my-new-feature`)
+  3. Commit your changes (`git commit -am "Add some feature"`)
+  4. Push to the branch (`git push origin my-new-feature`)
+  5. Create new Pull Request
+
+
+Other Reading
+=============
+
+- The structure which is used for Hamster's `Hash` and `Set`: [Hash Array Mapped Tries][HAMT]
+- An interesting perspective on why immutability itself is inherently a good thing: Matthias Felleisen's [Function Objects presentation][FO].
+- The Hamster {file:FAQ.md FAQ}
+- {file:CHANGELOG.md Changelog}
+- {file:CONDUCT.md Contributor's Code of Conduct}
+- {file:LICENSE License}
+
+[HAMT]: http://lampwww.epfl.ch/papers/idealhashtrees.pdf
+[FO]: http://www.ccs.neu.edu/home/matthias/Presentations/ecoop2004.pdf
diff --git a/app/server/vendor/hamster-3.0.0/bench/hash/each_bench.rb b/app/server/vendor/hamster-3.0.0/bench/hash/each_bench.rb
new file mode 100755
index 0000000..5ca5e7e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/bench/hash/each_bench.rb
@@ -0,0 +1,37 @@
+require "benchmark/ips"
+require "hamster/hash"
+
+Benchmark.ips do |b|
+  sml_hash = Hamster::Hash[1 => 1]
+  med_hash = Hamster::Hash.empty
+  1_000.times { |i| med_hash = med_hash.put(i, i) }
+  lrg_hash = Hamster::Hash.empty
+  1_000_000.times { |i| lrg_hash = lrg_hash.put(i, i) }
+
+  b.report "each small" do |n|
+    a = 0
+    x = 0
+    while a < n
+      sml_hash.each { |y| x = y }
+      a += 1
+    end
+  end
+
+  b.report "each medium" do |n|
+    a = 0
+    x = 0
+    while a < n
+      med_hash.each { |y| x = y }
+      a += 1
+    end
+  end
+
+  b.report "each large" do |n|
+    a = 0
+    x = 0
+    while a < n
+      lrg_hash.each { |y| x = y }
+      a += 1
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/bench/hash/get_bench.rb b/app/server/vendor/hamster-3.0.0/bench/hash/get_bench.rb
new file mode 100755
index 0000000..b787238
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/bench/hash/get_bench.rb
@@ -0,0 +1,65 @@
+require "benchmark/ips"
+
+require "hamster/hash"
+
+Benchmark.ips do |b|
+  sml_hash = Hamster::Hash[1 => 1]
+  med_hash = Hamster::Hash.empty
+  1_000.times { |i| med_hash = med_hash.put(i, i) }
+  lrg_hash = Hamster::Hash.empty
+  1_000_000.times { |i| lrg_hash = lrg_hash.put(i, i) }
+
+  b.report "get existing small" do |n|
+    a = 0
+    x = 0
+    while a < n
+      x = sml_hash.get(a)
+      a += 1
+    end
+  end
+
+  b.report "get existing medium" do |n|
+    a = 0
+    x = nil
+    while a < n
+      x = med_hash.get(a)
+      a += 1
+    end
+  end
+
+  b.report "get existing large" do |n|
+    a = 0
+    x = nil
+    while a < n
+      x = lrg_hash.get(a)
+      a += 1
+    end
+  end
+
+  b.report "get missing small" do |n|
+    a = 0
+    x = 0
+    while a < n
+      x = sml_hash.get(-1)
+      a += 1
+    end
+  end
+
+  b.report "get existing medium" do |n|
+    a = 0
+    x = nil
+    while a < n
+      x = med_hash.get(-1)
+      a += 1
+    end
+  end
+
+  b.report "get existing large" do |n|
+    a = 0
+    x = nil
+    while a < n
+      x = lrg_hash.get(-1)
+      a += 1
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/bench/hash/put_bench.rb b/app/server/vendor/hamster-3.0.0/bench/hash/put_bench.rb
new file mode 100755
index 0000000..812e119
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/bench/hash/put_bench.rb
@@ -0,0 +1,37 @@
+require "benchmark/ips"
+require "hamster/hash"
+
+Benchmark.ips do |b|
+  sml_hash = Hamster::Hash[1 => 1]
+  med_hash = Hamster::Hash.empty
+  1_000.times { |i| med_hash = med_hash.put(i, i) }
+  lrg_hash = Hamster::Hash.empty
+  1_000_000.times { |i| lrg_hash = lrg_hash.put(i, i) }
+
+  b.report "put value" do |n|
+    a = 0
+    sml = sml_hash
+    while a < n
+      sml = sml.put(a, a)
+      a += 1
+    end
+  end
+
+  b.report "put value medium" do |n|
+    a = 0
+    med = med_hash
+    while a < n
+      med = med.put(a, a)
+      a += 1
+    end
+  end
+
+  b.report "put value large" do |n|
+    a = 0
+    lrg = lrg_hash
+    while a < n
+      lrg = lrg.put(a, a)
+      a += 1
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/bench/list/at_bench.rb b/app/server/vendor/hamster-3.0.0/bench/list/at_bench.rb
new file mode 100755
index 0000000..a52522e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/bench/list/at_bench.rb
@@ -0,0 +1,39 @@
+require "benchmark/ips"
+require "hamster/list"
+
+Benchmark.ips do |b|
+  sml_list = Hamster::List[1]
+  # med_list = Hamster.iterate(1, &:next).take(100)
+  # lrg_list = Hamster.iterate(1, &:next).take(10000)
+  med_list = Hamster::List.empty
+  100.times { |i| med_list = med_list.cons(i) }
+  lrg_list = Hamster::List.empty
+  10000.times { |i| lrg_list = lrg_list.cons(i) }
+
+  b.report "at small" do |n|
+    a = 0
+    x = 0
+    while a < n
+      x = sml_list.at(0)
+      a += 1
+    end
+  end
+
+  b.report "at medium" do |n|
+    a = 0
+    x = 0
+    while a < n
+      x = med_list.at(99)
+      a += 1
+    end
+  end
+
+  b.report "at large" do |n|
+    a = 0
+    x = 0
+    while a < n
+      x = lrg_list.at(9999)
+      a += 1
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/bench/list/cons_bench.rb b/app/server/vendor/hamster-3.0.0/bench/list/cons_bench.rb
new file mode 100755
index 0000000..1c34849
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/bench/list/cons_bench.rb
@@ -0,0 +1,37 @@
+require "benchmark/ips"
+require "hamster/list"
+
+Benchmark.ips do |b|
+  sml_list = Hamster::List[1]
+  med_list = Hamster::List.empty
+  100.times { |i| med_list = med_list.cons(i) }
+  lrg_list = Hamster::List.empty
+  10000.times { |i| lrg_list = lrg_list.cons(i) }
+
+  b.report "cons small" do |n|
+    a = 0
+    sml = sml_list
+    while a < n
+      sml = sml.cons(a)
+      a += 1
+    end
+  end
+
+  b.report "cons medium" do |n|
+    a = 0
+    med = med_list
+    while a < n
+      med = med.cons(a)
+      a += 1
+    end
+  end
+
+  b.report "cons large" do |n|
+    a = 0
+    lrg = lrg_list
+    while a < n
+      lrg = lrg.cons(a)
+      a += 1
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/bench/set/union_bench.rb b/app/server/vendor/hamster-3.0.0/bench/set/union_bench.rb
new file mode 100755
index 0000000..636c978
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/bench/set/union_bench.rb
@@ -0,0 +1,15 @@
+require "benchmark/ips"
+require "hamster/set"
+
+Benchmark.ips do |b|
+  small_set = Hamster::Set.new((1..10).to_a)
+  large_set = Hamster::Set.new((1..1000).to_a)
+
+  b.report "small.union(large)" do
+    small_set.union(large_set)
+  end
+
+  b.report "large.union(small)" do
+    large_set.union(small_set)
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/hamster.gemspec b/app/server/vendor/hamster-3.0.0/hamster.gemspec
new file mode 100755
index 0000000..eb6479d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/hamster.gemspec
@@ -0,0 +1,33 @@
+# coding: utf-8
+lib = File.expand_path("../lib", __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+require "hamster/version"
+
+Gem::Specification.new do |spec|
+  spec.name          = "hamster"
+  spec.version       = Hamster::VERSION
+  spec.authors       = ["Simon Harris"]
+  spec.email         = ["haruki_zaemon at mac.com"]
+  spec.summary       = %q{Efficient, immutable, thread-safe collection classes for Ruby}
+  spec.description   = spec.summary
+  spec.homepage      = "https://github.com/hamstergem/hamster"
+  spec.license       = "MIT"
+
+  spec.platform      = Gem::Platform::RUBY
+  spec.required_ruby_version = ">= 1.9.3"
+
+  spec.files         = Dir["lib/**/*", "LICENSE"]
+  spec.executables   = Dir["bin/**/*"].map! { |f| f.gsub(/bin\//, '') }
+  spec.test_files    = Dir["test/**/*", "spec/**/*"]
+  spec.require_paths = ["lib"]
+
+  spec.add_runtime_dependency     "concurrent-ruby", "~> 1.0"
+  spec.add_development_dependency "bundler", "~> 1.3"
+  spec.add_development_dependency "rspec", "~> 3.0"
+  spec.add_development_dependency "rake", "~> 10.1"
+  spec.add_development_dependency "yard", "~> 0.8"
+  spec.add_development_dependency "pry", "~> 0.9"
+  spec.add_development_dependency "pry-doc", "~> 0.6"
+  spec.add_development_dependency "benchmark-ips", "~> 2.1"
+  spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4"
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster.rb b/app/server/vendor/hamster-3.0.0/lib/hamster.rb
new file mode 100755
index 0000000..9236898
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster.rb
@@ -0,0 +1,12 @@
+require "hamster/core_ext"
+require "hamster/immutable"
+require "hamster/list"
+require "hamster/deque"
+require "hamster/hash"
+require "hamster/set"
+require "hamster/vector"
+require "hamster/sorted_set"
+require "hamster/mutable_hash"
+require "hamster/nested"
+require "hamster/version"
+require "hamster/associable"
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/associable.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/associable.rb
new file mode 100755
index 0000000..d960af5
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/associable.rb
@@ -0,0 +1,71 @@
+module Hamster
+  # Including `Associable` in your container class gives it an `update_in`
+  # method.
+  #
+  # To mix in `Associable`, your class must implement two methods:
+  #
+  # * `fetch(index, default = (missing_default = true))`
+  # * `put(index, item = yield(get(index)))`
+  # * `get(key)`
+  #
+  # See {Vector#fetch}, {Vector#put}, {Hash#fetch}, and {Hash#put} for examples.
+  module Associable
+    # Return a new container with a deeply nested value modified to the result
+    # of the given code block.  When traversing the nested containers
+    # non-existing keys are created with empty `Hash` values.
+    #
+    # The code block receives the existing value of the deeply nested key/index
+    # (or `nil` if it doesn't exist). This is useful for "transforming" the
+    # value associated with a certain key/index.
+    #
+    # Naturally, the original container and sub-containers are left unmodified;
+    # new data structure copies are created along the path as needed.
+    #
+    # @example
+    #   v = Hamster::Vector[123, 456, 789, Hamster::Hash["a" => Hamster::Vector[5, 6, 7]]]
+    #   v.update_in(3, "a", 1) { |value| value + 9 }
+    #   # => Hamster::Vector[123, 456, 789, Hamster::Hash["a" => Hamster::Vector[5, 15, 7]]]
+    #   hash = Hamster::Hash["a" => Hamster::Hash["b" => Hamster::Hash["c" => 42]]]
+    #   hash.update_in("a", "b", "c") { |value| value + 5 }
+    #   # => Hamster::Hash["a" => Hamster::Hash["b" => Hamster::Hash["c" => 47]]]
+    #
+    # @param key_path [Object(s)] List of keys/indexes which form the path to the key to be modified
+    # @yield [value] The previously stored value
+    # @yieldreturn [Object] The new value to store
+    # @return [Associable]
+    def update_in(*key_path, &block)
+      if key_path.empty?
+        raise ArgumentError, "must have at least one key in path"
+      end
+      key = key_path[0]
+      if key_path.size == 1
+        new_value = block.call(fetch(key, nil))
+      else
+        value = fetch(key, EmptyHash)
+        new_value = value.update_in(*key_path[1..-1], &block)
+      end
+      put(key, new_value)
+    end
+
+    # Return the value of successively indexing into a collection.
+    # If any of the keys is not present in the collection, return `nil`.
+    # keys that the Hamster type doesn't understand, raises an argument error
+    #
+    # @example
+    #   h = Hamster::Hash[:a => 9, :b => Hamster::Vector['a', 'b'], :e => nil]
+    #   h.dig(:b, 0)    # => "a"
+    #   h.dig(:b, 5)    # => nil
+    #   h.dig(:b, 0, 0) # => nil
+    #   h.dig(:b, :a)   # ArgumentError
+    # @params keys to fetch from the collection
+    # @return [Object]
+    def dig(key, *rest)
+      value = get(key)
+      if rest.empty? || value.nil?
+        value
+      elsif value.respond_to?(:dig)
+        value.dig(*rest)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/core_ext.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/core_ext.rb
new file mode 100755
index 0000000..2e599a9
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/core_ext.rb
@@ -0,0 +1,2 @@
+require "hamster/core_ext/enumerable"
+require "hamster/core_ext/io"
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/core_ext/enumerable.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/core_ext/enumerable.rb
new file mode 100755
index 0000000..a166acc
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/core_ext/enumerable.rb
@@ -0,0 +1,11 @@
+require "hamster/list"
+
+# Monkey-patches to Ruby's built-in `Enumerable` module.
+# @see http://www.ruby-doc.org/core/Enumerable.html
+module Enumerable
+  # Return a new {Hamster::List} populated with the items in this `Enumerable` object.
+  # @return [List]
+  def to_list
+    Hamster::List.from_enum(self)
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/core_ext/io.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/core_ext/io.rb
new file mode 100755
index 0000000..c6e9237
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/core_ext/io.rb
@@ -0,0 +1,21 @@
+require "hamster/list"
+
+# Monkey-patches to Ruby's built-in `IO` class.
+# @see http://www.ruby-doc.org/core/IO.html
+class IO
+  # Return a lazy list of "records" read from this IO stream.
+  # "Records" are delimited by `$/`, the global input record separator string.
+  # By default, it is `"\n"`, a newline.
+  #
+  # @return [List]
+  def to_list(sep = $/) # global input record separator
+    Hamster::LazyList.new do
+      line = gets(sep)
+      if line
+        Hamster::Cons.new(line, to_list)
+      else
+        EmptyList
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/core_ext/struct.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/core_ext/struct.rb
new file mode 100755
index 0000000..1278a24
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/core_ext/struct.rb
@@ -0,0 +1,9 @@
+class Struct
+  # Implement Struct#to_h for Ruby interpreters which don't have it
+  # (such as MRI 1.9.3 and lower)
+  unless method_defined?(:to_h)
+    def to_h
+      Hash[each_pair.to_a]
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/deque.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/deque.rb
new file mode 100755
index 0000000..419fb5f
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/deque.rb
@@ -0,0 +1,248 @@
+require "hamster/immutable"
+require "hamster/list"
+
+module Hamster
+
+  # A `Deque` (or double-ended queue) is an ordered, sequential collection of
+  # objects, which allows elements to be retrieved, added and removed at the
+  # front and end of the sequence in constant time. This makes `Deque` perfect
+  # for use as an immutable queue or stack.
+  #
+  # A `Deque` differs from a {Vector} in that vectors allow indexed access to
+  # any element in the collection. `Deque`s only allow access to the first and
+  # last element. But adding and removing from the ends of a `Deque` is faster
+  # than adding and removing from the ends of a {Vector}.
+  #
+  # To create a new `Deque`:
+  #
+  #     Hamster::Deque.new([:first, :second, :third])
+  #     Hamster::Deque[1, 2, 3, 4, 5]
+  #
+  # Or you can start with an empty deque and build it up:
+  #
+  #     Hamster::Deque.empty.push('b').push('c').unshift('a')
+  #
+  # Like all Hamster collections, `Deque` is immutable. The four basic
+  # operations that "modify" deques ({#push}, {#pop}, {#shift}, and
+  # {#unshift}) all return a new collection and leave the existing one
+  # unchanged.
+  #
+  # @example
+  #   deque = Hamster::Deque.empty                 # => Hamster::Deque[]
+  #   deque = deque.push('a').push('b').push('c')  # => Hamster::Deque['a', 'b', 'c']
+  #   deque.first                                  # => 'a'
+  #   deque.last                                   # => 'c'
+  #   deque = deque.shift                          # => Hamster::Deque['b', 'c']
+  #
+  # @see http://en.wikipedia.org/wiki/Deque "Deque" on Wikipedia
+  #
+  class Deque
+    include Immutable
+
+    class << self
+      # Create a new `Deque` populated with the given items.
+      # @return [Deque]
+      def [](*items)
+        items.empty? ? empty : new(items)
+      end
+
+      # Return an empty `Deque`. If used on a subclass, returns an empty instance
+      # of that class.
+      #
+      # @return [Deque]
+      def empty
+        @empty ||= self.new
+      end
+
+      # "Raw" allocation of a new `Deque`. Used internally to create a new
+      # instance quickly after consing onto the front/rear lists or taking their
+      # tails.
+      #
+      # @return [Deque]
+      # @private
+      def alloc(front, rear)
+        result = allocate
+        result.instance_variable_set(:@front, front)
+        result.instance_variable_set(:@rear,  rear)
+        result.freeze
+      end
+    end
+
+    def initialize(items=[])
+      @front = Hamster::List.from_enum(items)
+      @rear  = EmptyList
+    end
+
+    # Return `true` if this `Deque` contains no items.
+    # @return [Boolean]
+    def empty?
+      @front.empty? && @rear.empty?
+    end
+
+    # Return the number of items in this `Deque`.
+    #
+    # @example
+    #   Hamster::Deque["A", "B", "C"].size  #=> 3
+    #
+    # @return [Integer]
+    def size
+      @front.size + @rear.size
+    end
+    alias :length :size
+
+    # Return the first item in the `Deque`. If the deque is empty, return `nil`.
+    #
+    # @example
+    #   Hamster::Deque["A", "B", "C"].first  #=> "A"
+    #
+    # @return [Object]
+    def first
+      return @front.head unless @front.empty?
+      @rear.last # memoize?
+    end
+
+    # Return the last item in the `Deque`. If the deque is empty, return `nil`.
+    #
+    # @example
+    #   Hamster::Deque["A", "B", "C"].last  #=> "C"
+    #
+    # @return [Object]
+    def last
+      return @rear.head unless @rear.empty?
+      @front.last # memoize?
+    end
+
+    # Return a new `Deque` with `item` added at the end.
+    #
+    # @example
+    #   Hamster::Deque["A", "B", "C"].add("Z")
+    #   # => Hamster::Deque["A", "B", "C", "Z"]
+    #
+    # @param item [Object] The item to add
+    # @return [Deque]
+    def push(item)
+      self.class.alloc(@front, @rear.cons(item))
+    end
+    alias :enqueue :push
+
+    # Return a new `Deque` with the last item removed.
+    #
+    # @example
+    #   Hamster::Deque["A", "B", "C"].pop
+    #   # => Hamster::Deque["A", "B"]
+    #
+    # @return [Deque]
+    def pop
+      front, rear = @front, @rear
+
+      if rear.empty?
+        return self.class.empty if front.empty?
+        front, rear = EmptyList, front.reverse
+      end
+
+      self.class.alloc(front, rear.tail)
+    end
+
+    # Return a new `Deque` with `item` added at the front.
+    #
+    # @example
+    #   Hamster::Deque["A", "B", "C"].unshift("Z")
+    #   # => Hamster::Deque["Z", "A", "B", "C"]
+    #
+    # @param item [Object] The item to add
+    # @return [Deque]
+    def unshift(item)
+      self.class.alloc(@front.cons(item), @rear)
+    end
+
+    # Return a new `Deque` with the first item removed.
+    #
+    # @example
+    #   Hamster::Deque["A", "B", "C"].shift
+    #   # => Hamster::Deque["B", "C"]
+    #
+    # @return [Deque]
+    def shift
+      front, rear = @front, @rear
+
+      if front.empty?
+        return self.class.empty if rear.empty?
+        front, rear = rear.reverse, EmptyList
+      end
+
+      self.class.alloc(front.tail, rear)
+    end
+    alias :dequeue :shift
+
+    # Return an empty `Deque` instance, of the same class as this one. Useful if you
+    # have multiple subclasses of `Deque` and want to treat them polymorphically.
+    #
+    # @return [Deque]
+    def clear
+      self.class.empty
+    end
+
+    # Return true if `other` has the same type and contents as this `Deque`.
+    #
+    # @param other [Object] The collection to compare with
+    # @return [Boolean]
+    def eql?(other)
+      return true if other.equal?(self)
+      instance_of?(other.class) && to_ary.eql?(other.to_ary)
+    end
+    alias :== :eql?
+
+    # Return an `Array` with the same elements, in the same order.
+    # @return [Array]
+    def to_a
+      @front.to_a.concat(@rear.to_a.tap { |a| a.reverse! })
+    end
+    alias :entries :to_a
+    alias :to_ary  :to_a
+
+    # Return a {List} with the same elements, in the same order.
+    # @return [Hamster::List]
+    def to_list
+      @front.append(@rear.reverse)
+    end
+
+    # Return the contents of this `Deque` as a programmer-readable `String`. If all the
+    # items in the deque are serializable as Ruby literal strings, the returned string can
+    # be passed to `eval` to reconstitute an equivalent `Deque`.
+    #
+    # @return [String]
+    def inspect
+      result = "#{self.class}["
+      i = 0
+      @front.each { |obj| result << ', ' if i > 0; result << obj.inspect; i += 1 }
+      @rear.to_a.tap { |a| a.reverse! }.each { |obj| result << ', ' if i > 0; result << obj.inspect; i += 1 }
+      result << "]"
+    end
+
+    # @private
+    def pretty_print(pp)
+      pp.group(1, "#{self.class}[", "]") do
+        pp.breakable ''
+        pp.seplist(self.to_a) { |obj| obj.pretty_print(pp) }
+      end
+    end
+
+    # @return [::Array]
+    # @private
+    def marshal_dump
+      to_a
+    end
+
+    # @private
+    def marshal_load(array)
+      initialize(array)
+    end
+  end
+
+  # The canonical empty `Deque`. Returned by `Deque[]` when
+  # invoked with no arguments; also returned by `Deque.empty`. Prefer using this
+  # one rather than creating many empty deques using `Deque.new`.
+  #
+  # @private
+  EmptyDeque = Hamster::Deque.empty
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/enumerable.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/enumerable.rb
new file mode 100755
index 0000000..e3faace
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/enumerable.rb
@@ -0,0 +1,160 @@
+module Hamster
+  # Helper module for Hamster's sequential collections
+  #
+  # Classes including `Hamster::Enumerable` must implement:
+  #
+  # - `#each` (just like `::Enumerable`).
+  # - `#select`, which takes a block, and returns an instance of the same class
+  #     with only the items for which the block returns a true value
+  module Enumerable
+    include ::Enumerable
+
+    # Return a new collection with all the elements for which the block returns false.
+    def reject
+      return enum_for(:reject) if not block_given?
+      select { |item| !yield(item) }
+    end
+    alias :delete_if :reject
+
+    # Return a new collection with all `nil` elements removed.
+    def compact
+      select { |item| !item.nil? }
+    end
+
+    # Search the collection for elements which are `#===` to `item`. Yield them to
+    # the optional code block if provided, and return them as a new collection.
+    def grep(pattern, &block)
+      result = select { |item| pattern === item }
+      result = result.map(&block) if block_given?
+      result
+    end
+
+    # Search the collection for elements which are not `#===` to `item`. Yield
+    # them to the optional code block if provided, and return them as a new
+    # collection.
+    def grep_v(pattern, &block)
+      result = select { |item| !(pattern === item) }
+      result = result.map(&block) if block_given?
+      result
+    end
+
+    # Yield all integers from 0 up to, but not including, the number of items in
+    # this collection. For collections which provide indexed access, these are all
+    # the valid, non-negative indices into the collection.
+    def each_index(&block)
+      return enum_for(:each_index) unless block_given?
+      0.upto(size-1, &block)
+      self
+    end
+
+    # Multiply all the items (presumably numeric) in this collection together.
+    def product
+      reduce(1, &:*)
+    end
+
+    # Add up all the items (presumably numeric) in this collection.
+    def sum
+      reduce(0, &:+)
+    end
+
+    # Return 2 collections, the first containing all the elements for which the block
+    # evaluates to true, the second containing the rest.
+    def partition
+      return enum_for(:partition) if not block_given?
+      a,b = super
+      [self.class.new(a), self.class.new(b)].freeze
+    end
+
+    # Groups the collection into sub-collections by the result of yielding them to
+    # the block. Returns a {Hash} where the keys are return values from the block,
+    # and the values are sub-collections. All the sub-collections are built up from
+    # `empty_group`, which should respond to `#add` by returning a new collection
+    # with an added element.
+    def group_by_with(empty_group, &block)
+      block ||= lambda { |item| item }
+      reduce(EmptyHash) do |hash, item|
+        key = block.call(item)
+        group = hash.get(key) || empty_group
+        hash.put(key, group.add(item))
+      end
+    end
+    protected :group_by_with
+
+    # Groups the collection into sub-collections by the result of yielding them to
+    # the block. Returns a {Hash} where the keys are return values from the block,
+    # and the values are sub-collections (of the same type as this one).
+    def group_by(&block)
+      group_by_with(self.class.empty, &block)
+    end
+
+    # Compare with `other`, and return 0, 1, or -1 if it is (respectively) equal to,
+    # greater than, or less than this collection.
+    def <=>(other)
+      return 0 if self.equal?(other)
+      enum1, enum2 = self.to_enum, other.to_enum
+      loop do
+        item1 = enum1.next
+        item2 = enum2.next
+        comp  = (item1 <=> item2)
+        return comp if comp != 0
+      end
+      size1, size2 = self.size, other.size
+      return 0 if size1 == size2
+      size1 > size2 ? 1 : -1
+    end
+
+    # Return true if `other` contains the same elements, in the same order.
+    # @return [Boolean]
+    def ==(other)
+      self.eql?(other) || other.respond_to?(:to_ary) && to_ary.eql?(other.to_ary)
+    end
+
+    # Convert all the elements into strings and join them together, separated by
+    # `separator`. By default, the `separator` is `$,`, the global default string
+    # separator, which is normally `nil`.
+    def join(separator = $,)
+      result = ""
+      if separator
+        each_with_index { |obj, i| result << separator if i > 0; result << obj.to_s }
+      else
+        each { |obj| result << obj.to_s }
+      end
+      result
+    end
+
+    # Convert this collection to a {Set}.
+    def to_set
+      Set.new(self)
+    end
+
+    # Convert this collection to a programmer-readable `String` representation.
+    def inspect
+      result = "#{self.class}["
+      each_with_index { |obj, i| result << ', ' if i > 0; result << obj.inspect }
+      result << "]"
+    end
+
+    # @private
+    def pretty_print(pp)
+      pp.group(1, "#{self.class}[", "]") do
+        pp.breakable ''
+        pp.seplist(self) { |obj| obj.pretty_print(pp) }
+      end
+    end
+
+    alias :to_ary :to_a
+    alias :index :find_index
+
+    ## Compatibility fixes
+
+    if RUBY_ENGINE == 'rbx'
+      # Rubinius implements Enumerable#sort_by using Enumerable#map
+      # Because we do our own, custom implementations of #map, that doesn't work well
+      # @private
+      def sort_by(&block)
+        result = to_a
+        result.frozen? ? result.sort_by(&block) : result.sort_by!(&block)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/experimental/mutable_queue.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/experimental/mutable_queue.rb
new file mode 100755
index 0000000..ffca618
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/experimental/mutable_queue.rb
@@ -0,0 +1,26 @@
+require "hamster/deque"
+require "hamster/read_copy_update"
+
+module Hamster
+  # @api private
+  class MutableQueue
+    include ReadCopyUpdate
+
+    def self.[](*items)
+      MutableQueue.new(Deque[*items])
+    end
+
+    def enqueue(item)
+      transform { |queue| queue.enqueue(item) }
+    end
+
+    def dequeue
+      head = nil
+      transform do |queue|
+        head = queue.head
+        queue.dequeue
+      end
+      head
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/experimental/mutable_set.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/experimental/mutable_set.rb
new file mode 100755
index 0000000..44d88ea
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/experimental/mutable_set.rb
@@ -0,0 +1,40 @@
+require "hamster/set"
+require "hamster/read_copy_update"
+
+module Hamster
+  # @api private
+  class MutableSet
+    include ReadCopyUpdate
+
+    def self.[](*items)
+      MutableSet.new(Set[*items])
+    end
+
+    def add(item)
+      transform { |set| set.add(item) }
+    end
+    alias :<< :add
+
+    def add?(item)
+      added = false
+      transform do |set|
+        added = !set.include?(item)
+        set.add(item)
+      end
+      added
+    end
+
+    def delete(item)
+      transform { |set| set.delete(item) }
+    end
+
+    def delete?(item)
+      deleted = false
+      transform do |set|
+        deleted = set.include?(item)
+        set.delete(item)
+      end
+      deleted
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/hash.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/hash.rb
new file mode 100755
index 0000000..15a944e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/hash.rb
@@ -0,0 +1,899 @@
+require "hamster/immutable"
+require "hamster/undefined"
+require "hamster/enumerable"
+require "hamster/trie"
+require "hamster/set"
+require "hamster/vector"
+require "hamster/associable"
+
+module Hamster
+  # A `Hamster::Hash` maps a set of unique keys to corresponding values, much
+  # like a dictionary maps from words to definitions. Given a key, it can store
+  # and retrieve an associated value in constant time. If an existing key is
+  # stored again, the new value will replace the old. It behaves much like
+  # Ruby's built-in Hash, which we will call RubyHash for clarity. Like
+  # RubyHash, two keys that are `#eql?` to each other and have the same
+  # `#hash` are considered identical in a `Hamster::Hash`.
+  #
+  # A `Hamster::Hash` can be created in a couple of ways:
+  #
+  #     Hamster::Hash.new(font_size: 10, font_family: 'Arial')
+  #     Hamster::Hash[first_name: 'John', last_name: 'Smith']
+  #
+  # Any `Enumerable` object which yields two-element `[key, value]` arrays
+  # can be used to initialize a `Hamster::Hash`:
+  #
+  #     Hamster::Hash.new([[:first_name, 'John'], [:last_name, 'Smith']])
+  #
+  # Key/value pairs can be added using {#put}. A new hash is returned and the
+  # existing one is left unchanged:
+  #
+  #     hash = Hamster::Hash[a: 100, b: 200]
+  #     hash.put(:c, 500) # => Hamster::Hash[:a => 100, :b => 200, :c => 500]
+  #     hash              # => Hamster::Hash[:a => 100, :b => 200]
+  #
+  # {#put} can also take a block, which is used to calculate the value to be
+  # stored.
+  #
+  #     hash.put(:a) { |current| current + 200 } # => Hamster::Hash[:a => 300, :b => 200]
+  #
+  # Since it is immutable, all methods which you might expect to "modify" a
+  # `Hamster::Hash` actually return a new hash and leave the existing one
+  # unchanged. This means that the `hash[key] = value` syntax from RubyHash
+  # *cannot* be used with `Hamster::Hash`.
+  #
+  # Nested data structures can easily be updated using {#update_in}:
+  #
+  #     hash = Hamster::Hash["a" => Hamster::Vector[Hamster::Hash["c" => 42]]]
+  #     hash.update_in("a", 0, "c") { |value| value + 5 }
+  #     # => Hamster::Hash["a" => Hamster::Hash["b" => Hamster::Hash["c" => 47]]]
+  #
+  # While a `Hamster::Hash` can iterate over its keys or values, it does not
+  # guarantee any specific iteration order (unlike RubyHash). Methods like
+  # {#flatten} do not guarantee the order of returned key/value pairs.
+  #
+  # Like RubyHash, a `Hamster::Hash` can have a default block which is used
+  # when looking up a key that does not exist. Unlike RubyHash, the default
+  # block will only be passed the missing key, without the hash itself:
+  #
+  #     hash = Hamster::Hash.new { |missing_key| missing_key * 10 }
+  #     hash[5] # => 50
+  class Hash
+    include Immutable
+    include Enumerable
+    include Associable
+
+    class << self
+      # Create a new `Hash` populated with the given key/value pairs.
+      #
+      # @example
+      #   Hamster::Hash["A" => 1, "B" => 2] # => Hamster::Hash["A" => 1, "B" => 2]
+      #   Hamster::Hash[["A", 1], ["B", 2]] # => Hamster::Hash["A" => 1, "B" => 2]
+      #
+      # @param pairs [::Enumerable] initial content of hash. An empty hash is returned if not provided.
+      # @return [Hash]
+      def [](pairs = nil)
+        (pairs.nil? || pairs.empty?) ? empty : new(pairs)
+      end
+
+      # Return an empty `Hash`. If used on a subclass, returns an empty instance
+      # of that class.
+      #
+      # @return [Hash]
+      def empty
+        @empty ||= self.new
+      end
+
+      # "Raw" allocation of a new `Hash`. Used internally to create a new
+      # instance quickly after obtaining a modified {Trie}.
+      #
+      # @return [Hash]
+      # @private
+      def alloc(trie = EmptyTrie, block = nil)
+        obj = allocate
+        obj.instance_variable_set(:@trie, trie)
+        obj.instance_variable_set(:@default, block)
+        obj
+      end
+    end
+
+    # @param pairs [::Enumerable] initial content of hash. An empty hash is returned if not provided.
+    # @yield [key] Optional _default block_ to be stored and used to calculate the default value of a missing key. It will not be yielded during this method. It will not be preserved when marshalling.
+    # @yieldparam key Key that was not present in the hash.
+    def initialize(pairs = nil, &block)
+      @trie = pairs ? Trie[pairs] : EmptyTrie
+      @default = block
+    end
+
+    # Return the default block if there is one. Otherwise, return `nil`.
+    #
+    # @return [Proc]
+    def default_proc
+      @default
+    end
+
+    # Return the number of key/value pairs in this `Hash`.
+    #
+    # @example
+    #   Hamster::Hash["A" => 1, "B" => 2, "C" => 3].size  # => 3
+    #
+    # @return [Integer]
+    def size
+      @trie.size
+    end
+    alias :length :size
+
+    # Return `true` if this `Hash` contains no key/value pairs.
+    #
+    # @return [Boolean]
+    def empty?
+      @trie.empty?
+    end
+
+    # Return `true` if the given key object is present in this `Hash`. More precisely,
+    # return `true` if a key with the same `#hash` code, and which is also `#eql?`
+    # to the given key object is present.
+    #
+    # @example
+    #   Hamster::Hash["A" => 1, "B" => 2, "C" => 3].key?("B")  # => true
+    #
+    # @param key [Object] The key to check for
+    # @return [Boolean]
+    def key?(key)
+      @trie.key?(key)
+    end
+    alias :has_key? :key?
+    alias :include? :key?
+    alias :member?  :key?
+
+    # Return `true` if this `Hash` has one or more keys which map to the provided value.
+    #
+    # @example
+    #   Hamster::Hash["A" => 1, "B" => 2, "C" => 3].value?(2)  # => true
+    #
+    # @param value [Object] The value to check for
+    # @return [Boolean]
+    def value?(value)
+      each { |k,v| return true if value == v }
+      false
+    end
+    alias :has_value? :value?
+
+    # Retrieve the value corresponding to the provided key object. If not found, and
+    # this `Hash` has a default block, the default block is called to provide the
+    # value. Otherwise, return `nil`.
+    #
+    # @example
+    #   h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #   h["B"]             # => 2
+    #   h.get("B")         # => 2
+    #   h.get("Elephant")  # => nil
+    #
+    #   # Hamster Hash with a default proc:
+    #   h = Hamster::Hash.new("A" => 1, "B" => 2, "C" => 3) { |key| key.size }
+    #   h.get("B")         # => 2
+    #   h.get("Elephant")  # => 8
+    #
+    # @param key [Object] The key to look up
+    # @return [Object]
+    def get(key)
+      entry = @trie.get(key)
+      if entry
+        entry[1]
+      elsif @default
+        @default.call(key)
+      end
+    end
+    alias :[] :get
+
+    # Retrieve the value corresponding to the given key object, or use the provided
+    # default value or block, or otherwise raise a `KeyError`.
+    #
+    # @overload fetch(key)
+    #   Retrieve the value corresponding to the given key, or raise a `KeyError`
+    #   if it is not found.
+    #   @param key [Object] The key to look up
+    # @overload fetch(key) { |key| ... }
+    #   Retrieve the value corresponding to the given key, or call the optional
+    #   code block (with the missing key) and get its return value.
+    #   @yield [key] The key which was not found
+    #   @yieldreturn [Object] Object to return since the key was not found
+    #   @param key [Object] The key to look up
+    # @overload fetch(key, default)
+    #   Retrieve the value corresponding to the given key, or else return
+    #   the provided `default` value.
+    #   @param key [Object] The key to look up
+    #   @param default [Object] Object to return if the key is not found
+    #
+    # @example
+    #   h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #   h.fetch("B")         # => 2
+    #   h.fetch("Elephant")  # => KeyError: key not found: "Elephant"
+    #
+    #   # with a default value:
+    #   h.fetch("B", 99)         # => 2
+    #   h.fetch("Elephant", 99)  # => 99
+    #
+    #   # with a block:
+    #   h.fetch("B") { |key| key.size }         # => 2
+    #   h.fetch("Elephant") { |key| key.size }  # => 8
+    #
+    # @return [Object]
+    def fetch(key, default = Undefined)
+      entry = @trie.get(key)
+      if entry
+        entry[1]
+      elsif block_given?
+        yield(key)
+      elsif default != Undefined
+        default
+      else
+        raise KeyError, "key not found: #{key.inspect}"
+      end
+    end
+
+    # Return a new `Hash` with the existing key/value associations, plus an association
+    # between the provided key and value. If an equivalent key is already present, its
+    # associated value will be replaced with the provided one.
+    #
+    # If the `value` argument is missing, but an optional code block is provided,
+    # it will be passed the existing value (or `nil` if there is none) and what it
+    # returns will replace the existing value. This is useful for "transforming"
+    # the value associated with a certain key.
+    #
+    # Avoid mutating objects which are used as keys. `String`s are an exception:
+    # unfrozen `String`s which are used as keys are internally duplicated and
+    # frozen. This matches RubyHash's behaviour.
+    #
+    # @example
+    #   h = Hamster::Hash["A" => 1, "B" => 2]
+    #   h.put("C", 3)
+    #   # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #   h.put("B") { |value| value * 10 }
+    #   # => Hamster::Hash["A" => 1, "B" => 20]
+    #
+    # @param key [Object] The key to store
+    # @param value [Object] The value to associate it with
+    # @yield [value] The previously stored value, or `nil` if none.
+    # @yieldreturn [Object] The new value to store
+    # @return [Hash]
+    def put(key, value = yield(get(key)))
+      new_trie = @trie.put(key, value)
+      if new_trie.equal?(@trie)
+        self
+      else
+        self.class.alloc(new_trie, @default)
+      end
+    end
+
+    # Return a new `Hash` with a deeply nested value modified to the result of
+    # the given code block.  When traversing the nested `Hash`es and `Vector`s,
+    # non-existing keys are created with empty `Hash` values.
+    #
+    # The code block receives the existing value of the deeply nested key (or
+    # `nil` if it doesn't exist). This is useful for "transforming" the value
+    # associated with a certain key.
+    #
+    # Note that the original `Hash` and sub-`Hash`es and sub-`Vector`s are left
+    # unmodified; new data structure copies are created along the path wherever
+    # needed.
+    #
+    # @example
+    #   hash = Hamster::Hash["a" => Hamster::Hash["b" => Hamster::Hash["c" => 42]]]
+    #   hash.update_in("a", "b", "c") { |value| value + 5 }
+    #   # => Hamster::Hash["a" => Hamster::Hash["b" => Hamster::Hash["c" => 47]]]
+    #
+    # @param key_path [::Array<Object>] List of keys which form the path to the key to be modified
+    # @yield [value] The previously stored value
+    # @yieldreturn [Object] The new value to store
+    # @return [Hash]
+
+    # An alias for {#put} to match RubyHash's API. Does not support {#put}'s
+    # block form.
+    #
+    # @see #put
+    # @param key [Object] The key to store
+    # @param value [Object] The value to associate it with
+    # @return [Hash]
+    def store(key, value)
+      put(key, value)
+    end
+
+    # Return a new `Hash` with `key` removed. If `key` is not present, return
+    # `self`.
+    #
+    # @example
+    #   Hamster::Hash["A" => 1, "B" => 2, "C" => 3].delete("B")
+    #   # => Hamster::Hash["A" => 1, "C" => 3]
+    #
+    # @param key [Object] The key to remove
+    # @return [Hash]
+    def delete(key)
+      derive_new_hash(@trie.delete(key))
+    end
+
+    # Call the block once for each key/value pair in this `Hash`, passing the key/value
+    # pair as parameters. No specific iteration order is guaranteed, though the order will
+    # be stable for any particular `Hash`.
+    #
+    # @example
+    #   Hamster::Hash["A" => 1, "B" => 2, "C" => 3].each { |k, v| puts "k=#{k} v=#{v}" }
+    #
+    #   k=A v=1
+    #   k=C v=3
+    #   k=B v=2
+    #   # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #
+    # @yield [key, value] Once for each key/value pair.
+    # @return [self]
+    def each(&block)
+      return to_enum if not block_given?
+      @trie.each(&block)
+      self
+    end
+    alias :each_pair :each
+
+    # Call the block once for each key/value pair in this `Hash`, passing the key/value
+    # pair as parameters. Iteration order will be the opposite of {#each}.
+    #
+    # @example
+    #   Hamster::Hash["A" => 1, "B" => 2, "C" => 3].reverse_each { |k, v| puts "k=#{k} v=#{v}" }
+    #
+    #   k=B v=2
+    #   k=C v=3
+    #   k=A v=1
+    #   # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #
+    # @yield [key, value] Once for each key/value pair.
+    # @return [self]
+    def reverse_each(&block)
+      return enum_for(:reverse_each) if not block_given?
+      @trie.reverse_each(&block)
+      self
+    end
+
+    # Call the block once for each key/value pair in this `Hash`, passing the key as a
+    # parameter. Ordering guarantees are the same as {#each}.
+    #
+    # @example
+    #   Hamster::Hash["A" => 1, "B" => 2, "C" => 3].each_key { |k| puts "k=#{k}" }
+    #
+    #   k=A
+    #   k=C
+    #   k=B
+    #   # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #
+    # @yield [key] Once for each key/value pair.
+    # @return [self]
+    def each_key
+      return enum_for(:each_key) if not block_given?
+      @trie.each { |k,v| yield k }
+      self
+    end
+
+    # Call the block once for each key/value pair in this `Hash`, passing the value as a
+    # parameter. Ordering guarantees are the same as {#each}.
+    #
+    # @example
+    #   Hamster::Hash["A" => 1, "B" => 2, "C" => 3].each_value { |v| puts "v=#{v}" }
+    #
+    #   v=1
+    #   v=3
+    #   v=2
+    #   # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #
+    # @yield [value] Once for each key/value pair.
+    # @return [self]
+    def each_value
+      return enum_for(:each_value) if not block_given?
+      @trie.each { |k,v| yield v }
+      self
+    end
+
+    # Call the block once for each key/value pair in this `Hash`, passing the key/value
+    # pair as parameters. The block should return a `[key, value]` array each time.
+    # All the returned `[key, value]` arrays will be gathered into a new `Hash`.
+    #
+    # @example
+    #   h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #   h.map { |k, v| ["new-#{k}", v * v] }
+    #   # => Hash["new-C" => 9, "new-B" => 4, "new-A" => 1]
+    #
+    # @yield [key, value] Once for each key/value pair.
+    # @return [Hash]
+    def map
+      return enum_for(:map) unless block_given?
+      return self if empty?
+      self.class.new(super, &@default)
+    end
+    alias :collect :map
+
+    # Return a new `Hash` with all the key/value pairs for which the block returns true.
+    #
+    # @example
+    #   h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #   h.select { |k, v| v >= 2 }
+    #   # => Hamster::Hash["B" => 2, "C" => 3]
+    #
+    # @yield [key, value] Once for each key/value pair.
+    # @yieldreturn Truthy if this pair should be present in the new `Hash`.
+    # @return [Hash]
+    def select(&block)
+      return enum_for(:select) unless block_given?
+      derive_new_hash(@trie.select(&block))
+    end
+    alias :find_all :select
+    alias :keep_if  :select
+
+    # Yield `[key, value]` pairs until one is found for which the block returns true.
+    # Return that `[key, value]` pair. If the block never returns true, return `nil`.
+    #
+    # @example
+    #   h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #   h.find { |k, v| v.even? }
+    #   # => ["B", 2]
+    #
+    # @return [Array]
+    # @yield [key, value] At most once for each key/value pair, until the block returns `true`.
+    # @yieldreturn Truthy to halt iteration and return the yielded key/value pair.
+    def find
+      return enum_for(:find) unless block_given?
+      each { |entry| return entry if yield entry }
+      nil
+    end
+    alias :detect :find
+
+    # Return a new `Hash` containing all the key/value pairs from this `Hash` and
+    # `other`. If no block is provided, the value for entries with colliding keys
+    # will be that from `other`. Otherwise, the value for each duplicate key is
+    # determined by calling the block.
+    #
+    # `other` can be a `Hamster::Hash`, a built-in Ruby `Hash`, or any `Enumerable`
+    # object which yields `[key, value]` pairs.
+    #
+    # @example
+    #   h1 = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #   h2 = Hamster::Hash["C" => 70, "D" => 80]
+    #   h1.merge(h2)
+    #   # => Hamster::Hash["C" => 70, "A" => 1, "D" => 80, "B" => 2]
+    #   h1.merge(h2) { |key, v1, v2| v1 + v2 }
+    #   # => Hamster::Hash["C" => 73, "A" => 1, "D" => 80, "B" => 2]
+    #
+    # @param other [::Enumerable] The collection to merge with
+    # @yieldparam key [Object] The key which was present in both collections
+    # @yieldparam my_value [Object] The associated value from this `Hash`
+    # @yieldparam other_value [Object] The associated value from the other collection
+    # @yieldreturn [Object] The value to associate this key with in the new `Hash`
+    # @return [Hash]
+    def merge(other)
+      trie = if block_given?
+        other.reduce(@trie) do |trie, (key, value)|
+          if entry = trie.get(key)
+            trie.put(key, yield(key, entry[1], value))
+          else
+            trie.put(key, value)
+          end
+        end
+      else
+        @trie.bulk_put(other)
+      end
+
+      derive_new_hash(trie)
+    end
+
+    # Retrieve the value corresponding to the given key object, or use the provided
+    # default value or block, or otherwise raise a `KeyError`.
+    #
+    # @overload fetch(key)
+    #   Retrieve the value corresponding to the given key, or raise a `KeyError`
+    #   if it is not found.
+    #   @param key [Object] The key to look up
+    # @overload fetch(key) { |key| ... }
+
+    # Return a sorted {Vector} which contains all the `[key, value]` pairs in
+    # this `Hash` as two-element `Array`s.
+    #
+    # @overload sort
+    #   Uses `#<=>` to determine sorted order.
+    # @overload sort { |(k1, v1), (k2, v2)| ... }
+    #   Uses the block as a comparator to determine sorted order.
+    #
+    #   @example
+    #     h = Hamster::Hash["Dog" => 1, "Elephant" => 2, "Lion" => 3]
+    #     h.sort { |(k1, v1), (k2, v2)| k1.size  <=> k2.size }
+    #     # => Hamster::Vector[["Dog", 1], ["Lion", 3], ["Elephant", 2]]
+    #   @yield [(k1, v1), (k2, v2)] Any number of times with different pairs of key/value associations.
+    #   @yieldreturn [Integer] Negative if the first pair should be sorted
+    #                          lower, positive if the latter pair, or 0 if equal.
+    #
+    # @see ::Enumerable#sort
+    #
+    # @return [Vector]
+    def sort
+      Vector.new(super)
+    end
+
+    # Return a {Vector} which contains all the `[key, value]` pairs in this `Hash`
+    # as two-element Arrays. The order which the pairs will appear in is determined by
+    # passing each pair to the code block to obtain a sort key object, and comparing
+    # the sort keys using `#<=>`.
+    #
+    # @see ::Enumerable#sort_by
+    #
+    # @example
+    #   h = Hamster::Hash["Dog" => 1, "Elephant" => 2, "Lion" => 3]
+    #   h.sort_by { |key, value| key.size }
+    #   # => Hamster::Vector[["Dog", 1], ["Lion", 3], ["Elephant", 2]]
+    #
+    # @yield [key, value] Once for each key/value pair.
+    # @yieldreturn a sort key object for the yielded pair.
+    # @return [Vector]
+    def sort_by
+      Vector.new(super)
+    end
+
+    # Return a new `Hash` with the associations for all of the given `keys` removed.
+    #
+    # @example
+    #   h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #   h.except("A", "C")  # => Hamster::Hash["B" => 2]
+    #
+    # @param keys [Array] The keys to remove
+    # @return [Hash]
+    def except(*keys)
+      keys.reduce(self) { |hash, key| hash.delete(key) }
+    end
+
+    # Return a new `Hash` with only the associations for the `wanted` keys retained.
+    #
+    # @example
+    #   h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #   h.slice("B", "C")  # => Hamster::Hash["B" => 2, "C" => 3]
+    #
+    # @param wanted [::Enumerable] The keys to retain
+    # @return [Hash]
+    def slice(*wanted)
+      trie = Trie.new(0)
+      wanted.each { |key| trie.put!(key, get(key)) if key?(key) }
+      self.class.alloc(trie, @default)
+    end
+
+    # Return a {Vector} of the values which correspond to the `wanted` keys.
+    # If any of the `wanted` keys are not present in this `Hash`, `nil` will be
+    # placed instead, or the result of the default proc (if one is defined),
+    # similar to the behavior of {#get}.
+    #
+    # @example
+    #   h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #   h.values_at("B", "A", "D")  # => Hamster::Vector[2, 1, nil]
+    #
+    # @param wanted [Array] The keys to retrieve
+    # @return [Vector]
+    def values_at(*wanted)
+      array = wanted.map { |key| get(key) }
+      Vector.new(array.freeze)
+    end
+
+    # Return a {Vector} of the values which correspond to the `wanted` keys.
+    # If any of the `wanted` keys are not present in this `Hash`, raise `KeyError`
+    # exception.
+    #
+    # @example
+    #   h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #   h.fetch_values("C", "A")  # => Hamster::Vector[3, 1]
+    #   h.fetch_values("C", "Z")  # => KeyError: key not found: "Z"
+    #
+    # @param wanted [Array] The keys to retrieve
+    # @return [Vector]
+    def fetch_values(*wanted)
+      array = wanted.map { |key| fetch(key) }
+      Vector.new(array.freeze)
+    end
+
+    # Return a new {Set} containing the keys from this `Hash`.
+    #
+    # @example
+    #   Hamster::Hash["A" => 1, "B" => 2, "C" => 3, "D" => 2].keys
+    #   # => Hamster::Set["D", "C", "B", "A"]
+    #
+    # @return [Set]
+    def keys
+      Set.alloc(@trie)
+    end
+
+    # Return a new {Vector} populated with the values from this `Hash`.
+    #
+    # @example
+    #   Hamster::Hash["A" => 1, "B" => 2, "C" => 3, "D" => 2].values
+    #   # => Hamster::Vector[2, 3, 2, 1]
+    #
+    # @return [Vector]
+    def values
+      Vector.new(each_value.to_a.freeze)
+    end
+
+    # Return a new `Hash` created by using keys as values and values as keys.
+    # If there are multiple values which are equivalent (as determined by `#hash` and
+    # `#eql?`), only one out of each group of equivalent values will be
+    # retained. Which one specifically is undefined.
+    #
+    # @example
+    #   Hamster::Hash["A" => 1, "B" => 2, "C" => 3, "D" => 2].invert
+    #   # => Hamster::Hash[1 => "A", 3 => "C", 2 => "B"]
+    #
+    # @return [Hash]
+    def invert
+      pairs = []
+      each { |k,v| pairs << [v, k] }
+      self.class.new(pairs, &@default)
+    end
+
+    # Return a new {Vector} which is a one-dimensional flattening of this `Hash`.
+    # If `level` is 1, all the `[key, value]` pairs in the hash will be concatenated
+    # into one {Vector}. If `level` is greater than 1, keys or values which are
+    # themselves `Array`s or {Vector}s will be recursively flattened into the output
+    # {Vector}. The depth to which that flattening will be recursively applied is
+    # determined by `level`.
+    #
+    # As a special case, if `level` is 0, each `[key, value]` pair will be a
+    # separate element in the returned {Vector}.
+    #
+    # @example
+    #   h = Hamster::Hash["A" => 1, "B" => [2, 3, 4]]
+    #   h.flatten
+    #   # => Hamster::Vector["A", 1, "B", [2, 3, 4]]
+    #   h.flatten(2)
+    #   # => Hamster::Vector["A", 1, "B", 2, 3, 4]
+    #
+    # @param level [Integer] The number of times to recursively flatten the `[key, value]` pairs in this `Hash`.
+    # @return [Vector]
+    def flatten(level = 1)
+      return Vector.new(self) if level == 0
+      array = []
+      each { |k,v| array << k; array << v }
+      array.flatten!(level-1) if level > 1
+      Vector.new(array.freeze)
+    end
+
+    # Searches through the `Hash`, comparing `obj` with each key (using `#==`).
+    # When a matching key is found, return the `[key, value]` pair as an array.
+    # Return `nil` if no match is found.
+    #
+    # @example
+    #   Hamster::Hash["A" => 1, "B" => 2, "C" => 3].assoc("B")  # => ["B", 2]
+    #
+    # @param obj [Object] The key to search for (using #==)
+    # @return [Array]
+    def assoc(obj)
+      each { |entry| return entry if obj == entry[0] }
+      nil
+    end
+
+    # Searches through the `Hash`, comparing `obj` with each value (using `#==`).
+    # When a matching value is found, return the `[key, value]` pair as an array.
+    # Return `nil` if no match is found.
+    #
+    # @example
+    #   Hamster::Hash["A" => 1, "B" => 2, "C" => 3].rassoc(2)  # => ["B", 2]
+    #
+    # @param obj [Object] The value to search for (using #==)
+    # @return [Array]
+    def rassoc(obj)
+      each { |entry| return entry if obj == entry[1] }
+      nil
+    end
+
+    # Searches through the `Hash`, comparing `value` with each value (using `#==`).
+    # When a matching value is found, return its associated key object.
+    # Return `nil` if no match is found.
+    #
+    # @example
+    #   Hamster::Hash["A" => 1, "B" => 2, "C" => 3].key(2)  # => "B"
+    #
+    # @param value [Object] The value to search for (using #==)
+    # @return [Object]
+    def key(value)
+      each { |entry| return entry[0] if value == entry[1] }
+      nil
+    end
+
+    # Return a randomly chosen `[key, value]` pair from this `Hash`. If the hash is empty,
+    # return `nil`.
+    #
+    # @example
+    #   Hamster::Hash["A" => 1, "B" => 2, "C" => 3].sample
+    #   # => ["C", 3]
+    #
+    # @return [Array]
+    def sample
+      @trie.at(rand(size))
+    end
+
+    # Return an empty `Hash` instance, of the same class as this one. Useful if you
+    # have multiple subclasses of `Hash` and want to treat them polymorphically.
+    # Maintains the default block, if there is one.
+    #
+    # @return [Hash]
+    def clear
+      if @default
+        self.class.alloc(EmptyTrie, @default)
+      else
+        self.class.empty
+      end
+    end
+
+    # Return true if `other` has the same type and contents as this `Hash`.
+    #
+    # @param other [Object] The collection to compare with
+    # @return [Boolean]
+    def eql?(other)
+      return true if other.equal?(self)
+      instance_of?(other.class) && @trie.eql?(other.instance_variable_get(:@trie))
+    end
+
+    # Return true if `other` has the same contents as this `Hash`. Will convert
+    # `other` to a Ruby `Hash` using `#to_hash` if necessary.
+    #
+    # @param other [Object] The object to compare with
+    # @return [Boolean]
+    def ==(other)
+      self.eql?(other) || (other.respond_to?(:to_hash) && to_hash.eql?(other.to_hash))
+    end
+
+    # Return true if this `Hash` is a proper superset of `other`, which means
+    # all `other`'s keys are contained in this `Hash` with the identical
+    # values, and the two hashes are not identical.
+    #
+    # @param other [Hamster::Hash] The object to compare with
+    # @return [Boolean]
+    def >(other)
+      self != other && self >= other
+    end
+
+    # Return true if this `Hash` is a superset of `other`, which means all
+    # `other`'s keys are contained in this `Hash` with the identical values.
+    #
+    # @param other [Hamster::Hash] The object to compare with
+    # @return [Boolean]
+    def >=(other)
+      other.each do |key, value|
+        if self[key] != value
+          return false
+        end
+      end
+      true
+    end
+
+    # Return true if this `Hash` is a proper subset of `other`, which means all
+    # its keys are contained in `other` with the identical values, and the two
+    # hashes are not identical.
+    #
+    # @param other [Hamster::Hash] The object to compare with
+    # @return [Boolean]
+    def <(other)
+      other > self
+    end
+
+    # Return true if this `Hash` is a subset of `other`, which means all its
+    # keys are contained in `other` with the identical values, and the two
+    # hashes are not identical.
+    #
+    # @param other [Hamster::Hash] The object to compare with
+    # @return [Boolean]
+    def <=(other)
+      other >= self
+    end
+
+    # See `Object#hash`.
+    # @return [Integer]
+    def hash
+      keys.to_a.sort.reduce(0) do |hash, key|
+        (hash << 32) - hash + key.hash + get(key).hash
+      end
+    end
+
+    # Return the contents of this `Hash` as a programmer-readable `String`. If all the
+    # keys and values are serializable as Ruby literal strings, the returned string can
+    # be passed to `eval` to reconstitute an equivalent `Hash`. The default
+    # block (if there is one) will be lost when doing this, however.
+    #
+    # @return [String]
+    def inspect
+      result = "#{self.class}["
+      i = 0
+      each do |key, val|
+        result << ', ' if i > 0
+        result << key.inspect << ' => ' << val.inspect
+        i += 1
+      end
+      result << "]"
+    end
+
+    # Allows this `Hash` to be printed at the `pry` console, or using `pp` (from the
+    # Ruby standard library), in a way which takes the amount of horizontal space on
+    # the screen into account, and which indents nested structures to make them easier
+    # to read.
+    #
+    # @private
+    def pretty_print(pp)
+      pp.group(1, "#{self.class}[", "]") do
+        pp.breakable ''
+        pp.seplist(self, nil) do |key, val|
+          pp.group do
+            key.pretty_print(pp)
+            pp.text ' => '
+            pp.group(1) do
+              pp.breakable ''
+              val.pretty_print(pp)
+            end
+          end
+        end
+      end
+    end
+
+    # Convert this `Hamster::Hash` to an instance of Ruby's built-in `Hash`.
+    #
+    # @return [::Hash]
+    def to_hash
+      output = {}
+      each do |key, value|
+        output[key] = value
+      end
+      output
+    end
+    alias :to_h :to_hash
+
+    # Return a Proc which accepts a key as an argument and returns the value.
+    # The Proc behaves like {#get} (when the key is missing, it returns nil or
+    # result of the default proc).
+    #
+    # @example
+    #   h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #   h.to_proc.call("B")
+    #   # => 2
+    #   ["A", "C", "X"].map(&h)   # The & is short for .to_proc in Ruby
+    #   # => [1, 3, nil]
+    #
+    # @return [Proc]
+    def to_proc
+      lambda { |key| get(key) }
+    end
+
+    # @return [::Hash]
+    # @private
+    def marshal_dump
+      to_hash
+    end
+
+    # @private
+    def marshal_load(dictionary)
+      @trie = Trie[dictionary]
+    end
+
+    private
+
+    # Return a new `Hash` which is derived from this one, using a modified {Trie}.
+    # The new `Hash` will retain the existing default block, if there is one.
+    #
+    def derive_new_hash(trie)
+      if trie.equal?(@trie)
+        self
+      elsif trie.empty?
+        if @default
+          self.class.alloc(EmptyTrie, @default)
+        else
+          self.class.empty
+        end
+      else
+        self.class.alloc(trie, @default)
+      end
+    end
+  end
+
+  # The canonical empty `Hash`. Returned by `Hash[]` when
+  # invoked with no arguments; also returned by `Hash.empty`. Prefer using this
+  # one rather than creating many empty hashes using `Hash.new`.
+  #
+  # @private
+  EmptyHash = Hamster::Hash.empty
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/immutable.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/immutable.rb
new file mode 100755
index 0000000..2ebe9ae
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/immutable.rb
@@ -0,0 +1,75 @@
+module Hamster
+  # @private
+  module Immutable
+    def self.included(klass)
+      klass.extend(ClassMethods)
+      klass.instance_eval do
+        include InstanceMethods
+      end
+    end
+
+    # @private
+    module ClassMethods
+      def new(*args)
+        super.__send__(:immutable!)
+      end
+
+      def memoize(*names)
+        include MemoizeMethods unless include?(MemoizeMethods)
+        names.each do |name|
+          original_method = "__hamster_immutable_#{name}__"
+          alias_method original_method, name
+          class_eval <<-METHOD, __FILE__, __LINE__
+            def #{name}
+              if @__hamster_immutable_memory__.instance_variable_defined?(:@#{name})
+                @__hamster_immutable_memory__.instance_variable_get(:@#{name})
+              else
+                @__hamster_immutable_memory__.instance_variable_set(:@#{name}, #{original_method})
+              end
+            end
+          METHOD
+        end
+      end
+    end
+
+    # @private
+    module MemoizeMethods
+      def immutable!
+        @__hamster_immutable_memory__ = Object.new
+        freeze
+      end
+    end
+
+    # @private
+    module InstanceMethods
+      def immutable!
+        freeze
+      end
+
+      def immutable?
+        frozen?
+      end
+
+      alias_method :__hamster_immutable_dup__, :dup
+      private :__hamster_immutable_dup__
+
+      def dup
+        self
+      end
+
+      def clone
+        self
+      end
+
+      protected
+
+      def transform_unless(condition, &block)
+        condition ? self : transform(&block)
+      end
+
+      def transform(&block)
+        __hamster_immutable_dup__.tap { |copy| copy.instance_eval(&block) }.immutable!
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/list.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/list.rb
new file mode 100755
index 0000000..a3fa903
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/list.rb
@@ -0,0 +1,1595 @@
+require "thread"
+require "set"
+require "concurrent/atomics"
+
+require "hamster/undefined"
+require "hamster/enumerable"
+require "hamster/hash"
+require "hamster/set"
+
+module Hamster
+  class << self
+
+    # Create a lazy, infinite list.
+    #
+    # The given block is called as necessary to return successive elements of the list.
+    #
+    # @example
+    #   Hamster.stream { :hello }.take(3)
+    #   # => Hamster::List[:hello, :hello, :hello]
+    #
+    # @return [List]
+    def stream(&block)
+      return EmptyList unless block_given?
+      LazyList.new { Cons.new(yield, stream(&block)) }
+    end
+
+    # Construct a list of consecutive integers.
+    #
+    # @example
+    #   Hamster.interval(5,9)
+    #   # => Hamster::List[5, 6, 7, 8, 9]
+    #
+    # @param from [Integer] Start value, inclusive
+    # @param to [Integer] End value, inclusive
+    # @return [List]
+    def interval(from, to)
+      return EmptyList if from > to
+      interval_exclusive(from, to.next)
+    end
+
+    # Create an infinite list repeating the same item indefinitely
+    #
+    # @example
+    #   Hamster.repeat(:chunky).take(4)
+    #   => Hamster::List[:chunky, :chunky, :chunky, :chunky]
+    #
+    # @return [List]
+    def repeat(item)
+      LazyList.new { Cons.new(item, repeat(item)) }
+    end
+
+    # Create a list that contains a given item a fixed number of times
+    #
+    # @example
+    #   Hamster.replicate(3, :hamster)
+    #   #=> Hamster::List[:hamster, :hamster, :hamster]
+    #
+    # @return [List]
+    def replicate(number, item)
+      repeat(item).take(number)
+    end
+
+    # Create an infinite list where each item is derived from the previous one,
+    # using the provided block
+    #
+    # @example
+    #   Hamster.iterate(0) { |i| i.next }.take(5)
+    #   # => Hamster::List[0, 1, 2, 3, 4]
+    #
+    # @param [Object] item Starting value
+    # @yieldparam [Object] previous The previous value
+    # @yieldreturn [Object] The next value
+    # @return [List]
+    def iterate(item, &block)
+      LazyList.new { Cons.new(item, iterate(yield(item), &block)) }
+    end
+
+    # Turn an `Enumerator` into a `Hamster::List`. The result is a lazy
+    # collection where the values are memoized as they are generated.
+    #
+    # If your code uses multiple threads, you need to make sure that the returned
+    # lazy collection is realized on a single thread only. Otherwise, a `FiberError`
+    # will be raised. After the collection is realized, it can be used from other
+    # threads as well.
+    #
+    # @example
+    #   def rg; loop { yield rand(100) }; end
+    #   Hamster.enumerate(to_enum(:rg)).take(10)
+    #
+    # @param enum [Enumerator] The object to iterate over
+    # @return [List]
+    def enumerate(enum)
+      LazyList.new do
+        begin
+          Cons.new(enum.next, enumerate(enum))
+        rescue StopIteration
+          EmptyList
+        end
+      end
+    end
+
+    private
+
+    def interval_exclusive(from, to)
+      return EmptyList if from == to
+      LazyList.new { Cons.new(from, interval_exclusive(from.next, to)) }
+    end
+  end
+
+  # A `List` can be constructed with {List.[] List[]}, or {Enumerable#to_list}.
+  # It consists of a *head* (the first element) and a *tail* (which itself is also
+  # a `List`, containing all the remaining elements).
+  #
+  # This is a singly linked list. Prepending to the list with {List#add} runs
+  # in constant time. Traversing the list from front to back is efficient,
+  # however, indexed access runs in linear time because the list needs to be
+  # traversed to find the element.
+  #
+  module List
+    include Enumerable
+
+    # @private
+    CADR = /^c([ad]+)r$/
+
+    # Create a new `List` populated with the given items.
+    #
+    # @example
+    #   list = Hamster::List[:a, :b, :c]
+    #   # => Hamster::List[:a, :b, :c]
+    #
+    # @return [List]
+    def self.[](*items)
+      from_enum(items)
+    end
+
+    # Return an empty `List`.
+    #
+    # @return [List]
+    def self.empty
+      EmptyList
+    end
+
+    # This method exists distinct from `.[]` since it is ~30% faster
+    # than splatting the argument.
+    #
+    # Marking as private only because it was introduced for an internal
+    # refactoring. It could potentially be made public with a good name.
+    #
+    # @private
+    def self.from_enum(items)
+      # use destructive operations to build up a new list, like Common Lisp's NCONC
+      # this is a very fast way to build up a linked list
+      list = tail = Hamster::Cons.allocate
+      items.each do |item|
+        new_node = Hamster::Cons.allocate
+        new_node.instance_variable_set(:@head, item)
+        tail.instance_variable_set(:@tail, new_node)
+        tail = new_node
+      end
+      tail.instance_variable_set(:@tail, Hamster::EmptyList)
+      list.tail
+    end
+
+    # Return the number of items in this `List`.
+    # @return [Integer]
+    def size
+      result, list = 0, self
+      until list.empty?
+        if list.cached_size?
+          return result + list.size
+        else
+          result += 1
+        end
+        list = list.tail
+      end
+      result
+    end
+    alias :length :size
+
+    # Create a new `List` with `item` added at the front. This is a constant
+    # time operation.
+    #
+    # @example
+    #   Hamster::List[:b, :c].add(:a)
+    #   # => Hamster::List[:a, :b, :c]
+    #
+    # @param item [Object] The item to add
+    # @return [List]
+    def add(item)
+      Cons.new(item, self)
+    end
+    alias :cons :add
+
+    # Create a new `List` with `item` added at the end. This is much less efficient
+    # than adding items at the front.
+    #
+    # @example
+    #   Hamster::List[:a, :b] << :c
+    #   # => Hamster::List[:a, :b, :c]
+    #
+    # @param item [Object] The item to add
+    # @return [List]
+    def <<(item)
+      append(List[item])
+    end
+
+    # Call the given block once for each item in the list, passing each
+    # item from first to last successively to the block. If no block is given,
+    # returns an `Enumerator`.
+    #
+    # @return [self]
+    # @yield [item]
+    def each
+      return to_enum unless block_given?
+      list = self
+      until list.empty?
+        yield(list.head)
+        list = list.tail
+      end
+    end
+
+    # Return a `List` in which each element is derived from the corresponding
+    # element in this `List`, transformed through the given block. If no block
+    # is given, returns an `Enumerator`.
+    #
+    # @example
+    #   Hamster::List[3, 2, 1].map { |e| e * e } # => Hamster::List[9, 4, 1]
+    #
+    # @return [List, Enumerator]
+    # @yield [item]
+    def map(&block)
+      return enum_for(:map) unless block_given?
+      LazyList.new do
+        next self if empty?
+        Cons.new(yield(head), tail.map(&block))
+      end
+    end
+    alias :collect :map
+
+    # Return a `List` which is realized by transforming each item into a `List`,
+    # and flattening the resulting lists.
+    #
+    # @example
+    #   Hamster::List[1, 2, 3].flat_map { |x| Hamster::List[x, 100] }
+    #   # => Hamster::List[1, 100, 2, 100, 3, 100]
+    #
+    # @return [List]
+    def flat_map(&block)
+      return enum_for(:flat_map) unless block_given?
+      LazyList.new do
+        next self if empty?
+        head_list = List.from_enum(yield(head))
+        next tail.flat_map(&block) if head_list.empty?
+        Cons.new(head_list.first, head_list.drop(1).append(tail.flat_map(&block)))
+      end
+    end
+
+    # Return a `List` which contains all the items for which the given block
+    # returns true.
+    #
+    # @example
+    #   Hamster::List["Bird", "Cow", "Elephant"].select { |e| e.size >= 4 }
+    #   # => Hamster::List["Bird", "Elephant"]
+    #
+    # @return [List]
+    # @yield [item] Once for each item.
+    def select(&block)
+      return enum_for(:select) unless block_given?
+      LazyList.new do
+        list = self
+        while true
+          break list if list.empty?
+          break Cons.new(list.head, list.tail.select(&block)) if yield(list.head)
+          list = list.tail
+        end
+      end
+    end
+    alias :find_all :select
+    alias :keep_if  :select
+
+    # Return a `List` which contains all elements up to, but not including, the
+    # first element for which the block returns `nil` or `false`.
+    #
+    # @example
+    #   Hamster::List[1, 3, 5, 7, 6, 4, 2].take_while { |e| e < 5 }
+    #   # => Hamster::List[1, 3]
+    #
+    # @return [List, Enumerator]
+    # @yield [item]
+    def take_while(&block)
+      return enum_for(:take_while) unless block_given?
+      LazyList.new do
+        next self if empty?
+        next Cons.new(head, tail.take_while(&block)) if yield(head)
+        EmptyList
+      end
+    end
+
+    # Return a `List` which contains all elements starting from the
+    # first element for which the block returns `nil` or `false`.
+    #
+    # @example
+    #   Hamster::List[1, 3, 5, 7, 6, 4, 2].drop_while { |e| e < 5 }
+    #   # => Hamster::List[5, 7, 6, 4, 2]
+    #
+    # @return [List, Enumerator]
+    # @yield [item]
+    def drop_while(&block)
+      return enum_for(:drop_while) unless block_given?
+      LazyList.new do
+        list = self
+        list = list.tail while !list.empty? && yield(list.head)
+        list
+      end
+    end
+
+    # Return a `List` containing the first `number` items from this `List`.
+    #
+    # @example
+    #   Hamster::List[1, 3, 5, 7, 6, 4, 2].take(3)
+    #   # => Hamster::List[1, 3, 5]
+    #
+    # @param number [Integer] The number of items to retain
+    # @return [List]
+    def take(number)
+      LazyList.new do
+        next self if empty?
+        next Cons.new(head, tail.take(number - 1)) if number > 0
+        EmptyList
+      end
+    end
+
+    # Return a `List` containing all but the last item from this `List`.
+    #
+    # @example
+    #   Hamster::List["A", "B", "C"].pop  # => Hamster::List["A", "B"]
+    #
+    # @return [List]
+    def pop
+      LazyList.new do
+        next self if empty?
+        new_size = size - 1
+        next Cons.new(head, tail.take(new_size - 1)) if new_size >= 1
+        EmptyList
+      end
+    end
+
+    # Return a `List` containing all items after the first `number` items from
+    # this `List`.
+    #
+    # @example
+    #   Hamster::List[1, 3, 5, 7, 6, 4, 2].drop(3)
+    #   # => Hamster::List[7, 6, 4, 2]
+    #
+    # @param number [Integer] The number of items to skip over
+    # @return [List]
+    def drop(number)
+      LazyList.new do
+        list = self
+        while !list.empty? && number > 0
+          number -= 1
+          list = list.tail
+        end
+        list
+      end
+    end
+
+    # Return a `List` with all items from this `List`, followed by all items from
+    # `other`.
+    #
+    # @example
+    #   Hamster::List[1, 2, 3].append(Hamster::List[4, 5])
+    #   # => Hamster::List[1, 2, 3, 4, 5]
+    #
+    # @param other [List] The list to add onto the end of this one
+    # @return [List]
+    def append(other)
+      LazyList.new do
+        next other if empty?
+        Cons.new(head, tail.append(other))
+      end
+    end
+    alias :concat :append
+    alias :+ :append
+
+    # Return a `List` with the same items, but in reverse order.
+    #
+    # @example
+    #   Hamster::List["A", "B", "C"].reverse # => Hamster::List["C", "B", "A"]
+    #
+    # @return [List]
+    def reverse
+      LazyList.new { reduce(EmptyList) { |list, item| list.cons(item) }}
+    end
+
+    # Combine two lists by "zipping" them together.  The corresponding elements
+    # from this `List` and each of `others` (that is, the elements with the
+    # same indices) will be gathered into lists.
+    #
+    # If `others` contains fewer elements than this list, `nil` will be used
+    # for padding.
+    #
+    # @example
+    #   Hamster::List["A", "B", "C"].zip(Hamster::List[1, 2, 3])
+    #   # => Hamster::List[Hamster::List["A", 1], Hamster::List["B", 2], Hamster::List["C", 3]]
+    #
+    # @param others [List] The list to zip together with this one
+    # @return [List]
+    def zip(others)
+      LazyList.new do
+        next self if empty? && others.empty?
+        Cons.new(Cons.new(head, Cons.new(others.head)), tail.zip(others.tail))
+      end
+    end
+
+    # Gather the first element of each nested list into a new `List`, then the second
+    # element of each nested list, then the third, and so on. In other words, if each
+    # nested list is a "row", return a `List` of "columns" instead.
+    #
+    # Although the returned list is lazy, each returned nested list (each "column")
+    # is strict. So while each nested list in the input can be infinite, the parent
+    # `List` must not be, or trying to realize the first element in the output will
+    # cause an infinite loop.
+    #
+    # @example
+    #   # First let's create some infinite lists
+    #   list1 = Hamster.iterate(1, &:next)
+    #   list2 = Hamster.iterate(2) { |n| n * 2 }
+    #   list3 = Hamster.iterate(3) { |n| n * 3 }
+    #
+    #   # Now we transpose our 3 infinite "rows" into an infinite series of 3-element "columns"
+    #   Hamster::List[list1, list2, list3].transpose.take(4)
+    #   # => Hamster::List[
+    #   #      Hamster::List[1, 2, 3],
+    #   #      Hamster::List[2, 4, 9],
+    #   #      Hamster::List[3, 8, 27],
+    #   #      Hamster::List[4, 16, 81]]
+    #
+    # @return [List]
+    def transpose
+      return EmptyList if empty?
+      LazyList.new do
+        next EmptyList if any? { |list| list.empty? }
+        heads, tails = EmptyList, EmptyList
+        reverse_each { |list| heads, tails = heads.cons(list.head), tails.cons(list.tail) }
+        Cons.new(heads, tails.transpose)
+      end
+    end
+
+    # Concatenate an infinite series of copies of this `List` together into a
+    # new `List`. Or, if empty, just return an empty list.
+    #
+    # @example
+    #   Hamster::List[1, 2, 3].cycle.take(10)
+    #   # => Hamster::List[1, 2, 3, 1, 2, 3, 1, 2, 3, 1]
+    #
+    # @return [List]
+    def cycle
+      LazyList.new do
+        next self if empty?
+        Cons.new(head, tail.append(cycle))
+      end
+    end
+
+    # Return a new `List` with the same elements, but rotated so that the one at
+    # index `count` is the first element of the new list. If `count` is positive,
+    # the elements will be shifted left, and those shifted past the lowest position
+    # will be moved to the end. If `count` is negative, the elements will be shifted
+    # right, and those shifted past the last position will be moved to the beginning.
+    #
+    # @example
+    #   l = Hamster::List["A", "B", "C", "D", "E", "F"]
+    #   l.rotate(2)   # => Hamster::List["C", "D", "E", "F", "A", "B"]
+    #   l.rotate(-1)  # => Hamster::List["F", "A", "B", "C", "D", "E"]
+    #
+    # @param count [Integer] The number of positions to shift items by
+    # @return [Vector]
+    # @raise [TypeError] if count is not an integer.
+    def rotate(count = 1)
+      raise TypeError, "expected Integer" if not count.is_a?(Integer)
+      return self if empty? || (count % size) == 0
+      count = (count >= 0) ? count % size : (size - (~count % size) - 1)
+      drop(count).append(take(count))
+    end
+
+    # Return two `List`s, one of the first `number` items, and another with the
+    # remaining.
+    #
+    # @example
+    #   Hamster::List["a", "b", "c", "d"].split_at(2)
+    #   # => [Hamster::List["a", "b"], Hamster::List["c", "d"]]
+    #
+    # @param number [Integer] The index at which to split this list
+    # @return [Array]
+    def split_at(number)
+      [take(number), drop(number)].freeze
+    end
+
+    # Return two `List`s, one up to (but not including) the first item for which the
+    # block returns `nil` or `false`, and another of all the remaining items.
+    #
+    # @example
+    #   Hamster::List[4, 3, 5, 2, 1].span { |x| x > 2 }
+    #   # => [Hamster::List[4, 3, 5], Hamster::List[2, 1]]
+    #
+    # @return [Array]
+    # @yield [item]
+    def span(&block)
+      return [self, EmptyList].freeze unless block_given?
+      splitter = Splitter.new(self, block)
+      mutex = Mutex.new
+      [Splitter::Left.new(splitter, splitter.left, mutex),
+       Splitter::Right.new(splitter, mutex)].freeze
+    end
+
+    # Return two `List`s, one up to (but not including) the first item for which the
+    # block returns true, and another of all the remaining items.
+    #
+    # @example
+    #   Hamster::List[1, 3, 4, 2, 5].break { |x| x > 3 }
+    #   # => [Hamster::List[1, 3], Hamster::List[4, 2, 5]]
+    #
+    # @return [Array]
+    # @yield [item]
+    def break(&block)
+      return span unless block_given?
+      span { |item| !yield(item) }
+    end
+
+    # Return an empty `List`. If used on a subclass, returns an empty instance
+    # of that class.
+    #
+    # @return [List]
+    def clear
+      EmptyList
+    end
+
+    # Return a new `List` with the same items, but sorted.
+    #
+    # @overload sort
+    #   Compare elements with their natural sort key (`#<=>`).
+    #
+    #   @example
+    #     Hamster::List["Elephant", "Dog", "Lion"].sort
+    #     # => Hamster::List["Dog", "Elephant", "Lion"]
+    #
+    # @overload sort
+    #   Uses the block as a comparator to determine sorted order.
+    #
+    #   @yield [a, b] Any number of times with different pairs of elements.
+    #   @yieldreturn [Integer] Negative if the first element should be sorted
+    #                          lower, positive if the latter element, or 0 if
+    #                          equal.
+    #   @example
+    #     Hamster::List["Elephant", "Dog", "Lion"].sort { |a,b| a.size <=> b.size }
+    #     # => Hamster::List["Dog", "Lion", "Elephant"]
+    #
+    # @return [List]
+    def sort(&comparator)
+      LazyList.new { List.from_enum(super(&comparator)) }
+    end
+
+    # Return a new `List` with the same items, but sorted. The sort order is
+    # determined by mapping the items through the given block to obtain sort
+    # keys, and then sorting the keys according to their natural sort order
+    # (`#<=>`).
+    #
+    # @yield [element] Once for each element.
+    # @yieldreturn a sort key object for the yielded element.
+    # @example
+    #   Hamster::List["Elephant", "Dog", "Lion"].sort_by { |e| e.size }
+    #   # => Hamster::List["Dog", "Lion", "Elephant"]
+    #
+    # @return [List]
+    def sort_by(&transformer)
+      return sort unless block_given?
+      LazyList.new { List.from_enum(super(&transformer)) }
+    end
+
+    # Return a new `List` with `sep` inserted between each of the existing elements.
+    #
+    # @example
+    #   Hamster::List["one", "two", "three"].intersperse(" ")
+    #   # => Hamster::List["one", " ", "two", " ", "three"]
+    #
+    # @return [List]
+    def intersperse(sep)
+      LazyList.new do
+        next self if tail.empty?
+        Cons.new(head, Cons.new(sep, tail.intersperse(sep)))
+      end
+    end
+
+    # Return a `List` with the same items, but all duplicates removed.
+    # Use `#hash` and `#eql?` to determine which items are duplicates.
+    #
+    # @example
+    #   Hamster::List[:a, :b, :a, :c, :b].uniq      # => Hamster::List[:a, :b, :c]
+    #   Hamster::List["a", "A", "b"].uniq(&:upcase) # => Hamster::List["a", "b"]
+    #
+    # @return [List]
+    def uniq(&block)
+      _uniq(::Set.new, &block)
+    end
+
+    # @private
+    # Separate from `uniq` so as not to expose `items` in the public API.
+    def _uniq(items, &block)
+      if block_given?
+        LazyList.new do
+          next self if empty?
+          if items.add?(block.call(head))
+            Cons.new(head, tail._uniq(items, &block))
+          else
+            tail._uniq(items, &block)
+          end
+        end
+      else
+        LazyList.new do
+          next self if empty?
+          next tail._uniq(items) if items.include?(head)
+          Cons.new(head, tail._uniq(items.add(head)))
+        end
+      end
+    end
+    protected :_uniq
+
+    # Return a `List` with all the elements from both this list and `other`,
+    # with all duplicates removed.
+    #
+    # @example
+    #   Hamster::List[1, 2].union(Hamster::List[2, 3]) # => Hamster::List[1, 2, 3]
+    #
+    # @param other [List] The list to merge with
+    # @return [List]
+    def union(other, items = ::Set.new)
+      LazyList.new do
+        next other._uniq(items) if empty?
+        next tail.union(other, items) if items.include?(head)
+        Cons.new(head, tail.union(other, items.add(head)))
+      end
+    end
+    alias :| :union
+
+    # Return a `List` with all elements except the last one.
+    #
+    # @example
+    #   Hamster::List["a", "b", "c"].init # => Hamster::List["a", "b"]
+    #
+    # @return [List]
+    def init
+      return EmptyList if tail.empty?
+      LazyList.new { Cons.new(head, tail.init) }
+    end
+
+    # Return the last item in this list.
+    # @return [Object]
+    def last
+      list = self
+      list = list.tail until list.tail.empty?
+      list.head
+    end
+
+    # Return a `List` of all suffixes of this list.
+    #
+    # @example
+    #   Hamster::List[1,2,3].tails
+    #   # => Hamster::List[
+    #   #      Hamster::List[1, 2, 3],
+    #   #      Hamster::List[2, 3],
+    #   #      Hamster::List[3]]
+    #
+    # @return [List]
+    def tails
+      LazyList.new do
+        next self if empty?
+        Cons.new(self, tail.tails)
+      end
+    end
+
+    # Return a `List` of all prefixes of this list.
+    #
+    # @example
+    #   Hamster::List[1,2,3].inits
+    #   # => Hamster::List[
+    #   #      Hamster::List[1],
+    #   #      Hamster::List[1, 2],
+    #   #      Hamster::List[1, 2, 3]]
+    #
+    # @return [List]
+    def inits
+      LazyList.new do
+        next self if empty?
+        Cons.new(List[head], tail.inits.map { |list| list.cons(head) })
+      end
+    end
+
+    # Return a `List` of all combinations of length `n` of items from this `List`.
+    #
+    # @example
+    #   Hamster::List[1,2,3].combination(2)
+    #   # => Hamster::List[
+    #   #      Hamster::List[1, 2],
+    #   #      Hamster::List[1, 3],
+    #   #      Hamster::List[2, 3]]
+    #
+    # @return [List]
+    def combination(n)
+      return Cons.new(EmptyList) if n == 0
+      LazyList.new do
+        next self if empty?
+        tail.combination(n - 1).map { |list| list.cons(head) }.append(tail.combination(n))
+      end
+    end
+
+    # Split the items in this list in groups of `number`. Return a list of lists.
+    #
+    # @example
+    #   ("a".."o").to_list.chunk(5)
+    #   # => Hamster::List[
+    #   #      Hamster::List["a", "b", "c", "d", "e"],
+    #   #      Hamster::List["f", "g", "h", "i", "j"],
+    #   #      Hamster::List["k", "l", "m", "n", "o"]]
+    #
+    # @return [List]
+    def chunk(number)
+      LazyList.new do
+        next self if empty?
+        first, remainder = split_at(number)
+        Cons.new(first, remainder.chunk(number))
+      end
+    end
+
+    # Split the items in this list in groups of `number`, and yield each group
+    # to the block (as a `List`). If no block is given, returns an
+    # `Enumerator`.
+    #
+    # @return [self, Enumerator]
+    # @yield [list] Once for each chunk.
+    def each_chunk(number, &block)
+      return enum_for(:each_chunk, number) unless block_given?
+      chunk(number).each(&block)
+      self
+    end
+    alias :each_slice :each_chunk
+
+    # Return a new `List` with all nested lists recursively "flattened out",
+    # that is, their elements inserted into the new `List` in the place where
+    # the nested list originally was.
+    #
+    # @example
+    #   Hamster::List[Hamster::List[1, 2], Hamster::List[3, 4]].flatten
+    #   # => Hamster::List[1, 2, 3, 4]
+    #
+    # @return [List]
+    def flatten
+      LazyList.new do
+        next self if empty?
+        next head.append(tail.flatten) if head.is_a?(List)
+        Cons.new(head, tail.flatten)
+      end
+    end
+
+    # Passes each item to the block, and gathers them into a {Hash} where the
+    # keys are return values from the block, and the values are `List`s of items
+    # for which the block returned that value.
+    #
+    # @return [Hash]
+    # @yield [item]
+    # @example
+    #    Hamster::List["a", "b", "ab"].group_by { |e| e.size }
+    #    # Hamster::Hash[
+    #    #   1 => Hamster::List["b", "a"],
+    #    #   2 => Hamster::List["ab"]
+    #    # ]
+    def group_by(&block)
+      group_by_with(EmptyList, &block)
+    end
+    alias :group :group_by
+
+    # Retrieve the item at `index`. Negative indices count back from the end of
+    # the list (-1 is the last item). If `index` is invalid (either too high or
+    # too low), return `nil`.
+    #
+    # @param index [Integer] The index to retrieve
+    # @return [Object]
+    def at(index)
+      index += size if index < 0
+      return nil if index < 0
+      node = self
+      while index > 0
+        node = node.tail
+        index -= 1
+      end
+      node.head
+    end
+
+    # Return specific objects from the `List`. All overloads return `nil` if
+    # the starting index is out of range.
+    #
+    # @overload list.slice(index)
+    #   Returns a single object at the given `index`. If `index` is negative,
+    #   count backwards from the end.
+    #
+    #   @param index [Integer] The index to retrieve. May be negative.
+    #   @return [Object]
+    #   @example
+    #     l = Hamster::List["A", "B", "C", "D", "E", "F"]
+    #     l[2]  # => "C"
+    #     l[-1] # => "F"
+    #     l[6]  # => nil
+    #
+    # @overload list.slice(index, length)
+    #   Return a sublist starting at `index` and continuing for `length`
+    #   elements or until the end of the `List`, whichever occurs first.
+    #
+    #   @param start [Integer] The index to start retrieving items from. May be
+    #                          negative.
+    #   @param length [Integer] The number of items to retrieve.
+    #   @return [List]
+    #   @example
+    #     l = Hamster::List["A", "B", "C", "D", "E", "F"]
+    #     l[2, 3]  # => Hamster::List["C", "D", "E"]
+    #     l[-2, 3] # => Hamster::List["E", "F"]
+    #     l[20, 1] # => nil
+    #
+    # @overload list.slice(index..end)
+    #   Return a sublist starting at `index` and continuing to index
+    #   `end` or the end of the `List`, whichever occurs first.
+    #
+    #   @param range [Range] The range of indices to retrieve.
+    #   @return [Vector]
+    #   @example
+    #     l = Hamster::List["A", "B", "C", "D", "E", "F"]
+    #     l[2..3]    # => Hamster::List["C", "D"]
+    #     l[-2..100] # => Hamster::List["E", "F"]
+    #     l[20..21]  # => nil
+    def slice(arg, length = (missing_length = true))
+      if missing_length
+        if arg.is_a?(Range)
+          from, to = arg.begin, arg.end
+          from += size if from < 0
+          return nil if from < 0
+          to   += size if to < 0
+          to   += 1    if !arg.exclude_end?
+          length = to - from
+          length = 0 if length < 0
+          list = self
+          while from > 0
+            return nil if list.empty?
+            list = list.tail
+            from -= 1
+          end
+          list.take(length)
+        else
+          at(arg)
+        end
+      else
+        return nil if length < 0
+        arg += size if arg < 0
+        return nil if arg < 0
+        list = self
+        while arg > 0
+          return nil if list.empty?
+          list = list.tail
+          arg -= 1
+        end
+        list.take(length)
+      end
+    end
+    alias :[] :slice
+
+    # Return a `List` of indices of matching objects.
+    #
+    # @overload indices(object)
+    #   Return a `List` of indices where `object` is found. Use `#==` for
+    #   testing equality.
+    #
+    #   @example
+    #     Hamster::List[1, 2, 3, 4].indices(2)
+    #     # => Hamster::List[1]
+    #
+    # @overload indices
+    #   Pass each item successively to the block. Return a list of indices
+    #   where the block returns true.
+    #
+    #   @yield [item]
+    #   @example
+    #     Hamster::List[1, 2, 3, 4].indices { |e| e.even? }
+    #     # => Hamster::List[1, 3]
+    #
+    # @return [List]
+    def indices(object = Undefined, i = 0, &block)
+      return indices { |item| item == object } if not block_given?
+      return EmptyList if empty?
+      LazyList.new do
+        node = self
+        while true
+          break Cons.new(i, node.tail.indices(Undefined, i + 1, &block)) if yield(node.head)
+          node = node.tail
+          break EmptyList if node.empty?
+          i += 1
+        end
+      end
+    end
+
+    # Merge all the nested lists into a single list, using the given comparator
+    # block to determine the order which items should be shifted out of the nested
+    # lists and into the output list.
+    #
+    # @example
+    #   list_1 = Hamster::List[1, -3, -5]
+    #   list_2 = Hamster::List[-2, 4, 6]
+    #   Hamster::List[list_1, list_2].merge { |a,b| a.abs <=> b.abs }
+    #   # => Hamster::List[1, -2, -3, 4, -5, 6]
+    #
+    # @return [List]
+    # @yield [a, b] Pairs of items from matching indices in each list.
+    # @yieldreturn [Integer] Negative if the first element should be selected
+    #                        first, positive if the latter element, or zero if
+    #                        either.
+    def merge(&comparator)
+      return merge_by unless block_given?
+      LazyList.new do
+        sorted = reject(&:empty?).sort do |a, b|
+          yield(a.head, b.head)
+        end
+        next EmptyList if sorted.empty?
+        Cons.new(sorted.head.head, sorted.tail.cons(sorted.head.tail).merge(&comparator))
+      end
+    end
+
+    # Merge all the nested lists into a single list, using sort keys generated
+    # by mapping the items in the nested lists through the given block to determine the
+    # order which items should be shifted out of the nested lists and into the output
+    # list. Whichever nested list's `#head` has the "lowest" sort key (according to
+    # their natural order) will be the first in the merged `List`.
+    #
+    # @example
+    #   list_1 = Hamster::List[1, -3, -5]
+    #   list_2 = Hamster::List[-2, 4, 6]
+    #   Hamster::List[list_1, list_2].merge_by { |x| x.abs }
+    #   # => Hamster::List[1, -2, -3, 4, -5, 6]
+    #
+    # @return [List]
+    # @yield [item] Once for each item in either list.
+    # @yieldreturn [Object] A sort key for the element.
+    def merge_by(&transformer)
+      return merge_by { |item| item } unless block_given?
+      LazyList.new do
+        sorted = reject(&:empty?).sort_by do |list|
+          yield(list.head)
+        end
+        next EmptyList if sorted.empty?
+        Cons.new(sorted.head.head, sorted.tail.cons(sorted.head.tail).merge_by(&transformer))
+      end
+    end
+
+    # Return a randomly chosen element from this list.
+    # @return [Object]
+    def sample
+      at(rand(size))
+    end
+
+    # Return a new `List` with the given items inserted before the item at `index`.
+    #
+    # @example
+    #   Hamster::List["A", "D", "E"].insert(1, "B", "C") # => Hamster::List["A", "B", "C", "D", "E"]
+    #
+    # @param index [Integer] The index where the new items should go
+    # @param items [Array] The items to add
+    # @return [List]
+    def insert(index, *items)
+      if index == 0
+        return List.from_enum(items).append(self)
+      elsif index > 0
+        LazyList.new do
+          Cons.new(head, tail.insert(index-1, *items))
+        end
+      else
+        raise IndexError if index < -size
+        insert(index + size, *items)
+      end
+    end
+
+    # Return a `List` with all elements equal to `obj` removed. `#==` is used
+    # for testing equality.
+    #
+    # @example
+    #   Hamster::List[:a, :b, :a, :a, :c].delete(:a) # => Hamster::List[:b, :c]
+    #
+    # @param obj [Object] The object to remove.
+    # @return [List]
+    def delete(obj)
+      list = self
+      list = list.tail while list.head == obj && !list.empty?
+      return EmptyList if list.empty?
+      LazyList.new { Cons.new(list.head, list.tail.delete(obj)) }
+    end
+
+    # Return a `List` containing the same items, minus the one at `index`.
+    # If `index` is negative, it counts back from the end of the list.
+    #
+    # @example
+    #   Hamster::List[1, 2, 3].delete_at(1)  # => Hamster::List[1, 3]
+    #   Hamster::List[1, 2, 3].delete_at(-1) # => Hamster::List[1, 2]
+    #
+    # @param index [Integer] The index of the item to remove
+    # @return [List]
+    def delete_at(index)
+      if index == 0
+        tail
+      elsif index < 0
+        index += size if index < 0
+        return self if index < 0
+        delete_at(index)
+      else
+        LazyList.new { Cons.new(head, tail.delete_at(index - 1)) }
+      end
+    end
+
+    # Replace a range of indexes with the given object.
+    #
+    # @overload fill(object)
+    #   Return a new `List` of the same size, with every index set to `object`.
+    #
+    #   @param [Object] object Fill value.
+    #   @example
+    #     Hamster::List["A", "B", "C", "D", "E", "F"].fill("Z")
+    #     # => Hamster::List["Z", "Z", "Z", "Z", "Z", "Z"]
+    #
+    # @overload fill(object, index)
+    #   Return a new `List` with all indexes from `index` to the end of the
+    #   vector set to `obj`.
+    #
+    #   @param [Object] object Fill value.
+    #   @param [Integer] index Starting index. May be negative.
+    #   @example
+    #     Hamster::List["A", "B", "C", "D", "E", "F"].fill("Z", 3)
+    #     # => Hamster::List["A", "B", "C", "Z", "Z", "Z"]
+    #
+    # @overload fill(object, index, length)
+    #   Return a new `List` with `length` indexes, beginning from `index`,
+    #   set to `obj`. Expands the `List` if `length` would extend beyond the
+    #   current length.
+    #
+    #   @param [Object] object Fill value.
+    #   @param [Integer] index Starting index. May be negative.
+    #   @param [Integer] length
+    #   @example
+    #     Hamster::List["A", "B", "C", "D", "E", "F"].fill("Z", 3, 2)
+    #     # => Hamster::List["A", "B", "C", "Z", "Z", "F"]
+    #     Hamster::List["A", "B"].fill("Z", 1, 5)
+    #     # => Hamster::List["A", "Z", "Z", "Z", "Z", "Z"]
+    #
+    # @return [List]
+    # @raise [IndexError] if index is out of negative range.
+    def fill(obj, index = 0, length = nil)
+      if index == 0
+        length ||= size
+        if length > 0
+          LazyList.new do
+            Cons.new(obj, tail.fill(obj, 0, length-1))
+          end
+        else
+          self
+        end
+      elsif index > 0
+        LazyList.new do
+          Cons.new(head, tail.fill(obj, index-1, length))
+        end
+      else
+        raise IndexError if index < -size
+        fill(obj, index + size, length)
+      end
+    end
+
+    # Yields all permutations of length `n` of the items in the list, and then
+    # returns `self`. If no length `n` is specified, permutations of the entire
+    # list will be yielded.
+    #
+    # There is no guarantee about which order the permutations will be yielded in.
+    #
+    # If no block is given, an `Enumerator` is returned instead.
+    #
+    # @example
+    #   Hamster::List[1, 2, 3].permutation.to_a
+    #   # => [Hamster::List[1, 2, 3],
+    #   #     Hamster::List[2, 1, 3],
+    #   #     Hamster::List[2, 3, 1],
+    #   #     Hamster::List[1, 3, 2],
+    #   #     Hamster::List[3, 1, 2],
+    #   #     Hamster::List[3, 2, 1]]
+    #
+    # @return [self, Enumerator]
+    # @yield [list] Once for each permutation.
+    def permutation(length = size, &block)
+      return enum_for(:permutation, length) if not block_given?
+      if length == 0
+        yield EmptyList
+      elsif length == 1
+        each { |obj| yield Cons.new(obj, EmptyList) }
+      elsif not empty?
+        if length < size
+          tail.permutation(length, &block)
+        end
+
+        tail.permutation(length-1) do |p|
+          0.upto(length-1) do |i|
+            left,right = p.split_at(i)
+            yield left.append(right.cons(head))
+          end
+        end
+      end
+      self
+    end
+
+    # Yield every non-empty sublist to the given block. (The entire `List` also
+    # counts as one sublist.)
+    #
+    # @example
+    #   Hamster::List[1, 2, 3].subsequences { |list| p list }
+    #   # prints:
+    #   # Hamster::List[1]
+    #   # Hamster::List[1, 2]
+    #   # Hamster::List[1, 2, 3]
+    #   # Hamster::List[2]
+    #   # Hamster::List[2, 3]
+    #   # Hamster::List[3]
+    #
+    # @yield [sublist] One or more contiguous elements from this list
+    # @return [self]
+    def subsequences(&block)
+      return enum_for(:subsequences) if not block_given?
+      if not empty?
+        1.upto(size) do |n|
+          yield take(n)
+        end
+        tail.subsequences(&block)
+      end
+      self
+    end
+
+    # Return two `List`s, the first containing all the elements for which the
+    # block evaluates to true, the second containing the rest.
+    #
+    # @example
+    #   Hamster::List[1, 2, 3, 4, 5, 6].partition { |x| x.even? }
+    #   # => [Hamster::List[2, 4, 6], Hamster::List[1, 3, 5]]
+    #
+    # @return [List]
+    # @yield [item] Once for each item.
+    def partition(&block)
+      return enum_for(:partition) if not block_given?
+      partitioner = Partitioner.new(self, block)
+      mutex = Mutex.new
+      [Partitioned.new(partitioner, partitioner.left, mutex),
+       Partitioned.new(partitioner, partitioner.right, mutex)].freeze
+    end
+
+    # Return true if `other` has the same type and contents as this `Hash`.
+    #
+    # @param other [Object] The collection to compare with
+    # @return [Boolean]
+    def eql?(other)
+      list = self
+      loop do
+        return true if other.equal?(list)
+        return false unless other.is_a?(List)
+        return other.empty? if list.empty?
+        return false if other.empty?
+        return false unless other.head.eql?(list.head)
+        list = list.tail
+        other = other.tail
+      end
+    end
+
+    # See `Object#hash`
+    # @return [Integer]
+    def hash
+      reduce(0) { |hash, item| (hash << 5) - hash + item.hash }
+    end
+
+    # Return `self`. Since this is an immutable object duplicates are
+    # equivalent.
+    # @return [List]
+    def dup
+      self
+    end
+    alias :clone :dup
+
+    # Return `self`.
+    # @return [List]
+    def to_list
+      self
+    end
+
+    # Return the contents of this `List` as a programmer-readable `String`. If all the
+    # items in the list are serializable as Ruby literal strings, the returned string can
+    # be passed to `eval` to reconstitute an equivalent `List`.
+    #
+    # @return [String]
+    def inspect
+      result = "Hamster::List["
+      each_with_index { |obj, i| result << ', ' if i > 0; result << obj.inspect }
+      result << "]"
+    end
+
+    # Allows this `List` to be printed at the `pry` console, or using `pp` (from the
+    # Ruby standard library), in a way which takes the amount of horizontal space on
+    # the screen into account, and which indents nested structures to make them easier
+    # to read.
+    #
+    # @private
+    def pretty_print(pp)
+      pp.group(1, "Hamster::List[", "]") do
+        pp.breakable ''
+        pp.seplist(self) { |obj| obj.pretty_print(pp) }
+      end
+    end
+
+    # @private
+    def respond_to?(name, include_private = false)
+      super || !!name.to_s.match(CADR)
+    end
+
+    # Return `true` if the size of this list can be obtained in constant time (without
+    # traversing the list).
+    # @return [Integer]
+    def cached_size?
+      false
+    end
+
+    private
+
+    # Perform compositions of `car` and `cdr` operations (traditional shorthand
+    # for `head` and `tail` respectively). Their names consist of a `c`,
+    # followed by at least one `a` or `d`, and finally an `r`. The series of
+    # `a`s and `d`s in the method name identify the series of `car` and `cdr`
+    # operations performed, in inverse order.
+    #
+    # @return [Object, List]
+    # @example
+    #   l = Hamster::List[nil, Hamster::List[1]]
+    #   l.car   # => nil
+    #   l.cdr   # => Hamster::List[Hamster::List[1]]
+    #   l.cadr  # => Hamster::List[1]
+    #   l.caadr # => 1
+    def method_missing(name, *args, &block)
+      if name.to_s.match(CADR)
+        code = "def #{name}; self."
+        code << Regexp.last_match[1].reverse.chars.map do |char|
+          {'a' => 'head', 'd' => 'tail'}[char]
+        end.join('.')
+        code << '; end'
+        List.class_eval(code)
+        send(name, *args, &block)
+      else
+        super
+      end
+    end
+  end
+
+  # The basic building block for constructing lists
+  #
+  # A Cons, also known as a "cons cell", has a "head" and a "tail", where
+  # the head is an element in the list, and the tail is a reference to the
+  # rest of the list. This way a singly linked list can be constructed, with
+  # each `Cons` holding a single element and a pointer to the next
+  # `Cons`.
+  #
+  # The last `Cons` instance in the chain has the {EmptyList} as its tail.
+  #
+  # @private
+  class Cons
+    include List
+
+    attr_reader :head, :tail
+
+    def initialize(head, tail = EmptyList)
+      @head = head
+      @tail = tail
+      @size = tail.cached_size? ? tail.size + 1 : nil
+    end
+
+    def empty?
+      false
+    end
+
+    def size
+      @size ||= super
+    end
+    alias :length :size
+
+    def cached_size?
+      @size != nil
+    end
+  end
+
+  # A `LazyList` takes a block that returns a `List`, i.e. an object that responds
+  # to `#head`, `#tail` and `#empty?`. The list is only realized (i.e. the block is
+  # only called) when one of these operations is performed.
+  #
+  # By returning a `Cons` that in turn has a {LazyList} as its tail, one can
+  # construct infinite `List`s.
+  #
+  # @private
+  class LazyList
+    include List
+
+    def initialize(&block)
+      @head   = block # doubles as storage for block while yet unrealized
+      @tail   = nil
+      @atomic = Concurrent::AtomicReference.new(0) # haven't yet run block
+      @size   = nil
+    end
+
+    def head
+      realize if @atomic.get != 2
+      @head
+    end
+    alias :first :head
+
+    def tail
+      realize if @atomic.get != 2
+      @tail
+    end
+
+    def empty?
+      realize if @atomic.get != 2
+      @size == 0
+    end
+
+    def size
+      @size ||= super
+    end
+    alias :length :size
+
+    def cached_size?
+      @size != nil
+    end
+
+    private
+
+    QUEUE = ConditionVariable.new
+    MUTEX = Mutex.new
+
+    def realize
+      while true
+        # try to "claim" the right to run the block which realizes target
+        if @atomic.compare_and_swap(0,1) # full memory barrier here
+          begin
+            list = @head.call
+            if list.empty?
+              @head, @tail, @size = nil, self, 0
+            else
+              @head, @tail = list.head, list.tail
+            end
+          rescue
+            @atomic.set(0)
+            MUTEX.synchronize { QUEUE.broadcast }
+            raise
+          end
+          @atomic.set(2)
+          MUTEX.synchronize { QUEUE.broadcast }
+          return
+        end
+        # we failed to "claim" it, another thread must be running it
+        if @atomic.get == 1 # another thread is running the block
+          MUTEX.synchronize do
+            # check value of @atomic again, in case another thread already changed it
+            #   *and* went past the call to QUEUE.broadcast before we got here
+            QUEUE.wait(MUTEX) if @atomic.get == 1
+          end
+        elsif @atomic.get == 2 # another thread finished the block
+          return
+        end
+      end
+    end
+  end
+
+  # Common behavior for other classes which implement various kinds of `List`s
+  # @private
+  class Realizable
+    include List
+
+    def initialize
+      @head, @tail, @size = Undefined, Undefined, nil
+    end
+
+    def head
+      realize if @head == Undefined
+      @head
+    end
+    alias :first :head
+
+    def tail
+      realize if @tail == Undefined
+      @tail
+    end
+
+    def empty?
+      realize if @head == Undefined
+      @size == 0
+    end
+
+    def size
+      @size ||= super
+    end
+    alias :length :size
+
+    def cached_size?
+      @size != nil
+    end
+
+    def realized?
+      @head != Undefined
+    end
+  end
+
+  # This class can divide a collection into 2 `List`s, one of items
+  #   for which the block returns true, and another for false
+  # At the same time, it guarantees the block will only be called ONCE for each item
+  #
+  # @private
+  class Partitioner
+    attr_reader :left, :right
+    def initialize(list, block)
+      @list, @block, @left, @right = list, block, [], []
+    end
+
+    def next_item
+      unless @list.empty?
+        item = @list.head
+        (@block.call(item) ? @left : @right) << item
+        @list = @list.tail
+      end
+    end
+
+    def done?
+      @list.empty?
+    end
+  end
+
+  # One of the `List`s which gets its items from a Partitioner
+  # @private
+  class Partitioned < Realizable
+    def initialize(partitioner, buffer, mutex)
+      super()
+      @partitioner, @buffer, @mutex = partitioner, buffer, mutex
+    end
+
+    def realize
+      # another thread may get ahead of us and null out @mutex
+      mutex = @mutex
+      mutex && mutex.synchronize do
+        return if @head != Undefined # another thread got ahead of us
+        while true
+          if !@buffer.empty?
+            @head = @buffer.shift
+            @tail = Partitioned.new(@partitioner, @buffer, @mutex)
+            # don't hold onto references
+            # tail will keep references alive until end of list is reached
+            @partitioner, @buffer, @mutex = nil, nil, nil
+            return
+          elsif @partitioner.done?
+            @head, @size, @tail = nil, 0, self
+            @partitioner, @buffer, @mutex = nil, nil, nil # allow them to be GC'd
+            return
+          else
+            @partitioner.next_item
+          end
+        end
+      end
+    end
+  end
+
+  # This class can divide a list up into 2 `List`s, one for the prefix of
+  # elements for which the block returns true, and another for all the elements
+  # after that. It guarantees that the block will only be called ONCE for each
+  # item
+  #
+  # @private
+  class Splitter
+    attr_reader :left, :right
+    def initialize(list, block)
+      @list, @block, @left, @right = list, block, [], EmptyList
+    end
+
+    def next_item
+      unless @list.empty?
+        item = @list.head
+        if @block.call(item)
+          @left << item
+          @list = @list.tail
+        else
+          @right = @list
+          @list  = EmptyList
+        end
+      end
+    end
+
+    def done?
+      @list.empty?
+    end
+
+    # @private
+    class Left < Realizable
+      def initialize(splitter, buffer, mutex)
+        super()
+        @splitter, @buffer, @mutex = splitter, buffer, mutex
+      end
+
+      def realize
+        # another thread may get ahead of us and null out @mutex
+        mutex = @mutex
+        mutex && mutex.synchronize do
+          return if @head != Undefined # another thread got ahead of us
+          while true
+            if !@buffer.empty?
+              @head = @buffer.shift
+              @tail = Left.new(@splitter, @buffer, @mutex)
+              @splitter, @buffer, @mutex = nil, nil, nil
+              return
+            elsif @splitter.done?
+              @head, @size, @tail = nil, 0, self
+              @splitter, @buffer, @mutex = nil, nil, nil
+              return
+            else
+              @splitter.next_item
+            end
+          end
+        end
+      end
+    end
+
+    # @private
+    class Right < Realizable
+      def initialize(splitter, mutex)
+        super()
+        @splitter, @mutex = splitter, mutex
+      end
+
+      def realize
+        mutex = @mutex
+        mutex && mutex.synchronize do
+          return if @head != Undefined
+          @splitter.next_item until @splitter.done?
+          if @splitter.right.empty?
+            @head, @size, @tail = nil, 0, self
+          else
+            @head, @tail = @splitter.right.head, @splitter.right.tail
+          end
+          @splitter, @mutex = nil, nil
+        end
+      end
+    end
+  end
+
+  # A list without any elements. This is a singleton, since all empty lists are equivalent.
+  # @private
+  module EmptyList
+    class << self
+      include List
+
+      # There is no first item in an empty list, so return `nil`.
+      # @return [nil]
+      def head
+        nil
+      end
+      alias :first :head
+
+      # There are no subsequent elements, so return an empty list.
+      # @return [self]
+      def tail
+        self
+      end
+
+      def empty?
+        true
+      end
+
+      # Return the number of items in this `List`.
+      # @return [Integer]
+      def size
+        0
+      end
+      alias :length :size
+
+      def cached_size?
+        true
+      end
+    end
+  end.freeze
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/mutable_hash.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/mutable_hash.rb
new file mode 100755
index 0000000..dcbc816
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/mutable_hash.rb
@@ -0,0 +1,32 @@
+require "hamster/hash"
+require "hamster/read_copy_update"
+
+module Hamster
+  # @api private
+  class MutableHash
+    include ReadCopyUpdate
+
+    def self.[](pairs = {})
+      MutableHash.new(Hash[pairs])
+    end
+
+    def put(key, value = Undefined, &block)
+      transform { |hash| hash.put(key, value, &block) }
+    end
+
+    def store(key, value)
+      put(key, value)
+      value
+    end
+    alias :[]= :store
+
+    def delete(key)
+      old_value = nil
+      transform do |hash|
+        old_value = hash.get(key)
+        hash.delete(key)
+      end
+      old_value
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/nested.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/nested.rb
new file mode 100755
index 0000000..393ca72
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/nested.rb
@@ -0,0 +1,78 @@
+require "set"
+require "hamster/hash"
+require "hamster/set"
+require "hamster/vector"
+require "hamster/sorted_set"
+require "hamster/list"
+require "hamster/deque"
+require "hamster/core_ext/struct"
+
+module Hamster
+  class << self
+
+    # Create a Hamster immutable data structure with nested Hamster data
+    # structure from a nested Ruby object `obj`.  This method recursively
+    # "walks" the Ruby object, converting Ruby `Hash` to {Hamster::Hash}, Ruby
+    # `Array` to {Hamster::Vector}, Ruby `Set` to {Hamster::Set}, and Ruby
+    # `SortedSet` to {Hamster::SortedSet}.  Other objects are left as-is.
+    #
+    # @example
+    #   h = Hamster.from({ "a" => [1, 2], "b" => "c" })
+    #   # => Hamster::Hash["a" => Hamster::Vector[1, 2], "b" => "c"]
+    #
+    # @return [Hash, Vector, Set, SortedSet, Object]
+    def from(obj)
+      case obj
+      when ::Hash
+        res = obj.map { |key, value| [from(key), from(value)] }
+        Hamster::Hash.new(res)
+      when Hamster::Hash
+        obj.map { |key, value| [from(key), from(value)] }
+      when ::Struct
+        from(obj.to_h)
+      when ::Array
+        res = obj.map { |element| from(element) }
+        Hamster::Vector.new(res)
+      when ::SortedSet
+        # This clause must go before ::Set clause, since ::SortedSet is a ::Set.
+        res = obj.map { |element| from(element) }
+        Hamster::SortedSet.new(res)
+      when ::Set
+        res = obj.map { |element| from(element) }
+        Hamster::Set.new(res)
+      when Hamster::Vector, Hamster::Set, Hamster::SortedSet
+        obj.map { |element| from(element) }
+      else
+        obj
+      end
+    end
+
+    # Create a Ruby object from Hamster data. This method recursively "walks"
+    # the Hamster object, converting {Hamster::Hash} to Ruby `Hash`,
+    # {Hamster::Vector} and {Hamster::Deque} to Ruby `Array`, {Hamster::Set}
+    # to Ruby `Set`, and {Hamster::SortedSet} to Ruby `SortedSet`.  Other
+    # objects are left as-is.
+    #
+    # @example
+    #   h = Hamster.to_ruby(Hamster.from({ "a" => [1, 2], "b" => "c" }))
+    #   # => { "a" => [1, 2], "b" => "c" }
+    #
+    # @return [::Hash, ::Array, ::Set, ::SortedSet, Object]
+    def to_ruby(obj)
+      case obj
+      when Hamster::Hash, ::Hash
+        obj.each_with_object({}) { |keyval, hash| hash[to_ruby(keyval[0])] = to_ruby(keyval[1]) }
+      when Hamster::Vector, ::Array
+        obj.each_with_object([]) { |element, arr| arr << to_ruby(element) }
+      when Hamster::Set, ::Set
+        obj.each_with_object(::Set.new) { |element, set| set << to_ruby(element) }
+      when Hamster::SortedSet, ::SortedSet
+        obj.each_with_object(::SortedSet.new) { |element, set| set << to_ruby(element) }
+      when Hamster::Deque
+        obj.to_a.tap { |arr| arr.map! { |element| to_ruby(element) }}
+      else
+        obj
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/read_copy_update.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/read_copy_update.rb
new file mode 100755
index 0000000..96128bb
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/read_copy_update.rb
@@ -0,0 +1,37 @@
+require "forwardable"
+require "thread"
+
+module Hamster
+  # @private
+  module ReadCopyUpdate
+    extend Forwardable
+
+    def initialize(content)
+      @content = content
+      @lock = Mutex.new
+    end
+
+    def eql?(other)
+      instance_of?(other.class) && @content.eql?(other.instance_variable_get(:@content))
+    end
+    alias :== :eql?
+
+    def_delegator :@content, :inspect
+    def_delegator :@content, :to_s
+
+    protected
+
+    def transform
+      @lock.synchronize do
+        @content = yield(@content)
+      end
+      self
+    end
+
+    private
+
+    def method_missing(name, *args, &block)
+      @content.send(name, *args, &block) rescue super
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/set.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/set.rb
new file mode 100755
index 0000000..7cb4f64
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/set.rb
@@ -0,0 +1,576 @@
+require "hamster/immutable"
+require "hamster/undefined"
+require "hamster/enumerable"
+require "hamster/hash"
+require "hamster/trie"
+require "hamster/sorted_set"
+require "set"
+
+module Hamster
+
+  # `Hamster::Set` is a collection of unordered values with no duplicates. Testing whether
+  # an object is present in the `Set` can be done in constant time. `Set` is also `Enumerable`, so you can
+  # iterate over the members of the set with {#each}, transform them with {#map}, filter
+  # them with {#select}, and so on. Some of the `Enumerable` methods are overridden to
+  # return Hamster collections.
+  #
+  # Like the `Set` class in Ruby's standard library, which we will call RubySet,
+  # `Hamster::Set` defines equivalency of objects using `#hash` and `#eql?`. No two
+  # objects with the same `#hash` code, and which are also `#eql?`, can coexist in the
+  # same `Set`. If one is already in the `Set`, attempts to add another one will have
+  # no effect.
+  #
+  # `Set`s have no natural ordering and cannot be compared using `#<=>`. However, they
+  # define {#<}, {#>}, {#<=}, and {#>=} as shorthand for {#proper_subset?},
+  # {#proper_superset?}, {#subset?}, and {#superset?} respectively.
+  #
+  # The basic set-theoretic operations {#union}, {#intersection}, {#difference}, and
+  # {#exclusion} work with any `Enumerable` object.
+  #
+  # A `Set` can be created in either of the following ways:
+  #
+  #     Hamster::Set.new([1, 2, 3]) # any Enumerable can be used to initialize
+  #     Hamster::Set['A', 'B', 'C', 'D']
+  #
+  # The latter 2 forms of initialization can be used with your own, custom subclasses
+  # of `Hamster::Set`.
+  #
+  # Unlike RubySet, all methods which you might expect to "modify" a `Hamster::Set`
+  # actually return a new set and leave the existing one unchanged.
+  #
+  # @example
+  #   set1 = Hamster::Set[1, 2] # => Hamster::Set[1, 2]
+  #   set2 = Hamster::Set[1, 2] # => Hamster::Set[1, 2]
+  #   set1 == set2              # => true
+  #   set3 = set1.add("foo")    # => Hamster::Set[1, 2, "foo"]
+  #   set3 - set2               # => Hamster::Set["foo"]
+  #   set3.subset?(set1)        # => false
+  #   set1.subset?(set3)        # => true
+  #
+  class Set
+    include Immutable
+    include Enumerable
+
+    class << self
+      # Create a new `Set` populated with the given items.
+      # @return [Set]
+      def [](*items)
+        items.empty? ? empty : new(items)
+      end
+
+      # Return an empty `Set`. If used on a subclass, returns an empty instance
+      # of that class.
+      #
+      # @return [Set]
+      def empty
+        @empty ||= self.new
+      end
+
+      # "Raw" allocation of a new `Set`. Used internally to create a new
+      # instance quickly after obtaining a modified {Trie}.
+      #
+      # @return [Set]
+      # @private
+      def alloc(trie = EmptyTrie)
+        allocate.tap { |s| s.instance_variable_set(:@trie, trie) }
+      end
+    end
+
+    def initialize(items=[])
+      @trie = Trie.new(0)
+      items.each { |item| @trie.put!(item, nil) }
+    end
+
+    # Return `true` if this `Set` contains no items.
+    # @return [Boolean]
+    def empty?
+      @trie.empty?
+    end
+
+    # Return the number of items in this `Set`.
+    # @return [Integer]
+    def size
+      @trie.size
+    end
+    alias :length :size
+
+    # Return a new `Set` with `item` added. If `item` is already in the set,
+    # return `self`.
+    #
+    # @example
+    #   Hamster::Set[1, 2, 3].add(4) # => Hamster::Set[1, 2, 4, 3]
+    #   Hamster::Set[1, 2, 3].add(2) # => Hamster::Set[1, 2, 3]
+    #
+    # @param item [Object] The object to add
+    # @return [Set]
+    def add(item)
+      include?(item) ? self : self.class.alloc(@trie.put(item, nil))
+    end
+    alias :<< :add
+
+    # If `item` is not a member of this `Set`, return a new `Set` with `item` added.
+    # Otherwise, return `false`.
+    #
+    # @example
+    #   Hamster::Set[1, 2, 3].add?(4) # => Hamster::Set[1, 2, 4, 3]
+    #   Hamster::Set[1, 2, 3].add?(2) # => false
+    #
+    # @param item [Object] The object to add
+    # @return [Set, false]
+    def add?(item)
+      !include?(item) && add(item)
+    end
+
+    # Return a new `Set` with `item` removed. If `item` is not a member of the set,
+    # return `self`.
+    #
+    # @example
+    #   Hamster::Set[1, 2, 3].delete(1)  # => Hamster::Set[2, 3]
+    #   Hamster::Set[1, 2, 3].delete(99) # => Hamster::Set[1, 2, 3]
+    #
+    # @param item [Object] The object to remove
+    # @return [Set]
+    def delete(item)
+      trie = @trie.delete(item)
+      new_trie(trie)
+    end
+
+    # If `item` is a member of this `Set`, return a new `Set` with `item` removed.
+    # Otherwise, return `false`.
+    #
+    # @example
+    #   Hamster::Set[1, 2, 3].delete?(1)  # => Hamster::Set[2, 3]
+    #   Hamster::Set[1, 2, 3].delete?(99) # => false
+    #
+    # @param item [Object] The object to remove
+    # @return [Set, false]
+    def delete?(item)
+      include?(item) && delete(item)
+    end
+
+    # Call the block once for each item in this `Set`. No specific iteration order
+    # is guaranteed, but the order will be stable for any particular `Set`. If
+    # no block is given, an `Enumerator` is returned instead.
+    #
+    # @example
+    #   Hamster::Set["Dog", "Elephant", "Lion"].each { |e| puts e }
+    #   Elephant
+    #   Dog
+    #   Lion
+    #   # => Hamster::Set["Dog", "Elephant", "Lion"]
+    #
+    # @yield [item] Once for each item.
+    # @return [self, Enumerator]
+    def each
+      return to_enum if not block_given?
+      @trie.each { |key, _| yield(key) }
+      self
+    end
+
+    # Call the block once for each item in this `Set`. Iteration order will be
+    # the opposite of {#each}. If no block is given, an `Enumerator` is
+    # returned instead.
+    #
+    # @example
+    #   Hamster::Set["Dog", "Elephant", "Lion"].reverse_each { |e| puts e }
+    #   Lion
+    #   Dog
+    #   Elephant
+    #   # => Hamster::Set["Dog", "Elephant", "Lion"]
+    #
+    # @yield [item] Once for each item.
+    # @return [self]
+    def reverse_each
+      return enum_for(:reverse_each) if not block_given?
+      @trie.reverse_each { |key, _| yield(key) }
+      self
+    end
+
+    # Return a new `Set` with all the items for which the block returns true.
+    #
+    # @example
+    #   Hamster::Set["Elephant", "Dog", "Lion"].select { |e| e.size >= 4 }
+    #   # => Hamster::Set["Elephant", "Lion"]
+    # @yield [item] Once for each item.
+    # @return [Set]
+    def select
+      return enum_for(:select) unless block_given?
+      trie = @trie.select { |key, _| yield(key) }
+      new_trie(trie)
+    end
+    alias :find_all :select
+    alias :keep_if  :select
+
+    # Call the block once for each item in this `Set`. All the values returned
+    # from the block will be gathered into a new `Set`. If no block is given,
+    # an `Enumerator` is returned instead.
+    #
+    # @example
+    #   Hamster::Set["Cat", "Elephant", "Dog", "Lion"].map { |e| e.size }
+    #   # => Hamster::Set[8, 4, 3]
+    #
+    # @yield [item] Once for each item.
+    # @return [Set]
+    def map
+      return enum_for(:map) if not block_given?
+      return self if empty?
+      self.class.new(super)
+    end
+    alias :collect :map
+
+    # Return `true` if the given item is present in this `Set`. More precisely,
+    # return `true` if an object with the same `#hash` code, and which is also `#eql?`
+    # to the given object is present.
+    #
+    # @example
+    #   Hamster::Set["A", "B", "C"].include?("B") # => true
+    #   Hamster::Set["A", "B", "C"].include?("Z") # => false
+    #
+    # @param object [Object] The object to check for
+    # @return [Boolean]
+    def include?(object)
+      @trie.key?(object)
+    end
+    alias :member? :include?
+
+    # Return a member of this `Set`. The member chosen will be the first one which
+    # would be yielded by {#each}. If the set is empty, return `nil`.
+    #
+    # @example
+    #   Hamster::Set["A", "B", "C"].first # => "C"
+    #
+    # @return [Object]
+    def first
+      (entry = @trie.at(0)) && entry[0]
+    end
+
+    # Return a {SortedSet} which contains the same items as this `Set`, ordered by
+    # the given comparator block.
+    #
+    # @example
+    #   Hamster::Set["Elephant", "Dog", "Lion"].sort
+    #   # => Hamster::SortedSet["Dog", "Elephant", "Lion"]
+    #   Hamster::Set["Elephant", "Dog", "Lion"].sort { |a,b| a.size <=> b.size }
+    #   # => Hamster::SortedSet["Dog", "Lion", "Elephant"]
+    #
+    # @yield [a, b] Any number of times with different pairs of elements.
+    # @yieldreturn [Integer] Negative if the first element should be sorted
+    #                        lower, positive if the latter element, or 0 if
+    #                        equal.
+    # @return [SortedSet]
+    def sort(&comparator)
+      SortedSet.new(self.to_a, &comparator)
+    end
+
+    # Return a {SortedSet} which contains the same items as this `Set`, ordered
+    # by mapping each item through the provided block to obtain sort keys, and
+    # then sorting the keys.
+    #
+    # @example
+    #   Hamster::Set["Elephant", "Dog", "Lion"].sort_by { |e| e.size }
+    #   # => Hamster::SortedSet["Dog", "Lion", "Elephant"]
+    #
+    # @yield [item] Once for each item to create the set, and then potentially
+    #               again depending on what operations are performed on the
+    #               returned {SortedSet}. As such, it is recommended that the
+    #               block be a pure function.
+    # @yieldreturn [Object] sort key for the item
+    # @return [SortedSet]
+    def sort_by(&mapper)
+      SortedSet.new(self.to_a, &mapper)
+    end
+
+    # Return a new `Set` which contains all the members of both this `Set` and `other`.
+    # `other` can be any `Enumerable` object.
+    #
+    # @example
+    #   Hamster::Set[1, 2] | Hamster::Set[2, 3] # => Hamster::Set[1, 2, 3]
+    #
+    # @param other [Enumerable] The collection to merge with
+    # @return [Set]
+    def union(other)
+      if other.is_a?(Hamster::Set)
+        if other.size > size
+          small_set_pairs = @trie
+          large_set_trie = other.instance_variable_get(:@trie)
+        else
+          small_set_pairs = other.instance_variable_get(:@trie)
+          large_set_trie = @trie
+        end
+      else
+        if other.respond_to?(:lazy)
+          small_set_pairs = other.lazy.map { |e| [e, nil] }
+        else
+          small_set_pairs = other.map { |e| [e, nil] }
+        end
+        large_set_trie = @trie
+      end
+
+      trie = large_set_trie.bulk_put(small_set_pairs)
+      new_trie(trie)
+    end
+    alias :| :union
+    alias :+ :union
+    alias :merge :union
+
+    # Return a new `Set` which contains all the items which are members of both
+    # this `Set` and `other`. `other` can be any `Enumerable` object.
+    #
+    # @example
+    #   Hamster::Set[1, 2] & Hamster::Set[2, 3] # => Hamster::Set[2]
+    #
+    # @param other [Enumerable] The collection to intersect with
+    # @return [Set]
+    def intersection(other)
+      if other.size < @trie.size
+        if other.is_a?(Hamster::Set)
+          trie = other.instance_variable_get(:@trie).select { |key, _| include?(key) }
+        else
+          trie = Trie.new(0)
+          other.each { |obj| trie.put!(obj, nil) if include?(obj) }
+        end
+      else
+        trie = @trie.select { |key, _| other.include?(key) }
+      end
+      new_trie(trie)
+    end
+    alias :& :intersection
+
+    # Return a new `Set` with all the items in `other` removed. `other` can be
+    # any `Enumerable` object.
+    #
+    # @example
+    #   Hamster::Set[1, 2] - Hamster::Set[2, 3] # => Hamster::Set[1]
+    #
+    # @param other [Enumerable] The collection to subtract from this set
+    # @return [Set]
+    def difference(other)
+      trie = if (@trie.size <= other.size) && (other.is_a?(Hamster::Set) || (defined?(::Set) && other.is_a?(::Set)))
+        @trie.select { |key, _| !other.include?(key) }
+      else
+        @trie.bulk_delete(other)
+      end
+      new_trie(trie)
+    end
+    alias :subtract :difference
+    alias :- :difference
+
+    # Return a new `Set` which contains all the items which are members of this
+    # `Set` or of `other`, but not both. `other` can be any `Enumerable` object.
+    #
+    # @example
+    #   Hamster::Set[1, 2] ^ Hamster::Set[2, 3] # => Hamster::Set[1, 3]
+    #
+    # @param other [Enumerable] The collection to take the exclusive disjunction of
+    # @return [Set]
+    def exclusion(other)
+      ((self | other) - (self & other))
+    end
+    alias :^ :exclusion
+
+    # Return `true` if all items in this `Set` are also in `other`.
+    #
+    # @example
+    #   Hamster::Set[2, 3].subset?(Hamster::Set[1, 2, 3]) # => true
+    #
+    # @param other [Set]
+    # @return [Boolean]
+    def subset?(other)
+      return false if other.size < size
+
+      # This method has the potential to be very slow if 'other' is a large Array, so to avoid that,
+      #   we convert those Arrays to Sets before checking presence of items
+      # Time to convert Array -> Set is linear in array.size
+      # Time to check for presence of all items in an Array is proportional to set.size * array.size
+      # Note that both sides of that equation have array.size -- hence those terms cancel out,
+      #   and the break-even point is solely dependent on the size of this collection
+      # After doing some benchmarking to estimate the constants, it appears break-even is at ~190 items
+      # We also check other.size, to avoid the more expensive #is_a? checks in cases where it doesn't matter
+      #
+      if other.size >= 150 && @trie.size >= 190 && !(other.is_a?(Hamster::Set) || other.is_a?(::Set))
+        other = ::Set.new(other)
+      end
+      all? { |item| other.include?(item) }
+    end
+    alias :<= :subset?
+
+    # Return `true` if all items in `other` are also in this `Set`.
+    #
+    # @example
+    #   Hamster::Set[1, 2, 3].superset?(Hamster::Set[2, 3]) # => true
+    #
+    # @param other [Set]
+    # @return [Boolean]
+    def superset?(other)
+      other.subset?(self)
+    end
+    alias :>= :superset?
+
+    # Returns `true` if `other` contains all the items in this `Set`, plus at least
+    # one item which is not in this set.
+    #
+    # @example
+    #   Hamster::Set[2, 3].proper_subset?(Hamster::Set[1, 2, 3])    # => true
+    #   Hamster::Set[1, 2, 3].proper_subset?(Hamster::Set[1, 2, 3]) # => false
+    #
+    # @param other [Set]
+    # @return [Boolean]
+    def proper_subset?(other)
+      return false if other.size <= size
+      # See comments above
+      if other.size >= 150 && @trie.size >= 190 && !(other.is_a?(Hamster::Set) || other.is_a?(::Set))
+        other = ::Set.new(other)
+      end
+      all? { |item| other.include?(item) }
+    end
+    alias :< :proper_subset?
+
+    # Returns `true` if this `Set` contains all the items in `other`, plus at least
+    # one item which is not in `other`.
+    #
+    # @example
+    #   Hamster::Set[1, 2, 3].proper_superset?(Hamster::Set[2, 3])    # => true
+    #   Hamster::Set[1, 2, 3].proper_superset?(Hamster::Set[1, 2, 3]) # => false
+    #
+    # @param other [Set]
+    # @return [Boolean]
+    def proper_superset?(other)
+      other.proper_subset?(self)
+    end
+    alias :> :proper_superset?
+
+    # Return `true` if this `Set` and `other` do not share any items.
+    #
+    # @example
+    #   Hamster::Set[1, 2].disjoint?(Hamster::Set[8, 9]) # => true
+    #
+    # @param other [Set]
+    # @return [Boolean]
+    def disjoint?(other)
+      if other.size <= size
+        other.each { |item| return false if include?(item) }
+      else
+        # See comment on #subset?
+        if other.size >= 150 && @trie.size >= 190 && !(other.is_a?(Hamster::Set) || other.is_a?(::Set))
+          other = ::Set.new(other)
+        end
+        each { |item| return false if other.include?(item) }
+      end
+      true
+    end
+
+    # Return `true` if this `Set` and `other` have at least one item in common.
+    #
+    # @example
+    #   Hamster::Set[1, 2].intersect?(Hamster::Set[2, 3]) # => true
+    #
+    # @param other [Set]
+    # @return [Boolean]
+    def intersect?(other)
+      !disjoint?(other)
+    end
+
+    # Recursively insert the contents of any nested `Set`s into this `Set`, and
+    # remove them.
+    #
+    # @example
+    #   Hamster::Set[Hamster::Set[1, 2], Hamster::Set[3, 4]].flatten
+    #   # => Hamster::Set[1, 2, 3, 4]
+    #
+    # @return [Set]
+    def flatten
+      reduce(self.class.empty) do |set, item|
+        next set.union(item.flatten) if item.is_a?(Set)
+        set.add(item)
+      end
+    end
+
+    alias :group :group_by
+    alias :classify :group_by
+
+    # Return a randomly chosen item from this `Set`. If the set is empty, return `nil`.
+    #
+    # @example
+    #   Hamster::Set[1, 2, 3, 4, 5].sample # => 3
+    #
+    # @return [Object]
+    def sample
+      empty? ? nil : @trie.at(rand(size))[0]
+    end
+
+    # Return an empty `Set` instance, of the same class as this one. Useful if you
+    # have multiple subclasses of `Set` and want to treat them polymorphically.
+    #
+    # @return [Set]
+    def clear
+      self.class.empty
+    end
+
+    # Return true if `other` has the same type and contents as this `Set`.
+    #
+    # @param other [Object] The object to compare with
+    # @return [Boolean]
+    def eql?(other)
+      return true if other.equal?(self)
+      return false if not instance_of?(other.class)
+      other_trie = other.instance_variable_get(:@trie)
+      return false if @trie.size != other_trie.size
+      @trie.each do |key, _|
+        return false if !other_trie.key?(key)
+      end
+      true
+    end
+    alias :== :eql?
+
+    # See `Object#hash`.
+    # @return [Integer]
+    def hash
+      reduce(0) { |hash, item| (hash << 5) - hash + item.hash }
+    end
+
+    undef :"<=>" # Sets are not ordered, so Enumerable#<=> will give a meaningless result
+    undef :each_index # Set members cannot be accessed by 'index', so #each_index is not meaningful
+
+    # Return `self`.
+    #
+    # @return [self]
+    def to_set
+      self
+    end
+
+    # @private
+    def marshal_dump
+      output = {}
+      each do |key|
+        output[key] = nil
+      end
+      output
+    end
+
+    # @private
+    def marshal_load(dictionary)
+      @trie = dictionary.reduce(EmptyTrie) do |trie, key_value|
+        trie.put(key_value.first, nil)
+      end
+    end
+
+    private
+
+    def new_trie(trie)
+      if trie.empty?
+        self.class.empty
+      elsif trie.equal?(@trie)
+        self
+      else
+        self.class.alloc(trie)
+      end
+    end
+  end
+
+  # The canonical empty `Set`. Returned by `Set[]` when
+  # invoked with no arguments; also returned by `Set.empty`. Prefer using this
+  # one rather than creating many empty sets using `Set.new`.
+  #
+  # @private
+  EmptySet = Hamster::Set.empty
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/sorted_set.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/sorted_set.rb
new file mode 100755
index 0000000..459b940
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/sorted_set.rb
@@ -0,0 +1,1459 @@
+require "hamster/immutable"
+require "hamster/enumerable"
+
+module Hamster
+
+  # A `SortedSet` is a collection of ordered values with no duplicates. Unlike a
+  # {Vector}, in which items can appear in any arbitrary order, a `SortedSet` always
+  # keeps items either in their natural order, or in an order defined by a comparator
+  # block which is provided at initialization time.
+  #
+  # `SortedSet` uses `#<=>` (or its comparator block) to determine which items are
+  # equivalent. If the comparator indicates that an existing item and a new item are
+  # equal, any attempt to insert the new item will have no effect.
+  #
+  # This means that *all* the items inserted into any one `SortedSet` must all be
+  # comparable. For example, you cannot put `String`s and `Integer`s in the same
+  # `SortedSet`. This is unlike {Set}, which can store items of any type, as long
+  # as they all support `#hash` and `#eql?`.
+  #
+  # A `SortedSet` can be created in either of the following ways:
+  #
+  #     Hamster::SortedSet.new([1, 2, 3]) # any Enumerable can be used to initialize
+  #     Hamster::SortedSet['A', 'B', 'C', 'D']
+  #
+  # Or if you want to use a custom ordering:
+  #
+  #     Hamster::SortedSet.new([1,2,3]) { |a, b| -a <=> -b }
+  #     Hamster::SortedSet.new([1, 2, 3]) { |num| -num }
+  #
+  # `SortedSet` can use a 2-parameter block which returns 0, 1, or -1
+  # as a comparator (like `Array#sort`), *or* use a 1-parameter block to derive sort
+  # keys (like `Array#sort_by`) which will be compared using `#<=>`.
+  #
+  # Like all Hamster collections, `SortedSet`s are immutable. Any operation which you
+  # might expect to "modify" a `SortedSet` will actually return a new collection and
+  # leave the existing one unchanged.
+  #
+  # `SortedSet` supports the same basic set-theoretic operations as {Set}, including
+  # {#union}, {#intersection}, {#difference}, and {#exclusion}, as well as {#subset?},
+  # {#superset?}, and so on. Unlike {Set}, it does not define comparison operators like
+  # `#>` or `#<` as aliases for the superset/subset predicates. Instead, these comparison
+  # operators do a item-by-item comparison between the `SortedSet` and another sequential
+  # collection. (See `Array#<=>` for details.)
+  #
+  # Additionally, since `SortedSet`s are ordered, they also support indexed retrieval
+  # of items using {#at} or {#[]}. Like {Vector},
+  # negative indices count back from the end of the `SortedSet`.
+  #
+  # Getting the {#max} or {#min} item from a `SortedSet`, as defined by its comparator,
+  # is a constant time operation.
+  #
+  class SortedSet
+    include Immutable
+    include Enumerable
+
+    class << self
+      # Create a new `SortedSet` populated with the given items. This method does not
+      # accept a comparator block.
+      #
+      # @return [SortedSet]
+      def [](*items)
+        new(items)
+      end
+
+      # Return an empty `SortedSet`. If used on a subclass, returns an empty instance
+      # of that class.
+      #
+      # @return [SortedSet]
+      def empty
+        @empty ||= self.alloc(PlainAVLNode::EmptyNode)
+      end
+
+      # "Raw" allocation of a new `SortedSet`. Used internally to create a new
+      # instance quickly after obtaining a modified binary tree.
+      #
+      # @return [Set]
+      # @private
+      def alloc(node)
+        result = allocate
+        result.instance_variable_set(:@node, node)
+        result
+      end
+    end
+
+    def initialize(items=[], &block)
+      items = items.to_a
+      if block
+        if block.arity == 1 || block.arity == -1
+          comparator = lambda { |a,b| block.call(a) <=> block.call(b) }
+          items = items.sort_by(&block)
+        else
+          comparator = block
+          items = items.sort(&block)
+        end
+        @node = AVLNode.from_items(items, comparator)
+      else
+        @node = PlainAVLNode.from_items(items.sort)
+      end
+    end
+
+    # Return `true` if this `SortedSet` contains no items.
+    #
+    # @return [Boolean]
+    def empty?
+      @node.empty?
+    end
+
+    # Return the number of items in this `SortedSet`.
+    #
+    # @example
+    #   Hamster::SortedSet["A", "B", "C"].size  # => 3
+    #
+    # @return [Integer]
+    def size
+      @node.size
+    end
+    alias :length :size
+
+    # Return a new `SortedSet` with `item` added. If `item` is already in the set,
+    # return `self`.
+    #
+    # @example
+    #   Hamster::SortedSet["Dog", "Lion"].add("Elephant")
+    #   # => Hamster::SortedSet["Dog", "Elephant", "Lion"]
+    #
+    # @param item [Object] The object to add
+    # @return [SortedSet]
+    def add(item)
+      catch :present do
+        node = @node.insert(item)
+        return self.class.alloc(node)
+      end
+      self
+    end
+    alias :<< :add
+
+    # If `item` is not a member of this `SortedSet`, return a new `SortedSet` with
+    # `item` added. Otherwise, return `false`.
+    #
+    # @example
+    #   Hamster::SortedSet["Dog", "Lion"].add?("Elephant")
+    #   # => Hamster::SortedSet["Dog", "Elephant", "Lion"]
+    #   Hamster::SortedSet["Dog", "Lion"].add?("Lion")
+    #   # => false
+    #
+    # @param item [Object] The object to add
+    # @return [SortedSet, false]
+    def add?(item)
+      !include?(item) && add(item)
+    end
+
+    # Return a new `SortedSet` with `item` removed. If `item` is not a member of the set,
+    # return `self`.
+    #
+    # @example
+    #   Hamster::SortedSet["A", "B", "C"].delete("B")
+    #   # => Hamster::SortedSet["A", "C"]
+    #
+    # @param item [Object] The object to remove
+    # @return [SortedSet]
+    def delete(item)
+      catch :not_present do
+        node = @node.delete(item)
+        if node.empty? && node.natural_order?
+          return self.class.empty
+        else
+          return self.class.alloc(node)
+        end
+      end
+      self
+    end
+
+    # If `item` is a member of this `SortedSet`, return a new `SortedSet` with
+    # `item` removed. Otherwise, return `false`.
+    #
+    # @example
+    #   Hamster::SortedSet["A", "B", "C"].delete?("B")
+    #   # => Hamster::SortedSet["A", "C"]
+    #   Hamster::SortedSet["A", "B", "C"].delete?("Z")
+    #   # => false
+    #
+    # @param item [Object] The object to remove
+    # @return [SortedSet, false]
+    def delete?(item)
+      include?(item) && delete(item)
+    end
+
+    # Return a new `SortedSet` with the item at `index` removed. If the given `index`
+    # does not exist (if it is too high or too low), return `self`.
+    #
+    # @example
+    #   Hamster::SortedSet["A", "B", "C", "D"].delete_at(2)
+    #   # => Hamster::SortedSet["A", "B", "D"]
+    #
+    # @param index [Integer] The index to remove
+    # @return [SortedSet]
+    def delete_at(index)
+      (item = at(index)) ? delete(item) : self
+    end
+
+    # Retrieve the item at `index`. If there is none (either the provided index
+    # is too high or too low), return `nil`.
+    #
+    # @example
+    #   s = Hamster::SortedSet["A", "B", "C", "D", "E", "F"]
+    #   s.at(2)   # => "C"
+    #   s.at(-2)  # => "E"
+    #   s.at(6)   # => nil
+    #
+    # @param index [Integer] The index to retrieve
+    # @return [Object]
+    def at(index)
+      index += @node.size if index < 0
+      return nil if index >= @node.size || index < 0
+      @node.at(index)
+    end
+
+    # Retrieve the value at `index` with optional default.
+    #
+    # @overload fetch(index)
+    #   Retrieve the value at the given index, or raise an `IndexError` if not
+    #   found.
+    #
+    #   @param index [Integer] The index to look up
+    #   @raise [IndexError] if index does not exist
+    #   @example
+    #     v = Hamster::SortedSet["A", "B", "C", "D"]
+    #     v.fetch(2)       # => "C"
+    #     v.fetch(-1)      # => "D"
+    #     v.fetch(4)       # => IndexError: index 4 outside of vector bounds
+    #
+    # @overload fetch(index) { |index| ... }
+    #   Retrieve the value at the given index, or return the result of yielding
+    #   the block if not found.
+    #
+    #   @yield Once if the index is not found.
+    #   @yieldparam [Integer] index The index which does not exist
+    #   @yieldreturn [Object] Default value to return
+    #   @param index [Integer] The index to look up
+    #   @example
+    #     v = Hamster::SortedSet["A", "B", "C", "D"]
+    #     v.fetch(2) { |i| i * i }   # => "C"
+    #     v.fetch(4) { |i| i * i }   # => 16
+    #
+    # @overload fetch(index, default)
+    #   Retrieve the value at the given index, or return the provided `default`
+    #   value if not found.
+    #
+    #   @param index [Integer] The index to look up
+    #   @param default [Object] Object to return if the key is not found
+    #   @example
+    #     v = Hamster::SortedSet["A", "B", "C", "D"]
+    #     v.fetch(2, "Z")  # => "C"
+    #     v.fetch(4, "Z")  # => "Z"
+    #
+    # @return [Object]
+    def fetch(index, default = (missing_default = true))
+      if index >= - at node.size && index < @node.size
+        at(index)
+      elsif block_given?
+        yield(index)
+      elsif !missing_default
+        default
+      else
+        raise IndexError, "index #{index} outside of sorted set bounds"
+      end
+    end
+
+    # Return specific objects from the `Vector`. All overloads return `nil` if
+    # the starting index is out of range.
+    #
+    # @overload set.slice(index)
+    #   Returns a single object at the given `index`. If `index` is negative,
+    #   count backwards from the end.
+    #
+    #   @param index [Integer] The index to retrieve. May be negative.
+    #   @return [Object]
+    #   @example
+    #     s = Hamster::SortedSet["A", "B", "C", "D", "E", "F"]
+    #     s[2]  # => "C"
+    #     s[-1] # => "F"
+    #     s[6]  # => nil
+    #
+    # @overload set.slice(index, length)
+    #   Return a subset starting at `index` and continuing for `length`
+    #   elements or until the end of the `SortedSet`, whichever occurs first.
+    #
+    #   @param start [Integer] The index to start retrieving items from. May be
+    #                          negative.
+    #   @param length [Integer] The number of items to retrieve.
+    #   @return [SortedSet]
+    #   @example
+    #     s = Hamster::SortedSet["A", "B", "C", "D", "E", "F"]
+    #     s[2, 3]  # => Hamster::SortedSet["C", "D", "E"]
+    #     s[-2, 3] # => Hamster::SortedSet["E", "F"]
+    #     s[20, 1] # => nil
+    #
+    # @overload set.slice(index..end)
+    #   Return a subset starting at `index` and continuing to index
+    #   `end` or the end of the `SortedSet`, whichever occurs first.
+    #
+    #   @param range [Range] The range of indices to retrieve.
+    #   @return [SortedSet]
+    #   @example
+    #     s = Hamster::SortedSet["A", "B", "C", "D", "E", "F"]
+    #     s[2..3]    # => Hamster::SortedSet["C", "D"]
+    #     s[-2..100] # => Hamster::SortedSet["E", "F"]
+    #     s[20..21]  # => nil
+    def slice(arg, length = (missing_length = true))
+      if missing_length
+        if arg.is_a?(Range)
+          from, to = arg.begin, arg.end
+          from += @node.size if from < 0
+          to   += @node.size if to < 0
+          to   += 1     if !arg.exclude_end?
+          length = to - from
+          length = 0 if length < 0
+          subsequence(from, length)
+        else
+          at(arg)
+        end
+      else
+        arg += @node.size if arg < 0
+        subsequence(arg, length)
+      end
+    end
+    alias :[] :slice
+
+    # Return a new `SortedSet` with only the elements at the given `indices`.
+    # If any of the `indices` do not exist, they will be skipped.
+    #
+    # @example
+    #   s = Hamster::SortedSet["A", "B", "C", "D", "E", "F"]
+    #   s.values_at(2, 4, 5)   # => Hamster::SortedSet["C", "E", "F"]
+    #
+    # @param indices [Array] The indices to retrieve and gather into a new `SortedSet`
+    # @return [SortedSet]
+    def values_at(*indices)
+      indices.select! { |i| i >= - at node.size && i < @node.size }
+      self.class.new(indices.map! { |i| at(i) })
+    end
+
+    # Call the given block once for each item in the set, passing each
+    # item from first to last successively to the block. If no block is
+    # provided, returns an `Enumerator`.
+    #
+    # @example
+    #   Hamster::SortedSet["A", "B", "C"].each { |e| puts "Element: #{e}" }
+    #
+    #   Element: A
+    #   Element: B
+    #   Element: C
+    #   # => Hamster::SortedSet["A", "B", "C"]
+    #
+    # @yield [item]
+    # @return [self, Enumerator]
+    def each(&block)
+      return @node.to_enum if not block_given?
+      @node.each(&block)
+      self
+    end
+
+    # Call the given block once for each item in the set, passing each
+    # item starting from the last, and counting back to the first, successively to
+    # the block.
+    #
+    # @example
+    #   Hamster::SortedSet["A", "B", "C"].reverse_each { |e| puts "Element: #{e}" }
+    #
+    #   Element: C
+    #   Element: B
+    #   Element: A
+    #   # => Hamster::SortedSet["A", "B", "C"]
+    #
+    # @return [self]
+    def reverse_each(&block)
+      return @node.enum_for(:reverse_each) if not block_given?
+      @node.reverse_each(&block)
+      self
+    end
+
+    # Return the "lowest" element in this set, as determined by its sort order.
+    # Or, if a block is provided, use the block as a comparator to find the
+    # "lowest" element. (See `Enumerable#min`.)
+    #
+    # @example
+    #   Hamster::SortedSet["A", "B", "C"].min  # => "A"
+    #
+    # @return [Object]
+    # @yield [a, b] Any number of times with different pairs of elements.
+    def min
+      block_given? ? super : @node.min
+    end
+
+    # Return the "lowest" element in this set, as determined by its sort order.
+    # @return [Object]
+    def first
+      @node.min
+    end
+
+    # Return the "highest" element in this set, as determined by its sort order.
+    # Or, if a block is provided, use the block as a comparator to find the
+    # "highest" element. (See `Enumerable#max`.)
+    #
+    # @example
+    #   Hamster::SortedSet["A", "B", "C"].max  # => "C"
+    #
+    # @yield [a, b] Any number of times with different pairs of elements.
+    # @return [Object]
+    def max
+      block_given? ? super : @node.max
+    end
+
+    # Return the "highest" element in this set, as determined by its sort order.
+    # @return [Object]
+    def last
+      @node.max
+    end
+
+    # Return a new `SortedSet` containing all elements for which the given block returns
+    # true.
+    #
+    # @example
+    #   Hamster::SortedSet["Bird", "Cow", "Elephant"].select { |e| e.size >= 4 }
+    #   # => Hamster::SortedSet["Bird", "Elephant"]
+    #
+    # @return [SortedSet]
+    # @yield [item] Once for each item.
+    def select
+      return enum_for(:select) unless block_given?
+      items_to_delete = []
+      each { |item| items_to_delete << item unless yield(item) }
+      derive_new_sorted_set(@node.bulk_delete(items_to_delete))
+    end
+    alias :find_all :select
+    alias :keep_if  :select
+
+    # Invoke the given block once for each item in the set, and return a new
+    # `SortedSet` containing the values returned by the block. If no block is
+    # given, returns an `Enumerator`.
+    #
+    # @example
+    #   Hamster::SortedSet[1, 2, 3].map { |e| -(e * e) }
+    #   # => Hamster::SortedSet[-9, -4, -1]
+    #
+    # @return [SortedSet, Enumerator]
+    # @yield [item] Once for each item.
+    def map
+      return enum_for(:map) if not block_given?
+      return self if empty?
+      self.class.alloc(@node.from_items(super))
+    end
+    alias :collect :map
+
+    # Return `true` if the given item is present in this `SortedSet`. More precisely,
+    # return `true` if an object which compares as "equal" using this set's
+    # comparator is present.
+    #
+    # @example
+    #   Hamster::SortedSet["A", "B", "C"].include?("B")  # => true
+    #
+    # @param item [Object] The object to check for
+    # @return [Boolean]
+    def include?(item)
+      @node.include?(item)
+    end
+    alias :member? :include?
+
+    # Return a new `SortedSet` with the same items, but a sort order determined
+    # by the given block.
+    #
+    # @example
+    #   Hamster::SortedSet["Bird", "Cow", "Elephant"].sort { |a, b| a.size <=> b.size }
+    #   # => Hamster::SortedSet["Cow", "Bird", "Elephant"]
+    #   Hamster::SortedSet["Bird", "Cow", "Elephant"].sort_by { |e| e.size }
+    #   # => Hamster::SortedSet["Cow", "Bird", "Elephant"]
+    #
+    # @return [SortedSet]
+    def sort(&block)
+      if block
+        self.class.new(self.to_a, &block)
+      else
+        self.class.new(self.to_a.sort)
+      end      
+    end
+    alias :sort_by :sort
+
+    # Find the index of a given object or an element that satisfies the given
+    # block.
+    #
+    # @overload find_index(obj)
+    #   Return the index of the first object in this set which is equal to
+    #   `obj`. Rather than using `#==`, we use `#<=>` (or our comparator block)
+    #   for comparisons. This means we can find the index in `O(log N)` time,
+    #   rather than `O(N)`.
+    #   @param obj [Object] The object to search for
+    #   @example
+    #     s = Hamster::SortedSet[2, 4, 6, 8, 10]
+    #     s.find_index(8)  # => 3
+    # @overload find_index
+    #   Return the index of the first object in this sorted set for which the
+    #   block returns to true. This takes `O(N)` time.
+    #   @yield [element] An element in the sorted set
+    #   @yieldreturn [Boolean] True if this is element matches
+    #   @example
+    #     s = Hamster::SortedSet[2, 4, 6, 8, 10]
+    #     s.find_index { |e| e > 7 }  # => 3
+    #
+    # @return [Integer] The index of the object, or `nil` if not found.
+    def find_index(obj = (missing_obj = true), &block)
+      if !missing_obj
+        # Enumerable provides a default implementation, but this is more efficient
+        node = @node
+        index = node.left.size
+        while !node.empty?
+          direction = node.direction(obj)
+          if direction > 0
+            node = node.right
+            index += (node.left.size + 1)
+          elsif direction < 0
+            node = node.left
+            index -= (node.right.size + 1)
+          else
+            return index
+          end
+        end
+        nil
+      else
+        super(&block)
+      end
+    end
+    alias :index :find_index
+
+    # Drop the first `n` elements and return the rest in a new `SortedSet`.
+    #
+    # @example
+    #   Hamster::SortedSet["A", "B", "C", "D", "E", "F"].drop(2)
+    #   # => Hamster::SortedSet["C", "D", "E", "F"]
+    #
+    # @param n [Integer] The number of elements to remove
+    # @return [SortedSet]
+    def drop(n)
+      derive_new_sorted_set(@node.drop(n))
+    end
+
+    # Return only the first `n` elements in a new `SortedSet`.
+    #
+    # @example
+    #   Hamster::SortedSet["A", "B", "C", "D", "E", "F"].take(4)
+    #   # => Hamster::SortedSet["A", "B", "C", "D"]
+    #
+    # @param n [Integer] The number of elements to retain
+    # @return [SortedSet]
+    def take(n)
+      derive_new_sorted_set(@node.take(n))
+    end
+
+    # Drop elements up to, but not including, the first element for which the
+    # block returns `nil` or `false`. Gather the remaining elements into a new
+    # `SortedSet`. If no block is given, an `Enumerator` is returned instead.
+    #
+    # @example
+    #   Hamster::SortedSet[2, 4, 6, 7, 8, 9].drop_while { |e| e.even? }
+    #   # => Hamster::SortedSet[7, 8, 9]
+    #
+    # @yield [item]
+    # @return [SortedSet, Enumerator]
+    def drop_while
+      return enum_for(:drop_while) if not block_given?
+      n = 0
+      each do |item|
+        break unless yield item
+        n += 1
+      end
+      drop(n)
+    end
+
+    # Gather elements up to, but not including, the first element for which the
+    # block returns `nil` or `false`, and return them in a new `SortedSet`. If no block
+    # is given, an `Enumerator` is returned instead.
+    #
+    # @example
+    #   Hamster::SortedSet[2, 4, 6, 7, 8, 9].take_while { |e| e.even? }
+    #   # => Hamster::SortedSet[2, 4, 6]
+    #
+    # @return [SortedSet, Enumerator]
+    # @yield [item]
+    def take_while
+      return enum_for(:take_while) if not block_given?
+      n = 0
+      each do |item|
+        break unless yield item
+        n += 1
+      end
+      take(n)
+    end
+
+    # Return a new `SortedSet` which contains all the members of both this set and `other`.
+    # `other` can be any `Enumerable` object.
+    #
+    # @example
+    #   Hamster::SortedSet[1, 2] | Hamster::SortedSet[2, 3]
+    #   # => Hamster::SortedSet[1, 2, 3]
+    #
+    # @param other [Enumerable] The collection to merge with
+    # @return [SortedSet]
+    def union(other)
+      self.class.alloc(@node.bulk_insert(other))
+    end
+    alias :| :union
+    alias :+ :union
+    alias :merge :union
+
+    # Return a new `SortedSet` which contains all the items which are members of both
+    # this set and `other`. `other` can be any `Enumerable` object.
+    #
+    # @example
+    #   Hamster::SortedSet[1, 2] & Hamster::SortedSet[2, 3]
+    #   # => Hamster::SortedSet[2]
+    #
+    # @param other [Enumerable] The collection to intersect with
+    # @return [SortedSet]
+    def intersection(other)
+      self.class.alloc(@node.keep_only(other))
+    end
+    alias :& :intersection
+
+    # Return a new `SortedSet` with all the items in `other` removed. `other` can be
+    # any `Enumerable` object.
+    #
+    # @example
+    #   Hamster::SortedSet[1, 2] - Hamster::SortedSet[2, 3]
+    #   # => Hamster::SortedSet[1]
+    #
+    # @param other [Enumerable] The collection to subtract from this set
+    # @return [SortedSet]
+    def difference(other)
+      self.class.alloc(@node.bulk_delete(other))
+    end
+    alias :subtract :difference
+    alias :- :difference
+
+    # Return a new `SortedSet` with all the items which are members of this
+    # set or of `other`, but not both. `other` can be any `Enumerable` object.
+    #
+    # @example
+    #   Hamster::SortedSet[1, 2] ^ Hamster::SortedSet[2, 3]
+    #   # => Hamster::SortedSet[1, 3]
+    #
+    # @param other [Enumerable] The collection to take the exclusive disjunction of
+    # @return [SortedSet]
+    def exclusion(other)
+      ((self | other) - (self & other))
+    end
+    alias :^ :exclusion
+
+    # Return `true` if all items in this set are also in `other`.
+    #
+    # @example
+    #   Hamster::SortedSet[2, 3].subset?(Hamster::SortedSet[1, 2, 3])  # => true
+    #
+    # @param other [Enumerable]
+    # @return [Boolean]
+    def subset?(other)
+      return false if other.size < size
+      all? { |item| other.include?(item) }
+    end
+
+    # Return `true` if all items in `other` are also in this set.
+    #
+    # @example
+    #   Hamster::SortedSet[1, 2, 3].superset?(Hamster::SortedSet[2, 3])  # => true
+    #
+    # @param other [Enumerable]
+    # @return [Boolean]
+    def superset?(other)
+      other.subset?(self)
+    end
+
+    # Returns `true` if `other` contains all the items in this set, plus at least
+    # one item which is not in this set.
+    #
+    # @example
+    #   Hamster::SortedSet[2, 3].proper_subset?(Hamster::SortedSet[1, 2, 3])     # => true
+    #   Hamster::SortedSet[1, 2, 3].proper_subset?(Hamster::SortedSet[1, 2, 3])  # => false
+    #
+    # @param other [Enumerable]
+    # @return [Boolean]
+    def proper_subset?(other)
+      return false if other.size <= size
+      all? { |item| other.include?(item) }
+    end
+
+    # Returns `true` if this set contains all the items in `other`, plus at least
+    # one item which is not in `other`.
+    #
+    # @example
+    #   Hamster::SortedSet[1, 2, 3].proper_superset?(Hamster::SortedSet[2, 3])     # => true
+    #   Hamster::SortedSet[1, 2, 3].proper_superset?(Hamster::SortedSet[1, 2, 3])  # => false
+    #
+    # @param other [Enumerable]
+    # @return [Boolean]
+    def proper_superset?(other)
+      other.proper_subset?(self)
+    end
+
+    # Return `true` if this set and `other` do not share any items.
+    #
+    # @example
+    #   Hamster::SortedSet[1, 2].disjoint?(Hamster::SortedSet[3, 4])  # => true
+    #
+    # @param other [Enumerable]
+    # @return [Boolean]
+    def disjoint?(other)
+      if size < other.size
+        each { |item| return false if other.include?(item) }
+      else
+        other.each { |item| return false if include?(item) }
+      end
+      true
+    end
+
+    # Return `true` if this set and `other` have at least one item in common.
+    #
+    # @example
+    #   Hamster::SortedSet[1, 2].intersect?(Hamster::SortedSet[2, 3])  # => true
+    #
+    # @param other [Enumerable]
+    # @return [Boolean]
+    def intersect?(other)
+      !disjoint?(other)
+    end
+
+    alias :group :group_by
+    alias :classify :group_by
+
+    # Select elements greater than a value.
+    #
+    # @overload above(item)
+    #   Return a new `SortedSet` containing all items greater than `item`.
+    #   @return [SortedSet]
+    #   @example
+    #     s = Hamster::SortedSet[2, 4, 6, 8, 10]
+    #     s.above(6)
+    #     # => Hamster::SortedSet[8, 10]
+    #  
+    # @overload above(item)
+    #   @yield [item] Once for each item greater than `item`, in order from
+    #                 lowest to highest.
+    #   @return [nil]
+    #   @example
+    #     s = Hamster::SortedSet[2, 4, 6, 8, 10]
+    #     s.above(6) { |e| puts "Element: #{e}" }
+    #  
+    #     Element: 8
+    #     Element: 10
+    #     # => nil
+    #
+    # @param item [Object]
+    def above(item, &block)
+      if block_given?
+        @node.each_greater(item, false, &block)
+      else
+        self.class.alloc(@node.suffix(item, false))
+      end
+    end
+
+    # Select elements less than a value.
+    #
+    # @overload below(item)
+    #   Return a new `SortedSet` containing all items less than `item`.
+    #   @return [SortedSet]
+    #   @example
+    #     s = Hamster::SortedSet[2, 4, 6, 8, 10]
+    #     s.below(6)
+    #     # => Hamster::SortedSet[2, 4]
+    #  
+    # @overload below(item)
+    #   @yield [item] Once for each item less than `item`, in order from lowest
+    #                 to highest.
+    #   @return [nil]
+    #   @example
+    #     s = Hamster::SortedSet[2, 4, 6, 8, 10]
+    #     s.below(6) { |e| puts "Element: #{e}" }
+    #  
+    #     Element: 2
+    #     Element: 4 
+    #     # => nil
+    #
+    # @param item [Object]
+    def below(item, &block)
+      if block_given?
+        @node.each_less(item, false, &block)
+      else
+        self.class.alloc(@node.prefix(item, false))
+      end
+    end
+
+    # Select elements greater than or equal to a value.
+    #
+    # @overload from(item)
+    #   Return a new `SortedSet` containing all items greater than or equal `item`.
+    #   @return [SortedSet]
+    #   @example
+    #     s = Hamster::SortedSet[2, 4, 6, 8, 10]
+    #     s.from(6)
+    #     # => Hamster::SortedSet[6, 8, 10]
+    #  
+    # @overload from(item)
+    #   @yield [item] Once for each item greater than or equal to `item`, in
+    #                 order from lowest to highest.
+    #   @return [nil]
+    #   @example
+    #     s = Hamster::SortedSet[2, 4, 6, 8, 10]
+    #     s.from(6) { |e| puts "Element: #{e}" }
+    #  
+    #     Element: 6
+    #     Element: 8
+    #     Element: 10
+    #     # => nil
+    #
+    # @param item [Object]
+    def from(item, &block)
+      if block_given?
+        @node.each_greater(item, true, &block)
+      else
+        self.class.alloc(@node.suffix(item, true))
+      end
+    end
+
+    # Select elements less than or equal to a value.
+    #
+    # @overload up_to(item)
+    #   Return a new `SortedSet` containing all items less than or equal to 
+    #   `item`.
+    #
+    #   @return [SortedSet]
+    #   @example
+    #     s = Hamster::SortedSet[2, 4, 6, 8, 10]
+    #     s.upto(6)
+    #     # => Hamster::SortedSet[2, 4, 6]
+    #  
+    # @overload up_to(item)
+    #   @yield [item] Once for each item less than or equal to `item`, in order
+    #                 from lowest to highest.
+    #   @return [nil]
+    #   @example
+    #     s = Hamster::SortedSet[2, 4, 6, 8, 10]
+    #     s.up_to(6) { |e| puts "Element: #{e}" }
+    #  
+    #     Element: 2
+    #     Element: 4 
+    #     Element: 6 
+    #     # => nil
+    #
+    # @param item [Object]
+    def up_to(item, &block)
+      if block_given?
+        @node.each_less(item, true, &block)
+      else
+        self.class.alloc(@node.prefix(item, true))
+      end
+    end
+
+    # Select elements between two values.
+    #
+    # @overload between(from, to)
+    #   Return a new `SortedSet` containing all items less than or equal to
+    #   `to` and greater than or equal to `from`.
+    #
+    #   @return [SortedSet]
+    #   @example
+    #     s = Hamster::SortedSet[2, 4, 6, 8, 10]
+    #     s.between(5, 8)
+    #     # => Hamster::SortedSet[6, 8]
+    #  
+    # @overload between(item)
+    #   @yield [item] Once for each item less than or equal to `to` and greater
+    #                 than or equal to `from`, in order from lowest to highest.
+    #   @return [nil]
+    #   @example
+    #     s = Hamster::SortedSet[2, 4, 6, 8, 10]
+    #     s.between(5, 8) { |e| puts "Element: #{e}" }
+    #  
+    #     Element: 6
+    #     Element: 8 
+    #     # => nil
+    #
+    # @param from [Object]
+    # @param to [Object]
+    def between(from, to, &block)
+      if block_given?
+        @node.each_between(from, to, &block)
+      else
+        self.class.alloc(@node.between(from, to))
+      end
+    end
+
+    # Return a randomly chosen item from this set. If the set is empty, return `nil`.
+    #
+    # @example
+    #   Hamster::SortedSet[1, 2, 3, 4, 5].sample  # => 2
+    #
+    # @return [Object]
+    def sample
+      @node.at(rand(@node.size))
+    end
+
+    # Return an empty `SortedSet` instance, of the same class as this one. Useful if you
+    # have multiple subclasses of `SortedSet` and want to treat them polymorphically.
+    #
+    # @return [SortedSet]
+    def clear
+      if @node.natural_order?
+        self.class.empty
+      else
+        self.class.alloc(@node.clear)
+      end
+    end
+
+    # Return true if `other` has the same type and contents as this `SortedSet`.
+    #
+    # @param other [Object] The object to compare with
+    # @return [Boolean]
+    def eql?(other)
+      return true if other.equal?(self)
+      return false if not instance_of?(other.class)
+      return false if size != other.size
+      a, b = self.to_enum, other.to_enum
+      while true
+        return false if !a.next.eql?(b.next)
+      end
+    rescue StopIteration
+      true
+    end
+
+    # See `Object#hash`.
+    # @return [Integer]
+    def hash
+      reduce(0) { |hash, item| (hash << 5) - hash + item.hash }
+    end
+
+    # @return [::Array]
+    # @private
+    def marshal_dump
+      if @node.natural_order?
+        to_a
+      else
+        raise TypeError, "can't dump SortedSet with custom sort order"
+      end
+    end
+
+    # @private
+    def marshal_load(array)
+      initialize(array)
+    end
+
+    private
+
+    def subsequence(from, length)
+      return nil if from > @node.size || from < 0 || length < 0
+      length = @node.size - from if @node.size < from + length
+      if length == 0
+        if @node.natural_order?
+          return self.class.empty
+        else
+          return self.class.alloc(@node.clear)
+        end
+      end
+      self.class.alloc(@node.slice(from, length))
+    end
+
+    # Return a new `SortedSet` which is derived from this one, using a modified
+    # {AVLNode}.  The new `SortedSet` will retain the existing comparator, if
+    # there is one.
+    def derive_new_sorted_set(node)
+      if node.equal?(@node)
+        self
+      elsif node.empty?
+        clear
+      else
+        self.class.alloc(node)
+      end
+    end
+
+    # @private
+    class AVLNode
+      def self.from_items(items, comparator, from = 0, to = items.size-1) # items must be sorted
+        size = to - from + 1
+        if size >= 3
+          middle = (to + from) / 2
+          AVLNode.new(items[middle], comparator, AVLNode.from_items(items, comparator, from, middle-1), AVLNode.from_items(items, comparator, middle+1, to))
+        elsif size == 2
+          empty = AVLNode::Empty.new(comparator)
+          AVLNode.new(items[from], comparator, empty, AVLNode.new(items[from+1], comparator, empty, empty))
+        elsif size == 1
+          empty = AVLNode::Empty.new(comparator)
+          AVLNode.new(items[from], comparator, empty, empty)
+        elsif size == 0
+          AVLNode::Empty.new(comparator)
+        end
+      end
+
+      def initialize(item, comparator, left, right)
+        @item, @comparator, @left, @right = item, comparator, left, right
+        @height = ((right.height > left.height) ? right.height : left.height) + 1
+        @size   = right.size + left.size + 1
+      end
+      attr_reader :item, :left, :right, :height, :size
+
+      def from_items(items)
+        AVLNode.from_items(items.sort(&@comparator), @comparator)
+      end
+
+      def natural_order?
+        false
+      end
+
+      def empty?
+        false
+      end
+
+      def clear
+        AVLNode::Empty.new(@comparator)
+      end
+
+      def derive(item, left, right)
+        AVLNode.new(item, @comparator, left, right)
+      end
+
+      def insert(item)
+        dir = direction(item)
+        if dir == 0
+          throw :present
+        elsif dir > 0
+          rebalance_right(@left, @right.insert(item))
+        else
+          rebalance_left(@left.insert(item), @right)
+        end
+      end
+
+      def bulk_insert(items)
+        return self if items.empty?
+        if items.size == 1
+          catch :present do
+            return insert(items.first)
+          end
+          return self
+        end
+        left, right = partition(items)
+
+        if right.size > left.size
+          rebalance_right(@left.bulk_insert(left), @right.bulk_insert(right))
+        else
+          rebalance_left(@left.bulk_insert(left), @right.bulk_insert(right))
+        end
+      end
+
+      def delete(item)
+        dir = direction(item)
+        if dir == 0
+          if @right.empty?
+            return @left # replace this node with its only child
+          elsif @left.empty?
+            return @right # likewise
+          end
+
+          if balance > 0
+            # tree is leaning to the left. replace with highest node on that side
+            replace_with = @left.max
+            derive(replace_with, @left.delete(replace_with), @right)
+          else
+            # tree is leaning to the right. replace with lowest node on that side
+            replace_with = @right.min
+            derive(replace_with, @left, @right.delete(replace_with))
+          end
+        elsif dir > 0
+          rebalance_left(@left, @right.delete(item))
+        else
+          rebalance_right(@left.delete(item), @right)
+        end
+      end
+
+      def bulk_delete(items)
+        return self if items.empty?
+        if items.size == 1
+          catch :not_present do
+            return delete(items.first)
+          end
+          return self
+        end
+
+        left, right, keep_item = [], [], true
+        items.each do |item|
+          dir = direction(item)
+          if dir > 0
+            right << item
+          elsif dir < 0
+            left << item
+          else
+            keep_item = false
+          end
+        end
+
+        left  = @left.bulk_delete(left)
+        right = @right.bulk_delete(right)
+        finish_removal(keep_item, left, right)
+      end
+
+      def keep_only(items)
+        return clear if items.empty?
+
+        left, right, keep_item = [], [], false
+        items.each do |item|
+          dir = direction(item)
+          if dir > 0
+            right << item
+          elsif dir < 0
+            left << item
+          else
+            keep_item = true
+          end
+        end
+
+        left  = @left.keep_only(left)
+        right = @right.keep_only(right)
+        finish_removal(keep_item, left, right)
+      end
+
+      def finish_removal(keep_item, left, right)
+        # deletion of items may have occurred on left and right sides
+        # now we may also need to delete the current item
+        if keep_item
+          rebalance(left, right) # no need to delete the current item
+        elsif left.empty?
+          right
+        elsif right.empty?
+          left
+        elsif left.height > right.height
+          replace_with = left.max
+          derive(replace_with, left.delete(replace_with), right)
+        else
+          replace_with = right.min
+          derive(replace_with, left, right.delete(replace_with))
+        end
+      end
+
+      def prefix(item, inclusive)
+        dir = direction(item)
+        if dir > 0 || (inclusive && dir == 0)
+          rebalance_left(@left, @right.prefix(item, inclusive))
+        else
+          @left.prefix(item, inclusive)
+        end
+      end
+
+      def suffix(item, inclusive)
+        dir = direction(item)
+        if dir < 0 || (inclusive && dir == 0)
+          rebalance_right(@left.suffix(item, inclusive), @right)
+        else
+          @right.suffix(item, inclusive)
+        end
+      end
+
+      def between(from, to)
+        if direction(from) > 0 # all on the right
+          @right.between(from, to)
+        elsif direction(to) < 0 # all on the left
+          @left.between(from, to)
+        else
+          left = @left.suffix(from, true)
+          right = @right.prefix(to, true)
+          rebalance(left, right)
+        end
+      end
+
+      def each_less(item, inclusive, &block)
+        dir = direction(item)
+        if dir > 0 || (inclusive && dir == 0)
+          @left.each(&block)
+          yield @item
+          @right.each_less(item, inclusive, &block)
+        else
+          @left.each_less(item, inclusive, &block)
+        end
+      end
+
+      def each_greater(item, inclusive, &block)
+        dir = direction(item)
+        if dir < 0 || (inclusive && dir == 0)
+          @left.each_greater(item, inclusive, &block)
+          yield @item
+          @right.each(&block)
+        else
+          @right.each_greater(item, inclusive, &block)
+        end
+      end
+
+      def each_between(from, to, &block)
+        if direction(from) > 0 # all on the right
+          @right.each_between(from, to, &block)
+        elsif direction(to) < 0 # all on the left
+          @left.each_between(from, to, &block)
+        else
+          @left.each_greater(from, true, &block)
+          yield @item
+          @right.each_less(to, true, &block)
+        end
+      end
+
+      def each(&block)
+        @left.each(&block)
+        yield @item
+        @right.each(&block)
+      end
+
+      def reverse_each(&block)
+        @right.reverse_each(&block)
+        yield @item
+        @left.reverse_each(&block)
+      end
+
+      def drop(n)
+        if n >= @size
+          clear
+        elsif n <= 0
+          self
+        elsif @left.size >= n
+          rebalance_right(@left.drop(n), @right)
+        elsif @left.size + 1 == n
+          @right
+        else
+          @right.drop(n - @left.size - 1)
+        end
+      end
+
+      def take(n)
+        if n >= @size
+          self
+        elsif n <= 0
+          clear
+        elsif @left.size >= n
+          @left.take(n)
+        else
+          rebalance_left(@left, @right.take(n - @left.size - 1))
+        end
+      end
+
+      def include?(item)
+        dir = direction(item)
+        if dir == 0
+          true
+        elsif dir > 0
+          @right.include?(item)
+        else
+          @left.include?(item)
+        end
+      end
+
+      def at(index)
+        if index < @left.size
+          @left.at(index)
+        elsif index > @left.size
+          @right.at(index - @left.size - 1)
+        else
+          @item
+        end
+      end
+
+      def max
+        @right.empty? ? @item : @right.max
+      end
+
+      def min
+        @left.empty? ? @item : @left.min
+      end
+
+      def balance
+        @left.height - @right.height
+      end
+
+      def slice(from, length)
+        if length <= 0
+          clear
+        elsif from + length <= @left.size
+          @left.slice(from, length)
+        elsif from > @left.size
+          @right.slice(from - @left.size - 1, length)
+        else
+          left  = @left.slice(from, @left.size - from)
+          right = @right.slice(0, from + length - @left.size - 1)
+          rebalance(left, right)
+        end
+      end
+
+      def partition(items)
+        left, right = [], []
+        items.each do |item|
+          dir = direction(item)
+          if dir > 0
+            right << item
+          elsif dir < 0
+            left << item
+          end
+        end
+        [left, right]
+      end
+
+      def rebalance(left, right)
+        if left.height > right.height
+          rebalance_left(left, right)
+        else
+          rebalance_right(left, right)
+        end
+      end
+
+      def rebalance_left(left, right)
+        # the tree might be unbalanced to the left (paths on the left too long)
+        balance = left.height - right.height
+        if balance >= 2
+          if left.balance > 0
+            # single right rotation
+            derive(left.item, left.left, derive(@item, left.right, right))
+          else
+            # left rotation, then right
+            derive(left.right.item, derive(left.item, left.left, left.right.left), derive(@item, left.right.right, right))
+          end
+        else
+          derive(@item, left, right)
+        end
+      end
+
+      def rebalance_right(left, right)
+        # the tree might be unbalanced to the right (paths on the right too long)
+        balance = left.height - right.height
+        if balance <= -2
+          if right.balance > 0
+            # right rotation, then left
+            derive(right.left.item, derive(@item, left, right.left.left), derive(right.item, right.left.right, right.right))
+          else
+            # single left rotation
+            derive(right.item, derive(@item, left, right.left), right.right)
+          end
+        else
+          derive(@item, left, right)
+        end
+      end
+
+      def direction(item)
+        @comparator.call(item, @item)
+      end
+
+      # @private
+      class Empty
+        def initialize(comparator); @comparator = comparator; end
+        def natural_order?; false; end
+        def left;  self;    end
+        def right; self;    end
+        def height;   0;    end
+        def size;     0;    end
+        def min;    nil;    end
+        def max;    nil;    end
+        def each;           end
+        def reverse_each;   end
+        def at(index); nil; end
+        def insert(item)
+          AVLNode.new(item, @comparator, self, self)
+        end
+        def bulk_insert(items)
+          items = items.to_a if !items.is_a?(Array)
+          AVLNode.from_items(items.sort(&@comparator), @comparator)
+        end
+        def bulk_delete(items); self; end
+        def keep_only(items);   self; end
+        def delete(item);       throw :not_present; end
+        def include?(item);     false; end
+        def prefix(item, inclusive); self; end
+        def suffix(item, inclusive); self; end
+        def between(from, to);       self; end
+        def each_greater(item, inclusive); end
+        def each_less(item, inclusive);    end
+        def each_between(item, inclusive); end
+        def drop(n);             self; end
+        def take(n);             self; end
+        def empty?;              true; end
+        def slice(from, length); self; end
+      end
+    end
+
+    # @private
+    # AVL node which does not use a comparator function; it keeps items sorted
+    #   in their natural order
+    class PlainAVLNode < AVLNode
+      def self.from_items(items, from = 0, to = items.size-1) # items must be sorted
+        size = to - from + 1
+        if size >= 3
+          middle = (to + from) / 2
+          PlainAVLNode.new(items[middle], PlainAVLNode.from_items(items, from, middle-1), PlainAVLNode.from_items(items, middle+1, to))
+        elsif size == 2
+          PlainAVLNode.new(items[from], PlainAVLNode::EmptyNode, PlainAVLNode.new(items[from+1], PlainAVLNode::EmptyNode, PlainAVLNode::EmptyNode))
+        elsif size == 1
+          PlainAVLNode.new(items[from], PlainAVLNode::EmptyNode, PlainAVLNode::EmptyNode)
+        elsif size == 0
+          PlainAVLNode::EmptyNode
+        end
+      end
+
+      def initialize(item, left, right)
+        @item,  @left, @right = item, left, right
+        @height = ((right.height > left.height) ? right.height : left.height) + 1
+        @size   = right.size + left.size + 1
+      end
+      attr_reader :item, :left, :right, :height, :size
+
+      def from_items(items)
+        PlainAVLNode.from_items(items.sort)
+      end
+
+      def natural_order?
+        true
+      end
+
+      def clear
+        PlainAVLNode::EmptyNode
+      end
+
+      def derive(item, left, right)
+        PlainAVLNode.new(item, left, right)
+      end
+
+      def direction(item)
+        item <=> @item
+      end
+
+      # @private
+      class Empty < AVLNode::Empty
+        def initialize;           end
+        def natural_order?; true; end
+        def insert(item)
+          PlainAVLNode.new(item, self, self)
+        end
+        def bulk_insert(items)
+          items = items.to_a if !items.is_a?(Array)
+          PlainAVLNode.from_items(items.sort)
+        end
+      end
+
+      EmptyNode = PlainAVLNode::Empty.new
+    end
+  end
+
+  # The canonical empty `SortedSet`. Returned by `SortedSet[]`
+  # when invoked with no arguments; also returned by `SortedSet.empty`. Prefer using
+  # this one rather than creating many empty sorted sets using `SortedSet.new`.
+  #
+  # @private
+  EmptySortedSet = Hamster::SortedSet.empty
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/trie.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/trie.rb
new file mode 100755
index 0000000..d5564ef
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/trie.rb
@@ -0,0 +1,338 @@
+module Hamster
+  # @private
+  class Trie
+    def self.[](pairs)
+      result = self.new(0)
+      pairs.each { |key, val| result.put!(key, val) }
+      result
+    end
+
+    # Returns the number of key-value pairs in the trie.
+    attr_reader :size
+
+    def initialize(significant_bits, size = 0, entries = [], children = [])
+      @significant_bits = significant_bits
+      @entries = entries
+      @children = children
+      @size = size
+    end
+
+    # Returns <tt>true</tt> if the trie contains no key-value pairs.
+    def empty?
+      size == 0
+    end
+
+    # Returns <tt>true</tt> if the given key is present in the trie.
+    def key?(key)
+      !!get(key)
+    end
+
+    # Calls <tt>block</tt> once for each entry in the trie, passing the key-value pair as parameters.
+    def each(&block)
+      # TODO: Using block.call here is slower than using yield by 5-10%, but
+      # the latter segfaults on ruby 2.2 and above. Once that is fixed and
+      # broken versions are sufficiently old, we should revert back to yield
+      # with a warning that the broken versions are unsupported.
+      #
+      # For more context:
+      # * https://bugs.ruby-lang.org/issues/11451
+      # * https://github.com/hamstergem/hamster/issues/189
+      @entries.each { |entry| block.call(entry) if entry }
+      @children.each do |child|
+        child.each(&block) if child
+      end
+      nil
+    end
+
+    def reverse_each(&block)
+      @children.reverse_each do |child|
+        child.reverse_each(&block) if child
+      end
+      @entries.reverse_each { |entry| yield(entry) if entry }
+      nil
+    end
+
+    def reduce(memo)
+      each { |entry| memo = yield(memo, entry) }
+      memo
+    end
+
+    def select
+      keys_to_delete = []
+      each { |entry| keys_to_delete << entry[0] unless yield(entry) }
+      bulk_delete(keys_to_delete)
+    end
+
+    # @return [Trie] A copy of `self` with the given value associated with the
+    #   key (or `self` if no modification was needed because an identical
+    #   key-value pair wes already stored
+    def put(key, value)
+      index = index_for(key)
+      entry = @entries[index]
+
+      if !entry
+        entries = @entries.dup
+        key = key.dup.freeze if key.is_a?(String) && !key.frozen?
+        entries[index] = [key, value].freeze
+        Trie.new(@significant_bits, @size + 1, entries, @children)
+      elsif entry[0].eql?(key)
+        if entry[1].equal?(value)
+          self
+        else
+          entries = @entries.dup
+          key = key.dup.freeze if key.is_a?(String) && !key.frozen?
+          entries[index] = [key, value].freeze
+          Trie.new(@significant_bits, @size, entries, @children)
+        end
+      else
+        child = @children[index]
+        if child
+          new_child = child.put(key, value)
+          if new_child.equal?(child)
+            self
+          else
+            children = @children.dup
+            children[index] = new_child
+            new_self_size = @size + (new_child.size - child.size)
+            Trie.new(@significant_bits, new_self_size, @entries, children)
+          end
+        else
+          children = @children.dup
+          children[index] = Trie.new(@significant_bits + 5).put!(key, value)
+          Trie.new(@significant_bits, @size + 1, @entries, children)
+        end
+      end
+    end
+
+    # Put multiple elements into a Trie.  This is more efficient than several
+    # calls to `#put`.
+    #
+    # @param key_value_pairs Enumerable of pairs (`[key, value]`)
+    # @return [Trie] A copy of `self` after associated the given keys and
+    #   values (or `self` if no modifications where needed).
+    def bulk_put(key_value_pairs)
+      new_entries = nil
+      new_children = nil
+      new_size = @size
+
+      key_value_pairs.each do |key, value|
+        index = index_for(key)
+        entry = (new_entries || @entries)[index]
+
+        if !entry
+          new_entries ||= @entries.dup
+          key = key.dup.freeze if key.is_a?(String) && !key.frozen?
+          new_entries[index] = [key, value].freeze
+          new_size += 1
+        elsif entry[0].eql?(key)
+          if !entry[1].equal?(value)
+            new_entries ||= @entries.dup
+            key = key.dup.freeze if key.is_a?(String) && !key.frozen?
+            new_entries[index] = [key, value].freeze
+          end
+        else
+          child = (new_children || @children)[index]
+          if child
+            new_child = child.put(key, value)
+            if !new_child.equal?(child)
+              new_children ||= @children.dup
+              new_children[index] = new_child
+              new_size += new_child.size - child.size
+            end
+          else
+            new_children ||= @children.dup
+            new_children[index] = Trie.new(@significant_bits + 5).put!(key, value)
+            new_size += 1
+          end
+        end
+      end
+
+      if new_entries || new_children
+        Trie.new(@significant_bits, new_size, new_entries || @entries, new_children || @children)
+      else
+        self
+      end
+    end
+
+    # Returns <tt>self</tt> after overwriting the element associated with the specified key.
+    def put!(key, value)
+      index = index_for(key)
+      entry = @entries[index]
+      if !entry
+        @size += 1
+        key = key.dup.freeze if key.is_a?(String) && !key.frozen?
+        @entries[index] = [key, value].freeze
+      elsif entry[0].eql?(key)
+        key = key.dup.freeze if key.is_a?(String) && !key.frozen?
+        @entries[index] = [key, value].freeze
+      else
+        child = @children[index]
+        if child
+          old_child_size = child.size
+          @children[index] = child.put!(key, value)
+          @size += child.size - old_child_size
+        else
+          @children[index] = Trie.new(@significant_bits + 5).put!(key, value)
+          @size += 1
+        end
+      end
+      self
+    end
+
+    # Retrieves the entry corresponding to the given key. If not found, returns <tt>nil</tt>.
+    def get(key)
+      index = index_for(key)
+      entry = @entries[index]
+      if entry && entry[0].eql?(key)
+        entry
+      else
+        child = @children[index]
+        child.get(key) if child
+      end
+    end
+
+    # Returns a copy of <tt>self</tt> with the given key (and associated value) deleted. If not found, returns <tt>self</tt>.
+    def delete(key)
+      find_and_delete(key) || Trie.new(@significant_bits)
+    end
+
+    # Delete multiple elements from a Trie.  This is more efficient than
+    # several calls to `#delete`.
+    #
+    # @param keys [Enumerable] The keys to delete
+    # @return [Trie]
+    def bulk_delete(keys)
+      new_entries = nil
+      new_children = nil
+      new_size = @size
+
+      keys.each do |key|
+        index = index_for(key)
+        entry = (new_entries || @entries)[index]
+        if !entry
+          next
+        elsif entry[0].eql?(key)
+          new_entries ||= @entries.dup
+          child = (new_children || @children)[index]
+          if child
+            # Bring up the first entry from the child into entries
+            new_children ||= @children.dup
+            new_children[index] = child.delete_at do |entry|
+              new_entries[index] = entry
+            end
+          else
+            new_entries[index] = nil
+          end
+          new_size -= 1
+        else
+          child = (new_children || @children)[index]
+          if child
+            copy = child.find_and_delete(key)
+            unless copy.equal?(child)
+              new_children ||= @children.dup
+              new_children[index] = copy
+              new_size -= (child.size - copy_size(copy))
+            end
+          end
+        end
+      end
+
+      if new_entries || new_children
+        Trie.new(@significant_bits, new_size, new_entries || @entries, new_children || @children)
+      else
+        self
+      end
+    end
+
+    def include?(key, value)
+      entry = get(key)
+      entry && value.eql?(entry[1])
+    end
+
+    def at(index)
+      @entries.each do |entry|
+        if entry
+          return entry if index == 0
+          index -= 1
+        end
+      end
+      @children.each do |child|
+        if child
+          if child.size >= index+1
+            return child.at(index)
+          else
+            index -= child.size
+          end
+        end
+      end
+      nil
+    end
+
+    # Returns <tt>true</tt> if . <tt>eql?</tt> is synonymous with <tt>==</tt>
+    def eql?(other)
+      return true if equal?(other)
+      return false unless instance_of?(other.class) && size == other.size
+      each do |entry|
+        return false unless other.include?(entry[0], entry[1])
+      end
+      true
+    end
+    alias :== :eql?
+
+    protected
+
+    # Returns a replacement instance after removing the specified key.
+    # If not found, returns <tt>self</tt>.
+    # If empty, returns <tt>nil</tt>.
+    def find_and_delete(key)
+      index = index_for(key)
+      entry = @entries[index]
+      if entry && entry[0].eql?(key)
+        return delete_at(index)
+      else
+        child = @children[index]
+        if child
+          copy = child.find_and_delete(key)
+          unless copy.equal?(child)
+            children = @children.dup
+            children[index] = copy
+            new_size = @size - (child.size - copy_size(copy))
+            return Trie.new(@significant_bits, new_size, @entries, children)
+          end
+        end
+      end
+      self
+    end
+
+    # Returns a replacement instance after removing the specified entry. If empty, returns <tt>nil</tt>
+    def delete_at(index = @entries.index { |e| e })
+      yield(@entries[index]) if block_given?
+      if size > 1
+        entries = @entries.dup
+        child = @children[index]
+        if child
+          children = @children.dup
+          children[index] = child.delete_at do |entry|
+            entries[index] = entry
+          end
+        else
+          entries[index] = nil
+        end
+        Trie.new(@significant_bits, @size - 1, entries, children || @children)
+      end
+    end
+
+    private
+
+    def index_for(key)
+      (key.hash.abs >> @significant_bits) & 31
+    end
+
+    def copy_size(copy)
+      copy ? copy.size : 0
+    end
+  end
+
+  # @private
+  EmptyTrie = Hamster::Trie.new(0)
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/undefined.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/undefined.rb
new file mode 100755
index 0000000..22b7f04
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/undefined.rb
@@ -0,0 +1,5 @@
+module Hamster
+  # @private
+  module Undefined
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/vector.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/vector.rb
new file mode 100755
index 0000000..41370e7
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/vector.rb
@@ -0,0 +1,1521 @@
+require "hamster/immutable"
+require "hamster/enumerable"
+require "hamster/hash"
+require "hamster/associable"
+
+module Hamster
+  # A `Vector` is an ordered, integer-indexed collection of objects. Like
+  # Ruby's `Array`, `Vector` indexing starts at zero and negative indexes count
+  # back from the end.
+  #
+  # `Vector` has a similar interface to `Array`. The main difference is methods
+  # that would destructively update an `Array` (such as {#insert} or
+  # {#delete_at}) instead return new `Vectors` and leave the existing one
+  # unchanged.
+  #
+  # ### Creating New Vectors
+  #
+  #     Hamster::Vector.new([:first, :second, :third])
+  #     Hamster::Vector[1, 2, 3, 4, 5]
+  #
+  # ### Retrieving Items from Vectors
+  #
+  #     vector = Hamster::Vector[1, 2, 3, 4, 5]
+  #
+  #     vector[0]      # => 1
+  #     vector[-1]     # => 5
+  #     vector[0,3]    # => Hamster::Vector[1, 2, 3]
+  #     vector[1..-1]  # => Hamster::Vector[2, 3, 4, 5]
+  #     vector.first   # => 1
+  #     vector.last    # => 5
+  #
+  # ### Creating Modified Vectors
+  #
+  #     vector.add(6)            # => Hamster::Vector[1, 2, 3, 4, 5, 6]
+  #     vector.insert(1, :a, :b) # => Hamster::Vector[1, :a, :b, 2, 3, 4, 5]
+  #     vector.delete_at(2)      # => Hamster::Vector[1, 2, 4, 5]
+  #     vector + [6, 7]          # => Hamster::Vector[1, 2, 3, 4, 5, 6, 7]
+  #
+  class Vector
+    include Immutable
+    include Enumerable
+    include Associable
+
+    # @private
+    BLOCK_SIZE = 32
+    # @private
+    INDEX_MASK = BLOCK_SIZE - 1
+    # @private
+    BITS_PER_LEVEL = 5
+
+    # Return the number of items in this `Vector`
+    # @return [Integer]
+    attr_reader :size
+    alias :length :size
+
+    class << self
+      # Create a new `Vector` populated with the given items.
+      # @return [Vector]
+      def [](*items)
+        new(items.freeze)
+      end
+
+      # Return an empty `Vector`. If used on a subclass, returns an empty instance
+      # of that class.
+      #
+      # @return [Vector]
+      def empty
+        @empty ||= self.new
+      end
+
+      # "Raw" allocation of a new `Vector`. Used internally to create a new
+      # instance quickly after building a modified trie.
+      #
+      # @return [Vector]
+      # @private
+      def alloc(root, size, levels)
+        obj = allocate
+        obj.instance_variable_set(:@root, root)
+        obj.instance_variable_set(:@size, size)
+        obj.instance_variable_set(:@levels, levels)
+        obj
+      end
+    end
+
+    def initialize(items=[].freeze)
+      items = items.to_a
+      if items.size <= 32
+        items = items.dup.freeze if !items.frozen?
+        @root, @size, @levels = items, items.size, 0
+      else
+        root, size, levels = items, items.size, 0
+        while root.size > 32
+          root = root.each_slice(32).to_a
+          levels += 1
+        end
+        @root, @size, @levels = root.freeze, size, levels
+      end
+    end
+
+    # Return `true` if this `Vector` contains no items.
+    #
+    # @return [Boolean]
+    def empty?
+      @size == 0
+    end
+
+    # Return the first item in the `Vector`. If the vector is empty, return `nil`.
+    #
+    # @example
+    #   Hamster::Vector["A", "B", "C"].first  # => "A"
+    #
+    # @return [Object]
+    def first
+      get(0)
+    end
+
+    # Return the last item in the `Vector`. If the vector is empty, return `nil`.
+    #
+    # @example
+    #   Hamster::Vector["A", "B", "C"].last  # => "C"
+    #
+    # @return [Object]
+    def last
+      get(-1)
+    end
+
+    # Return a new `Vector` with `item` added after the last occupied position.
+    #
+    # @example
+    #   Hamster::Vector[1, 2].add(99)  # => Hamster::Vector[1, 2, 99]
+    #
+    # @param item [Object] The object to insert at the end of the vector
+    # @return [Vector]
+    def add(item)
+      update_root(@size, item)
+    end
+    alias :<< :add
+    alias :push :add
+
+    # Return a new `Vector` with a new value at the given `index`. If `index`
+    # is greater than the length of the vector, the returned vector will be
+    # padded with `nil`s to the correct size.
+    #
+    # @overload put(index, item)
+    #   Return a new `Vector` with the item at `index` replaced by `item`.
+    #
+    #   @param item [Object] The object to insert into that position
+    #   @example
+    #     Hamster::Vector[1, 2, 3, 4].put(2, 99)
+    #     # => Hamster::Vector[1, 2, 99, 4]
+    #     Hamster::Vector[1, 2, 3, 4].put(-1, 99)
+    #     # => Hamster::Vector[1, 2, 3, 99]
+    #     Hamster::Vector[].put(2, 99)
+    #     # => Hamster::Vector[nil, nil, 99]
+    #
+    # @overload put(index)
+    #   Return a new `Vector` with the item at `index` replaced by the return
+    #   value of the block.
+    #
+    #   @yield (existing) Once with the existing value at the given `index`.
+    #   @example
+    #     Hamster::Vector[1, 2, 3, 4].put(2) { |v| v * 10 }
+    #     # => Hamster::Vector[1, 2, 30, 4]
+    #
+    # @param index [Integer] The index to update. May be negative.
+    # @return [Vector]
+    def put(index, item = yield(get(index)))
+      raise IndexError, "index #{index} outside of vector bounds" if index < - at size
+      index += @size if index < 0
+      if index > @size
+        suffix = Array.new(index - @size, nil)
+        suffix << item
+        replace_suffix(@size, suffix)
+      else
+        update_root(index, item)
+      end
+    end
+    alias :set :put
+
+    # Return a new `Vector` with a deeply nested value modified to the result
+    # of the given code block.  When traversing the nested `Vector`s and
+    # `Hash`es, non-existing keys are created with empty `Hash` values.
+    #
+    # The code block receives the existing value of the deeply nested key (or
+    # `nil` if it doesn't exist). This is useful for "transforming" the value
+    # associated with a certain key.
+    #
+    # Note that the original `Vector` and sub-`Vector`s and sub-`Hash`es are
+    # left unmodified; new data structure copies are created along the path
+    # wherever needed.
+    #
+    # @example
+    #   v = Hamster::Vector[123, 456, 789, Hamster::Hash["a" => Hamster::Vector[5, 6, 7]]]
+    #   v.update_in(3, "a", 1) { |value| value + 9 }
+    #   # => Hamster::Vector[123, 456, 789, Hamster::Hash["a" => Hamster::Vector[5, 15, 7]]]
+    #
+    # @param key_path [Object(s)] List of keys which form the path to the key to be modified
+    # @yield [value] The previously stored value
+    # @yieldreturn [Object] The new value to store
+    # @return [Vector]
+
+    # Retrieve the item at `index`. If there is none (either the provided index
+    # is too high or too low), return `nil`.
+    #
+    # @example
+    #   v = Hamster::Vector["A", "B", "C", "D"]
+    #   v.get(2)   # => "C"
+    #   v.get(-1)  # => "D"
+    #   v.get(4)   # => nil
+    #
+    # @param index [Integer] The index to retrieve
+    # @return [Object]
+    def get(index)
+      return nil if @size == 0
+      index += @size if index < 0
+      return nil if index >= @size || index < 0
+      leaf_node_for(@root, @levels * BITS_PER_LEVEL, index)[index & INDEX_MASK]
+    end
+    alias :at :get
+
+    # Retrieve the value at `index` with optional default.
+    #
+    # @overload fetch(index)
+    #   Retrieve the value at the given index, or raise an `IndexError` if not
+    #   found.
+    #
+    #   @param index [Integer] The index to look up
+    #   @raise [IndexError] if index does not exist
+    #   @example
+    #     v = Hamster::Vector["A", "B", "C", "D"]
+    #     v.fetch(2)       # => "C"
+    #     v.fetch(-1)      # => "D"
+    #     v.fetch(4)       # => IndexError: index 4 outside of vector bounds
+    #
+    # @overload fetch(index) { |index| ... }
+    #   Retrieve the value at the given index, or return the result of yielding
+    #   the block if not found.
+    #
+    #   @yield Once if the index is not found.
+    #   @yieldparam [Integer] index The index which does not exist
+    #   @yieldreturn [Object] Default value to return
+    #   @param index [Integer] The index to look up
+    #   @example
+    #     v = Hamster::Vector["A", "B", "C", "D"]
+    #     v.fetch(2) { |i| i * i }   # => "C"
+    #     v.fetch(4) { |i| i * i }   # => 16
+    #
+    # @overload fetch(index, default)
+    #   Retrieve the value at the given index, or return the provided `default`
+    #   value if not found.
+    #
+    #   @param index [Integer] The index to look up
+    #   @param default [Object] Object to return if the key is not found
+    #   @example
+    #     v = Hamster::Vector["A", "B", "C", "D"]
+    #     v.fetch(2, "Z")  # => "C"
+    #     v.fetch(4, "Z")  # => "Z"
+    #
+    # @return [Object]
+    def fetch(index, default = (missing_default = true))
+      if index >= - at size && index < @size
+        get(index)
+      elsif block_given?
+        yield(index)
+      elsif !missing_default
+        default
+      else
+        raise IndexError, "index #{index} outside of vector bounds"
+      end
+    end
+
+    # Return specific objects from the `Vector`. All overloads return `nil` if
+    # the starting index is out of range.
+    #
+    # @overload vector.slice(index)
+    #   Returns a single object at the given `index`. If `index` is negative,
+    #   count backwards from the end.
+    #
+    #   @param index [Integer] The index to retrieve. May be negative.
+    #   @return [Object]
+    #   @example
+    #     v = Hamster::Vector["A", "B", "C", "D", "E", "F"]
+    #     v[2]  # => "C"
+    #     v[-1] # => "F"
+    #     v[6]  # => nil
+    #
+    # @overload vector.slice(index, length)
+    #   Return a subvector starting at `index` and continuing for `length`
+    #   elements or until the end of the `Vector`, whichever occurs first.
+    #
+    #   @param start [Integer] The index to start retrieving items from. May be
+    #                          negative.
+    #   @param length [Integer] The number of items to retrieve.
+    #   @return [Vector]
+    #   @example
+    #     v = Hamster::Vector["A", "B", "C", "D", "E", "F"]
+    #     v[2, 3]  # => Hamster::Vector["C", "D", "E"]
+    #     v[-2, 3] # => Hamster::Vector["E", "F"]
+    #     v[20, 1] # => nil
+    #
+    # @overload vector.slice(index..end)
+    #   Return a subvector starting at `index` and continuing to index
+    #   `end` or the end of the `Vector`, whichever occurs first.
+    #
+    #   @param range [Range] The range of indices to retrieve.
+    #   @return [Vector]
+    #   @example
+    #     v = Hamster::Vector["A", "B", "C", "D", "E", "F"]
+    #     v[2..3]    # => Hamster::Vector["C", "D"]
+    #     v[-2..100] # => Hamster::Vector["E", "F"]
+    #     v[20..21]  # => nil
+    def slice(arg, length = (missing_length = true))
+      if missing_length
+        if arg.is_a?(Range)
+          from, to = arg.begin, arg.end
+          from += @size if from < 0
+          to   += @size if to < 0
+          to   += 1     if !arg.exclude_end?
+          length = to - from
+          length = 0 if length < 0
+          subsequence(from, length)
+        else
+          get(arg)
+        end
+      else
+        arg += @size if arg < 0
+        subsequence(arg, length)
+      end
+    end
+    alias :[] :slice
+
+    # Return a new `Vector` with the given values inserted before the element
+    # at `index`. If `index` is greater than the current length, `nil` values
+    # are added to pad the `Vector` to the required size.
+    #
+    # @example
+    #   Hamster::Vector["A", "B", "C", "D"].insert(2, "X", "Y", "Z")
+    #   # => Hamster::Vector["A", "B", "X", "Y", "Z", "C", "D"]
+    #   Hamster::Vector[].insert(2, "X", "Y", "Z")
+    #   # => Hamster::Vector[nil, nil, "X", "Y", "Z"]
+    #
+    # @param index [Integer] The index where the new items should go
+    # @param items [Array] The items to add
+    # @return [Vector]
+    # @raise [IndexError] if index exceeds negative range.
+    def insert(index, *items)
+      raise IndexError if index < - at size
+      index += @size if index < 0
+
+      if index < @size
+        suffix = flatten_suffix(@root, @levels * BITS_PER_LEVEL, index, [])
+        suffix.unshift(*items)
+      elsif index == @size
+        suffix = items
+      else
+        suffix = Array.new(index - @size, nil).concat(items)
+        index = @size
+      end
+
+      replace_suffix(index, suffix)
+    end
+
+    # Return a new `Vector` with the element at `index` removed. If the given `index`
+    # does not exist, return `self`.
+    #
+    # @example
+    #   Hamster::Vector["A", "B", "C", "D"].delete_at(2)
+    #   # => Hamster::Vector["A", "B", "D"]
+    #
+    # @param index [Integer] The index to remove
+    # @return [Vector]
+    def delete_at(index)
+      return self if index >= @size || index < - at size
+      index += @size if index < 0
+
+      suffix = flatten_suffix(@root, @levels * BITS_PER_LEVEL, index, [])
+      replace_suffix(index, suffix.tap { |a| a.shift })
+    end
+
+    # Return a new `Vector` with the last element removed. Return `self` if
+    # empty.
+    #
+    # @example
+    #   Hamster::Vector["A", "B", "C"].pop  # => Hamster::Vector["A", "B"]
+    #
+    # @return [Vector]
+    def pop
+      return self if @size == 0
+      replace_suffix(@size-1, [])
+    end
+
+    # Return a new `Vector` with `object` inserted before the first element,
+    # moving the other elements upwards.
+    #
+    # @example
+    #   Hamster::Vector["A", "B"].unshift("Z")
+    #   # => Hamster::Vector["Z", "A", "B"]
+    #
+    # @param object [Object] The value to prepend
+    # @return [Vector]
+    def unshift(object)
+      insert(0, object)
+    end
+
+    # Return a new `Vector` with the first element removed. If empty, return
+    # `self`.
+    #
+    # @example
+    #   Hamster::Vector["A", "B", "C"].shift  # => Hamster::Vector["B", "C"]
+    #
+    # @return [Vector]
+    def shift
+      delete_at(0)
+    end
+
+    # Call the given block once for each item in the vector, passing each
+    # item from first to last successively to the block. If no block is given,
+    # an `Enumerator` is returned instead.
+    #
+    # @example
+    #   Hamster::Vector["A", "B", "C"].each { |e| puts "Element: #{e}" }
+    #
+    #   Element: A
+    #   Element: B
+    #   Element: C
+    #   # => Hamster::Vector["A", "B", "C"]
+    #
+    # @return [self, Enumerator]
+    def each(&block)
+      return to_enum unless block_given?
+      traverse_depth_first(@root, @levels, &block)
+      self
+    end
+
+    # Call the given block once for each item in the vector, from last to
+    # first.
+    #
+    # @example
+    #   Hamster::Vector["A", "B", "C"].reverse_each { |e| puts "Element: #{e}" }
+    #
+    #   Element: C
+    #   Element: B
+    #   Element: A
+    #
+    # @return [self]
+    def reverse_each(&block)
+      return enum_for(:reverse_each) unless block_given?
+      reverse_traverse_depth_first(@root, @levels, &block)
+      self
+    end
+
+    # Return a new `Vector` containing all elements for which the given block returns
+    # true.
+    #
+    # @example
+    #   Hamster::Vector["Bird", "Cow", "Elephant"].select { |e| e.size >= 4 }
+    #   # => Hamster::Vector["Bird", "Elephant"]
+    #
+    # @return [Vector]
+    # @yield [element] Once for each element.
+    def select
+      return enum_for(:select) unless block_given?
+      reduce(self.class.empty) { |vector, item| yield(item) ? vector.add(item) : vector }
+    end
+    alias :find_all :select
+    alias :keep_if  :select
+
+    # Return a new `Vector` with all items which are equal to `obj` removed.
+    # `#==` is used for checking equality.
+    #
+    # @example
+    #   Hamster::Vector["C", "B", "A", "B"].delete("B")  # => Hamster::Vector["C", "A"]
+    #
+    # @param obj [Object] The object to remove (every occurrence)
+    # @return [Vector]
+    def delete(obj)
+      select { |item| item != obj }
+    end
+
+    # Invoke the given block once for each item in the vector, and return a new
+    # `Vector` containing the values returned by the block. If no block is
+    # provided, return an enumerator.
+    #
+    # @example
+    #   Hamster::Vector[3, 2, 1].map { |e| e * e }  # => Hamster::Vector[9, 4, 1]
+    #
+    # @return [Vector, Enumerator]
+    def map
+      return enum_for(:map) if not block_given?
+      return self if empty?
+      self.class.new(super)
+    end
+    alias :collect :map
+
+    # Return a new `Vector` with the concatenated results of running the block once
+    # for every element in this `Vector`.
+    #
+    # @example
+    #   Hamster::Vector[1, 2, 3].flat_map { |x| [x, -x] }
+    #   # => Hamster::Vector[1, -1, 2, -2, 3, -3]
+    #
+    # @return [Vector]
+    def flat_map
+      return enum_for(:flat_map) if not block_given?
+      return self if empty?
+      self.class.new(super)
+    end
+
+    # Return a new `Vector` with the same elements as this one, but randomly permuted.
+    #
+    # @example
+    #   Hamster::Vector[1, 2, 3, 4].shuffle  # => Hamster::Vector[4, 1, 3, 2]
+    #
+    # @return [Vector]
+    def shuffle
+      self.class.new(((array = to_a).frozen? ? array.shuffle : array.shuffle!).freeze)
+    end
+
+    # Return a new `Vector` with no duplicate elements, as determined by `#hash` and
+    # `#eql?`. For each group of equivalent elements, only the first will be retained.
+    #
+    # @example
+    #   Hamster::Vector["A", "B", "C", "B"].uniq      # => Hamster::Vector["A", "B", "C"]
+    #   Hamster::Vector["a", "A", "b"].uniq(&:upcase) # => Hamster::Vector["a", "b"]
+    #
+    # @return [Vector]
+    def uniq(&block)
+      array = self.to_a
+      if block_given?
+        if array.frozen?
+          self.class.new(array.uniq(&block).freeze)
+        elsif array.uniq!(&block) # returns nil if no changes were made
+          self.class.new(array.freeze)
+        else
+          self
+        end
+      elsif array.frozen?
+        self.class.new(array.uniq.freeze)
+      elsif array.uniq! # returns nil if no changes were made
+        self.class.new(array.freeze)
+      else
+        self
+      end
+    end
+
+    # Return a new `Vector` with the same elements as this one, but in reverse order.
+    #
+    # @example
+    #   Hamster::Vector["A", "B", "C"].reverse  # => Hamster::Vector["C", "B", "A"]
+    #
+    # @return [Vector]
+    def reverse
+      self.class.new(((array = to_a).frozen? ? array.reverse : array.reverse!).freeze)
+    end
+
+    # Return a new `Vector` with the same elements, but rotated so that the one at
+    # index `count` is the first element of the new vector. If `count` is positive,
+    # the elements will be shifted left, and those shifted past the lowest position
+    # will be moved to the end. If `count` is negative, the elements will be shifted
+    # right, and those shifted past the last position will be moved to the beginning.
+    #
+    # @example
+    #   v = Hamster::Vector["A", "B", "C", "D", "E", "F"]
+    #   v.rotate(2)   # => Hamster::Vector["C", "D", "E", "F", "A", "B"]
+    #   v.rotate(-1)  # => Hamster::Vector["F", "A", "B", "C", "D", "E"]
+    #
+    # @param count [Integer] The number of positions to shift items by
+    # @return [Vector]
+    def rotate(count = 1)
+      return self if (count % @size) == 0
+      self.class.new(((array = to_a).frozen? ? array.rotate(count) : array.rotate!(count)).freeze)
+    end
+
+    # Return a new `Vector` with all nested vectors and arrays recursively "flattened
+    # out". That is, their elements inserted into the new `Vector` in the place where
+    # the nested array/vector originally was. If an optional `level` argument is
+    # provided, the flattening will only be done recursively that number of times.
+    # A `level` of 0 means not to flatten at all, 1 means to only flatten nested
+    # arrays/vectors which are directly contained within this `Vector`.
+    #
+    # @example
+    #   v = Hamster::Vector["A", Hamster::Vector["B", "C", Hamster::Vector["D"]]]
+    #   v.flatten(1)
+    #   # => Hamster::Vector["A", "B", "C", Hamster::Vector["D"]]
+    #   v.flatten
+    #   # => Hamster::Vector["A", "B", "C", "D"]
+    #
+    # @param level [Integer] The depth to which flattening should be applied
+    # @return [Vector]
+    def flatten(level = -1)
+      return self if level == 0
+      array = self.to_a
+      if array.frozen?
+        self.class.new(array.flatten(level).freeze)
+      elsif array.flatten!(level) # returns nil if no changes were made
+        self.class.new(array.freeze)
+      else
+        self
+      end
+    end
+
+    # Return a new `Vector` built by concatenating this one with `other`. `other`
+    # can be any object which is convertible to an `Array` using `#to_a`.
+    #
+    # @example
+    #   Hamster::Vector["A", "B", "C"] + ["D", "E"]
+    #   # => Hamster::Vector["A", "B", "C", "D", "E"]
+    #
+    # @param other [Enumerable] The collection to concatenate onto this vector
+    # @return [Vector]
+    def +(other)
+      other = other.to_a
+      other = other.dup if other.frozen?
+      replace_suffix(@size, other)
+    end
+    alias :concat :+
+
+    # Combine two vectors by "zipping" them together. `others` should be arrays
+    # and/or vectors. The corresponding elements from this `Vector` and each of
+    # `others` (that is, the elements with the same indices) will be gathered
+    # into arrays.
+    #
+    # If `others` contains fewer elements than this vector, `nil` will be used
+    # for padding.
+    #
+    # @overload zip(*others)
+    #   Return a new vector containing the new arrays.
+    #
+    #   @return [Vector]
+    #
+    # @overload zip(*others)
+    #   @yield [pair] once for each array
+    #   @return [nil]
+    #
+    # @example
+    #   v1 = Hamster::Vector["A", "B", "C"]
+    #   v2 = Hamster::Vector[1, 2]
+    #   v1.zip(v2)
+    #   # => Hamster::Vector[["A", 1], ["B", 2], ["C", nil]]
+    #
+    # @param others [Array] The arrays/vectors to zip together with this one
+    # @return [Vector]
+    def zip(*others)
+      if block_given?
+        super
+      else
+        self.class.new(super)
+      end
+    end
+
+    # Return a new `Vector` with the same items, but sorted.
+    #
+    # @overload sort
+    #   Compare elements with their natural sort key (`#<=>`).
+    #
+    #   @example
+    #     Hamster::Vector["Elephant", "Dog", "Lion"].sort
+    #     # => Hamster::Vector["Dog", "Elephant", "Lion"]
+    #
+    # @overload sort
+    #   Uses the block as a comparator to determine sorted order.
+    #
+    #   @yield [a, b] Any number of times with different pairs of elements.
+    #   @yieldreturn [Integer] Negative if the first element should be sorted
+    #                          lower, positive if the latter element, or 0 if
+    #                          equal.
+    #   @example
+    #     Hamster::Vector["Elephant", "Dog", "Lion"].sort { |a,b| a.size <=> b.size }
+    #     # => Hamster::Vector["Dog", "Lion", "Elephant"]
+    #
+    # @return [Vector]
+    def sort
+      self.class.new(super)
+    end
+
+    # Return a new `Vector` with the same items, but sorted. The sort order is
+    # determined by mapping the items through the given block to obtain sort
+    # keys, and then sorting the keys according to their natural sort order
+    # (`#<=>`).
+    #
+    # @yield [element] Once for each element.
+    # @yieldreturn a sort key object for the yielded element.
+    # @example
+    #   Hamster::Vector["Elephant", "Dog", "Lion"].sort_by { |e| e.size }
+    #   # => Hamster::Vector["Dog", "Lion", "Elephant"]
+    #
+    # @return [Vector]
+    def sort_by
+      self.class.new(super)
+    end
+
+    # Drop the first `n` elements and return the rest in a new `Vector`.
+    #
+    # @example
+    #   Hamster::Vector["A", "B", "C", "D", "E", "F"].drop(2)
+    #   # => Hamster::Vector["C", "D", "E", "F"]
+    #
+    # @param n [Integer] The number of elements to remove
+    # @return [Vector]
+    # @raise ArgumentError if `n` is negative.
+    def drop(n)
+      return self if n == 0
+      return self.class.empty if n >= @size
+      raise ArgumentError, "attempt to drop negative size" if n < 0
+      self.class.new(flatten_suffix(@root, @levels * BITS_PER_LEVEL, n, []))
+    end
+
+    # Return only the first `n` elements in a new `Vector`.
+    #
+    # @example
+    #   Hamster::Vector["A", "B", "C", "D", "E", "F"].take(4)
+    #   # => Hamster::Vector["A", "B", "C", "D"]
+    #
+    # @param n [Integer] The number of elements to retain
+    # @return [Vector]
+    def take(n)
+      return self if n >= @size
+      self.class.new(super)
+    end
+
+    # Drop elements up to, but not including, the first element for which the
+    # block returns `nil` or `false`. Gather the remaining elements into a new
+    # `Vector`. If no block is given, an `Enumerator` is returned instead.
+    #
+    # @example
+    #   Hamster::Vector[1, 3, 5, 7, 6, 4, 2].drop_while { |e| e < 5 }
+    #   # => Hamster::Vector[5, 7, 6, 4, 2]
+    #
+    # @return [Vector, Enumerator]
+    def drop_while
+      return enum_for(:drop_while) if not block_given?
+      self.class.new(super)
+    end
+
+    # Gather elements up to, but not including, the first element for which the
+    # block returns `nil` or `false`, and return them in a new `Vector`. If no block
+    # is given, an `Enumerator` is returned instead.
+    #
+    # @example
+    #   Hamster::Vector[1, 3, 5, 7, 6, 4, 2].take_while { |e| e < 5 }
+    #   # => Hamster::Vector[1, 3]
+    #
+    # @return [Vector, Enumerator]
+    def take_while
+      return enum_for(:take_while) if not block_given?
+      self.class.new(super)
+    end
+
+    # Repetition. Return a new `Vector` built by concatenating `times` copies
+    # of this one together.
+    #
+    # @example
+    #   Hamster::Vector["A", "B"] * 3
+    #   # => Hamster::Vector["A", "B", "A", "B", "A", "B"]
+    #
+    # @param times [Integer] The number of times to repeat the elements in this vector
+    # @return [Vector]
+    def *(times)
+      return self.class.empty if times == 0
+      return self if times == 1
+      result = (to_a * times)
+      result.is_a?(Array) ? self.class.new(result) : result
+    end
+
+    # Replace a range of indexes with the given object.
+    #
+    # @overload fill(object)
+    #   Return a new `Vector` of the same size, with every index set to
+    #   `object`.
+    #
+    #   @param [Object] object Fill value.
+    #   @example
+    #     Hamster::Vector["A", "B", "C", "D", "E", "F"].fill("Z")
+    #     # => Hamster::Vector["Z", "Z", "Z", "Z", "Z", "Z"]
+    #
+    # @overload fill(object, index)
+    #   Return a new `Vector` with all indexes from `index` to the end of the
+    #   vector set to `object`.
+    #
+    #   @param [Object] object Fill value.
+    #   @param [Integer] index Starting index. May be negative.
+    #   @example
+    #     Hamster::Vector["A", "B", "C", "D", "E", "F"].fill("Z", 3)
+    #     # => Hamster::Vector["A", "B", "C", "Z", "Z", "Z"]
+    #
+    # @overload fill(object, index, length)
+    #   Return a new `Vector` with `length` indexes, beginning from `index`,
+    #   set to `object`. Expands the `Vector` if `length` would extend beyond
+    #   the current length.
+    #
+    #   @param [Object] object Fill value.
+    #   @param [Integer] index Starting index. May be negative.
+    #   @param [Integer] length
+    #   @example
+    #     Hamster::Vector["A", "B", "C", "D", "E", "F"].fill("Z", 3, 2)
+    #     # => Hamster::Vector["A", "B", "C", "Z", "Z", "F"]
+    #     Hamster::Vector["A", "B"].fill("Z", 1, 5)
+    #     # => Hamster::Vector["A", "Z", "Z", "Z", "Z", "Z"]
+    #
+    # @return [Vector]
+    # @raise [IndexError] if index is out of negative range.
+    def fill(object, index = 0, length = nil)
+      raise IndexError if index < - at size
+      index += @size if index < 0
+      length ||= @size - index # to the end of the array, if no length given
+
+      if index < @size
+        suffix = flatten_suffix(@root, @levels * BITS_PER_LEVEL, index, [])
+        suffix.fill(object, 0, length)
+      elsif index == @size
+        suffix = Array.new(length, object)
+      else
+        suffix = Array.new(index - @size, nil).concat(Array.new(length, object))
+        index = @size
+      end
+
+      replace_suffix(index, suffix)
+    end
+
+    # When invoked with a block, yields all combinations of length `n` of items
+    # from the `Vector`, and then returns `self`. There is no guarantee about
+    # which order the combinations will be yielded.
+    #
+    # If no block is given, an `Enumerator` is returned instead.
+    #
+    # @example
+    #   v = Hamster::Vector[5, 6, 7, 8]
+    #   v.combination(3) { |c| puts "Combination: #{c}" }
+    #
+    #   Combination: [5, 6, 7]
+    #   Combination: [5, 6, 8]
+    #   Combination: [5, 7, 8]
+    #   Combination: [6, 7, 8]
+    #   #=> Hamster::Vector[5, 6, 7, 8]
+    #
+    # @return [self, Enumerator]
+    def combination(n)
+      return enum_for(:combination, n) if not block_given?
+      return self if n < 0 || @size < n
+      if n == 0
+        yield []
+      elsif n == 1
+        each { |item| yield [item] }
+      elsif n == @size
+        yield self.to_a
+      else
+        combos = lambda do |result,index,remaining|
+          while @size - index > remaining
+            if remaining == 1
+              yield result.dup << get(index)
+            else
+              combos[result.dup << get(index), index+1, remaining-1]
+            end
+            index += 1
+          end
+          index.upto(@size-1) { |i| result << get(i) }
+          yield result
+        end
+        combos[[], 0, n]
+      end
+      self
+    end
+
+    # When invoked with a block, yields all repeated combinations of length `n` of
+    # items from the `Vector`, and then returns `self`. A "repeated combination" is
+    # one in which any item from the `Vector` can appear consecutively any number of
+    # times.
+    #
+    # There is no guarantee about which order the combinations will be yielded in.
+    #
+    # If no block is given, an `Enumerator` is returned instead.
+    #
+    # @example
+    #   v = Hamster::Vector[5, 6, 7, 8]
+    #   v.repeated_combination(2) { |c| puts "Combination: #{c}" }
+    #
+    #   Combination: [5, 5]
+    #   Combination: [5, 6]
+    #   Combination: [5, 7]
+    #   Combination: [5, 8]
+    #   Combination: [6, 6]
+    #   Combination: [6, 7]
+    #   Combination: [6, 8]
+    #   Combination: [7, 7]
+    #   Combination: [7, 8]
+    #   Combination: [8, 8]
+    #   # => Hamster::Vector[5, 6, 7, 8]
+    #
+    # @return [self, Enumerator]
+    def repeated_combination(n)
+      return enum_for(:repeated_combination, n) if not block_given?
+      if n < 0
+        # yield nothing
+      elsif n == 0
+        yield []
+      elsif n == 1
+        each { |item| yield [item] }
+      elsif @size == 0
+        # yield nothing
+      else
+        combos = lambda do |result,index,remaining|
+          while index < @size-1
+            if remaining == 1
+              yield result.dup << get(index)
+            else
+              combos[result.dup << get(index), index, remaining-1]
+            end
+            index += 1
+          end
+          item = get(index)
+          remaining.times { result << item }
+          yield result
+        end
+        combos[[], 0, n]
+      end
+      self
+    end
+
+    # Yields all permutations of length `n` of items from the `Vector`, and then
+    # returns `self`. If no length `n` is specified, permutations of all elements
+    # will be yielded.
+    #
+    # There is no guarantee about which order the permutations will be yielded in.
+    #
+    # If no block is given, an `Enumerator` is returned instead.
+    #
+    # @example
+    #   v = Hamster::Vector[5, 6, 7]
+    #   v.permutation(2) { |p| puts "Permutation: #{p}" }
+    #
+    #   Permutation: [5, 6]
+    #   Permutation: [5, 7]
+    #   Permutation: [6, 5]
+    #   Permutation: [6, 7]
+    #   Permutation: [7, 5]
+    #   Permutation: [7, 6]
+    #   # => Hamster::Vector[5, 6, 7]
+    #
+    # @return [self, Enumerator]
+    def permutation(n = @size)
+      return enum_for(:permutation, n) if not block_given?
+      if n < 0 || @size < n
+        # yield nothing
+      elsif n == 0
+        yield []
+      elsif n == 1
+        each { |item| yield [item] }
+      else
+        used, result = [], []
+        perms = lambda do |index|
+          0.upto(@size-1) do |i|
+            if !used[i]
+              result[index] = get(i)
+              if index < n-1
+                used[i] = true
+                perms[index+1]
+                used[i] = false
+              else
+                yield result.dup
+              end
+            end
+          end
+        end
+        perms[0]
+      end
+      self
+    end
+
+    # When invoked with a block, yields all repeated permutations of length `n` of
+    # items from the `Vector`, and then returns `self`. A "repeated permutation" is
+    # one where any item from the `Vector` can appear any number of times, and in
+    # any position (not just consecutively)
+    #
+    # If no length `n` is specified, permutations of all elements will be yielded.
+    # There is no guarantee about which order the permutations will be yielded in.
+    #
+    # If no block is given, an `Enumerator` is returned instead.
+    #
+    # @example
+    #   v = Hamster::Vector[5, 6, 7]
+    #   v.repeated_permutation(2) { |p| puts "Permutation: #{p}" }
+    #
+    #   Permutation: [5, 5]
+    #   Permutation: [5, 6]
+    #   Permutation: [5, 7]
+    #   Permutation: [6, 5]
+    #   Permutation: [6, 6]
+    #   Permutation: [6, 7]
+    #   Permutation: [7, 5]
+    #   Permutation: [7, 6]
+    #   Permutation: [7, 7]
+    #   # => Hamster::Vector[5, 6, 7]
+    #
+    # @return [self, Enumerator]
+    def repeated_permutation(n = @size)
+      return enum_for(:repeated_permutation, n) if not block_given?
+      if n < 0
+        # yield nothing
+      elsif n == 0
+        yield []
+      elsif n == 1
+        each { |item| yield [item] }
+      else
+        result = []
+        perms = lambda do |index|
+          0.upto(@size-1) do |i|
+            result[index] = get(i)
+            if index < n-1
+              perms[index+1]
+            else
+              yield result.dup
+            end
+          end
+        end
+        perms[0]
+      end
+      self
+    end
+
+    # Cartesian product or multiplication.
+    #
+    # @overload product(*vectors)
+    #   Return a `Vector` of all combinations of elements from this `Vector` and each
+    #   of the given vectors or arrays. The length of the returned `Vector` is the product
+    #   of `self.size` and the size of each argument vector or array.
+    #   @example
+    #     v1 = Hamster::Vector[1, 2, 3]
+    #     v2 = Hamster::Vector["A", "B"]
+    #     v1.product(v2)
+    #     # => [[1, "A"], [1, "B"], [2, "A"], [2, "B"], [3, "A"], [3, "B"]]
+    # @overload product
+    #   Return the result of multiplying all the items in this `Vector` together.
+    #
+    #   @example
+    #     Hamster::Vector[1, 2, 3, 4, 5].product  # => 120
+    #
+    # @return [Vector]
+    def product(*vectors)
+      # if no vectors passed, return "product" as in result of multiplying all items
+      return super if vectors.empty?
+
+      vectors.unshift(self)
+
+      if vectors.any?(&:empty?)
+        return block_given? ? self : []
+      end
+
+      counters = Array.new(vectors.size, 0)
+
+      bump_counters = lambda do
+        i = vectors.size-1
+        counters[i] += 1
+        while counters[i] == vectors[i].size
+          counters[i] = 0
+          i -= 1
+          return true if i == -1 # we are done
+          counters[i] += 1
+        end
+        false # not done yet
+      end
+      build_array = lambda do
+        array = []
+        counters.each_with_index { |index,i| array << vectors[i][index] }
+        array
+      end
+
+      if block_given?
+        while true
+          yield build_array[]
+          return self if bump_counters[]
+        end
+      else
+        result = []
+        while true
+          result << build_array[]
+          return result if bump_counters[]
+        end
+      end
+    end
+
+    # Assume all elements are vectors or arrays and transpose the rows and columns.
+    # In other words, take the first element of each nested vector/array and gather
+    # them together into a new `Vector`. Do likewise for the second, third, and so on
+    # down to the end of each nested vector/array. Gather all the resulting `Vectors`
+    # into a new `Vector` and return it.
+    #
+    # This operation is closely related to {#zip}. The result is almost the same as
+    # calling {#zip} on the first nested vector/array with the others supplied as
+    # arguments.
+    #
+    # @example
+    #   Hamster::Vector[["A", 10], ["B", 20], ["C", 30]].transpose
+    #   # => Hamster::Vector[Hamster::Vector["A", "B", "C"], Hamster::Vector[10, 20, 30]]
+    #
+    # @return [Vector]
+    # @raise [IndexError] if elements are not of the same size.
+    # @raise [TypeError] if an element can not be implicitly converted to an array (using `#to_ary`)
+    def transpose
+      return self.class.empty if empty?
+      result = Array.new(first.size) { [] }
+
+      0.upto(@size-1) do |i|
+        source = get(i)
+        if source.size != result.size
+          raise IndexError, "element size differs (#{source.size} should be #{result.size})"
+        end
+
+        0.upto(result.size-1) do |j|
+          result[j].push(source[j])
+        end
+      end
+
+      result.map! { |a| self.class.new(a) }
+      self.class.new(result)
+    end
+
+    # Finds a value from this `Vector` which meets the condition defined by the
+    # provided block, using a binary search. The vector must already be sorted
+    # with respect to the block.  See Ruby's `Array#bsearch` for details,
+    # behaviour is equivalent.
+    #
+    # @example
+    #   v = Hamster::Vector[1, 3, 5, 7, 9, 11, 13]
+    #   # Block returns true/false for exact element match:
+    #   v.bsearch { |e| e > 4 }      # => 5
+    #   # Block returns number to match an element in 4 <= e <= 7:
+    #   v.bsearch { |e| 1 - e / 4 }  # => 7
+    #
+    # @yield Once for at most `log n` elements, where `n` is the size of the
+    #        vector. The exact elements and ordering are undefined.
+    # @yieldreturn [Boolean] `true` if this element matches the criteria, `false` otherwise.
+    # @yieldreturn [Integer] See `Array#bsearch` for details.
+    # @yieldparam [Object] element element to be evaluated
+    # @return [Object] The matched element, or `nil` if none found.
+    # @raise TypeError if the block returns a non-numeric, non-boolean, non-nil
+    #                  value.
+    def bsearch
+      return enum_for(:bsearch) if not block_given?
+      low, high, result = 0, @size, nil
+      while low < high
+        mid = (low + ((high - low) >> 1))
+        val = get(mid)
+        v   = yield val
+        if v.is_a? Numeric
+          if v == 0
+            return val
+          elsif v > 0
+            high = mid
+          else
+            low = mid + 1
+          end
+        elsif v == true
+          result = val
+          high = mid
+        elsif !v
+          low = mid + 1
+        else
+          raise TypeError, "wrong argument type #{v.class} (must be numeric, true, false, or nil)"
+        end
+      end
+      result
+    end
+
+    # Return an empty `Vector` instance, of the same class as this one. Useful if you
+    # have multiple subclasses of `Vector` and want to treat them polymorphically.
+    #
+    # @return [Vector]
+    def clear
+      self.class.empty
+    end
+
+    # Return a randomly chosen item from this `Vector`. If the vector is empty, return `nil`.
+    #
+    # @example
+    #   Hamster::Vector[1, 2, 3, 4, 5].sample  # => 2
+    #
+    # @return [Object]
+    def sample
+      get(rand(@size))
+    end
+
+    # Return a new `Vector` with only the elements at the given `indices`, in the
+    # order specified by `indices`. If any of the `indices` do not exist, `nil`s will
+    # appear in their places.
+    #
+    # @example
+    #   v = Hamster::Vector["A", "B", "C", "D", "E", "F"]
+    #   v.values_at(2, 4, 5)   # => Hamster::Vector["C", "E", "F"]
+    #
+    # @param indices [Array] The indices to retrieve and gather into a new `Vector`
+    # @return [Vector]
+    def values_at(*indices)
+      self.class.new(indices.map { |i| get(i) }.freeze)
+    end
+
+    # Find the index of an element, starting from the end of the vector.
+    # Returns `nil` if no element is found.
+    #
+    # @overload rindex(obj)
+    #   Return the index of the last element which is `#==` to `obj`.
+    #
+    #   @example
+    #     v = Hamster::Vector[7, 8, 9, 7, 8, 9]
+    #     v.rindex(8) # => 4
+    #
+    # @overload rindex
+    #   Return the index of the last element for which the block returns true.
+    #
+    #   @yield [element] Once for each element, last to first, until the block
+    #                    returns true.
+    #   @example
+    #     v = Hamster::Vector[7, 8, 9, 7, 8, 9]
+    #     v.rindex { |e| e.even? }  # => 4
+    #
+    # @return [Integer]
+    def rindex(obj = (missing_arg = true))
+      i = @size - 1
+      if missing_arg
+        if block_given?
+          reverse_each { |item| return i if yield item; i -= 1 }
+          nil
+        else
+          enum_for(:rindex)
+        end
+      else
+        reverse_each { |item| return i if item == obj; i -= 1 }
+        nil
+      end
+    end
+
+    # Assumes all elements are nested, indexable collections, and searches through them,
+    # comparing `obj` with the first element of each nested collection. Return the
+    # first nested collection which matches, or `nil` if none is found.
+    # Behaviour is undefined when elements do not meet assumptions (i.e. are
+    # not indexable collections).
+    #
+    # @example
+    #   v = Hamster::Vector[["A", 10], ["B", 20], ["C", 30]]
+    #   v.assoc("B")  # => ["B", 20]
+    #
+    # @param obj [Object] The object to search for
+    # @return [Object]
+    def assoc(obj)
+      each do |array|
+        next if !array.respond_to?(:[])
+        return array if obj == array[0]
+      end
+      nil
+    end
+
+    # Assumes all elements are nested, indexable collections, and searches through them,
+    # comparing `obj` with the second element of each nested collection. Return
+    # the first nested collection which matches, or `nil` if none is found.
+    # Behaviour is undefined when elements do not meet assumptions (i.e. are
+    # not indexable collections).
+    #
+    # @example
+    #   v = Hamster::Vector[["A", 10], ["B", 20], ["C", 30]]
+    #   v.rassoc(20)  # => ["B", 20]
+    #
+    # @param obj [Object] The object to search for
+    # @return [Object]
+    def rassoc(obj)
+      each do |array|
+        next if !array.respond_to?(:[])
+        return array if obj == array[1]
+      end
+      nil
+    end
+
+    # Return an `Array` with the same elements, in the same order. The returned
+    # `Array` may or may not be frozen.
+    #
+    # @return [Array]
+    def to_a
+      if @levels == 0
+        # When initializing a Vector with 32 or less items, we always make
+        # sure @root is frozen, so we can return it directly here
+        @root
+      else
+        flatten_node(@root, @levels * BITS_PER_LEVEL, [])
+      end
+    end
+    alias :to_ary :to_a
+
+    # Return true if `other` has the same type and contents as this `Vector`.
+    #
+    # @param other [Object] The collection to compare with
+    # @return [Boolean]
+    def eql?(other)
+      return true if other.equal?(self)
+      return false unless instance_of?(other.class) && @size == other.size
+      @root.eql?(other.instance_variable_get(:@root))
+    end
+
+    # See `Object#hash`.
+    # @return [Integer]
+    def hash
+      reduce(0) { |hash, item| (hash << 5) - hash + item.hash }
+    end
+
+    # @return [::Array]
+    # @private
+    def marshal_dump
+      to_a
+    end
+
+    # @private
+    def marshal_load(array)
+      initialize(array.freeze)
+    end
+
+    private
+
+    def traverse_depth_first(node, level, &block)
+      return node.each(&block) if level == 0
+      node.each { |child| traverse_depth_first(child, level - 1, &block) }
+    end
+
+    def reverse_traverse_depth_first(node, level, &block)
+      return node.reverse_each(&block) if level == 0
+      node.reverse_each { |child| reverse_traverse_depth_first(child, level - 1, &block) }
+    end
+
+    def leaf_node_for(node, bitshift, index)
+      while bitshift > 0
+        node = node[(index >> bitshift) & INDEX_MASK]
+        bitshift -= BITS_PER_LEVEL
+      end
+      node
+    end
+
+    def update_root(index, item)
+      root, levels = @root, @levels
+      while index >= (1 << (BITS_PER_LEVEL * (levels + 1)))
+        root = [root].freeze
+        levels += 1
+      end
+      new_root = update_leaf_node(root, levels * BITS_PER_LEVEL, index, item)
+      if new_root.equal?(root)
+        self
+      else
+        self.class.alloc(new_root, @size > index ? @size : index + 1, levels)
+      end
+    end
+
+    def update_leaf_node(node, bitshift, index, item)
+      slot_index = (index >> bitshift) & INDEX_MASK
+      if bitshift > 0
+        old_child = node[slot_index] || []
+        item = update_leaf_node(old_child, bitshift - BITS_PER_LEVEL, index, item)
+      end
+      existing_item = node[slot_index]
+      if existing_item.equal?(item)
+        node
+      else
+        node.dup.tap { |n| n[slot_index] = item }.freeze
+      end
+    end
+
+    def flatten_range(node, bitshift, from, to)
+      from_slot = (from >> bitshift) & INDEX_MASK
+      to_slot   = (to   >> bitshift) & INDEX_MASK
+
+      if bitshift == 0 # are we at the bottom?
+        node.slice(from_slot, to_slot-from_slot+1)
+      elsif from_slot == to_slot
+        flatten_range(node[from_slot], bitshift - BITS_PER_LEVEL, from, to)
+      else
+        # the following bitmask can be used to pick out the part of the from/to indices
+        #   which will be used to direct path BELOW this node
+        mask   = ((1 << bitshift) - 1)
+        result = []
+
+        if from & mask == 0
+          flatten_node(node[from_slot], bitshift - BITS_PER_LEVEL, result)
+        else
+          result.concat(flatten_range(node[from_slot], bitshift - BITS_PER_LEVEL, from, from | mask))
+        end
+
+        (from_slot+1).upto(to_slot-1) do |slot_index|
+          flatten_node(node[slot_index], bitshift - BITS_PER_LEVEL, result)
+        end
+
+        if to & mask == mask
+          flatten_node(node[to_slot], bitshift - BITS_PER_LEVEL, result)
+        else
+          result.concat(flatten_range(node[to_slot], bitshift - BITS_PER_LEVEL, to & ~mask, to))
+        end
+
+        result
+      end
+    end
+
+    def flatten_node(node, bitshift, result)
+      if bitshift == 0
+        result.concat(node)
+      elsif bitshift == BITS_PER_LEVEL
+        node.each { |a| result.concat(a) }
+      else
+        bitshift -= BITS_PER_LEVEL
+        node.each { |a| flatten_node(a, bitshift, result) }
+      end
+      result
+    end
+
+    def subsequence(from, length)
+      return nil if from > @size || from < 0 || length < 0
+      length = @size - from if @size < from + length
+      return self.class.empty if length == 0
+      self.class.new(flatten_range(@root, @levels * BITS_PER_LEVEL, from, from + length - 1))
+    end
+
+    def flatten_suffix(node, bitshift, from, result)
+      from_slot = (from >> bitshift) & INDEX_MASK
+
+      if bitshift == 0
+        if from_slot == 0
+          result.concat(node)
+        else
+          result.concat(node.slice(from_slot, 32)) # entire suffix of node. excess length is ignored by #slice
+        end
+      else
+        mask = ((1 << bitshift) - 1)
+        if from & mask == 0
+          from_slot.upto(node.size-1) do |i|
+            flatten_node(node[i], bitshift - BITS_PER_LEVEL, result)
+          end
+        elsif child = node[from_slot]
+          flatten_suffix(child, bitshift - BITS_PER_LEVEL, from, result)
+          (from_slot+1).upto(node.size-1) do |i|
+            flatten_node(node[i], bitshift - BITS_PER_LEVEL, result)
+          end
+        end
+        result
+      end
+    end
+
+    def replace_suffix(from, suffix)
+      # new suffix can go directly after existing elements
+      raise IndexError if from > @size
+      root, levels = @root, @levels
+
+      if (from >> (BITS_PER_LEVEL * (@levels + 1))) != 0
+        # index where new suffix goes doesn't fall within current tree
+        # we will need to deepen tree
+        root = [root].freeze
+        levels += 1
+      end
+
+      new_size = from + suffix.size
+      root = replace_node_suffix(root, levels * BITS_PER_LEVEL, from, suffix)
+
+      if !suffix.empty?
+        levels.times { suffix = suffix.each_slice(32).to_a }
+        root.concat(suffix)
+        while root.size > 32
+          root = root.each_slice(32).to_a
+          levels += 1
+        end
+      else
+        while root.size == 1 && levels > 0
+          root = root[0]
+          levels -= 1
+        end
+      end
+
+      self.class.alloc(root.freeze, new_size, levels)
+    end
+
+    def replace_node_suffix(node, bitshift, from, suffix)
+      from_slot = (from >> bitshift) & INDEX_MASK
+
+      if bitshift == 0
+        if from_slot == 0
+          suffix.shift(32)
+        else
+          node.take(from_slot).concat(suffix.shift(32 - from_slot))
+        end
+      else
+        mask = ((1 << bitshift) - 1)
+        if from & mask == 0
+          if from_slot == 0
+            new_node = suffix.shift(32 * (1 << bitshift))
+            while bitshift != 0
+              new_node = new_node.each_slice(32).to_a
+              bitshift -= BITS_PER_LEVEL
+            end
+            new_node
+          else
+            result = node.take(from_slot)
+            remainder = suffix.shift((32 - from_slot) * (1 << bitshift))
+            while bitshift != 0
+              remainder = remainder.each_slice(32).to_a
+              bitshift -= BITS_PER_LEVEL
+            end
+            result.concat(remainder)
+          end
+        elsif child = node[from_slot]
+          result = node.take(from_slot)
+          result.push(replace_node_suffix(child, bitshift - BITS_PER_LEVEL, from, suffix))
+          remainder = suffix.shift((31 - from_slot) * (1 << bitshift))
+          while bitshift != 0
+            remainder = remainder.each_slice(32).to_a
+            bitshift -= BITS_PER_LEVEL
+          end
+          result.concat(remainder)
+        else
+          raise "Shouldn't happen"
+        end
+      end
+    end
+  end
+
+  # The canonical empty `Vector`. Returned by `Vector[]` when
+  # invoked with no arguments; also returned by `Vector.empty`. Prefer using this
+  # one rather than creating many empty vectors using `Vector.new`.
+  #
+  # @private
+  EmptyVector = Hamster::Vector.empty
+end
diff --git a/app/server/vendor/hamster-3.0.0/lib/hamster/version.rb b/app/server/vendor/hamster-3.0.0/lib/hamster/version.rb
new file mode 100755
index 0000000..8e910fb
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/lib/hamster/version.rb
@@ -0,0 +1,5 @@
+module Hamster
+  # Current released gem version. Note that master will often have the same
+  # value as a release gem but with different code.
+  VERSION = "3.0.0"
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/fixtures/io_spec.txt b/app/server/vendor/hamster-3.0.0/spec/fixtures/io_spec.txt
new file mode 100755
index 0000000..b1e6722
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/fixtures/io_spec.txt
@@ -0,0 +1,3 @@
+A
+B
+C
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/associable/associable_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/associable/associable_spec.rb
new file mode 100755
index 0000000..cfea0cc
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/associable/associable_spec.rb
@@ -0,0 +1,150 @@
+require "spec_helper"
+require "hamster/hash"
+require "hamster/vector"
+
+describe Hamster::Associable do
+  describe "#update_in" do
+    let(:hash) {
+      Hamster::Hash[
+        "A" => "aye",
+        "B" => Hamster::Hash["C" => "see", "D" => Hamster::Hash["E" => "eee"]],
+        "F" => Hamster::Vector["G", Hamster::Hash["H" => "eitch"], "I"]
+      ]
+    }
+    let(:vector) {
+      Hamster::Vector[
+        100,
+        101,
+        102,
+        Hamster::Vector[200, 201, Hamster::Vector[300, 301, 302]],
+        Hamster::Hash["A" => "alpha", "B" => "bravo"],
+        [400, 401, 402]
+      ]
+    }
+    context "with one level on existing key" do
+      it "Hash passes the value to the block" do
+        hash.update_in("A") { |value| value.should == "aye" }
+      end
+
+      it "Vector passes the value to the block" do
+        vector.update_in(1) { |value| value.should == 101 }
+      end
+
+      it "Hash replaces the value with the result of the block" do
+        result = hash.update_in("A") { |value| "FLIBBLE" }
+        result.get("A").should == "FLIBBLE"
+      end
+
+      it "Vector replaces the value with the result of the block" do
+        result = vector.update_in(1) { |value| "FLIBBLE" }
+        result.get(1).should == "FLIBBLE"
+      end
+
+      it "Hash should preserve the original" do
+        result = hash.update_in("A") { |value| "FLIBBLE" }
+        hash.get("A").should == "aye"
+      end
+
+      it "Vector should preserve the original" do
+        result = vector.update_in(1) { |value| "FLIBBLE" }
+        vector.get(1).should == 101
+      end
+    end
+
+    context "with multi-level on existing keys" do
+      it "Hash passes the value to the block" do
+        hash.update_in("B", "D", "E") { |value| value.should == "eee" }
+      end
+
+      it "Vector passes the value to the block" do
+        vector.update_in(3, 2, 0) { |value| value.should == 300 }
+      end
+
+      it "Hash replaces the value with the result of the block" do
+        result = hash.update_in("B", "D", "E") { |value| "FLIBBLE" }
+        result["B"]["D"]["E"].should == "FLIBBLE"
+      end
+
+      it "Vector replaces the value with the result of the block" do
+        result = vector.update_in(3, 2, 0) { |value| "FLIBBLE" }
+        result[3][2][0].should == "FLIBBLE"
+      end
+
+      it "Hash should preserve the original" do
+        result = hash.update_in("B", "D", "E") { |value| "FLIBBLE" }
+        hash["B"]["D"]["E"].should == "eee"
+      end
+
+      it "Vector should preserve the original" do
+        result = vector.update_in(3, 2, 0) { |value| "FLIBBLE" }
+        vector[3][2][0].should == 300
+      end
+
+    end
+
+    context "with multi-level creating sub-hashes when keys don't exist" do
+      it "Hash passes nil to the block" do
+        hash.update_in("B", "X", "Y") { |value| value.should be_nil }
+      end
+
+      it "Vector passes nil to the block" do
+        vector.update_in(3, 3, "X", "Y") { |value| value.should be_nil }
+      end
+
+      it "Hash creates subhashes on the way to set the value" do
+        result = hash.update_in("B", "X", "Y") { |value| "NEWVALUE" }
+        result["B"]["X"]["Y"].should == "NEWVALUE"
+        result["B"]["D"]["E"].should == "eee"
+      end
+
+      it "Vector creates subhashes on the way to set the value" do
+        result = vector.update_in(3, 3, "X", "Y") { |value| "NEWVALUE" }
+        result[3][3]["X"]["Y"].should == "NEWVALUE"
+        result[3][2][0].should == 300
+      end
+    end
+
+    context "Hash with multi-level including Vector with existing keys" do
+      it "passes the value to the block" do
+        hash.update_in("F", 1, "H") { |value| value.should == "eitch" }
+      end
+
+      it "replaces the value with the result of the block" do
+        result = hash.update_in("F", 1, "H") { |value| "FLIBBLE" }
+        result["F"][1]["H"].should == "FLIBBLE"
+      end
+
+      it "should preserve the original" do
+        result = hash.update_in("F", 1, "H") { |value| "FLIBBLE" }
+        hash["F"][1]["H"].should == "eitch"
+      end
+    end
+
+    context "Vector with multi-level including Hash with existing keys" do
+      it "passes the value to the block" do
+        vector.update_in(4, "B") { |value| value.should == "bravo" }
+      end
+
+      it "replaces the value with the result of the block" do
+        result = vector.update_in(4, "B") { |value| "FLIBBLE" }
+        result[4]["B"].should == "FLIBBLE"
+      end
+
+      it "should preserve the original" do
+        result = vector.update_in(4, "B") { |value| "FLIBBLE" }
+        vector[4]["B"].should == "bravo"
+      end
+    end
+
+    context "with empty key_path" do
+      it "Hash raises ArguemntError" do
+        expect { hash.update_in() { |v| 42 } }.to raise_error(ArgumentError)
+      end
+
+      it "Vector raises ArguemntError" do
+        expect { vector.update_in() { |v| 42 } }.to raise_error(ArgumentError)
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/core_ext/array_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/core_ext/array_spec.rb
new file mode 100755
index 0000000..c8fc7ce
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/core_ext/array_spec.rb
@@ -0,0 +1,14 @@
+require "spec_helper"
+require "hamster/core_ext/enumerable"
+
+describe Array do
+  let(:array) { %w[A B C] }
+
+  describe "#to_list" do
+    let(:to_list) { array.to_list }
+
+    it "returns an equivalent hamster list" do
+      expect(to_list).to eq(L["A", "B", "C"])
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/core_ext/enumerable_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/core_ext/enumerable_spec.rb
new file mode 100755
index 0000000..775e64d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/core_ext/enumerable_spec.rb
@@ -0,0 +1,30 @@
+require "spec_helper"
+require "hamster/core_ext/enumerable"
+
+describe Enumerable do
+  class TestEnumerable
+    include Enumerable
+
+    def initialize(*values)
+      @values = values
+    end
+
+    def each(&block)
+      @values.each(&block)
+    end
+  end
+
+  let(:enumerable) { TestEnumerable.new("A", "B", "C") }
+
+  describe "#to_list" do
+    let(:to_list) { enumerable.to_list }
+
+    it "returns an equivalent list" do
+      expect(to_list).to eq(L["A", "B", "C"])
+    end
+
+    it "works on Ranges" do
+      expect((1..3).to_list).to eq(L[1, 2, 3])
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/core_ext/io_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/core_ext/io_spec.rb
new file mode 100755
index 0000000..c2df05f
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/core_ext/io_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+require "hamster/core_ext/io"
+
+describe IO do
+  describe "#to_list" do
+    let(:list) { L["A\n", "B\n", "C\n"] }
+    let(:to_list) { io.to_list }
+
+    after(:each) do
+      io.close
+    end
+
+    context "with a File" do
+      let(:io) { File.new(fixture_path("io_spec.txt")) }
+
+      it "returns an equivalent list" do
+        expect(to_list).to eq(list)
+      end
+    end
+
+    context "with a StringIO" do
+      let(:io) { StringIO.new(fixture("io_spec.txt")) }
+
+      it "returns an equivalent list" do
+        expect(to_list).to eq(list)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/clear_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/clear_spec.rb
new file mode 100755
index 0000000..df2cefd
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/clear_spec.rb
@@ -0,0 +1,34 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  describe "#clear" do
+    [
+      [],
+      ["A"],
+      %w[A B C],
+    ].each do |values|
+      context "on #{values}" do
+        let(:deque) { D[*values] }
+
+        it "preserves the original" do
+          deque.clear
+          deque.should eql(D[*values])
+        end
+
+        it "returns an empty deque" do
+          deque.clear.should equal(D.empty)
+        end
+      end
+    end
+  end
+
+  context "from a subclass" do
+    it "returns an instance of the subclass" do
+      subclass = Class.new(Hamster::Deque)
+      instance = subclass.new([1,2])
+      instance.clear.should be_empty
+      instance.clear.class.should be(subclass)
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/construction_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/construction_spec.rb
new file mode 100755
index 0000000..aefe986
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/construction_spec.rb
@@ -0,0 +1,30 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  describe ".[]" do
+    context "with no arguments" do
+      it "always returns the same instance" do
+        D[].class.should be(Hamster::Deque)
+        D[].should equal(D[])
+      end
+
+      it "returns an empty, frozen deque" do
+        D[].should be_empty
+        D[].should be_frozen
+      end
+    end
+
+    context "with a number of items" do
+      let(:deque) { D["A", "B", "C"] }
+
+      it "always returns a different instance" do
+        deque.should_not equal(D["A", "B", "C"])
+      end
+
+      it "is the same as repeatedly using #endeque" do
+        deque.should eql(D.empty.enqueue("A").enqueue("B").enqueue("C"))
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/copying_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/copying_spec.rb
new file mode 100755
index 0000000..b34e18e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/copying_spec.rb
@@ -0,0 +1,20 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  [:dup, :clone].each do |method|
+    [
+      [],
+      ["A"],
+      %w[A B C],
+    ].each do |values|
+      context "on #{values.inspect}" do
+        let(:deque) { D[*values] }
+
+        it "returns self" do
+          deque.send(method).should equal(deque)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/dequeue_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/dequeue_spec.rb
new file mode 100755
index 0000000..03a9cc2
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/dequeue_spec.rb
@@ -0,0 +1,35 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  [:dequeue, :shift].each do |method|
+    describe "##{method}" do
+      [
+        [[], []],
+        [["A"], []],
+        [%w[A B C], %w[B C]],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          let(:deque) { D[*values] }
+
+          it "preserves the original" do
+            deque.send(method)
+            deque.should eql(D[*values])
+          end
+
+          it "returns #{expected.inspect}" do
+            deque.send(method).should eql(D[*expected])
+          end
+        end
+      end
+    end
+
+    context "on empty subclass" do
+      let(:subclass) { Class.new(Hamster::Deque) }
+      let(:empty_instance) { subclass.new }
+      it "returns emtpy object of same class" do
+        empty_instance.send(method).class.should be subclass
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/empty_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/empty_spec.rb
new file mode 100755
index 0000000..92d1073
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/empty_spec.rb
@@ -0,0 +1,40 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  describe "#empty?" do
+    [
+      [[], true],
+      [["A"], false],
+      [%w[A B C], false],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        it "returns #{expected.inspect}" do
+          D[*values].empty?.should == expected
+        end
+      end
+    end
+
+    context "after dedequeing an item from #{%w[A B C].inspect}" do
+      it "returns false" do
+        D["A", "B", "C"].dequeue.should_not be_empty
+      end
+    end
+  end
+
+  describe ".empty" do
+    it "returns the canonical empty deque" do
+      D.empty.size.should be(0)
+      D.empty.class.should be(Hamster::Deque)
+      D.empty.object_id.should be(Hamster::EmptyDeque.object_id)
+    end
+
+    context "from a subclass" do
+      it "returns an empty instance of the subclass" do
+        subclass = Class.new(Hamster::Deque)
+        subclass.empty.class.should be(subclass)
+        subclass.empty.should be_empty
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/enqueue_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/enqueue_spec.rb
new file mode 100755
index 0000000..fad5926
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/enqueue_spec.rb
@@ -0,0 +1,28 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  [:enqueue, :push].each do |method|
+    describe "##{method}" do
+      [
+        [[], "A", ["A"]],
+        [["A"], "B", %w[A B]],
+        [["A"], "A", %w[A A]],
+        [%w[A B C], "D", %w[A B C D]],
+      ].each do |values, new_value, expected|
+        describe "on #{values.inspect} with #{new_value.inspect}" do
+          let(:deque) { D[*values] }
+
+          it "preserves the original" do
+            deque.send(method, new_value)
+            deque.should eql(D[*values])
+          end
+
+          it "returns #{expected.inspect}" do
+            deque.send(method, new_value).should eql(D[*expected])
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/first_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/first_spec.rb
new file mode 100755
index 0000000..3f0ccba
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/first_spec.rb
@@ -0,0 +1,18 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  describe "#first" do
+    [
+      [[], nil],
+      [["A"], "A"],
+      [%w[A B C], "A"],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        it "returns #{expected.inspect}" do
+          D[*values].first.should == expected
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/inspect_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/inspect_spec.rb
new file mode 100755
index 0000000..ea6be30
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/inspect_spec.rb
@@ -0,0 +1,24 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  describe "#inspect" do
+    [
+      [[], 'Hamster::Deque[]'],
+      [["A"], 'Hamster::Deque["A"]'],
+      [%w[A B C], 'Hamster::Deque["A", "B", "C"]']
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:deque) { D[*values] }
+
+        it "returns #{expected.inspect}" do
+          deque.inspect.should == expected
+        end
+
+        it "returns a string which can be eval'd to get an equivalent object" do
+          eval(deque.inspect).should eql(deque)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/last_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/last_spec.rb
new file mode 100755
index 0000000..a3ac4b1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/last_spec.rb
@@ -0,0 +1,18 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  describe "#last" do
+    [
+      [[], nil],
+      [["A"], "A"],
+      [%w[A B C], "C"],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        it "returns #{expected.inspect}" do
+          D[*values].last.should eql(expected)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/marshal_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/marshal_spec.rb
new file mode 100755
index 0000000..56af317
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/marshal_spec.rb
@@ -0,0 +1,34 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  describe "#marshal_dump/#marshal_load" do
+    let(:ruby) do
+      File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"])
+    end
+    let(:child_cmd) do
+      %Q|#{ruby} -I lib -r hamster -e 'deque = Hamster::Deque[5, 10, 15]; $stdout.write(Marshal.dump(deque))'|
+    end
+
+    let(:reloaded_deque) do
+      IO.popen(child_cmd, "r+") do |child|
+        reloaded_deque = Marshal.load(child)
+        child.close
+        reloaded_deque
+      end
+    end
+
+    it "can survive dumping and loading into a new process" do
+      expect(reloaded_deque).to eql(D[5, 10, 15])
+    end
+
+    it "is still possible to push and pop items after loading" do
+      expect(reloaded_deque.first).to eq(5)
+      expect(reloaded_deque.last).to eq(15)
+      expect(reloaded_deque.push(20)).to eql(D[5, 10, 15, 20])
+      expect(reloaded_deque.pop).to eql(D[5, 10])
+      expect(reloaded_deque.unshift(1)).to eql(D[1, 5, 10, 15])
+      expect(reloaded_deque.shift).to eql(D[10, 15])
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/new_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/new_spec.rb
new file mode 100755
index 0000000..2e78b19
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/new_spec.rb
@@ -0,0 +1,44 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  describe ".new" do
+    it "accepts a single enumerable argument and creates a new deque" do
+      deque = Hamster::Deque.new([1,2,3])
+      deque.size.should be(3)
+      deque.first.should be(1)
+      deque.dequeue.first.should be(2)
+      deque.dequeue.dequeue.first.should be(3)
+    end
+
+    it "is amenable to overriding of #initialize" do
+      class SnazzyDeque < Hamster::Deque
+        def initialize
+          super(['SNAZZY!!!'])
+        end
+      end
+
+      deque = SnazzyDeque.new
+      deque.size.should be(1)
+      deque.to_a.should == ['SNAZZY!!!']
+    end
+
+    context "from a subclass" do
+      it "returns a frozen instance of the subclass" do
+        subclass = Class.new(Hamster::Deque)
+        instance = subclass.new(["some", "values"])
+        instance.class.should be subclass
+        instance.frozen?.should be true
+      end
+    end
+  end
+
+  describe ".[]" do
+    it "accepts a variable number of items and creates a new deque" do
+      deque = Hamster::Deque['a', 'b']
+      deque.size.should be(2)
+      deque.first.should == 'a'
+      deque.dequeue.first.should == 'b'
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/pop_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/pop_spec.rb
new file mode 100755
index 0000000..191ea9d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/pop_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  describe "#pop" do
+    [
+      [[], []],
+      [["A"], []],
+      [%w[A B C], %w[A B]],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:deque) { D[*values] }
+
+        it "preserves the original" do
+          deque.pop
+          deque.should eql(D[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          deque.pop.should eql(D[*expected])
+        end
+
+        it "returns a frozen instance" do
+          deque.pop.should be_frozen
+        end
+      end
+    end
+
+    context "on empty subclass" do
+      let(:subclass) { Class.new(Hamster::Deque) }
+      let(:empty_instance) { subclass.new }
+      it "returns emtpy object of same class" do
+        empty_instance.pop.class.should be subclass
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/pretty_print_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/pretty_print_spec.rb
new file mode 100755
index 0000000..19b022c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/pretty_print_spec.rb
@@ -0,0 +1,24 @@
+require "spec_helper"
+require "hamster/deque"
+require "pp"
+require "stringio"
+
+describe Hamster::Deque do
+  describe "#pretty_print" do
+    let(:deque) { Hamster::Deque["AAAA", "BBBB", "CCCC"] }
+    let(:stringio) { StringIO.new }
+
+    it "prints the whole Deque on one line if it fits" do
+      PP.pp(deque, stringio, 80)
+      stringio.string.chomp.should == 'Hamster::Deque["AAAA", "BBBB", "CCCC"]'
+    end
+
+    it "prints each item on its own line, if not" do
+      PP.pp(deque, stringio, 10)
+      stringio.string.chomp.should == 'Hamster::Deque[
+ "AAAA",
+ "BBBB",
+ "CCCC"]'
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/push_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/push_spec.rb
new file mode 100755
index 0000000..c7327b6
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/push_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  describe "#push" do
+    [
+      [[], "A", ["A"]],
+      [["A"], "B", %w[A B]],
+      [%w[A B C], "D", %w[A B C D]],
+    ].each do |original, item, expected|
+      context "pushing #{item.inspect} into #{original.inspect}" do
+        let(:deque) { D.new(original) }
+
+        it "preserves the original" do
+          deque.push(item)
+          deque.should eql(D.new(original))
+        end
+
+        it "returns #{expected.inspect}" do
+          deque.push(item).should eql(D.new(expected))
+        end
+
+        it "returns a frozen instance" do
+          deque.push(item).should be_frozen
+        end
+      end
+    end
+
+    context "on a subclass" do
+      let(:subclass) { Class.new(Hamster::Deque) }
+      let(:empty_instance) { subclass.new }
+      it "returns an object of same class" do
+        empty_instance.push(1).class.should be subclass
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/random_modification_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/random_modification_spec.rb
new file mode 100755
index 0000000..a90006c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/random_modification_spec.rb
@@ -0,0 +1,34 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  describe "modification (using #push, #pop, #shift, and #unshift)" do
+    it "works when applied in many random combinations" do
+      array = [1,2,3]
+      deque = Hamster::Deque.new(array)
+      1000.times do
+        case [:push, :pop, :shift, :unshift].sample
+        when :push
+          value = rand(10000)
+          array.push(value)
+          deque = deque.push(value)
+        when :pop
+          array.pop
+          deque = deque.pop
+        when :shift
+          array.shift
+          deque = deque.shift
+        when :unshift
+          value = rand(10000)
+          array.unshift(value)
+          deque = deque.unshift(value)
+        end
+
+        deque.to_a.should eql(array)
+        deque.size.should == array.size
+        deque.first.should == array.first
+        deque.last.should == array.last
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/shift_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/shift_spec.rb
new file mode 100755
index 0000000..99c8610
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/shift_spec.rb
@@ -0,0 +1,30 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  describe "#shift" do
+    [
+      [[], []],
+      [["A"], []],
+      [%w[A B C], %w[B C]],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:deque) { D.new(values) }
+
+        it "preserves the original" do
+          deque.shift
+          deque.should eql(D.new(values))
+        end
+
+        it "returns #{expected.inspect}" do
+          deque.shift.should eql(D.new(expected))
+        end
+
+
+        it "returns a frozen instance" do
+          deque.shift.should be_frozen
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/size_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/size_spec.rb
new file mode 100755
index 0000000..68e2913
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/size_spec.rb
@@ -0,0 +1,20 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  [:size, :length].each do |method|
+    describe "##{method}" do
+      [
+        [[], 0],
+        [["A"], 1],
+        [%w[A B C], 3],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            D[*values].send(method).should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/to_a_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/to_a_spec.rb
new file mode 100755
index 0000000..edbb896
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/to_a_spec.rb
@@ -0,0 +1,27 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  [:to_a, :entries].each do |method|
+    describe "##{method}" do
+      [
+        [],
+        ["A"],
+        %w[A B C],
+      ].each do |values|
+        context "on #{values.inspect}" do
+          it "returns #{values.inspect}" do
+            D[*values].send(method).should == values
+          end
+
+          it "returns a mutable array" do
+            result = D[*values].send(method)
+            expect(result.last).to_not eq("The End")
+            result << "The End"
+            result.last.should == "The End"
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/to_ary_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/to_ary_spec.rb
new file mode 100755
index 0000000..676929d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/to_ary_spec.rb
@@ -0,0 +1,36 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  let(:deque) { D["A", "B", "C", "D"] }
+
+  describe "#to_ary" do
+    context "enables implicit conversion to" do
+      it "block parameters" do
+        def func(&block)
+          yield(deque)
+        end
+
+        func do |a, b, *c|
+          expect(a).to eq("A")
+          expect(b).to eq("B")
+          expect(c).to eq(%w[C D])
+        end
+      end
+
+      it "method arguments" do
+        def func(a, b, *c)
+          expect(a).to eq("A")
+          expect(b).to eq("B")
+          expect(c).to eq(%w[C D])
+        end
+        func(*deque)
+      end
+
+      it "works with splat" do
+        array = *deque
+        expect(array).to eq(%w[A B C D])
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/to_list_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/to_list_spec.rb
new file mode 100755
index 0000000..4be06c1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/to_list_spec.rb
@@ -0,0 +1,26 @@
+require "spec_helper"
+require "hamster/deque"
+require "hamster/list"
+
+describe Hamster::Deque do
+  describe "#to_list" do
+    [
+      [],
+      ["A"],
+      %w[A B C],
+    ].each do |values|
+      context "on #{values.inspect}" do
+        it "returns a list containing #{values.inspect}" do
+          D[*values].to_list.should eql(L[*values])
+        end
+      end
+    end
+
+    context "after dedequeing an item from #{%w[A B C].inspect}" do
+      it "returns a list containing #{%w[B C].inspect}" do
+        list = D["A", "B", "C"].dequeue.to_list
+        list.should eql(L["B", "C"])
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/unshift_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/unshift_spec.rb
new file mode 100755
index 0000000..01f4eb1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/deque/unshift_spec.rb
@@ -0,0 +1,31 @@
+require "spec_helper"
+require "hamster/deque"
+
+describe Hamster::Deque do
+  describe "#unshift" do
+    [
+      [[], "A", ["A"]],
+      [["A"], "B", %w[B A]],
+      [["A"], "A", %w[A A]],
+      [%w[A B C], "D", %w[D A B C]],
+    ].each do |values, new_value, expected|
+      context "on #{values.inspect} with #{new_value.inspect}" do
+        let(:deque) { D[*values] }
+
+        it "preserves the original" do
+          deque.unshift(new_value)
+          deque.should eql(D[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          deque.unshift(new_value).should eql(D[*expected])
+        end
+
+
+        it "returns a frozen instance" do
+          deque.unshift(new_value).should be_frozen
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/experimental/mutable_set/add_qm_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/experimental/mutable_set/add_qm_spec.rb
new file mode 100755
index 0000000..75e8685
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/experimental/mutable_set/add_qm_spec.rb
@@ -0,0 +1,39 @@
+require "spec_helper"
+
+require "hamster/experimental/mutable_set"
+
+describe Hamster::MutableSet do
+  let(:mutable) { Hamster::MutableSet[*values] }
+
+  describe "#add?" do
+    let(:values) { %w[A B C] }
+    let(:add?) { mutable.add?(value) }
+
+    context "with a unique value" do
+      let(:value) { "D" }
+
+      it "returns true" do
+        expect(add?).to be true
+      end
+
+      it "modifies the set to include the new value" do
+        add?
+        expect(mutable).to eq(Hamster::MutableSet["A", "B", "C", "D"])
+      end
+
+    end
+
+    context "with a duplicate value" do
+      let(:value) { "C" }
+
+      it "returns false" do
+        expect(add?).to be(false)
+      end
+
+      it "preserves the original values" do
+        add?
+        expect(mutable).to eq(Hamster::MutableSet["A", "B", "C"])
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/experimental/mutable_set/add_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/experimental/mutable_set/add_spec.rb
new file mode 100755
index 0000000..120d8e9
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/experimental/mutable_set/add_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+require "hamster/experimental/mutable_set"
+
+describe Hamster::MutableSet do
+  let(:mutable) { Hamster::MutableSet[*values] }
+
+  describe "#add" do
+    let(:values) { %w[A B C] }
+    let(:add) { mutable.add(value) }
+
+    context "with a unique value" do
+      let(:value) { "D" }
+
+      it "returns self" do
+        expect(add).to eq(mutable)
+      end
+
+      it "modifies the original set to include new value" do
+        add
+        expect(mutable).to eq(Hamster::MutableSet["A", "B", "C", "D"])
+      end
+    end
+
+    context "with a duplicate value" do
+      let(:value) { "C" }
+
+      it "returns self" do
+        expect(add).to eq(mutable)
+      end
+
+      it "preserves the original values" do
+        add
+        expect(mutable).to eq(Hamster::MutableSet["A", "B", "C"])
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/experimental/mutable_set/delete_qm_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/experimental/mutable_set/delete_qm_spec.rb
new file mode 100755
index 0000000..77a7843
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/experimental/mutable_set/delete_qm_spec.rb
@@ -0,0 +1,38 @@
+require "spec_helper"
+require "hamster/experimental/mutable_set"
+
+describe Hamster::MutableSet do
+  let(:mutable) { Hamster::MutableSet[*values] }
+
+  describe "#delete?" do
+    let(:values) { %w[A B C] }
+    let(:delete?) { mutable.delete?(value) }
+
+
+    context "with an existing value" do
+      let(:value) { "B" }
+
+      it "returns true" do
+        expect(delete?).to be(true)
+      end
+
+      it "modifies the set to remove the value" do
+        delete?
+        expect(mutable).to eq(Hamster::MutableSet["A", "C"])
+      end
+    end
+
+    context "with a non-existing value" do
+      let(:value) { "D" }
+
+      it "returns false" do
+        expect(delete?).to be(false)
+      end
+
+      it "preserves the original values" do
+        delete?
+        expect(mutable).to eq(Hamster::MutableSet["A", "B", "C"])
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/experimental/mutable_set/delete_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/experimental/mutable_set/delete_spec.rb
new file mode 100755
index 0000000..7c5871e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/experimental/mutable_set/delete_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+require "hamster/experimental/mutable_set"
+
+describe Hamster::MutableSet do
+  let(:mutable) { Hamster::MutableSet[*values] }
+
+  describe "#delete" do
+    let(:values) { %w[A B C] }
+    let(:delete) { mutable.delete(value) }
+
+    context "with an existing value" do
+      let(:value) { "B" }
+
+      it "returns self" do
+        expect(delete).to eq(mutable)
+      end
+
+      it "modifies the set to remove the value" do
+        delete
+        expect(mutable).to eq(Hamster::MutableSet["A", "C"])
+      end
+    end
+
+    context "with a non-existing value" do
+      let(:value) { "D" }
+
+      it "returns self" do
+        expect(delete).to eq(mutable)
+      end
+
+      it "preserves the original values" do
+        delete
+        expect(mutable).to eq(Hamster::MutableSet["A", "B", "C"])
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/all_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/all_spec.rb
new file mode 100755
index 0000000..d41a9b2
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/all_spec.rb
@@ -0,0 +1,54 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  let(:hash) { H[values] }
+
+  describe "#all?" do
+    context "when empty" do
+      let(:values) { H.new }
+
+      context "without a block" do
+        it "returns true" do
+          hash.all?.should == true
+        end
+      end
+
+      context "with a block" do
+        it "returns true" do
+          hash.all? { false }.should == true
+        end
+      end
+    end
+
+    context "when not empty" do
+      let(:values) { { "A" => 1, "B" => 2, "C" => 3 } }
+
+      context "without a block" do
+        it "returns true" do
+          hash.all?.should == true
+        end
+      end
+
+      context "with a block" do
+        it "returns true if the block always returns true" do
+          hash.all? { true }.should == true
+        end
+
+        it "returns false if the block ever returns false" do
+          hash.all? { |k,v| k != 'C' }.should == false
+        end
+
+        it "propagates an exception from the block" do
+          -> { hash.all? { |k,v| raise "help" } }.should raise_error(RuntimeError)
+        end
+
+        it "stops iterating as soon as the block returns false" do
+          yielded = []
+          hash.all? { |k,v| yielded << k; false }
+          yielded.size.should == 1
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/any_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/any_spec.rb
new file mode 100755
index 0000000..8d6c6a4
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/any_spec.rb
@@ -0,0 +1,54 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#any?" do
+    context "when empty" do
+      it "with a block returns false" do
+        H.empty.any? {}.should == false
+      end
+
+      it "with no block returns false" do
+        H.empty.any?.should == false
+      end
+    end
+
+    context "when not empty" do
+      let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see", nil => "NIL"] }
+
+      context "with a block" do
+        [
+          %w[A aye],
+          %w[B bee],
+          %w[C see],
+          [nil, "NIL"],
+        ].each do |pair|
+
+          it "returns true if the block ever returns true (#{pair.inspect})" do
+            hash.any? { |key, value| key == pair.first && value == pair.last }.should == true
+          end
+
+          it "returns false if the block always returns false" do
+            hash.any? { |key, value| key == "D" && value == "dee" }.should == false
+          end
+        end
+
+        it "propagates exceptions raised in the block" do
+          -> { hash.any? { |k,v| raise "help" } }.should raise_error(RuntimeError)
+        end
+
+        it "stops iterating as soon as the block returns true" do
+          yielded = []
+          hash.any? { |k,v| yielded << k; true }
+          yielded.size.should == 1
+        end
+      end
+
+      context "with no block" do
+        it "returns true" do
+          hash.any?.should == true
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/assoc_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/assoc_spec.rb
new file mode 100755
index 0000000..0e0afbf
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/assoc_spec.rb
@@ -0,0 +1,52 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  let(:hash) { H[a: 3, b: 2, c: 1] }
+
+  describe "#assoc" do
+    it "searches for a key/val pair with a given key" do
+      hash.assoc(:a).should == [:a, 3]
+      hash.assoc(:b).should == [:b, 2]
+      hash.assoc(:c).should == [:c, 1]
+    end
+
+    it "returns nil if a matching key is not found" do
+      hash.assoc(:d).should be_nil
+      hash.assoc(nil).should be_nil
+      hash.assoc(0).should be_nil
+    end
+
+    it "returns nil even if there is a default" do
+      H.new(a: 1, b: 2) { fail }.assoc(:c).should be_nil
+    end
+
+    it "uses #== to compare keys with provided object" do
+      hash.assoc(EqualNotEql.new).should_not be_nil
+      hash.assoc(EqlNotEqual.new).should be_nil
+    end
+  end
+
+  describe "#rassoc" do
+    it "searches for a key/val pair with a given value" do
+      hash.rassoc(1).should == [:c, 1]
+      hash.rassoc(2).should == [:b, 2]
+      hash.rassoc(3).should == [:a, 3]
+    end
+
+    it "returns nil if a matching value is not found" do
+      hash.rassoc(0).should be_nil
+      hash.rassoc(4).should be_nil
+      hash.rassoc(nil).should be_nil
+    end
+
+    it "returns nil even if there is a default" do
+      H.new(a: 1, b: 2) { fail }.rassoc(3).should be_nil
+    end
+
+    it "uses #== to compare values with provided object" do
+      hash.rassoc(EqualNotEql.new).should_not be_nil
+      hash.rassoc(EqlNotEqual.new).should be_nil
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/clear_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/clear_spec.rb
new file mode 100755
index 0000000..36b72e9
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/clear_spec.rb
@@ -0,0 +1,43 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#clear" do
+    [
+      [],
+      ["A" => "aye"],
+      ["A" => "aye", "B" => "bee", "C" => "see"],
+    ].each do |values|
+      context "on #{values}" do
+        let(:original) { H[*values] }
+        let(:result)   { original.clear }
+
+        it "preserves the original" do
+          result
+          original.should eql(H[*values])
+        end
+
+        it "returns an empty hash" do
+          result.should equal(H.empty)
+          result.should be_empty
+        end
+      end
+    end
+
+    it "maintains the default Proc, if there is one" do
+      hash = H.new(a: 1) { 1 }
+      hash.clear[:b].should == 1
+      hash.clear[:c].should == 1
+      hash.clear.default_proc.should_not be_nil
+    end
+
+    context "on a subclass" do
+      it "returns an empty instance of the subclass" do
+        subclass = Class.new(Hamster::Hash)
+        instance = subclass.new(a: 1, b: 2)
+        instance.clear.class.should be(subclass)
+        instance.clear.should be_empty
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/construction_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/construction_spec.rb
new file mode 100755
index 0000000..5e74da4
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/construction_spec.rb
@@ -0,0 +1,39 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe ".hash" do
+    context "with nothing" do
+      it "returns the canonical empty hash" do
+        H.empty.should be_empty
+        H.empty.should equal(Hamster::EmptyHash)
+      end
+    end
+
+    context "with an implicit hash" do
+      let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+
+      it "is equivalent to repeatedly using #put" do
+        hash.should eql(H.empty.put("A", "aye").put("B", "bee").put("C", "see"))
+        hash.size.should == 3
+      end
+    end
+
+    context "with an array of pairs" do
+      let(:hash) { H[[[:a, 1], [:b, 2]]] }
+
+      it "initializes a new Hash" do
+        hash.should eql(H[a: 1, b: 2])
+      end
+    end
+
+    context "with a Hamster::Hash" do
+      let(:hash) { H[a: 1, b: 2] }
+      let(:other) { H[hash] }
+
+      it "initializes an equivalent Hash" do
+        hash.should eql(other)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/copying_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/copying_spec.rb
new file mode 100755
index 0000000..1de02d5
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/copying_spec.rb
@@ -0,0 +1,14 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+
+  [:dup, :clone].each do |method|
+    describe "##{method}" do
+      it "returns self" do
+        hash.send(method).should equal(hash)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/default_proc_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/default_proc_spec.rb
new file mode 100755
index 0000000..786bafd
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/default_proc_spec.rb
@@ -0,0 +1,73 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#default_proc" do
+    let(:hash) { H.new(1 => 2, 2 => 4) { |k| k * 2 } }
+
+    it "returns the default block given when the Hash was created" do
+      hash.default_proc.class.should be(Proc)
+      hash.default_proc.call(3).should == 6
+    end
+
+    it "returns nil if no default block was given" do
+      H.empty.default_proc.should be_nil
+    end
+
+    context "after a key/val pair are inserted" do
+      it "doesn't change" do
+        other = hash.put(3, 6)
+        other.default_proc.should be(hash.default_proc)
+        other.default_proc.call(4).should == 8
+      end
+    end
+
+    context "after all key/val pairs are filtered out" do
+      it "doesn't change" do
+        other = hash.reject { true }
+        other.default_proc.should be(hash.default_proc)
+        other.default_proc.call(4).should == 8
+      end
+    end
+
+    context "after Hash is inverted" do
+      it "doesn't change" do
+        other = hash.invert
+        other.default_proc.should be(hash.default_proc)
+        other.default_proc.call(4).should == 8
+      end
+    end
+
+    context "when a slice is taken" do
+      it "doesn't change" do
+        other = hash.slice(1)
+        other.default_proc.should be(hash.default_proc)
+        other.default_proc.call(5).should == 10
+      end
+    end
+
+    context "when keys are removed with #except" do
+      it "doesn't change" do
+        other = hash.except(1, 2)
+        other.default_proc.should be(hash.default_proc)
+        other.default_proc.call(5).should == 10
+      end
+    end
+
+    context "when Hash is mapped" do
+      it "doesn't change" do
+        other = hash.map { |k,v| [k + 10, v] }
+        other.default_proc.should be(hash.default_proc)
+        other.default_proc.call(5).should == 10
+      end
+    end
+
+    context "when another Hash is merged in" do
+      it "doesn't change" do
+        other = hash.merge(3 => 6, 4 => 8)
+        other.default_proc.should be(hash.default_proc)
+        other.default_proc.call(5).should == 10
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/delete_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/delete_spec.rb
new file mode 100755
index 0000000..af7404d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/delete_spec.rb
@@ -0,0 +1,40 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#delete" do
+    let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+
+    context "with an existing key" do
+      let(:result) { hash.delete("B") }
+
+      it "preserves the original" do
+        hash.should eql(H["A" => "aye", "B" => "bee", "C" => "see"])
+      end
+
+      it "returns a copy with the remaining key/value pairs" do
+        result.should eql(H["A" => "aye", "C" => "see"])
+      end
+    end
+
+    context "with a non-existing key" do
+      let(:result) { hash.delete("D") }
+
+      it "preserves the original values" do
+        hash.should eql(H["A" => "aye", "B" => "bee", "C" => "see"])
+      end
+
+      it "returns self" do
+        result.should equal(hash)
+      end
+    end
+
+    context "when removing the last key" do
+      context "from a Hash with no default block" do
+        it "returns the canonical empty Hash" do
+          hash.delete('A').delete('B').delete('C').should be(Hamster::EmptyHash)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/dig_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/dig_spec.rb
new file mode 100755
index 0000000..0e5d204
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/dig_spec.rb
@@ -0,0 +1,32 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#dig" do
+    let(:h) { H[:a => 9, :b => H[:c => 'a', :d => 4], :e => nil] }
+    it "returns the value with one argument to dig" do
+      expect(h.dig(:a)).to eq(9)
+    end
+
+    it "returns the value in nested hashes" do
+      expect(h.dig(:b, :c)).to eq('a')
+    end
+
+    it "returns nil if the key is not present" do
+      expect(h.dig(:f, :foo)).to eq(nil)
+    end
+
+    it "returns nil if you dig out the end of the hash" do
+      expect(h.dig(:f, :foo, :bar)).to eq(nil)
+    end
+
+    it "returns nil if a value does not support dig" do
+      expect(h.dig(:a, :foo)).to eq(nil)
+    end
+
+    it "returns the correct value when there is a default proc" do
+      default_hash = H.new { |k| "#{k}-default" }
+      expect(default_hash.dig(:a)).to eq("a-default")
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/each_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/each_spec.rb
new file mode 100755
index 0000000..b24238b
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/each_spec.rb
@@ -0,0 +1,78 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+
+  [:each, :each_pair].each do |method|
+    describe "##{method}" do
+      context "with a block (internal iteration)" do
+        it "returns self" do
+          hash.send(method) {}.should be(hash)
+        end
+
+        it "yields all key/value pairs" do
+          actual_pairs = {}
+          hash.send(method) { |key, value| actual_pairs[key] = value }
+          actual_pairs.should == { "A" => "aye", "B" => "bee", "C" => "see" }
+        end
+
+        it "yields key/value pairs in the same order as #each_key and #each_value" do
+          hash.each.to_a.should eql(hash.each_key.zip(hash.each_value))
+        end
+
+        it "yields both of a pair of colliding keys" do
+          yielded = []
+          hash = H[DeterministicHash.new('a', 1) => 1, DeterministicHash.new('b', 1) => 1]
+          hash.each { |k,v| yielded << k }
+          yielded.size.should == 2
+          yielded.map { |x| x.value }.sort.should == ['a', 'b']
+        end
+
+        it "yields only the key to a block expecting |key,|" do
+          keys = []
+          hash.each { |key,| keys << key }
+          keys.sort.should == ["A", "B", "C"]
+        end
+      end
+
+      context "with no block" do
+        it "returns an Enumerator" do
+          @result = hash.send(method)
+          @result.class.should be(Enumerator)
+          @result.to_a.should == hash.to_a
+        end
+      end
+    end
+  end
+
+  describe "#each_key" do
+    it "yields all keys" do
+      keys = []
+      hash.each_key { |k| keys << k }
+      keys.sort.should == ['A', 'B', 'C']
+    end
+
+    context "with no block" do
+      it "returns an Enumerator" do
+        hash.each_key.class.should be(Enumerator)
+        hash.each_key.to_a.sort.should == ['A', 'B', 'C']
+      end
+    end
+  end
+
+  describe "#each_value" do
+    it "yields all values" do
+      values = []
+      hash.each_value { |v| values << v }
+      values.sort.should == ['aye', 'bee', 'see']
+    end
+
+    context "with no block" do
+      it "returns an Enumerator" do
+        hash.each_value.class.should be(Enumerator)
+        hash.each_value.to_a.sort.should == ['aye', 'bee', 'see']
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/each_with_index_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/each_with_index_spec.rb
new file mode 100755
index 0000000..7165e46
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/each_with_index_spec.rb
@@ -0,0 +1,30 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#each_with_index" do
+    let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+
+    describe "with a block (internal iteration)" do
+      it "returns self" do
+        hash.each_with_index {}.should be(hash)
+      end
+
+      it "yields all key/value pairs with numeric indexes" do
+        actual_pairs = {}
+        indexes = []
+        hash.each_with_index { |(key, value), index| actual_pairs[key] = value; indexes << index }
+        actual_pairs.should == { "A" => "aye", "B" => "bee", "C" => "see" }
+        indexes.sort.should == [0, 1, 2]
+      end
+    end
+
+    describe "with no block" do
+      it "returns an Enumerator" do
+        hash.each_with_index.should be_kind_of(Enumerator)
+        hash.each_with_index.to_a.map(&:first).sort.should eql([["A", "aye"], ["B", "bee"], ["C", "see"]])
+        hash.each_with_index.to_a.map(&:last).should eql([0,1,2])
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/empty_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/empty_spec.rb
new file mode 100755
index 0000000..642be4b
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/empty_spec.rb
@@ -0,0 +1,44 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#empty?" do
+    [
+      [[], true],
+      [["A" => "aye"], false],
+      [["A" => "aye", "B" => "bee", "C" => "see"], false],
+    ].each do |pairs, result|
+      it "returns #{result} for #{pairs.inspect}" do
+        H[*pairs].empty?.should == result
+      end
+    end
+
+    it "returns true for empty hashes which have a default block" do
+      H.new { 'default' }.empty?.should == true
+    end
+  end
+
+  describe ".empty" do
+    it "returns the canonical empty Hash" do
+      H.empty.should be_empty
+      H.empty.should be(Hamster::EmptyHash)
+    end
+
+    context "from a subclass" do
+      it "returns an empty instance of the subclass" do
+        subclass = Class.new(Hamster::Hash)
+        subclass.empty.class.should be subclass
+        subclass.empty.should be_empty
+      end
+
+      it "calls overridden #initialize when creating empty Hash" do
+        subclass = Class.new(Hamster::Hash) do
+          def initialize
+            @variable = 'value'
+          end
+        end
+        subclass.empty.instance_variable_get(:@variable).should == 'value'
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/eql_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/eql_spec.rb
new file mode 100755
index 0000000..0018469
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/eql_spec.rb
@@ -0,0 +1,70 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+
+  describe "#eql?" do
+    it "returns false when comparing with a standard hash" do
+      hash.eql?("A" => "aye", "B" => "bee", "C" => "see").should == false
+    end
+
+    it "returns false when comparing with an arbitrary object" do
+      hash.eql?(Object.new).should == false
+    end
+
+    it "returns false when comparing with a subclass of Hamster::Hash" do
+      subclass = Class.new(Hamster::Hash)
+      instance = subclass.new("A" => "aye", "B" => "bee", "C" => "see")
+      hash.eql?(instance).should == false
+    end
+  end
+
+  describe "#==" do
+    it "returns true when comparing with a standard hash" do
+      (hash == {"A" => "aye", "B" => "bee", "C" => "see"}).should == true
+    end
+
+    it "returns false when comparing with an arbitrary object" do
+      (hash == Object.new).should == false
+    end
+
+    it "returns true when comparing with a subclass of Hamster::Hash" do
+      subclass = Class.new(Hamster::Hash)
+      instance = subclass.new("A" => "aye", "B" => "bee", "C" => "see")
+      (hash == instance).should == true
+    end
+  end
+
+  [:eql?, :==].each do |method|
+    describe "##{method}" do
+      [
+        [{}, {}, true],
+        [{ "A" => "aye" }, {}, false],
+        [{}, { "A" => "aye" }, false],
+        [{ "A" => "aye" }, { "A" => "aye" }, true],
+        [{ "A" => "aye" }, { "B" => "bee" }, false],
+        [{ "A" => "aye", "B" => "bee" }, { "A" => "aye" }, false],
+        [{ "A" => "aye" }, { "A" => "aye", "B" => "bee" }, false],
+        [{ "A" => "aye", "B" => "bee", "C" => "see" }, { "A" => "aye", "B" => "bee", "C" => "see" }, true],
+        [{ "C" => "see", "A" => "aye", "B" => "bee" }, { "A" => "aye", "B" => "bee", "C" => "see" }, true],
+      ].each do |a, b, expected|
+        describe "returns #{expected.inspect}" do
+          it "for #{a.inspect} and #{b.inspect}" do
+            H[a].send(method, H[b]).should == expected
+          end
+
+          it "for #{b.inspect} and #{a.inspect}" do
+            H[b].send(method, H[a]).should == expected
+          end
+        end
+      end
+    end
+  end
+
+  it "returns true on a large hash which is modified and then modified back again" do
+    hash = H.new((1..1000).zip(2..1001))
+    hash.put('a', 1).delete('a').should == hash
+    hash.put('b', 2).delete('b').should eql(hash)
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/except_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/except_spec.rb
new file mode 100755
index 0000000..8bfabe3
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/except_spec.rb
@@ -0,0 +1,43 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#except" do
+    let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see", nil => "NIL"] }
+
+    context "with only keys that the Hash has" do
+      it "returns a Hash without those values" do
+        hash.except("B", nil).should eql(H["A" => "aye", "C" => "see"])
+      end
+
+      it "doesn't change the original Hash" do
+        hash.except("B", nil)
+        hash.should eql(H["A" => "aye", "B" => "bee", "C" => "see", nil => "NIL"])
+      end
+    end
+
+    context "with keys that the Hash doesn't have" do
+      it "returns a Hash without the values that it had keys for" do
+        hash.except("B", "A", 3).should eql(H["C" => "see", nil => "NIL"])
+      end
+
+      it "doesn't change the original Hash" do
+        hash.except("B", "A", 3)
+        hash.should eql(H["A" => "aye", "B" => "bee", "C" => "see", nil => "NIL"])
+      end
+    end
+
+    it "works on a large Hash, with many combinations of input" do
+      keys = (1..1000).to_a
+      original = H.new(keys.zip(2..1001))
+      100.times do
+        to_remove = rand(100).times.collect { keys.sample }
+        result    = original.except(*to_remove)
+        result.size.should == original.size - to_remove.uniq.size
+        to_remove.each { |key| result.key?(key).should == false }
+        (keys.sample(100) - to_remove).each { |key| result.key?(key).should == true }
+      end
+      original.should eql(H.new(keys.zip(2..1001))) # shouldn't have changed
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/fetch_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/fetch_spec.rb
new file mode 100755
index 0000000..42fb653
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/fetch_spec.rb
@@ -0,0 +1,58 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#fetch" do
+    context "with no default provided" do
+      context "when the key exists" do
+        it "returns the value associated with the key" do
+          H["A" => "aye"].fetch("A").should == "aye"
+        end
+      end
+
+      context "when the key does not exist" do
+        it "raises a KeyError" do
+          -> { H["A" => "aye"].fetch("B") }.should raise_error(KeyError)
+        end
+      end
+    end
+
+    context "with a default value" do
+      context "when the key exists" do
+        it "returns the value associated with the key" do
+          H["A" => "aye"].fetch("A", "default").should == "aye"
+        end
+      end
+
+      context "when the key does not exist" do
+        it "returns the default value" do
+          H["A" => "aye"].fetch("B", "default").should == "default"
+        end
+      end
+    end
+
+    context "with a default block" do
+      context "when the key exists" do
+        it "returns the value associated with the key" do
+          H["A" => "aye"].fetch("A") { "default".upcase }.should == "aye"
+        end
+      end
+
+      context "when the key does not exist" do
+        it "invokes the default block with the missing key as paramter" do
+          H["A" => "aye"].fetch("B") { |key| key.should == "B" }
+          H["A" => "aye"].fetch("B") { "default".upcase }.should == "DEFAULT"
+        end
+      end
+    end
+
+    it "gives precedence to default block over default argument if passed both" do
+      H["A" => "aye"].fetch("B", 'one') { 'two' }.should == 'two'
+    end
+
+    it "raises an ArgumentError when not passed one or 2 arguments" do
+      -> { H.empty.fetch }.should raise_error(ArgumentError)
+      -> { H.empty.fetch(1, 2, 3) }.should raise_error(ArgumentError)
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/fetch_values_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/fetch_values_spec.rb
new file mode 100755
index 0000000..c697569
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/fetch_values_spec.rb
@@ -0,0 +1,22 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#fetch_values" do
+    context "when the all the requests keys exist" do
+      it "returns a vector of values for the given keys" do
+        h = H[:a => 9, :b => 'a', :c => -10, :d => nil]
+        h.fetch_values.should be_kind_of(Hamster::Vector)
+        h.fetch_values.should eql(V.empty)
+        h.fetch_values(:a, :d, :b).should be_kind_of(Hamster::Vector)
+        h.fetch_values(:a, :d, :b).should eql(V[9, nil, 'a'])
+      end
+    end
+
+    context "when the key does not exist" do
+      it "raises a KeyError" do
+        -> { H["A" => "aye", "C" => "Cee"].fetch_values("A", "B") }.should raise_error(KeyError)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/find_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/find_spec.rb
new file mode 100755
index 0000000..a306e1d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/find_spec.rb
@@ -0,0 +1,44 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  [:find, :detect].each do |method|
+    describe "##{method}" do
+      [
+        [[], "A", nil],
+        [[], nil, nil],
+        [["A" => "aye"], "A", ["A", "aye"]],
+        [["A" => "aye"], "B", nil],
+        [["A" => "aye"], nil, nil],
+        [["A" => "aye", "B" => "bee", nil => "NIL"], "A", ["A", "aye"]],
+        [["A" => "aye", "B" => "bee", nil => "NIL"], "B", ["B", "bee"]],
+        [["A" => "aye", "B" => "bee", nil => "NIL"], nil, [nil, "NIL"]],
+        [["A" => "aye", "B" => "bee", nil => "NIL"], "C", nil],
+      ].each do |values, key, expected|
+        describe "on #{values.inspect}" do
+          let(:hash) { H[*values] }
+
+          describe "with a block" do
+            it "returns #{expected.inspect}" do
+              hash.send(method) { |k, v| k == key }.should == expected
+            end
+          end
+
+          describe "without a block" do
+            it "returns an Enumerator" do
+              result = hash.send(method)
+              result.class.should be(Enumerator)
+              result.each { |k,v| k == key }.should == expected
+            end
+          end
+        end
+      end
+
+      it "stops iterating when the block returns true" do
+        yielded = []
+        H[a: 1, b: 2].find { |k,v| yielded << k; true }
+        yielded.size.should == 1
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/flat_map_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/flat_map_spec.rb
new file mode 100755
index 0000000..e95ffc0
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/flat_map_spec.rb
@@ -0,0 +1,36 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+
+  describe "#flat_map" do
+    it "yields each key/val pair" do
+      passed = []
+      hash.flat_map { |pair| passed << pair }
+      passed.sort.should == [['A', 'aye'], ['B', 'bee'], ['C', 'see']]
+    end
+
+    it "returns the concatenation of block return values" do
+      hash.flat_map { |k,v| [k,v] }.sort.should == ['A', 'B', 'C', 'aye', 'bee', 'see']
+      hash.flat_map { |k,v| L[k,v] }.sort.should == ['A', 'B', 'C', 'aye', 'bee', 'see']
+      hash.flat_map { |k,v| V[k,v] }.sort.should == ['A', 'B', 'C', 'aye', 'bee', 'see']
+    end
+
+    it "doesn't change the receiver" do
+      hash.flat_map { |k,v| [k,v] }
+      hash.should eql(H["A" => "aye", "B" => "bee", "C" => "see"])
+    end
+
+    context "with no block" do
+      it "returns an Enumerator" do
+        hash.flat_map.class.should be(Enumerator)
+        hash.flat_map.each { |k,v| [k] }.sort.should == ['A', 'B', 'C']
+      end
+    end
+
+    it "returns an empty array if only empty arrays are returned by block" do
+      hash.flat_map { [] }.should eql([])
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/flatten_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/flatten_spec.rb
new file mode 100755
index 0000000..9f628c3
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/flatten_spec.rb
@@ -0,0 +1,99 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#flatten" do
+    context "with flatten depth of zero" do
+      it "returns a vector of keys/value" do
+        hash = H[a: 1, b: 2]
+        hash.flatten(0).sort.should eql(V[[:a, 1], [:b, 2]])
+      end
+    end
+
+    context "without array keys or values" do
+      it "returns a vector of keys and values" do
+        hash = H[a: 1, b: 2, c: 3]
+        possibilities = [[:a, 1, :b, 2, :c, 3],
+         [:a, 1, :c, 3, :b, 2],
+         [:b, 2, :a, 1, :c, 3],
+         [:b, 2, :c, 3, :a, 1],
+         [:c, 3, :a, 1, :b, 2],
+         [:c, 3, :b, 2, :a, 1]]
+        possibilities.include?(hash.flatten).should == true
+        possibilities.include?(hash.flatten(1)).should == true
+        possibilities.include?(hash.flatten(2)).should == true
+        hash.flatten(2).class.should be(Hamster::Vector)
+        possibilities.include?(hash.flatten(10)).should == true
+      end
+
+      it "doesn't modify the receiver" do
+        hash = H[a: 1, b: 2, c: 3]
+        hash.flatten(1)
+        hash.flatten(2)
+        hash.should eql(H[a: 1, b: 2, c: 3])
+      end
+    end
+
+    context "on an empty Hash" do
+      it "returns an empty Vector" do
+        H.empty.flatten.should eql(V.empty)
+      end
+    end
+
+    context "with array keys" do
+      it "flattens array keys into returned vector if flatten depth is sufficient" do
+        hash = H[[1, 2] => 3, [4, 5] => 6]
+        [[[1, 2], 3, [4, 5], 6], [[4, 5], 6, [1, 2], 3]].include?(hash.flatten(1)).should == true
+        [[[1, 2], 3, [4, 5], 6], [[4, 5], 6, [1, 2], 3]].include?(hash.flatten).should == true
+        hash.flatten(1).class.should be(Hamster::Vector)
+        [[1, 2, 3, 4, 5, 6], [4, 5, 6, 1, 2, 3]].include?(hash.flatten(2)).should == true
+        [[1, 2, 3, 4, 5, 6], [4, 5, 6, 1, 2, 3]].include?(hash.flatten(3)).should == true
+      end
+
+      it "doesn't modify the receiver (or its contents)" do
+        hash = H[[1, 2] => 3, [4, 5] => 6]
+        hash.flatten(1)
+        hash.flatten(2)
+        hash.should eql(H[[1, 2] => 3, [4, 5] => 6])
+      end
+    end
+
+    context "with array values" do
+      it "flattens array values into returned vector if flatten depth is sufficient" do
+        hash = H[1 => [2, 3], 4 => [5, 6]]
+        [[1, [2, 3], 4, [5, 6]], [4, [5, 6], 1, [2, 3]]].include?(hash.flatten(1)).should == true
+        [[1, [2, 3], 4, [5, 6]], [4, [5, 6], 1, [2, 3]]].include?(hash.flatten).should == true
+        [[1, 2, 3, 4, 5, 6], [4, 5, 6, 1, 2, 3]].include?(hash.flatten(2)).should == true
+        [[1, 2, 3, 4, 5, 6], [4, 5, 6, 1, 2, 3]].include?(hash.flatten(3)).should == true
+        hash.flatten(3).class.should be(Hamster::Vector)
+      end
+
+      it "doesn't modify the receiver (or its contents)" do
+        hash = H[1 => [2, 3], 4 => [5, 6]]
+        hash.flatten(1)
+        hash.flatten(2)
+        hash.should eql(H[1 => [2, 3], 4 => [5, 6]])
+      end
+    end
+
+    context "with vector keys" do
+      it "flattens vector keys into returned vector if flatten depth is sufficient" do
+        hash = H[V[1, 2] => 3, V[4, 5] => 6]
+        [[V[1, 2], 3, V[4, 5], 6], [V[4, 5], 6, V[1, 2], 3]].include?(hash.flatten).should == true
+        [[V[1, 2], 3, V[4, 5], 6], [V[4, 5], 6, V[1, 2], 3]].include?(hash.flatten(1)).should == true
+        [[1, 2, 3, 4, 5, 6], [4, 5, 6, 1, 2, 3]].include?(hash.flatten(2)).should == true
+        [[1, 2, 3, 4, 5, 6], [4, 5, 6, 1, 2, 3]].include?(hash.flatten(3)).should == true
+      end
+    end
+
+    context "with vector values" do
+      it "flattens vector values into returned vector if flatten depth is sufficient" do
+        hash = H[1 => V[2, 3], 4 => V[5, 6]]
+        [[1, V[2, 3], 4, V[5, 6]], [4, V[5, 6], 1, V[2, 3]]].include?(hash.flatten(1)).should == true
+        [[1, V[2, 3], 4, V[5, 6]], [4, V[5, 6], 1, V[2, 3]]].include?(hash.flatten).should == true
+        [[1, 2, 3, 4, 5, 6], [4, 5, 6, 1, 2, 3]].include?(hash.flatten(2)).should == true
+        [[1, 2, 3, 4, 5, 6], [4, 5, 6, 1, 2, 3]].include?(hash.flatten(3)).should == true
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/get_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/get_spec.rb
new file mode 100755
index 0000000..08091c2
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/get_spec.rb
@@ -0,0 +1,80 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  [:get, :[]].each do |method|
+    describe "##{method}" do
+      context "with a default block" do
+        let(:hash) { H.new("A" => "aye") { |key| fail }}
+
+        context "when the key exists" do
+          it "returns the value associated with the key" do
+            hash.send(method, "A").should == "aye"
+          end
+
+          it "does not call the default block even if the key is 'nil'" do
+            H.new(nil => 'something') { fail }.send(method, nil)
+          end
+        end
+
+        context "when the key does not exist" do
+          let(:hash) do
+            H.new("A" => "aye") do |key|
+              expect(key).to eq("B")
+              "bee"
+            end
+          end
+
+          it "returns the value from the default block" do
+            hash.send(method, "B").should == "bee"
+          end
+        end
+      end
+
+      context "with no default block" do
+        let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see", nil => "NIL"] }
+
+        [
+          %w[A aye],
+          %w[B bee],
+          %w[C see],
+          [nil, "NIL"]
+        ].each do |key, value|
+          it "returns the value (#{value.inspect}) for an existing key (#{key.inspect})" do
+            hash.send(method, key).should == value
+          end
+        end
+
+        it "returns nil for a non-existing key" do
+          hash.send(method, "D").should be_nil
+        end
+      end
+
+      it "uses #hash to look up keys" do
+        x = double('0')
+        x.should_receive(:hash).and_return(0)
+        H[foo: :bar].send(method, x).should be_nil
+      end
+
+      it "uses #eql? to compare keys with the same hash code" do
+        x = double('x', hash: 42)
+        x.should_not_receive(:eql?)
+
+        y = double('y', hash: 42)
+        y.should_receive(:eql?).and_return(true)
+
+        H[y => 1][x].should == 1
+      end
+
+      it "does not use #eql? to compare keys with different hash codes" do
+        x = double('x', hash: 0)
+        x.should_not_receive(:eql?)
+
+        y = double('y', hash: 1)
+        y.should_not_receive(:eql?)
+
+        H[y => 1][x].should be_nil
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/has_key_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/has_key_spec.rb
new file mode 100755
index 0000000..25cc11f
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/has_key_spec.rb
@@ -0,0 +1,32 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  [:key?, :has_key?, :include?, :member?].each do |method|
+    describe "##{method}" do
+      let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see", nil => "NIL", 2.0 => "two"] }
+
+      ["A", "B", "C", nil, 2.0].each do |key|
+        it "returns true for an existing key (#{key.inspect})" do
+          hash.send(method, key).should == true
+        end
+      end
+
+      it "returns false for a non-existing key" do
+        hash.send(method, "D").should == false
+      end
+
+      it "uses #eql? for equality" do
+        hash.send(method, 2).should == false
+      end
+
+      it "returns true if the key is found and maps to nil" do
+        H["A" => nil].send(method, "A").should == true
+      end
+
+      it "returns true if the key is found and maps to false" do
+        H["A" => false].send(method, "A").should == true
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/has_value_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/has_value_spec.rb
new file mode 100755
index 0000000..7946b07
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/has_value_spec.rb
@@ -0,0 +1,28 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  let(:hash) { H[toast: 'buttered', jam: 'strawberry'] }
+
+  [:value?, :has_value?].each do |method|
+    describe "##{method}" do
+      it "returns true if any key/val pair in Hash has the same value" do
+        hash.send(method, 'strawberry').should == true
+      end
+
+      it "returns false if no key/val pair in Hash has the same value" do
+        hash.send(method, 'marmalade').should == false
+      end
+
+      it "uses #== to check equality" do
+        H[a: EqualNotEql.new].send(method, EqualNotEql.new).should == true
+        H[a: EqlNotEqual.new].send(method, EqlNotEqual.new).should == false
+      end
+
+      it "works on a large hash" do
+        large = H.new((1..1000).zip(2..1001))
+        [2, 100, 200, 500, 900, 1000, 1001].each { |n| large.value?(n).should == true }
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/hash_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/hash_spec.rb
new file mode 100755
index 0000000..681ca43
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/hash_spec.rb
@@ -0,0 +1,30 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#hash" do
+    it "values are sufficiently distributed" do
+      (1..4000).each_slice(4).map { |ka, va, kb, vb| H[ka => va, kb => vb].hash }.uniq.size.should == 1000
+    end
+
+    it "differs given the same keys and different values" do
+      H["ka" => "va"].hash.should_not == H["ka" => "vb"].hash
+    end
+
+    it "differs given the same values and different keys" do
+      H["ka" => "va"].hash.should_not == H["kb" => "va"].hash
+    end
+
+    it "generates the same hash value for a hash regardless of the order things were added to it" do
+      key1 = DeterministicHash.new('abc', 1)
+      key2 = DeterministicHash.new('xyz', 1)
+      H.empty.put(key1, nil).put(key2, nil).hash.should == H.empty.put(key2, nil).put(key1, nil).hash
+    end
+
+    describe "on an empty hash" do
+      it "returns 0" do
+        H.empty.hash.should == 0
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/immutable_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/immutable_spec.rb
new file mode 100755
index 0000000..cc6d89e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/immutable_spec.rb
@@ -0,0 +1,9 @@
+require "spec_helper"
+require "hamster/immutable"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  it "includes Immutable" do
+    Hamster::Hash.should include(Hamster::Immutable)
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/inspect_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/inspect_spec.rb
new file mode 100755
index 0000000..213f32b
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/inspect_spec.rb
@@ -0,0 +1,31 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#inspect" do
+    [
+      [[], 'Hamster::Hash[]'],
+      [["A" => "aye"], 'Hamster::Hash["A" => "aye"]'],
+      [[DeterministicHash.new("A", 1) => "aye", DeterministicHash.new("B", 2) => "bee", DeterministicHash.new("C", 3) => "see"], 'Hamster::Hash["A" => "aye", "B" => "bee", "C" => "see"]']
+    ].each do |values, expected|
+      describe "on #{values.inspect}" do
+        it "returns #{expected.inspect}" do
+          H[*values].inspect.should == expected
+        end
+      end
+    end
+
+    [
+      {},
+      {"A" => "aye"},
+      {a: "aye", b: "bee", c: "see"}
+    ].each do |values|
+      describe "on #{values.inspect}" do
+        it "returns a string which can be eval'd to get an equivalent object" do
+          original = H.new(values)
+          eval(original.inspect).should eql(original)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/invert_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/invert_spec.rb
new file mode 100755
index 0000000..8404f41
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/invert_spec.rb
@@ -0,0 +1,31 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#invert" do
+    let(:hash) { H[a: 3, b: 2, c: 1] }
+
+    it "uses the existing keys as values and values as keys" do
+      hash.invert.should eql(H[3 => :a, 2 => :b, 1 => :c])
+    end
+
+    it "will select one key/value pair among multiple which have same value" do
+      [H[1 => :a],
+       H[1 => :b],
+       H[1 => :c]].include?(H[a: 1, b: 1, c: 1].invert).should == true
+    end
+
+    it "doesn't change the original Hash" do
+      hash.invert
+      hash.should eql(H[a: 3, b: 2, c: 1])
+    end
+
+    context "from a subclass of Hash" do
+      it "returns an instance of the subclass" do
+        subclass = Class.new(Hamster::Hash)
+        instance = subclass.new(a: 1, b: 2)
+        instance.invert.class.should be(subclass)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/key_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/key_spec.rb
new file mode 100755
index 0000000..d65d3a1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/key_spec.rb
@@ -0,0 +1,28 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#key" do
+    let(:hash) { H[a: 1, b: 1, c: 2, d: 3] }
+
+    it "returns a key associated with the given value, if there is one" do
+      [:a, :b].include?(hash.key(1)).should == true
+      hash.key(2).should be(:c)
+      hash.key(3).should be(:d)
+    end
+
+    it "returns nil if there is no key associated with the given value" do
+      hash.key(5).should be_nil
+      hash.key(0).should be_nil
+    end
+
+    it "uses #== to compare values for equality" do
+      hash.key(EqualNotEql.new).should_not be_nil
+      hash.key(EqlNotEqual.new).should be_nil
+    end
+
+    it "doesn't use default block if value is not found" do
+      H.new(a: 1) { fail }.key(2).should be_nil
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/keys_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/keys_spec.rb
new file mode 100755
index 0000000..3fdb704
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/keys_spec.rb
@@ -0,0 +1,17 @@
+require "spec_helper"
+require "hamster/hash"
+require "hamster/set"
+
+describe Hamster::Hash do
+  describe "#keys" do
+    let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+
+    it "returns the keys as a set" do
+      hash.keys.should eql(S["A", "B", "C"])
+    end
+
+    it "returns frozen String keys" do
+      hash.keys.each { |s| s.should be_frozen }
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/map_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/map_spec.rb
new file mode 100755
index 0000000..83f0377
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/map_spec.rb
@@ -0,0 +1,46 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  [:map, :collect].each do |method|
+    describe "##{method}" do
+      context "when empty" do
+        it "returns self" do
+          H.empty.send(method) {}.should equal(H.empty)
+        end
+      end
+
+      context "when not empty" do
+        let(:hash) { H["A" => "aye", "B"  => "bee", "C" => "see"] }
+
+        context "with a block" do
+          let(:mapped) { hash.send(method) { |key, value| [key.downcase, value.upcase] }}
+
+          it "preserves the original values" do
+            mapped
+            hash.should eql(H["A" => "aye", "B"  => "bee", "C" => "see"])
+          end
+
+          it "returns a new hash with the mapped values" do
+            mapped.should eql(H["a" => "AYE", "b"  => "BEE", "c" => "SEE"])
+          end
+        end
+
+        context "with no block" do
+          it "returns an Enumerator" do
+            hash.send(method).class.should be(Enumerator)
+            hash.send(method).each { |k,v| [k.downcase, v] }.should == hash.map { |k,v| [k.downcase, v] }
+          end
+        end
+      end
+
+      context "from a subclass" do
+        it "returns an instance of the subclass" do
+          subclass = Class.new(Hamster::Hash)
+          instance = subclass.new('a' => 'aye', 'b' => 'bee')
+          instance.map { |k,v| [k, v.upcase] }.class.should be(subclass)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/marshal_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/marshal_spec.rb
new file mode 100755
index 0000000..fee09f6
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/marshal_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#marshal_dump/#marshal_load" do
+    let(:ruby) do
+      File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"])
+    end
+    let(:child_cmd) do
+      %Q|#{ruby} -I lib -r hamster -e 'dict = Hamster::Hash[existing_key: 42, other_thing: "data"]; $stdout.write(Marshal.dump(dict))'|
+    end
+
+    let(:reloaded_hash) do
+      IO.popen(child_cmd, "r+") do |child|
+        reloaded_hash = Marshal.load(child)
+        child.close
+        reloaded_hash
+      end
+    end
+
+    it "can survive dumping and loading into a new process" do
+      expect(reloaded_hash).to eql(H[existing_key: 42, other_thing: "data"])
+    end
+
+    it "is still possible to find items by key after loading" do
+      expect(reloaded_hash[:existing_key]).to eq(42)
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/merge_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/merge_spec.rb
new file mode 100755
index 0000000..a35ee1a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/merge_spec.rb
@@ -0,0 +1,83 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#merge" do
+    [
+      [{}, {}, {}],
+      [{"A" => "aye"}, {}, {"A" => "aye"}],
+      [{"A" => "aye"}, {"A" => "bee"}, {"A" => "bee"}],
+      [{"A" => "aye"}, {"B" => "bee"}, {"A" => "aye", "B" => "bee"}],
+      [(1..300).zip(1..300), (150..450).zip(150..450), (1..450).zip(1..450)]
+    ].each do |a, b, expected|
+      context "for #{a.inspect} and #{b.inspect}" do
+        let(:hash_a) { H[a] }
+        let(:hash_b) { H[b] }
+        let(:result) { hash_a.merge(hash_b) }
+
+        it "returns #{expected.inspect} when passed a Hamster::Hash"  do
+          result.should eql(H[expected])
+        end
+
+        it "returns #{expected.inspect} when passed a Ruby Hash" do
+          H[a].merge(::Hash[b]).should eql(H[expected])
+        end
+
+        it "doesn't change the original Hashes" do
+          result
+          hash_a.should eql(H[a])
+          hash_b.should eql(H[b])
+        end
+      end
+    end
+
+    context "when merging with an empty Hash" do
+      it "returns self" do
+        hash = H[a: 1, b: 2]
+        hash.merge(H.empty).should be(hash)
+      end
+    end
+
+    context "when merging with subset Hash" do
+      it "returns self" do
+        big_hash   = H[(1..300).zip(1..300)]
+        small_hash = H[(1..200).zip(1..200)]
+        big_hash.merge(small_hash).should be(big_hash)
+      end
+    end
+
+    context "when called on a subclass" do
+      it "returns an instance of the subclass" do
+        subclass = Class.new(Hamster::Hash)
+        instance = subclass.new(a: 1, b: 2)
+        instance.merge(c: 3, d: 4).class.should be(subclass)
+      end
+    end
+
+    it "sets any duplicate key to the value of block if passed a block" do
+      h1 = H[a: 2, b: 1, d: 5]
+      h2 = H[a: -2, b: 4, c: -3]
+      r = h1.merge(h2) { |k,x,y| nil }
+      r.should eql(H[a: nil, b: nil, c: -3, d: 5])
+
+      r = h1.merge(h2) { |k,x,y| "#{k}:#{x+2*y}" }
+      r.should eql(H[a: "a:-2", b: "b:9", c: -3, d: 5])
+
+      lambda {
+        h1.merge(h2) { |k, x, y| raise(IndexError) }
+      }.should raise_error(IndexError)
+
+      r = h1.merge(h1) { |k,x,y| :x }
+      r.should eql(H[a: :x, b: :x, d: :x])
+    end
+
+    it "yields key/value pairs in the same order as #each" do
+      hash = H[a: 1, b: 2, c: 3]
+      each_pairs = []
+      merge_pairs = []
+      hash.each { |k, v| each_pairs << [k, v] }
+      hash.merge(hash) { |k, v1, v2| merge_pairs << [k, v1] }
+      each_pairs.should == merge_pairs
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/min_max_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/min_max_spec.rb
new file mode 100755
index 0000000..7050a5b
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/min_max_spec.rb
@@ -0,0 +1,46 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  let(:hash) { H["a" => 3, "b" => 2, "c" => 1] }
+
+  describe "#min" do
+    it "returns the smallest key/val pair" do
+      hash.min.should == ["a", 3]
+    end
+  end
+
+  describe "#max" do
+    it "returns the largest key/val pair" do
+      hash.max.should == ["c", 1]
+    end
+  end
+
+  describe "#min_by" do
+    it "returns the smallest key/val pair (after passing it through a key function)" do
+      hash.min_by { |k,v| v }.should == ["c", 1]
+    end
+
+    it "returns the first key/val pair yielded by #each in case of a tie" do
+      hash.min_by { 0 }.should == hash.each.first
+    end
+
+    it "returns nil if the hash is empty" do
+      H.empty.min_by { |k,v| v }.should be_nil
+    end
+  end
+
+  describe "#max_by" do
+    it "returns the largest key/val pair (after passing it through a key function)" do
+      hash.max_by { |k,v| v }.should == ["a", 3]
+    end
+
+    it "returns the first key/val pair yielded by #each in case of a tie" do
+      hash.max_by { 0 }.should == hash.each.first
+    end
+
+    it "returns nil if the hash is empty" do
+      H.empty.max_by { |k,v| v }.should be_nil
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/new_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/new_spec.rb
new file mode 100755
index 0000000..feb64a2
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/new_spec.rb
@@ -0,0 +1,71 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe ".new" do
+    it "is amenable to overriding of #initialize" do
+      class SnazzyHash < Hamster::Hash
+        def initialize
+          super({'snazzy?' => 'oh yeah'})
+        end
+      end
+
+      SnazzyHash.new['snazzy?'].should == 'oh yeah'
+    end
+
+    context "from a subclass" do
+      it "returns a frozen instance of the subclass" do
+        subclass = Class.new(Hamster::Hash)
+        instance = subclass.new("some" => "values")
+        instance.class.should be(subclass)
+        instance.frozen?.should be true
+      end
+    end
+
+    it "accepts an array as initializer" do
+      H.new([['a', 'b'], ['c', 'd']]).should eql(H['a' => 'b', 'c' => 'd'])
+    end
+
+    it "returns a Hash which doesn't change even if initializer is mutated" do
+      rbhash = {a: 1, b: 2}
+      hash = H.new(rbhash)
+      rbhash[:a] = 'BAD'
+      hash.should eql(H[a: 1, b: 2])
+    end
+  end
+
+  describe ".[]" do
+    it "accepts a Ruby Hash as initializer" do
+      hash = H[a: 1, b: 2]
+      hash.class.should be(Hamster::Hash)
+      hash.size.should == 2
+      hash.key?(:a).should == true
+      hash.key?(:b).should == true
+    end
+
+    it "accepts a Hamster::Hash as initializer" do
+      hash = H[H.new(a: 1, b: 2)]
+      hash.class.should be(Hamster::Hash)
+      hash.size.should == 2
+      hash.key?(:a).should == true
+      hash.key?(:b).should == true
+    end
+
+    it "accepts an array as initializer" do
+      hash = H[[[:a, 1], [:b, 2]]]
+      hash.class.should be(Hamster::Hash)
+      hash.size.should == 2
+      hash.key?(:a).should == true
+      hash.key?(:b).should == true
+    end
+
+    it "can be used with a subclass of Hamster::Hash" do
+      subclass = Class.new(Hamster::Hash)
+      instance = subclass[a: 1, b: 2]
+      instance.class.should be(subclass)
+      instance.size.should == 2
+      instance.key?(:a).should == true
+      instance.key?(:b).should == true
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/none_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/none_spec.rb
new file mode 100755
index 0000000..77a5342
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/none_spec.rb
@@ -0,0 +1,49 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#none?" do
+    context "when empty" do
+      it "with a block returns true" do
+        H.empty.none? {}.should == true
+      end
+
+      it "with no block returns true" do
+        H.empty.none?.should == true
+      end
+    end
+
+    context "when not empty" do
+      let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see", nil => "NIL"] }
+
+      context "with a block" do
+        [
+          %w[A aye],
+          %w[B bee],
+          %w[C see],
+          [nil, "NIL"],
+        ].each do |pair|
+          it "returns false if the block ever returns true (#{pair.inspect})" do
+            hash.none? { |key, value| key == pair.first && value == pair.last }.should == false
+          end
+
+          it "returns true if the block always returns false" do
+            hash.none? { |key, value| key == "D" && value == "dee" }.should == true
+          end
+
+          it "stops iterating as soon as the block returns true" do
+            yielded = []
+            hash.none? { |k,v| yielded << k; true }
+            yielded.size.should == 1
+          end
+        end
+      end
+
+      context "with no block" do
+        it "returns false" do
+          hash.none?.should == false
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/partition_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/partition_spec.rb
new file mode 100755
index 0000000..66140be
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/partition_spec.rb
@@ -0,0 +1,36 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  let(:hash) { H["a" => 1, "b" => 2, "c" => 3, "d" => 4] }
+  let(:partition) { hash.partition { |k,v| v % 2 == 0 }}
+
+  describe "#partition" do
+    it "returns a pair of Hamster::Hashes" do
+      partition.each { |h| h.class.should be(Hamster::Hash) }
+      partition.should be_frozen
+    end
+
+    it "returns key/val pairs for which predicate is true in first Hash" do
+      partition[0].should == {"b" => 2, "d" => 4}
+    end
+
+    it "returns key/val pairs for which predicate is false in second Hash" do
+      partition[1].should == {"a" => 1, "c" => 3}
+    end
+
+    it "doesn't modify the original Hash" do
+      partition
+      hash.should eql(H["a" => 1, "b" => 2, "c" => 3, "d" => 4])
+    end
+
+    context "from a subclass" do
+      it "should return instances of the subclass" do
+        subclass  = Class.new(Hamster::Hash)
+        instance  = subclass.new("a" => 1, "b" => 2, "c" => 3, "d" => 4)
+        partition = instance.partition { |k,v| v % 2 == 0 }
+        partition.each { |h| h.class.should be(subclass) }
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/pretty_print_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/pretty_print_spec.rb
new file mode 100755
index 0000000..7893201
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/pretty_print_spec.rb
@@ -0,0 +1,35 @@
+require "spec_helper"
+require "hamster/hash"
+require "pp"
+require "stringio"
+
+describe Hamster::Hash do
+  describe "#pretty_print" do
+    let(:hash) { Hamster::Hash.new(DeterministicHash.new(1,1) => "tin", DeterministicHash.new(2,2) => "earwax", DeterministicHash.new(3,3) => "neanderthal") }
+    let(:stringio) { StringIO.new }
+
+
+    it "prints the whole Hash on one line if it fits" do
+      PP.pp(hash, stringio, 80)
+      stringio.string.chomp.should == 'Hamster::Hash[1 => "tin", 2 => "earwax", 3 => "neanderthal"]'
+    end
+
+    it "prints each key/val pair on its own line, if not" do
+      PP.pp(hash, stringio, 20)
+      stringio.string.chomp.should == 'Hamster::Hash[
+ 1 => "tin",
+ 2 => "earwax",
+ 3 => "neanderthal"]'
+    end
+
+    it "prints keys and vals on separate lines, if space is very tight" do
+      PP.pp(hash, stringio, 15)
+      # the trailing space after "3 =>" below is needed, don't remove it
+      stringio.string.chomp.should == 'Hamster::Hash[
+ 1 => "tin",
+ 2 => "earwax",
+ 3 => 
+  "neanderthal"]'
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/put_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/put_spec.rb
new file mode 100755
index 0000000..e2100b2
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/put_spec.rb
@@ -0,0 +1,103 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#put" do
+    let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+
+    context "with a block" do
+      it "passes the value to the block" do
+        hash.put("A") { |value| value.should == "aye" }
+      end
+
+      it "replaces the value with the result of the block" do
+        result = hash.put("A") { |value| "FLIBBLE" }
+        result.get("A").should == "FLIBBLE"
+      end
+
+      it "supports to_proc methods" do
+        result = hash.put("A", &:upcase)
+        result.get("A").should == "AYE"
+      end
+
+      context "if there is no existing association" do
+        it "passes nil to the block" do
+          hash.put("D") { |value| value.should be_nil }
+        end
+
+        it "stores the result of the block as the new value" do
+          result = hash.put("D") { |value| "FLIBBLE" }
+          result.get("D").should == "FLIBBLE"
+        end
+      end
+    end
+
+    context "with a unique key" do
+      let(:result) { hash.put("D", "dee") }
+
+      it "preserves the original" do
+        result
+        hash.should eql(H["A" => "aye", "B" => "bee", "C" => "see"])
+      end
+
+      it "returns a copy with the superset of key/value pairs" do
+        result.should eql(H["A" => "aye", "B" => "bee", "C" => "see", "D" => "dee"])
+      end
+    end
+
+    context "with a duplicate key" do
+      let(:result) { hash.put("C", "sea") }
+
+      it "preserves the original" do
+        result
+        hash.should eql(H["A" => "aye", "B" => "bee", "C" => "see"])
+      end
+
+      it "returns a copy with the superset of key/value pairs" do
+        result.should eql(H["A" => "aye", "B" => "bee", "C" => "sea"])
+      end
+    end
+
+    context "with duplicate key and identical value" do
+      let(:hash) { H["X" => 1, "Y" => 2] }
+      let(:result) { hash.put("X", 1) }
+
+      it "returns the original hash unmodified" do
+        result.should be(hash)
+      end
+
+      context "with big hash (force nested tries)" do
+        let(:keys) { (0..99).map(&:to_s) }
+        let(:values) { (100..199).to_a }
+        let(:hash) { H[keys.zip(values)] }
+
+        it "returns the original hash unmodified for all changes" do
+          keys.each_with_index do |key, index|
+            result = hash.put(key, values[index])
+            result.should be(hash)
+          end
+        end
+      end
+    end
+
+    context "with unequal keys which hash to the same value" do
+      let(:hash) { H[DeterministicHash.new('a', 1) => 'aye'] }
+
+      it "stores and can retrieve both" do
+        result = hash.put(DeterministicHash.new('b', 1), 'bee')
+        result.get(DeterministicHash.new('a', 1)).should eql('aye')
+        result.get(DeterministicHash.new('b', 1)).should eql('bee')
+      end
+    end
+
+    context "when a String is inserted as key and then mutated" do
+      it "is not affected" do
+        string = "a string!"
+        hash = H.empty.put(string, 'a value!')
+        string.upcase!
+        hash['a string!'].should == 'a value!'
+        hash['A STRING!'].should be_nil
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/reduce_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/reduce_spec.rb
new file mode 100755
index 0000000..b9300b1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/reduce_spec.rb
@@ -0,0 +1,36 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  [:reduce, :inject].each do |method|
+    describe "##{method}" do
+      context "when empty" do
+        it "returns the memo" do
+          H.empty.send(method, "ABC") {}.should == "ABC"
+        end
+      end
+
+      context "when not empty" do
+        let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+
+        context "with a block" do
+          it "returns the final memo" do
+            hash.send(method, 0) { |memo, key, value| memo + 1 }.should == 3
+          end
+        end
+
+        context "with no block" do
+          let(:hash) { H[a: 1, b: 2] }
+
+          it "uses a passed string as the name of a method to use instead" do
+            [[:a, 1, :b, 2], [:b, 2, :a, 1]].include?(hash.send(method, "+")).should == true
+          end
+
+          it "uses a passed symbol as the name of a method to use instead" do
+            [[:a, 1, :b, 2], [:b, 2, :a, 1]].include?(hash.send(method, :+)).should == true
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/reject_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/reject_spec.rb
new file mode 100755
index 0000000..e603a3f
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/reject_spec.rb
@@ -0,0 +1,62 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  [:reject, :delete_if].each do |method|
+    describe "##{method}" do
+      let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+
+      context "when nothing matches" do
+        it "returns self" do
+          hash.send(method) { |key, value| false }.should equal(hash)
+        end
+      end
+
+      context "when only some things match" do
+        context "with a block" do
+          let(:result) { hash.send(method) { |key, value| key == "A" && value == "aye" }}
+
+          it "preserves the original" do
+            result
+            hash.should eql(H["A" => "aye", "B" => "bee", "C" => "see"])
+          end
+
+          it "returns a set with the matching values" do
+            result.should eql(H["B" => "bee", "C" => "see"])
+          end
+
+          it "yields entries in the same order as #each" do
+            each_pairs = []
+            remove_pairs = []
+            hash.each_pair { |k,v| each_pairs << [k,v] }
+            hash.send(method) { |k,v| remove_pairs << [k,v] }
+            each_pairs.should == remove_pairs
+          end
+        end
+
+        context "with no block" do
+          it "returns an Enumerator" do
+            hash.send(method).class.should be(Enumerator)
+            hash.send(method).to_a.sort.should == [['A', 'aye'], ['B', 'bee'], ['C', 'see']]
+            hash.send(method).each { true }.should eql(H.empty)
+          end
+        end
+
+        context "on a large hash, with many combinations of input" do
+          it "still works" do
+            array = 1000.times.collect { |n| [n, n] }
+            hash  = H.new(array)
+            [0, 10, 100, 200, 500, 800, 900, 999, 1000].each do |threshold|
+              result = hash.send(method) { |k,v| k >= threshold}
+              result.size.should == threshold
+              0.upto(threshold-1) { |n| result.key?(n).should == true }
+              threshold.upto(1000) { |n| result.key?(n).should == false }
+            end
+            # shouldn't have changed
+            hash.should eql(H.new(1000.times.collect { |n| [n, n] }))
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/reverse_each_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/reverse_each_spec.rb
new file mode 100755
index 0000000..1dde0bc
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/reverse_each_spec.rb
@@ -0,0 +1,28 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+
+  describe "#reverse_each" do
+    context "with a block" do
+      it "returns self" do
+        hash.reverse_each {}.should be(hash)
+      end
+
+      it "yields all key/value pairs in the opposite order as #each" do
+        result = []
+        hash.reverse_each { |entry| result << entry }
+        result.should eql(hash.to_a.reverse)
+      end
+    end
+
+    context "with no block" do
+      it "returns an Enumerator" do
+        result = hash.reverse_each
+        result.class.should be(Enumerator)
+        result.to_a.should eql(hash.to_a.reverse)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/sample_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/sample_spec.rb
new file mode 100755
index 0000000..a77b5c3
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/sample_spec.rb
@@ -0,0 +1,14 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#sample" do
+    let(:hash) { Hamster::Hash.new((:a..:z).zip(1..26)) }
+
+    it "returns a randomly chosen item" do
+      chosen = 250.times.map { hash.sample }.sort.uniq
+      chosen.each { |item| hash.include?(item[0]).should == true }
+      hash.each { |item| chosen.include?(item).should == true }
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/select_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/select_spec.rb
new file mode 100755
index 0000000..cb5827d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/select_spec.rb
@@ -0,0 +1,58 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  [:select, :find_all, :keep_if].each do |method|
+    describe "##{method}" do
+      let(:original) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+
+      context "when everything matches" do
+        it "returns self" do
+          original.send(method) { |key, value| true }.should equal(original)
+        end
+      end
+
+      context "when only some things match" do
+        context "with a block" do
+          let(:result) { original.send(method) { |key, value| key == "A" && value == "aye" }}
+
+          it "preserves the original" do
+            original.should eql(H["A" => "aye", "B" => "bee", "C" => "see"])
+          end
+
+          it "returns a set with the matching values" do
+            result.should eql(H["A" => "aye"])
+          end
+        end
+
+        it "yields entries as [key, value] pairs" do
+          original.send(method) do |e|
+            e.should be_kind_of(Array)
+            ["A", "B", "C"].include?(e[0]).should == true
+            ["aye", "bee", "see"].include?(e[1]).should == true
+          end
+        end
+
+        context "with no block" do
+          it "returns an Enumerator" do
+            original.send(method).class.should be(Enumerator)
+            original.send(method).to_a.sort.should == [['A', 'aye'], ['B', 'bee'], ['C', 'see']]
+          end
+        end
+      end
+
+      it "works on a large hash, with many combinations of input" do
+        keys = (1..1000).to_a
+        original = H.new(keys.zip(2..1001))
+        25.times do
+          threshold = rand(1000)
+          result    = original.send(method) { |k,v| k <= threshold }
+          result.size.should == threshold
+          result.each_key { |k| k.should <= threshold }
+          (threshold+1).upto(1000) { |k| result.key?(k).should == false }
+        end
+        original.should eql(H.new(keys.zip(2..1001))) # shouldn't have changed
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/size_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/size_spec.rb
new file mode 100755
index 0000000..e65d2ae
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/size_spec.rb
@@ -0,0 +1,52 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  [:size, :length].each do |method|
+    describe "##{method}" do
+      [
+        [[], 0],
+        [["A" => "aye"], 1],
+        [["A" => "bee", "B" => "bee", "C" => "see"], 3],
+      ].each do |values, result|
+
+        it "returns #{result} for #{values.inspect}" do
+          H[*values].send(method).should == result
+        end
+      end
+
+      lots = (1..10_842).to_a
+      srand 89_533_474
+      random_things = (lots + lots).sort_by { |x|rand }
+
+      it "has the correct size after adding lots of things with colliding keys and such" do
+        h = H.empty
+        random_things.each do |thing|
+          h = h.put(thing, thing * 2)
+        end
+        h.size.should == 10_842
+      end
+
+      random_actions = (lots.map { |x|[:add, x] } + lots.map { |x|[:add, x] } + lots.map { |x|[:remove, x] }).sort_by { |x|rand }
+      ending_size = random_actions.reduce({}) do |h, (act, ob)|
+        if act == :add
+          h[ob] = 1
+        else
+          h.delete(ob)
+        end
+        h
+      end.size
+      it "has the correct size after lots of addings and removings" do
+        h = H.empty
+        random_actions.each do |(act, ob)|
+          if act == :add
+            h = h.put(ob, ob * 3)
+          else
+            h = h.delete(ob)
+          end
+        end
+        h.size.should == ending_size
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/slice_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/slice_spec.rb
new file mode 100755
index 0000000..69b9df8
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/slice_spec.rb
@@ -0,0 +1,45 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  let(:hash) { H.new("A" => "aye", "B" => "bee", "C" => "see", nil => "NIL") }
+
+  describe "#slice" do
+    let(:slice) { hash.slice(*values) }
+
+    context "with all keys present in the Hash" do
+      let(:values) { ["B", nil] }
+
+      it "returns the sliced values" do
+        expect(slice).to eq(described_class.new("B" => "bee", nil => "NIL"))
+      end
+
+      it "doesn't modify the original Hash" do
+        slice
+        hash.should eql(H.new("A" => "aye", "B" => "bee", "C" => "see", nil => "NIL"))
+      end
+    end
+
+    context "with keys aren't present in the Hash" do
+      let(:values) { ["B", "A", 3] }
+
+      it "returns the sliced values of the matching keys" do
+        expect(slice).to eq(described_class.new("A" => "aye", "B" => "bee"))
+      end
+
+      it "doesn't modify the original Hash" do
+        slice
+        hash.should eql(H.new("A" => "aye", "B" => "bee", "C" => "see", nil => "NIL"))
+      end
+    end
+
+    context "on a Hash with a default block" do
+      let(:hash) { H.new('A' => 'aye', 'B' => 'bee') { 'nothing' }}
+      let(:values) { ["B", nil] }
+
+      it "maintains the default block" do
+        expect(slice['C']).to eq('nothing')
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/sort_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/sort_spec.rb
new file mode 100755
index 0000000..57842d3
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/sort_spec.rb
@@ -0,0 +1,27 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  let(:hash) { H[a: 3, b: 2, c: 1] }
+
+  describe "#sort" do
+    it "returns a Vector of sorted key/val pairs" do
+      hash.sort.should eql(V[[:a, 3], [:b, 2], [:c, 1]])
+    end
+
+    it "works on large hashes" do
+      array = (1..1000).map { |n| [n,n] }
+      H.new(array.shuffle).sort.should eql(V.new(array))
+    end
+
+    it "uses block as comparator to sort if passed a block" do
+      hash.sort { |a,b| b <=> a }.should eql(V[[:c, 1], [:b, 2], [:a, 3]])
+    end
+  end
+
+  describe "#sort_by" do
+    it "returns a Vector of key/val pairs, sorted using the block as a key function" do
+      hash.sort_by { |k,v| v }.should eql(V[[:c, 1], [:b, 2], [:a, 3]])
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/store_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/store_spec.rb
new file mode 100755
index 0000000..9586110
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/store_spec.rb
@@ -0,0 +1,76 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#store" do
+    let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+
+    context "with a unique key" do
+      let(:result) { hash.store("D", "dee") }
+
+      it "preserves the original" do
+        result
+        hash.should eql(H["A" => "aye", "B" => "bee", "C" => "see"])
+      end
+
+      it "returns a copy with the superset of key/value pairs" do
+        result.should eql(H["A" => "aye", "B" => "bee", "C" => "see", "D" => "dee"])
+      end
+    end
+
+    context "with a duplicate key" do
+      let(:result) { hash.store("C", "sea") }
+
+      it "preserves the original" do
+        result
+        hash.should eql(H["A" => "aye", "B" => "bee", "C" => "see"])
+      end
+
+      it "returns a copy with the superset of key/value pairs" do
+        result.should eql(H["A" => "aye", "B" => "bee", "C" => "sea"])
+      end
+    end
+
+    context "with duplicate key and identical value" do
+      let(:hash) { H["X" => 1, "Y" => 2] }
+      let(:result) { hash.store("X", 1) }
+
+      it "returns the original hash unmodified" do
+        result.should be(hash)
+      end
+
+      context "with big hash (force nested tries)" do
+        let(:keys) { (0..99).map(&:to_s) }
+        let(:values) { (100..199).to_a }
+        let(:hash) { H[keys.zip(values)] }
+
+        it "returns the original hash unmodified for all changes" do
+          keys.each_with_index do |key, index|
+            result = hash.store(key, values[index])
+            result.should be(hash)
+          end
+        end
+      end
+    end
+
+    context "with unequal keys which hash to the same value" do
+      let(:hash) { H[DeterministicHash.new('a', 1) => 'aye'] }
+
+      it "stores and can retrieve both" do
+        result = hash.store(DeterministicHash.new('b', 1), 'bee')
+        result.get(DeterministicHash.new('a', 1)).should eql('aye')
+        result.get(DeterministicHash.new('b', 1)).should eql('bee')
+      end
+    end
+
+    context "when a String is inserted as key and then mutated" do
+      it "is not affected" do
+        string = "a string!"
+        hash = H.empty.store(string, 'a value!')
+        string.upcase!
+        hash['a string!'].should == 'a value!'
+        hash['A STRING!'].should be_nil
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/subset_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/subset_spec.rb
new file mode 100755
index 0000000..499895c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/subset_spec.rb
@@ -0,0 +1,42 @@
+require "spec_helper"
+require "hamster/hash"
+
+RSpec.describe Hamster::Hash do
+  describe "#<=" do
+    [
+      [{}, {}, true],
+      [{"A" => 1}, {}, false],
+      [{}, {"A" => 1}, true],
+      [{"A" => 1}, {"A" => 1}, true],
+      [{"A" => 1}, {"A" => 2}, false],
+      [{"B" => 2}, {"A" => 1, "B" => 2, "C" => 3}, true],
+      [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 2}, false],
+      [{"B" => 0}, {"A" => 1, "B" => 2, "C" => 3}, false],
+    ].each do |a, b, expected|
+      describe "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}"  do
+          expect(H[a] <= H[b]).to eq(expected)
+        end
+      end
+    end
+  end
+
+  describe "#<" do
+    [
+      [{}, {}, false],
+      [{"A" => 1}, {}, false],
+      [{}, {"A" => 1}, true],
+      [{"A" => 1}, {"A" => 1}, false],
+      [{"A" => 1}, {"A" => 2}, false],
+      [{"B" => 2}, {"A" => 1, "B" => 2, "C" => 3}, true],
+      [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 2}, false],
+      [{"B" => 0}, {"A" => 1, "B" => 2, "C" => 3}, false],
+    ].each do |a, b, expected|
+      describe "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}"  do
+          expect(H[a] < H[b]).to eq(expected)
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/superset_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/superset_spec.rb
new file mode 100755
index 0000000..8ed749a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/superset_spec.rb
@@ -0,0 +1,42 @@
+require "spec_helper"
+require "hamster/hash"
+
+RSpec.describe Hamster::Hash do
+  describe "#>=" do
+    [
+      [{}, {}, true],
+      [{"A" => 1}, {}, true],
+      [{}, {"A" => 1}, false],
+      [{"A" => 1}, {"A" => 1}, true],
+      [{"A" => 1}, {"A" => 2}, false],
+      [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 2}, true],
+      [{"B" => 2}, {"A" => 1, "B" => 2, "C" => 3}, false],
+      [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 0}, false],
+    ].each do |a, b, expected|
+      describe "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}"  do
+          expect(H[a] >= H[b]).to eq(expected)
+        end
+      end
+    end
+  end
+
+  describe "#>" do
+    [
+      [{}, {}, false],
+      [{"A" => 1}, {}, true],
+      [{}, {"A" => 1}, false],
+      [{"A" => 1}, {"A" => 1}, false],
+      [{"A" => 1}, {"A" => 2}, false],
+      [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 2}, true],
+      [{"B" => 2}, {"A" => 1, "B" => 2, "C" => 3}, false],
+      [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 0}, false],
+    ].each do |a, b, expected|
+      describe "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}"  do
+          expect(H[a] > H[b]).to eq(expected)
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/take_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/take_spec.rb
new file mode 100755
index 0000000..504f62e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/take_spec.rb
@@ -0,0 +1,36 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+
+  describe "#take" do
+    it "returns the first N key/val pairs from hash" do
+      hash.take(0).should == []
+      [[['A', 'aye']], [['B', 'bee']], [['C', 'see']]].include?(hash.take(1)).should == true
+      [['A', 'aye'], ['B', 'bee'], ['C', 'see']].combination(2).include?(hash.take(2).sort).should == true
+      hash.take(3).sort.should == [['A', 'aye'], ['B', 'bee'], ['C', 'see']]
+      hash.take(4).sort.should == [['A', 'aye'], ['B', 'bee'], ['C', 'see']]
+    end
+  end
+
+  describe "#take_while" do
+    it "passes elements to the block until the block returns nil/false" do
+      passed = nil
+      hash.take_while { |k,v| passed = k; false }
+      ['A', 'B', 'C'].include?(passed).should == true
+    end
+
+    it "returns an array of all elements before the one which returned nil/false" do
+      count = 0
+      result = hash.take_while { count += 1; count < 3 }
+      [['A', 'aye'], ['B', 'bee'], ['C', 'see']].combination(2).include?(result.sort).should == true
+    end
+
+    it "passes all elements if the block never returns nil/false" do
+      passed = []
+      hash.take_while { |k,v| passed << [k, v]; true }.should == hash.to_a
+      passed.sort.should == [['A', 'aye'], ['B', 'bee'], ['C', 'see']]
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/to_a_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/to_a_spec.rb
new file mode 100755
index 0000000..19239d9
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/to_a_spec.rb
@@ -0,0 +1,14 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#to_a" do
+    it "returns an Array of [key, value] pairs in same order as #each" do
+      hash = H[:a => 1, 1 => :a, 3 => :b, :b => 5]
+      pairs = []
+      hash.each_pair { |k,v| pairs << [k,v] }
+      hash.to_a.should be_kind_of(Array)
+      hash.to_a.should == pairs
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/to_hash_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/to_hash_spec.rb
new file mode 100755
index 0000000..db4a8cb
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/to_hash_spec.rb
@@ -0,0 +1,22 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  [:to_hash, :to_h].each do |method|
+    describe "##{method}" do
+      it "converts an empty Hamster::Hash to an empty Ruby Hash" do
+        H.empty.send(method).should eql({})
+      end
+
+      it "converts a non-empty Hamster::Hash to a Hash with the same keys and values" do
+        H[a: 1, b: 2].send(method).should eql({a: 1, b: 2})
+      end
+
+      it "doesn't modify the receiver" do
+        hash = H[a: 1, b: 2]
+        hash.send(method)
+        hash.should eql(H[a: 1, b: 2])
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/to_proc_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/to_proc_spec.rb
new file mode 100755
index 0000000..60acce4
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/to_proc_spec.rb
@@ -0,0 +1,39 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#to_proc" do
+    context "on Hash without default proc" do
+      let(:hash) { H.new("A" => "aye") }
+
+      it "returns a Proc instance" do
+        hash.to_proc.should be_kind_of(Proc)
+      end
+
+      it "returns a Proc that returns the value of an existing key" do
+        hash.to_proc.call("A").should == "aye"
+      end
+
+      it "returns a Proc that returns nil for a missing key" do
+        hash.to_proc.call("B").should be_nil
+      end
+    end
+
+    context "on Hash with a default proc" do
+      let(:hash) { H.new("A" => "aye") { |key| "#{key}-VAL" } }
+
+      it "returns a Proc instance" do
+        hash.to_proc.should be_kind_of(Proc)
+      end
+
+      it "returns a Proc that returns the value of an existing key" do
+        hash.to_proc.call("A").should == "aye"
+      end
+
+      it "returns a Proc that returns the result of the hash's default proc for a missing key" do
+        hash.to_proc.call("B").should == "B-VAL"
+        hash.should == H.new("A" => "aye")
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/values_at_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/values_at_spec.rb
new file mode 100755
index 0000000..5aee316
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/values_at_spec.rb
@@ -0,0 +1,34 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#values_at" do
+    context "on Hash without default proc" do
+      let(:hash) { H[:a => 9, :b => 'a', :c => -10, :d => nil] }
+
+      it "returns an empty vector when no keys are given" do
+        hash.values_at.should be_kind_of(Hamster::Vector)
+        hash.values_at.should eql(V.empty)
+      end
+
+      it "returns a vector of values for the given keys" do
+        hash.values_at(:a, :d, :b).should be_kind_of(Hamster::Vector)
+        hash.values_at(:a, :d, :b).should eql(V[9, nil, 'a'])
+      end
+
+      it "fills nil when keys are missing" do
+        hash.values_at(:x, :a, :y, :b).should be_kind_of(Hamster::Vector)
+        hash.values_at(:x, :a, :y, :b).should eql(V[nil, 9, nil, 'a'])
+      end
+    end
+
+    context "on Hash with default proc" do
+      let(:hash) { Hamster::Hash.new(:a => 9) { |key| "#{key}-VAL" } }
+
+      it "fills the result of the default proc when keys are missing" do
+        hash.values_at(:x, :a, :y).should be_kind_of(Hamster::Vector)
+        hash.values_at(:x, :a, :y).should eql(V['x-VAL', 9, 'y-VAL'])
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/values_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/values_spec.rb
new file mode 100755
index 0000000..e5df9c3
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/hash/values_spec.rb
@@ -0,0 +1,25 @@
+require "spec_helper"
+require "hamster/hash"
+require "hamster/set"
+
+describe Hamster::Hash do
+  describe "#values" do
+    let(:hash) { H["A" => "aye", "B" => "bee", "C" => "see"] }
+    let(:result) { hash.values }
+
+    it "returns the keys as a Vector" do
+      result.should be_a Hamster::Vector
+      result.to_a.sort.should == %w(aye bee see)
+    end
+
+    context "with duplicates" do
+      let(:hash) { H[:A => 15, :B => 19, :C => 15] }
+      let(:result) { hash.values }
+
+      it "returns the keys as a Vector" do
+        result.class.should be(Hamster::Vector)
+        result.to_a.sort.should == [15, 15, 19]
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/copying_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/copying_spec.rb
new file mode 100755
index 0000000..db62b30
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/copying_spec.rb
@@ -0,0 +1,21 @@
+require "spec_helper"
+require "hamster/immutable"
+
+describe Hamster::Immutable do
+  class Fixture
+    include Hamster::Immutable
+  end
+
+  [:dup, :clone].each do |method|
+    describe "##{method}" do
+      before do
+        @original = Fixture.new
+        @result = @original.send(method)
+      end
+
+      it "returns self" do
+        @result.should equal(@original)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/immutable_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/immutable_spec.rb
new file mode 100755
index 0000000..68e4f0d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/immutable_spec.rb
@@ -0,0 +1,45 @@
+require "spec_helper"
+require "hamster/immutable"
+
+describe Hamster::Immutable do
+  describe "#immutable?" do
+    describe "object constructed after its class becomes Immutable" do
+      class Fixture
+        include Hamster::Immutable
+      end
+
+      before do
+        @fixture = Fixture.new
+      end
+
+      it "returns true" do
+        @fixture.should be_immutable
+      end
+    end
+
+    describe "object constructed before its class becomes Immutable" do
+      before do
+        @fixture = Class.new.new
+        @fixture.class.instance_eval do
+          include Hamster::Immutable
+        end
+      end
+
+      describe "that are not frozen" do
+        it "returns false" do
+          @fixture.should_not be_immutable
+        end
+      end
+
+      describe "that are frozen" do
+        before do
+          @fixture.freeze
+        end
+
+        it "returns true" do
+          @fixture.should be_immutable
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/memoize_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/memoize_spec.rb
new file mode 100755
index 0000000..d8cd9c1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/memoize_spec.rb
@@ -0,0 +1,56 @@
+require "spec_helper"
+require "hamster/immutable"
+
+describe Hamster::Immutable do
+  class Fixture
+    include Hamster::Immutable
+
+    def initialize(&block)
+      @block = block
+    end
+
+    def call
+      @block.call
+    end
+    memoize :call
+
+    def copy
+      transform {}
+    end
+  end
+
+  let(:immutable) { Fixture.new { @count += 1 } }
+
+  describe "#memoize" do
+    before(:each) do
+      @count = 0
+      immutable.call
+    end
+
+    it "keeps the receiver frozen and immutable" do
+      expect(immutable).to be_immutable
+    end
+
+    context "when called multiple times" do
+      before(:each) do
+        immutable.call
+      end
+
+      it "doesn't evaluate the memoized method more than once" do
+        expect(@count).to eq(1)
+      end
+    end
+
+    describe "when making a copy" do
+      let(:copy) { immutable.copy }
+
+      before(:each) do
+        copy.call
+      end
+
+      it "clears all memory" do
+        expect(@count).to eq(2)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/new_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/new_spec.rb
new file mode 100755
index 0000000..75a9cf8
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/new_spec.rb
@@ -0,0 +1,28 @@
+require "spec_helper"
+require "hamster/immutable"
+
+describe Hamster::Immutable do
+  class NewPerson < Struct.new(:first, :last)
+    include Hamster::Immutable
+  end
+
+  let(:immutable) { NewPerson.new("Simon", "Harris") }
+
+  it "freezes the instance" do
+    expect(immutable).to be_frozen
+  end
+
+  context "subclass hides all public methods" do
+    it "freezes the instance" do
+      my_class = Class.new do
+        include Hamster::Immutable
+
+        (public_instance_methods - Object.public_instance_methods).each do |m|
+          protected m
+        end
+      end
+      immutable = my_class.new
+      expect(immutable).to be_frozen
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/transform_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/transform_spec.rb
new file mode 100755
index 0000000..b7a2a9c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/transform_spec.rb
@@ -0,0 +1,26 @@
+require "spec_helper"
+require "hamster/immutable"
+
+describe Hamster::Immutable do
+  class TransformPerson < Struct.new(:first, :last)
+    include Hamster::Immutable
+
+    public :transform
+  end
+
+  let(:immutable) { TransformPerson.new("Simon", "Harris") }
+
+  describe "#transform" do
+    let(:transform) { immutable.transform { self.first = "Sampy" } }
+    let(:original) { immutable.first }
+    let(:modified) { transform.first }
+
+    it "preserves the original" do
+      expect(original).to eq("Simon")
+    end
+
+    it "returns a new instance with the updated values" do
+      expect(modified).to eq("Sampy")
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/transform_unless_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/transform_unless_spec.rb
new file mode 100755
index 0000000..66ec4cb
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/immutable/transform_unless_spec.rb
@@ -0,0 +1,44 @@
+require "spec_helper"
+require "hamster/immutable"
+
+describe Hamster::Immutable do
+  class TransformUnlessPerson < Struct.new(:first, :last)
+    include Hamster::Immutable
+
+    public :transform_unless
+  end
+
+  let(:immutable) { TransformUnlessPerson.new("Simon", "Harris") }
+
+  describe "#transform_unless" do
+    let(:transform_unless) { immutable.transform_unless(condition, &block) }
+    let(:original) { immutable.first }
+    let(:modified) { transform_unless.first }
+
+    context "when the condition is false" do
+      let(:condition) { false }
+      let(:block) { ->(thing) { self.first = "Sampy" } }
+
+      it "preserves the original" do
+        expect(original).to eq("Simon")
+      end
+
+      it "returns a new instance with the updated values" do
+        expect(modified).to eq("Sampy")
+      end
+    end
+
+    context "when the condition is true" do
+      let(:condition) { true }
+      let(:block) { -> { fail("Should never be called") } }
+
+      it "preserves the original" do
+        expect(original).to eq("Simon")
+      end
+
+      it "returns the original" do
+        expect(original).to eq(modified)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/add_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/add_spec.rb
new file mode 100755
index 0000000..14fd3f9
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/add_spec.rb
@@ -0,0 +1,26 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#add" do
+    [
+      [[], "A", ["A"]],
+      [["A"], "B", %w[B A]],
+      [["A"], "A", %w[A A]],
+      [%w[A B C], "D", %w[D A B C]],
+    ].each do |values, new_value, expected|
+      context "on #{values.inspect} with #{new_value.inspect}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.add(new_value)
+          list.should eql(L[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          list.add(new_value).should eql(L[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/all_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/all_spec.rb
new file mode 100755
index 0000000..d5e815f
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/all_spec.rb
@@ -0,0 +1,58 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#all?" do
+    context "on a really big list" do
+      let(:list) { Hamster.interval(0, STACK_OVERFLOW_DEPTH) }
+
+      it "doesn't run out of stack" do
+        -> { list.all? }.should_not raise_error
+      end
+    end
+
+    context "when empty" do
+      it "with a block returns true" do
+        L.empty.all? {}.should == true
+      end
+
+      it "with no block returns true" do
+        L.empty.all?.should == true
+      end
+    end
+
+    context "when not empty" do
+      context "with a block" do
+        let(:list) { L["A", "B", "C"] }
+
+        context "if the block always returns true" do
+          it "returns true" do
+            list.all? { |item| true }.should == true
+          end
+        end
+
+        context "if the block ever returns false" do
+          it "returns false" do
+            list.all? { |item| item == "D" }.should == false
+          end
+        end
+      end
+
+      context "with no block" do
+        context "if all values are truthy" do
+          it "returns true" do
+            L[true, "A"].all?.should == true
+          end
+        end
+
+        [nil, false].each do |value|
+          context "if any value is #{value.inspect}" do
+            it "returns false" do
+              L[value, true, "A"].all?.should == false
+            end
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/any_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/any_spec.rb
new file mode 100755
index 0000000..e7d6c14
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/any_spec.rb
@@ -0,0 +1,50 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#any?" do
+    context "on a really big list" do
+      let(:list) { Hamster.interval(0, STACK_OVERFLOW_DEPTH) }
+
+      it "doesn't run out of stack" do
+        -> { list.any? { false } }.should_not raise_error
+      end
+    end
+
+    context "when empty" do
+      it "with a block returns false" do
+       L.empty.any? {}.should == false
+      end
+
+      it "with no block returns false" do
+        L.empty.any?.should == false
+      end
+    end
+
+    context "when not empty" do
+      context "with a block" do
+        let(:list) { L["A", "B", "C", nil] }
+
+        ["A", "B", "C", nil].each do |value|
+          it "returns true if the block ever returns true (#{value.inspect})" do
+            list.any? { |item| item == value }.should == true
+          end
+        end
+
+        it "returns false if the block always returns false" do
+          list.any? { |item| item == "D" }.should == false
+        end
+      end
+
+      context "with no block" do
+        it "returns true if any value is truthy" do
+          L[nil, false, "A", true].any?.should == true
+        end
+
+        it "returns false if all values are falsey" do
+          L[nil, false].any?.should == false
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/append_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/append_spec.rb
new file mode 100755
index 0000000..f81bc12
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/append_spec.rb
@@ -0,0 +1,39 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [:append, :concat, :+].each do |method|
+    describe "##{method}" do
+      it "is lazy" do
+        -> { Hamster.stream { fail }.append(Hamster.stream { fail }) }.should_not raise_error
+      end
+
+      [
+        [[], [], []],
+        [["A"], [], ["A"]],
+        [[], ["A"], ["A"]],
+        [%w[A B], %w[C D], %w[A B C D]],
+      ].each do |left_values, right_values, expected|
+        context "on #{left_values.inspect} and #{right_values.inspect}" do
+          let(:left) { L[*left_values] }
+          let(:right) { L[*right_values] }
+          let(:result) { left.append(right) }
+
+          it "preserves the left" do
+            result
+            left.should eql(L[*left_values])
+          end
+
+          it "preserves the right" do
+            result
+            right.should eql(L[*right_values])
+          end
+
+          it "returns #{expected.inspect}" do
+            result.should eql(L[*expected])
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/at_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/at_spec.rb
new file mode 100755
index 0000000..f8209dd
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/at_spec.rb
@@ -0,0 +1,30 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#at" do
+    context "on a really big list" do
+      let(:list) { Hamster.interval(0, STACK_OVERFLOW_DEPTH) }
+
+      it "doesn't run out of stack" do
+        -> { list.at(STACK_OVERFLOW_DEPTH) }.should_not raise_error
+      end
+    end
+
+    [
+      [[], 10, nil],
+      [["A"], 10, nil],
+      [%w[A B C], 0, "A"],
+      [%w[A B C], 2, "C"],
+      [%w[A B C], -1, "C"],
+      [%w[A B C], -2, "B"],
+      [%w[A B C], -4, nil]
+    ].each do |values, number, expected|
+      describe "#{values.inspect} with #{number}" do
+        it "returns #{expected.inspect}" do
+          L[*values].at(number).should == expected
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/break_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/break_spec.rb
new file mode 100755
index 0000000..7f5c516
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/break_spec.rb
@@ -0,0 +1,70 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#break" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.break { |item| false } }.should_not raise_error
+    end
+
+    [
+      [[], [], []],
+      [[1], [1], []],
+      [[1, 2], [1, 2], []],
+      [[1, 2, 3], [1, 2], [3]],
+      [[1, 2, 3, 4], [1, 2], [3, 4]],
+      [[2, 3, 4], [2], [3, 4]],
+      [[3, 4], [], [3, 4]],
+      [[4], [], [4]],
+    ].each do |values, expected_prefix, expected_remainder|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        context "with a block" do
+          let(:result) { list.break { |item| item > 2 }}
+          let(:prefix) { result.first }
+          let(:remainder) { result.last }
+
+          it "preserves the original" do
+            result
+            list.should eql(L[*values])
+          end
+
+          it "returns a frozen array with two items" do
+            result.class.should be(Array)
+            result.should be_frozen
+            result.size.should be(2)
+          end
+
+          it "correctly identifies the prefix" do
+            prefix.should eql(L[*expected_prefix])
+          end
+
+          it "correctly identifies the remainder" do
+            remainder.should eql(L[*expected_remainder])
+          end
+        end
+
+        context "without a block" do
+          let(:result) { list.break }
+          let(:prefix) { result.first }
+          let(:remainder) { result.last }
+
+          it "returns a frozen array with two items" do
+            result.class.should be(Array)
+            result.should be_frozen
+            result.size.should be(2)
+          end
+
+          it "returns self as the prefix" do
+            prefix.should equal(list)
+          end
+
+          it "leaves the remainder empty" do
+            remainder.should be_empty
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/cadr_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/cadr_spec.rb
new file mode 100755
index 0000000..eac5c05
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/cadr_spec.rb
@@ -0,0 +1,39 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [
+    [[], :car, nil],
+    [["A"], :car, "A"],
+    [%w[A B C], :car, "A"],
+    [%w[A B C], :cadr, "B"],
+    [%w[A B C], :caddr, "C"],
+    [%w[A B C], :cadddr, nil],
+    [%w[A B C], :caddddr, nil],
+    [[], :cdr, L.empty],
+    [["A"], :cdr, L.empty],
+    [%w[A B C], :cdr, L["B", "C"]],
+    [%w[A B C], :cddr, L["C"]],
+    [%w[A B C], :cdddr, L.empty],
+    [%w[A B C], :cddddr, L.empty],
+  ].each do |values, method, expected|
+    describe "##{method}" do
+      it "is responded to" do
+        L.empty.respond_to?(method).should == true
+      end
+
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.send(method)
+          list.should eql(L[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          list.send(method).should == expected
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/chunk_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/chunk_spec.rb
new file mode 100755
index 0000000..428edec
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/chunk_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#chunk" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.chunk(2) }.should_not raise_error
+    end
+
+    [
+      [[], []],
+      [["A"], [L["A"]]],
+      [%w[A B C], [L["A", "B"], L["C"]]],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.chunk(2)
+          list.should eql(L[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          list.chunk(2).should eql(L[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/clear_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/clear_spec.rb
new file mode 100755
index 0000000..11996e1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/clear_spec.rb
@@ -0,0 +1,25 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#clear" do
+    [
+      [],
+      ["A"],
+      %w[A B C],
+    ].each do |values|
+      describe "on #{values}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.clear
+          list.should eql(L[*values])
+        end
+
+        it "returns an empty list" do
+          list.clear.should equal(L.empty)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/combination_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/combination_spec.rb
new file mode 100755
index 0000000..6e8df05
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/combination_spec.rb
@@ -0,0 +1,34 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#combination" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.combination(2) }.should_not raise_error
+    end
+
+    [
+      [%w[A B C D], 1, [L["A"], L["B"], L["C"], L["D"]]],
+      [%w[A B C D], 2, [L["A","B"], L["A","C"], L["A","D"], L["B","C"], L["B","D"], L["C","D"]]],
+      [%w[A B C D], 3, [L["A","B","C"], L["A","B","D"], L["A","C","D"], L["B","C","D"]]],
+      [%w[A B C D], 4, [L["A", "B", "C", "D"]]],
+      [%w[A B C D], 0, [EmptyList]],
+      [%w[A B C D], 5, []],
+      [[], 0, [EmptyList]],
+      [[], 1, []],
+    ].each do |values, number, expected|
+      context "on #{values.inspect} in groups of #{number}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.combination(number)
+          list.should eql(L[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          list.combination(number).should eql(L[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/compact_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/compact_spec.rb
new file mode 100755
index 0000000..3bcef0b
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/compact_spec.rb
@@ -0,0 +1,35 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#compact" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.compact }.should_not raise_error
+    end
+
+    [
+      [[], []],
+      [["A"], ["A"]],
+      [%w[A B C], %w[A B C]],
+      [[nil], []],
+      [[nil, "B"], ["B"]],
+      [["A", nil], ["A"]],
+      [[nil, nil], []],
+      [["A", nil, "C"], %w[A C]],
+      [[nil, "B", nil], ["B"]],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.compact
+          list.should eql(L[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          list.compact.should eql(L[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/compare_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/compare_spec.rb
new file mode 100755
index 0000000..1b8b9c7
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/compare_spec.rb
@@ -0,0 +1,31 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#<=>" do
+    [
+      [[], [1]],
+      [[1], [2]],
+      [[1], [1, 2]],
+      [[2, 3, 4], [3, 4, 5]]
+    ].each do |items1, items2|
+      context "with #{items1} and #{items2}" do
+        it "returns -1" do
+          (L[*items1] <=> L[*items2]).should be(-1)
+        end
+      end
+
+      context "with #{items2} and #{items1}" do
+        it "returns 1" do
+          (L[*items2] <=> L[*items1]).should be(1)
+        end
+      end
+
+      context "with #{items1} and #{items1}" do
+        it "returns 0" do
+          (L[*items1] <=> L[*items1]).should be(0)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/cons_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/cons_spec.rb
new file mode 100755
index 0000000..3d11c91
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/cons_spec.rb
@@ -0,0 +1,26 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#cons" do
+    [
+      [[], "A", ["A"]],
+      [["A"], "B", %w[B A]],
+      [["A"], "A", %w[A A]],
+      [%w[A B C], "D", %w[D A B C]],
+    ].each do |values, new_value, expected|
+      context "on #{values.inspect} with #{new_value.inspect}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.cons(new_value)
+          list.should eql(L[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          list.cons(new_value).should eql(L[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/construction_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/construction_spec.rb
new file mode 100755
index 0000000..5cc1882
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/construction_spec.rb
@@ -0,0 +1,111 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster do
+  describe ".list" do
+    context "with no arguments" do
+      it "always returns the same instance" do
+        L.empty.should equal(L.empty)
+      end
+
+      it "returns an empty list" do
+        L.empty.should be_empty
+      end
+    end
+
+    context "with a number of items" do
+      it "always returns a different instance" do
+        L["A", "B", "C"].should_not equal(L["A", "B", "C"])
+      end
+
+      it "is the same as repeatedly using #cons" do
+        L["A", "B", "C"].should eql(L.empty.cons("C").cons("B").cons("A"))
+      end
+    end
+  end
+
+  describe ".stream" do
+    context "with no block" do
+      it "returns an empty list" do
+        Hamster.stream.should eql(L.empty)
+      end
+    end
+
+    context "with a block" do
+      let(:list) { count = 0; Hamster.stream { count += 1 }}
+
+      it "repeatedly calls the block" do
+        list.take(5).should eql(L[1, 2, 3, 4, 5])
+      end
+    end
+  end
+
+  describe ".interval" do
+    context "for numbers" do
+      it "is equivalent to a list with explicit values" do
+        Hamster.interval(98, 102).should eql(L[98, 99, 100, 101, 102])
+      end
+    end
+
+    context "for strings" do
+      it "is equivalent to a list with explicit values" do
+        Hamster.interval("A", "AA").should eql(L["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA"])
+      end
+    end
+  end
+
+  describe ".repeat" do
+    it "returns an infinite list with specified value for each element" do
+      Hamster.repeat("A").take(5).should eql(L["A", "A", "A", "A", "A"])
+    end
+  end
+
+  describe ".replicate" do
+    it "returns a list with the specified value repeated the specified number of times" do
+      Hamster.replicate(5, "A").should eql(L["A", "A", "A", "A", "A"])
+    end
+  end
+
+  describe ".iterate" do
+    it "returns an infinite list where the first item is calculated by applying the block on the initial argument, the second item by applying the function on the previous result and so on" do
+      Hamster.iterate(1) { |item| item * 2 }.take(10).should eql(L[1, 2, 4, 8, 16, 32, 64, 128, 256, 512])
+    end
+  end
+
+  describe ".enumerate" do
+    let(:enum) do
+      Enumerator.new do |yielder|
+        yielder << 1
+        yielder << 2
+        yielder << 3
+        raise "list fully realized"
+      end
+    end
+
+    let(:list) { Hamster.enumerate(enum) }
+
+    it "returns a list based on the values yielded from the enumerator" do
+      expect(list.take(2)).to eq L[1, 2]
+    end
+
+    it "realizes values as they are needed" do
+      # this example shows that Lists are not as lazy as they could be
+      # if Lists were fully lazy, you would have to take(4) to hit the exception
+      expect { list.take(3).to_a }.to raise_exception
+    end
+  end
+
+  describe "[]" do
+    it "takes a variable number of items and returns a list" do
+      list = Hamster::List[1,2,3]
+      list.should be_kind_of(Hamster::List)
+      list.size.should be(3)
+      list.to_a.should == [1,2,3]
+    end
+
+    it "returns an empty list when called without arguments" do
+      L[].should be_kind_of(Hamster::List)
+      L[].should be_empty
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/copying_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/copying_spec.rb
new file mode 100755
index 0000000..fe43ffd
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/copying_spec.rb
@@ -0,0 +1,20 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [:dup, :clone].each do |method|
+    [
+      [],
+      ["A"],
+      %w[A B C],
+    ].each do |values|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        it "returns self" do
+          list.send(method).should equal(list)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/count_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/count_spec.rb
new file mode 100755
index 0000000..3d833be
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/count_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#count" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).count }.should_not raise_error
+      end
+    end
+
+    [
+      [[], 0],
+      [[1], 1],
+      [[1, 2], 1],
+      [[1, 2, 3], 2],
+      [[1, 2, 3, 4], 2],
+      [[1, 2, 3, 4, 5], 3],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        context "with a block" do
+          it "returns #{expected.inspect}" do
+            list.count(&:odd?).should == expected
+          end
+        end
+
+        context "without a block" do
+          it "returns length" do
+            list.count.should == list.length
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/cycle_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/cycle_spec.rb
new file mode 100755
index 0000000..527ab48
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/cycle_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster do
+  describe "#cycle" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.cycle }.should_not raise_error
+    end
+
+    context "with an empty list" do
+      it "returns an empty list" do
+        L.empty.cycle.should be_empty
+      end
+    end
+
+    context "with a non-empty list" do
+      let(:list) { L["A", "B", "C"] }
+
+      it "preserves the original" do
+        list.cycle
+        list.should == L["A", "B", "C"]
+      end
+
+      it "infinitely cycles through all values" do
+        list.cycle.take(7).should == L["A", "B", "C", "A", "B", "C", "A"]
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/delete_at_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/delete_at_spec.rb
new file mode 100755
index 0000000..e31ed01
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/delete_at_spec.rb
@@ -0,0 +1,19 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#delete_at" do
+    let(:list) { L[1,2,3,4,5] }
+
+    it "removes the element at the specified index" do
+      list.delete_at(0).should eql(L[2,3,4,5])
+      list.delete_at(2).should eql(L[1,2,4,5])
+      list.delete_at(-1).should eql(L[1,2,3,4])
+    end
+
+    it "makes no modification if the index is out of range" do
+      list.delete_at(5).should eql(list)
+      list.delete_at(-6).should eql(list)
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/delete_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/delete_spec.rb
new file mode 100755
index 0000000..c4dc80b
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/delete_spec.rb
@@ -0,0 +1,17 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#delete" do
+    it "removes elements that are #== to the argument" do
+      L[1,2,3].delete(1).should eql(L[2,3])
+      L[1,2,3].delete(2).should eql(L[1,3])
+      L[1,2,3].delete(3).should eql(L[1,2])
+      L[1,2,3].delete(0).should eql(L[1,2,3])
+      L['a','b','a','c','a','a','d'].delete('a').should eql(L['b','c','d'])
+
+      L[EqualNotEql.new, EqualNotEql.new].delete(:something).should eql(L[])
+      L[EqlNotEqual.new, EqlNotEqual.new].delete(:something).should_not be_empty
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/drop_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/drop_spec.rb
new file mode 100755
index 0000000..b52ed3a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/drop_spec.rb
@@ -0,0 +1,31 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#drop" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.drop(1) }.should_not raise_error
+    end
+
+    [
+      [[], 10, []],
+      [["A"], 10, []],
+      [["A"], -1, ["A"]],
+      [%w[A B C], 0, %w[A B C]],
+      [%w[A B C], 2, ["C"]],
+    ].each do |values, number, expected|
+      context "with #{number} from #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.drop(number)
+          list.should eql(L[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          list.drop(number).should == L[*expected]
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/drop_while_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/drop_while_spec.rb
new file mode 100755
index 0000000..ba06b8a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/drop_while_spec.rb
@@ -0,0 +1,39 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#drop_while" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.drop_while { false } }.should_not raise_error
+    end
+
+    [
+      [[], []],
+      [["A"], []],
+      [%w[A B C], ["C"]],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        context "with a block" do
+          it "preserves the original" do
+            list.drop_while { |item| item < "C" }
+            list.should eql(L[*values])
+          end
+
+          it "returns #{expected.inspect}" do
+            list.drop_while { |item| item < "C" }.should eql(L[*expected])
+          end
+        end
+
+        context "without a block" do
+          it "returns an Enumerator" do
+            list.drop_while.class.should be(Enumerator)
+            list.drop_while.each { false }.should eql(list)
+            list.drop_while.each { true  }.should be_empty
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/each_slice_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/each_slice_spec.rb
new file mode 100755
index 0000000..e3f69dc
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/each_slice_spec.rb
@@ -0,0 +1,52 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [:each_chunk, :each_slice].each do |method|
+    describe "##{method}" do
+      context "on a really big list" do
+        it "doesn't run out of stack" do
+          -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).send(method, 1) { |item| } }.should_not raise_error
+        end
+      end
+
+      [
+        [[], []],
+        [["A"], [L["A"]]],
+        [%w[A B C], [L["A", "B"], L["C"]]],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          let(:list) { L[*values] }
+
+          context "with a block" do
+            it "preserves the original" do
+              list.should eql(L[*values])
+            end
+
+            it "iterates over the items in order" do
+              yielded = []
+              list.send(method, 2) { |item| yielded << item }
+              yielded.should eql(expected)
+            end
+
+            it "returns self" do
+              list.send(method, 2) { |item| item }.should be(list)
+            end
+          end
+
+          context "without a block" do
+            it "preserves the original" do
+              list.send(method, 2)
+              list.should eql(L[*values])
+            end
+
+            it "returns an Enumerator" do
+              list.send(method, 2).class.should be(Enumerator)
+              list.send(method, 2).to_a.should eql(expected)
+            end
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/each_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/each_spec.rb
new file mode 100755
index 0000000..a210e2d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/each_spec.rb
@@ -0,0 +1,41 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#each" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).each { |item| } }.should_not raise_error
+      end
+    end
+
+    [
+      [],
+      ["A"],
+      %w[A B C],
+    ].each do |values|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        context "with a block" do
+          it "iterates over the items in order" do
+            yielded = []
+            list.each { |item| yielded << item }
+            yielded.should == values
+          end
+
+          it "returns nil" do
+            list.each { |item| item }.should be_nil
+          end
+        end
+
+        context "without a block" do
+          it "returns an Enumerator" do
+            list.each.class.should be(Enumerator)
+            Hamster::List[*list.each].should eql(list)
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/each_with_index_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/each_with_index_spec.rb
new file mode 100755
index 0000000..510bef3
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/each_with_index_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#each_with_index" do
+    context "with no block" do
+      let(:list) { L["A", "B", "C"] }
+
+      it "returns an Enumerator" do
+        list.each_with_index.class.should be(Enumerator)
+        list.each_with_index.to_a.should == [['A', 0], ['B', 1], ['C', 2]]
+      end
+    end
+
+    context "with a block" do
+      let(:list) { Hamster.interval(1, 1025) }
+
+      it "returns self" do
+        list.each_with_index { |item, index| item }.should be(list)
+      end
+
+      it "iterates over the items in order, yielding item and index" do
+        yielded = []
+        list.each_with_index { |item, index| yielded << [item, index] }
+        yielded.should == (1..list.size).zip(0..list.size.pred)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/empty_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/empty_spec.rb
new file mode 100755
index 0000000..98f00c9
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/empty_spec.rb
@@ -0,0 +1,24 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#empty?" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).select(&:nil?).empty? }.should_not raise_error
+      end
+    end
+
+    [
+      [[], true],
+      [["A"], false],
+      [%w[A B C], false],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        it "returns #{expected.inspect}" do
+          L[*values].empty?.should == expected
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/eql_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/eql_spec.rb
new file mode 100755
index 0000000..eb711a2
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/eql_spec.rb
@@ -0,0 +1,62 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#eql?" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).eql?(Hamster.interval(0, STACK_OVERFLOW_DEPTH)) }.should_not raise_error
+      end
+    end
+  end
+
+  shared_examples 'equal using eql?' do |a, b|
+    specify "#{a.inspect} should eql? #{b.inspect}" do
+      expect(a).to eql b
+    end
+
+    specify "#{a.inspect} should == #{b.inspect}" do
+      expect(a).to eq b
+    end
+  end
+
+  shared_examples 'not equal using eql?' do |a, b|
+    specify "#{a.inspect} should not eql? #{b.inspect}" do
+      expect(a).to_not eql b
+    end
+  end
+
+  shared_examples 'equal using ==' do |a, b|
+    specify "#{a.inspect} should == #{b.inspect}" do
+      expect(a).to eq b
+    end
+  end
+
+  shared_examples 'not equal using ==' do |a, b|
+    specify "#{a.inspect} should not == #{b.inspect}" do
+      expect(a).to_not eq b
+    end
+  end
+
+  include_examples 'equal using =='       , L["A", "B", "C"], %w[A B C]
+  include_examples 'not equal using eql?' , L["A", "B", "C"], %w[A B C]
+  include_examples 'not equal using =='   , L["A", "B", "C"], Object.new
+  include_examples 'not equal using eql?' , L["A", "B", "C"], Object.new
+  include_examples 'equal using =='       , L.empty, []
+  include_examples 'not equal using eql?' , L.empty, []
+
+  include_examples 'equal using eql?'     , L.empty, L.empty
+  include_examples 'not equal using eql?' , L.empty, L[nil]
+  include_examples 'not equal using eql?' , L["A"], L.empty
+  include_examples 'equal using eql?'     , L["A"], L["A"]
+  include_examples 'not equal using eql?' , L["A"], L["B"]
+  include_examples 'not equal using eql?' , L["A", "B"], L["A"]
+  include_examples 'equal using eql?'     , L["A", "B", "C"], L["A", "B", "C"]
+  include_examples 'not equal using eql?' , L["C", "A", "B"], L["A", "B", "C"]
+
+  include_examples 'equal using =='       , L['A'], ['A']
+  include_examples 'equal using =='       , ['A'], L['A']
+
+  include_examples 'not equal using eql?' , L['A'], ['A']
+  include_examples 'not equal using eql?' , ['A'], L['A']
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/fill_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/fill_spec.rb
new file mode 100755
index 0000000..3ed5fe7
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/fill_spec.rb
@@ -0,0 +1,50 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#fill" do
+    let(:list) { L[1, 2, 3, 4, 5, 6] }
+
+    it "can replace a range of items at the beginning of a list" do
+      list.fill(:a, 0, 3).should eql(L[:a, :a, :a, 4, 5, 6])
+    end
+
+    it "can replace a range of items in the middle of a list" do
+      list.fill(:a, 3, 2).should eql(L[1, 2, 3, :a, :a, 6])
+    end
+
+    it "can replace a range of items at the end of a list" do
+      list.fill(:a, 4, 2).should eql(L[1, 2, 3, 4, :a, :a])
+    end
+
+    it "can replace all the items in a list" do
+      list.fill(:a, 0, 6).should eql(L[:a, :a, :a, :a, :a, :a])
+    end
+
+    it "can fill past the end of the list" do
+      list.fill(:a, 3, 6).should eql(L[1, 2, 3, :a, :a, :a, :a, :a, :a])
+    end
+
+    context "with 1 argument" do
+      it "replaces all the items in the list by default" do
+        list.fill(:a).should eql(L[:a, :a, :a, :a, :a, :a])
+      end
+    end
+
+    context "with 2 arguments" do
+      it "replaces up to the end of the list by default" do
+        list.fill(:a, 4).should eql(L[1, 2, 3, 4, :a, :a])
+      end
+    end
+
+    context "when index and length are 0" do
+      it "leaves the list unmodified" do
+        list.fill(:a, 0, 0).should eql(list)
+      end
+    end
+
+    it "is lazy" do
+      -> { Hamster.stream { fail }.fill(:a, 0, 1) }.should_not raise_error
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/find_all_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/find_all_spec.rb
new file mode 100755
index 0000000..91b4da9
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/find_all_spec.rb
@@ -0,0 +1,71 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  let(:list) { L[*values] }
+  let(:found_list) { L[*found_values] }
+
+  describe "#find_all" do
+    it "is lazy" do
+      expect { Hamster.stream { fail }.find_all { |item| false } }.to_not raise_error
+    end
+
+    shared_examples "checking values" do
+      context "with a block" do
+        let(:find_all) { list.find_all { |item| item == item.upcase } }
+
+        it "preserves the original" do
+          expect(list).to eq(L[*values])
+        end
+
+        it "returns the found list" do
+          expect(find_all).to eq(found_list)
+        end
+      end
+
+      context "without a block" do
+        let(:find_all) { list.find_all }
+
+        it "returns an Enumerator" do
+          expect(find_all.class).to be(Enumerator)
+          expect(find_all.each { |item| item == item.upcase }).to eq(found_list)
+        end
+      end
+    end
+
+    context "with an empty array" do
+      let(:values) { [] }
+      let(:found_values) { [] }
+
+      include_examples "checking values"
+    end
+
+    context "with a single item array" do
+      let(:values) { ["A"] }
+      let(:found_values) { ["A"] }
+
+      include_examples "checking values"
+    end
+
+    context "with a multi-item array" do
+      let(:values) { %w[A B] }
+      let(:found_values) { %w[A B] }
+
+      include_examples "checking values"
+    end
+
+    context "with a multi-item single find_allable array" do
+      let(:values) { %w[A b] }
+      let(:found_values) { ["A"] }
+
+      include_examples "checking values"
+    end
+
+    context "with a multi-item multi-find_allable array" do
+      let(:values) { %w[a b] }
+      let(:found_values) { [] }
+
+      include_examples "checking values"
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/find_index_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/find_index_spec.rb
new file mode 100755
index 0000000..14bd6a5
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/find_index_spec.rb
@@ -0,0 +1,36 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [:find_index, :index].each do |method|
+    describe "##{method}" do
+      context "on a really big list" do
+        it "doesn't run out of stack" do
+          -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).send(method) { |item| false } }.should_not raise_error
+        end
+      end
+
+      [
+        [[], "A", nil],
+        [[], nil, nil],
+        [["A"], "A", 0],
+        [["A"], "B", nil],
+        [["A"], nil, nil],
+        [["A", "B", nil], "A", 0],
+        [["A", "B", nil], "B", 1],
+        [["A", "B", nil], nil, 2],
+        [["A", "B", nil], "C", nil],
+        [[2], 2, 0],
+        [[2], 2.0, 0],
+        [[2.0], 2.0, 0],
+        [[2.0], 2, 0],
+      ].each do |values, item, expected|
+        context "looking for #{item.inspect} in #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            L[*values].send(method) { |x| x == item }.should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/find_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/find_spec.rb
new file mode 100755
index 0000000..6b4f08c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/find_spec.rb
@@ -0,0 +1,43 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [:find, :detect].each do |method|
+    describe "##{method}" do
+      context "on a really big list" do
+        it "doesn't run out of stack" do
+          -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).send(method) { false } }.should_not raise_error
+        end
+      end
+
+      [
+        [[], "A", nil],
+        [[], nil, nil],
+        [["A"], "A", "A"],
+        [["A"], "B", nil],
+        [["A"], nil, nil],
+        [["A", "B", nil], "A", "A"],
+        [["A", "B", nil], "B", "B"],
+        [["A", "B", nil], nil, nil],
+        [["A", "B", nil], "C", nil],
+      ].each do |values, item, expected|
+        context "on #{values.inspect}" do
+          let(:list) { L[*values] }
+
+          context "with a block" do
+            it "returns #{expected.inspect}" do
+              list.send(method) { |x| x == item }.should == expected
+            end
+          end
+
+          context "without a block" do
+            it "returns an Enumerator" do
+              list.send(method).class.should be(Enumerator)
+              list.send(method).each { |x| x == item }.should == expected
+            end
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/flat_map_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/flat_map_spec.rb
new file mode 100755
index 0000000..d78a1ab
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/flat_map_spec.rb
@@ -0,0 +1,52 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  let(:list) { L[*values] }
+
+  describe "#flat_map" do
+    let(:block) { ->(item) { [item, item + 1, item * item] } }
+    let(:flat_map) { list.flat_map(&block) }
+    let(:flattened_list) { L[*flattened_values] }
+
+    shared_examples "checking flattened result" do
+
+      it "returns the flattened values as a Hamster::List" do
+        expect(flat_map).to eq(flattened_list)
+      end
+
+      it "returns a Hamster::List" do
+        expect(flat_map).to be_a(Hamster::List)
+      end
+    end
+
+    context "with an empty list" do
+      let(:values) { [] }
+      let(:flattened_values) { [] }
+
+      include_examples "checking flattened result"
+    end
+
+    context "with a block that returns an empty list" do
+      let(:block) { ->(item) { [] } }
+      let(:values) { [1, 2, 3] }
+      let(:flattened_values) { [] }
+
+      include_examples "checking flattened result"
+    end
+
+    context "with a list of one item" do
+      let(:values) { [7] }
+      let(:flattened_values) { [7, 8, 49] }
+
+      include_examples "checking flattened result"
+    end
+
+    context "with a list of multiple items" do
+      let(:values) { [1, 2, 3] }
+      let(:flattened_values) { [1, 2, 1, 2, 3, 4, 3, 4, 9] }
+
+      include_examples "checking flattened result"
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/flatten_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/flatten_spec.rb
new file mode 100755
index 0000000..10651ef
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/flatten_spec.rb
@@ -0,0 +1,31 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster do
+  describe "#flatten" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.flatten }.should_not raise_error
+    end
+
+    [
+      [[], []],
+      [["A"], ["A"]],
+      [%w[A B C], %w[A B C]],
+      [["A", L["B"], "C"], %w[A B C]],
+      [[L["A"], L["B"], L["C"]], %w[A B C]],
+    ].each do |values, expected|
+      context "on #{values}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.flatten
+          list.should eql(L[*values])
+        end
+
+        it "returns an empty list" do
+          list.flatten.should eql(L[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/grep_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/grep_spec.rb
new file mode 100755
index 0000000..b12b728
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/grep_spec.rb
@@ -0,0 +1,47 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#grep" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.grep(Object) { |item| item } }.should_not raise_error
+    end
+
+    context "without a block" do
+      [
+        [[], []],
+        [["A"], ["A"]],
+        [[1], []],
+        [["A", 2, "C"], %w[A C]],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            L[*values].grep(String).should eql(L[*expected])
+          end
+        end
+      end
+    end
+
+    context "with a block" do
+      [
+        [[], []],
+        [["A"], ["a"]],
+        [[1], []],
+        [["A", 2, "C"], %w[a c]],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          let(:list) { L[*values] }
+
+          it "preserves the original" do
+            list.grep(String, &:downcase)
+            list.should eql(L[*values])
+          end
+
+          it "returns #{expected.inspect}" do
+            list.grep(String, &:downcase).should eql(L[*expected])
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/group_by_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/group_by_spec.rb
new file mode 100755
index 0000000..036ce1c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/group_by_spec.rb
@@ -0,0 +1,42 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [:group_by, :group].each do |method|
+    describe "##{method}" do
+      context "on a really big list" do
+        it "doesn't run out of stack" do
+          -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).send(method) }.should_not raise_error
+        end
+      end
+
+      context "with a block" do
+        [
+          [[], []],
+          [[1], [true => L[1]]],
+          [[1, 2, 3, 4], [true => L[3, 1], false => L[4, 2]]],
+        ].each do |values, expected|
+          context "on #{values.inspect}" do
+            it "returns #{expected.inspect}" do
+              L[*values].send(method, &:odd?).should eql(H[*expected])
+            end
+          end
+        end
+      end
+
+      context "without a block" do
+        [
+          [[], []],
+          [[1], [1 => L[1]]],
+          [[1, 2, 3, 4], [1 => L[1], 2 => L[2], 3 => L[3], 4 => L[4]]],
+        ].each do |values, expected|
+          context "on #{values.inspect}" do
+            it "returns #{expected.inspect}" do
+              L[*values].send(method).should eql(H[*expected])
+            end
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/hash_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/hash_spec.rb
new file mode 100755
index 0000000..e625df9
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/hash_spec.rb
@@ -0,0 +1,22 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#hash" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).hash }.should_not raise_error
+      end
+    end
+
+    context "on an empty list" do
+      it "returns 0" do
+        expect(L.empty.hash).to eq(0)
+      end
+    end
+
+    it "values are sufficiently distributed" do
+      (1..4000).each_slice(4).map { |a, b, c, d| L[a, b, c, d].hash }.uniq.size.should == 1000
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/head_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/head_spec.rb
new file mode 100755
index 0000000..de4e00a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/head_spec.rb
@@ -0,0 +1,20 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [:head, :first].each do |method|
+    describe "##{method}" do
+      [
+        [[], nil],
+        [["A"], "A"],
+        [%w[A B C], "A"],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            L[*values].send(method).should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/include_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/include_spec.rb
new file mode 100755
index 0000000..e4c2549
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/include_spec.rb
@@ -0,0 +1,36 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [:include?, :member?].each do |method|
+    describe "##{method}" do
+      context "on a really big list" do
+        it "doesn't run out of stack" do
+          -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).send(method, nil) }.should_not raise_error
+        end
+      end
+
+      [
+        [[], "A", false],
+        [[], nil, false],
+        [["A"], "A", true],
+        [["A"], "B", false],
+        [["A"], nil, false],
+        [["A", "B", nil], "A", true],
+        [["A", "B", nil], "B", true],
+        [["A", "B", nil], nil, true],
+        [["A", "B", nil], "C", false],
+        [[2], 2, true],
+        [[2], 2.0, true],
+        [[2.0], 2.0, true],
+        [[2.0], 2, true],
+      ].each do |values, item, expected|
+        context "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            L[*values].send(method, item).should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/index_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/index_spec.rb
new file mode 100755
index 0000000..f3a67f1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/index_spec.rb
@@ -0,0 +1,38 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#index" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).index(nil) }.should_not raise_error
+      end
+    end
+
+    [
+      [[], "A", nil],
+      [[], nil, nil],
+      [["A"], "A", 0],
+      [["A"], "B", nil],
+      [["A"], nil, nil],
+      [["A", "B", nil], "A", 0],
+      [["A", "B", nil], "B", 1],
+      [["A", "B", nil], nil, 2],
+      [["A", "B", nil], "C", nil],
+      [[2], 2, 0],
+      [[2], 2.0, 0],
+      [[2.0], 2.0, 0],
+      [[2.0], 2, 0],
+    ].each do |values, item, expected|
+      context "looking for #{item.inspect} in #{values.inspect}" do
+        it "returns #{expected.inspect}" do
+          if RUBY_ENGINE == 'jruby' && RUBY_VERSION <= '2.2.2' && values[0].is_a?(Fixnum) && item.is_a?(Float)
+            skip "On JRuby, Enumerable#find_index doesn't test equality properly"
+          else
+            L[*values].index(item).should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/indices_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/indices_spec.rb
new file mode 100755
index 0000000..f51842f
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/indices_spec.rb
@@ -0,0 +1,62 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#indices" do
+    context "when called with a block" do
+      it "is lazy" do
+        count = 0
+        Hamster.stream { count += 1 }.indices { |item| true }
+        count.should <= 1
+      end
+
+      context "on a large list which doesn't contain desired item" do
+        it "doesn't blow the stack" do
+          -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).indices { |x| x < 0 }.size }.should_not raise_error
+        end
+      end
+
+      [
+        [[], "A", []],
+        [["A"], "B", []],
+        [%w[A B A], "B", [1]],
+        [%w[A B A], "A", [0, 2]],
+        [[2], 2, [0]],
+        [[2], 2.0, [0]],
+        [[2.0], 2.0, [0]],
+        [[2.0], 2, [0]],
+      ].each do |values, item, expected|
+        context "looking for #{item.inspect} in #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            L[*values].indices { |x| x == item }.should eql(L[*expected])
+          end
+        end
+      end
+    end
+
+    context "when called with a single argument" do
+      it "is lazy" do
+        count = 0
+        Hamster.stream { count += 1 }.indices(nil)
+        count.should <= 1
+      end
+
+      [
+        [[], "A", []],
+        [["A"], "B", []],
+        [%w[A B A], "B", [1]],
+        [%w[A B A], "A", [0, 2]],
+        [[2], 2, [0]],
+        [[2], 2.0, [0]],
+        [[2.0], 2.0, [0]],
+        [[2.0], 2, [0]],
+      ].each do |values, item, expected|
+        context "looking for #{item.inspect} in #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            L[*values].indices(item).should eql(L[*expected])
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/init_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/init_spec.rb
new file mode 100755
index 0000000..5c5e62b
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/init_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#init" do
+    it "is lazy" do
+      -> { Hamster.stream { false }.init }.should_not raise_error
+    end
+
+    [
+      [[], []],
+      [["A"], []],
+      [%w[A B C], %w[A B]],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.init
+          list.should eql(L[*values])
+        end
+
+        it "returns the list without the last element: #{expected.inspect}" do
+          list.init.should eql(L[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/inits_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/inits_spec.rb
new file mode 100755
index 0000000..7ce1c78
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/inits_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#inits" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.inits }.should_not raise_error
+    end
+
+    [
+      [[], []],
+      [["A"], [L["A"]]],
+      [%w[A B C], [L["A"], L["A", "B"], L["A", "B", "C"]]],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.inits
+          list.should eql(L[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          list.inits.should eql(L[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/insert_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/insert_spec.rb
new file mode 100755
index 0000000..dd3d5b2
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/insert_spec.rb
@@ -0,0 +1,47 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#insert" do
+    let(:original) { L[1, 2, 3] }
+
+    it "can add items at the beginning of a list" do
+      list = original.insert(0, :a, :b)
+      list.size.should be(5)
+      list.at(0).should be(:a)
+      list.at(2).should be(1)
+    end
+
+    it "can add items in the middle of a list" do
+      list = original.insert(1, :a, :b, :c)
+      list.size.should be(6)
+      list.to_a.should == [1, :a, :b, :c, 2, 3]
+    end
+
+    it "can add items at the end of a list" do
+      list = original.insert(3, :a, :b, :c)
+      list.size.should be(6)
+      list.to_a.should == [1, 2, 3, :a, :b, :c]
+    end
+
+    it "can add items past the end of a list" do
+      list = original.insert(6, :a, :b)
+      list.size.should be(8)
+      list.to_a.should == [1, 2, 3, nil, nil, nil, :a, :b]
+    end
+
+    it "accepts a negative index, which counts back from the end of the list" do
+      list = original.insert(-2, :a)
+      list.size.should be(4)
+      list.to_a.should == [1, :a, 2, 3]
+    end
+
+    it "raises IndexError if a negative index is too great" do
+      expect { original.insert(-4, :a) }.to raise_error(IndexError)
+    end
+
+    it "is lazy" do
+      -> { Hamster.stream { fail }.insert(0, :a) }.should_not raise_error
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/inspect_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/inspect_spec.rb
new file mode 100755
index 0000000..07c7f93
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/inspect_spec.rb
@@ -0,0 +1,30 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#inspect" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).inspect }.should_not raise_error
+      end
+    end
+
+    [
+      [[], 'Hamster::List[]'],
+      [["A"], 'Hamster::List["A"]'],
+      [%w[A B C], 'Hamster::List["A", "B", "C"]']
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        it "returns #{expected.inspect}" do
+          list.inspect.should == expected
+        end
+
+        it "returns a string which can be eval'd to get an equivalent object" do
+          eval(list.inspect).should eql(list)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/intersperse_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/intersperse_spec.rb
new file mode 100755
index 0000000..bd91b9a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/intersperse_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#intersperse" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.intersperse("") }.should_not raise_error
+    end
+
+    [
+      [[], []],
+      [["A"], ["A"]],
+      [%w[A B C], ["A", "|", "B", "|", "C"]]
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.intersperse("|")
+          list.should eql(L[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          list.intersperse("|").should eql(L[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/join_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/join_spec.rb
new file mode 100755
index 0000000..86b65c5
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/join_spec.rb
@@ -0,0 +1,64 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#join" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).join }.should_not raise_error
+      end
+    end
+
+    context "with a separator" do
+      [
+        [[], ""],
+        [["A"], "A"],
+        [%w[A B C], "A|B|C"]
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          let(:list) { L[*values] }
+
+          it "preserves the original" do
+            list.join("|")
+            list.should eql(L[*values])
+          end
+
+          it "returns #{expected.inspect}" do
+            list.join("|").should == expected
+          end
+        end
+      end
+    end
+
+    context "without a separator" do
+      [
+        [[], ""],
+        [["A"], "A"],
+        [%w[A B C], "ABC"]
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          let(:list) { L[*values] }
+
+          it "preserves the original" do
+            list.join
+            list.should eql(L[*values])
+          end
+
+          it "returns #{expected.inspect}" do
+            list.join.should == expected
+          end
+        end
+      end
+    end
+
+    context "without a separator (with global default separator set)" do
+      before { $, = '**' }
+      let(:list) { L["A", "B", "C"] }
+      after  { $, = nil }
+
+      it "uses the default global separator" do
+        list.join.should == "A**B**C"
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/last_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/last_spec.rb
new file mode 100755
index 0000000..5cf718a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/last_spec.rb
@@ -0,0 +1,24 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#last" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).last }.should_not raise_error
+      end
+    end
+
+    [
+      [[], nil],
+      [["A"], "A"],
+      [%w[A B C], "C"],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        it "returns #{expected.inspect}" do
+          L[*values].last.should == expected
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/ltlt_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/ltlt_spec.rb
new file mode 100755
index 0000000..d9e951d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/ltlt_spec.rb
@@ -0,0 +1,20 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#<<" do
+    it "adds an item onto the end of a list" do
+      list = L["a", "b"]
+      (list << "c").should eql(L["a", "b", "c"])
+      list.should eql(L["a", "b"])
+    end
+
+    context "on an empty list" do
+      it "returns a list with one item" do
+        list = L.empty
+        (list << "c").should eql(L["c"])
+        list.should eql(L.empty)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/map_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/map_spec.rb
new file mode 100755
index 0000000..e8c03d2
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/map_spec.rb
@@ -0,0 +1,46 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [:map, :collect].each do |method|
+    describe "##{method}" do
+      it "is lazy" do
+        -> { Hamster.stream { fail }.map { |item| item } }.should_not raise_error
+      end
+
+      [
+        [[], []],
+        [["A"], ["a"]],
+        [%w[A B C], %w[a b c]],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          let(:list) { L[*values] }
+
+          context "with a block" do
+            it "preserves the original" do
+              list.send(method, &:downcase)
+              list.should eql(L[*values])
+            end
+
+            it "returns #{expected.inspect}" do
+              list.send(method, &:downcase).should eql(L[*expected])
+            end
+
+            it "is lazy" do
+              count = 0
+              list.send(method) { |item| count += 1 }
+              count.should <= 1
+            end
+          end
+
+          context "without a block" do
+            it "returns an Enumerator" do
+              list.send(method).class.should be(Enumerator)
+              list.send(method).each(&:downcase).should eql(L[*expected])
+            end
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/maximum_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/maximum_spec.rb
new file mode 100755
index 0000000..a8dcb57
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/maximum_spec.rb
@@ -0,0 +1,40 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#max" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).max }.should_not raise_error
+      end
+    end
+
+    context "with a block" do
+      [
+        [[], nil],
+        [["A"], "A"],
+        [%w[Ichi Ni San], "Ichi"],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            L[*values].max { |maximum, item| maximum.length <=> item.length }.should == expected
+          end
+        end
+      end
+    end
+
+    context "without a block" do
+      [
+        [[], nil],
+        [["A"], "A"],
+        [%w[Ichi Ni San], "San"],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            L[*values].max.should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/merge_by_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/merge_by_spec.rb
new file mode 100755
index 0000000..d851a36
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/merge_by_spec.rb
@@ -0,0 +1,52 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  context "without a comparator" do
+    context "on an empty list" do
+      it "returns an empty list" do
+        L.empty.merge_by.should be_empty
+      end
+    end
+
+    context "on a single list" do
+      let(:list) { L[1, 2, 3] }
+
+      it "returns the list" do
+        L[list].merge_by.should eql(list)
+      end
+    end
+
+    context "with multiple lists" do
+      subject { L[L[3, 6, 7, 8], L[1, 2, 4, 5, 9]] }
+
+      it "merges the lists based on natural sort order" do
+        subject.merge_by.should == L[1, 2, 3, 4, 5, 6, 7, 8, 9]
+      end
+    end
+  end
+
+  context "with a comparator" do
+    context "on an empty list" do
+      it "returns an empty list" do
+        L.empty.merge_by { |item| fail("should never be called") }.should be_empty
+      end
+    end
+
+    context "on a single list" do
+      let(:list) { L[1, 2, 3] }
+
+      it "returns the list" do
+        L[list].merge_by { |item| -item }.should == L[1, 2, 3]
+      end
+    end
+
+    context "with multiple lists" do
+      subject { L[L[8, 7, 6, 3], L[9, 5, 4, 2, 1]] }
+
+      it "merges the lists based on the specified transformer" do
+        subject.merge_by { |item| -item }.should == L[9, 8, 7, 6, 5, 4, 3, 2, 1]
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/merge_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/merge_spec.rb
new file mode 100755
index 0000000..41d344e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/merge_spec.rb
@@ -0,0 +1,60 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  context "without a comparator" do
+    context "on an empty list" do
+      subject { L.empty }
+
+      it "returns an empty list" do
+        subject.merge.should be_empty
+      end
+    end
+
+    context "on a single list" do
+      let(:list) { L[1, 2, 3] }
+
+      subject { L[list] }
+
+      it "returns the list" do
+        subject.merge.should == list
+      end
+    end
+
+    context "with multiple lists" do
+      subject { L[L[3, 6, 7, 8], L[1, 2, 4, 5, 9]] }
+
+      it "merges the lists based on natural sort order" do
+        subject.merge.should == L[1, 2, 3, 4, 5, 6, 7, 8, 9]
+      end
+    end
+  end
+
+  context "with a comparator" do
+    context "on an empty list" do
+      subject { L.empty }
+
+      it "returns an empty list" do
+        subject.merge { |a, b| fail("should never be called") }.should be_empty
+      end
+    end
+
+    context "on a single list" do
+      let(:list) { L[1, 2, 3] }
+
+      subject { L[list] }
+
+      it "returns the list" do
+        subject.merge { |a, b| fail("should never be called") }.should == list
+      end
+    end
+
+    context "with multiple lists" do
+      subject { L[L[8, 7, 6, 3], L[9, 5, 4, 2, 1]] }
+
+      it "merges the lists based on the specified comparator" do
+        subject.merge { |a, b| b <=> a }.should == L[9, 8, 7, 6, 5, 4, 3, 2, 1]
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/minimum_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/minimum_spec.rb
new file mode 100755
index 0000000..f72fbb5
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/minimum_spec.rb
@@ -0,0 +1,40 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#min" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).min }.should_not raise_error
+      end
+    end
+
+    context "with a block" do
+      [
+        [[], nil],
+        [["A"], "A"],
+        [%w[Ichi Ni San], "Ni"],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            L[*values].min { |minimum, item| minimum.length <=> item.length }.should == expected
+          end
+        end
+      end
+    end
+
+    context "without a block" do
+      [
+        [[], nil],
+        [["A"], "A"],
+        [%w[Ichi Ni San], "Ichi"],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            L[*values].min.should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/multithreading_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/multithreading_spec.rb
new file mode 100755
index 0000000..bb4359d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/multithreading_spec.rb
@@ -0,0 +1,48 @@
+require "spec_helper"
+require "hamster/list"
+require "concurrent/atomics"
+
+describe Hamster::List do
+  it "ensures each node of a lazy list will only be realized on ONE thread, even when accessed by multiple threads" do
+    counter = Concurrent::AtomicReference.new(0)
+    list = (1..10000).to_list.map { |x| counter.update { |count| count + 1 }; x * 2 }
+
+    threads = 10.times.collect do
+      Thread.new do
+        node = list
+        node = node.tail until node.empty?
+      end
+    end
+    threads.each(&:join)
+
+    counter.get.should == 10000
+    list.sum.should == 100010000
+  end
+
+  it "doesn't go into an infinite loop if lazy list block raises an exception" do
+    list = (1..10).to_list.map { raise "Oops!" }
+
+    threads = 10.times.collect do
+      Thread.new do
+        -> { list.head }.should raise_error(RuntimeError)
+      end
+    end
+    threads.each(&:join)
+  end
+
+  it "doesn't give horrendously bad performance if thread realizing the list sleeps" do
+    start = Time.now
+    list  = (1..100).to_list.map { |x| sleep(0.001); x * 2 }
+
+    threads = 10.times.collect do
+      Thread.new do
+        node = list
+        node = node.tail until node.empty?
+      end
+    end
+    threads.each(&:join)
+
+    elapsed = Time.now - start
+    elapsed.should_not > 0.3
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/none_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/none_spec.rb
new file mode 100755
index 0000000..4bcf6e5
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/none_spec.rb
@@ -0,0 +1,48 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#none?" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).none? { false } }.should_not raise_error
+      end
+    end
+
+    context "when empty" do
+      it "with a block returns true" do
+        L.empty.none? {}.should == true
+      end
+
+      it "with no block returns true" do
+        L.empty.none?.should == true
+      end
+    end
+
+    context "when not empty" do
+      context "with a block" do
+        let(:list) { L["A", "B", "C", nil] }
+
+        ["A", "B", "C", nil].each do |value|
+          it "returns false if the block ever returns true (#{value.inspect})" do
+            list.none? { |item| item == value }.should == false
+          end
+        end
+
+        it "returns true if the block always returns false" do
+          list.none? { |item| item == "D" }.should == true
+        end
+      end
+
+      context "with no block" do
+        it "returns false if any value is truthy" do
+          L[nil, false, true, "A"].none?.should == false
+        end
+
+        it "returns true if all values are falsey" do
+          L[nil, false].none?.should == true
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/one_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/one_spec.rb
new file mode 100755
index 0000000..83a1f95
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/one_spec.rb
@@ -0,0 +1,50 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#one?" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).one? { false } }.should_not raise_error
+      end
+    end
+
+    context "when empty" do
+      it "with a block returns false" do
+        L.empty.one? {}.should == false
+      end
+
+      it "with no block returns false" do
+        L.empty.one?.should == false
+      end
+    end
+
+    context "when not empty" do
+      context "with a block" do
+        let(:list) { L["A", "B", "C"] }
+
+        it "returns false if the block returns true more than once" do
+          list.one? { |item| true }.should == false
+        end
+
+        it "returns false if the block never returns true" do
+          list.one? { |item| false }.should == false
+        end
+
+        it "returns true if the block only returns true once" do
+          list.one? { |item| item == "A" }.should == true
+        end
+      end
+
+      context "with no block" do
+        it "returns false if more than one value is truthy" do
+          L[nil, true, "A"].one?.should == false
+        end
+
+        it "returns true if only one value is truthy" do
+          L[nil, true, false].one?.should == true
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/partition_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/partition_spec.rb
new file mode 100755
index 0000000..65eeb7a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/partition_spec.rb
@@ -0,0 +1,116 @@
+require "spec_helper"
+require "hamster/list"
+require "thread"
+
+describe Hamster::List do
+  describe "#partition" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.partition }.should_not raise_error
+    end
+
+    it "calls the passed block only once for each item" do
+      count = 0
+      a,b = L[1, 2, 3].partition { |item| count += 1; item.odd? }
+      (a.size + b.size).should be(3) # force realization of lazy lists
+      count.should be(3)
+    end
+
+    # note: Lists are not as lazy as they could be!
+    # they always realize elements a bit ahead of the current one
+
+    it "returns a lazy list of items for which predicate is true" do
+      count = 0
+      a,b = L[1, 2, 3, 4].partition { |item| count += 1; item.odd? }
+      a.take(1).should == [1]
+      count.should be(3) # would be 1 if lists were lazier
+      a.take(2).should == [1, 3]
+      count.should be(4) # would be 3 if lists were lazier
+    end
+
+    it "returns a lazy list of items for which predicate is false" do
+      count = 0
+      a,b = L[1, 2, 3, 4].partition { |item| count += 1; item.odd? }
+      b.take(1).should == [2]
+      count.should be(4) # would be 2 if lists were lazier
+      b.take(2).should == [2, 4]
+      count.should be(4)
+    end
+
+    it "calls the passed block only once for each item, even with multiple threads" do
+      mutex = Mutex.new
+      yielded = [] # record all the numbers yielded to the block, to make sure each is yielded only once
+      list = Hamster.iterate(0) do |n|
+        sleep(rand / 500) # give another thread a chance to get in
+        mutex.synchronize { yielded << n }
+        sleep(rand / 500)
+        n + 1
+      end
+      left, right = list.partition(&:odd?)
+
+      10.times.collect do |i|
+        Thread.new do
+          # half of the threads will consume the "left" lazy list, while half consume
+          # the "right" lazy list
+          # make sure that only one thread will run the above "iterate" block at a
+          # time, regardless
+          if i % 2 == 0
+            left.take(100).sum.should == 10000
+          else
+            right.take(100).sum.should == 9900
+          end
+        end
+      end.each(&:join)
+
+      # if no threads "stepped on" each other, the following should be true
+      # make some allowance for "lazy" lists which actually realize a little bit ahead:
+      (200..203).include?(yielded.size).should == true
+      yielded.should == (0..(yielded.size-1)).to_a
+    end
+
+    [
+      [[], [], []],
+      [[1], [1], []],
+      [[1, 2], [1], [2]],
+      [[1, 2, 3], [1, 3], [2]],
+      [[1, 2, 3, 4], [1, 3], [2, 4]],
+      [[2, 3, 4], [3], [2, 4]],
+      [[3, 4], [3], [4]],
+      [[4], [], [4]],
+    ].each do |values, expected_matches, expected_remainder|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        context "with a block" do
+          let(:result)  { list.partition(&:odd?) }
+          let(:matches) { result.first }
+          let(:remainder) { result.last }
+
+          it "preserves the original" do
+            list.should eql(L[*values])
+          end
+
+          it "returns a frozen array with two items" do
+            result.class.should be(Array)
+            result.should be_frozen
+            result.size.should be(2)
+          end
+
+          it "correctly identifies the matches" do
+            matches.should eql(L[*expected_matches])
+          end
+
+          it "correctly identifies the remainder" do
+            remainder.should eql(L[*expected_remainder])
+          end
+        end
+
+        context "without a block" do
+          it "returns an Enumerator" do
+            list.partition.class.should be(Enumerator)
+            list.partition.each(&:odd?).should eql([L[*expected_matches], L[*expected_remainder]])
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/permutation_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/permutation_spec.rb
new file mode 100755
index 0000000..4bfdee5
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/permutation_spec.rb
@@ -0,0 +1,56 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#permutation" do
+    let(:list) { L[1,2,3,4] }
+
+    context "with no block" do
+      it "returns an Enumerator" do
+        list.permutation.class.should be(Enumerator)
+        list.permutation.to_a.sort.should == [1,2,3,4].permutation.to_a.sort
+      end
+    end
+
+    context "with no argument" do
+      it "yields all permutations of the list" do
+        perms = list.permutation.to_a
+        perms.size.should be(24)
+        perms.sort.should == [1,2,3,4].permutation.to_a.sort
+        perms.each { |item| item.should be_kind_of(Hamster::List) }
+      end
+    end
+
+    context "with a length argument" do
+      it "yields all N-size permutations of the list" do
+        perms = list.permutation(2).to_a
+        perms.size.should be(12)
+        perms.sort.should == [1,2,3,4].permutation(2).to_a.sort
+        perms.each { |item| item.should be_kind_of(Hamster::List) }
+      end
+    end
+
+    context "with a length argument greater than length of list" do
+      it "yields nothing" do
+        list.permutation(5).to_a.should be_empty
+      end
+    end
+
+    context "with a length argument of 0" do
+      it "yields an empty list" do
+        perms = list.permutation(0).to_a
+        perms.size.should be(1)
+        perms[0].should be_kind_of(Hamster::List)
+        perms[0].should be_empty
+      end
+    end
+
+    context "with a block" do
+      it "returns the original list" do
+        list.permutation(0) {}.should be(list)
+        list.permutation(1) {}.should be(list)
+        list.permutation {}.should be(list)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/pop_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/pop_spec.rb
new file mode 100755
index 0000000..3d361b5
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/pop_spec.rb
@@ -0,0 +1,26 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  let(:list) { L[*values] }
+
+  describe "#pop" do
+    let(:pop) { list.pop }
+
+    context "with an empty list" do
+      let(:values) { [] }
+
+      it "returns an empty list" do
+        expect(pop).to eq(L.empty)
+      end
+    end
+
+    context "with a list with a few items" do
+      let(:values) { %w[a b c] }
+
+      it "removes the last item" do
+        expect(pop).to eq(L["a", "b"])
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/product_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/product_spec.rb
new file mode 100755
index 0000000..42b1a0c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/product_spec.rb
@@ -0,0 +1,24 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#product" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).product }.should_not raise_error
+      end
+    end
+
+    [
+      [[], 1],
+      [[2], 2],
+      [[1, 3, 5, 7, 11], 1155],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        it "returns #{expected.inspect}" do
+          L[*values].product.should == expected
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/reduce_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/reduce_spec.rb
new file mode 100755
index 0000000..69d1693
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/reduce_spec.rb
@@ -0,0 +1,54 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [:reduce, :inject].each do |method|
+    describe "##{method}" do
+      context "on a really big list" do
+        it "doesn't run out of stack" do
+          -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).send(method, &:+) }.should_not raise_error
+        end
+      end
+
+      [
+        [[], 10, 10],
+        [[1], 10, 9],
+        [[1, 2, 3], 10, 4],
+      ].each do |values, initial, expected|
+        context "on #{values.inspect}" do
+          context "with an initial value of #{initial} and a block" do
+            it "returns #{expected.inspect}" do
+              L[*values].send(method, initial) { |memo, item| memo - item }.should == expected
+            end
+          end
+        end
+      end
+
+      [
+        [[], nil],
+        [[1], 1],
+        [[1, 2, 3], -4],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          context "with no initial value and a block" do
+            it "returns #{expected.inspect}" do
+              L[*values].send(method) { |memo, item| memo - item }.should == expected
+            end
+          end
+        end
+      end
+
+      context "with no block and a symbol argument" do
+        it "uses the symbol as the name of a method to reduce with" do
+          L[1, 2, 3].send(method, :+).should == 6
+        end
+      end
+
+      context "with no block and a string argument" do
+        it "uses the string as the name of a method to reduce with" do
+          L[1, 2, 3].send(method, '+').should == 6
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/reject_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/reject_spec.rb
new file mode 100755
index 0000000..35adf43
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/reject_spec.rb
@@ -0,0 +1,46 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [:reject, :delete_if].each do |method|
+    describe "##{method}" do
+      it "is lazy" do
+        -> { Hamster.stream { fail }.send(method) { |item| false } }.should_not raise_error
+      end
+
+      [
+        [[], []],
+        [["A"], ["A"]],
+        [%w[A B C], %w[A B C]],
+        [%w[A b C], %w[A C]],
+        [%w[a b c], []],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          let(:list) { L[*values] }
+
+          context "with a block" do
+            it "returns #{expected.inspect}" do
+              list.send(method) { |item| item == item.downcase }.should eql(L[*expected])
+            end
+
+            it "is lazy" do
+              count = 0
+              list.send(method) do |item|
+                count += 1
+                false
+              end
+              count.should <= 1
+            end
+          end
+
+          context "without a block" do
+            it "returns an Enumerator" do
+              list.send(method).class.should be(Enumerator)
+              list.send(method).each { |item| item == item.downcase }.should eql(L[*expected])
+            end
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/reverse_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/reverse_spec.rb
new file mode 100755
index 0000000..b07fe61
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/reverse_spec.rb
@@ -0,0 +1,35 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#reverse" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).reverse }.should_not raise_error
+      end
+    end
+
+    it "is lazy" do
+      -> { Hamster.stream { fail }.reverse }.should_not raise_error
+    end
+
+    [
+      [[], []],
+      [["A"], ["A"]],
+      [%w[A B C], %w[C B A]],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.reverse { |item| item.downcase }
+          list.should eql(L[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          list.reverse { |item| item.downcase }.should == L[*expected]
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/rotate_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/rotate_spec.rb
new file mode 100755
index 0000000..c0566f4
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/rotate_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#rotate" do
+    let(:list) { L[1,2,3,4,5] }
+
+    context "when passed no argument" do
+      it "returns a new list with the first element moved to the end" do
+        list.rotate.should eql(L[2,3,4,5,1])
+      end
+    end
+
+    context "with an integral argument n" do
+      it "returns a new list with the first (n % size) elements moved to the end" do
+        list.rotate(2).should eql(L[3,4,5,1,2])
+        list.rotate(3).should eql(L[4,5,1,2,3])
+        list.rotate(4).should eql(L[5,1,2,3,4])
+        list.rotate(5).should eql(L[1,2,3,4,5])
+        list.rotate(-1).should eql(L[5,1,2,3,4])
+      end
+    end
+
+    context "with a non-numeric argument" do
+      it "raises a TypeError" do
+        -> { list.rotate('hello') }.should raise_error(TypeError)
+      end
+    end
+
+    context "with an argument of zero (or one evenly divisible by list length)" do
+      it "it returns self" do
+        list.rotate(0).should be(list)
+        list.rotate(5).should be(list)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/sample_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/sample_spec.rb
new file mode 100755
index 0000000..d209769
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/sample_spec.rb
@@ -0,0 +1,14 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#sample" do
+    let(:list) { (1..10).to_list }
+
+    it "returns a randomly chosen item" do
+      chosen = 100.times.map { list.sample }
+      chosen.each { |item| list.include?(item).should == true }
+      list.each { |item| chosen.include?(item).should == true }
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/select_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/select_spec.rb
new file mode 100755
index 0000000..d94bbab
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/select_spec.rb
@@ -0,0 +1,71 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  let(:list) { L[*values] }
+  let(:selected_list) { L[*selected_values] }
+
+  describe "#select" do
+    it "is lazy" do
+      expect { Hamster.stream { fail }.select { |item| false } }.to_not raise_error
+    end
+
+    shared_examples "checking values" do
+      context "with a block" do
+        let(:select) { list.select { |item| item == item.upcase } }
+
+        it "preserves the original" do
+          expect(list).to eq(L[*values])
+        end
+
+        it "returns the selected list" do
+          expect(select).to eq(selected_list)
+        end
+      end
+
+      context "without a block" do
+        let(:select) { list.select }
+
+        it "returns an Enumerator" do
+          expect(select.class).to be(Enumerator)
+          expect(select.each { |item| item == item.upcase }).to eq(selected_list)
+        end
+      end
+    end
+
+    context "with an empty array" do
+      let(:values) { [] }
+      let(:selected_values) { [] }
+
+      include_examples "checking values"
+    end
+
+    context "with a single item array" do
+      let(:values) { ["A"] }
+      let(:selected_values) { ["A"] }
+
+      include_examples "checking values"
+    end
+
+    context "with a multi-item array" do
+      let(:values) { %w[A B] }
+      let(:selected_values) { %w[A B] }
+
+      include_examples "checking values"
+    end
+
+    context "with a multi-item single selectable array" do
+      let(:values) { %w[A b] }
+      let(:selected_values) { ["A"] }
+
+      include_examples "checking values"
+    end
+
+    context "with a multi-item multi-selectable array" do
+      let(:values) { %w[a b] }
+      let(:selected_values) { [] }
+
+      include_examples "checking values"
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/size_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/size_spec.rb
new file mode 100755
index 0000000..9e7c1c8
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/size_spec.rb
@@ -0,0 +1,26 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [:size, :length].each do |method|
+    describe "##{method}" do
+      context "on a really big list" do
+        it "doesn't run out of stack" do
+          -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).size }.should_not raise_error
+        end
+      end
+
+      [
+        [[], 0],
+        [["A"], 1],
+        [%w[A B C], 3],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            L[*values].send(method).should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/slice_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/slice_spec.rb
new file mode 100755
index 0000000..a931fc6
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/slice_spec.rb
@@ -0,0 +1,230 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  let(:list) { L[1,2,3,4] }
+  let(:big)  { (1..10000).to_list }
+
+  [:slice, :[]].each do |method|
+    describe "##{method}" do
+      context "when passed a positive integral index" do
+        it "returns the element at that index" do
+          list.send(method, 0).should be(1)
+          list.send(method, 1).should be(2)
+          list.send(method, 2).should be(3)
+          list.send(method, 3).should be(4)
+          list.send(method, 4).should be(nil)
+          list.send(method, 10).should be(nil)
+
+          big.send(method, 0).should be(1)
+          big.send(method, 9999).should be(10000)
+        end
+
+        it "leaves the original unchanged" do
+          list.should eql(L[1,2,3,4])
+        end
+      end
+
+      context "when passed a negative integral index" do
+        it "returns the element which is number (index.abs) counting from the end of the list" do
+          list.send(method, -1).should be(4)
+          list.send(method, -2).should be(3)
+          list.send(method, -3).should be(2)
+          list.send(method, -4).should be(1)
+          list.send(method, -5).should be(nil)
+          list.send(method, -10).should be(nil)
+
+          big.send(method, -1).should be(10000)
+          big.send(method, -10000).should be(1)
+        end
+      end
+
+      context "when passed a positive integral index and count" do
+        it "returns 'count' elements starting from 'index'" do
+          list.send(method, 0, 0).should eql(L.empty)
+          list.send(method, 0, 1).should eql(L[1])
+          list.send(method, 0, 2).should eql(L[1,2])
+          list.send(method, 0, 4).should eql(L[1,2,3,4])
+          list.send(method, 0, 6).should eql(L[1,2,3,4])
+          list.send(method, 0, -1).should be_nil
+          list.send(method, 0, -2).should be_nil
+          list.send(method, 0, -4).should be_nil
+          list.send(method, 2, 0).should eql(L.empty)
+          list.send(method, 2, 1).should eql(L[3])
+          list.send(method, 2, 2).should eql(L[3,4])
+          list.send(method, 2, 4).should eql(L[3,4])
+          list.send(method, 2, -1).should be_nil
+          list.send(method, 4, 0).should eql(L.empty)
+          list.send(method, 4, 2).should eql(L.empty)
+          list.send(method, 4, -1).should be_nil
+          list.send(method, 5, 0).should be_nil
+          list.send(method, 5, 2).should be_nil
+          list.send(method, 5, -1).should be_nil
+          list.send(method, 6, 0).should be_nil
+          list.send(method, 6, 2).should be_nil
+          list.send(method, 6, -1).should be_nil
+
+          big.send(method, 0, 3).should eql(L[1,2,3])
+          big.send(method, 1023, 4).should eql(L[1024,1025,1026,1027])
+          big.send(method, 1024, 4).should eql(L[1025,1026,1027,1028])
+        end
+
+        it "leaves the original unchanged" do
+          list.should eql(L[1,2,3,4])
+        end
+      end
+
+      context "when passed a negative integral index and count" do
+        it "returns 'count' elements, starting from index which is number 'index.abs' counting from the end of the array" do
+          list.send(method, -1, 0).should eql(L.empty)
+          list.send(method, -1, 1).should eql(L[4])
+          list.send(method, -1, 2).should eql(L[4])
+          list.send(method, -1, -1).should be_nil
+          list.send(method, -2, 0).should eql(L.empty)
+          list.send(method, -2, 1).should eql(L[3])
+          list.send(method, -2, 2).should eql(L[3,4])
+          list.send(method, -2, 4).should eql(L[3,4])
+          list.send(method, -2, -1).should be_nil
+          list.send(method, -4, 0).should eql(L.empty)
+          list.send(method, -4, 1).should eql(L[1])
+          list.send(method, -4, 2).should eql(L[1,2])
+          list.send(method, -4, 4).should eql(L[1,2,3,4])
+          list.send(method, -4, 6).should eql(L[1,2,3,4])
+          list.send(method, -4, -1).should be_nil
+          list.send(method, -5, 0).should be_nil
+          list.send(method, -5, 1).should be_nil
+          list.send(method, -5, 10).should be_nil
+          list.send(method, -5, -1).should be_nil
+
+          big.send(method, -1, 1).should eql(L[10000])
+          big.send(method, -1, 2).should eql(L[10000])
+          big.send(method, -6, 2).should eql(L[9995,9996])
+        end
+      end
+
+      context "when passed a Range" do
+        it "returns the elements whose indexes are within the given Range" do
+          list.send(method, 0..-1).should eql(L[1,2,3,4])
+          list.send(method, 0..-10).should eql(L.empty)
+          list.send(method, 0..0).should eql(L[1])
+          list.send(method, 0..1).should eql(L[1,2])
+          list.send(method, 0..2).should eql(L[1,2,3])
+          list.send(method, 0..3).should eql(L[1,2,3,4])
+          list.send(method, 0..4).should eql(L[1,2,3,4])
+          list.send(method, 0..10).should eql(L[1,2,3,4])
+          list.send(method, 2..-10).should eql(L.empty)
+          list.send(method, 2..0).should eql(L.empty)
+          list.send(method, 2..2).should eql(L[3])
+          list.send(method, 2..3).should eql(L[3,4])
+          list.send(method, 2..4).should eql(L[3,4])
+          list.send(method, 3..0).should eql(L.empty)
+          list.send(method, 3..3).should eql(L[4])
+          list.send(method, 3..4).should eql(L[4])
+          list.send(method, 4..0).should eql(L.empty)
+          list.send(method, 4..4).should eql(L.empty)
+          list.send(method, 4..5).should eql(L.empty)
+          list.send(method, 5..0).should be_nil
+          list.send(method, 5..5).should be_nil
+          list.send(method, 5..6).should be_nil
+
+          big.send(method, 159..162).should eql(L[160,161,162,163])
+          big.send(method, 160..162).should eql(L[161,162,163])
+          big.send(method, 161..162).should eql(L[162,163])
+          big.send(method, 9999..10100).should eql(L[10000])
+          big.send(method, 10000..10100).should eql(L.empty)
+          big.send(method, 10001..10100).should be_nil
+
+          list.send(method, 0...-1).should eql(L[1,2,3])
+          list.send(method, 0...-10).should eql(L.empty)
+          list.send(method, 0...0).should eql(L.empty)
+          list.send(method, 0...1).should eql(L[1])
+          list.send(method, 0...2).should eql(L[1,2])
+          list.send(method, 0...3).should eql(L[1,2,3])
+          list.send(method, 0...4).should eql(L[1,2,3,4])
+          list.send(method, 0...10).should eql(L[1,2,3,4])
+          list.send(method, 2...-10).should eql(L.empty)
+          list.send(method, 2...0).should eql(L.empty)
+          list.send(method, 2...2).should eql(L.empty)
+          list.send(method, 2...3).should eql(L[3])
+          list.send(method, 2...4).should eql(L[3,4])
+          list.send(method, 3...0).should eql(L.empty)
+          list.send(method, 3...3).should eql(L.empty)
+          list.send(method, 3...4).should eql(L[4])
+          list.send(method, 4...0).should eql(L.empty)
+          list.send(method, 4...4).should eql(L.empty)
+          list.send(method, 4...5).should eql(L.empty)
+          list.send(method, 5...0).should be_nil
+          list.send(method, 5...5).should be_nil
+          list.send(method, 5...6).should be_nil
+
+          big.send(method, 159...162).should eql(L[160,161,162])
+          big.send(method, 160...162).should eql(L[161,162])
+          big.send(method, 161...162).should eql(L[162])
+          big.send(method, 9999...10100).should eql(L[10000])
+          big.send(method, 10000...10100).should eql(L.empty)
+          big.send(method, 10001...10100).should be_nil
+
+          list.send(method, -1..-1).should eql(L[4])
+          list.send(method, -1...-1).should eql(L.empty)
+          list.send(method, -1..3).should eql(L[4])
+          list.send(method, -1...3).should eql(L.empty)
+          list.send(method, -1..4).should eql(L[4])
+          list.send(method, -1...4).should eql(L[4])
+          list.send(method, -1..10).should eql(L[4])
+          list.send(method, -1...10).should eql(L[4])
+          list.send(method, -1..0).should eql(L.empty)
+          list.send(method, -1..-4).should eql(L.empty)
+          list.send(method, -1...-4).should eql(L.empty)
+          list.send(method, -1..-6).should eql(L.empty)
+          list.send(method, -1...-6).should eql(L.empty)
+          list.send(method, -2..-2).should eql(L[3])
+          list.send(method, -2...-2).should eql(L.empty)
+          list.send(method, -2..-1).should eql(L[3,4])
+          list.send(method, -2...-1).should eql(L[3])
+          list.send(method, -2..10).should eql(L[3,4])
+          list.send(method, -2...10).should eql(L[3,4])
+
+          big.send(method, -1..-1).should eql(L[10000])
+          big.send(method, -1..9999).should eql(L[10000])
+          big.send(method, -1...9999).should eql(L.empty)
+          big.send(method, -2...9999).should eql(L[9999])
+          big.send(method, -2..-1).should eql(L[9999,10000])
+
+          list.send(method, -4..-4).should eql(L[1])
+          list.send(method, -4..-2).should eql(L[1,2,3])
+          list.send(method, -4...-2).should eql(L[1,2])
+          list.send(method, -4..-1).should eql(L[1,2,3,4])
+          list.send(method, -4...-1).should eql(L[1,2,3])
+          list.send(method, -4..3).should eql(L[1,2,3,4])
+          list.send(method, -4...3).should eql(L[1,2,3])
+          list.send(method, -4..4).should eql(L[1,2,3,4])
+          list.send(method, -4...4).should eql(L[1,2,3,4])
+          list.send(method, -4..0).should eql(L[1])
+          list.send(method, -4...0).should eql(L.empty)
+          list.send(method, -4..1).should eql(L[1,2])
+          list.send(method, -4...1).should eql(L[1])
+
+          list.send(method, -5..-5).should be_nil
+          list.send(method, -5...-5).should be_nil
+          list.send(method, -5..-4).should be_nil
+          list.send(method, -5..-1).should be_nil
+          list.send(method, -5..10).should be_nil
+
+          big.send(method, -10001..-1).should be_nil
+        end
+
+        it "leaves the original unchanged" do
+          list.should eql(L[1,2,3,4])
+        end
+      end
+    end
+
+    context "when passed a subclass of Range" do
+      it "works the same as with a Range" do
+        subclass = Class.new(Range)
+        list.send(method, subclass.new(1,2)).should eql(L[2,3])
+        list.send(method, subclass.new(-3,-1,true)).should eql(L[2,3])
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/sorting_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/sorting_spec.rb
new file mode 100755
index 0000000..1de5f91
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/sorting_spec.rb
@@ -0,0 +1,47 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [
+    [:sort, ->(left, right) { left.length <=> right.length }],
+    [:sort_by, ->(item) { item.length }],
+  ].each do |method, comparator|
+    describe "##{method}" do
+      it "is lazy" do
+        -> { Hamster.stream { fail }.send(method, &comparator) }.should_not raise_error
+      end
+
+      [
+        [[], []],
+        [["A"], ["A"]],
+        [%w[Ichi Ni San], %w[Ni San Ichi]],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          let(:list) { L[*values] }
+
+          context "with a block" do
+            it "preserves the original" do
+              list.send(method, &comparator)
+              list.should == L[*values]
+            end
+
+            it "returns #{expected.inspect}" do
+              list.send(method, &comparator).should == L[*expected]
+            end
+          end
+
+          context "without a block" do
+            it "preserves the original" do
+              list.send(method)
+              list.should eql(L[*values])
+            end
+
+            it "returns #{expected.sort.inspect}" do
+              list.send(method).should == L[*expected.sort]
+            end
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/span_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/span_spec.rb
new file mode 100755
index 0000000..abf56fa
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/span_spec.rb
@@ -0,0 +1,77 @@
+require "spec_helper"
+require "hamster/list"
+
+describe "Hamster::list#span" do
+  it "is lazy" do
+    -> { Hamster.stream { |item| fail }.span { true } }.should_not raise_error
+  end
+
+  describe <<-DESC do
+given a predicate (in the form of a block), splits the list into two lists
+  (returned as an array) such that elements in the first list (the prefix) are
+  taken from the head of the list while the predicate is satisfied, and elements
+  in the second list (the remainder) are the remaining elements from the list
+  once the predicate is not satisfied. For example:
+DESC
+
+    [
+      [[], [], []],
+      [[1], [1], []],
+      [[1, 2], [1, 2], []],
+      [[1, 2, 3], [1, 2], [3]],
+      [[1, 2, 3, 4], [1, 2], [3, 4]],
+      [[2, 3, 4], [2], [3, 4]],
+      [[3, 4], [], [3, 4]],
+      [[4], [], [4]],
+    ].each do |values, expected_prefix, expected_remainder|
+      context "given the list #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        context "and a predicate that returns true for values <= 2" do
+          let(:result) { list.span { |item| item <= 2 }}
+          let(:prefix) { result.first }
+          let(:remainder) { result.last }
+
+          it "preserves the original" do
+            result
+            list.should eql(L[*values])
+          end
+
+          it "returns the prefix as #{expected_prefix.inspect}" do
+            prefix.should eql(L[*expected_prefix])
+          end
+
+          it "returns the remainder as #{expected_remainder.inspect}" do
+            remainder.should eql(L[*expected_remainder])
+          end
+
+          it "calls the block only once for each element" do
+            count = 0
+            result = list.span { |item| count += 1; item <= 2 }
+            # force realization of lazy lists
+            result.first.size.should == expected_prefix.size
+            result.last.size.should == expected_remainder.size
+            # it may not need to call the block on every element, just up to the
+            # point where the block first returns a false value
+            count.should <= values.size
+          end
+        end
+
+        context "without a predicate" do
+          it "returns a frozen array" do
+            list.span.class.should be(Array)
+            list.span.should be_frozen
+          end
+
+          it "returns self as the prefix" do
+            list.span.first.should equal(list)
+          end
+
+          it "returns an empty list as the remainder" do
+            list.span.last.should be_empty
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/split_at_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/split_at_spec.rb
new file mode 100755
index 0000000..5b4b8b9
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/split_at_spec.rb
@@ -0,0 +1,44 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#split_at" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.split_at(1) }.should_not raise_error
+    end
+
+    [
+      [[], [], []],
+      [[1], [1], []],
+      [[1, 2], [1, 2], []],
+      [[1, 2, 3], [1, 2], [3]],
+      [[1, 2, 3, 4], [1, 2], [3, 4]],
+    ].each do |values, expected_prefix, expected_remainder|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+        let(:result) { list.split_at(2) }
+        let(:prefix) { result.first }
+        let(:remainder) { result.last }
+
+        it "preserves the original" do
+          result
+          list.should eql(L[*values])
+        end
+
+        it "returns a frozen array with two items" do
+          result.class.should be(Array)
+          result.should be_frozen
+          result.size.should be(2)
+        end
+
+        it "correctly identifies the matches" do
+          prefix.should eql(L[*expected_prefix])
+        end
+
+        it "correctly identifies the remainder" do
+          remainder.should eql(L[*expected_remainder])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/subsequences_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/subsequences_spec.rb
new file mode 100755
index 0000000..3759b79
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/subsequences_spec.rb
@@ -0,0 +1,24 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#subsequences" do
+    let(:list) { L[1,2,3,4,5] }
+
+    it "yields all sublists with 1 or more consecutive items" do
+      result = []
+      list.subsequences { |l| result << l }
+      result.size.should == (5 + 4 + 3 + 2 + 1)
+      result.sort.should == [[1], [1,2], [1,2,3], [1,2,3,4], [1,2,3,4,5],
+        [2], [2,3], [2,3,4], [2,3,4,5], [3], [3,4], [3,4,5], [4], [4,5], [5]]
+    end
+
+    context "with no block" do
+      it "returns an Enumerator" do
+        list.subsequences.class.should be(Enumerator)
+        list.subsequences.to_a.sort.should == [[1], [1,2], [1,2,3], [1,2,3,4], [1,2,3,4,5],
+        [2], [2,3], [2,3,4], [2,3,4,5], [3], [3,4], [3,4,5], [4], [4,5], [5]]
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/sum_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/sum_spec.rb
new file mode 100755
index 0000000..d969a15
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/sum_spec.rb
@@ -0,0 +1,24 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#sum" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).sum }.should_not raise_error
+      end
+    end
+
+    [
+      [[], 0],
+      [[2], 2],
+      [[1, 3, 5, 7, 11], 27],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        it "returns #{expected.inspect}" do
+          L[*values].sum.should == expected
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/tail_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/tail_spec.rb
new file mode 100755
index 0000000..a95e776
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/tail_spec.rb
@@ -0,0 +1,31 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#tail" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).select(&:nil?).tail }.should_not raise_error
+      end
+    end
+
+    [
+      [[], []],
+      [["A"], []],
+      [%w[A B C], %w[B C]],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.tail
+          list.should eql(L[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          list.tail.should eql(L[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/tails_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/tails_spec.rb
new file mode 100755
index 0000000..c79fae0
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/tails_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#tails" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.tails }.should_not raise_error
+    end
+
+    [
+      [[], []],
+      [["A"], [L["A"]]],
+      [%w[A B C], [L["A", "B", "C"], L["B", "C"], L["C"]]],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.tails
+          list.should eql(L[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          list.tails.should eql(L[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/take_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/take_spec.rb
new file mode 100755
index 0000000..25c37c9
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/take_spec.rb
@@ -0,0 +1,31 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#take" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.take(1) }.should_not raise_error
+    end
+
+    [
+      [[], 10, []],
+      [["A"], 10, ["A"]],
+      [["A"], -1, []],
+      [%w[A B C], 0, []],
+      [%w[A B C], 2, %w[A B]],
+    ].each do |values, number, expected|
+      context "#{number} from #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.take(number)
+          list.should eql(L[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          list.take(number).should eql(L[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/take_while_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/take_while_spec.rb
new file mode 100755
index 0000000..508a537
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/take_while_spec.rb
@@ -0,0 +1,47 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#take_while" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.take_while { false } }.should_not raise_error
+    end
+
+    [
+      [[], []],
+      [["A"], ["A"]],
+      [%w[A B C], %w[A B]],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        context "with a block" do
+          it "returns #{expected.inspect}" do
+            list.take_while { |item| item < "C" }.should eql(L[*expected])
+          end
+
+          it "preserves the original" do
+            list.take_while { |item| item < "C" }
+            list.should eql(L[*values])
+          end
+
+          it "is lazy" do
+            count = 0
+            list.take_while do |item|
+              count += 1
+              true
+            end
+            count.should <= 1
+          end
+        end
+
+        context "without a block" do
+          it "returns an Enumerator" do
+            list.take_while.class.should be(Enumerator)
+            list.take_while.each { |item| item < "C" }.should eql(L[*expected])
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/to_a_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/to_a_spec.rb
new file mode 100755
index 0000000..23f0464
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/to_a_spec.rb
@@ -0,0 +1,40 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [:to_a, :entries].each do |method|
+    describe "##{method}" do
+      context "on a really big list" do
+        it "doesn't run out of stack" do
+          -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).to_a }.should_not raise_error
+        end
+      end
+
+      [
+        [],
+        ["A"],
+        %w[A B C],
+      ].each do |values|
+        context "on #{values.inspect}" do
+          let(:list) { L[*values] }
+
+          it "returns #{values.inspect}" do
+            list.send(method).should == values
+          end
+
+          it "leaves the original unchanged" do
+            list.send(method)
+            list.should eql(L[*values])
+          end
+
+          it "returns a mutable array" do
+            result = list.send(method)
+            expect(result.last).to_not eq("The End")
+            result << "The End"
+            result.last.should == "The End"
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/to_ary_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/to_ary_spec.rb
new file mode 100755
index 0000000..fa6b215
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/to_ary_spec.rb
@@ -0,0 +1,42 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  let(:list) { L["A", "B", "C", "D"] }
+
+  describe "#to_ary" do
+    context "on a really big list" do
+      it "doesn't run out of stack" do
+        -> { Hamster.interval(0, STACK_OVERFLOW_DEPTH).to_ary }.should_not raise_error
+      end
+    end
+
+    context "enables implicit conversion to" do
+      it "block parameters" do
+        def func(&block)
+          yield(list)
+        end
+
+        func do |a, b, *c|
+          expect(a).to eq("A")
+          expect(b).to eq("B")
+          expect(c).to eq(%w[C D])
+        end
+      end
+
+      it "method arguments" do
+        def func(a, b, *c)
+          expect(a).to eq("A")
+          expect(b).to eq("B")
+          expect(c).to eq(%w[C D])
+        end
+        func(*list)
+      end
+
+      it "works with splat" do
+        array = *list
+        expect(array).to eq(%w[A B C D])
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/to_list_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/to_list_spec.rb
new file mode 100755
index 0000000..d01f72a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/to_list_spec.rb
@@ -0,0 +1,20 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#to_list" do
+    [
+      [],
+      ["A"],
+      %w[A B C],
+    ].each do |values|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        it "returns self" do
+          list.to_list.should equal(list)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/to_set_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/to_set_spec.rb
new file mode 100755
index 0000000..10af4ca
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/to_set_spec.rb
@@ -0,0 +1,19 @@
+require "spec_helper"
+require "hamster/list"
+require "hamster/set"
+
+describe Hamster::List do
+  describe "#to_set" do
+    [
+      [],
+      ["A"],
+      %w[A B C],
+    ].each do |values|
+      context "on #{values.inspect}" do
+        it "returns a set with the same values" do
+          L[*values].to_set.should eql(S[*values])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/transpose_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/transpose_spec.rb
new file mode 100755
index 0000000..8053f8c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/transpose_spec.rb
@@ -0,0 +1,20 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#transpose" do
+    it "takes a list of lists and returns a list of all the first elements, all the 2nd elements, and so on" do
+      L[L[1, 'a'], L[2, 'b'], L[3, 'c']].transpose.should eql(L[L[1, 2, 3], L["a", "b", "c"]])
+      L[L[1, 2, 3], L["a", "b", "c"]].transpose.should eql(L[L[1, 'a'], L[2, 'b'], L[3, 'c']])
+      L[].transpose.should eql(L[])
+      L[L[]].transpose.should eql(L[])
+      L[L[], L[]].transpose.should eql(L[])
+      L[L[0]].transpose.should eql(L[L[0]])
+      L[L[0], L[1]].transpose.should eql(L[L[0, 1]])
+    end
+
+    it "only goes as far as the shortest list" do
+      L[L[1,2,3], L[2]].transpose.should eql(L[L[1,2]])
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/union_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/union_spec.rb
new file mode 100755
index 0000000..997d676
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/union_spec.rb
@@ -0,0 +1,32 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  [:union, :|].each do |method|
+    describe "##{method}" do
+      it "is lazy" do
+        -> { Hamster.stream { fail }.union(Hamster.stream { fail }) }.should_not raise_error
+      end
+
+      [
+        [[], [], []],
+        [["A"], [], ["A"]],
+        [%w[A B C], [], %w[A B C]],
+        [%w[A A], ["A"], ["A"]],
+      ].each do |a, b, expected|
+        context "returns #{expected.inspect}" do
+          let(:list_a) { L[*a] }
+          let(:list_b) { L[*b] }
+
+          it "for #{a.inspect} and #{b.inspect}"  do
+            list_a.send(method, list_b).should eql(L[*expected])
+          end
+
+          it "for #{b.inspect} and #{a.inspect}"  do
+            list_b.send(method, list_a).should eql(L[*expected])
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/uniq_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/uniq_spec.rb
new file mode 100755
index 0000000..cabbe88
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/uniq_spec.rb
@@ -0,0 +1,36 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#uniq" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.uniq }.should_not raise_error
+    end
+
+    context "when passed a block" do
+      it "uses the block to identify duplicates" do
+        L["a", "A", "b"].uniq(&:upcase).should eql(Hamster::List["a", "b"])
+      end
+    end
+
+    [
+      [[], []],
+      [["A"], ["A"]],
+      [%w[A B C], %w[A B C]],
+      [%w[A B A C C], %w[A B C]],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:list) { L[*values] }
+
+        it "preserves the original" do
+          list.uniq
+          list.should eql(L[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          list.uniq.should eql(L[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/zip_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/zip_spec.rb
new file mode 100755
index 0000000..e919bd3
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/list/zip_spec.rb
@@ -0,0 +1,24 @@
+require "spec_helper"
+require "hamster/list"
+
+describe Hamster::List do
+  describe "#zip" do
+    it "is lazy" do
+      -> { Hamster.stream { fail }.zip(Hamster.stream { fail }) }.should_not raise_error
+    end
+
+    [
+      [[], [], []],
+      [["A"], ["aye"], [L["A", "aye"]]],
+      [["A"], [], [L["A", nil]]],
+      [[], ["A"], [L[nil, "A"]]],
+      [%w[A B C], %w[aye bee see], [L["A", "aye"], L["B", "bee"], L["C", "see"]]],
+    ].each do |left, right, expected|
+      context "on #{left.inspect} and #{right.inspect}" do
+        it "returns #{expected.inspect}" do
+          L[*left].zip(L[*right]).should eql(L[*expected])
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/nested/construction_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/nested/construction_spec.rb
new file mode 100755
index 0000000..b54f501
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/nested/construction_spec.rb
@@ -0,0 +1,103 @@
+require "spec_helper"
+require "hamster/nested"
+require "hamster/deque"
+require "set"
+
+describe Hamster do
+  expectations = [
+    # [Ruby, Hamster]
+    [ { "a" => 1,
+        "b" => [2, {"c" => 3}, 4],
+        "d" => ::Set.new([5, 6, 7]),
+        "e" => {"f" => 8, "g" => 9},
+        "h" => Regexp.new("ijk"),
+        "l" => ::SortedSet.new([1, 2, 3]) },
+      Hamster::Hash[
+        "a" => 1,
+        "b" => Hamster::Vector[2, Hamster::Hash["c" => 3], 4],
+        "d" => Hamster::Set[5, 6, 7],
+        "e" => Hamster::Hash["f" => 8, "g" => 9],
+        "h" => Regexp.new("ijk"),
+        "l" => Hamster::SortedSet.new([1, 2, 3])] ],
+    [ {}, Hamster::Hash[] ],
+    [ {"a" => 1, "b" => 2, "c" => 3}, Hamster::Hash["a" => 1, "b" => 2, "c" => 3] ],
+    [ [], Hamster::Vector[] ],
+    [ [1, 2, 3], Hamster::Vector[1, 2, 3] ],
+    [ ::Set.new, Hamster::Set[] ],
+    [ ::Set.new([1, 2, 3]), Hamster::Set[1, 2, 3] ],
+    [ ::SortedSet.new, Hamster::SortedSet[] ],
+    [ ::SortedSet.new([1, 2, 3]), Hamster::SortedSet[1, 2, 3] ],
+    [ 42, 42 ],
+    [ STDOUT, STDOUT ],
+
+    # Struct conversion is one-way (from Ruby core Struct to Hamster::Hash), not back again!
+    [ Struct::Customer.new, Hamster::Hash[name: nil, address: nil], true ],
+    [ Struct::Customer.new('Dave', '123 Main'), Hamster::Hash[name: 'Dave', address: '123 Main'], true ]
+  ]
+
+  describe ".from" do
+    expectations.each do |input, expected_result|
+      context "with #{input.inspect} as input" do
+        it "should return #{expected_result.inspect}" do
+          Hamster.from(input).should eql(expected_result)
+        end
+      end
+    end
+
+    context "with mixed object" do
+      it "should return Hamster data" do
+        input = {
+          "a" => "b",
+          "c" => {"d" => "e"},
+          "f" => Hamster::Vector["g", "h", []],
+          "i" => Hamster::Hash["j" => {}, "k" => Hamster::Set[[], {}]] }
+        expected_result = Hamster::Hash[
+          "a" => "b",
+          "c" => Hamster::Hash["d" => "e"],
+          "f" => Hamster::Vector["g", "h", Hamster::EmptyVector],
+          "i" => Hamster::Hash["j" => Hamster::EmptyHash, "k" => Hamster::Set[Hamster::EmptyVector, Hamster::EmptyHash]] ]
+        Hamster.from(input).should eql(expected_result)
+      end
+    end
+  end
+
+  describe ".to_ruby" do
+    expectations.each do |expected_result, input, one_way|
+      unless one_way
+        context "with #{input.inspect} as input" do
+          it "should return #{expected_result.inspect}" do
+            Hamster.to_ruby(input).should eql(expected_result)
+          end
+        end
+      end
+    end
+
+    context "with Hamster::Deque[] as input" do
+      it "should return []" do
+        Hamster.to_ruby(Hamster::Deque[]).should eql([])
+      end
+    end
+
+    context "with Hamster::Deque[Hamster::Hash[\"a\" => 1]] as input" do
+      it "should return [{\"a\" => 1}]" do
+        Hamster.to_ruby(Hamster::Deque[Hamster::Hash["a" => 1]]).should eql([{"a" => 1}])
+      end
+    end
+
+    context "with mixed object" do
+      it "should return Ruby data structures" do
+        input = Hamster::Hash[
+          "a" => "b",
+          "c" => {"d" => "e"},
+          "f" => Hamster::Vector["g", "h"],
+          "i" => {"j" => Hamster::EmptyHash, "k" => Set.new([Hamster::EmptyVector, Hamster::EmptyHash])}]
+        expected_result = {
+          "a" => "b",
+          "c" => {"d" => "e"},
+          "f" => ["g", "h"],
+          "i" => {"j" => {}, "k" => Set.new([[], {}])} }
+        Hamster.to_ruby(input).should eql(expected_result)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/add_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/add_spec.rb
new file mode 100755
index 0000000..a04ee4d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/add_spec.rb
@@ -0,0 +1,78 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  let(:original) { S["A", "B", "C"] }
+
+  [:add, :<<].each do |method|
+    describe "##{method}" do
+      context "with a unique value" do
+        let(:result) { original.send(method, "D") }
+
+        it "preserves the original" do
+          result
+          original.should eql(S["A", "B", "C"])
+        end
+
+        it "returns a copy with the superset of values" do
+          result.should eql(S["A", "B", "C", "D"])
+        end
+      end
+
+      context "with a duplicate value" do
+        let(:result) { original.send(method, "C") }
+
+        it "preserves the original values" do
+          result
+          original.should eql(S["A", "B", "C"])
+        end
+
+        it "returns self" do
+          result.should equal(original)
+        end
+      end
+
+      it "can add nil to a set" do
+        original.add(nil).should eql(S["A", "B", "C", nil])
+      end
+
+      it "works on large sets, with many combinations of input" do
+        50.times do
+          # Array#sample is buggy on RBX 2.5.8; that's why #uniq is needed here
+          # See https://github.com/rubinius/rubinius/issues/3506
+          array = (1..500).to_a.sample(100).uniq
+          set   = S.new(array)
+          to_add = 1000 + rand(1000)
+          set.add(to_add).size.should == array.size + 1
+          set.add(to_add).include?(to_add).should == true
+        end
+      end
+    end
+  end
+
+  describe "#add?" do
+    context "with a unique value" do
+      let(:result) { original.add?("D") }
+
+      it "preserves the original" do
+        original.should eql(S["A", "B", "C"])
+      end
+
+      it "returns a copy with the superset of values" do
+        result.should eql(S["A", "B", "C", "D"])
+      end
+    end
+
+    context "with a duplicate value" do
+      let(:result) { original.add?("C") }
+
+      it "preserves the original values" do
+        original.should eql(S["A", "B", "C"])
+      end
+
+      it "returns false" do
+        result.should equal(false)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/all_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/all_spec.rb
new file mode 100755
index 0000000..96cdc44
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/all_spec.rb
@@ -0,0 +1,52 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#all?" do
+    context "when empty" do
+      it "with a block returns true" do
+        S.empty.all? {}.should == true
+      end
+
+      it "with no block returns true" do
+        S.empty.all?.should == true
+      end
+    end
+
+    context "when not empty" do
+      context "with a block" do
+        let(:set) { S["A", "B", "C"] }
+
+        it "returns true if the block always returns true" do
+          set.all? { |item| true }.should == true
+        end
+
+        it "returns false if the block ever returns false" do
+          set.all? { |item| item == "D" }.should == false
+        end
+
+        it "propagates an exception from the block" do
+          -> { set.all? { |k,v| raise "help" } }.should raise_error(RuntimeError)
+        end
+
+        it "stops iterating as soon as the block returns false" do
+          yielded = []
+          set.all? { |k,v| yielded << k; false }
+          yielded.size.should == 1
+        end
+      end
+
+      describe "with no block" do
+        it "returns true if all values are truthy" do
+          S[true, "A"].all?.should == true
+        end
+
+        [nil, false].each do |value|
+          it "returns false if any value is #{value.inspect}" do
+            S[value, true, "A"].all?.should == false
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/any_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/any_spec.rb
new file mode 100755
index 0000000..1c6cb34
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/any_spec.rb
@@ -0,0 +1,52 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#any?" do
+    context "when empty" do
+      it "with a block returns false" do
+        S.empty.any? {}.should == false
+      end
+
+      it "with no block returns false" do
+        S.empty.any?.should == false
+      end
+    end
+
+    context "when not empty" do
+      context "with a block" do
+        let(:set) { S["A", "B", "C", nil] }
+
+        ["A", "B", "C", nil].each do |value|
+          it "returns true if the block ever returns true (#{value.inspect})" do
+            set.any? { |item| item == value }.should == true
+          end
+        end
+
+        it "returns false if the block always returns false" do
+          set.any? { |item| item == "D" }.should == false
+        end
+
+        it "propagates exceptions raised in the block" do
+          -> { set.any? { |k,v| raise "help" } }.should raise_error(RuntimeError)
+        end
+
+        it "stops iterating as soon as the block returns true" do
+          yielded = []
+          set.any? { |k,v| yielded << k; true }
+          yielded.size.should == 1
+        end
+      end
+
+      context "with no block" do
+        it "returns true if any value is truthy" do
+          S[nil, false, true, "A"].any?.should == true
+        end
+
+        it "returns false if all values are falsey" do
+          S[nil, false].any?.should == false
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/clear_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/clear_spec.rb
new file mode 100755
index 0000000..dfdefad
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/clear_spec.rb
@@ -0,0 +1,34 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#clear" do
+    [
+      [],
+      ["A"],
+      %w[A B C],
+    ].each do |values|
+      describe "on #{values}" do
+        let(:set) { S[*values] }
+
+        it "preserves the original" do
+          set.clear
+          set.should eql(S[*values])
+        end
+
+        it "returns an empty set" do
+          set.clear.should equal(S.empty)
+        end
+      end
+    end
+
+    context "from a subclass" do
+      it "returns an empty instance of the subclass" do
+        subclass = Class.new(Hamster::Set)
+        instance = subclass.new([:a, :b, :c, :d])
+        instance.clear.class.should be(subclass)
+        instance.clear.should be_empty
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/compact_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/compact_spec.rb
new file mode 100755
index 0000000..9f419a1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/compact_spec.rb
@@ -0,0 +1,31 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#compact" do
+    [
+      [[], []],
+      [["A"], ["A"]],
+      [%w[A B C], %w[A B C]],
+      [[nil], []],
+      [[nil, "B"], ["B"]],
+      [["A", nil], ["A"]],
+      [[nil, nil], []],
+      [["A", nil, "C"], %w[A C]],
+      [[nil, "B", nil], ["B"]],
+    ].each do |values, expected|
+      describe "on #{values.inspect}" do
+        let(:set) { S[*values] }
+
+        it "preserves the original" do
+          set.compact
+          set.should eql(S[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          set.compact.should eql(S[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/construction_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/construction_spec.rb
new file mode 100755
index 0000000..82e84b4
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/construction_spec.rb
@@ -0,0 +1,19 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe ".set" do
+    context "with no values" do
+      it "returns the empty set" do
+        S.empty.should be_empty
+        S.empty.should equal(Hamster::EmptySet)
+      end
+    end
+
+    context "with a list of values" do
+      it "is equivalent to repeatedly using #add" do
+        S["A", "B", "C"].should eql(S.empty.add("A").add("B").add("C"))
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/copying_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/copying_spec.rb
new file mode 100755
index 0000000..49e5a4e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/copying_spec.rb
@@ -0,0 +1,14 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [:dup, :clone].each do |method|
+    let(:set) { S["A", "B", "C"] }
+
+    describe "##{method}" do
+      it "returns self" do
+        set.send(method).should equal(set)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/count_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/count_spec.rb
new file mode 100755
index 0000000..dcc5967
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/count_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#count" do
+    [
+      [[], 0],
+      [[1], 1],
+      [[1, 2], 1],
+      [[1, 2, 3], 2],
+      [[1, 2, 3, 4], 2],
+      [[1, 2, 3, 4, 5], 3],
+    ].each do |values, expected|
+      describe "on #{values.inspect}" do
+        let(:set) { S[*values] }
+
+        context "with a block" do
+          it "returns #{expected.inspect}" do
+            set.count(&:odd?).should == expected
+          end
+        end
+
+        context "without a block" do
+          it "returns length" do
+            set.count.should == set.length
+          end
+        end
+      end
+    end
+
+    it "works on large sets" do
+      set = Hamster::Set.new(1..2000)
+      set.count.should == 2000
+      set.count(&:odd?).should == 1000
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/delete_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/delete_spec.rb
new file mode 100755
index 0000000..6ca4a53
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/delete_spec.rb
@@ -0,0 +1,72 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  let(:set) { S["A", "B", "C"] }
+
+  describe "#delete" do
+    context "with an existing value" do
+      it "preserves the original" do
+        set.delete("B")
+        set.should eql(S["A", "B", "C"])
+      end
+
+      it "returns a copy with the remaining values" do
+        set.delete("B").should eql(S["A", "C"])
+      end
+    end
+
+    context "with a non-existing value" do
+      it "preserves the original values" do
+        set.delete("D")
+        set.should eql(S["A", "B", "C"])
+      end
+
+      it "returns self" do
+        set.delete("D").should equal(set)
+      end
+    end
+
+    context "when removing the last value in a set" do
+      it "returns the canonical empty set" do
+        set.delete("B").delete("C").delete("A").should be(Hamster::EmptySet)
+      end
+    end
+
+    it "works on large sets, with many combinations of input" do
+      array = 1000.times.map { %w[a b c d e f g h i j k l m n].sample(5).join }.uniq
+      set = S.new(array)
+      array.each do |key|
+        result = set.delete(key)
+        result.size.should == set.size - 1
+        result.include?(key).should == false
+        other = array.sample
+        (result.include?(other).should == true) if other != key
+      end
+    end
+  end
+
+  describe "#delete?" do
+    context "with an existing value" do
+      it "preserves the original" do
+        set.delete?("B")
+        set.should eql(S["A", "B", "C"])
+      end
+
+      it "returns a copy with the remaining values" do
+        set.delete?("B").should eql(S["A", "C"])
+      end
+    end
+
+    context "with a non-existing value" do
+      it "preserves the original values" do
+        set.delete?("D")
+        set.should eql(S["A", "B", "C"])
+      end
+
+      it "returns false" do
+        set.delete?("D").should be(false)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/difference_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/difference_spec.rb
new file mode 100755
index 0000000..16003c3
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/difference_spec.rb
@@ -0,0 +1,50 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [:difference, :subtract, :-].each do |method|
+    describe "##{method}" do
+      [
+        [[], [], []],
+        [["A"], [], ["A"]],
+        [["A"], ["A"], []],
+        [%w[A B C], ["B"], %w[A C]],
+        [%w[A B C], %w[A C], ["B"]],
+        [%w[A B C D E F G H], [], %w[A B C D E F G H]],
+        [%w[A B C M X Y Z], %w[B C D E F G H I J X], %w[A M Y Z]]
+      ].each do |a, b, expected|
+        context "for #{a.inspect} and #{b.inspect}" do
+          let(:set_a) { S[*a] }
+          let(:set_b) { S[*b] }
+          let(:result) { set_a.send(method, set_b) }
+
+          it "doesn't modify the original Sets" do
+            result
+            set_a.should eql(S.new(a))
+            set_b.should eql(S.new(b))
+          end
+
+          it "returns #{expected.inspect}"  do
+            result.should eql(S[*expected])
+          end
+        end
+
+        context "when passed a Ruby Array" do
+          it "returns the expected Set" do
+            S[*a].difference(b.freeze).should eql(S[*expected])
+          end
+        end
+      end
+
+      it "works on a wide variety of inputs" do
+        items = ('aa'..'zz').to_a
+        50.times do
+          array1 = items.sample(200)
+          array2 = items.sample(200)
+          result = S.new(array1).send(method, S.new(array2))
+          result.to_a.sort.should eql((array1 - array2).sort)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/disjoint_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/disjoint_spec.rb
new file mode 100755
index 0000000..b562964
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/disjoint_spec.rb
@@ -0,0 +1,26 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#disjoint?" do
+    [
+      [[], [], true],
+      [["A"], [], true],
+      [[], ["A"], true],
+      [["A"], ["A"], false],
+      [%w[A B C], ["B"], false],
+      [["B"], %w[A B C], false],
+      [%w[A B C], %w[D E], true],
+      [%w[F G H I], %w[A B C], true],
+      [%w[A B C], %w[A B C], false],
+      [%w[A B C], %w[A B C D], false],
+      [%w[D E F G], %w[A B C], true],
+    ].each do |a, b, expected|
+      describe "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}" do
+          S[*a].disjoint?(S[*b]).should be(expected)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/each_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/each_spec.rb
new file mode 100755
index 0000000..3fb45e5
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/each_spec.rb
@@ -0,0 +1,46 @@
+require "spec_helper"
+require "set"
+require "hamster/set"
+
+describe Hamster::Set do
+  let(:set) { S["A", "B", "C"] }
+
+  describe "#each" do
+    let(:each) { set.each(&block) }
+
+    context "without a block" do
+      let(:block) { nil }
+
+      it "returns an Enumerator" do
+        expect(each.class).to be(Enumerator)
+        expect(each.to_a).to eq(set.to_a)
+      end
+    end
+
+    context "with an empty block" do
+      let(:block) { ->(item) {} }
+
+      it "returns self" do
+        expect(each).to be(set)
+      end
+    end
+
+    context "with a block" do
+      let(:items)  { ::Set.new }
+      let(:values) { ::Set.new(%w[A B C]) }
+      let(:block)  { ->(item) { items << item } }
+      before(:each) { each }
+
+      it "yields all values" do
+        expect(items).to eq(values)
+      end
+    end
+
+    it "yields both of a pair of colliding keys" do
+      set = S[DeterministicHash.new('a', 1010), DeterministicHash.new('b', 1010)]
+      yielded = []
+      set.each { |obj| yielded << obj }
+      yielded.map(&:value).sort.should == ['a', 'b']
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/empty_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/empty_spec.rb
new file mode 100755
index 0000000..2fb14ee
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/empty_spec.rb
@@ -0,0 +1,45 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#empty?" do
+    [
+      [[], true],
+      [["A"], false],
+      [%w[A B C], false],
+      [[nil], false],
+      [[false], false]
+    ].each do |values, expected|
+      describe "on #{values.inspect}" do
+        it "returns #{expected.inspect}" do
+          S[*values].empty?.should == expected
+        end
+      end
+    end
+  end
+
+  describe ".empty" do
+    it "returns the canonical empty set" do
+      S.empty.should be_empty
+      S.empty.object_id.should be(S[].object_id)
+      S.empty.should be(Hamster::EmptySet)
+    end
+
+    context "from a subclass" do
+      it "returns an empty instance of the subclass" do
+        subclass = Class.new(Hamster::Set)
+        subclass.empty.class.should be(subclass)
+        subclass.empty.should be_empty
+      end
+
+      it "calls overridden #initialize when creating empty Set" do
+        subclass = Class.new(Hamster::Set) do
+          def initialize
+            @variable = 'value'
+          end
+        end
+        subclass.empty.instance_variable_get(:@variable).should == 'value'
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/eqeq_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/eqeq_spec.rb
new file mode 100755
index 0000000..6025a8a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/eqeq_spec.rb
@@ -0,0 +1,104 @@
+require "spec_helper"
+require "set"
+require "hamster/set"
+
+describe Hamster::Set do
+  let(:set) { S[*values] }
+  let(:comparison) { S[*comparison_values] }
+
+  describe "#==" do
+    let(:eqeq) { set == comparison }
+
+    shared_examples "comparing non-sets" do
+      let(:values) { %w[A B C] }
+
+      it "returns false" do
+        expect(eqeq).to eq(false)
+      end
+    end
+
+    context "when comparing to a standard set" do
+      let(:comparison) { ::Set.new(%w[A B C]) }
+
+      include_examples "comparing non-sets"
+    end
+
+    context "when comparing to a arbitrary object" do
+      let(:comparison) { Object.new }
+
+      include_examples "comparing non-sets"
+    end
+
+    context "with an empty set for each comparison" do
+      let(:values) { [] }
+      let(:comparison_values) { [] }
+
+      it "returns true" do
+        expect(eqeq).to eq(true)
+      end
+    end
+
+    context "with an empty set and a set with nil" do
+      let(:values) { [] }
+      let(:comparison_values) { [nil] }
+
+      it "returns false" do
+        expect(eqeq).to eq(false)
+      end
+    end
+
+    context "with a single item array and empty array" do
+      let(:values) { ["A"] }
+      let(:comparison_values) { [] }
+
+      it "returns false" do
+        expect(eqeq).to eq(false)
+      end
+    end
+
+    context "with matching single item array" do
+      let(:values) { ["A"] }
+      let(:comparison_values) { ["A"] }
+
+      it "returns true" do
+        expect(eqeq).to eq(true)
+      end
+    end
+
+    context "with mismatching single item array" do
+      let(:values) { ["A"] }
+      let(:comparison_values) { ["B"] }
+
+      it "returns false" do
+        expect(eqeq).to eq(false)
+      end
+    end
+
+    context "with a multi-item array and single item array" do
+      let(:values) { %w[A B] }
+      let(:comparison_values) { ["A"] }
+
+      it "returns false" do
+        expect(eqeq).to eq(false)
+      end
+    end
+
+    context "with matching multi-item array" do
+      let(:values) { %w[A B] }
+      let(:comparison_values) { %w[A B] }
+
+      it "returns true" do
+        expect(eqeq).to eq(true)
+      end
+    end
+
+    context "with a mismatching multi-item array" do
+      let(:values) { %w[A B] }
+      let(:comparison_values) { %w[B A] }
+
+      it "returns true" do
+        expect(eqeq).to eq(true)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/eql_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/eql_spec.rb
new file mode 100755
index 0000000..f123212
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/eql_spec.rb
@@ -0,0 +1,110 @@
+require "spec_helper"
+require "set"
+require "hamster/set"
+
+describe Hamster::Set do
+  let(:set) { S[*values] }
+  let(:comparison) { S[*comparison_values] }
+
+  describe "#eql?" do
+    let(:eql?) { set.eql?(comparison) }
+
+    shared_examples "comparing non-sets" do
+      let(:values) { %w[A B C] }
+
+      it "returns false" do
+        expect(eql?).to eq(false)
+      end
+    end
+
+    context "when comparing to a standard set" do
+      let(:comparison) { ::Set.new(%w[A B C]) }
+
+      include_examples "comparing non-sets"
+    end
+
+    context "when comparing to a arbitrary object" do
+      let(:comparison) { Object.new }
+
+      include_examples "comparing non-sets"
+    end
+
+    context "when comparing with a subclass of Hamster::Set" do
+      let(:comparison) { Class.new(Hamster::Set).new(%w[A B C]) }
+
+      include_examples "comparing non-sets"
+    end
+
+    context "with an empty set for each comparison" do
+      let(:values) { [] }
+      let(:comparison_values) { [] }
+
+      it "returns true" do
+        expect(eql?).to eq(true)
+      end
+    end
+
+    context "with an empty set and a set with nil" do
+      let(:values) { [] }
+      let(:comparison_values) { [nil] }
+
+      it "returns false" do
+        expect(eql?).to eq(false)
+      end
+    end
+
+    context "with a single item array and empty array" do
+      let(:values) { ["A"] }
+      let(:comparison_values) { [] }
+
+      it "returns false" do
+        expect(eql?).to eq(false)
+      end
+    end
+
+    context "with matching single item array" do
+      let(:values) { ["A"] }
+      let(:comparison_values) { ["A"] }
+
+      it "returns true" do
+        expect(eql?).to eq(true)
+      end
+    end
+
+    context "with mismatching single item array" do
+      let(:values) { ["A"] }
+      let(:comparison_values) { ["B"] }
+
+      it "returns false" do
+        expect(eql?).to eq(false)
+      end
+    end
+
+    context "with a multi-item array and single item array" do
+      let(:values) { %w[A B] }
+      let(:comparison_values) { ["A"] }
+
+      it "returns false" do
+        expect(eql?).to eq(false)
+      end
+    end
+
+    context "with matching multi-item array" do
+      let(:values) { %w[A B] }
+      let(:comparison_values) { %w[A B] }
+
+      it "returns true" do
+        expect(eql?).to eq(true)
+      end
+    end
+
+    context "with a mismatching multi-item array" do
+      let(:values) { %w[A B] }
+      let(:comparison_values) { %w[B A] }
+
+      it "returns true" do
+        expect(eql?).to eq(true)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/exclusion_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/exclusion_spec.rb
new file mode 100755
index 0000000..66338dd
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/exclusion_spec.rb
@@ -0,0 +1,48 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [:exclusion, :^].each do |method|
+    describe "##{method}" do
+      [
+        [[], [], []],
+        [["A"], [], ["A"]],
+        [["A"], ["A"], []],
+        [%w[A B C], ["B"], %w[A C]],
+        [%w[A B C], %w[B C D], %w[A D]],
+        [%w[A B C], %w[D E F], %w[A B C D E F]],
+      ].each do |a, b, expected|
+        context "for #{a.inspect} and #{b.inspect}" do
+          let(:set_a) { S[*a] }
+          let(:set_b) { S[*b] }
+          let(:result) { set_a.send(method, set_b) }
+
+          it "doesn't modify the original Sets" do
+            result
+            set_a.should eql(S.new(a))
+            set_b.should eql(S.new(b))
+          end
+
+          it "returns #{expected.inspect}"  do
+            result.should eql(S[*expected])
+          end
+        end
+
+        context "when passed a Ruby Array" do
+          it "returns the expected Set" do
+            S[*a].exclusion(b.freeze).should eql(S[*expected])
+          end
+        end
+      end
+
+      it "works for a wide variety of inputs" do
+        50.times do
+          array1 = (1..400).to_a.sample(100)
+          array2 = (1..400).to_a.sample(100)
+          result = S.new(array1) ^ S.new(array2)
+          result.to_a.sort.should eql(((array1 | array2) - (array1 & array2)).sort)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/find_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/find_spec.rb
new file mode 100755
index 0000000..80bab4c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/find_spec.rb
@@ -0,0 +1,36 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [:find, :detect].each do |method|
+    describe "##{method}" do
+      [
+        [[], "A", nil],
+        [[], nil, nil],
+        [["A"], "A", "A"],
+        [["A"], "B", nil],
+        [["A"], nil, nil],
+        [["A", "B", nil], "A", "A"],
+        [["A", "B", nil], "B", "B"],
+        [["A", "B", nil], nil, nil],
+        [["A", "B", nil], "C", nil],
+      ].each do |values, item, expected|
+        describe "on #{values.inspect}" do
+          context "with a block" do
+            it "returns #{expected.inspect}" do
+              S[*values].send(method) { |x| x == item }.should == expected
+            end
+          end
+
+          context "without a block" do
+            it "returns an Enumerator" do
+              result = S[*values].send(method)
+              result.class.should be(Enumerator)
+              result.each { |x| x == item}.should == expected
+            end
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/first_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/first_spec.rb
new file mode 100755
index 0000000..b5d4edd
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/first_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#first" do
+    context "on an empty set" do
+      it "returns nil" do
+        S.empty.first.should be_nil
+      end
+    end
+
+    context "on a non-empty set" do
+      it "returns an arbitrary value from the set" do
+        %w[A B C].include?(S["A", "B", "C"].first).should == true
+      end
+    end
+
+    it "returns nil if only member of set is nil" do
+      S[nil].first.should be(nil)
+    end
+
+    it "returns the first item yielded by #each" do
+      10.times do
+        set = S.new((rand(10)+1).times.collect { rand(10000 )})
+        set.each { |item| break item }.should be(set.first)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/flatten_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/flatten_spec.rb
new file mode 100755
index 0000000..a7c36c1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/flatten_spec.rb
@@ -0,0 +1,47 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster do
+  describe "#flatten" do
+    [
+      [["A"], ["A"]],
+      [%w[A B C], %w[A B C]],
+      [["A", S["B"], "C"], %w[A B C]],
+      [[S["A"], S["B"], S["C"]], %w[A B C]],
+    ].each do |values, expected|
+      describe "on #{values}" do
+        let(:set) { S[*values] }
+
+        it "preserves the original" do
+          set.flatten
+          set.should eql(S[*values])
+        end
+
+        it "returns the inlined values" do
+          set.flatten.should eql(S[*expected])
+        end
+      end
+    end
+
+    context "on an empty set" do
+      it "returns an empty set" do
+        S.empty.flatten.should equal(S.empty)
+      end
+    end
+
+    context "on a set with multiple levels of nesting" do
+      it "inlines lower levels of nesting" do
+        set = S[S[S[1]], S[S[2]]]
+        set.flatten.should eql(S[1, 2])
+      end
+    end
+
+    context "from a subclass" do
+      it "returns an instance of the subclass" do
+        subclass = Class.new(Hamster::Set)
+        subclass.new.flatten.class.should be(subclass)
+        subclass.new([S[1], S[2]]).flatten.class.should be(subclass)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/grep_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/grep_spec.rb
new file mode 100755
index 0000000..84121d7
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/grep_spec.rb
@@ -0,0 +1,59 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  let(:set) { S[*values] }
+
+  describe "#grep" do
+    let(:grep) { set.grep(String, &block) }
+
+    shared_examples "check filtered values" do
+      it "returns the filtered values" do
+        expect(grep).to eq(S[*filtered])
+      end
+    end
+
+    context "without a block" do
+      let(:block) { nil }
+
+      context "with an empty set" do
+        let(:values) { [] }
+        let(:filtered) { [] }
+
+        include_examples "check filtered values"
+      end
+
+      context "with a single item set" do
+        let(:values) { ["A"] }
+        let(:filtered) { ["A"] }
+
+        include_examples "check filtered values"
+      end
+
+      context "with a single item set that doesn't contain match" do
+        let(:values) { [1] }
+        let(:filtered) { [] }
+
+        include_examples "check filtered values"
+      end
+
+      context "with a multi-item set where one isn't a match" do
+        let(:values) { ["A", 2, "C"] }
+        let(:filtered) { %w[A C] }
+
+        include_examples "check filtered values"
+      end
+    end
+
+    describe "with a block" do
+      let(:block) { ->(item) { item.downcase }}
+
+      context "processes each matching item with the block" do
+        let(:values) { ["A", 2, "C"] }
+        let(:filtered) { %w[a c] }
+
+        include_examples "check filtered values"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/grep_v_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/grep_v_spec.rb
new file mode 100755
index 0000000..cbe462c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/grep_v_spec.rb
@@ -0,0 +1,59 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  let(:set) { S[*values] }
+
+  describe "#grep_v" do
+    let(:grep_v) { set.grep_v(String, &block) }
+
+    shared_examples "check filtered values" do
+      it "returns the filtered values" do
+        expect(grep_v).to eq(S[*filtered])
+      end
+    end
+
+    context "without a block" do
+      let(:block) { nil }
+
+      context "with an empty set" do
+        let(:values) { [] }
+        let(:filtered) { [] }
+
+        include_examples "check filtered values"
+      end
+
+      context "with a single item set" do
+        let(:values) { ["A"] }
+        let(:filtered) { [] }
+
+        include_examples "check filtered values"
+      end
+
+      context "with a single item set that doesn't contain match" do
+        let(:values) { [1] }
+        let(:filtered) { [1] }
+
+        include_examples "check filtered values"
+      end
+
+      context "with a multi-item set where one isn't a match" do
+        let(:values) { [2, "C", 4] }
+        let(:filtered) { [2, 4] }
+
+        include_examples "check filtered values"
+      end
+    end
+
+    describe "with a block" do
+      let(:block) { ->(item) { item + 100 }}
+
+      context "resulting items are processed with the block" do
+        let(:values) { [2, "C", 4] }
+        let(:filtered) { [102, 104] }
+
+        include_examples "check filtered values"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/group_by_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/group_by_spec.rb
new file mode 100755
index 0000000..6829b91
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/group_by_spec.rb
@@ -0,0 +1,60 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [:group_by, :group, :classify].each do |method|
+    describe "##{method}" do
+      context "with a block" do
+        [
+          [[], []],
+          [[1], [true => S[1]]],
+          [[1, 2, 3, 4], [true => S[3, 1], false => S[4, 2]]],
+        ].each do |values, expected|
+          context "on #{values.inspect}" do
+            let(:set) { S[*values] }
+
+            it "returns #{expected.inspect}" do
+              set.send(method, &:odd?).should eql(H[*expected])
+              set.should eql(S.new(values)) # make sure it hasn't changed
+            end
+          end
+        end
+      end
+
+      context "without a block" do
+        [
+          [[], []],
+          [[1], [1 => S[1]]],
+          [[1, 2, 3, 4], [1 => S[1], 2 => S[2], 3 => S[3], 4 => S[4]]],
+        ].each do |values, expected|
+          context "on #{values.inspect}" do
+            let(:set) { S[*values] }
+
+            it "returns #{expected.inspect}" do
+              set.group_by.should eql(H[*expected])
+              set.should eql(S.new(values)) # make sure it hasn't changed
+            end
+          end
+        end
+      end
+
+      context "on an empty set" do
+        it "returns an empty hash" do
+          S.empty.group_by { |x| x }.should eql(H.empty)
+        end
+      end
+
+      it "returns a hash without default proc" do
+        S[1,2,3].group_by { |x| x }.default_proc.should be_nil
+      end
+
+      context "from a subclass" do
+        it "returns an Hash whose values are instances of the subclass" do
+          subclass = Class.new(Hamster::Set)
+          instance = subclass.new([1, 'string', :symbol])
+          instance.group_by { |x| x.class }.values.each { |v| v.class.should be(subclass) }
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/hash_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/hash_spec.rb
new file mode 100755
index 0000000..9f06f14
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/hash_spec.rb
@@ -0,0 +1,23 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#hash" do
+    context "on an empty set" do
+      it "returns 0" do
+        S.empty.hash.should == 0
+      end
+    end
+
+    it "generates the same hash value for a set regardless of the order things were added to it" do
+      item1 = DeterministicHash.new('a', 121)
+      item2 = DeterministicHash.new('b', 474)
+      item3 = DeterministicHash.new('c', 121)
+      S.empty.add(item1).add(item2).add(item3).hash.should == S.empty.add(item3).add(item2).add(item1).hash
+    end
+
+    it "values are sufficiently distributed" do
+      (1..4000).each_slice(4).map { |a, b, c, d| S[a, b, c, d].hash }.uniq.size.should == 1000
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/immutable_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/immutable_spec.rb
new file mode 100755
index 0000000..4421797
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/immutable_spec.rb
@@ -0,0 +1,9 @@
+require "spec_helper"
+require "hamster/immutable"
+require "hamster/set"
+
+describe Hamster::Set do
+  it "includes Immutable" do
+    Hamster::Set.should include(Hamster::Immutable)
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/include_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/include_spec.rb
new file mode 100755
index 0000000..7c94362
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/include_spec.rb
@@ -0,0 +1,61 @@
+require "spec_helper"
+require "hamster/set"
+require 'set'
+
+describe Hamster::Set do
+  [:include?, :member?].each do |method|
+    describe "##{method}" do
+      let(:set) { S["A", "B", "C", 2.0, nil] }
+
+      ["A", "B", "C", 2.0, nil].each do |value|
+        it "returns true for an existing value (#{value.inspect})" do
+          set.send(method, value).should == true
+        end
+      end
+
+      it "returns false for a non-existing value" do
+        set.send(method, "D").should == false
+      end
+
+      it "returns true even if existing value is nil" do
+        S[nil].include?(nil).should == true
+      end
+
+      it "returns true even if existing value is false" do
+        S[false].include?(false).should == true
+      end
+
+      it "returns false for a mutable item which is mutated after adding" do
+        item = ['mutable']
+        item = [rand(1000000)] while (item.hash.abs & 31 == [item[0], 'HOSED!'].hash.abs & 31)
+        set  = S[item]
+        item.push('HOSED!')
+        set.include?(item).should == false
+      end
+
+      it "uses #eql? for equality" do
+        set.send(method, 2).should == false
+      end
+
+      it "returns the right answers after a lot of addings and removings" do
+        array, set, rb_set = [], S.new, ::Set.new
+
+        1000.times do
+          if rand(2) == 0
+            array << (item = rand(10000))
+            rb_set.add(item)
+            set = set.add(item)
+            set.include?(item).should == true
+          else
+            item = array.sample
+            rb_set.delete(item)
+            set = set.delete(item)
+            set.include?(item).should == false
+          end
+        end
+
+        array.each { |item| set.include?(item).should == rb_set.include?(item) }
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/inspect_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/inspect_spec.rb
new file mode 100755
index 0000000..813f180
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/inspect_spec.rb
@@ -0,0 +1,48 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#inspect" do
+    [
+      [[], "Hamster::Set[]"],
+      [["A"], 'Hamster::Set["A"]'],
+    ].each do |values, expected|
+      describe "on #{values.inspect}" do
+        let(:set) { S[*values] }
+
+        it "returns #{expected.inspect}" do
+          set.inspect.should == expected
+        end
+
+        it "returns a string which can be eval'd to get an equivalent set" do
+          eval(set.inspect).should eql(set)
+        end
+      end
+    end
+
+    describe 'on ["A", "B", "C"]' do
+      let(:set) { S["A", "B", "C"] }
+
+      it "returns a programmer-readable representation of the set contents" do
+        set.inspect.should match(/^Hamster::Set\["[A-C]", "[A-C]", "[A-C]"\]$/)
+      end
+
+      it "returns a string which can be eval'd to get an equivalent set" do
+        eval(set.inspect).should eql(set)
+      end
+    end
+
+    context "from a subclass" do
+      MySet = Class.new(Hamster::Set)
+      let(:set) { MySet[1, 2] }
+
+      it "returns a programmer-readable representation of the set contents" do
+        set.inspect.should match(/^MySet\[[1-2], [1-2]\]$/)
+      end
+
+      it "returns a string which can be eval'd to get an equivalent set" do
+        eval(set.inspect).should eql(set)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/intersect_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/intersect_spec.rb
new file mode 100755
index 0000000..90fbb94
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/intersect_spec.rb
@@ -0,0 +1,26 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#intersect?" do
+    [
+      [[], [], false],
+      [["A"], [], false],
+      [[], ["A"], false],
+      [["A"], ["A"], true],
+      [%w[A B C], ["B"], true],
+      [["B"], %w[A B C], true],
+      [%w[A B C], %w[D E], false],
+      [%w[F G H I], %w[A B C], false],
+      [%w[A B C], %w[A B C], true],
+      [%w[A B C], %w[A B C D], true],
+      [%w[D E F G], %w[A B C], false],
+    ].each do |a, b, expected|
+      describe "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}" do
+          S[*a].intersect?(S[*b]).should be(expected)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/intersection_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/intersection_spec.rb
new file mode 100755
index 0000000..7915093
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/intersection_spec.rb
@@ -0,0 +1,53 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [:intersection, :&].each do |method|
+    describe "##{method}" do
+      [
+        [[], [], []],
+        [["A"], [], []],
+        [["A"], ["A"], ["A"]],
+        [%w[A B C], ["B"], ["B"]],
+        [%w[A B C], %w[A C], %w[A C]],
+      ].each do |a, b, expected|
+        context "for #{a.inspect} and #{b.inspect}"  do
+          let(:set_a) { S[*a] }
+          let(:set_b) { S[*b] }
+
+          it "returns #{expected.inspect}, without changing the original Sets" do
+            set_a.send(method, set_b).should eql(S[*expected])
+            set_a.should eql(S.new(a))
+            set_b.should eql(S.new(b))
+          end
+        end
+
+        context "for #{b.inspect} and #{a.inspect}"  do
+          let(:set_a) { S[*a] }
+          let(:set_b) { S[*b] }
+
+          it "returns #{expected.inspect}, without changing the original Sets" do
+            set_b.send(method, set_a).should eql(S[*expected])
+            set_a.should eql(S.new(a))
+            set_b.should eql(S.new(b))
+          end
+        end
+
+        context "when passed a Ruby Array" do
+          it "returns the expected Set" do
+            S[*a].send(method, b.freeze).should eql(S[*expected])
+          end
+        end
+      end
+
+      it "returns results consistent with Array#&" do
+        50.times do
+          array1 = rand(100).times.map { rand(1000000).to_s(16) }
+          array2 = rand(100).times.map { rand(1000000).to_s(16) }
+          result = S.new(array1).send(method, S.new(array2))
+          result.to_a.sort.should eql((array1 & array2).sort)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/join_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/join_spec.rb
new file mode 100755
index 0000000..93043ad
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/join_spec.rb
@@ -0,0 +1,65 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#join" do
+    context "with a separator" do
+      [
+        [[], ""],
+        [["A"], "A"],
+        [[DeterministicHash.new("A", 1), DeterministicHash.new("B", 2), DeterministicHash.new("C", 3)], "A|B|C"]
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          let(:set) { S[*values] }
+
+          it "preserves the original" do
+            set.join("|")
+            set.should eql(S[*values])
+          end
+
+          it "returns #{expected.inspect}" do
+            set.join("|").should eql(expected)
+          end
+        end
+      end
+    end
+
+    context "without a separator" do
+      [
+        [[], ""],
+        [["A"], "A"],
+        [[DeterministicHash.new("A", 1), DeterministicHash.new("B", 2), DeterministicHash.new("C", 3)], "ABC"]
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          let(:set) { S[*values] }
+
+          it "preserves the original" do
+            set.join
+            set.should eql(S[*values])
+          end
+
+          it "returns #{expected.inspect}" do
+            set.join.should eql(expected)
+          end
+        end
+      end
+    end
+
+    context "without a separator (with global default separator set)" do
+      before { $, = '**' }
+      let(:set) { S[DeterministicHash.new("A", 1), DeterministicHash.new("B", 2), DeterministicHash.new("C", 3)] }
+      after  { $, = nil }
+
+      context "on ['A', 'B', 'C']" do
+        it "preserves the original" do
+          set.join
+          set.should eql(S[DeterministicHash.new("A", 1), DeterministicHash.new("B", 2), DeterministicHash.new("C", 3)])
+        end
+
+        it "returns #{@expected.inspect}" do
+          set.join.should == "A**B**C"
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/map_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/map_spec.rb
new file mode 100755
index 0000000..6ab0da2
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/map_spec.rb
@@ -0,0 +1,60 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [:map, :collect].each do |method|
+    describe "##{method}" do
+      context "when empty" do
+        it "returns self" do
+          S.empty.send(method) {}.should equal(S.empty)
+        end
+      end
+
+      context "when not empty" do
+        let(:set) { S["A", "B", "C"] }
+
+        context "with a block" do
+          it "preserves the original values" do
+            set.send(method, &:downcase)
+            set.should eql(S["A", "B", "C"])
+          end
+
+          it "returns a new set with the mapped values" do
+            set.send(method, &:downcase).should eql(S["a", "b", "c"])
+          end
+        end
+
+        context "with no block" do
+          it "returns an Enumerator" do
+            set.send(method).class.should be(Enumerator)
+            set.send(method).each(&:downcase).should == S['a', 'b', 'c']
+          end
+        end
+      end
+
+      context "from a subclass" do
+        it "returns an instance of the subclass" do
+          subclass = Class.new(Hamster::Set)
+          instance = subclass['a', 'b']
+          instance.map { |item| item.upcase }.class.should be(subclass)
+        end
+      end
+
+      context "when multiple items map to the same value" do
+        it "filters out the duplicates" do
+          set = S.new('aa'..'zz')
+          result = set.map { |s| s[0] }
+          result.should eql(Hamster::Set.new('a'..'z'))
+          result.size.should == 26
+        end
+      end
+
+      it "works on large sets" do
+        set = S.new(1..1000)
+        result = set.map { |x| x * 10 }
+        result.size.should == 1000
+        1.upto(1000) { |n| result.include?(n * 10).should == true }
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/marshal_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/marshal_spec.rb
new file mode 100755
index 0000000..22933e5
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/marshal_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#marshal_dump/#marshal_load" do
+    let(:ruby) { File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"]) }
+
+    let(:child_cmd) do
+      %Q|#{ruby} -I lib -r hamster -e 'set = Hamster::Set[:one, :two]; $stdout.write(Marshal.dump(set))'|
+    end
+
+    let(:reloaded_hash) do
+      IO.popen(child_cmd, "r+") do |child|
+        reloaded_hash = Marshal.load(child)
+        child.close
+        reloaded_hash
+      end
+    end
+
+    it "can survive dumping and loading into a new process" do
+      reloaded_hash.should eql(S[:one, :two])
+    end
+
+    it "is still possible to test items by key after loading" do
+      reloaded_hash.should include :one
+      reloaded_hash.should include :two
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/maximum_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/maximum_spec.rb
new file mode 100755
index 0000000..67366ce
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/maximum_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#max" do
+    context "with a block" do
+      [
+        [[], nil],
+        [["A"], "A"],
+        [%w[Ichi Ni San], "Ichi"],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          let(:set) { S[*values] }
+          let(:result) { set.max { |maximum, item| maximum.length <=> item.length }}
+
+          it "returns #{expected.inspect}" do
+            result.should == expected
+          end
+        end
+      end
+    end
+
+    context "without a block" do
+      [
+        [[], nil],
+        [["A"], "A"],
+        [%w[Ichi Ni San], "San"],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            S[*values].max.should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/minimum_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/minimum_spec.rb
new file mode 100755
index 0000000..a4593f4
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/minimum_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#min" do
+    context "with a block" do
+      [
+        [[], nil],
+        [["A"], "A"],
+        [%w[Ichi Ni San], "Ni"],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          let(:set) { S[*values] }
+          let(:result) { set.min { |minimum, item| minimum.length <=> item.length }}
+
+          it "returns #{expected.inspect}" do
+            result.should == expected
+          end
+        end
+      end
+    end
+
+    context "without a block" do
+      [
+        [[], nil],
+        [["A"], "A"],
+        [%w[Ichi Ni San], "Ichi"],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            S[*values].min.should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/new_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/new_spec.rb
new file mode 100755
index 0000000..01ba363
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/new_spec.rb
@@ -0,0 +1,54 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe ".new" do
+    it "initializes a new set" do
+      set = S.new([1,2,3])
+      set.size.should be(3)
+      [1,2,3].each { |n| set.include?(n).should == true }
+    end
+
+    it "accepts a Range" do
+      set = S.new(1..3)
+      set.size.should be(3)
+      [1,2,3].each { |n| set.include?(n).should == true }
+    end
+
+    it "returns a Set which doesn't change even if the initializer is mutated" do
+      array = [1,2,3]
+      set = S.new([1,2,3])
+      array.push('BAD')
+      set.should eql(S[1,2,3])
+    end
+
+    context "from a subclass" do
+      it "returns a frozen instance of the subclass" do
+        subclass = Class.new(Hamster::Set)
+        instance = subclass.new(["some", "values"])
+        instance.class.should be subclass
+        instance.should be_frozen
+      end
+    end
+
+    it "is amenable to overriding of #initialize" do
+      class SnazzySet < Hamster::Set
+        def initialize
+          super(['SNAZZY!!!'])
+        end
+      end
+
+      set = SnazzySet.new
+      set.size.should be(1)
+      set.include?('SNAZZY!!!').should == true
+    end
+  end
+
+  describe "[]" do
+    it "accepts any number of arguments and initializes a new set" do
+      set = S[1,2,3,4]
+      set.size.should be(4)
+      [1,2,3,4].each { |n| set.include?(n).should == true }
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/none_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/none_spec.rb
new file mode 100755
index 0000000..dcac9c0
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/none_spec.rb
@@ -0,0 +1,48 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#none?" do
+    context "when empty" do
+      it "with a block returns true" do
+        S.empty.none? {}.should == true
+      end
+
+      it "with no block returns true" do
+        S.empty.none?.should == true
+      end
+    end
+
+    context "when not empty" do
+      context "with a block" do
+        let(:set) { S["A", "B", "C", nil] }
+
+        ["A", "B", "C", nil].each do |value|
+          it "returns false if the block ever returns true (#{value.inspect})" do
+            set.none? { |item| item == value }.should == false
+          end
+        end
+
+        it "returns true if the block always returns false" do
+          set.none? { |item| item == "D" }.should == true
+        end
+
+        it "stops iterating as soon as the block returns true" do
+          yielded = []
+          set.none? { |item| yielded << item; true }
+          yielded.size.should == 1
+        end
+      end
+
+      context "with no block" do
+        it "returns false if any value is truthy" do
+          S[nil, false, true, "A"].none?.should == false
+        end
+
+        it "returns true if all values are falsey" do
+          S[nil, false].none?.should == true
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/one_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/one_spec.rb
new file mode 100755
index 0000000..05e0ccd
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/one_spec.rb
@@ -0,0 +1,48 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#one?" do
+    context "when empty" do
+      it "with a block returns false" do
+        S.empty.one? {}.should == false
+      end
+
+      it "with no block returns false" do
+        S.empty.one?.should == false
+      end
+    end
+
+    context "when not empty" do
+      context "with a block" do
+        let(:set) { S["A", "B", "C"] }
+
+        it "returns false if the block returns true more than once" do
+          set.one? { |item| true }.should == false
+        end
+
+        it "returns false if the block never returns true" do
+          set.one? { |item| false }.should == false
+        end
+
+        it "returns true if the block only returns true once" do
+          set.one? { |item| item == "A" }.should == true
+        end
+      end
+
+      context "with no block" do
+        it "returns false if more than one value is truthy" do
+          S[nil, true, "A"].one?.should == false
+        end
+
+        it "returns true if only one value is truthy" do
+          S[nil, true, false].one?.should == true
+        end
+
+        it "returns false if no values are truthy" do
+          S[nil, false].one?.should == false
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/partition_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/partition_spec.rb
new file mode 100755
index 0000000..13c78a2
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/partition_spec.rb
@@ -0,0 +1,53 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#partition" do
+    [
+      [[], [], []],
+      [[1], [1], []],
+      [[1, 2], [1], [2]],
+      [[1, 2, 3], [1, 3], [2]],
+      [[1, 2, 3, 4], [1, 3], [2, 4]],
+      [[2, 3, 4], [3], [2, 4]],
+      [[3, 4], [3], [4]],
+      [[4], [], [4]],
+    ].each do |values, expected_matches, expected_remainder|
+      context "on #{values.inspect}" do
+        let(:set) { S[*values] }
+
+        context "with a block" do
+          let(:result)  { set.partition(&:odd?) }
+          let(:matches) { result.first }
+          let(:remainder) { result.last }
+
+          it "preserves the original" do
+            result
+            set.should eql(S[*values])
+          end
+
+          it "returns a frozen array with two items" do
+            result.class.should be(Array)
+            result.should be_frozen
+            result.size.should be(2)
+          end
+
+          it "correctly identifies the matches" do
+            matches.should eql(S[*expected_matches])
+          end
+
+          it "correctly identifies the remainder" do
+            remainder.should eql(S[*expected_remainder])
+          end
+        end
+
+        describe "without a block" do
+          it "returns an Enumerator" do
+            set.partition.class.should be(Enumerator)
+            set.partition.each(&:odd?).should eql([S.new(expected_matches), S.new(expected_remainder)])
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/product_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/product_spec.rb
new file mode 100755
index 0000000..ac798cb
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/product_spec.rb
@@ -0,0 +1,24 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#product" do
+    [
+      [[], 1],
+      [[2], 2],
+      [[1, 3, 5, 7, 11], 1155],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:set) { S[*values] }
+
+        it "returns #{expected.inspect}" do
+          set.product.should == expected
+        end
+
+        it "doesn't change the original Set" do
+          set.should eql(S.new(values))
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/reduce_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/reduce_spec.rb
new file mode 100755
index 0000000..d464940
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/reduce_spec.rb
@@ -0,0 +1,56 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [:reduce, :inject].each do |method|
+    describe "##{method}" do
+      [
+        [[], 10, 10],
+        [[1], 10, 9],
+        [[1, 2, 3], 10, 4],
+      ].each do |values, initial, expected|
+        describe "on #{values.inspect}" do
+          let(:set) { S[*values] }
+
+          context "with an initial value of #{initial}" do
+            context "and a block" do
+              it "returns #{expected.inspect}" do
+                set.send(method, initial) { |memo, item| memo - item }.should == expected
+              end
+            end
+          end
+        end
+      end
+
+      [
+        [[], nil],
+        [[1], 1],
+        [[1, 2, 3], 6],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          let(:set) { S[*values] }
+
+          context "with no initial value" do
+            context "and a block" do
+              it "returns #{expected.inspect}" do
+                set.send(method) { |memo, item| memo + item }.should == expected
+              end
+            end
+          end
+        end
+      end
+
+      describe "with no block and a symbol argument" do
+        it "uses the symbol as the name of a method to reduce with" do
+          S[1, 2, 3].reduce(:+).should == 6
+        end
+      end
+
+      describe "with no block and a string argument" do
+        it "uses the string as the name of a method to reduce with" do
+          S[1, 2, 3].reduce('+').should == 6
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/reject_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/reject_spec.rb
new file mode 100755
index 0000000..272b5de
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/reject_spec.rb
@@ -0,0 +1,51 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [:reject, :delete_if].each do |method|
+    describe "##{method}" do
+      let(:set) { S["A", "B", "C"] }
+
+      context "when nothing matches" do
+        it "returns self" do
+          set.send(method) { |item| false }.should equal(set)
+        end
+      end
+
+      context "when only some things match" do
+        context "with a block" do
+          let(:result) { set.send(method) { |item| item == "A" }}
+
+          it "preserves the original" do
+            result
+            set.should eql(S["A", "B", "C"])
+          end
+
+          it "returns a set with the matching values" do
+            result.should eql(S["B", "C"])
+          end
+        end
+
+        context "with no block" do
+          it "returns self" do
+            set.send(method).class.should be(Enumerator)
+            set.send(method).each { |item| item == "A" }.should == S["B", "C"]
+          end
+        end
+      end
+
+      context "on a large set, with many combinations of input" do
+        it "still works" do
+          array = (1..1000).to_a
+          set   = S.new(array)
+          [0, 10, 100, 200, 500, 800, 900, 999, 1000].each do |threshold|
+            result = set.send(method) { |item| item > threshold }
+            result.size.should == threshold
+            1.upto(threshold)  { |n| result.include?(n).should == true }
+            (threshold+1).upto(1000) { |n| result.include?(n).should == false }
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/reverse_each_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/reverse_each_spec.rb
new file mode 100755
index 0000000..13943f1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/reverse_each_spec.rb
@@ -0,0 +1,39 @@
+require "spec_helper"
+require "set"
+require "hamster/set"
+
+describe Hamster::Set do
+  let(:set) { S["A", "B", "C"] }
+
+  describe "#reverse_each" do
+    let(:reverse_each) { set.reverse_each(&block) }
+
+    context "without a block" do
+      let(:block) { nil }
+
+      it "returns an Enumerator" do
+        expect(reverse_each.class).to be(Enumerator)
+        expect(reverse_each.to_a).to eq(set.to_a.reverse)
+      end
+    end
+
+    context "with an empty block" do
+      let(:block) { ->(item) {} }
+
+      it "returns self" do
+        expect(reverse_each).to be(set)
+      end
+    end
+
+    context "with a block" do
+      let(:items) { ::Set.new }
+      let(:values) { ::Set.new(%w[A B C]) }
+      let(:block) { ->(item) { items << item } }
+      before(:each) { reverse_each }
+
+      it "yields all values" do
+        expect(items).to eq(values)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/sample_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/sample_spec.rb
new file mode 100755
index 0000000..53e35ba
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/sample_spec.rb
@@ -0,0 +1,14 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#sample" do
+    let(:set) { S.new(1..10) }
+
+    it "returns a randomly chosen item" do
+      chosen = 100.times.map { set.sample }
+      chosen.each { |item| set.include?(item).should == true }
+      set.each { |item| chosen.include?(item).should == true }
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/select_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/select_spec.rb
new file mode 100755
index 0000000..74dae08
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/select_spec.rb
@@ -0,0 +1,74 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [:select, :find_all].each do |method|
+    describe "##{method}" do
+      let(:set) { S["A", "B", "C"] }
+
+      context "when everything matches" do
+        it "returns self" do
+          set.send(method) { |item| true }.should equal(set)
+        end
+      end
+
+      context "when only some things match" do
+        context "with a block" do
+          let(:result) { set.send(method) { |item| item == "A" }}
+
+          it "preserves the original" do
+            result
+            set.should eql(S["A", "B", "C"])
+          end
+
+          it "returns a set with the matching values" do
+            result.should eql(S["A"])
+          end
+        end
+
+        context "with no block" do
+          it "returns an Enumerator" do
+            set.send(method).class.should be(Enumerator)
+            set.send(method).each { |item| item == "A" }.should eql(S["A"])
+          end
+        end
+      end
+
+      context "when nothing matches" do
+        let(:result) { set.send(method) { |item| false }}
+
+        it "preserves the original" do
+          result
+          set.should eql(S["A", "B", "C"])
+        end
+
+        it "returns the canonical empty set" do
+          result.should equal(Hamster::EmptySet)
+        end
+      end
+
+      context "from a subclass" do
+        it "returns an instance of the same class" do
+          subclass = Class.new(Hamster::Set)
+          instance = subclass.new(['A', 'B', 'C'])
+          instance.send(method) { true }.class.should be(subclass)
+          instance.send(method) { false }.class.should be(subclass)
+          instance.send(method) { rand(2) == 0 }.class.should be(subclass)
+        end
+      end
+
+      it "works on a large set, with many combinations of input" do
+        items = (1..1000).to_a
+        original = S.new(items)
+        30.times do
+          threshold = rand(1000)
+          result    = original.send(method) { |item| item <= threshold }
+          result.size.should == threshold
+          result.each { |item| item.should <= threshold }
+          (threshold+1).upto(1000) { |item| result.include?(item).should == false }
+        end
+        original.should eql(S.new(items))
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/size_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/size_spec.rb
new file mode 100755
index 0000000..29dd970
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/size_spec.rb
@@ -0,0 +1,18 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [:size, :length].each do |method|
+    describe "##{method}" do
+      [
+        [[], 0],
+        [["A"], 1],
+        [%w[A B C], 3],
+      ].each do |values, result|
+        it "returns #{result} for #{values.inspect}" do
+          S[*values].send(method).should == result
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/sorting_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/sorting_spec.rb
new file mode 100755
index 0000000..700ce53
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/sorting_spec.rb
@@ -0,0 +1,60 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [
+    [:sort, ->(left, right) { left.length <=> right.length }],
+    [:sort_by, ->(item) { item.length }],
+  ].each do |method, comparator|
+    describe "##{method}" do
+      [
+        [[], []],
+        [["A"], ["A"]],
+        [%w[Ichi Ni San], %w[Ni San Ichi]],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          let(:set) { S[*values] }
+
+          describe "with a block" do
+            let(:result) { set.send(method, &comparator) }
+
+            it "returns #{expected.inspect}" do
+              result.should eql(SS.new(expected, &comparator))
+              result.to_a.should == expected
+            end
+
+            it "doesn't change the original Set" do
+              result
+              set.should eql(S.new(values))
+            end
+          end
+
+          describe "without a block" do
+            let(:result) { set.send(method) }
+
+            it "returns #{expected.sort.inspect}" do
+              result.should eql(SS[*expected])
+              result.to_a.should == expected.sort
+            end
+
+            it "doesn't change the original Set" do
+              result
+              set.should eql(S.new(values))
+            end
+          end
+        end
+      end
+    end
+  end
+
+  describe "#sort_by" do
+    it "only calls the passed block once for each item" do
+      count = 0
+      fn    = lambda { |x| count += 1; -x }
+      items = 100.times.collect { rand(10000) }.uniq
+
+      S[*items].sort_by(&fn).to_a.should == items.sort.reverse
+      count.should == items.length
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/subset_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/subset_spec.rb
new file mode 100755
index 0000000..d3a5516
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/subset_spec.rb
@@ -0,0 +1,52 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [:subset?, :<=].each do |method|
+    describe "##{method}" do
+      [
+        [[], [], true],
+        [["A"], [], false],
+        [[], ["A"], true],
+        [["A"], ["A"], true],
+        [%w[A B C], ["B"], false],
+        [["B"], %w[A B C], true],
+        [%w[A B C], %w[A C], false],
+        [%w[A C], %w[A B C], true],
+        [%w[A B C], %w[A B C], true],
+        [%w[A B C], %w[A B C D], true],
+        [%w[A B C D], %w[A B C], false],
+      ].each do |a, b, expected|
+        describe "for #{a.inspect} and #{b.inspect}" do
+          it "returns #{expected}"  do
+            S[*a].send(method, S[*b]).should == expected
+          end
+        end
+      end
+    end
+  end
+
+  [:proper_subset?, :<].each do |method|
+    describe "##{method}" do
+      [
+        [[], [], false],
+        [["A"], [], false],
+        [[], ["A"], true],
+        [["A"], ["A"], false],
+        [%w[A B C], ["B"], false],
+        [["B"], %w[A B C], true],
+        [%w[A B C], %w[A C], false],
+        [%w[A C], %w[A B C], true],
+        [%w[A B C], %w[A B C], false],
+        [%w[A B C], %w[A B C D], true],
+        [%w[A B C D], %w[A B C], false],
+      ].each do |a, b, expected|
+        describe "for #{a.inspect} and #{b.inspect}" do
+          it "returns #{expected}"  do
+            S[*a].send(method, S[*b]).should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/sum_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/sum_spec.rb
new file mode 100755
index 0000000..17cb771
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/sum_spec.rb
@@ -0,0 +1,24 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#sum" do
+    [
+      [[], 0],
+      [[2], 2],
+      [[1, 3, 5, 7, 11], 27],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:set) { S[*values] }
+
+        it "returns #{expected.inspect}" do
+          set.sum.should == expected
+        end
+
+        it "doesn't change the original Set" do
+          set.should eql(S.new(values))
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/superset_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/superset_spec.rb
new file mode 100755
index 0000000..2eaf2ba
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/superset_spec.rb
@@ -0,0 +1,52 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [:superset?, :>=].each do |method|
+    describe "##{method}" do
+      [
+        [[], [], true],
+        [["A"], [], true],
+        [[], ["A"], false],
+        [["A"], ["A"], true],
+        [%w[A B C], ["B"], true],
+        [["B"], %w[A B C], false],
+        [%w[A B C], %w[A C], true],
+        [%w[A C], %w[A B C], false],
+        [%w[A B C], %w[A B C], true],
+        [%w[A B C], %w[A B C D], false],
+        [%w[A B C D], %w[A B C], true],
+      ].each do |a, b, expected|
+        describe "for #{a.inspect} and #{b.inspect}" do
+          it "returns #{expected}"  do
+            S[*a].send(method, S[*b]).should == expected
+          end
+        end
+      end
+    end
+  end
+
+  [:proper_superset?, :>].each do |method|
+    describe "##{method}" do
+      [
+        [[], [], false],
+        [["A"], [], true],
+        [[], ["A"], false],
+        [["A"], ["A"], false],
+        [%w[A B C], ["B"], true],
+        [["B"], %w[A B C], false],
+        [%w[A B C], %w[A C], true],
+        [%w[A C], %w[A B C], false],
+        [%w[A B C], %w[A B C], false],
+        [%w[A B C], %w[A B C D], false],
+        [%w[A B C D], %w[A B C], true],
+      ].each do |a, b, expected|
+        describe "for #{a.inspect} and #{b.inspect}" do
+          it "returns #{expected}"  do
+            S[*a].send(method, S[*b]).should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/to_a_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/to_a_spec.rb
new file mode 100755
index 0000000..247d930
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/to_a_spec.rb
@@ -0,0 +1,31 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [:to_a, :entries].each do |method|
+    describe "##{method}" do
+      ('a'..'z').each do |letter|
+        let(:values) { ('a'..letter).to_a }
+        let(:set) { S.new(values) }
+        let(:result) { set.send(method) }
+
+        context "on 'a'..'#{letter}'" do
+          it "returns an equivalent array" do
+            result.sort.should == values.sort
+          end
+
+          it "doesn't change the original Set" do
+            result
+            set.should eql(S[*values])
+          end
+
+          it "returns a mutable array" do
+            expect(result.last).to_not eq("The End")
+            result << "The End"
+            result.last.should == "The End"
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/to_list_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/to_list_spec.rb
new file mode 100755
index 0000000..0153430
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/to_list_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+require "hamster/set"
+require "hamster/list"
+
+describe Hamster::Set do
+  describe "#to_list" do
+    [
+      [],
+      ["A"],
+      %w[A B C],
+    ].each do |values|
+      context "on #{values.inspect}" do
+        let(:set) { S[*values] }
+        let(:list) { set.to_list }
+
+        it "returns a list" do
+          list.is_a?(Hamster::List).should == true
+        end
+
+        it "doesn't change the original Set" do
+          list
+          set.should eql(S.new(values))
+        end
+
+        describe "the returned list" do
+          it "has the correct length" do
+            list.size.should == values.size
+          end
+
+          it "contains all values" do
+            list.to_a.sort.should == values.sort
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/to_set_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/to_set_spec.rb
new file mode 100755
index 0000000..ef9efe1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/to_set_spec.rb
@@ -0,0 +1,20 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  describe "#to_set" do
+    [
+      [],
+      ["A"],
+      %w[A B C],
+    ].each do |values|
+      describe "on #{values.inspect}" do
+        let(:set) { S[*values] }
+
+        it "returns self" do
+          set.to_set.should equal(set)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/union_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/union_spec.rb
new file mode 100755
index 0000000..b1e4276
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/set/union_spec.rb
@@ -0,0 +1,64 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  [:union, :|, :+, :merge].each do |method|
+    describe "##{method}" do
+      [
+        [[], [], []],
+        [["A"], [], ["A"]],
+        [["A"], ["A"], ["A"]],
+        [[], ["A"], ["A"]],
+        [%w[A B C], [], %w[A B C]],
+        [%w[A B C], %w[A B C], %w[A B C]],
+        [%w[A B C], %w[X Y Z], %w[A B C X Y Z]]
+      ].each do |a, b, expected|
+        context "for #{a.inspect} and #{b.inspect}" do
+          let(:set_a) { S[*a] }
+          let(:set_b) { S[*b] }
+
+          it "returns #{expected.inspect}, without changing the original Sets" do
+            set_a.send(method, set_b).should eql(S[*expected])
+            set_a.should eql(S.new(a))
+            set_b.should eql(S.new(b))
+          end
+        end
+
+        context "for #{b.inspect} and #{a.inspect}" do
+          let(:set_a) { S[*a] }
+          let(:set_b) { S[*b] }
+
+          it "returns #{expected.inspect}, without changing the original Sets" do
+            set_b.send(method, set_a).should eql(S[*expected])
+            set_a.should eql(S.new(a))
+            set_b.should eql(S.new(b))
+          end
+        end
+
+        context "when passed a Ruby Array" do
+          it "returns the expected Set" do
+            S[*a].send(method, b.freeze).should eql(S[*expected])
+            S[*b].send(method, a.freeze).should eql(S[*expected])
+          end
+        end
+
+        context "from a subclass" do
+          it "returns an instance of the subclass" do
+            subclass = Class.new(Hamster::Set)
+            subclass.new(a).send(method, S.new(b)).class.should be(subclass)
+            subclass.new(b).send(method, S.new(a)).class.should be(subclass)
+          end
+        end
+      end
+
+      context "when receiving a subset" do
+        let(:set_a) { S.new(1..300) }
+        let(:set_b) { S.new(1..200) }
+
+        it "returns self" do
+          set_a.send(method, set_b).should be(set_a)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/above_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/above_spec.rb
new file mode 100755
index 0000000..913bc44
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/above_spec.rb
@@ -0,0 +1,52 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#above" do
+    context "when called without a block" do
+      it "returns a sorted set of all items higher than the argument" do
+        100.times do
+          items     = rand(100).times.collect { rand(1000) }
+          set       = SS.new(items)
+          threshold = rand(1000)
+          result    = set.above(threshold)
+          array     = items.select { |x| x > threshold }.sort
+          result.class.should be(Hamster::SortedSet)
+          result.size.should == array.size
+          result.to_a.should == array
+        end
+      end
+    end
+
+    context "when called with a block" do
+      it "yields all the items higher than the argument" do
+        100.times do
+          items     = rand(100).times.collect { rand(1000) }
+          set       = SS.new(items)
+          threshold = rand(1000)
+          result    = []
+          set.above(threshold) { |x| result << x }
+          array  = items.select { |x| x > threshold }.sort
+          result.size.should == array.size
+          result.should == array
+        end
+      end
+    end
+
+    context "on an empty set" do
+      it "returns an empty set" do
+        SS.empty.above(1).should be_empty
+        SS.empty.above('abc').should be_empty
+        SS.empty.above(:symbol).should be_empty
+      end
+    end
+
+    context "with an argument higher than all the values in the set" do
+      it "returns an empty set" do
+        result = SS.new(1..100).above(100)
+        result.class.should be(Hamster::SortedSet)
+        result.should be_empty
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/add_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/add_spec.rb
new file mode 100755
index 0000000..d95c25f
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/add_spec.rb
@@ -0,0 +1,63 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  let(:sorted_set) { SS["B", "C", "D"] }
+
+  [:add, :<<].each do |method|
+    describe "##{method}" do
+      context "with a unique value" do
+        it "preserves the original" do
+          sorted_set.send(method, "A")
+          sorted_set.should eql(SS["B", "C", "D"])
+        end
+
+        it "returns a copy with the superset of values (in order)" do
+          sorted_set.send(method, "A").should eql(SS["A", "B", "C", "D"])
+        end
+      end
+
+      context "with a duplicate value" do
+        it "preserves the original values" do
+          sorted_set.send(method, "C")
+          sorted_set.should eql(SS["B", "C", "D"])
+        end
+
+        it "returns self" do
+          sorted_set.send(method, "C").should equal(sorted_set)
+        end
+      end
+
+      context "on a set ordered by a comparator" do
+        it "inserts the new item in the correct place" do
+          s = SS.new(['tick', 'pig', 'hippopotamus']) { |str| str.length }
+          s.add('giraffe').to_a.should == ['pig', 'tick', 'giraffe', 'hippopotamus']
+        end
+      end
+    end
+  end
+
+  describe "#add?" do
+    context "with a unique value" do
+      it "preserves the original" do
+        sorted_set.add?("A")
+        sorted_set.should eql(SS["B", "C", "D"])
+      end
+
+      it "returns a copy with the superset of values" do
+        sorted_set.add?("A").should eql(SS["A", "B", "C", "D"])
+      end
+    end
+
+    context "with a duplicate value" do
+      it "preserves the original values" do
+        sorted_set.add?("C")
+        sorted_set.should eql(SS["B", "C", "D"])
+      end
+
+      it "returns false" do
+        sorted_set.add?("C").should equal(false)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/at_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/at_spec.rb
new file mode 100755
index 0000000..55f497d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/at_spec.rb
@@ -0,0 +1,25 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#at" do
+    [
+      [[], 10, nil],
+      [["A"], 10, nil],
+      [%w[A B C], 0, "A"],
+      [%w[A B C], 1, "B"],
+      [%w[A B C], 2, "C"],
+      [%w[A B C], 3, nil],
+      [%w[A B C], -1, "C"],
+      [%w[A B C], -2, "B"],
+      [%w[A B C], -3, "A"],
+      [%w[A B C], -4, nil]
+    ].each do |values, number, expected|
+      describe "#{values.inspect} with #{number}" do
+        it "returns #{expected.inspect}" do
+          SS[*values].at(number).should == expected
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/below_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/below_spec.rb
new file mode 100755
index 0000000..8c31281
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/below_spec.rb
@@ -0,0 +1,52 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#below" do
+    context "when called without a block" do
+      it "returns a sorted set of all items lower than the argument" do
+        100.times do
+          items     = rand(100).times.collect { rand(1000) }
+          set       = SS.new(items)
+          threshold = rand(1000)
+          result    = set.below(threshold)
+          array     = items.select { |x| x < threshold }.sort
+          result.class.should be(Hamster::SortedSet)
+          result.size.should == array.size
+          result.to_a.should == array
+        end
+      end
+    end
+
+    context "when called with a block" do
+      it "yields all the items lower than the argument" do
+        100.times do
+          items     = rand(100).times.collect { rand(1000) }
+          set       = SS.new(items)
+          threshold = rand(1000)
+          result    = []
+          set.below(threshold) { |x| result << x }
+          array  = items.select { |x| x < threshold }.sort
+          result.size.should == array.size
+          result.should == array
+        end
+      end
+    end
+
+    context "on an empty set" do
+      it "returns an empty set" do
+        SS.empty.below(1).should be_empty
+        SS.empty.below('abc').should be_empty
+        SS.empty.below(:symbol).should be_empty
+      end
+    end
+
+    context "with an argument lower than all the values in the set" do
+      it "returns an empty set" do
+        result = SS.new(1..100).below(1)
+        result.class.should be(Hamster::SortedSet)
+        result.should be_empty
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/between_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/between_spec.rb
new file mode 100755
index 0000000..e4ca4ff
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/between_spec.rb
@@ -0,0 +1,52 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#between" do
+    context "when called without a block" do
+      it "returns a sorted set of all items from the first argument to the second" do
+        100.times do
+          items   = rand(100).times.collect { rand(1000) }
+          set     = SS.new(items)
+          from,to = [rand(1000),rand(1000)].sort
+          result  = set.between(from, to)
+          array   = items.select { |x| x >= from && x <= to }.sort
+          result.class.should be(Hamster::SortedSet)
+          result.size.should == array.size
+          result.to_a.should == array
+        end
+      end
+    end
+
+    context "when called with a block" do
+      it "yields all the items lower than the argument" do
+        100.times do
+          items   = rand(100).times.collect { rand(1000) }
+          set     = SS.new(items)
+          from,to = [rand(1000),rand(1000)].sort
+          result  = []
+          set.between(from, to) { |x| result << x }
+          array  = items.select { |x| x >= from && x <= to }.sort
+          result.size.should == array.size
+          result.should == array
+        end
+      end
+    end
+
+    context "on an empty set" do
+      it "returns an empty set" do
+        SS.empty.between(1, 2).should be_empty
+        SS.empty.between('abc', 'def').should be_empty
+        SS.empty.between(:symbol, :another).should be_empty
+      end
+    end
+
+    context "with a 'to' argument lower than the 'from' argument" do
+      it "returns an empty set" do
+        result = SS.new(1..100).between(6, 5)
+        result.class.should be(Hamster::SortedSet)
+        result.should be_empty
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/clear_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/clear_spec.rb
new file mode 100755
index 0000000..88d73d9
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/clear_spec.rb
@@ -0,0 +1,44 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#clear" do
+    [
+      [],
+      ["A"],
+      %w[A B C],
+    ].each do |values|
+      context "on #{values}" do
+        let(:sorted_set) { SS[*values] }
+
+        it "preserves the original" do
+          sorted_set.clear
+          sorted_set.should eql(SS[*values])
+        end
+
+        it "returns an empty set" do
+          sorted_set.clear.should equal(Hamster::EmptySortedSet)
+          sorted_set.clear.should be_empty
+        end
+      end
+    end
+
+    context "from a subclass" do
+      it "returns an empty instance of the subclass" do
+        subclass = Class.new(Hamster::SortedSet)
+        instance = subclass.new([:a, :b, :c, :d])
+        instance.clear.class.should be(subclass)
+        instance.clear.should be_empty
+      end
+    end
+
+    context "with a comparator" do
+      let(:sorted_set) { SS.new([1, 2, 3]) { |x| -x } }
+      it "returns an empty instance with same comparator" do
+        e = sorted_set.clear
+        e.should be_empty
+        e.add(4).add(5).add(6).to_a.should == [6, 5, 4]
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/copying_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/copying_spec.rb
new file mode 100755
index 0000000..2df410a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/copying_spec.rb
@@ -0,0 +1,21 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  [:dup, :clone].each do |method|
+    [
+      [],
+      ["A"],
+      %w[A B C],
+      (1..32),
+    ].each do |values|
+      describe "on #{values.inspect}" do
+        let(:sorted_set) { SS[*values] }
+
+        it "returns self" do
+          sorted_set.send(method).should equal(sorted_set)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/delete_at_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/delete_at_spec.rb
new file mode 100755
index 0000000..1979363
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/delete_at_spec.rb
@@ -0,0 +1,19 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#delete_at" do
+    let(:sorted_set) { SS[1,2,3,4,5] }
+
+    it "removes the element at the specified index" do
+      sorted_set.delete_at(0).should  eql(SS[2,3,4,5])
+      sorted_set.delete_at(2).should  eql(SS[1,2,4,5])
+      sorted_set.delete_at(-1).should eql(SS[1,2,3,4])
+    end
+
+    it "makes no modification if the index is out of range" do
+      sorted_set.delete_at(5).should eql(sorted_set)
+      sorted_set.delete_at(-6).should eql(sorted_set)
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/delete_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/delete_spec.rb
new file mode 100755
index 0000000..d2f3384
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/delete_spec.rb
@@ -0,0 +1,90 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  let(:sorted_set) { SS["A", "B", "C"] }
+
+  describe "#delete" do
+    context "on an empty set" do
+      it "returns an empty set" do
+        SS.empty.delete(0).should be(SS.empty)
+      end
+    end
+
+    context "with an existing value" do
+      it "preserves the original" do
+        sorted_set.delete("B")
+        sorted_set.should eql(SS["A", "B", "C"])
+      end
+
+      it "returns a copy with the remaining of values" do
+        sorted_set.delete("B").should eql(SS["A", "C"])
+      end
+    end
+
+    context "with a non-existing value" do
+      it "preserves the original values" do
+        sorted_set.delete("D")
+        sorted_set.should eql(SS["A", "B", "C"])
+      end
+
+      it "returns self" do
+        sorted_set.delete("D").should equal(sorted_set)
+      end
+    end
+
+    context "when removing the last value in a sorted set" do
+      it "maintains the set order" do
+        ss = SS.new(["peanuts", "jam", "milk"]) { |word| word.length }
+        ss = ss.delete("jam").delete("peanuts").delete("milk")
+        ss = ss.add("banana").add("sugar").add("spam")
+        ss.to_a.should == ['spam', 'sugar', 'banana']
+      end
+
+      context "when the set is in natural order" do
+        it "returns the canonical empty set" do
+          sorted_set.delete("B").delete("C").delete("A").should be(Hamster::EmptySortedSet)
+        end
+      end
+    end
+
+    1.upto(10) do |n|
+      values = (1..n).to_a
+      values.combination(3) do |to_delete|
+        expected = to_delete.reduce(values.dup) { |ary,val| ary.delete(val); ary }
+        describe "on #{values.inspect}, when deleting #{to_delete.inspect}" do
+          it "returns #{expected.inspect}" do
+            set    = SS.new(values)
+            result = to_delete.reduce(set) { |s,val| s.delete(val) }
+            result.should eql(SS.new(expected))
+            result.to_a.should eql(expected)
+          end
+        end
+      end
+    end
+  end
+
+  describe "#delete?" do
+    context "with an existing value" do
+      it "preserves the original" do
+        sorted_set.delete?("B")
+        sorted_set.should eql(SS["A", "B", "C"])
+      end
+
+      it "returns a copy with the remaining values" do
+        sorted_set.delete?("B").should eql(SS["A", "C"])
+      end
+    end
+
+    context "with a non-existing value" do
+      it "preserves the original values" do
+        sorted_set.delete?("D")
+        sorted_set.should eql(SS["A", "B", "C"])
+      end
+
+      it "returns false" do
+        sorted_set.delete?("D").should be(false)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/difference_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/difference_spec.rb
new file mode 100755
index 0000000..98010c9
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/difference_spec.rb
@@ -0,0 +1,23 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  [:difference, :subtract, :-].each do |method|
+    describe "##{method}" do
+      [
+        [[], [], []],
+        [["A"], [], ["A"]],
+        [["A"], ["A"], []],
+        [%w[A B C], ["B"], %w[A C]],
+        [%w[A B C], %w[A C], ["B"]],
+        [%w[A B C D E F], %w[B E F G M X], %w[A C D]]
+      ].each do |a, b, expected|
+        context "for #{a.inspect} and #{b.inspect}" do
+          it "returns #{expected.inspect}"  do
+            SS[*a].send(method, SS[*b]).should eql(SS[*expected])
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/disjoint_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/disjoint_spec.rb
new file mode 100755
index 0000000..0610777
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/disjoint_spec.rb
@@ -0,0 +1,26 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#disjoint?" do
+    [
+      [[], [], true],
+      [["A"], [], true],
+      [[], ["A"], true],
+      [["A"], ["A"], false],
+      [%w[A B C], ["B"], false],
+      [["B"], %w[A B C], false],
+      [%w[A B C], %w[D E], true],
+      [%w[F G H I], %w[A B C], true],
+      [%w[A B C], %w[A B C], false],
+      [%w[A B C], %w[A B C D], false],
+      [%w[D E F G], %w[A B C], true],
+    ].each do |a, b, expected|
+      context "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}" do
+          SS[*a].disjoint?(SS[*b]).should be(expected)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/drop_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/drop_spec.rb
new file mode 100755
index 0000000..4f13e30
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/drop_spec.rb
@@ -0,0 +1,56 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#drop" do
+    [
+      [[], 0, []],
+      [[], 10, []],
+      [["A"], 10, []],
+      [%w[A B C], 0, %w[A B C]],
+      [%w[A B C], 1, %w[B C]],
+      [%w[A B C], 2, ["C"]],
+      [%w[A B C], 3, []]
+    ].each do |values, number, expected|
+      context "#{number} from #{values.inspect}" do
+        let(:sorted_set) { SS[*values] }
+
+        it "preserves the original" do
+          sorted_set.drop(number)
+          sorted_set.should eql(SS[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          sorted_set.drop(number).should eql(SS[*expected])
+        end
+      end
+    end
+
+    context "when argument is zero" do
+      let(:sorted_set) { SS[6, 7, 8, 9] }
+      it "returns self" do
+        sorted_set.drop(0).should be(sorted_set)
+      end
+    end
+
+    context "when the set has a custom order" do
+      let(:sorted_set) { SS.new([1, 2, 3]) { |x| -x }}
+      it "maintains the custom order" do
+        sorted_set.drop(1).to_a.should == [2, 1]
+        sorted_set.drop(2).to_a.should == [1]
+      end
+
+      it "keeps the comparator even when set is cleared" do
+        s = sorted_set.drop(3)
+        s.add(4).add(5).add(6).to_a.should == [6, 5, 4]
+      end
+    end
+
+    context "when called on a subclass" do
+      it "should return an instance of the subclass" do
+        subclass = Class.new(Hamster::SortedSet)
+        subclass.new([1,2,3]).drop(1).class.should be(subclass)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/drop_while_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/drop_while_spec.rb
new file mode 100755
index 0000000..162c59a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/drop_while_spec.rb
@@ -0,0 +1,35 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#drop_while" do
+    [
+      [[], []],
+      [["A"], []],
+      [%w[A B C], ["C"]],
+      [%w[A B C D E F G], %w[C D E F G]]
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:sorted_set) { SS[*values] }
+
+        context "with a block" do
+          it "preserves the original" do
+            sorted_set.drop_while { |item| item < "C" }
+            sorted_set.should eql(SS[*values])
+          end
+
+          it "returns #{expected.inspect}" do
+            sorted_set.drop_while { |item| item < "C" }.should eql(SS[*expected])
+          end
+        end
+
+        context "without a block" do
+          it "returns an Enumerator" do
+            sorted_set.drop_while.class.should be(Enumerator)
+            sorted_set.drop_while.each { |item| item < "C" }.should eql(SS[*expected])
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/each_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/each_spec.rb
new file mode 100755
index 0000000..c3c2c17
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/each_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#each" do
+    context "with no block" do
+      let(:sorted_set) { SS["A", "B", "C"] }
+
+      it "returns an Enumerator" do
+        sorted_set.each.class.should be(Enumerator)
+        sorted_set.each.to_a.should eql(sorted_set.to_a)
+      end
+    end
+
+    context "with a block" do
+      let(:sorted_set) { SS.new((1..1025).to_a.reverse) }
+
+      it "returns self" do
+        sorted_set.each {}.should be(sorted_set)
+      end
+
+      it "iterates over the items in order" do
+        items = []
+        sorted_set.each { |item| items << item }
+        items.should == (1..1025).to_a
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/empty_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/empty_spec.rb
new file mode 100755
index 0000000..07a588c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/empty_spec.rb
@@ -0,0 +1,35 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#empty?" do
+    [
+      [[], true],
+      [["A"], false],
+      [%w[A B C], false],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:sorted_set) { SS[*values] }
+
+        it "returns #{expected.inspect}" do
+          sorted_set.empty?.should == expected
+        end
+      end
+    end
+  end
+
+  describe ".empty" do
+    it "returns the canonical empty set" do
+      SS.empty.size.should be(0)
+      SS.empty.object_id.should be(SS.empty.object_id)
+    end
+
+    context "from a subclass" do
+      it "returns an empty instance of the subclass" do
+        subclass = Class.new(Hamster::SortedSet)
+        subclass.empty.class.should be(subclass)
+        subclass.empty.should be_empty
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/eql_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/eql_spec.rb
new file mode 100755
index 0000000..2444833
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/eql_spec.rb
@@ -0,0 +1,121 @@
+require "spec_helper"
+require "set"
+require "hamster/set"
+
+describe Hamster::SortedSet do
+  let(:set) { SS[*values] }
+  let(:comparison) { SS[*comparison_values] }
+
+  describe "#eql?" do
+    let(:eql?) { set.eql?(comparison) }
+
+    shared_examples "comparing something which is not a sorted set" do
+      let(:values) { %w[A B C] }
+
+      it "returns false" do
+        expect(eql?).to eq(false)
+      end
+    end
+
+    context "when comparing to a standard set" do
+      let(:comparison) { ::Set.new(%w[A B C]) }
+      include_examples "comparing something which is not a sorted set"
+    end
+
+    context "when comparing to a arbitrary object" do
+      let(:comparison) { Object.new }
+      include_examples "comparing something which is not a sorted set"
+    end
+
+    context "when comparing to a Hamster::Set" do
+      let(:comparison) { Hamster::Set.new(%w[A B C]) }
+      include_examples "comparing something which is not a sorted set"
+    end
+
+    context "when comparing with a subclass of Hamster::SortedSet" do
+      let(:comparison) { Class.new(Hamster::SortedSet).new(%w[A B C]) }
+      include_examples "comparing something which is not a sorted set"
+    end
+
+    context "with an empty set for each comparison" do
+      let(:values) { [] }
+      let(:comparison_values) { [] }
+
+      it "returns true" do
+        expect(eql?).to eq(true)
+      end
+    end
+
+    context "with an empty set and a set with nil" do
+      let(:values) { [] }
+      let(:comparison_values) { [nil] }
+
+      it "returns false" do
+        expect(eql?).to eq(false)
+      end
+    end
+
+    context "with a single item array and empty array" do
+      let(:values) { ["A"] }
+      let(:comparison_values) { [] }
+
+      it "returns false" do
+        expect(eql?).to eq(false)
+      end
+    end
+
+    context "with matching single item array" do
+      let(:values) { ["A"] }
+      let(:comparison_values) { ["A"] }
+
+      it "returns true" do
+        expect(eql?).to eq(true)
+      end
+    end
+
+    context "with mismatching single item array" do
+      let(:values) { ["A"] }
+      let(:comparison_values) { ["B"] }
+
+      it "returns false" do
+        expect(eql?).to eq(false)
+      end
+    end
+
+    context "with a multi-item array and single item array" do
+      let(:values) { %w[A B] }
+      let(:comparison_values) { ["A"] }
+
+      it "returns false" do
+        expect(eql?).to eq(false)
+      end
+    end
+
+    context "with matching multi-item array" do
+      let(:values) { %w[A B] }
+      let(:comparison_values) { %w[A B] }
+
+      it "returns true" do
+        expect(eql?).to eq(true)
+      end
+    end
+
+    context "with a mismatching multi-item array" do
+      let(:values) { %w[A B] }
+      let(:comparison_values) { %w[B A] }
+
+      it "returns true" do
+        expect(eql?).to eq(true)
+      end
+    end
+
+    context "with the same values, but a different sort order" do
+      let(:set) { SS[1, 2, 3] }
+      let(:comparison) { SS.new([1, 2, 3]) { |n| -n }}
+
+      it "returns false" do
+        expect(eql?).to eq(false)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/exclusion_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/exclusion_spec.rb
new file mode 100755
index 0000000..d2cf701
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/exclusion_spec.rb
@@ -0,0 +1,23 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  [:exclusion, :^].each do |method|
+    describe "##{method}" do
+      [
+        [[], [], []],
+        [["A"], [], ["A"]],
+        [["A"], ["A"], []],
+        [%w[A B C], ["B"], %w[A C]],
+        [%w[A B C], %w[B C D], %w[A D]],
+        [%w[A B C], %w[D E F], %w[A B C D E F]],
+      ].each do |a, b, expected|
+        context "for #{a.inspect} and #{b.inspect}" do
+          it "returns #{expected.inspect}"  do
+            SS[*a].send(method, SS[*b]).should eql(SS[*expected])
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/fetch_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/fetch_spec.rb
new file mode 100755
index 0000000..980506e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/fetch_spec.rb
@@ -0,0 +1,65 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#fetch" do
+    let(:sorted_set) { SS['a', 'b', 'c'] }
+
+    context "with no default provided" do
+      context "when the index exists" do
+        it "returns the value at the index" do
+          sorted_set.fetch(0).should == "a"
+          sorted_set.fetch(1).should == "b"
+          sorted_set.fetch(2).should == "c"
+        end
+      end
+
+      context "when the key does not exist" do
+        it "raises an IndexError" do
+          -> { sorted_set.fetch(3) }.should raise_error(IndexError)
+          -> { sorted_set.fetch(-4) }.should raise_error(IndexError)
+        end
+      end
+    end
+
+    context "with a default value" do
+      context "when the index exists" do
+        it "returns the value at the index" do
+          sorted_set.fetch(0, "default").should == "a"
+          sorted_set.fetch(1, "default").should == "b"
+          sorted_set.fetch(2, "default").should == "c"
+        end
+      end
+
+      context "when the index does not exist" do
+        it "returns the default value" do
+          sorted_set.fetch(3, "default").should == "default"
+          sorted_set.fetch(-4, "default").should == "default"
+        end
+      end
+    end
+
+    context "with a default block" do
+      context "when the index exists" do
+        it "returns the value at the index" do
+          sorted_set.fetch(0) { "default".upcase }.should == "a"
+          sorted_set.fetch(1) { "default".upcase }.should == "b"
+          sorted_set.fetch(2) { "default".upcase }.should == "c"
+        end
+      end
+
+      context "when the index does not exist" do
+        it "invokes the block with the missing index as parameter" do
+          sorted_set.fetch(3) { |index| index.should == 3 }
+          sorted_set.fetch(-4) { |index| index.should == -4 }
+          sorted_set.fetch(3) { "default".upcase }.should == "DEFAULT"
+          sorted_set.fetch(-4) { "default".upcase }.should == "DEFAULT"
+        end
+      end
+    end
+
+    it "gives precedence to default block over default argument if passed both" do
+      sorted_set.fetch(3, 'one') { 'two' }.should == 'two'
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/find_index_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/find_index_spec.rb
new file mode 100755
index 0000000..cd71cb9
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/find_index_spec.rb
@@ -0,0 +1,41 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  [:find_index, :index].each do |method|
+    describe "##{method}" do
+      [
+        [[], "A", nil],
+        [[], nil, nil],
+        [["A"], "A", 0],
+        [["A"], "B", nil],
+        [["A"], nil, nil],
+        [["A", "B", "C"], "A", 0],
+        [["A", "B", "C"], "B", 1],
+        [["A", "B", "C"], "C", 2],
+        [["A", "B", "C"], "D", nil],
+        [0..1, 1, 1],
+        [0..10, 5, 5],
+        [0..10, 10, 10],
+        [[2], 2, 0],
+        [[2], 2.0, 0],
+        [[2.0], 2.0, 0],
+        [[2.0], 2, 0],
+      ].each do |values, item, expected|
+        unless item.nil? # test breaks otherwise
+          context "looking for #{item.inspect} in #{values.inspect} without block" do
+            it "returns #{expected.inspect}" do
+              SS[*values].send(method, item).should == expected
+            end
+          end
+        end
+
+        context "looking for #{item.inspect} in #{values.inspect} with block" do
+          it "returns #{expected.inspect}" do
+            SS[*values].send(method) { |x| x == item }.should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/first_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/first_spec.rb
new file mode 100755
index 0000000..bb9c599
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/first_spec.rb
@@ -0,0 +1,19 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#first" do
+    [
+      [[], nil],
+      [["A"], "A"],
+      [%w[A B C], "A"],
+      [%w[Z Y X], "X"]
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        it "returns #{expected.inspect}" do
+          SS[*values].first.should eql(expected)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/from_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/from_spec.rb
new file mode 100755
index 0000000..2082f54
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/from_spec.rb
@@ -0,0 +1,52 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#from" do
+    context "when called without a block" do
+      it "returns a sorted set of all items equal to or greater than the argument" do
+        100.times do
+          items     = rand(100).times.collect { rand(1000) }
+          set       = SS.new(items)
+          threshold = rand(1000)
+          result    = set.from(threshold)
+          array     = items.select { |x| x >= threshold }.sort
+          result.class.should be(Hamster::SortedSet)
+          result.size.should == array.size
+          result.to_a.should == array
+        end
+      end
+    end
+
+    context "when called with a block" do
+      it "yields all the items equal to or greater than than the argument" do
+        100.times do
+          items     = rand(100).times.collect { rand(1000) }
+          set       = SS.new(items)
+          threshold = rand(1000)
+          result    = []
+          set.from(threshold) { |x| result << x }
+          array  = items.select { |x| x >= threshold }.sort
+          result.size.should == array.size
+          result.should == array
+        end
+      end
+    end
+
+    context "on an empty set" do
+      it "returns an empty set" do
+        SS.empty.from(1).should be_empty
+        SS.empty.from('abc').should be_empty
+        SS.empty.from(:symbol).should be_empty
+      end
+    end
+
+    context "with an argument higher than all the values in the set" do
+      it "returns an empty set" do
+        result = SS.new(1..100).from(101)
+        result.class.should be(Hamster::SortedSet)
+        result.should be_empty
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/group_by_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/group_by_spec.rb
new file mode 100755
index 0000000..4ed786e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/group_by_spec.rb
@@ -0,0 +1,58 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  [:group_by, :group, :classify].each do |method|
+    describe "##{method}" do
+      context "with a block" do
+        [
+          [[], []],
+          [[1], [true => SS[1]]],
+          [[1, 2, 3, 4], [true => SS[3, 1], false => SS[4, 2]]],
+        ].each do |values, expected|
+          context "on #{values.inspect}" do
+            let(:sorted_set) { SS[*values] }
+
+            it "preserves the original" do
+              sorted_set.send(method, &:odd?)
+              sorted_set.should eql(SS[*values])
+            end
+
+            it "returns #{expected.inspect}" do
+              sorted_set.send(method, &:odd?).should eql(H[*expected])
+            end
+          end
+        end
+      end
+
+      context "without a block" do
+        [
+          [[], []],
+          [[1], [1 => SS[1]]],
+          [[1, 2, 3, 4], [1 => SS[1], 2 => SS[2], 3 => SS[3], 4 => SS[4]]],
+        ].each do |values, expected|
+          context "on #{values.inspect}" do
+            let(:sorted_set) { SS[*values] }
+
+            it "preserves the original" do
+              sorted_set.group_by
+              sorted_set.should eql(SS[*values])
+            end
+
+            it "returns #{expected.inspect}" do
+              sorted_set.group_by.should eql(H[*expected])
+            end
+          end
+        end
+      end
+
+      context "from a subclass" do
+        it "returns an Hash whose values are instances of the subclass" do
+          subclass = Class.new(Hamster::SortedSet)
+          instance = subclass.new(['some', 'strings', 'here'])
+          instance.group_by { |x| x }.values.each { |v| v.class.should be(subclass) }
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/include_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/include_spec.rb
new file mode 100755
index 0000000..ae95b6e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/include_spec.rb
@@ -0,0 +1,24 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  [:include?, :member?].each do |method|
+    describe "##{method}" do
+      let(:sorted_set) { SS[1, 2, 3, 4.0] }
+
+      [1, 2, 3, 4.0].each do |value|
+        it "returns true for an existing value (#{value.inspect})" do
+          sorted_set.send(method, value).should == true
+        end
+      end
+
+      it "returns false for a non-existing value" do
+        sorted_set.send(method, 5).should == false
+      end
+
+      it "uses #<=> for equality" do
+        sorted_set.send(method, 4).should == true
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/inspect_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/inspect_spec.rb
new file mode 100755
index 0000000..52758ce
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/inspect_spec.rb
@@ -0,0 +1,38 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#inspect" do
+    [
+      [[], "Hamster::SortedSet[]"],
+      [["A"], 'Hamster::SortedSet["A"]'],
+      [["C", "B", "A"], 'Hamster::SortedSet["A", "B", "C"]']
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:sorted_set) { SS[*values] }
+
+        it "returns #{expected.inspect}" do
+          sorted_set.inspect.should == expected
+        end
+
+        it "returns a string which can be eval'd to get an equivalent set" do
+          eval(sorted_set.inspect).should eql(sorted_set)
+        end
+      end
+    end
+
+    MySortedSet = Class.new(Hamster::SortedSet)
+
+    context "from a subclass" do
+      let(:sorted_set) { MySortedSet[1, 2] }
+
+      it "returns a programmer-readable representation of the set contents" do
+        sorted_set.inspect.should == 'MySortedSet[1, 2]'
+      end
+
+      it "returns a string which can be eval'd to get an equivalent set" do
+        eval(sorted_set.inspect).should eql(sorted_set)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/intersect_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/intersect_spec.rb
new file mode 100755
index 0000000..6455f31
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/intersect_spec.rb
@@ -0,0 +1,26 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#intersect?" do
+    [
+      [[], [], false],
+      [["A"], [], false],
+      [[], ["A"], false],
+      [["A"], ["A"], true],
+      [%w[A B C], ["B"], true],
+      [["B"], %w[A B C], true],
+      [%w[A B C], %w[D E], false],
+      [%w[F G H I], %w[A B C], false],
+      [%w[A B C], %w[A B C], true],
+      [%w[A B C], %w[A B C D], true],
+      [%w[D E F G], %w[A B C], false],
+    ].each do |a, b, expected|
+      context "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}" do
+          SS[*a].intersect?(SS[*b]).should be(expected)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/intersection_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/intersection_spec.rb
new file mode 100755
index 0000000..8faa315
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/intersection_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  [:intersection, :&].each do |method|
+    describe "##{method}" do
+      [
+        [[], [], []],
+        [["A"], [], []],
+        [["A"], ["A"], ["A"]],
+        [%w[A B C], ["B"], ["B"]],
+        [%w[A B C], %w[A C], %w[A C]],
+        [%w[A M T X], %w[B C D E F G H I M P Q T U], %w[M T]]
+      ].each do |a, b, expected|
+        context "for #{a.inspect} and #{b.inspect}" do
+          it "returns #{expected.inspect}" do
+            SS[*a].send(method, SS[*b]).should eql(SS[*expected])
+          end
+        end
+
+        context "for #{b.inspect} and #{a.inspect}" do
+          it "returns #{expected.inspect}" do
+            SS[*b].send(method, SS[*a]).should eql(SS[*expected])
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/last_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/last_spec.rb
new file mode 100755
index 0000000..6c36344
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/last_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  let(:sorted_set) { SS[*values] }
+
+  describe "#last" do
+    let(:last) { sorted_set.last }
+
+    shared_examples "checking values" do
+      it "returns the last item" do
+        expect(last).to eq(last_item)
+      end
+    end
+
+    context "with an empty set" do
+      let(:last_item) { nil }
+      let(:values) { [] }
+
+      include_examples "checking values"
+    end
+
+    context "with a single item set" do
+      let(:last_item) { "A" }
+      let(:values) { %w[A] }
+
+      include_examples "checking values"
+    end
+
+    context "with a multi-item set" do
+      let(:last_item) { "B" }
+      let(:values) { %w[B A] }
+
+      include_examples "checking values"
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/map_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/map_spec.rb
new file mode 100755
index 0000000..a34066b
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/map_spec.rb
@@ -0,0 +1,44 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  [:map, :collect].each do |method|
+    describe "##{method}" do
+      context "when empty" do
+        it "returns self" do
+          SS.empty.send(method) {}.should equal(SS.empty)
+        end
+      end
+
+      context "when not empty" do
+        let(:sorted_set) { SS["A", "B", "C"] }
+
+        context "with a block" do
+          it "preserves the original values" do
+            sorted_set.send(method, &:downcase)
+            sorted_set.should eql(SS["A", "B", "C"])
+          end
+
+          it "returns a new set with the mapped values" do
+            sorted_set.send(method, &:downcase).should eql(SS["a", "b", "c"])
+          end
+        end
+
+        context "with no block" do
+          it "returns an Enumerator" do
+            sorted_set.send(method).class.should be(Enumerator)
+            sorted_set.send(method).each(&:downcase).should == SS['a', 'b', 'c']
+          end
+        end
+      end
+
+      context "on a set ordered by a comparator" do
+        let(:sorted_set) { SS.new(["A", "B", "C"]) { |a,b| b <=> a }}
+
+        it "returns a new set with the mapped values" do
+          sorted_set.send(method, &:downcase).should == ['c', 'b', 'a']
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/marshal_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/marshal_spec.rb
new file mode 100755
index 0000000..d0a0bbb
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/marshal_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#marshal_dump/#marshal_load" do
+    let(:ruby) do
+      File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"])
+    end
+    let(:child_cmd) do
+      %Q|#{ruby} -I lib -r hamster -e 'set = Hamster::SortedSet[5, 10, 15]; $stdout.write(Marshal.dump(set))'|
+    end
+
+    let(:reloaded_set) do
+      IO.popen(child_cmd, "r+") do |child|
+        reloaded_set = Marshal.load(child)
+        child.close
+        reloaded_set
+      end
+    end
+
+    it "can survive dumping and loading into a new process" do
+      expect(reloaded_set).to eql(SS[5, 10, 15])
+    end
+
+    it "is still possible to find items by index after loading" do
+      expect(reloaded_set[0]).to eq(5)
+      expect(reloaded_set[1]).to eq(10)
+      expect(reloaded_set[2]).to eq(15)
+      expect(reloaded_set.size).to eq(3)
+    end
+
+    it "raises a TypeError if set has a custom sort order" do
+      # this is because comparator block can't be serialized
+      -> { Marshal.dump(SS.new([1, 2, 3]) { |x| -x }) }.should raise_error(TypeError)
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/maximum_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/maximum_spec.rb
new file mode 100755
index 0000000..9d78df1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/maximum_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::SortedSet do
+  describe "#max" do
+    context "with a block" do
+      [
+        [[], nil],
+        [["A"], "A"],
+        [%w[Ichi Ni San], "Ichi"],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          let(:set) { SS[*values] }
+          let(:result) { set.max { |maximum, item| maximum.length <=> item.length }}
+
+          it "returns #{expected.inspect}" do
+            result.should == expected
+          end
+        end
+      end
+    end
+
+    context "without a block" do
+      [
+        [[], nil],
+        [["A"], "A"],
+        [%w[Ichi Ni San], "San"],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            SS[*values].max.should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/minimum_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/minimum_spec.rb
new file mode 100755
index 0000000..824fed3
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/minimum_spec.rb
@@ -0,0 +1,20 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#min" do
+    [
+      [[], nil],
+      [["A"], "A"],
+      [%w[Ichi Ni San], "Ichi"],
+      [[1,2,3,4,5], 1],
+      [[0, -0.0, 2.2, -4, -4.2], -4.2],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        it "returns #{expected.inspect}" do
+          SS[*values].min.should == expected
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/new_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/new_spec.rb
new file mode 100755
index 0000000..b04b04a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/new_spec.rb
@@ -0,0 +1,72 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe ".new" do
+    it "accepts a single enumerable argument and creates a new sorted set" do
+      sorted_set = SS.new([1,2,3])
+      sorted_set.size.should be(3)
+      sorted_set[0].should be(1)
+      sorted_set[1].should be(2)
+      sorted_set[2].should be(3)
+    end
+
+    it "also works with a Range" do
+      sorted_set = SS.new(1..3)
+      sorted_set.size.should be(3)
+      sorted_set[0].should be(1)
+      sorted_set[1].should be(2)
+      sorted_set[2].should be(3)
+    end
+
+    it "is amenable to overriding of #initialize" do
+      class SnazzySortedSet < Hamster::SortedSet
+        def initialize
+          super(['SNAZZY!!!'])
+        end
+      end
+
+      sorted_set = SnazzySortedSet.new
+      sorted_set.size.should be(1)
+      sorted_set.to_a.should == ['SNAZZY!!!']
+    end
+
+    it "accepts a block with arity 1" do
+      sorted_set = SS.new(1..3) { |a| -a }
+      sorted_set[0].should be(3)
+      sorted_set[1].should be(2)
+      sorted_set[2].should be(1)
+    end
+
+    it "accepts a block with arity 2" do
+      sorted_set = SS.new(1..3) { |a,b| b <=> a }
+      sorted_set[0].should be(3)
+      sorted_set[1].should be(2)
+      sorted_set[2].should be(1)
+    end
+
+    it "can use a block produced by Symbol#to_proc" do
+      sorted_set = SS.new([Object, BasicObject], &:name.to_proc)
+      sorted_set[0].should be(BasicObject)
+      sorted_set[1].should be(Object)
+    end
+
+    context "from a subclass" do
+      it "returns a frozen instance of the subclass" do
+        subclass = Class.new(Hamster::SortedSet)
+        instance = subclass.new(["some", "values"])
+        instance.class.should be subclass
+        instance.frozen?.should be true
+      end
+    end
+  end
+
+  describe ".[]" do
+    it "accepts a variable number of items and creates a new sorted set" do
+      sorted_set = SS['a', 'b']
+      sorted_set.size.should be(2)
+      sorted_set[0].should == 'a'
+      sorted_set[1].should == 'b'
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/reverse_each_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/reverse_each_spec.rb
new file mode 100755
index 0000000..9b92db6
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/reverse_each_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#reverse_each" do
+    context "with no block" do
+      let(:sorted_set) { SS["A", "B", "C"] }
+
+      it "returns an Enumerator" do
+        sorted_set.reverse_each.class.should be(Enumerator)
+        sorted_set.reverse_each.to_a.should eql(sorted_set.to_a.reverse)
+      end
+    end
+
+    context "with a block" do
+      let(:sorted_set) { SS.new(1..1025) }
+
+      it "returns self" do
+        sorted_set.reverse_each {}.should be(sorted_set)
+      end
+
+      it "iterates over the items in order" do
+        items = []
+        sorted_set.reverse_each { |item| items << item }
+        items.should == (1..1025).to_a.reverse
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/sample_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/sample_spec.rb
new file mode 100755
index 0000000..b0644ea
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/sample_spec.rb
@@ -0,0 +1,14 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#sample" do
+    let(:sorted_set) { Hamster::SortedSet.new(1..10) }
+
+    it "returns a randomly chosen item" do
+      chosen = 100.times.map { sorted_set.sample }
+      chosen.each { |item| sorted_set.include?(item).should == true }
+      sorted_set.each { |item| chosen.include?(item).should == true }
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/select_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/select_spec.rb
new file mode 100755
index 0000000..2c48ed1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/select_spec.rb
@@ -0,0 +1,62 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  [:select, :find_all].each do |method|
+    describe "##{method}" do
+      let(:sorted_set) { SS["A", "B", "C"] }
+
+      context "when everything matches" do
+        it "preserves the original" do
+          sorted_set.send(method) { true }
+          sorted_set.should eql(SS["A", "B", "C"])
+        end
+
+        it "returns self" do
+          sorted_set.send(method) { |item| true }.should equal(sorted_set)
+        end
+      end
+
+      context "when only some things match" do
+        context "with a block" do
+          it "preserves the original" do
+            sorted_set.send(method) { |item| item == "A" }
+            sorted_set.should eql(SS["A", "B", "C"])
+          end
+
+          it "returns a set with the matching values" do
+            sorted_set.send(method) { |item| item == "A" }.should eql(SS["A"])
+          end
+        end
+
+        context "with no block" do
+          it "returns an Enumerator" do
+            sorted_set.send(method).class.should be(Enumerator)
+            sorted_set.send(method).each { |item| item == "A" }.should eql(SS["A"])
+          end
+        end
+      end
+
+      context "when nothing matches" do
+        it "preserves the original" do
+          sorted_set.send(method) { |item| false }
+          sorted_set.should eql(SS["A", "B", "C"])
+        end
+
+        it "returns the canonical empty set" do
+          sorted_set.send(method) { |item| false }.should equal(Hamster::EmptySortedSet)
+        end
+      end
+
+      context "from a subclass" do
+        it "returns an instance of the same class" do
+          subclass = Class.new(Hamster::SortedSet)
+          instance = subclass.new(['A', 'B', 'C'])
+          instance.send(method) { true }.class.should be(subclass)
+          instance.send(method) { false }.class.should be(subclass)
+          instance.send(method) { rand(2) == 0 }.class.should be(subclass)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/size_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/size_spec.rb
new file mode 100755
index 0000000..9ac18da
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/size_spec.rb
@@ -0,0 +1,18 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  [:size, :length].each do |method|
+    describe "##{method}" do
+      [
+        [[], 0],
+        [["A"], 1],
+        [%w[A B C], 3],
+      ].each do |values, result|
+        it "returns #{result} for #{values.inspect}" do
+          SS[*values].send(method).should == result
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/slice_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/slice_spec.rb
new file mode 100755
index 0000000..34ee7e2
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/slice_spec.rb
@@ -0,0 +1,257 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  let(:sorted_set) { SS[1,2,3,4] }
+  let(:big) { SS.new(1..10000) }
+
+  [:slice, :[]].each do |method|
+    describe "##{method}" do
+      context "when passed a positive integral index" do
+        it "returns the element at that index" do
+          sorted_set.send(method, 0).should be(1)
+          sorted_set.send(method, 1).should be(2)
+          sorted_set.send(method, 2).should be(3)
+          sorted_set.send(method, 3).should be(4)
+          sorted_set.send(method, 4).should be(nil)
+          sorted_set.send(method, 10).should be(nil)
+
+          big.send(method, 0).should be(1)
+          big.send(method, 9999).should be(10000)
+        end
+
+        it "leaves the original unchanged" do
+          sorted_set.should eql(SS[1,2,3,4])
+        end
+      end
+
+      context "when passed a negative integral index" do
+        it "returns the element which is number (index.abs) counting from the end of the sorted_set" do
+          sorted_set.send(method, -1).should be(4)
+          sorted_set.send(method, -2).should be(3)
+          sorted_set.send(method, -3).should be(2)
+          sorted_set.send(method, -4).should be(1)
+          sorted_set.send(method, -5).should be(nil)
+          sorted_set.send(method, -10).should be(nil)
+
+          big.send(method, -1).should be(10000)
+          big.send(method, -10000).should be(1)
+        end
+      end
+
+      context "when passed a positive integral index and count" do
+        it "returns 'count' elements starting from 'index'" do
+          sorted_set.send(method, 0, 0).should  eql(SS.empty)
+          sorted_set.send(method, 0, 1).should  eql(SS[1])
+          sorted_set.send(method, 0, 2).should  eql(SS[1,2])
+          sorted_set.send(method, 0, 4).should  eql(SS[1,2,3,4])
+          sorted_set.send(method, 0, 6).should  eql(SS[1,2,3,4])
+          sorted_set.send(method, 0, -1).should be_nil
+          sorted_set.send(method, 0, -2).should be_nil
+          sorted_set.send(method, 0, -4).should be_nil
+          sorted_set.send(method, 2, 0).should  eql(SS.empty)
+          sorted_set.send(method, 2, 1).should  eql(SS[3])
+          sorted_set.send(method, 2, 2).should  eql(SS[3,4])
+          sorted_set.send(method, 2, 4).should  eql(SS[3,4])
+          sorted_set.send(method, 2, -1).should be_nil
+          sorted_set.send(method, 4, 0).should  eql(SS.empty)
+          sorted_set.send(method, 4, 2).should  eql(SS.empty)
+          sorted_set.send(method, 4, -1).should be_nil
+          sorted_set.send(method, 5, 0).should  be_nil
+          sorted_set.send(method, 5, 2).should  be_nil
+          sorted_set.send(method, 5, -1).should be_nil
+          sorted_set.send(method, 6, 0).should  be_nil
+          sorted_set.send(method, 6, 2).should  be_nil
+          sorted_set.send(method, 6, -1).should be_nil
+
+          big.send(method, 0, 3).should    eql(SS[1,2,3])
+          big.send(method, 1023, 4).should eql(SS[1024,1025,1026,1027])
+          big.send(method, 1024, 4).should eql(SS[1025,1026,1027,1028])
+        end
+
+        it "leaves the original unchanged" do
+          sorted_set.should eql(SS[1,2,3,4])
+        end
+      end
+
+      context "when passed a negative integral index and count" do
+        it "returns 'count' elements, starting from index which is number 'index.abs' counting from the end of the array" do
+          sorted_set.send(method, -1, 0).should  eql(SS.empty)
+          sorted_set.send(method, -1, 1).should  eql(SS[4])
+          sorted_set.send(method, -1, 2).should  eql(SS[4])
+          sorted_set.send(method, -1, -1).should be_nil
+          sorted_set.send(method, -2, 0).should  eql(SS.empty)
+          sorted_set.send(method, -2, 1).should  eql(SS[3])
+          sorted_set.send(method, -2, 2).should  eql(SS[3,4])
+          sorted_set.send(method, -2, 4).should  eql(SS[3,4])
+          sorted_set.send(method, -2, -1).should be_nil
+          sorted_set.send(method, -4, 0).should  eql(SS.empty)
+          sorted_set.send(method, -4, 1).should  eql(SS[1])
+          sorted_set.send(method, -4, 2).should  eql(SS[1,2])
+          sorted_set.send(method, -4, 4).should  eql(SS[1,2,3,4])
+          sorted_set.send(method, -4, 6).should  eql(SS[1,2,3,4])
+          sorted_set.send(method, -4, -1).should be_nil
+          sorted_set.send(method, -5, 0).should  be_nil
+          sorted_set.send(method, -5, 1).should  be_nil
+          sorted_set.send(method, -5, 10).should be_nil
+          sorted_set.send(method, -5, -1).should be_nil
+
+          big.send(method, -1, 1).should eql(SS[10000])
+          big.send(method, -1, 2).should eql(SS[10000])
+          big.send(method, -6, 2).should eql(SS[9995,9996])
+        end
+      end
+
+      context "when passed a Range" do
+        it "returns the elements whose indexes are within the given Range" do
+          sorted_set.send(method, 0..-1).should  eql(SS[1,2,3,4])
+          sorted_set.send(method, 0..-10).should eql(SS.empty)
+          sorted_set.send(method, 0..0).should   eql(SS[1])
+          sorted_set.send(method, 0..1).should   eql(SS[1,2])
+          sorted_set.send(method, 0..2).should   eql(SS[1,2,3])
+          sorted_set.send(method, 0..3).should   eql(SS[1,2,3,4])
+          sorted_set.send(method, 0..4).should   eql(SS[1,2,3,4])
+          sorted_set.send(method, 0..10).should  eql(SS[1,2,3,4])
+          sorted_set.send(method, 2..-10).should eql(SS.empty)
+          sorted_set.send(method, 2..0).should   eql(SS.empty)
+          sorted_set.send(method, 2..2).should   eql(SS[3])
+          sorted_set.send(method, 2..3).should   eql(SS[3,4])
+          sorted_set.send(method, 2..4).should   eql(SS[3,4])
+          sorted_set.send(method, 3..0).should   eql(SS.empty)
+          sorted_set.send(method, 3..3).should   eql(SS[4])
+          sorted_set.send(method, 3..4).should   eql(SS[4])
+          sorted_set.send(method, 4..0).should   eql(SS.empty)
+          sorted_set.send(method, 4..4).should   eql(SS.empty)
+          sorted_set.send(method, 4..5).should   eql(SS.empty)
+          sorted_set.send(method, 5..0).should   be_nil
+          sorted_set.send(method, 5..5).should   be_nil
+          sorted_set.send(method, 5..6).should   be_nil
+
+          big.send(method, 159..162).should     eql(SS[160,161,162,163])
+          big.send(method, 160..162).should     eql(SS[161,162,163])
+          big.send(method, 161..162).should     eql(SS[162,163])
+          big.send(method, 9999..10100).should  eql(SS[10000])
+          big.send(method, 10000..10100).should eql(SS.empty)
+          big.send(method, 10001..10100).should be_nil
+
+          sorted_set.send(method, 0...-1).should  eql(SS[1,2,3])
+          sorted_set.send(method, 0...-10).should eql(SS.empty)
+          sorted_set.send(method, 0...0).should   eql(SS.empty)
+          sorted_set.send(method, 0...1).should   eql(SS[1])
+          sorted_set.send(method, 0...2).should   eql(SS[1,2])
+          sorted_set.send(method, 0...3).should   eql(SS[1,2,3])
+          sorted_set.send(method, 0...4).should   eql(SS[1,2,3,4])
+          sorted_set.send(method, 0...10).should  eql(SS[1,2,3,4])
+          sorted_set.send(method, 2...-10).should eql(SS.empty)
+          sorted_set.send(method, 2...0).should   eql(SS.empty)
+          sorted_set.send(method, 2...2).should   eql(SS.empty)
+          sorted_set.send(method, 2...3).should   eql(SS[3])
+          sorted_set.send(method, 2...4).should   eql(SS[3,4])
+          sorted_set.send(method, 3...0).should   eql(SS.empty)
+          sorted_set.send(method, 3...3).should   eql(SS.empty)
+          sorted_set.send(method, 3...4).should   eql(SS[4])
+          sorted_set.send(method, 4...0).should   eql(SS.empty)
+          sorted_set.send(method, 4...4).should   eql(SS.empty)
+          sorted_set.send(method, 4...5).should   eql(SS.empty)
+          sorted_set.send(method, 5...0).should   be_nil
+          sorted_set.send(method, 5...5).should   be_nil
+          sorted_set.send(method, 5...6).should   be_nil
+
+          big.send(method, 159...162).should     eql(SS[160,161,162])
+          big.send(method, 160...162).should     eql(SS[161,162])
+          big.send(method, 161...162).should     eql(SS[162])
+          big.send(method, 9999...10100).should  eql(SS[10000])
+          big.send(method, 10000...10100).should eql(SS.empty)
+          big.send(method, 10001...10100).should be_nil
+
+          sorted_set.send(method, -1..-1).should  eql(SS[4])
+          sorted_set.send(method, -1...-1).should eql(SS.empty)
+          sorted_set.send(method, -1..3).should   eql(SS[4])
+          sorted_set.send(method, -1...3).should  eql(SS.empty)
+          sorted_set.send(method, -1..4).should   eql(SS[4])
+          sorted_set.send(method, -1...4).should  eql(SS[4])
+          sorted_set.send(method, -1..10).should  eql(SS[4])
+          sorted_set.send(method, -1...10).should eql(SS[4])
+          sorted_set.send(method, -1..0).should   eql(SS.empty)
+          sorted_set.send(method, -1..-4).should  eql(SS.empty)
+          sorted_set.send(method, -1...-4).should eql(SS.empty)
+          sorted_set.send(method, -1..-6).should  eql(SS.empty)
+          sorted_set.send(method, -1...-6).should eql(SS.empty)
+          sorted_set.send(method, -2..-2).should  eql(SS[3])
+          sorted_set.send(method, -2...-2).should eql(SS.empty)
+          sorted_set.send(method, -2..-1).should  eql(SS[3,4])
+          sorted_set.send(method, -2...-1).should eql(SS[3])
+          sorted_set.send(method, -2..10).should  eql(SS[3,4])
+          sorted_set.send(method, -2...10).should eql(SS[3,4])
+
+          big.send(method, -1..-1).should    eql(SS[10000])
+          big.send(method, -1..9999).should  eql(SS[10000])
+          big.send(method, -1...9999).should eql(SS.empty)
+          big.send(method, -2...9999).should eql(SS[9999])
+          big.send(method, -2..-1).should    eql(SS[9999,10000])
+
+          sorted_set.send(method, -4..-4).should  eql(SS[1])
+          sorted_set.send(method, -4..-2).should  eql(SS[1,2,3])
+          sorted_set.send(method, -4...-2).should eql(SS[1,2])
+          sorted_set.send(method, -4..-1).should  eql(SS[1,2,3,4])
+          sorted_set.send(method, -4...-1).should eql(SS[1,2,3])
+          sorted_set.send(method, -4..3).should   eql(SS[1,2,3,4])
+          sorted_set.send(method, -4...3).should  eql(SS[1,2,3])
+          sorted_set.send(method, -4..4).should   eql(SS[1,2,3,4])
+          sorted_set.send(method, -4...4).should  eql(SS[1,2,3,4])
+          sorted_set.send(method, -4..0).should   eql(SS[1])
+          sorted_set.send(method, -4...0).should  eql(SS.empty)
+          sorted_set.send(method, -4..1).should   eql(SS[1,2])
+          sorted_set.send(method, -4...1).should  eql(SS[1])
+
+          sorted_set.send(method, -5..-5).should  be_nil
+          sorted_set.send(method, -5...-5).should be_nil
+          sorted_set.send(method, -5..-4).should  be_nil
+          sorted_set.send(method, -5..-1).should  be_nil
+          sorted_set.send(method, -5..10).should  be_nil
+
+          big.send(method, -10001..-1).should be_nil
+        end
+
+        it "leaves the original unchanged" do
+          sorted_set.should eql(SS[1,2,3,4])
+        end
+      end
+    end
+
+    context "when passed an empty Range" do
+      it "does not lose custom sort order" do
+        ss = SS.new(["yogurt", "cake", "pistachios"]) { |word| word.length }
+        ss = ss.send(method, 1...1).add("tea").add("fruitcake").add("toast")
+        ss.to_a.should == ["tea", "toast", "fruitcake"]
+      end
+    end
+
+    context "when passed a length of zero" do
+      it "does not lose custom sort order" do
+        ss = SS.new(["yogurt", "cake", "pistachios"]) { |word| word.length }
+        ss = ss.send(method, 0, 0).add("tea").add("fruitcake").add("toast")
+        ss.to_a.should == ["tea", "toast", "fruitcake"]
+      end
+    end
+
+    context "when passed a subclass of Range" do
+      it "works the same as with a Range" do
+        subclass = Class.new(Range)
+        sorted_set.send(method, subclass.new(1,2)).should eql(SS[2,3])
+        sorted_set.send(method, subclass.new(-3,-1,true)).should eql(SS[2,3])
+      end
+    end
+
+    context "on a subclass of SortedSet" do
+      it "with index and count or a range, returns an instance of the subclass" do
+        subclass = Class.new(Hamster::SortedSet)
+        instance = subclass.new([1,2,3])
+        instance.send(method, 0, 0).class.should be(subclass)
+        instance.send(method, 0, 2).class.should be(subclass)
+        instance.send(method, 0..0).class.should be(subclass)
+        instance.send(method, 1..-1).class.should be(subclass)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/sorting_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/sorting_spec.rb
new file mode 100755
index 0000000..d3f779c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/sorting_spec.rb
@@ -0,0 +1,45 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  [
+    [:sort, ->(left, right) { left.length <=> right.length }],
+    [:sort_by, ->(item) { item.length }],
+  ].each do |method, comparator|
+    describe "##{method}" do
+      [
+        [[], []],
+        [["A"], ["A"]],
+        [%w[Ichi Ni San], %w[Ni San Ichi]],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          let(:sorted_set) { SS.new(values) { |item| item.reverse }}
+
+          context "with a block" do
+            it "preserves the original" do
+              sorted_set.send(method, &comparator)
+              sorted_set.to_a.should == SS.new(values) { |item| item.reverse }
+            end
+
+            it "returns #{expected.inspect}" do
+              sorted_set.send(method, &comparator).class.should be(Hamster::SortedSet)
+              sorted_set.send(method, &comparator).to_a.should == expected
+            end
+          end
+
+          context "without a block" do
+            it "preserves the original" do
+              sorted_set.send(method)
+              sorted_set.to_a.should == SS.new(values) { |item| item.reverse }
+            end
+
+            it "returns #{expected.sort.inspect}" do
+              sorted_set.send(method).class.should be(Hamster::SortedSet)
+              sorted_set.send(method).to_a.should == expected.sort
+            end
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/subset_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/subset_spec.rb
new file mode 100755
index 0000000..61feaf6
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/subset_spec.rb
@@ -0,0 +1,48 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#subset?" do
+    [
+      [[], [], true],
+      [["A"], [], false],
+      [[], ["A"], true],
+      [["A"], ["A"], true],
+      [%w[A B C], ["B"], false],
+      [["B"], %w[A B C], true],
+      [%w[A B C], %w[A C], false],
+      [%w[A C], %w[A B C], true],
+      [%w[A B C], %w[A B C], true],
+      [%w[A B C], %w[A B C D], true],
+      [%w[A B C D], %w[A B C], false],
+    ].each do |a, b, expected|
+      context "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}"  do
+          SS[*a].subset?(SS[*b]).should == expected
+        end
+      end
+    end
+  end
+
+  describe "#proper_subset?" do
+    [
+      [[], [], false],
+      [["A"], [], false],
+      [[], ["A"], true],
+      [["A"], ["A"], false],
+      [%w[A B C], ["B"], false],
+      [["B"], %w[A B C], true],
+      [%w[A B C], %w[A C], false],
+      [%w[A C], %w[A B C], true],
+      [%w[A B C], %w[A B C], false],
+      [%w[A B C], %w[A B C D], true],
+      [%w[A B C D], %w[A B C], false],
+    ].each do |a, b, expected|
+      context "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}"  do
+          SS[*a].proper_subset?(SS[*b]).should == expected
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/superset_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/superset_spec.rb
new file mode 100755
index 0000000..268e8b6
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/superset_spec.rb
@@ -0,0 +1,48 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#superset?" do
+    [
+      [[], [], true],
+      [["A"], [], true],
+      [[], ["A"], false],
+      [["A"], ["A"], true],
+      [%w[A B C], ["B"], true],
+      [["B"], %w[A B C], false],
+      [%w[A B C], %w[A C], true],
+      [%w[A C], %w[A B C], false],
+      [%w[A B C], %w[A B C], true],
+      [%w[A B C], %w[A B C D], false],
+      [%w[A B C D], %w[A B C], true],
+    ].each do |a, b, expected|
+      context "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}"  do
+          SS[*a].superset?(SS[*b]).should == expected
+        end
+      end
+    end
+  end
+
+  describe "#proper_superset?" do
+    [
+      [[], [], false],
+      [["A"], [], true],
+      [[], ["A"], false],
+      [["A"], ["A"], false],
+      [%w[A B C], ["B"], true],
+      [["B"], %w[A B C], false],
+      [%w[A B C], %w[A C], true],
+      [%w[A C], %w[A B C], false],
+      [%w[A B C], %w[A B C], false],
+      [%w[A B C], %w[A B C D], false],
+      [%w[A B C D], %w[A B C], true],
+    ].each do |a, b, expected|
+      context "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}"  do
+          SS[*a].proper_superset?(SS[*b]).should == expected
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/take_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/take_spec.rb
new file mode 100755
index 0000000..6a92463
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/take_spec.rb
@@ -0,0 +1,55 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#take" do
+    [
+      [[], 10, []],
+      [["A"], 10, ["A"]],
+      [%w[A B C], 0, []],
+      [%w[A B C], 2, %w[A B]],
+    ].each do |values, number, expected|
+      context "#{number} from #{values.inspect}" do
+        let(:sorted_set) { SS[*values] }
+
+        it "preserves the original" do
+          sorted_set.take(number)
+          sorted_set.should eql(SS[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          sorted_set.take(number).should eql(SS[*expected])
+        end
+      end
+    end
+
+    context "when argument is at least size of receiver" do
+      let(:sorted_set) { SS[6, 7, 8, 9] }
+      it "returns self" do
+        sorted_set.take(sorted_set.size).should be(sorted_set)
+        sorted_set.take(sorted_set.size + 1).should be(sorted_set)
+      end
+    end
+
+    context "when the set has a custom order" do
+      let(:sorted_set) { SS.new([1, 2, 3]) { |x| -x }}
+      it "maintains the custom order" do
+        sorted_set.take(1).to_a.should == [3]
+        sorted_set.take(2).to_a.should == [3, 2]
+        sorted_set.take(3).to_a.should == [3, 2, 1]
+      end
+
+      it "keeps the comparator even when set is cleared" do
+        s = sorted_set.take(0)
+        s.add(4).add(5).add(6).to_a.should == [6, 5, 4]
+      end
+    end
+
+    context "when called on a subclass" do
+      it "should return an instance of the subclass" do
+        subclass = Class.new(Hamster::SortedSet)
+        subclass.new([1,2,3]).take(1).class.should be(subclass)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/take_while_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/take_while_spec.rb
new file mode 100755
index 0000000..9946eba
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/take_while_spec.rb
@@ -0,0 +1,34 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#take_while" do
+    [
+      [[], []],
+      [["A"], ["A"]],
+      [%w[A B C], %w[A B]],
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:sorted_set) { SS[*values] }
+
+        context "with a block" do
+          it "returns #{expected.inspect}" do
+            sorted_set.take_while { |item| item < "C" }.should eql(SS[*expected])
+          end
+
+          it "preserves the original" do
+            sorted_set.take_while { |item| item < "C" }
+            sorted_set.should eql(SS[*values])
+          end
+        end
+
+        context "without a block" do
+          it "returns an Enumerator" do
+            sorted_set.take_while.class.should be(Enumerator)
+            sorted_set.take_while.each { |item| item < "C" }.should eql(SS[*expected])
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/to_set_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/to_set_spec.rb
new file mode 100755
index 0000000..5ff4c09
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/to_set_spec.rb
@@ -0,0 +1,19 @@
+require "spec_helper"
+require "hamster/sorted_set"
+require "hamster/set"
+
+describe Hamster::SortedSet do
+  describe "#to_set" do
+    [
+      [],
+      ["A"],
+      %w[A B C],
+    ].each do |values|
+      context "on #{values.inspect}" do
+        it "returns a set with the same values" do
+          SS[*values].to_set.should eql(S[*values])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/union_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/union_spec.rb
new file mode 100755
index 0000000..dffb9d7
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/union_spec.rb
@@ -0,0 +1,28 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  [:union, :|, :+, :merge].each do |method|
+    describe "##{method}" do
+      [
+        [[], [], []],
+        [["A"], [], ["A"]],
+        [["A"], ["A"], ["A"]],
+        [%w[A B C], [], %w[A B C]],
+        [%w[A C E G X], %w[B C D E H M], %w[A B C D E G H M X]]
+      ].each do |a, b, expected|
+        context "for #{a.inspect} and #{b.inspect}" do
+          it "returns #{expected.inspect}" do
+            SS[*a].send(method, SS[*b]).should eql(SS[*expected])
+          end
+        end
+
+        context "for #{b.inspect} and #{a.inspect}" do
+          it "returns #{expected.inspect}" do
+            SS[*b].send(method, SS[*a]).should eql(SS[*expected])
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/up_to_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/up_to_spec.rb
new file mode 100755
index 0000000..f1f7e1c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/up_to_spec.rb
@@ -0,0 +1,53 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#up_to" do
+    context "when called without a block" do
+      it "returns a sorted set of all items equal to or less than the argument" do
+        100.times do
+          items     = rand(100).times.collect { rand(1000) }
+          set       = SS.new(items)
+          threshold = rand(1000)
+          result    = set.up_to(threshold)
+          array     = items.select { |x| x <= threshold }.sort
+          result.class.should be(Hamster::SortedSet)
+          result.size.should == array.size
+          result.to_a.should == array
+        end
+      end
+    end
+
+    context "when called with a block" do
+      it "yields all the items equal to or less than than the argument" do
+        100.times do
+          items     = rand(100).times.collect { rand(1000) }
+          set       = SS.new(items)
+          threshold = rand(1000)
+          result    = []
+          set.up_to(threshold) { |x| result << x }
+          array  = items.select { |x| x <= threshold }.sort
+          result.size.should == array.size
+          result.should == array
+        end
+      end
+    end
+
+    context "on an empty set" do
+      it "returns an empty set" do
+        SS.empty.up_to(1).should be_empty
+        SS.empty.up_to('abc').should be_empty
+        SS.empty.up_to(:symbol).should be_empty
+        SS.empty.up_to(nil).should be_empty
+      end
+    end
+
+    context "with an argument less than all the values in the set" do
+      it "returns an empty set" do
+        result = SS.new(1..100).up_to(0)
+        result.class.should be(Hamster::SortedSet)
+        result.should be_empty
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/values_at_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/values_at_spec.rb
new file mode 100755
index 0000000..e5a728f
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/sorted_set/values_at_spec.rb
@@ -0,0 +1,34 @@
+require "spec_helper"
+require "hamster/sorted_set"
+
+describe Hamster::SortedSet do
+  describe "#values_at" do
+    let(:sorted_set) { SS['a', 'b', 'c'] }
+
+    it "accepts any number of indices, and returns a sorted_set of items at those indices" do
+      sorted_set.values_at(0).should   eql(SS['a'])
+      sorted_set.values_at(1,2).should eql(SS['b', 'c'])
+    end
+
+    context "when passed invalid indices" do
+      it "filters them out" do
+        sorted_set.values_at(1,2,3).should  eql(SS['b', 'c'])
+        sorted_set.values_at(-10,10).should eql(SS.empty)
+      end
+    end
+
+    context "when passed no arguments" do
+      it "returns an empty sorted_set" do
+        sorted_set.values_at.should eql(SS.empty)
+      end
+    end
+
+    context "from a subclass" do
+      it "returns an instance of the subclass" do
+        subclass = Class.new(Hamster::SortedSet)
+        instance = subclass.new([1,2,3])
+        instance.values_at(1,2).class.should be(subclass)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/add_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/add_spec.rb
new file mode 100755
index 0000000..f2de2c4
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/add_spec.rb
@@ -0,0 +1,68 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  let(:vector) { V[*values] }
+
+  [:add, :<<, :push].each do |method|
+    describe "##{method}" do
+      shared_examples "checking adding values" do
+        let(:added_vector) { V[*added_values] }
+
+        it "preserves the original" do
+          original = vector
+          vector.send(method, added_value)
+          expect(original).to eq(vector)
+        end
+
+        it "adds the item to the vector" do
+          result = vector.send(method, added_value)
+          expect(result).to eq(added_vector)
+          expect(result.size).to eq(vector.size + 1)
+        end
+      end
+
+      context "with a empty vector adding a single item" do
+        let(:values) { [] }
+        let(:added_value) { "A" }
+        let(:added_values) { ["A"] }
+
+        include_examples "checking adding values"
+      end
+
+      context "with a single-item vector adding a different item" do
+        let(:values) { ["A"] }
+        let(:added_value) { "B" }
+        let(:added_values) { %w[A B] }
+
+        include_examples "checking adding values"
+      end
+
+      context "with a single-item vector adding a duplicate item" do
+        let(:values) { ["A"] }
+        let(:added_value) { "A" }
+        let(:added_values) { %w[A A] }
+
+        include_examples "checking adding values"
+      end
+
+      [31, 32, 33, 1023, 1024, 1025].each do |size|
+        context "with a #{size}-item vector adding a different item" do
+          let(:values) { (1..size).to_a }
+          let(:added_value) { size+1 }
+          let(:added_values) { (1..(size+1)).to_a }
+
+          include_examples "checking adding values"
+        end
+      end
+
+      context "from a subclass" do
+        it "returns an instance of the subclass" do
+          subclass = Class.new(Hamster::Vector)
+          instance = subclass[1,2,3]
+          instance.add(4).class.should be(subclass)
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/any_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/any_spec.rb
new file mode 100755
index 0000000..092fecb
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/any_spec.rb
@@ -0,0 +1,70 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  let(:vector) { V[*values] }
+
+  describe "#any?" do
+    let(:any?) { vector.any?(&block) }
+
+    context "when created with no values" do
+      let(:values) { [] }
+
+      context "with a block" do
+        let(:block) { ->(item) { item + 1 } }
+
+        it "returns false" do
+          expect(any?).to be(false)
+        end
+      end
+
+      context "with a block" do
+        let(:block) { nil }
+
+        it "returns false" do
+          expect(any?).to be(false)
+        end
+      end
+    end
+
+    context "when created with values" do
+      let(:values) { ["A", "B", 3, nil] }
+
+      context "with a block that returns true" do
+        let(:block) { ->(item) { item == 3 } }
+
+        it "returns true" do
+          expect(any?).to be(true)
+        end
+      end
+
+      context "with a block that doesn't return true" do
+        let(:block) { ->(item) { item == "D" } }
+
+        it "returns false" do
+          expect(any?).to be(false)
+        end
+      end
+
+      context "without a block" do
+        let(:block) { nil }
+
+        context "with some values that are truthy" do
+          let(:values) { [nil, false, "B"] }
+
+          it "returns true" do
+            expect(any?).to be(true)
+          end
+        end
+
+        context "with all values that are falsey" do
+          let(:values) { [nil, false] }
+
+          it "returns false" do
+            expect(any?).to be(false)
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/assoc_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/assoc_spec.rb
new file mode 100755
index 0000000..cf2faee
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/assoc_spec.rb
@@ -0,0 +1,46 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  let(:vector) { V[[:a, 3], [:b, 2], [:c, 1]] }
+
+  describe "#assoc" do
+    it "searches for a 2-element array with a given 1st item" do
+      vector.assoc(:b).should == [:b, 2]
+    end
+
+    it "returns nil if a matching 1st item is not found" do
+      vector.assoc(:d).should be_nil
+    end
+
+    it "uses #== to compare 1st items with provided object" do
+      vector.assoc(EqualNotEql.new).should_not be_nil
+      vector.assoc(EqlNotEqual.new).should be_nil
+    end
+
+    it "skips elements which are not indexable" do
+      V[false, true, nil].assoc(:b).should be_nil
+      V[[1,2], nil].assoc(3).should be_nil
+    end
+  end
+
+  describe "#rassoc" do
+    it "searches for a 2-element array with a given 2nd item" do
+      vector.rassoc(1).should == [:c, 1]
+    end
+
+    it "returns nil if a matching 2nd item is not found" do
+      vector.rassoc(4).should be_nil
+    end
+
+    it "uses #== to compare 2nd items with provided object" do
+      vector.rassoc(EqualNotEql.new).should_not be_nil
+      vector.rassoc(EqlNotEqual.new).should be_nil
+    end
+
+    it "skips elements which are not indexable" do
+      V[false, true, nil].rassoc(:b).should be_nil
+      V[[1,2], nil].rassoc(3).should be_nil
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/bsearch_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/bsearch_spec.rb
new file mode 100755
index 0000000..dbc594c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/bsearch_spec.rb
@@ -0,0 +1,66 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#bsearch" do
+    let(:vector) { V[5,10,20,30] }
+
+    context "with a block which returns false for elements below desired position, and true for those at/above" do
+      it "returns the first element for which the predicate is true" do
+        vector.bsearch { |x| x > 10 }.should be(20)
+        vector.bsearch { |x| x > 1 }.should be(5)
+        vector.bsearch { |x| x > 25 }.should be(30)
+      end
+
+      context "if the block always returns false" do
+        it "returns nil" do
+          vector.bsearch { false }.should be_nil
+        end
+      end
+
+      context "if the block always returns true" do
+        it "returns the first element" do
+          vector.bsearch { true }.should be(5)
+        end
+      end
+    end
+
+    context "with a block which returns a negative number for elements below desired position, zero for the right element, and positive for those above" do
+      it "returns the element for which the block returns zero" do
+        vector.bsearch { |x| x <=> 10 }.should be(10)
+      end
+
+      context "if the block always returns positive" do
+        it "returns nil" do
+          vector.bsearch { 1 }.should be_nil
+        end
+      end
+
+      context "if the block always returns negative" do
+        it "returns nil" do
+          vector.bsearch { -1 }.should be_nil
+        end
+      end
+
+      context "if the block returns sometimes positive, sometimes negative, but never zero" do
+        it "returns nil" do
+          vector.bsearch { |x| x <=> 11 }.should be_nil
+        end
+      end
+
+      context "if not passed a block" do
+        it "returns an Enumerator" do
+          enum = vector.bsearch
+          enum.should be_a(Enumerator)
+          enum.each { |x| x <=> 10 }.should == 10
+        end
+      end
+    end
+
+    context "on an empty vector" do
+      it "returns nil" do
+        V.empty.bsearch { |x| x > 5 }.should be_nil
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/clear_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/clear_spec.rb
new file mode 100755
index 0000000..bab6dab
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/clear_spec.rb
@@ -0,0 +1,34 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#clear" do
+    [
+      [],
+      ["A"],
+      %w[A B C],
+    ].each do |values|
+      describe "on #{values}" do
+        let(:vector) { V[*values] }
+
+        it "preserves the original" do
+          vector.clear
+          vector.should eql(V[*values])
+        end
+
+        it "returns an empty vector" do
+          vector.clear.should equal(V.empty)
+        end
+      end
+
+      context "from a subclass" do
+        it "returns an instance of the subclass" do
+          subclass = Class.new(Hamster::Vector)
+          instance = subclass.new(%w{a b c})
+          instance.clear.class.should be(subclass)
+          instance.clear.should be_empty
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/combination_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/combination_spec.rb
new file mode 100755
index 0000000..7aebaef
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/combination_spec.rb
@@ -0,0 +1,82 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#combination" do
+    let(:vector) { V[1,2,3,4] }
+
+    context "with a block" do
+      it "returns self" do
+        vector.combination(2) {}.should be(vector)
+      end
+    end
+
+    context "with no block" do
+      it "returns an Enumerator" do
+        vector.combination(2).class.should be(Enumerator)
+        vector.combination(2).to_a.should == vector.to_a.combination(2).to_a
+      end
+    end
+
+    context "when passed an argument which is out of bounds" do
+      it "yields nothing and returns self" do
+        vector.combination(5) { fail }.should be(vector)
+        vector.combination(-1) { fail }.should be(vector)
+      end
+    end
+
+    context "when passed an argument zero" do
+      it "yields an empty array" do
+        result = []
+        vector.combination(0) { |obj| result << obj }
+        result.should eql([[]])
+      end
+    end
+
+    context "when passed an argument equal to the vector's length" do
+      it "yields self as an array" do
+        result = []
+        vector.combination(4) { |obj| result << obj }
+        result.should eql([vector.to_a])
+      end
+    end
+
+    context "when passed an argument 1" do
+      it "yields each item in the vector, as single-item vectors" do
+        result = []
+        vector.combination(1) { |obj| result << obj }
+        result.should eql([[1], [2], [3], [4]])
+      end
+    end
+
+    context "when passed another integral argument" do
+      it "yields all combinations of the given length" do
+        result = []
+        vector.combination(3) { |obj| result << obj }
+        result.should eql([[1,2,3], [1,2,4], [1,3,4], [2,3,4]])
+      end
+    end
+
+    context "on an empty vector" do
+      it "works the same" do
+        V.empty.combination(0).to_a.should == [[]]
+        V.empty.combination(1).to_a.should == []
+      end
+    end
+
+    it "works on many combinations of input" do
+      0.upto(5) do |comb_size|
+        array = 12.times.map { rand(1000) }
+        V.new(array).combination(comb_size).to_a.should == array.combination(comb_size).to_a
+      end
+
+      array = 20.times.map { rand(1000) }
+      V.new(array).combination(2).to_a.should == array.combination(2).to_a
+    end
+
+    it "leaves the original unmodified" do
+      vector.combination(2) {}
+      vector.should eql(V[1,2,3,4])
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/compact_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/compact_spec.rb
new file mode 100755
index 0000000..ca3a5fe
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/compact_spec.rb
@@ -0,0 +1,30 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#compact" do
+    it "returns a new Vector with all nils removed" do
+      V[1, nil, 2, nil].compact.should eql(V[1, 2])
+      V[1, 2, 3].compact.should eql(V[1, 2, 3])
+      V[nil].compact.should eql(V.empty)
+    end
+
+    context "on an empty vector" do
+      it "returns self" do
+        V.empty.compact.should be(V.empty)
+      end
+    end
+
+    it "doesn't remove false" do
+      V[false].compact.should eql(V[false])
+    end
+
+    context "from a subclass" do
+      it "returns an instance of the subclass" do
+        subclass = Class.new(V)
+        instance = subclass[1, nil, 2]
+        instance.compact.class.should be(subclass)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/compare_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/compare_spec.rb
new file mode 100755
index 0000000..e16e5de
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/compare_spec.rb
@@ -0,0 +1,32 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#<=>" do
+    [
+      [[], [1]],
+      [[1], [2]],
+      [[1], [1, 2]],
+      [[2, 3, 4], [3, 4, 5]],
+      [[[0]], [[1]]]
+    ].each do |items1, items2|
+      describe "with #{items1} and #{items2}" do
+        it "returns -1" do
+          (V.new(items1) <=> V.new(items2)).should be(-1)
+        end
+      end
+
+      describe "with #{items2} and #{items1}" do
+        it "returns 1" do
+          (V.new(items2) <=> V.new(items1)).should be(1)
+        end
+      end
+
+      describe "with #{items1} and #{items1}" do
+        it "returns 0" do
+          (V.new(items1) <=> V.new(items1)).should be(0)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/concat_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/concat_spec.rb
new file mode 100755
index 0000000..87ab84e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/concat_spec.rb
@@ -0,0 +1,35 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  [:+, :concat].each do |method|
+    describe "##{method}" do
+      let(:vector) { V.new(1..100) }
+
+      it "preserves the original" do
+        vector.concat([1,2,3])
+        vector.should eql(V.new(1..100))
+      end
+
+      it "appends the elements in the other enumerable" do
+        vector.concat([1,2,3]).should eql(V.new((1..100).to_a + [1,2,3]))
+        vector.concat(1..1000).should eql(V.new((1..100).to_a + (1..1000).to_a))
+        vector.concat(1..200).size.should == 300
+        vector.concat(vector).should eql(V.new((1..100).to_a * 2))
+        vector.concat(V.empty).should eql(vector)
+        V.empty.concat(vector).should eql(vector)
+      end
+
+      [1, 31, 32, 33, 1023, 1024, 1025].each do |size|
+        context "on a #{size}-item vector" do
+          it "works the same" do
+            vector = V.new(1..size)
+            result = vector.concat((size+1)..size+10)
+            result.size.should == size + 10
+            result.should eql(V.new(1..(size+10)))
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/copying_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/copying_spec.rb
new file mode 100755
index 0000000..829ab78
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/copying_spec.rb
@@ -0,0 +1,21 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  [:dup, :clone].each do |method|
+    [
+      [],
+      ["A"],
+      %w[A B C],
+      (1..32),
+    ].each do |values|
+      describe "on #{values.inspect}" do
+        let(:vector) { V[*values] }
+
+        it "returns self" do
+          vector.send(method).should equal(vector)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/count_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/count_spec.rb
new file mode 100755
index 0000000..8eab1d2
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/count_spec.rb
@@ -0,0 +1,18 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#count" do
+    it "returns the number of elements" do
+      V[:a, :b, :c].count.should == 3
+    end
+
+    it "returns the number of elements that equal the argument" do
+      V[:a, :b, :b, :c].count(:b).should == 2
+    end
+
+    it "returns the number of element for which the block evaluates to true" do
+      V[:a, :b, :c].count { |s| s != :b }.should == 2
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/delete_at_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/delete_at_spec.rb
new file mode 100755
index 0000000..1a05190
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/delete_at_spec.rb
@@ -0,0 +1,54 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#delete_at" do
+    let(:vector) { V[1,2,3,4,5] }
+
+    it "removes the element at the specified index" do
+      vector.delete_at(0).should eql(V[2,3,4,5])
+      vector.delete_at(2).should eql(V[1,2,4,5])
+      vector.delete_at(-1).should eql(V[1,2,3,4])
+    end
+
+    it "makes no modification if the index is out of range" do
+      vector.delete_at(5).should eql(vector)
+      vector.delete_at(-6).should eql(vector)
+    end
+
+    it "works when deleting last item at boundary where vector trie needs to get shallower" do
+      vector = Hamster::Vector.new(1..33)
+      vector.delete_at(32).size.should == 32
+      vector.delete_at(32).to_a.should eql((1..32).to_a)
+    end
+
+    it "works on an empty vector" do
+      V.empty.delete_at(0).should be(V.empty)
+      V.empty.delete_at(1).should be(V.empty)
+    end
+
+    it "works on a vector with 1 item" do
+      V[10].delete_at(0).should eql(V.empty)
+      V[10].delete_at(1).should eql(V[10])
+    end
+
+    it "works on a vector with 32 items" do
+      V.new(1..32).delete_at(0).should eql(V.new(2..32))
+      V.new(1..32).delete_at(31).should eql(V.new(1..31))
+    end
+
+    it "has the right size and contents after many deletions" do
+      array  = (1..2000).to_a # we use an Array as standard of correctness
+      vector = Hamster::Vector.new(array)
+      500.times do
+        index = rand(vector.size)
+        vector = vector.delete_at(index)
+        array.delete_at(index)
+        vector.size.should == array.size
+        ary = vector.to_a
+        ary.size.should == vector.size
+        ary.should eql(array)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/delete_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/delete_spec.rb
new file mode 100755
index 0000000..ee8db82
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/delete_spec.rb
@@ -0,0 +1,31 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#delete" do
+    it "removes elements that are #== to the argument" do
+      V[1,2,3].delete(1).should eql(V[2,3])
+      V[1,2,3].delete(2).should eql(V[1,3])
+      V[1,2,3].delete(3).should eql(V[1,2])
+      V[1,2,3].delete(0).should eql(V[1,2,3])
+      V['a','b','a','c','a','a','d'].delete('a').should eql(V['b','c','d'])
+
+      V[EqualNotEql.new, EqualNotEql.new].delete(:something).should eql(V.empty)
+      V[EqlNotEqual.new, EqlNotEqual.new].delete(:something).should_not be_empty
+    end
+
+    context "on an empty vector" do
+      it "returns self" do
+        V.empty.delete(1).should be(V.empty)
+      end
+    end
+
+    context "on a subclass of Vector" do
+      it "returns an instance of the subclass" do
+        subclass = Class.new(Hamster::Vector)
+        instance = subclass.new([1,2,3])
+        instance.delete(1).class.should be(subclass)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/dig_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/dig_spec.rb
new file mode 100755
index 0000000..e457f3b
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/dig_spec.rb
@@ -0,0 +1,28 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  let(:v) { V[1, 2, V[3, 4]] }
+
+  describe "#dig" do
+    it "returns value at the index with one argument" do
+      expect(v.dig(0)).to eq(1)
+    end
+
+    it "returns value at index in nested arrays" do
+      expect(v.dig(2, 0)).to eq(3)
+    end
+
+    it "returns nil when indexing deeper than possible" do
+      expect(v.dig(0, 0)).to eq(nil)
+    end
+
+    it "returns nil if you index past the end of an array" do
+      expect(v.dig(5)).to eq(nil)
+    end
+
+    it "raises a type error when indexing with a key arrays don't understand" do
+      expect{ v.dig(:foo) }.to raise_error(ArgumentError)
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/drop_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/drop_spec.rb
new file mode 100755
index 0000000..1790e3d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/drop_spec.rb
@@ -0,0 +1,42 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#drop" do
+    [
+      [[], 10, []],
+      [["A"], 10, []],
+      [["A"], 1, []],
+      [["A"], 0, ["A"]],
+      [%w[A B C], 0, %w[A B C]],
+      [%w[A B C], 2, ["C"]],
+      [(1..32), 3, (4..32)],
+      [(1..33), 32, [33]]
+    ].each do |values, number, expected|
+      describe "#{number} from #{values.inspect}" do
+        let(:vector) { V[*values] }
+
+        it "preserves the original" do
+          vector.drop(number)
+          vector.should eql(V[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          vector.drop(number).should eql(V[*expected])
+        end
+      end
+    end
+
+    it "raises an ArgumentError if number of elements specified is negative" do
+      -> { V[1, 2, 3].drop(-1) }.should raise_error(ArgumentError)
+      -> { V[1, 2, 3].drop(-3) }.should raise_error(ArgumentError)
+    end
+
+    context "when number of elements specified is zero" do
+      let(:vector) { V[1, 2, 3, 4, 5, 6] }
+      it "returns self" do
+        vector.drop(0).should be(vector)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/drop_while_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/drop_while_spec.rb
new file mode 100755
index 0000000..a2c7d2e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/drop_while_spec.rb
@@ -0,0 +1,55 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#drop_while" do
+    [
+      [[], []],
+      [["A"], []],
+      [%w[A B C], ["C"]],
+    ].each do |values, expected|
+      describe "on #{values.inspect}" do
+        let(:vector) { V[*values] }
+
+        describe "with a block" do
+          let(:result) { vector.drop_while { |item| item < "C" } }
+
+          it "preserves the original" do
+            result
+            vector.should eql(V[*values])
+          end
+
+          it "returns #{expected.inspect}" do
+            result.should eql(V[*expected])
+          end
+        end
+
+        describe "without a block" do
+          it "returns an Enumerator" do
+            vector.drop_while.class.should be(Enumerator)
+            vector.drop_while.each { |item| item < "C" }.should eql(V[*expected])
+          end
+        end
+      end
+    end
+
+    context "on an empty vector" do
+      it "returns an empty vector" do
+        V.empty.drop_while { false }.should eql(V.empty)
+      end
+    end
+
+    it "returns an empty vector if block is always true" do
+      V.new(1..32).drop_while { true }.should eql(V.empty)
+      V.new(1..100).drop_while { true }.should eql(V.empty)
+    end
+
+    it "stops dropping items if block returns nil" do
+      V[1, 2, 3, nil, 4, 5].drop_while { |x| x }.should eql(V[nil, 4, 5])
+    end
+
+    it "stops dropping items if block returns false" do
+      V[1, 2, 3, false, 4, 5].drop_while { |x| x }.should eql(V[false, 4, 5])
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/each_index_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/each_index_spec.rb
new file mode 100755
index 0000000..ad2e8ba
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/each_index_spec.rb
@@ -0,0 +1,41 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#each_index" do
+    let(:vector) { V[1,2,3,4] }
+
+    context "with a block" do
+      it "yields all the valid indices into the vector" do
+        result = []
+        vector.each_index { |i| result << i }
+        result.should eql([0,1,2,3])
+      end
+
+      it "returns self" do
+        vector.each_index {}.should be(vector)
+      end
+    end
+
+    context "without a block" do
+      it "returns an Enumerator" do
+        vector.each_index.class.should be(Enumerator)
+        vector.each_index.to_a.should eql([0,1,2,3])
+      end
+    end
+
+    context "on an empty vector" do
+      it "doesn't yield anything" do
+        V.empty.each_index { fail }
+      end
+    end
+
+    [1, 2, 10, 31, 32, 33, 1000, 1024, 1025].each do |size|
+      context "on a #{size}-item vector" do
+        it "yields all valid indices" do
+          V.new(1..size).each_index.to_a.should == (0..(size-1)).to_a
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/each_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/each_spec.rb
new file mode 100755
index 0000000..10dae72
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/each_spec.rb
@@ -0,0 +1,45 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#each" do
+    describe "with no block" do
+      let(:vector) { V["A", "B", "C"] }
+
+      it "returns an Enumerator" do
+        vector.each.class.should be(Enumerator)
+        vector.each.to_a.should == vector
+      end
+    end
+
+    [31, 32, 33, 1023, 1024, 1025].each do |size|
+      context "on a #{size}-item vector" do
+        describe "with a block" do
+          let(:vector) { V.new(1..size) }
+
+          it "returns self" do
+            items = []
+            vector.each { |item| items << item }.should be(vector)
+          end
+
+          it "yields all the items" do
+            items = []
+            vector.each { |item| items << item }
+            items.should == (1..size).to_a
+          end
+
+          it "iterates over the items in order" do
+            vector.each.first.should == 1
+            vector.each.to_a.last.should == size
+          end
+        end
+      end
+    end
+
+    context "on an empty vector" do
+      it "doesn't yield anything" do
+        V.empty.each { fail }
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/each_with_index_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/each_with_index_spec.rb
new file mode 100755
index 0000000..ac8f79f
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/each_with_index_spec.rb
@@ -0,0 +1,40 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#each_with_index" do
+    describe "with no block" do
+      let(:vector) { V["A", "B", "C"] }
+
+      it "returns an Enumerator" do
+        vector.each_with_index.class.should be(Enumerator)
+        vector.each_with_index.to_a.should == [['A', 0], ['B', 1], ['C', 2]]
+      end
+    end
+
+    [1, 2, 31, 32, 33, 1023, 1024, 1025].each do |size|
+      context "on a #{size}-item vector" do
+        describe "with a block" do
+          let(:vector) { V.new(1..size) }
+
+          it "returns self" do
+            pairs = []
+            vector.each_with_index { |item, index| pairs << [item, index] }.should be(vector)
+          end
+
+          it "iterates over the items in order" do
+            pairs = []
+            vector.each_with_index { |item, index| pairs << [item, index] }.should be(vector)
+            pairs.should == (1..size).zip(0..size.pred)
+          end
+        end
+      end
+    end
+
+    context "on an empty vector" do
+      it "doesn't yield anything" do
+        V.empty.each_with_index { |item, index| fail }
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/empty_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/empty_spec.rb
new file mode 100755
index 0000000..ce92b7d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/empty_spec.rb
@@ -0,0 +1,42 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#empty?" do
+    [
+      [[], true],
+      [["A"], false],
+      [%w[A B C], false],
+    ].each do |values, expected|
+      describe "on #{values.inspect}" do
+        it "returns #{expected.inspect}" do
+          V[*values].empty?.should == expected
+        end
+      end
+    end
+  end
+
+  describe ".empty" do
+    it "returns the canonical empty vector" do
+      V.empty.size.should be(0)
+      V.empty.object_id.should be(V.empty.object_id)
+    end
+
+    context "from a subclass" do
+      it "returns an empty instance of the subclass" do
+        subclass = Class.new(Hamster::Vector)
+        subclass.empty.class.should be(subclass)
+        subclass.empty.should be_empty
+      end
+
+      it "calls overridden #initialize when creating empty Hash" do
+        subclass = Class.new(Hamster::Vector) do
+          def initialize
+            @variable = 'value'
+          end
+        end
+        subclass.empty.instance_variable_get(:@variable).should == 'value'
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/eql_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/eql_spec.rb
new file mode 100755
index 0000000..e8eebd4
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/eql_spec.rb
@@ -0,0 +1,77 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#eql" do
+    let(:vector) { V["A", "B", "C"] }
+
+    it "returns false when comparing with an array with the same contents" do
+      vector.eql?(%w[A B C]).should == false
+    end
+
+    it "returns false when comparing with an arbitrary object" do
+      vector.eql?(Object.new).should == false
+    end
+
+    it "returns false when comparing an empty vector with an empty array" do
+      V.empty.eql?([]).should == false
+    end
+
+    it "returns false when comparing with a subclass of Hamster::Vector" do
+      vector.eql?(Class.new(Hamster::Vector).new(%w[A B C])).should == false
+    end
+  end
+
+  describe "#==" do
+    let(:vector) { V["A", "B", "C"] }
+
+    it "returns true when comparing with an array with the same contents" do
+      (vector == %w[A B C]).should == true
+    end
+
+    it "returns false when comparing with an arbitrary object" do
+      (vector == Object.new).should == false
+    end
+
+    it "returns true when comparing an empty vector with an empty array" do
+      (V.empty == []).should == true
+    end
+
+    it "returns true when comparing with a subclass of Hamster::Vector" do
+      (vector == Class.new(Hamster::Vector).new(%w[A B C])).should == true
+    end
+
+    it "works on larger vectors" do
+      array = 2000.times.map { rand(10000) }
+      (V.new(array.dup) == array).should == true
+    end
+  end
+
+  [:eql?, :==].each do |method|
+    describe "##{method}" do
+      [
+        [[], [], true],
+        [[], [nil], false],
+        [["A"], [], false],
+        [["A"], ["A"], true],
+        [["A"], ["B"], false],
+        [%w[A B], ["A"], false],
+        [%w[A B C], %w[A B C], true],
+        [%w[C A B], %w[A B C], false],
+      ].each do |a, b, expected|
+        describe "returns #{expected.inspect}" do
+          let(:vector_a) { V[*a] }
+          let(:vector_b) { V[*b] }
+
+          it "for vectors #{a.inspect} and #{b.inspect}" do
+            vector_a.send(method, vector_b).should == expected
+          end
+
+          it "for vectors #{b.inspect} and #{a.inspect}" do
+            vector_b.send(method, vector_a).should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/fetch_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/fetch_spec.rb
new file mode 100755
index 0000000..f3520fe
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/fetch_spec.rb
@@ -0,0 +1,65 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#fetch" do
+    let(:vector) { V['a', 'b', 'c'] }
+
+    context "with no default provided" do
+      context "when the index exists" do
+        it "returns the value at the index" do
+          vector.fetch(0).should == "a"
+          vector.fetch(1).should == "b"
+          vector.fetch(2).should == "c"
+        end
+      end
+
+      context "when the key does not exist" do
+        it "raises an IndexError" do
+          -> { vector.fetch(3) }.should raise_error(IndexError)
+          -> { vector.fetch(-4) }.should raise_error(IndexError)
+        end
+      end
+    end
+
+    context "with a default value" do
+      context "when the index exists" do
+        it "returns the value at the index" do
+          vector.fetch(0, "default").should == "a"
+          vector.fetch(1, "default").should == "b"
+          vector.fetch(2, "default").should == "c"
+        end
+      end
+
+      context "when the index does not exist" do
+        it "returns the default value" do
+          vector.fetch(3, "default").should == "default"
+          vector.fetch(-4, "default").should == "default"
+        end
+      end
+    end
+
+    context "with a default block" do
+      context "when the index exists" do
+        it "returns the value at the index" do
+          vector.fetch(0) { "default".upcase }.should == "a"
+          vector.fetch(1) { "default".upcase }.should == "b"
+          vector.fetch(2) { "default".upcase }.should == "c"
+        end
+      end
+
+      context "when the index does not exist" do
+        it "invokes the block with the missing index as parameter" do
+          vector.fetch(3) { |index| index.should == 3}
+          vector.fetch(-4) { |index| index.should == -4 }
+          vector.fetch(3) { "default".upcase }.should == "DEFAULT"
+          vector.fetch(-4) { "default".upcase }.should == "DEFAULT"
+        end
+      end
+    end
+
+    it "gives precedence to default block over default argument if passed both" do
+      vector.fetch(3, 'one') { 'two' }.should == 'two'
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/fill_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/fill_spec.rb
new file mode 100755
index 0000000..1dffcaa
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/fill_spec.rb
@@ -0,0 +1,89 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#fill" do
+    let(:vector) { V[1, 2, 3, 4, 5, 6] }
+
+    it "can replace a range of items at the beginning of a vector" do
+      vector.fill(:a, 0, 3).should eql(V[:a, :a, :a, 4, 5, 6])
+    end
+
+    it "can replace a range of items in the middle of a vector" do
+      vector.fill(:a, 3, 2).should eql(V[1, 2, 3, :a, :a, 6])
+    end
+
+    it "can replace a range of items at the end of a vector" do
+      vector.fill(:a, 4, 2).should eql(V[1, 2, 3, 4, :a, :a])
+    end
+
+    it "can replace all the items in a vector" do
+      vector.fill(:a, 0, 6).should eql(V[:a, :a, :a, :a, :a, :a])
+    end
+
+    it "can fill past the end of the vector" do
+      vector.fill(:a, 3, 6).should eql(V[1, 2, 3, :a, :a, :a, :a, :a, :a])
+    end
+
+    context "with 1 argument" do
+      it "replaces all the items in the vector by default" do
+        vector.fill(:a).should eql(V[:a, :a, :a, :a, :a, :a])
+      end
+    end
+
+    context "with 2 arguments" do
+      it "replaces up to the end of the vector by default" do
+        vector.fill(:a, 4).should eql(V[1, 2, 3, 4, :a, :a])
+      end
+    end
+
+    context "when index and length are 0" do
+      it "leaves the vector unmodified" do
+        vector.fill(:a, 0, 0).should eql(vector)
+      end
+    end
+
+    context "when expanding a vector past boundary where vector trie needs to deepen" do
+      it "works the same" do
+        vector.fill(:a, 32, 3).size.should == 35
+        vector.fill(:a, 32, 3).to_a.size.should == 35
+      end
+    end
+
+    [1000, 1023, 1024, 1025, 2000].each do |size|
+      context "on a #{size}-item vector" do
+        it "works the same" do
+          array = (0..size).to_a
+          vector = V.new(array)
+          [[:a, 0, 5], [:b, 31, 2], [:c, 32, 60], [:d, 1000, 20], [:e, 1024, 33], [:f, 1200, 35]].each do |obj, index, length|
+            next if index > size
+            vector = vector.fill(obj, index, length)
+            array.fill(obj, index, length)
+            vector.size.should == array.size
+            ary = vector.to_a
+            ary.size.should == vector.size
+            ary.should eql(array)
+          end
+        end
+      end
+    end
+
+    it "behaves like Array#fill, on a variety of inputs" do
+      50.times do
+        array = rand(100).times.map { rand(1000) }
+        index = rand(array.size)
+        length = rand(50)
+        V.new(array).fill(:a, index, length).should == array.fill(:a, index, length)
+      end
+      10.times do
+        array = rand(100).times.map { rand(10000) }
+        length = rand(100)
+        V.new(array).fill(:a, array.size, length).should == array.fill(:a, array.size, length)
+      end
+      10.times do
+        array = rand(100).times.map { rand(10000) }
+        V.new(array).fill(:a).should == array.fill(:a)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/first_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/first_spec.rb
new file mode 100755
index 0000000..7538ae7
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/first_spec.rb
@@ -0,0 +1,19 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#first" do
+    [
+      [[], nil],
+      [["A"], "A"],
+      [%w[A B C], "A"],
+      [(1..32), 1],
+    ].each do |values, expected|
+      describe "on #{values.inspect}" do
+        it "returns #{expected.inspect}" do
+          V[*values].first.should == expected
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/flat_map_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/flat_map_spec.rb
new file mode 100755
index 0000000..5fb4352
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/flat_map_spec.rb
@@ -0,0 +1,51 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  let(:vector) { V[*values] }
+
+  describe "#flat_map" do
+    let(:block) { ->(item) { [item, item + 1, item * item] } }
+    let(:flat_map) { vector.flat_map(&block) }
+    let(:flattened_vector) { V[*flattened_values] }
+
+    shared_examples "checking flattened result" do
+      it "returns the flattened values as a Hamster::Vector" do
+        expect(flat_map).to eq(flattened_vector)
+      end
+
+      it "returns a Hamster::Vector" do
+        expect(flat_map).to be_a(Hamster::Vector)
+      end
+    end
+
+    context "with an empty vector" do
+      let(:values) { [] }
+      let(:flattened_values) { [] }
+
+      include_examples "checking flattened result"
+    end
+
+    context "with a block that returns an empty vector" do
+      let(:block) { ->(item) { [] } }
+      let(:values) { [1, 2, 3] }
+      let(:flattened_values) { [] }
+
+      include_examples "checking flattened result"
+    end
+
+    context "with a vector of one item" do
+      let(:values) { [7] }
+      let(:flattened_values) { [7, 8, 49] }
+
+      include_examples "checking flattened result"
+    end
+
+    context "with a vector of multiple items" do
+      let(:values) { [1, 2, 3] }
+      let(:flattened_values) { [1, 2, 1, 2, 3, 4, 3, 4, 9] }
+
+      include_examples "checking flattened result"
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/flatten_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/flatten_spec.rb
new file mode 100755
index 0000000..97e4cfe
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/flatten_spec.rb
@@ -0,0 +1,59 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#flatten" do
+    it "recursively flattens nested vectors into containing vector" do
+      V[V[1], V[2]].flatten.should eql(V[1,2])
+      V[V[V[V[V[V[1,2,3]]]]]].flatten.should eql(V[1,2,3])
+      V[V[V[1]], V[V[V[2]]]].flatten.should eql(V[1,2])
+    end
+
+    it "flattens nested arrays as well" do
+      V[[1,2,3],[[4],[5,6]]].flatten.should eql(V[1,2,3,4,5,6])
+    end
+
+    context "with an integral argument" do
+      it "only flattens down to the specified depth" do
+        V[V[V[1,2]]].flatten(1).should eql(V[V[1,2]])
+        V[V[V[V[1]], V[2], V[3]]].flatten(2).should eql(V[V[1], 2, 3])
+      end
+    end
+
+    context "with an argument of zero" do
+      it "returns self" do
+        vector = V[1,2,3]
+        vector.flatten(0).should be(vector)
+      end
+    end
+
+    context "on a subclass" do
+      it "returns an instance of the subclass" do
+        subclass = Class.new(Hamster::Vector)
+        instance = subclass.new([1,2])
+        instance.flatten.class.should be(subclass)
+      end
+    end
+
+    context "on a vector with no nested vectors" do
+      it "returns an unchanged vector" do
+        vector = V[1,2,3]
+        vector.flatten.should.eql?(V[1,2,3])
+      end
+
+      context "on a Vector larger than 32 items initialized with Vector.new" do
+        # Regression test, for problem discovered while working on GH issue #182
+        it "returns an unchanged vector" do
+          vector1,vector2 = 2.times.collect { V.new(0..33) }
+          vector1.flatten.should eql(vector2)
+        end
+      end
+    end
+
+    it "leaves the original unmodified" do
+      vector = V[1,2,3]
+      vector.flatten
+      vector.should eql(V[1,2,3])
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/get_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/get_spec.rb
new file mode 100755
index 0000000..d3b92e5
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/get_spec.rb
@@ -0,0 +1,75 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  [:get, :at].each do |method|
+    describe "##{method}" do
+      context "when empty" do
+        it "always returns nil" do
+          (-1..1).each do |i|
+            V.empty.send(method, i).should be_nil
+          end
+        end
+      end
+
+      context "when not empty" do
+        let(:vector) { V[*(1..1025)] }
+
+        context "with a positive index" do
+          context "within the absolute bounds of the vector" do
+            it "returns the value at the specified index from the head" do
+              (0..(vector.size - 1)).each do |i|
+                vector.send(method, i).should == i + 1
+              end
+            end
+          end
+
+          context "outside the absolute bounds of the vector" do
+            it "returns nil" do
+              vector.send(method, vector.size).should be_nil
+            end
+          end
+        end
+
+        context "with a negative index" do
+          context "within the absolute bounds of the vector" do
+            it "returns the value at the specified index from the tail" do
+              (-vector.size..-1).each do |i|
+                vector.send(method, i).should == vector.size + i + 1
+              end
+            end
+          end
+
+          context "outside the absolute bounds of the vector" do
+            it "returns nil" do
+              vector.send(method, -vector.size.next).should be_nil
+            end
+          end
+        end
+      end
+
+      [1, 10, 31, 32, 33, 1024, 1025, 2000].each do |size|
+        context "on a #{size}-item vector" do
+          it "works correctly, even after various addings and removings" do
+            array = size.times.map { rand(10000) }
+            vector = V.new(array)
+            100.times do
+              if rand(2) == 0
+                value, index = rand(10000), rand(size)
+                array[index] = value
+                vector = vector.put(index, value)
+              else
+                index = rand(array.size)
+                array.delete_at(index)
+                vector = vector.delete_at(index)
+              end
+            end
+            0.upto(array.size) do |i|
+              array[i].should == vector.send(method, i)
+            end
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/group_by_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/group_by_spec.rb
new file mode 100755
index 0000000..6bb70c1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/group_by_spec.rb
@@ -0,0 +1,58 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#group_by" do
+    context "with a block" do
+      [
+        [[], []],
+        [[1], [true => V[1]]],
+        [[1, 2, 3, 4], [true => V[1, 3], false => V[2, 4]]],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          let(:vector) { V[*values] }
+
+          it "returns #{expected.inspect}" do
+            vector.group_by(&:odd?).should eql(H[*expected])
+            vector.should eql(V.new(values)) # make sure it hasn't changed
+          end
+        end
+      end
+    end
+
+    context "without a block" do
+      [
+        [[], []],
+        [[1], [1 => V[1]]],
+        [[1, 2, 3, 4], [1 => V[1], 2 => V[2], 3 => V[3], 4 => V[4]]],
+      ].each do |values, expected|
+        context "on #{values.inspect}" do
+          let(:vector) { V[*values] }
+
+          it "returns #{expected.inspect}" do
+            vector.group_by.should eql(H[*expected])
+            vector.should eql(V.new(values)) # make sure it hasn't changed
+          end
+        end
+      end
+    end
+
+    context "on an empty vector" do
+      it "returns an empty hash" do
+        V.empty.group_by { |x| x }.should eql(H.empty)
+      end
+    end
+
+    it "returns a hash without default proc" do
+      V[1,2,3].group_by { |x| x }.default_proc.should be_nil
+    end
+
+    context "from a subclass" do
+      it "returns an Hash whose values are instances of the subclass" do
+        subclass = Class.new(Hamster::Vector)
+        instance = subclass.new([1, 'string', :symbol])
+        instance.group_by { |x| x.class }.values.each { |v| v.class.should be(subclass) }
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/include_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/include_spec.rb
new file mode 100755
index 0000000..0e57f49
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/include_spec.rb
@@ -0,0 +1,31 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  [:include?, :member?].each do |method|
+    describe "##{method}" do
+      [
+        [[], "A", false],
+        [[], nil, false],
+        [["A"], "A", true],
+        [["A"], "B", false],
+        [["A"], nil, false],
+        [["A", "B", nil], "A", true],
+        [["A", "B", nil], "B", true],
+        [["A", "B", nil], nil, true],
+        [["A", "B", nil], "C", false],
+        [["A", "B", false], false, true],
+        [[2], 2, true],
+        [[2], 2.0, true],
+        [[2.0], 2.0, true],
+        [[2.0], 2, true],
+      ].each do |values, item, expected|
+        describe "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            V[*values].send(method, item).should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/insert_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/insert_spec.rb
new file mode 100755
index 0000000..fe89314
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/insert_spec.rb
@@ -0,0 +1,69 @@
+require "spec_helper"
+require "hamster/vector"
+require 'pry'
+
+describe Hamster::Vector do
+  describe "#insert" do
+    let(:original) { V[1, 2, 3] }
+
+    it "can add items at the beginning of a vector" do
+      vector = original.insert(0, :a, :b)
+      vector.size.should be(5)
+      vector.at(0).should be(:a)
+      vector.at(2).should be(1)
+    end
+
+    it "can add items in the middle of a vector" do
+      vector = original.insert(1, :a, :b, :c)
+      vector.size.should be(6)
+      vector.to_a.should == [1, :a, :b, :c, 2, 3]
+    end
+
+    it "can add items at the end of a vector" do
+      vector = original.insert(3, :a, :b, :c)
+      vector.size.should be(6)
+      vector.to_a.should == [1, 2, 3, :a, :b, :c]
+    end
+
+    it "can add items past the end of a vector" do
+      vector = original.insert(6, :a, :b)
+      vector.size.should be(8)
+      vector.to_a.should == [1, 2, 3, nil, nil, nil, :a, :b]
+    end
+
+    it "accepts a negative index, which counts back from the end of the vector" do
+      vector = original.insert(-2, :a)
+      vector.size.should be(4)
+      vector.to_a.should == [1, :a, 2, 3]
+    end
+
+    it "raises IndexError if a negative index is too great" do
+      expect { original.insert(-4, :a) }.to raise_error(IndexError)
+    end
+
+    it "works when adding an item past boundary when vector trie needs to deepen" do
+      vector = original.insert(32, :a, :b)
+      vector.size.should == 34
+      vector.to_a.size.should == 34
+    end
+
+    it "works when adding to an empty Vector" do
+      V.empty.insert(0, :a).should eql(V[:a])
+    end
+
+    it "has the right size and contents after many insertions" do
+      array  = (1..4000).to_a # we use an Array as standard of correctness
+      vector = Hamster::Vector.new(array)
+      100.times do
+        items = rand(10).times.map { rand(10000) }
+        index = rand(vector.size)
+        vector = vector.insert(index, *items)
+        array.insert(index, *items)
+        vector.size.should == array.size
+        ary = vector.to_a
+        ary.size.should == vector.size
+        ary.should eql(array)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/inspect_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/inspect_spec.rb
new file mode 100755
index 0000000..7fd855e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/inspect_spec.rb
@@ -0,0 +1,50 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  let(:vector) { V[*values] }
+
+  describe "#inspect" do
+    let(:inspect) { vector.inspect }
+
+    shared_examples "checking output" do
+      it "returns its contents as a programmer-readable string" do
+        expect(inspect).to eq(output)
+      end
+
+      it "returns a string which can be eval'd to get back an equivalent vector" do
+        expect(eval(inspect)).to eql(vector)
+      end
+    end
+
+    context "with an empty array" do
+      let(:output) { "Hamster::Vector[]" }
+      let(:values) { [] }
+
+      include_examples "checking output"
+    end
+
+    context "with a single item array" do
+      let(:output) { "Hamster::Vector[\"A\"]" }
+      let(:values) { %w[A] }
+
+      include_examples "checking output"
+    end
+
+    context "with a multi-item array" do
+      let(:output) { "Hamster::Vector[\"A\", \"B\"]" }
+      let(:values) { %w[A B] }
+
+      include_examples "checking output"
+    end
+
+    context "from a subclass" do
+      MyVector = Class.new(Hamster::Vector)
+      let(:vector) { MyVector.new(values) }
+      let(:output) { "MyVector[1, 2]" }
+      let(:values) { [1, 2] }
+
+      include_examples "checking output"
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/join_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/join_spec.rb
new file mode 100755
index 0000000..87d093d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/join_spec.rb
@@ -0,0 +1,59 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#join" do
+    context "with a separator" do
+      [
+        [[], ""],
+        [["A"], "A"],
+        [[DeterministicHash.new("A", 1), DeterministicHash.new("B", 2), DeterministicHash.new("C", 3)], "A|B|C"]
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          let(:vector) { V[*values] }
+
+          it "preserves the original" do
+            vector.join("|")
+            vector.should eql(V[*values])
+          end
+
+          it "returns #{expected.inspect}" do
+            vector.join("|").should == expected
+          end
+        end
+      end
+    end
+
+    context "without a separator" do
+      [
+        [[], ""],
+        [["A"], "A"],
+        [[DeterministicHash.new("A", 1), DeterministicHash.new("B", 2), DeterministicHash.new("C", 3)], "ABC"]
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          let(:vector) { V[*values] }
+
+          it "preserves the original" do
+            vector.join
+            vector.should eql(V[*values])
+          end
+
+          it "returns #{expected.inspect}" do
+            vector.join.should == expected
+          end
+        end
+      end
+    end
+
+    context "without a separator (with global default separator set)" do
+      before { $, = '**' }
+      after  { $, = nil }
+
+      describe 'on ["A", "B", "C"]' do
+        it 'returns "A**B**C"' do
+          V["A", "B", "C"].join.should == "A**B**C"
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/last_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/last_spec.rb
new file mode 100755
index 0000000..7807989
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/last_spec.rb
@@ -0,0 +1,46 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  let(:vector) { V[*values] }
+
+  describe "#last" do
+    let(:last) { vector.last }
+
+    shared_examples "checking values" do
+      it "returns the last item" do
+        expect(last).to eq(last_item)
+      end
+    end
+
+    context "with an empty vector" do
+      let(:last_item) { nil }
+      let(:values) { [] }
+
+      include_examples "checking values"
+    end
+
+    context "with a single item vector" do
+      let(:last_item) { "A" }
+      let(:values) { %w[A] }
+
+      include_examples "checking values"
+    end
+
+    context "with a multi-item vector" do
+      let(:last_item) { "B" }
+      let(:values) { %w[A B] }
+
+      include_examples "checking values"
+    end
+
+    [31, 32, 33, 1023, 1024, 1025].each do |size|
+      context "with a #{size}-item vector" do
+        let(:last_item) { size }
+        let(:values) { (1..size).to_a }
+
+        include_examples "checking values"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/length_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/length_spec.rb
new file mode 100755
index 0000000..da13236
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/length_spec.rb
@@ -0,0 +1,46 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  let(:vector) { V[*values] }
+
+  describe "#length" do
+    let(:length) { vector.length }
+
+    shared_examples "checking size" do
+      it "returns the values" do
+        expect(length).to eq(size)
+      end
+    end
+
+    context "with an empty vector" do
+      let(:values) { [] }
+      let(:size) { 0 }
+
+      include_examples "checking size"
+    end
+
+    context "with a single item vector" do
+      let(:values) { %w[A] }
+      let(:size) { 1 }
+
+      include_examples "checking size"
+    end
+
+    context "with a multi-item vector" do
+      let(:values) { %w[A B] }
+      let(:size) { 2 }
+
+      include_examples "checking size"
+    end
+
+    [31, 32, 33, 1023, 1024, 1025].each do |size|
+      context "with a #{size}-item vector" do
+        let(:values) { (1..size).to_a }
+        let(:size) { size }
+
+        include_examples "checking size"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/ltlt_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/ltlt_spec.rb
new file mode 100755
index 0000000..88f67f2
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/ltlt_spec.rb
@@ -0,0 +1,66 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  let(:vector) { V[*values] }
+
+  describe "#<<" do
+    let(:ltlt) { vector << added_value }
+
+    shared_examples "checking adding values" do
+      let(:added_vector) { V[*added_values] }
+
+      it "preserves the original" do
+        original = vector
+        vector << added_value
+        expect(original).to eq(vector)
+      end
+
+      it "ltlts the item to the vector" do
+        expect(ltlt).to eq(added_vector)
+      end
+    end
+
+    context "with a empty array adding a single item" do
+      let(:values) { [] }
+      let(:added_value) { "A" }
+      let(:added_values) { ["A"] }
+
+      include_examples "checking adding values"
+    end
+
+    context "with a single-item array adding a different item" do
+      let(:values) { ["A"] }
+      let(:added_value) { "B" }
+      let(:added_values) { %w[A B] }
+
+      include_examples "checking adding values"
+    end
+
+    context "with a single-item array adding a duplicate item" do
+      let(:values) { ["A"] }
+      let(:added_value) { "A" }
+      let(:added_values) { %w[A A] }
+
+      include_examples "checking adding values"
+    end
+
+    [31, 32, 33, 1023, 1024, 1025].each do |size|
+      context "with a #{size}-item vector adding a different item" do
+        let(:values) { (1..size).to_a }
+        let(:added_value) { size+1 }
+        let(:added_values) { (1..(size+1)).to_a }
+
+        include_examples "checking adding values"
+      end
+    end
+
+    context "from a subclass" do
+      it "returns an instance of the subclass" do
+        subclass = Class.new(Hamster::Vector)
+        instance = subclass[1,2,3]
+        (instance << 4).class.should be(subclass)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/map_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/map_spec.rb
new file mode 100755
index 0000000..4615838
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/map_spec.rb
@@ -0,0 +1,52 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  [:map, :collect].each do |method|
+    describe "##{method}" do
+      context "when empty" do
+        let(:vector) { V.empty }
+
+        it "returns self" do
+          vector.send(method) {}.should equal(vector)
+        end
+      end
+
+      context "when not empty" do
+        let(:vector) { V["A", "B", "C"] }
+
+        context "with a block" do
+          it "preserves the original values" do
+            vector.send(method, &:downcase)
+            vector.should eql(V["A", "B", "C"])
+          end
+
+          it "returns a new vector with the mapped values" do
+            vector.send(method, &:downcase).should eql(V["a", "b", "c"])
+          end
+        end
+
+        context "with no block" do
+          it "returns an Enumerator" do
+            vector.send(method).class.should be(Enumerator)
+            vector.send(method).each(&:downcase).should eql(V['a', 'b', 'c'])
+          end
+        end
+      end
+
+      context "from a subclass" do
+        it "returns an instance of the subclass" do
+          subclass = Class.new(Hamster::Vector)
+          instance = subclass[1,2,3]
+          instance.map { |x| x + 1 }.class.should be(subclass)
+        end
+      end
+
+      context "on a large vector" do
+        it "works" do
+          V.new(1..2000).map { |x| x * 2 }.should eql(V.new((1..2000).map { |x| x * 2}))
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/marshal_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/marshal_spec.rb
new file mode 100755
index 0000000..4d1c58b
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/marshal_spec.rb
@@ -0,0 +1,32 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#marshal_dump/#marshal_load" do
+    let(:ruby) do
+      File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"])
+    end
+    let(:child_cmd) do
+      %Q|#{ruby} -I lib -r hamster -e 'vector = Hamster::Vector[5, 10, 15]; $stdout.write(Marshal.dump(vector))'|
+    end
+
+    let(:reloaded_vector) do
+      IO.popen(child_cmd, "r+") do |child|
+        reloaded_vector = Marshal.load(child)
+        child.close
+        reloaded_vector
+      end
+    end
+
+    it "can survive dumping and loading into a new process" do
+      expect(reloaded_vector).to eql(V[5, 10, 15])
+    end
+
+    it "is still possible to find items by index after loading" do
+      expect(reloaded_vector[0]).to eq(5)
+      expect(reloaded_vector[1]).to eq(10)
+      expect(reloaded_vector[2]).to eq(15)
+      expect(reloaded_vector.size).to eq(3)
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/maximum_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/maximum_spec.rb
new file mode 100755
index 0000000..7211f63
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/maximum_spec.rb
@@ -0,0 +1,34 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#max" do
+    context "with a block" do
+      [
+        [[], nil],
+        [["A"], "A"],
+        [%w[Ichi Ni San], "Ichi"],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            V[*values].max { |maximum, item| maximum.length <=> item.length }.should == expected
+          end
+        end
+      end
+    end
+
+    context "without a block" do
+      [
+        [[], nil],
+        [["A"], "A"],
+        [%w[Ichi Ni San], "San"],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            V[*values].max.should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/minimum_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/minimum_spec.rb
new file mode 100755
index 0000000..fff301c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/minimum_spec.rb
@@ -0,0 +1,34 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#min" do
+    context "with a block" do
+      [
+        [[], nil],
+        [["A"], "A"],
+        [%w[Ichi Ni San], "Ni"],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            V[*values].min { |minimum, item| minimum.length <=> item.length }.should == expected
+          end
+        end
+      end
+    end
+
+    context "without a block" do
+      [
+        [[], nil],
+        [["A"], "A"],
+        [%w[Ichi Ni San], "Ichi"],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          it "returns #{expected.inspect}" do
+            V[*values].min.should == expected
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/multiply_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/multiply_spec.rb
new file mode 100755
index 0000000..629f944
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/multiply_spec.rb
@@ -0,0 +1,48 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#*" do
+    let(:vector) { V[1, 2, 3] }
+
+    context "with a String argument" do
+      it "acts just like #join" do
+        (vector * 'boo').should eql(vector.join('boo'))
+      end
+    end
+
+    context "with an Integer argument" do
+      it "concatenates n copies of the array" do
+        (vector * 0).should eql(V.empty)
+        (vector * 1).should eql(vector)
+        (vector * 2).should eql(V[1,2,3,1,2,3])
+        (vector * 3).should eql(V[1,2,3,1,2,3,1,2,3])
+      end
+
+      it "raises an ArgumentError if integer is negative" do
+        -> { vector * -1 }.should raise_error(ArgumentError)
+      end
+
+      it "works on large vectors" do
+        array = (1..50).to_a
+        (V.new(array) * 25).should eql(V.new(array * 25))
+      end
+    end
+
+    context "with a subclass of Vector" do
+      it "returns an instance of the subclass" do
+        subclass = Class.new(Hamster::Vector)
+        instance = subclass.new([1,2,3])
+        (instance * 10).class.should be(subclass)
+      end
+    end
+
+    it "raises a TypeError if passed nil" do
+      -> { vector * nil }.should raise_error(TypeError)
+    end
+
+    it "raises an ArgumentError if passed no arguments" do
+      -> { vector.* }.should raise_error(ArgumentError)
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/new_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/new_spec.rb
new file mode 100755
index 0000000..b3f013f
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/new_spec.rb
@@ -0,0 +1,51 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe ".new" do
+    it "accepts a single enumerable argument and creates a new vector" do
+      vector = Hamster::Vector.new([1,2,3])
+      vector.size.should be(3)
+      vector[0].should be(1)
+      vector[1].should be(2)
+      vector[2].should be(3)
+    end
+
+    it "makes a defensive copy of a non-frozen mutable Array passed in" do
+      array = [1,2,3]
+      vector = Hamster::Vector.new(array)
+      array[0] = 'changed'
+      vector[0].should be(1)
+    end
+
+    it "is amenable to overriding of #initialize" do
+      class SnazzyVector < Hamster::Vector
+        def initialize
+          super(['SNAZZY!!!'])
+        end
+      end
+
+      vector = SnazzyVector.new
+      vector.size.should be(1)
+      vector.should == ['SNAZZY!!!']
+    end
+
+    context "from a subclass" do
+      it "returns a frozen instance of the subclass" do
+        subclass = Class.new(Hamster::Vector)
+        instance = subclass.new(["some", "values"])
+        instance.class.should be subclass
+        instance.frozen?.should be true
+      end
+    end
+  end
+
+  describe ".[]" do
+    it "accepts a variable number of items and creates a new vector" do
+      vector = Hamster::Vector['a', 'b']
+      vector.size.should be(2)
+      vector[0].should == 'a'
+      vector[1].should == 'b'
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/partition_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/partition_spec.rb
new file mode 100755
index 0000000..5db747d
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/partition_spec.rb
@@ -0,0 +1,53 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#partition" do
+    [
+      [[], [], []],
+      [[1], [1], []],
+      [[1, 2], [1], [2]],
+      [[1, 2, 3], [1, 3], [2]],
+      [[1, 2, 3, 4], [1, 3], [2, 4]],
+      [[2, 3, 4], [3], [2, 4]],
+      [[3, 4], [3], [4]],
+      [[4], [], [4]],
+    ].each do |values, expected_matches, expected_remainder|
+      describe "on #{values.inspect}" do
+        let(:vector) { V[*values] }
+
+        describe "with a block" do
+          let(:result)    { vector.partition(&:odd?) }
+          let(:matches)   { result.first }
+          let(:remainder) { result.last }
+
+          it "preserves the original" do
+            result
+            vector.should eql(V[*values])
+          end
+
+          it "returns a frozen array with two items" do
+            result.class.should be(Array)
+            result.should be_frozen
+            result.size.should be(2)
+          end
+
+          it "correctly identifies the matches" do
+            matches.should eql(V[*expected_matches])
+          end
+
+          it "correctly identifies the remainder" do
+            remainder.should eql(V[*expected_remainder])
+          end
+        end
+
+        describe "without a block" do
+          it "returns an Enumerator" do
+            vector.partition.class.should be(Enumerator)
+            vector.partition.each(&:odd?).should eql([V.new(expected_matches), V.new(expected_remainder)])
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/permutation_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/permutation_spec.rb
new file mode 100755
index 0000000..134ac7f
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/permutation_spec.rb
@@ -0,0 +1,92 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#permutation" do
+    let(:vector) { V[1,2,3,4] }
+
+    context "without a block or arguments" do
+      it "returns an Enumerator of all permutations" do
+        vector.permutation.class.should be(Enumerator)
+        vector.permutation.to_a.should eql(vector.to_a.permutation.to_a)
+      end
+    end
+
+    context "without a block, but with integral argument" do
+      it "returns an Enumerator of all permutations of given length" do
+        vector.permutation(2).class.should be(Enumerator)
+        vector.permutation(2).to_a.should eql(vector.to_a.permutation(2).to_a)
+        vector.permutation(3).class.should be(Enumerator)
+        vector.permutation(3).to_a.should eql(vector.to_a.permutation(3).to_a)
+      end
+    end
+
+    context "with a block" do
+      it "returns self" do
+        vector.permutation {}.should be(vector)
+      end
+
+      context "and no argument" do
+        it "yields all permutations" do
+          yielded = []
+          vector.permutation { |obj| yielded << obj }
+          yielded.sort.should eql([[1,2,3,4], [1,2,4,3], [1,3,2,4], [1,3,4,2],
+            [1,4,2,3], [1,4,3,2], [2,1,3,4], [2,1,4,3], [2,3,1,4], [2,3,4,1],
+            [2,4,1,3], [2,4,3,1], [3,1,2,4], [3,1,4,2], [3,2,1,4], [3,2,4,1],
+            [3,4,1,2], [3,4,2,1], [4,1,2,3], [4,1,3,2], [4,2,1,3], [4,2,3,1],
+            [4,3,1,2], [4,3,2,1]])
+        end
+      end
+
+      context "and an integral argument" do
+        it "yields all permutations of the given length" do
+          yielded = []
+          vector.permutation(2) { |obj| yielded << obj }
+          yielded.sort.should eql([[1,2], [1,3], [1,4], [2,1], [2,3], [2,4], [3,1],
+            [3,2], [3,4], [4,1], [4,2], [4,3]])
+        end
+      end
+    end
+
+    context "on an empty vector" do
+      it "yields the empty permutation" do
+        yielded = []
+        V.empty.permutation { |obj| yielded << obj }
+        yielded.should eql([[]])
+      end
+    end
+
+    context "with an argument of zero" do
+      it "yields the empty permutation" do
+        yielded = []
+        vector.permutation(0) { |obj| yielded << obj }
+        yielded.should eql([[]])
+      end
+    end
+
+    context "with a length greater than the size of the vector" do
+      it "yields no permutations" do
+        vector.permutation(5) { |obj| fail }
+      end
+    end
+
+    it "handles duplicate elements correctly" do
+      V[1,2,3,1].permutation(2).sort.should eql([[1,1], [1,1], [1,2], [1,2],
+        [1,3], [1,3], [2,1],[2,1],[2,3], [3,1],[3,1],[3,2]])
+    end
+
+    it "leaves the original unmodified" do
+      vector.permutation(2) {}
+      vector.should eql(V[1,2,3,4])
+    end
+
+    it "behaves like Array#permutation" do
+      10.times do
+        array  = rand(8).times.map { rand(10000) }
+        vector = V.new(array)
+        perm_size = array.size == 0 ? 0 : rand(array.size)
+        array.permutation(perm_size).to_a.should == vector.permutation(perm_size).to_a
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/pop_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/pop_spec.rb
new file mode 100755
index 0000000..0a6785c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/pop_spec.rb
@@ -0,0 +1,27 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#pop" do
+    [
+      [[], []],
+      [["A"], []],
+      [%w[A B C], %w[A B]],
+      [1..32, 1..31],
+      [1..33, 1..32]
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:vector) { V[*values] }
+
+        it "preserves the original" do
+          vector.pop
+          vector.should eql(V[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          vector.pop.should eql(V[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/product_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/product_spec.rb
new file mode 100755
index 0000000..cc082f7
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/product_spec.rb
@@ -0,0 +1,71 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#product" do
+    context "when passed no arguments" do
+      it "multiplies all items in vector" do
+        [
+          [[], 1],
+          [[2], 2],
+          [[1, 3, 5, 7, 11], 1155],
+        ].each do |values, expected|
+          V[*values].product.should == expected
+        end
+      end
+    end
+
+    context "when passed one or more vectors" do
+      let(:vector) { V[1,2,3] }
+
+      context "when passed a block" do
+        it "yields an array for each combination of items from the vectors" do
+          yielded = []
+          vector.product(vector) { |obj| yielded << obj }
+          yielded.should eql([[1,1], [1,2], [1,3], [2,1], [2,2], [2,3], [3,1], [3,2], [3,3]])
+
+          yielded = []
+          vector.product(V[3,4,5], V[6,8]) { |obj| yielded << obj }
+          yielded.should eql(
+            [[1, 3, 6], [1, 3, 8], [1, 4, 6], [1, 4, 8], [1, 5, 6], [1, 5, 8],
+             [2, 3, 6], [2, 3, 8], [2, 4, 6], [2, 4, 8], [2, 5, 6], [2, 5, 8],
+             [3, 3, 6], [3, 3, 8], [3, 4, 6], [3, 4, 8], [3, 5, 6], [3, 5, 8]])
+        end
+
+        it "returns self" do
+          vector.product(V.empty) {}.should be(vector)
+          vector.product(V[1,2], V[3]) {}.should be(vector)
+          V.empty.product(vector) {}.should be(V.empty)
+        end
+      end
+
+      context "when not passed a block" do
+        it "returns the cartesian product in an array" do
+          V[1,2].product(V[3,4,5], V[6,8]).should eql(
+            [[1, 3, 6], [1, 3, 8], [1, 4, 6], [1, 4, 8], [1, 5, 6], [1, 5, 8],
+            [2, 3, 6], [2, 3, 8], [2, 4, 6], [2, 4, 8], [2, 5, 6], [2, 5, 8]])
+        end
+      end
+
+      context "when one of the arguments is empty" do
+        it "returns an empty array" do
+          vector.product(V.empty, V[4,5,6]).should eql([])
+        end
+      end
+
+      context "when the receiver is empty" do
+        it "returns an empty array" do
+          V.empty.product(vector, V[4,5,6]).should eql([])
+        end
+      end
+    end
+
+    context "when passed one or more Arrays" do
+      it "also calculates the cartesian product correctly" do
+        V[1,2].product([3,4,5], [6,8]).should eql(
+          [[1, 3, 6], [1, 3, 8], [1, 4, 6], [1, 4, 8], [1, 5, 6], [1, 5, 8],
+          [2, 3, 6], [2, 3, 8], [2, 4, 6], [2, 4, 8], [2, 5, 6], [2, 5, 8]])
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/put_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/put_spec.rb
new file mode 100755
index 0000000..c54bcff
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/put_spec.rb
@@ -0,0 +1,175 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  let(:vector) { V[*values] }
+
+  describe "#put" do
+    context "when empty" do
+      let(:vector) { V.empty }
+
+      it "raises an error for index -1" do
+        expect { vector.put(-1, :a) }.to raise_error
+      end
+
+      it "allows indexes 0 and 1 to be put" do
+        vector.put(0, :a).should eql(V[:a])
+        vector.put(1, :a).should eql(V[nil, :a])
+      end
+    end
+
+    context "when not empty" do
+      let(:vector) { V["A", "B", "C"] }
+
+      context "with a block" do
+        context "and a positive index" do
+          context "within the absolute bounds of the vector" do
+            it "passes the current value to the block" do
+              vector.put(1) { |value| value.should == "B" }
+            end
+
+            it "replaces the value with the result of the block" do
+              result = vector.put(1) { |value| "FLIBBLE" }
+              result.should eql(V["A", "FLIBBLE", "C"])
+            end
+
+            it "supports to_proc methods" do
+              result = vector.put(1, &:downcase)
+              result.should eql(V["A", "b", "C"])
+            end
+          end
+
+          context "just past the end of the vector" do
+            it "passes nil to the block and adds a new value" do
+              result = vector.put(3) { |value| value.should be_nil; "D" }
+              result.should eql(V["A", "B", "C", "D"])
+            end
+          end
+
+          context "further outside the bounds of the vector" do
+            it "passes nil to the block, fills up missing nils, and adds a new value" do
+              result = vector.put(5) { |value| value.should be_nil; "D" }
+              result.should eql(V["A", "B", "C", nil, nil, "D"])
+            end
+          end
+        end
+
+        context "and a negative index" do
+          context "within the absolute bounds of the vector" do
+            it "passes the current value to the block" do
+              vector.put(-2) { |value| value.should == "B" }
+            end
+
+            it "replaces the value with the result of the block" do
+              result = vector.put(-2) { |value| "FLIBBLE" }
+              result.should eql(V["A", "FLIBBLE", "C"])
+            end
+
+            it "supports to_proc methods" do
+              result = vector.put(-2, &:downcase)
+              result.should eql(V["A", "b", "C"])
+            end
+          end
+
+          context "outside the absolute bounds of the vector" do
+            it "raises an error" do
+              expect { vector.put(-vector.size.next) {} }.to raise_error
+            end
+          end
+        end
+      end
+
+      context "with a value" do
+        context "and a positive index" do
+          context "within the absolute bounds of the vector" do
+            let(:put) { vector.put(1, "FLIBBLE") }
+
+            it "preserves the original" do
+              vector.should eql(V["A", "B", "C"])
+            end
+
+            it "puts the new value at the specified index" do
+              put.should eql(V["A", "FLIBBLE", "C"])
+            end
+          end
+
+          context "just past the end of the vector" do
+            it "adds a new value" do
+              result = vector.put(3, "FLIBBLE")
+              result.should eql(V["A", "B", "C", "FLIBBLE"])
+            end
+          end
+
+          context "outside the absolute bounds of the vector" do
+            it "fills up with nils" do
+              result = vector.put(5, "FLIBBLE")
+              result.should eql(V["A", "B", "C", nil, nil, "FLIBBLE"])
+            end
+          end
+        end
+
+        context "with a negative index" do
+          let(:put) { vector.put(-2, "FLIBBLE") }
+
+          it "preserves the original" do
+            put
+            vector.should eql(V["A", "B", "C"])
+          end
+
+          it "puts the new value at the specified index" do
+            put.should eql(V["A", "FLIBBLE", "C"])
+          end
+        end
+
+        context "outside the absolute bounds of the vector" do
+          it "raises an error" do
+            expect { vector.put(-vector.size.next, "FLIBBLE") }.to raise_error
+          end
+        end
+      end
+    end
+
+    context "from a subclass" do
+      it "returns an instance of the subclass" do
+        subclass = Class.new(Hamster::Vector)
+        instance = subclass[1,2,3]
+        instance.put(1, 2.5).class.should be(subclass)
+      end
+    end
+
+    [10, 31, 32, 33, 1000, 1023, 1024, 1025, 2000].each do |size|
+      context "on a #{size}-item vector" do
+        it "works correctly" do
+          array = (1..size).to_a
+          vector = V.new(array)
+
+          [0, 1, 10, 31, 32, 33, 100, 500, 1000, 1023, 1024, 1025, 1998, 1999].select { |n| n < size }.each do |i|
+            value = rand(10000)
+            array[i] = value
+            vector = vector.put(i, value)
+            vector[i].should be(value)
+          end
+
+          0.upto(size-1) do |i|
+            vector.get(i).should == array[i]
+          end
+        end
+      end
+    end
+
+    context "with an identical value to an existing item" do
+      [1, 2, 5, 31,32, 33, 100, 200].each do |size|
+        context "on a #{size}-item vector" do
+          let(:array) { (0...size).map { |x| x * x} }
+          let(:vector) { V.new(array) }
+
+          it "returns self" do
+            (0...size).each do |index|
+              vector.put(index, index * index).should equal(vector)
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/reduce_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/reduce_spec.rb
new file mode 100755
index 0000000..8e79a29
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/reduce_spec.rb
@@ -0,0 +1,56 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  [:reduce, :inject].each do |method|
+    describe "##{method}" do
+      [
+        [[], 10, 10],
+        [[1], 10, 9],
+        [[1, 2, 3], 10, 4],
+      ].each do |values, initial, expected|
+        describe "on #{values.inspect}" do
+          let(:vector) { V[*values] }
+
+          describe "with an initial value of #{initial}" do
+            describe "and a block" do
+              it "returns #{expected.inspect}" do
+                vector.send(method, initial) { |memo, item| memo - item }.should == expected
+              end
+            end
+          end
+        end
+      end
+
+      [
+        [[], nil],
+        [[1], 1],
+        [[1, 2, 3], -4],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          let(:vector) { V[*values] }
+
+          describe "with no initial value" do
+            describe "and a block" do
+              it "returns #{expected.inspect}" do
+                vector.send(method) { |memo, item| memo - item }.should == expected
+              end
+            end
+          end
+        end
+      end
+
+      describe "with no block and a symbol argument" do
+        it "uses the symbol as the name of a method to reduce with" do
+          V[1, 2, 3].send(method, :+).should == 6
+        end
+      end
+
+      describe "with no block and a string argument" do
+        it "uses the string as the name of a method to reduce with" do
+          V[1, 2, 3].send(method, '+').should == 6
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/reject_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/reject_spec.rb
new file mode 100755
index 0000000..f873661
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/reject_spec.rb
@@ -0,0 +1,44 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  [:reject, :delete_if].each do |method|
+    describe "##{method}" do
+      [
+        [[], []],
+        [["A"], ["A"]],
+        [%w[A B C], %w[A B C]],
+        [%w[A b C], %w[A C]],
+        [%w[a b c], []],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          let(:vector) { V[*values] }
+
+          context "with a block" do
+            it "returns #{expected.inspect}" do
+              vector.send(method) { |item| item == item.downcase }.should eql(V[*expected])
+            end
+          end
+
+          context "without a block" do
+            it "returns an Enumerator" do
+              vector.send(method).class.should be(Enumerator)
+              vector.send(method).each { |item| item == item.downcase }.should eql(V[*expected])
+            end
+          end
+        end
+      end
+
+      it "works with a variety of inputs" do
+        [1, 2, 10, 31, 32, 33, 1023, 1024, 1025].each do |size|
+          [0, 5, 32, 50, 500, 800, 1024].each do |threshold|
+            vector = V.new(1..size)
+            result = vector.send(method) { |item| item > threshold }
+            result.size.should == [size, threshold].min
+            result.should eql(V.new(1..[size, threshold].min))
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/repeated_combination_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/repeated_combination_spec.rb
new file mode 100755
index 0000000..c5b9971
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/repeated_combination_spec.rb
@@ -0,0 +1,78 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#repeated_combination" do
+    let(:vector) { V[1,2,3,4] }
+
+    context "with no block" do
+      it "returns an Enumerator" do
+        vector.repeated_combination(2).class.should be(Enumerator)
+      end
+    end
+
+    context "with a block" do
+      it "returns self" do
+        vector.repeated_combination(2) {}.should be(vector)
+      end
+    end
+
+    context "with a negative argument" do
+      it "yields nothing and returns self" do
+        result = []
+        vector.repeated_combination(-1) { |obj| result << obj }.should be(vector)
+        result.should eql([])
+      end
+    end
+
+    context "with a zero argument" do
+      it "yields an empty array" do
+        result = []
+        vector.repeated_combination(0) { |obj| result << obj }
+        result.should eql([[]])
+      end
+    end
+
+    context "with a argument of 1" do
+      it "yields each item in the vector, as single-item vectors" do
+        result = []
+        vector.repeated_combination(1) { |obj| result << obj }
+        result.should eql([[1],[2],[3],[4]])
+      end
+    end
+
+    context "on an empty vector, with an argument greater than zero" do
+      it "yields nothing" do
+        result = []
+        V.empty.repeated_combination(1) { |obj| result << obj }
+        result.should eql([])
+      end
+    end
+
+    context "with a positive argument, greater than 1" do
+      it "yields all combinations of the given size (where a single element can appear more than once in a row)" do
+        vector.repeated_combination(2).to_a.should == [[1,1], [1,2], [1,3], [1,4], [2,2], [2,3], [2,4], [3,3], [3,4], [4,4]]
+        vector.repeated_combination(3).to_a.should == [[1,1,1], [1,1,2], [1,1,3], [1,1,4],
+          [1,2,2], [1,2,3], [1,2,4], [1,3,3], [1,3,4], [1,4,4], [2,2,2], [2,2,3],
+          [2,2,4], [2,3,3], [2,3,4], [2,4,4], [3,3,3], [3,3,4], [3,4,4], [4,4,4]]
+        V[1,2,3].repeated_combination(3).to_a.should == [[1,1,1], [1,1,2],
+          [1,1,3], [1,2,2], [1,2,3], [1,3,3], [2,2,2], [2,2,3], [2,3,3], [3,3,3]]
+      end
+    end
+
+    it "leaves the original unmodified" do
+      vector.repeated_combination(2) {}
+      vector.should eql(V[1,2,3,4])
+    end
+
+    it "behaves like Array#repeated_combination" do
+      0.upto(5) do |comb_size|
+        array = 10.times.map { rand(1000) }
+        V.new(array).repeated_combination(comb_size).to_a.should == array.repeated_combination(comb_size).to_a
+      end
+
+      array = 18.times.map { rand(1000) }
+      V.new(array).repeated_combination(2).to_a.should == array.repeated_combination(2).to_a
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/repeated_permutation_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/repeated_permutation_spec.rb
new file mode 100755
index 0000000..a08637c
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/repeated_permutation_spec.rb
@@ -0,0 +1,94 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#repeated_permutation" do
+    let(:vector) { V[1,2,3,4] }
+
+    context "without a block" do
+      context "and without argument" do
+        it "returns an Enumerator of all repeated permutations" do
+          vector.repeated_permutation.class.should be(Enumerator)
+          vector.repeated_permutation.to_a.sort.should eql(vector.to_a.repeated_permutation(4).to_a.sort)
+        end
+      end
+
+      context "with an integral argument" do
+        it "returns an Enumerator of all repeated permutations of the given length" do
+          vector.repeated_permutation(2).class.should be(Enumerator)
+          vector.repeated_permutation(2).to_a.sort.should eql(vector.to_a.repeated_permutation(2).to_a.sort)
+          vector.repeated_permutation(3).class.should be(Enumerator)
+          vector.repeated_permutation(3).to_a.sort.should eql(vector.to_a.repeated_permutation(3).to_a.sort)
+        end
+      end
+    end
+
+    context "with a block" do
+      it "returns self" do
+        vector.repeated_permutation {}.should be(vector)
+      end
+
+      context "on an empty vector" do
+        it "yields the empty permutation" do
+          yielded = []
+          V.empty.repeated_permutation { |obj| yielded << obj }
+          yielded.should eql([[]])
+        end
+      end
+
+      context "with an argument of zero" do
+        it "yields the empty permutation" do
+          yielded = []
+          vector.repeated_permutation(0) { |obj| yielded << obj }
+          yielded.should eql([[]])
+        end
+      end
+
+      context "with no argument" do
+        it "yields all repeated permutations" do
+          yielded = []
+          V[1,2,3].repeated_permutation { |obj| yielded << obj }
+          yielded.sort.should eql([[1,1,1], [1,1,2], [1,1,3], [1,2,1], [1,2,2],
+            [1,2,3], [1,3,1], [1,3,2], [1,3,3], [2,1,1], [2,1,2], [2,1,3], [2,2,1],
+            [2,2,2], [2,2,3], [2,3,1], [2,3,2], [2,3,3], [3,1,1], [3,1,2], [3,1,3],
+            [3,2,1], [3,2,2], [3,2,3], [3,3,1], [3,3,2], [3,3,3]])
+        end
+      end
+
+      context "with a positive integral argument" do
+        it "yields all repeated permutations of the given length" do
+          yielded = []
+          vector.repeated_permutation(2) { |obj| yielded << obj }
+          yielded.sort.should eql([[1,1], [1,2], [1,3], [1,4], [2,1], [2,2], [2,3], [2,4],
+            [3,1], [3,2], [3,3], [3,4], [4,1], [4,2], [4,3], [4,4]])
+        end
+      end
+    end
+
+    it "handles duplicate elements correctly" do
+    V[10,11,10].repeated_permutation(2).sort.should eql([[10, 10], [10, 10],
+      [10, 10], [10, 10], [10, 11], [10, 11], [11, 10], [11, 10], [11, 11]])
+    end
+
+    it "allows permutations larger than the number of elements" do
+      V[1,2].repeated_permutation(3).sort.should eql(
+        [[1, 1, 1], [1, 1, 2], [1, 2, 1],
+         [1, 2, 2], [2, 1, 1], [2, 1, 2],
+         [2, 2, 1], [2, 2, 2]])
+    end
+
+    it "leaves the original unmodified" do
+      vector.repeated_permutation(2) {}
+      vector.should eql(V[1,2,3,4])
+    end
+
+    it "behaves like Array#repeated_permutation" do
+      10.times do
+        array  = rand(8).times.map { rand(10000) }
+        vector = V.new(array)
+        perm_size = array.size == 0 ? 0 : rand(array.size)
+        array.repeated_permutation(perm_size).to_a.should == vector.repeated_permutation(perm_size).to_a
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/reverse_each_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/reverse_each_spec.rb
new file mode 100755
index 0000000..fb1c9aa
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/reverse_each_spec.rb
@@ -0,0 +1,32 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#reverse_each" do
+    [2, 31, 32, 33, 1000, 1024, 1025, 2000].each do |size|
+      context "on a #{size}-item vector" do
+        let(:vector) { V[1..size] }
+
+        context "with a block (internal iteration)" do
+          it "returns self" do
+            vector.reverse_each {}.should be(vector)
+          end
+
+          it "yields all items in the opposite order as #each" do
+            result = []
+            vector.reverse_each { |item| result << item }
+            result.should eql(vector.to_a.reverse)
+          end
+        end
+
+        context "with no block" do
+          it "returns an Enumerator" do
+            result = vector.reverse_each
+            result.class.should be(Enumerator)
+            result.to_a.should eql(vector.to_a.reverse)
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/reverse_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/reverse_spec.rb
new file mode 100755
index 0000000..720248a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/reverse_spec.rb
@@ -0,0 +1,22 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#reverse" do
+    [
+      [[], []],
+      [[1], [1]],
+      [[1,2], [2,1]],
+      [(1..32).to_a, (1..32).to_a.reverse],
+      [(1..33).to_a, (1..33).to_a.reverse],
+      [(1..100).to_a, (1..100).to_a.reverse],
+      [(1..1024).to_a, (1..1024).to_a.reverse]
+    ].each do |initial, expected|
+      describe "on #{initial}" do
+        it "returns #{expected}" do
+          V.new(initial).reverse.should eql(V.new(expected))
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/rindex_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/rindex_spec.rb
new file mode 100755
index 0000000..b5c7aeb
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/rindex_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#rindex" do
+    let(:vector) { V[1,2,3,3,2,1] }
+
+    context "when passed an object present in the vector" do
+      it "returns the last index where the object is present" do
+        vector.rindex(1).should be(5)
+        vector.rindex(2).should be(4)
+        vector.rindex(3).should be(3)
+      end
+    end
+
+    context "when passed an object not present in the vector" do
+      it "returns nil" do
+        vector.rindex(0).should be_nil
+        vector.rindex(nil).should be_nil
+        vector.rindex('string').should be_nil
+      end
+    end
+
+    context "with a block" do
+      it "returns the last index of an object which the predicate is true for" do
+        vector.rindex { |n| n > 2 }.should be(3)
+      end
+    end
+
+    context "without an argument OR block" do
+      it "returns an Enumerator" do
+        vector.rindex.class.should be(Enumerator)
+        vector.rindex.each { |n| n > 2 }.should be(3)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/rotate_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/rotate_spec.rb
new file mode 100755
index 0000000..5614862
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/rotate_spec.rb
@@ -0,0 +1,74 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#rotate" do
+    let(:vector) { V[1,2,3,4,5] }
+
+    context "when passed no argument" do
+      it "returns a new vector with the first element moved to the end" do
+        vector.rotate.should eql(V[2,3,4,5,1])
+      end
+    end
+
+    context "with an integral argument n" do
+      it "returns a new vector with the first (n % size) elements moved to the end" do
+        vector.rotate(2).should eql(V[3,4,5,1,2])
+        vector.rotate(3).should eql(V[4,5,1,2,3])
+        vector.rotate(4).should eql(V[5,1,2,3,4])
+        vector.rotate(5).should eql(V[1,2,3,4,5])
+        vector.rotate(-1).should eql(V[5,1,2,3,4])
+      end
+    end
+
+    context "with a floating-point argument n" do
+      it "coerces the argument to integer using to_int" do
+        vector.rotate(2.1).should eql(V[3,4,5,1,2])
+      end
+    end
+
+    context "with a non-numeric argument" do
+      it "raises a TypeError" do
+        -> { vector.rotate('hello') }.should raise_error(TypeError)
+      end
+    end
+
+    context "with an argument of zero" do
+      it "returns self" do
+        vector.rotate(0).should be(vector)
+      end
+    end
+
+    context "with an argument equal to the vector's size" do
+      it "returns self" do
+        vector.rotate(5).should be(vector)
+      end
+    end
+
+    [31, 32, 33, 1000, 1023, 1024, 1025].each do |size|
+      context "on a #{size}-item vector" do
+        it "behaves like Array#rotate" do
+          array = (1..size).to_a
+          vector = V.new(array)
+          10.times do
+            offset = rand(size)
+            vector.rotate(offset).should == array.rotate(offset)
+          end
+        end
+      end
+    end
+
+    context "from a subclass" do
+      it "returns an instance of the subclass" do
+        subclass = Class.new(Hamster::Vector)
+        instance = subclass.new([1,2,3])
+        instance.rotate(2).class.should be(subclass)
+      end
+    end
+
+    it "leaves the original unmodified" do
+      vector.rotate(3)
+      vector.should eql(V[1,2,3,4,5])
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/sample_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/sample_spec.rb
new file mode 100755
index 0000000..90a97b2
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/sample_spec.rb
@@ -0,0 +1,14 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#sample" do
+    let(:vector) { V.new(1..10) }
+
+    it "returns a randomly chosen item" do
+      chosen = 100.times.map { vector.sample }
+      chosen.each { |item| vector.include?(item).should == true }
+      vector.each { |item| chosen.include?(item).should == true }
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/select_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/select_spec.rb
new file mode 100755
index 0000000..89b9ed1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/select_spec.rb
@@ -0,0 +1,64 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  [:select, :find_all].each do |method|
+    describe "##{method}" do
+      let(:vector) { V["A", "B", "C"] }
+
+      describe "with a block" do
+        it "preserves the original" do
+          vector.send(method) { |item| item == "A" }
+          vector.should eql(V["A", "B", "C"])
+        end
+
+        it "returns a vector with the matching values" do
+          vector.send(method) { |item| item == "A" }.should eql(V["A"])
+        end
+      end
+
+      describe "with no block" do
+        it "returns an Enumerator" do
+          vector.send(method).class.should be(Enumerator)
+          vector.send(method).each { |item| item == "A" }.should eql(V["A"])
+        end
+      end
+
+      describe "when nothing matches" do
+        it "preserves the original" do
+          vector.send(method) { |item| false }
+          vector.should eql(V["A", "B", "C"])
+        end
+
+        it "returns an empty vector" do
+          vector.send(method) { |item| false }.should equal(V.empty)
+        end
+      end
+
+      context "on an empty vector" do
+        it "returns self" do
+          V.empty.send(method) { |item| true }.should be(V.empty)
+        end
+      end
+
+      context "from a subclass" do
+        it "returns an instance of the subclass" do
+          subclass = Class.new(Hamster::Vector)
+          instance = subclass[1,2,3]
+          instance.send(method) { |x| x > 1 }.class.should be(subclass)
+        end
+      end
+
+      it "works with a variety of inputs" do
+        [1, 2, 10, 31, 32, 33, 1023, 1024, 1025].each do |size|
+          [0, 5, 32, 50, 500, 800, 1024].each do |threshold|
+            vector = V.new(1..size)
+            result = vector.send(method) { |item| item <= threshold }
+            result.size.should == [size, threshold].min
+            result.should eql(V.new(1..[size, threshold].min))
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/set_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/set_spec.rb
new file mode 100755
index 0000000..5c86001
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/set_spec.rb
@@ -0,0 +1,26 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+
+  # Note: Vector#set will be deprecated; use Vector#put instead. See
+  # `spec/lib/hamster/vector/put_spec.rb` for the full specs of Vector#put.
+
+  describe "#set" do
+    let(:vector) { V[5, 6, 7] }
+
+    context "without block" do
+      it "replaces the element" do
+        result = vector.set(1, 100)
+        result.should eql(V[5, 100, 7])
+      end
+    end
+
+    context "with block" do
+      it "passes the existing element to the block and replaces the result" do
+        result = vector.set(1) { |e| e + 100 }
+        result.should eql(V[5, 106, 7])
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/shift_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/shift_spec.rb
new file mode 100755
index 0000000..b65d605
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/shift_spec.rb
@@ -0,0 +1,28 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#shift" do
+    [
+      [[], []],
+      [["A"], []],
+      [%w[A B C], %w[B C]],
+      [1..31, 2..31],
+      [1..32, 2..32],
+      [1..33, 2..33]
+    ].each do |values, expected|
+      context "on #{values.inspect}" do
+        let(:vector) { V[*values] }
+
+        it "preserves the original" do
+          vector.shift
+          vector.should eql(V[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          vector.shift.should eql(V[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/shuffle_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/shuffle_spec.rb
new file mode 100755
index 0000000..48d1d1e
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/shuffle_spec.rb
@@ -0,0 +1,44 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#shuffle" do
+    let(:vector) { V[1,2,3,4] }
+
+    it "returns the same values, in a usually different order" do
+      different = false
+      10.times do
+        shuffled = vector.shuffle
+        shuffled.sort.should eql(vector)
+        different ||= (shuffled != vector)
+      end
+      different.should be(true)
+    end
+
+    it "leaves the original unchanged" do
+      vector.shuffle
+      vector.should eql(V[1,2,3,4])
+    end
+
+    context "from a subclass" do
+      it "returns an instance of the subclass" do
+        subclass = Class.new(Hamster::Vector)
+        instance = subclass.new([1,2,3])
+        instance.shuffle.class.should be(subclass)
+      end
+    end
+
+    [32, 33, 1023, 1024, 1025].each do |size|
+      context "on a #{size}-item vector" do
+        it "works correctly" do
+          vector = V.new(1..size)
+          shuffled = vector.shuffle
+          shuffled = vector.shuffle while shuffled.eql?(vector) # in case we get the same
+          vector.should eql(V.new(1..size))
+          shuffled.size.should == vector.size
+          shuffled.sort.should eql(vector)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/slice_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/slice_spec.rb
new file mode 100755
index 0000000..e97635f
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/slice_spec.rb
@@ -0,0 +1,241 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  let(:vector) { V[1,2,3,4] }
+  let(:big) { V.new(1..10000) }
+
+  [:slice, :[]].each do |method|
+    describe "##{method}" do
+      context "when passed a positive integral index" do
+        it "returns the element at that index" do
+          vector.send(method, 0).should be(1)
+          vector.send(method, 1).should be(2)
+          vector.send(method, 2).should be(3)
+          vector.send(method, 3).should be(4)
+          vector.send(method, 4).should be(nil)
+          vector.send(method, 10).should be(nil)
+
+          big.send(method, 0).should be(1)
+          big.send(method, 9999).should be(10000)
+        end
+
+        it "leaves the original unchanged" do
+          vector.should eql(V[1,2,3,4])
+        end
+      end
+
+      context "when passed a negative integral index" do
+        it "returns the element which is number (index.abs) counting from the end of the vector" do
+          vector.send(method, -1).should be(4)
+          vector.send(method, -2).should be(3)
+          vector.send(method, -3).should be(2)
+          vector.send(method, -4).should be(1)
+          vector.send(method, -5).should be(nil)
+          vector.send(method, -10).should be(nil)
+
+          big.send(method, -1).should be(10000)
+          big.send(method, -10000).should be(1)
+        end
+      end
+
+      context "when passed a positive integral index and count" do
+        it "returns 'count' elements starting from 'index'" do
+          vector.send(method, 0, 0).should  eql(V.empty)
+          vector.send(method, 0, 1).should  eql(V[1])
+          vector.send(method, 0, 2).should  eql(V[1,2])
+          vector.send(method, 0, 4).should  eql(V[1,2,3,4])
+          vector.send(method, 0, 6).should  eql(V[1,2,3,4])
+          vector.send(method, 0, -1).should be_nil
+          vector.send(method, 0, -2).should be_nil
+          vector.send(method, 0, -4).should be_nil
+          vector.send(method, 2, 0).should  eql(V.empty)
+          vector.send(method, 2, 1).should  eql(V[3])
+          vector.send(method, 2, 2).should  eql(V[3,4])
+          vector.send(method, 2, 4).should  eql(V[3,4])
+          vector.send(method, 2, -1).should be_nil
+          vector.send(method, 4, 0).should  eql(V.empty)
+          vector.send(method, 4, 2).should  eql(V.empty)
+          vector.send(method, 4, -1).should be_nil
+          vector.send(method, 5, 0).should  be_nil
+          vector.send(method, 5, 2).should  be_nil
+          vector.send(method, 5, -1).should be_nil
+          vector.send(method, 6, 0).should  be_nil
+          vector.send(method, 6, 2).should  be_nil
+          vector.send(method, 6, -1).should be_nil
+
+          big.send(method, 0, 3).should    eql(V[1,2,3])
+          big.send(method, 1023, 4).should eql(V[1024,1025,1026,1027])
+          big.send(method, 1024, 4).should eql(V[1025,1026,1027,1028])
+        end
+
+        it "leaves the original unchanged" do
+          vector.should eql(V[1,2,3,4])
+        end
+      end
+
+      context "when passed a negative integral index and count" do
+        it "returns 'count' elements, starting from index which is number 'index.abs' counting from the end of the array" do
+          vector.send(method, -1, 0).should  eql(V.empty)
+          vector.send(method, -1, 1).should  eql(V[4])
+          vector.send(method, -1, 2).should  eql(V[4])
+          vector.send(method, -1, -1).should be_nil
+          vector.send(method, -2, 0).should  eql(V.empty)
+          vector.send(method, -2, 1).should  eql(V[3])
+          vector.send(method, -2, 2).should  eql(V[3,4])
+          vector.send(method, -2, 4).should  eql(V[3,4])
+          vector.send(method, -2, -1).should be_nil
+          vector.send(method, -4, 0).should  eql(V.empty)
+          vector.send(method, -4, 1).should  eql(V[1])
+          vector.send(method, -4, 2).should  eql(V[1,2])
+          vector.send(method, -4, 4).should  eql(V[1,2,3,4])
+          vector.send(method, -4, 6).should  eql(V[1,2,3,4])
+          vector.send(method, -4, -1).should be_nil
+          vector.send(method, -5, 0).should  be_nil
+          vector.send(method, -5, 1).should  be_nil
+          vector.send(method, -5, 10).should be_nil
+          vector.send(method, -5, -1).should be_nil
+
+          big.send(method, -1, 1).should eql(V[10000])
+          big.send(method, -1, 2).should eql(V[10000])
+          big.send(method, -6, 2).should eql(V[9995,9996])
+        end
+      end
+
+      context "when passed a Range" do
+        it "returns the elements whose indexes are within the given Range" do
+          vector.send(method, 0..-1).should  eql(V[1,2,3,4])
+          vector.send(method, 0..-10).should eql(V.empty)
+          vector.send(method, 0..0).should   eql(V[1])
+          vector.send(method, 0..1).should   eql(V[1,2])
+          vector.send(method, 0..2).should   eql(V[1,2,3])
+          vector.send(method, 0..3).should   eql(V[1,2,3,4])
+          vector.send(method, 0..4).should   eql(V[1,2,3,4])
+          vector.send(method, 0..10).should  eql(V[1,2,3,4])
+          vector.send(method, 2..-10).should eql(V.empty)
+          vector.send(method, 2..0).should   eql(V.empty)
+          vector.send(method, 2..2).should   eql(V[3])
+          vector.send(method, 2..3).should   eql(V[3,4])
+          vector.send(method, 2..4).should   eql(V[3,4])
+          vector.send(method, 3..0).should   eql(V.empty)
+          vector.send(method, 3..3).should   eql(V[4])
+          vector.send(method, 3..4).should   eql(V[4])
+          vector.send(method, 4..0).should   eql(V.empty)
+          vector.send(method, 4..4).should   eql(V.empty)
+          vector.send(method, 4..5).should   eql(V.empty)
+          vector.send(method, 5..0).should   be_nil
+          vector.send(method, 5..5).should   be_nil
+          vector.send(method, 5..6).should   be_nil
+
+          big.send(method, 159..162).should     eql(V[160,161,162,163])
+          big.send(method, 160..162).should     eql(V[161,162,163])
+          big.send(method, 161..162).should     eql(V[162,163])
+          big.send(method, 9999..10100).should  eql(V[10000])
+          big.send(method, 10000..10100).should eql(V.empty)
+          big.send(method, 10001..10100).should be_nil
+
+          vector.send(method, 0...-1).should  eql(V[1,2,3])
+          vector.send(method, 0...-10).should eql(V.empty)
+          vector.send(method, 0...0).should   eql(V.empty)
+          vector.send(method, 0...1).should   eql(V[1])
+          vector.send(method, 0...2).should   eql(V[1,2])
+          vector.send(method, 0...3).should   eql(V[1,2,3])
+          vector.send(method, 0...4).should   eql(V[1,2,3,4])
+          vector.send(method, 0...10).should  eql(V[1,2,3,4])
+          vector.send(method, 2...-10).should eql(V.empty)
+          vector.send(method, 2...0).should   eql(V.empty)
+          vector.send(method, 2...2).should   eql(V.empty)
+          vector.send(method, 2...3).should   eql(V[3])
+          vector.send(method, 2...4).should   eql(V[3,4])
+          vector.send(method, 3...0).should   eql(V.empty)
+          vector.send(method, 3...3).should   eql(V.empty)
+          vector.send(method, 3...4).should   eql(V[4])
+          vector.send(method, 4...0).should   eql(V.empty)
+          vector.send(method, 4...4).should   eql(V.empty)
+          vector.send(method, 4...5).should   eql(V.empty)
+          vector.send(method, 5...0).should   be_nil
+          vector.send(method, 5...5).should   be_nil
+          vector.send(method, 5...6).should   be_nil
+
+          big.send(method, 159...162).should     eql(V[160,161,162])
+          big.send(method, 160...162).should     eql(V[161,162])
+          big.send(method, 161...162).should     eql(V[162])
+          big.send(method, 9999...10100).should  eql(V[10000])
+          big.send(method, 10000...10100).should eql(V.empty)
+          big.send(method, 10001...10100).should be_nil
+
+          vector.send(method, -1..-1).should  eql(V[4])
+          vector.send(method, -1...-1).should eql(V.empty)
+          vector.send(method, -1..3).should   eql(V[4])
+          vector.send(method, -1...3).should  eql(V.empty)
+          vector.send(method, -1..4).should   eql(V[4])
+          vector.send(method, -1...4).should  eql(V[4])
+          vector.send(method, -1..10).should  eql(V[4])
+          vector.send(method, -1...10).should eql(V[4])
+          vector.send(method, -1..0).should   eql(V.empty)
+          vector.send(method, -1..-4).should  eql(V.empty)
+          vector.send(method, -1...-4).should eql(V.empty)
+          vector.send(method, -1..-6).should  eql(V.empty)
+          vector.send(method, -1...-6).should eql(V.empty)
+          vector.send(method, -2..-2).should  eql(V[3])
+          vector.send(method, -2...-2).should eql(V.empty)
+          vector.send(method, -2..-1).should  eql(V[3,4])
+          vector.send(method, -2...-1).should eql(V[3])
+          vector.send(method, -2..10).should  eql(V[3,4])
+          vector.send(method, -2...10).should eql(V[3,4])
+
+          big.send(method, -1..-1).should    eql(V[10000])
+          big.send(method, -1..9999).should  eql(V[10000])
+          big.send(method, -1...9999).should eql(V.empty)
+          big.send(method, -2...9999).should eql(V[9999])
+          big.send(method, -2..-1).should    eql(V[9999,10000])
+
+          vector.send(method, -4..-4).should  eql(V[1])
+          vector.send(method, -4..-2).should  eql(V[1,2,3])
+          vector.send(method, -4...-2).should eql(V[1,2])
+          vector.send(method, -4..-1).should  eql(V[1,2,3,4])
+          vector.send(method, -4...-1).should eql(V[1,2,3])
+          vector.send(method, -4..3).should   eql(V[1,2,3,4])
+          vector.send(method, -4...3).should  eql(V[1,2,3])
+          vector.send(method, -4..4).should   eql(V[1,2,3,4])
+          vector.send(method, -4...4).should  eql(V[1,2,3,4])
+          vector.send(method, -4..0).should   eql(V[1])
+          vector.send(method, -4...0).should  eql(V.empty)
+          vector.send(method, -4..1).should   eql(V[1,2])
+          vector.send(method, -4...1).should  eql(V[1])
+
+          vector.send(method, -5..-5).should be_nil
+          vector.send(method, -5...-5).should be_nil
+          vector.send(method, -5..-4).should be_nil
+          vector.send(method, -5..-1).should be_nil
+          vector.send(method, -5..10).should be_nil
+
+          big.send(method, -10001..-1).should be_nil
+        end
+
+        it "leaves the original unchanged" do
+          vector.should eql(V[1,2,3,4])
+        end
+      end
+    end
+
+    context "when passed a subclass of Range" do
+      it "works the same as with a Range" do
+        subclass = Class.new(Range)
+        vector.send(method, subclass.new(1,2)).should eql(V[2,3])
+        vector.send(method, subclass.new(-3,-1,true)).should eql(V[2,3])
+      end
+    end
+
+    context "on a subclass of Vector" do
+      it "with index and count or a range, returns an instance of the subclass" do
+        subclass = Class.new(Hamster::Vector)
+        instance = subclass.new([1,2,3])
+        instance.send(method, 0, 0).class.should be(subclass)
+        instance.send(method, 0, 2).class.should be(subclass)
+        instance.send(method, 0..0).class.should be(subclass)
+        instance.send(method, 1..-1).class.should be(subclass)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/sorting_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/sorting_spec.rb
new file mode 100755
index 0000000..375e103
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/sorting_spec.rb
@@ -0,0 +1,57 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  [
+    [:sort, ->(left, right) { left.length <=> right.length }],
+    [:sort_by, ->(item) { item.length }],
+  ].each do |method, comparator|
+    describe "##{method}" do
+      [
+        [[], []],
+        [["A"], ["A"]],
+        [%w[Ichi Ni San], %w[Ni San Ichi]],
+      ].each do |values, expected|
+        describe "on #{values.inspect}" do
+          let(:vector) { V[*values] }
+
+          context "with a block" do
+            it "preserves the original" do
+              vector.send(method, &comparator)
+              vector.should eql(V[*values])
+            end
+
+            it "returns #{expected.inspect}" do
+              vector.send(method, &comparator).should eql(V[*expected])
+            end
+          end
+
+          context "without a block" do
+            it "preserves the original" do
+              vector.send(method)
+              vector.should eql(V[*values])
+            end
+
+            it "returns #{expected.sort.inspect}" do
+              vector.send(method).should eql(V[*expected.sort])
+            end
+          end
+        end
+      end
+
+      [10, 31, 32, 33, 1023, 1024, 1025].each do |size|
+        context "on a #{size}-item vector" do
+          it "behaves like Array#{method}" do
+            array = size.times.map { rand(10000) }
+            vector = V.new(array)
+            if method == :sort
+              vector.sort.should == array.sort
+            else
+              vector.sort_by { |x| -x }.should == array.sort_by { |x| -x }
+            end
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/sum_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/sum_spec.rb
new file mode 100755
index 0000000..6f51c75
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/sum_spec.rb
@@ -0,0 +1,18 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#sum" do
+    [
+      [[], 0],
+      [[2], 2],
+      [[1, 3, 5, 7, 11], 27],
+    ].each do |values, expected|
+      describe "on #{values.inspect}" do
+        it "returns #{expected.inspect}" do
+          V[*values].sum.should == expected
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/take_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/take_spec.rb
new file mode 100755
index 0000000..3320643
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/take_spec.rb
@@ -0,0 +1,43 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#take" do
+    [
+      [[], 10, []],
+      [["A"], 10, ["A"]],
+      [%w[A B C], 0, []],
+      [%w[A B C], 2, %w[A B]],
+      [(1..32), 1, [1]],
+      [(1..33), 32, (1..32)],
+      [(1..100), 40, (1..40)]
+    ].each do |values, number, expected|
+      describe "#{number} from #{values.inspect}" do
+        let(:vector) { V[*values] }
+
+        it "preserves the original" do
+          vector.take(number)
+          vector.should eql(V[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          vector.take(number).should eql(V[*expected])
+        end
+      end
+    end
+
+    context "when number of elements specified is identical to size" do
+      let(:vector) { V[1, 2, 3, 4, 5, 6] }
+      it "returns self" do
+        vector.take(vector.size).should be(vector)
+      end
+    end
+
+    context "when number of elements specified is bigger than size" do
+      let(:vector) { V[1, 2, 3, 4, 5, 6] }
+      it "returns self" do
+        vector.take(vector.size + 1).should be(vector)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/take_while_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/take_while_spec.rb
new file mode 100755
index 0000000..378a38b
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/take_while_spec.rb
@@ -0,0 +1,35 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#take_while" do
+    [
+      [[], []],
+      [["A"], ["A"]],
+      [%w[A B C], %w[A B]]
+    ].each do |values, expected|
+      describe "on #{values.inspect}" do
+        let(:vector) { V[*values] }
+        let(:result) { vector.take_while { |item| item < "C" }}
+
+        describe "with a block" do
+          it "returns #{expected.inspect}" do
+            result.should eql(V[*expected])
+          end
+
+          it "preserves the original" do
+            result
+            vector.should eql(V[*values])
+          end
+        end
+
+        describe "without a block" do
+          it "returns an Enumerator" do
+            vector.take_while.class.should be(Enumerator)
+            vector.take_while.each { |item| item < "C" }.should eql(V[*expected])
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/to_a_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/to_a_spec.rb
new file mode 100755
index 0000000..98c6a68
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/to_a_spec.rb
@@ -0,0 +1,42 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  let(:vector) { V[*values] }
+
+  describe "#to_a" do
+    let(:to_a) { vector.to_a }
+
+    shared_examples "checking to_a values" do
+      it "returns the values" do
+        expect(to_a).to eq(values)
+      end
+    end
+
+    context "with an empty vector" do
+      let(:values) { [] }
+
+      include_examples "checking to_a values"
+    end
+
+    context "with an single item vector" do
+      let(:values) { %w[A] }
+
+      include_examples "checking to_a values"
+    end
+
+    context "with an multi-item vector" do
+      let(:values) { %w[A B] }
+
+      include_examples "checking to_a values"
+    end
+
+    [10, 31, 32, 33, 1000, 1023, 1024, 1025].each do |size|
+      context "with a #{size}-item vector" do
+        let(:values) { (1..size).to_a }
+
+        include_examples "checking to_a values"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/to_ary_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/to_ary_spec.rb
new file mode 100755
index 0000000..b545f62
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/to_ary_spec.rb
@@ -0,0 +1,35 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  let(:vector) { V[*values] }
+
+  describe "#to_ary" do
+    let(:values) { %w[A B C D] }
+
+    it "converts using block parameters" do
+      def expectations(&block)
+        yield(vector)
+      end
+      expectations do |a, b, *c|
+        expect(a).to eq("A")
+        expect(b).to eq("B")
+        expect(c).to eq(%w[C D])
+      end
+    end
+
+    it "converts using method arguments" do
+      def expectations(a, b, *c)
+        expect(a).to eq("A")
+        expect(b).to eq("B")
+        expect(c).to eq(%w[C D])
+      end
+      expectations(*vector)
+    end
+
+    it "converts using splat" do
+      array = *vector
+      expect(array).to eq(%w[A B C D])
+    end
+  end
+end
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/to_list_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/to_list_spec.rb
new file mode 100755
index 0000000..550a7bc
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/to_list_spec.rb
@@ -0,0 +1,33 @@
+require "spec_helper"
+require "hamster/vector"
+require "hamster/list"
+require "hamster/core_ext"
+
+describe Hamster::Vector do
+  describe "#to_list" do
+    [
+      [],
+      ["A"],
+      %w[A B C],
+    ].each do |values|
+      describe "on #{values.inspect}" do
+        let(:vector) { V.new(values) }
+        let(:list) { vector.to_list }
+
+        it "returns a list" do
+          list.is_a?(Hamster::List).should == true
+        end
+
+        describe "the returned list" do
+          it "has the correct length" do
+            list.size.should == values.size
+          end
+
+          it "contains all values" do
+            list.to_a.should == values
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/to_set_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/to_set_spec.rb
new file mode 100755
index 0000000..48bf2fb
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/to_set_spec.rb
@@ -0,0 +1,23 @@
+require "spec_helper"
+require "hamster/vector"
+require "hamster/set"
+
+describe Hamster::Vector do
+  describe "#to_set" do
+    [
+      [],
+      ["A"],
+      %w[A B C],
+      (1..10),
+      (1..32),
+      (1..33),
+      (1..1000)
+    ].each do |values|
+      describe "on #{values.inspect}" do
+        it "returns a set with the same values" do
+          V[*values].to_set.should eql(S[*values])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/transpose_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/transpose_spec.rb
new file mode 100755
index 0000000..dbc76bb
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/transpose_spec.rb
@@ -0,0 +1,49 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#transpose" do
+    it "takes a vector of vectors and transposes rows and columns" do
+      V[V[1, 'a'], V[2, 'b'], V[3, 'c']].transpose.should eql(V[V[1, 2, 3], V["a", "b", "c"]])
+      V[V[1, 2, 3], V["a", "b", "c"]].transpose.should eql(V[V[1, 'a'], V[2, 'b'], V[3, 'c']])
+      V[].transpose.should eql(V[])
+      V[V[]].transpose.should eql(V[])
+      V[V[], V[]].transpose.should eql(V[])
+      V[V[0]].transpose.should eql(V[V[0]])
+      V[V[0], V[1]].transpose.should eql(V[V[0, 1]])
+    end
+
+    it "raises an IndexError if the vectors are not of the same length" do
+      -> { V[V[1,2], V[:a]].transpose }.should raise_error(IndexError)
+    end
+
+    it "also works on Vectors of Arrays" do
+      V[[1,2,3], [4,5,6]].transpose.should eql(V[V[1,4], V[2,5], V[3,6]])
+    end
+
+    [10, 31, 32, 33, 1000, 1023, 1024, 1025, 2000].each do |size|
+      context "on #{size}-item vectors" do
+        it "behaves like Array#transpose" do
+          array = rand(10).times.map { size.times.map { rand(10000) }}
+          vector = V.new(array)
+          result = vector.transpose
+          # Array#== uses Object#== to compare corresponding elements,
+          #   so although Vector#== does type coercion, it does not consider
+          #   nested Arrays and corresponding nested Vectors to be equal
+          # That is why the following ".map { |a| V.new(a) }" is needed
+          result.should == array.transpose.map { |a| V.new(a) }
+          result.each { |v| v.class.should be(Hamster::Vector) }
+        end
+      end
+    end
+
+    context "on a subclass of Vector" do
+      it "returns instances of the subclass" do
+        subclass = Class.new(V)
+        instance = subclass.new([[1,2,3], [4,5,6]])
+        instance.transpose.class.should be(subclass)
+        instance.transpose.each { |v| v.class.should be(subclass) }
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/uniq_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/uniq_spec.rb
new file mode 100755
index 0000000..1616fb4
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/uniq_spec.rb
@@ -0,0 +1,77 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#uniq" do
+    let(:vector) { V['a', 'b', 'a', 'a', 'c', 'b'] }
+
+    it "returns a vector with no duplicates" do
+      vector.uniq.should eql(V['a', 'b', 'c'])
+    end
+
+    it "leaves the original unmodified" do
+      vector.uniq
+      vector.should eql(V['a', 'b', 'a', 'a', 'c', 'b'])
+    end
+
+    it "uses #eql? semantics" do
+      V[1.0, 1].uniq.should eql(V[1.0, 1])
+    end
+
+    it "also uses #hash when determining which values are duplicates" do
+      x = double(1)
+      x.should_receive(:hash).at_least(1).times.and_return(1)
+      y = double(2)
+      y.should_receive(:hash).at_least(1).times.and_return(2)
+      V[x, y].uniq
+    end
+
+    it "keeps the first of each group of duplicate values" do
+      x, y, z = 'a', 'a', 'a'
+      result = V[x, y, z].uniq
+      result.size.should == 1
+      result[0].should be(x)
+    end
+
+    context "when passed a block" do
+      it "uses the return value of the block to determine which items are duplicate" do
+        v = V['a', 'A', 'B', 'b']
+        v.uniq(&:upcase).should == V['a', 'B']
+      end
+    end
+
+    context "on a vector with no duplicates" do
+      it "returns an unchanged vector" do
+        V[1, 2, 3].uniq.should eql(V[1, 2, 3])
+      end
+
+      context "if the vector has more than 32 elements and is initialized with Vector.new" do
+        # Regression test for GitHub issue #182
+        it "returns an unchanged vector" do
+          vector1,vector2 = 2.times.collect { V.new(0..36) }
+          vector1.uniq.should eql(vector2)
+        end
+      end
+    end
+
+    [10, 31, 32, 33, 1000, 1023, 1024, 1025, 2000].each do |size|
+      context "on a #{size}-item vector" do
+        it "behaves like Array#uniq" do
+          array = size.times.map { rand(size*2) }
+          vector = V.new(array)
+          result = vector.uniq
+          result.should == array.uniq
+          result.class.should be(Hamster::Vector)
+        end
+      end
+    end
+
+    context "from a subclass" do
+      it "returns an instance of the subclass" do
+        subclass = Class.new(Hamster::Vector)
+        instance = subclass.new([1,2,3])
+        instance.uniq.class.should be(subclass)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/unshift_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/unshift_spec.rb
new file mode 100755
index 0000000..490ce7a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/unshift_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#unshift" do
+    [
+      [[], "A", ["A"]],
+      [["A"], "B", %w[B A]],
+      [["A"], "A", %w[A A]],
+      [%w[A B C], "D", %w[D A B C]],
+      [1..31, 0, 0..31],
+      [1..32, 0, 0..32],
+      [1..33, 0, 0..33]
+    ].each do |values, new_value, expected|
+      context "on #{values.inspect} with #{new_value.inspect}" do
+        let(:vector) { V[*values] }
+
+        it "preserves the original" do
+          vector.unshift(new_value)
+          vector.should eql(V[*values])
+        end
+
+        it "returns #{expected.inspect}" do
+          vector.unshift(new_value).should eql(V[*expected])
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/values_at_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/values_at_spec.rb
new file mode 100755
index 0000000..adce3a1
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/values_at_spec.rb
@@ -0,0 +1,34 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#values_at" do
+    let(:vector) { V['a', 'b', 'c'] }
+
+    it "accepts any number of indices, and returns a vector of items at those indices" do
+      vector.values_at(0).should eql(V['a'])
+      vector.values_at(1,2).should eql(V['b', 'c'])
+    end
+
+    context "when passed invalid indices" do
+      it "fills in with nils" do
+        vector.values_at(1,2,3).should  eql(V['b', 'c', nil])
+        vector.values_at(-10,10).should eql(V[nil, nil])
+      end
+    end
+
+    context "when passed no arguments" do
+      it "returns an empty vector" do
+        vector.values_at.should eql(V.empty)
+      end
+    end
+
+    context "from a subclass" do
+      it "returns an instance of the subclass" do
+        subclass = Class.new(Hamster::Vector)
+        instance = subclass.new([1,2,3])
+        instance.values_at(1,2).class.should be(subclass)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/zip_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/zip_spec.rb
new file mode 100755
index 0000000..5c04b66
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/hamster/vector/zip_spec.rb
@@ -0,0 +1,58 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  describe "#zip" do
+    let(:vector) { V[1,2,3,4] }
+
+    context "with a block" do
+      it "yields arrays of one corresponding element from each input sequence" do
+        result = []
+        vector.zip(['a', 'b', 'c', 'd']) { |obj| result << obj }
+        result.should eql([[1,'a'], [2,'b'], [3,'c'], [4,'d']])
+      end
+
+      it "fills in the missing values with nils" do
+        result = []
+        vector.zip(['a', 'b']) { |obj| result << obj }
+        result.should eql([[1,'a'], [2,'b'], [3,nil], [4,nil]])
+      end
+
+      it "returns nil" do
+        vector.zip([2,3,4]) {}.should be_nil
+      end
+
+      it "can handle multiple inputs, of different classes" do
+        result = []
+        vector.zip(V[2,3,4,5], [5,6,7,8]) { |obj| result << obj }
+        result.should eql([[1,2,5], [2,3,6], [3,4,7], [4,5,8]])
+      end
+    end
+
+    context "without a block" do
+      it "returns a vector of arrays (one corresponding element from each input sequence)" do
+        vector.zip([2,3,4,5]).should eql(V[[1,2], [2,3], [3,4], [4,5]])
+      end
+    end
+
+    [10, 31, 32, 33, 1000, 1023, 1024, 1025].each do |size|
+      context "on #{size}-item vectors" do
+        it "behaves like Array#zip" do
+          array   = (rand(9)+1).times.map { size.times.map { rand(10000) }}
+          vectors = array.map { |a| V.new(a) }
+          result  = vectors.first.zip(*vectors.drop(1))
+          result.class.should be(Hamster::Vector)
+          result.should == array[0].zip(*array.drop(1))
+        end
+      end
+    end
+
+    context "from a subclass" do
+      it "returns an instance of the subclass" do
+        subclass = Class.new(Hamster::Vector)
+        instance = subclass.new([1,2,3])
+        instance.zip([4,5,6]).class.should be(subclass)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/lib/load_spec.rb b/app/server/vendor/hamster-3.0.0/spec/lib/load_spec.rb
new file mode 100755
index 0000000..e8b3f99
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/lib/load_spec.rb
@@ -0,0 +1,42 @@
+# It should be possible to require any one Hamster structure,
+# without loading all the others
+
+hamster_lib_dir = File.join(File.dirname(__FILE__), "..", "..", 'lib')
+
+describe :Hamster do
+  describe :Hash do
+    it "can be loaded separately" do
+      system(%{ruby -e "$:.unshift('#{hamster_lib_dir}'); require 'hamster/hash'; Hamster::Hash.new"}).should be(true)
+    end
+  end
+
+  describe :Set do
+    it "can be loaded separately" do
+      system(%{ruby -e "$:.unshift('#{hamster_lib_dir}'); require 'hamster/set'; Hamster::Set.new"}).should be(true)
+    end
+  end
+
+  describe :Vector do
+    it "can be loaded separately" do
+      system(%{ruby -e "$:.unshift('#{hamster_lib_dir}'); require 'hamster/vector'; Hamster::Vector.new"}).should be(true)
+    end
+  end
+
+  describe :List do
+    it "can be loaded separately" do
+      system(%{ruby -e "$:.unshift('#{hamster_lib_dir}'); require 'hamster/list'; Hamster::List[]"}).should be(true)
+    end
+  end
+
+  describe :SortedSet do
+    it "can be loaded separately" do
+      system(%{ruby -e "$:.unshift('#{hamster_lib_dir}'); require 'hamster/sorted_set'; Hamster::SortedSet.new"}).should be(true)
+    end
+  end
+
+  describe :Deque do
+    it "can be loaded separately" do
+      system(%{ruby -e "$:.unshift('#{hamster_lib_dir}'); require 'hamster/deque'; Hamster::Deque.new"}).should be(true)
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/hamster-3.0.0/spec/spec_helper.rb b/app/server/vendor/hamster-3.0.0/spec/spec_helper.rb
new file mode 100755
index 0000000..5f7c99a
--- /dev/null
+++ b/app/server/vendor/hamster-3.0.0/spec/spec_helper.rb
@@ -0,0 +1,96 @@
+require "codeclimate-test-reporter"
+CodeClimate::TestReporter.start
+
+require "pry"
+require "rspec"
+require "hamster/hash"
+require "hamster/set"
+require "hamster/vector"
+require "hamster/sorted_set"
+require "hamster/list"
+require "hamster/deque"
+require "hamster/core_ext"
+
+# Suppress warnings from use of old RSpec expectation and mock syntax
+# If all tests are eventually updated to use the new syntax, this can be removed
+RSpec.configure do |config|
+  config.expect_with :rspec do |c|
+    c.syntax = [:should, :expect]
+  end
+  config.mock_with :rspec do |c|
+    c.syntax = [:should, :expect]
+  end
+end
+
+V = Hamster::Vector
+L = Hamster::List
+H = Hamster::Hash
+S = Hamster::Set
+SS = Hamster::SortedSet
+D = Hamster::Deque
+EmptyList = Hamster::EmptyList
+
+Struct.new("Customer", :name, :address)
+
+def fixture(name)
+  File.read(fixture_path(name))
+end
+
+def fixture_path(name)
+  File.join("spec", "fixtures", name)
+end
+
+if RUBY_ENGINE == "ruby"
+  def calculate_stack_overflow_depth(n)
+    calculate_stack_overflow_depth(n + 1)
+  rescue SystemStackError
+    n
+  end
+  STACK_OVERFLOW_DEPTH = calculate_stack_overflow_depth(2)
+else
+  STACK_OVERFLOW_DEPTH = 16_384
+end
+
+class DeterministicHash
+  attr_reader :hash, :value
+
+  def initialize(value, hash)
+    @value = value
+    @hash = hash
+  end
+
+  def to_s
+    @value.to_s
+  end
+
+  def inspect
+    @value.inspect
+  end
+
+  def ==(other)
+    other.is_a?(DeterministicHash) && self.value == other.value
+  end
+  alias :eql? :==
+
+  def <=>(other)
+    self.value <=> other.value
+  end
+end
+
+class EqualNotEql
+  def ==(other)
+    true
+  end
+  def eql?(other)
+    false
+  end
+end
+
+class EqlNotEqual
+  def ==(other)
+    false
+  end
+  def eql?(other)
+    true
+  end
+end
diff --git a/app/server/vendor/i18n/.gitignore b/app/server/vendor/i18n/.gitignore
new file mode 100644
index 0000000..b066d1e
--- /dev/null
+++ b/app/server/vendor/i18n/.gitignore
@@ -0,0 +1,8 @@
+.DS_Store
+test/rails/fixtures
+nbproject/
+vendor/**/*
+*.swp
+pkg
+.bundle
+.rvmrc
diff --git a/app/server/vendor/i18n/.travis.yml b/app/server/vendor/i18n/.travis.yml
new file mode 100644
index 0000000..0fd9835
--- /dev/null
+++ b/app/server/vendor/i18n/.travis.yml
@@ -0,0 +1,43 @@
+before_install: "sudo apt-get install ruby-tokyocabinet -y"
+
+rvm:
+  - 1.8.7
+  - 1.9.3
+  - 2.0.0
+  - 2.1
+  - ree
+  - rbx
+  - jruby
+
+gemfile:
+  - Gemfile
+  - gemfiles/Gemfile.rails-2.3.x
+  - gemfiles/Gemfile.rails-3.0.x
+  - gemfiles/Gemfile.rails-3.1.x
+  - gemfiles/Gemfile.rails-3.2.x
+  - gemfiles/Gemfile.rails-4.0.x
+  - gemfiles/Gemfile.rails-4.1.x
+
+matrix:
+  allow_failures:
+    - rvm: ree
+    - rvm: rbx
+    - rvm: jruby
+  exclude:
+    - gemfile: gemfiles/Gemfile.rails-2.3.x
+      rvm: 2.0.0
+    - gemfile: gemfiles/Gemfile.rails-2.3.x
+      rvm: 2.1
+    - gemfile: gemfiles/Gemfile.rails-2.3.x
+      rvm: rbx
+    - gemfile: gemfiles/Gemfile.rails-2.3.x
+      rvm: jruby
+    - gemfile: gemfiles/Gemfile.rails-4.0.x
+      rvm: 1.8.7
+    - gemfile: gemfiles/Gemfile.rails-4.0.x
+      rvm: ree
+    - gemfile: gemfiles/Gemfile.rails-4.1.x
+      rvm: 1.8.7
+    - gemfile: gemfiles/Gemfile.rails-4.1.x
+      rvm: ree
+  fast_finish: true
diff --git a/app/server/vendor/i18n/Gemfile b/app/server/vendor/i18n/Gemfile
new file mode 100644
index 0000000..24ca9f4
--- /dev/null
+++ b/app/server/vendor/i18n/Gemfile
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gemspec
+
+gem 'mocha'
+gem 'test_declarative'
+gem 'rake'
diff --git a/app/server/vendor/i18n/Gemfile.lock b/app/server/vendor/i18n/Gemfile.lock
new file mode 100644
index 0000000..42eabc0
--- /dev/null
+++ b/app/server/vendor/i18n/Gemfile.lock
@@ -0,0 +1,23 @@
+PATH
+  remote: .
+  specs:
+    i18n (0.6.10)
+
+GEM
+  remote: https://rubygems.org/
+  specs:
+    metaclass (0.0.4)
+    mocha (1.0.0)
+      metaclass (~> 0.0.1)
+    rake (10.3.1)
+    test_declarative (0.0.5)
+
+PLATFORMS
+  java
+  ruby
+
+DEPENDENCIES
+  i18n!
+  mocha
+  rake
+  test_declarative
diff --git a/app/server/vendor/i18n/MIT-LICENSE b/app/server/vendor/i18n/MIT-LICENSE
new file mode 100644
index 0000000..ed8e9ee
--- /dev/null
+++ b/app/server/vendor/i18n/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2008 The Ruby I18n team
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/app/server/vendor/i18n/README.md b/app/server/vendor/i18n/README.md
new file mode 100644
index 0000000..df79695
--- /dev/null
+++ b/app/server/vendor/i18n/README.md
@@ -0,0 +1,105 @@
+# Ruby I18n
+
+[![Build Status](https://api.travis-ci.org/svenfuchs/i18n.svg?branch=master)](https://travis-ci.org/svenfuchs/i18n)
+
+Ruby Internationalization and localization solution.
+
+Features:
+
+* translation and localization
+* interpolation of values to translations (Ruby 1.9 compatible syntax)
+* pluralization (CLDR compatible)
+* customizable transliteration to ASCII
+* flexible defaults
+* bulk lookup
+* lambdas as translation data
+* custom key/scope separator
+* custom exception handlers
+* extensible architecture with a swappable backend
+
+Pluggable features:
+
+* Cache
+* Pluralization: lambda pluralizers stored as translation data
+* Locale fallbacks, RFC4647 compliant (optionally: RFC4646 locale validation)
+* Gettext support
+* Translation metadata
+
+Alternative backends:
+
+* Chain
+* ActiveRecord (optionally: ActiveRecord::Missing and ActiveRecord::StoreProcs)
+* KeyValue (uses active_support/json and cannot store procs)
+
+For more information and lots of resources see: [http://ruby-i18n.org/wiki](http://ruby-i18n.org/wiki)
+
+## Installation
+
+gem install i18n
+
+#### Rails version warning
+
+On Rails < 2.3.6 the method I18n.localize will fail with MissingInterpolationArgument (issue [20](http://github.com/svenfuchs/i18n/issues/issue/20). Upgrade to Rails 2.3.6 or higher (2.3.8 preferably) is recommended.
+
+### Installation on Rails < 2.3.5 (deprecated)
+
+Up to version 2.3.4 Rails will not accept i18n gems > 0.1.3. There is an unpacked
+gem inside of active_support/lib/vendor which gets loaded unless `gem 'i18n', '~> 0.1.3'`.
+This requirement is relaxed in [6da03653](http://github.com/rails/rails/commit/6da03653)
+
+The new i18n gem can be loaded from vendor/plugins like this:
+
+```
+def reload_i18n!
+  raise "Move to i18n version 0.2.0 or greater" if Rails.version > "2.3.4"
+
+  $:.grep(/i18n/).each { |path| $:.delete(path) }
+  I18n::Backend.send :remove_const, "Simple"
+  $: << Rails.root.join('vendor', 'plugins', 'i18n', 'lib').to_s
+end
+```
+
+Then you can `reload_i18n!` inside an i18n initializer.
+
+## Tests
+
+You can run tests both with
+
+* `rake test` or just `rake`
+* run any test file directly, e.g. `ruby -Ilib -Itest test/api/simple_test.rb`
+* run all tests with `ruby -Ilib -Itest test/all.rb`
+
+You can run all tests against all Gemfiles with
+
+* `ruby test/run_all.rb`
+
+The structure of the test suite is a bit unusual as it uses modules to reuse
+particular tests in different test cases.
+
+The reason for this is that we need to enforce the I18n API across various
+combinations of extensions. E.g. the Simple backend alone needs to support
+the same API as any combination of feature and/or optimization modules included
+to the Simple backend. We test this by reusing the same API defition (implemented
+as test methods) in test cases with different setups.
+
+You can find the test cases that enforce the API in test/api. And you can find
+the API definition test methods in test/api/tests.
+
+All other test cases (e.g. as defined in test/backend, test/core_ext) etc.
+follow the usual test setup and should be easy to grok.
+
+## Authors
+
+* [Sven Fuchs](http://www.artweb-design.de)
+* [Joshua Harvey](http://www.workingwithrails.com/person/759-joshua-harvey)
+* [Stephan Soller](http://www.arkanis-development.de)
+* [Saimon Moore](http://saimonmoore.net)
+* [Matt Aimonetti](http://railsontherun.com)
+
+## Contributors
+
+http://github.com/svenfuchs/i18n/contributors
+
+## License
+
+MIT License. See the included MIT-LICENSE file.
diff --git a/app/server/vendor/i18n/Rakefile b/app/server/vendor/i18n/Rakefile
new file mode 100644
index 0000000..5e6e1db
--- /dev/null
+++ b/app/server/vendor/i18n/Rakefile
@@ -0,0 +1,13 @@
+require 'bundler/gem_tasks'
+require 'rake/testtask'
+
+task :default => [:test]
+
+Rake::TestTask.new(:test) do |t|
+  t.libs << 'lib'
+  t.libs << 'test'
+  t.pattern = "#{File.dirname(__FILE__)}/test/all.rb"
+  t.verbose = true
+  t.warning = true
+end
+Rake::Task['test'].comment = "Run all i18n tests"
diff --git a/app/server/vendor/i18n/benchmark/example.yml b/app/server/vendor/i18n/benchmark/example.yml
new file mode 100644
index 0000000..650c390
--- /dev/null
+++ b/app/server/vendor/i18n/benchmark/example.yml
@@ -0,0 +1,154 @@
+en:
+  first: "First"
+
+  activemodel:
+    errors:
+      messages: :"activerecord.errors.messages"
+
+  activerecord:
+    errors:
+      messages:
+        inclusion: "is not included in the list"
+        exclusion: "is reserved"
+        invalid: "is invalid"
+        confirmation: "doesn't match confirmation"
+        accepted: "must be accepted"
+        empty: "can't be empty"
+        blank: "can't be blank"
+        too_long: "is too long (maximum is %{count} characters)"
+        too_short: "is too short (minimum is %{count} characters)"
+        wrong_length: "is the wrong length (should be %{count} characters)"
+        taken: "has already been taken"
+        not_a_number: "is not a number"
+        greater_than: "must be greater than %{count}"
+        greater_than_or_equal_to: "must be greater than or equal to %{count}"
+        equal_to: "must be equal to %{count}"
+        less_than: "must be less than %{count}"
+        less_than_or_equal_to: "must be less than or equal to %{count}"
+        odd: "must be odd"
+        even: "must be even"
+        record_invalid: "Validation failed: %{errors}"
+
+      models:
+        user:
+          blank: "This is a custom blank message for %{model}: %{attribute}"
+          attributes:
+            login:
+              blank: "This is a custom blank message for User login"
+
+    models:
+      user: "Dude"
+
+    attributes:
+      admins:
+        user:
+          login: "Handle"
+
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y-%m-%d"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+    day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
+    abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
+    abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
+    # Used in date_select and datime_select.
+    order:
+      - :year,
+      - :month,
+      - :day
+
+  time:
+    formats:
+      default: "%a, %d %b %Y %H:%M:%S %z"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "am"
+    pm: "pm"
+
+  support:
+    array:
+      words_connector: ", "
+      two_words_connector: " and "
+      last_word_connector: ", and "
+
+  activemodel:
+    errors:
+      messages:
+        inclusion: "is not included in the list"
+        exclusion: "is reserved"
+        invalid: "is invalid"
+        confirmation: "doesn't match confirmation"
+        accepted: "must be accepted"
+        empty: "can't be empty"
+        blank: "can't be blank"
+        too_long: "is too long (maximum is %{count} characters)"
+        too_short: "is too short (minimum is %{count} characters)"
+        wrong_length: "is the wrong length (should be %{count} characters)"
+        taken: "has already been taken"
+        not_a_number: "is not a number"
+        greater_than: "must be greater than %{count}"
+        greater_than_or_equal_to: "must be greater than or equal to %{count}"
+        equal_to: "must be equal to %{count}"
+        less_than: "must be less than %{count}"
+        less_than_or_equal_to: "must be less than or equal to %{count}"
+        odd: "must be odd"
+        even: "must be even"
+        record_invalid: "Validation failed: %{errors}"
+
+      models:
+        user:
+          blank: "This is a custom blank message for %{model}: %{attribute}"
+          attributes:
+            login:
+              blank: "This is a custom blank message for User login"
+
+    models:
+      user: "Dude"
+
+    attributes:
+      user:
+        login: "Handle"
+
+  model_data:
+    date:
+      formats:
+        # Use the strftime parameters for formats.
+        # When no format has been given, it uses default.
+        # You can provide other formats here if you like!
+        default: "%Y-%m-%d"
+        short: "%b %d"
+        long: "%B %d, %Y"
+
+      day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
+      abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
+
+      # Don't forget the nil at the beginning; there's no such thing as a 0th month
+      month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
+      abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
+      # Used in date_select and datime_select.
+      order:
+        - :year
+        - :month
+        - :day
+
+    time:
+      formats:
+        default: "%a, %d %b %Y %H:%M:%S %z"
+        short: "%d %b %H:%M"
+        long: "%B %d, %Y %H:%M"
+      am: "am"
+      pm: "pm"
+
+    support:
+      array:
+        words_connector: ", "
+        two_words_connector: " and "
+        last_word_connector: ", and "
diff --git a/app/server/vendor/i18n/benchmark/run.rb b/app/server/vendor/i18n/benchmark/run.rb
new file mode 100644
index 0000000..0a59eeb
--- /dev/null
+++ b/app/server/vendor/i18n/benchmark/run.rb
@@ -0,0 +1,117 @@
+#! /usr/bin/ruby
+$:.unshift File.expand_path('../../lib', __FILE__)
+
+require 'i18n'
+require 'benchmark'
+require 'yaml'
+
+DATA_STORES = ARGV.delete("-ds")
+N = (ARGV.shift || 1000).to_i
+YAML_HASH = YAML.load_file(File.expand_path("example.yml", File.dirname(__FILE__)))
+
+module Backends
+  Simple = I18n::Backend::Simple.new
+
+  Interpolation = Class.new(I18n::Backend::Simple) do
+    include I18n::Backend::InterpolationCompiler
+  end.new
+
+  if DATA_STORES
+    require 'rubygems'
+    require File.expand_path('../../test/test_setup/active_record', __FILE__)
+    require File.expand_path('../../test/test_setup/rufus_tokyo', __FILE__)
+
+    Test.setup_active_record
+    ActiveRecord = I18n::Backend::ActiveRecord.new if defined?(::ActiveRecord)
+
+    Test.setup_rufus_tokyo
+    TokyoCabinet = I18n::Backend::KeyValue.new(Rufus::Tokyo::Cabinet.new("*"), true) if defined?(::Rufus::Tokyo)
+  end
+end
+
+ORDER = %w(Simple Interpolation ActiveRecord TokyoCabinet)
+ORDER.map!(&:to_sym) if RUBY_VERSION > '1.9'
+
+module Benchmark
+  WIDTH = 20
+
+  def self.rt(label = "", n=N, &blk)
+    print label.ljust(WIDTH)
+    time, objects = measure_objects(n, &blk)
+    time = time.respond_to?(:real) ? time.real : time
+    print format("%8.2f ms  %8d objects\n", time * 1000, objects)
+  rescue Exception => e
+    print "FAILED: #{e.message}"
+  end
+
+  if ObjectSpace.respond_to?(:allocated_objects)
+    def self.measure_objects(n, &blk)
+      obj = ObjectSpace.allocated_objects
+      t = Benchmark.realtime { n.times(&blk) }
+      [t, ObjectSpace.allocated_objects - obj]
+    end
+  else
+    def self.measure_objects(n, &blk)
+      [Benchmark.measure { n.times(&blk) }, 0]
+    end
+  end
+end
+
+benchmarker = lambda do |backend_name|
+  I18n.backend = Backends.const_get(backend_name)
+  puts "=> #{backend_name}\n\n"
+
+  Benchmark.rt "store", 1 do
+    I18n.backend.store_translations *(YAML_HASH.to_a.first)
+  end
+
+  I18n.backend.translate :en, :first
+
+  Benchmark.rt "available_locales" do
+    I18n.backend.available_locales
+  end
+
+  Benchmark.rt "t (depth=3)" do
+    I18n.backend.translate :en, :"activerecord.models.user"
+  end
+
+  Benchmark.rt "t (depth=5)" do
+    I18n.backend.translate :en, :"activerecord.attributes.admins.user.login"
+  end
+
+  Benchmark.rt "t (depth=7)" do
+    I18n.backend.translate :en, :"activerecord.errors.models.user.attributes.login.blank"
+  end
+
+  Benchmark.rt "t w/ default" do
+    I18n.backend.translate :en, :"activerecord.models.another", :default => "Another"
+  end
+
+  Benchmark.rt "t w/ interpolation" do
+    I18n.backend.translate :en, :"activerecord.errors.models.user.blank", :model => "User", :attribute => "name"
+  end
+
+  Benchmark.rt "t w/ link" do
+    I18n.backend.translate :en, :"activemodel.errors.messages.blank"
+  end
+
+  Benchmark.rt "t subtree" do
+    I18n.backend.translate :en, :"activerecord.errors.messages"
+  end
+
+  puts
+end
+
+# Run!
+puts
+puts "Running benchmarks with N = #{N}\n\n"
+(ORDER & Backends.constants).each(&benchmarker)
+
+Backends.constants.each do |backend_name|
+ backend = Backends.const_get(backend_name)
+ backend.reload!
+ backend.extend I18n::Backend::Memoize
+end
+
+puts "Running memoized benchmarks with N = #{N}\n\n"
+(ORDER & Backends.constants).each(&benchmarker)
\ No newline at end of file
diff --git a/app/server/vendor/i18n/gemfiles/Gemfile.rails-2.3.x b/app/server/vendor/i18n/gemfiles/Gemfile.rails-2.3.x
new file mode 100644
index 0000000..b0b1fa1
--- /dev/null
+++ b/app/server/vendor/i18n/gemfiles/Gemfile.rails-2.3.x
@@ -0,0 +1,11 @@
+source 'https://rubygems.org'
+
+gemspec :path => '..'
+
+gem 'activesupport', '~> 2.3'
+gem 'mocha'
+gem 'test_declarative'
+gem 'rufus-tokyo'
+gem 'ffi'
+gem 'rake'
+gem 'yajl-ruby'
diff --git a/app/server/vendor/i18n/gemfiles/Gemfile.rails-2.3.x.lock b/app/server/vendor/i18n/gemfiles/Gemfile.rails-2.3.x.lock
new file mode 100644
index 0000000..453fb74
--- /dev/null
+++ b/app/server/vendor/i18n/gemfiles/Gemfile.rails-2.3.x.lock
@@ -0,0 +1,30 @@
+PATH
+  remote: ..
+  specs:
+    i18n (0.6.10)
+
+GEM
+  remote: https://rubygems.org/
+  specs:
+    activesupport (2.3.18)
+    ffi (1.9.3)
+    metaclass (0.0.4)
+    mocha (1.0.0)
+      metaclass (~> 0.0.1)
+    rake (10.3.1)
+    rufus-tokyo (1.0.7)
+    test_declarative (0.0.5)
+    yajl-ruby (1.2.0)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  activesupport (~> 2.3)
+  ffi
+  i18n!
+  mocha
+  rake
+  rufus-tokyo
+  test_declarative
+  yajl-ruby
diff --git a/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.0.x b/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.0.x
new file mode 100644
index 0000000..59fcf0e
--- /dev/null
+++ b/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.0.x
@@ -0,0 +1,11 @@
+source 'https://rubygems.org'
+
+gemspec :path => '..'
+
+gem 'activesupport', '~> 3.0.0'
+gem 'mocha'
+gem 'test_declarative'
+gem 'rufus-tokyo'
+gem 'ffi'
+gem 'rake'
+gem 'yajl-ruby'
diff --git a/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.0.x.lock b/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.0.x.lock
new file mode 100644
index 0000000..12d8524
--- /dev/null
+++ b/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.0.x.lock
@@ -0,0 +1,30 @@
+PATH
+  remote: ..
+  specs:
+    i18n (0.6.10)
+
+GEM
+  remote: https://rubygems.org/
+  specs:
+    activesupport (3.0.20)
+    ffi (1.9.3)
+    metaclass (0.0.4)
+    mocha (1.0.0)
+      metaclass (~> 0.0.1)
+    rake (10.3.1)
+    rufus-tokyo (1.0.7)
+    test_declarative (0.0.5)
+    yajl-ruby (1.2.0)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  activesupport (~> 3.0.0)
+  ffi
+  i18n!
+  mocha
+  rake
+  rufus-tokyo
+  test_declarative
+  yajl-ruby
diff --git a/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.1.x b/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.1.x
new file mode 100644
index 0000000..98174c4
--- /dev/null
+++ b/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.1.x
@@ -0,0 +1,10 @@
+source 'https://rubygems.org'
+
+gemspec :path => '..'
+
+gem 'activesupport', '~> 3.1.0'
+gem 'mocha'
+gem 'test_declarative'
+gem 'rufus-tokyo'
+gem 'ffi'
+gem 'rake'
diff --git a/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.1.x.lock b/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.1.x.lock
new file mode 100644
index 0000000..d3f0789
--- /dev/null
+++ b/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.1.x.lock
@@ -0,0 +1,30 @@
+PATH
+  remote: ..
+  specs:
+    i18n (0.6.10)
+
+GEM
+  remote: https://rubygems.org/
+  specs:
+    activesupport (3.1.12)
+      multi_json (~> 1.0)
+    ffi (1.9.3)
+    metaclass (0.0.4)
+    mocha (1.0.0)
+      metaclass (~> 0.0.1)
+    multi_json (1.10.0)
+    rake (10.3.1)
+    rufus-tokyo (1.0.7)
+    test_declarative (0.0.5)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  activesupport (~> 3.1.0)
+  ffi
+  i18n!
+  mocha
+  rake
+  rufus-tokyo
+  test_declarative
diff --git a/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.2.x b/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.2.x
new file mode 100644
index 0000000..0aed63b
--- /dev/null
+++ b/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.2.x
@@ -0,0 +1,10 @@
+source 'https://rubygems.org'
+
+gemspec :path => '..'
+
+gem 'activesupport', '~> 3.2.0'
+gem 'mocha'
+gem 'test_declarative'
+gem 'rufus-tokyo'
+gem 'ffi'
+gem 'rake'
diff --git a/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.2.x.lock b/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.2.x.lock
new file mode 100644
index 0000000..a036794
--- /dev/null
+++ b/app/server/vendor/i18n/gemfiles/Gemfile.rails-3.2.x.lock
@@ -0,0 +1,31 @@
+PATH
+  remote: ..
+  specs:
+    i18n (0.6.10)
+
+GEM
+  remote: https://rubygems.org/
+  specs:
+    activesupport (3.2.18)
+      i18n (~> 0.6, >= 0.6.4)
+      multi_json (~> 1.0)
+    ffi (1.9.3)
+    metaclass (0.0.4)
+    mocha (1.0.0)
+      metaclass (~> 0.0.1)
+    multi_json (1.10.0)
+    rake (10.3.1)
+    rufus-tokyo (1.0.7)
+    test_declarative (0.0.5)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  activesupport (~> 3.2.0)
+  ffi
+  i18n!
+  mocha
+  rake
+  rufus-tokyo
+  test_declarative
diff --git a/app/server/vendor/i18n/gemfiles/Gemfile.rails-4.0.x b/app/server/vendor/i18n/gemfiles/Gemfile.rails-4.0.x
new file mode 100644
index 0000000..ac0793d
--- /dev/null
+++ b/app/server/vendor/i18n/gemfiles/Gemfile.rails-4.0.x
@@ -0,0 +1,10 @@
+source 'https://rubygems.org'
+
+gemspec :path => '..'
+
+gem 'activesupport', '~> 4.0.0'
+gem 'mocha'
+gem 'test_declarative'
+gem 'rufus-tokyo'
+gem 'ffi'
+gem 'rake'
diff --git a/app/server/vendor/i18n/gemfiles/Gemfile.rails-4.0.x.lock b/app/server/vendor/i18n/gemfiles/Gemfile.rails-4.0.x.lock
new file mode 100644
index 0000000..e2dd701
--- /dev/null
+++ b/app/server/vendor/i18n/gemfiles/Gemfile.rails-4.0.x.lock
@@ -0,0 +1,37 @@
+PATH
+  remote: ..
+  specs:
+    i18n (0.6.10)
+
+GEM
+  remote: https://rubygems.org/
+  specs:
+    activesupport (4.0.5)
+      i18n (~> 0.6, >= 0.6.9)
+      minitest (~> 4.2)
+      multi_json (~> 1.3)
+      thread_safe (~> 0.1)
+      tzinfo (~> 0.3.37)
+    ffi (1.9.3)
+    metaclass (0.0.4)
+    minitest (4.7.5)
+    mocha (1.0.0)
+      metaclass (~> 0.0.1)
+    multi_json (1.10.0)
+    rake (10.3.1)
+    rufus-tokyo (1.0.7)
+    test_declarative (0.0.5)
+    thread_safe (0.3.3)
+    tzinfo (0.3.39)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  activesupport (~> 4.0.0)
+  ffi
+  i18n!
+  mocha
+  rake
+  rufus-tokyo
+  test_declarative
diff --git a/app/server/vendor/i18n/gemfiles/Gemfile.rails-4.1.x b/app/server/vendor/i18n/gemfiles/Gemfile.rails-4.1.x
new file mode 100644
index 0000000..8db40a5
--- /dev/null
+++ b/app/server/vendor/i18n/gemfiles/Gemfile.rails-4.1.x
@@ -0,0 +1,10 @@
+source 'https://rubygems.org'
+
+gemspec :path => '..'
+
+gem 'activesupport', '~> 4.1.0'
+gem 'mocha'
+gem 'test_declarative'
+gem 'rufus-tokyo'
+gem 'ffi'
+gem 'rake'
diff --git a/app/server/vendor/i18n/gemfiles/Gemfile.rails-4.1.x.lock b/app/server/vendor/i18n/gemfiles/Gemfile.rails-4.1.x.lock
new file mode 100644
index 0000000..945f3d7
--- /dev/null
+++ b/app/server/vendor/i18n/gemfiles/Gemfile.rails-4.1.x.lock
@@ -0,0 +1,38 @@
+PATH
+  remote: ..
+  specs:
+    i18n (0.6.10)
+
+GEM
+  remote: https://rubygems.org/
+  specs:
+    activesupport (4.1.1)
+      i18n (~> 0.6, >= 0.6.9)
+      json (~> 1.7, >= 1.7.7)
+      minitest (~> 5.1)
+      thread_safe (~> 0.1)
+      tzinfo (~> 1.1)
+    ffi (1.9.3)
+    json (1.8.1)
+    metaclass (0.0.4)
+    minitest (5.3.3)
+    mocha (1.0.0)
+      metaclass (~> 0.0.1)
+    rake (10.3.1)
+    rufus-tokyo (1.0.7)
+    test_declarative (0.0.5)
+    thread_safe (0.3.3)
+    tzinfo (1.1.0)
+      thread_safe (~> 0.1)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  activesupport (~> 4.1.0)
+  ffi
+  i18n!
+  mocha
+  rake
+  rufus-tokyo
+  test_declarative
diff --git a/app/server/vendor/i18n/i18n.gemspec b/app/server/vendor/i18n/i18n.gemspec
new file mode 100644
index 0000000..9feefe4
--- /dev/null
+++ b/app/server/vendor/i18n/i18n.gemspec
@@ -0,0 +1,21 @@
+# encoding: utf-8
+
+$: << File.expand_path('../lib', __FILE__)
+require 'i18n/version'
+
+Gem::Specification.new do |s|
+  s.name         = "i18n"
+  s.version      = I18n::VERSION
+  s.authors      = ["Sven Fuchs", "Joshua Harvey", "Matt Aimonetti", "Stephan Soller", "Saimon Moore"]
+  s.email        = "rails-i18n at googlegroups.com"
+  s.homepage     = "http://github.com/svenfuchs/i18n"
+  s.summary      = "New wave Internationalization support for Ruby"
+  s.description  = "New wave Internationalization support for Ruby."
+  s.license      = "MIT"
+
+  s.files        = Dir.glob("{gemfiles,lib,test}/**/**") + %w(README.md MIT-LICENSE)
+  s.platform     = Gem::Platform::RUBY
+  s.require_path = 'lib'
+  s.rubyforge_project = '[none]'
+  s.required_rubygems_version = '>= 1.3.5'
+end
diff --git a/app/server/vendor/i18n/lib/i18n.rb b/app/server/vendor/i18n/lib/i18n.rb
new file mode 100644
index 0000000..98b65bf
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n.rb
@@ -0,0 +1,364 @@
+require 'i18n/version'
+require 'i18n/exceptions'
+require 'i18n/interpolate/ruby'
+
+module I18n
+  autoload :Backend, 'i18n/backend'
+  autoload :Config,  'i18n/config'
+  autoload :Gettext, 'i18n/gettext'
+  autoload :Locale,  'i18n/locale'
+  autoload :Tests,   'i18n/tests'
+
+  RESERVED_KEYS = [:scope, :default, :separator, :resolve, :object, :fallback, :format, :cascade, :throw, :raise, :rescue_format]
+  RESERVED_KEYS_PATTERN = /%\{(#{RESERVED_KEYS.join("|")})\}/
+
+  extend(Module.new {
+    # Gets I18n configuration object.
+    def config
+      Thread.current[:i18n_config] ||= I18n::Config.new
+    end
+
+    # Sets I18n configuration object.
+    def config=(value)
+      Thread.current[:i18n_config] = value
+    end
+
+    # Write methods which delegates to the configuration object
+    %w(locale backend default_locale available_locales default_separator
+      exception_handler load_path enforce_available_locales).each do |method|
+      module_eval <<-DELEGATORS, __FILE__, __LINE__ + 1
+        def #{method}
+          config.#{method}
+        end
+
+        def #{method}=(value)
+          config.#{method} = (value)
+        end
+      DELEGATORS
+    end
+
+    # Tells the backend to reload translations. Used in situations like the
+    # Rails development environment. Backends can implement whatever strategy
+    # is useful.
+    def reload!
+      config.backend.reload!
+    end
+
+    # Translates, pluralizes and interpolates a given key using a given locale,
+    # scope, and default, as well as interpolation values.
+    #
+    # *LOOKUP*
+    #
+    # Translation data is organized as a nested hash using the upper-level keys
+    # as namespaces. <em>E.g.</em>, ActionView ships with the translation:
+    # <tt>:date => {:formats => {:short => "%b %d"}}</tt>.
+    #
+    # Translations can be looked up at any level of this hash using the key argument
+    # and the scope option. <em>E.g.</em>, in this example <tt>I18n.t :date</tt>
+    # returns the whole translations hash <tt>{:formats => {:short => "%b %d"}}</tt>.
+    #
+    # Key can be either a single key or a dot-separated key (both Strings and Symbols
+    # work). <em>E.g.</em>, the short format can be looked up using both:
+    #   I18n.t 'date.formats.short'
+    #   I18n.t :'date.formats.short'
+    #
+    # Scope can be either a single key, a dot-separated key or an array of keys
+    # or dot-separated keys. Keys and scopes can be combined freely. So these
+    # examples will all look up the same short date format:
+    #   I18n.t 'date.formats.short'
+    #   I18n.t 'formats.short', :scope => 'date'
+    #   I18n.t 'short', :scope => 'date.formats'
+    #   I18n.t 'short', :scope => %w(date formats)
+    #
+    # *INTERPOLATION*
+    #
+    # Translations can contain interpolation variables which will be replaced by
+    # values passed to #translate as part of the options hash, with the keys matching
+    # the interpolation variable names.
+    #
+    # <em>E.g.</em>, with a translation <tt>:foo => "foo %{bar}"</tt> the option
+    # value for the key +bar+ will be interpolated into the translation:
+    #   I18n.t :foo, :bar => 'baz' # => 'foo baz'
+    #
+    # *PLURALIZATION*
+    #
+    # Translation data can contain pluralized translations. Pluralized translations
+    # are arrays of singluar/plural versions of translations like <tt>['Foo', 'Foos']</tt>.
+    #
+    # Note that <tt>I18n::Backend::Simple</tt> only supports an algorithm for English
+    # pluralization rules. Other algorithms can be supported by custom backends.
+    #
+    # This returns the singular version of a pluralized translation:
+    #   I18n.t :foo, :count => 1 # => 'Foo'
+    #
+    # These both return the plural version of a pluralized translation:
+    #   I18n.t :foo, :count => 0 # => 'Foos'
+    #   I18n.t :foo, :count => 2 # => 'Foos'
+    #
+    # The <tt>:count</tt> option can be used both for pluralization and interpolation.
+    # <em>E.g.</em>, with the translation
+    # <tt>:foo => ['%{count} foo', '%{count} foos']</tt>, count will
+    # be interpolated to the pluralized translation:
+    #   I18n.t :foo, :count => 1 # => '1 foo'
+    #
+    # *DEFAULTS*
+    #
+    # This returns the translation for <tt>:foo</tt> or <tt>default</tt> if no translation was found:
+    #   I18n.t :foo, :default => 'default'
+    #
+    # This returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt> if no
+    # translation for <tt>:foo</tt> was found:
+    #   I18n.t :foo, :default => :bar
+    #
+    # Returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt>
+    # or <tt>default</tt> if no translations for <tt>:foo</tt> and <tt>:bar</tt> were found.
+    #   I18n.t :foo, :default => [:bar, 'default']
+    #
+    # *BULK LOOKUP*
+    #
+    # This returns an array with the translations for <tt>:foo</tt> and <tt>:bar</tt>.
+    #   I18n.t [:foo, :bar]
+    #
+    # Can be used with dot-separated nested keys:
+    #   I18n.t [:'baz.foo', :'baz.bar']
+    #
+    # Which is the same as using a scope option:
+    #   I18n.t [:foo, :bar], :scope => :baz
+    #
+    # *LAMBDAS*
+    #
+    # Both translations and defaults can be given as Ruby lambdas. Lambdas will be
+    # called and passed the key and options.
+    #
+    # E.g. assuming the key <tt>:salutation</tt> resolves to:
+    #   lambda { |key, options| options[:gender] == 'm' ? "Mr. %{options[:name]}" : "Mrs. %{options[:name]}" }
+    #
+    # Then <tt>I18n.t(:salutation, :gender => 'w', :name => 'Smith') will result in "Mrs. Smith".
+    #
+    # It is recommended to use/implement lambdas in an "idempotent" way. E.g. when
+    # a cache layer is put in front of I18n.translate it will generate a cache key
+    # from the argument values passed to #translate. Therefor your lambdas should
+    # always return the same translations/values per unique combination of argument
+    # values.
+    def translate(*args)
+      options  = args.last.is_a?(Hash) ? args.pop.dup : {}
+      key      = args.shift
+      backend  = config.backend
+      locale   = options.delete(:locale) || config.locale
+      handling = options.delete(:throw) && :throw || options.delete(:raise) && :raise # TODO deprecate :raise
+
+      enforce_available_locales!(locale)
+      raise I18n::ArgumentError if key.is_a?(String) && key.empty?
+
+      result = catch(:exception) do
+        if key.is_a?(Array)
+          key.map { |k| backend.translate(locale, k, options) }
+        else
+          backend.translate(locale, key, options)
+        end
+      end
+      result.is_a?(MissingTranslation) ? handle_exception(handling, result, locale, key, options) : result
+    end
+    alias :t :translate
+
+    # Wrapper for <tt>translate</tt> that adds <tt>:raise => true</tt>. With
+    # this option, if no translation is found, it will raise <tt>I18n::MissingTranslationData</tt>
+    def translate!(key, options={})
+      translate(key, options.merge(:raise => true))
+    end
+    alias :t! :translate!
+
+    # Returns true if a translation exists for a given key, otherwise returns false.
+    def exists?(key, locale = config.locale)
+      raise I18n::ArgumentError if key.is_a?(String) && key.empty?
+      config.backend.exists?(locale, key)
+    end
+
+    # Transliterates UTF-8 characters to ASCII. By default this method will
+    # transliterate only Latin strings to an ASCII approximation:
+    #
+    #    I18n.transliterate("Ærøskøbing")
+    #    # => "AEroskobing"
+    #
+    #    I18n.transliterate("日本語")
+    #    # => "???"
+    #
+    # It's also possible to add support for per-locale transliterations. I18n
+    # expects transliteration rules to be stored at
+    # <tt>i18n.transliterate.rule</tt>.
+    #
+    # Transliteration rules can either be a Hash or a Proc. Procs must accept a
+    # single string argument. Hash rules inherit the default transliteration
+    # rules, while Procs do not.
+    #
+    # *Examples*
+    #
+    # Setting a Hash in <locale>.yml:
+    #
+    #    i18n:
+    #      transliterate:
+    #        rule:
+    #          ü: "ue"
+    #          ö: "oe"
+    #
+    # Setting a Hash using Ruby:
+    #
+    #     store_translations(:de, :i18n => {
+    #       :transliterate => {
+    #         :rule => {
+    #           "ü" => "ue",
+    #           "ö" => "oe"
+    #         }
+    #       }
+    #     )
+    #
+    # Setting a Proc:
+    #
+    #     translit = lambda {|string| MyTransliterator.transliterate(string) }
+    #     store_translations(:xx, :i18n => {:transliterate => {:rule => translit})
+    #
+    # Transliterating strings:
+    #
+    #     I18n.locale = :en
+    #     I18n.transliterate("Jürgen") # => "Jurgen"
+    #     I18n.locale = :de
+    #     I18n.transliterate("Jürgen") # => "Juergen"
+    #     I18n.transliterate("Jürgen", :locale => :en) # => "Jurgen"
+    #     I18n.transliterate("Jürgen", :locale => :de) # => "Juergen"
+    def transliterate(*args)
+      options      = args.pop.dup if args.last.is_a?(Hash)
+      key          = args.shift
+      locale       = options && options.delete(:locale) || config.locale
+      handling     = options && (options.delete(:throw) && :throw || options.delete(:raise) && :raise)
+      replacement  = options && options.delete(:replacement)
+      enforce_available_locales!(locale)
+      config.backend.transliterate(locale, key, replacement)
+    rescue I18n::ArgumentError => exception
+      handle_exception(handling, exception, locale, key, options || {})
+    end
+
+    # Localizes certain objects, such as dates and numbers to local formatting.
+    def localize(object, options = nil)
+      options = options ? options.dup : {}
+      locale = options.delete(:locale) || config.locale
+      format = options.delete(:format) || :default
+      enforce_available_locales!(locale)
+      config.backend.localize(locale, object, format, options)
+    end
+    alias :l :localize
+
+    # Executes block with given I18n.locale set.
+    def with_locale(tmp_locale = nil)
+      if tmp_locale
+        current_locale = self.locale
+        self.locale    = tmp_locale
+      end
+      yield
+    ensure
+      self.locale = current_locale if tmp_locale
+    end
+
+    # Merges the given locale, key and scope into a single array of keys.
+    # Splits keys that contain dots into multiple keys. Makes sure all
+    # keys are Symbols.
+    def normalize_keys(locale, key, scope, separator = nil)
+      separator ||= I18n.default_separator
+
+      keys = []
+      keys.concat normalize_key(locale, separator)
+      keys.concat normalize_key(scope, separator)
+      keys.concat normalize_key(key, separator)
+      keys
+    end
+
+    # Returns true when the passed locale, which can be either a String or a
+    # Symbol, is in the list of available locales. Returns false otherwise.
+    def locale_available?(locale)
+      I18n.config.available_locales_set.include?(locale)
+    end
+
+    # Raises an InvalidLocale exception when the passed locale is not available.
+    def enforce_available_locales!(locale)
+      handle_enforce_available_locales_deprecation
+
+      if config.enforce_available_locales
+        raise I18n::InvalidLocale.new(locale) if !locale_available?(locale)
+      end
+    end
+
+  # making these private until Ruby 1.9.2 can send to protected methods again
+  # see http://redmine.ruby-lang.org/repositories/revision/ruby-19?rev=24280
+  private
+
+    # Any exceptions thrown in translate will be sent to the @@exception_handler
+    # which can be a Symbol, a Proc or any other Object unless they're forced to
+    # be raised or thrown (MissingTranslation).
+    #
+    # If exception_handler is a Symbol then it will simply be sent to I18n as
+    # a method call. A Proc will simply be called. In any other case the
+    # method #call will be called on the exception_handler object.
+    #
+    # Examples:
+    #
+    #   I18n.exception_handler = :default_exception_handler             # this is the default
+    #   I18n.default_exception_handler(exception, locale, key, options) # will be called like this
+    #
+    #   I18n.exception_handler = lambda { |*args| ... }                 # a lambda
+    #   I18n.exception_handler.call(exception, locale, key, options)    # will be called like this
+    #
+    #  I18n.exception_handler = I18nExceptionHandler.new                # an object
+    #  I18n.exception_handler.call(exception, locale, key, options)     # will be called like this
+    def handle_exception(handling, exception, locale, key, options)
+      case handling
+      when :raise
+        raise(exception.respond_to?(:to_exception) ? exception.to_exception : exception)
+      when :throw
+        throw :exception, exception
+      else
+        case handler = options[:exception_handler] || config.exception_handler
+        when Symbol
+          send(handler, exception, locale, key, options)
+        else
+          handler.call(exception, locale, key, options)
+        end
+      end
+    end
+
+    def normalize_key(key, separator)
+      normalized_key_cache[separator][key] ||=
+        case key
+        when Array
+          key.map { |k| normalize_key(k, separator) }.flatten
+        else
+          keys = key.to_s.split(separator)
+          keys.delete('')
+          keys.map! { |k| k.to_sym }
+          keys
+        end
+    end
+
+    def normalized_key_cache
+      @normalized_key_cache ||= Hash.new { |h,k| h[k] = {} }
+    end
+
+    # DEPRECATED. Use I18n.normalize_keys instead.
+    def normalize_translation_keys(locale, key, scope, separator = nil)
+      puts "I18n.normalize_translation_keys is deprecated. Please use the class I18n.normalize_keys instead."
+      normalize_keys(locale, key, scope, separator)
+    end
+
+    # DEPRECATED. Please use the I18n::ExceptionHandler class instead.
+    def default_exception_handler(exception, locale, key, options)
+      puts "I18n.default_exception_handler is deprecated. Please use the class I18n::ExceptionHandler instead " +
+           "(an instance of which is set to I18n.exception_handler by default)."
+      exception.is_a?(MissingTranslation) ? exception.message : raise(exception)
+    end
+
+    def handle_enforce_available_locales_deprecation
+      if config.enforce_available_locales.nil? && !defined?(@unenforced_available_locales_deprecation)
+        $stderr.puts "[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message."
+        @unenforced_available_locales_deprecation = true
+      end
+    end
+  })
+end
diff --git a/app/server/vendor/i18n/lib/i18n/backend.rb b/app/server/vendor/i18n/lib/i18n/backend.rb
new file mode 100644
index 0000000..46ef054
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/backend.rb
@@ -0,0 +1,18 @@
+module I18n
+  module Backend
+    autoload :Base,                  'i18n/backend/base'
+    autoload :InterpolationCompiler, 'i18n/backend/interpolation_compiler'
+    autoload :Cache,                 'i18n/backend/cache'
+    autoload :Cascade,               'i18n/backend/cascade'
+    autoload :Chain,                 'i18n/backend/chain'
+    autoload :Fallbacks,             'i18n/backend/fallbacks'
+    autoload :Flatten,               'i18n/backend/flatten'
+    autoload :Gettext,               'i18n/backend/gettext'
+    autoload :KeyValue,              'i18n/backend/key_value'
+    autoload :Memoize,               'i18n/backend/memoize'
+    autoload :Metadata,              'i18n/backend/metadata'
+    autoload :Pluralization,         'i18n/backend/pluralization'
+    autoload :Simple,                'i18n/backend/simple'
+    autoload :Transliterator,        'i18n/backend/transliterator'
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/backend/base.rb b/app/server/vendor/i18n/lib/i18n/backend/base.rb
new file mode 100644
index 0000000..4a823bc
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/backend/base.rb
@@ -0,0 +1,190 @@
+require 'yaml'
+require 'i18n/core_ext/hash'
+require 'i18n/core_ext/kernel/suppress_warnings'
+
+module I18n
+  module Backend
+    module Base
+      include I18n::Backend::Transliterator
+
+      # Accepts a list of paths to translation files. Loads translations from
+      # plain Ruby (*.rb) or YAML files (*.yml). See #load_rb and #load_yml
+      # for details.
+      def load_translations(*filenames)
+        filenames = I18n.load_path if filenames.empty?
+        filenames.flatten.each { |filename| load_file(filename) }
+      end
+
+      # This method receives a locale, a data hash and options for storing translations.
+      # Should be implemented
+      def store_translations(locale, data, options = {})
+        raise NotImplementedError
+      end
+
+      def translate(locale, key, options = {})
+        raise InvalidLocale.new(locale) unless locale
+        entry = key && lookup(locale, key, options[:scope], options)
+
+        if options.empty?
+          entry = resolve(locale, key, entry, options)
+        else
+          count, default = options.values_at(:count, :default)
+          values = options.except(*RESERVED_KEYS)
+          entry = entry.nil? && default ?
+            default(locale, key, default, options) : resolve(locale, key, entry, options)
+        end
+
+        throw(:exception, I18n::MissingTranslation.new(locale, key, options)) if entry.nil?
+        entry = entry.dup if entry.is_a?(String)
+
+        entry = pluralize(locale, entry, count) if count
+        entry = interpolate(locale, entry, values) if values
+        entry
+      end
+
+      def exists?(locale, key)
+        lookup(locale, key) != nil
+      end
+
+      # Acts the same as +strftime+, but uses a localized version of the
+      # format string. Takes a key from the date/time formats translations as
+      # a format argument (<em>e.g.</em>, <tt>:short</tt> in <tt>:'date.formats'</tt>).
+      def localize(locale, object, format = :default, options = {})
+        raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime)
+
+        if Symbol === format
+          key  = format
+          type = object.respond_to?(:sec) ? 'time' : 'date'
+          options = options.merge(:raise => true, :object => object, :locale => locale)
+          format  = I18n.t(:"#{type}.formats.#{key}", options)
+        end
+
+        # format = resolve(locale, object, format, options)
+        format = format.to_s.gsub(/%[aAbBpP]/) do |match|
+          case match
+          when '%a' then I18n.t(:"date.abbr_day_names",                  :locale => locale, :format => format)[object.wday]
+          when '%A' then I18n.t(:"date.day_names",                       :locale => locale, :format => format)[object.wday]
+          when '%b' then I18n.t(:"date.abbr_month_names",                :locale => locale, :format => format)[object.mon]
+          when '%B' then I18n.t(:"date.month_names",                     :locale => locale, :format => format)[object.mon]
+          when '%p' then I18n.t(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format).upcase if object.respond_to? :hour
+          when '%P' then I18n.t(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format).downcase if object.respond_to? :hour
+          end
+        end
+
+        object.strftime(format)
+      end
+
+      # Returns an array of locales for which translations are available
+      # ignoring the reserved translation meta data key :i18n.
+      def available_locales
+        raise NotImplementedError
+      end
+
+      def reload!
+        @skip_syntax_deprecation = false
+      end
+
+      protected
+
+        # The method which actually looks up for the translation in the store.
+        def lookup(locale, key, scope = [], options = {})
+          raise NotImplementedError
+        end
+
+        # Evaluates defaults.
+        # If given subject is an Array, it walks the array and returns the
+        # first translation that can be resolved. Otherwise it tries to resolve
+        # the translation directly.
+        def default(locale, object, subject, options = {})
+          options = options.dup.reject { |key, value| key == :default }
+          case subject
+          when Array
+            subject.each do |item|
+              result = resolve(locale, object, item, options) and return result
+            end and nil
+          else
+            resolve(locale, object, subject, options)
+          end
+        end
+
+        # Resolves a translation.
+        # If the given subject is a Symbol, it will be translated with the
+        # given options. If it is a Proc then it will be evaluated. All other
+        # subjects will be returned directly.
+        def resolve(locale, object, subject, options = {})
+          return subject if options[:resolve] == false
+          result = catch(:exception) do
+            case subject
+            when Symbol
+              I18n.translate(subject, options.merge(:locale => locale, :throw => true))
+            when Proc
+              date_or_time = options.delete(:object) || object
+              resolve(locale, object, subject.call(date_or_time, options))
+            else
+              subject
+            end
+          end
+          result unless result.is_a?(MissingTranslation)
+        end
+
+        # Picks a translation from a pluralized mnemonic subkey according to English
+        # pluralization rules :
+        # - It will pick the :one subkey if count is equal to 1.
+        # - It will pick the :other subkey otherwise.
+        # - It will pick the :zero subkey in the special case where count is
+        #   equal to 0 and there is a :zero subkey present. This behaviour is
+        #   not stand with regards to the CLDR pluralization rules.
+        # Other backends can implement more flexible or complex pluralization rules.
+        def pluralize(locale, entry, count)
+          return entry unless entry.is_a?(Hash) && count
+
+          key = :zero if count == 0 && entry.has_key?(:zero)
+          key ||= count == 1 ? :one : :other
+          raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key)
+          entry[key]
+        end
+
+        # Interpolates values into a given string.
+        #
+        #   interpolate "file %{file} opened by %%{user}", :file => 'test.txt', :user => 'Mr. X'
+        #   # => "file test.txt opened by %{user}"
+        def interpolate(locale, string, values = {})
+          if string.is_a?(::String) && !values.empty?
+            I18n.interpolate(string, values)
+          else
+            string
+          end
+        end
+
+        # Loads a single translations file by delegating to #load_rb or
+        # #load_yml depending on the file extension and directly merges the
+        # data to the existing translations. Raises I18n::UnknownFileType
+        # for all other file extensions.
+        def load_file(filename)
+          type = File.extname(filename).tr('.', '').downcase
+          raise UnknownFileType.new(type, filename) unless respond_to?(:"load_#{type}", true)
+          data = send(:"load_#{type}", filename)
+          unless data.is_a?(Hash)
+            raise InvalidLocaleData.new(filename, 'expects it to return a hash, but does not')
+          end
+          data.each { |locale, d| store_translations(locale, d || {}) }
+        end
+
+        # Loads a plain Ruby translations file. eval'ing the file must yield
+        # a Hash containing translation data with locales as toplevel keys.
+        def load_rb(filename)
+          eval(IO.read(filename), binding, filename)
+        end
+
+        # Loads a YAML translations file. The data must have locales as
+        # toplevel keys.
+        def load_yml(filename)
+          begin
+            YAML.load_file(filename)
+          rescue TypeError, ScriptError, StandardError => e
+            raise InvalidLocaleData.new(filename, e.inspect)
+          end
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/backend/cache.rb b/app/server/vendor/i18n/lib/i18n/backend/cache.rb
new file mode 100644
index 0000000..3c456ff
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/backend/cache.rb
@@ -0,0 +1,96 @@
+# This module allows you to easily cache all responses from the backend - thus
+# speeding up the I18n aspects of your application quite a bit.
+#
+# To enable caching you can simply include the Cache module to the Simple
+# backend - or whatever other backend you are using:
+#
+#   I18n::Backend::Simple.send(:include, I18n::Backend::Cache)
+#
+# You will also need to set a cache store implementation that you want to use:
+#
+#   I18n.cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
+#
+# You can use any cache implementation you want that provides the same API as
+# ActiveSupport::Cache (only the methods #fetch and #write are being used).
+#
+# The cache_key implementation assumes that you only pass values to
+# I18n.translate that return a valid key from #hash (see
+# http://www.ruby-doc.org/core/classes/Object.html#M000337).
+#
+# If you use a lambda as a default value in your translation like this:
+#
+#   I18n.t(:"date.order", :default => lambda {[:month, :day, :year]})
+#
+# Then you will always have a cache miss, because each time this method
+# is called the lambda will have a different hash value. If you know
+# the result of the lambda is a constant as in the example above, then
+# to cache this you can make the lambda a constant, like this:
+#
+#   DEFAULT_DATE_ORDER = lambda {[:month, :day, :year]}
+#   ...
+#   I18n.t(:"date.order", :default => DEFAULT_DATE_ORDER)
+#
+# If the lambda may result in different values for each call then consider
+# also using the Memoize backend.
+#
+module I18n
+  class << self
+    @@cache_store = nil
+    @@cache_namespace = nil
+
+    def cache_store
+      @@cache_store
+    end
+
+    def cache_store=(store)
+      @@cache_store = store
+    end
+
+    def cache_namespace
+      @@cache_namespace
+    end
+
+    def cache_namespace=(namespace)
+      @@cache_namespace = namespace
+    end
+
+    def perform_caching?
+      !cache_store.nil?
+    end
+  end
+
+  module Backend
+    # TODO Should the cache be cleared if new translations are stored?
+    module Cache
+      def translate(locale, key, options = {})
+        I18n.perform_caching? ? fetch(cache_key(locale, key, options)) { super } : super
+      end
+
+      protected
+
+        def fetch(cache_key, &block)
+          result = _fetch(cache_key, &block)
+          throw(:exception, result) if result.is_a?(MissingTranslation)
+          result = result.dup if result.frozen? rescue result
+          result
+        end
+
+        def _fetch(cache_key, &block)
+          result = I18n.cache_store.read(cache_key) and return result
+          result = catch(:exception, &block)
+          I18n.cache_store.write(cache_key, result) unless result.is_a?(Proc)
+          result
+        end
+
+        def cache_key(locale, key, options)
+          # This assumes that only simple, native Ruby values are passed to I18n.translate.
+          "i18n/#{I18n.cache_namespace}/#{locale}/#{key.hash}/#{USE_INSPECT_HASH ? options.inspect.hash : options.hash}"
+        end
+
+      private
+        # In Ruby < 1.9 the following is true: { :foo => 1, :bar => 2 }.hash == { :foo => 2, :bar => 1 }.hash
+        # Therefore we must use the hash of the inspect string instead to avoid cache key colisions.
+        USE_INSPECT_HASH = RUBY_VERSION <= "1.9"
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/backend/cascade.rb b/app/server/vendor/i18n/lib/i18n/backend/cascade.rb
new file mode 100644
index 0000000..d8fb1cf
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/backend/cascade.rb
@@ -0,0 +1,54 @@
+# The Cascade module adds the ability to do cascading lookups to backends that
+# are compatible to the Simple backend.
+#
+# By cascading lookups we mean that for any key that can not be found the
+# Cascade module strips one segment off the scope part of the key and then
+# tries to look up the key in that scope.
+#
+# E.g. when a lookup for the key :"foo.bar.baz" does not yield a result then
+# the segment :bar will be stripped off the scope part :"foo.bar" and the new
+# scope :foo will be used to look up the key :baz. If that does not succeed
+# then the remaining scope segment :foo will be omitted, too, and again the
+# key :baz will be looked up (now with no scope).
+#
+# To enable a cascading lookup one passes the :cascade option:
+#
+#   I18n.t(:'foo.bar.baz', :cascade => true)
+#
+# This will return the first translation found for :"foo.bar.baz", :"foo.baz"
+# or :baz in this order.
+#
+# The cascading lookup takes precedence over resolving any given defaults.
+# I.e. defaults will kick in after the cascading lookups haven't succeeded.
+#
+# This behavior is useful for libraries like ActiveRecord validations where
+# the library wants to give users a bunch of more or less fine-grained options
+# of scopes for a particular key.
+#
+# Thanks to Clemens Kofler for the initial idea and implementation! See
+# http://github.com/clemens/i18n-cascading-backend
+
+module I18n
+  module Backend
+    module Cascade
+      def lookup(locale, key, scope = [], options = {})
+        return super unless cascade = options[:cascade]
+
+        cascade   = { :step => 1 } unless cascade.is_a?(Hash)
+        step      = cascade[:step]   || 1
+        offset    = cascade[:offset] || 1
+        separator = options[:separator] || I18n.default_separator
+        skip_root = cascade.has_key?(:skip_root) ? cascade[:skip_root] : true
+
+        scope = I18n.normalize_keys(nil, key, scope, separator)
+        key   = (scope.slice!(-offset, offset) || []).join(separator)
+
+        begin
+          result = super
+          return result unless result.nil?
+          scope = scope.dup
+        end while (!scope.empty? || !skip_root) && scope.slice!(-step, step)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/backend/chain.rb b/app/server/vendor/i18n/lib/i18n/backend/chain.rb
new file mode 100644
index 0000000..cb6ad43
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/backend/chain.rb
@@ -0,0 +1,83 @@
+module I18n
+  module Backend
+    # Backend that chains multiple other backends and checks each of them when
+    # a translation needs to be looked up. This is useful when you want to use
+    # standard translations with a Simple backend but store custom application
+    # translations in a database or other backends.
+    #
+    # To use the Chain backend instantiate it and set it to the I18n module.
+    # You can add chained backends through the initializer or backends
+    # accessor:
+    #
+    #   # preserves the existing Simple backend set to I18n.backend
+    #   I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)
+    #
+    # The implementation assumes that all backends added to the Chain implement
+    # a lookup method with the same API as Simple backend does.
+    class Chain
+      module Implementation
+        include Base
+
+        attr_accessor :backends
+
+        def initialize(*backends)
+          self.backends = backends
+        end
+
+        def reload!
+          backends.each { |backend| backend.reload! }
+        end
+
+        def store_translations(locale, data, options = {})
+          backends.first.store_translations(locale, data, options)
+        end
+
+        def available_locales
+          backends.map { |backend| backend.available_locales }.flatten.uniq
+        end
+
+        def translate(locale, key, default_options = {})
+          namespace = nil
+          options = default_options.except(:default)
+
+          backends.each do |backend|
+            catch(:exception) do
+              options = default_options if backend == backends.last
+              translation = backend.translate(locale, key, options)
+              if namespace_lookup?(translation, options)
+                namespace = translation.merge(namespace || {})
+              elsif !translation.nil?
+                return translation
+              end
+            end
+          end
+
+          return namespace if namespace
+          throw(:exception, I18n::MissingTranslation.new(locale, key, options))
+        end
+
+        def exists?(locale, key)
+          backends.any? do |backend|
+            backend.exists?(locale, key)
+          end
+        end
+
+        def localize(locale, object, format = :default, options = {})
+          backends.each do |backend|
+            catch(:exception) do
+              result = backend.localize(locale, object, format, options) and return result
+            end
+          end
+          throw(:exception, I18n::MissingTranslation.new(locale, format, options))
+        end
+
+        protected
+          def namespace_lookup?(result, options)
+            result.is_a?(Hash) && !options.has_key?(:count)
+          end
+      end
+
+      include Implementation
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/backend/fallbacks.rb b/app/server/vendor/i18n/lib/i18n/backend/fallbacks.rb
new file mode 100644
index 0000000..d74b800
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/backend/fallbacks.rb
@@ -0,0 +1,69 @@
+# I18n locale fallbacks are useful when you want your application to use
+# translations from other locales when translations for the current locale are
+# missing. E.g. you might want to use :en translations when translations in
+# your applications main locale :de are missing.
+#
+# To enable locale fallbacks you can simply include the Fallbacks module to
+# the Simple backend - or whatever other backend you are using:
+#
+#   I18n::Backend::Simple.include(I18n::Backend::Fallbacks)
+module I18n
+  @@fallbacks = nil
+
+  class << self
+    # Returns the current fallbacks implementation. Defaults to +I18n::Locale::Fallbacks+.
+    def fallbacks
+      @@fallbacks ||= I18n::Locale::Fallbacks.new
+    end
+
+    # Sets the current fallbacks implementation. Use this to set a different fallbacks implementation.
+    def fallbacks=(fallbacks)
+      @@fallbacks = fallbacks
+    end
+  end
+
+  module Backend
+    module Fallbacks
+      # Overwrites the Base backend translate method so that it will try each
+      # locale given by I18n.fallbacks for the given locale. E.g. for the
+      # locale :"de-DE" it might try the locales :"de-DE", :de and :en
+      # (depends on the fallbacks implementation) until it finds a result with
+      # the given options. If it does not find any result for any of the
+      # locales it will then throw MissingTranslation as usual.
+      #
+      # The default option takes precedence over fallback locales only when
+      # it's a Symbol. When the default contains a String, Proc or Hash
+      # it is evaluated last after all the fallback locales have been tried.
+      def translate(locale, key, options = {})
+        return super if options[:fallback]
+        default = extract_non_symbol_default!(options) if options[:default]
+
+        options[:fallback] = true
+        I18n.fallbacks[locale].each do |fallback|
+          begin
+            catch(:exception) do
+              result = super(fallback, key, options)
+              return result unless result.nil?
+            end
+          rescue I18n::InvalidLocale
+            # we do nothing when the locale is invalid, as this is a fallback anyways.
+          end
+        end
+        options.delete(:fallback)
+
+        return super(locale, nil, options.merge(:default => default)) if default
+        throw(:exception, I18n::MissingTranslation.new(locale, key, options))
+      end
+
+      def extract_non_symbol_default!(options)
+        defaults = [options[:default]].flatten
+        first_non_symbol_default = defaults.detect{|default| !default.is_a?(Symbol)}
+        if first_non_symbol_default
+          options[:default] = defaults[0, defaults.index(first_non_symbol_default)]
+        end
+        return first_non_symbol_default
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/backend/flatten.rb b/app/server/vendor/i18n/lib/i18n/backend/flatten.rb
new file mode 100644
index 0000000..c23f7c1
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/backend/flatten.rb
@@ -0,0 +1,113 @@
+module I18n
+  module Backend
+    # This module contains several helpers to assist flattening translations.
+    # You may want to flatten translations for:
+    #
+    #   1) speed up lookups, as in the Memoize backend;
+    #   2) In case you want to store translations in a data store, as in ActiveRecord backend;
+    #
+    # You can check both backends above for some examples.
+    # This module also keeps all links in a hash so they can be properly resolved when flattened.
+    module Flatten
+      SEPARATOR_ESCAPE_CHAR = "\001"
+      FLATTEN_SEPARATOR = "."
+
+      # normalize_keys the flatten way. This method is significantly faster
+      # and creates way less objects than the one at I18n.normalize_keys.
+      # It also handles escaping the translation keys.
+      def self.normalize_flat_keys(locale, key, scope, separator)
+        keys = [scope, key].flatten.compact
+        separator ||= I18n.default_separator
+
+        if separator != FLATTEN_SEPARATOR
+          keys.map! do |k|
+            k.to_s.tr("#{FLATTEN_SEPARATOR}#{separator}",
+              "#{SEPARATOR_ESCAPE_CHAR}#{FLATTEN_SEPARATOR}")
+          end
+        end
+
+        keys.join(".")
+      end
+
+      # Receives a string and escape the default separator.
+      def self.escape_default_separator(key) #:nodoc:
+        key.to_s.tr(FLATTEN_SEPARATOR, SEPARATOR_ESCAPE_CHAR)
+      end
+
+      # Shortcut to I18n::Backend::Flatten.normalize_flat_keys
+      # and then resolve_links.
+      def normalize_flat_keys(locale, key, scope, separator)
+        key = I18n::Backend::Flatten.normalize_flat_keys(locale, key, scope, separator)
+        resolve_link(locale, key)
+      end
+
+      # Store flattened links.
+      def links
+        @links ||= Hash.new { |h,k| h[k] = {} }
+      end
+
+      # Flatten keys for nested Hashes by chaining up keys:
+      #
+      #   >> { "a" => { "b" => { "c" => "d", "e" => "f" }, "g" => "h" }, "i" => "j"}.wind
+      #   => { "a.b.c" => "d", "a.b.e" => "f", "a.g" => "h", "i" => "j" }
+      #
+      def flatten_keys(hash, escape, prev_key=nil, &block)
+        hash.each_pair do |key, value|
+          key = escape_default_separator(key) if escape
+          curr_key = [prev_key, key].compact.join(FLATTEN_SEPARATOR).to_sym
+          yield curr_key, value
+          flatten_keys(value, escape, curr_key, &block) if value.is_a?(Hash)
+        end
+      end
+
+      # Receives a hash of translations (where the key is a locale and
+      # the value is another hash) and return a hash with all
+      # translations flattened.
+      #
+      # Nested hashes are included in the flattened hash just if subtree
+      # is true and Symbols are automatically stored as links.
+      def flatten_translations(locale, data, escape, subtree)
+        hash = {}
+        flatten_keys(data, escape) do |key, value|
+          if value.is_a?(Hash)
+            hash[key] = value if subtree
+          else
+            store_link(locale, key, value) if value.is_a?(Symbol)
+            hash[key] = value
+          end
+        end
+        hash
+      end
+
+      protected
+
+        def store_link(locale, key, link)
+          links[locale.to_sym][key.to_s] = link.to_s
+        end
+
+        def resolve_link(locale, key)
+          key, locale = key.to_s, locale.to_sym
+          links = self.links[locale]
+
+          if links.key?(key)
+            links[key]
+          elsif link = find_link(locale, key)
+            store_link(locale, key, key.gsub(*link))
+          else
+            key
+          end
+        end
+
+        def find_link(locale, key) #:nodoc:
+          links[locale].each do |from, to|
+            return [from, to] if key[0, from.length] == from
+          end && nil
+        end
+
+        def escape_default_separator(key) #:nodoc:
+          I18n::Backend::Flatten.escape_default_separator(key)
+        end
+
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/i18n/lib/i18n/backend/gettext.rb b/app/server/vendor/i18n/lib/i18n/backend/gettext.rb
new file mode 100644
index 0000000..c357a6d
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/backend/gettext.rb
@@ -0,0 +1,72 @@
+require 'i18n/gettext'
+require 'i18n/gettext/po_parser'
+
+# Experimental support for using Gettext po files to store translations.
+#
+# To use this you can simply include the module to the Simple backend - or
+# whatever other backend you are using.
+#
+#   I18n::Backend::Simple.include(I18n::Backend::Gettext)
+#
+# Now you should be able to include your Gettext translation (*.po) files to
+# the I18n.load_path so they're loaded to the backend and you can use them as
+# usual:
+#
+#  I18n.load_path += Dir["path/to/locales/*.po"]
+#
+# Following the Gettext convention this implementation expects that your
+# translation files are named by their locales. E.g. the file en.po would
+# contain the translations for the English locale.
+module I18n
+  module Backend
+    module Gettext
+      class PoData < Hash
+        def set_comment(msgid_or_sym, comment)
+          # ignore
+        end
+      end
+
+      protected
+        def load_po(filename)
+          locale = ::File.basename(filename, '.po').to_sym
+          data = normalize(locale, parse(filename))
+          { locale => data }
+        end
+
+        def parse(filename)
+          GetText::PoParser.new.parse(::File.read(filename), PoData.new)
+        end
+
+        def normalize(locale, data)
+          data.inject({}) do |result, (key, value)|
+            unless key.nil? || key.empty?
+              key = key.gsub(I18n::Gettext::CONTEXT_SEPARATOR, '|')
+              key, value = normalize_pluralization(locale, key, value) if key.index("\000")
+
+              parts = key.split('|').reverse
+              normalized = parts.inject({}) do |_normalized, part|
+                { part => _normalized.empty? ? value : _normalized }
+              end
+
+              result.deep_merge!(normalized)
+            end
+            result
+          end
+        end
+
+        def normalize_pluralization(locale, key, value)
+          # FIXME po_parser includes \000 chars that can not be turned into Symbols
+          key = key.gsub("\000", I18n::Gettext::PLURAL_SEPARATOR).split(I18n::Gettext::PLURAL_SEPARATOR).first
+
+          keys = I18n::Gettext.plural_keys(locale)
+          values = value.split("\000")
+          raise "invalid number of plurals: #{values.size}, keys: #{keys.inspect} on #{locale} locale for msgid #{key.inspect} with values #{values.inspect}" if values.size != keys.size
+
+          result = {}
+          values.each_with_index { |_value, ix| result[keys[ix]] = _value }
+          [key, result]
+        end
+
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/backend/interpolation_compiler.rb b/app/server/vendor/i18n/lib/i18n/backend/interpolation_compiler.rb
new file mode 100644
index 0000000..c544070
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/backend/interpolation_compiler.rb
@@ -0,0 +1,121 @@
+# The InterpolationCompiler module contains optimizations that can tremendously
+# speed up the interpolation process on the Simple backend.
+#
+# It works by defining a pre-compiled method on stored translation Strings that
+# already bring all the knowledge about contained interpolation variables etc.
+# so that the actual recurring interpolation will be very fast.
+#
+# To enable pre-compiled interpolations you can simply include the
+# InterpolationCompiler module to the Simple backend:
+#
+#   I18n::Backend::Simple.include(I18n::Backend::InterpolationCompiler)
+#
+# Note that InterpolationCompiler does not yield meaningful results and consequently
+# should not be used with Ruby 1.9 (YARV) but improves performance everywhere else
+# (jRuby, Rubinius and 1.8.7).
+module I18n
+  module Backend
+    module InterpolationCompiler
+      module Compiler
+        extend self
+
+        TOKENIZER                    = /(%%\{[^\}]+\}|%\{[^\}]+\})/
+        INTERPOLATION_SYNTAX_PATTERN = /(%)?(%\{([^\}]+)\})/
+
+        def compile_if_an_interpolation(string)
+          if interpolated_str?(string)
+            string.instance_eval <<-RUBY_EVAL, __FILE__, __LINE__
+              def i18n_interpolate(v = {})
+                "#{compiled_interpolation_body(string)}"
+              end
+            RUBY_EVAL
+          end
+
+          string
+        end
+
+        def interpolated_str?(str)
+          str.kind_of?(::String) && str =~ INTERPOLATION_SYNTAX_PATTERN
+        end
+
+        protected
+        # tokenize("foo %{bar} baz %%{buz}") # => ["foo ", "%{bar}", " baz ", "%%{buz}"]
+        def tokenize(str)
+          str.split(TOKENIZER)
+        end
+
+        def compiled_interpolation_body(str)
+          tokenize(str).map do |token|
+            (matchdata = token.match(INTERPOLATION_SYNTAX_PATTERN)) ? handle_interpolation_token(token, matchdata) : escape_plain_str(token)
+          end.join
+        end
+
+        def handle_interpolation_token(interpolation, matchdata)
+          escaped, pattern, key = matchdata.values_at(1, 2, 3)
+          escaped ? pattern : compile_interpolation_token(key.to_sym)
+        end
+
+        def compile_interpolation_token(key)
+          "\#{#{interpolate_or_raise_missing(key)}}"
+        end
+
+        def interpolate_or_raise_missing(key)
+          escaped_key = escape_key_sym(key)
+          RESERVED_KEYS.include?(key) ? reserved_key(escaped_key) : interpolate_key(escaped_key)
+        end
+
+        def interpolate_key(key)
+          [direct_key(key), nil_key(key), missing_key(key)].join('||')
+        end
+
+        def direct_key(key)
+          "((t = v[#{key}]) && t.respond_to?(:call) ? t.call : t)"
+        end
+
+        def nil_key(key)
+          "(v.has_key?(#{key}) && '')"
+        end
+
+        def missing_key(key)
+          "I18n.config.missing_interpolation_argument_handler.call(#{key}, v, self)"
+        end
+
+        def reserved_key(key)
+          "raise(ReservedInterpolationKey.new(#{key}, self))"
+        end
+
+        def escape_plain_str(str)
+          str.gsub(/"|\\|#/) {|x| "\\#{x}"}
+        end
+
+        def escape_key_sym(key)
+          # rely on Ruby to do all the hard work :)
+          key.to_sym.inspect
+        end
+      end
+
+      def interpolate(locale, string, values)
+        if string.respond_to?(:i18n_interpolate)
+          string.i18n_interpolate(values)
+        elsif values
+          super
+        else
+          string
+        end
+      end
+
+      def store_translations(locale, data, options = {})
+        compile_all_strings_in(data)
+        super
+      end
+
+      protected
+      def compile_all_strings_in(data)
+        data.each_value do |value|
+          Compiler.compile_if_an_interpolation(value)
+          compile_all_strings_in(value) if value.kind_of?(Hash)
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/backend/key_value.rb b/app/server/vendor/i18n/lib/i18n/backend/key_value.rb
new file mode 100644
index 0000000..df80718
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/backend/key_value.rb
@@ -0,0 +1,101 @@
+require 'i18n/backend/base'
+require 'active_support/json'
+require 'active_support/ordered_hash' # active_support/json/encoding uses ActiveSupport::OrderedHash but does not require it
+
+module I18n
+  module Backend
+    # This is a basic backend for key value stores. It receives on
+    # initialization the store, which should respond to three methods:
+    #
+    # * store#[](key)         - Used to get a value
+    # * store#[]=(key, value) - Used to set a value
+    # * store#keys            - Used to get all keys
+    #
+    # Since these stores only supports string, all values are converted
+    # to JSON before being stored, allowing it to also store booleans,
+    # hashes and arrays. However, this store does not support Procs.
+    #
+    # As the ActiveRecord backend, Symbols are just supported when loading
+    # translations from the filesystem or through explicit store translations.
+    #
+    # Also, avoid calling I18n.available_locales since it's a somehow
+    # expensive operation in most stores.
+    #
+    # == Example
+    #
+    # To setup I18n to use TokyoCabinet in memory is quite straightforward:
+    #
+    #   require 'rufus/tokyo/cabinet' # gem install rufus-tokyo
+    #   I18n.backend = I18n::Backend::KeyValue.new(Rufus::Tokyo::Cabinet.new('*'))
+    #
+    # == Performance
+    #
+    # You may make this backend even faster by including the Memoize module.
+    # However, notice that you should properly clear the cache if you change
+    # values directly in the key-store.
+    #
+    # == Subtrees
+    #
+    # In most backends, you are allowed to retrieve part of a translation tree:
+    #
+    #   I18n.backend.store_translations :en, :foo => { :bar => :baz }
+    #   I18n.t "foo" #=> { :bar => :baz }
+    #
+    # This backend supports this feature by default, but it slows down the storage
+    # of new data considerably and makes hard to delete entries. That said, you are
+    # allowed to disable the storage of subtrees on initialization:
+    #
+    #   I18n::Backend::KeyValue.new(@store, false)
+    #
+    # This is useful if you are using a KeyValue backend chained to a Simple backend.
+    class KeyValue
+      module Implementation
+        attr_accessor :store
+
+        include Base, Flatten
+
+        def initialize(store, subtrees=true)
+          @store, @subtrees = store, subtrees
+        end
+
+        def store_translations(locale, data, options = {})
+          escape = options.fetch(:escape, true)
+          flatten_translations(locale, data, escape, @subtrees).each do |key, value|
+            key = "#{locale}.#{key}"
+
+            case value
+            when Hash
+              if @subtrees && (old_value = @store[key])
+                old_value = ActiveSupport::JSON.decode(old_value)
+                value = old_value.deep_symbolize_keys.deep_merge!(value) if old_value.is_a?(Hash)
+              end
+            when Proc
+              raise "Key-value stores cannot handle procs"
+            end
+
+            @store[key] = ActiveSupport::JSON.encode(value) unless value.is_a?(Symbol)
+          end
+        end
+
+        def available_locales
+          locales = @store.keys.map { |k| k =~ /\./; $` }
+          locales.uniq!
+          locales.compact!
+          locales.map! { |k| k.to_sym }
+          locales
+        end
+
+      protected
+
+        def lookup(locale, key, scope = [], options = {})
+          key   = normalize_flat_keys(locale, key, scope, options[:separator])
+          value = @store["#{locale}.#{key}"]
+          value = ActiveSupport::JSON.decode(value) if value
+          value.is_a?(Hash) ? value.deep_symbolize_keys : value
+        end
+      end
+
+      include Implementation
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/backend/memoize.rb b/app/server/vendor/i18n/lib/i18n/backend/memoize.rb
new file mode 100644
index 0000000..ae9801f
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/backend/memoize.rb
@@ -0,0 +1,46 @@
+# Memoize module simply memoizes the values returned by lookup using
+# a flat hash and can tremendously speed up the lookup process in a backend.
+#
+# To enable it you can simply include the Memoize module to your backend:
+#
+#   I18n::Backend::Simple.include(I18n::Backend::Memoize)
+#
+# Notice that it's the responsibility of the backend to define whenever the
+# cache should be cleaned.
+module I18n
+  module Backend
+    module Memoize
+      def available_locales
+        @memoized_locales ||= super
+      end
+
+      def store_translations(locale, data, options = {})
+        reset_memoizations!(locale)
+        super
+      end
+
+      def reload!
+        reset_memoizations!
+        super
+      end
+
+      protected
+
+        def lookup(locale, key, scope = nil, options = {})
+          flat_key  = I18n::Backend::Flatten.normalize_flat_keys(locale,
+            key, scope, options[:separator]).to_sym
+          flat_hash = memoized_lookup[locale.to_sym]
+          flat_hash.key?(flat_key) ? flat_hash[flat_key] : (flat_hash[flat_key] = super)
+        end
+
+        def memoized_lookup
+          @memoized_lookup ||= Hash.new { |h, k| h[k] = {} }
+        end
+
+        def reset_memoizations!(locale=nil)
+          @memoized_locales = nil
+          (locale ? memoized_lookup[locale.to_sym] : memoized_lookup).clear
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/backend/metadata.rb b/app/server/vendor/i18n/lib/i18n/backend/metadata.rb
new file mode 100644
index 0000000..52c0a29
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/backend/metadata.rb
@@ -0,0 +1,65 @@
+# I18n translation metadata is useful when you want to access information
+# about how a translation was looked up, pluralized or interpolated in
+# your application.
+#
+#   msg = I18n.t(:message, :default => 'Hi!', :scope => :foo)
+#   msg.translation_metadata
+#   # => { :key => :message, :scope => :foo, :default => 'Hi!' }
+#
+# If a :count option was passed to #translate it will be set to the metadata.
+# Likewise, if any interpolation variables were passed they will also be set.
+#
+# To enable translation metadata you can simply include the Metadata module
+# into the Simple backend class - or whatever other backend you are using:
+#
+#   I18n::Backend::Simple.include(I18n::Backend::Metadata)
+#
+module I18n
+  module Backend
+    module Metadata
+      class << self
+        def included(base)
+          Object.class_eval do
+            def translation_metadata
+              @translation_metadata ||= {}
+            end
+
+            def translation_metadata=(translation_metadata)
+              @translation_metadata = translation_metadata
+            end
+          end unless Object.method_defined?(:translation_metadata)
+        end
+      end
+
+      def translate(locale, key, options = {})
+        metadata = {
+          :locale    => locale,
+          :key       => key,
+          :scope     => options[:scope],
+          :default   => options[:default],
+          :separator => options[:separator],
+          :values    => options.reject { |name, value| RESERVED_KEYS.include?(name) }
+        }
+        with_metadata(metadata) { super }
+      end
+
+      def interpolate(locale, entry, values = {})
+        metadata = entry.translation_metadata.merge(:original => entry)
+        with_metadata(metadata) { super }
+      end
+
+      def pluralize(locale, entry, count)
+        with_metadata(:count => count) { super }
+      end
+
+      protected
+
+        def with_metadata(metadata, &block)
+          result = yield
+          result.translation_metadata = result.translation_metadata.merge(metadata) if result
+          result
+        end
+
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/backend/pluralization.rb b/app/server/vendor/i18n/lib/i18n/backend/pluralization.rb
new file mode 100644
index 0000000..c73a009
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/backend/pluralization.rb
@@ -0,0 +1,53 @@
+# I18n Pluralization are useful when you want your application to
+# customize pluralization rules.
+#
+# To enable locale specific pluralizations you can simply include the
+# Pluralization module to the Simple backend - or whatever other backend you
+# are using.
+#
+#   I18n::Backend::Simple.include(I18n::Backend::Pluralization)
+#
+# You also need to make sure to provide pluralization algorithms to the
+# backend, i.e. include them to your I18n.load_path accordingly.
+module I18n
+  module Backend
+    module Pluralization
+      # Overwrites the Base backend translate method so that it will check the
+      # translation meta data space (:i18n) for a locale specific pluralization
+      # rule and use it to pluralize the given entry. I.e. the library expects
+      # pluralization rules to be stored at I18n.t(:'i18n.plural.rule')
+      #
+      # Pluralization rules are expected to respond to #call(count) and
+      # return a pluralization key. Valid keys depend on the translation data
+      # hash (entry) but it is generally recommended to follow CLDR's style,
+      # i.e., return one of the keys :zero, :one, :few, :many, :other.
+      #
+      # The :zero key is always picked directly when count equals 0 AND the
+      # translation data has the key :zero. This way translators are free to
+      # either pick a special :zero translation even for languages where the
+      # pluralizer does not return a :zero key.
+      def pluralize(locale, entry, count)
+        return entry unless entry.is_a?(Hash) and count
+
+        pluralizer = pluralizer(locale)
+        if pluralizer.respond_to?(:call)
+          key = count == 0 && entry.has_key?(:zero) ? :zero : pluralizer.call(count)
+          raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key)
+          entry[key]
+        else
+          super
+        end
+      end
+
+      protected
+
+        def pluralizers
+          @pluralizers ||= {}
+        end
+
+        def pluralizer(locale)
+          pluralizers[locale] ||= I18n.t(:'i18n.plural.rule', :locale => locale, :resolve => false)
+        end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/backend/simple.rb b/app/server/vendor/i18n/lib/i18n/backend/simple.rb
new file mode 100644
index 0000000..95ffb6a
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/backend/simple.rb
@@ -0,0 +1,87 @@
+module I18n
+  module Backend
+    # A simple backend that reads translations from YAML files and stores them in
+    # an in-memory hash. Relies on the Base backend.
+    #
+    # The implementation is provided by a Implementation module allowing to easily
+    # extend Simple backend's behavior by including modules. E.g.:
+    #
+    # module I18n::Backend::Pluralization
+    #   def pluralize(*args)
+    #     # extended pluralization logic
+    #     super
+    #   end
+    # end
+    #
+    # I18n::Backend::Simple.include(I18n::Backend::Pluralization)
+    class Simple
+      (class << self; self; end).class_eval { public :include }
+
+      module Implementation
+        include Base
+
+        def initialized?
+          @initialized ||= false
+        end
+
+        # Stores translations for the given locale in memory.
+        # This uses a deep merge for the translations hash, so existing
+        # translations will be overwritten by new ones only at the deepest
+        # level of the hash.
+        def store_translations(locale, data, options = {})
+          locale = locale.to_sym
+          translations[locale] ||= {}
+          data = data.deep_symbolize_keys
+          translations[locale].deep_merge!(data)
+        end
+
+        # Get available locales from the translations hash
+        def available_locales
+          init_translations unless initialized?
+          translations.inject([]) do |locales, (locale, data)|
+            locales << locale unless (data.keys - [:i18n]).empty?
+            locales
+          end
+        end
+
+        # Clean up translations hash and set initialized to false on reload!
+        def reload!
+          @initialized = false
+          @translations = nil
+          super
+        end
+
+      protected
+
+        def init_translations
+          load_translations
+          @initialized = true
+        end
+
+        def translations
+          @translations ||= {}
+        end
+
+        # Looks up a translation from the translations hash. Returns nil if
+        # eiher key is nil, or locale, scope or key do not exist as a key in the
+        # nested translations hash. Splits keys or scopes containing dots
+        # into multiple keys, i.e. <tt>currency.format</tt> is regarded the same as
+        # <tt>%w(currency format)</tt>.
+        def lookup(locale, key, scope = [], options = {})
+          init_translations unless initialized?
+          keys = I18n.normalize_keys(locale, key, scope, options[:separator])
+
+          keys.inject(translations) do |result, _key|
+            _key = _key.to_sym
+            return nil unless result.is_a?(Hash) && result.has_key?(_key)
+            result = result[_key]
+            result = resolve(locale, _key, result, options.merge(:scope => nil)) if result.is_a?(Symbol)
+            result
+          end
+        end
+      end
+
+      include Implementation
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/backend/transliterator.rb b/app/server/vendor/i18n/lib/i18n/backend/transliterator.rb
new file mode 100644
index 0000000..2ee983d
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/backend/transliterator.rb
@@ -0,0 +1,99 @@
+# encoding: utf-8
+module I18n
+  module Backend
+    module Transliterator
+      DEFAULT_REPLACEMENT_CHAR = "?"
+
+      # Given a locale and a UTF-8 string, return the locale's ASCII
+      # approximation for the string.
+      def transliterate(locale, string, replacement = nil)
+        @transliterators ||= {}
+        @transliterators[locale] ||= Transliterator.get I18n.t(:'i18n.transliterate.rule',
+          :locale => locale, :resolve => false, :default => {})
+        @transliterators[locale].transliterate(string, replacement)
+      end
+
+      # Get a transliterator instance.
+      def self.get(rule = nil)
+        if !rule || rule.kind_of?(Hash)
+          HashTransliterator.new(rule)
+        elsif rule.kind_of? Proc
+          ProcTransliterator.new(rule)
+        else
+          raise I18n::ArgumentError, "Transliteration rule must be a proc or a hash."
+        end
+      end
+
+      # A transliterator which accepts a Proc as its transliteration rule.
+      class ProcTransliterator
+        def initialize(rule)
+          @rule = rule
+        end
+
+        def transliterate(string, replacement = nil)
+          @rule.call(string)
+        end
+      end
+
+      # A transliterator which accepts a Hash of characters as its translation
+      # rule.
+      class HashTransliterator
+        DEFAULT_APPROXIMATIONS = {
+          "À"=>"A", "Á"=>"A", "Â"=>"A", "Ã"=>"A", "Ä"=>"A", "Å"=>"A", "Æ"=>"AE",
+          "Ç"=>"C", "È"=>"E", "É"=>"E", "Ê"=>"E", "Ë"=>"E", "Ì"=>"I", "Í"=>"I",
+          "Î"=>"I", "Ï"=>"I", "Ð"=>"D", "Ñ"=>"N", "Ò"=>"O", "Ó"=>"O", "Ô"=>"O",
+          "Õ"=>"O", "Ö"=>"O", "×"=>"x", "Ø"=>"O", "Ù"=>"U", "Ú"=>"U", "Û"=>"U",
+          "Ü"=>"U", "Ý"=>"Y", "Þ"=>"Th", "ß"=>"ss", "à"=>"a", "á"=>"a", "â"=>"a",
+          "ã"=>"a", "ä"=>"a", "å"=>"a", "æ"=>"ae", "ç"=>"c", "è"=>"e", "é"=>"e",
+          "ê"=>"e", "ë"=>"e", "ì"=>"i", "í"=>"i", "î"=>"i", "ï"=>"i", "ð"=>"d",
+          "ñ"=>"n", "ò"=>"o", "ó"=>"o", "ô"=>"o", "õ"=>"o", "ö"=>"o", "ø"=>"o",
+          "ù"=>"u", "ú"=>"u", "û"=>"u", "ü"=>"u", "ý"=>"y", "þ"=>"th", "ÿ"=>"y",
+          "Ā"=>"A", "ā"=>"a", "Ă"=>"A", "ă"=>"a", "Ą"=>"A", "ą"=>"a", "Ć"=>"C",
+          "ć"=>"c", "Ĉ"=>"C", "ĉ"=>"c", "Ċ"=>"C", "ċ"=>"c", "Č"=>"C", "č"=>"c",
+          "Ď"=>"D", "ď"=>"d", "Đ"=>"D", "đ"=>"d", "Ē"=>"E", "ē"=>"e", "Ĕ"=>"E",
+          "ĕ"=>"e", "Ė"=>"E", "ė"=>"e", "Ę"=>"E", "ę"=>"e", "Ě"=>"E", "ě"=>"e",
+          "Ĝ"=>"G", "ĝ"=>"g", "Ğ"=>"G", "ğ"=>"g", "Ġ"=>"G", "ġ"=>"g", "Ģ"=>"G",
+          "ģ"=>"g", "Ĥ"=>"H", "ĥ"=>"h", "Ħ"=>"H", "ħ"=>"h", "Ĩ"=>"I", "ĩ"=>"i",
+          "Ī"=>"I", "ī"=>"i", "Ĭ"=>"I", "ĭ"=>"i", "Į"=>"I", "į"=>"i", "İ"=>"I",
+          "ı"=>"i", "IJ"=>"IJ", "ij"=>"ij", "Ĵ"=>"J", "ĵ"=>"j", "Ķ"=>"K", "ķ"=>"k",
+          "ĸ"=>"k", "Ĺ"=>"L", "ĺ"=>"l", "Ļ"=>"L", "ļ"=>"l", "Ľ"=>"L", "ľ"=>"l",
+          "Ŀ"=>"L", "ŀ"=>"l", "Ł"=>"L", "ł"=>"l", "Ń"=>"N", "ń"=>"n", "Ņ"=>"N",
+          "ņ"=>"n", "Ň"=>"N", "ň"=>"n", "ʼn"=>"'n", "Ŋ"=>"NG", "ŋ"=>"ng",
+          "Ō"=>"O", "ō"=>"o", "Ŏ"=>"O", "ŏ"=>"o", "Ő"=>"O", "ő"=>"o", "Œ"=>"OE",
+          "œ"=>"oe", "Ŕ"=>"R", "ŕ"=>"r", "Ŗ"=>"R", "ŗ"=>"r", "Ř"=>"R", "ř"=>"r",
+          "Ś"=>"S", "ś"=>"s", "Ŝ"=>"S", "ŝ"=>"s", "Ş"=>"S", "ş"=>"s", "Š"=>"S",
+          "š"=>"s", "Ţ"=>"T", "ţ"=>"t", "Ť"=>"T", "ť"=>"t", "Ŧ"=>"T", "ŧ"=>"t",
+          "Ũ"=>"U", "ũ"=>"u", "Ū"=>"U", "ū"=>"u", "Ŭ"=>"U", "ŭ"=>"u", "Ů"=>"U",
+          "ů"=>"u", "Ű"=>"U", "ű"=>"u", "Ų"=>"U", "ų"=>"u", "Ŵ"=>"W", "ŵ"=>"w",
+          "Ŷ"=>"Y", "ŷ"=>"y", "Ÿ"=>"Y", "Ź"=>"Z", "ź"=>"z", "Ż"=>"Z", "ż"=>"z",
+          "Ž"=>"Z", "ž"=>"z"
+        }.freeze
+
+        def initialize(rule = nil)
+          @rule = rule
+          add DEFAULT_APPROXIMATIONS.dup
+          add rule if rule
+        end
+
+        def transliterate(string, replacement = nil)
+          string.gsub(/[^\x00-\x7f]/u) do |char|
+            approximations[char] || replacement || DEFAULT_REPLACEMENT_CHAR
+          end
+        end
+
+        private
+
+        def approximations
+          @approximations ||= {}
+        end
+
+        # Add transliteration rules to the approximations hash.
+        def add(hash)
+          hash.each do |key, value|
+            approximations[key.to_s] = value.to_s
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/i18n/lib/i18n/config.rb b/app/server/vendor/i18n/lib/i18n/config.rb
new file mode 100644
index 0000000..b5750bd
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/config.rb
@@ -0,0 +1,130 @@
+module I18n
+  class Config
+    # The only configuration value that is not global and scoped to thread is :locale.
+    # It defaults to the default_locale.
+    def locale
+      @locale ||= default_locale
+    end
+
+    # Sets the current locale pseudo-globally, i.e. in the Thread.current hash.
+    def locale=(locale)
+      I18n.enforce_available_locales!(locale)
+      @locale = locale.to_sym rescue nil
+    end
+
+    # Returns the current backend. Defaults to +Backend::Simple+.
+    def backend
+      @@backend ||= Backend::Simple.new
+    end
+
+    # Sets the current backend. Used to set a custom backend.
+    def backend=(backend)
+      @@backend = backend
+    end
+
+    # Returns the current default locale. Defaults to :'en'
+    def default_locale
+      @@default_locale ||= :en
+    end
+
+    # Sets the current default locale. Used to set a custom default locale.
+    def default_locale=(locale)
+      I18n.enforce_available_locales!(locale)
+      @@default_locale = locale.to_sym rescue nil
+    end
+
+    # Returns an array of locales for which translations are available.
+    # Unless you explicitely set these through I18n.available_locales=
+    # the call will be delegated to the backend.
+    def available_locales
+      @@available_locales ||= nil
+      @@available_locales || backend.available_locales
+    end
+
+    # Caches the available locales list as both strings and symbols in a Set, so
+    # that we can have faster lookups to do the available locales enforce check.
+    def available_locales_set #:nodoc:
+      @@available_locales_set ||= available_locales.inject(Set.new) do |set, locale|
+        set << locale.to_s << locale.to_sym
+      end
+    end
+
+    # Sets the available locales.
+    def available_locales=(locales)
+      @@available_locales = Array(locales).map { |locale| locale.to_sym }
+      @@available_locales = nil if @@available_locales.empty?
+      @@available_locales_set = nil
+    end
+
+    # Returns the current default scope separator. Defaults to '.'
+    def default_separator
+      @@default_separator ||= '.'
+    end
+
+    # Sets the current default scope separator.
+    def default_separator=(separator)
+      @@default_separator = separator
+    end
+
+    # Return the current exception handler. Defaults to :default_exception_handler.
+    def exception_handler
+      @@exception_handler ||= ExceptionHandler.new
+    end
+
+    # Sets the exception handler.
+    def exception_handler=(exception_handler)
+      @@exception_handler = exception_handler
+    end
+
+    # Returns the current handler for situations when interpolation argument
+    # is missing. MissingInterpolationArgument will be raised by default.
+    def missing_interpolation_argument_handler
+      @@missing_interpolation_argument_handler ||= lambda do |missing_key, provided_hash, string|
+        raise MissingInterpolationArgument.new(missing_key, provided_hash, string)
+      end
+    end
+
+    # Sets the missing interpolation argument handler. It can be any
+    # object that responds to #call. The arguments that will be passed to #call
+    # are the same as for MissingInterpolationArgument initializer. Use +Proc.new+
+    # if you don't care about arity.
+    #
+    # == Example:
+    # You can supress raising an exception and return string instead:
+    #
+    #   I18n.config.missing_interpolation_argument_handler = Proc.new do |key|
+    #     "#{key} is missing"
+    #   end
+    def missing_interpolation_argument_handler=(exception_handler)
+      @@missing_interpolation_argument_handler = exception_handler
+    end
+
+    # Allow clients to register paths providing translation data sources. The
+    # backend defines acceptable sources.
+    #
+    # E.g. the provided SimpleBackend accepts a list of paths to translation
+    # files which are either named *.rb and contain plain Ruby Hashes or are
+    # named *.yml and contain YAML data. So for the SimpleBackend clients may
+    # register translation files like this:
+    #   I18n.load_path << 'path/to/locale/en.yml'
+    def load_path
+      @@load_path ||= []
+    end
+
+    # Sets the load path instance. Custom implementations are expected to
+    # behave like a Ruby Array.
+    def load_path=(load_path)
+      @@load_path = load_path
+    end
+
+    # [Deprecated] this will default to true in the future
+    # Defaults to nil so that it triggers the deprecation warning
+    def enforce_available_locales
+      defined?(@@enforce_available_locales) ? @@enforce_available_locales : nil
+    end
+
+    def enforce_available_locales=(enforce_available_locales)
+      @@enforce_available_locales = enforce_available_locales
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/core_ext/hash.rb b/app/server/vendor/i18n/lib/i18n/core_ext/hash.rb
new file mode 100644
index 0000000..f2a2422
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/core_ext/hash.rb
@@ -0,0 +1,29 @@
+class Hash
+  def slice(*keep_keys)
+    h = {}
+    keep_keys.each { |key| h[key] = fetch(key) }
+    h
+  end unless Hash.method_defined?(:slice)
+
+  def except(*less_keys)
+    slice(*keys - less_keys)
+  end unless Hash.method_defined?(:except)
+
+  def deep_symbolize_keys
+    inject({}) { |result, (key, value)|
+      value = value.deep_symbolize_keys if value.is_a?(Hash)
+      result[(key.to_sym rescue key) || key] = value
+      result
+    }
+  end unless Hash.method_defined?(:deep_symbolize_keys)
+
+  # deep_merge_hash! by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
+  MERGER = proc do |key, v1, v2|
+    Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2
+  end
+  
+  def deep_merge!(data)
+    merge!(data, &MERGER)
+  end unless Hash.method_defined?(:deep_merge!)
+end
+
diff --git a/app/server/vendor/i18n/lib/i18n/core_ext/kernel/suppress_warnings.rb b/app/server/vendor/i18n/lib/i18n/core_ext/kernel/suppress_warnings.rb
new file mode 100644
index 0000000..eec1435
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/core_ext/kernel/suppress_warnings.rb
@@ -0,0 +1,8 @@
+module Kernel
+  def suppress_warnings
+    original_verbosity, $VERBOSE = $VERBOSE, nil
+    yield
+  ensure
+    $VERBOSE = original_verbosity
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/core_ext/string/interpolate.rb b/app/server/vendor/i18n/lib/i18n/core_ext/string/interpolate.rb
new file mode 100644
index 0000000..56de8c0
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/core_ext/string/interpolate.rb
@@ -0,0 +1,105 @@
+# This backports the Ruby 1.9 String interpolation syntax to Ruby 1.8.
+#
+# This backport has been shipped with I18n for a number of versions. Meanwhile
+# Rails has started to rely on it and we are going to move it to ActiveSupport.
+# See https://rails.lighthouseapp.com/projects/8994/tickets/6013-move-19-string-interpolation-syntax-backport-from-i18n-to-activesupport
+#
+# Once the above patch has been applied to Rails the following code will be
+# removed from I18n.
+
+=begin
+  heavily based on Masao Mutoh's gettext String interpolation extension
+  http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb
+  Copyright (C) 2005-2009 Masao Mutoh
+  You may redistribute it and/or modify it under the same license terms as Ruby.
+=end
+
+begin
+  raise ArgumentError if ("a %{x}" % {:x=>'b'}) != 'a b'
+rescue ArgumentError
+  # KeyError is raised by String#% when the string contains a named placeholder
+  # that is not contained in the given arguments hash. Ruby 1.9 includes and
+  # raises this exception natively. We define it to mimic Ruby 1.9's behaviour
+  # in Ruby 1.8.x
+  class KeyError < IndexError
+    def initialize(message = nil)
+      super(message || "key not found")
+    end
+  end unless defined?(KeyError)
+
+  # Extension for String class. This feature is included in Ruby 1.9 or later but not occur TypeError.
+  #
+  # String#% method which accept "named argument". The translator can know
+  # the meaning of the msgids using "named argument" instead of %s/%d style.
+  class String
+    # For older ruby versions, such as ruby-1.8.5
+    alias :bytesize :size unless instance_methods.find {|m| m.to_s == 'bytesize'}
+    alias :interpolate_without_ruby_19_syntax :% # :nodoc:
+
+    INTERPOLATION_PATTERN = Regexp.union(
+      /%\{(\w+)\}/,                               # matches placeholders like "%{foo}"
+      /%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/  # matches placeholders like "%<foo>.d"
+    )
+
+    INTERPOLATION_PATTERN_WITH_ESCAPE = Regexp.union(
+      /%%/,
+      INTERPOLATION_PATTERN
+    )
+
+    # % uses self (i.e. the String) as a format specification and returns the
+    # result of applying it to the given arguments. In other words it interpolates
+    # the given arguments to the string according to the formats the string
+    # defines.
+    #
+    # There are three ways to use it:
+    #
+    # * Using a single argument or Array of arguments.
+    #
+    #   This is the default behaviour of the String class. See Kernel#sprintf for
+    #   more details about the format string.
+    #
+    #   Example:
+    #
+    #     "%d %s" % [1, "message"]
+    #     # => "1 message"
+    #
+    # * Using a Hash as an argument and unformatted, named placeholders.
+    #
+    #   When you pass a Hash as an argument and specify placeholders with %{foo}
+    #   it will interpret the hash values as named arguments.
+    #
+    #   Example:
+    #
+    #     "%{firstname}, %{lastname}" % {:firstname => "Masao", :lastname => "Mutoh"}
+    #     # => "Masao Mutoh"
+    #
+    # * Using a Hash as an argument and formatted, named placeholders.
+    #
+    #   When you pass a Hash as an argument and specify placeholders with %<foo>d
+    #   it will interpret the hash values as named arguments and format the value
+    #   according to the formatting instruction appended to the closing >.
+    #
+    #   Example:
+    #
+    #     "%<integer>d, %<float>.1f" % { :integer => 10, :float => 43.4 }
+    #     # => "10, 43.3"
+    def %(args)
+      if args.kind_of?(Hash)
+        dup.gsub(INTERPOLATION_PATTERN_WITH_ESCAPE) do |match|
+          if match == '%%'
+            '%'
+          else
+            key = ($1 || $2).to_sym
+            raise KeyError unless args.has_key?(key)
+            $3 ? sprintf("%#{$3}", args[key]) : args[key]
+          end
+        end
+      elsif self =~ INTERPOLATION_PATTERN
+        raise ArgumentError.new('one hash required')
+      else
+        result = gsub(/%([{<])/, '%%\1')
+        result.send :'interpolate_without_ruby_19_syntax', args
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/exceptions.rb b/app/server/vendor/i18n/lib/i18n/exceptions.rb
new file mode 100644
index 0000000..3e0b1c5
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/exceptions.rb
@@ -0,0 +1,128 @@
+require 'cgi'
+
+module I18n
+  # Handles exceptions raised in the backend. All exceptions except for
+  # MissingTranslationData exceptions are re-thrown. When a MissingTranslationData
+  # was caught the handler returns an error message string containing the key/scope.
+  # Note that the exception handler is not called when the option :throw was given.
+  class ExceptionHandler
+    include Module.new {
+      def call(exception, locale, key, options)
+        if exception.is_a?(MissingTranslation)
+          #
+          # TODO: this block is to be replaced by `exception.message` when
+          # rescue_format is removed
+          if options[:rescue_format] == :html
+            if !defined?(@rescue_format_deprecation)
+              $stderr.puts "[DEPRECATED] I18n's :recue_format option will be removed from a future release. All exception messages will be plain text. If you need the exception handler to return an html format please set or pass a custom exception handler."
+              @rescue_format_deprecation = true
+            end
+            exception.html_message
+          else
+            exception.message
+          end
+
+        elsif exception.is_a?(Exception)
+          raise exception
+        else
+          throw :exception, exception
+        end
+      end
+    }
+  end
+
+  class ArgumentError < ::ArgumentError; end
+
+  class InvalidLocale < ArgumentError
+    attr_reader :locale
+    def initialize(locale)
+      @locale = locale
+      super "#{locale.inspect} is not a valid locale"
+    end
+  end
+
+  class InvalidLocaleData < ArgumentError
+    attr_reader :filename
+    def initialize(filename, exception_message)
+      @filename, @exception_message = filename, exception_message
+      super "can not load translations from #{filename}: #{exception_message}"
+    end
+  end
+
+  class MissingTranslation
+    module Base
+      attr_reader :locale, :key, :options
+
+      def initialize(locale, key, options = nil)
+        @key, @locale, @options = key, locale, options.dup || {}
+        options.each { |k, v| self.options[k] = v.inspect if v.is_a?(Proc) }
+      end
+
+      def html_message
+        key  = CGI.escapeHTML titleize(keys.last)
+        path = CGI.escapeHTML keys.join('.')
+        %(<span class="translation_missing" title="translation missing: #{path}">#{key}</span>)
+      end
+
+      def keys
+        @keys ||= I18n.normalize_keys(locale, key, options[:scope]).tap do |keys|
+          keys << 'no key' if keys.size < 2
+        end
+      end
+
+      def message
+        "translation missing: #{keys.join('.')}"
+      end
+      alias :to_s :message
+
+      def to_exception
+        MissingTranslationData.new(locale, key, options)
+      end
+
+      protected
+
+      # TODO : remove when #html_message is removed
+      def titleize(key)
+        key.to_s.gsub('_', ' ').gsub(/\b('?[a-z])/) { $1.capitalize }
+      end
+    end
+
+    include Base
+  end
+
+  class MissingTranslationData < ArgumentError
+    include MissingTranslation::Base
+  end
+
+  class InvalidPluralizationData < ArgumentError
+    attr_reader :entry, :count
+    def initialize(entry, count)
+      @entry, @count = entry, count
+      super "translation data #{entry.inspect} can not be used with :count => #{count}"
+    end
+  end
+
+  class MissingInterpolationArgument < ArgumentError
+    attr_reader :key, :values, :string
+    def initialize(key, values, string)
+      @key, @values, @string = key, values, string
+      super "missing interpolation argument #{key.inspect} in #{string.inspect} (#{values.inspect} given)"
+    end
+  end
+
+  class ReservedInterpolationKey < ArgumentError
+    attr_reader :key, :string
+    def initialize(key, string)
+      @key, @string = key, string
+      super "reserved key #{key.inspect} used in #{string.inspect}"
+    end
+  end
+
+  class UnknownFileType < ArgumentError
+    attr_reader :type, :filename
+    def initialize(type, filename)
+      @type, @filename = type, filename
+      super "can not load translations from #{filename}, the file type #{type} is not known"
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/gettext.rb b/app/server/vendor/i18n/lib/i18n/gettext.rb
new file mode 100644
index 0000000..26a5d48
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/gettext.rb
@@ -0,0 +1,25 @@
+module I18n
+  module Gettext
+    PLURAL_SEPARATOR  = "\001"
+    CONTEXT_SEPARATOR = "\004"
+
+    autoload :Helpers, 'i18n/gettext/helpers'
+
+    @@plural_keys = { :en => [:one, :other] }
+
+    class << self
+      # returns an array of plural keys for the given locale so that we can
+      # convert from gettext's integer-index based style
+      # TODO move this information to the pluralization module
+      def plural_keys(locale)
+        @@plural_keys[locale] || @@plural_keys[:en]
+      end
+
+      def extract_scope(msgid, separator)
+        scope = msgid.to_s.split(separator)
+        msgid = scope.pop
+        [scope, msgid]
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/gettext/helpers.rb b/app/server/vendor/i18n/lib/i18n/gettext/helpers.rb
new file mode 100644
index 0000000..ea07d05
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/gettext/helpers.rb
@@ -0,0 +1,64 @@
+require 'i18n/gettext'
+
+module I18n
+  module Gettext
+    # Implements classical Gettext style accessors. To use this include the
+    # module to the global namespace or wherever you want to use it.
+    #
+    #   include I18n::Gettext::Helpers
+    module Helpers
+      def gettext(msgid, options = {})
+        I18n.t(msgid, { :default => msgid, :separator => '|' }.merge(options))
+      end
+      alias _ gettext
+
+      def sgettext(msgid, separator = '|')
+        scope, msgid = I18n::Gettext.extract_scope(msgid, separator)
+        I18n.t(msgid, :scope => scope, :default => msgid, :separator => separator)
+      end
+      alias s_ sgettext
+
+      def pgettext(msgctxt, msgid)
+        separator = I18n::Gettext::CONTEXT_SEPARATOR
+        sgettext([msgctxt, msgid].join(separator), separator)
+      end
+      alias p_ pgettext
+
+      def ngettext(msgid, msgid_plural, n = 1)
+        nsgettext(msgid, msgid_plural, n)
+      end
+      alias n_ ngettext
+
+      # Method signatures:
+      #   nsgettext('Fruits|apple', 'apples', 2)
+      #   nsgettext(['Fruits|apple', 'apples'], 2)
+      def nsgettext(msgid, msgid_plural, n = 1, separator = '|')
+        if msgid.is_a?(Array)
+          msgid, msgid_plural, n, separator = msgid[0], msgid[1], msgid_plural, n
+          separator = '|' unless separator.is_a?(::String)
+        end
+
+        scope, msgid = I18n::Gettext.extract_scope(msgid, separator)
+        default = { :one => msgid, :other => msgid_plural }
+        I18n.t(msgid, :default => default, :count => n, :scope => scope, :separator => separator)
+      end
+      alias ns_ nsgettext
+
+      # Method signatures:
+      #   npgettext('Fruits', 'apple', 'apples', 2)
+      #   npgettext('Fruits', ['apple', 'apples'], 2)
+      def npgettext(msgctxt, msgid, msgid_plural, n = 1)
+        separator = I18n::Gettext::CONTEXT_SEPARATOR
+
+        if msgid.is_a?(Array)
+          msgid_plural, msgid, n = msgid[1], [msgctxt, msgid[0]].join(separator), msgid_plural
+        else
+          msgid = [msgctxt, msgid].join(separator)
+        end
+
+        nsgettext(msgid, msgid_plural, n, separator)
+      end
+      alias np_ npgettext
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/gettext/po_parser.rb b/app/server/vendor/i18n/lib/i18n/gettext/po_parser.rb
new file mode 100644
index 0000000..547df6a
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/gettext/po_parser.rb
@@ -0,0 +1,329 @@
+=begin
+  poparser.rb - Generate a .mo
+
+  Copyright (C) 2003-2009 Masao Mutoh <mutoh at highway.ne.jp>
+
+  You may redistribute it and/or modify it under the same
+  license terms as Ruby.
+=end
+
+#MODIFIED
+# removed include GetText etc
+# added stub translation method _(x)
+require 'racc/parser'
+
+module GetText
+
+  class PoParser < Racc::Parser
+
+    def _(x)
+      x
+    end
+
+module_eval <<'..end src/poparser.ry modeval..id7a99570e05', 'src/poparser.ry', 108
+  def unescape(orig)
+    ret = orig.gsub(/\\n/, "\n")
+    ret.gsub!(/\\t/, "\t")
+    ret.gsub!(/\\r/, "\r")
+    ret.gsub!(/\\"/, "\"")
+    ret
+  end
+  
+  def parse(str, data, ignore_fuzzy = true)
+    @comments = []
+    @data = data
+    @fuzzy = false
+    @msgctxt = ""
+    $ignore_fuzzy = ignore_fuzzy
+
+    str.strip!
+    @q = []
+    until str.empty? do
+      case str
+      when /\A\s+/
+	str = $'
+      when /\Amsgctxt/
+	@q.push [:MSGCTXT, $&]
+	str = $'
+      when /\Amsgid_plural/
+	@q.push [:MSGID_PLURAL, $&]
+	str = $'
+      when /\Amsgid/
+	@q.push [:MSGID, $&]
+	str = $'
+      when /\Amsgstr/
+	@q.push [:MSGSTR, $&]
+	str = $'
+      when /\A\[(\d+)\]/
+	@q.push [:PLURAL_NUM, $1]
+	str = $'
+      when /\A\#~(.*)/
+	$stderr.print _("Warning: obsolete msgid exists.\n")
+	$stderr.print "         #{$&}\n"
+	@q.push [:COMMENT, $&]
+	str = $'
+      when /\A\#(.*)/
+	@q.push [:COMMENT, $&]
+	str = $'      
+      when /\A\"(.*)\"/
+	@q.push [:STRING, $1]
+	str = $'
+      else
+	#c = str[0,1]
+	#@q.push [:STRING, c]
+	str = str[1..-1]
+      end
+    end 
+    @q.push [false, '$end']
+    if $DEBUG
+      @q.each do |a,b|
+      puts "[#{a}, #{b}]"
+      end
+    end
+    @yydebug = true if $DEBUG
+    do_parse
+
+    if @comments.size > 0
+      @data.set_comment(:last, @comments.join("\n"))
+    end
+    @data
+  end
+  
+  def next_token
+    @q.shift
+  end
+
+  def on_message(msgid, msgstr)
+    if msgstr.size > 0
+      @data[msgid] = msgstr
+      @data.set_comment(msgid, @comments.join("\n"))
+    end
+    @comments.clear
+    @msgctxt = ""
+  end
+      
+  def on_comment(comment)
+    @fuzzy = true if (/fuzzy/ =~ comment)
+    @comments << comment
+  end 
+
+
+..end src/poparser.ry modeval..id7a99570e05
+
+##### racc 1.4.5 generates ###
+
+racc_reduce_table = [
+ 0, 0, :racc_error,
+ 0, 10, :_reduce_none,
+ 2, 10, :_reduce_none,
+ 2, 10, :_reduce_none,
+ 2, 10, :_reduce_none,
+ 2, 12, :_reduce_5,
+ 1, 13, :_reduce_none,
+ 1, 13, :_reduce_none,
+ 4, 15, :_reduce_8,
+ 5, 16, :_reduce_9,
+ 2, 17, :_reduce_10,
+ 1, 17, :_reduce_none,
+ 3, 18, :_reduce_12,
+ 1, 11, :_reduce_13,
+ 2, 14, :_reduce_14,
+ 1, 14, :_reduce_15 ]
+
+racc_reduce_n = 16
+
+racc_shift_n = 26
+
+racc_action_table = [
+     3,    13,     5,     7,     9,    15,    16,    17,    20,    17,
+    13,    17,    13,    13,    11,    17,    23,    20,    13,    17 ]
+
+racc_action_check = [
+     1,    16,     1,     1,     1,    12,    12,    12,    18,    18,
+     7,    14,    15,     9,     3,    19,    20,    21,    23,    25 ]
+
+racc_action_pointer = [
+   nil,     0,   nil,    14,   nil,   nil,   nil,     3,   nil,     6,
+   nil,   nil,     0,   nil,     4,     5,    -6,   nil,     2,     8,
+     8,    11,   nil,    11,   nil,    12 ]
+
+racc_action_default = [
+    -1,   -16,    -2,   -16,    -3,   -13,    -4,   -16,    -6,   -16,
+    -7,    26,   -16,   -15,    -5,   -16,   -16,   -14,   -16,    -8,
+   -16,    -9,   -11,   -16,   -10,   -12 ]
+
+racc_goto_table = [
+    12,    22,    14,     4,    24,     6,     2,     8,    18,    19,
+    10,    21,     1,   nil,   nil,   nil,    25 ]
+
+racc_goto_check = [
+     5,     9,     5,     3,     9,     4,     2,     6,     5,     5,
+     7,     8,     1,   nil,   nil,   nil,     5 ]
+
+racc_goto_pointer = [
+   nil,    12,     5,     2,     4,    -7,     6,     9,    -7,   -17 ]
+
+racc_goto_default = [
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil ]
+
+racc_token_table = {
+ false => 0,
+ Object.new => 1,
+ :COMMENT => 2,
+ :MSGID => 3,
+ :MSGCTXT => 4,
+ :MSGID_PLURAL => 5,
+ :MSGSTR => 6,
+ :STRING => 7,
+ :PLURAL_NUM => 8 }
+
+racc_use_result_var = true
+
+racc_nt_base = 9
+
+Racc_arg = [
+ racc_action_table,
+ racc_action_check,
+ racc_action_default,
+ racc_action_pointer,
+ racc_goto_table,
+ racc_goto_check,
+ racc_goto_default,
+ racc_goto_pointer,
+ racc_nt_base,
+ racc_reduce_table,
+ racc_token_table,
+ racc_shift_n,
+ racc_reduce_n,
+ racc_use_result_var ]
+
+Racc_token_to_s_table = [
+'$end',
+'error',
+'COMMENT',
+'MSGID',
+'MSGCTXT',
+'MSGID_PLURAL',
+'MSGSTR',
+'STRING',
+'PLURAL_NUM',
+'$start',
+'msgfmt',
+'comment',
+'msgctxt',
+'message',
+'string_list',
+'single_message',
+'plural_message',
+'msgstr_plural',
+'msgstr_plural_line']
+
+Racc_debug_parser = true
+
+##### racc system variables end #####
+
+ # reduce 0 omitted
+
+ # reduce 1 omitted
+
+ # reduce 2 omitted
+
+ # reduce 3 omitted
+
+ # reduce 4 omitted
+
+module_eval <<'.,.,', 'src/poparser.ry', 25
+  def _reduce_5( val, _values, result )
+    @msgctxt = unescape(val[1]) + "\004"
+   result
+  end
+.,.,
+
+ # reduce 6 omitted
+
+ # reduce 7 omitted
+
+module_eval <<'.,.,', 'src/poparser.ry', 48
+  def _reduce_8( val, _values, result )
+    if @fuzzy and $ignore_fuzzy 
+      if val[1] != ""
+        $stderr.print _("Warning: fuzzy message was ignored.\n")
+        $stderr.print "         msgid '#{val[1]}'\n"
+      else
+        on_message('', unescape(val[3]))
+      end
+      @fuzzy = false
+    else
+      on_message(@msgctxt + unescape(val[1]), unescape(val[3]))
+    end
+    result = ""
+   result
+  end
+.,.,
+
+module_eval <<'.,.,', 'src/poparser.ry', 65
+  def _reduce_9( val, _values, result )
+    if @fuzzy and $ignore_fuzzy
+      if val[1] != ""
+        $stderr.print _("Warning: fuzzy message was ignored.\n")
+        $stderr.print "msgid = '#{val[1]}\n"
+      else
+        on_message('', unescape(val[3]))
+      end
+      @fuzzy = false
+    else
+      on_message(@msgctxt + unescape(val[1]) + "\000" + unescape(val[3]), unescape(val[4]))
+    end
+    result = ""
+   result
+  end
+.,.,
+
+module_eval <<'.,.,', 'src/poparser.ry', 76
+  def _reduce_10( val, _values, result )
+    if val[0].size > 0
+      result = val[0] + "\000" + val[1]
+    else
+      result = ""
+    end
+   result
+  end
+.,.,
+
+ # reduce 11 omitted
+
+module_eval <<'.,.,', 'src/poparser.ry', 84
+  def _reduce_12( val, _values, result )
+    result = val[2]
+   result
+  end
+.,.,
+
+module_eval <<'.,.,', 'src/poparser.ry', 91
+  def _reduce_13( val, _values, result )
+    on_comment(val[0])
+   result
+  end
+.,.,
+
+module_eval <<'.,.,', 'src/poparser.ry', 99
+  def _reduce_14( val, _values, result )
+    result = val.delete_if{|item| item == ""}.join
+   result
+  end
+.,.,
+
+module_eval <<'.,.,', 'src/poparser.ry', 103
+  def _reduce_15( val, _values, result )
+    result = val[0]
+   result
+  end
+.,.,
+
+ def _reduce_none( val, _values, result )
+  result
+ end
+
+  end   # class PoParser
+
+end   # module GetText
diff --git a/app/server/vendor/i18n/lib/i18n/interpolate/ruby.rb b/app/server/vendor/i18n/lib/i18n/interpolate/ruby.rb
new file mode 100644
index 0000000..442677f
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/interpolate/ruby.rb
@@ -0,0 +1,37 @@
+# heavily based on Masao Mutoh's gettext String interpolation extension
+# http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb
+
+module I18n
+  INTERPOLATION_PATTERN = Regexp.union(
+    /%%/,
+    /%\{(\w+)\}/,                               # matches placeholders like "%{foo}"
+    /%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/  # matches placeholders like "%<foo>.d"
+  )
+
+  class << self
+    # Return String or raises MissingInterpolationArgument exception.
+    # Missing argument's logic is handled by I18n.config.missing_interpolation_argument_handler.
+    def interpolate(string, values)
+      raise ReservedInterpolationKey.new($1.to_sym, string) if string =~ RESERVED_KEYS_PATTERN
+      raise ArgumentError.new('Interpolation values must be a Hash.') unless values.kind_of?(Hash)
+      interpolate_hash(string, values)
+    end
+
+    def interpolate_hash(string, values)
+      string.gsub(INTERPOLATION_PATTERN) do |match|
+        if match == '%%'
+          '%'
+        else
+          key = ($1 || $2).to_sym
+          value = if values.key?(key)
+                    values[key]
+                  else
+                    config.missing_interpolation_argument_handler.call(key, values, string)
+                  end
+          value = value.call(values) if value.respond_to?(:call)
+          $3 ? sprintf("%#{$3}", value) : value
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/locale.rb b/app/server/vendor/i18n/lib/i18n/locale.rb
new file mode 100644
index 0000000..4f9d026
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/locale.rb
@@ -0,0 +1,6 @@
+module I18n
+  module Locale
+  autoload :Fallbacks, 'i18n/locale/fallbacks'
+  autoload :Tag,       'i18n/locale/tag'
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/locale/fallbacks.rb b/app/server/vendor/i18n/lib/i18n/locale/fallbacks.rb
new file mode 100644
index 0000000..08bf6f5
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/locale/fallbacks.rb
@@ -0,0 +1,96 @@
+# Locale Fallbacks
+#
+# Extends the I18n module to hold a fallbacks instance which is set to an
+# instance of I18n::Locale::Fallbacks by default but can be swapped with a
+# different implementation.
+#
+# Locale fallbacks will compute a number of fallback locales for a given locale.
+# For example:
+#
+# <pre><code>
+# I18n.fallbacks[:"es-MX"] # => [:"es-MX", :es, :en] </code></pre>
+#
+# Locale fallbacks always fall back to
+#
+#   * all parent locales of a given locale (e.g. :es for :"es-MX") first,
+#   * the current default locales and all of their parents second
+#
+# The default locales are set to [I18n.default_locale] by default but can be
+# set to something else.
+#
+# One can additionally add any number of additional fallback locales manually.
+# These will be added before the default locales to the fallback chain. For
+# example:
+#
+#   # using the default locale as default fallback locale
+#
+#   I18n.default_locale = :"en-US"
+#   I18n.fallbacks = I18n::Locale::Fallbacks.new(:"de-AT" => :"de-DE")
+#   I18n.fallbacks[:"de-AT"] # => [:"de-AT", :"de-DE", :de, :"en-US", :en]
+#
+#   # using a custom locale as default fallback locale
+#
+#   I18n.fallbacks = I18n::Locale::Fallbacks.new(:"en-GB", :"de-AT" => :de, :"de-CH" => :de)
+#   I18n.fallbacks[:"de-AT"] # => [:"de-AT", :de, :"en-GB", :en]
+#   I18n.fallbacks[:"de-CH"] # => [:"de-CH", :de, :"en-GB", :en]
+#
+#   # mapping fallbacks to an existing instance
+#
+#   # people speaking Catalan also speak Spanish as spoken in Spain
+#   fallbacks = I18n.fallbacks
+#   fallbacks.map(:ca => :"es-ES")
+#   fallbacks[:ca] # => [:ca, :"es-ES", :es, :"en-US", :en]
+#
+#   # people speaking Arabian as spoken in Palestine also speak Hebrew as spoken in Israel
+#   fallbacks.map(:"ar-PS" => :"he-IL")
+#   fallbacks[:"ar-PS"] # => [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en]
+#   fallbacks[:"ar-EG"] # => [:"ar-EG", :ar, :"en-US", :en]
+#
+#   # people speaking Sami as spoken in Finnland also speak Swedish and Finnish as spoken in Finnland
+#   fallbacks.map(:sms => [:"se-FI", :"fi-FI"])
+#   fallbacks[:sms] # => [:sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en]
+
+module I18n
+  module Locale
+    class Fallbacks < Hash
+      def initialize(*mappings)
+        @map = {}
+        map(mappings.pop) if mappings.last.is_a?(Hash)
+        self.defaults = mappings.empty? ? [I18n.default_locale.to_sym] : mappings
+      end
+
+      def defaults=(defaults)
+        @defaults = defaults.map { |default| compute(default, false) }.flatten
+      end
+      attr_reader :defaults
+
+      def [](locale)
+        raise InvalidLocale.new(locale) if locale.nil?
+        locale = locale.to_sym
+        super || store(locale, compute(locale))
+      end
+
+      def map(mappings)
+        mappings.each do |from, to|
+          from, to = from.to_sym, Array(to)
+          to.each do |_to|
+            @map[from] ||= []
+            @map[from] << _to.to_sym
+          end
+        end
+      end
+
+      protected
+
+      def compute(tags, include_defaults = true, exclude = [])
+        result = Array(tags).collect do |tag|
+          tags = I18n::Locale::Tag.tag(tag).self_and_parents.map! { |t| t.to_sym } - exclude
+          tags.each { |_tag| tags += compute(@map[_tag], false, exclude + tags) if @map[_tag] }
+          tags
+        end.flatten
+        result.push(*defaults) if include_defaults
+        result.uniq.compact
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/locale/tag.rb b/app/server/vendor/i18n/lib/i18n/locale/tag.rb
new file mode 100644
index 0000000..a640b44
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/locale/tag.rb
@@ -0,0 +1,28 @@
+# encoding: utf-8
+
+module I18n
+  module Locale
+    module Tag
+      autoload :Parents, 'i18n/locale/tag/parents'
+      autoload :Rfc4646, 'i18n/locale/tag/rfc4646'
+      autoload :Simple,  'i18n/locale/tag/simple'
+
+      class << self
+        # Returns the current locale tag implementation. Defaults to +I18n::Locale::Tag::Simple+.
+        def implementation
+          @@implementation ||= Simple
+        end
+
+        # Sets the current locale tag implementation. Use this to set a different locale tag implementation.
+        def implementation=(implementation)
+          @@implementation = implementation
+        end
+
+        # Factory method for locale tags. Delegates to the current locale tag implementation.
+        def tag(tag)
+          implementation.tag(tag)
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/locale/tag/parents.rb b/app/server/vendor/i18n/lib/i18n/locale/tag/parents.rb
new file mode 100644
index 0000000..ec53060
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/locale/tag/parents.rb
@@ -0,0 +1,22 @@
+module I18n
+  module Locale
+    module Tag
+      module Parents
+        def parent
+          @parent ||= begin
+            segs = to_a.compact
+            segs.length > 1 ? self.class.tag(*segs[0..(segs.length-2)].join('-')) : nil
+          end
+        end
+
+        def self_and_parents
+          @self_and_parents ||= [self] + parents
+        end
+
+        def parents
+          @parents ||= ([parent] + (parent ? parent.parents : [])).compact
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/locale/tag/rfc4646.rb b/app/server/vendor/i18n/lib/i18n/locale/tag/rfc4646.rb
new file mode 100644
index 0000000..4ce4c75
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/locale/tag/rfc4646.rb
@@ -0,0 +1,74 @@
+# RFC 4646/47 compliant Locale tag implementation that parses locale tags to
+# subtags such as language, script, region, variant etc.
+#
+# For more information see by http://en.wikipedia.org/wiki/IETF_language_tag
+#
+# Rfc4646::Parser does not implement grandfathered tags.
+
+module I18n
+  module Locale
+    module Tag
+      RFC4646_SUBTAGS = [ :language, :script, :region, :variant, :extension, :privateuse, :grandfathered ]
+      RFC4646_FORMATS = { :language => :downcase, :script => :capitalize, :region => :upcase, :variant => :downcase }
+
+      class Rfc4646 < Struct.new(*RFC4646_SUBTAGS)
+        class << self
+          # Parses the given tag and returns a Tag instance if it is valid.
+          # Returns false if the given tag is not valid according to RFC 4646.
+          def tag(tag)
+            matches = parser.match(tag)
+            new(*matches) if matches
+          end
+
+          def parser
+            @@parser ||= Rfc4646::Parser
+          end
+
+          def parser=(parser)
+            @@parser = parser
+          end
+        end
+
+        include Parents
+
+        RFC4646_FORMATS.each do |name, format|
+          define_method(name) { self[name].send(format) unless self[name].nil? }
+        end
+
+        def to_sym
+          to_s.to_sym
+        end
+
+        def to_s
+          @tag ||= to_a.compact.join("-")
+        end
+
+        def to_a
+          members.collect { |attr| self.send(attr) }
+        end
+
+        module Parser
+          PATTERN = %r{\A(?:
+            ([a-z]{2,3}(?:(?:-[a-z]{3}){0,3})?|[a-z]{4}|[a-z]{5,8}) # language
+            (?:-([a-z]{4}))?                                        # script
+            (?:-([a-z]{2}|\d{3}))?                                  # region
+            (?:-([0-9a-z]{5,8}|\d[0-9a-z]{3}))*                     # variant
+            (?:-([0-9a-wyz](?:-[0-9a-z]{2,8})+))*                   # extension
+            (?:-(x(?:-[0-9a-z]{1,8})+))?|                           # privateuse subtag
+            (x(?:-[0-9a-z]{1,8})+)|                                 # privateuse tag
+            /* ([a-z]{1,3}(?:-[0-9a-z]{2,8}){1,2}) */               # grandfathered
+            )\z}xi
+
+          class << self
+            def match(tag)
+              c = PATTERN.match(tag.to_s).captures
+              c[0..4] << (c[5].nil? ? c[6] : c[5])  << c[7] # TODO c[7] is grandfathered, throw a NotImplemented exception here?
+            rescue
+              false
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/locale/tag/simple.rb b/app/server/vendor/i18n/lib/i18n/locale/tag/simple.rb
new file mode 100644
index 0000000..68642a1
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/locale/tag/simple.rb
@@ -0,0 +1,39 @@
+# Simple Locale tag implementation that computes subtags by simply splitting
+# the locale tag at '-' occurences.
+module I18n
+  module Locale
+    module Tag
+      class Simple
+        class << self
+          def tag(tag)
+            new(tag)
+          end
+        end
+
+        include Parents
+
+        attr_reader :tag
+
+        def initialize(*tag)
+          @tag = tag.join('-').to_sym
+        end
+
+        def subtags
+          @subtags = tag.to_s.split('-').map { |subtag| subtag.to_s }
+        end
+
+        def to_sym
+          tag
+        end
+
+        def to_s
+          tag.to_s
+        end
+
+        def to_a
+          subtags
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/tests.rb b/app/server/vendor/i18n/lib/i18n/tests.rb
new file mode 100644
index 0000000..554cdef
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/tests.rb
@@ -0,0 +1,12 @@
+module I18n
+  module Tests
+    autoload :Basics,        'i18n/tests/basics'
+    autoload :Defaults,      'i18n/tests/defaults'
+    autoload :Interpolation, 'i18n/tests/interpolation'
+    autoload :Link,          'i18n/tests/link'
+    autoload :Localization,  'i18n/tests/localization'
+    autoload :Lookup,        'i18n/tests/lookup'
+    autoload :Pluralization, 'i18n/tests/pluralization'
+    autoload :Procs,         'i18n/tests/procs'
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/tests/basics.rb b/app/server/vendor/i18n/lib/i18n/tests/basics.rb
new file mode 100644
index 0000000..dc0596a
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/tests/basics.rb
@@ -0,0 +1,59 @@
+module I18n
+  module Tests
+    module Basics
+      def teardown
+        I18n.available_locales = nil
+      end
+
+      test "available_locales returns the locales stored to the backend by default" do
+        I18n.backend.store_translations('de', :foo => 'bar')
+        I18n.backend.store_translations('en', :foo => 'foo')
+
+        assert I18n.available_locales.include?(:de)
+        assert I18n.available_locales.include?(:en)
+      end
+
+      test "available_locales can be set to something else independently from the actual locale data" do
+        I18n.backend.store_translations('de', :foo => 'bar')
+        I18n.backend.store_translations('en', :foo => 'foo')
+
+        I18n.available_locales = :foo
+        assert_equal [:foo], I18n.available_locales
+
+        I18n.available_locales = [:foo, 'bar']
+        assert_equal [:foo, :bar], I18n.available_locales
+
+        I18n.available_locales = nil
+        assert I18n.available_locales.include?(:de)
+        assert I18n.available_locales.include?(:en)
+      end
+
+      test "available_locales memoizes when set explicitely" do
+        I18n.backend.expects(:available_locales).never
+        I18n.available_locales = [:foo]
+        I18n.backend.store_translations('de', :bar => 'baz')
+        I18n.reload!
+        assert_equal [:foo], I18n.available_locales
+      end
+
+      test "available_locales delegates to the backend when not set explicitely" do
+        I18n.backend.expects(:available_locales).twice
+        assert_equal I18n.available_locales, I18n.available_locales
+      end
+
+      test "exists? is implemented by the backend" do
+        I18n.backend.store_translations(:foo, :bar => 'baz')
+        assert I18n.exists?(:bar, :foo)
+      end
+
+      test "storing a nil value as a translation removes it from the available locale data" do
+        I18n.backend.store_translations(:en, :to_be_deleted => 'bar')
+        assert_equal 'bar', I18n.t(:to_be_deleted, :default => 'baz')
+
+        I18n.cache_store.clear if I18n.respond_to?(:cache_store) && I18n.cache_store
+        I18n.backend.store_translations(:en, :to_be_deleted => nil)
+        assert_equal 'baz', I18n.t(:to_be_deleted, :default => 'baz')
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/tests/defaults.rb b/app/server/vendor/i18n/lib/i18n/tests/defaults.rb
new file mode 100644
index 0000000..081dcbd
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/tests/defaults.rb
@@ -0,0 +1,40 @@
+# encoding: utf-8
+
+module I18n
+  module Tests
+    module Defaults
+      def setup
+        super
+        I18n.backend.store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' })
+      end
+
+      test "defaults: given nil as a key it returns the given default" do
+        assert_equal 'default', I18n.t(nil, :default => 'default')
+      end
+
+      test "defaults: given a symbol as a default it translates the symbol" do
+        assert_equal 'bar', I18n.t(nil, :default => :'foo.bar')
+      end
+
+      test "defaults: given a symbol as a default and a scope it stays inside the scope when looking up the symbol" do
+        assert_equal 'bar', I18n.t(:missing, :default => :bar, :scope => :foo)
+      end
+
+      test "defaults: given an array as a default it returns the first match" do
+        assert_equal 'bar', I18n.t(:does_not_exist, :default => [:does_not_exist_2, :'foo.bar'])
+      end
+
+      test "defaults: given an array of missing keys it raises a MissingTranslationData exception" do
+        assert_raise I18n::MissingTranslationData do
+          I18n.t(:does_not_exist, :default => [:does_not_exist_2, :does_not_exist_3], :raise => true)
+        end
+      end
+
+      test "defaults: using a custom scope separator" do
+        # data must have been stored using the custom separator when using the ActiveRecord backend
+        I18n.backend.store_translations(:en, { :foo => { :bar => 'bar' } }, { :separator => '|' })
+        assert_equal 'bar', I18n.t(nil, :default => :'foo|bar', :separator => '|')
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/tests/interpolation.rb b/app/server/vendor/i18n/lib/i18n/tests/interpolation.rb
new file mode 100644
index 0000000..add8b90
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/tests/interpolation.rb
@@ -0,0 +1,133 @@
+# encoding: utf-8
+
+module I18n
+  module Tests
+    module Interpolation
+      # If no interpolation parameter is not given, I18n should not alter the string.
+      # This behavior is due to three reasons:
+      #
+      #   * Checking interpolation keys in all strings hits performance, badly;
+      #
+      #   * This allows us to retrieve untouched values through I18n. For example
+      #     I could have a middleware that returns I18n lookup results in JSON
+      #     to be processed through Javascript. Leaving the keys untouched allows
+      #     the interpolation to happen at the javascript level;
+      #
+      #   * Security concerns: if I allow users to translate a web site, they can
+      #     insert %{} in messages causing the I18n lookup to fail in every request.
+      #
+      test "interpolation: given no values it does not alter the string" do
+        assert_equal 'Hi %{name}!', interpolate(:default => 'Hi %{name}!')
+      end
+
+      test "interpolation: given values it interpolates them into the string" do
+        assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => 'David')
+      end
+
+      test "interpolation: given a nil value it still interpolates it into the string" do
+        assert_equal 'Hi !', interpolate(:default => 'Hi %{name}!', :name => nil)
+      end
+
+      test "interpolation: given a lambda as a value it calls it if the string contains the key" do
+        assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => lambda { |*args| 'David' })
+      end
+
+      test "interpolation: given a lambda as a value it does not call it if the string does not contain the key" do
+        assert_nothing_raised { interpolate(:default => 'Hi!', :name => lambda { |*args| raise 'fail' }) }
+      end
+
+      test "interpolation: given values but missing a key it raises I18n::MissingInterpolationArgument" do
+        assert_raise(I18n::MissingInterpolationArgument) do
+          interpolate(:default => '%{foo}', :bar => 'bar')
+        end
+      end
+
+      test "interpolation: it does not raise I18n::MissingInterpolationArgument for escaped variables" do
+        assert_nothing_raised(I18n::MissingInterpolationArgument) do
+          assert_equal 'Barr %{foo}', interpolate(:default => '%{bar} %%{foo}', :bar => 'Barr')
+        end
+      end
+
+      test "interpolation: it does not change the original, stored translation string" do
+        I18n.backend.store_translations(:en, :interpolate => 'Hi %{name}!')
+        assert_equal 'Hi David!', interpolate(:interpolate, :name => 'David')
+        assert_equal 'Hi Yehuda!', interpolate(:interpolate, :name => 'Yehuda')
+      end
+
+      test "interpolation: given the translation is in utf-8 it still works" do
+        assert_equal 'Häi David!', interpolate(:default => 'Häi %{name}!', :name => 'David')
+      end
+
+      test "interpolation: given the value is in utf-8 it still works" do
+        assert_equal 'Hi ゆきひろ!', interpolate(:default => 'Hi %{name}!', :name => 'ゆきひろ')
+      end
+
+      test "interpolation: given the translation and the value are in utf-8 it still works" do
+        assert_equal 'こんにちは、ゆきひろさん!', interpolate(:default => 'こんにちは、%{name}さん!', :name => 'ゆきひろ')
+      end
+
+      if Object.const_defined?(:Encoding)
+        test "interpolation: given a euc-jp translation and a utf-8 value it raises Encoding::CompatibilityError" do
+          assert_raise(Encoding::CompatibilityError) do
+            interpolate(:default => euc_jp('こんにちは、%{name}さん!'), :name => 'ゆきひろ')
+          end
+        end
+
+        test "interpolation: given a utf-8 translation and a euc-jp value it raises Encoding::CompatibilityError" do
+          assert_raise(Encoding::CompatibilityError) do
+            interpolate(:default => 'こんにちは、%{name}さん!', :name => euc_jp('ゆきひろ'))
+          end
+        end
+
+        test "interpolation: ASCII strings in the backend should be encoded to UTF8 if interpolation options are in UTF8" do
+          I18n.backend.store_translations 'en', 'encoding' => ('%{who} let me go'.force_encoding("ASCII"))
+          result = I18n.t 'encoding', :who => "måmmå miå"
+          assert_equal Encoding::UTF_8, result.encoding
+        end
+
+        test "interpolation: UTF8 strings in the backend are still returned as UTF8 with ASCII interpolation" do
+          I18n.backend.store_translations 'en', 'encoding' => 'måmmå miå %{what}'
+          result = I18n.t 'encoding', :what => 'let me go'.force_encoding("ASCII")
+          assert_equal Encoding::UTF_8, result.encoding
+        end
+
+        test "interpolation: UTF8 strings in the backend are still returned as UTF8 even with numbers interpolation" do
+          I18n.backend.store_translations 'en', 'encoding' => '%{count} times: måmmå miå'
+          result = I18n.t 'encoding', :count => 3
+          assert_equal Encoding::UTF_8, result.encoding
+        end
+      end
+
+      test "interpolation: given a translations containing a reserved key it raises I18n::ReservedInterpolationKey" do
+        assert_raise(I18n::ReservedInterpolationKey) { interpolate(:default => '%{default}',   :foo => :bar) }
+        assert_raise(I18n::ReservedInterpolationKey) { interpolate(:default => '%{scope}',     :foo => :bar) }
+        assert_raise(I18n::ReservedInterpolationKey) { interpolate(:default => '%{separator}', :foo => :bar) }
+      end
+
+      protected
+
+      def capture(stream)
+        begin
+          stream = stream.to_s
+          eval "$#{stream} = StringIO.new"
+          yield
+          result = eval("$#{stream}").string
+        ensure
+          eval("$#{stream} = #{stream.upcase}")
+        end
+
+        result
+      end
+
+      def euc_jp(string)
+        string.encode!(Encoding::EUC_JP)
+      end
+
+      def interpolate(*args)
+        options = args.last.is_a?(Hash) ? args.pop : {}
+        key = args.pop
+        I18n.backend.translate('en', key, options)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/tests/link.rb b/app/server/vendor/i18n/lib/i18n/tests/link.rb
new file mode 100644
index 0000000..da84a2c
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/tests/link.rb
@@ -0,0 +1,56 @@
+# encoding: utf-8
+
+module I18n
+  module Tests
+    module Link
+      test "linked lookup: if a key resolves to a symbol it looks up the symbol" do
+        I18n.backend.store_translations 'en', {
+          :link  => :linked,
+          :linked => 'linked'
+        }
+        assert_equal 'linked', I18n.backend.translate('en', :link)
+      end
+
+      test "linked lookup: if a key resolves to a dot-separated symbol it looks up the symbol" do
+        I18n.backend.store_translations 'en', {
+          :link => :"foo.linked",
+          :foo  => { :linked => 'linked' }
+        }
+        assert_equal('linked', I18n.backend.translate('en', :link))
+      end
+
+      test "linked lookup: if a dot-separated key resolves to a symbol it looks up the symbol" do
+        I18n.backend.store_translations 'en', {
+          :foo    => { :link => :linked },
+          :linked => 'linked'
+        }
+        assert_equal('linked', I18n.backend.translate('en', :'foo.link'))
+      end
+      
+      test "linked lookup: if a dot-separated key resolves to a dot-separated symbol it looks up the symbol" do
+        I18n.backend.store_translations 'en', {
+          :foo => { :link   => :"bar.linked" },
+          :bar => { :linked => 'linked' }
+        }
+        assert_equal('linked', I18n.backend.translate('en', :'foo.link'))
+      end
+
+      test "linked lookup: links always refer to the absolute key" do
+        I18n.backend.store_translations 'en', {
+          :foo => { :link => :linked, :linked => 'linked in foo' },
+          :linked => 'linked absolutely'
+        }
+        assert_equal 'linked absolutely', I18n.backend.translate('en', :link, :scope => :foo)
+      end
+
+      test "linked lookup: a link can resolve to a namespace in the middle of a dot-separated key" do
+        I18n.backend.store_translations 'en', {
+          :activemodel  => { :errors => { :messages => { :blank => "can't be blank" } } },
+          :activerecord => { :errors => { :messages => :"activemodel.errors.messages" } }
+        }
+        assert_equal "can't be blank", I18n.t(:"activerecord.errors.messages.blank")
+        assert_equal "can't be blank", I18n.t(:"activerecord.errors.messages.blank")
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/tests/localization.rb b/app/server/vendor/i18n/lib/i18n/tests/localization.rb
new file mode 100644
index 0000000..53b1502
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/tests/localization.rb
@@ -0,0 +1,19 @@
+module I18n
+  module Tests
+    module Localization
+      autoload :Date,     'i18n/tests/localization/date'
+      autoload :DateTime, 'i18n/tests/localization/date_time'
+      autoload :Time,     'i18n/tests/localization/time'
+      autoload :Procs,    'i18n/tests/localization/procs'
+
+      def self.included(base)
+        base.class_eval do
+          include I18n::Tests::Localization::Date
+          include I18n::Tests::Localization::DateTime
+          include I18n::Tests::Localization::Procs
+          include I18n::Tests::Localization::Time
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/i18n/lib/i18n/tests/localization/date.rb b/app/server/vendor/i18n/lib/i18n/tests/localization/date.rb
new file mode 100644
index 0000000..a723475
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/tests/localization/date.rb
@@ -0,0 +1,91 @@
+# encoding: utf-8
+
+module I18n
+  module Tests
+    module Localization
+      module Date
+        def setup
+          super
+          setup_date_translations
+          @date = ::Date.new(2008, 3, 1)
+        end
+
+        test "localize Date: given the short format it uses it" do
+          # TODO should be Mrz, shouldn't it?
+          assert_equal '01. Mar', I18n.l(@date, :format => :short, :locale => :de)
+        end
+
+        test "localize Date: given the long format it uses it" do
+          assert_equal '01. März 2008', I18n.l(@date, :format => :long, :locale => :de)
+        end
+
+        test "localize Date: given the default format it uses it" do
+          assert_equal '01.03.2008', I18n.l(@date, :format => :default, :locale => :de)
+        end
+
+        test "localize Date: given a day name format it returns the correct day name" do
+          assert_equal 'Samstag', I18n.l(@date, :format => '%A', :locale => :de)
+        end
+
+        test "localize Date: given an abbreviated day name format it returns the correct abbreviated day name" do
+          assert_equal 'Sa', I18n.l(@date, :format => '%a', :locale => :de)
+        end
+
+        test "localize Date: given a month name format it returns the correct month name" do
+          assert_equal 'März', I18n.l(@date, :format => '%B', :locale => :de)
+        end
+
+        test "localize Date: given an abbreviated month name format it returns the correct abbreviated month name" do
+          # TODO should be Mrz, shouldn't it?
+          assert_equal 'Mar', I18n.l(@date, :format => '%b', :locale => :de)
+        end
+
+        test "localize Date: given an unknown format it does not fail" do
+          assert_nothing_raised { I18n.l(@date, :format => '%x') }
+        end
+
+        test "localize Date: does not modify the options hash" do
+          options = { :format => '%b', :locale => :de }
+          assert_equal 'Mar', I18n.l(@date, options)
+          assert_equal({ :format => '%b', :locale => :de }, options)
+          assert_nothing_raised { I18n.l(@date, options.freeze) }
+        end
+
+        test "localize Date: given nil it raises I18n::ArgumentError" do
+          assert_raise(I18n::ArgumentError) { I18n.l(nil) }
+        end
+
+        test "localize Date: given a plain Object it raises I18n::ArgumentError" do
+          assert_raise(I18n::ArgumentError) { I18n.l(Object.new) }
+        end
+
+        test "localize Date: given a format is missing it raises I18n::MissingTranslationData" do
+          assert_raise(I18n::MissingTranslationData) { I18n.l(@date, :format => :missing) }
+        end
+
+        test "localize Date: it does not alter the format string" do
+          assert_equal '01. Februar 2009', I18n.l(::Date.parse('2009-02-01'), :format => :long, :locale => :de)
+          assert_equal '01. Oktober 2009', I18n.l(::Date.parse('2009-10-01'), :format => :long, :locale => :de)
+        end
+
+        protected
+
+          def setup_date_translations
+            I18n.backend.store_translations :de, {
+              :date => {
+                :formats => {
+                  :default => "%d.%m.%Y",
+                  :short => "%d. %b",
+                  :long => "%d. %B %Y",
+                },
+                :day_names => %w(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag),
+                :abbr_day_names => %w(So Mo Di Mi Do Fr  Sa),
+                :month_names => %w(Januar Februar März April Mai Juni Juli August September Oktober November Dezember).unshift(nil),
+                :abbr_month_names => %w(Jan Feb Mar Apr Mai Jun Jul Aug Sep Okt Nov Dez).unshift(nil)
+              }
+            }
+          end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/tests/localization/date_time.rb b/app/server/vendor/i18n/lib/i18n/tests/localization/date_time.rb
new file mode 100644
index 0000000..7a30bff
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/tests/localization/date_time.rb
@@ -0,0 +1,82 @@
+# encoding: utf-8
+
+module I18n
+  module Tests
+    module Localization
+      module DateTime
+        def setup
+          super
+          setup_datetime_translations
+          @datetime = ::DateTime.new(2008, 3, 1, 6)
+          @other_datetime = ::DateTime.new(2008, 3, 1, 18)
+        end
+
+        test "localize DateTime: given the short format it uses it" do
+          # TODO should be Mrz, shouldn't it?
+          assert_equal '01. Mar 06:00', I18n.l(@datetime, :format => :short, :locale => :de)
+        end
+
+        test "localize DateTime: given the long format it uses it" do
+          assert_equal '01. März 2008 06:00', I18n.l(@datetime, :format => :long, :locale => :de)
+        end
+
+        test "localize DateTime: given the default format it uses it" do
+          # TODO should be Mrz, shouldn't it?
+          assert_equal 'Sa, 01. Mar 2008 06:00:00 +0000', I18n.l(@datetime, :format => :default, :locale => :de)
+        end
+
+        test "localize DateTime: given a day name format it returns the correct day name" do
+          assert_equal 'Samstag', I18n.l(@datetime, :format => '%A', :locale => :de)
+        end
+
+        test "localize DateTime: given an abbreviated day name format it returns the correct abbreviated day name" do
+          assert_equal 'Sa', I18n.l(@datetime, :format => '%a', :locale => :de)
+        end
+
+        test "localize DateTime: given a month name format it returns the correct month name" do
+          assert_equal 'März', I18n.l(@datetime, :format => '%B', :locale => :de)
+        end
+
+        test "localize DateTime: given an abbreviated month name format it returns the correct abbreviated month name" do
+          # TODO should be Mrz, shouldn't it?
+          assert_equal 'Mar', I18n.l(@datetime, :format => '%b', :locale => :de)
+        end
+
+        test "localize DateTime: given a meridian indicator format it returns the correct meridian indicator" do
+          assert_equal 'AM', I18n.l(@datetime, :format => '%p', :locale => :de)
+          assert_equal 'PM', I18n.l(@other_datetime, :format => '%p', :locale => :de)
+        end
+
+        test "localize DateTime: given a meridian indicator format it returns the correct meridian indicator in downcase" do
+          assert_equal 'am', I18n.l(@datetime, :format => '%P', :locale => :de)
+          assert_equal 'pm', I18n.l(@other_datetime, :format => '%P', :locale => :de)
+        end
+
+        test "localize DateTime: given an unknown format it does not fail" do
+          assert_nothing_raised { I18n.l(@datetime, :format => '%x') }
+        end
+
+        test "localize DateTime: given a format is missing it raises I18n::MissingTranslationData" do
+          assert_raise(I18n::MissingTranslationData) { I18n.l(@datetime, :format => :missing) }
+        end
+
+        protected
+
+          def setup_datetime_translations
+            # time translations might have been set up in Tests::Api::Localization::Time
+            I18n.backend.store_translations :de, {
+              :time => {
+                :formats => {
+                  :default => "%a, %d. %b %Y %H:%M:%S %z",
+                  :short => "%d. %b %H:%M",
+                  :long => "%d. %B %Y %H:%M"
+                },
+                :am => 'am',
+                :pm => 'pm'
+              }
+            }
+          end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/tests/localization/procs.rb b/app/server/vendor/i18n/lib/i18n/tests/localization/procs.rb
new file mode 100644
index 0000000..7b7813e
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/tests/localization/procs.rb
@@ -0,0 +1,116 @@
+# encoding: utf-8
+
+module I18n
+  module Tests
+    module Localization
+      module Procs
+        test "localize: using day names from lambdas" do
+          setup_time_proc_translations
+          time = ::Time.utc(2008, 3, 1, 6, 0)
+          assert_match(/Суббота/, I18n.l(time, :format => "%A, %d %B", :locale => :ru))
+          assert_match(/суббота/, I18n.l(time, :format => "%d %B (%A)", :locale => :ru))
+        end
+
+        test "localize: using month names from lambdas" do
+          setup_time_proc_translations
+          time = ::Time.utc(2008, 3, 1, 6, 0)
+          assert_match(/марта/, I18n.l(time, :format => "%d %B %Y", :locale => :ru))
+          assert_match(/Март /, I18n.l(time, :format => "%B %Y", :locale => :ru))
+        end
+
+        test "localize: using abbreviated day names from lambdas" do
+          setup_time_proc_translations
+          time = ::Time.utc(2008, 3, 1, 6, 0)
+          assert_match(/марта/, I18n.l(time, :format => "%d %b %Y", :locale => :ru))
+          assert_match(/март /, I18n.l(time, :format => "%b %Y", :locale => :ru))
+        end
+
+        test "localize Date: given a format that resolves to a Proc it calls the Proc with the object" do
+          setup_time_proc_translations
+          date = ::Date.new(2008, 3, 1)
+          assert_equal '[Sat, 01 Mar 2008, {}]', I18n.l(date, :format => :proc, :locale => :ru)
+        end
+
+        test "localize Date: given a format that resolves to a Proc it calls the Proc with the object and extra options" do
+          setup_time_proc_translations
+          date = ::Date.new(2008, 3, 1)
+          assert_equal '[Sat, 01 Mar 2008, {:foo=>"foo"}]', I18n.l(date, :format => :proc, :foo => 'foo', :locale => :ru)
+        end
+
+        test "localize DateTime: given a format that resolves to a Proc it calls the Proc with the object" do
+          setup_time_proc_translations
+          datetime = ::DateTime.new(2008, 3, 1, 6)
+          assert_equal '[Sat, 01 Mar 2008 06:00:00 +00:00, {}]', I18n.l(datetime, :format => :proc, :locale => :ru)
+        end
+
+        test "localize DateTime: given a format that resolves to a Proc it calls the Proc with the object and extra options" do
+          setup_time_proc_translations
+          datetime = ::DateTime.new(2008, 3, 1, 6)
+          assert_equal '[Sat, 01 Mar 2008 06:00:00 +00:00, {:foo=>"foo"}]', I18n.l(datetime, :format => :proc, :foo => 'foo', :locale => :ru)
+        end
+
+        test "localize Time: given a format that resolves to a Proc it calls the Proc with the object" do
+          setup_time_proc_translations
+          time = ::Time.utc(2008, 3, 1, 6, 0)
+          assert_equal inspect_args([time, {}]), I18n.l(time, :format => :proc, :locale => :ru)
+        end
+
+        test "localize Time: given a format that resolves to a Proc it calls the Proc with the object and extra options" do
+          setup_time_proc_translations
+          time = ::Time.utc(2008, 3, 1, 6, 0)
+          options = { :foo => 'foo' }
+          assert_equal inspect_args([time, options]), I18n.l(time, options.merge(:format => :proc, :locale => :ru))
+        end
+
+        protected
+
+          def inspect_args(args)
+            args = args.map do |arg|
+              case arg
+              when ::Time, ::DateTime
+                arg.strftime('%a, %d %b %Y %H:%M:%S %Z').sub('+0000', '+00:00')
+              when ::Date
+                arg.strftime('%a, %d %b %Y')
+              when Hash
+                arg.delete(:fallback)
+                arg.inspect
+              else
+                arg.inspect
+              end
+            end
+            "[#{args.join(', ')}]"
+          end
+
+          def setup_time_proc_translations
+            I18n.backend.store_translations :ru, {
+              :time => {
+                :formats => {
+                  :proc => lambda { |*args| inspect_args(args) }
+                }
+              },
+              :date => {
+                :formats => {
+                  :proc => lambda { |*args| inspect_args(args) }
+                },
+                :'day_names' => lambda { |key, options|
+                  (options[:format] =~ /^%A/) ?
+                  %w(Воскресенье Понедельник Вторник Среда Четверг Пятница Суббота) :
+                  %w(воскресенье понедельник вторник среда четверг пятница суббота)
+                },
+                :'month_names' => lambda { |key, options|
+                  (options[:format] =~ /(%d|%e)(\s*)?(%B)/) ?
+                  %w(января февраля марта апреля мая июня июля августа сентября октября ноября декабря).unshift(nil) :
+                  %w(Январь Февраль Март Апрель Май Июнь Июль Август Сентябрь Октябрь Ноябрь Декабрь).unshift(nil)
+                },
+                :'abbr_month_names' => lambda { |key, options|
+                  (options[:format] =~ /(%d|%e)(\s*)(%b)/) ?
+                  %w(янв. февр. марта апр. мая июня июля авг. сент. окт. нояб. дек.).unshift(nil) :
+                  %w(янв. февр. март апр. май июнь июль авг. сент. окт. нояб. дек.).unshift(nil)
+                },
+              }
+            }
+          end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/tests/localization/time.rb b/app/server/vendor/i18n/lib/i18n/tests/localization/time.rb
new file mode 100644
index 0000000..8bbba43
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/tests/localization/time.rb
@@ -0,0 +1,81 @@
+# encoding: utf-8
+
+module I18n
+  module Tests
+    module Localization
+      module Time
+        def setup
+          super
+          setup_time_translations
+          @time = ::Time.utc(2008, 3, 1, 6, 0)
+          @other_time = ::Time.utc(2008, 3, 1, 18, 0)
+        end
+
+        test "localize Time: given the short format it uses it" do
+          # TODO should be Mrz, shouldn't it?
+          assert_equal '01. Mar 06:00', I18n.l(@time, :format => :short, :locale => :de)
+        end
+
+        test "localize Time: given the long format it uses it" do
+          assert_equal '01. März 2008 06:00', I18n.l(@time, :format => :long, :locale => :de)
+        end
+
+        # TODO Seems to break on Windows because ENV['TZ'] is ignored. What's a better way to do this?
+        # def test_localize_given_the_default_format_it_uses_it
+        #   assert_equal 'Sa, 01. Mar 2008 06:00:00 +0000', I18n.l(@time, :format => :default, :locale => :de)
+        # end
+
+        test "localize Time: given a day name format it returns the correct day name" do
+          assert_equal 'Samstag', I18n.l(@time, :format => '%A', :locale => :de)
+        end
+
+        test "localize Time: given an abbreviated day name format it returns the correct abbreviated day name" do
+          assert_equal 'Sa', I18n.l(@time, :format => '%a', :locale => :de)
+        end
+
+        test "localize Time: given a month name format it returns the correct month name" do
+          assert_equal 'März', I18n.l(@time, :format => '%B', :locale => :de)
+        end
+
+        test "localize Time: given an abbreviated month name format it returns the correct abbreviated month name" do
+          # TODO should be Mrz, shouldn't it?
+          assert_equal 'Mar', I18n.l(@time, :format => '%b', :locale => :de)
+        end
+
+        test "localize Time: given a meridian indicator format it returns the correct meridian indicator" do
+          assert_equal 'AM', I18n.l(@time, :format => '%p', :locale => :de)
+          assert_equal 'PM', I18n.l(@other_time, :format => '%p', :locale => :de)
+        end
+
+        test "localize Time: given a meridian indicator format it returns the correct meridian indicator in upcase" do
+          assert_equal 'am', I18n.l(@time, :format => '%P', :locale => :de)
+          assert_equal 'pm', I18n.l(@other_time, :format => '%P', :locale => :de)
+        end
+
+        test "localize Time: given an unknown format it does not fail" do
+          assert_nothing_raised { I18n.l(@time, :format => '%x') }
+        end
+
+        test "localize Time: given a format is missing it raises I18n::MissingTranslationData" do
+          assert_raise(I18n::MissingTranslationData) { I18n.l(@time, :format => :missing) }
+        end
+
+        protected
+
+          def setup_time_translations
+            I18n.backend.store_translations :de, {
+              :time => {
+                :formats => {
+                  :default => "%a, %d. %b %Y %H:%M:%S %z",
+                  :short => "%d. %b %H:%M",
+                  :long => "%d. %B %Y %H:%M",
+                },
+                :am => 'am',
+                :pm => 'pm'
+              }
+            }
+          end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/tests/lookup.rb b/app/server/vendor/i18n/lib/i18n/tests/lookup.rb
new file mode 100644
index 0000000..62c069d
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/tests/lookup.rb
@@ -0,0 +1,81 @@
+# encoding: utf-8
+
+module I18n
+  module Tests
+    module Lookup
+      def setup
+        super
+        I18n.backend.store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' }, :falsy => false, :truthy => true,
+          :string => "a", :array => %w(a b c), :hash => { "a" => "b" })
+      end
+
+      test "lookup: it returns a string" do
+        assert_equal("a", I18n.t(:string))
+      end
+
+      test "lookup: it returns hash" do
+        assert_equal({ :a => "b" }, I18n.t(:hash))
+      end
+
+      test "lookup: it returns a array" do
+        assert_equal(%w(a b c), I18n.t(:array))
+      end
+
+      test "lookup: it returns a native true" do
+        assert I18n.t(:truthy) === true
+      end
+
+      test "lookup: it returns a native false" do
+        assert I18n.t(:falsy) === false
+      end
+
+      test "lookup: given a missing key, no default and no raise option it returns an error message" do
+        assert_equal "translation missing: en.missing", I18n.t(:missing)
+      end
+
+      test "lookup: given a missing key, no default and the raise option it raises MissingTranslationData" do
+        assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
+      end
+
+      test "lookup: does not raise an exception if no translation data is present for the given locale" do
+        assert_nothing_raised { I18n.t(:foo, :locale => :xx) }
+      end
+
+      test "lookup: does not modify the options hash" do
+        options = {}
+        assert_equal "a", I18n.t(:string, options)
+        assert_equal({}, options)
+        assert_nothing_raised { I18n.t(:string, options.freeze) }
+      end
+
+      test "lookup: given an array of keys it translates all of them" do
+        assert_equal %w(bar baz), I18n.t([:bar, :baz], :scope => [:foo])
+      end
+
+      test "lookup: using a custom scope separator" do
+        # data must have been stored using the custom separator when using the ActiveRecord backend
+        I18n.backend.store_translations(:en, { :foo => { :bar => 'bar' } }, { :separator => '|' })
+        assert_equal 'bar', I18n.t('foo|bar', :separator => '|')
+      end
+
+      # In fact it probably *should* fail but Rails currently relies on using the default locale instead.
+      # So we'll stick to this for now until we get it fixed in Rails.
+      test "lookup: given nil as a locale it does not raise but use the default locale" do
+        # assert_raise(I18n::InvalidLocale) { I18n.t(:bar, :locale => nil) }
+        assert_nothing_raised { I18n.t(:bar, :locale => nil) }
+      end
+
+      test "lookup: a resulting String is not frozen" do
+        assert !I18n.t(:string).frozen?
+      end
+
+      test "lookup: a resulting Array is not frozen" do
+        assert !I18n.t(:array).frozen?
+      end
+
+      test "lookup: a resulting Hash is not frozen" do
+        assert !I18n.t(:hash).frozen?
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/tests/pluralization.rb b/app/server/vendor/i18n/lib/i18n/tests/pluralization.rb
new file mode 100644
index 0000000..d3319dc
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/tests/pluralization.rb
@@ -0,0 +1,35 @@
+# encoding: utf-8
+
+module I18n
+  module Tests
+    module Pluralization
+      test "pluralization: given 0 it returns the :zero translation if it is defined" do
+        assert_equal 'zero', I18n.t(:default => { :zero => 'zero' }, :count => 0)
+      end
+
+      test "pluralization: given 0 it returns the :other translation if :zero is not defined" do
+        assert_equal 'bars', I18n.t(:default => { :other => 'bars' }, :count => 0)
+      end
+
+      test "pluralization: given 1 it returns the singular translation" do
+        assert_equal 'bar', I18n.t(:default => { :one => 'bar' }, :count => 1)
+      end
+
+      test "pluralization: given 2 it returns the :other translation" do
+        assert_equal 'bars', I18n.t(:default => { :other => 'bars' }, :count => 2)
+      end
+
+      test "pluralization: given 3 it returns the :other translation" do
+        assert_equal 'bars', I18n.t(:default => { :other => 'bars' }, :count => 3)
+      end
+
+      test "pluralization: given nil it returns the whole entry" do
+        assert_equal({ :one => 'bar' }, I18n.t(:default => { :one => 'bar' }, :count => nil))
+      end
+
+      test "pluralization: given incomplete pluralization data it raises I18n::InvalidPluralizationData" do
+        assert_raise(I18n::InvalidPluralizationData) { I18n.t(:default => { :one => 'bar' }, :count => 2) }
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/tests/procs.rb b/app/server/vendor/i18n/lib/i18n/tests/procs.rb
new file mode 100644
index 0000000..55ff952
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/tests/procs.rb
@@ -0,0 +1,55 @@
+# encoding: utf-8
+
+module I18n
+  module Tests
+    module Procs
+      test "lookup: given a translation is a proc it calls the proc with the key and interpolation values" do
+        I18n.backend.store_translations(:en, :a_lambda => lambda { |*args| filter_args(*args) })
+        assert_equal '[:a_lambda, {:foo=>"foo"}]', I18n.t(:a_lambda, :foo => 'foo')
+      end
+
+      test "defaults: given a default is a Proc it calls it with the key and interpolation values" do
+        proc = lambda { |*args| filter_args(*args) }
+        assert_equal '[nil, {:foo=>"foo"}]', I18n.t(nil, :default => proc, :foo => 'foo')
+      end
+
+      test "defaults: given a default is a key that resolves to a Proc it calls it with the key and interpolation values" do
+        I18n.backend.store_translations(:en, :a_lambda => lambda { |*args| filter_args(*args) })
+        assert_equal '[:a_lambda, {:foo=>"foo"}]', I18n.t(nil, :default => :a_lambda, :foo => 'foo')
+        assert_equal '[:a_lambda, {:foo=>"foo"}]', I18n.t(nil, :default => [nil, :a_lambda], :foo => 'foo')
+      end
+
+      test "interpolation: given an interpolation value is a lambda it calls it with key and values before interpolating it" do
+        proc = lambda { |*args| filter_args(*args) }
+        assert_match %r(\[\{:foo=>#<Proc.*>\}\]), I18n.t(nil, :default => '%{foo}', :foo => proc)
+      end
+
+      test "interpolation: given a key resolves to a Proc that returns a string then interpolation still works" do
+        proc = lambda { |*args| "%{foo}: " + filter_args(*args) }
+        assert_equal 'foo: [nil, {:foo=>"foo"}]', I18n.t(nil, :default => proc, :foo => 'foo')
+      end
+
+      test "pluralization: given a key resolves to a Proc that returns valid data then pluralization still works" do
+        proc = lambda { |*args| { :zero => 'zero', :one => 'one', :other => 'other' } }
+        assert_equal 'zero',  I18n.t(:default => proc, :count => 0)
+        assert_equal 'one',   I18n.t(:default => proc, :count => 1)
+        assert_equal 'other', I18n.t(:default => proc, :count => 2)
+      end
+
+      test "lookup: given the option :resolve => false was passed it does not resolve proc translations" do
+        I18n.backend.store_translations(:en, :a_lambda => lambda { |*args| filter_args(*args) })
+        assert_equal Proc, I18n.t(:a_lambda, :resolve => false).class
+      end
+
+      test "lookup: given the option :resolve => false was passed it does not resolve proc default" do
+        assert_equal Proc, I18n.t(nil, :default => lambda { |*args| filter_args(*args) }, :resolve => false).class
+      end
+
+      protected
+
+      def filter_args(*args)
+        args.map {|arg| arg.delete(:fallback) if arg.is_a?(Hash) ; arg }.inspect
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/lib/i18n/version.rb b/app/server/vendor/i18n/lib/i18n/version.rb
new file mode 100644
index 0000000..87cda09
--- /dev/null
+++ b/app/server/vendor/i18n/lib/i18n/version.rb
@@ -0,0 +1,3 @@
+module I18n
+  VERSION = "0.6.10"
+end
diff --git a/app/server/vendor/i18n/test/all.rb b/app/server/vendor/i18n/test/all.rb
new file mode 100644
index 0000000..e846143
--- /dev/null
+++ b/app/server/vendor/i18n/test/all.rb
@@ -0,0 +1,8 @@
+# encoding: utf-8
+
+dir = File.dirname(__FILE__)
+$LOAD_PATH.unshift(dir)
+
+Dir["#{dir}/**/*_test.rb"].sort.each do |file|
+  require file.sub(/^#{dir}\/(.*)\.rb$/, '\1')
+end
diff --git a/app/server/vendor/i18n/test/api/all_features_test.rb b/app/server/vendor/i18n/test/api/all_features_test.rb
new file mode 100644
index 0000000..a1799bd
--- /dev/null
+++ b/app/server/vendor/i18n/test/api/all_features_test.rb
@@ -0,0 +1,58 @@
+require 'test_helper'
+
+begin
+  require 'rubygems'
+  require 'active_support'
+rescue LoadError
+  puts "not testing with Cache enabled because active_support can not be found"
+end
+
+class I18nAllFeaturesApiTest < I18n::TestCase
+  class Backend < I18n::Backend::Simple
+    include I18n::Backend::Metadata
+    include I18n::Backend::Cache
+    include I18n::Backend::Cascade
+    include I18n::Backend::Fallbacks
+    include I18n::Backend::Pluralization
+    include I18n::Backend::Memoize
+  end
+
+  def setup
+    I18n.backend = I18n::Backend::Chain.new(Backend.new, I18n::Backend::Simple.new)
+    I18n.cache_store = cache_store
+    super
+  end
+
+  def teardown
+    I18n.cache_store.clear if I18n.cache_store
+    I18n.cache_store = nil
+    super
+  end
+
+  def cache_store
+    ActiveSupport::Cache.lookup_store(:memory_store) if cache_available?
+  end
+
+  def cache_available?
+    defined?(ActiveSupport) && defined?(ActiveSupport::Cache)
+  end
+
+  include I18n::Tests::Basics
+  include I18n::Tests::Defaults
+  include I18n::Tests::Interpolation
+  include I18n::Tests::Link
+  include I18n::Tests::Lookup
+  include I18n::Tests::Pluralization
+  include I18n::Tests::Procs
+  include I18n::Tests::Localization::Date
+  include I18n::Tests::Localization::DateTime
+  include I18n::Tests::Localization::Time
+  include I18n::Tests::Localization::Procs
+
+  test "make sure we use a Chain backend with an all features backend" do
+    assert_equal I18n::Backend::Chain, I18n.backend.class
+    assert_equal Backend, I18n.backend.backends.first.class
+  end
+
+  # links: test that keys stored on one backend can link to keys stored on another backend
+end
diff --git a/app/server/vendor/i18n/test/api/cascade_test.rb b/app/server/vendor/i18n/test/api/cascade_test.rb
new file mode 100644
index 0000000..4d9516c
--- /dev/null
+++ b/app/server/vendor/i18n/test/api/cascade_test.rb
@@ -0,0 +1,28 @@
+require 'test_helper'
+
+class I18nCascadeApiTest < I18n::TestCase
+  class Backend < I18n::Backend::Simple
+    include I18n::Backend::Cascade
+  end
+
+  def setup
+    I18n.backend = Backend.new
+    super
+  end
+
+  include I18n::Tests::Basics
+  include I18n::Tests::Defaults
+  include I18n::Tests::Interpolation
+  include I18n::Tests::Link
+  include I18n::Tests::Lookup
+  include I18n::Tests::Pluralization
+  include I18n::Tests::Procs
+  include I18n::Tests::Localization::Date
+  include I18n::Tests::Localization::DateTime
+  include I18n::Tests::Localization::Time
+  include I18n::Tests::Localization::Procs
+
+  test "make sure we use a backend with Cascade included" do
+    assert_equal Backend, I18n.backend.class
+  end
+end
diff --git a/app/server/vendor/i18n/test/api/chain_test.rb b/app/server/vendor/i18n/test/api/chain_test.rb
new file mode 100644
index 0000000..f3dff1b
--- /dev/null
+++ b/app/server/vendor/i18n/test/api/chain_test.rb
@@ -0,0 +1,24 @@
+require 'test_helper'
+
+class I18nApiChainTest < I18n::TestCase
+  def setup
+    super
+    I18n.backend = I18n::Backend::Chain.new(I18n::Backend::Simple.new, I18n.backend)
+  end
+
+  include I18n::Tests::Basics
+  include I18n::Tests::Defaults
+  include I18n::Tests::Interpolation
+  include I18n::Tests::Link
+  include I18n::Tests::Lookup
+  include I18n::Tests::Pluralization
+  include I18n::Tests::Procs
+  include I18n::Tests::Localization::Date
+  include I18n::Tests::Localization::DateTime
+  include I18n::Tests::Localization::Time
+  include I18n::Tests::Localization::Procs
+
+  test "make sure we use the Chain backend" do
+    assert_equal I18n::Backend::Chain, I18n.backend.class
+  end
+end
diff --git a/app/server/vendor/i18n/test/api/fallbacks_test.rb b/app/server/vendor/i18n/test/api/fallbacks_test.rb
new file mode 100644
index 0000000..e5ca5f2
--- /dev/null
+++ b/app/server/vendor/i18n/test/api/fallbacks_test.rb
@@ -0,0 +1,30 @@
+require 'test_helper'
+
+class I18nFallbacksApiTest < I18n::TestCase
+  class Backend < I18n::Backend::Simple
+    include I18n::Backend::Fallbacks
+  end
+
+  def setup
+    I18n.backend = Backend.new
+    super
+  end
+
+  include I18n::Tests::Basics
+  include I18n::Tests::Defaults
+  include I18n::Tests::Interpolation
+  include I18n::Tests::Link
+  include I18n::Tests::Lookup
+  include I18n::Tests::Pluralization
+  include I18n::Tests::Procs
+  include I18n::Tests::Localization::Date
+  include I18n::Tests::Localization::DateTime
+  include I18n::Tests::Localization::Time
+  include I18n::Tests::Localization::Procs
+
+  test "make sure we use a backend with Fallbacks included" do
+    assert_equal Backend, I18n.backend.class
+  end
+
+  # links: test that keys stored on one backend can link to keys stored on another backend
+end
diff --git a/app/server/vendor/i18n/test/api/key_value_test.rb b/app/server/vendor/i18n/test/api/key_value_test.rb
new file mode 100644
index 0000000..6a8d405
--- /dev/null
+++ b/app/server/vendor/i18n/test/api/key_value_test.rb
@@ -0,0 +1,28 @@
+require 'test_helper'
+
+I18n::TestCase.setup_rufus_tokyo
+
+class I18nKeyValueApiTest < I18n::TestCase
+  include I18n::Tests::Basics
+  include I18n::Tests::Defaults
+  include I18n::Tests::Interpolation
+  include I18n::Tests::Link
+  include I18n::Tests::Lookup
+  include I18n::Tests::Pluralization
+  # include Tests::Api::Procs
+  include I18n::Tests::Localization::Date
+  include I18n::Tests::Localization::DateTime
+  include I18n::Tests::Localization::Time
+  # include Tests::Api::Localization::Procs
+
+  STORE = Rufus::Tokyo::Cabinet.new('*')
+
+  def setup
+    I18n.backend = I18n::Backend::KeyValue.new(STORE)
+    super
+  end
+
+  test "make sure we use the KeyValue backend" do
+    assert_equal I18n::Backend::KeyValue, I18n.backend.class
+  end
+end if defined?(Rufus::Tokyo::Cabinet)
diff --git a/app/server/vendor/i18n/test/api/memoize_test.rb b/app/server/vendor/i18n/test/api/memoize_test.rb
new file mode 100644
index 0000000..0304580
--- /dev/null
+++ b/app/server/vendor/i18n/test/api/memoize_test.rb
@@ -0,0 +1,60 @@
+require 'test_helper'
+
+class I18nMemoizeBackendWithSimpleApiTest < I18n::TestCase
+  include I18n::Tests::Basics
+  include I18n::Tests::Defaults
+  include I18n::Tests::Interpolation
+  include I18n::Tests::Link
+  include I18n::Tests::Lookup
+  include I18n::Tests::Pluralization
+  include I18n::Tests::Procs
+  include I18n::Tests::Localization::Date
+  include I18n::Tests::Localization::DateTime
+  include I18n::Tests::Localization::Time
+  include I18n::Tests::Localization::Procs
+
+  class MemoizeBackend < I18n::Backend::Simple
+    include I18n::Backend::Memoize
+  end
+
+  def setup
+    I18n.backend = MemoizeBackend.new
+    super
+  end
+
+  test "make sure we use the MemoizeBackend backend" do
+    assert_equal MemoizeBackend, I18n.backend.class
+  end
+end
+
+I18n::TestCase.setup_rufus_tokyo
+
+class I18nMemoizeBackendWithKeyValueApiTest < I18n::TestCase
+  include I18n::Tests::Basics
+  include I18n::Tests::Defaults
+  include I18n::Tests::Interpolation
+  include I18n::Tests::Link
+  include I18n::Tests::Lookup
+  include I18n::Tests::Pluralization
+  include I18n::Tests::Localization::Date
+  include I18n::Tests::Localization::DateTime
+  include I18n::Tests::Localization::Time
+
+  # include I18n::Tests::Procs
+  # include I18n::Tests::Localization::Procs
+
+  class MemoizeBackend < I18n::Backend::KeyValue
+    include I18n::Backend::Memoize
+  end
+
+  STORE = Rufus::Tokyo::Cabinet.new('*')
+
+  def setup
+    I18n.backend = MemoizeBackend.new(STORE)
+    super
+  end
+
+  test "make sure we use the MemoizeBackend backend" do
+    assert_equal MemoizeBackend, I18n.backend.class
+  end
+end if defined?(Rufus::Tokyo::Cabinet)
diff --git a/app/server/vendor/i18n/test/api/override_test.rb b/app/server/vendor/i18n/test/api/override_test.rb
new file mode 100644
index 0000000..67e1f06
--- /dev/null
+++ b/app/server/vendor/i18n/test/api/override_test.rb
@@ -0,0 +1,43 @@
+require 'test_helper'
+
+class I18nOverrideTest < I18n::TestCase
+  module OverrideInverse
+    def translate(*args)
+      super(*args).reverse
+    end
+    alias :t :translate
+  end
+
+  module OverrideSignature
+    def translate(*args)
+      args.first + args[1]
+    end
+    alias :t :translate
+  end
+
+  def setup
+    @I18n = I18n.dup
+    @I18n.backend = I18n::Backend::Simple.new
+    super
+  end
+
+  test "make sure modules can overwrite I18n methods" do
+    @I18n.extend OverrideInverse
+    @I18n.backend.store_translations('en', :foo => 'bar')
+
+    assert_equal 'rab', @I18n.translate(:foo, :locale => 'en')
+    # FIXME: this fails under 1.8.7
+    # assert_equal 'rab', @I18n.t(:foo, :locale => 'en')
+    assert_equal 'rab', @I18n.translate!(:foo, :locale => 'en')
+    assert_equal 'rab', @I18n.t!(:foo, :locale => 'en')
+  end
+
+  test "make sure modules can overwrite I18n signature" do
+    exception = catch(:exception) do
+      @I18n.t('Hello', 'Welcome message on home page', :tokenize => true, :throw => true)
+    end
+    assert exception.message
+    @I18n.extend OverrideSignature
+    assert_equal 'HelloWelcome message on home page', @I18n.translate('Hello', 'Welcome message on home page', :tokenize => true) # tr8n example
+  end
+end
diff --git a/app/server/vendor/i18n/test/api/pluralization_test.rb b/app/server/vendor/i18n/test/api/pluralization_test.rb
new file mode 100644
index 0000000..53004be
--- /dev/null
+++ b/app/server/vendor/i18n/test/api/pluralization_test.rb
@@ -0,0 +1,30 @@
+require 'test_helper'
+
+class I18nPluralizationApiTest < I18n::TestCase
+  class Backend < I18n::Backend::Simple
+    include I18n::Backend::Pluralization
+  end
+
+  def setup
+    I18n.backend = Backend.new
+    super
+  end
+
+  include I18n::Tests::Basics
+  include I18n::Tests::Defaults
+  include I18n::Tests::Interpolation
+  include I18n::Tests::Link
+  include I18n::Tests::Lookup
+  include I18n::Tests::Pluralization
+  include I18n::Tests::Procs
+  include I18n::Tests::Localization::Date
+  include I18n::Tests::Localization::DateTime
+  include I18n::Tests::Localization::Time
+  include I18n::Tests::Localization::Procs
+
+  test "make sure we use a backend with Pluralization included" do
+    assert_equal Backend, I18n.backend.class
+  end
+
+  # links: test that keys stored on one backend can link to keys stored on another backend
+end
diff --git a/app/server/vendor/i18n/test/api/simple_test.rb b/app/server/vendor/i18n/test/api/simple_test.rb
new file mode 100644
index 0000000..3fd3a42
--- /dev/null
+++ b/app/server/vendor/i18n/test/api/simple_test.rb
@@ -0,0 +1,28 @@
+require 'test_helper'
+
+class I18nSimpleBackendApiTest < I18n::TestCase
+  class Backend < I18n::Backend::Simple
+    include I18n::Backend::Pluralization
+  end
+
+  def setup
+    I18n.backend = I18n::Backend::Simple.new
+    super
+  end
+
+  include I18n::Tests::Basics
+  include I18n::Tests::Defaults
+  include I18n::Tests::Interpolation
+  include I18n::Tests::Link
+  include I18n::Tests::Lookup
+  include I18n::Tests::Pluralization
+  include I18n::Tests::Procs
+  include I18n::Tests::Localization::Date
+  include I18n::Tests::Localization::DateTime
+  include I18n::Tests::Localization::Time
+  include I18n::Tests::Localization::Procs
+
+  test "make sure we use the Simple backend" do
+    assert_equal I18n::Backend::Simple, I18n.backend.class
+  end
+end
diff --git a/app/server/vendor/i18n/test/backend/cache_test.rb b/app/server/vendor/i18n/test/backend/cache_test.rb
new file mode 100644
index 0000000..0f0e028
--- /dev/null
+++ b/app/server/vendor/i18n/test/backend/cache_test.rb
@@ -0,0 +1,85 @@
+require 'test_helper'
+
+begin
+  require 'active_support'
+rescue LoadError
+  $stderr.puts "Skipping cache tests using ActiveSupport"
+else
+
+class I18nBackendCacheTest < I18n::TestCase
+  class Backend < I18n::Backend::Simple
+    include I18n::Backend::Cache
+  end
+
+  def setup
+    I18n.backend = Backend.new
+    super
+    I18n.cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
+  end
+
+  def teardown
+    I18n.cache_store = nil
+  end
+
+  test "it uses the cache" do
+    assert I18n.cache_store.is_a?(ActiveSupport::Cache::MemoryStore)
+  end
+
+  test "translate hits the backend and caches the response" do
+    I18n.backend.expects(:lookup).returns('Foo')
+    assert_equal 'Foo', I18n.t(:foo)
+
+    I18n.backend.expects(:lookup).never
+    assert_equal 'Foo', I18n.t(:foo)
+
+    I18n.backend.expects(:lookup).returns('Bar')
+    assert_equal 'Bar', I18n.t(:bar)
+  end
+
+  test "still raises MissingTranslationData but also caches it" do
+    assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
+    assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
+    assert_equal 1, I18n.cache_store.instance_variable_get(:@data).size
+
+    # I18n.backend.expects(:lookup).returns(nil)
+    # assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
+    # I18n.backend.expects(:lookup).never
+    # assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
+  end
+
+  test "uses 'i18n' as a cache key namespace by default" do
+    assert_equal 0, I18n.backend.send(:cache_key, :en, :foo, {}).index('i18n')
+  end
+
+  test "adds a custom cache key namespace" do
+    with_cache_namespace('bar') do
+      assert_equal 0, I18n.backend.send(:cache_key, :en, :foo, {}).index('i18n/bar/')
+    end
+  end
+
+  test "adds locale and hash of key and hash of options" do
+    options = { :bar=>1 }
+    options_hash = I18n::Backend::Cache::USE_INSPECT_HASH ? options.inspect.hash : options.hash
+    assert_equal "i18n//en/#{:foo.hash}/#{options_hash}", I18n.backend.send(:cache_key, :en, :foo, options)
+  end
+
+  test "keys should not be equal" do
+    interpolation_values1 = { :foo => 1, :bar => 2 }
+    interpolation_values2 = { :foo => 2, :bar => 1 }
+
+    key1 = I18n.backend.send(:cache_key, :en, :some_key, interpolation_values1)
+    key2 = I18n.backend.send(:cache_key, :en, :some_key, interpolation_values2)
+
+    assert key1 != key2
+  end
+
+  protected
+
+    def with_cache_namespace(namespace)
+      I18n.cache_namespace = namespace
+      yield
+      I18n.cache_namespace = nil
+    end
+end
+
+end # AS cache check
diff --git a/app/server/vendor/i18n/test/backend/cascade_test.rb b/app/server/vendor/i18n/test/backend/cascade_test.rb
new file mode 100644
index 0000000..e0bda10
--- /dev/null
+++ b/app/server/vendor/i18n/test/backend/cascade_test.rb
@@ -0,0 +1,85 @@
+require 'test_helper'
+
+class I18nBackendCascadeTest < I18n::TestCase
+  class Backend < I18n::Backend::Simple
+    include I18n::Backend::Cascade
+  end
+
+  def setup
+    I18n.backend = Backend.new
+    store_translations(:en, :foo => 'foo', :bar => { :baz => 'baz' })
+    @cascade_options = { :step => 1, :offset => 1, :skip_root => false }
+  end
+
+  def lookup(key, options = {})
+    I18n.t(key, options.merge(:cascade => @cascade_options))
+  end
+
+  test "still returns an existing translation as usual" do
+    assert_equal 'foo', lookup(:foo)
+    assert_equal 'baz', lookup(:'bar.baz')
+  end
+
+  test "falls back by cutting keys off the end of the scope" do
+    assert_equal 'foo', lookup(:foo, :scope => :'missing')
+    assert_equal 'foo', lookup(:foo, :scope => :'missing.missing')
+    assert_equal 'baz', lookup(:baz, :scope => :'bar.missing')
+    assert_equal 'baz', lookup(:baz, :scope => :'bar.missing.missing')
+  end
+
+  test "raises I18n::MissingTranslationData exception when no translation was found" do
+    assert_raise(I18n::MissingTranslationData) { lookup(:'foo.missing', :raise => true) }
+    assert_raise(I18n::MissingTranslationData) { lookup(:'bar.baz.missing', :raise => true) }
+    assert_raise(I18n::MissingTranslationData) { lookup(:'missing.bar.baz', :raise => true) }
+  end
+
+  test "cascades before evaluating the default" do
+    assert_equal 'foo', lookup(:foo, :scope => :missing, :default => 'default')
+  end
+
+  test "cascades defaults, too" do
+    assert_equal 'foo', lookup(nil, :default => [:'missing.missing', :'missing.foo'])
+  end
+
+  test "works with :offset => 2 and a single key" do
+    @cascade_options[:offset] = 2
+    lookup(:foo)
+  end
+
+  test "assemble required fallbacks for ActiveRecord validation messages" do
+    store_translations(:en,
+      :errors => {
+        :odd => 'errors.odd',
+        :reply => { :title => { :blank => 'errors.reply.title.blank'   }, :taken  => 'errors.reply.taken'  },
+        :topic => { :title => { :format => 'errors.topic.title.format' }, :length => 'errors.topic.length' }
+      }
+    )
+    assert_equal 'errors.reply.title.blank',  lookup(:'errors.reply.title.blank',  :default => :'errors.topic.title.blank')
+    assert_equal 'errors.reply.taken',        lookup(:'errors.reply.title.taken',  :default => :'errors.topic.title.taken')
+    assert_equal 'errors.topic.title.format', lookup(:'errors.reply.title.format', :default => :'errors.topic.title.format')
+    assert_equal 'errors.topic.length',       lookup(:'errors.reply.title.length', :default => :'errors.topic.title.length')
+    assert_equal 'errors.odd',                lookup(:'errors.reply.title.odd',    :default => :'errors.topic.title.odd')
+  end
+
+  test "assemble action view translation helper lookup cascade" do
+    @cascade_options[:offset] = 2
+
+    store_translations(:en,
+      :menu => { :show => 'menu.show' },
+      :namespace => {
+        :menu => { :new => 'namespace.menu.new' },
+        :controller => {
+          :menu => { :edit => 'namespace.controller.menu.edit' },
+          :action => {
+            :menu => { :destroy => 'namespace.controller.action.menu.destroy' }
+          }
+        }
+      }
+    )
+
+    assert_equal 'menu.show',                                lookup(:'namespace.controller.action.menu.show')
+    assert_equal 'namespace.menu.new',                       lookup(:'namespace.controller.action.menu.new')
+    assert_equal 'namespace.controller.menu.edit',           lookup(:'namespace.controller.action.menu.edit')
+    assert_equal 'namespace.controller.action.menu.destroy', lookup(:'namespace.controller.action.menu.destroy')
+  end
+end
diff --git a/app/server/vendor/i18n/test/backend/chain_test.rb b/app/server/vendor/i18n/test/backend/chain_test.rb
new file mode 100644
index 0000000..6b55413
--- /dev/null
+++ b/app/server/vendor/i18n/test/backend/chain_test.rb
@@ -0,0 +1,76 @@
+require 'test_helper'
+
+class I18nBackendChainTest < I18n::TestCase
+  def setup
+    @first  = backend(:en => {
+      :foo => 'Foo', :formats => { :short => 'short' }, :plural_1 => { :one => '%{count}' }, :dates => {:a => "A"}
+    })
+    @second = backend(:en => {
+      :bar => 'Bar', :formats => { :long => 'long' }, :plural_2 => { :one => 'one' }, :dates => {:a => "B", :b => "B"}
+    })
+    @chain  = I18n.backend = I18n::Backend::Chain.new(@first, @second)
+  end
+
+  test "looks up translations from the first chained backend" do
+    assert_equal 'Foo', @first.send(:translations)[:en][:foo]
+    assert_equal 'Foo', I18n.t(:foo)
+  end
+
+  test "looks up translations from the second chained backend" do
+    assert_equal 'Bar', @second.send(:translations)[:en][:bar]
+    assert_equal 'Bar', I18n.t(:bar)
+  end
+
+  test "defaults only apply to lookups on the last backend in the chain" do
+    assert_equal 'Foo', I18n.t(:foo, :default => 'Bah')
+    assert_equal 'Bar', I18n.t(:bar, :default => 'Bah')
+    assert_equal 'Bah', I18n.t(:bah, :default => 'Bah') # default kicks in only here
+  end
+
+  test "default" do
+    assert_equal 'Fuh',  I18n.t(:default => 'Fuh')
+    assert_equal 'Zero', I18n.t(:default => { :zero => 'Zero' }, :count => 0)
+    assert_equal({ :zero => 'Zero' }, I18n.t(:default => { :zero => 'Zero' }))
+    assert_equal 'Foo', I18n.t(:default => :foo)
+  end
+
+  test 'default is returned if translation is missing' do
+    assert_equal({}, I18n.t(:'i18n.transliterate.rule', :locale => 'en', :default => {}))
+  end
+
+  test "namespace lookup collects results from all backends" do
+    assert_equal({ :short => 'short', :long => 'long' }, I18n.t(:formats))
+  end
+
+  test "namespace lookup collects results from all backends and does not overwrite" do
+    assert_equal({ :a => "A", :b => "B" }, I18n.t(:dates))
+  end
+
+  test "namespace lookup with only the first backend returning a result" do
+    assert_equal({ :one => '%{count}' }, I18n.t(:plural_1))
+  end
+
+  test "pluralization still works" do
+    assert_equal '1',   I18n.t(:plural_1, :count => 1)
+    assert_equal 'one', I18n.t(:plural_2, :count => 1)
+  end
+
+  test "bulk lookup collects results from all backends" do
+    assert_equal ['Foo', 'Bar'], I18n.t([:foo, :bar])
+    assert_equal ['Foo', 'Bar', 'Bah'], I18n.t([:foo, :bar, :bah], :default => 'Bah')
+    assert_equal [{ :short => 'short', :long => 'long' }, { :one => 'one' }, 'Bah'], I18n.t([:formats, :plural_2, :bah], :default => 'Bah')
+  end
+
+  test "store_translations options are not dropped while transfering to backend" do
+    @first.expects(:store_translations).with(:foo, {:bar => :baz}, {:option => 'persists'})
+    I18n.backend.store_translations :foo, {:bar => :baz}, {:option => 'persists'}
+  end
+
+  protected
+
+    def backend(translations)
+      backend = I18n::Backend::Simple.new
+      translations.each { |locale, data| backend.store_translations(locale, data) }
+      backend
+    end
+end
diff --git a/app/server/vendor/i18n/test/backend/exceptions_test.rb b/app/server/vendor/i18n/test/backend/exceptions_test.rb
new file mode 100644
index 0000000..5b5aef9
--- /dev/null
+++ b/app/server/vendor/i18n/test/backend/exceptions_test.rb
@@ -0,0 +1,35 @@
+require 'test_helper'
+
+class I18nBackendExceptionsTest < I18n::TestCase
+  def setup
+    I18n.backend = I18n::Backend::Simple.new
+  end
+
+  test "throw message: MissingTranslation message from #translate includes the given scope and full key" do
+    exception = catch(:exception) do
+      I18n.t(:'baz.missing', :scope => :'foo.bar', :throw => true)
+    end
+    assert_equal "translation missing: en.foo.bar.baz.missing", exception.message
+  end
+
+  test "exceptions: MissingTranslationData message from #translate includes the given scope and full key" do
+    begin
+      I18n.t(:'baz.missing', :scope => :'foo.bar', :raise => true)
+    rescue I18n::MissingTranslationData => exception
+    end
+    assert_equal "translation missing: en.foo.bar.baz.missing", exception.message
+  end
+
+  test "exceptions: MissingTranslationData message from #localize includes the given scope and full key" do
+    begin
+      I18n.l(Time.now, :format => :foo)
+    rescue I18n::MissingTranslationData => exception
+    end
+    assert_equal "translation missing: en.time.formats.foo", exception.message
+  end
+
+  test "exceptions: MissingInterpolationArgument message includes missing key, provided keys and full string" do
+    exception = I18n::MissingInterpolationArgument.new('key', {:this => 'was given'}, 'string')
+    assert_equal 'missing interpolation argument "key" in "string" ({:this=>"was given"} given)', exception.message
+  end
+end
diff --git a/app/server/vendor/i18n/test/backend/fallbacks_test.rb b/app/server/vendor/i18n/test/backend/fallbacks_test.rb
new file mode 100644
index 0000000..8baeed6
--- /dev/null
+++ b/app/server/vendor/i18n/test/backend/fallbacks_test.rb
@@ -0,0 +1,146 @@
+require 'test_helper'
+
+class I18nBackendFallbacksTranslateTest < I18n::TestCase
+  class Backend < I18n::Backend::Simple
+    include I18n::Backend::Fallbacks
+  end
+
+  def setup
+    I18n.backend = Backend.new
+    store_translations(:en, :foo => 'Foo in :en', :bar => 'Bar in :en', :buz => 'Buz in :en')
+    store_translations(:de, :bar => 'Bar in :de', :baz => 'Baz in :de')
+    store_translations(:'de-DE', :baz => 'Baz in :de-DE')
+    store_translations(:'pt-BR', :baz => 'Baz in :pt-BR')
+  end
+
+  test "still returns an existing translation as usual" do
+    assert_equal 'Foo in :en', I18n.t(:foo, :locale => :en)
+    assert_equal 'Bar in :de', I18n.t(:bar, :locale => :de)
+    assert_equal 'Baz in :de-DE', I18n.t(:baz, :locale => :'de-DE')
+  end
+
+  test "returns the :en translation for a missing :de translation" do
+    assert_equal 'Foo in :en', I18n.t(:foo, :locale => :de)
+  end
+
+  test "returns the :de translation for a missing :'de-DE' translation" do
+    assert_equal 'Bar in :de', I18n.t(:bar, :locale => :'de-DE')
+  end
+
+  test "returns the :en translation for translation missing in both :de and :'de-De'" do
+    assert_equal 'Buz in :en', I18n.t(:buz, :locale => :'de-DE')
+  end
+
+  test "returns the :de translation for a missing :'de-DE' when :default is a String" do
+    assert_equal 'Bar in :de', I18n.t(:bar, :locale => :'de-DE', :default => "Default Bar")
+    assert_equal "Default Bar", I18n.t(:missing_bar, :locale => :'de-DE', :default => "Default Bar")
+  end
+
+  test "returns the :de translation for a missing :'de-DE' when defaults is a Symbol (which exists in :en)" do
+    assert_equal "Bar in :de", I18n.t(:bar, :locale => :'de-DE', :default => [:buz])
+  end
+
+  test "returns the :'de-DE' default :baz translation for a missing :'de-DE' (which exists in :de)" do
+    assert_equal "Baz in :de-DE", I18n.t(:bar, :locale => :'de-DE', :default => [:baz])
+  end
+
+  test "returns the :de translation for a missing :'de-DE' when :default is a Proc" do
+    assert_equal 'Bar in :de', I18n.t(:bar, :locale => :'de-DE', :default => Proc.new { "Default Bar" })
+    assert_equal "Default Bar", I18n.t(:missing_bar, :locale => :'de-DE', :default => Proc.new { "Default Bar" })
+  end
+
+  test "returns the :de translation for a missing :'de-DE' when :default is a Hash" do
+    assert_equal 'Bar in :de', I18n.t(:bar, :locale => :'de-DE', :default => {})
+    assert_equal({}, I18n.t(:missing_bar, :locale => :'de-DE', :default => {}))
+  end
+
+  test "returns the :'de-DE' default :baz translation for a missing :'de-DE' when defaults contains Symbol" do
+    assert_equal 'Baz in :de-DE', I18n.t(:missing_foo, :locale => :'de-DE', :default => [:baz, "Default Bar"])
+  end
+
+  test "returns the defaults translation for a missing :'de-DE' when defaults contains a String or Proc before Symbol" do
+    assert_equal "Default Bar", I18n.t(:missing_foo, :locale => :'de-DE', :default => [:missing_bar, "Default Bar", :baz])
+    assert_equal "Default Bar", I18n.t(:missing_foo, :locale => :'de-DE', :default => [:missing_bar, Proc.new { "Default Bar" }, :baz])
+  end
+
+  test "returns the default translation for a missing :'de-DE' and existing :de when default is a Hash" do
+    assert_equal 'Default 6 Bars', I18n.t(:missing_foo, :locale => :'de-DE', :default => [:missing_bar, {:other => "Default %{count} Bars"}, "Default Bar"], :count => 6)
+  end
+
+  test "raises I18n::MissingTranslationData exception when no translation was found" do
+    assert_raise(I18n::MissingTranslationData) { I18n.t(:faa, :locale => :en, :raise => true) }
+    assert_raise(I18n::MissingTranslationData) { I18n.t(:faa, :locale => :de, :raise => true) }
+  end
+
+  test "should ensure that default is not splitted on new line char" do
+    assert_equal "Default \n Bar", I18n.t(:missing_bar, :default => "Default \n Bar")
+  end
+
+  test "should not raise error when enforce_available_locales is true, :'pt' is missing and default is a Symbol" do
+    I18n.enforce_available_locales = true
+    begin
+      assert_equal 'Foo', I18n.t(:'model.attrs.foo', :locale => :'pt-BR', :default => [:'attrs.foo', "Foo"])
+    ensure
+      I18n.enforce_available_locales = false
+    end
+  end
+end
+
+class I18nBackendFallbacksLocalizeTest < I18n::TestCase
+  class Backend < I18n::Backend::Simple
+    include I18n::Backend::Fallbacks
+  end
+
+  def setup
+    I18n.backend = Backend.new
+    store_translations(:en, :date => { :formats => { :en => 'en' }, :day_names => %w(Sunday) })
+    store_translations(:de, :date => { :formats => { :de => 'de' } })
+  end
+
+  test "still uses an existing format as usual" do
+    assert_equal 'en', I18n.l(Date.today, :format => :en, :locale => :en)
+  end
+
+  test "looks up and uses a fallback locale's format for a key missing in the given locale (1)" do
+    assert_equal 'en', I18n.l(Date.today, :format => :en, :locale => :de)
+  end
+
+  test "looks up and uses a fallback locale's format for a key missing in the given locale (2)" do
+    assert_equal 'de', I18n.l(Date.today, :format => :de, :locale => :'de-DE')
+  end
+
+  test "still uses an existing day name translation as usual" do
+    assert_equal 'Sunday', I18n.l(Date.new(2010, 1, 3), :format => '%A', :locale => :en)
+  end
+
+  test "uses a fallback locale's translation for a key missing in the given locale" do
+    assert_equal 'Sunday', I18n.l(Date.new(2010, 1, 3), :format => '%A', :locale => :de)
+  end
+end
+
+class I18nBackendFallbacksWithChainTest < I18n::TestCase
+  class Backend < I18n::Backend::Simple
+    include I18n::Backend::Fallbacks
+  end
+
+  def setup
+    backend = Backend.new
+    backend.store_translations(:de, :foo => 'FOO')
+    backend.store_translations(:'pt-BR', :foo => 'Baz in :pt-BR')
+    I18n.backend = I18n::Backend::Chain.new(I18n::Backend::Simple.new, backend)
+    I18n.backend.class.send(:include, I18n::Backend::Fallbacks)
+  end
+
+  test "falls back from de-DE to de when there is no translation for de-DE available" do
+    assert_equal 'FOO', I18n.t(:foo, :locale => :'de-DE')
+  end
+
+  test "should not raise error when enforce_available_locales is true, :'pt' is missing and default is a Symbol" do
+    I18n.enforce_available_locales = true
+    begin
+      assert_equal 'Foo', I18n.t(:'model.attrs.foo', :locale => :'pt-BR', :default => [:'attrs.foo', "Foo"])
+    ensure
+      I18n.enforce_available_locales = false
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/test/backend/interpolation_compiler_test.rb b/app/server/vendor/i18n/test/backend/interpolation_compiler_test.rb
new file mode 100644
index 0000000..cffe28f
--- /dev/null
+++ b/app/server/vendor/i18n/test/backend/interpolation_compiler_test.rb
@@ -0,0 +1,118 @@
+require 'test_helper'
+
+class InterpolationCompilerTest < I18n::TestCase
+  Compiler = I18n::Backend::InterpolationCompiler::Compiler
+
+  def compile_and_interpolate(str, values = {})
+    Compiler.compile_if_an_interpolation(str).i18n_interpolate(values)
+  end
+
+  def assert_escapes_interpolation_key(expected, malicious_str)
+    assert_equal(expected, Compiler.send(:escape_key_sym, malicious_str))
+  end
+
+  def test_escape_key_properly_escapes
+    assert_escapes_interpolation_key ':"\""',       '"'
+    assert_escapes_interpolation_key ':"\\\\"',     '\\'
+    assert_escapes_interpolation_key ':"\\\\\""',   '\\"'
+    assert_escapes_interpolation_key ':"\#{}"',     '#{}'
+    assert_escapes_interpolation_key ':"\\\\\#{}"', '\#{}'
+  end
+
+  def assert_escapes_plain_string(expected, plain_str)
+    assert_equal expected, Compiler.send(:escape_plain_str, plain_str)
+  end
+
+  def test_escape_plain_string_properly_escapes
+    assert_escapes_plain_string '\\"',    '"'
+    assert_escapes_plain_string '\'',     '\''
+    assert_escapes_plain_string '\\#',    '#'
+    assert_escapes_plain_string '\\#{}',  '#{}'
+    assert_escapes_plain_string '\\\\\\"','\\"'
+  end
+
+  def test_non_interpolated_strings_or_arrays_dont_get_compiled
+    ['abc', '\\{a}}', '{a}}', []].each do |obj|
+      Compiler.compile_if_an_interpolation(obj)
+      assert_equal false, obj.respond_to?(:i18n_interpolate)
+    end
+  end
+
+  def test_interpolated_string_gets_compiled
+    assert_equal '-A-', compile_and_interpolate('-%{a}-', :a => 'A')
+  end
+
+  def assert_handles_key(str, key)
+    assert_equal 'A', compile_and_interpolate(str, key => 'A')
+  end
+
+  def test_compiles_fancy_keys
+    assert_handles_key('%{\}',       :'\\'    )
+    assert_handles_key('%{#}',       :'#'     )
+    assert_handles_key('%{#{}',      :'#{'    )
+    assert_handles_key('%{#$SAFE}',  :'#$SAFE')
+    assert_handles_key('%{\000}',    :'\000'  )
+    assert_handles_key('%{\'}',      :'\''    )
+    assert_handles_key('%{\'\'}',    :'\'\''  )
+    assert_handles_key('%{a.b}',     :'a.b'   )
+    assert_handles_key('%{ }',       :' '     )
+    assert_handles_key('%{:}',       :':'     )
+    assert_handles_key("%{:''}",     :":''"   )
+    assert_handles_key('%{:"}',      :':"'    )
+  end
+
+  def test_str_containing_only_escaped_interpolation_is_handled_correctly
+    assert_equal 'abc %{x}', compile_and_interpolate('abc %%{x}')
+  end
+
+  def test_handles_weird_strings
+    assert_equal '#{} a',         compile_and_interpolate('#{} %{a}',         :a    => 'a')
+    assert_equal '"#{abc}"',      compile_and_interpolate('"#{ab%{a}c}"',     :a    => '' )
+    assert_equal 'a}',            compile_and_interpolate('%{{a}}',           :'{a' => 'a')
+    assert_equal '"',             compile_and_interpolate('"%{a}',            :a    => '' )
+    assert_equal 'a%{a}',         compile_and_interpolate('%{a}%%{a}',        :a    => 'a')
+    assert_equal '%%{a}',         compile_and_interpolate('%%%{a}')
+    assert_equal '\";eval("a")',  compile_and_interpolate('\";eval("%{a}")',  :a    => 'a')
+    assert_equal '\";eval("a")',  compile_and_interpolate('\";eval("a")%{a}', :a    => '' )
+    assert_equal "\na",           compile_and_interpolate("\n%{a}",           :a    => 'a')
+  end
+
+  def test_raises_exception_when_argument_is_missing
+    assert_raise(I18n::MissingInterpolationArgument) do
+      compile_and_interpolate('%{first} %{last}', :first => 'first')
+    end
+  end
+
+  def test_custom_missing_interpolation_argument_handler
+    old_handler = I18n.config.missing_interpolation_argument_handler
+    I18n.config.missing_interpolation_argument_handler = lambda do |key, values, string|
+      "missing key is #{key}, values are #{values.inspect}, given string is '#{string}'"
+    end
+    assert_equal %|first missing key is last, values are {:first=>"first"}, given string is '%{first} %{last}'|,
+        compile_and_interpolate('%{first} %{last}', :first => 'first')
+  ensure
+    I18n.config.missing_interpolation_argument_handler = old_handler
+  end
+end
+
+class I18nBackendInterpolationCompilerTest < I18n::TestCase
+  class Backend < I18n::Backend::Simple
+    include I18n::Backend::InterpolationCompiler
+  end
+
+  include I18n::Tests::Interpolation
+
+  def setup
+    I18n.backend = Backend.new
+    super
+  end
+
+  # pre-compile default strings to make sure we are testing I18n::Backend::InterpolationCompiler
+  def interpolate(*args)
+    options = args.last.kind_of?(Hash) ? args.last : {}
+    if default_str = options[:default]
+      I18n::Backend::InterpolationCompiler::Compiler.compile_if_an_interpolation(default_str)
+    end
+    super
+  end
+end
diff --git a/app/server/vendor/i18n/test/backend/key_value_test.rb b/app/server/vendor/i18n/test/backend/key_value_test.rb
new file mode 100644
index 0000000..b7fe876
--- /dev/null
+++ b/app/server/vendor/i18n/test/backend/key_value_test.rb
@@ -0,0 +1,46 @@
+require 'test_helper'
+
+I18n::TestCase.setup_rufus_tokyo
+
+class I18nBackendKeyValueTest < I18n::TestCase
+  def setup_backend!(subtree=true)
+    I18n.backend = I18n::Backend::KeyValue.new(Rufus::Tokyo::Cabinet.new('*'), subtree)
+    store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' })
+  end
+
+  def assert_flattens(expected, nested, escape=true, subtree=true)
+    assert_equal expected, I18n.backend.flatten_translations("en", nested, escape, subtree)
+  end
+
+  test "hash flattening works" do
+    setup_backend!
+    assert_flattens(
+      {:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}, :"b.f" => {:x=>"x"}, :"b.c"=>"c", :"b.f.x"=>"x", :"b.d"=>"d"},
+      {:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}}
+    )
+    assert_flattens({:a=>{:b =>['a', 'b']}, :"a.b"=>['a', 'b']}, {:a=>{:b =>['a', 'b']}})
+    assert_flattens({:"a\001b" => "c"}, {:"a.b" => "c"})
+    assert_flattens({:"a.b"=>['a', 'b']}, {:a=>{:b =>['a', 'b']}}, true, false)
+    assert_flattens({:"a.b" => "c"}, {:"a.b" => "c"}, false)
+  end
+
+  test "store_translations handle subtrees by default" do
+    setup_backend!
+    assert_equal({ :bar => 'bar', :baz => 'baz' }, I18n.t("foo"))
+  end
+
+  test "store_translations merge subtrees accordingly" do
+    setup_backend!
+    store_translations(:en, :foo => { :baz => "BAZ"})
+    assert_equal('BAZ', I18n.t("foo.baz"))
+    assert_equal({ :bar => 'bar', :baz => 'BAZ' }, I18n.t("foo"))
+  end
+
+  test "store_translations does not handle subtrees if desired" do
+    setup_backend!(false)
+    assert_raise I18n::MissingTranslationData do
+      I18n.t("foo", :raise => true)
+    end
+  end
+
+end if defined?(Rufus::Tokyo::Cabinet)
diff --git a/app/server/vendor/i18n/test/backend/memoize_test.rb b/app/server/vendor/i18n/test/backend/memoize_test.rb
new file mode 100644
index 0000000..a8a2e11
--- /dev/null
+++ b/app/server/vendor/i18n/test/backend/memoize_test.rb
@@ -0,0 +1,47 @@
+require 'test_helper'
+
+require 'backend/simple_test'
+
+class I18nBackendMemoizeTest < I18nBackendSimpleTest
+  module MemoizeSpy
+    attr_accessor :spy_calls
+
+    def available_locales
+      self.spy_calls = (self.spy_calls || 0) + 1
+      super
+    end
+  end
+
+  class MemoizeBackend < I18n::Backend::Simple
+    include MemoizeSpy
+    include I18n::Backend::Memoize
+  end
+
+  def setup
+    super
+    I18n.backend = MemoizeBackend.new
+  end
+
+  def test_memoizes_available_locales
+    I18n.backend.spy_calls = 0
+    assert_equal I18n.available_locales, I18n.available_locales
+    assert_equal 1, I18n.backend.spy_calls
+  end
+
+  def test_resets_available_locales_on_reload!
+    I18n.available_locales
+    I18n.backend.spy_calls = 0
+    I18n.reload!
+    assert_equal I18n.available_locales, I18n.available_locales
+    assert_equal 1, I18n.backend.spy_calls
+  end
+
+  def test_resets_available_locales_on_store_translations
+    I18n.available_locales
+    I18n.backend.spy_calls = 0
+    I18n.backend.store_translations(:copa, :ca => :bana)
+    assert_equal I18n.available_locales, I18n.available_locales
+    assert I18n.available_locales.include?(:copa)
+    assert_equal 1, I18n.backend.spy_calls
+  end
+end
diff --git a/app/server/vendor/i18n/test/backend/metadata_test.rb b/app/server/vendor/i18n/test/backend/metadata_test.rb
new file mode 100644
index 0000000..5ccb646
--- /dev/null
+++ b/app/server/vendor/i18n/test/backend/metadata_test.rb
@@ -0,0 +1,47 @@
+require 'test_helper'
+
+class I18nBackendMetadataTest < I18n::TestCase
+  class Backend < I18n::Backend::Simple
+    include I18n::Backend::Metadata
+  end
+
+  def setup
+    I18n.backend = Backend.new
+    store_translations(:en, :foo => 'Hi %{name}')
+  end
+
+  test "translation strings carry metadata" do
+    translation = I18n.t(:foo, :name => 'David')
+    assert translation.respond_to?(:translation_metadata)
+    assert translation.translation_metadata.is_a?(Hash)
+  end
+
+  test "translate adds the locale to metadata on Strings" do
+    assert_equal :en, I18n.t(:foo, :name => 'David', :locale => :en).translation_metadata[:locale]
+  end
+
+  test "translate adds the key to metadata on Strings" do
+    assert_equal :foo, I18n.t(:foo, :name => 'David').translation_metadata[:key]
+  end
+
+  test "translate adds the default to metadata on Strings" do
+    assert_equal 'bar', I18n.t(:foo, :default => 'bar', :name => '').translation_metadata[:default]
+  end
+
+  test "translation adds the interpolation values to metadata on Strings" do
+    assert_equal({:name => 'David'}, I18n.t(:foo, :name => 'David').translation_metadata[:values])
+  end
+
+  test "interpolation adds the original string to metadata on Strings" do
+    assert_equal('Hi %{name}', I18n.t(:foo, :name => 'David').translation_metadata[:original])
+  end
+
+  test "pluralization adds the count to metadata on Strings" do
+    assert_equal(1, I18n.t(:missing, :count => 1, :default => { :one => 'foo' }).translation_metadata[:count])
+  end
+
+  test "metadata works with frozen values" do
+    assert_equal(1, I18n.t(:missing, :count => 1, :default => 'foo'.freeze).translation_metadata[:count])
+  end
+end
+
diff --git a/app/server/vendor/i18n/test/backend/pluralization_test.rb b/app/server/vendor/i18n/test/backend/pluralization_test.rb
new file mode 100644
index 0000000..de318f1
--- /dev/null
+++ b/app/server/vendor/i18n/test/backend/pluralization_test.rb
@@ -0,0 +1,44 @@
+require 'test_helper'
+
+class I18nBackendPluralizationTest < I18n::TestCase
+  class Backend < I18n::Backend::Simple
+    include I18n::Backend::Pluralization
+    include I18n::Backend::Fallbacks
+  end
+
+  def setup
+    I18n.backend = Backend.new
+    @rule = lambda { |n| n == 1 ? :one : n == 0 || (2..10).include?(n % 100) ? :few : (11..19).include?(n % 100) ? :many : :other }
+    store_translations(:xx, :i18n => { :plural => { :rule => @rule } })
+    @entry = { :zero => 'zero', :one => 'one', :few => 'few', :many => 'many', :other => 'other' }
+  end
+
+  test "pluralization picks a pluralizer from :'i18n.pluralize'" do
+    assert_equal @rule, I18n.backend.send(:pluralizer, :xx)
+  end
+
+  test "pluralization picks :one for 1" do
+    assert_equal 'one', I18n.t(:count => 1, :default => @entry, :locale => :xx)
+  end
+
+  test "pluralization picks :few for 2" do
+    assert_equal 'few', I18n.t(:count => 2, :default => @entry, :locale => :xx)
+  end
+
+  test "pluralization picks :many for 11" do
+    assert_equal 'many', I18n.t(:count => 11, :default => @entry, :locale => :xx)
+  end
+
+  test "pluralization picks zero for 0 if the key is contained in the data" do
+    assert_equal 'zero', I18n.t(:count => 0, :default => @entry, :locale => :xx)
+  end
+
+  test "pluralization picks few for 0 if the key is not contained in the data" do
+    @entry.delete(:zero)
+    assert_equal 'few', I18n.t(:count => 0, :default => @entry, :locale => :xx)
+  end
+
+  test "Fallbacks can pick up rules from fallback locales, too" do
+    assert_equal @rule, I18n.backend.send(:pluralizer, :'xx-XX')
+  end
+end
diff --git a/app/server/vendor/i18n/test/backend/simple_test.rb b/app/server/vendor/i18n/test/backend/simple_test.rb
new file mode 100644
index 0000000..777a77c
--- /dev/null
+++ b/app/server/vendor/i18n/test/backend/simple_test.rb
@@ -0,0 +1,83 @@
+require 'test_helper'
+
+class I18nBackendSimpleTest < I18n::TestCase
+  def setup
+    I18n.backend = I18n::Backend::Simple.new
+    I18n.load_path = [locales_dir + '/en.yml']
+  end
+
+  # useful because this way we can use the backend with no key for interpolation/pluralization
+  test "simple backend translate: given nil as a key it still interpolations the default value" do
+    assert_equal "Hi David", I18n.t(nil, :default => "Hi %{name}", :name => "David")
+  end
+
+  # loading translations
+  test "simple load_translations: given an unknown file type it raises I18n::UnknownFileType" do
+    assert_raise(I18n::UnknownFileType) { I18n.backend.load_translations("#{locales_dir}/en.xml") }
+  end
+
+  test "simple load_translations: given a Ruby file name it does not raise anything" do
+    assert_nothing_raised { I18n.backend.load_translations("#{locales_dir}/en.rb") }
+  end
+
+  test "simple load_translations: given no argument, it uses I18n.load_path" do
+    I18n.backend.load_translations
+    assert_equal({ :en => { :foo => { :bar => 'baz' } } }, I18n.backend.send(:translations))
+  end
+
+  test "simple load_rb: loads data from a Ruby file" do
+    data = I18n.backend.send(:load_rb, "#{locales_dir}/en.rb")
+    assert_equal({ :en => { :fuh => { :bah => 'bas' } } }, data)
+  end
+
+  test "simple load_yml: loads data from a YAML file" do
+    data = I18n.backend.send(:load_yml, "#{locales_dir}/en.yml")
+    assert_equal({ 'en' => { 'foo' => { 'bar' => 'baz' } } }, data)
+  end
+
+  test "simple load_translations: loads data from known file formats" do
+    I18n.backend = I18n::Backend::Simple.new
+    I18n.backend.load_translations("#{locales_dir}/en.rb", "#{locales_dir}/en.yml")
+    expected = { :en => { :fuh => { :bah => "bas" }, :foo => { :bar => "baz" } } }
+    assert_equal expected, translations
+  end
+
+  test "simple load_translations: given file names as array it does not raise anything" do
+    assert_nothing_raised { I18n.backend.load_translations(["#{locales_dir}/en.rb", "#{locales_dir}/en.yml"]) }
+  end
+
+  # storing translations
+
+  test "simple store_translations: stores translations, ... no, really :-)" do
+    store_translations :'en', :foo => 'bar'
+    assert_equal Hash[:'en', {:foo => 'bar'}], translations
+  end
+
+  test "simple store_translations: deep_merges with existing translations" do
+    store_translations :'en', :foo => {:bar => 'bar'}
+    store_translations :'en', :foo => {:baz => 'baz'}
+    assert_equal Hash[:'en', {:foo => {:bar => 'bar', :baz => 'baz'}}], translations
+  end
+
+  test "simple store_translations: converts the given locale to a Symbol" do
+    store_translations 'en', :foo => 'bar'
+    assert_equal Hash[:'en', {:foo => 'bar'}], translations
+  end
+
+  test "simple store_translations: converts keys to Symbols" do
+    store_translations 'en', 'foo' => {'bar' => 'bar', 'baz' => 'baz'}
+    assert_equal Hash[:'en', {:foo => {:bar => 'bar', :baz => 'baz'}}], translations
+  end
+
+  # reloading translations
+
+  test "simple reload_translations: unloads translations" do
+    I18n.backend.reload!
+    assert_nil translations
+  end
+
+  test "simple reload_translations: uninitializes the backend" do
+    I18n.backend.reload!
+    assert_equal I18n.backend.initialized?, false
+  end
+end
diff --git a/app/server/vendor/i18n/test/backend/transliterator_test.rb b/app/server/vendor/i18n/test/backend/transliterator_test.rb
new file mode 100644
index 0000000..4012dce
--- /dev/null
+++ b/app/server/vendor/i18n/test/backend/transliterator_test.rb
@@ -0,0 +1,85 @@
+# encoding: utf-8
+require 'test_helper'
+
+class I18nBackendTransliterator < I18n::TestCase
+  def setup
+    I18n.backend = I18n::Backend::Simple.new
+    @proc = lambda { |n| n.upcase }
+    @hash = { "ü" => "ue", "ö" => "oe", "a" => "a" }
+    @transliterator = I18n::Backend::Transliterator.get
+  end
+
+  test "transliteration rule can be a proc" do
+    store_translations(:xx, :i18n => {:transliterate => {:rule => @proc}})
+    assert_equal "HELLO", I18n.backend.transliterate(:xx, "hello")
+  end
+
+  test "transliteration rule can be a hash" do
+    store_translations(:xx, :i18n => {:transliterate => {:rule => @hash}})
+    assert_equal "ue", I18n.backend.transliterate(:xx, "ü")
+  end
+
+  test "transliteration rule must be a proc or hash" do
+    store_translations(:xx, :i18n => {:transliterate => {:rule => ""}})
+    assert_raise I18n::ArgumentError do
+      I18n.backend.transliterate(:xx, "ü")
+    end
+  end
+
+  test "transliterator defaults to latin => ascii when no rule is given" do
+    assert_equal "AEroskobing", I18n.backend.transliterate(:xx, "Ærøskøbing")
+  end
+
+  test "default transliterator should not modify ascii characters" do
+    (0..127).each do |byte|
+      char = [byte].pack("U")
+      assert_equal char, @transliterator.transliterate(char)
+    end
+  end
+
+  test "default transliterator correctly transliterates latin characters" do
+    # create string with range of Unicode's western characters with
+    # diacritics, excluding the division and multiplication signs which for
+    # some reason or other are floating in the middle of all the letters.
+    string = (0xC0..0x17E).to_a.reject {|c| [0xD7, 0xF7].include? c}.pack("U*")
+    string.split(//) do |char|
+      assert_match %r{^[a-zA-Z']*$}, @transliterator.transliterate(string)
+    end
+  end
+
+  test "should replace non-ASCII chars not in map with a replacement char" do
+    assert_equal "abc?", @transliterator.transliterate("abcſ")
+  end
+
+  test "can replace non-ASCII chars not in map with a custom replacement string" do
+    assert_equal "abc#", @transliterator.transliterate("abcſ", "#")
+  end
+
+  if RUBY_VERSION >= "1.9"
+    test "default transliterator raises errors for invalid UTF-8" do
+      assert_raise ArgumentError do
+        @transliterator.transliterate("a\x92b")
+      end
+    end
+  end
+
+  test "I18n.transliterate should transliterate using a default transliterator" do
+    assert_equal "aeo", I18n.transliterate("áèö")
+  end
+
+  test "I18n.transliterate should transliterate using a locale" do
+    store_translations(:xx, :i18n => {:transliterate => {:rule => @hash}})
+    assert_equal "ue", I18n.transliterate("ü", :locale => :xx)
+  end
+
+  test "default transliterator fails with custom rules with uncomposed input" do
+    char = [117, 776].pack("U*") # "ü" as ASCII "u" plus COMBINING DIAERESIS
+    transliterator = I18n::Backend::Transliterator.get(@hash)
+    assert_not_equal "ue", transliterator.transliterate(char)
+  end
+
+  test "DEFAULT_APPROXIMATIONS is frozen to prevent concurrency issues" do
+    assert I18n::Backend::Transliterator::HashTransliterator::DEFAULT_APPROXIMATIONS.frozen?
+  end
+
+end
diff --git a/app/server/vendor/i18n/test/core_ext/hash_test.rb b/app/server/vendor/i18n/test/core_ext/hash_test.rb
new file mode 100644
index 0000000..8309336
--- /dev/null
+++ b/app/server/vendor/i18n/test/core_ext/hash_test.rb
@@ -0,0 +1,30 @@
+require 'test_helper'
+require 'i18n/core_ext/hash'
+
+class I18nCoreExtHashInterpolationTest < I18n::TestCase
+  test "#deep_symbolize_keys" do
+    hash = { 'foo' => { 'bar' => { 'baz' => 'bar' } } }
+    expected = { :foo => { :bar => { :baz => 'bar' } } }
+    assert_equal expected, hash.deep_symbolize_keys
+  end
+
+  test "#slice" do
+    hash = { :foo => 'bar',  :baz => 'bar' }
+    expected = { :foo => 'bar' }
+    assert_equal expected, hash.slice(:foo)
+  end
+
+  test "#except" do
+    hash = { :foo => 'bar',  :baz => 'bar' }
+    expected = { :foo => 'bar' }
+    assert_equal expected, hash.except(:baz)
+  end
+
+  test "#deep_merge!" do
+    hash = { :foo => { :bar => { :baz => 'bar' } }, :baz => 'bar' }
+    hash.deep_merge!(:foo => { :bar => { :baz => 'foo' } })
+
+    expected = { :foo => { :bar => { :baz => 'foo' } }, :baz => 'bar' }
+    assert_equal expected, hash
+  end
+end
diff --git a/app/server/vendor/i18n/test/core_ext/string/interpolate_test.rb b/app/server/vendor/i18n/test/core_ext/string/interpolate_test.rb
new file mode 100644
index 0000000..a1ed9c4
--- /dev/null
+++ b/app/server/vendor/i18n/test/core_ext/string/interpolate_test.rb
@@ -0,0 +1,99 @@
+require 'test_helper'
+
+# thanks to Masao's String extensions these should work the same in
+# Ruby 1.8 (patched) and Ruby 1.9 (native)
+# some tests taken from Masao's tests
+# http://github.com/mutoh/gettext/blob/edbbe1fa8238fa12c7f26f2418403015f0270e47/test/test_string.rb
+
+class I18nCoreExtStringInterpolationTest < I18n::TestCase
+  test "String interpolates a single argument" do
+    assert_equal "Masao", "%s" % "Masao"
+  end
+
+  test "String interpolates an array argument" do
+    assert_equal "1 message", "%d %s" % [1, 'message']
+  end
+
+  test "String interpolates a hash argument w/ named placeholders" do
+    assert_equal "Masao Mutoh", "%{first} %{last}" % { :first => 'Masao', :last => 'Mutoh' }
+  end
+
+  test "String interpolates a hash argument w/ named placeholders (reverse order)" do
+    assert_equal "Mutoh, Masao", "%{last}, %{first}" % { :first => 'Masao', :last => 'Mutoh' }
+  end
+
+  test "String interpolates named placeholders with sprintf syntax" do
+    assert_equal "10, 43.4", "%<integer>d, %<float>.1f" % {:integer => 10, :float => 43.4}
+  end
+
+  test "String interpolates named placeholders with sprintf syntax, does not recurse" do
+    assert_equal "%<not_translated>s", "%{msg}" % { :msg => '%<not_translated>s', :not_translated => 'should not happen' }
+  end
+
+  test "String interpolation does not replace anything when no placeholders are given" do
+    assert_equal("aaa", "aaa" % {:num => 1})
+    assert_equal("bbb", "bbb" % [1])
+  end
+
+  test "String interpolation sprintf behaviour equals Ruby 1.9 behaviour" do
+    assert_equal("1", "%<num>d" % {:num => 1})
+    assert_equal("0b1", "%<num>#b" % {:num => 1})
+    assert_equal("foo", "%<msg>s" % {:msg => "foo"})
+    assert_equal("1.000000", "%<num>f" % {:num => 1.0})
+    assert_equal("  1", "%<num>3.0f" % {:num => 1.0})
+    assert_equal("100.00", "%<num>2.2f" % {:num => 100.0})
+    assert_equal("0x64", "%<num>#x" % {:num => 100.0})
+    assert_raise(ArgumentError) { "%<num>,d" % {:num => 100} }
+    assert_raise(ArgumentError) { "%<num>/d" % {:num => 100} }
+  end
+
+  test "String interpolation old-style sprintf still works" do
+    assert_equal("foo 1.000000", "%s %f" % ["foo", 1.0])
+  end
+
+  test "String interpolation raises an ArgumentError when the string has extra placeholders (Array)" do
+    assert_raise(ArgumentError) do # Ruby 1.9 msg: "too few arguments"
+      "%s %s" % %w(Masao)
+    end
+  end
+
+  test "String interpolation raises a KeyError when the string has extra placeholders (Hash)" do
+    assert_raise(KeyError) do # Ruby 1.9 msg: "key not found"
+      "%{first} %{last}" % { :first => 'Masao' }
+    end
+  end
+
+  test "String interpolation does not raise when passed extra values (Array)" do
+    assert_nothing_raised do
+      assert_equal "Masao", "%s" % %w(Masao Mutoh)
+    end
+  end
+
+  test "String interpolation does not raise when passed extra values (Hash)" do
+    assert_nothing_raised do
+      assert_equal "Masao Mutoh", "%{first} %{last}" % { :first => 'Masao', :last => 'Mutoh', :salutation => 'Mr.' }
+    end
+  end
+
+  test "% acts as escape character in String interpolation" do
+    assert_equal "%{first}", "%%{first}" % { :first => 'Masao' }
+    assert_equal("% 1", "%% %<num>d" % {:num => 1.0})
+    assert_equal("%{num} %<num>d", "%%{num} %%<num>d" % {:num => 1})
+  end
+
+  test "% can be used in Ruby's own sprintf behavior" do
+    assert_equal "70%", "%d%%" % 70
+    assert_equal "70-100%", "%d-%d%%" % [70, 100]
+    assert_equal "+2.30%", "%+.2f%%" % 2.3
+  end
+
+  def test_sprintf_mix_unformatted_and_formatted_named_placeholders
+    assert_equal("foo 1.000000", "%{name} %<num>f" % {:name => "foo", :num => 1.0})
+  end
+
+  def test_string_interpolation_raises_an_argument_error_when_mixing_named_and_unnamed_placeholders
+    assert_raise(ArgumentError) { "%{name} %f" % [1.0] }
+    assert_raise(ArgumentError) { "%{name} %f" % [1.0, 2.0] }
+  end
+end
+
diff --git a/app/server/vendor/i18n/test/gettext/api_test.rb b/app/server/vendor/i18n/test/gettext/api_test.rb
new file mode 100644
index 0000000..ac4edaf
--- /dev/null
+++ b/app/server/vendor/i18n/test/gettext/api_test.rb
@@ -0,0 +1,206 @@
+# encoding: utf-8
+require 'test_helper'
+require 'i18n/gettext/helpers'
+
+include I18n::Gettext::Helpers
+
+class I18nGettextApiTest < I18n::TestCase
+  def setup
+    I18n.locale = :en
+    I18n.backend.store_translations :de, {
+      'Hi Gettext!' => 'Hallo Gettext!',
+      'Sentence 1. Sentence 2.' => 'Satz 1. Satz 2.',
+      "An apple" => { :one => 'Ein Apfel', :other => '%{count} Äpfel' },
+      :special => { "A special apple" => { :one => 'Ein spezieller Apfel', :other => '%{count} spezielle Äpfel' } },
+      :foo => { :bar => 'bar-de' },
+      'foo.bar' => 'Foo Bar'
+    }, :separator => '|'
+  end
+
+  # gettext
+  def test_gettext_uses_msg_as_default
+    assert_equal 'Hi Gettext!', _('Hi Gettext!')
+  end
+
+  def test_gettext_uses_msg_as_key
+    I18n.locale = :de
+    assert_equal 'Hallo Gettext!', gettext('Hi Gettext!')
+    assert_equal 'Hallo Gettext!', _('Hi Gettext!')
+  end
+
+  def test_gettext_uses_msg_containing_dots_as_default
+    assert_equal 'Sentence 1. Sentence 2.', gettext('Sentence 1. Sentence 2.')
+    assert_equal 'Sentence 1. Sentence 2.', _('Sentence 1. Sentence 2.')
+  end
+
+  def test_gettext_uses_msg_containing_dots_as_key
+    I18n.locale = :de
+    assert_equal 'Satz 1. Satz 2.', gettext('Sentence 1. Sentence 2.')
+    assert_equal 'Satz 1. Satz 2.', _('Sentence 1. Sentence 2.')
+  end
+
+  # sgettext
+  def test_sgettext_defaults_to_the_last_token_of_a_scoped_msgid
+    assert_equal 'bar', sgettext('foo|bar')
+    assert_equal 'bar', s_('foo|bar')
+  end
+
+  def test_sgettext_looks_up_a_scoped_translation
+    I18n.locale = :de
+    assert_equal 'bar-de', sgettext('foo|bar')
+    assert_equal 'bar-de', s_('foo|bar')
+  end
+
+  def test_sgettext_ignores_dots
+    I18n.locale = :de
+    assert_equal 'Foo Bar', sgettext('foo.bar')
+    assert_equal 'Foo Bar', s_('foo.bar')
+  end
+
+  # pgettext
+  def test_pgettext_defaults_to_msgid
+    assert_equal 'bar', pgettext('foo', 'bar')
+    assert_equal 'bar', p_('foo', 'bar')
+  end
+
+  def test_pgettext_looks_up_a_scoped_translation
+    I18n.locale = :de
+    assert_equal 'bar-de', pgettext('foo', 'bar')
+    assert_equal 'bar-de', p_('foo', 'bar')
+  end
+
+  # ngettext
+  def test_ngettext_looks_up_msg_id_as_default_singular
+    assert_equal 'An apple', ngettext('An apple', '%{count} apples', 1)
+    assert_equal 'An apple', n_('An apple', '%{count} apples', 1)
+  end
+
+  def test_ngettext_looks_up_msg_id_plural_as_default_plural
+    assert_equal '2 apples', ngettext('An apple', '%{count} apples', 2)
+    assert_equal '2 apples', n_('An apple', '%{count} apples', 2)
+  end
+
+  def test_ngettext_looks_up_a_singular
+    I18n.locale = :de
+    assert_equal 'Ein Apfel', ngettext('An apple', '%{count} apples', 1)
+    assert_equal 'Ein Apfel', n_('An apple', '%{count} apples', 1)
+  end
+
+  def test_ngettext_looks_up_a_plural
+    I18n.locale = :de
+    assert_equal '2 Äpfel', ngettext('An apple', '%{count} apples', 2)
+    assert_equal '2 Äpfel', n_('An apple', '%{count} apples', 2)
+  end
+
+  def test_ngettext_looks_up_msg_id_as_default_singular_with_alternative_syntax
+    assert_equal 'An apple', ngettext(['An apple', '%{count} apples'], 1)
+    assert_equal 'An apple', n_(['An apple', '%{count} apples'], 1)
+  end
+
+  def test_ngettext_looks_up_msg_id_plural_as_default_plural_with_alternative_syntax
+    assert_equal '2 apples', ngettext(['An apple', '%{count} apples'], 2)
+    assert_equal '2 apples', n_(['An apple', '%{count} apples'], 2)
+  end
+
+  def test_ngettext_looks_up_a_singular_with_alternative_syntax
+    I18n.locale = :de
+    assert_equal 'Ein Apfel', ngettext(['An apple', '%{count} apples'], 1)
+    assert_equal 'Ein Apfel', n_(['An apple', '%{count} apples'], 1)
+  end
+
+  def test_ngettext_looks_up_a_plural_with_alternative_syntax
+    I18n.locale = :de
+    assert_equal '2 Äpfel', ngettext(['An apple', '%{count} apples'], 2)
+    assert_equal '2 Äpfel', n_(['An apple', '%{count} apples'], 2)
+  end
+
+  # nsgettext
+  def test_nsgettext_looks_up_msg_id_as_default_singular
+    assert_equal 'A special apple', nsgettext('special|A special apple', '%{count} special apples', 1)
+    assert_equal 'A special apple', ns_('special|A special apple', '%{count} special apples', 1)
+  end
+
+  def test_nsgettext_looks_up_msg_id_plural_as_default_plural
+    assert_equal '2 special apples', nsgettext('special|A special apple', '%{count} special apples', 2)
+    assert_equal '2 special apples', ns_('special|A special apple', '%{count} special apples', 2)
+  end
+
+  def test_nsgettext_looks_up_a_singular
+    I18n.locale = :de
+    assert_equal 'Ein spezieller Apfel', nsgettext('special|A special apple', '%{count} special apples', 1)
+    assert_equal 'Ein spezieller Apfel', ns_('special|A special apple', '%{count} special apples', 1)
+  end
+
+  def test_nsgettext_looks_up_a_plural
+    I18n.locale = :de
+    assert_equal '2 spezielle Äpfel', nsgettext('special|A special apple', '%{count} special apples', 2)
+    assert_equal '2 spezielle Äpfel', ns_('special|A special apple', '%{count} special apples', 2)
+  end
+
+  def test_nsgettext_looks_up_msg_id_as_default_singular_with_alternative_syntax
+    assert_equal 'A special apple', nsgettext(['special|A special apple', '%{count} special apples'], 1)
+    assert_equal 'A special apple', ns_(['special|A special apple', '%{count} special apples'], 1)
+  end
+
+  def test_nsgettext_looks_up_msg_id_plural_as_default_plural_with_alternative_syntax
+    assert_equal '2 special apples', nsgettext(['special|A special apple', '%{count} special apples'], 2)
+    assert_equal '2 special apples', ns_(['special|A special apple', '%{count} special apples'], 2)
+  end
+
+  def test_nsgettext_looks_up_a_singular_with_alternative_syntax
+    I18n.locale = :de
+    assert_equal 'Ein spezieller Apfel', nsgettext(['special|A special apple', '%{count} special apples'], 1)
+    assert_equal 'Ein spezieller Apfel', ns_(['special|A special apple', '%{count} special apples'], 1)
+  end
+
+  def test_nsgettext_looks_up_a_plural_with_alternative_syntax
+    I18n.locale = :de
+    assert_equal '2 spezielle Äpfel', nsgettext(['special|A special apple', '%{count} special apples'], 2)
+    assert_equal '2 spezielle Äpfel', ns_(['special|A special apple', '%{count} special apples'], 2)
+  end
+
+  # npgettext
+  def test_npgettext_looks_up_msg_id_as_default_singular
+    assert_equal 'A special apple', npgettext('special', 'A special apple', '%{count} special apples', 1)
+    assert_equal 'A special apple', np_('special', 'A special apple', '%{count} special apples', 1)
+  end
+
+  def test_npgettext_looks_up_msg_id_plural_as_default_plural
+    assert_equal '2 special apples', npgettext('special', 'A special apple', '%{count} special apples', 2)
+    assert_equal '2 special apples', np_('special', 'A special apple', '%{count} special apples', 2)
+  end
+
+  def test_npgettext_looks_up_a_singular
+    I18n.locale = :de
+    assert_equal 'Ein spezieller Apfel', npgettext('special', 'A special apple', '%{count} special apples', 1)
+    assert_equal 'Ein spezieller Apfel', np_('special', 'A special apple', '%{count} special apples', 1)
+  end
+
+  def test_npgettext_looks_up_a_plural
+    I18n.locale = :de
+    assert_equal '2 spezielle Äpfel', npgettext('special', 'A special apple', '%{count} special apples', 2)
+    assert_equal '2 spezielle Äpfel', np_('special', 'A special apple', '%{count} special apples', 2)
+  end
+
+  def test_npgettext_looks_up_msg_id_as_default_singular_with_alternative_syntax
+    assert_equal 'A special apple', npgettext('special', ['A special apple', '%{count} special apples'], 1)
+    assert_equal 'A special apple', np_('special', ['A special apple', '%{count} special apples'], 1)
+  end
+
+  def test_npgettext_looks_up_msg_id_plural_as_default_plural_with_alternative_syntax
+    assert_equal '2 special apples', npgettext('special', ['A special apple', '%{count} special apples'], 2)
+    assert_equal '2 special apples', np_('special', ['A special apple', '%{count} special apples'], 2)
+  end
+
+  def test_npgettext_looks_up_a_singular_with_alternative_syntax
+    I18n.locale = :de
+    assert_equal 'Ein spezieller Apfel', npgettext('special', ['A special apple', '%{count} special apples'], 1)
+    assert_equal 'Ein spezieller Apfel', np_('special', ['A special apple', '%{count} special apples'], 1)
+  end
+
+  def test_npgettext_looks_up_a_plural_with_alternative_syntax
+    I18n.locale = :de
+    assert_equal '2 spezielle Äpfel', npgettext('special', ['A special apple', '%{count} special apples'], 2)
+    assert_equal '2 spezielle Äpfel', np_('special', ['A special apple', '%{count} special apples'], 2)
+  end
+end
diff --git a/app/server/vendor/i18n/test/gettext/backend_test.rb b/app/server/vendor/i18n/test/gettext/backend_test.rb
new file mode 100644
index 0000000..ebba90b
--- /dev/null
+++ b/app/server/vendor/i18n/test/gettext/backend_test.rb
@@ -0,0 +1,101 @@
+# encoding: utf-8
+
+require 'test_helper'
+
+# apparently Ruby 1.9.1p129 has encoding problems with the gettext po parser
+unless RUBY_VERSION == '1.9.1' && RUBY_PATCHLEVEL <= 129
+
+  class I18nGettextBackendTest < I18n::TestCase
+    include I18n::Gettext::Helpers
+
+    class Backend < I18n::Backend::Simple
+      include I18n::Backend::Gettext
+    end
+
+    def setup
+      I18n.backend = Backend.new
+      I18n.locale = :en
+      I18n.load_path = ["#{locales_dir}/de.po"]
+      @old_separator, I18n.default_separator = I18n.default_separator, '|'
+    end
+
+    def teardown
+      I18n.load_path = nil
+      I18n.backend = nil
+      I18n.default_separator = @old_separator
+    end
+
+    def test_backend_loads_po_file
+      I18n.backend.send(:init_translations)
+      assert I18n.backend.send(:translations)[:de][:"Axis"]
+    end
+
+    def test_looks_up_a_translation
+      I18n.locale = :de
+      assert_equal 'Auto', gettext('car')
+    end
+
+    def test_uses_default_translation
+      assert_equal 'car', gettext('car')
+    end
+
+    def test_looks_up_a_namespaced_translation
+      I18n.locale = :de
+      assert_equal 'Räderzahl', sgettext('Car|Wheels count')
+      assert_equal 'Räderzahl', pgettext('Car', 'Wheels count')
+      assert_equal 'Räderzahl!', pgettext('New car', 'Wheels count')
+    end
+
+    def test_uses_namespaced_default_translation
+      assert_equal 'Wheels count', sgettext('Car|Wheels count')
+      assert_equal 'Wheels count', pgettext('Car', 'Wheels count')
+      assert_equal 'Wheels count', pgettext('New car', 'Wheels count')
+    end
+
+    def test_pluralizes_entry
+      I18n.locale = :de
+      assert_equal 'Achse', ngettext('Axis', 'Axis', 1)
+      assert_equal 'Achsen', ngettext('Axis', 'Axis', 2)
+    end
+
+    def test_pluralizes_default_entry
+      assert_equal 'Axis', ngettext('Axis', 'Axis', 1)
+      assert_equal 'Axis', ngettext('Axis', 'Axis', 2)
+    end
+
+    def test_pluralizes_namespaced_entry
+      I18n.locale = :de
+      assert_equal 'Rad',   nsgettext('Car|wheel', 'wheels', 1)
+      assert_equal 'Räder', nsgettext('Car|wheel', 'wheels', 2)
+      assert_equal 'Rad',   npgettext('Car', 'wheel', 'wheels', 1)
+      assert_equal 'Räder', npgettext('Car', 'wheel', 'wheels', 2)
+      assert_equal 'Rad!', npgettext('New car', 'wheel', 'wheels', 1)
+      assert_equal 'Räder!', npgettext('New car', 'wheel', 'wheels', 2)
+    end
+
+    def test_pluralizes_namespaced_default_entry
+      assert_equal 'wheel',  nsgettext('Car|wheel', 'wheels', 1)
+      assert_equal 'wheels', nsgettext('Car|wheel', 'wheels', 2)
+      assert_equal 'wheel',  npgettext('Car', 'wheel', 'wheels', 1)
+      assert_equal 'wheels', npgettext('Car', 'wheel', 'wheels', 2)
+      assert_equal 'wheel', npgettext('New car', 'wheel', 'wheels', 1)
+      assert_equal 'wheels', npgettext('New car', 'wheel', 'wheels', 2)
+    end
+
+    def test_pluralizes_namespaced_entry_with_alternative_syntax
+      I18n.locale = :de
+      assert_equal 'Rad',   nsgettext(['Car|wheel', 'wheels'], 1)
+      assert_equal 'Räder', nsgettext(['Car|wheel', 'wheels'], 2)
+      assert_equal 'Rad',   npgettext('Car', ['wheel', 'wheels'], 1)
+      assert_equal 'Räder', npgettext('Car', ['wheel', 'wheels'], 2)
+      assert_equal 'Rad!', npgettext('New car', ['wheel', 'wheels'], 1)
+      assert_equal 'Räder!', npgettext('New car', ['wheel', 'wheels'], 2)
+    end
+
+    def test_ngettextpluralizes_entry_with_dots
+      I18n.locale = :de
+      assert_equal 'Auf 1 Achse.', n_("On %{count} wheel.", "On %{count} wheels.", 1)
+      assert_equal 'Auf 2 Achsen.', n_("On %{count} wheel.", "On %{count} wheels.", 2)
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/test/i18n/exceptions_test.rb b/app/server/vendor/i18n/test/i18n/exceptions_test.rb
new file mode 100644
index 0000000..e633d7d
--- /dev/null
+++ b/app/server/vendor/i18n/test/i18n/exceptions_test.rb
@@ -0,0 +1,120 @@
+require 'test_helper'
+
+class I18nExceptionsTest < I18n::TestCase
+  def test_invalid_locale_stores_locale
+    force_invalid_locale
+  rescue I18n::ArgumentError => exception
+    assert_nil exception.locale
+  end
+
+  test "passing an invalid locale raises an InvalidLocale exception" do
+    force_invalid_locale do |exception|
+      assert_equal 'nil is not a valid locale', exception.message
+    end
+  end
+
+  test "MissingTranslationData exception stores locale, key and options" do
+    force_missing_translation_data do |exception|
+      assert_equal 'de', exception.locale
+      assert_equal :foo, exception.key
+      assert_equal({:scope => :bar}, exception.options)
+    end
+  end
+
+  test "MissingTranslationData message contains the locale and scoped key" do
+    force_missing_translation_data do |exception|
+      assert_equal 'translation missing: de.bar.foo', exception.message
+    end
+  end
+
+  test "MissingTranslationData html_message is a span with the titlelized last key token" do
+    exception = I18n::MissingTranslationData.new(:de, :foo, :scope => :bar)
+    assert_equal '<span class="translation_missing" title="translation missing: de.bar.foo">Foo</span>', exception.html_message
+  end
+
+  test "MissingTranslationData html_message html escapes key names" do
+    exception = I18n::MissingTranslationData.new(:de, '<script>Evil</script>', :scope => '<iframe src="example.com" />')
+    assert_equal '<span class="translation_missing" title="translation missing: de.<iframe src="example.com" />.<script>Evil</script>"><Script>Evil</Script></span>', exception.html_message
+  end
+
+  test "ExceptionHandler returns the html_message if :rescue_format => :html was given" do
+    message = force_missing_translation_data(:rescue_format => :html)
+    assert_equal '<span class="translation_missing" title="translation missing: de.bar.foo">Foo</span>', message
+  end
+
+  test "InvalidPluralizationData stores entry and count" do
+    force_invalid_pluralization_data do |exception|
+      assert_equal [:bar], exception.entry
+      assert_equal 1, exception.count
+    end
+  end
+
+  test "InvalidPluralizationData message contains count and data" do
+    force_invalid_pluralization_data do |exception|
+      assert_equal 'translation data [:bar] can not be used with :count => 1', exception.message
+    end
+  end
+
+  test "MissingInterpolationArgument stores key and string" do
+    assert_raise(I18n::MissingInterpolationArgument) { force_missing_interpolation_argument }
+    force_missing_interpolation_argument do |exception|
+      assert_equal :bar, exception.key
+      assert_equal "%{bar}", exception.string
+    end
+  end
+
+  test "MissingInterpolationArgument message contains the missing and given arguments" do
+    force_missing_interpolation_argument do |exception|
+      assert_equal 'missing interpolation argument :bar in "%{bar}" ({:baz=>"baz"} given)', exception.message
+    end
+  end
+
+  test "ReservedInterpolationKey stores key and string" do
+    force_reserved_interpolation_key do |exception|
+      assert_equal :scope, exception.key
+      assert_equal "%{scope}", exception.string
+    end
+  end
+
+  test "ReservedInterpolationKey message contains the reserved key" do
+    force_reserved_interpolation_key do |exception|
+      assert_equal 'reserved key :scope used in "%{scope}"', exception.message
+    end
+  end
+
+  private
+
+    def force_invalid_locale
+      I18n.translate(:foo, :locale => nil)
+    rescue I18n::ArgumentError => e
+      block_given? ? yield(e) : raise(e)
+    end
+
+    def force_missing_translation_data(options = {})
+      store_translations('de', :bar => nil)
+      I18n.translate(:foo, options.merge(:scope => :bar, :locale => :de))
+    rescue I18n::ArgumentError => e
+      block_given? ? yield(e) : raise(e)
+    end
+
+    def force_invalid_pluralization_data
+      store_translations('de', :foo => [:bar])
+      I18n.translate(:foo, :count => 1, :locale => :de)
+    rescue I18n::ArgumentError => e
+      block_given? ? yield(e) : raise(e)
+    end
+
+    def force_missing_interpolation_argument
+      store_translations('de', :foo => "%{bar}")
+      I18n.translate(:foo, :baz => 'baz', :locale => :de)
+    rescue I18n::ArgumentError => e
+      block_given? ? yield(e) : raise(e)
+    end
+
+    def force_reserved_interpolation_key
+      store_translations('de', :foo => "%{scope}")
+      I18n.translate(:foo, :baz => 'baz', :locale => :de)
+    rescue I18n::ArgumentError => e
+      block_given? ? yield(e) : raise(e)
+    end
+end
diff --git a/app/server/vendor/i18n/test/i18n/interpolate_test.rb b/app/server/vendor/i18n/test/i18n/interpolate_test.rb
new file mode 100644
index 0000000..74b6204
--- /dev/null
+++ b/app/server/vendor/i18n/test/i18n/interpolate_test.rb
@@ -0,0 +1,79 @@
+require 'test_helper'
+require 'i18n/core_ext/string/interpolate'
+
+# thanks to Masao's String extensions, some tests taken from Masao's tests
+# http://github.com/mutoh/gettext/blob/edbbe1fa8238fa12c7f26f2418403015f0270e47/test/test_string.rb
+
+class I18nInterpolateTest < I18n::TestCase
+  test "String interpolates a hash argument w/ named placeholders" do
+    assert_equal "Masao Mutoh", I18n.interpolate("%{first} %{last}", :first => 'Masao', :last => 'Mutoh' )
+  end
+
+  test "String interpolates a hash argument w/ named placeholders (reverse order)" do
+    assert_equal "Mutoh, Masao", I18n.interpolate("%{last}, %{first}", :first => 'Masao', :last => 'Mutoh' )
+  end
+
+  test "String interpolates named placeholders with sprintf syntax" do
+    assert_equal "10, 43.4", I18n.interpolate("%<integer>d, %<float>.1f", :integer => 10, :float => 43.4)
+  end
+
+  test "String interpolates named placeholders with sprintf syntax, does not recurse" do
+    assert_equal "%<not_translated>s", I18n.interpolate("%{msg}", :msg => '%<not_translated>s', :not_translated => 'should not happen' )
+  end
+
+  test "String interpolation does not replace anything when no placeholders are given" do
+    assert_equal "aaa", I18n.interpolate("aaa", :num => 1)
+  end
+
+  test "String interpolation sprintf behaviour equals Ruby 1.9 behaviour" do
+    assert_equal "1", I18n.interpolate("%<num>d", :num => 1)
+    assert_equal "0b1", I18n.interpolate("%<num>#b", :num => 1)
+    assert_equal "foo", I18n.interpolate("%<msg>s", :msg => "foo")
+    assert_equal "1.000000", I18n.interpolate("%<num>f", :num => 1.0)
+    assert_equal "  1", I18n.interpolate("%<num>3.0f", :num => 1.0)
+    assert_equal "100.00", I18n.interpolate("%<num>2.2f", :num => 100.0)
+    assert_equal "0x64", I18n.interpolate("%<num>#x", :num => 100.0)
+    assert_raise(ArgumentError) { I18n.interpolate("%<num>,d", :num => 100) }
+    assert_raise(ArgumentError) { I18n.interpolate("%<num>/d", :num => 100) }
+  end
+
+  test "String interpolation raises an I18n::MissingInterpolationArgument when the string has extra placeholders" do
+    assert_raise(I18n::MissingInterpolationArgument) do # Ruby 1.9 msg: "key not found"
+      I18n.interpolate("%{first} %{last}", :first => 'Masao')
+    end
+  end
+
+  test "String interpolation does not raise when extra values were passed" do
+    assert_nothing_raised do
+      assert_equal "Masao Mutoh", I18n.interpolate("%{first} %{last}", :first => 'Masao', :last => 'Mutoh', :salutation => 'Mr.' )
+    end
+  end
+
+  test "% acts as escape character in String interpolation" do
+    assert_equal "%{first}", I18n.interpolate("%%{first}", :first => 'Masao')
+    assert_equal "% 1", I18n.interpolate("%% %<num>d", :num => 1.0)
+    assert_equal "%{num} %<num>d", I18n.interpolate("%%{num} %%<num>d", :num => 1)
+  end
+
+  def test_sprintf_mix_unformatted_and_formatted_named_placeholders
+    assert_equal "foo 1.000000", I18n.interpolate("%{name} %<num>f", :name => "foo", :num => 1.0)
+  end
+end
+
+class I18nMissingInterpolationCustomHandlerTest < I18n::TestCase
+  def setup
+    @old_handler = I18n.config.missing_interpolation_argument_handler
+    I18n.config.missing_interpolation_argument_handler = lambda do |key, values, string|
+      "missing key is #{key}, values are #{values.inspect}, given string is '#{string}'"
+    end
+  end
+
+  def teardown
+    I18n.config.missing_interpolation_argument_handler = @old_handler
+  end
+
+  test "String interpolation can use custom missing interpolation handler" do
+    assert_equal %|Masao missing key is last, values are {:first=>"Masao"}, given string is '%{first} %{last}'|,
+      I18n.interpolate("%{first} %{last}", :first => 'Masao')
+  end
+end
diff --git a/app/server/vendor/i18n/test/i18n/load_path_test.rb b/app/server/vendor/i18n/test/i18n/load_path_test.rb
new file mode 100644
index 0000000..ebb023e
--- /dev/null
+++ b/app/server/vendor/i18n/test/i18n/load_path_test.rb
@@ -0,0 +1,33 @@
+require 'test_helper'
+
+class I18nLoadPathTest < I18n::TestCase
+  def setup
+    I18n.locale = :en
+    I18n.backend = I18n::Backend::Simple.new
+    store_translations(:en, :foo => {:bar => 'bar', :baz => 'baz'})
+  end
+
+  test "nested load paths do not break locale loading" do
+    I18n.load_path = [[locales_dir + '/en.yml']]
+    assert_equal "baz", I18n.t(:'foo.bar')
+  end
+
+  test "loading an empty yml file raises an InvalidLocaleData exception" do
+    assert_raise I18n::InvalidLocaleData do
+      I18n.load_path = [[locales_dir + '/invalid/empty.yml']]
+      I18n.t(:'foo.bar', :default => "baz")
+    end
+  end
+
+  test "loading an invalid yml file raises an InvalidLocaleData exception" do
+    assert_raise I18n::InvalidLocaleData do
+      I18n.load_path = [[locales_dir + '/invalid/syntax.yml']]
+      I18n.t(:'foo.bar', :default => "baz")
+    end
+  end
+
+  test "adding arrays of filenames to the load path does not break locale loading" do
+    I18n.load_path << Dir[locales_dir + '/*.{rb,yml}']
+    assert_equal "baz", I18n.t(:'foo.bar')
+  end
+end
diff --git a/app/server/vendor/i18n/test/i18n_test.rb b/app/server/vendor/i18n/test/i18n_test.rb
new file mode 100644
index 0000000..c64d595
--- /dev/null
+++ b/app/server/vendor/i18n/test/i18n_test.rb
@@ -0,0 +1,382 @@
+# encoding: utf-8
+require 'test_helper'
+
+class I18nTest < I18n::TestCase
+  def setup
+    store_translations(:en, :currency => { :format => { :separator => '.', :delimiter => ',', } })
+    store_translations(:nl, :currency => { :format => { :separator => ',', :delimiter => '.', } })
+  end
+
+  test "exposes its VERSION constant" do
+    assert I18n::VERSION
+  end
+
+  test "uses the simple backend by default" do
+    assert I18n.backend.is_a?(I18n::Backend::Simple)
+  end
+
+  test "can set the backend" do
+    begin
+      assert_nothing_raised { I18n.backend = self }
+      assert_equal self, I18n.backend
+    ensure
+      I18n.backend = I18n::Backend::Simple.new
+    end
+  end
+
+  test "uses :en as a default_locale by default" do
+    assert_equal :en, I18n.default_locale
+  end
+
+  test "can set the default locale" do
+    begin
+      assert_nothing_raised { I18n.default_locale = 'de' }
+      assert_equal :de, I18n.default_locale
+    ensure
+      I18n.default_locale = :en
+    end
+  end
+
+  test "raises an I18n::InvalidLocale exception when setting an unavailable default locale" do
+    begin
+      I18n.config.enforce_available_locales = true
+      assert_raise(I18n::InvalidLocale) { I18n.default_locale = :klingon }
+    ensure
+      I18n.config.enforce_available_locales = false
+    end
+  end
+
+  test "uses the default locale as a locale by default" do
+    assert_equal I18n.default_locale, I18n.locale
+  end
+
+  test "sets the current locale to Thread.current" do
+    assert_nothing_raised { I18n.locale = 'de' }
+    assert_equal :de, I18n.locale
+    assert_equal :de, Thread.current[:i18n_config].locale
+    I18n.locale = :en
+  end
+
+  test "raises an I18n::InvalidLocale exception when setting an unavailable locale" do
+    begin
+      I18n.config.enforce_available_locales = true
+      assert_raise(I18n::InvalidLocale) { I18n.locale = :klingon }
+    ensure
+      I18n.config.enforce_available_locales = false
+    end
+  end
+
+  test "can set the configuration object" do
+    begin
+      I18n.config = self
+      assert_equal self, I18n.config
+      assert_equal self, Thread.current[:i18n_config]
+    ensure
+      I18n.config = ::I18n::Config.new
+    end
+  end
+
+  test "locale is not shared between configurations" do
+    a = I18n::Config.new
+    b = I18n::Config.new
+    a.locale = :fr
+    b.locale = :es
+    assert_equal :fr, a.locale
+    assert_equal :es, b.locale
+    assert_equal :en, I18n.locale
+  end
+
+  test "other options are shared between configurations" do
+    begin
+      a = I18n::Config.new
+      b = I18n::Config.new
+      a.default_locale = :fr
+      b.default_locale = :es
+      assert_equal :es, a.default_locale
+      assert_equal :es, b.default_locale
+      assert_equal :es, I18n.default_locale
+    ensure
+      I18n.default_locale = :en
+    end
+  end
+
+  test "uses a dot as a default_separator by default" do
+    assert_equal '.', I18n.default_separator
+  end
+
+  test "can set the default_separator" do
+    begin
+      assert_nothing_raised { I18n.default_separator = "\001" }
+    ensure
+      I18n.default_separator = '.'
+    end
+  end
+
+  test "normalize_keys normalizes given locale, keys and scope to an array of single-key symbols" do
+    assert_equal [:en, :foo, :bar], I18n.normalize_keys(:en, :bar, :foo)
+    assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, :'baz.buz', :'foo.bar')
+    assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, 'baz.buz', 'foo.bar')
+    assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, %w(baz buz), %w(foo bar))
+    assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, [:baz, :buz], [:foo, :bar])
+  end
+
+  test "normalize_keys discards empty keys" do
+    assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, :'baz..buz', :'foo..bar')
+    assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, :'baz......buz', :'foo......bar')
+    assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, ['baz', nil, '', 'buz'], ['foo', nil, '', 'bar'])
+  end
+
+  test "normalize_keys uses a given separator" do
+    assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, :'baz|buz', :'foo|bar', '|')
+  end
+
+  test "can set the exception_handler" do
+    begin
+      previous_exception_handler = I18n.exception_handler
+      assert_nothing_raised { I18n.exception_handler = :custom_exception_handler }
+    ensure
+      I18n.exception_handler = previous_exception_handler
+    end
+  end
+
+  test "uses a custom exception handler set to I18n.exception_handler" do
+    begin
+      previous_exception_handler = I18n.exception_handler
+      I18n.exception_handler = :custom_exception_handler
+      I18n.expects(:custom_exception_handler)
+      I18n.translate :bogus
+    ensure
+      I18n.exception_handler = previous_exception_handler
+    end
+  end
+
+  test "uses a custom exception handler passed as an option" do
+    I18n.expects(:custom_exception_handler)
+    I18n.translate(:bogus, :exception_handler => :custom_exception_handler)
+  end
+
+  test "delegates translate calls to the backend" do
+    I18n.backend.expects(:translate).with('de', :foo, {})
+    I18n.translate :foo, :locale => 'de'
+  end
+
+  test "delegates localize calls to the backend" do
+    I18n.backend.expects(:localize).with('de', :whatever, :default, {})
+    I18n.localize :whatever, :locale => 'de'
+  end
+
+  test "translate given no locale uses the current locale" do
+    I18n.backend.expects(:translate).with(:en, :foo, {})
+    I18n.translate :foo
+  end
+
+  test "translate works with nested symbol keys" do
+    assert_equal ".", I18n.t(:'currency.format.separator')
+  end
+
+  test "translate works with nested string keys" do
+    assert_equal ".", I18n.t('currency.format.separator')
+  end
+
+  test "translate with an array as a scope works" do
+    assert_equal ".", I18n.t(:separator, :scope => %w(currency format))
+  end
+
+  test "translate with an array containing dot separated strings as a scope works" do
+    assert_equal ".", I18n.t(:separator, :scope => ['currency.format'])
+  end
+
+  test "translate with an array of keys and a dot separated string as a scope works" do
+    assert_equal [".", ","], I18n.t(%w(separator delimiter), :scope => 'currency.format')
+  end
+
+  test "translate with an array of dot separated keys and a scope works" do
+    assert_equal [".", ","], I18n.t(%w(format.separator format.delimiter), :scope => 'currency')
+  end
+
+  # def test_translate_given_no_args_raises_missing_translation_data
+  #   assert_equal "translation missing: en, no key", I18n.t
+  # end
+
+  test "translate given a bogus key returns an error message" do
+    assert_equal "translation missing: en.bogus", I18n.t(:bogus)
+  end
+
+  test "translate given an empty string as a key raises an I18n::ArgumentError" do
+    assert_raise(I18n::ArgumentError) { I18n.t("") }
+  end
+
+  test "translate given an unavailable locale rases an I18n::InvalidLocale" do
+    begin
+      I18n.config.enforce_available_locales = true
+      assert_raise(I18n::InvalidLocale) { I18n.t(:foo, :locale => 'klingon') }
+    ensure
+      I18n.config.enforce_available_locales = false
+    end
+  end
+
+  test "available_locales can be replaced at runtime" do
+    begin
+      I18n.config.enforce_available_locales = true
+      assert_raise(I18n::InvalidLocale) { I18n.t(:foo, :locale => 'klingon') }
+      old_locales, I18n.config.available_locales = I18n.config.available_locales, [:klingon]
+      I18n.t(:foo, :locale => 'klingon')
+    ensure
+      I18n.config.enforce_available_locales = false
+      I18n.config.available_locales = old_locales
+    end
+  end
+
+  test "available_locales_set should return a set" do
+    assert_equal Set, I18n.config.available_locales_set.class
+    assert_equal I18n.config.available_locales.size * 2, I18n.config.available_locales_set.size
+  end
+
+  test "exists? given an existing key will return true" do
+    assert_equal true, I18n.exists?(:currency)
+  end
+
+  test "exists? given a non-existing key will return false" do
+    assert_equal false, I18n.exists?(:bogus)
+  end
+
+  test "exists? given an existing dot-separated key will return true" do
+    assert_equal true, I18n.exists?('currency.format.delimiter')
+  end
+
+  test "exists? given a non-existing dot-separated key will return false" do
+    assert_equal false, I18n.exists?('currency.format.bogus')
+  end
+
+  test "exists? given an existing key and an existing locale will return true" do
+    assert_equal true, I18n.exists?(:currency, :nl)
+  end
+
+  test "exists? given a non-existing key and an existing locale will return false" do
+    assert_equal false, I18n.exists?(:bogus, :nl)
+  end
+
+  test "localize given nil raises an I18n::ArgumentError" do
+    assert_raise(I18n::ArgumentError) { I18n.l nil }
+  end
+
+  test "localize given an Object raises an I18n::ArgumentError" do
+    assert_raise(I18n::ArgumentError) { I18n.l Object.new }
+  end
+
+  test "localize given an unavailable locale rases an I18n::InvalidLocale" do
+    begin
+      I18n.config.enforce_available_locales = true
+      assert_raise(I18n::InvalidLocale) { I18n.l(Time.now, :locale => 'klingon') }
+    ensure
+      I18n.config.enforce_available_locales = false
+    end
+  end
+
+  test "can use a lambda as an exception handler" do
+    begin
+      previous_exception_handler = I18n.exception_handler
+      I18n.exception_handler = Proc.new { |exception, locale, key, options| key }
+      assert_equal :test_proc_handler, I18n.translate(:test_proc_handler)
+    ensure
+      I18n.exception_handler = previous_exception_handler
+    end
+  end
+
+  test "can use an object responding to #call as an exception handler" do
+    begin
+      previous_exception_handler = I18n.exception_handler
+      I18n.exception_handler = Class.new do
+        def call(exception, locale, key, options); key; end
+      end.new
+      assert_equal :test_proc_handler, I18n.translate(:test_proc_handler)
+    ensure
+      I18n.exception_handler = previous_exception_handler
+    end
+  end
+
+  test "I18n.with_locale temporarily sets the given locale" do
+    store_translations(:en, :foo => 'Foo in :en')
+    store_translations(:de, :foo => 'Foo in :de')
+    store_translations(:pl, :foo => 'Foo in :pl')
+
+    I18n.with_locale      { assert_equal [:en, 'Foo in :en'], [I18n.locale, I18n.t(:foo)] }
+    I18n.with_locale(:de) { assert_equal [:de, 'Foo in :de'], [I18n.locale, I18n.t(:foo)] }
+    I18n.with_locale(:pl) { assert_equal [:pl, 'Foo in :pl'], [I18n.locale, I18n.t(:foo)] }
+    I18n.with_locale(:en) { assert_equal [:en, 'Foo in :en'], [I18n.locale, I18n.t(:foo)] }
+
+    assert_equal I18n.default_locale, I18n.locale
+  end
+
+  test "I18n.with_locale resets the locale in case of errors" do
+    assert_raise(I18n::ArgumentError) { I18n.with_locale(:pl) { raise I18n::ArgumentError } }
+    assert_equal I18n.default_locale, I18n.locale
+  end
+
+  test "I18n.translitarate handles I18n::ArgumentError exception" do
+    I18n::Backend::Transliterator.stubs(:get).raises(I18n::ArgumentError)
+    I18n.exception_handler.expects(:call).raises(I18n::ArgumentError)
+    assert_raise(I18n::ArgumentError) {
+      I18n.transliterate("ąćó")
+    }
+  end
+
+  test "I18n.translitarate raises I18n::ArgumentError exception" do
+    I18n::Backend::Transliterator.stubs(:get).raises(I18n::ArgumentError)
+    I18n.exception_handler.expects(:call).never
+    assert_raise(I18n::ArgumentError) {
+      I18n.transliterate("ąćó", :raise => true)
+    }
+  end
+
+  test "transliterate given an unavailable locale rases an I18n::InvalidLocale" do
+    begin
+      I18n.config.enforce_available_locales = true
+      assert_raise(I18n::InvalidLocale) { I18n.transliterate('string', :locale => 'klingon') }
+    ensure
+      I18n.config.enforce_available_locales = false
+    end
+  end
+
+  test "I18n.locale_available? returns true when the passed locale is available" do
+    I18n.available_locales = [:en, :de]
+    assert_equal true, I18n.locale_available?(:de)
+  end
+
+  test "I18n.locale_available? returns true when the passed locale is a string and is available" do
+    I18n.available_locales = [:en, :de]
+    assert_equal true, I18n.locale_available?('de')
+  end
+
+  test "I18n.locale_available? returns false when the passed locale is unavailable" do
+    assert_equal false, I18n.locale_available?(:klingon)
+  end
+
+  test "I18n.enforce_available_locales! raises an I18n::InvalidLocale when the passed locale is unavailable" do
+    begin
+      I18n.config.enforce_available_locales = true
+      assert_raise(I18n::InvalidLocale) { I18n.enforce_available_locales!(:klingon) }
+    ensure
+      I18n.config.enforce_available_locales = false
+    end
+  end
+
+  test "I18n.enforce_available_locales! does nothing when the passed locale is available" do
+    I18n.available_locales = [:en, :de]
+    begin
+      I18n.config.enforce_available_locales = true
+      assert_nothing_raised { I18n.enforce_available_locales!(:en) }
+    ensure
+      I18n.config.enforce_available_locales = false
+    end
+  end
+
+  test "I18n.enforce_available_locales config can be set to false" do
+    begin
+      I18n.config.enforce_available_locales = false
+      assert_equal false, I18n.config.enforce_available_locales
+    ensure
+      I18n.config.enforce_available_locales = false
+    end
+  end
+end
diff --git a/app/server/vendor/i18n/test/locale/fallbacks_test.rb b/app/server/vendor/i18n/test/locale/fallbacks_test.rb
new file mode 100644
index 0000000..b25f02d
--- /dev/null
+++ b/app/server/vendor/i18n/test/locale/fallbacks_test.rb
@@ -0,0 +1,136 @@
+require 'test_helper'
+
+include I18n::Locale
+
+class I18nFallbacksDefaultsTest < I18n::TestCase
+  def teardown
+    I18n.default_locale = :en
+  end
+
+  test "defaults reflect the I18n.default_locale if no default has been set manually" do
+    I18n.default_locale = :'en-US'
+    fallbacks = Fallbacks.new
+    assert_equal [:'en-US', :en], fallbacks.defaults
+  end
+
+  test "defaults reflect a manually passed default locale if any" do
+    fallbacks = Fallbacks.new(:'fi-FI')
+    assert_equal [:'fi-FI', :fi], fallbacks.defaults
+    I18n.default_locale = :'de-DE'
+    assert_equal [:'fi-FI', :fi], fallbacks.defaults
+  end
+
+  test "defaults allows to set multiple defaults" do
+    fallbacks = Fallbacks.new(:'fi-FI', :'se-FI')
+    assert_equal [:'fi-FI', :fi, :'se-FI', :se], fallbacks.defaults
+  end
+end
+
+class I18nFallbacksComputationTest < I18n::TestCase
+  def setup
+    @fallbacks = Fallbacks.new(:'en-US')
+  end
+
+  test "with no mappings defined it returns [:es, :en-US] for :es" do
+    assert_equal [:es, :"en-US", :en], @fallbacks[:es]
+  end
+
+  test "with no mappings defined it returns [:es-ES, :es, :en-US] for :es-ES" do
+    assert_equal [:"es-ES", :es, :"en-US", :en], @fallbacks[:"es-ES"]
+  end
+
+  test "with no mappings defined it returns [:es-MX, :es, :en-US] for :es-MX" do
+    assert_equal [:"es-MX", :es, :"en-US", :en], @fallbacks[:"es-MX"]
+  end
+
+  test "with no mappings defined it returns [:es-Latn-ES, :es-Latn, :es, :en-US] for :es-Latn-ES" do
+    assert_equal [:"es-Latn-ES", :"es-Latn", :es, :"en-US", :en], @fallbacks[:'es-Latn-ES']
+  end
+
+  test "with no mappings defined it returns [:en, :en-US] for :en" do
+    assert_equal [:en, :"en-US"], @fallbacks[:en]
+  end
+
+  test "with no mappings defined it returns [:en-US, :en] for :en-US (special case: locale == default)" do
+    assert_equal [:"en-US", :en], @fallbacks[:"en-US"]
+  end
+
+  # Most people who speak Catalan also live in Spain, so it is safe to assume
+  # that they also speak Spanish as spoken in Spain.
+  test "with a Catalan mapping defined it returns [:ca, :es-ES, :es, :en-US] for :ca" do
+    @fallbacks.map(:ca => :"es-ES")
+    assert_equal [:ca, :"es-ES", :es, :"en-US", :en], @fallbacks[:ca]
+  end
+
+  test "with a Catalan mapping defined it returns [:ca-ES, :ca, :es-ES, :es, :en-US] for :ca-ES" do
+    @fallbacks.map(:ca => :"es-ES")
+    assert_equal [:"ca-ES", :ca, :"es-ES", :es, :"en-US", :en], @fallbacks[:"ca-ES"]
+  end
+
+  # People who speak Arabic as spoken in Palestine often times also speak
+  # Hebrew as spoken in Israel. However it is in no way safe to assume that
+  # everybody who speaks Arabic also speaks Hebrew.
+
+  test "with a Hebrew mapping defined it returns [:ar, :en-US] for :ar" do
+    @fallbacks.map(:"ar-PS" => :"he-IL")
+    assert_equal [:ar, :"en-US", :en], @fallbacks[:ar]
+  end
+
+  test "with a Hebrew mapping defined it returns [:ar-EG, :ar, :en-US] for :ar-EG" do
+    @fallbacks.map(:"ar-PS" => :"he-IL")
+    assert_equal [:"ar-EG", :ar, :"en-US", :en], @fallbacks[:"ar-EG"]
+  end
+
+  test "with a Hebrew mapping defined it returns [:ar-PS, :ar, :he-IL, :he, :en-US] for :ar-PS" do
+    @fallbacks.map(:"ar-PS" => :"he-IL")
+    assert_equal [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en], @fallbacks[:"ar-PS"]
+  end
+
+  # Sami people live in several scandinavian countries. In Finnland many people
+  # know Swedish and Finnish. Thus, it can be assumed that Sami living in
+  # Finnland also speak Swedish and Finnish.
+
+  test "with a Sami mapping defined it returns [:sms-FI, :sms, :se-FI, :se, :fi-FI, :fi, :en-US] for :sms-FI" do
+    @fallbacks.map(:sms => [:"se-FI", :"fi-FI"])
+    assert_equal [:"sms-FI", :sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en], @fallbacks[:"sms-FI"]
+  end
+
+  # Austrian people understand German as spoken in Germany
+
+  test "with a German mapping defined it returns [:de, :en-US] for de" do
+    @fallbacks.map(:"de-AT" => :"de-DE")
+    assert_equal [:de, :"en-US", :en], @fallbacks[:"de"]
+  end
+
+  test "with a German mapping defined it returns [:de-DE, :de, :en-US] for de-DE" do
+    @fallbacks.map(:"de-AT" => :"de-DE")
+    assert_equal [:"de-DE", :de, :"en-US", :en], @fallbacks[:"de-DE"]
+  end
+
+  test "with a German mapping defined it returns [:de-AT, :de, :de-DE, :en-US] for de-AT" do
+    @fallbacks.map(:"de-AT" => :"de-DE")
+    assert_equal [:"de-AT", :de, :"de-DE", :"en-US", :en], @fallbacks[:"de-AT"]
+  end
+
+  # Mapping :de => :en, :he => :en
+
+  test "with a mapping :de => :en, :he => :en defined it returns [:de, :en] for :de" do
+    assert_equal [:de, :"en-US", :en], @fallbacks[:de]
+  end
+
+  test "with a mapping :de => :en, :he => :en defined it [:he, :en] for :de" do
+    assert_equal [:he, :"en-US", :en], @fallbacks[:he]
+  end
+
+  # Test allowing mappings that fallback to each other
+
+  test "with :no => :nb, :nb => :no defined :no returns [:no, :nb, :en-US, :en]" do
+    @fallbacks.map(:no => :nb, :nb => :no)
+    assert_equal [:no, :nb, :"en-US", :en], @fallbacks[:no]
+  end
+
+  test "with :no => :nb, :nb => :no defined :nb returns [:nb, :no, :en-US, :en]" do
+    @fallbacks.map(:no => :nb, :nb => :no)
+    assert_equal [:nb, :no, :"en-US", :en], @fallbacks[:nb]
+  end
+end
diff --git a/app/server/vendor/i18n/test/locale/tag/rfc4646_test.rb b/app/server/vendor/i18n/test/locale/tag/rfc4646_test.rb
new file mode 100644
index 0000000..97fa6e4
--- /dev/null
+++ b/app/server/vendor/i18n/test/locale/tag/rfc4646_test.rb
@@ -0,0 +1,142 @@
+# encoding: utf-8
+require 'test_helper'
+
+class I18nLocaleTagRfc4646ParserTest < I18n::TestCase
+  include I18n::Locale
+
+  test "Rfc4646::Parser given a valid tag 'de' returns an array of subtags" do
+    assert_equal ['de', nil, nil, nil, nil, nil, nil], Tag::Rfc4646::Parser.match('de')
+  end
+
+  test "Rfc4646::Parser given a valid tag 'de-DE' returns an array of subtags" do
+    assert_equal ['de', nil, 'DE', nil, nil, nil, nil], Tag::Rfc4646::Parser.match('de-DE')
+  end
+
+  test "Rfc4646::Parser given a valid lowercase tag 'de-latn-de-variant-x-phonebk' returns an array of subtags" do
+    assert_equal ['de', 'latn', 'de', 'variant', nil, 'x-phonebk', nil], Tag::Rfc4646::Parser.match('de-latn-de-variant-x-phonebk')
+  end
+
+  test "Rfc4646::Parser given a valid uppercase tag 'DE-LATN-DE-VARIANT-X-PHONEBK' returns an array of subtags" do
+    assert_equal ['DE', 'LATN', 'DE', 'VARIANT', nil, 'X-PHONEBK', nil], Tag::Rfc4646::Parser.match('DE-LATN-DE-VARIANT-X-PHONEBK')
+  end
+
+  test "Rfc4646::Parser given an invalid tag 'a-DE' it returns false" do
+    assert_equal false, Tag::Rfc4646::Parser.match('a-DE')
+  end
+
+  test "Rfc4646::Parser given an invalid tag 'de-419-DE' it returns false" do
+    assert_equal false, Tag::Rfc4646::Parser.match('de-419-DE')
+  end
+end
+
+# Tag for the locale 'de-Latn-DE-Variant-a-ext-x-phonebk-i-klingon'
+
+class I18nLocaleTagSubtagsTest < I18n::TestCase
+  include I18n::Locale
+
+  def setup
+    subtags = %w(de Latn DE variant a-ext x-phonebk i-klingon)
+    @tag = Tag::Rfc4646.new(*subtags)
+  end
+
+  test "returns 'de' as the language subtag in lowercase" do
+    assert_equal 'de', @tag.language
+  end
+
+  test "returns 'Latn' as the script subtag in titlecase" do
+    assert_equal 'Latn', @tag.script
+  end
+
+  test "returns 'DE' as the region subtag in uppercase" do
+    assert_equal 'DE', @tag.region
+  end
+
+  test "returns 'variant' as the variant subtag in lowercase" do
+    assert_equal 'variant', @tag.variant
+  end
+
+  test "returns 'a-ext' as the extension subtag" do
+    assert_equal 'a-ext', @tag.extension
+  end
+
+  test "returns 'x-phonebk' as the privateuse subtag" do
+    assert_equal 'x-phonebk', @tag.privateuse
+  end
+
+  test "returns 'i-klingon' as the grandfathered subtag" do
+    assert_equal 'i-klingon', @tag.grandfathered
+  end
+
+  test "returns a formatted tag string from #to_s" do
+    assert_equal 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon', @tag.to_s
+  end
+
+  test "returns an array containing the formatted subtags from #to_a" do
+    assert_equal %w(de Latn DE variant a-ext x-phonebk i-klingon), @tag.to_a
+  end
+end
+
+# Tag inheritance
+
+class I18nLocaleTagSubtagsTest < I18n::TestCase
+  test "#parent returns 'de-Latn-DE-variant-a-ext-x-phonebk' as the parent of 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon'" do
+    tag = Tag::Rfc4646.new(*%w(de Latn DE variant a-ext x-phonebk i-klingon))
+    assert_equal 'de-Latn-DE-variant-a-ext-x-phonebk', tag.parent.to_s
+  end
+
+  test "#parent returns 'de-Latn-DE-variant-a-ext' as the parent of 'de-Latn-DE-variant-a-ext-x-phonebk'" do
+    tag = Tag::Rfc4646.new(*%w(de Latn DE variant a-ext x-phonebk))
+    assert_equal 'de-Latn-DE-variant-a-ext', tag.parent.to_s
+  end
+
+  test "#parent returns 'de-Latn-DE-variant' as the parent of 'de-Latn-DE-variant-a-ext'" do
+    tag = Tag::Rfc4646.new(*%w(de Latn DE variant a-ext))
+    assert_equal 'de-Latn-DE-variant', tag.parent.to_s
+  end
+
+  test "#parent returns 'de-Latn-DE' as the parent of 'de-Latn-DE-variant'" do
+    tag = Tag::Rfc4646.new(*%w(de Latn DE variant))
+    assert_equal 'de-Latn-DE', tag.parent.to_s
+  end
+
+  test "#parent returns 'de-Latn' as the parent of 'de-Latn-DE'" do
+    tag = Tag::Rfc4646.new(*%w(de Latn DE))
+    assert_equal 'de-Latn', tag.parent.to_s
+  end
+
+  test "#parent returns 'de' as the parent of 'de-Latn'" do
+    tag = Tag::Rfc4646.new(*%w(de Latn))
+    assert_equal 'de', tag.parent.to_s
+  end
+
+  # TODO RFC4647 says: "If no language tag matches the request, the "default" value is returned."
+  # where should we set the default language?
+  # test "#parent returns '' as the parent of 'de'" do
+  #   tag = Tag::Rfc4646.new *%w(de)
+  #   assert_equal '', tag.parent.to_s
+  # end
+
+  test "#parent returns an array of 5 parents for 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon'" do
+    parents = %w(de-Latn-DE-variant-a-ext-x-phonebk-i-klingon
+                 de-Latn-DE-variant-a-ext-x-phonebk
+                 de-Latn-DE-variant-a-ext
+                 de-Latn-DE-variant
+                 de-Latn-DE
+                 de-Latn
+                 de)
+    tag = Tag::Rfc4646.new(*%w(de Latn DE variant a-ext x-phonebk i-klingon))
+    assert_equal parents, tag.self_and_parents.map(&:to_s)
+  end
+
+  test "returns an array of 5 parents for 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon'" do
+    parents = %w(de-Latn-DE-variant-a-ext-x-phonebk-i-klingon
+                 de-Latn-DE-variant-a-ext-x-phonebk
+                 de-Latn-DE-variant-a-ext
+                 de-Latn-DE-variant
+                 de-Latn-DE
+                 de-Latn
+                 de)
+    tag = Tag::Rfc4646.new(*%w(de Latn DE variant a-ext x-phonebk i-klingon))
+    assert_equal parents, tag.self_and_parents.map(&:to_s)
+  end
+end
diff --git a/app/server/vendor/i18n/test/locale/tag/simple_test.rb b/app/server/vendor/i18n/test/locale/tag/simple_test.rb
new file mode 100644
index 0000000..002c63d
--- /dev/null
+++ b/app/server/vendor/i18n/test/locale/tag/simple_test.rb
@@ -0,0 +1,32 @@
+# encoding: utf-8
+require 'test_helper'
+
+class I18nLocaleTagSimpleTest < I18n::TestCase
+  include I18n::Locale
+
+  test "returns 'de' as the language subtag in lowercase" do
+    assert_equal %w(de Latn DE), Tag::Simple.new('de-Latn-DE').subtags
+  end
+
+  test "returns a formatted tag string from #to_s" do
+    assert_equal 'de-Latn-DE', Tag::Simple.new('de-Latn-DE').to_s
+  end
+
+  test "returns an array containing the formatted subtags from #to_a" do
+    assert_equal %w(de Latn DE), Tag::Simple.new('de-Latn-DE').to_a
+  end
+
+  # Tag inheritance
+
+  test "#parent returns 'de-Latn' as the parent of 'de-Latn-DE'" do
+    assert_equal 'de-Latn', Tag::Simple.new('de-Latn-DE').parent.to_s
+  end
+
+  test "#parent returns 'de' as the parent of 'de-Latn'" do
+    assert_equal 'de', Tag::Simple.new('de-Latn').parent.to_s
+  end
+
+  test "#self_and_parents returns an array of 3 tags for 'de-Latn-DE'" do
+    assert_equal %w(de-Latn-DE de-Latn de), Tag::Simple.new('de-Latn-DE').self_and_parents.map { |tag| tag.to_s}
+  end
+end
diff --git a/app/server/vendor/i18n/test/run_all.rb b/app/server/vendor/i18n/test/run_all.rb
new file mode 100644
index 0000000..46bc43c
--- /dev/null
+++ b/app/server/vendor/i18n/test/run_all.rb
@@ -0,0 +1,20 @@
+def bundle_check
+  `bundle check` == "Resolving dependencies...\nThe Gemfile's dependencies are satisfied\n"
+end
+
+def execute(command)
+  puts command
+  system command
+end
+
+gemfiles = %w(Gemfile) + Dir['gemfiles/Gemfile*'].reject { |f| f.end_with?('.lock') }
+
+results = gemfiles.map do |gemfile|
+  puts "\nBUNDLE_GEMFILE=#{gemfile}"
+  ENV['BUNDLE_GEMFILE'] = File.expand_path("../../#{gemfile}", __FILE__)
+
+  execute 'bundle install' unless bundle_check
+  execute 'bundle exec ruby -w -Ilib -Itest test/all.rb'
+end
+
+exit results.all?
diff --git a/app/server/vendor/i18n/test/test_data/locales/de.po b/app/server/vendor/i18n/test/test_data/locales/de.po
new file mode 100644
index 0000000..f3c9998
--- /dev/null
+++ b/app/server/vendor/i18n/test/test_data/locales/de.po
@@ -0,0 +1,82 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: version 0.0.1\n"
+"POT-Creation-Date: 2009-02-26 19:50+0100\n"
+"PO-Revision-Date: 2009-02-18 14:53+0100\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: LANGUAGE <LL at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+# #: app/helpers/translation_helper.rb:3
+# msgid "%{relative_time} ago"
+# msgstr "vor %{relative_time}"
+
+#: app/views/cars/show.html.erb:5
+msgid "Axis"
+msgid_plural "Axis"
+msgstr[0] "Achse"
+msgstr[1] "Achsen"
+
+#: app/controllers/cars_controller.rb:47
+msgid "Car was successfully created."
+msgstr "Auto wurde erfolgreich gespeichert"
+
+#: app/controllers/cars_controller.rb:64
+msgid "Car was successfully updated."
+msgstr "Auto wurde erfolgreich aktualisiert"
+
+#: app/views/cars/show.html.erb:1 locale/model_attributes.rb:3
+msgid "Car|Model"
+msgstr "Modell"
+
+#: app/views/cars/show.html.erb:3 locale/model_attributes.rb:4
+msgid "Car|Wheels count"
+msgstr "Räderzahl"
+
+msgctxt "New car"
+msgid "Wheels count"
+msgstr "Räderzahl!"
+
+#: app/views/cars/show.html.erb:7
+msgid "Created"
+msgstr "Erstellt"
+
+#: app/views/cars/show.html.erb:9
+msgid "Month"
+msgstr "Monat"
+
+#: locale/model_attributes.rb:2
+msgid "car"
+msgstr "Auto"
+
+#: locale/testlog_phrases.rb:2
+msgid "this is a dynamic translation which was found thorugh gettext_test_log!"
+msgstr ""
+"Dies ist eine dynamische Ãœbersetzung, die durch gettext_test_log "
+"gefunden wurde!"
+
+#: app/views/cars/nowhere_really
+msgid "Car|wheel"
+msgid_plural "Car|wheels"
+msgstr[0] "Rad"
+msgstr[1] "Räder"
+
+msgctxt "New car"
+msgid "wheel"
+msgid_plural "wheels"
+msgstr[0] "Rad!"
+msgstr[1] "Räder!"
+
+msgid "On %{count} wheel."
+msgid_plural "On %{count} wheels."
+msgstr[0] "Auf %{count} Achse."
+msgstr[1] "Auf %{count} Achsen."
diff --git a/app/server/vendor/i18n/test/test_data/locales/en.rb b/app/server/vendor/i18n/test/test_data/locales/en.rb
new file mode 100644
index 0000000..e847d10
--- /dev/null
+++ b/app/server/vendor/i18n/test/test_data/locales/en.rb
@@ -0,0 +1,3 @@
+# encoding: utf-8
+
+{ :en => { :fuh => { :bah => "bas" } } }
\ No newline at end of file
diff --git a/app/server/vendor/i18n/test/test_data/locales/en.yml b/app/server/vendor/i18n/test/test_data/locales/en.yml
new file mode 100644
index 0000000..25f5bb6
--- /dev/null
+++ b/app/server/vendor/i18n/test/test_data/locales/en.yml
@@ -0,0 +1,3 @@
+en:
+  foo:
+    bar: baz
\ No newline at end of file
diff --git a/app/server/vendor/i18n/test/test_data/locales/invalid/empty.yml b/app/server/vendor/i18n/test/test_data/locales/invalid/empty.yml
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/vendor/i18n/test/test_data/locales/invalid/syntax.yml b/app/server/vendor/i18n/test/test_data/locales/invalid/syntax.yml
new file mode 100644
index 0000000..40b1e61
--- /dev/null
+++ b/app/server/vendor/i18n/test/test_data/locales/invalid/syntax.yml
@@ -0,0 +1,4 @@
+en:
+ foo: foo
+    bar:
+  baz:
\ No newline at end of file
diff --git a/app/server/vendor/i18n/test/test_data/locales/plurals.rb b/app/server/vendor/i18n/test/test_data/locales/plurals.rb
new file mode 100644
index 0000000..835e28f
--- /dev/null
+++ b/app/server/vendor/i18n/test/test_data/locales/plurals.rb
@@ -0,0 +1,113 @@
+# encoding: utf-8
+
+{
+  :af => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :am => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } },
+  :ar => { :i18n => { :plural => { :keys => [:zero, :one, :two, :few, :many, :other], :rule => lambda { |n| n == 0 ? :zero : n == 1 ? :one : n == 2 ? :two : [3, 4, 5, 6, 7, 8, 9, 10].include?(n % 100) ? :few : [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99].include?(n % 100) ? :many : :other } } } },
+  :az => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :be => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other } } } },
+  :bg => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :bh => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } },
+  :bn => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :bo => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :bs => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other } } } },
+  :ca => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :cs => { :i18n => { :plural => { :keys => [:one, :few, :other], :rule => lambda { |n| n == 1 ? :one : [2, 3, 4].include?(n) ? :few : :other } } } },
+  :cy => { :i18n => { :plural => { :keys => [:one, :two, :many, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : n == 8 || n == 11 ? :many : :other } } } },
+  :da => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :de => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :dz => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :el => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :en => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :eo => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :es => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :et => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :eu => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :fa => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :fi => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :fil => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } },
+  :fo => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :fr => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n.between?(0, 2) && n != 2 ? :one : :other } } } },
+  :fur => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :fy => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :ga => { :i18n => { :plural => { :keys => [:one, :two, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : :other } } } },
+  :gl => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :gu => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :guw => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } },
+  :ha => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :he => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :hi => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } },
+  :hr => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other } } } },
+  :hu => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :id => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :is => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :it => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :iw => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :ja => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :jv => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :ka => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :km => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :kn => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :ko => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :ku => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :lb => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :ln => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } },
+  :lt => { :i18n => { :plural => { :keys => [:one, :few, :other], :rule => lambda { |n| n % 10 == 1 && ![11, 12, 13, 14, 15, 16, 17, 18, 19].include?(n % 100) ? :one : [2, 3, 4, 5, 6, 7, 8, 9].include?(n % 10) && ![11, 12, 13, 14, 15, 16, 17, 18, 19].include?(n % 100) ? :few : :other } } } },
+  :lv => { :i18n => { :plural => { :keys => [:zero, :one, :other], :rule => lambda { |n| n == 0 ? :zero : n % 10 == 1 && n % 100 != 11 ? :one : :other } } } },
+  :mg => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } },
+  :mk => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n % 10 == 1 ? :one : :other } } } },
+  :ml => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :mn => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :mo => { :i18n => { :plural => { :keys => [:one, :few, :other], :rule => lambda { |n| n == 1 ? :one : n == 0 ? :few : :other } } } },
+  :mr => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :ms => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :mt => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n == 1 ? :one : n == 0 || [2, 3, 4, 5, 6, 7, 8, 9, 10].include?(n % 100) ? :few : [11, 12, 13, 14, 15, 16, 17, 18, 19].include?(n % 100) ? :many : :other } } } },
+  :my => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :nah => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :nb => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :ne => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :nl => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :nn => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :no => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :nso => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } },
+  :om => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :or => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :pa => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :pap => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :pl => { :i18n => { :plural => { :keys => [:one, :few, :other], :rule => lambda { |n| n == 1 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : :other } } } },
+  :ps => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :pt => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } },
+  :"pt-PT" => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :ro => { :i18n => { :plural => { :keys => [:one, :few, :other], :rule => lambda { |n| n == 1 ? :one : n == 0 ? :few : :other } } } },
+  :ru => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other } } } },
+  :se => { :i18n => { :plural => { :keys => [:one, :two, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : :other } } } },
+  :sh => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other } } } },
+  :sk => { :i18n => { :plural => { :keys => [:one, :few, :other], :rule => lambda { |n| n == 1 ? :one : [2, 3, 4].include?(n) ? :few : :other } } } },
+  :sl => { :i18n => { :plural => { :keys => [:one, :two, :few, :other], :rule => lambda { |n| n % 100 == 1 ? :one : n % 100 == 2 ? :two : [3, 4].include?(n % 100) ? :few : :other } } } },
+  :sma => { :i18n => { :plural => { :keys => [:one, :two, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : :other } } } },
+  :smi => { :i18n => { :plural => { :keys => [:one, :two, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : :other } } } },
+  :smj => { :i18n => { :plural => { :keys => [:one, :two, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : :other } } } },
+  :smn => { :i18n => { :plural => { :keys => [:one, :two, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : :other } } } },
+  :sms => { :i18n => { :plural => { :keys => [:one, :two, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : :other } } } },
+  :so => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :sq => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :sr => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other } } } },
+  :sv => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :sw => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :ta => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :te => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :th => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :ti => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } },
+  :tk => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :tl => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } },
+  :to => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :tr => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :uk => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other } } } },
+  :ur => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } },
+  :vi => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :wa => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } },
+  :yo => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :zh => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } },
+  :zu => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }
+}
+
diff --git a/app/server/vendor/i18n/test/test_helper.rb b/app/server/vendor/i18n/test/test_helper.rb
new file mode 100644
index 0000000..d24b81f
--- /dev/null
+++ b/app/server/vendor/i18n/test/test_helper.rb
@@ -0,0 +1,76 @@
+$KCODE = 'u' if RUBY_VERSION <= '1.9'
+
+require 'rubygems'
+
+# Use minitest if we can, otherwise fallback to test-unit.
+begin
+  require 'minitest/autorun'
+  TEST_CASE = defined?(Minitest::Test) ? Minitest::Test : MiniTest::Unit::TestCase
+
+  # TODO: Remove these aliases and update tests accordingly.
+  class TEST_CASE
+    alias :assert_raise :assert_raises
+    alias :assert_not_equal :refute_equal
+
+    def assert_nothing_raised(*args)
+      yield
+    end
+  end
+rescue LoadError
+  require 'test/unit'
+  TEST_CASE = Test::Unit::TestCase
+end
+
+# Do not load the i18n gem from libraries like active_support.
+#
+# This is required for testing against Rails 2.3 because active_support/vendor.rb#24 tries
+# to load I18n using the gem method. Instead, we want to test the local library of course.
+alias :gem_for_ruby_19 :gem # for 1.9. gives a super ugly seg fault otherwise
+def gem(gem_name, *version_requirements)
+  gem_name =='i18n' ? puts("skipping loading the i18n gem ...") : super
+end
+
+require 'bundler/setup'
+require 'i18n'
+require 'mocha/setup'
+require 'test_declarative'
+
+class I18n::TestCase < TEST_CASE
+  def self.setup_rufus_tokyo
+    require 'rufus/tokyo'
+  rescue LoadError => e
+    puts "can't use KeyValue backend because: #{e.message}"
+  end
+
+  def teardown
+    super
+    I18n.locale = nil
+    I18n.default_locale = :en
+    I18n.load_path = []
+    I18n.available_locales = nil
+    I18n.backend = nil
+    I18n.enforce_available_locales = nil
+  end
+
+  # Ignore Test::Unit::TestCase failing if the test case does not contain any
+  # test, otherwise it will blow up because of this base class.
+  #
+  # TODO: remove when test-unit is not used anymore.
+  def default_test
+    nil
+  end
+
+  protected
+
+  def translations
+    I18n.backend.instance_variable_get(:@translations)
+  end
+
+  def store_translations(locale, data)
+    I18n.backend.store_translations(locale, data)
+  end
+
+  def locales_dir
+    File.dirname(__FILE__) + '/test_data/locales'
+  end
+end
diff --git a/app/server/vendor/interception/.gitignore b/app/server/vendor/interception/.gitignore
new file mode 100755
index 0000000..c6100c8
--- /dev/null
+++ b/app/server/vendor/interception/.gitignore
@@ -0,0 +1,9 @@
+.rbx
+ext/Makefile
+*.class
+*.o
+*.so
+*.gem
+*.lock
+doc/
+.yardoc
diff --git a/app/server/vendor/interception/.travis.yml b/app/server/vendor/interception/.travis.yml
new file mode 100755
index 0000000..3838ec5
--- /dev/null
+++ b/app/server/vendor/interception/.travis.yml
@@ -0,0 +1,12 @@
+language: ruby
+rvm:
+  - 2.1.1
+  - 2.1.0
+  - 2.0.0
+  - 1.9.3
+  - 1.9.2
+  - jruby-18mode
+  - jruby-19mode
+  - rbx
+  - 1.8.7
+  - ree
diff --git a/app/server/vendor/interception/CHANGELOG.md b/app/server/vendor/interception/CHANGELOG.md
new file mode 100755
index 0000000..43b66d0
--- /dev/null
+++ b/app/server/vendor/interception/CHANGELOG.md
@@ -0,0 +1,17 @@
+Interception changelog
+======================
+
+### v0.5 (March 6, 2014)
+
+* Added support for MRI 2.1.1
+* Added support for MRI 2.0.0-p451
+* Changed support for MRI 2.0.0 with patchlevel lower than p451
+  not using NativeExtension but using TracePointAPI which Ruby offers.
+
+### v0.4 (January 21, 2014)
+
+* Added support for MRI 2.1.0
+
+### v0.3 and lower
+
+* We weren't writing changelogs before, sorry.
diff --git a/app/server/vendor/interception/Gemfile b/app/server/vendor/interception/Gemfile
new file mode 100755
index 0000000..851fabc
--- /dev/null
+++ b/app/server/vendor/interception/Gemfile
@@ -0,0 +1,2 @@
+source 'https://rubygems.org'
+gemspec
diff --git a/app/server/vendor/interception/LICENSE.MIT b/app/server/vendor/interception/LICENSE.MIT
new file mode 100755
index 0000000..2161828
--- /dev/null
+++ b/app/server/vendor/interception/LICENSE.MIT
@@ -0,0 +1,19 @@
+Copyright (c) 2012 Conrad Irwin <conrad.irwin at gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/app/server/vendor/interception/README.md b/app/server/vendor/interception/README.md
new file mode 100755
index 0000000..d821c31
--- /dev/null
+++ b/app/server/vendor/interception/README.md
@@ -0,0 +1,84 @@
+
+Interception (intercept + exception) allows you to intercept all exceptions as they are
+raised.
+
+Installation
+============
+
+As with all rubygems, use gem to install:
+
+```shell
+gem install interception
+```
+
+Or, if you're using bundler:
+
+```ruby
+source 'https://rubygems.org'
+gem 'interception'
+```
+
+Usage
+=====
+
+Add and remove listeners. They'll be called whenever an exception is raised (whether or
+not it would later be rescued) with both the exception object, and the binding from which
+it was raised. The binding can be used to discover further information about the context.
+
+```ruby
+require 'interception'
+listener = lambda{ |exception, binding|
+  puts "raised: #{exception.inspect}"
+}
+
+Interception.listen(listener)
+
+begin
+  raise "oopsy"
+rescue => exception
+  puts "rescued: #{exception.inspect}"
+end
+
+raise "daisy"
+
+Interception.unlisten(listener)
+```
+
+In the common case that you want to listen to events for the duration of a block, you can
+also pass that block to listen:
+
+```ruby
+require 'interception'
+def log_exceptions(&block)
+  Interception.listen(block) do |exception, binding|
+    puts "raised: #{exception.inspect} from #{binding.eval("__method__")}"
+  end
+end
+
+def hello
+  raise "oopsy"
+rescue => exception
+  puts "rescued: #{exception.inspect} in #{__method__}"
+  raise "daisy"
+end
+
+log_exceptions do
+  hello
+end
+```
+
+Your listen block is run as through it were called by `Kernel#raise`, so try not to raise
+an exception from within it, or you will loose the original exception.
+
+Known bugs
+==========
+
+* On rubinius we don't catch some low-level exceptions (like `ZeroDivisionError`).
+* On MRI-1.8.7, the binding sometimes has the wrong value for `self`.
+* The Interception versions prior to `0.4` **do not** support MRI-2.1.0. `>= 0.4` does support it.
+
+Meta-fu
+=======
+
+Interception is released under the MIT license (see `LICENSE.MIT` for details).
+Contributions and bug reports are welcome.
diff --git a/app/server/vendor/interception/Rakefile b/app/server/vendor/interception/Rakefile
new file mode 100755
index 0000000..ee485a4
--- /dev/null
+++ b/app/server/vendor/interception/Rakefile
@@ -0,0 +1,32 @@
+
+task :clean do
+  sh 'rm -f ext/*.o ext/*.so ext/*.dylib'
+  sh 'rm -f ext/org/pryrepl/*.class'
+end
+
+desc "Compile *.c files"
+task :compile => [:clean] do
+  cd 'ext/' do
+    sh 'ruby extconf.rb'
+    sh 'make'
+  end
+end
+
+desc "Run example"
+task :example do
+  sh "ruby -I./lib/ ./examples/example.rb "
+end
+
+desc "Run example 2"
+task :example2 do
+  sh "ruby -I./lib/ ./examples/example2.rb "
+end
+
+desc "Run tests"
+task :test do
+  sh 'rspec spec -r ./spec/spec_helpers.rb'
+end
+
+task :default => [:compile, :test]
+
+
diff --git a/app/server/vendor/interception/examples/example.rb b/app/server/vendor/interception/examples/example.rb
new file mode 100755
index 0000000..ffd2173
--- /dev/null
+++ b/app/server/vendor/interception/examples/example.rb
@@ -0,0 +1,16 @@
+require 'interception'
+listener = lambda{ |exception, binding|
+  puts "raised: #{exception.inspect}"
+}
+
+Interception.listen(listener)
+
+begin
+  raise "oopsy"
+rescue => exception
+  puts "rescued: #{exception.inspect}"
+end
+
+raise "daisy"
+
+Interception.unlisten(listener)
diff --git a/app/server/vendor/interception/examples/example2.rb b/app/server/vendor/interception/examples/example2.rb
new file mode 100755
index 0000000..03b5205
--- /dev/null
+++ b/app/server/vendor/interception/examples/example2.rb
@@ -0,0 +1,17 @@
+require 'interception'
+def log_exceptions(&block)
+  Interception.listen(block) do |exception, binding|
+    puts "raised: #{exception.inspect} from #{binding.eval("__method__")}"
+  end
+end
+
+def hello
+  raise "oopsy"
+rescue => exception
+  puts "rescued: #{exception.inspect} in #{__method__}"
+  raise "daisy"
+end
+
+log_exceptions do
+  hello
+end
diff --git a/app/server/vendor/interception/ext/extconf.rb b/app/server/vendor/interception/ext/extconf.rb
new file mode 100755
index 0000000..3d118d4
--- /dev/null
+++ b/app/server/vendor/interception/ext/extconf.rb
@@ -0,0 +1,25 @@
+require 'rbconfig'
+
+
+if RbConfig::CONFIG['ruby_install_name'] == 'jruby'
+
+  File.open("Makefile", "w") do |f|
+    f.write "install:\n\tjrubyc --javac org/pryrepl/InterceptionEventHook.java\n"
+  end
+
+elsif RbConfig::CONFIG['ruby_install_name'] =~ /^ruby/ && RUBY_VERSION.to_f < 2.0
+
+  require 'mkmf'
+  $CFLAGS += " -DRUBY_18" if RUBY_VERSION =~ /^(1.8)/
+  $CFLAGS += " -DRUBY_19" if RUBY_VERSION =~ /^(1.9)/
+  extension_name = "interception"
+  dir_config(extension_name)
+  create_makefile(extension_name)
+
+else
+
+  File.open("Makefile", "w") do |f|
+    f.write "install:\n\t:\n"
+  end
+
+end
diff --git a/app/server/vendor/interception/ext/interception.c b/app/server/vendor/interception/ext/interception.c
new file mode 100755
index 0000000..6d32647
--- /dev/null
+++ b/app/server/vendor/interception/ext/interception.c
@@ -0,0 +1,80 @@
+#include "ruby.h"
+
+static VALUE rb_mInterception;
+
+struct FRAME {
+    VALUE self;
+    int argc;
+    ID last_func;
+    ID orig_func;
+    VALUE last_class;
+    struct FRAME *prev;
+    struct FRAME *tmp;
+    struct RNode *node;
+    int iter;
+    int flags;
+    unsigned long uniq;
+} *ruby_frame;
+
+#ifdef RUBY_18
+
+#include "node.h"
+
+void
+interception_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
+{
+    VALUE bself = ruby_frame->prev->self;
+    if (node == ruby_frame->node) {
+        bself = ruby_frame->prev->prev->self;
+    }
+
+    VALUE binding = rb_funcall(bself, rb_intern("binding"), 0, NULL);
+    rb_funcall(rb_mInterception, rb_intern("rescue"), 2, ruby_errinfo, binding);
+}
+
+VALUE
+interception_start(VALUE self)
+{
+    rb_add_event_hook(interception_hook, RUBY_EVENT_RAISE);
+    return Qnil;
+}
+
+VALUE
+interception_stop(VALUE self)
+{
+    rb_remove_event_hook(interception_hook);
+    return Qnil;
+}
+
+#elif RUBY_19
+
+void
+interception_hook(rb_event_flag_t evflag, VALUE data, VALUE self, ID mid, VALUE klass)
+{
+    VALUE binding = rb_funcall(rb_mKernel, rb_intern("binding"), 0, NULL);
+    rb_funcall(rb_mInterception, rb_intern("rescue"), 2, rb_errinfo(), binding);
+}
+
+VALUE
+interception_start(VALUE self)
+{
+    rb_add_event_hook(interception_hook, RUBY_EVENT_RAISE, rb_mInterception);
+    return Qnil;
+}
+
+VALUE
+interception_stop(VALUE self)
+{
+    rb_remove_event_hook(interception_hook);
+    return Qnil;
+}
+#endif
+
+void
+Init_interception()
+{
+    rb_mInterception = rb_define_module("Interception");
+
+    rb_define_singleton_method(rb_mInterception, "start", interception_start, 0);
+    rb_define_singleton_method(rb_mInterception, "stop", interception_stop, 0);
+}
diff --git a/app/server/vendor/interception/ext/org/pryrepl/InterceptionEventHook.java b/app/server/vendor/interception/ext/org/pryrepl/InterceptionEventHook.java
new file mode 100755
index 0000000..99e4bc3
--- /dev/null
+++ b/app/server/vendor/interception/ext/org/pryrepl/InterceptionEventHook.java
@@ -0,0 +1,28 @@
+package org.pryrepl;
+
+import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.runtime.EventHook;
+import org.jruby.runtime.RubyEvent;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.RubyException;
+import org.jruby.RubyBinding;
+import org.jruby.RubyProc;
+
+public class InterceptionEventHook extends EventHook {
+
+    private RubyProc proc;
+
+    public InterceptionEventHook(RubyProc proc) {
+        this.proc = proc;
+    }
+
+    public boolean isInterestedInEvent(RubyEvent event) {
+        return event == RubyEvent.RAISE;
+    }
+
+    public void eventHandler(ThreadContext context, String eventName, String file, int line, String name, IRubyObject type) {
+        RubyBinding binding = RubyBinding.newBinding(context.runtime, context.currentBinding());
+        RubyException exception = (RubyException)context.runtime.getGlobalVariables().get("$!");
+        proc.call(context, new IRubyObject[] {exception, binding});
+    }
+}
diff --git a/app/server/vendor/interception/interception.gemspec b/app/server/vendor/interception/interception.gemspec
new file mode 100755
index 0000000..241e021
--- /dev/null
+++ b/app/server/vendor/interception/interception.gemspec
@@ -0,0 +1,16 @@
+Gem::Specification.new do |s|
+  s.name = "interception"
+  s.version = "0.5"
+  s.author = "Conrad Irwin"
+  s.email = "conrad.irwin at gmail.com"
+  s.homepage = "http://github.com/ConradIrwin/interception"
+  s.summary = "Intercept exceptions as they are being raised"
+  s.description = "Provides a cross-platform ability to intercept all exceptions as they are raised."
+
+  s.files = `git ls-files`.split("\n")
+  s.extensions = "ext/extconf.rb"
+  s.require_path = "lib"
+
+  s.add_development_dependency 'rake'
+  s.add_development_dependency 'rspec'
+end
diff --git a/app/server/vendor/interception/lib/cross_platform.rb b/app/server/vendor/interception/lib/cross_platform.rb
new file mode 100755
index 0000000..5a3061d
--- /dev/null
+++ b/app/server/vendor/interception/lib/cross_platform.rb
@@ -0,0 +1,84 @@
+# Platform specific implementations of Interception.start and Interception.stop
+class << Interception
+  private
+
+  # For Rubinius we just monkeypatch Kernel#raise_exception,
+  #
+  # This is normally a thin wrapper around raising an exception on the VM
+  # (so the layer of abstraction below Kernel#raise).
+  if defined? Rubinius
+
+    def start
+      class << Rubinius
+
+        alias raise_with_no_interception raise_exception
+
+        def raise_exception(exc)
+          bt = Rubinius::VM.backtrace(1, true).drop_while do |x|
+            x.variables.method.file.to_s.start_with?("kernel/")
+          end.first
+          b = Binding.setup(bt.variables, bt.variables.method, bt.constant_scope, bt.variables.self, bt)
+
+          Interception.rescue(exc, b)
+          raise_with_no_interception(exc)
+        end
+      end
+    end
+
+    def stop
+      class << Rubinius
+        alias raise_exception raise_with_no_interception
+      end
+    end
+
+  # For JRuby we use the underlying hooks mechanism.
+  #
+  # It seems to work even if I don't pass --debug, but it still
+  # warns about it. So disable the warnings and install the hook.
+  elsif defined?(JRuby)
+
+    require 'java'
+    $CLASSPATH << File.expand_path('../../ext/', __FILE__)
+    java_import org.pryrepl.InterceptionEventHook
+
+    def start
+      old_verbose = $VERBOSE
+      $VERBOSE = nil
+      JRuby.runtime.add_event_hook(hook)
+    ensure
+      $VERBOSE  = old_verbose
+    end
+
+    def stop
+      JRuby.runtime.remove_event_hook(hook)
+    end
+
+    def hook
+      @hook ||= InterceptionEventHook.new(proc do |e, b|
+        self.rescue(e, b)
+      end)
+    end
+
+  # For MRI
+  # @note For Ruby 2.0 and later we use the new TracePoint API.
+  elsif RUBY_VERSION.to_f >= 2.0 && RUBY_ENGINE == 'ruby'
+
+    def start
+      @tracepoint ||= TracePoint.new(:raise) do |tp|
+        self.rescue(tp.raised_exception, tp.binding)
+      end
+
+      @tracepoint.enable
+    end
+
+    def stop
+      @tracepoint.disable
+    end
+
+  # For old MRI
+  else
+
+    require File.expand_path('../../ext/interception', __FILE__)
+
+  end
+end
diff --git a/app/server/vendor/interception/lib/interception.rb b/app/server/vendor/interception/lib/interception.rb
new file mode 100755
index 0000000..af2a883
--- /dev/null
+++ b/app/server/vendor/interception/lib/interception.rb
@@ -0,0 +1,120 @@
+require 'thread'
+
+
+# Provides global facility for monitoring exceptions raised in your application.
+module Interception
+
+  class << self
+    attr_accessor :mutex, :listeners, :rescueing
+  end
+  self.mutex = Mutex.new
+  self.listeners = []
+  self.rescueing = false
+
+  # Listen for any exceptions raised.
+  #
+  # The listener block that you pass in will be executed as though inside Kernel#raise,
+  # so your entire program is still actively running. If you have a gem like
+  # pry-stack_explorer you can access the stack frames that lead to the exception
+  # occurring.
+  #
+  # NOTE: Be careful when writing a listener, if your listener raises an
+  # exception it will mask the original exception (though it will not recursively
+  # call your listener).
+  #
+  # @example
+  #
+  #   # To report exceptions for the entire run of the program:
+  #   Interception.listen do |exception, binding|
+  #     Emailer.spam!('on-duty at startup.com', exception, binding.eval('self.class.name'))
+  #   end
+  #
+  # @example
+  #
+  #   # To log exceptions for the duration of a given block.
+  #   def log_exceptions(&block)
+  #     Interception.listen(block) do |exception, binding|
+  #       puts "#{binding.eval("self.inspect")} raised #{exception.inspect}"
+  #     end
+  #   end
+  #
+  # @example
+  #
+  #   # You can also turn listeners on and off manually
+  #
+  #   listener = Proc.new{ |exception, binding|
+  #     binding.pry
+  #   }
+  #   Interception.listen(listener)
+  #   Async::Redis.get("foo") do
+  #     Interception.unlisten(listener)
+  #   end
+  #
+  # @param [Proc] for_block (nil) If you pass for_block in, then you will only
+  #                               intercept exceptions raised while that block
+  #                               is running.
+  # @param [Proc] listen_block    The block to call when an exception occurs,
+  #                               takes two arguments, the exception and the
+  #                               binding
+  # @return [Object]              The return value of the for_block (if present)
+  # @yield [exception, binding]
+  # @see .unlisten
+  def self.listen(for_block=nil, &listen_block)
+    raise ArgumentError, "no block given" unless listen_block || for_block
+    mutex.synchronize{
+      start if listeners.empty?
+      listeners << (listen_block || for_block)
+    }
+
+    if listen_block && for_block
+      begin
+        for_block.call
+      ensure
+        unlisten listen_block
+      end
+    else
+      listen_block
+    end
+  end
+
+  # Disable a previously added listener
+  #
+  # @param [Proc] listen_block  The listen block you wish to remove.
+  # @see .listen
+  def self.unlisten(listen_block)
+    mutex.synchronize{
+      listeners.delete listen_block
+      stop if listeners.empty?
+    }
+  end
+
+  # Called by platform-specific implementations whenever an exception is raised.
+  #
+  # The arguments will be forwarded on to all listeners added via {listen} that
+  # haven't been removed via {unlisten}.
+  #
+  # For efficiency, this block will never be called unless there are active
+  # listeners.
+  #
+  # @param [Exception] exception  The exception that was raised
+  # @param [Binding] binding  The binding from which it was raised
+  def self.rescue(exception, binding)
+    return if rescueing
+    self.rescueing = true
+    listeners.each do |l|
+      l.call(exception, binding)
+    end
+  ensure
+    self.rescueing = false
+  end
+
+  # Start sending events to rescue.
+  # Implemented per-platform
+  def self.start; raise NotImplementedError end
+
+  # Stop sending events to rescue.
+  # Implemented per-platform
+  def self.stop; raise NotImplementedError end
+
+  require File.expand_path('../cross_platform.rb', __FILE__)
+end
diff --git a/app/server/vendor/interception/spec/interception_spec.rb b/app/server/vendor/interception/spec/interception_spec.rb
new file mode 100755
index 0000000..825b023
--- /dev/null
+++ b/app/server/vendor/interception/spec/interception_spec.rb
@@ -0,0 +1,160 @@
+Interception.listen(proc {
+  begin; raise "fooo"; rescue; end
+}) do |e, b|
+  $initial_eb = [e,b]
+end
+
+describe Interception do
+
+  before do
+    @exceptions = []
+    Interception.listen do |e, b|
+      @exceptions << [e, b]
+    end
+  end
+
+  after do
+    Interception.listeners.each do |l|
+      Interception.unlisten l
+    end
+  end
+
+  it "should allow keeping a log of all exceptions raised" do
+    begin
+      raise "foo"
+    rescue => e
+      #
+    end
+
+    @exceptions.map(&:first).should == [e]
+  end
+
+  it "should catch the correct binding" do
+    shoulder = :bucket
+    begin
+      raise "foo"
+    rescue => e
+      #
+    end
+
+    @exceptions.map{ |e, b| b.eval('shoulder') }.should == [:bucket]
+  end
+
+  it "should catch the binding on the correct line" do
+    shoulder = :bucket
+
+    line = nil
+    begin
+      line = __LINE__; raise "foo"
+    rescue => e
+      #
+    end
+
+    @exceptions.map{ |e, b| b.eval('__LINE__') }.should == [line]
+  end
+
+  it "should catch all nested exceptions" do
+
+    begin
+      begin
+        raise "foo"
+      rescue => e1
+        raise "bar"
+      end
+    rescue => e2
+      #
+    end
+
+    @exceptions.map(&:first).should == [e1, e2]
+  end
+
+  it "should be able to listen for the duration of a block" do
+
+    e1, e2 = nil
+    block = proc{
+      begin
+        line = __LINE__; raise "foo"
+      rescue => e1
+        #
+      end
+    }
+    Interception.listen(block) do |e, b|
+      e2 = e
+    end
+
+    e1.should == e2
+  end
+
+  it "should allow nested calls to listen with a block" do
+    e1, e2 = nil
+    b1, b2 = nil
+    block = proc{
+      begin
+        raise "foo"
+      rescue => e1
+        #
+      end
+    }
+    block2 = proc{
+      Interception.listen(block) do |e, b|
+        e2 = e
+        b1 = b
+      end
+    }
+    Interception.listen(block2) do |e, b|
+      b2 = b
+    end
+
+    e1.should == e2
+    b1.should == b2
+  end
+
+  it "should be able to handle NoMethodErrors" do
+    shoulder = :bucket
+
+    begin
+      line = __LINE__; "snorkle".desnrok
+    rescue => e1
+      #
+    end
+
+    @exceptions.map{ |e, b| [e] + b.eval('[__LINE__, shoulder, self]') }.should == [[e1, line, :bucket, self]]
+    e1.message.should =~ /desnrok/
+  end
+
+  it "should be able to handle division by 0 errors" do
+    pending "RBX doesn't yet support this",
+      :if => defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx' do
+
+      shoulder = :bucket
+
+      begin
+        line = __LINE__; 1 / 0
+      rescue => e1
+        #
+      end
+
+      @exceptions.map{ |e, b| [e] + b.eval('[__LINE__, shoulder, self]') }.should == [[e1, line, :bucket, self]]
+      ZeroDivisionError.should === e1
+    end
+  end
+
+  it "should have the right exception and binding at the top level" do
+    $initial_eb.last.eval("self").should == TOPLEVEL_BINDING.eval("self")
+  end
+
+  if defined? BasicObject
+    it "should catch exceptions on basic objects" do
+
+      line = __LINE__ + 1
+      foo = Class.new(BasicObject){ def oops; shoulder = :bracket; foops; end }.new
+      begin
+        foo.oops
+      rescue => e1
+        #
+      end
+
+      @exceptions.map{ |e, b| [e] + b.eval('[self, shoulder, __LINE__]') }.should  == [[e1, foo, :bracket, line]]
+    end
+  end
+end
diff --git a/app/server/vendor/interception/spec/spec_helpers.rb b/app/server/vendor/interception/spec/spec_helpers.rb
new file mode 100755
index 0000000..569b6fb
--- /dev/null
+++ b/app/server/vendor/interception/spec/spec_helpers.rb
@@ -0,0 +1 @@
+require File.expand_path('../../lib/interception', __FILE__)
diff --git a/app/server/vendor/kramdown/AUTHORS b/app/server/vendor/kramdown/AUTHORS
new file mode 100644
index 0000000..0583596
--- /dev/null
+++ b/app/server/vendor/kramdown/AUTHORS
@@ -0,0 +1 @@
+The author of kramdown is Thomas Leitner <t_leitner at gmx.at>.
diff --git a/app/server/vendor/kramdown/CONTRIBUTERS b/app/server/vendor/kramdown/CONTRIBUTERS
new file mode 100644
index 0000000..0795ad7
--- /dev/null
+++ b/app/server/vendor/kramdown/CONTRIBUTERS
@@ -0,0 +1,31 @@
+  Count Name
+======= ====
+    676 Thomas Leitner <t_leitner at gmx.at>
+      6 Gioele Barabucci <gioele at svario.it>
+      4 Ted Pak <powerpak006 at gmail.com>
+      4 Arne Brasseur <arne at arnebrasseur.net>
+      3 Henning Perl <perl at fast-sicher.de>
+      3 gettalong <t_leitner at gmx.at>
+      3 Brandur <brandur at mutelight.org>
+      3 Ben Armston <ben.armston at googlemail.com>
+      3 Alex Marandon <contact at alexmarandon.com>
+      2 Nathanael Jones <nathanael.jones at gmail.com>
+      2 Jo Hund <jhund at clearcove.ca>
+      2 Bran <m.versum at gmail.com>
+      1 Trevor Wennblom <trevor at well.com>
+      1 tomykaira <tomykaira at gmail.com>
+      1 Tim Besard <tim.besard at gmail.com>
+      1 Tim Bates <tim at rumpuslabs.com>
+      1 Simon Lydell <simon.lydell at gmail.com>
+      1 Shusaku NAKAZATO <cu393uc at gmail.com>
+      1 Postmodern <postmodern.mod3 at gmail.com>
+      1 Pete Michaud <michaudp at gmail.com>
+      1 myqlarson <myqlarson at gmail.com>
+      1 Michal Till <michal.till at gmail.com>
+      1 Matt Hickford <matt.hickford at gmail.com>
+      1 Marcus Stollsteimer <sto.mar at web.de>
+      1 Luca Barbato <luca.barbato at gmail.com>
+      1 John Croisant <jacius at gmail.com>
+      1 Joe Fiorini <joe at faithfulgeek.org>
+      1 Damien Pollet <damien.pollet at gmail.com>
+      1 Alex Tomlins <alex.tomlins at digital.cabinet-office.gov.uk>
diff --git a/app/server/vendor/kramdown/COPYING b/app/server/vendor/kramdown/COPYING
new file mode 100644
index 0000000..1c29282
--- /dev/null
+++ b/app/server/vendor/kramdown/COPYING
@@ -0,0 +1,30 @@
+kramdown - fast, pure-Ruby Markdown-superset converter
+Copyright (C) 2009-2013 Thomas Leitner <t_leitner at gmx.at>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+Some test cases and the benchmark files are based on test cases from
+the MDTest test suite:
+
+    MDTest
+    Copyright (c) 2007 Michel Fortin
+    <http://www.michelf.com/>
+
diff --git a/app/server/vendor/kramdown/README.md b/app/server/vendor/kramdown/README.md
new file mode 100644
index 0000000..604d10d
--- /dev/null
+++ b/app/server/vendor/kramdown/README.md
@@ -0,0 +1,68 @@
+# kramdown
+
+## Readme first!
+
+kramdown was originally licensed under the GPL until the 1.0.0 release. However, due to the many
+requests it is now released under the MIT license and therefore can easily be used in commercial
+projects, too.
+
+However, if you use kramdown in a commercial setting, please consider **contributing back any
+changes** for the benefit of the community and/or **making a donation** (see the links in the
+sidebar on the [kramdown homepage](http://kramdown.gettalong.org/)!
+
+
+## Introduction
+
+kramdown is yet-another-markdown-parser but fast, pure Ruby, using a strict syntax definition and
+supporting several common extensions.
+
+The syntax definition for the kramdown syntax can be found in **doc/syntax.page** (or online at
+<http://kramdown.gettalong.org/syntax.html>) and a quick reference is available in
+**doc/quickref.page** or online at <http://kramdown.gettalong.org/quickref.html>.
+
+The kramdown library is mainly written to support the kramdown-to-HTML conversion chain. However,
+due to its flexibility it supports other input and output formats as well. Here is a list of the
+supported formats:
+
+* input formats: kramdown (a Markdown superset), Markdown, HTML
+* output formats: HTML, kramdown, LaTeX (and therefore PDF)
+
+All the documentation on the available input and output formats is available in the **doc/**
+directory and online at <http://kramdown.gettalong.org>.
+
+Starting from version 1.0.0 kramdown is using a versioning scheme with major, minor and patch parts
+in the version number where the major number changes on backwards-incompatible changes, the minor
+number on the introduction of new features and the patch number on everything else.
+
+
+## Usage
+
+kramdown has a basic *Cloth API, so using kramdown is as easy as
+
+```ruby
+require 'kramdown'
+
+Kramdown::Document.new(text).to_html
+```
+
+For detailed information have a look at the API documentation of the `Kramdown::Document` class.
+
+The full API documentation is available at <http://kramdown.gettalong.org/rdoc/>, other sites with an
+API documentation for kramdown probably don't provide the complete documentation!
+
+There are also some third-party libraries that extend the functionality of kramdown -- see the
+kramdown Wiki at <https://github.com/gettalong/kramdown/wiki>.
+
+
+## Development
+
+Just clone the git repository as described in **doc/installation.page** and you are good to go. You
+probably want to install `rake` so that you can use the provided rake tasks. Aside from that:
+
+* The `tidy` binary needs to be installed for the automatically derived tests to work.
+* The `latex` binary needs to be installed for the latex-compilation tests to work.
+
+
+## License
+
+MIT - see the **COPYING** file.
diff --git a/app/server/vendor/kramdown/Rakefile b/app/server/vendor/kramdown/Rakefile
new file mode 100644
index 0000000..d831151
--- /dev/null
+++ b/app/server/vendor/kramdown/Rakefile
@@ -0,0 +1,267 @@
+# -*- ruby -*-
+
+# load all optional developer libraries
+begin
+  require 'rubygems'
+  require 'rubygems/package_task'
+rescue LoadError
+end
+
+begin
+  require 'webgen/page'
+rescue LoadError
+end
+
+begin
+  gem 'rdoc' if RUBY_VERSION >= '1.9'
+  require 'rdoc/task'
+  require 'rdoc/rdoc'
+
+  class RDoc::RDoc
+
+    alias :old_parse_files :parse_files
+
+    def parse_files(options)
+      file_info = old_parse_files(options)
+      require 'kramdown/options'
+
+      # Add options documentation to Kramdown::Options module
+      opt_module = @store.all_classes_and_modules.find {|m| m.full_name == 'Kramdown::Options'}
+      opt_defs = Kramdown::Options.definitions.sort.collect do |n, definition|
+        desc = definition.desc.split(/\n/).map {|l| "    #{l}"}
+        desc[-2] = []
+        desc = desc.join("\n")
+        "[<tt>#{n}</tt> (type: #{definition.type}, default: #{definition.default.inspect})]\n#{desc}\n\n"
+      end
+      opt_module.comment.text += "\n== Available Options\n\n" << opt_defs.join("\n\n")
+
+      file_info
+    end
+
+  end
+
+rescue LoadError
+end
+
+begin
+  require 'rcov/rcovtask'
+rescue LoadError
+end
+
+require 'fileutils'
+require 'rake/clean'
+require 'rake/testtask'
+require 'rake/packagetask'
+require 'erb'
+
+$:.unshift('lib')
+require 'kramdown'
+
+# End user tasks ################################################################
+
+task :default => :test
+
+desc "Install using setup.rb"
+task :install do
+  ruby "setup.rb config"
+  ruby "setup.rb setup"
+  ruby "setup.rb install"
+end
+
+task :clobber do
+  ruby "setup.rb clean"
+end
+
+if defined?(Webgen)
+  desc "Generate the HTML documentation"
+  task :htmldoc do
+    ruby "-Ilib -S webgen"
+  end
+  CLOBBER << "htmldoc/"
+  CLOBBER << "webgen-tmp"
+end
+
+if defined? RDoc::Task
+  rd = RDoc::Task.new do |rdoc|
+    rdoc.rdoc_dir = 'htmldoc/rdoc'
+    rdoc.title = 'kramdown'
+    rdoc.main = 'lib/kramdown/document.rb'
+    rdoc.rdoc_files.include('lib')
+  end
+end
+
+if defined?(Webgen) && defined?(RDoc::Task)
+  desc "Build the whole user documentation"
+  task :doc => [:rdoc, 'htmldoc']
+end
+
+tt = Rake::TestTask.new do |test|
+  test.warning = false
+  test.libs << 'test'
+  test.test_files = FileList['test/test_*.rb']
+end
+
+# Release tasks and development tasks ############################################
+
+namespace :dev do
+
+  SUMMARY = 'kramdown is a fast, pure-Ruby Markdown-superset converter.'
+  DESCRIPTION = <<EOF
+kramdown is yet-another-markdown-parser but fast, pure Ruby,
+using a strict syntax definition and supporting several common extensions.
+EOF
+
+  begin
+    REL_PAGE = Webgen::Page.from_data(File.read('doc/news/release_' + Kramdown::VERSION.split('.').join('_') + '.page'))
+  rescue
+    puts 'NO RELEASE NOTES/CHANGES FILE'
+  end
+
+  PKG_FILES = FileList.new([
+                            'Rakefile',
+                            'setup.rb',
+                            'COPYING', 'README.md', 'AUTHORS',
+                            'VERSION', 'CONTRIBUTERS',
+                            'bin/*',
+                            'benchmark/*',
+                            'lib/**/*.rb',
+                            'man/man1/kramdown.1',
+                            'data/**/*',
+                            'doc/**',
+                            'test/**/*'
+                           ])
+
+  CLOBBER << "VERSION"
+  file 'VERSION' do
+    puts "Generating VERSION file"
+    File.open('VERSION', 'w+') {|file| file.write(Kramdown::VERSION + "\n")}
+  end
+
+  CLOBBER << 'CONTRIBUTERS'
+  file 'CONTRIBUTERS' do
+    puts "Generating CONTRIBUTERS file"
+    `echo "  Count Name" > CONTRIBUTERS`
+    `echo "======= ====" >> CONTRIBUTERS`
+    `git log | grep ^Author: | sed 's/^Author: //' | sort | uniq -c | sort -nr >> CONTRIBUTERS`
+  end
+
+  CLOBBER << "man/man1/kramdown.1"
+  file 'man/man1/kramdown.1' => ['man/man1/kramdown.1.erb'] do
+    puts "Generating kramdown man page"
+    File.open('man/man1/kramdown.1', 'w+') do |file|
+      file.write(ERB.new(File.read('man/man1/kramdown.1.erb')).result(binding))
+    end
+  end
+
+  Rake::PackageTask.new('kramdown', Kramdown::VERSION) do |pkg|
+    pkg.need_tar = true
+    pkg.need_zip = true
+    pkg.package_files = PKG_FILES
+  end
+
+  if defined? Gem
+    spec = Gem::Specification.new do |s|
+
+      #### Basic information
+      s.name = 'kramdown'
+      s.version = Kramdown::VERSION
+      s.summary = SUMMARY
+      s.description = DESCRIPTION
+      s.license = 'MIT'
+
+      #### Dependencies, requirements and files
+      s.files = PKG_FILES.to_a
+
+      s.require_path = 'lib'
+      s.executables = ['kramdown']
+      s.default_executable = 'kramdown'
+      s.add_development_dependency 'minitest', '~> 5.0'
+      s.add_development_dependency 'coderay', '~> 1.0.0'
+      s.add_development_dependency 'stringex', '~> 1.5.1'
+      s.add_development_dependency 'prawn', '~> 0.13'
+
+      #### Documentation
+
+      s.has_rdoc = true
+      s.rdoc_options = ['--main', 'lib/kramdown/document.rb']
+
+      #### Author and project details
+
+      s.author = 'Thomas Leitner'
+      s.email = 't_leitner at gmx.at'
+      s.homepage = "http://kramdown.gettalong.org"
+    end
+
+
+    task :gemspec => [ 'CONTRIBUTERS', 'VERSION', 'man/man1/kramdown.1'] do
+      print "Generating Gemspec\n"
+      contents = spec.to_ruby
+      File.open("kramdown.gemspec", 'w+') {|f| f.puts(contents)}
+    end
+
+    Gem::PackageTask.new(spec) do |pkg|
+      pkg.need_zip = true
+      pkg.need_tar = true
+    end
+
+  end
+
+  if defined?(Webgen) && defined?(Gem) && defined?(Rake::RDocTask)
+    desc 'Release Kramdown version ' + Kramdown::VERSION
+    task :release => [:clobber, :package, :publish_files, :publish_website]
+  end
+
+  if defined?(Gem)
+    desc "Upload the release to Rubygems"
+    task :publish_files => [:package] do
+      sh "gem push pkg/kramdown-#{Kramdown::VERSION}.gem"
+      puts 'done'
+    end
+  end
+
+  desc "Upload the website"
+  task :publish_website => ['doc'] do
+    puts "Transfer manually!!!"
+    # sh "rsync -avc --delete --exclude 'MathJax' --exclude 'robots.txt'  htmldoc/ gettalong at rubyforge.org:/var/www/gforge-projects/kramdown/"
+  end
+
+
+  if defined? Rcov
+    Rcov::RcovTask.new do |rcov|
+      rcov.libs << 'test'
+    end
+  end
+
+  CODING_LINE = "# -*- coding: utf-8 -*-\n"
+  COPYRIGHT=<<EOF
+#
+#--
+# Copyright (C) 2009-2013 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+EOF
+
+  desc "Insert/Update copyright notice"
+  task :update_copyright do
+    inserted = false
+    Dir["lib/**/*.rb", "test/**/*.rb"].each do |file|
+      if !File.read(file).start_with?(CODING_LINE + COPYRIGHT)
+        inserted = true
+        puts "Updating file #{file}"
+        old = File.read(file)
+        if !old.gsub!(/\A#{Regexp.escape(CODING_LINE)}#\n#--.*?\n#\+\+\n#\n/m, CODING_LINE + COPYRIGHT)
+          old.gsub!(/\A(#{Regexp.escape(CODING_LINE)})?/, CODING_LINE + COPYRIGHT + "\n")
+        end
+        File.open(file, 'w+') {|f| f.puts(old)}
+      end
+    end
+    puts "Look through the above mentioned files and correct all problems" if inserted
+  end
+
+end
+
+task :gemspec => ['dev:gemspec']
+
+task :clobber => ['dev:clobber']
diff --git a/app/server/vendor/kramdown/VERSION b/app/server/vendor/kramdown/VERSION
new file mode 100644
index 0000000..88c5fb8
--- /dev/null
+++ b/app/server/vendor/kramdown/VERSION
@@ -0,0 +1 @@
+1.4.0
diff --git a/app/server/vendor/kramdown/benchmark/benchmark.rb b/app/server/vendor/kramdown/benchmark/benchmark.rb
new file mode 100644
index 0000000..bad86af
--- /dev/null
+++ b/app/server/vendor/kramdown/benchmark/benchmark.rb
@@ -0,0 +1,43 @@
+require 'benchmark'
+require 'stringio'
+
+require 'kramdown'
+require 'bluecloth'
+require 'maruku'
+require 'maruku/version'
+require 'rdiscount'
+require 'bluefeather'
+require 'redcarpet'
+
+module MaRuKu::Errors
+  def tell_user(s)
+  end
+end
+
+
+RUNS=20
+
+FILES=['mdsyntax.text', 'mdbasics.text']
+
+puts "Running tests on #{Time.now.strftime("%Y-%m-%d")} under #{RUBY_DESCRIPTION}"
+
+FILES.each do |file|
+  data = File.read(File.join(File.dirname(__FILE__), file))
+  puts
+  puts "Test using file #{file} and #{RUNS} runs"
+  results = Benchmark.bmbm do |b|
+    b.report("kramdown #{Kramdown::VERSION}") { RUNS.times { Kramdown::Document.new(data).to_html } }
+    b.report("Maruku #{MaRuKu::Version}") { RUNS.times { Maruku.new(data, :on_error => :ignore).to_html } }
+    b.report("BlueFeather #{BlueFeather::VERSION}") { RUNS.times { BlueFeather.parse(data) } }
+    b.report("BlueCloth #{BlueCloth::VERSION}") { RUNS.times { BlueCloth.new(data).to_html } }
+    b.report("RDiscount #{RDiscount::VERSION}") { RUNS.times { RDiscount.new(data).to_html } }
+    b.report("redcarpet #{Redcarpet::VERSION}") { RUNS.times { Redcarpet::Markdown.new(Redcarpet::Render::HTML).render(data) } }
+  end
+
+  puts
+  puts "Real time of X divided by real time of kramdown"
+  kd = results.shift.real
+  %w[Maruku BlueFeather BlueCloth RDiscount redcarpet].each do |name|
+    puts name.ljust(19) << (results.shift.real/kd).round(4).to_s
+  end
+end
diff --git a/app/server/vendor/kramdown/benchmark/benchmark.sh b/app/server/vendor/kramdown/benchmark/benchmark.sh
new file mode 100644
index 0000000..b652554
--- /dev/null
+++ b/app/server/vendor/kramdown/benchmark/benchmark.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+
+source ~/.bashrc
+
+RUBY_VERSIONS=`rvm list strings | sort`
+KD_VERSIONS="`git tag | sort -V` master"
+OTHERS=false
+AVERAGE=1
+MASTER_AS=master
+
+while getopts "r:k:o:m:a:" optname; do
+    case "$optname" in
+        "r")
+            RUBY_VERSIONS="$OPTARG"
+            ;;
+        "k")
+            KD_VERSIONS="$OPTARG"
+            ;;
+        "o")
+            OTHERS=true
+	    ;;
+	"m")
+	    MASTER_AS="$OPTARG"
+            ;;
+	"a")
+	    AVERAGE="$OPTARG"
+	    ;;
+        "?")
+            echo "Unknown option $OPTARG"
+            exit 1
+            ;;
+        ":")
+            echo "No argument value for option $OPTARG"
+            exit 1
+            ;;
+        *)
+            echo "Unknown error while processing options"
+            exit 1
+            ;;
+    esac
+done
+
+TMPDIR=/tmp/kramdown-benchmark
+
+rm -rf $TMPDIR
+mkdir -p $TMPDIR
+cp benchmark/md* $TMPDIR
+cp benchmark/generate_data.rb $TMPDIR
+git clone .git ${TMPDIR}/kramdown
+cd ${TMPDIR}/kramdown
+
+for RUBY_VERSION in $RUBY_VERSIONS; do
+	rvm $RUBY_VERSION
+	echo "Creating benchmark data for $(ruby -v)"
+
+    for KD_VERSION in $KD_VERSIONS; do
+        echo "Using kramdown version $KD_VERSION"
+        git co $KD_VERSION 2>/dev/null
+        if [ -z $MASTER_AS -o $KD_VERSION != master ]; then
+            VNUM=${KD_VERSION}
+        else
+            VNUM=$MASTER_AS
+        fi
+        ruby -I${TMPDIR}/kramdown/lib ../generate_data.rb -k ${VNUM} -a ${AVERAGE} >/dev/null
+    done
+
+    if [ $OTHERS = "true" ]; then
+        ruby -rubygems -I${TMPDIR}/kramdown/lib ../generate_data.rb -o >/dev/null
+    fi
+done
+
+cd ${TMPDIR}
+rvm default
+ruby generate_data.rb -g
diff --git a/app/server/vendor/kramdown/benchmark/generate_data.rb b/app/server/vendor/kramdown/benchmark/generate_data.rb
new file mode 100644
index 0000000..762ebc3
--- /dev/null
+++ b/app/server/vendor/kramdown/benchmark/generate_data.rb
@@ -0,0 +1,119 @@
+require 'benchmark'
+require 'optparse'
+require 'fileutils'
+
+require 'kramdown'
+
+options = {:others => false, :average => 1}
+OptionParser.new do |opts|
+  opts.on("-a AVG", "--average AVG", Integer, "Average times over the specified number of runs") {|v| options[:average] = v }
+  opts.on("-o", "--[no-]others", "Generate data for other parsers") {|v| options[:others] = v}
+  opts.on("-g", "--[no-]graph", "Generate graph") {|v| options[:graph] = v}
+  opts.on("-k VERSION", "--kramdown VERSION", String, "Add benchmark data for kramdown version VERSION") {|v| options[:kramdown] = v}
+end.parse!
+
+THISRUBY = (self.class.const_defined?(:RUBY_DESCRIPTION) ? RUBY_DESCRIPTION.scan(/^.*?(?=\s*\()/).first.sub(/\s/, '-') : "ruby-#{RUBY_VERSION}") + '-' + RUBY_PATCHLEVEL.to_s
+
+Dir.chdir(File.dirname(__FILE__))
+BMDATA = File.read('mdbasics.text')
+MULTIPLIER = (0..5).map {|i| 2**i}
+
+if options[:others]
+  require 'maruku'
+  require 'maruku/version'
+  begin
+    require 'rdiscount'
+  rescue LoadError
+  end
+  #require 'bluefeather'
+
+  module MaRuKu::Errors
+    def tell_user(s)
+    end
+  end
+
+  bmdata = {}
+  labels = []
+  MULTIPLIER.each do |i|
+    $stderr.puts "Generating benchmark data for other parsers, multiplier #{i}"
+    mddata = BMDATA*i
+    labels = []
+    bmdata[i] = Benchmark::bmbm do |x|
+      labels << "Maruku #{MaRuKu::Version}"
+      x.report { Maruku.new(mddata, :on_error => :ignore).to_html }
+      if self.class.const_defined?(:BlueFeather)
+        labels << "BlueFeather #{BlueFeather::VERSION}"
+        x.report { BlueFeather.parse(mddata) }
+      end
+      if self.class.const_defined?(:RDiscount)
+        labels << "RDiscount #{RDiscount::VERSION}"
+        x.report { RDiscount.new(mddata).to_html }
+      end
+    end
+  end
+  File.open("static-#{THISRUBY}.dat", 'w+') do |f|
+    f.puts "# " + labels.join(" || ")
+    format_str = "%5d" + " %10.5f"*bmdata[MULTIPLIER.first].size
+    bmdata.sort.each do |m,v|
+      f.puts format_str % [m, *v.map {|tms| tms.real}]
+    end
+  end
+end
+
+if options[:kramdown]
+  kramdown = "kramdown-#{THISRUBY}.dat"
+  data = if File.exist?(kramdown)
+           lines = File.readlines(kramdown).map {|l| l.chomp}
+           lines.first << " || "
+           lines
+         else
+           ["#      ", *MULTIPLIER.map {|m| "%3d" % m}]
+         end
+  data.first << "#{options[:kramdown]}".rjust(10)
+
+  times = []
+  options[:average].times do
+    MULTIPLIER.each_with_index do |m, i|
+      $stderr.puts "Generating benchmark data for kramdown version #{options[:kramdown]}, multiplier #{m}"
+      mddata = BMDATA*m
+      begin
+        (times[i] ||= []) << Benchmark::bmbm {|x| x.report { Kramdown::Document.new(mddata).to_html } }.first.real
+      rescue
+        $stderr.puts $!.message
+        (times[i] ||= []) << 0
+      end
+    end
+  end
+  times.each_with_index {|t,i| data[i+1] << "%14.5f" % (t.inject(0) {|sum,v| sum+v}/3.0)}
+  File.open(kramdown, 'w+') do |f|
+    data.each {|l| f.puts l}
+  end
+end
+
+if options[:graph]
+  Dir['kramdown-*.dat'].each do |kramdown_name|
+    theruby = kramdown_name.sub(/^kramdown-/, '').sub(/\.dat$/, '')
+    graph_name = "graph-#{theruby}.png"
+    static_name = "static-#{theruby}.dat"
+    kramdown_names = File.readlines(kramdown_name).first.chomp[1..-1].split(/\s*\|\|\s*/)
+    static_names = (File.exist?(static_name) ? File.readlines(static_name).first.chomp[1..-1].split(/\s*\|\|\s*/) : [])
+    File.open("gnuplot.dat", "w+") do |f|
+      f.puts <<EOF
+set title "Execution Time Performance for #{theruby}"
+set xlabel "File Multiplier (i.e. n times mdbasic.text)"
+set ylabel "Execution Time in secondes"
+set key left top
+set grid
+set terminal png
+set output "#{graph_name}"
+EOF
+      f.print "plot "
+      i, j = 1, 1
+      f.puts((kramdown_names.map {|n| i += 1; "\"#{kramdown_name}\" using 1:#{i} with lp title \"#{n}\""} +
+              static_names.map {|n| j += 1; n =~ /bluefeather/i ? nil : "\"#{static_name}\" using 1:#{j} with lp title \"#{n}\""}.compact
+             ).join(", "))
+    end
+    `gnuplot gnuplot.dat`
+    FileUtils.rm("gnuplot.dat")
+  end
+end
diff --git a/app/server/vendor/kramdown/benchmark/mdbasics.text b/app/server/vendor/kramdown/benchmark/mdbasics.text
new file mode 100644
index 0000000..486055c
--- /dev/null
+++ b/app/server/vendor/kramdown/benchmark/mdbasics.text
@@ -0,0 +1,306 @@
+Markdown: Basics
+================
+
+<ul id="ProjectSubmenu">
+    <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
+    <li><a class="selected" title="Markdown Basics">Basics</a></li>
+    <li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li>
+    <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
+    <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
+</ul>
+
+
+Getting the Gist of Markdown's Formatting Syntax
+------------------------------------------------
+
+This page offers a brief overview of what it's like to use Markdown.
+The [syntax page] [s] provides complete, detailed documentation for
+every feature, but Markdown should be very easy to pick up simply by
+looking at a few examples of it in action. The examples on this page
+are written in a before/after style, showing example syntax and the
+HTML output produced by Markdown.
+
+It's also helpful to simply try Markdown out; the [Dingus] [d] is a
+web application that allows you type your own Markdown-formatted text
+and translate it to XHTML.
+
+**Note:** This document is itself written using Markdown; you
+can [see the source for it by adding '.text' to the URL] [src].
+
+  [s]: /projects/markdown/syntax  "Markdown Syntax"
+  [d]: /projects/markdown/dingus  "Markdown Dingus"
+  [src]: /projects/markdown/basics.text
+
+
+## Paragraphs, Headers, Blockquotes ##
+
+A paragraph is simply one or more consecutive lines of text, separated
+by one or more blank lines. (A blank line is any line that looks like a
+blank line -- a line containing nothing spaces or tabs is considered
+blank.) Normal paragraphs should not be intended with spaces or tabs.
+
+Markdown offers two styles of headers: *Setext* and *atx*.
+Setext-style headers for `<h1>` and `<h2>` are created by
+"underlining" with equal signs (`=`) and hyphens (`-`), respectively.
+To create an atx-style header, you put 1-6 hash marks (`#`) at the
+beginning of the line -- the number of hashes equals the resulting
+HTML header level.
+
+Blockquotes are indicated using email-style '`>`' angle brackets.
+
+Markdown:
+
+    A First Level Header
+    ====================
+    
+    A Second Level Header
+    ---------------------
+
+    Now is the time for all good men to come to
+    the aid of their country. This is just a
+    regular paragraph.
+
+    The quick brown fox jumped over the lazy
+    dog's back.
+    
+    ### Header 3
+
+    > This is a blockquote.
+    > 
+    > This is the second paragraph in the blockquote.
+    >
+    > ## This is an H2 in a blockquote
+
+
+Output:
+
+    <h1>A First Level Header</h1>
+    
+    <h2>A Second Level Header</h2>
+    
+    <p>Now is the time for all good men to come to
+    the aid of their country. This is just a
+    regular paragraph.</p>
+    
+    <p>The quick brown fox jumped over the lazy
+    dog's back.</p>
+    
+    <h3>Header 3</h3>
+    
+    <blockquote>
+        <p>This is a blockquote.</p>
+        
+        <p>This is the second paragraph in the blockquote.</p>
+        
+        <h2>This is an H2 in a blockquote</h2>
+    </blockquote>
+
+
+
+### Phrase Emphasis ###
+
+Markdown uses asterisks and underscores to indicate spans of emphasis.
+
+Markdown:
+
+    Some of these words *are emphasized*.
+    Some of these words _are emphasized also_.
+    
+    Use two asterisks for **strong emphasis**.
+    Or, if you prefer, __use two underscores instead__.
+
+Output:
+
+    <p>Some of these words <em>are emphasized</em>.
+    Some of these words <em>are emphasized also</em>.</p>
+    
+    <p>Use two asterisks for <strong>strong emphasis</strong>.
+    Or, if you prefer, <strong>use two underscores instead</strong>.</p>
+   
+
+
+## Lists ##
+
+Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`,
+`+`, and `-`) as list markers. These three markers are
+interchangable; this:
+
+    *   Candy.
+    *   Gum.
+    *   Booze.
+
+this:
+
+    +   Candy.
+    +   Gum.
+    +   Booze.
+
+and this:
+
+    -   Candy.
+    -   Gum.
+    -   Booze.
+
+all produce the same output:
+
+    <ul>
+    <li>Candy.</li>
+    <li>Gum.</li>
+    <li>Booze.</li>
+    </ul>
+
+Ordered (numbered) lists use regular numbers, followed by periods, as
+list markers:
+
+    1.  Red
+    2.  Green
+    3.  Blue
+
+Output:
+
+    <ol>
+    <li>Red</li>
+    <li>Green</li>
+    <li>Blue</li>
+    </ol>
+
+If you put blank lines between items, you'll get `<p>` tags for the
+list item text. You can create multi-paragraph list items by indenting
+the paragraphs by 4 spaces or 1 tab:
+
+    *   A list item.
+    
+        With multiple paragraphs.
+
+    *   Another item in the list.
+
+Output:
+
+    <ul>
+    <li><p>A list item.</p>
+    <p>With multiple paragraphs.</p></li>
+    <li><p>Another item in the list.</p></li>
+    </ul>
+    
+
+
+### Links ###
+
+Markdown supports two styles for creating links: *inline* and
+*reference*. With both styles, you use square brackets to delimit the
+text you want to turn into a link.
+
+Inline-style links use parentheses immediately after the link text.
+For example:
+
+    This is an [example link](http://example.com/).
+
+Output:
+
+    <p>This is an <a href="http://example.com/">
+    example link</a>.</p>
+
+Optionally, you may include a title attribute in the parentheses:
+
+    This is an [example link](http://example.com/ "With a Title").
+
+Output:
+
+    <p>This is an <a href="http://example.com/" title="With a Title">
+    example link</a>.</p>
+
+Reference-style links allow you to refer to your links by names, which
+you define elsewhere in your document:
+
+    I get 10 times more traffic from [Google][1] than from
+    [Yahoo][2] or [MSN][3].
+
+    [1]: http://google.com/        "Google"
+    [2]: http://search.yahoo.com/  "Yahoo Search"
+    [3]: http://search.msn.com/    "MSN Search"
+
+Output:
+
+    <p>I get 10 times more traffic from <a href="http://google.com/"
+    title="Google">Google</a> than from <a href="http://search.yahoo.com/"
+    title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"
+    title="MSN Search">MSN</a>.</p>
+
+The title attribute is optional. Link names may contain letters,
+numbers and spaces, but are *not* case sensitive:
+
+    I start my morning with a cup of coffee and
+    [The New York Times][NY Times].
+
+    [ny times]: http://www.nytimes.com/
+
+Output:
+
+    <p>I start my morning with a cup of coffee and
+    <a href="http://www.nytimes.com/">The New York Times</a>.</p>
+
+
+### Images ###
+
+Image syntax is very much like link syntax.
+
+Inline (titles are optional):
+
+    ![alt text](/path/to/img.jpg "Title")
+
+Reference-style:
+
+    ![alt text][id]
+
+    [id]: /path/to/img.jpg "Title"
+
+Both of the above examples produce the same output:
+
+    <img src="/path/to/img.jpg" alt="alt text" title="Title" />
+
+
+
+### Code ###
+
+In a regular paragraph, you can create code span by wrapping text in
+backtick quotes. Any ampersands (`&`) and angle brackets (`<` or
+`>`) will automatically be translated into HTML entities. This makes
+it easy to use Markdown to write about HTML example code:
+
+    I strongly recommend against using any `<blink>` tags.
+
+    I wish SmartyPants used named entities like `—`
+    instead of decimal-encoded entites like `—`.
+
+Output:
+
+    <p>I strongly recommend against using any
+    <code><blink></code> tags.</p>
+    
+    <p>I wish SmartyPants used named entities like
+    <code>&mdash;</code> instead of decimal-encoded
+    entites like <code>&#8212;</code>.</p>
+
+
+To specify an entire block of pre-formatted code, indent every line of
+the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`,
+and `>` characters will be escaped automatically.
+
+Markdown:
+
+    If you want your page to validate under XHTML 1.0 Strict,
+    you've got to put paragraph tags in your blockquotes:
+
+        <blockquote>
+            <p>For example.</p>
+        </blockquote>
+
+Output:
+
+    <p>If you want your page to validate under XHTML 1.0 Strict,
+    you've got to put paragraph tags in your blockquotes:</p>
+    
+    <pre><code><blockquote>
+        <p>For example.</p>
+    </blockquote>
+    </code></pre>
diff --git a/app/server/vendor/kramdown/benchmark/mdsyntax.text b/app/server/vendor/kramdown/benchmark/mdsyntax.text
new file mode 100644
index 0000000..57360a1
--- /dev/null
+++ b/app/server/vendor/kramdown/benchmark/mdsyntax.text
@@ -0,0 +1,888 @@
+Markdown: Syntax
+================
+
+<ul id="ProjectSubmenu">
+    <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
+    <li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li>
+    <li><a class="selected" title="Markdown Syntax Documentation">Syntax</a></li>
+    <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
+    <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
+</ul>
+
+
+*   [Overview](#overview)
+    *   [Philosophy](#philosophy)
+    *   [Inline HTML](#html)
+    *   [Automatic Escaping for Special Characters](#autoescape)
+*   [Block Elements](#block)
+    *   [Paragraphs and Line Breaks](#p)
+    *   [Headers](#header)
+    *   [Blockquotes](#blockquote)
+    *   [Lists](#list)
+    *   [Code Blocks](#precode)
+    *   [Horizontal Rules](#hr)
+*   [Span Elements](#span)
+    *   [Links](#link)
+    *   [Emphasis](#em)
+    *   [Code](#code)
+    *   [Images](#img)
+*   [Miscellaneous](#misc)
+    *   [Backslash Escapes](#backslash)
+    *   [Automatic Links](#autolink)
+
+
+**Note:** This document is itself written using Markdown; you
+can [see the source for it by adding '.text' to the URL][src].
+
+  [src]: /projects/markdown/syntax.text
+
+* * *
+
+<h2 id="overview">Overview</h2>
+
+<h3 id="philosophy">Philosophy</h3>
+
+Markdown is intended to be as easy-to-read and easy-to-write as is feasible.
+
+Readability, however, is emphasized above all else. A Markdown-formatted
+document should be publishable as-is, as plain text, without looking
+like it's been marked up with tags or formatting instructions. While
+Markdown's syntax has been influenced by several existing text-to-HTML
+filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4],
+[Grutatext] [5], and [EtText] [6] -- the single biggest source of
+inspiration for Markdown's syntax is the format of plain text email.
+
+  [1]: http://docutils.sourceforge.net/mirror/setext.html
+  [2]: http://www.aaronsw.com/2002/atx/
+  [3]: http://textism.com/tools/textile/
+  [4]: http://docutils.sourceforge.net/rst.html
+  [5]: http://www.triptico.com/software/grutatxt.html
+  [6]: http://ettext.taint.org/doc/
+
+To this end, Markdown's syntax is comprised entirely of punctuation
+characters, which punctuation characters have been carefully chosen so
+as to look like what they mean. E.g., asterisks around a word actually
+look like \*emphasis\*. Markdown lists look like, well, lists. Even
+blockquotes look like quoted passages of text, assuming you've ever
+used email.
+
+
+
+<h3 id="html">Inline HTML</h3>
+
+Markdown's syntax is intended for one purpose: to be used as a
+format for *writing* for the web.
+
+Markdown is not a replacement for HTML, or even close to it. Its
+syntax is very small, corresponding only to a very small subset of
+HTML tags. The idea is *not* to create a syntax that makes it easier
+to insert HTML tags. In my opinion, HTML tags are already easy to
+insert. The idea for Markdown is to make it easy to read, write, and
+edit prose. HTML is a *publishing* format; Markdown is a *writing*
+format. Thus, Markdown's formatting syntax only addresses issues that
+can be conveyed in plain text.
+
+For any markup that is not covered by Markdown's syntax, you simply
+use HTML itself. There's no need to preface it or delimit it to
+indicate that you're switching from Markdown to HTML; you just use
+the tags.
+
+The only restrictions are that block-level HTML elements -- e.g. `<div>`,
+`<table>`, `<pre>`, `<p>`, etc. -- must be separated from surrounding
+content by blank lines, and the start and end tags of the block should
+not be indented with tabs or spaces. Markdown is smart enough not
+to add extra (unwanted) `<p>` tags around HTML block-level tags.
+
+For example, to add an HTML table to a Markdown article:
+
+    This is a regular paragraph.
+
+    <table>
+        <tr>
+            <td>Foo</td>
+        </tr>
+    </table>
+
+    This is another regular paragraph.
+
+Note that Markdown formatting syntax is not processed within block-level
+HTML tags. E.g., you can't use Markdown-style `*emphasis*` inside an
+HTML block.
+
+Span-level HTML tags -- e.g. `<span>`, `<cite>`, or `<del>` -- can be
+used anywhere in a Markdown paragraph, list item, or header. If you
+want, you can even use HTML tags instead of Markdown formatting; e.g. if
+you'd prefer to use HTML `<a>` or `<img>` tags instead of Markdown's
+link or image syntax, go right ahead.
+
+Unlike block-level HTML tags, Markdown syntax *is* processed within
+span-level tags.
+
+
+<h3 id="autoescape">Automatic Escaping for Special Characters</h3>
+
+In HTML, there are two characters that demand special treatment: `<`
+and `&`. Left angle brackets are used to start tags; ampersands are
+used to denote HTML entities. If you want to use them as literal
+characters, you must escape them as entities, e.g. `<`, and
+`&`.
+
+Ampersands in particular are bedeviling for web writers. If you want to
+write about 'AT&T', you need to write '`AT&T`'. You even need to
+escape ampersands within URLs. Thus, if you want to link to:
+
+    http://images.google.com/images?num=30&q=larry+bird
+
+you need to encode the URL as:
+
+    http://images.google.com/images?num=30&q=larry+bird
+
+in your anchor tag `href` attribute. Needless to say, this is easy to
+forget, and is probably the single most common source of HTML validation
+errors in otherwise well-marked-up web sites.
+
+Markdown allows you to use these characters naturally, taking care of
+all the necessary escaping for you. If you use an ampersand as part of
+an HTML entity, it remains unchanged; otherwise it will be translated
+into `&`.
+
+So, if you want to include a copyright symbol in your article, you can write:
+
+    ©
+
+and Markdown will leave it alone. But if you write:
+
+    AT&T
+
+Markdown will translate it to:
+
+    AT&T
+
+Similarly, because Markdown supports [inline HTML](#html), if you use
+angle brackets as delimiters for HTML tags, Markdown will treat them as
+such. But if you write:
+
+    4 < 5
+
+Markdown will translate it to:
+
+    4 < 5
+
+However, inside Markdown code spans and blocks, angle brackets and
+ampersands are *always* encoded automatically. This makes it easy to use
+Markdown to write about HTML code. (As opposed to raw HTML, which is a
+terrible format for writing about HTML syntax, because every single `<`
+and `&` in your example code needs to be escaped.)
+
+
+* * *
+
+
+<h2 id="block">Block Elements</h2>
+
+
+<h3 id="p">Paragraphs and Line Breaks</h3>
+
+A paragraph is simply one or more consecutive lines of text, separated
+by one or more blank lines. (A blank line is any line that looks like a
+blank line -- a line containing nothing but spaces or tabs is considered
+blank.) Normal paragraphs should not be intended with spaces or tabs.
+
+The implication of the "one or more consecutive lines of text" rule is
+that Markdown supports "hard-wrapped" text paragraphs. This differs
+significantly from most other text-to-HTML formatters (including Movable
+Type's "Convert Line Breaks" option) which translate every line break
+character in a paragraph into a `<br />` tag.
+
+When you *do* want to insert a `<br />` break tag using Markdown, you
+end a line with two or more spaces, then type return.
+
+Yes, this takes a tad more effort to create a `<br />`, but a simplistic
+"every line break is a `<br />`" rule wouldn't work for Markdown.
+Markdown's email-style [blockquoting][bq] and multi-paragraph [list items][l]
+work best -- and look better -- when you format them with hard breaks.
+
+  [bq]: #blockquote
+  [l]:  #list
+
+
+
+<h3 id="header">Headers</h3>
+
+Markdown supports two styles of headers, [Setext] [1] and [atx] [2].
+
+Setext-style headers are "underlined" using equal signs (for first-level
+headers) and dashes (for second-level headers). For example:
+
+    This is an H1
+    =============
+
+    This is an H2
+    -------------
+
+Any number of underlining `=`'s or `-`'s will work.
+
+Atx-style headers use 1-6 hash characters at the start of the line,
+corresponding to header levels 1-6. For example:
+
+    # This is an H1
+
+    ## This is an H2
+
+    ###### This is an H6
+
+Optionally, you may "close" atx-style headers. This is purely
+cosmetic -- you can use this if you think it looks better. The
+closing hashes don't even need to match the number of hashes
+used to open the header. (The number of opening hashes
+determines the header level.) :
+
+    # This is an H1 #
+
+    ## This is an H2 ##
+
+    ### This is an H3 ######
+
+
+<h3 id="blockquote">Blockquotes</h3>
+
+Markdown uses email-style `>` characters for blockquoting. If you're
+familiar with quoting passages of text in an email message, then you
+know how to create a blockquote in Markdown. It looks best if you hard
+wrap the text and put a `>` before every line:
+
+    > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
+    > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
+    > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
+    > 
+    > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
+    > id sem consectetuer libero luctus adipiscing.
+
+Markdown allows you to be lazy and only put the `>` before the first
+line of a hard-wrapped paragraph:
+
+    > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
+    consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
+    Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
+
+    > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
+    id sem consectetuer libero luctus adipiscing.
+
+Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by
+adding additional levels of `>`:
+
+    > This is the first level of quoting.
+    >
+    > > This is nested blockquote.
+    >
+    > Back to the first level.
+
+Blockquotes can contain other Markdown elements, including headers, lists,
+and code blocks:
+
+	> ## This is a header.
+	> 
+	> 1.   This is the first list item.
+	> 2.   This is the second list item.
+	> 
+	> Here's some example code:
+	> 
+	>     return shell_exec("echo $input | $markdown_script");
+
+Any decent text editor should make email-style quoting easy. For
+example, with BBEdit, you can make a selection and choose Increase
+Quote Level from the Text menu.
+
+
+<h3 id="list">Lists</h3>
+
+Markdown supports ordered (numbered) and unordered (bulleted) lists.
+
+Unordered lists use asterisks, pluses, and hyphens -- interchangably
+-- as list markers:
+
+    *   Red
+    *   Green
+    *   Blue
+
+is equivalent to:
+
+    +   Red
+    +   Green
+    +   Blue
+
+and:
+
+    -   Red
+    -   Green
+    -   Blue
+
+Ordered lists use numbers followed by periods:
+
+    1.  Bird
+    2.  McHale
+    3.  Parish
+
+It's important to note that the actual numbers you use to mark the
+list have no effect on the HTML output Markdown produces. The HTML
+Markdown produces from the above list is:
+
+    <ol>
+    <li>Bird</li>
+    <li>McHale</li>
+    <li>Parish</li>
+    </ol>
+
+If you instead wrote the list in Markdown like this:
+
+    1.  Bird
+    1.  McHale
+    1.  Parish
+
+or even:
+
+    3. Bird
+    1. McHale
+    8. Parish
+
+you'd get the exact same HTML output. The point is, if you want to,
+you can use ordinal numbers in your ordered Markdown lists, so that
+the numbers in your source match the numbers in your published HTML.
+But if you want to be lazy, you don't have to.
+
+If you do use lazy list numbering, however, you should still start the
+list with the number 1. At some point in the future, Markdown may support
+starting ordered lists at an arbitrary number.
+
+List markers typically start at the left margin, but may be indented by
+up to three spaces. List markers must be followed by one or more spaces
+or a tab.
+
+To make lists look nice, you can wrap items with hanging indents:
+
+    *   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+        Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
+        viverra nec, fringilla in, laoreet vitae, risus.
+    *   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
+        Suspendisse id sem consectetuer libero luctus adipiscing.
+
+But if you want to be lazy, you don't have to:
+
+    *   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+    Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
+    viverra nec, fringilla in, laoreet vitae, risus.
+    *   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
+    Suspendisse id sem consectetuer libero luctus adipiscing.
+
+If list items are separated by blank lines, Markdown will wrap the
+items in `<p>` tags in the HTML output. For example, this input:
+
+    *   Bird
+    *   Magic
+
+will turn into:
+
+    <ul>
+    <li>Bird</li>
+    <li>Magic</li>
+    </ul>
+
+But this:
+
+    *   Bird
+
+    *   Magic
+
+will turn into:
+
+    <ul>
+    <li><p>Bird</p></li>
+    <li><p>Magic</p></li>
+    </ul>
+
+List items may consist of multiple paragraphs. Each subsequent
+paragraph in a list item must be intended by either 4 spaces
+or one tab:
+
+    1.  This is a list item with two paragraphs. Lorem ipsum dolor
+        sit amet, consectetuer adipiscing elit. Aliquam hendrerit
+        mi posuere lectus.
+
+        Vestibulum enim wisi, viverra nec, fringilla in, laoreet
+        vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
+        sit amet velit.
+
+    2.  Suspendisse id sem consectetuer libero luctus adipiscing.
+
+It looks nice if you indent every line of the subsequent
+paragraphs, but here again, Markdown will allow you to be
+lazy:
+
+    *   This is a list item with two paragraphs.
+
+        This is the second paragraph in the list item. You're
+    only required to indent the first line. Lorem ipsum dolor
+    sit amet, consectetuer adipiscing elit.
+
+    *   Another item in the same list.
+
+To put a blockquote within a list item, the blockquote's `>`
+delimiters need to be indented:
+
+    *   A list item with a blockquote:
+
+        > This is a blockquote
+        > inside a list item.
+
+To put a code block within a list item, the code block needs
+to be indented *twice* -- 8 spaces or two tabs:
+
+    *   A list item with a code block:
+
+            <code goes here>
+
+
+It's worth noting that it's possible to trigger an ordered list by
+accident, by writing something like this:
+
+    1986. What a great season.
+
+In other words, a *number-period-space* sequence at the beginning of a
+line. To avoid this, you can backslash-escape the period:
+
+    1986\. What a great season.
+
+
+
+<h3 id="precode">Code Blocks</h3>
+
+Pre-formatted code blocks are used for writing about programming or
+markup source code. Rather than forming normal paragraphs, the lines
+of a code block are interpreted literally. Markdown wraps a code block
+in both `<pre>` and `<code>` tags.
+
+To produce a code block in Markdown, simply indent every line of the
+block by at least 4 spaces or 1 tab. For example, given this input:
+
+    This is a normal paragraph:
+
+        This is a code block.
+
+Markdown will generate:
+
+    <p>This is a normal paragraph:</p>
+
+    <pre><code>This is a code block.
+    </code></pre>
+
+One level of indentation -- 4 spaces or 1 tab -- is removed from each
+line of the code block. For example, this:
+
+    Here is an example of AppleScript:
+
+        tell application "Foo"
+            beep
+        end tell
+
+will turn into:
+
+    <p>Here is an example of AppleScript:</p>
+
+    <pre><code>tell application "Foo"
+        beep
+    end tell
+    </code></pre>
+
+A code block continues until it reaches a line that is not indented
+(or the end of the article).
+
+Within a code block, ampersands (`&`) and angle brackets (`<` and `>`)
+are automatically converted into HTML entities. This makes it very
+easy to include example HTML source code using Markdown -- just paste
+it and indent it, and Markdown will handle the hassle of encoding the
+ampersands and angle brackets. For example, this:
+
+        <div class="footer">
+            © 2004 Foo Corporation
+        </div>
+
+will turn into:
+
+    <pre><code><div class="footer">
+        &copy; 2004 Foo Corporation
+    </div>
+    </code></pre>
+
+Regular Markdown syntax is not processed within code blocks. E.g.,
+asterisks are just literal asterisks within a code block. This means
+it's also easy to use Markdown to write about Markdown's own syntax.
+
+
+
+<h3 id="hr">Horizontal Rules</h3>
+
+You can produce a horizontal rule tag (`<hr />`) by placing three or
+more hyphens, asterisks, or underscores on a line by themselves. If you
+wish, you may use spaces between the hyphens or asterisks. Each of the
+following lines will produce a horizontal rule:
+
+    * * *
+
+    ***
+
+    *****
+	
+    - - -
+
+    ---------------------------------------
+
+	_ _ _
+
+
+* * *
+
+<h2 id="span">Span Elements</h2>
+
+<h3 id="link">Links</h3>
+
+Markdown supports two style of links: *inline* and *reference*.
+
+In both styles, the link text is delimited by [square brackets].
+
+To create an inline link, use a set of regular parentheses immediately
+after the link text's closing square bracket. Inside the parentheses,
+put the URL where you want the link to point, along with an *optional*
+title for the link, surrounded in quotes. For example:
+
+    This is [an example](http://example.com/ "Title") inline link.
+
+    [This link](http://example.net/) has no title attribute.
+
+Will produce:
+
+    <p>This is <a href="http://example.com/" title="Title">
+    an example</a> inline link.</p>
+
+    <p><a href="http://example.net/">This link</a> has no
+    title attribute.</p>
+
+If you're referring to a local resource on the same server, you can
+use relative paths:
+
+    See my [About](/about/) page for details.
+
+Reference-style links use a second set of square brackets, inside
+which you place a label of your choosing to identify the link:
+
+    This is [an example][id] reference-style link.
+
+You can optionally use a space to separate the sets of brackets:
+
+    This is [an example] [id] reference-style link.
+
+Then, anywhere in the document, you define your link label like this,
+on a line by itself:
+
+    [id]: http://example.com/  "Optional Title Here"
+
+That is:
+
+*   Square brackets containing the link identifier (optionally
+    indented from the left margin using up to three spaces);
+*   followed by a colon;
+*   followed by one or more spaces (or tabs);
+*   followed by the URL for the link;
+*   optionally followed by a title attribute for the link, enclosed
+    in double or single quotes.
+
+The link URL may, optionally, be surrounded by angle brackets:
+
+    [id]: <http://example.com/>  "Optional Title Here"
+
+You can put the title attribute on the next line and use extra spaces
+or tabs for padding, which tends to look better with longer URLs:
+
+    [id]: http://example.com/longish/path/to/resource/here
+        "Optional Title Here"
+
+Link definitions are only used for creating links during Markdown
+processing, and are stripped from your document in the HTML output.
+
+Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are *not* case sensitive. E.g. these two links:
+
+	[link text][a]
+	[link text][A]
+
+are equivalent.
+
+The *implicit link name* shortcut allows you to omit the name of the
+link, in which case the link text itself is used as the name.
+Just use an empty set of square brackets -- e.g., to link the word
+"Google" to the google.com web site, you could simply write:
+
+	[Google][]
+
+And then define the link:
+
+	[Google]: http://google.com/
+
+Because link names may contain spaces, this shortcut even works for
+multiple words in the link text:
+
+	Visit [Daring Fireball][] for more information.
+
+And then define the link:
+	
+	[Daring Fireball]: http://daringfireball.net/
+
+Link definitions can be placed anywhere in your Markdown document. I
+tend to put them immediately after each paragraph in which they're
+used, but if you want, you can put them all at the end of your
+document, sort of like footnotes.
+
+Here's an example of reference links in action:
+
+    I get 10 times more traffic from [Google] [1] than from
+    [Yahoo] [2] or [MSN] [3].
+
+      [1]: http://google.com/        "Google"
+      [2]: http://search.yahoo.com/  "Yahoo Search"
+      [3]: http://search.msn.com/    "MSN Search"
+
+Using the implicit link name shortcut, you could instead write:
+
+    I get 10 times more traffic from [Google][] than from
+    [Yahoo][] or [MSN][].
+
+      [google]: http://google.com/        "Google"
+      [yahoo]:  http://search.yahoo.com/  "Yahoo Search"
+      [msn]:    http://search.msn.com/    "MSN Search"
+
+Both of the above examples will produce the following HTML output:
+
+    <p>I get 10 times more traffic from <a href="http://google.com/"
+    title="Google">Google</a> than from
+    <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>
+    or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
+
+For comparison, here is the same paragraph written using
+Markdown's inline link style:
+
+    I get 10 times more traffic from [Google](http://google.com/ "Google")
+    than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
+    [MSN](http://search.msn.com/ "MSN Search").
+
+The point of reference-style links is not that they're easier to
+write. The point is that with reference-style links, your document
+source is vastly more readable. Compare the above examples: using
+reference-style links, the paragraph itself is only 81 characters
+long; with inline-style links, it's 176 characters; and as raw HTML,
+it's 234 characters. In the raw HTML, there's more markup than there
+is text.
+
+With Markdown's reference-style links, a source document much more
+closely resembles the final output, as rendered in a browser. By
+allowing you to move the markup-related metadata out of the paragraph,
+you can add links without interrupting the narrative flow of your
+prose.
+
+
+<h3 id="em">Emphasis</h3>
+
+Markdown treats asterisks (`*`) and underscores (`_`) as indicators of
+emphasis. Text wrapped with one `*` or `_` will be wrapped with an
+HTML `<em>` tag; double `*`'s or `_`'s will be wrapped with an HTML
+`<strong>` tag. E.g., this input:
+
+    *single asterisks*
+
+    _single underscores_
+
+    **double asterisks**
+
+    __double underscores__
+
+will produce:
+
+    <em>single asterisks</em>
+
+    <em>single underscores</em>
+
+    <strong>double asterisks</strong>
+
+    <strong>double underscores</strong>
+
+You can use whichever style you prefer; the lone restriction is that
+the same character must be used to open and close an emphasis span.
+
+Emphasis can be used in the middle of a word:
+
+    un*fucking*believable
+
+But if you surround an `*` or `_` with spaces, it'll be treated as a
+literal asterisk or underscore.
+
+To produce a literal asterisk or underscore at a position where it
+would otherwise be used as an emphasis delimiter, you can backslash
+escape it:
+
+    \*this text is surrounded by literal asterisks\*
+
+
+
+<h3 id="code">Code</h3>
+
+To indicate a span of code, wrap it with backtick quotes (`` ` ``).
+Unlike a pre-formatted code block, a code span indicates code within a
+normal paragraph. For example:
+
+    Use the `printf()` function.
+
+will produce:
+
+    <p>Use the <code>printf()</code> function.</p>
+
+To include a literal backtick character within a code span, you can use
+multiple backticks as the opening and closing delimiters:
+
+    ``There is a literal backtick (`) here.``
+
+which will produce this:
+
+    <p><code>There is a literal backtick (`) here.</code></p>
+
+The backtick delimiters surrounding a code span may include spaces --
+one after the opening, one before the closing. This allows you to place
+literal backtick characters at the beginning or end of a code span:
+
+	A single backtick in a code span: `` ` ``
+	
+	A backtick-delimited string in a code span: `` `foo` ``
+
+will produce:
+
+	<p>A single backtick in a code span: <code>`</code></p>
+	
+	<p>A backtick-delimited string in a code span: <code>`foo`</code></p>
+
+With a code span, ampersands and angle brackets are encoded as HTML
+entities automatically, which makes it easy to include example HTML
+tags. Markdown will turn this:
+
+    Please don't use any `<blink>` tags.
+
+into:
+
+    <p>Please don't use any <code><blink></code> tags.</p>
+
+You can write this:
+
+    `—` is the decimal-encoded equivalent of `—`.
+
+to produce:
+
+    <p><code>&#8212;</code> is the decimal-encoded
+    equivalent of <code>&mdash;</code>.</p>
+
+
+
+<h3 id="img">Images</h3>
+
+Admittedly, it's fairly difficult to devise a "natural" syntax for
+placing images into a plain text document format.
+
+Markdown uses an image syntax that is intended to resemble the syntax
+for links, allowing for two styles: *inline* and *reference*.
+
+Inline image syntax looks like this:
+
+    ![Alt text](/path/to/img.jpg)
+
+    ![Alt text](/path/to/img.jpg "Optional title")
+
+That is:
+
+*   An exclamation mark: `!`;
+*   followed by a set of square brackets, containing the `alt`
+    attribute text for the image;
+*   followed by a set of parentheses, containing the URL or path to
+    the image, and an optional `title` attribute enclosed in double
+    or single quotes.
+
+Reference-style image syntax looks like this:
+
+    ![Alt text][id]
+
+Where "id" is the name of a defined image reference. Image references
+are defined using syntax identical to link references:
+
+    [id]: url/to/image  "Optional title attribute"
+
+As of this writing, Markdown has no syntax for specifying the
+dimensions of an image; if this is important to you, you can simply
+use regular HTML `<img>` tags.
+
+
+* * *
+
+
+<h2 id="misc">Miscellaneous</h2>
+
+<h3 id="autolink">Automatic Links</h3>
+
+Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:
+
+    <http://example.com/>
+    
+Markdown will turn this into:
+
+    <a href="http://example.com/">http://example.com/</a>
+
+Automatic links for email addresses work similarly, except that
+Markdown will also perform a bit of randomized decimal and hex
+entity-encoding to help obscure your address from address-harvesting
+spambots. For example, Markdown will turn this:
+
+    <address at example.com>
+
+into something like this:
+
+    <a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65;
+    ss@ex&#x61;m&#x70;&#x6C;e&#x2E;co
+    m">&#x61;&#x64;&#x64;&#x72;&#x65;ss@ex&#x61;
+    m&#x70;&#x6C;e&#x2E;com</a>
+
+which will render in a browser as a clickable link to "address at example.com".
+
+(This sort of entity-encoding trick will indeed fool many, if not
+most, address-harvesting bots, but it definitely won't fool all of
+them. It's better than nothing, but an address published in this way
+will probably eventually start receiving spam.)
+
+
+
+<h3 id="backslash">Backslash Escapes</h3>
+
+Markdown allows you to use backslash escapes to generate literal
+characters which would otherwise have special meaning in Markdown's
+formatting syntax. For example, if you wanted to surround a word with
+literal asterisks (instead of an HTML `<em>` tag), you can backslashes
+before the asterisks, like this:
+
+    \*literal asterisks\*
+
+Markdown provides backslash escapes for the following characters:
+
+    \   backslash
+    `   backtick
+    *   asterisk
+    _   underscore
+    {}  curly braces
+    []  square brackets
+    ()  parentheses
+    #   hash mark
+	+	plus sign
+	-	minus sign (hyphen)
+    .   dot
+    !   exclamation mark
+
diff --git a/app/server/vendor/kramdown/benchmark/testing.sh b/app/server/vendor/kramdown/benchmark/testing.sh
new file mode 100755
index 0000000..eb08fe7
--- /dev/null
+++ b/app/server/vendor/kramdown/benchmark/testing.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+source ~/.bashrc
+
+COMMAND="$@"
+if [[ -z "$COMMAND" ]]; then COMMAND="rake test"; fi
+
+for VERSION in `rvm list strings | sort`; do
+	rvm $VERSION
+	echo $(ruby -v)
+	RUBYOPT=-rubygems $COMMAND
+done
diff --git a/app/server/vendor/kramdown/benchmark/timing.sh b/app/server/vendor/kramdown/benchmark/timing.sh
new file mode 100755
index 0000000..fc009a3
--- /dev/null
+++ b/app/server/vendor/kramdown/benchmark/timing.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+source ~/.bashrc
+
+for VERSION in `rvm list strings | sort`; do
+	rvm $VERSION
+	echo $(ruby -v)
+	ruby -Ilib bin/kramdown < benchmark/mdsyntax.text 2>/dev/null >/dev/null
+	time ruby -Ilib bin/kramdown < benchmark/mdsyntax.text 2>/dev/null >/dev/null
+done
diff --git a/app/server/vendor/kramdown/bin/kramdown b/app/server/vendor/kramdown/bin/kramdown
new file mode 100755
index 0000000..89bff8a
--- /dev/null
+++ b/app/server/vendor/kramdown/bin/kramdown
@@ -0,0 +1,67 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2013 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'optparse'
+require 'kramdown'
+
+options = {}
+format = ['html']
+OptionParser.new do |opts|
+  opts.banner = "Usage: kramdown [options] [FILE FILE ...]"
+  opts.summary_indent = ' '*4
+
+  opts.separator ""
+  opts.separator "Command line options:"
+  opts.separator ""
+
+  opts.on("-i", "--input ARG", "Specify the input format: kramdown (default) or html") {|v| options[:input] = v}
+  opts.on("-o", "--output ARG", Array, "Specify one or more output formats separated by commas: html (default), kramdown, latex or remove_html_tags") {|v| format = v}
+
+  opts.on("-v", "--version", "Show the version of kramdown") do
+    puts Kramdown::VERSION
+    exit
+  end
+  opts.on("-h", "--help", "Show the help") do
+    puts opts.summarize('', 5, 72)
+    exit
+  end
+
+  opts.separator ""
+  opts.separator "kramdown options:"
+  opts.separator ""
+
+  Kramdown::Options.definitions.each do |n, definition|
+    no = n.to_s.tr('_', '-')
+    if definition.type == Kramdown::Options::Boolean
+      opts.on("--[no-]#{no}") {|v| options[n] = Kramdown::Options.parse(n, v)}
+    else
+      type = definition.type
+      type = String if type == Symbol || type == Object
+      opts.on("--#{no} ARG", type) {|v| options[n] = Kramdown::Options.parse(n, v)}
+    end
+
+    definition.desc.split(/\n/).each do |line|
+      opts.separator opts.summary_indent + ' '*6 + line
+    end
+    opts.separator ''
+  end
+
+end.parse!
+
+begin
+  doc = Kramdown::Document.new(ARGF.read, options)
+  result = ''
+  format.each {|f| result = doc.send("to_#{f}")}
+  puts result
+  doc.warnings.each {|warn| $stderr.puts "Warning: #{warn}"}
+rescue Kramdown::Error => e
+  $stderr.puts "Error: #{e.message}"
+  exit(1)
+end
diff --git a/app/server/vendor/kramdown/data/kramdown/document.html b/app/server/vendor/kramdown/data/kramdown/document.html
new file mode 100644
index 0000000..731d0ea
--- /dev/null
+++ b/app/server/vendor/kramdown/data/kramdown/document.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <% if @converter.root.options[:encoding] %>
+    <meta http-equiv="Content-type" content="text/html;charset=<%= @converter.root.options[:encoding] %>">
+    <% end %>
+<%
+extend ::Kramdown::Utils::Html
+title = ''
+h = @converter.root.children.find {|c| c.type == :header}
+if h
+  collector = lambda {|c| c.children.collect {|cc| cc.type == :text ? escape_html(cc.value, :text) : collector.call(cc)}.join('')}
+  title = collector.call(h)
+end
+%>
+    <title><%= title %></title>
+    <meta name="generator" content="kramdown <%= ::Kramdown::VERSION %>" />
+  </head>
+  <body>
+  <%= @body %>
+  </body>
+</html>
diff --git a/app/server/vendor/kramdown/data/kramdown/document.latex b/app/server/vendor/kramdown/data/kramdown/document.latex
new file mode 100644
index 0000000..78d1095
--- /dev/null
+++ b/app/server/vendor/kramdown/data/kramdown/document.latex
@@ -0,0 +1,48 @@
+<%
+encmap = {
+  'UTF-8' => 'utf8x',
+  'US-ASCII' => 'ascii',
+  'ISO-8859-1' => 'latin1',
+  'ISO-8859-2' => 'latin2',
+  'ISO-8859-3' => 'latin3',
+  'ISO-8859-4' => 'latin4',
+  'ISO-8859-5' => 'latin5',
+  'ISO-8859-9' => 'latin9',
+  'ISO-8859-10' => 'latin10',
+  'CP850' => 'cp850',
+  'CP852' => 'cp852',
+  'CP858' => 'cp858',
+  'CP437' => 'cp437',
+  'CP865' => 'cp865',
+  'CP1250' => 'cp120',
+  'CP1252' => 'cp1252',
+  'CP1257' => 'cp1257'
+}
+%>
+\documentclass{scrartcl}
+<% if RUBY_VERSION >= '1.9' %>
+\usepackage[<%= encmap[@body.encoding.name] %>]{inputenc}
+<% else %>
+\usepackage[mathletters]{ucs}
+\usepackage[utf8x]{inputenc}
+<% end %>
+\usepackage[T1]{fontenc}
+\usepackage{listings}
+<% @converter.data[:packages].each {|pkg| %>\usepackage{<%= pkg %>}
+<% } %>
+\usepackage{hyperref}
+
+<% if @converter.data[:packages].include?('fancyvrb') %>
+\VerbatimFootnotes
+<% end %>
+
+<% if @converter.data[:packages].include?('acronym') %>
+<%   @converter.root.options[:abbrev_defs].each_pair do |k,v| %>\acrodef{<%= @converter.normalize_abbreviation_key(k) %>}[<%= k %>]{<%= @converter.escape(v) %>}
+<%   end %>
+<% end %>
+
+\hypersetup{colorlinks=true,urlcolor=blue}
+
+\begin{document}
+<%= @body %>
+\end{document}
diff --git a/app/server/vendor/kramdown/doc/_design.scss b/app/server/vendor/kramdown/doc/_design.scss
new file mode 100644
index 0000000..1a42fe3
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/_design.scss
@@ -0,0 +1,441 @@
+/*  Based on the Less Framework 4
+    http://lessframework.com
+    by Joni Korpi
+    License: http://opensource.org/licenses/mit-license.php */
+
+
+/***** Variables for easy customization *****/
+
+/* the baseline height in px */
+$baseline-height: 24;
+
+/* The overlay color for the background image */
+$bg-grad-color: rgba(255,255,128,0.1);
+
+/* The font size of the logo in px */
+$logo-size: 36;
+
+/* Color settings */
+$link-color: #1666A3;
+
+
+
+/*  Resets
+    ------  */
+
+html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6,
+p, blockquote, pre, a, abbr, address, cite, code, del, dfn, em,
+img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, hr,
+dl, dt, dd, ol, ul, li, fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, figure, figcaption, hgroup,
+menu, footer, header, nav, section, summary, time, mark, audio, video {
+    margin: 0;
+    padding: 0;
+    border: 0;
+}
+
+article, aside, canvas, figure, figure img, figcaption, hgroup,
+footer, header, nav, section, audio, video {
+    display: block;
+}
+
+a img {border: 0;}
+
+
+
+/*  Typography presets
+    ------------------  */
+
+.gigantic {
+    font-size: 59px;
+    line-height: 72px;
+}
+
+.huge {
+    font-size: 36px;
+    line-height: 48px;
+}
+
+.large {
+    font-size: 23px;
+    line-height: 24px;
+}
+
+.bigger {
+    font-size: 18px;
+    line-height: 24px;
+}
+
+.big {
+    font-size: 14px;
+    line-height: 24px;
+}
+
+body {
+    font: 14px/24px 'Palatino Linotype', 'Book Antiqua', Palatino, serif;
+}
+
+.small, small {
+    font-size: 12px;
+    line-height: 24px;
+}
+
+*:target::after {
+    content: " ☜";
+}
+
+
+/* Typographics grid overlay */
+
+.grid{
+    background-image: -moz-linear-gradient(top, rgba(0,0,0,0) 95%, rgba(0,0,0,0.3) 100%); /* FF3.6+ */
+    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(95%,rgba(0,0,0,0)), color-stop(100%,rgba(0,0,0,0.3))); /* Chrome,Safari4+ */
+    background-image: -webkit-linear-gradient(top, rgba(0,0,0,0) 95%,rgba(0,0,0,0.3) 100%); /* Chrome10+,Safari5.1+ */
+    background-image: -o-linear-gradient(top, rgba(0,0,0,0) 95%, rgba(0,0,0,0.3) 100%); /* Opera11.10+ */
+    background-image: -ms-linear-gradient(top, rgba(0,0,0,0) 95%,rgba(0,0,0,0.3) 100%); /* IE10+ */
+    background-image: linear-gradient(top, rgba(0,0,0,0.3) 95%,rgba(0,0,0,0.3) 100%); /* W3C */
+
+    -webkit-background-size: 100% #{$baseline-height}px;
+         -o-background-size: 100% #{$baseline-height}px;
+            background-size: 100% #{$baseline-height}px;
+}
+
+
+/* Basic mixins */
+
+ at mixin background {
+    background-image: -moz-linear-gradient($bg-grad-color, $bg-grad-color), url('bg.png');
+    background-image: -webkit-linear-gradient($bg-grad-color, $bg-grad-color), url('bg.png');
+    background-image: -o-linear-gradient($bg-grad-color, $bg-grad-color), url('bg.png');
+    background-image: -ms-linear-gradient($bg-grad-color, $bg-grad-color), url('bg.png');
+    background-image: linear-gradient($bg-grad-color, $bg-grad-color), url('bg.png');
+}
+
+ at mixin typography($size: big) {
+    h3, h4, h5, h6, p, ul, ol, dl, pre, blockquote, table {
+        margin-top: 24px;
+        margin-bottom: 24px;
+    }
+
+    @if $size == big {
+        h1 { @extend .huge }
+        h2 { @extend .large }
+        h3 { @extend .bigger }
+        h4,h5,h6 { @extend .big }
+    } @else {
+        h1 { @extend .large }
+        h2 { @extend .bigger }
+        h3,h4,h5,h6 { @extend .big }
+    }
+
+    h1, h2, h3, h4, h5, h6 {
+        font-weight: normal;
+        padding-left: 48px;
+        margin-left: -48px;
+        margin-top: 36px;
+        margin-bottom: -12px;
+    }
+
+    ul, ol, dd {
+        padding-left: 24px;
+    }
+
+    ul ul, ul ol, ol ul, ol ol {
+        margin-top: 0;
+        margin-bottom: 0;
+    }
+
+    pre {
+        padding-left: 12px;
+        padding-right: 12px;
+        border: 1px solid #ccc;
+        font-family: "Bitstream Vera Sans Mono", Consolas, monospace;
+    }
+
+    dt {
+        font-weight: bold;
+    }
+
+    a {
+        color: $link-color;
+        text-decoration: underline;
+    }
+
+    a:hover, a:link {
+        color: $link-color / 2;
+    }
+}
+
+/*      Default Layout: 992px.
+        Gutters: 24px.
+        Outer margins: 48px.
+        Leftover space for scrollbars @1024px: 32px.
+        -------------------------------------------------------------------------------
+        cols    1     2      3      4      5      6      7      8      9      10
+        px      68    160    252    344    436    528    620    712    804    896    */
+
+body {
+    width: 992px;
+    margin: 0 auto 48px;
+    color: rgb(60,60,60);
+    -webkit-text-size-adjust: 100%; /* Stops Mobile Safari from auto-adjusting font-sizes */
+    @include background;
+}
+
+body > header {
+    position: relative;
+    padding: 12px;
+    font-family: Verdana;
+    color: #eee;
+    -moz-box-shadow:     0 0 24px rgba(0,0,0,0.6);
+    -webkit-box-shadow:  0 0 24px rgba(0,0,0,0.6);
+    box-shadow:          0 0 24px rgba(0,0,0,0.6);
+    z-index: 1;
+}
+
+#logo {
+    font-size: #{$logo-size}px;
+    line-height:  #{$baseline-height * (floor($logo-size / $baseline-height) + 1)}px;
+    margin: 12px;
+    text-shadow: 0px 2px 5px rgba(0, 0, 0, 0.5);
+
+    a {
+        color: #eee;
+        text-decoration: none;
+
+        &:hover {
+            color: #fff;
+        }
+    }
+
+}
+
+#slogan {
+    font-size: 100%;
+    margin: 12px;
+    text-shadow: 0px 2px 5px rgba(0, 0, 0, 0.5);
+}
+
+nav {
+    position: absolute;
+    bottom: 0px;
+    right: 0px;
+    background-color: rgba(255,255,255,0.1);
+
+    li {
+        display: inline-block;
+    }
+
+    ul {
+        margin: 0;
+        padding: 0;
+    }
+
+    a, span {
+        display: block;
+        padding: 12px;
+        color: #ccc;
+        text-decoration: none;
+    }
+
+    span {
+        background-color: rgba(255,255,255,0.3);
+    }
+
+    a:hover {
+        background-color: rgba(255,255,255,0.3);
+    }
+
+}
+
+#wrapper {
+    clear: both;
+    position: relative;
+    background-color: white;
+    -moz-box-shadow:     0 0 24px rgba(0,0,0,0.6);
+    -webkit-box-shadow:  0 0 24px rgba(0,0,0,0.6);
+    box-shadow:          0 0 24px rgba(0,0,0,0.6);
+}
+
+aside {
+    float: right;
+    right: 0;
+    background-color: white;
+    width: 252px;
+    padding: 24px;
+
+    @include typography(small);
+
+    h1, h2, h3, h4, h5, h6 {
+        padding-left: 48px;
+        margin-left: -48px;
+    }
+}
+
+
+aside.banner {
+    @include background;
+    position: relative;
+    width: inherit;
+    margin: 0;
+    float: none;
+    padding: 24px;
+    border: 10px solid rgba(255,255,255,0.1);
+    color: #ccc;
+    font-size: 36px;
+    line-height: 48px;
+
+    a {
+        color: #ccc;
+        text-decoration: underline;
+    }
+
+    a:hover {
+        background-color: rgba(255,255,255,0.3);
+    }
+
+    p {
+        margin: 0;
+    }
+
+    p + p {
+        margin-top: 24px;
+    }
+}
+
+#content {
+    width: 620px;
+    padding: 24px 48px;
+
+    @include typography(big);
+}
+
+footer {
+   background-color: rgba(255,255,255,0.1);
+   min-height: 24px;
+   color: #eee;
+}
+
+
+/*      Tablet Layout: 768px.
+        Gutters: 24px.
+        Outer margins: 28px.
+        Inherits styles from: Default Layout.
+        -----------------------------------------------------------------
+        cols    1     2      3      4      5      6      7      8
+        px      68    160    252    344    436    528    620    712    */
+
+ at media only screen and (min-width: 768px) and (max-width: 1005px) {
+
+    body {
+        width: 716px;
+    }
+
+    body > header {
+        padding: 0;
+    }
+
+    aside {
+        position: static;
+        float: right;
+    }
+
+    nav {
+        position: relative;
+        margin-top: 12px;
+    }
+}
+
+
+
+/*      Mobile Layout: 320px.
+        Gutters: 24px.
+        Outer margins: 34px.
+        Inherits styles from: Default Layout.
+        ---------------------------------------------
+        cols    1     2      3
+        px      68    160    252    */
+
+ at media only screen and (max-width: 767px) {
+
+    body {
+        width: 320px;
+    }
+
+    body > header {
+        padding: 0;
+    }
+
+    nav {
+        position: relative;
+        margin-top: 12px;
+    }
+
+    aside {
+        position: relative;
+    }
+
+    #content, aside {
+        width: 296px;
+        padding: 24px 12px;
+    }
+
+    #content {
+        h1, h2, h3, h4, h5, h6 {
+            padding-left: 12px;
+            margin-left: -12px;
+        }
+    }
+
+}
+
+
+
+/*      Wide Mobile Layout: 480px.
+        Gutters: 24px.
+        Outer margins: 22px.
+        Inherits styles from: Default Layout, Mobile Layout.
+        ------------------------------------------------------------
+        cols    1     2      3      4      5
+        px      68    160    252    344    436    */
+
+ at media only screen and (min-width: 480px) and (max-width: 767px) {
+
+    body {
+        width: 90%;
+    }
+
+    aside {
+        position: relative;
+    }
+
+    #content, aside {
+        width: inherit;
+        padding: 24px 48px;
+    }
+
+    #content {
+        h1, h2, h3, h4, h5, h6 {
+            padding-left: 48px;
+            margin-left: -48px;
+        }
+    }
+
+}
+
+
+/*  Retina media query.
+    Overrides styles for devices with a
+    device-pixel-ratio of 2+, such as iPhone 4.
+    -----------------------------------------------    */
+
+ at media
+only screen and (-webkit-min-device-pixel-ratio: 2),
+only screen and (min-device-pixel-ratio: 2) {
+
+    body {
+
+    }
+
+}
diff --git a/app/server/vendor/kramdown/doc/bg.png b/app/server/vendor/kramdown/doc/bg.png
new file mode 100644
index 0000000..b4df134
Binary files /dev/null and b/app/server/vendor/kramdown/doc/bg.png differ
diff --git a/app/server/vendor/kramdown/doc/default.scss b/app/server/vendor/kramdown/doc/default.scss
new file mode 100644
index 0000000..f8e44a7
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/default.scss
@@ -0,0 +1,192 @@
+ at import 'design';
+
+a:hover {
+    background-color: rgba(0,0,0,0.1);
+}
+
+aside.banner {
+    font-size: 18px;
+    line-height: 27px;
+}
+
+aside a {
+    text-decoration: none;
+
+    &:hover, &:link {
+        text-decoration: underline;
+    }
+
+}
+
+#content {
+    blockquote.information {
+        border-left: 12px solid #080;
+        background-color: #bfb;
+        padding: 12px 12px 12px 0;
+        margin-left: -48px;
+        padding-left: 48px;
+    }
+
+    blockquote.markdown-difference {
+        border-left: 12px solid #dc0;
+        background-color: #ffa;
+        padding: 12px 12px 12px 0;
+        margin-left: -48px;
+        padding-left: 48px;
+
+        &:before {
+            content: "Difference to Standard Markdown";
+            display: block;
+            font-weight: bold;
+        }
+    }
+
+    blockquote pre {
+        border: none;
+    }
+
+    table {
+        border-collapse: collapse;
+        margin-left: auto;
+        margin-right: auto;
+        width: 100%;
+
+        td, th {
+            padding: 3px 5px;
+        }
+        th {
+            background-color: #080;
+            color: white;
+        }
+    }
+
+    pre.show-whitespaces .ws-space {
+        background-color: #f44;
+    }
+    pre.show-whitespaces .ws-space-l {
+        background-color: #f22;
+    }
+    pre.show-whitespaces .ws-space-r {
+        background-color: #f00;
+    }
+    pre.show-whitespaces .ws-tab {
+        background-color: #ff4;
+    }
+    pre.show-whitespaces .ws-tab-l {
+        background-color: #ff2;
+    }
+    pre.show-whitespaces .ws-tab-r {
+        background-color: #ff0;
+    }
+    pre.show-whitespaces.ws-lr .ws-tab {
+        background-color: inherit;
+    }
+    pre.show-whitespaces.ws-lr .ws-space {
+        background-color: inherit;
+        opacity: 0;
+    }
+
+    table.kdexample td {
+        vertical-align: top;
+    }
+
+    table.kdexample pre {
+        margin: 5px 0px;
+    }
+
+    .kdexample:hover .kdexample-after-source {
+        display: block;
+    }
+
+    .kdexample-after-source {
+        display: none;
+        background-color: #ffffee;
+        border: 2px solid #e6e8e9;
+        margin: 0 10px;
+        padding: 5px;
+    }
+
+    .kdexample-after-live {
+        background-color: #eeffee;
+        border: 2px solid #e6e8e9;
+        margin: 5px 0px 12px;
+        padding: 5px;
+    }
+
+    div.kdsyntaxlink {
+        float: right;
+        position: relative;
+        top: -17px;
+        padding: 5px;
+        border: 1px solid #e6e8e9;
+        margin-right: 10px;
+        margin-left: 10px;
+
+        a {
+            text-decoration: none;
+        }
+    }
+}
+
+.news-item {
+    border-top: 2px solid #ddd;
+    margin-top: 46px;
+}
+
+.news-date {
+    float: right;
+    margin-top: 2px;
+    font-size: small;
+    color: #888;
+}
+
+footer {
+    clear: both;
+    font-size: 92%;
+    text-align: left;
+
+    a {
+        color: #898989;
+
+        &:hover {
+            text-decoration: none;
+            color: #666;
+        }
+    }
+}
+
+/* common rules */
+acronym {
+    cursor: help;
+    border-bottom: 1px solid #777;
+}
+
+.float-left {
+    float: left;
+}
+
+.float-right {
+    float: right;
+}
+
+.a-left, tr.a-left td {
+    text-align: left;
+}
+
+.a-center, tr.a-center td {
+    text-align: center;
+}
+
+.a-right, tr.a-right td {
+    text-align: right;
+}
+
+.clear {
+    clear: both;
+}
+
+.inline-important {
+    font-weight: bold;
+    display: block;
+    text-align: center;
+}
diff --git a/app/server/vendor/kramdown/doc/default.template b/app/server/vendor/kramdown/doc/default.template
new file mode 100644
index 0000000..2783140
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/default.template
@@ -0,0 +1,68 @@
+<!doctype html>
+<html xml:lang="{lang:}" lang="{lang:}">
+  <head>
+    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+    <meta name="author" content="Thomas Leitner" />
+    <meta name="copyright" content="2009-2013 Thomas Leitner" />
+    <meta name="description" content="kramdown is a fast, pure-Ruby Markdown-superset converter" />
+    <meta name="keywords" content="ruby, kramdown, markdown, text markup" />
+    <link href="{relocatable: default.css}" type="text/css" rel="stylesheet" media="screen,projection" />
+    <link href="{relocatable: news.atom}" type="application/atom+xml" rel="alternate" />
+    <script src="http://kramdown.gettalong.org/MathJax/MathJax.js" type="text/javascript"></script>
+    <title>{title:} | kramdown</title>
+  </head>
+  <body>
+    <header>
+      <hgroup>
+        <h1 id="logo"><a href="{relocatable: /}" title="Homepage">kramdown</a></h1>
+        <h2 id="slogan">fast, pure-Ruby Markdown-superset converter</h2>
+      </hgroup>
+
+      <nav>
+        {menu: {options: {mi: {in_menu: true}, sort: sort_info, flatten: true}}}
+      </nav>
+    </header>
+
+    <div id="wrapper">
+      <% if context.content_node.blocks.has_key?('intro') %>
+      <aside class="banner">
+        <webgen:block name="intro" node="first" />
+      </aside>
+      <% end %>
+
+      <aside>
+        <webgen:block name="sidebar" node="first" notfound="ignore" />
+
+        <webgen:block name="content" chain="sidebar.template" />
+      </aside>
+
+      <div id="content">
+        <webgen:block name="content" node="first" />
+      </div>
+      <div style="clear:both"></div>
+    </div>
+
+    <footer>
+      <div class="float-left">Copyright © 2009-2013 Thomas Leitner</div>
+      <div class="float-right">Generated by <a href="http://webgen.gettalong.org">webgen</a></div>
+    </footer>
+
+    <!-- Start of StatCounter Code -->
+    <script type="text/javascript">
+      var sc_project=4267845;
+      var sc_invisible=1;
+      var sc_partition=46;
+      var sc_click_stat=1;
+      var sc_security="41321455";
+    </script>
+
+    <script type="text/javascript" src="http://www.statcounter.com/counter/counter_xhtml.js"></script>
+    <noscript><div class="statcounter">
+        <a title="web counter" class="statcounter" href="http://www.statcounter.com/free_hit_counter.html">
+          <img class="statcounter" src="http://c.statcounter.com/4267845/0/41321455/1/" alt="web counter" />
+        </a>
+    </div></noscript>
+    <!-- End of StatCounter Code -->
+
+  </body>
+</html>
diff --git a/app/server/vendor/kramdown/doc/documentation.page b/app/server/vendor/kramdown/doc/documentation.page
new file mode 100644
index 0000000..ebafaaf
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/documentation.page
@@ -0,0 +1,84 @@
+---
+title: Documentation
+in_menu: true
+sort_info: 7
+---
+# kramdown Documentation
+
+## Overview
+
+kramdown is first and foremost a library for converting text written in a superset of Markdown to
+HTML. However, due to its modular architecture it is able to support additional input and output
+formats. The following input and output formats are currently supported:
+
+* Input: [kramdown](parser/kramdown.html) (a superset of Markdown),
+  [Markdown](parser/markdown.html), [Github Flavored Markdown](parser/gfm.html), [HTML](parser/html.html)
+
+* Output: [HTML](converter/html.html), [LaTeX](converter/latex.html),
+  [kramdown](converter/kramdown.html), [RemoveHtmlTags](converter/remove_html_tags.html) (a special
+  converter which removes HTML tags, normally used in conjunction with the LaTeX or kramdown
+  converters)
+
+The [kramdown syntax page](syntax.html) describes in detail what is supported and how it differs
+from standard Markdown.
+
+For all available options have a look at the [options documentation](options.html) or have a look at
+a parser/converter page to see which options they support!
+
+
+## Usage
+
+{:ruby: .language-ruby}
+
+The kramdown package provides two ways for using it:
+
+* **As a library**
+
+  kramdown uses basically the same API as [RedCloth], [BlueCloth] and [Maruku]:
+
+      require 'kramdown'
+
+      puts Kramdown::Document.new(text).to_html
+  {:ruby}
+
+  The second parameter to the `new` call is an options hash for (de)activating certain features. For
+  example, to disable automatic header ID generation, you can do the following:
+
+      puts Kramdown::Document.new(text, :auto_ids => false).to_html
+  {:ruby}
+
+  The default parser used is `kramdown`, however, you can select a different one with the `:input`
+  option:
+
+      puts Kramdown::Document.new(text, :input => 'html').to_latex
+  {:ruby}
+
+  You can also reuse the created document object to produce multiple outputs:
+
+      doc = Kramdown::Document.new(text, :input => 'html')
+      puts doc.to_html
+      puts doc.to_latex
+  {:ruby}
+
+  More information on how to use or extend kramdown can be found in the [API
+  documentation](rdoc/index.html)!
+
+* **As an application**
+
+  Together with the library files a binary called `kramdown` is shipped which can be used to convert
+  text in any supported input format to any supported output format. It either reads from the files
+  specified as the command line arguments or from the standard input. For example:
+
+      kramdown path/to/kramdown/doc/syntax.page
+
+  The input and output formats as well as all available kramdown options are supported through
+  command line switches.
+
+
+## Tests
+
+kramdown uses various test suites to verify the correct working of the parsers and converters. For
+more information, have a look at the [tests document](tests.html).
+
+
+{include_file: doc/links.markdown}
diff --git a/app/server/vendor/kramdown/doc/documentation.template b/app/server/vendor/kramdown/doc/documentation.template
new file mode 100644
index 0000000..f89b2ee
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/documentation.template
@@ -0,0 +1,21 @@
+--- name:sidebar pipeline:erb,tags,kramdown
+<h1>Documentation</h1>
+
+* Parsers
+  * [kramdown](parser/kramdown.html)
+  * [Markdown](parser/markdown.html)
+  * [GFM](parser/gfm.html)
+  * [HTML](parser/html.html)
+* Converters
+  * [HTML](converter/html.html)
+  * [LaTeX](converter/latex.html)
+  * [kramdown](converter/kramdown.html)
+  * [RemoveHtmlTags](converter/remove_html_tags.html)
+* [Configuration Options](options.html)
+* [Tests](tests.html)
+
+<% if context.node.children.first && context.node.children.first.children.length > 1 %>
+<h1>Contents</h1>
+<% end %>
+
+{menu: {options: {descendants: true, levels: [3,6]}}}
diff --git a/app/server/vendor/kramdown/doc/index.page b/app/server/vendor/kramdown/doc/index.page
new file mode 100644
index 0000000..1fa595f
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/index.page
@@ -0,0 +1,95 @@
+---
+title: Home
+in_menu: true
+sort_info: 1
+---
+## Overview
+
+If you want to get started with kramdown, have a look at the [installation page](installation.html)
+to see how you can install it on your system. Then look through the
+[documentation](documentation.html) for finding information about how to actually use kramdown and
+its parsers/converters. The [quick reference](quickref.html) provides a overview of the syntax -- if
+you need a more detailed description of the superset of Markdown which kramdown supports the [syntax
+page](syntax.html) is the place to go!
+
+{tikz::
+path: overview.png
+img_attr: {style: 'background:transparent'}
+content_processor.tikz.libraries: [mindmap, trees, arrows]
+content_processor.tikz.transparent: true
+content_processor.tikz.resolution: 300 100
+content_processor.tikz.opts: |
+  mindmap, concept color=black, text=white,
+  root concept/.append style={font=\Large},
+  level 1 concept/.append style={font=\Large, minimum size=2.6cm},
+  level 2 concept/.append style={font=\Large},
+}
+\node[concept, font=\Large] (lib) {kramdown's internal representation}
+  child[concept color=orange, grow=120, ->] {node[concept] (i-kramdown) {kramdown}}
+  child[concept color=orange, grow=160] {node[concept] (i-html) {HTML}}
+  child[concept color=orange, grow=200] {node[concept] (i-gfm) {GFM}}
+  child[concept color=orange, grow=240] {node[concept] (i-markdown) {Markdown}}
+  child[concept color=green!50!black, grow=60] {node[concept] (o-html) {HTML}}
+  child[concept color=green!50!black, grow=20] {node[concept] (o-kramdown) {kramdown}}
+  child[concept color=green!50!black, grow=-20] {
+    node[concept] (o-latex) {\LaTeX}
+    child[grow=0] {
+      node[concept] (o-latex-pdf) {PDF}
+    }
+  }
+  child[concept color=green!50!black, grow=-60] {node[concept] (o-pdf) {PDF}}
+;
+\draw [dash pattern=on 0pt off 2pt,line width=5pt,arrows=-angle 60,shorten >=15pt,shorten <=10pt,color=orange]
+   (i-kramdown) edge(lib)
+   (i-markdown) edge(lib)
+   (i-html) edge (lib)
+   (i-gfm) edge (lib);
+\draw [dash pattern=on 0pt off 2pt,line width=5pt,arrows=-angle 60,shorten >=10pt,shorten <=15pt,color=green!50!black]
+   (lib) edge(o-html)
+   (lib) edge (o-kramdown)
+   (lib) edge (o-latex)
+   (lib) edge (o-pdf);
+{tikz}
+{: style="text-align: center"}
+
+
+## Bugs, Forums, Mailing Lists
+
+If you have found a bug, you should [report it here][bug_report]. Also, there is the [kramdown-users
+google group][ml] available if you have any questions!
+
+[bug_report]: http://github.com/gettalong/kramdown/issues
+[ml]: https://groups.google.com/forum/#!forum/kramdown-users
+
+
+## Thanks
+
+kramdown would not be possible without the prior work of many other people. I want to thank everyone
+involved with making Markdown such a nice markup language and especially the developers of other
+Markdown implementations because kramdown borrowed many ideas from existing packages.
+
+
+## Author
+
+* Thomas Leitner
+* e-Mail: <mailto:t_leitner at gmx.at>
+
+
+[PHP Markdown Extra]: http://michelf.com/projects/php-markdown/extra/
+[Maruku]:             http://maruku.rubyforge.org
+[BlueCloth]: http://www.deveiate.org/projects/BlueCloth
+
+
+--- name:intro
+
+**kramdown** (sic, not Kramdown or KramDown, just kramdown) is a *free* MIT-licensed
+[Ruby](http://www.ruby-lang.org) library for parsing and converting a superset of Markdown. It is
+completely written in Ruby, supports standard Markdown (with some minor modifications) and various
+extensions that have been made popular by the [PHP Markdown Extra] package and [Maruku].
+
+It is probably the fastest pure-Ruby Markdown converter available (March 2013), being about 4x
+faster than [Maruku] and about 5x faster than [BlueFeather].
+
+[PHP Markdown Extra]: http://michelf.com/projects/php-markdown/extra/
+[Maruku]: http://maruku.rubyforge.org
+[BlueFeather]: http://ruby.morphball.net/bluefeather/index_en.html
diff --git a/app/server/vendor/kramdown/doc/installation.page b/app/server/vendor/kramdown/doc/installation.page
new file mode 100644
index 0000000..ffb2221
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/installation.page
@@ -0,0 +1,89 @@
+---
+title: Installation
+in_menu: true
+sort_info: 5
+---
+# Download & Installation
+
+## Dependencies
+
+Since kramdown is written in Ruby, you just need the [Ruby interpreter](http://www.ruby-lang.org),
+version 1.8.5, 1.8.6, 1.8.7, 1.9.2, 1.9.3 or 2.0.0. There are no other dependencies.
+
+
+## Compatibility Notes
+
+kramdown should work on any platform which supports Ruby. It has been successfully tested on the
+following platforms:
+
+* Linux with Ruby 1.8.5, 1.8.6, 1.8.7, 1.9.2, 1.9.3, 2.0.0 and jruby 1.7.3.
+
+See the platform specific installation notes for more information!
+
+
+## Platform Specific Installation Instructions
+
+### Linux
+
+There are a variety of Linux distributions out there with different package management systems. So
+we will focus on instructions for Ubuntu 9.04 here (which should probably also work for any newer
+Ubuntu version or any recent Debian based distribution).
+
+After running the following commands, kramdown is installed and ready to use:
+
+    sudo aptitude install ruby rubygems
+    sudo gem install kramdown
+
+> You will also need to add `export PATH=$PATH:/var/lib/gems/1.9/bin` to your `~/.bashrc` because
+> this is the binary path the executable files get installed to.
+
+
+### Mac OS X
+
+Mac OS X Snow Leopard comes with Ruby and Rubygems preinstalled. So installing kramdown is as easy
+as running:
+
+    sudo gem install kramdown
+
+
+### Windows
+
+You need to install Ruby first. This can easily be done by using the [RubyInstaller] - just download
+the installation binary and run it. After that open a command shell (select `Start -> Run...`, then
+enter `cmd` and click on `Ok`) and type in the following:
+
+    gem install kramdown
+
+[RubyInstaller]: http://rubyinstaller.org
+
+
+## Generic Installation Instructions
+
+
+### Using Rubygems
+
+If you are using Rubygems, installing the latest version of kramdown is as simple as executing
+
+    gem install kramdown
+
+
+### Manual Installation
+
+The latest version of kramdown can always be downloaded as `.tar.gz` or `.zip` via the [Github
+releases page][ghreleases]. After the download the package needs to be decompressed and then you can
+install kramdown using the included `setup.rb` installation method:
+
+    $ ruby setup.rb config
+    $ ruby setup.rb setup
+    $ ruby setup.rb install
+
+[ghreleases]: https://github.com/gettalong/kramdown/releases
+
+
+### Using the repository version
+
+kramdown uses git as its versioning system and kramdown's repository is hosted on GitHub. The
+repository always contains a clean state of the current development version of kramdown. To check
+out kramdown use the following command:
+
+     git clone git://github.com/gettalong/kramdown.git
diff --git a/app/server/vendor/kramdown/doc/links.markdown b/app/server/vendor/kramdown/doc/links.markdown
new file mode 100644
index 0000000..6baa05a
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/links.markdown
@@ -0,0 +1,6 @@
+[Maruku]: http://maruku.rubyforge.org
+[PHP Markdown Extra]: http://michelf.com/projects/php-markdown/extra/
+[Pandoc]: http://johnmacfarlane.net/pandoc/
+[MathJax]: http://www.mathjax.org
+[BlueCloth]: http://deveiate.org/projects/BlueCloth
+[RedCloth]: http://redcloth.org/
diff --git a/app/server/vendor/kramdown/doc/metainfo b/app/server/vendor/kramdown/doc/metainfo
new file mode 100644
index 0000000..efce601
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/metainfo
@@ -0,0 +1,3 @@
+--- alcn
+[converter/*.html, parser/*.html, documentation.en.html, options.en.html, tests.en.html]:
+  template: ../documentation.template
diff --git a/app/server/vendor/kramdown/doc/news.feed b/app/server/vendor/kramdown/doc/news.feed
new file mode 100644
index 0000000..65e511f
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/news.feed
@@ -0,0 +1,9 @@
+---
+title: kramdown News
+description: kramdown - a fast, pure Ruby Markdown-superset converter
+author: Thomas Leitner
+author_url: http://kramdown.gettalong.org
+entries: {alcn: news/*.html, sort: sort_info, reverse: true, limit: 10}
+versions:
+  atom:
+
diff --git a/app/server/vendor/kramdown/doc/news.page b/app/server/vendor/kramdown/doc/news.page
new file mode 100644
index 0000000..b0f7f42
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/news.page
@@ -0,0 +1,29 @@
+---
+title: News
+in_menu: false
+sort_info: 30
+--- pipeline:tags,blocks,fragments
+
+<h1>News</h1>
+
+<a href="{relocatable: news.atom}">Atom-Feed</a>
+
+<webgen:block name="newsdata" node="current" />
+
+--- name:newsdata pipeline:erb
+<%
+opts = {:alcn => '/news/*.html', :sort => 'sort_info', :reverse => true, :flatten => true}
+context.website.ext.item_tracker.add(context.dest_node, :nodes, :node_finder_option_set,
+  {:opts => opts, :ref_alcn => context.node.alcn}, :content)
+context.website.ext.node_finder.find(opts, context.node).each do |node|
+ # context.options['contentprocessor.kramdown.options'] = {:auto_id_prefix => node.lcn.tr('.', '-')}
+%>
+
+<div class='news-item'>
+<div class="news-date float-right">
+  Published on <%= node['created_at'].strftime("%A, %d %B %Y") %>
+</div>
+<%= context.render_block(:name => 'content', :chain => [node]) %>
+</div>
+
+<% end %>
diff --git a/app/server/vendor/kramdown/doc/options.page b/app/server/vendor/kramdown/doc/options.page
new file mode 100644
index 0000000..60cb271
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/options.page
@@ -0,0 +1,10 @@
+---
+title: Options
+---
+## Available Options
+
+The behaviour of kramdown can be adjusted via the available options. Below is a list of all
+currently available options. Have a look at the documentation of a converter or parser to see
+directly which options they support!
+
+{options: {items: all}}
diff --git a/app/server/vendor/kramdown/doc/quickref.page b/app/server/vendor/kramdown/doc/quickref.page
new file mode 100644
index 0000000..f21663a
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/quickref.page
@@ -0,0 +1,599 @@
+---
+title: Quick Reference
+in_menu: true
+sort_info: 9
+--- name:sidebar
+<h1>Contents</h1>
+
+{menu: {options: {descendants: true, levels: [2,6]}}}
+--- name:content
+# Quick Reference
+
+Below are examples of all available structural elements that can be used in a kramdown text. Since
+the kramdown syntax is a superset of the Markdown syntax, only a small part of the available syntax
+is not available in standard Markdown syntax. Note, that only the most basic syntax information is
+given. However, a link to the detailed syntax for each element is provided (which also details the
+differences to the standard Markdown syntax). The quick reference is for version **<%=
+::Kramdown::VERSION %>** of the syntax documentation.
+
+kramdown has two main classes of elements: block and span-level elements. Block-level elements are
+used to create paragraphs, headers, lists and so on whereas span-level elements are used to markup
+text phrases as emphasized, as a link and so on.
+
+All examples below feature the kramdown source, the converted HTML source (shown when hovering over
+the kramdown source) and the output as it appears in the browser. This looks like this:
+
+<table class="kdexample">
+<tr>
+<td><pre class="kdexample-before"><code>kramdown example code</code></pre></td>
+<td><pre class="kdexample-after-source"><code>Example code converted to HTML</code></pre>
+<div class="kdexample-after-live" style="clear:none">
+Live browser view of example code
+</div>
+</td>
+</tr>
+</table>
+
+
+# Block-level Elements - Main Structural Elements
+
+## Paragraphs
+
+{kdlink: {oid: paragraphs, part: "paragraphs"}}
+
+Consecutive lines of text are considered to be one paragraph. As with other block level elements you
+have to add a blank line to separate it from the following block-level element:
+
+{kdexample::}
+The first paragraph.
+
+Another paragraph
+{kdexample}
+
+Explicit line breaks in a paragraph can be made by using two spaces or two backslashes at the end of a line:
+
+{kdexample::}
+This is a paragraph  
+which contains a hard line break.
+{kdexample}
+
+
+## Headers
+
+{kdlink: {oid: headers, part: "headers"}}
+
+kramdown supports Setext style headers and atx style headers. A header must always be preceded by a
+blank line except at the beginning of the document:
+
+
+{kdexample::}
+First level header
+==================
+
+Second level header
+-------------------
+{kdexample}
+
+{kdexample::}
+# H1 header
+
+## H2 header
+
+### H3 header
+
+#### H4 header
+
+##### H5 header
+
+###### H6 header
+{kdexample}
+
+If you set the option `auto_ids` to `false` (for example, by using the `options` extension, see
+[Extensions](#extensions)), then the automatic header ID generation is turned off:
+
+{kdexample::}
+{::options auto_ids="false" /}
+
+# A header without an ID
+{kdexample}
+
+
+## Blockquotes
+
+{kdlink: {oid: blockquotes, part: "blockquotes"}}
+
+A blockquote is started using the `>` marker followed by an optional space; all following lines that
+are also started with the blockquote marker belong to the blockquote. You can use any block-level
+elements inside a blockquote:
+
+{kdexample::}
+> A sample blockquote.
+>
+> >Nested blockquotes are
+> >also possible.
+>
+> ## Headers work too
+> This is the outer quote again.
+{kdexample}
+
+You may also be lazy with the `>` markers as long as there is no blank line:
+
+{kdexample::}
+> This is a blockquote
+continued on this
+and this line.
+
+But this is a separate paragraph.
+{kdexample}
+
+## Code Blocks
+
+{kdlink: {oid: code-blocks, part: "code blocks"}}
+
+kramdown supports two different code block styles. One uses lines indented with either four spaces
+or one tab whereas the other uses lines with tilde characters as delimiters -- therefore the content
+does not need to be indented:
+
+{kdexample::}
+    This is a sample code block.
+
+    Continued here.
+{kdexample}
+
+{kdexample::}
+~~~~~~
+This is also a code block.
+~~~
+Ending lines must have at least as
+many tildes as the starting line.
+~~~~~~~~~~~~
+{kdexample}
+
+The following is a code block with a language specified:
+
+{kdexample::}
+~~~ ruby
+def what?
+  42
+end
+~~~
+{kdexample}
+
+
+## Horizontal Rules
+
+{kdlink: {oid: horizontal-rules, part: "horizontal rules"}}
+
+It is easy to insert a horizontal rule in kramdown: just use three or more asterisks, dashes or
+underscores, optionally separated by spaces or tabs, on an otherwise blank line:
+
+{kdexample::}
+* * *
+
+\---
+
+  _  _  _  _
+
+---------------
+{kdexample}
+
+
+## Lists
+
+{kdlink: {oid: lists, part: "lists"}}
+
+kramdown supports ordered and unordered lists. Ordered lists are started by using a number followed
+by a period, a space and then the list item text. The content of a list item consists of block-level
+elements. All lines which have the same indent as the text of the line with the list marker belong
+to the list item:
+
+{kdexample::}
+1. This is a list item
+2. And another item
+2. And the third one
+   with additional text
+{kdexample}
+
+As with block quotes, you may be lazy when using the list item marker:
+
+{kdexample::}
+* A list item
+with additional text
+{kdexample}
+
+As the content consists of block-level elements you can do things like the following:
+
+{kdexample::}
+1.  This is a list item
+
+    > with a blockquote
+
+    # And a header
+
+2.  Followed by another item
+{kdexample}
+
+Nested lists are also easy to create:
+
+{kdexample::}
+1. Item one
+   1. sub item one
+   2. sub item two
+   3. sub item three
+2. Item two
+{kdexample}
+
+Lists can occur directly after other block-level elements, however, there has to be at least one
+blank line if you want to follow a paragraph with a list:
+
+{kdexample::}
+This is a paragraph.
+1. This is NOT a list.
+
+1. This is a list!
+{kdexample}
+
+Unordered lists are started by using an asterisk, a dash or a plus sign (they can be mixed) and a
+space. Apart from that unordered lists follow the same rules as ordered lists:
+
+{kdexample::}
+* Item one
++ Item two
+- Item three
+{kdexample}
+
+## Definition Lists
+
+{kdlink: {oid: definition-lists, part: "definition lists"}}
+
+A definition list works similar to a normal list and is used to associate definitions with terms.
+Definition lists are started when a normal paragraph is followed by a line starting with a colon and
+then the definition text. One term can have many definitions and multiple terms can have the same
+definition. Each line of the preceding paragraph is assumed to contain one term, for example:
+
+{kdexample::}
+term
+: definition
+: another definition
+
+another term
+and another term
+: and a definition for the term
+{kdexample}
+
+If you insert a blank line before a definition (note: there must only be one blank line between the
+terms and the first definition), the definition will be wrapped in a paragraph:
+
+{kdexample::}
+term
+
+: definition
+: definition
+{kdexample}
+
+Each term can be styled using span-level elements and each definition is parsed as block-level
+elements, i.e. you can use any block-level in a definition. Just use the same indent for the lines
+following the definition line:
+
+{kdexample::}
+This *is* a term
+
+: This will be a para
+
+  > a blockquote
+
+  # A header
+{kdexample}
+
+
+## Tables
+
+{kdlink: {oid: tables, part: "tables"}}
+
+kramdown supports a syntax for creating simple tables. A line starting with a pipe character (`|`)
+starts a table row. However, if the pipe characters is immediately followed by a dash (`-`), a
+separator line is created. Separator lines are used to split the table header from the table body
+(and optionally align the table columns) and to split the table body into multiple parts. If the
+pipe character is followed by an equal sign (`=`), the tables rows below it are part of the table
+footer.
+
+{kdexample::}
+| A simple | table |
+| with multiple | lines|
+{kdexample}
+
+{kdexample::}
+| Header1 | Header2 | Header3 |
+|:--------|:-------:|--------:|
+| cell1   | cell2   | cell3   |
+| cell4   | cell5   | cell6   |
+|----
+| cell1   | cell2   | cell3   |
+| cell4   | cell5   | cell6   |
+|=====
+| Foot1   | Foot2   | Foot3
+{: rules="groups"}
+{kdexample}
+
+
+## HTML elements
+
+{kdlink: {oid: html-blocks, part: "HTML blocks"}}
+
+kramdown allows you to use block-level HTML tags (`div`, `p`, `pre`, ...) to markup whole blocks of
+text -- just start a line with a block-level HTML tag. kramdown syntax is normally not processed
+inside an HTML tag but this can be changed with the `parse_block_html` option. If this options is
+set to `true`, then the content of a block-level HTML tag is parsed by kramdown either as block
+level or span-level text, depending on the tag:
+
+{kdexample::}
+<div style="float: right">
+Something that stays right and is not wrapped in a para.
+</div>
+
+{::options parse_block_html="true" /}
+
+<div>
+This is wrapped in a para.
+</div>
+<p>
+This can contain only *span* level elements.
+</p>
+{kdexample}
+
+
+## Block Attributes
+
+{kdlink: {oid: block-ials, part: "block IALs"}}
+{kdlink: {oid: attribute-list-definitions, part: "ALDs"}}
+
+You can assign any attribute to a block-level element. Just directly follow the block with a *block
+inline attribute list* (or short: block IAL). A block IAL consists of a left curly brace, followed
+by a colon, the attribute definitions and a right curly brace. Here is a simple example which sets the
+`title` attribute of a block quote:
+
+{kdexample::}
+> A nice blockquote
+{: title="Blockquote title"}
+{kdexample}
+
+As one often wants to set one or more CSS classes on an element, there is an easy shortcut:
+
+{kdexample::}
+> A nice blockquote
+{: .class1 .class2}
+{kdexample}
+
+A shortcut for setting the ID is also provided. Just prefix the ID with a hash symbol:
+
+{kdexample::}
+> A nice blockquote
+{: #with-an-id}
+{kdexample}
+
+Sometimes one wants to use the same attributes for many elements. kramdown allows you to define the
+attributes in one place with an *attribute list definition* (or short: ALD) and just reference this
+definition in a block IAL. An ALD has the same structure as a block IAL but the colon has to be
+replace with a colon, the reference name and another colon. By just using the reference name as-is
+in a block IAL, one can include the attributes of the referenced ALD:
+
+{kdexample::}
+{:refdef: .c1 #id .c2 title="title"}
+paragraph
+{: refdef}
+{kdexample}
+
+The order in a block IAL or ALD is important because later defined attributes overwrite (with the
+exception of the shortcut for CSS classes) prior defined attributes:
+
+{kdexample::}
+{:refdef: .c1 #id .c2 title="title"}
+paragraph
+{: refdef .c3 title="t" #para}
+{kdexample}
+
+
+## Extensions
+
+{kdlink: {oid: extensions, part: "extensions"}}
+
+kramdown provides some less used functionality through a common syntax. This will allow the easy
+addition of other extensions if need arises. Currently, there are extensions for ignoring text (i.e.
+treating text as comment), for inserting arbitrary text as-is into the output and for setting
+kramdown options.
+
+Here is an example that shows how to insert comments into text:
+
+{kdexample::}
+This is a paragraph
+{::comment}
+This is a comment which is
+completely ignored.
+{:/comment}
+... paragraph continues here.
+
+Extensions can also be used
+inline {::nomarkdown}**see**{:/}!
+{kdexample}
+
+As one can see from the above example, the syntax for extensions is nearly identical to that of
+ALDs. However, there is no trailing colon after the extension name and the extension end tag needs a
+slash between the colon and the extension name. One can also use the short form of the end tag, i.e.
+`{:/}`. Attribute definitions can be specified on the start tag by separating them with a space from
+the extension name. Also, if the extension does not have a body, there needs to be a slash right
+before the closing brace:
+
+{kdexample::}
+{::options auto_ids="false" /}
+
+# Header without id
+{kdexample}
+
+
+
+
+# Span-Level Elements - Text Modifiers
+
+## Emphasis
+
+{kdlink: {oid: emphasis, part: "emphasis"}}
+
+Emphasis can be added to text by surrounding the text with either asterisks or underscores:
+
+{kdexample::}
+This is *emphasized*,
+_this_ too!
+{kdexample}
+
+Strong emphasis can be done by doubling the delimiters:
+
+{kdexample::}
+This is **strong**,
+__this__ too!
+{kdexample}
+
+The form with the asterisks can also be used to markup parts of words:
+
+{kdexample::}
+This w**ork**s as expected!
+{kdexample}
+
+
+## Links and Images
+
+{kdlink: {oid: links-and-images, part: "links and images"}}
+
+A simple link can be created by surrounding the text with square brackets and the link URL with
+parentheses:
+
+{kdexample::}
+A [link](http://kramdown.gettalong.org)
+to the kramdown homepage.
+{kdexample}
+
+You can also add title information to the link:
+
+{kdexample::}
+A [link](http://kramdown.gettalong.org "hp")
+to the homepage.
+{kdexample}
+
+There is another way to create links which does not interrupt the text flow. The URL and title are
+defined using a reference name and this reference name is then used in square brackets instead of
+the link URL:
+
+{kdexample::}
+A [link][kramdown hp]
+to the homepage.
+
+[kramdown hp]: http://kramdown.gettalong.org "hp"
+{kdexample}
+
+If the link text itself is the reference name, the second set of square brackets can be omitted:
+
+{kdexample::}
+A link to the [kramdown hp].
+
+[kramdown hp]: http://kramdown.gettalong.org "hp"
+{kdexample}
+
+Images can be created in a similar way: just use an exclamation mark before the square brackets. The
+link text will become the alternative text of the image and the link URL specifies the image source:
+
+{kdexample::}
+An image: ![gras](img/image.jpg)
+{kdexample}
+
+
+## Inline Code
+
+{kdlink: {oid: code-spans, part: "code spans"}}
+
+Text phrases can be easily marked up as code by surrounding them with backticks:
+
+{kdexample::}
+Use `Kramdown::Document.new(text).to_html`
+to convert the `text` in kramdown
+syntax to HTML.
+{kdexample}
+
+If you want to use literal backticks in your code, just use two or more backticks as delimiters. The
+space right after the beginning delimiter and the one right before the closing delimiter are ignore:
+
+{kdexample::}
+Use backticks to markup code,
+e.g. `` `code` ``.
+{kdexample}
+
+
+## Footnotes
+
+{kdlink: {oid: footnotes, part: "footnotes"}}
+
+Footnotes can easily be used in kramdown. Just set a footnote marker (consists of square brackets
+with a caret and the footnote name inside) in the text and somewhere else the footnote definition (which
+basically looks like a reference link definition):
+
+{kdexample::}
+This is a text with a
+footnote[^1].
+
+[^1]: And here is the definition.
+{kdexample}
+
+The footnote definition can contain any block-level element, all lines following a footnote
+definition indented with four spaces or one tab belong to the definition:
+
+{kdexample::}
+This is a text with a
+footnote[^2].
+
+[^2]:
+    And here is the definition.
+
+    > With a quote!
+{kdexample}
+
+As can be seen above the footnote name is only used for the anchors and the numbering is done
+automatically in document order.  Repeated footnote markers will link to the same footnote
+definition.
+
+
+## Abbreviations
+
+{kdlink: {oid: abbreviations, part: "abbreviations"}}
+
+Abbreviations will work out of the box once you add an abbreviation definition. So you can just
+write the text and add the definitions later on.
+
+{kdexample::}
+This is an HTML
+example.
+
+*[HTML]: Hyper Text Markup Language
+{kdexample}
+
+
+## HTML Elements
+
+{kdlink: {oid: html-spans, part: "HTML spans"}}
+
+HTML is not only supported on the block-level but also on the span-level:
+
+{kdexample::}
+This is <span style="color: red">written in
+red</span>.
+{kdexample}
+
+
+## Inline Attributes
+
+{kdlink: {oid: span-ials, part: "span IALs"}}
+
+As with a block-level element you can assign any attribute to a span-level elements using a *span
+inline attribute list* (or short: span IAL). A span IAL has the same syntax as a block IAL and must
+immediately follow the span-level element:
+
+{kdexample::}
+This is *red*{: style="color: red"}.
+{kdexample}
diff --git a/app/server/vendor/kramdown/doc/sidebar.template b/app/server/vendor/kramdown/doc/sidebar.template
new file mode 100644
index 0000000..5557b1a
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/sidebar.template
@@ -0,0 +1,26 @@
+<h2>News</h2>
+
+<p>The latest version of kramdown is <span class="inline-important">1.4.0</span> and it was released
+on <span class="inline-important">2014-06-18</span></p>
+
+<p>More <a href="{relocatable: news.html}">news</a>…</p>
+
+<h2>Support kramdown</h2>
+
+<p>If you like kramdown and would like to support it, you are welcome to make a small
+donation (PayPal or Pledgie) -- it will surely be appreciated! Thanks!</p>
+
+<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
+<input type="hidden" name="cmd" value="_s-xclick">
+<input type="hidden" name="hosted_button_id" value="99HUWKWPMUHWG">
+<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
+<img alt="" border="0" src="https://www.paypalobjects.com/de_DE/i/scr/pixel.gif" width="1" height="1">
+</form>
+
+<a href='http://www.pledgie.com/campaigns/16657'><img alt='Click here to lend your support to: kramdown and make a donation at www.pledgie.com !' src='http://www.pledgie.com/campaigns/16657.png?skin_name=chrome' border='0' /></a>
+
+<h2>Sponsors</h2>
+
+<p>GROSSWEBER provides <a href="http://grossweber.com/b/kramdown" target="_blank">software
+development consulting and training services</a>. <em>We like to work on open source. We use it heavily.
+We love kramdown!</em></p>
diff --git a/app/server/vendor/kramdown/doc/syntax.page b/app/server/vendor/kramdown/doc/syntax.page
new file mode 100644
index 0000000..976bc56
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/syntax.page
@@ -0,0 +1,1710 @@
+---
+title: Syntax
+in_menu: true
+sort_info: 10
+--- name:sidebar
+<h1>Contents</h1>
+
+{menu: {options: {descendants: true, levels: [2,6]}}}
+--- name:content
+
+# kramdown Syntax
+
+This is version **<%= ::Kramdown::VERSION %>** of the syntax documentation.
+
+The kramdown syntax is based on the Markdown syntax and has been enhanced with features that are
+found in other Markdown implementations like [Maruku], [PHP Markdown Extra] and [Pandoc]. However,
+it strives to provide a strict syntax with definite rules and therefore isn't completely compatible
+with Markdown. Nonetheless, most Markdown documents should work fine when parsed with kramdown. All
+places where the kramdown syntax differs from the Markdown syntax are highlighted.
+
+Following is the complete syntax definition for all elements kramdown supports. Together with the
+documentation on the available converters, it is clearly specified what you will get when a kramdown
+document is converted.
+
+
+## Source Text Formatting
+
+A kramdown document may be in any encoding, for example ASCII, UTF-8 or ISO-8859-1, and the output
+will have the same encoding as the source.
+
+The document consists of two types of elements, block-level elements and span-level elements:
+
+* Block-level elements define the main structure of the content, for example, what part of the text
+  should be a paragraph, a list, a blockquote and so on.
+
+* Span-level elements mark up small text parts as, for example, emphasized text or a link.
+
+Thus span-level elements can only occur inside block-level elements or other span-level elements.
+
+You will often find references to the "first column" or "first character" of a line in a block-level
+element descriptions. Such a reference is always to be taken relative to the current indentation
+level because some block-level elements open up a new indentation level (e.g. blockquotes). The
+beginning of a kramdown document opens up the default indentation level which begins at the first
+column of the text.
+
+
+### Line Wrapping
+
+Some lightweight markup syntax don't work well in environments where lines are hard-wrapped. For
+example, this is the case with many email programs. Therefore kramdown allows content like
+paragraphs or blockquotes to be hard-wrapped, i.e. broken across lines. This is sometimes referred
+to as "lazy syntax" since the indentation or line prefix required for the first line of content is
+not required for the consecutive lines.
+
+Block-level elements that support line wrapping always end when one of the following conditions is
+met:
+
+* a [blank line](#blank-lines), an [EOB marker line](#eob-marker), a [block IAL](#block-ials) or the
+  end of the document (i.e. a [block boundary](#block-boundaries)),
+
+*  or an [HTML block](#html-blocks).
+
+Line wrapping is allowed throughout a kramdown document but there are some block-level elements that
+do *not* support being hard-wrapped:
+
+[headers](#headers)
+
+: This is not an issue in most situations since headers normally fit on one line. If a header text
+  gets too long for one line, you need to use HTML syntax instead.
+
+[fenced code blocks](#fenced-code-blocks)
+
+: The delimiting lines of a fenced code block do not support hard-wrapping. Since everything between
+  the delimiting lines is taken as is, the content of a fenced code block does also not support
+  hard-wrapping.
+
+[definition list terms](#definition-lists)
+
+: Each definition term has to appear on a separate line. Hard-wrapping would therefore introduce
+  additional definition terms. The definitions themselves, however, do support hard-wrapping.
+
+[tables](#tables)
+
+: Since each line of a kramdown table describes one table row or a separator, it is not possible to
+  hard-wrap tables.
+
+**Note** that it is **NOT** recommended to use lazy syntax to write a kramdown document. The
+flexibility that the kramdown syntax offers due to the issue of line wrapping hinders readability
+and should therefore not be used.
+
+
+### Usage of Tabs
+
+kramdown assumes that tab stops are set at multiples of four. This is especially important when
+using tabs for indentation in lists. Also, tabs may only be used at the beginning of a line when
+indenting text and must not be preceded by spaces. Otherwise the results may be unexpected.
+
+
+### Automatic and Manual Escaping
+
+Depending on the output format, there are often characters that need special treatment. For example,
+when converting a kramdown document to HTML one needs to take care of the characters `<`, `>` and
+`&`. To ease working with these special characters, they are automatically and correctly escaped
+depending on the output format.
+
+This means, for example, that you can just use `<`, `>` and `&` in a kramdown document and need not
+think about when to use their HTML entity counterparts. However, if you *do use* HTML entities or
+HTML tags which use one of the characters, the result will be correct nonetheless!
+
+Since kramdown also uses some characters to mark-up the text, there needs to be a way to escape
+these special characters so that they can have their normal meaning. This can be done by using
+backslash escapes. For example, you can use a literal back tick like this:
+
+    This \`is not a code\` span!
+
+Following is a list of all the characters (character sequences) that can be escaped:
+
+    \         backslash
+    .         period
+    *         asterisk
+    _         underscore
+    +         plus
+    -         minus
+    =         equal sign
+    `         back tick
+    ()[]{}<>  left and right parens/brackets/braces/angle brackets
+    #         hash
+    !         bang
+    <<        left guillemet
+    >>        right guillemet
+    :         colon
+    |         pipe
+    "         double quote
+    '         single quote
+    $         dollar sign
+
+
+## Block Boundaries
+
+Some block-level elements have to start and/or end on so called block boundaries, as stated in their
+documentation. There are two cases where block boundaries come into play:
+
+* If a block-level element has to start on a block boundary, it has to be preceded by either a
+  [blank line](#blank-lines), an [EOB marker](#eob-marker), a [block IAL](#block-ials) or it has to
+  be the first element.
+
+* If a block-level element has to end on a block boundary, it has to be followed by either a [blank
+  line](#blank-lines), an [EOB marker](#eob-marker), a [block IAL](#block-ials) or it has to be the
+  last element.
+
+
+
+# Structural Elements
+
+All structural elements are block-level elements and they are used to structure the content. They
+can mark up some text as, for example, a simple paragraph, a quote or as a list item.
+
+
+## Blank lines
+
+Any line that just contains white space characters such as spaces and tabs is considered a blank
+line by kramdown. One or more consecutive blank lines are handled as one empty blank line. Blank
+lines are used to separate block-level elements from each other and in this case they don't have
+semantic meaning. However, there are some cases where blank lines do have a semantic meaning:
+
+* When used in headers -- see the [headers section](#headers)
+* When used in code blocks -- see the [code blocks section](#code-blocks)
+* When used in lists -- see the [lists section](#lists)
+* When used in math blocks -- see the [math blocks section](#math-blocks)
+* When used for elements that have to start/end on [block boundaries](#block-boundaries)
+
+
+## Paragraphs
+
+Paragraphs are the most used block-level elements. One or more consecutive lines of text are
+interpreted as one paragraph. The first line of a paragraph may be indented up to three spaces, the
+other lines can have any amount of indentation because paragraphs support [line
+wrapping](#line-wrapping). In addition to the rules outlined in the section about line wrapping, a
+paragraph ends when a [definition list line](#definition-lists) is encountered.
+
+You can separate two consecutive paragraphs from each other by using one or more blank lines. Notice
+that a line break in the source does not mean a line break in the output (due to the [lazy
+syntax](#line-wrapping))!. If you want to have an explicit line break (i.e. a `<br />` tag) you need
+to end a line with two or more spaces or two backslashes! Note, however, that a line break on the
+last text line of a paragraph is not possible and will be ignored. Leading and trailing spaces will
+be stripped from the paragraph text.
+
+The following gives you an example of how paragraphs look like:
+
+    This para line starts at the first column. However,
+          the following lines can be indented any number of spaces/tabs.
+       The para continues here.
+
+      This is another paragraph, not connected to the above one. But  
+    with a hard line break. \\
+    And another one.
+{: .show-whitespaces .ws-lr}
+
+
+## Headers
+
+kramdown supports so called Setext style and atx style headers. Both forms can be used inside a
+single document.
+
+### Setext Style
+
+Setext style headers have to start on a [block boundary](#block-boundaries) with a line of text (the
+header text) and a line with only equal signs (for a first level header) or dashes (for a second
+level header). The header text may be indented up to three spaces but any leading or trailing spaces
+are stripped from the header text. The amount of equal signs or dashes is not significant, just one
+is enough but more may look better. The equal signs or dashes have to begin at the first column. For
+example:
+
+    First level header
+    ==================
+
+    Second level header
+    ------
+
+       Other first level header
+    =
+
+Since Setext headers start on block boundaries, this means in most situations that they have to be
+preceded by a blank line. However, blank lines are not necessary after a Setext header:
+
+    This is a normal
+    paragraph.
+
+    And A Header
+    ------------
+    And a paragraph
+
+    > This is a blockquote.
+
+    And A Header
+    ------------
+
+However, it is generally a good idea to also use a blank line after a Setext header because it looks
+more appropriate and eases reading of the document.
+
+> The original Markdown syntax allows one to omit the blank line before a Setext header. However,
+> this leads to ambiguities and makes reading the document harder than necessary. Therefore it is
+> not allowed in a kramdown document.
+{: .markdown-difference}
+
+An edge case worth mentioning is the following:
+
+    header
+    ---
+    para
+
+One might ask if this represents two paragraphs separated by a [horizontal rule](#horizontal-rules)
+or a second level header and a paragraph. As suggested by the wording in the example, the latter is
+the case. The general rule is that Setext headers are processed before horizontal rules.
+
+### atx Style
+
+atx style headers have to start on a [block boundary](#block-boundaries) with a line that contains
+one or more hash characters and then the header text. No spaces are allowed before the hash
+characters. The number of hash characters specifies the heading level: one hash character gives you
+a first level heading, two a second level heading and so on until the maximum of six hash characters
+for a sixth level heading. You may optionally use any number of hashes at the end of the line to
+close the header. Any leading or trailing spaces are stripped from the header text. For example:
+
+    # First level header
+
+    ### Third level header    ###
+
+    ## Second level header ######
+
+> Again, the original Markdown syntax allows one to omit the blank line before an atx style header.
+{: .markdown-difference}
+
+
+### Specifying a Header ID
+
+kramdown supports a nice way for explicitly setting the header ID which is taken from [PHP Markdown
+Extra] and [Maruku]: If you follow the header text with an opening curly bracket (separated from the
+text with a least one space), a hash, the ID and a closing curly bracket, the ID is set on the
+header. If you use the trailing hash feature of atx style headers, the header ID has to go after the
+trailing hashes. For example:
+
+    Hello        {#id}
+    -----
+
+    # Hello      {#id}
+
+    # Hello #    {#id}
+
+> This additional syntax is not part of standard Markdown.
+{: .markdown-difference}
+
+
+## Blockquotes
+
+A blockquote is started using the `>` marker followed by an optional space and the content of the
+blockquote. The marker itself may be indented up to three spaces. All following lines, whether they
+are started with the blockquote marker or just contain text, belong to the blockquote because
+blockquotes support [line wrapping](#line-wrapping).
+
+The contents of a blockquote are block-level elements. This means that if you are just using text as
+content that it will be wrapped in a paragraph. For example, the following gives you one blockquote
+with two paragraphs in it:
+
+    > This is a blockquote.
+    >     on multiple lines
+    that may be lazy.
+    >
+    > This is the second paragraph.
+
+Since the contents of a blockquote are block-level elements, you can nest blockquotes and use other
+block-level elements (this is also the reason why blockquotes need to support line wrapping):
+
+    > This is a paragraph.
+    >
+    > > A nested blockquote.
+    >
+    > ## Headers work
+    >
+    > * lists too
+    >
+    > and all other block-level elements
+
+Note that the first space character after the `>` marker does *not* count when counting spaces for
+the indentation of the block-level elements inside the blockquote! So [code blocks](#code-blocks)
+will have to be indented with five spaces or one space and one tab, like this:
+
+    > A code block:
+    >
+    >     ruby -e 'puts :works'
+
+[Line wrapping](#line-wrapping) allows one to be lazy but hinders readability and should therefore
+be avoided, especially with blockquotes. Here is an example of using blockquotes with line wrapping:
+
+    > This is a paragraph inside
+    a blockquote.
+    >
+    > > This is a nested paragraph
+    that continues here
+    > and here
+    > > and here
+
+
+## Code Blocks
+
+Code blocks can be used to represent verbatim text like markup, HTML or a program fragment because
+no syntax is parsed within a code block.
+
+### Standard Code Blocks
+
+A code block can be started by using four spaces or one tab and then the text of the code block. All
+following lines containing text, whether they adhere to this syntax or not, belong to the code block
+because code blocks support [line wrapping](#line-wrapping)). A wrapped code line is automatically
+appended to the preceding code line by substituting the line break with a space character. The
+indentation (four spaces or one tab) is stripped from each line of the code block.
+
+> The original Markdown syntax does not allow line wrapping in code blocks.
+{: .markdown-difference}
+
+Note that consecutive code blocks that are only separate by [blank lines](#blank-lines) are merged
+together into one code block:
+
+        Here comes some code
+
+        This text belongs to the same code block.
+
+If you want to have one code block directly after another one, you need to use an [EOB
+marker](#eob-marker) to separate the two:
+
+        Here comes some code
+    ^
+        This one is separate.
+
+### Fenced Code Blocks
+
+> This alternative syntax is not part of the original Markdown syntax. The idea and syntax comes
+> from the [PHP Markdown Extra] package.
+{: .markdown-difference}
+
+kramdown also supports an alternative syntax for code blocks which does not use indented blocks but
+delimiting lines. The starting line needs to begin with three or more tilde characters (`~`) and the
+closing line needs to have at least the number of tildes the starting line has. Everything between
+is taken literally as with the other syntax but there is no need for indenting the text. For
+example:
+
+    ~~~~~~~~
+    Here comes some code.
+    ~~~~~~~~
+
+If you need lines of tildes in such a code block, just start the code block with more tildes. For
+example:
+
+    ~~~~~~~~~~~~
+    ~~~~~~~
+    code with tildes
+    ~~~~~~~~
+    ~~~~~~~~~~~~~~~~~~
+
+This type of code block is especially useful for copy-pasted code since you don't need to indent the
+code.
+
+### Language of Code Blocks
+
+You can tell kramdown the language of a code block by using an [IAL](#inline-attribute-lists):
+
+    ~~~
+    def what?
+      42
+    end
+    ~~~
+    {: .language-ruby}
+
+The specially named class `language-ruby` tells kramdown that this code block is written in the Ruby
+language. Such information can be used, for example, by converters to do syntax highlighting on the
+code block.
+
+Fenced code blocks provide an easier way to specify the language, namely by appending the language
+of the code block to the end of the starting line:
+
+    ~~~ ruby
+    def what?
+      42
+    end
+    ~~~
+
+
+## Lists
+
+kramdown provides syntax elements for creating ordered and unordered lists as well as definition
+lists.
+
+### Ordered and Unordered lists
+
+Both ordered and unordered lists follow the same rules.
+
+A list is started with a list marker (in case of unordered lists one of `+`, `-` or `*` -- you can
+mix them -- and in case of ordered lists a number followed by a period) followed by one tab or at
+least one space, optionally followed by an [IAL](#inline-attribute-lists) that should be applied to
+the list item and then the first part of the content of the list item. The leading tabs or spaces
+are stripped away from this first line of content to allow for a nice alignment with the following
+content of a list item (see below). All following list items with the same marker type (unordered or
+ordered) are put into the same list. The numbers used for ordered lists are irrelevant, an ordered
+list always starts at 1.
+
+The following gives you an unordered list and an ordered list:
+
+    * kram
+    + down
+    - now
+
+    1. kram
+    2. down
+    3. now
+
+> The original Markdown syntax allows the markers of ordered and unordered lists to be mixed, the
+> first marker specifying the list type (ordered or unordered). This is not allowed in kramdown. As
+> stated, the above example will give you two lists (an unordered and an ordered) in kramdown and
+> only one unordered list in Markdown.
+{: .markdown-difference}
+
+The first list marker in a list may be indented up to three spaces. The column number of the first
+non-space character which appears after the list item marker on the same line specifies the
+indentation that has to be used for the following lines of content of the list item. If there is no
+such character, the indentation that needs to be used is four spaces or one tab. Indented lines may
+be followed by lines containing text with any amount of indentation due to [line
+wrapping](#line-wrapping). Note, however, that in addition to the rules outlined in the section
+about line wrapping, a list item also ends when a line with another list item marker is encountered
+-- see the next paragraph.
+
+The indentation is stripped from the content and the content (note that the content naturally also
+contains the content of the line with the item marker) is processed as text containing block-level
+elements. All other list markers in the list may be indented up to three spaces or the number of
+spaces used for the indentation of the last list item minus one, whichever number is smaller. For
+example:
+
+    * This is the first line. Since the first non-space characters appears in
+      column 3, all other indented lines have to be indented 2 spaces.
+    However, one could be lazy and not indent a line but this is not
+    recommended.
+    *       This is the another item of the list. It uses a different number
+       of spaces for indentation which is okay but should generally be avoided.
+       * The list item marker is indented 3 spaces which is allowed but should
+         also be avoided and starts the third list item. Note that the lazy
+         line in the second list item may make you believe that this is a
+         sub-list which it isn't! So avoid being lazy!
+
+So, while the above is possible and creates one list with three items, it is not advised to use
+different (marker and list content) indents for same level list items as well as lazy indentation!
+It is much better to write such a list in the following way:
+
+    * This is the first list item bla blabla blabla blabla blabla blabla
+      blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla
+      blabla blabla blabla bla
+    * This is the another item of the list. bla blabla blabla blabla blabla
+      blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla
+
+> The original Markdown syntax also allows you to indent the marker, however, the behaviour of what
+> happens with the list items is not clearly specified and may surprise you.
+>
+> Also, Markdown uses a fixed number of spaces/tabs to indent the lines that belong to a list item!
+{: .markdown-difference}
+
+When using tabs for indenting the content of a list item, remember that tab stops occur at multiples
+of four for kramdown. Tabs are correctly converted to spaces for calculating the indentation. For
+example:
+
+    *   Using a tab to indent this line, the tab only counts as three spaces
+        and therefore the overall indentation is four spaces.
+
+       1.   The tab after the marker counts here as three spaces. Since the
+            indentation of the marker is three spaces and the marker itself
+            takes two characters, the overall indentation needed for the
+            following lines is eight spaces or two tabs.
+
+It is clear that you might get unexpected results if you mix tabs and spaces or if you don't have
+the tab stops set to multiples of four in your editor! Therefore this should be avoided!
+
+The content of a list item is made up of either text or block-level elements. Simple list items only
+contain text like in the above examples. They are not even wrapped in a paragraph tag. If the first
+list text is followed by one or more blank lines, it will be wrapped in a paragraph tag:
+
+    * kram
+
+    * down
+    * now
+
+In the above example, the first list item text will be wrapped in a paragraph tag since it is
+followed by a blank line whereas the second list item contains just text. There is obviously a
+problem for doing this with the last list item when it contains only text. You can circumvent this
+by leaving a blank line after the last list item and using an EOB marker:
+
+    * Not wrapped in a paragraph
+    * Wrapped in a paragraph due to the following blank line.
+
+    * Also wrapped in a paragraph due to the
+      following blank line and the EOB marker.
+
+    ^
+
+The text of the last list item is also wrapped in a paragraph tag if *all* other list items contain
+a proper paragraph as first element. This makes the following use case work like expected, i.e.
+*all* the list items are wrapped in paragraphs:
+
+    * First list item
+
+    * Second list item
+
+    * Last list item
+
+> The original Markdown syntax page specifies that list items which are separated by one or more
+> blank lines are wrapped in paragraph tags. This means that the first text will also be wrapped in
+> a paragraph if you have block-level elements in a list which are separated by blank lines. The
+> above rule is easy to remember and lets you exactly specify when the first list text should be
+> wrapped in a paragraph. The idea for the above rule comes from the [Pandoc] package.
+{: .markdown-difference}
+
+As seen in the examples above, blank lines between list items are allowed.
+
+Since the content of a list item can contain block-level elements, you can do the following:
+
+    *   First item
+
+        A second paragraph
+
+        * nested list
+
+        > blockquote
+
+    *   Second item
+
+However, there is a problem when you want to have a code block immediately after a list item. You
+can use an EOB marker to circumvent this problem:
+
+    *   This is a list item.
+
+        The second para of the list item.
+    ^
+        A code block following the list item.
+
+You can have any block-level element as first element in a list item. However, as described above,
+the leading tabs or spaces of the line with the list item marker are stripped away. This leads to a
+problem when you want to have a code block as first element. The solution to this problem is the
+following construct:
+
+    * 
+            This is a code block (indentation needs to be 4(1)+4(1)
+            spaces (tabs)).
+{: .show-whitespaces .ws-lr}
+
+Note that the list marker needs to be followed with at least one space or tab! Otherwise the line is
+not recognized as the start of a list item but interpreted as a paragraph containing the list
+marker.
+
+If you want to have one list directly after another one (both with the same list type, i.e. ordered
+or unordered), you need to use an EOB marker to separate the two:
+
+    * List one
+    ^
+    * List two
+
+Since paragraphs support [line wrapping](#line-wrapping), it would usually not be possible to create
+compact nested list, i.e. a list where the text is not wrapped in paragraphs because there is no
+blank line but a sub list after it:
+
+    *   This is just text.
+        * this is a sub list item
+          * this is a sub sub list item
+    * This is just text,
+        spanning two lines
+      * this is a nested list item.
+
+However, this is an often used syntax and is therefore support by kramdown.
+
+If you want to start a paragraph with something that looks like a list item marker, you need to
+escape it. This is done by escaping the period in an ordered list or the list item marker in an
+unordered list:
+
+    1984\. It was great
+    \- others say that, too!
+
+As mentioned at the beginning, an optional IAL for applying attributes to a list item can be used
+after the list item marker:
+
+    * {:.cls} This item has the class "cls".
+      Here continues the above paragraph.
+
+    * This is a normal list item.
+
+
+### Definition Lists
+
+> This syntax feature is not part of the original Markdown syntax. The idea and syntax comes from
+> the [PHP Markdown Extra] package.
+{: .markdown-difference}
+
+Definition lists allow you to assign one or more definitions to one or more terms.
+
+A definition list is started when a normal paragraph is followed by a line with a definition marker
+(a colon which may be optionally indented up to three spaces), then at least one tab or one space,
+optionally followed by an [IAL](#inline-attribute-lists) that should be applied to the list item and
+then the first part of the definition. The line with the definition marker may optionally be
+separated from the preceding paragraph by a blank line. The leading tabs or spaces are stripped away
+from this first line of the definition to allow for a nice alignment with the following definition
+content. Each line of the preceding paragraph is taken to be a term and the lines separately parsed
+as span-level elements.
+
+The following is a simple definition list:
+
+    kramdown
+    : A Markdown-superset converter
+
+    Maruku
+    :     Another Markdown-superset converter
+
+The column number of the first non-space character which appears after a definition marker on the
+same line specifies the indentation that has to be used for the following lines of the definition.
+If there is no such character, the indentation that needs to be used is four spaces or one tab.
+Indented lines may be followed by lines containing text with any amount of indentation due to [line
+wrapping](#line-wrapping). Note, however, that in addition to the rules outlined in the section
+about line wrapping, a list item also ends when a line with another definition marker is encountered.
+
+The indentation is stripped from the definition and it (note that the definition naturally also
+contains the content of the line with the definition marker) is processed as text containing block
+level elements. If there is more than one definition, all other definition markers for the term may
+be indented up to three spaces or the number of spaces used for the indentation of the last
+definition minus one, whichever number is smaller. For example:
+
+    definition term 1
+    definition term 2
+    : This is the first line. Since the first non-space characters appears in
+    column 3, all other lines have to be indented 2 spaces (or lazy syntax may
+      be used after an indented line). This tells kramdown that the lines
+      belong to the definition.
+    :       This is the another definition for the same term. It uses a
+            different number of spaces for indentation which is okay but
+            should generally be avoided.
+       : The definition marker is indented 3 spaces which is allowed but
+         should also be avoided.
+
+So, while the above is possible and creates a definition list with two terms and three definitions
+for them, it is not advised to use different (definition marker and definition) indents in the same
+definition list as well as lazy indentation!
+
+The definition for a term is made up of text and/or block-level elements. If a definition is *not*
+preceded by a blank line, the first part of the definition will just be text if it would be a
+paragraph otherwise:
+
+    definition term
+    : This definition will just be text because it would normally be a
+      paragraph and the there is no preceding blank line.
+
+      > although the definition contains other block-level elements
+
+    : This definition *will* be a paragraph since it is preceded by a
+      blank line.
+
+The rules about having any block-level element as first element in a list item also apply to a
+definition.
+
+
+## Tables
+
+> This syntax feature is not part of the original Markdown syntax. The syntax is based on the one
+> from the [PHP Markdown Extra] package.
+{: .markdown-difference}
+
+Sometimes one wants to include simple tabular data in a kramdown document for which using a
+full-blown HTML table is just too much. kramdown supports this with a simple syntax for ASCII
+tables.
+
+Tables can be created with or without a leading pipe character: If the first line of a table
+contains a pipe character at the start of the line (optionally indented up to three spaces), then
+all leading pipe characters (i.e. pipe characters that are only preceded by whitespace) are ignored
+on all table lines. Otherwise they are not ignored and count when dividing a table line into table
+cells.
+
+There are four different line types that can be used in a table:
+
+* *Table rows* define the content of a table.
+
+  A table row is any line that contains at least one pipe character and is not identified as any
+  other type of table line! The table row is divided into individual table cells by pipe characters.
+  An optional trailing pipe character is ignored. Note that literal pipe characters need to be
+  escaped *except* if they occur in code spans or HTML `<code>` elements!
+
+  Header rows, footer rows and normal rows are all done using these table rows. Table cells can only
+  contain a single line of text, no multi-line text is supported. The text of a table cell is parsed
+  as span-level elements.
+
+  Here are some example table rows:
+
+      | First cell|Second cell|Third cell
+      | First | Second | Third |
+
+      First | Second | | Fourth |
+
+* *Separator lines* are used to split the table body into multiple body parts.
+
+  A separator line is any line that contains only pipes, dashes, pluses, colons and spaces and which
+  contains at least one dash and one pipe character. The pipe and plus characters can be used to
+  visually separate columns although this is not needed. Multiple separator lines after another are
+  treated as one separator line.
+
+  Here are some example separator lines:
+
+      |----+----|
+      +----|----+
+      |---------|
+      |-
+      | :-----: |
+      -|-
+
+* The first separator line after at least one table row is treated specially, namely as *header
+  separator line*. It is used to demarcate header rows from normal table rows and/or to set column
+  alignments. All table rows above the header separator line are considered to be header rows.
+
+  The header separator line can be specially formatted to contain column alignment definitions: An
+  alignment definition consists of an optional space followed by an optional colon, one or more
+  dashes, an optional colon and another optional space. The colons of an alignment definition are
+  used to set the alignment of a column: if there are no colons, the column uses the default
+  alignment, if there is a colon only before the dashes, the column is left aligned, if there are
+  colons before and after the dashes, the column is center aligned and if there is only a colon
+  after the dashes, the column is right aligned. Each alignment definition sets the alignment for
+  one column, the first alignment definition for the first column, the second alignment definition
+  for the second column and so on.
+
+  Here are some example header separator lines with alignment definitions:
+
+      |---+---+---|
+      + :-: |:------| ---:|
+      | :-: :- -: -
+      :-: | :-
+
+* A *footer separator line* is used to demarcate footer rows from normal table rows. All table rows
+  below the footer separator line are considered to be footer rows.
+
+  A footer separator line is like a normal separator line except that dashes are replaced by equal
+  signs. A footer separator line may only appear once in a table. If multiple footer separator lines
+  are used in one table, only the last is treated as footer separator line, all others are treated
+  as normal separator lines. Normal separator lines that are used after the footer separator line
+  are ignored.
+
+  Here are some example footer separator lines:
+
+      |====+====|
+      +====|====+
+      |=========|
+      |=
+
+Trailing spaces or tabs are ignored in all cases. To simplify table creation and maintenance,
+header, footer and normal separator lines need not specify the same number of columns as table rows;
+even `|-` and `|=` are a valid separators.
+
+Given the above components, a table is specified by
+
+* an optional separator line,
+* optionally followed by zero, one or more table rows followed by a header separator line,
+* one or more table rows, optionally interspersed with separator lines,
+* optionally followed by a footer separator line and zero, one or more table rows and
+* an optional trailing separator line.
+
+Also note
+
+* that the first line of a table must not have more than three spaces of indentation before the
+  first non-space character,
+* that each line of a table needs to have at least one not escaped pipe character so that kramdown
+  recognizes it as a line belonging to the table and
+* that tables have to start and end on [block boundaries](#block-boundaries)!
+
+> The table syntax differs from the one used in [PHP Markdown Extra] as follows:
+>
+> * kramdown tables do not need to have a table header.
+> * kramdown tables can be structured using separator lines.
+> * kramdown tables can contain a table footer.
+> * kramdown tables need to be separated from other block-level elements.
+{: .markdown-difference}
+
+Here is an example for a kramdown table with a table header row, two table bodies and a table footer
+row:
+
+    |-----------------+------------+-----------------+----------------|
+    | Default aligned |Left aligned| Center aligned  | Right aligned  |
+    |-----------------|:-----------|:---------------:|---------------:|
+    | First body part |Second cell | Third cell      | fourth cell    |
+    | Second line     |foo         | **strong**      | baz            |
+    | Third line      |quux        | baz             | bar            |
+    |-----------------+------------+-----------------+----------------|
+    | Second body     |            |                 |                |
+    | 2 line          |            |                 |                |
+    |=================+============+=================+================|
+    | Footer row      |            |                 |                |
+    |-----------------+------------+-----------------+----------------|
+
+The above example table is rather time-consuming to create without the help of an ASCII table
+editor. However, the table syntax is flexible and the above table could also be written like this:
+
+    |---
+    | Default aligned | Left aligned | Center aligned | Right aligned
+    |-|:-|:-:|-:
+    | First body part | Second cell | Third cell | fourth cell
+    | Second line |foo | **strong** | baz
+    | Third line |quux | baz | bar
+    |---
+    | Second body
+    | 2 line
+    |===
+    | Footer row
+
+
+## Horizontal Rules
+
+A horizontal rule for visually separating content is created by using three or more asterisks,
+dashes or underscores (these may not be mixed on a line), optionally separated by spaces or tabs, on
+an otherwise blank line. The first asterisk, dash or underscore may optionally be indented up to
+three spaces. The following examples show different possibilities to create a horizontal rule:
+
+    * * *
+
+    ---
+
+      _  _  _  _
+
+    ---------------
+
+
+## Math Blocks
+
+> This syntax feature is not part of the original Markdown syntax. The idea comes from the [Maruku]
+> and [Pandoc] packages.
+{: .markdown-difference}
+
+kramdown has built-in support for block and span-level mathematics written in LaTeX.
+
+A math block needs to start and end on [block boundaries](#block-boundaries). It is started using
+two dollar signs, optionally indented up to three spaces. The math block continues until the next
+two dollar signs (which may be on the same line or on one of the next lines) that appear at the end
+of a line, i.e. they may only be followed by whitespace characters. The content of a math block has
+to be valid LaTeX math. It is always wrapped inside a `\begin{displaymath}...\end{displaymath}`
+enviroment except if it begins with a `\begin` statement.
+
+The following kramdown fragment
+
+    $$
+    \begin{align*}
+      & \phi(x,y) = \phi \left(\sum_{i=1}^n x_ie_i, \sum_{j=1}^n y_je_j \right)
+      = \sum_{i=1}^n \sum_{j=1}^n x_i y_j \phi(e_i, e_j) = \\
+      & (x_1, \ldots, x_n) \left( \begin{array}{ccc}
+          \phi(e_1, e_1) & \cdots & \phi(e_1, e_n) \\
+          \vdots & \ddots & \vdots \\
+          \phi(e_n, e_1) & \cdots & \phi(e_n, e_n)
+        \end{array} \right)
+      \left( \begin{array}{c}
+          y_1 \\
+          \vdots \\
+          y_n
+        \end{array} \right)
+    \end{align*}
+    $$
+
+renders (using Javascript library [MathJax](http://www.mathjax.org/)) as
+
+$$
+\begin{align*}
+  & \phi(x,y) = \phi \left(\sum_{i=1}^n x_ie_i, \sum_{j=1}^n y_je_j \right)
+  = \sum_{i=1}^n \sum_{j=1}^n x_i y_j \phi(e_i, e_j) = \\
+  & (x_1, \ldots, x_n) \left( \begin{array}{ccc}
+      \phi(e_1, e_1) & \cdots & \phi(e_1, e_n) \\
+      \vdots & \ddots & \vdots \\
+      \phi(e_n, e_1) & \cdots & \phi(e_n, e_n)
+    \end{array} \right)
+  \left( \begin{array}{c}
+      y_1 \\
+      \vdots \\
+      y_n
+    \end{array} \right)
+\end{align*}
+$$
+
+Using inline math is also easy: just surround your math content with two dollar signs, like with a
+math block. If you don't want to start an inline math statement, just escape the dollar signs and
+they will be treated as simple dollar signs.
+
+> **Note** that LaTeX code that uses the pipe symbol `|` in inline math statements may lead to a
+> line being recognized as a table line. This problem can be avoided by using the `\vert` command
+> instead of `|`!
+{:.information}
+
+If you have a paragraph that looks like a math block but should actually be a paragraph with just an
+inline math statement, you need to escape the first dollar sign:
+
+    The following is a math block:
+
+    $$ 5 + 5 $$
+
+    But next comes a paragraph with an inline math statement:
+
+    \$$ 5 + 5 $$
+
+If you don't even won't the inline math statement, escape the first two dollar signs:
+
+    \$\$ 5 + 5 $$
+
+## HTML Blocks
+
+> The original Markdown syntax specifies that an HTML block must start at the left margin, i.e. no
+> indentation is allowed. Also, the HTML block has to be surrounded by blank lines. Both
+> restrictions are lifted for kramdown documents. Additionally, the original syntax does not allow
+> you to use Markdown syntax in HTML blocks which is allowed with kramdown.
+{: .markdown-difference}
+
+An HTML block is potentially started if a line is encountered that begins with a non-span-level HTML
+tag or a general XML tag (opening or closing) which may be indented up to three spaces.
+
+The following HTML tags count as span-level HTML tags and *won't* start an HTML block if found at
+the beginning of an HTML block line:
+
+    a abbr acronym b big bdo br button cite code del dfn em i img input
+    ins kbd label option q rb rbc rp rt rtc ruby samp select small span
+    strong sub sup textarea tt var
+
+Further parsing of a found start tag depends on the tag and in which of three possible ways its
+content is parsed:
+
+* Parse as raw HTML block: If the HTML/XML tag content should be handled as raw HTML, then only
+  HTML/XML tags are parsed from this point onwards and text is handled as raw, unparsed text until
+  the matching end tag is found or until the end of the document. Each found tag will be parsed as
+  raw HTML again. However, if a tag has a `markdown` attribute, this attribute controls parsing of
+  this one tag (see below).
+
+  Note that the parser basically supports only correct XHTML! However, there are some exceptions.
+  For example, attributes without values (i.e. boolean attributes) are also supported and elements
+  without content like `<hr />` can be written as `<hr>`. If an invalid closing tag is found, it is
+  ignored.
+
+* Parse as block-level elements: If the HTML/XML tag content should be parsed as text containing
+  block-level elements, the remaining text on the line will be parsed by the block-level parser as
+  if it appears on a separate line (**Caution**: This also means that if the line consists of the
+  start tag, text and the end tag, the end tag will not be found!). All following lines are parsed
+  as block-level elements until an HTML block line with the matching end tag is found or until the
+  end of the document.
+
+* Parse as span-level elements: If the HTML/XML tag content should be parsed as text containing span
+  level elements, then all text until the *next* matching end tag or until the end of the document
+  will be the content of the tag and will later be parsed by the span-level parser. This also means
+  that if the matching end tag is inside what appears to be a code span, it is still used!
+
+If there is text after an end tag, it will be parsed as if it appears on a separate line except when
+inside a raw HTML block.
+
+Also, if an invalid closing tag is found, it is ignored.
+
+Note that all HTML tag and attribute names are converted to lowercase!
+
+By default, kramdown parses all block HTML tags and all XML tags as raw HTML blocks. However, this
+can be configured with the `parse_block_html`. If this is set to `true`, then syntax parsing in HTML
+blocks is globally enabled. It is also possible to enable/disable syntax parsing on a tag per tag
+basis using the `markdown` attribute:
+
+* If an HTML tag has an attribute `markdown="0"`, then the tag is parsed as raw HTML block.
+
+* If an HTML tag has an attribute `markdown="1"`, then the default mechanism for parsing syntax in
+  this tag is used.
+
+* If an HTML tag has an attribute `markdown="block"`, then the content of the tag is parsed as block
+  level elements.
+
+* If an HTML tag has an attribute `markdown="span"`, then the content of the tag is parsed as span
+  level elements.
+
+The following list shows which HTML tags are parsed in which mode by default when `markdown="1"` is
+applied or `parse_block_html` is `true`:
+
+Parse as raw HTML
+: 
+        script style math option textarea pre code kbd samp var
+
+    Also, all general XML tags are parsed as raw HTML blocks.
+
+Parse as block-level elements
+: 
+        applet button blockquote body colgroup dd div dl fieldset form iframe li
+        map noscript object ol table tbody thead tfoot tr td ul
+
+Parse as span-level elements
+: 
+        a abbr acronym address b bdo big cite caption code del dfn dt em
+        h1 h2 h3 h4 h5 h6 i ins kbd label legend optgroup p pre q rb rbc
+        rp rt rtc ruby samp select small span strong sub sup th tt var
+
+> Remember that all span-level HTML tags like `a` or `b` do not start a HTML block! However, the
+> above lists also include span-level HTML tags in the case the `markdown` attribute is used on a
+> tag inside a raw HTML block.
+
+Here is a simple example input and its HTML output with `parse_block_html` set to `false`:
+
+    This is a para.
+    <div>
+    Something in here.
+    </div>
+    Other para.
+^
+    <p>This is a para.</p>
+    <div>
+    Something in here.
+    </div>
+    <p>Other para.</p>
+
+As one can see the content of the `div` tag will be parsed as raw HTML block and left alone.
+However, if the `markdown="1"` attribute was used on the `div` tag, the content would be parsed as
+block-level elements and therefore converted to a paragraph.
+
+You can also use several HTML tags at once:
+
+    <div id="content"><div id="layers"><div id="layer1">
+    This is some text in the `layer1` div.
+    </div>
+    This is some text in the `layers` div.
+    </div></div>
+    This is a para outside the HTML block.
+
+However, remember that if the content of a tag is parsed as block-level elements, the content that
+appears after a start/end tag but on the same line, is processed as if it appears on a new line:
+
+    <div markdown="1">This is the first part of a para,
+    which is continued here.
+    </div>
+
+    <p markdown="1">This works without problems because it is parsed as
+    span-level elements</p>
+
+    <div markdown="1">The end tag is not found because
+    this line is parsed as a paragraph</div>
+
+Since setting `parse_block_html` to `true` can lead to some not wanted behaviour, it is generally
+better to selectively enable or disable block/span-level elements parsing by using the `markdown`
+attribute!
+
+Unclosed block-level HTML tags are correctly closed at the end of the document to ensure correct
+nesting and invalidly used end tags are removed from the output:
+
+    This is a para.
+    <div markdown="1">
+    Another para.
+    </p>
+^
+    <p>This is a para.</p>
+    <div>
+      <p>Another para.</p>
+    </div>
+
+The parsing of processing instructions and XML comments is also supported. The content of both, PIs
+and XML comments, may span multiple lines. The start of a PI/XML comment may only appear at the
+beginning of a line, optionally indented up to three spaces. If there is text after the end of a PI
+or XML comment, it will be parsed as if it appears on a separate line. kramdown syntax in PIs/XML
+comments is not processed:
+
+    This is a para.
+    <!-- a *comment* -->
+    <? a processing `instruction`
+       spanning multiple lines
+    ?> First part of para,
+    continues here.
+
+
+
+# Text Markup
+
+These elements are all span-level elements and used inside block-level elements to markup text
+fragments. For example, one can easily create links or apply emphasis to certain text parts.
+
+Note that empty span-level elements are not converted to empty HTML tags but are copied as-is to the
+output.
+
+
+
+## Links and Images
+
+Three types of links are supported: automatic links, inline links and reference links.
+
+### Automatic Links
+
+This is the easiest one to create: Just surround a web address or an email address with angle
+brackets and the address will be turned into a proper link. The address will be used as link target
+and as link text. For example:
+
+    Information can be found on the <http://example.com> homepage.
+    You can also mail me: <me.example at example.com>
+
+It is not possible to specify a different link text using automatic links -- use the other link
+types for this!
+
+
+### Inline Links
+
+As the wording suggests, inline links provide all information inline in the text flow. Reference
+style links only provide the link text in the text flow and everything else is defined
+elsewhere. This also allows you to reuse link definitions.
+
+An inline style link can be created by surrounding the link text which must contain at least one
+character with square brackets, followed immediately by the link URL (and an optional title in
+single or double quotes preceded by at least one space) in normal parentheses. For example:
+
+    This is [a link](http://rubyforge.org) to a page.
+    A [link](../test "local URI") can also have a title.
+    And [spaces](link with spaces.html)!
+
+Notes:
+
+* The link text is treated like normal span-level text and therefore is parsed and converted.
+  However, if you use square brackets within the link text, you have to either properly nest them or
+  to escape them. It is not possible to create nested links!
+
+* The link URL must not contain single or double quotes and it has to contain properly nested
+  parentheses if no title is specified, or the link URL must be contained in angle brackets
+  (incorrectly nested parentheses are allowed).
+
+* The link title may not contain its delimiters and may not be empty.
+
+### Reference Links
+
+To create a reference style link, you need to surround the link text with square brackets (as with
+inline links), followed by optional spaces/tabs/line breaks and then optionally followed with
+another set of square brackets with the link identifier in them. A link identifier may not contain a
+closing bracket and, when specified in a link definition, newline characters; it is also not case
+sensitive, line breaks and tabs are converted to spaces and multiple spaces are compressed into one.
+For example:
+
+    This is a [reference style link][linkid] to a page. And [this]
+    [linkid] is also a link. As is [this][] and [THIS].
+
+If you don't specify a link identifier (i.e. only use empty square brackets) or completely omit the
+second pair of square brackets, the link text is converted to a valid link identifier by removing
+all invalid characters and inserting spaces for line breaks. If there is a link definition found for
+the link identifier, a link will be created. Otherwise the text is not converted to a link.
+
+### Link Definitions
+
+The link definition can be put anywhere in the document. It does not appear in the output. A link
+definition looks like this:
+
+    [linkid]: http://www.example.com/ "Optional Title"
+
+> Link definitions are, despite being described here, non-content block-level elements.
+{: .information}
+
+The link definition has the following structure:
+
+* The link identifier in square brackets, optionally indented up to three spaces,
+* then a colon and one or more spaces/tabs,
+* then the link URL which must not contain any single or double quotes and which must contain at
+  least one non-space character, or a left angle bracket, the link URL and a right angle bracket,
+* then optionally the title in single or double quotes, separated from the link URL by one or more
+  spaces or on the next line by itself indented any number of spaces/tabs.
+
+> The original Markdown syntax also allowed the title to be specified in parenthesis. This is not
+> allowed for consistency with the inline title.
+{: .markdown-difference}
+
+If you have some text that looks like a link definition but should really be a link and some text,
+you can escape the colon after the link identifier:
+
+    The next paragraph contains a link and some text.
+
+    [Room 100]\: There you should find everything you need!
+
+    [Room 100]: link_to_room_100.html
+
+
+### Images
+
+Images can be specified via a syntax that is similar to the one used by links. The difference is
+that you have to use an exclamation mark before the first square bracket and that the link text of a
+normal link, which may also be the empty string in case of image links, becomes the alternative text
+of the image link. As with normal links, image links can be written inline or reference style. For
+example:
+
+    Here comes a ![smiley](../images/smiley.png)! And here
+    ![too](../images/other.png 'Title text'). Or ![here].
+    With empty alt text ![](see.jpg)
+
+The link definition for images is exactly the same as the link definition for normal links.
+
+
+## Emphasis
+
+kramdown supports two types of emphasis: light and strong emphasis. Text parts that are surrounded
+with single asterisks `*` or underscores `_` are treated as text with light emphasis, text parts
+surrounded with two asterisks or underscores are treated as text with strong emphasis. Surrounded
+means that the starting delimiter must not be followed by a space and that the stopping delimiter
+must not be preceded by a space.
+
+Here is an example for text with light and strong emphasis:
+
+    *some text*
+    _some text_
+    **some text**
+    __some text__
+
+The asterisk form is also allowed within a single word:
+
+    This is un*believe*able! This d_oe_s not work!
+
+Text can be marked up with both light and strong emphasis, possibly using different delimiters.
+However, it is not possible to nest strong within strong or light within light emphasized text:
+
+    This is a ***text with light and strong emphasis***.
+    This **is _emphasized_ as well**.
+    This *does _not_ work*.
+    This **does __not__ work either**.
+
+If one or two asterisks or underscores are surrounded by spaces, they are treated literally. If you
+want to force the literal meaning of an asterisk or an underscore you can backslash-escape it:
+
+    This is a * literal asterisk.
+    These are ** two literal asterisk.
+    As \*are\* these!
+
+
+## Code Spans
+
+This is the span-level equivalent of the [code block](#code-blocks) element. You can markup a text
+part as code span by surrounding it with backticks `` ` ``. For example:
+
+    Use `<html>` tags for this.
+
+Note that all special characters in a code span are treated correctly. For example, when a code span
+is converted to HTML, the characters `<`, `>` and `&` are substituted by their respective HTML
+counterparts.
+
+To include a literal backtick in a code span, you need to use two or more backticks as delimiters.
+You can insert one optional space after the starting and before the ending delimiter (these spaces
+are not used in the output). For example:
+
+    Here is a literal `` ` `` backtick.
+    And here is ``  `some`  `` text (note the two spaces so that one is left
+    in the output!).
+
+A single backtick surrounded by spaces is treated as literal backtick. If you want to force the
+literal meaning of a backtick you can backslash-escape it:
+
+    This is a ` literal backtick.
+    As \`are\` these!
+
+As with [code blocks](#language-of-code-blocks) you can set the language of a code span by using an
+[IAL](#inline-attribute-lists):
+
+    This is a Ruby code fragment `x = Class.new`{:.language-ruby}
+
+
+## HTML Spans
+
+HTML tags cannot only be used on the block-level but also on the span-level. Span-level HTML tags
+can only be used inside one block-level element, it is not possible to use a start tag in one block
+level element and the end tag in another. Note that only correct XHTML is supported! This means that
+you have to use, for example, `<br />` instead of `<br>` (although kramdown tries to fix such errors
+if possible).
+
+By default, kramdown parses kramdown syntax inside span HTML tags. However, this behaviour can be
+configured with the `parse_span_html` option. If this is set to `true`, then syntax parsing in HTML
+spans is enabled, if it is set to `false`, parsing is disabled. It is also possible to
+enable/disable syntax parsing on a tag per tag basis using the `markdown` attribute:
+
+* If an HTML tag has an attribute `markdown="0"`, then no parsing (except parsing of HTML span tags)
+  is done inside that HTML tag.
+
+* If an HTML tag has an attribute `markdown="1"`, then the content of the tag is parsed as span
+  level elements.
+
+* If an HTML tag has an attribute `markdown="block"`, then a warning is issued because HTML spans
+  cannot contain block-level elements and the attribute is ignored.
+
+* If an HTML tag has an attribute `markdown="span"`, then the content of the tag is parsed as span
+  level elements.
+
+The content of a span-level HTML tag is normally parsed as span-level elements. Note, however, that
+some tags like `<script>` are not parsed, i.e. their content is not modified.
+
+Processing instructions and XML comments can also be used (their content is not parsed). However, as
+with HTML tags the start and the end have to appear in the same block-level element.
+
+Span-level PIs and span-level XML comments as well as general span-level HTML and XML tags have to
+be preceded by at least one non whitespace character on the same line so that kramdown correctly
+recognizes them as span-level element and not as block-level element. However, all span HTML tags,
+i.e. `a`, `em`, `b`, ..., (opening or closing) can appear at the start of a line.
+
+Unclosed span-level HTML tags are correctly closed at the end of the span-level text to ensure
+correct nesting and invalidly used end tags or block HTML tags are removed from the output:
+
+    This is </invalid>.
+
+    This <span>is automatically closed.
+^
+    <p>This is .</p>
+
+    <p>This <span>is automatically closed.</span></p>
+
+Also note that one or more consecutive new line characters in an HTML span tag are replaced by a
+single space, for example:
+
+    Link: <a href="some
+    link">text</a>
+^
+    <p>Link: <a href="some link">text</a></p>
+
+
+## Footnotes
+
+> This syntax feature is not part of the original Markdown syntax. The idea and syntax comes from
+> the [PHP Markdown Extra] package.
+{: .markdown-difference}
+
+Footnotes in kramdown are similar to reference style links and link definitions. You need to place
+the footnote marker in the correct position in the text and the actual footnote content can be
+defined anywhere in the document.
+
+More exactly, a footnote marker can be created by placing the footnote name in square brackets.
+The footnote name has to start with a caret (`^`), followed by a word character or a digit and then
+optionally followed by other word characters, digits or dashes. For example:
+
+    This is some text.[^1]. Other text.[^footnote].
+
+Footnote markers with the same name will link to the same footnote definition. The actual naming of
+a footnote does not matter since the numbering of footnotes is controlled via the position of the
+footnote markers in the document (the first found footnote marker will get the number 1, the second 
+new footnote marker the number 2 and so on). If there is a footnote definition found for the
+identifier, a footnote will be created. Otherwise the footnote marker is not converted to a footnote
+link. Also note that all attributes set via a span IAL are ignored for a footnote marker!
+
+A footnote definition is used to define the content of a footnote and has the following structure:
+
+* The footnote name in square brackets, optionally indented up to three spaces,
+* then a colon and one or more optional spaces,
+* then the text of the footnote
+* and optionally more text on the following lines which have to follow the syntax for [standard code
+  blocks](#standard-code-blocks) (the leading four spaces/one tab are naturally stripped from the
+  text)
+
+> Footnote definitions are, despite being described here, non-content block-level elements.
+{: .information}
+
+The whole footnote content is treated like block-level text and can therefore contain any valid
+block-level element (also, any block-level element can be the first element). If you want to have a
+code block as first element, note that all leading spaces/tabs on the first line are stripped away.
+Here are some example footnote definitions:
+
+    [^1]: Some *crazy* footnote definition.
+
+    [^footnote]:
+        > Blockquotes can be in a footnote.
+
+            as well as code blocks
+
+        or, naturally, simple paragraphs.
+
+    [^other-note]:       no code block here (spaces are stripped away)
+
+    [^codeblock-note]:
+            this is now a code block (8 spaces indentation)
+
+It does not matter where you put a footnote definition in a kramdown document; the content of all
+referenced footnote definitions will be placed at the end of the kramdown document. Not referenced
+footnote definitions are ignored. If more than one footnote definitions have the same footnote name,
+all footnote definitions but the last are ignored.
+
+
+## Abbreviations
+
+> This syntax feature is not part of the original Markdown syntax. The idea and syntax comes from
+> the [PHP Markdown Extra] package.
+{: .markdown-difference}
+
+kramdown provides a syntax to assign the full phrase to an abbreviation. When writing the text, you
+don't need to do anything special. However, once you add abbreviation definitions, the
+abbreviations in the text get marked up automatically. Abbreviations can consist of any character
+except a closing bracket.
+
+An abbreviation definition is used to define the full phrase for an abbreviation and has the
+following structure:
+
+* An asterisk and the abbreviation in square brackets, optionally indented up to three
+  spaces,
+* then a colon and the full phrase of the abbreviation on one line (leading and trailing spaces are
+  stripped from the full phrase).
+
+Later abbreviation definition for the same abbreviation override prior ones and it does not matter
+where you put an abbreviation definition in a kramdown document. Empty definitions are also allowed.
+
+Here are some examples:
+
+    This is some text not written in HTML but in another language!
+
+    *[another language]: It's called Markdown
+    *[HTML]: HyperTextMarkupLanguage
+
+> Abbreviation definitions are, despite being described here, non-content block-level elements.
+{: .information}
+
+
+## Typographic Symbols
+
+> The original Markdown syntax does not support these transformations.
+{: .markdown-difference}
+
+kramdown converts the following plain ASCII character into their corresponding typographic symbols:
+
+* `---` will become an em-dash (like this ---)
+* `--` will become an en-dash (like this --)
+* `...` will become an ellipsis (like this ...)
+* `<<` will become a left guillemet (like this <<) -- an optional following space will become a
+  non-breakable space
+* `>>` will become a right guillemet (like this >>) -- an optional leading space will become a
+  non-breakable space
+
+The parser also replaces normal single `'` and double quotes `"` with "fancy quotes". There *may* be
+times when kramdown falsely replace the quotes. If this is the case, just \'escape\" the quotes and
+they won't be replaced with fancy ones.
+
+
+
+# Non-content elements
+
+This section describes the non-content elements that are used in kramdown documents, i.e. elements
+that don't provide content for the document but have other uses such as separating block-level
+elements or attaching attributes to elements.
+
+Three non-content block-level elements are not described here because they fit better where they
+are:
+
+* [link definitions](#link-definitions)
+* [footnote definitions](#footnotes)
+* [abbreviation definition](#abbreviations)
+
+
+## End-Of-Block Marker    {#eob-marker}
+
+> The EOB marker is not part of the standard Markdown syntax.
+{: .markdown-difference}
+
+The End-Of-Block (EOB) marker -- a `^` as first character on an otherwise empty line -- is a block
+level element that can be used to specify the end of a block-level element even if the block-level
+element, after which it is used, would continue otherwise. If there is no block-level element to
+end, the EOB marker is simply ignored.
+
+You won't find an EOB marker in most kramdown documents but sometimes it is necessary to use it to
+achieve the wanted results which would be impossible otherwise. However, it should only be used when
+absolutely necessary!
+
+For example, the following gives you one list with two items:
+
+    * list item one
+
+    * list item two
+
+By using an EOB marker, you can make two lists with one item each:
+
+    * list one
+    ^
+    * list two
+
+
+## Attribute List Definitions
+
+> This syntax feature is not part of the original Markdown syntax. The idea and syntax comes from
+> the [Maruku] package.
+{: .markdown-difference}
+
+This is an implementation of [Maruku]'s feature for adding attributes to block and span-level
+elements (the naming is also taken from Maruku). This block-level element is used to define
+attributes which can be referenced later. The [Block Inline Attribute List](#block-ials) is used to
+attach attributes to a block-level element and the [Span Inline Attribute List](#span-ials) is used
+to attach attributes to a span-level element.
+
+Following are some examples of attribute list definitions (ALDs) and afterwards comes the syntax
+explanation:
+
+    {:ref-name: #myid .my-class}
+    {:other: ref-name #id-of-other title="hallo you"}
+    {:test: key="value \" with quote" and other='quote brace \}'}
+
+An ALD line has the following structure:
+
+* a left brace, optionally preceded by up to three spaces,
+* followed by a colon, the reference name and another colon,
+* followed by attribute definitions (allowed characters are backslash-escaped closing braces or any
+  character except a not escaped closing brace),
+* followed by a closing brace and optional spaces until the end of the line.
+
+The reference name needs to start with a word character or a digit, optionally followed by other
+word characters, digits or dashes.
+
+There are four different types of attribute definitions which have to be separated by one or more
+spaces:
+
+references
+
+: This must be a valid reference name. It is used to reference an other ALD so that the attributes
+  of the other ALD are also included in this one. The reference name is ignored when collecting the
+  attributes if no attribute definition list with this reference name exists. For example, a simple
+  reference looks like `id`.
+
+key-value pairs
+
+: A key-value pair is defined by a key name, which must follow the rules for reference names, then
+  an equal sign and then the value in single or double quotes. If you need to use the value
+  delimiter (a single or a double quote) inside the value, you need to escape it with a backslash.
+  Key-value pairs can be used to specify arbitrary attributes for block or span-level elements. For
+  example, a key-value pair looks like `key1="bef \"quoted\" aft"` or `title='This is a title'`.
+
+ID name
+
+: An ID name is defined by using a hash and then the identifier name which needs to start with an
+  ASCII alphabetic character (A-Z or a-z), optionally followed by other ASCII characters, digits,
+  dashes or colons. This is a short hand for the key-value pair `id="IDNAME"` since this is often
+  used. The ID name specifies the unique ID of a block or span-level element. For example, an ID
+  name looks like `#myid`.
+
+class names
+
+: A class name is defined by using a dot and then the class name. This is (almost, but not quite) a
+  short hand for the key-value pair `class="class-name"`. Almost because it actually means that the
+  class name should be appended to the current value of the `class` attribute. The following ALDs
+  are all equivalent:
+
+      {:id: .cls1 .cls2}
+      {:id: class="cls1" .cls2}
+      {:id: class="something" class="cls1" .cls2}
+      {:id: class="cls1 cls2"}
+
+As can be seen from the example of the class names, attributes that are defined earlier are
+overwritten by ones with the same name defined later.
+
+> Also, everything in the attribute definitions part that does not match one of the above four types
+> is ignored.
+{:.information}
+
+If there is more than one ALD with the same reference name, the attribute definitions of all the
+ALDs are processed like they are defined in one ALD.
+
+
+## Inline Attribute Lists
+
+These elements are used to attach attributes to another element.
+
+### Block Inline Attribute Lists   {#block-ials}
+
+> This syntax feature is not part of the original Markdown syntax. The idea and syntax comes from
+> the [Maruku] package.
+{: .markdown-difference}
+
+This block-level element is used to attach attributes to a block-level element. A block inline
+attribute list (block IAL) has the same structure as an [ALD](#attribute-list-definitions) except
+that the colon/reference name/colon part is replaced by a colon. A block IAL (or two or more block
+IALs) has to be put directly before or after the block-level element to which the attributes should
+be attached. If a block IAL is directly after *and* before a block-level element, it is applied to
+preceding element. The block IAL is ignored in all other cases, for example, when the block IAL is
+surrounded by blank lines.
+
+Key-value pairs of an IAL take precedence over equally named key-value pairs in referenced ALDs.
+
+Here are some examples for block IALs:
+
+    A simple paragraph with an ID attribute.
+    {: #para-one}
+
+    > A blockquote with a title
+    {:title="The blockquote title"}
+    {: #myid}
+
+    {:.ruby}
+        Some code here
+
+### Span Inline Attribute Lists      {#span-ials}
+
+> This syntax feature is not part of the original Markdown syntax. The idea and syntax comes from
+> the [Maruku] package.
+{: .markdown-difference}
+
+This is a version of the [block inline attribute list](#block-ials) for span-level elements. It has
+the same structure as the block IAL except that leading and trailing spaces are not allowed. A span
+IAL (or two or more span IALs) has to be put directly after the span-level element to which it
+should be applied, no additional character is allowed between, otherwise it is ignored and only
+removed from the output.
+
+Here are some examples for span IALs:
+
+    This *is*{:.underline} some `code`{:#id}{:.class}.
+    A [link](test.html){:rel='something'} and some **tools**{:.tools}.
+
+The special span IAL `{::}` contains no attributes but doesn't generate a warning either. It can be
+used to separate consecutive elements that would be falsely parsed if not separated. Here is an use
+case:
+
+    This *is italic*{::}*marked*{:.special} text
+
+
+## Extensions
+
+> This syntax feature is not part of the original Markdown syntax.
+{: .markdown-difference}
+
+Extensions provide additional functionality but use the same syntax for it. They are available as
+block as well as span-level elements.
+
+The syntax for an extension is very similar to the syntax of [ALDs](#attribute-list-definitions).
+Here are some examples of how to specify extensions and afterwards is the syntax definition:
+
+    {::comment}
+    This text is completely ignored by kramdown - a comment in the text.
+    {:/comment}
+
+    Do you see {::comment}this text{:/comment}?
+    {::comment}some other comment{:/}
+
+    {::options key="val" /}
+
+An extension can be specified with or without a body. Therefore there exist a start and an end tag
+for extensions. The start tag has the following structure:
+
+* a left brace,
+* followed by two colons and the extension name,
+* optionally followed by a space and attribute definitions (allowed characters are backslash-escaped
+  closing braces or any character except a not escaped closing brace -- same as with ALDs),
+* followed by a slash and a right brace (in case the extension has no body) or only a right
+  brace (in case the extension has a body).
+
+The stop tag has the following structure:
+
+* a left brace,
+* followed by a colon and a slash,
+* optionally followed by the extension name,
+* followed by a right brace.
+
+A stop tag is only needed if the extension has a body!
+
+The above syntax can be used as is for span-level extensions. The starting and ending lines for block-level
+extensions are defined as:
+
+* The starting line consists of the extension start tag, optionally preceded by up to three spaces,
+  and followed by optional spaces until the end of the line.
+* The ending line consists of the extension stop tag, optionally preceded by up to three spaces,
+  and followed by optional spaces until the end of the line.
+
+If no end tag can be found for an extension start tag, the start tag is treated as if it has no
+body. If an invalid extension stop tag is found, it is ignored. If an invalid extension name is
+specified the extension (and the eventually specified body) are ignored.
+
+The following extensions can be used with kramdown:
+
+`comment`
+
+: Treat the body text as a comment which does not show in the output.
+
+`nomarkdown`
+
+: Don't process the body with kramdown but output it as-is. The attribute `type` specifies which
+  converters should output the body: if the attribute is missing, all converters should output it.
+  Otherwise the attribute value has to be a space separated list of converter names and these
+  converters should output the body.
+
+`options`
+
+: Should be used without a body since the body is ignored. Is used for setting the global options
+  for the kramdown processor (for example, to disable automatic header ID generation). Note that
+  options that are used by the parser are immediately effective whereas all other options are not!
+  This means, for example, that it is not possible to set converter options only for some part of a
+  kramdown document.
+
+
+
+{include_file: doc/links.markdown}
diff --git a/app/server/vendor/kramdown/doc/tests.page b/app/server/vendor/kramdown/doc/tests.page
new file mode 100644
index 0000000..2431cb8
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/tests.page
@@ -0,0 +1,105 @@
+---
+title: Tests and Benchmark
+---
+# Tests and Benchmark
+
+## Tests
+
+There exist several test suites for testing the correctness of a Markdown implementation. The
+original [Markdown Test Suite] is the standard which one needs to test against. The [PHP Markdown
+suite][MDTest] contains the original test suite and several more tests (some specifically geared
+towards the extension of the PHP Markdown Extra package). I have used the latter test tool to
+roughly verify that kramdown is able to parse standard Markdown. However, since the syntax used by
+kramdown varies slightly from standard Markdown most of the tests fail - which is fine. When looking
+at the differences one can see that the failures result from these differences.
+
+Besides using the above mentioned test suite kramdown comes with its own set of tests which is used
+to verify that the implementation matches the kramdown specification.
+
+If you believe you have found a bug in the implementation, please follow these steps:
+
+* Check the [syntax page](syntax.html) and see if the behaviour is not intended.
+
+* If the behaviour is not intended and it seems that kramdown should parse some text in another
+  fashion, please open a [bug report] and attach two files: one with the text and one with the HTML
+  conversion you think is correct.
+
+[bug report]: http://github.com/gettalong/kramdown/issues
+
+
+## Benchmark
+
+kramdown comes with a small benchmark to test how fast it is in regard to four other Ruby Markdown
+implementations: Maruku, BlueFeather, BlueCloth, RDiscount and Redcarpet. The first two are written
+using only Ruby, the latter three are written in C and need to be compiled.
+
+As one can see below, kramdown is currently (January 2014) ~2.5x faster than Maruku, ~4-6x faster
+than BlueFeather but ~30x slower than BlueCloth and RDiscount and ~150x slower than Redcarpet:
+
+<pre><code>
+Running tests on 2014-01-05 under ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-linux]
+
+Test using file mdsyntax.text and 20 runs
+Rehearsal ----------------------------------------------------
+kramdown 1.3.0     1.090000   0.020000   1.110000 (  1.102094)
+Maruku 0.7.0       3.140000   0.010000   3.150000 (  3.151116)
+BlueFeather 0.41   5.140000   0.000000   5.140000 (  5.136591)
+BlueCloth 2.2.0    0.050000   0.000000   0.050000 (  0.057502)
+RDiscount 2.0.7    0.020000   0.000000   0.020000 (  0.015115)
+redcarpet 3.0.0    0.000000   0.000000   0.000000 (  0.004641)
+------------------------------------------- total: 9.470000sec
+
+                       user     system      total        real
+kramdown 1.3.0     1.200000   0.000000   1.200000 (  1.199684)
+Maruku 0.7.0       3.010000   0.040000   3.050000 (  3.043411)
+BlueFeather 0.41   5.720000   0.000000   5.720000 (  5.723845)
+BlueCloth 2.2.0    0.040000   0.000000   0.040000 (  0.040749)
+RDiscount 2.0.7    0.020000   0.000000   0.020000 (  0.017600)
+redcarpet 3.0.0    0.000000   0.000000   0.000000 (  0.004822)
+
+Real time of X divided by real time of kramdown
+Maruku             2.5368
+BlueFeather        4.7711
+BlueCloth          0.034
+RDiscount          0.0147
+redcarpet          0.004
+
+Test using file mdbasics.text and 20 runs
+Rehearsal ----------------------------------------------------
+kramdown 1.3.0     0.220000   0.000000   0.220000 (  0.217277)
+Maruku 0.7.0       0.850000   0.000000   0.850000 (  0.847144)
+BlueFeather 0.41   1.290000   0.010000   1.300000 (  1.291695)
+BlueCloth 2.2.0    0.010000   0.000000   0.010000 (  0.012484)
+RDiscount 2.0.7    0.000000   0.000000   0.000000 (  0.004158)
+redcarpet 3.0.0    0.000000   0.000000   0.000000 (  0.001721)
+------------------------------------------- total: 2.380000sec
+
+                       user     system      total        real
+kramdown 1.3.0     0.210000   0.000000   0.210000 (  0.215760)
+Maruku 0.7.0       0.590000   0.000000   0.590000 (  0.591681)
+BlueFeather 0.41   1.360000   0.000000   1.360000 (  1.362281)
+BlueCloth 2.2.0    0.010000   0.000000   0.010000 (  0.013973)
+RDiscount 2.0.7    0.010000   0.000000   0.010000 (  0.005797)
+redcarpet 3.0.0    0.000000   0.000000   0.000000 (  0.001692)
+
+Real time of X divided by real time of kramdown
+Maruku             2.7423
+BlueFeather        6.3139
+BlueCloth          0.0648
+RDiscount          0.0269
+redcarpet          0.0078
+</code></pre>
+
+And here are some graphs which show the execution times of the various kramdown releases on
+different Ruby interpreters:
+
+![ruby 1.8.7p302]({relocatable: img/graph-ruby-1.8.7-302.png})
+![ruby 1.9.2p320]({relocatable: img/graph-ruby-1.9.2p320-320.png})
+![ruby 1.9.3p448]({relocatable: img/graph-ruby-1.9.3p448-448.png})
+![ruby 2.0.0p247]({relocatable: img/graph-ruby-2.0.0p247-247.png})
+![ruby 2.1.0p0]({relocatable: img/graph-ruby-2.1.0p0-0.png})
+![jruby 1.7.3]({relocatable: img/graph-jruby-1.7.3-385.png})
+![rubinius 2.0.0]({relocatable: img/graph-rubinius-2.0.0-0.png})
+
+[Markdown Test Suite]: http://daringfireball.net/projects/downloads/MarkdownTest_1.0.zip
+[MDTest]: http://www.michelf.com/docs/projets/mdtest-1.0.zip
diff --git a/app/server/vendor/kramdown/doc/virtual b/app/server/vendor/kramdown/doc/virtual
new file mode 100644
index 0000000..01db3b1
--- /dev/null
+++ b/app/server/vendor/kramdown/doc/virtual
@@ -0,0 +1,2 @@
+rdoc/index.html:
+  title: API Documentation
diff --git a/app/server/vendor/kramdown/lib/kramdown.rb b/app/server/vendor/kramdown/lib/kramdown.rb
new file mode 100644
index 0000000..6c4bac5
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown.rb
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'kramdown/document'
diff --git a/app/server/vendor/kramdown/lib/kramdown/compatibility.rb b/app/server/vendor/kramdown/lib/kramdown/compatibility.rb
new file mode 100644
index 0000000..f12783d
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/compatibility.rb
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+# All the code in this file is backported from Ruby 1.8.7 sothat kramdown works under 1.8.5
+#
+# :stopdoc:
+
+if RUBY_VERSION <= '1.8.6'
+  require 'rexml/parsers/baseparser'
+  module REXML
+    module Parsers
+      class BaseParser
+        UNAME_STR= "(?:#{NCNAME_STR}:)?#{NCNAME_STR}" unless const_defined?(:UNAME_STR)
+      end
+    end
+  end
+
+  if !String.instance_methods.include?("start_with?")
+
+    class String
+      def start_with?(str)
+        self[0, str.length] == str
+      end
+      def end_with?(str)
+        self[-str.length, str.length] == str
+      end
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/converter.rb b/app/server/vendor/kramdown/lib/kramdown/converter.rb
new file mode 100644
index 0000000..1f37938
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/converter.rb
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+
+  # This module contains all available converters, i.e. classes that take a root Element and convert
+  # it to a specific output format. The result is normally a string. For example, the
+  # Converter::Html module converts an element tree into valid HTML.
+  #
+  # Converters use the Base class for common functionality (like applying a template to the output)
+  # \- see its API documentation for how to create a custom converter class.
+  module Converter
+
+    autoload :Base, 'kramdown/converter/base'
+    autoload :Html, 'kramdown/converter/html'
+    autoload :Latex, 'kramdown/converter/latex'
+    autoload :Kramdown, 'kramdown/converter/kramdown'
+    autoload :Toc, 'kramdown/converter/toc'
+    autoload :RemoveHtmlTags, 'kramdown/converter/remove_html_tags'
+    autoload :Pdf, 'kramdown/converter/pdf'
+
+  end
+
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/converter/base.rb b/app/server/vendor/kramdown/lib/kramdown/converter/base.rb
new file mode 100644
index 0000000..4f38615
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/converter/base.rb
@@ -0,0 +1,231 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'erb'
+require 'kramdown/utils'
+
+module Kramdown
+
+  module Converter
+
+    # == \Base class for converters
+    #
+    # This class serves as base class for all converters. It provides methods that can/should be
+    # used by all converters (like #generate_id) as well as common functionality that is
+    # automatically applied to the result (for example, embedding the output into a template).
+    #
+    # A converter object is used as a throw-away object, i.e. it is only used for storing the needed
+    # state information during conversion. Therefore one can't instantiate a converter object
+    # directly but only use the Base::convert method.
+    #
+    # == Implementing a converter
+    #
+    # Implementing a new converter is rather easy: just derive a new class from this class and put
+    # it in the Kramdown::Converter module (the latter is only needed if auto-detection should work
+    # properly). Then you need to implement the #convert method which has to contain the conversion
+    # code for converting an element and has to return the conversion result.
+    #
+    # The actual transformation of the document tree can be done in any way. However, writing one
+    # method per element type is a straight forward way to do it - this is how the Html and Latex
+    # converters do the transformation.
+    #
+    # Have a look at the Base::convert method for additional information!
+    class Base
+
+      # Can be used by a converter for storing arbitrary information during the conversion process.
+      attr_reader :data
+
+      # The hash with the conversion options.
+      attr_reader :options
+
+      # The root element that is converted.
+      attr_reader :root
+
+      # The warnings array.
+      attr_reader :warnings
+
+      # Initialize the converter with the given +root+ element and +options+ hash.
+      def initialize(root, options)
+        @options = options
+        @root = root
+        @data = {}
+        @warnings = []
+      end
+      private_class_method(:new, :allocate)
+
+      # Returns whether the template should be applied before the conversion of the tree.
+      #
+      # Defaults to false.
+      def apply_template_before?
+        false
+      end
+
+      # Returns whether the template should be applied ater the conversion of the tree.
+      #
+      # Defaults to true.
+      def apply_template_after?
+        true
+      end
+
+      # Convert the element tree +tree+ and return the resulting conversion object (normally a
+      # string) and an array with warning messages. The parameter +options+ specifies the conversion
+      # options that should be used.
+      #
+      # Initializes a new instance of the calling class and then calls the #convert method with
+      # +tree+ as parameter.
+      #
+      # If the +template+ option is specified and non-empty, the template is evaluate with ERB
+      # before and/or after the tree conversion depending on the result of #apply_template_before?
+      # and #apply_template_after?. If the template is evaluated before, an empty string is used for
+      # the body; if evaluated after, the result is used as body. See ::apply_template.
+      #
+      # The template resolution is done in the following way (for the converter ConverterName):
+      #
+      # 1. Look in the current working directory for the template.
+      #
+      # 2. Append +.converter_name+ (e.g. +.html+) to the template name and look for the resulting
+      #    file in the current working directory (the form +.convertername+ is deprecated).
+      #
+      # 3. Append +.converter_name+ to the template name and look for it in the kramdown data
+      #    directory (the form +.convertername+ is deprecated).
+      #
+      # 4. Check if the template name starts with 'string://' and if so, strip this prefix away and
+      #    use the rest as template.
+      def self.convert(tree, options = {})
+        converter = new(tree, ::Kramdown::Options.merge(options.merge(tree.options[:options] || {})))
+
+        apply_template(converter, '') if !converter.options[:template].empty? && converter.apply_template_before?
+        result = converter.convert(tree)
+        result.encode!(tree.options[:encoding]) if result.respond_to?(:encode!) && result.encoding != Encoding::BINARY
+        result = apply_template(converter, result) if !converter.options[:template].empty? && converter.apply_template_after?
+
+        [result, converter.warnings]
+      end
+
+      # Convert the element +el+ and return the resulting object.
+      #
+      # This is the only method that has to be implemented by sub-classes!
+      def convert(el)
+        raise NotImplementedError
+      end
+
+      # Apply the +template+ using +body+ as the body string.
+      #
+      # The template is evaluated using ERB and the body is available in the @body instance variable
+      # and the converter object in the @converter instance variable.
+      def self.apply_template(converter, body) # :nodoc:
+        erb = ERB.new(get_template(converter.options[:template]))
+        obj = Object.new
+        obj.instance_variable_set(:@converter, converter)
+        obj.instance_variable_set(:@body, body)
+        erb.result(obj.instance_eval{binding})
+      end
+
+      # Return the template specified by +template+.
+      def self.get_template(template)
+        #DEPRECATED: use content of #get_template_new in 2.0
+        format_ext = '.' + self.name.split(/::/).last.downcase
+        shipped = File.join(::Kramdown.data_dir, template + format_ext)
+        if File.exist?(template)
+          File.read(template)
+        elsif File.exist?(template + format_ext)
+          File.read(template + format_ext)
+        elsif File.exist?(shipped)
+          File.read(shipped)
+        elsif template.start_with?('string://')
+          template.sub(/\Astring:\/\//, '')
+        else
+          get_template_new(template)
+        end
+      end
+
+      def self.get_template_new(template) # :nodoc:
+        format_ext = '.' + ::Kramdown::Utils.snake_case(self.name.split(/::/).last)
+        shipped = File.join(::Kramdown.data_dir, template + format_ext)
+        if File.exist?(template)
+          File.read(template)
+        elsif File.exist?(template + format_ext)
+          File.read(template + format_ext)
+        elsif File.exist?(shipped)
+          File.read(shipped)
+        elsif template.start_with?('string://')
+          template.sub(/\Astring:\/\//, '')
+        else
+          raise "The specified template file #{template} does not exist"
+        end
+      end
+
+      # Add the given warning +text+ to the warning array.
+      def warning(text)
+        @warnings << text
+      end
+
+      # Return +true+ if the header element +el+ should be used for the table of contents (as
+      # specified by the +toc_levels+ option).
+      def in_toc?(el)
+        @options[:toc_levels].include?(el.options[:level]) && (el.attr['class'] || '') !~ /\bno_toc\b/
+      end
+
+      # Return the output header level given a level.
+      #
+      # Uses the +header_offset+ option for adjusting the header level.
+      def output_header_level(level)
+        [[level + @options[:header_offset], 6].min, 1].max
+      end
+
+      # Extract the code block/span language from the attributes.
+      def extract_code_language(attr)
+        if attr['class'] && attr['class'] =~ /\blanguage-\w+\b/
+          attr['class'].scan(/\blanguage-(\w+)\b/).first.first
+        end
+      end
+
+      # See #extract_code_language
+      #
+      # *Warning*: This version will modify the given attributes if a language is present.
+      def extract_code_language!(attr)
+        lang = extract_code_language(attr)
+        attr['class'] = attr['class'].sub(/\blanguage-\w+\b/, '').strip if lang
+        attr.delete('class') if lang && attr['class'].empty?
+        lang
+      end
+
+      # Generate an unique alpha-numeric ID from the the string +str+ for use as a header ID.
+      #
+      # Uses the option +auto_id_prefix+: the value of this option is prepended to every generated
+      # ID.
+      def generate_id(str)
+        str = ::Kramdown::Utils::Unidecoder.decode(str) if @options[:transliterated_header_ids]
+        gen_id = str.gsub(/^[^a-zA-Z]+/, '')
+        gen_id.tr!('^a-zA-Z0-9 -', '')
+        gen_id.tr!(' ', '-')
+        gen_id.downcase!
+        gen_id = 'section' if gen_id.length == 0
+        @used_ids ||= {}
+        if @used_ids.has_key?(gen_id)
+          gen_id += '-' << (@used_ids[gen_id] += 1).to_s
+        else
+          @used_ids[gen_id] = 0
+        end
+        @options[:auto_id_prefix] + gen_id
+      end
+
+      SMART_QUOTE_INDICES = {:lsquo => 0, :rsquo => 1, :ldquo => 2, :rdquo => 3} # :nodoc:
+
+      # Return the entity that represents the given smart_quote element.
+      def smart_quote_entity(el)
+        res = @options[:smart_quotes][SMART_QUOTE_INDICES[el.value]]
+        ::Kramdown::Utils::Entities.entity(res)
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/converter/html.rb b/app/server/vendor/kramdown/lib/kramdown/converter/html.rb
new file mode 100644
index 0000000..49d76b8
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/converter/html.rb
@@ -0,0 +1,457 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'rexml/parsers/baseparser'
+require 'kramdown/parser/html'
+
+module Kramdown
+
+  module Converter
+
+    # Converts a Kramdown::Document to HTML.
+    #
+    # You can customize the HTML converter by sub-classing it and overriding the +convert_NAME+
+    # methods. Each such method takes the following parameters:
+    #
+    # [+el+] The element of type +NAME+ to be converted.
+    #
+    # [+indent+] A number representing the current amount of spaces for indent (only used for
+    #            block-level elements).
+    #
+    # The return value of such a method has to be a string containing the element +el+ formatted as
+    # HTML element.
+    class Html < Base
+
+      begin
+        require 'coderay'
+
+        # Highlighting via coderay is available if this constant is +true+.
+        HIGHLIGHTING_AVAILABLE = true
+      rescue LoadError
+        HIGHLIGHTING_AVAILABLE = false  # :nodoc:
+      end
+
+      include ::Kramdown::Utils::Html
+      include ::Kramdown::Parser::Html::Constants
+
+      # The amount of indentation used when nesting HTML tags.
+      attr_accessor :indent
+
+      # Initialize the HTML converter with the given Kramdown document +doc+.
+      def initialize(root, options)
+        super
+        @footnote_counter = @footnote_start = @options[:footnote_nr]
+        @footnotes = []
+        @footnotes_by_name = {}
+        @footnote_location = nil
+        @toc = []
+        @toc_code = nil
+        @indent = 2
+        @stack = []
+        @coderay_enabled = @options[:enable_coderay] && HIGHLIGHTING_AVAILABLE
+      end
+
+      # The mapping of element type to conversion method.
+      DISPATCHER = Hash.new {|h,k| h[k] = "convert_#{k}"}
+
+      # Dispatch the conversion of the element +el+ to a +convert_TYPE+ method using the +type+ of
+      # the element.
+      def convert(el, indent = - at indent)
+        send(DISPATCHER[el.type], el, indent)
+      end
+
+      # Return the converted content of the children of +el+ as a string. The parameter +indent+ has
+      # to be the amount of indentation used for the element +el+.
+      #
+      # Pushes +el+ onto the @stack before converting the child elements and pops it from the stack
+      # afterwards.
+      def inner(el, indent)
+        result = ''
+        indent += @indent
+        @stack.push(el)
+        el.children.each do |inner_el|
+          result << send(DISPATCHER[inner_el.type], inner_el, indent)
+        end
+        @stack.pop
+        result
+      end
+
+      def convert_blank(el, indent)
+        "\n"
+      end
+
+      def convert_text(el, indent)
+        escape_html(el.value, :text)
+      end
+
+      def convert_p(el, indent)
+        if el.options[:transparent]
+          inner(el, indent)
+        else
+          format_as_block_html(el.type, el.attr, inner(el, indent), indent)
+        end
+      end
+
+      def convert_codeblock(el, indent)
+        attr = el.attr.dup
+        lang = extract_code_language!(attr)
+        if @coderay_enabled && (lang || @options[:coderay_default_lang])
+          opts = {:wrap => @options[:coderay_wrap], :line_numbers => @options[:coderay_line_numbers],
+            :line_number_start => @options[:coderay_line_number_start], :tab_width => @options[:coderay_tab_width],
+            :bold_every => @options[:coderay_bold_every], :css => @options[:coderay_css]}
+          lang = (lang || @options[:coderay_default_lang]).to_sym
+          result = CodeRay.scan(el.value, lang).html(opts).chomp << "\n"
+          "#{' '*indent}<div#{html_attributes(attr)}>#{result}#{' '*indent}</div>\n"
+        else
+          result = escape_html(el.value)
+          result.chomp!
+          if el.attr['class'].to_s =~ /\bshow-whitespaces\b/
+            result.gsub!(/(?:(^[ \t]+)|([ \t]+$)|([ \t]+))/) do |m|
+              suffix = ($1 ? '-l' : ($2 ? '-r' : ''))
+              m.scan(/./).map do |c|
+                case c
+                when "\t" then "<span class=\"ws-tab#{suffix}\">\t</span>"
+                when " " then "<span class=\"ws-space#{suffix}\">⋅</span>"
+                end
+              end.join('')
+            end
+          end
+          code_attr = {}
+          code_attr['class'] = "language-#{lang}" if lang
+          "#{' '*indent}<pre#{html_attributes(attr)}><code#{html_attributes(code_attr)}>#{result}\n</code></pre>\n"
+        end
+      end
+
+      def convert_blockquote(el, indent)
+        format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent)
+      end
+
+      def convert_header(el, indent)
+        attr = el.attr.dup
+        if @options[:auto_ids] && !attr['id']
+          attr['id'] = generate_id(el.options[:raw_text])
+        end
+        @toc << [el.options[:level], attr['id'], el.children] if attr['id'] && in_toc?(el)
+        level = output_header_level(el.options[:level])
+        format_as_block_html("h#{level}", attr, inner(el, indent), indent)
+      end
+
+      def convert_hr(el, indent)
+        "#{' '*indent}<hr#{html_attributes(el.attr)} />\n"
+      end
+
+      def convert_ul(el, indent)
+        if !@toc_code && (el.options[:ial][:refs].include?('toc') rescue nil)
+          @toc_code = [el.type, el.attr, (0..128).to_a.map{|a| rand(36).to_s(36)}.join]
+          @toc_code.last
+        elsif !@footnote_location && el.options[:ial] && (el.options[:ial][:refs] || []).include?('footnotes')
+          @footnote_location = (0..128).to_a.map{|a| rand(36).to_s(36)}.join
+        else
+          format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent)
+        end
+      end
+      alias :convert_ol :convert_ul
+
+      def convert_dl(el, indent)
+        format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent)
+      end
+
+      def convert_li(el, indent)
+        output = ' '*indent << "<#{el.type}" << html_attributes(el.attr) << ">"
+        res = inner(el, indent)
+        if el.children.empty? || (el.children.first.type == :p && el.children.first.options[:transparent])
+          output << res << (res =~ /\n\Z/ ? ' '*indent : '')
+        else
+          output << "\n" << res << ' '*indent
+        end
+        output << "</#{el.type}>\n"
+      end
+      alias :convert_dd :convert_li
+
+      def convert_dt(el, indent)
+        format_as_block_html(el.type, el.attr, inner(el, indent), indent)
+      end
+
+      def convert_html_element(el, indent)
+        res = inner(el, indent)
+        if el.options[:category] == :span
+          "<#{el.value}#{html_attributes(el.attr)}" << (res.empty? && HTML_ELEMENTS_WITHOUT_BODY.include?(el.value) ? " />" : ">#{res}</#{el.value}>")
+        else
+          output = ''
+          output << ' '*indent if @stack.last.type != :html_element || @stack.last.options[:content_model] != :raw
+          output << "<#{el.value}#{html_attributes(el.attr)}"
+          if el.options[:is_closed] && el.options[:content_model] == :raw
+            output << " />"
+          elsif !res.empty? && el.options[:content_model] != :block
+            output << ">#{res}</#{el.value}>"
+          elsif !res.empty?
+            output << ">\n#{res.chomp}\n"  << ' '*indent << "</#{el.value}>"
+          elsif HTML_ELEMENTS_WITHOUT_BODY.include?(el.value)
+            output << " />"
+          else
+            output << "></#{el.value}>"
+          end
+          output << "\n" if @stack.last.type != :html_element || @stack.last.options[:content_model] != :raw
+          output
+        end
+      end
+
+      def convert_xml_comment(el, indent)
+        if el.options[:category] == :block && (@stack.last.type != :html_element || @stack.last.options[:content_model] != :raw)
+          ' '*indent << el.value << "\n"
+        else
+          el.value
+        end
+      end
+      alias :convert_xml_pi :convert_xml_comment
+
+      def convert_table(el, indent)
+        format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent)
+      end
+      alias :convert_thead :convert_table
+      alias :convert_tbody :convert_table
+      alias :convert_tfoot :convert_table
+      alias :convert_tr  :convert_table
+
+      ENTITY_NBSP = ::Kramdown::Utils::Entities.entity('nbsp') # :nodoc:
+
+      def convert_td(el, indent)
+        res = inner(el, indent)
+        type = (@stack[-2].type == :thead ? :th : :td)
+        attr = el.attr
+        alignment = @stack[-3].options[:alignment][@stack.last.children.index(el)]
+        if alignment != :default
+          attr = el.attr.dup
+          attr['style'] = (attr.has_key?('style') ? "#{attr['style']}; ": '') << "text-align: #{alignment}"
+        end
+        format_as_block_html(type, attr, res.empty? ? entity_to_str(ENTITY_NBSP) : res, indent)
+      end
+
+      def convert_comment(el, indent)
+        if el.options[:category] == :block
+          "#{' '*indent}<!-- #{el.value} -->\n"
+        else
+          "<!-- #{el.value} -->"
+        end
+      end
+
+      def convert_br(el, indent)
+        "<br />"
+      end
+
+      def convert_a(el, indent)
+        res = inner(el, indent)
+        attr = el.attr.dup
+        if attr['href'].start_with?('mailto:')
+          mail_addr = attr['href'][7..-1]
+          attr['href'] = obfuscate('mailto') << ":" << obfuscate(mail_addr)
+          res = obfuscate(res) if res == mail_addr
+        end
+        format_as_span_html(el.type, attr, res)
+      end
+
+      def convert_img(el, indent)
+        "<img#{html_attributes(el.attr)} />"
+      end
+
+      def convert_codespan(el, indent)
+        lang = extract_code_language(el.attr)
+        result = if @coderay_enabled && lang
+                   CodeRay.scan(el.value, lang.to_sym).html(:wrap => :span, :css => @options[:coderay_css]).chomp
+                 else
+                   escape_html(el.value)
+                 end
+        format_as_span_html('code', el.attr, result)
+      end
+
+      def convert_footnote(el, indent)
+        repeat = ''
+        if (footnote = @footnotes_by_name[el.options[:name]])
+          number = footnote[2]
+          repeat = ":#{footnote[3] += 1}"
+        else
+          number = @footnote_counter
+          @footnote_counter += 1
+          @footnotes << [el.options[:name], el.value, number, 0]
+          @footnotes_by_name[el.options[:name]] = @footnotes.last
+        end
+        "<sup id=\"fnref:#{el.options[:name]}#{repeat}\"><a href=\"#fn:#{el.options[:name]}\" class=\"footnote\">#{number}</a></sup>"
+      end
+
+      def convert_raw(el, indent)
+        if !el.options[:type] || el.options[:type].empty? || el.options[:type].include?('html')
+          el.value + (el.options[:category] == :block ? "\n" : '')
+        else
+          ''
+        end
+      end
+
+      def convert_em(el, indent)
+        format_as_span_html(el.type, el.attr, inner(el, indent))
+      end
+      alias :convert_strong :convert_em
+
+      def convert_entity(el, indent)
+        entity_to_str(el.value, el.options[:original])
+      end
+
+      TYPOGRAPHIC_SYMS = {
+        :mdash => [::Kramdown::Utils::Entities.entity('mdash')],
+        :ndash => [::Kramdown::Utils::Entities.entity('ndash')],
+        :hellip => [::Kramdown::Utils::Entities.entity('hellip')],
+        :laquo_space => [::Kramdown::Utils::Entities.entity('laquo'), ::Kramdown::Utils::Entities.entity('nbsp')],
+        :raquo_space => [::Kramdown::Utils::Entities.entity('nbsp'), ::Kramdown::Utils::Entities.entity('raquo')],
+        :laquo => [::Kramdown::Utils::Entities.entity('laquo')],
+        :raquo => [::Kramdown::Utils::Entities.entity('raquo')]
+      } # :nodoc:
+      def convert_typographic_sym(el, indent)
+        TYPOGRAPHIC_SYMS[el.value].map {|e| entity_to_str(e)}.join('')
+      end
+
+      def convert_smart_quote(el, indent)
+        entity_to_str(smart_quote_entity(el))
+      end
+
+      def convert_math(el, indent)
+        block = (el.options[:category] == :block)
+        value = (el.value =~ /<|&/ ? "% <![CDATA[\n#{el.value} %]]>" : el.value)
+        value.gsub!(/<\/?script>?/, '')
+        type = {:type => "math/tex#{block ? '; mode=display' : ''}"}
+        if block
+          format_as_block_html('script', type, value, indent)
+        else
+          format_as_span_html('script', type, value)
+        end
+      end
+
+      def convert_abbreviation(el, indent)
+        title = @root.options[:abbrev_defs][el.value]
+        format_as_span_html("abbr", {:title => (title.empty? ? nil : title)}, el.value)
+      end
+
+      def convert_root(el, indent)
+        result = inner(el, indent)
+        if @footnote_location
+          result.sub!(/#{@footnote_location}/, footnote_content)
+        else
+          result << footnote_content
+        end
+        if @toc_code
+          toc_tree = generate_toc_tree(@toc, @toc_code[0], @toc_code[1] || {})
+          text = if toc_tree.children.size > 0
+                   convert(toc_tree, 0)
+                 else
+                   ''
+                 end
+          result.sub!(/#{@toc_code.last}/, text)
+        end
+        result
+      end
+
+      # Format the given element as span HTML.
+      def format_as_span_html(name, attr, body)
+        "<#{name}#{html_attributes(attr)}>#{body}</#{name}>"
+      end
+
+      # Format the given element as block HTML.
+      def format_as_block_html(name, attr, body, indent)
+        "#{' '*indent}<#{name}#{html_attributes(attr)}>#{body}</#{name}>\n"
+      end
+
+      # Format the given element as block HTML with a newline after the start tag and indentation
+      # before the end tag.
+      def format_as_indented_block_html(name, attr, body, indent)
+        "#{' '*indent}<#{name}#{html_attributes(attr)}>\n#{body}#{' '*indent}</#{name}>\n"
+      end
+
+      # Generate and return an element tree for the table of contents.
+      def generate_toc_tree(toc, type, attr)
+        sections = Element.new(type, nil, attr)
+        sections.attr['id'] ||= 'markdown-toc'
+        stack = []
+        toc.each do |level, id, children|
+          li = Element.new(:li, nil, nil, {:level => level})
+          li.children << Element.new(:p, nil, nil, {:transparent => true})
+          a = Element.new(:a, nil, {'href' => "##{id}"})
+          a.children.concat(remove_footnotes(Marshal.load(Marshal.dump(children))))
+          li.children.last.children << a
+          li.children << Element.new(type)
+
+          success = false
+          while !success
+            if stack.empty?
+              sections.children << li
+              stack << li
+              success = true
+            elsif stack.last.options[:level] < li.options[:level]
+              stack.last.children.last.children << li
+              stack << li
+              success = true
+            else
+              item = stack.pop
+              item.children.pop unless item.children.last.children.size > 0
+            end
+          end
+        end
+        while !stack.empty?
+          item = stack.pop
+          item.children.pop unless item.children.last.children.size > 0
+        end
+        sections
+      end
+
+      # Remove all footnotes from the given elements.
+      def remove_footnotes(elements)
+        elements.delete_if do |c|
+          remove_footnotes(c.children)
+          c.type == :footnote
+        end
+      end
+
+      # Obfuscate the +text+ by using HTML entities.
+      def obfuscate(text)
+        result = ""
+        text.each_byte do |b|
+          result << (b > 128 ? b.chr : "&#%03d;" % b)
+        end
+        result.force_encoding(text.encoding) if result.respond_to?(:force_encoding)
+        result
+      end
+
+      FOOTNOTE_BACKLINK_FMT = "%s<a href=\"#fnref:%s\" class=\"reversefootnote\">%s</a>"
+
+      # Return a HTML ordered list with the footnote content for the used footnotes.
+      def footnote_content
+        ol = Element.new(:ol)
+        ol.attr['start'] = @footnote_start if @footnote_start != 1
+        @footnotes.each do |name, data, _, repeat|
+          li = Element.new(:li, nil, {'id' => "fn:#{name}"})
+          li.children = Marshal.load(Marshal.dump(data.children))
+          ol.children << li
+
+          if li.children.last.type == :p
+            para = li.children.last
+            insert_space = true
+          else
+            li.children << (para = Element.new(:p))
+            insert_space = false
+          end
+
+          para.children << Element.new(:raw, FOOTNOTE_BACKLINK_FMT % [insert_space ? ' ' : '', name, "↩"])
+          (1..repeat).each do |index|
+            para.children << Element.new(:raw, FOOTNOTE_BACKLINK_FMT % [" ", "#{name}:#{index}", "↩<sup>#{index+1}</sup>"])
+          end
+        end
+        (ol.children.empty? ? '' : format_as_indented_block_html('div', {:class => "footnotes"}, convert(ol, 2), 0))
+      end
+
+    end
+
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/converter/kramdown.rb b/app/server/vendor/kramdown/lib/kramdown/converter/kramdown.rb
new file mode 100644
index 0000000..871fa1a
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/converter/kramdown.rb
@@ -0,0 +1,422 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'rexml/parsers/baseparser'
+
+module Kramdown
+
+  module Converter
+
+    # Converts an element tree to the kramdown format.
+    class Kramdown < Base
+
+      # :stopdoc:
+
+      include ::Kramdown::Utils::Html
+
+      def initialize(root, options)
+        super
+        @linkrefs = []
+        @footnotes = []
+        @abbrevs = []
+        @stack = []
+      end
+
+      def convert(el, opts = {:indent => 0})
+        res = send("convert_#{el.type}", el, opts)
+        if ![:html_element, :li, :dd, :td].include?(el.type) && (ial = ial_for_element(el))
+          res << ial
+          res << "\n\n" if Element.category(el) == :block
+        elsif [:ul, :dl, :ol, :codeblock].include?(el.type) && opts[:next] &&
+            ([el.type, :codeblock].include?(opts[:next].type) ||
+             (opts[:next].type == :blank && opts[:nnext] && [el.type, :codeblock].include?(opts[:nnext].type)))
+          res << "^\n\n"
+        elsif Element.category(el) == :block &&
+            ![:li, :dd, :dt, :td, :th, :tr, :thead, :tbody, :tfoot, :blank].include?(el.type) &&
+            (el.type != :html_element || @stack.last.type != :html_element) &&
+            (el.type != :p || !el.options[:transparent])
+          res << "\n"
+        end
+        res
+      end
+
+      def inner(el, opts = {:indent => 0})
+        @stack.push(el)
+        result = ''
+        el.children.each_with_index do |inner_el, index|
+          options = opts.dup
+          options[:index] = index
+          options[:prev] = (index == 0 ? nil : el.children[index-1])
+          options[:pprev] = (index <= 1 ? nil : el.children[index-2])
+          options[:next] = (index == el.children.length - 1 ? nil : el.children[index+1])
+          options[:nnext] = (index >= el.children.length - 2 ? nil : el.children[index+2])
+          result << convert(inner_el, options)
+        end
+        @stack.pop
+        result
+      end
+
+      def convert_blank(el, opts)
+        ""
+      end
+
+      ESCAPED_CHAR_RE = /(\$\$|[\\*_`\[\]\{"'|])|^[ ]{0,3}(:)/
+
+      def convert_text(el, opts)
+        if opts[:raw_text]
+          el.value
+        else
+          el.value.gsub(/\A\n/) do
+            opts[:prev] && opts[:prev].type == :br ? '' : "\n"
+          end.gsub(/\s+/, ' ').gsub(ESCAPED_CHAR_RE) { "\\#{$1 || $2}" }
+        end
+      end
+
+      def convert_p(el, opts)
+        w = @options[:line_width] - opts[:indent].to_s.to_i
+        first, second, *rest = inner(el, opts).strip.gsub(/(.{1,#{w}})( +|$\n?)/, "\\1\n").split(/\n/)
+        first.gsub!(/^(?:(#|>)|(\d+)\.|([+-]\s))/) { $1 || $3 ? "\\#{$1 || $3}" : "#{$2}\\."} if first
+        second.gsub!(/^([=-]+\s*?)$/, "\\\1") if second
+        res = [first, second, *rest].compact.join("\n") + "\n"
+        if el.children.length == 1 && el.children.first.type == :math
+          res = "\\#{res}"
+        elsif res.start_with?('\$$') && res.end_with?("\\$$\n")
+          res.sub!(/^\\\$\$/, '\$\$')
+        end
+        res
+      end
+
+
+      def convert_codeblock(el, opts)
+        el.value.split(/\n/).map {|l| l.empty? ? "    " : "    #{l}"}.join("\n") + "\n"
+      end
+
+      def convert_blockquote(el, opts)
+        opts[:indent] += 2
+        inner(el, opts).chomp.split(/\n/).map {|l| "> #{l}"}.join("\n") << "\n"
+      end
+
+      def convert_header(el, opts)
+        res = ''
+        res << "#{'#' * output_header_level(el.options[:level])} #{inner(el, opts)}"
+        res << "   {##{el.attr['id']}}" if el.attr['id'] && !el.attr['id'].strip.empty?
+        res << "\n"
+      end
+
+      def convert_hr(el, opts)
+        "* * *\n"
+      end
+
+      def convert_ul(el, opts)
+        inner(el, opts).sub(/\n+\Z/, "\n")
+      end
+      alias :convert_ol :convert_ul
+      alias :convert_dl :convert_ul
+
+      def convert_li(el, opts)
+        sym, width = if @stack.last.type == :ul
+                       ['* ', el.children.first && el.children.first.type == :codeblock ? 4 : 2]
+                     else
+                       ["#{opts[:index] + 1}.".ljust(4), 4]
+                     end
+        if ial = ial_for_element(el)
+          sym << ial << " "
+        end
+
+        opts[:indent] += width
+        text = inner(el, opts)
+        newlines = text.scan(/\n*\Z/).first
+        first, *last = text.split(/\n/)
+        last = last.map {|l| " "*width + l}.join("\n")
+        text = (first.nil? ? "\n" : first + (last.empty? ? "" : "\n") + last + newlines)
+        if el.children.first && el.children.first.type == :p && !el.children.first.options[:transparent]
+          res = "#{sym}#{text}"
+          res << "^\n" if el.children.size == 1 && @stack.last.children.last == el &&
+            (@stack.last.children.any? {|c| c.children.first.type != :p} || @stack.last.children.size == 1)
+          res
+        elsif el.children.first && el.children.first.type == :codeblock
+          "#{sym}\n    #{text}"
+        else
+          "#{sym}#{text}"
+        end
+      end
+
+      def convert_dd(el, opts)
+        sym, width = ": ", (el.children.first && el.children.first.type == :codeblock ? 4 : 2)
+        if ial = ial_for_element(el)
+          sym << ial << " "
+        end
+
+        opts[:indent] += width
+        text = inner(el, opts)
+        newlines = text.scan(/\n*\Z/).first
+        first, *last = text.split(/\n/)
+        last = last.map {|l| " "*width + l}.join("\n")
+        text = first.to_s + (last.empty? ? "" : "\n") + last + newlines
+        text.chomp! if text =~ /\n\n\Z/ && opts[:next] && opts[:next].type == :dd
+        text << "\n" if (text !~ /\n\n\Z/ && opts[:next] && opts[:next].type == :dt)
+        text << "\n" if el.children.empty?
+        if el.children.first && el.children.first.type == :p && !el.children.first.options[:transparent]
+          "\n#{sym}#{text}"
+        elsif el.children.first && el.children.first.type == :codeblock
+          "#{sym}\n    #{text}"
+        else
+          "#{sym}#{text}"
+        end
+      end
+
+      def convert_dt(el, opts)
+        inner(el, opts) << "\n"
+      end
+
+      HTML_TAGS_WITH_BODY=['div', 'script', 'iframe', 'textarea']
+
+      def convert_html_element(el, opts)
+        markdown_attr = el.options[:category] == :block && el.children.any? do |c|
+          c.type != :html_element && (c.type != :p || !c.options[:transparent]) && Element.category(c) == :block
+        end
+        opts[:force_raw_text] = true if %w{script pre code}.include?(el.value)
+        opts[:raw_text] = opts[:force_raw_text] || opts[:block_raw_text] || (el.options[:category] != :span && !markdown_attr)
+        opts[:block_raw_text] = true if el.options[:category] == :block && opts[:raw_text]
+        res = inner(el, opts)
+        if el.options[:category] == :span
+          "<#{el.value}#{html_attributes(el.attr)}" << (!res.empty? || HTML_TAGS_WITH_BODY.include?(el.value) ? ">#{res}</#{el.value}>" : " />")
+        else
+          output = ''
+          attr = el.attr.dup
+          attr['markdown'] = '1' if markdown_attr
+          output << "<#{el.value}#{html_attributes(attr)}"
+          if !res.empty? && el.options[:content_model] != :block
+            output << ">#{res}</#{el.value}>"
+          elsif !res.empty?
+            output << ">\n#{res}"  <<  "</#{el.value}>"
+          elsif HTML_TAGS_WITH_BODY.include?(el.value)
+            output << "></#{el.value}>"
+          else
+            output << " />"
+          end
+          output << "\n" if @stack.last.type != :html_element || @stack.last.options[:content_model] != :raw
+          output
+        end
+      end
+
+      def convert_xml_comment(el, opts)
+        if el.options[:category] == :block && (@stack.last.type != :html_element || @stack.last.options[:content_model] != :raw)
+          el.value + "\n"
+        else
+          el.value.dup
+        end
+      end
+      alias :convert_xml_pi :convert_xml_comment
+
+      def convert_table(el, opts)
+        opts[:alignment] = el.options[:alignment]
+        inner(el, opts)
+      end
+
+      def convert_thead(el, opts)
+        rows = inner(el, opts)
+        if opts[:alignment].all? {|a| a == :default}
+          "#{rows}|" << "-"*10 << "\n"
+        else
+          "#{rows}| " << opts[:alignment].map do |a|
+            case a
+            when :left then ":-"
+            when :right then "-:"
+            when :center then ":-:"
+            when :default then "-"
+            end
+          end.join(' ') << "\n"
+        end
+      end
+
+      def convert_tbody(el, opts)
+        res = ''
+        res << inner(el, opts)
+        res << '|' << '-'*10 << "\n" if opts[:next] && opts[:next].type == :tbody
+        res
+      end
+
+      def convert_tfoot(el, opts)
+        "|" << "="*10 << "\n#{inner(el, opts)}"
+      end
+
+      def convert_tr(el, opts)
+        "| " << el.children.map {|c| convert(c, opts)}.join(" | ") << " |\n"
+      end
+
+      def convert_td(el, opts)
+        inner(el, opts)
+      end
+
+      def convert_comment(el, opts)
+        if el.options[:category] == :block
+          "{::comment}\n#{el.value}\n{:/}\n"
+        else
+          "{::comment}#{el.value}{:/}"
+        end
+      end
+
+      def convert_br(el, opts)
+        "  \n"
+      end
+
+      def convert_a(el, opts)
+        if el.attr['href'].empty?
+          "[#{inner(el, opts)}]()"
+        elsif el.attr['href'] =~ /^(?:http|ftp)/ || el.attr['href'].count("()") > 0
+          index = if link_el = @linkrefs.find {|c| c.attr['href'] == el.attr['href']}
+                    @linkrefs.index(link_el) + 1
+                  else
+                    @linkrefs << el
+                    @linkrefs.size
+                  end
+          "[#{inner(el, opts)}][#{index}]"
+        else
+          title = el.attr['title'].to_s.empty? ? '' : ' "' + el.attr['title'].gsub(/"/, """) + '"'
+          "[#{inner(el, opts)}](#{el.attr['href']}#{title})"
+        end
+      end
+
+      def convert_img(el, opts)
+        alt_text = el.attr['alt'].gsub(ESCAPED_CHAR_RE) { $1 ? "\\#{$1}" : $2 }
+        if el.attr['src'].empty?
+          "![#{alt_text}]()"
+        else
+          title = (el.attr['title'] ? ' "' + el.attr['title'].gsub(/"/, """) + '"' : '')
+          link = if el.attr['src'].count("()") > 0
+                   "<#{el.attr['src']}>"
+                 else
+                   el.attr['src']
+                 end
+          "![#{alt_text}](#{link}#{title})"
+        end
+      end
+
+      def convert_codespan(el, opts)
+        delim = (el.value.scan(/`+/).max || '') + '`'
+        "#{delim}#{' ' if delim.size > 1}#{el.value}#{' ' if delim.size > 1}#{delim}"
+      end
+
+      def convert_footnote(el, opts)
+        @footnotes << [el.options[:name], el.value]
+        "[^#{el.options[:name]}]"
+      end
+
+      def convert_raw(el, opts)
+        attr = (el.options[:type] || []).join(' ')
+        attr = " type=\"#{attr}\"" if attr.length > 0
+        if @stack.last.type == :html_element
+          el.value
+        elsif el.options[:category] == :block
+          "{::nomarkdown#{attr}}\n#{el.value}\n{:/}\n"
+        else
+          "{::nomarkdown#{attr}}#{el.value}{:/}"
+        end
+      end
+
+      def convert_em(el, opts)
+        "*#{inner(el, opts)}*" +
+          (opts[:next] && [:em, :strong].include?(opts[:next].type) && !ial_for_element(el) ? '{::}' : '')
+      end
+
+      def convert_strong(el, opts)
+        "**#{inner(el, opts)}**" +
+          (opts[:next] && [:em, :strong].include?(opts[:next].type) && !ial_for_element(el) ? '{::}' : '')
+      end
+
+      def convert_entity(el, opts)
+        entity_to_str(el.value, el.options[:original])
+      end
+
+      TYPOGRAPHIC_SYMS = {
+        :mdash => '---', :ndash => '--', :hellip => '...',
+        :laquo_space => '<< ', :raquo_space => ' >>',
+        :laquo => '<<', :raquo => '>>'
+      }
+      def convert_typographic_sym(el, opts)
+        TYPOGRAPHIC_SYMS[el.value]
+      end
+
+      def convert_smart_quote(el, opts)
+        el.value.to_s =~ /[rl]dquo/ ? "\"" : "'"
+      end
+
+      def convert_math(el, opts)
+        "$$#{el.value}$$" + (el.options[:category] == :block ? "\n" : '')
+      end
+
+      def convert_abbreviation(el, opts)
+        el.value
+      end
+
+      def convert_root(el, opts)
+        res = inner(el, opts)
+        res << create_link_defs
+        res << create_footnote_defs
+        res << create_abbrev_defs
+        res
+      end
+
+      def create_link_defs
+        res = ''
+        res << "\n\n" if @linkrefs.size > 0
+        @linkrefs.each_with_index do |el, i|
+          title = el.attr['title']
+          res << "[#{i+1}]: #{el.attr['href']}#{title ? ' "' + title.gsub(/"/, """) + '"' : ''}\n"
+        end
+        res
+      end
+
+      def create_footnote_defs
+        res = ''
+        @footnotes.each do |name, data|
+          res << "[^#{name}]:\n"
+          res << inner(data).chomp.split(/\n/).map {|l| "    #{l}"}.join("\n") + "\n\n"
+        end
+        res
+      end
+
+      def create_abbrev_defs
+        return '' unless @root.options[:abbrev_defs]
+        res = ''
+        @root.options[:abbrev_defs].each do |name, text|
+          res << "*[#{name}]: #{text}\n"
+        end
+        res
+      end
+
+      # Return the IAL containing the attributes of the element +el+.
+      def ial_for_element(el)
+        res = el.attr.map do |k,v|
+          next if [:img, :a].include?(el.type) && ['href', 'src', 'alt', 'title'].include?(k)
+          next if el.type == :header && k == 'id' && !v.strip.empty?
+          if v.nil?
+            ''
+          elsif k == 'class' && !v.empty?
+            " " + v.split(/\s+/).map {|w| ".#{w}"}.join(" ")
+          elsif k == 'id' && !v.strip.empty?
+            " ##{v}"
+          else
+            " #{k}=\"#{v.to_s}\""
+          end
+        end.compact.join('')
+        res = "toc" << (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) &&
+          (el.options[:ial][:refs].include?('toc') rescue nil)
+        res = "footnotes" << (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) &&
+          (el.options[:ial][:refs].include?('footnotes') rescue nil)
+        res.strip.empty? ? nil : "{:#{res}}"
+      end
+
+      # :startdoc:
+
+    end
+
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/converter/latex.rb b/app/server/vendor/kramdown/lib/kramdown/converter/latex.rb
new file mode 100644
index 0000000..00e7ae2
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/converter/latex.rb
@@ -0,0 +1,601 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'set'
+
+module Kramdown
+
+  module Converter
+
+    # Converts an element tree to LaTeX.
+    #
+    # This converter uses ideas from other Markdown-to-LaTeX converters like Pandoc and Maruku.
+    #
+    # You can customize this converter by sub-classing it and overriding the +convert_NAME+ methods.
+    # Each such method takes the following parameters:
+    #
+    # [+el+] The element of type +NAME+ to be converted.
+    #
+    # [+opts+] A hash containing processing options that are passed down from parent elements. The
+    #          key :parent is always set and contains the parent element as value.
+    #
+    # The return value of such a method has to be a string containing the element +el+ formatted
+    # correctly as LaTeX markup.
+    class Latex < Base
+
+      # Initialize the LaTeX converter with the +root+ element and the conversion +options+.
+      def initialize(root, options)
+        super
+        #TODO: set the footnote counter at the beginning of the document
+        @options[:footnote_nr]
+        @data[:packages] = Set.new
+      end
+
+      # Dispatch the conversion of the element +el+ to a +convert_TYPE+ method using the +type+ of
+      # the element.
+      def convert(el, opts = {})
+        send("convert_#{el.type}", el, opts)
+      end
+
+      # Return the converted content of the children of +el+ as a string.
+      def inner(el, opts)
+        result = ''
+        options = opts.dup.merge(:parent => el)
+        el.children.each_with_index do |inner_el, index|
+          options[:index] = index
+          options[:result] = result
+          result << send("convert_#{inner_el.type}", inner_el, options)
+        end
+        result
+      end
+
+      def convert_root(el, opts)
+        inner(el, opts)
+      end
+
+      def convert_blank(el, opts)
+        opts[:result] =~ /\n\n\Z|\A\Z/ ? "" : "\n"
+      end
+
+      def convert_text(el, opts)
+        escape(el.value)
+      end
+
+      def convert_p(el, opts)
+        if el.children.size == 1 && el.children.first.type == :img && !(img = convert_img(el.children.first, opts)).empty?
+          convert_standalone_image(el, opts, img)
+        else
+          "#{latex_link_target(el)}#{inner(el, opts)}\n\n"
+        end
+      end
+
+      # Helper method used by +convert_p+ to convert a paragraph that only contains a single :img
+      # element.
+      def convert_standalone_image(el, opts, img)
+        attrs = attribute_list(el)
+        "\\begin{figure}#{attrs}\n\\begin{center}\n#{img}\n\\end{center}\n\\caption{#{escape(el.children.first.attr['alt'])}}\n#{latex_link_target(el, true)}\n\\end{figure}#{attrs}\n"
+      end
+
+      def convert_codeblock(el, opts)
+        show_whitespace = el.attr['class'].to_s =~ /\bshow-whitespaces\b/
+        lang = extract_code_language(el.attr)
+        if show_whitespace || lang
+          options = []
+          options << "showspaces=%s,showtabs=%s" % (show_whitespace ? ['true', 'true'] : ['false', 'false'])
+          options << "language=#{lang}" if lang
+          options << "basicstyle=\\ttfamily\\footnotesize,columns=fixed,frame=tlbr"
+          id = el.attr['id']
+          options << "label=#{id}" if id
+          attrs = attribute_list(el)
+          "#{latex_link_target(el)}\\begin{lstlisting}[#{options.join(',')}]\n#{el.value}\n\\end{lstlisting}#{attrs}\n"
+        else
+          "#{latex_link_target(el)}\\begin{verbatim}#{el.value}\\end{verbatim}\n"
+        end
+      end
+
+      def convert_blockquote(el, opts)
+        latex_environment(el.children.size > 1 ? 'quotation' : 'quote', el, inner(el, opts))
+      end
+
+      def convert_header(el, opts)
+        type = @options[:latex_headers][output_header_level(el.options[:level]) - 1]
+        if ((id = el.attr['id']) ||
+            (@options[:auto_ids] && (id = generate_id(el.options[:raw_text])))) && in_toc?(el)
+          "\\#{type}{#{inner(el, opts)}}\\hypertarget{#{id}}{}\\label{#{id}}\n\n"
+        else
+          "\\#{type}*{#{inner(el, opts)}}\n\n"
+        end
+      end
+
+      def convert_hr(el, opts)
+        attrs = attribute_list(el)
+        "#{latex_link_target(el)}\\begin{center}#{attrs}\n\\rule{3in}{0.4pt}\n\\end{center}#{attrs}\n"
+      end
+
+      def convert_ul(el, opts)
+        if !@data[:has_toc] && (el.options[:ial][:refs].include?('toc') rescue nil)
+          @data[:has_toc] = true
+          '\tableofcontents'
+        else
+          latex_environment(el.type == :ul ? 'itemize' : 'enumerate', el, inner(el, opts))
+        end
+      end
+      alias :convert_ol :convert_ul
+
+      def convert_dl(el, opts)
+        latex_environment('description', el, inner(el, opts))
+      end
+
+      def convert_li(el, opts)
+        "\\item #{latex_link_target(el, true)}#{inner(el, opts).sub(/\n+\Z/, '')}\n"
+      end
+
+      def convert_dt(el, opts)
+        "\\item[#{inner(el, opts)}] "
+      end
+
+      def convert_dd(el, opts)
+        "#{latex_link_target(el)}#{inner(el, opts)}\n\n"
+      end
+
+      def convert_html_element(el, opts)
+        if el.value == 'i' || el.value == 'em'
+          "\\emph{#{inner(el, opts)}}"
+        elsif el.value == 'b' || el.value == 'strong'
+          "\\textbf{#{inner(el, opts)}}"
+        else
+          warning("Can't convert HTML element")
+          ''
+        end
+      end
+
+      def convert_xml_comment(el, opts)
+        el.value.split(/\n/).map {|l| "% #{l}"}.join("\n") + "\n"
+      end
+
+      def convert_xml_pi(el, opts)
+        warning("Can't convert XML PI")
+        ''
+      end
+
+      TABLE_ALIGNMENT_CHAR = {:default => 'l', :left => 'l', :center => 'c', :right => 'r'} # :nodoc:
+
+      def convert_table(el, opts)
+        @data[:packages] << 'longtable'
+        align = el.options[:alignment].map {|a| TABLE_ALIGNMENT_CHAR[a]}.join('|')
+        attrs = attribute_list(el)
+        "#{latex_link_target(el)}\\begin{longtable}{|#{align}|}#{attrs}\n\\hline\n#{inner(el, opts)}\\hline\n\\end{longtable}#{attrs}\n\n"
+      end
+
+      def convert_thead(el, opts)
+        "#{inner(el, opts)}\\hline\n"
+      end
+
+      def convert_tbody(el, opts)
+        inner(el, opts)
+      end
+
+      def convert_tfoot(el, opts)
+        "\\hline \\hline \n#{inner(el, opts)}"
+      end
+
+      def convert_tr(el, opts)
+        el.children.map {|c| send("convert_#{c.type}", c, opts)}.join(' & ') << "\\\\\n"
+      end
+
+      def convert_td(el, opts)
+        inner(el, opts)
+      end
+
+      def convert_comment(el, opts)
+        el.value.split(/\n/).map {|l| "% #{l}"}.join("\n") << "\n"
+      end
+
+      def convert_br(el, opts)
+        res = "\\newline"
+        res << "\n" if (c = opts[:parent].children[opts[:index]+1]) && (c.type != :text || c.value !~ /^\s*\n/)
+        res
+      end
+
+      def convert_a(el, opts)
+        url = el.attr['href']
+        if url.start_with?('#')
+          "\\hyperlink{#{escape(url[1..-1])}}{#{inner(el, opts)}}"
+        else
+          "\\href{#{escape(url)}}{#{inner(el, opts)}}"
+        end
+      end
+
+      def convert_img(el, opts)
+        if el.attr['src'] =~ /^(https?|ftps?):\/\//
+          warning("Cannot include non-local image")
+          ''
+        elsif !el.attr['src'].empty?
+          @data[:packages] << 'graphicx'
+          "#{latex_link_target(el)}\\includegraphics{#{el.attr['src']}}"
+        else
+          warning("Cannot include image with empty path")
+          ''
+        end
+      end
+
+      def convert_codespan(el, opts)
+        "{\\tt #{latex_link_target(el)}#{escape(el.value)}}"
+      end
+
+      def convert_footnote(el, opts)
+        @data[:packages] << 'fancyvrb'
+        "\\footnote{#{inner(el.value, opts).rstrip}}"
+      end
+
+      def convert_raw(el, opts)
+        if !el.options[:type] || el.options[:type].empty? || el.options[:type].include?('latex')
+          el.value + (el.options[:category] == :block ? "\n" : '')
+        else
+          ''
+        end
+      end
+
+      def convert_em(el, opts)
+        "\\emph{#{latex_link_target(el)}#{inner(el, opts)}}"
+      end
+
+      def convert_strong(el, opts)
+        "\\textbf{#{latex_link_target(el)}#{inner(el, opts)}}"
+      end
+
+      # Inspired by Maruku: entity conversion table based on the one from htmltolatex
+      # (http://sourceforge.net/projects/htmltolatex/), with some small adjustments/additions
+      ENTITY_CONV_TABLE = {
+        913 => ['$A$'],
+        914 => ['$B$'],
+        915 => ['$\Gamma$'],
+        916 => ['$\Delta$'],
+        917 => ['$E$'],
+        918 => ['$Z$'],
+        919 => ['$H$'],
+        920 => ['$\Theta$'],
+        921 => ['$I$'],
+        922 => ['$K$'],
+        923 => ['$\Lambda$'],
+        924 => ['$M$'],
+        925 => ['$N$'],
+        926 => ['$\Xi$'],
+        927 => ['$O$'],
+        928 => ['$\Pi$'],
+        929 => ['$P$'],
+        931 => ['$\Sigma$'],
+        932 => ['$T$'],
+        933 => ['$Y$'],
+        934 => ['$\Phi$'],
+        935 => ['$X$'],
+        936 => ['$\Psi$'],
+        937 => ['$\Omega$'],
+        945 => ['$\alpha$'],
+        946 => ['$\beta$'],
+        947 => ['$\gamma$'],
+        948 => ['$\delta$'],
+        949 => ['$\epsilon$'],
+        950 => ['$\zeta$'],
+        951 => ['$\eta$'],
+        952 => ['$\theta$'],
+        953 => ['$\iota$'],
+        954 => ['$\kappa$'],
+        955 => ['$\lambda$'],
+        956 => ['$\mu$'],
+        957 => ['$\nu$'],
+        958 => ['$\xi$'],
+        959 => ['$o$'],
+        960 => ['$\pi$'],
+        961 => ['$\rho$'],
+        963 => ['$\sigma$'],
+        964 => ['$\tau$'],
+        965 => ['$\upsilon$'],
+        966 => ['$\phi$'],
+        967 => ['$\chi$'],
+        968 => ['$\psi$'],
+        969 => ['$\omega$'],
+        962 => ['$\varsigma$'],
+        977 => ['$\vartheta$'],
+        982 => ['$\varpi$'],
+        8230 => ['\ldots'],
+        8242 => ['$\prime$'],
+        8254 => ['-'],
+        8260 => ['/'],
+        8472 => ['$\wp$'],
+        8465 => ['$\Im$'],
+        8476 => ['$\Re$'],
+        8501 => ['$\aleph$'],
+        8226 => ['$\bullet$'],
+        8482 => ['$^{\rm TM}$'],
+        8592 => ['$\leftarrow$'],
+        8594 => ['$\rightarrow$'],
+        8593 => ['$\uparrow$'],
+        8595 => ['$\downarrow$'],
+        8596 => ['$\leftrightarrow$'],
+        8629 => ['$\hookleftarrow$'],
+        8657 => ['$\Uparrow$'],
+        8659 => ['$\Downarrow$'],
+        8656 => ['$\Leftarrow$'],
+        8658 => ['$\Rightarrow$'],
+        8660 => ['$\Leftrightarrow$'],
+        8704 => ['$\forall$'],
+        8706 => ['$\partial$'],
+        8707 => ['$\exists$'],
+        8709 => ['$\emptyset$'],
+        8711 => ['$\nabla$'],
+        8712 => ['$\in$'],
+        8715 => ['$\ni$'],
+        8713 => ['$\notin$'],
+        8721 => ['$\sum$'],
+        8719 => ['$\prod$'],
+        8722 => ['$-$'],
+        8727 => ['$\ast$'],
+        8730 => ['$\surd$'],
+        8733 => ['$\propto$'],
+        8734 => ['$\infty$'],
+        8736 => ['$\angle$'],
+        8743 => ['$\wedge$'],
+        8744 => ['$\vee$'],
+        8745 => ['$\cup$'],
+        8746 => ['$\cap$'],
+        8747 => ['$\int$'],
+        8756 => ['$\therefore$', 'amssymb'],
+        8764 => ['$\sim$'],
+        8776 => ['$\approx$'],
+        8773 => ['$\cong$'],
+        8800 => ['$\neq$'],
+        8801 => ['$\equiv$'],
+        8804 => ['$\leq$'],
+        8805 => ['$\geq$'],
+        8834 => ['$\subset$'],
+        8835 => ['$\supset$'],
+        8838 => ['$\subseteq$'],
+        8839 => ['$\supseteq$'],
+        8836 => ['$\nsubset$', 'amssymb'],
+        8853 => ['$\oplus$'],
+        8855 => ['$\otimes$'],
+        8869 => ['$\perp$'],
+        8901 => ['$\cdot$'],
+        8968 => ['$\rceil$'],
+        8969 => ['$\lceil$'],
+        8970 => ['$\lfloor$'],
+        8971 => ['$\rfloor$'],
+        9001 => ['$\rangle$'],
+        9002 => ['$\langle$'],
+        9674 => ['$\lozenge$', 'amssymb'],
+        9824 => ['$\spadesuit$'],
+        9827 => ['$\clubsuit$'],
+        9829 => ['$\heartsuit$'],
+        9830 => ['$\diamondsuit$'],
+        38 => ['\&'],
+        34 => ['"'],
+        39 => ['\''],
+        169 => ['\copyright'],
+        60 => ['\textless'],
+        62 => ['\textgreater'],
+        338 => ['\OE'],
+        339 => ['\oe'],
+        352 => ['\v{S}'],
+        353 => ['\v{s}'],
+        376 => ['\"Y'],
+        710 => ['\textasciicircum'],
+        732 => ['\textasciitilde'],
+        8211 => ['--'],
+        8212 => ['---'],
+        8216 => ['`'],
+        8217 => ['\''],
+        8220 => ['``'],
+        8221 => ['\'\''],
+        8224 => ['\dag'],
+        8225 => ['\ddag'],
+        8240 => ['\permil', 'wasysym'],
+        8364 => ['\euro', 'eurosym'],
+        8249 => ['\guilsinglleft'],
+        8250 => ['\guilsinglright'],
+        8218 => ['\quotesinglbase', 'mathcomp'],
+        8222 => ['\quotedblbase', 'mathcomp'],
+        402 => ['\textflorin', 'mathcomp'],
+        381 => ['\v{Z}'],
+        382 => ['\v{z}'],
+        160 => ['~'],
+        161 => ['\textexclamdown'],
+        163 => ['\pounds'],
+        164 => ['\currency', 'wasysym'],
+        165 => ['\textyen', 'textcomp'],
+        166 => ['\brokenvert', 'wasysym'],
+        167 => ['\S'],
+        171 => ['\guillemotleft'],
+        187 => ['\guillemotright'],
+        174 => ['\textregistered'],
+        170 => ['\textordfeminine'],
+        172 => ['$\neg$'],
+        173 => ['\-'],
+        176 => ['$\degree$', 'mathabx'],
+        177 => ['$\pm$'],
+        180 => ['\''],
+        181 => ['$\mu$'],
+        182 => ['\P'],
+        183 => ['$\cdot$'],
+        186 => ['\textordmasculine'],
+        162 => ['\cent', 'wasysym'],
+        185 => ['$^1$'],
+        178 => ['$^2$'],
+        179 => ['$^3$'],
+        189 => ['$\frac{1}{2}$'],
+        188 => ['$\frac{1}{4}$'],
+        190 => ['$\frac{3}{4}'],
+        192 => ['\`A'],
+        193 => ['\\\'A'],
+        194 => ['\^A'],
+        195 => ['\~A'],
+        196 => ['\"A'],
+        197 => ['\AA'],
+        198 => ['\AE'],
+        199 => ['\cC'],
+        200 => ['\`E'],
+        201 => ['\\\'E'],
+        202 => ['\^E'],
+        203 => ['\"E'],
+        204 => ['\`I'],
+        205 => ['\\\'I'],
+        206 => ['\^I'],
+        207 => ['\"I'],
+        208 => ['$\eth$', 'amssymb'],
+        209 => ['\~N'],
+        210 => ['\`O'],
+        211 => ['\\\'O'],
+        212 => ['\^O'],
+        213 => ['\~O'],
+        214 => ['\"O'],
+        215 => ['$\times$'],
+        216 => ['\O'],
+        217 => ['\`U'],
+        218 => ['\\\'U'],
+        219 => ['\^U'],
+        220 => ['\"U'],
+        221 => ['\\\'Y'],
+        222 => ['\Thorn', 'wasysym'],
+        223 => ['\ss'],
+        224 => ['\`a'],
+        225 => ['\\\'a'],
+        226 => ['\^a'],
+        227 => ['\~a'],
+        228 => ['\"a'],
+        229 => ['\aa'],
+        230 => ['\ae'],
+        231 => ['\cc'],
+        232 => ['\`e'],
+        233 => ['\\\'e'],
+        234 => ['\^e'],
+        235 => ['\"e'],
+        236 => ['\`i'],
+        237 => ['\\\'i'],
+        238 => ['\^i'],
+        239 => ['\"i'],
+        240 => ['$\eth$'],
+        241 => ['\~n'],
+        242 => ['\`o'],
+        243 => ['\\\'o'],
+        244 => ['\^o'],
+        245 => ['\~o'],
+        246 => ['\"o'],
+        247 => ['$\divide$'],
+        248 => ['\o'],
+        249 => ['\`u'],
+        250 => ['\\\'u'],
+        251 => ['\^u'],
+        252 => ['\"u'],
+        253 => ['\\\'y'],
+        254 => ['\thorn', 'wasysym'],
+        255 => ['\"y'],
+        8201 => ['\thinspace'],
+        8194 => ['\hskip .5em\relax'],
+        8195 => ['\quad'],
+      } # :nodoc:
+      ENTITY_CONV_TABLE.each {|k,v| ENTITY_CONV_TABLE[k][0].insert(-1, '{}')}
+
+      def entity_to_latex(entity)
+        text, package = ENTITY_CONV_TABLE[entity.code_point]
+        if text
+          @data[:packages] << package if package
+          text
+        else
+          warning("Couldn't find entity with code #{entity.code_point} in substitution table!")
+          ''
+        end
+      end
+
+      def convert_entity(el, opts)
+        entity_to_latex(el.value)
+      end
+
+      TYPOGRAPHIC_SYMS = {
+        :mdash => '---', :ndash => '--', :hellip => '\ldots{}',
+        :laquo_space => '\guillemotleft{}~', :raquo_space => '~\guillemotright{}',
+        :laquo => '\guillemotleft{}', :raquo => '\guillemotright{}'
+      } # :nodoc:
+      def convert_typographic_sym(el, opts)
+        TYPOGRAPHIC_SYMS[el.value]
+      end
+
+      def convert_smart_quote(el, opts)
+        res = entity_to_latex(smart_quote_entity(el)).chomp('{}')
+        res << "{}" if ((nel = opts[:parent].children[opts[:index]+1]) && nel.type == :smart_quote) || res =~ /\w$/
+        res
+      end
+
+      def convert_math(el, opts)
+        @data[:packages] += %w[amssymb amsmath amsthm amsfonts]
+        if el.options[:category] == :block
+          if el.value =~ /\A\s*\\begin\{/
+            el.value
+          else
+            latex_environment('displaymath', el, el.value)
+          end
+        else
+          "$#{el.value}$"
+        end
+      end
+
+      def convert_abbreviation(el, opts)
+        @data[:packages] += %w[acronym]
+        "\\ac{#{normalize_abbreviation_key(el.value)}}"
+      end
+
+      # Normalize the abbreviation key so that it only contains allowed ASCII character
+      def normalize_abbreviation_key(key)
+        key.gsub(/\W/) {|m| m.unpack('H*').first}
+      end
+
+      # Wrap the +text+ inside a LaTeX environment of type +type+. The element +el+ is passed on to
+      # the method #attribute_list -- the resulting string is appended to both the \\begin and the
+      # \\end lines of the LaTeX environment for easier post-processing of LaTeX environments.
+      def latex_environment(type, el, text)
+        attrs = attribute_list(el)
+        "\\begin{#{type}}#{latex_link_target(el)}#{attrs}\n#{text.rstrip}\n\\end{#{type}}#{attrs}\n"
+      end
+
+      # Return a string containing a valid \hypertarget command if the element has an ID defined, or
+      # +nil+ otherwise. If the parameter +add_label+ is +true+, a \label command will also be used
+      # additionally to the \hypertarget command.
+      def latex_link_target(el, add_label = false)
+        if (id = el.attr['id'])
+          "\\hypertarget{#{id}}{}" << (add_label ? "\\label{#{id}}" : '')
+        else
+          nil
+        end
+      end
+
+      # Return a LaTeX comment containing all attributes as 'key="value"' pairs.
+      def attribute_list(el)
+        attrs = el.attr.map {|k,v| v.nil? ? '' : " #{k}=\"#{v.to_s}\""}.compact.sort.join('')
+        attrs = "   % #{attrs}" if !attrs.empty?
+        attrs
+      end
+
+      ESCAPE_MAP = {
+        "^"  => "\\^{}",
+        "\\" => "\\textbackslash{}",
+        "~"  => "\\ensuremath{\\sim}",
+        "|"  => "\\textbar{}",
+        "<"  => "\\textless{}",
+        ">"  => "\\textgreater{}"
+      }.merge(Hash[*("{}$%&_#".scan(/./).map {|c| [c, "\\#{c}"]}.flatten)]) # :nodoc:
+      ESCAPE_RE = Regexp.union(*ESCAPE_MAP.collect {|k,v| k}) # :nodoc:
+
+      # Escape the special LaTeX characters in the string +str+.
+      def escape(str)
+        str.gsub(ESCAPE_RE) {|m| ESCAPE_MAP[m]}
+      end
+
+    end
+
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/converter/pdf.rb b/app/server/vendor/kramdown/lib/kramdown/converter/pdf.rb
new file mode 100644
index 0000000..808169b
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/converter/pdf.rb
@@ -0,0 +1,619 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'prawn'
+require 'kramdown/utils/entities'
+require 'open-uri'
+
+module Kramdown
+
+  module Converter
+
+    # Converts an element tree to a PDF using the prawn PDF library.
+    #
+    # This basic version provides a nice starting point for customizations but can also be used
+    # directly.
+    #
+    # There can be the following two methods for each element type: render_TYPE(el, opts) and
+    # TYPE_options(el, opts) where +el+ is a kramdown element and +opts+ an hash with rendering
+    # options.
+    #
+    # The render_TYPE(el, opts) is used for rendering the specific element. If the element is a span
+    # element, it should return a hash or an array of hashes that can be used by the #formatted_text
+    # method of Prawn::Document. This method can then be used in block elements to actually render
+    # the span elements.
+    #
+    # The rendering options are passed from the parent to its child elements. This allows one to
+    # define general options at the top of the tree (the root element) that can later be changed or
+    # amended.
+    #
+    #
+    # Currently supports the conversion of all elements except those of the following types:
+    #
+    #   :html_element, :img, :footnote
+    #
+    #
+    class Pdf < Base
+
+      include Prawn::Measurements
+
+      def initialize(root, options)
+        super
+        @stack = []
+        @dests = {}
+      end
+
+      # PDF templates are applied before conversion. They should contain code to augment the
+      # converter object (i.e. to override the methods).
+      def apply_template_before?
+        true
+      end
+
+      # Returns +false+.
+      def apply_template_after?
+        false
+      end
+
+      DISPATCHER_RENDER = Hash.new {|h,k| h[k] = "render_#{k}"} #:nodoc:
+      DISPATCHER_OPTIONS = Hash.new {|h,k| h[k] = "#{k}_options"} #:nodoc:
+
+      # Invoke the special rendering method for the given element +el+.
+      #
+      # A PDF destination is also added at the current location if th element has an ID or if the
+      # element is of type :header and the :auto_ids option is set.
+      def convert(el, opts = {})
+        id = el.attr['id']
+        id = generate_id(el.options[:raw_text]) if !id && @options[:auto_ids] && el.type == :header
+        if !id.to_s.empty? && !@dests.has_key?(id)
+          @pdf.add_dest(id, @pdf.dest_xyz(0, @pdf.y))
+          @dests[id] = @pdf.dest_xyz(0, @pdf.y)
+        end
+        send(DISPATCHER_RENDER[el.type], el, opts)
+      end
+
+      protected
+
+      # Render the children of this element with the given options and return the results as array.
+      #
+      # Each time a child is rendered, the +TYPE_options+ method is invoked (if it exists) to get
+      # the specific options for the element with which the given options are updated.
+      def inner(el, opts)
+        @stack.push([el, opts])
+        result = el.children.map do |inner_el|
+          options = opts.dup
+          options.update(send(DISPATCHER_OPTIONS[inner_el.type], inner_el, options))
+          convert(inner_el, options)
+        end.flatten.compact
+        @stack.pop
+        result
+      end
+
+
+      # ----------------------------
+      # :section: Element rendering methods
+      # ----------------------------
+
+
+      def root_options(root, opts)
+        {:font => 'Times-Roman', :size => 12, :leading => 2}
+      end
+
+      def render_root(root, opts)
+        @pdf = setup_document(root)
+        inner(root, root_options(root, opts))
+        create_outline(root)
+        finish_document(root)
+        @pdf.render
+      end
+
+      def header_options(el, opts)
+        size = opts[:size] * 1.15**(6 - el.options[:level])
+        {
+          :font => "Helvetica", :styles => (opts[:styles] || []) + [:bold],
+          :size => size, :bottom_padding => opts[:size], :top_padding => opts[:size]
+        }
+      end
+
+      def render_header(el, opts)
+        render_padded_and_formatted_text(el, opts)
+      end
+
+      def p_options(el, opts)
+        bpad = (el.options[:transparent] ? opts[:leading] : opts[:size])
+        {:align => :justify, :bottom_padding => bpad}
+      end
+
+      def render_p(el, opts)
+        if el.children.size == 1 && el.children.first.type == :img
+          render_standalone_image(el, opts)
+        else
+          render_padded_and_formatted_text(el, opts)
+        end
+      end
+
+      def render_standalone_image(el, opts)
+        img = el.children.first
+
+        if img.attr['src'].empty?
+          warning("Rendering an image without a source is not possible")
+          return nil
+        elsif img.attr['src'] !~ /\.jpe?g$|\.png$/
+          warning("Cannot render images other than JPEG or PNG, got #{img.attr['src']}")
+          return nil
+        end
+
+        img_dirs = (@options[:image_directories] || ['.']).dup
+        begin
+          img_path = File.join(img_dirs.shift, img.attr['src'])
+          image_obj, image_info = @pdf.build_image_object(open(img_path))
+        rescue
+          img_dirs.empty? ? raise : retry
+        end
+
+        options = {:position => :center}
+        if img.attr['height'] && img.attr['height'] =~ /px$/
+          options[:height] = img.attr['height'].to_i / (@options[:image_dpi] || 150.0) * 72
+        elsif img.attr['width'] && img.attr['width'] =~ /px$/
+          options[:width] = img.attr['width'].to_i / (@options[:image_dpi] || 150.0) * 72
+        else
+          options[:scale] =[(@pdf.bounds.width - mm2pt(20)) / image_info.width.to_f, 1].min
+        end
+
+        if img.attr['class'] =~ /\bright\b/
+          options[:position] = :right
+          @pdf.float { @pdf.embed_image(image_obj, image_info, options) }
+        else
+          with_block_padding(el, opts) do
+            @pdf.embed_image(image_obj, image_info, options)
+          end
+        end
+      end
+
+      def blockquote_options(el, opts)
+        {:styles => [:italic]}
+      end
+
+      def render_blockquote(el, opts)
+        @pdf.indent(mm2pt(10), mm2pt(10)) { inner(el, opts) }
+      end
+
+      def ul_options(el, opts)
+        {:bottom_padding => opts[:size]}
+      end
+
+      def render_ul(el, opts)
+        with_block_padding(el, opts) do
+          el.children.each do |li|
+            @pdf.float { @pdf.formatted_text([text_hash("•", opts)]) }
+            @pdf.indent(mm2pt(6)) { convert(li, opts) }
+          end
+        end
+      end
+
+      def ol_options(el, opts)
+        {:bottom_padding => opts[:size]}
+      end
+
+      def render_ol(el, opts)
+        with_block_padding(el, opts) do
+          el.children.each_with_index do |li, index|
+            @pdf.float { @pdf.formatted_text([text_hash("#{index+1}.", opts)]) }
+            @pdf.indent(mm2pt(6)) { convert(li, opts) }
+          end
+        end
+      end
+
+      def li_options(el, opts)
+        {}
+      end
+
+      def render_li(el, opts)
+        inner(el, opts)
+      end
+
+      def dl_options(el, opts)
+        {}
+      end
+
+      def render_dl(el, opts)
+        inner(el, opts)
+      end
+
+      def dt_options(el, opts)
+        {:styles => (opts[:styles] || []) + [:bold], :bottom_padding => 0}
+      end
+
+      def render_dt(el, opts)
+        render_padded_and_formatted_text(el, opts)
+      end
+
+      def dd_options(el, opts)
+        {}
+      end
+
+      def render_dd(el, opts)
+        @pdf.indent(mm2pt(10)) { inner(el, opts) }
+      end
+
+      def math_options(el, opts)
+        {}
+      end
+
+      def render_math(el, opts)
+        if el.options[:category] == :block
+          @pdf.formatted_text([{:text => el.value}], block_hash(opts))
+        else
+          {:text => el.value}
+        end
+      end
+
+      def hr_options(el, opts)
+        {:top_padding => opts[:size], :bottom_padding => opts[:size]}
+      end
+
+      def render_hr(el, opts)
+        with_block_padding(el, opts) do
+          @pdf.stroke_horizontal_line(@pdf.bounds.left + mm2pt(5), @pdf.bounds.right - mm2pt(5))
+        end
+      end
+
+      def codeblock_options(el, opts)
+        {
+          :font => 'Courier', :color => '880000',
+          :bottom_padding => opts[:size]
+        }
+      end
+
+      def render_codeblock(el, opts)
+        with_block_padding(el, opts) do
+          @pdf.formatted_text([text_hash(el.value, opts, false)], block_hash(opts))
+        end
+      end
+
+      def table_options(el, opts)
+        {:bottom_padding => opts[:size]}
+      end
+
+      def render_table(el, opts)
+        data = []
+        el.children.each do |container|
+          container.children.each do |row|
+            data << []
+            row.children.each do |cell|
+              if cell.children.any? {|child| child.options[:category] == :block}
+                warning("Can't render tables with cells containing block elements")
+                return
+              end
+              cell_data = inner(cell, opts)
+              data.last << cell_data.map {|c| c[:text]}.join('')
+            end
+          end
+        end
+        with_block_padding(el, opts) do
+          @pdf.table(data, :width => @pdf.bounds.right) do
+            el.options[:alignment].each_with_index do |alignment, index|
+              columns(index).align = alignment unless alignment == :default
+            end
+          end
+        end
+      end
+
+
+
+      def text_options(el, opts)
+        {}
+      end
+
+      def render_text(el, opts)
+        text_hash(el.value.to_s, opts)
+      end
+
+      def em_options(el, opts)
+        if opts[:styles] && opts[:styles].include?(:italic)
+          {:styles => opts[:styles].reject {|i| i == :italic}}
+        else
+          {:styles => (opts[:styles] || []) << :italic}
+        end
+      end
+
+      def strong_options(el, opts)
+        {:styles => (opts[:styles] || []) + [:bold]}
+      end
+
+      def a_options(el, opts)
+        hash = {:color => '000088'}
+        if el.attr['href'].start_with?('#')
+          hash[:anchor] = el.attr['href'].sub(/\A#/, '')
+        else
+          hash[:link] = el.attr['href']
+        end
+        hash
+      end
+
+      def render_em(el, opts)
+        inner(el, opts)
+      end
+      alias_method :render_strong, :render_em
+      alias_method :render_a, :render_em
+
+      def codespan_options(el, opts)
+        {:font => 'Courier', :color => '880000'}
+      end
+
+      def render_codespan(el, opts)
+        text_hash(el.value, opts)
+      end
+
+      def br_options(el, opts)
+        {}
+      end
+
+      def render_br(el, opts)
+        text_hash("\n", opts, false)
+      end
+
+      def smart_quote_options(el, opts)
+        {}
+      end
+
+      def render_smart_quote(el, opts)
+        text_hash(smart_quote_entity(el).char, opts)
+      end
+
+      def typographic_sym_options(el, opts)
+        {}
+      end
+
+      def render_typographic_sym(el, opts)
+        str = if el.value == :laquo_space
+                ::Kramdown::Utils::Entities.entity('laquo').char +
+                  ::Kramdown::Utils::Entities.entity('nbsp').char
+              elsif el.value == :raquo_space
+                ::Kramdown::Utils::Entities.entity('raquo').char +
+                  ::Kramdown::Utils::Entities.entity('nbsp').char
+              else
+                ::Kramdown::Utils::Entities.entity(el.value.to_s).char
+              end
+        text_hash(str, opts)
+      end
+
+      def entity_options(el, opts)
+        {}
+      end
+
+      def render_entity(el, opts)
+        text_hash(el.value.char, opts)
+      end
+
+      def abbreviation_options(el, opts)
+        {}
+      end
+
+      def render_abbreviation(el, opts)
+        text_hash(el.value, opts)
+      end
+
+      def img_options(el, opts)
+        {}
+      end
+
+      def render_img(el, *args) #:nodoc:
+        warning("Rendering span images is not supported for PDF converter")
+        nil
+      end
+
+
+
+      def xml_comment_options(el, opts) #:nodoc:
+        {}
+      end
+      alias_method :xml_pi_options, :xml_comment_options
+      alias_method :comment_options, :xml_comment_options
+      alias_method :blank_options, :xml_comment_options
+      alias_method :footnote_options, :xml_comment_options
+      alias_method :raw_options, :xml_comment_options
+      alias_method :html_element_options, :xml_comment_options
+
+      def render_xml_comment(el, opts) #:nodoc:
+        # noop
+      end
+      alias_method :render_xml_pi, :render_xml_comment
+      alias_method :render_comment, :render_xml_comment
+      alias_method :render_blank, :render_xml_comment
+
+      def render_footnote(el, *args) #:nodoc:
+        warning("Rendering #{el.type} not supported for PDF converter")
+        nil
+      end
+      alias_method :render_raw, :render_footnote
+      alias_method :render_html_element, :render_footnote
+
+
+      # ----------------------------
+      # :section: Organizational methods
+      #
+      # These methods are used, for example, to up the needed Prawn::Document instance or to create
+      # a PDF outline.
+      # ----------------------------
+
+
+      # This module gets mixed into the Prawn::Document instance.
+      module PrawnDocumentExtension
+
+        # Extension for the formatted box class to recognize images and move text around them.
+        module CustomBox
+
+          def available_width
+            return super unless @document.respond_to?(:converter) && @document.converter
+
+            @document.image_floats.each do |pn, x, y, w, h|
+              next if @document.page_number != pn
+              if @at[1] + @baseline_y <= y - @document.bounds.absolute_bottom &&
+                  (@at[1] + @baseline_y + @arranger.max_line_height + @leading >= y - h - @document.bounds.absolute_bottom)
+                return @width - w
+              end
+            end
+
+            return super
+          end
+
+        end
+
+        Prawn::Text::Formatted::Box.extensions << CustomBox
+
+        # Access the converter instance from within Prawn
+        attr_accessor :converter
+
+        def image_floats
+          @image_floats ||= []
+        end
+
+        # Override image embedding method for adding image positions to #image_floats.
+        def embed_image(pdf_obj, info, options)
+          # find where the image will be placed and how big it will be
+          w,h = info.calc_image_dimensions(options)
+
+          if options[:at]
+            x,y = map_to_absolute(options[:at])
+          else
+            x,y = image_position(w,h,options)
+            move_text_position h
+          end
+
+          #--> This part is new
+          if options[:position] == :right
+            image_floats << [page_number, x - 15, y, w + 15, h + 15]
+          end
+
+          # add a reference to the image object to the current page
+          # resource list and give it a label
+          label = "I#{next_image_id}"
+          state.page.xobjects.merge!(label => pdf_obj)
+
+          # add the image to the current page
+          instruct = "\nq\n%.3f 0 0 %.3f %.3f %.3f cm\n/%s Do\nQ"
+          add_content instruct % [ w, h, x, y - h, label ]
+        end
+
+      end
+
+
+      # Return a hash with options that are suitable for Prawn::Document.new.
+      #
+      # Used in #setup_document.
+      def document_options(root)
+        {
+          :page_size => 'A4', :page_layout => :portrait, :margin => mm2pt(20),
+          :info => {
+            :Creator => 'kramdown PDF converter',
+            :CreationDate => Time.now
+          },
+          :compress => true, :optimize_objects => true
+        }
+      end
+
+      # Create a Prawn::Document object and return it.
+      #
+      # Can be used to define repeatable content or register fonts.
+      #
+      # Used in #render_root.
+      def setup_document(root)
+        doc = Prawn::Document.new(document_options(root))
+        doc.extend(PrawnDocumentExtension)
+        doc.converter = self
+        doc
+      end
+
+      #
+      #
+      # Used in #render_root.
+      def finish_document(root)
+        # no op
+      end
+
+      # Create the PDF outline from the header elements in the TOC.
+      def create_outline(root)
+        toc = ::Kramdown::Converter::Toc.convert(root).first
+
+        text_of_header = lambda do |el|
+          if el.type == :text
+            el.value
+          else
+            el.children.map {|c| text_of_header.call(c)}.join('')
+          end
+        end
+
+        add_section = lambda do |item, parent|
+          text = text_of_header.call(item.value)
+          destination = @dests[item.attr[:id]]
+          if !parent
+            @pdf.outline.page(:title => text, :destination => destination)
+          else
+            @pdf.outline.add_subsection_to(parent) do
+              @pdf.outline.page(:title => text, :destination => destination)
+            end
+          end
+          item.children.each {|c| add_section.call(c, text)}
+        end
+
+        toc.children.each do |item|
+          add_section.call(item, nil)
+        end
+      end
+
+
+      # ----------------------------
+      # :section: Helper methods
+      # ----------------------------
+
+
+      # Move the prawn document cursor down before and/or after yielding the given block.
+      #
+      # The :top_padding and :bottom_padding options are used for determinig the padding amount.
+      def with_block_padding(el, opts)
+        @pdf.move_down(opts[:top_padding]) if opts.has_key?(:top_padding)
+        yield
+        @pdf.move_down(opts[:bottom_padding]) if opts.has_key?(:bottom_padding)
+      end
+
+      # Render the children of the given element as formatted text and respect the top/bottom
+      # padding (see #with_block_padding).
+      def render_padded_and_formatted_text(el, opts)
+        with_block_padding(el, opts) { @pdf.formatted_text(inner(el, opts), block_hash(opts)) }
+      end
+
+      # Helper function that returns a hash with valid "formatted text" options.
+      #
+      # The +text+ parameter is used as value for the :text key and if +squeeze_whitespace+ is
+      # +true+, all whitespace is converted into spaces.
+      def text_hash(text, opts, squeeze_whitespace = true)
+        text = text.gsub(/\s+/, ' ') if squeeze_whitespace
+        hash = {:text => text}
+        [:styles, :size, :character_spacing, :font, :color, :link,
+         :anchor, :draw_text_callback, :callback].each do |key|
+          hash[key] = opts[key] if opts.has_key?(key)
+        end
+        hash
+      end
+
+      # Helper function that returns a hash with valid options for the prawn #text_box extracted
+      # from the given options.
+      def block_hash(opts)
+        hash = {}
+        [:align, :valign, :mode, :final_gap, :leading, :fallback_fonts,
+         :direction, :indent_paragraphs].each do |key|
+          hash[key] = opts[key] if opts.has_key?(key)
+        end
+        hash
+      end
+
+    end
+
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/converter/remove_html_tags.rb b/app/server/vendor/kramdown/lib/kramdown/converter/remove_html_tags.rb
new file mode 100644
index 0000000..4813182
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/converter/remove_html_tags.rb
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+
+  module Converter
+
+    # Removes all block (and optionally span) level HTML tags from the element tree.
+    #
+    # This converter can be used on parsed HTML documents to get an element tree that will only
+    # contain native kramdown elements.
+    #
+    # *Note* that the returned element tree may not be fully conformant (i.e. the content models of
+    # *some elements may be violated)!
+    #
+    # This converter modifies the given tree in-place and returns it.
+    class RemoveHtmlTags < Base
+
+      def initialize(root, options)
+        super
+        @options[:template] = ''
+      end
+
+      def convert(el)
+        children = el.children.dup
+        index = 0
+        while index < children.length
+          if [:xml_pi].include?(children[index].type) ||
+              (children[index].type == :html_element && %w[style script].include?(children[index].value))
+            children[index..index] = []
+          elsif children[index].type == :html_element &&
+            ((@options[:remove_block_html_tags] && children[index].options[:category] == :block) ||
+             (@options[:remove_span_html_tags] && children[index].options[:category] == :span))
+            children[index..index] = children[index].children
+          else
+            convert(children[index])
+            index += 1
+          end
+        end
+        el.children = children
+        el
+      end
+
+    end
+
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/converter/toc.rb b/app/server/vendor/kramdown/lib/kramdown/converter/toc.rb
new file mode 100644
index 0000000..d2fbc2f
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/converter/toc.rb
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'rexml/parsers/baseparser'
+
+module Kramdown
+
+  module Converter
+
+    # Converts a Kramdown::Document to an element tree that represents the table of contents.
+    #
+    # The returned tree consists of Element objects of type :toc where the root element is just used
+    # as container object. Each :toc element contains as value the wrapped :header element and under
+    # the attribute key :id the header ID that should be used (note that this ID may not exist in
+    # the wrapped element).
+    #
+    # Since the TOC tree consists of special :toc elements, one cannot directly feed this tree to
+    # other converters!
+    class Toc < Base
+
+      def initialize(root, options)
+        super
+        @toc = Element.new(:toc)
+        @stack = []
+        @options[:template] = ''
+      end
+
+      def convert(el)
+        if el.type == :header && in_toc?(el)
+          attr = el.attr.dup
+          attr['id'] = generate_id(el.options[:raw_text]) if @options[:auto_ids] && !attr['id']
+          add_to_toc(el, attr['id']) if attr['id']
+        else
+          el.children.each {|child| convert(child)}
+        end
+        @toc
+      end
+
+      private
+
+      def add_to_toc(el, id)
+        toc_element = Element.new(:toc, el, :id => id)
+
+        success = false
+        while !success
+          if @stack.empty?
+            @toc.children << toc_element
+            @stack << toc_element
+            success = true
+          elsif @stack.last.value.options[:level] < el.options[:level]
+            @stack.last.children << toc_element
+            @stack << toc_element
+            success = true
+          else
+            @stack.pop
+          end
+        end
+      end
+
+    end
+
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/document.rb b/app/server/vendor/kramdown/lib/kramdown/document.rb
new file mode 100644
index 0000000..b844c2b
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/document.rb
@@ -0,0 +1,144 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+# = kramdown
+#
+# kramdown is yet-another-markdown-parser but fast, pure Ruby, using a strict syntax definition and
+# supporting several common extensions.
+#
+# The kramdown library is mainly written to support the kramdown-to-HTML conversion chain. However,
+# due to its flexibility it supports other input and output formats as well. Here is a list of the
+# supported formats:
+#
+# * input formats: kramdown (a Markdown superset), Markdown, HTML
+# * output formats: HTML, kramdown, LaTeX (and therefore PDF)
+#
+# All the documentation on the available input and output formats is available at
+# http://kramdown.gettalong.org.
+#
+# == Usage
+#
+# kramdown has a basic *Cloth API, so using kramdown is as easy as
+#
+#     require 'kramdown'
+#
+#     Kramdown::Document.new(text).to_html
+#
+# For detailed information have a look at the Kramdown::Document class.
+#
+# == License
+#
+# MIT - see the COPYING file.
+
+
+require 'kramdown/compatibility'
+
+require 'kramdown/version'
+require 'kramdown/element'
+require 'kramdown/error'
+require 'kramdown/parser'
+require 'kramdown/converter'
+require 'kramdown/options'
+require 'kramdown/utils'
+
+module Kramdown
+
+  # Return the data directory for kramdown.
+  def self.data_dir
+    unless defined?(@@data_dir)
+      require 'rbconfig'
+      @@data_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'data', 'kramdown'))
+      @@data_dir = File.expand_path(File.join(Config::CONFIG["datadir"], "kramdown")) if !File.exists?(@@data_dir)
+      raise "kramdown data directory not found! This is a bug, please report it!" unless File.directory?(@@data_dir)
+    end
+    @@data_dir
+  end
+
+
+  # The main interface to kramdown.
+  #
+  # This class provides a one-stop-shop for using kramdown to convert text into various output
+  # formats. Use it like this:
+  #
+  #   require 'kramdown'
+  #   doc = Kramdown::Document.new('This *is* some kramdown text')
+  #   puts doc.to_html
+  #
+  # The #to_html method is a shortcut for using the Converter::Html class. See #method_missing for
+  # more information.
+  #
+  # The second argument to the ::new method is an options hash for customizing the behaviour of the
+  # used parser and the converter. See ::new for more information!
+  class Document
+
+    # The root Element of the element tree. It is immediately available after the ::new method has
+    # been called.
+    attr_accessor :root
+
+    # The options hash which holds the options for parsing/converting the Kramdown document.
+    attr_reader :options
+
+    # An array of warning messages. It is filled with warnings during the parsing phase (i.e. in
+    # ::new) and the conversion phase.
+    attr_reader :warnings
+
+
+    # Create a new Kramdown document from the string +source+ and use the provided +options+. The
+    # options that can be used are defined in the Options module.
+    #
+    # The special options key :input can be used to select the parser that should parse the
+    # +source+. It has to be the name of a class in the Kramdown::Parser module. For example, to
+    # select the kramdown parser, one would set the :input key to +Kramdown+. If this key is not
+    # set, it defaults to +Kramdown+.
+    #
+    # The +source+ is immediately parsed by the selected parser so that the root element is
+    # immediately available and the output can be generated.
+    def initialize(source, options = {})
+      @options = Options.merge(options).freeze
+      parser = (options[:input] || 'kramdown').to_s
+      parser = parser[0..0].upcase + parser[1..-1]
+      try_require('parser', parser)
+      if Parser.const_defined?(parser)
+        @root, @warnings = Parser.const_get(parser).parse(source, @options)
+      else
+        raise Kramdown::Error.new("kramdown has no parser to handle the specified input format: #{options[:input]}")
+      end
+    end
+
+    # Check if a method is invoked that begins with +to_+ and if so, try to instantiate a converter
+    # class (i.e. a class in the Kramdown::Converter module) and use it for converting the document.
+    #
+    # For example, +to_html+ would instantiate the Kramdown::Converter::Html class.
+    def method_missing(id, *attr, &block)
+      if id.to_s =~ /^to_(\w+)$/ && (name = Utils.camelize($1)) &&
+          try_require('converter', name) && Converter.const_defined?(name)
+        output, warnings = Converter.const_get(name).convert(@root, @options)
+        @warnings.concat(warnings)
+        output
+      else
+        super
+      end
+    end
+
+    def inspect #:nodoc:
+      "<KD:Document: options=#{@options.inspect} root=#{@root.inspect} warnings=#{@warnings.inspect}>"
+    end
+
+    # Try requiring a parser or converter class and don't raise an error if the file is not found.
+    def try_require(type, name)
+      require("kramdown/#{type}/#{Utils.snake_case(name)}")
+      true
+    rescue LoadError
+      true
+    end
+    protected :try_require
+
+  end
+
+end
+
diff --git a/app/server/vendor/kramdown/lib/kramdown/element.rb b/app/server/vendor/kramdown/lib/kramdown/element.rb
new file mode 100644
index 0000000..2510783
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/element.rb
@@ -0,0 +1,515 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+
+  # Represents all elements in the element tree.
+  #
+  # kramdown only uses this one class for representing all available elements in an element tree
+  # (paragraphs, headers, emphasis, ...). The type of element can be set via the #type accessor.
+  #
+  # Following is a description of all supported element types.
+  #
+  # Note that the option :location may contain the start line number of an element in the source
+  # document.
+  #
+  # == Structural Elements
+  #
+  # === :root
+  #
+  # [Category] None
+  # [Usage context] As the root element of a document
+  # [Content model] Block-level elements
+  #
+  # Represents the root of a kramdown document.
+  #
+  # The root element contains the following option keys:
+  #
+  # :encoding:: When running on Ruby 1.9 this key has to be set to the encoding used for the text
+  #             parts of the kramdown document.
+  #
+  # :abbrev_defs:: This key may be used to store the mapping of abbreviation to abbreviation
+  #                definition.
+  #
+  # :options:: This key may be used to store options that were set during parsing of the document.
+  #
+  #
+  # === :blank
+  #
+  # [Category] Block-level element
+  # [Usage context] Where block-level elements are expected
+  # [Content model] Empty
+  #
+  # Represents one or more blank lines. It is not allowed to have two or more consecutive blank
+  # elements.
+  #
+  # The +value+ field may contain the original content of the blank lines.
+  #
+  #
+  # === :p
+  #
+  # [Category] Block-level element
+  # [Usage context] Where block-level elements are expected
+  # [Content model] Span-level elements
+  #
+  # Represents a paragraph.
+  #
+  # If the option :transparent is +true+, this element just represents a block of text. I.e. this
+  # element just functions as a container for span-level elements.
+  #
+  #
+  # === :header
+  #
+  # [Category] Block-level element
+  # [Usage context] Where block-level elements are expected
+  # [Content model] Span-level elements
+  #
+  # Represents a header.
+  #
+  # The option :level specifies the header level and has to contain a number between 1 and \6. The
+  # option :raw_text has to contain the raw header text.
+  #
+  #
+  # === :blockquote
+  #
+  # [Category] Block-level element
+  # [Usage context] Where block-level elements are expected
+  # [Content model] Block-level elements
+  #
+  # Represents a blockquote.
+  #
+  #
+  # === :codeblock
+  #
+  # [Category] Block-level element
+  # [Usage context] Where block-level elements are expected
+  # [Content model] Empty
+  #
+  # Represents a code block, i.e. a block of text that should be used as-is.
+  #
+  # The +value+ field has to contain the content of the code block.
+  #
+  #
+  # === :ul
+  #
+  # [Category] Block-level element
+  # [Usage context] Where block-level elements are expected
+  # [Content model] One or more :li elements
+  #
+  # Represents an unordered list.
+  #
+  #
+  # === :ol
+  #
+  # [Category] Block-level element
+  # [Usage context] Where block-level elements are expected
+  # [Content model] One or more :li elements
+  #
+  # Represents an ordered list.
+  #
+  #
+  # === :li
+  #
+  # [Category] None
+  # [Usage context] Inside :ol and :ul elements
+  # [Content model] Block-level elements
+  #
+  # Represents a list item of an ordered or unordered list.
+  #
+  # Note that the first child of a list item must not be a :blank element!
+  #
+  #
+  # === :dl
+  #
+  # [Category] Block-level element
+  # [Usage context] Where block-level elements are expected
+  # [Content model] One or more groups each consisting of one or more :dt elements followed by one
+  #                 or more :dd elements.
+  #
+  # Represents a definition list which contains groups consisting of terms and definitions for them.
+  #
+  #
+  # === :dt
+  #
+  # [Category] None
+  # [Usage context] Before :dt or :dd elements inside a :dl elment
+  # [Content model] Span-level elements
+  #
+  # Represents the term part of a term-definition group in a definition list.
+  #
+  #
+  # === :dd
+  #
+  # [Category] None
+  # [Usage context] After :dt or :dd elements inside a :dl elment
+  # [Content model] Block-level elements
+  #
+  # Represents the definition part of a term-definition group in a definition list.
+  #
+  #
+  # === :hr
+  #
+  # [Category] Block-level element
+  # [Usage context] Where block-level elements are expected
+  # [Content model] None
+  #
+  # Represents a horizontal line.
+  #
+  #
+  # === :table
+  #
+  # [Category] Block-level element
+  # [Usage context] Where block-level elements are expected
+  # [Content model] Zero or one :thead elements, one or more :tbody elements, zero or one :tfoot
+  #                 elements
+  #
+  # Represents a table. Each table row (i.e. :tr element) of the table has to contain the same
+  # number of :td elements.
+  #
+  # The option :alignment has to be an array containing the alignment values, exactly one for each
+  # column of the table. The possible alignment values are :left, :center, :right and :default.
+  #
+  #
+  # === :thead
+  #
+  # [Category] None
+  # [Usage context] As first element inside a :table element
+  # [Content model] One or more :tr elements
+  #
+  # Represents the table header.
+  #
+  #
+  # === :tbody
+  #
+  # [Category] None
+  # [Usage context] After a :thead element but before a :tfoot element inside a :table element
+  # [Content model] One or more :tr elements
+  #
+  # Represents a table body.
+  #
+  #
+  # === :tfoot
+  #
+  # [Category] None
+  # [Usage context] As last element inside a :table element
+  # [Content model] One or more :tr elements
+  #
+  # Represents the table footer.
+  #
+  #
+  # === :tr
+  #
+  # [Category] None
+  # [Usage context] Inside :thead, :tbody and :tfoot elements
+  # [Content model] One or more :td elements
+  #
+  # Represents a table row.
+  #
+  #
+  # === :td
+  #
+  # [Category] None
+  # [Usage context] Inside :tr elements
+  # [Content model] As child of :thead/:tr span-level elements, as child of :tbody/:tr and
+  #                 :tfoot/:tr block-level elements
+  #
+  # Represents a table cell.
+  #
+  #
+  # === :math
+  #
+  # [Category] Block/span-level element
+  # [Usage context] Where block/span-level elements are expected
+  # [Content model] None
+  #
+  # Represents mathematical text that is written in LaTeX.
+  #
+  # The +value+ field has to contain the actual mathematical text.
+  #
+  # The option :category has to be set to either :span or :block depending on the context where the
+  # element is used.
+  #
+  #
+  # == Text Markup Elements
+  #
+  # === :text
+  #
+  # [Category] Span-level element
+  # [Usage context] Where span-level elements are expected
+  # [Content model] None
+  #
+  # Represents text.
+  #
+  # The +value+ field has to contain the text itself.
+  #
+  #
+  # === :br
+  #
+  # [Category] Span-level element
+  # [Usage context] Where span-level elements are expected
+  # [Content model] None
+  #
+  # Represents a hard line break.
+  #
+  #
+  # === :a
+  #
+  # [Category] Span-level element
+  # [Usage context] Where span-level elements are expected
+  # [Content model] Span-level elements
+  #
+  # Represents a link to an URL.
+  #
+  # The attribute +href+ has to be set to the URL to which the link points. The attribute +title+
+  # optionally contains the title of the link.
+  #
+  #
+  # === :img
+  #
+  # [Category] Span-level element
+  # [Usage context] Where span-level elements are expected
+  # [Content model] None
+  #
+  # Represents an image.
+  #
+  # The attribute +src+ has to be set to the URL of the image. The attribute +alt+ has to contain a
+  # text description of the image. The attribute +title+ optionally contains the title of the image.
+  #
+  #
+  # === :codespan
+  #
+  # [Category] Span-level element
+  # [Usage context] Where span-level elements are expected
+  # [Content model] None
+  #
+  # Represents verbatim text.
+  #
+  # The +value+ field has to contain the content of the code span.
+  #
+  #
+  # === :footnote
+  #
+  # [Category] Span-level element
+  # [Usage context] Where span-level elements are expected
+  # [Content model] None
+  #
+  # Represents a footnote marker.
+  #
+  # The +value+ field has to contain an element whose children are the content of the footnote. The
+  # option :name has to contain a valid and unique footnote name. A valid footnote name consists of
+  # a word character or a digit and then optionally followed by other word characters, digits or
+  # dashes.
+  #
+  #
+  # === :em
+  #
+  # [Category] Span-level element
+  # [Usage context] Where span-level elements are expected
+  # [Content model] Span-level elements
+  #
+  # Represents emphasis of its contents.
+  #
+  #
+  # === :strong
+  #
+  # [Category] Span-level element
+  # [Usage context] Where span-level elements are expected
+  # [Content model] Span-level elements
+  #
+  # Represents strong importance for its contents.
+  #
+  #
+  # === :entity
+  #
+  # [Category] Span-level element
+  # [Usage context] Where span-level elements are expected
+  # [Content model] None
+  #
+  # Represents an HTML entity.
+  #
+  # The +value+ field has to contain an instance of Kramdown::Utils::Entities::Entity. The option
+  # :original can be used to store the original representation of the entity.
+  #
+  #
+  # === :typographic_sym
+  #
+  # [Category] Span-level element
+  # [Usage context] Where span-level elements are expected
+  # [Content model] None
+  #
+  # Represents a typographic symbol.
+  #
+  # The +value+ field needs to contain a Symbol representing the specific typographic symbol from
+  # the following list:
+  #
+  # :mdash:: An mdash character (---)
+  # :ndash:: An ndash character (--)
+  # :hellip:: An ellipsis (...)
+  # :laquo:: A left guillemet (<<)
+  # :raquo:: A right guillemet (>>)
+  # :laquo_space:: A left guillemet with a space (<< )
+  # :raquo_space:: A right guillemet with a space ( >>)
+  #
+  #
+  # === :smart_quote
+  #
+  # [Category] Span-level element
+  # [Usage context] Where span-level elements are expected
+  # [Content model] None
+  #
+  # Represents a quotation character.
+  #
+  # The +value+ field needs to contain a Symbol representing the specific quotation character:
+  #
+  # :lsquo:: Left single quote
+  # :rsquo:: Right single quote
+  # :ldquo:: Left double quote
+  # :rdquo:: Right double quote
+  #
+  #
+  # === :abbreviation
+  #
+  # [Category] Span-level element
+  # [Usage context] Where span-level elements are expected
+  # [Content model] None
+  #
+  # Represents a text part that is an abbreviation.
+  #
+  # The +value+ field has to contain the text part that is the abbreviation. The definition of the
+  # abbreviation is stored in the :root element of the document.
+  #
+  #
+  # == Other Elements
+  #
+  # === :html_element
+  #
+  # [Category] Block/span-level element
+  # [Usage context] Where block/span-level elements or raw HTML elements are expected
+  # [Content model] Depends on the element
+  #
+  # Represents an HTML element.
+  #
+  # The +value+ field has to contain the name of the HTML element the element is representing.
+  #
+  # The option :category has to be set to either :span or :block depending on the whether the
+  # element is a block-level or a span-level element. The option :content_model has to be set to the
+  # content model for the element (either :block if it contains block-level elements, :span if it
+  # contains span-level elements or :raw if it contains raw content).
+  #
+  #
+  # === :xml_comment
+  #
+  # [Category] Block/span-level element
+  # [Usage context] Where block/span-level elements are expected or in raw HTML elements
+  # [Content model] None
+  #
+  # Represents an XML/HTML comment.
+  #
+  # The +value+ field has to contain the whole XML/HTML comment including the delimiters.
+  #
+  # The option :category has to be set to either :span or :block depending on the context where the
+  # element is used.
+  #
+  #
+  # === :xml_pi
+  #
+  # [Category] Block/span-level element
+  # [Usage context] Where block/span-level elements are expected or in raw HTML elements
+  # [Content model] None
+  #
+  # Represents an XML/HTML processing instruction.
+  #
+  # The +value+ field has to contain the whole XML/HTML processing instruction including the
+  # delimiters.
+  #
+  # The option :category has to be set to either :span or :block depending on the context where the
+  # element is used.
+  #
+  #
+  # === :comment
+  #
+  # [Category] Block/span-level element
+  # [Usage context] Where block/span-level elements are expected
+  # [Content model] None
+  #
+  # Represents a comment.
+  #
+  # The +value+ field has to contain the comment.
+  #
+  # The option :category has to be set to either :span or :block depending on the context where the
+  # element is used. If it is set to :span, then no blank lines are allowed in the comment.
+  #
+  #
+  # === :raw
+  #
+  # [Category] Block/span-level element
+  # [Usage context] Where block/span-level elements are expected
+  # [Content model] None
+  #
+  # Represents a raw string that should not be modified. For example, the element could contain some
+  # HTML code that should be output as-is without modification and escaping.
+  #
+  # The +value+ field has to contain the actual raw text.
+  #
+  # The option :category has to be set to either :span or :block depending on the context where the
+  # element is used. If it is set to :span, then no blank lines are allowed in the raw text.
+  #
+  # The option :type can be set to an array of strings to define for which converters the raw string
+  # is valid.
+  #
+  class Element
+
+    # A symbol representing the element type. For example, :p or :blockquote.
+    attr_accessor :type
+
+    # The value of the element. The interpretation of this field depends on the type of the element.
+    # Many elements don't use this field.
+    attr_accessor :value
+
+    # The child elements of this element.
+    attr_accessor :children
+
+
+    # Create a new Element object of type +type+. The optional parameters +value+, +attr+ and
+    # +options+ can also be set in this constructor for convenience.
+    def initialize(type, value = nil, attr = nil, options = nil)
+      @type, @value, @attr, @options = type, value, (Utils::OrderedHash.new.merge!(attr) if attr), options
+      @children = []
+    end
+
+    # The attributes of the element. Uses an Utils::OrderedHash to retain the insertion order.
+    def attr
+      @attr ||= Utils::OrderedHash.new
+    end
+
+    # The options hash for the element. It is used for storing arbitray options.
+    def options
+      @options ||= {}
+    end
+
+    def inspect #:nodoc:
+      "<kd:#{@type}#{@value.nil? ? '' : ' ' + @value.inspect} #{@attr.inspect}#{options.empty? ? '' : ' ' + @options.inspect}#{@children.empty? ? '' : ' ' + @children.inspect}>"
+    end
+
+    CATEGORY = {} # :nodoc:
+    [:blank, :p, :header, :blockquote, :codeblock, :ul, :ol, :dl, :table, :hr].each {|b| CATEGORY[b] = :block}
+    [:text, :a, :br, :img, :codespan, :footnote, :em, :strong, :entity, :typographic_sym,
+     :smart_quote, :abbreviation].each {|b| CATEGORY[b] = :span}
+
+    # Return the category of +el+ which can be :block, :span or +nil+.
+    #
+    # Most elements have a fixed category, however, some elements can either appear in a block-level
+    # or a span-level context. These elements need to have the option :category correctly set.
+    def self.category(el)
+      CATEGORY[el.type] || el.options[:category]
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/error.rb b/app/server/vendor/kramdown/lib/kramdown/error.rb
new file mode 100644
index 0000000..643311d
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/error.rb
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+
+  # This error is raised when an error condition is encountered.
+  #
+  # *Note* that this error is only raised by the support framework for the parsers and converters.
+  class Error < RuntimeError; end
+
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/options.rb b/app/server/vendor/kramdown/lib/kramdown/options.rb
new file mode 100644
index 0000000..ae6cf6c
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/options.rb
@@ -0,0 +1,499 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'yaml'
+
+module Kramdown
+
+  # This module defines all options that are used by parsers and/or converters as well as providing
+  # methods to deal with the options.
+  module Options
+
+    # Helper class introducing a boolean type for specifying boolean values (+true+ and +false+) as
+    # option types.
+    class Boolean
+
+      # Return +true+ if +other+ is either +true+ or +false+
+      def self.===(other)
+        FalseClass === other || TrueClass === other
+      end
+
+    end
+
+    # ----------------------------
+    # :section: Option definitions
+    #
+    # This sections describes the methods that can be used on the Options module.
+    # ----------------------------
+
+    # Struct class for storing the definition of an option.
+    Definition = Struct.new(:name, :type, :default, :desc, :validator)
+
+    # Allowed option types.
+    ALLOWED_TYPES = [String, Integer, Float, Symbol, Boolean, Object]
+
+    @options = {}
+
+    # Define a new option called +name+ (a Symbol) with the given +type+ (String, Integer, Float,
+    # Symbol, Boolean, Object), default value +default+ and the description +desc+. If a block is
+    # specified, it should validate the value and either raise an error or return a valid value.
+    #
+    # The type 'Object' should only be used for complex types for which none of the other types
+    # suffices. A block needs to be specified when using type 'Object' and it has to cope with
+    # a value given as string and as the opaque type.
+    def self.define(name, type, default, desc, &block)
+      name = name.to_sym
+      raise ArgumentError, "Option name #{name} is already used" if @options.has_key?(name)
+      raise ArgumentError, "Invalid option type #{type} specified" if !ALLOWED_TYPES.include?(type)
+      raise ArgumentError, "Invalid type for default value" if !(type === default) && !default.nil?
+      raise ArgumentError, "Missing validator block" if type == Object && block.nil?
+      @options[name] = Definition.new(name, type, default, desc, block)
+    end
+
+    # Return all option definitions.
+    def self.definitions
+      @options
+    end
+
+    # Return +true+ if an option called +name+ is defined.
+    def self.defined?(name)
+      @options.has_key?(name.to_sym)
+    end
+
+    # Return a Hash with the default values for all options.
+    def self.defaults
+      temp = {}
+      @options.each {|n, o| temp[o.name] = o.default}
+      temp
+    end
+
+    # Merge the #defaults Hash with the *parsed* options from the given Hash, i.e. only valid option
+    # names are considered and their value is run through the #parse method.
+    def self.merge(hash)
+      temp = defaults
+      hash.each do |k,v|
+        k = k.to_sym
+        @options.has_key?(k) ? temp[k] = parse(k, v) : temp[k] = v
+      end
+      temp
+    end
+
+    # Parse the given value +data+ as if it was a value for the option +name+ and return the parsed
+    # value with the correct type.
+    #
+    # If +data+ already has the correct type, it is just returned. Otherwise it is converted to a
+    # String and then to the correct type.
+    def self.parse(name, data)
+      name = name.to_sym
+      raise ArgumentError, "No option named #{name} defined" if !@options.has_key?(name)
+      if !(@options[name].type === data)
+        data = data.to_s
+        data = if @options[name].type == String
+                 data
+               elsif @options[name].type == Integer
+                 Integer(data) rescue raise Kramdown::Error, "Invalid integer value for option '#{name}': '#{data}'"
+               elsif @options[name].type == Float
+                 Float(data) rescue raise Kramdown::Error, "Invalid float value for option '#{name}': '#{data}'"
+               elsif @options[name].type == Symbol
+                 data.strip!
+                 data = data[1..-1] if data[0] == ?:
+                 (data.empty? || data == 'nil' ? nil : data.to_sym)
+               elsif @options[name].type == Boolean
+                 data.downcase.strip != 'false' && !data.empty?
+               end
+      end
+      data = @options[name].validator[data] if @options[name].validator
+      data
+    end
+
+    # ----------------------------
+    # :section: Option Validators
+    #
+    # This sections contains all pre-defined option validators.
+    # ----------------------------
+
+    # Ensures that the option value +val+ for the option called +name+ is a valid array. The
+    # parameter +val+ can be
+    #
+    # - a comma separated string which is split into an array of values
+    # - or an array.
+    #
+    # Additionally, the array is checked for the correct size.
+    def self.simple_array_validator(val, name, size)
+      if String === val
+        val = val.split(/,/)
+      elsif !(Array === val)
+        raise Kramdown::Error, "Invalid type #{val.class} for option #{name}"
+      end
+      if val.size != size
+        raise Kramdown::Error, "Option #{name} needs exactly #{size} values"
+      end
+      val
+    end
+
+    # ----------------------------
+    # :section: Option Definitions
+    #
+    # This sections contains all option definitions that are used by the included
+    # parsers/converters.
+    # ----------------------------
+
+    define(:template, String, '', <<EOF)
+The name of an ERB template file that should be used to wrap the output
+or the ERB template itself.
+
+This is used to wrap the output in an environment so that the output can
+be used as a stand-alone document. For example, an HTML template would
+provide the needed header and body tags so that the whole output is a
+valid HTML file. If no template is specified, the output will be just
+the converted text.
+
+When resolving the template file, the given template name is used first.
+If such a file is not found, the converter extension (the same as the
+converter name) is appended. If the file still cannot be found, the
+templates name is interpreted as a template name that is provided by
+kramdown (without the converter extension). If the file is still not
+found, the template name is checked if it starts with 'string://' and if
+it does, this prefix is removed and the rest is used as template
+content.
+
+kramdown provides a default template named 'document' for each converter.
+
+Default: ''
+Used by: all converters
+EOF
+
+    define(:auto_ids, Boolean, true, <<EOF)
+Use automatic header ID generation
+
+If this option is `true`, ID values for all headers are automatically
+generated if no ID is explicitly specified.
+
+Default: true
+Used by: HTML/Latex converter
+EOF
+
+    define(:auto_id_stripping, Boolean, false, <<EOF)
+Strip all formatting from header text for automatic ID generation
+
+If this option is `true`, only the text elements of a header are used
+for generating the ID later (in contrast to just using the raw header
+text line).
+
+This option will be removed in version 2.0 because this will be the
+default then.
+
+Default: false
+Used by: kramdown parser
+EOF
+
+    define(:auto_id_prefix, String, '', <<EOF)
+Prefix used for automatically generated header IDs
+
+This option can be used to set a prefix for the automatically generated
+header IDs so that there is no conflict when rendering multiple kramdown
+documents into one output file separately. The prefix should only
+contain characters that are valid in an ID!
+
+Default: ''
+Used by: HTML/Latex converter
+EOF
+
+    define(:transliterated_header_ids, Boolean, false, <<EOF)
+Transliterate the header text before generating the ID
+
+Only ASCII characters are used in headers IDs. This is not good for
+languages with many non-ASCII characters. By enabling this option
+the header text is transliterated to ASCII as good as possible so that
+the resulting header ID is more useful.
+
+The stringex library needs to be installed for this feature to work!
+
+Default: false
+Used by: HTML/Latex converter
+EOF
+
+    define(:parse_block_html, Boolean, false, <<EOF)
+Process kramdown syntax in block HTML tags
+
+If this option is `true`, the kramdown parser processes the content of
+block HTML tags as text containing block-level elements. Since this is
+not wanted normally, the default is `false`. It is normally better to
+selectively enable kramdown processing via the markdown attribute.
+
+Default: false
+Used by: kramdown parser
+EOF
+
+    define(:parse_span_html, Boolean, true, <<EOF)
+Process kramdown syntax in span HTML tags
+
+If this option is `true`, the kramdown parser processes the content of
+span HTML tags as text containing span-level elements.
+
+Default: true
+Used by: kramdown parser
+EOF
+
+    define(:html_to_native, Boolean, false, <<EOF)
+Convert HTML elements to native elements
+
+If this option is `true`, the parser converts HTML elements to native
+elements. For example, when parsing `<em>hallo</em>` the emphasis tag
+would normally be converted to an `:html` element with tag type `:em`.
+If `html_to_native` is `true`, then the emphasis would be converted to a
+native `:em` element.
+
+This is useful for converters that cannot deal with HTML elements.
+
+Default: false
+Used by: kramdown parser
+EOF
+
+    define(:link_defs, Object, {}, <<EOF) do |val|
+Pre-defines link definitions
+
+This option can be used to pre-define link definitions. The value needs
+to be a Hash where the keys are the link identifiers and the values are
+two element Arrays with the link URL and the link title.
+
+If the value is a String, it has to contain a valid YAML hash and the
+hash has to follow the above guidelines.
+
+Default: {}
+Used by: kramdown parser
+EOF
+      if String === val
+        begin
+          val = YAML.load(val)
+        rescue RuntimeError, ArgumentError, SyntaxError
+          raise Kramdown::Error, "Invalid YAML value for option link_defs"
+        end
+      end
+      raise Kramdown::Error, "Invalid type #{val.class} for option #{name}" if !(Hash === val)
+      val.each do |k,v|
+        if !(Array === v) || v.size > 2 || v.size < 1
+          raise Kramdown::Error, "Invalid structure for hash value of option #{name}"
+        end
+        v << nil if v.size == 1
+      end
+      val
+    end
+
+    define(:footnote_nr, Integer, 1, <<EOF)
+The number of the first footnote
+
+This option can be used to specify the number that is used for the first
+footnote.
+
+Default: 1
+Used by: HTML converter
+EOF
+
+    define(:enable_coderay, Boolean, true, <<EOF)
+Use coderay for syntax highlighting
+
+If this option is `true`, coderay is used by the HTML converter for
+syntax highlighting the content of code spans and code blocks.
+
+Default: true
+Used by: HTML converter
+EOF
+
+    define(:coderay_wrap, Symbol, :div, <<EOF)
+Defines how the highlighted code should be wrapped
+
+The possible values are :span, :div or nil.
+
+Default: :div
+Used by: HTML converter
+EOF
+
+    define(:coderay_line_numbers, Symbol, :inline, <<EOF)
+Defines how and if line numbers should be shown
+
+The possible values are :table, :inline or nil. If this option is
+nil, no line numbers are shown.
+
+Default: :inline
+Used by: HTML converter
+EOF
+
+    define(:coderay_line_number_start, Integer, 1, <<EOF)
+The start value for the line numbers
+
+Default: 1
+Used by: HTML converter
+EOF
+
+    define(:coderay_tab_width, Integer, 8, <<EOF)
+The tab width used in highlighted code
+
+Used by: HTML converter
+EOF
+
+    define(:coderay_bold_every, Object, 10, <<EOF) do |val|
+Defines how often a line number should be made bold
+
+Can either be an integer or false (to turn off bold line numbers
+completely).
+
+Default: 10
+Used by: HTML converter
+EOF
+      if val == false || val.to_s == 'false'
+        false
+      else
+        Integer(val.to_s) rescue raise Kramdown::Error, "Invalid value for option 'coderay_bold_every'"
+      end
+end
+
+    define(:coderay_css, Symbol, :style, <<EOF)
+Defines how the highlighted code gets styled
+
+Possible values are :class (CSS classes are applied to the code
+elements, one must supply the needed CSS file) or :style (default CSS
+styles are directly applied to the code elements).
+
+Default: style
+Used by: HTML converter
+EOF
+
+    define(:coderay_default_lang, Symbol, nil, <<EOF)
+Sets the default language for highlighting code blocks
+
+If no language is set for a code block, the default language is used
+instead. The value has to be one of the languages supported by coderay
+or nil if no default language should be used.
+
+Default: nil
+Used by: HTML converter
+EOF
+
+    define(:entity_output, Symbol, :as_char, <<EOF)
+Defines how entities are output
+
+The possible values are :as_input (entities are output in the same
+form as found in the input), :numeric (entities are output in numeric
+form), :symbolic (entities are output in symbolic form if possible) or
+:as_char (entities are output as characters if possible, only available
+on Ruby 1.9).
+
+Default: :as_char
+Used by: HTML converter, kramdown converter
+EOF
+
+    define(:toc_levels, Object, (1..6).to_a, <<EOF) do |val|
+Defines the levels that are used for the table of contents
+
+The individual levels can be specified by separating them with commas
+(e.g. 1,2,3) or by using the range syntax (e.g. 1..3). Only the
+specified levels are used for the table of contents.
+
+Default: 1..6
+Used by: HTML/Latex converter
+EOF
+      if String === val
+        if val =~ /^(\d)\.\.(\d)$/
+          val = Range.new($1.to_i, $2.to_i).to_a
+        elsif val =~ /^\d(?:,\d)*$/
+          val = val.split(/,/).map {|s| s.to_i}.uniq
+        else
+          raise Kramdown::Error, "Invalid syntax for option toc_levels"
+        end
+      elsif Array === val
+        val = val.map {|s| s.to_i}.uniq
+      else
+        raise Kramdown::Error, "Invalid type #{val.class} for option toc_levels"
+      end
+      if val.any? {|i| !(1..6).include?(i)}
+        raise Kramdown::Error, "Level numbers for option toc_levels have to be integers from 1 to 6"
+      end
+      val
+    end
+
+    define(:line_width, Integer, 72, <<EOF)
+Defines the line width to be used when outputting a document
+
+Default: 72
+Used by: kramdown converter
+EOF
+
+    define(:latex_headers, Object, %w{section subsection subsubsection paragraph subparagraph subparagraph}, <<EOF) do |val|
+Defines the LaTeX commands for different header levels
+
+The commands for the header levels one to six can be specified by
+separating them with commas.
+
+Default: section,subsection,subsubsection,paragraph,subparagraph,subparagraph
+Used by: Latex converter
+EOF
+      simple_array_validator(val, :latex_headers, 6)
+    end
+
+    define(:smart_quotes, Object, %w{lsquo rsquo ldquo rdquo}, <<EOF) do |val|
+Defines the HTML entity names or code points for smart quote output
+
+The entities identified by entity name or code point that should be
+used for, in order, a left single quote, a right single quote, a left
+double and a right double quote are specified by separating them with
+commas.
+
+Default: lsquo,rsquo,ldquo,rdquo
+Used by: HTML/Latex converter
+EOF
+      val = simple_array_validator(val, :smart_quotes, 4)
+      val.map! {|v| Integer(v) rescue v}
+      val
+    end
+
+    define(:remove_block_html_tags, Boolean, true, <<EOF)
+Remove block HTML tags
+
+If this option is `true`, the RemoveHtmlTags converter removes
+block HTML tags.
+
+Default: true
+Used by: RemoveHtmlTags converter
+EOF
+
+    define(:remove_span_html_tags, Boolean, false, <<EOF)
+Remove span HTML tags
+
+If this option is `true`, the RemoveHtmlTags converter removes
+span HTML tags.
+
+Default: false
+Used by: RemoveHtmlTags converter
+EOF
+
+    define(:header_offset, Integer, 0, <<EOF)
+Sets the output offset for headers
+
+If this option is c (may also be negative) then a header with level n
+will be output as a header with level c+n. If c+n is lower than 1,
+level 1 will be used. If c+n is greater than 6, level 6 will be used.
+
+Default: 0
+Used by: HTML converter, Kramdown converter, Latex converter
+EOF
+
+    define(:hard_wrap, Boolean, true, <<EOF)
+Interprets line breaks literally
+
+Insert HTML `<br />` tags inside paragraphs where the original Markdown
+document had newlines (by default, Markdown ignores these newlines).
+
+Default: true
+Used by: GFM parser
+EOF
+
+  end
+
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser.rb b/app/server/vendor/kramdown/lib/kramdown/parser.rb
new file mode 100644
index 0000000..424afbe
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser.rb
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+
+  # This module contains all available parsers. A parser takes an input string and converts the
+  # string to an element tree.
+  #
+  # New parsers should be derived from the Base class which provides common functionality - see its
+  # API documentation for how to create a custom converter class.
+  module Parser
+
+    autoload :Base, 'kramdown/parser/base'
+    autoload :Kramdown, 'kramdown/parser/kramdown'
+    autoload :Html, 'kramdown/parser/html'
+    autoload :Markdown, 'kramdown/parser/markdown'
+    autoload :GFM, 'kramdown/parser/gfm'
+
+  end
+
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/base.rb b/app/server/vendor/kramdown/lib/kramdown/parser/base.rb
new file mode 100644
index 0000000..167d1ea
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/base.rb
@@ -0,0 +1,129 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'kramdown/utils/string_scanner'
+
+module Kramdown
+
+  module Parser
+
+    # == \Base class for parsers
+    #
+    # This class serves as base class for parsers. It provides common methods that can/should be
+    # used by all parsers, especially by those using StringScanner(Kramdown) for parsing.
+    #
+    # A parser object is used as a throw-away object, i.e. it is only used for storing the needed
+    # state information during parsing. Therefore one can't instantiate a parser object directly but
+    # only use the Base::parse method.
+    #
+    # == Implementing a parser
+    #
+    # Implementing a new parser is rather easy: just derive a new class from this class and put it
+    # in the Kramdown::Parser module -- the latter is needed so that the auto-detection of the new
+    # parser works correctly. Then you need to implement the +#parse+ method which has to contain
+    # the parsing code.
+    #
+    # Have a look at the Base::parse, Base::new and Base#parse methods for additional information!
+    class Base
+
+      # The hash with the parsing options.
+      attr_reader :options
+
+      # The array with the parser warnings.
+      attr_reader :warnings
+
+      # The original source string.
+      attr_reader :source
+
+      # The root element of element tree that is created from the source string.
+      attr_reader :root
+
+      # Initialize the parser object with the +source+ string and the parsing +options+.
+      #
+      # The @root element, the @warnings array and @text_type (specifies the default type for newly
+      # created text nodes) are automatically initialized.
+      def initialize(source, options)
+        @source = source
+        @options = Kramdown::Options.merge(options)
+        @root = Element.new(:root, nil, nil, :encoding => (source.encoding rescue nil), :location => 1)
+        @warnings = []
+        @text_type = :text
+      end
+      private_class_method(:new, :allocate)
+
+      # Parse the +source+ string into an element tree, possibly using the parsing +options+, and
+      # return the root element of the element tree and an array with warning messages.
+      #
+      # Initializes a new instance of the calling class and then calls the +#parse+ method that must
+      # be implemented by each subclass.
+      def self.parse(source, options = {})
+        parser = new(source, options)
+        parser.parse
+        [parser.root, parser.warnings]
+      end
+
+      # Parse the source string into an element tree.
+      #
+      # The parsing code should parse the source provided in @source and build an element tree the
+      # root of which should be @root.
+      #
+      # This is the only method that has to be implemented by sub-classes!
+      def parse
+        raise NotImplementedError
+      end
+
+      # Add the given warning +text+ to the warning array.
+      def warning(text)
+        @warnings << text
+        #TODO: add position information
+      end
+
+      # Modify the string +source+ to be usable by the parser (unifies line ending characters to
+      # +\n+ and makes sure +source+ ends with a new line character).
+      def adapt_source(source)
+        if source.respond_to?(:encode)
+          raise "The encoding of the source text is not valid!" if !source.valid_encoding?
+          source = source.encode('UTF-8')
+        end
+        source.gsub(/\r\n?/, "\n").chomp + "\n"
+      end
+
+      # This helper method adds the given +text+ either to the last element in the +tree+ if it is a
+      # +type+ element or creates a new text element with the given +type+.
+      def add_text(text, tree = @tree, type = @text_type)
+        if tree.children.last && tree.children.last.type == type
+          tree.children.last.value << text
+        elsif !text.empty?
+          tree.children << Element.new(type, text)
+        end
+      end
+
+      # Extract the part of the StringScanner +strscan+ backed string specified by the +range+. This
+      # method works correctly under Ruby 1.8 and Ruby 1.9.
+      def extract_string(range, strscan)
+        result = nil
+        if strscan.string.respond_to?(:encoding)
+          begin
+            enc = strscan.string.encoding
+            strscan.string.force_encoding('ASCII-8BIT')
+            result = strscan.string[range].force_encoding(enc)
+          ensure
+            strscan.string.force_encoding(enc)
+          end
+        else
+          result = strscan.string[range]
+        end
+        result
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/gfm.rb b/app/server/vendor/kramdown/lib/kramdown/parser/gfm.rb
new file mode 100644
index 0000000..921d05e
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/gfm.rb
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+
+require 'kramdown/parser/kramdown'
+
+module Kramdown
+  module Parser
+    class GFM < Kramdown::Parser::Kramdown
+
+      def initialize(source, options)
+        super
+        @span_parsers.delete(:line_break)
+        {:codeblock_fenced => :codeblock_fenced_gfm,
+          :atx_header => :atx_header_gfm}.each do |current, replacement|
+          i = @block_parsers.index(current)
+          @block_parsers.delete(current)
+          @block_parsers.insert(i, replacement)
+        end
+      end
+
+      def parse
+        super
+        add_hard_line_breaks(@root) if @options[:hard_wrap]
+      end
+
+      def add_hard_line_breaks(element)
+        element.children.map! do |child|
+          if child.type == :text && child.value =~ /\n/
+            children = []
+            lines = child.value.split(/\n(?=.)/)
+            lines.each_with_index do |line, index|
+              children << Element.new(:text, (index > 0 ? "\n#{line}" : line))
+              children << Element.new(:br) if index < lines.size - 1
+            end
+            children
+          elsif child.type == :html_element
+            child
+          else
+            add_hard_line_breaks(child)
+            child
+          end
+        end.flatten!
+      end
+
+      ATX_HEADER_START = /^\#{1,6}\s/
+      define_parser(:atx_header_gfm, ATX_HEADER_START, nil, 'parse_atx_header')
+
+      FENCED_CODEBLOCK_MATCH = /^(([~`]){3,})\s*?(\w+)?\s*?\n(.*?)^\1\2*\s*?\n/m
+      define_parser(:codeblock_fenced_gfm, /^[~`]{3,}/, nil, 'parse_codeblock_fenced')
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/html.rb b/app/server/vendor/kramdown/lib/kramdown/parser/html.rb
new file mode 100644
index 0000000..6ceffef
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/html.rb
@@ -0,0 +1,563 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'rexml/parsers/baseparser'
+require 'strscan'
+require 'kramdown/utils'
+
+module Kramdown
+
+  module Parser
+
+    # Used for parsing a HTML document.
+    #
+    # The parsing code is in the Parser module that can also be used by other parsers.
+    class Html < Base
+
+      # Contains all constants that are used when parsing.
+      module Constants
+
+        #:stopdoc:
+        # The following regexps are based on the ones used by REXML, with some slight modifications.
+        HTML_DOCTYPE_RE = /<!DOCTYPE.*?>/im
+        HTML_COMMENT_RE = /<!--(.*?)-->/m
+        HTML_INSTRUCTION_RE = /<\?(.*?)\?>/m
+        HTML_ATTRIBUTE_RE = /\s*(#{REXML::Parsers::BaseParser::UNAME_STR})(?:\s*=\s*(["'])(.*?)\2)?/m
+        HTML_TAG_RE = /<((?>#{REXML::Parsers::BaseParser::UNAME_STR}))\s*((?>\s+#{REXML::Parsers::BaseParser::UNAME_STR}(?:\s*=\s*(["']).*?\3)?)*)\s*(\/)?>/m
+        HTML_TAG_CLOSE_RE = /<\/(#{REXML::Parsers::BaseParser::UNAME_STR})\s*>/m
+        HTML_ENTITY_RE = /&([\w:][\-\w\.:]*);|&#(\d+);|&\#x([0-9a-fA-F]+);/
+
+        HTML_CONTENT_MODEL_BLOCK = %w{address applet article aside button blockquote body
+             dd div dl fieldset figure figcaption footer form header hgroup iframe li map menu nav
+              noscript object section td}
+        HTML_CONTENT_MODEL_SPAN  = %w{a abbr acronym b bdo big button cite caption del dfn dt em
+             h1 h2 h3 h4 h5 h6 i ins label legend optgroup p q rb rbc
+             rp rt rtc ruby select small span strong sub sup summary th tt}
+        HTML_CONTENT_MODEL_RAW   = %w{script style math option textarea pre code kbd samp var}
+        # The following elements are also parsed as raw since they need child elements that cannot
+        # be expressed using kramdown syntax: colgroup table tbody thead tfoot tr ul ol
+
+        HTML_CONTENT_MODEL = Hash.new {|h,k| h[k] = :raw}
+        HTML_CONTENT_MODEL_BLOCK.each {|i| HTML_CONTENT_MODEL[i] = :block}
+        HTML_CONTENT_MODEL_SPAN.each {|i| HTML_CONTENT_MODEL[i] = :span}
+        HTML_CONTENT_MODEL_RAW.each {|i| HTML_CONTENT_MODEL[i] = :raw}
+
+        # Some HTML elements like script belong to both categories (i.e. are valid in block and
+        # span HTML) and don't appear therefore!
+        HTML_SPAN_ELEMENTS = %w{a abbr acronym b big bdo br button cite code del dfn em i img input
+                              ins kbd label option q rb rbc rp rt rtc ruby samp select small span
+                              strong sub sup textarea tt var}
+        HTML_BLOCK_ELEMENTS = %w{address article aside applet body button blockquote caption col colgroup dd div dl dt fieldset
+                               figcaption footer form h1 h2 h3 h4 h5 h6 header hgroup hr html head iframe legend menu
+                               li map nav ol optgroup p pre section summary table tbody td th thead tfoot tr ul}
+        HTML_ELEMENTS_WITHOUT_BODY = %w{area base br col command embed hr img input keygen link meta param source track wbr}
+      end
+
+
+      # Contains the parsing methods. This module can be mixed into any parser to get HTML parsing
+      # functionality. The only thing that must be provided by the class are instance variable
+      # @stack for storing the needed state and @src (instance of StringScanner) for the actual
+      # parsing.
+      module Parser
+
+        include Constants
+
+        # Process the HTML start tag that has already be scanned/checked via @src.
+        #
+        # Does the common processing steps and then yields to the caller for further processing
+        # (first parameter is the created element; the second parameter is +true+ if the HTML
+        # element is already closed, ie. contains no body; the third parameter specifies whether the
+        # body - and the end tag - need to be handled in case closed=false).
+        def handle_html_start_tag # :yields: el, closed, handle_body
+          name = @src[1].downcase
+          closed = !@src[4].nil?
+          attrs = Utils::OrderedHash.new
+          @src[2].scan(HTML_ATTRIBUTE_RE).each {|attr,sep,val| attrs[attr.downcase] = val || ""}
+
+          el = Element.new(:html_element, name, attrs, :category => :block)
+          @tree.children << el
+
+          if !closed && HTML_ELEMENTS_WITHOUT_BODY.include?(el.value)
+            warning("The HTML tag '#{el.value}' cannot have any content - auto-closing it")
+            closed = true
+          end
+          if name == 'script' || name == 'style'
+            handle_raw_html_tag(name)
+            yield(el, false, false)
+          else
+            yield(el, closed, true)
+          end
+        end
+
+        # Handle the raw HTML tag at the current position.
+        def handle_raw_html_tag(name)
+          curpos = @src.pos
+          if @src.scan_until(/(?=<\/#{name}\s*>)/mi)
+            add_text(extract_string(curpos... at src.pos, @src), @tree.children.last, :raw)
+            @src.scan(HTML_TAG_CLOSE_RE)
+          else
+            add_text(@src.rest, @tree.children.last, :raw)
+            @src.terminate
+            warning("Found no end tag for '#{name}' - auto-closing it")
+          end
+        end
+
+        HTML_RAW_START = /(?=<(#{REXML::Parsers::BaseParser::UNAME_STR}|\/|!--|\?))/ # :nodoc:
+
+        # Parse raw HTML from the current source position, storing the found elements in +el+.
+        # Parsing continues until one of the following criteria are fulfilled:
+        #
+        # - The end of the document is reached.
+        # - The matching end tag for the element +el+ is found (only used if +el+ is an HTML
+        #   element).
+        #
+        # When an HTML start tag is found, processing is deferred to #handle_html_start_tag,
+        # providing the block given to this method.
+        def parse_raw_html(el, &block)
+          @stack.push(@tree)
+          @tree = el
+
+          done = false
+          while !@src.eos? && !done
+            if result = @src.scan_until(HTML_RAW_START)
+              add_text(result, @tree, :text)
+              if result = @src.scan(HTML_COMMENT_RE)
+                @tree.children << Element.new(:xml_comment, result, nil, :category => :block)
+              elsif result = @src.scan(HTML_INSTRUCTION_RE)
+                @tree.children << Element.new(:xml_pi, result, nil, :category => :block)
+              elsif @src.scan(HTML_TAG_RE)
+                handle_html_start_tag(&block)
+              elsif @src.scan(HTML_TAG_CLOSE_RE)
+                if @tree.value == @src[1].downcase
+                  done = true
+                else
+                  warning("Found invalidly used HTML closing tag for '#{@src[1].downcase}' - ignoring it")
+                end
+              else
+                add_text(@src.getch, @tree, :text)
+              end
+            else
+              add_text(@src.rest, @tree, :text)
+              @src.terminate
+              warning("Found no end tag for '#{@tree.value}' - auto-closing it") if @tree.type == :html_element
+              done = true
+            end
+          end
+
+          @tree = @stack.pop
+        end
+
+      end
+
+
+      # Converts HTML elements to native elements if possible.
+      class ElementConverter
+
+        # :stopdoc:
+
+        include Constants
+        include ::Kramdown::Utils::Entities
+
+        REMOVE_TEXT_CHILDREN =  %w{html head hgroup ol ul dl table colgroup tbody thead tfoot tr select optgroup}
+        WRAP_TEXT_CHILDREN = %w{body section nav article aside header footer address div li dd blockquote figure
+                                figcaption fieldset form}
+        REMOVE_WHITESPACE_CHILDREN = %w{body section nav article aside header footer address
+                                        div li dd blockquote figure figcaption td th fieldset form}
+        STRIP_WHITESPACE = %w{address article aside blockquote body caption dd div dl dt fieldset figcaption form footer
+                              header h1 h2 h3 h4 h5 h6 legend li nav p section td th}
+        SIMPLE_ELEMENTS = %w{em strong blockquote hr br img p thead tbody tfoot tr td th ul ol dl li dl dt dd}
+
+        def initialize(root)
+          @root = root
+        end
+
+        def self.convert(root, el = root)
+          new(root).process(el)
+        end
+
+        # Convert the element +el+ and its children.
+        def process(el, do_conversion = true, preserve_text = false, parent = nil)
+          case el.type
+          when :xml_comment, :xml_pi
+            ptype = if parent.nil?
+                      'div'
+                    else
+                      case parent.type
+                      when :html_element then parent.value
+                      when :code_span then 'code'
+                      when :code_block then 'pre'
+                      when :header then 'h1'
+                      else parent.type.to_s
+                      end
+                    end
+            el.options.replace({:category => (HTML_CONTENT_MODEL[ptype] == :span ? :span : :block)})
+            return
+          when :html_element
+          when :root
+            el.children.each {|c| process(c)}
+            remove_whitespace_children(el)
+            return
+          else return
+          end
+
+          mname = "convert_#{el.value}"
+          if do_conversion && self.class.method_defined?(mname)
+            send(mname, el)
+          else
+            type = el.value
+            remove_text_children(el) if do_conversion && REMOVE_TEXT_CHILDREN.include?(type)
+
+            if do_conversion && SIMPLE_ELEMENTS.include?(type)
+              set_basics(el, type.intern)
+              process_children(el, do_conversion, preserve_text)
+            else
+              process_html_element(el, do_conversion, preserve_text)
+            end
+
+            if do_conversion
+              strip_whitespace(el) if STRIP_WHITESPACE.include?(type)
+              remove_whitespace_children(el) if REMOVE_WHITESPACE_CHILDREN.include?(type)
+              wrap_text_children(el) if WRAP_TEXT_CHILDREN.include?(type)
+            end
+          end
+        end
+
+        def process_children(el, do_conversion = true, preserve_text = false)
+          el.children.map! do |c|
+            if c.type == :text
+              process_text(c.value, preserve_text || !do_conversion)
+            else
+              process(c, do_conversion, preserve_text, el)
+              c
+            end
+          end.flatten!
+        end
+
+        # Process the HTML text +raw+: compress whitespace (if +preserve+ is +false+) and convert
+        # entities in entity elements.
+        def process_text(raw, preserve = false)
+          raw.gsub!(/\s+/, ' ') unless preserve
+          src = Kramdown::Utils::StringScanner.new(raw)
+          result = []
+          while !src.eos?
+            if tmp = src.scan_until(/(?=#{HTML_ENTITY_RE})/)
+              result << Element.new(:text, tmp)
+              src.scan(HTML_ENTITY_RE)
+              val = src[1] || (src[2] && src[2].to_i) || src[3].hex
+              result << if %w{lsquo rsquo ldquo rdquo}.include?(val)
+                          Element.new(:smart_quote, val.intern)
+                        elsif %w{mdash ndash hellip laquo raquo}.include?(val)
+                          Element.new(:typographic_sym, val.intern)
+                        else
+                          begin
+                            Element.new(:entity, entity(val), nil, :original => src.matched)
+                          rescue ::Kramdown::Error
+                            src.pos -= src.matched_size - 1
+                            Element.new(:entity, ::Kramdown::Utils::Entities.entity('amp'))
+                          end
+                        end
+            else
+              result << Element.new(:text, src.rest)
+              src.terminate
+            end
+          end
+          result
+        end
+
+        def process_html_element(el, do_conversion = true, preserve_text = false)
+          el.options.replace(:category => HTML_SPAN_ELEMENTS.include?(el.value) ? :span : :block,
+                             :content_model => (do_conversion ? HTML_CONTENT_MODEL[el.value] : :raw))
+          process_children(el, do_conversion, preserve_text)
+        end
+
+        def remove_text_children(el)
+          el.children.delete_if {|c| c.type == :text}
+        end
+
+        def wrap_text_children(el)
+          tmp = []
+          last_is_p = false
+          el.children.each do |c|
+            if Element.category(c) != :block || c.type == :text
+              if !last_is_p
+                tmp << Element.new(:p, nil, nil, :transparent => true)
+                last_is_p = true
+              end
+              tmp.last.children << c
+              tmp
+            else
+              tmp << c
+              last_is_p = false
+            end
+          end
+          el.children = tmp
+        end
+
+        def strip_whitespace(el)
+          return if el.children.empty?
+          if el.children.first.type == :text
+            el.children.first.value.lstrip!
+          end
+          if el.children.last.type == :text
+            el.children.last.value.rstrip!
+          end
+        end
+
+        def remove_whitespace_children(el)
+          i = -1
+          el.children = el.children.reject do |c|
+            i += 1
+            c.type == :text && c.value.strip.empty? &&
+              (i == 0 || i == el.children.length - 1 || (Element.category(el.children[i-1]) == :block &&
+                                                         Element.category(el.children[i+1]) == :block))
+          end
+        end
+
+        def set_basics(el, type, opts = {})
+          el.type = type
+          el.options.replace(opts)
+          el.value = nil
+        end
+
+        def extract_text(el, raw)
+          raw << el.value.to_s if el.type == :text
+          el.children.each {|c| extract_text(c, raw)}
+        end
+
+        def convert_a(el)
+          if el.attr['href']
+            set_basics(el, :a)
+            process_children(el)
+          else
+            process_html_element(el, false)
+          end
+        end
+
+        EMPHASIS_TYPE_MAP = {'em' => :em, 'i' => :em, 'strong' => :strong, 'b' => :strong}
+        def convert_em(el)
+          text = ''
+          extract_text(el, text)
+          if text =~ /\A\s/ || text =~ /\s\z/
+            process_html_element(el, false)
+          else
+            set_basics(el, EMPHASIS_TYPE_MAP[el.value])
+            process_children(el)
+          end
+        end
+        %w{b strong i}.each do |i|
+          alias_method("convert_#{i}".to_sym, :convert_em)
+        end
+
+        def convert_h1(el)
+          set_basics(el, :header, :level => el.value[1..1].to_i)
+          extract_text(el, el.options[:raw_text] = '')
+          process_children(el)
+        end
+        %w{h2 h3 h4 h5 h6}.each do |i|
+          alias_method("convert_#{i}".to_sym, :convert_h1)
+        end
+
+        def convert_code(el)
+          raw = ''
+          extract_text(el, raw)
+          result = process_text(raw, true)
+          begin
+            str = result.inject('') do |mem, c|
+              if c.type == :text
+                mem << c.value
+              elsif c.type == :entity
+                if [60, 62, 34, 38].include?(c.value.code_point)
+                  mem << c.value.code_point.chr
+                else
+                  mem << c.value.char
+                end
+              elsif c.type == :smart_quote || c.type == :typographic_sym
+                mem << entity(c.value.to_s).char
+              else
+                raise "Bug - please report"
+              end
+            end
+            result.clear
+            result << Element.new(:text, str)
+          rescue
+          end
+          if result.length > 1 || result.first.type != :text
+            process_html_element(el, false, true)
+          else
+            if el.value == 'code'
+              set_basics(el, :codespan)
+            else
+              set_basics(el, :codeblock)
+              if el.children.size == 1 && el.children.first.value == 'code'
+                value = (el.children.first.attr['class'] || '').scan(/\blanguage-\w+\b/).first
+                el.attr['class'] = "#{value} #{el.attr['class']}".rstrip if value
+              end
+            end
+            el.value = result.first.value
+            el.children.clear
+          end
+        end
+        alias :convert_pre :convert_code
+
+        def convert_table(el)
+          if !is_simple_table?(el)
+            process_html_element(el, false)
+            return
+          end
+          remove_text_children(el)
+          process_children(el)
+          set_basics(el, :table)
+
+          calc_alignment = lambda do |c|
+            if c.type == :tr
+              el.options[:alignment] = c.children.map do |td|
+                if td.attr['style']
+                  td.attr['style'].slice!(/(?:;\s*)?text-align:\s+(center|left|right)/)
+                  td.attr.delete('style') if td.attr['style'].strip.empty?
+                  $1 ? $1.to_sym : :default
+                else
+                  :default
+                end
+              end
+            else
+              c.children.each {|cc| calc_alignment.call(cc)}
+            end
+          end
+          calc_alignment.call(el)
+          el.children.delete_if {|c| c.type == :html_element}
+
+          change_th_type = lambda do |c|
+            if c.type == :th
+              c.type = :td
+            else
+              c.children.each {|cc| change_th_type.call(cc)}
+            end
+          end
+          change_th_type.call(el)
+
+          if el.children.first.type == :tr
+            tbody = Element.new(:tbody)
+            tbody.children = el.children
+            el.children = [tbody]
+          end
+        end
+
+        def is_simple_table?(el)
+          only_phrasing_content = lambda do |c|
+            c.children.all? do |cc|
+              (cc.type == :text || !HTML_BLOCK_ELEMENTS.include?(cc.value)) && only_phrasing_content.call(cc)
+            end
+          end
+          check_cells = Proc.new do |c|
+            if c.value == 'th' || c.value == 'td'
+              return false if !only_phrasing_content.call(c)
+            else
+              c.children.each {|cc| check_cells.call(cc)}
+            end
+          end
+          check_cells.call(el)
+
+          nr_cells = 0
+          check_nr_cells = lambda do |t|
+            if t.value == 'tr'
+              count = t.children.select {|cc| cc.value == 'th' || cc.value == 'td'}.length
+              if count != nr_cells
+                if nr_cells == 0
+                  nr_cells = count
+                else
+                  nr_cells = -1
+                  break
+                end
+              end
+            else
+              t.children.each {|cc| check_nr_cells.call(cc)}
+            end
+          end
+          check_nr_cells.call(el)
+          return false if nr_cells == -1
+
+          alignment = nil
+          check_alignment = Proc.new do |t|
+            if t.value == 'tr'
+              cur_alignment = t.children.select {|cc| cc.value == 'th' || cc.value == 'td'}.map do |cell|
+                md = /text-align:\s+(center|left|right|justify|inherit)/.match(cell.attr['style'].to_s)
+                return false if md && (md[1] == 'justify' || md[1] == 'inherit')
+                md.nil? ? :default : md[1]
+              end
+              alignment = cur_alignment if alignment.nil?
+              return false if alignment != cur_alignment
+            else
+              t.children.each {|cc| check_alignment.call(cc)}
+            end
+          end
+          check_alignment.call(el)
+
+          check_rows = lambda do |t, type|
+            t.children.all? {|r| (r.value == 'tr' || r.type == :text) && r.children.all? {|c| c.value == type || c.type == :text}}
+          end
+          check_rows.call(el, 'td') ||
+            (el.children.all? do |t|
+               t.type == :text || (t.value == 'thead' && check_rows.call(t, 'th')) ||
+                 ((t.value == 'tfoot' || t.value == 'tbody') && check_rows.call(t, 'td'))
+             end && el.children.any? {|t| t.value == 'tbody'})
+        end
+
+        def convert_script(el)
+          if !is_math_tag?(el)
+            process_html_element(el)
+          else
+            handle_math_tag(el)
+          end
+        end
+
+        def is_math_tag?(el)
+          el.attr['type'].to_s =~ /\bmath\/tex\b/
+        end
+
+        def handle_math_tag(el)
+          set_basics(el, :math, :category => (el.attr['type'] =~ /mode=display/ ? :block : :span))
+          el.value = el.children.shift.value.sub(/\A(?:%\s*)?<!\[CDATA\[\n?(.*?)(?:\s%)?\]\]>\z/m, '\1')
+          el.attr.delete('type')
+        end
+
+      end
+
+      include Parser
+
+      # Parse the source string provided on initialization as HTML document.
+      def parse
+        @stack, @tree = [], @root
+        @src = Kramdown::Utils::StringScanner.new(adapt_source(source))
+
+        while true
+          if result = @src.scan(/\s*#{HTML_INSTRUCTION_RE}/)
+            @tree.children << Element.new(:xml_pi, result.strip, nil, :category => :block)
+          elsif result = @src.scan(/\s*#{HTML_DOCTYPE_RE}/)
+            # ignore the doctype
+          elsif result = @src.scan(/\s*#{HTML_COMMENT_RE}/)
+            @tree.children << Element.new(:xml_comment, result.strip, nil, :category => :block)
+          else
+            break
+          end
+        end
+
+        tag_handler = lambda do |c, closed, handle_body|
+          parse_raw_html(c, &tag_handler) if !closed && handle_body
+        end
+        parse_raw_html(@tree, &tag_handler)
+
+        ElementConverter.convert(@tree)
+      end
+
+    end
+
+  end
+
+end
+
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown.rb
new file mode 100644
index 0000000..aa8f796
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown.rb
@@ -0,0 +1,359 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'strscan'
+require 'stringio'
+
+#TODO: use [[:alpha:]] in all regexp to allow parsing of international values in 1.9.1
+#NOTE: use @src.pre_match only before other check/match?/... operations, otherwise the content is changed
+
+module Kramdown
+
+  module Parser
+
+    # Used for parsing a document in kramdown format.
+    #
+    # If you want to extend the functionality of the parser, you need to do the following:
+    #
+    # * Create a new subclass
+    # * add the needed parser methods
+    # * modify the @block_parsers and @span_parsers variables and add the names of your parser
+    #   methods
+    #
+    # Here is a small example for an extended parser class that parses ERB style tags as raw text if
+    # they are used as span-level elements (an equivalent block-level parser should probably also be
+    # made to handle the block case):
+    #
+    #   require 'kramdown/parser/kramdown'
+    #
+    #   class Kramdown::Parser::ERBKramdown < Kramdown::Parser::Kramdown
+    #
+    #      def initialize(source, options)
+    #        super
+    #        @span_parsers.unshift(:erb_tags)
+    #      end
+    #
+    #      ERB_TAGS_START = /<%.*?%>/
+    #
+    #      def parse_erb_tags
+    #        @src.pos += @src.matched_size
+    #        @tree.children << Element.new(:raw, @src.matched)
+    #      end
+    #      define_parser(:erb_tags, ERB_TAGS_START, '<%')
+    #
+    #   end
+    #
+    # The new parser can be used like this:
+    #
+    #   require 'kramdown/document'
+    #   # require the file with the above parser class
+    #
+    #   Kramdown::Document.new(input_text, :input => 'ERBKramdown').to_html
+    #
+    class Kramdown < Base
+
+      include ::Kramdown
+
+      # Create a new Kramdown parser object with the given +options+.
+      def initialize(source, options)
+        super
+
+        reset_env
+
+        @root.options[:abbrev_defs] = {}
+        @alds = {}
+        @footnotes = {}
+        @link_defs = {}
+        update_link_definitions(@options[:link_defs])
+
+        @block_parsers = [:blank_line, :codeblock, :codeblock_fenced, :blockquote, :atx_header,
+                          :horizontal_rule, :list, :definition_list, :block_html, :setext_header,
+                          :block_math, :table, :footnote_definition, :link_definition, :abbrev_definition,
+                          :block_extensions, :eob_marker, :paragraph]
+        @span_parsers =  [:emphasis, :codespan, :autolink, :span_html, :footnote_marker, :link, :smart_quotes, :inline_math,
+                         :span_extensions, :html_entity, :typographic_syms, :line_break, :escaped_chars]
+
+      end
+      private_class_method(:new, :allocate)
+
+
+      # The source string provided on initialization is parsed into the @root element.
+      def parse
+        configure_parser
+        parse_blocks(@root, adapt_source(source))
+        update_tree(@root)
+        replace_abbreviations(@root)
+        @footnotes.each {|name,data| update_tree(data[:marker].last.value) if data[:marker]}
+      end
+
+      #######
+      protected
+      #######
+
+      # :doc:
+      #
+      # Update the parser specific link definitions with the data from +link_defs+ (the value of the
+      # :link_defs option).
+      #
+      # The parameter +link_defs+ is a hash where the keys are possibly unnormalized link IDs and
+      # the values are two element arrays consisting of the link target and a title (can be +nil+).
+      def update_link_definitions(link_defs)
+        link_defs.each {|k,v| @link_defs[normalize_link_id(k)] = v}
+      end
+
+      # Adapt the object to allow parsing like specified in the options.
+      def configure_parser
+        @parsers = {}
+        (@block_parsers + @span_parsers).each do |name|
+          if self.class.has_parser?(name)
+            @parsers[name] = self.class.parser(name)
+          else
+            raise Kramdown::Error, "Unknown parser: #{name}"
+          end
+        end
+        @span_start, @span_start_re = span_parser_regexps
+      end
+
+      # Create the needed span parser regexps.
+      def span_parser_regexps(parsers = @span_parsers)
+        span_start = /#{parsers.map {|name| @parsers[name].span_start}.join('|')}/
+        [span_start, /(?=#{span_start})/]
+      end
+
+      # Parse all block-level elements in +text+ into the element +el+.
+      def parse_blocks(el, text = nil)
+        @stack.push([@tree, @src, @block_ial])
+        @tree, @block_ial = el, nil
+        @src = (text.nil? ? @src : ::Kramdown::Utils::StringScanner.new(text, el.options[:location]))
+
+        status = catch(:stop_block_parsing) do
+          while !@src.eos?
+            block_ial_set = @block_ial
+            @block_parsers.any? do |name|
+              if @src.check(@parsers[name].start_re)
+                send(@parsers[name].method)
+              else
+                false
+              end
+            end || begin
+              warning('Warning: this should not occur - no block parser handled the line')
+              add_text(@src.scan(/.*\n/))
+            end
+            @block_ial = nil if block_ial_set
+          end
+        end
+
+        @tree, @src, @block_ial = *@stack.pop
+        status
+      end
+
+      # Update the tree by parsing all :+raw_text+ elements with the span-level parser (resets the
+      # environment) and by updating the attributes from the IALs.
+      def update_tree(element)
+        last_blank = nil
+        element.children.map! do |child|
+          if child.type == :raw_text
+            last_blank = nil
+            reset_env(:src => ::Kramdown::Utils::StringScanner.new(child.value, element.options[:location]),
+                      :text_type => :text)
+            parse_spans(child)
+            child.children
+          elsif child.type == :eob
+            []
+          elsif child.type == :blank
+            if last_blank
+              last_blank.value << child.value
+              []
+            else
+              last_blank = child
+              child
+            end
+          else
+            last_blank = nil
+            update_tree(child)
+            update_attr_with_ial(child.attr, child.options[:ial]) if child.options[:ial]
+            update_raw_header_text(child) if child.type == :header
+            child
+          end
+        end.flatten!
+      end
+
+      # Parse all span-level elements in the source string of @src into +el+.
+      #
+      # If the parameter +stop_re+ (a regexp) is used, parsing is immediately stopped if the regexp
+      # matches and if no block is given or if a block is given and it returns +true+.
+      #
+      # The parameter +parsers+ can be used to specify the (span-level) parsing methods that should
+      # be used for parsing.
+      #
+      # The parameter +text_type+ specifies the type which should be used for created text nodes.
+      def parse_spans(el, stop_re = nil, parsers = nil, text_type = @text_type)
+        @stack.push([@tree, @text_type]) unless @tree.nil?
+        @tree, @text_type = el, text_type
+
+        span_start = @span_start
+        span_start_re = @span_start_re
+        span_start, span_start_re = span_parser_regexps(parsers) if parsers
+        parsers = parsers || @span_parsers
+
+        used_re = (stop_re.nil? ? span_start_re : /(?=#{Regexp.union(stop_re, span_start)})/)
+        stop_re_found = false
+        while !@src.eos? && !stop_re_found
+          if result = @src.scan_until(used_re)
+            add_text(result)
+            if stop_re && @src.check(stop_re)
+              stop_re_found = (block_given? ? yield : true)
+            end
+            processed = parsers.any? do |name|
+              if @src.check(@parsers[name].start_re)
+                send(@parsers[name].method)
+                true
+              else
+                false
+              end
+            end unless stop_re_found
+            add_text(@src.getch) if !processed && !stop_re_found
+          else
+            (add_text(@src.rest); @src.terminate) unless stop_re
+            break
+          end
+        end
+
+        @tree, @text_type = @stack.pop
+
+        stop_re_found
+      end
+
+      # Reset the current parsing environment. The parameter +env+ can be used to set initial
+      # values for one or more environment variables.
+      def reset_env(opts = {})
+        opts = {:text_type => :raw_text, :stack => []}.merge(opts)
+        @src = opts[:src]
+        @tree = opts[:tree]
+        @block_ial = opts[:block_ial]
+        @stack = opts[:stack]
+        @text_type = opts[:text_type]
+      end
+
+      # Return the current parsing environment.
+      def save_env
+        [@src, @tree, @block_ial, @stack,  @text_type]
+      end
+
+      # Restore the current parsing environment.
+      def restore_env(env)
+        @src, @tree, @block_ial, @stack,  @text_type = *env
+      end
+
+      # Update the given attributes hash +attr+ with the information from the inline attribute list
+      # +ial+ and all referenced ALDs.
+      def update_attr_with_ial(attr, ial)
+        ial[:refs].each do |ref|
+          update_attr_with_ial(attr, ref) if ref = @alds[ref]
+        end if ial[:refs]
+        ial.each do |k,v|
+          if k == IAL_CLASS_ATTR
+            attr[k] = (attr[k] || '') << " #{v}"
+            attr[k].lstrip!
+          elsif k.kind_of?(String)
+            attr[k] = v
+          end
+        end
+      end
+
+      # Update the raw header text for automatic ID generation.
+      def update_raw_header_text(header)
+        # DEPRECATED: option auto_id_stripping will be removed in 2.0 because then this will be the
+        # default behaviour
+        return unless @options[:auto_id_stripping]
+        raw_text = ''
+
+        append_text = lambda do |child|
+          if child.type == :text
+            raw_text << child.value
+          else
+            child.children.each {|c| append_text.call(c)}
+          end
+        end
+
+        append_text.call(header)
+        header.options[:raw_text] = raw_text
+      end
+
+      # Create a new block-level element, taking care of applying a preceding block IAL if it
+      # exists. This method should always be used for creating a block-level element!
+      def new_block_el(*args)
+        el = Element.new(*args)
+        el.options[:ial] = @block_ial if @block_ial && el.type != :blank && el.type != :eob
+        el
+      end
+
+      @@parsers = {}
+
+      # Struct class holding all the needed data for one block/span-level parser method.
+      Data = Struct.new(:name, :start_re, :span_start, :method)
+
+      # Add a parser method
+      #
+      # * with the given +name+,
+      # * using +start_re+ as start regexp
+      # * and, for span parsers, +span_start+ as a String that can be used in a regexp and
+      #   which identifies the starting character(s)
+      #
+      # to the registry. The method name is automatically derived from the +name+ or can explicitly
+      # be set by using the +meth_name+ parameter.
+      def self.define_parser(name, start_re, span_start = nil, meth_name = "parse_#{name}")
+        raise "A parser with the name #{name} already exists!" if @@parsers.has_key?(name)
+        @@parsers[name] = Data.new(name, start_re, span_start, meth_name)
+      end
+
+      # Return the Data structure for the parser +name+.
+      def self.parser(name = nil)
+        @@parsers[name]
+      end
+
+      # Return +true+ if there is a parser called +name+.
+      def self.has_parser?(name)
+        @@parsers.has_key?(name)
+      end
+
+      # Regexp for matching indentation (one tab or four spaces)
+      INDENT = /^(?:\t| {4})/
+      # Regexp for matching the optional space (zero or up to three spaces)
+      OPT_SPACE = / {0,3}/
+
+      require 'kramdown/parser/kramdown/blank_line'
+      require 'kramdown/parser/kramdown/eob'
+      require 'kramdown/parser/kramdown/paragraph'
+      require 'kramdown/parser/kramdown/header'
+      require 'kramdown/parser/kramdown/blockquote'
+      require 'kramdown/parser/kramdown/table'
+      require 'kramdown/parser/kramdown/codeblock'
+      require 'kramdown/parser/kramdown/horizontal_rule'
+      require 'kramdown/parser/kramdown/list'
+      require 'kramdown/parser/kramdown/link'
+      require 'kramdown/parser/kramdown/extensions'
+      require 'kramdown/parser/kramdown/footnote'
+      require 'kramdown/parser/kramdown/html'
+      require 'kramdown/parser/kramdown/escaped_chars'
+      require 'kramdown/parser/kramdown/html_entity'
+      require 'kramdown/parser/kramdown/line_break'
+      require 'kramdown/parser/kramdown/typographic_symbol'
+      require 'kramdown/parser/kramdown/autolink'
+      require 'kramdown/parser/kramdown/codespan'
+      require 'kramdown/parser/kramdown/emphasis'
+      require 'kramdown/parser/kramdown/smart_quotes'
+      require 'kramdown/parser/kramdown/math'
+      require 'kramdown/parser/kramdown/abbreviation'
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/abbreviation.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/abbreviation.rb
new file mode 100644
index 0000000..5bc369c
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/abbreviation.rb
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      ABBREV_DEFINITION_START = /^#{OPT_SPACE}\*\[(.+?)\]:(.*?)\n/
+
+      # Parse the link definition at the current location.
+      def parse_abbrev_definition
+        start_line_number = @src.current_line_number
+        @src.pos += @src.matched_size
+        abbrev_id, abbrev_text = @src[1], @src[2]
+        abbrev_text.strip!
+        warning("Duplicate abbreviation ID '#{abbrev_id}' on line #{start_line_number} - overwriting") if @root.options[:abbrev_defs][abbrev_id]
+        @root.options[:abbrev_defs][abbrev_id] = abbrev_text
+        @tree.children << Element.new(:eob, :abbrev_def)
+        true
+      end
+      define_parser(:abbrev_definition, ABBREV_DEFINITION_START)
+
+      # Replace the abbreviation text with elements.
+      def replace_abbreviations(el, regexps = nil)
+        return if @root.options[:abbrev_defs].empty?
+        if !regexps
+          sorted_abbrevs = @root.options[:abbrev_defs].keys.sort {|a,b| b.length <=> a.length}
+          regexps = [Regexp.union(*sorted_abbrevs.map {|k| /#{Regexp.escape(k)}/})]
+          regexps << /(?=(?:\W|^)#{regexps.first}(?!\w))/ # regexp should only match on word boundaries
+        end
+        el.children.map! do |child|
+          if child.type == :text
+            if child.value =~ regexps.first
+              result = []
+              strscan = Kramdown::Utils::StringScanner.new(child.value)
+              while temp = strscan.scan_until(regexps.last)
+                abbr = strscan.scan(regexps.first) # begin of line case of abbr with \W char as first one
+                if abbr.nil?
+                  temp << strscan.scan(/\W|^/)
+                  abbr = strscan.scan(regexps.first)
+                end
+                result << Element.new(:text, temp) << Element.new(:abbreviation, abbr)
+              end
+              result << Element.new(:text, strscan.rest)
+            else
+              child
+            end
+          else
+            replace_abbreviations(child, regexps)
+            child
+          end
+        end.flatten!
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/autolink.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/autolink.rb
new file mode 100644
index 0000000..4161d41
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/autolink.rb
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      if RUBY_VERSION == '1.8.5'
+        ACHARS = '\w\x80-\xFF'
+      elsif RUBY_VERSION < '1.9.0'
+        ACHARS = '\w'
+      else
+        ACHARS = '[[:alnum:]]'
+      end
+      AUTOLINK_START_STR = "<((mailto|https?|ftps?):.+?|[-.#{ACHARS}]+@[-#{ACHARS}]+(?:\.[-#{ACHARS}]+)*\.[a-z]+)>"
+      AUTOLINK_START = /#{AUTOLINK_START_STR}/u
+
+      # Parse the autolink at the current location.
+      def parse_autolink
+        start_line_number = @src.current_line_number
+        @src.pos += @src.matched_size
+        href = (@src[2].nil? ? "mailto:#{@src[1]}" : @src[1])
+        el = Element.new(:a, nil, {'href' => href}, :location => start_line_number)
+        add_text(@src[1].sub(/^mailto:/, ''), el)
+        @tree.children << el
+      end
+      define_parser(:autolink, AUTOLINK_START, '<')
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/blank_line.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/blank_line.rb
new file mode 100644
index 0000000..f1c52c0
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/blank_line.rb
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      BLANK_LINE = /(?:^\s*\n)+/
+
+      # Parse the blank line at the current postition.
+      def parse_blank_line
+        @src.pos += @src.matched_size
+        if @tree.children.last && @tree.children.last.type == :blank
+          @tree.children.last.value << @src.matched
+        else
+          @tree.children << new_block_el(:blank, @src.matched)
+        end
+        true
+      end
+      define_parser(:blank_line, BLANK_LINE)
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/block_boundary.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/block_boundary.rb
new file mode 100644
index 0000000..52e4744
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/block_boundary.rb
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'kramdown/parser/kramdown/extensions'
+require 'kramdown/parser/kramdown/blank_line'
+require 'kramdown/parser/kramdown/eob'
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      BLOCK_BOUNDARY = /#{BLANK_LINE}|#{EOB_MARKER}|#{IAL_BLOCK_START}|\Z/
+
+      # Return +true+ if we are after a block boundary.
+      def after_block_boundary?
+        !@tree.children.last || @tree.children.last.type == :blank ||
+          (@tree.children.last.type == :eob && @tree.children.last.value.nil?) || @block_ial
+      end
+
+      # Return +true+ if we are before a block boundary.
+      def before_block_boundary?
+        @src.check(self.class::BLOCK_BOUNDARY)
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/blockquote.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/blockquote.rb
new file mode 100644
index 0000000..aaf0a06
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/blockquote.rb
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'kramdown/parser/kramdown/blank_line'
+require 'kramdown/parser/kramdown/extensions'
+require 'kramdown/parser/kramdown/eob'
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      BLOCKQUOTE_START = /^#{OPT_SPACE}> ?/
+
+      # Parse the blockquote at the current location.
+      def parse_blockquote
+        start_line_number = @src.current_line_number
+        result = @src.scan(PARAGRAPH_MATCH)
+        while !@src.match?(self.class::LAZY_END)
+          result << @src.scan(PARAGRAPH_MATCH)
+        end
+        result.gsub!(BLOCKQUOTE_START, '')
+
+        el = new_block_el(:blockquote, nil, nil, :location => start_line_number)
+        @tree.children << el
+        parse_blocks(el, result)
+        true
+      end
+      define_parser(:blockquote, BLOCKQUOTE_START)
+
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/codeblock.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/codeblock.rb
new file mode 100644
index 0000000..345a130
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/codeblock.rb
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'kramdown/parser/kramdown/blank_line'
+require 'kramdown/parser/kramdown/extensions'
+require 'kramdown/parser/kramdown/eob'
+require 'kramdown/parser/kramdown/paragraph'
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      CODEBLOCK_START = INDENT
+      CODEBLOCK_MATCH = /(?:#{BLANK_LINE}?(?:#{INDENT}[ \t]*\S.*\n)+(?:(?!#{IAL_BLOCK_START}|#{EOB_MARKER}|^#{OPT_SPACE}#{LAZY_END_HTML_STOP}|^#{OPT_SPACE}#{LAZY_END_HTML_START})^[ \t]*\S.*\n)*)*/
+
+      # Parse the indented codeblock at the current location.
+      def parse_codeblock
+        start_line_number = @src.current_line_number
+        data = @src.scan(self.class::CODEBLOCK_MATCH)
+        data.gsub!(/\n( {0,3}\S)/, ' \\1')
+        data.gsub!(INDENT, '')
+        @tree.children << new_block_el(:codeblock, data, nil, :location => start_line_number)
+        true
+      end
+      define_parser(:codeblock, CODEBLOCK_START)
+
+
+      FENCED_CODEBLOCK_START = /^~{3,}/
+      FENCED_CODEBLOCK_MATCH = /^((~){3,})\s*?(\w+)?\s*?\n(.*?)^\1\2*\s*?\n/m
+
+      # Parse the fenced codeblock at the current location.
+      def parse_codeblock_fenced
+        if @src.check(self.class::FENCED_CODEBLOCK_MATCH)
+          start_line_number = @src.current_line_number
+          @src.pos += @src.matched_size
+          el = new_block_el(:codeblock, @src[4], nil, :location => start_line_number)
+          lang = @src[3].to_s.strip
+          el.attr['class'] = "language-#{lang}" unless lang.empty?
+          @tree.children << el
+          true
+        else
+          false
+        end
+      end
+      define_parser(:codeblock_fenced, FENCED_CODEBLOCK_START)
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/codespan.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/codespan.rb
new file mode 100644
index 0000000..aeb8e20
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/codespan.rb
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      CODESPAN_DELIMITER = /`+/
+
+      # Parse the codespan at the current scanner location.
+      def parse_codespan
+        start_line_number = @src.current_line_number
+        result = @src.scan(CODESPAN_DELIMITER)
+        simple = (result.length == 1)
+        reset_pos = @src.pos
+
+        if simple && @src.pre_match =~ /\s\Z/ && @src.match?(/\s/)
+          add_text(result)
+          return
+        end
+
+        if text = @src.scan_until(/#{result}/)
+          text.sub!(/#{result}\Z/, '')
+          if !simple
+            text = text[1..-1] if text[0..0] == ' '
+            text = text[0..-2] if text[-1..-1] == ' '
+          end
+          @tree.children << Element.new(:codespan, text, nil, :location => start_line_number)
+        else
+          @src.pos = reset_pos
+          add_text(result)
+        end
+      end
+      define_parser(:codespan, CODESPAN_DELIMITER, '`')
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/emphasis.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/emphasis.rb
new file mode 100644
index 0000000..953e7a6
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/emphasis.rb
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      EMPHASIS_START = /(?:\*\*?|__?)/
+
+      # Parse the emphasis at the current location.
+      def parse_emphasis
+        start_line_number = @src.current_line_number
+        result = @src.scan(EMPHASIS_START)
+        element = (result.length == 2 ? :strong : :em)
+        type = result[0..0]
+        reset_pos = @src.pos
+
+        if (type == '_' && @src.pre_match =~ /[[:alnum:]]\z/ && @src.check(/[[:alnum:]]/)) || @src.check(/\s/) ||
+            @tree.type == element || @stack.any? {|el, _| el.type == element}
+          add_text(result)
+          return
+        end
+
+        sub_parse = lambda do |delim, elem|
+          el = Element.new(elem, nil, nil, :location => start_line_number)
+          stop_re = /#{Regexp.escape(delim)}/
+          found = parse_spans(el, stop_re) do
+            (@src.pre_match[-1, 1] !~ /\s/) &&
+              (elem != :em || !@src.match?(/#{Regexp.escape(delim*2)}(?!#{Regexp.escape(delim)})/)) &&
+              (type != '_' || !@src.match?(/#{Regexp.escape(delim)}[[:alnum:]]/)) && el.children.size > 0
+          end
+          [found, el, stop_re]
+        end
+
+        found, el, stop_re = sub_parse.call(result, element)
+        if !found && element == :strong && @tree.type != :em
+          @src.pos = reset_pos - 1
+          found, el, stop_re = sub_parse.call(type, :em)
+        end
+        if found
+          @src.scan(stop_re)
+          @tree.children << el
+        else
+          @src.pos = reset_pos
+          add_text(result)
+        end
+      end
+      define_parser(:emphasis, EMPHASIS_START, '\*|_')
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/eob.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/eob.rb
new file mode 100644
index 0000000..c773037
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/eob.rb
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      EOB_MARKER = /^\^\s*?\n/
+
+      # Parse the EOB marker at the current location.
+      def parse_eob_marker
+        @src.pos += @src.matched_size
+        @tree.children << new_block_el(:eob)
+        true
+      end
+      define_parser(:eob_marker, EOB_MARKER)
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/escaped_chars.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/escaped_chars.rb
new file mode 100644
index 0000000..0f76aa6
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/escaped_chars.rb
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      ESCAPED_CHARS = /\\([\\.*_+`<>()\[\]{}#!:|"'\$=-])/
+
+      # Parse the backslash-escaped character at the current location.
+      def parse_escaped_chars
+        @src.pos += @src.matched_size
+        add_text(@src[1])
+      end
+      define_parser(:escaped_chars, ESCAPED_CHARS, '\\\\')
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/extensions.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/extensions.rb
new file mode 100644
index 0000000..a4a1ab3
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/extensions.rb
@@ -0,0 +1,201 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      IAL_CLASS_ATTR = 'class'
+
+      # Parse the string +str+ and extract all attributes and add all found attributes to the hash
+      # +opts+.
+      def parse_attribute_list(str, opts)
+        return if str.strip.empty? || str.strip == ':'
+        attrs = str.scan(ALD_TYPE_ANY)
+        attrs.each do |key, sep, val, ref, id_and_or_class, _, _|
+          if ref
+            (opts[:refs] ||= []) << ref
+          elsif id_and_or_class
+            id_and_or_class.scan(ALD_TYPE_ID_OR_CLASS).each do |id_attr, class_attr|
+              if class_attr
+                opts[IAL_CLASS_ATTR] = (opts[IAL_CLASS_ATTR] || '') << " #{class_attr}"
+                opts[IAL_CLASS_ATTR].lstrip!
+              else
+                opts['id'] = id_attr
+              end
+            end
+          else
+            val.gsub!(/\\(\}|#{sep})/, "\\1")
+            opts[key] = val
+          end
+        end
+        warning("No or invalid attributes found in IAL/ALD content: #{str}") if attrs.length == 0
+      end
+
+      # Update the +ial+ with the information from the inline attribute list +opts+.
+      def update_ial_with_ial(ial, opts)
+        (ial[:refs] ||= []) << opts[:refs]
+        opts.each do |k,v|
+          if k == IAL_CLASS_ATTR
+            ial[k] = (ial[k] || '') << " #{v}"
+            ial[k].lstrip!
+          elsif k.kind_of?(String)
+            ial[k] = v
+          end
+        end
+      end
+
+      # Parse the generic extension at the current point. The parameter +type+ can either be :block
+      # or :span depending whether we parse a block or span extension tag.
+      def parse_extension_start_tag(type)
+        orig_pos = @src.pos
+        start_line_number = @src.current_line_number
+        @src.pos += @src.matched_size
+
+        error_block = lambda do |msg|
+          warning(msg)
+          @src.pos = orig_pos
+          add_text(@src.getch) if type == :span
+          false
+        end
+
+        if @src[4] || @src.matched == '{:/}'
+          name = (@src[4] ? "for '#{@src[4]}' " : '')
+          return error_block.call("Invalid extension stop tag #{name} found on line #{start_line_number} - ignoring it")
+        end
+
+        ext = @src[1]
+        opts = {}
+        body = nil
+        parse_attribute_list(@src[2] || '', opts)
+
+        if !@src[3]
+          stop_re = (type == :block ? /#{EXT_BLOCK_STOP_STR % ext}/ : /#{EXT_STOP_STR % ext}/)
+          if result = @src.scan_until(stop_re)
+            body = result.sub!(stop_re, '')
+            body.chomp! if type == :block
+          else
+            return error_block.call("No stop tag for extension '#{ext}' found on line #{start_line_number} - ignoring it")
+          end
+        end
+
+        if !handle_extension(ext, opts, body, type)
+          error_block.call("Invalid extension with name '#{ext}' specified on line #{start_line_number} - ignoring it")
+        else
+          true
+        end
+      end
+
+      def handle_extension(name, opts, body, type)
+        case name
+        when 'comment'
+          @tree.children << Element.new(:comment, body, nil, :category => type) if body.kind_of?(String)
+          true
+        when 'nomarkdown'
+          @tree.children << Element.new(:raw, body, nil, :category => type, :type => opts['type'].to_s.split(/\s+/)) if body.kind_of?(String)
+          true
+        when 'options'
+          opts.select do |k,v|
+            k = k.to_sym
+            if Kramdown::Options.defined?(k)
+              begin
+                val = Kramdown::Options.parse(k, v)
+                @options[k] = val
+                (@root.options[:options] ||= {})[k] = val
+              rescue
+              end
+              false
+            else
+              true
+            end
+          end.each do |k,v|
+            warning("Unknown kramdown option '#{k}'")
+          end
+          @tree.children << Element.new(:eob, :extension) if type == :block
+          true
+        else
+          false
+        end
+      end
+
+
+      ALD_ID_CHARS = /[\w-]/
+      ALD_ANY_CHARS = /\\\}|[^\}]/
+      ALD_ID_NAME = /\w#{ALD_ID_CHARS}*/
+      ALD_TYPE_KEY_VALUE_PAIR = /(#{ALD_ID_NAME})=("|')((?:\\\}|\\\2|[^\}\2])*?)\2/
+      ALD_TYPE_CLASS_NAME = /\.(#{ALD_ID_NAME})/
+      ALD_TYPE_ID_NAME = /#([A-Za-z][\w:-]*)/
+      ALD_TYPE_ID_OR_CLASS = /#{ALD_TYPE_ID_NAME}|#{ALD_TYPE_CLASS_NAME}/
+      ALD_TYPE_ID_OR_CLASS_MULTI = /((?:#{ALD_TYPE_ID_NAME}|#{ALD_TYPE_CLASS_NAME})+)/
+      ALD_TYPE_REF = /(#{ALD_ID_NAME})/
+      ALD_TYPE_ANY = /(?:\A|\s)(?:#{ALD_TYPE_KEY_VALUE_PAIR}|#{ALD_TYPE_REF}|#{ALD_TYPE_ID_OR_CLASS_MULTI})(?=\s|\Z)/
+      ALD_START = /^#{OPT_SPACE}\{:(#{ALD_ID_NAME}):(#{ALD_ANY_CHARS}+)\}\s*?\n/
+
+      EXT_STOP_STR = "\\{:/(%s)?\\}"
+      EXT_START_STR = "\\{::(\\w+)(?:\\s(#{ALD_ANY_CHARS}*?)|)(\\/)?\\}"
+      EXT_BLOCK_START = /^#{OPT_SPACE}(?:#{EXT_START_STR}|#{EXT_STOP_STR % ALD_ID_NAME})\s*?\n/
+      EXT_BLOCK_STOP_STR = "^#{OPT_SPACE}#{EXT_STOP_STR}\s*?\n"
+
+      IAL_BLOCK = /\{:(?!:|\/)(#{ALD_ANY_CHARS}+)\}\s*?\n/
+      IAL_BLOCK_START = /^#{OPT_SPACE}#{IAL_BLOCK}/
+
+      BLOCK_EXTENSIONS_START = /^#{OPT_SPACE}\{:/
+
+      # Parse one of the block extensions (ALD, block IAL or generic extension) at the current
+      # location.
+      def parse_block_extensions
+        if @src.scan(ALD_START)
+          parse_attribute_list(@src[2], @alds[@src[1]] ||= Utils::OrderedHash.new)
+          @tree.children << Element.new(:eob, :ald)
+          true
+        elsif @src.check(EXT_BLOCK_START)
+          parse_extension_start_tag(:block)
+        elsif @src.scan(IAL_BLOCK_START)
+          if @tree.children.last && @tree.children.last.type != :blank && @tree.children.last.type != :eob
+            parse_attribute_list(@src[1], @tree.children.last.options[:ial] ||= Utils::OrderedHash.new)
+            @tree.children << Element.new(:eob, :ial) unless @src.check(IAL_BLOCK_START)
+          else
+            parse_attribute_list(@src[1], @block_ial = Utils::OrderedHash.new)
+          end
+          true
+        else
+          false
+        end
+      end
+      define_parser(:block_extensions, BLOCK_EXTENSIONS_START)
+
+
+      EXT_SPAN_START = /#{EXT_START_STR}|#{EXT_STOP_STR % ALD_ID_NAME}/
+      IAL_SPAN_START = /\{:(#{ALD_ANY_CHARS}+)\}/
+      SPAN_EXTENSIONS_START = /\{:/
+
+      # Parse the extension span at the current location.
+      def parse_span_extensions
+        if @src.check(EXT_SPAN_START)
+          parse_extension_start_tag(:span)
+        elsif @src.check(IAL_SPAN_START)
+          if @tree.children.last && @tree.children.last.type != :text
+            @src.pos += @src.matched_size
+            attr = Utils::OrderedHash.new
+            parse_attribute_list(@src[1], attr)
+            update_ial_with_ial(@tree.children.last.options[:ial] ||= Utils::OrderedHash.new, attr)
+            update_attr_with_ial(@tree.children.last.attr, attr)
+          else
+            warning("Found span IAL after text - ignoring it")
+            add_text(@src.getch)
+          end
+        else
+          add_text(@src.getch)
+        end
+      end
+      define_parser(:span_extensions, SPAN_EXTENSIONS_START, '\{:')
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/footnote.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/footnote.rb
new file mode 100644
index 0000000..ac801f3
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/footnote.rb
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'kramdown/parser/kramdown/extensions'
+require 'kramdown/parser/kramdown/blank_line'
+require 'kramdown/parser/kramdown/codeblock'
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      FOOTNOTE_DEFINITION_START = /^#{OPT_SPACE}\[\^(#{ALD_ID_NAME})\]:\s*?(.*?\n#{CODEBLOCK_MATCH})/
+
+      # Parse the foot note definition at the current location.
+      def parse_footnote_definition
+        start_line_number = @src.current_line_number
+        @src.pos += @src.matched_size
+
+        el = Element.new(:footnote_def, nil, nil, :location => start_line_number)
+        parse_blocks(el, @src[2].gsub(INDENT, ''))
+        warning("Duplicate footnote name '#{@src[1]}' - overwriting") if @footnotes[@src[1]]
+        (@footnotes[@src[1]] = {})[:content] = el
+        @tree.children << Element.new(:eob, :footnote_def, nil, :location => start_line_number)
+        true
+      end
+      define_parser(:footnote_definition, FOOTNOTE_DEFINITION_START)
+
+
+      FOOTNOTE_MARKER_START = /\[\^(#{ALD_ID_NAME})\]/
+
+      # Parse the footnote marker at the current location.
+      def parse_footnote_marker
+        start_line_number = @src.current_line_number
+        @src.pos += @src.matched_size
+        fn_def = @footnotes[@src[1]]
+        if fn_def
+          fn_def[:marker] ||= []
+          fn_def[:marker].push(Element.new(:footnote, fn_def[:content], nil, :name => @src[1], :location => start_line_number))
+          fn_def[:stack] = [@stack.map {|s| s.first}, @tree, fn_def[:marker]].flatten.compact
+          @tree.children << fn_def[:marker].last
+        else
+          warning("Footnote definition for '#{@src[1]}' not found on line #{start_line_number}")
+          add_text(@src.matched)
+        end
+      end
+      define_parser(:footnote_marker, FOOTNOTE_MARKER_START, '\[')
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/header.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/header.rb
new file mode 100644
index 0000000..ca7a997
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/header.rb
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'kramdown/parser/kramdown/block_boundary'
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      HEADER_ID=/(?:[ \t]+\{#([A-Za-z][\w:-]*)\})?/
+      SETEXT_HEADER_START = /^(#{OPT_SPACE}[^ \t].*?)#{HEADER_ID}[ \t]*?\n(-|=)+\s*?\n/
+
+      # Parse the Setext header at the current location.
+      def parse_setext_header
+        return false if !after_block_boundary?
+
+        start_line_number = @src.current_line_number
+        @src.pos += @src.matched_size
+        text, id, level = @src[1], @src[2], @src[3]
+        text.strip!
+        el = new_block_el(:header, nil, nil, :level => (level == '-' ? 2 : 1), :raw_text => text, :location => start_line_number)
+        add_text(text, el)
+        el.attr['id'] = id if id
+        @tree.children << el
+        true
+      end
+      define_parser(:setext_header, SETEXT_HEADER_START)
+
+
+      ATX_HEADER_START = /^\#{1,6}/
+      ATX_HEADER_MATCH = /^(\#{1,6})(.+?)\s*?#*#{HEADER_ID}\s*?\n/
+
+      # Parse the Atx header at the current location.
+      def parse_atx_header
+        return false if !after_block_boundary?
+
+        start_line_number = @src.current_line_number
+        @src.check(ATX_HEADER_MATCH)
+        level, text, id = @src[1], @src[2].to_s.strip, @src[3]
+        return false if text.empty?
+
+        @src.pos += @src.matched_size
+        el = new_block_el(:header, nil, nil, :level => level.length, :raw_text => text, :location => start_line_number)
+        add_text(text, el)
+        el.attr['id'] = id if id
+        @tree.children << el
+        true
+      end
+      define_parser(:atx_header, ATX_HEADER_START)
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/horizontal_rule.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/horizontal_rule.rb
new file mode 100644
index 0000000..d5ea684
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/horizontal_rule.rb
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      HR_START = /^#{OPT_SPACE}(\*|-|_)[ \t]*\1[ \t]*\1(\1|[ \t])*\n/
+
+      # Parse the horizontal rule at the current location.
+      def parse_horizontal_rule
+        start_line_number = @src.current_line_number
+        @src.pos += @src.matched_size
+        @tree.children << new_block_el(:hr, nil, nil, :location => start_line_number)
+        true
+      end
+      define_parser(:horizontal_rule, HR_START)
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/html.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/html.rb
new file mode 100644
index 0000000..01e6a95
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/html.rb
@@ -0,0 +1,158 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'kramdown/parser/html'
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      include Kramdown::Parser::Html::Parser
+
+      # Mapping of markdown attribute value to content model. I.e. :raw when "0", :default when "1"
+      # (use default content model for the HTML element), :span when "span", :block when block and
+      # for everything else +nil+ is returned.
+      HTML_MARKDOWN_ATTR_MAP = {"0" => :raw, "1" => :default, "span" => :span, "block" => :block}
+
+      TRAILING_WHITESPACE = /[ \t]*\n/
+
+      def handle_kramdown_html_tag(el, closed, handle_body)
+        el.options[:ial] = @block_ial if @block_ial
+
+        content_model = if @tree.type != :html_element || @tree.options[:content_model] != :raw
+                          (@options[:parse_block_html] ? HTML_CONTENT_MODEL[el.value] : :raw)
+                        else
+                          :raw
+                        end
+        if val = HTML_MARKDOWN_ATTR_MAP[el.attr.delete('markdown')]
+          content_model = (val == :default ? HTML_CONTENT_MODEL[el.value] : val)
+        end
+
+        @src.scan(TRAILING_WHITESPACE) if content_model == :block
+        el.options[:content_model] = content_model
+        el.options[:is_closed] = closed
+
+        if !closed && handle_body
+          if content_model == :block
+            if !parse_blocks(el)
+              warning("Found no end tag for '#{el.value}' - auto-closing it")
+            end
+          elsif content_model == :span
+            curpos = @src.pos
+            if @src.scan_until(/(?=<\/#{el.value}\s*>)/mi)
+              add_text(extract_string(curpos... at src.pos, @src), el)
+              @src.scan(HTML_TAG_CLOSE_RE)
+            else
+              add_text(@src.rest, el)
+              @src.terminate
+              warning("Found no end tag for '#{el.value}' - auto-closing it")
+            end
+          else
+            parse_raw_html(el, &method(:handle_kramdown_html_tag))
+          end
+          @src.scan(TRAILING_WHITESPACE) unless (@tree.type == :html_element && @tree.options[:content_model] == :raw)
+        end
+      end
+
+
+      HTML_BLOCK_START = /^#{OPT_SPACE}<(#{REXML::Parsers::BaseParser::UNAME_STR}|\?|!--|\/)/
+
+      # Parse the HTML at the current position as block-level HTML.
+      def parse_block_html
+        if result = @src.scan(HTML_COMMENT_RE)
+          @tree.children << Element.new(:xml_comment, result, nil, :category => :block)
+          @src.scan(TRAILING_WHITESPACE)
+          true
+        elsif result = @src.scan(HTML_INSTRUCTION_RE)
+          @tree.children << Element.new(:xml_pi, result, nil, :category => :block)
+          @src.scan(TRAILING_WHITESPACE)
+          true
+        else
+          if result = @src.check(/^#{OPT_SPACE}#{HTML_TAG_RE}/) && !HTML_SPAN_ELEMENTS.include?(@src[1].downcase)
+            @src.pos += @src.matched_size
+            handle_html_start_tag(&method(:handle_kramdown_html_tag))
+            Kramdown::Parser::Html::ElementConverter.convert(@root, @tree.children.last) if @options[:html_to_native]
+            true
+          elsif result = @src.check(/^#{OPT_SPACE}#{HTML_TAG_CLOSE_RE}/) && !HTML_SPAN_ELEMENTS.include?(@src[1].downcase)
+            name = @src[1].downcase
+
+            if @tree.type == :html_element && @tree.value == name
+              @src.pos += @src.matched_size
+              throw :stop_block_parsing, :found
+            else
+              false
+            end
+          else
+            false
+          end
+        end
+      end
+      define_parser(:block_html, HTML_BLOCK_START)
+
+
+      HTML_SPAN_START = /<(#{REXML::Parsers::BaseParser::UNAME_STR}|\?|!--|\/)/
+
+      # Parse the HTML at the current position as span-level HTML.
+      def parse_span_html
+        if result = @src.scan(HTML_COMMENT_RE)
+          @tree.children << Element.new(:xml_comment, result, nil, :category => :span)
+        elsif result = @src.scan(HTML_INSTRUCTION_RE)
+          @tree.children << Element.new(:xml_pi, result, nil, :category => :span)
+        elsif result = @src.scan(HTML_TAG_CLOSE_RE)
+          warning("Found invalidly used HTML closing tag for '#{@src[1]}'")
+          add_text(result)
+        elsif result = @src.scan(HTML_TAG_RE)
+          tag_name = @src[1].downcase
+          if HTML_BLOCK_ELEMENTS.include?(tag_name)
+            warning("Found block HTML tag '#{tag_name}' in span-level text")
+            add_text(result)
+            return
+          end
+
+          attrs = Utils::OrderedHash.new
+          @src[2].scan(HTML_ATTRIBUTE_RE).each {|name,sep,val| attrs[name.downcase] = (val || '').gsub(/\n+/, ' ')}
+
+          do_parsing = (HTML_CONTENT_MODEL[tag_name] == :raw || @tree.options[:content_model] == :raw ? false : @options[:parse_span_html])
+          if val = HTML_MARKDOWN_ATTR_MAP[attrs.delete('markdown')]
+            if val == :block
+              warning("Cannot use block-level parsing in span-level HTML tag - using default mode")
+            elsif val == :span
+              do_parsing = true
+            elsif val == :default
+              do_parsing = HTML_CONTENT_MODEL[tag_name] != :raw
+            elsif val == :raw
+              do_parsing = false
+            end
+          end
+
+          el = Element.new(:html_element, tag_name, attrs, :category => :span,
+                           :content_model => (do_parsing ? :span : :raw), :is_closed => !!@src[4])
+          @tree.children << el
+          stop_re = /<\/#{Regexp.escape(tag_name)}\s*>/i
+          if !@src[4] && HTML_ELEMENTS_WITHOUT_BODY.include?(el.value)
+            warning("The HTML tag '#{el.value}' cannot have any content - auto-closing it")
+          elsif !@src[4]
+            if parse_spans(el, stop_re, (do_parsing ? nil : [:span_html]))
+              @src.scan(stop_re)
+            else
+              warning("Found no end tag for '#{el.value}' - auto-closing it")
+              add_text(@src.rest, el)
+              @src.terminate
+            end
+          end
+          Kramdown::Parser::Html::ElementConverter.convert(@root, el) if @options[:html_to_native]
+        else
+          add_text(@src.getch)
+        end
+      end
+      define_parser(:span_html, HTML_SPAN_START, '<')
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/html_entity.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/html_entity.rb
new file mode 100644
index 0000000..519cee4
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/html_entity.rb
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'kramdown/parser/html'
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      # Parse the HTML entity at the current location.
+      def parse_html_entity
+        start_line_number = @src.current_line_number
+        @src.pos += @src.matched_size
+        begin
+          @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity(@src[1] || (@src[2] && @src[2].to_i) || @src[3].hex),
+                                        nil, :original => @src.matched, :location => start_line_number)
+        rescue ::Kramdown::Error
+          @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('amp'),
+                                        nil, :location => start_line_number)
+          add_text(@src.matched[1..-1])
+        end
+      end
+      define_parser(:html_entity, Kramdown::Parser::Html::Constants::HTML_ENTITY_RE, '&')
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/line_break.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/line_break.rb
new file mode 100644
index 0000000..fb9eb55
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/line_break.rb
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      LINE_BREAK = /(  |\\\\)(?=\n)/
+
+      # Parse the line break at the current location.
+      def parse_line_break
+        @src.pos += @src.matched_size
+        @tree.children << Element.new(:br)
+      end
+      define_parser(:line_break, LINE_BREAK, '(  |\\\\)(?=\n)')
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/link.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/link.rb
new file mode 100644
index 0000000..53cda6c
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/link.rb
@@ -0,0 +1,138 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'kramdown/parser/kramdown/escaped_chars'
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      # Normalize the link identifier.
+      def normalize_link_id(id)
+        id.gsub(/[\s\n]+/, ' ').downcase
+      end
+
+      LINK_DEFINITION_START = /^#{OPT_SPACE}\[([^\n\]]+)\]:[ \t]*(?:<(.*?)>|([^'"\n]*?\S[^'"\n]*?))[ \t]*?(?:\n?[ \t]*?(["'])(.+?)\4[ \t]*?)?\n/
+
+      # Parse the link definition at the current location.
+      def parse_link_definition
+        @src.pos += @src.matched_size
+        link_id, link_url, link_title = normalize_link_id(@src[1]), @src[2] || @src[3], @src[5]
+        warning("Duplicate link ID '#{link_id}' on line #{@src.current_line_number} - overwriting") if @link_defs[link_id]
+        @link_defs[link_id] = [link_url, link_title]
+        @tree.children << Element.new(:eob, :link_def)
+        true
+      end
+      define_parser(:link_definition, LINK_DEFINITION_START)
+
+
+      # This helper methods adds the approriate attributes to the element +el+ of type +a+ or +img+
+      # and the element itself to the @tree.
+      def add_link(el, href, title, alt_text = nil)
+        if el.type == :a
+          el.attr['href'] = href
+        else
+          el.attr['src'] = href
+          el.attr['alt'] = alt_text
+          el.children.clear
+        end
+        el.attr['title'] = title if title
+        @tree.children << el
+      end
+
+      LINK_BRACKET_STOP_RE = /(\])|!?\[/
+      LINK_PAREN_STOP_RE = /(\()|(\))|\s(?=['"])/
+      LINK_INLINE_ID_RE = /\s*?\[([^\]]+)?\]/
+      LINK_INLINE_TITLE_RE = /\s*?(["'])(.+?)\1\s*?\)/m
+      LINK_START = /!?\[(?=[^^])/
+
+      # Parse the link at the current scanner position. This method is used to parse normal links as
+      # well as image links.
+      def parse_link
+        start_line_number = @src.current_line_number
+        result = @src.scan(LINK_START)
+        reset_pos = @src.pos
+
+        link_type = (result =~ /^!/ ? :img : :a)
+
+        # no nested links allowed
+        if link_type == :a && (@tree.type == :img || @tree.type == :a || @stack.any? {|t,s| t && (t.type == :img || t.type == :a)})
+          add_text(result)
+          return
+        end
+        el = Element.new(link_type, nil, nil, :location => start_line_number)
+
+        count = 1
+        found = parse_spans(el, LINK_BRACKET_STOP_RE) do
+          count = count + (@src[1] ? -1 : 1)
+          count - el.children.select {|c| c.type == :img}.size == 0
+        end
+        if !found || (link_type == :a && el.children.empty?)
+          @src.pos = reset_pos
+          add_text(result)
+          return
+        end
+        alt_text = extract_string(reset_pos... at src.pos, @src).gsub(ESCAPED_CHARS, '\1')
+        @src.scan(LINK_BRACKET_STOP_RE)
+
+        # reference style link or no link url
+        if @src.scan(LINK_INLINE_ID_RE) || !@src.check(/\(/)
+          link_id = normalize_link_id(@src[1] || alt_text)
+          if @link_defs.has_key?(link_id)
+            add_link(el, @link_defs[link_id].first, @link_defs[link_id].last, alt_text)
+          else
+            warning("No link definition for link ID '#{link_id}' found")
+            @src.pos = reset_pos
+            add_text(result)
+          end
+          return
+        end
+
+        # link url in parentheses
+        if @src.scan(/\(<(.*?)>/)
+          link_url = @src[1]
+          if @src.scan(/\)/)
+            add_link(el, link_url, nil, alt_text)
+            return
+          end
+        else
+          link_url = ''
+          nr_of_brackets = 0
+          while temp = @src.scan_until(LINK_PAREN_STOP_RE)
+            link_url << temp
+            if @src[2]
+              nr_of_brackets -= 1
+              break if nr_of_brackets == 0
+            elsif @src[1]
+              nr_of_brackets += 1
+            else
+              break
+            end
+          end
+          link_url = link_url[1..-2]
+          link_url.strip!
+
+          if nr_of_brackets == 0
+            add_link(el, link_url, nil, alt_text)
+            return
+          end
+        end
+
+        if @src.scan(LINK_INLINE_TITLE_RE)
+          add_link(el, link_url, @src[2], alt_text)
+        else
+          @src.pos = reset_pos
+          add_text(result)
+        end
+      end
+      define_parser(:link, LINK_START, '!?\[')
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/list.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/list.rb
new file mode 100644
index 0000000..dd83a30
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/list.rb
@@ -0,0 +1,243 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'kramdown/parser/kramdown/blank_line'
+require 'kramdown/parser/kramdown/eob'
+require 'kramdown/parser/kramdown/horizontal_rule'
+require 'kramdown/parser/kramdown/extensions'
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      LIST_ITEM_IAL = /^\s*(?:\{:(?!(?:#{ALD_ID_NAME})?:|\/)(#{ALD_ANY_CHARS}+)\})\s*/
+      LIST_ITEM_IAL_CHECK = /^#{LIST_ITEM_IAL}?\s*\n/
+
+      # Used for parsing the first line of a list item or a definition, i.e. the line with list item
+      # marker or the definition marker.
+      def parse_first_list_line(indentation, content)
+        if content =~ self.class::LIST_ITEM_IAL_CHECK
+          indentation = 4
+        else
+          while content =~ /^ *\t/
+            temp = content.scan(/^ */).first.length + indentation
+            content.sub!(/^( *)(\t+)/) {$1 << " "*(4 - (temp % 4) + ($2.length - 1)*4)}
+          end
+          indentation += content.scan(/^ */).first.length
+        end
+        content.sub!(/^\s*/, '')
+
+        indent_re = /^ {#{indentation}}/
+        content_re = /^(?:(?:\t| {4}){#{indentation / 4}} {#{indentation % 4}}|(?:\t| {4}){#{indentation / 4 + 1}}).*\S.*\n/
+        lazy_re = /(?!^ {0,#{[indentation, 3].min}}(?:#{IAL_BLOCK}|#{LAZY_END_HTML_STOP}|#{LAZY_END_HTML_START})).*\S.*\n/
+        [content, indentation, content_re, lazy_re, indent_re]
+      end
+
+
+      LIST_START_UL = /^(#{OPT_SPACE}[+*-])([\t| ].*?\n)/
+      LIST_START_OL = /^(#{OPT_SPACE}\d+\.)([\t| ].*?\n)/
+      LIST_START = /#{LIST_START_UL}|#{LIST_START_OL}/
+
+      # Parse the ordered or unordered list at the current location.
+      def parse_list
+        start_line_number = @src.current_line_number
+        type, list_start_re = (@src.check(LIST_START_UL) ? [:ul, LIST_START_UL] : [:ol, LIST_START_OL])
+        list = new_block_el(type, nil, nil, :location => start_line_number)
+
+        item = nil
+        content_re, lazy_re, indent_re = nil
+        eob_found = false
+        nested_list_found = false
+        last_is_blank = false
+        while !@src.eos?
+          start_line_number = @src.current_line_number
+          if last_is_blank && @src.check(HR_START)
+            break
+          elsif @src.scan(EOB_MARKER)
+            eob_found = true
+            break
+          elsif @src.scan(list_start_re)
+            item = Element.new(:li, nil, nil, :location => start_line_number)
+            item.value, indentation, content_re, lazy_re, indent_re = parse_first_list_line(@src[1].length, @src[2])
+            list.children << item
+
+            item.value.sub!(self.class::LIST_ITEM_IAL) do |match|
+              parse_attribute_list($1, item.options[:ial] ||= {})
+              ''
+            end
+
+            list_start_re = (type == :ul ? /^( {0,#{[3, indentation - 1].min}}[+*-])([\t| ].*?\n)/ :
+                             /^( {0,#{[3, indentation - 1].min}}\d+\.)([\t| ].*?\n)/)
+            nested_list_found = (item.value =~ LIST_START)
+            last_is_blank = false
+            item.value = [item.value]
+          elsif (result = @src.scan(content_re)) || (!last_is_blank && (result = @src.scan(lazy_re)))
+            result.sub!(/^(\t+)/) { " "*($1 ? 4*$1.length : 0) }
+            result.sub!(indent_re, '')
+            if !nested_list_found && result =~ LIST_START
+              item.value << ''
+              nested_list_found = true
+            end
+            item.value.last << result
+            last_is_blank = false
+          elsif result = @src.scan(BLANK_LINE)
+            nested_list_found = true
+            last_is_blank = true
+            item.value.last << result
+          else
+            break
+          end
+        end
+
+        @tree.children << list
+
+        last = nil
+        list.children.each do |it|
+          temp = Element.new(:temp, nil, nil, :location => it.options[:location])
+
+          env = save_env
+          location = it.options[:location]
+          it.value.each do |val|
+            @src = ::Kramdown::Utils::StringScanner.new(val, location)
+            parse_blocks(temp)
+            location = @src.current_line_number
+          end
+          restore_env(env)
+
+          it.children = temp.children
+          it.value = nil
+          next if it.children.size == 0
+
+          # Handle the case where an EOB marker is inserted by a block IAL for the first paragraph
+          it.children.delete_at(1) if it.children.first.type == :p &&
+            it.children.length >= 2 && it.children[1].type == :eob && it.children.first.options[:ial]
+
+          if it.children.first.type == :p &&
+              (it.children.length < 2 || it.children[1].type != :blank ||
+               (it == list.children.last && it.children.length == 2 && !eob_found)) &&
+              (list.children.last != it || list.children.size == 1 ||
+               list.children[0..-2].any? {|cit| !cit.children.first || cit.children.first.type != :p || cit.children.first.options[:transparent]})
+            it.children.first.children.first.value << "\n" if it.children.size > 1 && it.children[1].type != :blank
+            it.children.first.options[:transparent] = true
+          end
+
+          if it.children.last.type == :blank
+            last = it.children.pop
+          else
+            last = nil
+          end
+        end
+
+        @tree.children << last if !last.nil? && !eob_found
+
+        true
+      end
+      define_parser(:list, LIST_START)
+
+
+      DEFINITION_LIST_START = /^(#{OPT_SPACE}:)([\t| ].*?\n)/
+
+      # Parse the ordered or unordered list at the current location.
+      def parse_definition_list
+        children = @tree.children
+        if !children.last || (children.length == 1 && children.last.type != :p ) ||
+            (children.length >= 2 && children[-1].type != :p && (children[-1].type != :blank || children[-1].value != "\n" || children[-2].type != :p))
+          return false
+        end
+
+        first_as_para = false
+        deflist = new_block_el(:dl)
+        para = @tree.children.pop
+        if para.type == :blank
+          para = @tree.children.pop
+          first_as_para = true
+        end
+        deflist.options[:location] = para.options[:location] # take location from preceding para which is the first definition term
+        para.children.first.value.split(/\n/).each do |term|
+          el = Element.new(:dt, nil, nil, :location => @src.current_line_number)
+          el.children << Element.new(:raw_text, term)
+          deflist.children << el
+        end
+        deflist.options[:ial] = para.options[:ial]
+
+        item = nil
+        content_re, lazy_re, indent_re = nil
+        def_start_re = DEFINITION_LIST_START
+        last_is_blank = false
+        while !@src.eos?
+          start_line_number = @src.current_line_number
+          if @src.scan(def_start_re)
+            item = Element.new(:dd, nil, nil, :location => start_line_number)
+            item.options[:first_as_para] = first_as_para
+            item.value, indentation, content_re, lazy_re, indent_re = parse_first_list_line(@src[1].length, @src[2])
+            deflist.children << item
+
+            item.value.sub!(self.class::LIST_ITEM_IAL) do |match|
+              parse_attribute_list($1, item.options[:ial] ||= {})
+              ''
+            end
+
+            def_start_re = /^( {0,#{[3, indentation - 1].min}}:)([\t| ].*?\n)/
+            first_as_para = false
+            last_is_blank = false
+          elsif @src.check(EOB_MARKER)
+            break
+          elsif (result = @src.scan(content_re)) || (!last_is_blank && (result = @src.scan(lazy_re)))
+            result.sub!(/^(\t+)/) { " "*($1 ? 4*$1.length : 0) }
+            result.sub!(indent_re, '')
+            item.value << result
+            first_as_para = false
+            last_is_blank = false
+          elsif result = @src.scan(BLANK_LINE)
+            first_as_para = true
+            item.value << result
+            last_is_blank = true
+          else
+            break
+          end
+        end
+
+        last = nil
+        deflist.children.each do |it|
+          next if it.type == :dt
+
+          parse_blocks(it, it.value)
+          it.value = nil
+          next if it.children.size == 0
+
+          if it.children.last.type == :blank
+            last = it.children.pop
+          else
+            last = nil
+          end
+
+          if it.children.first && it.children.first.type == :p && !it.options.delete(:first_as_para)
+            it.children.first.children.first.value << "\n" if it.children.size > 1
+            it.children.first.options[:transparent] = true
+          end
+        end
+
+        if @tree.children.length >= 1 && @tree.children.last.type == :dl
+          @tree.children[-1].children.concat(deflist.children)
+        elsif @tree.children.length >= 2 && @tree.children[-1].type == :blank && @tree.children[-2].type == :dl
+          @tree.children.pop
+          @tree.children[-1].children.concat(deflist.children)
+        else
+          @tree.children << deflist
+        end
+
+        @tree.children << last if !last.nil?
+
+        true
+      end
+      define_parser(:definition_list, DEFINITION_LIST_START)
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/math.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/math.rb
new file mode 100644
index 0000000..4a10fcd
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/math.rb
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'kramdown/parser/kramdown/block_boundary'
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      BLOCK_MATH_START = /^#{OPT_SPACE}(\\)?\$\$(.*?)\$\$(\s*?\n)?/m
+
+      # Parse the math block at the current location.
+      def parse_block_math
+        start_line_number = @src.current_line_number
+        if !after_block_boundary?
+          return false
+        elsif @src[1]
+          @src.scan(/^#{OPT_SPACE}\\/) if @src[3]
+          return false
+        end
+
+        orig_pos = @src.pos
+        @src.pos += @src.matched_size
+        data = @src[2]
+        if before_block_boundary?
+          @tree.children << new_block_el(:math, data, nil, :category => :block, :location => start_line_number)
+          true
+        else
+          @src.pos = orig_pos
+          false
+        end
+      end
+      define_parser(:block_math, BLOCK_MATH_START)
+
+
+      INLINE_MATH_START = /\$\$(.*?)\$\$/m
+
+      # Parse the inline math at the current location.
+      def parse_inline_math
+        start_line_number = @src.current_line_number
+        @src.pos += @src.matched_size
+        @tree.children << Element.new(:math, @src[1], nil, :category => :span, :location => start_line_number)
+      end
+      define_parser(:inline_math, INLINE_MATH_START, '\$')
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/paragraph.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/paragraph.rb
new file mode 100644
index 0000000..09d5327
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/paragraph.rb
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'kramdown/parser/kramdown/blank_line'
+require 'kramdown/parser/kramdown/extensions'
+require 'kramdown/parser/kramdown/eob'
+require 'kramdown/parser/kramdown/list'
+require 'kramdown/parser/kramdown/html'
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      LAZY_END_HTML_SPAN_ELEMENTS = HTML_SPAN_ELEMENTS + %w{script}
+      LAZY_END_HTML_START = /<(?>(?!(?:#{LAZY_END_HTML_SPAN_ELEMENTS.join('|')})\b)#{REXML::Parsers::BaseParser::UNAME_STR})\s*(?>\s+#{REXML::Parsers::BaseParser::UNAME_STR}\s*=\s*(["']).*?\1)*\s*\/?>/m
+      LAZY_END_HTML_STOP = /<\/(?!(?:#{LAZY_END_HTML_SPAN_ELEMENTS.join('|')})\b)#{REXML::Parsers::BaseParser::UNAME_STR}\s*>/m
+
+      LAZY_END = /#{BLANK_LINE}|#{IAL_BLOCK_START}|#{EOB_MARKER}|^#{OPT_SPACE}#{LAZY_END_HTML_STOP}|^#{OPT_SPACE}#{LAZY_END_HTML_START}|\Z/
+
+      PARAGRAPH_START = /^#{OPT_SPACE}[^ \t].*?\n/
+      PARAGRAPH_MATCH = /^.*?\n/
+      PARAGRAPH_END = /#{LAZY_END}|#{DEFINITION_LIST_START}/
+
+      # Parse the paragraph at the current location.
+      def parse_paragraph
+        start_line_number = @src.current_line_number
+        result = @src.scan(PARAGRAPH_MATCH)
+        while !@src.match?(self.class::PARAGRAPH_END)
+          result << @src.scan(PARAGRAPH_MATCH)
+        end
+        result.chomp!
+        if @tree.children.last && @tree.children.last.type == :p
+          @tree.children.last.children.first.value << "\n" << result
+        else
+          @tree.children << new_block_el(:p, nil, nil, :location => start_line_number)
+          result.lstrip!
+          @tree.children.last.children << Element.new(@text_type, result)
+        end
+        true
+      end
+      define_parser(:paragraph, PARAGRAPH_START)
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/smart_quotes.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/smart_quotes.rb
new file mode 100644
index 0000000..9ff6b5b
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/smart_quotes.rb
@@ -0,0 +1,173 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+#--
+# Parts of this file are based on code from RubyPants:
+#
+# = RubyPants -- SmartyPants ported to Ruby
+#
+# Ported by Christian Neukirchen <mailto:chneukirchen at gmail.com>
+#   Copyright (C) 2004 Christian Neukirchen
+#
+# Incooporates ideas, comments and documentation by Chad Miller
+#   Copyright (C) 2004 Chad Miller
+#
+# Original SmartyPants by John Gruber
+#   Copyright (C) 2003 John Gruber
+#
+#
+# = RubyPants -- SmartyPants ported to Ruby
+#
+#
+# [snip]
+#
+# == Authors
+#
+# John Gruber did all of the hard work of writing this software in
+# Perl for Movable Type and almost all of this useful documentation.
+# Chad Miller ported it to Python to use with Pyblosxom.
+#
+# Christian Neukirchen provided the Ruby port, as a general-purpose
+# library that follows the *Cloth API.
+#
+#
+# == Copyright and License
+#
+# === SmartyPants license:
+#
+# Copyright (c) 2003 John Gruber
+# (http://daringfireball.net)
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in
+#   the documentation and/or other materials provided with the
+#   distribution.
+#
+# * Neither the name "SmartyPants" nor the names of its contributors
+#   may be used to endorse or promote products derived from this
+#   software without specific prior written permission.
+#
+# This software is provided by the copyright holders and contributors
+# "as is" and any express or implied warranties, including, but not
+# limited to, the implied warranties of merchantability and fitness
+# for a particular purpose are disclaimed. In no event shall the
+# copyright owner or contributors be liable for any direct, indirect,
+# incidental, special, exemplary, or consequential damages (including,
+# but not limited to, procurement of substitute goods or services;
+# loss of use, data, or profits; or business interruption) however
+# caused and on any theory of liability, whether in contract, strict
+# liability, or tort (including negligence or otherwise) arising in
+# any way out of the use of this software, even if advised of the
+# possibility of such damage.
+#
+# === RubyPants license
+#
+# RubyPants is a derivative work of SmartyPants and smartypants.py.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in
+#   the documentation and/or other materials provided with the
+#   distribution.
+#
+# This software is provided by the copyright holders and contributors
+# "as is" and any express or implied warranties, including, but not
+# limited to, the implied warranties of merchantability and fitness
+# for a particular purpose are disclaimed. In no event shall the
+# copyright owner or contributors be liable for any direct, indirect,
+# incidental, special, exemplary, or consequential damages (including,
+# but not limited to, procurement of substitute goods or services;
+# loss of use, data, or profits; or business interruption) however
+# caused and on any theory of liability, whether in contract, strict
+# liability, or tort (including negligence or otherwise) arising in
+# any way out of the use of this software, even if advised of the
+# possibility of such damage.
+#
+# == Links
+#
+# John Gruber:: http://daringfireball.net
+# SmartyPants:: http://daringfireball.net/projects/smartypants
+#
+# Chad Miller:: http://web.chad.org
+#
+# Christian Neukirchen:: http://kronavita.de/chris
+#
+#++
+#
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      SQ_PUNCT = '[!"#\$\%\'()*+,\-.\/:;<=>?\@\[\\\\\]\^_`{|}~]'
+      SQ_CLOSE = %![^\ \\\\\t\r\n\\[{(-]!
+
+      SQ_RULES = [
+                  [/("|')(?=[_*]{1,2}\S)/, [:lquote1]],
+                  [/("|')(?=#{SQ_PUNCT}\B)/, [:rquote1]],
+                  # Special case for double sets of quotes, e.g.:
+                  #   <p>He said, "'Quoted' words in a larger quote."</p>
+                  [/(\s?)"'(?=\w)/, [1, :ldquo, :lsquo]],
+                  [/(\s?)'"(?=\w)/, [1, :lsquo, :ldquo]],
+                  # Special case for decade abbreviations (the '80s):
+                  [/(\s?)'(?=\d\ds)/, [1, :rsquo]],
+
+                  # Get most opening single/double quotes:
+                  [/(\s)('|")(?=\w)/, [1, :lquote2]],
+                  # Single/double closing quotes:
+                  [/(#{SQ_CLOSE})('|")/, [1, :rquote2]],
+                  # Special case for e.g. "<i>Custer</i>'s Last Stand."
+                  [/("|')(\s|s\b|$)/, [:rquote1, 2]],
+                  # Any remaining single quotes should be opening ones:
+                  [/(.?)'/m, [1, :lsquo]],
+                  [/(.?)"/m, [1, :ldquo]],
+                 ] #'"
+
+      SQ_SUBSTS = {
+        [:rquote1, '"'] => :rdquo,
+        [:rquote1, "'"] => :rsquo,
+        [:rquote2, '"'] => :rdquo,
+        [:rquote2, "'"] => :rsquo,
+        [:lquote1, '"'] => :ldquo,
+        [:lquote1, "'"] => :lsquo,
+        [:lquote2, '"'] => :ldquo,
+        [:lquote2, "'"] => :lsquo,
+      }
+      SMART_QUOTES_RE = /[^\\]?["']/
+
+      # Parse the smart quotes at current location.
+      def parse_smart_quotes
+        substs = SQ_RULES.find {|reg, subst| @src.scan(reg)}[1]
+        substs.each do |subst|
+          if subst.kind_of?(Integer)
+            add_text(@src[subst])
+          else
+            val = SQ_SUBSTS[[subst, @src[subst.to_s[-1,1].to_i]]] || subst
+            @tree.children << Element.new(:smart_quote, val)
+          end
+        end
+      end
+      define_parser(:smart_quotes, SMART_QUOTES_RE, '[^\\\\]?["\']')
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/table.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/table.rb
new file mode 100644
index 0000000..942c595
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/table.rb
@@ -0,0 +1,170 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'kramdown/parser/kramdown/block_boundary'
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      TABLE_SEP_LINE = /^([+|: -]*?-[+|: -]*?)[ \t]*\n/
+      TABLE_HSEP_ALIGN = /[ ]?(:?)-+(:?)[ ]?/
+      TABLE_FSEP_LINE = /^[+|: =]*?=[+|: =]*?[ \t]*\n/
+      TABLE_ROW_LINE = /^(.*?)[ \t]*\n/
+      TABLE_PIPE_CHECK = /(?:\||.*?[^\\\n]\|)/
+      TABLE_LINE = /#{TABLE_PIPE_CHECK}.*?\n/
+      TABLE_START = /^#{OPT_SPACE}(?=\S)#{TABLE_LINE}/
+
+      # Parse the table at the current location.
+      def parse_table
+        return false if !after_block_boundary?
+
+        orig_pos = @src.pos
+        table = new_block_el(:table, nil, nil, :alignment => [], :location => @src.current_line_number)
+        leading_pipe = (@src.check(TABLE_LINE) =~ /^\s*\|/)
+        @src.scan(TABLE_SEP_LINE)
+
+        rows = []
+        has_footer = false
+        columns = 0
+
+        add_container = lambda do |type, force|
+          if !has_footer || type != :tbody || force
+            cont = Element.new(type)
+            cont.children, rows = rows, []
+            table.children << cont
+          end
+        end
+
+        while !@src.eos?
+          break if !@src.check(TABLE_LINE)
+          if @src.scan(TABLE_SEP_LINE) && !rows.empty?
+            if table.options[:alignment].empty? && !has_footer
+              add_container.call(:thead, false)
+              table.options[:alignment] = @src[1].scan(TABLE_HSEP_ALIGN).map do |left, right|
+                (left.empty? && right.empty? && :default) || (right.empty? && :left) || (left.empty? && :right) || :center
+              end
+            else # treat as normal separator line
+              add_container.call(:tbody, false)
+            end
+          elsif @src.scan(TABLE_FSEP_LINE)
+            add_container.call(:tbody, true) if !rows.empty?
+            has_footer = true
+          elsif @src.scan(TABLE_ROW_LINE)
+            trow = Element.new(:tr)
+
+            # parse possible code spans on the line and correctly split the line into cells
+            env = save_env
+            cells = []
+            @src[1].split(/(<code.*?>.*?<\/code>)/).each_with_index do |str, i|
+              if i % 2 == 1
+                (cells.empty? ? cells : cells.last) << str
+              else
+                reset_env(:src => Kramdown::Utils::StringScanner.new(str, @src.current_line_number))
+                root = Element.new(:root)
+                parse_spans(root, nil, [:codespan])
+
+                root.children.each do |c|
+                  if c.type == :raw_text
+                    # Only on Ruby 1.9: f, *l = c.value.split(/(?<!\\)\|/).map {|t| t.gsub(/\\\|/, '|')}
+                    f, *l = c.value.split(/\\\|/, -1).map {|t| t.split(/\|/, -1)}.inject([]) do |memo, t|
+                      memo.last << "|#{t.shift}" if memo.size > 0
+                      memo.concat(t)
+                    end
+                    (cells.empty? ? cells : cells.last) << f
+                    cells.concat(l)
+                  else
+                    delim = (c.value.scan(/`+/).max || '') + '`'
+                    tmp = "#{delim}#{' ' if delim.size > 1}#{c.value}#{' ' if delim.size > 1}#{delim}"
+                    (cells.empty? ? cells : cells.last) << tmp
+                  end
+                end
+              end
+            end
+            restore_env(env)
+
+            cells.shift if leading_pipe && cells.first.strip.empty?
+            cells.pop if cells.last.strip.empty?
+            cells.each do |cell_text|
+              tcell = Element.new(:td)
+              tcell.children << Element.new(:raw_text, cell_text.strip)
+              trow.children << tcell
+            end
+            columns = [columns, cells.length].max
+            rows << trow
+          else
+            break
+          end
+        end
+
+        if !before_block_boundary?
+          @src.pos = orig_pos
+          return false
+        end
+
+        # Parse all lines of the table with the code span parser
+        env = save_env
+        l_src = ::Kramdown::Utils::StringScanner.new(extract_string(orig_pos...(@src.pos-1), @src),
+                                                     @src.current_line_number)
+        reset_env(:src => l_src)
+        root = Element.new(:root)
+        parse_spans(root, nil, [:codespan, :span_html])
+        restore_env(env)
+
+        # Check if each line has at least one unescaped pipe that is not inside a code span/code
+        # HTML element
+        # Note: It doesn't matter that we parse *all* span HTML elements because the row splitting
+        # algorithm above only takes <code> elements into account!
+        pipe_on_line = false
+        while (c = root.children.shift)
+          lines = c.value.split(/\n/)
+          if c.type == :codespan
+            if lines.size > 2 || (lines.size == 2 && !pipe_on_line)
+              break
+            elsif lines.size == 2 && pipe_on_line
+              pipe_on_line = false
+            end
+          else
+            break if lines.size > 1 && !pipe_on_line && lines.first !~ /^#{TABLE_PIPE_CHECK}/
+            pipe_on_line = (lines.size > 1 ? false : pipe_on_line) || (lines.last =~ /^#{TABLE_PIPE_CHECK}/)
+          end
+        end
+        @src.pos = orig_pos and return false if !pipe_on_line
+
+        add_container.call(has_footer ? :tfoot : :tbody, false) if !rows.empty?
+
+        if !table.children.any? {|el| el.type == :tbody}
+          warning("Found table without body - ignoring it")
+          @src.pos = orig_pos
+          return false
+        end
+
+        # adjust all table rows to have equal number of columns, same for alignment defs
+        table.children.each do |kind|
+          kind.children.each do |row|
+            (columns - row.children.length).times do
+              row.children << Element.new(:td)
+            end
+          end
+        end
+        if table.options[:alignment].length > columns
+          table.options[:alignment] = table.options[:alignment][0...columns]
+        else
+          table.options[:alignment] += [:default] * (columns - table.options[:alignment].length)
+        end
+
+        @tree.children << table
+
+        true
+      end
+      define_parser(:table, TABLE_START)
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/typographic_symbol.rb b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/typographic_symbol.rb
new file mode 100644
index 0000000..5a34961
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/kramdown/typographic_symbol.rb
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+  module Parser
+    class Kramdown
+
+      TYPOGRAPHIC_SYMS = [['---', :mdash], ['--', :ndash], ['...', :hellip],
+                          ['\\<<', '<<'], ['\\>>', '>>'],
+                          ['<< ', :laquo_space], [' >>', :raquo_space],
+                          ['<<', :laquo], ['>>', :raquo]]
+      TYPOGRAPHIC_SYMS_SUBST = Hash[*TYPOGRAPHIC_SYMS.flatten]
+      TYPOGRAPHIC_SYMS_RE = /#{TYPOGRAPHIC_SYMS.map {|k,v| Regexp.escape(k)}.join('|')}/
+
+      # Parse the typographic symbols at the current location.
+      def parse_typographic_syms
+        start_line_number = @src.current_line_number
+        @src.pos += @src.matched_size
+        val = TYPOGRAPHIC_SYMS_SUBST[@src.matched]
+        if val.kind_of?(Symbol)
+          @tree.children << Element.new(:typographic_sym, val, nil, :location => start_line_number)
+        elsif @src.matched == '\\<<'
+          @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'),
+                                        nil, :location => start_line_number)
+          @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'),
+                                        nil, :location => start_line_number)
+        else
+          @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'),
+                                        nil, :location => start_line_number)
+          @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'),
+                                        nil, :location => start_line_number)
+        end
+      end
+      define_parser(:typographic_syms, TYPOGRAPHIC_SYMS_RE, '--|\\.\\.\\.|(?:\\\\| )?(?:<<|>>)')
+
+    end
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/parser/markdown.rb b/app/server/vendor/kramdown/lib/kramdown/parser/markdown.rb
new file mode 100644
index 0000000..d451c6a
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/parser/markdown.rb
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'kramdown/parser/kramdown'
+
+module Kramdown
+
+  module Parser
+
+    # Used for parsing a document in Markdown format.
+    #
+    # This parser is based on the kramdown parser and removes the parser methods for the additional
+    # non-Markdown features. However, since some things are handled differently by the kramdown
+    # parser methods (like deciding when a list item contains just text), this parser differs from
+    # real Markdown parsers in some respects.
+    #
+    # Note, though, that the parser basically fails just one of the Markdown test cases (some others
+    # also fail but those failures are negligible).
+    class Markdown < Kramdown
+
+      # Array with all the parsing methods that should be removed from the standard kramdown parser.
+      EXTENDED = [:codeblock_fenced, :table, :definition_list, :footnote_definition, :abbrev_definition, :block_math,
+                  :block_extensions,
+                  :footnote_marker, :smart_quotes, :inline_math, :span_extensions, :typographic_syms]
+
+      def initialize(source, options) # :nodoc:
+        super
+        @block_parsers.delete_if {|i| EXTENDED.include?(i)}
+        @span_parsers.delete_if {|i| EXTENDED.include?(i)}
+      end
+
+      # :stopdoc:
+
+      BLOCK_BOUNDARY = /#{BLANK_LINE}|#{EOB_MARKER}|\Z/
+      LAZY_END = /#{BLANK_LINE}|#{EOB_MARKER}|^#{OPT_SPACE}#{LAZY_END_HTML_STOP}|^#{OPT_SPACE}#{LAZY_END_HTML_START}|\Z/
+      CODEBLOCK_MATCH = /(?:#{BLANK_LINE}?(?:#{INDENT}[ \t]*\S.*\n)+)*/
+      PARAGRAPH_END = LAZY_END
+
+      IAL_RAND_CHARS = (('a'..'z').to_a + ('0'..'9').to_a)
+      IAL_RAND_STRING = (1..20).collect {|a| IAL_RAND_CHARS[rand(IAL_RAND_CHARS.size)]}.join
+      LIST_ITEM_IAL = /^\s*(#{IAL_RAND_STRING})?\s*\n/
+      IAL_SPAN_START = LIST_ITEM_IAL
+
+      # :startdoc:
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/utils.rb b/app/server/vendor/kramdown/lib/kramdown/utils.rb
new file mode 100644
index 0000000..d8d5b3b
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/utils.rb
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+
+  # == \Utils Module
+  #
+  # This module contains utility class/modules/methods that can be used by both parsers and
+  # converters.
+  module Utils
+
+    autoload :Entities, 'kramdown/utils/entities'
+    autoload :Html, 'kramdown/utils/html'
+    autoload :OrderedHash, 'kramdown/utils/ordered_hash'
+    autoload :Unidecoder, 'kramdown/utils/unidecoder'
+    autoload :StringScanner, 'kramdown/utils/string_scanner'
+
+    # Treat +name+ as if it were snake cased (e.g. snake_case) and camelize it (e.g. SnakeCase).
+    def self.camelize(name)
+      name.split('_').inject('') {|s,x| s << x[0..0].upcase << x[1..-1] }
+    end
+
+    # Treat +name+ as if it were camelized (e.g. CamelizedName) and snake-case it (e.g. camelized_name).
+    def self.snake_case(name)
+      name = name.dup
+      name.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
+      name.gsub!(/([a-z])([A-Z])/,'\1_\2')
+      name.downcase!
+      name
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/utils/entities.rb b/app/server/vendor/kramdown/lib/kramdown/utils/entities.rb
new file mode 100644
index 0000000..2747f6b
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/utils/entities.rb
@@ -0,0 +1,347 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+
+  module Utils
+
+    # Provides convenience methods for handling named and numeric entities.
+    module Entities
+
+      # Represents an entity that has a +code_point+ and +name+.
+      class Entity < Struct.new(:code_point, :name)
+
+        # Return the UTF8 representation of the entity.
+        def char
+          [code_point].pack('U*') rescue nil
+        end
+
+      end
+
+      # Array of arrays. Each sub-array specifies a code point and the associated name.
+      #
+      # This table is not used directly -- Entity objects are automatically created from it and put
+      # into a Hash map when this file is loaded.
+      ENTITY_TABLE = [
+                      [913, 'Alpha'],
+                      [914, 'Beta'],
+                      [915, 'Gamma'],
+                      [916, 'Delta'],
+                      [917, 'Epsilon'],
+                      [918, 'Zeta'],
+                      [919, 'Eta'],
+                      [920, 'Theta'],
+                      [921, 'Iota'],
+                      [922, 'Kappa'],
+                      [923, 'Lambda'],
+                      [924, 'Mu'],
+                      [925, 'Nu'],
+                      [926, 'Xi'],
+                      [927, 'Omicron'],
+                      [928, 'Pi'],
+                      [929, 'Rho'],
+                      [931, 'Sigma'],
+                      [932, 'Tau'],
+                      [933, 'Upsilon'],
+                      [934, 'Phi'],
+                      [935, 'Chi'],
+                      [936, 'Psi'],
+                      [937, 'Omega'],
+                      [945, 'alpha'],
+                      [946, 'beta'],
+                      [947, 'gamma'],
+                      [948, 'delta'],
+                      [949, 'epsilon'],
+                      [950, 'zeta'],
+                      [951, 'eta'],
+                      [952, 'theta'],
+                      [953, 'iota'],
+                      [954, 'kappa'],
+                      [955, 'lambda'],
+                      [956, 'mu'],
+                      [957, 'nu'],
+                      [958, 'xi'],
+                      [959, 'omicron'],
+                      [960, 'pi'],
+                      [961, 'rho'],
+                      [963, 'sigma'],
+                      [964, 'tau'],
+                      [965, 'upsilon'],
+                      [966, 'phi'],
+                      [967, 'chi'],
+                      [968, 'psi'],
+                      [969, 'omega'],
+                      [962, 'sigmaf'],
+                      [977, 'thetasym'],
+                      [978, 'upsih'],
+                      [982, 'piv'],
+                      [8204, 'zwnj'],
+                      [8205, 'zwj'],
+                      [8206, 'lrm'],
+                      [8207, 'rlm'],
+                      [8230, 'hellip'],
+                      [8242, 'prime'],
+                      [8243, 'Prime'],
+                      [8254, 'oline'],
+                      [8260, 'frasl'],
+                      [8472, 'weierp'],
+                      [8465, 'image'],
+                      [8476, 'real'],
+                      [8501, 'alefsym'],
+                      [8226, 'bull'],
+                      [8482, 'trade'],
+                      [8592, 'larr'],
+                      [8594, 'rarr'],
+                      [8593, 'uarr'],
+                      [8595, 'darr'],
+                      [8596, 'harr'],
+                      [8629, 'crarr'],
+                      [8657, 'uArr'],
+                      [8659, 'dArr'],
+                      [8656, 'lArr'],
+                      [8658, 'rArr'],
+                      [8660, 'hArr'],
+                      [8704, 'forall'],
+                      [8706, 'part'],
+                      [8707, 'exist'],
+                      [8709, 'empty'],
+                      [8711, 'nabla'],
+                      [8712, 'isin'],
+                      [8715, 'ni'],
+                      [8713, 'notin'],
+                      [8721, 'sum'],
+                      [8719, 'prod'],
+                      [8722, 'minus'],
+                      [8727, 'lowast'],
+                      [8730, 'radic'],
+                      [8733, 'prop'],
+                      [8734, 'infin'],
+                      [8736, 'ang'],
+                      [8743, 'and'],
+                      [8744, 'or'],
+                      [8745, 'cup'],
+                      [8746, 'cap'],
+                      [8747, 'int'],
+                      [8756, 'there4'],
+                      [8764, 'sim'],
+                      [8776, 'asymp'],
+                      [8773, 'cong'],
+                      [8800, 'ne'],
+                      [8801, 'equiv'],
+                      [8804, 'le'],
+                      [8805, 'ge'],
+                      [8834, 'sub'],
+                      [8835, 'sup'],
+                      [8838, 'sube'],
+                      [8839, 'supe'],
+                      [8836, 'nsub'],
+                      [8853, 'oplus'],
+                      [8855, 'otimes'],
+                      [8869, 'perp'],
+                      [8901, 'sdot'],
+                      [8942, 'vellip'],
+                      [8968, 'rceil'],
+                      [8969, 'lceil'],
+                      [8970, 'lfloor'],
+                      [8971, 'rfloor'],
+                      [9001, 'rang'],
+                      [9002, 'lang'],
+                      [9674, 'loz'],
+                      [9824, 'spades'],
+                      [9827, 'clubs'],
+                      [9829, 'hearts'],
+                      [9830, 'diams'],
+                      [38, 'amp'],
+                      [34, 'quot'],
+                      [39, 'apos'],
+                      [169, 'copy'],
+                      [60, 'lt'],
+                      [62, 'gt'],
+                      [338, 'OElig'],
+                      [339, 'oelig'],
+                      [352, 'Scaron'],
+                      [353, 'scaron'],
+                      [376, 'Yuml'],
+                      [710, 'circ'],
+                      [732, 'tilde'],
+                      [8211, 'ndash'],
+                      [8212, 'mdash'],
+                      [8216, 'lsquo'],
+                      [8217, 'rsquo'],
+                      [8220, 'ldquo'],
+                      [8221, 'rdquo'],
+                      [8224, 'dagger'],
+                      [8225, 'Dagger'],
+                      [8240, 'permil'],
+                      [8364, 'euro'],
+                      [8249, 'lsaquo'],
+                      [8250, 'rsaquo'],
+                      [160, 'nbsp'],
+                      [161, 'iexcl'],
+                      [163, 'pound'],
+                      [164, 'curren'],
+                      [165, 'yen'],
+                      [166, 'brvbar'],
+                      [167, 'sect'],
+                      [168, 'uml'],
+                      [171, 'laquo'],
+                      [187, 'raquo'],
+                      [174, 'reg'],
+                      [170, 'ordf'],
+                      [172, 'not'],
+                      [173, 'shy'],
+                      [175, 'macr'],
+                      [176, 'deg'],
+                      [177, 'plusmn'],
+                      [180, 'acute'],
+                      [181, 'micro'],
+                      [182, 'para'],
+                      [183, 'middot'],
+                      [184, 'cedil'],
+                      [186, 'ordm'],
+                      [162, 'cent'],
+                      [185, 'sup1'],
+                      [178, 'sup2'],
+                      [179, 'sup3'],
+                      [189, 'frac12'],
+                      [188, 'frac14'],
+                      [190, 'frac34'],
+                      [191, 'iquest'],
+                      [192, 'Agrave'],
+                      [193, 'Aacute'],
+                      [194, 'Acirc'],
+                      [195, 'Atilde'],
+                      [196, 'Auml'],
+                      [197, 'Aring'],
+                      [198, 'AElig'],
+                      [199, 'Ccedil'],
+                      [200, 'Egrave'],
+                      [201, 'Eacute'],
+                      [202, 'Ecirc'],
+                      [203, 'Euml'],
+                      [204, 'Igrave'],
+                      [205, 'Iacute'],
+                      [206, 'Icirc'],
+                      [207, 'Iuml'],
+                      [208, 'ETH'],
+                      [209, 'Ntilde'],
+                      [210, 'Ograve'],
+                      [211, 'Oacute'],
+                      [212, 'Ocirc'],
+                      [213, 'Otilde'],
+                      [214, 'Ouml'],
+                      [215, 'times'],
+                      [216, 'Oslash'],
+                      [217, 'Ugrave'],
+                      [218, 'Uacute'],
+                      [219, 'Ucirc'],
+                      [220, 'Uuml'],
+                      [221, 'Yacute'],
+                      [222, 'THORN'],
+                      [223, 'szlig'],
+                      [224, 'agrave'],
+                      [225, 'aacute'],
+                      [226, 'acirc'],
+                      [227, 'atilde'],
+                      [228, 'auml'],
+                      [229, 'aring'],
+                      [230, 'aelig'],
+                      [231, 'ccedil'],
+                      [232, 'egrave'],
+                      [233, 'eacute'],
+                      [234, 'ecirc'],
+                      [235, 'euml'],
+                      [236, 'igrave'],
+                      [237, 'iacute'],
+                      [238, 'icirc'],
+                      [239, 'iuml'],
+                      [240, 'eth'],
+                      [241, 'ntilde'],
+                      [242, 'ograve'],
+                      [243, 'oacute'],
+                      [244, 'ocirc'],
+                      [245, 'otilde'],
+                      [246, 'ouml'],
+                      [247, 'divide'],
+                      [248, 'oslash'],
+                      [249, 'ugrave'],
+                      [250, 'uacute'],
+                      [251, 'ucirc'],
+                      [252, 'uuml'],
+                      [253, 'yacute'],
+                      [254, 'thorn'],
+                      [255, 'yuml'],
+
+                      [8218, 'sbquo'],
+                      [402, 'fnof'],
+                      [8222, 'bdquo'],
+
+                      [128, 8364],
+                      [130, 8218],
+                      [131, 402],
+                      [132, 8222],
+                      [133, 8230],
+                      [134, 8224],
+                      [135, 8225],
+                      [136, 710],
+                      [137, 8240],
+                      [138, 352],
+                      [139, 8249],
+                      [140, 338],
+                      [142, 381],
+                      [145, 8216],
+                      [146, 8217],
+                      [147, 8220],
+                      [148, 8221],
+                      [149, 8226],
+                      [150, 8211],
+                      [151, 8212],
+                      [152, 732],
+                      [153, 8482],
+                      [154, 353],
+                      [155, 8250],
+                      [156, 339],
+                      [158, 382],
+                      [159, 376],
+
+                      [8194, 'ensp'],
+                      [8195, 'emsp'],
+                      [8201, 'thinsp'],
+                     ]
+
+      # Contains the mapping of code point (or name) to the actual Entity object.
+      ENTITY_MAP = Hash.new do |h,k|
+        if k.kind_of?(Integer)
+          h[k] = Entity.new(k, nil)
+        else
+          raise Kramdown::Error, "Can't handle generic non-integer character reference '#{k}'"
+        end
+      end
+
+      ENTITY_TABLE.each do |code_point, data|
+        if data.kind_of?(String)
+          ENTITY_MAP[code_point] = ENTITY_MAP[data] = Entity.new(code_point, data)
+        else
+          ENTITY_MAP[code_point] = ENTITY_MAP[data]
+        end
+      end
+
+      # Return the entity for the given code point or name +point_or_name+.
+      def entity(point_or_name)
+        ENTITY_MAP[point_or_name]
+      end
+
+      module_function :entity
+
+    end
+
+  end
+
+end
+
diff --git a/app/server/vendor/kramdown/lib/kramdown/utils/html.rb b/app/server/vendor/kramdown/lib/kramdown/utils/html.rb
new file mode 100644
index 0000000..bb30c49
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/utils/html.rb
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+
+  module Utils
+
+    # Provides convenience methods for HTML related tasks.
+    #
+    # *Note* that this module has to be mixed into a class that has a @root (containing an element
+    # of type :root) and an @options (containing an options hash) instance variable so that some of
+    # the methods can work correctly.
+    module Html
+
+      # Convert the entity +e+ to a string. The optional parameter +original+ may contain the
+      # original representation of the entity.
+      #
+      # This method uses the option +entity_output+ to determine the output form for the entity.
+      def entity_to_str(e, original = nil)
+        entity_output = @options[:entity_output]
+
+        if e.char.respond_to?(:encoding) && entity_output == :as_char &&
+            (c = e.char.encode(@root.options[:encoding]) rescue nil) &&
+            ((c = e.char) == '"' || !ESCAPE_MAP.has_key?(c))
+          c
+        elsif (entity_output == :as_input || entity_output == :as_char) && original
+          original
+        elsif (entity_output == :symbolic || ESCAPE_MAP.has_key?(e.char)) && !e.name.nil?
+          "&#{e.name};"
+        else # default to :numeric
+          "&##{e.code_point};"
+        end
+      end
+
+      # Return the HTML representation of the attributes +attr+.
+      def html_attributes(attr)
+        attr.map {|k,v| v.nil? || (k == 'id' && v.strip.empty?) ? '' : " #{k}=\"#{escape_html(v.to_s, :attribute)}\"" }.join('')
+      end
+
+      # :stopdoc:
+      ESCAPE_MAP = {
+        '<' => '<',
+        '>' => '>',
+        '&' => '&',
+        '"' => '"'
+      }
+      ESCAPE_ALL_RE = /<|>|&/
+      ESCAPE_TEXT_RE = Regexp.union(REXML::Parsers::BaseParser::REFERENCE_RE, /<|>|&/)
+      ESCAPE_ATTRIBUTE_RE = Regexp.union(REXML::Parsers::BaseParser::REFERENCE_RE, /<|>|&|"/)
+      ESCAPE_RE_FROM_TYPE = {
+        :all => ESCAPE_ALL_RE,
+        :text => ESCAPE_TEXT_RE,
+        :attribute => ESCAPE_ATTRIBUTE_RE
+      }
+      # :startdoc:
+
+      # Escape the special HTML characters in the string +str+. The parameter +type+ specifies what
+      # is escaped: :all - all special HTML characters except the quotation mark as well as
+      # entities, :text - all special HTML characters except the quotation mark but no entities and
+      # :attribute - all special HTML characters including the quotation mark but no entities.
+      def escape_html(str, type = :all)
+        str.gsub(ESCAPE_RE_FROM_TYPE[type]) {|m| ESCAPE_MAP[m] || m}
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/utils/ordered_hash.rb b/app/server/vendor/kramdown/lib/kramdown/utils/ordered_hash.rb
new file mode 100644
index 0000000..acbefb7
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/utils/ordered_hash.rb
@@ -0,0 +1,87 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+
+  module Utils
+
+    if RUBY_VERSION < '1.9'
+
+      # A partial hash implementation which preserves the insertion order of the keys.
+      #
+      # *Note* that this class is only used on Ruby 1.8 since the built-in Hash on Ruby 1.9
+      # automatically preserves the insertion order. However, to remain compatibility only the
+      # methods defined in this class may be used when working with OrderedHash on Ruby 1.9.
+      class OrderedHash
+
+        include Enumerable
+
+        # Initialize the OrderedHash object.
+        def initialize
+          @data =  {}
+          @order = []
+        end
+
+        # Iterate over the stored keys in insertion order.
+        def each
+          @order.each {|k| yield(k, @data[k])}
+        end
+
+        # Return the value for the +key+.
+        def [](key)
+          @data[key]
+        end
+
+        # Return +true+ if the hash contains the key.
+        def has_key?(key)
+          @data.has_key?(key)
+        end
+
+        # Set the value for the +key+ to +val+.
+        def []=(key, val)
+          @order << key if !@data.has_key?(key)
+          @data[key] = val
+        end
+
+        # Delete the +key+.
+        def delete(key)
+          @order.delete(key)
+          @data.delete(key)
+        end
+
+        def merge!(other)
+          other.each {|k,v| self[k] = v}
+          self
+        end
+
+        def dup #:nodoc:
+          new_object = super
+          new_object.instance_variable_set(:@data, @data.dup)
+          new_object.instance_variable_set(:@order, @order.dup)
+          new_object
+        end
+
+        def ==(other) #:nodoc:
+          return false unless other.kind_of?(self.class)
+          @data == other.instance_variable_get(:@data) && @order == other.instance_variable_get(:@order)
+        end
+
+        def inspect #:nodoc:
+          "{" + map {|k,v| "#{k.inspect}=>#{v.inspect}"}.join(" ") + "}"
+        end
+
+      end
+
+    else
+      OrderedHash = Hash
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/utils/string_scanner.rb b/app/server/vendor/kramdown/lib/kramdown/utils/string_scanner.rb
new file mode 100644
index 0000000..52ab68d
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/utils/string_scanner.rb
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*-
+
+require 'strscan'
+
+module Kramdown
+  module Utils
+
+    # This patched StringScanner adds line number information for current scan position and a
+    # start_line_number override for nested StringScanners.
+    class StringScanner < ::StringScanner
+
+      # The start line number. Used for nested StringScanners that scan a sub-string of the source
+      # document. The kramdown parser uses this, e.g., for span level parsers.
+      attr_reader :start_line_number
+
+      # Takes the start line number as optional second argument.
+      #
+      # Note: The original second argument is no longer used so this should be safe.
+      def initialize(string, start_line_number = 1)
+        super(string)
+        @start_line_number = start_line_number || 1
+        @previous_pos = 0
+        @previous_line_number = @start_line_number
+      end
+
+      # To make this unicode (multibyte) aware, we have to use #charpos which was added in Ruby
+      # version 2.0.0.
+      #
+      # This method will work with older versions of Ruby, however it will report incorrect line
+      # numbers if the scanned string contains multibyte characters.
+      if instance_methods.include?(:charpos)
+        def best_pos
+          charpos
+        end
+      else
+        def best_pos
+          pos
+        end
+      end
+
+      # Sets the byte position of the scan pointer.
+      #
+      # Note: This also resets some internal variables, so always use pos= when setting the position
+      # and don't use any other method for that!
+      def pos=(pos)
+        super
+        @previous_line_number = @start_line_number
+        @previous_pos = 0
+      end
+
+      # Returns the line number for current charpos.
+      #
+      # NOTE: Requires that all line endings are normalized to '\n'
+      #
+      # NOTE: Normally we'd have to add one to the count of newlines to get the correct line number.
+      # However we add the one indirectly by using a one-based start_line_number.
+      def current_line_number
+        # Not using string[@previous_pos..best_pos].count('\n') because it is slower
+        strscan = ::StringScanner.new(string)
+        strscan.pos = @previous_pos
+        old_pos = pos + 1
+        @previous_line_number += 1 while strscan.skip_until(/\n/) && strscan.pos <= old_pos
+
+        @previous_pos = (eos? ? best_pos : best_pos + 1)
+        @previous_line_number
+      end
+
+    end
+
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/utils/unidecoder.rb b/app/server/vendor/kramdown/lib/kramdown/utils/unidecoder.rb
new file mode 100644
index 0000000..56777da
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/utils/unidecoder.rb
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+# This file is based on code originally from the Stringex library and needs the data files from
+# Stringex to work correctly.
+
+module Kramdown
+  module Utils
+
+    # Provides the ability to tranliterate Unicode strings into plain ASCII ones.
+    module Unidecoder
+
+      gem 'stringex' if defined?(Gem)
+      path = $:.find {|dir| File.directory?(File.join(File.expand_path(dir), "stringex", "unidecoder_data"))}
+
+      if RUBY_VERSION <= '1.8.6' || !path
+        def self.decode(string)
+          string
+        end
+      else
+
+        CODEPOINTS = Hash.new do |h, k|
+          h[k] = YAML.load_file(File.join(path, "stringex", "unidecoder_data", "#{k}.yml"))
+        end
+
+        # Transliterate string from Unicode into ASCII.
+        def self.decode(string)
+          string.gsub(/[^\x00-\x7f]/u) do |codepoint|
+            begin
+              unpacked = codepoint.unpack("U")[0]
+              CODEPOINTS["x%02x" % (unpacked >> 8)][unpacked & 255]
+            rescue
+              "?"
+            end
+          end
+        end
+
+      end
+
+    end
+
+  end
+end
diff --git a/app/server/vendor/kramdown/lib/kramdown/version.rb b/app/server/vendor/kramdown/lib/kramdown/version.rb
new file mode 100644
index 0000000..e5757af
--- /dev/null
+++ b/app/server/vendor/kramdown/lib/kramdown/version.rb
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+module Kramdown
+
+  # The kramdown version.
+  VERSION = '1.4.0'
+
+end
diff --git a/app/server/vendor/kramdown/man/man1/kramdown.1 b/app/server/vendor/kramdown/man/man1/kramdown.1
new file mode 100644
index 0000000..051f19c
--- /dev/null
+++ b/app/server/vendor/kramdown/man/man1/kramdown.1
@@ -0,0 +1,404 @@
+.TH "KRAMDOWN" 1 "June 2014"
+.SH NAME
+kramdown \- a fast, pure-Ruby Markdown-superset converter
+.SH SYNOPSIS
+.B kramdown
+[\fIoptions\fR]
+[\fIFILE\fR ...]
+.SH DESCRIPTION
+kramdown is primarily used for parsing a superset of Markdown and converting it to different output
+formats. It supports standard Markdown (with some minor modifications) and various extensions like
+tables and definition lists. Due to its modular architecture it also allows other input formats than
+Markdown, for example, HTML or Github Flavored Markdown.
+
+If \fIFILE\fR is not specified, kramdown reads from the standard input. The result is written to the
+standard output.
+
+There are two sets of options that kramdown accepts: The first one includes the options that are
+used directly by the kramdown binary. The second set of options controls how kramdown parses and
+converts its input.
+.SH OPTIONS
+.TP
+.B \-i, \-\-input ARG
+Specify the input format. Available input formats: kramdown (this is the default), markdown, GFM or html.
+.TP
+.B \-o, \-\-output ARG
+Specify one or more output formats separated by commas: html (default), kramdown, latex, pdf or
+remove_html_tags.
+.TP
+.B \-v, \-\-version
+Show the version of kramdown.
+.TP
+.B \-h, \-\-help
+Show the help.
+
+.SH KRAMDOWN OPTIONS
+
+.TP
+.B \-\-template ARG
+
+The name of an ERB template file that should be used to wrap the output
+or the ERB template itself.
+
+This is used to wrap the output in an environment so that the output can
+be used as a stand-alone document. For example, an HTML template would
+provide the needed header and body tags so that the whole output is a
+valid HTML file. If no template is specified, the output will be just
+the converted text.
+
+When resolving the template file, the given template name is used first.
+If such a file is not found, the converter extension (the same as the
+converter name) is appended. If the file still cannot be found, the
+templates name is interpreted as a template name that is provided by
+kramdown (without the converter extension). If the file is still not
+found, the template name is checked if it starts with 'string://' and if
+it does, this prefix is removed and the rest is used as template
+content.
+
+kramdown provides a default template named 'document' for each converter.
+
+Default: ''
+Used by: all converters
+
+
+.TP
+.B \-\-[no\-]auto-ids
+
+Use automatic header ID generation
+
+If this option is `true`, ID values for all headers are automatically
+generated if no ID is explicitly specified.
+
+Default: true
+Used by: HTML/Latex converter
+
+
+.TP
+.B \-\-[no\-]auto-id-stripping
+
+Strip all formatting from header text for automatic ID generation
+
+If this option is `true`, only the text elements of a header are used
+for generating the ID later (in contrast to just using the raw header
+text line).
+
+This option will be removed in version 2.0 because this will be the
+default then.
+
+Default: false
+Used by: kramdown parser
+
+
+.TP
+.B \-\-auto-id-prefix ARG
+
+Prefix used for automatically generated header IDs
+
+This option can be used to set a prefix for the automatically generated
+header IDs so that there is no conflict when rendering multiple kramdown
+documents into one output file separately. The prefix should only
+contain characters that are valid in an ID!
+
+Default: ''
+Used by: HTML/Latex converter
+
+
+.TP
+.B \-\-[no\-]transliterated-header-ids
+
+Transliterate the header text before generating the ID
+
+Only ASCII characters are used in headers IDs. This is not good for
+languages with many non-ASCII characters. By enabling this option
+the header text is transliterated to ASCII as good as possible so that
+the resulting header ID is more useful.
+
+The stringex library needs to be installed for this feature to work!
+
+Default: false
+Used by: HTML/Latex converter
+
+
+.TP
+.B \-\-[no\-]parse-block-html
+
+Process kramdown syntax in block HTML tags
+
+If this option is `true`, the kramdown parser processes the content of
+block HTML tags as text containing block-level elements. Since this is
+not wanted normally, the default is `false`. It is normally better to
+selectively enable kramdown processing via the markdown attribute.
+
+Default: false
+Used by: kramdown parser
+
+
+.TP
+.B \-\-[no\-]parse-span-html
+
+Process kramdown syntax in span HTML tags
+
+If this option is `true`, the kramdown parser processes the content of
+span HTML tags as text containing span-level elements.
+
+Default: true
+Used by: kramdown parser
+
+
+.TP
+.B \-\-[no\-]html-to-native
+
+Convert HTML elements to native elements
+
+If this option is `true`, the parser converts HTML elements to native
+elements. For example, when parsing `<em>hallo</em>` the emphasis tag
+would normally be converted to an `:html` element with tag type `:em`.
+If `html_to_native` is `true`, then the emphasis would be converted to a
+native `:em` element.
+
+This is useful for converters that cannot deal with HTML elements.
+
+Default: false
+Used by: kramdown parser
+
+
+.TP
+.B \-\-link-defs ARG
+
+Pre-defines link definitions
+
+This option can be used to pre-define link definitions. The value needs
+to be a Hash where the keys are the link identifiers and the values are
+two element Arrays with the link URL and the link title.
+
+If the value is a String, it has to contain a valid YAML hash and the
+hash has to follow the above guidelines.
+
+Default: {}
+Used by: kramdown parser
+
+
+.TP
+.B \-\-footnote-nr ARG
+
+The number of the first footnote
+
+This option can be used to specify the number that is used for the first
+footnote.
+
+Default: 1
+Used by: HTML converter
+
+
+.TP
+.B \-\-[no\-]enable-coderay
+
+Use coderay for syntax highlighting
+
+If this option is `true`, coderay is used by the HTML converter for
+syntax highlighting the content of code spans and code blocks.
+
+Default: true
+Used by: HTML converter
+
+
+.TP
+.B \-\-coderay-wrap ARG
+
+Defines how the highlighted code should be wrapped
+
+The possible values are :span, :div or nil.
+
+Default: :div
+Used by: HTML converter
+
+
+.TP
+.B \-\-coderay-line-numbers ARG
+
+Defines how and if line numbers should be shown
+
+The possible values are :table, :inline or nil. If this option is
+nil, no line numbers are shown.
+
+Default: :inline
+Used by: HTML converter
+
+
+.TP
+.B \-\-coderay-line-number-start ARG
+
+The start value for the line numbers
+
+Default: 1
+Used by: HTML converter
+
+
+.TP
+.B \-\-coderay-tab-width ARG
+
+The tab width used in highlighted code
+
+Used by: HTML converter
+
+
+.TP
+.B \-\-coderay-bold-every ARG
+
+Defines how often a line number should be made bold
+
+Can either be an integer or false (to turn off bold line numbers
+completely).
+
+Default: 10
+Used by: HTML converter
+
+
+.TP
+.B \-\-coderay-css ARG
+
+Defines how the highlighted code gets styled
+
+Possible values are :class (CSS classes are applied to the code
+elements, one must supply the needed CSS file) or :style (default CSS
+styles are directly applied to the code elements).
+
+Default: style
+Used by: HTML converter
+
+
+.TP
+.B \-\-coderay-default-lang ARG
+
+Sets the default language for highlighting code blocks
+
+If no language is set for a code block, the default language is used
+instead. The value has to be one of the languages supported by coderay
+or nil if no default language should be used.
+
+Default: nil
+Used by: HTML converter
+
+
+.TP
+.B \-\-entity-output ARG
+
+Defines how entities are output
+
+The possible values are :as_input (entities are output in the same
+form as found in the input), :numeric (entities are output in numeric
+form), :symbolic (entities are output in symbolic form if possible) or
+:as_char (entities are output as characters if possible, only available
+on Ruby 1.9).
+
+Default: :as_char
+Used by: HTML converter, kramdown converter
+
+
+.TP
+.B \-\-toc-levels ARG
+
+Defines the levels that are used for the table of contents
+
+The individual levels can be specified by separating them with commas
+(e.g. 1,2,3) or by using the range syntax (e.g. 1..3). Only the
+specified levels are used for the table of contents.
+
+Default: 1..6
+Used by: HTML/Latex converter
+
+
+.TP
+.B \-\-line-width ARG
+
+Defines the line width to be used when outputting a document
+
+Default: 72
+Used by: kramdown converter
+
+
+.TP
+.B \-\-latex-headers ARG
+
+Defines the LaTeX commands for different header levels
+
+The commands for the header levels one to six can be specified by
+separating them with commas.
+
+Default: section,subsection,subsubsection,paragraph,subparagraph,subparagraph
+Used by: Latex converter
+
+
+.TP
+.B \-\-smart-quotes ARG
+
+Defines the HTML entity names or code points for smart quote output
+
+The entities identified by entity name or code point that should be
+used for, in order, a left single quote, a right single quote, a left
+double and a right double quote are specified by separating them with
+commas.
+
+Default: lsquo,rsquo,ldquo,rdquo
+Used by: HTML/Latex converter
+
+
+.TP
+.B \-\-[no\-]remove-block-html-tags
+
+Remove block HTML tags
+
+If this option is `true`, the RemoveHtmlTags converter removes
+block HTML tags.
+
+Default: true
+Used by: RemoveHtmlTags converter
+
+
+.TP
+.B \-\-[no\-]remove-span-html-tags
+
+Remove span HTML tags
+
+If this option is `true`, the RemoveHtmlTags converter removes
+span HTML tags.
+
+Default: false
+Used by: RemoveHtmlTags converter
+
+
+.TP
+.B \-\-header-offset ARG
+
+Sets the output offset for headers
+
+If this option is c (may also be negative) then a header with level n
+will be output as a header with level c+n. If c+n is lower than 1,
+level 1 will be used. If c+n is greater than 6, level 6 will be used.
+
+Default: 0
+Used by: HTML converter, Kramdown converter, Latex converter
+
+
+.TP
+.B \-\-[no\-]hard-wrap
+
+Interprets line breaks literally
+
+Insert HTML `<br />` tags inside paragraphs where the original Markdown
+document had newlines (by default, Markdown ignores these newlines).
+
+Default: true
+Used by: GFM parser
+
+
+.SH EXIT STATUS
+The exit status is 0 if no error happened. Otherwise it is 1.
+.SH SEE ALSO
+The kramdown website, http://kramdown.gettalong.org/ for more information, especially on the supported
+input syntax.
+.SH AUTHOR
+kramdown was written by Thomas Leitner <t_leitner at gmx.at>.
+.PP
+This manual page was written by Thomas Leitner <t_leitner at gmx.at>.
+
diff --git a/app/server/vendor/kramdown/setup.rb b/app/server/vendor/kramdown/setup.rb
new file mode 100644
index 0000000..4f1e198
--- /dev/null
+++ b/app/server/vendor/kramdown/setup.rb
@@ -0,0 +1,1585 @@
+#
+# setup.rb
+#
+# Copyright (c) 2000-2005 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the terms of
+# the GNU LGPL, Lesser General Public License version 2.1.
+#
+
+unless Enumerable.method_defined?(:map)   # Ruby 1.4.6
+  module Enumerable
+    alias map collect
+  end
+end
+
+unless File.respond_to?(:read)   # Ruby 1.6
+  def File.read(fname)
+    open(fname) {|f|
+      return f.read
+    }
+  end
+end
+
+unless Errno.const_defined?(:ENOTEMPTY)   # Windows?
+  module Errno
+    class ENOTEMPTY
+      # We do not raise this exception, implementation is not needed.
+    end
+  end
+end
+
+def File.binread(fname)
+  open(fname, 'rb') {|f|
+    return f.read
+  }
+end
+
+# for corrupted Windows' stat(2)
+def File.dir?(path)
+  File.directory?((path[-1,1] == '/') ? path : path + '/')
+end
+
+
+class ConfigTable
+
+  include Enumerable
+
+  def initialize(rbconfig)
+    @rbconfig = rbconfig
+    @items = []
+    @table = {}
+    # options
+    @install_prefix = nil
+    @config_opt = nil
+    @verbose = true
+    @no_harm = false
+  end
+
+  attr_accessor :install_prefix
+  attr_accessor :config_opt
+
+  attr_writer :verbose
+
+  def verbose?
+    @verbose
+  end
+
+  attr_writer :no_harm
+
+  def no_harm?
+    @no_harm
+  end
+
+  def [](key)
+    lookup(key).resolve(self)
+  end
+
+  def []=(key, val)
+    lookup(key).set val
+  end
+
+  def names
+    @items.map {|i| i.name }
+  end
+
+  def each(&block)
+    @items.each(&block)
+  end
+
+  def key?(name)
+    @table.key?(name)
+  end
+
+  def lookup(name)
+    @table[name] or setup_rb_error "no such config item: #{name}"
+  end
+
+  def add(item)
+    @items.push item
+    @table[item.name] = item
+  end
+
+  def remove(name)
+    item = lookup(name)
+    @items.delete_if {|i| i.name == name }
+    @table.delete_if {|name, i| i.name == name }
+    item
+  end
+
+  def load_script(path, inst = nil)
+    if File.file?(path)
+      MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path
+    end
+  end
+
+  def savefile
+    '.config'
+  end
+
+  def load_savefile
+    begin
+      File.foreach(savefile()) do |line|
+        k, v = *line.split(/=/, 2)
+        self[k] = v.strip
+      end
+    rescue Errno::ENOENT
+      setup_rb_error $!.message + "\n#{File.basename($0)} config first"
+    end
+  end
+
+  def save
+    @items.each {|i| i.value }
+    File.open(savefile(), 'w') {|f|
+      @items.each do |i|
+        f.printf "%s=%s\n", i.name, i.value if i.value? and i.value
+      end
+    }
+  end
+
+  def load_standard_entries
+    standard_entries(@rbconfig).each do |ent|
+      add ent
+    end
+  end
+
+  def standard_entries(rbconfig)
+    c = rbconfig
+
+    rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT'])
+
+    major = c['MAJOR'].to_i
+    minor = c['MINOR'].to_i
+    teeny = c['TEENY'].to_i
+    version = "#{major}.#{minor}"
+
+    # ruby ver. >= 1.4.4?
+    newpath_p = ((major >= 2) or
+                 ((major == 1) and
+                  ((minor >= 5) or
+                   ((minor == 4) and (teeny >= 4)))))
+
+    if c['rubylibdir']
+      # V > 1.6.3
+      libruby         = "#{c['prefix']}/lib/ruby"
+      librubyver      = c['rubylibdir']
+      librubyverarch  = c['archdir']
+      siteruby        = c['sitedir']
+      siterubyver     = c['sitelibdir']
+      siterubyverarch = c['sitearchdir']
+    elsif newpath_p
+      # 1.4.4 <= V <= 1.6.3
+      libruby         = "#{c['prefix']}/lib/ruby"
+      librubyver      = "#{c['prefix']}/lib/ruby/#{version}"
+      librubyverarch  = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
+      siteruby        = c['sitedir']
+      siterubyver     = "$siteruby/#{version}"
+      siterubyverarch = "$siterubyver/#{c['arch']}"
+    else
+      # V < 1.4.4
+      libruby         = "#{c['prefix']}/lib/ruby"
+      librubyver      = "#{c['prefix']}/lib/ruby/#{version}"
+      librubyverarch  = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
+      siteruby        = "#{c['prefix']}/lib/ruby/#{version}/site_ruby"
+      siterubyver     = siteruby
+      siterubyverarch = "$siterubyver/#{c['arch']}"
+    end
+    parameterize = lambda {|path|
+      path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')
+    }
+
+    if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
+      makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
+    else
+      makeprog = 'make'
+    end
+
+    [
+      ExecItem.new('installdirs', 'std/site/home',
+                   'std: install under libruby; site: install under site_ruby; home: install under $HOME')\
+          {|val, table|
+            case val
+            when 'std'
+              table['rbdir'] = '$librubyver'
+              table['sodir'] = '$librubyverarch'
+            when 'site'
+              table['rbdir'] = '$siterubyver'
+              table['sodir'] = '$siterubyverarch'
+            when 'home'
+              setup_rb_error '$HOME was not set' unless ENV['HOME']
+              table['prefix'] = ENV['HOME']
+              table['rbdir'] = '$libdir/ruby'
+              table['sodir'] = '$libdir/ruby'
+            end
+          },
+      PathItem.new('prefix', 'path', c['prefix'],
+                   'path prefix of target environment'),
+      PathItem.new('bindir', 'path', parameterize.call(c['bindir']),
+                   'the directory for commands'),
+      PathItem.new('libdir', 'path', parameterize.call(c['libdir']),
+                   'the directory for libraries'),
+      PathItem.new('datadir', 'path', parameterize.call(c['datadir']),
+                   'the directory for shared data'),
+      PathItem.new('mandir', 'path', parameterize.call(c['mandir']),
+                   'the directory for man pages'),
+      PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']),
+                   'the directory for system configuration files'),
+      PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']),
+                   'the directory for local state data'),
+      PathItem.new('libruby', 'path', libruby,
+                   'the directory for ruby libraries'),
+      PathItem.new('librubyver', 'path', librubyver,
+                   'the directory for standard ruby libraries'),
+      PathItem.new('librubyverarch', 'path', librubyverarch,
+                   'the directory for standard ruby extensions'),
+      PathItem.new('siteruby', 'path', siteruby,
+          'the directory for version-independent aux ruby libraries'),
+      PathItem.new('siterubyver', 'path', siterubyver,
+                   'the directory for aux ruby libraries'),
+      PathItem.new('siterubyverarch', 'path', siterubyverarch,
+                   'the directory for aux ruby binaries'),
+      PathItem.new('rbdir', 'path', '$siterubyver',
+                   'the directory for ruby scripts'),
+      PathItem.new('sodir', 'path', '$siterubyverarch',
+                   'the directory for ruby extentions'),
+      PathItem.new('rubypath', 'path', rubypath,
+                   'the path to set to #! line'),
+      ProgramItem.new('rubyprog', 'name', rubypath,
+                      'the ruby program using for installation'),
+      ProgramItem.new('makeprog', 'name', makeprog,
+                      'the make program to compile ruby extentions'),
+      SelectItem.new('shebang', 'all/ruby/never', 'ruby',
+                     'shebang line (#!) editing mode'),
+      BoolItem.new('without-ext', 'yes/no', 'no',
+                   'does not compile/install ruby extentions')
+    ]
+  end
+  private :standard_entries
+
+  def load_multipackage_entries
+    multipackage_entries().each do |ent|
+      add ent
+    end
+  end
+
+  def multipackage_entries
+    [
+      PackageSelectionItem.new('with', 'name,name...', '', 'ALL',
+                               'package names that you want to install'),
+      PackageSelectionItem.new('without', 'name,name...', '', 'NONE',
+                               'package names that you do not want to install')
+    ]
+  end
+  private :multipackage_entries
+
+  ALIASES = {
+    'std-ruby'         => 'librubyver',
+    'stdruby'          => 'librubyver',
+    'rubylibdir'       => 'librubyver',
+    'archdir'          => 'librubyverarch',
+    'site-ruby-common' => 'siteruby',     # For backward compatibility
+    'site-ruby'        => 'siterubyver',  # For backward compatibility
+    'bin-dir'          => 'bindir',
+    'bin-dir'          => 'bindir',
+    'rb-dir'           => 'rbdir',
+    'so-dir'           => 'sodir',
+    'data-dir'         => 'datadir',
+    'ruby-path'        => 'rubypath',
+    'ruby-prog'        => 'rubyprog',
+    'ruby'             => 'rubyprog',
+    'make-prog'        => 'makeprog',
+    'make'             => 'makeprog'
+  }
+
+  def fixup
+    ALIASES.each do |ali, name|
+      @table[ali] = @table[name]
+    end
+    @items.freeze
+    @table.freeze
+    @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/
+  end
+
+  def parse_opt(opt)
+    m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}"
+    m.to_a[1,2]
+  end
+
+  def dllext
+    @rbconfig['DLEXT']
+  end
+
+  def value_config?(name)
+    lookup(name).value?
+  end
+
+  class Item
+    def initialize(name, template, default, desc)
+      @name = name.freeze
+      @template = template
+      @value = default
+      @default = default
+      @description = desc
+    end
+
+    attr_reader :name
+    attr_reader :description
+
+    attr_accessor :default
+    alias help_default default
+
+    def help_opt
+      "--#{@name}=#{@template}"
+    end
+
+    def value?
+      true
+    end
+
+    def value
+      @value
+    end
+
+    def resolve(table)
+      @value.gsub(%r<\$([^/]+)>) { table[$1] }
+    end
+
+    def set(val)
+      @value = check(val)
+    end
+
+    private
+
+    def check(val)
+      setup_rb_error "config: --#{name} requires argument" unless val
+      val
+    end
+  end
+
+  class BoolItem < Item
+    def config_type
+      'bool'
+    end
+
+    def help_opt
+      "--#{@name}"
+    end
+
+    private
+
+    def check(val)
+      return 'yes' unless val
+      case val
+      when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes'
+      when /\An(o)?\z/i, /\Af(alse)\z/i  then 'no'
+      else
+        setup_rb_error "config: --#{@name} accepts only yes/no for argument"
+      end
+    end
+  end
+
+  class PathItem < Item
+    def config_type
+      'path'
+    end
+
+    private
+
+    def check(path)
+      setup_rb_error "config: --#{@name} requires argument"  unless path
+      path[0,1] == '$' ? path : File.expand_path(path)
+    end
+  end
+
+  class ProgramItem < Item
+    def config_type
+      'program'
+    end
+  end
+
+  class SelectItem < Item
+    def initialize(name, selection, default, desc)
+      super
+      @ok = selection.split('/')
+    end
+
+    def config_type
+      'select'
+    end
+
+    private
+
+    def check(val)
+      unless @ok.include?(val.strip)
+        setup_rb_error "config: use --#{@name}=#{@template} (#{val})"
+      end
+      val.strip
+    end
+  end
+
+  class ExecItem < Item
+    def initialize(name, selection, desc, &block)
+      super name, selection, nil, desc
+      @ok = selection.split('/')
+      @action = block
+    end
+
+    def config_type
+      'exec'
+    end
+
+    def value?
+      false
+    end
+
+    def resolve(table)
+      setup_rb_error "$#{name()} wrongly used as option value"
+    end
+
+    undef set
+
+    def evaluate(val, table)
+      v = val.strip.downcase
+      unless @ok.include?(v)
+        setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})"
+      end
+      @action.call v, table
+    end
+  end
+
+  class PackageSelectionItem < Item
+    def initialize(name, template, default, help_default, desc)
+      super name, template, default, desc
+      @help_default = help_default
+    end
+
+    attr_reader :help_default
+
+    def config_type
+      'package'
+    end
+
+    private
+
+    def check(val)
+      unless File.dir?("packages/#{val}")
+        setup_rb_error "config: no such package: #{val}"
+      end
+      val
+    end
+  end
+
+  class MetaConfigEnvironment
+    def initialize(config, installer)
+      @config = config
+      @installer = installer
+    end
+
+    def config_names
+      @config.names
+    end
+
+    def config?(name)
+      @config.key?(name)
+    end
+
+    def bool_config?(name)
+      @config.lookup(name).config_type == 'bool'
+    end
+
+    def path_config?(name)
+      @config.lookup(name).config_type == 'path'
+    end
+
+    def value_config?(name)
+      @config.lookup(name).config_type != 'exec'
+    end
+
+    def add_config(item)
+      @config.add item
+    end
+
+    def add_bool_config(name, default, desc)
+      @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc)
+    end
+
+    def add_path_config(name, default, desc)
+      @config.add PathItem.new(name, 'path', default, desc)
+    end
+
+    def set_config_default(name, default)
+      @config.lookup(name).default = default
+    end
+
+    def remove_config(name)
+      @config.remove(name)
+    end
+
+    # For only multipackage
+    def packages
+      raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer
+      @installer.packages
+    end
+
+    # For only multipackage
+    def declare_packages(list)
+      raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer
+      @installer.packages = list
+    end
+  end
+
+end   # class ConfigTable
+
+
+# This module requires: #verbose?, #no_harm?
+module FileOperations
+
+  def mkdir_p(dirname, prefix = nil)
+    dirname = prefix + File.expand_path(dirname) if prefix
+    $stderr.puts "mkdir -p #{dirname}" if verbose?
+    return if no_harm?
+
+    # Does not check '/', it's too abnormal.
+    dirs = File.expand_path(dirname).split(%r<(?=/)>)
+    if /\A[a-z]:\z/i =~ dirs[0]
+      disk = dirs.shift
+      dirs[0] = disk + dirs[0]
+    end
+    dirs.each_index do |idx|
+      path = dirs[0..idx].join('')
+      Dir.mkdir path unless File.dir?(path)
+    end
+  end
+
+  def rm_f(path)
+    $stderr.puts "rm -f #{path}" if verbose?
+    return if no_harm?
+    force_remove_file path
+  end
+
+  def rm_rf(path)
+    $stderr.puts "rm -rf #{path}" if verbose?
+    return if no_harm?
+    remove_tree path
+  end
+
+  def remove_tree(path)
+    if File.symlink?(path)
+      remove_file path
+    elsif File.dir?(path)
+      remove_tree0 path
+    else
+      force_remove_file path
+    end
+  end
+
+  def remove_tree0(path)
+    Dir.foreach(path) do |ent|
+      next if ent == '.'
+      next if ent == '..'
+      entpath = "#{path}/#{ent}"
+      if File.symlink?(entpath)
+        remove_file entpath
+      elsif File.dir?(entpath)
+        remove_tree0 entpath
+      else
+        force_remove_file entpath
+      end
+    end
+    begin
+      Dir.rmdir path
+    rescue Errno::ENOTEMPTY
+      # directory may not be empty
+    end
+  end
+
+  def move_file(src, dest)
+    force_remove_file dest
+    begin
+      File.rename src, dest
+    rescue
+      File.open(dest, 'wb') {|f|
+        f.write File.binread(src)
+      }
+      File.chmod File.stat(src).mode, dest
+      File.unlink src
+    end
+  end
+
+  def force_remove_file(path)
+    begin
+      remove_file path
+    rescue
+    end
+  end
+
+  def remove_file(path)
+    File.chmod 0777, path
+    File.unlink path
+  end
+
+  def install(from, dest, mode, prefix = nil)
+    $stderr.puts "install #{from} #{dest}" if verbose?
+    return if no_harm?
+
+    realdest = prefix ? prefix + File.expand_path(dest) : dest
+    realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
+    str = File.binread(from)
+    if diff?(str, realdest)
+      verbose_off {
+        rm_f realdest if File.exist?(realdest)
+      }
+      File.open(realdest, 'wb') {|f|
+        f.write str
+      }
+      File.chmod mode, realdest
+
+      File.open("#{objdir_root()}/InstalledFiles", 'a') {|f|
+        if prefix
+          f.puts realdest.sub(prefix, '')
+        else
+          f.puts realdest
+        end
+      }
+    end
+  end
+
+  def diff?(new_content, path)
+    return true unless File.exist?(path)
+    new_content != File.binread(path)
+  end
+
+  def command(*args)
+    $stderr.puts args.join(' ') if verbose?
+    system(*args) or raise RuntimeError,
+        "system(#{args.map{|a| a.inspect }.join(' ')}) failed"
+  end
+
+  def ruby(*args)
+    command config('rubyprog'), *args
+  end
+  
+  def make(task = nil)
+    command(*[config('makeprog'), task].compact)
+  end
+
+  def extdir?(dir)
+    File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb")
+  end
+
+  def files_of(dir)
+    Dir.open(dir) {|d|
+      return d.select {|ent| File.file?("#{dir}/#{ent}") }
+    }
+  end
+
+  DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn )
+
+  def directories_of(dir)
+    Dir.open(dir) {|d|
+      return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT
+    }
+  end
+
+end
+
+
+# This module requires: #srcdir_root, #objdir_root, #relpath
+module HookScriptAPI
+
+  def get_config(key)
+    @config[key]
+  end
+
+  alias config get_config
+
+  # obsolete: use metaconfig to change configuration
+  def set_config(key, val)
+    @config[key] = val
+  end
+
+  #
+  # srcdir/objdir (works only in the package directory)
+  #
+
+  def curr_srcdir
+    "#{srcdir_root()}/#{relpath()}"
+  end
+
+  def curr_objdir
+    "#{objdir_root()}/#{relpath()}"
+  end
+
+  def srcfile(path)
+    "#{curr_srcdir()}/#{path}"
+  end
+
+  def srcexist?(path)
+    File.exist?(srcfile(path))
+  end
+
+  def srcdirectory?(path)
+    File.dir?(srcfile(path))
+  end
+  
+  def srcfile?(path)
+    File.file?(srcfile(path))
+  end
+
+  def srcentries(path = '.')
+    Dir.open("#{curr_srcdir()}/#{path}") {|d|
+      return d.to_a - %w(. ..)
+    }
+  end
+
+  def srcfiles(path = '.')
+    srcentries(path).select {|fname|
+      File.file?(File.join(curr_srcdir(), path, fname))
+    }
+  end
+
+  def srcdirectories(path = '.')
+    srcentries(path).select {|fname|
+      File.dir?(File.join(curr_srcdir(), path, fname))
+    }
+  end
+
+end
+
+
+class ToplevelInstaller
+
+  Version   = '3.4.1'
+  Copyright = 'Copyright (c) 2000-2005 Minero Aoki'
+
+  TASKS = [
+    [ 'all',      'do config, setup, then install' ],
+    [ 'config',   'saves your configurations' ],
+    [ 'show',     'shows current configuration' ],
+    [ 'setup',    'compiles ruby extentions and others' ],
+    [ 'install',  'installs files' ],
+    [ 'test',     'run all tests in test/' ],
+    [ 'clean',    "does `make clean' for each extention" ],
+    [ 'distclean',"does `make distclean' for each extention" ]
+  ]
+
+  def ToplevelInstaller.invoke
+    config = ConfigTable.new(load_rbconfig())
+    config.load_standard_entries
+    config.load_multipackage_entries if multipackage?
+    config.fixup
+    klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller)
+    klass.new(File.dirname($0), config).invoke
+  end
+
+  def ToplevelInstaller.multipackage?
+    File.dir?(File.dirname($0) + '/packages')
+  end
+
+  def ToplevelInstaller.load_rbconfig
+    if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
+      ARGV.delete(arg)
+      load File.expand_path(arg.split(/=/, 2)[1])
+      $".push 'rbconfig.rb'
+    else
+      require 'rbconfig'
+    end
+    ::RbConfig::CONFIG
+  end
+
+  def initialize(ardir_root, config)
+    @ardir = File.expand_path(ardir_root)
+    @config = config
+    # cache
+    @valid_task_re = nil
+  end
+
+  def config(key)
+    @config[key]
+  end
+
+  def inspect
+    "#<#{self.class} #{__id__()}>"
+  end
+
+  def invoke
+    run_metaconfigs
+    case task = parsearg_global()
+    when nil, 'all'
+      parsearg_config
+      init_installers
+      exec_config
+      exec_setup
+      exec_install
+    else
+      case task
+      when 'config', 'test'
+        ;
+      when 'clean', 'distclean'
+        @config.load_savefile if File.exist?(@config.savefile)
+      else
+        @config.load_savefile
+      end
+      __send__ "parsearg_#{task}"
+      init_installers
+      __send__ "exec_#{task}"
+    end
+  end
+  
+  def run_metaconfigs
+    @config.load_script "#{@ardir}/metaconfig"
+  end
+
+  def init_installers
+    @installer = Installer.new(@config, @ardir, File.expand_path('.'))
+  end
+
+  #
+  # Hook Script API bases
+  #
+
+  def srcdir_root
+    @ardir
+  end
+
+  def objdir_root
+    '.'
+  end
+
+  def relpath
+    '.'
+  end
+
+  #
+  # Option Parsing
+  #
+
+  def parsearg_global
+    while arg = ARGV.shift
+      case arg
+      when /\A\w+\z/
+        setup_rb_error "invalid task: #{arg}" unless valid_task?(arg)
+        return arg
+      when '-q', '--quiet'
+        @config.verbose = false
+      when '--verbose'
+        @config.verbose = true
+      when '--help'
+        print_usage $stdout
+        exit 0
+      when '--version'
+        puts "#{File.basename($0)} version #{Version}"
+        exit 0
+      when '--copyright'
+        puts Copyright
+        exit 0
+      else
+        setup_rb_error "unknown global option '#{arg}'"
+      end
+    end
+    nil
+  end
+
+  def valid_task?(t)
+    valid_task_re() =~ t
+  end
+
+  def valid_task_re
+    @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/
+  end
+
+  def parsearg_no_options
+    unless ARGV.empty?
+      task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1)
+      setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}"
+    end
+  end
+
+  alias parsearg_show       parsearg_no_options
+  alias parsearg_setup      parsearg_no_options
+  alias parsearg_test       parsearg_no_options
+  alias parsearg_clean      parsearg_no_options
+  alias parsearg_distclean  parsearg_no_options
+
+  def parsearg_config
+    evalopt = []
+    set = []
+    @config.config_opt = []
+    while i = ARGV.shift
+      if /\A--?\z/ =~ i
+        @config.config_opt = ARGV.dup
+        break
+      end
+      name, value = *@config.parse_opt(i)
+      if @config.value_config?(name)
+        @config[name] = value
+      else
+        evalopt.push [name, value]
+      end
+      set.push name
+    end
+    evalopt.each do |name, value|
+      @config.lookup(name).evaluate value, @config
+    end
+    # Check if configuration is valid
+    set.each do |n|
+      @config[n] if @config.value_config?(n)
+    end
+  end
+
+  def parsearg_install
+    @config.no_harm = false
+    @config.install_prefix = ''
+    while a = ARGV.shift
+      case a
+      when '--no-harm'
+        @config.no_harm = true
+      when /\A--prefix=/
+        path = a.split(/=/, 2)[1]
+        path = File.expand_path(path) unless path[0,1] == '/'
+        @config.install_prefix = path
+      else
+        setup_rb_error "install: unknown option #{a}"
+      end
+    end
+  end
+
+  def print_usage(out)
+    out.puts 'Typical Installation Procedure:'
+    out.puts "  $ ruby #{File.basename $0} config"
+    out.puts "  $ ruby #{File.basename $0} setup"
+    out.puts "  # ruby #{File.basename $0} install (may require root privilege)"
+    out.puts
+    out.puts 'Detailed Usage:'
+    out.puts "  ruby #{File.basename $0} <global option>"
+    out.puts "  ruby #{File.basename $0} [<global options>] <task> [<task options>]"
+
+    fmt = "  %-24s %s\n"
+    out.puts
+    out.puts 'Global options:'
+    out.printf fmt, '-q,--quiet',   'suppress message outputs'
+    out.printf fmt, '   --verbose', 'output messages verbosely'
+    out.printf fmt, '   --help',    'print this message'
+    out.printf fmt, '   --version', 'print version and quit'
+    out.printf fmt, '   --copyright',  'print copyright and quit'
+    out.puts
+    out.puts 'Tasks:'
+    TASKS.each do |name, desc|
+      out.printf fmt, name, desc
+    end
+
+    fmt = "  %-24s %s [%s]\n"
+    out.puts
+    out.puts 'Options for CONFIG or ALL:'
+    @config.each do |item|
+      out.printf fmt, item.help_opt, item.description, item.help_default
+    end
+    out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's"
+    out.puts
+    out.puts 'Options for INSTALL:'
+    out.printf fmt, '--no-harm', 'only display what to do if given', 'off'
+    out.printf fmt, '--prefix=path',  'install path prefix', ''
+    out.puts
+  end
+
+  #
+  # Task Handlers
+  #
+
+  def exec_config
+    @installer.exec_config
+    @config.save   # must be final
+  end
+
+  def exec_setup
+    @installer.exec_setup
+  end
+
+  def exec_install
+    @installer.exec_install
+  end
+
+  def exec_test
+    @installer.exec_test
+  end
+
+  def exec_show
+    @config.each do |i|
+      printf "%-20s %s\n", i.name, i.value if i.value?
+    end
+  end
+
+  def exec_clean
+    @installer.exec_clean
+  end
+
+  def exec_distclean
+    @installer.exec_distclean
+  end
+
+end   # class ToplevelInstaller
+
+
+class ToplevelInstallerMulti < ToplevelInstaller
+
+  include FileOperations
+
+  def initialize(ardir_root, config)
+    super
+    @packages = directories_of("#{@ardir}/packages")
+    raise 'no package exists' if @packages.empty?
+    @root_installer = Installer.new(@config, @ardir, File.expand_path('.'))
+  end
+
+  def run_metaconfigs
+    @config.load_script "#{@ardir}/metaconfig", self
+    @packages.each do |name|
+      @config.load_script "#{@ardir}/packages/#{name}/metaconfig"
+    end
+  end
+
+  attr_reader :packages
+
+  def packages=(list)
+    raise 'package list is empty' if list.empty?
+    list.each do |name|
+      raise "directory packages/#{name} does not exist"\
+              unless File.dir?("#{@ardir}/packages/#{name}")
+    end
+    @packages = list
+  end
+
+  def init_installers
+    @installers = {}
+    @packages.each do |pack|
+      @installers[pack] = Installer.new(@config,
+                                       "#{@ardir}/packages/#{pack}",
+                                       "packages/#{pack}")
+    end
+    with    = extract_selection(config('with'))
+    without = extract_selection(config('without'))
+    @selected = @installers.keys.select {|name|
+                  (with.empty? or with.include?(name)) \
+                      and not without.include?(name)
+                }
+  end
+
+  def extract_selection(list)
+    a = list.split(/,/)
+    a.each do |name|
+      setup_rb_error "no such package: #{name}"  unless @installers.key?(name)
+    end
+    a
+  end
+
+  def print_usage(f)
+    super
+    f.puts 'Inluded packages:'
+    f.puts '  ' + @packages.sort.join(' ')
+    f.puts
+  end
+
+  #
+  # Task Handlers
+  #
+
+  def exec_config
+    run_hook 'pre-config'
+    each_selected_installers {|inst| inst.exec_config }
+    run_hook 'post-config'
+    @config.save   # must be final
+  end
+
+  def exec_setup
+    run_hook 'pre-setup'
+    each_selected_installers {|inst| inst.exec_setup }
+    run_hook 'post-setup'
+  end
+
+  def exec_install
+    run_hook 'pre-install'
+    each_selected_installers {|inst| inst.exec_install }
+    run_hook 'post-install'
+  end
+
+  def exec_test
+    run_hook 'pre-test'
+    each_selected_installers {|inst| inst.exec_test }
+    run_hook 'post-test'
+  end
+
+  def exec_clean
+    rm_f @config.savefile
+    run_hook 'pre-clean'
+    each_selected_installers {|inst| inst.exec_clean }
+    run_hook 'post-clean'
+  end
+
+  def exec_distclean
+    rm_f @config.savefile
+    run_hook 'pre-distclean'
+    each_selected_installers {|inst| inst.exec_distclean }
+    run_hook 'post-distclean'
+  end
+
+  #
+  # lib
+  #
+
+  def each_selected_installers
+    Dir.mkdir 'packages' unless File.dir?('packages')
+    @selected.each do |pack|
+      $stderr.puts "Processing the package `#{pack}' ..." if verbose?
+      Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
+      Dir.chdir "packages/#{pack}"
+      yield @installers[pack]
+      Dir.chdir '../..'
+    end
+  end
+
+  def run_hook(id)
+    @root_installer.run_hook id
+  end
+
+  # module FileOperations requires this
+  def verbose?
+    @config.verbose?
+  end
+
+  # module FileOperations requires this
+  def no_harm?
+    @config.no_harm?
+  end
+
+end   # class ToplevelInstallerMulti
+
+
+class Installer
+
+  FILETYPES = %w( bin lib ext data conf man )
+
+  include FileOperations
+  include HookScriptAPI
+
+  def initialize(config, srcroot, objroot)
+    @config = config
+    @srcdir = File.expand_path(srcroot)
+    @objdir = File.expand_path(objroot)
+    @currdir = '.'
+  end
+
+  def inspect
+    "#<#{self.class} #{File.basename(@srcdir)}>"
+  end
+
+  def noop(rel)
+  end
+
+  #
+  # Hook Script API base methods
+  #
+
+  def srcdir_root
+    @srcdir
+  end
+
+  def objdir_root
+    @objdir
+  end
+
+  def relpath
+    @currdir
+  end
+
+  #
+  # Config Access
+  #
+
+  # module FileOperations requires this
+  def verbose?
+    @config.verbose?
+  end
+
+  # module FileOperations requires this
+  def no_harm?
+    @config.no_harm?
+  end
+
+  def verbose_off
+    begin
+      save, @config.verbose = @config.verbose?, false
+      yield
+    ensure
+      @config.verbose = save
+    end
+  end
+
+  #
+  # TASK config
+  #
+
+  def exec_config
+    exec_task_traverse 'config'
+  end
+
+  alias config_dir_bin noop
+  alias config_dir_lib noop
+
+  def config_dir_ext(rel)
+    extconf if extdir?(curr_srcdir())
+  end
+
+  alias config_dir_data noop
+  alias config_dir_conf noop
+  alias config_dir_man noop
+
+  def extconf
+    ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt
+  end
+
+  #
+  # TASK setup
+  #
+
+  def exec_setup
+    exec_task_traverse 'setup'
+  end
+
+  def setup_dir_bin(rel)
+    files_of(curr_srcdir()).each do |fname|
+      update_shebang_line "#{curr_srcdir()}/#{fname}"
+    end
+  end
+
+  alias setup_dir_lib noop
+
+  def setup_dir_ext(rel)
+    make if extdir?(curr_srcdir())
+  end
+
+  alias setup_dir_data noop
+  alias setup_dir_conf noop
+  alias setup_dir_man noop
+
+  def update_shebang_line(path)
+    return if no_harm?
+    return if config('shebang') == 'never'
+    old = Shebang.load(path)
+    if old
+      $stderr.puts "warning: #{path}: Shebang line includes too many args.  It is not portable and your program may not work." if old.args.size > 1
+      new = new_shebang(old)
+      return if new.to_s == old.to_s
+    else
+      return unless config('shebang') == 'all'
+      new = Shebang.new(config('rubypath'))
+    end
+    $stderr.puts "updating shebang: #{File.basename(path)}" if verbose?
+    open_atomic_writer(path) {|output|
+      File.open(path, 'rb') {|f|
+        f.gets if old   # discard
+        output.puts new.to_s
+        output.print f.read
+      }
+    }
+  end
+
+  def new_shebang(old)
+    if /\Aruby/ =~ File.basename(old.cmd)
+      Shebang.new(config('rubypath'), old.args)
+    elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby'
+      Shebang.new(config('rubypath'), old.args[1..-1])
+    else
+      return old unless config('shebang') == 'all'
+      Shebang.new(config('rubypath'))
+    end
+  end
+
+  def open_atomic_writer(path, &block)
+    tmpfile = File.basename(path) + '.tmp'
+    begin
+      File.open(tmpfile, 'wb', &block)
+      File.rename tmpfile, File.basename(path)
+    ensure
+      File.unlink tmpfile if File.exist?(tmpfile)
+    end
+  end
+
+  class Shebang
+    def Shebang.load(path)
+      line = nil
+      File.open(path) {|f|
+        line = f.gets
+      }
+      return nil unless /\A#!/ =~ line
+      parse(line)
+    end
+
+    def Shebang.parse(line)
+      cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ')
+      new(cmd, args)
+    end
+
+    def initialize(cmd, args = [])
+      @cmd = cmd
+      @args = args
+    end
+
+    attr_reader :cmd
+    attr_reader :args
+
+    def to_s
+      "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}")
+    end
+  end
+
+  #
+  # TASK install
+  #
+
+  def exec_install
+    rm_f 'InstalledFiles'
+    exec_task_traverse 'install'
+  end
+
+  def install_dir_bin(rel)
+    install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755
+  end
+
+  def install_dir_lib(rel)
+    install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644
+  end
+
+  def install_dir_ext(rel)
+    return unless extdir?(curr_srcdir())
+    install_files rubyextentions('.'),
+                  "#{config('sodir')}/#{File.dirname(rel)}",
+                  0555
+  end
+
+  def install_dir_data(rel)
+    install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644
+  end
+
+  def install_dir_conf(rel)
+    # FIXME: should not remove current config files
+    # (rename previous file to .old/.org)
+    install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644
+  end
+
+  def install_dir_man(rel)
+    install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644
+  end
+
+  def install_files(list, dest, mode)
+    mkdir_p dest, @config.install_prefix
+    list.each do |fname|
+      install fname, dest, mode, @config.install_prefix
+    end
+  end
+
+  def libfiles
+    glob_reject(%w(*.y *.output), targetfiles())
+  end
+
+  def rubyextentions(dir)
+    ents = glob_select("*.#{@config.dllext}", targetfiles())
+    if ents.empty?
+      setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first"
+    end
+    ents
+  end
+
+  def targetfiles
+    mapdir(existfiles() - hookfiles())
+  end
+
+  def mapdir(ents)
+    ents.map {|ent|
+      if File.exist?(ent)
+      then ent                         # objdir
+      else "#{curr_srcdir()}/#{ent}"   # srcdir
+      end
+    }
+  end
+
+  # picked up many entries from cvs-1.11.1/src/ignore.c
+  JUNK_FILES = %w( 
+    core RCSLOG tags TAGS .make.state
+    .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
+    *~ *.old *.bak *.BAK *.orig *.rej _$* *$
+
+    *.org *.in .*
+  )
+
+  def existfiles
+    glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.')))
+  end
+
+  def hookfiles
+    %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|
+      %w( config setup install clean ).map {|t| sprintf(fmt, t) }
+    }.flatten
+  end
+
+  def glob_select(pat, ents)
+    re = globs2re([pat])
+    ents.select {|ent| re =~ ent }
+  end
+
+  def glob_reject(pats, ents)
+    re = globs2re(pats)
+    ents.reject {|ent| re =~ ent }
+  end
+
+  GLOB2REGEX = {
+    '.' => '\.',
+    '$' => '\$',
+    '#' => '\#',
+    '*' => '.*'
+  }
+
+  def globs2re(pats)
+    /\A(?:#{
+      pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|')
+    })\z/
+  end
+
+  #
+  # TASK test
+  #
+
+  TESTDIR = 'test'
+
+  def exec_test
+    unless File.directory?('test')
+      $stderr.puts 'no test in this package' if verbose?
+      return
+    end
+    $stderr.puts 'Running tests...' if verbose?
+    begin
+      require 'test/unit'
+    rescue LoadError
+      setup_rb_error 'test/unit cannot loaded.  You need Ruby 1.8 or later to invoke this task.'
+    end
+    runner = Test::Unit::AutoRunner.new(true)
+    runner.to_run << TESTDIR
+    runner.run
+  end
+
+  #
+  # TASK clean
+  #
+
+  def exec_clean
+    exec_task_traverse 'clean'
+    rm_f @config.savefile
+    rm_f 'InstalledFiles'
+  end
+
+  alias clean_dir_bin noop
+  alias clean_dir_lib noop
+  alias clean_dir_data noop
+  alias clean_dir_conf noop
+  alias clean_dir_man noop
+
+  def clean_dir_ext(rel)
+    return unless extdir?(curr_srcdir())
+    make 'clean' if File.file?('Makefile')
+  end
+
+  #
+  # TASK distclean
+  #
+
+  def exec_distclean
+    exec_task_traverse 'distclean'
+    rm_f @config.savefile
+    rm_f 'InstalledFiles'
+  end
+
+  alias distclean_dir_bin noop
+  alias distclean_dir_lib noop
+
+  def distclean_dir_ext(rel)
+    return unless extdir?(curr_srcdir())
+    make 'distclean' if File.file?('Makefile')
+  end
+
+  alias distclean_dir_data noop
+  alias distclean_dir_conf noop
+  alias distclean_dir_man noop
+
+  #
+  # Traversing
+  #
+
+  def exec_task_traverse(task)
+    run_hook "pre-#{task}"
+    FILETYPES.each do |type|
+      if type == 'ext' and config('without-ext') == 'yes'
+        $stderr.puts 'skipping ext/* by user option' if verbose?
+        next
+      end
+      traverse task, type, "#{task}_dir_#{type}"
+    end
+    run_hook "post-#{task}"
+  end
+
+  def traverse(task, rel, mid)
+    dive_into(rel) {
+      run_hook "pre-#{task}"
+      __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
+      directories_of(curr_srcdir()).each do |d|
+        traverse task, "#{rel}/#{d}", mid
+      end
+      run_hook "post-#{task}"
+    }
+  end
+
+  def dive_into(rel)
+    return unless File.dir?("#{@srcdir}/#{rel}")
+
+    dir = File.basename(rel)
+    Dir.mkdir dir unless File.dir?(dir)
+    prevdir = Dir.pwd
+    Dir.chdir dir
+    $stderr.puts '---> ' + rel if verbose?
+    @currdir = rel
+    yield
+    Dir.chdir prevdir
+    $stderr.puts '<--- ' + rel if verbose?
+    @currdir = File.dirname(rel)
+  end
+
+  def run_hook(id)
+    path = [ "#{curr_srcdir()}/#{id}",
+             "#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) }
+    return unless path
+    begin
+      instance_eval File.read(path), path, 1
+    rescue
+      raise if $DEBUG
+      setup_rb_error "hook #{path} failed:\n" + $!.message
+    end
+  end
+
+end   # class Installer
+
+
+class SetupError < StandardError; end
+
+def setup_rb_error(msg)
+  raise SetupError, msg
+end
+
+if $0 == __FILE__
+  begin
+    ToplevelInstaller.invoke
+  rescue SetupError
+    raise if $DEBUG
+    $stderr.puts $!.message
+    $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
+    exit 1
+  end
+end
diff --git a/app/server/vendor/kramdown/test/run_tests.rb b/app/server/vendor/kramdown/test/run_tests.rb
new file mode 100644
index 0000000..3cde1dd
--- /dev/null
+++ b/app/server/vendor/kramdown/test/run_tests.rb
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+$:.unshift File.dirname(__FILE__) + '/../lib'
+require 'kramdown'
+require 'test/unit/assertions'
+require 'yaml'
+
+include Test::Unit::Assertions
+
+arg = ARGV[0] || File.join(File.dirname(__FILE__), 'testcases')
+
+arg = if File.directory?(arg)
+        File.join(arg, '**/*.text')
+      else
+        arg + '.text'
+      end
+
+width = ((size = %x{stty size 2>/dev/null}).length > 0 ? size.split.last.to_i : 72) rescue 72
+width -= 8
+fwidth = 0
+Dir[arg].each {|f| fwidth = [fwidth, f.length + 10].max }.each do |file|
+  print(('Testing ' + file + ' ').ljust([fwidth, width].min))
+  $stdout.flush
+
+  html_file = file.sub('.text', '.html')
+  opts_file = file.sub('.text', '.options')
+  opts_file = File.join(File.dirname(file), 'options') if !File.exist?(opts_file)
+  options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {:auto_ids => false, :footnote_nr => 1}
+  doc = Kramdown::Document.new(File.read(file), options)
+  begin
+    assert_equal(File.read(html_file), doc.to_html)
+    puts 'PASSED'
+  rescue Exception => e
+    puts '  FAILED'
+    puts $!.message if $VERBOSE
+    puts $!.backtrace if $DEBUG
+  end
+  puts "Warnings:\n" + doc.warnings.join("\n") if !doc.warnings.empty? && $VERBOSE
+end
diff --git a/app/server/vendor/kramdown/test/test_files.rb b/app/server/vendor/kramdown/test/test_files.rb
new file mode 100644
index 0000000..d460921
--- /dev/null
+++ b/app/server/vendor/kramdown/test/test_files.rb
@@ -0,0 +1,284 @@
+# -*- coding: utf-8 -*-
+#
+#--
+# Copyright (C) 2009-2014 Thomas Leitner <t_leitner at gmx.at>
+#
+# This file is part of kramdown which is licensed under the MIT.
+#++
+#
+
+require 'minitest/autorun'
+require 'kramdown'
+require 'yaml'
+require 'tmpdir'
+
+Encoding.default_external = 'utf-8' if RUBY_VERSION >= '1.9'
+
+class TestFiles < Minitest::Test
+
+  EXCLUDE_KD_FILES = [('test/testcases/block/04_header/with_auto_ids.text' if RUBY_VERSION <= '1.8.6'), # bc of dep stringex not working
+                     ].compact
+
+  # Generate test methods for kramdown-to-xxx conversion
+  Dir[File.dirname(__FILE__) + '/testcases/**/*.text'].each do |text_file|
+    next if EXCLUDE_KD_FILES.any? {|f| text_file =~ /#{f}$/}
+    basename = text_file.sub(/\.text$/, '')
+    opts_file = text_file.sub(/\.text$/, '.options')
+    (Dir[basename + ".*"] - [text_file, opts_file]).each do |output_file|
+      next if (RUBY_VERSION >= '1.9' && File.exist?(output_file + '.19')) ||
+        (RUBY_VERSION < '1.9' && output_file =~ /\.19$/)
+      output_format = File.extname(output_file.sub(/\.19$/, ''))[1..-1]
+      next if !Kramdown::Converter.const_defined?(output_format[0..0].upcase + output_format[1..-1])
+      define_method('test_' + text_file.tr('.', '_') + "_to_#{output_format}") do
+        opts_file = File.join(File.dirname(text_file), 'options') if !File.exist?(opts_file)
+        options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {:auto_ids => false, :footnote_nr => 1}
+        doc = Kramdown::Document.new(File.read(text_file), options)
+        assert_equal(File.read(output_file), doc.send("to_#{output_format}"))
+      end
+    end
+  end
+
+  # Generate test methods for html-to-html conversion
+  `tidy -v 2>&1`
+  if $?.exitstatus != 0
+    warn("Skipping html-to-html tests because tidy executable is missing")
+  else
+    EXCLUDE_HTML_FILES = ['test/testcases/block/06_codeblock/whitespace.html', # bc of span inside pre
+                          'test/testcases/block/09_html/simple.html', # bc of xml elements
+                          'test/testcases/span/03_codespan/highlighting.html', # bc of span elements inside code element
+                          'test/testcases/block/04_header/with_auto_ids.html', # bc of auto_ids=true option
+                          'test/testcases/block/04_header/header_type_offset.html', # bc of header_offset option
+                         ]
+    Dir[File.dirname(__FILE__) + '/testcases/**/*.{html,html.19,htmlinput,htmlinput.19}'].each do |html_file|
+      next if EXCLUDE_HTML_FILES.any? {|f| html_file =~ /#{f}(\.19)?$/}
+      next if (RUBY_VERSION >= '1.9' && File.exist?(html_file + '.19')) ||
+        (RUBY_VERSION < '1.9' && html_file =~ /\.19$/)
+      out_file = (html_file =~ /\.htmlinput(\.19)?$/ ? html_file.sub(/input(\.19)?$/, '') : html_file)
+      define_method('test_' + html_file.tr('.', '_') + "_to_html") do
+        opts_file = html_file.sub(/\.html(input)?(\.19)?$/, '.options')
+        opts_file = File.join(File.dirname(html_file), 'options') if !File.exist?(opts_file)
+        options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {:auto_ids => false, :footnote_nr => 1}
+        doc = Kramdown::Document.new(File.read(html_file), options.merge(:input => 'html'))
+        assert_equal(tidy_output(File.read(out_file)), tidy_output(doc.to_html))
+      end
+    end
+  end
+
+  def tidy_output(out)
+    cmd = "tidy -q --doctype omit #{RUBY_VERSION >= '1.9' ? '-utf8' : '-raw'} 2>/dev/null"
+    result = IO.popen(cmd, 'r+') do |io|
+      io.write(out)
+      io.close_write
+      io.read
+    end
+    if $?.exitstatus == 2
+      raise "Problem using tidy"
+    end
+    result
+  end
+
+  # Generate test methods for text-to-latex conversion and compilation
+  `latex -v 2>&1`
+  if $?.exitstatus != 0
+    warn("Skipping latex compilation tests because latex executable is missing")
+  else
+    EXCLUDE_LATEX_FILES = ['test/testcases/span/01_link/image_in_a.text', # bc of image link
+                           'test/testcases/span/01_link/imagelinks.text', # bc of image links
+                           'test/testcases/span/04_footnote/markers.text', # bc of footnote in header
+                          ]
+    Dir[File.dirname(__FILE__) + '/testcases/**/*.text'].each do |text_file|
+      next if EXCLUDE_LATEX_FILES.any? {|f| text_file =~ /#{f}$/}
+      define_method('test_' + text_file.tr('.', '_') + "_to_latex_compilation") do
+        latex =  Kramdown::Document.new(File.read(text_file),
+                                        :auto_ids => false, :footnote_nr => 1,
+                                        :template => 'document').to_latex
+        Dir.mktmpdir do |tmpdir|
+          result = IO.popen("latex -output-directory='#{tmpdir}' 2>/dev/null", 'r+') do |io|
+            io.write(latex)
+            io.close_write
+            io.read
+          end
+          assert($?.exitstatus == 0, result.scan(/^!(.*\n.*)/).join("\n"))
+        end
+      end
+    end
+  end
+
+  # Generate test methods for text->kramdown->html conversion
+  `tidy -v 2>&1`
+  if $?.exitstatus != 0
+    warn("Skipping text->kramdown->html tests because tidy executable is missing")
+  else
+    EXCLUDE_TEXT_FILES = ['test/testcases/span/05_html/markdown_attr.text',  # bc of markdown attr
+                          'test/testcases/block/09_html/markdown_attr.text', # bc of markdown attr
+                          'test/testcases/span/extension/options.text',      # bc of parse_span_html option
+                          'test/testcases/block/12_extension/options.text',  # bc of options option
+                          'test/testcases/block/12_extension/options3.text', # bc of options option
+                          'test/testcases/block/09_html/content_model/tables.text',  # bc of parse_block_html option
+                          'test/testcases/block/09_html/html_to_native/header.text', # bc of auto_ids option that interferes
+                          'test/testcases/block/09_html/html_to_native/table_simple.text', # bc of tr style attr getting removed
+                          'test/testcases/block/09_html/simple.text',        # bc of webgen:block elements
+                          'test/testcases/block/11_ial/simple.text',         # bc of change of ordering of attributes in header
+                          'test/testcases/span/extension/comment.text',      # bc of comment text modifications (can this be avoided?)
+                          'test/testcases/block/04_header/header_type_offset.text', # bc of header_offset being applied twice
+                          ('test/testcases/block/04_header/with_auto_ids.text' if RUBY_VERSION <= '1.8.6'), # bc of dep stringex not working
+                         ].compact
+    Dir[File.dirname(__FILE__) + '/testcases/**/*.text'].each do |text_file|
+      next if EXCLUDE_TEXT_FILES.any? {|f| text_file =~ /#{f}$/}
+      define_method('test_' + text_file.tr('.', '_') + "_to_kramdown_to_html") do
+        html_file = text_file.sub(/\.text$/, '.html')
+        html_file += '.19' if RUBY_VERSION >= '1.9' && File.exist?(html_file + '.19')
+        opts_file = text_file.sub(/\.text$/, '.options')
+        opts_file = File.join(File.dirname(text_file), 'options') if !File.exist?(opts_file)
+        options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {:auto_ids => false, :footnote_nr => 1}
+        kdtext = Kramdown::Document.new(File.read(text_file), options).to_kramdown
+        html = Kramdown::Document.new(kdtext, options).to_html
+        assert_equal(tidy_output(File.read(html_file)), tidy_output(html))
+      end
+    end
+  end
+
+  # Generate test methods for html-to-kramdown-to-html conversion
+  `tidy -v 2>&1`
+  if $?.exitstatus != 0
+    warn("Skipping html-to-kramdown-to-html tests because tidy executable is missing")
+  else
+    EXCLUDE_HTML_KD_FILES = ['test/testcases/span/extension/options.html',        # bc of parse_span_html option
+                             'test/testcases/span/05_html/normal.html',           # bc of br tag before closing p tag
+                             'test/testcases/block/12_extension/nomarkdown.html', # bc of nomarkdown extension
+                             'test/testcases/block/09_html/simple.html',          # bc of webgen:block elements
+                             'test/testcases/block/09_html/markdown_attr.html',   # bc of markdown attr
+                             'test/testcases/block/09_html/html_to_native/table_simple.html', # bc of invalidly converted simple table
+                             'test/testcases/block/06_codeblock/whitespace.html', # bc of entity to char conversion
+                             'test/testcases/block/11_ial/simple.html',           # bc of change of ordering of attributes in header
+                             'test/testcases/span/03_codespan/highlighting.html', # bc of span elements inside code element
+                             'test/testcases/block/04_header/with_auto_ids.html', # bc of auto_ids=true option
+                             'test/testcases/block/04_header/header_type_offset.html', # bc of header_offset option
+                             'test/testcases/block/16_toc/toc_exclude.html',      # bc of different attribute ordering
+                             'test/testcases/span/autolinks/url_links.html',      # bc of quot entity being converted to char
+                            ]
+    Dir[File.dirname(__FILE__) + '/testcases/**/*.{html,html.19}'].each do |html_file|
+      next if EXCLUDE_HTML_KD_FILES.any? {|f| html_file =~ /#{f}(\.19)?$/}
+      next if (RUBY_VERSION >= '1.9' && File.exist?(html_file + '.19')) ||
+        (RUBY_VERSION < '1.9' && html_file =~ /\.19$/)
+      define_method('test_' + html_file.tr('.', '_') + "_to_kramdown_to_html") do
+        kd = Kramdown::Document.new(File.read(html_file), :input => 'html', :auto_ids => false, :footnote_nr => 1).to_kramdown
+        opts_file = html_file.sub(/\.html(\.19)?$/, '.options')
+        opts_file = File.join(File.dirname(html_file), 'options') if !File.exist?(opts_file)
+        options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {:auto_ids => false, :footnote_nr => 1}
+        doc = Kramdown::Document.new(kd, options)
+        assert_equal(tidy_output(File.read(html_file)), tidy_output(doc.to_html))
+      end
+    end
+  end
+
+  EXCLUDE_GFM_FILES = [
+    'test/testcases/block/03_paragraph/no_newline_at_end.text',
+    'test/testcases/block/03_paragraph/indented.text',
+    'test/testcases/block/03_paragraph/two_para.text',
+    'test/testcases/block/04_header/atx_header.text',
+    'test/testcases/block/04_header/setext_header.text',
+    'test/testcases/block/05_blockquote/indented.text',
+    'test/testcases/block/05_blockquote/lazy.text',
+    'test/testcases/block/05_blockquote/nested.text',
+    'test/testcases/block/05_blockquote/no_newline_at_end.text',
+    'test/testcases/block/06_codeblock/error.text',
+    'test/testcases/block/07_horizontal_rule/error.text',
+    'test/testcases/block/08_list/escaping.text',
+    'test/testcases/block/08_list/item_ial.text',
+    'test/testcases/block/08_list/lazy.text',
+    'test/testcases/block/08_list/list_and_others.text',
+    'test/testcases/block/08_list/other_first_element.text',
+    'test/testcases/block/08_list/simple_ul.text',
+    'test/testcases/block/08_list/special_cases.text',
+    'test/testcases/block/09_html/comment.text',
+    'test/testcases/block/09_html/html_to_native/code.text',
+    'test/testcases/block/09_html/html_to_native/emphasis.text',
+    'test/testcases/block/09_html/html_to_native/typography.text',
+    'test/testcases/block/09_html/parse_as_raw.text',
+    'test/testcases/block/09_html/simple.text',
+    'test/testcases/block/12_extension/comment.text',
+    'test/testcases/block/12_extension/ignored.text',
+    'test/testcases/block/12_extension/nomarkdown.text',
+    'test/testcases/block/13_definition_list/item_ial.text',
+    'test/testcases/block/13_definition_list/multiple_terms.text',
+    'test/testcases/block/13_definition_list/no_def_list.text',
+    'test/testcases/block/13_definition_list/simple.text',
+    'test/testcases/block/13_definition_list/with_blocks.text',
+    'test/testcases/block/14_table/errors.text',
+    'test/testcases/block/14_table/escaping.text',
+    'test/testcases/block/14_table/simple.text',
+    'test/testcases/block/15_math/normal.text',
+    'test/testcases/encoding.text',
+    'test/testcases/span/01_link/inline.text',
+    'test/testcases/span/01_link/link_defs.text',
+    'test/testcases/span/01_link/reference.text',
+    'test/testcases/span/02_emphasis/normal.text',
+    'test/testcases/span/03_codespan/normal.text',
+    'test/testcases/span/04_footnote/definitions.text',
+    'test/testcases/span/04_footnote/markers.text',
+    'test/testcases/span/05_html/across_lines.text',
+    'test/testcases/span/05_html/markdown_attr.text',
+    'test/testcases/span/05_html/normal.text',
+    'test/testcases/span/autolinks/url_links.text',
+    'test/testcases/span/extension/comment.text',
+    'test/testcases/span/ial/simple.text',
+    'test/testcases/span/line_breaks/normal.text',
+    'test/testcases/span/text_substitutions/entities_as_char.text',
+    'test/testcases/span/text_substitutions/entities.text',
+    'test/testcases/span/text_substitutions/typography.text'
+  ]
+
+  # Generate test methods for gfm-to-html conversion
+  Dir[File.dirname(__FILE__) + '/{testcases,testcases_gfm}/**/*.text'].each do |text_file|
+    next if EXCLUDE_GFM_FILES.any? {|f| text_file =~ /#{f}$/}
+    basename = text_file.sub(/\.text$/, '')
+
+    html_file = [(".html.19" if RUBY_VERSION >= '1.9'), ".html"].compact.
+      map {|ext| basename + ext }.
+      detect {|file| File.exist?(file) }
+
+    define_method('test_gfm_' + text_file.tr('.', '_') + "_to_html") do
+      opts_file = basename + '.options'
+      opts_file = File.join(File.dirname(html_file), 'options') if !File.exist?(opts_file)
+      options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {:auto_ids => false, :footnote_nr => 1}
+      doc = Kramdown::Document.new(File.read(text_file), options.merge(:input => 'GFM'))
+      assert_equal(File.read(html_file), doc.to_html)
+    end
+  end
+
+
+  # Generate test methods for asserting that converters don't modify the document tree.
+  Dir[File.dirname(__FILE__) + '/testcases/**/*.text'].each do |text_file|
+    opts_file = text_file.sub(/\.text$/, '.options')
+    options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {:auto_ids => false, :footnote_nr => 1}
+    (Kramdown::Converter.constants.map {|c| c.to_sym} - [:Base, :RemoveHtmlTags]).each do |conv_class|
+      next if conv_class == :Pdf && RUBY_VERSION < '1.9'
+      define_method("test_whether_#{conv_class}_modifies_tree_with_file_#{text_file.tr('.', '_')}") do
+        doc = Kramdown::Document.new(File.read(text_file), options)
+        options_before = Marshal.load(Marshal.dump(doc.options))
+        tree_before = Marshal.load(Marshal.dump(doc.root))
+        Kramdown::Converter.const_get(conv_class).convert(doc.root, doc.options)
+        assert_equal(options_before, doc.options)
+        assert_tree_not_changed(tree_before, doc.root)
+      end
+    end
+  end
+
+  def assert_tree_not_changed(old, new)
+    assert_equal(old.type, new.type, "type mismatch")
+    if old.value.kind_of?(Kramdown::Element)
+      assert_tree_not_changed(old.value, new.value)
+    else
+      assert_equal(old.value, new.value, "value mismatch")
+    end
+    assert_equal(old.attr, new.attr, "attr mismatch")
+    assert_equal(old.options, new.options, "options mismatch")
+    assert_equal(old.children.length, new.children.length, "children count mismatch")
+
+    old.children.each_with_index do |child, index|
+      assert_tree_not_changed(child, new.children[index])
+    end
+  end
+
+end
diff --git a/app/server/vendor/kramdown/test/test_location.rb b/app/server/vendor/kramdown/test/test_location.rb
new file mode 100644
index 0000000..2f435fb
--- /dev/null
+++ b/app/server/vendor/kramdown/test/test_location.rb
@@ -0,0 +1,172 @@
+# -*- coding: utf-8 -*-
+
+require 'minitest/autorun'
+require 'kramdown'
+
+Encoding.default_external = 'utf-8' if RUBY_VERSION >= '1.9'
+
+describe 'location' do
+
+  # checks that +element+'s :location option corresponds to the location stored
+  # in the element.attr['class']
+  def check_element_for_location(element)
+    if (match = /^line-(\d+)/.match(element.attr['class'] || ''))
+      expected_line = match[1].to_i
+      element.options[:location].must_equal(expected_line)
+    end
+    element.children.each do |child|
+      check_element_for_location(child)
+    end
+  end
+
+  # Test cases consist of a kramdown string that uses IALs to specify the expected
+  # line numbers for a given element.
+  test_cases = {
+    'autolink' => %(testing autolinks\n\n<http://kramdown.org>{:.line-3}),
+    'blockquote' => %(
+      > block quote1
+      >
+      > * {:.line-3} list item in block quote
+      > * {:.line-4} list item in block quote
+      > {:.line-3}
+      {:.line-1}
+
+      > block quote2
+      {:.line-8}
+    ),
+    'codeblock' => %(\na para\n\n~~~~\ntest code 1\n~~~~\n{:.line-3}\n\n    test code 2\n{:.line-8}\n),
+    'codespan' => %(a para\n\nanother para `<code>`{:.line-3} with code\n),
+    'emphasis' => %(
+      para *span*{:.line-1}
+      {:.line-1}
+
+      ## header *span*{:.line-4}
+      {:.line-4}
+
+      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+      tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+      quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+      consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+      cillum *short span on single line*{:.line-11}
+      dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
+      *long span over multiple lines - proident, sunt in culpa qui officia deserunt
+      mollit anim id est laborum.*{:.line-13}
+      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+      tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+      quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+      `code span`{:.line-18}
+      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+      tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+      quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+      {:.line-7}
+    ),
+    'header' => %(
+      # header1
+      {:.line-1}
+
+      ## header2
+      {:.line-4}
+
+      ## header3
+      {:.line-7}
+
+      header4
+      =======
+      {:.line-10}
+
+      ^
+
+      header5
+      -------
+      {:.line-16}
+    ),
+    'horizontal_rule' => %(\na para\n\n----\n{:.line-3}\n),
+    'html_entity' => "a para\n\nanother para with &{:.line-3} html entity.\n",
+    'link' => %(
+      a para
+
+      This is [a link](http://rubyforge.org){:.line-3} to a page.
+
+      Here comes a ![smiley](../images/smiley.png){:.line-5}
+    ),
+    'list' => %(
+      * {:.line-1} list item
+      * {:.line-2} list item
+      * {:.line-3} list item
+      {:.line-1}
+
+      {:.line-7}
+      1. {:.line-7} list item
+      2. {:.line-8} list item
+      3. {:.line-9} list item
+
+      {:.line-12}
+      definition term 1
+      : {:.line-13} definition definition 1
+      definition term 2
+      : {:.line-15} definition definition 2
+    ),
+    'math_block' => %(\na para\n\n$$5+5$$\n{:.line-3}\n),
+    'math_inline' => %(\na para\n\nanother para with inline math $$5+5$${:.line-3}\n),
+    'paragraph' => %(
+      para1
+      {:.line-1}
+
+      para2
+      {:.line-4}
+
+      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+      tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+      quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+      consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+      {:.line-7}
+
+      {:.line-14}
+      para with leading IAL
+    ),
+    'table' => %(
+      a para
+
+      |first|second|third|
+      |-----|------|-----|
+      |a    |b     |c    |
+      {:.line-3}
+    ),
+    'typographic_symbol' => %(
+      a para
+
+      another para ---{:.line-3}
+
+      another para ...{:.line-5}
+    ),
+    'gh issue 129' => %(
+      `|`
+      {:.line-1}
+    ),
+    'gh issue 131' => %(
+      * {:.line-1} test
+        line 2
+        * {:.line-3} second
+        * {:.line-4} third
+      * {:.line-5} * {:.line-5} one
+        * {:.line-6} two
+    ),
+  }
+  test_cases.each do |name, test_string|
+    it "Handles #{ name }" do
+      doc = Kramdown::Document.new(test_string.gsub(/^      /, '').strip)
+      check_element_for_location(doc.root)
+    end
+  end
+
+  it 'adds location info to duplicate abbreviation definition warnings' do
+    test_string = %(This snippet contains a duplicate abbreviation definition
+
+*[duplicate]: The first definition
+*[duplicate]: The second definition
+    )
+    doc = Kramdown::Document.new(test_string.strip)
+    doc.warnings.must_equal ["Duplicate abbreviation ID 'duplicate' on line 4 - overwriting"]
+  end
+
+end
diff --git a/app/server/vendor/kramdown/test/test_string_scanner_kramdown.rb b/app/server/vendor/kramdown/test/test_string_scanner_kramdown.rb
new file mode 100644
index 0000000..374c076
--- /dev/null
+++ b/app/server/vendor/kramdown/test/test_string_scanner_kramdown.rb
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+
+require 'minitest/autorun'
+require 'kramdown/utils/string_scanner'
+
+describe Kramdown::Utils::StringScanner do
+
+  [
+    ["...........X............", [/X/], 1],
+    ["1\n2\n3\n4\n5\n6X", [/X/], 6],
+    ["1\n2\n3\n4\n5\n6X\n7\n8X", [/X/,/X/], 8],
+    [(".\n" * 1000) + 'X', [/X/], 1001]
+  ].each_with_index do |test_data, i|
+    test_string, scan_regexes, expect = test_data
+    it "computes the correct current_line_number for example ##{i+1}" do
+      str_sc = Kramdown::Utils::StringScanner.new(test_string)
+      scan_regexes.each { |scan_re| str_sc.scan_until(scan_re) }
+      str_sc.current_line_number.must_equal expect
+    end
+  end
+
+end
diff --git a/app/server/vendor/kramdown/test/testcases/block/01_blank_line/spaces.html b/app/server/vendor/kramdown/test/testcases/block/01_blank_line/spaces.html
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/01_blank_line/spaces.html
@@ -0,0 +1 @@
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/01_blank_line/spaces.text b/app/server/vendor/kramdown/test/testcases/block/01_blank_line/spaces.text
new file mode 100644
index 0000000..2cbdaa6
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/01_blank_line/spaces.text
@@ -0,0 +1,3 @@
+
+             
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/01_blank_line/tabs.html b/app/server/vendor/kramdown/test/testcases/block/01_blank_line/tabs.html
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/01_blank_line/tabs.html
@@ -0,0 +1 @@
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/01_blank_line/tabs.text b/app/server/vendor/kramdown/test/testcases/block/01_blank_line/tabs.text
new file mode 100644
index 0000000..69d6a47
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/01_blank_line/tabs.text
@@ -0,0 +1,6 @@
+	
+			
+	
+		
+
+	
diff --git a/app/server/vendor/kramdown/test/testcases/block/02_eob/beginning.html b/app/server/vendor/kramdown/test/testcases/block/02_eob/beginning.html
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/02_eob/beginning.html
@@ -0,0 +1 @@
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/02_eob/beginning.text b/app/server/vendor/kramdown/test/testcases/block/02_eob/beginning.text
new file mode 100644
index 0000000..8d15802
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/02_eob/beginning.text
@@ -0,0 +1,3 @@
+^
+
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/02_eob/end.html b/app/server/vendor/kramdown/test/testcases/block/02_eob/end.html
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/02_eob/end.html
@@ -0,0 +1 @@
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/02_eob/end.text b/app/server/vendor/kramdown/test/testcases/block/02_eob/end.text
new file mode 100644
index 0000000..db56ec3
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/02_eob/end.text
@@ -0,0 +1,3 @@
+
+
+^
diff --git a/app/server/vendor/kramdown/test/testcases/block/02_eob/middle.html b/app/server/vendor/kramdown/test/testcases/block/02_eob/middle.html
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/02_eob/middle.html
@@ -0,0 +1 @@
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/02_eob/middle.text b/app/server/vendor/kramdown/test/testcases/block/02_eob/middle.text
new file mode 100644
index 0000000..87210a1
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/02_eob/middle.text
@@ -0,0 +1,5 @@
+
+
+^
+
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/03_paragraph/indented.html b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/indented.html
new file mode 100644
index 0000000..810cfc0
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/indented.html
@@ -0,0 +1,18 @@
+<p>This is a para.</p>
+
+<p>This is a para.</p>
+
+<p>This is a para.</p>
+
+<p>This is a para.</p>
+
+<pre><code>This is a code block.
+</code></pre>
+
+<p>And this is another.</p>
+
+<p>A para
+ with
+  mixed
+indents.
+   and with much indent</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/03_paragraph/indented.html.gfm b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/indented.html.gfm
new file mode 100644
index 0000000..4440c62
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/indented.html.gfm
@@ -0,0 +1,18 @@
+<p>This is a para.</p>
+
+<p>This is a para.</p>
+
+<p>This is a para.</p>
+
+<p>This is a para.</p>
+
+<pre><code>This is a code block.
+</code></pre>
+
+<p>And this is another.</p>
+
+<p>A para
+<br /> with
+<br />  mixed
+<br />indents.
+<br />   and with much indent</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/03_paragraph/indented.text b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/indented.text
new file mode 100644
index 0000000..5849f5b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/indented.text
@@ -0,0 +1,19 @@
+This is a para.
+
+ This is a para.
+
+  This is a para.
+
+   This is a para.
+
+    This is a code block.
+
+
+       
+And this is another.
+
+A para
+ with
+  mixed
+indents.
+   and with much indent
diff --git a/app/server/vendor/kramdown/test/testcases/block/03_paragraph/no_newline_at_end.html b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/no_newline_at_end.html
new file mode 100644
index 0000000..6a209e2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/no_newline_at_end.html
@@ -0,0 +1,5 @@
+<p>One paragraph
+over
+   multiple lines.</p>
+
+<p>Second one without newline.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/03_paragraph/no_newline_at_end.text b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/no_newline_at_end.text
new file mode 100644
index 0000000..7f1169d
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/no_newline_at_end.text
@@ -0,0 +1,5 @@
+  One paragraph
+over
+   multiple lines.
+
+Second one without newline.
\ No newline at end of file
diff --git a/app/server/vendor/kramdown/test/testcases/block/03_paragraph/one_para.html b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/one_para.html
new file mode 100644
index 0000000..0d20e17
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/one_para.html
@@ -0,0 +1 @@
+<p>This is just a normal paragraph.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/03_paragraph/one_para.text b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/one_para.text
new file mode 100644
index 0000000..0b01324
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/one_para.text
@@ -0,0 +1 @@
+This is just a normal paragraph.
diff --git a/app/server/vendor/kramdown/test/testcases/block/03_paragraph/two_para.html b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/two_para.html
new file mode 100644
index 0000000..d6194ea
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/two_para.html
@@ -0,0 +1,4 @@
+<p>This is just a normal paragraph.
+That goes on to the second line.</p>
+
+<p>Another paragraph.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/03_paragraph/two_para.text b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/two_para.text
new file mode 100644
index 0000000..b0c730d
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/03_paragraph/two_para.text
@@ -0,0 +1,4 @@
+This is just a normal paragraph.
+That goes on to the second line.
+
+Another paragraph.
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/atx_header.html b/app/server/vendor/kramdown/test/testcases/block/04_header/atx_header.html
new file mode 100644
index 0000000..95a20d4
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/atx_header.html
@@ -0,0 +1,49 @@
+<h1>This is a header</h1>
+
+<h2>This is a header</h2>
+
+<h3>This is a header</h3>
+
+<h4>This is a header</h4>
+
+<h5>This is a header</h5>
+
+<h6>This is a header</h6>
+
+<h1>Header</h1>
+<h1>Header</h1>
+
+<h2>Header</h2>
+<blockquote>
+  <p>blockquote</p>
+</blockquote>
+
+<h6>header</h6>
+<p>paragraph</p>
+
+<blockquote>
+  <p>blockquote
+### not a header</p>
+</blockquote>
+
+<h1>header</h1>
+
+<p># </p>
+
+<p>#</p>
+
+<h3 id="id">Header</h3>
+
+<h3 id="Id">Header</h3>
+
+<h3 id="id">Header</h3>
+
+<h3 id="A-Za-z0-9_:t">Header</h3>
+
+<h3>Header {#9ab}</h3>
+
+<h3>Header{#noid}</h3>
+
+<h3>Header ##{#noid}</h3>
+
+<h3>Last</h3>
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/atx_header.text b/app/server/vendor/kramdown/test/testcases/block/04_header/atx_header.text
new file mode 100644
index 0000000..d7240c1
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/atx_header.text
@@ -0,0 +1,47 @@
+# This is a header
+
+## This is a header
+
+### This is a header
+
+#### This is a header
+
+##### This is a header
+
+###### This is a header
+
+# Header
+^
+# Header
+
+##Header   #####
+> blockquote
+
+###### header 
+paragraph
+
+> blockquote
+### not a header
+
+
+# header
+
+# 
+
+#
+
+### Header {#id}
+
+### Header ## {#Id}  
+
+### Header    ##    {#id}
+
+### Header {#A-Za-z0-9_:t}
+
+### Header {#9ab}
+
+### Header{#noid}
+
+### Header ##{#noid}
+
+### Last
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/atx_header_no_newline_at_end.html b/app/server/vendor/kramdown/test/testcases/block/04_header/atx_header_no_newline_at_end.html
new file mode 100644
index 0000000..9f49c3b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/atx_header_no_newline_at_end.html
@@ -0,0 +1 @@
+<h1>header</h1>
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/atx_header_no_newline_at_end.text b/app/server/vendor/kramdown/test/testcases/block/04_header/atx_header_no_newline_at_end.text
new file mode 100644
index 0000000..7b74be4
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/atx_header_no_newline_at_end.text
@@ -0,0 +1 @@
+# header
\ No newline at end of file
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/header_type_offset.html b/app/server/vendor/kramdown/test/testcases/block/04_header/header_type_offset.html
new file mode 100644
index 0000000..e031b9a
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/header_type_offset.html
@@ -0,0 +1,11 @@
+<h2>Lorem ipsum</h2>
+
+<h3>Lorem ipsum</h3>
+
+<h4>Lorem ipsum</h4>
+
+<h6>Lorem ipsum</h6>
+
+<h2>Lorem ipsum</h2>
+
+<h3>Lorem ipsum</h3>
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/header_type_offset.kramdown b/app/server/vendor/kramdown/test/testcases/block/04_header/header_type_offset.kramdown
new file mode 100644
index 0000000..a77deb9
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/header_type_offset.kramdown
@@ -0,0 +1,12 @@
+## Lorem ipsum
+
+### Lorem ipsum
+
+#### Lorem ipsum
+
+###### Lorem ipsum
+
+## Lorem ipsum
+
+### Lorem ipsum
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/header_type_offset.latex b/app/server/vendor/kramdown/test/testcases/block/04_header/header_type_offset.latex
new file mode 100644
index 0000000..c9017e6
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/header_type_offset.latex
@@ -0,0 +1,12 @@
+\subsection*{Lorem ipsum}
+
+\subsubsection*{Lorem ipsum}
+
+\paragraph*{Lorem ipsum}
+
+\subparagraph*{Lorem ipsum}
+
+\subsection*{Lorem ipsum}
+
+\subsubsection*{Lorem ipsum}
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/header_type_offset.options b/app/server/vendor/kramdown/test/testcases/block/04_header/header_type_offset.options
new file mode 100644
index 0000000..a805035
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/header_type_offset.options
@@ -0,0 +1,2 @@
+:header_offset: 1
+:auto_ids: false
\ No newline at end of file
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/header_type_offset.text b/app/server/vendor/kramdown/test/testcases/block/04_header/header_type_offset.text
new file mode 100644
index 0000000..bfaefa2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/header_type_offset.text
@@ -0,0 +1,13 @@
+# Lorem ipsum
+
+## Lorem ipsum
+
+### Lorem ipsum
+
+###### Lorem ipsum
+
+Lorem ipsum
+===========
+
+Lorem ipsum
+-----------
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/setext_header.html b/app/server/vendor/kramdown/test/testcases/block/04_header/setext_header.html
new file mode 100644
index 0000000..147c345
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/setext_header.html
@@ -0,0 +1,32 @@
+<h2>test</h2>
+
+<h1>test2</h1>
+
+<h2>test</h2>
+<p>para</p>
+
+<pre><code>   header =
+</code></pre>
+
+<p>=</p>
+
+<p>This is a para.
+With two lines.
+And not a header.
+=================</p>
+
+<blockquote>
+  <p>Blockquote.
+Not a Header
+-</p>
+</blockquote>
+
+<h2 id="id">header</h2>
+
+<h1 id="Id">header</h1>
+
+<h2 id="A-Za-z0-9_:">header</h2>
+
+<h2>header{#noid}</h2>
+
+<h2>header</h2>
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/setext_header.text b/app/server/vendor/kramdown/test/testcases/block/04_header/setext_header.text
new file mode 100644
index 0000000..ae94ecd
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/setext_header.text
@@ -0,0 +1,39 @@
+test
+-
+
+test2
+=========
+
+test
+-
+para
+
+       header
+=
+
+
+=
+
+This is a para.
+With two lines.
+And not a header.
+=================
+
+> Blockquote.
+Not a Header
+-
+
+header {#id}  
+------------
+
+header        {#Id}
+======
+
+header {#A-Za-z0-9_:}
+------
+
+header{#noid}
+-----
+
+header
+------
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/setext_header_no_newline_at_end.html b/app/server/vendor/kramdown/test/testcases/block/04_header/setext_header_no_newline_at_end.html
new file mode 100644
index 0000000..9f49c3b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/setext_header_no_newline_at_end.html
@@ -0,0 +1 @@
+<h1>header</h1>
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/setext_header_no_newline_at_end.text b/app/server/vendor/kramdown/test/testcases/block/04_header/setext_header_no_newline_at_end.text
new file mode 100644
index 0000000..0f00750
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/setext_header_no_newline_at_end.text
@@ -0,0 +1,2 @@
+header
+======
\ No newline at end of file
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_prefix.html b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_prefix.html
new file mode 100644
index 0000000..724d391
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_prefix.html
@@ -0,0 +1,3 @@
+<h1 id="hallo_header-1">Header 1</h1>
+
+<h1 id="hallo_section">123</h1>
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_prefix.options b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_prefix.options
new file mode 100644
index 0000000..83305cb
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_prefix.options
@@ -0,0 +1,2 @@
+:auto_ids: true
+:auto_id_prefix: hallo_
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_prefix.text b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_prefix.text
new file mode 100644
index 0000000..acf09fe
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_prefix.text
@@ -0,0 +1,3 @@
+# Header 1
+
+# 123
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_stripping.html b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_stripping.html
new file mode 100644
index 0000000..1d342cd
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_stripping.html
@@ -0,0 +1 @@
+<h1 id="this-is-a-header"><em class="none">This is a header</em></h1>
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_stripping.options b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_stripping.options
new file mode 100644
index 0000000..68800f6
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_stripping.options
@@ -0,0 +1 @@
+:auto_id_stripping: true
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_stripping.text b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_stripping.text
new file mode 100644
index 0000000..2b57bc8
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_id_stripping.text
@@ -0,0 +1 @@
+# <em class="none">This is a header</em>
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_ids.html b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_ids.html
new file mode 100644
index 0000000..af8126d
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_ids.html
@@ -0,0 +1,21 @@
+<h1 id="this-is-a-header">This is a header</h1>
+
+<h2 id="another-one-1-here">12. Another one-1-here</h2>
+
+<h3 id="do--it-now">Do ^& it now</h3>
+
+<h1 id="hallo">Hallo</h1>
+
+<h2 id="not-now">Not now</h2>
+
+<h1 id="hallo-1">Hallo</h1>
+
+<h1 id="section">23232</h1>
+
+<h1 id="section-1">33333</h1>
+
+<h2 id="hallo-2">hallO</h2>
+
+<h1>Header without ID</h1>
+
+<h1 id="transliterated-day-la-vi-du">Transliterated: Đây-là-ví-dụ</h1>
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_ids.options b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_ids.options
new file mode 100644
index 0000000..0a1fec8
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_ids.options
@@ -0,0 +1,2 @@
+:auto_ids: true
+:transliterated_header_ids: true
diff --git a/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_ids.text b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_ids.text
new file mode 100644
index 0000000..f4cd91b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/04_header/with_auto_ids.text
@@ -0,0 +1,24 @@
+# This is a header
+
+## 12. Another one-1-here
+
+### Do ^& it now
+
+Hallo
+=====
+
+Not now
+-------
+
+# Hallo
+
+# 23232
+
+# 33333
+
+## hallO
+
+# Header without ID
+{: id=""}
+
+# Transliterated: Đây-là-ví-dụ
diff --git a/app/server/vendor/kramdown/test/testcases/block/05_blockquote/indented.html b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/indented.html
new file mode 100644
index 0000000..734bb7a
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/indented.html
@@ -0,0 +1,25 @@
+<blockquote>
+  <p>A normal blockquote.</p>
+</blockquote>
+
+<blockquote>
+  <p>A normal blockquote.</p>
+</blockquote>
+
+<blockquote>
+  <p>A normal blockquote.</p>
+</blockquote>
+
+<blockquote>
+  <p>A normal blockquote.</p>
+</blockquote>
+
+<pre><code>> A codeblock
+</code></pre>
+
+<blockquote>
+  <p>Blockquote
+with
+mixed
+indents.</p>
+</blockquote>
diff --git a/app/server/vendor/kramdown/test/testcases/block/05_blockquote/indented.text b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/indented.text
new file mode 100644
index 0000000..70850b0
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/indented.text
@@ -0,0 +1,14 @@
+> A normal blockquote.
+
+ > A normal blockquote.
+
+  > A normal blockquote.
+
+   > A normal blockquote.
+
+    > A codeblock
+
+> Blockquote
+ > with
+  >mixed
+> indents.
diff --git a/app/server/vendor/kramdown/test/testcases/block/05_blockquote/lazy.html b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/lazy.html
new file mode 100644
index 0000000..00a2102
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/lazy.html
@@ -0,0 +1,34 @@
+<blockquote>
+  <p>This is a long
+long line.</p>
+</blockquote>
+
+<blockquote>
+  <blockquote>
+    <p>Nested quote
+inside
+still inside</p>
+  </blockquote>
+</blockquote>
+
+<blockquote>
+  <blockquote>
+    <p>This is a subquote.
+over multipline lines.
+continuing
+here</p>
+  </blockquote>
+</blockquote>
+
+<blockquote>
+  <p>This is a quote
+    no code</p>
+</blockquote>
+
+<blockquote id="id">
+  <p>This is a quote</p>
+</blockquote>
+
+<blockquote>
+  <p>This is a quote</p>
+</blockquote>
diff --git a/app/server/vendor/kramdown/test/testcases/block/05_blockquote/lazy.text b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/lazy.text
new file mode 100644
index 0000000..adde6a6
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/lazy.text
@@ -0,0 +1,20 @@
+> This is a long
+long line.
+
+> > Nested quote
+inside
+> still inside
+
+> > This is a subquote.
+> > over multipline lines.
+> continuing
+here
+
+> This is a quote
+    no code
+
+> This is a quote
+{: #id}
+
+> This is a quote
+^
diff --git a/app/server/vendor/kramdown/test/testcases/block/05_blockquote/nested.html b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/nested.html
new file mode 100644
index 0000000..4bc94f0
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/nested.html
@@ -0,0 +1,10 @@
+<blockquote>
+  <p>foo</p>
+
+  <blockquote>
+    <p>bar
+ baz</p>
+  </blockquote>
+
+  <p>foo</p>
+</blockquote>
diff --git a/app/server/vendor/kramdown/test/testcases/block/05_blockquote/nested.text b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/nested.text
new file mode 100644
index 0000000..2176882
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/nested.text
@@ -0,0 +1,6 @@
+> foo
+>
+> > bar
+>>  baz
+>
+> foo
diff --git a/app/server/vendor/kramdown/test/testcases/block/05_blockquote/no_newline_at_end.html b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/no_newline_at_end.html
new file mode 100644
index 0000000..1de4a60
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/no_newline_at_end.html
@@ -0,0 +1,4 @@
+<blockquote>
+  <p>This is a block quote
+with no newline.</p>
+</blockquote>
diff --git a/app/server/vendor/kramdown/test/testcases/block/05_blockquote/no_newline_at_end.text b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/no_newline_at_end.text
new file mode 100644
index 0000000..402648a
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/no_newline_at_end.text
@@ -0,0 +1,2 @@
+> This is a block quote
+> with no newline.
\ No newline at end of file
diff --git a/app/server/vendor/kramdown/test/testcases/block/05_blockquote/very_long_line.html b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/very_long_line.html
new file mode 100644
index 0000000..4a9aaf5
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/very_long_line.html
@@ -0,0 +1,3 @@
+<blockquote>
+  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+</blockquote>
diff --git a/app/server/vendor/kramdown/test/testcases/block/05_blockquote/very_long_line.text b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/very_long_line.text
new file mode 100644
index 0000000..a2b33bd
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/very_long_line.text
@@ -0,0 +1 @@
+> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
diff --git a/app/server/vendor/kramdown/test/testcases/block/05_blockquote/with_code_blocks.html b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/with_code_blocks.html
new file mode 100644
index 0000000..30abd99
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/with_code_blocks.html
@@ -0,0 +1,15 @@
+<blockquote>
+  <p>Example:</p>
+
+  <pre><code>sub status {
+    print "working";
+}
+</code></pre>
+
+  <p>Or:</p>
+
+  <pre><code>sub status {
+    return "working";
+}
+</code></pre>
+</blockquote>
diff --git a/app/server/vendor/kramdown/test/testcases/block/05_blockquote/with_code_blocks.text b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/with_code_blocks.text
new file mode 100644
index 0000000..3b188dd
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/05_blockquote/with_code_blocks.text
@@ -0,0 +1,11 @@
+>Example:
+> 
+>     sub status {
+>         print "working";
+>     }
+> 
+> Or:
+> 
+>     sub status {
+>         return "working";
+>     }
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/disable-highlighting.html b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/disable-highlighting.html
new file mode 100644
index 0000000..142a5d3
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/disable-highlighting.html
@@ -0,0 +1,4 @@
+<pre><code>x = Class.new
+</code></pre>
+<pre lang="html"><code><a>href</a>
+</code></pre>
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/disable-highlighting.options b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/disable-highlighting.options
new file mode 100644
index 0000000..72e9bc1
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/disable-highlighting.options
@@ -0,0 +1 @@
+:enable_coderay: false
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/disable-highlighting.text b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/disable-highlighting.text
new file mode 100644
index 0000000..af4d0bd
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/disable-highlighting.text
@@ -0,0 +1,4 @@
+    x = Class.new
+^
+    <a>href</a>
+{: lang="html"}
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/error.html b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/error.html
new file mode 100644
index 0000000..d9f9da3
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/error.html
@@ -0,0 +1,4 @@
+<p>Some para</p>
+
+<p>~~~~~~
+not codeblock</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/error.text b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/error.text
new file mode 100644
index 0000000..60ea366
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/error.text
@@ -0,0 +1,4 @@
+Some para
+
+~~~~~~
+not codeblock
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/highlighting.html b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/highlighting.html
new file mode 100644
index 0000000..5067d74
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/highlighting.html
@@ -0,0 +1,6 @@
+<div><span class="CodeRay">x = <span class="constant">Class</span>.new
+</span>
+</div>
+<div><span class="CodeRay"><span class="tag"><a></span>href<span class="tag"></a></span>
+</span>
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/highlighting.options b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/highlighting.options
new file mode 100644
index 0000000..8133537
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/highlighting.options
@@ -0,0 +1,5 @@
+:coderay_default_lang: ruby
+:coderay_wrap: span
+:coderay_line_numbers: ~
+:coderay_css: class
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/highlighting.text b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/highlighting.text
new file mode 100644
index 0000000..5ac4746
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/highlighting.text
@@ -0,0 +1,4 @@
+    x = Class.new
+^
+    <a>href</a>
+{: .language-html}
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/issue_gh45.html b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/issue_gh45.html
new file mode 100644
index 0000000..b096a9e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/issue_gh45.html
@@ -0,0 +1,164 @@
+
+<p>B</p>
+
+<pre><code>                       BBBBBBBB. 
+
+
+
+           BBBB BB BBBBBBBB BBBBB. BBBBBBB BB BBBBB BB BBB BBBB BBBBB BBB BBB BBBB BBB BBBBBBB BBB BBBBBBB. B BBB'B BBBBB BBBB BBB BBBB BBBBBBB BBBB BBBB BBBB BBBBBBBB.
+
+
+                BBB BBBBB BBBBB BBB BBBB BBBB BBBB, BBB BBBBB BB BBBBB BBB BB BBBBBB BBBB BBB BBBBB BBBB BB. BBBBB BBB BBBBB BBBBB BBB BBBB BB BBBB BBBB BBBBB.
+
+
+                         BBBB BBBBB, BBBBB, BBBBBBBB?
+
+                   BB BBB BB BBBB BBB BBBB BBB BBBBBB /BBB BB BBBBBBBBB BBBB BBBBBBB BBBBBB BB BBB. 
+
+
+                   BBBB BBBBBBBB BBB BBBB BB BBBBB BBB BBBBBB BBBB BBBBB BBBBBB BBBBBBBBB BBBB BB BBBBB......................................................................
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+              BBBBB B'B BBB BBBBB. BBBB BBBBB BBBBB. ( B BBBBB BBBBBBBBBB BBBBB BBBB'B BBBBB BBBBB. BBB BBBB BBBBB BBBB BBBB. BBBBBBB BBB BB BBBBBBB BBB BBB B BBBB BBBBBBBBBBBB. BBBBB BBBBB.)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+             BBBB'B BB
+</code></pre>
+
+<p>.</p>
+
+<pre><code>        B BBB BBB BBB ? B. B BBB BBBBBB BBBB BBB BBBB. BBBBBBB BB BBBBBBB B BBBB BBBB BBB BBBBBB. 
+
+
+
+
+
+
+
+
+
+
+
+
+
+         BBBB BB 'BBBB' BBBB BBBBB.
+
+
+                           BBBBBBBB B BBBB BBBBBB BB BBBBBBBB BBB BBBBBBB BBBBBBB BBBBBBB. 
+
+
+     B BBBB BB BBBB. BBBBB BBBBBBBB. BBB BB BB. BB BB BBBB BB BBBBBBBBBB. BB BBBBBBBB BB BBBBBBBBB. 
+
+
+                     BBBBBBBB BB BBBB. BBBBBBB BBB BBBBB BBBBB BBBBB. B'BB BBBBBBB BB BBBBB BBBBB BBBBBBB BBB BBBBB. BBBB. 
+
+  B BBBBBB BBBB BB BBBB BBB. (BB BBB BBBBB BBBBB...............B)
+
+
+
+           BBBB!
+
+
+
+         BBBB BB BBB BBBBBBB BBBBBB.            B
+</code></pre>
+
+<p>B</p>
+
+<pre><code>     BBBBB BB/BBB BBBBB!  BBBB BBBB BBBBBBBBBBB 'BBB'B BBBBBB.' 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          BBBB BBBBBBB BBBB BB BBB BBBBBBBB BB BBBB BBBBBB BBB BBBBBBBBB BBBB. BBBBBBBB BBBBBBB BBBB BBBB BBBB BB BBBB BB BBBB BB BBBB B BBB BB BBBBB BBBBBB.  B BBBB BBBBBBB BB BBBB BBBBB B BBB BBBBBBB BB BBBBB BBBB. BBB BBBBBBB BBBB. B BBB BBBB BBBB B BBBB BBBBBB BBB B BBBBBB BBBBBB. BBB BB BBBBBB BBBBBB BBBBBBBBBB BB...BBBBB BBBB BBBB BB BBBBB. (BBBBBBB BBB BBBBBB BBB'B BBBB BBB BBBBB BBB BB BBBBB BBBBBBBBBBB  BBBBB B BBBB BBBB BBBBB. 
+
+
+
+
+
+
+
+
+
+BBBBB BB BB BBBB B'B BBBB BBBBB BBBBB BBB BB BBBBBB/BBB (BBBBB) BBBBBB BB. 
+                          BBBBBBBB. B BBB BBBB BB BB BBB/BBBBBB BBBBBB BBB BBBB BBBBBBBB BB BB B BBBBBB BBBBBB BBBBB. (BBB/B BBB BBBB BBBB...BBB BBB BBB BBBB BB BB B BBBB BB BBB BB? BBBBBBB B BBB B BBBB BBBBBBBB BBB B BBB BBB BBBBB BBBB BBB BBBB BB B BBBBBBBB BB BBBBB BB BB BBB BBBBB BBB BB BBBBB BBBBBBB B BBB BBBBBBB. BBBBBB (BBBBB) BBBB BBBBB BBBBBBB BBBBB BBBB BBBB BBB. 100 BBBBBB BB BBBBB. BBBB BBB BBB BBBBBB BBB BB. BBB BBBB BB BBB BBBBB! BBB BB BBBBBB BBBBB B BBB'B BBBBBBBBB BBBB BBB BBB. (BBBBBB BBBBBBB BB BBBB BBBBB (BBBBBB BBBBB BBBBB BBBBB.))
+
+
+    BBB B BBBBBBBBBBB BBBB BBB BB BBB. BBBBB BBB BBBBB B BBBB BBBBBB BBBBB BBB. BB BBBBBB BBB BBBB B BBB BB BBBBBBBB BBBBBB BBBB BBB B BBBBBB BBBB BBBBBB BBBBBBB BBBB BBBB BBB BBBBBBBB.
+
+
+
+
+
+
+
+
+
+
+
+           BBBBB!!!!!!!
+
+
+         B BBB BBBB BBBBBB BBBB BBBB BBBB B BBB BBBBB BBB BBBBB B BBBB BBBBBBB BB BB BBBB BBBBBBBBB. B BBBB BBBBBB BBBBBBB BBBB BBBB BBB BBBB.
+
+                                               BB BB, BB BBBBBB BBBB, (BBBBBB BB BBB BBBB . BBBBB BB BBBB BBBB BB BB BBBB BBBB B BBBB BB BB (BB BBBB BB BBB BBBBBBB BB BBBBBBB. )) BB'BB BBB BBB'B BB BB BBBB BB B BBBB B BBBBB (BB BBBBBB BB BBB B'BB BBBBBBBB BB BBBB BBBB.)
+
+
+  B BBBBB B'BB BBB BB BBBB BBB BBB.
+</code></pre>
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/issue_gh45.test b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/issue_gh45.test
new file mode 100644
index 0000000..1bf8901
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/issue_gh45.test
@@ -0,0 +1,188 @@
+   
+ 
+ B
+ 
+ 
+ 
+ 
+                           BBBBBBBB. 
+
+
+
+               BBBB BB BBBBBBBB BBBBB. BBBBBBB BB BBBBB BB BBB BBBB BBBBB BBB BBB BBBB BBB BBBBBBB BBB BBBBBBB. B BBB'B BBBBB BBBB BBB BBBB BBBBBBB BBBB BBBB BBBB BBBBBBBB.
+
+
+                    BBB BBBBB BBBBB BBB BBBB BBBB BBBB, BBB BBBBB BB BBBBB BBB BB BBBBBB BBBB BBB BBBBB BBBB BB. BBBBB BBB BBBBB BBBBB BBB BBBB BB BBBB BBBB BBBBB.
+
+
+                             BBBB BBBBB, BBBBB, BBBBBBBB?
+
+                       BB BBB BB BBBB BBB BBBB BBB BBBBBB /BBB BB BBBBBBBBB BBBB BBBBBBB BBBBBB BB BBB. 
+
+
+                       BBBB BBBBBBBB BBB BBBB BB BBBBB BBB BBBBBB BBBB BBBBB BBBBBB BBBBBBBBB BBBB BB BBBBB......................................................................
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                  BBBBB B'B BBB BBBBB. BBBB BBBBB BBBBB. ( B BBBBB BBBBBBBBBB BBBBB BBBB'B BBBBB BBBBB. BBB BBBB BBBBB BBBB BBBB. BBBBBBB BBB BB BBBBBBB BBB BBB B BBBB BBBBBBBBBBBB. BBBBB BBBBB.)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                 BBBB'B BB
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.
+
+            B BBB BBB BBB ? B. B BBB BBBBBB BBBB BBB BBBB. BBBBBBB BB BBBBBBB B BBBB BBBB BBB BBBBBB. 
+
+
+
+
+
+
+
+
+
+
+
+
+
+             BBBB BB 'BBBB' BBBB BBBBB.
+
+
+                               BBBBBBBB B BBBB BBBBBB BB BBBBBBBB BBB BBBBBBB BBBBBBB BBBBBBB. 
+
+
+         B BBBB BB BBBB. BBBBB BBBBBBBB. BBB BB BB. BB BB BBBB BB BBBBBBBBBB. BB BBBBBBBB BB BBBBBBBBB. 
+
+
+                         BBBBBBBB BB BBBB. BBBBBBB BBB BBBBB BBBBB BBBBB. B'BB BBBBBBB BB BBBBB BBBBB BBBBBBB BBB BBBBB. BBBB. 
+
+      B BBBBBB BBBB BB BBBB BBB. (BB BBB BBBBB BBBBB...............B)
+
+
+
+               BBBB!
+
+
+
+             BBBB BB BBB BBBBBBB BBBBBB.           
+B
+
+B
+
+
+
+         BBBBB BB/BBB BBBBB!  BBBB BBBB BBBBBBBBBBB 'BBB'B BBBBBB.' 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+              BBBB BBBBBBB BBBB BB BBB BBBBBBBB BB BBBB BBBBBB BBB BBBBBBBBB BBBB. BBBBBBBB BBBBBBB BBBB BBBB BBBB BB BBBB BB BBBB BB BBBB B BBB BB BBBBB BBBBBB.  B BBBB BBBBBBB BB BBBB BBBBB B BBB BBBBBBB BB BBBBB BBBB. BBB BBBBBBB BBBB. B BBB BBBB BBBB B BBBB BBBBBB BBB B BBBBBB BBBBBB. BBB BB BBBBBB BBBBBB BBBBBBBBBB BB...BBBBB BBBB BBBB BB BBBBB. (BBBBBBB BBB BBBBBB BBB'B BBBB BBB BBBBB BBB BB BBBBB BBBBBBBBBBB  BBBBB B BBBB BBBB BBBBB. 
+
+
+
+
+
+
+
+
+
+    BBBBB BB BB BBBB B'B BBBB BBBBB BBBBB BBB BB BBBBBB/BBB (BBBBB) BBBBBB BB. 
+                              BBBBBBBB. B BBB BBBB BB BB BBB/BBBBBB BBBBBB BBB BBBB BBBBBBBB BB BB B BBBBBB BBBBBB BBBBB. (BBB/B BBB BBBB BBBB...BBB BBB BBB BBBB BB BB B BBBB BB BBB BB? BBBBBBB B BBB B BBBB BBBBBBBB BBB B BBB BBB BBBBB BBBB BBB BBBB BB B BBBBBBBB BB BBBBB BB BB BBB BBBBB BBB BB BBBBB BBBBBBB B BBB BBBBBBB. BBBBBB (BBBBB) BBBB BBBBB BBBBBBB BBBBB BBBB BBBB BBB. 100 BBBBBB BB BBBBB. BBBB BBB BBB BBBBBB BBB BB. BBB BBBB BB BBB BBBBB! BBB BB BBBBBB BBBBB B BBB'B BBBBBBBBB BBBB BBB BBB. (BBBBBB BBBBBBB BB BBBB BBBBB (BBBBBB BBBBB BBBBB BBBBB.))
+
+
+        BBB B BBBBBBBBBBB BBBB BBB BB BBB. BBBBB BBB BBBBB B BBBB BBBBBB BBBBB BBB. BB BBBBBB BBB BBBB B BBB BB BBBBBBBB BBBBBB BBBB BBB B BBBBBB BBBB BBBBBB BBBBBBB BBBB BBBB BBB BBBBBBBB.
+
+
+
+
+
+
+
+
+
+
+
+               BBBBB!!!!!!!
+
+
+             B BBB BBBB BBBBBB BBBB BBBB BBBB B BBB BBBBB BBB BBBBB B BBBB BBBBBBB BB BB BBBB BBBBBBBBB. B BBBB BBBBBB BBBBBBB BBBB BBBB BBB BBBB.
+
+                                                   BB BB, BB BBBBBB BBBB, (BBBBBB BB BBB BBBB . BBBBB BB BBBB BBBB BB BB BBBB BBBB B BBBB BB BB (BB BBBB BB BBB BBBBBBB BB BBBBBBB. )) BB'BB BBB BBB'B BB BB BBBB BB B BBBB B BBBBB (BB BBBBBB BB BBB B'BB BBBBBBBB BB BBBB BBBB.)
+
+
+      B BBBBB B'BB BBB BB BBBB BBB BBB.
+
+
+       
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/lazy.html b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/lazy.html
new file mode 100644
index 0000000..47188f2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/lazy.html
@@ -0,0 +1,4 @@
+<pre><code>This is some code
+
+This is some  other code
+</code></pre>
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/lazy.text b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/lazy.text
new file mode 100644
index 0000000..2a95de6
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/lazy.text
@@ -0,0 +1,5 @@
+    This is some
+code
+
+    This is some
+ other code
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/no_newline_at_end.html b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/no_newline_at_end.html
new file mode 100644
index 0000000..7a003b2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/no_newline_at_end.html
@@ -0,0 +1,2 @@
+<pre><code>test  
+</code></pre>
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/no_newline_at_end.text b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/no_newline_at_end.text
new file mode 100644
index 0000000..b64563f
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/no_newline_at_end.text
@@ -0,0 +1 @@
+    test  
\ No newline at end of file
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/no_newline_at_end_1.html b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/no_newline_at_end_1.html
new file mode 100644
index 0000000..005870e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/no_newline_at_end_1.html
@@ -0,0 +1,2 @@
+<pre><code>test   test
+</code></pre>
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/no_newline_at_end_1.text b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/no_newline_at_end_1.text
new file mode 100644
index 0000000..65df71e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/no_newline_at_end_1.text
@@ -0,0 +1,2 @@
+    test  
+test
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/normal.html b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/normal.html
new file mode 100644
index 0000000..0bd2c1f
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/normal.html
@@ -0,0 +1,13 @@
+<pre><code>starting code
+</code></pre>
+
+<p>paragraph</p>
+
+<pre><code>other code  
+with samples 
+</code></pre>
+
+<p>paragraph</p>
+
+<pre><code>  ending code
+</code></pre>
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/normal.text b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/normal.text
new file mode 100644
index 0000000..40ea702
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/normal.text
@@ -0,0 +1,10 @@
+    starting code
+
+paragraph
+
+    other code  
+    with samples 
+
+paragraph
+
+      ending code
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/tilde_syntax.html b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/tilde_syntax.html
new file mode 100644
index 0000000..1ddd91e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/tilde_syntax.html
@@ -0,0 +1,7 @@
+<pre><code>Here comes some code.
+</code></pre>
+
+<pre><code>~~~~~~~
+code with tildes
+~~~~~~~~
+</code></pre>
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/tilde_syntax.text b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/tilde_syntax.text
new file mode 100644
index 0000000..7625a1b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/tilde_syntax.text
@@ -0,0 +1,9 @@
+~~~~~~~~
+Here comes some code.
+~~~~~~~~
+
+~~~~~~~~~~~~
+~~~~~~~
+code with tildes
+~~~~~~~~
+~~~~~~~~~~~~~~~~~~
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/whitespace.html b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/whitespace.html
new file mode 100644
index 0000000..dcbb40f
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/whitespace.html
@@ -0,0 +1,3 @@
+<pre class="show-whitespaces"><code>This<span class="ws-tab">	</span>is<span class="ws-space">⋅</span>some<span class="ws-space-r">⋅</span><span class="ws-space-r">⋅</span>
+<span class="ws-space-l">⋅</span><span class="ws-space-l">⋅</span><span class="ws-space-l">⋅</span><span class="ws-space-l">⋅</span>whitespace<span class="ws-space-r">⋅</span><span class="ws-space-r">⋅</span>
+</code></pre>
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/whitespace.text b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/whitespace.text
new file mode 100644
index 0000000..b15c9c9
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/whitespace.text
@@ -0,0 +1,3 @@
+    This	is some  
+        whitespace  
+{:.show-whitespaces}
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_blank_line.html b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_blank_line.html
new file mode 100644
index 0000000..f7c20b2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_blank_line.html
@@ -0,0 +1,13 @@
+<p>paragraph</p>
+
+<pre><code>code block
+
+continued here
+</code></pre>
+
+<p>ended</p>
+
+<pre><code>next blank line has 4 spaces
+</code></pre>
+
+<p>paragraph</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_blank_line.text b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_blank_line.text
new file mode 100644
index 0000000..e51dfa5
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_blank_line.text
@@ -0,0 +1,12 @@
+paragraph
+
+    code block
+
+    continued here
+    
+
+ended
+
+    next blank line has 4 spaces
+    
+paragraph
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_eob_marker.html b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_eob_marker.html
new file mode 100644
index 0000000..cca17a2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_eob_marker.html
@@ -0,0 +1,6 @@
+<pre><code>code block
+
+continued here
+</code></pre>
+<pre><code>new block here
+</code></pre>
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_eob_marker.text b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_eob_marker.text
new file mode 100644
index 0000000..834c768
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_eob_marker.text
@@ -0,0 +1,5 @@
+    code block
+
+    continued here
+^
+    new block here
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_ial.html b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_ial.html
new file mode 100644
index 0000000..77085b3
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_ial.html
@@ -0,0 +1,6 @@
+<pre class="cls"><code>code block
+
+continued here
+</code></pre>
+<pre><code>new block here
+</code></pre>
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_ial.text b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_ial.text
new file mode 100644
index 0000000..4489f2d
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_ial.text
@@ -0,0 +1,5 @@
+    code block
+
+    continued here
+{:.cls}
+    new block here
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_lang_in_fenced_block.html b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_lang_in_fenced_block.html
new file mode 100644
index 0000000..f5872c3
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_lang_in_fenced_block.html
@@ -0,0 +1,24 @@
+<pre><code class="language-ruby">def what?
+  42
+end
+</code></pre>
+
+<pre class="class1"><code class="language-ruby">def what?
+  42
+end
+</code></pre>
+
+<pre><code class="language-ruby">def what?
+  42
+end
+</code></pre>
+
+<pre class="language-python"><code class="language-ruby">def what?
+  42
+end
+</code></pre>
+
+<pre class="language-python"><code class="language-ruby">def what?
+  42
+end
+</code></pre>
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_lang_in_fenced_block.options b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_lang_in_fenced_block.options
new file mode 100644
index 0000000..871923c
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_lang_in_fenced_block.options
@@ -0,0 +1,2 @@
+:enable_coderay: false
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_lang_in_fenced_block.text b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_lang_in_fenced_block.text
new file mode 100644
index 0000000..07f437e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/06_codeblock/with_lang_in_fenced_block.text
@@ -0,0 +1,33 @@
+~~~ ruby
+def what?
+  42
+end
+~~~
+
+~~~ ruby
+def what?
+  42
+end
+~~~
+{:.class1}
+
+~~~
+def what?
+  42
+end
+~~~
+{: .language-ruby}
+
+~~~ ruby
+def what?
+  42
+end
+~~~
+{: .language-python}
+
+~~~ ruby
+def what?
+  42
+end
+~~~
+{: class="language-python"}
diff --git a/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/error.html b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/error.html
new file mode 100644
index 0000000..6b01ba9
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/error.html
@@ -0,0 +1,7 @@
+<p>_ * _</p>
+
+<p>— * * *</p>
+
+<p>_ - *</p>
+
+<p>———————————————- test</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/error.html.19 b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/error.html.19
new file mode 100644
index 0000000..068811c
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/error.html.19
@@ -0,0 +1,7 @@
+<p>_ * _</p>
+
+<p>— * * *</p>
+
+<p>_ - *</p>
+
+<p>———————————————- test</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/error.text b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/error.text
new file mode 100644
index 0000000..a024710
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/error.text
@@ -0,0 +1,7 @@
+_ * _
+
+--- * * *
+
+_ - *
+
+---------------------------------------------- test
diff --git a/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/normal.html b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/normal.html
new file mode 100644
index 0000000..e74b6e6
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/normal.html
@@ -0,0 +1,19 @@
+<hr />
+<hr />
+<hr />
+
+<p>d- -</p>
+
+<hr />
+<hr />
+<hr />
+
+<h2>para</h2>
+<p>text</p>
+
+<hr />
+
+<pre><code>- - -
+</code></pre>
+
+<hr class="test" />
diff --git a/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/normal.text b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/normal.text
new file mode 100644
index 0000000..986101a
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/normal.text
@@ -0,0 +1,20 @@
+***
+* * *
+-  - -   
+
+d- -
+
+---
+___
+***
+
+para
+-----------
+text
+
+* * *
+
+    - - -
+
+* * *
+{:.test}
diff --git a/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/sepspaces.html b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/sepspaces.html
new file mode 100644
index 0000000..dbb86e5
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/sepspaces.html
@@ -0,0 +1,3 @@
+<hr />
+<hr />
+<hr />
diff --git a/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/sepspaces.text b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/sepspaces.text
new file mode 100644
index 0000000..a5798b2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/sepspaces.text
@@ -0,0 +1,3 @@
+- - -
+*      *      *
+_  _ _    _  _
diff --git a/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/septabs.html b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/septabs.html
new file mode 100644
index 0000000..dbb86e5
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/septabs.html
@@ -0,0 +1,3 @@
+<hr />
+<hr />
+<hr />
diff --git a/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/septabs.text b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/septabs.text
new file mode 100644
index 0000000..464fe20
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/07_horizontal_rule/septabs.text
@@ -0,0 +1,3 @@
+-	-	-
+*		*		*
+_		_	_			_	_
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/escaping.html b/app/server/vendor/kramdown/test/testcases/block/08_list/escaping.html
new file mode 100644
index 0000000..afc795c
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/escaping.html
@@ -0,0 +1,17 @@
+<p>I have read the book
+1984. It was great
+- other say that, too!</p>
+
+<p>I have read the book
+1984. It was great
+- other say that, too!</p>
+
+<p>I have read the book
+  1984. It was great.</p>
+
+<p>I have read the book 1984.
+  - it was great!</p>
+
+<p>1984. Was great!</p>
+
+<p>- This too!</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/escaping.text b/app/server/vendor/kramdown/test/testcases/block/08_list/escaping.text
new file mode 100644
index 0000000..c3b1c59
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/escaping.text
@@ -0,0 +1,17 @@
+I have read the book
+1984. It was great
+- other say that, too!
+
+I have read the book
+1984\. It was great
+\- other say that, too!
+
+I have read the book
+  1984. It was great.
+
+I have read the book 1984.
+  - it was great!
+
+1984\. Was great!
+
+\- This too!
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/item_ial.html b/app/server/vendor/kramdown/test/testcases/block/08_list/item_ial.html
new file mode 100644
index 0000000..e6dfd3a
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/item_ial.html
@@ -0,0 +1,10 @@
+<ul>
+  <li class="cls">IAL at first
+continued</li>
+  <li>another {:.cls}</li>
+  <li class="cls">IAL at last
+    code</li>
+  <li>X
+  test</li>
+  <li>X OK</li>
+</ul>
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/item_ial.text b/app/server/vendor/kramdown/test/testcases/block/08_list/item_ial.text
new file mode 100644
index 0000000..67bee70
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/item_ial.text
@@ -0,0 +1,8 @@
+*   {:.cls} IAL at first
+    continued
+* another {:.cls}
+* {:.cls} IAL at last
+      code
+* {::nomarkdown type="html"}X{:/nomarkdown}
+    test
+* {::nomarkdown type="html"}X{:/nomarkdown} OK
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/lazy.html b/app/server/vendor/kramdown/test/testcases/block/08_list/lazy.html
new file mode 100644
index 0000000..01a5f9d
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/lazy.html
@@ -0,0 +1,39 @@
+<ul>
+  <li>This is a simple
+list item</li>
+  <li>
+    <p>Followed by another
+list item</p>
+  </li>
+  <li>
+    <p>Followed by</p>
+
+    <p>a para list item
+continued here</p>
+  </li>
+  <li>and a normal one</li>
+  <li>
+    <p>and</p>
+
+    <p>a para
+continued here</p>
+  </li>
+</ul>
+
+<p>para</p>
+
+<ul>
+  <li>multi line
+list item</li>
+</ul>
+
+<p>para</p>
+
+<ul>
+  <li>list item line1
+ one line
+  two lines</li>
+  <li>list item line2
+one line
+two lines</li>
+</ul>
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/lazy.text b/app/server/vendor/kramdown/test/testcases/block/08_list/lazy.text
new file mode 100644
index 0000000..f372422
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/lazy.text
@@ -0,0 +1,29 @@
+* This is a simple
+list item
+* Followed by another
+list item
+
+
+* Followed by
+
+    a para list item
+continued here
+* and a normal one
+* and
+
+    a para
+continued here
+
+para
+
+* multi line
+list item
+
+para
+
+*  list item line1
+ one line
+  two lines
+*  list item line2
+   one line
+two lines
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/list_and_hr.html b/app/server/vendor/kramdown/test/testcases/block/08_list/list_and_hr.html
new file mode 100644
index 0000000..ecf51c7
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/list_and_hr.html
@@ -0,0 +1,9 @@
+<ul>
+  <li>Starting a list</li>
+</ul>
+
+<hr />
+
+<ul>
+  <li>Starting a new list</li>
+</ul>
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/list_and_hr.text b/app/server/vendor/kramdown/test/testcases/block/08_list/list_and_hr.text
new file mode 100644
index 0000000..c7fcd47
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/list_and_hr.text
@@ -0,0 +1,5 @@
+* Starting a list
+
+* * *
+
+* Starting a new list
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/list_and_others.html b/app/server/vendor/kramdown/test/testcases/block/08_list/list_and_others.html
new file mode 100644
index 0000000..672428e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/list_and_others.html
@@ -0,0 +1,40 @@
+<ul>
+  <li>list item</li>
+</ul>
+
+<blockquote>
+  <p>blockquote</p>
+</blockquote>
+
+<p>para
+* * *
+para
+  - no list</p>
+
+<ul>
+  <li>
+    <p>item</p>
+
+    <blockquote>
+      <p>block</p>
+    </blockquote>
+
+    <h2>header</h2>
+  </li>
+  <li>
+    <p>test</p>
+
+    <pre><code>codeblock
+</code></pre>
+
+    <p>test</p>
+  </li>
+  <li>
+    <p>test</p>
+
+    <pre><code>codeblock
+</code></pre>
+
+    <p>test</p>
+  </li>
+</ul>
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/list_and_others.text b/app/server/vendor/kramdown/test/testcases/block/08_list/list_and_others.text
new file mode 100644
index 0000000..f680262
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/list_and_others.text
@@ -0,0 +1,26 @@
+* list item
+
+> blockquote
+
+para
+* * *
+para
+  - no list
+
++ item
+
+  > block
+
+  ## header
+
+* test
+
+      codeblock
+
+  test
+
+*	test
+
+		codeblock
+
+	test
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/mixed.html b/app/server/vendor/kramdown/test/testcases/block/08_list/mixed.html
new file mode 100644
index 0000000..9bc47e3
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/mixed.html
@@ -0,0 +1,117 @@
+<p>With tabs/spaces, no paras:</p>
+
+<ul>
+  <li>item1</li>
+  <li>item2</li>
+  <li>item3</li>
+</ul>
+
+<p>With tabs/spaces, paras:</p>
+
+<ul>
+  <li>
+    <p>item1</p>
+  </li>
+  <li>
+    <p>item2</p>
+  </li>
+  <li>
+    <p>item3</p>
+  </li>
+</ul>
+
+<p>With tabs/spaces, no paras:</p>
+
+<ol>
+  <li>item1</li>
+  <li>item2</li>
+  <li>item3</li>
+</ol>
+
+<p>With tabs/spaces, paras:</p>
+
+<ol>
+  <li>
+    <p>item1</p>
+  </li>
+  <li>
+    <p>item2</p>
+  </li>
+  <li>
+    <p>item3</p>
+  </li>
+</ol>
+
+<p>Nested, without paras:</p>
+
+<ul>
+  <li>item1
+    <ul>
+      <li>item2
+        <ul>
+          <li>item3</li>
+        </ul>
+      </li>
+    </ul>
+  </li>
+</ul>
+
+<p>Nested, with paras:</p>
+
+<ul>
+  <li>
+    <p>item1</p>
+
+    <ul>
+      <li>item2
+        <ul>
+          <li>item3 (level 3)</li>
+        </ul>
+      </li>
+    </ul>
+  </li>
+</ul>
+
+<p>Ordered, without paras:</p>
+
+<ol>
+  <li>item1</li>
+  <li>item2
+    <ul>
+      <li>do</li>
+      <li>it</li>
+      <li>now</li>
+    </ul>
+  </li>
+  <li>item3</li>
+</ol>
+
+<p>Ordered, with paras:</p>
+
+<ol>
+  <li>
+    <p>item1</p>
+  </li>
+  <li>
+    <p>item2</p>
+
+    <ul>
+      <li>do</li>
+      <li>it</li>
+      <li>now</li>
+    </ul>
+  </li>
+  <li>
+    <p>item3</p>
+  </li>
+</ol>
+
+<p>Mixed tabs and spaces:</p>
+
+<ul>
+  <li>some text
+    <ul>
+      <li>nested</li>
+    </ul>
+  </li>
+</ul>
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/mixed.text b/app/server/vendor/kramdown/test/testcases/block/08_list/mixed.text
new file mode 100644
index 0000000..22b578d
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/mixed.text
@@ -0,0 +1,66 @@
+With tabs/spaces, no paras:
+
+*	item1
++   item2
+-	item3
+
+With tabs/spaces, paras:
+
+-	item1
+
+*   item2
+
++	item3
+
+With tabs/spaces, no paras:
+
+1.	item1
+20. item2
+3.	item3
+
+With tabs/spaces, paras:
+
+1.	item1
+
+2.  item2
+
+3.	item3
+
+Nested, without paras:
+
+*	item1
+    *    item2
+	     *	item3
+
+Nested, with paras:
+
++   item1
+
+	* item2
+      * item3 (level 3)
+
+Ordered, without paras:
+
+1. item1
+2. item2
+	* do
+    * it
+    * now
+3. item3
+
+Ordered, with paras:
+
+1. item1
+
+2. item2
+
+	* do
+    * it
+    * now
+
+3. item3
+
+Mixed tabs and spaces:
+
+* 	  	some text
+        * nested
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/nested.html b/app/server/vendor/kramdown/test/testcases/block/08_list/nested.html
new file mode 100644
index 0000000..1921ee9
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/nested.html
@@ -0,0 +1,17 @@
+<ul>
+  <li>some item
+    <ul>
+      <li>nested</li>
+    </ul>
+  </li>
+  <li>last item</li>
+</ul>
+<ul>
+  <li>
+    <p>some text</p>
+
+    <ul>
+      <li>nested</li>
+    </ul>
+  </li>
+</ul>
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/nested.text b/app/server/vendor/kramdown/test/testcases/block/08_list/nested.text
new file mode 100644
index 0000000..c71d864
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/nested.text
@@ -0,0 +1,7 @@
+* some item
+    * nested
+* last item
+^
+*	some text
+
+	* nested
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/other_first_element.html b/app/server/vendor/kramdown/test/testcases/block/08_list/other_first_element.html
new file mode 100644
index 0000000..3f4cd0f
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/other_first_element.html
@@ -0,0 +1,39 @@
+<ul>
+  <li>
+    <pre><code>This is a code block.
+</code></pre>
+  </li>
+  <li>
+    <blockquote>
+      <p>This is a blockquote.</p>
+    </blockquote>
+  </li>
+  <li>
+    <h2>A header</h2>
+  </li>
+</ul>
+<ul>
+  <li>
+    <pre><code>This is a code block.
+</code></pre>
+  </li>
+  <li>
+    <blockquote>
+      <p>This is a blockquote.
+continued by some para.</p>
+    </blockquote>
+  </li>
+  <li>
+    <h1>A header</h1>
+    <p>a para</p>
+  </li>
+</ul>
+<ul>
+  <li>
+    <ul>
+      <li>nested list</li>
+      <li>other nested item</li>
+    </ul>
+  </li>
+  <li>item 2</li>
+</ul>
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/other_first_element.text b/app/server/vendor/kramdown/test/testcases/block/08_list/other_first_element.text
new file mode 100644
index 0000000..321cef6
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/other_first_element.text
@@ -0,0 +1,18 @@
+* 
+        This is a code block.
+*   > This is a blockquote.
+*   ## A header
+^
+* 
+        This is a code block.
+
+*    > This is a blockquote.
+     continued by some para.
+
+*   A header
+    =========
+    a para
+^
+*   * nested list
+    * other nested item
+*   item 2
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/simple_ol.html b/app/server/vendor/kramdown/test/testcases/block/08_list/simple_ol.html
new file mode 100644
index 0000000..84e5a6b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/simple_ol.html
@@ -0,0 +1,19 @@
+<ol>
+  <li>This is a simple list item</li>
+  <li>
+    <p>Followed by another</p>
+  </li>
+  <li>
+    <p>Followed by</p>
+
+    <p>a para list item</p>
+  </li>
+  <li>and a normal one</li>
+  <li>
+    <p>and</p>
+
+    <p>a para</p>
+  </li>
+</ol>
+
+<p>para</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/simple_ol.text b/app/server/vendor/kramdown/test/testcases/block/08_list/simple_ol.text
new file mode 100644
index 0000000..aaf7dae
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/simple_ol.text
@@ -0,0 +1,13 @@
+1. This is a simple list item
+3. Followed by another
+
+
+10.	Followed by
+
+    a para list item
+1. and a normal one
+2. and
+
+    a para
+
+para
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/simple_ul.html b/app/server/vendor/kramdown/test/testcases/block/08_list/simple_ul.html
new file mode 100644
index 0000000..68db05e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/simple_ul.html
@@ -0,0 +1,48 @@
+<ul>
+  <li>This is a simple list item</li>
+  <li>
+    <p>Followed by another</p>
+  </li>
+  <li>
+    <p>Followed by</p>
+
+    <p>a para list item</p>
+  </li>
+  <li>and a normal one</li>
+  <li>
+    <p>and</p>
+
+    <p>a para</p>
+  </li>
+</ul>
+
+<p>para</p>
+
+<ul>
+  <li>multi line
+list item</li>
+</ul>
+
+<p>para</p>
+
+<ul>
+  <li>list item line1
+one line
+two lines</li>
+  <li>list item line2
+one line
+two lines</li>
+</ul>
+
+<p>para</p>
+
+<ul>
+  <li>list item line3
+one line
+two lines</li>
+  <li>list item line4
+ one line
+  two lines</li>
+</ul>
+
+<p>para</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/simple_ul.text b/app/server/vendor/kramdown/test/testcases/block/08_list/simple_ul.text
new file mode 100644
index 0000000..ccd25c3
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/simple_ul.text
@@ -0,0 +1,36 @@
+* This is a simple list item
+* Followed by another
+
+
+* Followed by
+
+    a para list item
+* and a normal one
+* and
+
+    a para
+
+para
+
+* multi line
+  list item
+
+para
+
+*  list item line1
+   one line
+   two lines
+*  list item line2
+   one line
+   two lines
+
+para
+
+*   list item line3
+    one line
+    two lines
+*  list item line4
+    one line
+     two lines
+
+para
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/single_item.html b/app/server/vendor/kramdown/test/testcases/block/08_list/single_item.html
new file mode 100644
index 0000000..e079461
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/single_item.html
@@ -0,0 +1,3 @@
+<ul>
+  <li>single</li>
+</ul>
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/single_item.text b/app/server/vendor/kramdown/test/testcases/block/08_list/single_item.text
new file mode 100644
index 0000000..877d369
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/single_item.text
@@ -0,0 +1 @@
+* single
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/special_cases.html b/app/server/vendor/kramdown/test/testcases/block/08_list/special_cases.html
new file mode 100644
index 0000000..fbc775a
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/special_cases.html
@@ -0,0 +1,62 @@
+<ul>
+  <li>
+    <p>not a para
+here</p>
+
+    <blockquote>
+      <p>blockquote</p>
+    </blockquote>
+  </li>
+  <li>
+    <p>and not
+  here</p>
+
+    <blockquote>
+      <p>blockquote</p>
+    </blockquote>
+  </li>
+  <li>
+    <p>this is a para</p>
+  </li>
+  <li>
+    <blockquote>
+      <p>blockquote</p>
+    </blockquote>
+  </li>
+  <li>
+    <p>this too</p>
+  </li>
+</ul>
+
+<p>A paragraph
+  1. followed not by ol
+- followed not by ul</p>
+
+<p>A compact list:</p>
+
+<ul>
+  <li>compact</li>
+  <li>list</li>
+  <li>items</li>
+</ul>
+
+<p>A normal list:</p>
+
+<ul>
+  <li>
+    <p>not</p>
+  </li>
+  <li>
+    <p>compact</p>
+  </li>
+  <li>
+    <p>but here</p>
+  </li>
+</ul>
+
+<p>List item without content:</p>
+
+<ul>
+  <li></li>
+  <li>a</li>
+</ul>
diff --git a/app/server/vendor/kramdown/test/testcases/block/08_list/special_cases.text b/app/server/vendor/kramdown/test/testcases/block/08_list/special_cases.text
new file mode 100644
index 0000000..7406305
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/08_list/special_cases.text
@@ -0,0 +1,40 @@
+* not a para
+  here
+
+    > blockquote
+
+* and not
+    here
+
+    >blockquote
+
+* this is a para
+
+* > blockquote
+
+* this too
+
+^
+
+A paragraph
+  1. followed not by ol
+- followed not by ul
+
+A compact list:
+
+* compact
+* list
+* items
+
+A normal list:
+
+* not
+
+* compact
+
+* but here
+
+List item without content:
+
+* 
+* a
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/comment.html b/app/server/vendor/kramdown/test/testcases/block/09_html/comment.html
new file mode 100644
index 0000000..8d31bd4
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/comment.html
@@ -0,0 +1,18 @@
+<!--comment-->
+
+<p>para1</p>
+
+<!-- Comment -->
+
+<p>para2</p>
+
+<!--
+Blah
+Blah
+-->
+<p>para</p>
+
+<blockquote>
+  <p>This is
+<!-- a comment --></p>
+</blockquote>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/comment.text b/app/server/vendor/kramdown/test/testcases/block/09_html/comment.text
new file mode 100644
index 0000000..b632bf2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/comment.text
@@ -0,0 +1,15 @@
+<!--comment-->
+
+para1
+
+<!-- Comment -->
+
+para2
+
+<!--
+Blah
+Blah
+--> para
+
+> This is
+> <!-- a comment -->
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/deflists.html b/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/deflists.html
new file mode 100644
index 0000000..587d55a
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/deflists.html
@@ -0,0 +1,6 @@
+<dl>
+  <dt><em>text</em></dt>
+  <dd>
+    <p>para</p>
+  </dd>
+</dl>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/deflists.options b/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/deflists.options
new file mode 100644
index 0000000..a660da2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/deflists.options
@@ -0,0 +1 @@
+:parse_block_html: true
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/deflists.text b/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/deflists.text
new file mode 100644
index 0000000..1e381d1
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/deflists.text
@@ -0,0 +1,6 @@
+<dl>
+<dt>*text*</dt>
+<dd>
+para
+</dd>
+</dl>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/tables.html b/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/tables.html
new file mode 100644
index 0000000..e11dc14
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/tables.html
@@ -0,0 +1,14 @@
+<table class="examples">
+<tr>
+  <th><em>Usage</em></th>
+  <th>
+Output
+  </th>
+</tr>
+<tr>
+  <td>Some <em>data</em></td>
+  <td>
+      <h1 id="some-more">Some more</h1>
+    </td>
+</tr>
+</table>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/tables.options b/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/tables.options
new file mode 100644
index 0000000..a660da2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/tables.options
@@ -0,0 +1 @@
+:parse_block_html: true
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/tables.text b/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/tables.text
new file mode 100644
index 0000000..c0cf2e7
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/content_model/tables.text
@@ -0,0 +1,14 @@
+<table class="examples">
+<tr>
+  <th markdown="span">*Usage*</th>
+  <th>
+Output
+  </th>
+</tr>
+<tr>
+  <td markdown="span">Some *data*</td>
+  <td markdown="1">
+# Some more
+  </td>
+</tr>
+</table>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html5_attributes.html b/app/server/vendor/kramdown/test/testcases/block/09_html/html5_attributes.html
new file mode 100644
index 0000000..c68a432
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html5_attributes.html
@@ -0,0 +1,13 @@
+<p lang="en" style="nothing" class="">paragraph</p>
+
+<p lang="en" style="nothing" class="">paragraph</p>
+
+<p lang="en" style="nothing" class="">paragraph</p>
+
+<p lang="en" class="" style="nothing">paragraph</p>
+
+<p class="" lang="en" style="nothing">paragraph</p>
+
+<p class="">paragraph</p>
+
+<p class="">paragraph</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html5_attributes.text b/app/server/vendor/kramdown/test/testcases/block/09_html/html5_attributes.text
new file mode 100644
index 0000000..de182a9
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html5_attributes.text
@@ -0,0 +1,13 @@
+<p lang="en" style='nothing' class>paragraph</p>
+
+<p lang='en' style="nothing" class>paragraph</p>
+
+<p lang='en' style="nothing" class >paragraph</p>
+
+<p lang='en' class style="nothing">paragraph</p>
+
+<p class lang='en' style="nothing">paragraph</p>
+
+<p cLaSs>paragraph</p>
+
+<p class >paragraph</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_and_codeblocks.html b/app/server/vendor/kramdown/test/testcases/block/09_html/html_and_codeblocks.html
new file mode 100644
index 0000000..93d695a
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_and_codeblocks.html
@@ -0,0 +1,15 @@
+<p>para</p>
+
+<pre><code>codeblock
+</code></pre>
+
+<div>
+  <p>test</p>
+</div>
+
+<pre><code><p>codeblock</p>
+</code></pre>
+
+<div>
+  <p>test</p>
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_and_codeblocks.options b/app/server/vendor/kramdown/test/testcases/block/09_html/html_and_codeblocks.options
new file mode 100644
index 0000000..a660da2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_and_codeblocks.options
@@ -0,0 +1 @@
+:parse_block_html: true
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_and_codeblocks.text b/app/server/vendor/kramdown/test/testcases/block/09_html/html_and_codeblocks.text
new file mode 100644
index 0000000..a3cfda7
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_and_codeblocks.text
@@ -0,0 +1,13 @@
+para
+
+    codeblock
+
+<div>
+  test
+</div>
+
+    <p>codeblock</p>
+
+<div>
+  test
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_and_headers.html b/app/server/vendor/kramdown/test/testcases/block/09_html/html_and_headers.html
new file mode 100644
index 0000000..65cb7e2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_and_headers.html
@@ -0,0 +1,5 @@
+<h1>header</h1>
+
+<div>
+======
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_and_headers.text b/app/server/vendor/kramdown/test/testcases/block/09_html/html_and_headers.text
new file mode 100644
index 0000000..64dc477
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_and_headers.text
@@ -0,0 +1,6 @@
+header
+======
+
+<div>
+======
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/code.html b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/code.html
new file mode 100644
index 0000000..f4b3221
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/code.html
@@ -0,0 +1,10 @@
+<p>This is a <code>code span with <entities> that should be preserved</code>.
+This is a <code>simple code</code> span.</p>
+
+<p>Some <code><</code></p>
+
+<pre><code>Some very important < thing
+</code></pre>
+
+<pre><code>Some code<<
+</code></pre>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/code.text b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/code.text
new file mode 100644
index 0000000..fda7db5
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/code.text
@@ -0,0 +1,9 @@
+This is a <code>code span <b>with</b> <entities> that should be preserved</code>.
+This is a <code>simple code</code> span.
+
+<p>Some <code><</code></p>
+
+<pre>Some very important <b><</b> thing</pre>
+
+<pre><code>Some code<span><</span><
+</code></pre>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/comment.html b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/comment.html
new file mode 100644
index 0000000..dacd437
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/comment.html
@@ -0,0 +1,7 @@
+<div>
+  <!--comment-->
+  <!--
+Blah
+Blah
+-->
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/comment.text b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/comment.text
new file mode 100644
index 0000000..1788630
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/comment.text
@@ -0,0 +1,8 @@
+<div>
+  <!--comment-->
+
+  <!--
+Blah
+Blah
+-->
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/emphasis.html b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/emphasis.html
new file mode 100644
index 0000000..e4389c0
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/emphasis.html
@@ -0,0 +1,6 @@
+<p>This is <em>sized<strong>hallo</strong></em>.</p>
+
+<p>This is <strong>strong<em>italic</em>, yes!</strong>.</p>
+
+<p>This is <em> not</em> converted, as <em>is
+</em> this.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/emphasis.text b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/emphasis.text
new file mode 100644
index 0000000..7c75930
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/emphasis.text
@@ -0,0 +1,6 @@
+This is <em>sized<strong>hallo</strong></em>.
+
+This is <b>strong<i>italic</i>, yes!</b>.
+
+This is <em> not</em> converted, as <em>is
+</em> this.
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/entity.html b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/entity.html
new file mode 100644
index 0000000..5c80ce6
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/entity.html
@@ -0,0 +1 @@
+<p>This is *raw* HTML text containing < entities!</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/entity.text b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/entity.text
new file mode 100644
index 0000000..5c80ce6
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/entity.text
@@ -0,0 +1 @@
+<p>This is *raw* HTML text containing < entities!</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/header.html b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/header.html
new file mode 100644
index 0000000..aebb206
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/header.html
@@ -0,0 +1,6 @@
+<h1 id="some-headerhere">Some <em class="cls">header</em>here!</h1>
+<h2 id="test">hallo</h2>
+<h3 id="hallo">hallo</h3>
+<h4 id="hallo-1">hallo</h4>
+<h5 id="hallo-2">hallo</h5>
+<h6 id="hallo-3">hallo</h6>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/header.options b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/header.options
new file mode 100644
index 0000000..987b4d9
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/header.options
@@ -0,0 +1,2 @@
+:auto_ids: true
+:html_to_native: true
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/header.text b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/header.text
new file mode 100644
index 0000000..27eed3b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/header.text
@@ -0,0 +1,6 @@
+<h1>Some <em class='cls'>header</em>here!</h1>
+<h2 id="test">hallo</h2>
+<h3>hallo</h3>
+<h4>hallo</h4>
+<h5>hallo</h5>
+<h6>hallo</h6>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_dl.html b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_dl.html
new file mode 100644
index 0000000..6eaccfe
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_dl.html
@@ -0,0 +1,8 @@
+<dl>
+  <dt>kram</dt>
+  <dd>down</dd>
+  <dt>kram</dt>
+  <dd>down</dd>
+  <dt>kram</dt>
+  <dd>down</dd>
+</dl>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_dl.text b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_dl.text
new file mode 100644
index 0000000..6eaccfe
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_dl.text
@@ -0,0 +1,8 @@
+<dl>
+  <dt>kram</dt>
+  <dd>down</dd>
+  <dt>kram</dt>
+  <dd>down</dd>
+  <dt>kram</dt>
+  <dd>down</dd>
+</dl>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_ol.html b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_ol.html
new file mode 100644
index 0000000..eeebdfb
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_ol.html
@@ -0,0 +1,15 @@
+<ol>
+  <li>This is a simple list item</li>
+  <li>
+    <p>Followed by another</p>
+  </li>
+  <li>
+    <p>Followed by</p>
+    <p>a para list item</p>
+  </li>
+  <li>and a normal one</li>
+  <li>
+    <p>and</p>
+    <p>a para</p>
+  </li>
+</ol>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_ol.text b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_ol.text
new file mode 100644
index 0000000..41246df
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_ol.text
@@ -0,0 +1,17 @@
+<ol>
+  <li>This is a simple list item</li>
+  <li>
+    <p>Followed by another</p>
+  </li>
+  <li>
+    <p>Followed by</p>
+
+    <p>a para list item</p>
+  </li>
+  <li>and a normal one</li>
+  <li>
+    <p>and</p>
+
+    <p>a para</p>
+  </li>
+</ol>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_ul.html b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_ul.html
new file mode 100644
index 0000000..c9b38d0
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_ul.html
@@ -0,0 +1,19 @@
+<ul>
+  <li>This is a simple list item</li>
+  <li>
+    <p>Followed by another</p>
+  </li>
+  <li>
+    <p>Followed by</p>
+    <p>a para list item</p>
+  </li>
+  <li>and a normal one</li>
+  <li>
+    <p>and</p>
+    <p>a para</p>
+  </li>
+</ul>
+
+<ul>
+  <li>multi line list item</li>
+</ul>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_ul.text b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_ul.text
new file mode 100644
index 0000000..5a2d68e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/list_ul.text
@@ -0,0 +1,22 @@
+<ul>
+  <li>This is a simple list item</li>
+  <li>
+    <p>Followed by another</p>
+  </li>
+  <li>
+    <p>Followed by</p>
+
+    <p>a para list item</p>
+  </li>
+  <li>and a normal one</li>
+  <li>
+    <p>and</p>
+
+    <p>a para</p>
+  </li>
+</ul>
+
+<ul>
+  <li>multi line
+list item</li>
+</ul>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/options b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/options
new file mode 100644
index 0000000..63936b9
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/options
@@ -0,0 +1 @@
+:html_to_native: true
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/paragraph.html b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/paragraph.html
new file mode 100644
index 0000000..a276b1c
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/paragraph.html
@@ -0,0 +1,3 @@
+<p>Some text here<span> and </span>end</p>
+
+<p>Some other text here</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/paragraph.text b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/paragraph.text
new file mode 100644
index 0000000..b10035c
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/paragraph.text
@@ -0,0 +1,4 @@
+<p>Some text here<span> and </span>end
+</p>
+
+<p>Some other text here</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/table_normal.html b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/table_normal.html
new file mode 100644
index 0000000..bdd79ee
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/table_normal.html
@@ -0,0 +1,12 @@
+<table class="examples">
+<tr>
+  <th>Usage</th>
+  <th>Other</th>
+</tr>
+<tr>
+  <td>Some *data*</td>
+  <td>
+    <p>Some more</p>
+  </td>
+</tr>
+</table>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/table_normal.text b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/table_normal.text
new file mode 100644
index 0000000..bdd79ee
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/table_normal.text
@@ -0,0 +1,12 @@
+<table class="examples">
+<tr>
+  <th>Usage</th>
+  <th>Other</th>
+</tr>
+<tr>
+  <td>Some *data*</td>
+  <td>
+    <p>Some more</p>
+  </td>
+</tr>
+</table>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/table_simple.html b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/table_simple.html
new file mode 100644
index 0000000..88d9e6c
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/table_simple.html
@@ -0,0 +1,61 @@
+<table class="examples">
+  <tbody>
+    <tr>
+      <td>Usage</td>
+      <td>Output</td>
+    </tr>
+    <tr>
+      <td>Some *data*</td>
+      <td>Some more</td>
+    </tr>
+  </tbody>
+</table>
+
+<table class="examples">
+  <thead>
+    <tr>
+      <th>Usage</th>
+      <th>Output</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>Some *data*</td>
+      <td>Some more</td>
+    </tr>
+  </tbody>
+  <tfoot>
+    <tr>
+      <td>foot</td>
+      <td>locker</td>
+    </tr>
+  </tfoot>
+</table>
+
+<table class="examples">
+  <tbody>
+    <tr>
+      <td style="text-align: left">Usage</td>
+      <td style="width: 10em">Output</td>
+    </tr>
+    <tr>
+      <td style="text-align: left">Some *data*</td>
+      <td>Some more</td>
+    </tr>
+  </tbody>
+</table>
+
+<table class="examples">
+<tr>
+  <th>Usage</th>
+  <th>
+Output
+  </th>
+</tr>
+<tr>
+  <td>Some *data*</td>
+  <td>
+Some more
+  </td>
+</tr>
+</table>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/table_simple.text b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/table_simple.text
new file mode 100644
index 0000000..ae7852b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/table_simple.text
@@ -0,0 +1,71 @@
+<table class="examples">
+<tr>
+  <td>Usage</td>
+  <td>
+Output
+  </td>
+</tr>
+<tr>
+  <td>Some *data*</td>
+  <td>
+Some more
+  </td>
+</tr>
+</table>
+
+<table class="examples">
+<thead>
+<tr>
+  <th>Usage</th>
+  <th>
+Output
+  </th>
+</tr>
+</thead>
+<tbody>
+<tr>
+  <td>Some *data*</td>
+  <td>
+Some more
+  </td>
+</tr>
+</tbody>
+<tfoot>
+<tr>
+  <td>foot</td>
+  <td>
+locker
+  </td>
+</tr>
+</tfoot>
+</table>
+
+<table class="examples">
+<tr>
+  <td style="text-align: left">Usage</td>
+  <td style="width: 10em">
+Output
+  </td>
+</tr>
+<tr>
+  <td style="text-align: left">Some *data*</td>
+  <td>
+Some more
+  </td>
+</tr>
+</table>
+
+<table class="examples">
+<tr>
+  <th>Usage</th>
+  <th>
+Output
+  </th>
+</tr>
+<tr>
+  <td>Some *data*</td>
+  <td>
+Some more
+  </td>
+</tr>
+</table>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/typography.html b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/typography.html
new file mode 100644
index 0000000..2f865aa
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/typography.html
@@ -0,0 +1 @@
+<p>This is … something “to remember”!</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/typography.html.19 b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/typography.html.19
new file mode 100644
index 0000000..2443965
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/typography.html.19
@@ -0,0 +1 @@
+<p>This is … something “to remember”!</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/typography.text b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/typography.text
new file mode 100644
index 0000000..ee33c5c
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/html_to_native/typography.text
@@ -0,0 +1 @@
+<p>This is … something “to remember”!</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/invalid_html_1.html b/app/server/vendor/kramdown/test/testcases/block/09_html/invalid_html_1.html
new file mode 100644
index 0000000..77e0d78
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/invalid_html_1.html
@@ -0,0 +1,5 @@
+<p>para</p>
+
+<p></div></p>
+
+<p>para</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/invalid_html_1.text b/app/server/vendor/kramdown/test/testcases/block/09_html/invalid_html_1.text
new file mode 100644
index 0000000..f2fc834
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/invalid_html_1.text
@@ -0,0 +1,5 @@
+para
+
+</div>
+
+para
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/invalid_html_2.html b/app/server/vendor/kramdown/test/testcases/block/09_html/invalid_html_2.html
new file mode 100644
index 0000000..b5da12f
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/invalid_html_2.html
@@ -0,0 +1,5 @@
+<p>para</p>
+
+<hr />
+
+<p>para</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/invalid_html_2.text b/app/server/vendor/kramdown/test/testcases/block/09_html/invalid_html_2.text
new file mode 100644
index 0000000..675c94f
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/invalid_html_2.text
@@ -0,0 +1,5 @@
+para
+
+<hr>
+
+para
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/markdown_attr.html b/app/server/vendor/kramdown/test/testcases/block/09_html/markdown_attr.html
new file mode 100644
index 0000000..930b8f4
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/markdown_attr.html
@@ -0,0 +1,38 @@
+<div>
+  <p><em>para</em></p>
+</div>
+
+<div>
+<em>para</em>
+</div>
+
+<div>
+  <p><em>para</em></p>
+</div>
+
+<div>
+*para*
+</div>
+
+<p>
+  <p><em>para</em></p>
+</p>
+
+<p>
+<em>para</em>
+</p>
+
+<p>
+<em>para</em>
+</p>
+
+<p>
+*para*
+</p>
+
+<dl>
+  <dt><em>emphasize</em></dt>
+  <dd>
+    <p>para</p>
+  </dd>
+</dl>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/markdown_attr.text b/app/server/vendor/kramdown/test/testcases/block/09_html/markdown_attr.text
new file mode 100644
index 0000000..12e5aee
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/markdown_attr.text
@@ -0,0 +1,38 @@
+<div markdown="block">
+*para*
+</div>
+
+<div markdown="span">
+*para*
+</div>
+
+<div markdown="1">
+*para*
+</div>
+
+<div markdown="0">
+*para*
+</div>
+
+<p markdown="block">
+*para*
+</p>
+
+<p markdown="span">
+*para*
+</p>
+
+<p markdown="1">
+*para*
+</p>
+
+<p markdown="0">
+*para*
+</p>
+
+<dl>
+  <dt markdown="1">*emphasize*</dt>
+  <dd markdown="1">
+para
+</dd>
+</dl>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/not_parsed.html b/app/server/vendor/kramdown/test/testcases/block/09_html/not_parsed.html
new file mode 100644
index 0000000..0dda33d
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/not_parsed.html
@@ -0,0 +1,24 @@
+<div>
+This is some text
+</div>
+
+<div><div>
+This is some text
+</div></div>
+
+<div>
+
+</div>
+
+<div>
+<p><a href="/">Foo</a></p>
+</div>
+
+<p>This is some
+text</p>
+
+<p><a href="http://example.com">http://example.com</a></p>
+
+<div>
+<http://example.com>
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/not_parsed.text b/app/server/vendor/kramdown/test/testcases/block/09_html/not_parsed.text
new file mode 100644
index 0000000..1d1c71c
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/not_parsed.text
@@ -0,0 +1,24 @@
+<div>
+This is some text
+</div>
+
+<div><div>
+This is some text
+</div></div>
+
+<div>
+</p>
+</div>
+
+<div>
+<p><a href="/">Foo</a></p>
+</div>
+
+<p>This is some
+text</p>
+
+<http://example.com>
+
+<div>
+<http://example.com>
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_raw.html b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_raw.html
new file mode 100644
index 0000000..860f9b2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_raw.html
@@ -0,0 +1,35 @@
+<p>baz { |qux| quux }</p>
+
+<p>This is some para.
+<script type="javascript">
+This *text* must not be converted.
+  </script></p>
+
+<script>Not *parsed* here</script>
+
+<script>*not*</script>
+<p><em>parsed</em>
+This too
+</p>
+
+<script>*not*<p>*parsed*
+This too
+</p></script>
+
+<script>something<p>*not*</p></script>
+
+<script></script>
+
+<script>
+This should be output
+<p> *as* is
+</p> and nothing should be done
+about it
+</not>
+</p>
+</script>
+
+<p><a href="http://example.com">http://example.com</a></p>
+
+<style> body > * { background-color: Red; } </style>
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_raw.htmlinput b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_raw.htmlinput
new file mode 100644
index 0000000..22b9ea5
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_raw.htmlinput
@@ -0,0 +1,34 @@
+<p>baz { |qux| quux }</p>
+
+<p>This is some para.
+<script type="javascript">
+This *text* must not be converted.
+  </SCRIPT></p>
+
+<script>Not *parsed* here</script>
+
+<sCRIpt>*not*</script>
+<p><em>parsed</em>
+This too
+</p>
+
+<script>*not*<p>*parsed*
+This too
+</p></script>
+
+<sCRIpt>something<p>*not*</p></scrIPt>
+
+<script></script>
+
+<script>
+This should be output
+<p> *as* is
+</p> and nothing should be done
+about it
+</not>
+</p>
+</script>
+
+<p><a href="http://example.com">http://example.com</a></p>
+
+<style> body > * { background-color: Red; } </style>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_raw.options b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_raw.options
new file mode 100644
index 0000000..a660da2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_raw.options
@@ -0,0 +1 @@
+:parse_block_html: true
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_raw.text b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_raw.text
new file mode 100644
index 0000000..e0617c4
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_raw.text
@@ -0,0 +1,33 @@
+<p>baz { |qux| quux }</p>
+
+This is some para.
+<script type="javascript">
+This *text* must not be converted.
+  </SCRIPT>
+
+<script>Not *parsed* here</script>
+
+<script>*not*</script><p>*parsed*
+This too
+</p>
+
+<script>*not*<p>*parsed*
+This too
+</p></script>
+
+<script>something<p>*not*</p></script>
+
+<script></script>
+
+<script>
+This should be output
+<p> *as* is
+</p> and nothing should be done
+about it
+</not>
+</p>
+</script>
+
+<http://example.com>
+
+<style> body > * { background-color: Red; } </style>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_span.html b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_span.html
new file mode 100644
index 0000000..2a6191f
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_span.html
@@ -0,0 +1,12 @@
+<p>This <em>text
+should</em> be parsed
+as span
+</p>
+
+<p>This produces `</p>
+<p>` an unwanted result.</p></p>
+
+<p>This <em>text</em> too</p>
+<p>
+some text
+</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_span.htmlinput b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_span.htmlinput
new file mode 100644
index 0000000..4199b8b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_span.htmlinput
@@ -0,0 +1,12 @@
+<P>This <EM>text
+should</em> be parsed
+as span
+</p>
+
+<p>This produces `</p>
+<p>` an unwanted result.</p></p>
+
+<p>This <em>text</EM> too</P>
+<p>
+some text
+</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_span.options b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_span.options
new file mode 100644
index 0000000..a660da2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_span.options
@@ -0,0 +1 @@
+:parse_block_html: true
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_span.text b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_span.text
new file mode 100644
index 0000000..d07cf6d
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_as_span.text
@@ -0,0 +1,9 @@
+<p>This *text
+should* be parsed
+as span
+</P>
+
+<p>This produces `</p>` an unwanted result.</p>
+
+<p>This *text* too</p><p>
+some text
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/parse_block_html.html b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_block_html.html
new file mode 100644
index 0000000..8de78c0
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_block_html.html
@@ -0,0 +1,21 @@
+<div>
+  <p>test</p>
+</div>
+
+<div>
+  <pre><code>test
+</code></pre>
+  <div>
+    <pre><code>test
+</code></pre>
+  </div>
+</div>
+
+<div>
+  <pre><code>code block with </div>
+</code></pre>
+</div>
+
+<div>
+  <p>No matching end tag</p>
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/parse_block_html.options b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_block_html.options
new file mode 100644
index 0000000..a660da2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_block_html.options
@@ -0,0 +1 @@
+:parse_block_html: true
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/parse_block_html.text b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_block_html.text
new file mode 100644
index 0000000..b8b1845
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/parse_block_html.text
@@ -0,0 +1,17 @@
+<DIV>
+  test
+</diV>
+
+<div>
+    test
+  <div>
+    test
+  </div>
+</div>
+
+<div>
+    code block with </div>
+</div>
+
+<div>
+No matching end tag
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/processing_instruction.html b/app/server/vendor/kramdown/test/testcases/block/09_html/processing_instruction.html
new file mode 100644
index 0000000..b292a05
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/processing_instruction.html
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+
+<p>para</p>
+
+<?  test  ?>
+<p>para</p>
+
+<p>other</p>
+
+<?
+multiline *text*
+is allowed
+?>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/processing_instruction.text b/app/server/vendor/kramdown/test/testcases/block/09_html/processing_instruction.text
new file mode 100644
index 0000000..fcb866f
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/processing_instruction.text
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+
+para
+
+<?  test  ?> para
+
+other
+
+<?
+multiline *text*
+is allowed
+?>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/simple.html b/app/server/vendor/kramdown/test/testcases/block/09_html/simple.html
new file mode 100644
index 0000000..edf4161
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/simple.html
@@ -0,0 +1,64 @@
+<div>
+  <p>test</p>
+</div>
+
+<p>
+para2
+</p>
+
+<div id="test">
+  <p>tes</p>
+
+  <p>test
+weiter
+</p>
+</div>
+
+<p>para4</p>
+
+<div>
+  <div>
+    <div>
+      <p>foo</p>
+    </div>
+    <div style=" "></div>
+  </div>
+  <div>
+    <p>bar </p>
+  </div>
+</div>
+
+<p>para5</p>
+
+<div>
+  <p>id</p>
+</div>
+<p>test</p>
+
+<div>
+  <p>hallo</p>
+</div>
+<div>
+  <p>hallo</p>
+</div>
+
+<p>para6</p>
+
+<div>
+  <div class="clear"></div>
+  <p>Another para.</p>
+</div>
+
+<webgen:block name="test" />
+
+<some:url name:spac="hallo">doit</some:url>
+
+<p><em>Test</em></p>
+
+<p><em>Test</em></p>
+
+<p><em>Test
+</em>
+</p>
+
+<iframe></iframe>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/simple.html.19 b/app/server/vendor/kramdown/test/testcases/block/09_html/simple.html.19
new file mode 100644
index 0000000..ac026e5
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/simple.html.19
@@ -0,0 +1,64 @@
+<div>
+  <p>test</p>
+</div>
+
+<p>
+para2
+</p>
+
+<div id="test">
+  <p>tes</p>
+
+  <p>test
+weiter
+</p>
+</div>
+
+<p>para4</p>
+
+<div>
+  <div>
+    <div>
+      <p>foo</p>
+    </div>
+    <div style=" "></div>
+  </div>
+  <div>
+    <p>bar </p>
+  </div>
+</div>
+
+<p>para5</p>
+
+<div>
+  <p>id</p>
+</div>
+<p>test</p>
+
+<div>
+  <p>hallo</p>
+</div>
+<div>
+  <p>hallo</p>
+</div>
+
+<p>para6</p>
+
+<div>
+  <div class="clear"></div>
+  <p>Another para.</p>
+</div>
+
+<webgen:block name="test" />
+
+<some:url name:spac="hallo">doit</some:url>
+
+<p><em>Test</em></p>
+
+<p><em>Test</em></p>
+
+<p><em>Test
+</em>
+</p>
+
+<iframe></iframe>
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/simple.options b/app/server/vendor/kramdown/test/testcases/block/09_html/simple.options
new file mode 100644
index 0000000..a660da2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/simple.options
@@ -0,0 +1 @@
+:parse_block_html: true
diff --git a/app/server/vendor/kramdown/test/testcases/block/09_html/simple.text b/app/server/vendor/kramdown/test/testcases/block/09_html/simple.text
new file mode 100644
index 0000000..17cc689
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/09_html/simple.text
@@ -0,0 +1,59 @@
+  <div>   
+test
+</div>
+
+<p>
+para2
+</p>
+
+<div id='test'>
+  <p>tes</p>
+
+  <p>test
+weiter
+</p>
+</div>
+
+para4
+
+<div>
+<div>
+<div>
+foo
+</div>
+   <div style=" "></div>
+</div>
+<div>bar 
+</div>
+</div>
+
+para5
+
+<div>id
+</div> test
+
+<div>
+hallo
+</div> <div>
+hallo
+</div>
+
+para6
+
+<div><div cLASs="clear"></div>
+Another para.
+</div>
+
+<webgen:block name="test" />
+
+<some:url name:spac='hallo'>doit</some:url>
+
+<em>Test</em>
+
+<p><em>Test</em></p>
+
+<p><em>Test
+</em>
+</p>
+
+<iframe></iframe>
diff --git a/app/server/vendor/kramdown/test/testcases/block/10_ald/simple.html b/app/server/vendor/kramdown/test/testcases/block/10_ald/simple.html
new file mode 100644
index 0000000..74b03d5
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/10_ald/simple.html
@@ -0,0 +1,2 @@
+<p>Some paragraph</p>
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/10_ald/simple.text b/app/server/vendor/kramdown/test/testcases/block/10_ald/simple.text
new file mode 100644
index 0000000..f58768a
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/10_ald/simple.text
@@ -0,0 +1,8 @@
+Some paragraph
+
+{:id: ref1}
+{:id: .class1}
+ {:id: #id}
+  {:id: key="value"}
+   {:id: .class2 .class3 ref2 #id-with key="value" key='value' key='dfsd\}' }
+{:test: k ey=value}
diff --git a/app/server/vendor/kramdown/test/testcases/block/11_ial/auto_id_and_ial.html b/app/server/vendor/kramdown/test/testcases/block/11_ial/auto_id_and_ial.html
new file mode 100644
index 0000000..9857a03
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/11_ial/auto_id_and_ial.html
@@ -0,0 +1 @@
+<h2 id="myid" class="cls">A header</h2>
diff --git a/app/server/vendor/kramdown/test/testcases/block/11_ial/auto_id_and_ial.options b/app/server/vendor/kramdown/test/testcases/block/11_ial/auto_id_and_ial.options
new file mode 100644
index 0000000..8776b55
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/11_ial/auto_id_and_ial.options
@@ -0,0 +1 @@
+:auto_ids: true
diff --git a/app/server/vendor/kramdown/test/testcases/block/11_ial/auto_id_and_ial.text b/app/server/vendor/kramdown/test/testcases/block/11_ial/auto_id_and_ial.text
new file mode 100644
index 0000000..f521fb0
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/11_ial/auto_id_and_ial.text
@@ -0,0 +1,2 @@
+## A header
+{:#myid .cls}
diff --git a/app/server/vendor/kramdown/test/testcases/block/11_ial/nested.html b/app/server/vendor/kramdown/test/testcases/block/11_ial/nested.html
new file mode 100644
index 0000000..84cc368
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/11_ial/nested.html
@@ -0,0 +1,11 @@
+<div class="cls" id="id">
+test
+</div>
+
+<div class="cls" id="id">
+  <p>test</p>
+</div>
+
+<blockquote class="cls" id="id">
+  <p>para</p>
+</blockquote>
diff --git a/app/server/vendor/kramdown/test/testcases/block/11_ial/nested.text b/app/server/vendor/kramdown/test/testcases/block/11_ial/nested.text
new file mode 100644
index 0000000..827645c
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/11_ial/nested.text
@@ -0,0 +1,15 @@
+{:.cls}
+<div>
+test
+</div>
+{:#id}
+
+{:.cls}
+<div markdown="1">
+test
+</div>
+{:#id}
+
+{:.cls}
+> para
+{:#id}
diff --git a/app/server/vendor/kramdown/test/testcases/block/11_ial/simple.html b/app/server/vendor/kramdown/test/testcases/block/11_ial/simple.html
new file mode 100644
index 0000000..c7d19b0
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/11_ial/simple.html
@@ -0,0 +1,27 @@
+<p key1="val"" key2="val'" class="other-class myclass class" id="other" key="val">Some paragraph.</p>
+
+<p class="cls1 cls2" id="id">Some paragraph.</p>
+
+<blockquote id="id" class="class">
+  <p>quote</p>
+</blockquote>
+
+<ul key="val">
+  <li>list</li>
+</ul>
+
+<pre id="other"><code>code block
+</code></pre>
+
+<pre><code>other code block
+</code></pre>
+
+<h2 id="myid">A header</h2>
+
+<p class="cls">Some paragraph here</p>
+
+<p class="cls">Paragraph</p>
+<p>Paragraph</p>
+
+<h1 class="class" id="other">Another header</h1>
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/11_ial/simple.text b/app/server/vendor/kramdown/test/testcases/block/11_ial/simple.text
new file mode 100644
index 0000000..a310e91
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/11_ial/simple.text
@@ -0,0 +1,37 @@
+Some paragraph.
+{:.class id key="val"}
+
+Some paragraph.
+{:.cls1#id.cls2}
+
+> quote
+{: #id}
+  {: .class}
+
+* list
+{: key="val"}
+
+    code block
+{: #other}
+
+    other code block
+
+## A header
+{:#myid}
+
+{:.cls}
+Some paragraph here
+
+Paragraph
+{:.cls}
+Paragraph
+
+Another header
+==============
+{: .class #other}
+
+{:id: #id key="valo"}
+{:id: #other .myclass other}
+{:other: key1="val\""  - ig.nored as_is#this key2='val\'' .other-class}
+
+{:.invalid}
diff --git a/app/server/vendor/kramdown/test/testcases/block/12_extension/comment.html b/app/server/vendor/kramdown/test/testcases/block/12_extension/comment.html
new file mode 100644
index 0000000..20b4c66
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/12_extension/comment.html
@@ -0,0 +1,8 @@
+<p>This is a simple paragraph.</p>
+
+<!-- This is a comment {:/}which is {:/comment} ignored. -->
+
+<p>And another paragraph</p>
+
+<p>{::comment}
+Another paragraph</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/12_extension/comment.text b/app/server/vendor/kramdown/test/testcases/block/12_extension/comment.text
new file mode 100644
index 0000000..2dfc919
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/12_extension/comment.text
@@ -0,0 +1,12 @@
+This is a simple paragraph.
+
+{::comment}
+This is a comment {:/}which is {:/comment} ignored.
+{:/comment}
+
+And another paragraph
+
+{::comment this='is' .ignore /}
+
+{::comment}
+Another paragraph
diff --git a/app/server/vendor/kramdown/test/testcases/block/12_extension/ignored.html b/app/server/vendor/kramdown/test/testcases/block/12_extension/ignored.html
new file mode 100644
index 0000000..17aae5c
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/12_extension/ignored.html
@@ -0,0 +1,8 @@
+<p>paragraph</p>
+
+<p>{::something}
+anotherthing
+{:/something}</p>
+
+<p>{::something/}
+paragraph</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/12_extension/ignored.text b/app/server/vendor/kramdown/test/testcases/block/12_extension/ignored.text
new file mode 100644
index 0000000..ae94a8f
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/12_extension/ignored.text
@@ -0,0 +1,8 @@
+paragraph
+
+{::something}
+anotherthing
+{:/something}
+
+{::something/}
+paragraph
diff --git a/app/server/vendor/kramdown/test/testcases/block/12_extension/nomarkdown.html b/app/server/vendor/kramdown/test/testcases/block/12_extension/nomarkdown.html
new file mode 100644
index 0000000..7fe58d5
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/12_extension/nomarkdown.html
@@ -0,0 +1,10 @@
+<p>This is a simple paragraph.</p>
+
+This *is* not processed 
+
+<p>And another paragraph</p>
+
+<em>bold</em>
+
+<p>{::nomarkdown}
+Another paragraph</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/12_extension/nomarkdown.kramdown b/app/server/vendor/kramdown/test/testcases/block/12_extension/nomarkdown.kramdown
new file mode 100644
index 0000000..2cee512
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/12_extension/nomarkdown.kramdown
@@ -0,0 +1,20 @@
+This is a simple paragraph.
+
+{::nomarkdown}
+This *is* not processed 
+{:/}
+
+And another paragraph
+
+{::nomarkdown type="html"}
+<em>bold</em>
+{:/}
+
+{::nomarkdown type="latex"}
+\begin{itemize}
+\item[Yes] YESSSS!
+\end{itemize}
+{:/}
+
+\{::nomarkdown} Another paragraph
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/12_extension/nomarkdown.latex b/app/server/vendor/kramdown/test/testcases/block/12_extension/nomarkdown.latex
new file mode 100644
index 0000000..5af0263
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/12_extension/nomarkdown.latex
@@ -0,0 +1,13 @@
+This is a simple paragraph.
+
+This *is* not processed 
+
+And another paragraph
+
+\begin{itemize}
+\item[Yes] YESSSS!
+\end{itemize}
+
+\{::nomarkdown\}
+Another paragraph
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/12_extension/nomarkdown.text b/app/server/vendor/kramdown/test/testcases/block/12_extension/nomarkdown.text
new file mode 100644
index 0000000..43d441d
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/12_extension/nomarkdown.text
@@ -0,0 +1,21 @@
+This is a simple paragraph.
+
+{::nomarkdown}  
+This *is* not processed 
+  {:/nomarkdown}
+
+And another paragraph
+
+{::nomarkdown this='is' .ignore /}
+
+{::nomarkdown type='html'}
+<em>bold</em>
+{:/}
+{::nomarkdown type="latex"}
+\begin{itemize}
+\item[Yes] YESSSS!
+\end{itemize}
+{:/}
+
+{::nomarkdown}
+Another paragraph
diff --git a/app/server/vendor/kramdown/test/testcases/block/12_extension/options.html b/app/server/vendor/kramdown/test/testcases/block/12_extension/options.html
new file mode 100644
index 0000000..8a3a47e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/12_extension/options.html
@@ -0,0 +1,21 @@
+<h1>No header id</h1>
+
+<h1>without header id</h1>
+
+<div>
+some <span>*para*</span>
+</div>
+
+<div>
+  <p>some <span><em>para</em></span></p>
+</div>
+
+<p>Some text<sup id="fnref:ab"><a href="#fn:ab" class="footnote">10</a></sup>.</p>
+
+<div class="footnotes">
+  <ol start="10">
+    <li id="fn:ab">
+      <p>Some text. <a href="#fnref:ab" class="reversefootnote">↩</a></p>
+    </li>
+  </ol>
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/block/12_extension/options.text b/app/server/vendor/kramdown/test/testcases/block/12_extension/options.text
new file mode 100644
index 0000000..5991ab7
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/12_extension/options.text
@@ -0,0 +1,21 @@
+# No header id
+
+{::options unusedvar="val" /}
+
+# without header id
+
+<div>
+some <span>*para*</span>
+</div>
+
+{::options parse_block_html="true" parse_span_html="true" /}
+
+<div>
+some <span>*para*</span>
+</div>
+
+{::options footnote_nr="10" /}
+
+Some text[^ab].
+
+[^ab]: Some text.
diff --git a/app/server/vendor/kramdown/test/testcases/block/12_extension/options2.html b/app/server/vendor/kramdown/test/testcases/block/12_extension/options2.html
new file mode 100644
index 0000000..f2ad2ef
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/12_extension/options2.html
@@ -0,0 +1,10 @@
+
+<p>Some text<sup id="fnref:ab"><a href="#fn:ab" class="footnote">1</a></sup>.</p>
+
+<div class="footnotes">
+  <ol>
+    <li id="fn:ab">
+      <p>Some text. <a href="#fnref:ab" class="reversefootnote">↩</a></p>
+    </li>
+  </ol>
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/block/12_extension/options2.text b/app/server/vendor/kramdown/test/testcases/block/12_extension/options2.text
new file mode 100644
index 0000000..78abfbe
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/12_extension/options2.text
@@ -0,0 +1,5 @@
+{::options footnote_nr="da10" /}
+
+Some text[^ab].
+
+[^ab]: Some text.
diff --git a/app/server/vendor/kramdown/test/testcases/block/12_extension/options3.html b/app/server/vendor/kramdown/test/testcases/block/12_extension/options3.html
new file mode 100644
index 0000000..7b646b6
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/12_extension/options3.html
@@ -0,0 +1,7 @@
+<div><span class="CodeRay">x = <span class="constant">Class</span>.new
+</span>
+</div>
+
+<div><span class="CodeRay">x = <span class="constant">Class</span>.new
+</span>
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/block/12_extension/options3.text b/app/server/vendor/kramdown/test/testcases/block/12_extension/options3.text
new file mode 100644
index 0000000..e0ee87c
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/12_extension/options3.text
@@ -0,0 +1,7 @@
+    x = Class.new
+{: .language-ruby}
+
+{::options coderay_wrap="span" coderay_line_numbers="" coderay_css="class" coderay_tab_width="4" /}
+
+    x = Class.new
+{: .language-ruby}
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/definition_at_beginning.html b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/definition_at_beginning.html
new file mode 100644
index 0000000..7c5cc04
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/definition_at_beginning.html
@@ -0,0 +1 @@
+<p>: no definition</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/definition_at_beginning.text b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/definition_at_beginning.text
new file mode 100644
index 0000000..cd3671b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/definition_at_beginning.text
@@ -0,0 +1 @@
+: no definition
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/deflist_ial.html b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/deflist_ial.html
new file mode 100644
index 0000000..3090b1e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/deflist_ial.html
@@ -0,0 +1,4 @@
+<dl class="dl-horizontal dl-other">
+  <dt>item</dt>
+  <dd>definition</dd>
+</dl>
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/deflist_ial.text b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/deflist_ial.text
new file mode 100644
index 0000000..587c3b0
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/deflist_ial.text
@@ -0,0 +1,4 @@
+{:.dl-horizontal}
+item
+:   definition
+{:.dl-other}
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/item_ial.html b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/item_ial.html
new file mode 100644
index 0000000..2bbf1b0
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/item_ial.html
@@ -0,0 +1,12 @@
+<dl>
+  <dt>item</dt>
+  <dd class="cls">definition
+continued</dd>
+  <dd>another {:.cls}</dd>
+  <dd class="class">
+    <pre><code>code
+</code></pre>
+  </dd>
+  <dd class="cls">IAL at last
+    no code bc of text</dd>
+</dl>
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/item_ial.text b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/item_ial.text
new file mode 100644
index 0000000..f75da18
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/item_ial.text
@@ -0,0 +1,8 @@
+item
+:   {:.cls} definition
+    continued
+: another {:.cls}
+: {:.class}
+        code
+: {:.cls} IAL at last
+      no code bc of text
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/multiple_terms.html b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/multiple_terms.html
new file mode 100644
index 0000000..e2e089b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/multiple_terms.html
@@ -0,0 +1,13 @@
+<dl>
+  <dt>kram</dt>
+  <dt><em>down</em></dt>
+  <dt>now</dt>
+  <dd>definition 1</dd>
+  <dd>definition 2</dd>
+  <dd>
+    <p>definition 3</p>
+  </dd>
+  <dd>
+    <p>definition 4</p>
+  </dd>
+</dl>
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/multiple_terms.text b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/multiple_terms.text
new file mode 100644
index 0000000..b834258
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/multiple_terms.text
@@ -0,0 +1,10 @@
+kram
+*down*
+now
+: definition 1
+: definition 2
+
+: definition 3
+
+
+: definition 4
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/no_def_list.html b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/no_def_list.html
new file mode 100644
index 0000000..c16f962
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/no_def_list.html
@@ -0,0 +1,2 @@
+<p>This is a para
+: and not a definition list</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/no_def_list.text b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/no_def_list.text
new file mode 100644
index 0000000..98b52b3
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/no_def_list.text
@@ -0,0 +1,2 @@
+This is a para
+\: and not a definition list
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/para_wrapping.html b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/para_wrapping.html
new file mode 100644
index 0000000..5f28fdf
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/para_wrapping.html
@@ -0,0 +1,10 @@
+<dl>
+  <dt>term</dt>
+  <dd>
+    <p>definition</p>
+  </dd>
+  <dd>definition</dd>
+  <dd>
+    <p>definition</p>
+  </dd>
+</dl>
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/para_wrapping.text b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/para_wrapping.text
new file mode 100644
index 0000000..280fa47
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/para_wrapping.text
@@ -0,0 +1,6 @@
+term
+
+: definition
+: definition
+
+: definition
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/separated_by_eob.html b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/separated_by_eob.html
new file mode 100644
index 0000000..0a1c4dc
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/separated_by_eob.html
@@ -0,0 +1,8 @@
+<dl>
+  <dt>kram</dt>
+  <dd>down</dd>
+</dl>
+<dl>
+  <dt>kram</dt>
+  <dd>down</dd>
+</dl>
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/separated_by_eob.text b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/separated_by_eob.text
new file mode 100644
index 0000000..56fedf1
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/separated_by_eob.text
@@ -0,0 +1,5 @@
+kram
+: down
+^
+kram
+: down
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/simple.html b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/simple.html
new file mode 100644
index 0000000..791f145
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/simple.html
@@ -0,0 +1,10 @@
+<dl>
+  <dt>kram</dt>
+  <dd>down</dd>
+  <dt>novalue</dt>
+  <dd></dd>
+  <dt>kram</dt>
+  <dd>down
+kram</dd>
+  <dd>down</dd>
+</dl>
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/simple.text b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/simple.text
new file mode 100644
index 0000000..e3bf730
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/simple.text
@@ -0,0 +1,10 @@
+kram
+: down
+
+novalue
+: 
+
+kram
+:   down
+kram
+: down
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/styled_terms.html b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/styled_terms.html
new file mode 100644
index 0000000..cf7d785
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/styled_terms.html
@@ -0,0 +1,4 @@
+<dl>
+  <dt><em>kram</em></dt>
+  <dd>down</dd>
+</dl>
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/styled_terms.text b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/styled_terms.text
new file mode 100644
index 0000000..76eb355
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/styled_terms.text
@@ -0,0 +1,2 @@
+*kram*
+: down
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/too_much_space.html b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/too_much_space.html
new file mode 100644
index 0000000..b4df878
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/too_much_space.html
@@ -0,0 +1,3 @@
+<p>para</p>
+
+<p>: no definition</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/too_much_space.text b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/too_much_space.text
new file mode 100644
index 0000000..30ab445
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/too_much_space.text
@@ -0,0 +1,4 @@
+para
+
+
+: no definition
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/with_blocks.html b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/with_blocks.html
new file mode 100644
index 0000000..45b5865
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/with_blocks.html
@@ -0,0 +1,38 @@
+<dl>
+  <dt>kram</dt>
+  <dd>this is some
+text</dd>
+  <dd>
+    <p>this is some
+more text</p>
+  </dd>
+  <dt>kram</dt>
+  <dd>
+    <blockquote>
+      <p>blockquote</p>
+    </blockquote>
+  </dd>
+  <dt>kram</dt>
+  <dd>
+    <pre><code>code
+</code></pre>
+  </dd>
+  <dt>kram</dt>
+  <dd>
+    <dl>
+      <dt>kram</dt>
+      <dd>down</dd>
+    </dl>
+  </dd>
+  <dt>kram</dt>
+  <dd>
+    <h1>header</h1>
+  </dd>
+  <dt>kram</dt>
+  <dd>
+    <ul>
+      <li>list</li>
+      <li>items</li>
+    </ul>
+  </dd>
+</dl>
diff --git a/app/server/vendor/kramdown/test/testcases/block/13_definition_list/with_blocks.text b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/with_blocks.text
new file mode 100644
index 0000000..15195ce
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/13_definition_list/with_blocks.text
@@ -0,0 +1,24 @@
+kram
+: this is some
+  text
+
+ :   this is some
+     more text
+
+kram
+: > blockquote
+
+kram
+: 
+        code
+
+kram
+: kram
+  : down
+
+kram
+: # header
+
+kram
+: * list
+  * items
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/errors.html b/app/server/vendor/kramdown/test/testcases/block/14_table/errors.html
new file mode 100644
index 0000000..70e1fa7
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/errors.html
@@ -0,0 +1,8 @@
+<p>No table body</p>
+
+<p>|-|-|-</p>
+
+<p>|no|table|here|</p>
+
+<p>|no|table|here|
+paragraph</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/errors.text b/app/server/vendor/kramdown/test/testcases/block/14_table/errors.text
new file mode 100644
index 0000000..a13107b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/errors.text
@@ -0,0 +1,9 @@
+No table body
+
+|-|-|-
+
+[5]: test
+|no|table|here|
+
+|no|table|here|
+paragraph
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/escaping.html b/app/server/vendor/kramdown/test/testcases/block/14_table/escaping.html
new file mode 100644
index 0000000..b4528a1
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/escaping.html
@@ -0,0 +1,52 @@
+<p><code>cell 1 | cell 2</code></p>
+
+<p>cell 1 | cell 2</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>cell 1</td>
+      <td>cell 2 | continued</td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+      <td>cell 1</td>
+      <td>cell <code>2</code></td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+      <td>cell 1</td>
+      <td><code>code | span</code></td>
+    </tr>
+  </tbody>
+</table>
+
+<p>cell 1 <code>code | span</code></p>
+
+<p>cell 1 | <code>code | span</code></p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>cell 1</td>
+      <td>cell `2</td>
+      <td>cell 3</td>
+    </tr>
+    <tr>
+      <td>cell 1`</td>
+      <td>cell 2</td>
+      <td>cell 3</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>cell 1 | cell <code>2 | cell 3
+cell 1</code> | cell 2 | cell 3</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/escaping.text b/app/server/vendor/kramdown/test/testcases/block/14_table/escaping.text
new file mode 100644
index 0000000..a8a24d6
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/escaping.text
@@ -0,0 +1,19 @@
+`cell 1 | cell 2`
+
+cell 1 \| cell 2
+
+cell 1 | cell 2 \| continued
+
+cell 1 | cell `2`
+
+cell 1 | `code | span`
+
+cell 1 `code | span`
+
+cell 1 \| `code | span`
+
+cell 1 | cell `2 | cell 3
+cell 1` | cell 2 | cell 3
+
+cell 1 \| cell `2 | cell 3
+cell 1` | cell 2 | cell 3
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/footer.html b/app/server/vendor/kramdown/test/testcases/block/14_table/footer.html
new file mode 100644
index 0000000..e6596ed
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/footer.html
@@ -0,0 +1,65 @@
+<p>Simple footer</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>cell1</td>
+      <td>cell2</td>
+    </tr>
+  </tbody>
+  <tfoot>
+    <tr>
+      <td>cell3</td>
+      <td>cell4</td>
+    </tr>
+  </tfoot>
+</table>
+
+<p>Full footer</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>cell1</td>
+      <td>cell2</td>
+    </tr>
+  </tbody>
+  <tfoot>
+    <tr>
+      <td>cell3</td>
+      <td>cell4</td>
+    </tr>
+  </tfoot>
+</table>
+
+<p>Footer with separator lines</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>cell1</td>
+      <td>cell2</td>
+    </tr>
+  </tbody>
+  <tfoot>
+    <tr>
+      <td>cell3</td>
+      <td>cell4</td>
+    </tr>
+    <tr>
+      <td>cell5</td>
+      <td>cell6</td>
+    </tr>
+  </tfoot>
+</table>
+
+<p>Empty footer</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>cell1</td>
+      <td>cell2</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/footer.text b/app/server/vendor/kramdown/test/testcases/block/14_table/footer.text
new file mode 100644
index 0000000..faaed8d
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/footer.text
@@ -0,0 +1,25 @@
+Simple footer
+
+| cell1 | cell2
+|=
+| cell3 | cell4
+
+Full footer
+
+| cell1 | cell2
+|=======|=======|
+| cell3 | cell4
+
+Footer with separator lines
+
+| cell1 | cell2
+|=======|=======|
+| cell3 | cell4
+|---
+| cell5 | cell6
+|---
+
+Empty footer
+
+| cell1 | cell2
+|=
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/header.html b/app/server/vendor/kramdown/test/testcases/block/14_table/header.html
new file mode 100644
index 0000000..cc7c6e6
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/header.html
@@ -0,0 +1,96 @@
+<p>Simple header</p>
+
+<table>
+  <thead>
+    <tr>
+      <th>cell1</th>
+      <th>cell2</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>cell3</td>
+      <td>cell4</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>Full header</p>
+
+<table>
+  <thead>
+    <tr>
+      <th>cell1</th>
+      <th>cell2</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>cell3</td>
+      <td>cell4</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>With alignment and superfluous alignment defs</p>
+
+<table>
+  <thead>
+    <tr>
+      <th>default</th>
+      <th style="text-align: left">left</th>
+      <th style="text-align: center">center</th>
+      <th style="text-align: right">right</th>
+      <th>default</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>cell1</td>
+      <td style="text-align: left">cell2</td>
+      <td style="text-align: center">cell3</td>
+      <td style="text-align: right">cell4</td>
+      <td>cell5</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>With leading sep line</p>
+
+<table>
+  <thead>
+    <tr>
+      <th>cell1</th>
+      <th>cell2</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>cell3</td>
+      <td>cell4</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>Multiple bodies</p>
+
+<table>
+  <thead>
+    <tr>
+      <th style="text-align: center">cell1</th>
+      <th>cell2</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td style="text-align: center">cell3</td>
+      <td>cell4</td>
+    </tr>
+  </tbody>
+  <tbody>
+    <tr>
+      <td style="text-align: center">cell5</td>
+      <td>cell6</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/header.text b/app/server/vendor/kramdown/test/testcases/block/14_table/header.text
new file mode 100644
index 0000000..a42827b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/header.text
@@ -0,0 +1,32 @@
+Simple header
+
+| cell1 | cell2
+|-----
+| cell3 | cell4
+
+Full header
+
+| cell1 | cell2
+|-------|-------|
+| cell3 | cell4
+
+With alignment and superfluous alignment defs
+
+| default | left | center | right | default
+|-| :- |:-: | -: | - | :-: | :-
+| cell1 | cell2 | cell3 | cell4 | cell5
+
+With leading sep line
+
+|:-:|-:|
+| cell1 | cell2
+|-------|-------|
+| cell3 | cell4
+
+Multiple bodies
+
+| cell1 | cell2
++ :-: |
+| cell3 | cell4
+|----|||
+| cell5 | cell6
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/no_table.html b/app/server/vendor/kramdown/test/testcases/block/14_table/no_table.html
new file mode 100644
index 0000000..dce46b1
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/no_table.html
@@ -0,0 +1,3 @@
+<p>No table</p>
+
+<p>| Some | thing | here</p>
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/no_table.text b/app/server/vendor/kramdown/test/testcases/block/14_table/no_table.text
new file mode 100644
index 0000000..90f90b3
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/no_table.text
@@ -0,0 +1,3 @@
+No table
+
+\| Some \| thing \| here
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/simple.html b/app/server/vendor/kramdown/test/testcases/block/14_table/simple.html
new file mode 100644
index 0000000..186b1a1
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/simple.html
@@ -0,0 +1,177 @@
+<table>
+  <tbody>
+    <tr>
+      <td>cell1</td>
+      <td>cell2</td>
+    </tr>
+    <tr>
+      <td>cell3</td>
+      <td>cell4</td>
+    </tr>
+    <tr>
+      <td>cell5</td>
+      <td>cell6 |</td>
+    </tr>
+    <tr>
+      <td>cell7</td>
+      <td>cell8</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>Missing cells at end</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>cell1</td>
+      <td>cell2</td>
+      <td>cell3</td>
+    </tr>
+    <tr>
+      <td>cell1</td>
+      <td> </td>
+      <td> </td>
+    </tr>
+    <tr>
+      <td> </td>
+      <td>cell2</td>
+      <td>cell3</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>Escaped pipe characters</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>cell1 | cell1</td>
+      <td>cell2</td>
+    </tr>
+    <tr>
+      <td>cell1</td>
+      <td>cell2 |</td>
+    </tr>
+    <tr>
+      <td>cell1 <code>|</code> con</td>
+      <td>cell2</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>Table with code elements</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>This is a <code>span | with</code> a pipe.</td>
+      <td> </td>
+      <td> </td>
+      <td> </td>
+    </tr>
+    <tr>
+      <td>Some <em>span</em></td>
+      <td></em> here</td>
+      <td>a <code>span | with</code> a</td>
+      <td>pipe.</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>Special cases regarding codespan syntax</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>a</td>
+      <td><code>b</code></td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+      <td><code>a</code></td>
+    </tr>
+  </tbody>
+</table>
+
+<table class="cls">
+  <tbody>
+    <tr>
+      <td>table</td>
+      <td>with</td>
+      <td>ial</td>
+    </tr>
+  </tbody>
+</table>
+
+<table class="cls">
+  <tbody>
+    <tr>
+      <td>table</td>
+      <td>with</td>
+      <td>ial</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>not starting with a bar</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>simple</td>
+      <td>table</td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <thead>
+    <tr>
+      <th>head1</th>
+      <th>head2</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>cell1</td>
+      <td>cell2</td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <thead>
+    <tr>
+      <th>head1</th>
+      <th>head2</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td> </td>
+      <td>cell2</td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+      <td>a</td>
+      <td>b</td>
+    </tr>
+    <tr>
+      <td>c</td>
+      <td>d</td>
+    </tr>
+    <tr>
+      <td>e</td>
+      <td>f</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/simple.html.19 b/app/server/vendor/kramdown/test/testcases/block/14_table/simple.html.19
new file mode 100644
index 0000000..db7c892
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/simple.html.19
@@ -0,0 +1,177 @@
+<table>
+  <tbody>
+    <tr>
+      <td>cell1</td>
+      <td>cell2</td>
+    </tr>
+    <tr>
+      <td>cell3</td>
+      <td>cell4</td>
+    </tr>
+    <tr>
+      <td>cell5</td>
+      <td>cell6 |</td>
+    </tr>
+    <tr>
+      <td>cell7</td>
+      <td>cell8</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>Missing cells at end</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>cell1</td>
+      <td>cell2</td>
+      <td>cell3</td>
+    </tr>
+    <tr>
+      <td>cell1</td>
+      <td> </td>
+      <td> </td>
+    </tr>
+    <tr>
+      <td> </td>
+      <td>cell2</td>
+      <td>cell3</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>Escaped pipe characters</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>cell1 | cell1</td>
+      <td>cell2</td>
+    </tr>
+    <tr>
+      <td>cell1</td>
+      <td>cell2 |</td>
+    </tr>
+    <tr>
+      <td>cell1 <code>|</code> con</td>
+      <td>cell2</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>Table with code elements</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>This is a <code>span | with</code> a pipe.</td>
+      <td> </td>
+      <td> </td>
+      <td> </td>
+    </tr>
+    <tr>
+      <td>Some <em>span</em></td>
+      <td></em> here</td>
+      <td>a <code>span | with</code> a</td>
+      <td>pipe.</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>Special cases regarding codespan syntax</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>a</td>
+      <td><code>b</code></td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+      <td><code>a</code></td>
+    </tr>
+  </tbody>
+</table>
+
+<table class="cls">
+  <tbody>
+    <tr>
+      <td>table</td>
+      <td>with</td>
+      <td>ial</td>
+    </tr>
+  </tbody>
+</table>
+
+<table class="cls">
+  <tbody>
+    <tr>
+      <td>table</td>
+      <td>with</td>
+      <td>ial</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>not starting with a bar</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>simple</td>
+      <td>table</td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <thead>
+    <tr>
+      <th>head1</th>
+      <th>head2</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>cell1</td>
+      <td>cell2</td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <thead>
+    <tr>
+      <th>head1</th>
+      <th>head2</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td> </td>
+      <td>cell2</td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+      <td>a</td>
+      <td>b</td>
+    </tr>
+    <tr>
+      <td>c</td>
+      <td>d</td>
+    </tr>
+    <tr>
+      <td>e</td>
+      <td>f</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/simple.text b/app/server/vendor/kramdown/test/testcases/block/14_table/simple.text
new file mode 100644
index 0000000..2c176e8
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/simple.text
@@ -0,0 +1,49 @@
+| cell1 | cell2 |
+|cell3 | cell4|
+|cell5|cell6 \|	
+| cell7|cell8   
+
+Missing cells at end
+
+| cell1 | cell2 | cell3 |
+| cell1 ||
+|| cell2 | cell3
+
+Escaped pipe characters
+
+| cell1 \| cell1 | cell2 |
+| cell1          | cell2 \|
+| cell1 `|` con | cell2
+
+Table with code elements
+
+| This is a <code>span | with</code> a pipe.
+| Some <em>span | </em> here | a <code>span | with</code> a | pipe.
+
+Special cases regarding codespan syntax
+
+|a|`b`
+
+|`a`
+
+{:.cls}
+| table | with | ial
+
+| table | with | ial
+{:.cls}
+
+not starting with a bar
+
+simple | table
+
+head1 | head2
+------|------
+cell1 | cell2
+
+ head1 | head2
+-------|------
+       | cell2
+
+| a | b |
+  c | d
+| e | f |
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/table_with_footnote.html b/app/server/vendor/kramdown/test/testcases/block/14_table/table_with_footnote.html
new file mode 100644
index 0000000..0bf6781
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/table_with_footnote.html
@@ -0,0 +1,25 @@
+<table>
+  <tbody>
+    <tr>
+      <td>this is <sup id="fnref:1"><a href="#fn:1" class="footnote">1</a></sup></td>
+      <td>a table</td>
+    </tr>
+    <tr>
+      <td>with a</td>
+      <td>footnote</td>
+    </tr>
+  </tbody>
+</table>
+
+<div class="footnotes">
+  <ol>
+    <li id="fn:1">
+      <p>Something</p>
+
+      <blockquote>
+        <p>special here</p>
+      </blockquote>
+      <p><a href="#fnref:1" class="reversefootnote">↩</a></p>
+    </li>
+  </ol>
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/table_with_footnote.latex b/app/server/vendor/kramdown/test/testcases/block/14_table/table_with_footnote.latex
new file mode 100644
index 0000000..99b5312
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/table_with_footnote.latex
@@ -0,0 +1,11 @@
+\begin{longtable}{|l|l|}
+\hline
+this is \footnote{Something
+
+\begin{quote}
+special here
+\end{quote}} & a table\\
+with a & footnote\\
+\hline
+\end{longtable}
+
diff --git a/app/server/vendor/kramdown/test/testcases/block/14_table/table_with_footnote.text b/app/server/vendor/kramdown/test/testcases/block/14_table/table_with_footnote.text
new file mode 100644
index 0000000..345fc5d
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/14_table/table_with_footnote.text
@@ -0,0 +1,6 @@
+| this is [^1] | a table
+| with a | footnote
+
+[^1]: Something
+
+    > special here
diff --git a/app/server/vendor/kramdown/test/testcases/block/15_math/gh_128.html b/app/server/vendor/kramdown/test/testcases/block/15_math/gh_128.html
new file mode 100644
index 0000000..ecc0a6e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/15_math/gh_128.html
@@ -0,0 +1,2 @@
+<script type="math/tex; mode=display">% <![CDATA[
+ alert('a') alert('b<')  %]]></script>
diff --git a/app/server/vendor/kramdown/test/testcases/block/15_math/gh_128.text b/app/server/vendor/kramdown/test/testcases/block/15_math/gh_128.text
new file mode 100644
index 0000000..95252a7
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/15_math/gh_128.text
@@ -0,0 +1 @@
+$$ <script>alert('a')</script> <script>alert('b<')</script> $$
diff --git a/app/server/vendor/kramdown/test/testcases/block/15_math/normal.html b/app/server/vendor/kramdown/test/testcases/block/15_math/normal.html
new file mode 100644
index 0000000..0abbcba
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/15_math/normal.html
@@ -0,0 +1,29 @@
+<p>This is a para.
+<script type="math/tex"> \text{LaTeX} \lambda_5 </script></p>
+
+<script type="math/tex; mode=display">\lambda_5 = \alpha + 4</script>
+
+<p><script type="math/tex">\lambda_\alpha > 5</script>
+This is a para.</p>
+
+<script type="math/tex; mode=display">% <![CDATA[
+\begin{align*}
+&=5 \\
+&=6 \\
+\end{align*} %]]></script>
+
+<script type="math/tex; mode=display">5+5</script>
+
+<script type="math/tex; mode=display">5+5</script>
+
+<script type="math/tex; mode=display">5+5</script>
+
+<script type="math/tex; mode=display">5+5</script>
+
+<pre><code>$$5+5$$
+</code></pre>
+
+<script type="math/tex; mode=display">5+5</script>
+<script type="math/tex; mode=display">5+5</script>
+
+<script type="math/tex; mode=display">|x| = 5</script>
diff --git a/app/server/vendor/kramdown/test/testcases/block/15_math/normal.text b/app/server/vendor/kramdown/test/testcases/block/15_math/normal.text
new file mode 100644
index 0000000..aa5984a
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/15_math/normal.text
@@ -0,0 +1,30 @@
+This is a para.
+$$ \text{LaTeX} \lambda_5 $$
+
+$$\lambda_5 = \alpha + 4$$
+
+$$\lambda_\alpha > 5$$
+This is a para.
+
+$$\begin{align*}
+&=5 \\
+&=6 \\
+\end{align*}$$
+
+$$5+5$$ 
+
+ $$5+5$$	
+
+  $$5+5$$
+
+   $$5+5$$
+
+    $$5+5$$
+
+{:.cls}
+$$5+5$$
+^
+$$5+5$$
+{:.cls}
+
+$$|x| = 5$$
diff --git a/app/server/vendor/kramdown/test/testcases/block/16_toc/no_toc.html b/app/server/vendor/kramdown/test/testcases/block/16_toc/no_toc.html
new file mode 100644
index 0000000..bbb831e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/16_toc/no_toc.html
@@ -0,0 +1,14 @@
+
+<h1>Header level 1</h1>
+
+<h2>Header level 2</h2>
+
+<h3>Header level 3</h3>
+
+<h4>Header level 4</h4>
+
+<h1>Other header level 1</h1>
+
+<h2>Other header level 2</h2>
+
+<h3>Other header level 3</h3>
diff --git a/app/server/vendor/kramdown/test/testcases/block/16_toc/no_toc.text b/app/server/vendor/kramdown/test/testcases/block/16_toc/no_toc.text
new file mode 100644
index 0000000..11ad829
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/16_toc/no_toc.text
@@ -0,0 +1,16 @@
+* Here comes the table of content
+{:toc}
+
+# Header level 1
+
+## Header level 2
+
+### Header level 3
+
+#### Header level 4
+
+# Other header level 1
+
+## Other header level 2
+
+### Other header level 3
diff --git a/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_exclude.html b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_exclude.html
new file mode 100644
index 0000000..b8b61ce
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_exclude.html
@@ -0,0 +1,35 @@
+<h1 class="no_toc" id="contents">Contents</h1>
+
+<ul id="markdown-toc">
+  <li><a href="#header-level-1">Header level 1</a>    <ul>
+      <li><a href="#header-level-2">Header level 2</a>        <ul>
+          <li><a href="#header-level-3">Header level 3</a>            <ul>
+              <li><a href="#header-level-4">Header level 4</a></li>
+            </ul>
+          </li>
+        </ul>
+      </li>
+    </ul>
+  </li>
+  <li><a href="#other-header-level-1">Other header level 1</a>    <ul>
+      <li><a href="#other-header-level-2">Other header level 2</a>        <ul>
+          <li><a href="#other-header-level-3">Other header level 3</a></li>
+        </ul>
+      </li>
+    </ul>
+  </li>
+</ul>
+
+<h1 id="header-level-1">Header level 1</h1>
+
+<h2 id="header-level-2">Header level 2</h2>
+
+<h3 id="header-level-3">Header level 3</h3>
+
+<h4 id="header-level-4">Header level 4</h4>
+
+<h1 id="other-header-level-1">Other header level 1</h1>
+
+<h2 id="other-header-level-2">Other header level 2</h2>
+
+<h3 id="other-header-level-3">Other header level 3</h3>
diff --git a/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_exclude.options b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_exclude.options
new file mode 100644
index 0000000..8776b55
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_exclude.options
@@ -0,0 +1 @@
+:auto_ids: true
diff --git a/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_exclude.text b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_exclude.text
new file mode 100644
index 0000000..d8f0b86
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_exclude.text
@@ -0,0 +1,19 @@
+# Contents
+{:.no_toc}
+
+* Here comes the table of content
+{:toc}
+
+# Header level 1
+
+## Header level 2
+
+### Header level 3
+
+#### Header level 4
+
+# Other header level 1
+
+## Other header level 2
+
+### Other header level 3
diff --git a/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_levels.html b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_levels.html
new file mode 100644
index 0000000..7891e1d
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_levels.html
@@ -0,0 +1,24 @@
+<ul id="markdown-toc">
+  <li><a href="#header-level-2">Header level 2</a>    <ul>
+      <li><a href="#header-level-3">Header level 3</a></li>
+    </ul>
+  </li>
+  <li><a href="#other-header-level-2">Other header level 2</a>    <ul>
+      <li><a href="#other-header-level-3">Other header level 3</a></li>
+    </ul>
+  </li>
+</ul>
+
+<h1 id="header-level-1">Header level 1</h1>
+
+<h2 id="header-level-2">Header level 2</h2>
+
+<h3 id="header-level-3">Header level 3</h3>
+
+<h4 id="header-level-4">Header level 4</h4>
+
+<h1 id="other-header-level-1">Other header level 1</h1>
+
+<h2 id="other-header-level-2">Other header level 2</h2>
+
+<h3 id="other-header-level-3">Other header level 3</h3>
diff --git a/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_levels.options b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_levels.options
new file mode 100644
index 0000000..bdfbeba
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_levels.options
@@ -0,0 +1,2 @@
+:toc_levels: 2..3
+:auto_ids: true
diff --git a/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_levels.text b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_levels.text
new file mode 100644
index 0000000..11ad829
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_levels.text
@@ -0,0 +1,16 @@
+* Here comes the table of content
+{:toc}
+
+# Header level 1
+
+## Header level 2
+
+### Header level 3
+
+#### Header level 4
+
+# Other header level 1
+
+## Other header level 2
+
+### Other header level 3
diff --git a/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_with_footnotes.html b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_with_footnotes.html
new file mode 100644
index 0000000..542482f
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_with_footnotes.html
@@ -0,0 +1,13 @@
+<ul id="markdown-toc">
+  <li><a href="#header1-level-1">Header level 1</a></li>
+</ul>
+
+<h1 id="header1-level-1">Header<sup id="fnref:1"><a href="#fn:1" class="footnote">1</a></sup> level 1</h1>
+
+<div class="footnotes">
+  <ol>
+    <li id="fn:1">
+      <p>Some footnote content here <a href="#fnref:1" class="reversefootnote">↩</a></p>
+    </li>
+  </ol>
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_with_footnotes.options b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_with_footnotes.options
new file mode 100644
index 0000000..8776b55
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_with_footnotes.options
@@ -0,0 +1 @@
+:auto_ids: true
diff --git a/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_with_footnotes.text b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_with_footnotes.text
new file mode 100644
index 0000000..5879ed5
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/block/16_toc/toc_with_footnotes.text
@@ -0,0 +1,6 @@
+* Here comes the table of content
+{:toc}
+
+# Header[^1] level 1
+
+[^1]: Some footnote content here
diff --git a/app/server/vendor/kramdown/test/testcases/encoding.html b/app/server/vendor/kramdown/test/testcases/encoding.html
new file mode 100644
index 0000000..0339347
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/encoding.html
@@ -0,0 +1,46 @@
+<p>Das ist gewöhnlich <em>ein</em> <a href="http://example.org">Über-Problem</a> mit manchen<br />
+Sälen <a href="http://example.org">http://example.org</a> und <span id="test">anderen Dinge</span>. Siehe
+<img src="http://example.org" alt="Ãœber mich" />!</p>
+
+<blockquote class="test">
+  <p>Vielleicht <em class="red">höre</em> ich nicht richtig?</p>
+</blockquote>
+
+<ul>
+  <li>Sollten wir uns das überl<em>egen</em>? <em>Verhöhne</em> mich nicht!</li>
+  <li>Ho ho höher! Sind *wir* da?</li>
+</ul>
+
+<h1>Titel sind urschön</h1>
+
+<h2 id="hot">Manche mögens <em>ärmer</em></h2>
+
+<pre><code>öha
+was nun?
+</code></pre>
+
+<dl>
+  <dt>Töne</dt>
+  <dd>Laute Geräusche</dd>
+  <dd>vielleicht noch was ä<em>hnliches</em></dd>
+</dl>
+
+<table>
+  <thead>
+    <tr>
+      <th>hoch</th>
+      <th>höher</th>
+      <th>am höchsten</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>über</td>
+      <td>drüber</td>
+      <td>müde</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>Das ist schön
+gemacht</p>
diff --git a/app/server/vendor/kramdown/test/testcases/encoding.text b/app/server/vendor/kramdown/test/testcases/encoding.text
new file mode 100644
index 0000000..65edf4b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/encoding.text
@@ -0,0 +1,28 @@
+Das ist gewöhnlich *ein* [Über-Problem](http://example.org) mit manchen  
+Sälen <http://example.org> und <span id='test'>anderen Dinge</span>. Siehe
+![Ãœber mich](http://example.org)!
+
+> Vielleicht *höre*{:.red} ich nicht richtig?
+{:.test}
+
+* Sollten wir uns das überl*egen*? *Verhöhne* mich nicht!
+* Ho ho höher! Sind \*wir\* da?
+
+Titel sind urschön
+==================
+
+## Manche mögens *ärmer*   {#hot}
+
+    öha
+    was nun?
+
+Töne
+: Laute Geräusche
+: vielleicht noch was ä*hnliches*
+
+| hoch | höher | am höchsten |
+|----------------------------|
+| über | drüber | müde       |
+
+<p markdown='1'>Das ist schön
+gemacht</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/empty.html b/app/server/vendor/kramdown/test/testcases/span/01_link/empty.html
new file mode 100644
index 0000000..56bac53
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/empty.html
@@ -0,0 +1,5 @@
+<p>This is [] empty.</p>
+
+<p>This is [][] empty.</p>
+
+<p>This is [](test.html) empty.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/empty.text b/app/server/vendor/kramdown/test/testcases/span/01_link/empty.text
new file mode 100644
index 0000000..cca5de5
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/empty.text
@@ -0,0 +1,5 @@
+This is [] empty.
+
+This is [][] empty.
+
+This is [](test.html) empty.
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/image_in_a.html b/app/server/vendor/kramdown/test/testcases/span/01_link/image_in_a.html
new file mode 100644
index 0000000..e1f4ade
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/image_in_a.html
@@ -0,0 +1,5 @@
+<p>Simple: <a href="local.html">Some <img src="/images/other.png" alt="alt text" /></a></p>
+
+<p>Nested: <a href="local.html">Some <img src="/images/other.png" alt="alt ![img](text.png) text" /></a></p>
+
+<p>Simple: <a href="local.html">Some <em>text <img src="/images/other.png" alt="alt text" /> text</em></a></p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/image_in_a.text b/app/server/vendor/kramdown/test/testcases/span/01_link/image_in_a.text
new file mode 100644
index 0000000..bdbfb65
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/image_in_a.text
@@ -0,0 +1,5 @@
+Simple: [Some ![alt text](/images/other.png)](local.html)
+
+Nested: [Some ![alt ![img](text.png) text](/images/other.png)](local.html)
+
+Simple: [Some *text ![alt text](/images/other.png) text*](local.html)
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/imagelinks.html b/app/server/vendor/kramdown/test/testcases/span/01_link/imagelinks.html
new file mode 100644
index 0000000..565d36f
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/imagelinks.html
@@ -0,0 +1,15 @@
+<p>Simple: <img src="/images/other.png" alt="alt text" /></p>
+
+<p>Simple with title: <img src="/images/other.png" alt="alt text" title="title" /></p>
+
+<p>Empty img link: <img src="" alt="alt text" /></p>
+
+<p>Reference style: <img src="other.png" alt="alt text" /></p>
+
+<p>Reference style with title: <img src="other.png" alt="alt text" title="Title" /></p>
+
+<p>No alt text: <img src="other.png" alt="" /></p>
+
+<p>No id: <img src="other.png" alt="imgo" title="Title" /></p>
+
+<p>With escaped pipe: <img src="other.png" alt="an | pipe" /></p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/imagelinks.text b/app/server/vendor/kramdown/test/testcases/span/01_link/imagelinks.text
new file mode 100644
index 0000000..05050a2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/imagelinks.text
@@ -0,0 +1,18 @@
+Simple: ![alt text](/images/other.png)
+
+Simple with title: ![alt text](/images/other.png "title")
+
+Empty img link: ![alt text]()
+
+Reference style: ![alt text][img]
+
+Reference style with title: ![alt text][imgo]
+
+No alt text: ![](other.png)
+
+No id: ![imgo]
+
+[img]: other.png
+[imgo]: other.png "Title"
+
+With escaped pipe: ![an \| pipe](other.png)
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/inline.html b/app/server/vendor/kramdown/test/testcases/span/01_link/inline.html
new file mode 100644
index 0000000..0810bc7
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/inline.html
@@ -0,0 +1,46 @@
+<p>simple <a href="">URL</a></p>
+
+<p>simple <a href="something.html">URL</a></p>
+
+<p>simple <a href="something.html">URL <em>with</em> formatting</a></p>
+
+<p>simple <a href="something.html" title="a t"itle">URL with single quoted title</a></p>
+
+<p>simple <a href="something.html" title="a t'itle">URL with double quoted title</a></p>
+
+<p>simple <a href="something.html">URL [with ] escaped</a></p>
+
+<p>simple <a href="something.html">URL with ] escaped</a></p>
+
+<p>simple <a href="something.html">URL [with] nested</a></p>
+
+<p>simple <a href="something.html">URL with [no](link.html) inside</a></p>
+
+<p>simple <a href="/something/to(do)">URL with parens</a></p>
+
+<p>simple <a href="/something/to(do" title="doit">URL with parens</a></p>
+
+<p>simple <a href="something.html" title="title">URL broken
+on line</a></p>
+
+<p>simple <a href="with spaces.html">URL with spaces</a></p>
+
+<p>simple <a href="with spaces.html" title="title">URL with spaces</a></p>
+
+<p>simple <a href="with (spaces).html">URL with spaces</a></p>
+
+<p>simple <a href="spaces.html">leading/trailing spaces</a></p>
+
+<p>simple <a href="spaces.html">leading/trailing spaces</a></p>
+
+<p>simple <a href="spaces.html">leading/trailing spaces</a></p>
+
+<p>bad [URL <a href="something.html">not</a></p>
+
+<p>bad [URL with parens](something(new.html)</p>
+
+<p>bad [URL with empty title](something.html ‘’)</p>
+
+<p>bad [URL](</p>
+
+<p>bad [URL](no</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/inline.html.19 b/app/server/vendor/kramdown/test/testcases/span/01_link/inline.html.19
new file mode 100644
index 0000000..8d00efa
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/inline.html.19
@@ -0,0 +1,46 @@
+<p>simple <a href="">URL</a></p>
+
+<p>simple <a href="something.html">URL</a></p>
+
+<p>simple <a href="something.html">URL <em>with</em> formatting</a></p>
+
+<p>simple <a href="something.html" title="a t"itle">URL with single quoted title</a></p>
+
+<p>simple <a href="something.html" title="a t'itle">URL with double quoted title</a></p>
+
+<p>simple <a href="something.html">URL [with ] escaped</a></p>
+
+<p>simple <a href="something.html">URL with ] escaped</a></p>
+
+<p>simple <a href="something.html">URL [with] nested</a></p>
+
+<p>simple <a href="something.html">URL with [no](link.html) inside</a></p>
+
+<p>simple <a href="/something/to(do)">URL with parens</a></p>
+
+<p>simple <a href="/something/to(do" title="doit">URL with parens</a></p>
+
+<p>simple <a href="something.html" title="title">URL broken
+on line</a></p>
+
+<p>simple <a href="with spaces.html">URL with spaces</a></p>
+
+<p>simple <a href="with spaces.html" title="title">URL with spaces</a></p>
+
+<p>simple <a href="with (spaces).html">URL with spaces</a></p>
+
+<p>simple <a href="spaces.html">leading/trailing spaces</a></p>
+
+<p>simple <a href="spaces.html">leading/trailing spaces</a></p>
+
+<p>simple <a href="spaces.html">leading/trailing spaces</a></p>
+
+<p>bad [URL <a href="something.html">not</a></p>
+
+<p>bad [URL with parens](something(new.html)</p>
+
+<p>bad [URL with empty title](something.html ‘’)</p>
+
+<p>bad [URL](</p>
+
+<p>bad [URL](no</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/inline.text b/app/server/vendor/kramdown/test/testcases/span/01_link/inline.text
new file mode 100644
index 0000000..c705764
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/inline.text
@@ -0,0 +1,48 @@
+simple [URL]()
+
+simple [URL](something.html)
+
+simple [URL *with* formatting](something.html)
+
+simple [URL with single quoted title](something.html 'a t"itle')
+
+simple [URL with double quoted title](something.html "a t'itle")
+
+simple [URL \[with \] escaped](something.html)
+
+simple [URL with \] escaped](something.html)
+
+simple [URL [with] nested](something.html)
+
+simple [URL with [no](link.html) inside](something.html)
+
+simple [URL with parens](/something/to(do))
+
+simple [URL with parens](/something/to(do "doit")
+
+simple [URL broken
+on line](something.html
+"title")
+
+simple [URL with spaces](with spaces.html)
+
+simple [URL with spaces](with spaces.html 'title')
+
+simple [URL with spaces](with (spaces).html)
+
+simple [leading/trailing spaces](  spaces.html)
+
+simple [leading/trailing spaces](spaces.html  )
+
+simple [leading/trailing spaces](  spaces.html  )
+
+
+bad [URL [not](something.html)
+
+bad [URL with parens](something(new.html)
+
+bad [URL with empty title](something.html '')
+
+bad [URL](
+
+bad [URL](no
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/link_defs.html b/app/server/vendor/kramdown/test/testcases/span/01_link/link_defs.html
new file mode 100644
index 0000000..065ed53
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/link_defs.html
@@ -0,0 +1,9 @@
+<p>This is a para.
+[id]: http://www.example.com/</p>
+
+<pre><code>[4]: nourl
+</code></pre>
+
+<p>Points to <a href="one.url">1</a> and <a href="two.url">2</a> and <a href="three.url">3</a> but not [4]</p>
+
+<p>Points to <a href="http://example.com">_.:,;!?-</a></p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/link_defs.text b/app/server/vendor/kramdown/test/testcases/span/01_link/link_defs.text
new file mode 100644
index 0000000..ef6789c
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/link_defs.text
@@ -0,0 +1,26 @@
+This is a para.
+[id]: http://www.example.com/
+
+[otherid1]: http://wwww.example.com/ "title 1"
+[otherid2]: http://wwww.example.com/ 'title 2'
+[otherid3]: <some spaces.html>
+[otherid4]: <some spaces.html> 'title'
+[otherid5]: some spaces.html
+[otherid6]: some spaces.html 'title'
+[otherid7]: some spaces
+            "title"
+
+[break]:	http://www.example.com/test/asdf.html
+                'Another title'
+
+[1]: ignored.url
+ [1]: one.url
+  [2]: two.url
+   [3]: three.url
+    [4]: nourl
+
+Points to [1] and [2] and [3] but not [4]
+
+[_.:,;!?-]: http://example.com
+
+Points to [_.:,;!?-]
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/links_with_angle_brackets.html b/app/server/vendor/kramdown/test/testcases/span/01_link/links_with_angle_brackets.html
new file mode 100644
index 0000000..ecaa31e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/links_with_angle_brackets.html
@@ -0,0 +1,3 @@
+<p>This is a <a href="with angle.html">link</a>.</p>
+
+<p>This is a <a href="with angle.html" title="and title">link</a>.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/links_with_angle_brackets.text b/app/server/vendor/kramdown/test/testcases/span/01_link/links_with_angle_brackets.text
new file mode 100644
index 0000000..2cf0ece
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/links_with_angle_brackets.text
@@ -0,0 +1,3 @@
+This is a [link](<with angle.html>).
+
+This is a [link](<with angle.html> 'and title').
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/reference.html b/app/server/vendor/kramdown/test/testcases/span/01_link/reference.html
new file mode 100644
index 0000000..49afd2e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/reference.html
@@ -0,0 +1,37 @@
+
+<p>simple <a href="otherurl.html">URL</a> and <a href="someurl.html">URL</a></p>
+
+<p>simple <a href="otherurl.html">URL</a> and <a href="someurl.html">URL</a></p>
+
+<p>simple <a href="otherurl.html">1</a> and <a href="someurl.html">isurl</a></p>
+
+<p>simple <a href="otherurl.html">1</a> and <a href="someurl.html">isurl</a></p>
+
+<p>this is [a holy <a href="someurl.html">isurl</a>]</p>
+
+<p>no [resolution][] here and [here]</p>
+
+<p>with a <a href="url.html">break 	 in
+the text</a></p>
+
+<p>this not [isurl] and not [isurl]</p>
+
+<p>a <a href="letters.html" title="This is the title">Link with_BIG</a> letters</p>
+
+<p>bad [no URL] d <a href="someurl.html">isurl</a></p>
+
+<p>[no url] invalid.html
+[no url]:</p>
+
+<p>“title”</p>
+
+<p>test <a href="invalid.html">url but no title</a>
+test [urldef]</p>
+
+<p>[urldef]: some.url ‘title”</p>
+
+<p>some <a href="with spaces.html" title="title">with spaces</a></p>
+
+<p>this <a href="occasion.html">is a ‘special’ occasion for /all/ of us</a></p>
+
+<p>this is <a href="predefined.html">predefined</a> for <a href="uri.html" title="My URI">URI</a></p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/reference.html.19 b/app/server/vendor/kramdown/test/testcases/span/01_link/reference.html.19
new file mode 100644
index 0000000..f6fed18
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/reference.html.19
@@ -0,0 +1,37 @@
+
+<p>simple <a href="otherurl.html">URL</a> and <a href="someurl.html">URL</a></p>
+
+<p>simple <a href="otherurl.html">URL</a> and <a href="someurl.html">URL</a></p>
+
+<p>simple <a href="otherurl.html">1</a> and <a href="someurl.html">isurl</a></p>
+
+<p>simple <a href="otherurl.html">1</a> and <a href="someurl.html">isurl</a></p>
+
+<p>this is [a holy <a href="someurl.html">isurl</a>]</p>
+
+<p>no [resolution][] here and [here]</p>
+
+<p>with a <a href="url.html">break 	 in
+the text</a></p>
+
+<p>this not [isurl] and not [isurl]</p>
+
+<p>a <a href="letters.html" title="This is the title">Link with_BIG</a> letters</p>
+
+<p>bad [no URL] d <a href="someurl.html">isurl</a></p>
+
+<p>[no url] invalid.html
+[no url]:</p>
+
+<p>“title”</p>
+
+<p>test <a href="invalid.html">url but no title</a>
+test [urldef]</p>
+
+<p>[urldef]: some.url ‘title”</p>
+
+<p>some <a href="with spaces.html" title="title">with spaces</a></p>
+
+<p>this <a href="occasion.html">is a ‘special’ occasion for /all/ of us</a></p>
+
+<p>this is <a href="predefined.html">predefined</a> for <a href="uri.html" title="My URI">URI</a></p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/reference.options b/app/server/vendor/kramdown/test/testcases/span/01_link/reference.options
new file mode 100644
index 0000000..efb4b01
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/reference.options
@@ -0,0 +1,3 @@
+:link_defs:
+  predefined: [predefined.html]
+  URI: [uri.html, My URI]
diff --git a/app/server/vendor/kramdown/test/testcases/span/01_link/reference.text b/app/server/vendor/kramdown/test/testcases/span/01_link/reference.text
new file mode 100644
index 0000000..9f39fa7
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/01_link/reference.text
@@ -0,0 +1,53 @@
+[isurl]: someurl.html
+ [1]:     otherurl.html
+
+simple [URL][1] and [URL][isurl]
+
+simple [URL] [1] and [URL]
+[isurl]
+
+simple [1][] and [isurl][]
+
+simple [1] and [isurl]
+
+this is [a holy [isurl]]
+
+no [resolution][] here and [here]
+
+with a [break 	 in
+the text]
+
+  [break in the text]: url.html
+
+this not \[isurl] and not [isurl\]
+
+a [Link with_BIG] letters
+
+   [link WITH_big]: letters.html
+                    'This is the title'
+
+bad [no URL] d [isurl]
+
+[no url] invalid.html
+[no url]:
+
+[URL but no title]: invalid.html
+
+   "title"
+
+test [url but no title]
+test [urldef]
+
+[urldef]: some.url 'title"
+
+
+some [with spaces]
+
+[with spaces]: with spaces.html "title"
+
+this [is a 'special' occasion for /all/ of us]
+
+[is a 'special' occasion for /all/ of us]: occasion.html
+
+
+this is [predefined] for [URI]
diff --git a/app/server/vendor/kramdown/test/testcases/span/02_emphasis/empty.html b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/empty.html
new file mode 100644
index 0000000..127e694
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/empty.html
@@ -0,0 +1,3 @@
+<p>This __is **empty.</p>
+
+<p>This <em>**</em>is empty.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/02_emphasis/empty.text b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/empty.text
new file mode 100644
index 0000000..c99d053
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/empty.text
@@ -0,0 +1,3 @@
+This __is **empty.
+
+This ****is empty.
diff --git a/app/server/vendor/kramdown/test/testcases/span/02_emphasis/errors.html b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/errors.html
new file mode 100644
index 0000000..e62f03f
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/errors.html
@@ -0,0 +1,9 @@
+<p>This is a *star.</p>
+
+<p>This is a **star.</p>
+
+<p>This is <em>*a *star</em>.</p>
+
+<p>This is *a star*.</p>
+
+<p>This** is** a star.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/02_emphasis/errors.text b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/errors.text
new file mode 100644
index 0000000..e80e5eb
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/errors.text
@@ -0,0 +1,9 @@
+This is a *star.
+
+This is a **star.
+
+This is **a *star*.
+
+This is *a star\*.
+
+This** is** a star.
diff --git a/app/server/vendor/kramdown/test/testcases/span/02_emphasis/nesting.html b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/nesting.html
new file mode 100644
index 0000000..3d34cee
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/nesting.html
@@ -0,0 +1,41 @@
+<ul>
+  <li><strong><em>test test</em></strong></li>
+  <li><strong><em>test test</em></strong></li>
+  <li><em>test <strong>test</strong></em></li>
+  <li><strong>test <em>test</em></strong></li>
+  <li><strong><em>test</em> test</strong></li>
+  <li><em><strong>test</strong> test</em></li>
+  <li><strong><em>test</em> test</strong></li>
+  <li><strong>test <em>test</em></strong></li>
+  <li><em>test <strong>test</strong></em></li>
+  <li><em>test <strong>test</strong></em></li>
+  <li><strong>test <em>test</em></strong></li>
+  <li><strong><em>test</em> test</strong></li>
+  <li><em><strong>test</strong> test</em></li>
+  <li><strong><em>test</em> test</strong></li>
+  <li><strong>test <em>test</em></strong></li>
+  <li><em>test <strong>test</strong></em></li>
+</ul>
+<ul>
+  <li><em>a</em>b</li>
+  <li>a<em>b</em></li>
+  <li>a<em>b</em>c</li>
+  <li><strong>a</strong>b</li>
+  <li>a<strong>b</strong></li>
+  <li>a<strong>b</strong>c</li>
+</ul>
+<ul>
+  <li>_a_b</li>
+  <li>a_b_</li>
+  <li>a_b_c</li>
+  <li>__a__b</li>
+  <li>a__b__</li>
+  <li>a__b__c</li>
+  <li>a__2__c</li>
+  <li>a__2__3</li>
+  <li>1__2__3</li>
+</ul>
+<ul>
+  <li><em>a _b_ c</em></li>
+  <li><strong>a __b__ c</strong></li>
+</ul>
diff --git a/app/server/vendor/kramdown/test/testcases/span/02_emphasis/nesting.text b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/nesting.text
new file mode 100644
index 0000000..ba67e84
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/nesting.text
@@ -0,0 +1,36 @@
+- ***test test***
+- ___test test___
+- *test **test***
+- **test *test***
+- ***test* test**
+- ***test** test*
+- ***test* test**
+- **test *test***
+- *test **test***
+- _test __test___
+- __test _test___
+- ___test_ test__
+- ___test__ test_
+- ___test_ test__
+- __test _test___
+- _test __test___
+^
+-  *a*b
+-   a*b*
+-   a*b*c
+- **a**b
+-   a**b**
+-   a**b**c
+^
+-  _a_b
+-   a_b_
+-   a_b_c
+- __a__b
+-   a__b__
+-   a__b__c
+-   a__2__c
+-   a__2__3
+-   1__2__3
+^
+-  *a _b_ c*
+-  **a __b__ c**
diff --git a/app/server/vendor/kramdown/test/testcases/span/02_emphasis/normal.html b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/normal.html
new file mode 100644
index 0000000..f369d56
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/normal.html
@@ -0,0 +1,46 @@
+<p>This <em>is</em> so <strong>hard</strong>.</p>
+
+<p>This <em>is</em> so <strong>hard</strong> too.</p>
+
+<p><em>At</em> start
+<em>At</em> start</p>
+
+<p>At <em>end</em>
+At <em>end</em></p>
+
+<p><em>At</em> start
+<em>At</em> start</p>
+
+<p>At <em>end</em>
+At <em>end</em></p>
+
+<p>And <em>nest<strong>ed</strong></em>.</p>
+
+<p>And <em>nest**ed</em>.</p>
+
+<p>And *nest<strong>ed* like</strong> this.</p>
+
+<p>And <em>not_nest_ed</em>.</p>
+
+<p>And <strong><em>nested</em></strong>.</p>
+
+<p>And <strong><em>nested</em></strong>.</p>
+
+<p>And <strong>nest<em>e</em></strong>.</p>
+
+<p>And lonely * here*.</p>
+
+<p>And lonely ** here**.</p>
+
+<p>And <strong>lonely ** here</strong>.</p>
+
+<p>** and here**.</p>
+
+<p>And <strong>compli*cated *</strong> here</p>
+
+<p>Some<em>**what</em> more * <em>**he</em>re</p>
+
+<p>Do it <em>*this*</em> way
+Or this *<em>this</em>* way
+Or that <em>*that</em>* way
+Or that *<em>that*</em> way</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/02_emphasis/normal.text b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/normal.text
new file mode 100644
index 0000000..d5885df
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/02_emphasis/normal.text
@@ -0,0 +1,46 @@
+This *is* so **hard**.
+
+This _is_ so __hard__ too.
+
+*At* start
+*At* start
+
+At *end*
+At *end*
+
+_At_ start
+_At_ start
+
+At _end_
+At _end_
+
+And *nest**ed***.
+
+And *nest**ed*.
+
+And *nest**ed* like** this.
+
+And *not_nest_ed*.
+
+And ***nested***.
+
+And ___nested___.
+
+And **nest*e***.
+
+And lonely * here*.
+
+And lonely ** here**.
+
+And **lonely ** here**.
+
+** and here**.
+
+And **compli*cated \*** here
+
+Some***what* more * ***he*re
+
+Do it *\*this\** way
+Or this \**this*\* way
+Or that *\*that*\* way
+Or that \**that\** way
diff --git a/app/server/vendor/kramdown/test/testcases/span/03_codespan/empty.html b/app/server/vendor/kramdown/test/testcases/span/03_codespan/empty.html
new file mode 100644
index 0000000..20c5051
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/03_codespan/empty.html
@@ -0,0 +1,5 @@
+<p>This is `` empty.</p>
+
+<p>This is ``empty.</p>
+
+<p>This is ````empty.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/03_codespan/empty.text b/app/server/vendor/kramdown/test/testcases/span/03_codespan/empty.text
new file mode 100644
index 0000000..cbb9152
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/03_codespan/empty.text
@@ -0,0 +1,5 @@
+This is `` empty.
+
+This is ``empty.
+
+This is ````empty.
diff --git a/app/server/vendor/kramdown/test/testcases/span/03_codespan/errors.html b/app/server/vendor/kramdown/test/testcases/span/03_codespan/errors.html
new file mode 100644
index 0000000..1d341a8
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/03_codespan/errors.html
@@ -0,0 +1 @@
+<p>Not ended `span.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/03_codespan/errors.text b/app/server/vendor/kramdown/test/testcases/span/03_codespan/errors.text
new file mode 100644
index 0000000..7a948b4
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/03_codespan/errors.text
@@ -0,0 +1 @@
+Not ended `span.
diff --git a/app/server/vendor/kramdown/test/testcases/span/03_codespan/highlighting.html b/app/server/vendor/kramdown/test/testcases/span/03_codespan/highlighting.html
new file mode 100644
index 0000000..98c0b4a
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/03_codespan/highlighting.html
@@ -0,0 +1 @@
+<p>You can say <code class="language-ruby"><span class="CodeRay">x = <span style="color:#036;font-weight:bold">Class</span>.new</span></code>, for example.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/03_codespan/highlighting.text b/app/server/vendor/kramdown/test/testcases/span/03_codespan/highlighting.text
new file mode 100644
index 0000000..7373290
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/03_codespan/highlighting.text
@@ -0,0 +1 @@
+You can say `x = Class.new`{:.language-ruby}, for example.
diff --git a/app/server/vendor/kramdown/test/testcases/span/03_codespan/normal.html b/app/server/vendor/kramdown/test/testcases/span/03_codespan/normal.html
new file mode 100644
index 0000000..68eddbe
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/03_codespan/normal.html
@@ -0,0 +1,16 @@
+<p>This is <code>a</code> simple span.</p>
+
+<p>With <code>some<ht>&ml</code> in it.</p>
+
+<p>And <code>`</code> backticks.</p>
+
+<p>And <code>``some``</code> more.</p>
+
+<p>With backslash <code>in\</code> it.</p>
+
+<p>This is a ` literal backtick.
+As `are` these!</p>
+
+<p>No <code>literal backtick</code>.</p>
+
+<p><code>something</code></p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/03_codespan/normal.text b/app/server/vendor/kramdown/test/testcases/span/03_codespan/normal.text
new file mode 100644
index 0000000..10d06e2
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/03_codespan/normal.text
@@ -0,0 +1,16 @@
+This is `a` simple span.
+
+With `some<ht>&ml` in it.
+
+And `` ` `` backticks.
+
+And ``` ``some`` ``` more.
+
+With backslash `in\` it.
+
+This is a ` literal backtick.
+As \`are\` these!
+
+No `` literal backtick``.
+
+`something`
diff --git a/app/server/vendor/kramdown/test/testcases/span/04_footnote/definitions.html b/app/server/vendor/kramdown/test/testcases/span/04_footnote/definitions.html
new file mode 100644
index 0000000..9012cc0
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/04_footnote/definitions.html
@@ -0,0 +1,17 @@
+<p>Some para.</p>
+
+<blockquote>
+  <p>blockquote</p>
+</blockquote>
+
+<ul>
+  <li>a list
+with some text</li>
+</ul>
+
+<ul>
+  <li>other list</li>
+</ul>
+<pre><code>code
+</code></pre>
+
diff --git a/app/server/vendor/kramdown/test/testcases/span/04_footnote/definitions.latex b/app/server/vendor/kramdown/test/testcases/span/04_footnote/definitions.latex
new file mode 100644
index 0000000..f666976
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/04_footnote/definitions.latex
@@ -0,0 +1,17 @@
+Some para.
+
+\begin{quote}
+blockquote
+\end{quote}
+
+\begin{itemize}
+\item a list
+with some text
+\end{itemize}
+
+\begin{itemize}
+\item other list
+\end{itemize}
+\begin{verbatim}code
+\end{verbatim}
+
diff --git a/app/server/vendor/kramdown/test/testcases/span/04_footnote/definitions.text b/app/server/vendor/kramdown/test/testcases/span/04_footnote/definitions.text
new file mode 100644
index 0000000..44b52e0
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/04_footnote/definitions.text
@@ -0,0 +1,24 @@
+Some para.
+
+[^footnote]: ignored definition
+[^footnote]: Some footnote text
+
+> blockquote
+
+[^other]: some
+    foot
+
+    note text
+
+* a list
+  with some text
+
+[^tnote]: foot note
+
+* other list
+^
+    code
+
+[^1]:
+    > a blockquote
+    and some para
diff --git a/app/server/vendor/kramdown/test/testcases/span/04_footnote/footnote_nr.html b/app/server/vendor/kramdown/test/testcases/span/04_footnote/footnote_nr.html
new file mode 100644
index 0000000..5133521
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/04_footnote/footnote_nr.html
@@ -0,0 +1,12 @@
+<p>This is a footnote<sup id="fnref:ab"><a href="#fn:ab" class="footnote">35</a></sup>. And another<sup id="fnref:bc"><a href="#fn:bc" class="footnote">36</a></sup>.</p>
+
+<div class="footnotes">
+  <ol start="35">
+    <li id="fn:ab">
+      <p>Some text. <a href="#fnref:ab" class="reversefootnote">↩</a></p>
+    </li>
+    <li id="fn:bc">
+      <p>Some other text. <a href="#fnref:bc" class="reversefootnote">↩</a></p>
+    </li>
+  </ol>
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/span/04_footnote/footnote_nr.latex b/app/server/vendor/kramdown/test/testcases/span/04_footnote/footnote_nr.latex
new file mode 100644
index 0000000..8f07dde
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/04_footnote/footnote_nr.latex
@@ -0,0 +1,2 @@
+This is a footnote\footnote{Some text.}. And another\footnote{Some other text.}.
+
diff --git a/app/server/vendor/kramdown/test/testcases/span/04_footnote/footnote_nr.options b/app/server/vendor/kramdown/test/testcases/span/04_footnote/footnote_nr.options
new file mode 100644
index 0000000..f606ecf
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/04_footnote/footnote_nr.options
@@ -0,0 +1 @@
+:footnote_nr: 35
diff --git a/app/server/vendor/kramdown/test/testcases/span/04_footnote/footnote_nr.text b/app/server/vendor/kramdown/test/testcases/span/04_footnote/footnote_nr.text
new file mode 100644
index 0000000..cad2935
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/04_footnote/footnote_nr.text
@@ -0,0 +1,4 @@
+This is a footnote[^ab]. And another[^bc].
+
+[^ab]: Some text.
+[^bc]: Some other text.
diff --git a/app/server/vendor/kramdown/test/testcases/span/04_footnote/markers.html b/app/server/vendor/kramdown/test/testcases/span/04_footnote/markers.html
new file mode 100644
index 0000000..3a5bc28
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/04_footnote/markers.html
@@ -0,0 +1,46 @@
+<p>This is some *ref.<sup id="fnref:fn"><a href="#fn:fn" class="footnote">1</a></sup></p>
+
+<blockquote>
+  <p>a blockquote <sup id="fnref:3"><a href="#fn:3" class="footnote">2</a></sup></p>
+</blockquote>
+
+<ul>
+  <li>and a list item <sup id="fnref:1"><a href="#fn:1" class="footnote">3</a></sup></li>
+</ul>
+
+<h1>And a header<sup id="fnref:now"><a href="#fn:now" class="footnote">4</a></sup></h1>
+
+<p>A marker without a definition [^without].</p>
+
+<p>A marker <sup id="fnref:empty"><a href="#fn:empty" class="footnote">5</a></sup> used twice<sup id="fnref:fn:1"><a href="#fn:fn" class="footnote">1</a></sup> and thrice<sup id="fnref:fn:2"><a href="#fn:fn" class="footnote">1</a></sup>.</p>
+
+<div class="footnotes">
+  <ol>
+    <li id="fn:fn">
+      <p>Some foot note text <a href="#fnref:fn" class="reversefootnote">↩</a> <a href="#fnref:fn:1" class="reversefootnote">↩<sup>2</sup></a> <a href="#fnref:fn:2" class="reversefootnote">↩<sup>3</sup></a></p>
+    </li>
+    <li id="fn:3">
+      <p>other text
+with more lines</p>
+
+      <blockquote>
+        <p>and a quote</p>
+      </blockquote>
+      <p><a href="#fnref:3" class="reversefootnote">↩</a></p>
+    </li>
+    <li id="fn:1">
+      <p>some <em>text</em> <a href="#fnref:1" class="reversefootnote">↩</a></p>
+    </li>
+    <li id="fn:now">
+
+      <pre><code>code block
+continued here
+</code></pre>
+      <p><a href="#fnref:now" class="reversefootnote">↩</a></p>
+    </li>
+    <li id="fn:empty">
+
+      <p><a href="#fnref:empty" class="reversefootnote">↩</a></p>
+    </li>
+  </ol>
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases/span/04_footnote/markers.latex b/app/server/vendor/kramdown/test/testcases/span/04_footnote/markers.latex
new file mode 100644
index 0000000..fb5237e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/04_footnote/markers.latex
@@ -0,0 +1,23 @@
+This is some *ref.\footnote{Some foot note text}
+
+\begin{quote}
+a blockquote \footnote{other text
+with more lines
+
+\begin{quote}
+and a quote
+\end{quote}}
+\end{quote}
+
+\begin{itemize}
+\item and a list item \footnote{some \emph{text}}
+\end{itemize}
+
+\section*{And a header\footnote{\begin{verbatim}code block
+continued here
+\end{verbatim}}}
+
+A marker without a definition [\^{}without].
+
+A marker \footnote{} used twice\footnote{Some foot note text} and thrice\footnote{Some foot note text}.
+
diff --git a/app/server/vendor/kramdown/test/testcases/span/04_footnote/markers.text b/app/server/vendor/kramdown/test/testcases/span/04_footnote/markers.text
new file mode 100644
index 0000000..cc2b199
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/04_footnote/markers.text
@@ -0,0 +1,26 @@
+This is some *ref.[^fn]
+
+[^fn]: Some foot note text
+
+> a blockquote [^3]
+
+* and a list item [^1]
+
+# And a header[^now]
+
+[^1]:some *text*
+[^3]: other text
+    with more lines
+
+    > and a quote
+
+A marker without a definition [^without].
+
+A marker [^empty] used twice[^fn] and thrice[^fn].
+
+[^now]:
+
+    	code block
+        continued here
+
+[^empty]:
diff --git a/app/server/vendor/kramdown/test/testcases/span/04_footnote/placement.html b/app/server/vendor/kramdown/test/testcases/span/04_footnote/placement.html
new file mode 100644
index 0000000..c6d0eb8
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/04_footnote/placement.html
@@ -0,0 +1,11 @@
+<div class="footnotes">
+  <ol>
+    <li id="fn:1">
+      <p>Footnote text <a href="#fnref:1" class="reversefootnote">↩</a></p>
+    </li>
+  </ol>
+</div>
+
+<p>Some para with a<sup id="fnref:1"><a href="#fn:1" class="footnote">1</a></sup> footnote.</p>
+
+<p>And another para.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/04_footnote/placement.text b/app/server/vendor/kramdown/test/testcases/span/04_footnote/placement.text
new file mode 100644
index 0000000..eb8ab3d
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/04_footnote/placement.text
@@ -0,0 +1,8 @@
+* footnotes will be placed here
+{:footnotes}
+
+Some para with a[^1] footnote.
+
+[^1]: Footnote text
+
+And another para.
diff --git a/app/server/vendor/kramdown/test/testcases/span/05_html/across_lines.html b/app/server/vendor/kramdown/test/testcases/span/05_html/across_lines.html
new file mode 100644
index 0000000..e7cec40
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/05_html/across_lines.html
@@ -0,0 +1 @@
+<p>Link: <a href="test foo">test</a></p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/05_html/across_lines.text b/app/server/vendor/kramdown/test/testcases/span/05_html/across_lines.text
new file mode 100644
index 0000000..8f39d95
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/05_html/across_lines.text
@@ -0,0 +1,2 @@
+Link: <a href="test
+foo">test</a>
diff --git a/app/server/vendor/kramdown/test/testcases/span/05_html/invalid.html b/app/server/vendor/kramdown/test/testcases/span/05_html/invalid.html
new file mode 100644
index 0000000..030552f
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/05_html/invalid.html
@@ -0,0 +1 @@
+<p>This is <span>some text</span></p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/05_html/invalid.text b/app/server/vendor/kramdown/test/testcases/span/05_html/invalid.text
new file mode 100644
index 0000000..383f0a8
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/05_html/invalid.text
@@ -0,0 +1 @@
+This is <span>some text
diff --git a/app/server/vendor/kramdown/test/testcases/span/05_html/link_with_mailto.html b/app/server/vendor/kramdown/test/testcases/span/05_html/link_with_mailto.html
new file mode 100644
index 0000000..7d0d6ad
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/05_html/link_with_mailto.html
@@ -0,0 +1 @@
+<p>Link: <a href="mailto:test at example.com">text</a></p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/05_html/link_with_mailto.text b/app/server/vendor/kramdown/test/testcases/span/05_html/link_with_mailto.text
new file mode 100644
index 0000000..fb01619
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/05_html/link_with_mailto.text
@@ -0,0 +1 @@
+Link: <a href="mailto:test at example.com">text</a>
diff --git a/app/server/vendor/kramdown/test/testcases/span/05_html/markdown_attr.html b/app/server/vendor/kramdown/test/testcases/span/05_html/markdown_attr.html
new file mode 100644
index 0000000..44158c3
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/05_html/markdown_attr.html
@@ -0,0 +1,6 @@
+<p>This is <span><em>text</em></span>
+This is <span>*text*</span>
+This is <span><em>text</em></span>
+This is <span><em>text</em></span>
+This is <span>*nothing* <strong>to <em>fear</em></strong> about</span>.
+This is <span><http://example.com></span>.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/05_html/markdown_attr.text b/app/server/vendor/kramdown/test/testcases/span/05_html/markdown_attr.text
new file mode 100644
index 0000000..dcc10ff
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/05_html/markdown_attr.text
@@ -0,0 +1,6 @@
+This is <span markdown="1">*text*</span>
+This is <span markdown="0">*text*</span>
+This is <span markdown="span">*text*</span>
+This is <span markdown="block">*text*</span>
+This is <span markdown="0">*nothing* <strong markdown="1">to *fear*</strong> about</span>.
+This is <span markdown="0"><http://example.com></span>.
diff --git a/app/server/vendor/kramdown/test/testcases/span/05_html/normal.html b/app/server/vendor/kramdown/test/testcases/span/05_html/normal.html
new file mode 100644
index 0000000..1efbee8
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/05_html/normal.html
@@ -0,0 +1,41 @@
+<p>Empty <a name="anchor" id="anchor" class=""></a>!</p>
+
+<p><a href="test">title</a> is a title.</p>
+
+<p>This is <? a PI ?>.</p>
+
+<p>This is <!-- a --> comment.</p>
+
+<p>This is <!-- a
+--> multiline comment.</p>
+
+<p>This is <span>tag
+now </span>.</p>
+
+<p>This is <span>tag
+</span> now.</p>
+
+<p>This is an empty <span></span> tag.</p>
+
+<p>This is <em>something<span test="do_it"></span> strange</em>.</p>
+
+<p>Auto-closing: <br /></p>
+
+<p>Expanding: <textarea></textarea></p>
+
+<p>An invalid tag: <hR></p>
+
+<p>A <p>block tag</p>.</p>
+
+<p>An invalid </closing> tag.</p>
+
+<p>A <script>*not*</script> tag.</p>
+
+<p>An <span>unclosed <em>tag.</em></span></p>
+
+<p>Some <code>element with | pipe symbol</code></p>
+
+<p>Some <span><code>element with | pipe symbol</code></span></p>
+
+<p>Some <code>element with | pipe
+symbol|</code></p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/05_html/normal.text b/app/server/vendor/kramdown/test/testcases/span/05_html/normal.text
new file mode 100644
index 0000000..661e9c8
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/05_html/normal.text
@@ -0,0 +1,41 @@
+Empty <a NaMe="anchor" ID="anchor" cLaSs></A>!
+
+<a href="test">title</a> is a title.
+
+This is <? a PI ?>.
+
+This is <!-- a --> comment.
+
+This is <!-- a
+--> multiline comment.
+
+This is <span>tag
+now </span>.
+
+This is <sPAn>tag
+</SPAN> now.
+
+This is an empty <span></span> tag.
+
+This is _something<span test="do_it" /> strange_.
+
+Auto-closing: <br>
+
+Expanding: <textarea></textarea>
+
+An invalid tag: <hR>
+
+A <p>block tag</p>.
+
+An invalid </closing> tag.
+
+A <script>*not*</script> tag.
+
+An <span>unclosed *tag.*
+
+Some <code>element with | pipe symbol</code>
+
+Some <span><code>element with | pipe symbol</code></span>
+
+Some <code>element with | pipe
+symbol|</code>
diff --git a/app/server/vendor/kramdown/test/testcases/span/05_html/raw_span_elements.html b/app/server/vendor/kramdown/test/testcases/span/05_html/raw_span_elements.html
new file mode 100644
index 0000000..808f1db
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/05_html/raw_span_elements.html
@@ -0,0 +1,2 @@
+<p>This is raw <kbd>--version</kbd> and <samp>--version</samp> and <var>--version</var> and
+<code>---version</code>.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/05_html/raw_span_elements.text b/app/server/vendor/kramdown/test/testcases/span/05_html/raw_span_elements.text
new file mode 100644
index 0000000..5b128fc
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/05_html/raw_span_elements.text
@@ -0,0 +1,2 @@
+This is raw <kbd>--version</kbd> and <samp>--version</samp> and <var>--version</var> and
+<code>---version</code>.
diff --git a/app/server/vendor/kramdown/test/testcases/span/abbreviations/abbrev.html b/app/server/vendor/kramdown/test/testcases/span/abbreviations/abbrev.html
new file mode 100644
index 0000000..0a3329e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/abbreviations/abbrev.html
@@ -0,0 +1,19 @@
+<p>This <abbr title="It is, yes">is some</abbr> text.</p>
+
+<p>There <em><abbr title="It is, yes">is some</abbr> real</em> concern about <abbr title="This & that">OtHeR!</abbr></p>
+
+<p><abbr title="It is, yes">is some</abbr> Think <abbr>empty</abbr> about <abbr title="Very nice country">Oesterreich</abbr>. <abbr title="Cascading">CSS</abbr> und <abbr title="Cascading 3">CSS3</abbr></p>
+
+<p>no abbrev here because there is someone and kulis some</p>
+
+<ul>
+  <li><abbr title="(eXtensible) HyperText Markup Language">(X)HTML</abbr> test </li>
+  <li>line two</li>
+</ul>
+
+<p><a href="http://en.wikipedia.org/wiki/Xhtml"><abbr title="(eXtensible) HyperText Markup Language">(X)HTML</abbr></a></p>
+
+<ul>
+  <li>test <abbr title="(eXtensible) HyperText Markup Language">(X)HTML</abbr></li>
+</ul>
+
diff --git a/app/server/vendor/kramdown/test/testcases/span/abbreviations/abbrev.text b/app/server/vendor/kramdown/test/testcases/span/abbreviations/abbrev.text
new file mode 100644
index 0000000..23c347e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/abbreviations/abbrev.text
@@ -0,0 +1,27 @@
+This is some text.
+
+*[is some]: Yes it is  
+*[OtHeR!]: This & that
+
+*[is some]: It is, yes  
+*[empty]:
+
+There *is some real* concern about OtHeR!
+
+is some Think empty about Oesterreich. CSS und CSS3
+
+no abbrev here because there is someone and kulis some
+
+*[Oesterreich]: 	Very nice country	
+
+*[CSS]: Cascading
+*[CSS3]: Cascading 3
+
+* (X)HTML test 
+* line two
+
+[(X)HTML](http://en.wikipedia.org/wiki/Xhtml)
+
+* test (X)HTML
+
+*[(X)HTML]: (eXtensible) HyperText Markup Language
diff --git a/app/server/vendor/kramdown/test/testcases/span/abbreviations/abbrev_defs.html b/app/server/vendor/kramdown/test/testcases/span/abbreviations/abbrev_defs.html
new file mode 100644
index 0000000..108fcfc
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/abbreviations/abbrev_defs.html
@@ -0,0 +1,2 @@
+<pre><code>*[4]: noabbrev
+</code></pre>
diff --git a/app/server/vendor/kramdown/test/testcases/span/abbreviations/abbrev_defs.text b/app/server/vendor/kramdown/test/testcases/span/abbreviations/abbrev_defs.text
new file mode 100644
index 0000000..3f3a0e5
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/abbreviations/abbrev_defs.text
@@ -0,0 +1,5 @@
+*[ABBR]: Some abbreviations   
+ *[one abbr]: one abbrev
+  *[2 and other]: another
+   *[3]: yet another 
+    *[4]: noabbrev
diff --git a/app/server/vendor/kramdown/test/testcases/span/autolinks/url_links.html b/app/server/vendor/kramdown/test/testcases/span/autolinks/url_links.html
new file mode 100644
index 0000000..d170eef
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/autolinks/url_links.html
@@ -0,0 +1,14 @@
+<p>This should be a <a href="http://www.example.com/">http://www.example.com/</a> link.
+This should be a <a href="mailto:john.doe@example.com">john.doe@example.com</a> link.
+As should <a href="mailto:john.doe@example.com">john.doe@example.com</a> this.
+As should <a href="mailto:CSS@example.com"><abbr title="Cascading">CSS</abbr>@example.com</a> this.
+Another ampersand <a href="http://www.example.com/?doit&x=y">http://www.example.com/?doit&x=y</a> link.
+More entities  <a href="http://www.example.com/?doit&x="y&z=y">http://www.example.com/?doit&x="y&z=y</a>.</p>
+
+<p>Email international <a href="mailto:übung@macht.den.meister.de">übung@macht.den.meister.de</a>, <a href="mailto:ü.äß@hülse.de">ü.äß@hülse.de</a>
+Email invalid: <<a href="mailtos:me at example.com">me at example.com</a>></p>
+
+<p>Autolink with underscore: <a href="http://www.example.com/with_under_score">http://www.example.com/with_under_score</a></p>
+
+<p><a href="http://www.example.com/">http://www.example.com/</a></p>
+
diff --git a/app/server/vendor/kramdown/test/testcases/span/autolinks/url_links.text b/app/server/vendor/kramdown/test/testcases/span/autolinks/url_links.text
new file mode 100644
index 0000000..f63e599
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/autolinks/url_links.text
@@ -0,0 +1,15 @@
+This should be a <http://www.example.com/> link.
+This should be a <mailto:john.doe at example.com> link.
+As should <john.doe at example.com> this.
+As should <CSS at example.com> this.
+Another ampersand <http://www.example.com/?doit&x=y> link.
+More entities  <http://www.example.com/?doit&x="y&z=y>.
+
+Email international <übung at macht.den.meister.de>, <ü.äß@hülse.de>
+Email invalid: <[me at example.com](mailtos:me at example.com)>
+
+Autolink with underscore: <http://www.example.com/with_under_score>
+
+<http://www.example.com/>
+
+*[CSS]: Cascading
diff --git a/app/server/vendor/kramdown/test/testcases/span/escaped_chars/normal.html b/app/server/vendor/kramdown/test/testcases/span/escaped_chars/normal.html
new file mode 100644
index 0000000..015d594
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/escaped_chars/normal.html
@@ -0,0 +1,47 @@
+<p>\</p>
+
+<p>.</p>
+
+<p>*</p>
+
+<p>_</p>
+
+<p>+</p>
+
+<p>-</p>
+
+<p>`</p>
+
+<p>(</p>
+
+<p>)</p>
+
+<p>[</p>
+
+<p>]</p>
+
+<p>{</p>
+
+<p>}</p>
+
+<p>#</p>
+
+<p>!</p>
+
+<p><<</p>
+
+<p>>></p>
+
+<p>:</p>
+
+<p>|</p>
+
+<p>"</p>
+
+<p>'</p>
+
+<p>=</p>
+
+<p>></p>
+
+<p><</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/escaped_chars/normal.text b/app/server/vendor/kramdown/test/testcases/span/escaped_chars/normal.text
new file mode 100644
index 0000000..1c47104
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/escaped_chars/normal.text
@@ -0,0 +1,47 @@
+\\
+
+\.
+
+\*
+
+\_
+
+\+
+
+\-
+
+\`
+
+\(
+
+\)
+
+\[
+
+\]
+
+\{
+
+\}
+
+\#
+
+\!
+
+\<<
+
+\>>
+
+\:
+
+\|
+
+\"
+
+\'
+
+\=
+
+\>
+
+\<
diff --git a/app/server/vendor/kramdown/test/testcases/span/extension/comment.html b/app/server/vendor/kramdown/test/testcases/span/extension/comment.html
new file mode 100644
index 0000000..3544d49
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/extension/comment.html
@@ -0,0 +1,6 @@
+<p>This is a <!-- simple --> paragraph.
+This is a <!-- simple --> paragraph.
+This is a <!-- simple {:/other} paragraph -->.
+This is a  paragraph.
+This is a {:/comment} simple {:/} paragraph.
+This is a {::comment} paragraph.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/extension/comment.text b/app/server/vendor/kramdown/test/testcases/span/extension/comment.text
new file mode 100644
index 0000000..8b9e8d3
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/extension/comment.text
@@ -0,0 +1,6 @@
+This is a {::comment}simple{:/} paragraph.
+This is a {::comment}simple{:/comment} paragraph.
+This is a {::comment}simple {:/other} paragraph{:/comment}.
+This is a {::comment/} paragraph.
+This is a {:/comment} simple {:/} paragraph.
+This is a {::comment} paragraph.
diff --git a/app/server/vendor/kramdown/test/testcases/span/extension/ignored.html b/app/server/vendor/kramdown/test/testcases/span/extension/ignored.html
new file mode 100644
index 0000000..63c2c40
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/extension/ignored.html
@@ -0,0 +1 @@
+<p>This is {::something}paragraph{:/}</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/extension/ignored.text b/app/server/vendor/kramdown/test/testcases/span/extension/ignored.text
new file mode 100644
index 0000000..a7e7737
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/extension/ignored.text
@@ -0,0 +1 @@
+This is {::something}paragraph{:/}
diff --git a/app/server/vendor/kramdown/test/testcases/span/extension/nomarkdown.html b/app/server/vendor/kramdown/test/testcases/span/extension/nomarkdown.html
new file mode 100644
index 0000000..83de931
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/extension/nomarkdown.html
@@ -0,0 +1 @@
+<p>This is *some* text.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/extension/nomarkdown.text b/app/server/vendor/kramdown/test/testcases/span/extension/nomarkdown.text
new file mode 100644
index 0000000..57c4b38
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/extension/nomarkdown.text
@@ -0,0 +1 @@
+This is {::nomarkdown}*some*{:/} text.
diff --git a/app/server/vendor/kramdown/test/testcases/span/extension/options.html b/app/server/vendor/kramdown/test/testcases/span/extension/options.html
new file mode 100644
index 0000000..48e3076
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/extension/options.html
@@ -0,0 +1 @@
+<p>This is an  option <span>*true*</span>!</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/extension/options.text b/app/server/vendor/kramdown/test/testcases/span/extension/options.text
new file mode 100644
index 0000000..e289491
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/extension/options.text
@@ -0,0 +1 @@
+This is an {::options parse_span_html="false" /} option <span>*true*</span>!
diff --git a/app/server/vendor/kramdown/test/testcases/span/ial/simple.html b/app/server/vendor/kramdown/test/testcases/span/ial/simple.html
new file mode 100644
index 0000000..c0f3a47
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/ial/simple.html
@@ -0,0 +1,6 @@
+<p>This is a <code class="hund" id="dog">span</code>.</p>
+
+<p>This is a <code class="hund katz" id="dog" key="val">span</code>.</p>
+
+<p>This is an{: .ignored} span ial.
+This is an{: .escaped} span ial.</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/ial/simple.text b/app/server/vendor/kramdown/test/testcases/span/ial/simple.text
new file mode 100644
index 0000000..8945602
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/ial/simple.text
@@ -0,0 +1,6 @@
+This is a `span`{: .hund #dog}.
+
+This is a `span`{: .hund #dog}{: .katz key='val'}.
+
+This is an{: .ignored} span ial.
+This is an\{: .escaped} span ial.
diff --git a/app/server/vendor/kramdown/test/testcases/span/line_breaks/normal.html b/app/server/vendor/kramdown/test/testcases/span/line_breaks/normal.html
new file mode 100644
index 0000000..da53e7e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/line_breaks/normal.html
@@ -0,0 +1,11 @@
+<p>This is a line<br />
+with a line break.  </p>
+
+<p>This is a line 
+without a line break.</p>
+
+<p>This is a line <br />
+with a line\ <br />
+break.</p>
+
+<p>Line break on last line.  </p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/line_breaks/normal.latex b/app/server/vendor/kramdown/test/testcases/span/line_breaks/normal.latex
new file mode 100644
index 0000000..25782fa
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/line_breaks/normal.latex
@@ -0,0 +1,12 @@
+This is a line\newline
+with a line break.  
+
+This is a line 
+without a line break.
+
+This is a line \newline
+with a line\textbackslash{} \newline
+break.
+
+Line break on last line.  
+
diff --git a/app/server/vendor/kramdown/test/testcases/span/line_breaks/normal.text b/app/server/vendor/kramdown/test/testcases/span/line_breaks/normal.text
new file mode 100644
index 0000000..92f866f
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/line_breaks/normal.text
@@ -0,0 +1,11 @@
+This is a line  
+with a line break.  
+
+This is a line 
+without a line break.
+
+This is a line \\
+with a line\\   
+break.
+
+Line break on last line.  
diff --git a/app/server/vendor/kramdown/test/testcases/span/math/normal.html b/app/server/vendor/kramdown/test/testcases/span/math/normal.html
new file mode 100644
index 0000000..d99130e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/math/normal.html
@@ -0,0 +1,10 @@
+<p>This is <script type="math/tex">\lambda_\alpha > 5</script> some math. With <script type="math/tex">1
++ 1</script> new line characters in between.</p>
+
+<p><script type="math/tex">5+5</script> inline math, $5.00 $$no math$$</p>
+
+<p>$$5+5$$ inline math</p>
+
+<p><script type="math/tex">5+5</script></p>
+
+<p>$$5+5$$</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/math/normal.text b/app/server/vendor/kramdown/test/testcases/span/math/normal.text
new file mode 100644
index 0000000..e37a007
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/math/normal.text
@@ -0,0 +1,10 @@
+This is $$\lambda_\alpha > 5$$ some math. With $$1
++ 1$$ new line characters in between.
+
+$$5+5$$ inline math, $5.00 \$$no math$$
+
+\$\$5+5$$ inline math
+
+\$$5+5$$
+
+\$\$5+5$$
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities.html b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities.html
new file mode 100644
index 0000000..96b3b5c
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities.html
@@ -0,0 +1,6 @@
+<p>This is the A&O. © 2008 by me
+As well \& as this. Some ŗ other
+values may &#xAF; may also show but
+not st. like &#xYZ;.</p>
+
+<p>This is BS&T; done!</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities.options b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities.options
new file mode 100644
index 0000000..036c561
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities.options
@@ -0,0 +1 @@
+:entity_output: :as_input
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities.text b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities.text
new file mode 100644
index 0000000..0446f4c
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities.text
@@ -0,0 +1,6 @@
+This is the A&O. © 2008 by me
+As well \& as this. Some ŗ other
+values may &#xAF; may also show but
+not st. like &#xYZ;.
+
+This is BS&T; done!
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_char.html b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_char.html
new file mode 100644
index 0000000..7507f75
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_char.html
@@ -0,0 +1 @@
+<p>This "is" 'the' A&O. © 2008 by me ŗ and &#x3bb;</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_char.html.19 b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_char.html.19
new file mode 100644
index 0000000..ed2817b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_char.html.19
@@ -0,0 +1 @@
+<p>This "is" 'the' A&O. © 2008 by me ŗ and λ</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_char.options b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_char.options
new file mode 100644
index 0000000..32a751e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_char.options
@@ -0,0 +1,2 @@
+:entity_output: :as_char
+:smart_quotes: apos,apos,quot,quot
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_char.text b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_char.text
new file mode 100644
index 0000000..279b511
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_char.text
@@ -0,0 +1 @@
+This "is" 'the' A&O. © 2008 by me ŗ and &#x3bb;
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_input.html b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_input.html
new file mode 100644
index 0000000..d2eec9d
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_input.html
@@ -0,0 +1 @@
+<p>This is the A&O. © 2008 by me ŗ and &#x3bb;</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_input.options b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_input.options
new file mode 100644
index 0000000..036c561
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_input.options
@@ -0,0 +1 @@
+:entity_output: :as_input
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_input.text b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_input.text
new file mode 100644
index 0000000..1ddf7cd
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_as_input.text
@@ -0,0 +1 @@
+This is the A&O. © 2008 by me ŗ and &#x3bb;
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_numeric.html b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_numeric.html
new file mode 100644
index 0000000..d04613e
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_numeric.html
@@ -0,0 +1 @@
+<p>This is the A&O. © 2008 by me ŗ and λ</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_numeric.options b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_numeric.options
new file mode 100644
index 0000000..2e6e0a1
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_numeric.options
@@ -0,0 +1 @@
+:entity_output: :numeric
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_numeric.text b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_numeric.text
new file mode 100644
index 0000000..1ddf7cd
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_numeric.text
@@ -0,0 +1 @@
+This is the A&O. © 2008 by me ŗ and &#x3bb;
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_symbolic.html b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_symbolic.html
new file mode 100644
index 0000000..258ba14
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_symbolic.html
@@ -0,0 +1 @@
+<p>This is the A&O. © 2008 by me ŗ and λ</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_symbolic.options b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_symbolic.options
new file mode 100644
index 0000000..c195785
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_symbolic.options
@@ -0,0 +1 @@
+:entity_output: :symbolic
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_symbolic.text b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_symbolic.text
new file mode 100644
index 0000000..1ddf7cd
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/entities_symbolic.text
@@ -0,0 +1 @@
+This is the A&O. © 2008 by me ŗ and &#x3bb;
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/greaterthan.html b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/greaterthan.html
new file mode 100644
index 0000000..dcce4cc
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/greaterthan.html
@@ -0,0 +1 @@
+<p>2 > 1 > 0</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/greaterthan.text b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/greaterthan.text
new file mode 100644
index 0000000..7dfb7f1
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/greaterthan.text
@@ -0,0 +1 @@
+2 > 1 > 0
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/lowerthan.html b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/lowerthan.html
new file mode 100644
index 0000000..8ebac23
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/lowerthan.html
@@ -0,0 +1 @@
+<p>0 < 1 < 2</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/lowerthan.text b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/lowerthan.text
new file mode 100644
index 0000000..038df8b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/lowerthan.text
@@ -0,0 +1 @@
+0 < 1 < 2
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/typography.html b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/typography.html
new file mode 100644
index 0000000..0effd5b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/typography.html
@@ -0,0 +1,30 @@
+<p>This is… something—this too–!</p>
+
+<p>This «is» some text, « this » too!</p>
+
+<p>“Fancy quotes” are ‘cool’, even in the ’80s!
+Je t’ aime. You’re a funny one! Thomas’ name
+Mark’s name. “…you”
+“‘Nested’ quotes are ‘possible’”, too!
+‘“Otherway” is “round”’!</p>
+
+<p>‘Opening now!’</p>
+
+<p>’80s are really cool.</p>
+
+<p><em>Cluster</em>’s Last Stand.</p>
+
+<p>Nam liber tempor
+“…At vero eos et accusam”</p>
+
+<p>“<em>Single underscores</em> should work.”</p>
+
+<p>“<em>Single asterisks</em> should work.”</p>
+
+<p>‘<strong>Double underscores</strong> should work.’</p>
+
+<p>‘<strong>Double asterisks</strong> should work.’</p>
+
+<p>“<em>Hurrah!</em>”</p>
+
+<p>‘<strong>Absolutely</strong>.’</p>
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/typography.options b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/typography.options
new file mode 100644
index 0000000..4f1c17c
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/typography.options
@@ -0,0 +1 @@
+:entity_output: symbolic
diff --git a/app/server/vendor/kramdown/test/testcases/span/text_substitutions/typography.text b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/typography.text
new file mode 100644
index 0000000..e4cdb41
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases/span/text_substitutions/typography.text
@@ -0,0 +1,30 @@
+This is... something---this too--!
+
+This <<is>> some text, << this >> too!
+
+"Fancy quotes" are 'cool', even in the '80s!
+Je t' aime. You're a funny one! Thomas' name
+Mark's name. "...you"
+"'Nested' quotes are 'possible'", too!
+'"Otherway" is "round"'!
+
+'Opening now!'
+
+'80s are really cool.
+
+<em>Cluster</em>'s Last Stand.
+
+Nam liber tempor
+"...At vero eos et accusam"
+
+"_Single underscores_ should work."
+
+"*Single asterisks* should work."
+
+'__Double underscores__ should work.'
+
+'**Double asterisks** should work.'
+
+"_Hurrah!_"
+
+'__Absolutely__.'
diff --git a/app/server/vendor/kramdown/test/testcases_gfm/atx_header.html b/app/server/vendor/kramdown/test/testcases_gfm/atx_header.html
new file mode 100644
index 0000000..776d7a1
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases_gfm/atx_header.html
@@ -0,0 +1,3 @@
+<h1>header</h1>
+
+<p>#no header</p>
diff --git a/app/server/vendor/kramdown/test/testcases_gfm/atx_header.text b/app/server/vendor/kramdown/test/testcases_gfm/atx_header.text
new file mode 100644
index 0000000..5e70e2b
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases_gfm/atx_header.text
@@ -0,0 +1,3 @@
+# header
+
+#no header
diff --git a/app/server/vendor/kramdown/test/testcases_gfm/backticks_disable_highlighting.html b/app/server/vendor/kramdown/test/testcases_gfm/backticks_disable_highlighting.html
new file mode 100644
index 0000000..8390d09
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases_gfm/backticks_disable_highlighting.html
@@ -0,0 +1,2 @@
+<pre><code class="language-ruby">Kramdown::Document.new(text, :input => 'GFM')
+</code></pre>
diff --git a/app/server/vendor/kramdown/test/testcases_gfm/backticks_disable_highlighting.options b/app/server/vendor/kramdown/test/testcases_gfm/backticks_disable_highlighting.options
new file mode 100644
index 0000000..72e9bc1
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases_gfm/backticks_disable_highlighting.options
@@ -0,0 +1 @@
+:enable_coderay: false
diff --git a/app/server/vendor/kramdown/test/testcases_gfm/backticks_disable_highlighting.text b/app/server/vendor/kramdown/test/testcases_gfm/backticks_disable_highlighting.text
new file mode 100644
index 0000000..98cf3a8
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases_gfm/backticks_disable_highlighting.text
@@ -0,0 +1,3 @@
+```ruby
+Kramdown::Document.new(text, :input => 'GFM')
+```
diff --git a/app/server/vendor/kramdown/test/testcases_gfm/backticks_syntax.html b/app/server/vendor/kramdown/test/testcases_gfm/backticks_syntax.html
new file mode 100644
index 0000000..3cac9f5
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases_gfm/backticks_syntax.html
@@ -0,0 +1,20 @@
+<pre><code>Three backticks
+</code></pre>
+
+<pre><code>Four backticks
+</code></pre>
+
+<pre><code>Unbalanced bottom heavy
+</code></pre>
+
+<div><div class="CodeRay">
+  <div class="code"><pre><span class="line-numbers"><a href="#n1" name="n1">1</a></span>language no space
+</pre></div>
+</div>
+</div>
+
+<div><div class="CodeRay">
+  <div class="code"><pre><span class="line-numbers"><a href="#n1" name="n1">1</a></span>language with space
+</pre></div>
+</div>
+</div>
diff --git a/app/server/vendor/kramdown/test/testcases_gfm/backticks_syntax.text b/app/server/vendor/kramdown/test/testcases_gfm/backticks_syntax.text
new file mode 100644
index 0000000..fb5c611
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases_gfm/backticks_syntax.text
@@ -0,0 +1,19 @@
+```
+Three backticks
+```
+
+````
+Four backticks
+````
+
+```
+Unbalanced bottom heavy
+``````
+
+````ruby
+language no space
+````
+
+```` ruby
+language with space
+````
diff --git a/app/server/vendor/kramdown/test/testcases_gfm/hard_line_breaks_off.html b/app/server/vendor/kramdown/test/testcases_gfm/hard_line_breaks_off.html
new file mode 100644
index 0000000..bec61d8
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases_gfm/hard_line_breaks_off.html
@@ -0,0 +1,2 @@
+<p>This is just a normal paragraph.
+Containing a line break.</p>
diff --git a/app/server/vendor/kramdown/test/testcases_gfm/hard_line_breaks_off.options b/app/server/vendor/kramdown/test/testcases_gfm/hard_line_breaks_off.options
new file mode 100644
index 0000000..f2da683
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases_gfm/hard_line_breaks_off.options
@@ -0,0 +1 @@
+:hard_wrap: false
diff --git a/app/server/vendor/kramdown/test/testcases_gfm/hard_line_breaks_off.text b/app/server/vendor/kramdown/test/testcases_gfm/hard_line_breaks_off.text
new file mode 100644
index 0000000..a9599cc
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases_gfm/hard_line_breaks_off.text
@@ -0,0 +1,2 @@
+This is just a normal paragraph.
+Containing a line break.
diff --git a/app/server/vendor/kramdown/test/testcases_gfm/two_para_hard_line_breaks.html b/app/server/vendor/kramdown/test/testcases_gfm/two_para_hard_line_breaks.html
new file mode 100644
index 0000000..a7470bc
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases_gfm/two_para_hard_line_breaks.html
@@ -0,0 +1,4 @@
+<p>This is just a normal paragraph.<br />
+Containing a line break.</p>
+
+<p>Another paragraph.</p>
diff --git a/app/server/vendor/kramdown/test/testcases_gfm/two_para_hard_line_breaks.text b/app/server/vendor/kramdown/test/testcases_gfm/two_para_hard_line_breaks.text
new file mode 100644
index 0000000..e152d5d
--- /dev/null
+++ b/app/server/vendor/kramdown/test/testcases_gfm/two_para_hard_line_breaks.text
@@ -0,0 +1,4 @@
+This is just a normal paragraph.
+Containing a line break.
+
+Another paragraph.
diff --git a/app/server/vendor/metaclass-0.0.4/.gitignore b/app/server/vendor/metaclass-0.0.4/.gitignore
new file mode 100755
index 0000000..4040c6c
--- /dev/null
+++ b/app/server/vendor/metaclass-0.0.4/.gitignore
@@ -0,0 +1,4 @@
+*.gem
+.bundle
+Gemfile.lock
+pkg/*
diff --git a/app/server/vendor/metaclass-0.0.4/COPYING.txt b/app/server/vendor/metaclass-0.0.4/COPYING.txt
new file mode 100755
index 0000000..86eb1ab
--- /dev/null
+++ b/app/server/vendor/metaclass-0.0.4/COPYING.txt
@@ -0,0 +1,21 @@
+== Licence (MIT)
+
+Copyright (c) 2011 James Mead
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/app/server/vendor/metaclass-0.0.4/Gemfile b/app/server/vendor/metaclass-0.0.4/Gemfile
new file mode 100755
index 0000000..c80ee36
--- /dev/null
+++ b/app/server/vendor/metaclass-0.0.4/Gemfile
@@ -0,0 +1,3 @@
+source "http://rubygems.org"
+
+gemspec
diff --git a/app/server/vendor/metaclass-0.0.4/README.md b/app/server/vendor/metaclass-0.0.4/README.md
new file mode 100755
index 0000000..561ce2f
--- /dev/null
+++ b/app/server/vendor/metaclass-0.0.4/README.md
@@ -0,0 +1,10 @@
+Adds a `__metaclass__` method to all Ruby objects.
+
+## Motivations
+
+* Even though WhyTheLuckyStiff's [metaid gem](https://rubygems.org/gems/metaid) does something similar, apparently the metaclass method without underscores [doesn't play well with Rails v2.3](https://github.com/floehopper/mocha/commit/f0749d6d291164cc9280aa8ba16f33d652d45fe1#commitcomment-475799).
+* I'm trying to extract code out of the [mocha gem](https://github.com/floehopper/mocha) and this is an obvious candidate.
+
+## License
+
+This library is released under the [MIT License](http://www.opensource.org/licenses/MIT). See [COPYING.txt](https://github.com/floehopper/metaclass/blob/master/COPYING.txt).
\ No newline at end of file
diff --git a/app/server/vendor/metaclass-0.0.4/Rakefile b/app/server/vendor/metaclass-0.0.4/Rakefile
new file mode 100755
index 0000000..0394630
--- /dev/null
+++ b/app/server/vendor/metaclass-0.0.4/Rakefile
@@ -0,0 +1,11 @@
+require 'bundler/gem_tasks'
+
+
+require "rake/testtask"
+Rake::TestTask.new do |t|
+  t.libs << "test"
+  t.test_files = FileList["test/**/*_test.rb"]
+  t.verbose = true
+end
+
+task :default => :test
diff --git a/app/server/vendor/metaclass-0.0.4/lib/metaclass.rb b/app/server/vendor/metaclass-0.0.4/lib/metaclass.rb
new file mode 100755
index 0000000..7e6b72f
--- /dev/null
+++ b/app/server/vendor/metaclass-0.0.4/lib/metaclass.rb
@@ -0,0 +1,5 @@
+module Metaclass
+end
+
+require "metaclass/version"
+require "metaclass/object_methods"
diff --git a/app/server/vendor/metaclass-0.0.4/lib/metaclass/object_methods.rb b/app/server/vendor/metaclass-0.0.4/lib/metaclass/object_methods.rb
new file mode 100755
index 0000000..ba6bd3b
--- /dev/null
+++ b/app/server/vendor/metaclass-0.0.4/lib/metaclass/object_methods.rb
@@ -0,0 +1,11 @@
+module Metaclass::ObjectMethods
+  def __metaclass__
+    class << self
+      self
+    end
+  end
+end
+
+class Object
+  include Metaclass::ObjectMethods
+end
\ No newline at end of file
diff --git a/app/server/vendor/metaclass-0.0.4/lib/metaclass/version.rb b/app/server/vendor/metaclass-0.0.4/lib/metaclass/version.rb
new file mode 100755
index 0000000..79ec9ce
--- /dev/null
+++ b/app/server/vendor/metaclass-0.0.4/lib/metaclass/version.rb
@@ -0,0 +1,3 @@
+module Metaclass
+  VERSION = "0.0.4"
+end
diff --git a/app/server/vendor/metaclass-0.0.4/metaclass.gemspec b/app/server/vendor/metaclass-0.0.4/metaclass.gemspec
new file mode 100755
index 0000000..3208ff8
--- /dev/null
+++ b/app/server/vendor/metaclass-0.0.4/metaclass.gemspec
@@ -0,0 +1,20 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "metaclass/version"
+
+Gem::Specification.new do |s|
+  s.name        = "metaclass"
+  s.version     = Metaclass::VERSION
+  s.authors     = ["James Mead"]
+  s.email       = ["james at floehopper.org"]
+  s.homepage    = "http://github.com/floehopper/metaclass"
+  s.summary     = %q{Adds a metaclass method to all Ruby objects}
+  s.license     = "MIT"
+
+  s.rubyforge_project = "metaclass"
+
+  s.files         = `git ls-files`.split("\n")
+  s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
+  s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+  s.require_paths = ["lib"]
+end
\ No newline at end of file
diff --git a/app/server/vendor/metaclass-0.0.4/test/object_methods_test.rb b/app/server/vendor/metaclass-0.0.4/test/object_methods_test.rb
new file mode 100755
index 0000000..b4d9c2a
--- /dev/null
+++ b/app/server/vendor/metaclass-0.0.4/test/object_methods_test.rb
@@ -0,0 +1,31 @@
+require "test_helper"
+
+class ObjectMethodsTest < Test::Unit::TestCase
+
+  def setup
+    @klass = Class.new
+  end
+
+  def test_define_method_on_only_one_instance_of_a_class
+    instance = @klass.new
+    assert_raises(NoMethodError) { instance.success? }
+
+    instance.__metaclass__.class_eval { def success?; true; end }
+    assert_nothing_raised(NoMethodError) { assert instance.success? }
+
+    another_instance = @klass.new
+    assert_raises(NoMethodError) { another_instance.success? }
+  end
+
+  def test_metaclass_ancestors
+    instance = @klass.new
+    assert instance.__metaclass__.ancestors.include?(Object)
+    assert instance.__metaclass__.ancestors.include?(Kernel)
+  end
+
+  def test_metaclass_is_itself_a_class
+    instance = @klass.new
+    assert instance.__metaclass__.is_a?(Class)
+  end
+
+end
\ No newline at end of file
diff --git a/app/server/vendor/metaclass-0.0.4/test/test_helper.rb b/app/server/vendor/metaclass-0.0.4/test/test_helper.rb
new file mode 100755
index 0000000..1573fa8
--- /dev/null
+++ b/app/server/vendor/metaclass-0.0.4/test/test_helper.rb
@@ -0,0 +1,5 @@
+require "rubygems"
+require "bundler/setup"
+
+require "metaclass"
+require "test/unit"
diff --git a/app/server/vendor/minitest-5.8.1/.autotest b/app/server/vendor/minitest-5.8.1/.autotest
new file mode 100644
index 0000000..b6fbce5
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/.autotest
@@ -0,0 +1,34 @@
+# -*- ruby -*-
+
+require 'autotest/restart'
+require 'autotest/rcov' if ENV['RCOV']
+
+Autotest.add_hook :initialize do |at|
+  at.testlib = 'minitest/autorun'
+
+  bench_tests = %w(TestMinitestBenchmark)
+  mock_tests = %w(TestMinitestMock TestMinitestStub)
+  spec_tests = %w(TestMinitestReporter TestMetaStatic TestMeta
+                  TestSpecInTestCase)
+  unit_tests = %w(TestMinitestGuard TestMinitestRunnable
+                  TestMinitestRunner TestMinitestTest TestMinitestUnit
+                  TestMinitestUnitInherited TestMinitestUnitOrder
+                  TestMinitestUnitRecording TestMinitestUnitTestCase)
+
+  {
+    bench_tests => "test/minitest/test_minitest_benchmark.rb",
+    mock_tests  => "test/minitest/test_minitest_mock.rb",
+    spec_tests  => "test/minitest/test_minitest_reporter.rb",
+    unit_tests  => "test/minitest/test_minitest_unit.rb",
+  }.each do |klasses, file|
+    klasses.each do |klass|
+      at.extra_class_map[klass] = file
+    end
+  end
+
+  at.add_exception 'coverage.info'
+  at.add_exception 'coverage'
+end
+
+# require 'autotest/rcov'
+# Autotest::RCov.command = 'rcov_info'
diff --git a/app/server/vendor/minitest-5.8.1/History.rdoc b/app/server/vendor/minitest-5.8.1/History.rdoc
new file mode 100644
index 0000000..81181d6
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/History.rdoc
@@ -0,0 +1,1137 @@
+=== 5.8.1 / 2015-09-23
+
+* 1 minor enhancement:
+
+  * Refactor assert_raises to be cleaner and to pass SystemExit and SignalException. (bhenderson)
+
+=== 5.8.0 / 2015-08-06
+
+* 2 minor enhancements:
+
+  * Add optional delegation mechanism to extend object with a mock. (zamith)
+  * Return early if there are no filtered methods. (jeremyevans)
+
+* 1 bug fix:
+
+  * Don't extend io with pride if io is not a tty. (toy)
+
+=== 5.7.0 / 2015-05-27
+
+* 1 major enhancement:
+
+  * assert_raises now matches subclasses of the expected exception types. (jeremyevans)
+
+* 3 minor enhancements:
+
+  * Added :block type for minitest/spec's #infect_an_assertion. (jeremyevans)
+  * Inline verification error messages in minitest/mock for GC performance. (zamith)
+  * assert_raises defaults to RuntimeError if not specified. (jeremyevans)
+
+* 4 bug fixes:
+
+  * Added 'class' to minitest/mock's overridden_methods list. (zamith)
+  * Added file/line to infect_an_assertion's class_eval call. (jeremyevans)
+  * Cleared UnexpectedError's mesg w/ generic string.
+  * Fixed non-proc-oriented expectations when used on proc target. (jeremyevans)
+
+=== 5.6.1 / 2015-04-27
+
+* 2 bug fixes:
+
+  * Added Minitest.clock_time and switched all Time.now to it. (tenderlove)
+  * Moved Minitest::Expectations#_ into Minitest::Spec::DSL.
+
+=== 5.6.0 / 2015-04-13
+
+* 4 major enhancements:
+
+  * Added Minitest::Expectation value monad.
+  * Added Minitest::Expectations#_ that returns an Expectation. Aliased to value.
+  * All expectations are added to Minitest::Expectation.
+  * At some point, the methods on Object will be deprecated and then removed.
+
+* 4 minor enhancements:
+
+  * Added a note about bundle exec pitfall in ruby 2.2+. (searls)
+  * Lazily start the parallel executor. (tenderlove)
+  * Make mocks more debugger-friendly (edward)
+  * Print out the current test run on interrupt. (riffraff)
+
+* 3 bug fixes:
+
+  * Fix failing test under Windows. (kimhmadsen)
+  * Record mocked calls before they happen so mocks can raise exceptions easier (tho I'm not a fan). (corecode)
+  * Tried to clarify mocks vs stubs terminology better. (kkirsche)
+
+=== 5.5.1 / 2015-01-09
+
+* 1 bug fix:
+
+  * Fixed doco problems. (zzak)
+
+=== 5.5.0 / 2014-12-12 // mri 2.2.0 (as a real gem)
+
+* 1 minor enhancement:
+
+  * Allow seed to be given via ENV for rake test loader sadness: eg rake SEED=42.
+
+=== 5.4.3 / 2014-11-11
+
+* 2 bug fixes:
+
+  * Clarified requirements for ruby are now 1.8.7 or better.
+  * Force encode error output in case mal-encoded exception is raised. (jasonrclark)
+
+=== 5.4.2 / 2014-09-26
+
+* 2 minor enhancements:
+
+  * Extract teardown method list.
+  * Thanks to minitest-gcstats got a 5-10% speedup via reduced GC!
+
+=== 5.4.1 / 2014-08-28
+
+* 1 bug fix:
+
+  * Fixed specs hidden by nesting/ordering bug (blowmage/apotonick)
+
+=== 5.4.0 / 2014-07-07
+
+* 2 minor enhancements:
+
+  * Kernel#describe extended to splat additional_desc.
+  * Spec#spec_type extended to take a splat of additional items, passed to matcher procs.
+
+* 1 bug fix:
+
+  * minitest/spec should require minitest/test, not minitest/unit. (doudou)
+
+=== 5.3.5 / 2014-06-17
+
+* 1 minor enhancement:
+
+  * Spit and polish (mostly spit).
+
+=== 5.3.4 / 2014-05-15
+
+* 1 minor enhancement:
+
+  * Test classes are randomized before running. (judofyr)
+
+=== 5.3.3 / 2014-04-14
+
+* 1 bug fix:
+
+  * Fixed using expectations w/ DSL in Test class w/o describe. (blowmage+others)
+
+=== 5.3.2 / 2014-04-02
+
+* 1 bug fix:
+
+  * Fixed doco on Assertions.assertions. (xaviershay)
+
+=== 5.3.1 / 2014-03-14
+
+* 1 minor enhancement:
+
+  * Modified verbage on bad 'let' names to be more helpful. (Archytaus)
+
+* 1 bug fix:
+
+  * Fixed 2 cases still using MiniTest. (mikesea)
+
+=== 5.3.0 / 2014-02-25
+
+* 1 minor enhancement:
+
+  * Mocked methods can take a block to verify state. Seattle.rb 12 bday present from ernie! Thanks!!
+
+=== 5.2.3 / 2014-02-10
+
+* 1 bug fix:
+
+  * Fixed Spec#let check to allow overriding of other lets. (mvz)
+
+=== 5.2.2 / 2014-01-22
+
+* 1 minor enhancement:
+
+  * Spec#let raises ArgumentError if you override _any_ instance method (except subject). (rynr)
+
+* 1 bug fix:
+
+  * Fixed up benchmark spec doco and added a test to demonstrate. (bhenderson)
+
+=== 5.2.1 / 2014-01-07
+
+* 1 bug fix:
+
+  * Properly deal with horrible mix of runtime load errors + other at_exit handlers. (dougo/chqr)
+
+=== 5.2.0 / 2013-12-13
+
+* 1 minor enhancement:
+
+  * Change expectations to allow calling most on procs (but not calling the proc). (bhenderson+others)
+
+=== 5.1.0 / 2013-12-05
+
+* 1 minor enhancement:
+
+  * Use a Queue for scheduling parallel tests. (tenderlove)
+
+* 1 bug fix:
+
+  * Fixed misspelling in doco. (amatsuda)
+
+=== 5.0.8 / 2013-09-20
+
+* 1 bug fix:
+
+  * Fixed siginfo handler by rearranging reporters and fixing to_s. (tenderlove)
+
+=== 5.0.7 / 2013-09-05
+
+* 2 minor enhancements:
+
+  * Added clarification about the use of thread local variables in expectations. (jemc)
+  * Added extra message about skipped tests, if any. Disable globally with $MT_NO_SKIP_MSG.
+
+* 2 bug fixes:
+
+  * Only require minitest, not minitest/autorun in pride_plugin. (judofyr)
+  * Require rubygems in load_plugins in case you're not using minitest/autorun.
+
+=== 5.0.6 / 2013-06-28
+
+* 3 minor enhancements:
+
+  * Allow stub to pass args to blocks. (swindsor)
+  * Improved warning message about minitest/autorun to address 1.9's minitest/autorun.
+  * Made minitest/test require minitest as needed. For lib writers. (erikh)
+
+* 1 bug fix:
+
+  * Fixed missing require in minitest/test. (erikh)
+
+=== 4.7.5 / 2013-06-21 // mri 2.1.1
+
+* 2 bug fixes:
+
+  * Fix Spec#describe_stack to be thread local.
+  * Fix multithreaded test failures by defining Time local to mock test namespace
+
+=== 5.0.5 / 2013-06-20
+
+* 6 bug fixes:
+
+  * DOH! Fixed the rest of the new casing on Minitest. (splattael)
+  * Fixed typo on minitest/mock rdoc. (mrgilman/guiceolin)
+  * Make Spec::DSL.describe_stack thread local to avoid failing on my own tests.
+  * Make a fake Time.now local to the tests so they won't interfere with real reporter timings.
+  * Make everything mockable by wrapping all 'special' methods in a smarter wrapper. (bestie)
+  * Raise ArgumentError if let name starts with 'test'. (johnmaxwell)
+
+=== 5.0.4 / 2013-06-07
+
+* 5 minor enhancements:
+
+  * Added AbstractReporter, defining required Reporter API to quack properly.
+  * Added doco for writing reporters.
+  * Refactored Reporter into ProgressReporter and SummaryReporter. (idea: phiggins, code:me+scotch)
+  * Refactored SummaryReporter pushing up to StatisticsReporter. (phiggins)
+  * Removed Reporter#run_and_report... cleaner, but doesn't "fit" in the API.
+
+=== 5.0.3 / 2013-05-29
+
+* 4 minor enhancements:
+
+  * Added Runnable.with_info_handler and Runnable.on_signal.
+  * Moved io.sync restore to Reporter#run_and_report.
+  * Refactored inner loop of Reporter#report to #to_s. Callable for status updates.
+  * Restored MT4's mid-run report (^t). (tenderlove).
+
+=== 5.0.2 / 2013-05-20
+
+* 3 bug fixes:
+
+  * Gem.find_files is smarter than I remember... cause I wrote it that way. *sigh* I'm getting old.
+  * Pride wasn't doing puts through its #io. (tmiller/tenderlove)
+  * Replaced Runnable#dup and Test#dup with marshal_dump/load. Too many problems cropping up on untested rails code. (tenderlove/rubys)
+
+=== 5.0.1 / 2013-05-14
+
+* 2 bug fixes:
+
+  * Documented Assertions' need for @assertions to be defined by the includer.
+  * Only load one plugin version per name. Tries for latest.
+
+=== 5.0.0 / 2013-05-10
+
+Oh god... here we go...
+
+Minitest 5:
+
+* 4 deaths in the family:
+
+  * MiniTest.runner is dead. No more manager objects.
+  * MiniTest::Unit#record is dead. Use a Reporter instance instead.
+  * MiniTest::Unit._run_* is dead. Runnable things are responsible for their own runs.
+  * MiniTest::Unit.output is dead. No more centralized IO.
+
+* 12 major (oft incompatible) changes:
+
+  * Renamed MiniTest to Minitest. Your pinkies will thank me. (aliased to MiniTest)
+  * Removed MiniTest::Unit entirely. No more manager objects.
+  * Added Minitest::Runnable. Everything minitest can run subclasses this.
+  * Renamed MiniTest::Unit::TestCase to Minitest::Test (subclassing Runnable).
+  * Added Minitest::Benchmark.
+    * Your benchmarks need to move to their own subclass.
+    * Benchmarks using the spec DSL have to have "Bench" somewhere in their describe.
+  * MiniTest::Unit.after_tests moved to Minitest.after_tests
+  * MiniTest::Unit.autorun is now Minitest.autorun. Just require minitest/autorun pls.
+  * Removed ParallelEach#grep since it isn't used anywhere.
+  * Renamed Runnable#__name__ to Runnable#name (but uses @NAME internally).
+  * Runnable#run needs to return self. Allows for swapping of results as needed.
+
+* 8 minor moves:
+
+  * Moved Assertions module to minitest/assertions.rb
+  * Moved Expectations module to minitest/expectations.rb
+  * Moved Test to minitest/test.rb
+  * Moved everything else in minitest/unit.rb to minitest.rb
+  * minitest/unit.rb is now just a small (user-test only) compatibility layer.
+  * Moved most of minitest/pride into minitest/pride_plugin.
+  * minitest/pride now just activates pride.
+  * Moved ParallelEach under Minitest.
+
+* 9 additions:
+
+  * Added a plugin system that can extend command-line options.
+  * Added Minitest.extensions.
+  * Added Minitest.reporter (only available during startup).
+  * Added Minitest.run(args). This is the very top of any Minitest run.
+  * Added Minitest::Reporter. Everything minitest can report goes through here.
+    * Minitest.reporter is a composite so you can add your own.
+  * Added Minitest::CompositeReporter. Much easier to extend with your own reporters.
+  * Added UnexpectedError, an Assertion subclass, to wrap up errors.
+  * Minitest::Test#run is now freakin' beautiful. 47 -> 17 loc
+
+* 11 other:
+
+  * Removed Object.infect_with_assertions (it was already dead code).
+  * Runnables are responsible for knowing their result_code (eg "." or "F").
+  * Minitest.autorun now returns boolean, not exit code.
+  * Added FAQ entry for extending via modules. (phiggins)
+  * Implement Runnable#dup to cleanse state back to test results. Helps with serialization. pair:tenderlove
+  * Moved ParallelEach under Minitest.
+  * Runnable#run needs to return self. Allows for swapping of results as needed.
+  * Minitest.init_plugins passes down options.
+  * Minitest.load_plugins only loads once.
+  * Fixed minitest/pride to work with rake test loader again. (tmiller)
+  * Added count/size to ParallelEach to fix use w/in stdlib's test/unit. :( (btaitelb)
+
+* 5 voodoo:
+
+  * Removed mutex from minitest.rb (phiggins)
+  * Removed mutex from test.rb (phiggins)
+  * Removed Minitest::Reporter.synchronize (phiggins)
+  * Removed Minitest::Test.synchronize (phiggins)
+  * Upon loading minitest/parallel_each, record, capture_io and capture_subprocess_io are doped with synchronization code. (phiggins)
+
+=== 4.7.4 / 2013-05-01
+
+This is probably the last release of the 4.x series. It will be merged
+to ruby and will be put into maintenance mode there.
+
+I'm not set in stone on this, but at this point further development of
+minitest (5+) will be gem-only. It is just too hard to work w/in
+ruby-core w/ test-unit compatibility holding minitest development
+back.
+
+* 2 minor enhancements:
+
+  * Added count/size to ParallelEach to fix use w/in stdlib's test/unit. :( (btaitelb)
+  * Allow disabling of info_signal handler in runner. (erikh)
+
+=== 4.7.3 / 2013-04-20
+
+* 1 bug fix:
+
+  * Reverted stubbing of module methods change. Stub the user, not the impl. (ab9/tyabe)
+
+=== 4.7.2 / 2013-04-18
+
+* 2 bug fixes:
+
+  * Fixed inconsistency in refute_in_delta/epsilon. I double negatived my logic. (nettsundere)
+  * Fixed stubbing of module methods (eg Kernel#sleep). (steveklabnik)
+
+=== 4.7.1 / 2013-04-09
+
+* 1 minor enhancement:
+
+  * Added FAQ section to README
+
+* 1 bug fix:
+
+  * Fixed bug where guard runs tests bypassing minitest/autorun and an ivar isn't set right. (darrencauthon)
+
+=== 4.7.0 / 2013-03-18
+
+* 1 major enhancement:
+
+  * Refactored MiniTest::Spec into MiniTest::Spec::DSL.
+
+* 1 bug fix:
+
+  * Removed $DEBUG handler that detected when test/unit and minitest were both loaded. (tenderlove)
+
+=== 4.6.2 / 2013-02-27
+
+* 1 minor enhancement:
+
+  * Change error output to match Class#method, making it easier to use -n filter.
+
+=== 4.6.1 / 2013-02-14
+
+* 1 bug fix:
+
+  * Fixed an option processing bug caused by test/unit's irresponsibly convoluted code. (floehopper)
+
+=== 4.6.0 / 2013-02-07
+
+* 3 major enhancements:
+
+  * Removed ::reset_setup_teardown_hooks
+  * Removed the long deprecated assert_block
+  * Removed the long deprecated lifecycle hooks: add_(setup|teardown)_hook
+
+* 1 minor enhancement:
+
+  * Allow filtering tests by suite name as well as test name. (lazyatom)
+
+* 2 bug fixes:
+
+  * Made hex handling (eg object_ids) in mu_pp_for_diff more specific. (maxim)
+  * nodoc top-level module. (zzak)
+
+=== 4.5.0 / 2013-01-22
+
+* 1 major enhancement:
+
+  * Rearranged minitest/unit.rb so NO parallelization code is loaded/used until you opt-in.
+
+* 4 minor enhancements:
+
+  * Added TestCase#skipped? for teardown guards
+  * Added maglev? guard
+  * Document that record can be sent twice if teardown fails or errors (randycoulman)
+  * Errors in teardown are now recorded. (randycoulman)
+
+* 3 bug fixes:
+
+  * Added hacks and skips to get clean test runs on maglev
+  * Modified float tests for maglev float output differences. Not sure this is right. Not sure I care.
+  * Test for existance of diff.exe instead of assuming they have devkit. (blowmage/Cumbayah)
+
+=== 4.4.0 / 2013-01-07
+
+* 3 minor enhancements:
+
+  * Added fit_logarithic and assert_performance_logarithmic. (ktheory)
+  * Merge processed options so others can mess with defaults. (tenderlove)
+  * TestCase#message can now take another proc to defer custom message cost. (ordinaryzelig/bhenderson)
+
+* 1 bug fix:
+
+  * TestCase#passed? now true if test is skipped. (qanhd)
+
+=== 4.3.3 / 2012-12-06
+
+* 1 bug fix:
+
+  * Updated information about stubbing. (daviddavis)
+
+=== 4.3.2 / 2012-11-27 // mri 2.0.0
+
+* 1 minor enhancement:
+
+  * Improved assert_equals error message to point you at #== of member objects. (kcurtin)
+
+=== 4.3.1 / 2012-11-23
+
+* 1 bug fix:
+
+  * Moved test_children to serial testcase to prevent random failures.
+
+=== 4.3.0 / 2012-11-17
+
+* 4 minor enhancements:
+
+  * Allow #autorun to run even if loaded with other test libs that call exit. (sunaku)
+  * Do not include Expectations in Object if $MT_NO_EXPECTATIONS is set (experimental?)
+  * Gave some much needed love to assert_raises.
+  * Mock#expect can take a block to custom-validate args. (gmoothart)
+
+=== 4.2.0 / 2012-11-02
+
+* 4 major enhancements:
+
+  * Added minitest/hell - run all your tests through the ringer!
+  * Added support for :parallel test_order to run test cases in parallel.
+  * Removed last_error and refactored runner code to be threadsafe.
+  * _run_suites now runs suites in parallel if they opt-in.
+
+* 4 minor enhancements:
+
+  * Added TestCase#synchronize
+  * Added TestCase.make_my_diffs_pretty!
+  * Added TestCase.parallelize_me!
+  * Lock on capture_io for thread safety (tenderlove)
+
+=== 4.1.0 / 2012-10-05
+
+* 2 minor enhancements:
+
+  * Added skip example to readme. (dissolved)
+  * Extracted backtrace filter to object. (tenderlove)
+
+* 1 bug fix:
+
+  * OMG I'm so dumb. Fixed access to deprecated hook class methods. I hate ruby modules. (route)
+
+=== 4.0.0 / 2012-09-28
+
+* 1 major enhancement:
+
+  * The names of a privately-used undocumented constants are Super Importantâ„¢.
+
+* 1 minor enhancement:
+
+  * Support stubbing methods that would be handled via method_missing. (jhsu)
+
+* 3 bug fixes:
+
+  * Add include_private param to MiniTest::Mock#respond_to? (rf-)
+  * Fixed use of minitest/pride with --help. (zw963)
+  * Made 'No visible difference.' message more clear. (ckrailo)
+
+=== 3.5.0 / 2012-09-21
+
+* 1 minor enhancement:
+
+  * Added #capture_subprocess_io. (route)
+
+=== 3.4.0 / 2012-09-05
+
+* 2 minor enhancements:
+
+  * assert_output can now take regexps for expected values. (suggested by stomar)
+  * Clarified that ruby 1.9/2.0's phony gems cause serious confusion for rubygems.
+
+=== 3.3.0 / 2012-07-26
+
+* 1 major enhancement:
+
+  * Deprecated add_(setup|teardown)_hook in favor of (before|after)_(setup|teardown) [2013-01-01]
+
+* 4 minor enhancements:
+
+  * Refactored deprecated hook system into a module.
+  * Refactored lifecycle hooks into a module.
+  * Removed after_setup/before_teardown + run_X_hooks from Spec.
+  * Spec#before/after now do a simple define_method and call super. DUR.
+
+* 2 bug fixes:
+
+  * Fixed #passed? when used against a test that called flunk. (floehopper)
+  * Fixed rdoc bug preventing doco for some expectations. (stomar).
+
+=== 3.2.0 / 2012-06-26
+
+* 1 minor enhancement:
+
+  * Stubs now yield self. (peterhellberg)
+
+* 1 bug fix:
+
+  * Fixed verbose test that only fails when run in verbose mode. mmmm irony.
+
+=== 3.1.0 / 2012-06-13
+
+* 2 minor enhancements:
+
+  * Removed LONG deprecated Unit.out accessor
+  * Removed generated method name munging from minitest/spec. (ordinaryzelig/tenderlove)
+
+=== 3.0.1 / 2012-05-24
+
+* 1 bug fix:
+
+  * I'm a dumbass and refactored into Mock#call. Renamed to #__call so you can mock #call. (mschuerig)
+
+=== 3.0.0 / 2012-05-08
+
+* 3 major enhancements:
+
+  * Added Object#stub (in minitest/mock.rb).
+  * Mock#expect mocks are used in the order they're given.
+  * Mock#verify now strictly compares against expect calls.
+
+* 3 minor enhancements:
+
+  * Added caller to deprecation message.
+  * Mock error messages are much prettier.
+  * Removed String check for RHS of assert/refute_match. This lets #to_str work properly.
+
+* 1 bug fix:
+
+  * Support drive letter on Windows. Patch provided from MRI by Usaku NAKAMURA. (ayumin)
+
+=== 2.12.1 / 2012-04-10
+
+* 1 minor enhancement:
+
+  * Added ruby releases to History.txt to make it easier to see what you're missing
+
+* 1 bug fix:
+
+  * Rolled my own deprecate msg to allow MT to work with rubygems < 1.7
+
+=== 2.12.0 / 2012-04-03
+
+* 4 minor enhancements:
+
+  * ::it returns test method name (wojtekmach)
+  * Added #record method to runner so runner subclasses can cleanly gather data.
+  * Added Minitest alias for MiniTest because even I forget.
+  * Deprecated assert_block!! Yay!!!
+
+* 1 bug fix:
+
+  * Fixed warning in i_suck_and_my_tests_are_order_dependent! (phiggins)
+
+=== 2.11.4 / 2012-03-20
+
+* 2 minor enhancements:
+
+  * Updated known extensions
+  * You got your unicode in my tests! You got your tests in my unicode! (fl00r)
+
+* 1 bug fix:
+
+  * Fixed MiniTest::Mock example in the readme. (conradwt)
+
+=== 2.11.3 / 2012-02-29
+
+* 2 bug fixes:
+
+  * Clarified that assert_raises returns the exception for further testing
+  * Fixed assert_in_epsilon when both args are negative. (tamc)
+
+=== 2.11.2 / 2012-02-14
+
+* 1 minor enhancement:
+
+  * Display failures/errors on SIGINFO. (tenderlove)
+
+* 1 bug fix:
+
+  * Fixed MiniTest::Unit.after_tests for Ruby 1.9.3. (ysbaddaden)
+
+=== 2.11.1 / 2012-02-01
+
+* 3 bug fixes:
+
+  * Improved description for --name argument. (drd)
+  * Ensure Mock#expect's expected args is an Array. (mperham)
+  * Ensure Mock#verify verifies multiple expects of the same method. (chastell)
+
+=== 2.11.0 / 2012-01-25
+
+* 2 minor enhancements:
+
+  * Added before / after hooks for setup and teardown. (tenderlove)
+  * Pushed run_setup_hooks down to Spec. (tenderlove)
+
+=== 2.10.1 / 2012-01-17
+
+* 1 bug fix:
+
+  * Fixed stupid 1.9 path handling grumble grumble. (graaff)
+
+=== 2.10.0 / 2011-12-20
+
+* 3 minor enhancements:
+
+  * Added specs for must/wont be_empty/respond_to/be_kind_of and others.
+  * Added tests for assert/refute predicate.
+  * Split minitest/excludes.rb out to its own gem.
+
+* 1 bug fix:
+
+  * Fixed must_be_empty and wont_be_empty argument handling. (mrsimo)
+
+=== 2.9.1 / 2011-12-13
+
+* 4 minor enhancements:
+
+  * Added a ton of tests on spec error message output.
+  * Cleaned up consistency of msg handling on unary expectations.
+  * Improved error messages on assert/refute_in_delta.
+  * infect_an_assertion no longer checks arity and better handles args.
+
+* 1 bug fix:
+
+  * Fixed error message on specs when 2+ args and custom message provided. (chastell)
+
+=== 2.9.0 / 2011-12-07
+
+* 4 minor enhancements:
+
+  * Added TestCase.exclude and load_excludes for programmatic filtering of tests.
+  * Added guard methods so you can cleanly skip based on platform/impl
+  * Holy crap! 100% doco! `rdoc -C` ftw
+  * Switch assert_output to test stderr before stdout to possibly improve debugging
+
+=== 2.8.1 / 2011-11-17
+
+* 1 bug fix:
+
+  * Ugh. 1.9's test/unit violates my internals. Added const_missing.
+
+=== 2.8.0 / 2011-11-08
+
+* 2 minor enhancements:
+
+  * Add a  method so that code can be run around a particular test case (tenderlove)
+  * Turn off backtrace filtering if we're running inside a ruby checkout. (drbrain)
+
+* 2 bug fixes:
+
+  * Fixed 2 typos and 2 doc glitches. (splattael)
+  * Remove unused block arguments to avoid creating Proc objects. (k-tsj)
+
+=== 2.7.0 / 2011-10-25
+
+* 2 minor enhancements:
+
+  * Include failed values in the expected arg output in MockExpectationError. (nono)
+  * Make minitest/pride work with other 256 color capable terms. (sunaku)
+
+* 2 bug fixes:
+
+  * Clarified the documentation of minitest/benchmark (eregon)
+  * Fixed using expectations in regular unit tests. (sunaku)
+
+=== 2.6.2 / 2011-10-19
+
+* 1 minor enhancement:
+
+  * Added link to vim bundle. (sunaku)
+
+* 2 bug fixes:
+
+  * Force gem activation in hoe minitest plugin
+  * Support RUBY_VERSION='2.0.0' (nagachika)
+
+=== 2.6.1 / 2011-09-27
+
+* 2 bug fixes:
+
+  * Alias Spec.name from Spec.to_s so it works when @name is nil (nathany)
+  * Fixed assert and refute_operator where second object has a bad == method.
+
+=== 2.6.0 / 2011-09-13
+
+* 2 minor enhancements:
+
+  * Added specify alias for it and made desc optional.
+  * Spec#must_be and #wont_be can be used with predicates (metaskills)
+
+* 1 bug fix:
+
+  * Fixed Mock.respond_to?(var) to work with strings. (holli)
+
+=== 2.5.1 / 2011-08-27 // ruby 1.9.3: p0, p125, p34579
+
+* 2 minor enhancements:
+
+  * Added gem activation for minitest in minitest/autoload to help out 1.9 users
+  * Extended Spec.register_spec_type to allow for procs instead of just regexps.
+
+=== 2.5.0 / 2011-08-18
+
+* 4 minor enhancements:
+
+  * Added 2 more arguments against rspec: let & subject in 9 loc! (emmanuel/luis)
+  * Added TestCase.i_suck_and_my_tests_are_order_dependent!
+  * Extended describe to take an optional method name (2 line change!). (emmanuel)
+  * Refactored and extended minitest/pride to do full 256 color support. (lolcat)
+
+* 1 bug fix:
+
+  * Doc fixes. (chastell)
+
+=== 2.4.0 / 2011-08-09
+
+* 4 minor enhancements:
+
+  * Added simple examples for all expectations.
+  * Improved Mock error output when args mismatch.
+  * Moved all expectations from Object to MiniTest::Expectations.
+  * infect_with_assertions has been removed due to excessive clever
+
+* 4 bug fixes:
+
+  * Fix Assertions#mu_pp to deal with immutable encoded strings. (ferrous26)
+  * Fix minitest/pride for MacRuby (ferrous26)
+  * Made error output less fancy so it is more readable
+  * Mock shouldn't undef === and inspect. (dgraham)
+
+=== 2.3.1 / 2011-06-22
+
+* 1 bug fix:
+
+  * Fixed minitest hoe plugin to be a spermy dep and not depend on itself.
+
+=== 2.3.0 / 2011-06-15
+
+* 5 minor enhancements:
+
+  * Add setup and teardown hooks to MiniTest::TestCase. (phiggins)
+  * Added nicer error messages for MiniTest::Mock. (phiggins)
+  * Allow for less specific expected arguments in Mock. (bhenderson/phiggins)
+  * Made MiniTest::Mock a blank slate. (phiggins)
+  * Refactored minitest/spec to use the hooks instead of define_inheritable_method. (phiggins)
+
+* 2 bug fixes:
+
+  * Fixed TestCase's inherited hook. (dchelimsky/phiggins/jamis, the 'good' neighbor)
+  * MiniTest::Assertions#refute_empty should use mu_pp in the default message. (whatthejeff)
+
+=== 2.2.2 / 2011-06-01
+
+* 2 bug fixes:
+
+  * Got rid of the trailing period in message for assert_equal. (tenderlove)
+  * Windows needs more flushing. (Akio Tajima)
+
+=== 2.2.1 / 2011-05-31
+
+* 1 bug fix:
+
+  * My _ONE_ non-rubygems-using minitest user goes to Seattle.rb!
+
+=== 2.2.0 / 2011-05-29
+
+* 6 minor enhancements:
+
+  * assert_equal (and must_equal) now tries to diff output where it makes sense.
+    * Added Assertions#diff(exp, act) to be used by assert_equal.
+    * Added Assertions#mu_pp_for_diff
+    * Added Assertions.diff and diff=
+  * Moved minitest hoe-plugin from hoe-seattlerb. (erikh)
+  * Skipped tests only output details in verbose mode. (tenderlove+zenspider=xoxo)
+
+=== 2.1.0 / 2011-04-11
+
+* 5 minor enhancements:
+
+  * Added MiniTest::Spec.register_spec_type(matcher, klass) and spec_type(desc)
+  * Added ability for specs to share code via subclassing of Spec. (metaskills)
+  * Clarified (or tried to) bench_performance_linear's use of threshold.
+  * MiniTest::Unit.runner=(runner) provides an easy way of creating custom test runners for specialized needs. (justinweiss)
+  * Reverse order of inheritance in teardowns of specs. (deepfryed)
+
+* 3 bug fixes:
+
+  * FINALLY fixed problems of inheriting specs in describe/it/describe scenario. (MGPalmer)
+  * Fixed a new warning in 1.9.3.
+  * Fixed assert_block's message handling. (nobu)
+
+=== 2.0.2 / 2010-12-24
+
+* 1 minor enhancement:
+
+  * Completed doco on minitest/benchmark for specs.
+
+* 1 bug fix:
+
+  * Benchmarks in specs that didn't call bench_range would die. (zzak).
+
+=== 2.0.1 / 2010-12-15
+
+* 4 minor enhancements:
+
+  * Do not filter backtrace if $DEBUG
+  * Exit autorun via nested at_exit handler, in case other libs call exit
+  * Make options accesor lazy.
+  * Split printing of test name and its time. (nurse)
+
+* 1 bug fix:
+
+  * Fix bug when ^T is hit before runner start
+
+=== 2.0.0 / 2010-11-11
+
+* 3 major enhancements:
+
+  * Added minitest/benchmark! Assert your performance! YAY!
+  * Refactored runner to allow for more extensibility. See minitest/benchmark.
+  * This makes the runner backwards incompatible in some ways!
+
+* 9 minor enhancements:
+
+  * Added MiniTest::Unit.after_tests { ... }
+  * Improved output by adding test rates and a more sortable verbose format
+  * Improved readme based on feedback from others
+  * Added io method to TestCase. If used, it'll supplant '.EF' output.
+  * Refactored IO in MiniTest::Unit.
+  * Refactored _run_anything to _run_suite to make it easier to wrap (ngauthier)
+  * Spec class names are now the unmunged descriptions (btakita)
+  * YAY for not having redundant rdoc/readmes!
+  * Help output is now generated from the flags you passed straight up.
+
+* 4 bug fixes:
+
+  * Fixed scoping issue on minitest/mock (srbaker/prosperity)
+  * Fixed some of the assertion default messages
+  * Fixes autorun when on windows with ruby install on different drive (larsch)
+  * Fixed rdoc output bug in spec.rb
+
+=== 1.7.2 / 2010-09-23
+
+* 3 bug fixes:
+
+  * Fixed doco for expectations and Spec.
+  * Fixed test_capture_io on 1.9.3+ (sora_h)
+  * assert_raises now lets MiniTest::Skip through. (shyouhei)
+
+=== 1.7.1 / 2010-09-01
+
+* 1 bug fix:
+
+  * 1.9.2 fixes for spec tests
+
+=== 1.7.0 / 2010-07-15
+
+* 5 minor enhancements:
+
+  * Added assert_output (mapped to must_output).
+  * Added assert_silent (mapped to must_be_silent).
+  * Added examples to readme (Mike Dalessio)
+  * Added options output at the top of the run, for fatal run debugging (tenderlove)
+  * Spec's describe method returns created class
+
+=== 1.6.0 / 2010-03-27 // ruby 1.9.2-p290
+
+* 10 minor enhancements:
+
+  * Added --seed argument so you can reproduce a random order for debugging.
+  * Added documentation for assertions
+  * Added more rdoc and tons of :nodoc:
+  * Added output to give you all the options you need to reproduce that run.
+  * Added proper argument parsing to minitest.
+  * Added unique serial # to spec names so order can be preserved (needs tests). (phrogz)
+  * Empty 'it' fails with default msg. (phrogz)
+  * Remove previous method on expect to remove 1.9 warnings
+  * Spec#it is now order-proof wrt subclasses/nested describes.
+  * assert_same error message now reports in decimal, eg: oid=123. (mattkent)
+
+* 2 bug fixes:
+
+  * Fixed message on refute_same to be consistent with assert_same.
+  * Fixed method randomization to be stable for testing.
+
+=== 1.5.0 / 2010-01-06
+
+* 4 minor enhancements:
+
+  * Added ability to specify what assertions should have their args flipped.
+  * Don't flip arguments on *include and *respond_to assertions.
+  * Refactored Module.infect_an_assertion from Module.infect_with_assertions.
+  * before/after :all now bitches and acts like :each
+
+* 3 bug fixes:
+
+  * Nested describes now map to nested test classes to avoid namespace collision.
+  * Using undef_method instead of remove_method to clean out inherited specs.
+  * assert_raises was ignoring passed in message.
+
+=== 1.4.2 / 2009-06-25
+
+* 1 bug fix:
+
+  * Fixed info handler for systems that don't have siginfo.
+
+=== 1.4.1 / 2009-06-23
+
+* 1 major enhancement:
+
+  * Handle ^C and other fatal exceptions by failing
+
+* 1 minor enhancement:
+
+  * Added something to catch mixed use of test/unit and minitest if $DEBUG
+
+* 1 bug fix:
+
+  * Added SIGINFO handler for finding slow tests without verbose
+
+=== 1.4.0 / 2009-06-18
+
+* 5 minor enhancement:
+
+  * Added clarification doco.
+  * Added specs and mocks to autorun.
+  * Changed spec test class creation to be non-destructive.
+  * Updated rakefile for new hoe capabilities.
+  * describes are nestable (via subclass). before/after/def inherits, specs don't.
+
+* 3 bug fixes:
+
+  * Fixed location on must/wont.
+  * Switched to __name__ to avoid common ivar name.
+  * Fixed indentation in test file (1.9).
+
+=== 1.3.1 / 2009-01-20 // ruby 1.9.1-p431
+
+* 1 minor enhancement:
+
+  * Added miniunit/autorun.rb as replacement for test/unit.rb's autorun.
+
+* 16 bug fixes:
+
+  * 1.9 test fixes.
+  * Bug fixes from nobu and akira for really odd scenarios. They run ruby funny.
+  * Fixed (assert|refute)_match's argument order.
+  * Fixed LocalJumpError in autorun if exception thrown before at_exit.
+  * Fixed assert_in_delta (should be >=, not >).
+  * Fixed assert_raises to match Modules.
+  * Fixed capture_io to not dup IOs.
+  * Fixed indentation of capture_io for ruby 1.9 warning.
+  * Fixed location to deal better with custom assertions and load paths. (Yuki)
+  * Fixed order of (must|wont)_include in MiniTest::Spec.
+  * Fixed skip's backtrace.
+  * Got arg order wrong in *_match in tests, message wrong as a result.
+  * Made describe private. For some reason I thought that an attribute of Kernel.
+  * Removed disable_autorun method, added autorun.rb instead.
+  * assert_match escapes if passed string for pattern.
+  * instance_of? is different from ===, use instance_of.
+
+=== 1.3.0 / 2008-10-09
+
+* 2 major enhancements:
+
+  * renamed to minitest and pulled out test/unit compatibility.
+  * mini/test.rb is now minitest/unit.rb, everything else maps directly.
+
+* 12 minor enhancements:
+
+  * assert_match now checks that act can call =~ and converts exp to a
+    regexp only if needed.
+  * Added assert_send... seems useless to me tho.
+  * message now forces to string... ruby-core likes to pass classes and arrays :(
+  * Added -v handling and switched to @verbose from $DEBUG.
+  * Verbose output now includes test class name and adds a sortable running time!
+  * Switched message generation into procs for message deferment.
+  * Added skip and renamed fail to flunk.
+  * Improved output failure messages for assert_instance_of, assert_kind_of
+  * Improved output for assert_respond_to, assert_same.
+  * at_exit now exits false instead of errors+failures.
+  * Made the tests happier and more readable imhfo.
+  * Switched index(s) == 0 to rindex(s, 0) on nobu's suggestion. Faster.
+
+* 5 bug fixes:
+
+  * 1.9: Added encoding normalization in mu_pp.
+  * 1.9: Fixed backtrace filtering (BTs are expanded now)
+  * Added back exception_details to assert_raises. DOH.
+  * Fixed shadowed variable in mock.rb
+  * Fixed stupid muscle memory message bug in assert_send.
+
+=== 1.2.1 / 2008-06-10
+
+* 7 minor enhancements:
+
+  * Added deprecations everywhere in test/unit.
+  * Added test_order to TestCase. :random on mini, :sorted on test/unit (for now).
+  * Big cleanup in test/unit for rails. Thanks Jeremy Kemper!
+  * Minor readability cleanup.
+  * Pushed setup/run/teardown down to testcase allowing specialized testcases.
+  * Removed pp. Tests run 2x faster. :/
+  * Renamed deprecation methods and moved to test/unit/deprecate.rb.
+
+=== 1.2.0 / 2008-06-09
+
+* 2 major enhancements:
+
+  * Added Mini::Spec.
+  * Added Mini::Mock. Thanks Steven Baker!!
+
+* 23 minor enhancements:
+
+  * Added bin/use_miniunit to make it easy to test out miniunit.
+  * Added -n filtering, thanks to Phil Hagelberg!
+  * Added args argument to #run, takes ARGV from at_exit.
+  * Added test name output if $DEBUG.
+  * Added a refute (was deny) for every assert.
+  * Added capture_io and a bunch of nice assertions from zentest.
+  * Added deprecation mechanism for assert_no/not methods to test/unit/assertions.
+  * Added pp output when available.
+  * Added tests for all assertions. Pretty much maxed out coverage.
+  * Added tests to verify consistency and good naming.
+  * Aliased and deprecated all ugly assertions.
+  * Cleaned out test/unit. Moved autorun there.
+  * Code cleanup to make extensions easier. Thanks Chad!
+  * Got spec args reversed in all but a couple assertions. Much more readable.
+  * Improved error messages across the board. Adds your message to the default.
+  * Moved into Mini namespace, renamed to Mini::Test and Mini::Spec.
+  * Pulled the assertions into their own module...
+  * Removed as much code as I could while still maintaining full functionality.
+    * Moved filter_backtrace into MiniTest.
+    * Removed MiniTest::Unit::run. Unnecessary.
+    * Removed location_of_failure. Unnecessary.
+    * Rewrote test/unit's filter_backtrace. Flog from 37.0 to 18.1
+  * Removed assert_send. Google says it is never used.
+  * Renamed MiniTest::Unit.autotest to #run.
+  * Renamed deny to refute.
+  * Rewrote some ugly/confusing default assertion messages.
+  * assert_in_delta now defaults to 0.001 precision. Makes specs prettier.
+
+* 9 bug fixes:
+
+  * Fixed assert_raises to raise outside of the inner-begin/rescue.
+  * Fixed for ruby 1.9 and rubinius.
+  * No longer exits 0 if exception in code PRE-test run causes early exit.
+  * Removed implementors method list from mini/test.rb - too stale.
+  * assert_nothing_raised takes a class as an arg. wtf? STUPID
+  * ".EF" output is now unbuffered.
+  * Bunch of changes to get working with rails... UGH.
+    * Added stupid hacks to deal with rails not requiring their dependencies.
+    * Now bitch loudly if someone defines one of my classes instead of requiring.
+  * Fixed infect method to work better on 1.9.
+  * Fixed all shadowed variable warnings in 1.9.
+
+=== 1.1.0 / 2007-11-08
+
+* 4 major enhancements:
+
+  * Finished writing all missing assertions.
+  * Output matches original test/unit.
+  * Documented every method needed by language implementor.
+  * Fully switched over to self-testing setup.
+
+* 2 minor enhancements:
+
+  * Added deny (assert ! test), our favorite extension to test/unit.
+  * Added .autotest and fairly complete unit tests. (thanks Chad for help here)
+
+=== 1.0.0 / 2006-10-30
+
+* 1 major enhancement
+
+  * Birthday!
+
diff --git a/app/server/vendor/minitest-5.8.1/Manifest.txt b/app/server/vendor/minitest-5.8.1/Manifest.txt
new file mode 100644
index 0000000..fa92dcd
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/Manifest.txt
@@ -0,0 +1,26 @@
+.autotest
+History.rdoc
+Manifest.txt
+README.rdoc
+Rakefile
+design_rationale.rb
+lib/hoe/minitest.rb
+lib/minitest.rb
+lib/minitest/assertions.rb
+lib/minitest/autorun.rb
+lib/minitest/benchmark.rb
+lib/minitest/expectations.rb
+lib/minitest/hell.rb
+lib/minitest/mock.rb
+lib/minitest/parallel.rb
+lib/minitest/pride.rb
+lib/minitest/pride_plugin.rb
+lib/minitest/spec.rb
+lib/minitest/test.rb
+lib/minitest/unit.rb
+test/minitest/metametameta.rb
+test/minitest/test_minitest_benchmark.rb
+test/minitest/test_minitest_mock.rb
+test/minitest/test_minitest_reporter.rb
+test/minitest/test_minitest_spec.rb
+test/minitest/test_minitest_unit.rb
diff --git a/app/server/vendor/minitest-5.8.1/README.rdoc b/app/server/vendor/minitest-5.8.1/README.rdoc
new file mode 100644
index 0000000..15c6bff
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/README.rdoc
@@ -0,0 +1,631 @@
+= minitest/{unit,spec,mock,benchmark}
+
+home :: https://github.com/seattlerb/minitest
+bugs :: https://github.com/seattlerb/minitest/issues
+rdoc :: http://docs.seattlerb.org/minitest
+vim  :: https://github.com/sunaku/vim-ruby-minitest
+emacs:: https://github.com/arthurnn/minitest-emacs
+
+== DESCRIPTION:
+
+minitest provides a complete suite of testing facilities supporting
+TDD, BDD, mocking, and benchmarking.
+
+    "I had a class with Jim Weirich on testing last week and we were
+     allowed to choose our testing frameworks. Kirk Haines and I were
+     paired up and we cracked open the code for a few test
+     frameworks...
+
+     I MUST say that minitest is *very* readable / understandable
+     compared to the 'other two' options we looked at. Nicely done and
+     thank you for helping us keep our mental sanity."
+
+    -- Wayne E. Seguin
+
+minitest/unit is a small and incredibly fast unit testing framework.
+It provides a rich set of assertions to make your tests clean and
+readable.
+
+minitest/spec is a functionally complete spec engine. It hooks onto
+minitest/unit and seamlessly bridges test assertions over to spec
+expectations.
+
+minitest/benchmark is an awesome way to assert the performance of your
+algorithms in a repeatable manner. Now you can assert that your newb
+co-worker doesn't replace your linear algorithm with an exponential
+one!
+
+minitest/mock by Steven Baker, is a beautifully tiny mock (and stub)
+object framework.
+
+minitest/pride shows pride in testing and adds coloring to your test
+output. I guess it is an example of how to write IO pipes too. :P
+
+minitest/unit is meant to have a clean implementation for language
+implementors that need a minimal set of methods to bootstrap a working
+test suite. For example, there is no magic involved for test-case
+discovery.
+
+    "Again, I can't praise enough the idea of a testing/specing
+     framework that I can actually read in full in one sitting!"
+
+    -- Piotr Szotkowski
+
+Comparing to rspec:
+
+    rspec is a testing DSL. minitest is ruby.
+
+    -- Adam Hawkins, "Bow Before MiniTest"
+
+minitest doesn't reinvent anything that ruby already provides, like:
+classes, modules, inheritance, methods. This means you only have to
+learn ruby to use minitest and all of your regular OO practices like
+extract-method refactorings still apply.
+
+== FEATURES/PROBLEMS:
+
+* minitest/autorun - the easy and explicit way to run all your tests.
+* minitest/unit - a very fast, simple, and clean test system.
+* minitest/spec - a very fast, simple, and clean spec system.
+* minitest/mock - a simple and clean mock/stub system.
+* minitest/benchmark - an awesome way to assert your algorithm's performance.
+* minitest/pride - show your pride in testing!
+* Incredibly small and fast runner, but no bells and whistles.
+
+== RATIONALE:
+
+See design_rationale.rb to see how specs and tests work in minitest.
+
+== SYNOPSIS:
+
+Given that you'd like to test the following class:
+
+  class Meme
+    def i_can_has_cheezburger?
+      "OHAI!"
+    end
+
+    def will_it_blend?
+      "YES!"
+    end
+  end
+
+=== Unit tests
+
+Define your tests as methods beginning with `test_`.
+
+  require "minitest/autorun"
+
+  class TestMeme < Minitest::Test
+    def setup
+      @meme = Meme.new
+    end
+
+    def test_that_kitty_can_eat
+      assert_equal "OHAI!", @meme.i_can_has_cheezburger?
+    end
+
+    def test_that_it_will_not_blend
+      refute_match /^no/i, @meme.will_it_blend?
+    end
+
+    def test_that_will_be_skipped
+      skip "test this later"
+    end
+  end
+
+=== Specs
+
+  require "minitest/autorun"
+
+  describe Meme do
+    before do
+      @meme = Meme.new
+    end
+
+    describe "when asked about cheeseburgers" do
+      it "must respond positively" do
+        @meme.i_can_has_cheezburger?.must_equal "OHAI!"
+      end
+    end
+
+    describe "when asked about blending possibilities" do
+      it "won't say no" do
+        @meme.will_it_blend?.wont_match /^no/i
+      end
+    end
+  end
+
+For matchers support check out:
+
+https://github.com/wojtekmach/minitest-matchers
+https://github.com/rmm5t/minitest-matchers_vaccine
+
+=== Benchmarks
+
+Add benchmarks to your tests.
+
+  # optionally run benchmarks, good for CI-only work!
+  require "minitest/benchmark" if ENV["BENCH"]
+
+  class TestMeme < Minitest::Benchmark
+    # Override self.bench_range or default range is [1, 10, 100, 1_000, 10_000]
+    def bench_my_algorithm
+      assert_performance_linear 0.9999 do |n| # n is a range value
+        @obj.my_algorithm(n)
+      end
+    end
+  end
+
+Or add them to your specs. If you make benchmarks optional, you'll
+need to wrap your benchmarks in a conditional since the methods won't
+be defined. In minitest 5, the describe name needs to match
+/Bench(mark)?$/.
+
+  describe "Meme Benchmark" do
+    if ENV["BENCH"] then
+      bench_performance_linear "my_algorithm", 0.9999 do |n|
+        100.times do
+          @obj.my_algorithm(n)
+        end
+      end
+    end
+  end
+
+outputs something like:
+
+  # Running benchmarks:
+
+  TestBlah	100	1000	10000
+  bench_my_algorithm	 0.006167	 0.079279	 0.786993
+  bench_other_algorithm	 0.061679	 0.792797	 7.869932
+
+Output is tab-delimited to make it easy to paste into a spreadsheet.
+
+=== Mocks
+
+Mocks and stubs defined using terminology by Fowler & Meszaros at
+http://www.martinfowler.com/bliki/TestDouble.html:
+
+"Mocks are pre-programmed with expectations which form a specification
+of the calls they are expected to receive. They can throw an exception
+if they receive a call they don't expect and are checked during
+verification to ensure they got all the calls they were expecting."
+
+  class MemeAsker
+    def initialize(meme)
+      @meme = meme
+    end
+
+    def ask(question)
+      method = question.tr(" ", "_") + "?"
+      @meme.__send__(method)
+    end
+  end
+
+  require "minitest/autorun"
+
+  describe MemeAsker, :ask do
+    describe "when passed an unpunctuated question" do
+      it "should invoke the appropriate predicate method on the meme" do
+        @meme = Minitest::Mock.new
+        @meme_asker = MemeAsker.new @meme
+        @meme.expect :will_it_blend?, :return_value
+
+        @meme_asker.ask "will it blend"
+
+        @meme.verify
+      end
+    end
+  end
+
+=== Stubs
+
+Mocks and stubs are defined using terminology by Fowler & Meszaros at
+http://www.martinfowler.com/bliki/TestDouble.html:
+
+"Stubs provide canned answers to calls made during the test".
+
+Minitest's stub method overrides a single method for the duration of
+the block.
+
+  def test_stale_eh
+    obj_under_test = Something.new
+
+    refute obj_under_test.stale?
+
+    Time.stub :now, Time.at(0) do   # stub goes away once the block is done
+      assert obj_under_test.stale?
+    end
+  end
+
+A note on stubbing: In order to stub a method, the method must
+actually exist prior to stubbing. Use a singleton method to create a
+new non-existing method:
+
+  def obj_under_test.fake_method
+    ...
+  end
+
+=== Running Your Tests
+
+Ideally, you'll use a rake task to run your tests, either piecemeal or
+all at once. Both rake and rails ship with rake tasks for running your
+tests. BUT! You don't have to:
+
+    % ruby -Ilib:test test/minitest/test_minitest_unit.rb
+    Run options: --seed 37685
+
+    # Running:
+
+    ...................................................................... (etc)
+
+    Finished in 0.107130s, 1446.8403 runs/s, 2959.0217 assertions/s.
+
+    155 runs, 317 assertions, 0 failures, 0 errors, 0 skips
+
+There are runtime options available, both from minitest itself, and also
+provided via plugins. To see them, simply run with `--help`:
+
+    % ruby -Ilib:test test/minitest/test_minitest_unit.rb --help
+    minitest options:
+        -h, --help                       Display this help.
+        -s, --seed SEED                  Sets random seed
+        -v, --verbose                    Verbose. Show progress processing files.
+        -n, --name PATTERN               Filter run on /pattern/ or string.
+
+    Known extensions: pride, autotest
+        -p, --pride                      Pride. Show your testing pride!
+        -a, --autotest                   Connect to autotest server.
+
+== Writing Extensions
+
+To define a plugin, add a file named minitest/XXX_plugin.rb to your
+project/gem. That file must be discoverable via ruby's LOAD_PATH (via
+rubygems or otherwise). Minitest will find and require that file using
+Gem.find_files. It will then try to call plugin_XXX_init during
+startup. The option processor will also try to call plugin_XXX_options
+passing the OptionParser instance and the current options hash. This
+lets you register your own command-line options. Here's a totally
+bogus example:
+
+    # minitest/bogus_plugin.rb:
+
+    module Minitest
+      def self.plugin_bogus_options(opts, options)
+        opts.on "--myci", "Report results to my CI" do
+          options[:myci] = true
+          options[:myci_addr] = get_myci_addr
+          options[:myci_port] = get_myci_port
+        end
+      end
+
+      def self.plugin_bogus_init(options)
+        self.reporter << MyCI.new(options) if options[:myci]
+      end
+    end
+
+=== Adding custom reporters
+
+Minitest uses composite reporter to output test results using multiple
+reporter instances. You can add new reporters to the composite during
+the init_plugins phase. As we saw in +plugin_bonus_init+ above, you
+simply add your reporter instance to the composite via +<<+.
+
++AbstractReporter+ defines the API for reporters. You may subclass it
+and override any method you want to achieve your desired behavior.
+
+start   :: Called when the run has started.
+record  :: Called for each result, passed or otherwise.
+report  :: Called at the end of the run.
+passed? :: Called to see if you detected any problems.
+
+Using our example above, here is how we might implement MyCI:
+
+    # minitest/bogus_plugin.rb
+
+    module Minitest
+      class MyCI < AbstractReporter
+        attr_accessor :results, :addr, :port
+
+        def initialize options
+          self.results = []
+          self.addr = options[:myci_addr]
+          self.port = options[:myci_port]
+        end
+
+        def record result
+          self.results << result
+        end
+
+        def report
+          CI.connect(addr, port).send_results self.results
+        end
+      end
+
+      # code from above...
+    end
+
+== FAQ
+
+=== How to test SimpleDelegates?
+
+The following implementation and test:
+
+    class Worker < SimpleDelegator
+      def work
+      end
+    end
+
+    describe Worker do
+      before do
+        @worker = Worker.new(Object.new)
+      end
+
+      it "must respond to work" do
+        @worker.must_respond_to :work
+      end
+    end
+
+outputs a failure:
+
+      1) Failure:
+    Worker#test_0001_must respond to work [bug11.rb:16]:
+    Expected #<Object:0x007f9e7184f0a0> (Object) to respond to #work.
+
+Worker is a SimpleDelegate which in 1.9+ is a subclass of BasicObject.
+Expectations are put on Object (one level down) so the Worker
+(SimpleDelegate) hits `method_missing` and delegates down to the
+`Object.new` instance. That object doesn't respond to work so the test
+fails.
+
+You can bypass `SimpleDelegate#method_missing` by extending the worker
+with `Minitest::Expectations`. You can either do that in your setup at
+the instance level, like:
+
+    before do
+      @worker = Worker.new(Object.new)
+      @worker.extend Minitest::Expectations
+    end
+
+or you can extend the Worker class (within the test file!), like:
+
+    class Worker
+      include ::Minitest::Expectations
+    end
+
+=== How to share code across test classes?
+
+Use a module. That's exactly what they're for:
+
+    module UsefulStuff
+      def useful_method
+        # ...
+      end
+    end
+
+    describe Blah do
+      include UsefulStuff
+
+      def test_whatever
+        # useful_method available here
+      end
+    end
+
+Remember, `describe` simply creates test classes. It's just ruby at
+the end of the day and all your normal Good Ruby Rules (tm) apply. If
+you want to extend your test using setup/teardown via a module, just
+make sure you ALWAYS call super. before/after automatically call super
+for you, so make sure you don't do it twice.
+
+=== Why am I seeing `uninitialized constant MiniTest::Test (NameError)`?
+
+Are you running the test with Bundler (e.g. via `bundle exec`)? If so, 
+in order to require minitest, you must first add the `gem 'minitest'`
+to your Gemfile and run `bundle`. Once it's installed, you should be 
+able to require minitest and run your tests.
+
+== Prominent Projects using Minitest:
+
+* arel
+* journey
+* mime-types
+* nokogiri
+* rails (active_support et al)
+* rake
+* rdoc
+* ...and of course, everything from seattle.rb...
+
+== Known Extensions:
+
+capybara_minitest_spec      :: Bridge between Capybara RSpec matchers and
+                               Minitest::Spec expectations (e.g.
+                               page.must_have_content("Title")).
+color_pound_spec_reporter   :: Test names print Ruby Object types in color with
+                               your Minitest Spec style tests.
+minispec-metadata           :: Metadata for describe/it blocks & CLI tag filter.
+                               E.g. `it "requires JS driver", js: true do` &
+                               `ruby test.rb --tag js` runs tests tagged :js.
+minitest-around             :: Around block for minitest. An alternative to
+                               setup/teardown dance.
+minitest-autotest           :: autotest is a continous testing facility meant to
+                               be used during development.
+minitest-bacon              :: minitest-bacon extends minitest with bacon-like
+                               functionality.
+minitest-bang               :: Adds support for RSpec-style let! to immediately
+                               invoke let statements before each test.
+minitest-bisect             :: Helps you isolate and debug random test failures.
+minitest-blink1_reporter    :: Display test results with a Blink1.
+minitest-capistrano         :: Assertions and expectations for testing
+                               Capistrano recipes.
+minitest-capybara           :: Capybara matchers support for minitest unit and
+                               spec.
+minitest-chef-handler       :: Run Minitest suites as Chef report handlers
+minitest-ci                 :: CI reporter plugin for Minitest.
+minitest-context            :: Defines contexts for code reuse in Minitest
+                               specs that share common expectations.
+minitest-debugger           :: Wraps assert so failed assertions drop into
+                               the ruby debugger.
+minitest-display            :: Patches Minitest to allow for an easily
+                               configurable output.
+minitest-documentation      :: Minimal documentation format inspired by rspec's.
+minitest-doc_reporter       :: Detailed output inspired by rspec's documentation
+                               format.
+minitest-emoji              :: Print out emoji for your test passes, fails, and
+                               skips.
+minitest-english            :: Semantically symmetric aliases for assertions and
+                               expectations.
+minitest-excludes           :: Clean API for excluding certain tests you
+                               don't want to run under certain conditions.
+minitest-fail-fast          :: Reimplements RSpec's "fail fast" feature
+minitest-filecontent        :: Support unit tests with expectation results in files.
+                               Differing results will be stored again in files.
+minitest-filesystem         :: Adds assertion and expectation to help testing
+                               filesystem contents.
+minitest-firemock           :: Makes your Minitest mocks more resilient.
+minitest-focus              :: Focus on one test at a time.
+minitest-gcstats            :: A minitest plugin that adds a report of the top
+                               tests by number of objects allocated.
+minitest-great_expectations :: Generally useful additions to minitest's
+                               assertions and expectations.
+minitest-growl              :: Test notifier for minitest via growl.
+minitest-happy              :: GLOBALLY ACTIVATE MINITEST PRIDE! RAWR!
+minitest-hooks              :: Around and before_all/after_all/around_all hooks
+minitest-implicit-subject   :: Implicit declaration of the test subject.
+minitest-instrument         :: Instrument ActiveSupport::Notifications when
+                               test method is executed.
+minitest-instrument-db      :: Store information about speed of test execution
+                               provided by minitest-instrument in database.
+minitest-junit              :: JUnit-style XML reporter for minitest.
+minitest-libnotify          :: Test notifier for minitest via libnotify.
+minitest-line               :: Run test at line number.
+minitest-logger             :: Define assert_log and enable minitest to test log messages.
+                               Supports Logger and Log4r::Logger.
+minitest-macruby            :: Provides extensions to minitest for macruby UI
+                               testing.
+minitest-matchers           :: Adds support for RSpec-style matchers to
+                               minitest.
+minitest-matchers_vaccine   :: Adds assertions that adhere to the matcher spec,
+                               but without any expectation infections.
+minitest-metadata           :: Annotate tests with metadata (key-value).
+minitest-mongoid            :: Mongoid assertion matchers for Minitest.
+minitest-must_not           :: Provides must_not as an alias for wont in
+                               Minitest.
+minitest-osx                :: Reporter for the Mac OS X notification center.
+minitest-parallel_fork      :: Fork-based parallelization
+minitest-parallel-db        :: Run tests in parallel with a single database.
+minitest-power_assert       :: PowerAssert for Minitest.
+minitest-predicates         :: Adds support for .predicate? methods.
+minitest-profile            :: List the 10 slowest tests in your suite.
+minitest-rails              :: Minitest integration for Rails 3.x.
+minitest-rails-capybara     :: Capybara integration for Minitest::Rails.
+minitest-reporters          :: Create customizable Minitest output formats.
+minitest-rg                 :: Colored red/green output for Minitest.
+minitest-rspec_mocks        :: Use RSpec Mocks with Minitest.
+minitest-server             :: minitest-server provides a client/server setup 
+                               with your minitest process, allowing your test 
+                               run to send its results directly to a handler.
+minitest-shared_description :: Support for shared specs and shared spec
+                               subclasses
+minitest-should_syntax      :: RSpec-style +x.should == y+ assertions for
+                               Minitest.
+minitest-shouldify          :: Adding all manner of shoulds to Minitest (bad
+                               idea)
+minitest-snail              :: Print a list of tests that take too long
+minitest-spec-context       :: Provides rspec-ish context method to
+                               Minitest::Spec.
+minitest-spec-expect        :: Expect syntax for Minitest::Spec (e.g.
+                               expect(sequences).to_include :celery_man).
+minitest-spec-magic         :: Minitest::Spec extensions for Rails and beyond.
+minitest-spec-rails         :: Drop in Minitest::Spec superclass for
+                               ActiveSupport::TestCase.
+minitest-sprint             :: Runs (Get it? It's fast!) your tests and makes
+                               it easier to rerun individual failures.
+minitest-stately            :: Find leaking state between tests
+minitest-stub_any_instance  :: Stub any instance of a method on the given class
+                               for the duration of a block.
+minitest-stub-const         :: Stub constants for the duration of a block.
+minitest-tags               :: Add tags for minitest.
+minitest-unordered          :: Adds a new assertion to minitest for checking the
+                               contents of a collection, ignoring element order.
+minitest-vcr                :: Automatic cassette managment with Minitest::Spec
+                               and VCR.
+minitest_owrapper           :: Get tests results as a TestResult object.
+minitest_should             :: Shoulda style syntax for minitest test::unit.
+minitest_tu_shim            :: Bridges between test/unit and minitest.
+mongoid-minitest            :: Minitest matchers for Mongoid.
+pry-rescue                  :: A pry plugin w/ minitest support. See
+                               pry-rescue/minitest.rb.
+rspec2minitest              :: Easily translate any RSpec matchers to Minitest
+                               assertions and expectations.
+
+== Unknown Extensions:
+
+Authors... Please send me a pull request with a description of your minitest extension.
+
+* assay-minitest
+* detroit-minitest
+* em-minitest-spec
+* flexmock-minitest
+* guard-minitest
+* guard-minitest-decisiv
+* minitest-activemodel
+* minitest-ar-assertions
+* minitest-capybara-unit
+* minitest-colorer
+* minitest-deluxe
+* minitest-extra-assertions
+* minitest-rails-shoulda
+* minitest-spec
+* minitest-spec-should
+* minitest-sugar
+* spork-minitest
+
+== REQUIREMENTS:
+
+* Ruby 1.8.7+. No magic is involved. I hope.
+
+== INSTALL:
+
+  sudo gem install minitest
+
+On 1.9, you already have it. To get newer candy you can still install
+the gem, and then requiring "minitest/autorun" should automatically
+pull it in. If not, you'll need to do it yourself:
+
+  gem "minitest"     # ensures you"re using the gem, and not the built-in MT
+  require "minitest/autorun"
+
+  # ... usual testing stuffs ...
+
+DO NOTE: There is a serious problem with the way that ruby 1.9/2.0
+packages their own gems. They install a gem specification file, but
+don't install the gem contents in the gem path. This messes up
+Gem.find_files and many other things (gem which, gem contents, etc).
+
+Just install minitest as a gem for real and you'll be happier.
+
+== LICENSE:
+
+(The MIT License)
+
+Copyright (c) Ryan Davis, seattle.rb
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/minitest-5.8.1/Rakefile b/app/server/vendor/minitest-5.8.1/Rakefile
new file mode 100644
index 0000000..0fc5232
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/Rakefile
@@ -0,0 +1,72 @@
+# -*- ruby -*-
+
+require "rubygems"
+require "hoe"
+
+Hoe.plugin :seattlerb
+Hoe.plugin :rdoc
+
+Hoe.spec "minitest" do
+  developer "Ryan Davis", "ryand-ruby at zenspider.com"
+
+  license "MIT"
+
+  self.testlib = :minitest
+end
+
+desc "Find missing expectations"
+task :specs do
+  $:.unshift "lib"
+  require "minitest/unit"
+  require "minitest/spec"
+
+  pos_prefix, neg_prefix = "must", "wont"
+  skip_re = /^(must|wont)$|wont_(throw)|must_(block|not?_|nothing|raise$)/x
+  dont_flip_re = /(must|wont)_(include|respond_to)/
+
+  map = {
+    /(must_throw)s/                        => '\1',
+    /(?!not)_same/                         => "_be_same_as",
+    /_in_/                                 => "_be_within_",
+    /_operator/                            => "_be",
+    /_includes/                            => "_include",
+    /(must|wont)_(.*_of|nil|silent|empty)/ => '\1_be_\2',
+    /must_raises/                          => "must_raise",
+  }
+
+  expectations = Minitest::Expectations.public_instance_methods.map(&:to_s)
+  assertions   = Minitest::Assertions.public_instance_methods.map(&:to_s)
+
+  assertions.sort.each do |assertion|
+    expectation = case assertion
+                  when /^assert/ then
+                    assertion.sub(/^assert/, pos_prefix.to_s)
+                  when /^refute/ then
+                    assertion.sub(/^refute/, neg_prefix.to_s)
+                  end
+
+    next unless expectation
+    next if expectation =~ skip_re
+
+    regexp, replacement = map.find { |re, _| expectation =~ re }
+    expectation.sub! regexp, replacement if replacement
+
+    next if expectations.include? expectation
+
+    args = [assertion, expectation].map(&:to_sym).map(&:inspect)
+    args << :reverse if expectation =~ dont_flip_re
+
+    puts
+    puts "##"
+    puts "# :method: #{expectation}"
+    puts "# See Minitest::Assertions##{assertion}"
+    puts
+    puts "infect_an_assertion #{args.join ", "}"
+  end
+end
+
+task :bugs do
+  sh "for f in bug*.rb ; do echo $f; echo; #{Gem.ruby} -Ilib $f && rm $f ; done"
+end
+
+# vim: syntax=Ruby
diff --git a/app/server/vendor/minitest-5.8.1/design_rationale.rb b/app/server/vendor/minitest-5.8.1/design_rationale.rb
new file mode 100644
index 0000000..a3fcc37
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/design_rationale.rb
@@ -0,0 +1,52 @@
+# Specs:                               # Equivalent Unit Tests:
+###############################################################################
+describe Thingy do                     # class TestThingy < Minitest::Test
+  before do                            #   def setup
+    do_some_setup                      #     super
+  end                                  #     do_some_setup
+                                       #   end
+  it "should do the first thing" do    #
+    1.must_equal 1                     #   def test_first_thing
+  end                                  #     assert_equal 1, 1
+                                       #   end
+  describe SubThingy do                # end
+    before do                          #
+      do_more_setup                    # class TestSubThingy < TestThingy
+    end                                #   def setup
+                                       #     super
+    it "should do the second thing" do #     do_more_setup
+      2.must_equal 2                   #   end
+    end                                #
+  end                                  #   def test_second_thing
+end                                    #     assert_equal 2, 2
+                                       #   end
+                                       # end
+###############################################################################
+# runs 2 specs                         # runs 3 tests
+###############################################################################
+# The specs generate:
+
+class ThingySpec < Minitest::Spec
+  def setup
+    super
+    do_some_setup
+  end
+
+  def test_should_do_the_first_thing
+    assert_equal 1, 1
+  end
+end
+
+class SubThingySpec < ThingySpec
+  def setup
+    super
+    do_more_setup
+  end
+
+  # because only setup/teardown is inherited, not specs
+  remove_method :test_should_do_the_first_thing
+
+  def test_should_do_the_second_thing
+    assert_equal 2, 2
+  end
+end
diff --git a/app/server/vendor/minitest-5.8.1/lib/hoe/minitest.rb b/app/server/vendor/minitest-5.8.1/lib/hoe/minitest.rb
new file mode 100644
index 0000000..dc2f029
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/lib/hoe/minitest.rb
@@ -0,0 +1,26 @@
+# :stopdoc:
+
+class Hoe
+end
+
+module Hoe::Minitest
+  def initialize_minitest
+    dir = "../../minitest/dev/lib"
+    Hoe.add_include_dirs dir if File.directory? dir
+
+    gem "minitest"
+    require "minitest"
+    version = Minitest::VERSION.split(/\./).first(2).join(".")
+
+    dependency "minitest", "~> #{version}", :development unless
+      self.name == "minitest" or ENV["MT_NO_ISOLATE"]
+  end
+
+  def define_minitest_tasks
+    self.testlib = :minitest
+
+    # make sure we use the gemmed minitest on 1.9
+    self.test_prelude = 'gem "minitest"' unless
+      self.name == "minitest" or ENV["MT_NO_ISOLATE"]
+  end
+end
diff --git a/app/server/vendor/minitest-5.8.1/lib/minitest.rb b/app/server/vendor/minitest-5.8.1/lib/minitest.rb
new file mode 100644
index 0000000..99ac8e5
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/lib/minitest.rb
@@ -0,0 +1,797 @@
+require "optparse"
+require "thread"
+require "mutex_m"
+require "minitest/parallel"
+
+##
+# :include: README.rdoc
+
+module Minitest
+  VERSION = "5.8.1" # :nodoc:
+  ENCS = "".respond_to? :encoding # :nodoc:
+
+  @@installed_at_exit ||= false
+  @@after_run = []
+  @extensions = []
+
+  mc = (class << self; self; end)
+
+  ##
+  # Parallel test executor
+
+  mc.send :attr_accessor, :parallel_executor
+  self.parallel_executor = Parallel::Executor.new((ENV["N"] || 2).to_i)
+
+  ##
+  # Filter object for backtraces.
+
+  mc.send :attr_accessor, :backtrace_filter
+
+  ##
+  # Reporter object to be used for all runs.
+  #
+  # NOTE: This accessor is only available during setup, not during runs.
+
+  mc.send :attr_accessor, :reporter
+
+  ##
+  # Names of known extension plugins.
+
+  mc.send :attr_accessor, :extensions
+
+  ##
+  # Registers Minitest to run at process exit
+
+  def self.autorun
+    at_exit {
+      next if $! and not ($!.kind_of? SystemExit and $!.success?)
+
+      exit_code = nil
+
+      at_exit {
+        @@after_run.reverse_each(&:call)
+        exit exit_code || false
+      }
+
+      exit_code = Minitest.run ARGV
+    } unless @@installed_at_exit
+    @@installed_at_exit = true
+  end
+
+  ##
+  # A simple hook allowing you to run a block of code after everything
+  # is done running. Eg:
+  #
+  #   Minitest.after_run { p $debugging_info }
+
+  def self.after_run &block
+    @@after_run << block
+  end
+
+  def self.init_plugins options # :nodoc:
+    self.extensions.each do |name|
+      msg = "plugin_#{name}_init"
+      send msg, options if self.respond_to? msg
+    end
+  end
+
+  def self.load_plugins # :nodoc:
+    return unless self.extensions.empty?
+
+    seen = {}
+
+    require "rubygems" unless defined? Gem
+
+    Gem.find_files("minitest/*_plugin.rb").each do |plugin_path|
+      name = File.basename plugin_path, "_plugin.rb"
+
+      next if seen[name]
+      seen[name] = true
+
+      require plugin_path
+      self.extensions << name
+    end
+  end
+
+  ##
+  # This is the top-level run method. Everything starts from here. It
+  # tells each Runnable sub-class to run, and each of those are
+  # responsible for doing whatever they do.
+  #
+  # The overall structure of a run looks like this:
+  #
+  #   Minitest.autorun
+  #     Minitest.run(args)
+  #       Minitest.__run(reporter, options)
+  #         Runnable.runnables.each
+  #           runnable.run(reporter, options)
+  #             self.runnable_methods.each
+  #               self.run_one_method(self, runnable_method, reporter)
+  #                 Minitest.run_one_method(klass, runnable_method)
+  #                   klass.new(runnable_method).run
+
+  def self.run args = []
+    self.load_plugins
+
+    options = process_args args
+
+    reporter = CompositeReporter.new
+    reporter << SummaryReporter.new(options[:io], options)
+    reporter << ProgressReporter.new(options[:io], options)
+
+    self.reporter = reporter # this makes it available to plugins
+    self.init_plugins options
+    self.reporter = nil # runnables shouldn't depend on the reporter, ever
+
+    self.parallel_executor.start if parallel_executor.respond_to?(:start)
+    reporter.start
+    begin
+      __run reporter, options
+    rescue Interrupt
+      warn "Interrupted. Exiting..."
+    end
+    self.parallel_executor.shutdown
+    reporter.report
+
+    reporter.passed?
+  end
+
+  ##
+  # Internal run method. Responsible for telling all Runnable
+  # sub-classes to run.
+  #
+  # NOTE: this method is redefined in parallel_each.rb, which is
+  # loaded if a Runnable calls parallelize_me!.
+
+  def self.__run reporter, options
+    suites = Runnable.runnables.shuffle
+    parallel, serial = suites.partition { |s| s.test_order == :parallel }
+
+    # If we run the parallel tests before the serial tests, the parallel tests
+    # could run in parallel with the serial tests. This would be bad because
+    # the serial tests won't lock around Reporter#record. Run the serial tests
+    # first, so that after they complete, the parallel tests will lock when
+    # recording results.
+    serial.map { |suite| suite.run reporter, options } +
+      parallel.map { |suite| suite.run reporter, options }
+  end
+
+  def self.process_args args = [] # :nodoc:
+    options = {
+               :io => $stdout,
+              }
+    orig_args = args.dup
+
+    OptionParser.new do |opts|
+      opts.banner  = "minitest options:"
+      opts.version = Minitest::VERSION
+
+      opts.on "-h", "--help", "Display this help." do
+        puts opts
+        exit
+      end
+
+      desc = "Sets random seed. Also via env. Eg: SEED=n rake"
+      opts.on "-s", "--seed SEED", Integer, desc do |m|
+        options[:seed] = m.to_i
+      end
+
+      opts.on "-v", "--verbose", "Verbose. Show progress processing files." do
+        options[:verbose] = true
+      end
+
+      opts.on "-n", "--name PATTERN", "Filter run on /regexp/ or string." do |a|
+        options[:filter] = a
+      end
+
+      unless extensions.empty?
+        opts.separator ""
+        opts.separator "Known extensions: #{extensions.join(", ")}"
+
+        extensions.each do |meth|
+          msg = "plugin_#{meth}_options"
+          send msg, opts, options if self.respond_to?(msg)
+        end
+      end
+
+      begin
+        opts.parse! args
+      rescue OptionParser::InvalidOption => e
+        puts
+        puts e
+        puts
+        puts opts
+        exit 1
+      end
+
+      orig_args -= args
+    end
+
+    unless options[:seed] then
+      srand
+      options[:seed] = (ENV["SEED"] || srand).to_i % 0xFFFF
+      orig_args << "--seed" << options[:seed].to_s
+    end
+
+    srand options[:seed]
+
+    options[:args] = orig_args.map { |s|
+      s =~ /[\s|&<>$()]/ ? s.inspect : s
+    }.join " "
+
+    options
+  end
+
+  def self.filter_backtrace bt # :nodoc:
+    backtrace_filter.filter bt
+  end
+
+  ##
+  # Represents anything "runnable", like Test, Spec, Benchmark, or
+  # whatever you can dream up.
+  #
+  # Subclasses of this are automatically registered and available in
+  # Runnable.runnables.
+
+  class Runnable
+    ##
+    # Number of assertions executed in this run.
+
+    attr_accessor :assertions
+
+    ##
+    # An assertion raised during the run, if any.
+
+    attr_accessor :failures
+
+    ##
+    # Name of the run.
+
+    def name
+      @NAME
+    end
+
+    ##
+    # Set the name of the run.
+
+    def name= o
+      @NAME = o
+    end
+
+    def self.inherited klass # :nodoc:
+      self.runnables << klass
+      super
+    end
+
+    ##
+    # Returns all instance methods matching the pattern +re+.
+
+    def self.methods_matching re
+      public_instance_methods(true).grep(re).map(&:to_s)
+    end
+
+    def self.reset # :nodoc:
+      @@runnables = []
+    end
+
+    reset
+
+    ##
+    # Responsible for running all runnable methods in a given class,
+    # each in its own instance. Each instance is passed to the
+    # reporter to record.
+
+    def self.run reporter, options = {}
+      filter = options[:filter] || "/./"
+      filter = Regexp.new $1 if filter =~ %r%/(.*)/%
+
+      filtered_methods = self.runnable_methods.find_all { |m|
+        filter === m || filter === "#{self}##{m}"
+      }
+
+      return if filtered_methods.empty?
+
+      with_info_handler reporter do
+        filtered_methods.each do |method_name|
+          run_one_method self, method_name, reporter
+        end
+      end
+    end
+
+    ##
+    # Runs a single method and has the reporter record the result.
+    # This was considered internal API but is factored out of run so
+    # that subclasses can specialize the running of an individual
+    # test. See Minitest::ParallelTest::ClassMethods for an example.
+
+    def self.run_one_method klass, method_name, reporter
+      reporter.record Minitest.run_one_method(klass, method_name)
+    end
+
+    def self.with_info_handler reporter, &block # :nodoc:
+      handler = lambda do
+        unless reporter.passed? then
+          warn "Current results:"
+          warn ""
+          warn reporter.reporters.first
+          warn ""
+        end
+      end
+
+      on_signal "INFO", handler, &block
+    end
+
+    SIGNALS = Signal.list # :nodoc:
+
+    def self.on_signal name, action # :nodoc:
+      supported = SIGNALS[name]
+
+      old_trap = trap name do
+        old_trap.call if old_trap.respond_to? :call
+        action.call
+      end if supported
+
+      yield
+    ensure
+      trap name, old_trap if supported
+    end
+
+    ##
+    # Each subclass of Runnable is responsible for overriding this
+    # method to return all runnable methods. See #methods_matching.
+
+    def self.runnable_methods
+      raise NotImplementedError, "subclass responsibility"
+    end
+
+    ##
+    # Returns all subclasses of Runnable.
+
+    def self.runnables
+      @@runnables
+    end
+
+    def marshal_dump # :nodoc:
+      [self.name, self.failures, self.assertions]
+    end
+
+    def marshal_load ary # :nodoc:
+      self.name, self.failures, self.assertions = ary
+    end
+
+    def failure # :nodoc:
+      self.failures.first
+    end
+
+    def initialize name # :nodoc:
+      self.name       = name
+      self.failures   = []
+      self.assertions = 0
+    end
+
+    ##
+    # Runs a single method. Needs to return self.
+
+    def run
+      raise NotImplementedError, "subclass responsibility"
+    end
+
+    ##
+    # Did this run pass?
+    #
+    # Note: skipped runs are not considered passing, but they don't
+    # cause the process to exit non-zero.
+
+    def passed?
+      raise NotImplementedError, "subclass responsibility"
+    end
+
+    ##
+    # Returns a single character string to print based on the result
+    # of the run. Eg ".", "F", or "E".
+
+    def result_code
+      raise NotImplementedError, "subclass responsibility"
+    end
+
+    ##
+    # Was this run skipped? See #passed? for more information.
+
+    def skipped?
+      raise NotImplementedError, "subclass responsibility"
+    end
+  end
+
+  ##
+  # Defines the API for Reporters. Subclass this and override whatever
+  # you want. Go nuts.
+
+  class AbstractReporter
+    include Mutex_m
+
+    ##
+    # Starts reporting on the run.
+
+    def start
+    end
+
+    ##
+    # Record a result and output the Runnable#result_code. Stores the
+    # result of the run if the run did not pass.
+
+    def record result
+    end
+
+    ##
+    # Outputs the summary of the run.
+
+    def report
+    end
+
+    ##
+    # Did this run pass?
+
+    def passed?
+      true
+    end
+  end
+
+  class Reporter < AbstractReporter # :nodoc:
+    ##
+    # The IO used to report.
+
+    attr_accessor :io
+
+    ##
+    # Command-line options for this run.
+
+    attr_accessor :options
+
+    def initialize io = $stdout, options = {} # :nodoc:
+      super()
+      self.io      = io
+      self.options = options
+    end
+  end
+
+  ##
+  # A very simple reporter that prints the "dots" during the run.
+  #
+  # This is added to the top-level CompositeReporter at the start of
+  # the run. If you want to change the output of minitest via a
+  # plugin, pull this out of the composite and replace it with your
+  # own.
+
+  class ProgressReporter < Reporter
+    def record result # :nodoc:
+      io.print "%s#%s = %.2f s = " % [result.class, result.name, result.time] if
+        options[:verbose]
+      io.print result.result_code
+      io.puts if options[:verbose]
+    end
+  end
+
+  ##
+  # A reporter that gathers statistics about a test run. Does not do
+  # any IO because meant to be used as a parent class for a reporter
+  # that does.
+  #
+  # If you want to create an entirely different type of output (eg,
+  # CI, HTML, etc), this is the place to start.
+
+  class StatisticsReporter < Reporter
+    # :stopdoc:
+    attr_accessor :assertions
+    attr_accessor :count
+    attr_accessor :results
+    attr_accessor :start_time
+    attr_accessor :total_time
+    attr_accessor :failures
+    attr_accessor :errors
+    attr_accessor :skips
+    # :startdoc:
+
+    def initialize io = $stdout, options = {} # :nodoc:
+      super
+
+      self.assertions = 0
+      self.count      = 0
+      self.results    = []
+      self.start_time = nil
+      self.total_time = nil
+      self.failures   = nil
+      self.errors     = nil
+      self.skips      = nil
+    end
+
+    def passed? # :nodoc:
+      results.all?(&:skipped?)
+    end
+
+    def start # :nodoc:
+      self.start_time = Minitest.clock_time
+    end
+
+    def record result # :nodoc:
+      self.count += 1
+      self.assertions += result.assertions
+
+      results << result if not result.passed? or result.skipped?
+    end
+
+    def report # :nodoc:
+      aggregate = results.group_by { |r| r.failure.class }
+      aggregate.default = [] # dumb. group_by should provide this
+
+      self.total_time = Minitest.clock_time - start_time
+      self.failures   = aggregate[Assertion].size
+      self.errors     = aggregate[UnexpectedError].size
+      self.skips      = aggregate[Skip].size
+    end
+  end
+
+  ##
+  # A reporter that prints the header, summary, and failure details at
+  # the end of the run.
+  #
+  # This is added to the top-level CompositeReporter at the start of
+  # the run. If you want to change the output of minitest via a
+  # plugin, pull this out of the composite and replace it with your
+  # own.
+
+  class SummaryReporter < StatisticsReporter
+    # :stopdoc:
+    attr_accessor :sync
+    attr_accessor :old_sync
+    # :startdoc:
+
+    def start # :nodoc:
+      super
+
+      io.puts "Run options: #{options[:args]}"
+      io.puts
+      io.puts "# Running:"
+      io.puts
+
+      self.sync = io.respond_to? :"sync=" # stupid emacs
+      self.old_sync, io.sync = io.sync, true if self.sync
+    end
+
+    def report # :nodoc:
+      super
+
+      io.sync = self.old_sync
+
+      io.puts unless options[:verbose] # finish the dots
+      io.puts
+      io.puts statistics
+      io.puts aggregated_results
+      io.puts summary
+    end
+
+    def statistics # :nodoc:
+      "Finished in %.6fs, %.4f runs/s, %.4f assertions/s." %
+        [total_time, count / total_time, assertions / total_time]
+    end
+
+    def aggregated_results # :nodoc:
+      filtered_results = results.dup
+      filtered_results.reject!(&:skipped?) unless options[:verbose]
+
+      s = filtered_results.each_with_index.map { |result, i|
+        "\n%3d) %s" % [i+1, result]
+      }.join("\n") + "\n"
+
+      s.force_encoding(io.external_encoding) if
+        ENCS and io.external_encoding and s.encoding != io.external_encoding
+
+      s
+    end
+
+    alias to_s aggregated_results
+
+    def summary # :nodoc:
+      extra = ""
+
+      extra = "\n\nYou have skipped tests. Run with --verbose for details." if
+        results.any?(&:skipped?) unless options[:verbose] or ENV["MT_NO_SKIP_MSG"]
+
+      "%d runs, %d assertions, %d failures, %d errors, %d skips%s" %
+        [count, assertions, failures, errors, skips, extra]
+    end
+  end
+
+  ##
+  # Dispatch to multiple reporters as one.
+
+  class CompositeReporter < AbstractReporter
+    ##
+    # The list of reporters to dispatch to.
+
+    attr_accessor :reporters
+
+    def initialize *reporters # :nodoc:
+      super()
+      self.reporters = reporters
+    end
+
+    ##
+    # Add another reporter to the mix.
+
+    def << reporter
+      self.reporters << reporter
+    end
+
+    def passed? # :nodoc:
+      self.reporters.all?(&:passed?)
+    end
+
+    def start # :nodoc:
+      self.reporters.each(&:start)
+    end
+
+    def record result # :nodoc:
+      self.reporters.each do |reporter|
+        reporter.record result
+      end
+    end
+
+    def report # :nodoc:
+      self.reporters.each(&:report)
+    end
+  end
+
+  ##
+  # Represents run failures.
+
+  class Assertion < Exception
+    def error # :nodoc:
+      self
+    end
+
+    ##
+    # Where was this run before an assertion was raised?
+
+    def location
+      last_before_assertion = ""
+      self.backtrace.reverse_each do |s|
+        break if s =~ /in .(assert|refute|flunk|pass|fail|raise|must|wont)/
+        last_before_assertion = s
+      end
+      last_before_assertion.sub(/:in .*$/, "")
+    end
+
+    def result_code # :nodoc:
+      result_label[0, 1]
+    end
+
+    def result_label # :nodoc:
+      "Failure"
+    end
+  end
+
+  ##
+  # Assertion raised when skipping a run.
+
+  class Skip < Assertion
+    def result_label # :nodoc:
+      "Skipped"
+    end
+  end
+
+  ##
+  # Assertion wrapping an unexpected error that was raised during a run.
+
+  class UnexpectedError < Assertion
+    attr_accessor :exception # :nodoc:
+
+    def initialize exception # :nodoc:
+      super "Unexpected exception"
+      self.exception = exception
+    end
+
+    def backtrace # :nodoc:
+      self.exception.backtrace
+    end
+
+    def error # :nodoc:
+      self.exception
+    end
+
+    def message # :nodoc:
+      bt = Minitest.filter_backtrace(self.backtrace).join "\n    "
+      "#{self.exception.class}: #{self.exception.message}\n    #{bt}"
+    end
+
+    def result_label # :nodoc:
+      "Error"
+    end
+  end
+
+  ##
+  # Provides a simple set of guards that you can use in your tests
+  # to skip execution if it is not applicable. These methods are
+  # mixed into Test as both instance and class methods so you
+  # can use them inside or outside of the test methods.
+  #
+  #   def test_something_for_mri
+  #     skip "bug 1234"  if jruby?
+  #     # ...
+  #   end
+  #
+  #   if windows? then
+  #     # ... lots of test methods ...
+  #   end
+
+  module Guard
+
+    ##
+    # Is this running on jruby?
+
+    def jruby? platform = RUBY_PLATFORM
+      "java" == platform
+    end
+
+    ##
+    # Is this running on maglev?
+
+    def maglev? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
+      "maglev" == platform
+    end
+
+    ##
+    # Is this running on mri?
+
+    def mri? platform = RUBY_DESCRIPTION
+      /^ruby/ =~ platform
+    end
+
+    ##
+    # Is this running on rubinius?
+
+    def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
+      "rbx" == platform
+    end
+
+    ##
+    # Is this running on windows?
+
+    def windows? platform = RUBY_PLATFORM
+      /mswin|mingw/ =~ platform
+    end
+  end
+
+  class BacktraceFilter # :nodoc:
+    def filter bt
+      return ["No backtrace"] unless bt
+
+      return bt.dup if $DEBUG
+
+      new_bt = bt.take_while { |line| line !~ /lib\/minitest/ }
+      new_bt = bt.select     { |line| line !~ /lib\/minitest/ } if new_bt.empty?
+      new_bt = bt.dup                                           if new_bt.empty?
+
+      new_bt
+    end
+  end
+
+  self.backtrace_filter = BacktraceFilter.new
+
+  def self.run_one_method klass, method_name # :nodoc:
+    result = klass.new(method_name).run
+    raise "#{klass}#run _must_ return self" unless klass === result
+    result
+  end
+
+  if defined? Process::CLOCK_MONOTONIC
+    def self.clock_time
+      Process.clock_gettime Process::CLOCK_MONOTONIC
+    end
+  else
+    def self.clock_time
+      Time.now
+    end
+  end
+end
+
+require "minitest/test"
diff --git a/app/server/vendor/minitest-5.8.1/lib/minitest/assertions.rb b/app/server/vendor/minitest-5.8.1/lib/minitest/assertions.rb
new file mode 100644
index 0000000..5f274a8
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/lib/minitest/assertions.rb
@@ -0,0 +1,661 @@
+require "rbconfig"
+require "tempfile"
+require "stringio"
+
+module Minitest
+  ##
+  # Minitest Assertions.  All assertion methods accept a +msg+ which is
+  # printed if the assertion fails.
+  #
+  # Protocol: Nearly everything here boils up to +assert+, which
+  # expects to be able to increment an instance accessor named
+  # +assertions+. This is not provided by Assertions and must be
+  # provided by the thing including Assertions. See Minitest::Runnable
+  # for an example.
+
+  module Assertions
+    UNDEFINED = Object.new # :nodoc:
+
+    def UNDEFINED.inspect # :nodoc:
+      "UNDEFINED" # again with the rdoc bugs... :(
+    end
+
+    ##
+    # Returns the diff command to use in #diff. Tries to intelligently
+    # figure out what diff to use.
+
+    def self.diff
+      @diff = if (RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ &&
+                  system("diff.exe", __FILE__, __FILE__)) then
+                "diff.exe -u"
+              elsif Minitest::Test.maglev? then
+                "diff -u"
+              elsif system("gdiff", __FILE__, __FILE__)
+                "gdiff -u" # solaris and kin suck
+              elsif system("diff", __FILE__, __FILE__)
+                "diff -u"
+              else
+                nil
+              end unless defined? @diff
+
+      @diff
+    end
+
+    ##
+    # Set the diff command to use in #diff.
+
+    def self.diff= o
+      @diff = o
+    end
+
+    ##
+    # Returns a diff between +exp+ and +act+. If there is no known
+    # diff command or if it doesn't make sense to diff the output
+    # (single line, short output), then it simply returns a basic
+    # comparison between the two.
+
+    def diff exp, act
+      expect = mu_pp_for_diff exp
+      butwas = mu_pp_for_diff act
+      result = nil
+
+      need_to_diff =
+        (expect.include?("\n")    ||
+         butwas.include?("\n")    ||
+         expect.size > 30         ||
+         butwas.size > 30         ||
+         expect == butwas)        &&
+        Minitest::Assertions.diff
+
+      return "Expected: #{mu_pp exp}\n  Actual: #{mu_pp act}" unless
+        need_to_diff
+
+      Tempfile.open("expect") do |a|
+        a.puts expect
+        a.flush
+
+        Tempfile.open("butwas") do |b|
+          b.puts butwas
+          b.flush
+
+          result = `#{Minitest::Assertions.diff} #{a.path} #{b.path}`
+          result.sub!(/^\-\-\- .+/, "--- expected")
+          result.sub!(/^\+\+\+ .+/, "+++ actual")
+
+          if result.empty? then
+            klass = exp.class
+            result = [
+                      "No visible difference in the #{klass}#inspect output.\n",
+                      "You should look at the implementation of #== on ",
+                      "#{klass} or its members.\n",
+                      expect,
+                     ].join
+          end
+        end
+      end
+
+      result
+    end
+
+    ##
+    # This returns a human-readable version of +obj+. By default
+    # #inspect is called. You can override this to use #pretty_print
+    # if you want.
+
+    def mu_pp obj
+      s = obj.inspect
+      s = s.encode Encoding.default_external if defined? Encoding
+      s
+    end
+
+    ##
+    # This returns a diff-able human-readable version of +obj+. This
+    # differs from the regular mu_pp because it expands escaped
+    # newlines and makes hex-values generic (like object_ids). This
+    # uses mu_pp to do the first pass and then cleans it up.
+
+    def mu_pp_for_diff obj
+      mu_pp(obj).gsub(/\\n/, "\n").gsub(/:0x[a-fA-F0-9]{4,}/m, ":0xXXXXXX")
+    end
+
+    ##
+    # Fails unless +test+ is truthy.
+
+    def assert test, msg = nil
+      self.assertions += 1
+      unless test then
+        msg ||= "Failed assertion, no message given."
+        msg = msg.call if Proc === msg
+        raise Minitest::Assertion, msg
+      end
+      true
+    end
+
+    def _synchronize # :nodoc:
+      yield
+    end
+
+    ##
+    # Fails unless +obj+ is empty.
+
+    def assert_empty obj, msg = nil
+      msg = message(msg) { "Expected #{mu_pp(obj)} to be empty" }
+      assert_respond_to obj, :empty?
+      assert obj.empty?, msg
+    end
+
+    E = "" # :nodoc:
+
+    ##
+    # Fails unless <tt>exp == act</tt> printing the difference between
+    # the two, if possible.
+    #
+    # If there is no visible difference but the assertion fails, you
+    # should suspect that your #== is buggy, or your inspect output is
+    # missing crucial details.
+    #
+    # For floats use assert_in_delta.
+    #
+    # See also: Minitest::Assertions.diff
+
+    def assert_equal exp, act, msg = nil
+      msg = message(msg, E) { diff exp, act }
+      assert exp == act, msg
+    end
+
+    ##
+    # For comparing Floats.  Fails unless +exp+ and +act+ are within +delta+
+    # of each other.
+    #
+    #   assert_in_delta Math::PI, (22.0 / 7.0), 0.01
+
+    def assert_in_delta exp, act, delta = 0.001, msg = nil
+      n = (exp - act).abs
+      msg = message(msg) {
+        "Expected |#{exp} - #{act}| (#{n}) to be <= #{delta}"
+      }
+      assert delta >= n, msg
+    end
+
+    ##
+    # For comparing Floats.  Fails unless +exp+ and +act+ have a relative
+    # error less than +epsilon+.
+
+    def assert_in_epsilon a, b, epsilon = 0.001, msg = nil
+      assert_in_delta a, b, [a.abs, b.abs].min * epsilon, msg
+    end
+
+    ##
+    # Fails unless +collection+ includes +obj+.
+
+    def assert_includes collection, obj, msg = nil
+      msg = message(msg) {
+        "Expected #{mu_pp(collection)} to include #{mu_pp(obj)}"
+      }
+      assert_respond_to collection, :include?
+      assert collection.include?(obj), msg
+    end
+
+    ##
+    # Fails unless +obj+ is an instance of +cls+.
+
+    def assert_instance_of cls, obj, msg = nil
+      msg = message(msg) {
+        "Expected #{mu_pp(obj)} to be an instance of #{cls}, not #{obj.class}"
+      }
+
+      assert obj.instance_of?(cls), msg
+    end
+
+    ##
+    # Fails unless +obj+ is a kind of +cls+.
+
+    def assert_kind_of cls, obj, msg = nil
+      msg = message(msg) {
+        "Expected #{mu_pp(obj)} to be a kind of #{cls}, not #{obj.class}" }
+
+      assert obj.kind_of?(cls), msg
+    end
+
+    ##
+    # Fails unless +matcher+ <tt>=~</tt> +obj+.
+
+    def assert_match matcher, obj, msg = nil
+      msg = message(msg) { "Expected #{mu_pp matcher} to match #{mu_pp obj}" }
+      assert_respond_to matcher, :"=~"
+      matcher = Regexp.new Regexp.escape matcher if String === matcher
+      assert matcher =~ obj, msg
+    end
+
+    ##
+    # Fails unless +obj+ is nil
+
+    def assert_nil obj, msg = nil
+      msg = message(msg) { "Expected #{mu_pp(obj)} to be nil" }
+      assert obj.nil?, msg
+    end
+
+    ##
+    # For testing with binary operators. Eg:
+    #
+    #   assert_operator 5, :<=, 4
+
+    def assert_operator o1, op, o2 = UNDEFINED, msg = nil
+      return assert_predicate o1, op, msg if UNDEFINED == o2
+      msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op} #{mu_pp(o2)}" }
+      assert o1.__send__(op, o2), msg
+    end
+
+    ##
+    # Fails if stdout or stderr do not output the expected results.
+    # Pass in nil if you don't care about that streams output. Pass in
+    # "" if you require it to be silent. Pass in a regexp if you want
+    # to pattern match.
+    #
+    # NOTE: this uses #capture_io, not #capture_subprocess_io.
+    #
+    # See also: #assert_silent
+
+    def assert_output stdout = nil, stderr = nil
+      out, err = capture_io do
+        yield
+      end
+
+      err_msg = Regexp === stderr ? :assert_match : :assert_equal if stderr
+      out_msg = Regexp === stdout ? :assert_match : :assert_equal if stdout
+
+      y = send err_msg, stderr, err, "In stderr" if err_msg
+      x = send out_msg, stdout, out, "In stdout" if out_msg
+
+      (!stdout || x) && (!stderr || y)
+    end
+
+    ##
+    # For testing with predicates. Eg:
+    #
+    #   assert_predicate str, :empty?
+    #
+    # This is really meant for specs and is front-ended by assert_operator:
+    #
+    #   str.must_be :empty?
+
+    def assert_predicate o1, op, msg = nil
+      msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op}" }
+      assert o1.__send__(op), msg
+    end
+
+    ##
+    # Fails unless the block raises one of +exp+. Returns the
+    # exception matched so you can check the message, attributes, etc.
+    #
+    # +exp+ takes an optional message on the end to help explain
+    # failures and defaults to StandardError if no exception class is
+    # passed.
+
+    def assert_raises *exp
+      msg = "#{exp.pop}.\n" if String === exp.last
+      exp << StandardError if exp.empty?
+
+      begin
+        yield
+      rescue *exp => e
+        pass # count assertion
+        return e
+      rescue Minitest::Skip
+        # don't count assertion
+        raise
+      rescue SignalException, SystemExit
+        raise
+      rescue Exception => e
+        flunk proc {
+          exception_details(e, "#{msg}#{mu_pp(exp)} exception expected, not")
+        }
+      end
+
+      exp = exp.first if exp.size == 1
+
+      flunk "#{msg}#{mu_pp(exp)} expected but nothing was raised."
+    end
+
+    ##
+    # Fails unless +obj+ responds to +meth+.
+
+    def assert_respond_to obj, meth, msg = nil
+      msg = message(msg) {
+        "Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}"
+      }
+      assert obj.respond_to?(meth), msg
+    end
+
+    ##
+    # Fails unless +exp+ and +act+ are #equal?
+
+    def assert_same exp, act, msg = nil
+      msg = message(msg) {
+        data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id]
+        "Expected %s (oid=%d) to be the same as %s (oid=%d)" % data
+      }
+      assert exp.equal?(act), msg
+    end
+
+    ##
+    # +send_ary+ is a receiver, message and arguments.
+    #
+    # Fails unless the call returns a true value
+
+    def assert_send send_ary, m = nil
+      recv, msg, *args = send_ary
+      m = message(m) {
+        "Expected #{mu_pp(recv)}.#{msg}(*#{mu_pp(args)}) to return true" }
+      assert recv.__send__(msg, *args), m
+    end
+
+    ##
+    # Fails if the block outputs anything to stderr or stdout.
+    #
+    # See also: #assert_output
+
+    def assert_silent
+      assert_output "", "" do
+        yield
+      end
+    end
+
+    ##
+    # Fails unless the block throws +sym+
+
+    def assert_throws sym, msg = nil
+      default = "Expected #{mu_pp(sym)} to have been thrown"
+      caught = true
+      catch(sym) do
+        begin
+          yield
+        rescue ThreadError => e       # wtf?!? 1.8 + threads == suck
+          default += ", not \:#{e.message[/uncaught throw \`(\w+?)\'/, 1]}"
+        rescue ArgumentError => e     # 1.9 exception
+          default += ", not #{e.message.split(/ /).last}"
+        rescue NameError => e         # 1.8 exception
+          default += ", not #{e.name.inspect}"
+        end
+        caught = false
+      end
+
+      assert caught, message(msg) { default }
+    end
+
+    ##
+    # Captures $stdout and $stderr into strings:
+    #
+    #   out, err = capture_io do
+    #     puts "Some info"
+    #     warn "You did a bad thing"
+    #   end
+    #
+    #   assert_match %r%info%, out
+    #   assert_match %r%bad%, err
+    #
+    # NOTE: For efficiency, this method uses StringIO and does not
+    # capture IO for subprocesses. Use #capture_subprocess_io for
+    # that.
+
+    def capture_io
+      _synchronize do
+        begin
+          captured_stdout, captured_stderr = StringIO.new, StringIO.new
+
+          orig_stdout, orig_stderr = $stdout, $stderr
+          $stdout, $stderr         = captured_stdout, captured_stderr
+
+          yield
+
+          return captured_stdout.string, captured_stderr.string
+        ensure
+          $stdout = orig_stdout
+          $stderr = orig_stderr
+        end
+      end
+    end
+
+    ##
+    # Captures $stdout and $stderr into strings, using Tempfile to
+    # ensure that subprocess IO is captured as well.
+    #
+    #   out, err = capture_subprocess_io do
+    #     system "echo Some info"
+    #     system "echo You did a bad thing 1>&2"
+    #   end
+    #
+    #   assert_match %r%info%, out
+    #   assert_match %r%bad%, err
+    #
+    # NOTE: This method is approximately 10x slower than #capture_io so
+    # only use it when you need to test the output of a subprocess.
+
+    def capture_subprocess_io
+      _synchronize do
+        begin
+          require "tempfile"
+
+          captured_stdout, captured_stderr = Tempfile.new("out"), Tempfile.new("err")
+
+          orig_stdout, orig_stderr = $stdout.dup, $stderr.dup
+          $stdout.reopen captured_stdout
+          $stderr.reopen captured_stderr
+
+          yield
+
+          $stdout.rewind
+          $stderr.rewind
+
+          return captured_stdout.read, captured_stderr.read
+        ensure
+          captured_stdout.unlink
+          captured_stderr.unlink
+          $stdout.reopen orig_stdout
+          $stderr.reopen orig_stderr
+        end
+      end
+    end
+
+    ##
+    # Returns details for exception +e+
+
+    def exception_details e, msg
+      [
+       "#{msg}",
+       "Class: <#{e.class}>",
+       "Message: <#{e.message.inspect}>",
+       "---Backtrace---",
+       "#{Minitest.filter_backtrace(e.backtrace).join("\n")}",
+       "---------------",
+      ].join "\n"
+    end
+
+    ##
+    # Fails with +msg+
+
+    def flunk msg = nil
+      msg ||= "Epic Fail!"
+      assert false, msg
+    end
+
+    ##
+    # Returns a proc that will output +msg+ along with the default message.
+
+    def message msg = nil, ending = nil, &default
+      proc {
+        msg = msg.call.chomp(".") if Proc === msg
+        custom_message = "#{msg}.\n" unless msg.nil? or msg.to_s.empty?
+        "#{custom_message}#{default.call}#{ending || "."}"
+      }
+    end
+
+    ##
+    # used for counting assertions
+
+    def pass _msg = nil
+      assert true
+    end
+
+    ##
+    # Fails if +test+ is truthy.
+
+    def refute test, msg = nil
+      msg ||= "Failed refutation, no message given"
+      not assert !test, msg
+    end
+
+    ##
+    # Fails if +obj+ is empty.
+
+    def refute_empty obj, msg = nil
+      msg = message(msg) { "Expected #{mu_pp(obj)} to not be empty" }
+      assert_respond_to obj, :empty?
+      refute obj.empty?, msg
+    end
+
+    ##
+    # Fails if <tt>exp == act</tt>.
+    #
+    # For floats use refute_in_delta.
+
+    def refute_equal exp, act, msg = nil
+      msg = message(msg) {
+        "Expected #{mu_pp(act)} to not be equal to #{mu_pp(exp)}"
+      }
+      refute exp == act, msg
+    end
+
+    ##
+    # For comparing Floats.  Fails if +exp+ is within +delta+ of +act+.
+    #
+    #   refute_in_delta Math::PI, (22.0 / 7.0)
+
+    def refute_in_delta exp, act, delta = 0.001, msg = nil
+      n = (exp - act).abs
+      msg = message(msg) {
+        "Expected |#{exp} - #{act}| (#{n}) to not be <= #{delta}"
+      }
+      refute delta >= n, msg
+    end
+
+    ##
+    # For comparing Floats.  Fails if +exp+ and +act+ have a relative error
+    # less than +epsilon+.
+
+    def refute_in_epsilon a, b, epsilon = 0.001, msg = nil
+      refute_in_delta a, b, a * epsilon, msg
+    end
+
+    ##
+    # Fails if +collection+ includes +obj+.
+
+    def refute_includes collection, obj, msg = nil
+      msg = message(msg) {
+        "Expected #{mu_pp(collection)} to not include #{mu_pp(obj)}"
+      }
+      assert_respond_to collection, :include?
+      refute collection.include?(obj), msg
+    end
+
+    ##
+    # Fails if +obj+ is an instance of +cls+.
+
+    def refute_instance_of cls, obj, msg = nil
+      msg = message(msg) {
+        "Expected #{mu_pp(obj)} to not be an instance of #{cls}"
+      }
+      refute obj.instance_of?(cls), msg
+    end
+
+    ##
+    # Fails if +obj+ is a kind of +cls+.
+
+    def refute_kind_of cls, obj, msg = nil
+      msg = message(msg) { "Expected #{mu_pp(obj)} to not be a kind of #{cls}" }
+      refute obj.kind_of?(cls), msg
+    end
+
+    ##
+    # Fails if +matcher+ <tt>=~</tt> +obj+.
+
+    def refute_match matcher, obj, msg = nil
+      msg = message(msg) { "Expected #{mu_pp matcher} to not match #{mu_pp obj}" }
+      assert_respond_to matcher, :"=~"
+      matcher = Regexp.new Regexp.escape matcher if String === matcher
+      refute matcher =~ obj, msg
+    end
+
+    ##
+    # Fails if +obj+ is nil.
+
+    def refute_nil obj, msg = nil
+      msg = message(msg) { "Expected #{mu_pp(obj)} to not be nil" }
+      refute obj.nil?, msg
+    end
+
+    ##
+    # Fails if +o1+ is not +op+ +o2+. Eg:
+    #
+    #   refute_operator 1, :>, 2 #=> pass
+    #   refute_operator 1, :<, 2 #=> fail
+
+    def refute_operator o1, op, o2 = UNDEFINED, msg = nil
+      return refute_predicate o1, op, msg if UNDEFINED == o2
+      msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op} #{mu_pp(o2)}" }
+      refute o1.__send__(op, o2), msg
+    end
+
+    ##
+    # For testing with predicates.
+    #
+    #   refute_predicate str, :empty?
+    #
+    # This is really meant for specs and is front-ended by refute_operator:
+    #
+    #   str.wont_be :empty?
+
+    def refute_predicate o1, op, msg = nil
+      msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op}" }
+      refute o1.__send__(op), msg
+    end
+
+    ##
+    # Fails if +obj+ responds to the message +meth+.
+
+    def refute_respond_to obj, meth, msg = nil
+      msg = message(msg) { "Expected #{mu_pp(obj)} to not respond to #{meth}" }
+
+      refute obj.respond_to?(meth), msg
+    end
+
+    ##
+    # Fails if +exp+ is the same (by object identity) as +act+.
+
+    def refute_same exp, act, msg = nil
+      msg = message(msg) {
+        data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id]
+        "Expected %s (oid=%d) to not be the same as %s (oid=%d)" % data
+      }
+      refute exp.equal?(act), msg
+    end
+
+    ##
+    # Skips the current run. If run in verbose-mode, the skipped run
+    # gets listed at the end of the run but doesn't cause a failure
+    # exit code.
+
+    def skip msg = nil, bt = caller
+      msg ||= "Skipped, no message given"
+      @skip = true
+      raise Minitest::Skip, msg, bt
+    end
+
+    ##
+    # Was this testcase skipped? Meant for #teardown.
+
+    def skipped?
+      defined?(@skip) and @skip
+    end
+  end
+end
diff --git a/app/server/vendor/minitest-5.8.1/lib/minitest/autorun.rb b/app/server/vendor/minitest-5.8.1/lib/minitest/autorun.rb
new file mode 100644
index 0000000..a02659d
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/lib/minitest/autorun.rb
@@ -0,0 +1,12 @@
+begin
+  require "rubygems"
+  gem "minitest"
+rescue Gem::LoadError
+  # do nothing
+end
+
+require "minitest"
+require "minitest/spec"
+require "minitest/mock"
+
+Minitest.autorun
diff --git a/app/server/vendor/minitest-5.8.1/lib/minitest/benchmark.rb b/app/server/vendor/minitest-5.8.1/lib/minitest/benchmark.rb
new file mode 100644
index 0000000..0841c41
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/lib/minitest/benchmark.rb
@@ -0,0 +1,425 @@
+require "minitest/unit"
+require "minitest/spec"
+
+module Minitest
+  ##
+  # Subclass Benchmark to create your own benchmark runs. Methods
+  # starting with "bench_" get executed on a per-class.
+  #
+  # See Minitest::Assertions
+
+  class Benchmark < Test
+    def self.io # :nodoc:
+      @io
+    end
+
+    def io # :nodoc:
+      self.class.io
+    end
+
+    def self.run reporter, options = {} # :nodoc:
+      # NOTE: this is truly horrible... but I don't see a way around this ATM.
+      @io = reporter.reporters.first.io
+      super
+    end
+
+    def self.runnable_methods # :nodoc:
+      methods_matching(/^bench_/)
+    end
+
+    ##
+    # Returns a set of ranges stepped exponentially from +min+ to
+    # +max+ by powers of +base+. Eg:
+    #
+    #   bench_exp(2, 16, 2) # => [2, 4, 8, 16]
+
+    def self.bench_exp min, max, base = 10
+      min = (Math.log10(min) / Math.log10(base)).to_i
+      max = (Math.log10(max) / Math.log10(base)).to_i
+
+      (min..max).map { |m| base ** m }.to_a
+    end
+
+    ##
+    # Returns a set of ranges stepped linearly from +min+ to +max+ by
+    # +step+. Eg:
+    #
+    #   bench_linear(20, 40, 10) # => [20, 30, 40]
+
+    def self.bench_linear min, max, step = 10
+      (min..max).step(step).to_a
+    rescue LocalJumpError # 1.8.6
+      r = []; (min..max).step(step) { |n| r << n }; r
+    end
+
+    ##
+    # Specifies the ranges used for benchmarking for that class.
+    # Defaults to exponential growth from 1 to 10k by powers of 10.
+    # Override if you need different ranges for your benchmarks.
+    #
+    # See also: ::bench_exp and ::bench_linear.
+
+    def self.bench_range
+      bench_exp 1, 10_000
+    end
+
+    ##
+    # Runs the given +work+, gathering the times of each run. Range
+    # and times are then passed to a given +validation+ proc. Outputs
+    # the benchmark name and times in tab-separated format, making it
+    # easy to paste into a spreadsheet for graphing or further
+    # analysis.
+    #
+    # Ranges are specified by ::bench_range.
+    #
+    # Eg:
+    #
+    #   def bench_algorithm
+    #     validation = proc { |x, y| ... }
+    #     assert_performance validation do |n|
+    #       @obj.algorithm(n)
+    #     end
+    #   end
+
+    def assert_performance validation, &work
+      range = self.class.bench_range
+
+      io.print "#{self.name}"
+
+      times = []
+
+      range.each do |x|
+        GC.start
+        t0 = Minitest.clock_time
+        instance_exec(x, &work)
+        t = Minitest.clock_time - t0
+
+        io.print "\t%9.6f" % t
+        times << t
+      end
+      io.puts
+
+      validation[range, times]
+    end
+
+    ##
+    # Runs the given +work+ and asserts that the times gathered fit to
+    # match a constant rate (eg, linear slope == 0) within a given
+    # +threshold+. Note: because we're testing for a slope of 0, R^2
+    # is not a good determining factor for the fit, so the threshold
+    # is applied against the slope itself. As such, you probably want
+    # to tighten it from the default.
+    #
+    # See http://www.graphpad.com/curvefit/goodness_of_fit.htm for
+    # more details.
+    #
+    # Fit is calculated by #fit_linear.
+    #
+    # Ranges are specified by ::bench_range.
+    #
+    # Eg:
+    #
+    #   def bench_algorithm
+    #     assert_performance_constant 0.9999 do |n|
+    #       @obj.algorithm(n)
+    #     end
+    #   end
+
+    def assert_performance_constant threshold = 0.99, &work
+      validation = proc do |range, times|
+        a, b, rr = fit_linear range, times
+        assert_in_delta 0, b, 1 - threshold
+        [a, b, rr]
+      end
+
+      assert_performance validation, &work
+    end
+
+    ##
+    # Runs the given +work+ and asserts that the times gathered fit to
+    # match a exponential curve within a given error +threshold+.
+    #
+    # Fit is calculated by #fit_exponential.
+    #
+    # Ranges are specified by ::bench_range.
+    #
+    # Eg:
+    #
+    #   def bench_algorithm
+    #     assert_performance_exponential 0.9999 do |n|
+    #       @obj.algorithm(n)
+    #     end
+    #   end
+
+    def assert_performance_exponential threshold = 0.99, &work
+      assert_performance validation_for_fit(:exponential, threshold), &work
+    end
+
+    ##
+    # Runs the given +work+ and asserts that the times gathered fit to
+    # match a logarithmic curve within a given error +threshold+.
+    #
+    # Fit is calculated by #fit_logarithmic.
+    #
+    # Ranges are specified by ::bench_range.
+    #
+    # Eg:
+    #
+    #   def bench_algorithm
+    #     assert_performance_logarithmic 0.9999 do |n|
+    #       @obj.algorithm(n)
+    #     end
+    #   end
+
+    def assert_performance_logarithmic threshold = 0.99, &work
+      assert_performance validation_for_fit(:logarithmic, threshold), &work
+    end
+
+    ##
+    # Runs the given +work+ and asserts that the times gathered fit to
+    # match a straight line within a given error +threshold+.
+    #
+    # Fit is calculated by #fit_linear.
+    #
+    # Ranges are specified by ::bench_range.
+    #
+    # Eg:
+    #
+    #   def bench_algorithm
+    #     assert_performance_linear 0.9999 do |n|
+    #       @obj.algorithm(n)
+    #     end
+    #   end
+
+    def assert_performance_linear threshold = 0.99, &work
+      assert_performance validation_for_fit(:linear, threshold), &work
+    end
+
+    ##
+    # Runs the given +work+ and asserts that the times gathered curve
+    # fit to match a power curve within a given error +threshold+.
+    #
+    # Fit is calculated by #fit_power.
+    #
+    # Ranges are specified by ::bench_range.
+    #
+    # Eg:
+    #
+    #   def bench_algorithm
+    #     assert_performance_power 0.9999 do |x|
+    #       @obj.algorithm
+    #     end
+    #   end
+
+    def assert_performance_power threshold = 0.99, &work
+      assert_performance validation_for_fit(:power, threshold), &work
+    end
+
+    ##
+    # Takes an array of x/y pairs and calculates the general R^2 value.
+    #
+    # See: http://en.wikipedia.org/wiki/Coefficient_of_determination
+
+    def fit_error xys
+      y_bar  = sigma(xys) { |_, y| y } / xys.size.to_f
+      ss_tot = sigma(xys) { |_, y| (y    - y_bar) ** 2 }
+      ss_err = sigma(xys) { |x, y| (yield(x) - y) ** 2 }
+
+      1 - (ss_err / ss_tot)
+    end
+
+    ##
+    # To fit a functional form: y = ae^(bx).
+    #
+    # Takes x and y values and returns [a, b, r^2].
+    #
+    # See: http://mathworld.wolfram.com/LeastSquaresFittingExponential.html
+
+    def fit_exponential xs, ys
+      n     = xs.size
+      xys   = xs.zip(ys)
+      sxlny = sigma(xys) { |x, y| x * Math.log(y) }
+      slny  = sigma(xys) { |_, y| Math.log(y)     }
+      sx2   = sigma(xys) { |x, _| x * x           }
+      sx    = sigma xs
+
+      c = n * sx2 - sx ** 2
+      a = (slny * sx2 - sx * sxlny) / c
+      b = ( n * sxlny - sx * slny ) / c
+
+      return Math.exp(a), b, fit_error(xys) { |x| Math.exp(a + b * x) }
+    end
+
+    ##
+    # To fit a functional form: y = a + b*ln(x).
+    #
+    # Takes x and y values and returns [a, b, r^2].
+    #
+    # See: http://mathworld.wolfram.com/LeastSquaresFittingLogarithmic.html
+
+    def fit_logarithmic xs, ys
+      n     = xs.size
+      xys   = xs.zip(ys)
+      slnx2 = sigma(xys) { |x, _| Math.log(x) ** 2 }
+      slnx  = sigma(xys) { |x, _| Math.log(x)      }
+      sylnx = sigma(xys) { |x, y| y * Math.log(x)  }
+      sy    = sigma(xys) { |_, y| y                }
+
+      c = n * slnx2 - slnx ** 2
+      b = ( n * sylnx - sy * slnx ) / c
+      a = (sy - b * slnx) / n
+
+      return a, b, fit_error(xys) { |x| a + b * Math.log(x) }
+    end
+
+    ##
+    # Fits the functional form: a + bx.
+    #
+    # Takes x and y values and returns [a, b, r^2].
+    #
+    # See: http://mathworld.wolfram.com/LeastSquaresFitting.html
+
+    def fit_linear xs, ys
+      n   = xs.size
+      xys = xs.zip(ys)
+      sx  = sigma xs
+      sy  = sigma ys
+      sx2 = sigma(xs)  { |x|   x ** 2 }
+      sxy = sigma(xys) { |x, y| x * y  }
+
+      c = n * sx2 - sx**2
+      a = (sy * sx2 - sx * sxy) / c
+      b = ( n * sxy - sx * sy ) / c
+
+      return a, b, fit_error(xys) { |x| a + b * x }
+    end
+
+    ##
+    # To fit a functional form: y = ax^b.
+    #
+    # Takes x and y values and returns [a, b, r^2].
+    #
+    # See: http://mathworld.wolfram.com/LeastSquaresFittingPowerLaw.html
+
+    def fit_power xs, ys
+      n       = xs.size
+      xys     = xs.zip(ys)
+      slnxlny = sigma(xys) { |x, y| Math.log(x) * Math.log(y) }
+      slnx    = sigma(xs)  { |x   | Math.log(x)               }
+      slny    = sigma(ys)  { |   y| Math.log(y)               }
+      slnx2   = sigma(xs)  { |x   | Math.log(x) ** 2          }
+
+      b = (n * slnxlny - slnx * slny) / (n * slnx2 - slnx ** 2)
+      a = (slny - b * slnx) / n
+
+      return Math.exp(a), b, fit_error(xys) { |x| (Math.exp(a) * (x ** b)) }
+    end
+
+    ##
+    # Enumerates over +enum+ mapping +block+ if given, returning the
+    # sum of the result. Eg:
+    #
+    #   sigma([1, 2, 3])                # => 1 + 2 + 3 => 7
+    #   sigma([1, 2, 3]) { |n| n ** 2 } # => 1 + 4 + 9 => 14
+
+    def sigma enum, &block
+      enum = enum.map(&block) if block
+      enum.inject { |sum, n| sum + n }
+    end
+
+    ##
+    # Returns a proc that calls the specified fit method and asserts
+    # that the error is within a tolerable threshold.
+
+    def validation_for_fit msg, threshold
+      proc do |range, times|
+        a, b, rr = send "fit_#{msg}", range, times
+        assert_operator rr, :>=, threshold
+        [a, b, rr]
+      end
+    end
+  end
+end
+
+module Minitest
+  ##
+  # The spec version of Minitest::Benchmark.
+
+  class BenchSpec < Benchmark
+    extend Minitest::Spec::DSL
+
+    ##
+    # This is used to define a new benchmark method. You usually don't
+    # use this directly and is intended for those needing to write new
+    # performance curve fits (eg: you need a specific polynomial fit).
+    #
+    # See ::bench_performance_linear for an example of how to use this.
+
+    def self.bench name, &block
+      define_method "bench_#{name.gsub(/\W+/, "_")}", &block
+    end
+
+    ##
+    # Specifies the ranges used for benchmarking for that class.
+    #
+    #   bench_range do
+    #     bench_exp(2, 16, 2)
+    #   end
+    #
+    # See Minitest::Benchmark#bench_range for more details.
+
+    def self.bench_range &block
+      return super unless block
+
+      meta = (class << self; self; end)
+      meta.send :define_method, "bench_range", &block
+    end
+
+    ##
+    # Create a benchmark that verifies that the performance is linear.
+    #
+    #   describe "my class Bench" do
+    #     bench_performance_linear "fast_algorithm", 0.9999 do |n|
+    #       @obj.fast_algorithm(n)
+    #     end
+    #   end
+
+    def self.bench_performance_linear name, threshold = 0.99, &work
+      bench name do
+        assert_performance_linear threshold, &work
+      end
+    end
+
+    ##
+    # Create a benchmark that verifies that the performance is constant.
+    #
+    #   describe "my class Bench" do
+    #     bench_performance_constant "zoom_algorithm!" do |n|
+    #       @obj.zoom_algorithm!(n)
+    #     end
+    #   end
+
+    def self.bench_performance_constant name, threshold = 0.99, &work
+      bench name do
+        assert_performance_constant threshold, &work
+      end
+    end
+
+    ##
+    # Create a benchmark that verifies that the performance is exponential.
+    #
+    #   describe "my class Bench" do
+    #     bench_performance_exponential "algorithm" do |n|
+    #       @obj.algorithm(n)
+    #     end
+    #   end
+
+    def self.bench_performance_exponential name, threshold = 0.99, &work
+      bench name do
+        assert_performance_exponential threshold, &work
+      end
+    end
+  end
+
+  Minitest::Spec.register_spec_type(/Bench(mark)?$/, Minitest::BenchSpec)
+end
diff --git a/app/server/vendor/minitest-5.8.1/lib/minitest/expectations.rb b/app/server/vendor/minitest-5.8.1/lib/minitest/expectations.rb
new file mode 100644
index 0000000..53b3186
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/lib/minitest/expectations.rb
@@ -0,0 +1,284 @@
+##
+# It's where you hide your "assertions".
+#
+# Please note, because of the way that expectations are implemented,
+# all expectations (eg must_equal) are dependent upon a thread local
+# variable +:current_spec+. If your specs rely on mixing threads into
+# the specs themselves, you're better off using assertions or the new
+# _(value) wrapper. For example:
+#
+#     it "should still work in threads" do
+#       my_threaded_thingy do
+#         (1+1).must_equal 2         # bad
+#         assert_equal 2, 1+1        # good
+#         _(1 + 1).must_equal 2      # good
+#         value(1 + 1).must_equal 2  # good, also #expect
+#       end
+#     end
+
+module Minitest::Expectations
+
+  ##
+  # See Minitest::Assertions#assert_empty.
+  #
+  #    collection.must_be_empty
+  #
+  # :method: must_be_empty
+
+  infect_an_assertion :assert_empty, :must_be_empty, :unary
+
+  ##
+  # See Minitest::Assertions#assert_equal
+  #
+  #    a.must_equal b
+  #
+  # :method: must_equal
+
+  infect_an_assertion :assert_equal, :must_equal
+
+  ##
+  # See Minitest::Assertions#assert_in_delta
+  #
+  #    n.must_be_close_to m [, delta]
+  #
+  # :method: must_be_close_to
+
+  infect_an_assertion :assert_in_delta, :must_be_close_to
+
+  alias :must_be_within_delta :must_be_close_to # :nodoc:
+
+  ##
+  # See Minitest::Assertions#assert_in_epsilon
+  #
+  #    n.must_be_within_epsilon m [, epsilon]
+  #
+  # :method: must_be_within_epsilon
+
+  infect_an_assertion :assert_in_epsilon, :must_be_within_epsilon
+
+  ##
+  # See Minitest::Assertions#assert_includes
+  #
+  #    collection.must_include obj
+  #
+  # :method: must_include
+
+  infect_an_assertion :assert_includes, :must_include, :reverse
+
+  ##
+  # See Minitest::Assertions#assert_instance_of
+  #
+  #    obj.must_be_instance_of klass
+  #
+  # :method: must_be_instance_of
+
+  infect_an_assertion :assert_instance_of, :must_be_instance_of
+
+  ##
+  # See Minitest::Assertions#assert_kind_of
+  #
+  #    obj.must_be_kind_of mod
+  #
+  # :method: must_be_kind_of
+
+  infect_an_assertion :assert_kind_of, :must_be_kind_of
+
+  ##
+  # See Minitest::Assertions#assert_match
+  #
+  #    a.must_match b
+  #
+  # :method: must_match
+
+  infect_an_assertion :assert_match, :must_match
+
+  ##
+  # See Minitest::Assertions#assert_nil
+  #
+  #    obj.must_be_nil
+  #
+  # :method: must_be_nil
+
+  infect_an_assertion :assert_nil, :must_be_nil, :unary
+
+  ##
+  # See Minitest::Assertions#assert_operator
+  #
+  #    n.must_be :<=, 42
+  #
+  # This can also do predicates:
+  #
+  #    str.must_be :empty?
+  #
+  # :method: must_be
+
+  infect_an_assertion :assert_operator, :must_be, :reverse
+
+  ##
+  # See Minitest::Assertions#assert_output
+  #
+  #    proc { ... }.must_output out_or_nil [, err]
+  #
+  # :method: must_output
+
+  infect_an_assertion :assert_output, :must_output, :block
+
+  ##
+  # See Minitest::Assertions#assert_raises
+  #
+  #    proc { ... }.must_raise exception
+  #
+  # :method: must_raise
+
+  infect_an_assertion :assert_raises, :must_raise, :block
+
+  ##
+  # See Minitest::Assertions#assert_respond_to
+  #
+  #    obj.must_respond_to msg
+  #
+  # :method: must_respond_to
+
+  infect_an_assertion :assert_respond_to, :must_respond_to, :reverse
+
+  ##
+  # See Minitest::Assertions#assert_same
+  #
+  #    a.must_be_same_as b
+  #
+  # :method: must_be_same_as
+
+  infect_an_assertion :assert_same, :must_be_same_as
+
+  ##
+  # See Minitest::Assertions#assert_silent
+  #
+  #    proc { ... }.must_be_silent
+  #
+  # :method: must_be_silent
+
+  infect_an_assertion :assert_silent, :must_be_silent, :block
+
+  ##
+  # See Minitest::Assertions#assert_throws
+  #
+  #    proc { ... }.must_throw sym
+  #
+  # :method: must_throw
+
+  infect_an_assertion :assert_throws, :must_throw, :block
+
+  ##
+  # See Minitest::Assertions#refute_empty
+  #
+  #    collection.wont_be_empty
+  #
+  # :method: wont_be_empty
+
+  infect_an_assertion :refute_empty, :wont_be_empty, :unary
+
+  ##
+  # See Minitest::Assertions#refute_equal
+  #
+  #    a.wont_equal b
+  #
+  # :method: wont_equal
+
+  infect_an_assertion :refute_equal, :wont_equal
+
+  ##
+  # See Minitest::Assertions#refute_in_delta
+  #
+  #    n.wont_be_close_to m [, delta]
+  #
+  # :method: wont_be_close_to
+
+  infect_an_assertion :refute_in_delta, :wont_be_close_to
+
+  alias :wont_be_within_delta :wont_be_close_to # :nodoc:
+
+  ##
+  # See Minitest::Assertions#refute_in_epsilon
+  #
+  #    n.wont_be_within_epsilon m [, epsilon]
+  #
+  # :method: wont_be_within_epsilon
+
+  infect_an_assertion :refute_in_epsilon, :wont_be_within_epsilon
+
+  ##
+  # See Minitest::Assertions#refute_includes
+  #
+  #    collection.wont_include obj
+  #
+  # :method: wont_include
+
+  infect_an_assertion :refute_includes, :wont_include, :reverse
+
+  ##
+  # See Minitest::Assertions#refute_instance_of
+  #
+  #    obj.wont_be_instance_of klass
+  #
+  # :method: wont_be_instance_of
+
+  infect_an_assertion :refute_instance_of, :wont_be_instance_of
+
+  ##
+  # See Minitest::Assertions#refute_kind_of
+  #
+  #    obj.wont_be_kind_of mod
+  #
+  # :method: wont_be_kind_of
+
+  infect_an_assertion :refute_kind_of, :wont_be_kind_of
+
+  ##
+  # See Minitest::Assertions#refute_match
+  #
+  #    a.wont_match b
+  #
+  # :method: wont_match
+
+  infect_an_assertion :refute_match, :wont_match
+
+  ##
+  # See Minitest::Assertions#refute_nil
+  #
+  #    obj.wont_be_nil
+  #
+  # :method: wont_be_nil
+
+  infect_an_assertion :refute_nil, :wont_be_nil, :unary
+
+  ##
+  # See Minitest::Assertions#refute_operator
+  #
+  #    n.wont_be :<=, 42
+  #
+  # This can also do predicates:
+  #
+  #    str.wont_be :empty?
+  #
+  # :method: wont_be
+
+  infect_an_assertion :refute_operator, :wont_be, :reverse
+
+  ##
+  # See Minitest::Assertions#refute_respond_to
+  #
+  #    obj.wont_respond_to msg
+  #
+  # :method: wont_respond_to
+
+  infect_an_assertion :refute_respond_to, :wont_respond_to, :reverse
+
+  ##
+  # See Minitest::Assertions#refute_same
+  #
+  #    a.wont_be_same_as b
+  #
+  # :method: wont_be_same_as
+
+  infect_an_assertion :refute_same, :wont_be_same_as
+end
diff --git a/app/server/vendor/minitest-5.8.1/lib/minitest/hell.rb b/app/server/vendor/minitest-5.8.1/lib/minitest/hell.rb
new file mode 100644
index 0000000..cbdc8c1
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/lib/minitest/hell.rb
@@ -0,0 +1,11 @@
+require "minitest/parallel"
+
+class Minitest::Test
+  class << self
+    alias :old_test_order :test_order # :nodoc:
+
+    def test_order # :nodoc:
+      :parallel
+    end
+  end
+end
diff --git a/app/server/vendor/minitest-5.8.1/lib/minitest/mock.rb b/app/server/vendor/minitest-5.8.1/lib/minitest/mock.rb
new file mode 100644
index 0000000..50edc1a
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/lib/minitest/mock.rb
@@ -0,0 +1,229 @@
+class MockExpectationError < StandardError; end # :nodoc:
+
+module Minitest # :nodoc:
+
+  ##
+  # A simple and clean mock object framework.
+  #
+  # All mock objects are an instance of Mock
+
+  class Mock
+    alias :__respond_to? :respond_to?
+
+    overridden_methods = %w[
+      ===
+      class
+      inspect
+      instance_eval
+      instance_variables
+      object_id
+      public_send
+      respond_to_missing?
+      send
+      to_s
+    ]
+
+    instance_methods.each do |m|
+      undef_method m unless overridden_methods.include?(m.to_s) || m =~ /^__/
+    end
+
+    overridden_methods.map(&:to_sym).each do |method_id|
+      define_method method_id do |*args, &b|
+        if @expected_calls.key? method_id then
+          method_missing(method_id, *args, &b)
+        else
+          super(*args, &b)
+        end
+      end
+    end
+
+    def initialize(delegator = nil) # :nodoc:
+      @delegator = delegator
+      @expected_calls = Hash.new { |calls, name| calls[name] = [] }
+      @actual_calls   = Hash.new { |calls, name| calls[name] = [] }
+    end
+
+    ##
+    # Expect that method +name+ is called, optionally with +args+ or a
+    # +blk+, and returns +retval+.
+    #
+    #   @mock.expect(:meaning_of_life, 42)
+    #   @mock.meaning_of_life # => 42
+    #
+    #   @mock.expect(:do_something_with, true, [some_obj, true])
+    #   @mock.do_something_with(some_obj, true) # => true
+    #
+    #   @mock.expect(:do_something_else, true) do |a1, a2|
+    #     a1 == "buggs" && a2 == :bunny
+    #   end
+    #
+    # +args+ is compared to the expected args using case equality (ie, the
+    # '===' operator), allowing for less specific expectations.
+    #
+    #   @mock.expect(:uses_any_string, true, [String])
+    #   @mock.uses_any_string("foo") # => true
+    #   @mock.verify  # => true
+    #
+    #   @mock.expect(:uses_one_string, true, ["foo"])
+    #   @mock.uses_one_string("bar") # => true
+    #   @mock.verify  # => raises MockExpectationError
+
+    def expect(name, retval, args = [], &blk)
+      name = name.to_sym
+
+      if block_given?
+        raise ArgumentError, "args ignored when block given" unless args.empty?
+        @expected_calls[name] << { :retval => retval, :block => blk }
+      else
+        raise ArgumentError, "args must be an array" unless Array === args
+        @expected_calls[name] << { :retval => retval, :args => args }
+      end
+      self
+    end
+
+    def __call name, data # :nodoc:
+      case data
+      when Hash then
+        "#{name}(#{data[:args].inspect[1..-2]}) => #{data[:retval].inspect}"
+      else
+        data.map { |d| __call name, d }.join ", "
+      end
+    end
+
+    ##
+    # Verify that all methods were called as expected. Raises
+    # +MockExpectationError+ if the mock object was not called as
+    # expected.
+
+    def verify
+      @expected_calls.each do |name, calls|
+        calls.each do |expected|
+          raise MockExpectationError, "expected #{__call name, expected}, got [#{__call name, @actual_calls[name]}]" if
+            @actual_calls.key?(name) and
+            not @actual_calls[name].include?(expected)
+
+          raise MockExpectationError, "expected #{__call name, expected}" unless
+            @actual_calls.key?(name) and
+            @actual_calls[name].include?(expected)
+        end
+      end
+      true
+    end
+
+    def method_missing(sym, *args, &block) # :nodoc:
+      unless @expected_calls.key?(sym) then
+        if @delegator && @delegator.respond_to?(sym)
+          return @delegator.public_send(sym, *args, &block)
+        else
+          raise NoMethodError, "unmocked method %p, expected one of %p" %
+            [sym, @expected_calls.keys.sort_by(&:to_s)]
+        end
+      end
+
+      index = @actual_calls[sym].length
+      expected_call = @expected_calls[sym][index]
+
+      unless expected_call then
+        raise MockExpectationError, "No more expects available for %p: %p" %
+          [sym, args]
+      end
+
+      expected_args, retval, val_block =
+        expected_call.values_at(:args, :retval, :block)
+
+      if val_block then
+        # keep "verify" happy
+        @actual_calls[sym] << expected_call
+
+        raise MockExpectationError, "mocked method %p failed block w/ %p" %
+          [sym, args] unless val_block.call(*args, &block)
+
+        return retval
+      end
+
+      if expected_args.size != args.size then
+        raise ArgumentError, "mocked method %p expects %d arguments, got %d" %
+          [sym, expected_args.size, args.size]
+      end
+
+      zipped_args = expected_args.zip(args)
+      fully_matched = zipped_args.all? { |mod, a|
+        mod === a or mod == a
+      }
+
+      unless fully_matched then
+        raise MockExpectationError, "mocked method %p called with unexpected arguments %p" %
+          [sym, args]
+      end
+
+      @actual_calls[sym] << {
+        :retval => retval,
+        :args => zipped_args.map! { |mod, a| mod === a ? mod : a },
+      }
+
+      retval
+    end
+
+    def respond_to?(sym, include_private = false) # :nodoc:
+      return true if @expected_calls.key? sym.to_sym
+      return true if @delegator && @delegator.respond_to?(sym, include_private)
+      __respond_to?(sym, include_private)
+    end
+  end
+end
+
+##
+# Object extensions for Minitest::Mock.
+
+class Object
+
+  ##
+  # Add a temporary stubbed method replacing +name+ for the duration
+  # of the +block+. If +val_or_callable+ responds to #call, then it
+  # returns the result of calling it, otherwise returns the value
+  # as-is. If stubbed method yields a block, +block_args+ will be
+  # passed along. Cleans up the stub at the end of the +block+. The
+  # method +name+ must exist before stubbing.
+  #
+  #     def test_stale_eh
+  #       obj_under_test = Something.new
+  #       refute obj_under_test.stale?
+  #
+  #       Time.stub :now, Time.at(0) do
+  #         assert obj_under_test.stale?
+  #       end
+  #     end
+  #
+
+  def stub name, val_or_callable, *block_args
+    new_name = "__minitest_stub__#{name}"
+
+    metaclass = class << self; self; end
+
+    if respond_to? name and not methods.map(&:to_s).include? name.to_s then
+      metaclass.send :define_method, name do |*args|
+        super(*args)
+      end
+    end
+
+    metaclass.send :alias_method, new_name, name
+
+    metaclass.send :define_method, name do |*args, &blk|
+      ret = if val_or_callable.respond_to? :call then
+              val_or_callable.call(*args)
+            else
+              val_or_callable
+            end
+
+      blk.call(*block_args) if blk
+
+      ret
+    end
+
+    yield self
+  ensure
+    metaclass.send :undef_method, name
+    metaclass.send :alias_method, name, new_name
+    metaclass.send :undef_method, new_name
+  end
+end
diff --git a/app/server/vendor/minitest-5.8.1/lib/minitest/parallel.rb b/app/server/vendor/minitest-5.8.1/lib/minitest/parallel.rb
new file mode 100644
index 0000000..25bbf80
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/lib/minitest/parallel.rb
@@ -0,0 +1,69 @@
+module Minitest
+  module Parallel
+
+    ##
+    # The engine used to run multiple tests in parallel.
+
+    class Executor
+
+      ##
+      # The size of the pool of workers.
+
+      attr_reader :size
+
+      ##
+      # Create a parallel test executor of with +size+ workers.
+
+      def initialize size
+        @size  = size
+        @queue = Queue.new
+        @pool  = nil
+      end
+
+      ##
+      # Start the executor
+
+      def start
+        @pool  = size.times.map {
+          Thread.new(@queue) do |queue|
+            Thread.current.abort_on_exception = true
+            while (job = queue.pop)
+              klass, method, reporter = job
+              result = Minitest.run_one_method klass, method
+              reporter.synchronize { reporter.record result }
+            end
+          end
+        }
+      end
+
+      ##
+      # Add a job to the queue
+
+      def << work; @queue << work; end
+
+      ##
+      # Shuts down the pool of workers by signalling them to quit and
+      # waiting for them all to finish what they're currently working
+      # on.
+
+      def shutdown
+        size.times { @queue << nil }
+        @pool.each(&:join)
+      end
+    end
+
+    module Test
+      def _synchronize; Test.io_lock.synchronize { yield }; end # :nodoc:
+
+      module ClassMethods # :nodoc:
+        def run_one_method klass, method_name, reporter
+          Minitest.parallel_executor << [klass, method_name, reporter]
+        end
+
+        def test_order
+          :parallel
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/minitest-5.8.1/lib/minitest/pride.rb b/app/server/vendor/minitest-5.8.1/lib/minitest/pride.rb
new file mode 100644
index 0000000..f3b8e47
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/lib/minitest/pride.rb
@@ -0,0 +1,4 @@
+require "minitest"
+
+Minitest.load_plugins
+Minitest::PrideIO.pride!
diff --git a/app/server/vendor/minitest-5.8.1/lib/minitest/pride_plugin.rb b/app/server/vendor/minitest-5.8.1/lib/minitest/pride_plugin.rb
new file mode 100644
index 0000000..335cd5c
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/lib/minitest/pride_plugin.rb
@@ -0,0 +1,142 @@
+require "minitest"
+
+module Minitest
+  def self.plugin_pride_options opts, _options # :nodoc:
+    opts.on "-p", "--pride", "Pride. Show your testing pride!" do
+      PrideIO.pride!
+    end
+  end
+
+  def self.plugin_pride_init options # :nodoc:
+    if PrideIO.pride? then
+      klass = ENV["TERM"] =~ /^xterm|-256color$/ ? PrideLOL : PrideIO
+      io    = klass.new options[:io]
+
+      self.reporter.reporters.grep(Minitest::Reporter).each do |rep|
+        rep.io = io if rep.io.tty?
+      end
+    end
+  end
+
+  ##
+  # Show your testing pride!
+
+  class PrideIO
+    ##
+    # Activate the pride plugin. Called from both -p option and minitest/pride
+
+    def self.pride!
+      @pride = true
+    end
+
+    ##
+    # Are we showing our testing pride?
+
+    def self.pride?
+      @pride ||= false
+    end
+
+    # Start an escape sequence
+    ESC = "\e["
+
+    # End the escape sequence
+    NND = "#{ESC}0m"
+
+    # The IO we're going to pipe through.
+    attr_reader :io
+
+    def initialize io # :nodoc:
+      @io = io
+      # stolen from /System/Library/Perl/5.10.0/Term/ANSIColor.pm
+      # also reference http://en.wikipedia.org/wiki/ANSI_escape_code
+      @colors ||= (31..36).to_a
+      @size   = @colors.size
+      @index  = 0
+    end
+
+    ##
+    # Wrap print to colorize the output.
+
+    def print o
+      case o
+      when "." then
+        io.print pride o
+      when "E", "F" then
+        io.print "#{ESC}41m#{ESC}37m#{o}#{NND}"
+      when "S" then
+        io.print pride o
+      else
+        io.print o
+      end
+    end
+
+    def puts(*o) # :nodoc:
+      o.map! { |s|
+        s.to_s.sub(/Finished/) {
+          @index = 0
+          "Fabulous run".split(//).map { |c|
+            pride(c)
+          }.join
+        }
+      }
+
+      io.puts(*o)
+    end
+
+    ##
+    # Color a string.
+
+    def pride string
+      string = "*" if string == "."
+      c = @colors[@index % @size]
+      @index += 1
+      "#{ESC}#{c}m#{string}#{NND}"
+    end
+
+    def method_missing msg, *args # :nodoc:
+      io.send(msg, *args)
+    end
+  end
+
+  ##
+  # If you thought the PrideIO was colorful...
+  #
+  # (Inspired by lolcat, but with clean math)
+
+  class PrideLOL < PrideIO
+    PI_3 = Math::PI / 3 # :nodoc:
+
+    def initialize io # :nodoc:
+      # walk red, green, and blue around a circle separated by equal thirds.
+      #
+      # To visualize, type this into wolfram-alpha:
+      #
+      #   plot (3*sin(x)+3), (3*sin(x+2*pi/3)+3), (3*sin(x+4*pi/3)+3)
+
+      # 6 has wide pretty gradients. 3 == lolcat, about half the width
+      @colors = (0...(6 * 7)).map { |n|
+        n *= 1.0 / 6
+        r  = (3 * Math.sin(n           ) + 3).to_i
+        g  = (3 * Math.sin(n + 2 * PI_3) + 3).to_i
+        b  = (3 * Math.sin(n + 4 * PI_3) + 3).to_i
+
+        # Then we take rgb and encode them in a single number using base 6.
+        # For some mysterious reason, we add 16... to clear the bottom 4 bits?
+        # Yes... they're ugly.
+
+        36 * r + 6 * g + b + 16
+      }
+
+      super
+    end
+
+    ##
+    # Make the string even more colorful. Damnit.
+
+    def pride string
+      c = @colors[@index % @size]
+      @index += 1
+      "#{ESC}38;5;#{c}m#{string}#{NND}"
+    end
+  end
+end
diff --git a/app/server/vendor/minitest-5.8.1/lib/minitest/spec.rb b/app/server/vendor/minitest-5.8.1/lib/minitest/spec.rb
new file mode 100644
index 0000000..9c958db
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/lib/minitest/spec.rb
@@ -0,0 +1,331 @@
+require "minitest/test"
+
+class Module # :nodoc:
+  def infect_an_assertion meth, new_name, dont_flip = false # :nodoc:
+    block = dont_flip == :block
+    dont_flip = false if block
+
+    # warn "%-22p -> %p %p" % [meth, new_name, dont_flip]
+    self.class_eval <<-EOM, __FILE__, __LINE__ + 1
+      def #{new_name} *args
+        Minitest::Expectation.new(self, Minitest::Spec.current).#{new_name}(*args)
+      end
+    EOM
+
+    Minitest::Expectation.class_eval <<-EOM, __FILE__, __LINE__ + 1
+      def #{new_name} *args
+        case
+        when #{!!dont_flip} then
+          ctx.#{meth}(target, *args)
+        when #{block} && Proc === target then
+          ctx.#{meth}(*args, &target)
+        else
+          ctx.#{meth}(args.first, target, *args[1..-1])
+        end
+      end
+    EOM
+  end
+end
+
+Minitest::Expectation = Struct.new :target, :ctx # :nodoc:
+
+##
+# Kernel extensions for minitest
+
+module Kernel
+  ##
+  # Describe a series of expectations for a given target +desc+.
+  #
+  # Defines a test class subclassing from either Minitest::Spec or
+  # from the surrounding describe's class. The surrounding class may
+  # subclass Minitest::Spec manually in order to easily share code:
+  #
+  #     class MySpec < Minitest::Spec
+  #       # ... shared code ...
+  #     end
+  #
+  #     class TestStuff < MySpec
+  #       it "does stuff" do
+  #         # shared code available here
+  #       end
+  #       describe "inner stuff" do
+  #         it "still does stuff" do
+  #           # ...and here
+  #         end
+  #       end
+  #     end
+  #
+  # For more information on getting started with writing specs, see:
+  #
+  # http://www.rubyinside.com/a-minitestspec-tutorial-elegant-spec-style-testing-that-comes-with-ruby-5354.html
+  #
+  # For some suggestions on how to improve your specs, try:
+  #
+  # http://betterspecs.org
+  #
+  # but do note that several items there are debatable or specific to
+  # rspec.
+  #
+  # For more information about expectations, see Minitest::Expectations.
+
+  def describe desc, *additional_desc, &block # :doc:
+    stack = Minitest::Spec.describe_stack
+    name  = [stack.last, desc, *additional_desc].compact.join("::")
+    sclas = stack.last || if Class === self && kind_of?(Minitest::Spec::DSL) then
+                            self
+                          else
+                            Minitest::Spec.spec_type desc, *additional_desc
+                          end
+
+    cls = sclas.create name, desc
+
+    stack.push cls
+    cls.class_eval(&block)
+    stack.pop
+    cls
+  end
+  private :describe
+end
+
+##
+# Minitest::Spec -- The faster, better, less-magical spec framework!
+#
+# For a list of expectations, see Minitest::Expectations.
+
+class Minitest::Spec < Minitest::Test
+
+  def self.current # :nodoc:
+    Thread.current[:current_spec]
+  end
+
+  def initialize name # :nodoc:
+    super
+    Thread.current[:current_spec] = self
+  end
+
+  ##
+  # Oh look! A Minitest::Spec::DSL module! Eat your heart out DHH.
+
+  module DSL
+    ##
+    # Contains pairs of matchers and Spec classes to be used to
+    # calculate the superclass of a top-level describe. This allows for
+    # automatically customizable spec types.
+    #
+    # See: register_spec_type and spec_type
+
+    TYPES = [[//, Minitest::Spec]]
+
+    ##
+    # Register a new type of spec that matches the spec's description.
+    # This method can take either a Regexp and a spec class or a spec
+    # class and a block that takes the description and returns true if
+    # it matches.
+    #
+    # Eg:
+    #
+    #     register_spec_type(/Controller$/, Minitest::Spec::Rails)
+    #
+    # or:
+    #
+    #     register_spec_type(Minitest::Spec::RailsModel) do |desc|
+    #       desc.superclass == ActiveRecord::Base
+    #     end
+
+    def register_spec_type(*args, &block)
+      if block then
+        matcher, klass = block, args.first
+      else
+        matcher, klass = *args
+      end
+      TYPES.unshift [matcher, klass]
+    end
+
+    ##
+    # Figure out the spec class to use based on a spec's description. Eg:
+    #
+    #     spec_type("BlahController") # => Minitest::Spec::Rails
+
+    def spec_type desc, *additional
+      TYPES.find { |matcher, _klass|
+        if matcher.respond_to? :call then
+          matcher.call desc, *additional
+        else
+          matcher === desc.to_s
+        end
+      }.last
+    end
+
+    def describe_stack # :nodoc:
+      Thread.current[:describe_stack] ||= []
+    end
+
+    def children # :nodoc:
+      @children ||= []
+    end
+
+    def nuke_test_methods! # :nodoc:
+      self.public_instance_methods.grep(/^test_/).each do |name|
+        self.send :undef_method, name
+      end
+    end
+
+    ##
+    # Define a 'before' action. Inherits the way normal methods should.
+    #
+    # NOTE: +type+ is ignored and is only there to make porting easier.
+    #
+    # Equivalent to Minitest::Test#setup.
+
+    def before _type = nil, &block
+      define_method :setup do
+        super()
+        self.instance_eval(&block)
+      end
+    end
+
+    ##
+    # Define an 'after' action. Inherits the way normal methods should.
+    #
+    # NOTE: +type+ is ignored and is only there to make porting easier.
+    #
+    # Equivalent to Minitest::Test#teardown.
+
+    def after _type = nil, &block
+      define_method :teardown do
+        self.instance_eval(&block)
+        super()
+      end
+    end
+
+    ##
+    # Define an expectation with name +desc+. Name gets morphed to a
+    # proper test method name. For some freakish reason, people who
+    # write specs don't like class inheritance, so this goes way out of
+    # its way to make sure that expectations aren't inherited.
+    #
+    # This is also aliased to #specify and doesn't require a +desc+ arg.
+    #
+    # Hint: If you _do_ want inheritance, use minitest/test. You can mix
+    # and match between assertions and expectations as much as you want.
+
+    def it desc = "anonymous", &block
+      block ||= proc { skip "(no tests defined)" }
+
+      @specs ||= 0
+      @specs += 1
+
+      name = "test_%04d_%s" % [ @specs, desc ]
+
+      undef_klasses = self.children.reject { |c| c.public_method_defined? name }
+
+      define_method name, &block
+
+      undef_klasses.each do |undef_klass|
+        undef_klass.send :undef_method, name
+      end
+
+      name
+    end
+
+    ##
+    # Essentially, define an accessor for +name+ with +block+.
+    #
+    # Why use let instead of def? I honestly don't know.
+
+    def let name, &block
+      name = name.to_s
+      pre, post = "let '#{name}' cannot ", ". Please use another name."
+      methods = Minitest::Spec.instance_methods.map(&:to_s) - %w[subject]
+      raise ArgumentError, "#{pre}begin with 'test'#{post}" if
+        name =~ /\Atest/
+      raise ArgumentError, "#{pre}override a method in Minitest::Spec#{post}" if
+        methods.include? name
+
+      define_method name do
+        @_memoized ||= {}
+        @_memoized.fetch(name) { |k| @_memoized[k] = instance_eval(&block) }
+      end
+    end
+
+    ##
+    # Another lazy man's accessor generator. Made even more lazy by
+    # setting the name for you to +subject+.
+
+    def subject &block
+      let :subject, &block
+    end
+
+    def create name, desc # :nodoc:
+      cls = Class.new(self) do
+        @name = name
+        @desc = desc
+
+        nuke_test_methods!
+      end
+
+      children << cls
+
+      cls
+    end
+
+    def name # :nodoc:
+      defined?(@name) ? @name : super
+    end
+
+    def to_s # :nodoc:
+      name # Can't alias due to 1.8.7, not sure why
+    end
+
+    attr_reader :desc # :nodoc:
+    alias :specify :it
+
+    ##
+    # Rdoc... why are you so dumb?
+
+    module InstanceMethods
+      ##
+      # Returns a value monad that has all of Expectations methods
+      # available to it.
+      #
+      # Also aliased to #value and #expect for your aesthetic pleasure:
+      #
+      #         _(1 + 1).must_equal 2
+      #     value(1 + 1).must_equal 2
+      #    expect(1 + 1).must_equal 2
+      #
+      # This method of expectation-based testing is preferable to
+      # straight-expectation methods (on Object) because it stores its
+      # test context, bypassing our hacky use of thread-local variables.
+      #
+      # At some point, the methods on Object will be deprecated and then
+      # removed.
+
+      def _ value = nil, &block
+        Minitest::Expectation.new block || value, self
+      end
+
+      alias value _
+      alias expect _
+
+      def before_setup # :nodoc:
+        super
+        Thread.current[:current_spec] = self
+      end
+    end
+
+    def self.extended obj # :nodoc:
+      obj.send :include, InstanceMethods
+    end
+  end
+
+  extend DSL
+
+  TYPES = DSL::TYPES # :nodoc:
+end
+
+require "minitest/expectations"
+
+class Object # :nodoc:
+  include Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
+end
diff --git a/app/server/vendor/minitest-5.8.1/lib/minitest/test.rb b/app/server/vendor/minitest-5.8.1/lib/minitest/test.rb
new file mode 100644
index 0000000..c64166b
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/lib/minitest/test.rb
@@ -0,0 +1,285 @@
+require "minitest" unless defined? Minitest::Runnable
+
+module Minitest
+  ##
+  # Subclass Test to create your own tests. Typically you'll want a
+  # Test subclass per implementation class.
+  #
+  # See Minitest::Assertions
+
+  class Test < Runnable
+    require "minitest/assertions"
+    include Minitest::Assertions
+
+    PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, # :nodoc:
+                              Interrupt, SystemExit]
+
+    class << self; attr_accessor :io_lock; end # :nodoc:
+    self.io_lock = Mutex.new
+
+    ##
+    # Call this at the top of your tests when you absolutely
+    # positively need to have ordered tests. In doing so, you're
+    # admitting that you suck and your tests are weak.
+
+    def self.i_suck_and_my_tests_are_order_dependent!
+      class << self
+        undef_method :test_order if method_defined? :test_order
+        define_method :test_order do :alpha end
+      end
+    end
+
+    ##
+    # Make diffs for this Test use #pretty_inspect so that diff
+    # in assert_equal can have more details. NOTE: this is much slower
+    # than the regular inspect but much more usable for complex
+    # objects.
+
+    def self.make_my_diffs_pretty!
+      require "pp"
+
+      define_method :mu_pp do |o|
+        o.pretty_inspect
+      end
+    end
+
+    ##
+    # Call this at the top of your tests when you want to run your
+    # tests in parallel. In doing so, you're admitting that you rule
+    # and your tests are awesome.
+
+    def self.parallelize_me!
+      include Minitest::Parallel::Test
+      extend Minitest::Parallel::Test::ClassMethods
+    end
+
+    ##
+    # Returns all instance methods starting with "test_". Based on
+    # #test_order, the methods are either sorted, randomized
+    # (default), or run in parallel.
+
+    def self.runnable_methods
+      methods = methods_matching(/^test_/)
+
+      case self.test_order
+      when :random, :parallel then
+        max = methods.size
+        methods.sort.sort_by { rand max }
+      when :alpha, :sorted then
+        methods.sort
+      else
+        raise "Unknown test_order: #{self.test_order.inspect}"
+      end
+    end
+
+    ##
+    # Defines the order to run tests (:random by default). Override
+    # this or use a convenience method to change it for your tests.
+
+    def self.test_order
+      :random
+    end
+
+    ##
+    # The time it took to run this test.
+
+    attr_accessor :time
+
+    def marshal_dump # :nodoc:
+      super << self.time
+    end
+
+    def marshal_load ary # :nodoc:
+      self.time = ary.pop
+      super
+    end
+
+    TEARDOWN_METHODS = %w[ before_teardown teardown after_teardown ] # :nodoc:
+
+    ##
+    # Runs a single test with setup/teardown hooks.
+
+    def run
+      with_info_handler do
+        time_it do
+          capture_exceptions do
+            before_setup; setup; after_setup
+
+            self.send self.name
+          end
+
+          TEARDOWN_METHODS.each do |hook|
+            capture_exceptions do
+              self.send hook
+            end
+          end
+        end
+      end
+
+      self # per contract
+    end
+
+    ##
+    # Provides before/after hooks for setup and teardown. These are
+    # meant for library writers, NOT for regular test authors. See
+    # #before_setup for an example.
+
+    module LifecycleHooks
+
+      ##
+      # Runs before every test, before setup. This hook is meant for
+      # libraries to extend minitest. It is not meant to be used by
+      # test developers.
+      #
+      # As a simplistic example:
+      #
+      #   module MyMinitestPlugin
+      #     def before_setup
+      #       super
+      #       # ... stuff to do before setup is run
+      #     end
+      #
+      #     def after_setup
+      #       # ... stuff to do after setup is run
+      #       super
+      #     end
+      #
+      #     def before_teardown
+      #       super
+      #       # ... stuff to do before teardown is run
+      #     end
+      #
+      #     def after_teardown
+      #       # ... stuff to do after teardown is run
+      #       super
+      #     end
+      #   end
+      #
+      #   class MiniTest::Test
+      #     include MyMinitestPlugin
+      #   end
+
+      def before_setup; end
+
+      ##
+      # Runs before every test. Use this to set up before each test
+      # run.
+
+      def setup; end
+
+      ##
+      # Runs before every test, after setup. This hook is meant for
+      # libraries to extend minitest. It is not meant to be used by
+      # test developers.
+      #
+      # See #before_setup for an example.
+
+      def after_setup; end
+
+      ##
+      # Runs after every test, before teardown. This hook is meant for
+      # libraries to extend minitest. It is not meant to be used by
+      # test developers.
+      #
+      # See #before_setup for an example.
+
+      def before_teardown; end
+
+      ##
+      # Runs after every test. Use this to clean up after each test
+      # run.
+
+      def teardown; end
+
+      ##
+      # Runs after every test, after teardown. This hook is meant for
+      # libraries to extend minitest. It is not meant to be used by
+      # test developers.
+      #
+      # See #before_setup for an example.
+
+      def after_teardown; end
+    end # LifecycleHooks
+
+    def capture_exceptions # :nodoc:
+      yield
+    rescue *PASSTHROUGH_EXCEPTIONS
+      raise
+    rescue Assertion => e
+      self.failures << e
+    rescue Exception => e
+      self.failures << UnexpectedError.new(e)
+    end
+
+    ##
+    # Did this run error?
+
+    def error?
+      self.failures.any? { |f| UnexpectedError === f }
+    end
+
+    ##
+    # The location identifier of this test.
+
+    def location
+      loc = " [#{self.failure.location}]" unless passed? or error?
+      "#{self.class}##{self.name}#{loc}"
+    end
+
+    ##
+    # Did this run pass?
+    #
+    # Note: skipped runs are not considered passing, but they don't
+    # cause the process to exit non-zero.
+
+    def passed?
+      not self.failure
+    end
+
+    ##
+    # Returns ".", "F", or "E" based on the result of the run.
+
+    def result_code
+      self.failure and self.failure.result_code or "."
+    end
+
+    ##
+    # Was this run skipped?
+
+    def skipped?
+      self.failure and Skip === self.failure
+    end
+
+    def time_it # :nodoc:
+      t0 = Minitest.clock_time
+
+      yield
+    ensure
+      self.time = Minitest.clock_time - t0
+    end
+
+    def to_s # :nodoc:
+      return location if passed? and not skipped?
+
+      failures.map { |failure|
+        "#{failure.result_label}:\n#{self.location}:\n#{failure.message}\n"
+      }.join "\n"
+    end
+
+    def with_info_handler &block # :nodoc:
+      t0 = Minitest.clock_time
+
+      handler = lambda do
+        warn "\nCurrent: %s#%s %.2fs" % [self.class, self.name, Minitest.clock_time - t0]
+      end
+
+      self.class.on_signal "INFO", handler, &block
+    end
+
+    include LifecycleHooks
+    include Guard
+    extend Guard
+  end # Test
+end
+
+require "minitest/unit" unless defined?(MiniTest) # compatibility layer only
diff --git a/app/server/vendor/minitest-5.8.1/lib/minitest/unit.rb b/app/server/vendor/minitest-5.8.1/lib/minitest/unit.rb
new file mode 100644
index 0000000..28b549f
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/lib/minitest/unit.rb
@@ -0,0 +1,45 @@
+# :stopdoc:
+
+unless defined?(Minitest) then
+  # all of this crap is just to avoid circular requires and is only
+  # needed if a user requires "minitest/unit" directly instead of
+  # "minitest/autorun", so we also warn
+
+  from = caller.reject { |s| s =~ /rubygems/ }.join("\n  ")
+  warn "Warning: you should require 'minitest/autorun' instead."
+  warn %(Warning: or add 'gem "minitest"' before 'require "minitest/autorun"')
+  warn "From:\n  #{from}"
+
+  module Minitest; end
+  MiniTest = Minitest # prevents minitest.rb from requiring back to us
+  require "minitest"
+end
+
+MiniTest = Minitest unless defined?(MiniTest)
+
+module Minitest
+  class Unit
+    VERSION = Minitest::VERSION
+    class TestCase < Minitest::Test
+      def self.inherited klass # :nodoc:
+        from = caller.first
+        warn "MiniTest::Unit::TestCase is now Minitest::Test. From #{from}"
+        super
+      end
+    end
+
+    def self.autorun # :nodoc:
+      from = caller.first
+      warn "MiniTest::Unit.autorun is now Minitest.autorun. From #{from}"
+      Minitest.autorun
+    end
+
+    def self.after_tests(&b)
+      from = caller.first
+      warn "MiniTest::Unit.after_tests is now Minitest.after_run. From #{from}"
+      Minitest.after_run(&b)
+    end
+  end
+end
+
+# :startdoc:
diff --git a/app/server/vendor/minitest-5.8.1/test/minitest/metametameta.rb b/app/server/vendor/minitest-5.8.1/test/minitest/metametameta.rb
new file mode 100644
index 0000000..e2f87d0
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/test/minitest/metametameta.rb
@@ -0,0 +1,90 @@
+require "tempfile"
+require "stringio"
+require "minitest/autorun"
+
+class Minitest::Test
+  def clean s
+    s.gsub(/^ {6}/, "")
+  end
+end
+
+class MetaMetaMetaTestCase < Minitest::Test
+  attr_accessor :reporter, :output, :tu
+
+  def run_tu_with_fresh_reporter flags = %w[--seed 42]
+    options = Minitest.process_args flags
+
+    @output = StringIO.new("")
+
+    self.reporter = Minitest::CompositeReporter.new
+    reporter << Minitest::SummaryReporter.new(@output, options)
+    reporter << Minitest::ProgressReporter.new(@output, options)
+
+    reporter.start
+
+    yield(reporter) if block_given?
+
+    @tus ||= [@tu]
+    @tus.each do |tu|
+      Minitest::Runnable.runnables.delete tu
+
+      tu.run reporter, options
+    end
+
+    reporter.report
+  end
+
+  def first_reporter
+    reporter.reporters.first
+  end
+
+  def assert_report expected, flags = %w[--seed 42], &block
+    header = clean <<-EOM
+      Run options: #{flags.map { |s| s =~ /\|/ ? s.inspect : s }.join " "}
+
+      # Running:
+
+    EOM
+
+    run_tu_with_fresh_reporter flags, &block
+
+    output = normalize_output @output.string.dup
+
+    assert_equal header + expected, output
+  end
+
+  def normalize_output output
+    output.sub!(/Finished in .*/, "Finished in 0.00")
+    output.sub!(/Loaded suite .*/, "Loaded suite blah")
+
+    output.gsub!(/ = \d+.\d\d s = /, " = 0.00 s = ")
+    output.gsub!(/0x[A-Fa-f0-9]+/, "0xXXX")
+    output.gsub!(/ +$/, "")
+
+    if windows? then
+      output.gsub!(/\[(?:[A-Za-z]:)?[^\]:]+:\d+\]/, "[FILE:LINE]")
+      output.gsub!(/^(\s+)(?:[A-Za-z]:)?[^:]+:\d+:in/, '\1FILE:LINE:in')
+    else
+      output.gsub!(/\[[^\]:]+:\d+\]/, "[FILE:LINE]")
+      output.gsub!(/^(\s+)[^:]+:\d+:in/, '\1FILE:LINE:in')
+    end
+
+    output
+  end
+
+  def restore_env
+    old_value = ENV["MT_NO_SKIP_MSG"]
+    ENV.delete "MT_NO_SKIP_MSG"
+
+    yield
+  ensure
+    ENV["MT_NO_SKIP_MSG"] = old_value
+  end
+
+  def setup
+    super
+    srand 42
+    Minitest::Test.reset
+    @tu = nil
+  end
+end
diff --git a/app/server/vendor/minitest-5.8.1/test/minitest/test_minitest_benchmark.rb b/app/server/vendor/minitest-5.8.1/test/minitest/test_minitest_benchmark.rb
new file mode 100644
index 0000000..88abf77
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/test/minitest/test_minitest_benchmark.rb
@@ -0,0 +1,137 @@
+require "minitest/autorun"
+require "minitest/benchmark"
+
+##
+# Used to verify data:
+# http://www.wolframalpha.com/examples/RegressionAnalysis.html
+
+class TestMinitestBenchmark < Minitest::Test
+  def test_cls_bench_exp
+    assert_equal [2, 4, 8, 16, 32], Minitest::Benchmark.bench_exp(2, 32, 2)
+  end
+
+  def test_cls_bench_linear
+    assert_equal [2, 4, 6, 8, 10], Minitest::Benchmark.bench_linear(2, 10, 2)
+  end
+
+  def test_cls_runnable_methods
+    assert_equal [], Minitest::Benchmark.runnable_methods
+
+    c = Class.new(Minitest::Benchmark) do
+      def bench_blah
+      end
+    end
+
+    assert_equal ["bench_blah"], c.runnable_methods
+  end
+
+  def test_cls_bench_range
+    assert_equal [1, 10, 100, 1_000, 10_000], Minitest::Benchmark.bench_range
+  end
+
+  def test_fit_exponential_clean
+    x = [1.0, 2.0, 3.0, 4.0, 5.0]
+    y = x.map { |n| 1.1 * Math.exp(2.1 * n) }
+
+    assert_fit :exponential, x, y, 1.0, 1.1, 2.1
+  end
+
+  def test_fit_exponential_noisy
+    x = [1.0, 1.9, 2.6, 3.4, 5.0]
+    y = [12, 10, 8.2, 6.9, 5.9]
+
+    # verified with Numbers and R
+    assert_fit :exponential, x, y, 0.95, 13.81148, -0.1820
+  end
+
+  def test_fit_logarithmic_clean
+    x = [1.0, 2.0, 3.0, 4.0, 5.0]
+    y = x.map { |n| 1.1 + 2.1 * Math.log(n) }
+
+    assert_fit :logarithmic, x, y, 1.0, 1.1, 2.1
+  end
+
+  def test_fit_logarithmic_noisy
+    x = [1.0, 2.0, 3.0, 4.0, 5.0]
+    # Generated with
+    # y = x.map { |n| jitter = 0.999 + 0.002 * rand; (Math.log(n) ) * jitter }
+    y = [0.0, 0.6935, 1.0995, 1.3873, 1.6097]
+
+    assert_fit :logarithmic, x, y, 0.95, 0, 1
+  end
+
+  def test_fit_constant_clean
+    x = (1..5).to_a
+    y = [5.0, 5.0, 5.0, 5.0, 5.0]
+
+    assert_fit :linear, x, y, nil, 5.0, 0
+  end
+
+  def test_fit_constant_noisy
+    x = (1..5).to_a
+    y = [1.0, 1.2, 1.0, 0.8, 1.0]
+
+    # verified in numbers and R
+    assert_fit :linear, x, y, nil, 1.12, -0.04
+  end
+
+  def test_fit_linear_clean
+    # y = m * x + b where m = 2.2, b = 3.1
+    x = (1..5).to_a
+    y = x.map { |n| 2.2 * n + 3.1 }
+
+    assert_fit :linear, x, y, 1.0, 3.1, 2.2
+  end
+
+  def test_fit_linear_noisy
+    x = [ 60,  61,  62,  63,  65]
+    y = [3.1, 3.6, 3.8, 4.0, 4.1]
+
+    # verified in numbers and R
+    assert_fit :linear, x, y, 0.8315, -7.9635, 0.1878
+  end
+
+  def test_fit_power_clean
+    # y = A x ** B, where B = b and A = e ** a
+    # if, A = 1, B = 2, then
+
+    x = [1.0, 2.0, 3.0, 4.0, 5.0]
+    y = [1.0, 4.0, 9.0, 16.0, 25.0]
+
+    assert_fit :power, x, y, 1.0, 1.0, 2.0
+  end
+
+  def test_fit_power_noisy
+    # from www.engr.uidaho.edu/thompson/courses/ME330/lecture/least_squares.html
+    x = [10, 12, 15, 17, 20, 22, 25, 27, 30, 32, 35]
+    y = [95, 105, 125, 141, 173, 200, 253, 298, 385, 459, 602]
+
+    # verified in numbers
+    assert_fit :power, x, y, 0.90, 2.6217, 1.4556
+
+    # income to % of households below income amount
+    # http://library.wolfram.com/infocenter/Conferences/6461/PowerLaws.nb
+    x = [15_000, 25_000, 35_000, 50_000, 75_000, 100_000]
+    y = [0.154, 0.283, 0.402, 0.55, 0.733, 0.843]
+
+    # verified in numbers
+    assert_fit :power, x, y, 0.96, 3.119e-5, 0.8959
+  end
+
+  def assert_fit msg, x, y, fit, exp_a, exp_b
+    bench = Minitest::Benchmark.new :blah
+
+    a, b, rr = bench.send "fit_#{msg}", x, y
+
+    assert_operator rr, :>=, fit if fit
+    assert_in_delta exp_a, a
+    assert_in_delta exp_b, b
+  end
+end
+
+describe "my class Bench" do
+  klass = self
+  it "should provide bench methods" do
+    klass.must_respond_to :bench
+  end
+end
diff --git a/app/server/vendor/minitest-5.8.1/test/minitest/test_minitest_mock.rb b/app/server/vendor/minitest-5.8.1/test/minitest/test_minitest_mock.rb
new file mode 100644
index 0000000..6e3d9b3
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/test/minitest/test_minitest_mock.rb
@@ -0,0 +1,498 @@
+require "minitest/autorun"
+
+class TestMinitestMock < Minitest::Test
+  parallelize_me!
+
+  def setup
+    @mock = Minitest::Mock.new.expect(:foo, nil)
+    @mock.expect(:meaning_of_life, 42)
+  end
+
+  def test_create_stub_method
+    assert_nil @mock.foo
+  end
+
+  def test_allow_return_value_specification
+    assert_equal 42, @mock.meaning_of_life
+  end
+
+  def test_blow_up_if_not_called
+    @mock.foo
+
+    util_verify_bad "expected meaning_of_life() => 42"
+  end
+
+  def test_not_blow_up_if_everything_called
+    @mock.foo
+    @mock.meaning_of_life
+
+    assert @mock.verify
+  end
+
+  def test_allow_expectations_to_be_added_after_creation
+    @mock.expect(:bar, true)
+    assert @mock.bar
+  end
+
+  def test_not_verify_if_new_expected_method_is_not_called
+    @mock.foo
+    @mock.meaning_of_life
+    @mock.expect(:bar, true)
+
+    util_verify_bad "expected bar() => true"
+  end
+
+  def test_blow_up_on_wrong_number_of_arguments
+    @mock.foo
+    @mock.meaning_of_life
+    @mock.expect(:sum, 3, [1, 2])
+
+    e = assert_raises ArgumentError do
+      @mock.sum
+    end
+
+    assert_equal "mocked method :sum expects 2 arguments, got 0", e.message
+  end
+
+  def test_return_mock_does_not_raise
+    retval = Minitest::Mock.new
+    mock = Minitest::Mock.new
+    mock.expect(:foo, retval)
+    mock.foo
+
+    assert mock.verify
+  end
+
+  def test_mock_args_does_not_raise
+    skip "non-opaque use of ==" if maglev?
+
+    arg = Minitest::Mock.new
+    mock = Minitest::Mock.new
+    mock.expect(:foo, nil, [arg])
+    mock.foo(arg)
+
+    assert mock.verify
+  end
+
+  def test_set_expectation_on_special_methods
+    mock = Minitest::Mock.new
+
+    mock.expect :object_id, "received object_id"
+    assert_equal "received object_id", mock.object_id
+
+    mock.expect :respond_to_missing?, "received respond_to_missing?"
+    assert_equal "received respond_to_missing?", mock.respond_to_missing?
+
+    mock.expect :===, "received ==="
+    assert_equal "received ===", mock.===
+
+    mock.expect :inspect, "received inspect"
+    assert_equal "received inspect", mock.inspect
+
+    mock.expect :to_s, "received to_s"
+    assert_equal "received to_s", mock.to_s
+
+    mock.expect :public_send, "received public_send"
+    assert_equal "received public_send", mock.public_send
+
+    mock.expect :send, "received send"
+    assert_equal "received send", mock.send
+
+    assert mock.verify
+  end
+
+  def test_expectations_can_be_satisfied_via_send
+    @mock.send :foo
+    @mock.send :meaning_of_life
+
+    assert @mock.verify
+  end
+
+  def test_expectations_can_be_satisfied_via_public_send
+    skip "Doesn't run on 1.8" if RUBY_VERSION < "1.9"
+
+    @mock.public_send :foo
+    @mock.public_send :meaning_of_life
+
+    assert @mock.verify
+  end
+
+  def test_blow_up_on_wrong_arguments
+    @mock.foo
+    @mock.meaning_of_life
+    @mock.expect(:sum, 3, [1, 2])
+
+    e = assert_raises MockExpectationError do
+      @mock.sum(2, 4)
+    end
+
+    exp = "mocked method :sum called with unexpected arguments [2, 4]"
+    assert_equal exp, e.message
+  end
+
+  def test_expect_with_non_array_args
+    e = assert_raises ArgumentError do
+      @mock.expect :blah, 3, false
+    end
+
+    assert_equal "args must be an array", e.message
+  end
+
+  def test_respond_appropriately
+    assert @mock.respond_to?(:foo)
+    assert @mock.respond_to?(:foo, true)
+    assert @mock.respond_to?("foo")
+    assert !@mock.respond_to?(:bar)
+  end
+
+  def test_no_method_error_on_unexpected_methods
+    e = assert_raises NoMethodError do
+      @mock.bar
+    end
+
+    expected = "unmocked method :bar, expected one of [:foo, :meaning_of_life]"
+
+    assert_equal expected, e.message
+  end
+
+  def test_assign_per_mock_return_values
+    a = Minitest::Mock.new
+    b = Minitest::Mock.new
+
+    a.expect(:foo, :a)
+    b.expect(:foo, :b)
+
+    assert_equal :a, a.foo
+    assert_equal :b, b.foo
+  end
+
+  def test_do_not_create_stub_method_on_new_mocks
+    a = Minitest::Mock.new
+    a.expect(:foo, :a)
+
+    assert !Minitest::Mock.new.respond_to?(:foo)
+  end
+
+  def test_mock_is_a_blank_slate
+    @mock.expect :kind_of?, true, [Fixnum]
+    @mock.expect :==, true, [1]
+
+    assert @mock.kind_of?(Fixnum), "didn't mock :kind_of\?"
+    assert @mock == 1, "didn't mock :=="
+  end
+
+  def test_verify_allows_called_args_to_be_loosely_specified
+    mock = Minitest::Mock.new
+    mock.expect :loose_expectation, true, [Integer]
+    mock.loose_expectation 1
+
+    assert mock.verify
+  end
+
+  def test_verify_raises_with_strict_args
+    mock = Minitest::Mock.new
+    mock.expect :strict_expectation, true, [2]
+
+    e = assert_raises MockExpectationError do
+      mock.strict_expectation 1
+    end
+
+    exp = "mocked method :strict_expectation called with unexpected arguments [1]"
+    assert_equal exp, e.message
+  end
+
+  def test_method_missing_empty
+    mock = Minitest::Mock.new
+
+    mock.expect :a, nil
+
+    mock.a
+
+    e = assert_raises MockExpectationError do
+      mock.a
+    end
+
+    assert_equal "No more expects available for :a: []", e.message
+  end
+
+  def test_same_method_expects_are_verified_when_all_called
+    mock = Minitest::Mock.new
+    mock.expect :foo, nil, [:bar]
+    mock.expect :foo, nil, [:baz]
+
+    mock.foo :bar
+    mock.foo :baz
+
+    assert mock.verify
+  end
+
+  def test_same_method_expects_blow_up_when_not_all_called
+    mock = Minitest::Mock.new
+    mock.expect :foo, nil, [:bar]
+    mock.expect :foo, nil, [:baz]
+
+    mock.foo :bar
+
+    e = assert_raises(MockExpectationError) { mock.verify }
+
+    exp = "expected foo(:baz) => nil, got [foo(:bar) => nil]"
+
+    assert_equal exp, e.message
+  end
+
+  def test_verify_passes_when_mock_block_returns_true
+    mock = Minitest::Mock.new
+    mock.expect :foo, nil do
+      true
+    end
+
+    mock.foo
+
+    assert mock.verify
+  end
+
+  def test_mock_block_is_passed_function_params
+    arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
+    mock = Minitest::Mock.new
+    mock.expect :foo, nil do |a1, a2, a3|
+      a1 == arg1 && a2 == arg2 && a3 == arg3
+    end
+
+    mock.foo arg1, arg2, arg3
+
+    assert mock.verify
+  end
+
+  def test_mock_block_is_passed_function_block
+    mock = Minitest::Mock.new
+    block = proc { "bar" }
+    mock.expect :foo, nil do |arg, &blk|
+      arg == "foo" &&
+      blk == block
+    end
+    mock.foo "foo", &block
+    assert mock.verify
+  end
+
+  def test_verify_fails_when_mock_block_returns_false
+    mock = Minitest::Mock.new
+    mock.expect :foo, nil do
+      false
+    end
+
+    e = assert_raises(MockExpectationError) { mock.foo }
+    exp = "mocked method :foo failed block w/ []"
+
+    assert_equal exp, e.message
+  end
+
+  def test_mock_block_throws_if_args_passed
+    mock = Minitest::Mock.new
+
+    e = assert_raises(ArgumentError) do
+      mock.expect :foo, nil, [:a, :b, :c] do
+        true
+      end
+    end
+
+    exp = "args ignored when block given"
+
+    assert_equal exp, e.message
+  end
+
+  def test_mock_returns_retval_when_called_with_block
+    mock = Minitest::Mock.new
+    mock.expect(:foo, 32) do
+      true
+    end
+
+    rs = mock.foo
+
+    assert_equal rs, 32
+  end
+
+  def util_verify_bad exp
+    e = assert_raises MockExpectationError do
+      @mock.verify
+    end
+
+    assert_equal exp, e.message
+  end
+
+  def test_mock_called_via_send
+    mock = Minitest::Mock.new
+    mock.expect(:foo, true)
+
+    mock.send :foo
+    mock.verify
+  end
+
+  def test_mock_called_via___send__
+    mock = Minitest::Mock.new
+    mock.expect(:foo, true)
+
+    mock.__send__ :foo
+    mock.verify
+  end
+
+  def test_mock_called_via_send_with_args
+    mock = Minitest::Mock.new
+    mock.expect(:foo, true, [1, 2, 3])
+
+    mock.send(:foo, 1, 2, 3)
+    mock.verify
+  end
+
+end
+
+require "minitest/metametameta"
+
+class TestMinitestStub < Minitest::Test
+  parallelize_me!
+
+  def setup
+    super
+    Minitest::Test.reset
+
+    @tc = Minitest::Test.new "fake tc"
+    @assertion_count = 1
+  end
+
+  def teardown
+    super
+    assert_equal @assertion_count, @tc.assertions
+  end
+
+  class Time
+    def self.now
+      24
+    end
+  end
+
+  def assert_stub val_or_callable
+    @assertion_count += 1
+
+    t = Time.now.to_i
+
+    Time.stub :now, val_or_callable do
+      @tc.assert_equal 42, Time.now
+    end
+
+    @tc.assert_operator Time.now.to_i, :>=, t
+  end
+
+  def test_stub_private_module_method
+    @assertion_count += 1
+
+    t0 = Time.now
+
+    self.stub :sleep, nil do
+      @tc.assert_nil sleep(10)
+    end
+
+    @tc.assert_operator Time.now - t0, :<=, 1
+  end
+
+  def test_stub_private_module_method_indirect
+    @assertion_count += 1
+
+    fail_clapper = Class.new do
+      def fail_clap
+        raise
+        :clap
+      end
+    end.new
+
+    fail_clapper.stub :raise, nil do |safe_clapper|
+      @tc.assert_equal :clap, safe_clapper.fail_clap # either form works
+      @tc.assert_equal :clap, fail_clapper.fail_clap # yay closures
+    end
+  end
+
+  def test_stub_public_module_method
+    Math.stub :log10, :stubbed do
+      @tc.assert_equal :stubbed, Math.log10(1000)
+    end
+  end
+
+  def test_stub_value
+    assert_stub 42
+  end
+
+  def test_stub_block
+    assert_stub lambda { 42 }
+  end
+
+  def test_stub_block_args
+    @assertion_count += 1
+
+    t = Time.now.to_i
+
+    Time.stub :now,  lambda { |n| n * 2 } do
+      @tc.assert_equal 42, Time.now(21)
+    end
+
+    @tc.assert_operator Time.now.to_i, :>=, t
+  end
+
+  def test_stub_callable
+    obj = Object.new
+
+    def obj.call
+      42
+    end
+
+    assert_stub obj
+  end
+
+  def test_stub_yield_self
+    obj = "foo"
+
+    val = obj.stub :to_s, "bar" do |s|
+      s.to_s
+    end
+
+    @tc.assert_equal "bar", val
+  end
+
+  def test_dynamic_method
+    @assertion_count = 2
+
+    dynamic = Class.new do
+      def self.respond_to?(meth)
+        meth == :found
+      end
+
+      def self.method_missing(meth, *args, &block)
+        if meth == :found
+          false
+        else
+          super
+        end
+      end
+    end
+
+    val = dynamic.stub(:found, true) do |s|
+      s.found
+    end
+
+    @tc.assert_equal true, val
+    @tc.assert_equal false, dynamic.found
+  end
+
+  def test_mock_with_yield
+    mock = Minitest::Mock.new
+    mock.expect(:write, true) do
+      true
+    end
+    rs = nil
+
+    File.stub(:open, true, mock) do
+      File.open("foo.txt", "r") do |f|
+        rs = f.write
+      end
+    end
+    @tc.assert_equal true, rs
+  end
+
+end
diff --git a/app/server/vendor/minitest-5.8.1/test/minitest/test_minitest_reporter.rb b/app/server/vendor/minitest-5.8.1/test/minitest/test_minitest_reporter.rb
new file mode 100644
index 0000000..18b8a75
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/test/minitest/test_minitest_reporter.rb
@@ -0,0 +1,281 @@
+require "minitest/autorun"
+require "minitest/metametameta"
+
+class TestMinitestReporter < MetaMetaMetaTestCase
+
+  attr_accessor :r, :io
+
+  def new_composite_reporter
+    reporter = Minitest::CompositeReporter.new
+    reporter << Minitest::SummaryReporter.new(self.io)
+    reporter << Minitest::ProgressReporter.new(self.io)
+
+    def reporter.first
+      reporters.first
+    end
+
+    def reporter.results
+      first.results
+    end
+
+    def reporter.count
+      first.count
+    end
+
+    def reporter.assertions
+      first.assertions
+    end
+
+    reporter
+  end
+
+  def setup
+    self.io = StringIO.new("")
+    self.r  = new_composite_reporter
+  end
+
+  def error_test
+    unless defined? @et then
+      @et = Minitest::Test.new(:woot)
+      @et.failures << Minitest::UnexpectedError.new(begin
+                                                      raise "no"
+                                                    rescue => e
+                                                      e
+                                                    end)
+    end
+    @et
+  end
+
+  def fail_test
+    unless defined? @ft then
+      @ft = Minitest::Test.new(:woot)
+      @ft.failures <<   begin
+                          raise Minitest::Assertion, "boo"
+                        rescue Minitest::Assertion => e
+                          e
+                        end
+    end
+    @ft
+  end
+
+  def passing_test
+    @pt ||= Minitest::Test.new(:woot)
+  end
+
+  def skip_test
+    unless defined? @st then
+      @st = Minitest::Test.new(:woot)
+      @st.failures << begin
+                        raise Minitest::Skip
+                      rescue Minitest::Assertion => e
+                        e
+                      end
+    end
+    @st
+  end
+
+  def test_passed_eh_empty
+    assert r.passed?
+  end
+
+  def test_passed_eh_failure
+    r.results << fail_test
+
+    refute r.passed?
+  end
+
+  SKIP_MSG = "\n\nYou have skipped tests. Run with --verbose for details."
+
+  def test_passed_eh_error
+    r.start
+
+    r.results << error_test
+
+    refute r.passed?
+
+    r.report
+
+    refute_match SKIP_MSG, io.string
+  end
+
+  def test_passed_eh_skipped
+    r.start
+    r.results << skip_test
+    assert r.passed?
+
+    restore_env do
+      r.report
+    end
+
+    assert_match SKIP_MSG, io.string
+  end
+
+  def test_passed_eh_skipped_verbose
+    r.first.options[:verbose] = true
+
+    r.start
+    r.results << skip_test
+    assert r.passed?
+    r.report
+
+    refute_match SKIP_MSG, io.string
+  end
+
+  def test_start
+    r.start
+
+    exp = "Run options: \n\n# Running:\n\n"
+
+    assert_equal exp, io.string
+  end
+
+  def test_record_pass
+    r.record passing_test
+
+    assert_equal ".", io.string
+    assert_empty r.results
+    assert_equal 1, r.count
+    assert_equal 0, r.assertions
+  end
+
+  def test_record_fail
+    r.record fail_test
+
+    assert_equal "F", io.string
+    assert_equal [fail_test], r.results
+    assert_equal 1, r.count
+    assert_equal 0, r.assertions
+  end
+
+  def test_record_error
+    r.record error_test
+
+    assert_equal "E", io.string
+    assert_equal [error_test], r.results
+    assert_equal 1, r.count
+    assert_equal 0, r.assertions
+  end
+
+  def test_record_skip
+    r.record skip_test
+
+    assert_equal "S", io.string
+    assert_equal [skip_test], r.results
+    assert_equal 1, r.count
+    assert_equal 0, r.assertions
+  end
+
+  def test_report_empty
+    r.start
+    r.report
+
+    exp = clean <<-EOM
+      Run options:
+
+      # Running:
+
+
+
+      Finished in 0.00
+
+      0 runs, 0 assertions, 0 failures, 0 errors, 0 skips
+    EOM
+
+    assert_equal exp, normalize_output(io.string)
+  end
+
+  def test_report_passing
+    r.start
+    r.record passing_test
+    r.report
+
+    exp = clean <<-EOM
+      Run options:
+
+      # Running:
+
+      .
+
+      Finished in 0.00
+
+      1 runs, 0 assertions, 0 failures, 0 errors, 0 skips
+    EOM
+
+    assert_equal exp, normalize_output(io.string)
+  end
+
+  def test_report_failure
+    r.start
+    r.record fail_test
+    r.report
+
+    exp = clean <<-EOM
+      Run options:
+
+      # Running:
+
+      F
+
+      Finished in 0.00
+
+        1) Failure:
+      Minitest::Test#woot [FILE:LINE]:
+      boo
+
+      1 runs, 0 assertions, 1 failures, 0 errors, 0 skips
+    EOM
+
+    assert_equal exp, normalize_output(io.string)
+  end
+
+  def test_report_error
+    r.start
+    r.record error_test
+    r.report
+
+    exp = clean <<-EOM
+      Run options:
+
+      # Running:
+
+      E
+
+      Finished in 0.00
+
+        1) Error:
+      Minitest::Test#woot:
+      RuntimeError: no
+          FILE:LINE:in `error_test'
+          FILE:LINE:in `test_report_error'
+
+      1 runs, 0 assertions, 0 failures, 1 errors, 0 skips
+    EOM
+
+    assert_equal exp, normalize_output(io.string)
+  end
+
+  def test_report_skipped
+    r.start
+    r.record skip_test
+
+    restore_env do
+      r.report
+    end
+
+    exp = clean <<-EOM
+      Run options:
+
+      # Running:
+
+      S
+
+      Finished in 0.00
+
+      1 runs, 0 assertions, 0 failures, 0 errors, 1 skips
+
+      You have skipped tests. Run with --verbose for details.
+    EOM
+
+    assert_equal exp, normalize_output(io.string)
+  end
+end
diff --git a/app/server/vendor/minitest-5.8.1/test/minitest/test_minitest_spec.rb b/app/server/vendor/minitest-5.8.1/test/minitest/test_minitest_spec.rb
new file mode 100644
index 0000000..a77adc5
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/test/minitest/test_minitest_spec.rb
@@ -0,0 +1,967 @@
+# encoding: utf-8
+require "minitest/autorun"
+require "stringio"
+
+class MiniSpecA < Minitest::Spec; end
+class MiniSpecB < Minitest::Test; extend Minitest::Spec::DSL; end
+class MiniSpecC < MiniSpecB; end
+class NamedExampleA < MiniSpecA; end
+class NamedExampleB < MiniSpecB; end
+class NamedExampleC < MiniSpecC; end
+class ExampleA; end
+class ExampleB < ExampleA; end
+
+describe Minitest::Spec do
+  # do not parallelize this suite... it just can"t handle it.
+
+  def assert_triggered expected = "blah", klass = Minitest::Assertion
+    @assertion_count += 1
+
+    e = assert_raises(klass) do
+      yield
+    end
+
+    msg = e.message.sub(/(---Backtrace---).*/m, '\1')
+    msg.gsub!(/\(oid=[-0-9]+\)/, "(oid=N)")
+    msg.gsub!(/@.+>/, "@PATH>")
+    msg.gsub!(/(\d\.\d{6})\d+/, '\1xxx') # normalize: ruby version, impl, platform
+    msg.gsub!(/:0x[a-fA-F0-9]{4,}/m, ":0xXXXXXX")
+
+    if expected
+      @assertion_count += 1
+      case expected
+      when String then
+        assert_equal expected, msg
+      when Regexp then
+        @assertion_count += 1
+        assert_match expected, msg
+      else
+        flunk "Unknown: #{expected.inspect}"
+      end
+    end
+  end
+
+  before do
+    @assertion_count = 4
+  end
+
+  after do
+    _(self.assertions).must_equal @assertion_count if passed? and not skipped?
+  end
+
+  it "needs to be able to catch a Minitest::Assertion exception" do
+    @assertion_count = 1
+
+    assert_triggered "Expected 1 to not be equal to 1." do
+      1.wont_equal 1
+    end
+  end
+
+  it "needs to be sensible about must_include order" do
+    @assertion_count += 3 # must_include is 2 assertions
+
+    [1, 2, 3].must_include(2).must_equal true
+
+    assert_triggered "Expected [1, 2, 3] to include 5." do
+      [1, 2, 3].must_include 5
+    end
+
+    assert_triggered "msg.\nExpected [1, 2, 3] to include 5." do
+      [1, 2, 3].must_include 5, "msg"
+    end
+  end
+
+  it "needs to be sensible about wont_include order" do
+    @assertion_count += 3 # wont_include is 2 assertions
+
+    [1, 2, 3].wont_include(5).must_equal false
+
+    assert_triggered "Expected [1, 2, 3] to not include 2." do
+      [1, 2, 3].wont_include 2
+    end
+
+    assert_triggered "msg.\nExpected [1, 2, 3] to not include 2." do
+      [1, 2, 3].wont_include 2, "msg"
+    end
+  end
+
+  it "needs to catch an expected exception" do
+    @assertion_count = 2
+
+    proc { raise "blah" }.must_raise RuntimeError
+    proc { raise Minitest::Assertion }.must_raise Minitest::Assertion
+  end
+
+  it "needs to catch an unexpected exception" do
+    @assertion_count -= 2 # no positive
+
+    msg = <<-EOM.gsub(/^ {6}/, "").chomp
+      [RuntimeError] exception expected, not
+      Class: <Minitest::Assertion>
+      Message: <"Minitest::Assertion">
+      ---Backtrace---
+    EOM
+
+    assert_triggered msg do
+      proc { raise Minitest::Assertion }.must_raise RuntimeError
+    end
+
+    assert_triggered "msg.\n#{msg}" do
+      proc { raise Minitest::Assertion }.must_raise RuntimeError, "msg"
+    end
+  end
+
+  it "needs to ensure silence" do
+    @assertion_count -= 1 # no msg
+    @assertion_count += 2 # assert_output is 2 assertions
+
+    proc {  }.must_be_silent.must_equal true
+
+    assert_triggered "In stdout.\nExpected: \"\"\n  Actual: \"xxx\"" do
+      proc { print "xxx" }.must_be_silent
+    end
+  end
+
+  it "needs to have all methods named well" do
+    @assertion_count = 2
+
+    methods = Object.public_instance_methods.find_all { |n| n =~ /^must|^wont/ }
+    methods.map!(&:to_s) if Symbol === methods.first
+
+    musts, wonts = methods.sort.partition { |m| m =~ /^must/ }
+
+    expected_musts = %w[must_be
+                        must_be_close_to
+                        must_be_empty
+                        must_be_instance_of
+                        must_be_kind_of
+                        must_be_nil
+                        must_be_same_as
+                        must_be_silent
+                        must_be_within_delta
+                        must_be_within_epsilon
+                        must_equal
+                        must_include
+                        must_match
+                        must_output
+                        must_raise
+                        must_respond_to
+                        must_throw]
+
+    bad = %w[not raise throw send output be_silent]
+
+    expected_wonts = expected_musts.map { |m| m.sub(/^must/, "wont") }
+    expected_wonts.reject! { |m| m =~ /wont_#{Regexp.union(*bad)}/ }
+
+    musts.must_equal expected_musts
+    wonts.must_equal expected_wonts
+  end
+
+  it "needs to raise if an expected exception is not raised" do
+    @assertion_count -= 2 # no positive test
+
+    assert_triggered "RuntimeError expected but nothing was raised." do
+      proc { 42 }.must_raise RuntimeError
+    end
+
+    assert_triggered "msg.\nRuntimeError expected but nothing was raised." do
+      proc { 42 }.must_raise RuntimeError, "msg"
+    end
+  end
+
+  it "needs to verify binary messages" do
+    42.wont_be(:<, 24).must_equal false
+
+    assert_triggered "Expected 24 to not be < 42." do
+      24.wont_be :<, 42
+    end
+
+    assert_triggered "msg.\nExpected 24 to not be < 42." do
+      24.wont_be :<, 42, "msg"
+    end
+  end
+
+  it "needs to verify emptyness" do
+    @assertion_count += 3 # empty is 2 assertions
+
+    [].must_be_empty.must_equal true
+
+    assert_triggered "Expected [42] to be empty." do
+      [42].must_be_empty
+    end
+
+    assert_triggered "msg.\nExpected [42] to be empty." do
+      [42].must_be_empty "msg"
+    end
+  end
+
+  it "needs to verify equality" do
+    @assertion_count += 1
+
+    (6 * 7).must_equal(42).must_equal true
+
+    assert_triggered "Expected: 42\n  Actual: 54" do
+      (6 * 9).must_equal 42
+    end
+
+    assert_triggered "msg.\nExpected: 42\n  Actual: 54" do
+      (6 * 9).must_equal 42, "msg"
+    end
+
+    assert_triggered(/^-42\n\+#<Proc:0xXXXXXX at PATH>\n/) do
+      proc { 42 }.must_equal 42 # proc isn't called, so expectation fails
+    end
+  end
+
+  it "needs to verify floats outside a delta" do
+    @assertion_count += 1 # extra test
+
+    24.wont_be_close_to(42).must_equal false
+
+    assert_triggered "Expected |42 - 42.0| (0.0) to not be <= 0.001." do
+      (6 * 7.0).wont_be_close_to 42
+    end
+
+    x = maglev? ? "1.0000000000000001e-05" : "1.0e-05"
+    assert_triggered "Expected |42 - 42.0| (0.0) to not be <= #{x}." do
+      (6 * 7.0).wont_be_close_to 42, 0.00001
+    end
+
+    assert_triggered "msg.\nExpected |42 - 42.0| (0.0) to not be <= #{x}." do
+      (6 * 7.0).wont_be_close_to 42, 0.00001, "msg"
+    end
+  end
+
+  it "needs to verify floats outside an epsilon" do
+    @assertion_count += 1 # extra test
+
+    24.wont_be_within_epsilon(42).must_equal false
+
+    x = maglev? ? "0.042000000000000003" : "0.042"
+    assert_triggered "Expected |42 - 42.0| (0.0) to not be <= #{x}." do
+      (6 * 7.0).wont_be_within_epsilon 42
+    end
+
+    x = maglev? ? "0.00042000000000000002" : "0.00042"
+    assert_triggered "Expected |42 - 42.0| (0.0) to not be <= #{x}." do
+      (6 * 7.0).wont_be_within_epsilon 42, 0.00001
+    end
+
+    assert_triggered "msg.\nExpected |42 - 42.0| (0.0) to not be <= #{x}." do
+      (6 * 7.0).wont_be_within_epsilon 42, 0.00001, "msg"
+    end
+  end
+
+  it "needs to verify floats within a delta" do
+    @assertion_count += 1 # extra test
+
+    (6.0 * 7).must_be_close_to(42.0).must_equal true
+
+    assert_triggered "Expected |0.0 - 0.01| (0.01) to be <= 0.001." do
+      (1.0 / 100).must_be_close_to 0.0
+    end
+
+    x = maglev? ? "9.9999999999999995e-07" : "1.0e-06"
+    assert_triggered "Expected |0.0 - 0.001| (0.001) to be <= #{x}." do
+      (1.0 / 1000).must_be_close_to 0.0, 0.000001
+    end
+
+    assert_triggered "msg.\nExpected |0.0 - 0.001| (0.001) to be <= #{x}." do
+      (1.0 / 1000).must_be_close_to 0.0, 0.000001, "msg"
+    end
+  end
+
+  it "needs to verify floats within an epsilon" do
+    @assertion_count += 1 # extra test
+
+    (6.0 * 7).must_be_within_epsilon(42.0).must_equal true
+
+    assert_triggered "Expected |0.0 - 0.01| (0.01) to be <= 0.0." do
+      (1.0 / 100).must_be_within_epsilon 0.0
+    end
+
+    assert_triggered "Expected |0.0 - 0.001| (0.001) to be <= 0.0." do
+      (1.0 / 1000).must_be_within_epsilon 0.0, 0.000001
+    end
+
+    assert_triggered "msg.\nExpected |0.0 - 0.001| (0.001) to be <= 0.0." do
+      (1.0 / 1000).must_be_within_epsilon 0.0, 0.000001, "msg"
+    end
+  end
+
+  it "needs to verify identity" do
+    1.must_be_same_as(1).must_equal true
+
+    assert_triggered "Expected 1 (oid=N) to be the same as 2 (oid=N)." do
+      1.must_be_same_as 2
+    end
+
+    assert_triggered "msg.\nExpected 1 (oid=N) to be the same as 2 (oid=N)." do
+      1.must_be_same_as 2, "msg"
+    end
+  end
+
+  it "needs to verify inequality" do
+    @assertion_count += 2
+    42.wont_equal(6 * 9).must_equal false
+    proc{}.wont_equal(42).must_equal false
+
+    assert_triggered "Expected 1 to not be equal to 1." do
+      1.wont_equal 1
+    end
+
+    assert_triggered "msg.\nExpected 1 to not be equal to 1." do
+      1.wont_equal 1, "msg"
+    end
+  end
+
+  it "needs to verify instances of a class" do
+    42.wont_be_instance_of(String).must_equal false
+
+    assert_triggered "Expected 42 to not be an instance of Fixnum." do
+      42.wont_be_instance_of Fixnum
+    end
+
+    assert_triggered "msg.\nExpected 42 to not be an instance of Fixnum." do
+      42.wont_be_instance_of Fixnum, "msg"
+    end
+  end
+
+  it "needs to verify kinds of a class" do
+    @assertion_count += 2
+
+    42.wont_be_kind_of(String).must_equal false
+    proc{}.wont_be_kind_of(String).must_equal false
+
+    assert_triggered "Expected 42 to not be a kind of Integer." do
+      42.wont_be_kind_of Integer
+    end
+
+    assert_triggered "msg.\nExpected 42 to not be a kind of Integer." do
+      42.wont_be_kind_of Integer, "msg"
+    end
+  end
+
+  it "needs to verify kinds of objects" do
+    @assertion_count += 3 # extra test
+
+    (6 * 7).must_be_kind_of(Fixnum).must_equal true
+    (6 * 7).must_be_kind_of(Numeric).must_equal true
+
+    assert_triggered "Expected 42 to be a kind of String, not Fixnum." do
+      (6 * 7).must_be_kind_of String
+    end
+
+    assert_triggered "msg.\nExpected 42 to be a kind of String, not Fixnum." do
+      (6 * 7).must_be_kind_of String, "msg"
+    end
+
+    exp = "Expected #<Proc:0xXXXXXX at PATH> to be a kind of String, not Proc."
+    assert_triggered exp do
+      proc{}.must_be_kind_of String
+    end
+  end
+
+  it "needs to verify mismatch" do
+    @assertion_count += 3 # match is 2
+
+    "blah".wont_match(/\d+/).must_equal false
+
+    assert_triggered "Expected /\\w+/ to not match \"blah\"." do
+      "blah".wont_match(/\w+/)
+    end
+
+    assert_triggered "msg.\nExpected /\\w+/ to not match \"blah\"." do
+      "blah".wont_match(/\w+/, "msg")
+    end
+  end
+
+  it "needs to verify nil" do
+    nil.must_be_nil.must_equal true
+
+    assert_triggered "Expected 42 to be nil." do
+      42.must_be_nil
+    end
+
+    assert_triggered "msg.\nExpected 42 to be nil." do
+      42.must_be_nil "msg"
+    end
+  end
+
+  it "needs to verify non-emptyness" do
+    @assertion_count += 3 # empty is 2 assertions
+
+    ["some item"].wont_be_empty.must_equal false
+
+    assert_triggered "Expected [] to not be empty." do
+      [].wont_be_empty
+    end
+
+    assert_triggered "msg.\nExpected [] to not be empty." do
+      [].wont_be_empty "msg"
+    end
+  end
+
+  it "needs to verify non-identity" do
+    1.wont_be_same_as(2).must_equal false
+
+    assert_triggered "Expected 1 (oid=N) to not be the same as 1 (oid=N)." do
+      1.wont_be_same_as 1
+    end
+
+    assert_triggered "msg.\nExpected 1 (oid=N) to not be the same as 1 (oid=N)." do
+      1.wont_be_same_as 1, "msg"
+    end
+  end
+
+  it "needs to verify non-nil" do
+    42.wont_be_nil.must_equal false
+
+    assert_triggered "Expected nil to not be nil." do
+      nil.wont_be_nil
+    end
+
+    assert_triggered "msg.\nExpected nil to not be nil." do
+      nil.wont_be_nil "msg"
+    end
+  end
+
+  it "needs to verify objects not responding to a message" do
+    "".wont_respond_to(:woot!).must_equal false
+
+    assert_triggered "Expected \"\" to not respond to to_s." do
+      "".wont_respond_to :to_s
+    end
+
+    assert_triggered "msg.\nExpected \"\" to not respond to to_s." do
+      "".wont_respond_to :to_s, "msg"
+    end
+  end
+
+  it "needs to verify output in stderr" do
+    @assertion_count -= 1 # no msg
+
+    proc { $stderr.print "blah" }.must_output(nil, "blah").must_equal true
+
+    assert_triggered "In stderr.\nExpected: \"blah\"\n  Actual: \"xxx\"" do
+      proc { $stderr.print "xxx" }.must_output(nil, "blah")
+    end
+  end
+
+  it "needs to verify output in stdout" do
+    @assertion_count -= 1 # no msg
+
+    proc { print "blah" }.must_output("blah").must_equal true
+
+    assert_triggered "In stdout.\nExpected: \"blah\"\n  Actual: \"xxx\"" do
+      proc { print "xxx" }.must_output("blah")
+    end
+  end
+
+  it "needs to verify regexp matches" do
+    @assertion_count += 3 # must_match is 2 assertions
+
+    "blah".must_match(/\w+/).must_equal true
+
+    assert_triggered "Expected /\\d+/ to match \"blah\"." do
+      "blah".must_match(/\d+/)
+    end
+
+    assert_triggered "msg.\nExpected /\\d+/ to match \"blah\"." do
+      "blah".must_match(/\d+/, "msg")
+    end
+  end
+
+  describe "expect" do
+    before do
+      @assertion_count -= 3
+    end
+
+    it "can use expect" do
+      _(1 + 1).must_equal 2
+    end
+
+    it "can use expect with a lambda" do
+      _ { raise "blah" }.must_raise RuntimeError
+    end
+
+    it "can use expect in a thread" do
+      Thread.new { _(1 + 1).must_equal 2 }.join
+    end
+
+    it "can NOT use must_equal in a thread. It must use expect in a thread" do
+      assert_raises NoMethodError do
+        Thread.new { (1 + 1).must_equal 2 }.join
+      end
+    end
+  end
+
+  it "needs to verify throw" do
+    @assertion_count += 2 # 2 extra tests
+
+    proc { throw :blah }.must_throw(:blah).must_equal true
+
+    assert_triggered "Expected :blah to have been thrown." do
+      proc { }.must_throw :blah
+    end
+
+    assert_triggered "Expected :blah to have been thrown, not :xxx." do
+      proc { throw :xxx }.must_throw :blah
+    end
+
+    assert_triggered "msg.\nExpected :blah to have been thrown." do
+      proc { }.must_throw :blah, "msg"
+    end
+
+    assert_triggered "msg.\nExpected :blah to have been thrown, not :xxx." do
+      proc { throw :xxx }.must_throw :blah, "msg"
+    end
+  end
+
+  it "needs to verify types of objects" do
+    (6 * 7).must_be_instance_of(Fixnum).must_equal true
+
+    exp = "Expected 42 to be an instance of String, not Fixnum."
+
+    assert_triggered exp do
+      (6 * 7).must_be_instance_of String
+    end
+
+    assert_triggered "msg.\n#{exp}" do
+      (6 * 7).must_be_instance_of String, "msg"
+    end
+  end
+
+  it "needs to verify using any (negative) predicate" do
+    @assertion_count -= 1 # doesn"t take a message
+
+    "blah".wont_be(:empty?).must_equal false
+
+    assert_triggered "Expected \"\" to not be empty?." do
+      "".wont_be :empty?
+    end
+  end
+
+  it "needs to verify using any binary operator" do
+    @assertion_count -= 1 # no msg
+
+    41.must_be(:<, 42).must_equal true
+
+    assert_triggered "Expected 42 to be < 41." do
+      42.must_be(:<, 41)
+    end
+  end
+
+  it "needs to verify using any predicate" do
+    @assertion_count -= 1 # no msg
+
+    "".must_be(:empty?).must_equal true
+
+    assert_triggered "Expected \"blah\" to be empty?." do
+      "blah".must_be :empty?
+    end
+  end
+
+  it "needs to verify using respond_to" do
+    42.must_respond_to(:+).must_equal true
+
+    assert_triggered "Expected 42 (Fixnum) to respond to #clear." do
+      42.must_respond_to :clear
+    end
+
+    assert_triggered "msg.\nExpected 42 (Fixnum) to respond to #clear." do
+      42.must_respond_to :clear, "msg"
+    end
+  end
+end
+
+describe Minitest::Spec, :let do
+  i_suck_and_my_tests_are_order_dependent!
+
+  def _count
+    $let_count ||= 0
+  end
+
+  let :count do
+    $let_count += 1
+    $let_count
+  end
+
+  it "is evaluated once per example" do
+    _count.must_equal 0
+
+    count.must_equal 1
+    count.must_equal 1
+
+    _count.must_equal 1
+  end
+
+  it "is REALLY evaluated once per example" do
+    _count.must_equal 1
+
+    count.must_equal 2
+    count.must_equal 2
+
+    _count.must_equal 2
+  end
+
+  it 'raises an error if the name begins with "test"' do
+    proc { self.class.let(:test_value) { true } }.must_raise ArgumentError
+  end
+
+  it "raises an error if the name shadows a normal instance method" do
+    proc { self.class.let(:message) { true } }.must_raise ArgumentError
+  end
+
+  it "doesn't raise an error if it is just another let" do
+    proc do
+      describe :outer do
+        let(:bar)
+        describe :inner do
+          let(:bar)
+        end
+      end
+      :good
+    end.call.must_equal :good
+  end
+
+  it "procs come after dont_flip" do
+    p = proc { }
+    assert_respond_to p, :call
+    p.must_respond_to :call
+  end
+end
+
+describe Minitest::Spec, :subject do
+  attr_reader :subject_evaluation_count
+
+  subject do
+    @subject_evaluation_count ||= 0
+    @subject_evaluation_count  += 1
+    @subject_evaluation_count
+  end
+
+  it "is evaluated once per example" do
+    subject.must_equal 1
+    subject.must_equal 1
+    subject_evaluation_count.must_equal 1
+  end
+end
+
+class TestMetaStatic < Minitest::Test
+  def test_children
+    Minitest::Spec.children.clear # prevents parallel run
+
+    y = z = nil
+    x = describe "top-level thingy" do
+      y = describe "first thingy" do end
+
+      it "top-level-it" do end
+
+      z = describe "second thingy" do end
+    end
+
+    assert_equal [x], Minitest::Spec.children
+    assert_equal [y, z], x.children
+    assert_equal [], y.children
+    assert_equal [], z.children
+  end
+
+  def test_it_wont_remove_existing_child_test_methods
+    Minitest::Spec.children.clear # prevents parallel run
+
+    inner = nil
+    outer = describe "outer" do
+      inner = describe "inner" do
+        it do
+          assert true
+        end
+      end
+      it do
+        assert true
+      end
+    end
+
+    assert_equal 1, outer.public_instance_methods.grep(/^test_/).count
+    assert_equal 1, inner.public_instance_methods.grep(/^test_/).count
+  end
+
+  def test_it_wont_add_test_methods_to_children
+    Minitest::Spec.children.clear # prevents parallel run
+
+    inner = nil
+    outer = describe "outer" do
+      inner = describe "inner" do end
+      it do
+        assert true
+      end
+    end
+
+    assert_equal 1, outer.public_instance_methods.grep(/^test_/).count
+    assert_equal 0, inner.public_instance_methods.grep(/^test_/).count
+  end
+end
+
+require "minitest/metametameta"
+
+class TestMeta < MetaMetaMetaTestCase
+  parallelize_me!
+
+  def util_structure
+    y = z = nil
+    before_list = []
+    after_list  = []
+    x = describe "top-level thingy" do
+      before { before_list << 1 }
+      after  { after_list  << 1 }
+
+      it "top-level-it" do end
+
+      y = describe "inner thingy" do
+        before { before_list << 2 }
+        after  { after_list  << 2 }
+        it "inner-it" do end
+
+        z = describe "very inner thingy" do
+          before { before_list << 3 }
+          after  { after_list  << 3 }
+          it "inner-it" do end
+
+          it      { } # ignore me
+          specify { } # anonymous it
+        end
+      end
+    end
+
+    return x, y, z, before_list, after_list
+  end
+
+  def test_register_spec_type
+    original_types = Minitest::Spec::TYPES.dup
+
+    assert_includes Minitest::Spec::TYPES, [//, Minitest::Spec]
+
+    Minitest::Spec.register_spec_type(/woot/, TestMeta)
+
+    p = lambda do |_| true end
+    Minitest::Spec.register_spec_type TestMeta, &p
+
+    keys = Minitest::Spec::TYPES.map(&:first)
+
+    assert_includes keys, /woot/
+    assert_includes keys, p
+  ensure
+    Minitest::Spec::TYPES.replace original_types
+  end
+
+  def test_spec_type
+    original_types = Minitest::Spec::TYPES.dup
+
+    Minitest::Spec.register_spec_type(/A$/, MiniSpecA)
+    Minitest::Spec.register_spec_type MiniSpecB do |desc|
+      desc.superclass == ExampleA
+    end
+    Minitest::Spec.register_spec_type MiniSpecC do |_desc, *addl|
+      addl.include? :woot
+    end
+
+    assert_equal MiniSpecA, Minitest::Spec.spec_type(ExampleA)
+    assert_equal MiniSpecB, Minitest::Spec.spec_type(ExampleB)
+    assert_equal MiniSpecC, Minitest::Spec.spec_type(ExampleB, :woot)
+  ensure
+    Minitest::Spec::TYPES.replace original_types
+  end
+
+  def test_bug_dsl_expectations
+    spec_class = Class.new MiniSpecB do
+      it "should work" do
+        0.must_equal 0
+      end
+    end
+
+    test_name = spec_class.instance_methods.sort.grep(/test/).first
+
+    spec = spec_class.new test_name
+
+    result = spec.run
+
+    assert spec.passed?
+    assert result.passed?
+    assert_equal 1, result.assertions
+  end
+
+  def test_name
+    spec_a = describe ExampleA do; end
+    spec_b = describe ExampleB, :random_method do; end
+    spec_c = describe ExampleB, :random_method, :addl_context do; end
+
+    assert_equal "ExampleA", spec_a.name
+    assert_equal "ExampleB::random_method", spec_b.name
+    assert_equal "ExampleB::random_method::addl_context", spec_c.name
+  end
+
+  def test_name2
+    assert_equal "NamedExampleA", NamedExampleA.name
+    assert_equal "NamedExampleB", NamedExampleB.name
+    assert_equal "NamedExampleC", NamedExampleC.name
+
+    spec_a = describe ExampleA do; end
+    spec_b = describe ExampleB, :random_method do; end
+
+    assert_equal "ExampleA", spec_a.name
+    assert_equal "ExampleB::random_method", spec_b.name
+  end
+
+  def test_structure
+    x, y, z, * = util_structure
+
+    assert_equal "top-level thingy",                                  x.to_s
+    assert_equal "top-level thingy::inner thingy",                    y.to_s
+    assert_equal "top-level thingy::inner thingy::very inner thingy", z.to_s
+
+    assert_equal "top-level thingy",  x.desc
+    assert_equal "inner thingy",      y.desc
+    assert_equal "very inner thingy", z.desc
+
+    top_methods = %w[setup teardown test_0001_top-level-it]
+    inner_methods1 = %w[setup teardown test_0001_inner-it]
+    inner_methods2 = inner_methods1 +
+      %w[test_0002_anonymous test_0003_anonymous]
+
+    assert_equal top_methods,    x.instance_methods(false).sort.map(&:to_s)
+    assert_equal inner_methods1, y.instance_methods(false).sort.map(&:to_s)
+    assert_equal inner_methods2, z.instance_methods(false).sort.map(&:to_s)
+  end
+
+  def test_structure_postfix_it
+    z = nil
+    y = describe "outer" do
+      # NOT here, below the inner-describe!
+      # it "inner-it" do end
+
+      z = describe "inner" do
+        it "inner-it" do end
+      end
+
+      # defined AFTER inner describe means we'll try to wipe out the inner-it
+      it "inner-it" do end
+    end
+
+    assert_equal %w[test_0001_inner-it], y.instance_methods(false).map(&:to_s)
+    assert_equal %w[test_0001_inner-it], z.instance_methods(false).map(&:to_s)
+  end
+
+  def test_setup_teardown_behavior
+    _, _, z, before_list, after_list = util_structure
+
+    @tu = z
+
+    run_tu_with_fresh_reporter
+
+    size = z.runnable_methods.size
+    assert_equal [1, 2, 3] * size, before_list
+    assert_equal [3, 2, 1] * size, after_list
+  end
+
+  def test_describe_first_structure
+    x1 = x2 = y = z = nil
+    x = describe "top-level thingy" do
+      y = describe "first thingy" do end
+
+      x1 = it "top level it" do end
+      x2 = it "не латинские &いった α, β, γ, δ, ε hello!!! world" do end
+
+      z = describe "second thingy" do end
+    end
+
+    test_methods = ["test_0001_top level it",
+                    "test_0002_не латинские &いった α, β, γ, δ, ε hello!!! world",
+                   ].sort
+
+    assert_equal test_methods, [x1, x2]
+    assert_equal test_methods, x.instance_methods.grep(/^test/).map(&:to_s).sort
+    assert_equal [], y.instance_methods.grep(/^test/)
+    assert_equal [], z.instance_methods.grep(/^test/)
+  end
+
+  def test_structure_subclasses
+    z = nil
+    x = Class.new Minitest::Spec do
+      def xyz; end
+    end
+    y = Class.new x do
+      z = describe("inner") { }
+    end
+
+    assert_respond_to x.new(nil), "xyz"
+    assert_respond_to y.new(nil), "xyz"
+    assert_respond_to z.new(nil), "xyz"
+  end
+end
+
+class TestSpecInTestCase < MetaMetaMetaTestCase
+  def setup
+    super
+
+    Thread.current[:current_spec] = self
+    @tc = self
+    @assertion_count = 2
+  end
+
+  def assert_triggered expected, klass = Minitest::Assertion
+    @assertion_count += 1
+
+    e = assert_raises klass do
+      yield
+    end
+
+    msg = e.message.sub(/(---Backtrace---).*/m, "\1")
+    msg.gsub!(/\(oid=[-0-9]+\)/, "(oid=N)")
+
+    assert_equal expected, msg
+  end
+
+  def teardown
+    msg = "expected #{@assertion_count} assertions, not #{@tc.assertions}"
+    assert_equal @assertion_count, @tc.assertions, msg
+  end
+
+  def test_expectation
+    @tc.assert_equal true, 1.must_equal(1)
+  end
+
+  def test_expectation_triggered
+    assert_triggered "Expected: 2\n  Actual: 1" do
+      1.must_equal 2
+    end
+  end
+
+  def test_expectation_with_a_message
+    assert_triggered "woot.\nExpected: 2\n  Actual: 1" do
+      1.must_equal 2, "woot"
+    end
+  end
+end
+
+class ValueMonadTest < Minitest::Test
+  attr_accessor :struct
+
+  def setup
+    @struct = { :_ => 'a', :value => 'b', :expect => 'c' }
+    def @struct.method_missing k # think openstruct
+      self[k]
+    end
+  end
+
+  def test_value_monad_method
+    assert_equal 'a', struct._
+  end
+
+  def test_value_monad_value_alias
+    assert_equal 'b', struct.value
+  end
+
+  def test_value_monad_expect_alias
+    assert_equal 'c', struct.expect
+  end
+end
diff --git a/app/server/vendor/minitest-5.8.1/test/minitest/test_minitest_unit.rb b/app/server/vendor/minitest-5.8.1/test/minitest/test_minitest_unit.rb
new file mode 100644
index 0000000..f804c48
--- /dev/null
+++ b/app/server/vendor/minitest-5.8.1/test/minitest/test_minitest_unit.rb
@@ -0,0 +1,1898 @@
+require "pathname"
+require "minitest/metametameta"
+
+module MyModule; end
+class AnError < StandardError; include MyModule; end
+class ImmutableString < String; def inspect; super.freeze; end; end
+SomeError = Class.new Exception
+
+class TestMinitestUnit < MetaMetaMetaTestCase
+  parallelize_me!
+
+  pwd = Pathname.new File.expand_path Dir.pwd
+  basedir = Pathname.new(File.expand_path "lib/minitest") + "mini"
+  basedir = basedir.relative_path_from(pwd).to_s
+  MINITEST_BASE_DIR = basedir[/\A\./] ? basedir : "./#{basedir}"
+  BT_MIDDLE = ["#{MINITEST_BASE_DIR}/test.rb:161:in `each'",
+               "#{MINITEST_BASE_DIR}/test.rb:158:in `each'",
+               "#{MINITEST_BASE_DIR}/test.rb:139:in `run'",
+               "#{MINITEST_BASE_DIR}/test.rb:106:in `run'"]
+
+  def test_filter_backtrace
+    # this is a semi-lame mix of relative paths.
+    # I cheated by making the autotest parts not have ./
+    bt = (["lib/autotest.rb:571:in `add_exception'",
+           "test/test_autotest.rb:62:in `test_add_exception'",
+           "#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
+          BT_MIDDLE +
+          ["#{MINITEST_BASE_DIR}/test.rb:29",
+           "test/test_autotest.rb:422"])
+    bt = util_expand_bt bt
+
+    ex = ["lib/autotest.rb:571:in `add_exception'",
+          "test/test_autotest.rb:62:in `test_add_exception'"]
+    ex = util_expand_bt ex
+
+    fu = Minitest.filter_backtrace(bt)
+
+    assert_equal ex, fu
+  end
+
+  def test_filter_backtrace_all_unit
+    bt = (["#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
+          BT_MIDDLE +
+          ["#{MINITEST_BASE_DIR}/test.rb:29"])
+    ex = bt.clone
+    fu = Minitest.filter_backtrace(bt)
+    assert_equal ex, fu
+  end
+
+  def test_filter_backtrace_unit_starts
+    bt = (["#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
+          BT_MIDDLE +
+          ["#{MINITEST_BASE_DIR}/mini/test.rb:29",
+           "-e:1"])
+
+    bt = util_expand_bt bt
+
+    ex = ["-e:1"]
+    fu = Minitest.filter_backtrace bt
+    assert_equal ex, fu
+  end
+
+  # def test_default_runner_is_minitest_unit
+  #   assert_instance_of Minitest::Unit, Minitest::Unit.runner
+  # end
+
+  def test_passed_eh_teardown_good
+    test_class = Class.new Minitest::Test do
+      def teardown; assert true; end
+      def test_omg; assert true; end
+    end
+
+    test = test_class.new :test_omg
+    test.run
+    assert test.passed?
+  end
+
+  def test_passed_eh_teardown_skipped
+    test_class = Class.new Minitest::Test do
+      def teardown; assert true; end
+      def test_omg; skip "bork"; end
+    end
+
+    test = test_class.new :test_omg
+    test.run
+
+    assert test.skipped?
+    refute test.passed?
+  end
+
+  def test_passed_eh_teardown_flunked
+    test_class = Class.new Minitest::Test do
+      def teardown; flunk;       end
+      def test_omg; assert true; end
+    end
+
+    test = test_class.new :test_omg
+    test.run
+    refute test.passed?
+  end
+
+  def util_expand_bt bt
+    if RUBY_VERSION >= "1.9.0" then
+      bt.map { |f| (f =~ /^\./) ? File.expand_path(f) : f }
+    else
+      bt
+    end
+  end
+end
+
+class TestMinitestUnitInherited < MetaMetaMetaTestCase
+  def with_overridden_include
+    Class.class_eval do
+      def inherited_with_hacks _klass
+        throw :inherited_hook
+      end
+
+      alias inherited_without_hacks inherited
+      alias inherited               inherited_with_hacks
+      alias IGNORE_ME!              inherited # 1.8 bug. god I love venture bros
+    end
+
+    yield
+  ensure
+    Class.class_eval do
+      alias inherited inherited_without_hacks
+
+      undef_method :inherited_with_hacks
+      undef_method :inherited_without_hacks
+    end
+
+    refute_respond_to Class, :inherited_with_hacks
+    refute_respond_to Class, :inherited_without_hacks
+  end
+
+  def test_inherited_hook_plays_nice_with_others
+    with_overridden_include do
+      assert_throws :inherited_hook do
+        Class.new Minitest::Test
+      end
+    end
+  end
+end
+
+class TestMinitestRunner < MetaMetaMetaTestCase
+  # do not parallelize this suite... it just can't handle it.
+
+  def test_class_runnables
+    @assertion_count = 0
+
+    tc = Class.new(Minitest::Test)
+
+    assert_equal 1, Minitest::Test.runnables.size
+    assert_equal [tc], Minitest::Test.runnables
+  end
+
+  def test_run_test
+    @tu =
+    Class.new Minitest::Test do
+      attr_reader :foo
+
+      def run
+        @foo = "hi mom!"
+        super
+        @foo = "okay"
+
+        self # per contract
+      end
+
+      def test_something
+        assert_equal "hi mom!", foo
+      end
+    end
+
+    expected = clean <<-EOM
+      .
+
+      Finished in 0.00
+
+      1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
+    EOM
+
+    assert_report expected
+  end
+
+  def test_run_error
+    @tu =
+    Class.new Minitest::Test do
+      def test_something
+        assert true
+      end
+
+      def test_error
+        raise "unhandled exception"
+      end
+    end
+
+    expected = clean <<-EOM
+      E.
+
+      Finished in 0.00
+
+        1) Error:
+      #<Class:0xXXX>#test_error:
+      RuntimeError: unhandled exception
+          FILE:LINE:in \`test_error\'
+
+      2 runs, 1 assertions, 0 failures, 1 errors, 0 skips
+    EOM
+
+    assert_report expected
+  end
+
+  def test_run_error_teardown
+    @tu =
+    Class.new Minitest::Test do
+      def test_something
+        assert true
+      end
+
+      def teardown
+        raise "unhandled exception"
+      end
+    end
+
+    expected = clean <<-EOM
+      E
+
+      Finished in 0.00
+
+        1) Error:
+      #<Class:0xXXX>#test_something:
+      RuntimeError: unhandled exception
+          FILE:LINE:in \`teardown\'
+
+      1 runs, 1 assertions, 0 failures, 1 errors, 0 skips
+    EOM
+
+    assert_report expected
+  end
+
+  def test_run_failing
+    setup_basic_tu
+
+    expected = clean <<-EOM
+      F.
+
+      Finished in 0.00
+
+        1) Failure:
+      #<Class:0xXXX>#test_failure [FILE:LINE]:
+      Failed assertion, no message given.
+
+      2 runs, 2 assertions, 1 failures, 0 errors, 0 skips
+    EOM
+
+    assert_report expected
+  end
+
+  def setup_basic_tu
+    @tu =
+    Class.new Minitest::Test do
+      def test_something
+        assert true
+      end
+
+      def test_failure
+        assert false
+      end
+    end
+  end
+
+  def test_run_failing_filtered
+    setup_basic_tu
+
+    expected = clean <<-EOM
+      .
+
+      Finished in 0.00
+
+      1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
+    EOM
+
+    assert_report expected, %w[--name /some|thing/ --seed 42]
+  end
+
+  def assert_filtering name, expected, a = false
+    args = %W[--name #{name} --seed 42]
+
+    alpha = Class.new Minitest::Test do
+      define_method :test_something do
+        assert a
+      end
+    end
+    Object.const_set(:Alpha, alpha)
+
+    beta = Class.new Minitest::Test do
+      define_method :test_something do
+        assert true
+      end
+    end
+    Object.const_set(:Beta, beta)
+
+    @tus = [alpha, beta]
+
+    assert_report expected, args
+  ensure
+    Object.send :remove_const, :Alpha
+    Object.send :remove_const, :Beta
+  end
+
+  def test_run_filtered_including_suite_name
+    expected = clean <<-EOM
+      .
+
+      Finished in 0.00
+
+      1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
+    EOM
+
+    assert_filtering "/Beta#test_something/", expected
+  end
+
+  def test_run_filtered_including_suite_name_string
+    expected = clean <<-EOM
+      .
+
+      Finished in 0.00
+
+      1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
+    EOM
+
+    assert_filtering "Beta#test_something", expected
+  end
+
+  def test_run_filtered_string_method_only
+    expected = clean <<-EOM
+      ..
+
+      Finished in 0.00
+
+      2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
+    EOM
+
+    assert_filtering "test_something", expected, :pass
+  end
+
+  def test_run_passing
+    @tu =
+    Class.new Minitest::Test do
+      def test_something
+        assert true
+      end
+    end
+
+    expected = clean <<-EOM
+      .
+
+      Finished in 0.00
+
+      1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
+    EOM
+
+    assert_report expected
+  end
+
+  def test_run_skip
+    @tu =
+    Class.new Minitest::Test do
+      def test_something
+        assert true
+      end
+
+      def test_skip
+        skip "not yet"
+      end
+    end
+
+    expected = clean <<-EOM
+      S.
+
+      Finished in 0.00
+
+      2 runs, 1 assertions, 0 failures, 0 errors, 1 skips
+
+      You have skipped tests. Run with --verbose for details.
+    EOM
+
+    restore_env do
+      assert_report expected
+    end
+  end
+
+  def test_run_skip_verbose
+    @tu =
+    Class.new Minitest::Test do
+      def test_something
+        assert true
+      end
+
+      def test_skip
+        skip "not yet"
+      end
+    end
+
+    expected = clean <<-EOM
+      #<Class:0xXXX>#test_skip = 0.00 s = S
+      #<Class:0xXXX>#test_something = 0.00 s = .
+
+      Finished in 0.00
+
+        1) Skipped:
+      #<Class:0xXXX>#test_skip [FILE:LINE]:
+      not yet
+
+      2 runs, 1 assertions, 0 failures, 0 errors, 1 skips
+    EOM
+
+    assert_report expected, %w[--seed 42 --verbose]
+  end
+
+  def test_run_with_other_runner
+    @tu =
+    Class.new Minitest::Test do
+      def self.run reporter, options = {}
+        @reporter = reporter
+        before_my_suite
+        super
+      end
+
+      def self.name; "wacky!" end
+
+      def self.before_my_suite
+        @reporter.reporters.first.io.puts "Running #{self.name} tests"
+        @@foo = 1
+      end
+
+      def test_something
+        assert_equal 1, @@foo
+      end
+
+      def test_something_else
+        assert_equal 1, @@foo
+      end
+    end
+
+    expected = clean <<-EOM
+      Running wacky! tests
+      ..
+
+      Finished in 0.00
+
+      2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
+    EOM
+
+    assert_report expected
+  end
+
+  require "monitor"
+
+  class Latch
+    def initialize count = 1
+      @count = count
+      @lock  = Monitor.new
+      @cv    = @lock.new_cond
+    end
+
+    def release
+      @lock.synchronize do
+        @count -= 1 if @count > 0
+        @cv.broadcast if @count == 0
+      end
+    end
+
+    def await
+      @lock.synchronize { @cv.wait_while { @count > 0 } }
+    end
+  end
+
+  def test_run_parallel
+    skip "I don't have ParallelEach debugged yet" if maglev?
+
+    test_count = 2
+    test_latch = Latch.new test_count
+    wait_latch = Latch.new test_count
+    main_latch = Latch.new
+
+    thread = Thread.new {
+      Thread.current.abort_on_exception = true
+
+      # This latch waits until both test latches have been released.  Both
+      # latches can't be released unless done in separate threads because
+      # `main_latch` keeps the test method from finishing.
+      test_latch.await
+      main_latch.release
+    }
+
+    @tu =
+    Class.new Minitest::Test do
+      parallelize_me!
+
+      test_count.times do |i|
+        define_method :"test_wait_on_main_thread_#{i}" do
+          test_latch.release
+
+          # This latch blocks until the "main thread" releases it. The main
+          # thread can't release this latch until both test latches have
+          # been released.  This forces the latches to be released in separate
+          # threads.
+          main_latch.await
+          assert true
+        end
+      end
+    end
+
+    expected = clean <<-EOM
+      ..
+
+      Finished in 0.00
+
+      2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
+    EOM
+
+    assert_report(expected) do |reporter|
+      reporter.extend(Module.new {
+        define_method("record") do |result|
+          super(result)
+          wait_latch.release
+        end
+
+        define_method("report") do
+          wait_latch.await
+          super()
+        end
+      })
+    end
+    assert thread.join
+  end
+end
+
+class TestMinitestUnitOrder < MetaMetaMetaTestCase
+  # do not parallelize this suite... it just can't handle it.
+
+  def test_before_setup
+    call_order = []
+    @tu =
+    Class.new Minitest::Test do
+      define_method :setup do
+        super()
+        call_order << :setup
+      end
+
+      define_method :before_setup do
+        call_order << :before_setup
+      end
+
+      def test_omg; assert true; end
+    end
+
+    run_tu_with_fresh_reporter
+
+    expected = [:before_setup, :setup]
+    assert_equal expected, call_order
+  end
+
+  def test_after_teardown
+    call_order = []
+    @tu =
+    Class.new Minitest::Test do
+      define_method :teardown do
+        super()
+        call_order << :teardown
+      end
+
+      define_method :after_teardown do
+        call_order << :after_teardown
+      end
+
+      def test_omg; assert true; end
+    end
+
+    run_tu_with_fresh_reporter
+
+    expected = [:teardown, :after_teardown]
+    assert_equal expected, call_order
+  end
+
+  def test_all_teardowns_are_guaranteed_to_run
+    call_order = []
+    @tu =
+    Class.new Minitest::Test do
+      define_method :after_teardown do
+        super()
+        call_order << :after_teardown
+        raise
+      end
+
+      define_method :teardown do
+        super()
+        call_order << :teardown
+        raise
+      end
+
+      define_method :before_teardown do
+        super()
+        call_order << :before_teardown
+        raise
+      end
+
+      def test_omg; assert true; end
+    end
+
+    run_tu_with_fresh_reporter
+
+    expected = [:before_teardown, :teardown, :after_teardown]
+    assert_equal expected, call_order
+  end
+
+  def test_setup_and_teardown_survive_inheritance
+    call_order = []
+
+    @tu = Class.new Minitest::Test do
+      define_method :setup do
+        call_order << :setup_method
+      end
+
+      define_method :teardown do
+        call_order << :teardown_method
+      end
+
+      define_method :test_something do
+        call_order << :test
+      end
+    end
+
+    run_tu_with_fresh_reporter
+
+    @tu = Class.new @tu
+    run_tu_with_fresh_reporter
+
+    # Once for the parent class, once for the child
+    expected = [:setup_method, :test, :teardown_method] * 2
+
+    assert_equal expected, call_order
+  end
+end
+
+class TestMinitestRunnable < Minitest::Test
+  def setup_marshal klass
+    tc = klass.new "whatever"
+    tc.assertions = 42
+    tc.failures << "a failure"
+
+    yield tc if block_given?
+
+    def tc.setup
+      @blah = "blah"
+    end
+    tc.setup
+
+    @tc = tc
+  end
+
+  def assert_marshal expected_ivars
+    new_tc = Marshal.load Marshal.dump @tc
+
+    ivars = new_tc.instance_variables.map(&:to_s).sort
+    assert_equal expected_ivars, ivars
+    assert_equal "whatever",     new_tc.name
+    assert_equal 42,             new_tc.assertions
+    assert_equal ["a failure"],  new_tc.failures
+
+    yield new_tc if block_given?
+  end
+
+  def test_marshal
+    setup_marshal Minitest::Runnable
+
+    assert_marshal %w[@NAME @assertions @failures]
+  end
+end
+
+class TestMinitestTest < TestMinitestRunnable
+  def test_dup
+    setup_marshal Minitest::Test do |tc|
+      tc.time = 3.14
+    end
+
+    assert_marshal %w[@NAME @assertions @failures @time] do |new_tc|
+      assert_in_epsilon 3.14, new_tc.time
+    end
+  end
+end
+
+class TestMinitestUnitTestCase < Minitest::Test
+  # do not call parallelize_me! - teardown accesses @tc._assertions
+  # which is not threadsafe. Nearly every method in here is an
+  # assertion test so it isn't worth splitting it out further.
+
+  RUBY18 = !defined? Encoding
+
+  def setup
+    super
+
+    Minitest::Test.reset
+
+    @tc = Minitest::Test.new "fake tc"
+    @zomg = "zomg ponies!"
+    @assertion_count = 1
+  end
+
+  def teardown
+    assert_equal(@assertion_count, @tc.assertions,
+                 "expected #{@assertion_count} assertions to be fired during the test, not #{@tc.assertions}") if @tc.passed?
+  end
+
+  def non_verbose
+    orig_verbose = $VERBOSE
+    $VERBOSE = false
+
+    yield
+  ensure
+    $VERBOSE = orig_verbose
+  end
+
+  def test_assert
+    @assertion_count = 2
+
+    @tc.assert_equal true, @tc.assert(true), "returns true on success"
+  end
+
+  def test_assert__triggered
+    util_assert_triggered "Failed assertion, no message given." do
+      @tc.assert false
+    end
+  end
+
+  def test_assert__triggered_message
+    util_assert_triggered @zomg do
+      @tc.assert false, @zomg
+    end
+  end
+
+  def test_assert_empty
+    @assertion_count = 2
+
+    @tc.assert_empty []
+  end
+
+  def test_assert_empty_triggered
+    @assertion_count = 2
+
+    util_assert_triggered "Expected [1] to be empty." do
+      @tc.assert_empty [1]
+    end
+  end
+
+  def test_assert_equal
+    @tc.assert_equal 1, 1
+  end
+
+  def test_assert_equal_different_collection_array_hex_invisible
+    object1 = Object.new
+    object2 = Object.new
+    msg = "No visible difference in the Array#inspect output.
+           You should look at the implementation of #== on Array or its members.
+           [#<Object:0xXXXXXX>]".gsub(/^ +/, "")
+    util_assert_triggered msg do
+      @tc.assert_equal [object1], [object2]
+    end
+  end
+
+  def test_assert_equal_different_collection_hash_hex_invisible
+    h1, h2 = {}, {}
+    h1[1] = Object.new
+    h2[1] = Object.new
+    msg = "No visible difference in the Hash#inspect output.
+           You should look at the implementation of #== on Hash or its members.
+           {1=>#<Object:0xXXXXXX>}".gsub(/^ +/, "")
+
+    util_assert_triggered msg do
+      @tc.assert_equal h1, h2
+    end
+  end
+
+  def test_assert_equal_different_diff_deactivated
+    skip "https://github.com/MagLev/maglev/issues/209" if maglev?
+
+    without_diff do
+      util_assert_triggered util_msg("haha" * 10, "blah" * 10) do
+        o1 = "haha" * 10
+        o2 = "blah" * 10
+
+        @tc.assert_equal o1, o2
+      end
+    end
+  end
+
+  def test_assert_equal_different_hex
+    c = Class.new do
+      def initialize s; @name = s; end
+    end
+
+    o1 = c.new "a"
+    o2 = c.new "b"
+    msg = "--- expected
+           +++ actual
+           @@ -1 +1 @@
+           -#<#<Class:0xXXXXXX>:0xXXXXXX @name=\"a\">
+           +#<#<Class:0xXXXXXX>:0xXXXXXX @name=\"b\">
+           ".gsub(/^ +/, "")
+
+    util_assert_triggered msg do
+      @tc.assert_equal o1, o2
+    end
+  end
+
+  def test_assert_equal_different_hex_invisible
+    o1 = Object.new
+    o2 = Object.new
+
+    msg = "No visible difference in the Object#inspect output.
+           You should look at the implementation of #== on Object or its members.
+           #<Object:0xXXXXXX>".gsub(/^ +/, "")
+
+    util_assert_triggered msg do
+      @tc.assert_equal o1, o2
+    end
+  end
+
+  def test_assert_equal_different_long
+    msg = "--- expected
+           +++ actual
+           @@ -1 +1 @@
+           -\"hahahahahahahahahahahahahahahahahahahaha\"
+           +\"blahblahblahblahblahblahblahblahblahblah\"
+           ".gsub(/^ +/, "")
+
+    util_assert_triggered msg do
+      o1 = "haha" * 10
+      o2 = "blah" * 10
+
+      @tc.assert_equal o1, o2
+    end
+  end
+
+  def test_assert_equal_different_long_invisible
+    msg = "No visible difference in the String#inspect output.
+           You should look at the implementation of #== on String or its members.
+           \"blahblahblahblahblahblahblahblahblahblah\"".gsub(/^ +/, "")
+
+    util_assert_triggered msg do
+      o1 = "blah" * 10
+      o2 = "blah" * 10
+      def o1.== _
+        false
+      end
+      @tc.assert_equal o1, o2
+    end
+  end
+
+  def test_assert_equal_different_long_msg
+    msg = "message.
+           --- expected
+           +++ actual
+           @@ -1 +1 @@
+           -\"hahahahahahahahahahahahahahahahahahahaha\"
+           +\"blahblahblahblahblahblahblahblahblahblah\"
+           ".gsub(/^ +/, "")
+
+    util_assert_triggered msg do
+      o1 = "haha" * 10
+      o2 = "blah" * 10
+      @tc.assert_equal o1, o2, "message"
+    end
+  end
+
+  def test_assert_equal_different_short
+    util_assert_triggered util_msg(1, 2) do
+      @tc.assert_equal 1, 2
+    end
+  end
+
+  def test_assert_equal_different_short_msg
+    util_assert_triggered util_msg(1, 2, "message") do
+      @tc.assert_equal 1, 2, "message"
+    end
+  end
+
+  def test_assert_equal_different_short_multiline
+    msg = "--- expected\n+++ actual\n@@ -1,2 +1,2 @@\n \"a\n-b\"\n+c\"\n"
+    util_assert_triggered msg do
+      @tc.assert_equal "a\nb", "a\nc"
+    end
+  end
+
+  def test_assert_in_delta
+    @tc.assert_in_delta 0.0, 1.0 / 1000, 0.1
+  end
+
+  def test_delta_consistency
+    @assertion_count = 2
+
+    @tc.assert_in_delta 0, 1, 1
+
+    util_assert_triggered "Expected |0 - 1| (1) to not be <= 1." do
+      @tc.refute_in_delta 0, 1, 1
+    end
+  end
+
+  def test_assert_in_delta_triggered
+    x = maglev? ? "9.999999xxxe-07" : "1.0e-06"
+    util_assert_triggered "Expected |0.0 - 0.001| (0.001) to be <= #{x}." do
+      @tc.assert_in_delta 0.0, 1.0 / 1000, 0.000001
+    end
+  end
+
+  def test_assert_in_epsilon
+    @assertion_count = 10
+
+    @tc.assert_in_epsilon 10_000, 9991
+    @tc.assert_in_epsilon 9991, 10_000
+    @tc.assert_in_epsilon 1.0, 1.001
+    @tc.assert_in_epsilon 1.001, 1.0
+
+    @tc.assert_in_epsilon 10_000, 9999.1, 0.0001
+    @tc.assert_in_epsilon 9999.1, 10_000, 0.0001
+    @tc.assert_in_epsilon 1.0, 1.0001, 0.0001
+    @tc.assert_in_epsilon 1.0001, 1.0, 0.0001
+
+    @tc.assert_in_epsilon(-1, -1)
+    @tc.assert_in_epsilon(-10_000, -9991)
+  end
+
+  def test_epsilon_consistency
+    @assertion_count = 2
+
+    @tc.assert_in_epsilon 1.0, 1.001
+
+    msg = "Expected |1.0 - 1.001| (0.000999xxx) to not be <= 0.001."
+    util_assert_triggered msg do
+      @tc.refute_in_epsilon 1.0, 1.001
+    end
+  end
+
+  def test_assert_in_epsilon_triggered
+    util_assert_triggered "Expected |10000 - 9990| (10) to be <= 9.99." do
+      @tc.assert_in_epsilon 10_000, 9990
+    end
+  end
+
+  def test_assert_in_epsilon_triggered_negative_case
+    x = (RUBY18 and not maglev?) ? "0.1" : "0.100000xxx"
+    y = maglev? ? "0.100000xxx" : "0.1"
+    util_assert_triggered "Expected |-1.1 - -1| (#{x}) to be <= #{y}." do
+      @tc.assert_in_epsilon(-1.1, -1, 0.1)
+    end
+  end
+
+  def test_assert_includes
+    @assertion_count = 2
+
+    @tc.assert_includes [true], true
+  end
+
+  def test_assert_includes_triggered
+    @assertion_count = 3
+
+    e = @tc.assert_raises Minitest::Assertion do
+      @tc.assert_includes [true], false
+    end
+
+    expected = "Expected [true] to include false."
+    assert_equal expected, e.message
+  end
+
+  def test_assert_instance_of
+    @tc.assert_instance_of String, "blah"
+  end
+
+  def test_assert_instance_of_triggered
+    util_assert_triggered 'Expected "blah" to be an instance of Array, not String.' do
+      @tc.assert_instance_of Array, "blah"
+    end
+  end
+
+  def test_assert_kind_of
+    @tc.assert_kind_of String, "blah"
+  end
+
+  def test_assert_kind_of_triggered
+    util_assert_triggered 'Expected "blah" to be a kind of Array, not String.' do
+      @tc.assert_kind_of Array, "blah"
+    end
+  end
+
+  def test_assert_match
+    @assertion_count = 2
+    @tc.assert_match(/\w+/, "blah blah blah")
+  end
+
+  def test_assert_match_matcher_object
+    @assertion_count = 2
+
+    pattern = Object.new
+    def pattern.=~(_) true end
+
+    @tc.assert_match pattern, 5
+  end
+
+  def test_assert_match_matchee_to_str
+    @assertion_count = 2
+
+    obj = Object.new
+    def obj.to_str; "blah" end
+
+    @tc.assert_match "blah", obj
+  end
+
+  def test_assert_match_object_triggered
+    @assertion_count = 2
+
+    pattern = Object.new
+    def pattern.=~(_) false end
+    def pattern.inspect; "[Object]" end
+
+    util_assert_triggered "Expected [Object] to match 5." do
+      @tc.assert_match pattern, 5
+    end
+  end
+
+  def test_assert_match_triggered
+    @assertion_count = 2
+    util_assert_triggered 'Expected /\d+/ to match "blah blah blah".' do
+      @tc.assert_match(/\d+/, "blah blah blah")
+    end
+  end
+
+  def test_assert_nil
+    @tc.assert_nil nil
+  end
+
+  def test_assert_nil_triggered
+    util_assert_triggered "Expected 42 to be nil." do
+      @tc.assert_nil 42
+    end
+  end
+
+  def test_assert_operator
+    @tc.assert_operator 2, :>, 1
+  end
+
+  def test_assert_operator_bad_object
+    bad = Object.new
+    def bad.==(_) true end
+
+    @tc.assert_operator bad, :equal?, bad
+  end
+
+  def test_assert_operator_triggered
+    util_assert_triggered "Expected 2 to be < 1." do
+      @tc.assert_operator 2, :<, 1
+    end
+  end
+
+  def test_assert_output_both
+    @assertion_count = 2
+
+    @tc.assert_output "yay", "blah" do
+      print "yay"
+      $stderr.print "blah"
+    end
+  end
+
+  def test_assert_output_both_regexps
+    @assertion_count = 4
+
+    @tc.assert_output(/y.y/, /bl.h/) do
+      print "yay"
+      $stderr.print "blah"
+    end
+  end
+
+  def test_assert_output_err
+    @tc.assert_output nil, "blah" do
+      $stderr.print "blah"
+    end
+  end
+
+  def test_assert_output_neither
+    @assertion_count = 0
+
+    @tc.assert_output do
+      # do nothing
+    end
+  end
+
+  def test_assert_output_out
+    @tc.assert_output "blah" do
+      print "blah"
+    end
+  end
+
+  def test_assert_output_triggered_both
+    util_assert_triggered util_msg("blah", "blah blah", "In stderr") do
+      @tc.assert_output "yay", "blah" do
+        print "boo"
+        $stderr.print "blah blah"
+      end
+    end
+  end
+
+  def test_assert_output_triggered_err
+    util_assert_triggered util_msg("blah", "blah blah", "In stderr") do
+      @tc.assert_output nil, "blah" do
+        $stderr.print "blah blah"
+      end
+    end
+  end
+
+  def test_assert_output_triggered_out
+    util_assert_triggered util_msg("blah", "blah blah", "In stdout") do
+      @tc.assert_output "blah" do
+        print "blah blah"
+      end
+    end
+  end
+
+  def test_assert_predicate
+    @tc.assert_predicate "", :empty?
+  end
+
+  def test_assert_predicate_triggered
+    util_assert_triggered 'Expected "blah" to be empty?.' do
+      @tc.assert_predicate "blah", :empty?
+    end
+  end
+
+  def test_assert_raises
+    @tc.assert_raises RuntimeError do
+      raise "blah"
+    end
+  end
+
+  def test_assert_raises_default
+    @tc.assert_raises do
+      raise StandardError, "blah"
+    end
+  end
+
+  def test_assert_raises_default_triggered
+    e = assert_raises Minitest::Assertion do
+      @tc.assert_raises do
+        raise SomeError, "blah"
+      end
+    end
+
+    expected = clean <<-EOM.chomp
+      [StandardError] exception expected, not
+      Class: <SomeError>
+      Message: <\"blah\">
+      ---Backtrace---
+      FILE:LINE:in \`test_assert_raises_default_triggered\'
+      ---------------
+    EOM
+
+    actual = e.message.gsub(/^.+:\d+/, "FILE:LINE")
+    actual.gsub!(/block \(\d+ levels\) in /, "") if RUBY_VERSION >= "1.9.0"
+
+    assert_equal expected, actual
+  end
+
+  def test_assert_raises_module
+    @tc.assert_raises MyModule do
+      raise AnError
+    end
+  end
+
+  ##
+  # *sigh* This is quite an odd scenario, but it is from real (albeit
+  # ugly) test code in ruby-core:
+  #
+  # http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=29259
+
+  def test_assert_raises_skip
+    @assertion_count = 0
+
+    util_assert_triggered "skipped", Minitest::Skip do
+      @tc.assert_raises ArgumentError do
+        begin
+          raise "blah"
+        rescue
+          skip "skipped"
+        end
+      end
+    end
+  end
+
+  def test_assert_raises_triggered_different
+    e = assert_raises Minitest::Assertion do
+      @tc.assert_raises RuntimeError do
+        raise SyntaxError, "icky"
+      end
+    end
+
+    expected = clean <<-EOM.chomp
+      [RuntimeError] exception expected, not
+      Class: <SyntaxError>
+      Message: <\"icky\">
+      ---Backtrace---
+      FILE:LINE:in \`test_assert_raises_triggered_different\'
+      ---------------
+    EOM
+
+    actual = e.message.gsub(/^.+:\d+/, "FILE:LINE")
+    actual.gsub!(/block \(\d+ levels\) in /, "") if RUBY_VERSION >= "1.9.0"
+
+    assert_equal expected, actual
+  end
+
+  def test_assert_raises_triggered_different_msg
+    e = assert_raises Minitest::Assertion do
+      @tc.assert_raises RuntimeError, "XXX" do
+        raise SyntaxError, "icky"
+      end
+    end
+
+    expected = clean <<-EOM
+      XXX.
+      [RuntimeError] exception expected, not
+      Class: <SyntaxError>
+      Message: <\"icky\">
+      ---Backtrace---
+      FILE:LINE:in \`test_assert_raises_triggered_different_msg\'
+      ---------------
+    EOM
+
+    actual = e.message.gsub(/^.+:\d+/, "FILE:LINE")
+    actual.gsub!(/block \(\d+ levels\) in /, "") if RUBY_VERSION >= "1.9.0"
+
+    assert_equal expected.chomp, actual
+  end
+
+  def test_assert_raises_triggered_none
+    e = assert_raises Minitest::Assertion do
+      @tc.assert_raises Minitest::Assertion do
+        # do nothing
+      end
+    end
+
+    expected = "Minitest::Assertion expected but nothing was raised."
+
+    assert_equal expected, e.message
+  end
+
+  def test_assert_raises_triggered_none_msg
+    e = assert_raises Minitest::Assertion do
+      @tc.assert_raises Minitest::Assertion, "XXX" do
+        # do nothing
+      end
+    end
+
+    expected = "XXX.\nMinitest::Assertion expected but nothing was raised."
+
+    assert_equal expected, e.message
+  end
+
+  def test_assert_raises_subclass
+    @tc.assert_raises StandardError do
+      raise AnError
+    end
+  end
+
+  def test_assert_raises_subclass_triggered
+    e = assert_raises Minitest::Assertion do
+      @tc.assert_raises SomeError do
+        raise AnError, "some message"
+      end
+    end
+
+    expected = clean <<-EOM
+      [SomeError] exception expected, not
+      Class: <AnError>
+      Message: <\"some message\">
+      ---Backtrace---
+      FILE:LINE:in \`test_assert_raises_subclass_triggered\'
+      ---------------
+    EOM
+
+    actual = e.message.gsub(/^.+:\d+/, "FILE:LINE")
+    actual.gsub!(/block \(\d+ levels\) in /, "") if RUBY_VERSION >= "1.9.0"
+
+    assert_equal expected.chomp, actual
+  end
+
+  def test_assert_raises_exit
+    @tc.assert_raises SystemExit do
+      exit 1
+    end
+  end
+
+  def test_assert_raises_signals
+    @tc.assert_raises SignalException do
+      raise SignalException, :INT
+    end
+  end
+
+  def test_assert_respond_to
+    @tc.assert_respond_to "blah", :empty?
+  end
+
+  def test_assert_respond_to_triggered
+    util_assert_triggered 'Expected "blah" (String) to respond to #rawr!.' do
+      @tc.assert_respond_to "blah", :rawr!
+    end
+  end
+
+  def test_assert_same
+    @assertion_count = 3
+
+    o = "blah"
+    @tc.assert_same 1, 1
+    @tc.assert_same :blah, :blah
+    @tc.assert_same o, o
+  end
+
+  def test_assert_same_triggered
+    @assertion_count = 2
+
+    util_assert_triggered "Expected 2 (oid=N) to be the same as 1 (oid=N)." do
+      @tc.assert_same 1, 2
+    end
+
+    s1 = "blah"
+    s2 = "blah"
+
+    util_assert_triggered 'Expected "blah" (oid=N) to be the same as "blah" (oid=N).' do
+      @tc.assert_same s1, s2
+    end
+  end
+
+  def test_assert_send
+    @tc.assert_send [1, :<, 2]
+  end
+
+  def test_assert_send_bad
+    util_assert_triggered "Expected 1.>(*[2]) to return true." do
+      @tc.assert_send [1, :>, 2]
+    end
+  end
+
+  def test_assert_silent
+    @assertion_count = 2
+
+    @tc.assert_silent do
+      # do nothing
+    end
+  end
+
+  def test_assert_silent_triggered_err
+    util_assert_triggered util_msg("", "blah blah", "In stderr") do
+      @tc.assert_silent do
+        $stderr.print "blah blah"
+      end
+    end
+  end
+
+  def test_assert_silent_triggered_out
+    @assertion_count = 2
+
+    util_assert_triggered util_msg("", "blah blah", "In stdout") do
+      @tc.assert_silent do
+        print "blah blah"
+      end
+    end
+  end
+
+  def test_assert_throws
+    @tc.assert_throws :blah do
+      throw :blah
+    end
+  end
+
+  def test_assert_throws_different
+    util_assert_triggered "Expected :blah to have been thrown, not :not_blah." do
+      @tc.assert_throws :blah do
+        throw :not_blah
+      end
+    end
+  end
+
+  def test_assert_throws_unthrown
+    util_assert_triggered "Expected :blah to have been thrown." do
+      @tc.assert_throws :blah do
+        # do nothing
+      end
+    end
+  end
+
+  def test_capture_io
+    @assertion_count = 0
+
+    non_verbose do
+      out, err = capture_io do
+        puts "hi"
+        $stderr.puts "bye!"
+      end
+
+      assert_equal "hi\n", out
+      assert_equal "bye!\n", err
+    end
+  end
+
+  def test_capture_subprocess_io
+    @assertion_count = 0
+
+    non_verbose do
+      out, err = capture_subprocess_io do
+        system("echo hi")
+        system("echo bye! 1>&2")
+      end
+
+      assert_equal "hi\n", out
+      assert_equal "bye!", err.strip
+    end
+  end
+
+  def test_class_asserts_match_refutes
+    @assertion_count = 0
+
+    methods = Minitest::Assertions.public_instance_methods
+    methods.map!(&:to_s) if Symbol === methods.first
+
+    # These don't have corresponding refutes _on purpose_. They're
+    # useless and will never be added, so don't bother.
+    ignores = %w[assert_output assert_raises assert_send
+                 assert_silent assert_throws]
+
+    # These are test/unit methods. I'm not actually sure why they're still here
+    ignores += %w[assert_no_match assert_not_equal assert_not_nil
+                  assert_not_same assert_nothing_raised
+                  assert_nothing_thrown assert_raise]
+
+    asserts = methods.grep(/^assert/).sort - ignores
+    refutes = methods.grep(/^refute/).sort - ignores
+
+    assert_empty refutes.map { |n| n.sub(/^refute/, "assert") } - asserts
+    assert_empty asserts.map { |n| n.sub(/^assert/, "refute") } - refutes
+  end
+
+  def test_flunk
+    util_assert_triggered "Epic Fail!" do
+      @tc.flunk
+    end
+  end
+
+  def test_flunk_message
+    util_assert_triggered @zomg do
+      @tc.flunk @zomg
+    end
+  end
+
+  def test_message
+    @assertion_count = 0
+
+    assert_equal "blah2.",         @tc.message          { "blah2" }.call
+    assert_equal "blah2.",         @tc.message("")      { "blah2" }.call
+    assert_equal "blah1.\nblah2.", @tc.message(:blah1)  { "blah2" }.call
+    assert_equal "blah1.\nblah2.", @tc.message("blah1") { "blah2" }.call
+
+    message = proc { "blah1" }
+    assert_equal "blah1.\nblah2.", @tc.message(message) { "blah2" }.call
+
+    message = @tc.message { "blah1" }
+    assert_equal "blah1.\nblah2.", @tc.message(message) { "blah2" }.call
+  end
+
+  def test_message_message
+    util_assert_triggered "whoops.\nExpected: 1\n  Actual: 2" do
+      @tc.assert_equal 1, 2, message { "whoops" }
+    end
+  end
+
+  def test_message_lambda
+    util_assert_triggered "whoops.\nExpected: 1\n  Actual: 2" do
+      @tc.assert_equal 1, 2, lambda { "whoops" }
+    end
+  end
+
+  def test_message_deferred
+    @assertion_count, var = 0, nil
+
+    msg = message { var = "blah" }
+
+    assert_nil var
+
+    msg.call
+
+    assert_equal "blah", var
+  end
+
+  def test_pass
+    @tc.pass
+  end
+
+  def test_prints
+    printer = Class.new { extend Minitest::Assertions }
+    @tc.assert_equal '"test"', printer.mu_pp(ImmutableString.new "test")
+  end
+
+  def test_refute
+    @assertion_count = 2
+
+    @tc.assert_equal false, @tc.refute(false), "returns false on success"
+  end
+
+  def test_refute_empty
+    @assertion_count = 2
+
+    @tc.refute_empty [1]
+  end
+
+  def test_refute_empty_triggered
+    @assertion_count = 2
+
+    util_assert_triggered "Expected [] to not be empty." do
+      @tc.refute_empty []
+    end
+  end
+
+  def test_refute_equal
+    @tc.refute_equal "blah", "yay"
+  end
+
+  def test_refute_equal_triggered
+    util_assert_triggered 'Expected "blah" to not be equal to "blah".' do
+      @tc.refute_equal "blah", "blah"
+    end
+  end
+
+  def test_refute_in_delta
+    @tc.refute_in_delta 0.0, 1.0 / 1000, 0.000001
+  end
+
+  def test_refute_in_delta_triggered
+    x = maglev? ? "0.100000xxx" : "0.1"
+    util_assert_triggered "Expected |0.0 - 0.001| (0.001) to not be <= #{x}." do
+      @tc.refute_in_delta 0.0, 1.0 / 1000, 0.1
+    end
+  end
+
+  def test_refute_in_epsilon
+    @tc.refute_in_epsilon 10_000, 9990-1
+  end
+
+  def test_refute_in_epsilon_triggered
+    util_assert_triggered "Expected |10000 - 9990| (10) to not be <= 10.0." do
+      @tc.refute_in_epsilon 10_000, 9990
+      flunk
+    end
+  end
+
+  def test_refute_includes
+    @assertion_count = 2
+
+    @tc.refute_includes [true], false
+  end
+
+  def test_refute_includes_triggered
+    @assertion_count = 3
+
+    e = @tc.assert_raises Minitest::Assertion do
+      @tc.refute_includes [true], true
+    end
+
+    expected = "Expected [true] to not include true."
+    assert_equal expected, e.message
+  end
+
+  def test_refute_instance_of
+    @tc.refute_instance_of Array, "blah"
+  end
+
+  def test_refute_instance_of_triggered
+    util_assert_triggered 'Expected "blah" to not be an instance of String.' do
+      @tc.refute_instance_of String, "blah"
+    end
+  end
+
+  def test_refute_kind_of
+    @tc.refute_kind_of Array, "blah"
+  end
+
+  def test_refute_kind_of_triggered
+    util_assert_triggered 'Expected "blah" to not be a kind of String.' do
+      @tc.refute_kind_of String, "blah"
+    end
+  end
+
+  def test_refute_match
+    @assertion_count = 2
+    @tc.refute_match(/\d+/, "blah blah blah")
+  end
+
+  def test_refute_match_matcher_object
+    @assertion_count = 2
+    @tc.refute_match Object.new, 5 # default #=~ returns false
+  end
+
+  def test_refute_match_object_triggered
+    @assertion_count = 2
+
+    pattern = Object.new
+    def pattern.=~(_) true end
+    def pattern.inspect; "[Object]" end
+
+    util_assert_triggered "Expected [Object] to not match 5." do
+      @tc.refute_match pattern, 5
+    end
+  end
+
+  def test_refute_match_triggered
+    @assertion_count = 2
+    util_assert_triggered 'Expected /\w+/ to not match "blah blah blah".' do
+      @tc.refute_match(/\w+/, "blah blah blah")
+    end
+  end
+
+  def test_refute_nil
+    @tc.refute_nil 42
+  end
+
+  def test_refute_nil_triggered
+    util_assert_triggered "Expected nil to not be nil." do
+      @tc.refute_nil nil
+    end
+  end
+
+  def test_refute_predicate
+    @tc.refute_predicate "42", :empty?
+  end
+
+  def test_refute_predicate_triggered
+    util_assert_triggered 'Expected "" to not be empty?.' do
+      @tc.refute_predicate "", :empty?
+    end
+  end
+
+  def test_refute_operator
+    @tc.refute_operator 2, :<, 1
+  end
+
+  def test_refute_operator_bad_object
+    bad = Object.new
+    def bad.==(_) true end
+
+    @tc.refute_operator true, :equal?, bad
+  end
+
+  def test_refute_operator_triggered
+    util_assert_triggered "Expected 2 to not be > 1." do
+      @tc.refute_operator 2, :>, 1
+    end
+  end
+
+  def test_refute_respond_to
+    @tc.refute_respond_to "blah", :rawr!
+  end
+
+  def test_refute_respond_to_triggered
+    util_assert_triggered 'Expected "blah" to not respond to empty?.' do
+      @tc.refute_respond_to "blah", :empty?
+    end
+  end
+
+  def test_refute_same
+    @tc.refute_same 1, 2
+  end
+
+  def test_refute_same_triggered
+    util_assert_triggered "Expected 1 (oid=N) to not be the same as 1 (oid=N)." do
+      @tc.refute_same 1, 1
+    end
+  end
+
+  def test_skip
+    @assertion_count = 0
+
+    util_assert_triggered "haha!", Minitest::Skip do
+      @tc.skip "haha!"
+    end
+  end
+
+  def test_runnable_methods_random
+    @assertion_count = 0
+
+    sample_test_case = Class.new Minitest::Test do
+      def self.test_order; :random; end
+      def test_test1; assert "does not matter" end
+      def test_test2; assert "does not matter" end
+      def test_test3; assert "does not matter" end
+    end
+
+    srand 42
+    expected = case
+               when maglev? then
+                 %w[test_test2 test_test3 test_test1]
+               else
+                 %w[test_test2 test_test1 test_test3]
+               end
+    assert_equal expected, sample_test_case.runnable_methods
+  end
+
+  def test_runnable_methods_sorted
+    @assertion_count = 0
+
+    sample_test_case = Class.new Minitest::Test do
+      def self.test_order; :sorted end
+      def test_test3; assert "does not matter" end
+      def test_test2; assert "does not matter" end
+      def test_test1; assert "does not matter" end
+    end
+
+    expected = %w[test_test1 test_test2 test_test3]
+    assert_equal expected, sample_test_case.runnable_methods
+  end
+
+  def test_i_suck_and_my_tests_are_order_dependent_bang_sets_test_order_alpha
+    @assertion_count = 0
+
+    shitty_test_case = Class.new Minitest::Test
+
+    shitty_test_case.i_suck_and_my_tests_are_order_dependent!
+
+    assert_equal :alpha, shitty_test_case.test_order
+  end
+
+  def test_i_suck_and_my_tests_are_order_dependent_bang_does_not_warn
+    @assertion_count = 0
+
+    shitty_test_case = Class.new Minitest::Test
+
+    def shitty_test_case.test_order; :lol end
+
+    assert_silent do
+      shitty_test_case.i_suck_and_my_tests_are_order_dependent!
+    end
+  end
+
+  def util_assert_triggered expected, klass = Minitest::Assertion
+    e = assert_raises klass do
+      yield
+    end
+
+    msg = e.message.sub(/(---Backtrace---).*/m, '\1')
+    msg.gsub!(/\(oid=[-0-9]+\)/, "(oid=N)")
+    msg.gsub!(/(\d\.\d{6})\d+/, '\1xxx') # normalize: ruby version, impl, platform
+
+    assert_equal expected, msg
+  end
+
+  def util_msg exp, act, msg = nil
+    s = "Expected: #{exp.inspect}\n  Actual: #{act.inspect}"
+    s = "#{msg}.\n#{s}" if msg
+    s
+  end
+
+  def without_diff
+    old_diff = Minitest::Assertions.diff
+    Minitest::Assertions.diff = nil
+
+    yield
+  ensure
+    Minitest::Assertions.diff = old_diff
+  end
+end
+
+class TestMinitestGuard < Minitest::Test
+  parallelize_me!
+
+  def test_mri_eh
+    assert self.class.mri? "ruby blah"
+    assert self.mri? "ruby blah"
+  end
+
+  def test_jruby_eh
+    assert self.class.jruby? "java"
+    assert self.jruby? "java"
+  end
+
+  def test_rubinius_eh
+    assert self.class.rubinius? "rbx"
+    assert self.rubinius? "rbx"
+  end
+
+  def test_windows_eh
+    assert self.class.windows? "mswin"
+    assert self.windows? "mswin"
+  end
+end
+
+class TestMinitestUnitRecording < MetaMetaMetaTestCase
+  # do not parallelize this suite... it just can't handle it.
+
+  def assert_run_record(*expected, &block)
+    @tu = Class.new Minitest::Test, &block
+
+    run_tu_with_fresh_reporter
+
+    recorded = first_reporter.results.map(&:failures).flatten.map { |f| f.error.class }
+
+    assert_equal expected, recorded
+  end
+
+  def test_record_passing
+    assert_run_record do
+      def test_method
+        assert true
+      end
+    end
+  end
+
+  def test_record_failing
+    assert_run_record Minitest::Assertion do
+      def test_method
+        assert false
+      end
+    end
+  end
+
+  def test_record_error
+    assert_run_record RuntimeError do
+      def test_method
+        raise "unhandled exception"
+      end
+    end
+  end
+
+  def test_record_error_teardown
+    assert_run_record RuntimeError do
+      def test_method
+        assert true
+      end
+
+      def teardown
+        raise "unhandled exception"
+      end
+    end
+  end
+
+  def test_record_error_in_test_and_teardown
+    assert_run_record AnError, RuntimeError do
+      def test_method
+        raise AnError
+      end
+
+      def teardown
+        raise "unhandled exception"
+      end
+    end
+  end
+
+  def test_to_s_error_in_test_and_teardown
+    @tu = Class.new Minitest::Test do
+      def test_method
+        raise AnError
+      end
+
+      def teardown
+        raise "unhandled exception"
+      end
+    end
+
+    run_tu_with_fresh_reporter
+
+    exp = clean "
+      Error:
+      #<Class:0xXXX>#test_method:
+      AnError: AnError
+          FILE:LINE:in `test_method'
+
+      Error:
+      #<Class:0xXXX>#test_method:
+      RuntimeError: unhandled exception
+          FILE:LINE:in `teardown'
+    "
+
+    assert_equal exp.strip, normalize_output(first_reporter.results.first.to_s).strip
+  end
+
+  def test_record_skip
+    assert_run_record Minitest::Skip do
+      def test_method
+        skip "not yet"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/.gemtest b/app/server/vendor/mocha-1.1.0/.gemtest
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/mocha-1.1.0/.gitignore b/app/server/vendor/mocha-1.1.0/.gitignore
new file mode 100755
index 0000000..8036342
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/.gitignore
@@ -0,0 +1,5 @@
+TODO
+Gemfile*.lock
+doc
+pkg
+
diff --git a/app/server/vendor/mocha-1.1.0/.travis.yml b/app/server/vendor/mocha-1.1.0/.travis.yml
new file mode 100755
index 0000000..58c388d
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/.travis.yml
@@ -0,0 +1,96 @@
+before_install:
+- gem update --system
+- gem --version
+script: "rake test"
+rvm:
+  - 1.8.7
+  - 1.9.3
+  - 2.0.0
+  - 2.1.0
+gemfile:
+  - Gemfile
+env:
+  - MOCHA_OPTIONS=debug
+matrix:
+  include:
+    - rvm: 2.0.0
+      gemfile: gemfiles/Gemfile.minitest.latest
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.9.3
+      gemfile: gemfiles/Gemfile.minitest.latest
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.9.3
+      gemfile: gemfiles/Gemfile.minitest.2.11.2
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.9.3
+      gemfile: gemfiles/Gemfile.minitest.2.11.0
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.9.3
+      gemfile: gemfiles/Gemfile.minitest.2.3.0
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.9.3
+      gemfile: gemfiles/Gemfile.minitest.2.0.1
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.9.3
+      gemfile: gemfiles/Gemfile.minitest.2.0.0
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.9.3
+      gemfile: Gemfile
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.8.7
+      gemfile: gemfiles/Gemfile.minitest.latest
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.8.7
+      gemfile: gemfiles/Gemfile.minitest.2.11.2
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.8.7
+      gemfile: gemfiles/Gemfile.minitest.2.11.0
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.8.7
+      gemfile: gemfiles/Gemfile.minitest.2.3.0
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.8.7
+      gemfile: gemfiles/Gemfile.minitest.2.0.1
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.8.7
+      gemfile: gemfiles/Gemfile.minitest.2.0.0
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.8.7
+      gemfile: gemfiles/Gemfile.minitest.1.4.2
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.8.7
+      gemfile: gemfiles/Gemfile.minitest.1.4.0
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 1.8.7
+      gemfile: gemfiles/Gemfile.minitest.1.3.0
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=minitest
+    - rvm: 2.0.0
+      gemfile: gemfiles/Gemfile.test-unit.latest
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=test-unit
+    - rvm: 1.9.3
+      gemfile: gemfiles/Gemfile.test-unit.latest
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=test-unit
+    - rvm: 1.9.3
+      gemfile: gemfiles/Gemfile.test-unit.2.0.3
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=test-unit
+    - rvm: 1.9.3
+      gemfile: gemfiles/Gemfile.test-unit.2.0.1
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=test-unit
+    - rvm: 1.9.3
+      gemfile: gemfiles/Gemfile.test-unit.2.0.0
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=test-unit
+    - rvm: 1.8.7
+      gemfile: gemfiles/Gemfile.test-unit.latest
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=test-unit
+    - rvm: 1.8.7
+      gemfile: gemfiles/Gemfile.test-unit.2.0.3
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=test-unit
+    - rvm: 1.8.7
+      gemfile: gemfiles/Gemfile.test-unit.2.0.1
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=test-unit
+    - rvm: 1.8.7
+      gemfile: gemfiles/Gemfile.test-unit.2.0.0
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=test-unit
+    - rvm: 1.8.7
+      gemfile: Gemfile
+      env: MOCHA_OPTIONS=debug MOCHA_RUN_INTEGRATION_TESTS=test-unit
diff --git a/app/server/vendor/mocha-1.1.0/.yardopts b/app/server/vendor/mocha-1.1.0/.yardopts
new file mode 100755
index 0000000..a86a4ce
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/.yardopts
@@ -0,0 +1,23 @@
+--template-path yard-templates
+--no-private
+lib/mocha/api.rb
+lib/mocha/hooks.rb
+lib/mocha/mock.rb
+lib/mocha/expectation.rb
+lib/mocha/object_methods.rb
+lib/mocha/class_methods.rb
+lib/mocha/parameter_matchers.rb
+lib/mocha/parameter_matchers
+lib/mocha/state_machine.rb
+lib/mocha/sequence.rb
+lib/mocha/configuration.rb
+lib/mocha/expectation_error_factory.rb
+lib/mocha/expectation_error.rb
+lib/mocha/stubbing_error.rb
+lib/mocha/unexpected_invocation.rb
+lib/mocha/integration/test_unit/adapter.rb
+lib/mocha/integration/mini_test/adapter.rb
+-
+RELEASE.md
+COPYING.md
+MIT-LICENSE.md
diff --git a/app/server/vendor/mocha-1.1.0/CONTRIBUTING.md b/app/server/vendor/mocha-1.1.0/CONTRIBUTING.md
new file mode 100755
index 0000000..14e318d
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/CONTRIBUTING.md
@@ -0,0 +1,12 @@
+* Pull requests are welcomed.
+* Fork the repository.
+* Make your changes in a branch.
+* Add tests for new behaviour. Modify/remove existing tests for changes to existing behaviour.
+* Run `bin/build-matrix` from the root directory and ensure all the tests pass.
+  * This script depends on `rbenv` being installed.
+  * You must have all the ruby versions listed in `.travis.yml` under the `rvm` key installed (currently 1.8.7, 1.9.3 & 2.0.0).
+  * I use `rbenv-aliases` to alias the patch versions.
+  * Note that the build matrix takes quite a while to run.
+* Send us a pull request from your fork/branch.
+* Wait for your pull request to build on [Travis CI](https://travis-ci.org/freerange/mocha).
+* I will not accept pull requests with failing tests.
diff --git a/app/server/vendor/mocha-1.1.0/COPYING.md b/app/server/vendor/mocha-1.1.0/COPYING.md
new file mode 100755
index 0000000..754057c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/COPYING.md
@@ -0,0 +1,3 @@
+Copyright Revieworld Ltd. 2006
+
+You may use, copy and redistribute this library under the same terms as [Ruby itself](http://www.ruby-lang.org/en/LICENSE.txt) or under the [MIT license](http://www.opensource.org/licenses/MIT).
diff --git a/app/server/vendor/mocha-1.1.0/Gemfile b/app/server/vendor/mocha-1.1.0/Gemfile
new file mode 100755
index 0000000..fa75df1
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/Gemfile
@@ -0,0 +1,3 @@
+source 'https://rubygems.org'
+
+gemspec
diff --git a/app/server/vendor/mocha-1.1.0/MIT-LICENSE.md b/app/server/vendor/mocha-1.1.0/MIT-LICENSE.md
new file mode 100755
index 0000000..c04087f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/MIT-LICENSE.md
@@ -0,0 +1,7 @@
+Copyright (c) 2006 Revieworld Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/mocha-1.1.0/README.md b/app/server/vendor/mocha-1.1.0/README.md
new file mode 100755
index 0000000..3c0f39c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/README.md
@@ -0,0 +1,277 @@
+## Mocha [![build status](https://secure.travis-ci.org/freerange/mocha.png)](https://secure.travis-ci.org/freerange/mocha) [![Gem Version](https://badge.fury.io/rb/mocha.png)](http://badge.fury.io/rb/mocha)
+
+### Description
+
+* A Ruby library for mocking and stubbing.
+* A unified, simple and readable syntax for both full & partial mocking.
+* Built-in support for MiniTest and Test::Unit.
+* Supported by many other test frameworks.
+
+### Installation
+
+#### Gem
+
+Install the latest version of the gem with the following command...
+
+    $ gem install mocha
+
+Note: If you are intending to use Mocha with Test::Unit or MiniTest, you should only setup Mocha *after* loading the relevant test library...
+
+##### Test::Unit
+
+```ruby
+require 'rubygems'
+gem 'mocha'
+require 'test/unit'
+require 'mocha/test_unit'
+```
+
+##### MiniTest
+
+```ruby
+require 'rubygems'
+gem 'mocha'
+require 'minitest/unit'
+require 'mocha/mini_test'
+```
+
+#### Bundler
+
+If you're using Bundler, include Mocha in the `Gemfile` and then setup Mocha later once you know the test library has been loaded...
+
+##### Test::Unit
+
+```ruby
+# Gemfile
+gem "mocha"
+
+# Elsewhere after Bundler has loaded gems e.g. after `require 'bundler/setup'`
+require "test/unit"
+require "mocha/test_unit"
+```
+
+##### MiniTest
+
+```ruby
+# Gemfile
+gem "mocha"
+
+# Elsewhere after Bundler has loaded gems e.g. after `require 'bundler/setup'`
+require "minitest/unit"
+require "mocha/mini_test"
+```
+
+#### Rails
+
+If you're loading Mocha using Bundler within a Rails application, you should setup Mocha manually e.g. at the bottom of your `test_helper.rb`.
+
+##### MiniTest
+
+```ruby
+# Gemfile in Rails app
+gem 'mocha'
+
+# At bottom of test_helper.rb (or at least after `require 'rails/test_help'`)
+require 'mocha/mini_test'
+```
+
+#### Rails Plugin
+
+Install the Rails plugin...
+
+    $ rails plugin install git://github.com/freerange/mocha.git
+
+Note: As of version 0.9.8, the Mocha plugin is not automatically setup at plugin load time. Instead it must be manually setup e.g. at the bottom of your `test_helper.rb`.
+
+##### MiniTest
+
+```ruby
+# At bottom of test_helper.rb (or at least after `require 'rails/test_help'`)
+require 'mocha/mini_test'
+```
+
+#### Know Issues
+
+* 0.13.x versions cause a harmless, but annoying, deprecation warning when used with Rails 3.2.0-3.2.12, 3.1.0-3.1.10 & 3.0.0-3.0.19.
+* 0.11.x versions don't work with Rails 3.2.13 (`TypeError: superclass mismatch for class ExpectationError`). See #115.
+* Versions 0.10.2, 0.10.3 & 0.11.0 of the Mocha gem were broken. Please do not use these versions.
+* Versions 0.9.6 & 0.9.7 of the Mocha Rails plugin were broken. Please do not use these versions.
+
+### Usage
+
+#### Quick Start
+
+```ruby
+require 'test/unit'
+require 'mocha/test_unit'
+
+class MiscExampleTest < Test::Unit::TestCase
+  def test_mocking_a_class_method
+    product = Product.new
+    Product.expects(:find).with(1).returns(product)
+    assert_equal product, Product.find(1)
+  end
+
+  def test_mocking_an_instance_method_on_a_real_object
+    product = Product.new
+    product.expects(:save).returns(true)
+    assert product.save
+  end
+
+  def test_stubbing_instance_methods_on_real_objects
+    prices = [stub(:pence => 1000), stub(:pence => 2000)]
+    product = Product.new
+    product.stubs(:prices).returns(prices)
+    assert_equal [1000, 2000], product.prices.collect {|p| p.pence}
+  end
+
+  def test_stubbing_an_instance_method_on_all_instances_of_a_class
+    Product.any_instance.stubs(:name).returns('stubbed_name')
+    product = Product.new
+    assert_equal 'stubbed_name', product.name
+  end
+
+  def test_traditional_mocking
+    object = mock('object')
+    object.expects(:expected_method).with(:p1, :p2).returns(:result)
+    assert_equal :result, object.expected_method(:p1, :p2)
+  end
+
+  def test_shortcuts
+    object = stub(:method1 => :result1, :method2 => :result2)
+    assert_equal :result1, object.method1
+    assert_equal :result2, object.method2
+  end
+end
+```
+
+#### Mock Objects
+
+```ruby
+class Enterprise
+  def initialize(dilithium)
+    @dilithium = dilithium
+  end
+
+  def go(warp_factor)
+    warp_factor.times { @dilithium.nuke(:anti_matter) }
+  end
+end
+
+require 'test/unit'
+require 'mocha/test_unit'
+
+class EnterpriseTest < Test::Unit::TestCase
+  def test_should_boldly_go
+    dilithium = mock()
+    dilithium.expects(:nuke).with(:anti_matter).at_least_once  # auto-verified at end of test
+    enterprise = Enterprise.new(dilithium)
+    enterprise.go(2)
+  end
+end
+```
+
+#### Partial Mocking
+
+```ruby
+class Order
+  attr_accessor :shipped_on
+
+  def total_cost
+    line_items.inject(0) { |total, line_item| total + line_item.price } + shipping_cost
+  end
+
+  def total_weight
+    line_items.inject(0) { |total, line_item| total + line_item.weight }
+  end
+
+  def shipping_cost
+    total_weight * 5 + 10
+  end
+
+  class << self
+    def find_all
+      # Database.connection.execute('select * from orders...
+    end
+  
+    def number_shipped_since(date)
+      find_all.select { |order| order.shipped_on > date }.length
+    end
+
+    def unshipped_value
+      find_all.inject(0) { |total, order| order.shipped_on ? total : total + order.total_cost }
+    end
+  end
+end
+
+require 'test/unit'
+require 'mocha/test_unit'
+
+class OrderTest < Test::Unit::TestCase
+  # illustrates stubbing instance method
+  def test_should_calculate_shipping_cost_based_on_total_weight
+    order = Order.new
+    order.stubs(:total_weight).returns(10)
+    assert_equal 60, order.shipping_cost
+  end
+
+  # illustrates stubbing class method
+  def test_should_count_number_of_orders_shipped_after_specified_date
+    now = Time.now; week_in_secs = 7 * 24 * 60 * 60
+    order_1 = Order.new; order_1.shipped_on = now - 1 * week_in_secs
+    order_2 = Order.new; order_2.shipped_on = now - 3 * week_in_secs
+    Order.stubs(:find_all).returns([order_1, order_2])
+    assert_equal 1, Order.number_shipped_since(now - 2 * week_in_secs)
+  end
+
+  # illustrates stubbing instance method for all instances of a class
+  def test_should_calculate_value_of_unshipped_orders
+    Order.stubs(:find_all).returns([Order.new, Order.new, Order.new])
+    Order.any_instance.stubs(:shipped_on).returns(nil)
+    Order.any_instance.stubs(:total_cost).returns(10)
+    assert_equal 30, Order.unshipped_value
+  end
+end
+```
+
+### Thread safety
+
+Mocha is currently *not* thread-safe. There are two main reasons for this: (a) in multi-threaded code Mocha exceptions may be raised in a thread other than the one which is running the test and thus a Mocha exception may not be correctly intercepted by Mocha exception handling code; and (b) partial mocking changes the state of objects in the `ObjectSpace` which is shared across all threads in the Ruby process and this access to what is effectively global state is not synchronized.
+
+### Expectation matching / invocation order
+
+Stubs and expectations are basically the same thing. A stub is just an expectation of zero or more invocations. The `Expectation#stubs` method is syntactic sugar to make the intent of the test more explicit.
+
+When a method is invoked on a mock object, the mock object searches through its expectations from newest to oldest to find one that matches the invocation. After the invocation, the matching expectation might stop matching further invocations.
+
+See the [documentation](http://gofreerange.com/mocha/docs/Mocha/Mock.html) for `Mocha::Mock` for further details.
+
+### Useful Links
+
+* [Official Documentation](http://gofreerange.com/mocha/docs/)
+* [Source Code](http://github.com/freerange/mocha)
+* [Mailing List](http://groups.google.com/group/mocha-developer)
+* [James Mead's Blog](http://jamesmead.org/blog/)
+* [An Introduction To Mock Objects In Ruby](http://jamesmead.org/talks/2007-07-09-introduction-to-mock-objects-in-ruby-at-lrug/)
+* [Mocks Aren't Stubs](http://martinfowler.com/articles/mocksArentStubs.html)
+* [Growing Object-Oriented Software Guided By Tests](http://www.growing-object-oriented-software.com/)
+* [Mock Roles Not Objects](http://www.jmock.org/oopsla2004.pdf)
+* [jMock](http://www.jmock.org/)
+
+### Contributors
+
+See this [list of contributors](https://github.com/freerange/mocha/graphs/contributors).
+
+### Translations
+
+* [Serbo-Croatian](http://science.webhostinggeeks.com/mocha) by [WHG Team](http://webhostinggeeks.com/). (may be out-of-date)
+
+### History
+
+Mocha was initially harvested from projects at [Reevoo](http://www.reevoo.com/). It's syntax is heavily based on that of [jMock](http://www.jmock.org).
+
+### License
+
+© Copyright Revieworld Ltd. 2006
+
+You may use, copy and redistribute this library under the same terms as [Ruby itself](http://www.ruby-lang.org/en/LICENSE.txt) or under the [MIT license](http://www.opensource.org/licenses/MIT).
diff --git a/app/server/vendor/mocha-1.1.0/RELEASE.md b/app/server/vendor/mocha-1.1.0/RELEASE.md
new file mode 100755
index 0000000..679398c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/RELEASE.md
@@ -0,0 +1,536 @@
+# Release Notes
+
+## 1.1.0
+
+* Set visibility of any instance stub method.
+* Stub methods with a prepended method if there are other prepended methods. Thanks to @mrsimo.
+* Improve docs for `Mock#responds_like` & `#responds_like_instance_of`.
+* Use GitHub convention for instructions on contributing to Mocha.
+* Fix typos in docs. Thanks to @10io
+
+## 1.0.0
+
+### External changes
+* Assume 'mocha' has been required when requiring 'mocha/setup'.
+* Provide shortcuts for integrating with specific test library i.e. `require 'mocha/test_unit'` or `require 'mocha/mini_test'`
+as alternatives to `require 'mocha/setup'`.
+* Do not automatically try to integrate with test libraries. Since the automatic test library integration functionality
+requires the test library to be loaded and this doesn't usually happen until *after* the bundle is loaded, it makes things
+simpler if we use `require 'mocha/setup'` to explicitly setup Mocha when we know the test library has been loaded. Fixes #146 & #155.
+* Consider stubs on superclasses if none exist on primary receiver. Largely based on changes suggested by @ccutrer in #145.
+Note: this may break existing tests which rely on the old behaviour. Stubbing a superclass method and then invoking that
+method on a child class would previously cause an unexpected invocation error. By searching up through the inheritance
+hierarchy for each of the delegate mock objects, we can provide more intuitive behaviour. Instead of an unexpected invocation
+error, invoking the method on the child class will cause the stubbed method on the superclass to be used.
+* Avoid recursion when constructing unexpected invocation message. Fixes #168.
+* Add explanation of method dispatch. Heavily based on the relevant jMock v1 documentation. Fixes #172.
+* Make class_eval line number more accurate. This sets the line number as the line number of the `def` statement. Closes #169.
+* Allow nesting of `responds_with` parameter matcher. Closes #166.
+* Define `Mocha` module before it's referenced. The test helper defines a class `TestCase` within the `Mocha` module. When
+running the tests inside the bundle, the `Mocha` module happens to be defined at this point. However when running the tests outside the bundle, it is not defined and so an exception is raised: `uninitialized constant Mocha (NameError)`. Fixes #163.
+* Document lack of thread-safety. Fixes #154.
+* Document how to use the build-matrix script. Fixes #160.
+* Stubbing non-public method should use same visibility. This will probably break some existing tests that were somehow relying
+on the stubbed method being public while the original method was protected or private. Fixes #150.
+
+### Internal changes
+* Use lastest Rubygems in Travis CI builds.
+* Run the standard test suite against Ruby 2.1.0 in the build matrix.
+* Run integration tests against Ruby 2.0.0 with latest Test::Unit gem in the build matrix.
+* Test::Unit is not available in Ruby v1.9.3 standard library, so remove it from the build matrix.
+* Force use of Test::Unit runner, etc in relevant integration tests. Prior to this, I don't think we were really testing the
+Mocha integration with Test::Unit much, because, although `TestUnitTest` was a subclass of `Test::Unit::TestCase`, the
+important test case instances are the temporary ones built by `TestRunner#run_as_test` et al. Prior to this change, these
+would only have used Test::Unit where MiniTest was not available *at all* i.e. only in early versions of Ruby and when the
+MiniTest gem was not loaded.
+* Reset environment variables between build matrix builds.
+* Only activate integration with relevant test library for each of the integration tests.
+* Include standard build combinations from Travis CI config i.e. builds using standard library versions of test libraries.
+* Fix `build-matrix.rb` script. Also use `.travis.yml` to decide what combinations to run. This means we
+can now simulate the Travis CI build locally and avoid duplication. Fixes #157.
+* Remove Ruby version map from build matrix script. I'm using the `rbenv-aliases` plugin to alias minor versions to the
+relevant patch version.
+
+## 0.14.0
+
+* Official support for MiniTest v5. All tests now pass on the continuous integration build.
+
+## 0.14.0.alpha
+
+* Add speculative support for Minitest v5. Due to incompatibilities it has not yet been possible to run the Mocha test suite against Minitest v5. However, @zenspider (author of Minitest) provided the patch and he has tested it against Rails v4. Fixes #156. Thanks to @zenspider.
+* Documentation updates.
+
+## 0.13.3
+* Allow `Mocha::ParameterMatchers#includes` to accept multiple items. Thanks to @simao.
+* Allow stubbing of *private* `Kernel` methods. Fixes #134. Thanks to @camski for reporting.
+* Avoid a warning when `test/unit/version` is required by other libraries in the same project. Fixes #140. Thanks to @tmiller.
+* Make auto-activation of Test::Unit integration more resilient. This change is specifically to cope with the nasty re-defining of classes that is done by the `minitest-spec-rails` gem. Fixes #143. Thanks to @tubaxenor for reporting.
+* Safer restoration of stubbed method visibility. Fixes #141. Thanks to @tmm1.
+* Ensure `Mockery` instance gets reset even if exception raised. Fixes #144.
+* Adapt Mocha acceptance tests to cope with changes in output from latest (v4.6.2) of MiniTest.
+* Updates to README about Rails compatibility.
+
+## 0.13.2
+* Stubbing of methods re-declared with different visibilty. Fixes #109.
+* Add `Mock#responds_like_instance_of`. Fixes #119.
+* Make `Expectation#inspect` less verbose and more useful. Fixes #122.
+* Make unit tests more robust to changes in environment. Fixes #121.
+* Update README in an attempt to head Rails-related issues off at the pass.
+* Add a Gem Badge to provide a link to Mocha on Rubygems.
+* Make documentation example consistent with other examples.
+
+## 0.13.1
+* Fix #97 - `Mocha::ParameterMatchers#has_entry` does not work with an Array as the entry's value. Thanks to @ngokli.
+* Allow deprecation `:debug` mode to be switched on from `MOCHA_OPTIONS` environment variable.
+
+## 0.13.0
+* Major overhaul of MiniTest & Test::Unit integration. Mocha now integrates with later versions of the two test libraries using documented hooks rather than monkey-patching. This should mean that Mocha will integrate with new versions of either library without the need to release a new version of Mocha each time, which was clearly bad and unsustainable. Many thanks to @tenderlove, @zenspider & @kou for their help, suggestions & patience.
+* Temporarily deprecated `require 'mocha'`. Use `require 'mocha/setup'` instead. The plan is that eventually `require 'mocha'` will *not* automatically integrate with either of the two test libraries as it does at the moment, and you'll need to explicitly & separately trigger the integration. I think this will provide a lot more flexibility and will hopefully do away with the need for the `require: false` option in the `Gemfile` which has always confused people.
+* Deprecated `require 'mocha_standalone'` and `require 'mocha/standalone'`. Use `require 'mocha/api` instead.
+* Although these are not part of Mocha's public API, I thought I should mention that the MiniTest and Test::Unit assertion counter classes have been combined into a single class `Mocha::Integration::AssertionCounter`.
+* Extracted Mocha::Hooks module from Mocha::API and added documentation for test library authors.
+* Improvements to documentation. Much of it has been combined into the README file.
+* Fix #101 - Mock#respond_to? doesn't work with a string argument - thanks to @urbanautomaton.
+* Fix #105 - Travis link in README - thanks to @cknadler.
+* Various improvements to automated testing of integration with test libraries.
+* Make deprecation warnings more prominent.
+
+## 0.12.7
+* Officially support minitest v4.1.0 (still monkey-patching).
+
+## 0.12.6
+* Fixes #103.
+
+## 0.12.5
+* Officially support minitest v3.5.0 (still monkey-patching).
+
+## 0.12.4
+* Officially support minitest v3.4.0 & test-unit v2.5.2 (still monkey-patching).
+
+## 0.12.3
+* Revert rename of undocumented internal module since it turns out Rails/ActiveSupport is relying on its existence.
+
+## 0.12.2
+* Officially support minitest v3.3.0 (still monkey-patching)
+
+## 0.12.1
+* Deprecation warning (instead of fail fast) if neither Test::Unit nor MiniTest is loaded. Fixes #88.
+* Remove deprecated access to `Mocha::Standalone`.
+* Remove the deprecated file `stubba.rb`.
+* Officially support test-unit v2.5.1 (still monkey-patching).
+* Improve the API acceptance test.
+
+## 0.12.0
+* Fail fast if neither Test::Unit nor MiniTest is loaded. Fixes #40.
+* Officially support MiniTest up to v3.2.0 (still monkey-patching).
+* Officially support test-unit v2.5.0 (still monkey-patching).
+* Do not monkey-patch Test::Unit or MiniTest unless we *know* it's ok.
+* Add acceptance tests to demonstrate using a block as a custom parameter matcher.
+* Update Travis CI build status image to use the new build under the freerange account.
+
+## 0.11.4
+* Homepage has moved to http://gofreerange.com/mocha/docs.
+
+## 0.11.3
+* Fix for #78 i.e. alias Object#method as Object#_method, not Object#__method__ which already exists as another Ruby method.
+
+## 0.11.2
+* Rails has a Request class which defines its own #method method. This broke the new mechanism for stubbing a method. This release includes a slightly modified version of fix #77 provided by @sikachu. See https://github.com/rails/rails/pull/5907 for further info.
+
+## 0.11.1
+* In Ruby 1.8.7 methods accepting a block parameter were incorrectly restored without the block parameter after being stubbed. Fix for #76.
+
+## 0.11.0
+* Store original method when stubbing rather than using alias_method. This fixes #41, #47, #74 and all tests now pass on both Ruby 1.8.7 and 1.9.3.
+* Attempting to stub a method on a frozen object should fail fast. See #68.
+* Prevent stubbing a method on nil by default. See #68.
+* Generate documentation using YARD instead of Rdoc - removes dependency on Coderay.
+* Publish documentation on Github pages instead of Rubyforge - uses rake task written by @tomafro.
+* Remove agiledox which has outlived it's usefulness.
+* Removed trailing whitespace throughout codebase.
+* Add documentation for Mock#unstub.
+* Improve documentation for ObjectMethods.
+* Provide a way to run multiple tests within a single acceptance test method.
+
+## 0.10.5
+* Fix for issue #66 (hopefully without regressing on issue #63) - Mocha::Mock has Mocha::Mockery as a dependency. Stop trying to pretend otherwise. Thanks to @kennyj for reporting.
+* Fix a bunch of warnings in Ruby 1.9. There are still the 6 test failures mentioned in issue #41 which I suspect are due to the introspection gem not being Ruby 1.9-compatible.
+* Add links to README for source code & issue tracker.
+* Fix for issue #67 - Make the travis-ci badge visible in the README. Thanks to Diego Plentz for pull request.
+* Fix for issue #70 - Rename Mock#expectations to Mock#__expectations__ to avoid conflicts. Thanks to Jeremy Stephens for pull request.
+
+## 0.10.4
+* Fix for issue #65 - expectations not being verified in subsequent tests.
+* Fix for issue #63 - require Mocha::Mockery at Mocha::Mock class load time and not on invocation of Mock#method_missing.
+* Fix for issue #45 - raise ArgumentError if Mocha::ParameterMatchers#has_entry is given
+Hash with wrong number of entries.
+* Make global variable name more obscure to avoid clashes with other libraries.
+* Move travis-ci-related gemfiles into their own directory.
+
+## 0.10.3
+* Fix for issue #57. Gem::Requirement#=~ was only added in rubygems v1.8.0, but Object#=~ means the result of various monkey-patching checks is always false/nil for earlier versions of rubygems. However, the method it aliases #satisfied_by? has existed since Gem::Dependency was extracted from Gem::Version in rubygems v0.9.4.4, so it's much safer to use that. Thanks to fguillen for reporting and helping with diagnosis.
+
+## 0.10.2
+* Merge pull request #53. Unstubbing a method should not remove expectations for other stubbed methods. Fixes #52. Thanks to saikat.
+
+## 0.10.1
+* Merge pull request #51. Use Gem::Requirement & Gem::Version for version comparison. Fixes issue #50. Thanks to meineerde.
+* Fixed typo in rdoc for Mocha::ObjectMethods.
+* Improve README as suggested in issue #46. Explain that Mocha must be loaded after test libraries and how to achieve this using Bundler.
+* Merge pull request #43 - nobody expects the spanish inquisition! Thanks to cairo140.
+* Fix for issue #39 - improve documentation for Expectation#multiple_yields.
+* Fix for issue #38 where a subtle change in test-unit v2.3.0 had been missed - only visible in verbose mode.
+* Support for MiniTest up to v2.6.2 has been verified.
+* Add explicit development dependency on coderay for generating syntax-highlighted code examples.
+
+## 0.10.0
+* Add Expectation#throws to allow a stubbed method to use Kernel#throw.
+* Updates for versions of Test::Unit up to and including v2.3.3 (including patch by Jens Fahnenbruck).
+* Updates for versions of MiniTest up to and including v2.5.1.
+* Since the singleton method added by Mocha masks the underlying instance method, there's no need to move it out the way and then back again. This fixes Github issue #20, because the original method is left unchanged - https://github.com/floehopper/mocha/issues/20 (thanks to Nick Lewis).
+* Handle stubbing of a singleton method, leaving the original method unchanged after the test.
+* When stubbing an instance method that was originally defined as a singleton method, the original method should still exist after the test.
+* Fixed mis-print in Mocha::ObjectMethods#unstub documentation (patch by Gleb Pomykalov).
+* Improved test coverage around stubbing of methods defined in different ways - this makes use of the newly extracted introspection gem (although this means some tests are now failing in Ruby v1.9.2).
+* Added configuration for Travis continuous integration.
+* Make the gemspec the canonical reference and stop generating it from the Rakefile.
+* Use the built-in Bundler rake tasks for packaging the gem.
+* Use the "release" rake task provided by Bundler instead of using the Rake::XForge::Release functionality.
+* Extract Object#__metaclass__ into a new metaclass gem.
+* Run rake tasks without `bundle exec`.
+* Avoid deprecation warning for rdoc rake task.
+* Remove the `use_test_unit_gem` MOCHA_OPTION which hasn't worked since we switched to bundler - we can now run the tests specifying a different Gemfile instead.
+* Use multiple Gemfiles seems to run Travis CI builds against multiple version of test-unit & minitest.
+
+## 0.9.12
+* Make Mocha's tests pass under Ruby 1.9.2 i.e. using MiniTest. One of the main issues was that we were not parsing stacktraces on MiniTest errors comprehensively enough.
+* Avoid 'circular require considered harmful' warning when running Mocha's tests in Ruby 1.9.2
+* Make performance tests work on Ruby 1.9.2 i.e. using MiniTest.
+* Declare rake as a *development* dependency with newer versions of Rubygems since it's only needed to carry out developer-related tasks.
+
+## 0.9.11
+* Added explicit support for minitest v1.5.0 to v2.0.2.
+* Make testable by rubygems-test.
+* Update links to my blog and make other links consistent.
+* Added a URI parameter matcher that ignores the order of query parameters so that tests can be independent of undefined hash ordering (patch by Paul Battley).
+* Include unexpected invocation in failure message and change the language slightly to make the failure message less confusing. See http://floehopper.lighthouseapp.com/projects/22289/tickets/52.
+* No need to create regular expression every time the BacktraceFilter#filtered method is called. See http://floehopper.lighthouseapp.com/projects/22289-mocha/tickets/66.
+
+## 0.9.10
+* Added Mocha::ObjectMethods#unstub method - https://github.com/floehopper/mocha/issues#issue/6
+* Inherit Mocha::ExpectationError from Exception instead of StandardError to reduce the chances of a test passing by accident - thanks to James Sanders (jsanders) - https://github.com/floehopper/mocha/issues#issue/15
+* Fixed bug - GitHub README page to link correctly to code examples - https://github.com/floehopper/mocha/issues/closed#issue/11
+* Fixed bug - PASSTHROUGH_EXCEPTIONS are defined on MiniTest::Unit::TestCase not in Mocha - thanks to Brian Troutwine (blt) - https://github.com/floehopper/mocha/issues/closed#issue/14
+
+## 0.9.9
+* Avoid loading bits of the test-unit gem by accident. This is an attempt at a fix for the problem that James Adam reported [1]. By using 'load' instead of 'require' to detect the version of Test::Unit, we can avoid rubygems trying to load bits of the test-unit gem when it's not wanted. [1] http://floehopper.lighthouseapp.com/projects/22289-mocha/tickets/50#ticket-50-13
+* Fix exception when running rake without test-unit gem. When test-unit gem >=v2.0.0 was installed but the "use_test_unit_gem" MOCHA_OPTIONS was not specified, a "comparison of Fixnum with Hash failed" exception was being raised when running the performance tests. This was because bits of the test-unit gem were being loaded accidentally and a Hash was being incorrectly supplied to the TestRunner.run method.
+* Explicitly require rubygems for running tests via rake using test-unit gem.
+* Handle newer versions of test-unit gem (v2.0.2 to v2.0.9)
+* Handle newer versions of minitest gem (v1.4.0 to v1.6.0)
+* Added warnings about monkey-patching test-unit and minitest to aid debugging. These are enabled by including "debug" in the MOCHA_OPTIONS environment variable. This is now a comma-separated list, so that we can specify multiple options e.g. MOCHA_OPTIONS=debug,use_test_unit_gem
+* Eloy Duran (alloy) made the unit tests run on 1.9.2dev r25249.
+* Eloy Duran (alloy) also improved some MiniTest TestResult code I'd written and got the acceptance tests running on Ruby 1.9 HEAD. There are still 4 failures because for some reason the backtrace line numbers are off by one. And the minitest_test test case does not run when the whole suite is run with MiniTest. These issues still need investigation.
+* Fixed some acceptance tests to run in Ruby 1.9.2 - it's no longer possible to subvert the protection of a method by calling it via Object#send.
+* Fixed "test:performance" rake task so it runs in Ruby 1.9.2.
+* Fix test incorrectly failing under Rubinius 1.0. This test imposed too many constraints. It appears that Object#inspect legitimately calls Object#object_id in Rubinius. But we're only interested in what 'id' methods Mocha::ObjectMethods#mocha_inspect calls. By stubbing Object#inspect we can relax the constraints imposed by the test.
+* Luke Redpath (lukeredpath) added new shorthand "any" and "all" composite parameter matchers using "&" and "|". This provides an alternative syntax for expecting any or all matchers to pass, e.g. foo.expects(:bar).with(equals(1) | equals(2)).
+* Improved documentation for Expectation#raises. A number of people have suggested an extension to the API to cope with custom exceptions that have extra constructor parameters. However, since the arguments supplied to Expectation#raises are just passed on to Kernel#raise, it's possible to pass in an instance of an exception. Thus no change to the API is required, but it does seem worthwhile pointing this out in the docs.
+* Corrected RDoc example for Expectation#never thanks to Red David (reddavis).
+* Improved RDoc including a change suggested by Rohit Arondekar (rohit).
+* Updated gemspec as requested by Sam Woodard (shwoodard).
+
+## 0.9.8
+* Fixed bug "NameError raised when using Mocha as a Rails plug-in" - http://floehopper.lighthouseapp.com/projects/22289/tickets/53. Since 0.9.6 the Rails plugin has been broken. See bug report for details. You will need to explicitly load Mocha *after* the test framework has been loaded, e.g. by adding "require 'mocha'" at the bottom of test/test_helper.rb.
+* Make Mocha::ParameterMatchers#regexp_matches, #includes, #has_value, #has_key more robust. Thanks to Sander Hartlage.
+* Allow passing a block to Mocha::Configuration methods to only change configuration for the duration of the block. Thanks to Dan Manges.
+* Fixed bug "doc generation fails in 0.9.7 gem" - http://floehopper.lighthouseapp.com/projects/22289/tickets/51.
+* Remove rdoc template incorporating google analytics from source control. The file just needs to exist locally and be ignored by source control. This should stop the warning showing up on e.g. RunCodeRun build results.
+
+## 0.9.7
+* Although I had provided a deprecation warning for people using Mocha::Standalone, I had assumed people wouldn't be explicitly loading the mocha/standalone.rb file. It turns out this assumption was incorrect at least in the case of Rspec. This is now fixed.
+
+## 0.9.6
+* Version 2.0.1 of the test-unit gem introduced a private 'run_test' method on TestCase which clashed with the public TestRunner#run_test method. So this latter method has been renamed to 'run_as_test'.
+* Stop requiring rubygems - this should be an environmental choice for the user. http://gist.github.com/54177 - describes why requiring rubygems in your library code is a bad idea.
+* It seems like overkill to vendorize coderay and meta_project when they're only needed to generate the examples for documentation and for publishing files on RubyForge. So I'm removing them and installing them locally as gems when I need them.
+* Added support for 'test-unit' gem (version >= 2.0). Note that as with other versions of Test::Unit I'm completely replacing the TestCase#run method. Unfortunately in version 2.0.0 this method differs slightly from the same method in version 2.0.1 & 2.0.2, so we have to provide different implementations to ensure that the internal working of Test::Unit are not compromised by Mocha. Note also that unless the 'test-unit' gem is loaded, requiring 'test/unit' leads to a mixture of stdlib and gem classes being loaded causing errors. To avoid a dependency on rubygems, the gem is loaded only if MOCHA_OPTIONS is set to 'use_test_unit_gem' - this option is only intended for use in running Mocha's own tests. It might be worthwhile to create a shim gem like minitest_tu_shim to allow the test-unit gem to completely replace the stdlib, but that's a job for another day. The changes in the Rakefile are to make the default task run with the 'test-unit' gem (version >= 2.0).
+* Renamed Mocha::Standalone to Mocha::API to better reflect its purpose. Added a deprecation warning for those who are referencing Mocha::Standalone.
+* Fix exception raised by HasEntry#matches? if first param is not a Hash (thanks to Taylor Barstow).
+* Ken Collins reported [1] that Mocha is always loading MiniTest if it is available and loading it causes some Rails/ActionPack tests to break. I've removed the loading of MiniTest, but this now means the user has to ensure that if they want to use MiniTest in conjunction with Mocha, he must load MiniTest before loading Mocha. [1] http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2060
+* Implemented Bacon integration (thanks to Ubiratan Pires Alberton), but this was then removed after deciding only to maintain integration with Test::Unit and MiniTest which are both Ruby standard libraries. See mailing list for details.
+* Don't monkey-patch MiniTest if it's already been monkey-patched by Mocha.
+* Fixed bug: MiniTest integration was counting ExpectationErrors as errors not failures. http://floehopper.lighthouseapp.com/projects/22289-mocha/tickets/41.
+* Fixed bug: Some Bacon tests were failing in Ruby 1.9.1. http://floehopper.lighthouseapp.com/projects/22289-mocha/tickets/43.
+* Chad Humphries pointed out that in Ruby 1.9.1, if you are not using Test::Unit or MiniTest, Mocha will attempt to load and monkey-patch Test::Unit. Mocha will now only monkey-patch Test::Unit and/or MiniTest if they have already been loaded. MiniTest tests will now run in both Ruby 1.8.6 (with MiniTest gem) and in Ruby 1.9.1 (with MiniTest std lib). See Ligthouse ticket - http://floehopper.lighthouseapp.com/projects/22289/tickets/49.
+* Made Mocha compatible with minitest 1.4.0 and above (thanks to Denis Defreyne).
+
+## 0.9.5
+* Fixed Lighthouse bug #32 - stub_everything should mean mock responds to anything.
+* Added Expectation#twice to improve readability. Thanks to pull request from Celestino Gomes.
+* In Ruby 1.9.1, requiring 'test/unit' loads a thin wrapper around MiniTest and Test::Unit::TestCase ends up inheriting from MiniTest::Unit::TestCase. So we need to avoid including the Mocha modules more than once to avoid nasty consequences. Thanks to Matthias Hennemeyer for help with this.
+* Ruby 1.9 includes rake, but not rake/contrib. For the moment I've moved the sshpublisher require into the only rake task that needs it, so that I can at least run the tests in Ruby 1.9. It looks like I will need to build a rake/contrib gem or similar to get this working properly - http://intertwingly.net/blog/2008/01/07/Rake-Contrib-for-1-9
+
+## 0.9.4
+* Added mocha.gemspec file generated with Chad Woolley's new rake task, so that a floehopper-mocha gem will get built on GitHub.
+* Add rake task to update mocha.gemspec with unique version, which will cause gem to be auto-built on github
+* As Tobias Crawley correctly pointed out in feature request #23055 "stubs(with_hash) not working with existing object" [1], following the principle of least surprise, it should be possible to call ObjectMethods#expects & ObjectMethods#stubs with a Hash of method_names vs return_values like you can with Mock#expects & Mock#stubs. I've also updated & improved the docs to reflect the changes. [1] http://rubyforge.org/tracker/index.php?func=detail&aid=23055&group_id=1917&atid=7480
+* Removed deprecated gem autorequire.
+
+## 0.9.3
+* Added support for MiniTest thanks to Jeff Smick.
+* Fixed a possible bug with some of the non-default Configuration options relating to the argument to Object#respond_to?
+* As per Jay Fields recommendations [1] and with further impetus from a talk at Ruby Manor, any methods added to core classes are now added by including a module. This means that Mocha is a better citizen of the Ruby world and it's behaviour is more easily extended. [1] http://blog.jayfields.com/2008/07/ruby-underuse-of-modules.html & http://blog.jayfields.com/2008/07/ruby-redefine-method-behavior.html
+* Removed deprecated gem autorequire.
+
+## 0.9.2
+* Improved documentation to address [#22530] 'Mock methods with multiple return values not possible?'
+* respond_with parameter matcher was not available in tests.
+* Patch [#22630] Fix for a bug in running Rails tests with Ruby 1.8.7. Array#flatten was being called which in turn was checking whether each element responded to #to_ary. This check was using the two parameter version of #respond_to?, but Mock was only defining a one parameter version.
+
+## 0.9.1
+
+* Fixed bug #21465 - expects & stubs should support method names as strings (as well as symbols) or fail fast. Convert all expectation method names to a symbol in case they were supplied as a string.
+* By removing Mock#unexpected_method_called we reduce the number of methods vulnerable to the problem that surfaced in bug #21563.
+* Fix bug #21563 - stubbing 'verified?' method is unsafe. Instance method names on the Mock class should be more obscure.
+* Performance improvement. StubbaExampleTest goes twice as fast on my local machine.
+* Added primitive performance test to default rake task.
+* Fix format of case statements which don't work in Ruby 1.9 and make others consistent.
+* There is no point in running (potentially expensive) checks if configuration is set to allow such checks to fail. This is a relatively quick fix in response to Chris McGrath's performance problems.
+* Fix for bug #21161 - 'uninitialized constant Deprecation in stubba.rb'.
+* It's more readable to talk about 'once' and 'twice' rather than '1 time' and '2 times'.
+* Fix bug #20883 - never should raise when called to prevent follow up errors. Fail fast when there are no matching invokable expectations and handle the stub_everything case sensibly. This might not be entirely backwards compatible, but I think the benefits outweigh the risks. The most likely change is that a test that was already failing will now fail faster, which doesn't seem so awful.
+
+## 0.9.0
+
+* Configurable warnings or errors
+  * when a method on a non-public method is stubbed
+  * when a method on a non-existent method is stubbed
+  * when a method on a non-mock object is stubbed
+  * when a method is stubbed unnecessarily (i.e. the stubbed method is not called during the test)
+
+* Improved error messages
+  * User-friendly list of unsatisfied expectations, satisfied expectations and state machines.
+  * Improved readability of cardinality description.
+  * Display sensible failure message for any_instance expectations e.g. "#<AnyInstance:Foo>.bar - expected calls: 1, actual calls: 0"
+
+* Parameter matchers
+  * New to this release
+    * optionally (allows matching of optional parameters if available)
+    * yaml_equivalent (allows matching of YAML that represents the specified object)
+    * responds_with (tests the quack not the duck)
+  * Nesting of parameter matchers is now supported.
+
+* Optional block passed into mock initializer is evaluated in the context of the new mock instance and can be used as a shortcut to set up expectations.
+
+* Added JMock-style sequences for constraining the order of expected invocations. See Standalone#sequence and Expectation#in_sequence.
+
+* Added JMock-style states for constraining the order of expected invocations. See Standalone#states, Expectation#then, Expectation#when and StateMachine.
+
+* Compatibility with versions of Ruby
+  * Compatibility with Ruby v1.9. All test errors and warnings fixed.
+  * Nasty fix so that TestCaseAdaptor works consistently with earlier versions of Test::Unit as well as more recent versions.
+  * Added platform to gem specification to avoid bug in rubygems 0.9.5 - see http://www.dcmanges.com/blog/rubygems-0-9-5-platform-bug and http://rubygems.org/read/chapter/20#platform.
+  * Make ExpectationRaiser deal with subclasses of Interrupt which seem to need a message supplied in the raise statement in Ruby 1.8.6 (but not 1.8.4 or 1.9). Not sure this is really Mocha's responsibility.
+
+* Added deprecation warning in stubba.rb which is no longer needed and will be removed.
+
+* Supply positioning information to evals to improve any error messages. See http://ola-bini.blogspot.com/2008/01/ruby-antipattern-using-eval-without.html
+
+* Bug fixes
+  * 18914 in revision 296 - http://rubyforge.org/tracker/index.php?func=detail&aid=18914&group_id=1917&atid=7477
+  * 18917 in revision 295 - http://rubyforge.org/tracker/index.php?func=detail&aid=18917&group_id=1917&atid=7477
+  * 18336 in revision 287 - http://rubyforge.org/tracker/index.php?func=detail&aid=18336&group_id=1917&atid=7477
+  * 17835 in revision 255 - http://rubyforge.org/tracker/index.php?func=detail&aid=17835&group_id=1917&atid=7477
+  * 17412 in revision 242 - http://rubyforge.org/tracker/index.php?func=detail&aid=17412&group_id=1917&atid=7477
+  * 15977 in revision 198 - http://rubyforge.org/tracker/index.php?func=detail&aid=15977&group_id=1917&atid=7477
+  * 11885 in revision 156 - http://rubyforge.org/tracker/index.php?func=detail&aid=11885&group_id=1917&atid=7477
+
+## 0.5.5
+
+- Renamed Matches parameter matcher to RegexpMatches for clarity.
+- Added noframes tag to rdoc index to assist Google.
+
+## 0.5.4
+
+- Added matches parameter matcher for matching regular expressions.
+
+## 0.5.3
+
+- Attempt to fix packaging problems by switching to newer version (1.15.1) of gnutar and setting COPY_EXTENDED_ATTRIBUTES_DISABLE environment variable.
+- Removed unused ExpectationSequenceError exception.
+- Added instance_of and kind_of parameter matchers.
+- Added Google Webmaster meta tag to rdoc template header.
+- Put Google Webmaster meta tag in the right header i.e. the one for the index page.
+
+## 0.5.2
+
+- Fix bug 11885 - "never doesn't work with stub_everything" submitted by Alexander Lang. In fixing this bug, also fixed undiscoverd bug where expected & actual invocation counts were being incorrectly reported which seems to have been introduced when fixes were added for invocation dispatch (see MockedMethodDispatchAcceptanceTest).
+- Previously when an expectation did not allow more invocations, it was treated as not matching. Now we prefer matching expectations which allow more invocations, but still match expectations which cannot allow more invocations. I think this may be overcomplicating things, but let's see how it goes.
+
+## 0.5.1
+
+- Fixed bug #11583 "Mocha 0.5.0 throwing unexpected warnings". Also switched on ruby warning for all rake test tasks. Fixed majority of warnings, but some left to fix.
+
+## 0.5.0
+
+- Parameter Matchers - I’ve added a few Hamcrest-style parameter matchers which are designed to be used inside Expectation#with. The following matchers are currently available: anything(), includes(), has_key(), has_value(), has_entry(), all_of() & any_of(). More to follow soon. The idea is eventually to get rid of the nasty parameter_block option on Expectation#with.
+
+  object = mock()
+  object.expects(:method).with(has_key('key_1'))
+  object.method('key_1' => 1, 'key_2' => 2)
+  # no verification error raised
+
+  object = mock()
+  object.expects(:method).with(has_key('key_1'))
+  object.method('key_2' => 2)
+  # verification error raised, because method was not called with Hash containing key: 'key_1'
+
+- Values Returned and Exceptions Raised on Consecutive Invocations - Allow multiple calls to Expectation#returns and Expectation#raises to build up a sequence of responses to invocations on the mock. Added syntactic sugar method Expectation#then to allow more readable expectations.
+
+  object = mock()
+  object.stubs(:method).returns(1, 2).then.raises(Exception).then.returns(4)
+  object.method # => 1
+  object.method # => 2
+  object.method # => raises exception of class Exception
+  object.method # => 4
+
+- Yields on Consecutive Invocations - Allow multiple calls to yields on single expectation to allow yield parameters to be specified for consecutive invocations.
+
+  object = mock()
+  object.stubs(:method).yields(1, 2).then.yields(3)
+  object.method { |*values| p values } # => [1, 2]
+  object.method { |*values| p values } # => [3]
+
+- Multiple Yields on Single Invocation - Added Expectation#multiple_yields to allow a mocked or stubbed method to yield multiple times for a single invocation.
+
+  object = mock()
+  object.stubs(:method).multiple_yields([1, 2], [3])
+  object.method { |*values| p values } # => [1, 2] # => [3]
+
+- Invocation Dispatch - Expectations were already being matched in reverse order i.e. the most recently defined one was being found first. This is still the case, but we now stop matching an expectation when its maximum number of expected invocations is reached. c.f. JMock v1. A stub will never stop matching by default. Hopefully this means we can soon get rid of the need to pass a Proc to Expectation#returns.
+
+  object = mock()
+  object.stubs(:method).returns(2)
+  object.expects(:method).once.returns(1)
+  object.method # => 1
+  object.method # => 2
+  object.method # => 2
+  # no verification error raised
+
+  # The following should still work...
+
+  Time.stubs(:now).returns(Time.parse('Mon Jan 01 00:00:00 UTC 2007'))
+  Time.now # => Mon Jan 01 00:00:00 UTC 2007
+  Time.stubs(:now).returns(Time.parse('Thu Feb 01 00:00:00 UTC 2007'))
+  Time.now # => Thu Feb 01 00:00:00 UTC 2007
+
+- Deprecate passing an instance of Proc to Expectation#returns.
+- Explicitly include all Rakefile dependencies in project.
+- Fixed old Stubba example.
+- Fix so that it is possible for a stubbed method to raise an Interrupt exception without a message in Ruby 1.8.6
+- Added responds_like and quacks_like.
+- Capture standard object methods before Mocha adds any.
+- Added Expectation#once method to make interface less surprising.
+- Use Rake::TestTask to run tests. Created three separate tasks to run unit, integration & acceptance tests. Split inspect_test into one file per TestCase. Deleted superfluous all_tests file.
+- Fiddled with mocha_inspect and tests to give more sensible results on x86 platform.
+- Fixed bug #7834 "infinite_range.rb makes incorrect assumption about to_f" logged by James Moore.
+
+## 0.4.0
+
+- Allow naming of mocks (patch from Chris Roos).
+- Specify multiple return values for consecutive calls.
+- Improved consistency of expectation error messages.
+- Allow mocking of Object instance methods e.g. kind_of?, type.
+- Provide aliased versions of #expects and #stubs to allow mocking of these methods.
+- Added at_least, at_most, at_most_once methods to expectation.
+- Allow expects and stubs to take a hash of method and return values.
+- Eliminate warning: "instance variable @yield not initialized" (patch from Xavier Shay).
+- Restore instance methods on partial mocks (patch from Chris Roos).
+- Allow stubbing of a method with non-word characters in its name (patch from Paul Battley).
+- Removed coupling to Test::Unit.
+- Allow specified exception instance to be raised (patch from Chris Roos).
+- Make mock object_id appear in hex like normal Ruby inspect (patch from Paul Battley).
+- Fix path to object.rb in rdoc rake task (patch from Tomas Pospisek).
+- Reverse order in which expectations are matched, so that last expectation is matched first. This allows e.g. a call to #stubs to be effectively overridden by a call to #expects (patch from Tobias Lutke).
+- Stubba & SmartTestCase modules incorporated into Mocha module so only need to require 'mocha' - no longer need to require 'stubba'.
+- AutoMocha removed.
+
+## 0.3.3
+
+- Quick bug fix to restore instance methods on partial mocks (for Kevin Clark).
+
+## 0.3.2
+
+- Examples added.
+
+## 0.3.1
+
+- Dual licensing with MIT license added.
+
+## 0.3.0
+
+* Rails plugin.
+* Auto-verify for expectations on concrete classes.
+* Include each expectation verification in the test result assertion count.
+* Filter out noise from assertion backtraces.
+* Point assertion backtrace to line where failing expectation was created.
+* New yields method for expectations.
+* Create stubs which stub all method calls.
+* Mocks now respond_to? expected methods.
+
+## 0.2.1
+
+* Rename MochaAcceptanceTest::Rover#move method to avoid conflict with Rake (in Ruby 1.8.4 only?)
+
+## 0.2.0
+
+* Small change to SetupAndTeardown#teardown_stubs suggested by Luke Redpath (http://www.lukeredpath.co.uk) to allow use of Stubba with RSpec (http://rspec.rubyforge.org).
+* Reorganized directory structure and extracted addition of setup and teardown methods into SmartTestCase mini-library.
+* Addition of auto-verify for Mocha (but not Stubba). This means there is more significance in the choice of expects or stubs in that any expects on a mock will automatically get verified.
+
+So instead of...
+
+  wotsit = Mocha.new
+  wotsit.expects(:thingummy).with(5).returns(10)
+  doobrey = Doobrey.new(wotsit)
+  doobrey.hoojamaflip
+  wotsit.verify
+
+you need to do...
+
+  wotsit = mock()
+  wotsit.expects(:thingummy).with(5).returns(10)
+  doobrey = Doobrey.new(wotsit)
+  doobrey.hoojamaflip
+  # no need to verify
+
+There are also shortcuts as follows...
+
+instead of...
+
+  wotsit = Mocha.new
+  wotsit.expects(:thingummy).returns(10)
+  wotsit.expects(:summat).returns(25)
+
+you can have...
+
+  wotsit = mock(:thingummy => 5, :summat => 25)
+
+and instead of...
+
+  wotsit = Mocha.new
+  wotsit.stubs(:thingummy).returns(10)
+  wotsit.stubs(:summat).returns(25)
+
+you can have...
+
+  wotsit = stub(:thingummy => 5, :summat => 25)
+
+## 0.1.2
+
+* Minor tweaks
+
+## 0.1.1
+
+* Initial release.
diff --git a/app/server/vendor/mocha-1.1.0/Rakefile b/app/server/vendor/mocha-1.1.0/Rakefile
new file mode 100755
index 0000000..ca0124c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/Rakefile
@@ -0,0 +1,139 @@
+require "bundler"
+Bundler::GemHelper.install_tasks
+require "bundler/setup"
+
+require 'rake/testtask'
+
+desc "Run all tests"
+task 'default' => ['test', 'test:performance']
+
+desc "Run tests"
+task 'test' do
+  if test_library = ENV['MOCHA_RUN_INTEGRATION_TESTS']
+    Rake::Task["test:integration:#{test_library}"].invoke
+  else
+    Rake::Task['test:units'].invoke
+    Rake::Task['test:acceptance'].invoke
+  end
+end
+
+namespace 'test' do
+
+  unit_tests = FileList['test/unit/**/*_test.rb']
+  all_acceptance_tests = FileList['test/acceptance/*_test.rb']
+  ruby186_incompatible_acceptance_tests = FileList['test/acceptance/stub_class_method_defined_on_*_test.rb'] + FileList['test/acceptance/stub_instance_method_defined_on_*_test.rb']
+  ruby186_compatible_acceptance_tests = all_acceptance_tests - ruby186_incompatible_acceptance_tests
+
+  desc "Run unit tests"
+  Rake::TestTask.new('units') do |t|
+    t.libs << 'test'
+    t.test_files = unit_tests
+    t.verbose = true
+    t.warning = true
+  end
+
+  desc "Run acceptance tests"
+  Rake::TestTask.new('acceptance') do |t|
+    t.libs << 'test'
+    if defined?(RUBY_VERSION) && (RUBY_VERSION >= "1.8.7")
+      t.test_files = all_acceptance_tests
+    else
+      t.test_files = ruby186_compatible_acceptance_tests
+    end
+    t.verbose = true
+    t.warning = true
+  end
+
+  namespace 'integration' do
+    desc "Run MiniTest integration tests (intended to be run in its own process)"
+    Rake::TestTask.new('minitest') do |t|
+      t.libs << 'test'
+      t.test_files = FileList['test/integration/mini_test_test.rb']
+      t.verbose = true
+      t.warning = true
+    end
+
+    desc "Run Test::Unit integration tests (intended to be run in its own process)"
+    Rake::TestTask.new('test-unit') do |t|
+      t.libs << 'test'
+      t.test_files = FileList['test/integration/test_unit_test.rb']
+      t.verbose = true
+      t.warning = true
+    end
+  end
+
+  # require 'rcov/rcovtask'
+  # Rcov::RcovTask.new('coverage') do |t|
+  #   t.libs << 'test'
+  #   t.test_files = unit_tests + acceptance_tests
+  #   t.verbose = true
+  #   t.warning = true
+  #   t.rcov_opts << '--sort coverage'
+  #   t.rcov_opts << '--xref'
+  # end
+
+  desc "Run performance tests"
+  task 'performance' do
+    require File.join(File.dirname(__FILE__), 'test', 'acceptance', 'stubba_example_test')
+    require File.join(File.dirname(__FILE__), 'test', 'acceptance', 'mocha_example_test')
+    iterations = 1000
+    puts "\nBenchmarking with #{iterations} iterations..."
+    [MochaExampleTest, StubbaExampleTest].each do |test_case|
+      puts "#{test_case}: #{benchmark_test_case(test_case, iterations)} seconds."
+    end
+  end
+
+end
+
+def benchmark_test_case(klass, iterations)
+  require 'benchmark'
+
+  if defined?(MiniTest)
+    MiniTest::Unit.output = StringIO.new
+    Benchmark.realtime { iterations.times { |i| MiniTest::Unit.new.run([klass]) } }
+  else
+    load 'test/unit/ui/console/testrunner.rb' unless defined?(Test::Unit::UI::Console::TestRunner)
+    unless $silent_option
+      begin
+        load 'test/unit/ui/console/outputlevel.rb' unless defined?(Test::Unit::UI::Console::OutputLevel::SILENT)
+        $silent_option = { :output_level => Test::Unit::UI::Console::OutputLevel::SILENT }
+      rescue LoadError
+        $silent_option = Test::Unit::UI::SILENT
+      end
+    end
+    Benchmark.realtime { iterations.times { Test::Unit::UI::Console::TestRunner.run(klass, $silent_option) } }
+  end
+end
+
+unless ENV["MOCHA_NO_DOCS"]
+  require 'yard'
+
+  desc 'Remove generated documentation'
+  task 'clobber_yardoc' do
+    `rm -rf ./doc`
+  end
+
+  task 'docs_environment' do
+    unless ENV['GOOGLE_ANALYTICS_WEB_PROPERTY_ID']
+      puts "\nWarning: GOOGLE_ANALYTICS_WEB_PROPERTY_ID was not defined\n\n"
+    end
+  end
+
+  desc 'Generate documentation'
+  YARD::Rake::YardocTask.new('yardoc' => 'docs_environment') do |task|
+    task.options = ["--title", "Mocha #{Mocha::VERSION}"]
+  end
+
+  desc "Generate documentation"
+  task 'generate_docs' => ['clobber_yardoc', 'yardoc']
+
+  desc "Publish docs to gofreerange.com/docs/mocha"
+  task 'publish_docs' => 'generate_docs' do
+    path = "/home/freerange/docs/mocha"
+    system %{ssh gofreerange.com "sudo rm -fr #{path} && mkdir -p #{path}" && scp -r doc/* gofreerange.com:#{path}}
+  end
+end
+
+task 'release' => 'default' do
+  Rake::Task['publish_docs'].invoke
+end
diff --git a/app/server/vendor/mocha-1.1.0/bin/build-matrix b/app/server/vendor/mocha-1.1.0/bin/build-matrix
new file mode 100755
index 0000000..fbc8d30
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/bin/build-matrix
@@ -0,0 +1,71 @@
+#!/usr/bin/env ruby
+
+require 'yaml'
+
+def execute(*commands)
+  commands.each do |command|
+    system(command)
+    unless $?.success?
+      message = [
+        "Executing shell command failed.",
+        "  Command: #{command}",
+        "  Status:  #{$?.exitstatus}"
+      ].join("\n")
+      raise message
+    end
+  end
+end
+
+def reset_bundle
+  execute(
+    "rm -rf .bundle/gems",
+    "rm -rf gemfiles/.bundle/gems",
+    "rm -f *.lock",
+    "rm -f gemfiles/*.lock"
+  )
+end
+
+def with_rbenv(command)
+  %{export PATH="$HOME/.rbenv/bin:$PATH"; eval "$(rbenv init -)"; #{command}}
+end
+
+def run(ruby_version, gemfile, task = "test")
+  ENV["RBENV_VERSION"] = ruby_version
+  ENV["BUNDLE_GEMFILE"] = gemfile
+  ENV["MOCHA_OPTIONS"] = "debug"
+  ENV["MOCHA_NO_DOCS"] = "true"
+  reset_bundle
+  execute(
+    with_rbenv("bundle install --gemfile=#{gemfile}"),
+    with_rbenv("bundle exec rake #{task}"),
+  )
+end
+
+travis_config = YAML.load(File.read('.travis.yml'))
+build_configs = travis_config['matrix']['include']
+travis_config['rvm'].each do |ruby_version|
+  travis_config['gemfile'].each do |gemfile|
+    travis_config['env'].each do |env|
+      build_configs << { 'rvm' => ruby_version, 'gemfile' => gemfile, 'env' => env }
+    end
+  end
+end
+
+build_configs.each do |config|
+  ruby_version = config['rvm']
+  gemfile = config['gemfile']
+  environment_variables = Hash[*config['env'].split.flat_map { |e| e.split('=') }]
+  original_environment_variables = {}
+  begin
+    environment_variables.each do |k, v|
+      original_environment_variables[k] = ENV[k]
+      ENV[k] = v
+    end
+    p [ruby_version, gemfile, environment_variables]
+    run(ruby_version, gemfile)
+  ensure
+    original_environment_variables.each do |k, v|
+      ENV[k] = v
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.1.3.0 b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.1.3.0
new file mode 100755
index 0000000..e9b7c27
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.1.3.0
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gemspec :path=>"../"
+
+group :development do
+  gem "minitest", "1.3.0"
+end
diff --git a/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.1.4.0 b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.1.4.0
new file mode 100755
index 0000000..1f47507
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.1.4.0
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gemspec :path=>"../"
+
+group :development do
+  gem "minitest", "1.4.0"
+end
diff --git a/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.1.4.1 b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.1.4.1
new file mode 100755
index 0000000..ac583ad
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.1.4.1
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gemspec :path=>"../"
+
+group :development do
+  gem "minitest", "1.4.1"
+end
diff --git a/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.1.4.2 b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.1.4.2
new file mode 100755
index 0000000..44fa8ab
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.1.4.2
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gemspec :path=>"../"
+
+group :development do
+  gem "minitest", "1.4.2"
+end
diff --git a/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.2.0.0 b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.2.0.0
new file mode 100755
index 0000000..d3ac31a
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.2.0.0
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gemspec :path=>"../"
+
+group :development do
+  gem "minitest", "2.0.0"
+end
diff --git a/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.2.0.1 b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.2.0.1
new file mode 100755
index 0000000..ed8a23a
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.2.0.1
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gemspec :path=>"../"
+
+group :development do
+  gem "minitest", "2.0.1"
+end
diff --git a/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.2.11.0 b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.2.11.0
new file mode 100755
index 0000000..bbd32d1
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.2.11.0
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gemspec :path=>"../"
+
+group :development do
+  gem "minitest", "2.11.0"
+end
diff --git a/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.2.11.2 b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.2.11.2
new file mode 100755
index 0000000..19507e5
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.2.11.2
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gemspec :path=>"../"
+
+group :development do
+  gem "minitest", "2.11.2"
+end
diff --git a/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.2.3.0 b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.2.3.0
new file mode 100755
index 0000000..8fd93e8
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.2.3.0
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gemspec :path=>"../"
+
+group :development do
+  gem "minitest", "2.3.0"
+end
diff --git a/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.latest b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.latest
new file mode 100755
index 0000000..399364e
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.minitest.latest
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gemspec :path=>"../"
+
+group :development do
+  gem "minitest"
+end
diff --git a/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.test-unit.2.0.0 b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.test-unit.2.0.0
new file mode 100755
index 0000000..dbab065
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.test-unit.2.0.0
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gemspec :path=>"../"
+
+group :development do
+  gem "test-unit", "2.0.0"
+end
diff --git a/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.test-unit.2.0.1 b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.test-unit.2.0.1
new file mode 100755
index 0000000..5de0203
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.test-unit.2.0.1
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gemspec :path=>"../"
+
+group :development do
+  gem "test-unit", "2.0.1"
+end
diff --git a/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.test-unit.2.0.3 b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.test-unit.2.0.3
new file mode 100755
index 0000000..e75266f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.test-unit.2.0.3
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gemspec :path=>"../"
+
+group :development do
+  gem "test-unit", "2.0.3"
+end
diff --git a/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.test-unit.latest b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.test-unit.latest
new file mode 100755
index 0000000..32b9119
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/gemfiles/Gemfile.test-unit.latest
@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+
+gemspec :path=>"../"
+
+group :development do
+  gem "test-unit"
+end
diff --git a/app/server/vendor/mocha-1.1.0/init.rb b/app/server/vendor/mocha-1.1.0/init.rb
new file mode 100755
index 0000000..b45eea9
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/init.rb
@@ -0,0 +1,3 @@
+# Mocha should no longer be loaded at plugin load time
+# You should explicitly load Mocha *after* Test::Unit or MiniTest have been loaded
+# e.g. by adding "require 'mocha'" at the bottom of test/test_helper.rb
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha.rb b/app/server/vendor/mocha-1.1.0/lib/mocha.rb
new file mode 100755
index 0000000..0b6ab2d
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha.rb
@@ -0,0 +1 @@
+require 'mocha/version'
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/any_instance_method.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/any_instance_method.rb
new file mode 100755
index 0000000..eec1528
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/any_instance_method.rb
@@ -0,0 +1,84 @@
+require 'mocha/class_method'
+
+module Mocha
+
+  class AnyInstanceMethod < ClassMethod
+
+    def mock
+      stubbee.any_instance.mocha
+    end
+
+    def reset_mocha
+      stubbee.any_instance.reset_mocha
+    end
+
+    def hide_original_method
+      if method_exists?(method)
+        begin
+          @original_method = stubbee.instance_method(method)
+          if @original_method && @original_method.owner == stubbee
+            @original_visibility = :public
+            if stubbee.protected_instance_methods.include?(method)
+              @original_visibility = :protected
+            elsif stubbee.private_instance_methods.include?(method)
+              @original_visibility = :private
+            end
+            stubbee.send(:remove_method, method)
+          end
+
+          include_prepended_module if RUBY_VERSION >= '2.0'
+        rescue NameError
+          # deal with nasties like ActiveRecord::Associations::AssociationProxy
+        end
+      end
+    end
+
+    def define_new_method
+      definition_target.class_eval(<<-CODE, __FILE__, __LINE__ + 1)
+        def #{method}(*args, &block)
+          self.class.any_instance.mocha.method_missing(:#{method}, *args, &block)
+        end
+      CODE
+      if @original_visibility
+        Module.instance_method(@original_visibility).bind(definition_target).call(method)
+      end
+    end
+
+    def remove_new_method
+      definition_target.send(:remove_method, method)
+    end
+
+    def restore_original_method
+      if @original_method && @original_method.owner == stubbee
+        stubbee.send(:define_method, method, @original_method)
+        Module.instance_method(@original_visibility).bind(stubbee).call(method)
+      end
+    end
+
+    def method_exists?(method)
+      return true if stubbee.public_instance_methods(false).include?(method)
+      return true if stubbee.protected_instance_methods(false).include?(method)
+      return true if stubbee.private_instance_methods(false).include?(method)
+      return false
+    end
+
+    private
+
+    def include_prepended_module
+      possible_prepended_modules = stubbee.ancestors.take_while do |mod|
+        !(Class === mod)
+      end
+
+      if possible_prepended_modules.any?
+        @definition_target = PrependedModule.new
+        stubbee.__send__ :prepend, @definition_target
+      end
+    end
+
+    def definition_target
+      @definition_target ||= stubbee
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/api.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/api.rb
new file mode 100755
index 0000000..51392df
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/api.rb
@@ -0,0 +1,176 @@
+require 'mocha/parameter_matchers'
+require 'mocha/hooks'
+require 'mocha/mockery'
+require 'mocha/sequence'
+require 'mocha/object_methods'
+require 'mocha/module_methods'
+require 'mocha/class_methods'
+
+module Mocha
+
+  # Methods added to +Test::Unit::TestCase+, +MiniTest::Unit::TestCase+ or equivalent.
+  module API
+
+    include ParameterMatchers
+    include Hooks
+
+    # @private
+    def self.included(mod)
+      Object.send(:include, Mocha::ObjectMethods)
+      Module.send(:include, Mocha::ModuleMethods)
+      Class.send(:include, Mocha::ClassMethods)
+    end
+
+    # Builds a new mock object
+    #
+    # @param [String] name identifies mock object in error messages.
+    # @param [Hash] expected_methods_vs_return_values expected method name symbols as keys and corresponding return values as values - these expectations are setup as if {Mock#expects} were called multiple times.
+    # @yield optional block to be evaluated against the mock object instance, giving an alternative way to setup expectations.
+    # @return [Mock] a new mock object
+    #
+    # @overload def mock(name, &block)
+    # @overload def mock(expected_methods_vs_return_values = {}, &block)
+    # @overload def mock(name, expected_methods_vs_return_values = {}, &block)
+    #
+    # @example Using expected_methods_vs_return_values Hash to setup expectations.
+    #   def test_motor_starts_and_stops
+    #     motor = mock('motor', :start => true, :stop => true)
+    #     assert motor.start
+    #     assert motor.stop
+    #     # an error will be raised unless both Motor#start and Motor#stop have been called
+    #   end
+    # @example Using the optional block to setup expectations & stubbed methods.
+    #   def test_motor_starts_and_stops
+    #     motor = mock('motor') do
+    #       expects(:start).with(100.rpm).returns(true)
+    #       stubs(:stop).returns(true)
+    #     end
+    #     assert motor.start(100.rpm)
+    #     assert motor.stop
+    #     # an error will only be raised if Motor#start(100.rpm) has not been called
+    #   end
+    def mock(*arguments, &block)
+      name = arguments.shift if arguments.first.is_a?(String)
+      expectations = arguments.shift || {}
+      mock = name ? Mockery.instance.named_mock(name, &block) : Mockery.instance.unnamed_mock(&block)
+      mock.expects(expectations)
+      mock
+    end
+
+    # Builds a new mock object
+    #
+    # @param [String] name identifies mock object in error messages.
+    # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {Mock#stubs} were called multiple times.
+    # @yield optional block to be evaluated against the mock object instance, giving an alternative way to setup stubbed methods.
+    # @return [Mock] a new mock object
+    #
+    # @overload def stub(name, &block)
+    # @overload def stub(stubbed_methods_vs_return_values = {}, &block)
+    # @overload def stub(name, stubbed_methods_vs_return_values = {}, &block)
+    #
+    # @example Using stubbed_methods_vs_return_values Hash to setup stubbed methods.
+    #   def test_motor_starts_and_stops
+    #     motor = mock('motor', :start => true, :stop => true)
+    #     assert motor.start
+    #     assert motor.stop
+    #     # an error will not be raised even if either Motor#start or Motor#stop has not been called
+    #   end
+    #
+    # @example Using the optional block to setup expectations & stubbed methods.
+    #   def test_motor_starts_and_stops
+    #     motor = mock('motor') do
+    #       expects(:start).with(100.rpm).returns(true)
+    #       stubs(:stop).returns(true)
+    #     end
+    #     assert motor.start(100.rpm)
+    #     assert motor.stop
+    #     # an error will only be raised if Motor#start(100.rpm) has not been called
+    #   end
+    def stub(*arguments, &block)
+      name = arguments.shift if arguments.first.is_a?(String)
+      expectations = arguments.shift || {}
+      stub = name ? Mockery.instance.named_mock(name, &block) : Mockery.instance.unnamed_mock(&block)
+      stub.stubs(expectations)
+      stub
+    end
+
+    # Builds a mock object that accepts calls to any method. By default it will return +nil+ for any method call.
+    #
+    # @param [String] name identifies mock object in error messages.
+    # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {Mock#stubs} were called multiple times.
+    # @yield optional block to be evaluated against the mock object instance, giving an alternative way to setup stubbed methods.
+    # @return [Mock] a new mock object
+    #
+    # @overload def stub_everything(name, &block)
+    # @overload def stub_everything(stubbed_methods_vs_return_values = {}, &block)
+    # @overload def stub_everything(name, stubbed_methods_vs_return_values = {}, &block)
+    #
+    # @example Ignore invocations of irrelevant methods.
+    #   def test_motor_stops
+    #     motor = stub_everything('motor', :stop => true)
+    #     assert_nil motor.irrelevant_method_1 # => no error raised
+    #     assert_nil motor.irrelevant_method_2 # => no error raised
+    #     assert motor.stop
+    #   end
+    def stub_everything(*arguments, &block)
+      name = arguments.shift if arguments.first.is_a?(String)
+      expectations = arguments.shift || {}
+      stub = name ? Mockery.instance.named_mock(name, &block) : Mockery.instance.unnamed_mock(&block)
+      stub.stub_everything
+      stub.stubs(expectations)
+      stub
+    end
+
+    # Builds a new sequence which can be used to constrain the order in which expectations can occur.
+    #
+    # Specify that an expected invocation must occur within a named {Sequence} by using {Expectation#in_sequence}.
+    #
+    # @return [Sequence] a new sequence
+    #
+    # @see Expectation#in_sequence
+    #
+    # @example Ensure methods on egg are invoked in correct order.
+    #   breakfast = sequence('breakfast')
+    #
+    #   egg = mock('egg') do
+    #     expects(:crack).in_sequence(breakfast)
+    #     expects(:fry).in_sequence(breakfast)
+    #     expects(:eat).in_sequence(breakfast)
+    #   end
+    def sequence(name)
+      Sequence.new(name)
+    end
+
+    # Builds a new state machine which can be used to constrain the order in which expectations can occur.
+    #
+    # Specify the initial state of the state machine by using {StateMachine#starts_as}.
+    #
+    # Specify that an expected invocation should change the state of the state machine by using {Expectation#then}.
+    #
+    # Specify that an expected invocation should be constrained to occur within a particular +state+ by using {Expectation#when}.
+    #
+    # A test can contain multiple state machines.
+    #
+    # @return [StateMachine] a new state machine
+    #
+    # @see Expectation#then
+    # @see Expectation#when
+    # @see StateMachine
+    # @example Constrain expected invocations to occur in particular states.
+    #   power = states('power').starts_as('off')
+    #
+    #   radio = mock('radio') do
+    #     expects(:switch_on).then(power.is('on'))
+    #     expects(:select_channel).with('BBC Radio 4').when(power.is('on'))
+    #     expects(:adjust_volume).with(+5).when(power.is('on'))
+    #     expects(:select_channel).with('BBC World Service').when(power.is('on'))
+    #     expects(:adjust_volume).with(-5).when(power.is('on'))
+    #     expects(:switch_off).then(power.is('off'))
+    #   end
+    def states(name)
+      Mockery.instance.new_state_machine(name)
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/argument_iterator.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/argument_iterator.rb
new file mode 100755
index 0000000..2a9fa74
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/argument_iterator.rb
@@ -0,0 +1,21 @@
+module Mocha
+
+  class ArgumentIterator
+
+    def initialize(argument)
+      @argument = argument
+    end
+
+    def each(&block)
+      if @argument.is_a?(Hash) then
+        @argument.each do |method_name, return_value|
+          block.call(method_name, return_value)
+        end
+      else
+        block.call(@argument)
+      end
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/backtrace_filter.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/backtrace_filter.rb
new file mode 100755
index 0000000..8d22df6
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/backtrace_filter.rb
@@ -0,0 +1,17 @@
+module Mocha
+
+  class BacktraceFilter
+
+    LIB_DIRECTORY = File.expand_path(File.join(File.dirname(__FILE__), "..")) + File::SEPARATOR
+
+    def initialize(lib_directory = LIB_DIRECTORY)
+      @path_pattern = Regexp.new(lib_directory)
+    end
+
+    def filtered(backtrace)
+      backtrace.reject { |location| @path_pattern.match(File.expand_path(location)) }
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/cardinality.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/cardinality.rb
new file mode 100755
index 0000000..52ee7de
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/cardinality.rb
@@ -0,0 +1,95 @@
+module Mocha
+
+  class Cardinality
+
+    INFINITY = 1 / 0.0
+
+    class << self
+
+      def exactly(count)
+        new(count, count)
+      end
+
+      def at_least(count)
+        new(count, INFINITY)
+      end
+
+      def at_most(count)
+        new(0, count)
+      end
+
+      def times(range_or_count)
+        case range_or_count
+          when Range then new(range_or_count.first, range_or_count.last)
+          else new(range_or_count, range_or_count)
+        end
+      end
+
+    end
+
+    def initialize(required, maximum)
+      @required, @maximum = required, maximum
+    end
+
+    def invocations_allowed?(invocation_count)
+      invocation_count < maximum
+    end
+
+    def satisfied?(invocations_so_far)
+      invocations_so_far >= required
+    end
+
+    def needs_verifying?
+      !allowed_any_number_of_times?
+    end
+
+    def verified?(invocation_count)
+      (invocation_count >= required) && (invocation_count <= maximum)
+    end
+
+    def allowed_any_number_of_times?
+      required == 0 && infinite?(maximum)
+    end
+
+    def used?(invocation_count)
+      (invocation_count > 0) || (maximum == 0)
+    end
+
+    def mocha_inspect
+      if allowed_any_number_of_times?
+        "allowed any number of times"
+      else
+        if required == 0 && maximum == 0
+          "expected never"
+        elsif required == maximum
+          "expected exactly #{times(required)}"
+        elsif infinite?(maximum)
+          "expected at least #{times(required)}"
+        elsif required == 0
+          "expected at most #{times(maximum)}"
+        else
+          "expected between #{required} and #{times(maximum)}"
+        end
+      end
+    end
+
+    protected
+
+    attr_reader :required, :maximum
+
+    def times(number)
+      case number
+        when 0 then "no times"
+        when 1 then "once"
+        when 2 then "twice"
+        else "#{number} times"
+      end
+    end
+
+    def infinite?(number)
+      number.respond_to?(:infinite?) && number.infinite?
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/central.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/central.rb
new file mode 100755
index 0000000..927069b
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/central.rb
@@ -0,0 +1,33 @@
+module Mocha
+
+  class Central
+
+    attr_accessor :stubba_methods
+
+    def initialize
+      self.stubba_methods = []
+    end
+
+    def stub(method)
+      unless stubba_methods.detect { |m| m.matches?(method) }
+        method.stub
+        stubba_methods.push(method)
+      end
+    end
+
+    def unstub(method)
+      if existing = stubba_methods.detect { |m| m.matches?(method) }
+        existing.unstub
+        stubba_methods.delete(existing)
+      end
+    end
+
+    def unstub_all
+      while stubba_methods.any? do
+        unstub(stubba_methods.first)
+      end
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/change_state_side_effect.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/change_state_side_effect.rb
new file mode 100755
index 0000000..79f2115
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/change_state_side_effect.rb
@@ -0,0 +1,19 @@
+module Mocha
+
+  class ChangeStateSideEffect
+
+    def initialize(state)
+      @state = state
+    end
+
+    def perform
+      @state.activate
+    end
+
+    def mocha_inspect
+      "then #{@state.mocha_inspect}"
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/class_method.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/class_method.rb
new file mode 100755
index 0000000..b2d7fdf
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/class_method.rb
@@ -0,0 +1,127 @@
+require 'metaclass'
+
+module Mocha
+
+  class ClassMethod
+
+    PrependedModule = Class.new(Module)
+
+    attr_reader :stubbee, :method
+
+    def initialize(stubbee, method)
+      @stubbee = stubbee
+      @original_method, @original_visibility = nil, nil
+      @method = RUBY_VERSION < '1.9' ? method.to_s : method.to_sym
+    end
+
+    def stub
+      hide_original_method
+      define_new_method
+    end
+
+    def unstub
+      remove_new_method
+      restore_original_method
+      mock.unstub(method.to_sym)
+      unless mock.any_expectations?
+        reset_mocha
+      end
+    end
+
+    def mock
+      stubbee.mocha
+    end
+
+    def reset_mocha
+      stubbee.reset_mocha
+    end
+
+    def hide_original_method
+      if method_exists?(method)
+        begin
+          @original_method = stubbee._method(method)
+          @original_visibility = :public
+          if stubbee.__metaclass__.protected_instance_methods.include?(method)
+            @original_visibility = :protected
+          elsif stubbee.__metaclass__.private_instance_methods.include?(method)
+            @original_visibility = :private
+          end
+          if @original_method && @original_method.owner == stubbee.__metaclass__
+            stubbee.__metaclass__.send(:remove_method, method)
+          end
+
+          include_prepended_module if RUBY_VERSION >= '2.0'
+        rescue NameError
+          # deal with nasties like ActiveRecord::Associations::AssociationProxy
+        end
+      end
+    end
+
+    def define_new_method
+      definition_target.class_eval(<<-CODE, __FILE__, __LINE__ + 1)
+        def #{method}(*args, &block)
+          mocha.method_missing(:#{method}, *args, &block)
+        end
+      CODE
+      if @original_visibility
+        Module.instance_method(@original_visibility).bind(definition_target).call(method)
+      end
+    end
+
+    def remove_new_method
+      definition_target.send(:remove_method, method)
+    end
+
+    def restore_original_method
+      if @original_method && @original_method.owner == stubbee.__metaclass__
+        if RUBY_VERSION < '1.9'
+          original_method = @original_method
+          stubbee.__metaclass__.send(:define_method, method) do |*args, &block|
+            original_method.call(*args, &block)
+          end
+        else
+          stubbee.__metaclass__.send(:define_method, method, @original_method)
+        end
+      end
+      if @original_visibility
+        Module.instance_method(@original_visibility).bind(stubbee.__metaclass__).call(method)
+      end
+    end
+
+    def matches?(other)
+      return false unless (other.class == self.class)
+      (stubbee.object_id == other.stubbee.object_id) and (method == other.method)
+    end
+
+    alias_method :==, :eql?
+
+    def to_s
+      "#{stubbee}.#{method}"
+    end
+
+    def method_exists?(method)
+      symbol = method.to_sym
+      __metaclass__ = stubbee.__metaclass__
+      __metaclass__.public_method_defined?(symbol) || __metaclass__.protected_method_defined?(symbol) || __metaclass__.private_method_defined?(symbol)
+    end
+
+    private
+
+    def include_prepended_module
+      possible_prepended_modules = stubbee.__metaclass__.ancestors.take_while do |mod|
+        !(Class === mod)
+      end
+
+      if possible_prepended_modules.any?
+        @definition_target = PrependedModule.new
+        stubbee.__metaclass__.__send__ :prepend, @definition_target
+      end
+    end
+
+    def definition_target
+      @definition_target ||= stubbee.__metaclass__
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/class_methods.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/class_methods.rb
new file mode 100755
index 0000000..3bb10e4
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/class_methods.rb
@@ -0,0 +1,63 @@
+require 'mocha/mockery'
+require 'mocha/class_method'
+require 'mocha/any_instance_method'
+
+module Mocha
+
+  # Methods added to all classes to allow mocking and stubbing on real (i.e. non-mock) objects.
+  module ClassMethods
+
+    # @private
+    def stubba_method
+      Mocha::ClassMethod
+    end
+
+    # @private
+    class AnyInstance
+
+      def initialize(klass)
+        @stubba_object = klass
+      end
+
+      def mocha
+        @mocha ||= Mocha::Mockery.instance.mock_impersonating_any_instance_of(@stubba_object)
+      end
+
+      def stubba_method
+        Mocha::AnyInstanceMethod
+      end
+
+      def stubba_object
+        @stubba_object
+      end
+
+      def method_exists?(method, include_public_methods = true)
+        if include_public_methods
+          return true if @stubba_object.public_instance_methods(include_superclass_methods = true).include?(method)
+        end
+        return true if @stubba_object.protected_instance_methods(include_superclass_methods = true).include?(method)
+        return true if @stubba_object.private_instance_methods(include_superclass_methods = true).include?(method)
+        return false
+      end
+
+    end
+
+    # @return [Mock] a mock object which will detect calls to any instance of this class.
+    # @raise [StubbingError] if attempting to stub method which is not allowed.
+    #
+    # @example Return false to invocation of +Product#save+ for any instance of +Product+.
+    #   Product.any_instance.stubs(:save).returns(false)
+    #   product_1 = Product.new
+    #   assert_equal false, product_1.save
+    #   product_2 = Product.new
+    #   assert_equal false, product_2.save
+    def any_instance
+      if frozen?
+        raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}.any_instance", caller)
+      end
+      @any_instance ||= AnyInstance.new(self)
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/configuration.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/configuration.rb
new file mode 100755
index 0000000..d1ccbdb
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/configuration.rb
@@ -0,0 +1,89 @@
+module Mocha
+
+  # Configuration settings.
+  class Configuration
+
+    DEFAULTS = {
+      :stubbing_method_unnecessarily => :allow,
+      :stubbing_method_on_non_mock_object => :allow,
+      :stubbing_non_existent_method => :allow,
+      :stubbing_non_public_method => :allow,
+      :stubbing_method_on_nil => :prevent,
+    }
+
+    class << self
+
+      # Allow the specified +action+.
+      #
+      # @param [Symbol] action one of +:stubbing_method_unnecessarily+, +:stubbing_method_on_non_mock_object+, +:stubbing_non_existent_method+, +:stubbing_non_public_method+, +:stubbing_method_on_nil+.
+      # @yield optional block during which the configuration change will be changed before being returned to its original value at the end of the block.
+      def allow(action, &block)
+        change_config action, :allow, &block
+      end
+
+      # @private
+      def allow?(action)
+        configuration[action] == :allow
+      end
+
+      # Warn if the specified +action+ is attempted.
+      #
+      # @param [Symbol] action one of +:stubbing_method_unnecessarily+, +:stubbing_method_on_non_mock_object+, +:stubbing_non_existent_method+, +:stubbing_non_public_method+, +:stubbing_method_on_nil+.
+      # @yield optional block during which the configuration change will be changed before being returned to its original value at the end of the block.
+      def warn_when(action, &block)
+        change_config action, :warn, &block
+      end
+
+      # @private
+      def warn_when?(action)
+        configuration[action] == :warn
+      end
+
+      # Raise a {StubbingError} if if the specified +action+ is attempted.
+      #
+      # @param [Symbol] action one of +:stubbing_method_unnecessarily+, +:stubbing_method_on_non_mock_object+, +:stubbing_non_existent_method+, +:stubbing_non_public_method+, +:stubbing_method_on_nil+.
+      # @yield optional block during which the configuration change will be changed before being returned to its original value at the end of the block.
+      def prevent(action, &block)
+        change_config action, :prevent, &block
+      end
+
+      # @private
+      def prevent?(action)
+        configuration[action] == :prevent
+      end
+
+      # @private
+      def reset_configuration
+        @configuration = nil
+      end
+
+      private
+
+      # @private
+      def configuration
+        @configuration ||= DEFAULTS.dup
+      end
+
+      # @private
+      def change_config(action, new_value, &block)
+        if block_given?
+          temporarily_change_config action, new_value, &block
+        else
+          configuration[action] = new_value
+        end
+      end
+
+      # @private
+      def temporarily_change_config(action, new_value, &block)
+        original_value = configuration[action]
+        configuration[action] = new_value
+        yield
+      ensure
+        configuration[action] = original_value
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/debug.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/debug.rb
new file mode 100755
index 0000000..535be93
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/debug.rb
@@ -0,0 +1,11 @@
+module Mocha
+  module Debug
+    OPTIONS = (ENV['MOCHA_OPTIONS'] || '').split(',').inject({}) do |hash, key|
+      hash[key] = true; hash
+    end.freeze
+
+    def self.puts(message)
+      $stderr.puts(message) if OPTIONS['debug']
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/deprecation.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/deprecation.rb
new file mode 100755
index 0000000..57ffa6e
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/deprecation.rb
@@ -0,0 +1,24 @@
+require 'mocha/debug'
+
+module Mocha
+
+  class Deprecation
+
+    class << self
+
+      attr_accessor :mode, :messages
+
+      def warning(message)
+        @messages << message
+        $stderr.puts "\n*** Mocha deprecation warning: #{message}\n\n" unless mode == :disabled
+        $stderr.puts caller.join("\n  ") if mode == :debug
+      end
+
+    end
+
+    self.mode = Debug::OPTIONS['debug'] ? :debug : :enabled
+    self.messages = []
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/detection/mini_test.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/detection/mini_test.rb
new file mode 100755
index 0000000..edd1947
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/detection/mini_test.rb
@@ -0,0 +1,25 @@
+module Mocha
+  module Detection
+    module MiniTest
+      def self.testcase
+        if defined?(::Minitest::Test)
+          ::Minitest::Test
+        elsif defined?(::MiniTest::Unit::TestCase)
+          ::MiniTest::Unit::TestCase
+        else
+          nil
+        end
+      end
+
+      def self.version
+        if defined?(::MiniTest::Unit::VERSION)
+          ::MiniTest::Unit::VERSION
+        elsif defined?(::Minitest::VERSION)
+          ::Minitest::VERSION
+        else
+          '0.0.0'
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/detection/test_unit.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/detection/test_unit.rb
new file mode 100755
index 0000000..a75a87c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/detection/test_unit.rb
@@ -0,0 +1,29 @@
+module Mocha
+  module Detection
+    module TestUnit
+      def self.testcase
+        if defined?(::Test::Unit::TestCase) &&
+          !(defined?(::MiniTest::Unit::TestCase) && (::Test::Unit::TestCase < ::MiniTest::Unit::TestCase)) &&
+          !(defined?(::MiniTest::Spec) && (::Test::Unit::TestCase < ::MiniTest::Spec))
+          ::Test::Unit::TestCase
+        else
+          nil
+        end
+      end
+
+      def self.version
+        version = '1.0.0'
+        if testcase
+          begin
+            require 'test/unit/version'
+          rescue LoadError
+          end
+          if defined?(::Test::Unit::VERSION)
+            version = ::Test::Unit::VERSION
+          end
+        end
+        version
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/exception_raiser.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/exception_raiser.rb
new file mode 100755
index 0000000..d6708a2
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/exception_raiser.rb
@@ -0,0 +1,17 @@
+module Mocha
+
+  class ExceptionRaiser
+
+    def initialize(exception, message)
+      @exception, @message = exception, message
+    end
+
+    def evaluate
+      raise @exception, @exception.to_s if @exception.is_a?(Module) && (@exception < Interrupt)
+      raise @exception, @message if @message
+      raise @exception
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/expectation.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/expectation.rb
new file mode 100755
index 0000000..d0ed1b2
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/expectation.rb
@@ -0,0 +1,612 @@
+require 'mocha/method_matcher'
+require 'mocha/parameters_matcher'
+require 'mocha/expectation_error'
+require 'mocha/return_values'
+require 'mocha/exception_raiser'
+require 'mocha/thrower'
+require 'mocha/yield_parameters'
+require 'mocha/is_a'
+require 'mocha/in_state_ordering_constraint'
+require 'mocha/change_state_side_effect'
+require 'mocha/cardinality'
+
+module Mocha
+
+  # Methods on expectations returned from {Mock#expects}, {Mock#stubs}, {ObjectMethods#expects} and {ObjectMethods#stubs}.
+  class Expectation
+
+    # Modifies expectation so that the number of calls to the expected method must be within a specific +range+.
+    #
+    # @param [Range,Integer] range specifies the allowable range in the number of expected invocations.
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    #
+    # @example Specifying a specific number of expected invocations.
+    #   object = mock()
+    #   object.expects(:expected_method).times(3)
+    #   3.times { object.expected_method }
+    #   # => verify succeeds
+    #
+    #   object = mock()
+    #   object.expects(:expected_method).times(3)
+    #   2.times { object.expected_method }
+    #   # => verify fails
+    #
+    # @example Specifying a range in the number of expected invocations.
+    #   object = mock()
+    #   object.expects(:expected_method).times(2..4)
+    #   3.times { object.expected_method }
+    #   # => verify succeeds
+    #
+    #   object = mock()
+    #   object.expects(:expected_method).times(2..4)
+    #   object.expected_method
+    #   # => verify fails
+    def times(range)
+      @cardinality = Cardinality.times(range)
+      self
+    end
+
+    # Modifies expectation so that the expected method must be called exactly twice.
+    #
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    #
+    # @example Expected method must be invoked exactly twice.
+    #   object = mock()
+    #   object.expects(:expected_method).twice
+    #   object.expected_method
+    #   object.expected_method
+    #   # => verify succeeds
+    #
+    #   object = mock()
+    #   object.expects(:expected_method).twice
+    #   object.expected_method
+    #   object.expected_method
+    #   object.expected_method # => unexpected invocation
+    #
+    #   object = mock()
+    #   object.expects(:expected_method).twice
+    #   object.expected_method
+    #   # => verify fails
+    def twice
+      @cardinality = Cardinality.exactly(2)
+      self
+    end
+
+    # Modifies expectation so that the expected method must be called exactly once.
+    #
+    # Note that this is the default behaviour for an expectation, but you may wish to use it for clarity/emphasis.
+    #
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    #
+    # @example Expected method must be invoked exactly once.
+    #   object = mock()
+    #   object.expects(:expected_method).once
+    #   object.expected_method
+    #   # => verify succeeds
+    #
+    #   object = mock()
+    #   object.expects(:expected_method).once
+    #   object.expected_method
+    #   object.expected_method # => unexpected invocation
+    #
+    #   object = mock()
+    #   object.expects(:expected_method).once
+    #   # => verify fails
+    def once
+      @cardinality = Cardinality.exactly(1)
+      self
+    end
+
+    # Modifies expectation so that the expected method must never be called.
+    #
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    #
+    # @example Expected method must never be called.
+    #   object = mock()
+    #   object.expects(:expected_method).never
+    #   object.expected_method # => unexpected invocation
+    #
+    #   object = mock()
+    #   object.expects(:expected_method).never
+    #   # => verify succeeds
+    def never
+      @cardinality = Cardinality.exactly(0)
+      self
+    end
+
+    # Modifies expectation so that the expected method must be called at least a +minimum_number_of_times+.
+    #
+    # @param [Integer] minimum_number_of_times minimum number of expected invocations.
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    #
+    # @example Expected method must be called at least twice.
+    #   object = mock()
+    #   object.expects(:expected_method).at_least(2)
+    #   3.times { object.expected_method }
+    #   # => verify succeeds
+    #
+    #   object = mock()
+    #   object.expects(:expected_method).at_least(2)
+    #   object.expected_method
+    #   # => verify fails
+    def at_least(minimum_number_of_times)
+      @cardinality = Cardinality.at_least(minimum_number_of_times)
+      self
+    end
+
+    # Modifies expectation so that the expected method must be called at least once.
+    #
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    #
+    # @example Expected method must be called at least once.
+    #   object = mock()
+    #   object.expects(:expected_method).at_least_once
+    #   object.expected_method
+    #   # => verify succeeds
+    #
+    #   object = mock()
+    #   object.expects(:expected_method).at_least_once
+    #   # => verify fails
+    def at_least_once
+      at_least(1)
+      self
+    end
+
+    # Modifies expectation so that the expected method must be called at most a +maximum_number_of_times+.
+    #
+    # @param [Integer] maximum_number_of_times maximum number of expected invocations.
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    #
+    # @example Expected method must be called at most twice.
+    #   object = mock()
+    #   object.expects(:expected_method).at_most(2)
+    #   2.times { object.expected_method }
+    #   # => verify succeeds
+    #
+    #   object = mock()
+    #   object.expects(:expected_method).at_most(2)
+    #   3.times { object.expected_method } # => unexpected invocation
+    def at_most(maximum_number_of_times)
+      @cardinality = Cardinality.at_most(maximum_number_of_times)
+      self
+    end
+
+    # Modifies expectation so that the expected method must be called at most once.
+    #
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    #
+    # @example Expected method must be called at most once.
+    #   object = mock()
+    #   object.expects(:expected_method).at_most_once
+    #   object.expected_method
+    #   # => verify succeeds
+    #
+    #   object = mock()
+    #   object.expects(:expected_method).at_most_once
+    #   2.times { object.expected_method } # => unexpected invocation
+    def at_most_once()
+      at_most(1)
+      self
+    end
+
+    # Modifies expectation so that the expected method must be called with +expected_parameters+.
+    #
+    # May be used with parameter matchers in {ParameterMatchers}.
+    #
+    # @param [*Array] expected_parameters parameters expected.
+    # @yield optional block specifying custom matching.
+    # @yieldparam [*Array] actual_parameters parameters with which expected method was invoked.
+    # @yieldreturn [Boolean] +true+ if +actual_parameters+ are acceptable.
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    #
+    # @example Expected method must be called with expected parameters.
+    #   object = mock()
+    #   object.expects(:expected_method).with(:param1, :param2)
+    #   object.expected_method(:param1, :param2)
+    #   # => verify succeeds
+    #
+    #   object = mock()
+    #   object.expects(:expected_method).with(:param1, :param2)
+    #   object.expected_method(:param3)
+    #   # => verify fails
+    #
+    # @example Expected method must be called with a value divisible by 4.
+    #   object = mock()
+    #   object.expects(:expected_method).with() { |value| value % 4 == 0 }
+    #   object.expected_method(16)
+    #   # => verify succeeds
+    #
+    #   object = mock()
+    #   object.expects(:expected_method).with() { |value| value % 4 == 0 }
+    #   object.expected_method(17)
+    #   # => verify fails
+    def with(*expected_parameters, &matching_block)
+      @parameters_matcher = ParametersMatcher.new(expected_parameters, &matching_block)
+      self
+    end
+
+    # Modifies expectation so that when the expected method is called, it yields with the specified +parameters+.
+    #
+    # May be called multiple times on the same expectation for consecutive invocations.
+    #
+    # @param [*Array] parameters parameters to be yielded.
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    # @see #then
+    #
+    # @example Yield parameters when expected method is invoked.
+    #   object = mock()
+    #   object.expects(:expected_method).yields('result')
+    #   yielded_value = nil
+    #   object.expected_method { |value| yielded_value = value }
+    #   yielded_value # => 'result'
+    #
+    # @example Yield different parameters on different invocations of the expected method.
+    #   object = mock()
+    #   object.stubs(:expected_method).yields(1).then.yields(2)
+    #   yielded_values_from_first_invocation = []
+    #   yielded_values_from_second_invocation = []
+    #   object.expected_method { |value| yielded_values_from_first_invocation << value } # first invocation
+    #   object.expected_method { |value| yielded_values_from_second_invocation << value } # second invocation
+    #   yielded_values_from_first_invocation # => [1]
+    #   yielded_values_from_second_invocation # => [2]
+    def yields(*parameters)
+      @yield_parameters.add(*parameters)
+      self
+    end
+
+    # Modifies expectation so that when the expected method is called, it yields multiple times per invocation with the specified +parameter_groups+.
+    #
+    # @param [*Array<Array>] parameter_groups each element of +parameter_groups+ should iself be an +Array+ representing the parameters to be passed to the block for a single yield.
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    # @see #then
+    #
+    # @example When the +expected_method+ is called, the stub will invoke the block twice, the first time it passes +'result_1'+, +'result_2'+ as the parameters, and the second time it passes 'result_3' as the parameters.
+    #   object = mock()
+    #   object.expects(:expected_method).multiple_yields(['result_1', 'result_2'], ['result_3'])
+    #   yielded_values = []
+    #   object.expected_method { |*values| yielded_values << values }
+    #   yielded_values # => [['result_1', 'result_2'], ['result_3]]
+    #
+    # @example Yield different groups of parameters on different invocations of the expected method.
+    #   object = mock()
+    #   object.stubs(:expected_method).multiple_yields([1, 2], [3]).then.multiple_yields([4], [5, 6])
+    #   yielded_values_from_first_invocation = []
+    #   yielded_values_from_second_invocation = []
+    #   object.expected_method { |*values| yielded_values_from_first_invocation << values } # first invocation
+    #   object.expected_method { |*values| yielded_values_from_second_invocation << values } # second invocation
+    #   yielded_values_from_first_invocation # => [[1, 2], [3]]
+    #   yielded_values_from_second_invocation # => [[4], [5, 6]]
+    def multiple_yields(*parameter_groups)
+      @yield_parameters.multiple_add(*parameter_groups)
+      self
+    end
+
+    # Modifies expectation so that when the expected method is called, it returns the specified +value+.
+    #
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    # @see #then
+    #
+    # @overload def returns(value)
+    #   @param [Object] value value to return on invocation of expected method.
+    # @overload def returns(*values)
+    #   @param [*Array] values values to return on consecutive invocations of expected method.
+    #
+    # @example Return the same value on every invocation.
+    #   object = mock()
+    #   object.stubs(:stubbed_method).returns('result')
+    #   object.stubbed_method # => 'result'
+    #   object.stubbed_method # => 'result'
+    #
+    # @example Return a different value on consecutive invocations.
+    #   object = mock()
+    #   object.stubs(:stubbed_method).returns(1, 2)
+    #   object.stubbed_method # => 1
+    #   object.stubbed_method # => 2
+    #
+    # @example Alternative way to return a different value on consecutive invocations.
+    #   object = mock()
+    #   object.stubs(:expected_method).returns(1, 2).then.returns(3)
+    #   object.expected_method # => 1
+    #   object.expected_method # => 2
+    #   object.expected_method # => 3
+    #
+    # @example May be called in conjunction with {#raises} on the same expectation.
+    #   object = mock()
+    #   object.stubs(:expected_method).returns(1, 2).then.raises(Exception)
+    #   object.expected_method # => 1
+    #   object.expected_method # => 2
+    #   object.expected_method # => raises exception of class Exception1
+    #
+    # @example Note that in Ruby a method returning multiple values is exactly equivalent to a method returning an +Array+ of those values.
+    #   object = mock()
+    #   object.stubs(:expected_method).returns([1, 2])
+    #   x, y = object.expected_method
+    #   x # => 1
+    #   y # => 2
+    def returns(*values)
+      @return_values += ReturnValues.build(*values)
+      self
+    end
+
+    # Modifies expectation so that when the expected method is called, it raises the specified +exception+ with the specified +message+ i.e. calls +Kernel#raise(exception, message)+.
+    #
+    # @param [Class,Exception,String,#exception] exception exception to be raised or message to be passed to RuntimeError.
+    # @param [String] message exception message.
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    #
+    # @see Kernel#raise
+    # @see #then
+    #
+    # @overload def raises
+    # @overload def raises(exception)
+    # @overload def raises(exception, message)
+    #
+    # @example Raise specified exception if expected method is invoked.
+    #   object = stub()
+    #   object.stubs(:expected_method).raises(Exception, 'message')
+    #   object.expected_method # => raises exception of class Exception and with message 'message'
+    #
+    # @example Raise custom exception with extra constructor parameters by passing in an instance of the exception.
+    #   object = stub()
+    #   object.stubs(:expected_method).raises(MyException.new('message', 1, 2, 3))
+    #   object.expected_method # => raises the specified instance of MyException
+    #
+    # @example Raise different exceptions on consecutive invocations of the expected method.
+    #   object = stub()
+    #   object.stubs(:expected_method).raises(Exception1).then.raises(Exception2)
+    #   object.expected_method # => raises exception of class Exception1
+    #   object.expected_method # => raises exception of class Exception2
+    #
+    # @example Raise an exception on first invocation of expected method and then return values on subsequent invocations.
+    #   object = stub()
+    #   object.stubs(:expected_method).raises(Exception).then.returns(2, 3)
+    #   object.expected_method # => raises exception of class Exception1
+    #   object.expected_method # => 2
+    #   object.expected_method # => 3
+    def raises(exception = RuntimeError, message = nil)
+      @return_values += ReturnValues.new(ExceptionRaiser.new(exception, message))
+      self
+    end
+
+    # Modifies expectation so that when the expected method is called, it throws the specified +tag+ with the specific return value +object+ i.e. calls +Kernel#throw(tag, object)+.
+    #
+    # @param [Symbol,String] tag tag to throw to transfer control to the active catch block.
+    # @param [Object] object return value for the catch block.
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    #
+    # @see Kernel#throw
+    # @see #then
+    #
+    # @overload def throw(tag)
+    # @overload def throw(tag, object)
+    #
+    # @example Throw tag when expected method is invoked.
+    #   object = stub()
+    #   object.stubs(:expected_method).throws(:done)
+    #   object.expected_method # => throws tag :done
+    #
+    # @example Throw tag with return value +object+ c.f. +Kernel#throw+.
+    #   object = stub()
+    #   object.stubs(:expected_method).throws(:done, 'result')
+    #   object.expected_method # => throws tag :done and causes catch block to return 'result'
+    #
+    # @example Throw different tags on consecutive invocations of the expected method.
+    #   object = stub()
+    #   object.stubs(:expected_method).throws(:done).then.throws(:continue)
+    #   object.expected_method # => throws :done
+    #   object.expected_method # => throws :continue
+    #
+    # @example Throw tag on first invocation of expected method and then return values for subsequent invocations.
+    #   object = stub()
+    #   object.stubs(:expected_method).throws(:done).then.returns(2, 3)
+    #   object.expected_method # => throws :done
+    #   object.expected_method # => 2
+    #   object.expected_method # => 3
+    def throws(tag, object = nil)
+      @return_values += ReturnValues.new(Thrower.new(tag, object))
+      self
+    end
+
+    # @overload def then
+    #   Used as syntactic sugar to improve readability. It has no effect on state of the expectation.
+    # @overload def then(state_machine.is(state_name))
+    #   Used to change the +state_machine+ to the state specified by +state_name+ when the expected invocation occurs.
+    #   @param [StateMachine::State] state_machine.is(state_name) provides a mechanism to change the +state_machine+ into the state specified by +state_name+ when the expected method is invoked.
+    #
+    #   @see API#states
+    #   @see StateMachine
+    #   @see #when
+    #
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    #
+    # @example Using {#then} as syntactic sugar when specifying values to be returned and exceptions to be raised on consecutive invocations of the expected method.
+    #   object = mock()
+    #   object.stubs(:expected_method).returns(1, 2).then.raises(Exception).then.returns(4)
+    #   object.expected_method # => 1
+    #   object.expected_method # => 2
+    #   object.expected_method # => raises exception of class Exception
+    #   object.expected_method # => 4
+    #
+    # @example Using {#then} to change the +state+ of a +state_machine+ on the invocation of an expected method.
+    #   power = states('power').starts_as('off')
+    #
+    #   radio = mock('radio')
+    #   radio.expects(:switch_on).then(power.is('on'))
+    #   radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on'))
+    #   radio.expects(:adjust_volume).with(+5).when(power.is('on'))
+    #   radio.expects(:select_channel).with('BBC World Service').when(power.is('on'))
+    #   radio.expects(:adjust_volume).with(-5).when(power.is('on'))
+    #   radio.expects(:switch_off).then(power.is('off'))
+    def then(*parameters)
+      if parameters.length == 1
+        state = parameters.first
+        add_side_effect(ChangeStateSideEffect.new(state))
+      end
+      self
+    end
+
+    # Constrains the expectation to occur only when the +state_machine+ is in the state specified by +state_name+.
+    #
+    # @param [StateMachine::StatePredicate] state_machine.is(state_name) provides a mechanism to determine whether the +state_machine+ is in the state specified by +state_name+ when the expected method is invoked.
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    #
+    # @see API#states
+    # @see StateMachine
+    # @see #then
+    #
+    # @example Using {#when} to only allow invocation of methods when "power" state machine is in the "on" state.
+    #   power = states('power').starts_as('off')
+    #
+    #   radio = mock('radio')
+    #   radio.expects(:switch_on).then(power.is('on'))
+    #   radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on'))
+    #   radio.expects(:adjust_volume).with(+5).when(power.is('on'))
+    #   radio.expects(:select_channel).with('BBC World Service').when(power.is('on'))
+    #   radio.expects(:adjust_volume).with(-5).when(power.is('on'))
+    #   radio.expects(:switch_off).then(power.is('off'))
+    def when(state_predicate)
+      add_ordering_constraint(InStateOrderingConstraint.new(state_predicate))
+      self
+    end
+
+    # Constrains the expectation so that it must be invoked at the current point in the +sequence+.
+    #
+    # To expect a sequence of invocations, write the expectations in order and add the +in_sequence(sequence)+ clause to each one.
+    #
+    # Expectations in a +sequence+ can have any invocation count.
+    #
+    # If an expectation in a sequence is stubbed, rather than expected, it can be skipped in the +sequence+.
+    #
+    # An expected method can appear in multiple sequences.
+    #
+    # @param [*Array<Sequence>] sequences sequences in which expected method should appear.
+    # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
+    #
+    # @see API#sequence
+    #
+    # @example Ensure methods are invoked in a specified order.
+    #   breakfast = sequence('breakfast')
+    #
+    #   egg = mock('egg')
+    #   egg.expects(:crack).in_sequence(breakfast)
+    #   egg.expects(:fry).in_sequence(breakfast)
+    #   egg.expects(:eat).in_sequence(breakfast)
+    def in_sequence(*sequences)
+      sequences.each { |sequence| add_in_sequence_ordering_constraint(sequence) }
+      self
+    end
+
+    # @private
+    attr_reader :backtrace
+
+    # @private
+    def initialize(mock, expected_method_name, backtrace = nil)
+      @mock = mock
+      @method_matcher = MethodMatcher.new(expected_method_name.to_sym)
+      @parameters_matcher = ParametersMatcher.new
+      @ordering_constraints = []
+      @side_effects = []
+      @cardinality, @invocation_count = Cardinality.exactly(1), 0
+      @return_values = ReturnValues.new
+      @yield_parameters = YieldParameters.new
+      @backtrace = backtrace || caller
+    end
+
+    # @private
+    def add_ordering_constraint(ordering_constraint)
+      @ordering_constraints << ordering_constraint
+    end
+
+    # @private
+    def add_in_sequence_ordering_constraint(sequence)
+      sequence.constrain_as_next_in_sequence(self)
+    end
+
+    # @private
+    def add_side_effect(side_effect)
+      @side_effects << side_effect
+    end
+
+    # @private
+    def perform_side_effects
+      @side_effects.each { |side_effect| side_effect.perform }
+    end
+
+    # @private
+    def in_correct_order?
+      @ordering_constraints.all? { |ordering_constraint| ordering_constraint.allows_invocation_now? }
+    end
+
+    # @private
+    def matches_method?(method_name)
+      @method_matcher.match?(method_name)
+    end
+
+    # @private
+    def match?(actual_method_name, *actual_parameters)
+      @method_matcher.match?(actual_method_name) && @parameters_matcher.match?(actual_parameters) && in_correct_order?
+    end
+
+    # @private
+    def invocations_allowed?
+      @cardinality.invocations_allowed?(@invocation_count)
+    end
+
+    # @private
+    def satisfied?
+      @cardinality.satisfied?(@invocation_count)
+    end
+
+    # @private
+    def invoke
+      @invocation_count += 1
+      perform_side_effects()
+      if block_given? then
+        @yield_parameters.next_invocation.each do |yield_parameters|
+          yield(*yield_parameters)
+        end
+      end
+      @return_values.next
+    end
+
+    # @private
+    def verified?(assertion_counter = nil)
+      assertion_counter.increment if assertion_counter && @cardinality.needs_verifying?
+      @cardinality.verified?(@invocation_count)
+    end
+
+    # @private
+    def used?
+      @cardinality.used?(@invocation_count)
+    end
+
+    # @private
+    def inspect
+      address = __id__ * 2
+      address += 0x100000000 if address < 0
+      "#<Expectation:0x#{'%x' % address} #{mocha_inspect} >"
+    end
+
+    # @private
+    def mocha_inspect
+      message = "#{@cardinality.mocha_inspect}, "
+      message << case @invocation_count
+        when 0 then "not yet invoked"
+        when 1 then "invoked once"
+        when 2 then "invoked twice"
+        else "invoked #{@invocation_count} times"
+      end
+      message << ": "
+      message << method_signature
+      message << "; #{@ordering_constraints.map { |oc| oc.mocha_inspect }.join("; ")}" unless @ordering_constraints.empty?
+      message
+    end
+
+    # @private
+    def method_signature
+      "#{@mock.mocha_inspect}.#{@method_matcher.mocha_inspect}#{@parameters_matcher.mocha_inspect}"
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/expectation_error.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/expectation_error.rb
new file mode 100755
index 0000000..29a3d4b
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/expectation_error.rb
@@ -0,0 +1,8 @@
+module Mocha
+  # Default exception class raised when an unexpected invocation or an unsatisfied expectation occurs.
+  #
+  # Authors of test libraries may use +Mocha::ExpectationErrorFactory+ to have Mocha raise a different exception.
+  #
+  # @see Mocha::ExpectationErrorFactory
+  class ExpectationError < Exception; end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/expectation_error_factory.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/expectation_error_factory.rb
new file mode 100755
index 0000000..507d02e
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/expectation_error_factory.rb
@@ -0,0 +1,36 @@
+require 'mocha/backtrace_filter'
+require 'mocha/expectation_error'
+
+module Mocha
+
+  # This factory determines what class of exception should be raised when Mocha detects a test failure.
+  #
+  # This class should only be used by authors of test libraries and not by typical "users" of Mocha.
+  #
+  # For example, it is used by +Mocha::Integration::MiniTest::Adapter+ in order to have Mocha raise a +MiniTest::Assertion+ which can then be sensibly handled by +MiniTest::Unit::TestCase+.
+  #
+  # @see Mocha::Integration::MiniTest::Adapter
+  class ExpectationErrorFactory
+    class << self
+      # @!attribute exception_class
+      #   Determines what class of exception should be raised when Mocha detects a test failure.
+      #
+      #   This attribute may be set by authors of test libraries in order to have Mocha raise exceptions of a specific class when there is an unexpected invocation or an unsatisfied expectation.
+      #
+      #   By default a +Mocha::ExpectationError+ will be raised.
+      #
+      #   @return [Exception] class of exception to be raised when an expectation error occurs
+      #   @see Mocha::ExpectationError
+      attr_accessor :exception_class
+
+      # @private
+      def build(message = nil, backtrace = [])
+        exception = exception_class.new(message)
+        filter = BacktraceFilter.new
+        exception.set_backtrace(filter.filtered(backtrace))
+        exception
+      end
+    end
+    self.exception_class = ExpectationError
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/expectation_list.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/expectation_list.rb
new file mode 100755
index 0000000..99d1d1e
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/expectation_list.rb
@@ -0,0 +1,62 @@
+module Mocha
+
+  class ExpectationList
+
+    def initialize(expectations = [])
+      @expectations = expectations
+    end
+
+    def add(expectation)
+      @expectations.unshift(expectation)
+      expectation
+    end
+
+    def remove_all_matching_method(method_name)
+      @expectations.reject! { |expectation| expectation.matches_method?(method_name) }
+    end
+
+    def matches_method?(method_name)
+      @expectations.any? { |expectation| expectation.matches_method?(method_name) }
+    end
+
+    def match(method_name, *arguments)
+      matching_expectations(method_name, *arguments).first
+    end
+
+    def match_allowing_invocation(method_name, *arguments)
+      matching_expectations(method_name, *arguments).detect { |e| e.invocations_allowed? }
+    end
+
+    def verified?(assertion_counter = nil)
+      @expectations.all? { |expectation| expectation.verified?(assertion_counter) }
+    end
+
+    def to_a
+      @expectations
+    end
+
+    def to_set
+      @expectations.to_set
+    end
+
+    def length
+      @expectations.length
+    end
+
+    def any?
+      @expectations.any?
+    end
+
+    def +(other)
+      self.class.new(self.to_a + other.to_a)
+    end
+
+    private
+
+    def matching_expectations(method_name, *arguments)
+      @expectations.select { |e| e.match?(method_name, *arguments) }
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/hooks.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/hooks.rb
new file mode 100755
index 0000000..f5a1407
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/hooks.rb
@@ -0,0 +1,44 @@
+require 'mocha/mockery'
+
+module Mocha
+
+  # Integration hooks for test library authors.
+  #
+  # The methods in this module should be called from test libraries wishing to integrate with Mocha.
+  #
+  # This module is provided as part of the +Mocha::API+ module and is therefore part of the public API, but should only be used by authors of test libraries and not by typical "users" of Mocha.
+  #
+  # Integration with Test::Unit and MiniTest are provided as part of Mocha, because they are (or were once) part of the Ruby standard library. Integration with other test libraries is not provided as *part* of Mocha, but is supported by means of the methods in this module.
+  #
+  # See the code in the +Adapter+ modules for examples of how to use the methods in this module. +Mocha::ExpectationErrorFactory+ may be used if you want +Mocha+ to raise a different type of exception.
+  #
+  # @see Mocha::Integration::TestUnit::Adapter
+  # @see Mocha::Integration::MiniTest::Adapter
+  # @see Mocha::ExpectationErrorFactory
+  # @see Mocha::API
+  module Hooks
+    # Prepares Mocha before a test (only for use by authors of test libraries).
+    #
+    # This method should be called before each individual test starts (including before any "setup" code).
+    def mocha_setup
+    end
+
+    # Verifies that all mock expectations have been met (only for use by authors of test libraries).
+    #
+    # This is equivalent to a series of "assertions".
+    #
+    # This method should be called at the end of each individual test, before it has been determined whether or not the test has passed.
+    def mocha_verify(assertion_counter = nil)
+      Mockery.verify(assertion_counter)
+    end
+
+    # Resets Mocha after a test (only for use by authors of test libraries).
+    #
+    # This method should be called after each individual test has finished (including after any "teardown" code).
+    def mocha_teardown
+      Mockery.teardown
+    ensure
+      Mockery.reset_instance
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/in_state_ordering_constraint.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/in_state_ordering_constraint.rb
new file mode 100755
index 0000000..25b2de1
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/in_state_ordering_constraint.rb
@@ -0,0 +1,19 @@
+module Mocha
+
+  class InStateOrderingConstraint
+
+    def initialize(state_predicate)
+      @state_predicate = state_predicate
+    end
+
+    def allows_invocation_now?
+      @state_predicate.active?
+    end
+
+    def mocha_inspect
+      "when #{@state_predicate.mocha_inspect}"
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/inspect.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/inspect.rb
new file mode 100755
index 0000000..4d50a1f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/inspect.rb
@@ -0,0 +1,67 @@
+require 'date'
+
+module Mocha
+
+  module ObjectMethods
+    def mocha_inspect
+      address = self.__id__ * 2
+      address += 0x100000000 if address < 0
+      inspect =~ /#</ ? "#<#{self.class}:0x#{'%x' % address}>" : inspect
+    end
+  end
+
+  module StringMethods
+    def mocha_inspect
+      inspect.gsub(/\"/, "'")
+    end
+  end
+
+  module ArrayMethods
+    def mocha_inspect
+      "[#{collect { |member| member.mocha_inspect }.join(', ')}]"
+    end
+  end
+
+  module HashMethods
+    def mocha_inspect
+      "{#{collect { |key, value| "#{key.mocha_inspect} => #{value.mocha_inspect}" }.join(', ')}}"
+    end
+  end
+
+  module TimeMethods
+    def mocha_inspect
+      "#{inspect} (#{to_f} secs)"
+    end
+  end
+
+  module DateMethods
+    def mocha_inspect
+      to_s
+    end
+  end
+
+end
+
+class Object
+  include Mocha::ObjectMethods
+end
+
+class String
+  include Mocha::StringMethods
+end
+
+class Array
+  include Mocha::ArrayMethods
+end
+
+class Hash
+  include Mocha::HashMethods
+end
+
+class Time
+  include Mocha::TimeMethods
+end
+
+class Date
+  include Mocha::DateMethods
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/instance_method.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/instance_method.rb
new file mode 100755
index 0000000..4b3555f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/instance_method.rb
@@ -0,0 +1,16 @@
+require 'mocha/class_method'
+
+module Mocha
+
+  class InstanceMethod < ClassMethod
+
+    def method_exists?(method)
+      return true if stubbee.public_methods(false).include?(method)
+      return true if stubbee.protected_methods(false).include?(method)
+      return true if stubbee.private_methods(false).include?(method)
+      return false
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration.rb
new file mode 100755
index 0000000..57b3f38
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration.rb
@@ -0,0 +1,14 @@
+require 'mocha/deprecation'
+require 'mocha/integration/test_unit'
+require 'mocha/integration/mini_test'
+
+module Mocha
+  module Integration
+    def self.activate
+      if [Integration::TestUnit, Integration::MiniTest].map(&:activate).none?
+        Deprecation.warning("Test::Unit or MiniTest must be loaded *before* `require 'mocha/setup'`.")
+        Deprecation.warning("If you're integrating with a test library other than Test::Unit or MiniTest, you should use `require 'mocha/api'` instead of `require 'mocha/setup'`.")
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/assertion_counter.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/assertion_counter.rb
new file mode 100755
index 0000000..1284513
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/assertion_counter.rb
@@ -0,0 +1,13 @@
+module Mocha
+  module Integration
+    class AssertionCounter
+      def initialize(test_case)
+        @test_case = test_case
+      end
+
+      def increment
+        @test_case.assert(true)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test.rb
new file mode 100755
index 0000000..357e7be
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test.rb
@@ -0,0 +1,49 @@
+require 'mocha/debug'
+
+require 'mocha/detection/mini_test'
+
+require 'mocha/integration/mini_test/nothing'
+require 'mocha/integration/mini_test/version_13'
+require 'mocha/integration/mini_test/version_140'
+require 'mocha/integration/mini_test/version_141'
+require 'mocha/integration/mini_test/version_142_to_172'
+require 'mocha/integration/mini_test/version_200'
+require 'mocha/integration/mini_test/version_201_to_222'
+require 'mocha/integration/mini_test/version_230_to_2101'
+require 'mocha/integration/mini_test/version_2110_to_2111'
+require 'mocha/integration/mini_test/version_2112_to_320'
+require 'mocha/integration/mini_test/adapter'
+
+module Mocha
+  module Integration
+    module MiniTest
+      def self.activate
+        return false unless Detection::MiniTest.testcase
+        mini_test_version = Gem::Version.new(Detection::MiniTest.version)
+
+        Debug.puts "Detected MiniTest version: #{mini_test_version}"
+
+        integration_module = [
+          MiniTest::Adapter,
+          MiniTest::Version2112To320,
+          MiniTest::Version2110To2111,
+          MiniTest::Version230To2101,
+          MiniTest::Version201To222,
+          MiniTest::Version200,
+          MiniTest::Version142To172,
+          MiniTest::Version141,
+          MiniTest::Version140,
+          MiniTest::Version13,
+          MiniTest::Nothing
+        ].detect { |m| m.applicable_to?(mini_test_version) }
+
+        target = Detection::MiniTest.testcase
+        unless target < integration_module
+          Debug.puts "Applying #{integration_module.description}"
+          target.send(:include, integration_module)
+        end
+        true
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/adapter.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/adapter.rb
new file mode 100755
index 0000000..25af703
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/adapter.rb
@@ -0,0 +1,54 @@
+require 'mocha/api'
+require 'mocha/integration/assertion_counter'
+require 'mocha/expectation_error_factory'
+
+module Mocha
+  module Integration
+    module MiniTest
+
+      # Integrates Mocha into recent versions of MiniTest.
+      #
+      # See the source code for an example of how to integrate Mocha into a test library.
+      module Adapter
+        include Mocha::API
+
+        # @private
+        def self.applicable_to?(mini_test_version)
+          Gem::Requirement.new('>= 3.3.0').satisfied_by?(mini_test_version)
+        end
+
+        # @private
+        def self.description
+          "adapter for MiniTest gem >= v3.3.0"
+        end
+
+        # @private
+        def self.included(mod)
+          Mocha::ExpectationErrorFactory.exception_class = ::MiniTest::Assertion
+        end
+
+        # @private
+        def before_setup
+          mocha_setup
+          super
+        end
+
+        # @private
+        def before_teardown
+          return unless passed?
+          assertion_counter = Integration::AssertionCounter.new(self)
+          mocha_verify(assertion_counter)
+        ensure
+          super
+        end
+
+        # @private
+        def after_teardown
+          super
+          mocha_teardown
+        end
+      end
+    end
+  end
+end
+
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/exception_translation.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/exception_translation.rb
new file mode 100755
index 0000000..d620aac
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/exception_translation.rb
@@ -0,0 +1,14 @@
+require 'mocha/expectation_error'
+
+module Mocha
+  module Integration
+    module MiniTest
+      def self.translate(exception)
+        return exception unless exception.kind_of?(::Mocha::ExpectationError)
+        translated_exception = ::MiniTest::Assertion.new(exception.message)
+        translated_exception.set_backtrace(exception.backtrace)
+        translated_exception
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/nothing.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/nothing.rb
new file mode 100755
index 0000000..2988e07
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/nothing.rb
@@ -0,0 +1,19 @@
+module Mocha
+  module Integration
+    module MiniTest
+      module Nothing
+        def self.applicable_to?(test_unit_version, ruby_version = nil)
+          true
+        end
+
+        def self.description
+          "nothing (no MiniTest integration available)"
+        end
+
+        def self.included(mod)
+          raise "No MiniTest integration available"
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_13.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_13.rb
new file mode 100755
index 0000000..61238af
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_13.rb
@@ -0,0 +1,51 @@
+require 'mocha/integration/assertion_counter'
+require 'mocha/integration/monkey_patcher'
+require 'mocha/integration/mini_test/exception_translation'
+
+module Mocha
+  module Integration
+    module MiniTest
+      module Version13
+        def self.applicable_to?(mini_test_version)
+          Gem::Requirement.new('>= 1.3.0', '<= 1.3.1').satisfied_by?(mini_test_version)
+        end
+
+        def self.description
+          "monkey patch for MiniTest gem v1.3"
+        end
+
+        def self.included(mod)
+          MonkeyPatcher.apply(mod, RunMethodPatch)
+        end
+
+        module RunMethodPatch
+          def run runner
+            assertion_counter = AssertionCounter.new(self)
+            result = '.'
+            begin
+              begin
+                @passed = nil
+                self.setup
+                self.__send__ self.name
+                mocha_verify(assertion_counter)
+                @passed = true
+              rescue Exception => e
+                @passed = false
+                result = runner.puke(self.class, self.name, Mocha::Integration::MiniTest.translate(e))
+              ensure
+                begin
+                  self.teardown
+                rescue Exception => e
+                  result = runner.puke(self.class, self.name, Mocha::Integration::MiniTest.translate(e))
+                end
+              end
+            ensure
+              mocha_teardown
+            end
+            result
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_140.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_140.rb
new file mode 100755
index 0000000..fb043ce
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_140.rb
@@ -0,0 +1,51 @@
+require 'mocha/integration/assertion_counter'
+require 'mocha/integration/monkey_patcher'
+require 'mocha/integration/mini_test/exception_translation'
+
+module Mocha
+  module Integration
+    module MiniTest
+      module Version140
+        def self.applicable_to?(mini_test_version)
+          Gem::Requirement.new('1.4.0').satisfied_by?(mini_test_version)
+        end
+
+        def self.description
+          "monkey patch for MiniTest gem v1.4.0"
+        end
+
+        def self.included(mod)
+          MonkeyPatcher.apply(mod, RunMethodPatch)
+        end
+
+        module RunMethodPatch
+          def run runner
+            assertion_counter = AssertionCounter.new(self)
+            result = '.'
+            begin
+              begin
+                @passed = nil
+                self.setup
+                self.__send__ self.__name__
+                mocha_verify(assertion_counter)
+                @passed = true
+              rescue Exception => e
+                @passed = false
+                result = runner.puke(self.class, self.__name__, Mocha::Integration::MiniTest.translate(e))
+              ensure
+                begin
+                  self.teardown
+                rescue Exception => e
+                  result = runner.puke(self.class, self.__name__, Mocha::Integration::MiniTest.translate(e))
+                end
+              end
+            ensure
+              mocha_teardown
+            end
+            result
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_141.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_141.rb
new file mode 100755
index 0000000..2742170
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_141.rb
@@ -0,0 +1,62 @@
+require 'mocha/integration/assertion_counter'
+require 'mocha/integration/monkey_patcher'
+require 'mocha/integration/mini_test/exception_translation'
+
+module Mocha
+  module Integration
+    module MiniTest
+      module Version141
+        def self.applicable_to?(mini_test_version)
+          Gem::Requirement.new('1.4.1').satisfied_by?(mini_test_version)
+        end
+
+        def self.description
+          "monkey patch for MiniTest gem v1.4.1"
+        end
+
+        def self.included(mod)
+          MonkeyPatcher.apply(mod, RunMethodPatch)
+        end
+
+        module RunMethodPatch
+          def run runner
+            trap 'INFO' do
+              warn '%s#%s %.2fs' % [self.class, self.__name__,
+                (Time.now - runner.start_time)]
+              runner.status $stderr
+            end
+
+            assertion_counter = AssertionCounter.new(self)
+            result = '.'
+            begin
+              begin
+                @passed = nil
+                self.setup
+                self.__send__ self.__name__
+                mocha_verify(assertion_counter)
+                @passed = true
+              rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
+                raise
+              rescue Exception => e
+                @passed = false
+                result = runner.puke(self.class, self.__name__, Mocha::Integration::MiniTest.translate(e))
+              ensure
+                begin
+                  self.teardown
+                rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
+                  raise
+                rescue Exception => e
+                  result = runner.puke(self.class, self.__name__, Mocha::Integration::MiniTest.translate(e))
+                end
+                trap 'INFO', 'DEFAULT'
+              end
+            ensure
+              mocha_teardown
+            end
+            result
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_142_to_172.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_142_to_172.rb
new file mode 100755
index 0000000..cda5249
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_142_to_172.rb
@@ -0,0 +1,62 @@
+require 'mocha/integration/assertion_counter'
+require 'mocha/integration/monkey_patcher'
+require 'mocha/integration/mini_test/exception_translation'
+
+module Mocha
+  module Integration
+    module MiniTest
+      module Version142To172
+        def self.applicable_to?(mini_test_version)
+          Gem::Requirement.new('>= 1.4.2', '<= 1.7.2').satisfied_by?(mini_test_version)
+        end
+
+        def self.description
+          "monkey patch for MiniTest gem >= v1.4.2 and <= v1.7.2"
+        end
+
+        def self.included(mod)
+          MonkeyPatcher.apply(mod, RunMethodPatch)
+        end
+
+        module RunMethodPatch
+          def run runner
+            trap 'INFO' do
+              warn '%s#%s %.2fs' % [self.class, self.__name__,
+                (Time.now - runner.start_time)]
+              runner.status $stderr
+            end if ::MiniTest::Unit::TestCase::SUPPORTS_INFO_SIGNAL
+
+            assertion_counter = AssertionCounter.new(self)
+            result = '.'
+            begin
+              begin
+                @passed = nil
+                self.setup
+                self.__send__ self.__name__
+                mocha_verify(assertion_counter)
+                @passed = true
+              rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
+                raise
+              rescue Exception => e
+                @passed = false
+                result = runner.puke(self.class, self.__name__, Mocha::Integration::MiniTest.translate(e))
+              ensure
+                begin
+                  self.teardown
+                rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
+                  raise
+                rescue Exception => e
+                  result = runner.puke(self.class, self.__name__, Mocha::Integration::MiniTest.translate(e))
+                end
+                trap 'INFO', 'DEFAULT' if ::MiniTest::Unit::TestCase::SUPPORTS_INFO_SIGNAL
+              end
+            ensure
+              mocha_teardown
+            end
+            result
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_200.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_200.rb
new file mode 100755
index 0000000..ebba55c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_200.rb
@@ -0,0 +1,63 @@
+require 'mocha/integration/assertion_counter'
+require 'mocha/integration/monkey_patcher'
+require 'mocha/integration/mini_test/exception_translation'
+
+module Mocha
+  module Integration
+    module MiniTest
+      module Version200
+        def self.applicable_to?(mini_test_version)
+          Gem::Requirement.new('2.0.0').satisfied_by?(mini_test_version)
+        end
+
+        def self.description
+          "monkey patch for MiniTest gem v2.0.0"
+        end
+
+        def self.included(mod)
+          MonkeyPatcher.apply(mod, RunMethodPatch)
+        end
+
+        module RunMethodPatch
+          def run runner
+            trap 'INFO' do
+              time = Time.now - runner.start_time
+              warn "%s#%s %.2fs" % [self.class, self.__name__, time]
+              runner.status $stderr
+            end if ::MiniTest::Unit::TestCase::SUPPORTS_INFO_SIGNAL
+
+            assertion_counter = AssertionCounter.new(self)
+            result = ""
+            begin
+              begin
+                @passed = nil
+                self.setup
+                self.__send__ self.__name__
+                mocha_verify(assertion_counter)
+                result = "." unless io?
+                @passed = true
+              rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
+                raise
+              rescue Exception => e
+                @passed = false
+                result = runner.puke self.class, self.__name__, Mocha::Integration::MiniTest.translate(e)
+              ensure
+                begin
+                  self.teardown
+                rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
+                  raise
+                rescue Exception => e
+                  result = runner.puke self.class, self.__name__, Mocha::Integration::MiniTest.translate(e)
+                end
+                trap 'INFO', 'DEFAULT' if ::MiniTest::Unit::TestCase::SUPPORTS_INFO_SIGNAL
+              end
+            ensure
+              mocha_teardown
+            end
+            result
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_201_to_222.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_201_to_222.rb
new file mode 100755
index 0000000..fa882b2
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_201_to_222.rb
@@ -0,0 +1,63 @@
+require 'mocha/integration/assertion_counter'
+require 'mocha/integration/monkey_patcher'
+require 'mocha/integration/mini_test/exception_translation'
+
+module Mocha
+  module Integration
+    module MiniTest
+      module Version201To222
+        def self.applicable_to?(mini_test_version)
+          Gem::Requirement.new('>= 2.0.1', '<= 2.2.2').satisfied_by?(mini_test_version)
+        end
+
+        def self.description
+          "monkey patch for MiniTest gem >= v2.0.1 <= v2.2.2"
+        end
+
+        def self.included(mod)
+          MonkeyPatcher.apply(mod, RunMethodPatch)
+        end
+
+        module RunMethodPatch
+          def run runner
+            trap 'INFO' do
+              time = runner.start_time ? Time.now - runner.start_time : 0
+              warn "%s#%s %.2fs" % [self.class, self.__name__, time]
+              runner.status $stderr
+            end if ::MiniTest::Unit::TestCase::SUPPORTS_INFO_SIGNAL
+
+            assertion_counter = AssertionCounter.new(self)
+            result = ""
+            begin
+              begin
+                @passed = nil
+                self.setup
+                self.__send__ self.__name__
+                mocha_verify(assertion_counter)
+                result = "." unless io?
+                @passed = true
+              rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
+                raise
+              rescue Exception => e
+                @passed = false
+                result = runner.puke self.class, self.__name__, Mocha::Integration::MiniTest.translate(e)
+              ensure
+                begin
+                  self.teardown
+                rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
+                  raise
+                rescue Exception => e
+                  result = runner.puke self.class, self.__name__, Mocha::Integration::MiniTest.translate(e)
+                end
+                trap 'INFO', 'DEFAULT' if ::MiniTest::Unit::TestCase::SUPPORTS_INFO_SIGNAL
+              end
+            ensure
+              mocha_teardown
+            end
+            result
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_2110_to_2111.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_2110_to_2111.rb
new file mode 100755
index 0000000..2983478
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_2110_to_2111.rb
@@ -0,0 +1,67 @@
+require 'mocha/integration/assertion_counter'
+require 'mocha/integration/monkey_patcher'
+require 'mocha/integration/mini_test/exception_translation'
+
+module Mocha
+  module Integration
+    module MiniTest
+      module Version2110To2111
+        def self.applicable_to?(mini_test_version)
+          Gem::Requirement.new('>= 2.11.0', '<= 2.11.1').satisfied_by?(mini_test_version)
+        end
+
+        def self.description
+          "monkey patch for MiniTest gem >= v2.11.0 <= v2.11.1"
+        end
+
+        def self.included(mod)
+          MonkeyPatcher.apply(mod, RunMethodPatch)
+        end
+
+        module RunMethodPatch
+          def run runner
+            trap 'INFO' do
+              time = runner.start_time ? Time.now - runner.start_time : 0
+              warn "%s#%s %.2fs" % [self.class, self.__name__, time]
+              runner.status $stderr
+            end if ::MiniTest::Unit::TestCase::SUPPORTS_INFO_SIGNAL
+
+            assertion_counter = AssertionCounter.new(self)
+            result = ""
+            begin
+              begin
+                @passed = nil
+                self.before_setup
+                self.setup
+                self.after_setup
+                self.run_test self.__name__
+                mocha_verify(assertion_counter)
+                result = "." unless io?
+                @passed = true
+              rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
+                raise
+              rescue Exception => e
+                @passed = false
+                result = runner.puke self.class, self.__name__, Mocha::Integration::MiniTest.translate(e)
+              ensure
+                %w{ before_teardown teardown after_teardown }.each do |hook|
+                  begin
+                    self.send hook
+                  rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
+                    raise
+                  rescue Exception => e
+                    result = runner.puke self.class, self.__name__, Mocha::Integration::MiniTest.translate(e)
+                  end
+                end
+                trap 'INFO', 'DEFAULT' if ::MiniTest::Unit::TestCase::SUPPORTS_INFO_SIGNAL
+              end
+            ensure
+              mocha_teardown
+            end
+            result
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_2112_to_320.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_2112_to_320.rb
new file mode 100755
index 0000000..16fe1da
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_2112_to_320.rb
@@ -0,0 +1,70 @@
+require 'mocha/integration/assertion_counter'
+require 'mocha/integration/monkey_patcher'
+require 'mocha/integration/mini_test/exception_translation'
+
+module Mocha
+  module Integration
+    module MiniTest
+      module Version2112To320
+        def self.applicable_to?(mini_test_version)
+          Gem::Requirement.new('>= 2.11.2', '<= 3.2.0').satisfied_by?(mini_test_version)
+        end
+
+        def self.description
+          "monkey patch for MiniTest gem >= v2.11.2 <= v3.2.0"
+        end
+
+        def self.included(mod)
+          MonkeyPatcher.apply(mod, RunMethodPatch)
+        end
+
+        module RunMethodPatch
+          def run runner
+            trap "INFO" do
+              runner.report.each_with_index do |msg, i|
+                warn "\n%3d) %s" % [i + 1, msg]
+              end
+              warn ''
+              time = runner.start_time ? Time.now - runner.start_time : 0
+              warn "Current Test: %s#%s %.2fs" % [self.class, self.__name__, time]
+              runner.status $stderr
+            end if ::MiniTest::Unit::TestCase::SUPPORTS_INFO_SIGNAL
+            assertion_counter = AssertionCounter.new(self)
+            result = ""
+            begin
+              begin
+                @passed = nil
+                self.before_setup
+                self.setup
+                self.after_setup
+                self.run_test self.__name__
+                mocha_verify(assertion_counter)
+                result = "." unless io?
+                @passed = true
+              rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
+                raise
+              rescue Exception => e
+                @passed = false
+                result = runner.puke self.class, self.__name__, Mocha::Integration::MiniTest.translate(e)
+              ensure
+                %w{ before_teardown teardown after_teardown }.each do |hook|
+                  begin
+                    self.send hook
+                  rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
+                    raise
+                  rescue Exception => e
+                    result = runner.puke self.class, self.__name__, Mocha::Integration::MiniTest.translate(e)
+                  end
+                end
+                trap 'INFO', 'DEFAULT' if ::MiniTest::Unit::TestCase::SUPPORTS_INFO_SIGNAL
+              end
+            ensure
+              mocha_teardown
+            end
+            result
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_230_to_2101.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_230_to_2101.rb
new file mode 100755
index 0000000..270efd4
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/mini_test/version_230_to_2101.rb
@@ -0,0 +1,65 @@
+require 'mocha/integration/assertion_counter'
+require 'mocha/integration/monkey_patcher'
+require 'mocha/integration/mini_test/exception_translation'
+
+module Mocha
+  module Integration
+    module MiniTest
+      module Version230To2101
+        def self.applicable_to?(mini_test_version)
+          Gem::Requirement.new('>= 2.3.0', '<= 2.10.1').satisfied_by?(mini_test_version)
+        end
+
+        def self.description
+          "monkey patch for MiniTest gem >= v2.3.0 <= v2.10.1"
+        end
+
+        def self.included(mod)
+          MonkeyPatcher.apply(mod, RunMethodPatch)
+        end
+
+        module RunMethodPatch
+          def run runner
+            trap 'INFO' do
+              time = runner.start_time ? Time.now - runner.start_time : 0
+              warn "%s#%s %.2fs" % [self.class, self.__name__, time]
+              runner.status $stderr
+            end if ::MiniTest::Unit::TestCase::SUPPORTS_INFO_SIGNAL
+
+            assertion_counter = AssertionCounter.new(self)
+            result = ""
+            begin
+              begin
+                @passed = nil
+                self.setup
+                self.run_setup_hooks
+                self.__send__ self.__name__
+                mocha_verify(assertion_counter)
+                result = "." unless io?
+                @passed = true
+              rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
+                raise
+              rescue Exception => e
+                @passed = false
+                result = runner.puke self.class, self.__name__, Mocha::Integration::MiniTest.translate(e)
+              ensure
+                begin
+                  self.run_teardown_hooks
+                  self.teardown
+                rescue *::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
+                  raise
+                rescue Exception => e
+                  result = runner.puke self.class, self.__name__, Mocha::Integration::MiniTest.translate(e)
+                end
+                trap 'INFO', 'DEFAULT' if ::MiniTest::Unit::TestCase::SUPPORTS_INFO_SIGNAL
+              end
+            ensure
+              mocha_teardown
+            end
+            result
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/monkey_patcher.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/monkey_patcher.rb
new file mode 100755
index 0000000..da60e07
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/monkey_patcher.rb
@@ -0,0 +1,18 @@
+require 'mocha/api'
+
+module Mocha
+  module Integration
+    module MonkeyPatcher
+      def self.apply(mod, run_method_patch)
+        unless mod < Mocha::API
+          mod.send(:include, Mocha::API)
+        end
+        unless mod.method_defined?(:run_before_mocha)
+          mod.send(:alias_method, :run_before_mocha, :run)
+          mod.send(:remove_method, :run)
+          mod.send(:include, run_method_patch)
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit.rb
new file mode 100755
index 0000000..32cbe46
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit.rb
@@ -0,0 +1,44 @@
+require 'mocha/debug'
+
+require 'mocha/detection/test_unit'
+
+require 'mocha/integration/test_unit/nothing'
+require 'mocha/integration/test_unit/ruby_version_185_and_below'
+require 'mocha/integration/test_unit/ruby_version_186_and_above'
+require 'mocha/integration/test_unit/gem_version_200'
+require 'mocha/integration/test_unit/gem_version_201_to_202'
+require 'mocha/integration/test_unit/gem_version_203_to_220'
+require 'mocha/integration/test_unit/gem_version_230_to_250'
+require 'mocha/integration/test_unit/adapter'
+
+module Mocha
+  module Integration
+    module TestUnit
+      def self.activate
+        return false unless Detection::TestUnit.testcase
+        test_unit_version = Gem::Version.new(Detection::TestUnit.version)
+        ruby_version = Gem::Version.new(RUBY_VERSION.dup)
+
+        Debug.puts "Detected Ruby version: #{ruby_version}"
+        Debug.puts "Detected Test::Unit version: #{test_unit_version}"
+
+        integration_module = [
+          TestUnit::Adapter,
+          TestUnit::GemVersion230To250,
+          TestUnit::GemVersion203To220,
+          TestUnit::GemVersion201To202,
+          TestUnit::GemVersion200,
+          TestUnit::RubyVersion186AndAbove,
+          TestUnit::RubyVersion185AndBelow,
+          TestUnit::Nothing
+        ].detect { |m| m.applicable_to?(test_unit_version, ruby_version) }
+
+        unless ::Test::Unit::TestCase < integration_module
+          Debug.puts "Applying #{integration_module.description}"
+          ::Test::Unit::TestCase.send(:include, integration_module)
+        end
+        true
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/adapter.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/adapter.rb
new file mode 100755
index 0000000..87ba222
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/adapter.rb
@@ -0,0 +1,51 @@
+require 'mocha/api'
+require 'mocha/integration/assertion_counter'
+require 'mocha/expectation_error'
+
+module Mocha
+  module Integration
+    module TestUnit
+
+      # Integrates Mocha into recent versions of Test::Unit.
+      #
+      # See the source code for an example of how to integrate Mocha into a test library.
+      module Adapter
+        include Mocha::API
+
+        # @private
+        def self.applicable_to?(test_unit_version, ruby_version = nil)
+          Gem::Requirement.new('>= 2.5.1').satisfied_by?(test_unit_version)
+        end
+
+        # @private
+        def self.description
+          "adapter for Test::Unit gem >= v2.5.1"
+        end
+
+        # @private
+        def self.included(mod)
+          mod.setup :mocha_setup, :before => :prepend
+
+          mod.exception_handler(:handle_mocha_expectation_error)
+
+          mod.cleanup :after => :append do
+            assertion_counter = Integration::AssertionCounter.new(self)
+            mocha_verify(assertion_counter)
+          end
+
+          mod.teardown :mocha_teardown, :after => :append
+        end
+
+        private
+
+        # @private
+        def handle_mocha_expectation_error(e)
+          return false unless e.is_a?(Mocha::ExpectationError)
+          problem_occurred
+          add_failure(e.message, e.backtrace)
+          true
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/gem_version_200.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/gem_version_200.rb
new file mode 100755
index 0000000..6afdd72
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/gem_version_200.rb
@@ -0,0 +1,59 @@
+require 'mocha/integration/assertion_counter'
+require 'mocha/integration/monkey_patcher'
+require 'mocha/expectation_error'
+
+module Mocha
+  module Integration
+    module TestUnit
+      module GemVersion200
+        def self.applicable_to?(test_unit_version, ruby_version = nil)
+          Gem::Requirement.new('2.0.0').satisfied_by?(test_unit_version)
+        end
+
+        def self.description
+          "monkey patch for Test::Unit gem v2.0.0"
+        end
+
+        def self.included(mod)
+          MonkeyPatcher.apply(mod, RunMethodPatch)
+        end
+
+        module RunMethodPatch
+          def run(result)
+            assertion_counter = AssertionCounter.new(self)
+            begin
+              @_result = result
+              yield(Test::Unit::TestCase::STARTED, name)
+              begin
+                begin
+                  run_setup
+                  __send__(@method_name)
+                  mocha_verify(assertion_counter)
+                rescue Mocha::ExpectationError => e
+                  add_failure(e.message, e.backtrace)
+                rescue Exception
+                  @interrupted = true
+                  raise unless handle_exception($!)
+                ensure
+                  begin
+                    run_teardown
+                  rescue Mocha::ExpectationError => e
+                    add_failure(e.message, e.backtrace)
+                  rescue Exception
+                    raise unless handle_exception($!)
+                  end
+                end
+              ensure
+                mocha_teardown
+              end
+              result.add_run
+              yield(Test::Unit::TestCase::FINISHED, name)
+            ensure
+              @_result = nil
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/gem_version_201_to_202.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/gem_version_201_to_202.rb
new file mode 100755
index 0000000..a7a3d32
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/gem_version_201_to_202.rb
@@ -0,0 +1,59 @@
+require 'mocha/integration/assertion_counter'
+require 'mocha/integration/monkey_patcher'
+require 'mocha/expectation_error'
+
+module Mocha
+  module Integration
+    module TestUnit
+      module GemVersion201To202
+        def self.applicable_to?(test_unit_version, ruby_version = nil)
+          Gem::Requirement.new('>= 2.0.1', '<= 2.0.2').satisfied_by?(test_unit_version)
+        end
+
+        def self.description
+          "monkey patch for Test::Unit gem >= v2.0.1 and <= v2.0.2"
+        end
+
+        def self.included(mod)
+          MonkeyPatcher.apply(mod, RunMethodPatch)
+        end
+
+        module RunMethodPatch
+          def run(result)
+            assertion_counter = AssertionCounter.new(self)
+            begin
+              @_result = result
+              yield(Test::Unit::TestCase::STARTED, name)
+              begin
+                begin
+                  run_setup
+                  run_test
+                  mocha_verify(assertion_counter)
+                rescue Mocha::ExpectationError => e
+                  add_failure(e.message, e.backtrace)
+                rescue Exception
+                  @interrupted = true
+                  raise unless handle_exception($!)
+                ensure
+                  begin
+                    run_teardown
+                  rescue Mocha::ExpectationError => e
+                    add_failure(e.message, e.backtrace)
+                  rescue Exception
+                    raise unless handle_exception($!)
+                  end
+                end
+              ensure
+                mocha_teardown
+              end
+              result.add_run
+              yield(Test::Unit::TestCase::FINISHED, name)
+            ensure
+              @_result = nil
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/gem_version_203_to_220.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/gem_version_203_to_220.rb
new file mode 100755
index 0000000..ef14f73
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/gem_version_203_to_220.rb
@@ -0,0 +1,59 @@
+require 'mocha/integration/assertion_counter'
+require 'mocha/integration/monkey_patcher'
+require 'mocha/expectation_error'
+
+module Mocha
+  module Integration
+    module TestUnit
+      module GemVersion203To220
+        def self.applicable_to?(test_unit_version, ruby_version = nil)
+          Gem::Requirement.new('>= 2.0.3', '<= 2.2.0').satisfied_by?(test_unit_version)
+        end
+
+        def self.description
+          "monkey patch for Test::Unit gem >= v2.0.3 and <= v2.2.0"
+        end
+
+        def self.included(mod)
+          MonkeyPatcher.apply(mod, RunMethodPatch)
+        end
+
+        module RunMethodPatch
+          def run(result)
+            assertion_counter = AssertionCounter.new(self)
+            begin
+              @_result = result
+              yield(Test::Unit::TestCase::STARTED, name)
+              begin
+                begin
+                  run_setup
+                  run_test
+                  mocha_verify(assertion_counter)
+                rescue Mocha::ExpectationError => e
+                  add_failure(e.message, e.backtrace)
+                rescue Exception
+                  @interrupted = true
+                  raise unless handle_exception($!)
+                ensure
+                  begin
+                    run_teardown
+                  rescue Mocha::ExpectationError => e
+                    add_failure(e.message, e.backtrace)
+                  rescue Exception
+                    raise unless handle_exception($!)
+                  end
+                end
+              ensure
+                mocha_teardown
+              end
+              result.add_run
+              yield(Test::Unit::TestCase::FINISHED, name)
+            ensure
+              # @_result = nil # For test-spec's after_all :<
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/gem_version_230_to_250.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/gem_version_230_to_250.rb
new file mode 100755
index 0000000..2a0cfb6
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/gem_version_230_to_250.rb
@@ -0,0 +1,65 @@
+require 'mocha/integration/assertion_counter'
+require 'mocha/integration/monkey_patcher'
+require 'mocha/expectation_error'
+
+module Mocha
+  module Integration
+    module TestUnit
+      module GemVersion230To250
+        def self.applicable_to?(test_unit_version, ruby_version = nil)
+          Gem::Requirement.new('>= 2.3.0', '<= 2.5.0').satisfied_by?(test_unit_version)
+        end
+
+        def self.description
+          "monkey patch for Test::Unit gem >= v2.3.0 and <= v2.5.0"
+        end
+
+        def self.included(mod)
+          MonkeyPatcher.apply(mod, RunMethodPatch)
+        end
+
+        module RunMethodPatch
+          def run(result)
+            assertion_counter = AssertionCounter.new(self)
+            begin
+              @internal_data.test_started
+              @_result = result
+              yield(Test::Unit::TestCase::STARTED, name)
+              yield(Test::Unit::TestCase::STARTED_OBJECT, self)
+              begin
+                begin
+                  run_setup
+                  run_test
+                  run_cleanup
+                  mocha_verify(assertion_counter)
+                  add_pass
+                rescue Mocha::ExpectationError => e
+                  add_failure(e.message, e.backtrace)
+                rescue Exception
+                  @internal_data.interrupted
+                  raise unless handle_exception($!)
+                ensure
+                  begin
+                    run_teardown
+                  rescue Mocha::ExpectationError => e
+                    add_failure(e.message, e.backtrace)
+                  rescue Exception
+                    raise unless handle_exception($!)
+                  end
+                end
+              ensure
+                mocha_teardown
+              end
+              @internal_data.test_finished
+              result.add_run
+              yield(Test::Unit::TestCase::FINISHED, name)
+              yield(Test::Unit::TestCase::FINISHED_OBJECT, self)
+            ensure
+              # @_result = nil # For test-spec's after_all :<
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/nothing.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/nothing.rb
new file mode 100755
index 0000000..41538db
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/nothing.rb
@@ -0,0 +1,19 @@
+module Mocha
+  module Integration
+    module TestUnit
+      module Nothing
+        def self.applicable_to?(test_unit_version, ruby_version = nil)
+          true
+        end
+
+        def self.description
+          "nothing (no Test::Unit integration available)"
+        end
+
+        def self.included(mod)
+          raise "No Test::Unit integration available"
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/ruby_version_185_and_below.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/ruby_version_185_and_below.rb
new file mode 100755
index 0000000..d97e492
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/ruby_version_185_and_below.rb
@@ -0,0 +1,58 @@
+require 'mocha/integration/assertion_counter'
+require 'mocha/integration/monkey_patcher'
+require 'mocha/expectation_error'
+
+module Mocha
+  module Integration
+    module TestUnit
+      module RubyVersion185AndBelow
+        def self.applicable_to?(test_unit_version, ruby_version)
+          Gem::Requirement.new('<= 1.2.3').satisfied_by?(test_unit_version) && Gem::Requirement.new('<= 1.8.5').satisfied_by?(ruby_version)
+        end
+
+        def self.description
+          "monkey patch for standard library in Ruby <= v1.8.5"
+        end
+
+        def self.included(mod)
+          MonkeyPatcher.apply(mod, RunMethodPatch)
+        end
+
+        module RunMethodPatch
+          def run(result)
+            assertion_counter = AssertionCounter.new(self)
+            yield(Test::Unit::TestCase::STARTED, name)
+            @_result = result
+            begin
+              begin
+                setup
+                __send__(@method_name)
+                mocha_verify(assertion_counter)
+              rescue Mocha::ExpectationError => e
+                add_failure(e.message, e.backtrace)
+              rescue Test::Unit::AssertionFailedError => e
+                add_failure(e.message, e.backtrace)
+              rescue StandardError, ScriptError
+                add_error($!)
+              ensure
+                begin
+                  teardown
+                rescue Mocha::ExpectationError => e
+                  add_failure(e.message, e.backtrace)
+                rescue Test::Unit::AssertionFailedError => e
+                  add_failure(e.message, e.backtrace)
+                rescue StandardError, ScriptError
+                  add_error($!)
+                end
+              end
+            ensure
+              mocha_teardown
+            end
+            result.add_run
+            yield(Test::Unit::TestCase::FINISHED, name)
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb
new file mode 100755
index 0000000..e47c82e
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb
@@ -0,0 +1,60 @@
+require 'mocha/integration/assertion_counter'
+require 'mocha/integration/monkey_patcher'
+require 'mocha/expectation_error'
+
+module Mocha
+  module Integration
+    module TestUnit
+      module RubyVersion186AndAbove
+        def self.applicable_to?(test_unit_version, ruby_version)
+          Gem::Requirement.new('<= 1.2.3').satisfied_by?(test_unit_version) && Gem::Requirement.new('>= 1.8.6').satisfied_by?(ruby_version)
+        end
+
+        def self.description
+          "monkey patch for standard library Test::Unit in Ruby >= v1.8.6"
+        end
+
+        def self.included(mod)
+          MonkeyPatcher.apply(mod, RunMethodPatch)
+        end
+
+        module RunMethodPatch
+          def run(result)
+            assertion_counter = AssertionCounter.new(self)
+            yield(Test::Unit::TestCase::STARTED, name)
+            @_result = result
+            begin
+              begin
+                setup
+                __send__(@method_name)
+                mocha_verify(assertion_counter)
+              rescue Mocha::ExpectationError => e
+                add_failure(e.message, e.backtrace)
+              rescue Test::Unit::AssertionFailedError => e
+                add_failure(e.message, e.backtrace)
+              rescue Exception
+                raise if Test::Unit::TestCase::PASSTHROUGH_EXCEPTIONS.include? $!.class
+                add_error($!)
+              ensure
+                begin
+                  teardown
+                rescue Mocha::ExpectationError => e
+                  add_failure(e.message, e.backtrace)
+                rescue Test::Unit::AssertionFailedError => e
+                  add_failure(e.message, e.backtrace)
+                rescue Exception
+                  raise if Test::Unit::TestCase::PASSTHROUGH_EXCEPTIONS.include? $!.class
+                  add_error($!)
+                end
+              end
+            ensure
+              mocha_teardown
+            end
+            result.add_run
+            yield(Test::Unit::TestCase::FINISHED, name)
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/is_a.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/is_a.rb
new file mode 100755
index 0000000..a027a8c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/is_a.rb
@@ -0,0 +1,9 @@
+class Object
+
+  # :stopdoc:
+
+  alias_method :__is_a__, :is_a?
+
+  # :startdoc:
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/logger.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/logger.rb
new file mode 100755
index 0000000..3c66650
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/logger.rb
@@ -0,0 +1,15 @@
+module Mocha
+
+  class Logger
+
+    def initialize(io)
+      @io = io
+    end
+
+    def warn(message)
+      @io.puts "WARNING: #{message}"
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/method_matcher.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/method_matcher.rb
new file mode 100755
index 0000000..66fed9c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/method_matcher.rb
@@ -0,0 +1,21 @@
+module Mocha
+
+  class MethodMatcher
+
+    attr_reader :expected_method_name
+
+    def initialize(expected_method_name)
+      @expected_method_name = expected_method_name
+    end
+
+    def match?(actual_method_name)
+      @expected_method_name == actual_method_name.to_sym
+    end
+
+    def mocha_inspect
+      "#{@expected_method_name}"
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/mini_test.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/mini_test.rb
new file mode 100755
index 0000000..4417799
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/mini_test.rb
@@ -0,0 +1,3 @@
+require "mocha/integration/mini_test"
+
+Mocha::Integration::MiniTest.activate
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/mock.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/mock.rb
new file mode 100755
index 0000000..b7cc54b
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/mock.rb
@@ -0,0 +1,352 @@
+require 'metaclass'
+require 'mocha/expectation'
+require 'mocha/expectation_list'
+require 'mocha/names'
+require 'mocha/receivers'
+require 'mocha/method_matcher'
+require 'mocha/parameters_matcher'
+require 'mocha/unexpected_invocation'
+require 'mocha/argument_iterator'
+require 'mocha/expectation_error_factory'
+
+module Mocha
+
+  # Traditional mock object.
+  #
+  # All methods return an {Expectation} which can be further modified by
+  # methods on {Expectation}.
+  #
+  # Stubs and expectations are basically the same thing. A stub is just an
+  # expectation of zero or more invocations. The {#stubs} method is syntactic
+  # sugar to make the intent of the test more explicit.
+  #
+  # When a method is invoked on a mock object, the mock object searches through
+  # its expectations from newest to oldest to find one that matches the
+  # invocation. After the invocation, the matching expectation might stop
+  # matching further invocations. For example, an +expects(:foo).once+
+  # expectation only matches once and will be ignored on future invocations
+  # while an +expects(:foo).at_least_once+ expectation will always be matched
+  # against invocations.
+  #
+  # This scheme allows you to:
+  #
+  # - Set up default stubs in your the +setup+ method of your test class and
+  #   override some of those stubs in individual tests.
+  # - Set up different +once+ expectations for the same method with different
+  #   action per invocation. However, it's better to use the
+  #   {Expectation#returns} method with multiple arguments to do this, as
+  #   described below.
+  #
+  # However, there are some possible "gotchas" caused by this scheme:
+  #
+  # - if you create an expectation and then a stub for the same method, the
+  #   stub will always override the expectation and the expectation will never
+  #   be met.
+  # - if you create a stub and then an expectation for the same method, the
+  #   expectation will match, and when it stops matching the stub will be used
+  #   instead, possibly masking test failures.
+  # - if you create different expectations for the same method, they will be
+  #   invoked in the opposite order than that in which they were specified,
+  #   rather than the same order.
+  #
+  # The best thing to do is not set up multiple expectations and stubs for the
+  # same method with exactly the same matchers. Instead, use the
+  # {Expectation#returns} method with multiple arguments to create multiple
+  # actions for a method. You can also chain multiple calls to
+  # {Expectation#returns} and {Expectation#raises} (along with syntactic sugar
+  # {Expectation#then} if desired).
+  #
+  # @example
+  #   object = mock()
+  #   object.stubs(:expected_method).returns(1, 2).then.raises(Exception)
+  #   object.expected_method # => 1
+  #   object.expected_method # => 2
+  #   object.expected_method # => raises exception of class Exception1
+  #
+  # If you want to specify more complex ordering or order invocations across
+  # different mock objects, use the {Expectation#in_sequence} method to
+  # explicitly define a total or partial ordering of invocations.
+  class Mock
+
+    # Adds an expectation that the specified method must be called exactly once with any parameters.
+    #
+    # @param [Symbol,String] method_name name of expected method
+    # @param [Hash] expected_methods_vs_return_values expected method name symbols as keys and corresponding return values as values - these expectations are setup as if {#expects} were called multiple times.
+    #
+    # @overload def expects(method_name)
+    # @overload def expects(expected_methods_vs_return_values)
+    # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}.
+    #
+    # @example Expected method invoked once so no error raised
+    #   object = mock()
+    #   object.expects(:expected_method)
+    #   object.expected_method
+    #
+    # @example Expected method not invoked so error raised
+    #   object = mock()
+    #   object.expects(:expected_method)
+    #   # error raised when test completes, because expected_method not called exactly once
+    #
+    # @example Expected method invoked twice so error raised
+    #   object = mock()
+    #   object.expects(:expected_method)
+    #   object.expected_method
+    #   object.expected_method # => error raised when expected method invoked second time
+    #
+    # @example Setup multiple expectations using +expected_methods_vs_return_values+.
+    #   object = mock()
+    #   object.expects(:expected_method_one => :result_one, :expected_method_two => :result_two)
+    #
+    #   # is exactly equivalent to
+    #
+    #   object = mock()
+    #   object.expects(:expected_method_one).returns(:result_one)
+    #   object.expects(:expected_method_two).returns(:result_two)
+    def expects(method_name_or_hash, backtrace = nil)
+      iterator = ArgumentIterator.new(method_name_or_hash)
+      iterator.each { |*args|
+        method_name = args.shift
+        ensure_method_not_already_defined(method_name)
+        expectation = Expectation.new(self, method_name, backtrace)
+        expectation.returns(args.shift) if args.length > 0
+        @expectations.add(expectation)
+      }
+    end
+
+    # Adds an expectation that the specified method may be called any number of times with any parameters.
+    #
+    # @param [Symbol,String] method_name name of stubbed method
+    # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {#stubs} were called multiple times.
+    #
+    # @overload def stubs(method_name)
+    # @overload def stubs(stubbed_methods_vs_return_values)
+    # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}.
+    #
+    # @example No error raised however many times stubbed method is invoked
+    #   object = mock()
+    #   object.stubs(:stubbed_method)
+    #   object.stubbed_method
+    #   object.stubbed_method
+    #   # no error raised
+    #
+    # @example Setup multiple expectations using +stubbed_methods_vs_return_values+.
+    #   object = mock()
+    #   object.stubs(:stubbed_method_one => :result_one, :stubbed_method_two => :result_two)
+    #
+    #   # is exactly equivalent to
+    #
+    #   object = mock()
+    #   object.stubs(:stubbed_method_one).returns(:result_one)
+    #   object.stubs(:stubbed_method_two).returns(:result_two)
+    def stubs(method_name_or_hash, backtrace = nil)
+      iterator = ArgumentIterator.new(method_name_or_hash)
+      iterator.each { |*args|
+        method_name = args.shift
+        ensure_method_not_already_defined(method_name)
+        expectation = Expectation.new(self, method_name, backtrace)
+        expectation.at_least(0)
+        expectation.returns(args.shift) if args.length > 0
+        @expectations.add(expectation)
+      }
+    end
+
+    # Removes the specified stubbed method (added by calls to {#expects} or {#stubs}) and all expectations associated with it.
+    #
+    # @param [Symbol] method_name name of method to unstub.
+    #
+    # @example Invoking an unstubbed method causes error to be raised
+    #   object = mock('mock') do
+    #   object.stubs(:stubbed_method).returns(:result_one)
+    #   object.stubbed_method # => :result_one
+    #   object.unstub(:stubbed_method)
+    #   object.stubbed_method # => unexpected invocation: #<Mock:mock>.stubbed_method()
+    def unstub(method_name)
+      @expectations.remove_all_matching_method(method_name)
+    end
+
+    # Constrains the {Mock} instance so that it can only expect or stub methods to which +responder+ responds. The constraint is only applied at method invocation time.
+    #
+    # A +NoMethodError+ will be raised if the +responder+ does not +#respond_to?+ a method invocation (even if the method has been expected or stubbed).
+    #
+    # The {Mock} instance will delegate its +#respond_to?+ method to the +responder+.
+    #
+    # Note that the methods on +responder+ are never actually invoked.
+    #
+    # @param [Object, #respond_to?] responder an object used to determine whether {Mock} instance should +#respond_to?+ to an invocation.
+    # @return [Mock] the same {Mock} instance, thereby allowing invocations of other {Mock} methods to be chained.
+    # @see #responds_like_instance_of
+    #
+    # @example Normal mocking
+    #   sheep = mock('sheep')
+    #   sheep.expects(:chew)
+    #   sheep.expects(:foo)
+    #   sheep.respond_to?(:chew) # => true
+    #   sheep.respond_to?(:foo) # => true
+    #   sheep.chew
+    #   sheep.foo
+    #   # no error raised
+    #
+    # @example Using {#responds_like} with an instance method
+    #   class Sheep
+    #     def chew(grass); end
+    #   end
+    #
+    #   sheep = mock('sheep')
+    #   sheep.responds_like(Sheep.new)
+    #   sheep.expects(:chew)
+    #   sheep.expects(:foo)
+    #   sheep.respond_to?(:chew) # => true
+    #   sheep.respond_to?(:foo) # => false
+    #   sheep.chew
+    #   sheep.foo # => raises NoMethodError exception
+    #
+    # @example Using {#responds_like} with a class method
+    #   class Sheep
+    #     def self.number_of_legs; end
+    #   end
+    #
+    #   sheep_class = mock('sheep_class')
+    #   sheep_class.responds_like(Sheep)
+    #   sheep_class.stubs(:number_of_legs).returns(4)
+    #   sheep_class.expects(:foo)
+    #   sheep_class.respond_to?(:number_of_legs) # => true
+    #   sheep_class.respond_to?(:foo) # => false
+    #   sheep_class.number_of_legs # => 4
+    #   sheep_class.foo # => raises NoMethodError exception
+    def responds_like(responder)
+      @responder = responder
+      self
+    end
+
+    # Constrains the {Mock} instance so that it can only expect or stub methods to which an instance of the +responder_class+ responds. The constraint is only applied at method invocation time. Note that the responder instance is instantiated using +Class#allocate+.
+    #
+    # A +NoMethodError+ will be raised if the responder instance does not +#respond_to?+ a method invocation (even if the method has been expected or stubbed).
+    #
+    # The {Mock} instance will delegate its +#respond_to?+ method to the responder instance.
+    #
+    # Note that the methods on the responder instance are never actually invoked.
+    #
+    # @param [Class] responder_class a class used to determine whether {Mock} instance should +#respond_to?+ to an invocation.
+    # @return [Mock] the same {Mock} instance, thereby allowing invocations of other {Mock} methods to be chained.
+    # @see #responds_like
+    #
+    # @example Using {#responds_like_instance_of}
+    #   class Sheep
+    #     def initialize
+    #       raise "some awkward code we don't want to call"
+    #     end
+    #     def chew(grass); end
+    #   end
+    #
+    #   sheep = mock('sheep')
+    #   sheep.responds_like_instance_of(Sheep)
+    #   sheep.expects(:chew)
+    #   sheep.expects(:foo)
+    #   sheep.respond_to?(:chew) # => true
+    #   sheep.respond_to?(:foo) # => false
+    #   sheep.chew
+    #   sheep.foo # => raises NoMethodError exception
+    def responds_like_instance_of(responder_class)
+      responds_like(responder_class.allocate)
+    end
+
+    # @private
+    def initialize(mockery, name = nil, receiver = nil, &block)
+      @mockery = mockery
+      @name = name || DefaultName.new(self)
+      @receiver = receiver || DefaultReceiver.new(self)
+      @expectations = ExpectationList.new
+      @everything_stubbed = false
+      @responder = nil
+      @unexpected_invocation = nil
+      instance_eval(&block) if block
+    end
+
+    # @private
+    attr_reader :everything_stubbed
+
+    alias_method :__expects__, :expects
+
+    alias_method :__stubs__, :stubs
+
+    alias_method :quacks_like, :responds_like
+    alias_method :quacks_like_instance_of, :responds_like_instance_of
+
+    # @private
+    def __expectations__
+      @expectations
+    end
+
+    # @private
+    def stub_everything
+      @everything_stubbed = true
+    end
+
+    # @private
+    def all_expectations
+      @receiver.mocks.inject(ExpectationList.new) { |e, m| e + m.__expectations__ }
+    end
+
+    # @private
+    def method_missing(symbol, *arguments, &block)
+      if @responder and not @responder.respond_to?(symbol)
+        raise NoMethodError, "undefined method `#{symbol}' for #{self.mocha_inspect} which responds like #{@responder.mocha_inspect}"
+      end
+      if matching_expectation_allowing_invocation = all_expectations.match_allowing_invocation(symbol, *arguments)
+        matching_expectation_allowing_invocation.invoke(&block)
+      else
+        if (matching_expectation = all_expectations.match(symbol, *arguments)) || (!matching_expectation && !@everything_stubbed)
+          if @unexpected_invocation.nil?
+            @unexpected_invocation = UnexpectedInvocation.new(self, symbol, *arguments)
+            matching_expectation.invoke(&block) if matching_expectation
+            message = @unexpected_invocation.full_description
+            message << @mockery.mocha_inspect
+          else
+            message = @unexpected_invocation.short_description
+          end
+          raise ExpectationErrorFactory.build(message, caller)
+        end
+      end
+    end
+
+    # @private
+    def respond_to?(symbol, include_private = false)
+      if @responder then
+        if @responder.method(:respond_to?).arity > 1
+          @responder.respond_to?(symbol, include_private)
+        else
+          @responder.respond_to?(symbol)
+        end
+      else
+        @everything_stubbed || all_expectations.matches_method?(symbol)
+      end
+    end
+
+    # @private
+    def __verified__?(assertion_counter = nil)
+      @expectations.verified?(assertion_counter)
+    end
+
+    # @private
+    def mocha_inspect
+      @name.mocha_inspect
+    end
+
+    # @private
+    def inspect
+      mocha_inspect
+    end
+
+    # @private
+    def ensure_method_not_already_defined(method_name)
+      self.__metaclass__.send(:undef_method, method_name) if self.__metaclass__.method_defined?(method_name) || self.__metaclass__.private_method_defined?(method_name)
+    end
+
+    # @private
+    def any_expectations?
+      @expectations.any?
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/mockery.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/mockery.rb
new file mode 100755
index 0000000..57a8436
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/mockery.rb
@@ -0,0 +1,205 @@
+require 'mocha/central'
+require 'mocha/mock'
+require 'mocha/names'
+require 'mocha/receivers'
+require 'mocha/state_machine'
+require 'mocha/logger'
+require 'mocha/configuration'
+require 'mocha/stubbing_error'
+require 'mocha/expectation_error_factory'
+
+module Mocha
+
+  class Mockery
+
+    class << self
+
+      def instance
+        @instance ||= new
+      end
+
+      def verify(*args)
+        instance.verify(*args)
+      end
+
+      def teardown
+        instance.teardown
+      end
+
+      def reset_instance
+        @instance = nil
+      end
+
+    end
+
+    def named_mock(name, &block)
+      add_mock(Mock.new(self, Name.new(name), &block))
+    end
+
+    def unnamed_mock(&block)
+      add_mock(Mock.new(self, &block))
+    end
+
+    def mock_impersonating(object, &block)
+      add_mock(Mock.new(self, ImpersonatingName.new(object), ObjectReceiver.new(object), &block))
+    end
+
+    def mock_impersonating_any_instance_of(klass, &block)
+      add_mock(Mock.new(self, ImpersonatingAnyInstanceName.new(klass), AnyInstanceReceiver.new(klass), &block))
+    end
+
+    def new_state_machine(name)
+      add_state_machine(StateMachine.new(name))
+    end
+
+    def verify(assertion_counter = nil)
+      unless mocks.all? { |mock| mock.__verified__?(assertion_counter) }
+        message = "not all expectations were satisfied\n#{mocha_inspect}"
+        if unsatisfied_expectations.empty?
+          backtrace = caller
+        else
+          backtrace = unsatisfied_expectations[0].backtrace
+        end
+        raise ExpectationErrorFactory.build(message, backtrace)
+      end
+      expectations.each do |e|
+        unless Mocha::Configuration.allow?(:stubbing_method_unnecessarily)
+          unless e.used?
+            on_stubbing_method_unnecessarily(e)
+          end
+        end
+      end
+    end
+
+    def teardown
+      stubba.unstub_all
+      reset
+    end
+
+    def stubba
+      @stubba ||= Central.new
+    end
+
+    def mocks
+      @mocks ||= []
+    end
+
+    def state_machines
+      @state_machines ||= []
+    end
+
+    def mocha_inspect
+      message = ""
+      message << "unsatisfied expectations:\n- #{unsatisfied_expectations.map { |e| e.mocha_inspect }.join("\n- ")}\n" unless unsatisfied_expectations.empty?
+      message << "satisfied expectations:\n- #{satisfied_expectations.map { |e| e.mocha_inspect }.join("\n- ")}\n" unless satisfied_expectations.empty?
+      message << "states:\n- #{state_machines.map { |sm| sm.mocha_inspect }.join("\n- ")}" unless state_machines.empty?
+      message
+    end
+
+    def on_stubbing(object, method)
+      method = RUBY_VERSION < '1.9' ? method.to_s : method.to_sym
+      unless Mocha::Configuration.allow?(:stubbing_non_existent_method)
+        unless object.method_exists?(method, include_public_methods = true)
+          on_stubbing_non_existent_method(object, method)
+        end
+      end
+      unless Mocha::Configuration.allow?(:stubbing_non_public_method)
+        if object.method_exists?(method, include_public_methods = false)
+          on_stubbing_non_public_method(object, method)
+        end
+      end
+      unless Mocha::Configuration.allow?(:stubbing_method_on_nil)
+        if object.nil?
+          on_stubbing_method_on_nil(object, method)
+        end
+      end
+      unless Mocha::Configuration.allow?(:stubbing_method_on_non_mock_object)
+        on_stubbing_method_on_non_mock_object(object, method)
+      end
+    end
+
+    def on_stubbing_non_existent_method(object, method)
+      if Mocha::Configuration.prevent?(:stubbing_non_existent_method)
+        raise StubbingError.new("stubbing non-existent method: #{object.mocha_inspect}.#{method}", caller)
+      end
+      if Mocha::Configuration.warn_when?(:stubbing_non_existent_method)
+        logger.warn "stubbing non-existent method: #{object.mocha_inspect}.#{method}"
+      end
+    end
+
+    def on_stubbing_non_public_method(object, method)
+      if Mocha::Configuration.prevent?(:stubbing_non_public_method)
+        raise StubbingError.new("stubbing non-public method: #{object.mocha_inspect}.#{method}", caller)
+      end
+      if Mocha::Configuration.warn_when?(:stubbing_non_public_method)
+        logger.warn "stubbing non-public method: #{object.mocha_inspect}.#{method}"
+      end
+    end
+
+    def on_stubbing_method_on_nil(object, method)
+      if Mocha::Configuration.prevent?(:stubbing_method_on_nil)
+        raise StubbingError.new("stubbing method on nil: #{object.mocha_inspect}.#{method}", caller)
+      end
+      if Mocha::Configuration.warn_when?(:stubbing_method_on_nil)
+        logger.warn "stubbing method on nil: #{object.mocha_inspect}.#{method}"
+      end
+    end
+
+    def on_stubbing_method_on_non_mock_object(object, method)
+      if Mocha::Configuration.prevent?(:stubbing_method_on_non_mock_object)
+        raise StubbingError.new("stubbing method on non-mock object: #{object.mocha_inspect}.#{method}", caller)
+      end
+      if Mocha::Configuration.warn_when?(:stubbing_method_on_non_mock_object)
+        logger.warn "stubbing method on non-mock object: #{object.mocha_inspect}.#{method}"
+      end
+    end
+
+    def on_stubbing_method_unnecessarily(expectation)
+      if Mocha::Configuration.prevent?(:stubbing_method_unnecessarily)
+        raise StubbingError.new("stubbing method unnecessarily: #{expectation.method_signature}", expectation.backtrace)
+      end
+      if Mocha::Configuration.warn_when?(:stubbing_method_unnecessarily)
+        logger.warn "stubbing method unnecessarily: #{expectation.method_signature}"
+      end
+    end
+
+    attr_writer :logger
+
+    def logger
+      @logger ||= Logger.new($stderr)
+    end
+
+
+    private
+
+    def expectations
+      mocks.map { |mock| mock.__expectations__.to_a }.flatten
+    end
+
+    def unsatisfied_expectations
+      expectations.reject { |e| e.verified? }
+    end
+
+    def satisfied_expectations
+      expectations.select { |e| e.verified? }
+    end
+
+    def add_mock(mock)
+      mocks << mock
+      mock
+    end
+
+    def add_state_machine(state_machine)
+      state_machines << state_machine
+      state_machine
+    end
+
+    def reset
+      @stubba = nil
+      @mocks = nil
+      @state_machines = nil
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/module_method.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/module_method.rb
new file mode 100755
index 0000000..8f842a8
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/module_method.rb
@@ -0,0 +1,16 @@
+require 'mocha/class_method'
+
+module Mocha
+
+  class ModuleMethod < ClassMethod
+
+    def method_exists?(method)
+      return true if stubbee.public_methods(false).include?(method)
+      return true if stubbee.protected_methods(false).include?(method)
+      return true if stubbee.private_methods(false).include?(method)
+      return false
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/module_methods.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/module_methods.rb
new file mode 100755
index 0000000..d01155f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/module_methods.rb
@@ -0,0 +1,14 @@
+require 'mocha/module_method'
+
+module Mocha
+
+  # @private
+  module ModuleMethods
+
+    def stubba_method
+      Mocha::ModuleMethod
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/multiple_yields.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/multiple_yields.rb
new file mode 100755
index 0000000..052c349
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/multiple_yields.rb
@@ -0,0 +1,20 @@
+module Mocha
+
+  class MultipleYields
+
+    attr_reader :parameter_groups
+
+    def initialize(*parameter_groups)
+      @parameter_groups = parameter_groups
+    end
+
+    def each
+      @parameter_groups.each do |parameter_group|
+        yield(parameter_group)
+      end
+    end
+
+  end
+
+end
+
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/names.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/names.rb
new file mode 100755
index 0000000..c50955e
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/names.rb
@@ -0,0 +1,53 @@
+module Mocha
+
+  class ImpersonatingName
+
+    def initialize(object)
+      @object = object
+    end
+
+    def mocha_inspect
+      @object.mocha_inspect
+    end
+
+  end
+
+  class ImpersonatingAnyInstanceName
+
+    def initialize(klass)
+      @klass = klass
+    end
+
+    def mocha_inspect
+      "#<AnyInstance:#{@klass.mocha_inspect}>"
+    end
+
+  end
+
+  class Name
+
+    def initialize(name)
+      @name = name
+    end
+
+    def mocha_inspect
+      "#<Mock:#{@name}>"
+    end
+
+  end
+
+  class DefaultName
+
+    def initialize(mock)
+      @mock = mock
+    end
+
+    def mocha_inspect
+      address = @mock.__id__ * 2
+      address += 0x100000000 if address < 0
+      "#<Mock:0x#{'%x' % address}>"
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/no_yields.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/no_yields.rb
new file mode 100755
index 0000000..1c60cbc
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/no_yields.rb
@@ -0,0 +1,11 @@
+module Mocha
+
+  class NoYields
+
+    def each
+    end
+
+  end
+
+end
+
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/object_methods.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/object_methods.rb
new file mode 100755
index 0000000..75c4eef
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/object_methods.rb
@@ -0,0 +1,175 @@
+require 'mocha/mockery'
+require 'mocha/instance_method'
+require 'mocha/argument_iterator'
+require 'mocha/expectation_error_factory'
+
+module Mocha
+
+  # Methods added to all objects to allow mocking and stubbing on real (i.e. non-mock) objects.
+  #
+  # Both {#expects} and {#stubs} return an {Expectation} which can be further modified by methods on {Expectation}.
+  module ObjectMethods
+
+    # @private
+    alias_method :_method, :method
+
+    # @private
+    def mocha
+      @mocha ||= Mocha::Mockery.instance.mock_impersonating(self)
+    end
+
+    # @private
+    def reset_mocha
+      @mocha = nil
+    end
+
+    # @private
+    def stubba_method
+      Mocha::InstanceMethod
+    end
+
+    # @private
+    def stubba_object
+      self
+    end
+
+    # Adds an expectation that the specified method must be called exactly once with any parameters.
+    #
+    # The original implementation of the method is replaced during the test and then restored at the end of the test. The temporary replacement method has the same visibility as the original method.
+    #
+    # @param [Symbol,String] method_name name of expected method
+    # @param [Hash] expected_methods_vs_return_values expected method name symbols as keys and corresponding return values as values - these expectations are setup as if {#expects} were called multiple times.
+    #
+    # @overload def expects(method_name)
+    # @overload def expects(expected_methods_vs_return_values)
+    # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}.
+    # @raise [StubbingError] if attempting to stub method which is not allowed.
+    #
+    # @example Setting up an expectation on a non-mock object.
+    #   product = Product.new
+    #   product.expects(:save).returns(true)
+    #   assert_equal true, product.save
+    #
+    # @example Setting up multiple expectations on a non-mock object.
+    #   product = Product.new
+    #   product.expects(:valid? => true, :save => true)
+    #
+    #   # exactly equivalent to
+    #
+    #   product = Product.new
+    #   product.expects(:valid?).returns(true)
+    #   product.expects(:save).returns(true)
+    #
+    # @see Mock#expects
+    def expects(expected_methods_vs_return_values)
+      if expected_methods_vs_return_values.to_s =~ /the[^a-z]*spanish[^a-z]*inquisition/i
+        raise ExpectationErrorFactory.build('NOBODY EXPECTS THE SPANISH INQUISITION!')
+      end
+      if frozen?
+        raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}", caller)
+      end
+      expectation = nil
+      mockery = Mocha::Mockery.instance
+      iterator = ArgumentIterator.new(expected_methods_vs_return_values)
+      iterator.each { |*args|
+        method_name = args.shift
+        mockery.on_stubbing(self, method_name)
+        method = stubba_method.new(stubba_object, method_name)
+        mockery.stubba.stub(method)
+        expectation = mocha.expects(method_name, caller)
+        expectation.returns(args.shift) if args.length > 0
+      }
+      expectation
+    end
+
+    # Adds an expectation that the specified method may be called any number of times with any parameters.
+    #
+    # The original implementation of the method is replaced during the test and then restored at the end of the test. The temporary replacement method has the same visibility as the original method.
+    #
+    # @param [Symbol,String] method_name name of stubbed method
+    # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {#stubs} were called multiple times.
+    #
+    # @overload def stubs(method_name)
+    # @overload def stubs(stubbed_methods_vs_return_values)
+    # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}.
+    # @raise [StubbingError] if attempting to stub method which is not allowed.
+    #
+    # @example Setting up a stubbed methods on a non-mock object.
+    #   product = Product.new
+    #   product.stubs(:save).returns(true)
+    #   assert_equal true, product.save
+    #
+    # @example Setting up multiple stubbed methods on a non-mock object.
+    #   product = Product.new
+    #   product.stubs(:valid? => true, :save => true)
+    #
+    #   # exactly equivalent to
+    #
+    #   product = Product.new
+    #   product.stubs(:valid?).returns(true)
+    #   product.stubs(:save).returns(true)
+    #
+    # @see Mock#stubs
+    def stubs(stubbed_methods_vs_return_values)
+      if frozen?
+        raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}", caller)
+      end
+      expectation = nil
+      mockery = Mocha::Mockery.instance
+      iterator = ArgumentIterator.new(stubbed_methods_vs_return_values)
+      iterator.each { |*args|
+        method_name = args.shift
+        mockery.on_stubbing(self, method_name)
+        method = stubba_method.new(stubba_object, method_name)
+        mockery.stubba.stub(method)
+        expectation = mocha.stubs(method_name, caller)
+        expectation.returns(args.shift) if args.length > 0
+      }
+      expectation
+    end
+
+    # Removes the specified stubbed methods (added by calls to {#expects} or {#stubs}) and all expectations associated with them.
+    #
+    # Restores the original behaviour of the methods before they were stubbed. This is normally done automatically at the end of each test, but in some circumstances you may want to do it *before* the end of the test.
+    #
+    # WARNING: If you {#unstub} a method which still has unsatisfied expectations, you may be removing the only way those expectations can be satisfied. Use {#unstub} with care.
+    #
+    # @param [Array<Symbol>] method_names names of methods to unstub.
+    #
+    # @example Stubbing and unstubbing a method on a real (non-mock) object.
+    #   multiplier = Multiplier.new
+    #   multiplier.double(2) # => 4
+    #   multiplier.stubs(:double).raises # new behaviour defined
+    #   multiplier.double(2) # => raises exception
+    #   multiplier.unstub(:double) # original behaviour restored
+    #   multiplier.double(2) # => 4
+    #
+    # @example Unstubbing multiple methods on a real (non-mock) object.
+    #   multiplier.unstub(:double, :triple)
+    #
+    #   # exactly equivalent to
+    #
+    #   multiplier.unstub(:double)
+    #   multiplier.unstub(:triple)
+    def unstub(*method_names)
+      mockery = Mocha::Mockery.instance
+      method_names.each do |method_name|
+        method = stubba_method.new(stubba_object, method_name)
+        mockery.stubba.unstub(method)
+      end
+    end
+
+    # @private
+    def method_exists?(method, include_public_methods = true)
+      if include_public_methods
+        return true if public_methods(include_superclass_methods = true).include?(method)
+        return true if respond_to?(method.to_sym)
+      end
+      return true if protected_methods(include_superclass_methods = true).include?(method)
+      return true if private_methods(include_superclass_methods = true).include?(method)
+      return false
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers.rb
new file mode 100755
index 0000000..460556e
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers.rb
@@ -0,0 +1,28 @@
+module Mocha
+
+  # Used as parameters for {Expectation#with} to restrict the parameter values which will match the expectation. Can be nested.
+  module ParameterMatchers; end
+
+end
+
+require 'mocha/parameter_matchers/object'
+
+require 'mocha/parameter_matchers/all_of'
+require 'mocha/parameter_matchers/any_of'
+require 'mocha/parameter_matchers/any_parameters'
+require 'mocha/parameter_matchers/anything'
+require 'mocha/parameter_matchers/equals'
+require 'mocha/parameter_matchers/has_entry'
+require 'mocha/parameter_matchers/has_entries'
+require 'mocha/parameter_matchers/has_key'
+require 'mocha/parameter_matchers/has_value'
+require 'mocha/parameter_matchers/includes'
+require 'mocha/parameter_matchers/instance_of'
+require 'mocha/parameter_matchers/is_a'
+require 'mocha/parameter_matchers/kind_of'
+require 'mocha/parameter_matchers/not'
+require 'mocha/parameter_matchers/optionally'
+require 'mocha/parameter_matchers/regexp_matches'
+require 'mocha/parameter_matchers/responds_with'
+require 'mocha/parameter_matchers/yaml_equivalent'
+require 'mocha/parameter_matchers/query_string'
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/all_of.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/all_of.rb
new file mode 100755
index 0000000..eb1ebbd
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/all_of.rb
@@ -0,0 +1,52 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches if all +matchers+ match.
+    #
+    # @param [*Array<Base>] parameter_matchers parameter matchers.
+    # @return [AllOf] parameter matcher.
+    #
+    # @see Expectation#with
+    #
+    # @example All parameter matchers match.
+    #   object = mock()
+    #   object.expects(:method_1).with(all_of(includes(1), includes(3)))
+    #   object.method_1([1, 3])
+    #   # no error raised
+    #
+    # @example One of the parameter matchers does not match.
+    #   object = mock()
+    #   object.expects(:method_1).with(all_of(includes(1), includes(3)))
+    #   object.method_1([1, 2])
+    #   # error raised, because method_1 was not called with object including 1 and 3
+    def all_of(*matchers)
+      AllOf.new(*matchers)
+    end
+
+    # Parameter matcher which combines a number of other matchers using a logical AND.
+    class AllOf < Base
+
+      # @private
+      def initialize(*matchers)
+        @matchers = matchers
+      end
+
+      # @private
+      def matches?(available_parameters)
+        parameter = available_parameters.shift
+        @matchers.all? { |matcher| matcher.to_matcher.matches?([parameter]) }
+      end
+
+      # @private
+      def mocha_inspect
+        "all_of(#{@matchers.map { |matcher| matcher.mocha_inspect }.join(", ") })"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/any_of.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/any_of.rb
new file mode 100755
index 0000000..cd051d8
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/any_of.rb
@@ -0,0 +1,58 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches if any +matchers+ match.
+    #
+    # @param [*Array<Base>] parameter_matchers parameter matchers.
+    # @return [AnyOf] parameter matcher.
+    #
+    # @see Expectation#with
+    #
+    # @example One parameter matcher matches.
+    #   object = mock()
+    #   object.expects(:method_1).with(any_of(1, 3))
+    #   object.method_1(1)
+    #   # no error raised
+    #
+    # @example The other parameter matcher matches.
+    #   object = mock()
+    #   object.expects(:method_1).with(any_of(1, 3))
+    #   object.method_1(3)
+    #   # no error raised
+    #
+    # @example Neither parameter matcher matches.
+    #   object = mock()
+    #   object.expects(:method_1).with(any_of(1, 3))
+    #   object.method_1(2)
+    #   # error raised, because method_1 was not called with 1 or 3
+    def any_of(*matchers)
+      AnyOf.new(*matchers)
+    end
+
+    # Parameter matcher which combines a number of other matchers using a logical OR.
+    class AnyOf < Base
+
+      # @private
+      def initialize(*matchers)
+        @matchers = matchers
+      end
+
+      # @private
+      def matches?(available_parameters)
+        parameter = available_parameters.shift
+        @matchers.any? { |matcher| matcher.to_matcher.matches?([parameter]) }
+      end
+
+      # @private
+      def mocha_inspect
+        "any_of(#{@matchers.map { |matcher| matcher.mocha_inspect }.join(", ") })"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/any_parameters.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/any_parameters.rb
new file mode 100755
index 0000000..0c90d16
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/any_parameters.rb
@@ -0,0 +1,47 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches any parameters. This is used as the default for a newly built expectation.
+    #
+    # @return [AnyParameters] parameter matcher.
+    #
+    # @see Expectation#with
+    #
+    # @example Any parameters will match.
+    #   object = mock()
+    #   object.expects(:method_1).with(any_parameters)
+    #   object.method_1(1, 2, 3, 4)
+    #   # no error raised
+    #
+    #   object = mock()
+    #   object.expects(:method_1).with(any_parameters)
+    #   object.method_1(5, 6, 7, 8, 9, 0)
+    #   # no error raised
+    def any_parameters
+      AnyParameters.new
+    end
+
+    # Parameter matcher which always matches whatever the parameters.
+    class AnyParameters < Base
+
+      # @private
+      def matches?(available_parameters)
+        while available_parameters.length > 0 do
+          available_parameters.shift
+        end
+        return true
+      end
+
+      # @private
+      def mocha_inspect
+        "any_parameters"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/anything.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/anything.rb
new file mode 100755
index 0000000..11b9ab3
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/anything.rb
@@ -0,0 +1,42 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches any object.
+    #
+    # @return [Anything] parameter matcher.
+    #
+    # @see Expectation#with
+    #
+    # @example Any object will match.
+    #   object = mock()
+    #   object.expects(:method_1).with(anything)
+    #   object.method_1('foo')
+    #   object.method_1(789)
+    #   object.method_1(:bar)
+    #   # no error raised
+    def anything
+      Anything.new
+    end
+
+    # Parameter matcher which always matches a single parameter.
+    class Anything < Base
+
+      # @private
+      def matches?(available_parameters)
+        available_parameters.shift
+        return true
+      end
+
+      # @private
+      def mocha_inspect
+        "anything"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/base.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/base.rb
new file mode 100755
index 0000000..8a03765
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/base.rb
@@ -0,0 +1,71 @@
+module Mocha
+
+  module ParameterMatchers
+
+    # @abstract Subclass and implement +#matches?+ and +#mocha_inspect+ to define a custom matcher. Also add a suitably named instance method to {ParameterMatchers} to build an instance of the new matcher c.f. {#equals}.
+    class Base
+
+      # @private
+      def to_matcher
+        self
+      end
+
+      # A shorthand way of combining two matchers when both must match.
+      #
+      # Returns a new {AllOf} parameter matcher combining two matchers using a logical AND.
+      #
+      # This shorthand will not work with an implicit equals match. Instead, an explicit {Equals} matcher should be used.
+      #
+      # @param [Base] matcher parameter matcher.
+      # @return [AllOf] parameter matcher.
+      #
+      # @see Expectation#with
+      #
+      # @example Alternative ways to combine matchers with a logical AND.
+      #   object = mock()
+      #   object.expects(:run).with(all_of(has_key(:foo), has_key(:bar)))
+      #   object.run(:foo => 'foovalue', :bar => 'barvalue')
+      #
+      #   # is exactly equivalent to
+      #
+      #   object.expects(:run).with(has_key(:foo) & has_key(:bar))
+      #   object.run(:foo => 'foovalue', :bar => 'barvalue)
+      def &(matcher)
+        AllOf.new(self, matcher)
+      end
+
+      # A shorthand way of combining two matchers when at least one must match.
+      #
+      # Returns a new +AnyOf+ parameter matcher combining two matchers using a logical OR.
+      #
+      # This shorthand will not work with an implicit equals match. Instead, an explicit {Equals} matcher should be used.
+      #
+      # @param [Base] matcher parameter matcher.
+      # @return [AnyOf] parameter matcher.
+      #
+      # @see Expectation#with
+      #
+      # @example Alternative ways to combine matchers with a logical OR.
+      #   object = mock()
+      #   object.expects(:run).with(any_of(has_key(:foo), has_key(:bar)))
+      #   object.run(:foo => 'foovalue')
+      #
+      #   # is exactly equivalent to
+      #
+      #   object.expects(:run).with(has_key(:foo) | has_key(:bar))
+      #   object.run(:foo => 'foovalue')
+      #
+      # @example Using an explicit {Equals} matcher in combination with {#|}.
+      #   object.expects(:run).with(equals(1) | equals(2))
+      #   object.run(1) # passes
+      #   object.run(2) # passes
+      #   object.run(3) # fails
+      def |(matcher)
+        AnyOf.new(self, matcher)
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/equals.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/equals.rb
new file mode 100755
index 0000000..e822718
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/equals.rb
@@ -0,0 +1,53 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches any +Object+ equalling +value+.
+    #
+    # @param [Object] value expected value.
+    # @return [Equals] parameter matcher.
+    #
+    # @see Expectation#with
+    # @see Object#==
+    #
+    # @example Actual parameter equals expected parameter.
+    #   object = mock()
+    #   object.expects(:method_1).with(equals(2))
+    #   object.method_1(2)
+    #   # no error raised
+    #
+    # @example Actual parameter does not equal expected parameter.
+    #   object = mock()
+    #   object.expects(:method_1).with(equals(2))
+    #   object.method_1(3)
+    #   # error raised, because method_1 was not called with an +Object+ that equals 3
+    def equals(value)
+      Equals.new(value)
+    end
+
+    # Parameter matcher which matches when actual parameter equals expected value.
+    class Equals < Base
+
+      # @private
+      def initialize(value)
+        @value = value
+      end
+
+      # @private
+      def matches?(available_parameters)
+        parameter = available_parameters.shift
+        parameter == @value
+      end
+
+      # @private
+      def mocha_inspect
+        @value.mocha_inspect
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/has_entries.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/has_entries.rb
new file mode 100755
index 0000000..a217301
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/has_entries.rb
@@ -0,0 +1,55 @@
+require 'mocha/parameter_matchers/base'
+require 'mocha/parameter_matchers/all_of'
+require 'mocha/parameter_matchers/has_entry'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches +Hash+ containing all +entries+.
+    #
+    # @param [Hash] entries expected +Hash+ entries.
+    # @return [HasEntries] parameter matcher.
+    #
+    # @see Expectation#with
+    #
+    # @example Actual parameter contains all expected entries.
+    #   object = mock()
+    #   object.expects(:method_1).with(has_entries('key_1' => 1, 'key_2' => 2))
+    #   object.method_1('key_1' => 1, 'key_2' => 2, 'key_3' => 3)
+    #   # no error raised
+    #
+    # @example Actual parameter does not contain all expected entries.
+    #   object = mock()
+    #   object.expects(:method_1).with(has_entries('key_1' => 1, 'key_2' => 2))
+    #   object.method_1('key_1' => 1, 'key_2' => 99)
+    #   # error raised, because method_1 was not called with Hash containing entries: 'key_1' => 1, 'key_2' => 2
+    def has_entries(entries)
+      HasEntries.new(entries)
+    end
+
+    # Parameter matcher which matches when actual parameter contains all expected +Hash+ entries.
+    class HasEntries < Base
+
+      # @private
+      def initialize(entries)
+        @entries = entries
+      end
+
+      # @private
+      def matches?(available_parameters)
+        parameter = available_parameters.shift
+        has_entry_matchers = @entries.map { |key, value| HasEntry.new(key, value) }
+        AllOf.new(*has_entry_matchers).matches?([parameter])
+      end
+
+      # @private
+      def mocha_inspect
+        "has_entries(#{@entries.mocha_inspect})"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/has_entry.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/has_entry.rb
new file mode 100755
index 0000000..c52fa89
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/has_entry.rb
@@ -0,0 +1,93 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches +Hash+ containing entry with +key+ and +value+.
+    #
+    # @overload def has_entry(key, value)
+    #   @param [Object] key key for entry.
+    #   @param [Object] value value for entry.
+    # @overload def has_entry(single_entry_hash)
+    #   @param [Hash] single_entry_hash +Hash+ with single entry.
+    #   @raise [ArgumentError] if +single_entry_hash+ does not contain exactly one entry.
+    #
+    # @return [HasEntry] parameter matcher.
+    #
+    # @see Expectation#with
+    #
+    # @example Actual parameter contains expected entry supplied as key and value.
+    #   object = mock()
+    #   object.expects(:method_1).with(has_entry('key_1', 1))
+    #   object.method_1('key_1' => 1, 'key_2' => 2)
+    #   # no error raised
+    #
+    # @example Actual parameter contains expected entry supplied as +Hash+ entry.
+    #   object = mock()
+    #   object.expects(:method_1).with(has_entry('key_1' => 1))
+    #   object.method_1('key_1' => 1, 'key_2' => 2)
+    #   # no error raised
+    #
+    # @example Actual parameter does not contain expected entry supplied as key and value.
+    #   object = mock()
+    #   object.expects(:method_1).with(has_entry('key_1', 1))
+    #   object.method_1('key_1' => 2, 'key_2' => 1)
+    #   # error raised, because method_1 was not called with Hash containing entry: 'key_1' => 1
+    #
+    # @example Actual parameter does not contain expected entry supplied as +Hash+ entry.
+    #
+    #   object = mock()
+    #   object.expects(:method_1).with(has_entry('key_1' => 1))
+    #   object.method_1('key_1' => 2, 'key_2' => 1)
+    #   # error raised, because method_1 was not called with Hash containing entry: 'key_1' => 1
+    def has_entry(*options)
+      case options.length
+      when 1
+        case options[0]
+        when Hash
+          case options[0].length
+          when 0
+            raise ArgumentError.new("Argument has no entries.")
+          when 1
+            key, value = options[0].first
+          else
+            raise ArgumentError.new("Argument has multiple entries. Use Mocha::ParameterMatchers#has_entries instead.")
+          end
+        else
+          raise ArgumentError.new("Argument is not a Hash.")
+        end
+      when 2
+        key, value = options
+      else
+        raise ArgumentError.new("Too many arguments; use either a single argument (must be a Hash) or two arguments (a key and a value).")
+      end
+      HasEntry.new(key, value)
+    end
+
+    # Parameter matcher which matches when actual parameter contains expected +Hash+ entry.
+    class HasEntry < Base
+
+      # @private
+      def initialize(key, value)
+        @key, @value = key, value
+      end
+
+      # @private
+      def matches?(available_parameters)
+        parameter = available_parameters.shift
+        return false unless parameter.respond_to?(:keys) && parameter.respond_to?(:[])
+        matching_keys = parameter.keys.select { |key| @key.to_matcher.matches?([key]) }
+        matching_keys.any? { |key| @value.to_matcher.matches?([parameter[key]]) }
+      end
+
+      # @private
+      def mocha_inspect
+        "has_entry(#{@key.mocha_inspect} => #{@value.mocha_inspect})"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/has_key.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/has_key.rb
new file mode 100755
index 0000000..9f54416
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/has_key.rb
@@ -0,0 +1,53 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches +Hash+ containing +key+.
+    #
+    # @param [Object] key expected key.
+    # @return [HasKey] parameter matcher.
+    #
+    # @see Expectation#with
+    #
+    # @example Actual parameter contains entry with expected key.
+    #   object = mock()
+    #   object.expects(:method_1).with(has_key('key_1'))
+    #   object.method_1('key_1' => 1, 'key_2' => 2)
+    #   # no error raised
+    #
+    # @example Actual parameter does not contain entry with expected key.
+    #   object = mock()
+    #   object.expects(:method_1).with(has_key('key_1'))
+    #   object.method_1('key_2' => 2)
+    #   # error raised, because method_1 was not called with Hash containing key: 'key_1'
+    def has_key(key)
+      HasKey.new(key)
+    end
+
+    # Parameter matcher which matches when actual parameter contains +Hash+ entry with expected key.
+    class HasKey < Base
+
+      # @private
+      def initialize(key)
+        @key = key
+      end
+
+      # @private
+      def matches?(available_parameters)
+        parameter = available_parameters.shift
+        return false unless parameter.respond_to?(:keys)
+        parameter.keys.any? { |key| @key.to_matcher.matches?([key]) }
+      end
+
+      # @private
+      def mocha_inspect
+        "has_key(#{@key.mocha_inspect})"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/has_value.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/has_value.rb
new file mode 100755
index 0000000..cfed085
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/has_value.rb
@@ -0,0 +1,53 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches +Hash+ containing +value+.
+    #
+    # @param [Object] value expected value.
+    # @return [HasValue] parameter matcher.
+    #
+    # @see Expectation#with
+    #
+    # @example Actual parameter contains entry with expected value.
+    #   object = mock()
+    #   object.expects(:method_1).with(has_value(1))
+    #   object.method_1('key_1' => 1, 'key_2' => 2)
+    #   # no error raised
+    #
+    # @example Actual parameter does not contain entry with expected value.
+    #   object = mock()
+    #   object.expects(:method_1).with(has_value(1))
+    #   object.method_1('key_2' => 2)
+    #   # error raised, because method_1 was not called with Hash containing value: 1
+    def has_value(value)
+      HasValue.new(value)
+    end
+
+    # Parameter matcher which matches when actual parameter contains +Hash+ entry with expected value.
+    class HasValue < Base
+
+      # @private
+      def initialize(value)
+        @value = value
+      end
+
+      # @private
+      def matches?(available_parameters)
+        parameter = available_parameters.shift
+        return false unless parameter.respond_to?(:values)
+        parameter.values.any? { |value| @value.to_matcher.matches?([value]) }
+      end
+
+      # @private
+      def mocha_inspect
+        "has_value(#{@value.mocha_inspect})"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/includes.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/includes.rb
new file mode 100755
index 0000000..ab668a7
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/includes.rb
@@ -0,0 +1,60 @@
+require 'mocha/parameter_matchers/all_of'
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches any object that responds with +true+ to +include?(item)+
+    # for all items.
+    #
+    # @param [*Array] items expected items.
+    # @return [Includes] parameter matcher.
+    #
+    # @see Expectation#with
+    #
+    # @example Actual parameter includes all items.
+    #   object = mock()
+    #   object.expects(:method_1).with(includes('foo', 'bar'))
+    #   object.method_1(['foo', 'bar', 'baz'])
+    #   # no error raised
+    #
+    # @example Actual parameter does not include all items.
+    #   object.method_1(['foo', 'baz'])
+    #   # error raised, because ['foo', 'baz'] does not include 'bar'.
+    def includes(*items)
+      Includes.new(*items)
+    end
+
+    # Parameter matcher which matches when actual parameter includes expected values.
+    class Includes < Base
+
+      # @private
+      def initialize(*items)
+        @items = items
+      end
+
+      # @private
+      def matches?(available_parameters)
+        parameter = available_parameters.shift
+        return false unless parameter.respond_to?(:include?)
+
+        if @items.size == 1
+          return parameter.include?(@items.first)
+        else
+          includes_matchers = @items.map { |item| Includes.new(item) }
+          AllOf.new(*includes_matchers).matches?([parameter])
+        end
+      end
+
+      # @private
+      def mocha_inspect
+        item_descriptions = @items.map(&:mocha_inspect)
+        "includes(#{item_descriptions.join(', ')})"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/instance_of.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/instance_of.rb
new file mode 100755
index 0000000..0c90909
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/instance_of.rb
@@ -0,0 +1,53 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches any object that is an instance of +klass+
+    #
+    # @param [Class] klass expected class.
+    # @return [InstanceOf] parameter matcher.
+    #
+    # @see Expectation#with
+    # @see Kernel#instance_of?
+    #
+    # @example Actual parameter is an instance of +String+.
+    #   object = mock()
+    #   object.expects(:method_1).with(instance_of(String))
+    #   object.method_1('string')
+    #   # no error raised
+    #
+    # @example Actual parameter is not an instance of +String+.
+    #   object = mock()
+    #   object.expects(:method_1).with(instance_of(String))
+    #   object.method_1(99)
+    #   # error raised, because method_1 was not called with an instance of String
+    def instance_of(klass)
+      InstanceOf.new(klass)
+    end
+
+    # Parameter matcher which matches when actual parameter is an instance of the specified class.
+    class InstanceOf < Base
+
+      # @private
+      def initialize(klass)
+        @klass = klass
+      end
+
+      # @private
+      def matches?(available_parameters)
+        parameter = available_parameters.shift
+        parameter.instance_of?(@klass)
+      end
+
+      # @private
+      def mocha_inspect
+        "instance_of(#{@klass.mocha_inspect})"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/is_a.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/is_a.rb
new file mode 100755
index 0000000..493e84c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/is_a.rb
@@ -0,0 +1,53 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches any object that is a +klass+.
+    #
+    # @param [Class] klass expected class.
+    # @return [IsA] parameter matcher.
+    #
+    # @see Expectation#with
+    # @see Kernel#is_a?
+    #
+    # @example Actual parameter is a +Integer+.
+    #   object = mock()
+    #   object.expects(:method_1).with(is_a(Integer))
+    #   object.method_1(99)
+    #   # no error raised
+    #
+    # @example Actual parameter is not a +Integer+.
+    #   object = mock()
+    #   object.expects(:method_1).with(is_a(Integer))
+    #   object.method_1('string')
+    #   # error raised, because method_1 was not called with an Integer
+    def is_a(klass)
+      IsA.new(klass)
+    end
+
+    # Parameter matcher which matches when actual parameter is a specific class.
+    class IsA < Base
+
+      # @private
+      def initialize(klass)
+        @klass = klass
+      end
+
+      # @private
+      def matches?(available_parameters)
+        parameter = available_parameters.shift
+        parameter.is_a?(@klass)
+      end
+
+      # @private
+      def mocha_inspect
+        "is_a(#{@klass.mocha_inspect})"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/kind_of.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/kind_of.rb
new file mode 100755
index 0000000..cb9edd1
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/kind_of.rb
@@ -0,0 +1,53 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches any +Object+ that is a kind of +klass+.
+    #
+    # @param [Class] klass expected class.
+    # @return [KindOf] parameter matcher.
+    #
+    # @see Expectation#with
+    # @see Kernel#kind_of?
+    #
+    # @example Actual parameter is a kind of +Integer+.
+    #   object = mock()
+    #   object.expects(:method_1).with(kind_of(Integer))
+    #   object.method_1(99)
+    #   # no error raised
+    #
+    # @example Actual parameter is not a kind of +Integer+.
+    #   object = mock()
+    #   object.expects(:method_1).with(kind_of(Integer))
+    #   object.method_1('string')
+    #   # error raised, because method_1 was not called with a kind of Integer
+    def kind_of(klass)
+      KindOf.new(klass)
+    end
+
+    # Parameter matcher which matches when actual parameter is a kind of specified class.
+    class KindOf < Base
+
+      # @private
+      def initialize(klass)
+        @klass = klass
+      end
+
+      # @private
+      def matches?(available_parameters)
+        parameter = available_parameters.shift
+        parameter.kind_of?(@klass)
+      end
+
+      # @private
+      def mocha_inspect
+        "kind_of(#{@klass.mocha_inspect})"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/not.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/not.rb
new file mode 100755
index 0000000..d13e793
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/not.rb
@@ -0,0 +1,52 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches if +matcher+ does *not* match.
+    #
+    # @param [Base] matcher matcher whose logic to invert.
+    # @return [Not] parameter matcher.
+    #
+    # @see Expectation#with
+    #
+    # @example Actual parameter does not include the value +1+.
+    #   object = mock()
+    #   object.expects(:method_1).with(Not(includes(1)))
+    #   object.method_1([0, 2, 3])
+    #   # no error raised
+    #
+    # @example Actual parameter does include the value +1+.
+    #   object = mock()
+    #   object.expects(:method_1).with(Not(includes(1)))
+    #   object.method_1([0, 1, 2, 3])
+    #   # error raised, because method_1 was not called with object not including 1
+    def Not(matcher)
+      Not.new(matcher)
+    end
+
+    # Parameter matcher which inverts the logic of the specified matcher using a logical NOT operation.
+    class Not < Base
+
+      # @private
+      def initialize(matcher)
+        @matcher = matcher
+      end
+
+      # @private
+      def matches?(available_parameters)
+        parameter = available_parameters.shift
+        !@matcher.matches?([parameter])
+      end
+
+      # @private
+      def mocha_inspect
+        "Not(#{@matcher.mocha_inspect})"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/object.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/object.rb
new file mode 100755
index 0000000..9d646f0
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/object.rb
@@ -0,0 +1,17 @@
+require 'mocha/parameter_matchers/equals'
+
+module Mocha
+
+  module ObjectMethods
+    # @private
+    def to_matcher
+      Mocha::ParameterMatchers::Equals.new(self)
+    end
+  end
+
+end
+
+# @private
+class Object
+  include Mocha::ObjectMethods
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/optionally.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/optionally.rb
new file mode 100755
index 0000000..3ec098c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/optionally.rb
@@ -0,0 +1,67 @@
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches optional parameters if available.
+    #
+    # @param [*Array<Base>] matchers matchers for optional parameters.
+    # @return [Optionally] parameter matcher.
+    #
+    # @see Expectation#with
+    #
+    # @example Only the two required parameters are supplied and they both match their expected value.
+    #   object = mock()
+    #   object.expects(:method_1).with(1, 2, optionally(3, 4))
+    #   object.method_1(1, 2)
+    #   # no error raised
+    #
+    # @example Both required parameters and one of the optional parameters are supplied and they all match their expected value.
+    #   object = mock()
+    #   object.expects(:method_1).with(1, 2, optionally(3, 4))
+    #   object.method_1(1, 2, 3)
+    #   # no error raised
+    #
+    # @example Both required parameters and both of the optional parameters are supplied and they all match their expected value.
+    #   object = mock()
+    #   object.expects(:method_1).with(1, 2, optionally(3, 4))
+    #   object.method_1(1, 2, 3, 4)
+    #   # no error raised
+    #
+    # @example One of the actual optional parameters does not match the expected value.
+    #   object = mock()
+    #   object.expects(:method_1).with(1, 2, optionally(3, 4))
+    #   object.method_1(1, 2, 3, 5)
+    #   # error raised, because optional parameters did not match
+    def optionally(*matchers)
+      Optionally.new(*matchers)
+    end
+
+    # Parameter matcher which allows optional parameters to be specified.
+    class Optionally < Base
+
+      # @private
+      def initialize(*parameters)
+        @matchers = parameters.map { |parameter| parameter.to_matcher }
+      end
+
+      # @private
+      def matches?(available_parameters)
+        index = 0
+        while (available_parameters.length > 0) && (index < @matchers.length) do
+          matcher = @matchers[index]
+          return false unless matcher.matches?(available_parameters)
+          index += 1
+        end
+        return true
+      end
+
+      # @private
+      def mocha_inspect
+        "optionally(#{@matchers.map { |matcher| matcher.mocha_inspect }.join(", ") })"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/query_string.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/query_string.rb
new file mode 100755
index 0000000..e6c11c7
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/query_string.rb
@@ -0,0 +1,58 @@
+require 'mocha/parameter_matchers/base'
+require 'uri'
+
+module Mocha
+  module ParameterMatchers
+
+    # Matches a URI without regard to the ordering of parameters in the query string.
+    #
+    # @param [String] uri URI to match.
+    # @return [QueryStringMatches] parameter matcher.
+    #
+    # @see Expectation#with
+    #
+    # @example Actual URI has equivalent query string.
+    #   object = mock()
+    #   object.expects(:method_1).with(has_equivalent_query_string('http://example.com/foo?a=1&b=2))
+    #   object.method_1('http://example.com/foo?b=2&a=1')
+    #   # no error raised
+    #
+    # @example Actual URI does not have equivalent query string.
+    #   object = mock()
+    #   object.expects(:method_1).with(has_equivalent_query_string('http://example.com/foo?a=1&b=2))
+    #   object.method_1('http://example.com/foo?a=1&b=3')
+    #   # error raised, because the query parameters were different
+    def has_equivalent_query_string(uri)
+      QueryStringMatches.new(uri)
+    end
+
+    # Parameter matcher which matches URIs with equivalent query strings.
+    class QueryStringMatches < Base
+
+      # @private
+      def initialize(uri)
+        @uri = URI.parse(uri)
+      end
+
+      # @private
+      def matches?(available_parameters)
+        actual = explode(URI.parse(available_parameters.shift))
+        expected = explode(@uri)
+        actual == expected
+      end
+
+      # @private
+      def mocha_inspect
+        "has_equivalent_query_string(#{@uri.mocha_inspect})"
+      end
+
+    private
+      # @private
+      def explode(uri)
+        query_hash = (uri.query || '').split('&').inject({}){ |h, kv| h.merge(Hash[*kv.split('=')]) }
+        URI::Generic::COMPONENT.inject({}){ |h, k| h.merge(k => uri.__send__(k)) }.merge(:query => query_hash)
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/regexp_matches.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/regexp_matches.rb
new file mode 100755
index 0000000..88d2fc6
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/regexp_matches.rb
@@ -0,0 +1,54 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches any object that matches +regexp+.
+    #
+    # @param [Regexp] regexp regular expression to match.
+    # @return [RegexpMatches] parameter matcher.
+    #
+    # @see Expectation#with
+    #
+    # @example Actual parameter is matched by specified regular expression.
+    #   object = mock()
+    #   object.expects(:method_1).with(regexp_matches(/e/))
+    #   object.method_1('hello')
+    #   # no error raised
+    #
+    # @example Actual parameter is not matched by specified regular expression.
+    #   object = mock()
+    #   object.expects(:method_1).with(regexp_matches(/a/))
+    #   object.method_1('hello')
+    #   # error raised, because method_1 was not called with a parameter that matched the
+    #   # regular expression
+    def regexp_matches(regexp)
+      RegexpMatches.new(regexp)
+    end
+
+    # Parameter matcher which matches if specified regular expression matches actual paramter.
+    class RegexpMatches < Base
+
+      # @private
+      def initialize(regexp)
+        @regexp = regexp
+      end
+
+      # @private
+      def matches?(available_parameters)
+        parameter = available_parameters.shift
+        return false unless parameter.respond_to?(:=~)
+        parameter =~ @regexp
+      end
+
+      # @private
+      def mocha_inspect
+        "regexp_matches(#{@regexp.mocha_inspect})"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/responds_with.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/responds_with.rb
new file mode 100755
index 0000000..544171b
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/responds_with.rb
@@ -0,0 +1,54 @@
+require 'mocha/parameter_matchers/base'
+require 'yaml'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches any object that responds to +message+ with +result+. To put it another way, it tests the quack, not the duck.
+    #
+    # @param [Symbol] message method to invoke.
+    # @param [Object] result expected result of sending +message+.
+    # @return [RespondsWith] parameter matcher.
+    #
+    # @see Expectation#with
+    #
+    # @example Actual parameter responds with "FOO" when :upcase is invoked.
+    #   object = mock()
+    #   object.expects(:method_1).with(responds_with(:upcase, "FOO"))
+    #   object.method_1("foo")
+    #   # no error raised, because "foo".upcase == "FOO"
+    #
+    # @example Actual parameter does not respond with "FOO" when :upcase is invoked.
+    #   object = mock()
+    #   object.expects(:method_1).with(responds_with(:upcase, "BAR"))
+    #   object.method_1("foo")
+    #   # error raised, because "foo".upcase != "BAR"
+    def responds_with(message, result)
+      RespondsWith.new(message, result)
+    end
+
+    # Parameter matcher which matches if actual parameter returns expected result when specified method is invoked.
+    class RespondsWith < Base
+
+      # @private
+      def initialize(message, result)
+        @message, @result = message, result
+      end
+
+      # @private
+      def matches?(available_parameters)
+        parameter = available_parameters.shift
+        @result.to_matcher.matches?( [parameter.__send__(@message)] )
+      end
+
+      # @private
+      def mocha_inspect
+        "responds_with(#{@message.mocha_inspect}, #{@result.mocha_inspect})"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/yaml_equivalent.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/yaml_equivalent.rb
new file mode 100755
index 0000000..ea3f116
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameter_matchers/yaml_equivalent.rb
@@ -0,0 +1,53 @@
+require 'mocha/parameter_matchers/base'
+require 'yaml'
+
+module Mocha
+
+  module ParameterMatchers
+
+    # Matches any YAML that represents the specified +object+
+    #
+    # @param [Object] object object whose YAML to compare.
+    # @return [YamlEquivalent] parameter matcher.
+    #
+    # @see Expectation#with
+    #
+    # @example Actual parameter is YAML equivalent of specified +object+.
+    #   object = mock()
+    #   object.expects(:method_1).with(yaml_equivalent(1, 2, 3))
+    #   object.method_1("--- \n- 1\n- 2\n- 3\n")
+    #   # no error raised
+    #
+    # @example Actual parameter is not YAML equivalent of specified +object+.
+    #   object = mock()
+    #   object.expects(:method_1).with(yaml_equivalent(1, 2, 3))
+    #   object.method_1("--- \n- 1\n- 2\n")
+    #   # error raised, because method_1 was not called with YAML representing the specified Array
+    def yaml_equivalent(object)
+      YamlEquivalent.new(object)
+    end
+
+    # Parameter matcher which matches if actual parameter is YAML equivalent of specified object.
+    class YamlEquivalent < Base
+
+      # @private
+      def initialize(object)
+        @object = object
+      end
+
+      # @private
+      def matches?(available_parameters)
+        parameter = available_parameters.shift
+        @object == YAML.load(parameter)
+      end
+
+      # @private
+      def mocha_inspect
+        "yaml_equivalent(#{@object.mocha_inspect})"
+      end
+
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/parameters_matcher.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/parameters_matcher.rb
new file mode 100755
index 0000000..88857d2
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/parameters_matcher.rb
@@ -0,0 +1,37 @@
+require 'mocha/inspect'
+require 'mocha/parameter_matchers'
+
+module Mocha
+
+  class ParametersMatcher
+
+    def initialize(expected_parameters = [ParameterMatchers::AnyParameters.new], &matching_block)
+      @expected_parameters, @matching_block = expected_parameters, matching_block
+    end
+
+    def match?(actual_parameters = [])
+      if @matching_block
+        return @matching_block.call(*actual_parameters)
+      else
+        return parameters_match?(actual_parameters)
+      end
+    end
+
+    def parameters_match?(actual_parameters)
+      matchers.all? { |matcher| matcher.matches?(actual_parameters) } && (actual_parameters.length == 0)
+    end
+
+    def mocha_inspect
+      signature = matchers.mocha_inspect
+      signature = signature.gsub(/^\[|\]$/, '')
+      signature = signature.gsub(/^\{|\}$/, '') if matchers.length == 1
+      "(#{signature})"
+    end
+
+    def matchers
+      @expected_parameters.map { |parameter| parameter.to_matcher }
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/pretty_parameters.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/pretty_parameters.rb
new file mode 100755
index 0000000..0daeb80
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/pretty_parameters.rb
@@ -0,0 +1,28 @@
+require 'mocha/inspect'
+
+module Mocha
+
+  class PrettyParameters
+
+    def initialize(params)
+      @params = params
+      @params_string = params.mocha_inspect
+    end
+
+    def pretty
+      remove_outer_array_braces!
+      remove_outer_hash_braces!
+      @params_string
+    end
+
+    def remove_outer_array_braces!
+      @params_string = @params_string.gsub(/^\[|\]$/, '')
+    end
+
+    def remove_outer_hash_braces!
+      @params_string = @params_string.gsub(/^\{|\}$/, '') if @params.length == 1
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/receivers.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/receivers.rb
new file mode 100755
index 0000000..bbe0efe
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/receivers.rb
@@ -0,0 +1,49 @@
+module Mocha
+
+  class ObjectReceiver
+
+    def initialize(object)
+      @object = object
+    end
+
+    def mocks
+      object, mocks = @object, []
+      while object do
+        mocks << object.mocha
+        object = object.is_a?(Class) ? object.superclass : nil
+      end
+      mocks
+    end
+
+  end
+
+  class AnyInstanceReceiver
+
+    def initialize(klass)
+      @klass = klass
+    end
+
+    def mocks
+      klass, mocks = @klass, []
+      while klass do
+        mocks << klass.any_instance.mocha
+        klass = klass.superclass
+      end
+      mocks
+    end
+
+  end
+
+  class DefaultReceiver
+
+    def initialize(mock)
+      @mock = mock
+    end
+
+    def mocks
+      [@mock]
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/return_values.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/return_values.rb
new file mode 100755
index 0000000..418499f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/return_values.rb
@@ -0,0 +1,31 @@
+require 'mocha/single_return_value'
+
+module Mocha
+
+  class ReturnValues
+
+    def self.build(*values)
+      new(*values.map { |value| SingleReturnValue.new(value) })
+    end
+
+    attr_accessor :values
+
+    def initialize(*values)
+      @values = values
+    end
+
+    def next
+      case @values.length
+        when 0 then nil
+        when 1 then @values.first.evaluate
+        else @values.shift.evaluate
+      end
+    end
+
+    def +(other)
+      self.class.new(*(@values + other.values))
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/sequence.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/sequence.rb
new file mode 100755
index 0000000..2c12d3c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/sequence.rb
@@ -0,0 +1,51 @@
+module Mocha
+
+  # Used to constrain the order in which expectations can occur.
+  #
+  # @see API#sequence
+  # @see Expectation#in_sequence
+  class Sequence
+
+    # @private
+    class InSequenceOrderingConstraint
+
+      def initialize(sequence, index)
+        @sequence, @index = sequence, index
+      end
+
+      def allows_invocation_now?
+        @sequence.satisfied_to_index?(@index)
+      end
+
+      def mocha_inspect
+        "in sequence #{@sequence.mocha_inspect}"
+      end
+
+    end
+
+    # @private
+    def initialize(name)
+      @name = name
+      @expectations = []
+    end
+
+    # @private
+    def constrain_as_next_in_sequence(expectation)
+      index = @expectations.length
+      @expectations << expectation
+      expectation.add_ordering_constraint(InSequenceOrderingConstraint.new(self, index))
+    end
+
+    # @private
+    def satisfied_to_index?(index)
+      @expectations[0...index].all? { |expectation| expectation.satisfied? }
+    end
+
+    # @private
+    def mocha_inspect
+      "#{@name.mocha_inspect}"
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/setup.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/setup.rb
new file mode 100755
index 0000000..70e6a09
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/setup.rb
@@ -0,0 +1,9 @@
+require 'mocha/integration'
+
+module Mocha
+  def self.activate
+    Integration.activate
+  end
+end
+
+Mocha.activate
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/single_return_value.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/single_return_value.rb
new file mode 100755
index 0000000..63122b0
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/single_return_value.rb
@@ -0,0 +1,17 @@
+require 'mocha/is_a'
+
+module Mocha
+
+  class SingleReturnValue
+
+    def initialize(value)
+      @value = value
+    end
+
+    def evaluate
+      @value
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/single_yield.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/single_yield.rb
new file mode 100755
index 0000000..a795593
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/single_yield.rb
@@ -0,0 +1,18 @@
+module Mocha
+
+  class SingleYield
+
+    attr_reader :parameters
+
+    def initialize(*parameters)
+      @parameters = parameters
+    end
+
+    def each
+      yield(@parameters)
+    end
+
+  end
+
+end
+
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/standalone.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/standalone.rb
new file mode 100755
index 0000000..5d039c5
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/standalone.rb
@@ -0,0 +1,4 @@
+require 'mocha/api'
+require 'mocha/deprecation'
+
+Mocha::Deprecation.warning("`require 'mocha/standalone'` has been deprecated. Please use `require 'mocha/api' instead.")
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/state_machine.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/state_machine.rb
new file mode 100755
index 0000000..603c75e
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/state_machine.rb
@@ -0,0 +1,106 @@
+module Mocha
+
+  # A state machine that is used to constrain the order of invocations.
+  # An invocation can be constrained to occur when a state {#is}, or {#is_not}, active.
+  class StateMachine
+
+    # Provides a mechanism to change the state of a {StateMachine} at some point in the future.
+    class State
+
+      # @private
+      def initialize(state_machine, state)
+        @state_machine, @state = state_machine, state
+      end
+
+      # @private
+      def activate
+        @state_machine.current_state = @state
+      end
+
+      # @private
+      def active?
+        @state_machine.current_state == @state
+      end
+
+      # @private
+      def mocha_inspect
+        "#{@state_machine.name} is #{@state.mocha_inspect}"
+      end
+
+    end
+
+    # Provides the ability to determine whether a {StateMachine} is in a specified state at some point in the future.
+    class StatePredicate
+
+      # @private
+      def initialize(state_machine, state)
+        @state_machine, @state = state_machine, state
+      end
+
+      # @private
+      def active?
+        @state_machine.current_state != @state
+      end
+
+      # @private
+      def mocha_inspect
+        "#{@state_machine.name} is not #{@state.mocha_inspect}"
+      end
+
+    end
+
+    # @private
+    attr_reader :name
+
+    # @private
+    attr_accessor :current_state
+
+    # @private
+    def initialize(name)
+      @name = name
+      @current_state = nil
+    end
+
+    # Put the {StateMachine} into the state specified by +initial_state_name+.
+    #
+    # @param [String] initial_state_name name of initial state
+    # @return [StateMachine] state machine, thereby allowing invocations of other {StateMachine} methods to be chained.
+    def starts_as(initial_state_name)
+      become(initial_state_name)
+      self
+    end
+
+    # Put the {StateMachine} into the +next_state_name+.
+    #
+    # @param [String] next_state_name name of new state
+    def become(next_state_name)
+      @current_state = next_state_name
+    end
+
+    # Provides a mechanism to change the {StateMachine} into the state specified by +state_name+ at some point in the future.
+    #
+    # Or provides a mechanism to determine whether the {StateMachine} is in the state specified by +state_name+ at some point in the future.
+    #
+    # @param [String] state_name name of new state
+    # @return [State] state which, when activated, will change the {StateMachine} into the state with the specified +state_name+.
+    def is(state_name)
+      State.new(self, state_name)
+    end
+
+    # Provides a mechanism to determine whether the {StateMachine} is not in the state specified by +state_name+ at some point in the future.
+    def is_not(state_name)
+      StatePredicate.new(self, state_name)
+    end
+
+    # @private
+    def mocha_inspect
+      if @current_state
+        "#{@name} is #{@current_state.mocha_inspect}"
+      else
+        "#{@name} has no current state"
+      end
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/stubbing_error.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/stubbing_error.rb
new file mode 100755
index 0000000..9d15552
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/stubbing_error.rb
@@ -0,0 +1,19 @@
+require 'mocha/backtrace_filter'
+
+module Mocha
+
+  # Exception raised when stubbing a particular method is not allowed.
+  #
+  # @see Configuration.prevent
+  class StubbingError < StandardError
+
+    # @private
+    def initialize(message = nil, backtrace = [])
+      super(message)
+      filter = BacktraceFilter.new
+      set_backtrace(filter.filtered(backtrace))
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/test_unit.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/test_unit.rb
new file mode 100755
index 0000000..6c6c687
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/test_unit.rb
@@ -0,0 +1,3 @@
+require "mocha/integration/test_unit"
+
+Mocha::Integration::TestUnit.activate
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/thrower.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/thrower.rb
new file mode 100755
index 0000000..c954be9
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/thrower.rb
@@ -0,0 +1,15 @@
+module Mocha
+
+  class Thrower
+
+    def initialize(tag, object = nil)
+      @tag, @object = tag, object
+    end
+
+    def evaluate
+      throw @tag, @object
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/unexpected_invocation.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/unexpected_invocation.rb
new file mode 100755
index 0000000..f3f41fe
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/unexpected_invocation.rb
@@ -0,0 +1,26 @@
+module Mocha
+
+  # Exception raised when an unexpected method is invoked
+  class UnexpectedInvocation
+
+    # @private
+    def initialize(mock, symbol, *arguments)
+      @mock, @symbol, @arguments = mock, symbol, arguments
+    end
+
+    # @private
+    def full_description
+      method_matcher = MethodMatcher.new(@symbol)
+      parameters_matcher = ParametersMatcher.new(@arguments)
+      method_signature = "#{@mock.mocha_inspect}.#{method_matcher.mocha_inspect}#{parameters_matcher.mocha_inspect}"
+      "unexpected invocation: #{method_signature}\n"
+    end
+
+    # @private
+    def short_description
+      "unexpected invocation: #{@symbol}(#{@arguments.join(', ')})"
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/version.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/version.rb
new file mode 100755
index 0000000..fc0c829
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/version.rb
@@ -0,0 +1,3 @@
+module Mocha
+  VERSION = "1.1.0"
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha/yield_parameters.rb b/app/server/vendor/mocha-1.1.0/lib/mocha/yield_parameters.rb
new file mode 100755
index 0000000..4196c58
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha/yield_parameters.rb
@@ -0,0 +1,31 @@
+require 'mocha/no_yields'
+require 'mocha/single_yield'
+require 'mocha/multiple_yields'
+
+module Mocha
+
+  class YieldParameters
+
+    def initialize
+      @parameter_groups = []
+    end
+
+    def next_invocation
+      case @parameter_groups.length
+        when 0 then NoYields.new
+        when 1 then @parameter_groups.first
+        else @parameter_groups.shift
+      end
+    end
+
+    def add(*parameters)
+      @parameter_groups << SingleYield.new(*parameters)
+    end
+
+    def multiple_add(*parameter_groups)
+      @parameter_groups << MultipleYields.new(*parameter_groups)
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/lib/mocha_standalone.rb b/app/server/vendor/mocha-1.1.0/lib/mocha_standalone.rb
new file mode 100755
index 0000000..ebf9e24
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/lib/mocha_standalone.rb
@@ -0,0 +1,4 @@
+require 'mocha/api'
+require 'mocha/deprecation'
+
+Mocha::Deprecation.warning("`require 'mocha_standalone'` has been deprecated. Please use `require 'mocha/api' instead.")
diff --git a/app/server/vendor/mocha-1.1.0/mocha.gemspec b/app/server/vendor/mocha-1.1.0/mocha.gemspec
new file mode 100755
index 0000000..32ad409
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/mocha.gemspec
@@ -0,0 +1,53 @@
+# -*- encoding: utf-8 -*-
+lib = File.expand_path('../lib/', __FILE__)
+$LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
+require "mocha/version"
+
+Gem::Specification.new do |s|
+  s.name = "mocha"
+  s.version = Mocha::VERSION
+
+  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+  s.authors = ["James Mead"]
+  s.description = "Mocking and stubbing library with JMock/SchMock syntax, which allows mocking and stubbing of methods on real (non-mock) classes."
+  s.email = "mocha-developer at googlegroups.com"
+
+  s.files = `git ls-files`.split("\n")
+  s.files.delete(".travis.yml")
+  s.files.delete(".gitignore")
+
+  s.homepage = "http://gofreerange.com/mocha/docs"
+  s.require_paths = ["lib"]
+  s.rubyforge_project = "mocha"
+  s.summary = "Mocking and stubbing library"
+  s.has_rdoc = "yard"
+
+  s.add_dependency("metaclass", "~> 0.0.1")
+  if s.respond_to? :specification_version then
+    current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+    s.specification_version = 3
+
+    if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+      s.add_development_dependency("rake", ">= 0")
+      s.add_development_dependency("introspection", "~> 0.0.1")
+      unless ENV["MOCHA_NO_DOCS"]
+        s.add_development_dependency("yard")
+        s.add_development_dependency("redcarpet", "~> 1")
+      end
+    else
+      s.add_dependency("rake", ">= 0")
+      s.add_dependency("introspection", "~> 0.0.1")
+      unless ENV["MOCHA_NO_DOCS"]
+        s.add_dependency("yard")
+        s.add_dependency("redcarpet", "~> 1")
+      end
+    end
+  else
+    s.add_dependency("rake", ">= 0")
+    s.add_dependency("introspection", "~> 0.0.1")
+    unless ENV["MOCHA_NO_DOCS"]
+      s.add_dependency("yard")
+      s.add_dependency("redcarpet", "~> 1")
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/acceptance_test_helper.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/acceptance_test_helper.rb
new file mode 100755
index 0000000..5698d4f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/acceptance_test_helper.rb
@@ -0,0 +1,41 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'test_runner'
+require 'mocha/configuration'
+require 'introspection'
+
+module AcceptanceTest
+
+  class FakeLogger
+
+    attr_reader :warnings
+
+    def initialize
+      @warnings = []
+    end
+
+    def warn(message)
+      @warnings << message
+    end
+
+  end
+
+  attr_reader :logger
+
+  include TestRunner
+
+  def setup_acceptance_test
+    Mocha::Configuration.reset_configuration
+    @logger = FakeLogger.new
+    mockery = Mocha::Mockery.instance
+    @original_logger = mockery.logger
+    mockery.logger = @logger
+  end
+
+  def teardown_acceptance_test
+    Mocha::Configuration.reset_configuration
+    Mocha::Mockery.instance.logger = @original_logger
+  end
+
+  include Introspection::Assertions
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/bug_18914_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/bug_18914_test.rb
new file mode 100755
index 0000000..89cfe11
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/bug_18914_test.rb
@@ -0,0 +1,43 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class Bug18914Test < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  class AlwaysEql
+
+    def my_method
+      true
+    end
+
+    def ==(o)
+      true
+    end
+
+    def eql?(o)
+      true
+    end
+
+  end
+
+  def test_should_not_allow_stubbing_of_non_mock_instance_disrupted_by_legitimate_overriding_of_eql_method
+
+    always_eql_1 = AlwaysEql.new
+    always_eql_1.stubs(:my_method).returns(false)
+
+    always_eql_2 = AlwaysEql.new
+    always_eql_2.stubs(:my_method).returns(false)
+
+    assert_equal false, always_eql_2.my_method
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/bug_21465_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/bug_21465_test.rb
new file mode 100755
index 0000000..de603d9
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/bug_21465_test.rb
@@ -0,0 +1,34 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class Bug21465Test < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_allow_expected_method_name_to_be_a_string
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects('wibble')
+      mock.wibble
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbed_method_name_to_be_a_string
+    test_result = run_as_test do
+      mock = mock()
+      mock.stubs('wibble')
+      mock.wibble
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/bug_21563_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/bug_21563_test.rb
new file mode 100755
index 0000000..654186b
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/bug_21563_test.rb
@@ -0,0 +1,25 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class Bug21563Test < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_allow_stubbing_of_verified_method
+    test_result = run_as_test do
+      object = Object.new
+      object.stubs(:verified?).returns(false)
+      assert !object.verified?
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/exception_rescue_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/exception_rescue_test.rb
new file mode 100755
index 0000000..55ccd9e
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/exception_rescue_test.rb
@@ -0,0 +1,55 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class ExceptionRescueTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_unexpected_invocation_exception_is_not_caught_by_standard_rescue
+    test_result = run_as_test do
+      mock = mock('mock')
+      begin
+        mock.some_method
+      rescue => e
+        flunk "should not rescue #{e.class}"
+      end
+    end
+    assert_failed(test_result)
+    assert_equal "unexpected invocation: #<Mock:mock>.some_method()", test_result.failure_message_lines[0]
+  end
+
+  def test_invocation_never_expected_exception_is_not_caught_by_standard_rescue
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:some_method).never
+      begin
+        mock.some_method
+      rescue => e
+        flunk "should not rescue #{e.class}"
+      end
+    end
+    assert_failed(test_result)
+    assert_equal "unexpected invocation: #<Mock:mock>.some_method()", test_result.failure_message_lines[0]
+  end
+
+  def test_unsatisfied_expectation_exception_is_not_caught_by_standard_rescue
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:some_method)
+    end
+    assert_failed(test_result)
+    assert_equal [
+      "not all expectations were satisfied",
+      "unsatisfied expectations:",
+      "- expected exactly once, not yet invoked: #<Mock:mock>.some_method(any_parameters)"
+    ], test_result.failure_message_lines
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/expectations_on_multiple_methods_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/expectations_on_multiple_methods_test.rb
new file mode 100755
index 0000000..63bd5fe
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/expectations_on_multiple_methods_test.rb
@@ -0,0 +1,55 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class ExpectationsOnMultipleMethodsTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_expect_calls_to_multiple_methods
+    instance = Class.new do
+      def my_instance_method_1
+        :original_return_value_1
+      end
+      def my_instance_method_2
+        :original_return_value_2
+      end
+    end.new
+    test_result = run_as_test do
+      instance.expects(
+        :my_instance_method_1 => :new_return_value_1,
+        :my_instance_method_2 => :new_return_value_2
+      )
+      assert_equal :new_return_value_1, instance.my_instance_method_1
+      assert_equal :new_return_value_2, instance.my_instance_method_2
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_stub_calls_to_multiple_methods
+    instance = Class.new do
+      def my_instance_method_1
+        :original_return_value_1
+      end
+      def my_instance_method_2
+        :original_return_value_2
+      end
+    end.new
+    test_result = run_as_test do
+      instance.stubs(
+        :my_instance_method_1 => :new_return_value_1,
+        :my_instance_method_2 => :new_return_value_2
+      )
+      assert_equal :new_return_value_1, instance.my_instance_method_1
+      assert_equal :new_return_value_2, instance.my_instance_method_2
+    end
+    assert_passed(test_result)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/expected_invocation_count_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/expected_invocation_count_test.rb
new file mode 100755
index 0000000..304b85a
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/expected_invocation_count_test.rb
@@ -0,0 +1,232 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class ExpectedInvocationCountTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_pass_if_method_is_never_expected_and_is_never_called
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).never
+      0.times { mock.method }
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_fail_fast_if_method_is_never_expected_but_is_called_once
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).never
+      1.times { mock.method }
+    end
+    assert_failed(test_result)
+    assert_equal [
+      "unexpected invocation: #<Mock:mock>.method()",
+      "unsatisfied expectations:",
+      "- expected never, invoked once: #<Mock:mock>.method(any_parameters)"
+    ], test_result.failure_message_lines
+  end
+
+  def test_should_pass_if_method_is_expected_twice_and_is_called_twice
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).twice
+      2.times { mock.method }
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_fail_if_method_is_expected_twice_but_is_called_once
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).twice
+      1.times { mock.method }
+    end
+    assert_failed(test_result)
+    assert_equal [
+      "not all expectations were satisfied",
+      "unsatisfied expectations:",
+      "- expected exactly twice, invoked once: #<Mock:mock>.method(any_parameters)"
+    ], test_result.failure_message_lines
+  end
+
+  def test_should_fail_fast_if_method_is_expected_twice_but_is_called_three_times
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).twice
+      3.times { mock.method }
+    end
+    assert_failed(test_result)
+    assert_equal [
+      "unexpected invocation: #<Mock:mock>.method()",
+      "unsatisfied expectations:",
+      "- expected exactly twice, invoked 3 times: #<Mock:mock>.method(any_parameters)"
+    ], test_result.failure_message_lines
+  end
+
+  def test_should_pass_if_method_is_expected_between_two_and_four_times_and_is_called_twice
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).times(2..4)
+      2.times { mock.method }
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_pass_if_method_is_expected_between_two_and_four_times_and_is_called_three_times
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).times(2..4)
+      3.times { mock.method }
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_pass_if_method_is_expected_between_two_and_four_times_and_is_called_four_times
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).times(2..4)
+      4.times { mock.method }
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_fail_if_method_is_expected_between_two_and_four_times_and_is_called_once
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).times(2..4)
+      1.times { mock.method }
+    end
+    assert_failed(test_result)
+    assert_equal [
+      "not all expectations were satisfied",
+      "unsatisfied expectations:",
+      "- expected between 2 and 4 times, invoked once: #<Mock:mock>.method(any_parameters)"
+    ], test_result.failure_message_lines
+  end
+
+  def test_should_fail_fast_if_method_is_expected_between_two_and_four_times_and_is_called_five_times
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).times(2..4)
+      5.times { mock.method }
+    end
+    assert_failed(test_result)
+    assert_equal [
+      "unexpected invocation: #<Mock:mock>.method()",
+      "unsatisfied expectations:",
+      "- expected between 2 and 4 times, invoked 5 times: #<Mock:mock>.method(any_parameters)"
+    ], test_result.failure_message_lines
+  end
+
+  def test_should_pass_if_method_is_expected_at_least_once_and_is_called_once
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).at_least_once
+      1.times { mock.method }
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_pass_if_method_is_expected_at_least_once_and_is_called_twice
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).at_least_once
+      2.times { mock.method }
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_fail_if_method_is_expected_at_least_once_but_is_never_called
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).at_least_once
+      0.times { mock.method }
+    end
+    assert_failed(test_result)
+    assert_equal [
+      "not all expectations were satisfied",
+      "unsatisfied expectations:",
+      "- expected at least once, not yet invoked: #<Mock:mock>.method(any_parameters)"
+    ], test_result.failure_message_lines
+  end
+
+  def test_should_pass_if_method_is_expected_at_most_once_and_is_never_called
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).at_most_once
+      0.times { mock.method }
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_pass_if_method_is_expected_at_most_once_and_called_once
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).at_most_once
+      1.times { mock.method }
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_fail_fast_if_method_is_expected_at_most_once_but_is_called_twice
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).at_most_once
+      2.times { mock.method }
+    end
+    assert_failed(test_result)
+    assert_equal [
+      "unexpected invocation: #<Mock:mock>.method()",
+      "unsatisfied expectations:",
+      "- expected at most once, invoked twice: #<Mock:mock>.method(any_parameters)"
+    ], test_result.failure_message_lines
+  end
+
+  def test_should_pass_if_method_is_never_expected_and_is_never_called_even_if_everything_is_stubbed
+    test_result = run_as_test do
+      stub = stub_everything('stub')
+      stub.expects(:method).never
+      0.times { stub.method }
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_fail_fast_if_method_is_never_expected_but_is_called_once_even_if_everything_is_stubbed
+    test_result = run_as_test do
+      stub = stub_everything('stub')
+      stub.expects(:method).never
+      1.times { stub.method }
+    end
+    assert_failed(test_result)
+    assert_equal [
+      "unexpected invocation: #<Mock:stub>.method()",
+      "unsatisfied expectations:",
+      "- expected never, invoked once: #<Mock:stub>.method(any_parameters)"
+    ], test_result.failure_message_lines
+  end
+
+  def test_should_fail_fast_if_there_is_no_matching_expectation
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method).with(1)
+      1.times { mock.method }
+    end
+    assert_failed(test_result)
+    assert_equal [
+      "unexpected invocation: #<Mock:mock>.method()",
+      "unsatisfied expectations:",
+      "- expected exactly once, not yet invoked: #<Mock:mock>.method(1)"
+    ], test_result.failure_message_lines
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/failure_messages_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/failure_messages_test.rb
new file mode 100755
index 0000000..7096461
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/failure_messages_test.rb
@@ -0,0 +1,64 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class FailureMessagesTest < Mocha::TestCase
+
+  OBJECT_ADDRESS_PATTERN = '0x[0-9A-Fa-f]{1,12}'
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  class Foo; end
+
+  def test_should_display_class_name_when_expectation_was_on_class
+    test_result = run_as_test do
+      Foo.expects(:bar)
+    end
+    assert_match Regexp.new('FailureMessagesTest::Foo'), test_result.failures[0].message
+  end
+
+  def test_should_display_class_name_and_address_when_expectation_was_on_instance
+    test_result = run_as_test do
+      Foo.new.expects(:bar)
+    end
+    assert_match Regexp.new("#<FailureMessagesTest::Foo:#{OBJECT_ADDRESS_PATTERN}>"), test_result.failures[0].message
+  end
+
+  def test_should_display_class_name_and_any_instance_prefix_when_expectation_was_on_any_instance
+    test_result = run_as_test do
+      Foo.any_instance.expects(:bar)
+    end
+    assert_match Regexp.new('#<AnyInstance:FailureMessagesTest::Foo>'), test_result.failures[0].message
+  end
+
+  def test_should_display_mock_name_when_expectation_was_on_named_mock
+    test_result = run_as_test do
+      foo = mock('foo')
+      foo.expects(:bar)
+    end
+    assert_match Regexp.new('#<Mock:foo>'), test_result.failures[0].message
+  end
+
+  def test_should_display_mock_address_when_expectation_was_on_unnamed_mock
+    test_result = run_as_test do
+      foo = mock()
+      foo.expects(:bar)
+    end
+    assert_match Regexp.new("#<Mock:#{OBJECT_ADDRESS_PATTERN}>"), test_result.failures[0].message
+  end
+
+  def test_should_display_string_when_expectation_was_on_string
+    test_result = run_as_test do
+      'Foo'.expects(:bar)
+    end
+    assert_match Regexp.new("'Foo'"), test_result.failures[0].message
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/issue_65_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/issue_65_test.rb
new file mode 100755
index 0000000..51addee
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/issue_65_test.rb
@@ -0,0 +1,63 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class Issue65Test < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_expectations_on_class_methods_on_same_class_should_be_verified_in_consecutive_tests
+    klass = Class.new do
+      def self.foo; end
+      def self.bar; end
+    end
+    test_1 = run_as_test do
+      klass.expects(:foo)
+      klass.foo
+    end
+    assert_passed(test_1)
+    test_2 = run_as_test do
+      klass.expects(:bar)
+    end
+    assert_failed(test_2)
+  end
+
+  def test_expectations_on_any_instance_methods_on_same_class_should_be_verified_in_consecutive_tests
+    klass = Class.new do
+      def foo; end
+      def bar; end
+    end
+    test_1 = run_as_test do
+      klass.any_instance.expects(:foo)
+      klass.new.foo
+    end
+    assert_passed(test_1)
+    test_2 = run_as_test do
+      klass.any_instance.expects(:bar)
+    end
+    assert_failed(test_2)
+  end
+
+  def test_expectations_on_instance_methods_on_same_object_should_be_verified_in_consecutive_tests
+    instance = Class.new do
+      def foo; end
+      def bar; end
+    end.new
+    test_1 = run_as_test do
+      instance.expects(:foo)
+      instance.foo
+    end
+    assert_passed(test_1)
+    test_2 = run_as_test do
+      instance.expects(:bar)
+    end
+    assert_failed(test_2)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/issue_70_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/issue_70_test.rb
new file mode 100755
index 0000000..e9915f5
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/issue_70_test.rb
@@ -0,0 +1,55 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class Issue70Test < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_stub_expectations_instance_method
+    instance = Class.new do
+      def expectations
+        :original_return_value
+      end
+    end.new
+    test_result = run_as_test do
+      instance.stubs(:expectations).returns(:stubbed_return_value)
+      assert_equal :stubbed_return_value, instance.expectations
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_stub_expectations_class_method
+    klass = Class.new do
+      def self.expectations
+        :original_return_value
+      end
+    end
+    test_result = run_as_test do
+      klass.stubs(:expectations).returns(:stubbed_return_value)
+      assert_equal :stubbed_return_value, klass.expectations
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_stub_expectations_any_instance_method
+    klass = Class.new do
+      def expectations
+        :original_return_value
+      end
+    end
+    instance = klass.new
+    test_result = run_as_test do
+      klass.any_instance.stubs(:expectations).returns(:stubbed_return_value)
+      assert_equal :stubbed_return_value, instance.expectations
+    end
+    assert_passed(test_result)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/mocha_example_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/mocha_example_test.rb
new file mode 100755
index 0000000..ceddf3b
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/mocha_example_test.rb
@@ -0,0 +1,98 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/setup'
+
+class MochaExampleTest < Mocha::TestCase
+
+  class Rover
+
+    def initialize(left_track, right_track, steps_per_metre, steps_per_degree)
+      @left_track, @right_track, @steps_per_metre, @steps_per_degree = left_track, right_track, steps_per_metre, steps_per_degree
+    end
+
+    def forward(metres)
+      @left_track.step(metres * @steps_per_metre)
+      @right_track.step(metres * @steps_per_metre)
+      wait
+    end
+
+    def backward(metres)
+      forward(-metres)
+    end
+
+    def left(degrees)
+      @left_track.step(-degrees * @steps_per_degree)
+      @right_track.step(+degrees * @steps_per_degree)
+      wait
+    end
+
+    def right(degrees)
+      left(-degrees)
+    end
+
+    def wait
+      while (@left_track.moving? or @right_track.moving?); end
+    end
+
+  end
+
+  def test_should_step_both_tracks_forward_ten_steps
+    left_track = mock('left_track')
+    right_track = mock('right_track')
+    steps_per_metre = 5
+    rover = Rover.new(left_track, right_track, steps_per_metre, nil)
+
+    left_track.expects(:step).with(10)
+    right_track.expects(:step).with(10)
+
+    left_track.stubs(:moving?).returns(false)
+    right_track.stubs(:moving?).returns(false)
+
+    rover.forward(2)
+  end
+
+  def test_should_step_both_tracks_backward_ten_steps
+    left_track = mock('left_track')
+    right_track = mock('right_track')
+    steps_per_metre = 5
+    rover = Rover.new(left_track, right_track, steps_per_metre, nil)
+
+    left_track.expects(:step).with(-10)
+    right_track.expects(:step).with(-10)
+
+    left_track.stubs(:moving?).returns(false)
+    right_track.stubs(:moving?).returns(false)
+
+    rover.backward(2)
+  end
+
+  def test_should_step_left_track_forwards_five_steps_and_right_track_backwards_five_steps
+    left_track = mock('left_track')
+    right_track = mock('right_track')
+    steps_per_degree = 5.0 / 90.0
+    rover = Rover.new(left_track, right_track, nil, steps_per_degree)
+
+    left_track.expects(:step).with(+5)
+    right_track.expects(:step).with(-5)
+
+    left_track.stubs(:moving?).returns(false)
+    right_track.stubs(:moving?).returns(false)
+
+    rover.right(90)
+  end
+
+  def test_should_step_left_track_backwards_five_steps_and_right_track_forwards_five_steps
+    left_track = mock('left_track')
+    right_track = mock('right_track')
+    steps_per_degree = 5.0 / 90.0
+    rover = Rover.new(left_track, right_track, nil, steps_per_degree)
+
+    left_track.expects(:step).with(-5)
+    right_track.expects(:step).with(+5)
+
+    left_track.stubs(:moving?).returns(false)
+    right_track.stubs(:moving?).returns(false)
+
+    rover.left(90)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/mocha_test_result_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/mocha_test_result_test.rb
new file mode 100755
index 0000000..368f46f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/mocha_test_result_test.rb
@@ -0,0 +1,84 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+require 'execution_point'
+
+class MochaTestResultTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_include_expectation_verification_in_assertion_count
+    test_result = run_as_test do
+      object = mock()
+      object.expects(:message)
+      object.message
+    end
+    assert_equal 1, test_result.assertion_count
+  end
+
+  def test_should_include_assertions_in_assertion_count
+    test_result = run_as_test do
+      assert true
+    end
+    assert_equal 1, test_result.assertion_count
+  end
+
+  def test_should_not_include_stubbing_expectation_verification_in_assertion_count
+    test_result = run_as_test do
+      object = mock()
+      object.stubs(:message)
+      object.message
+    end
+    assert_equal 0, test_result.assertion_count
+  end
+
+  def test_should_include_expectation_verification_failure_in_failure_count
+    test_result = run_as_test do
+      object = mock()
+      object.expects(:message)
+    end
+    assert_equal 1, test_result.failure_count
+  end
+
+  def test_should_include_unexpected_verification_failure_in_failure_count
+    test_result = run_as_test do
+      object = mock()
+      object.message
+    end
+    assert_equal 1, test_result.failure_count
+  end
+
+  def test_should_include_assertion_failure_in_failure_count
+    test_result = run_as_test do
+      flunk
+    end
+    assert_equal 1, test_result.failure_count
+  end
+
+  def test_should_display_backtrace_indicating_line_number_where_unexpected_method_was_called
+    execution_point = nil
+    test_result = run_as_test do
+      object = mock()
+      execution_point = ExecutionPoint.current; object.message
+    end
+    assert_equal 1, test_result.failure_count
+    assert_equal execution_point, ExecutionPoint.new(test_result.failures[0].location)
+  end
+
+  def test_should_display_backtrace_indicating_line_number_where_failing_assertion_was_called
+    execution_point = nil
+    test_result = run_as_test do
+      execution_point = ExecutionPoint.current; flunk
+    end
+    assert_equal 1, test_result.failure_count
+    assert_equal execution_point, ExecutionPoint.new(test_result.failures[0].location)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/mock_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/mock_test.rb
new file mode 100755
index 0000000..7ae7bba
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/mock_test.rb
@@ -0,0 +1,100 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class MockTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_build_mock_and_explicitly_add_an_expectation_which_is_satisfied
+    test_result = run_as_test do
+      foo = mock()
+      foo.expects(:bar)
+      foo.bar
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_build_mock_and_explicitly_add_an_expectation_which_is_not_satisfied
+    test_result = run_as_test do
+      foo = mock()
+      foo.expects(:bar)
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_build_named_mock_and_explicitly_add_an_expectation_which_is_satisfied
+    test_result = run_as_test do
+      foo = mock('foo')
+      foo.expects(:bar)
+      foo.bar
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_build_named_mock_and_explicitly_add_an_expectation_which_is_not_satisfied
+    test_result = run_as_test do
+      foo = mock('foo')
+      foo.expects(:bar)
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_build_mock_incorporating_two_expectations_which_are_satisifed
+    test_result = run_as_test do
+      foo = mock(:bar => 'bar', :baz => 'baz')
+      foo.bar
+      foo.baz
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_build_mock_incorporating_two_expectations_the_first_of_which_is_not_satisifed
+    test_result = run_as_test do
+      foo = mock(:bar => 'bar', :baz => 'baz')
+      foo.baz
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_build_mock_incorporating_two_expectations_the_second_of_which_is_not_satisifed
+    test_result = run_as_test do
+      foo = mock(:bar => 'bar', :baz => 'baz')
+      foo.bar
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_build_named_mock_incorporating_two_expectations_which_are_satisifed
+    test_result = run_as_test do
+      foo = mock('foo', :bar => 'bar', :baz => 'baz')
+      foo.bar
+      foo.baz
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_build_named_mock_incorporating_two_expectations_the_first_of_which_is_not_satisifed
+    test_result = run_as_test do
+      foo = mock('foo', :bar => 'bar', :baz => 'baz')
+      foo.baz
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_build_named_mock_incorporating_two_expectations_the_second_of_which_is_not_satisifed
+    test_result = run_as_test do
+      foo = mock('foo', :bar => 'bar', :baz => 'baz')
+      foo.bar
+    end
+    assert_failed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/mock_with_initializer_block_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/mock_with_initializer_block_test.rb
new file mode 100755
index 0000000..908061c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/mock_with_initializer_block_test.rb
@@ -0,0 +1,51 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class MockWithInitializerBlockTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_expect_two_method_invocations_and_receive_both_of_them
+    test_result = run_as_test do
+      mock = mock() do
+        expects(:method_1)
+        expects(:method_2)
+      end
+      mock.method_1
+      mock.method_2
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_expect_two_method_invocations_but_receive_only_one_of_them
+    test_result = run_as_test do
+      mock = mock() do
+        expects(:method_1)
+        expects(:method_2)
+      end
+      mock.method_1
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_stub_methods
+    test_result = run_as_test do
+      mock = mock() do
+        stubs(:method_1).returns(1)
+        stubs(:method_2).returns(2)
+      end
+      assert_equal 1, mock.method_1
+      assert_equal 2, mock.method_2
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/mocked_methods_dispatch_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/mocked_methods_dispatch_test.rb
new file mode 100755
index 0000000..ba943f6
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/mocked_methods_dispatch_test.rb
@@ -0,0 +1,78 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class MockedMethodDispatchTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_find_latest_matching_expectation
+    test_result = run_as_test do
+      mock = mock()
+      mock.stubs(:method).returns(1)
+      mock.stubs(:method).returns(2)
+      assert_equal 2, mock.method
+      assert_equal 2, mock.method
+      assert_equal 2, mock.method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_find_latest_expectation_which_has_not_stopped_matching
+    test_result = run_as_test do
+      mock = mock()
+      mock.stubs(:method).returns(1)
+      mock.stubs(:method).once.returns(2)
+      assert_equal 2, mock.method
+      assert_equal 1, mock.method
+      assert_equal 1, mock.method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_keep_finding_later_stub_and_so_never_satisfy_earlier_expectation
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).returns(1)
+      mock.stubs(:method).returns(2)
+      assert_equal 2, mock.method
+      assert_equal 2, mock.method
+      assert_equal 2, mock.method
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_find_later_expectation_until_it_stops_matching_then_find_earlier_stub
+    test_result = run_as_test do
+      mock = mock()
+      mock.stubs(:method).returns(1)
+      mock.expects(:method).returns(2)
+      assert_equal 2, mock.method
+      assert_equal 1, mock.method
+      assert_equal 1, mock.method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_find_latest_expectation_with_range_of_expected_invocation_count_which_has_not_stopped_matching
+    test_result = run_as_test do
+      mock = mock()
+      mock.stubs(:method).returns(1)
+      mock.stubs(:method).times(2..3).returns(2)
+      assert_equal 2, mock.method
+      assert_equal 2, mock.method
+      assert_equal 2, mock.method
+      assert_equal 1, mock.method
+      assert_equal 1, mock.method
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/multiple_expectations_failure_message_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/multiple_expectations_failure_message_test.rb
new file mode 100755
index 0000000..567c121
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/multiple_expectations_failure_message_test.rb
@@ -0,0 +1,68 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class FailureMessageTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_include_unexpected_invocation_in_unsatisfied_expectation_message
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method_one).once
+      2.times { mock.method_one }
+    end
+    assert_failed(test_result)
+    assert_equal [
+      "unexpected invocation: #<Mock:mock>.method_one()",
+      "unsatisfied expectations:",
+      "- expected exactly once, invoked twice: #<Mock:mock>.method_one(any_parameters)"
+     ], test_result.failure_message_lines
+  end
+
+  def test_should_report_satisfied_expectations_as_well_as_unsatisfied_expectations
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method_one).once
+      mock.expects(:method_two).twice
+      1.times { mock.method_one }
+      1.times { mock.method_two }
+    end
+    assert_failed(test_result)
+    assert_equal [
+      "not all expectations were satisfied",
+       "unsatisfied expectations:",
+       "- expected exactly twice, invoked once: #<Mock:mock>.method_two(any_parameters)",
+       "satisfied expectations:",
+       "- expected exactly once, invoked once: #<Mock:mock>.method_one(any_parameters)"
+    ], test_result.failure_message_lines
+  end
+
+  def test_should_report_multiple_satisfied_expectations
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.expects(:method_one).once
+      mock.expects(:method_two).twice
+      mock.expects(:method_three).times(3)
+      1.times { mock.method_one }
+      2.times { mock.method_two }
+      2.times { mock.method_three }
+    end
+    assert_failed(test_result)
+    assert_equal [
+      "not all expectations were satisfied",
+      "unsatisfied expectations:",
+      "- expected exactly 3 times, invoked twice: #<Mock:mock>.method_three(any_parameters)",
+      "satisfied expectations:",
+      "- expected exactly twice, invoked twice: #<Mock:mock>.method_two(any_parameters)",
+      "- expected exactly once, invoked once: #<Mock:mock>.method_one(any_parameters)"
+     ], test_result.failure_message_lines
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/optional_parameters_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/optional_parameters_test.rb
new file mode 100755
index 0000000..0f5aed3
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/optional_parameters_test.rb
@@ -0,0 +1,70 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class OptionalParameterMatcherTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_pass_if_all_required_parameters_match_and_no_optional_parameters_are_supplied
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(1, 2, optionally(3, 4))
+      mock.method(1, 2)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_pass_if_all_required_and_optional_parameters_match_and_some_optional_parameters_are_supplied
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(1, 2, optionally(3, 4))
+      mock.method(1, 2, 3)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_pass_if_all_required_and_optional_parameters_match_and_all_optional_parameters_are_supplied
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(1, 2, optionally(3, 4))
+      mock.method(1, 2, 3, 4)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_fail_if_all_required_and_optional_parameters_match_but_too_many_optional_parameters_are_supplied
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(1, 2, optionally(3, 4))
+      mock.method(1, 2, 3, 4, 5)
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_fail_if_all_required_parameters_match_but_some_optional_parameters_do_not_match
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(1, 2, optionally(3, 4))
+      mock.method(1, 2, 4)
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_fail_if_all_required_parameters_match_but_no_optional_parameters_match
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(1, 2, optionally(3, 4))
+      mock.method(1, 2, 4, 5)
+    end
+    assert_failed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/parameter_matcher_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/parameter_matcher_test.rb
new file mode 100755
index 0000000..70610a2
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/parameter_matcher_test.rb
@@ -0,0 +1,337 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class ParameterMatcherTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_match_hash_parameter_with_specified_key
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_key(:key_1))
+      mock.method(:key_1 => 'value_1', :key_2 => 'value_2')
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_not_match_hash_parameter_with_specified_key
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_key(:key_1))
+      mock.method(:key_2 => 'value_2')
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_match_hash_parameter_with_specified_value
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_value('value_1'))
+      mock.method(:key_1 => 'value_1', :key_2 => 'value_2')
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_not_match_hash_parameter_with_specified_value
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_value('value_1'))
+      mock.method(:key_2 => 'value_2')
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_match_hash_parameter_with_specified_key_value_pair
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_entry(:key_1, 'value_1'))
+      mock.method(:key_1 => 'value_1', :key_2 => 'value_2')
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_not_match_hash_parameter_with_specified_key_value_pair
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_entry(:key_1, 'value_2'))
+      mock.method(:key_1 => 'value_1', :key_2 => 'value_2')
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_match_hash_parameter_with_specified_hash_entry
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_entry(:key_1 => 'value_1'))
+      mock.method(:key_1 => 'value_1', :key_2 => 'value_2')
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_not_match_hash_parameter_with_specified_hash_entry
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_entry(:key_1 => 'value_2'))
+      mock.method(:key_1 => 'value_1', :key_2 => 'value_2')
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_match_hash_parameter_with_specified_entries
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_entries(:key_1 => 'value_1', :key_2 => 'value_2'))
+      mock.method(:key_1 => 'value_1', :key_2 => 'value_2', :key_3 => 'value_3')
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_not_match_hash_parameter_with_specified_entries
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_entries(:key_1 => 'value_1', :key_2 => 'value_2'))
+      mock.method(:key_1 => 'value_1', :key_2 => 'value_3')
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_match_parameter_that_matches_regular_expression
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(regexp_matches(/meter/))
+      mock.method('this parameter should match')
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_not_match_parameter_that_does_not_match_regular_expression
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(regexp_matches(/something different/))
+      mock.method('this parameter should not match')
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_match_hash_parameter_with_specified_entries_using_nested_matchers
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_entries(:key_1 => regexp_matches(/value_1/), kind_of(Symbol) => 'value_2'))
+      mock.method(:key_1 => 'value_1', :key_2 => 'value_2', :key_3 => 'value_3')
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_not_match_hash_parameter_with_specified_entries_using_nested_matchers
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_entries(:key_1 => regexp_matches(/value_1/), kind_of(String) => 'value_2'))
+      mock.method(:key_1 => 'value_2', :key_2 => 'value_3')
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_match_parameter_that_matches_any_value
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(any_of('value_1', 'value_2')).times(2)
+      mock.method('value_1')
+      mock.method('value_2')
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_not_match_parameter_that_does_not_match_any_value
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(any_of('value_1', 'value_2'))
+      mock.method('value_3')
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_match_parameter_that_matches_any_of_the_given_matchers
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_key(:foo) | has_key(:bar)).times(2)
+      mock.method(:foo => 'fooval')
+      mock.method(:bar => 'barval')
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_not_match_parameter_that_does_not_match_any_of_the_given_matchers
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_key(:foo) | has_key(:bar))
+      mock.method(:baz => 'bazval')
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_match_parameter_that_matches_all_values
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(all_of('value_1', 'value_1'))
+      mock.method('value_1')
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_not_match_parameter_that_does_not_match_all_values
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(all_of('value_1', 'value_2'))
+      mock.method('value_1')
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_match_parameter_that_matches_all_matchers
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_key(:foo) & has_key(:bar))
+      mock.method(:foo => 'fooval', :bar => 'barval')
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_not_match_parameter_that_does_not_match_all_matchers
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_key(:foo) & has_key(:bar))
+      mock.method(:foo => 'fooval', :baz => 'bazval')
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_match_parameter_that_responds_with_specified_value
+    klass = Class.new do
+      def quack
+        'quack'
+      end
+    end
+    duck = klass.new
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(responds_with(:quack, 'quack'))
+      mock.method(duck)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_not_match_parameter_that_does_not_respond_with_specified_value
+    klass = Class.new do
+      def quack
+        'woof'
+      end
+    end
+    duck = klass.new
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(responds_with(:quack, 'quack'))
+      mock.method(duck)
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_match_parameter_that_has_identical_query_string
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_equivalent_query_string('http://example.com/foo?a=1&b=2'))
+      mock.method('http://example.com/foo?a=1&b=2')
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_match_parameter_that_has_rearranged_query_string
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_equivalent_query_string('http://example.com/foo?b=2&a=1'))
+      mock.method('http://example.com/foo?a=1&b=2')
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_not_match_parameter_that_does_not_have_the_same_query_parameters
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_equivalent_query_string('http://example.com/foo?a=1'))
+      mock.method('http://example.com/foo?a=1&b=2')
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_not_match_parameter_that_has_no_query_parameters_when_they_are_expected
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_equivalent_query_string('http://example.com/foo'))
+      mock.method('http://example.com/foo?a=1&b=2')
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_not_match_parameter_that_has_the_same_query_string_bit_which_differs_otherwise
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_equivalent_query_string('http://a.example.com/foo?a=1&b=2'))
+      mock.method('http://b.example.com/foo?a=1&b=2')
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_match_parameter_with_no_domain_or_scheme
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with(has_equivalent_query_string('/foo?a=1&b=2'))
+      mock.method('/foo?a=1&b=2')
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_match_parameter_when_value_is_divisible_by_four
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with { |actual_value| actual_value % 4 == 0 }
+      mock.method(8)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_not_match_parameter_when_value_is_not_divisible_by_four
+    test_result = run_as_test do
+      mock = mock()
+      mock.expects(:method).with { |actual_value| actual_value % 4 == 0 }
+      mock.method(9)
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_match_parameters_when_values_add_up_to_ten
+    test_result = run_as_test do
+      mock = mock()
+      matcher = lambda { |*values| values.inject(0) { |sum, n| sum + n } == 10 }
+      mock.expects(:method).with(&matcher)
+      mock.method(1, 2, 3, 4)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_not_match_parameters_when_values_do_not_add_up_to_ten
+    test_result = run_as_test do
+      mock = mock()
+      matcher = lambda { |*values| values.inject(0) { |sum, n| sum + n } == 10 }
+      mock.expects(:method).with(&matcher)
+      mock.method(1, 2, 3, 4, 5)
+    end
+    assert_failed(test_result)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/partial_mocks_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/partial_mocks_test.rb
new file mode 100755
index 0000000..683b6ab
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/partial_mocks_test.rb
@@ -0,0 +1,47 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class PartialMockTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_pass_if_all_expectations_are_satisfied
+    test_result = run_as_test do
+      partial_mock_one = "partial_mock_one"
+      partial_mock_two = "partial_mock_two"
+
+      partial_mock_one.expects(:first)
+      partial_mock_one.expects(:second)
+      partial_mock_two.expects(:third)
+
+      partial_mock_one.first
+      partial_mock_one.second
+      partial_mock_two.third
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_fail_if_all_expectations_are_not_satisfied
+    test_result = run_as_test do
+      partial_mock_one = "partial_mock_one"
+      partial_mock_two = "partial_mock_two"
+
+      partial_mock_one.expects(:first)
+      partial_mock_one.expects(:second)
+      partial_mock_two.expects(:third)
+
+      partial_mock_one.first
+      partial_mock_two.third
+    end
+    assert_failed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/prepend_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/prepend_test.rb
new file mode 100755
index 0000000..56a91e5
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/prepend_test.rb
@@ -0,0 +1,88 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class PrependTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  if RUBY_VERSION >= '2.0'
+
+    module Mod1
+      def my_method
+        super + " World"
+      end
+    end
+
+    module Mod2
+      def my_method
+        super + " Wide"
+      end
+    end
+
+    class Klass1
+      prepend Mod1
+      prepend Mod2
+
+      def my_method
+        "Hello"
+      end
+    end
+
+    class Klass2
+      class << self
+        prepend Mod1
+        prepend Mod2
+
+        def my_method
+          "Hello"
+        end
+      end
+    end
+
+    def test_stubbing_any_instance_with_multiple_prepended_methods
+      assert_snapshot_unchanged(Klass1) do
+        test_result = run_as_test do
+          Klass1.any_instance.stubs(:my_method).returns("Bye World")
+          assert_equal "Bye World", Klass1.new.my_method
+        end
+        assert_passed(test_result)
+      end
+      assert_equal "Hello World Wide", Klass1.new.my_method
+    end
+
+    def test_stubbing_instance_with_multiple_prepended_methods
+      object = Klass1.new
+
+      assert_snapshot_unchanged(object) do
+        test_result = run_as_test do
+          object.stubs(:my_method).returns("Bye World")
+          assert_equal "Bye World", object.my_method
+          assert_equal "Hello World Wide", Klass1.new.my_method
+        end
+        assert_passed(test_result)
+      end
+      assert_equal "Hello World Wide", object.my_method
+    end
+
+    def test_stubbing_a_prepended_class_method
+      assert_snapshot_unchanged(Klass2) do
+        test_result = run_as_test do
+          Klass2.stubs(:my_method).returns("Bye World")
+          assert_equal "Bye World", Klass2.my_method
+        end
+        assert_passed(test_result)
+      end
+      assert_equal "Hello World Wide", Klass2.my_method
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/raise_exception_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/raise_exception_test.rb
new file mode 100755
index 0000000..085cc4e
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/raise_exception_test.rb
@@ -0,0 +1,39 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class RaiseExceptionTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_raise_exception
+    exception_class = Class.new(StandardError)
+    test_result = run_as_test do
+      foo = stub('foo')
+      foo.stubs(:bar).raises(exception_class, "my-message")
+      exception = assert_raises(exception_class) { foo.bar }
+      assert_equal "my-message", exception.message
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_raise_two_different_exceptions
+    exception_one_class = Class.new(StandardError)
+    exception_two_class = Class.new(StandardError)
+    test_result = run_as_test do
+      foo = stub('foo')
+      foo.stubs(:bar).raises(exception_one_class).then.raises(exception_two_class)
+      assert_raises(exception_one_class) { foo.bar }
+      assert_raises(exception_two_class) { foo.bar }
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/return_value_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/return_value_test.rb
new file mode 100755
index 0000000..8a7d411
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/return_value_test.rb
@@ -0,0 +1,52 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class ReturnValueTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_build_mock_and_explicitly_add_an_expectation_with_a_return_value
+    test_result = run_as_test do
+      foo = mock('foo')
+      foo.expects(:bar).returns('bar')
+      assert_equal 'bar', foo.bar
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_build_mock_incorporating_two_expectations_with_return_values
+    test_result = run_as_test do
+      foo = mock('foo', :bar => 'bar', :baz => 'baz')
+      assert_equal 'bar', foo.bar
+      assert_equal 'baz', foo.baz
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_build_stub_and_explicitly_add_an_expectation_with_a_return_value
+    test_result = run_as_test do
+      foo = stub('foo')
+      foo.stubs(:bar).returns('bar')
+      assert_equal 'bar', foo.bar
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_build_stub_incorporating_two_expectations_with_return_values
+    test_result = run_as_test do
+      foo = stub('foo', :bar => 'bar', :baz => 'baz')
+      assert_equal 'bar', foo.bar
+      assert_equal 'baz', foo.baz
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/sequence_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/sequence_test.rb
new file mode 100755
index 0000000..93a4187
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/sequence_test.rb
@@ -0,0 +1,192 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class SequenceTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_constrain_invocations_to_occur_in_expected_order
+    test_result = run_as_test do
+      mock = mock()
+      sequence = sequence('one')
+
+      mock.expects(:first).in_sequence(sequence)
+      mock.expects(:second).in_sequence(sequence)
+
+      mock.second
+      mock.first
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_allow_invocations_in_sequence
+    test_result = run_as_test do
+      mock = mock()
+      sequence = sequence('one')
+
+      mock.expects(:first).in_sequence(sequence)
+      mock.expects(:second).in_sequence(sequence)
+
+      mock.first
+      mock.second
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_constrain_invocations_to_occur_in_expected_order_even_if_expected_on_different_mocks
+    test_result = run_as_test do
+      mock_one = mock('1')
+      mock_two = mock('2')
+      sequence = sequence('one')
+
+      mock_one.expects(:first).in_sequence(sequence)
+      mock_two.expects(:second).in_sequence(sequence)
+
+      mock_two.second
+      mock_one.first
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_allow_invocations_in_sequence_even_if_expected_on_different_mocks
+    test_result = run_as_test do
+      mock_one = mock('1')
+      mock_two = mock('2')
+      sequence = sequence('one')
+
+      mock_one.expects(:first).in_sequence(sequence)
+      mock_two.expects(:second).in_sequence(sequence)
+
+      mock_one.first
+      mock_two.second
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_constrain_invocations_to_occur_in_expected_order_even_if_expected_on_partial_mocks
+    test_result = run_as_test do
+      partial_mock_one = "1"
+      partial_mock_two = "2"
+      sequence = sequence('one')
+
+      partial_mock_one.expects(:first).in_sequence(sequence)
+      partial_mock_two.expects(:second).in_sequence(sequence)
+
+      partial_mock_two.second
+      partial_mock_one.first
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_allow_invocations_in_sequence_even_if_expected_on_partial_mocks
+    test_result = run_as_test do
+      partial_mock_one = "1"
+      partial_mock_two = "2"
+      sequence = sequence('one')
+
+      partial_mock_one.expects(:first).in_sequence(sequence)
+      partial_mock_two.expects(:second).in_sequence(sequence)
+
+      partial_mock_one.first
+      partial_mock_two.second
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stub_expectations_to_be_skipped_in_sequence
+    test_result = run_as_test do
+      mock = mock()
+      sequence = sequence('one')
+
+      mock.expects(:first).in_sequence(sequence)
+      mock.stubs(:second).in_sequence(sequence)
+      mock.expects(:third).in_sequence(sequence)
+
+      mock.first
+      mock.third
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_regard_sequences_as_independent_of_each_other
+    test_result = run_as_test do
+      mock = mock()
+      sequence_one = sequence('one')
+      sequence_two = sequence('two')
+
+      mock.expects(:first).in_sequence(sequence_one)
+      mock.expects(:second).in_sequence(sequence_one)
+
+      mock.expects(:third).in_sequence(sequence_two)
+      mock.expects(:fourth).in_sequence(sequence_two)
+
+      mock.first
+      mock.third
+      mock.second
+      mock.fourth
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_include_sequence_in_failure_message
+    test_result = run_as_test do
+      mock = mock()
+      sequence = sequence('one')
+
+      mock.expects(:first).in_sequence(sequence)
+      mock.expects(:second).in_sequence(sequence)
+
+      mock.second
+      mock.first
+    end
+    assert_failed(test_result)
+    assert_match Regexp.new("in sequence 'one'"), test_result.failures.first.message
+  end
+
+  def test_should_allow_expectations_to_be_in_more_than_one_sequence
+    test_result = run_as_test do
+      mock = mock()
+      sequence_one = sequence('one')
+      sequence_two = sequence('two')
+
+      mock.expects(:first).in_sequence(sequence_one)
+      mock.expects(:second).in_sequence(sequence_two)
+      mock.expects(:third).in_sequence(sequence_one).in_sequence(sequence_two)
+
+      mock.first
+      mock.third
+      mock.second
+    end
+    assert_failed(test_result)
+    assert_match Regexp.new("in sequence 'one'"), test_result.failures.first.message
+    assert_match Regexp.new("in sequence 'two'"), test_result.failures.first.message
+  end
+
+  def test_should_have_shortcut_for_expectations_to_be_in_more_than_one_sequence
+    test_result = run_as_test do
+      mock = mock()
+      sequence_one = sequence('one')
+      sequence_two = sequence('two')
+
+      mock.expects(:first).in_sequence(sequence_one)
+      mock.expects(:second).in_sequence(sequence_two)
+      mock.expects(:third).in_sequence(sequence_one, sequence_two)
+
+      mock.first
+      mock.third
+      mock.second
+    end
+    assert_failed(test_result)
+    assert_match Regexp.new("in sequence 'one'"), test_result.failures.first.message
+    assert_match Regexp.new("in sequence 'two'"), test_result.failures.first.message
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/states_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/states_test.rb
new file mode 100755
index 0000000..ca5e8fc
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/states_test.rb
@@ -0,0 +1,70 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StatesTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_constrain_expectations_to_occur_within_a_given_state
+    test_result = run_as_test do
+      mock = mock()
+      readiness = states('readiness')
+
+      mock.stubs(:first).when(readiness.is('ready'))
+      mock.stubs(:second).then(readiness.is('ready'))
+
+      mock.first
+    end
+    assert_failed(test_result)
+  end
+
+  def test_should_allow_expectations_to_occur_in_correct_state
+    test_result = run_as_test do
+      mock = mock()
+      readiness = states('readiness')
+
+      mock.stubs(:first).when(readiness.is('ready'))
+      mock.stubs(:second).then(readiness.is('ready'))
+
+      mock.second
+      mock.first
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_start_in_a_specific_state
+    test_result = run_as_test do
+      mock = mock()
+      readiness = states('readiness')
+
+      mock.stubs(:first).when(readiness.is('ready'))
+
+      readiness.starts_as('ready')
+      mock.first
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_switch_state_when_method_raises_an_exception
+    test_result = run_as_test do
+      mock = mock()
+      readiness = states('readiness')
+
+      mock.expects(:first).raises().then(readiness.is('ready'))
+      mock.expects(:second).when(readiness.is('ready'))
+
+      mock.first rescue nil
+      mock.second
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_any_instance_method_defined_on_superclass_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_any_instance_method_defined_on_superclass_test.rb
new file mode 100755
index 0000000..51004f3
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_any_instance_method_defined_on_superclass_test.rb
@@ -0,0 +1,34 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubAnyInstanceMethodDefinedOnSuperclassTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_stub_method_and_leave_it_unchanged_after_test
+    superklass = Class.new do
+      def my_superclass_method
+        :original_return_value
+      end
+      public :my_superclass_method
+    end
+    klass = Class.new(superklass)
+    instance = klass.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        superklass.any_instance.stubs(:my_superclass_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.my_superclass_method
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.my_superclass_method
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_any_instance_method_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_any_instance_method_test.rb
new file mode 100755
index 0000000..5e521f9
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_any_instance_method_test.rb
@@ -0,0 +1,238 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubAnyInstanceMethodTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_stub_public_method_within_test
+    klass = Class.new do
+      def my_instance_method
+        :original_return_value
+      end
+    end
+    instance = klass.new
+    test_result = run_as_test do
+      klass.any_instance.stubs(:my_instance_method).returns(:new_return_value)
+      assert_method_visiblity instance, :my_instance_method, :public
+      assert_equal :new_return_value, instance.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_leave_stubbed_public_method_unchanged_after_test
+    klass = Class.new do
+      def my_instance_method
+        :original_return_value
+      end
+      public :my_instance_method
+      def self.public(*args); end
+    end
+    instance = klass.new
+    run_as_test do
+      klass.any_instance.stubs(:my_instance_method).returns(:new_return_value)
+    end
+    assert instance.public_methods(false).any? { |m| m.to_s == 'my_instance_method' }
+    assert_equal :original_return_value, instance.my_instance_method
+  end
+
+  def test_should_leave_stubbed_protected_method_unchanged_after_test
+    klass = Class.new do
+      def my_instance_method
+        :original_return_value
+      end
+      protected :my_instance_method
+      def self.protected(*args); end
+      def my_unprotected_instance_method
+        my_instance_method
+      end
+    end
+    instance = klass.new
+    run_as_test do
+      klass.any_instance.stubs(:my_instance_method).returns(:new_return_value)
+    end
+    assert instance.protected_methods(false).any? { |m| m.to_s == 'my_instance_method' }
+    assert_equal :original_return_value, instance.my_unprotected_instance_method
+  end
+
+  def test_should_stub_protected_method_within_test
+    klass = Class.new do
+      def my_instance_method
+        :original_return_value
+      end
+      protected :my_instance_method
+      def self.protected(*args); end
+      def my_unprotected_instance_method
+        my_instance_method
+      end
+    end
+    instance = klass.new
+    test_result = run_as_test do
+      klass.any_instance.stubs(:my_instance_method).returns(:new_return_value)
+      assert_method_visiblity instance, :my_instance_method, :protected
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_leave_stubbed_private_method_unchanged_after_test
+    klass = Class.new do
+      def my_instance_method
+        :original_return_value
+      end
+      private :my_instance_method
+      def self.private(*args); end
+    end
+    instance = klass.new
+    run_as_test do
+      klass.any_instance.stubs(:my_instance_method).returns(:new_return_value)
+    end
+    assert instance.private_methods(false).any? { |m| m.to_s == 'my_instance_method' }
+    assert_equal :original_return_value, instance.send(:my_instance_method)
+  end
+
+  def test_should_stub_private_method_within_test
+    klass = Class.new do
+      def my_instance_method
+        :original_return_value
+      end
+      private :my_instance_method
+      def self.private(*args); end
+    end
+    instance = klass.new
+    test_result = run_as_test do
+      klass.any_instance.stubs(:my_instance_method).returns(:new_return_value)
+      assert_method_visiblity instance, :my_instance_method, :private
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_reset_expectations_after_test
+    klass = Class.new do
+      def my_instance_method
+        :original_return_value
+      end
+    end
+    run_as_test do
+      klass.any_instance.stubs(:my_instance_method).returns(:new_return_value)
+    end
+
+    assert_equal 0, klass.any_instance.mocha.__expectations__.length
+  end
+
+  def test_should_be_able_to_stub_a_superclass_method
+    superklass = Class.new do
+      def my_superclass_method
+        :original_return_value
+      end
+    end
+    klass = Class.new(superklass)
+    instance = klass.new
+    test_result = run_as_test do
+      klass.any_instance.stubs(:my_superclass_method).returns(:new_return_value)
+      assert_equal :new_return_value, instance.my_superclass_method
+    end
+    assert_passed(test_result)
+    assert instance.public_methods(true).any? { |m| m.to_s == 'my_superclass_method' }
+    assert !klass.public_methods(false).any? { |m| m.to_s == 'my_superclass_method' }
+    assert_equal :original_return_value, instance.my_superclass_method
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby18_public_instance_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby18_klass = Class.new do
+      class << self
+        def public_instance_methods(include_superclass = true)
+          ['my_instance_method']
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby18_klass.any_instance.stubs(:my_instance_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby18_klass.new.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby19_public_instance_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby19_klass = Class.new do
+      class << self
+        def public_instance_methods(include_superclass = true)
+          [:my_instance_method]
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby19_klass.any_instance.stubs(:my_instance_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby19_klass.new.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby18_protected_instance_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby18_klass = Class.new do
+      class << self
+        def protected_instance_methods(include_superclass = true)
+          ['my_instance_method']
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby18_klass.any_instance.stubs(:my_instance_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby18_klass.new.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby19_protected_instance_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby19_klass = Class.new do
+      class << self
+        def protected_instance_methods(include_superclass = true)
+          [:my_instance_method]
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby19_klass.any_instance.stubs(:my_instance_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby19_klass.new.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby18_private_instance_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby18_klass = Class.new do
+      class << self
+        def private_instance_methods(include_superclass = true)
+          ['my_instance_method']
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby18_klass.any_instance.stubs(:my_instance_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby18_klass.new.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby19_private_instance_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby19_klass = Class.new do
+      class << self
+        def private_instance_methods(include_superclass = true)
+          [:my_instance_method]
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby19_klass.any_instance.stubs(:my_instance_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby19_klass.new.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_class_method_defined_on_active_record_association_proxy_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_class_method_defined_on_active_record_association_proxy_test.rb
new file mode 100755
index 0000000..3bc27bc
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_class_method_defined_on_active_record_association_proxy_test.rb
@@ -0,0 +1,106 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubClassMethodDefinedOnActiveRecordAssociationProxyTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby18_public_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby18_klass = Class.new do
+      class << self
+        def public_methods(include_superclass = true)
+          ['my_class_method']
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby18_klass.stubs(:my_class_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby18_klass.my_class_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby19_public_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby19_klass = Class.new do
+      class << self
+        def public_methods(include_superclass = true)
+          [:my_class_method]
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby19_klass.stubs(:my_class_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby19_klass.my_class_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby18_protected_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby18_klass = Class.new do
+      class << self
+        def protected_methods(include_superclass = true)
+          ['my_class_method']
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby18_klass.stubs(:my_class_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby18_klass.my_class_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby19_protected_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby19_klass = Class.new do
+      class << self
+        def protected_methods(include_superclass = true)
+          [:my_class_method]
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby19_klass.stubs(:my_class_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby19_klass.my_class_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby18_private_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby18_klass = Class.new do
+      class << self
+        def private_methods(include_superclass = true)
+          ['my_class_method']
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby18_klass.stubs(:my_class_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby18_klass.my_class_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby19_private_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby19_klass = Class.new do
+      class << self
+        def private_methods(include_superclass = true)
+          [:my_class_method]
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby19_klass.stubs(:my_class_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby19_klass.my_class_method
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_class_method_defined_on_class_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_class_method_defined_on_class_test.rb
new file mode 100755
index 0000000..c497b65
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_class_method_defined_on_class_test.rb
@@ -0,0 +1,78 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubClassMethodDefinedOnClassTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_stub_public_method_and_leave_it_unchanged_after_test
+    klass = Class.new do
+      class << self
+        def my_class_method
+          :original_return_value
+        end
+        public :my_class_method
+        def self.public(*args); end
+      end
+    end
+    assert_snapshot_unchanged(klass) do
+      test_result = run_as_test do
+        klass.stubs(:my_class_method).returns(:new_return_value)
+        assert_method_visiblity klass, :my_class_method, :public
+        assert_equal :new_return_value, klass.my_class_method
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, klass.my_class_method
+  end
+
+  def test_should_stub_protected_method_and_leave_it_unchanged_after_test
+    klass = Class.new do
+      class << self
+        def my_class_method
+          :original_return_value
+        end
+        protected :my_class_method
+        def self.protected(*args); end
+      end
+    end
+    assert_snapshot_unchanged(klass) do
+      test_result = run_as_test do
+        klass.stubs(:my_class_method).returns(:new_return_value)
+        assert_method_visiblity klass, :my_class_method, :protected
+        assert_equal :new_return_value, klass.send(:my_class_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, klass.send(:my_class_method)
+  end
+
+  def test_should_stub_private_method_and_leave_it_unchanged_after_test
+    klass = Class.new do
+      class << self
+        def my_class_method
+          :original_return_value
+        end
+        private :my_class_method
+        def self.private(*args); end
+      end
+    end
+    assert_snapshot_unchanged(klass) do
+      test_result = run_as_test do
+        klass.stubs(:my_class_method).returns(:new_return_value)
+        assert_method_visiblity klass, :my_class_method, :private
+        assert_equal :new_return_value, klass.send(:my_class_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, klass.send(:my_class_method)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_class_method_defined_on_module_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_class_method_defined_on_module_test.rb
new file mode 100755
index 0000000..83eff1a
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_class_method_defined_on_module_test.rb
@@ -0,0 +1,75 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubClassMethodDefinedOnModuleTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_stub_public_method_and_leave_it_unchanged_after_test
+    mod = Module.new do
+      def my_class_method
+        :original_return_value
+      end
+      public :my_class_method
+    end
+    klass = Class.new do
+      extend mod
+    end
+    assert_snapshot_unchanged(klass) do
+      test_result = run_as_test do
+        klass.stubs(:my_class_method).returns(:new_return_value)
+        assert_equal :new_return_value, klass.my_class_method
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, klass.my_class_method
+  end
+
+  def test_should_stub_protected_method_and_leave_it_unchanged_after_test
+    mod = Module.new do
+      def my_class_method
+        :original_return_value
+      end
+      protected :my_class_method
+    end
+    klass = Class.new do
+      extend mod
+    end
+    assert_snapshot_unchanged(klass) do
+      test_result = run_as_test do
+        klass.stubs(:my_class_method).returns(:new_return_value)
+        assert_equal :new_return_value, klass.send(:my_class_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, klass.send(:my_class_method)
+  end
+
+  def test_should_stub_private_method_and_leave_it_unchanged_after_test
+    mod = Module.new do
+      def my_class_method
+        :original_return_value
+      end
+      private :my_class_method
+    end
+    klass = Class.new do
+      extend mod
+    end
+    assert_snapshot_unchanged(klass) do
+      test_result = run_as_test do
+        klass.stubs(:my_class_method).returns(:new_return_value)
+        assert_equal :new_return_value, klass.send(:my_class_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, klass.send(:my_class_method)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_class_method_defined_on_superclass_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_class_method_defined_on_superclass_test.rb
new file mode 100755
index 0000000..6dd77ef
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_class_method_defined_on_superclass_test.rb
@@ -0,0 +1,112 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubClassMethodDefinedOnSuperclassTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_stub_public_method_on_child_class_and_leave_it_unchanged_after_test
+    superklass = Class.new do
+      class << self
+        def my_class_method
+          :original_return_value
+        end
+        public :my_class_method
+      end
+    end
+    klass = Class.new(superklass)
+    assert_snapshot_unchanged(klass) do
+      test_result = run_as_test do
+        klass.stubs(:my_class_method).returns(:new_return_value)
+        assert_equal :new_return_value, klass.my_class_method
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, klass.my_class_method
+  end
+
+  def test_should_stub_protected_method_on_child_class_and_leave_it_unchanged_after_test
+    superklass = Class.new do
+      class << self
+        def my_class_method
+          :original_return_value
+        end
+        protected :my_class_method
+      end
+    end
+    klass = Class.new(superklass)
+    assert_snapshot_unchanged(klass) do
+      test_result = run_as_test do
+        klass.stubs(:my_class_method).returns(:new_return_value)
+        assert_equal :new_return_value, klass.send(:my_class_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, klass.send(:my_class_method)
+  end
+
+  def test_should_stub_private_method_on_child_class_and_leave_it_unchanged_after_test
+    superklass = Class.new do
+      class << self
+        def my_class_method
+          :original_return_value
+        end
+        private :my_class_method
+      end
+    end
+    klass = Class.new(superklass)
+    assert_snapshot_unchanged(klass) do
+      test_result = run_as_test do
+        klass.stubs(:my_class_method).returns(:new_return_value)
+        assert_equal :new_return_value, klass.send(:my_class_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, klass.send(:my_class_method)
+  end
+
+  def test_should_stub_method_on_superclass_and_leave_it_unchanged_after_test
+    superklass = Class.new do
+      class << self
+        def my_class_method
+          :original_return_value
+        end
+        public :my_class_method
+      end
+    end
+    klass = Class.new(superklass)
+    assert_snapshot_unchanged(klass) do
+      test_result = run_as_test do
+        superklass.stubs(:my_class_method).returns(:new_return_value)
+        assert_equal :new_return_value, klass.my_class_method
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, klass.my_class_method
+  end
+
+  def test_stub_on_earliest_receiver_should_take_priority
+    superklass = Class.new do
+      class << self
+        def my_class_method
+          :original_return_value
+        end
+      end
+    end
+    klass = Class.new(superklass)
+    test_result = run_as_test do
+      klass.stubs(:my_class_method).returns(:klass_return_value)
+      superklass.stubs(:my_class_method).returns(:superklass_return_value)
+      assert_equal :klass_return_value, klass.my_class_method
+    end
+    assert_passed(test_result)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_everything_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_everything_test.rb
new file mode 100755
index 0000000..3e0188b
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_everything_test.rb
@@ -0,0 +1,56 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubEverythingTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_build_stub_and_explicitly_add_an_expectation
+    test_result = run_as_test do
+      foo = stub_everything()
+      foo.stubs(:bar)
+      foo.bar
+      foo.unexpected_invocation
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_build_named_stub_and_explicitly_add_an_expectation
+    test_result = run_as_test do
+      foo = stub_everything('foo')
+      foo.stubs(:bar)
+      foo.bar
+      foo.unexpected_invocation
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_build_stub_incorporating_two_expectations
+    test_result = run_as_test do
+      foo = stub_everything(:bar => 'bar', :baz => 'baz')
+      foo.bar
+      foo.baz
+      foo.unexpected_invocation
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_build_named_stub_incorporating_two_expectations
+    test_result = run_as_test do
+      foo = stub_everything('foo', :bar => 'bar', :baz => 'baz')
+      foo.bar
+      foo.baz
+      foo.unexpected_invocation
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_active_record_association_proxy_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_active_record_association_proxy_test.rb
new file mode 100755
index 0000000..ca6d38c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_active_record_association_proxy_test.rb
@@ -0,0 +1,93 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubInstanceMethodDefinedOnActiveRecordAssociationProxyTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby18_public_methods_include_method_but_method_does_not_exist
+    ruby18_instance = Class.new do
+      def public_methods(include_superclass = true)
+        ['my_instance_method']
+      end
+    end.new
+    test_result = run_as_test do
+      ruby18_instance.stubs(:my_instance_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby18_instance.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby19_public_methods_include_method_but_method_does_not_exist
+    ruby19_instance = Class.new do
+      def public_methods(include_superclass = true)
+        [:my_instance_method]
+      end
+    end.new
+    test_result = run_as_test do
+      ruby19_instance.stubs(:my_instance_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby19_instance.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby18_protected_methods_include_method_but_method_does_not_exist
+    ruby18_instance = Class.new do
+      def protected_methods(include_superclass = true)
+        ['my_instance_method']
+      end
+    end.new
+    test_result = run_as_test do
+      ruby18_instance.stubs(:my_instance_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby18_instance.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby19_protected_methods_include_method_but_method_does_not_exist
+    ruby19_instance = Class.new do
+      def protected_methods(include_superclass = true)
+        [:my_instance_method]
+      end
+    end.new
+    test_result = run_as_test do
+      ruby19_instance.stubs(:my_instance_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby19_instance.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby18_private_methods_include_method_but_method_does_not_exist
+    ruby18_instance = Class.new do
+      def private_methods(include_superclass = true)
+        ['my_instance_method']
+      end
+    end.new
+    test_result = run_as_test do
+      ruby18_instance.stubs(:my_instance_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby18_instance.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby19_private_methods_include_method_but_method_does_not_exist
+    ruby19_instance = Class.new do
+      def private_methods(include_superclass = true)
+        [:my_instance_method]
+      end
+    end.new
+    test_result = run_as_test do
+      ruby19_instance.stubs(:my_instance_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby19_instance.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_class_and_aliased_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_class_and_aliased_test.rb
new file mode 100755
index 0000000..56d150d
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_class_and_aliased_test.rb
@@ -0,0 +1,69 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubInstanceMethodDefinedOnClassAndAliasedTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_stub_public_method_and_leave_it_unchanged_after_test
+    instance = Class.new do
+      def my_instance_method
+        :original_return_value
+      end
+      public :my_instance_method
+      alias_method :my_aliased_method, :my_instance_method
+    end.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_aliased_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.my_aliased_method
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.my_aliased_method
+  end
+
+  def test_should_stub_protected_method_and_leave_it_unchanged_after_test
+    instance = Class.new do
+      def my_instance_method
+        :original_return_value
+      end
+      protected :my_instance_method
+      alias_method :my_aliased_method, :my_instance_method
+    end.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_aliased_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.send(:my_aliased_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.send(:my_aliased_method)
+  end
+
+  def test_should_stub_private_method_and_leave_it_unchanged_after_test
+    instance = Class.new do
+      def my_instance_method
+        :original_return_value
+      end
+      private :my_instance_method
+      alias_method :my_aliased_method, :my_instance_method
+    end.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_aliased_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.send(:my_aliased_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.send(:my_aliased_method)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_class_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_class_test.rb
new file mode 100755
index 0000000..f8c4015
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_class_test.rb
@@ -0,0 +1,69 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubInstanceMethodDefinedOnClassTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_stub_public_method_and_leave_it_unchanged_after_test
+    instance = Class.new do
+      def my_instance_method
+        :original_return_value
+      end
+      public :my_instance_method
+    end.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_instance_method).returns(:new_return_value)
+        assert_method_visiblity instance, :my_instance_method, :public
+        assert_equal :new_return_value, instance.my_instance_method
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.my_instance_method
+  end
+
+  def test_should_stub_protected_method_and_leave_it_unchanged_after_test
+    instance = Class.new do
+      def my_instance_method
+        :original_return_value
+      end
+      protected :my_instance_method
+    end.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_instance_method).returns(:new_return_value)
+        assert_method_visiblity instance, :my_instance_method, :protected
+        assert_equal :new_return_value, instance.send(:my_instance_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.send(:my_instance_method)
+  end
+
+  def test_should_stub_private_method_and_leave_it_unchanged_after_test
+    instance = Class.new do
+      def my_instance_method
+        :original_return_value
+      end
+      private :my_instance_method
+    end.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_instance_method).returns(:new_return_value)
+        assert_method_visiblity instance, :my_instance_method, :private
+        assert_equal :new_return_value, instance.send(:my_instance_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.send(:my_instance_method)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_kernel_module_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_kernel_module_test.rb
new file mode 100755
index 0000000..722566a
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_kernel_module_test.rb
@@ -0,0 +1,75 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubInstanceMethodDefinedOnKernelModuleTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_stub_public_method_and_leave_it_unchanged_after_test
+    Kernel.module_eval do
+      def my_instance_method
+        :original_return_value
+      end
+      public :my_instance_method
+    end
+    instance = Class.new.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_instance_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.my_instance_method
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.my_instance_method
+  ensure
+    Kernel.module_eval { remove_method :my_instance_method }
+  end
+
+  def test_should_stub_protected_method_and_leave_it_unchanged_after_test
+    Kernel.module_eval do
+      def my_instance_method
+        :original_return_value
+      end
+      protected :my_instance_method
+    end
+    instance = Class.new.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_instance_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.send(:my_instance_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.send(:my_instance_method)
+  ensure
+    Kernel.module_eval { remove_method :my_instance_method }
+  end
+
+  def test_should_stub_private_method_and_leave_it_unchanged_after_test
+    Kernel.module_eval do
+      def my_instance_method
+        :original_return_value
+      end
+      private :my_instance_method
+    end
+    instance = Class.new.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_instance_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.send(:my_instance_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.send(:my_instance_method)
+  ensure
+    Kernel.module_eval { remove_method :my_instance_method }
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_module_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_module_test.rb
new file mode 100755
index 0000000..41f9dfe
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_module_test.rb
@@ -0,0 +1,75 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubInstanceMethodDefinedOnModuleTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_stub_public_method_and_leave_it_unchanged_after_test
+    mod = Module.new do
+      def my_module_method
+        :original_return_value
+      end
+      public :my_module_method
+    end
+    instance = Class.new do
+      include mod
+    end.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_module_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.my_module_method
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.my_module_method
+  end
+
+  def test_should_stub_protected_method_and_leave_it_unchanged_after_test
+    mod = Module.new do
+      def my_module_method
+        :original_return_value
+      end
+      protected :my_module_method
+    end
+    instance = Class.new do
+      include mod
+    end.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_module_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.send(:my_module_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.send(:my_module_method)
+  end
+
+  def test_should_stub_private_method_and_leave_it_unchanged_after_test
+    mod = Module.new do
+      def my_module_method
+        :original_return_value
+      end
+      private :my_module_method
+    end
+    instance = Class.new do
+      include mod
+    end.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_module_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.send(:my_module_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.send(:my_module_method)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_object_class_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_object_class_test.rb
new file mode 100755
index 0000000..2c095df
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_object_class_test.rb
@@ -0,0 +1,75 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubInstanceMethodDefinedOnObjectClassTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_stub_public_method_and_leave_it_unchanged_after_test
+    Object.class_eval do
+      def my_instance_method
+        :original_return_value
+      end
+      public :my_instance_method
+    end
+    instance = Class.new.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_instance_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.my_instance_method
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.my_instance_method
+  ensure
+    Object.class_eval { remove_method :my_instance_method }
+  end
+
+  def test_should_stub_protected_method_and_leave_it_unchanged_after_test
+    Object.class_eval do
+      def my_instance_method
+        :original_return_value
+      end
+      protected :my_instance_method
+    end
+    instance = Class.new.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_instance_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.send(:my_instance_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.send(:my_instance_method)
+  ensure
+    Object.class_eval { remove_method :my_instance_method }
+  end
+
+  def test_should_stub_private_method_and_leave_it_unchanged_after_test
+    Object.class_eval do
+      def my_instance_method
+        :original_return_value
+      end
+      private :my_instance_method
+    end
+    instance = Class.new.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_instance_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.send(:my_instance_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.send(:my_instance_method)
+  ensure
+    Object.class_eval { remove_method :my_instance_method }
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_singleton_class_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_singleton_class_test.rb
new file mode 100755
index 0000000..199f035
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_singleton_class_test.rb
@@ -0,0 +1,70 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubInstanceMethodDefinedOnSingletonClassTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_stub_public_method_and_leave_it_unchanged_after_test
+    instance = Class.new.new
+    class << instance
+      def my_singleton_method
+        :original_return_value
+      end
+      public :my_singleton_method
+    end
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_singleton_method).returns(:stubbed_return_value)
+        assert_equal :stubbed_return_value, instance.my_singleton_method
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.my_singleton_method
+  end
+
+  def test_should_stub_protected_method_and_leave_it_unchanged_after_test
+    instance = Class.new.new
+    class << instance
+      def my_singleton_method
+        :original_return_value
+      end
+      protected :my_singleton_method
+    end
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_singleton_method).returns(:stubbed_return_value)
+        assert_equal :stubbed_return_value, instance.send(:my_singleton_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.send(:my_singleton_method)
+  end
+
+  def test_should_stub_private_method_and_leave_it_unchanged_after_test
+    instance = Class.new.new
+    class << instance
+      def my_singleton_method
+        :original_return_value
+      end
+      private :my_singleton_method
+    end
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_singleton_method).returns(:stubbed_return_value)
+        assert_equal :stubbed_return_value, instance.send(:my_singleton_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.send(:my_singleton_method)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_superclass_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_superclass_test.rb
new file mode 100755
index 0000000..ac530fe
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_instance_method_defined_on_superclass_test.rb
@@ -0,0 +1,72 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubInstanceMethodDefinedOnSuperclassTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_stub_public_method_and_leave_it_unchanged_after_test
+    superklass = Class.new do
+      def my_superclass_method
+        :original_return_value
+      end
+      public :my_superclass_method
+    end
+    klass = Class.new(superklass)
+    instance = klass.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_superclass_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.my_superclass_method
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.my_superclass_method
+  end
+
+  def test_should_stub_protected_method_and_leave_it_unchanged_after_test
+    superklass = Class.new do
+      def my_superclass_method
+        :original_return_value
+      end
+      protected :my_superclass_method
+    end
+    klass = Class.new(superklass)
+    instance = klass.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_superclass_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.send(:my_superclass_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.send(:my_superclass_method)
+  end
+
+  def test_should_stub_private_method_and_leave_it_unchanged_after_test
+    superklass = Class.new do
+      def my_superclass_method
+        :original_return_value
+      end
+      private :my_superclass_method
+    end
+    klass = Class.new(superklass)
+    instance = klass.new
+    assert_snapshot_unchanged(instance) do
+      test_result = run_as_test do
+        instance.stubs(:my_superclass_method).returns(:new_return_value)
+        assert_equal :new_return_value, instance.send(:my_superclass_method)
+      end
+      assert_passed(test_result)
+    end
+    assert_equal :original_return_value, instance.send(:my_superclass_method)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_module_method_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_module_method_test.rb
new file mode 100755
index 0000000..4e69812
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_module_method_test.rb
@@ -0,0 +1,163 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubModuleMethodTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_stub_method_within_test
+    mod = Module.new { def self.my_module_method; :original_return_value; end }
+    test_result = run_as_test do
+      mod.stubs(:my_module_method).returns(:new_return_value)
+      assert_equal :new_return_value, mod.my_module_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_leave_stubbed_public_method_unchanged_after_test
+    mod = Module.new { class << self; def my_module_method; :original_return_value; end; public :my_module_method; end }
+    run_as_test do
+      mod.stubs(:my_module_method).returns(:new_return_value)
+    end
+    assert mod.public_methods(false).any? { |m| m.to_s == 'my_module_method' }
+    assert_equal :original_return_value, mod.my_module_method
+  end
+
+  def test_should_leave_stubbed_protected_method_unchanged_after_test
+    mod = Module.new { class << self; def my_module_method; :original_return_value; end; protected :my_module_method; def my_unprotected_module_method; my_module_method; end; end }
+    run_as_test do
+      mod.stubs(:my_module_method).returns(:new_return_value)
+    end
+    assert mod.protected_methods(false).any? { |m| m.to_s == 'my_module_method' }
+    assert_equal :original_return_value, mod.my_unprotected_module_method
+  end
+
+  def test_should_leave_stubbed_private_method_unchanged_after_test
+    mod = Module.new { class << self; def my_module_method; :original_return_value; end; private :my_module_method; end }
+    run_as_test do
+      mod.stubs(:my_module_method).returns(:new_return_value)
+    end
+    assert mod.private_methods(false).any? { |m| m.to_s == 'my_module_method' }
+    assert_equal :original_return_value, mod.send(:my_module_method)
+  end
+
+  def test_should_reset_expectations_after_test
+    mod = Module.new { def self.my_module_method; :original_return_value; end }
+    run_as_test do
+      mod.stubs(:my_module_method)
+    end
+    assert_equal 0, mod.mocha.__expectations__.length
+  end
+
+  def test_should_be_able_to_stub_a_superclass_method
+    supermod = Module.new { def self.my_superclass_method; :original_return_value; end }
+    mod = Module.new { include supermod }
+    test_result = run_as_test do
+      mod.stubs(:my_superclass_method).returns(:new_return_value)
+      assert_equal :new_return_value, mod.my_superclass_method
+    end
+    assert_passed(test_result)
+    assert supermod.public_methods.any? { |m| m.to_s == 'my_superclass_method' }
+    assert !mod.public_methods(false).any? { |m| m.to_s == 'my_superclass_method' }
+    assert_equal :original_return_value, supermod.my_superclass_method
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby18_public_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby18_mod = Module.new do
+      class << self
+        def public_methods(include_superclass = true)
+          ['my_module_method']
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby18_mod.stubs(:my_module_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby18_mod.my_module_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby19_public_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby19_mod = Module.new do
+      class << self
+        def public_methods(include_superclass = true)
+          [:my_module_method]
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby19_mod.stubs(:my_module_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby19_mod.my_module_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby_18_protected_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby18_mod = Module.new do
+      class << self
+        def protected_methods(include_superclass = true)
+          ['my_module_method']
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby18_mod.stubs(:my_module_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby18_mod.my_module_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby19_protected_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby19_mod = Module.new do
+      class << self
+        def protected_methods(include_superclass = true)
+          [:my_module_method]
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby19_mod.stubs(:my_module_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby19_mod.my_module_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby18_private_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby18_mod = Module.new do
+      class << self
+        def private_methods(include_superclass = true)
+          ['my_module_method']
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby18_mod.stubs(:my_module_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby18_mod.my_module_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_be_able_to_stub_method_if_ruby19_private_methods_include_method_but_method_does_not_actually_exist_like_active_record_association_proxy
+    ruby19_mod = Module.new do
+      class << self
+        def private_methods(include_superclass = true)
+          [:my_module_method]
+        end
+      end
+    end
+    test_result = run_as_test do
+      ruby19_mod.stubs(:my_module_method).returns(:new_return_value)
+      assert_equal :new_return_value, ruby19_mod.my_module_method
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stub_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_test.rb
new file mode 100755
index 0000000..b3f6087
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stub_test.rb
@@ -0,0 +1,52 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_build_stub_and_explicitly_add_an_expectation
+    test_result = run_as_test do
+      foo = stub()
+      foo.stubs(:bar)
+      foo.bar
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_build_named_stub_and_explicitly_add_an_expectation
+    test_result = run_as_test do
+      foo = stub('foo')
+      foo.stubs(:bar)
+      foo.bar
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_build_stub_incorporating_two_expectations
+    test_result = run_as_test do
+      foo = stub(:bar => 'bar', :baz => 'baz')
+      foo.bar
+      foo.baz
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_build_named_stub_incorporating_two_expectations
+    test_result = run_as_test do
+      foo = stub('foo', :bar => 'bar', :baz => 'baz')
+      foo.bar
+      foo.baz
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stubba_example_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stubba_example_test.rb
new file mode 100755
index 0000000..14e208b
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stubba_example_test.rb
@@ -0,0 +1,102 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/setup'
+
+class Widget
+
+  def model
+    'original_model'
+  end
+
+  class << self
+
+    def find(options)
+      []
+    end
+
+    def create(attributes)
+      Widget.new
+    end
+
+  end
+
+end
+
+module Thingy
+
+  def self.wotsit
+    :hoojamaflip
+  end
+
+end
+
+class StubbaExampleTest < Mocha::TestCase
+
+  def test_should_stub_instance_method
+    widget = Widget.new
+    widget.expects(:model).returns('different_model')
+    assert_equal 'different_model', widget.model
+  end
+
+  def test_should_stub_module_method
+    should_stub_module_method
+  end
+
+  def test_should_stub_module_method_again
+    should_stub_module_method
+  end
+
+  def test_should_stub_class_method
+    should_stub_class_method
+  end
+
+  def test_should_stub_class_method_again
+    should_stub_class_method
+  end
+
+  def test_should_stub_instance_method_on_any_instance_of_a_class
+    should_stub_instance_method_on_any_instance_of_a_class
+  end
+
+  def test_should_stub_instance_method_on_any_instance_of_a_class_again
+    should_stub_instance_method_on_any_instance_of_a_class
+  end
+
+  def test_should_stub_two_different_class_methods
+    should_stub_two_different_class_methods
+  end
+
+  def test_should_stub_two_different_class_methods_again
+    should_stub_two_different_class_methods
+  end
+
+  private
+
+  def should_stub_module_method
+    Thingy.expects(:wotsit).returns(:dooda)
+    assert_equal :dooda, Thingy.wotsit
+  end
+
+  def should_stub_class_method
+    widgets = [Widget.new]
+    Widget.expects(:find).with(:all).returns(widgets)
+    assert_equal widgets, Widget.find(:all)
+  end
+
+  def should_stub_two_different_class_methods
+    found_widgets = [Widget.new]
+    created_widget = Widget.new
+    Widget.expects(:find).with(:all).returns(found_widgets)
+    Widget.expects(:create).with(:model => 'wombat').returns(created_widget)
+    assert_equal found_widgets, Widget.find(:all)
+    assert_equal created_widget, Widget.create(:model => 'wombat')
+  end
+
+  def should_stub_instance_method_on_any_instance_of_a_class
+    Widget.any_instance.expects(:model).at_least_once.returns('another_model')
+    widget_1 = Widget.new
+    widget_2 = Widget.new
+    assert_equal 'another_model', widget_1.model
+    assert_equal 'another_model', widget_2.model
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stubba_test_result_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stubba_test_result_test.rb
new file mode 100755
index 0000000..f9ed95b
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stubba_test_result_test.rb
@@ -0,0 +1,66 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+require 'execution_point'
+
+class StubbaTestResultTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_include_expectation_verification_in_assertion_count
+    test_result = run_as_test do
+      object = Class.new { def message; end }.new
+      object.expects(:message)
+      object.message
+    end
+    assert_equal 1, test_result.assertion_count
+  end
+
+  def test_should_include_assertions_in_assertion_count
+    test_result = run_as_test do
+      assert true
+    end
+    assert_equal 1, test_result.assertion_count
+  end
+
+  def test_should_not_include_stubbing_expectation_verification_in_assertion_count
+    test_result = run_as_test do
+      object = Class.new { def message; end }.new
+      object.stubs(:message)
+      object.message
+    end
+    assert_equal 0, test_result.assertion_count
+  end
+
+  def test_should_include_expectation_verification_failure_in_failure_count
+    test_result = run_as_test do
+      object = Class.new { def message; end }.new
+      object.expects(:message)
+    end
+    assert_equal 1, test_result.failure_count
+  end
+
+  def test_should_include_assertion_failure_in_failure_count
+    test_result = run_as_test do
+      flunk
+    end
+    assert_equal 1, test_result.failure_count
+  end
+
+  def test_should_display_backtrace_indicating_line_number_where_failing_assertion_was_called
+    execution_point = nil
+    test_result = run_as_test do
+      execution_point = ExecutionPoint.current; flunk
+    end
+    assert_equal 1, test_result.failure_count
+    assert_equal execution_point, ExecutionPoint.new(test_result.failures[0].location)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_error_backtrace_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_error_backtrace_test.rb
new file mode 100755
index 0000000..313305f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_error_backtrace_test.rb
@@ -0,0 +1,64 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+require 'execution_point'
+
+class StubbingErrorBacktraceTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_display_backtrace_indicating_line_number_where_attempt_to_stub_non_existent_method_was_made
+    execution_point = nil
+    object = Object.new
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    test_result = run_as_test do
+      execution_point = ExecutionPoint.current; object.stubs(:non_existent_method)
+    end
+    assert_equal 1, test_result.error_count
+    assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace)
+  end
+
+  def test_should_display_backtrace_indicating_line_number_where_attempt_to_stub_non_public_method_was_made
+    execution_point = nil
+    object = Class.new do
+      def non_public_method; end
+      private :non_public_method
+    end.new
+    Mocha::Configuration.prevent(:stubbing_non_public_method)
+    test_result = run_as_test do
+      execution_point = ExecutionPoint.current; object.stubs(:non_public_method)
+    end
+    assert_equal 1, test_result.error_count
+    assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace)
+  end
+
+  def test_should_display_backtrace_indicating_line_number_where_attempt_to_stub_method_on_non_mock_object_was_made
+    execution_point = nil
+    object = Object.new
+    Mocha::Configuration.prevent(:stubbing_method_on_non_mock_object)
+    test_result = run_as_test do
+      execution_point = ExecutionPoint.current; object.stubs(:any_method)
+    end
+    assert_equal 1, test_result.error_count
+    assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace)
+  end
+
+  def test_should_display_backtrace_indicating_line_number_where_method_was_unnecessarily_stubbed
+    execution_point = nil
+    object = Object.new
+    Mocha::Configuration.prevent(:stubbing_method_unnecessarily)
+    test_result = run_as_test do
+      execution_point = ExecutionPoint.current; object.stubs(:unused_method)
+    end
+    assert_equal 1, test_result.error_count
+    assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_frozen_object_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_frozen_object_test.rb
new file mode 100755
index 0000000..a9b50cc
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_frozen_object_test.rb
@@ -0,0 +1,88 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+require 'execution_point'
+
+class StubbingFrozenObjectTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_fail_fast_if_attempting_to_stub_method_on_frozen_object
+    object = Object.new
+    object.freeze
+    execution_point = nil
+    test_result = run_as_test do
+      execution_point = ExecutionPoint.current; object.stubs(:stubbed_method)
+    end
+    assert_failed(test_result)
+    assert_equal 1, test_result.error_count
+    assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace)
+  end
+
+  def test_should_fail_fast_if_attempting_to_expect_method_on_frozen_object
+    object = Object.new
+    object.freeze
+    execution_point = nil
+    test_result = run_as_test do
+      execution_point = ExecutionPoint.current; object.expects(:stubbed_method)
+    end
+    assert_failed(test_result)
+    assert_equal 1, test_result.error_count
+    assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace)
+  end
+
+  def test_should_fail_fast_if_attempting_to_stub_method_on_frozen_class
+    klass = Class.new
+    klass.freeze
+    execution_point = nil
+    test_result = run_as_test do
+      execution_point = ExecutionPoint.current; klass.stubs(:stubbed_method)
+    end
+    assert_failed(test_result)
+    assert_equal 1, test_result.error_count
+    assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace)
+  end
+
+  def test_should_fail_fast_if_attempting_to_expect_method_on_frozen_class
+    klass = Class.new
+    klass.freeze
+    execution_point = nil
+    test_result = run_as_test do
+      execution_point = ExecutionPoint.current; klass.expects(:stubbed_method)
+    end
+    assert_failed(test_result)
+    assert_equal 1, test_result.error_count
+    assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace)
+  end
+
+  def test_should_fail_fast_if_attempting_to_stub_method_on_any_instance_of_frozen_class
+    klass = Class.new
+    klass.freeze
+    execution_point = nil
+    test_result = run_as_test do
+      execution_point = ExecutionPoint.current; klass.any_instance.stubs(:stubbed_method)
+    end
+    assert_failed(test_result)
+    assert_equal 1, test_result.error_count
+    assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace)
+  end
+
+  def test_should_fail_fast_if_attempting_to_expect_method_on_any_instance_of_frozen_class
+    klass = Class.new
+    klass.freeze
+    execution_point = nil
+    test_result = run_as_test do
+      execution_point = ExecutionPoint.current; klass.any_instance.expects(:stubbed_method)
+    end
+    assert_failed(test_result)
+    assert_equal 1, test_result.error_count
+    assert_equal execution_point, ExecutionPoint.new(test_result.errors[0].exception.backtrace)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_method_accepting_block_parameter_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_method_accepting_block_parameter_test.rb
new file mode 100755
index 0000000..d761538
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_method_accepting_block_parameter_test.rb
@@ -0,0 +1,48 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubbingMethodAcceptingBlockParameterTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_stubbing_class_method_accepting_block_parameter_should_restore_original_method
+    klass = Class.new do
+      def self.my_class_method(&block); block.call; end
+    end
+    test_result = run_as_test do
+      klass.stubs(:my_class_method)
+    end
+    assert_passed(test_result)
+    assert_equal :return_value, klass.my_class_method { :return_value }
+  end
+
+  def test_stubbing_instance_method_accepting_block_parameter_should_restore_original_method
+    instance = Class.new do
+      def my_instance_method(&block); block.call; end
+    end.new
+    test_result = run_as_test do
+      instance.stubs(:my_instance_method)
+    end
+    assert_passed(test_result)
+    assert_equal :return_value, instance.my_instance_method { :return_value }
+  end
+
+  def test_stubbing_any_instance_method_accepting_block_parameter_should_restore_original_method
+    klass = Class.new do
+      def my_instance_method(&block); block.call; end
+    end
+    test_result = run_as_test do
+      klass.any_instance.stubs(:my_instance_method)
+    end
+    assert_passed(test_result)
+    assert_equal :return_value, klass.new.my_instance_method { :return_value }
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_method_unnecessarily_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_method_unnecessarily_test.rb
new file mode 100755
index 0000000..ef83d67
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_method_unnecessarily_test.rb
@@ -0,0 +1,65 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubbingMethodUnnecessarilyTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_allow_stubbing_method_unnecessarily
+    Mocha::Configuration.allow(:stubbing_method_unnecessarily)
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.stubs(:public_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?('stubbing method unnecessarily: #<Mock:mock>.public_method(any_parameters)')
+  end
+
+  def test_should_warn_when_stubbing_method_unnecessarily
+    Mocha::Configuration.warn_when(:stubbing_method_unnecessarily)
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.stubs(:public_method)
+    end
+    assert_passed(test_result)
+    assert @logger.warnings.include?('stubbing method unnecessarily: #<Mock:mock>.public_method(any_parameters)')
+  end
+
+  def test_should_prevent_stubbing_method_unnecessarily
+    Mocha::Configuration.prevent(:stubbing_method_unnecessarily)
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.stubs(:public_method)
+    end
+    assert_failed(test_result)
+    assert test_result.error_messages.include?('Mocha::StubbingError: stubbing method unnecessarily: #<Mock:mock>.public_method(any_parameters)')
+  end
+
+  def test_should_default_to_allow_stubbing_method_unnecessarily
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.stubs(:public_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?('stubbing method unnecessarily: #<Mock:mock>.public_method(any_parameters)')
+  end
+
+  def test_should_allow_stubbing_method_when_stubbed_method_is_invoked
+    Mocha::Configuration.prevent(:stubbing_method_unnecessarily)
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.stubs(:public_method)
+      mock.public_method
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_nil_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_nil_test.rb
new file mode 100755
index 0000000..ac163e7
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_nil_test.rb
@@ -0,0 +1,59 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubbingNilTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_allow_stubbing_method_on_nil
+    Mocha::Configuration.allow(:stubbing_method_on_nil)
+    test_result = run_as_test do
+      nil.stubs(:stubbed_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?("stubbing method on nil: nil.stubbed_method")
+  end
+
+  def test_should_warn_on_stubbing_method_on_nil
+    Mocha::Configuration.warn_when(:stubbing_method_on_nil)
+    test_result = run_as_test do
+      nil.stubs(:stubbed_method)
+    end
+    assert_passed(test_result)
+    assert @logger.warnings.include?("stubbing method on nil: nil.stubbed_method")
+  end
+
+  def test_should_prevent_stubbing_method_on_nil
+    Mocha::Configuration.prevent(:stubbing_method_on_nil)
+    test_result = run_as_test do
+      nil.stubs(:stubbed_method)
+    end
+    assert_failed(test_result)
+    assert test_result.error_messages.include?("Mocha::StubbingError: stubbing method on nil: nil.stubbed_method")
+  end
+
+  def test_should_default_to_prevent_stubbing_method_on_non_mock_object
+    test_result = run_as_test do
+      nil.stubs(:stubbed_method)
+    end
+    assert_failed(test_result)
+    assert test_result.error_messages.include?("Mocha::StubbingError: stubbing method on nil: nil.stubbed_method")
+  end
+
+  def test_should_allow_stubbing_method_on_non_nil_object
+    Mocha::Configuration.prevent(:stubbing_method_on_nil)
+    object = Object.new
+    test_result = run_as_test do
+      object.stubs(:stubbed_method)
+    end
+    assert_passed(test_result)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_existent_any_instance_method_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_existent_any_instance_method_test.rb
new file mode 100755
index 0000000..bcfd0ef
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_existent_any_instance_method_test.rb
@@ -0,0 +1,130 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubbingNonExistentAnyInstanceMethodTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_allow_stubbing_non_existent_any_instance_method
+    Mocha::Configuration.allow(:stubbing_non_existent_method)
+    klass = Class.new
+    test_result = run_as_test do
+      klass.any_instance.stubs(:non_existent_method)
+    end
+    assert !@logger.warnings.include?("stubbing non-existent method: #{klass.any_instance.mocha_inspect}.non_existent_method")
+    assert_passed(test_result)
+  end
+
+  def test_should_warn_when_stubbing_non_existent_any_instance_method
+    Mocha::Configuration.warn_when(:stubbing_non_existent_method)
+    klass = Class.new
+    test_result = run_as_test do
+      klass.any_instance.stubs(:non_existent_method)
+    end
+    assert_passed(test_result)
+    assert @logger.warnings.include?("stubbing non-existent method: #{klass.any_instance.mocha_inspect}.non_existent_method")
+  end
+
+  def test_should_prevent_stubbing_non_existent_any_instance_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    klass = Class.new
+    test_result = run_as_test do
+      klass.any_instance.stubs(:non_existent_method)
+    end
+    assert_failed(test_result)
+    assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-existent method: #{klass.any_instance.mocha_inspect}.non_existent_method")
+  end
+
+  def test_should_default_to_allow_stubbing_non_existent_any_instance_method
+    klass = Class.new
+    test_result = run_as_test do
+      klass.any_instance.stubs(:non_existent_method)
+    end
+    assert !@logger.warnings.include?("stubbing non-existent method: #{klass.any_instance.mocha_inspect}.non_existent_method")
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_public_any_instance_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    klass = Class.new do
+      def existing_public_method; end
+      public :existing_public_method
+    end
+    test_result = run_as_test do
+      klass.any_instance.stubs(:existing_public_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_protected_any_instance_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    klass = Class.new do
+      def existing_protected_method; end
+      protected :existing_protected_method
+    end
+    test_result = run_as_test do
+      klass.any_instance.stubs(:existing_protected_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_private_any_instance_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    klass = Class.new do
+      def existing_private_method; end
+      private :existing_private_method
+    end
+    test_result = run_as_test do
+      klass.any_instance.stubs(:existing_private_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_public_any_instance_superclass_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    superklass = Class.new do
+      def existing_public_method; end
+      public :existing_public_method
+    end
+    klass = Class.new(superklass)
+    test_result = run_as_test do
+      klass.any_instance.stubs(:existing_public_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_protected_any_instance_superclass_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    superklass = Class.new do
+      def existing_protected_method; end
+      protected :existing_protected_method
+    end
+    klass = Class.new(superklass)
+    test_result = run_as_test do
+      klass.any_instance.stubs(:existing_protected_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_private_any_instance_superclass_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    superklass = Class.new do
+      def existing_private_method; end
+      private :existing_private_method
+    end
+    klass = Class.new(superklass)
+    test_result = run_as_test do
+      klass.any_instance.stubs(:existing_private_method)
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_existent_class_method_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_existent_class_method_test.rb
new file mode 100755
index 0000000..a643994
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_existent_class_method_test.rb
@@ -0,0 +1,157 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubbingNonExistentClassMethodTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_allow_stubbing_non_existent_class_method
+    Mocha::Configuration.allow(:stubbing_non_existent_method)
+    klass = Class.new
+    test_result = run_as_test do
+      klass.stubs(:non_existent_method)
+    end
+    assert !@logger.warnings.include?("stubbing non-existent method: #{klass.mocha_inspect}.non_existent_method")
+    assert_passed(test_result)
+  end
+
+  def test_should_warn_when_stubbing_non_existent_class_method
+    Mocha::Configuration.warn_when(:stubbing_non_existent_method)
+    klass = Class.new
+    test_result = run_as_test do
+      klass.stubs(:non_existent_method)
+    end
+    assert_passed(test_result)
+    assert @logger.warnings.include?("stubbing non-existent method: #{klass.mocha_inspect}.non_existent_method")
+  end
+
+  def test_should_prevent_stubbing_non_existent_class_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    klass = Class.new
+    test_result = run_as_test do
+      klass.stubs(:non_existent_method)
+    end
+    assert_failed(test_result)
+    assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-existent method: #{klass.mocha_inspect}.non_existent_method")
+  end
+
+  def test_should_default_to_allow_stubbing_non_existent_class_method
+    klass = Class.new
+    test_result = run_as_test do
+      klass.stubs(:non_existent_method)
+    end
+    assert !@logger.warnings.include?("stubbing non-existent method: #{klass.mocha_inspect}.non_existent_method")
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_public_class_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    klass = Class.new do
+      class << self
+        def existing_public_method; end
+        public :existing_public_method
+      end
+    end
+    test_result = run_as_test do
+      klass.stubs(:existing_public_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_method_to_which_class_responds
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    klass = Class.new do
+      class << self
+        def respond_to?(method, include_private = false)
+          (method == :method_to_which_class_responds)
+        end
+      end
+    end
+    test_result = run_as_test do
+      klass.stubs(:method_to_which_class_responds)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_protected_class_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    klass = Class.new do
+      class << self
+        def existing_protected_method; end
+        protected :existing_protected_method
+      end
+    end
+    test_result = run_as_test do
+      klass.stubs(:existing_protected_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_private_class_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    klass = Class.new do
+      class << self
+        def existing_private_method; end
+        private :existing_private_method
+      end
+    end
+    test_result = run_as_test do
+      klass.stubs(:existing_private_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_public_superclass_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    superklass = Class.new do
+      class << self
+        def existing_public_method; end
+        public :existing_public_method
+      end
+    end
+    klass = Class.new(superklass)
+    test_result = run_as_test do
+      klass.stubs(:existing_public_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_protected_superclass_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    superklass = Class.new do
+      class << self
+        def existing_protected_method; end
+        protected :existing_protected_method
+      end
+    end
+    klass = Class.new(superklass)
+    test_result = run_as_test do
+      klass.stubs(:existing_protected_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_private_superclass_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    superklass = Class.new do
+      class << self
+        def existing_private_method; end
+        protected :existing_private_method
+      end
+    end
+    klass = Class.new(superklass)
+    test_result = run_as_test do
+      klass.stubs(:existing_private_method)
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_existent_instance_method_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_existent_instance_method_test.rb
new file mode 100755
index 0000000..9bed8ff
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_existent_instance_method_test.rb
@@ -0,0 +1,147 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubbingNonExistentInstanceMethodTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_allow_stubbing_non_existent_instance_method
+    Mocha::Configuration.allow(:stubbing_non_existent_method)
+    instance = Class.new.new
+    test_result = run_as_test do
+      instance.stubs(:non_existent_method)
+    end
+    assert !@logger.warnings.include?("stubbing non-existent method: #{instance.mocha_inspect}.non_existent_method")
+    assert_passed(test_result)
+  end
+
+  def test_should_warn_when_stubbing_non_existent_instance_method
+    Mocha::Configuration.warn_when(:stubbing_non_existent_method)
+    instance = Class.new.new
+    test_result = run_as_test do
+      instance.stubs(:non_existent_method)
+    end
+    assert_passed(test_result)
+    assert @logger.warnings.include?("stubbing non-existent method: #{instance.mocha_inspect}.non_existent_method")
+  end
+
+  def test_should_prevent_stubbing_non_existent_instance_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    instance = Class.new.new
+    test_result = run_as_test do
+      instance.stubs(:non_existent_method)
+    end
+    assert_failed(test_result)
+    assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-existent method: #{instance.mocha_inspect}.non_existent_method")
+  end
+
+  def test_should_default_to_allow_stubbing_non_existent_instance_method
+    instance = Class.new.new
+    test_result = run_as_test do
+      instance.stubs(:non_existent_method)
+    end
+    assert !@logger.warnings.include?("stubbing non-existent method: #{instance.mocha_inspect}.non_existent_method")
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_public_instance_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    klass = Class.new do
+      def existing_public_method; end
+      public :existing_public_method
+    end
+    instance = klass.new
+    test_result = run_as_test do
+      instance.stubs(:existing_public_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_method_to_which_instance_responds
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    klass = Class.new do
+      def respond_to?(method, include_private = false)
+        (method == :method_to_which_instance_responds)
+      end
+    end
+    instance = klass.new
+    test_result = run_as_test do
+      instance.stubs(:method_to_which_instance_responds)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_protected_instance_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    klass = Class.new do
+      def existing_protected_method; end
+      protected :existing_protected_method
+    end
+    instance = klass.new
+    test_result = run_as_test do
+      instance.stubs(:existing_protected_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_private_instance_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    klass = Class.new do
+      def existing_private_method; end
+      private :existing_private_method
+    end
+    instance = klass.new
+    test_result = run_as_test do
+      instance.stubs(:existing_private_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_public_instance_superclass_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    superklass = Class.new do
+      def existing_public_method; end
+      public :existing_public_method
+    end
+    instance = Class.new(superklass).new
+    test_result = run_as_test do
+      instance.stubs(:existing_public_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_protected_instance_superclass_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    superklass = Class.new do
+      def existing_protected_method; end
+      protected :existing_protected_method
+    end
+    instance = Class.new(superklass).new
+    test_result = run_as_test do
+      instance.stubs(:existing_protected_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_existing_private_instance_superclass_method
+    Mocha::Configuration.prevent(:stubbing_non_existent_method)
+    superklass = Class.new do
+      def existing_private_method; end
+      private :existing_private_method
+    end
+    instance = Class.new(superklass).new
+    test_result = run_as_test do
+      instance.stubs(:existing_private_method)
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_public_any_instance_method_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_public_any_instance_method_test.rb
new file mode 100755
index 0000000..330d045
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_public_any_instance_method_test.rb
@@ -0,0 +1,130 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubbingNonPublicAnyInstanceMethodTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_allow_stubbing_private_any_instance_method
+    Mocha::Configuration.allow(:stubbing_non_public_method)
+    klass = Class.new do
+      def private_method; end
+      private :private_method
+    end
+    test_result = run_as_test do
+      klass.any_instance.stubs(:private_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?("stubbing non-public method: #{klass.any_instance.mocha_inspect}.private_method")
+  end
+
+  def test_should_allow_stubbing_protected_any_instance_method
+    Mocha::Configuration.allow(:stubbing_non_public_method)
+    klass = Class.new do
+      def protected_method; end
+      protected :protected_method
+    end
+    test_result = run_as_test do
+      klass.any_instance.stubs(:protected_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?("stubbing non-public method: #{klass.any_instance.mocha_inspect}.protected_method")
+  end
+
+  def test_should_warn_when_stubbing_private_any_instance_method
+    Mocha::Configuration.warn_when(:stubbing_non_public_method)
+    klass = Class.new do
+      def private_method; end
+      private :private_method
+    end
+    test_result = run_as_test do
+      klass.any_instance.stubs(:private_method)
+    end
+    assert_passed(test_result)
+    assert @logger.warnings.include?("stubbing non-public method: #{klass.any_instance.mocha_inspect}.private_method")
+  end
+
+  def test_should_warn_when_stubbing_protected_any_instance_method
+    Mocha::Configuration.warn_when(:stubbing_non_public_method)
+    klass = Class.new do
+      def protected_method; end
+      protected :protected_method
+    end
+    test_result = run_as_test do
+      klass.any_instance.stubs(:protected_method)
+    end
+    assert_passed(test_result)
+    assert @logger.warnings.include?("stubbing non-public method: #{klass.any_instance.mocha_inspect}.protected_method")
+  end
+
+  def test_should_prevent_stubbing_private_any_instance_method
+    Mocha::Configuration.prevent(:stubbing_non_public_method)
+    klass = Class.new do
+      def private_method; end
+      private :private_method
+    end
+    test_result = run_as_test do
+      klass.any_instance.stubs(:private_method)
+    end
+    assert_failed(test_result)
+    assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-public method: #{klass.any_instance.mocha_inspect}.private_method")
+  end
+
+  def test_should_prevent_stubbing_protected_any_instance_method
+    Mocha::Configuration.prevent(:stubbing_non_public_method)
+    klass = Class.new do
+      def protected_method; end
+      protected :protected_method
+    end
+    test_result = run_as_test do
+      klass.any_instance.stubs(:protected_method)
+    end
+    assert_failed(test_result)
+    assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-public method: #{klass.any_instance.mocha_inspect}.protected_method")
+  end
+
+  def test_should_default_to_allow_stubbing_private_any_instance_method
+    klass = Class.new do
+      def private_method; end
+      private :private_method
+    end
+    test_result = run_as_test do
+      klass.any_instance.stubs(:private_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?("stubbing non-public method: #{klass.any_instance.mocha_inspect}.private_method")
+  end
+
+  def test_should_default_to_allow_stubbing_protected_any_instance_method
+    klass = Class.new do
+      def protected_method; end
+      protected :protected_method
+    end
+    test_result = run_as_test do
+      klass.any_instance.stubs(:protected_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?("stubbing non-public method: #{klass.any_instance.mocha_inspect}.protected_method")
+  end
+
+  def test_should_allow_stubbing_public_any_instance_method
+    Mocha::Configuration.prevent(:stubbing_non_public_method)
+    klass = Class.new do
+      def public_method; end
+      public :public_method
+    end
+    test_result = run_as_test do
+      klass.any_instance.stubs(:public_method)
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_public_class_method_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_public_class_method_test.rb
new file mode 100755
index 0000000..aa5cff0
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_public_class_method_test.rb
@@ -0,0 +1,163 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubbingNonPublicClassMethodTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_allow_stubbing_private_class_method
+    Mocha::Configuration.allow(:stubbing_non_public_method)
+    klass = Class.new do
+      class << self
+        def private_method; end
+        private :private_method
+      end
+    end
+    test_result = run_as_test do
+      klass.stubs(:private_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?("stubbing non-public method: #{klass.mocha_inspect}.private_method")
+  end
+
+  def test_should_allow_stubbing_protected_class_method
+    Mocha::Configuration.allow(:stubbing_non_public_method)
+    klass = Class.new do
+      class << self
+        def protected_method; end
+        protected :protected_method
+      end
+    end
+    test_result = run_as_test do
+      klass.stubs(:protected_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?("stubbing non-public method: #{klass.mocha_inspect}.protected_method")
+  end
+
+  def test_should_warn_when_stubbing_private_class_method
+    Mocha::Configuration.warn_when(:stubbing_non_public_method)
+    klass = Class.new do
+      class << self
+        def private_method; end
+        private :private_method
+      end
+    end
+    test_result = run_as_test do
+      klass.stubs(:private_method)
+    end
+    assert_passed(test_result)
+    assert @logger.warnings.include?("stubbing non-public method: #{klass.mocha_inspect}.private_method")
+  end
+
+  def test_should_warn_when_stubbing_protected_class_method
+    Mocha::Configuration.warn_when(:stubbing_non_public_method)
+    klass = Class.new do
+      class << self
+        def protected_method; end
+        protected :protected_method
+      end
+    end
+    test_result = run_as_test do
+      klass.stubs(:protected_method)
+    end
+    assert_passed(test_result)
+    assert @logger.warnings.include?("stubbing non-public method: #{klass.mocha_inspect}.protected_method")
+  end
+
+  def test_should_prevent_stubbing_private_class_method
+    Mocha::Configuration.prevent(:stubbing_non_public_method)
+    klass = Class.new do
+      class << self
+        def private_method; end
+        private :private_method
+      end
+    end
+    test_result = run_as_test do
+      klass.stubs(:private_method)
+    end
+    assert_failed(test_result)
+    assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-public method: #{klass.mocha_inspect}.private_method")
+  end
+
+  def test_should_prevent_stubbing_protected_class_method
+    Mocha::Configuration.prevent(:stubbing_non_public_method)
+    klass = Class.new do
+      class << self
+        def protected_method; end
+        protected :protected_method
+      end
+    end
+    test_result = run_as_test do
+      klass.stubs(:protected_method)
+    end
+    assert_failed(test_result)
+    assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-public method: #{klass.mocha_inspect}.protected_method")
+  end
+
+  def test_should_default_to_allow_stubbing_private_class_method
+    klass = Class.new do
+      class << self
+        def private_method; end
+        private :private_method
+      end
+    end
+    test_result = run_as_test do
+      klass.stubs(:private_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?("stubbing non-public method: #{klass.mocha_inspect}.private_method")
+  end
+
+  def test_should_default_to_allow_stubbing_protected_class_method
+    klass = Class.new do
+      class << self
+        def protected_method; end
+        protected :protected_method
+      end
+    end
+    test_result = run_as_test do
+      klass.stubs(:protected_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?("stubbing non-public method: #{klass.mocha_inspect}.protected_method")
+  end
+
+  def test_should_allow_stubbing_public_class_method
+    Mocha::Configuration.prevent(:stubbing_non_public_method)
+    klass = Class.new do
+      class << self
+        def public_method; end
+        public :public_method
+      end
+    end
+    test_result = run_as_test do
+      klass.stubs(:public_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_method_to_which_class_responds
+    Mocha::Configuration.prevent(:stubbing_non_public_method)
+    klass = Class.new do
+      class << self
+        def respond_to?(method, include_private_methods = false)
+          (method == :method_to_which_class_responds)
+        end
+      end
+    end
+    test_result = run_as_test do
+      klass.stubs(:method_to_which_class_responds)
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_public_instance_method_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_public_instance_method_test.rb
new file mode 100755
index 0000000..3e497d3
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_non_public_instance_method_test.rb
@@ -0,0 +1,143 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubbingNonPublicInstanceMethodTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_allow_stubbing_private_instance_method
+    Mocha::Configuration.allow(:stubbing_non_public_method)
+    instance = Class.new do
+      def private_method; end
+      private :private_method
+    end.new
+    test_result = run_as_test do
+      instance.stubs(:private_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?("stubbing non-public method: #{instance.mocha_inspect}.private_method")
+  end
+
+  def test_should_allow_stubbing_protected_instance_method
+    Mocha::Configuration.allow(:stubbing_non_public_method)
+    instance = Class.new do
+      def protected_method; end
+      protected :protected_method
+    end.new
+    test_result = run_as_test do
+      instance.stubs(:protected_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?("stubbing non-public method: #{instance.mocha_inspect}.protected_method")
+  end
+
+  def test_should_warn_when_stubbing_private_instance_method
+    Mocha::Configuration.warn_when(:stubbing_non_public_method)
+    instance = Class.new do
+      def private_method; end
+      private :private_method
+    end.new
+    test_result = run_as_test do
+      instance.stubs(:private_method)
+    end
+    assert_passed(test_result)
+    assert @logger.warnings.include?("stubbing non-public method: #{instance.mocha_inspect}.private_method")
+  end
+
+  def test_should_warn_when_stubbing_protected_instance_method
+    Mocha::Configuration.warn_when(:stubbing_non_public_method)
+    instance = Class.new do
+      def protected_method; end
+      protected :protected_method
+    end.new
+    test_result = run_as_test do
+      instance.stubs(:protected_method)
+    end
+    assert_passed(test_result)
+    assert @logger.warnings.include?("stubbing non-public method: #{instance.mocha_inspect}.protected_method")
+  end
+
+  def test_should_prevent_stubbing_private_instance_method
+    Mocha::Configuration.prevent(:stubbing_non_public_method)
+    instance = Class.new do
+      def private_method; end
+      private :private_method
+    end.new
+    test_result = run_as_test do
+      instance.stubs(:private_method)
+    end
+    assert_failed(test_result)
+    assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-public method: #{instance.mocha_inspect}.private_method")
+  end
+
+  def test_should_prevent_stubbing_protected_instance_method
+    Mocha::Configuration.prevent(:stubbing_non_public_method)
+    instance = Class.new do
+      def protected_method; end
+      protected :protected_method
+    end.new
+    test_result = run_as_test do
+      instance.stubs(:protected_method)
+    end
+    assert_failed(test_result)
+    assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-public method: #{instance.mocha_inspect}.protected_method")
+  end
+
+  def test_should_default_to_allow_stubbing_private_instance_method
+    instance = Class.new do
+      def private_method; end
+      private :private_method
+    end.new
+    test_result = run_as_test do
+      instance.stubs(:private_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?("stubbing non-public method: #{instance.mocha_inspect}.private_method")
+  end
+
+  def test_should_default_to_allow_stubbing_protected_instance_method
+    instance = Class.new do
+      def protected_method; end
+      protected :protected_method
+    end.new
+    test_result = run_as_test do
+      instance.stubs(:protected_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?("stubbing non-public method: #{instance.mocha_inspect}.protected_method")
+  end
+
+  def test_should_allow_stubbing_public_instance_method
+    Mocha::Configuration.prevent(:stubbing_non_public_method)
+    instance = Class.new do
+      def public_method; end
+      public :public_method
+    end.new
+    test_result = run_as_test do
+      instance.stubs(:public_method)
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_allow_stubbing_method_to_which_instance_responds
+    Mocha::Configuration.prevent(:stubbing_non_public_method)
+    instance = Class.new do
+      def respond_to?(method, include_private_methods = false)
+        (method == :method_to_which_instance_responds)
+      end
+    end.new
+    test_result = run_as_test do
+      instance.stubs(:method_to_which_instance_responds)
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_on_non_mock_object_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_on_non_mock_object_test.rb
new file mode 100755
index 0000000..6c0804c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_on_non_mock_object_test.rb
@@ -0,0 +1,64 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubbingOnNonMockObjectTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_allow_stubbing_method_on_non_mock_object
+    Mocha::Configuration.allow(:stubbing_method_on_non_mock_object)
+    non_mock_object = Class.new { def existing_method; end }
+    test_result = run_as_test do
+      non_mock_object.stubs(:existing_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?("stubbing method on non-mock object: #{non_mock_object.mocha_inspect}.existing_method")
+  end
+
+  def test_should_warn_on_stubbing_method_on_non_mock_object
+    Mocha::Configuration.warn_when(:stubbing_method_on_non_mock_object)
+    non_mock_object = Class.new { def existing_method; end }
+    test_result = run_as_test do
+      non_mock_object.stubs(:existing_method)
+    end
+    assert_passed(test_result)
+    assert @logger.warnings.include?("stubbing method on non-mock object: #{non_mock_object.mocha_inspect}.existing_method")
+  end
+
+  def test_should_prevent_stubbing_method_on_non_mock_object
+    Mocha::Configuration.prevent(:stubbing_method_on_non_mock_object)
+    non_mock_object = Class.new { def existing_method; end }
+    test_result = run_as_test do
+      non_mock_object.stubs(:existing_method)
+    end
+    assert_failed(test_result)
+    assert test_result.error_messages.include?("Mocha::StubbingError: stubbing method on non-mock object: #{non_mock_object.mocha_inspect}.existing_method")
+  end
+
+  def test_should_default_to_allow_stubbing_method_on_non_mock_object
+    non_mock_object = Class.new { def existing_method; end }
+    test_result = run_as_test do
+      non_mock_object.stubs(:existing_method)
+    end
+    assert_passed(test_result)
+    assert !@logger.warnings.include?("stubbing method on non-mock object: #{non_mock_object.mocha_inspect}.existing_method")
+  end
+
+  def test_should_allow_stubbing_method_on_mock_object
+    Mocha::Configuration.prevent(:stubbing_method_on_non_mock_object)
+    test_result = run_as_test do
+      mock = mock('mock')
+      mock.stubs(:any_method)
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_same_class_method_on_parent_and_child_classes_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_same_class_method_on_parent_and_child_classes_test.rb
new file mode 100755
index 0000000..cd3eda8
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/stubbing_same_class_method_on_parent_and_child_classes_test.rb
@@ -0,0 +1,35 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class StubbingSameClassMethodOnParentAndChildClassTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_stubbing_same_method_on_parent_and_child_classes
+    parent_class = Class.new do
+      def self.foo
+        "Parent.foo"
+      end
+    end
+    child_class = Class.new(parent_class)
+    test_result = run_as_tests(
+      :test_1 => lambda {
+        parent_class.stubs(:foo).returns("stubbed Parent.foo")
+        child_class.stubs(:foo).returns("stubbed Child.foo")
+      },
+      :test_2 => lambda {
+        parent_class.foo
+        child_class.foo
+      }
+    )
+    assert_passed(test_result)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/throw_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/throw_test.rb
new file mode 100755
index 0000000..6f7252f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/throw_test.rb
@@ -0,0 +1,45 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class ThrowTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_should_throw_tag
+    test_result = run_as_test do
+      foo = stub('foo')
+      foo.stubs(:bar).throws(:tag)
+      assert_throws(:tag) { foo.bar }
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_throw_with_return_value
+    test_result = run_as_test do
+      foo = stub('foo')
+      foo.stubs(:bar).throws(:tag, 'return-value')
+      return_value = catch(:tag) { foo.bar }
+      assert_equal 'return-value', return_value
+    end
+    assert_passed(test_result)
+  end
+
+  def test_should_throw_two_different_tags
+    test_result = run_as_test do
+      foo = stub('foo')
+      foo.stubs(:bar).throws(:tag_one).then.throws(:tag_two)
+      assert_throws(:tag_one) { foo.bar }
+      assert_throws(:tag_two) { foo.bar }
+    end
+    assert_passed(test_result)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/unexpected_invocation_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/unexpected_invocation_test.rb
new file mode 100755
index 0000000..8365772
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/unexpected_invocation_test.rb
@@ -0,0 +1,25 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class UnexpectedInvocationTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_avoid_recursion_when_unexpected_invocation_exception_message_depends_on_uninspectable_object
+    test_result = run_as_test do
+      instance = Class.new.new
+      instance.expects(:inspect).never
+      instance.inspect(1, 2, 'foo')
+    end
+    assert_failed(test_result)
+    assert_equal "unexpected invocation: inspect(1, 2, foo)", test_result.failure_message_lines[0]
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/mocha-1.1.0/test/acceptance/unstubbing_test.rb b/app/server/vendor/mocha-1.1.0/test/acceptance/unstubbing_test.rb
new file mode 100755
index 0000000..ad4a65f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/acceptance/unstubbing_test.rb
@@ -0,0 +1,168 @@
+require File.expand_path('../acceptance_test_helper', __FILE__)
+require 'mocha/setup'
+
+class UnstubbingTest < Mocha::TestCase
+
+  include AcceptanceTest
+
+  def setup
+    setup_acceptance_test
+  end
+
+  def teardown
+    teardown_acceptance_test
+  end
+
+  def test_unstubbing_an_instance_method_should_restore_original_behaviour
+    klass = Class.new do
+      def my_instance_method; :original_return_value; end
+    end
+    test_result = run_as_test do
+      object = klass.new
+      object.stubs(:my_instance_method).returns(:new_return_value)
+      object.unstub(:my_instance_method)
+      assert_equal :original_return_value, object.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_unstubbing_a_class_method_should_restore_original_behaviour
+    klass = Class.new do
+      def self.my_class_method; :original_return_value; end
+    end
+    test_result = run_as_test do
+      klass.stubs(:my_class_method).returns(:new_return_value)
+      klass.unstub(:my_class_method)
+      assert_equal :original_return_value, klass.my_class_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_unstubbing_a_module_method_should_restore_original_behaviour
+    mod = Module.new do
+      def self.my_module_method; :original_return_value; end
+    end
+    test_result = run_as_test do
+      mod.stubs(:my_module_method).returns(:new_return_value)
+      mod.unstub(:my_module_method)
+      assert_equal :original_return_value, mod.my_module_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_unstubbing_a_module_method_defined_like_fileutils_in_ruby_2_0_should_restore_original_behaviour
+    mod = Module.new do
+      def my_module_method; :original_return_value; end
+      private :my_module_method
+      extend self
+      class << self
+        public :my_module_method
+      end
+    end
+    test_result = run_as_test do
+      mod.stubs(:my_module_method).returns(:new_return_value)
+      mod.unstub(:my_module_method)
+      assert_equal :original_return_value, mod.my_module_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_unstubbing_an_any_instance_method_should_restore_original_behaviour
+    klass = Class.new do
+      def my_instance_method; :original_return_value; end
+    end
+    test_result = run_as_test do
+      object = klass.new
+      klass.any_instance.stubs(:my_instance_method).returns(:new_return_value)
+      klass.any_instance.unstub(:my_instance_method)
+      assert_equal :original_return_value, object.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_unstubbing_multiple_methods_should_restore_original_behaviour
+    klass = Class.new do
+      def my_first_instance_method; :original_return_value; end
+      def my_second_instance_method; :original_return_value; end
+    end
+    test_result = run_as_test do
+      object = klass.new
+      object.stubs(:my_first_instance_method).returns(:new_return_value)
+      object.stubs(:my_second_instance_method).returns(:new_return_value)
+      object.unstub(:my_first_instance_method, :my_second_instance_method)
+      assert_equal :original_return_value, object.my_first_instance_method
+      assert_equal :original_return_value, object.my_second_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_unstubbing_a_method_multiple_times_should_restore_original_behaviour
+    klass = Class.new do
+      def my_instance_method; :original_return_value; end
+    end
+    test_result = run_as_test do
+      object = klass.new
+      object.stubs(:my_instance_method).returns(:new_return_value)
+      object.unstub(:my_instance_method)
+      object.unstub(:my_instance_method)
+      assert_equal :original_return_value, object.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_unstubbing_a_non_stubbed_method_should_do_nothing
+    klass = Class.new do
+      def my_instance_method; :original_return_value; end
+    end
+    test_result = run_as_test do
+      object = klass.new
+      object.unstub(:my_instance_method)
+      assert_equal :original_return_value, object.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_unstubbing_a_method_which_was_stubbed_multiple_times_should_restore_orginal_behaviour
+    klass = Class.new do
+      def my_instance_method; :original_return_value; end
+    end
+    test_result = run_as_test do
+      object = klass.new
+      object.stubs(:my_instance_method).with(:first).returns(:first_new_return_value)
+      object.stubs(:my_instance_method).with(:second).returns(:second_new_return_value)
+      object.unstub(:my_instance_method)
+      assert_equal :original_return_value, object.my_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_unstubbing_a_method_should_not_unstub_other_stubbed_methods
+    klass = Class.new do
+      def my_first_instance_method; :first_return_value; end
+      def my_second_instance_method; :second_return_value; end
+    end
+
+    test_result = run_as_test do
+      object = klass.new
+      object.stubs(:my_first_instance_method).returns(:first_new_return_value)
+      object.stubs(:my_second_instance_method).returns(:second_new_return_value)
+      object.unstub(:my_first_instance_method)
+      assert_equal :first_return_value, object.my_first_instance_method
+      assert_equal :second_new_return_value, object.my_second_instance_method
+    end
+    assert_passed(test_result)
+  end
+
+  def test_unstubbing_a_method_should_remove_all_expectations_for_that_method
+    klass = Class.new do
+      def my_instance_method; :original_return_value; end
+    end
+    test_result = run_as_test do
+      object = klass.new
+      object.expects(:my_instance_method).with(:first)
+      object.expects(:my_instance_method).with(:second)
+      object.unstub(:my_instance_method)
+    end
+    assert_passed(test_result)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/assertions.rb b/app/server/vendor/mocha-1.1.0/test/assertions.rb
new file mode 100755
index 0000000..0b84199
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/assertions.rb
@@ -0,0 +1,6 @@
+module Assertions
+  def assert_method_visiblity(object, method_name, visiblity)
+    method_key = RUBY_VERSION < '1.9' ? method_name.to_s : method_name.to_sym
+    assert object.send("#{visiblity}_methods", false).include?(method_key), "#{method_name} is not #{visiblity}"
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/mocha-1.1.0/test/deprecation_disabler.rb b/app/server/vendor/mocha-1.1.0/test/deprecation_disabler.rb
new file mode 100755
index 0000000..f2f3cf2
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/deprecation_disabler.rb
@@ -0,0 +1,15 @@
+require 'mocha/deprecation'
+
+module DeprecationDisabler
+
+  def disable_deprecations
+    original_mode = Mocha::Deprecation.mode
+    Mocha::Deprecation.mode = :disabled
+    begin
+      yield
+    ensure
+      Mocha::Deprecation.mode = original_mode
+    end
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/execution_point.rb b/app/server/vendor/mocha-1.1.0/test/execution_point.rb
new file mode 100755
index 0000000..0e7db09
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/execution_point.rb
@@ -0,0 +1,36 @@
+class ExecutionPoint
+
+  attr_reader :backtrace
+
+  def self.current
+    new(caller)
+  end
+
+  def initialize(backtrace)
+    @backtrace = backtrace
+  end
+
+  def file_name
+    return "unknown" unless @backtrace && @backtrace.first
+    /\A(.*?):\d+/.match(@backtrace.first)[1]
+  end
+
+  def line_number
+    return "unknown" unless @backtrace && @backtrace.first
+    Integer(/\A.*?:(\d+)/.match(@backtrace.first)[1])
+  end
+
+  def ==(other)
+    return false unless other.is_a?(ExecutionPoint)
+    (file_name == other.file_name) and (line_number == other.line_number)
+  end
+
+  def to_s
+    "file: #{file_name}; line: #{line_number}"
+  end
+
+  def inspect
+    to_s
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/integration/mini_test_test.rb b/app/server/vendor/mocha-1.1.0/test/integration/mini_test_test.rb
new file mode 100755
index 0000000..33f529c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/integration/mini_test_test.rb
@@ -0,0 +1,8 @@
+require File.expand_path('../../test_helper', __FILE__)
+
+require "mocha/mini_test"
+require "integration/shared_tests"
+
+class MiniTestTest < Mocha::TestCase
+  include SharedTests
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/integration/shared_tests.rb b/app/server/vendor/mocha-1.1.0/test/integration/shared_tests.rb
new file mode 100755
index 0000000..869eea4
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/integration/shared_tests.rb
@@ -0,0 +1,174 @@
+require 'test_runner'
+require 'execution_point'
+
+module SharedTests
+  include TestRunner
+
+  def test_assertion_satisfied
+    test_result = run_as_test do
+      assert true
+    end
+    assert_passed(test_result)
+  end
+
+  def test_assertion_unsatisfied
+    execution_point = nil
+    test_result = run_as_test do
+      execution_point = ExecutionPoint.current; flunk
+    end
+    assert_failed(test_result)
+    failure = test_result.failures.first
+    assert_equal execution_point, ExecutionPoint.new(failure.location)
+  end
+
+  def test_mock_object_unexpected_invocation
+    execution_point = nil
+    test_result = run_as_test do
+      mock = mock("not expecting invocation")
+      execution_point = ExecutionPoint.current; mock.unexpected
+    end
+    assert_failed(test_result)
+    failure = test_result.failures.first
+    assert_equal execution_point, ExecutionPoint.new(failure.location)
+    assert_equal ["unexpected invocation: #<Mock:not expecting invocation>.unexpected()"], test_result.failure_message_lines
+  end
+
+  def test_mock_object_explicitly_unexpected_invocation
+    execution_point = nil
+    test_result = run_as_test do
+      mock = mock("not expecting invocation")
+      mock.expects(:unexpected).never
+      execution_point = ExecutionPoint.current; mock.unexpected
+    end
+    assert_failed(test_result)
+    failure = test_result.failures.first
+    assert_equal execution_point, ExecutionPoint.new(failure.location)
+    assert_equal [
+      "unexpected invocation: #<Mock:not expecting invocation>.unexpected()",
+      "unsatisfied expectations:",
+      "- expected never, invoked once: #<Mock:not expecting invocation>.unexpected(any_parameters)"
+    ], test_result.failure_message_lines
+  end
+
+  def test_mock_object_unsatisfied_expectation
+    execution_point = nil
+    test_result = run_as_test do
+      mock = mock("expecting invocation")
+      execution_point = ExecutionPoint.current; mock.expects(:expected)
+    end
+    assert_failed(test_result)
+    failure = test_result.failures.first
+    assert_equal execution_point, ExecutionPoint.new(failure.location)
+    assert_equal [
+      "not all expectations were satisfied",
+      "unsatisfied expectations:",
+      "- expected exactly once, not yet invoked: #<Mock:expecting invocation>.expected(any_parameters)"
+    ], test_result.failure_message_lines
+  end
+
+  def test_mock_object_unexpected_invocation_in_setup
+    execution_point = nil
+    test_result = run_as_tests(
+      :setup => lambda {
+        mock = mock("not expecting invocation")
+        execution_point = ExecutionPoint.current; mock.unexpected
+      },
+      :test_me => lambda {
+        assert true
+      }
+    )
+    assert_failed(test_result)
+    failure = test_result.failures.first
+    assert_equal execution_point, ExecutionPoint.new(failure.location)
+    assert_equal ["unexpected invocation: #<Mock:not expecting invocation>.unexpected()"], test_result.failure_message_lines
+  end
+
+  def test_mock_object_unsatisfied_expectation_in_setup
+    execution_point = nil
+    test_result = run_as_tests(
+      :setup => lambda {
+        mock = mock("expecting invocation")
+        execution_point = ExecutionPoint.current; mock.expects(:expected)
+      },
+      :test_me => lambda {
+        assert true
+      }
+    )
+    assert_failed(test_result)
+    failure = test_result.failures.first
+    assert_equal execution_point, ExecutionPoint.new(failure.location)
+    assert_equal [
+      "not all expectations were satisfied",
+      "unsatisfied expectations:",
+      "- expected exactly once, not yet invoked: #<Mock:expecting invocation>.expected(any_parameters)"
+    ], test_result.failure_message_lines
+  end
+
+  def test_mock_object_unexpected_invocation_in_teardown
+    execution_point = nil
+    test_result = run_as_tests(
+      :test_me => lambda {
+        assert true
+      },
+      :teardown => lambda {
+        mock = mock("not expecting invocation")
+        execution_point = ExecutionPoint.current; mock.unexpected
+      }
+    )
+    assert_failed(test_result)
+    failure = test_result.failures.first
+    assert_equal execution_point, ExecutionPoint.new(failure.location)
+    assert_equal ["unexpected invocation: #<Mock:not expecting invocation>.unexpected()"], test_result.failure_message_lines
+  end
+
+  def test_real_object_explicitly_unexpected_invocation
+    execution_point = nil
+    object = Object.new
+    test_result = run_as_test do
+      object.expects(:unexpected).never
+      execution_point = ExecutionPoint.current; object.unexpected
+    end
+    assert_failed(test_result)
+    failure = test_result.failures.first
+    assert_equal execution_point, ExecutionPoint.new(failure.location)
+    assert_equal [
+      "unexpected invocation: #{object.mocha_inspect}.unexpected()",
+      "unsatisfied expectations:",
+      "- expected never, invoked once: #{object.mocha_inspect}.unexpected(any_parameters)"
+    ], test_result.failure_message_lines
+  end
+
+  def test_real_object_unsatisfied_expectation
+    execution_point = nil
+    object = Object.new
+    test_result = run_as_test do
+      execution_point = ExecutionPoint.current; object.expects(:expected)
+    end
+    assert_failed(test_result)
+    failure = test_result.failures.first
+    assert_equal execution_point, ExecutionPoint.new(failure.location)
+    assert_equal [
+      "not all expectations were satisfied",
+      "unsatisfied expectations:",
+      "- expected exactly once, not yet invoked: #{object.mocha_inspect}.expected(any_parameters)"
+    ], test_result.failure_message_lines
+  end
+
+  def test_real_object_expectation_does_not_leak_into_subsequent_test
+    execution_point = nil
+    klass = Class.new
+    test_result = run_as_tests(
+      :test_1 => lambda {
+        klass.expects(:foo)
+        klass.foo
+      },
+      :test_2 => lambda {
+        execution_point = ExecutionPoint.current; klass.foo
+      }
+    )
+    assert_failed(test_result)
+    exception = test_result.errors.first.exception
+    assert_equal execution_point, ExecutionPoint.new(exception.backtrace)
+    assert_match %r{undefined method `foo'}, exception.message
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/integration/test_unit_test.rb b/app/server/vendor/mocha-1.1.0/test/integration/test_unit_test.rb
new file mode 100755
index 0000000..489eeb3
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/integration/test_unit_test.rb
@@ -0,0 +1,8 @@
+require File.expand_path('../../test_helper', __FILE__)
+
+require "mocha/test_unit"
+require "integration/shared_tests"
+
+class TestUnitTest < Mocha::TestCase
+  include SharedTests
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/method_definer.rb b/app/server/vendor/mocha-1.1.0/test/method_definer.rb
new file mode 100755
index 0000000..332f254
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/method_definer.rb
@@ -0,0 +1,24 @@
+require 'metaclass'
+
+module Mocha
+
+  module ObjectMethods
+    def define_instance_method(method_symbol, &block)
+      __metaclass__.send(:define_method, method_symbol, block)
+    end
+
+    def replace_instance_method(method_symbol, &block)
+      raise "Cannot replace #{method_symbol} as #{self} does not respond to it." unless self.respond_to?(method_symbol)
+      define_instance_method(method_symbol, &block)
+    end
+
+    def define_instance_accessor(*symbols)
+      symbols.each { |symbol| __metaclass__.send(:attr_accessor, symbol) }
+    end
+  end
+
+end
+
+class Object
+  include Mocha::ObjectMethods
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/mini_test_result.rb b/app/server/vendor/mocha-1.1.0/test/mini_test_result.rb
new file mode 100755
index 0000000..992d7ed
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/mini_test_result.rb
@@ -0,0 +1,90 @@
+require 'stringio'
+require 'minitest/unit'
+
+class MiniTestResult
+
+  minitest_version = Gem::Version.new(::MiniTest::Unit::VERSION)
+  if Gem::Requirement.new('<= 4.6.1').satisfied_by?(minitest_version)
+    FAILURE_PATTERN = %r{(Failure)\:\n([^\(]+)\(([^\)]+)\) \[([^\]]+)\]\:\n(.*)\n}m
+    ERROR_PATTERN   = %r{(Error)\:\n([^\(]+)\(([^\)]+)\)\:\n(.+?)\n}m
+    PATTERN_INDICES = { :method => 2, :testcase => 3 }
+  else
+    FAILURE_PATTERN = %r{(Failure)\:\n.([^#]+)\#([^ ]+) \[([^\]]+)\]\:\n(.*)\n}m
+    ERROR_PATTERN   = %r{(Error)\:\n.([^#]+)\#([^ ]+)\:\n(.+?)\n}m
+    PATTERN_INDICES = { :method => 3, :testcase => 2 }
+  end
+
+  def self.parse_failure(raw)
+    matches = FAILURE_PATTERN.match(raw)
+    return nil unless matches
+    Failure.new(matches[PATTERN_INDICES[:method]], matches[PATTERN_INDICES[:testcase]], [matches[4]], matches[5])
+  end
+
+  def self.parse_error(raw)
+    matches = ERROR_PATTERN.match(raw)
+    return nil unless matches
+    backtrace = raw.gsub(ERROR_PATTERN, '').split("\n").map(&:strip)
+    Error.new(matches[PATTERN_INDICES[:method]], matches[PATTERN_INDICES[:testcase]], matches[4], backtrace)
+  end
+
+  class Failure
+    attr_reader :method, :test_case, :location, :message
+    def initialize(method, test_case, location, message)
+      @method, @test_case, @location, @message = method, test_case, location, message
+    end
+  end
+
+  class Error
+    class Exception
+      attr_reader :message, :backtrace
+      def initialize(message, location)
+        @message, @backtrace = message, location
+      end
+    end
+
+    attr_reader :method, :test_case, :exception
+    def initialize(method, test_case, message, backtrace)
+      @method, @test_case, @exception = method, test_case, Exception.new(message, backtrace)
+    end
+  end
+
+  def initialize(runner, tests)
+    @runner, @tests = runner, tests
+  end
+
+  def failure_count
+    @runner.failures
+  end
+
+  def assertion_count
+    @tests.inject(0) { |total, test| total + test._assertions }
+  end
+
+  def error_count
+    @runner.errors
+  end
+
+  def passed?
+    @tests.all?(&:passed?)
+  end
+
+  def failures
+    @runner.report.map { |puked| MiniTestResult.parse_failure(puked) }.compact
+  end
+
+  def errors
+    @runner.report.map { |puked| MiniTestResult.parse_error(puked) }.compact
+  end
+
+  def failure_messages
+    failures.map(&:message)
+  end
+
+  def failure_message_lines
+    failure_messages.map { |message| message.split("\n") }.flatten
+  end
+
+  def error_messages
+    errors.map { |e| e.exception.message }
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/minitest_result.rb b/app/server/vendor/mocha-1.1.0/test/minitest_result.rb
new file mode 100755
index 0000000..af05cd7
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/minitest_result.rb
@@ -0,0 +1,49 @@
+require 'forwardable'
+
+class MinitestResult
+
+  class Failure
+    extend Forwardable
+    def_delegators :@failure, :message, :backtrace
+
+    def initialize(failure)
+      @failure = failure
+    end
+
+    def location
+      Minitest.filter_backtrace(backtrace)
+    end
+  end
+
+  def initialize(tests)
+    @tests = tests
+  end
+
+  def failures
+    @tests.map(&:failures).flatten.select { |r| Minitest::Assertion === r }.map { |f| Failure.new(f) }
+  end
+
+  def failure_count
+    failures.length
+  end
+
+  def failure_message_lines
+    failures.map { |f| f.message.split("\n") }.flatten
+  end
+
+  def errors
+    @tests.map(&:failures).flatten.select { |r| Minitest::UnexpectedError === r }
+  end
+
+  def error_count
+    errors.length
+  end
+
+  def error_messages
+    errors.map { |e| e.message.split("\n") }.flatten
+  end
+
+  def assertion_count
+    @tests.inject(0) { |total, test| total + test.assertions }
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/simple_counter.rb b/app/server/vendor/mocha-1.1.0/test/simple_counter.rb
new file mode 100755
index 0000000..10b03a5
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/simple_counter.rb
@@ -0,0 +1,13 @@
+class SimpleCounter
+
+  attr_reader :count
+
+  def initialize
+    @count = 0
+  end
+
+  def increment
+    @count += 1
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/test_helper.rb b/app/server/vendor/mocha-1.1.0/test/test_helper.rb
new file mode 100755
index 0000000..e25405f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/test_helper.rb
@@ -0,0 +1,50 @@
+unless defined?(STANDARD_OBJECT_PUBLIC_INSTANCE_METHODS)
+  STANDARD_OBJECT_PUBLIC_INSTANCE_METHODS = Object.instance_methods + Object.private_instance_methods
+end
+
+$:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
+$:.unshift File.expand_path(File.join(File.dirname(__FILE__)))
+$:.unshift File.expand_path(File.join(File.dirname(__FILE__), 'unit'))
+$:.unshift File.expand_path(File.join(File.dirname(__FILE__), 'unit', 'parameter_matchers'))
+$:.unshift File.expand_path(File.join(File.dirname(__FILE__), 'acceptance'))
+
+require 'mocha/detection/mini_test'
+
+begin
+  require 'minitest'
+rescue LoadError
+end
+begin
+  require 'minitest/unit'
+rescue LoadError
+end
+
+module Mocha; end
+
+if (minitest_testcase = Mocha::Detection::MiniTest.testcase) && (ENV['MOCHA_RUN_INTEGRATION_TESTS'] != 'test-unit')
+  begin
+    require 'minitest/autorun'
+  rescue LoadError
+    MiniTest::Unit.autorun
+  end
+  class Mocha::TestCase < minitest_testcase
+    def assert_nothing_raised(exception = StandardError)
+      yield
+    rescue exception => e
+      flunk "Unexpected exception raised: #{e}"
+    end
+
+    alias_method :assert_not_nil, :refute_nil
+    alias_method :assert_raise, :assert_raises
+    alias_method :assert_not_same, :refute_same
+    alias_method :assert_no_match, :refute_match
+  end
+else
+  require 'test/unit'
+  class Mocha::TestCase < Test::Unit::TestCase
+    def test_dummy
+      # Some versions (?) of Test::Unit try to run this base class as a test case
+      # and it fails because it has no test methods, so I'm adding a dummy test.
+    end
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/test_runner.rb b/app/server/vendor/mocha-1.1.0/test/test_runner.rb
new file mode 100755
index 0000000..dc7c51d
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/test_runner.rb
@@ -0,0 +1,58 @@
+require 'assertions'
+
+require 'mocha/detection/mini_test'
+
+module TestRunner
+  def run_as_test(&block)
+    run_as_tests(:test_me => block)
+  end
+
+  def run_as_tests(methods = {})
+    base_class = Mocha::TestCase
+    test_class = Class.new(base_class) do
+      include Assertions
+
+      methods.each do |(method_name, proc)|
+        define_method(method_name, proc)
+      end
+    end
+
+    tests = methods.keys.select { |m| m.to_s[/^test/] }.map { |m| test_class.new(m) }
+
+    if Mocha::Detection::MiniTest.testcase && (ENV['MOCHA_RUN_INTEGRATION_TESTS'] != 'test-unit')
+      minitest_version = Gem::Version.new(Mocha::Detection::MiniTest.version)
+      if Gem::Requirement.new('>= 5.0.0').satisfied_by?(minitest_version)
+        require File.expand_path('../minitest_result', __FILE__)
+        tests.each do |test|
+          test.run
+        end
+        Minitest::Runnable.runnables.delete(test_class)
+        test_result = MinitestResult.new(tests)
+      elsif Gem::Requirement.new('> 0.0.0', '< 5.0.0').satisfied_by?(minitest_version)
+        require File.expand_path('../mini_test_result', __FILE__)
+        runner = MiniTest::Unit.new
+        tests.each do |test|
+          test.run(runner)
+        end
+        test_result = MiniTestResult.new(runner, tests)
+      end
+    else
+      require File.expand_path('../test_unit_result', __FILE__)
+      test_result = TestUnitResult.build_test_result
+      tests.each do |test|
+        test.run(test_result) {}
+      end
+    end
+
+    test_result
+  end
+
+  def assert_passed(test_result)
+    flunk "Test failed unexpectedly with message: #{test_result.failures}" if test_result.failure_count > 0
+    flunk "Test failed unexpectedly with message: #{test_result.errors}" if test_result.error_count > 0
+  end
+
+  def assert_failed(test_result)
+    flunk "Test passed unexpectedly" unless test_result.failure_count + test_result.error_count > 0
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/test_unit_result.rb b/app/server/vendor/mocha-1.1.0/test/test_unit_result.rb
new file mode 100755
index 0000000..1c9671d
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/test_unit_result.rb
@@ -0,0 +1,20 @@
+require 'test/unit/testresult'
+
+class TestUnitResult
+  def self.build_test_result
+    test_result = Test::Unit::TestResult.new
+    class << test_result
+      attr_reader :failures, :errors
+      def failure_messages
+        failures.map { |failure| failure.message }
+      end
+      def failure_message_lines
+        failure_messages.map { |message| message.split("\n") }.flatten
+      end
+      def error_messages
+        errors.map { |error| error.message }
+      end
+    end
+    test_result
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/any_instance_method_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/any_instance_method_test.rb
new file mode 100755
index 0000000..8876058
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/any_instance_method_test.rb
@@ -0,0 +1,132 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'method_definer'
+require 'mocha/mock'
+require 'mocha/any_instance_method'
+
+class AnyInstanceMethodTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_hide_original_method
+    klass = Class.new { def method_x; end }
+    method = AnyInstanceMethod.new(klass, :method_x)
+
+    method.hide_original_method
+
+    assert_equal false, klass.method_defined?(:method_x)
+  end
+
+  def test_should_not_raise_error_hiding_method_that_isnt_defined
+    klass = Class.new
+    method = AnyInstanceMethod.new(klass, :method_x)
+
+    assert_nothing_raised { method.hide_original_method }
+  end
+
+  def test_should_define_a_new_method
+    klass = Class.new { def method_x; end }
+    method = AnyInstanceMethod.new(klass, :method_x)
+    mocha = build_mock
+    mocha.expects(:method_x).with(:param1, :param2).returns(:result)
+    any_instance = Object.new
+    any_instance.define_instance_method(:mocha) { mocha }
+    klass.define_instance_method(:any_instance) { any_instance }
+
+    method.hide_original_method
+    method.define_new_method
+
+    instance = klass.new
+    result = instance.method_x(:param1, :param2)
+
+    assert_equal :result, result
+    assert mocha.__verified__?
+  end
+
+  def test_should_restore_original_method
+    klass = Class.new { def method_x; :original_result; end }
+    method = AnyInstanceMethod.new(klass, :method_x)
+
+    method.hide_original_method
+    method.define_new_method
+    method.remove_new_method
+    method.restore_original_method
+
+    instance = klass.new
+    assert instance.respond_to?(:method_x)
+    assert_equal :original_result, instance.method_x
+  end
+
+  def test_should_not_restore_original_method_if_none_was_defined_in_first_place
+    klass = Class.new { def method_x; :new_result; end }
+    method = AnyInstanceMethod.new(klass, :method_x)
+
+    method.restore_original_method
+
+    instance = klass.new
+    assert_equal :new_result, instance.method_x
+  end
+
+  def test_should_call_remove_new_method
+    klass = Class.new { def method_x; end }
+    any_instance = build_mock
+    any_instance_mocha = build_mock
+    any_instance.stubs(:mocha).returns(any_instance_mocha)
+    klass.define_instance_method(:any_instance) { any_instance }
+    method = AnyInstanceMethod.new(klass, :method_x)
+    method.replace_instance_method(:restore_original_method) { }
+    method.define_instance_accessor(:remove_called)
+    method.replace_instance_method(:remove_new_method) { self.remove_called = true }
+
+    method.unstub
+
+    assert method.remove_called
+  end
+
+  def test_should_call_restore_original_method
+    klass = Class.new { def method_x; end }
+    any_instance = build_mock
+    any_instance_mocha = build_mock
+    any_instance.stubs(:mocha).returns(any_instance_mocha)
+    klass.define_instance_method(:any_instance) { any_instance }
+    method = AnyInstanceMethod.new(klass, :method_x)
+    method.replace_instance_method(:remove_new_method) { }
+    method.define_instance_accessor(:restore_called)
+    method.replace_instance_method(:restore_original_method) { self.restore_called = true }
+
+    method.unstub
+
+    assert method.restore_called
+  end
+
+  def test_should_call_mock_unstub
+    klass = Class.new { def method_x; end }
+
+    method = AnyInstanceMethod.new(klass, :method_x)
+
+    method.replace_instance_method(:remove_new_method) { }
+    method.replace_instance_method(:restore_original_method) { }
+    mocha = Class.new { class << self; attr_accessor :unstub_method; end; def self.unstub(method); self.unstub_method = method; end; }
+    mocha.define_instance_method(:any_expectations?) { true }
+    method.replace_instance_method(:mock) { mocha }
+
+    method.unstub
+
+    assert_equal mocha.unstub_method, :method_x
+  end
+
+  def test_should_return_any_instance_mocha_for_stubbee
+    mocha = Object.new
+    any_instance = Object.new
+    any_instance.define_instance_method(:mocha) { mocha }
+    stubbee = Class.new
+    stubbee.define_instance_method(:any_instance) { any_instance }
+    method = AnyInstanceMethod.new(stubbee, :method_name)
+    assert_equal stubbee.any_instance.mocha, method.mock
+  end
+
+  private
+
+  def build_mock
+    Mock.new(nil)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/array_inspect_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/array_inspect_test.rb
new file mode 100755
index 0000000..6f39703
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/array_inspect_test.rb
@@ -0,0 +1,16 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/inspect'
+
+class ArrayInspectTest < Mocha::TestCase
+
+  def test_should_use_inspect
+    array = [1, 2]
+    assert_equal array.inspect, array.mocha_inspect
+  end
+
+  def test_should_use_mocha_inspect_on_each_item
+    array = [1, 2, "chris"]
+    assert_equal "[1, 2, 'chris']", array.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/backtrace_filter_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/backtrace_filter_test.rb
new file mode 100755
index 0000000..00556c1
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/backtrace_filter_test.rb
@@ -0,0 +1,19 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/backtrace_filter'
+
+class BacktraceFilterTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_exclude_mocha_locations_from_backtrace
+    mocha_lib = "/username/workspace/mocha_wibble/lib/"
+    backtrace = [ mocha_lib + 'exclude/me/1', mocha_lib + 'exclude/me/2', '/keep/me', mocha_lib + 'exclude/me/3']
+    filter = BacktraceFilter.new(mocha_lib)
+    assert_equal ['/keep/me'], filter.filtered(backtrace)
+  end
+
+  def test_should_determine_path_for_mocha_lib_directory
+    assert_match Regexp.new("/lib/$"), BacktraceFilter::LIB_DIRECTORY
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/cardinality_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/cardinality_test.rb
new file mode 100755
index 0000000..feaa095
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/cardinality_test.rb
@@ -0,0 +1,56 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/cardinality'
+
+class CardinalityTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_allow_invocations_if_invocation_count_has_not_yet_reached_maximum
+    cardinality = Cardinality.new(2, 3)
+    assert cardinality.invocations_allowed?(0)
+    assert cardinality.invocations_allowed?(1)
+    assert cardinality.invocations_allowed?(2)
+    assert !cardinality.invocations_allowed?(3)
+  end
+
+  def test_should_be_satisfied_if_invocations_so_far_have_reached_required_threshold
+    cardinality = Cardinality.new(2, 3)
+    assert !cardinality.satisfied?(0)
+    assert !cardinality.satisfied?(1)
+    assert cardinality.satisfied?(2)
+    assert cardinality.satisfied?(3)
+  end
+
+  def test_should_describe_cardinality
+    assert_equal 'allowed any number of times', Cardinality.at_least(0).mocha_inspect
+
+    assert_equal 'expected at most once', Cardinality.at_most(1).mocha_inspect
+    assert_equal 'expected at most twice', Cardinality.at_most(2).mocha_inspect
+    assert_equal 'expected at most 3 times', Cardinality.at_most(3).mocha_inspect
+
+    assert_equal 'expected at least once', Cardinality.at_least(1).mocha_inspect
+    assert_equal 'expected at least twice', Cardinality.at_least(2).mocha_inspect
+    assert_equal 'expected at least 3 times', Cardinality.at_least(3).mocha_inspect
+
+    assert_equal 'expected never', Cardinality.exactly(0).mocha_inspect
+    assert_equal 'expected exactly once', Cardinality.exactly(1).mocha_inspect
+    assert_equal 'expected exactly twice', Cardinality.exactly(2).mocha_inspect
+    assert_equal 'expected exactly 3 times', Cardinality.times(3).mocha_inspect
+
+    assert_equal 'expected between 2 and 4 times', Cardinality.times(2..4).mocha_inspect
+    assert_equal 'expected between 1 and 3 times', Cardinality.times(1..3).mocha_inspect
+  end
+
+  def test_should_need_verifying
+    assert Cardinality.exactly(2).needs_verifying?
+    assert Cardinality.at_least(3).needs_verifying?
+    assert Cardinality.at_most(2).needs_verifying?
+    assert Cardinality.times(4).needs_verifying?
+    assert Cardinality.times(2..4).needs_verifying?
+  end
+
+  def test_should_not_need_verifying
+    assert_equal false, Cardinality.at_least(0).needs_verifying?
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/central_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/central_test.rb
new file mode 100755
index 0000000..2169e60
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/central_test.rb
@@ -0,0 +1,100 @@
+require File.expand_path('../../test_helper', __FILE__)
+
+require 'mocha/central'
+require 'mocha/mock'
+require 'method_definer'
+
+class CentralTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_start_with_empty_stubba_methods
+    stubba = Central.new
+
+    assert_equal [], stubba.stubba_methods
+  end
+
+  def test_should_stub_method_if_not_already_stubbed
+    method = build_mock
+    method.expects(:stub)
+    stubba = Central.new
+
+    stubba.stub(method)
+
+    assert method.__verified__?
+  end
+
+  def test_should_not_stub_method_if_already_stubbed
+    method = build_mock
+    method.stubs(:matches?).returns(true)
+    method.expects(:stub).times(0)
+    stubba = Central.new
+    stubba.stubba_methods = [method]
+
+    stubba.stub(method)
+
+    assert method.__verified__?
+  end
+
+  def test_should_record_method
+    method = build_mock
+    method.expects(:stub)
+    stubba = Central.new
+
+    stubba.stub(method)
+
+    assert_equal [method], stubba.stubba_methods
+  end
+
+  def test_should_unstub_specified_method
+    stubba = Central.new
+    method_1 = build_mock
+    method_1.stubs(:matches?).returns(false)
+    method_2 = build_mock
+    method_2.stubs(:matches?).returns(true)
+    method_2.expects(:unstub)
+    stubba.stubba_methods = [method_1, method_2]
+
+    stubba.unstub(method_2)
+
+    assert_equal [method_1], stubba.stubba_methods
+    assert method_2.__verified__?
+  end
+
+  def test_should_not_unstub_specified_method_if_not_already_stubbed
+    stubba = Central.new
+    method_1 = build_mock
+    method_1.stubs(:matches?).returns(false)
+    method_2 = build_mock
+    method_2.expects(:unstub).never
+    stubba.stubba_methods = [method_1]
+
+    stubba.unstub(method_2)
+
+    assert_equal [method_1], stubba.stubba_methods
+    assert method_2.__verified__?
+  end
+
+  def test_should_unstub_all_methods
+    stubba = Central.new
+    method_1 = build_mock
+    method_1.stubs(:matches?).returns(true)
+    method_1.expects(:unstub)
+    method_2 = build_mock
+    method_2.stubs(:matches?).returns(true)
+    method_2.expects(:unstub)
+    stubba.stubba_methods = [method_1, method_2]
+
+    stubba.unstub_all
+
+    assert_equal [], stubba.stubba_methods
+    assert method_1.__verified__?
+    assert method_2.__verified__?
+  end
+
+  private
+
+  def build_mock
+    Mock.new(nil)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/change_state_side_effect_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/change_state_side_effect_test.rb
new file mode 100755
index 0000000..986b2e5
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/change_state_side_effect_test.rb
@@ -0,0 +1,41 @@
+require File.expand_path('../../test_helper', __FILE__)
+
+require 'mocha/change_state_side_effect'
+
+class ChangeStateSideEffectTest < Mocha::TestCase
+
+  include Mocha
+
+  class FakeState
+
+    attr_reader :active
+    attr_writer :description
+
+    def activate
+      @active = true
+    end
+
+    def mocha_inspect
+      @description
+    end
+
+  end
+
+  def test_should_activate_the_given_state
+    state = FakeState.new
+    side_effect = ChangeStateSideEffect.new(state)
+
+    side_effect.perform
+
+    assert state.active
+  end
+
+  def test_should_describe_itself_in_terms_of_the_activated_state
+    state = FakeState.new
+    state.description = 'the-new-state'
+    side_effect = ChangeStateSideEffect.new(state)
+
+    assert_equal 'then the-new-state', side_effect.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/class_method_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/class_method_test.rb
new file mode 100755
index 0000000..b349d0c
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/class_method_test.rb
@@ -0,0 +1,223 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'method_definer'
+require 'mocha/mock'
+
+require 'mocha/class_method'
+
+class ClassMethodTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_hide_original_method
+    klass = Class.new { def self.method_x; end }
+    method = ClassMethod.new(klass, :method_x)
+
+    method.hide_original_method
+
+    assert_equal false, klass.respond_to?(:method_x)
+  end
+
+  def test_should_not_raise_error_hiding_method_that_isnt_defined
+    klass = Class.new
+    method = ClassMethod.new(klass, :method_x)
+
+    assert_nothing_raised { method.hide_original_method }
+  end
+
+  def test_should_not_raise_error_hiding_method_in_class_that_implements_method_called_method
+    klass = Class.new { def self.method; end }
+    method = ClassMethod.new(klass, :method)
+
+    assert_nothing_raised { method.hide_original_method }
+  end
+
+  def test_should_define_a_new_method_which_should_call_mocha_method_missing
+    klass = Class.new { def self.method_x; end }
+    mocha = build_mock
+    klass.define_instance_method(:mocha) { mocha }
+    mocha.expects(:method_x).with(:param1, :param2).returns(:result)
+    method = ClassMethod.new(klass, :method_x)
+
+    method.hide_original_method
+    method.define_new_method
+    result = klass.method_x(:param1, :param2)
+
+    assert_equal :result, result
+    assert mocha.__verified__?
+  end
+
+  def test_should_remove_new_method
+    klass = Class.new { def self.method_x; end }
+    method = ClassMethod.new(klass, :method_x)
+
+    method.remove_new_method
+
+    assert_equal false, klass.respond_to?(:method_x)
+  end
+
+  def test_should_restore_original_method
+    klass = Class.new { def self.method_x; :original_result; end }
+    method = ClassMethod.new(klass, :method_x)
+
+    method.hide_original_method
+    method.define_new_method
+    method.remove_new_method
+    method.restore_original_method
+
+    assert klass.respond_to?(:method_x)
+    assert_equal :original_result, klass.method_x
+  end
+
+  def test_should_restore_original_method_accepting_a_block_parameter
+    klass = Class.new { def self.method_x(&block); block.call if block_given? ; end }
+    method = ClassMethod.new(klass, :method_x)
+
+    method.hide_original_method
+    method.define_new_method
+    method.remove_new_method
+    method.restore_original_method
+
+    block_called = false
+    klass.method_x { block_called = true }
+    assert block_called
+  end
+
+  def test_should_not_restore_original_method_if_none_was_defined_in_first_place
+    klass = Class.new { def self.method_x; :new_result; end }
+    method = ClassMethod.new(klass, :method_x)
+
+    method.restore_original_method
+
+    assert_equal :new_result, klass.method_x
+  end
+
+  def test_should_call_hide_original_method
+    klass = Class.new { def self.method_x; end }
+    method = ClassMethod.new(klass, :method_x)
+    method.hide_original_method
+    method.define_instance_accessor(:hide_called)
+    method.replace_instance_method(:hide_original_method) { self.hide_called = true }
+
+    method.stub
+
+    assert method.hide_called
+  end
+
+  def test_should_call_define_new_method
+    klass = Class.new { def self.method_x; end }
+    method = ClassMethod.new(klass, :method_x)
+    method.define_instance_accessor(:define_called)
+    method.replace_instance_method(:define_new_method) { self.define_called = true }
+
+    method.stub
+
+    assert method.define_called
+  end
+
+  def test_should_call_remove_new_method
+    klass = Class.new { def self.method_x; end }
+    method = ClassMethod.new(klass, :method_x)
+    mocha = build_mock
+    klass.define_instance_method(:mocha) { mocha }
+    method.define_instance_accessor(:remove_called)
+    method.replace_instance_method(:remove_new_method) { self.remove_called = true }
+
+    method.unstub
+
+    assert method.remove_called
+  end
+
+  def test_should_call_restore_original_method
+    klass = Class.new { def self.method_x; end }
+    mocha = build_mock
+    klass.define_instance_method(:mocha) { mocha }
+    method = ClassMethod.new(klass, :method_x)
+    method.define_instance_accessor(:restore_called)
+    method.replace_instance_method(:restore_original_method) { self.restore_called = true }
+
+    method.unstub
+
+    assert method.restore_called
+  end
+
+  def test_should_call_mocha_unstub
+    klass = Class.new { def self.method_x; end }
+    method = ClassMethod.new(klass, :method_x)
+    method.replace_instance_method(:restore_original_method) { }
+    mocha = Class.new { class << self; attr_accessor :unstub_method; end; def self.unstub(method); self.unstub_method = method; end; }
+    mocha.define_instance_method(:any_expectations?) { true }
+    method.replace_instance_method(:mock) { mocha }
+
+    method.unstub
+    assert_equal mocha.unstub_method, :method_x
+  end
+
+  def test_should_call_stubbee_reset_mocha_if_no_expectations_remaining
+    klass = Class.new { def self.method_x; end }
+    method = ClassMethod.new(klass, :method_x)
+    method.replace_instance_method(:remove_new_method) { }
+    method.replace_instance_method(:restore_original_method) { }
+    mocha = Class.new
+    mocha.define_instance_method(:unstub) { |method_name| }
+    mocha.define_instance_method(:any_expectations?) { false }
+    method.replace_instance_method(:mock) { mocha }
+    stubbee = Class.new { attr_accessor :reset_mocha_called; def reset_mocha; self.reset_mocha_called = true; end; }.new
+    method.replace_instance_method(:stubbee) { stubbee }
+
+    method.unstub
+
+    assert stubbee.reset_mocha_called
+  end
+
+  def test_should_return_mock_for_stubbee
+    mocha = Object.new
+    stubbee = Object.new
+    stubbee.define_instance_accessor(:mocha) { mocha }
+    stubbee.mocha = nil
+    method = ClassMethod.new(stubbee, :method_name)
+    assert_equal stubbee.mocha, method.mock
+  end
+
+  def test_should_not_match_if_other_object_has_a_different_class
+    class_method = ClassMethod.new(Object.new, :method)
+    other_object = Object.new
+    assert !class_method.matches?(other_object)
+  end
+
+  def test_should_not_match_if_other_class_method_has_different_stubbee
+    stubbee_1 = Object.new
+    stubbee_2 = Object.new
+    class_method_1 = ClassMethod.new(stubbee_1, :method)
+    class_method_2 = ClassMethod.new(stubbee_2, :method)
+    assert !class_method_1.matches?(class_method_2)
+  end
+
+  def test_should_not_match_if_other_class_method_has_different_method
+    stubbee = Object.new
+    class_method_1 = ClassMethod.new(stubbee, :method_1)
+    class_method_2 = ClassMethod.new(stubbee, :method_2)
+    assert !class_method_1.matches?(class_method_2)
+  end
+
+  def test_should_match_if_other_class_method_has_same_stubbee_and_same_method_so_no_attempt_is_made_to_stub_a_method_twice
+    stubbee = Object.new
+    class_method_1 = ClassMethod.new(stubbee, :method)
+    class_method_2 = ClassMethod.new(stubbee, :method)
+    assert class_method_1.matches?(class_method_2)
+  end
+
+  def test_should_match_if_other_class_method_has_same_stubbee_and_same_method_but_stubbee_equal_method_lies_like_active_record_association_proxy
+    stubbee = Class.new do
+      def equal?(other); false; end
+    end.new
+    class_method_1 = ClassMethod.new(stubbee, :method)
+    class_method_2 = ClassMethod.new(stubbee, :method)
+    assert class_method_1.matches?(class_method_2)
+  end
+
+  private
+
+  def build_mock
+    Mock.new(nil)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/class_methods_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/class_methods_test.rb
new file mode 100755
index 0000000..0686bbc
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/class_methods_test.rb
@@ -0,0 +1,40 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/class_methods'
+require 'mocha/object_methods'
+
+class ClassMethodsTest < Mocha::TestCase
+
+  def setup
+    @klass = Class.new.extend(Mocha::ClassMethods, Mocha::ObjectMethods)
+  end
+
+  def test_should_build_any_instance_object
+    any_instance = @klass.any_instance
+    assert_not_nil any_instance
+    assert any_instance.is_a?(Mocha::ClassMethods::AnyInstance)
+  end
+
+  def test_should_return_same_any_instance_object
+    any_instance_1 = @klass.any_instance
+    any_instance_2 = @klass.any_instance
+    assert_equal any_instance_1, any_instance_2
+  end
+
+  def test_should_use_stubba_class_method_for_class
+    assert_equal Mocha::ClassMethod, @klass.stubba_method
+  end
+
+  def test_should_use_stubba_class_method_for_any_instance
+    assert_equal Mocha::AnyInstanceMethod, @klass.any_instance.stubba_method
+  end
+
+  def test_should_stub_self_for_class
+    assert_equal @klass, @klass.stubba_object
+  end
+
+  def test_should_stub_relevant_class_for_any_instance
+    any_instance = @klass.any_instance
+    assert_equal @klass, any_instance.stubba_object
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/configuration_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/configuration_test.rb
new file mode 100755
index 0000000..e00bfe6
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/configuration_test.rb
@@ -0,0 +1,38 @@
+require File.expand_path('../../test_helper', __FILE__)
+require "mocha/configuration"
+
+class ConfigurationTest < Mocha::TestCase
+  def test_allow_temporarily_changes_config_when_given_block
+    Mocha::Configuration.warn_when(:stubbing_method_unnecessarily)
+    yielded = false
+    Mocha::Configuration.allow(:stubbing_method_unnecessarily) do
+      yielded = true
+      assert Mocha::Configuration.allow?(:stubbing_method_unnecessarily)
+    end
+    assert yielded
+    assert Mocha::Configuration.warn_when?(:stubbing_method_unnecessarily)
+  end
+
+  def test_prevent_temporarily_changes_config_when_given_block
+    Mocha::Configuration.allow(:stubbing_method_unnecessarily)
+    yielded = false
+    Mocha::Configuration.prevent(:stubbing_method_unnecessarily) do
+      yielded = true
+      assert Mocha::Configuration.prevent?(:stubbing_method_unnecessarily)
+    end
+    assert yielded
+    assert Mocha::Configuration.allow?(:stubbing_method_unnecessarily)
+  end
+
+  def test_warn_when_temporarily_changes_config_when_given_block
+    Mocha::Configuration.allow(:stubbing_method_unnecessarily)
+    yielded = false
+    Mocha::Configuration.warn_when(:stubbing_method_unnecessarily) do
+      yielded = true
+      assert Mocha::Configuration.warn_when?(:stubbing_method_unnecessarily)
+    end
+    assert yielded
+    assert Mocha::Configuration.allow?(:stubbing_method_unnecessarily)
+  end
+end
+
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/date_time_inspect_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/date_time_inspect_test.rb
new file mode 100755
index 0000000..f2e0ebd
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/date_time_inspect_test.rb
@@ -0,0 +1,21 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/inspect'
+
+class DateTimeInspectTest < Mocha::TestCase
+
+  def test_should_use_include_date_in_seconds
+    time = Time.now
+    assert_equal "#{time.inspect} (#{time.to_f} secs)", time.mocha_inspect
+  end
+
+  def test_should_use_to_s_for_date
+    date = Date.new(2006, 1, 1)
+    assert_equal date.to_s, date.mocha_inspect
+  end
+
+  def test_should_use_to_s_for_datetime
+    datetime = DateTime.new(2006, 1, 1)
+    assert_equal datetime.to_s, datetime.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/exception_raiser_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/exception_raiser_test.rb
new file mode 100755
index 0000000..5407423
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/exception_raiser_test.rb
@@ -0,0 +1,42 @@
+require File.expand_path('../../test_helper', __FILE__)
+
+require 'mocha/exception_raiser'
+require 'timeout'
+
+class ExceptionRaiserTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_raise_exception_with_specified_class_and_default_message
+    exception_class = Class.new(StandardError)
+    raiser = ExceptionRaiser.new(exception_class, nil)
+    exception = assert_raises(exception_class) { raiser.evaluate }
+    assert_equal exception_class.to_s, exception.message
+  end
+
+  def test_should_raise_exception_with_specified_class_and_message
+    exception_class = Class.new(StandardError)
+    raiser = ExceptionRaiser.new(exception_class, 'message')
+    exception = assert_raises(exception_class) { raiser.evaluate }
+    assert_equal 'message', exception.message
+  end
+
+  def test_should_raise_exception_instance
+    exception_class = Class.new(StandardError)
+    raiser = ExceptionRaiser.new(exception_class.new('message'), nil)
+    exception = assert_raises(exception_class) { raiser.evaluate }
+    assert_equal 'message', exception.message
+  end
+
+  def test_should_raise_interrupt_exception_with_default_message_so_it_works_in_ruby_1_8_6
+    raiser = ExceptionRaiser.new(Interrupt, nil)
+    assert_raises(Interrupt) { raiser.evaluate }
+  end
+
+  def test_should_raise_subclass_of_interrupt_exception_with_default_message_so_it_works_in_ruby_1_8_6
+    exception_class = Class.new(Interrupt)
+    raiser = ExceptionRaiser.new(exception_class, nil)
+    assert_raises(exception_class) { raiser.evaluate }
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/expectation_list_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/expectation_list_test.rb
new file mode 100755
index 0000000..bf41b9f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/expectation_list_test.rb
@@ -0,0 +1,82 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/expectation_list'
+require 'mocha/expectation'
+require 'set'
+require 'method_definer'
+
+class ExpectationListTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_return_added_expectation
+    expectation_list = ExpectationList.new
+    expectation = Expectation.new(nil, :my_method)
+    assert_same expectation, expectation_list.add(expectation)
+  end
+
+  def test_should_find_matching_expectation
+    expectation_list = ExpectationList.new
+    expectation1 = Expectation.new(nil, :my_method).with(:argument1, :argument2)
+    expectation2 = Expectation.new(nil, :my_method).with(:argument3, :argument4)
+    expectation_list.add(expectation1)
+    expectation_list.add(expectation2)
+    assert_same expectation1, expectation_list.match(:my_method, :argument1, :argument2)
+  end
+
+  def test_should_remove_all_expectations_matching_method_name
+    expectation_list = ExpectationList.new
+    expectation1 = Expectation.new(nil, :method_one).with(:argument1, :argument2)
+    expectation2 = Expectation.new(nil, :method_one).with(:argument3, :argument4)
+    expectation3 = Expectation.new(nil, :method_two)
+    expectation_list.add(expectation1)
+    expectation_list.add(expectation2)
+    expectation_list.add(expectation3)
+    expectation_list.remove_all_matching_method(:method_one)
+    assert_nil expectation_list.match(:method_one, :argument1, :argument2)
+    assert_nil expectation_list.match(:method_one, :argument3, :argument4)
+    assert_same expectation3, expectation_list.match(:method_two)
+  end
+
+  def test_should_find_most_recent_matching_expectation
+    expectation_list = ExpectationList.new
+    expectation1 = Expectation.new(nil, :my_method).with(:argument1, :argument2)
+    expectation2 = Expectation.new(nil, :my_method).with(:argument1, :argument2)
+    expectation_list.add(expectation1)
+    expectation_list.add(expectation2)
+    assert_same expectation2, expectation_list.match(:my_method, :argument1, :argument2)
+  end
+
+  def test_should_find_matching_expectation_allowing_invocation
+    expectation_list = ExpectationList.new
+    expectation1 = Expectation.new(nil, :my_method).with(:argument1, :argument2)
+    expectation2 = Expectation.new(nil, :my_method).with(:argument3, :argument4)
+    expectation1.define_instance_method(:invocations_allowed?) { true }
+    expectation2.define_instance_method(:invocations_allowed?) { true }
+    expectation_list.add(expectation1)
+    expectation_list.add(expectation2)
+    assert_same expectation1, expectation_list.match_allowing_invocation(:my_method, :argument1, :argument2)
+  end
+
+  def test_should_find_most_recent_matching_expectation_allowing_invocation
+    expectation_list = ExpectationList.new
+    expectation1 = Expectation.new(nil, :my_method)
+    expectation2 = Expectation.new(nil, :my_method)
+    expectation1.define_instance_method(:invocations_allowed?) { true }
+    expectation2.define_instance_method(:invocations_allowed?) { false }
+    expectation_list.add(expectation1)
+    expectation_list.add(expectation2)
+    assert_same expectation1, expectation_list.match_allowing_invocation(:my_method)
+  end
+
+  def test_should_combine_two_expectation_lists_into_one
+    expectation_list1 = ExpectationList.new
+    expectation_list2 = ExpectationList.new
+    expectation1 = Expectation.new(nil, :my_method)
+    expectation2 = Expectation.new(nil, :my_method)
+    expectation_list1.add(expectation1)
+    expectation_list2.add(expectation2)
+    expectation_list = expectation_list1 + expectation_list2
+    assert_equal [expectation1, expectation2], expectation_list.to_a
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/expectation_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/expectation_test.rb
new file mode 100755
index 0000000..e36da67
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/expectation_test.rb
@@ -0,0 +1,497 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'method_definer'
+require 'mocha/expectation'
+require 'mocha/sequence'
+require 'execution_point'
+require 'simple_counter'
+
+class ExpectationTest < Mocha::TestCase
+
+  include Mocha
+
+  def new_expectation
+    Expectation.new(nil, :expected_method)
+  end
+
+  def test_should_match_calls_to_same_method_with_any_parameters
+    assert new_expectation.match?(:expected_method, 1, 2, 3)
+  end
+
+  def test_should_match_calls_to_same_method_with_exactly_zero_parameters
+    expectation = new_expectation.with()
+    assert expectation.match?(:expected_method)
+  end
+
+  def test_should_not_match_calls_to_same_method_with_more_than_zero_parameters
+    expectation = new_expectation.with()
+    assert !expectation.match?(:expected_method, 1, 2, 3)
+  end
+
+  def test_should_match_calls_to_same_method_with_expected_parameter_values
+    expectation = new_expectation.with(1, 2, 3)
+    assert expectation.match?(:expected_method, 1, 2, 3)
+  end
+
+  def test_should_match_calls_to_same_method_with_parameters_constrained_as_expected
+    expectation = new_expectation.with() {|x, y, z| x + y == z}
+    assert expectation.match?(:expected_method, 1, 2, 3)
+  end
+
+  def test_should_not_match_calls_to_different_method_with_parameters_constrained_as_expected
+    expectation = new_expectation.with() {|x, y, z| x + y == z}
+    assert !expectation.match?(:different_method, 1, 2, 3)
+  end
+
+  def test_should_not_match_calls_to_different_methods_with_no_parameters
+    assert !new_expectation.match?(:unexpected_method)
+  end
+
+  def test_should_not_match_calls_to_same_method_with_too_few_parameters
+    expectation = new_expectation.with(1, 2, 3)
+    assert !expectation.match?(:unexpected_method, 1, 2)
+  end
+
+  def test_should_not_match_calls_to_same_method_with_too_many_parameters
+    expectation = new_expectation.with(1, 2)
+    assert !expectation.match?(:unexpected_method, 1, 2, 3)
+  end
+
+  def test_should_not_match_calls_to_same_method_with_unexpected_parameter_values
+    expectation = new_expectation.with(1, 2, 3)
+    assert !expectation.match?(:unexpected_method, 1, 0, 3)
+  end
+
+  def test_should_not_match_calls_to_same_method_with_parameters_not_constrained_as_expected
+    expectation = new_expectation.with() {|x, y, z| x + y == z}
+    assert !expectation.match?(:expected_method, 1, 0, 3)
+  end
+
+  def test_should_allow_invocations_until_expected_invocation_count_is_one_and_actual_invocation_count_would_be_two
+    expectation = new_expectation.times(1)
+    assert expectation.invocations_allowed?
+    expectation.invoke
+    assert !expectation.invocations_allowed?
+  end
+
+  def test_should_allow_invocations_until_expected_invocation_count_is_two_and_actual_invocation_count_would_be_three
+    expectation = new_expectation.times(2)
+    assert expectation.invocations_allowed?
+    expectation.invoke
+    assert expectation.invocations_allowed?
+    expectation.invoke
+    assert !expectation.invocations_allowed?
+  end
+
+  def test_should_allow_invocations_until_expected_invocation_count_is_a_range_from_two_to_three_and_actual_invocation_count_would_be_four
+    expectation = new_expectation.times(2..3)
+    assert expectation.invocations_allowed?
+    expectation.invoke
+    assert expectation.invocations_allowed?
+    expectation.invoke
+    assert expectation.invocations_allowed?
+    expectation.invoke
+    assert !expectation.invocations_allowed?
+  end
+
+  def test_should_store_provided_backtrace
+    backtrace = Object.new
+    expectation = Expectation.new(nil, :expected_method, backtrace)
+    assert_equal backtrace, expectation.backtrace
+  end
+
+  def test_should_default_backtrace_to_caller
+    execution_point = ExecutionPoint.current; expectation = Expectation.new(nil, :expected_method)
+    assert_equal execution_point, ExecutionPoint.new(expectation.backtrace)
+  end
+
+  def test_should_not_yield
+    yielded = false
+    new_expectation.invoke() { yielded = true }
+    assert_equal false, yielded
+  end
+
+  def test_should_yield_no_parameters
+    expectation = new_expectation().yields()
+    yielded_parameters = nil
+    expectation.invoke() { |*parameters| yielded_parameters = parameters }
+    assert_equal Array.new, yielded_parameters
+  end
+
+  def test_should_yield_with_specified_parameters
+    expectation = new_expectation().yields(1, 2, 3)
+    yielded_parameters = nil
+    expectation.invoke() { |*parameters| yielded_parameters = parameters }
+    assert_equal [1, 2, 3], yielded_parameters
+  end
+
+  def test_should_yield_different_parameters_on_consecutive_invocations
+    expectation = new_expectation().yields(1, 2, 3).yields(4, 5)
+    yielded_parameters = []
+    expectation.invoke() { |*parameters| yielded_parameters << parameters }
+    expectation.invoke() { |*parameters| yielded_parameters << parameters }
+    assert_equal [[1, 2, 3], [4, 5]], yielded_parameters
+  end
+
+  def test_should_yield_multiple_times_for_single_invocation
+    expectation = new_expectation().multiple_yields([1, 2, 3], [4, 5])
+    yielded_parameters = []
+    expectation.invoke() { |*parameters| yielded_parameters << parameters }
+    assert_equal [[1, 2, 3], [4, 5]], yielded_parameters
+  end
+
+  def test_should_yield_multiple_times_for_first_invocation_and_once_for_second_invocation
+    expectation = new_expectation().multiple_yields([1, 2, 3], [4, 5]).then.yields(6, 7)
+    yielded_parameters = []
+    expectation.invoke() { |*parameters| yielded_parameters << parameters }
+    expectation.invoke() { |*parameters| yielded_parameters << parameters }
+    assert_equal [[1, 2, 3], [4, 5], [6, 7]], yielded_parameters
+  end
+
+  def test_should_return_specified_value
+    expectation = new_expectation.returns(99)
+    assert_equal 99, expectation.invoke
+  end
+
+  def test_should_return_same_specified_value_multiple_times
+    expectation = new_expectation.returns(99)
+    assert_equal 99, expectation.invoke
+    assert_equal 99, expectation.invoke
+  end
+
+  def test_should_return_specified_values_on_consecutive_calls
+    expectation = new_expectation.returns(99, 100, 101)
+    assert_equal 99, expectation.invoke
+    assert_equal 100, expectation.invoke
+    assert_equal 101, expectation.invoke
+  end
+
+  def test_should_return_specified_values_on_consecutive_calls_even_if_values_are_modified
+    values = [99, 100, 101]
+    expectation = new_expectation.returns(*values)
+    values.shift
+    assert_equal 99, expectation.invoke
+    assert_equal 100, expectation.invoke
+    assert_equal 101, expectation.invoke
+  end
+
+  def test_should_return_nil_by_default
+    assert_nil new_expectation.invoke
+  end
+
+  def test_should_return_nil_if_no_value_specified
+    expectation = new_expectation.returns()
+    assert_nil expectation.invoke
+  end
+
+  def test_should_raise_runtime_exception
+    expectation = new_expectation.raises
+    assert_raise(RuntimeError) { expectation.invoke }
+  end
+
+  def test_should_raise_custom_exception
+    exception = Class.new(Exception)
+    expectation = new_expectation.raises(exception)
+    assert_raise(exception) { expectation.invoke }
+  end
+
+  def test_should_raise_same_instance_of_custom_exception
+    exception_klass = Class.new(StandardError)
+    expected_exception = exception_klass.new
+    expectation = new_expectation.raises(expected_exception)
+    actual_exception = assert_raise(exception_klass) { expectation.invoke }
+    assert_same expected_exception, actual_exception
+  end
+
+  def test_should_use_the_default_exception_message
+    expectation = new_expectation.raises(Exception)
+    exception = assert_raise(Exception) { expectation.invoke }
+    assert_equal Exception.new.message, exception.message
+  end
+
+  def test_should_raise_custom_exception_with_message
+    exception_msg = "exception message"
+    expectation = new_expectation.raises(Exception, exception_msg)
+    exception = assert_raise(Exception) { expectation.invoke }
+    assert_equal exception_msg, exception.message
+  end
+
+  def test_should_return_values_then_raise_exception
+    expectation = new_expectation.returns(1, 2).then.raises()
+    assert_equal 1, expectation.invoke
+    assert_equal 2, expectation.invoke
+    assert_raise(RuntimeError) { expectation.invoke }
+  end
+
+  def test_should_raise_exception_then_return_values
+    expectation = new_expectation.raises().then.returns(1, 2)
+    assert_raise(RuntimeError) { expectation.invoke }
+    assert_equal 1, expectation.invoke
+    assert_equal 2, expectation.invoke
+  end
+
+  def test_should_verify_successfully_if_expected_call_was_made
+    expectation = new_expectation
+    expectation.invoke
+    assert expectation.verified?
+  end
+
+  def test_should_not_verify_successfully_if_call_expected_once_but_invoked_twice
+    expectation = new_expectation.once
+    expectation.invoke
+    expectation.invoke
+    assert !expectation.verified?
+  end
+
+  def test_should_not_verify_successfully_if_call_expected_once_but_not_invoked
+    expectation = new_expectation.once
+    assert !expectation.verified?
+  end
+
+  def test_should_verify_successfully_if_call_expected_once_and_invoked_once
+    expectation = new_expectation.once
+    expectation.invoke
+    assert expectation.verified?
+  end
+
+  def test_should_not_verify_successfully_if_call_expected_twice_and_invoked_three_times
+    expectation = new_expectation.twice
+    expectation.invoke
+    expectation.invoke
+    expectation.invoke
+    assert !expectation.verified?
+  end
+
+  def test_should_not_verify_successfully_if_call_expected_twice_but_invoked_once
+    expectation = new_expectation.twice
+    expectation.invoke
+    assert !expectation.verified?
+  end
+
+  def test_should_verify_successfully_if_call_expected_twice_and_invoked_twice
+    expectation = new_expectation.twice
+    expectation.invoke
+    expectation.invoke
+    assert expectation.verified?
+  end
+
+  def test_should_verify_successfully_if_expected_call_was_made_at_least_once
+    expectation = new_expectation.at_least_once
+    3.times {expectation.invoke}
+    assert expectation.verified?
+  end
+
+  def test_should_not_verify_successfully_if_expected_call_was_not_made_at_least_once
+    expectation = new_expectation.with(1, 2, 3).at_least_once
+    assert !expectation.verified?
+    assert_match(/expected at least once, not yet invoked/i, expectation.mocha_inspect)
+  end
+
+  def test_should_verify_successfully_if_expected_call_was_made_expected_number_of_times
+    expectation = new_expectation.times(2)
+    2.times {expectation.invoke}
+    assert expectation.verified?
+  end
+
+  def test_should_not_verify_successfully_if_expected_call_was_made_too_few_times
+    expectation = new_expectation.times(2)
+    1.times {expectation.invoke}
+    assert !expectation.verified?
+    assert_match(/expected exactly twice, invoked once/i, expectation.mocha_inspect)
+  end
+
+  def test_should_not_verify_successfully_if_expected_call_was_made_too_many_times
+    expectation = new_expectation.times(2)
+    3.times {expectation.invoke}
+    assert !expectation.verified?
+  end
+
+  def test_should_increment_assertion_counter_for_expectation_because_it_does_need_verifyng
+    expectation = new_expectation
+    expectation.invoke
+    assertion_counter = SimpleCounter.new
+    expectation.verified?(assertion_counter)
+    assert_equal 1, assertion_counter.count
+  end
+
+  def test_should_not_increment_assertion_counter_for_stub_because_it_does_not_need_verifying
+    stub = Expectation.new(nil, :expected_method).at_least(0)
+    assertion_counter = SimpleCounter.new
+    stub.verified?(assertion_counter)
+    assert_equal 0, assertion_counter.count
+  end
+
+  def test_should_store_backtrace_from_point_where_expectation_was_created
+    execution_point = ExecutionPoint.current; expectation = Expectation.new(nil, :expected_method)
+    assert_equal execution_point, ExecutionPoint.new(expectation.backtrace)
+  end
+
+  class FakeMock
+
+    def initialize(name)
+      @name = name
+    end
+
+    def mocha_inspect
+      @name
+    end
+
+  end
+
+  def test_should_raise_error_with_message_indicating_which_method_was_expected_to_be_called_on_which_mock_object_with_which_parameters_and_in_what_sequences
+    mock = FakeMock.new('mock')
+    sequence_one = Sequence.new('one')
+    sequence_two = Sequence.new('two')
+    expectation = Expectation.new(mock, :expected_method).with(1, 2, {'a' => true}, {:b => false}, [1, 2, 3]).in_sequence(sequence_one, sequence_two)
+    assert !expectation.verified?
+    assert_match "mock.expected_method(1, 2, {'a' => true}, {:b => false}, [1, 2, 3]); in sequence 'one'; in sequence 'two'", expectation.mocha_inspect
+  end
+
+  class FakeConstraint
+
+    def initialize(allows_invocation_now)
+      @allows_invocation_now = allows_invocation_now
+    end
+
+    def allows_invocation_now?
+      @allows_invocation_now
+    end
+
+  end
+
+  def test_should_be_in_correct_order_if_all_ordering_constraints_allow_invocation_now
+    constraint_one = FakeConstraint.new(allows_invocation_now = true)
+    constraint_two = FakeConstraint.new(allows_invocation_now = true)
+    expectation = Expectation.new(nil, :method_one)
+    expectation.add_ordering_constraint(constraint_one)
+    expectation.add_ordering_constraint(constraint_two)
+    assert expectation.in_correct_order?
+  end
+
+  def test_should_not_be_in_correct_order_if_one_ordering_constraint_does_not_allow_invocation_now
+    constraint_one = FakeConstraint.new(allows_invocation_now = true)
+    constraint_two = FakeConstraint.new(allows_invocation_now = false)
+    expectation = Expectation.new(nil, :method_one)
+    expectation.add_ordering_constraint(constraint_one)
+    expectation.add_ordering_constraint(constraint_two)
+    assert !expectation.in_correct_order?
+  end
+
+  def test_should_match_if_all_ordering_constraints_allow_invocation_now
+    constraint_one = FakeConstraint.new(allows_invocation_now = true)
+    constraint_two = FakeConstraint.new(allows_invocation_now = true)
+    expectation = Expectation.new(nil, :method_one)
+    expectation.add_ordering_constraint(constraint_one)
+    expectation.add_ordering_constraint(constraint_two)
+    assert expectation.match?(:method_one)
+  end
+
+  def test_should_not_match_if_one_ordering_constraints_does_not_allow_invocation_now
+    constraint_one = FakeConstraint.new(allows_invocation_now = true)
+    constraint_two = FakeConstraint.new(allows_invocation_now = false)
+    expectation = Expectation.new(nil, :method_one)
+    expectation.add_ordering_constraint(constraint_one)
+    expectation.add_ordering_constraint(constraint_two)
+    assert !expectation.match?(:method_one)
+  end
+
+  def test_should_not_be_satisfied_when_required_invocation_has_not_been_made
+    expectation = Expectation.new(nil, :method_one).times(1)
+    assert !expectation.satisfied?
+  end
+
+  def test_should_be_satisfied_when_required_invocation_has_been_made
+    expectation = Expectation.new(nil, :method_one).times(1)
+    expectation.invoke
+    assert expectation.satisfied?
+  end
+
+  def test_should_not_be_satisfied_when_minimum_number_of_invocations_has_not_been_made
+    expectation = Expectation.new(nil, :method_one).at_least(2)
+    expectation.invoke
+    assert !expectation.satisfied?
+  end
+
+  def test_should_be_satisfied_when_minimum_number_of_invocations_has_been_made
+    expectation = Expectation.new(nil, :method_one).at_least(2)
+    2.times { expectation.invoke }
+    assert expectation.satisfied?
+  end
+
+  class FakeSequence
+
+    attr_reader :expectations
+
+    def initialize
+      @expectations = []
+    end
+
+    def constrain_as_next_in_sequence(expectation)
+      @expectations << expectation
+    end
+
+  end
+
+  def test_should_tell_sequences_to_constrain_expectation_as_next_in_sequence
+    sequence_one = FakeSequence.new
+    sequence_two = FakeSequence.new
+    expectation = Expectation.new(nil, :method_one)
+    assert_equal expectation, expectation.in_sequence(sequence_one, sequence_two)
+    assert_equal [expectation], sequence_one.expectations
+    assert_equal [expectation], sequence_two.expectations
+  end
+
+  class FakeState
+
+    def initialize
+      @active = false
+    end
+
+    def activate
+      @active = true
+    end
+
+    def active?
+      @active
+    end
+
+  end
+
+  def test_should_change_state_when_expectation_is_invoked
+    state = FakeState.new
+    expectation = Expectation.new(nil, :method_one)
+
+    expectation.then(state)
+
+    expectation.invoke
+    assert state.active?
+  end
+
+  def test_should_match_when_state_is_active
+    state = FakeState.new
+    expectation = Expectation.new(nil, :method_one)
+
+    expectation.when(state)
+    assert !expectation.match?(:method_one)
+
+    state.activate
+    assert expectation.match?(:method_one)
+  end
+
+  def test_should_include_default_representation_of_object_in_inspect
+    object = Object.new
+    class << object
+      define_method(:inspect) { 'mock' }
+    end
+    expectation = Expectation.new(object, :method_one)
+    assert_match Regexp.new("^#<Expectation:0x[0-9A-Fa-f]{1,12} .* >$"), expectation.inspect
+  end
+
+  def test_should_include_output_of_mocha_inspect_in_inspect
+    object = Object.new
+    class << object
+      define_method(:inspect) { 'mock' }
+    end
+    expectation = Expectation.new(object, :method_one)
+    assert expectation.inspect.include?(expectation.mocha_inspect)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/hash_inspect_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/hash_inspect_test.rb
new file mode 100755
index 0000000..125f668
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/hash_inspect_test.rb
@@ -0,0 +1,16 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/inspect'
+
+class HashInspectTest < Mocha::TestCase
+
+  def test_should_keep_spacing_between_key_value
+    hash = {:a => true}
+    assert_equal '{:a => true}', hash.mocha_inspect
+  end
+
+  def test_should_use_mocha_inspect_on_each_item
+    hash = {:a => 'mocha'}
+    assert_equal "{:a => 'mocha'}", hash.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/hooks_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/hooks_test.rb
new file mode 100755
index 0000000..ed05271
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/hooks_test.rb
@@ -0,0 +1,29 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/hooks'
+
+class HooksTest < Mocha::TestCase
+  class Mocha::Mockery
+    class << self
+      attr_writer :instance
+    end
+  end
+
+  class FakeMockery
+    def verify(*args)
+    end
+
+    def teardown
+      raise "exception within Mockery#teardown"
+    end
+  end
+
+  def test_ensure_mockery_instance_is_reset_even_when_an_exception_is_raised_in_mockery_teardown
+    fake_test_case = Object.new.extend(Mocha::Hooks)
+    original_mockery = FakeMockery.new
+    Mocha::Mockery.instance = original_mockery
+
+    fake_test_case.mocha_teardown rescue nil
+
+    assert_not_same Mocha::Mockery.instance, original_mockery
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/in_state_ordering_constraint_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/in_state_ordering_constraint_test.rb
new file mode 100755
index 0000000..5ca4241
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/in_state_ordering_constraint_test.rb
@@ -0,0 +1,43 @@
+require File.expand_path('../../test_helper', __FILE__)
+
+require 'mocha/in_state_ordering_constraint'
+
+class InStateOrderingConstraintTest < Mocha::TestCase
+
+  include Mocha
+
+  class FakeStatePredicate
+
+    attr_writer :active, :description
+
+    def active?
+      @active
+    end
+
+    def mocha_inspect
+      @description
+    end
+
+  end
+
+  def test_should_allow_invocation_when_state_is_active
+    state_predicate = FakeStatePredicate.new
+    ordering_constraint = InStateOrderingConstraint.new(state_predicate)
+
+    state_predicate.active = true
+    assert ordering_constraint.allows_invocation_now?
+
+    state_predicate.active = false
+    assert !ordering_constraint.allows_invocation_now?
+  end
+
+  def test_should_describe_itself_in_terms_of_the_state_predicates_description
+    state_predicate = FakeStatePredicate.new
+    ordering_constraint = InStateOrderingConstraint.new(state_predicate)
+
+    state_predicate.description = 'the-state-predicate'
+
+    assert_equal 'when the-state-predicate', ordering_constraint.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/method_matcher_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/method_matcher_test.rb
new file mode 100755
index 0000000..e112f34
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/method_matcher_test.rb
@@ -0,0 +1,28 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/method_matcher'
+
+class MethodMatcherTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_match_if_actual_method_name_is_same_as_expected_method_name
+    method_matcher = MethodMatcher.new(:method_name)
+    assert method_matcher.match?(:method_name)
+  end
+
+  def test_should_match_if_actual_method_name_is_expected_method_name_as_string
+    method_matcher = MethodMatcher.new(:method_name)
+    assert method_matcher.match?('method_name')
+  end
+
+  def test_should_not_match_if_actual_method_name_is_not_same_as_expected_method_name
+    method_matcher = MethodMatcher.new(:method_name)
+    assert !method_matcher.match?(:different_method_name)
+  end
+
+  def test_should_describe_what_method_is_expected
+    method_matcher = MethodMatcher.new(:method_name)
+    assert_equal "method_name", method_matcher.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/mock_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/mock_test.rb
new file mode 100755
index 0000000..868fec5
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/mock_test.rb
@@ -0,0 +1,341 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/mock'
+require 'mocha/expectation_error_factory'
+require 'set'
+require 'simple_counter'
+
+class MockTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_set_single_expectation
+   mock = build_mock
+   mock.expects(:method1).returns(1)
+   assert_nothing_raised(ExpectationErrorFactory.exception_class) do
+     assert_equal 1, mock.method1
+   end
+  end
+
+  def test_should_build_and_store_expectations
+   mock = build_mock
+   expectation = mock.expects(:method1)
+   assert_not_nil expectation
+   assert_equal [expectation], mock.__expectations__.to_a
+  end
+
+  def test_should_not_stub_everything_by_default
+    mock = build_mock
+    assert_equal false, mock.everything_stubbed
+  end
+
+  def test_should_stub_everything
+    mock = build_mock
+    mock.stub_everything
+    assert_equal true, mock.everything_stubbed
+  end
+
+  def test_should_be_able_to_extend_mock_object_with_module
+    mock = build_mock
+    assert_nothing_raised(ExpectationErrorFactory.exception_class) { mock.extend(Module.new) }
+  end
+
+  def test_should_be_equal
+    mock = build_mock
+    assert_equal true, mock.eql?(mock)
+  end
+
+  if RUBY_VERSION < '1.9'
+    OBJECT_METHODS = STANDARD_OBJECT_PUBLIC_INSTANCE_METHODS.reject { |m| m =~ /^__.*__$/ || ["method_missing", "singleton_method_undefined", "initialize"].include?(m)}
+  else
+    OBJECT_METHODS = STANDARD_OBJECT_PUBLIC_INSTANCE_METHODS.reject { |m| m =~ /^__.*__$/ || [:object_id, :method_missing, :singleton_method_undefined, :initialize, :String, :singleton_method_added].include?(m) }
+  end
+
+  def test_should_be_able_to_mock_standard_object_methods
+    mock = build_mock
+    OBJECT_METHODS.each { |method| mock.__expects__(method.to_sym).returns(method) }
+    OBJECT_METHODS.each { |method| assert_equal method, mock.__send__(method.to_sym) }
+    assert mock.__verified__?
+  end
+
+  def test_should_be_able_to_stub_standard_object_methods
+    mock = build_mock
+    OBJECT_METHODS.each { |method| mock.__stubs__(method.to_sym).returns(method) }
+    OBJECT_METHODS.each { |method| assert_equal method, mock.__send__(method.to_sym) }
+  end
+
+  def test_should_create_and_add_expectations
+    mock = build_mock
+    expectation1 = mock.expects(:method1)
+    expectation2 = mock.expects(:method2)
+    assert_equal [expectation1, expectation2].to_set, mock.__expectations__.to_set
+  end
+
+  def test_should_pass_backtrace_into_expectation
+    mock = build_mock
+    backtrace = Object.new
+    expectation = mock.expects(:method1, backtrace)
+    assert_equal backtrace, expectation.backtrace
+  end
+
+  def test_should_pass_backtrace_into_stub
+    mock = build_mock
+    backtrace = Object.new
+    stub = mock.stubs(:method1, backtrace)
+    assert_equal backtrace, stub.backtrace
+  end
+
+  def test_should_create_and_add_stubs
+    mock = build_mock
+    stub1 = mock.stubs(:method1)
+    stub2 = mock.stubs(:method2)
+    assert_equal [stub1, stub2].to_set, mock.__expectations__.to_set
+  end
+
+  def test_should_invoke_expectation_and_return_result
+    mock = build_mock
+    mock.expects(:my_method).returns(:result)
+    result = mock.my_method
+    assert_equal :result, result
+  end
+
+  def test_should_not_raise_error_if_stubbing_everything
+    mock = build_mock
+    mock.stub_everything
+    result = nil
+    assert_nothing_raised(ExpectationErrorFactory.exception_class) do
+      result = mock.unexpected_method
+    end
+    assert_nil result
+  end
+
+  def test_should_raise_assertion_error_for_unexpected_method_call
+    mock = build_mock
+    error = assert_raise(ExpectationErrorFactory.exception_class) do
+      mock.unexpected_method_called(:my_method, :argument1, :argument2)
+    end
+    assert_match(/unexpected invocation/, error.message)
+    assert_match(/my_method/, error.message)
+    assert_match(/argument1/, error.message)
+    assert_match(/argument2/, error.message)
+  end
+
+  def test_should_not_verify_successfully_because_not_all_expectations_have_been_satisfied
+    mock = build_mock
+    mock.expects(:method1)
+    mock.expects(:method2)
+    mock.method1
+    assert !mock.__verified__?
+  end
+
+  def test_should_increment_assertion_counter_for_every_verified_expectation
+    mock = build_mock
+
+    mock.expects(:method1)
+    mock.method1
+
+    mock.expects(:method2)
+    mock.method2
+
+    assertion_counter = SimpleCounter.new
+
+    mock.__verified__?(assertion_counter)
+
+    assert_equal 2, assertion_counter.count
+  end
+
+  def test_should_yield_supplied_parameters_to_block
+    mock = build_mock
+    parameters_for_yield = [1, 2, 3]
+    mock.expects(:method1).yields(*parameters_for_yield)
+    yielded_parameters = nil
+    mock.method1() { |*parameters| yielded_parameters = parameters }
+    assert_equal parameters_for_yield, yielded_parameters
+  end
+
+  def test_should_set_up_multiple_expectations_with_return_values
+    mock = build_mock
+    mock.expects(:method1 => :result1, :method2 => :result2)
+    assert_equal :result1, mock.method1
+    assert_equal :result2, mock.method2
+  end
+
+  def test_should_set_up_multiple_stubs_with_return_values
+    mock = build_mock
+    mock.stubs(:method1 => :result1, :method2 => :result2)
+    assert_equal :result1, mock.method1
+    assert_equal :result2, mock.method2
+  end
+
+  def test_should_keep_returning_specified_value_for_stubs
+    mock = build_mock
+    mock.stubs(:method1).returns(1)
+    assert_equal 1, mock.method1
+    assert_equal 1, mock.method1
+  end
+
+  def test_should_keep_returning_specified_value_for_expects
+    mock = build_mock
+    mock.expects(:method1).times(2).returns(1)
+    assert_equal 1, mock.method1
+    assert_equal 1, mock.method1
+  end
+
+  def test_should_match_most_recent_call_to_expects
+    mock = build_mock
+    mock.expects(:method1).returns(0)
+    mock.expects(:method1).returns(1)
+    assert_equal 1, mock.method1
+  end
+
+  def test_should_match_most_recent_call_to_stubs
+    mock = build_mock
+    mock.stubs(:method1).returns(0)
+    mock.stubs(:method1).returns(1)
+    assert_equal 1, mock.method1
+  end
+
+  def test_should_match_most_recent_call_to_stubs_or_expects
+    mock = build_mock
+    mock.stubs(:method1).returns(0)
+    mock.expects(:method1).returns(1)
+    assert_equal 1, mock.method1
+  end
+
+  def test_should_match_most_recent_call_to_expects_or_stubs
+    mock = build_mock
+    mock.expects(:method1).returns(0)
+    mock.stubs(:method1).returns(1)
+    assert_equal 1, mock.method1
+  end
+
+  def test_should_respond_to_expected_method
+    mock = build_mock
+    mock.expects(:method1)
+    assert_equal true, mock.respond_to?(:method1)
+  end
+
+  def test_should_respond_to_expected_method_as_string
+    mock = build_mock
+    mock.expects(:method1)
+    assert_equal true, mock.respond_to?('method1')
+  end
+
+  def test_should_not_respond_to_unexpected_method
+    mock = build_mock
+    assert_equal false, mock.respond_to?(:method1)
+  end
+
+  def test_should_respond_to_methods_which_the_responder_does_responds_to
+    instance = Class.new do
+      define_method(:respond_to?) { |symbol| true }
+    end.new
+    mock = build_mock
+    mock.responds_like(instance)
+    assert_equal true, mock.respond_to?(:invoked_method)
+  end
+
+  def test_should_not_respond_to_methods_which_the_responder_does_not_responds_to
+    instance = Class.new do
+      define_method(:respond_to?) { |symbol| false }
+    end.new
+    mock = build_mock
+    mock.responds_like(instance)
+    assert_equal false, mock.respond_to?(:invoked_method)
+  end
+
+  def test_should_respond_to_methods_which_the_responder_instance_does_responds_to
+    klass = Class.new do
+      define_method(:respond_to?) { |symbol| true }
+    end
+    mock = build_mock
+    mock.responds_like_instance_of(klass)
+    assert_equal true, mock.respond_to?(:invoked_method)
+  end
+
+  def test_should_not_respond_to_methods_which_the_responder_instance_does_not_responds_to
+    klass = Class.new do
+      define_method(:respond_to?) { |symbol| false }
+    end
+    mock = build_mock
+    mock.responds_like_instance_of(klass)
+    assert_equal false, mock.respond_to?(:invoked_method)
+  end
+
+  def test_respond_like_should_return_itself_to_allow_method_chaining
+    mock = build_mock
+    assert_same mock.responds_like(Object.new), mock
+  end
+
+  def test_respond_like_instance_of_should_return_itself_to_allow_method_chaining
+    mock = build_mock
+    assert_same mock.responds_like_instance_of(Object), mock
+  end
+
+  def test_should_not_raise_no_method_error_if_mock_is_not_restricted_to_respond_like_a_responder
+    mock = build_mock
+    mock.stubs(:invoked_method)
+    assert_nothing_raised(NoMethodError) { mock.invoked_method }
+  end
+
+  def test_should_not_raise_no_method_error_if_responder_does_respond_to_invoked_method
+    instance = Class.new do
+      define_method(:respond_to?) { |symbol| true }
+    end.new
+    mock = build_mock
+    mock.responds_like(instance)
+    mock.stubs(:invoked_method)
+    assert_nothing_raised(NoMethodError) { mock.invoked_method }
+  end
+
+  def test_should_raise_no_method_error_if_responder_does_not_respond_to_invoked_method
+    instance = Class.new do
+      define_method(:respond_to?) { |symbol| false }
+      define_method(:mocha_inspect) { 'mocha_inspect' }
+    end.new
+    mock = build_mock
+    mock.responds_like(instance)
+    mock.stubs(:invoked_method)
+    assert_raises(NoMethodError) { mock.invoked_method }
+  end
+
+  def test_should_raise_no_method_error_with_message_indicating_that_mock_is_constrained_to_respond_like_responder
+    instance = Class.new do
+      define_method(:respond_to?) { |symbol| false }
+      define_method(:mocha_inspect) { 'mocha_inspect' }
+    end.new
+    mock = build_mock
+    mock.responds_like(instance)
+    mock.stubs(:invoked_method)
+    begin
+      mock.invoked_method
+    rescue NoMethodError => e
+      assert_match(/which responds like mocha_inspect/, e.message)
+    end
+  end
+
+  def test_should_handle_respond_to_with_private_methods_param_without_error
+    mock = build_mock
+    assert_nothing_raised { mock.respond_to?(:object_id, false) }
+  end
+
+  def test_should_respond_to_any_method_if_stubbing_everything
+    mock = build_mock
+    mock.stub_everything
+    assert mock.respond_to?(:abc)
+    assert mock.respond_to?(:xyz)
+  end
+
+  def test_should_remove_expectation_for_unstubbed_method
+    mock = build_mock
+    mock.expects(:method1)
+    mock.unstub(:method1)
+    e = assert_raises(ExpectationErrorFactory.exception_class) { mock.method1 }
+    assert_match(/unexpected invocation/, e.message)
+  end
+
+  private
+
+  def build_mock
+    Mock.new(nil)
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/mockery_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/mockery_test.rb
new file mode 100755
index 0000000..f98f318
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/mockery_test.rb
@@ -0,0 +1,151 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/mockery'
+require 'mocha/state_machine'
+require 'mocha/expectation_error_factory'
+
+class MockeryTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_build_instance_of_mockery
+    mockery = Mockery.instance
+    assert_not_nil mockery
+    assert_kind_of Mockery, mockery
+  end
+
+  def test_should_cache_instance_of_mockery
+    mockery_1 = Mockery.instance
+    mockery_2 = Mockery.instance
+    assert_same mockery_1, mockery_2
+  end
+
+  def test_should_expire_mockery_instance_cache
+    mockery_1 = Mockery.instance
+    Mockery.reset_instance
+    mockery_2 = Mockery.instance
+    assert_not_same mockery_1, mockery_2
+  end
+
+  def test_should_raise_expectation_error_because_not_all_expectations_are_satisfied
+    mockery = Mockery.new
+    mock_1 = mockery.named_mock('mock-1') { expects(:method_1) }
+    mock_2 = mockery.named_mock('mock-2') { expects(:method_2) }
+    1.times { mock_1.method_1 }
+    0.times { mock_2.method_2 }
+    assert_raises(ExpectationErrorFactory.exception_class) { mockery.verify }
+  end
+
+  def test_should_reset_list_of_mocks_on_teardown
+    mockery = Mockery.new
+    mockery.unnamed_mock { expects(:my_method) }
+    mockery.teardown
+    assert_nothing_raised(ExpectationErrorFactory.exception_class) { mockery.verify }
+  end
+
+  def test_should_build_instance_of_stubba_on_instantiation
+    mockery = Mockery.new
+    assert_not_nil mockery.stubba
+    assert_kind_of Central, mockery.stubba
+  end
+
+  def test_should_build_new_instance_of_stubba_on_teardown
+    mockery = Mockery.new
+    stubba_1 = mockery.stubba
+    mockery.teardown
+    stubba_2 = mockery.stubba
+    assert_not_same stubba_1, stubba_2
+  end
+
+  def test_should_build_and_store_new_state_machine
+    mockery = Mockery.new
+    mockery.new_state_machine('state-machine-name')
+    assert_equal 1, mockery.state_machines.length
+    assert_kind_of StateMachine, mockery.state_machines[0]
+  end
+
+  def test_should_reset_list_of_state_machines_on_teardown
+    mockery = Mockery.new
+    mockery.new_state_machine('state-machine-name')
+    mockery.teardown
+    assert_equal 0, mockery.state_machines.length
+  end
+
+  class FakeMethod
+    def stub; end
+    def unstub; end
+    def matches?(other); true; end
+  end
+
+  def test_should_unstub_all_methods_on_teardown
+    mockery = Mockery.new
+    stubba = mockery.stubba
+    stubba.stub(FakeMethod.new)
+    mockery.teardown
+    assert stubba.stubba_methods.empty?
+  end
+
+  def test_should_display_object_id_for_mocha_inspect_if_mock_has_no_name
+    mockery = Mockery.new
+    mock = mockery.unnamed_mock
+    assert_match Regexp.new("^#<Mock:0x[0-9A-Fa-f]{1,12}>$"), mock.mocha_inspect
+  end
+
+  def test_should_display_object_id_for_inspect_if_mock_has_no_name
+    mockery = Mockery.new
+    mock = mockery.unnamed_mock
+    assert_match Regexp.new("^#<Mock:0x[0-9A-Fa-f]{1,12}>$"), mock.inspect
+  end
+
+  def test_should_display_name_for_mocha_inspect_if_mock_has_string_name
+    mockery = Mockery.new
+    mock = mockery.named_mock('named_mock')
+    assert_equal "#<Mock:named_mock>", mock.mocha_inspect
+  end
+
+  def test_should_display_name_for_mocha_inspect_if_mock_has_symbol_name
+    mockery = Mockery.new
+    mock = mockery.named_mock(:named_mock)
+    assert_equal "#<Mock:named_mock>", mock.mocha_inspect
+  end
+
+  def test_should_display_name_for_inspect_if_mock_has_string_name
+    mockery = Mockery.new
+    mock = mockery.named_mock('named_mock')
+    assert_equal "#<Mock:named_mock>", mock.inspect
+  end
+
+  def test_should_display_name_for_inspect_if_mock_has_symbol_name
+    mockery = Mockery.new
+    mock = mockery.named_mock(:named_mock)
+    assert_equal "#<Mock:named_mock>", mock.inspect
+  end
+
+  def test_should_display_impersonated_object_for_mocha_inspect
+    mockery = Mockery.new
+    instance = Object.new
+    mock = mockery.mock_impersonating(instance)
+    assert_equal "#{instance.mocha_inspect}", mock.mocha_inspect
+  end
+
+  def test_should_display_impersonated_object_for_inspect
+    mockery = Mockery.new
+    instance = Object.new
+    mock = mockery.mock_impersonating(instance)
+    assert_equal "#{instance.mocha_inspect}", mock.inspect
+  end
+
+  class FakeClass; end
+
+  def test_should_display_any_instance_prefix_followed_by_class_whose_instances_are_being_impersonated_for_mocha_inspect
+    mockery = Mockery.new
+    mock = mockery.mock_impersonating_any_instance_of(FakeClass)
+    assert_equal "#<AnyInstance:MockeryTest::FakeClass>", mock.mocha_inspect
+  end
+
+  def test_should_display_any_instance_prefix_followed_by_class_whose_instances_are_being_impersonated_for_inspect
+    mockery = Mockery.new
+    mock = mockery.mock_impersonating_any_instance_of(FakeClass)
+    assert_equal "#<AnyInstance:MockeryTest::FakeClass>", mock.inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/module_methods_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/module_methods_test.rb
new file mode 100755
index 0000000..7352194
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/module_methods_test.rb
@@ -0,0 +1,19 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/module_methods'
+require 'mocha/object_methods'
+
+class ModuleMethodsTest < Mocha::TestCase
+
+  def setup
+    @module = Module.new.extend(Mocha::ModuleMethods, Mocha::ObjectMethods)
+  end
+
+  def test_should_use_stubba_module_method_for_module
+    assert_equal Mocha::ModuleMethod, @module.stubba_method
+  end
+
+  def test_should_stub_self_for_module
+    assert_equal @module, @module.stubba_object
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/multiple_yields_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/multiple_yields_test.rb
new file mode 100755
index 0000000..1f37c67
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/multiple_yields_test.rb
@@ -0,0 +1,18 @@
+require File.expand_path('../../test_helper', __FILE__)
+
+require 'mocha/multiple_yields'
+
+class MultipleYieldsTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_provide_parameters_for_multiple_yields_in_single_invocation
+    parameter_group = MultipleYields.new([1, 2, 3], [4, 5])
+    parameter_groups = []
+    parameter_group.each do |parameters|
+      parameter_groups << parameters
+    end
+    assert_equal [[1, 2, 3], [4, 5]], parameter_groups
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/no_yields_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/no_yields_test.rb
new file mode 100755
index 0000000..7203bb2
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/no_yields_test.rb
@@ -0,0 +1,18 @@
+require File.expand_path('../../test_helper', __FILE__)
+
+require 'mocha/no_yields'
+
+class NoYieldsTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_provide_parameters_for_no_yields_in_single_invocation
+    parameter_group = NoYields.new
+    parameter_groups = []
+    parameter_group.each do |parameters|
+      parameter_groups << parameters
+    end
+    assert_equal [], parameter_groups
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/object_inspect_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/object_inspect_test.rb
new file mode 100755
index 0000000..e5ef1a8
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/object_inspect_test.rb
@@ -0,0 +1,38 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/inspect'
+require 'method_definer'
+
+class ObjectInspectTest < Mocha::TestCase
+
+  def test_should_return_default_string_representation_of_object_not_including_instance_variables
+    object = Object.new
+    class << object
+      attr_accessor :attribute
+    end
+    object.attribute = 'instance_variable'
+    assert_match Regexp.new("^#<Object:0x[0-9A-Fa-f]{1,8}.*>$"), object.mocha_inspect
+    assert_no_match(/instance_variable/, object.mocha_inspect)
+  end
+
+  def test_should_return_customized_string_representation_of_object
+    object = Object.new
+    class << object
+      define_method(:inspect) { 'custom_inspect' }
+    end
+    assert_equal 'custom_inspect', object.mocha_inspect
+  end
+
+  def test_should_use_underscored_id_instead_of_object_id_or_id_so_that_they_can_be_stubbed
+    calls = []
+    object = Object.new
+    object.replace_instance_method(:id) { calls << :id; return 1 } if RUBY_VERSION < '1.9'
+    object.replace_instance_method(:object_id) { calls << :object_id; return 1 }
+    object.replace_instance_method(:__id__) { calls << :__id__; return 1 }
+    object.replace_instance_method(:inspect) { "object-description" }
+
+    object.mocha_inspect
+
+    assert_equal [:__id__], calls.uniq
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/object_methods_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/object_methods_test.rb
new file mode 100755
index 0000000..0fb2ac2
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/object_methods_test.rb
@@ -0,0 +1,46 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/object_methods'
+require 'mocha/mock'
+require 'mocha/expectation_error_factory'
+
+class ObjectMethodsTest < Mocha::TestCase
+
+  def setup
+    @object = Object.new.extend(Mocha::ObjectMethods)
+  end
+
+  def test_should_build_mocha_referring_to_self
+    mocha = @object.mocha
+    assert_not_nil mocha
+    assert mocha.is_a?(Mocha::Mock)
+    assert_equal @object.mocha_inspect, mocha.mocha_inspect
+  end
+
+  def test_should_reuse_existing_mocha
+    mocha_1 = @object.mocha
+    mocha_2 = @object.mocha
+    assert_equal mocha_1, mocha_2
+  end
+
+  def test_should_reset_mocha
+    assert_nil @object.reset_mocha
+  end
+
+  def test_should_use_stubba_instance_method_for_object
+    assert_equal Mocha::InstanceMethod, Object.new.stubba_method
+  end
+
+  def test_should_stub_self_for_object
+    assert_equal @object, @object.stubba_object
+  end
+
+  def test_nobody_expects_the_spanish_inquisition
+    assert_raise(Mocha::ExpectationErrorFactory.exception_class) { @object.expects(:the_spanish_inquisition) }
+  end
+
+  def test_should_alias_object_method
+    klass = Class.new { def self.method_x; end }
+    assert_equal klass._method(:method_x), klass.method(:method_x)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/all_of_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/all_of_test.rb
new file mode 100755
index 0000000..ba8ea2e
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/all_of_test.rb
@@ -0,0 +1,26 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/all_of'
+require 'mocha/inspect'
+require 'stub_matcher'
+
+class AllOfTest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_if_all_matchers_match
+    matcher = all_of(Stub::Matcher.new(true), Stub::Matcher.new(true), Stub::Matcher.new(true))
+    assert matcher.matches?(['any_old_value'])
+  end
+
+  def test_should_not_match_if_any_matcher_does_not_match
+    matcher = all_of(Stub::Matcher.new(true), Stub::Matcher.new(false), Stub::Matcher.new(true))
+    assert !matcher.matches?(['any_old_value'])
+  end
+
+  def test_should_describe_matcher
+    matcher = all_of(Stub::Matcher.new(true), Stub::Matcher.new(false), Stub::Matcher.new(true))
+    assert_equal 'all_of(matcher(true), matcher(false), matcher(true))', matcher.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/any_of_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/any_of_test.rb
new file mode 100755
index 0000000..fa73ef4
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/any_of_test.rb
@@ -0,0 +1,26 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/any_of'
+require 'mocha/inspect'
+require 'stub_matcher'
+
+class AnyOfTest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_if_any_matchers_match
+    matcher = any_of(Stub::Matcher.new(false), Stub::Matcher.new(true), Stub::Matcher.new(false))
+    assert matcher.matches?(['any_old_value'])
+  end
+
+  def test_should_not_match_if_no_matchers_match
+    matcher = any_of(Stub::Matcher.new(false), Stub::Matcher.new(false), Stub::Matcher.new(false))
+    assert !matcher.matches?(['any_old_value'])
+  end
+
+  def test_should_describe_matcher
+    matcher = any_of(Stub::Matcher.new(false), Stub::Matcher.new(true), Stub::Matcher.new(false))
+    assert_equal 'any_of(matcher(false), matcher(true), matcher(false))', matcher.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/anything_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/anything_test.rb
new file mode 100755
index 0000000..cc73621
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/anything_test.rb
@@ -0,0 +1,21 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/anything'
+require 'mocha/inspect'
+
+class AnythingTest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_anything
+    matcher = anything
+    assert matcher.matches?([:something])
+    assert matcher.matches?([{'x' => 'y'}])
+  end
+
+  def test_should_describe_matcher
+    matcher = anything
+    assert_equal "anything", matcher.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/equals_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/equals_test.rb
new file mode 100755
index 0000000..67bf897
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/equals_test.rb
@@ -0,0 +1,25 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/equals'
+require 'mocha/inspect'
+
+class EqualsTest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_object_that_equals_value
+    matcher = equals('x')
+    assert matcher.matches?(['x'])
+  end
+
+  def test_should_not_match_object_that_does_not_equal_value
+    matcher = equals('x')
+    assert !matcher.matches?(['y'])
+  end
+
+  def test_should_describe_matcher
+    matcher = equals('x')
+    assert_equal "'x'", matcher.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/has_entries_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/has_entries_test.rb
new file mode 100755
index 0000000..c574dfc
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/has_entries_test.rb
@@ -0,0 +1,51 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/has_entries'
+require 'mocha/parameter_matchers/object'
+require 'mocha/inspect'
+
+class HasEntriesTest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_hash_including_specified_entries
+    matcher = has_entries(:key_1 => 'value_1', :key_2 => 'value_2')
+    assert matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2', :key_3 => 'value_3' }])
+  end
+
+  def test_should_not_match_hash_not_including_specified_entries
+    matcher = has_entries(:key_1 => 'value_2', :key_2 => 'value_2', :key_3 => 'value_3')
+    assert !matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+  end
+
+  def test_should_describe_matcher
+    matcher = has_entries(:key_1 => 'value_1', :key_2 => 'value_2')
+    description = matcher.mocha_inspect
+    matches = /has_entries\((.*)\)/.match(description)
+    assert_not_nil matches[0]
+    entries = eval(matches[1], binding, __FILE__, __LINE__)
+    assert_equal 'value_1', entries[:key_1]
+    assert_equal 'value_2', entries[:key_2]
+  end
+
+  def test_should_match_hash_including_specified_entries_with_nested_key_matchers
+    matcher = has_entries(equals(:key_1) => 'value_1', equals(:key_2) => 'value_2')
+    assert matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2', :key_3 => 'value_3' }])
+  end
+
+  def test_should_not_match_hash_not_including_specified_entries_with_nested_key_matchers
+    matcher = has_entries(equals(:key_1) => 'value_2', equals(:key_2) => 'value_2', equals(:key_3) => 'value_3')
+    assert !matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+  end
+
+  def test_should_match_hash_including_specified_entries_with_nested_value_matchers
+    matcher = has_entries(:key_1 => equals('value_1'), :key_2 => equals('value_2'))
+    assert matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2', :key_3 => 'value_3' }])
+  end
+
+  def test_should_not_match_hash_not_including_specified_entries_with_nested_value_matchers
+    matcher = has_entries(:key_1 => equals('value_2'), :key_2 => equals('value_2'), :key_3 => equals('value_3'))
+    assert !matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/has_entry_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/has_entry_test.rb
new file mode 100755
index 0000000..f5889c6
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/has_entry_test.rb
@@ -0,0 +1,129 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/has_entry'
+require 'mocha/parameter_matchers/object'
+require 'mocha/parameter_matchers/equals'
+require 'mocha/inspect'
+
+class HasEntryTest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_hash_including_specified_key_value_pair
+    matcher = has_entry(:key_1, 'value_1')
+    assert matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+  end
+
+  def test_should_not_match_hash_not_including_specified_key_value_pair
+    matcher = has_entry(:key_1, 'value_2')
+    assert !matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+  end
+
+  def test_should_match_hash_including_specified_entry
+    matcher = has_entry(:key_1 => 'value_1')
+    assert matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+  end
+
+  def test_should_not_match_hash_not_including_specified_entry
+    matcher = has_entry(:key_1 => 'value_2')
+    assert !matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+  end
+
+  def test_should_describe_matcher_with_key_value_pair
+    matcher = has_entry(:key_1, 'value_1')
+    assert_equal "has_entry(:key_1 => 'value_1')", matcher.mocha_inspect
+  end
+
+  def test_should_describe_matcher_with_entry
+    matcher = has_entry(:key_1 => 'value_1')
+    assert_equal "has_entry(:key_1 => 'value_1')", matcher.mocha_inspect
+  end
+
+  def test_should_match_hash_including_specified_entry_with_nested_key_matcher
+    matcher = has_entry(equals(:key_1) => 'value_1')
+    assert matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+  end
+
+  def test_should_match_hash_including_specified_entry_with_nested_value_matcher
+    matcher = has_entry(:key_1 => equals('value_1'))
+    assert matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+  end
+
+  def test_should_not_match_hash_not_including_specified_entry_with_nested_key_matcher
+    matcher = has_entry(equals(:key_1) => 'value_2')
+    assert !matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+  end
+
+  def test_should_not_match_hash_not_including_specified_entry_with_nested_value_matcher
+    matcher = has_entry(:key_1 => equals('value_2'))
+    assert !matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+  end
+
+  def test_should_not_match_object_that_doesnt_respond_to_keys
+    matcher = has_entry(:key_1 => equals('value_2'))
+    object = Class.new do
+      def [](key)
+        'value_2'
+      end
+    end.new
+    assert !matcher.matches?([object])
+  end
+
+  def test_should_not_match_object_that_doesnt_respond_to_square_bracket
+    matcher = has_entry(:key_1 => equals('value_2'))
+    object = Class.new do
+      def keys
+        [:key_1]
+      end
+    end.new
+    assert !matcher.matches?([object])
+  end
+
+  def test_should_raise_argument_error_if_single_argument_is_not_a_hash
+    e = assert_raises(ArgumentError) do
+      has_entry(Array.new)
+    end
+    assert_equal "Argument is not a Hash.", e.message
+  end
+
+  def test_should_raise_argument_error_if_no_entries_are_supplied
+    e = assert_raises(ArgumentError) do
+      has_entry({})
+    end
+    assert_equal "Argument has no entries.", e.message
+  end
+
+  def test_should_raise_argument_error_if_multiple_entries_are_supplied
+    e = assert_raises(ArgumentError) do
+      has_entry(:key_1 => 'value_1', :key_2 => 'value_2')
+    end
+    assert_equal "Argument has multiple entries. Use Mocha::ParameterMatchers#has_entries instead.", e.message
+  end
+
+  def test_should_raise_argument_error_if_more_than_two_arguments_are_supplied
+    e = assert_raises(ArgumentError) do
+      has_entry(1, 2, 3)
+    end
+    assert_equal "Too many arguments; use either a single argument (must be a Hash) or two arguments (a key and a value).", e.message
+  end
+
+  def test_should_match_array_as_key
+    matcher = has_entry([:key_1, :key_2] => 'value_1')
+    assert matcher.matches?([{[:key_1, :key_2] => 'value_1', :key_3 => 'value_2'}])
+  end
+
+  def test_should_match_array_as_value
+    matcher = has_entry(:key_1 => ['value_1', 'value_2'])
+    assert matcher.matches?([{:key_1 => ['value_1', 'value_2']}])
+  end
+
+  def test_should_match_hash_as_value_and_key
+    matcher = has_entry({{:key_1 => 'value_1', :key_2 => 'value_2'} => {:key_3 => 'value_3', :key_4 => 'value_4'}})
+    assert matcher.matches?([{{:key_1 => 'value_1', :key_2 => 'value_2'} => {:key_3 => 'value_3', :key_4 => 'value_4'}, :key_5 => 'value_5'}])
+  end
+
+  def test_should_match_matcher_as_value_and_key
+    matcher = has_entry({has_entry(:key_1 => 'value_1') => has_entry(:key_3 => 'value_3')})
+    assert matcher.matches?([{{:key_1 => 'value_1', :key_2 => 'value_2'} => {:key_3 => 'value_3', :key_4 => 'value_4'}, :key_5 => 'value_5'}])
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/has_key_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/has_key_test.rb
new file mode 100755
index 0000000..1cd574d
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/has_key_test.rb
@@ -0,0 +1,55 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/has_key'
+require 'mocha/parameter_matchers/object'
+require 'mocha/inspect'
+
+class HasKeyTest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_hash_including_specified_key
+    matcher = has_key(:key_1)
+    assert matcher.matches?([{ :key_1 => 1, :key_2 => 2 }])
+  end
+
+  def test_should_not_match_hash_not_including_specified_key
+    matcher = has_key(:key_1)
+    assert !matcher.matches?([{ :key_2 => 2 }])
+  end
+
+  def test_should_describe_matcher
+    matcher = has_key(:key)
+    assert_equal 'has_key(:key)', matcher.mocha_inspect
+  end
+
+  def test_should_match_hash_including_specified_key_with_nested_key_matcher
+    matcher = has_key(equals(:key_1))
+    assert matcher.matches?([{ :key_1 => 1, :key_2 => 2 }])
+  end
+
+  def test_should_not_match_hash_not_including_specified_key_with_nested_key_matcher
+    matcher = has_key(equals(:key_1))
+    assert !matcher.matches?([{ :key_2 => 2 }])
+  end
+
+  def test_should_not_raise_error_on_empty_arguments
+    matcher = has_key(:key)
+    assert_nothing_raised { matcher.matches?([]) }
+  end
+
+  def test_should_not_match_on_empty_arguments
+    matcher = has_key(:key)
+    assert !matcher.matches?([])
+  end
+
+  def test_should_not_raise_error_on_argument_that_does_not_respond_to_keys
+    matcher = has_key(:key)
+    assert_nothing_raised { matcher.matches?([:key]) }
+  end
+
+  def test_should_not_match_on_argument_that_does_not_respond_to_keys
+    matcher = has_key(:key)
+    assert !matcher.matches?([:key])
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/has_value_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/has_value_test.rb
new file mode 100755
index 0000000..542b26f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/has_value_test.rb
@@ -0,0 +1,57 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/has_value'
+require 'mocha/parameter_matchers/object'
+require 'mocha/parameter_matchers/equals'
+require 'mocha/inspect'
+
+class HasValueTest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_hash_including_specified_value
+    matcher = has_value('value_1')
+    assert matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+  end
+
+  def test_should_not_match_hash_not_including_specified_value
+    matcher = has_value('value_1')
+    assert !matcher.matches?([{ :key_2 => 'value_2' }])
+  end
+
+  def test_should_describe_matcher
+    matcher = has_value('value_1')
+    assert_equal "has_value('value_1')", matcher.mocha_inspect
+  end
+
+  def test_should_match_hash_including_specified_value_with_nested_value_matcher
+    matcher = has_value(equals('value_1'))
+    assert matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+  end
+
+  def test_should_not_match_hash_not_including_specified_value_with_nested_value_matcher
+    matcher = has_value(equals('value_1'))
+    assert !matcher.matches?([{ :key_2 => 'value_2' }])
+  end
+
+  def test_should_not_raise_error_on_empty_arguments
+    matcher = has_value('value_1')
+    assert_nothing_raised { matcher.matches?([]) }
+  end
+
+  def test_should_not_match_empty_arguments
+    matcher = has_value('value_1')
+    assert !matcher.matches?([])
+  end
+
+  def test_should_not_raise_error_on_argument_that_does_not_respond_to_values
+    matcher = has_value('value_1')
+    assert_nothing_raised { matcher.matches?(['value_1']) }
+  end
+
+  def test_should_not_match_on_argument_that_does_not_respond_to_values
+    matcher = has_value('value_1')
+    assert !matcher.matches?(['value_1'])
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/includes_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/includes_test.rb
new file mode 100755
index 0000000..0eb7893
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/includes_test.rb
@@ -0,0 +1,59 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/includes'
+require 'mocha/inspect'
+
+class IncludesTest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_object_including_value
+    matcher = includes(:x)
+    assert matcher.matches?([[:x, :y, :z]])
+  end
+
+  def test_should_match_object_including_all_values
+    matcher = includes(:x, :y, :z)
+    assert matcher.matches?([[:x, :y, :z]])
+  end
+
+  def test_should_not_match_object_that_does_not_include_value
+    matcher = includes(:not_included)
+    assert !matcher.matches?([[:x, :y, :z]])
+  end
+
+  def test_should_not_match_object_that_does_not_include_any_one_value
+    matcher = includes(:x, :y, :z, :not_included)
+    assert !matcher.matches?([[:x, :y, :z]])
+  end
+
+  def test_should_describe_matcher_with_one_item
+    matcher = includes(:x)
+    assert_equal "includes(:x)", matcher.mocha_inspect
+  end
+
+  def test_should_describe_matcher_with_multiple_items
+    matcher = includes(:x, :y, :z)
+    assert_equal "includes(:x, :y, :z)", matcher.mocha_inspect
+  end
+
+  def test_should_not_raise_error_on_emtpy_arguments
+    matcher = includes(:x)
+    assert_nothing_raised { matcher.matches?([]) }
+  end
+
+  def test_should_not_match_on_empty_arguments
+    matcher = includes(:x)
+    assert !matcher.matches?([])
+  end
+
+  def test_should_not_raise_error_on_argument_that_does_not_respond_to_include
+    matcher = includes(:x)
+    assert_nothing_raised { matcher.matches?([:x]) }
+  end
+
+  def test_should_not_match_on_argument_that_does_not_respond_to_include
+    matcher = includes(:x)
+    assert !matcher.matches?([:x])
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/instance_of_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/instance_of_test.rb
new file mode 100755
index 0000000..eaa442f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/instance_of_test.rb
@@ -0,0 +1,25 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/instance_of'
+require 'mocha/inspect'
+
+class InstanceOfTest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_object_that_is_an_instance_of_specified_class
+    matcher = instance_of(String)
+    assert matcher.matches?(['string'])
+  end
+
+  def test_should_not_match_object_that_is_not_an_instance_of_specified_class
+    matcher = instance_of(String)
+    assert !matcher.matches?([99])
+  end
+
+  def test_should_describe_matcher
+    matcher = instance_of(String)
+    assert_equal "instance_of(String)", matcher.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/is_a_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/is_a_test.rb
new file mode 100755
index 0000000..6cd4ca2
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/is_a_test.rb
@@ -0,0 +1,25 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/is_a'
+require 'mocha/inspect'
+
+class IsATest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_object_that_is_a_specified_class
+    matcher = is_a(Integer)
+    assert matcher.matches?([99])
+  end
+
+  def test_should_not_match_object_that_is_not_a_specified_class
+    matcher = is_a(Integer)
+    assert !matcher.matches?(['string'])
+  end
+
+  def test_should_describe_matcher
+    matcher = is_a(Integer)
+    assert_equal "is_a(Integer)", matcher.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/kind_of_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/kind_of_test.rb
new file mode 100755
index 0000000..bdb020f
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/kind_of_test.rb
@@ -0,0 +1,25 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/kind_of'
+require 'mocha/inspect'
+
+class KindOfTest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_object_that_is_a_kind_of_specified_class
+    matcher = kind_of(Integer)
+    assert matcher.matches?([99])
+  end
+
+  def test_should_not_match_object_that_is_not_a_kind_of_specified_class
+    matcher = kind_of(Integer)
+    assert !matcher.matches?(['string'])
+  end
+
+  def test_should_describe_matcher
+    matcher = kind_of(Integer)
+    assert_equal "kind_of(Integer)", matcher.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/not_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/not_test.rb
new file mode 100755
index 0000000..fa6ffaa
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/not_test.rb
@@ -0,0 +1,26 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/not'
+require 'mocha/inspect'
+require 'stub_matcher'
+
+class NotTest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_if_matcher_does_not_match
+    matcher = Not(Stub::Matcher.new(false))
+    assert matcher.matches?(['any_old_value'])
+  end
+
+  def test_should_not_match_if_matcher_does_match
+    matcher = Not(Stub::Matcher.new(true))
+    assert !matcher.matches?(['any_old_value'])
+  end
+
+  def test_should_describe_matcher
+    matcher = Not(Stub::Matcher.new(true))
+    assert_equal 'Not(matcher(true))', matcher.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/regexp_matches_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/regexp_matches_test.rb
new file mode 100755
index 0000000..a7f8ab7
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/regexp_matches_test.rb
@@ -0,0 +1,46 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/regexp_matches'
+require 'mocha/inspect'
+
+class RegexpMatchesTest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_parameter_matching_regular_expression
+    matcher = regexp_matches(/oo/)
+    assert matcher.matches?(['foo'])
+  end
+
+  def test_should_not_match_parameter_not_matching_regular_expression
+    matcher = regexp_matches(/oo/)
+    assert !matcher.matches?(['bar'])
+  end
+
+  def test_should_describe_matcher
+    matcher = regexp_matches(/oo/)
+    assert_equal "regexp_matches(/oo/)", matcher.mocha_inspect
+  end
+
+  def test_should_not_raise_error_on_empty_arguments
+    matcher = regexp_matches(/oo/)
+    assert_nothing_raised { matcher.matches?([]) }
+  end
+
+  def test_should_not_match_on_empty_arguments
+    matcher = regexp_matches(/oo/)
+    assert !matcher.matches?([])
+  end
+
+  def test_should_not_raise_error_on_argument_that_does_not_respond_to_equals_tilde
+    object_not_responding_to_equals_tilde = Class.new { undef =~ }.new
+    matcher = regexp_matches(/oo/)
+    assert_nothing_raised { matcher.matches?([object_not_responding_to_equals_tilde]) }
+  end
+
+  def test_should_not_match_on_argument_that_does_not_respond_to_equals_tilde
+    object_not_responding_to_equals_tilde = Class.new { undef =~ }.new
+    matcher = regexp_matches(/oo/)
+    assert !matcher.matches?([object_not_responding_to_equals_tilde])
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/responds_with_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/responds_with_test.rb
new file mode 100755
index 0000000..443f43d
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/responds_with_test.rb
@@ -0,0 +1,32 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/responds_with'
+require 'mocha/parameter_matchers/object'
+require 'mocha/inspect'
+
+class RespondsWithTest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_parameter_responding_with_expected_value
+    matcher = responds_with(:upcase, 'FOO')
+    assert matcher.matches?(['foo'])
+  end
+
+  def test_should_not_match_parameter_responding_with_unexpected_value
+    matcher = responds_with(:upcase, 'FOO')
+    assert !matcher.matches?(['bar'])
+  end
+
+  def test_should_match_parameter_responding_with_nested_responds_with_matcher
+    matcher = responds_with(:foo, responds_with(:bar, 'baz'))
+    object = Class.new { def foo; Class.new { def bar; 'baz'; end }.new; end }.new
+    assert matcher.matches?([object])
+  end
+
+  def test_should_describe_matcher
+    matcher = responds_with(:foo, :bar)
+    assert_equal 'responds_with(:foo, :bar)', matcher.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/stub_matcher.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/stub_matcher.rb
new file mode 100755
index 0000000..71e24c2
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/stub_matcher.rb
@@ -0,0 +1,27 @@
+module Stub
+
+  class Matcher
+
+    attr_accessor :value
+
+    def initialize(matches)
+      @matches = matches
+    end
+
+    def matches?(available_parameters)
+      value = available_parameters.shift
+      @value = value
+      @matches
+    end
+
+    def mocha_inspect
+      "matcher(#{@matches})"
+    end
+
+    def to_matcher
+      self
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/yaml_equivalent_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/yaml_equivalent_test.rb
new file mode 100755
index 0000000..24d3712
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameter_matchers/yaml_equivalent_test.rb
@@ -0,0 +1,25 @@
+require File.expand_path('../../../test_helper', __FILE__)
+
+require 'mocha/parameter_matchers/yaml_equivalent'
+require 'mocha/inspect'
+
+class YamlEquivalentTest < Mocha::TestCase
+
+  include Mocha::ParameterMatchers
+
+  def test_should_match_parameter_matching_yaml_representation_of_object
+    matcher = yaml_equivalent([1, 2, 3])
+    assert matcher.matches?(["--- \n- 1\n- 2\n- 3\n"])
+  end
+
+  def test_should_not_match_parameter_matching_yaml_representation_of_object
+    matcher = yaml_equivalent([1, 2, 3])
+    assert !matcher.matches?(["--- \n- 4\n- 5\n"])
+  end
+
+  def test_should_describe_matcher
+    matcher = yaml_equivalent([1, 2, 3])
+    assert_equal "yaml_equivalent([1, 2, 3])", matcher.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/parameters_matcher_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/parameters_matcher_test.rb
new file mode 100755
index 0000000..b1e5a36
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/parameters_matcher_test.rb
@@ -0,0 +1,121 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/parameters_matcher'
+
+class ParametersMatcherTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_match_any_actual_parameters_if_no_expected_parameters_specified
+    parameters_matcher = ParametersMatcher.new
+    assert parameters_matcher.match?([1, 2, 3])
+  end
+
+  def test_should_match_if_actual_parameters_are_same_as_expected_parameters
+    parameters_matcher = ParametersMatcher.new([4, 5, 6])
+    assert parameters_matcher.match?([4, 5, 6])
+  end
+
+  def test_should_not_match_if_actual_parameters_are_different_from_expected_parameters
+    parameters_matcher = ParametersMatcher.new([4, 5, 6])
+    assert !parameters_matcher.match?([1, 2, 3])
+  end
+
+  def test_should_not_match_if_there_are_less_actual_parameters_than_expected_parameters
+    parameters_matcher = ParametersMatcher.new([4, 5, 6])
+    assert !parameters_matcher.match?([4, 5])
+  end
+
+  def test_should_not_match_if_there_are_more_actual_parameters_than_expected_parameters
+    parameters_matcher = ParametersMatcher.new([4, 5])
+    assert !parameters_matcher.match?([4, 5, 6])
+  end
+
+  def test_should_not_match_if_not_all_required_parameters_are_supplied
+    optionals = ParameterMatchers::Optionally.new(6, 7)
+    parameters_matcher = ParametersMatcher.new([4, 5, optionals])
+    assert !parameters_matcher.match?([4])
+  end
+
+  def test_should_match_if_all_required_parameters_match_and_no_optional_parameters_are_supplied
+    optionals = ParameterMatchers::Optionally.new(6, 7)
+    parameters_matcher = ParametersMatcher.new([4, 5, optionals])
+    assert parameters_matcher.match?([4, 5])
+  end
+
+  def test_should_match_if_all_required_and_optional_parameters_match_and_some_optional_parameters_are_supplied
+    optionals = ParameterMatchers::Optionally.new(6, 7)
+    parameters_matcher = ParametersMatcher.new([4, 5, optionals])
+    assert parameters_matcher.match?([4, 5, 6])
+  end
+
+  def test_should_match_if_all_required_and_optional_parameters_match_and_all_optional_parameters_are_supplied
+    optionals = ParameterMatchers::Optionally.new(6, 7)
+    parameters_matcher = ParametersMatcher.new([4, 5, optionals])
+    assert parameters_matcher.match?([4, 5, 6, 7])
+  end
+
+  def test_should_not_match_if_all_required_and_optional_parameters_match_but_too_many_optional_parameters_are_supplied
+    optionals = ParameterMatchers::Optionally.new(6, 7)
+    parameters_matcher = ParametersMatcher.new([4, 5, optionals])
+    assert !parameters_matcher.match?([4, 5, 6, 7, 8])
+  end
+
+  def test_should_not_match_if_all_required_parameters_match_but_some_optional_parameters_do_not_match
+    optionals = ParameterMatchers::Optionally.new(6, 7)
+    parameters_matcher = ParametersMatcher.new([4, 5, optionals])
+    assert !parameters_matcher.match?([4, 5, 6, 0])
+  end
+
+  def test_should_not_match_if_some_required_parameters_do_not_match_although_all_optional_parameters_do_match
+    optionals = ParameterMatchers::Optionally.new(6, 7)
+    parameters_matcher = ParametersMatcher.new([4, 5, optionals])
+    assert !parameters_matcher.match?([4, 0, 6])
+  end
+
+  def test_should_not_match_if_all_required_parameters_match_but_no_optional_parameters_match
+    optionals = ParameterMatchers::Optionally.new(6, 7)
+    parameters_matcher = ParametersMatcher.new([4, 5, optionals])
+    assert !parameters_matcher.match?([4, 5, 0, 0])
+  end
+
+  def test_should_match_if_actual_parameters_satisfy_matching_block
+    parameters_matcher = ParametersMatcher.new { |x, y| x + y == 3 }
+    assert parameters_matcher.match?([1, 2])
+  end
+
+  def test_should_not_match_if_actual_parameters_do_not_satisfy_matching_block
+    parameters_matcher = ParametersMatcher.new { |x, y| x + y == 3 }
+    assert !parameters_matcher.match?([2, 3])
+  end
+
+  def test_should_remove_outer_array_braces
+    params = [1, 2, [3, 4]]
+    parameters_matcher = ParametersMatcher.new(params)
+    assert_equal '(1, 2, [3, 4])', parameters_matcher.mocha_inspect
+  end
+
+  def test_should_display_numeric_arguments_as_is
+    params = [1, 2, 3]
+    parameters_matcher = ParametersMatcher.new(params)
+    assert_equal '(1, 2, 3)', parameters_matcher.mocha_inspect
+  end
+
+  def test_should_remove_curly_braces_if_hash_is_only_argument
+    params = [{:a => 1, :z => 2}]
+    parameters_matcher = ParametersMatcher.new(params)
+    assert_nil parameters_matcher.mocha_inspect.index('{')
+    assert_nil parameters_matcher.mocha_inspect.index('}')
+  end
+
+  def test_should_not_remove_curly_braces_if_hash_is_not_the_only_argument
+    params = [1, {:a => 1}]
+    parameters_matcher = ParametersMatcher.new(params)
+    assert_equal '(1, {:a => 1})', parameters_matcher.mocha_inspect
+  end
+
+  def test_should_indicate_that_matcher_will_match_any_actual_parameters
+    parameters_matcher = ParametersMatcher.new
+    assert_equal '(any_parameters)', parameters_matcher.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/receivers_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/receivers_test.rb
new file mode 100755
index 0000000..2a64dc1
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/receivers_test.rb
@@ -0,0 +1,66 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/receivers'
+
+class ObjectReceiverTest < Mocha::TestCase
+  include Mocha
+
+  class FakeObject < Struct.new(:mocha)
+    def is_a?(klass)
+      false
+    end
+  end
+
+  class FakeClass < Struct.new(:superclass, :mocha)
+    def is_a?(klass)
+      klass == Class
+    end
+  end
+
+  def test_mocks_returns_mock_for_object
+    object = FakeObject.new(:mocha)
+    receiver = ObjectReceiver.new(object)
+    assert_equal [:mocha], receiver.mocks
+  end
+
+  def test_mocks_returns_mocks_for_class_and_its_superclasses
+    grandparent = FakeClass.new(nil, :grandparent_mocha)
+    parent = FakeClass.new(grandparent, :parent_mocha)
+    klass = FakeClass.new(parent, :mocha)
+    receiver = ObjectReceiver.new(klass)
+    assert_equal [:mocha, :parent_mocha, :grandparent_mocha], receiver.mocks
+  end
+end
+
+class AnyInstanceReceiverTest < Mocha::TestCase
+  include Mocha
+
+  class FakeAnyInstanceClass
+    attr_reader :superclass
+
+    def initialize(superclass, mocha)
+      @superclass, @mocha = superclass, mocha
+    end
+
+    def any_instance
+      Struct.new(:mocha).new(@mocha)
+    end
+  end
+
+  def test_mocks_returns_mocks_for_class_and_its_superclasses
+    grandparent = FakeAnyInstanceClass.new(nil, :grandparent_mocha)
+    parent = FakeAnyInstanceClass.new(grandparent, :parent_mocha)
+    klass = FakeAnyInstanceClass.new(parent, :mocha)
+    receiver = AnyInstanceReceiver.new(klass)
+    assert_equal [:mocha, :parent_mocha, :grandparent_mocha], receiver.mocks
+  end
+end
+
+class DefaultReceiverTest < Mocha::TestCase
+  include Mocha
+
+  def test_mocks_returns_mock
+    mock = :mocha
+    receiver = DefaultReceiver.new(mock)
+    assert_equal [:mocha], receiver.mocks
+  end
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/return_values_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/return_values_test.rb
new file mode 100755
index 0000000..6a9cfb3
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/return_values_test.rb
@@ -0,0 +1,63 @@
+require File.expand_path('../../test_helper', __FILE__)
+
+require 'mocha/return_values'
+
+class ReturnValuesTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_return_nil
+    values = ReturnValues.new
+    assert_nil values.next
+  end
+
+  def test_should_keep_returning_nil
+    values = ReturnValues.new
+    values.next
+    assert_nil values.next
+    assert_nil values.next
+  end
+
+  def test_should_return_evaluated_single_return_value
+    values = ReturnValues.new(SingleReturnValue.new('value'))
+    assert_equal 'value', values.next
+  end
+
+  def test_should_keep_returning_evaluated_single_return_value
+    values = ReturnValues.new(SingleReturnValue.new('value'))
+    values.next
+    assert_equal 'value', values.next
+    assert_equal 'value', values.next
+  end
+
+  def test_should_return_consecutive_evaluated_single_return_values
+    values = ReturnValues.new(SingleReturnValue.new('value_1'), SingleReturnValue.new('value_2'))
+    assert_equal 'value_1', values.next
+    assert_equal 'value_2', values.next
+  end
+
+  def test_should_keep_returning_last_of_consecutive_evaluated_single_return_values
+    values = ReturnValues.new(SingleReturnValue.new('value_1'), SingleReturnValue.new('value_2'))
+    values.next
+    values.next
+    assert_equal 'value_2', values.next
+    assert_equal 'value_2', values.next
+  end
+
+  def test_should_build_single_return_values_for_each_values
+    values = ReturnValues.build('value_1', 'value_2', 'value_3').values
+    assert_equal 'value_1', values[0].evaluate
+    assert_equal 'value_2', values[1].evaluate
+    assert_equal 'value_3', values[2].evaluate
+  end
+
+  def test_should_combine_two_sets_of_return_values
+    values_1 = ReturnValues.build('value_1')
+    values_2 = ReturnValues.build('value_2a', 'value_2b')
+    values = (values_1 + values_2).values
+    assert_equal 'value_1', values[0].evaluate
+    assert_equal 'value_2a', values[1].evaluate
+    assert_equal 'value_2b', values[2].evaluate
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/sequence_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/sequence_test.rb
new file mode 100755
index 0000000..d4e9232
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/sequence_test.rb
@@ -0,0 +1,104 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/sequence'
+require 'mocha/expectation'
+
+class SequenceTest < Mocha::TestCase
+
+  include Mocha
+
+  class FakeExpectation
+
+    attr_reader :ordering_constraints
+
+    def initialize(satisfied = false)
+      @satisfied = satisfied
+      @ordering_constraints = []
+    end
+
+    def add_ordering_constraint(ordering_constraint)
+      @ordering_constraints << ordering_constraint
+    end
+
+    def satisfied?
+      @satisfied
+    end
+
+  end
+
+  def test_should_be_satisfied_if_no_expectations_added
+    sequence = Sequence.new('name')
+    assert sequence.satisfied_to_index?(0)
+  end
+
+  def test_should_be_satisfied_if_one_unsatisfied_expectations_added_but_it_is_not_included_by_index
+    sequence = Sequence.new('name')
+    expectation = FakeExpectation.new(false)
+    sequence.constrain_as_next_in_sequence(expectation)
+    assert sequence.satisfied_to_index?(0)
+  end
+
+  def test_should_not_be_satisfied_if_one_unsatisfied_expectations_added_and_it_is_included_by_index
+    sequence = Sequence.new('name')
+    expectation = FakeExpectation.new(false)
+    sequence.constrain_as_next_in_sequence(expectation)
+    assert !sequence.satisfied_to_index?(1)
+  end
+
+  def test_should_be_satisfied_if_one_satisfied_expectations_added_and_it_is_included_by_index
+    sequence = Sequence.new('name')
+    expectation = FakeExpectation.new(true)
+    sequence.constrain_as_next_in_sequence(expectation)
+    assert sequence.satisfied_to_index?(1)
+  end
+
+  def test_should_not_be_satisfied_if_one_satisfied_and_one_unsatisfied_expectation_added_and_both_are_included_by_index
+    sequence = Sequence.new('name')
+    expectation_one = FakeExpectation.new(true)
+    expectation_two = FakeExpectation.new(false)
+    sequence.constrain_as_next_in_sequence(expectation_one)
+    sequence.constrain_as_next_in_sequence(expectation_two)
+    assert !sequence.satisfied_to_index?(2)
+  end
+
+  def test_should_be_satisfied_if_two_satisfied_expectations_added_and_both_are_included_by_index
+    sequence = Sequence.new('name')
+    expectation_one = FakeExpectation.new(true)
+    expectation_two = FakeExpectation.new(true)
+    sequence.constrain_as_next_in_sequence(expectation_one)
+    sequence.constrain_as_next_in_sequence(expectation_two)
+    assert sequence.satisfied_to_index?(2)
+  end
+
+  def test_should_add_ordering_constraint_to_expectation
+    sequence = Sequence.new('name')
+    expectation = FakeExpectation.new
+    sequence.constrain_as_next_in_sequence(expectation)
+    assert_equal 1, expectation.ordering_constraints.length
+  end
+
+  def test_should_not_allow_invocation_of_second_method_when_first_n_sequence_has_not_been_invoked
+    sequence = Sequence.new('name')
+    expectation_one = FakeExpectation.new(false)
+    expectation_two = FakeExpectation.new(false)
+    sequence.constrain_as_next_in_sequence(expectation_one)
+    sequence.constrain_as_next_in_sequence(expectation_two)
+    assert !expectation_two.ordering_constraints[0].allows_invocation_now?
+  end
+
+  def test_should_allow_invocation_of_second_method_when_first_in_sequence_has_been_invoked
+    sequence = Sequence.new('name')
+    expectation_one = FakeExpectation.new(true)
+    expectation_two = FakeExpectation.new(false)
+    sequence.constrain_as_next_in_sequence(expectation_one)
+    sequence.constrain_as_next_in_sequence(expectation_two)
+    assert expectation_two.ordering_constraints[0].allows_invocation_now?
+  end
+
+  def test_should_describe_ordering_constraint_as_being_part_of_named_sequence
+    sequence = Sequence.new('wibble')
+    expectation = FakeExpectation.new
+    sequence.constrain_as_next_in_sequence(expectation)
+    assert_equal "in sequence 'wibble'", expectation.ordering_constraints[0].mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/single_return_value_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/single_return_value_test.rb
new file mode 100755
index 0000000..4619499
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/single_return_value_test.rb
@@ -0,0 +1,14 @@
+require File.expand_path('../../test_helper', __FILE__)
+
+require 'mocha/single_return_value'
+
+class SingleReturnValueTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_return_value
+    value = SingleReturnValue.new('value')
+    assert_equal 'value', value.evaluate
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/single_yield_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/single_yield_test.rb
new file mode 100755
index 0000000..e403093
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/single_yield_test.rb
@@ -0,0 +1,18 @@
+require File.expand_path('../../test_helper', __FILE__)
+
+require 'mocha/single_yield'
+
+class SingleYieldTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_provide_parameters_for_single_yield_in_single_invocation
+    parameter_group = SingleYield.new(1, 2, 3)
+    parameter_groups = []
+    parameter_group.each do |parameters|
+      parameter_groups << parameters
+    end
+    assert_equal [[1, 2, 3]], parameter_groups
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/state_machine_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/state_machine_test.rb
new file mode 100755
index 0000000..8fe4e8e
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/state_machine_test.rb
@@ -0,0 +1,98 @@
+require File.expand_path('../../test_helper', __FILE__)
+
+require 'mocha/state_machine'
+
+class StateMachineTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_initially_be_in_no_state
+    state_machine = StateMachine.new('name')
+    any_state.each do |state|
+      assert !state_machine.is(state).active?
+      assert state_machine.is_not(state).active?
+    end
+  end
+
+  def test_should_be_able_to_enter_a_state
+    state_machine = StateMachine.new('name')
+    state = 'A'
+    other_states = any_state.reject { |s| s == state }
+
+    state_machine.is(state).activate
+
+    assert state_machine.is(state).active?
+    assert !state_machine.is_not(state).active?
+    other_states.each do |s|
+      assert !state_machine.is(s).active?
+      assert state_machine.is_not(s).active?
+    end
+  end
+
+  def test_should_be_able_to_change_state
+    state_machine = StateMachine.new('name')
+    state = 'B'
+    other_states = any_state.reject { |s| s == state }
+
+    state_machine.is('A').activate
+    state_machine.is(state).activate
+
+    assert state_machine.is(state).active?
+    assert !state_machine.is_not(state).active?
+    other_states.each do |s|
+      assert !state_machine.is(s).active?
+      assert state_machine.is_not(s).active?
+    end
+  end
+
+  def test_should_be_put_into_an_initial_state
+    state_machine = StateMachine.new('name')
+    initial_state = 'A'
+    other_states = any_state.reject { |s| s == initial_state }
+
+    state_machine.starts_as(initial_state)
+
+    assert state_machine.is(initial_state).active?
+    assert !state_machine.is_not(initial_state).active?
+    other_states.each do |state|
+      assert !state_machine.is(state).active?
+      assert state_machine.is_not(state).active?
+    end
+  end
+
+  def test_should_be_put_into_a_new_state
+    next_state = 'B'
+
+    other_states = any_state.reject { |s| s == next_state }
+    state_machine = StateMachine.new('name').starts_as('A')
+
+    state_machine.become(next_state)
+
+    assert state_machine.is(next_state).active?
+    assert !state_machine.is_not(next_state).active?
+    other_states.each do |state|
+      assert !state_machine.is(state).active?
+      assert state_machine.is_not(state).active?
+    end
+  end
+
+  def test_should_describe_itself_as_name_and_current_state
+    state_machine = StateMachine.new('state_machine_name')
+    assert_equal 'state_machine_name has no current state', state_machine.mocha_inspect
+    inspectable_state = Class.new { define_method(:mocha_inspect) { "'inspectable_state'" } }.new
+    state_machine.is(inspectable_state).activate
+    assert_equal "state_machine_name is 'inspectable_state'", state_machine.mocha_inspect
+  end
+
+  def test_should_have_self_describing_states
+    state_machine = StateMachine.new('state_machine_name')
+    inspectable_state = Class.new { define_method(:mocha_inspect) { "'inspectable_state'" } }.new
+    assert_equal "state_machine_name is 'inspectable_state'", state_machine.is(inspectable_state).mocha_inspect
+    assert_equal "state_machine_name is not 'inspectable_state'", state_machine.is_not(inspectable_state).mocha_inspect
+  end
+
+  def any_state
+    %w(A B C D)
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/string_inspect_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/string_inspect_test.rb
new file mode 100755
index 0000000..2c54f33
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/string_inspect_test.rb
@@ -0,0 +1,11 @@
+require File.expand_path('../../test_helper', __FILE__)
+require 'mocha/inspect'
+
+class StringInspectTest < Mocha::TestCase
+
+  def test_should_replace_escaped_quotes_with_single_quote
+    string = "my_string"
+    assert_equal "'my_string'", string.mocha_inspect
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/thrower_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/thrower_test.rb
new file mode 100755
index 0000000..9486161
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/thrower_test.rb
@@ -0,0 +1,20 @@
+require File.expand_path('../../test_helper', __FILE__)
+
+require 'mocha/thrower'
+
+class ThrowerTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_throw_tag
+    thrower = Thrower.new(:tag)
+    assert_throws(:tag) { thrower.evaluate }
+  end
+
+  def test_should_throw_tag_with_return_value
+    thrower = Thrower.new(:tag, 'return-value')
+    return_value = catch(:tag) { thrower.evaluate }
+    assert_equal 'return-value', return_value
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/test/unit/yield_parameters_test.rb b/app/server/vendor/mocha-1.1.0/test/unit/yield_parameters_test.rb
new file mode 100755
index 0000000..e1b7007
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/test/unit/yield_parameters_test.rb
@@ -0,0 +1,93 @@
+require File.expand_path('../../test_helper', __FILE__)
+
+require 'mocha/yield_parameters'
+require 'mocha/no_yields'
+require 'mocha/single_yield'
+require 'mocha/multiple_yields'
+
+class YieldParametersTest < Mocha::TestCase
+
+  include Mocha
+
+  def test_should_return_null_yield_parameter_group_by_default
+    yield_parameters = YieldParameters.new
+    assert yield_parameters.next_invocation.is_a?(NoYields)
+  end
+
+  def test_should_return_single_yield_parameter_group
+    yield_parameters = YieldParameters.new
+    yield_parameters.add(1, 2, 3)
+    parameter_group = yield_parameters.next_invocation
+    assert parameter_group.is_a?(SingleYield)
+    assert_equal [1, 2, 3], parameter_group.parameters
+  end
+
+  def test_should_keep_returning_single_yield_parameter_group
+    yield_parameters = YieldParameters.new
+    yield_parameters.add(1, 2, 3)
+    yield_parameters.next_invocation
+    parameter_group = yield_parameters.next_invocation
+    assert parameter_group.is_a?(SingleYield)
+    assert_equal [1, 2, 3], parameter_group.parameters
+    parameter_group = yield_parameters.next_invocation
+    assert parameter_group.is_a?(SingleYield)
+    assert_equal [1, 2, 3], parameter_group.parameters
+  end
+
+  def test_should_return_consecutive_single_yield_parameter_groups
+    yield_parameters = YieldParameters.new
+    yield_parameters.add(1, 2, 3)
+    yield_parameters.add(4, 5)
+    parameter_group = yield_parameters.next_invocation
+    assert parameter_group.is_a?(SingleYield)
+    assert_equal [1, 2, 3], parameter_group.parameters
+    parameter_group = yield_parameters.next_invocation
+    assert parameter_group.is_a?(SingleYield)
+    assert_equal [4, 5], parameter_group.parameters
+  end
+
+  def test_should_return_multiple_yield_parameter_group
+    yield_parameters = YieldParameters.new
+    yield_parameters.multiple_add([1, 2, 3], [4, 5])
+    parameter_group = yield_parameters.next_invocation
+    assert parameter_group.is_a?(MultipleYields)
+    assert_equal [[1, 2, 3], [4, 5]], parameter_group.parameter_groups
+  end
+
+  def test_should_keep_returning_multiple_yield_parameter_group
+    yield_parameters = YieldParameters.new
+    yield_parameters.multiple_add([1, 2, 3], [4, 5])
+    yield_parameters.next_invocation
+    parameter_group = yield_parameters.next_invocation
+    assert parameter_group.is_a?(MultipleYields)
+    assert_equal [[1, 2, 3], [4, 5]], parameter_group.parameter_groups
+    parameter_group = yield_parameters.next_invocation
+    assert parameter_group.is_a?(MultipleYields)
+    assert_equal [[1, 2, 3], [4, 5]], parameter_group.parameter_groups
+  end
+
+  def test_should_return_consecutive_multiple_yield_parameter_groups
+    yield_parameters = YieldParameters.new
+    yield_parameters.multiple_add([1, 2, 3], [4, 5])
+    yield_parameters.multiple_add([6, 7], [8, 9, 0])
+    parameter_group = yield_parameters.next_invocation
+    assert parameter_group.is_a?(MultipleYields)
+    assert_equal [[1, 2, 3], [4, 5]], parameter_group.parameter_groups
+    parameter_group = yield_parameters.next_invocation
+    assert parameter_group.is_a?(MultipleYields)
+    assert_equal [[6, 7], [8, 9, 0]], parameter_group.parameter_groups
+  end
+
+  def test_should_return_consecutive_single_and_multiple_yield_parameter_groups
+    yield_parameters = YieldParameters.new
+    yield_parameters.add(1, 2, 3)
+    yield_parameters.multiple_add([4, 5, 6], [7, 8])
+    parameter_group = yield_parameters.next_invocation
+    assert parameter_group.is_a?(SingleYield)
+    assert_equal [1, 2, 3], parameter_group.parameters
+    parameter_group = yield_parameters.next_invocation
+    assert parameter_group.is_a?(MultipleYields)
+    assert_equal [[4, 5, 6], [7, 8]], parameter_group.parameter_groups
+  end
+
+end
diff --git a/app/server/vendor/mocha-1.1.0/yard-templates/default/layout/html/google_analytics.erb b/app/server/vendor/mocha-1.1.0/yard-templates/default/layout/html/google_analytics.erb
new file mode 100755
index 0000000..62b09a6
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/yard-templates/default/layout/html/google_analytics.erb
@@ -0,0 +1,11 @@
+<script src="/javascripts/app.js" type="text/javascript" charset="utf-8"></script>
+
+<script>
+  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+  ga('create', '<%= ENV['GOOGLE_ANALYTICS_WEB_PROPERTY_ID'] %>', 'gofreerange.com');
+  ga('send', 'pageview');
+</script>
\ No newline at end of file
diff --git a/app/server/vendor/mocha-1.1.0/yard-templates/default/layout/html/setup.rb b/app/server/vendor/mocha-1.1.0/yard-templates/default/layout/html/setup.rb
new file mode 100755
index 0000000..4ddc1aa
--- /dev/null
+++ b/app/server/vendor/mocha-1.1.0/yard-templates/default/layout/html/setup.rb
@@ -0,0 +1,6 @@
+def init
+  super
+  if ENV['GOOGLE_ANALYTICS_WEB_PROPERTY_ID']
+    sections[:layout] << :google_analytics
+  end
+end
diff --git a/app/server/vendor/multi_json/.document b/app/server/vendor/multi_json/.document
new file mode 100644
index 0000000..3b0c733
--- /dev/null
+++ b/app/server/vendor/multi_json/.document
@@ -0,0 +1,5 @@
+LICENSE.md
+README.md
+bin/*
+features/**/*.feature
+lib/**/*.rb
diff --git a/app/server/vendor/multi_json/.gemtest b/app/server/vendor/multi_json/.gemtest
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/vendor/multi_json/.gitignore b/app/server/vendor/multi_json/.gitignore
new file mode 100644
index 0000000..fc699d3
--- /dev/null
+++ b/app/server/vendor/multi_json/.gitignore
@@ -0,0 +1,36 @@
+## TEXTMATE
+*.tmproj
+tmtags
+
+## EMACS
+*~
+\#*
+.\#*
+
+## VIM
+*.swp
+
+## PROJECT::GENERAL
+.yardoc
+coverage
+doc
+rdoc
+log
+
+## BUNDLER
+*.gem
+.bundle
+pkg
+Gemfile.lock
+
+## RBENV
+.ruby-version
+.rbenv*
+
+## RCOV
+coverage.data
+
+tmp
+
+## RUBINIUS
+*.rbc
diff --git a/app/server/vendor/multi_json/.rspec b/app/server/vendor/multi_json/.rspec
new file mode 100644
index 0000000..0912718
--- /dev/null
+++ b/app/server/vendor/multi_json/.rspec
@@ -0,0 +1,2 @@
+--color
+--order random
diff --git a/app/server/vendor/multi_json/.travis.yml b/app/server/vendor/multi_json/.travis.yml
new file mode 100644
index 0000000..05dfbb0
--- /dev/null
+++ b/app/server/vendor/multi_json/.travis.yml
@@ -0,0 +1,19 @@
+bundler_args: --without development
+language: ruby
+rvm:
+  - 1.8.7
+  - 1.9.2
+  - 1.9.3
+  - 2.0.0
+  - 2.1.0
+  - 2.1.1
+  - jruby-18mode
+  - jruby-19mode
+  - jruby-head
+  - rbx-2
+  - ruby-head
+matrix:
+  allow_failures:
+    - rvm: jruby-head
+    - rvm: ruby-head
+  fast_finish: true
diff --git a/app/server/vendor/multi_json/.yardopts b/app/server/vendor/multi_json/.yardopts
new file mode 100644
index 0000000..884b083
--- /dev/null
+++ b/app/server/vendor/multi_json/.yardopts
@@ -0,0 +1,6 @@
+--markup markdown
+-
+CHANGELOG.md
+CONTRIBUTING.md
+LICENSE.md
+README.md
diff --git a/app/server/vendor/multi_json/CHANGELOG.md b/app/server/vendor/multi_json/CHANGELOG.md
new file mode 100644
index 0000000..1a9882d
--- /dev/null
+++ b/app/server/vendor/multi_json/CHANGELOG.md
@@ -0,0 +1,207 @@
+1.9.2
+-----
+* [Enable use_to_json option for Oj adapter by default](https://github.com/intridea/multi_json/commit/76a4aaf697b10bbabd5d535d83cf1149efcfe5c7)
+
+1.9.1
+-----
+* [Remove unused LoadError file](https://github.com/intridea/multi_json/commit/65dedd84d59baeefc25c477fedf0bbe85e7ce2cd)
+
+1.9.0
+----
+* [Rename LoadError to ParseError](https://github.com/intridea/multi_json/commit/4abb98fe3a90b2a7b3d1594515c8a06042b4a27d)
+* [Adapter load failure throws AdapterError instead of ArgumentError](https://github.com/intridea/multi_json/commit/4da612b617bd932bb6fa1cc4c43210327f98f271)
+
+1.8.4
+-----
+* [Make Gson adapter explicitly read StringIO object](https://github.com/intridea/multi_json/commit/b58b498747ff6e94f41488c971b2a30a98760ef2)
+
+1.8.3
+-----
+* [Make JrJackson explicitly read StringIO objects](https://github.com/intridea/multi_json/commit/e1f162d5b668e5e4db5afa175361a601a8aa2b05)
+* [Prevent calling #downcase on alias symbols](https://github.com/intridea/multi_json/commit/c1cf075453ce0110f7decc4f906444b1233bb67c)
+
+1.8.2
+-----
+* [Downcase adapter string name for OS compatibility](https://github.com/intridea/multi_json/commit/b8e15a032247a63f1410d21a18add05035f3fa66)
+
+1.8.1
+-----
+* [Let the adapter handle strings with invalid encoding](https://github.com/intridea/multi_json/commit/6af2bf87b89f44eabf2ae9ca96779febc65ea94b)
+
+1.8.0
+-----
+* [Raise MultiJson::LoadError on blank input](https://github.com/intridea/multi_json/commit/c44f9c928bb25fe672246ad394b3e5b991be32e6)
+
+1.7.9
+-----
+* [Explicitly require json gem code even when constant is defined](https://github.com/intridea/multi_json/commit/36f7906c66477eb4b55b7afeaa3684b6db69eff2)
+
+1.7.8
+-----
+* [Reorder JrJackson before json_gem](https://github.com/intridea/multi_json/commit/315b6e460b6e4dcdb6c82e04e4be8ee975d395da)
+* [Update vendored OkJson to version 43](https://github.com/intridea/multi_json/commit/99a6b662f6ef4036e3ee94d7eb547fa72fb2ab50)
+
+1.7.7
+-----
+* [Fix options caching issues](https://github.com/intridea/multi_json/commit/a3f14c3661688c5927638fa6088c7b46a67e875e)
+
+1.7.6
+-----
+* [Bring back MultiJson::VERSION constant](https://github.com/intridea/multi_json/commit/31b990c2725e6673bf8ce57540fe66b57a751a72)
+
+1.7.5
+-----
+* [Fix warning '*' interpreted as argument prefix](https://github.com/intridea/multi_json/commit/b698962c7f64430222a1f06430669706a47aff89)
+* [Remove stdlib warning](https://github.com/intridea/multi_json/commit/d06eec6b7996ac8b4ff0e2229efd835379b0c30f)
+
+1.7.4
+-----
+* [Cache options for better performance](https://github.com/intridea/multi_json/commit/8a26ee93140c4bed36194ed9fb887a1b6919257b)
+
+1.7.3
+-----
+* [Require json/ext to ensure extension version gets loaded for json_gem](https://github.com/intridea/multi_json/commit/942686f7e8597418c6f90ee69e1d45242fac07b1)
+* [Rename JrJackson](https://github.com/intridea/multi_json/commit/078de7ba8b6035343c3e96b4767549e9ec43369a)
+* [Prefer JrJackson to JSON gem if present](https://github.com/intridea/multi_json/commit/af8bd9799a66855f04b3aff1c488485950cec7bf)
+* [Print a warning if outdated gem versions are used](https://github.com/intridea/multi_json/commit/e7438e7ba2be0236cfa24c2bb9ad40ee821286d1)
+* [Loosen required_rubygems_version for compatibility with Ubuntu 10.04](https://github.com/intridea/multi_json/commit/59fad014e8fe41dbc6f09485ea0dc21fc42fd7a7)
+
+1.7.2
+-----
+* [Rename Jrjackson adapter to JrJackson](https://github.com/intridea/multi_json/commit/b36dc915fc0e6548cbad06b5db6f520e040c9c8b)
+* [Implement jrjackson -> jr_jackson alias for back-compatability](https://github.com/intridea/multi_json/commit/aa50ab8b7bb646b8b75d5d65dfeadae8248a4f10)
+* [Update vendored OkJson module](https://github.com/intridea/multi_json/commit/30a3f474e17dd86a697c3fab04f468d1a4fd69d7)
+
+1.7.1
+-----
+* [Fix capitalization of JrJackson class](https://github.com/intridea/multi_json/commit/5373a5e38c647f02427a0477cb8e0e0dafad1b8d)
+
+1.7.0
+-----
+* [Add load_options/dump_options to MultiJson](https://github.com/intridea/multi_json/commit/a153956be6b0df06ea1705ce3c1ff0b5b0e27ea5)
+* [MultiJson does not modify arguments](https://github.com/intridea/multi_json/commit/58525b01c4c2f6635ba2ac13d6fd987b79f3962f)
+* [Enable quirks_mode by default for json_gem/json_pure adapters](https://github.com/intridea/multi_json/commit/1fd4e6635c436515b7d7d5a0bee4548de8571520)
+* [Add JrJackson adapter](https://github.com/intridea/multi_json/commit/4dd86fa96300aaaf6d762578b9b31ea82adb056d)
+* [Raise ArgumentError on bad adapter input](https://github.com/intridea/multi_json/commit/911a3756bdff2cb5ac06497da3fa3e72199cb7ad)
+
+1.6.1
+-----
+* [Revert "Use JSON.generate instead of #to_json"](https://github.com/intridea/multi_json/issues/86)
+
+1.6.0
+-----
+* [Add gson.rb support](https://github.com/intridea/multi_json/pull/71)
+* [Add MultiJson.default_options](https://github.com/intridea/multi_json/pull/70)
+* [Add MultiJson.with_adapter](https://github.com/intridea/multi_json/pull/67)
+* [Stringify all possible keys for ok_json](https://github.com/intridea/multi_json/pull/66)
+* [Use JSON.generate instead of #to_json](https://github.com/intridea/multi_json/issues/73)
+* [Alias `MultiJson::DecodeError` to `MultiJson::LoadError`](https://github.com/intridea/multi_json/pull/79)
+
+1.5.1
+-----
+* [Do not allow Oj or JSON to create symbols by searching for classes](https://github.com/intridea/multi_json/commit/193e28cf4dc61b6e7b7b7d80f06f74c76df65c41)
+
+1.5.0
+-----
+* [Add `MultiJson.with_adapter` method](https://github.com/intridea/multi_json/commit/d14c5d28cae96557a0421298621b9499e1f28104)
+* [Stringify all possible keys for `ok_json`](https://github.com/intridea/multi_json/commit/73998074058e1e58c557ffa7b9541d486d6041fa)
+
+1.4.0
+-----
+* [Allow `load`/`dump` of JSON fragments](https://github.com/intridea/multi_json/commit/707aae7d48d39c85b38febbd2c210ba87f6e4a36)
+
+1.3.7
+-----
+* [Fix rescue clause for MagLev](https://github.com/intridea/multi_json/commit/39abdf50199828c50e85b2ce8f8ba31fcbbc9332)
+* [Remove unnecessary check for string version of options key](https://github.com/intridea/multi_json/commit/660101b70e962b3c007d0b90d45944fa47d13ec4)
+* [Explicitly set default adapter when adapter is set to `nil` or `false`](https://github.com/intridea/multi_json/commit/a9e587d5a63eafb4baee9fb211265e4dd96a26bc)
+* [Fix Oj `ParseError` mapping for Oj 1.4.0](https://github.com/intridea/multi_json/commit/7d9045338cc9029401c16f3c409d54ce97f275e2)
+
+1.3.6
+-----
+* [Allow adapter-specific options to be passed through to Oj](https://github.com/intridea/multi_json/commit/d0e5feeebcba0bc69400dd203a295f5c30971223)
+
+1.3.5
+-----
+* [Add pretty support to Oj adapter](https://github.com/intridea/multi_json/commit/0c8f75f03020c53bcf4c6be258faf433d24b2c2b)
+
+1.3.4
+-----
+* [Use `class << self` instead of `module_function` to create aliases](https://github.com/intridea/multi_json/commit/ba1451c4c48baa297e049889be241a424cb05980)
+
+1.3.3
+-----
+* [Remove deprecation warnings](https://github.com/intridea/multi_json/commit/36b524e71544eb0186826a891bcc03b2820a008f)
+
+1.3.2
+-----
+* [Add ability to use adapter per call](https://github.com/intridea/multi_json/commit/106bbec469d5d0a832bfa31fffcb8c0f0cdc9bd3)
+* [Add and deprecate `default_engine` method](https://github.com/intridea/multi_json/commit/fc3df0c7a3e2ab9ce0c2c7e7617a4da97dd13f6e)
+
+1.3.1
+-----
+* [Only warn once for each instance a deprecated method is called](https://github.com/intridea/multi_json/commit/e21d6eb7da74b3f283995c1d27d5880e75f0ae84)
+
+1.3.0
+-----
+* [Implement `load`/`dump`; deprecate `decode`/`encode`](https://github.com/intridea/multi_json/commit/e90fd6cb1b0293eb0c73c2f4eb0f7a1764370216)
+* [Rename engines to adapters](https://github.com/intridea/multi_json/commit/ae7fd144a7949a9c221dcaa446196ec23db908df)
+
+1.2.0
+-----
+* [Add support for Oj](https://github.com/intridea/multi_json/commit/acd06b233edabe6c44f226873db7b49dab560c60)
+
+1.1.0
+-----
+* [`NSJSONSerialization` support for MacRuby](https://github.com/intridea/multi_json/commit/f862e2fc966cac8867fe7da3997fc76e8a6cf5d4)
+
+1.0.4
+-----
+* [Set data context to `DecodeError` exception](https://github.com/intridea/multi_json/commit/19ddafd44029c6681f66fae2a0f6eabfd0f85176)
+* [Allow `ok_json` to fallback to `to_json`](https://github.com/intridea/multi_json/commit/c157240b1193b283d06d1bd4d4b5b06bcf3761f8)
+* [Add warning when using `ok_json`](https://github.com/intridea/multi_json/commit/dd4b68810c84f826fb98f9713bfb29ab96888d57)
+* [Options can be passed to an engine on encode](https://github.com/intridea/multi_json/commit/e0a7ff5d5ff621ffccc61617ed8aeec5816e81f7)
+
+1.0.3
+-----
+* [`Array` support for `stringify_keys`](https://github.com/intridea/multi_json/commit/644d1c5c7c7f6a27663b11668527b346094e38b9)
+* [`Array` support for `symbolize_keys`](https://github.com/intridea/multi_json/commit/c885377d47a2aa39cb0d971fea78db2d2fa479a7)
+
+1.0.2
+-----
+* [Allow encoding of rootless JSON when `ok_json` is used](https://github.com/intridea/multi_json/commit/d1cde7de97cb0f6152aef8daf14037521cdce8c6)
+
+1.0.1
+-----
+* [Correct an issue with `ok_json` not being returned as the default engine](https://github.com/intridea/multi_json/commit/d33c141619c54cccd770199694da8fd1bd8f449d)
+
+1.0.0
+-----
+* [Remove `ActiveSupport::JSON` support](https://github.com/intridea/multi_json/commit/c2f4140141d785a24b3f56e58811b0e561b37f6a)
+* [Fix `@engine` ivar warning](https://github.com/intridea/multi_json/commit/3b978a8995721a8dffedc3b75a7f49e5494ec553)
+* [Only `rescue` from parsing errors during decoding, not any `StandardError`](https://github.com/intridea/multi_json/commit/391d00b5e85294d42d41347605d8d46b4a7f66cc)
+* [Rename `okjson` engine and vendored lib to `ok_json`](https://github.com/intridea/multi_json/commit/5bd1afc977a8208ddb0443e1d57cb79665c019f1)
+* [Add `StringIO` support to `json` gem and `ok_json`](https://github.com/intridea/multi_json/commit/1706b11568db7f50af451fce5f4d679aeb3bbe8f)
+
+0.0.5
+-----
+* [Trap all JSON decoding errors; raise `MultiJson::DecodeError`](https://github.com/intridea/multi_json/commit/dea9a1aef6dd1212aa1e5a37ab1669f9b045b732)
+
+0.0.4
+-----
+* [Fix default_engine check for `json` gem](https://github.com/intridea/multi_json/commit/caced0c4e8c795922a109ebc00c3c4fa8635bed8)
+* [Make requirement mapper an `Array` to preserve order in Ruby versions < 1.9](https://github.com/intridea/multi_json/commit/526f5f29a42131574a088ad9bbb43d7f48439b2c)
+
+0.0.3
+-----
+* [Improve defaulting and documentation](https://github.com/sferik/twitter/commit/3a0e41b9e4b0909201045fa47704b78c9d949b73)
+
+0.0.2
+-----
+
+* [Rename to `multi_json`](https://github.com/sferik/twitter/commit/461ab89ce071c8c9fabfc183581e0ec523788b62)
+
+0.0.1
+-----
+
+* [Initial commit](https://github.com/sferik/twitter/commit/518c21ab299c500527491e6c049ab2229e22a805)
diff --git a/app/server/vendor/multi_json/CONTRIBUTING.md b/app/server/vendor/multi_json/CONTRIBUTING.md
new file mode 100644
index 0000000..3e8bfd5
--- /dev/null
+++ b/app/server/vendor/multi_json/CONTRIBUTING.md
@@ -0,0 +1,46 @@
+## Contributing
+In the spirit of [free software][free-sw], **everyone** is encouraged to help
+improve this project.
+
+[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html
+
+Here are some ways *you* can contribute:
+
+* by using alpha, beta, and prerelease versions
+* by reporting bugs
+* by suggesting new features
+* by writing or editing documentation
+* by writing specifications
+* by writing code (**no patch is too small**: fix typos, add comments, clean up
+  inconsistent whitespace)
+* by refactoring code
+* by closing [issues][]
+* by reviewing patches
+
+[issues]: https://github.com/intridea/multi_json/issues
+
+## Submitting an Issue
+We use the [GitHub issue tracker][issues] to track bugs and features. Before
+submitting a bug report or feature request, check to make sure it hasn't
+already been submitted. When submitting a bug report, please include a [Gist][]
+that includes a stack trace and any details that may be necessary to reproduce
+the bug, including your gem version, Ruby version, and operating system.
+Ideally, a bug report should include a pull request with failing specs.
+
+[gist]: https://gist.github.com/
+
+## Submitting a Pull Request
+1. [Fork the repository.][fork]
+2. [Create a topic branch.][branch]
+3. Add specs for your unimplemented feature or bug fix.
+4. Run `bundle exec rake spec`. If your specs pass, return to step 3.
+5. Implement your feature or bug fix.
+6. Run `bundle exec rake spec`. If your specs fail, return to step 5.
+7. Run `open coverage/index.html`. If your changes are not completely covered
+   by your tests, return to step 3.
+8. Add, commit, and push your changes.
+9. [Submit a pull request.][pr]
+
+[fork]: http://help.github.com/fork-a-repo/
+[branch]: http://learn.github.com/p/branching.html
+[pr]: http://help.github.com/send-pull-requests/
diff --git a/app/server/vendor/multi_json/Gemfile b/app/server/vendor/multi_json/Gemfile
new file mode 100644
index 0000000..c49a36e
--- /dev/null
+++ b/app/server/vendor/multi_json/Gemfile
@@ -0,0 +1,30 @@
+source 'https://rubygems.org'
+
+gem 'rake', '>= 0.9'
+gem 'yard', '>= 0.8'
+
+gem 'json',      '~> 1.4', :require => nil
+gem 'json_pure', '~> 1.4', :require => nil
+
+group :development do
+  gem 'kramdown', '>= 0.14'
+  gem 'pry'
+  gem 'pry-debugger', :platforms => :mri
+end
+
+group :test do
+  gem 'rspec', '>= 2.14'
+  gem 'simplecov', :require => false
+end
+
+platforms :jruby do
+  gem 'gson', '>= 0.6', :require => nil
+  gem 'jrjackson', '~> 0.2.2', :require => nil
+end
+
+platforms :mingw, :mswin, :ruby do
+  gem 'oj', '~> 2.0', :require => nil
+  gem 'yajl-ruby', '~> 1.0', :require => nil
+end
+
+gemspec
diff --git a/app/server/vendor/multi_json/LICENSE.md b/app/server/vendor/multi_json/LICENSE.md
new file mode 100644
index 0000000..1768f37
--- /dev/null
+++ b/app/server/vendor/multi_json/LICENSE.md
@@ -0,0 +1,20 @@
+Copyright (c) 2010-2013 Michael Bleigh, Josh Kalderimis, Erik Michaels-Ober, Pavel Pravosud
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/multi_json/README.md b/app/server/vendor/multi_json/README.md
new file mode 100644
index 0000000..c2ebe07
--- /dev/null
+++ b/app/server/vendor/multi_json/README.md
@@ -0,0 +1,120 @@
+# MultiJSON
+
+[![Gem Version](http://img.shields.io/gem/v/multi_json.svg)][gem]
+[![Build Status](http://img.shields.io/travis/intridea/multi_json.svg)][travis]
+[![Dependency Status](http://img.shields.io/gemnasium/intridea/multi_json.svg)][gemnasium]
+[![Code Climate](http://img.shields.io/codeclimate/github/intridea/multi_json.svg)][codeclimate]
+
+[gem]: https://rubygems.org/gems/multi_json
+[travis]: http://travis-ci.org/intridea/multi_json
+[gemnasium]: https://gemnasium.com/intridea/multi_json
+[codeclimate]: https://codeclimate.com/github/intridea/multi_json
+
+Lots of Ruby libraries parse JSON and everyone has their favorite JSON coder.
+Instead of choosing a single JSON coder and forcing users of your library to be
+stuck with it, you can use MultiJSON instead, which will simply choose the
+fastest available JSON coder. Here's how to use it:
+
+```ruby
+require 'multi_json'
+
+MultiJson.load('{"abc":"def"}') #=> {"abc" => "def"}
+MultiJson.load('{"abc":"def"}', :symbolize_keys => true) #=> {:abc => "def"}
+MultiJson.dump({:abc => 'def'}) # convert Ruby back to JSON
+MultiJson.dump({:abc => 'def'}, :pretty => true) # encoded in a pretty form (if supported by the coder)
+```
+
+When loading invalid JSON, MultiJson will throw a `MultiJson::ParseError`. `MultiJson::DecodeError` and `MultiJson::LoadError` are aliases for backwards compatibility.
+
+```ruby
+begin
+  MultiJson.load('{invalid json}')
+rescue MultiJson::ParseError => exception
+  exception.data # => "{invalid json}"
+  exception.cause # => JSON::ParserError: 795: unexpected token at '{invalid json}'
+end
+```
+
+`ParseError` instance has `cause` reader which contains the original exception.
+It also has `data` reader with the input that caused the problem.
+
+The `use` method, which sets the MultiJson adapter, takes either a symbol or a
+class (to allow for custom JSON parsers) that responds to both `.load` and `.dump`
+at the class level.
+
+When MultiJson fails to load the specified adapter, it'll throw `MultiJson::AdapterError`
+which inherits from `ArgumentError`.
+
+MultiJSON tries to have intelligent defaulting. That is, if you have any of the
+supported engines already loaded, it will utilize them before attempting to
+load any. When loading, libraries are ordered by speed. First Oj, then Yajl,
+then the JSON gem, then JSON pure. If no other JSON library is available,
+MultiJSON falls back to [OkJson][], a simple, vendorable JSON parser.
+
+[okjson]: https://github.com/kr/okjson
+
+## Supported JSON Engines
+
+* [Oj](https://github.com/ohler55/oj) Optimized JSON by Peter Ohler
+* [Yajl](https://github.com/brianmario/yajl-ruby) Yet Another JSON Library by Brian Lopez
+* [JSON](https://github.com/flori/json) The default JSON gem with C-extensions (ships with Ruby 1.9)
+* [JSON Pure](https://github.com/flori/json) A Ruby variant of the JSON gem
+* [NSJSONSerialization](https://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html) Wrapper for Apple's NSJSONSerialization in the Cocoa Framework (MacRuby only)
+* [gson.rb](https://github.com/avsej/gson.rb) A Ruby wrapper for google-gson library (JRuby only)
+* [JrJackson](https://github.com/guyboertje/jrjackson) JRuby wrapper for Jackson (JRuby only)
+* [OkJson][okjson] A simple, vendorable JSON parser
+
+## Supported Ruby Versions
+This library aims to support and is [tested against][travis] the following Ruby
+implementations:
+
+* Ruby 1.8.7
+* Ruby 1.9.2
+* Ruby 1.9.3
+* Ruby 2.0.0
+* Ruby 2.1.0
+* Ruby 2.1.1
+* [JRuby][]
+* [Rubinius][]
+* [MacRuby][] (not tested on Travis CI)
+
+[jruby]: http://www.jruby.org/
+[rubinius]: http://rubini.us/
+[macruby]: http://www.macruby.org/
+
+If something doesn't work on one of these interpreters, it's a bug.
+
+This library may inadvertently work (or seem to work) on other Ruby
+implementations, however support will only be provided for the versions listed
+above.
+
+If you would like this library to support another Ruby version, you may
+volunteer to be a maintainer. Being a maintainer entails making sure all tests
+run and pass on that implementation. When something breaks on your
+implementation, you will be responsible for providing patches in a timely
+fashion. If critical issues for a particular implementation exist at the time
+of a major release, support for that Ruby version may be dropped.
+
+## Versioning
+
+This library aims to adhere to [Semantic Versioning 2.0.0][semver]. Violations
+of this scheme should be reported as bugs. Specifically, if a minor or patch
+version is released that breaks backward compatibility, that version should be
+immediately yanked and/or a new version should be immediately released that
+restores compatibility. Breaking changes to the public API will only be
+introduced with new major versions. As a result of this policy, you can (and
+should) specify a dependency on this gem using the [Pessimistic Version
+Constraint][pvc] with two digits of precision. For example:
+
+```ruby
+spec.add_dependency 'multi_json', '~> 1.0'
+```
+
+[semver]: http://semver.org/
+[pvc]: http://docs.rubygems.org/read/chapter/16#page74
+
+## Copyright
+Copyright (c) 2010-2013 Michael Bleigh, Josh Kalderimis, Erik Michaels-Ober,
+and Pavel Pravosud. See [LICENSE][] for details.
+
+[license]: LICENSE.md
diff --git a/app/server/vendor/multi_json/Rakefile b/app/server/vendor/multi_json/Rakefile
new file mode 100644
index 0000000..e84074e
--- /dev/null
+++ b/app/server/vendor/multi_json/Rakefile
@@ -0,0 +1,25 @@
+require 'bundler'
+Bundler::GemHelper.install_tasks
+
+require 'rspec/core/rake_task'
+RSpec::Core::RakeTask.new(:base_spec) do |task|
+  task.pattern = 'spec/multi_json_spec.rb'
+end
+
+namespace :adapters do
+  Dir['spec/*_adapter_spec.rb'].each do |adapter_spec|
+    adapter_name = adapter_spec[/(\w+)_adapter_spec/, 1]
+    desc "Run #{adapter_name} adapter specs"
+    RSpec::Core::RakeTask.new(adapter_name) do |task|
+      task.pattern = adapter_spec
+    end
+  end
+end
+
+task :spec => %w[base_spec adapters:oj adapters:yajl adapters:json_gem adapters:json_pure adapters:ok_json adapters:gson adapters:jr_jackson adapters:nsjsonserialization]
+
+task :default => :spec
+task :test => :spec
+
+require 'yard'
+YARD::Rake::YardocTask.new
diff --git a/app/server/vendor/multi_json/certs/rwz.pem b/app/server/vendor/multi_json/certs/rwz.pem
new file mode 100644
index 0000000..3cdc0ab
--- /dev/null
+++ b/app/server/vendor/multi_json/certs/rwz.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MQ4wDAYDVQQDDAVwYXZl
+bDEYMBYGCgmSJomT8ixkARkWCHByYXZvc3VkMRMwEQYKCZImiZPyLGQBGRYDY29t
+MB4XDTEzMDgxMTE1NDYzNVoXDTE0MDgxMTE1NDYzNVowPzEOMAwGA1UEAwwFcGF2
+ZWwxGDAWBgoJkiaJk/IsZAEZFghwcmF2b3N1ZDETMBEGCgmSJomT8ixkARkWA2Nv
+bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO8/eRkT0QewaGvJ4nnV
+PejBZ50kVhQIQAdc+fdp4JyQX4Nn1FdxMe2q7BGYtSmdCLNnqO//m/HRzAyjIN5O
+tYRcODPI4gCSJR2wlS72+PJvZv8m0FHnzO5BeQ2w5UcGifyaR/A/xOx1oFnNcDMB
+N6yIOV7IcQrz1OaGwdr7r+1D4Y0ZM0bCJVq882UNsqlnLC3tHGMNsPEj+dgrysWp
+c7XRxH+LZHfPVYy2JQ+DmAFZE8yjuRe/BgsAe59j7Zxtxu62BrLk2yWp44YZF0Gx
+nwJh83W7cSmNDGKy72tIsuUAqSUunp3rJ2zkgkY3G9lFQHqIzxQJxdq8Ir0GFlUo
+W6cCAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFDti
++zDBnPhm+3PsLqXqlFWuxiCsMB0GA1UdEQQWMBSBEnBhdmVsQHByYXZvc3VkLmNv
+bTAdBgNVHRIEFjAUgRJwYXZlbEBwcmF2b3N1ZC5jb20wDQYJKoZIhvcNAQEFBQAD
+ggEBAC/fDN75QBrn+A5ERo9qlMd1DcAC3UNvjnWpHvRTva2I1PxIg2zEJphOimDo
+hEvmruC3urPpMwEuAsRfyL6+5SRBnAfLP4Yu7SFYuMRtnZvIYVUgUmxoteISbm7g
+FPXe8v3M5aYJ1e/VM11G+2ZwXsAx/rH4kaAhFBMQadrnamluFHX+tdTVCbEwZW/5
+NrgsYshJ0qFLYhfktlApOAisrXZskGYAeUQSWVu5nzqQlQ3+wXNsPtATuZNtvUaB
+7BTxdlSpJZDcAK29Ni3NRCRu6Air4wfDln0Ilzeuut6cJ4/j2/RlvsccVSRaEfOa
+wM7GTK5SEdU3qelyBdc4+RRs6uU=
+-----END CERTIFICATE-----
diff --git a/app/server/vendor/multi_json/certs/sferik.pem b/app/server/vendor/multi_json/certs/sferik.pem
new file mode 100644
index 0000000..04e0640
--- /dev/null
+++ b/app/server/vendor/multi_json/certs/sferik.pem
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDLjCCAhagAwIBAgIBADANBgkqhkiG9w0BAQUFADA9MQ8wDQYDVQQDDAZzZmVy
+aWsxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2NvbTAe
+Fw0xMzAyMDMxMDAyMjdaFw0xNDAyMDMxMDAyMjdaMD0xDzANBgNVBAMMBnNmZXJp
+azEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29tMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl0x5dx8uKxi7TkrIuyBUTJVB
+v1o93nUB9j/y4M96gV2rYwAci1JPBseNd6Fybzjo3YGuHl7EQHuSHNaf1p2lxew/
+y60JXIJBBgPcDK/KCP4NUHofm0jfoYD+H5uNJfHCNq7/ZsTxOtE3Ra92s0BCMTpm
+wBMMlWR5MtdEhIYuBO4XhnejYgH0L/7BL2lymntVnsr/agdQoojQCN1IQmsRJvrR
+duZRO3tZvoIo1pBc4JEehDuqCeyBgPLOqMoKtQlold1TQs1kWUBK7KWMFEhKC/Kg
+zyzKRHQo9yDYwOvYngoBLY+T/lwCT4dyssdhzRbfnxAhaKu4SAssIwaC01yVowID
+AQABozkwNzAJBgNVHRMEAjAAMB0GA1UdDgQWBBS0ruDfRak5ci1OpDNX/ZdDEkIs
+iTALBgNVHQ8EBAMCBLAwDQYJKoZIhvcNAQEFBQADggEBAHHSMs/MP0sOaLkEv4Jo
+zvkm3qn5A6t0vaHx774cmejyMU+5wySxRezspL7ULh9NeuK2OhU+Oe3TpqrAg5TK
+R8GQILnVu2FemGA6sAkPDlcPtgA6ieI19PZOF6HVLmc/ID/dP/NgZWWzEeqQKmcK
+2+HM+SEEDhZkScYekw4ZOe164ZtZG816oAv5x0pGitSIkumUp7V8iEZ/6ehr7Y9e
+XOg4eeun5L/JjmjARoW2kNdvkRD3c2EeSLqWvQRsBlypHfhs6JJuLlyZPGhU3R/v
+Sf3lVKpBCWgRpGTvy45XVpB+59y33PJmEuQ1PTEOYvQyao9UKMAAaAN/7qWQtjl0
+hlw=
+-----END CERTIFICATE-----
diff --git a/app/server/vendor/multi_json/lib/multi_json.rb b/app/server/vendor/multi_json/lib/multi_json.rb
new file mode 100644
index 0000000..b86296b
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json.rb
@@ -0,0 +1,160 @@
+require 'multi_json/options'
+require 'multi_json/version'
+require 'multi_json/adapter_error'
+require 'multi_json/parse_error'
+
+module MultiJson
+  include Options
+  extend self
+
+  class << self
+    def cached_options
+      @cached_options ||= {}
+    end
+
+    def reset_cached_options!
+      @cached_options = {}
+    end
+  end
+
+  # Since `default_options` is deprecated, the
+  # reader is aliased to `dump_options` and the
+  # writer sets both `dump_options` and `load_options`
+  alias default_options dump_options
+
+  def default_options=(value)
+    Kernel.warn "MultiJson.default_options setter is deprecated\n" +
+      "Use MultiJson.load_options and MultiJson.dump_options instead"
+
+    self.load_options = self.dump_options = value
+  end
+
+  ALIASES = { 'jrjackson' => 'jr_jackson' }
+
+  REQUIREMENT_MAP = [
+    ['oj',           :oj],
+    ['yajl',         :yajl],
+    ['jrjackson',    :jr_jackson],
+    ['json/ext',     :json_gem],
+    ['gson',         :gson],
+    ['json/pure',    :json_pure]
+  ]
+
+  # The default adapter based on what you currently
+  # have loaded and installed. First checks to see
+  # if any adapters are already loaded, then checks
+  # to see which are installed if none are loaded.
+  def default_adapter
+    return :oj if defined?(::Oj)
+    return :yajl if defined?(::Yajl)
+    return :jr_jackson if defined?(::JrJackson)
+    return :json_gem if defined?(::JSON::JSON_LOADED)
+    return :gson if defined?(::Gson)
+
+    REQUIREMENT_MAP.each do |library, adapter|
+      begin
+        require library
+        return adapter
+      rescue ::LoadError
+        next
+      end
+    end
+
+    Kernel.warn '[WARNING] MultiJson is using the default adapter (ok_json).' +
+      'We recommend loading a different JSON library to improve performance.'
+
+    :ok_json
+  end
+  alias default_engine default_adapter
+
+  # Get the current adapter class.
+  def adapter
+    return @adapter if defined?(@adapter) && @adapter
+
+    self.use nil # load default adapter
+
+    @adapter
+  end
+  alias engine adapter
+
+  # Set the JSON parser utilizing a symbol, string, or class.
+  # Supported by default are:
+  #
+  # * <tt>:oj</tt>
+  # * <tt>:json_gem</tt>
+  # * <tt>:json_pure</tt>
+  # * <tt>:ok_json</tt>
+  # * <tt>:yajl</tt>
+  # * <tt>:nsjsonserialization</tt> (MacRuby only)
+  # * <tt>:gson</tt> (JRuby only)
+  # * <tt>:jr_jackson</tt> (JRuby only)
+  def use(new_adapter)
+    @adapter = load_adapter(new_adapter)
+  end
+  alias adapter= use
+  alias engine= use
+
+  def load_adapter(new_adapter)
+    case new_adapter
+    when String, Symbol
+      load_adapter_from_string_name new_adapter.to_s
+    when NilClass, FalseClass
+      load_adapter default_adapter
+    when Class, Module
+      new_adapter
+    else
+      raise ::LoadError, new_adapter
+    end
+  rescue ::LoadError => exception
+    raise AdapterError.build(exception)
+  end
+
+  # Decode a JSON string into Ruby.
+  #
+  # <b>Options</b>
+  #
+  # <tt>:symbolize_keys</tt> :: If true, will use symbols instead of strings for the keys.
+  # <tt>:adapter</tt> :: If set, the selected adapter will be used for this call.
+  def load(string, options={})
+    adapter = current_adapter(options)
+    begin
+      adapter.load(string, options)
+    rescue adapter::ParseError => exception
+      raise ParseError.build(exception, string)
+    end
+  end
+  alias decode load
+
+  def current_adapter(options={})
+    if new_adapter = options[:adapter]
+      load_adapter(new_adapter)
+    else
+      adapter
+    end
+  end
+
+  # Encodes a Ruby object as JSON.
+  def dump(object, options={})
+    current_adapter(options).dump(object, options)
+  end
+  alias encode dump
+
+  #  Executes passed block using specified adapter.
+  def with_adapter(new_adapter)
+    old_adapter, self.adapter = adapter, new_adapter
+    yield
+  ensure
+    self.adapter = old_adapter
+  end
+  alias with_engine with_adapter
+
+  private
+
+  def load_adapter_from_string_name(name)
+    name = ALIASES.fetch(name, name)
+    require "multi_json/adapters/#{name.downcase}"
+    klass_name = name.to_s.split('_').map(&:capitalize) * ''
+    MultiJson::Adapters.const_get(klass_name)
+  end
+
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/adapter.rb b/app/server/vendor/multi_json/lib/multi_json/adapter.rb
new file mode 100644
index 0000000..35af056
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/adapter.rb
@@ -0,0 +1,57 @@
+require 'singleton'
+require 'multi_json/options'
+
+module MultiJson
+  class Adapter
+    extend Options
+    include Singleton
+    class << self
+
+      def defaults(action, value)
+        metaclass = class << self; self; end
+
+        metaclass.instance_eval do
+          define_method("default_#{action}_options"){ value }
+        end
+      end
+
+      def load(string, options={})
+        raise self::ParseError if blank?(string)
+        instance.load(string, collect_load_options(options).clone)
+      end
+
+      def dump(object, options={})
+        instance.dump(object, collect_dump_options(options).clone)
+      end
+
+    protected
+
+      def collect_load_options(options)
+        cache('load', options){ collect_options(:load_options, options).merge(options) }
+      end
+
+      def collect_dump_options(options)
+        cache('dump', options){ collect_options(:dump_options, options).merge(options) }
+      end
+
+      def collect_options(method, *args)
+        global, local = *[MultiJson, self].map{ |r| r.send(method, *args) }
+        local.merge(global)
+      end
+
+      def cache(method, options)
+        cache_key = [self, options].map(&:hash).join + method
+        MultiJson.cached_options[cache_key] ||= yield
+      end
+
+    private
+
+      def blank?(input)
+        input.nil? || /\A\s*\z/ === input
+      rescue ArgumentError # invalid byte sequence in UTF-8
+        false
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/adapter_error.rb b/app/server/vendor/multi_json/lib/multi_json/adapter_error.rb
new file mode 100644
index 0000000..86902b6
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/adapter_error.rb
@@ -0,0 +1,15 @@
+module MultiJson
+  class AdapterError < ArgumentError
+    attr_reader :cause
+
+    def self.build(original_exception)
+      message = "Did not recognize your adapter specification (#{original_exception.message})."
+      new(message).tap do |exception|
+        exception.instance_eval do
+          @cause = original_exception
+          set_backtrace original_exception.backtrace
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/adapters/gson.rb b/app/server/vendor/multi_json/lib/multi_json/adapters/gson.rb
new file mode 100644
index 0000000..8c43660
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/adapters/gson.rb
@@ -0,0 +1,20 @@
+require 'gson'
+require 'multi_json/adapter'
+
+module MultiJson
+  module Adapters
+    # Use the gson.rb library to dump/load.
+    class Gson < Adapter
+      ParseError = ::Gson::DecodeError
+
+      def load(string, options={})
+        string = string.read if StringIO === string
+        ::Gson::Decoder.new(options).decode(string)
+      end
+
+      def dump(object, options={})
+        ::Gson::Encoder.new(options).encode(object)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/adapters/jr_jackson.rb b/app/server/vendor/multi_json/lib/multi_json/adapters/jr_jackson.rb
new file mode 100644
index 0000000..ccdcc9a
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/adapters/jr_jackson.rb
@@ -0,0 +1,21 @@
+require 'jrjackson' unless defined?(::JrJackson)
+require 'multi_json/adapter'
+
+module MultiJson
+  module Adapters
+    # Use the jrjackson.rb library to dump/load.
+    class JrJackson < Adapter
+      ParseError = ::JrJackson::ParseError
+
+      def load(string, options={}) #:nodoc:
+        # https://github.com/guyboertje/jrjackson/issues/20
+        string = string.read if StringIO === string
+        ::JrJackson::Json.load(string, options)
+      end
+
+      def dump(object, options={}) #:nodoc:
+        ::JrJackson::Json.dump(object)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/adapters/json_common.rb b/app/server/vendor/multi_json/lib/multi_json/adapters/json_common.rb
new file mode 100644
index 0000000..e48cca2
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/adapters/json_common.rb
@@ -0,0 +1,25 @@
+require 'multi_json/adapter'
+
+module MultiJson
+  module Adapters
+    class JsonCommon < Adapter
+      defaults :load, :create_additions => false, :quirks_mode => true
+
+      def load(string, options={})
+        string = string.read if string.respond_to?(:read)
+
+        if string.respond_to?(:force_encoding)
+          string = string.dup.force_encoding(::Encoding::ASCII_8BIT)
+        end
+
+        options[:symbolize_names] = true if options.delete(:symbolize_keys)
+        ::JSON.parse(string, options)
+      end
+
+      def dump(object, options={})
+        options.merge!(::JSON::PRETTY_STATE_PROTOTYPE.to_h) if options.delete(:pretty)
+        object.to_json(options)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/adapters/json_gem.rb b/app/server/vendor/multi_json/lib/multi_json/adapters/json_gem.rb
new file mode 100644
index 0000000..035de37
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/adapters/json_gem.rb
@@ -0,0 +1,11 @@
+require 'json/ext'
+require 'multi_json/adapters/json_common'
+
+module MultiJson
+  module Adapters
+    # Use the JSON gem to dump/load.
+    class JsonGem < JsonCommon
+      ParseError = ::JSON::ParserError
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/adapters/json_pure.rb b/app/server/vendor/multi_json/lib/multi_json/adapters/json_pure.rb
new file mode 100644
index 0000000..c5d7036
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/adapters/json_pure.rb
@@ -0,0 +1,11 @@
+require 'json/pure'
+require 'multi_json/adapters/json_common'
+
+module MultiJson
+  module Adapters
+    # Use JSON pure to dump/load.
+    class JsonPure < JsonCommon
+      ParseError = ::JSON::ParserError
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/adapters/nsjsonserialization.rb b/app/server/vendor/multi_json/lib/multi_json/adapters/nsjsonserialization.rb
new file mode 100644
index 0000000..a50d596
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/adapters/nsjsonserialization.rb
@@ -0,0 +1,34 @@
+framework 'Foundation'
+require 'multi_json/adapters/ok_json'
+
+module MultiJson
+  module Adapters
+    class Nsjsonserialization < MultiJson::Adapters::OkJson
+      ParseError = ::MultiJson::OkJson::Error
+
+      def load(string, options={})
+        string = string.read if string.respond_to?(:read)
+        data = string.dataUsingEncoding(NSUTF8StringEncoding)
+        object = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves, error: nil)
+        if object
+          object = symbolize_keys(object) if options[:symbolize_keys]
+          object
+        else
+          super(string, options={})
+        end
+      end
+
+      def dump(object, options={})
+        pretty = options[:pretty] ? NSJSONWritingPrettyPrinted : 0
+        object = object.as_json if object.respond_to?(:as_json)
+        if NSJSONSerialization.isValidJSONObject(object)
+          data = NSJSONSerialization.dataWithJSONObject(object, options: pretty, error: nil)
+          NSMutableString.alloc.initWithData(data, encoding: NSUTF8StringEncoding)
+        else
+          super(object, options)
+        end
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/adapters/oj.rb b/app/server/vendor/multi_json/lib/multi_json/adapters/oj.rb
new file mode 100644
index 0000000..67ad652
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/adapters/oj.rb
@@ -0,0 +1,24 @@
+require 'oj'
+require 'multi_json/adapter'
+
+module MultiJson
+  module Adapters
+    # Use the Oj library to dump/load.
+    class Oj < Adapter
+      defaults :load, :mode => :strict, :symbolize_keys => false
+      defaults :dump, :mode => :compat, :time_format => :ruby, :use_to_json => true
+
+      ParseError = defined?(::Oj::ParseError) ? ::Oj::ParseError : SyntaxError
+
+      def load(string, options={})
+        options[:symbol_keys] = options.delete(:symbolize_keys)
+        ::Oj.load(string, options)
+      end
+
+      def dump(object, options={})
+        options.merge!(:indent => 2) if options[:pretty]
+        ::Oj.dump(object, options)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/adapters/ok_json.rb b/app/server/vendor/multi_json/lib/multi_json/adapters/ok_json.rb
new file mode 100644
index 0000000..1ee504b
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/adapters/ok_json.rb
@@ -0,0 +1,24 @@
+require 'multi_json/adapter'
+require 'multi_json/convertible_hash_keys'
+require 'multi_json/vendor/okjson'
+
+module MultiJson
+  module Adapters
+    class OkJson < Adapter
+      include ConvertibleHashKeys
+      ParseError = ::MultiJson::OkJson::Error
+
+      def load(string, options={})
+        string = string.read if string.respond_to?(:read)
+        result = ::MultiJson::OkJson.decode("[#{string}]").first
+        options[:symbolize_keys] ? symbolize_keys(result) : result
+      rescue ArgumentError # invalid byte sequence in UTF-8
+        raise ParseError
+      end
+
+      def dump(object, options={})
+        ::MultiJson::OkJson.valenc(stringify_keys(object))
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/adapters/yajl.rb b/app/server/vendor/multi_json/lib/multi_json/adapters/yajl.rb
new file mode 100644
index 0000000..34d5eeb
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/adapters/yajl.rb
@@ -0,0 +1,19 @@
+require 'yajl'
+require 'multi_json/adapter'
+
+module MultiJson
+  module Adapters
+    # Use the Yajl-Ruby library to dump/load.
+    class Yajl < Adapter
+      ParseError = ::Yajl::ParseError
+
+      def load(string, options={})
+        ::Yajl::Parser.new(:symbolize_keys => options[:symbolize_keys]).parse(string)
+      end
+
+      def dump(object, options={})
+        ::Yajl::Encoder.encode(object, options)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/convertible_hash_keys.rb b/app/server/vendor/multi_json/lib/multi_json/convertible_hash_keys.rb
new file mode 100644
index 0000000..71996b9
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/convertible_hash_keys.rb
@@ -0,0 +1,43 @@
+module MultiJson
+  module ConvertibleHashKeys
+    private
+
+    def symbolize_keys(hash)
+      prepare_hash(hash) do |key|
+        key.respond_to?(:to_sym) ? key.to_sym : key
+      end
+    end
+
+    def stringify_keys(hash)
+      prepare_hash(hash) do |key|
+        key.respond_to?(:to_s) ? key.to_s : key
+      end
+    end
+
+    def prepare_hash(hash, &key_modifier)
+      return hash unless block_given?
+      case hash
+      when Array
+        hash.map do |value|
+          prepare_hash(value, &key_modifier)
+        end
+      when Hash
+        hash.inject({}) do |result, (key, value)|
+          new_key   = key_modifier.call(key)
+          new_value = prepare_hash(value, &key_modifier)
+          result.merge! new_key => new_value
+        end
+      when String, Numeric, true, false, nil
+        hash
+      else
+        if hash.respond_to?(:to_json)
+          hash
+        elsif hash.respond_to?(:to_s)
+          hash.to_s
+        else
+          hash
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/options.rb b/app/server/vendor/multi_json/lib/multi_json/options.rb
new file mode 100644
index 0000000..78fefb1
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/options.rb
@@ -0,0 +1,48 @@
+module MultiJson
+  module Options
+
+    def load_options=(options)
+      MultiJson.reset_cached_options!
+      @load_options = options
+    end
+
+    def dump_options=(options)
+      MultiJson.reset_cached_options!
+      @dump_options = options
+    end
+
+    def load_options(*args)
+      get_options :load_options, *args
+    end
+
+    def dump_options(*args)
+      get_options :dump_options, *args
+    end
+
+    def default_load_options
+      @default_load_options ||= {}
+    end
+
+    def default_dump_options
+      @default_dump_options ||= {}
+    end
+
+    private
+
+    def get_options(ivar, *args)
+      defaults = send("default_#{ivar}")
+
+      return defaults unless instance_variable_defined?("@#{ivar}")
+
+      value = instance_variable_get("@#{ivar}")
+
+      if value.respond_to?(:call) and value.arity
+        value.arity == 0 ? value[] : value[*args]
+      elsif Hash === value or value.respond_to?(:to_hash)
+        value.to_hash
+      else
+        defaults
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/parse_error.rb b/app/server/vendor/multi_json/lib/multi_json/parse_error.rb
new file mode 100644
index 0000000..407a622
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/parse_error.rb
@@ -0,0 +1,17 @@
+module MultiJson
+  class ParseError < StandardError
+    attr_reader :data, :cause
+
+    def self.build(original_exception, data)
+      new(original_exception.message).tap do |exception|
+        exception.instance_eval do
+          @cause = original_exception
+          set_backtrace original_exception.backtrace
+          @data = data
+        end
+      end
+    end
+  end
+
+  DecodeError = LoadError = ParseError # Legacy support
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/vendor/okjson.rb b/app/server/vendor/multi_json/lib/multi_json/vendor/okjson.rb
new file mode 100644
index 0000000..f026071
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/vendor/okjson.rb
@@ -0,0 +1,606 @@
+# encoding: UTF-8
+#
+# Copyright 2011, 2012 Keith Rarick
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+# See https://github.com/kr/okjson for updates.
+
+require 'stringio'
+
+module MultiJson
+  # Some parts adapted from
+  # http://golang.org/src/pkg/json/decode.go and
+  # http://golang.org/src/pkg/utf8/utf8.go
+  module OkJson
+    Upstream = '43'
+    extend self
+
+
+    # Decodes a json document in string s and
+    # returns the corresponding ruby value.
+    # String s must be valid UTF-8. If you have
+    # a string in some other encoding, convert
+    # it first.
+    #
+    # String values in the resulting structure
+    # will be UTF-8.
+    def decode(s)
+      ts = lex(s)
+      v, ts = textparse(ts)
+      if ts.length > 0
+        raise Error, 'trailing garbage'
+      end
+      v
+    end
+
+
+    # Encodes x into a json text. It may contain only
+    # Array, Hash, String, Numeric, true, false, nil.
+    # (Note, this list excludes Symbol.)
+    # X itself must be an Array or a Hash.
+    # No other value can be encoded, and an error will
+    # be raised if x contains any other value, such as
+    # Nan, Infinity, Symbol, and Proc, or if a Hash key
+    # is not a String.
+    # Strings contained in x must be valid UTF-8.
+    def encode(x)
+      case x
+      when Hash    then objenc(x)
+      when Array   then arrenc(x)
+      else
+        raise Error, 'root value must be an Array or a Hash'
+      end
+    end
+
+
+    def valenc(x)
+      case x
+      when Hash    then objenc(x)
+      when Array   then arrenc(x)
+      when String  then strenc(x)
+      when Numeric then numenc(x)
+      when true    then "true"
+      when false   then "false"
+      when nil     then "null"
+      else
+        if x.respond_to?(:to_json)
+          x.to_json
+        else
+          raise Error, "cannot encode #{x.class}: #{x.inspect}"
+        end
+      end
+    end
+
+
+  private
+
+
+    # Parses a "json text" in the sense of RFC 4627.
+    # Returns the parsed value and any trailing tokens.
+    # Note: this is almost the same as valparse,
+    # except that it does not accept atomic values.
+    def textparse(ts)
+      if ts.length <= 0
+        raise Error, 'empty'
+      end
+
+      typ, _, val = ts[0]
+      case typ
+      when '{' then objparse(ts)
+      when '[' then arrparse(ts)
+      else
+        raise Error, "unexpected #{val.inspect}"
+      end
+    end
+
+
+    # Parses a "value" in the sense of RFC 4627.
+    # Returns the parsed value and any trailing tokens.
+    def valparse(ts)
+      if ts.length <= 0
+        raise Error, 'empty'
+      end
+
+      typ, _, val = ts[0]
+      case typ
+      when '{' then objparse(ts)
+      when '[' then arrparse(ts)
+      when :val,:str then [val, ts[1..-1]]
+      else
+        raise Error, "unexpected #{val.inspect}"
+      end
+    end
+
+
+    # Parses an "object" in the sense of RFC 4627.
+    # Returns the parsed value and any trailing tokens.
+    def objparse(ts)
+      ts = eat('{', ts)
+      obj = {}
+
+      if ts[0][0] == '}'
+        return obj, ts[1..-1]
+      end
+
+      k, v, ts = pairparse(ts)
+      obj[k] = v
+
+      if ts[0][0] == '}'
+        return obj, ts[1..-1]
+      end
+
+      loop do
+        ts = eat(',', ts)
+
+        k, v, ts = pairparse(ts)
+        obj[k] = v
+
+        if ts[0][0] == '}'
+          return obj, ts[1..-1]
+        end
+      end
+    end
+
+
+    # Parses a "member" in the sense of RFC 4627.
+    # Returns the parsed values and any trailing tokens.
+    def pairparse(ts)
+      (typ, _, k), ts = ts[0], ts[1..-1]
+      if typ != :str
+        raise Error, "unexpected #{k.inspect}"
+      end
+      ts = eat(':', ts)
+      v, ts = valparse(ts)
+      [k, v, ts]
+    end
+
+
+    # Parses an "array" in the sense of RFC 4627.
+    # Returns the parsed value and any trailing tokens.
+    def arrparse(ts)
+      ts = eat('[', ts)
+      arr = []
+
+      if ts[0][0] == ']'
+        return arr, ts[1..-1]
+      end
+
+      v, ts = valparse(ts)
+      arr << v
+
+      if ts[0][0] == ']'
+        return arr, ts[1..-1]
+      end
+
+      loop do
+        ts = eat(',', ts)
+
+        v, ts = valparse(ts)
+        arr << v
+
+        if ts[0][0] == ']'
+          return arr, ts[1..-1]
+        end
+      end
+    end
+
+
+    def eat(typ, ts)
+      if ts[0][0] != typ
+        raise Error, "expected #{typ} (got #{ts[0].inspect})"
+      end
+      ts[1..-1]
+    end
+
+
+    # Scans s and returns a list of json tokens,
+    # excluding white space (as defined in RFC 4627).
+    def lex(s)
+      ts = []
+      while s.length > 0
+        typ, lexeme, val = tok(s)
+        if typ == nil
+          raise Error, "invalid character at #{s[0,10].inspect}"
+        end
+        if typ != :space
+          ts << [typ, lexeme, val]
+        end
+        s = s[lexeme.length..-1]
+      end
+      ts
+    end
+
+
+    # Scans the first token in s and
+    # returns a 3-element list, or nil
+    # if s does not begin with a valid token.
+    #
+    # The first list element is one of
+    # '{', '}', ':', ',', '[', ']',
+    # :val, :str, and :space.
+    #
+    # The second element is the lexeme.
+    #
+    # The third element is the value of the
+    # token for :val and :str, otherwise
+    # it is the lexeme.
+    def tok(s)
+      case s[0]
+      when ?{ then ['{', s[0,1], s[0,1]]
+      when ?} then ['}', s[0,1], s[0,1]]
+      when ?: then [':', s[0,1], s[0,1]]
+      when ?, then [',', s[0,1], s[0,1]]
+      when ?[ then ['[', s[0,1], s[0,1]]
+      when ?] then [']', s[0,1], s[0,1]]
+      when ?n then nulltok(s)
+      when ?t then truetok(s)
+      when ?f then falsetok(s)
+      when ?" then strtok(s)
+      when Spc, ?\t, ?\n, ?\r then [:space, s[0,1], s[0,1]]
+      else
+        numtok(s)
+      end
+    end
+
+
+    def nulltok(s);  s[0,4] == 'null'  ? [:val, 'null',  nil]   : [] end
+    def truetok(s);  s[0,4] == 'true'  ? [:val, 'true',  true]  : [] end
+    def falsetok(s); s[0,5] == 'false' ? [:val, 'false', false] : [] end
+
+
+    def numtok(s)
+      m = /-?([1-9][0-9]+|[0-9])([.][0-9]+)?([eE][+-]?[0-9]+)?/.match(s)
+      if m && m.begin(0) == 0
+        if !m[2] && !m[3]
+          [:val, m[0], Integer(m[0])]
+        elsif m[2]
+          [:val, m[0], Float(m[0])]
+        else
+          [:val, m[0], Integer(m[1])*(10**Integer(m[3][1..-1]))]
+        end
+      else
+        []
+      end
+    end
+
+
+    def strtok(s)
+      m = /"([^"\\]|\\["\/\\bfnrt]|\\u[0-9a-fA-F]{4})*"/.match(s)
+      if ! m
+        raise Error, "invalid string literal at #{abbrev(s)}"
+      end
+      [:str, m[0], unquote(m[0])]
+    end
+
+
+    def abbrev(s)
+      t = s[0,10]
+      p = t['`']
+      t = t[0,p] if p
+      t = t + '...' if t.length < s.length
+      '`' + t + '`'
+    end
+
+
+    # Converts a quoted json string literal q into a UTF-8-encoded string.
+    # The rules are different than for Ruby, so we cannot use eval.
+    # Unquote will raise an error if q contains control characters.
+    def unquote(q)
+      q = q[1...-1]
+      a = q.dup # allocate a big enough string
+      # In ruby >= 1.9, a[w] is a codepoint, not a byte.
+      if rubydoesenc?
+        a.force_encoding('UTF-8')
+      end
+      r, w = 0, 0
+      while r < q.length
+        c = q[r]
+        if c == ?\\
+          r += 1
+          if r >= q.length
+            raise Error, "string literal ends with a \"\\\": \"#{q}\""
+          end
+
+          case q[r]
+          when ?",?\\,?/,?'
+            a[w] = q[r]
+            r += 1
+            w += 1
+          when ?b,?f,?n,?r,?t
+            a[w] = Unesc[q[r]]
+            r += 1
+            w += 1
+          when ?u
+            r += 1
+            uchar = begin
+              hexdec4(q[r,4])
+            rescue RuntimeError => e
+              raise Error, "invalid escape sequence \\u#{q[r,4]}: #{e}"
+            end
+            r += 4
+            if surrogate? uchar
+              if q.length >= r+6
+                uchar1 = hexdec4(q[r+2,4])
+                uchar = subst(uchar, uchar1)
+                if uchar != Ucharerr
+                  # A valid pair; consume.
+                  r += 6
+                end
+              end
+            end
+            if rubydoesenc?
+              a[w] = '' << uchar
+              w += 1
+            else
+              w += ucharenc(a, w, uchar)
+            end
+          else
+            raise Error, "invalid escape char #{q[r]} in \"#{q}\""
+          end
+        elsif c == ?" || c < Spc
+          raise Error, "invalid character in string literal \"#{q}\""
+        else
+          # Copy anything else byte-for-byte.
+          # Valid UTF-8 will remain valid UTF-8.
+          # Invalid UTF-8 will remain invalid UTF-8.
+          # In ruby >= 1.9, c is a codepoint, not a byte,
+          # in which case this is still what we want.
+          a[w] = c
+          r += 1
+          w += 1
+        end
+      end
+      a[0,w]
+    end
+
+
+    # Encodes unicode character u as UTF-8
+    # bytes in string a at position i.
+    # Returns the number of bytes written.
+    def ucharenc(a, i, u)
+      if u <= Uchar1max
+        a[i] = (u & 0xff).chr
+        1
+      elsif u <= Uchar2max
+        a[i+0] = (Utag2 | ((u>>6)&0xff)).chr
+        a[i+1] = (Utagx | (u&Umaskx)).chr
+        2
+      elsif u <= Uchar3max
+        a[i+0] = (Utag3 | ((u>>12)&0xff)).chr
+        a[i+1] = (Utagx | ((u>>6)&Umaskx)).chr
+        a[i+2] = (Utagx | (u&Umaskx)).chr
+        3
+      else
+        a[i+0] = (Utag4 | ((u>>18)&0xff)).chr
+        a[i+1] = (Utagx | ((u>>12)&Umaskx)).chr
+        a[i+2] = (Utagx | ((u>>6)&Umaskx)).chr
+        a[i+3] = (Utagx | (u&Umaskx)).chr
+        4
+      end
+    end
+
+
+    def hexdec4(s)
+      if s.length != 4
+        raise Error, 'short'
+      end
+      (nibble(s[0])<<12) | (nibble(s[1])<<8) | (nibble(s[2])<<4) | nibble(s[3])
+    end
+
+
+    def subst(u1, u2)
+      if Usurr1 <= u1 && u1 < Usurr2 && Usurr2 <= u2 && u2 < Usurr3
+        return ((u1-Usurr1)<<10) | (u2-Usurr2) + Usurrself
+      end
+      return Ucharerr
+    end
+
+
+    def surrogate?(u)
+      Usurr1 <= u && u < Usurr3
+    end
+
+
+    def nibble(c)
+      if ?0 <= c && c <= ?9 then c.ord - ?0.ord
+      elsif ?a <= c && c <= ?z then c.ord - ?a.ord + 10
+      elsif ?A <= c && c <= ?Z then c.ord - ?A.ord + 10
+      else
+        raise Error, "invalid hex code #{c}"
+      end
+    end
+
+
+    def objenc(x)
+      '{' + x.map{|k,v| keyenc(k) + ':' + valenc(v)}.join(',') + '}'
+    end
+
+
+    def arrenc(a)
+      '[' + a.map{|x| valenc(x)}.join(',') + ']'
+    end
+
+
+    def keyenc(k)
+      case k
+      when String then strenc(k)
+      else
+        raise Error, "Hash key is not a string: #{k.inspect}"
+      end
+    end
+
+
+    def strenc(s)
+      t = StringIO.new
+      t.putc(?")
+      r = 0
+
+      while r < s.length
+        case s[r]
+        when ?"  then t.print('\\"')
+        when ?\\ then t.print('\\\\')
+        when ?\b then t.print('\\b')
+        when ?\f then t.print('\\f')
+        when ?\n then t.print('\\n')
+        when ?\r then t.print('\\r')
+        when ?\t then t.print('\\t')
+        else
+          c = s[r]
+          # In ruby >= 1.9, s[r] is a codepoint, not a byte.
+          if rubydoesenc?
+            begin
+              # c.ord will raise an error if c is invalid UTF-8
+              if c.ord < Spc.ord
+                c = "\\u%04x" % [c.ord]
+              end
+              t.write(c)
+            rescue
+              t.write(Ustrerr)
+            end
+          elsif c < Spc
+            t.write("\\u%04x" % c)
+          elsif Spc <= c && c <= ?~
+            t.putc(c)
+          else
+            n = ucharcopy(t, s, r) # ensure valid UTF-8 output
+            r += n - 1 # r is incremented below
+          end
+        end
+        r += 1
+      end
+      t.putc(?")
+      t.string
+    end
+
+
+    def numenc(x)
+      if ((x.nan? || x.infinite?) rescue false)
+        raise Error, "Numeric cannot be represented: #{x}"
+      end
+      "#{x}"
+    end
+
+
+    # Copies the valid UTF-8 bytes of a single character
+    # from string s at position i to I/O object t, and
+    # returns the number of bytes copied.
+    # If no valid UTF-8 char exists at position i,
+    # ucharcopy writes Ustrerr and returns 1.
+    def ucharcopy(t, s, i)
+      n = s.length - i
+      raise Utf8Error if n < 1
+
+      c0 = s[i].ord
+
+      # 1-byte, 7-bit sequence?
+      if c0 < Utagx
+        t.putc(c0)
+        return 1
+      end
+
+      raise Utf8Error if c0 < Utag2 # unexpected continuation byte?
+
+      raise Utf8Error if n < 2 # need continuation byte
+      c1 = s[i+1].ord
+      raise Utf8Error if c1 < Utagx || Utag2 <= c1
+
+      # 2-byte, 11-bit sequence?
+      if c0 < Utag3
+        raise Utf8Error if ((c0&Umask2)<<6 | (c1&Umaskx)) <= Uchar1max
+        t.putc(c0)
+        t.putc(c1)
+        return 2
+      end
+
+      # need second continuation byte
+      raise Utf8Error if n < 3
+
+      c2 = s[i+2].ord
+      raise Utf8Error if c2 < Utagx || Utag2 <= c2
+
+      # 3-byte, 16-bit sequence?
+      if c0 < Utag4
+        u = (c0&Umask3)<<12 | (c1&Umaskx)<<6 | (c2&Umaskx)
+        raise Utf8Error if u <= Uchar2max
+        t.putc(c0)
+        t.putc(c1)
+        t.putc(c2)
+        return 3
+      end
+
+      # need third continuation byte
+      raise Utf8Error if n < 4
+      c3 = s[i+3].ord
+      raise Utf8Error if c3 < Utagx || Utag2 <= c3
+
+      # 4-byte, 21-bit sequence?
+      if c0 < Utag5
+        u = (c0&Umask4)<<18 | (c1&Umaskx)<<12 | (c2&Umaskx)<<6 | (c3&Umaskx)
+        raise Utf8Error if u <= Uchar3max
+        t.putc(c0)
+        t.putc(c1)
+        t.putc(c2)
+        t.putc(c3)
+        return 4
+      end
+
+      raise Utf8Error
+    rescue Utf8Error
+      t.write(Ustrerr)
+      return 1
+    end
+
+
+    def rubydoesenc?
+      ::String.method_defined?(:force_encoding)
+    end
+
+
+    class Utf8Error < ::StandardError
+    end
+
+
+    class Error < ::StandardError
+    end
+
+
+    Utagx = 0b1000_0000
+    Utag2 = 0b1100_0000
+    Utag3 = 0b1110_0000
+    Utag4 = 0b1111_0000
+    Utag5 = 0b1111_1000
+    Umaskx = 0b0011_1111
+    Umask2 = 0b0001_1111
+    Umask3 = 0b0000_1111
+    Umask4 = 0b0000_0111
+    Uchar1max = (1<<7) - 1
+    Uchar2max = (1<<11) - 1
+    Uchar3max = (1<<16) - 1
+    Ucharerr = 0xFFFD # unicode "replacement char"
+    Ustrerr = "\xef\xbf\xbd" # unicode "replacement char"
+    Usurrself = 0x10000
+    Usurr1 = 0xd800
+    Usurr2 = 0xdc00
+    Usurr3 = 0xe000
+
+    Spc = ' '[0]
+    Unesc = {?b=>?\b, ?f=>?\f, ?n=>?\n, ?r=>?\r, ?t=>?\t}
+  end
+end
diff --git a/app/server/vendor/multi_json/lib/multi_json/version.rb b/app/server/vendor/multi_json/lib/multi_json/version.rb
new file mode 100644
index 0000000..8aa5b8d
--- /dev/null
+++ b/app/server/vendor/multi_json/lib/multi_json/version.rb
@@ -0,0 +1,20 @@
+module MultiJson
+  class Version
+    MAJOR = 1 unless defined? MultiJson::Version::MAJOR
+    MINOR = 9 unless defined? MultiJson::Version::MINOR
+    PATCH = 2 unless defined? MultiJson::Version::PATCH
+    PRE = nil unless defined? MultiJson::Version::PRE
+
+    class << self
+
+      # @return [String]
+      def to_s
+        [MAJOR, MINOR, PATCH, PRE].compact.join('.')
+      end
+
+    end
+
+  end
+
+  VERSION = Version.to_s.freeze
+end
diff --git a/app/server/vendor/multi_json/multi_json.gemspec b/app/server/vendor/multi_json/multi_json.gemspec
new file mode 100644
index 0000000..cf16e89
--- /dev/null
+++ b/app/server/vendor/multi_json/multi_json.gemspec
@@ -0,0 +1,22 @@
+# coding: utf-8
+lib = File.expand_path('../lib', __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+require 'multi_json/version'
+
+Gem::Specification.new do |spec|
+  spec.add_development_dependency 'bundler', '~> 1.0'
+  spec.authors       = ["Michael Bleigh", "Josh Kalderimis", "Erik Michaels-Ober", "Pavel Pravosud"]
+  spec.cert_chain    = %w(certs/rwz.pem)
+  spec.description   = %q{A common interface to multiple JSON libraries, including Oj, Yajl, the JSON gem (with C-extensions), the pure-Ruby JSON gem, NSJSONSerialization, gson.rb, JrJackson, and OkJson.}
+  spec.email         = ['michael at intridea.com', 'josh.kalderimis at gmail.com', 'sferik at gmail.com']
+  spec.files         = Dir['.yardopts', 'CHANGELOG.md', 'CONTRIBUTING.md', 'LICENSE.md', 'README.md', 'Rakefile', 'multi_json.gemspec', 'Gemfile', '.document', '.rspec', '.travis.yml' ,'spec/**/*', 'lib/**/*']
+  spec.homepage      = 'http://github.com/intridea/multi_json'
+  spec.licenses      = ['MIT']
+  spec.name          = 'multi_json'
+  spec.require_paths = ['lib']
+  spec.required_rubygems_version = '>= 1.3.5'
+  spec.signing_key   = File.expand_path("~/.gem/private_key.pem") if $0 =~ /gem\z/
+  spec.summary       = %q{A common interface to multiple JSON libraries.}
+  spec.test_files    = Dir['spec/**/*']
+  spec.version       = MultiJson::Version
+end
diff --git a/app/server/vendor/multi_json/spec/gson_adapter_spec.rb b/app/server/vendor/multi_json/spec/gson_adapter_spec.rb
new file mode 100644
index 0000000..71575ec
--- /dev/null
+++ b/app/server/vendor/multi_json/spec/gson_adapter_spec.rb
@@ -0,0 +1,10 @@
+require 'spec_helper'
+
+exit true unless jruby?
+
+require 'shared/adapter'
+require 'multi_json/adapters/gson'
+
+describe MultiJson::Adapters::Gson do
+  it_behaves_like 'an adapter', described_class
+end
\ No newline at end of file
diff --git a/app/server/vendor/multi_json/spec/jr_jackson_adapter_spec.rb b/app/server/vendor/multi_json/spec/jr_jackson_adapter_spec.rb
new file mode 100644
index 0000000..0b80e61
--- /dev/null
+++ b/app/server/vendor/multi_json/spec/jr_jackson_adapter_spec.rb
@@ -0,0 +1,10 @@
+require 'spec_helper'
+
+exit true unless jruby?
+
+require 'shared/adapter'
+require 'multi_json/adapters/jr_jackson'
+
+describe MultiJson::Adapters::JrJackson do
+  it_behaves_like 'an adapter', described_class
+end
\ No newline at end of file
diff --git a/app/server/vendor/multi_json/spec/json_gem_adapter_spec.rb b/app/server/vendor/multi_json/spec/json_gem_adapter_spec.rb
new file mode 100644
index 0000000..2c9f35d
--- /dev/null
+++ b/app/server/vendor/multi_json/spec/json_gem_adapter_spec.rb
@@ -0,0 +1,9 @@
+require 'spec_helper'
+require 'shared/adapter'
+require 'shared/json_common_adapter'
+require 'multi_json/adapters/json_gem'
+
+describe MultiJson::Adapters::JsonGem do
+  it_behaves_like 'an adapter', described_class
+  it_behaves_like 'JSON-like adapter', described_class
+end
\ No newline at end of file
diff --git a/app/server/vendor/multi_json/spec/json_pure_adapter_spec.rb b/app/server/vendor/multi_json/spec/json_pure_adapter_spec.rb
new file mode 100644
index 0000000..e1fc625
--- /dev/null
+++ b/app/server/vendor/multi_json/spec/json_pure_adapter_spec.rb
@@ -0,0 +1,9 @@
+require 'spec_helper'
+require 'shared/adapter'
+require 'shared/json_common_adapter'
+require 'multi_json/adapters/json_pure'
+
+describe MultiJson::Adapters::JsonPure do
+  it_behaves_like 'an adapter', described_class
+  it_behaves_like 'JSON-like adapter', described_class
+end
\ No newline at end of file
diff --git a/app/server/vendor/multi_json/spec/multi_json_spec.rb b/app/server/vendor/multi_json/spec/multi_json_spec.rb
new file mode 100644
index 0000000..22ac5c6
--- /dev/null
+++ b/app/server/vendor/multi_json/spec/multi_json_spec.rb
@@ -0,0 +1,200 @@
+require 'spec_helper'
+require 'shared/options'
+
+describe MultiJson do
+  before(:all) do
+    # make sure all available libs are required
+    MultiJson::REQUIREMENT_MAP.each do |library, adapter|
+      begin
+        require library
+      rescue ::LoadError
+        next
+      end
+    end
+  end
+
+  context 'when no other json implementations are available' do
+    around do |example|
+      simulate_no_adapters{ example.call }
+    end
+
+    it 'defaults to ok_json if no other json implementions are available' do
+      silence_warnings do
+        expect(MultiJson.default_adapter).to eq(:ok_json)
+      end
+    end
+
+    it 'prints a warning' do
+      expect(Kernel).to receive(:warn).with(/warning/i)
+      MultiJson.default_adapter
+    end
+  end
+
+  context 'caching' do
+    before{ MultiJson.use adapter }
+    let(:adapter){ MultiJson::Adapters::JsonGem }
+    let(:json_string){ '{"abc":"def"}' }
+
+    it 'busts caches on global options change' do
+      MultiJson.load_options = { :symbolize_keys => true }
+      expect(MultiJson.load(json_string)).to eq(:abc => 'def')
+      MultiJson.load_options = nil
+      expect(MultiJson.load(json_string)).to eq('abc' => 'def')
+    end
+
+    it 'busts caches on per-adapter options change' do
+      adapter.load_options = { :symbolize_keys => true }
+      expect(MultiJson.load(json_string)).to eq(:abc => 'def')
+      adapter.load_options = nil
+      expect(MultiJson.load(json_string)).to eq('abc' => 'def')
+    end
+  end
+
+  it 'defaults to the best available gem' do
+    # Clear cache variable already set by previous tests
+    MultiJson.send(:remove_instance_variable, :@adapter) if MultiJson.instance_variable_defined?(:@adapter)
+
+    if jruby?
+      expect(MultiJson.adapter.to_s).to eq('MultiJson::Adapters::JrJackson')
+    else
+      expect(MultiJson.adapter.to_s).to eq('MultiJson::Adapters::Oj')
+    end
+  end
+
+  it 'looks for adapter even if @adapter variable is nil' do
+    MultiJson.send(:instance_variable_set, :@adapter, nil)
+    expect(MultiJson).to receive(:default_adapter).and_return(:ok_json)
+    expect(MultiJson.adapter).to eq(MultiJson::Adapters::OkJson)
+  end
+
+  it 'is settable via a symbol' do
+    MultiJson.use :json_gem
+    expect(MultiJson.adapter).to eq(MultiJson::Adapters::JsonGem)
+  end
+
+  it 'is settable via a case-insensitive string' do
+    MultiJson.use 'Json_Gem'
+    expect(MultiJson.adapter).to eq(MultiJson::Adapters::JsonGem)
+  end
+
+  it 'is settable via a class' do
+    adapter = Class.new
+    MultiJson.use adapter
+    expect(MultiJson.adapter).to eq(adapter)
+  end
+
+  it 'is settable via a module' do
+    adapter = Module.new
+    MultiJson.use adapter
+    expect(MultiJson.adapter).to eq(adapter)
+  end
+
+  it 'throws AdapterError on bad input' do
+    expect{ MultiJson.use 'bad adapter' }.to raise_error(MultiJson::AdapterError, /bad adapter/)
+  end
+
+  it 'gives access to original error when raising AdapterError' do
+    exception = get_exception(MultiJson::AdapterError){ MultiJson.use 'foobar' }
+    expect(exception.cause).to be_instance_of(::LoadError)
+    expect(exception.message).to include("-- multi_json/adapters/foobar")
+    expect(exception.message).to include("Did not recognize your adapter specification")
+  end
+
+  context 'using one-shot parser' do
+    before do
+      expect(MultiJson::Adapters::JsonPure).to receive(:dump).once.and_return('dump_something')
+      expect(MultiJson::Adapters::JsonPure).to receive(:load).once.and_return('load_something')
+    end
+
+    it 'should use the defined parser just for the call' do
+      MultiJson.use :json_gem
+      expect(MultiJson.dump('', :adapter => :json_pure)).to eq('dump_something')
+      expect(MultiJson.load('', :adapter => :json_pure)).to eq('load_something')
+      expect(MultiJson.adapter).to eq(MultiJson::Adapters::JsonGem)
+    end
+  end
+
+  it 'can set adapter for a block' do
+    MultiJson.use :ok_json
+    MultiJson.with_adapter(:json_pure) do
+      MultiJson.with_engine(:json_gem) do
+        expect(MultiJson.adapter).to eq(MultiJson::Adapters::JsonGem)
+      end
+      expect(MultiJson.adapter).to eq(MultiJson::Adapters::JsonPure)
+    end
+    expect(MultiJson.adapter).to eq(MultiJson::Adapters::OkJson)
+  end
+
+  it 'JSON gem does not create symbols on parse' do
+    MultiJson.with_engine(:json_gem) do
+      MultiJson.load('{"json_class":"ZOMG"}') rescue nil
+
+      expect{
+        MultiJson.load('{"json_class":"OMG"}') rescue nil
+      }.to_not change{Symbol.all_symbols.count}
+    end
+  end
+
+  unless jruby?
+    it 'Oj does not create symbols on parse' do
+      MultiJson.with_engine(:oj) do
+        MultiJson.load('{"json_class":"ZOMG"}') rescue nil
+
+        expect{
+          MultiJson.load('{"json_class":"OMG"}') rescue nil
+        }.to_not change{Symbol.all_symbols.count}
+      end
+    end
+
+    context 'with Oj.default_settings' do
+      around do |example|
+        options = Oj.default_options
+        Oj.default_options = { :symbol_keys => true }
+        MultiJson.with_engine(:oj){ example.call }
+        Oj.default_options = options
+      end
+
+      it 'ignores global settings' do
+        MultiJson.with_engine(:oj) do
+          example = '{"a": 1, "b": 2}'
+          expected = { 'a' => 1, 'b' => 2 }
+          expect(MultiJson.load(example)).to eq(expected)
+        end
+      end
+    end
+  end
+
+  describe 'default options' do
+    after(:all){ MultiJson.load_options = MultiJson.dump_options = nil }
+
+    it 'is deprecated' do
+      expect(Kernel).to receive(:warn).with(/deprecated/i)
+      silence_warnings{ MultiJson.default_options = {:foo => 'bar'} }
+    end
+
+    it 'sets both load and dump options' do
+      expect(MultiJson).to receive(:dump_options=).with(:foo => 'bar')
+      expect(MultiJson).to receive(:load_options=).with(:foo => 'bar')
+      silence_warnings{ MultiJson.default_options = {:foo => 'bar'} }
+    end
+  end
+
+  it_behaves_like 'has options', MultiJson
+
+  describe 'aliases' do
+    if jruby?
+      describe 'jrjackson' do
+        after{ expect(MultiJson.adapter).to eq(MultiJson::Adapters::JrJackson) }
+
+        it 'allows jrjackson alias as symbol' do
+          expect{ MultiJson.use :jrjackson }.not_to raise_error
+        end
+
+        it 'allows jrjackson alias as string' do
+          expect{ MultiJson.use 'jrjackson' }.not_to raise_error
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/spec/nsjsonserialization_adapter_spec.rb b/app/server/vendor/multi_json/spec/nsjsonserialization_adapter_spec.rb
new file mode 100644
index 0000000..302ecc6
--- /dev/null
+++ b/app/server/vendor/multi_json/spec/nsjsonserialization_adapter_spec.rb
@@ -0,0 +1,10 @@
+require 'spec_helper'
+
+exit true unless macruby?
+
+require 'shared/adapter'
+require 'multi_json/adapters/nsjsonserialization'
+
+describe MultiJson::Adapters::Nsjsonserialization do
+  it_behaves_like 'an adapter', described_class
+end
\ No newline at end of file
diff --git a/app/server/vendor/multi_json/spec/oj_adapter_spec.rb b/app/server/vendor/multi_json/spec/oj_adapter_spec.rb
new file mode 100644
index 0000000..a0d6b19
--- /dev/null
+++ b/app/server/vendor/multi_json/spec/oj_adapter_spec.rb
@@ -0,0 +1,10 @@
+require 'spec_helper'
+
+exit true if jruby?
+
+require 'shared/adapter'
+require 'multi_json/adapters/oj'
+
+describe MultiJson::Adapters::Oj do
+  it_behaves_like 'an adapter', described_class
+end
\ No newline at end of file
diff --git a/app/server/vendor/multi_json/spec/ok_json_adapter_spec.rb b/app/server/vendor/multi_json/spec/ok_json_adapter_spec.rb
new file mode 100644
index 0000000..7bfdf11
--- /dev/null
+++ b/app/server/vendor/multi_json/spec/ok_json_adapter_spec.rb
@@ -0,0 +1,7 @@
+require 'spec_helper'
+require 'shared/adapter'
+require 'multi_json/adapters/ok_json'
+
+describe MultiJson::Adapters::OkJson do
+  it_behaves_like 'an adapter', described_class
+end
\ No newline at end of file
diff --git a/app/server/vendor/multi_json/spec/shared/adapter.rb b/app/server/vendor/multi_json/spec/shared/adapter.rb
new file mode 100644
index 0000000..86bca42
--- /dev/null
+++ b/app/server/vendor/multi_json/spec/shared/adapter.rb
@@ -0,0 +1,236 @@
+# encoding: UTF-8
+
+require 'shared/options'
+
+shared_examples_for 'an adapter' do |adapter|
+
+  before{ MultiJson.use adapter }
+
+  it_behaves_like 'has options', adapter
+
+  it 'does not modify argument hashes' do
+    options = { :symbolize_keys => true, :pretty => false, :adapter => :ok_json }
+    expect{MultiJson.load('{}', options)}.to_not change{options}
+    expect{MultiJson.dump([42], options)}.to_not change{options}
+  end
+
+  describe '.dump' do
+    describe '#dump_options' do
+      before{ MultiJson.dump_options = MultiJson.adapter.dump_options = {} }
+
+      after do
+        expect(MultiJson.adapter.instance).to receive(:dump).with(1, :foo => 'bar', :fizz => 'buzz')
+        MultiJson.dump(1, :fizz => 'buzz')
+        MultiJson.dump_options = MultiJson.adapter.dump_options = nil
+      end
+
+      it 'respects global dump options' do
+        MultiJson.dump_options = {:foo => 'bar'}
+      end
+
+      it 'respects per-adapter dump options' do
+        MultiJson.adapter.dump_options = {:foo => 'bar'}
+      end
+
+      it 'adapter-specific are overridden by global options' do
+        MultiJson.adapter.dump_options = {:foo => 'foo'}
+        MultiJson.dump_options = {:foo => 'bar'}
+      end
+    end
+
+    it 'writes decodable JSON' do
+      [
+        {'abc' => 'def'},
+        [1, 2, 3, '4', true, false, nil]
+      ].each do |example|
+        expect(MultiJson.load(MultiJson.dump(example))).to eq(example)
+      end
+    end
+
+    unless 'json_pure' == adapter || 'json_gem' == adapter
+      it 'dumps time in correct format' do
+        time = Time.at(1355218745).utc
+
+        dumped_json = MultiJson.dump(time)
+        expected = if RUBY_VERSION > '1.9'
+          '2012-12-11 09:39:05 UTC'
+        else
+          'Tue Dec 11 09:39:05 UTC 2012'
+        end
+        expect(MultiJson.load(dumped_json)).to eq(expected)
+      end
+    end
+
+    it 'dumps symbol and fixnum keys as strings' do
+      [
+        [
+          {:foo => {:bar => 'baz'}},
+          {'foo' => {'bar' => 'baz'}},
+        ],
+        [
+          [{:foo => {:bar => 'baz'}}],
+          [{'foo' => {'bar' => 'baz'}}],
+        ],
+        [
+          {:foo => [{:bar => 'baz'}]},
+          {'foo' => [{'bar' => 'baz'}]},
+        ],
+        [
+          {1 => {2 => {3 => 'bar'}}},
+          {'1' => {'2' => {'3' => 'bar'}}}
+        ]
+      ].each do |example, expected|
+        dumped_json = MultiJson.dump(example)
+        expect(MultiJson.load(dumped_json)).to eq(expected)
+      end
+    end
+
+    it 'dumps rootless JSON' do
+      expect(MultiJson.dump('random rootless string')).to eq('"random rootless string"')
+      expect(MultiJson.dump(123)).to eq('123')
+    end
+
+    it 'passes options to the adapter' do
+      expect(MultiJson.adapter).to receive(:dump).with('foo', {:bar => :baz})
+      MultiJson.dump('foo', :bar => :baz)
+    end
+
+    it 'dumps custom objects that implement to_json' do
+      pending 'not supported' if adapter.name == 'MultiJson::Adapters::Gson'
+      klass = Class.new do
+        def to_json(*)
+          '"foobar"'
+        end
+      end
+      expect(MultiJson.dump(klass.new)).to eq('"foobar"')
+    end
+
+    it 'allows to dump JSON values' do
+      expect(MultiJson.dump(42)).to eq('42')
+    end
+
+    it 'allows to dump JSON with UTF-8 characters' do
+      expect(MultiJson.dump('color' => 'żółć')).to eq('{"color":"żółć"}')
+    end
+  end
+
+  describe '.load' do
+    describe '#load_options' do
+      before{ MultiJson.load_options = MultiJson.adapter.load_options = {} }
+
+      after do
+        expect(MultiJson.adapter.instance).to receive(:load).with('1', :foo => 'bar', :fizz => 'buzz')
+        MultiJson.load('1', :fizz => 'buzz')
+        MultiJson.load_options = MultiJson.adapter.load_options = nil
+      end
+
+      it 'respects global load options' do
+        MultiJson.load_options = {:foo => 'bar'}
+      end
+
+      it 'respects per-adapter load options' do
+        MultiJson.adapter.load_options = {:foo => 'bar'}
+      end
+
+      it 'adapter-specific are overridden by global options' do
+        MultiJson.adapter.load_options = {:foo => 'foo'}
+        MultiJson.load_options = {:foo => 'bar'}
+      end
+    end
+
+    it 'does not modify input' do
+      input = %Q{\n\n  {"foo":"bar"} \n\n\t}
+      expect{
+        MultiJson.load(input)
+      }.to_not change{ input }
+    end
+
+    # Ruby 1.8 doesn't support String encodings
+    if RUBY_VERSION > '1.9'
+      it 'does not modify input encoding' do
+
+        input = '[123]'
+        input.force_encoding('iso-8859-1')
+
+        expect{
+          MultiJson.load(input)
+        }.to_not change{ input.encoding }
+      end
+    end
+
+    it 'properly loads valid JSON' do
+      expect(MultiJson.load('{"abc":"def"}')).to eq('abc' => 'def')
+    end
+
+    it 'raises MultiJson::ParseError on blank input or invalid input' do
+      [nil, '{"abc"}', ' ', "\t\t\t", "\n", "\x82\xAC\xEF"].each do |input|
+        if input == "\x82\xAC\xEF"
+          pending 'GSON bug: https://github.com/avsej/gson.rb/issues/3' if adapter.name =~ /Gson/
+          pending 'JrJackson bug: https://github.com/guyboertje/jrjackson/issues/21' if adapter.name =~ /JrJackson/
+        end
+
+        expect{MultiJson.load(input)}.to raise_error(MultiJson::ParseError)
+      end
+    end
+
+    it 'raises MultiJson::ParseError with data on invalid JSON' do
+      data = '{invalid}'
+      exception = get_exception(MultiJson::ParseError){ MultiJson.load data }
+      expect(exception.data).to eq(data)
+      expect(exception.cause).to be_kind_of(MultiJson.adapter::ParseError)
+    end
+
+    it 'catches MultiJson::DecodeError for legacy support' do
+      data = '{invalid}'
+      exception = get_exception(MultiJson::DecodeError){ MultiJson.load data }
+      expect(exception.data).to eq(data)
+      expect(exception.cause).to be_kind_of(MultiJson.adapter::ParseError)
+    end
+
+    it 'catches MultiJson::LoadError for legacy support' do
+      data = '{invalid}'
+      exception = get_exception(MultiJson::LoadError){ MultiJson.load data }
+      expect(exception.data).to eq(data)
+      expect(exception.cause).to be_kind_of(MultiJson.adapter::ParseError)
+    end
+
+
+    it 'stringifys symbol keys when encoding' do
+      dumped_json = MultiJson.dump(:a => 1, :b => {:c => 2})
+      loaded_json = MultiJson.load(dumped_json)
+      expect(loaded_json).to eq('a' => 1, 'b' => {'c' => 2})
+    end
+
+    it 'properly loads valid JSON in StringIOs' do
+      json = StringIO.new('{"abc":"def"}')
+      expect(MultiJson.load(json)).to eq('abc' => 'def')
+    end
+
+    it 'allows for symbolization of keys' do
+      [
+        [
+          '{"abc":{"def":"hgi"}}',
+          {:abc => {:def => 'hgi'}},
+        ],
+        [
+          '[{"abc":{"def":"hgi"}}]',
+          [{:abc => {:def => 'hgi'}}],
+        ],
+        [
+          '{"abc":[{"def":"hgi"}]}',
+          {:abc => [{:def => 'hgi'}]},
+        ]
+      ].each do |example, expected|
+        expect(MultiJson.load(example, :symbolize_keys => true)).to eq(expected)
+      end
+    end
+
+    it 'allows to load JSON values' do
+      expect(MultiJson.load('42')).to eq(42)
+    end
+
+    it 'allows to load JSON with UTF-8 characters' do
+      expect(MultiJson.load('{"color":"żółć"}')).to eq('color' => 'żółć')
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/spec/shared/json_common_adapter.rb b/app/server/vendor/multi_json/spec/shared/json_common_adapter.rb
new file mode 100644
index 0000000..0003581
--- /dev/null
+++ b/app/server/vendor/multi_json/spec/shared/json_common_adapter.rb
@@ -0,0 +1,30 @@
+shared_examples_for 'JSON-like adapter' do |adapter|
+  before{ MultiJson.use adapter }
+
+  describe '.dump' do
+    before{ MultiJson.dump_options = MultiJson.adapter.dump_options = nil }
+
+    describe 'with :pretty option set to true' do
+      it 'passes default pretty options' do
+        object = 'foo'
+        expect(object).to receive(:to_json).with(JSON::PRETTY_STATE_PROTOTYPE.to_h)
+        MultiJson.dump(object, :pretty => true)
+      end
+    end
+
+    describe 'with :indent option' do
+      it 'passes it on dump' do
+        object = 'foo'
+        expect(object).to receive(:to_json).with(:indent => "\t")
+        MultiJson.dump(object, :indent => "\t")
+      end
+    end
+  end
+
+  describe '.load' do
+    it 'passes :quirks_mode option' do
+      expect(::JSON).to receive(:parse).with('[123]', {:quirks_mode => false, :create_additions => false})
+      MultiJson.load('[123]', :quirks_mode => false)
+    end
+  end
+end
diff --git a/app/server/vendor/multi_json/spec/shared/options.rb b/app/server/vendor/multi_json/spec/shared/options.rb
new file mode 100644
index 0000000..fa55b3d
--- /dev/null
+++ b/app/server/vendor/multi_json/spec/shared/options.rb
@@ -0,0 +1,119 @@
+shared_examples_for 'has options' do |object|
+
+  if object.respond_to?(:call)
+    subject{ object.call }
+  else
+    subject{ object }
+  end
+
+  describe "dump options" do
+
+    before do
+      subject.dump_options = nil
+    end
+
+    after do
+      subject.dump_options = nil
+    end
+
+    it 'returns default options if not set' do
+      expect(subject.dump_options).to eq(subject.default_dump_options)
+    end
+
+    it 'allows hashes' do
+      subject.dump_options = {:foo => 'bar'}
+      expect(subject.dump_options).to eq(:foo => 'bar')
+    end
+
+    it 'allows objects that implement #to_hash' do
+      value = Class.new do
+        def to_hash
+          {:foo => 'bar'}
+        end
+      end.new
+
+      subject.dump_options = value
+      expect(subject.dump_options).to eq(:foo => 'bar')
+    end
+
+    it 'evaluates lambda returning options (with args)' do
+      subject.dump_options = lambda{ |a1, a2| { a1 => a2 }}
+      expect(subject.dump_options('1', '2')).to eq('1' => '2')
+    end
+
+    it 'evaluates lambda returning options (with no args)' do
+      subject.dump_options = lambda{{:foo => 'bar'}}
+      expect(subject.dump_options).to eq(:foo => 'bar')
+    end
+
+    it 'returns empty hash in all other cases' do
+      subject.dump_options = true
+      expect(subject.dump_options).to eq(subject.default_dump_options)
+
+      subject.dump_options = false
+      expect(subject.dump_options).to eq(subject.default_dump_options)
+
+      subject.dump_options = 10
+      expect(subject.dump_options).to eq(subject.default_dump_options)
+
+      subject.dump_options = nil
+      expect(subject.dump_options).to eq(subject.default_dump_options)
+    end
+  end
+
+  describe "load options" do
+
+    before do
+      subject.load_options = nil
+    end
+
+    after do
+      subject.load_options = nil
+    end
+
+    it 'returns default options if not set' do
+      expect(subject.load_options).to eq(subject.default_load_options)
+    end
+
+    it 'allows hashes' do
+      subject.load_options = {:foo => 'bar'}
+      expect(subject.load_options).to eq(:foo => 'bar')
+    end
+
+    it 'allows objects that implement #to_hash' do
+      value = Class.new do
+        def to_hash
+          {:foo => 'bar'}
+        end
+      end.new
+
+      subject.load_options = value
+      expect(subject.load_options).to eq(:foo => 'bar')
+    end
+
+    it 'evaluates lambda returning options (with args)' do
+      subject.load_options = lambda{ |a1, a2| { a1 => a2 }}
+      expect(subject.load_options('1', '2')).to eq('1' => '2')
+    end
+
+    it 'evaluates lambda returning options (with no args)' do
+      subject.load_options = lambda{{:foo => 'bar'}}
+      expect(subject.load_options).to eq(:foo => 'bar')
+    end
+
+    it 'returns empty hash in all other cases' do
+      subject.load_options = true
+      expect(subject.load_options).to eq(subject.default_load_options)
+
+      subject.load_options = false
+      expect(subject.load_options).to eq(subject.default_load_options)
+
+      subject.load_options = 10
+      expect(subject.load_options).to eq(subject.default_load_options)
+
+      subject.load_options = nil
+      expect(subject.load_options).to eq(subject.default_load_options)
+    end
+  end
+
+end
diff --git a/app/server/vendor/multi_json/spec/spec_helper.rb b/app/server/vendor/multi_json/spec/spec_helper.rb
new file mode 100644
index 0000000..23b77d9
--- /dev/null
+++ b/app/server/vendor/multi_json/spec/spec_helper.rb
@@ -0,0 +1,81 @@
+require 'simplecov'
+# require 'coveralls'
+
+# SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
+#   SimpleCov::Formatter::HTMLFormatter,
+#   Coveralls::SimpleCov::Formatter
+# ]
+# SimpleCov.start do
+#   add_filter 'spec'
+#   add_filter 'vendor'
+# end
+
+require 'multi_json'
+require 'rspec'
+
+RSpec.configure do |config|
+  config.expect_with :rspec do |c|
+    c.syntax = :expect
+  end
+end
+
+def silence_warnings
+  old_verbose, $VERBOSE = $VERBOSE, nil
+  yield
+ensure
+  $VERBOSE = old_verbose
+end
+
+def macruby?
+  defined?(RUBY_ENGINE) && RUBY_ENGINE == 'macruby'
+end
+
+def jruby?
+  defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
+end
+
+def undefine_constants(*consts)
+  values = {}
+  consts.each do |const|
+    if Object.const_defined?(const)
+      values[const] = Object.const_get(const)
+      Object.send :remove_const, const
+    end
+  end
+
+  yield
+
+ensure
+  values.each do |const, value|
+    Object.const_set const, value
+  end
+end
+
+def break_requirements
+  requirements = MultiJson::REQUIREMENT_MAP
+  MultiJson::REQUIREMENT_MAP.each_with_index do |(library, adapter), index|
+    MultiJson::REQUIREMENT_MAP[index] = ["foo/#{library}", adapter]
+  end
+
+  yield
+ensure
+  requirements.each_with_index do |(library, adapter), index|
+    MultiJson::REQUIREMENT_MAP[index] = [library, adapter]
+  end
+end
+
+def simulate_no_adapters
+  break_requirements do
+    undefine_constants :JSON, :Oj, :Yajl, :Gson, :JrJackson do
+      yield
+    end
+  end
+end
+
+def get_exception(exception_class = StandardError)
+  begin
+    yield
+  rescue exception_class => exception
+    exception
+  end
+end
diff --git a/app/server/vendor/multi_json/spec/yajl_adapter_spec.rb b/app/server/vendor/multi_json/spec/yajl_adapter_spec.rb
new file mode 100644
index 0000000..224ec4b
--- /dev/null
+++ b/app/server/vendor/multi_json/spec/yajl_adapter_spec.rb
@@ -0,0 +1,10 @@
+require 'spec_helper'
+
+exit true if jruby?
+
+require 'shared/adapter'
+require 'multi_json/adapters/yajl'
+
+describe MultiJson::Adapters::Yajl do
+  it_behaves_like 'an adapter', described_class
+end
\ No newline at end of file
diff --git a/app/server/vendor/narray-0.6.1.1/.gitignore b/app/server/vendor/narray-0.6.1.1/.gitignore
new file mode 100755
index 0000000..77812d5
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/.gitignore
@@ -0,0 +1,18 @@
+.config
+*~
+*/*~
+*/*/*~
+
+Makefile
+narray_config.h
+*.o
+narray.so
+mkmf.log
+na_math.c
+na_op.c
+
+pkg/
+src
+doc
+
+narray-*.gem
diff --git a/app/server/vendor/narray-0.6.1.1/ChangeLog b/app/server/vendor/narray-0.6.1.1/ChangeLog
new file mode 100755
index 0000000..067decd
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/ChangeLog
@@ -0,0 +1,809 @@
+2013-03-16  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* narray.c (Init_narray): add map, map!
+	Thanks to Michael Macias.
+
+2013-02-27  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* Rakefile: use rubygems/package_task.
+	* narray.gemspec: add --exclude in rdoc_options.
+	* ver 0.6.0.8
+
+2013-02-26  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* test/ld.rb: add require "rubygems".
+	* narray.gemspec: change gem directory from src to ext.
+	* narray.c: avoid warnings in require "complex" and rdoc parsing.
+
+2013-02-13  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* lib/narray_ext.rb: new method: NArray.cast
+
+2013-02-01  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* lib/narray_ext.rb: eql? hash methods implemented.
+	* ver 0.6.0.7
+
+2013-01-31  Masahiro TANAKA <masa16.tanaka at gmail.com>
+
+	* na_raondom.c: unuse u_int16_t
+	* mknafunc.rb, mkmath.rb, mkop.rb, na_linalg.c:
+	  bug: duplicated definition of asinh/acosh/atanh,
+	  typecast warning (mingw/mswin)
+	* ver 0.6.0.6
+
+2013-01-30  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* narray.c (na_check_class_narray):
+	  use Module#<= instead of rb_mod_ancestors
+	* na_random.c, na_linalg.c:
+	  avoid warnings of signed <=> unsigned comparison
+	* ver 0.6.0.5
+
+2012-12-07 geoffyoungs
+
+	* narray.c (na_check_class_narray):
+	  Use ruby methods to check class ancestors,
+	  instead of m_tbl directly
+	* ver 0.6.0.2
+
+2012-09-20  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* lib/narray_ext.rb (reverse,rot90): new method
+
+2012-09-01  ohai
+
+	* lib/narray_ext.rb: Change NMath#recip into a module function.
+
+2011-08-29  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* narray.c (na_alloc_struct): check array size (zero/negative).
+	* ver 0.6.0.1
+
+2011-08-27  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* narray.c (na_alloc_struct): check array size (overflow).
+	* extconf.rb (#install_rb): --export-all option for mingw.
+	* ver 0.6.0.0
+
+2011-02-04  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* na_func.c (na_prod, na_prod_body, na_cumprod, na_cumprod_bang):
+	  New method.
+
+2010-01-04  David MacMahon <davidm at astro.berkeley...>
+
+	* mkop.rb, na_func.c, na_linalg.c, narray_local.h:
+	Add NArray#mod! method
+	Also adds NArray#mod as an alias for NArray#%.
+
+2010-01-04  David MacMahon <davidm at astro.berkeley...>
+
+	* mkop.rb: Fix divide-by-zero bug in % operator
+	Prior to this fix, the following would crash Ruby with a floating point
+	exception (at least on Mac OS X 10.6)...
+	  1 % NArray[0]
+	Now that code raises ZeroDivisionError which can be rescued.
+
+2010-01-04  David MacMahon <davidm at astro.berkeley...>
+
+	* Rakefile: Add Rakefile for easy gem creation
+	Just run "rake gem" to create the gem file in the pkg/ subdirectory.
+	Added .gitignore file to ignore pkg/ subdirectory.
+
+2011-01-04  sgwong
+
+	* extconf.rb: failure due to the change of
+	  $DLDFLAGS in ruby1.9
+
+2010-12-14  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* lib/nmatrix.rb (NMatrix#diagonal!):
+	  - failed due to spec change of NArray.to_na.
+	    Thanks to M. Kikkawa.
+	* ver 0.5.9p9
+
+2010-09-13  David MacMahon <davidm at astro.berkeley...>
+
+	* narray.c (na_where2):
+	  - Convert to NA_BYTE by calling "obj.ne(0)"
+	* ver 0.5.9p8
+
+2010-07-12  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* narray.c (na_s_to_na):
+	  - improve argument check in NArray.to_na
+
+2010-04-30  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* narray.c (na_s_to_na):
+	  - the number of arguments was not checked.
+	    Thanks to S D for report.
+
+2010-01-16  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* na_index.c (na_index_analysis):
+	  - access out-of-bounds "struct slice" array.
+	* SPEC.en, SPEC.ja:
+	  - fix wrong explanation in count_false/true.
+	* na_random.c (na_random):
+	  - modify random method not to change itself.
+	* lib/narray_ext.rb:
+	  - modify randomn! method to replace itself.
+	    Thank Yusuke ENDOH for report and comments.
+
+2009-06-14  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* narray.h:
+	  include sys/stdint.h rather than sys/types.h
+	  for C99 confomance
+	* ver 0.5.9p7
+
+2009-05-20  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* lib/narray_ext.rb (mean, stddev,rms,rsmdev,covariance):
+	  - swith to DFLOAT type if integer array.
+	  - thanks to Philip Silva for report.
+
+2009-03-11  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* na_index.c (na_aset_single_dim):
+	  - add check of storing empty array.
+	  - thanks to NISHI Takao for report.
+
+2008-11-05  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* work with ruby 1.9.1 preview1
+	  - use RARRAY_*** macros instead of struct RArray.
+	  - follow changes in Complex feature.
+	  - change oprator arg of coerce_rev func : id -> symbol
+	  - modify test scripts.
+
+	* na_array.c (na_do_mdai):
+	  - bug fix in counting narray's rank.
+
+	* ver 0.5.9p6
+
+2008-06-10  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* bench/: new sophisticated benchmark script.
+
+	* ver 0.5.9p5
+
+2008-05-27  Jose M <braket at hotmai...>
+
+	* na_array.c, na_index.c, na_random.c, na_func.c:
+	* na_linalg.c, narray.c, mkmath.rb, mkop.rb:
+	  change var++ to ++var: make NArray perform faster.
+
+2008-05-24  Hiroki Motoyoshi <himotoyoshi at yahoo.co...>
+
+	* mkmath.rb:
+	  fix bug in powOO.
+
+2008-04-02  David MacMahon <davidm at astro.berkeley...>
+
+	* na_func.c:
+	  new methods: conj!, conjugate!
+
+2008-01-11  David MacMahon <davidm at astro.berkeley...>
+
+	* lib/narray_ext.rb (stddev):
+	  fix for complex NArrays.
+	* lib/narray_ext.rb (rms, rmsdev):
+	  new methods.
+
+2008-01-28  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* na_array.c (na_range_to_sequence, na_do_mdai):
+	* na_index.c (na_index_range):
+	  change in internal structure of Ruby 1.9 Range object.
+	  Thanks to Hargobind Khalsa.
+
+	* ver 0.5.9p4
+
+2007-12-27  Masahiro TANAKA  <masa16.tanaka at gmail.com>
+
+	* narray_local.h, narray.c, na_array.c:
+	  use RSTRING_PTR, RSTRING_LEN for Ruby 1.9.0.
+
+	* ver 0.5.9p3
+
+2007-12-11  Masahiro TANAKA  <masah16.tanaka at gmail.com>
+
+	* mkop.rb:
+	  omit precision in format "%g" for InspS/D/X/C.
+	  Thanks to Shigenori OTSUKA at kyoto-u.
+
+	* ver 0.5.9p2
+
+2007-10-09  David MacMahon <davidm at astro.berkeley...>
+
+	* narray.h, mkop.rb:
+	  bug in NArray::NARRAY_VERSION and InspX.
+
+2006-08-09  Masahiro TANAKA  <masahiro.tanaka at nao.ac.jp>
+
+	* na_fftw.c, extconf.rb, narray.c (Init_narray):
+	  Remove FFTW2 support; it is a separete module.
+
+	* ver 0.5.9
+
+2006-08-08  Masahiro TANAKA  <masahiro.tanaka at nao.ac.jp>
+
+	* na_index.c (na_index_test, na_aset_single_dim):
+	  `nv[1] = nu' should work if nv and nu are NVector.
+	  `NA_IsNArray(nu)' is used for checking NArray.
+	  Thanks to sun at titech.
+
+2006-08-08  Masahiro TANAKA  <masahiro.tanaka at nao.ac.jp>
+
+	* narray_local.h, mknafunc.rb (mksortfuncs):
+	  Argument type of comparison function passed to
+	  qsort should be `const void *'.
+	  Thank Daniel Berger for report.
+
+2006-07-30  Masahiro TANAKA  <masahiro.tanaka at nao.ac.jp>
+
+	* narray.h, narray.c:
+	  Do not declare external variables of
+	  cNArray, na_sizeof in narray.c.
+	  Thank Daniel Berger for report.
+
+2006-03-22  Masahiro TANAKA  <masahiro.tanaka at nao.ac.jp>
+
+	* lib/narray_ext.rb (mean, stddev):
+	  Fix to work with NVector/NMatrix classes.
+	  Thank Stephen Hill for report.
+
+2005-09-13  Charlie Mills  <Charlie.Mills at m...>
+
+	* mkop.rb, na_func.c, narray_local.h:
+	  Make NArray#eq more robust.
+
+2005-08-05  Masahiro TANAKA  <masahiro.tanaka at nao.ac.jp>
+
+	* mkmath.rb (na_math_func):
+	  Bug: In NMath functions, Float class arguments have been
+	   converted to SFLOAT type.  Thank Yuhei Kuratomi for his report.
+	  Spec Change: Calculate and return as DFLOAT type
+	   if an integer argument is given to NMath functions.
+
+	* na_func.c (na_math_atan2):
+	  NMath.atan2() accepts other objects than NArray class.
+	  Treat as DFLOAT for integer arguments.
+
+	* ver 0.5.8
+
+2005-01-25  Masahiro TANAKA  <masahiro.tanaka at nao.ac.jp>
+
+	* na_array.c (na_ary_to_nary_w_type):
+	  Bug: "type" is not initialized when an array is empty.
+
+2005-01-07  Masahiro TANAKA  <masahiro.tanaka at nao.ac.jp>
+
+	* narray.h: #define NARRAY_VERSION  NARRAY_VERSION_CODE
+
+	* narray.c: new constant: NArray::NARRAY_VERSION
+
+2004-11-10  Masahiro TANAKA  <masahiro.tanaka at nao.ac.jp>
+
+	* na_random.c:
+	  Fix infinite loop due to gcc bug?;
+	  "int32_t x; x>>=32;" unvaried although 0 expected.
+	  Thanks to David G. Andersen.
+
+	* lib/narray_ext.rb (randomn):
+	  Raise error if NArray type is other than float.
+
+	* ver 0.5.7p4
+
+2004-09-22  Masahiro TANAKA  <masahiro.tanaka at nao.ac.jp>
+
+	* nimage/nimage.c:
+	  Argument type of rb_str2cstr is changed.
+	  Use RSTRING()->ptr & RSTRING()->len.
+	  Thanks to Ara Howard.
+
+2004-06-28  KOSHIRO Tsuyoshi <koshiro rish.kyoto-u.ac.jp>
+
+	* extconf.rb: generate libnarray.a for Cygwin + Ruby 1.8.1.
+
+	* ver 0.5.7p3
+
+2004-02-19  Masahiro TANAKA  <masahiro.tanaka at nao.ac.jp>
+
+	* na_array.c (na_free_mdai):
+	  memory free bug: xfree(mdai->type); added.
+
+	* ver 0.5.7p2
+
+2004-01-04  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+
+	* extconf.rb: narray.h, narray_conf.h was not installed on ruby-1.8.x
+
+	* narray.c: NArray-GC is disabled.
+
+	* nimage/nimage.c, test/testwhere.rb, speed/[mybench.rb,mul_rep.rb]:
+	  fix ruby-1.8.x incompatibility
+
+	* ver 0.5.7p1
+
+2003-03-04  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+
+	* narray.c (na_alloc_struct):
+	  NArray-specific GC is enabled for ruby-1.8.0.
+
+	* ver 0.5.7
+
+2003-03-03  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+
+	* na_random.c: created.
+
+	* lib/narray_ext.rb (rank_total):
+	 Array#indices is obsolete. use Array#select.
+	 Default `to_a' will be obsolete.
+
+	* lib/nmatrix.rb: Object#type is obsolete. use Object#class.
+
+2003-03-01  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+
+	* narray_ext.rb (swap_byte,hton,htov): removed.
+	* mkop.rb, mknafunc.rb, na_func.c, narray_local.h:
+	  add C-version of swap_byte, hton, htov.
+
+2003-02-28  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+
+	* extconf.rb: do not add "--output-lib libnarray.a"
+	  to link options if Cygwin with Ruby 1.8.0.
+	  Thank MoonWolf for the note.
+
+2002-11-25  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+	* na_func.c (na_cumsum_bang,na_cumsum_): created.
+	  Thank Jon Davidson for the proposal.
+
+2002-09-15  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+
+	* na_array.c (na_do_mdai):
+	  Index is not `i' but `j' in recursive array check.
+	  Thank Ara Howard for the bug report.
+
+2002-05-30 WATANABE Hirofumi <eban at os.rim.or.jp>
+
+	* extconf.rb: to build in another directory than source tree.
+	* depend: ditto.
+
+2002-05-18  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+
+	* lib/narray_ext.rb (NArray#==): return false unless other is NArray.
+
+	* narray.h, narray_local.h, narray.c:
+	  move na_sizeof variable from narray_local.h to narray.h.
+	  const keyword added.  Thanks to Horinouchi-san.
+	* narray.c (na_get_typecode): change to public method.
+	* narray.c (na_sizeof,na_typestring): const keyword added.
+	* mkop.rb : ditto.
+	* na_func.c (na_unary_func): ditto.
+	* mkmath.rb : dismiss sincos()
+
+2002-04-11  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+
+	* mkmath.rb (asinh,acosh,atanh): better precision.
+
+2002-04-10  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+
+	* mkop.rb (SetFucs): should use INT2NUM to extract 32-bit int.
+	 Thanks to Kozuka-san.
+
+2002-03-26  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+
+	* narray.def: remove unused entry. Thanks to Watanabe-san.
+
+2002-03-24  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+
+	* na_array.c:
+	  New multi-dimentional array investigation is introduced.
+	  Scan array only once and check recursive array.
+
+	* narray.h, narray_local.h:
+	  Local definisions in narray.h are moved into narray_local.h.
+
+	* ver 0.5.6
+
+2002-03-17  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+
+	* nmatrix.rb (NMatrix#*): accept Array as an argument.
+
+2002-02-26  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+
+	* na_array.c (na_copy_ary_to_nary): accept Range as a sequence.
+
+2002-02-06  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+
+	* narray.c, na_func.c, na_index.c, na_linalg.c, na_fftw.c, mkmath.rb:
+	  add volatile keyword instead of na_touch_object() function.
+
+2002-01-25  Masahiro TANAKA  <masa at ir.isas.ac.jp>
+
+	* na_array.c (na_to_array0): Bug: GC fails if ary->len is set
+	  in advance.  Thanks to Bil Kleb.
+
+2001-12-30  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* extconf.rb: Modify install_rb to install narray.h, narray_config.h.
+	* na_index.c (na_aref,na_aset):
+	  Mask support.  Thanks to T.Horinoichi.
+	* mkop.rb: Mask functions added.
+	* narray.h: Macros added.
+	* narray.def: created.
+
+	* ver 0.5.5
+
+2001-11-20 Takeshi Horinouchi <horinout at kurasc.kyoto-u.ac.jp>
+
+	* narray.c (na_get_typecode): Bug: "!" needed at strncmp.
+	* Mask support in [], []=.
+	  na_aref/aset_mask(), na_count_true/false() added.
+          Methods mask, count_true, count_false added.
+	* test/testmask.rb: created.
+
+2001-07-01  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* narray.h: introduce na_index_t.
+	* na_func.c (na_init_slice,na_loop_index_ref,na_loop_general):
+	  change to na_index_t.
+	* na_index.c: modify EXCL(range) to use excule_end?.
+	* na_index.c (na_aref_single_dim): remain array if sl->step!=0.
+	  i.e., a[0..0] results in 1-element array.
+	* na_func.c (Init_na_funcs): alias image, arg, conjugate.
+
+	* ver 0.5.4
+
+2001-06-30  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* extconf.rb: check sys/typedef.h, u_int8_t, int16_t, int32_t.
+	  generating narray_config.h.
+	* narray.h: conditional typedef. define NARRAY_H.
+	* na_func.c (Init_na_funcs): change == to eq. add gt,ge,lt,le.
+	* lib/narray_ext.rb: new entry: ==, all?, any?, none?.
+
+	* mkop.rb: new entry: conditional XOR.
+	* na_func.c (na_cond_xor): ditto.
+	* narray.h: ditto.
+
+2001-06-05  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* na_index.c (na_aref_body): NVector#[] should return NVector
+	  class even when single argument of range/array.
+	  Thanks to Daishi Harada.
+	* narray.h (na_class_dim): delete redundant ";"
+	* extconf.rb: delete config_dir("narray"), add dir_config("fftw").
+
+2001-06-04  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* na_index.c (na_aref_multi_dim_single_elm):
+	  do not change class even if a[0..0,0..0] for NMatrix.
+	  Thanks to Daishi Harada.
+	* narray.c (na_inspect): rb_str_cat(str,": \n",4);
+	  not 4, but 3. Thanks to Matju.
+
+2001-05-11  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* nimage/extconf.rb: add dir_config("x11"). rm have_header.
+
+2001-04-10  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* narray.h: exclude typedef int32_t,int16_t,u_int8_t for Mac OS X.
+	  Thanks to T.Yamamoto.
+	* mkmath.rb (atan,atanh): avoid non-constant initializer for complex.
+
+2001-04-03  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* na_array.c (na_search_rank): ignore empty array.
+	* na_array.c (na_copy_ary_to_nary): ignore empty array and nil.
+	* ver 0.5.3
+
+2001-04-02  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* narray.c (na_to_s): bug: na_sizeof[] is necessary.
+	  Thank matju for report.
+
+2001-01-29  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* mkop.rb (Angl): added.
+	* na_func.c (na_angle): added.  Thank M.Tagusai for proposal.
+	* ver 0.5.2
+
+2001-01-21  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* mkop.rb, mkmath.rb: loop-end condition changed from n>0 to n.
+	  5% speed up for multiplication of double.
+
+2001-01-20  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* mkop.rb (DivU,DivB): raise error if divided by 0.
+
+2001-01-19  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* mkop.rb (round): bug: has omitted the case of 0.
+
+2001-01-18  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* narray.c (na_is_empty): added.
+	* na_func.c (na_exec_unary,na_exec_binary,na_make_object_extend):
+	  enable operation of empty array.
+
+2001-01-17  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* na_index.c (na_aset_array_index): allow a[[]]=1.
+
+2001-01-14  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* na_index.c (na_ary_to_index): bug: should raise error if < -n.
+
+2001-01-13  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* na_func.c (na_unary_func): should call func of self-type.
+	  Thanks to Matju.
+
+2001-01-06  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* narray.c (na_s_new_int): check argc==0. Thanks to Matju.
+
+2000-12-10  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* ver 0.5.1
+
+2000-12-11  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* narray.c (na_alloc_struct): cope with empty array.
+	* na_func.c (na_exec_unary,na_shape_max_2obj): empty check.
+
+2000-12-10  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* narray.c (na_random): disable initalizing seed.
+	* na_touch_object created.
+	* free -> xfree.  Thanks to Naoki Matsumoto.
+
+2000-12-07  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* ver 0.5.0.p2
+
+	* fix problems for VC++. Thanks to Naoki Matsumoto.
+	* mkmath.rb: create asinh, acosh, atanh missing in VC++.
+	* mkop.rb (TpErrI): return int after rb_raise().
+	* narray.h: max() -> NA_MAX(), swap() -> NA_SWAP().
+	* narray.c (na_get_typecode): return int after rb_raise().
+	* na_func.c (na_sort,na_sort_index): fix function decl. for qsort.
+
+2000-12-01  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* ver 0.5.0.p1
+
+	* lib/nmatrix.rb (NVector#+,-): should change Class to NArray
+	  before calling super.  Thanks to Kenya OGATA.
+
+	* na_index.c (EXCL): follow the change of EXCL() in 1.6.2.
+	  Thanks to Robert Feldt.
+
+2000-11-25  Masahiro Tanaka  <masa at ir.isas.ac.jp>
+
+	* ver 0.5.0
+	* No Log between 0.5.0 and 0.3.5.p1. Sorry.
+
+2000-10-14  Masahiro Tanaka  <masa>
+
+	* narray.c (na_wrap_struct_class): na_mark_ref, na_mark_obj.
+
+2000-10-05  Masahiro Tanaka  <masa>
+
+	* nmatrix.rb: created.
+
+	* too many changes are applied to source codes. ^^;
+
+2000-10-03  Masahiro Tanaka  <masa>
+
+	* na_index.c (na_shrink_rank): created for general purposes.
+
+	* narray.c (na_reshape): use new na_shrink rank.
+	  recognize "true" argument.
+
+	* lib/narray_ext.rb: use new feature of reshape
+
+2000-10-02  Masahiro Tanaka  <masa>
+
+	* na_index.c (na_make_slice_aset_fill): created.
+
+	* lib/narray_ext.rb (flatten): no more use dup.
+
+	* na_func.c (na_s_mul_sum): created.
+
+	* narray.c (na_wrap_struct): wrap with referring class.
+	(na_ref_alloc_struct): created.
+	(na_reshape_ref,na_newrank_ref): created.
+	(na_inspect): print class name.
+
+	* narray.h: add "VALUE obj" elmt to "struct NARRAY".
+
+2000-09-29  Masahiro Tanaka  <masa>
+
+	* mkopfunc.rb (mulacmfunc): created.
+
+	* mkfuncs.rb: rewrite with %w().
+	(mktrifunc): renamed from mkcmpfunc. accept block.
+
+	* na_loop.c (na_slice_set_extend): change arguments.
+
+	* na_func.c (na_mul_acm,na_shape_max_3obj): created.
+	(na_exec_trifunc_extend): a1 can be shrinkable.
+
+2000-09-28  Masahiro Tanaka  <masa>
+
+	* lib/narray_ext.rb (is_ineger?,is_complex?):
+	  -> ineger?, complex?.
+
+2000-09-27  Masahiro Tanaka  <masa>
+
+	* na_index.c (na_index_analysis): add false dimension.
+
+	* narray.c (na_clone): renamed from ns_dup.
+
+2000-09-04  Masahiro Tanaka  <masa>
+
+	* ver 0.3.5.p1
+
+	* narray.c, na_array.c, na_func.c, narray.h, mknmath.rb
+	  remove unused variables and functions. (-Wall check)
+	  (Thanks to Robert Feldt)
+
+	* lib/narray_ext.rb (convol): put in module FFTW.
+	  (Thanks to Robert Feldt)
+
+2000-09-01  Masahiro Tanaka  <masa>
+
+	* ver 0.3.5
+
+	* narray.c (na_random): remove `seed' argument.  add rand().
+
+2000-08-25  Masahiro Tanaka  <masa>
+
+	* lib/narray_ext.rb: create randomn (Box-Muller).
+
+2000-08-23  Masahiro Tanaka  <masa>
+
+	* na_index.c (aref, aset): categolize procedures with arguments.
+
+2000-08-02  Masahiro Tanaka  <masa>
+
+	* lib/narray_ext.rb: create FFTW.convol.
+
+2000-08-01  Masahiro Tanaka  <masa>
+
+	* na_index.c (na_aref_array_index): bug fix: free index memory.
+
+2000-07-28  Masahiro Tanaka  <masa>
+
+	* ver 0.3.4
+
+	* mkcmpfunc.rb : remove <=> with complex.  add ~.
+
+	* mkopfunc.rb, na_func.c: add &, |, ^.
+
+2000-07-27  Masahiro Tanaka  <masa>
+
+	* mknmath.rb, lib/narray_ext.rb: add covariance.
+
+	* mkopfunc.rb (data_mod): add imag=.
+
+	* mksetfunc.rb: add im (ImagMul).
+
+	* mknmath.rb, lib/narray_ext.rb: add trigonometric functions.
+
+2000-07-26  Masahiro Tanaka  <masa>
+
+	* na_func.c (na_exec_math_func): extract object if argument is
+	  non-array.
+
+	* lib/narray_ext.rb: add mean, stddev.
+
+2000-07-21  Masahiro Tanaka  <masa>
+
+	* na_index.c (na_aset): bug fix for empty index, etc.
+
+	* na_func.c (na_shape_check): raise error if empty array.
+	(na_sum_body,na_min,na_min,na_transpose): better arg-parse.
+	(na_arg_to_rank,na_accum_set_shape,na_accum_shrink_rank):
+	  created.
+
+2000-07-20  Masahiro Tanaka  <masa>
+
+	* narray.c (na_str_to_na): more size check.
+
+	* na_index.c (na_aset): allow if src-ary has smaller dims.
+
+	* narray.c (na_to_narray): moved from na_array.c
+
+	* lib/narray_ext.rb: created. swap_byte, hton etc.
+
+	* narray.c (Init_narray): change type=>typecode.
+	  add NArray.dfloat, NArray::DFLOAT etc.
+	  add element_size, to_binary, to_type_as_binary.
+
+2000-07-18  Masahiro Tanaka  <masa>
+
+	* na_loop.c (na_loop_general): created. na_loop_index is obsolete.
+
+2000-07-17  Masahiro Tanaka  <masa>
+
+	* na_func.c (na_sum_body,na_accum): created.
+
+	* na_index.c (na_slice): created.
+
+	* na_index.c (na_aref,na_aset): if the argument is an array,
+	  methods [],[]= return same shape as the array.  e.g,
+	  a[[[0,1],[2,3]]] creates 2-D array.
+
+	* na_index.c
+	  (na_serialize_struct,na_aref_aryindex,na_aref_single): Created.
+
+2000-07-16  Masahiro Tanaka  <masa>
+
+	* na_func.c (na_transpose_bifunc,na_transpose),
+	  test/testtrans.rb: Created.
+
+2000-07-15  Masahiro Tanaka  <masa>
+
+	* ver 0.3.3
+
+	* na_func.c (na_sort,na_sort_index,na_sort_number): Created.
+
+	* mkfuncs.rb (mksortfunc): Created.
+
+	* test/testsort.rb: Created.
+
+2000-07-14  Masahiro Tanaka  <masa>
+
+	* narray.c (Init_narray), narrah.h:  introduce NArrayScalar class.
+
+	* narray.c (na_coerce), na_func.c (na_bifunc):	better casting.
+
+2000-07-11  Masahiro Tanaka  <masa>
+
+	* mk*.rb, depend: include code-generating scripts in distribution.
+
+	* na_func.c, mkopfunc.rb: rename sub! => sbt!.
+
+	* mkfuncs.rb: fix to work for Ruby ver 1.5.4.
+
+2000-07-10  Masahiro Tanaka  <masa>
+
+	* na_array.c: rename na_to_narray1 to na_ary_to_narray
+
+	* na_array.c: reduce GC problem; delay registration of objects.
+	  change return value of na_to_narray0
+	  from VALUE to struct NARRAY *
+	  reflect in na_ary_to_na, na_ary_to_na, na_ary_to_narray.
+
+	* narray.h: add GetOrMakeNArray(obj,ary), FreeMadeNArray(obj,ary)
+
+	* narray.c, na_index.c, na_func.c, na_fftw.c:
+	  change na_to_narray0 to GetOrMakeNArray/FreeMadeNArray.
+
+	* narray.c (na_free): free memory of itself structure.
+
+	* narray.c (na_mark): pass pointer to rb_gc_mark.
+
+	* na_array.c (na_make_inspect): return if total<0.
+
+	* na_index.c (na_ary_to_index, na_aref, na_aset):
+	  judge whether empty array.
+
+	* naimage/demo/mandel.rb: Now no need for checking size.
+
+	* test/testindex*.rb: print more description.
+
+2000-07-05  Masahiro Tanaka  <masa>
+
+	* ver 0.3.2
+
+	* Create NImage library
diff --git a/app/server/vendor/narray-0.6.1.1/MANIFEST b/app/server/vendor/narray-0.6.1.1/MANIFEST
new file mode 100755
index 0000000..07f8ec1
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/MANIFEST
@@ -0,0 +1,53 @@
+ChangeLog
+MANIFEST
+README.md
+README.ja.md
+SPEC.en.txt
+SPEC.ja.txt
+depend
+extconf.rb
+mkmath.rb
+mknafunc.rb
+mkop.rb
+na_array.c
+na_func.c
+na_index.c
+na_linalg.c
+na_random.c
+narray.c
+narray.def
+narray.h
+narray_local.h
+lib/narray_ext.rb
+lib/nmatrix.rb
+test/statistics.rb
+test/testarray.rb
+test/testbit.rb
+test/testcast.rb
+test/testcomplex.rb
+test/testfftw.rb
+test/testindex.rb
+test/testindexary.rb
+test/testindexset.rb
+test/testmask.rb
+test/testmath.rb
+test/testmath2.rb
+test/testmatrix.rb
+test/testmatrix2.rb
+test/testmatrix3.rb
+test/testminmax.rb
+test/testobject.rb
+test/testpow.rb
+test/testrandom.rb
+test/testround.rb
+test/testsort.rb
+test/teststr.rb
+test/testtrans.rb
+test/testwhere.rb
+bench/all.rb
+bench/bench.m
+bench/bench.py
+bench/bench.rb
+bench/dummy.m
+bench/dummy.py
+bench/dummy.rb
diff --git a/app/server/vendor/narray-0.6.1.1/README.ja.md b/app/server/vendor/narray-0.6.1.1/README.ja.md
new file mode 100755
index 0000000..8ab5b4a
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/README.ja.md
@@ -0,0 +1,55 @@
+# Ruby/NArray
+
+* ver 0.6.1.0 (2014-06-02)
+* [Home page](http://masa16.github.io/narray/index.ja.html)
+* [GitHub Repository](https://github.com/masa16/narray)
+* [RubyGems](https://rubygems.org/gems/narray)
+* [NArrayメソッド一覧](https://github.com/masa16/narray/blob/master/SPEC.ja.txt)
+
+## Ruby/NArrayの特徴:
+
+* Rubyで、高速な数値計算が可能。
+* 要素には、8,16,32 bit 整数、単精度/倍精度の実数/複素数、
+  および Rubyオブジェクトをサポート。
+* 部分配列の取出し、代入も容易。
+  要素位置の指定には、数値、範囲、インデックスの配列が使用可能。
+* +, -, *, /, %, ** や 算術関数の演算は、要素-対-要素でおこなう。
+* NMath 算術関数モジュール
+* 配列同士の演算・代入は、各次元のサイズが同じであることが必要。
+  ただし、サイズが1の次元は、他方の配列のサイズに合わせて
+  「繰り返し」同じ要素が適用される。
+* FFTW (高速フーリエ変換) version 3 は次のモジュールでサポート。
+* Ruby/PGPLOT (グラフィックスライブラリ、別悃) にて
+  XYグラフ、ヒストグラム、等高線、イメージ表示可能。
+* 数値計算・画像処理・データ解析など幅広い応用が可能(と思う)。
+
+* 類似品
+  * Python/NumPy, Perl/PDL, Yorick, IDL
+
+* 不十分な点
+  * メソッドが不足。
+  * バグ出しが不十分。
+  * ドキュメントがない。
+
+## インストール方法
+
+Rubyの標準的な拡張ライブラリと同じです。ソースを展開したディレクトリで、
+
+    ruby extconf.rb
+    make
+    make install
+
+と実行します。
+
+## 動作確認
+
+* ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
+* gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)
+
+## 配布条件
+
+Rubyのライセンスに準拠します。
+
+## 著者
+
+田中昌宏
diff --git a/app/server/vendor/narray-0.6.1.1/README.md b/app/server/vendor/narray-0.6.1.1/README.md
new file mode 100755
index 0000000..22afc3b
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/README.md
@@ -0,0 +1,51 @@
+# Ruby/NArray
+
+* ver 0.6.1.0 (2014-06-02)
+* [Home page](http://masa16.github.io/narray/)
+* [GitHub Repository](https://github.com/masa16/narray)
+* [RubyGems](https://rubygems.org/gems/narray)
+* [NArray method list](https://github.com/masa16/narray/blob/master/SPEC.en.txt)
+
+## NArray Features:
+
+* Fast and easy calculation for large numerical array.
+* Accepting Elements:
+  8,16,32 bit integer, single/double float/complex, Ruby Object.
+* Easy extraction/substitution of array subset,
+  using assignment with number, range, array index.
+* Operator: +, -, *, /, %, **, etc.
+* NMath: Mathematics functions.
+* FFTW version 2 or 3 is separately supported.
+* Ruby/PGPLOT: Graphics library interface (separately distributed)
+  X-Y Graph, Histogram, Contour map, Image map, etc.
+
+* NArray is similar to:
+  * Python/NumPy, Perl/PDL, Yorick, IDL
+
+* NArray is far from completed!
+  * Experimental!  Specification may be changed.
+  * Far from completed.
+  * Bugs may be included.
+  * No document.
+
+## Installation
+
+    ruby extconf.rb
+    make
+    make install
+
+## Tested Platform
+
+* ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
+* gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)
+
+## License
+
+    This program is free software.
+    You can distribute/modify this program
+    under the same terms as Ruby itself.
+    NO WARRANTY.
+
+## Author
+
+Masahiro TANAKA
diff --git a/app/server/vendor/narray-0.6.1.1/Rakefile b/app/server/vendor/narray-0.6.1.1/Rakefile
new file mode 100755
index 0000000..5a9e6c0
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/Rakefile
@@ -0,0 +1,24 @@
+require 'rubygems'
+require 'rubygems/package_task'
+
+FileUtils.ln_s('.', 'src') if !File.symlink?('src')
+
+load './narray.gemspec'
+
+pkgtsk = Gem::PackageTask.new(GEMSPEC) do |pkg|
+  pkg.need_zip = true
+  pkg.need_tar = true
+end
+
+task :default => "gem"
+
+#--
+GEMFILE = File.join(pkgtsk.package_dir, GEMSPEC.file_name)
+
+task :install => GEMFILE do
+  sh "gem install -V --backtrace #{GEMFILE}"
+end
+
+task :push => GEMFILE do
+  sh "gem push #{GEMFILE}"
+end
diff --git a/app/server/vendor/narray-0.6.1.1/SPEC.en.txt b/app/server/vendor/narray-0.6.1.1/SPEC.en.txt
new file mode 100755
index 0000000..0685cbf
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/SPEC.en.txt
@@ -0,0 +1,327 @@
+
+	Ruby/NArray  ver 0.6.0.7 (2013-02-01)	by Masahiro TANAKA
+
+
+Class method:
+    NArray.new(typecode, size, ...)	create new NArray. initialize with 0.
+
+    NArray.byte(size,...)		1 byte unsigned integer
+    NArray.sint(size,...)		2 byte signed integer
+    NArray.int(size,...)		4 byte signed integer
+    NArray.sfloat(size,...)		single precision float
+    NArray.float(size,...)		double precision float
+    NArray.scomplex(size,...)		single precision complex
+    NArray.complex(size,...)		double precision complex
+    NArray.object(size,...)		Ruby object
+				all above method initialize with 0 or nil.
+
+    NArray.to_na(array)			convert to NArray
+    NArray.to_na(string,type[,size,...])
+    NArray[...]
+      NArray[1,5,10.0]  #=>  NArray.float(3):[1.0, 5.0, 10.0]
+      NArray[1..10]     #=>  NArray.int(10):[1,2,3,4,5,6,7,8,9,10]
+
+
+Class constant:
+    CLASS_DIMENSION	# of dimension treated as data.
+			0 for NArray, 1 for NVector, 2 for NMatrix.
+
+NArray information
+    self.dim		Return the dimension = the number of indices
+    self.rank		same as dim
+    self.shape		Return the array of sizes of each index
+    self.total		Return the number of total elements
+
+Slicing Array
+ - Index components:	Integer, Range, Array, true.
+ - Index order:		FORTRAN type.
+    a[ 1, 2, -1 ]	element slicing.
+			  If negative, counts backward from the end.
+			  Element-dimensions are contracted.
+    a[ 0..3, 4..1 ]	extract in the range.
+			  If the former of the range is bigger,
+			   return elements in reversed order.
+    a[ [1,3,2,4] ]	an array with the elements of the indices.
+			  If `a' has multi-dimension but, in [],
+			   single index is specified,
+			   `a' is treated as a single dimension array.
+    a[ 1, 2..3, [1,3,2,4], true ]   compound index.
+				    This returns 3-dim array.
+    a[]			same as a.dup.
+    a[ 0, true ]	sams as a[0,0..-1]. `true' means all.
+    a[ false, 0 ]	same as a[true,true,0], if a is a 3-d array,
+			`false' means ellipsis dimension.
+    a[ mask ]		masking. "mask" is a byte NArray with its
+			length equal to that of "a". According to the
+			value of each element of mask, the corresponding
+			element in "a" is eliminated (when 0) or
+			retained (when not 0).
+			Example:
+				a=NArray.float(2,2).indgen!
+				p a[ a.lt 3 ]
+				--> [ 0.0, 1.0, 2.0 ]
+				(Here, a.lt 3 gives a byte NArray)
+				(This is also done by a[ (a.lt 3).where ])
+
+ - A 2-or-more-dim array object with only one argument in `[ ]',
+   is treated as a flat 1-d array.
+   e.g.: a[3] is same as a[0,1] if a is 3x3 array.
+
+ - self.slice(...)	Same as self[...] but keeps the rank of
+			original array by not elimiting dimensions
+			whose length became equal to 1 (which self[]
+			does). This is not the case with the
+			1-dimensional indexing and masking (same as []).
+
+Replacing Elements -- Same rule as slicing
+
+    a[ 1, 2, 3 ] = 1
+    a[ 0..3, 1..4, 2..5 ] = 2
+    a[ [1,3,2,4], true ] = 3
+    a[] = 4			Same as a.fill!(4)
+
+    a[0..2]  = b[1..5]		--> Error! due to different num of elements.
+    a[1,2]   = b[0..2,1..3]	Storing elements from index [1,2]
+				( a[1,2]=b[0,1],a[2,2]=b[1,1],... )
+    a[0..2,0..3]  = b[0..2,1]	Storing repetitively
+				( a[0,0]=b[0,1],..,a[0,3]=b[0,1] )
+
+Delete row/columns -- Complement of slice
+
+    self.delete_at(...)	  Arguments are the same as the [] and slice methods
+			  see https://github.com/masa16/narray/issues/5
+
+Filling values
+    self.indgen!([start[,step]]) Generate index;
+				 Set values from 'start' with 'step' increment
+    self.fill!(value)		 Fill elements with 'value'
+    self.random!(max)		 Set random values between 0<=x<max
+				 using MT19337
+    self.randomn		 Set Normally distributed random values
+				 with mean=0, dispersion=1 (Box-Muller)
+    NArray.srand([seed])	 Set random seed.
+				 A time-depend seed is choosed if omitted.
+
+Operation: performed element by element
+    a = NArray.float(3,3).indgen
+    b = NArray.float(3,3).fill(10)
+    c = a*b	# --> NArray.float(3,3)
+
+    a = NArray.float(3,1).indgen
+    b = NArray.float(1,3).fill(10)
+    c = a*b	# --> NArray.float(3,3) -- size=1 dimension is extensible.
+
+Arithmetic operator
+    -self
+    self + other
+    self - other
+    self * other
+    self / other
+    self % other
+    self ** other
+    self.abs
+
+    self.add! other
+    self.sbt! other
+    self.mul! other
+    self.div! other
+    self.mod! other
+
+Bitwise operator (only for integers)
+    ~self
+    self & other
+    self | other
+    self ^ other
+
+Comparison
+  -- element-wise comparison, results in BYTE-type NArray;
+     Note that not true nor false is returned.
+    self.eq other  (distinguish from == operator; see below )
+    self.ne other
+    self.gt other
+    self >  other
+    self.ge other
+    self >= other
+    self.lt other
+    self <  other
+    self.le other
+    self <= other
+
+    self.and other  element-wise condition.
+    self.or  other
+    self.xor other
+    self.not other
+
+    self.all?	  true if all the elements are true.
+    self.any?	  true if any element is true.
+    self.none?	  true if none of the element is true.
+    self.where	  Return NArray of indices where elements are true.
+    self.where2	  Return Array including two NArrays of indices,
+		  where elements are true and false, respectively.
+
+	e.g.: idx_t,idx_f = (a>12).where2
+
+Equivalence
+    NArray[1] == NArray[1]      #=> true
+    NArray[1] == NArray[1.0]    #=> true
+    NArray[1].eql? NArray[1]    #=> true
+    NArray[1].eql? NArray[1.0]  #=> false
+    NArray[1].equal? NArray[1]  #=> false
+    a=b=NArray[1]; a.equal? b   #=> true
+
+Statistics
+    self.sum(dim,..)     Summation
+    self.cumsum          Cumulative Summation (for 1-d array)
+    self.prod(dim,..)    Product (Multiply elements)
+    self.cumprod         Cumulative Produce (for 1-d array)
+    self.mean(dim,..)    Mean
+    self.stddev(dim,..)  Standard deviation
+    self.rms(dim,..)     Root mean square
+    self.rmsdev(dim,..)  Root mean square deviation
+    self.min(dim,..)     Minimum
+    self.max(dim,..)     Maximum
+	note: * If dimensions are specified, statistics are performed
+	      	on those dimensions and the rest dimensions are kept.
+	      * Range can be used.
+	      * If dimension is not specified, statistics are performed
+	        for all the elements.
+    self.median(dim)	 Median in 0..dim (All dimensions if omitted)
+
+Sort
+    self.sort(dim)	  Sort in 0..dim (All dimensions if omitted)
+    self.sort_index(dim)  Return index of Sort result.
+			     self[self.sort_index] equals to self.sort.
+
+Transpose
+    self.transpose( dim0, dim1, .. )
+	Transpose array.
+	The dim0-th dimension goes to the 0-th dimension of new array.
+	Negative number counts backward.
+	transpose(-1,1..-2,0) is replacement between the first and the last.
+
+Changing Shapes of indices
+    self.reshape!(size,...)
+    self.shape=(size,...)
+    self.newdim=(dim)	    Insert new dimension with size=1
+
+Reference to another NArray
+    self.refer			create NArray obj referring to another NArray
+    self.reshape(size,...)	same as self.refer.reshape!
+    self.newdim(dim,...)	same as self.refer.newdim!
+
+Reverse and Rotate
+    self.reverse([dim,...])	Reverse array at axes
+    self.rot90([k])		Rotate array by 90 degrees k times
+
+Type conversion
+    self.floor      Return integer NArray whose elements processed 'floor'
+    self.ceil
+    self.round
+    self.to_f	    Convert NArray type to float
+    self.to_i       Convert NArray type to integer
+    self.to_a	    Convert NArray type to Ruby-object
+    self.to_s	    Convert NArray data to String as a binary data.
+    self.to_string  Convert NArray type to Ruby-object
+		    containing Strings as printed elements
+
+Iteration
+    self.each {|i| ...}
+    self.collect {|i| ...}
+    self.collect! {|i| ...}
+
+Byte swap
+    self.swap_byte	swap byte order
+    self.hton		convert to network byte order
+    self.ntoh
+    self.htov		convert to VAX byte order
+    self.vtoh
+
+Boolean / mask related
+    self.count_false	count # of elements whose value == 0 (only for
+			byte type)
+    self.count_true	count # of elements whose value != 0 (only for
+			byte type)
+    self.mask( mask )	same as self[ mask ], but exclusively for masking.
+			Unlike [], a int or sint mask is accepted.
+
+Complex compound number
+    self.real
+    self.imag
+    self.conj
+    self.conj!
+    self.angle		atan2(self.imag, self.real)
+    self.imag= other	set imaginary part
+    self.im		multiply by imaginary unit
+
+NMath module
+    sqrt(x)
+    exp(x)
+    log(x)
+    log10(x)
+    log2(x)
+    atan2(x,y)
+    sin,cos,tan
+    sinh,cosh,tanh
+    asin,acos,atan
+    asinh,acosh,atanh
+    csc,sec,cot
+    csch,sech,coth
+    acsc,asec,acot
+    acsch,asech,acoth
+    covariance	(no idea why NMath::covariance doesn't work)
+
+
+FFTW module
+ (separate module)
+    fftw(x,[1|-1])
+    convol(a,b)		convolution with FFTW
+
+
+NMatrix
+
+  Subclass of NArray.  First 2 dimensions are used as Matrix.
+  Residual dimensions are treated as Multi-dimensional array.
+  The order of Matrix dimensions is opposite from
+  the notation of mathematics:  a_ij => a[j,i]
+
+  Methods:
+    +,-	 enable if other is NMatrix.
+    *	 Matrix product if other is NMatrix or NVector.
+	 Scalar product if other is Numeric or NArray.
+	 ex: NMatrix[[1,2],[3,4]] * [1,10]
+	       == NMatrix[ [[1,2],[3,4]], [[10,20],[30,40]] ]
+    /	 Scalar division if other is Numeric or NArray.
+	 Solve Linear Equation with LU factorization
+	  if other is square NMatrix.  a/b == b.lu.solve(a)
+
+    transpose		transpose Matrix dimensions if argument omitted.
+    diagonal(val)
+    diagonal!(val)	set val to diagonal elements. (set 1 if omitted)
+    unit		set 1 to diagonal elements.
+    inverse		Inverse matrix.
+    lu			compute LU factorization.
+			return NMatrixLU class object.
+
+NVector
+
+  Subclass of NArray.  First 1 dimension is used as Vector.
+  Residual dimensions are treated as Multi-dimensional array.
+
+  Methods:
+    +,-	 enable if other is NVector.
+    *	 Matrix product if other is NMatrix.
+	 Inner product if other is NVector.
+	 Scalar product if other is Numeric or NArray.
+    /	 Scalar division if other is Numeric or NArray.
+	 Solve Linear Equation with LU factorization
+	   if other is square NMatrix.  v/m == m.lu.solve(v)
+
+
+NMatrixLU
+
+  Created by NMatrix#lu method.
+  Including LU (NMatrix) and pivot (NVector).
+
+  Methods:
+    solve(other)	Solve with the result of LU factorization.
+			other should be NMatrix or NVector instance.
diff --git a/app/server/vendor/narray-0.6.1.1/SPEC.ja.txt b/app/server/vendor/narray-0.6.1.1/SPEC.ja.txt
new file mode 100755
index 0000000..3d03ae9
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/SPEC.ja.txt
@@ -0,0 +1,307 @@
+
+	Ruby/NArray  ver 0.6.0.7 (2013-02-01)	by Masahiro TANAKA
+
+
+クラスメソッド:
+    NArray.new(typecode, size, ...)	配列を生成する。要素は0で初期化。
+
+    NArray.byte(size,...)		1 byte unsigned integer
+    NArray.sint(size,...)		2 byte signed integer
+    NArray.int(size,...)		4 byte signed integer
+    NArray.sfloat(size,...)		single precision float
+    NArray.float(size,...)		double precision float
+    NArray.scomplex(size,...)		single precision complex
+    NArray.complex(size,...)		double precision complex
+    NArray.object(size,...)		Ruby object
+					以上要素は0またはnilで初期化。
+
+    NArray.to_na(array)			NArrayに変換
+    NArray.to_na(string,type[,size,..])
+    NArray[...]
+      NArray[1,5,10.0]  #=>  NArray.float(3):[1.0, 5.0, 10.0]
+      NArray[1..10]     #=>  NArray.int(10):[1,2,3,4,5,6,7,8,9,10]
+
+
+クラス変数:
+    CLASS_DIMENSION	データとして扱われる次元。
+			NArrayは0。NVectorは1。NMatrixは2。
+
+配列情報参照
+    self.dim	    次元(インデックスの数)を返す。
+    self.rank	    次元(インデックスの数)を返す。
+    self.shape	    次元ごとのサイズを返す。
+    self.total	    全要素数を返す。
+
+インデックス参照
+    self[ dim0, dim1, ... ]
+
+  -- インデックス引数に指定できるもの:  数値、範囲、配列、true, false
+  -- インデックスの順序:		FORTRAN 型
+  -- 添字引数が1つの場合、多次元配列はflattenされた1次元配列とみなされる。
+     例: a が 3x3 配列のとき、a[3] は a[0,1] の要素を指す。
+
+    a[ 1, 2, -1 ]	要素の取り出し。負数は最後から数える(-1が最後)
+			要素指定の次元は縮約される。
+    a[ 0..3, 4..1 ]	範囲取り出し。範囲の最後が最初より前ならば逆順になる。
+    a[ [1,4,2] ]	インデックス配列。要素が[a[1],a[4],a[2]]のNArrayが返る。
+    a[]			a.dup と同じ。
+    a[ 0, true ]	a[0, 0..-1] と同じ。
+    a[ 0, false ]	aが3次元のとき、a[0,true,true] と同じ。
+			省略された次元すべてにtrueを指定したのと同じ。
+    a[ mask ]		マスキング. mask は長さが a と等しい byte 型
+			NArray. mask の各要素の値に応じて、a のそれぞ
+			れは落される(0の場合)か、保持される(0以外の場合)。
+			例:
+				a=NArray.float(2,2).indgen!
+				p a[ a.lt 3 ]
+				--> [ 0.0, 1.0, 2.0 ]
+				(a.lt 3 は byte 型 NArray を返す)
+				(同じことは a[ (a.lt 3).where ] でも出来る)
+
+  -- self.slice(...)	self[...] と同じだが、長さが1になった次元を落
+			さず(self[]は落す)、もとのランクを保つ。但し、
+			1次元インデックス付けとマスキングは例外([]と同
+			じ)。
+
+インデックス代入。-- 取出しとほぼ同じルール。
+
+    a[ 1, 2, 3 ] = 1
+    a[ 0..3, 1..4, 2..5 ] = 2
+    a[ [1,3,2,4], true ] = 3
+    a[] = 4			a.fill!(4) と同じ。
+
+    a[0..2]  = b[1..5]		--> 要素数が異なるのでエラー。
+    a[1,2]   = b[0..2,1..3]	[1,2]を始点として代入。
+    a[0..2,0..3]  = b[0..2,1]	繰り返し代入。
+				( a[0,0]=b[0,1],..,a[0,3]=b[0,1] )
+
+行・列の削除 -- インデックス取り出しの逆
+
+    self.delete_at(...)	  引数はインデクス参照と同じ。
+			  参照: https://github.com/masa16/narray/issues/5
+
+値のセット。
+    self.indgen!([start[,step]]) startからstepづつ増加した値をセット。
+    self.fill!(value)		 すべての要素にvalueをセット。
+    self.random!(max)		 0<=x<max の一様なランダム値を生成。
+				 using MT19337
+    self.randomn		 平均0、分散1の正規分布のランダム値を生成。
+				 (Box-Muller)
+    NArray.srand([seed])	 乱数のシードを設定。
+				 省略時は時刻から自動生成。
+
+演算: 要素ごとにおこなう。
+    a = NArray.float(3,3).indgen
+    b = NArray.float(3,3).fill(10)
+    c = a*b	# --> NArray.float(3,3)
+
+    a = NArray.float(3,1).indgen
+    b = NArray.float(1,3).fill(10)
+    c = a*b	# --> NArray.float(3,3) -- size=1の次元は拡張する。
+
+算術演算子
+    -self
+    self + other
+    self - other
+    self * other
+    self / other
+    self % other
+    self ** other
+    self.abs
+
+    self.add! other
+    self.sbt! other
+    self.mul! other
+    self.div! other
+    self.mod! other
+
+    self.mul_add(other,dim,...)   (self * other).sum(dim,...)とほぼ同じ。
+				  ただし途中で配列を作らない。
+
+ビット演算子(整数のみ可能)
+    ~self
+    self & other
+    self | other
+    self ^ other
+
+比較
+  -- 要素ごとに値を比較し、結果をBYTE型 NArrayを返す。
+     true/falseでないことに注意。
+    self.eq other ( == とは異なることに注意)
+    self.ne other
+    self.gt other
+    self >  other
+    self.ge other
+    self >= other
+    self.lt other
+    self <  other
+    self.le other
+    self <= other
+
+    self.and other  要素ごとの条件比較。
+    self.or  other
+    self.xor other
+    self.not other
+
+    self.all?     要素がすべて真ならば真。
+    self.any?     要素のどれかが真ならば真。
+    self.none?    要素のどれかが真ならば真。
+    self.where	  要素が真のインデックス配列を返す。
+    self.where2	  要素が真と偽のインデックス配列を含む(Ruby)配列を返す。
+
+	例: idx_t,idx_f = (a>12).where2
+
+同値性
+    NArray[1] == NArray[1]      #=> true
+    NArray[1] == NArray[1.0]    #=> true
+    NArray[1].eql? NArray[1]    #=> true
+    NArray[1].eql? NArray[1.0]  #=> false
+    NArray[1].equal? NArray[1]  #=> false
+    a=b=NArray[1]; a.equal? b   #=> true
+
+統計
+    self.sum(dim,..)	    指定した次元の和
+    self.cumsum	            累積和(1次元配列のみ)
+    self.prod(dim,..)	    指定した次元の積
+    self.cumprod	    累積積(1次元配列のみ)
+    self.mean(dim,..)       指定した次元の平均。
+    self.stddev(dim,..)     指定した次元の標準偏差(標本標準偏差)。
+    self.rms(dim,..)        指定した次元のroot mean square。
+    self.rmsdev(dim,..)     指定した次元のroot mean square deviation。
+    self.min(dim,..)        指定した次元の最小。
+    self.max(dim,..)        指定した次元の最大。
+			    (省略時は全ての次元。Range指定可。)
+    self.median(dim)	    0..dimの次元の中央値。省略時はすべての次元。
+
+ソート
+    self.sort(dim)	     0..dimの次元でソート。省略時はすべての次元。
+    self.sort_index(dim)     ソートしたインデックスを返す。
+			     self[self.sort_index] は self.sort と同等。
+
+転置
+    self.transpose( dim0, dim1, .. )
+	配列の転置。selfの第(dim0)次元が新しい配列の第0次元になる。
+	負数は後からの順番。
+	transpose(-1,1..-2,0) で最初と最後を入れ換え。
+
+インデックスの変更 (要素数は不変)
+    self.reshape!(size,...)
+    self.shape= size,...
+    self.newdim!(dim,...)	指定位置にサイズ1の次元を挿入する。
+
+データの参照
+    self.refer			selfのデータを参照する別のオブジェクトを作成。
+    self.reshape(size,...)	self.refer.reshape! と同様。
+    self.newdim(dim,...)	self.refer.newdim! と同様。
+
+反転・回転
+    self.reverse([dim,...])	指定した次元を逆順にする
+    self.rot90([k])		2次元配列の90度の回転をk回行う
+
+型変換
+    self.floor selfより小さい最大の整数を返す。
+    self.ceil  selfより大きい最小の整数を返す。
+    self.round selfにもっとも近い整数を返す。
+    self.to_f  値を浮動小数点数に変換する。
+    self.to_i  値を整数に変換する。
+    self.to_a  値をRubyの配列に変換する。
+    self.to_s  バイナリデータをそのままRubyの文字列データに変換する。
+    self.to_string  各要素を文字列に変換する。
+
+イテレータ
+    self.each {|i| ...}
+    self.collect {|i| ...}
+    self.collect! {|i| ...}
+
+バイトスワップ
+    self.swap_byte	バイトスワップ
+    self.hton		ネットワークバイトオーダーに変換
+    self.ntoh
+    self.htov		VAXバイトオーダーに変換
+    self.vtoh
+
+Boolean / マスク関係
+    self.count_false	値 == 0 の要素数 (byte型のみ)
+    self.count_true	値 == 1 の要素数 (byte型のみ)
+    self.mask( mask )	self[ mask ] と同じだかマスキング専用.
+			[] と違い int, sint のマスクも使える.
+
+複素数
+    self.real
+    self.imag
+    self.conj
+    self.conj!
+    self.angle		atan2(self.imag, self.real)
+    self.imag= other	虚数部分にotherをセット。
+    self.im		虚数倍。
+
+NMath モジュール
+    sqrt(x)
+    exp(x)
+    log(x)
+    log10(x)
+    log2(x)
+    atan2(x,y)
+    sin,cos,tan
+    sinh,cosh,tanh
+    asin,acos,atan
+    asinh,acosh,atanh
+    csc,sec,cot
+    csch,sech,coth
+    acsc,asec,acot
+    acsch,asech,acoth
+    covariance
+
+
+FFTW モジュール (fftw-2.1.3をshared libでコンパイルしたもので確認)
+ (別モジュール)
+    fftw(x,[1|-1])
+    convol(a,b)		FFTWを用いた畳み込み。
+
+
+NMatrix
+
+  NArrayのサブクラス。最初の2次元をMatrixとして用いる。
+  残りの次元は多次元配列として扱われる。
+  次元の順序は、数学での表記とは逆:  a_ij => a[j,i]
+
+  メソッド:
+    +,-	 相手が NMatrix のときに演算可。
+    *	 相手が NMatrix または NVector のときは Matrix積。
+	 相手が Numeric または NArray のときは Scalar積。
+	 例: NMatrix[[1,2],[3,4]] * [1,10]
+	       == NMatrix[ [[1,2],[3,4]], [[10,20],[30,40]] ]
+    /	 相手が Numeric または NArray のときはScalar除算。
+	 相手が square NMatrix のときはLUにより線形方程式を解く。
+	 a/b == b.lu.solve(a)
+
+    transpose		引数を省略した場合は、最初のMatrix次元を交換。
+    diagonal(other)
+    diagonal!(other)	対角要素に値をセット。引数省略時は1をセット。
+    I			対角要素に値に1をセット。
+    inverse		逆行列
+    lu			LU分解を計算。NMatrixLU クラスのインスタンスを返す。
+
+
+NVector
+
+  NArrayのサブクラス。最初の1次元をVectorとして用いる。
+  残りの次元は多次元配列として扱われる。
+
+  メソッド:
+    +,-	 相手が NVector のときに演算可。
+    *	 相手が NMatrix のときは Matrix積。
+    	 相手が NVector のときは 内積。
+	 相手が Numeric または NArray のときは Scalar積。
+    /	 相手が Numeric または NArray のときは Scalar除算。
+	 相手が square NMatrix のときはLUにより線形方程式を解く。
+	 v/m == m.lu.solve(v)
+
+NMatrixLU
+
+  NMatrix#lu メソッドにより作られる。
+  LU (NMatrix) と pivot (NVector) を含む。
+
+  メソッド:
+    solve(other)	LU分解の結果を使って other を解く。
+			other は NMatrix または NVector のインスタンス。
diff --git a/app/server/vendor/narray-0.6.1.1/bench/all.rb b/app/server/vendor/narray-0.6.1.1/bench/all.rb
new file mode 100755
index 0000000..c226712
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/bench/all.rb
@@ -0,0 +1,90 @@
+require "narray"
+T = (RUBY_VERSION<"1.8.0") ? Time : Process
+
+ruby_narray = system( "ruby -r narray dummy.rb" )
+python_numeric = system( "python dummy.py numeric" )
+python_numarray = system( "python dummy.py numarray" )
+python_numpy = system( "python dummy.py numpy" )
+octave = system( "octave -qf dummy.m" )
+
+def array_size
+  list = [
+    100000, 200000, 500000,
+    1000000, 2000000, 5000000,
+    10000000, 20000000, 50000000
+  ]
+  mlist = [
+    150, 200, 300, 500, 700, 1000, 1500, 2000, 3000
+    #300, 400, 700, 1000, 1400, 2000, 3000, 4000, 7000
+  ]
+
+  r = 50
+  m = nil
+  j = nil
+  list.each_with_index do |n,i|
+    a = NArray.float(n)
+    b = NArray.float(n)
+    t = bench_time(r) { c = a+b }
+    j = i
+    m = n
+    break if t>0.5
+  end
+  [m, mlist[j], r*2]
+end
+
+def bench_time(n)
+  t1 = T.times.utime
+   for i in 1..n
+     yield
+   end
+  t = T.times.utime - t1
+  puts " Time: %.2f sec\n" % [t]
+  t
+end
+
+n,m,r = array_size
+puts "array size = #{n}, repeat = #{r}\n\n"
+
+system "ruby   bench.rb          float  mul #{n} #{r}" if ruby_narray
+system "python bench.py numeric  float  mul #{n} #{r}" if python_numeric
+system "python bench.py numarray float  mul #{n} #{r}" if python_numarray
+system "python bench.py numpy    float  mul #{n} #{r}" if python_numpy
+system "octave -qf bench.m       float  mul #{n} #{r}" if octave
+puts
+
+system "ruby   bench.rb          int  add #{n} #{r}" if ruby_narray
+system "python bench.py numeric  int  add #{n} #{r}" if python_numeric
+system "python bench.py numarray int  add #{n} #{r}" if python_numarray
+system "python bench.py numpy    int  add #{n} #{r}" if python_numpy
+system "octave -qf bench.m       int  add #{n} #{r}" if octave
+puts
+
+system "ruby   bench.rb          complex  mul #{n} #{r}" if ruby_narray
+system "python bench.py numeric  complex  mul #{n} #{r}" if python_numeric
+system "python bench.py numarray complex  mul #{n} #{r}" if python_numarray
+system "python bench.py numpy    complex  mul #{n} #{r}" if python_numpy
+system "octave -qf bench.m       complex  mul #{n} #{r}" if octave
+puts
+
+system "ruby   bench.rb          float_cross mul    #{m*2} #{r}" if ruby_narray
+system "python bench.py numeric  float_cross mul    #{m*2} #{r}" if python_numeric
+system "python bench.py numarray float_cross mul    #{m*2} #{r}" if python_numarray
+system "python bench.py numpy    float_cross mul    #{m*2} #{r}" if python_numpy
+system "octave -qf bench.m       float_cross matmul #{m*2} #{r}" if octave
+puts
+
+system "ruby   bench.rb          float_matrix mul    #{m} 4" if ruby_narray
+system "python bench.py numeric  float_matrix matmul #{m} 4" if python_numeric
+system "python bench.py numarray float_matrix matmul #{m} 4" if python_numarray
+system "python bench.py numpy    float_matrix matmul #{m} 4" if python_numpy
+system "octave -qf bench.m       float_matrix matmul #{m} 4" if octave
+puts
+
+system "ruby   bench.rb          float_solve solve #{m} 2" if ruby_narray
+system "python bench.py numeric  float_solve solve #{m} 2" if python_numeric
+system "python bench.py numarray float_solve solve #{m} 2" if python_numarray
+system "python bench.py numpy    float_solve solve #{m} 2" if python_numpy
+system "octave -qf bench.m       float_solve solve #{m} 2" if octave
+puts
+
+exit
diff --git a/app/server/vendor/narray-0.6.1.1/bench/bench.m b/app/server/vendor/narray-0.6.1.1/bench/bench.m
new file mode 100755
index 0000000..812c1c9
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/bench/bench.m
@@ -0,0 +1,61 @@
+#! /bin/octave -qf
+
+arg_list = argv();
+TYPE   = arg_list{1};
+OP     = arg_list{2};
+ARRSZ  = str2num(arg_list{3});
+REPEAT = str2num(arg_list{4});
+n = ARRSZ;
+
+switch(TYPE)
+  case "float"
+    a = linspace(0,n-1,n);
+    b = linspace(0,n-1,n);
+  case "int"
+    a = int32(linspace(0,n-1,n));
+    b = int32(linspace(0,n-1,n));
+  case "complex"
+    a = complex(linspace(0,n-1,n));
+    b = complex(linspace(0,n-1,n));
+  case "float_cross"
+    a = linspace(0,n-1,n)';
+    b = linspace(0,n-1,n);
+  case "float_matrix"
+    a = linspace(0,n*n-1,n*n);
+    a = rem(a, n+1) + 1;
+    a = reshape(a,n,n);
+    b = linspace(0,n*n-1,n*n);
+    b = rem(b, n-1) + 1;
+    b = reshape(b,n,n);
+  case "float_solve"
+    a = linspace(0,n*n-1,n*n);
+    a = rem(a, n+1) + 1;
+    a = reshape(a,n,n);
+    b = reshape(linspace(1,n*n,n*n),n,n);
+endswitch
+
+[t1, u1, s1] = cputime ();
+switch(OP)
+  case "add"
+    for i = 1:REPEAT
+      c = a + b;
+    endfor
+  case "mul"
+    for i = 1:REPEAT
+      c = a .* b;
+    endfor
+  case "matmul"
+    for i = 1:REPEAT
+      c = a * b;
+    endfor
+    #size(c)
+  case "solve"
+    for i = 1:REPEAT
+      c = a \ b;
+    endfor
+    #size(c)
+endswitch
+[t2, u2, s2] = cputime ();
+
+printf ("Octave type=%s size=%d op=%s repeat=%d  Time: %.2f sec", 
+	TYPE,ARRSZ,OP,REPEAT,u2 - u1);
diff --git a/app/server/vendor/narray-0.6.1.1/bench/bench.py b/app/server/vendor/narray-0.6.1.1/bench/bench.py
new file mode 100755
index 0000000..0b759ae
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/bench/bench.py
@@ -0,0 +1,91 @@
+import time
+import sys
+
+MODULE = sys.argv[1]
+TYPE   = sys.argv[2]
+OP     = sys.argv[3]
+ARRSZ  = int(sys.argv[4])
+REPEAT = int(sys.argv[5])
+
+if MODULE=="numeric":
+    from Numeric import *
+    from LinearAlgebra import *
+elif MODULE=="numarray":
+    from numarray import *
+    from LinearAlgebra import *
+elif MODULE=="numpy":
+    from numpy import *
+    from numpy.linalg import solve
+
+def bench_time(func,repeat=REPEAT):
+  #start = time.clock()
+  start = time.time()
+  for i in range(repeat):
+    c = func()
+  #stop = time.clock()
+  stop = time.time()
+  print "Python %s type=%s size=%d op=%s repeat=%d  Time: %.6f sec" % \
+      (MODULE,TYPE,ARRSZ,OP,REPEAT,stop-start)
+  #print shape(c)
+
+n = ARRSZ
+
+if MODULE=="numpy":
+    def bench_array(type=float):
+        return arange(ARRSZ,dtype=type)
+
+    if TYPE=="float":
+        a = bench_array(float)
+        b = bench_array(float)
+    elif TYPE=="int":
+        a = bench_array(int)
+        b = bench_array(int)
+    elif TYPE=="complex":
+        a = bench_array(complex)
+        b = bench_array(complex)
+    elif TYPE=="float_cross":
+        a = reshape(arange(ARRSZ,dtype=float),(ARRSZ,1))
+        b = reshape(arange(ARRSZ,dtype=float),(1,ARRSZ))
+    elif TYPE=="float_matrix":
+        a = reshape(arange(ARRSZ**2,dtype=float),(ARRSZ,ARRSZ))
+        b = reshape(arange(ARRSZ**2,dtype=float),(ARRSZ,ARRSZ))
+    elif TYPE=="float_solve":
+        a = reshape(arange(n**2,dtype=float)%(n+1)+1,(n,n))
+        b = reshape(arange(n**2,dtype=float)+1,(n,n))
+else:
+    def bench_array(type=float):
+        return arrayrange(ARRSZ).astype(type)
+    if TYPE=="float":
+        a = bench_array(Float64)
+        b = bench_array(Float64)
+    elif TYPE=="int":
+        a = bench_array(Int32)
+        b = bench_array(Int32)
+    elif TYPE=="complex":
+        a = bench_array(Complex64)
+        b = bench_array(Complex64)
+    elif TYPE=="float_cross":
+        a = reshape(arrayrange(ARRSZ),(ARRSZ,1)).astype(Float64)
+        b = reshape(arrayrange(ARRSZ),(1,ARRSZ)).astype(Float64)
+    elif TYPE=="float_matrix":
+        a = reshape(arrayrange(ARRSZ**2),(ARRSZ,ARRSZ)).astype(Float64)
+        b = reshape(arrayrange(ARRSZ**2),(ARRSZ,ARRSZ)).astype(Float64)
+    elif TYPE=="float_solve":
+        a = reshape(arrayrange(n*n)%(n+1)+1,(n,n)).astype(Float64)
+        b = reshape(arrayrange(n*n)+1,(n,n)).astype(Float64)
+    dot = matrixmultiply
+    solve = solve_linear_equations
+
+def lambda_add(a=a,b=b):    c = a+b; return c;
+def lambda_mul(a=a,b=b):    c = a*b; return c;
+def lambda_matmul(a=a,b=b): c = dot(a,b); return c;
+def lambda_solve(a=a,b=b):  c = solve(a,b); return c;
+
+if OP=="add":
+    bench_time(lambda_add)
+elif OP=="mul":
+    bench_time(lambda_mul)
+elif OP=="matmul":
+    bench_time(lambda_matmul)
+elif OP=="solve":
+    bench_time(lambda_solve)
diff --git a/app/server/vendor/narray-0.6.1.1/bench/bench.rb b/app/server/vendor/narray-0.6.1.1/bench/bench.rb
new file mode 100755
index 0000000..b805ee1
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/bench/bench.rb
@@ -0,0 +1,59 @@
+require 'narray'
+T = (RUBY_VERSION<"1.8.0") ? Time : Process
+
+TYPE   = ARGV[0]
+OP     = ARGV[1]
+ARRSZ  = Integer(ARGV[2])
+REPEAT = Integer(ARGV[3])
+
+def bench_array(type=Float)
+  [ NArray.new(type,ARRSZ).indgen!,
+    NArray.new(type,ARRSZ).indgen!  ]
+end
+
+def bench_time(n=REPEAT)
+  t1 = T.times.utime
+   for i in 1..n
+     yield
+   end
+  t = T.times.utime - t1
+  printf "Ruby NArray type=%s size=%d op=%s repeat=%d  Time: %.2f sec\n",
+    TYPE,ARRSZ,OP,REPEAT,t
+end
+
+n = ARRSZ
+
+case TYPE
+when "float"
+  a,b = bench_array(Float)
+when "int"
+  a,b = bench_array(Integer)
+when "complex"
+  a,b = bench_array(Complex)
+when "float_cross"
+  a = NArray.float(n,1).indgen!
+  b = NArray.float(1,n).indgen!
+when "float_matrix"
+  a = NArray.float(n,n).indgen!
+  a = a % (n+1) + 1
+  a = NMatrix.ref(a)#.transpose
+  b = NArray.float(n,n).indgen!
+  b = b % (n-1) + 1
+  b = NMatrix.ref(b)#.transpose
+when "float_solve"
+  a = NMatrix.float(n,n).indgen!(1).transpose
+  b = NArray.float(n,n).indgen!
+  b = b % (n+1) + 1
+  b = NMatrix.ref(b).transpose
+end
+
+c = 0
+
+case OP
+when "add"
+  bench_time{ c = a+b }
+when "mul"
+  bench_time{ c = a*b }
+when "solve"
+  bench_time{ c = a/b }
+end
diff --git a/app/server/vendor/narray-0.6.1.1/bench/dummy.m b/app/server/vendor/narray-0.6.1.1/bench/dummy.m
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/narray-0.6.1.1/bench/dummy.py b/app/server/vendor/narray-0.6.1.1/bench/dummy.py
new file mode 100755
index 0000000..a925ea9
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/bench/dummy.py
@@ -0,0 +1,13 @@
+import sys
+
+MODULE = sys.argv[1]
+
+if MODULE=="numeric":
+    from Numeric import *
+    from LinearAlgebra import *
+elif MODULE=="numarray":
+    from numarray import *
+    from LinearAlgebra import *
+elif MODULE=="numpy":
+    from numpy import *
+    from numpy.linalg import solve
diff --git a/app/server/vendor/narray-0.6.1.1/bench/dummy.rb b/app/server/vendor/narray-0.6.1.1/bench/dummy.rb
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/narray-0.6.1.1/depend b/app/server/vendor/narray-0.6.1.1/depend
new file mode 100755
index 0000000..1d48ba8
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/depend
@@ -0,0 +1,14 @@
+na_op.c: mknafunc.rb mkop.rb
+	$(RUBY) -I$(srcdir) $(srcdir)/mkop.rb
+
+na_op.o: na_op.c narray.h $(hdrdir)/ruby.h
+
+
+na_math.c: mknafunc.rb mkmath.rb
+	$(RUBY) -I$(srcdir) $(srcdir)/mkmath.rb
+
+na_math.o: na_math.c narray.h $(hdrdir)/ruby.h
+
+
+cleanall:  clean
+	@$(RM) -r Makefile narray_config.h na_op.c na_math.c src pkg
diff --git a/app/server/vendor/narray-0.6.1.1/extconf.rb b/app/server/vendor/narray-0.6.1.1/extconf.rb
new file mode 100755
index 0000000..71fff3f
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/extconf.rb
@@ -0,0 +1,100 @@
+require "mkmf"
+
+def have_type(type, header=nil)
+  printf "checking for %s... ", type
+  STDOUT.flush
+  src = <<"SRC"
+#include <ruby.h>
+SRC
+  unless header.nil?
+  src << <<"SRC"
+#include <#{header}>
+SRC
+  end
+  r = try_link(src + <<"SRC")
+  int main() { return 0; }
+  int t() { #{type} a; return 0; }
+SRC
+  unless r
+    print "no\n"
+    return false
+  end
+  $defs.push(format("-DHAVE_%s", type.upcase))
+  print "yes\n"
+  return true
+end
+
+def create_conf_h(file)
+  print "creating #{file}\n"
+  hfile = open(file, "w")
+  for line in $defs
+    line =~ /^-D(.*)/
+    hfile.printf "#define %s 1\n", $1
+  end
+  hfile.close
+end
+
+if RUBY_VERSION < '1.8'
+  alias __install_rb :install_rb
+  def install_rb(mfile, dest, srcdir = nil)
+    __install_rb(mfile, dest, srcdir)
+    archdir = dest.sub(/sitelibdir/,"sitearchdir").sub(/rubylibdir/,"archdir")
+    path = ['$(srcdir)/narray.h','narray_config.h']
+    path << ['libnarray.a'] if /cygwin|mingw/ =~ RUBY_PLATFORM
+    for f in path
+      mfile.printf "\t@$(RUBY) -r ftools -e 'File::install(ARGV[0], ARGV[1], 0644, true)' %s %s\n", f, archdir
+    end
+  end
+else
+  $INSTALLFILES = [['narray.h', '$(archdir)'], ['narray_config.h', '$(archdir)']]
+  if /cygwin|mingw/ =~ RUBY_PLATFORM
+	 $INSTALLFILES << ['libnarray.a', '$(archdir)']
+  end
+end
+
+if /cygwin|mingw/ =~ RUBY_PLATFORM
+  if RUBY_VERSION >= '1.9.0'
+    $DLDFLAGS << " -Wl,--export-all,--out-implib=libnarray.a"
+  elsif RUBY_VERSION > '1.8.0'
+    $DLDFLAGS << ",--out-implib=libnarray.a"
+  elsif RUBY_VERSION > '1.8'
+    CONFIG["DLDFLAGS"] << ",--out-implib=libnarray.a"
+    system("touch libnarray.a")
+  else
+    CONFIG["DLDFLAGS"] << " --output-lib libnarray.a"
+  end
+end
+
+#$DEBUG = true
+#$CFLAGS = ["-Wall",$CFLAGS].join(" ")
+
+srcs = %w(
+narray
+na_array
+na_func
+na_index
+na_random
+na_op
+na_math
+na_linalg
+)
+
+header = "stdint.h"
+unless have_header(header)
+  header = "sys/types.h"
+  unless have_header(header)
+    header = nil
+  end
+end
+
+have_type("u_int8_t", header)
+have_type("uint8_t", header)
+have_type("int16_t", header)
+have_type("int32_t", header)
+have_type("u_int32_t", header)
+have_type("uint32_t", header)
+
+$objs = srcs.collect{|i| i+".o"}
+
+create_conf_h("narray_config.h")
+create_makefile("narray")
diff --git a/app/server/vendor/narray-0.6.1.1/lib/narray_ext.rb b/app/server/vendor/narray-0.6.1.1/lib/narray_ext.rb
new file mode 100755
index 0000000..643c4fd
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/lib/narray_ext.rb
@@ -0,0 +1,362 @@
+#  Numerical Array Extention for Ruby
+#    (C) Copyright 2000-2008 by Masahiro TANAKA
+#
+#  This program is free software.
+#  You can distribute/modify this program
+#  under the same terms as Ruby itself.
+#  NO WARRANTY.
+#
+class NArray
+
+  def self.cast(array,type=nil)
+    case array
+    when NArray
+    when Array
+      array = NArray.to_na(array)
+    else
+      raise ArgumentError, "1st argument must be NArray or Array"
+    end
+    type = array.typecode if type.nil?
+    shape = array.shape
+    na = self.new(type,*shape)
+    na[] = array
+    na
+  end
+
+  def integer?
+    self.typecode==NArray::BYTE ||
+    self.typecode==NArray::SINT ||
+    self.typecode==NArray::LINT
+  end
+  def complex?
+    self.typecode==NArray::DCOMPLEX ||
+    self.typecode==NArray::SCOMPLEX
+  end
+
+  def all?
+    where.size == size
+  end
+
+  def any?
+    where.size > 0
+  end
+
+  def none?
+    where.size == 0
+  end
+
+  def ==(other)
+    other.kind_of?(NArray) &&
+      shape == other.shape && 
+      eq(other).all?
+  end
+
+  def eql?(other)
+    self.class == other.class &&
+      typecode == other.typecode &&
+      shape == other.shape &&
+      case typecode
+      when NArray::OBJECT
+	to_a.eql? other.to_a
+      else
+	to_s.eql? other.to_s
+      end
+  end
+
+  def hash
+    case typecode
+    when NArray::OBJECT
+      [self.class, to_a].hash
+    else
+      [self.class, typecode, shape, to_s].hash
+    end
+  end
+
+  def rank_total(*ranks)
+    if ranks.size>0
+      idx = []
+      ranks.each{|i| idx.push(*i)}
+      # ranks is expected to be, e.g., [1, 3..5, 7]
+      a = self.shape
+      n = 1
+      idx.each{|i| n *= a[i]}
+      n
+    else
+      self.total
+    end
+  end
+
+  # delete rows/columns
+  def delete_at(*args)
+    if args.size > self.rank
+      raise ArgumentError, "too many arguments"
+    end
+    shp = self.shape
+    ind = []
+    self.rank.times do |i|
+      n = shp[i]
+      case a=args[i]
+      when Integer
+        a = n+a if a<0
+        raise IndexError, "index(%d) out of range"%[a] if a<0
+        x = [0...a,a+1...n]
+      when Range
+        b = a.first
+        b = n+b if b<0
+        raise IndexError, "index(%s) out of range"%[a] if b<0
+        e = a.last
+        e = n+e if e<0
+        e -= 1 if a.exclude_end?
+        raise IndexError, "index(%s) out of range"%[a] if e<0
+        x = [0...b,e+1...n]
+      when Array
+        x = (0...n).to_a
+        x -= a.map do |j|
+          raise IndexError, "contains non-integer" unless Integer===j
+          (j<0) ? n+j : j
+        end
+      else
+        if a
+          raise ArgumentError, "invalid argument"
+        else
+          x = true
+        end
+      end
+      ind << x
+    end
+    self[*ind]
+  end
+
+# Statistics
+  def mean(*ranks)
+    if integer?
+      a = self.to_type(NArray::DFLOAT)
+    else
+      a = self
+    end
+    a = NArray.ref(a)
+    a.sum(*ranks) / (rank_total(*ranks))
+  end
+
+  def stddev(*ranks)
+    if integer?
+      a = self.to_type(NArray::DFLOAT)
+    else
+      a = self
+    end
+    a = NArray.ref(a)
+    n = rank_total(*ranks)
+    if complex?
+      NMath::sqrt( (( a-a.accum(*ranks).div!(n) ).abs**2).sum(*ranks)/(n-1) )
+    else
+      NMath::sqrt( (( a-a.accum(*ranks).div!(n) )**2).sum(*ranks)/(n-1) )
+    end
+  end
+
+  def rms(*ranks)
+    if integer?
+      a = self.to_type(NArray::DFLOAT)
+    else
+      a = self
+    end
+    a = NArray.ref(a)
+    n = rank_total(*ranks)
+    if complex?
+      NMath::sqrt( (a.abs**2).sum(*ranks)/n )
+    else
+      NMath::sqrt( (a**2).sum(*ranks)/n )
+    end
+  end
+
+  def rmsdev(*ranks)
+    if integer?
+      a = self.to_type(NArray::DFLOAT)
+    else
+      a = self
+    end
+    a = NArray.ref(a)
+    n = rank_total(*ranks)
+    if complex?
+      NMath::sqrt( (( a-a.accum(*ranks).div!(n) ).abs**2).sum(*ranks)/n )
+    else
+      NMath::sqrt( (( a-a.accum(*ranks).div!(n) )**2).sum(*ranks)/n )
+    end
+  end
+
+  def median(rank=nil)
+    shape = self.shape
+    rank = shape.size-1 if rank==nil
+    s = sort(rank).reshape!(true,*shape[rank+1..-1])
+    n = s.shape[0]
+    if n%2==1
+      s[n/2,false]
+    else
+      s[n/2-1..n/2,false].sum(0)/2
+    end
+  end
+
+
+# Normal distributed random number;  valid for floating point types
+  def randomn
+    size = self.size
+    case type = self.typecode
+    when COMPLEX; type=FLOAT
+    when SCOMPLEX; type=SFLOAT
+    when FLOAT
+    when SFLOAT
+    else
+      raise TypeError, "NArray type must be (S)FLOAT or (S)COMPLEX."
+    end
+    rr = NArray.new(type,size)
+    xx = NArray.new(type,size)
+    i = 0
+    while i < size
+      n = size-i
+      m = ((n+Math::sqrt(n))*1.27).to_i
+      x = NArray.new(type,m).random!(1) * 2 - 1
+      y = NArray.new(type,m).random!(1) * 2 - 1
+      r = x**2 + y**2
+      idx = (r<1).where
+      idx = idx[0...n] if idx.size > n
+      if idx.size>0
+	rr[i] = r[idx]
+	xx[i] = x[idx]
+	i += idx.size
+      end
+    end
+    # Box-Muller transform
+    rr = ( xx * NMath::sqrt( -2 * NMath::log(rr) / rr ) )
+    # finish
+    rr.reshape!(*self.shape) if self.rank > 1
+    rr = rr.to_type(self.typecode) if type!=self.typecode
+    if RUBY_VERSION < "1.8.0"
+      self.type.refer(rr)
+    else
+      self.class.refer(rr)
+    end
+  end
+  #alias randomn! randomn
+
+  def randomn!
+    self[]= randomn
+    self
+  end
+
+  def reverse(*ranks)
+    if self.rank==0
+      return self.dup
+    elsif ranks.size==0
+      idx = (0...self.rank).map{-1..0}
+    else
+      idx = [true]*self.rank
+      ranks.each do |i|
+        if !i.kind_of?(Integer)
+          raise ArgumentError, "Argument must be Integer"
+        end
+        if i >= self.rank
+          raise ArgumentError, "dimension(%s) out of range"%[i]
+        end
+        idx[i] = -1..0
+      end
+    end
+    self[*idx]
+  end
+
+  def rot90(n_times=1)
+    if self.rank < 2
+      raise "must be >= 2 dimensional array"
+    end
+    case n_times%4
+    when 0
+      self.dup
+    when 1
+      self.transpose(1,0).reverse(0)
+    when 2
+      self.reverse(0,1)
+    when 3
+      self.transpose(1,0).reverse(1)
+    end
+  end
+
+  #SFloatOne = NArray.sfloat(1).fill!(1)
+end
+
+
+module NMath
+  PI = Math::PI
+  E = Math::E
+
+  def recip x
+    1/x.to_f
+  end
+
+# Trigonometric function
+  def csc x
+    1/sin(x)
+  end
+  def csch x
+    1/sinh(x)
+  end
+  def acsc x
+    asin(1/x.to_f)
+  end
+  def acsch x
+    asinh(1/x.to_f)
+  end
+
+  def sec x
+    1/cos(x)
+  end
+  def sech x
+    1/cosh(x)
+  end
+  def asec x
+    acos(1/x.to_f)
+  end
+  def asech x
+    acosh(1/x.to_f)
+  end
+
+  def cot x
+    1/tan(x)
+  end
+  def coth x
+    1/tanh(x)
+  end
+  def acot x
+    atan(1/x.to_f)
+  end
+  def acoth x
+    atanh(1/x.to_f)
+  end
+
+# Statistics
+  def covariance(x,y,*ranks)
+    x = NArray.to_na(x) unless x.kind_of?(NArray)
+    x = x.to_type(NArray::DFLOAT) if x.integer?
+    y = NArray.to_na(y) unless y.kind_of?(NArray)
+    y = y.to_type(NArray::DFLOAT) if y.integer?
+    n = x.rank_total(*ranks)
+    xm = x.accum(*ranks).div!(n)
+    ym = y.accum(*ranks).div!(n)
+    ((x-xm)*(y-ym)).sum(*ranks) / (n-1)
+  end
+
+  module_function :recip
+  module_function :csc,:sec,:cot,:csch,:sech,:coth
+  module_function :acsc,:asec,:acot,:acsch,:asech,:acoth
+  module_function :covariance
+end
+
+
+module FFTW
+  def convol(a1,a2)
+    n1x,n1y = a1.shape
+    n2x,n2y = a2.shape
+    raise "arrays must have same shape" if n1x!=n2x || n1y!=n2y
+    (FFTW.fftw( FFTW.fftw(a1,-1) * FFTW.fftw(a2,-1), 1).real) / (n1x*n1y)
+  end
+  module_function :convol
+end
+
+require 'nmatrix'
diff --git a/app/server/vendor/narray-0.6.1.1/lib/nmatrix.rb b/app/server/vendor/narray-0.6.1.1/lib/nmatrix.rb
new file mode 100755
index 0000000..4b6b102
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/lib/nmatrix.rb
@@ -0,0 +1,248 @@
+#  Numerical Array Extention for Ruby
+#    (C) Copyright 2000-2003 by Masahiro TANAKA
+#
+
+#
+# ------ NMatrix ------
+#
+class NMatrix < NArray
+  CLASS_DIMENSION = 2
+
+  def +(other)
+    case other
+    when NMatrix
+      return super(NArray.refer(other))
+    when NArray
+      unless other.instance_of?(NArray)
+        return other.coerce_rev( self, :+ )
+      end
+    end
+    raise TypeError,"Illegal operation: NMatrix + %s" % other.class
+  end
+
+  def -(other)
+    case other
+    when NMatrix
+      return super(NArray.refer(other))
+    when NArray
+      unless other.instance_of?(NArray)
+        return other.coerce_rev( self, :- )
+      end
+    end
+    raise TypeError,"Illegal operation: NMatrix - %s" % other.class
+  end
+
+  def *(other)
+    case other
+    when NMatrix
+      NMatrix.mul_add( NArray.refer(self).newdim!(0),other.newdim(2), 1 )
+      #NMatrix.mul_add( NArray.refer(self).newdim!(0),
+      #		       other.transpose(1,0).newdim!(2), 0 )
+    when NVector
+      NVector.mul_add( NArray.refer(self), other.newdim(1), 0 )
+    when NArray
+      if other.instance_of?(NArray)
+	NMatrix.mul( NArray.refer(self), other.newdim(0,0) )
+      else
+	other.coerce_rev( self, :* )
+      end
+    when Numeric
+      super
+      #NMatrix.mul( NArray.refer(self), other )
+    when Array
+      NMatrix.mul( self, NArray[*other].newdim!(0,0) )
+    else
+      raise TypeError,"Illegal operation: NMatrix * %s" % other.class
+    end
+  end
+
+  def /(other)
+    case other
+    when NMatrix
+      other.lu.solve(self)
+    when NVector
+      raise TypeError,"Illegal operation: NMatrix / %s" % other.class
+    when NArray
+      if other.instance_of?(NArray)
+	NMatrix.div( NArray.refer(self), other.newdim(0,0) )
+      else
+	other.coerce_rev( self, :/ )
+      end
+    when Numeric
+      NMatrix.div( NArray.refer(self), other )
+    when Array
+      NMatrix.div( self, NArray[*other].newdim!(0,0) )
+    else
+      raise TypeError,"Illegal operation: NMatrix / %s" % other.class
+    end
+  end
+
+  def **(n)
+    case n
+    when Integer
+      if n==0
+	return 1.0
+      elsif n<0
+	m = self.inverse
+	n = -n
+      else
+	m = self
+      end
+      (2..n).each{ m *= self }
+      m
+    else
+      raise TypeError,"Illegal operation: NMatrix ** %s" % n.class
+    end
+  end
+
+  def coerce_rev(other,id)
+    case id
+    when :*
+	if other.instance_of?(NArray)
+	  return NMatrix.mul( other.newdim(0,0), self )
+	end
+	if other.instance_of?(NArrayScalar)
+	  return NMatrix.mul( other.newdim(0), self )
+	end
+    when :/
+	if other.instance_of?(NArray)
+	  return NMatrix.mul( other.newdim(0,0), self.inverse )
+	end
+	if other.instance_of?(NArrayScalar)
+	  return NMatrix.mul( other.newdim(0), self.inverse )
+	end
+    end
+    raise TypeError,"Illegal operation: %s %s NMatrix" %
+      [other.class, id.id2name]
+  end
+
+  def inverse
+    self.lu.solve( NMatrix.new(self.typecode, *self.shape).fill!(0).unit )
+  end
+
+  def transpose(*arg)
+    if arg.size==0
+      super(1,0)
+    else
+      super
+    end
+  end
+
+  def diagonal!(val=1)
+    shp = self.shape
+    idx = NArray.int(shp[0..1].min).indgen! * (shp[0]+1)
+    ref = reshape(shp[0]*shp[1],true)
+    if val.kind_of?(Numeric)
+      ref[idx,true] = val
+    else
+      val = NArray.to_na(val)
+      raise ArgumentError, "must be 1-d array" if val.dim!=1
+      ref[idx,true] = val.newdim!(-1)
+    end
+    self
+  end
+
+  def diagonal(val)
+    self.dup.diagonal!(val)
+  end
+
+  def unit
+    diagonal!
+  end
+  alias identity unit
+  alias I unit
+
+end # class NMatrix
+
+
+#
+# ------ NVector ------
+#
+class NVector < NArray
+  CLASS_DIMENSION = 1
+
+  def +(other)
+    case other
+    when NVector
+      return super(NArray.refer(other))
+    when NArray
+      unless other.instance_of?(NArray)
+        return other.coerce_rev( self, :+ )
+      end
+    end
+    raise TypeError,"Illegal operation: NVector + %s" % other.class
+  end
+
+  def -(other)
+    case other
+    when NVector
+      return super(NArray.refer(other))
+    when NArray
+      unless other.instance_of?(NArray)
+        return other.coerce_rev( self, :- )
+      end
+    end
+    raise TypeError,"Illegal operation: NVector - %s" % other.class
+  end
+
+  def *(other)
+    case other
+    when NMatrix
+      NVector.mul_add( NArray.refer(self).newdim!(0), other, 1 )
+    when NVector
+      NArray.mul_add( NArray.refer(self), other, 0 ) # inner product
+    when NArray
+      if other.instance_of?(NArray)
+	NVector.mul( NArray.refer(self), other.newdim(0) )
+      else
+	other.coerce_rev( self, :* )
+      end
+    when Numeric
+      NVector.mul( NArray.refer(self), other )
+    else
+      raise TypeError,"Illegal operation: NVector * %s" % other.class
+    end
+  end
+
+  def /(other)
+    case other
+    when NMatrix
+      other.lu.solve(self)
+    when NVector
+      raise TypeError,"Illegal operation: NVector / %s" % other.class
+    when NArray
+      if other.instance_of?(NArray)
+	NVector.div( NArray.refer(self), other.newdim(0) )
+      else
+	other.coerce_rev( self, :/ )
+      end
+    when Numeric
+      NVector.div( NArray.refer(self), other )
+    else
+      raise TypeError,"Illegal operation: NVector / %s" % other.class
+    end
+  end
+
+  def **(n)
+    if n==2
+      self*self
+    else
+      raise ArgumentError,"Only v**2 is implemented"
+    end
+  end
+
+  def coerce_rev(other,id)
+    case id
+    when :*
+	if other.instance_of?(NArray)
+	  return NVector.mul( other.newdim(0), self )
+	end
+	if other.instance_of?(NArrayScalar)
+	  return NVector.mul( other, self )
+	end
+    end
+    raise TypeError,"Illegal operation: %s %s NVector" %
+      [other.class, id.id2name]
+  end
+
+end # class NVector
diff --git a/app/server/vendor/narray-0.6.1.1/mkmath.rb b/app/server/vendor/narray-0.6.1.1/mkmath.rb
new file mode 100755
index 0000000..e4a48e6
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/mkmath.rb
@@ -0,0 +1,784 @@
+require "mknafunc"
+
+# File name
+fname = "na_math.c"
+$> = open(fname,"w")
+
+print <<EOM
+/*
+  #{fname}
+  Automatically generated code
+  Numerical Array Extention for Ruby
+    (C) Copyright 1999-2008 by Masahiro TANAKA
+
+  This program is free software.
+  You can distribute/modify this program
+  under the same terms as Ruby itself.
+  NO WARRANTY.
+*/
+#include <ruby.h>
+#include "narray.h"
+#include "narray_local.h"
+
+#ifndef M_LOG2E
+#define M_LOG2E         1.4426950408889634074
+#endif
+#ifndef M_LOG10E
+#define M_LOG10E        0.43429448190325182765
+#endif
+
+VALUE rb_mNMath;
+
+static void TpErr(void) {
+    rb_raise(rb_eTypeError,"illegal operation with this type");
+}
+
+#if 0
+void sincos(double x, double *s, double *c)
+{
+  *s=sin(x); *c=cos(x);
+}
+
+#ifndef HAVE_ACOSH
+static double rb_log1p (const double x)
+{
+  double y;
+  y = 1+x;
+
+  if (y==1)
+     return x;
+  else
+     return log(y)*(x/(y-1));
+}
+
+static double zero=0;
+
+static double acosh(double x)
+{
+   /* acosh(x) = log(x+sqrt(x*x-1)) */
+   if (x>2) {
+      return log(2*x-1/(sqrt(x*x-1)+x));
+   } else if (x>=1) {
+      x-=1;
+      return rb_log1p(x+sqrt(2*x+x*x));
+   }
+   return zero/(x-x); /* x<1: NaN */
+}
+
+static double asinh(double x)
+{
+   double a, x2;
+   int neg;
+
+   /* asinh(x) = log(x+sqrt(x*x+1)) */
+   neg = x<0;
+   if (neg) {x=-x;}
+   x2 = x*x;
+
+   if (x>2) {
+      a = log(2*x+1/(x+sqrt(x2+1)));
+   } else {
+      a = rb_log1p(x+x2/(1+sqrt(x2+1)));
+   }
+   if (neg) {a=-a;}
+   return a;
+}
+
+static double atanh(double x)
+{
+   double a, x2;
+   int neg;
+
+   /* atanh(x) = 0.5*log((1+x)/(1-x)) */
+   neg = x<0;
+   if (neg) {x=-x;}
+   x2 = x*2;
+
+   if (x<0.5) {
+      a = 0.5*rb_log1p(x2+x2*x/(1-x));
+   } else if (x<1) {
+      a = 0.5*rb_log1p(x2/(1-x));
+   } else if (x==1) {
+      a = 1/zero;        /* Infinity */
+   } else {
+      return zero/(x-x); /* x>1: NaN */
+   }
+   if (neg) {a=-a;}
+   return a;
+}
+#endif
+#endif
+
+static void squareX(scomplex *x) {
+  float r=x->r;
+  x->r = r*r - x->i*x->i;
+  x->i = 2*r*x->i;
+}
+
+static void squareC(dcomplex *x) {
+  double r=x->r;
+  x->r = r*r - x->i*x->i;
+  x->i = 2*r*x->i;
+}
+
+
+static void mulX(scomplex *x, scomplex *y) {
+  scomplex z=*x;
+  x->r = z.r*y->r - z.i*y->i;
+  x->i = z.r*y->i + z.i*y->r;
+}
+
+static void mulC(dcomplex *x, dcomplex *y) {
+  dcomplex z=*x;
+  x->r = z.r*y->r - z.i*y->i;
+  x->i = z.r*y->i + z.i*y->r;
+}
+
+
+static void divX(scomplex *p1, scomplex *p2) {
+  scomplex x = *p1;
+  float    a = p2->r*p2->r + p2->i*p2->i;
+  p1->r = (x.r*p2->r + x.i*p2->i)/a;
+  p1->i = (x.i*p2->r - x.r*p2->i)/a;
+}
+
+static void divC(dcomplex *p1, dcomplex *p2) {
+  dcomplex x = *p1;
+  double   a = p2->r*p2->r + p2->i*p2->i;
+  p1->r = (x.r*p2->r + x.i*p2->i)/a;
+  p1->i = (x.i*p2->r - x.r*p2->i)/a;
+}
+
+
+static scomplex recipX(scomplex *z)
+{
+  scomplex r;
+  float    n;
+
+  if ( (z->r<0 ? -z->r:z->r) > (z->i<0 ? -z->i:z->i) ) {
+    r.i  = z->i/z->r;
+    n    = (1+r.i*r.i)*z->r;
+    r.r  = 1/n;
+    r.i /= -n;
+  } else {
+    r.r  = z->r/z->i;
+    n    = (1+r.r*r.r)*z->i;
+    r.r /= n;
+    r.i  = -1/n;
+  }
+  return r;
+}
+
+static dcomplex recipC(dcomplex *z)
+{
+  dcomplex r;
+  double   n;
+
+  if ( (z->r<0 ? -z->r:z->r) > (z->i<0 ? -z->i:z->i) ) {
+    r.i  = z->i/z->r;
+    n    = (1+r.i*r.i)*z->r;
+    r.r  = 1/n;
+    r.i /= -n;
+  } else {
+    r.r  = z->r/z->i;
+    n    = (1+r.r*r.r)*z->i;
+    r.r /= n;
+    r.i  = -1/n;
+  }
+  return r;
+}
+
+
+static int powInt(int x, int p)
+{
+  int r=1;
+
+  switch(p) {
+  case 2: return x*x;
+  case 3: return x*x*x;
+  case 1: return x;
+  case 0: return 1;
+  }
+  if (p<0)  return 0;
+  /* if(p>3) */	
+  while (p) {
+    if ( (p%2) == 1 ) r *= x;
+    x *= x;
+    p /= 2;
+  }
+  return r;
+}
+
+
+static float powFi(float x, int p)
+{
+  float r=1;
+
+  switch(p) {
+  case 2: return x*x;
+  case 3: return x*x*x;
+  case 1: return x;
+  case 0: return 1;
+  }
+  if (p<0)  return 1/powFi(x,-p);
+  /* if(p>3) */	
+  while (p) {
+    if ( (p%2) == 1 ) r *= x;
+    x *= x;
+    p /= 2;
+  }
+  return r;
+}
+
+
+static double powDi(double x, int p)
+{
+  double r=1;
+
+  switch(p) {
+  case 2: return x*x;
+  case 3: return x*x*x;
+  case 1: return x;
+  case 0: return 1;
+  }
+  if (p<0)  return 1/powDi(x,-p);
+  /* if(p>3) */	
+  while (p) {
+    if ( (p%2) == 1 ) r *= x;
+    x *= x;
+    p /= 2;
+  }
+  return r;
+}
+
+
+static scomplex powXi(scomplex *x, int p)
+{
+  scomplex y=*x, r={1,0};
+
+  if (p==2) { squareX(&y); return y; }
+  if (p==1) { return y; }
+  if (p==0) { return r; }
+  if (p<0) {
+    y = powXi(x,-p);
+    return recipX(&y);
+  }
+  /* if (p>2) */
+  while (p) {
+    if ( (p%2) == 1 ) mulX(&r,&y);
+    squareX(&y);
+    p /= 2;
+  }
+  return r;
+}
+
+static dcomplex powCi(dcomplex *x, int p)
+{
+  dcomplex y=*x, r={1,0};
+
+  if (p==2) { squareC(&y); return y; }
+  if (p==1) { return y; }
+  if (p==0) { return r; }
+  if (p<0) {
+    y = powCi(x,-p);
+    return recipC(&y);
+  }
+  /* if (p>2) */
+  while (p) {
+    if ( (p%2) == 1 ) mulC(&r,&y);
+    squareC(&y);
+    p /= 2;
+  }
+  return r;
+}
+
+
+EOM
+
+data = [
+['sqrt',
+[nil]*4 +
+["{ *p1 = sqrt(*p2); }"]*2 +
+["{
+  typer xr=p2->r/2, xi=p2->i/2, r=hypot(xr,xi);
+  if (xr>0) {
+    p1->r = sqrt(r+xr);
+    p1->i = xi/p1->r;
+  } else if ( (r-=xr) ) {
+    p1->i = (xi>=0) ? sqrt(r):-sqrt(r);
+    p1->r = xi/p1->i;
+  } else {
+    p1->r = p1->i = 0;
+  }
+}"]*2 +
+[nil] ],
+
+['sin',
+[nil]*4 +
+["{ *p1 = sin(*p2); }"]*2 +
+["{
+  p1->r = sin(p2->r)*cosh(p2->i);
+  p1->i = cos(p2->r)*sinh(p2->i); }"]*2 +
+[nil] ],
+
+['cos',
+[nil]*4 +
+["{ *p1 = cos(*p2); }"]*2 +
+["{
+  p1->r = cos(p2->r)*cosh(p2->i);
+  p1->i = -sin(p2->r)*sinh(p2->i); }"]*2 +
+[nil] ],
+
+['tan',
+[nil]*4 +
+["{ *p1 = tan(*p2); }"]*2 +
+["{
+  typer d, th;
+  p1->i = th = tanh(2*p2->i);
+  p1->r = sqrt(1-th*th); /* sech */
+  d  = 1 + cos(2*p2->r) * p1->r;
+  p1->r *= sin(2*p2->r)/d;
+  p1->i /= d;
+}"]*2 +
+[nil] ],
+
+['sinh',
+[nil]*4 +
+["{ *p1 = sinh(*p2); }"]*2 +
+["{
+  p1->r = sinh(p2->r)*cos(p2->i);
+  p1->i = cosh(p2->r)*sin(p2->i);
+}"]*2 +
+[nil] ],
+
+['cosh',
+[nil]*4 +
+["{ *p1 = cosh(*p2); }"]*2 +
+["{
+  p1->r = cosh(p2->r)*cos(p2->i);
+  p1->i = sinh(p2->r)*sin(p2->i);
+}"]*2 +
+[nil] ],
+
+['tanh',
+[nil]*4 +
+["{ *p1 = tanh(*p2); }"]*2 +
+["{
+  typer d, th;
+  p1->r = th = tanh(2*p2->r);
+  p1->i = sqrt(1-th*th); /* sech */
+  d  = 1 + cos(2*p2->i) * p1->i;
+  p1->r /= d;
+  p1->i *= sin(2*p2->i)/d;
+}"]*2 +
+[nil] ],
+
+['exp',
+[nil]*4 +
+["{ *p1 = exp(*p2); }"]*2 +
+["{
+  typer a = exp(p2->r);
+  p1->r = a*cos(p2->i);
+  p1->i = a*sin(p2->i);
+}"]*2 +
+[nil] ],
+
+['log',
+[nil]*4 +
+["{ *p1 = log(*p2); }"]*2 +
+["{
+  typed x = *p2;
+  p1->r = log(hypot(x.r, x.i));
+  p1->i = atan2(x.i, x.r);
+}"]*2 +
+[nil] ],
+
+['log10',
+[nil]*4 +
+["{ *p1 = log10(*p2); }"]*2 +
+["{
+  log#code(p1,p2);
+  p1->r *= (typer)M_LOG10E;
+  p1->i *= (typer)M_LOG10E;
+}"]*2 +
+[nil] ],
+
+
+['log2',
+[nil]*4 +
+["{ *p1 = log(*p2)*M_LOG2E; }"]*2 +
+["{
+  log#code(p1,p2);
+  p1->r *= (typer)M_LOG2E;
+  p1->i *= (typer)M_LOG2E;
+}"]*2 +
+[nil] ],
+
+
+['asin',
+[nil]*4 +
+["{ *p1 = asin(*p2); }"]*2 +
+# -i * log( sqrt(1-x**2) + x*i )
+["{
+  typed x = *p2;
+  square#code(&x);
+  x.r = 1 - x.r;
+  x.i =   - x.i;
+  sqrt#code(&x,&x);
+  x.r -= p2->i;
+  x.i += p2->r;
+  log#code(&x,&x);
+  p1->r =  x.i;
+  p1->i = -x.r;
+}"]*2 +
+[nil]*1 ],
+
+['asinh',
+[nil]*4 +
+["{ *p1 = asinh(*p2); }"]*2 +
+# log(sqrt(x**2+1)+x)
+["{
+  typed x = *p2;
+  square#code(&x);
+  x.r += 1;
+  sqrt#code(&x,&x);
+  x.r += p2->r;
+  x.i += p2->i;
+  log#code(p1,&x);
+}"]*2 +
+[nil]*1 ],
+
+['acos',
+[nil]*4 +
+["{ *p1 = acos(*p2); }"]*2 +
+# -i * log( sqrt(1-x**2)*i + x )
+["{
+  typed x = *p2;
+  typer tmp;
+  square#code(&x);
+  x.r = 1 - x.r;
+  x.i =   - x.i;
+  sqrt#code(&x,&x);
+  tmp =  x.r + p2->i;
+  x.r = -x.i + p2->r;
+  x.i = tmp;
+  log#code(&x,&x);
+  p1->r =  x.i;
+  p1->i = -x.r;
+}"]*2 +
+[nil]*1 ],
+
+['acosh',
+[nil]*4 +
+["{ *p1 = acosh(*p2); }"]*2 +
+# log(x+sqrt(x**2-1))
+["{
+  typed x = *p2;
+  square#code(&x);
+  x.r -= 1;
+  sqrt#code(&x,&x);
+  x.r += p2->r;
+  x.i += p2->i;
+  log#code(p1,&x);
+}"]*2 +
+[nil]*1 ],
+
+['atan',
+[nil]*4 +
+["{ *p1 = atan(*p2); }"]*2 +
+# i/2 * log((i+x)/(i-x))
+["{
+  typed x,y;
+  x.r=-p2->r; x.i=1-p2->i;
+  y.r= p2->r; y.i=1+p2->i;
+  div#code((void*)&y,(void*)&x);
+  log#code((void*)&x,(void*)&y);
+  p1->r = -x.i/2;
+  p1->i =  x.r/2;
+}"]*2 +
+[nil]*1 ],
+
+['atanh',
+[nil]*4 +
+["{ *p1 = atanh(*p2); }"]*2 +
+# 1/2 * log((1+x)/(1-x))
+["{
+  typed x,y;
+  x.r=1-p2->r; x.i=-p2->i;
+  y.r=1+p2->r; y.i= p2->i;
+  div#code((void*)&y,(void*)&x);
+  log#code((void*)&x,(void*)&y);
+  p1->r = x.r/2;
+  p1->i = x.i/2;
+}"]*2 +
+[nil]*1 ] ]
+
+
+
+def mkmathfuncs(bsname,func)
+
+  print "
+/* ------------------------- #{bsname} --------------------------- */\n"
+  c  = $type_codes
+  tr = $real_types
+  td = $data_types
+  name = bsname
+
+  # Function Definition
+  head = "static void #{name}#code(void *p1, void *p2)"
+  for i in 0...c.size
+    if func[i] != nil && func[i]=~/^\{/
+      f = func[i].
+	gsub(/p1->/,"((#{td[i]}*)p1)->").
+	gsub(/p2->/,"((#{td[i]}*)p2)->").
+	gsub(/\*p1/,"*(#{td[i]}*)p1").
+	gsub(/\*p2/,"*(#{td[i]}*)p2").
+	gsub(/typer/, tr[i]).
+	gsub(/typed/, td[i])
+      puts( (head+f).gsub(/#code/,c[i]) )
+    end
+  end
+
+  # Function Array
+
+  print "\nna_mathfunc_t #{name}Funcs =\n{ "
+  m = []
+  for i in 0...c.size
+    if func[i] == nil
+      m += ['TpErr']
+    elsif func[i]=='copy'
+      m += ['Set'+c[i]*2]
+    elsif !( func[i] =~ /^\{/ )
+      m += [func[i]]
+    else
+      m += [name+c[i]]
+    end
+  end
+  print m.join(", ")+" };\n"
+
+end
+
+
+# Function Definitions
+for i in data
+  mkmathfuncs( i[0], i[1] )
+end
+
+
+#
+#  Recip
+#
+$func_body = 
+  "static void #name#C(int n, char *p1, int i1, char *p2, int i2)
+{
+  for (; n; --n) {
+    OPERATION
+    p1+=i1; p2+=i2;
+  }
+}
+"
+mkfuncs('Rcp', $data_types, $data_types,
+ [nil] +
+ ["*p1 = 1/(*p2);"]*5 + 
+ ["*p1 = recip#C((type1*)p2);"]*2 +
+ ["*p1 = rb_funcall(INT2FIX(1),na_id_div,1,*p2);"]
+)
+
+
+#
+#   Power
+#
+def mkpowfuncs(name,funcs)
+
+  print "
+/* ------------------------- #{name} --------------------------- */\n"
+  c  = $type_codes
+  n  = $type_codes.size
+  td = $data_types
+  tr = $real_types
+
+  # Function Definition
+
+  for i in 0...n
+    for j in 0...n
+      funcs.each do |k|
+	if c[i]=~k[0] && c[j]=~k[1]
+	  tu = $data_types[$upcast[i][j]]
+	  f = k[2].
+	    gsub(/p1->/,"((#{tu}*)p1)->").
+	    gsub(/p2->/,"((#{td[i]}*)p2)->").
+	    gsub(/p3->/,"((#{td[j]}*)p3)->").
+	    gsub(/\*p1/,"*(#{tu}*)p1").
+	    gsub(/\*p2/,"*(#{td[i]}*)p2").
+	    gsub(/\*p3/,"*(#{td[j]}*)p3").
+	    gsub(/typed/,td[i]).
+            gsub(/typef/,tr[i])
+	  puts $func_body.
+	    gsub(/#name/,name).
+	    sub(/OPERATION/,f).
+	    gsub(/#CC/,c[i]+c[j]).
+	    gsub(/#C/, c[i])
+	end
+      end
+    end
+  end
+
+  # function pointer array
+  print "\nna_setfunc_t "+name+"Funcs = {\n"
+  m = []
+  for i in 0...n
+    l = []
+    for j in 0...n
+      f = true
+      for k in funcs
+	if c[i]=~k[0] && c[j]=~k[1]
+	  l += [name+c[i]+c[j]]
+	  f = false
+	  break
+	end
+      end
+      if f
+	l += ['TpErr']
+      end
+    end
+    m += ['  { '+l.join(', ')+' }']
+  end
+  print m.join(",\n")+"\n};\n"
+
+end
+
+$func_body = 
+"static void #name#CC(int n, char *p1, int i1, char *p2, int i2, char *p3, int i3)
+{
+  for (; n; --n) {
+    OPERATION
+    p1+=i1; p2+=i2; p3+=i3;
+  }
+}
+"
+mkpowfuncs('Pow',
+[
+[/[O]/,/[O]/,     "*p1 = rb_funcall(*p2,na_id_power,1,*p3);"],
+[/[BIL]/,/[BIL]/, "*p1 = powInt(*p2,*p3);"],
+[/[FD]/,/[BIL]/,  "*p1 = pow#Ci(*p2,*p3);"],
+[/[BILFD]/,/[FD]/,"*p1 = pow(*p2,*p3);"],
+[/[XC]/,/[BIL]/,  "*p1 = pow#Ci((typed*)p2,*p3);"],
+[/[XC]/,/[FD]/,
+   "typed r;
+    if (*p3==0)
+    { p1->r=1; p1->i=0; } else
+    if (p2->r==0 && p2->i==0 && *p3>0)
+    { p1->r=0; p1->i=0; } else {
+    log#C(&r, p2);
+    r.r *= *p3;
+    r.i *= *p3;
+    exp#C(p1, &r); }"],
+[/[XC]/,/[XC]/,
+   "typed l, r;
+    if (p3->r==0 && p3->i==0)
+    { p1->r=1; p1->i=0; } else
+    if (p2->r==0 && p2->i==0 && p3->r>0 && p3->i==0)
+    { p1->r=0; p1->i=0; } else {
+    log#C(&l, p2);
+    r.r = p3->r * l.r - p3->i * l.i;
+    r.i = p3->r * l.i + p3->i * l.r;
+    exp#C(p1, &r); }"]
+])
+
+
+# Execution
+print <<EOM
+
+
+/* ------------------------- Execution -------------------------- */
+
+static void
+ na_exec_math(struct NARRAY *a1, struct NARRAY *a2, void (*func)())
+{
+  int  i, s1, s2;
+  char *p1, *p2;
+
+  s1 = na_sizeof[a1->type];
+  s2 = na_sizeof[a2->type];
+  p1 = a1->ptr;
+  p2 = a2->ptr;
+  for (i=a1->total; i ; i--) {
+    (*func)( p1, p2 );
+    p1 += s1;
+    p2 += s2;
+  }
+}
+
+
+static VALUE
+ na_math_func(volatile VALUE self, na_mathfunc_t funcs)
+{
+  struct NARRAY *a1, *a2;
+  VALUE ans;
+
+  if (TYPE(self) == T_ARRAY) {
+    self = na_ary_to_nary(self,cNArray);
+  } else
+  if (!IsNArray(self)) {
+    self = na_make_scalar(self,na_object_type(self));
+  }
+
+  GetNArray(self,a2);
+  if (NA_IsINTEGER(a2)) {
+    self = na_upcast_type(self,NA_DFLOAT);
+    GetNArray(self,a2);
+  }
+  ans = na_make_object(a2->type, a2->rank, a2->shape, CLASS_OF(self));
+  GetNArray(ans,a1);
+
+  na_exec_math(a1, a2, funcs[a2->type]);
+
+  if (CLASS_OF(self) == cNArrayScalar)
+    SetFuncs[NA_ROBJ][a1->type](1,&ans,0,a1->ptr,0);    
+
+  return ans;
+}
+EOM
+
+
+# Module Methods
+print <<EOM
+
+/* ------------------------- Module Methods -------------------------- */
+EOM
+for i in data
+  bsname=i[0]
+  name=bsname
+  print <<EOM
+
+/*
+ *  call-seq:
+ *     NMath.#{name}(arg)  -> narray
+ */
+static VALUE na_math_#{bsname}(VALUE obj, VALUE x)
+{ return na_math_func(x,#{name}Funcs); }
+EOM
+end
+
+
+
+# Initializer
+print <<EOM
+
+
+/* Initialization of NMath module */
+void Init_nmath(void)
+{
+  /* define ExtMath module */
+  rb_mNMath = rb_define_module("NMath");
+
+  /* methods */
+EOM
+
+for i in data
+  print "  rb_define_module_function(rb_mNMath,\"#{i[0]}\",na_math_#{i[0]},1);\n"
+end
+
+print <<EOM
+}
+EOM
diff --git a/app/server/vendor/narray-0.6.1.1/mknafunc.rb b/app/server/vendor/narray-0.6.1.1/mknafunc.rb
new file mode 100755
index 0000000..be617b0
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/mknafunc.rb
@@ -0,0 +1,192 @@
+$type_codes = %w(n B I L F D X C O)
+$data_types = 
+ %w(none u_int8_t int16_t int32_t float double scomplex dcomplex VALUE)
+$real_types =
+ %w(none u_int8_t int16_t int32_t float double float double VALUE)
+$int_types  = 
+ %w(none u_int8_t int16_t int32_t int32_t int32_t scomplex dcomplex VALUE)
+$comp_types =
+ %w(none scomplex scomplex scomplex scomplex dcomplex scomplex dcomplex VALUE)
+$swap_types  = 
+ %w(none u_int8_t na_size16_t na_size32_t na_size32_t na_size64_t na_size64_t na_size128_t VALUE)
+$upcast = [
+  [ 0, 0, 0, 0, 0, 0, 0, 0, 0],
+  [ 0, 1, 2, 3, 4, 5, 6, 7, 8],
+  [ 0, 2, 2, 3, 4, 5, 6, 7, 8],
+  [ 0, 3, 3, 3, 4, 5, 6, 7, 8],
+  [ 0, 4, 4, 4, 4, 5, 6, 7, 8],
+  [ 0, 5, 5, 5, 5, 5, 7, 7, 8],
+  [ 0, 6, 6, 6, 6, 7, 6, 7, 8],
+  [ 0, 7, 7, 7, 7, 7, 7, 7, 8],
+  [ 0, 8, 8, 8, 8, 8, 8, 8, 8] ]
+$data_obj = [
+  [/[O]/,/[O]/,  "
+    *p1 = rb_funcall(*p1,#id,1,*p2);"],
+  [/[O]/,/[BIL]/,"
+    *p1 = rb_funcall(*p1,#id,1,INT2FIX(*p2));"],
+  [/[O]/,/[FD]/, "
+    *p1 = rb_funcall(*p1,#id,1,rb_float_new(*p2));"],
+  [/[O]/,/[XC]/, "
+    *p1 = rb_funcall(*p1,#id,1,rb_complex_new(p2->r,p2->i));"],
+  [/[BIL]/,/[O]/,"
+    *p1 = NUM2INT(rb_funcall(INT2FIX(*p1),#id,1,*p2));"],
+  [/[FD]/,/[O]/, "
+    *p1 = NUM2DBL(rb_funcall(rb_float_new(*p1),#id,1,*p2));"],
+  [/[XC]/,/[O]/, "VALUE v=rb_funcall(rb_complex_new(p1->r,p1->i),#id,1,*p2);
+    p1->r = NUM2REAL(v); p1->i = NUM2IMAG(v);"] ]
+
+
+def mksetfuncs(name,op,id,funcs)
+
+  print "
+/* ------------------------- #{name} --------------------------- */\n"
+  c  = $type_codes
+  n  = $type_codes.size
+  td = $data_types
+  tr = $real_types
+
+  # Function Definition
+
+  for i in 0...n
+    for j in 0...n
+      funcs.each do |k|
+	if c[i]=~k[0] && c[j]=~k[1]
+	  #if i==j
+	  #  f = "memcpy(p1,p1,sizeof(typed));"
+	  #else
+	    f = k[2]
+	  #end
+	  f = f.
+	    gsub(/p1->/,"((#{td[i]}*)p1)->").
+	    gsub(/p2->/,"((#{td[j]}*)p2)->").
+	    gsub(/\*p1/,"*(#{td[i]}*)p1").
+	    gsub(/\*p2/,"*(#{td[j]}*)p2").
+	    gsub(/ = /," = (#{tr[i]})").
+            gsub(/#id/,id).
+            gsub(/#op/,op).
+	    gsub(/typed/,td[i]).
+            gsub(/typef/,tr[i])
+	  puts $func_body.
+	    gsub(/#name/,name).
+	    sub(/OPERATION/,f).
+	    gsub(/#CC/,c[i]+c[j])
+	end
+      end
+    end
+  end
+
+  # function pointer array
+  print "\nna_setfunc_t "+name+"Funcs = {\n"
+  m = []
+  for i in 0...n
+    l = []
+    for j in 0...n
+      f = true
+      for k in funcs
+	if c[i]=~k[0] && c[j]=~k[1]
+	  l += [name+c[i]+c[j]]
+	  f = false
+	  break
+	end
+      end
+      if f
+	l += ['TpErr']
+      end
+    end
+    m += ['  { '+l.join(', ')+' }']
+  end
+  print m.join(",\n")+"\n};\n"
+
+end
+
+
+
+def mkfuncs(name,t1,t2,func)
+
+  print "
+/* ------------------------- #{name} --------------------------- */\n"
+  c  = $type_codes
+  td = $data_types
+  tr = $real_types
+
+  for i in 0...c.size
+    if func[i] != nil && func[i] != "copy"
+      f = func[i].
+	gsub(/p1->/,"((#{t1[i]}*)p1)->").
+	gsub(/p2->/,"((#{t2[i]}*)p2)->").
+	gsub(/p3->/,"((#{t2[i]}*)p3)->").
+	gsub(/\*p1/,"*(#{t1[i]}*)p1").
+	gsub(/\*p2/,"*(#{t2[i]}*)p2").
+	gsub(/\*p3/,"*(#{t2[i]}*)p3").
+	gsub(/type1/,td[i]).
+	gsub(/typec/,t1[i]).
+	gsub(/typef/,tr[i])
+      puts $func_body.
+	gsub(/#name/,name).
+	sub(/OPERATION/,f).
+	gsub(/#C/,c[i])
+    end
+  end
+
+  # Function Array
+
+  print "\nna_func_t #{name}Funcs =\n{ "
+  m = []
+  for i in 0...c.size
+    if func[i] == nil
+      m += ['TpErr']
+    elsif func[i]=='copy'
+      m += ['Set'+c[$data_types.index(t1[i])]+c[i]]
+    else
+      m += [name+c[i]]
+    end
+  end
+  print m.join(", ")+" };\n"
+
+end
+
+
+
+def mksortfuncs(bsname,t1,t2,func)
+
+  print "
+/* ------------------------- #{bsname} --------------------------- */\n"
+  c  = $type_codes
+  tf = $real_types
+  name = bsname
+
+  # Function Definition
+  head = "static int #{name}#code(const void *p1, const void *p2)"
+  for i in 0...c.size
+    if func[i] != nil && func[i]=~/^\{/
+      f = func[i].
+	gsub(/p1->/,"((#{t1[i]}*)p1)->").
+	gsub(/p2->/,"((#{t2[i]}*)p2)->").
+	gsub(/\*\*p1/,"**(#{t1[i]}**)p1").
+	gsub(/\*\*p2/,"**(#{t2[i]}**)p2").
+	gsub(/\*p1/,"*(#{t1[i]}*)p1").
+	gsub(/\*p2/,"*(#{t2[i]}*)p2").
+	gsub(/typef/,tf[i])
+      puts( (head+f).gsub(/#code/,c[i]) )
+    end
+  end
+
+  # Function Array
+
+  print "\nna_sortfunc_t #{name}Funcs =\n{ "
+  m = []
+  for i in 0...c.size
+    if func[i] == nil
+      m += ['(int (*)(const void *, const void *))TpErrI']
+    elsif func[i]=='copy'
+      m += ['Set'+c[i]*2]
+    elsif !( func[i] =~ /^\{/ )
+      m += [func[i]]
+    else
+      m += [name+c[i]]
+    end
+  end
+  print m.join(", ")+" };\n"
+
+end
+
diff --git a/app/server/vendor/narray-0.6.1.1/mkop.rb b/app/server/vendor/narray-0.6.1.1/mkop.rb
new file mode 100755
index 0000000..51bbe17
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/mkop.rb
@@ -0,0 +1,648 @@
+require "mknafunc"
+
+fname = "na_op.c"
+$> = open(fname,"w")
+
+upcast_ary = $upcast.collect{|i| '  {'+i.join(", ")+'}'}.join(",\n")
+
+print <<EOM
+/*
+  #{fname}
+  Automatically generated code
+  Numerical Array Extention for Ruby
+    (C) Copyright 1999-2008 by Masahiro TANAKA
+
+  This program is free software.
+  You can distribute/modify this program
+  under the same terms as Ruby itself.
+  NO WARRANTY.
+*/
+#include <ruby.h>
+#include "narray.h"
+#include "narray_local.h"
+/* isalpha(3) etc. */
+#include <ctype.h>
+
+const int na_upcast[NA_NTYPES][NA_NTYPES] = {
+#{upcast_ary} };
+
+const int na_no_cast[NA_NTYPES] =
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
+const int na_cast_real[NA_NTYPES] =
+ { 0, 1, 2, 3, 4, 5, 4, 5, 8 };
+const int na_cast_comp[NA_NTYPES] =
+ { 0, 6, 6, 6, 6, 7, 6, 7, 8 };
+const int na_cast_round[NA_NTYPES] =
+ { 0, 1, 2, 3, 3, 3, 6, 7, 8 };
+const int na_cast_byte[NA_NTYPES] =
+ { 0, 1, 1, 1, 1, 1, 1, 1, 1 };
+
+
+static void TpErr(void) {
+    rb_raise(rb_eTypeError,"illegal operation with this type");
+}
+static int TpErrI(void) {
+    rb_raise(rb_eTypeError,"illegal operation with this type");
+    return 0;
+}
+static void na_zerodiv() {
+    rb_raise(rb_eZeroDivError, "divided by 0");
+}
+
+static int notnanF(float *n)
+{
+  return *n == *n;
+}
+static int notnanD(double *n)
+{
+  return *n == *n;
+}
+EOM
+
+
+#
+#  Set Fucs
+#
+data = [
+  [/[O]/,/[O]/,        "*p1 = *p2;"],
+  [/[O]/,/[BI]/,       "*p1 = INT2FIX(*p2);"],
+  [/[O]/,/[L]/,        "*p1 = INT2NUM(*p2);"],
+  [/[O]/,/[FD]/,       "*p1 = rb_float_new(*p2);"],
+  [/[O]/,/[XC]/,       "*p1 = rb_complex_new(p2->r,p2->i);"],
+  [/[BIL]/,/[O]/,      "*p1 = NUM2INT(*p2);"],
+  [/[FD]/,/[O]/,       "*p1 = NUM2DBL(*p2);"],
+  [/[XC]/,/[O]/,       "p1->r = NUM2REAL(*p2); p1->i = NUM2IMAG(*p2);"],
+  [/[BILFD]/,/[BILFD]/,"*p1 = *p2;"],
+  [/[BILFD]/,/[XC]/,   "*p1 = p2->r;"],
+  [/[XC]/,/[BILFD]/,   "p1->r = *p2; p1->i = 0;"],
+  [/[XC]/,/[XC]/,      "p1->r = p2->r; p1->i = p2->i;"] ]
+
+$func_body = 
+  "static void #name#CC(int n, char *p1, int i1, char *p2, int i2)
+{
+  for (; n; --n) {
+    OPERATION
+    p1+=i1; p2+=i2;
+  }
+}
+"
+mksetfuncs('Set','','',data)
+
+
+
+#
+#  Unary Funcs
+#
+$func_body = 
+  "static void #name#C(int n, char *p1, int i1, char *p2, int i2)
+{
+  for (; n; --n) {
+    OPERATION
+    p1+=i1; p2+=i2;
+  }
+}
+"
+
+
+mkfuncs('Swp', $swap_types, $swap_types,
+ [nil] +
+ ["*p1 = *p2;"] + 
+ ["na_size16_t x;  swap16(x,*p2);   *p1 = x;"] + 
+ ["na_size32_t x;  swap32(x,*p2);   *p1 = x;"] + 
+ ["na_size32_t x;  swap32(x,*p2);   *p1 = x;"] + 
+ ["na_size64_t x;  swap64(x,*p2);   *p1 = x;"] + 
+ ["na_size64_t x;  swap64c(x,*p2);  *p1 = x;"] + 
+ ["na_size128_t x; swap128c(x,*p2); *p1 = x;"] + 
+ ["*p1 = *p2;"]
+)
+
+print <<EOM
+
+/* ------------------------- H2N --------------------------- */
+#ifdef WORDS_BIGENDIAN
+
+na_func_t H2NFuncs =
+{ TpErr, SetBB, SetII, SetLL, SetFF, SetDD, SetXX, SetCC, SetOO };
+
+na_func_t H2VFuncs =
+{ TpErr, SetBB, SwpI, SwpL, SwpF, SwpD, SwpX, SwpC, SetOO };
+
+#else
+#ifdef DYNAMIC_ENDIAN  /* not supported yet */
+#else  /* LITTLE ENDIAN */
+
+na_func_t H2NFuncs =
+{ TpErr, SetBB, SwpI, SwpL, SwpF, SwpD, SwpX, SwpC, SetOO };
+
+na_func_t H2VFuncs =
+{ TpErr, SetBB, SetII, SetLL, SetFF, SetDD, SetXX, SetCC, SetOO };
+
+#endif
+#endif
+EOM
+
+mkfuncs('Neg', $data_types, $data_types,
+ [nil] +
+ ["*p1 = -*p2;"]*5 + 
+ ["p1->r = -p2->r;
+    p1->i = -p2->i;"]*2 +
+ ["*p1 = rb_funcall(*p2,na_id_minus,0);"]
+)
+
+mkfuncs('AddU', $data_types, $data_types,
+ [nil] +
+ ["*p1 += *p2;"]*5 + 
+ ["p1->r += p2->r;
+    p1->i += p2->i;"]*2 +
+ ["*p1 = rb_funcall(*p1,'+',1,*p2);"]
+)
+
+mkfuncs('SbtU', $data_types, $data_types,
+ [nil] +
+ ["*p1 -= *p2;"]*5 + 
+ ["p1->r -= p2->r;
+    p1->i -= p2->i;"]*2 +
+ ["*p1 = rb_funcall(*p1,'-',1,*p2);"]
+)
+
+mkfuncs('MulU', $data_types, $data_types,
+ [nil] +
+ ["*p1 *= *p2;"]*5 + 
+ ["type1 x = *p1;
+    p1->r = x.r*p2->r - x.i*p2->i;
+    p1->i = x.r*p2->i + x.i*p2->r;"]*2 +
+ ["*p1 = rb_funcall(*p1,'*',1,*p2);"]
+)
+
+mkfuncs('DivU', $data_types, $data_types,
+ [nil] +
+ ["if (*p2==0) {na_zerodiv();}
+    *p1 /= *p2;"]*3 + 
+ ["*p1 /= *p2;"]*2 + 
+ ["type1 x = *p1;
+    typef a = p2->r*p2->r + p2->i*p2->i;
+    p1->r = (x.r*p2->r + x.i*p2->i)/a;
+    p1->i = (x.i*p2->r - x.r*p2->i)/a;"]*2 +
+ ["*p1 = rb_funcall(*p1,'/',1,*p2);"]
+)
+
+mkfuncs('ModU', $data_types, $data_types,
+ [nil] +
+ ["if (*p2==0) {na_zerodiv();}
+    *p1 %= *p2;"]*3 +
+ ["*p1 = fmod(*p1, *p2);"]*2 +
+ [nil]*2 +
+ ["*p1 = rb_funcall(*p1,'%',1,*p2);"]
+)
+
+
+# method: imag=
+mkfuncs('ImgSet',$data_types,$real_types,
+ [nil]*6 +
+ ["p1->i = *p2;"]*2 +
+ [nil]
+)
+
+
+mkfuncs('Floor',$int_types,$data_types,[nil] +
+ ['copy']*3 + 
+ ["*p1 = (typec)floor(*p2);"]*2 + 
+ [nil]*3
+)
+
+mkfuncs('Ceil',$int_types,$data_types,[nil] +
+ ['copy']*3 + 
+ ["*p1 = (typec)ceil(*p2);"]*2 + 
+ [nil]*3
+)
+
+mkfuncs('Round',$int_types,$data_types,[nil] +
+ ['copy']*3 + 
+# ["*p1 = floor(*p2+0.5);"]*2 + 
+ ["if (*p2 >= 0) *p1 = (typec)floor(*p2+0.5);
+     else *p1 = (typec)ceil(*p2-0.5);"]*2 + 
+ [nil]*3
+)
+
+mkfuncs('Abs',$real_types,$data_types,[nil] +
+ ["*p1 = *p2;"] + 
+ ["*p1 = (*p2<0) ? -*p2 : *p2;"]*4 + 
+ ["*p1 = (typec)hypot(p2->r, p2->i);"]*2 +
+ ["*p1 = rb_funcall(*p2,na_id_abs,0);"]
+)
+
+
+mkfuncs('Real',$real_types,$data_types,[nil] +
+ ['copy']*7 + 
+ [nil]
+)
+
+mkfuncs('Imag',$real_types,$data_types,[nil] +
+ ["*p1 = 0;"]*5 + 
+ ["*p1 = p2->i;"]*2 +
+ [nil]
+)
+
+mkfuncs('Angl',$real_types,$data_types,[nil] +
+ [nil]*5 +
+ ["*p1 = atan2(p2->i,p2->r);"]*2 +
+ [nil]
+)
+
+mkfuncs('ImagMul',$comp_types,$data_types,[nil] +
+ [nil]*3 +
+ ["p1->r = 0; p1->i = *p2;"]*2 + 
+ ["p1->r = -p2->i; p1->i = p2->r;"]*2 +
+ [nil]
+)
+
+mkfuncs('Conj',$data_types,$data_types,[nil] +
+ ['copy']*5 + 
+ ["p1->r = p2->r; p1->i = -p2->i;"]*2 +
+ [nil]
+)
+
+mkfuncs('Not', [$data_types[1]]*9, $data_types,
+ [nil] +
+ ["*p1 = (*p2==0) ? 1:0;"]*5 +
+ ["*p1 = (p2->r==0 && p2->i==0) ? 1:0;"]*2 +
+ ["*p1 = RTEST(*p2) ? 0:1;"]
+)
+
+mkfuncs('BRv', $data_types, $data_types, [nil] +
+ ["*p1 = ~(*p2);"]*3 +
+ [nil]*4 +
+ ["*p1 = rb_funcall(*p2,'~',0);"]
+)
+
+mkfuncs('Min', $data_types, $data_types, [nil] +
+ ["if (*p1>*p2) *p1=*p2;"]*3 +
+ ["if (notnan#C((type1*)p2) && *p1>*p2) *p1=*p2;"]*2 +
+ [nil]*2 +
+ ["if (FIX2INT(rb_funcall(*p1,na_id_compare,1,*p2))>0) *p1=*p2;"]
+)
+
+mkfuncs('Max', $data_types, $data_types, [nil] +
+ ["if (*p1<*p2) *p1=*p2;"]*3 +
+ ["if (notnan#C((type1*)p2) && *p1<*p2) *p1=*p2;"]*2 +
+ [nil]*2 +
+ ["if (FIX2INT(rb_funcall(*p1,na_id_compare,1,*p2))<0) *p1=*p2;"]
+)
+
+
+mksortfuncs('Sort', $data_types, $data_types, [nil] +
+ ["
+{ if (*p1 > *p2) return 1;
+  if (*p1 < *p2) return -1;
+  return 0; }"]*5 +
+ [nil]*2 +
+ ["
+{ VALUE r = rb_funcall(*p1, na_id_compare, 1, *p2);
+  return NUM2INT(r); }"]
+)
+
+mksortfuncs('SortIdx', $data_types, $data_types, [nil] +
+ ["
+{ if (**p1 > **p2) return 1;
+  if (**p1 < **p2) return -1;
+  return 0; }"]*5 +
+ [nil]*2 +
+ ["
+{ VALUE r = rb_funcall(**p1, na_id_compare, 1, **p2);
+  return NUM2INT(r); }"]
+)
+
+# indgen
+$func_body = 
+  "static void #name#C(int n, char *p1, int i1, int p2, int i2)
+{
+  for (; n; --n) {
+    OPERATION
+    p1+=i1; p2+=i2;
+  }
+}
+"
+mkfuncs('IndGen',$data_types,[$data_types[3]]*8,
+ [nil] +
+ ["*p1 = (typef)p2;"]*5 +
+ ["p1->r = (typef)p2;
+   p1->i = 0;"]*2 +
+ ["*p1 = INT2FIX(p2);"]
+)
+
+
+
+$func_body = 
+"static void #name#C(int n, char *p1, int i1, char *p2, int i2)
+{
+  OPERATION
+}
+"
+mkfuncs('ToStr',['']+[$data_types[8]]*8,$data_types,
+ [nil] +
+ ["char buf[22];
+  for (; n; --n) {
+    sprintf(buf,\"%i\",(int)*p2);
+    *p1 = rb_str_new2(buf);
+    p1+=i1; p2+=i2;
+  }"]*3 +
+ ["char buf[24];
+  for (; n; --n) {
+    sprintf(buf,\"%.5g\",(double)*p2);
+    *p1 = rb_str_new2(buf);
+    p1+=i1; p2+=i2;
+  }"] +
+ ["char buf[24];
+  for (; n; --n) {
+    sprintf(buf,\"%.8g\",(double)*p2);
+    *p1 = rb_str_new2(buf);
+    p1+=i1; p2+=i2;
+  }"] +
+ ["char buf[50];
+  for (; n; --n) {
+    sprintf(buf,\"%.5g%+.5gi\",(double)p2->r,(double)p2->i);
+    *p1 = rb_str_new2(buf);
+    p1+=i1; p2+=i2;
+  }"] +
+ ["char buf[50];
+  for (; n; --n) {
+    sprintf(buf,\"%.8g%+.8gi\",(double)p2->r,(double)p2->i);
+    *p1 = rb_str_new2(buf);
+    p1+=i1; p2+=i2;
+  }"] +
+ ["for (; n; --n) {
+    *p1 = rb_obj_as_string(*p2);
+    p1+=i1; p2+=i2;
+  }"]
+)
+
+
+print <<EOM
+
+/* from numeric.c */
+static void na_str_append_fp(char *buf)
+{
+  if (buf[0]=='-' || buf[0]=='+') ++buf;
+  if (ISALPHA(buf[0])) return; /* NaN or Inf */
+  if (strchr(buf, '.') == 0) {
+      int   len = strlen(buf);
+      char *ind = strchr(buf, 'e');
+      if (ind) {
+          memmove(ind+2, ind, len-(ind-buf)+1);
+          ind[0] = '.';
+	  ind[1] = '0';
+      } else {
+          strcat(buf, ".0");
+      }
+  }
+}
+EOM
+
+$func_body = 
+"static void #name#C(char *p1, char *p2)
+{
+  OPERATION
+}
+"
+mkfuncs('Insp',['']+[$data_types[8]]*8,$data_types,
+ [nil] +
+ ["char buf[22];
+  sprintf(buf,\"%i\",(int)*p2);
+  *p1 = rb_str_new2(buf);"]*3 +
+ ["char buf[24];
+  sprintf(buf,\"%g\",(double)*p2);
+  na_str_append_fp(buf);
+  *p1 = rb_str_new2(buf);"] +
+ ["char buf[24];
+  sprintf(buf,\"%g\",(double)*p2);
+  na_str_append_fp(buf);
+  *p1 = rb_str_new2(buf);"] +
+ ["char buf[50], *b;
+  sprintf(buf,\"%g\",(double)p2->r);
+  na_str_append_fp(buf);
+  b = buf+strlen(buf);
+  sprintf(b,\"%+g\",(double)p2->i);
+  na_str_append_fp(b);
+  strcat(buf,\"i\");
+  *p1 = rb_str_new2(buf);"] +
+ ["char buf[50], *b;
+  sprintf(buf,\"%g\",(double)p2->r);
+  na_str_append_fp(buf);
+  b = buf+strlen(buf);
+  sprintf(b,\"%+g\",(double)p2->i);
+  na_str_append_fp(b);
+  strcat(buf,\"i\");
+  *p1 = rb_str_new2(buf);"] +
+ ["*p1 = rb_inspect(*p2);"]
+)
+
+
+
+#
+#   Binary Funcs
+#
+
+=begin
+# Optimize experiment
+$func_body = 
+  "static void #name#C(int n, char *p1, int i1, char *p2, int i2, char *p3, int i3)
+{
+  int i;
+  if (i1==sizeof(type1) && i2==sizeof(type1) && i3==sizeof(type1)) {
+    type1 *a1=p1, *a2=p2, *a3=p3;
+    for (i=0; n; --n,++i) {
+      *a1 = *a2 * *a3; +++a1;++a2;++a3;
+    }
+  } else
+    for (; n; --n) {
+      OPERATION
+      p1+=i1; p2+=i2; p3+=i3;
+    }
+}
+"
+mkfuncs('MulB', $data_types, $data_types,
+ [nil] +
+ ["*p1 = *p2 * *p3;"]*5 + [nil]*3
+)
+=end
+
+$func_body = 
+  "static void #name#C(int n, char *p1, int i1, char *p2, int i2, char *p3, int i3)
+{
+  for (; n; --n) {
+    OPERATION
+    p1+=i1; p2+=i2; p3+=i3;
+  }
+}
+"
+
+mkfuncs('AddB', $data_types, $data_types,
+ [nil] +
+ ["*p1 = *p2 + *p3;"]*5 + 
+ ["p1->r = p2->r + p3->r;
+    p1->i = p2->i + p3->i;"]*2 +
+ ["*p1 = rb_funcall(*p2,'+',1,*p3);"]
+)
+
+mkfuncs('SbtB', $data_types, $data_types,
+ [nil] +
+ ["*p1 = *p2 - *p3;"]*5 + 
+ ["p1->r = p2->r - p3->r;
+    p1->i = p2->i - p3->i;"]*2 +
+ ["*p1 = rb_funcall(*p2,'-',1,*p3);"]
+)
+
+mkfuncs('MulB', $data_types, $data_types,
+ [nil] +
+ ["*p1 = *p2 * *p3;"]*5 + 
+ ["type1 x = *p2;
+    p1->r = x.r*p3->r - x.i*p3->i;
+    p1->i = x.r*p3->i + x.i*p3->r;"]*2 +
+ ["*p1 = rb_funcall(*p2,'*',1,*p3);"]
+)
+
+mkfuncs('DivB', $data_types, $data_types,
+ [nil] +
+ ["if (*p3==0) {na_zerodiv();};
+    *p1 = *p2 / *p3;"]*3 +
+ ["*p1 = *p2 / *p3;"]*2 +
+ ["type1 x = *p2;
+    typef a = p3->r*p3->r + p3->i*p3->i;
+    p1->r = (x.r*p3->r + x.i*p3->i)/a;
+    p1->i = (x.i*p3->r - x.r*p3->i)/a;"]*2 +
+ ["*p1 = rb_funcall(*p2,'/',1,*p3);"]
+)
+
+mkfuncs('ModB', $data_types, $data_types,
+ [nil] +
+ ["if (*p3==0) {na_zerodiv();};
+    *p1 = *p2 % *p3;"]*3 +
+ ["*p1 = fmod(*p2, *p3);"]*2 + 
+ [nil]*2 +
+ ["*p1 = rb_funcall(*p2,'%',1,*p3);"]
+)
+
+
+mkfuncs('MulAdd', $data_types, $data_types,
+ [nil] +
+ ["*p1 += *p2 * *p3;"]*5 + 
+ ["type1 x = *p2;
+    p1->r += x.r*p3->r - x.i*p3->i;
+    p1->i += x.r*p3->i + x.i*p3->r;"]*2 +
+ ["*p1 = rb_funcall(*p1,'+',1,
+    rb_funcall(*p2,'*',1,*p3));"]
+)
+
+mkfuncs('MulSbt', $data_types, $data_types,
+ [nil] +
+ ["*p1 -= *p2 * *p3;"]*5 + 
+ ["type1 x = *p2;
+    p1->r -= x.r*p3->r - x.i*p3->i;
+    p1->i -= x.r*p3->i + x.i*p3->r;"]*2 +
+ ["*p1 = rb_funcall(*p1,'-',1,
+    rb_funcall(*p2,'*',1,*p3));"]
+)
+
+
+#
+#   Bit operator
+#
+
+mkfuncs('BAn', $data_types, $data_types,
+ [nil] +
+ ["*p1 = *p2 & *p3;"]*3 + 
+ [nil]*4 +
+ ["*p1 = rb_funcall(*p2,'&',1,*p3);"]
+)
+
+mkfuncs('BOr', $data_types, $data_types,
+ [nil] +
+ ["*p1 = *p2 | *p3;"]*3 + 
+ [nil]*4 +
+ ["*p1 = rb_funcall(*p2,'|',1,*p3);"]
+)
+
+mkfuncs('BXo', $data_types, $data_types,
+ [nil] +
+ ["*p1 = *p2 ^ *p3;"]*3 + 
+ [nil]*4 +
+ ["*p1 = rb_funcall(*p2,'^',1,*p3);"]
+)
+
+
+#
+#   Comparison
+#
+
+mkfuncs('Eql', [$data_types[1]]*9, $data_types,
+ [nil] +
+ ["*p1 = (*p2==*p3) ? 1:0;"]*5 +
+ ["*p1 = (p2->r==p3->r) && (p2->i==p3->i) ? 1:0;"]*2 +
+ ["*p1 = RTEST(rb_equal(*p2, *p3)) ? 1:0;"]
+)
+
+mkfuncs('Cmp', [$data_types[1]]*9, $data_types,
+ [nil] +
+ ["if (*p2>*p3) *p1=1;
+    else if (*p2<*p3) *p1=2;
+    else *p1=0;"]*5 +
+ [nil]*2 +
+ ["int v = NUM2INT(rb_funcall(*p2,na_id_compare,1,*p3));
+    if (v>0) *p1=1; else if (v<0) *p1=2; else *p1=0;"]
+)
+
+mkfuncs('And', [$data_types[1]]*9, $data_types,
+ [nil] +
+ ["*p1 = (*p2!=0 && *p3!=0) ? 1:0;"]*5 +
+ ["*p1 = ((p2->r!=0||p2->i!=0) && (p3->r!=0||p3->i!=0)) ? 1:0;"]*2 +
+ ["*p1 = (RTEST(*p2) && RTEST(*p3)) ? 1:0;"]
+)
+
+mkfuncs('Or_', [$data_types[1]]*9, $data_types,
+ [nil] +
+ ["*p1 = (*p2!=0 || *p3!=0) ? 1:0;"]*5 +
+ ["*p1 = ((p2->r!=0||p2->i!=0) || (p3->r!=0||p3->i!=0)) ? 1:0;"]*2 +
+ ["*p1 = (RTEST(*p2) || RTEST(*p3)) ? 1:0;"]
+)
+
+mkfuncs('Xor', [$data_types[1]]*9, $data_types,
+ [nil] +
+ ["*p1 = ((*p2!=0) == (*p3!=0)) ? 0:1;"]*5 +
+ ["*p1 = ((p2->r!=0||p2->i!=0) == (p3->r!=0||p3->i!=0)) ? 0:1;"]*2 +
+ ["*p1 = (RTEST(*p2) == RTEST(*p3)) ? 0:1;"]
+)
+
+
+#
+#   Atan2
+#
+
+mkfuncs('atan2', $data_types, $data_types,
+ [nil]*4 +
+ ["*p1 = atan2(*p2, *p3);"]*2 +
+ [nil]*3
+)
+
+
+#
+#   Mask
+#
+$func_body = 
+  "static void #name#C(int n, char *p1, int i1, char *p2, int i2, char *p3, int i3)
+{
+  for (; n; --n) {
+    OPERATION
+  }
+}
+"
+mkfuncs('RefMask',$data_types,$data_types,
+ [nil] +
+ ["if (*(u_int8_t*)p3) { *p1=*p2; p1+=i1; }
+    p3+=i3; p2+=i2;"]*8
+)
+
+mkfuncs('SetMask',$data_types,$data_types,
+ [nil] +
+ ["if (*(u_int8_t*)p3) { *p1=*p2; p2+=i2; }
+    p3+=i3; p1+=i1;"]*8
+)
diff --git a/app/server/vendor/narray-0.6.1.1/na_array.c b/app/server/vendor/narray-0.6.1.1/na_array.c
new file mode 100755
index 0000000..8fdf4f0
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/na_array.c
@@ -0,0 +1,650 @@
+/*
+  na_array.c
+  Numerical Array Extention for Ruby
+    (C) Copyright 1999-2008 by Masahiro TANAKA
+
+  This program is free software.
+  You can distribute/modify this program
+  under the same terms as Ruby itself.
+  NO WARRANTY.
+*/
+#include <ruby.h>
+#include "narray.h"
+#include "narray_local.h"
+
+/* Multi-Dimensional Array Investigation */
+typedef struct {
+  int shape;
+  VALUE val;
+} na_mdai_item_t;
+
+typedef struct {
+  int n;
+  na_mdai_item_t *item;
+  int *type;
+} na_mdai_t;
+
+
+int na_object_type(VALUE v)
+{
+  switch(TYPE(v)) {
+
+  case T_TRUE:
+  case T_FALSE:
+    return NA_BYTE;
+
+  case T_FIXNUM:
+  case T_BIGNUM:
+    return NA_LINT;
+
+  case T_FLOAT:
+    return NA_DFLOAT;
+
+  case T_NIL:
+    return NA_NONE;
+
+  default:
+    if (IsNArray(v))
+      return ((struct NARRAY *)(RDATA(v)->data))->type ;
+
+    if (CLASS_OF(v) == cComplex)
+      return NA_DCOMPLEX;
+  }
+  return NA_ROBJ;
+}
+
+
+static na_mdai_t *
+  na_alloc_mdai(VALUE ary)
+{
+  int i, n=2;
+  na_mdai_t *mdai;
+
+  mdai = ALLOC(na_mdai_t);
+  mdai->n = n;
+  mdai->item = ALLOC_N( na_mdai_item_t, n );
+  for (i=0; i<n; ++i) {
+    mdai->item[i].shape = 0;
+    mdai->item[i].val = Qnil;
+  }
+  mdai->item[0].val = ary;
+  mdai->type = ALLOC_N( int, NA_NTYPES );
+  for (i=0; i<NA_NTYPES; ++i)
+    mdai->type[i]=0;
+
+  return mdai;
+}
+
+static void
+  na_realloc_mdai(na_mdai_t *mdai, int n_extra)
+{
+  int i, n;
+
+  i = mdai->n;
+  mdai->n += n_extra;
+  n = mdai->n;
+  REALLOC_N( mdai->item, na_mdai_item_t, n );
+  for (; i<n; ++i) {
+    mdai->item[i].shape = 0;
+    mdai->item[i].val = Qnil;
+  }
+}
+
+static int *
+  na_free_mdai(na_mdai_t *mdai, int *rank, int *type)
+{
+  int i, t, r;
+  int *shape;
+
+  for (t=i=NA_BYTE; i<NA_NTYPES; ++i) {
+    if ( mdai->type[i] > 0 )
+      t = na_upcast[t][i];
+  }
+  *type = t;
+  for (i=0; i < mdai->n && mdai->item[i].shape > 0; ++i) ;
+  *rank = r = i;
+  shape = ALLOC_N(int,r);
+  for (i=0; r-->0; ++i) {
+    shape[i] = mdai->item[r].shape;
+  }
+  xfree(mdai->type);
+  xfree(mdai->item);
+  xfree(mdai);
+  return shape;
+}
+
+
+#define EXCL(r) (RTEST(rb_funcall((r),na_id_exclude_end,0)))
+
+/* Range as a Sequence of numbers */
+static void
+ na_range_to_sequence(VALUE obj, int *n, int *beg, int *step)
+{
+  int end,len;
+
+  *beg = NUM2INT(rb_funcall(obj, na_id_beg, 0));
+  end = NUM2INT(rb_funcall(obj, na_id_end, 0));
+  len = end - *beg;
+
+  /* direction */
+  if (len>0) {
+    *step = 1;
+    if (EXCL(obj)) --end; else ++len;
+  }
+  else if (len<0) {
+    len   = -len;
+    *step = -1;
+    if (EXCL(obj)) ++end; else ++len;
+  }
+  else /*if(len==0)*/ {
+    *step = 0;
+    if (!EXCL(obj)) {
+      ++len;
+    }
+  } 
+  *n = len;
+}
+
+
+/* investigate rank, shape, type of Array */
+static int
+  na_do_mdai(na_mdai_t *mdai, int rank)
+{
+  int i, j, len, length, start, dir;
+  VALUE v;
+  VALUE ary;
+
+  ary = mdai->item[rank-1].val;
+  len = RARRAY_LEN(ary);
+
+  for (i=0; i < RARRAY_LEN(ary); ++i) {
+
+    v = RARRAY_PTR(ary)[i];
+
+    if (TYPE(v) == T_ARRAY) {
+      /* check recursive array */
+      for (j=0; j<rank; ++j) {
+	if (mdai->item[j].val == v)
+	  rb_raise(rb_eStandardError,"converting recursive Array to NArray");
+      }
+      if ( rank >= mdai->n ) {
+	na_realloc_mdai(mdai,2);
+      }
+      mdai->item[rank].val = v;
+      if ( na_do_mdai(mdai,rank+1) ) {
+	--len; /* Array is empty */
+      }
+    }
+    else
+    if ( rb_obj_is_kind_of(v, rb_cRange) ) {
+      na_range_to_sequence(v,&length,&start,&dir);
+      len += length-1;
+      mdai->type[ na_object_type(rb_funcall(v, na_id_beg, 0)) ] = 1;
+      mdai->type[ na_object_type(rb_funcall(v, na_id_end, 0)) ] = 1;
+    }
+    else {
+
+      mdai->type[ na_object_type(v) ] = 1;
+
+      if (IsNArray(v)) {
+	int r;
+	struct NARRAY *na;  GetNArray(v,na);
+
+	if ( na->rank == 0 ) {
+	  --len; /* NArray is empty */
+	} else {
+	  if ( rank+na->rank > mdai->n ) {
+	    na_realloc_mdai(mdai,((na->rank-1)/4+1)*4);
+	  }
+	  for ( j=na->rank, r=rank; j-- > 0  ; ++r ) {
+	    if ( mdai->item[r].shape < na->shape[j] )
+	      mdai->item[r].shape = na->shape[j];
+	  }
+	}
+      }
+    }
+  }
+
+  if (len==0) return 1; /* this array is empty */
+  if (mdai->item[rank-1].shape < len) {
+    mdai->item[rank-1].shape = len;
+  }
+  return 0;
+}
+
+
+/* get index from multiple-index  */
+static int
+ na_index_pos(struct NARRAY *ary, int *idxs)
+{
+  int i, idx, pos = 0;
+
+  for ( i = ary->rank; (i--)>0; ) {
+    idx = idxs[i];
+    if (idx < 0 || ary->shape[i] <= idx) {
+      abort();
+      rb_raise(rb_eRuntimeError,
+	       "Subsctipt out of range: accessing shape[%i]=%i with %i",
+	       i, ary->shape[i], idx );
+    }
+    pos = pos * ary->shape[i] + idx;
+  }
+  return pos;
+}
+
+
+static void
+ na_copy_nary_to_nary(VALUE obj, struct NARRAY *dst,
+		      int thisrank, int *idx)
+{
+  struct NARRAY *src;
+  struct slice *s;
+  int  i, n;
+
+  GetNArray(obj,src);
+  n = thisrank - src->rank + 1;
+
+  s = ALLOCA_N(struct slice, dst->rank+1);
+  for (i=0; i < n; ++i) {
+    s[i].n    = 1;
+    s[i].beg  = 0;
+    s[i].step = 0;
+    s[i].idx  = NULL;
+  }
+  for (   ; i <= thisrank; ++i) {
+    s[i].n    = src->shape[i-n];
+    s[i].beg  = 0;
+    s[i].step = 1;
+    s[i].idx  = NULL;
+  }
+  for (   ; i < dst->rank; ++i) {
+    s[i].n    = 1;
+    s[i].beg  = idx[i];
+    s[i].step = 0;
+    s[i].idx  = NULL;
+  }
+  na_aset_slice(dst,src,s);
+}
+
+
+/* copy Array to NArray */
+static void
+ na_copy_ary_to_nary( VALUE ary, struct NARRAY *na,
+		      int thisrank, int *idx, int type )
+{
+  int i, j, pos, len, start, step, dir;
+  VALUE v;
+
+  if (thisrank==0) {
+    for (i = idx[0] = 0; i < RARRAY_LEN(ary); ++i) {
+      v = RARRAY_PTR(ary)[i];
+      if (rb_obj_is_kind_of(v, rb_cRange)) {
+	na_range_to_sequence(v,&len,&start,&dir);
+	if (len>0) {
+	  pos = na_index_pos(na,idx);
+	  IndGenFuncs[type](len, NA_PTR(na,pos),na_sizeof[type], start,dir);
+	  idx[0] += len;
+	}
+      }
+      else if (TYPE(v) != T_ARRAY) {
+	/* NIL if empty */
+	if (v != Qnil) {
+	  pos = na_index_pos(na,idx);
+	  SetFuncs[type][NA_ROBJ]( 1, NA_PTR(na,pos), 0, &v, 0 );
+	  /* copy here */
+	}
+	idx[0] ++;
+      }
+    }
+  }
+  else /* thisrank > 0 */
+  { 
+    for (i = idx[thisrank] = 0; i < RARRAY_LEN(ary); ++i) {
+      v = RARRAY_PTR(ary)[i];
+      if (TYPE(v) == T_ARRAY) {
+	na_copy_ary_to_nary(v,na,thisrank-1,idx,type);
+	if (idx[thisrank-1]>0) ++idx[thisrank];
+      }
+      else if (IsNArray(v)) {
+	na_copy_nary_to_nary(v,na,thisrank-1,idx);
+	++idx[thisrank];
+      }
+      else {
+	for (j=thisrank; j; ) idx[--j] = 0;
+
+	if (rb_obj_is_kind_of(v, rb_cRange)) {
+	  na_range_to_sequence(v,&len,&start,&dir);
+	  if (len>0) {
+	    pos = na_index_pos(na,idx);
+	    ++idx[thisrank];
+	    step = na_index_pos(na,idx)-pos;
+	    IndGenFuncs[type]( len, NA_PTR(na,pos), na_sizeof[type]*step,
+			       start, dir );
+	    idx[thisrank] += len-1;
+	  }
+	}
+	else {
+	  pos = na_index_pos(na,idx);
+	  SetFuncs[type][NA_ROBJ]( 1, NA_PTR(na,pos), 0, &(RARRAY_PTR(ary)[i]), 0 );
+	  ++idx[thisrank];
+	}
+	/* copy here */
+      }
+    }
+  }
+}
+
+
+static VALUE
+ na_ary_to_nary_w_type(VALUE ary, int type_spec, VALUE klass)
+{
+  int  i, rank;
+  int  type = NA_BYTE;
+  int *shape, *idx;
+  na_mdai_t *mdai;
+  struct NARRAY *na;
+  VALUE v;
+
+  /* empty array */
+  if (RARRAY_LEN(ary) < 1) {
+    return na_make_empty( type, klass );
+  }
+
+  mdai  = na_alloc_mdai(ary);
+  na_do_mdai(mdai,1);
+  shape = na_free_mdai(mdai,&rank,&type);
+
+  /*
+  printf("rank=%i\n", rank);
+  printf("type=%i\n", type);
+  for (i=0; i<rank; ++i) {
+    printf("shape[%i]=%i\n", i, shape[i]);
+  }
+  */
+
+  /* type specification */
+  if (type_spec!=NA_NONE)
+    type = type_spec;
+
+  /* empty array */
+  if (rank==0)
+    return na_make_empty( type, klass );
+
+  /* Create NArray */
+  v  = na_make_object(type,rank,shape,klass);
+  xfree(shape);
+
+  GetNArray(v,na);
+  na_clear_data(na);
+
+  idx = ALLOCA_N(int,rank);
+  for (i=0; i<rank; ++i) idx[i]=0;
+
+  na_copy_ary_to_nary( ary, na, rank-1, idx, type );
+
+  return v;
+}
+
+
+VALUE
+ na_ary_to_nary(VALUE ary, VALUE klass)
+{
+  return na_ary_to_nary_w_type( ary, NA_NONE, klass );
+}
+
+
+/* obj.kind_of?(NArray) == true */
+
+VALUE
+ na_dup_w_type(VALUE v2, int type)
+{
+  VALUE  v1;
+  struct NARRAY *a1, *a2;
+
+  GetNArray(v2,a2);
+  v1 = na_make_object(type, a2->rank, a2->shape, CLASS_OF(v2));
+  GetNArray(v1,a1);
+  na_copy_nary(a1,a2);
+  return v1;
+}
+
+
+VALUE
+ na_change_type(VALUE obj, int type)
+{
+  struct NARRAY *a2;
+
+  GetNArray(obj,a2);
+
+  if (a2->type == type)
+    return obj;
+
+  return na_dup_w_type(obj, type);
+}
+
+
+VALUE
+ na_upcast_type(VALUE obj, int type)  /* na_upcast_narray */
+{
+  int newtype;
+  struct NARRAY *a2;
+
+  GetNArray(obj,a2);
+  newtype = na_upcast[a2->type][type];
+
+  if (newtype == a2->type)
+    return obj;
+
+  return na_dup_w_type(obj, newtype);
+}
+
+
+/* obj.kind_of?(Object) == true */
+
+VALUE
+ na_cast_object(VALUE obj, int type) /* na_cast_certain */
+{
+  if (IsNArray(obj)) {
+    return na_change_type(obj,type);
+  }
+  if (TYPE(obj) == T_ARRAY) {
+    return na_ary_to_nary_w_type(obj,type,cNArray);
+  }
+  return na_make_scalar(obj,type);
+}
+
+
+VALUE
+ na_cast_unless_narray(VALUE obj, int type)
+{
+  if (IsNArray(obj)) {
+    return obj;
+  }
+  if (TYPE(obj) == T_ARRAY) {
+    return na_ary_to_nary_w_type(obj,type,cNArray);
+  }
+  return na_make_scalar(obj,type);
+}
+
+
+VALUE
+ na_cast_unless_array(VALUE obj, int type)
+{
+  if (IsNArray(obj)) {
+    return obj;
+  }
+  if (TYPE(obj) == T_ARRAY) {
+    return na_ary_to_nary(obj,cNArray);
+  }
+  return na_make_scalar(obj,type);
+}
+
+
+VALUE
+ na_upcast_object(VALUE obj, int type)
+{
+  if (IsNArray(obj)) {
+    return na_upcast_type(obj,type);
+  }
+  if (TYPE(obj) == T_ARRAY) {
+    return na_ary_to_nary_w_type(obj,type,cNArray);
+  }
+  return na_make_scalar(obj,type);
+}
+
+
+/* :nodoc: */
+VALUE
+ na_to_narray(VALUE obj)
+{
+  if (IsNArray(obj)) {
+    return obj;
+  }
+  if (TYPE(obj) == T_ARRAY) {
+    return na_ary_to_nary(obj,cNArray);
+  }
+  return na_make_scalar(obj,na_object_type(obj));
+}
+
+
+/* convert NArray to Array */
+static VALUE
+ na_to_array0(struct NARRAY* na, int *idx, int thisrank, void (*func)())
+{
+  int i, elmsz;
+  char *ptr;
+  VALUE ary, val;
+
+  /* Create New Array */
+  ary = rb_ary_new2(na->shape[thisrank]);
+
+  if (thisrank == 0) {
+    ptr   = NA_PTR( na, na_index_pos(na,idx) );
+    elmsz = na_sizeof[na->type];
+    for (i = na->shape[0]; i; --i) {
+      (*func)( 1, &val, 0, ptr, 0 );
+      ptr += elmsz;
+      rb_ary_push( ary, val );
+    }
+  }
+  else {
+    for (i = 0; i < na->shape[thisrank]; ++i) {
+      idx[thisrank] = i;
+      rb_ary_push( ary, na_to_array0(na,idx,thisrank-1,func) );
+    }
+  }
+  return ary;
+}
+
+
+/* method: to_a -- convert itself to Array */
+VALUE
+ na_to_array(VALUE obj)
+{
+  struct NARRAY *na;
+  int *idx, i;
+
+  GetNArray(obj,na);
+
+  if (na->rank<1)
+    return rb_ary_new();
+
+  idx = ALLOCA_N(int,na->rank);
+  for (i = 0; i<na->rank; ++i) idx[i] = 0;
+  return na_to_array0(na,idx,na->rank-1,SetFuncs[NA_ROBJ][na->type]);
+}
+
+
+static VALUE
+ na_inspect_col( int n, char *p2, int p2step, void (*tostr)(),
+		 VALUE sep, int rank )
+{
+  VALUE str=Qnil, tmp;
+  int max_col = 77;
+  int sep_len = RSTRING_LEN(sep);
+
+  if (n>0)
+    (*tostr)(&str,p2);
+
+  for (n--; n>0; --n) {
+    p2 += p2step;
+    (*tostr)(&tmp,p2);
+
+    if (!NIL_P(sep)) rb_str_concat(str, sep);
+
+    if (RSTRING_LEN(str) + RSTRING_LEN(tmp) + rank*4 + sep_len < max_col) {
+      rb_str_concat(str, tmp);
+    } else {
+      rb_str_cat(str,"...",3);
+      return str;
+    }
+  }
+  return str;
+}
+
+
+/*
+ *   Create inspect string ... under construction
+ */
+
+VALUE
+ na_make_inspect(VALUE val)
+{
+  int   i, ii, rank, count_line=0, max_line=10;
+  int  *si;
+  struct NARRAY *ary;
+  struct slice *s1;
+
+  VALUE fs = rb_str_new(", ",2);
+
+  GetNArray(val,ary);
+  if (ary->total < 1) return rb_str_new(0, 0);
+
+  /* Allocate Structure */
+  rank = ary->rank;
+  s1 = ALLOCA_N(struct slice, rank+1);
+  si = ALLOCA_N(int,rank);
+  na_set_slice_1obj(rank,s1,ary->shape);
+
+  /* Iteration */
+  na_init_slice(s1, rank, ary->shape, na_sizeof[ary->type]);
+  i = rank;
+  s1[i].p = ary->ptr;
+  val = rb_str_new(0,0);
+  for(;;) {
+    /* set pointers */
+    while (i > 0) {
+      --i;
+      rb_str_cat(val, "[ ", 2);
+      s1[i].p = s1[i].pbeg + s1[i+1].p;
+      si[i] = s1[i].n;
+    }
+
+    rb_str_concat(val, na_inspect_col( s1[0].n, s1[0].p, s1[0].pstep,
+				       InspFuncs[ary->type], fs, rank ));
+
+    /* rank up */
+    do {
+      rb_str_cat(val, " ]", 2);
+      if ( ++i == rank ) return val;
+    } while ( --si[i] == 0 );
+    s1[i].p += s1[i].pstep;
+
+    rb_str_concat(val, fs);
+    rb_str_cat(val, "\n", 1);
+
+    /* count check */
+    if (++count_line>=max_line) {
+      rb_str_cat(val, " ...", 4);
+      return val;
+    }
+    /* indent */
+    for (ii=i; ii<rank; ++ii)
+      rb_str_cat(val, "  ", 2);
+  }
+}
+
+
+void Init_na_array() {
+    rb_define_method(cNArray, "to_a", na_to_array,0); //
+}
diff --git a/app/server/vendor/narray-0.6.1.1/na_func.c b/app/server/vendor/narray-0.6.1.1/na_func.c
new file mode 100755
index 0000000..ba9145a
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/na_func.c
@@ -0,0 +1,1706 @@
+/*
+  na_func.c
+  Numerical Array Extention for Ruby
+    (C) Copyright 1999-2008 by Masahiro TANAKA
+
+  This program is free software.
+  You can distribute/modify this program
+  under the same terms as Ruby itself.
+  NO WARRANTY.
+*/
+#include <ruby.h>
+#include "narray.h"
+#include "narray_local.h"
+
+int
+ na_max3(int a, int b, int c)
+{
+  int m;
+
+  if ((a) > (b))
+    m = a;
+  else
+    m = b;
+  if ((c) > m)
+    m = c;
+  return m;
+}
+
+
+void
+  na_shape_max3(int ndim, int *max_shp, int *shp1, int *shp2, int *shp3)
+{
+  int i;
+
+  for (i=0; i<ndim; ++i) {
+    max_shp[i] = na_max3(shp1[i], shp2[i], shp3[i]);
+  }
+}
+
+
+/* initialize slice structure */
+void na_init_slice( struct slice *s, int rank, int *shape, int elmsz )
+{
+  int r, i, b;
+  na_index_t *idx;
+
+  /*
+  if (rank<1)
+    rb_raise(rb_eRuntimeError,"cannot execute for empty array");
+  */
+
+  /* set strides and clear index */
+  s[0].stride = 1;
+  for (r=1; r<rank; ++r)
+    s[r].stride = s[r-1].stride * shape[r-1];
+
+  for (r=0; r<rank; ++r) {
+    if ( s[r].idx == NULL )
+      /* regular interval */
+      s[r].pstep = s[r].step * s[r].stride * elmsz;
+    else {
+      /* index */
+      s[r].pstep = b = s[r].stride * elmsz;
+      /* convert index to byte-unit */
+      for (i=0; i<16; ++i)
+	if ( (1<<i) == b ) { b=i; break; }
+      if (i==16)
+	for (idx=s[r].idx,i=s[r].n; i-->0; ) { *(idx++)*=b; }
+      else
+	for (idx=s[r].idx,i=s[r].n; i-->0; ) { *(idx++)<<=b; }
+    }
+  }
+
+  /* set termination mark */
+  s[rank].n = 0;
+  s[rank].idx = NULL;
+
+  for (r=rank-1;r>=0;--r) {
+    /* set beginning pointers */
+    if ( s[r].idx == NULL )
+      s[r].pbeg = s[r].stride * s[r].beg * elmsz;
+    else
+      s[r].pbeg = s[r].idx[0];
+  }
+}
+
+
+static void
+ na_do_loop_unary( int nd, char *p1, char *p2,
+		   struct slice *s1, struct slice *s2, void (*func)() )
+{
+  int *si;
+  int  i;
+  int  ps1 = s1[0].pstep;
+  int  ps2 = s2[0].pstep;
+
+  i  = nd;
+  si = ALLOCA_N(int,nd);
+  s1[i].p = p1;
+  s2[i].p = p2;
+
+  for(;;) {
+    /* set pointers */
+    while (i > 0) {
+      --i;
+      s2[i].p = s2[i].pbeg + s2[i+1].p;
+      s1[i].p = s1[i].pbeg + s1[i+1].p;
+      si[i] = s1[i].n;
+    }
+    (*func)(s2[0].n, s1[0].p, ps1, s2[0].p, ps2);
+    /* rank up */
+    do {
+      if ( ++i >= nd ) return;
+    } while ( --si[i] == 0 );
+    /* next point */
+    s1[i].p += s1[i].pstep;
+    s2[i].p += s2[i].pstep;
+  }
+}
+
+
+static void
+ na_do_loop_binary( int nd, char *p1, char *p2, char *p3,
+		    struct slice *s1, struct slice *s2, struct slice *s3,
+		    void (*func)() )
+{
+  int i;
+  int ps1 = s1[0].pstep;
+  int ps2 = s2[0].pstep;
+  int ps3 = s3[0].pstep;
+  int *si;
+
+  si = ALLOCA_N(int,nd);
+  i  = nd;
+  s1[i].p = p1;
+  s2[i].p = p2;
+  s3[i].p = p3;
+
+  for(;;) {
+    /* set pointers */
+    while (i > 0) {
+      --i;
+      s3[i].p = s3[i].pbeg + s3[i+1].p;
+      s2[i].p = s2[i].pbeg + s2[i+1].p;
+      s1[i].p = s1[i].pbeg + s1[i+1].p;
+      si[i] = s1[i].n;
+    }
+    /* rank 0 loop */
+    (*func)(s2[0].n, s1[0].p, ps1, s2[0].p, ps2, s3[0].p, ps3);
+    /* rank up */
+    do {
+      if ( ++i >= nd ) return;
+    } while ( --si[i] == 0 );
+    /* next point */
+    s1[i].p += s1[i].pstep;
+    s2[i].p += s2[i].pstep;
+    s3[i].p += s3[i].pstep;
+  }
+}
+
+
+
+void na_loop_index_ref( struct NARRAY *a1, struct NARRAY *a2,
+			struct slice *s1, struct slice *s2, void (*func)() )
+{
+  char *p1, *p2;
+  int nr, i, ii;
+  int ps1 = s1[0].pstep;
+  int ps2 = s2[0].pstep;
+  int *si;
+  na_index_t *idx;
+
+  /*
+  int copy;
+  if (a1->type==a2->type && s1[0].step==1 && s2[0].step==1)
+    copy = s1[0].n * na_sizeof[a1->type];
+  else
+    copy = 0;
+  */
+
+  /* Initialize */
+  nr = i = a1->rank;
+  si = ALLOCA_N(int,nr);
+  s1[i].p = a1->ptr;
+  s2[i].p = a2->ptr;
+
+  for(;;) {
+    /* set pointers */
+    while (i > 0) {
+      --i;
+      s2[i].p = s2[i].pbeg + s2[i+1].p;
+      s1[i].p = s1[i].pbeg + s1[i+1].p;
+      si[i] = 0;
+    }
+
+    /* rank 0 loop */
+    if ( s2[0].idx == NULL ) {
+      /* regular interval */
+      /*
+      if (copy) {
+	memcpy(s1[0].p, s2[0].p, copy);
+      } else
+      */
+      (*func)(s2[0].n, s1[0].p, ps1, s2[0].p, ps2);
+    } else {
+      /* a2 has index */
+      p1 = s1[0].p;
+      p2 = s2[1].p;
+      for ( idx=s2[0].idx, ii=s2[0].n; ii-->0;) {
+	(*func)( 1, p1, 0, p2+*(idx++), 0 );
+	p1 += ps1;
+      }
+    }
+    /* rank up */
+    do {
+      if ( ++i >= nr ) return;
+    } while ( ++si[i] == s1[i].n );
+    /* next point */
+    s1[i].p += s1[i].pstep;
+    /* array2 may have index */
+    if ( s2[i].idx == NULL )
+      s2[i].p += s2[i].pstep;
+    else
+      s2[i].p = s2[i+1].p + s2[i].idx[si[i]]; /* * s2[i].pstep; */
+  }
+}
+
+
+void na_loop_general( struct NARRAY *a1, struct NARRAY *a2,
+		      struct slice *s1, struct slice *s2, void (*func)() )
+{
+  char *p1, *p2;
+  int nr, i, ii;
+  int ps1 = s1[0].pstep;
+  int ps2 = s2[0].pstep;
+  int *si;
+  na_index_t *idx1, *idx2;
+
+  /* Initialize */
+  nr = i = a1->rank;
+  si = ALLOCA_N(int,nr);
+  s1[i].p = a1->ptr;
+  s2[i].p = a2->ptr;
+
+  for(;;) {
+    /* set pointers */
+    while (i > 0) {
+      --i;
+      s2[i].p = s2[i].pbeg + s2[i+1].p;
+      s1[i].p = s1[i].pbeg + s1[i+1].p;
+      si[i] = 0;
+    }
+
+    /* rank 0 loop */
+    if ( s1[0].idx == NULL ) {
+      if ( s2[0].idx == NULL ) {
+	/* normal interval */
+	(*func)(s2[0].n, s1[0].p, ps1, s2[0].p, ps2);
+      } else {
+	/* s2 has index */
+	p1 = s1[0].p;
+	p2 = s2[1].p;
+	for ( idx2=s2[0].idx, ii=s2[0].n; ii-->0; ) {
+	  (*func)( 1, p1, 0, p2+*(idx2++), 0 );
+	  p1 += ps1;
+	}
+      }
+    } else {
+      if ( s2[0].idx == NULL ) {
+	/* s1 has index */
+	p1 = s1[1].p;
+	p2 = s2[0].p;
+	for ( idx1=s1[0].idx, ii=s2[0].n; ii-->0; ) {
+	  (*func)( 1, p1+*(idx1++), 0, p2, 0 );
+	  p2 += ps2;
+	}
+      } else {
+	/* s1 & s2 has index */
+	p1 = s1[1].p;
+	p2 = s2[1].p;
+	for ( idx1=s1[0].idx, idx2=s2[0].idx, ii=s2[0].n; ii-->0; ) {
+	  (*func)( 1, p1+*(idx1++), 0, p2+*(idx2++), 0 );
+	}
+      }
+    }
+
+    /* rank up */
+    do {
+      if ( ++i >= nr ) return;
+    } while ( ++si[i] == s1[i].n );
+
+    /* next point for a1 */
+    if ( s1[i].idx == NULL )
+      s1[i].p += s1[i].pstep;
+    else
+      s1[i].p = s1[i+1].p + s1[i].idx[si[i]];
+    /* next point for a2 */
+    if ( s2[i].idx == NULL )
+      s2[i].p += s2[i].pstep;
+    else
+      s2[i].p = s2[i+1].p + s2[i].idx[si[i]];
+  }
+}
+
+
+void
+ na_shape_copy( int ndim, int *shape, struct NARRAY *a )
+{
+  int i;
+
+  for (i=0; i<a->rank; ++i)
+    shape[i] = a->shape[i];
+  for (   ; i<ndim; ++i)
+    shape[i] = 1;
+}
+
+
+void
+ na_set_slice_1obj( int ndim, struct slice *slc, int *shape )
+{
+  int i;
+
+  /* for normal access */
+  for (i=0; i<ndim; ++i) {
+    slc[i].n    = shape[i];
+    slc[i].beg  = 0;
+    slc[i].step = 1;
+    slc[i].idx  = NULL;
+  }
+}
+
+
+
+static int
+ na_set_slice_2obj( int ndim, struct slice *s1, struct slice *s2,
+		    int *shp1, int *shp2 )
+{
+  int i, j;
+
+  for (i=j=0; i<ndim; ++i) {
+
+    if ( shp1[i]==1 && shp2[i]>1 ) {
+      s1[j].n    =
+      s2[j].n    = shp2[i];
+      s1[j].step = 0;
+      s2[j].step = 1;
+    } else
+    if ( shp2[i]==1 && shp1[i]>1 ) {
+      s1[j].n    =
+      s2[j].n    = shp1[i];
+      s1[j].step = 1;
+      s2[j].step = 0;
+    } else
+    if ( shp1[i] == shp2[i] ) {
+      s1[j].n    =
+      s2[j].n    = shp1[i];
+      s1[j].step = 1;
+      s2[j].step = 1;
+    } else
+      rb_raise(rb_eRuntimeError, "Array size mismatch: %i != %i in %i-th dim",
+	       shp1[i], shp2[i], i);
+
+    if (j<i) {
+      shp1[j] = shp1[i];
+      shp2[j] = shp2[i];
+    }
+
+    if (j>0)
+      if ( s1[j].step == s1[j-1].step &&
+	   s2[j].step == s2[j-1].step   ) {   /* contract dimension */
+	s1[j-1].n  =
+	s2[j-1].n *= s2[j].n;
+	shp1[j-1] *= shp1[j];
+	shp2[j-1] *= shp2[j];
+	continue;
+      }
+    s1[j].beg =
+    s2[j].beg = 0;
+    s1[j].idx =
+    s2[j].idx = NULL;
+    ++j;
+  }
+
+  return j;
+}
+
+
+static int
+ na_set_slice_check(int ary_sz, int itr_sz, int i)
+{
+  if ( ary_sz == itr_sz )
+    return 1;
+  else if ( ary_sz == 1 )
+    return 0;
+  else
+    rb_raise(rb_eRuntimeError, "Array size mismatch: %i != %i at %i-th dim",
+	     ary_sz, itr_sz, i);
+}
+
+
+int
+ na_set_slice_3obj( int ndim,
+		    struct slice *s1, struct slice *s2, struct slice *s3,
+		    int *shp1, int *shp2, int *shp3, int *shape )
+{
+  int i, j;
+
+  /* for repetitous access */
+  for (i=j=0; i<ndim; ++i) {
+
+    s1[j].step = na_set_slice_check(shp1[i],shape[i],i);
+    s2[j].step = na_set_slice_check(shp2[i],shape[i],i);
+    s3[j].step = na_set_slice_check(shp3[i],shape[i],i);
+
+    if (j<i) {
+      shp1[j] = shp1[i];
+      shp2[j] = shp2[i];
+      shp3[j] = shp3[i];
+    }
+
+    if (j>0) {
+      if ( s1[j].step == s1[j-1].step &&
+	   s2[j].step == s2[j-1].step &&
+	   s3[j].step == s3[j-1].step   )   /* contract dimension */
+      {
+	s1[j-1].n =
+	s2[j-1].n =
+	s3[j-1].n *= shape[i];
+
+	shp1[j-1] *= shp1[j];
+	shp2[j-1] *= shp2[j];
+	shp3[j-1] *= shp3[j];
+	continue;
+      }
+    }
+
+    s1[j].n   =
+    s2[j].n   =
+    s3[j].n   = shape[i];
+
+    s1[j].beg =
+    s2[j].beg =
+    s3[j].beg = 0;
+
+    s1[j].idx =
+    s2[j].idx =
+    s3[j].idx = NULL;
+
+    ++j;
+  }
+
+  return j;
+}
+
+
+static void
+ na_exec_unary(struct NARRAY *a1, struct NARRAY *a2, void (*func)())
+{
+  int  ndim;
+  int *shp1, *shp2;
+  struct slice *s1, *s2;
+
+  /* empty check */
+  if ( a1->total==0 || a2->total==0 )
+    /* rb_raise( rb_eTypeError, "cannot execute for empty array" ); */
+    return; /* do nothing */
+
+  ndim = NA_MAX(a1->rank,a2->rank);
+
+  NA_ALLOC_SLICE(s1,(ndim+1)*2,shp1,ndim*2);
+  shp2 = &shp1[ndim];
+  s2   = &s1[ndim+1];
+
+  na_shape_copy( ndim, shp1, a1 );
+  na_shape_copy( ndim, shp2, a2 );
+
+  ndim = na_set_slice_2obj( ndim, s1, s2, shp1, shp2 );
+  na_init_slice( s1, ndim, shp1, na_sizeof[a1->type] );
+  na_init_slice( s2, ndim, shp2, na_sizeof[a2->type] );
+
+  na_do_loop_unary( ndim, a1->ptr, a2->ptr, s1, s2, func );
+
+  xfree(s1);
+}
+
+
+/* a1 and/or a2 and/or a3 have extensible index */
+static void
+ na_exec_binary( struct NARRAY *a1, struct NARRAY *a2,
+		 struct NARRAY *a3, void (*func)() )
+{
+  int   ndim;
+  int  *itr, *shp1, *shp2, *shp3;
+  struct slice *s1, *s2, *s3;
+
+  /* empty check */
+  if (a1->total==0) return; /* do nothing */
+
+  ndim = na_max3(a1->rank, a2->rank, a3->rank);
+
+  NA_ALLOC_SLICE(s1,(ndim+1)*3,shp1,ndim*4);
+  shp2 = &shp1[ndim];
+  shp3 = &shp2[ndim];
+  itr  = &shp3[ndim];
+  s2   = &s1[ndim+1];
+  s3   = &s2[ndim+1];
+
+  na_shape_copy( ndim, shp1, a1 );
+  na_shape_copy( ndim, shp2, a2 );
+  na_shape_copy( ndim, shp3, a3 );
+  na_shape_max3( ndim, itr, shp1, shp2, shp3 );
+
+  ndim = na_set_slice_3obj( ndim, s1, s2, s3, shp1, shp2, shp3, itr );
+
+  na_init_slice(s1, ndim, shp1, na_sizeof[a1->type] );
+  na_init_slice(s2, ndim, shp2, na_sizeof[a2->type] );
+  na_init_slice(s3, ndim, shp3, na_sizeof[a3->type] );
+
+  na_do_loop_binary( ndim, a1->ptr, a2->ptr, a3->ptr, s1, s2, s3, func );
+  xfree(s1);
+}
+
+
+static void
+ na_shape_max_2obj(int ndim, int *shape, struct NARRAY *a1, struct NARRAY *a2)
+{
+  struct NARRAY *tmp;
+  int  i;
+
+  /* empty check */
+  if ( a1->total==0 || a2->total==0 )
+    rb_raise( rb_eTypeError, "cannot execute for empty array" );
+
+  if (a1->rank < a2->rank) {
+    NA_SWAP(a1,a2,tmp);
+  }
+
+  for (i=0; i<a2->rank; ++i) {
+    shape[i] = NA_MAX(a1->shape[i],a2->shape[i]);
+  }
+  for (   ; i<a1->rank; ++i) {
+    shape[i] = a1->shape[i];
+  }
+  for (   ; i<ndim; ++i) {
+    shape[i] = 1;
+  }
+}
+
+
+static VALUE
+ na_make_object_extend(struct NARRAY *a1, struct NARRAY *a2,
+		       int type, VALUE klass)
+{
+  int  ndim;
+  int *shape;
+
+  /* empty check */
+  if ( a1->total==0 || a2->total==0 )
+    return na_make_empty(type, klass); /* return empty */
+
+  ndim  = NA_MAX(a1->rank, a2->rank);
+  shape = ALLOCA_N(int, ndim);
+  na_shape_max_2obj( ndim, shape, a1, a2 );
+
+  return na_make_object( type, ndim, shape, klass );
+}
+
+
+static ID na_bifunc_to_id(na_bifunc_t funcs)
+{
+  if (funcs==AddBFuncs)	return na_id_add;
+  if (funcs==SbtBFuncs)	return na_id_sbt;
+  if (funcs==MulBFuncs)	return na_id_mul;
+  if (funcs==DivBFuncs)	return na_id_div;
+  if (funcs==ModBFuncs)	return na_id_mod;
+  return 0;
+  /* if (funcs==PowFuncs)	return na_id_power;
+     rb_raise(rb_eRuntimeError, "coerce_rev: function not soppurted");
+  */
+}
+
+
+static VALUE
+ na_bifunc_class(VALUE klass1, VALUE klass2)
+{
+  if ( klass2==cNArray || klass2==cNArrayScalar ) {
+    if ( klass1==cNArrayScalar ) return cNArray;
+    else return klass1;
+  }
+  return Qnil;
+}
+
+
+static VALUE
+ na_bifunc(VALUE obj1, VALUE obj2, VALUE klass, na_bifunc_t funcs)
+{
+  VALUE obj3;
+  ID id;
+  int type;
+
+  Check_Type(obj1, T_DATA);
+  obj2 = na_upcast_object(obj2,NA_STRUCT(obj1)->type);
+  obj1 = na_upcast_type(obj1,type=NA_STRUCT(obj2)->type);
+
+  if (klass==Qnil) {
+    klass = na_bifunc_class(CLASS_OF(obj1),CLASS_OF(obj2));
+
+    if (klass==Qnil) { /* coerce_rev */
+      if ((id=na_bifunc_to_id(funcs))!=0)
+	return rb_funcall( obj2, na_id_coerce_rev, 2, obj1, ID2SYM(id) );
+      else
+	klass = cNArray;
+    }
+  }
+
+  obj3 = na_make_object_extend(NA_STRUCT(obj1),NA_STRUCT(obj2),type,klass);
+
+  na_exec_binary( NA_STRUCT(obj3), NA_STRUCT(obj1), NA_STRUCT(obj2),
+		  funcs[type] );
+
+  return obj3;
+}
+
+
+static VALUE
+ na_power(VALUE val1, VALUE val2)
+{
+  volatile VALUE obj1, obj2, obj3;
+  struct NARRAY *a1, *a2;
+
+  obj1 = val1;
+  obj2 = val2;
+  GetNArray(obj1,a1);
+  obj2 = na_to_narray(obj2);
+  GetNArray(obj2,a2);
+
+  if (a1->type==NA_ROBJ && a2->type!=NA_ROBJ) {
+    obj2 = na_change_type(obj2,NA_ROBJ);
+    GetNArray(obj2,a2);
+  } else
+  if (a2->type==NA_ROBJ && a1->type!=NA_ROBJ) {
+    obj1 = na_change_type(obj1,NA_ROBJ);
+    GetNArray(obj1,a1);
+  } else
+  if (!NA_IsCOMPLEX(a1) && NA_IsCOMPLEX(a2)) {
+    obj1 = na_upcast_type(obj1,a2->type);
+    GetNArray(obj1,a1);
+  }
+
+  obj3 = na_make_object_extend( a1, a2, na_upcast[a1->type][a2->type],
+				CLASS_OF(obj1) );
+
+  na_exec_binary( NA_STRUCT(obj3), a1, a2,
+		  PowFuncs[a1->type][a2->type] );
+
+  return obj3;
+}
+
+
+static VALUE
+ na_set_func(VALUE obj1, volatile VALUE obj2, na_ufunc_t funcs)
+{
+  struct NARRAY *a1;
+
+  GetNArray(obj1,a1);
+  obj2 = na_cast_object(obj2,a1->type);
+
+  na_exec_unary( NA_STRUCT(obj1), NA_STRUCT(obj2), funcs[a1->type] );
+
+  return obj1;
+}
+
+
+static VALUE
+ na_imag_set(VALUE obj1, volatile VALUE obj2)
+{
+  struct NARRAY *a1;
+
+  GetNArray(obj1,a1);
+  obj2 = na_cast_object(obj2, na_cast_real[a1->type]);
+
+  na_exec_unary( NA_STRUCT(obj1), NA_STRUCT(obj2), ImgSetFuncs[a1->type] );
+
+  return obj1;
+}
+
+
+static VALUE
+ na_unary_func(VALUE self, const int *cast, na_ufunc_t funcs)
+{
+  VALUE ans;
+  struct NARRAY *a2;
+
+  GetNArray(self,a2);
+  ans = na_make_object(cast[a2->type], a2->rank, a2->shape, CLASS_OF(self));
+
+  na_exec_unary( NA_STRUCT(ans), a2, funcs[a2->type] );
+  return ans;
+}
+
+
+
+/* local function for comparison */
+static VALUE
+ na_compare_func(VALUE self, VALUE other, na_bifunc_t funcs)
+{
+  VALUE ans;
+  int type;
+
+  Check_Type(self, T_DATA);
+  /*if (NA_IsComplex(a1)) rb_raise();*/
+  other = na_upcast_object(other,NA_STRUCT(self)->type);
+  self = na_upcast_type(self,type=NA_STRUCT(other)->type);
+
+  ans = na_make_object_extend( NA_STRUCT(self), NA_STRUCT(other),
+			       NA_BYTE, cNArray );
+
+  na_exec_binary( NA_STRUCT(ans), NA_STRUCT(self), NA_STRUCT(other),
+		  funcs[type] );
+  return ans;
+}
+
+
+/* method: self + other */
+static VALUE na_add(VALUE obj1, VALUE obj2)
+{ return na_bifunc( obj1, obj2, Qnil, AddBFuncs ); }
+
+/* method: self - other */
+static VALUE na_sbt(VALUE obj1, VALUE obj2)
+{ return na_bifunc( obj1, obj2, Qnil, SbtBFuncs ); }
+
+/* method: self * other */
+static VALUE na_mul(VALUE obj1, VALUE obj2)
+{ return na_bifunc( obj1, obj2, Qnil, MulBFuncs ); }
+
+/* method: self / other */
+static VALUE na_div(VALUE obj1, VALUE obj2)
+{ return na_bifunc( obj1, obj2, Qnil, DivBFuncs ); }
+
+/* method: self / other */
+static VALUE na_mod(VALUE obj1, VALUE obj2)
+{ return na_bifunc( obj1, obj2, Qnil, ModBFuncs ); }
+
+/* method: self & other */
+static VALUE na_bit_and(VALUE obj1, VALUE obj2)
+{ return na_bifunc( obj1, obj2, Qnil, BAnFuncs ); }
+
+/* method: self | other */
+static VALUE na_bit_or(VALUE obj1, VALUE obj2)
+{ return na_bifunc( obj1, obj2, Qnil, BOrFuncs ); }
+
+/* method: self ^ other */
+static VALUE na_bit_xor(VALUE obj1, VALUE obj2)
+{ return na_bifunc( obj1, obj2, Qnil, BXoFuncs ); }
+
+/* method: atan2(y,x) */
+static VALUE na_math_atan2(VALUE module, volatile VALUE y, volatile VALUE x)
+{
+  VALUE ans;
+  struct NARRAY *ya, *xa, *aa;
+
+  if (TYPE(y) == T_ARRAY) {
+    y = na_ary_to_nary(y,cNArray);
+  } else
+  if (!IsNArray(y)) {
+    y = na_make_scalar(y,na_object_type(y));
+  }
+
+  if (TYPE(x) == T_ARRAY) {
+    x = na_ary_to_nary(x,cNArray);
+  } else
+  if (!IsNArray(x)) {
+    x = na_make_scalar(x,na_object_type(x));
+  }
+
+  GetNArray(y,ya);
+  GetNArray(x,xa);
+  if (NA_IsINTEGER(ya) && NA_IsINTEGER(xa)) {
+    y = na_upcast_type(y,NA_DFLOAT);
+    x = na_upcast_type(x,NA_DFLOAT);
+  }
+
+  ans = na_bifunc( y, x, Qnil, atan2Funcs );
+  GetNArray(ans,aa);
+
+  if (CLASS_OF(y) == cNArrayScalar && CLASS_OF(x) == cNArrayScalar)
+    SetFuncs[NA_ROBJ][aa->type](1,&ans,0,aa->ptr,0);
+
+  return ans;
+}
+
+
+
+/* singleton method: NArray.mul( obj1, obj2 ) */
+static VALUE
+ na_s_mul(VALUE klass, VALUE obj1, VALUE obj2)
+{ return na_bifunc( obj1, obj2, klass, MulBFuncs ); }
+
+/* singleton method: NArray.div( obj1, obj2 ) */
+static VALUE
+ na_s_div(VALUE klass, VALUE obj1, VALUE obj2)
+{ return na_bifunc( obj1, obj2, klass, DivBFuncs ); }
+
+
+
+/* method: self.add!(other) */
+static VALUE na_add_bang(VALUE obj1, VALUE obj2)
+{ return na_set_func( obj1, obj2, AddUFuncs ); }
+
+/* method: self.sbt!(other) */
+static VALUE na_sbt_bang(VALUE obj1, VALUE obj2)
+{ return na_set_func( obj1, obj2, SbtUFuncs ); }
+
+/* method: self.div!(other) */
+static VALUE na_div_bang(VALUE obj1, VALUE obj2)
+{ return na_set_func( obj1, obj2, DivUFuncs ); }
+
+/* method: self.mul!(other) */
+static VALUE na_mul_bang(VALUE obj1, VALUE obj2)
+{ return na_set_func( obj1, obj2, MulUFuncs ); }
+
+/* method: self.mod!(other) */
+static VALUE na_mod_bang(VALUE obj1, VALUE obj2)
+{ return na_set_func( obj1, obj2, ModUFuncs ); }
+
+/* method: self.conj! */
+static VALUE na_conj_bang(VALUE self)
+{ return na_set_func( self, self, ConjFuncs ); }
+
+
+/* method: self.swap_byte */
+static VALUE na_swap_byte(VALUE self)
+{ return na_unary_func( self, na_no_cast, SwpFuncs ); }
+
+/* method: self.hton , self.ntoh */
+static VALUE na_hton(VALUE self)
+{ return na_unary_func( self, na_no_cast, H2NFuncs ); }
+
+/* method: self.htov , self.vtoh */
+static VALUE na_htov(VALUE self)
+{ return na_unary_func( self, na_no_cast, H2VFuncs ); }
+
+/* method: ~self */
+static VALUE na_bit_rev(VALUE self)
+{ return na_unary_func( self, na_no_cast, BRvFuncs ); }
+
+/* method: -self */
+static VALUE na_neg(VALUE self)
+{ return na_unary_func( self, na_no_cast, NegFuncs ); }
+
+/* method: self.recip */
+static VALUE na_recip(VALUE self)
+{ return na_unary_func( self, na_no_cast, RcpFuncs ); }
+
+/* method: self.abs */
+static VALUE na_abs(VALUE self)
+{ return na_unary_func( self, na_cast_real, AbsFuncs ); }
+
+/* method: self.real */
+static VALUE na_real(VALUE self)
+{ return na_unary_func( self, na_cast_real, RealFuncs ); }
+
+/* method: self.imag */
+static VALUE na_imag(VALUE self)
+{ return na_unary_func( self, na_cast_real, ImagFuncs ); }
+
+/* method: self.imag */
+static VALUE na_angle(VALUE self)
+{ return na_unary_func( self, na_cast_real, AnglFuncs ); }
+
+/* method: self.im */
+static VALUE na_imag_mul(VALUE self)
+{ return na_unary_func( self, na_cast_comp, ImagMulFuncs ); }
+
+/* method: self.conj */
+static VALUE na_conj(VALUE self)
+{ return na_unary_func( self, na_no_cast, ConjFuncs ); }
+
+/* method: self.floor */
+static VALUE na_floor(VALUE self)
+{ return na_unary_func( self, na_cast_round, FloorFuncs ); }
+
+/* method: self.ceil */
+static VALUE na_ceil(VALUE self)
+{ return na_unary_func( self, na_cast_round, CeilFuncs ); }
+
+/* method: self.round */
+static VALUE na_round(VALUE self)
+{ return na_unary_func( self, na_cast_round, RoundFuncs ); }
+
+/* method: self.not */
+static VALUE na_not(VALUE self)
+{ return na_unary_func( self, na_cast_byte, NotFuncs ); }
+
+
+/* method: self.and other */
+static VALUE
+ na_cond_and(VALUE obj1, VALUE obj2)
+{ return na_compare_func( obj1, obj2, AndFuncs ); }
+
+/* method: self.or other */
+static VALUE
+ na_cond_or(VALUE obj1, VALUE obj2)
+{ return na_compare_func( obj1, obj2, Or_Funcs ); }
+
+/* method: self.xor other */
+static VALUE
+ na_cond_xor(VALUE obj1, VALUE obj2)
+{ return na_compare_func( obj1, obj2, XorFuncs ); }
+
+
+
+/* method: self <=> other */
+static VALUE
+ na_compare(VALUE obj1, VALUE obj2)
+{ return na_compare_func( obj1, obj2, CmpFuncs ); }
+
+
+
+/* method: self.eq(other) */
+static VALUE
+ na_equal(VALUE obj1, VALUE obj2)
+{
+  return na_compare_func( obj1, obj2, EqlFuncs );
+}
+
+/* method: self.ne(other) */
+static VALUE
+ na_not_equal(VALUE obj1, VALUE obj2)
+{
+  VALUE obj;
+  int  i;  char *p;
+  struct NARRAY *a;
+
+  obj = na_compare_func( obj1, obj2, EqlFuncs );
+  GetNArray(obj,a);
+  p = a->ptr;
+  for( i=a->total; i-->0; ) {
+    *p = *p==0 ? 1 : 0;
+    ++p;
+  }
+  return obj;
+}
+
+/* method: self > other */
+static VALUE
+ na_greater_than(VALUE self, VALUE obj2)
+{
+  int  i;  char *p;
+  struct NARRAY *a;
+
+  self = na_compare_func( self, obj2, CmpFuncs );
+  GetNArray(self,a);
+  p = a->ptr;
+  for( i=a->total; i-->0; ) {
+    if (*p!=1) *p=0;
+    ++p;
+  }
+  return self;
+}
+
+/* method: self >= other */
+static VALUE
+ na_greater_equal(VALUE obj1, VALUE obj2)
+{
+  VALUE obj;
+  int  i;  char *p;
+  struct NARRAY *a;
+
+  obj = na_compare_func( obj1, obj2, CmpFuncs );
+  GetNArray(obj,a);
+  p = a->ptr;
+  for( i=a->total; i-->0; ) {
+    if (*p==1 || *p==0) *p=1;
+    else *p=0;
+    ++p;
+  }
+  return obj;
+}
+
+/* method: self < other */
+static VALUE
+ na_less_than(VALUE obj1, VALUE obj2)
+{
+  VALUE obj;
+  int  i;  char *p;
+  struct NARRAY *a;
+
+  obj = na_compare_func( obj1, obj2, CmpFuncs );
+  GetNArray(obj,a);
+  p = a->ptr;
+  for( i=a->total; i-->0; ) {
+    if (*p==2) *p=1;
+    else *p=0;
+    ++p;
+  }
+  return obj;
+}
+
+/* method: self <= other */
+static VALUE
+ na_less_equal(VALUE obj1, VALUE obj2)
+{
+  VALUE obj;
+  int  i;  char *p;
+  struct NARRAY *a;
+
+  obj = na_compare_func( obj1, obj2, CmpFuncs );
+  GetNArray(obj,a);
+  p = a->ptr;
+  for( i=a->total; i-->0; ) {
+    if (*p==2 || *p==0) *p=1;
+    else *p=0;
+    ++p;
+  }
+  return obj;
+}
+
+
+
+
+/*
+ ------- Sum, Min, Max, Transpose --------
+*/
+VALUE
+ rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err );
+
+static int
+ na_arg_to_rank(int argc, VALUE *argv, int rankc, int *rankv, int flag)
+/* e.g.: argv=[1,3..5]
+	if flag==0
+	  rankv = [0,1,0,1,1,1,0,..]
+	else
+	  rankv = [1,3,4,5]
+*/
+{
+  int i, j, c=0;
+  long r, n;
+  VALUE v;
+  volatile VALUE s;
+
+  if (flag==0)
+    MEMZERO(rankv,int,rankc);
+
+  for (i=0;i<argc;++i) {
+    if ( c >= rankc )
+      rb_raise(rb_eArgError, "too many ranks");
+
+    v = argv[i];
+
+    if (TYPE(v)==T_FIXNUM) {
+      r = NUM2INT(v);
+      if (r<0) r += rankc;     /* negative for from end */
+      if (r<0 || r>=rankc)
+        rb_raise(rb_eArgError, "rank %ld out of range", r);
+      if (flag)
+	rankv[c] = r;
+      else
+	rankv[r] = 1;
+      ++c;
+    }
+    else
+    if (CLASS_OF(v)==rb_cRange) {
+      rb_range_beg_len( v, &r, &n, rankc, 1 );
+      if ( c+n > rankc ) {
+        s = rb_inspect(v);
+        rb_raise(rb_eArgError,"invalid dimension range: %s",StringValueCStr(s));
+      }
+      if (flag) {
+	for(j=0; j<n; ++j)
+	  rankv[c++] = r++;
+      } else {
+	for(j=0; j<n; ++j) {
+	  rankv[r++] = 1;
+	  ++c;
+	}
+      }
+    }
+    else
+      rb_raise(rb_eArgError, "wrong type");
+  }
+  return c;
+}
+
+
+
+/*  Transpose procedure  */
+static struct NARRAY *
+ na_transpose_bifunc(struct NARRAY *a1, struct NARRAY *a2, int *trans)
+{
+  int  i, ndim=a2->rank;
+  struct slice *s1, *s2;
+
+  s1 = ALLOC_N(struct slice, (ndim+1)*2);
+  s2 = &s1[ndim+1];
+
+  /* for Source array -- s1 is temporarily used */
+  na_set_slice_1obj(a2->rank,s1,a2->shape);
+  na_init_slice( s1, ndim, a2->shape, na_sizeof[a2->type] );
+
+  /* Transpose Slice */
+  for (i=0; i<ndim; ++i)
+    s2[i] = s1[trans[i]];
+  s2[ndim] = s1[ndim];
+
+  /* for Destination */
+  na_set_slice_1obj(a1->rank,s1,a1->shape);
+  na_init_slice( s1, ndim, a1->shape, na_sizeof[a1->type] );
+
+  /* Loop */
+  na_do_loop_unary( ndim, a1->ptr, a2->ptr, s1, s2,
+		    SetFuncs[a1->type][a2->type] );
+  xfree(s1);
+  return a1;
+}
+
+
+/* method: self.transpose( ... ) */
+static VALUE
+ na_transpose(int argc, VALUE *argv, VALUE self)
+{
+  struct NARRAY *a2;
+  int i, rankc, *rankv, *shape;
+  VALUE obj;
+
+  GetNArray(self,a2);
+
+  /* Parse Argument */
+  rankv = ALLOC_N( int, a2->rank*2 );
+  shape = &rankv[a2->rank];
+  rankc = na_arg_to_rank( argc, argv, a2->rank, rankv, 1 );
+  for ( ;rankc<a2->rank; ++rankc)
+    rankv[rankc] = rankc;
+
+  /* Argument Check */
+  MEMZERO(shape,int,rankc);
+  for (i=0; i<rankc; ++i) {
+    if (shape[rankv[i]] != 0)
+      rb_raise(rb_eArgError,"rank doublebooking");
+    shape[rankv[i]] = 1;
+  }
+
+  for (i=0; i<a2->rank; ++i)
+    shape[i] = a2->shape[rankv[i]];
+
+  obj = na_make_object(a2->type, a2->rank, shape, CLASS_OF(self));
+
+  na_transpose_bifunc( NA_STRUCT(obj), a2, rankv );
+  xfree(rankv);
+  return obj;
+}
+
+
+
+
+static void
+ na_accum_set_shape(int *itr_shape, int rank, int *ary_shape,
+		    int rankc, int *rankv)
+{
+  int i;
+
+  if (rankc==0) {
+    /* Accumulate all elements */
+    for (i=0; i<rank; ++i) {
+      itr_shape[i] = 1;
+      rankv[i] = 1;
+    }
+  } else {
+    /* Select Accumulate ranks */
+    for (i=0; i<rank; ++i) {
+      if (rankv[i]==1)
+	itr_shape[i] = 1;
+      else
+	itr_shape[i] = ary_shape[i];
+    }
+  }
+}
+
+
+static void
+ na_zero_obj(struct NARRAY *ary)
+{
+  int i;
+  VALUE zero = INT2FIX(0);
+  VALUE *v = (VALUE*)ary->ptr;
+
+  for (i=ary->total; i>0; --i)
+    *(v++) = zero;
+}
+
+static void
+ na_zero_data(struct NARRAY *ary)
+{
+  if (ary->type==NA_ROBJ)
+    na_zero_obj(ary);
+  else
+    na_clear_data(ary);
+}
+
+static VALUE
+ na_sum_body(int argc, VALUE *argv, VALUE self, int flag)
+{
+  int *shape, rankc, *rankv, cl_dim;
+  struct NARRAY *a1, *a2;
+  VALUE obj, klass;
+
+  GetNArray(self,a1);
+
+  rankv = ALLOC_N(int,a1->rank*2);
+  rankc = na_arg_to_rank( argc, argv, a1->rank, rankv, 0 );
+
+  shape = &rankv[a1->rank];
+  na_accum_set_shape( shape, a1->rank, a1->shape, rankc, rankv );
+
+  klass  = CLASS_OF(self);
+  cl_dim = na_class_dim(klass);
+  if (flag==0 && cl_dim>0 && na_shrink_class(cl_dim,rankv))
+    klass = cNArray;
+
+  obj = na_make_object(a1->type,a1->rank,shape,klass);
+  GetNArray(obj,a2);
+
+  na_zero_data(a2);
+  na_exec_unary( a2, a1, AddUFuncs[a1->type] );
+
+  if (flag==0)
+    obj = na_shrink_rank(obj,cl_dim,rankv);
+
+  xfree(rankv);
+  return obj;
+}
+
+/* method: sum( rank, ... ) */
+static VALUE
+ na_sum(int argc, VALUE *argv, VALUE self)
+{ return na_sum_body(argc,argv,self,0); }
+
+/* method: accum( rank, ... ) */
+static VALUE
+ na_accum(int argc, VALUE *argv, VALUE self)
+{ return na_sum_body(argc,argv,self,1); }
+
+
+
+static VALUE
+ na_prod_body(int argc, VALUE *argv, VALUE self, int flag)
+{
+  int *shape, rankc, *rankv, cl_dim;
+  struct NARRAY *a1, *a2;
+  VALUE obj, klass;
+  int32_t one = 1;
+
+  GetNArray(self,a1);
+
+  rankv = ALLOC_N(int,a1->rank*2);
+  rankc = na_arg_to_rank( argc, argv, a1->rank, rankv, 0 );
+
+  shape = &rankv[a1->rank];
+  na_accum_set_shape( shape, a1->rank, a1->shape, rankc, rankv );
+
+  klass  = CLASS_OF(self);
+  cl_dim = na_class_dim(klass);
+  if (flag==0 && cl_dim>0 && na_shrink_class(cl_dim,rankv))
+    klass = cNArray;
+
+  obj = na_make_object(a1->type,a1->rank,shape,klass);
+  GetNArray(obj,a2);
+
+  SetFuncs[a2->type][NA_LINT](a2->total, a2->ptr, na_sizeof[a2->type], &one, 0);
+
+  na_exec_unary( a2, a1, MulUFuncs[a1->type] );
+
+  if (flag==0)
+    obj = na_shrink_rank(obj,cl_dim,rankv);
+
+  xfree(rankv);
+  return obj;
+}
+
+/* method: prod( rank, ... ) */
+static VALUE
+ na_prod(int argc, VALUE *argv, VALUE self)
+{ return na_prod_body(argc,argv,self,0); }
+
+
+static VALUE
+ na_mul_add_body(int argc, VALUE *argv, volatile VALUE self, volatile VALUE other,
+		 VALUE wrap_klass, int flag)
+{
+  VALUE ans, op_klass;
+  int  rank, cl_dim;
+  int *dst_shape, *max_shape;
+  int  rankc, *rankv;
+  int  type;
+  struct NARRAY *a1, *a2;
+
+  GetNArray(self,a1);
+  other = na_upcast_object(other,a1->type);
+  GetNArray(other,a2);
+  self  = na_upcast_type(self,type=a2->type);
+  GetNArray(self,a1);
+
+  rank = NA_MAX(a1->rank,a2->rank);
+
+  rankv = ALLOC_N(int,rank*3);
+  rankc = na_arg_to_rank( argc, argv, rank, rankv, 0 );
+
+  max_shape = &rankv[rank];
+  na_shape_max_2obj(rank,max_shape,a1,a2);
+
+  dst_shape = &max_shape[rank];
+  na_accum_set_shape( dst_shape, rank, max_shape, rankc, rankv );
+
+  op_klass = na_bifunc_class(CLASS_OF(self),CLASS_OF(other));
+  if (op_klass==Qnil) /* coerce_rev --- unsupported */
+    op_klass = cNArray;
+
+  cl_dim = na_class_dim(op_klass);
+  if (flag==0 && cl_dim>0 && na_shrink_class(cl_dim,rankv))
+    op_klass = cNArray;
+
+  ans = na_make_object( type, rank, dst_shape,
+			(wrap_klass==Qnil) ? op_klass : wrap_klass);
+
+  na_zero_data( NA_STRUCT(ans) );
+  na_exec_binary( NA_STRUCT(ans), a1, a2, MulAddFuncs[type] );
+
+  if (flag==0)
+    ans = na_shrink_rank(ans,cl_dim,rankv);
+
+  xfree(rankv);
+  return ans;
+}
+
+
+
+/* method: mul_add( other, rank, ... ) */
+static VALUE
+ na_mul_add(int argc, VALUE *argv, VALUE self)
+{
+  if (argc<2)
+    rb_raise(rb_eArgError, "wrong # of arguments (%d for >=2)", argc);
+  return na_mul_add_body(argc-1,argv+1,self,argv[0],Qnil,0);
+}
+
+/* method: mul_accum( other, rank, ... ) */
+static VALUE
+ na_mul_accum(int argc, VALUE *argv, VALUE self)
+{
+  if (argc<2)
+    rb_raise(rb_eArgError, "wrong # of arguments (%d for >=2)", argc);
+  return na_mul_add_body(argc-1,argv+1,self,argv[0],Qnil,1);
+}
+
+/* singleton method: NArray.mul_add( obj1, obj2, rank, ... ) */
+static VALUE
+ na_s_mul_add(int argc, VALUE *argv, VALUE klass)
+{
+  if (argc<3)
+    rb_raise(rb_eArgError, "wrong # of arguments (%d for >=3)", argc);
+  return na_mul_add_body(argc-2,argv+2,argv[0],argv[1],klass,0);
+}
+
+
+/* cumsum!
+ [1 2 3 4 5] -> [1 3 6 10 15]
+*/
+static VALUE
+  na_cumsum_bang(VALUE self)
+{
+  struct NARRAY *a;
+  int step;
+
+  GetNArray(self,a);
+
+  if ( a->rank != 1 )
+    rb_raise( rb_eTypeError, "only for 1-dimensional array" );
+  if ( a->total < 2 )
+    return self; /* do nothing */
+
+  step = na_sizeof[a->type];
+  AddUFuncs[a->type](a->total-1, a->ptr+step,step, a->ptr,step);
+
+  return self;
+}
+
+/* cumsum */
+static VALUE
+  na_cumsum(VALUE self)
+{
+  return na_cumsum_bang(na_clone(self));
+}
+
+
+/* cumprod!
+ [1 2 3 4 5] -> [1 3 6 10 15]
+*/
+static VALUE
+  na_cumprod_bang(VALUE self)
+{
+  struct NARRAY *a;
+  int step;
+
+  GetNArray(self,a);
+
+  if ( a->rank != 1 )
+    rb_raise( rb_eTypeError, "only for 1-dimensional array" );
+  if ( a->total < 2 )
+    return self; /* do nothing */
+
+  step = na_sizeof[a->type];
+  MulUFuncs[a->type](a->total-1, a->ptr+step,step, a->ptr,step);
+
+  return self;
+}
+
+/* cumprod */
+static VALUE
+  na_cumprod(VALUE self)
+{
+  return na_cumprod_bang(na_clone(self));
+}
+
+
+/*  Copy element of idx=0  from a2 to a1, as start of accumulation */
+/*   a1->rank <= a2->rank is assumed  */
+static void
+ na_minmax_copy0(struct NARRAY *a1, struct NARRAY *a2)
+{
+  int  i, ndim=a2->rank; /* a2 has larger rank */
+  struct slice *s1, *s2;
+
+  /* Allocate Structure */
+  s1 = ALLOC_N(struct slice, (ndim+1)*2);
+  s2 = &s1[ndim+1];
+
+  na_set_slice_1obj(a1->rank,s1,a1->shape);
+  for (i=0; i<ndim; ++i) {
+    s2[i].n    = a1->shape[i]; /* no-repeat if a1->shape[i]==1 */
+    s2[i].beg  = 0;	       /* copy idx=0 */
+    s2[i].step = 1;
+    s2[i].idx  = NULL;
+  }
+
+  /* Initialize */
+  na_init_slice(s1, ndim, a1->shape, na_sizeof[a1->type] );
+  na_init_slice(s2, ndim, a2->shape, na_sizeof[a2->type] );
+  /* Loop */
+  na_do_loop_unary( ndim, a1->ptr, a2->ptr, s1, s2,
+		    SetFuncs[a1->type][a2->type] );
+  xfree(s1);
+}
+
+
+static VALUE
+ na_minmax_func(int argc, VALUE *argv, VALUE self, na_ufunc_t funcs)
+{
+  VALUE obj, klass;
+  int *shape, rankc, *rankv, cl_dim;
+  struct NARRAY *a1, *a2;
+
+  GetNArray(self,a1);
+
+  rankv = ALLOC_N(int,a1->rank*2);
+  rankc = na_arg_to_rank( argc, argv, a1->rank, rankv, 0 );
+
+  shape = &rankv[a1->rank];
+  na_accum_set_shape( shape, a1->rank, a1->shape, rankc, rankv );
+
+  klass  = CLASS_OF(self);
+  cl_dim = na_class_dim(klass);
+  if (na_shrink_class(cl_dim,rankv)) klass = cNArray;
+
+  obj = na_make_object(a1->type,a1->rank,shape,klass);
+  GetNArray(obj,a2);
+
+  na_minmax_copy0( a2, a1 );
+  na_exec_unary( a2, a1, funcs[a1->type] );
+
+  obj = na_shrink_rank(obj, cl_dim, rankv);
+
+  xfree(rankv);
+  return obj;
+}
+
+
+/* method: min( rank, ... ) */
+static VALUE
+ na_min(int argc, VALUE *argv, VALUE self)
+{ return na_minmax_func(argc,argv,self,MinFuncs); }
+
+/* method: max( rank, ... ) */
+static VALUE
+ na_max(int argc, VALUE *argv, VALUE self)
+{ return na_minmax_func(argc,argv,self,MaxFuncs); }
+
+
+
+static int
+ na_sort_number(int argc, VALUE *argv, struct NARRAY *a1)
+{
+  int i, nsort, rank;
+
+  if (argc==0) {
+    rank = a1->rank-1;
+  } else {
+    rank = NUM2INT(argv[0]);
+    if (rank >= a1->rank || rank < -a1->rank)
+      rb_raise(rb_eArgError,"illeagal rank:%i out of %i",rank,a1->rank);
+    if (rank < 0) rank += a1->rank;
+  }
+
+  nsort = 1;
+  for (i=0; i<=rank; ++i)
+    nsort *= a1->shape[i];
+  return nsort;
+}
+
+
+/* method: sort([rank]) */
+static VALUE
+ na_sort(int argc, VALUE *argv, VALUE self)
+{
+  struct NARRAY *a1, *a2;
+  VALUE obj;
+  int  (*func)(const void*, const void*);
+  int   i, size, step, nloop, nsort;
+  char *ptr;
+
+  GetNArray(self,a1);
+
+  nsort = na_sort_number(argc,argv,a1);
+  nloop = a1->total/nsort;
+
+  obj = na_make_object(a1->type,a1->rank,a1->shape,CLASS_OF(self));
+  GetNArray(obj,a2);
+  memcpy(a2->ptr, a1->ptr, a1->total*na_sizeof[a1->type]);
+  func = SortFuncs[a2->type];
+  size = na_sizeof[a2->type];
+  ptr  = a2->ptr;
+  step = size * nsort;
+
+  for (i=0; i<nloop; ++i) {
+    qsort( ptr, nsort, size, func );
+    ptr += step;
+  }
+  return obj;
+}
+
+
+/* method: sort!([rank]) */
+static VALUE
+ na_sort_bang(int argc, VALUE *argv, VALUE self)
+{
+  struct NARRAY *a1;
+  int  (*func)(const void*, const void*);
+  int   i, size, step, nloop, nsort;
+  char *ptr;
+
+  GetNArray(self,a1);
+
+  nsort = na_sort_number(argc,argv,a1);
+  nloop = a1->total/nsort;
+
+  func = SortFuncs[a1->type];
+  size = na_sizeof[a1->type];
+  ptr  = a1->ptr;
+  step = size * nsort;
+
+  for (i=0; i<nloop; ++i) {
+    qsort( ptr, nsort, size, func );
+    ptr += step;
+  }
+  return self;
+}
+
+
+/* method: sort_index([rank]) */
+static VALUE
+ na_sort_index(int argc, VALUE *argv, VALUE self)
+{
+  struct NARRAY *a1, *a2;
+  VALUE obj;
+  int  (*func)(const void*, const void*);
+  int   i, size, nloop, nsort;
+  char **ptr_ptr, **ptr_p;
+  char  *ptr_ary,  *ptr_a;
+  int32_t *ptr_i;
+
+  GetNArray(self,a1);
+
+  nsort = na_sort_number(argc,argv,a1);
+  nloop = a1->total/nsort;
+
+  size = na_sizeof[a1->type];
+  ptr_p = ptr_ptr = ALLOC_N(char*, a1->total);
+  ptr_a = ptr_ary = a1->ptr;
+
+  for (i=a1->total; i>0; --i) {
+    *(ptr_p++) = ptr_a;
+    ptr_a += size;
+  }
+
+  func = SortIdxFuncs[a1->type];
+  ptr_p = ptr_ptr;
+
+  for (i=0; i<nloop; ++i) {
+    qsort( ptr_p, nsort, sizeof(char*), func );
+    ptr_p += nsort;
+  }
+
+  obj = na_make_object(NA_LINT,a1->rank,a1->shape,CLASS_OF(self));
+  GetNArray(obj,a2);
+  ptr_p = ptr_ptr;
+  ptr_i = (int32_t*)(a2->ptr);
+  for (i=a2->total; i>0; --i) {
+    *(ptr_i++) = (int32_t)(*(ptr_p++)-ptr_ary)/size;
+  }
+  xfree(ptr_ptr);
+  return obj;
+}
+
+
+
+void Init_na_funcs(void)
+{
+  rb_define_method(cNArray, "+",  na_add, 1);
+  rb_define_method(cNArray, "-",  na_sbt, 1);
+  rb_define_method(cNArray, "*",  na_mul, 1);
+  rb_define_method(cNArray, "/",  na_div, 1);
+  rb_define_method(cNArray, "%",  na_mod, 1);
+  rb_define_alias (cNArray, "mod", "%");
+  rb_define_method(cNArray, "&",  na_bit_and, 1);
+  rb_define_method(cNArray, "|",  na_bit_or, 1);
+  rb_define_method(cNArray, "^",  na_bit_xor, 1);
+  rb_define_method(cNArray, "**", na_power, 1);
+
+  rb_define_method(cNArray, "add!", na_add_bang, 1);
+  rb_define_method(cNArray, "sbt!", na_sbt_bang, 1);
+  rb_define_method(cNArray, "mul!", na_mul_bang, 1);
+  rb_define_method(cNArray, "div!", na_div_bang, 1);
+  rb_define_method(cNArray, "mod!", na_mod_bang, 1);
+  rb_define_method(cNArray, "imag=",na_imag_set, 1);
+
+  rb_define_method(cNArray, "swap_byte", na_swap_byte, 0);
+  rb_define_method(cNArray, "hton", na_hton, 0);
+  rb_define_alias (cNArray, "ntoh", "hton");
+  rb_define_method(cNArray, "htov", na_htov, 0);
+  rb_define_alias (cNArray, "vtoh", "htov");
+  rb_define_method(cNArray, "-@",   na_neg, 0);
+  rb_define_method(cNArray, "recip",na_recip, 0);
+  rb_define_method(cNArray, "abs",  na_abs, 0);
+  rb_define_method(cNArray, "real", na_real, 0);
+  rb_define_method(cNArray, "imag", na_imag, 0);
+  rb_define_alias (cNArray, "image", "imag");
+  rb_define_method(cNArray, "angle", na_angle, 0);
+  rb_define_alias (cNArray, "arg", "angle");
+  rb_define_method(cNArray, "conj", na_conj, 0);
+  rb_define_alias (cNArray, "conjugate", "conj");
+  rb_define_method(cNArray, "conj!", na_conj_bang, 0);
+  rb_define_alias (cNArray, "conjugate!", "conj!");
+  rb_define_method(cNArray, "im",   na_imag_mul, 0);
+  rb_define_method(cNArray, "floor",na_floor, 0);
+  rb_define_method(cNArray, "ceil", na_ceil, 0);
+  rb_define_method(cNArray, "round",na_round, 0);
+  rb_define_method(cNArray, "~",    na_bit_rev, 0);
+  rb_define_method(cNArray, "not",  na_not, 0);
+
+  rb_define_method(cNArray, "<=>", na_compare, 1);
+  rb_define_method(cNArray, "eq",  na_equal, 1);
+  rb_define_method(cNArray, "ne",  na_not_equal, 1);
+  rb_define_method(cNArray, "gt",  na_greater_than, 1);
+  rb_define_alias (cNArray, ">",   "gt");
+  rb_define_method(cNArray, "ge",  na_greater_equal, 1);
+  rb_define_alias (cNArray, ">=",  "ge");
+  rb_define_method(cNArray, "lt",  na_less_than, 1);
+  rb_define_alias (cNArray, "<",   "lt");
+  rb_define_method(cNArray, "le",  na_less_equal, 1);
+  rb_define_alias (cNArray, "<=",  "le");
+  rb_define_method(cNArray, "and", na_cond_and, 1);
+  rb_define_method(cNArray, "or",  na_cond_or, 1);
+  rb_define_method(cNArray, "xor", na_cond_xor, 1);
+
+  rb_define_method(cNArray, "mul_add",   na_mul_add, -1);
+  rb_define_method(cNArray, "mul_accum", na_mul_accum, -1);
+
+  rb_define_method(cNArray, "sum", na_sum, -1);
+  rb_define_method(cNArray, "accum", na_accum, -1);
+  rb_define_method(cNArray, "prod", na_prod, -1);
+  rb_define_method(cNArray, "min", na_min, -1);
+  rb_define_method(cNArray, "max", na_max, -1);
+  rb_define_method(cNArray, "cumsum!", na_cumsum_bang, 0);
+  rb_define_method(cNArray, "cumsum", na_cumsum, 0);
+  rb_define_method(cNArray, "cumprod!", na_cumprod_bang, 0);
+  rb_define_method(cNArray, "cumprod", na_cumprod, 0);
+  rb_define_method(cNArray, "sort", na_sort, -1);
+  rb_define_method(cNArray, "sort!", na_sort_bang, -1);
+  rb_define_method(cNArray, "sort_index", na_sort_index, -1);
+  rb_define_method(cNArray, "transpose", na_transpose, -1);
+
+  rb_define_singleton_method(cNArray,"mul",na_s_mul,2);
+  rb_define_singleton_method(cNArray,"div",na_s_div,2);
+  rb_define_singleton_method(cNArray,"mul_add",na_s_mul_add,-1);
+
+  rb_define_module_function(rb_mNMath,"atan2",na_math_atan2,2);
+}
diff --git a/app/server/vendor/narray-0.6.1.1/na_index.c b/app/server/vendor/narray-0.6.1.1/na_index.c
new file mode 100755
index 0000000..003cf15
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/na_index.c
@@ -0,0 +1,1011 @@
+/*
+  na_index.c
+  Numerical Array Extention for Ruby
+    (C) Copyright 1999-2008 by Masahiro TANAKA
+
+  This program is free software.
+  You can distribute/modify this program
+  under the same terms as Ruby itself.
+  NO WARRANTY.
+*/
+#include <ruby.h>
+#include "narray.h"
+#include "narray_local.h"
+
+#define EXCL(r) (RTEST(rb_funcall((r),na_id_exclude_end,0)))
+
+static int
+ na_index_range(VALUE obj, int size, struct slice *sl)
+{
+  int beg,end,len,step;
+  VALUE vbeg, vend;
+
+  sl->idx  = NULL;
+
+  /* Beginning */
+  vbeg = rb_funcall(obj, na_id_beg, 0);
+  if (vbeg==Qnil) /* First is nil */
+    beg = 0;
+  else
+    beg = NUM2INT(vbeg);
+  if (beg<0) beg += size;
+
+  /* End */
+  vend = rb_funcall(obj, na_id_end, 0);
+  if (vend==Qnil) { /* Last is nil */
+    sl->beg  = beg;
+    sl->step = 1;
+    return sl->n = 0;
+  }
+  else
+    end = NUM2INT(vend);
+  if (end<0) end += size;
+
+  /* length */
+  len = end-beg;
+
+  /* direction */
+  if (len>0) {
+    step = 1;
+    if (EXCL(obj)) --end; else ++len;
+  }
+  else if (len<0) {
+    len  = -len;
+    step = -1;
+    if (EXCL(obj)) ++end; else ++len;
+  }
+  else /*if(len==0)*/ {
+    if (EXCL(obj))
+      rb_raise(rb_eIndexError, "empty range");
+    else {
+      ++len;
+      step = 1;  /* or 0 ? depend on whether removing rank */
+    }
+  } 
+
+  if ( beg<0 || beg>=size || end<0 || end>=size )
+    rb_raise(rb_eIndexError, "index out of range");
+
+  sl->n    = len;
+  sl->beg  = beg;
+  sl->step = step;
+  return len;
+}
+
+
+static int
+ na_index_scalar(int idx, int size, struct slice *sl)
+{
+  if (idx<0) idx+=size;
+  if (idx<0 || idx>=size)
+    rb_raise(rb_eIndexError, "index out of range");
+  sl->n    = 1;
+  sl->beg  = idx;
+  sl->step = 0;
+  sl->idx  = NULL;
+  return 1;
+}
+
+
+static int
+ na_ary_to_index(struct NARRAY *a1, int size, struct slice *s)
+{
+  int i;
+  na_index_t idx, *p;
+
+  /* Empty Array */
+  if (a1->total==0) {
+    s->n    = 0;
+    s->beg  = 0;
+    s->step = 1;
+    s->idx  = NULL;
+  }
+  else
+  /* single element */
+  if (a1->total==1) {
+    SetFuncs[NA_LINT][a1->type](1, &idx, 0, a1->ptr, 0);
+    if ( idx<0 ) idx += size;
+    if ( idx<0 || idx>=size )
+      rb_raise(rb_eIndexError, "index %i out of range %i", idx, size);
+    s->n    = 1;
+    s->beg  = idx;
+    s->step = 1;
+    s->idx  = NULL;
+  }
+  else {
+    /* Copy index array */
+    s->n    = a1->total;
+    s->step = 1;
+    s->idx  = p = ALLOC_N(na_index_t, a1->total);
+    SetFuncs[NA_LINT][a1->type]( s->n,
+				 s->idx, na_sizeof[NA_LINT],
+				 a1->ptr, na_sizeof[a1->type] );
+    for ( i=a1->total; i>0; --i ) {
+      if ( *p<0 ) *p += size;
+      if ( *p<0 || *p>=size )
+	rb_raise(rb_eIndexError, "index %i out of range %i", *p, size);
+      ++p;
+    }
+    s->beg  = s->idx[0];
+  }
+
+  return s->n;
+}
+
+
+static struct NARRAY *
+ na_flatten_temporarily(struct NARRAY *dst, struct NARRAY *src)
+{
+  /* Not normal construction !! Do not wrap as object ! */
+  dst->shape = &(dst->total);
+  dst->rank  = 1;
+  dst->total = src->total;
+  dst->type  = src->type;
+  dst->ptr   = src->ptr;
+  dst->ref   = src->ref;
+  return dst;
+}
+#define na_flatten_temp(ary) \
+ {ary = na_flatten_temporarily(ALLOCA_N(struct NARRAY,1), ary);}
+
+
+/* free index memory */
+static void na_free_slice_index(struct slice *s, int n)
+{
+  while (n-->0)
+    if (s[n].idx != NULL) xfree(s[n].idx);
+}
+
+
+static int na_index_test(volatile VALUE idx, int shape, struct slice *sl)
+{
+  int size;
+  struct NARRAY *na;
+
+  switch(TYPE(idx)) {
+
+  case T_FIXNUM:
+    /* scalar slice */
+    na_index_scalar(FIX2LONG(idx),shape,sl);
+    return 1;
+
+  case T_FLOAT:
+    /* scalar slice */
+    na_index_scalar(NUM2LONG(idx),shape,sl);
+    return 1;
+
+  case T_NIL:
+  case T_TRUE:
+    /* entire slice */
+    sl->n    = shape;
+    sl->beg  = 0;
+    sl->step = 1;
+    sl->idx  = NULL;
+    return shape;
+
+  case T_ARRAY:
+    /* Array Index */
+    idx = na_cast_object(idx,NA_LINT);
+    GetNArray(idx,na);
+    size = na_ary_to_index(na,shape,sl);
+    return size;
+
+  default:
+    /* Range object */
+    if (rb_obj_is_kind_of(idx, rb_cRange)) {
+      size = na_index_range(idx,shape,sl);
+    }
+    else
+    /* NArray index */
+    if (NA_IsNArray(idx)) {
+      GetNArray(idx,na);
+      size = na_ary_to_index(na,shape,sl);
+    }
+    else
+    /* NO ALLOWED */
+    if (TYPE(idx)==T_BIGNUM) {
+      rb_raise(rb_eIndexError, "BigNum is not allowed");
+    }
+    else
+      rb_raise(rb_eIndexError, "not allowed type");
+  }
+  return size;
+}
+
+
+static int
+ na_index_analysis(int nidx, VALUE *idx, struct NARRAY *ary, struct slice *sl)
+{
+  int i, j, k, total=1, size;
+  int multi_ellip=0;
+
+  for (i=j=0; i<nidx; ++i) {
+    if (TYPE(idx[i])==T_FALSE) {
+      if (multi_ellip!=0)
+	rb_raise(rb_eIndexError, "multiple ellipsis-dimension is not allowd");
+      for (k=ary->rank-nidx+1; k>0; --k,++j) {
+	size = na_index_test( Qtrue, ary->shape[j], &sl[j] );
+	if (size != 1)
+	  total *= size;
+      }
+      multi_ellip = 1;
+    } else {
+      if (j < ary->rank) {
+         size = na_index_test( idx[i], ary->shape[j], &sl[j] );
+         if (size != 1)
+             total *= size;
+      }
+      ++j;
+    }
+  }
+  if (j != ary->rank)
+    rb_raise(rb_eIndexError, "# of index=%i != ary.dim=%i", j, ary->rank);
+
+  return total;
+}
+
+
+/* --------------------  Class Dimension  -------------------- */
+int
+ na_shrink_class(int class_dim, int *shrink)
+{
+  int i;
+
+  for (i=0; i<class_dim; ++i) {
+    if (shrink[i]==0)      /* non-trim dimention */
+      return 0;
+  }
+  return 1; /* all trim */
+}
+
+
+/* remove single-element rank */
+VALUE
+ na_shrink_rank(VALUE obj, int class_dim, int *shrink)
+{
+  int  i, j;
+  struct NARRAY *ary;
+
+  GetNArray(obj,ary);
+
+  if (ary->rank < class_dim)
+    return obj;
+  
+  for (j=i=0; i<class_dim; ++i) {
+    if (ary->shape[i]!=1 || shrink[i]==0) /* not trim */
+      ++j;
+  }
+
+  if (j>0)		/* if   non-trim dimensions exist, */
+    j = class_dim;      /* then do not trim class_dimension.  */
+			/* if (j==0) then all trim. */
+
+  for (i=class_dim; i<ary->rank; ++i) {
+    if (ary->shape[i]!=1 || shrink[i]==0) {    /* not trim */
+      if (i>j) ary->shape[j] = ary->shape[i];
+      ++j;
+    }
+  }
+  ary->rank = j;
+
+  if (j==0 && ary->total==1) {
+    SetFuncs[NA_ROBJ][ary->type](1, &obj, 0, ary->ptr, 0);
+  }
+  return obj;
+}
+
+
+/* ------------------- bracket methods ------------------ */
+/*
+	[] -- Reference method
+*/
+
+static VALUE
+ na_aref_slice(struct NARRAY *a2, struct slice *s2, VALUE klass, int flag)
+{
+  int i, ndim, class_dim, *shape, *shrink;
+  VALUE  extr;
+  struct NARRAY *a1;
+  struct slice  *s1;
+
+  ndim = a2->rank;
+  shape = ALLOCA_N(int,ndim);
+  shrink = ALLOCA_N(int,ndim);
+
+  for (i=0; i<ndim; ++i) {
+    shape[i] = s2[i].n;
+    if (shape[i]==1 && s2[i].step==0) /* shrink? */
+      shrink[i] = 1;
+    else
+      shrink[i] = 0;
+  }
+
+  class_dim = na_class_dim(klass);
+
+  if (ndim < class_dim)
+    rb_raise(rb_eRuntimeError,
+	     "dimension(%i) is smaller than CLASS_DIMENSION(%i)",
+	     ndim, class_dim);
+
+  if ((!flag) && class_dim>0 && na_shrink_class(class_dim,shrink))
+    klass = cNArray;
+
+  extr = na_make_object( a2->type, ndim, shape, klass );
+  GetNArray(extr,a1);
+
+  s1 = ALLOC_N(struct slice, ndim+1);
+  na_set_slice_1obj(ndim,s1,a1->shape);
+
+  na_init_slice( s1, ndim, shape, na_sizeof[a2->type] );
+  na_init_slice( s2, ndim, a2->shape, na_sizeof[a2->type] );
+  na_loop_index_ref( a1, a2, s1, s2, SetFuncs[a2->type][a2->type] );
+
+  xfree(s1);
+  if (!flag)
+    extr = na_shrink_rank(extr,class_dim,shrink);
+
+  return extr;
+}
+
+
+
+static VALUE
+ na_aref_single_dim_array(VALUE self, volatile VALUE vidx)
+{
+  int  total;
+  struct NARRAY *a1, *a2, *aidx;
+  struct slice  *s1, *s2;
+  VALUE v;
+
+  GetNArray( self, a1 );
+  vidx = na_cast_object( vidx, NA_LINT );
+  GetNArray(vidx,aidx);
+
+  /* make Slice from index */
+  s1    = ALLOCA_N(struct slice, 2);
+  total = na_ary_to_index( aidx, a1->total, s1 );
+
+  if (total==0) {
+    return na_make_empty(a1->type,cNArray);
+  }
+  else {
+    /* create New NArray & 1-dimentionize */
+    v = na_make_object( a1->type, aidx->rank, aidx->shape, CLASS_OF(vidx) );
+    GetNArray(v,a2);
+    if (a2->rank>1) na_flatten_temp(a2);
+    if (a1->rank>1) na_flatten_temp(a1);
+
+    /* Slice for Destination array */
+    s2 = ALLOCA_N(struct slice, 2);
+    na_set_slice_1obj(1,s2,a2->shape);
+
+    /* Iteration */
+    na_init_slice( s2, 1, a2->shape, na_sizeof[a1->type] );
+    na_init_slice( s1, 1, a1->shape, na_sizeof[a1->type] );
+    na_loop_index_ref( a2, a1, s2, s1, SetFuncs[a1->type][a1->type] );
+  }
+
+  na_free_slice_index(s1,1);
+  return v;
+}
+
+
+static VALUE
+ na_aref_single_dim(VALUE self, VALUE idx, int flag)
+{
+  int size;
+  VALUE v;
+  struct NARRAY *ary, *arynew;
+  struct slice *sl;
+
+  GetNArray(self,ary);
+
+  sl   = ALLOCA_N(struct slice, 2);
+  size = na_index_test(idx, ary->total, sl);
+
+  if ( size == 1 ) {
+    if (flag || sl->step!=0) {
+      /* single-element NArray */
+      v = na_make_object(ary->type,1,&size,cNArray);
+      GetNArray(v,arynew);
+      SetFuncs[ary->type][ary->type](1, arynew->ptr,0, NA_PTR(ary,sl->beg),0);
+    } else {
+      SetFuncs[NA_ROBJ][ary->type](1, &v,0, NA_PTR(ary,sl->beg),0);
+    }
+  }
+  else
+  if ( size > 1 ) {
+    if ( ary->rank > 1 )  /* 1-dimensional serial index */
+      na_flatten_temp(ary);
+    v = na_aref_slice(ary, sl, CLASS_OF(self), flag);
+  }
+  else /* size < 1 */ {
+    v = na_make_empty(ary->type,cNArray);
+  }
+  /* na_free_slice_index(sl,1);  free index memory */
+  return v;
+}
+
+
+static VALUE
+ na_aref_multi_dim_single_elm(VALUE self, struct slice *sl, int flag)
+{
+  int i, rank, pos, *shape;
+  struct NARRAY *ary, *arynew;
+  VALUE v;
+
+  ary = (struct NARRAY *)DATA_PTR(self); /* type is already checked */
+
+  /* check rank-shrink; whether return NArray or Element */
+  if (flag==0) {
+    rank = 0; /* [] */
+    for ( i=ary->rank; (i--)>0; ) {
+      if (sl[i].step!=0) ++rank;
+    }
+  }
+  else {
+    rank = ary->rank; /* slice() */
+  }
+  /* get position */
+  pos = 0;
+  for ( i=ary->rank; i-->0; ) {
+    pos = pos * ary->shape[i] + sl[i].beg;
+  }
+  if (rank==0) {
+    SetFuncs[NA_ROBJ][ary->type](1, &v, 0, NA_PTR(ary,pos), 0);
+  } else {
+    VALUE klass;
+    int   class_dim;
+    klass = CLASS_OF(self);
+    class_dim = na_class_dim(klass);
+    if (rank < class_dim) rank = class_dim;
+    shape = ALLOCA_N(int, rank);
+    for (i=0;i<rank;++i) shape[i]=1;
+    v = na_make_object(ary->type,rank,shape,klass);
+    GetNArray(v,arynew);
+    SetFuncs[ary->type][ary->type](1, arynew->ptr, 0, NA_PTR(ary,pos), 0);
+  }
+  return v;
+}
+
+
+static VALUE
+ na_aref_multi_dim(VALUE self, int nidx, VALUE *idx, int flag)
+{
+  VALUE v;
+  int   size;
+  struct NARRAY *ary;
+  struct slice *sl;
+
+  GetNArray(self,ary);
+
+  if (ary->rank==0)
+    rb_raise(rb_eIndexError, "Cannot extract from Empty NArray");
+
+  /* make Slice */
+  sl   = ALLOC_N(struct slice, ary->rank+1);
+  size = na_index_analysis(nidx, idx, ary, sl);
+
+  if ( size == 1 ) { /* return Single Element */
+    v = na_aref_multi_dim_single_elm(self, sl, flag);
+  }
+  else
+  if ( size > 1 ) {
+    v = na_aref_slice(ary, sl, CLASS_OF(self), flag);
+  }
+  else /* size < 1 */ {
+    v = na_make_empty(ary->type,cNArray);
+  }
+  na_free_slice_index(sl,ary->rank); /* free index memory */
+  xfree(sl);
+  return v;
+}
+
+
+/* vvv mask vvv */
+static int
+ na_count_true_body(VALUE self)
+{
+  struct NARRAY *ary;
+  int  n, count=0;
+  u_int8_t *ptr;
+
+  GetNArray(self,ary);
+
+  if ( ary->type == NA_BYTE ) {
+    ptr = (u_int8_t *)ary->ptr;
+    n   = ary->total;
+    for (; n; --n) {
+      if (*ptr++) ++count;
+    }
+  } else
+    rb_raise(rb_eTypeError,"cannot count_true NArray except BYTE type");
+  return count;
+}
+
+/*
+ *  call-seq:
+ *     narray.count_true  -> int
+ *
+ *  Returns the number of true (non-zero) in narray
+ */
+VALUE
+ na_count_true(VALUE self)
+{
+  return( INT2NUM(na_count_true_body(self)) );
+}
+
+static int
+ na_count_false_body(VALUE self)
+{
+  struct NARRAY *ary;
+  int  n, count=0;
+  u_int8_t *ptr;
+
+  GetNArray(self,ary);
+
+  if ( ary->type == NA_BYTE ) {
+    ptr = (u_int8_t *)ary->ptr;
+    n   = ary->total;
+    for (; n; --n) {
+      if (!*ptr++) ++count;
+    }
+  } else
+    rb_raise(rb_eTypeError,"cannot count_false NArray except BYTE type");
+  return count;
+}
+
+/*
+ *  call-seq:
+ *     narray.count_false  -> int
+ *
+ *  Returns the number of false (zero-value) in narray
+ */
+VALUE
+ na_count_false(VALUE self)
+{
+  return( INT2NUM(na_count_false_body(self)) );
+}
+
+/* :nodoc: */
+VALUE
+ na_aref_mask(VALUE self, VALUE mask)
+{
+  int total, i;
+  struct NARRAY *a1, *am, *a2;
+  VALUE v;
+
+  GetNArray( self, a1 );
+  GetNArray( mask, am );
+
+  if (a1->total != am->total)
+    rb_raise(rb_eTypeError,"self.size(=%i) != mask.size(=%i)",
+	     a1->total, am->total);
+  if (a1->rank != am->rank) 
+    rb_raise(rb_eTypeError,"self.rank(=%i) != mask.rank(=%i)",
+	     a1->rank, am->rank);
+  for (i=0; i<a1->rank; ++i)
+    if (a1->shape[i] != am->shape[i])
+      rb_raise(rb_eTypeError,"self.shape[%i](=%i) != mask.shape[%i](=%i)",
+	       i, a1->shape[i], i, am->shape[i]);
+
+  total = na_count_true_body(mask);
+
+  v = na_make_object( a1->type, 1, &total, CLASS_OF(self) );
+  GetNArray(v,a2);
+
+  RefMaskFuncs[a1->type]
+    ( a1->total, a2->ptr, na_sizeof[a2->type], a1->ptr,
+      na_sizeof[a1->type], am->ptr, 1 );
+
+  return(v);
+}
+
+/* ^^^ mask ^^^ */
+
+
+/* method: [](idx1,idx2,...,idxN) */
+static VALUE
+ na_aref_body(int nidx, VALUE *idx, VALUE self, int flag)
+{
+  if (nidx==0) {
+    return na_clone(self);
+  }
+  if (nidx==1) {
+    if ( NA_IsNArray(idx[0]) ) {
+      if( NA_TYPE(idx[0]) == NA_BYTE ) /* then supposed to be a mask */
+	return na_aref_mask(self, idx[0]);
+    }
+    if ( na_class_dim(CLASS_OF(self)) != 1 ) {
+      if ( NA_IsArray(idx[0]) ) /* Array Index ? */
+	return na_aref_single_dim_array( self, idx[0] );
+      else
+	return na_aref_single_dim( self, idx[0], flag );
+    }
+  }
+  /* if (nidx>1) */
+    return na_aref_multi_dim( self, nidx, idx, flag );
+}
+
+/* method: [](idx1,idx2,...,idxN) */
+VALUE na_aref(int argc, VALUE *argv, VALUE self)
+{ return na_aref_body(argc, argv, self, 0); }
+
+/* method: slice(idx1,idx2,...,idxN) */
+VALUE na_slice(int argc, VALUE *argv, VALUE self)
+{ return na_aref_body(argc, argv, self, 1); }
+
+
+
+/*
+	[]=  --  Set elements to specified indices
+*/
+
+/* make slice for array-set: a[0..-1,1..2] = 1 */
+static void
+ na_make_slice_aset_fill(int rank, struct NARRAY *src_ary,
+			 struct slice *src_slc, int *src_shape,
+			 struct slice *dst_slc)
+{
+  int i;
+
+  for (i=0; i<rank; ++i) {
+    src_shape[i]    = 1; /* all 1 */
+    if ( (src_slc[i].n = dst_slc[i].n) < 1 )
+      rb_raise(rb_eIndexError, "dst_slice[%i].n=%i ???", i, dst_slc[i].n);
+    src_slc[i].beg  = 0;
+    src_slc[i].idx  = NULL;
+    src_slc[i].step = 0;
+  }
+}
+
+
+/* make slice for array-set */
+static void
+ na_make_slice_aset(struct NARRAY *dst, struct NARRAY *src,
+		    struct slice *s1, struct slice *s2, int *src_shape)
+{
+  int  i, j, idx_end;
+  
+  /* count range index */
+  for (j=i=0; i<dst->rank; ++i) {
+
+    if ( s1[i].step !=0 ) { /* Range index */
+
+      /* rank check */
+      if ( j >= src->rank )
+	  rb_raise(rb_eIndexError, "dst.range-dim=%i > src.dim=%i",
+		   j+1, src->rank);
+
+      if ( s1[i].n == 0 ) {
+	/* Size is NOT specified:
+	   a[0..nil] = other_array
+	   a[0]      = other_array
+	 */
+	s1[i].n = src->shape[j];
+
+	idx_end = s1[i].beg + (s1[i].n-1) * s1[i].step;
+	if ( idx_end < 0 || idx_end >= dst->shape[i] )
+	  rb_raise(rb_eIndexError, "end-index=%i is out of dst.shape[%i]=%i",
+		   idx_end, i, dst->shape[i]);
+
+      } else
+	/* Size is specified:
+	     a[0..10] = other
+	 */
+      if ( src->shape[j] >1 && s1[i].n != src->shape[j] ) {
+	  rb_raise(rb_eIndexError, "dst.shape[%i]=%i != src.shape[%i]=%i",
+		   i, s1[i].n, j, src->shape[j]);
+      }
+      /* copy source shape */
+      src_shape[i] = src->shape[j++];
+
+    }
+    else /* if ( s1[i].n==1 )
+	 Scalar index:
+	   a[0, 0..-1] = other  --- first rank is skipped.
+       */
+      src_shape[i] = 1;  /* insert dummy rank */
+
+    s2[i].beg  = 0;
+    s2[i].idx  = NULL;
+    s2[i].n    = s1[i].n;  /* repeate number is same as a1 index */
+
+    if ( s1[i].n >1 && src_shape[i]==1 ) /* Extensible index */
+      s2[i].step = 0;
+    else
+      s2[i].step = 1;
+  }
+
+  /* rank check */
+  if ( j != src->rank )
+    rb_raise(rb_eIndexError, "dst.range-dim=%i < src.dim=%i", j, src->rank);
+}
+
+
+
+/* Iterate with bifinc, src has extensible index */
+void
+ na_aset_slice(struct NARRAY *dst, struct NARRAY *src, struct slice *dst_slc)
+{
+  int   rank = dst->rank;
+  int  *src_shape;
+  struct slice *src_slc;
+
+  /* rank check */
+  if (rank < src->rank)
+    rb_raise(rb_eIndexError, "%i dst.ranks < %i src.ranks", rank, src->rank);
+  if (src->rank == 0)
+    rb_raise(rb_eIndexError, "cannot store empty array");
+
+  /* extend rank */
+  src_shape = ALLOCA_N(int, rank);
+  src_slc   = ALLOC_N(struct slice, rank+1);
+
+  if (src->total==1)
+    na_make_slice_aset_fill( rank, src, src_slc, src_shape, dst_slc );
+  else
+    na_make_slice_aset( dst, src, dst_slc, src_slc, src_shape );
+
+  /* Iteration */
+  na_init_slice( dst_slc, rank, dst->shape, na_sizeof[dst->type] );
+  na_init_slice( src_slc, rank, src_shape,  na_sizeof[src->type] );
+  na_loop_general( dst,src, dst_slc,src_slc, SetFuncs[dst->type][src->type] );
+  xfree(src_slc);
+}
+
+
+static void
+ na_aset_array_index( VALUE self, volatile VALUE idx, volatile VALUE val )
+{
+  int i, total;
+  struct NARRAY *aidx, *src, *dst;
+  struct slice *sl;
+
+  GetNArray(self,dst);
+  idx = na_cast_object(idx,NA_LINT);
+  GetNArray(idx,aidx);
+  val = na_cast_unless_narray(val,dst->type);
+  GetNArray(val,src);
+
+  /* empty index -- do nothing */
+  if (aidx->total==0 && (src->total==0 || src->total==1))
+    return;
+
+  /* check rank */
+  if (aidx->rank != src->rank)
+    rb_raise( rb_eIndexError, "idx.rank=%i != src.rank=%i",
+	      aidx->rank, src->rank );
+  /* check shape */
+  for (i=0;i<src->rank;++i)
+    if (aidx->shape[i] != src->shape[i] && src->shape[i] != 1)
+      rb_raise( rb_eIndexError, "idx.shape[%i]=%i != src.shape[%i]=%i",
+		i, aidx->shape[i], i, src->shape[i] );
+
+  /* make Slice from index */
+  sl    = ALLOCA_N(struct slice,2);
+  total = na_ary_to_index( NA_STRUCT(idx), dst->total, sl );
+
+  /* 1-dimensionize */
+  if (dst->rank > 1) {
+    na_flatten_temp(dst);
+  }
+  if (src->rank > 1) {
+    na_flatten_temp(src);
+  }
+
+  na_aset_slice( dst, src, sl );
+  na_free_slice_index( sl, 1 ); /* free index memory */
+}
+
+
+static void
+ na_aset_single_dim(VALUE self, VALUE idx, volatile VALUE val)
+{
+  int size;
+  struct NARRAY *src, *dst;
+  struct slice *sl;
+
+  GetNArray(self,dst);
+  if (dst->total==0)
+    rb_raise(rb_eRuntimeError, "cannot set value to empty array");
+
+  sl   = ALLOCA_N(struct slice, 2);
+  size = na_index_test(idx, dst->total, sl);
+
+  if ( size == 1 ) {
+    if (NA_IsNArray(val)) {
+      GetNArray(val,src);
+      if ( src->total == 1 ) {
+	SetFuncs[dst->type][src->type](1, NA_PTR(dst,sl->beg),0, src->ptr,0);
+	return;
+      }
+    }
+    else if (TYPE(val)!=T_ARRAY) {
+      /* Storing single element:
+	 a[1] = 1
+      */
+      SetFuncs[dst->type][NA_ROBJ](1, NA_PTR(dst,sl->beg),0, &val,0);
+      return;
+    }
+    /* Beginning index:
+       a[1] = [1,2,3]
+    */
+    sl[0].n = 0;
+    sl[0].step = 1;
+  }
+  else if ( size == 0 ) return; /* Empty index */
+
+  if ( dst->rank > 1 ) { /* 1-dimensionize */
+    na_flatten_temp(dst);
+  }
+  val = na_cast_unless_narray(val,dst->type);
+  GetNArray(val,src);
+  na_aset_slice( dst, src, sl );
+
+  na_free_slice_index(sl,1); /* free index memory */
+}
+
+
+static void
+ na_aset_multi_dim(VALUE self, int nidx, VALUE *idx, volatile VALUE val)
+{
+  int    i, pos, size;
+  struct NARRAY *dst, *src;
+  struct slice *sl;
+
+  GetNArray(self,dst);
+  if (dst->total==0)
+    rb_raise(rb_eRuntimeError, "cannot set value to empty array");
+
+  /* make Slice from index-argv */
+  sl   = ALLOC_N(struct slice, dst->rank+1);
+  size = na_index_analysis( nidx, idx, dst, sl );
+
+  if ( size == 0 ) { xfree(sl); return; } /* Empty index */
+  if ( size == 1 ) {
+    if (NA_IsArray(val)) {
+      /* Beginning index:
+	   a[2,3,4] = other
+       */
+      val = na_cast_unless_narray(val,dst->type);
+      GetNArray(val,src);
+      if (src->total > 1)
+	for( i=0; i<src->rank; ++i ) {
+	  sl[i].n = 0;
+	  sl[i].step = 1;
+	}
+    }
+    else {
+      /* Single Element:
+         a[2,3,4] = 5
+      */
+      for ( pos=0, i=dst->rank; i-->0; )
+	pos = pos * dst->shape[i] + sl[i].beg;
+      SetFuncs[dst->type][NA_ROBJ](1, NA_PTR(dst,pos), 0, &val, 0 );
+      xfree(sl);
+      return;
+    }
+  }
+  else
+    val = na_cast_unless_narray(val,dst->type);
+    GetNArray(val,src);
+
+  /* if ( size>1 ) */
+    /* Range index:
+         a[0..9,0] = other
+     */
+  na_aset_slice( dst, src, sl );
+
+  na_free_slice_index(sl,nidx); /* free index memory */
+  xfree(sl); 
+}
+
+
+
+static void
+ na_aset_fill(VALUE self, volatile VALUE val)
+{
+  struct NARRAY *dst, *src;
+  struct slice *sl;
+
+  GetNArray(self,dst);
+  if (dst->total==0)
+    rb_raise(rb_eRuntimeError, "cannot set value to empty array");
+
+  if ( NA_IsArray(val) ) {    /* store Array? */
+    sl = ALLOC_N(struct slice, dst->rank+1);
+    na_set_slice_1obj(dst->rank,sl,dst->shape);
+
+    val = na_cast_unless_narray(val,dst->type);
+    GetNArray(val,src);
+    na_aset_slice( dst, src, sl );
+    xfree(sl);
+  }
+  else {
+    na_fill( self, val );  /* Simple filling */
+  }
+}
+
+
+/* --- mask --- */
+void
+ na_aset_mask(VALUE self, VALUE mask, VALUE val)
+{
+  int size, step, i;
+  struct NARRAY *a1, *am, *a2;
+
+  GetNArray( self, a1 );
+  GetNArray( mask, am );
+
+  if (a1->total != am->total)
+    rb_raise(rb_eTypeError,"self.size(=%i) != mask.size(=%i)",
+	     a1->total, am->total);
+  if (a1->rank != am->rank) 
+    rb_raise(rb_eTypeError,"self.rank(=%i) != mask.rank(=%i)",
+	     a1->rank, am->rank);
+  for (i=0; i<a1->rank; ++i)
+    if (a1->shape[i] != am->shape[i])
+      rb_raise(rb_eTypeError,"self.shape[%i](=%i) != mask.shape[%i](=%i)",
+	       i, a1->shape[i], i, am->shape[i]);
+
+  size = na_count_true_body(mask);
+
+  val = na_cast_object(val,a1->type);
+  GetNArray( val, a2 );
+  if (a2->total == 1) {
+    step = 0;
+  } else if (a2->total == size) { 
+    step = na_sizeof[a2->type];
+  } else {
+    rb_raise(rb_eTypeError,"val.length != mask.count_true");
+  }
+
+  SetMaskFuncs[a1->type]
+    ( a1->total, a1->ptr, na_sizeof[a1->type],
+      a2->ptr, step, am->ptr, 1 );
+}
+
+/* method: []=(idx1,idx2,...,idxN,val) */
+VALUE
+ na_aset(int nidx, VALUE *idx, VALUE self)
+{
+  --nidx;
+
+  if (nidx==0) {
+    na_aset_fill( self, idx[0] );
+  }
+  else
+  if (nidx==1) {
+    if ( NA_IsNArray(idx[0]) ) {
+      if( NA_TYPE(idx[0]) == NA_BYTE ) { /* then supposed to be a mask */
+	na_aset_mask(self, idx[0], idx[1]);
+	return(idx[1]);
+      }
+    }
+    if ( NA_IsArray(idx[0]) ) /* Array Index ? */
+      na_aset_array_index( self, idx[0], idx[1] );
+    else
+      na_aset_single_dim( self, idx[0], idx[1] );
+  }
+  else
+  if (nidx>1) {
+    na_aset_multi_dim( self, nidx, idx, idx[nidx] );
+  }
+  else /* if (nidx<0) */
+    rb_raise( rb_eArgError, "No value specified" );
+
+  return idx[nidx];
+}
+
+
+void Init_na_index() {
+    /* slice */
+    rb_define_method(cNArray, "[]", na_aref,-1);
+    rb_define_method(cNArray, "[]=", na_aset,-1);
+    rb_define_method(cNArray, "slice", na_slice,-1);
+    /* mask */
+    rb_define_method(cNArray, "count_false", na_count_false, 0);
+    rb_define_method(cNArray, "count_true", na_count_true, 0);
+    rb_define_method(cNArray, "mask", na_aref_mask, 1);
+}
diff --git a/app/server/vendor/narray-0.6.1.1/na_linalg.c b/app/server/vendor/narray-0.6.1.1/na_linalg.c
new file mode 100755
index 0000000..df54e7b
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/na_linalg.c
@@ -0,0 +1,633 @@
+/*
+ * na_linalg.c
+ * Numerical Array Extention for Ruby
+ *   (C) Copyright 2000-2008 by Masahiro TANAKA
+ */
+#include <ruby.h>
+#include "narray.h"
+#include "narray_local.h"
+#define ARRAY_BUF
+
+/*
+  a_ij == a[j,i]
+     j  - >
+   i 11 21 31
+   | 12 22 32
+   v 13 23 33
+*/
+
+#define SWAPMEM(a,b,tmp,sz) \
+{ memcpy(tmp,a,sz); memcpy(a,b,sz); memcpy(b,tmp,sz); }
+
+typedef struct NARRAY_FUNCSET {
+  int   elmsz;
+  char *zero;
+  char *one;
+  char *tiny;
+  void (*set)();
+  void (*neg)();
+  void (*rcp)();
+  void (*abs)();
+  void (*add)();
+  void (*sbt)();
+  void (*mul)();
+  void (*div)();
+  void (*mod)();
+  void (*muladd)();
+  void (*mulsbt)();
+  void (*cmp)();
+  int  (*sort)();
+  void (*min)();
+  void (*max)();
+} na_funcset_t;
+
+VALUE cNMatrix, cNVector, cNMatrixLU;
+static na_funcset_t na_funcset[NA_NTYPES];
+static ID id_lu, id_pivot;
+
+
+static void
+na_loop_linalg( int nd, char *p1, char *p2, char *p3,
+		struct slice *s1, struct slice *s2, struct slice *s3,
+		void (*func)(), int *shape, int type )
+{
+  int i;
+  int ps1 = s1[0].pstep;
+  int ps2 = s2[0].pstep;
+  int ps3 = s3[0].pstep;
+  int *si;
+
+  if (nd==0) {
+    (*func)(1, p1, 0, p2, 0, p3, 0, shape, type);
+    return;
+  }
+
+  si = ALLOCA_N(int,nd);
+  i  = nd;
+  s1[i].p = p1;
+  s2[i].p = p2;
+  s3[i].p = p3;
+
+  for(;;) {
+    /* set pointers */
+    while (i > 0) {
+      --i;
+      s3[i].p = s3[i].pbeg + s3[i+1].p;
+      s2[i].p = s2[i].pbeg + s2[i+1].p;
+      s1[i].p = s1[i].pbeg + s1[i+1].p;
+      si[i] = s1[i].n;
+    }
+    /* rank 0 loop */
+    (*func)(s2[0].n, s1[0].p, ps1, s2[0].p, ps2, s3[0].p, ps3, shape, type);
+    /* rank up */
+    do {
+      if ( ++i >= nd ) return;
+    } while ( --si[i] == 0 );
+    /* next point */
+    s1[i].p += s1[i].pstep;
+    s2[i].p += s2[i].pstep;
+    s3[i].p += s3[i].pstep;
+  }
+}
+
+static int
+na_shape_total( int n, int *shape )
+{
+  int total=1;
+
+  for (; n>0; --n)
+    total *= *(shape++);
+
+  return total;
+}
+
+static void
+na_exec_linalg( struct NARRAY *a1, struct NARRAY *a2, struct NARRAY *a3,
+		int ncd1, int ncd2, int ncd3, void (*func)() )
+{
+  int   ndim, ncd, nsz1, nsz2, nsz3;
+  int  *itr, *shp1, *shp2, *shp3;
+  struct slice *s1, *s2, *s3;
+
+  ncd  = na_max3(ncd1,ncd2,ncd3); /* class dim */
+  ndim = na_max3(a1->rank-ncd1, a2->rank-ncd2, a3->rank-ncd3) + ncd;
+
+  NA_ALLOC_SLICE(s1,(ndim+1)*3,shp1,ndim*4);
+  shp2 = &shp1[ndim];
+  shp3 = &shp2[ndim];
+  itr  = &shp3[ndim];
+  s2   = &s1[ndim+1];
+  s3   = &s2[ndim+1];
+
+  na_shape_copy( ndim, shp1, a1 );
+  na_shape_copy( ndim, shp2, a2 );
+  na_shape_copy( ndim, shp3, a3 );
+  ndim -= ncd;
+  shp1 += ncd1;
+  shp2 += ncd2;
+  shp3 += ncd3;
+  na_shape_max3( ndim, itr, shp1, shp2, shp3 );
+
+  ndim = na_set_slice_3obj( ndim, s1, s2, s3, shp1, shp2, shp3, itr );
+
+  nsz1 = na_shape_total(a1->rank-ncd1,a1->shape+ncd1);
+  nsz2 = na_shape_total(a2->rank-ncd2,a2->shape+ncd2);
+  nsz3 = na_shape_total(a3->rank-ncd3,a3->shape+ncd3);
+
+  na_init_slice(s1, ndim, shp1, na_sizeof[a1->type]*nsz1 );
+  na_init_slice(s2, ndim, shp2, na_sizeof[a2->type]*nsz2 );
+  na_init_slice(s3, ndim, shp3, na_sizeof[a3->type]*nsz3 );
+
+  na_loop_linalg( ndim, a1->ptr, a2->ptr, a3->ptr,
+		  s1, s2, s3, func, a2->shape, a2->type );
+  xfree(s1);
+}
+
+
+static int
+na_lu_fact_func_body(int ni, char *a, char *idx, int *shape, int type, char *buf)
+{
+  int i, j, k;
+  int imax;
+
+  char *amax, *rtmp;
+  char *aa, *aii, *aij, *ai0, *a0i, *a0j;
+  char *v, *vi;
+
+  na_funcset_t *f = &na_funcset[type];
+  na_funcset_t *r = &na_funcset[na_cast_real[type]];
+
+  int status = 0;
+  int n = shape[0];
+  int relmsz = r->elmsz;
+  int felmsz = f->elmsz;
+  int rowsz  = felmsz*n;
+  int matsz  = rowsz*n;
+  int diagsz = rowsz + felmsz;
+
+  v    = buf + rowsz;
+  amax = v   + relmsz*n;
+
+  while (ni-->0) {
+
+    aa = a;
+    vi = v;
+
+    /* v[j] = 1/max( abs( a[i,j] ) ) */
+    for (j=0;j<n;++j) {
+      f->abs(n, buf, relmsz, aa, felmsz);
+
+      r->set(1, amax,0, r->zero,0);
+      rtmp = buf;
+      for (i=0;i<n;++i) {
+	if (r->sort(rtmp, amax) == 1)
+	  r->set(1, amax,0, rtmp,0);
+	rtmp += relmsz;
+      }
+
+      if (r->sort(amax,r->tiny) != 1)
+	status = 2; /* Singular Matrix */
+
+      r->rcp(1, vi,0, amax,0);
+      vi += relmsz;
+    }
+
+    ai0 = a0i = aii = a;
+    vi  = v;
+
+    for (i=0;i<n;++i) {
+
+      f->set(n, buf, felmsz, ai0, rowsz);
+
+      aij = buf;
+      a0j = a;
+      /* a[i,j(<i)]  -=  sum(k<j){ a[i,k]*a[k,j] } */
+      for (j=1;j<i;++j) {
+	aij += felmsz;
+	a0j += rowsz;
+	f->mulsbt(j, aij, 0, buf, felmsz, a0j, felmsz);
+      }
+      /* a[i,j(>=i)]  -=  sum(k<i){ a[i,k]*a[k,j] } */
+      for (  ;j<n;++j) {
+	aij += felmsz;
+	a0j += rowsz;
+	f->mulsbt(i, aij, 0, buf, felmsz, a0j, felmsz);
+      }
+      f->set(n, ai0, rowsz, buf, felmsz);
+
+      /* pivoting
+	 imax = max_idx( abs( a[i,j(>=i)] ) * v[j(>=i)] ) */
+      f->abs(n-i, buf, relmsz, aii, rowsz);
+      r->mul(n-i, buf, relmsz, vi, relmsz);
+
+      r->set(1, amax,0, r->zero,0);
+      rtmp = buf;
+      imax = 0;
+      for (j=i;j<n;++j) {
+	if (r->sort(rtmp,amax) == 1) {
+	  r->set(1, amax,0, rtmp,0);
+	  imax = j;
+	}
+	rtmp += relmsz;
+      }
+
+      if (r->sort(amax,r->tiny)!=1)
+	status = 1; /* Singular Matrix */
+
+      if (i != imax) {
+	/* a[*,i] <=> a[*,imax] */
+	SWAPMEM(a+i*rowsz, a+imax*rowsz, buf, rowsz);
+	/* v[i]   <=> v[imax] */
+	SWAPMEM(vi, v+imax*relmsz, buf, relmsz);
+	NA_SWAP(((int32_t*)idx)[i],((int32_t*)idx)[imax],k);
+      }
+
+      /* a[i,j(>i)]  = a[i,j]/a[i,i] */
+      f->div(n-i-1, aii+rowsz, rowsz, aii, 0);
+
+      ai0 += felmsz;
+      a0i += rowsz;
+      aii += diagsz;
+      vi  += relmsz;
+    }
+
+    a   += matsz;
+    idx += sizeof(int32_t)*n;
+  }
+  return status;
+}
+
+
+
+static int
+ na_lu_fact_func(int ni, char *a, char *idx, int *shape, int type)
+{
+  volatile VALUE val;
+  char *buf;
+  int status, size, n=shape[0];
+
+  if (type==NA_ROBJ) {
+    VALUE *mem;
+    int i;
+    size = n*2+1;
+    mem = ALLOC_N(VALUE, size);
+    for (i=0; i<size; i++) mem[i] = Qnil;
+    val = rb_ary_new4(size, mem);
+    xfree(mem);
+    buf = (char*)((RARRAY_PTR(val)));
+    status = na_lu_fact_func_body( ni, a, idx, shape, type, buf );
+  } else {
+    size = na_sizeof[type]*n + na_sizeof[na_cast_real[type]]*(n+1);
+    buf = ALLOC_N(char, size);
+    status = na_lu_fact_func_body( ni, a, idx, shape, type, buf );
+    xfree(buf);
+  }
+  return status;
+}
+
+
+/* :nodoc: */
+static VALUE
+ na_lu_fact_bang(VALUE self)
+{ 
+  int i, total, n, sz, stat;
+  struct NARRAY *ary;
+  VALUE piv;
+  char *ptr, *idx;
+  void (*func)();
+
+  GetNArray(self,ary);
+
+  /* shape & dimension check */
+  if (ary->rank<2)
+    rb_raise(rb_eTypeError,"dim(=%i) < 2", ary->rank);
+
+  n = ary->shape[0];
+  if (n != ary->shape[1])
+    rb_raise(rb_eTypeError,"not square matrix");
+
+  total=1;
+  for (i=2; i<ary->rank; ++i)
+    total *= ary->shape[i];
+
+  piv = na_make_object(NA_LINT, ary->rank-1, ary->shape+1, cNVector);
+
+  /* prepare pivot index */
+  func = IndGenFuncs[NA_LINT];
+  sz   = na_sizeof[NA_LINT];
+  ptr  = idx = ((struct NARRAY *)DATA_PTR(piv))->ptr;
+  for (i=0; i<total; ++i) {
+    func(n,ptr,sz,0,1);
+    ptr += n*sz;
+  }
+
+  stat = na_lu_fact_func(total, ary->ptr, idx, ary->shape, ary->type);
+
+  if (stat!=0)
+    rb_raise(rb_eZeroDivError,"singular matrix, status=%i",stat);
+
+  return rb_funcall(cNMatrixLU,na_id_new,2,self,piv);
+}
+
+
+/* :nodoc: */
+static VALUE
+ na_lu_fact(VALUE self)
+{
+  return na_lu_fact_bang( na_clone(self) );
+}
+
+
+static void
+na_lu_pivot_func( int ni,
+		  char *x, int ps1, char *y, int ps2, char *idx, int ps3,
+		  int *shape, int type )
+{
+  int i, n, sz;
+  char *xi;
+  na_funcset_t *f = &na_funcset[type];
+
+  n = shape[1];
+  sz = f->elmsz * shape[0];
+
+  for (; ni>0; --ni) {
+    xi = x;
+    for (i=0; i<n; ++i) {
+      memcpy(xi, y+((int32_t*)idx)[i]*sz, sz);
+      xi += sz;
+    }
+    x   += ps1;
+    y   += ps2;
+    idx += ps3;
+  }
+}
+
+
+
+static void
+na_lu_solve_func_body( int ni,
+		       char *x, int ps1,  char *a, int ps2,
+		       int *shape, int type, char *buf )
+{
+  char *aii, *a0i, *xx, *xi;
+  int i,k;
+  na_funcset_t *f = &na_funcset[type];
+  int n = shape[1];
+  int sz = na_sizeof[type];
+  int xsz = shape[0] * sz;
+  int rowsz = sz * n;
+  int matsz = rowsz * n;
+  int diagsz = rowsz + sz;
+
+  for (; ni>0; --ni) {
+
+    xx = x;
+
+    for (k=shape[0]; k>0; --k) { /* once if x is vector */
+
+      f->set(n, buf,sz, xx,xsz);
+
+      xi  = buf;
+      a0i = a;
+
+      /* solve Lx' = y' */
+      for (i=1; i<n; ++i) {
+	/* x[i] -= a[j(<i),i] * x[j(<i)] */
+	xi  += sz;
+	a0i += rowsz;
+	f->mulsbt(i, xi, 0, a0i, sz, buf, sz);
+      }
+
+      xi  = buf + sz*(n-1);
+      aii = a + (matsz-sz);
+
+      /* solve Ux = x' */
+      f->div(1, xi,0, aii,0);
+      for (i=n-1; i>0; --i) {
+	xi  -= sz;
+	aii -= diagsz;
+	/* x[i] -= a[j(>i),i] * x[j(>i)] */
+	f->mulsbt(n-i, xi,0, aii+sz, sz, xi+sz, sz);
+	/* x[i] /= a[i,i] */
+	f->div(1, xi,0, aii,0);
+      }
+
+      f->set(n, xx,xsz, buf,sz);
+
+      xx += sz;
+    }
+
+    x += ps1;
+    a += ps2;
+  }
+}
+
+
+static void
+na_lu_solve_func( int ni,
+		  char *z, int ps,  char *x, int ps1,  char *a, int ps2,
+		  int *shape, int type )
+{
+  volatile VALUE val;
+  char *buf;
+  int size;
+
+  if (type==NA_ROBJ) {
+    VALUE *mem;
+    int i;
+    size = shape[1];
+    mem = ALLOC_N(VALUE, size);
+    for (i=0; i<size; i++) mem[i] = Qnil;
+    val = rb_ary_new4(size, mem);
+    xfree(mem);
+    buf = (char*)((RARRAY_PTR(val)));
+    na_lu_solve_func_body( ni, x, ps1, a, ps2, shape, type, buf );
+  } else {
+    size = shape[1] * na_sizeof[type];
+    buf = ALLOC_N(char, size);
+    na_lu_solve_func_body( ni, x, ps1, a, ps2, shape, type, buf );
+    xfree(buf);
+  }
+}
+
+
+static void
+na_shape_max2(int ndim, int *shape, int n1, int *shape1, int n2, int *shape2)
+{
+  int *tmp;
+  int  i;
+
+  if (n1 < n2) {
+    NA_SWAP(shape1,shape2,tmp);
+  }
+
+  for (i=0; i<n2; ++i) {
+    shape[i] = NA_MAX(shape1[i],shape2[i]);
+  }
+  for (   ; i<n1; ++i) {
+    shape[i] = shape1[i];
+  }
+  for (   ; i<ndim; ++i) {
+    shape[i] = 1;
+  }
+}
+
+
+
+/*
+ *  call-seq:
+ *     lu.solve(arg)  -> result
+ *
+ *  Solve with the result of LU factorization.
+ *  arg should be NMatrix or NVector instance.
+ *  Returns an instance of same class with arg.
+ */
+static VALUE
+na_lu_solve(VALUE self, volatile VALUE other)
+{
+  int  n, ndim;
+  int *shape;
+  struct NARRAY *a1, *a2, *l, *p;
+  VALUE pv, obj, klass;
+  volatile VALUE lu;
+
+  klass = CLASS_OF(other);
+  if (klass==cNVector)
+    other = na_newdim_ref(1,(VALUE*)na_funcset[NA_ROBJ].zero,other);
+  else if (klass!=cNMatrix)
+    rb_raise(rb_eTypeError,"neither NMatrix or NVector");
+
+  lu = rb_ivar_get(self, id_lu);
+  pv = rb_ivar_get(self, id_pivot);
+
+  GetNArray(lu,l);
+
+  other = na_upcast_object(other,l->type);
+  GetNArray(other,a1);
+
+  lu = na_upcast_type(lu,a1->type);
+  GetNArray(lu,l);
+  GetNArray(pv,p);
+
+  n = l->shape[0];
+  if (n != a1->shape[1])
+    rb_raise(rb_eTypeError,"size mismatch (%i!=%i)",n,a1->shape[1]);
+
+  ndim  = NA_MAX(l->rank, a1->rank);
+  shape = ALLOCA_N(int, ndim);
+
+  shape[0] = a1->shape[0];
+  na_shape_max2( ndim-1, shape+1, a1->rank-1, a1->shape+1,
+		 l->rank-1, l->shape+1 );
+  obj = na_make_object( a1->type, ndim, shape, klass );
+
+  GetNArray(obj,a2);
+
+  na_exec_linalg( a2, a1, p, 2, 2, 1, na_lu_pivot_func );
+  na_exec_linalg( a2, a2, l, 2, 2, 2, na_lu_solve_func );
+
+  if (klass==cNVector) {
+    shape = ALLOC_N(int, ndim-1);
+    memcpy(shape,a2->shape+1,sizeof(int)*(ndim-1));
+    xfree(a2->shape);
+    a2->shape = shape;
+    --(a2->rank);
+  }
+  return obj;
+}
+
+
+/* :nodoc: */
+static VALUE
+na_lu_init(VALUE self, VALUE lu, VALUE piv)
+{
+  int i;
+  struct NARRAY *l, *p;
+
+  if (CLASS_OF(lu)!=cNMatrix)
+    rb_raise(rb_eTypeError,"LU should be NMatrix");
+  if (CLASS_OF(piv)!=cNVector)
+    rb_raise(rb_eTypeError,"pivot should be NVector");
+
+  GetNArray(lu,l);
+  GetNArray(piv,p);
+
+  if (p->type != NA_LINT)
+    rb_raise(rb_eRuntimeError,"pivot type must be Integer");
+
+  if (l->rank != p->rank+1)
+    rb_raise(rb_eRuntimeError,"array dimension mismatch %i!=%i+1",
+	     l->rank, p->rank);
+
+  if (l->shape[0] != l->shape[1])
+    rb_raise(rb_eRuntimeError,"LU matrix (%i,%i) is not square",
+	     l->shape[0], l->shape[1]);
+
+  for (i=1; i<l->rank; ++i)
+    if (l->shape[i] != p->shape[i-1])
+      rb_raise(rb_eRuntimeError,"array size mismatch %i!=%i at %i",
+	       l->shape[i], p->shape[i-1], i);
+
+  rb_ivar_set(self, id_lu, lu);
+  rb_ivar_set(self, id_pivot, piv);
+  return Qnil;
+}
+
+
+
+void Init_na_linalg()
+{
+  static double tiny_d = 1e-15;
+  static float  tiny_f = (float)1e-7;
+  int i, sz;
+  int32_t one=1, zero=0;
+  static VALUE zerov = INT2FIX(0);
+  static VALUE onev = INT2FIX(1);
+  char *a = malloc(NA_NTYPES*sizeof(dcomplex)*2);
+
+  for (i=1;i<NA_NTYPES;++i) {
+    sz = na_funcset[i].elmsz = na_sizeof[i];
+    sz = (sz>((int)sizeof(int))) ? sz : (int)sizeof(int);
+    SetFuncs[i][NA_LINT](1, a,0, &one, 0);
+    na_funcset[i].one = a;
+    a += sz;
+    SetFuncs[i][NA_LINT](1, a,0, &zero,0);
+    na_funcset[i].zero = a;
+    na_funcset[i].tiny = a;
+    a += sz;
+    na_funcset[i].set = SetFuncs[i][i];
+    na_funcset[i].neg = NegFuncs[i];
+    na_funcset[i].rcp = RcpFuncs[i];
+    na_funcset[i].abs = AbsFuncs[i];
+    na_funcset[i].add = AddUFuncs[i];
+    na_funcset[i].sbt = SbtUFuncs[i];
+    na_funcset[i].mul = MulUFuncs[i];
+    na_funcset[i].div = DivUFuncs[i];
+    na_funcset[i].mod = ModUFuncs[i];
+    na_funcset[i].muladd = MulAddFuncs[i];
+    na_funcset[i].mulsbt = MulSbtFuncs[i];
+    na_funcset[i].cmp = CmpFuncs[i];
+    na_funcset[i].min = MinFuncs[i];
+    na_funcset[i].max = MaxFuncs[i];
+    na_funcset[i].sort = SortFuncs[i];
+  }
+  na_funcset[NA_SFLOAT].tiny = (char*)&tiny_f;
+  na_funcset[NA_DFLOAT].tiny = (char*)&tiny_d;
+  na_funcset[NA_ROBJ].zero = (char*)&zerov;
+  na_funcset[NA_ROBJ].one  = (char*)&onev;
+
+  cNVector = rb_define_class("NVector",cNArray);
+  cNMatrix = rb_define_class("NMatrix",cNArray);
+  cNMatrixLU = rb_define_class("NMatrixLU",rb_cObject);
+
+  rb_define_method(cNMatrix, "lu_fact!", na_lu_fact_bang, 0);
+  rb_define_alias(cNMatrix,  "lu!","lu_fact!");
+  rb_define_method(cNMatrix, "lu_fact",  na_lu_fact, 0);
+  rb_define_alias(cNMatrix,  "lu","lu_fact");
+
+  rb_define_method(cNMatrixLU, "initialize", na_lu_init, 2);
+  rb_define_method(cNMatrixLU, "solve", na_lu_solve, 1);
+
+  id_lu    = rb_intern("@lu");
+  id_pivot = rb_intern("@pivot");
+}
diff --git a/app/server/vendor/narray-0.6.1.1/na_random.c b/app/server/vendor/narray-0.6.1.1/na_random.c
new file mode 100755
index 0000000..1ccf1c1
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/na_random.c
@@ -0,0 +1,416 @@
+/*
+  na_random.c
+  Numerical Array Extention for Ruby
+    (C) Copyright 2003-2008 by Masahiro TANAKA
+
+  This program is free software.
+  You can distribute/modify this program
+  under the same terms as Ruby itself.
+  NO WARRANTY.
+*/
+
+/*
+This is based on trimmed version of MT19937.  To get the original version,
+contact <http://www.math.keio.ac.jp/~matumoto/emt.html>.
+
+The original copyright notice follows.
+
+   A C-program for MT19937, with initialization improved 2002/2/10.
+   Coded by Takuji Nishimura and Makoto Matsumoto.
+   This is a faster version by taking Shawn Cokus's optimization,
+   Matthe Bellew's simplification, Isaku Wada's real version.
+
+   Before using, initialize the state by using init_genrand(seed)
+   or init_by_array(init_key, key_length).
+
+   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+     1. Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+
+     2. Redistributions in binary form must reproduce the above copyright
+        notice, this list of conditions and the following disclaimer in the
+        documentation and/or other materials provided with the distribution.
+
+     3. The names of its contributors may not be used to endorse or promote
+        products derived from this software without specific prior written
+        permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+   Any feedback is very welcome.
+   http://www.math.keio.ac.jp/matumoto/emt.html
+   email: matumoto at math.keio.ac.jp
+*/
+#include "ruby.h"
+#include "narray.h"
+#include "narray_local.h"
+
+/* Period parameters */
+#define N 624
+#define M 397
+#define MATRIX_A 0x9908b0dfUL   /* constant vector a */
+#define UMASK 0x80000000UL /* most significant w-r bits */
+#define LMASK 0x7fffffffUL /* least significant r bits */
+#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
+#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
+
+static u_int32_t state[N]; /* the array for the state vector  */
+static int left = 1;
+static int initf = 0;
+static u_int32_t *next;
+
+/* initializes state[N] with a seed */
+static void
+ init_genrand(u_int32_t s)
+{
+    int j;
+    state[0]= s & 0xffffffffUL;
+    for (j=1; j<N; ++j) {
+        state[j] = (1812433253UL * (state[j-1] ^ (state[j-1] >> 30)) + j);
+        /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
+        /* In the previous versions, MSBs of the seed affect   */
+        /* only MSBs of the array state[].                        */
+        /* 2002/01/09 modified by Makoto Matsumoto             */
+        state[j] &= 0xffffffffUL;  /* for >32 bit machines */
+    }
+    left = 1; initf = 1;
+}
+
+static void
+ next_state()
+{
+    u_int32_t *p=state;
+    int j;
+
+    /* if init_genrand() has not been called, */
+    /* a default initial seed is used         */
+    if (initf==0) init_genrand(5489UL);
+
+    left = N;
+    next = state;
+
+    for (j=N-M+1; --j; ++p)
+        *p = p[M] ^ TWIST(p[0], p[1]);
+
+    for (j=M; --j; ++p)
+        *p = p[M-N] ^ TWIST(p[0], p[1]);
+
+    *p = p[M-N] ^ TWIST(p[0], state[0]);
+}
+
+#undef N
+#undef M
+
+/* These real versions are due to Isaku Wada, 2002/01/09 added */
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <time.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+static int first = 1;
+
+static int
+rand_init(seed)
+    u_int32_t seed;
+{
+    static u_int32_t saved_seed;
+    u_int32_t old;
+
+    first = 0;
+    init_genrand(seed);
+    old = saved_seed;
+    saved_seed = seed;
+
+    return old;
+}
+
+static u_int32_t
+ random_seed()
+{
+    static int n = 0;
+    struct timeval tv;
+
+    gettimeofday(&tv, 0);
+    return tv.tv_sec ^ tv.tv_usec ^ getpid() ^ n++;
+}
+
+static VALUE
+ na_s_srand(int argc, VALUE *argv, VALUE obj)
+{
+    VALUE sd;
+    u_int32_t seed, old;
+
+    //rb_secure(4);
+    if (rb_scan_args(argc, argv, "01", &sd) == 0) {
+	seed = random_seed();
+    }
+    else {
+	seed = NUM2ULONG(sd);
+    }
+    old = rand_init(seed);
+
+    return ULONG2NUM(old);
+}
+
+/* - end of the code from ruby/random.c - */
+
+#define genrand(y) \
+{ if (--left == 0) next_state();\
+  (y) = *next++;\
+  (y) ^= ((y) >> 11);\
+  (y) ^= ((y) << 7) & 0x9d2c5680UL;\
+  (y) ^= ((y) << 15) & 0xefc60000UL;\
+  (y) ^= ((y) >> 18); }
+
+#define rand_double(x,y) \
+  (((double)((x)>>5)+(double)((y)>>6)*(1.0/67108864.0)) * (1.0/134217728.0))
+
+#define rand_single(y) \
+  ((double)(y) * (1.0/4294967296.0))
+
+static int n_bits(int32_t a)
+{
+  int i, x, xu, xl, n=4;
+  int32_t m;
+
+  if (a==0) return 0;
+  if (a<0) a=-a;
+
+  x  = 1<<n;
+  xu = 1<<(n+1);
+  xl = 0;
+
+  for (i=n; i>=0; --i) {
+    m = ~((1<<(x-1))-1);
+
+    if (m & a) {
+      xl = x;
+      x += 1<<(i-1);
+    } else {
+      xu = x;
+      x -= 1<<(i-1);
+    }
+    /* printf("%3i, [%3i, %3i], %x\n", i, xu, xl, m1); */
+  }
+  /* if (xu-xl!=1) printf("*** erorr %d - %d != 1\n", xu, xl); */
+  return xl;
+}
+
+// max&limit must be integer
+static u_int32_t size_check(double rmax, double limit)
+{
+  u_int32_t max;
+
+  if ( rmax == 0 ) {
+    return (u_int32_t)(limit-1);
+  }
+  if ( rmax < 0 ) {
+    rmax = -rmax;
+  }
+  max = (u_int32_t)(rmax - 1);
+  if ( max >= limit ) {
+    rb_raise(rb_eArgError, "rand-max(%.0f) must be <= %.0f", rmax, limit);
+  }
+  return max;
+}
+
+static void TpErr(void) {
+    rb_raise(rb_eTypeError,"illegal operation with this type");
+}
+
+static void RndB(int n, char *p1, int i1, double rmax)
+{
+  u_int32_t y;
+  u_int8_t max;
+  int shift;
+
+  if ( rmax < 0 ) {
+    rb_raise(rb_eArgError, "rand-max must be positive");
+  }
+  max   = size_check(rmax,0x100);
+  shift = 32 - n_bits(max);
+
+  if (max<1) {
+    for (; n; --n) {
+      *(u_int8_t*)p1 = 0;
+      p1+=i1;
+    }
+  } else {
+    for (; n; --n) {
+      do {
+	genrand(y);
+	y >>= shift;
+      } while (y > max);
+      *(u_int8_t*)p1 = (u_int8_t)y;
+      p1+=i1;
+    }
+  }
+}
+
+static void RndI(int n, char *p1, int i1, double rmax)
+{
+  u_int32_t y;
+  u_int32_t max;
+  int shift, sign=1;
+
+  if ( rmax < 0 ) { rmax = -rmax; sign = -1; }
+  max   = size_check(rmax,0x8000);
+  shift = 32 - n_bits(max);
+
+  if (max<1) {
+    for (; n; --n) {
+      *(int16_t*)p1 = 0;
+      p1+=i1;
+    }
+  } else {
+    for (; n; --n) {
+      do {
+	genrand(y);
+	y >>= shift;
+      } while (y > max);
+      *(int16_t*)p1 = (int16_t)y*sign;
+      p1+=i1;
+    }
+  }
+}
+
+static void RndL(int n, char *p1, int i1, double rmax)
+{
+  u_int32_t y;
+  u_int32_t max;
+  int shift, sign=1;
+
+  if ( rmax < 0 ) { rmax = -rmax; sign = -1; }
+  max   = size_check(rmax,0x80000000);
+  shift = 32 - n_bits(max);
+
+  if (max<1) {
+    for (; n; --n) {
+      *(int32_t*)p1 = 0;
+      p1+=i1;
+    }
+  } else {
+    for (; n; --n) {
+      do {
+	genrand(y);
+	y >>= shift;
+      } while (y > max);
+      *(int32_t*)p1 = (int32_t)y*sign;
+      p1+=i1;
+    }
+  }
+}
+
+static void RndF(int n, char *p1, int i1, double rmax)
+{
+  u_int32_t y;
+
+  for (; n; --n) {
+    genrand(y);
+    *(float*)p1 = rand_single(y) * rmax;
+    p1+=i1;
+  }
+}
+
+static void RndD(int n, char *p1, int i1, double rmax)
+{
+  u_int32_t x,y;
+
+  for (; n; --n) {
+    genrand(x);
+    genrand(y);
+    *(double*)p1 = rand_double(x,y) * rmax;
+    p1+=i1;
+  }
+}
+
+static void RndX(int n, char *p1, int i1, double rmax)
+{
+  u_int32_t y;
+
+  for (; n; --n) {
+    genrand(y);
+    ((scomplex*)p1)->r = rand_single(y) * rmax;
+    ((scomplex*)p1)->i = 0;
+    p1+=i1;
+  }
+}
+
+static void RndC(int n, char *p1, int i1, double rmax)
+{
+  u_int32_t x,y;
+
+  for (; n; --n) {
+    genrand(x);
+    genrand(y);
+    ((dcomplex*)p1)->r = rand_double(x,y) * rmax;
+    ((dcomplex*)p1)->i = 0;
+    p1+=i1;
+  }
+}
+
+na_func_t RndFuncs =
+  { TpErr, RndB, RndI, RndL, RndF, RndD, RndX, RndC, TpErr };
+
+
+static VALUE
+ na_random_bang(int argc, VALUE *argv, VALUE self)
+{
+  VALUE  vmax;
+  struct NARRAY *ary;
+  double rmax;
+
+  rb_scan_args(argc, argv, "01", &vmax);
+  if (first) {
+    rand_init(random_seed());
+  }
+  if (NIL_P(vmax)) {
+    rmax = 1;
+  } else {
+    rmax = NUM2DBL(vmax);
+  }
+  if (isinf(rmax) || isnan(rmax)) {
+    rb_raise(rb_eArgError, "rand-max must be regular value");
+  }
+
+  GetNArray(self,ary);
+
+  (*RndFuncs[ary->type])( ary->total, ary->ptr, na_sizeof[ary->type], rmax );
+
+  return self;
+}
+
+static VALUE
+ na_random(int argc, VALUE *argv, VALUE self)
+{
+  return na_random_bang(argc, argv, na_clone(self));
+}
+
+void
+Init_na_random()
+{
+    rb_define_singleton_method(cNArray,"srand",na_s_srand,-1);
+    rb_define_method(cNArray, "random!", na_random_bang,-1);
+    rb_define_method(cNArray, "random",  na_random,-1);
+}
diff --git a/app/server/vendor/narray-0.6.1.1/narray.c b/app/server/vendor/narray-0.6.1.1/narray.c
new file mode 100755
index 0000000..5405beb
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/narray.c
@@ -0,0 +1,1323 @@
+/*
+  narray.c
+  Numerical Array Extention for Ruby
+    (C) Copyright 1999-2008 by Masahiro TANAKA
+
+  This program is free software.
+  You can distribute/modify this program
+  under the same terms as Ruby itself.
+  NO WARRANTY.
+*/
+#define NARRAY_C
+#include <ruby.h>
+#include "narray.h"
+#include "narray_local.h"
+
+/* global variables within this module */
+VALUE cNArray, cNArrayScalar, cComplex;
+
+ID na_id_beg, na_id_end, na_id_exclude_end;
+ID na_id_minus, na_id_abs, na_id_power;
+ID na_id_compare, na_id_ne, na_id_and, na_id_or;
+ID na_id_class_dim;
+ID na_id_add, na_id_sbt, na_id_mul, na_id_div, na_id_mod;
+ID na_id_real, na_id_imag;
+ID na_id_coerce_rev;
+ID na_id_new;
+ID na_id_Complex;
+static ID na_id_to_i, na_id_usec, na_id_now;
+
+const int na_sizeof[NA_NTYPES+1] = {
+  0,
+  sizeof(u_int8_t),
+  sizeof(int16_t),
+  sizeof(int32_t),
+  sizeof(float),
+  sizeof(double),
+  sizeof(scomplex),
+  sizeof(dcomplex),
+  sizeof(VALUE),
+  0
+};
+
+const char *na_typestring[] = {
+  "none",
+  "byte",	/* 1 */
+  "sint",	/* 2 */
+  "int",	/* 3 */
+  "sfloat",	/* 4 */
+  "float",	/* 5 */
+  "scomplex",	/* 6 */
+  "complex",	/* 7 */
+  "object",	/* 8 */
+  "ntypes"	/* 9 */
+};
+
+#ifdef NARRAY_GC
+static int mem_count = 0;
+static int na_gc_freq = 2500000;   /* Frequency of Garbage Collection */
+#endif
+
+void Init_na_array(void);
+void Init_na_index(void);
+void Init_nmath(void);
+void Init_na_funcs(void);
+void Init_na_linalg(void);
+void Init_na_random(void);
+
+
+#ifdef DEBUG
+void na_xfree(void *ptr)
+{
+  if (!ptr) abort();
+  free(ptr);
+}
+#endif
+
+/* mark items */
+static void
+ na_mark_obj(struct NARRAY *ary)
+{
+  int i;
+  VALUE *ptr;
+
+  ptr = (VALUE*) ary->ptr;
+  for (i=ary->total; i>0; --i)
+    rb_gc_mark(*ptr++);
+}
+
+static void
+ na_mark_ref(struct NARRAY *ary)
+{
+  struct NARRAY *a2;
+
+  rb_gc_mark( ary->ref );
+
+  GetNArray(ary->ref,a2);
+  if (a2->type == NA_ROBJ) na_mark_obj(a2);
+}
+
+
+static void
+ na_free(struct NARRAY* ary)
+{
+  if ( ary->total > 0 ) {
+    if (ary->ref == Qnil || ary->ref == Qtrue) {  /* non reference */
+      xfree(ary->ptr);
+    }
+    xfree(ary->shape);
+#ifdef DEBUG
+    ary->shape = NULL;
+    ary->ptr = NULL;
+#endif
+  }
+  xfree(ary);
+}
+
+
+/* allocation of NARRAY */
+struct NARRAY*
+ na_alloc_struct(int type, int rank, int *shape)
+{
+  int total=1, total_bak;
+  int i, memsz;
+  struct NARRAY *ary;
+
+  for (i=0; i<rank; ++i) {
+    if (shape[i] < 0) {
+      rb_raise(rb_eArgError, "negative array size");
+    } else if (shape[i] == 0) {
+      total = 0;
+      break;
+    }
+    total_bak = total;
+    total *= shape[i];
+    if (total < 1 || total > 2147483647 || total/shape[i] != total_bak) {
+      rb_raise(rb_eArgError, "array size is too large");
+    }
+  }
+
+  if (rank<=0 || total<=0) {
+    /* empty array */
+    ary = ALLOC(struct NARRAY);
+    ary->rank  =
+    ary->total = 0;
+    ary->shape = NULL;
+    ary->ptr   = NULL;
+    ary->type  = type;
+  }
+  else {
+    memsz = na_sizeof[type] * total;
+
+    if (memsz < 1 || memsz > 2147483647 || memsz/na_sizeof[type] != total) {
+      rb_raise(rb_eArgError, "allocation size is too large");
+    }
+
+    /* Garbage Collection */
+#ifdef NARRAY_GC
+    mem_count += memsz;
+    if ( mem_count > na_gc_freq ) { rb_gc(); mem_count=0; }
+#endif
+
+    ary        = ALLOC(struct NARRAY);
+    ary->shape = ALLOC_N(int,  rank);
+    ary->ptr   = ALLOC_N(char, memsz);
+
+    ary->rank  = rank;
+    ary->total = total;
+    ary->type  = type;
+    for (i=0; i<rank; ++i)
+      ary->shape[i] = shape[i];
+  }
+  ary->ref = Qtrue;
+  return ary;
+}
+
+#if !defined RCLASS_SUPER
+#define RCLASS_SUPER(v) (RCLASS(v)->super)
+#endif
+
+static void
+ na_check_class_narray(VALUE v)
+{
+  if (TYPE(v) != T_CLASS) {
+    rb_raise(rb_eRuntimeError, "class required");
+  }
+
+  if (v == cNArray)
+    return;
+  if (RTEST(rb_funcall(v, rb_intern("<="), 1, cNArray)))
+    return;
+
+  rb_raise(rb_eRuntimeError, "need NArray or its subclass");
+}
+
+
+static VALUE
+ na_wrap_struct_class(struct NARRAY *ary, VALUE klass)
+{
+  VALUE v;
+  int class_dim;
+
+  /* Extract element */
+  if (ary->rank==0 && ary->total==1) {
+    SetFuncs[NA_ROBJ][ary->type](1,&v,0,ary->ptr,0);
+    na_free(ary);
+    return v;
+  }
+
+  /* check NArray >= klass */
+  na_check_class_narray(klass);
+
+  /* Check dimension */
+  class_dim = NUM2INT(rb_const_get(klass, na_id_class_dim));
+  if (ary->rank < class_dim)
+    rb_raise(rb_eTypeError, "array.dim(=%i) < CLASS_DIMENSION(=%i)",
+	     ary->rank, class_dim);
+
+  if (ary->ref == Qnil)
+    rb_raise(rb_eRuntimeError, "already wrapped object");
+
+  /* Turn on WRAPPED flag */
+  if (ary->ref == Qtrue) {
+    ary->ref = Qnil;
+    if (NA_IsROBJ(ary))
+      return Data_Wrap_Struct(klass, na_mark_obj, na_free, ary);
+    else
+      return Data_Wrap_Struct(klass, 0, na_free, ary);
+  }
+
+  /* reference to another NArray*/
+  return Data_Wrap_Struct(klass, na_mark_ref, na_free, ary);
+}
+
+
+static VALUE
+ na_wrap_struct(struct NARRAY *ary, VALUE obj)
+{
+  return na_wrap_struct_class(ary,CLASS_OF(obj));
+}
+
+
+VALUE
+ na_make_object(int type, int rank, int *shape, VALUE klass)
+{
+  struct NARRAY *na;
+
+  na = na_alloc_struct(type, rank, shape);
+
+  if (type==NA_ROBJ) {
+    rb_mem_clear((VALUE*)(na->ptr), na->total);
+  }
+  return na_wrap_struct_class(na, klass);
+}
+
+
+/* restriction: Integer, Float, Complex === obj */
+VALUE
+ na_make_scalar(VALUE obj, int type)
+{
+  static int shape=1;
+  VALUE v;
+  struct NARRAY *ary;
+
+  v = na_make_object(type,1,&shape,cNArrayScalar);
+  GetNArray(v,ary);
+  SetFuncs[ary->type][NA_ROBJ](1, ary->ptr,0, &obj,0);
+
+  return v;
+}
+
+
+VALUE
+ na_make_empty(int type, VALUE klass)
+{
+  struct NARRAY *na;
+
+  na = na_alloc_struct(type, 0, NULL);
+  return na_wrap_struct_class(na, klass);
+}
+
+
+/* allocate reference to NArray */
+struct NARRAY*
+ na_ref_alloc_struct(VALUE obj)
+{
+  int i;
+  struct NARRAY *orig, *ary;
+
+  GetNArray(obj,orig);
+
+  if (orig->rank<=0)
+    rb_raise(rb_eRuntimeError, "cannot create NArrayRefer of Empty NArray");
+
+  ary        = ALLOC(struct NARRAY);
+  ary->shape = ALLOC_N(int, orig->rank);
+  ary->ptr   = orig->ptr;
+  ary->rank  = orig->rank;
+  ary->total = orig->total;
+  ary->type  = orig->type;
+  for (i=0; i<orig->rank; ++i)
+    ary->shape[i] = orig->shape[i];
+  ary->ref   = obj;
+
+  return ary;
+}
+
+/* method:  self.refer */
+static VALUE
+ na_refer(VALUE self)
+{
+  return na_wrap_struct(na_ref_alloc_struct(self), self);
+}
+
+/* singleton method:  NArray.refer( other ) */
+static VALUE
+ na_s_refer(VALUE klass, VALUE self)
+{
+  return na_wrap_struct_class(na_ref_alloc_struct(self), klass);
+}
+
+/* method:  self.original */
+static VALUE
+ na_original(VALUE self)
+{
+  struct NARRAY *ary;
+
+  GetNArray(self,ary);
+  return ary->ref;
+}
+
+
+void
+ na_clear_data(struct NARRAY *ary)
+{
+  if (NA_IsROBJ(ary))
+    rb_mem_clear((VALUE*)(ary->ptr), ary->total);
+  else
+    MEMZERO(ary->ptr, char, na_sizeof[ary->type]*ary->total);
+}
+
+
+/* local function for new array creation */
+static VALUE
+ na_new2(int argc, VALUE *argv, int type, VALUE klass)
+{
+  int i, *shape;
+  struct NARRAY *ary;
+  VALUE v;
+
+  if (argc == 0)
+    rb_raise(rb_eArgError, "Argument required");
+
+  shape = ALLOCA_N(int,argc);
+  for (i=0; i<argc; ++i) shape[i]=NUM2INT(argv[i]);
+
+  v = na_make_object(type,argc,shape,klass);
+  GetNArray(v,ary);
+
+  if (ary->type != NA_ROBJ)
+    na_clear_data(ary);
+
+  /* rb_obj_call_init(v, 0, 0); */
+  return v;
+}
+
+
+/* Convert type arguments -> typecode */
+int
+ na_get_typecode(VALUE v)
+{
+  struct NARRAY *na;
+  int i;
+
+  if (v==rb_cFloat)   return NA_DFLOAT;
+  if (v==rb_cInteger) return NA_LINT;
+  if (v==cComplex)    return NA_DCOMPLEX;
+  if (v==rb_cObject)  return NA_ROBJ;
+  if (FIXNUM_P(v)) {
+    i = NUM2INT(v);
+    if (i<=NA_NONE || i>=NA_NTYPES)
+      rb_raise(rb_eArgError, "Wrong type code");
+    return i;
+  }
+  if (NA_IsNArray(v)) {
+    GetNArray(v,na);
+    return na->type;
+  }
+  if (TYPE(v)==T_STRING) {
+    for (i=1; i<NA_NTYPES; ++i) {
+      if ( !strncmp( RSTRING_PTR(v), na_typestring[i], RSTRING_LEN(v)) )
+	return i;
+    }
+  }
+  rb_raise(rb_eArgError, "Unrecognized NArray type");
+  return 0;
+}
+
+
+/* class method: new(type, size1,size2,...,sizeN) */
+static VALUE
+ na_s_new(int argc, VALUE *argv, VALUE klass)
+{
+  if (argc == 0)
+    rb_raise(rb_eArgError, "Argument required");
+  return na_new2(argc-1, argv+1, na_get_typecode(argv[0]), klass);
+}
+
+/* class method: byte(size1,size2,...,sizeN) */
+static VALUE
+ na_s_new_byte(int argc, VALUE *argv, VALUE klass)
+{ return na_new2(argc, argv, NA_BYTE, klass); }
+
+/* class method: sint(size1,size2,...,sizeN) */
+static VALUE
+ na_s_new_sint(int argc, VALUE *argv, VALUE klass)
+{ return na_new2(argc, argv, NA_SINT, klass); }
+
+/* class method: int(size1,size2,...,sizeN) */
+static VALUE
+ na_s_new_int(int argc, VALUE *argv, VALUE klass)
+{ return na_new2(argc, argv, NA_LINT, klass); }
+
+/* class method: sfloat(size1,size2,...,sizeN) */
+static VALUE
+ na_s_new_sfloat(int argc, VALUE *argv, VALUE klass)
+{ return na_new2(argc, argv, NA_SFLOAT, klass); }
+
+/* class method: float(size1,size2,...,sizeN) */
+static VALUE
+ na_s_new_float(int argc, VALUE *argv, VALUE klass)
+{ return na_new2(argc, argv, NA_DFLOAT, klass); }
+
+/* class method: scomplex(size1,size2,...,sizeN) */
+static VALUE
+ na_s_new_scomplex(int argc, VALUE *argv, VALUE klass)
+{ return na_new2(argc, argv, NA_SCOMPLEX, klass); }
+
+/* class method: complex(size1,size2,...,sizeN) */
+static VALUE
+ na_s_new_complex(int argc, VALUE *argv, VALUE klass)
+{ return na_new2(argc, argv, NA_DCOMPLEX, klass); }
+
+/* class method: object(size1,size2,...,sizeN) */
+static VALUE
+ na_s_new_object(int argc, VALUE *argv, VALUE klass)
+{ return na_new2(argc, argv, NA_ROBJ, klass); }
+
+
+
+/* method: dup() */
+VALUE
+ na_clone(VALUE self)
+{
+  struct NARRAY *org, *cpy;
+
+  GetNArray(self,org);
+  cpy = na_alloc_struct(org->type,org->rank,org->shape);
+  memcpy(cpy->ptr, org->ptr, na_sizeof[org->type] * org->total);
+  return na_wrap_struct(cpy,self);
+}
+
+
+/* local function */
+void
+ na_copy_nary(struct NARRAY *dst, struct NARRAY *src)
+{
+  if (dst->total != src->total)
+    rb_raise(rb_eRuntimeError, "src and dst array sizes mismatch");
+
+  if (dst->type == src->type)
+    memcpy(dst->ptr, src->ptr, src->total*na_sizeof[src->type]);
+  else {
+    SetFuncs[dst->type][src->type]( src->total,
+				    dst->ptr, na_sizeof[dst->type],
+				    src->ptr, na_sizeof[src->type] );
+  }
+}
+
+
+/* method: to_type(type) */
+static VALUE
+ na_to_type(VALUE self, VALUE vtype)
+{
+  struct NARRAY *a1, *a2;
+  VALUE v;
+
+  GetNArray(self,a1);
+
+  v = na_make_object(na_get_typecode(vtype), a1->rank, a1->shape,
+		     CLASS_OF(self));
+  GetNArray(v,a2);
+  na_copy_nary(a2,a1);
+  return v;
+}
+
+
+/* method: to_f() */
+static VALUE
+ na_to_float(VALUE self)
+{
+  struct NARRAY *a1, *a2;
+  VALUE v;
+
+  GetNArray(self,a1);
+
+  v = na_make_object(na_upcast[NA_SFLOAT][a1->type], a1->rank, a1->shape,
+		     CLASS_OF(self));
+  GetNArray(v,a2);
+  na_copy_nary(a2,a1);
+  return v;
+}
+
+
+/* method: to_i() */
+static VALUE
+ na_to_integer(VALUE self)
+{
+  int type;
+  struct NARRAY *a1, *a2;
+  VALUE v;
+
+  GetNArray(self,a1);
+  if (!NA_IsINTEGER(a1))
+    type = NA_LINT;
+  else
+    type = a1->type;
+  v = na_make_object(type, a1->rank, a1->shape, CLASS_OF(self));
+  GetNArray(v,a2);
+  na_copy_nary(a2,a1);
+  return v;
+}
+
+
+/* method: shape() -- returns an array of shape of each rank */
+static VALUE
+ na_shape(VALUE self)
+{
+  struct NARRAY *ary;
+  VALUE *shape;
+  int i;
+
+  GetNArray(self,ary);
+  shape = ALLOCA_N(VALUE,ary->rank);
+  for (i = 0; i < ary->rank; ++i)
+    shape[i] = INT2FIX(ary->shape[i]);
+  return rb_ary_new4(ary->rank,shape);
+}
+
+
+/* method: rank() -- returns the rank of the array */
+static VALUE
+ na_rank(VALUE self)
+{
+  struct NARRAY *ary;
+  GetNArray(self,ary);
+  return INT2FIX(ary->rank);
+}
+
+
+/* method: size() -- returns the total number of elements */
+static VALUE
+ na_size(VALUE self)
+{
+  struct NARRAY *ary;
+  GetNArray(self,ary);
+  return INT2FIX(ary->total);
+}
+
+
+/* method: typecode -- returns the type of the array */
+static VALUE
+ na_typecode(VALUE self)
+{
+  struct NARRAY *ary;
+  GetNArray(self,ary);
+  return INT2FIX(ary->type);
+}
+
+
+/* method: element_size -- returns the element size of the array type */
+static VALUE
+ na_element_size(VALUE self)
+{
+  struct NARRAY *ary;
+  GetNArray(self,ary);
+  return INT2FIX(na_sizeof[ary->type]);
+}
+
+
+/* method: empty? -- returns true if empty array */
+static VALUE
+ na_is_empty(VALUE self)
+{
+  struct NARRAY *ary;
+  GetNArray(self,ary);
+  if (ary->total==0) return Qtrue;
+  return Qfalse;
+}
+
+
+/* Binary copy of String => NArray */
+static VALUE
+ na_str_to_na(int argc, VALUE *argv, VALUE str)
+{
+  struct NARRAY *ary;
+  VALUE v;
+  int i, type, len=1, str_len, *shape, rank=argc-1;
+
+  if (argc < 1)
+    rb_raise(rb_eArgError, "Type and Size Arguments required");
+
+  type = na_get_typecode(argv[0]);
+
+  str_len = RSTRING_LEN(str);
+
+  if (argc == 1) {
+    rank  = 1;
+    shape = ALLOCA_N(int,rank);
+    if ( str_len % na_sizeof[type] != 0 )
+      rb_raise(rb_eArgError, "string size mismatch");
+    shape[0] = str_len / na_sizeof[type];
+  }
+  else {
+    shape = ALLOCA_N(int,rank);
+    for (i=0; i<rank; ++i)
+      len *= shape[i] = NUM2INT(argv[i+1]);
+    len *= na_sizeof[type];
+    if ( len != str_len )
+      rb_raise(rb_eArgError, "size mismatch");
+  }
+
+  v = na_make_object( type, rank, shape, cNArray );
+  GetNArray(v,ary);
+  memcpy( ary->ptr, RSTRING_PTR(str), ary->total*na_sizeof[type] );
+
+  return v;
+}
+
+
+/* method: to_s -- convert the data contents to a binary string */
+static VALUE
+ na_to_s(VALUE self)
+{
+  struct NARRAY *ary;
+  GetNArray(self,ary);
+  if (NA_IsROBJ(ary))
+    rb_raise(rb_eTypeError,"cannot convert object-type NArray");
+  return rb_str_new(ary->ptr,ary->total*na_sizeof[ary->type]);
+}
+
+
+/* method: to_binary -- convert the data contents to a BYTE type NArray */
+static VALUE
+ na_to_binary(VALUE self)
+{
+  struct NARRAY *a1, *a2;
+  int i, *shape, rank;
+  VALUE v;
+
+  GetNArray(self,a1);
+
+  rank = a1->rank+1;
+  shape = ALLOCA_N(int,rank);
+  shape[0] = na_sizeof[a1->type];
+  for (i=1; i<rank; ++i)
+    shape[i] = a1->shape[i-1];
+
+  v = na_make_object( NA_BYTE, rank, shape, cNArray );
+  GetNArray(v,a2);
+  MEMCPY(a2->ptr,a1->ptr,char,a2->total);
+
+  return v;
+}
+
+
+/* method: to_type_as_binary(type) */
+static VALUE
+ na_to_type_as_binary(VALUE self, VALUE vtype)
+{
+  struct NARRAY *a1, *a2;
+  int size, total, type;
+  VALUE v;
+
+  type = na_get_typecode(vtype);
+  GetNArray(self,a1);
+
+  size = a1->total * na_sizeof[a1->type];
+  if ( size % na_sizeof[type] != 0 )
+    rb_raise(rb_eRuntimeError, "bina1 size mismatch");
+  total = size / na_sizeof[type];
+
+  v = na_make_object( type, 1, &total, cNArray );
+  GetNArray(v,a2);
+  MEMCPY(a2->ptr,a1->ptr,char,size);
+
+  return v;
+}
+
+
+static void
+ na_to_string_binary(int n, char *p1, int i1, char *p2, int i2)
+{
+  for (; n>0; --n) {
+    *(VALUE*)p1 = rb_str_new(p2,i2);
+    p1+=i1; p2+=i2;
+  }
+}
+
+
+/* method: to_string */
+static VALUE
+ na_to_string(VALUE self)
+{
+  VALUE v;
+  struct NARRAY *a1, *a2;
+
+  GetNArray(self,a1);
+
+  if (a1->total==0)
+    v = na_make_empty(NA_ROBJ, CLASS_OF(self));
+  else
+  if (a1->type==NA_BYTE) {
+    if (a1->rank==1)
+      return rb_str_new(a1->ptr,a1->shape[0]);
+    v  = na_make_object(NA_ROBJ, a1->rank-1, a1->shape+1, cNArray);
+    GetNArray(v,a2);
+    na_to_string_binary( a2->total,
+			 a2->ptr, sizeof(VALUE),
+			 a1->ptr, a1->shape[0] );
+  } else {
+    v = na_make_object(NA_ROBJ, a1->rank, a1->shape, CLASS_OF(self));
+    GetNArray(v,a2);
+    ToStrFuncs[a1->type]( a2->total,
+			  a2->ptr, sizeof(VALUE),
+			  a1->ptr, na_sizeof[a1->type] );
+  }
+  return v;
+}
+
+
+/* singleton method:
+   NArray.to_na( string, type, size1,size2,...,sizeN )
+   NArray.to_na( array )
+*/
+static VALUE
+ na_s_to_na(int argc, VALUE *argv, VALUE klass)
+{
+  if (argc < 1) {
+    rb_raise(rb_eArgError, "Argument is required");
+  }
+  if (TYPE(argv[0]) == T_STRING) {
+    return na_str_to_na(argc-1,argv+1,argv[0]);
+  }
+  if (argc > 1) {
+    rb_raise(rb_eArgError, "Only one array argument must be provided");
+  }
+  if (TYPE(argv[0]) == T_ARRAY) {
+    return na_ary_to_nary( argv[0], klass );
+  }
+  if (NA_IsNArray(argv[0])) {
+    return argv[0];
+  }
+  rb_raise(rb_eTypeError, "Argument must be Array or String (or NArray)");
+  return Qnil;
+}
+
+
+/* singleton method:
+   NArray[object]
+*/
+static VALUE
+ na_s_bracket(int argc, VALUE *argv, VALUE klass)
+{
+  VALUE v = rb_ary_new4(argc, argv);
+  return na_ary_to_nary( v, klass );
+}
+
+
+/* method: coerce(other) */
+static VALUE na_coerce(VALUE self, VALUE other)
+{
+  struct NARRAY *a1;
+
+  GetNArray(self,a1);
+  return rb_assoc_new( na_cast_object(other,a1->type), self );
+}
+
+
+/* method: inspect() -- returns the inspect of the array */
+static VALUE
+ na_inspect(VALUE self)
+{
+  VALUE str;
+  struct NARRAY *ary;
+  int i;
+  char buf[256];
+  const char *classname;
+  const char *ref = "%s(ref).%s(%i";
+  const char *org = "%s.%s(%i";
+
+  GetNArray(self,ary);
+  classname = rb_class2name(CLASS_OF(self));
+
+  str = rb_str_new(0,0);
+  if (ary->rank < 1) {
+    sprintf(buf, "%s.%s(): []", classname, na_typestring[ary->type]);
+    rb_str_cat(str,buf,strlen(buf));
+  }
+  else {
+    sprintf(buf, (ary->ref==Qnil) ? org:ref,
+	    classname, na_typestring[ary->type], ary->shape[0]);
+    rb_str_cat(str,buf,strlen(buf));
+    for (i=1; i<ary->rank; ++i) {
+      sprintf(buf,",%i",ary->shape[i]);
+      rb_str_cat(str,buf,strlen(buf));
+    }
+    rb_str_cat(str,")",1);
+    rb_str_cat(str,": \n",3);
+    rb_str_concat(str, na_make_inspect(self));
+  }
+  return str;
+}
+
+
+/* private function for reshape */
+static void
+ na_reshape(int argc, VALUE *argv, struct NARRAY *ary, VALUE self)
+{
+  int *shape, class_dim;
+  int  i, total=1, unfixed=-1;
+  VALUE klass;
+
+  if (ary->total==0)
+    rb_raise(rb_eRuntimeError, "cannot reshape empty array");
+
+  klass = CLASS_OF(self);
+  class_dim = NUM2INT(rb_const_get(klass, na_id_class_dim));
+
+  if (argc == 0) {  /* trim ranks of size=1 */
+    shape = ALLOCA_N(int,ary->rank+1);
+    for (i=0; i<class_dim; ++i) shape[i]=0;
+    for (   ; i<ary->rank; ++i) shape[i]=1;
+    na_shrink_rank( self, class_dim, shape );
+    if (ary->rank==0) ary->rank=1;
+    return;
+  }
+
+  /* get shape from argument */
+  shape = ALLOC_N(int,argc);
+  for (i=0; i<argc; ++i)
+    switch(TYPE(argv[i])) {
+    case T_FIXNUM:
+      total *= shape[i] = NUM2INT(argv[i]);
+      break;
+    case T_TRUE:
+      unfixed = i;
+      break;
+    default:
+      rb_raise(rb_eArgError,"illegal type");
+    }
+
+  if (unfixed>=0) {
+    if (ary->total % total != 0)
+      rb_raise(rb_eArgError, "Total size size must be divisor");
+    shape[unfixed] = ary->total / total;
+  }
+  else if (total != ary->total)
+    rb_raise(rb_eArgError, "Total size must be same");
+
+  /* exchange */
+  xfree(ary->shape);
+  ary->shape = shape;
+  ary->rank = argc;
+}
+
+
+/* method: reshape!(size1,size2,...,sizeN) */
+static VALUE
+ na_reshape_bang(int argc, VALUE *argv, VALUE self)
+{
+  struct NARRAY *ary;
+
+  GetNArray(self,ary);
+  na_reshape(argc, argv, ary, self);
+  return self;
+}
+
+
+/* method: reshape(size1,size2,...,sizeN) */
+static VALUE
+ na_reshape_ref(int argc, VALUE *argv, VALUE self)
+{
+  struct NARRAY *ary;
+
+  GetNArray(self,ary);
+  ary = na_ref_alloc_struct(self);
+  na_reshape(argc, argv, ary, self);
+  return na_wrap_struct(ary,self);
+}
+
+
+/* method: flatten! */
+static VALUE
+ na_flatten_bang(VALUE self)
+{
+  struct NARRAY *ary;
+
+  GetNArray(self,ary);
+  if (ary->total==0 || ary->rank==0)
+    rb_raise(rb_eRuntimeError, "cannot reshape empty array");
+  ary->shape[0] = ary->total;
+  ary->rank = 1;
+  return self;
+}
+
+
+/* method: flatten */
+static VALUE
+ na_flatten_ref(VALUE self)
+{
+  return na_flatten_bang( na_wrap_struct( na_ref_alloc_struct(self), self ));
+}
+
+
+/* private function for newdim */
+static void
+ na_newdim(int argc, VALUE *argv, struct NARRAY *ary)
+{
+  int *shape, *count;
+  int  i, j;
+
+  if (argc==0)
+    rb_raise(rb_eArgError, "Argument required");
+  if (ary->total==0)
+    rb_raise(rb_eRuntimeError, "cannot extend empty array");
+
+  /* count new rank */
+  count = ALLOCA_N(int,ary->rank+1);
+  for (i=0; i<=ary->rank; ++i)
+    count[i]=0;
+  for (i=0; i<argc; ++i) {
+    j = NUM2INT(argv[i]);
+    if (j<0)	/* negative rank : -1=>append after last rank */
+      j += ary->rank+1;
+    if (j<0 || j>ary->rank)  /* range check */
+      rb_raise(rb_eArgError, "rank out of range");
+    ++count[j];
+  }
+  /* extend shape shape */
+  shape = ALLOC_N(int,ary->rank+argc);
+  for (j=i=0; i<ary->rank; ++i) {
+    while (count[i]-->0) shape[j++] = 1;
+    shape[j++] = ary->shape[i];
+  }
+  while (count[i]-->0) shape[j++] = 1;
+
+  /* exchange shape */
+  xfree(ary->shape);
+  ary->shape = shape;
+  ary->rank += argc;
+}
+
+
+/* method: newdim!(size1,size2,...,sizeN) */
+static VALUE
+ na_newdim_bang(int argc, VALUE *argv, VALUE self)
+{
+  struct NARRAY *ary;
+
+  GetNArray(self,ary);
+  na_newdim(argc, argv, ary);
+  return self;
+}
+
+
+/* method: newdim(size1,size2,...,sizeN) */
+VALUE
+ na_newdim_ref(int argc, VALUE *argv, VALUE self)
+{
+  struct NARRAY *ary;
+
+  GetNArray(self,ary);
+  ary = na_ref_alloc_struct(self);
+  na_newdim(argc, argv, ary);
+  return na_wrap_struct(ary,self);
+}
+
+
+/* method: fill!(val) */
+VALUE na_fill(VALUE self, volatile VALUE val)
+{
+  struct NARRAY *a1, *a2;
+
+  GetNArray(self,a1);
+  val = na_cast_unless_narray(val,a1->type);
+  GetNArray(val,a2);
+
+  if (a2->total != 1)
+    rb_raise(rb_eArgError, "single-element argument required");
+
+  SetFuncs[a1->type][a2->type]( a1->total,
+				a1->ptr, na_sizeof[a1->type],
+				a2->ptr, 0 );
+  return self;
+}
+
+
+/* method: indgen!([start,[step]]) */
+VALUE
+ na_indgen(int argc, VALUE *argv, VALUE self)
+{
+  int start=0, step=1;
+  struct NARRAY *ary;
+
+  if (argc>0) {
+    start = NUM2INT(argv[0]);
+    if (argc==2)
+      step = NUM2INT(argv[1]);
+    else
+      if (argc>2)
+	rb_raise(rb_eArgError, "wrong # of arguments (%d for <= 2)", argc);
+  }
+
+  GetNArray(self,ary);
+  IndGenFuncs[ary->type]( ary->total,
+			  ary->ptr, na_sizeof[ary->type],
+			  start, step );
+  return self;
+}
+
+
+/* method:  where2
+   idx_true, idx_false = narray.where2 */
+static VALUE
+ na_where2(volatile VALUE obj)
+{
+  VALUE v1, v0;
+  int  n, i, n1, n0;
+  char *c;
+  int32_t *idx1, *idx0;
+  struct NARRAY *ary, *a1, *a0; /* a1=true, a0=false */
+
+  GetNArray(obj,ary);
+  /* Convert to NA_BYTE by calling "obj.ne(0)", if needed */
+  if(ary->type != NA_BYTE) {
+    obj = rb_funcall(obj, na_id_ne, 1, INT2FIX(0));
+    GetNArray(obj,ary);
+  }
+  n = ary->total;
+
+  /* Count true */
+  c = ary->ptr;
+  n1 = 0;
+  for (i=0; i<n; ++i)
+    if (*(c++)) ++n1;
+
+  n0 = n-n1;
+
+  /* partially true and false */
+  v1 = na_make_object( NA_LINT, 1, &n1, cNArray );
+  GetNArray(v1,a1);
+  idx1 = (int32_t*) a1->ptr;
+  v0 = na_make_object( NA_LINT, 1, &n0, cNArray );
+  GetNArray(v0,a0);
+  idx0 = (int32_t*) a0->ptr;
+
+  /* Get Indices */
+  c = ary->ptr;
+  for ( i=0; i<n; ++i ) {
+    if (*(c++))
+      *(idx1++) = i;
+    else
+      *(idx0++) = i;
+  }
+
+  return rb_assoc_new( v1, v0 );
+}
+
+
+/* method:  where
+   idx_true = narray.where */
+static VALUE
+ na_where(VALUE self)
+{
+  return RARRAY_PTR( na_where2(self) )[0];
+}
+
+
+/* iterator: each() */
+static VALUE
+ na_each(VALUE obj)
+{
+  int i, sz;
+  VALUE v;
+  struct NARRAY *ary;
+  char *p;
+  void (*func)();
+
+  if (rb_block_given_p()) {
+    GetNArray(obj,ary);
+
+    p  = ary->ptr;
+    sz = na_sizeof[ary->type];
+    func = SetFuncs[NA_ROBJ][ary->type];
+
+    for ( i=ary->total; i-->0; ) {
+      (*func)( 1, &v, 0, p, 0 );
+      rb_yield(v);
+      p += sz;
+    }
+    return Qnil;
+  } else {
+    return rb_funcall(obj, rb_intern("to_enum"), 0);
+  }
+}
+
+
+/* iterator: collect() */
+static VALUE
+ na_collect(VALUE obj1)
+{
+  int i, sz;
+  VALUE v, obj2;
+  struct NARRAY *a1, *a2;
+  char *p1, *p2;
+  void (*get)(), (*set)();
+
+  GetNArray(obj1,a1);
+  obj2 = na_make_object(a1->type, a1->rank, a1->shape, CLASS_OF(obj1));
+  GetNArray(obj2,a2);
+
+  p1  = a1->ptr;
+  p2  = a2->ptr;
+  sz  = na_sizeof[a1->type];
+  get = SetFuncs[NA_ROBJ][a1->type];
+  set = SetFuncs[a1->type][NA_ROBJ];
+
+  for ( i=a1->total; i-->0; ) {
+    (*get)( 1, &v, 0, p1, 0 );
+    v = rb_yield(v);
+    (*set)( 1, p2, 0, &v, 0 );
+    p1 += sz;
+    p2 += sz;
+  }
+  return obj2;
+}
+
+
+/* iterator: collect!() */
+static VALUE
+ na_collect_bang(VALUE self)
+{
+  int i, sz;
+  VALUE v;
+  struct NARRAY *a1;
+  char *p1;
+  void (*get)(), (*set)();
+
+  GetNArray(self,a1);
+
+  p1  = a1->ptr;
+  sz  = na_sizeof[a1->type];
+  get = SetFuncs[NA_ROBJ][a1->type];
+  set = SetFuncs[a1->type][NA_ROBJ];
+
+  for ( i=a1->total; i-->0; ) {
+    (*get)( 1, &v, 0, p1, 0 );
+    v = rb_yield(v);
+    (*set)( 1, p1, 0, &v, 0 );
+    p1 += sz;
+  }
+  return self;
+}
+
+
+/* initialization of NArray Class */
+void
+ Init_narray()
+{
+    ID id_Complex = rb_intern("Complex");
+
+    if (!rb_const_defined( rb_cObject, id_Complex)) {
+	/* require Complex class */
+	rb_require("complex");
+    }
+    cComplex = rb_const_get( rb_cObject, rb_intern("Complex") );
+
+    /* define NArray class */
+    cNArray = rb_define_class("NArray",rb_cObject);
+
+    /* class methods */
+    rb_define_singleton_method(cNArray,"new",na_s_new,-1);
+    rb_define_singleton_method(cNArray,"byte",na_s_new_byte,-1);
+    rb_define_singleton_method(cNArray,"sint",na_s_new_sint,-1);
+    rb_define_singleton_method(cNArray,"lint",na_s_new_int,-1);
+    rb_define_singleton_method(cNArray,"int", na_s_new_int,-1);
+    rb_define_singleton_method(cNArray,"sfloat",na_s_new_sfloat,-1);
+    rb_define_singleton_method(cNArray,"dfloat",na_s_new_float,-1);
+    rb_define_singleton_method(cNArray,"float", na_s_new_float,-1);
+    rb_define_singleton_method(cNArray,"scomplex",na_s_new_scomplex,-1);
+    rb_define_singleton_method(cNArray,"dcomplex",na_s_new_complex,-1);
+    rb_define_singleton_method(cNArray,"complex", na_s_new_complex,-1);
+    rb_define_singleton_method(cNArray,"object",na_s_new_object,-1);
+
+    rb_define_singleton_method(cNArray,"to_na",na_s_to_na,-1);
+    rb_define_singleton_method(cNArray,"to_narray",na_s_to_na,-1);
+    rb_define_singleton_method(cNArray,"[]",na_s_bracket,-1);
+
+    /* methods */
+    rb_define_method(cNArray, "shape", na_shape,0);
+    rb_define_alias(cNArray,  "sizes","shape");
+    rb_define_method(cNArray, "size", na_size,0);
+    rb_define_alias(cNArray,  "total","size");
+    rb_define_alias(cNArray,  "length","size");
+    rb_define_method(cNArray, "rank", na_rank,0);
+    rb_define_alias(cNArray,  "dim","rank");
+    rb_define_alias(cNArray,  "dimension","rank");
+    rb_define_method(cNArray, "typecode", na_typecode,0);
+    rb_define_method(cNArray, "element_size", na_element_size,0);
+    rb_define_method(cNArray, "empty?", na_is_empty,0);
+    rb_define_method(cNArray, "clone", na_clone,0);
+    rb_define_alias(cNArray,  "dup","clone");
+    rb_define_method(cNArray, "inspect", na_inspect,0);
+    rb_define_method(cNArray, "coerce", na_coerce,1);
+    rb_define_method(cNArray, "reshape", na_reshape_ref,-1);
+    rb_define_method(cNArray, "reshape!", na_reshape_bang,-1);
+    rb_define_alias(cNArray,  "shape=","reshape!");
+    rb_define_method(cNArray, "newdim", na_newdim_ref,-1);
+    rb_define_alias(cNArray,  "newrank","newdim");
+    rb_define_method(cNArray, "newdim!", na_newdim_bang,-1);
+    rb_define_alias(cNArray,  "newdim=","newdim!");
+    rb_define_alias(cNArray,  "newrank!","newdim!");
+    rb_define_alias(cNArray,  "newrank=","newdim!");
+    rb_define_method(cNArray, "flatten", na_flatten_ref,0);
+    rb_define_method(cNArray, "flatten!", na_flatten_bang,0);
+    rb_define_method(cNArray, "fill!", na_fill,1);
+    rb_define_alias(cNArray,  "fill","fill!");
+    rb_define_method(cNArray, "indgen!", na_indgen,-1);
+    rb_define_alias(cNArray,  "indgen","indgen!");
+    rb_define_method(cNArray, "where", na_where, 0);
+    rb_define_method(cNArray, "where2", na_where2, 0);
+    rb_define_method(cNArray, "each", na_each,0);
+    rb_define_method(cNArray, "collect", na_collect,0);
+    rb_define_method(cNArray, "collect!", na_collect_bang,0);
+    rb_define_alias(cNArray, "map", "collect");
+    rb_define_alias(cNArray, "map!", "collect!");
+    rb_define_method(cNArray, "to_s", na_to_s, 0);
+    rb_define_method(cNArray, "to_f", na_to_float, 0);
+    rb_define_method(cNArray, "to_i", na_to_integer, 0);
+    rb_define_method(cNArray, "to_type", na_to_type, 1);
+    rb_define_method(cNArray, "to_binary", na_to_binary, 0);
+    rb_define_method(cNArray, "to_type_as_binary", na_to_type_as_binary, 1);
+    rb_define_method(cNArray, "to_string", na_to_string, 0);
+
+    rb_define_const(cNArray, "NARRAY_VERSION", rb_str_new2(NARRAY_VERSION));
+    rb_define_const(cNArray, "BYTE", INT2FIX(NA_BYTE));
+    rb_define_const(cNArray, "SINT", INT2FIX(NA_SINT));
+    rb_define_const(cNArray, "LINT", INT2FIX(NA_LINT));
+    rb_define_const(cNArray, "INT",  INT2FIX(NA_LINT));
+    rb_define_const(cNArray, "SFLOAT", INT2FIX(NA_SFLOAT));
+    rb_define_const(cNArray, "DFLOAT", INT2FIX(NA_DFLOAT));
+    rb_define_const(cNArray, "FLOAT",  INT2FIX(NA_DFLOAT));
+    rb_define_const(cNArray, "SCOMPLEX", INT2FIX(NA_SCOMPLEX));
+    rb_define_const(cNArray, "DCOMPLEX", INT2FIX(NA_DCOMPLEX));
+    rb_define_const(cNArray, "COMPLEX",  INT2FIX(NA_DCOMPLEX));
+    rb_define_const(cNArray, "ROBJ", INT2FIX(NA_ROBJ));
+    rb_define_const(cNArray, "OBJECT", INT2FIX(NA_ROBJ));
+    rb_define_const(cNArray, "NONE", INT2FIX(NA_NONE));
+    rb_define_const(cNArray, "CLASS_DIMENSION", INT2FIX(0));
+#ifdef WORDS_BIGENDIAN
+    rb_define_const(cNArray, "ENDIAN",  INT2FIX(1));
+#else
+#ifdef DYNAMIC_ENDIAN	/* not supported yet */
+    rb_define_const(cNArray, "ENDIAN",  INT2FIX(-1));
+#else  /* LITTLE_ENDIAN */
+    rb_define_const(cNArray, "ENDIAN",  INT2FIX(0));
+#endif
+#endif
+    /* Reference */
+    rb_define_singleton_method(cNArray, "refer", na_s_refer,1);
+    rb_define_singleton_method(cNArray, "ref", na_s_refer,1);
+    rb_define_method(cNArray, "refer", na_refer,0);
+    rb_define_method(cNArray, "original", na_original,0);
+
+    Init_na_array();
+    Init_na_index();
+    Init_nmath();
+    Init_na_funcs();
+    Init_na_random();
+
+    cNArrayScalar = rb_define_class("NArrayScalar", cNArray);
+
+    na_id_beg  	= rb_intern("begin");
+    na_id_end  	= rb_intern("end");
+    na_id_exclude_end	= rb_intern("exclude_end?");
+    na_id_real 	= rb_intern("real");
+    na_id_imag	= rb_intern("imag");
+    na_id_new  	= rb_intern("new");
+    na_id_to_i 	= rb_intern("to_i");
+    na_id_usec 	= rb_intern("usec");
+    na_id_now 	= rb_intern("now");
+    na_id_compare = rb_intern("<=>");
+    na_id_ne    = rb_intern("ne");
+    na_id_and   = rb_intern("&&");
+    na_id_or    = rb_intern("||");
+    na_id_minus = rb_intern("-@");
+    na_id_abs   = rb_intern("abs");
+    na_id_power = rb_intern("**");
+    na_id_add   = rb_intern("+");
+    na_id_sbt   = rb_intern("-");
+    na_id_mul   = rb_intern("*");
+    na_id_div   = rb_intern("/");
+    na_id_mod   = rb_intern("%");
+    na_id_coerce_rev = rb_intern("coerce_rev");
+    na_id_Complex = rb_intern("Complex");
+
+    na_id_class_dim = rb_intern("CLASS_DIMENSION");
+
+    Init_na_linalg();
+
+    /* NArray extention script */
+    rb_require("narray_ext.rb");
+}
diff --git a/app/server/vendor/narray-0.6.1.1/narray.def b/app/server/vendor/narray-0.6.1.1/narray.def
new file mode 100755
index 0000000..025fe00
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/narray.def
@@ -0,0 +1,29 @@
+EXPORTS
+Init_narray
+na_sizeof
+na_make_object
+na_make_scalar
+na_make_empty
+na_get_typecode
+na_clear_data
+na_clone
+na_fill
+na_copy_nary
+na_to_array
+na_ary_to_nary
+na_object_type
+na_cast_object
+na_cast_unless_narray
+na_cast_unless_array
+na_upcast_object
+na_dup_w_type
+na_change_type
+na_upcast_type
+na_to_narray
+na_aset
+na_aref
+na_slice
+na_count_true
+na_count_false
+na_aref_mask
+na_aset_mask
diff --git a/app/server/vendor/narray-0.6.1.1/narray.gemspec b/app/server/vendor/narray-0.6.1.1/narray.gemspec
new file mode 100755
index 0000000..f0bcb79
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/narray.gemspec
@@ -0,0 +1,69 @@
+open("src/narray.h") do |f|
+  f.each_line do |l|
+    if /NARRAY_VERSION "([\d.]+)"/ =~ l
+      NARRAY_VERSION = $1
+      break
+    end
+  end
+end
+
+GEMSPEC = Gem::Specification.new do |s|
+  s.name = "narray"
+  s.version = NARRAY_VERSION
+
+  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+  s.authors = ["Masahiro Tanaka"]
+  s.date = Time.now.strftime("%F")
+  s.description = "Numerical N-dimensional Array class"
+  s.email = "masa16.tanaka at gmail.com"
+  s.extensions = ["src/extconf.rb"]
+  s.files = %w[
+ChangeLog
+MANIFEST
+README.md
+README.ja.md
+SPEC.en.txt
+SPEC.ja.txt
+src/depend
+src/extconf.rb
+src/mkmath.rb
+src/mknafunc.rb
+src/mkop.rb
+src/na_array.c
+src/na_func.c
+src/na_index.c
+src/na_linalg.c
+src/na_random.c
+src/narray.c
+src/narray.def
+src/narray.h
+src/narray_local.h
+src/lib/narray_ext.rb
+src/lib/nmatrix.rb
+]
+  s.rdoc_options = %w[
+    --title NArray
+    --main NArray
+    --exclude mk.*
+    --exclude extconf\.rb
+    --exclude src/.*\.h
+    --exclude src/lib/
+    --exclude .*\.o
+    --exclude narray\.so
+    --exclude libnarray\.*
+  ]
+  s.homepage = "http://masa16.github.io/narray/"
+  s.require_paths = ["."]
+  s.rubygems_version = "1.8.10"
+  s.summary = "N-dimensional Numerical Array class for Ruby"
+  s.license = "Ruby"
+
+  if s.respond_to? :specification_version then
+    s.specification_version = 2
+
+    if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+    else
+    end
+  else
+  end
+end
diff --git a/app/server/vendor/narray-0.6.1.1/narray.h b/app/server/vendor/narray-0.6.1.1/narray.h
new file mode 100755
index 0000000..eaa860f
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/narray.h
@@ -0,0 +1,184 @@
+/*
+  narray.h
+  Numerical Array Extention for Ruby
+    (C) Copyright 1999-2011 by Masahiro TANAKA
+
+  This program is free software.
+  You can distribute/modify this program
+  under the same terms as Ruby itself.
+  NO WARRANTY.
+*/
+#ifndef NARRAY_H
+#define NARRAY_H
+
+#include <math.h>
+
+#include "narray_config.h"
+
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#define NARRAY_VERSION "0.6.1.1"
+#define NARRAY_VERSION_CODE 611
+
+/*
+  Data types used in NArray :
+  Please modify these types if your system has any different type.
+*/
+
+
+/* NA_BYTE : unsigned 8-bit integer */
+#ifndef HAVE_U_INT8_T
+# ifdef HAVE_UINT8_T
+typedef uint8_t			u_int8_t;
+# else
+typedef unsigned char		u_int8_t;
+# endif
+#endif
+
+#ifndef HAVE_INT16_T
+# if SIZEOF_SHORT == 2
+typedef short                  int16_t;  /* NA_SINT */
+# else
+---->> Please define int16_t manually because sizeof(short) != 2. <<----
+# endif
+#endif /* HAVE_INT16_T */
+
+#ifndef HAVE_INT32_T
+# if SIZEOF_LONG == 4
+typedef long                   int32_t;  /* NA_LINT */
+# else
+#  if SIZEOF_INT == 4
+typedef int                    int32_t;  /* NA_LINT */
+#  else
+---->> Please define int32_t manually because sizeof(long) != 4. <<----
+#  endif
+# endif
+#endif /* HAVE_INT32_T */
+
+/* unsigned 32-bit integer */
+#ifndef HAVE_U_INT32_T
+# ifdef HAVE_UINT32_T
+typedef uint32_t			u_int32_t;
+# else
+#  if SIZEOF_LONG == 4
+typedef unsigned long                   u_int32_t;
+#  else
+#   if SIZEOF_INT == 4
+typedef unsigned int                    u_int32_t;
+#   else
+---->> Please define u_int32_t manually because sizeof(long) != 4. <<----
+#   endif
+#  endif
+# endif
+#endif /* HAVE_U_INT32_T */
+
+typedef struct { float r,i; }  scomplex;
+typedef struct { double r,i; } dcomplex;
+
+enum NArray_Types {
+  NA_NONE,
+  NA_BYTE,	/* 1 */
+  NA_SINT,	/* 2 */
+  NA_LINT,	/* 3 */
+  NA_SFLOAT,	/* 4 */
+  NA_DFLOAT,	/* 5 */
+  NA_SCOMPLEX,	/* 6 */
+  NA_DCOMPLEX,	/* 7 */
+  NA_ROBJ,	/* 8 */
+  NA_NTYPES	/* 9 */
+};
+
+/* struct for Numerical Array */
+struct NARRAY {
+  int    rank;	  /* # of dimension */
+  int    total;	  /* # of total element */
+  int    type;	  /* data type */
+  int   *shape;
+  char  *ptr;	  /* pointer to data */
+  VALUE  ref;	  /* NArray object wrapping this structure */
+};
+
+#ifndef NARRAY_C
+extern VALUE cNArray;
+
+extern const int na_sizeof[NA_NTYPES+1];
+#endif
+
+#define GetNArray(obj,var)  Data_Get_Struct(obj, struct NARRAY, var)
+#define IsNArray(obj) (rb_obj_is_kind_of(obj,cNArray)==Qtrue)
+
+#define NA_PTR(a,p)    ((a)->ptr+(p)*na_sizeof[(a)->type])
+#define NA_STRUCT(val) ((struct NARRAY*)DATA_PTR(val))
+#define NA_PTR_TYPE(val,type) (type)(((struct NARRAY*)DATA_PTR(val))->ptr)
+#define NA_RANK(val)   (((struct NARRAY*)DATA_PTR(val))->rank)
+#define NA_TYPE(val)   (((struct NARRAY*)DATA_PTR(val))->type)
+#define NA_TOTAL(val)  (((struct NARRAY*)DATA_PTR(val))->total)
+#define NA_SHAPE0(val) (((struct NARRAY*)DATA_PTR(val))->shape[0])
+#define NA_SHAPE1(val) (((struct NARRAY*)DATA_PTR(val))->shape[1])
+
+#define NA_IsNArray(obj) \
+  (rb_obj_is_kind_of(obj,cNArray)==Qtrue)
+#define NA_IsArray(obj) \
+  (TYPE(obj)==T_ARRAY || rb_obj_is_kind_of(obj,cNArray)==Qtrue)
+#define NA_IsROBJ(d) ((d)->type==NA_ROBJ)
+#define NA_IsINTEGER(a) \
+  ((a)->type==NA_BYTE || (a)->type==NA_SINT || (a)->type==NA_LINT )
+#define NA_IsCOMPLEX(a) \
+  ((a)->type==NA_SCOMPLEX || (a)->type==NA_DCOMPLEX)
+#define NA_MAX(a,b) (((a)>(b))?(a):(b))
+#define NA_SWAP(a,b,tmp) {(tmp)=(a);(a)=(b);(b)=(tmp);}
+
+#define na_class_dim(klass) NUM2INT(rb_const_get(klass, na_id_class_dim))
+
+#define NUM2REAL(v)  NUM2DBL( rb_funcall((v),na_id_real,0) )
+#define NUM2IMAG(v)  NUM2DBL( rb_funcall((v),na_id_imag,0) )
+
+#define NA_ALLOC_SLICE(slc,nc,shp,np) \
+{ slc = (struct slice*)xmalloc( sizeof(struct slice)*(nc) + \
+				sizeof(int)*(np) );\
+  shp = (int*)&( (slc)[nc] ); }
+
+
+/* Function Prototypes */
+
+/* narray.c */
+VALUE na_make_object(int type, int rank, int *shape, VALUE klass);
+VALUE na_make_scalar(VALUE obj, int type);
+VALUE na_make_empty(int type, VALUE klass);
+int   na_get_typecode(VALUE v);
+void  na_clear_data(struct NARRAY *ary);
+VALUE na_clone(VALUE self);
+VALUE na_fill(VALUE self, volatile VALUE obj);
+void  na_copy_nary(struct NARRAY *dst, struct NARRAY *src);
+
+/* na_array.c */
+VALUE na_to_array(VALUE obj);
+VALUE na_make_inspect(VALUE self);
+VALUE na_ary_to_nary(VALUE ary, VALUE klass);
+int   na_object_type(VALUE v);
+
+VALUE na_cast_object(VALUE obj, int type);
+VALUE na_cast_unless_narray(VALUE obj, int type);
+VALUE na_cast_unless_array(VALUE obj, int type);
+VALUE na_upcast_object(VALUE obj, int type);
+VALUE na_dup_w_type(VALUE obj, int type);
+VALUE na_change_type(VALUE obj, int type);
+VALUE na_upcast_type(VALUE obj, int type);
+VALUE na_to_narray(VALUE obj);
+
+/* na_index.c */
+VALUE na_aset(int argc, VALUE *argv, VALUE self);
+VALUE na_aref(int argc, VALUE *argv, VALUE self);
+VALUE na_slice(int argc, VALUE *argv, VALUE self);
+VALUE na_count_true(VALUE self);
+VALUE na_count_false(VALUE self);
+VALUE na_aref_mask(VALUE self, VALUE mask);
+void  na_aset_mask(VALUE self, VALUE mask, VALUE v);
+
+#endif /* ifndef NARRAY_H */
diff --git a/app/server/vendor/narray-0.6.1.1/narray_local.h b/app/server/vendor/narray-0.6.1.1/narray_local.h
new file mode 100755
index 0000000..5ccc521
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/narray_local.h
@@ -0,0 +1,218 @@
+/*
+  narray_local.h
+  Numerical Array Extention for Ruby
+    (C) Copyright 1999-2008 by Masahiro TANAKA
+
+  This program is free software.
+  You can distribute/modify this program
+  under the same terms as Ruby itself.
+  NO WARRANTY.
+*/
+
+typedef int32_t na_index_t;
+
+struct slice {
+  char *p;   	/* pointer to data		--- used in loop */
+  int n;       	/* n of indices of this rank */
+  int pstep;   	/* = step * stride * elmsz	--- set in na_init_slice */ 
+  int pbeg;    	/* = beg * stride * elmsz	--- set in na_init_slice */
+  int stride;  	/* = shape[0]*shape[1]*...*shape[r-1]
+						--- set in na_init_slice */
+  int step;
+  int beg;
+  na_index_t *idx;    	/* NULL if normal step */
+};
+
+typedef void (*na_setfunc_t[NA_NTYPES][NA_NTYPES]) ();
+typedef void (*na_func_t[NA_NTYPES]) ();
+typedef void (*na_ufunc_t[NA_NTYPES]) ();
+typedef void (*na_bifunc_t[NA_NTYPES]) ();
+typedef void (*na_mathfunc_t[NA_NTYPES]) ();
+typedef int  (*na_sortfunc_t[NA_NTYPES]) (const void *, const void *);
+
+/* function arrays */
+extern na_setfunc_t SetFuncs;
+extern na_ufunc_t  SwpFuncs;
+extern na_ufunc_t  H2NFuncs;
+extern na_ufunc_t  H2VFuncs;
+extern na_ufunc_t  NegFuncs;
+extern na_ufunc_t  RcpFuncs;
+extern na_ufunc_t  AbsFuncs;
+extern na_ufunc_t  RealFuncs;
+extern na_ufunc_t  ImagFuncs;
+extern na_ufunc_t  AnglFuncs;
+extern na_ufunc_t  ImagMulFuncs;
+extern na_ufunc_t  ConjFuncs;
+extern na_ufunc_t  FloorFuncs;
+extern na_ufunc_t  CeilFuncs;
+extern na_ufunc_t  RoundFuncs;
+extern na_ufunc_t  ToStrFuncs;
+extern na_ufunc_t  InspFuncs;
+extern na_ufunc_t  IndGenFuncs;
+extern na_ufunc_t  AddUFuncs;
+extern na_ufunc_t  SbtUFuncs;
+extern na_ufunc_t  MulUFuncs;
+extern na_ufunc_t  DivUFuncs;
+extern na_ufunc_t  ModUFuncs;
+extern na_bifunc_t AddBFuncs;
+extern na_bifunc_t SbtBFuncs;
+extern na_bifunc_t MulBFuncs;
+extern na_bifunc_t DivBFuncs;
+extern na_bifunc_t MulAddFuncs;
+extern na_bifunc_t MulSbtFuncs;
+extern na_bifunc_t ModBFuncs;
+extern na_bifunc_t BAnFuncs;
+extern na_bifunc_t BOrFuncs;
+extern na_bifunc_t BXoFuncs;
+extern na_ufunc_t  BRvFuncs;
+extern na_bifunc_t ImgSetFuncs;
+extern na_setfunc_t PowFuncs;
+extern na_bifunc_t atan2Funcs;
+extern na_bifunc_t CmpFuncs;
+extern na_bifunc_t EqlFuncs;
+extern na_ufunc_t  AndFuncs;
+extern na_ufunc_t  Or_Funcs;
+extern na_ufunc_t  XorFuncs;
+extern na_ufunc_t  NotFuncs;
+extern na_ufunc_t  MinFuncs;
+extern na_ufunc_t  MaxFuncs;
+extern na_sortfunc_t SortFuncs;
+extern na_sortfunc_t SortIdxFuncs;
+extern na_bifunc_t RefMaskFuncs;
+extern na_bifunc_t SetMaskFuncs;
+
+/* variables */
+
+extern VALUE rb_mNMath;
+extern ID na_id_beg, na_id_end, na_id_exclude_end;
+extern ID na_id_minus, na_id_abs, na_id_power;
+extern ID na_id_compare, na_id_and, na_id_or;
+extern ID na_id_equal;
+extern ID na_id_class_dim;
+extern ID na_id_add, na_id_sbt, na_id_mul, na_id_div, na_id_mod;
+extern ID na_id_real, na_id_imag;
+extern ID na_id_coerce_rev;
+extern ID na_id_new;
+extern ID na_id_Complex;
+
+extern const int na_upcast[NA_NTYPES][NA_NTYPES];
+extern const int na_no_cast[NA_NTYPES];
+extern const int na_cast_real[NA_NTYPES];
+extern const int na_cast_comp[NA_NTYPES];
+extern const int na_cast_round[NA_NTYPES];
+extern const int na_cast_byte[NA_NTYPES];
+
+extern const char *na_typestring[];
+
+extern VALUE cNArrayScalar, cComplex;
+
+/* narray.c */
+VALUE na_newdim_ref(int argc, VALUE *argv, VALUE self);
+
+/* na_func.c */
+int  na_max3(int a, int b, int c);
+void na_shape_max3(int ndim, int *max_shp, int *shp1, int *shp2, int *shp3);
+void na_shape_copy( int ndim, int *shape, struct NARRAY *a );
+
+void na_init_slice(struct slice *s, int rank, int *shape, int elmsz);
+void na_set_slice_1obj(int ndim, struct slice *slc, int *shape);
+int  na_set_slice_3obj( int ndim,
+			struct slice *s1, struct slice *s2, struct slice *s3,
+			int *shp1, int *shp2, int *shp3, int *shape );
+void na_loop_general(struct NARRAY *a1, struct NARRAY *a2,
+		     struct slice *s1, struct slice *s2, void (*func)());
+void na_loop_index_ref(struct NARRAY *a1, struct NARRAY *a2,
+		       struct slice *s1, struct slice *s2, void (*func)());
+
+/* na_index.c */
+void  na_aset_slice(struct NARRAY *dst, struct NARRAY *src, struct slice *s1);
+int   na_shrink_class(int class_dim, int *shrink);
+VALUE na_shrink_rank(VALUE obj, int class_dim, int *shrink);
+
+#define rb_complex_new(r,i) \
+  rb_funcall(rb_mKernel, na_id_Complex, 2, rb_float_new(r), rb_float_new(i))
+
+
+typedef union {
+  u_int8_t b[2];
+  int16_t s;
+} na_size16_t;
+
+typedef union {
+  u_int8_t b[4];
+  int32_t  i;
+  float    f;
+} na_size32_t;
+
+typedef union {
+  u_int8_t b[8];
+  float    f[2];
+  double   d;
+} na_size64_t;
+
+typedef union {
+  u_int8_t b[16];
+  double   d[2];
+} na_size128_t;
+
+
+#define swap16(d,s) \
+(d).b[0]=(s).b[1];\
+(d).b[1]=(s).b[0];
+
+#define swap32(d,s) \
+(d).b[0]=(s).b[3];\
+(d).b[1]=(s).b[2];\
+(d).b[2]=(s).b[1];\
+(d).b[3]=(s).b[0];
+
+#define swap64(d,s) \
+(d).b[0]=(s).b[7];\
+(d).b[1]=(s).b[6];\
+(d).b[2]=(s).b[5];\
+(d).b[3]=(s).b[4];\
+(d).b[4]=(s).b[3];\
+(d).b[5]=(s).b[2];\
+(d).b[6]=(s).b[1];\
+(d).b[7]=(s).b[0];
+
+#define swap64c(d,s) \
+(d).b[0]=(s).b[3];\
+(d).b[1]=(s).b[2];\
+(d).b[2]=(s).b[1];\
+(d).b[3]=(s).b[0];\
+(d).b[4]=(s).b[7];\
+(d).b[5]=(s).b[6];\
+(d).b[6]=(s).b[5];\
+(d).b[7]=(s).b[4];
+
+#define swap128c(d,s) \
+(d).b[0]=(s).b[7];\
+(d).b[1]=(s).b[6];\
+(d).b[2]=(s).b[5];\
+(d).b[3]=(s).b[4];\
+(d).b[4]=(s).b[3];\
+(d).b[5]=(s).b[2];\
+(d).b[6]=(s).b[1];\
+(d).b[7]=(s).b[0];\
+(d).b[8]=(s).b[15];\
+(d).b[9]=(s).b[14];\
+(d).b[10]=(s).b[13];\
+(d).b[11]=(s).b[12];\
+(d).b[12]=(s).b[11];\
+(d).b[13]=(s).b[10];\
+(d).b[14]=(s).b[9];\
+(d).b[15]=(s).b[8];
+
+#if !defined RSTRING_LEN
+#define RSTRING_LEN(a) RSTRING(a)->len
+#endif
+#if !defined RSTRING_PTR
+#define RSTRING_PTR(a) RSTRING(a)->ptr
+#endif
+#if !defined RARRAY_LEN
+#define RARRAY_LEN(a) RARRAY(a)->len
+#endif
+#if !defined RARRAY_PTR
+#define RARRAY_PTR(a) RARRAY(a)->ptr
+#endif
diff --git a/app/server/vendor/narray-0.6.1.1/test/ld.rb b/app/server/vendor/narray-0.6.1.1/test/ld.rb
new file mode 100755
index 0000000..7b0f951
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/ld.rb
@@ -0,0 +1,11 @@
+libpath = File.expand_path(File.dirname(__FILE__))+"/../lib"
+$LOAD_PATH.unshift libpath
+libpath = File.expand_path(File.dirname(__FILE__))+"/../"
+$LOAD_PATH.unshift libpath
+
+begin
+  require "rubygems"
+rescue
+end
+
+require "narray"
diff --git a/app/server/vendor/narray-0.6.1.1/test/statistics.rb b/app/server/vendor/narray-0.6.1.1/test/statistics.rb
new file mode 100755
index 0000000..9170614
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/statistics.rb
@@ -0,0 +1,22 @@
+require "narray"
+include NMath
+
+x = NArray[65, 63, 67, 64, 68, 62, 70, 66, 68, 67, 69, 71]
+y = NArray[68, 66, 68, 65, 69, 66, 68, 65, 71, 67, 68, 70]
+
+def test str, x, y=nil
+  print str," #=> "
+  p eval(str)
+end
+
+test "x",x,y
+test "y",x,y
+test "covariance(x,y)",x,y
+
+a = covariance(x,y)
+
+test "x.stddev",x
+
+test "x.sort",x
+test "x.median",x
+test "(x+y.newrank!(0)).median(0)",x,y
diff --git a/app/server/vendor/narray-0.6.1.1/test/testarray.rb b/app/server/vendor/narray-0.6.1.1/test/testarray.rb
new file mode 100755
index 0000000..19d99eb
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testarray.rb
@@ -0,0 +1,20 @@
+require 'narray'
+
+a = NArray.float(3,3).indgen
+
+p NArray[a,[100,101]]
+
+b = NArray[ [ [ 0.0, 1.0, 2.0 ], 
+              [ 3.0, 4.0, 5.0 ], 
+              [ 6.0, 7.0, 8.0 ] ],
+            [100,101] ]
+p b
+
+a = NArray.float(2,2).indgen
+
+b = NArray[ a,[a] ]
+p b
+
+b = NArray[ [ 0.0, 1.0 ], 
+            [ [ 0.0, 1.0 ] ] ]
+p b
diff --git a/app/server/vendor/narray-0.6.1.1/test/testbit.rb b/app/server/vendor/narray-0.6.1.1/test/testbit.rb
new file mode 100755
index 0000000..5a3bfab
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testbit.rb
@@ -0,0 +1,27 @@
+require "narray"
+
+a = NArray.byte(10).indgen!
+
+def test a, str
+  print str," #=>\n"
+  p eval(str)
+end
+
+test a, "a"
+test a, "a & 1"
+test a, "a & 2"
+test a, "a & -1"
+
+test a, "a | 1"
+test a, "a | 2"
+test a, "a | -1"
+
+test a, "a ^ 1"
+test a, "a ^ 2"
+test a, "a ^ -1"
+
+test a, "~a"
+
+a = NArray.int(10).indgen!
+test a, "a"
+test a, "~a"
diff --git a/app/server/vendor/narray-0.6.1.1/test/testcast.rb b/app/server/vendor/narray-0.6.1.1/test/testcast.rb
new file mode 100755
index 0000000..3cde6a0
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testcast.rb
@@ -0,0 +1,14 @@
+require 'narray'
+
+def test a,b
+  print a," #=> "
+  p b
+end
+
+a = NArray.int(3,3).indgen!
+
+test "a",a
+test "a+1.5",a+1.5
+test "1.5+a",1.5+a
+test "a+NArray[1.2,3.4,5.6]",a+NArray[1.2,3.4,5.6]
+test "a+NArray[Complex(0.5,1.5)]",a+NArray[Complex(0.5,1.5)]
diff --git a/app/server/vendor/narray-0.6.1.1/test/testcomplex.rb b/app/server/vendor/narray-0.6.1.1/test/testcomplex.rb
new file mode 100755
index 0000000..8a6346d
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testcomplex.rb
@@ -0,0 +1,35 @@
+require 'narray'
+
+def testop(a,b)
+  print "a = "; p a
+  print "b = "; p b
+  print "a+b = "; p a+b
+  print "a-b = "; p a-b
+  print "a*b = "; p a*b
+  print "a/b = "; p a/b
+  print "a**b = "; p a**b
+end
+
+a = NArray.complex(4,1).indgen!.sbt!(-1) + Complex(0,0.25)
+b = NArray.complex(1,3).indgen!.add!(-0.5).mul!(Complex(0,0.5))
+testop(a,b)
+
+# compare a/b with real-number operation
+# a = NArray(4,1).indgen!.sbt!(-1)
+# b = NArray(1,3).fill!(1)
+# c = b*b + b*b
+# p ( (a*b + 0*b)/c )
+# p ( (0*b - a*b)/c )
+
+def testimag(a)
+  print "a.real = "
+  p a.real
+  print "a.imag = "
+  p a.imag
+  print "a.angle = "
+  p a.angle
+  print "a.conj = "
+  p a.conj
+end
+
+testimag a
diff --git a/app/server/vendor/narray-0.6.1.1/test/testindex.rb b/app/server/vendor/narray-0.6.1.1/test/testindex.rb
new file mode 100755
index 0000000..f388701
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testindex.rb
@@ -0,0 +1,11 @@
+require 'narray'
+
+a = NArray.float(3,3).indgen!
+
+print "a #=> "; p a
+print "a[1, -1] #=> "; p a[1, -1]
+print "a[1, 2..0] #=> "; p a[1, 2..0]
+print "a[1...2, 0..1] #=> "; p a[1...2, 0..1]  # without rank-reduce
+print "a[true, 0..1] #=> "; p a[true, 0..1]
+print "a[0..5] #=> "; p a[0..5]
+
diff --git a/app/server/vendor/narray-0.6.1.1/test/testindexary.rb b/app/server/vendor/narray-0.6.1.1/test/testindexary.rb
new file mode 100755
index 0000000..4939e32
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testindexary.rb
@@ -0,0 +1,26 @@
+require 'narray'
+
+a = NArray.new(NArray::DFLOAT,5,5).indgen!
+print "a #=> "; p a
+
+idx = [2,0,1]
+print "\nidx #=> "
+ p idx
+
+print "\na[idx,idx]  # Index Array\n #=> "
+ p a[idx,idx]
+
+idx = NArray.to_na(idx)
+idx += 10
+print "\nidx #=> "
+ p idx
+
+print "\na[idx] #=> "
+ p a[idx]
+
+print "\na[1,[]]  # Empty Array\n #=> "
+ p a[1,[]]
+
+print "\nFollowing will fail...\n\n"
+print "a[idx,0] #=> \n"
+p a[idx,0]
diff --git a/app/server/vendor/narray-0.6.1.1/test/testindexset.rb b/app/server/vendor/narray-0.6.1.1/test/testindexset.rb
new file mode 100755
index 0000000..7bdc284
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testindexset.rb
@@ -0,0 +1,55 @@
+require 'narray'
+
+a = NArray.float(3,3).indgen!
+
+print "a #=> "; p a
+
+print "\na[[]] = []  # Do nothing \na #=> ";
+a[[]] = []; p a
+
+print "\na[1,1] = 0  # 1-element replace\na #=> ";
+b=a.dup; b[1,1] = 0
+p b
+
+print "\na[0..-1, 1] = 0  # Range replace\na #=> ";
+b=a.dup; b[0..-1, 1] = 0
+p b
+
+print "\na[1,2..0] = [100,101,102]  # Array replace\na #=> ";
+b=a.dup; b[1,2..0] = [100,101,102]
+p b
+
+print "\na[0,1] = [100,101,102]  # Specifing Starting point \na #=> ";
+b=a.dup; b[0,1] = [100,101,102]
+p b
+
+print "\na[1,0] = [[100],[101],[102]]  # Specifing Starting point \na #=> ";
+b=a.dup; b[1,0] = [[100],[101],[102]]
+p b
+
+print "\na[true,1] = [100,101,102]  # `true' means entire range\na #=> ";
+b=a.dup; b[true,1] = [100,101,102]
+p b
+
+print "\na[true,true] = [[100,101,102]] \na #=> ";
+b=a.dup; b[true,true] = [[100,101,102]]
+p b
+
+
+print "\nFollowing will fail ...\n"
+
+print "\na[true,1] = [[100,101,102]] \na #=> ";
+b=a.dup; b[true,1] = [[100,101,102]]
+p b
+
+print "\na[true,1] = [[100],[101],[102]] \na #=> ";
+b=a.dup; b[true,1] = [[100],[101],[102]]
+p b
+
+print "\na[true,true] = [100,101,102] \na #=> ";
+b=a.dup; b[true,true] = [100,101,102]
+p b
+
+print "\na[1,0] = [100,101,102] \na #=> ";
+b=a.dup; b[1,0] = [100,101,102]
+p b
diff --git a/app/server/vendor/narray-0.6.1.1/test/testmask.rb b/app/server/vendor/narray-0.6.1.1/test/testmask.rb
new file mode 100755
index 0000000..97ddb3d
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testmask.rb
@@ -0,0 +1,40 @@
+require "narray"
+
+a = NArray.byte(10)
+a[2..4] = 1
+p a.class, a.count_true, a.count_false
+
+begin
+   a = NArray.float(10)
+   a[2..4] = 1
+   p a.class, a.count_true, a.count_false
+rescue
+   print a.class," -- Exception raised as expected. The message was: ", $!,"\n"
+end
+
+#-------------------
+print "\n--- test masking (float) ---\n"
+
+a = NArray.float(5,3).indgen!
+b = (a-2)*2
+c = a.lt(b)
+p c, c.typecode
+
+p a, b, a.mask( c ), a[c]
+
+#a[c] = ( NArray.int(c.length).indgen!+100 )
+#p a
+
+a[c] = 10000
+p a
+
+#-------------------
+print "\n--- test masking (complex) ---\n"
+p a = NArray.complex(5).indgen! + Complex::I
+
+m = NArray.byte(5)
+m[true] = [0,0,1,1,0]
+
+p a[m]
+a[m] = 100.0
+p a
diff --git a/app/server/vendor/narray-0.6.1.1/test/testmath.rb b/app/server/vendor/narray-0.6.1.1/test/testmath.rb
new file mode 100755
index 0000000..0aaf089
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testmath.rb
@@ -0,0 +1,48 @@
+require 'narray'
+include NMath
+
+def pr x
+  x.each{|i|
+    if i.kind_of?(Complex)
+      printf("%.3f%+.3fi ",i.real,i.imag)
+    else
+      printf("%.3f ",i)
+    end
+  }
+  print "\n"
+end
+
+def testmath(x)
+  print "x = "
+  pr x
+  print "sqrt(x) = "
+  pr sqrt(x)
+  print "sin(x) = "
+  pr sin(x)
+  print "cos(x) = "
+  pr cos(x)
+  print "tan(x) = "
+  pr tan(x)
+  print "sinh(x) = "
+  pr sinh(x)
+  print "cosh(x) = "
+  pr cosh(x)
+  print "tanh(x) = "
+  pr tanh(x)
+  print "exp(x) = "
+  pr exp(x)
+  print "log(x) = "
+  pr log(x)
+  print "log10(x) = "
+  pr log10(x)
+  print "atan(x) = "
+  pr atan(x)
+  print "atan(tan(x)) = "
+  pr atan(tan(x))
+end
+
+testmath NArray.sfloat(6).indgen.div!(2)
+testmath NArray.float(6).indgen.div!(2)
+
+testmath NArray.scomplex(6).indgen.div!(2)-2 - Complex(0,1)
+testmath NArray.complex(6).indgen!/5-0.5# - Complex(0,0.3)
diff --git a/app/server/vendor/narray-0.6.1.1/test/testmath2.rb b/app/server/vendor/narray-0.6.1.1/test/testmath2.rb
new file mode 100755
index 0000000..bf4f18c
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testmath2.rb
@@ -0,0 +1,46 @@
+require "narray"
+include NMath
+
+def testm x,name
+  f = "a#{name}(#{name}(x))"
+  print "\n### #{f} ###\n"
+  y = eval(f)
+  p y
+  #d = x-y
+  #p d.abs
+end
+
+PI=Math::PI
+
+i = NArray.complex(1)
+i.imag=1
+
+n=7
+x = NArray.complex(n).random!(1)
+x.imag= NArray.float(n).random!(1)
+
+p x
+testm x,"sin"
+testm x,"cos"
+testm x,"tan"
+testm x,"sinh"
+testm x,"cosh"
+testm x,"tanh"
+testm x,"sec"
+testm x,"sech"
+
+p cot(1)
+
+exit
+
+a= -i * log( sqrt(1-x**2)*i + x )
+b= -i * log( sqrt(x**2-1) + x )
+p a
+p b
+p a-b
+
+a= -i * log( sqrt(1-x**2) + x*i )
+b= -i * log( (-sqrt(x**2-1) + x)*i )
+p a
+p b
+p a-b
diff --git a/app/server/vendor/narray-0.6.1.1/test/testmatrix.rb b/app/server/vendor/narray-0.6.1.1/test/testmatrix.rb
new file mode 100755
index 0000000..f190ad3
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testmatrix.rb
@@ -0,0 +1,13 @@
+require "narray"
+
+m = NMatrix.float(3,3,3).indgen!
+
+puts
+puts 'm  #=>'
+p m			#=> NMatrix.float(3,3,3):
+puts
+puts 'm[1,1,true]  #=>'
+p m[1,1,true]		#=> NArray.float(3): 
+puts
+puts 'm[0..1,2,true]  #=>'
+p m[0..1,2,true]	#=> NMatrix.float(2,1,3): 
diff --git a/app/server/vendor/narray-0.6.1.1/test/testmatrix2.rb b/app/server/vendor/narray-0.6.1.1/test/testmatrix2.rb
new file mode 100755
index 0000000..ff5271c
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testmatrix2.rb
@@ -0,0 +1,42 @@
+require 'narray'
+#require 'irb/xmp'
+# xmp :: http://www.ruby-lang.org/en/raa-list.rhtml?name=xmp
+def xp(s)
+  begin
+    puts s+" #=>"
+    p eval(s)
+  rescue
+    puts $!
+  end
+  puts
+end
+
+$m1 = NMatrix.float(2,2).indgen!
+$m2 = NMatrix[[0,1.2],[1.5,0]]
+
+$v1 = NVector[0.5,1.5]
+$v2 = NVector.float(2,2).indgen!
+
+$a  = NArray.float(2,2).indgen!
+
+xp '$m1'
+xp '$m1.inverse'
+xp '$m2'
+xp '$m1*$m2'
+xp '$m2*$m1'
+xp '$m1+$m2'
+xp '3.14*$m1'
+xp '$m2*1.25'
+xp '$v1'
+xp '$v2'
+xp '1.25*$v1'
+xp 'NMath.sqrt($v2**2)'
+xp '$v1*$v2'
+xp '$m1*$v1'
+xp '$v2*$m2'
+xp '$m1.diagonal([98,99])'
+xp 'NMatrix.float(4,3).unit'
+
+puts "\n=== following will fail ...\n"
+xp '$m1+$v1'
+xp '$m1+1'
diff --git a/app/server/vendor/narray-0.6.1.1/test/testmatrix3.rb b/app/server/vendor/narray-0.6.1.1/test/testmatrix3.rb
new file mode 100755
index 0000000..2172d9a
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testmatrix3.rb
@@ -0,0 +1,19 @@
+require 'narray'
+require 'rational'
+
+#class Rational
+#  def inspect
+#    @numerator.to_s+"/"+ at denominator.to_s
+#  end
+#end
+
+srand(1)
+n=5
+
+m = NMatrix.object(n,n).collect{Rational(rand(10))}
+
+puts 'm  #=>'
+p m
+
+puts 'm/m  #=>'
+p m/m
diff --git a/app/server/vendor/narray-0.6.1.1/test/testminmax.rb b/app/server/vendor/narray-0.6.1.1/test/testminmax.rb
new file mode 100755
index 0000000..51d0c3c
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testminmax.rb
@@ -0,0 +1,46 @@
+require 'narray'
+
+def test a
+  print "a = "
+  p a
+  print "a.min = "
+  p a.min
+  print "a.max = "
+  p a.max
+  print "a.sum = "
+  p a.sum
+  print "a.mean = "
+  p a.mean
+  print "a.stddev = "
+  p a.stddev
+end
+
+a = NArray[0,2,-2.5,3,1.4]
+
+test a
+
+a = NArray.float(5,1).indgen!(1)
+b = NArray.float(1,3).indgen!(1)
+a *= b
+test a
+
+print "a.min(0) = "
+p a.min(0)
+print "a.max(0) = "
+p a.max(0)
+print "a.min(1) = "
+p a.min(1)
+print "a.max(1) = "
+p a.max(1)
+print "a.sum(0) = "
+p a.sum(0)
+print "a.sum(1) = "
+p a.sum(1)
+print "a.mean(0) = "
+p a.mean(0)
+print "a.mean(1) = "
+p a.mean(1)
+print "a.stddev(0) = "
+p a.stddev(0)
+print "a.stddev(1) = "
+p a.stddev(1)
diff --git a/app/server/vendor/narray-0.6.1.1/test/testobject.rb b/app/server/vendor/narray-0.6.1.1/test/testobject.rb
new file mode 100755
index 0000000..0494a96
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testobject.rb
@@ -0,0 +1,29 @@
+require 'narray'
+require 'rational'
+
+n = 4
+a = NArray.object(4,4).fill!(Rational(1))
+b = NArray.object(4,4).indgen!(1).collect{|i| Rational(i)}
+
+print 'a #=> '
+p a
+
+print 'b #=> '
+p b
+
+
+class Rational
+  def inspect
+    self.to_s
+  end
+end
+
+print 'a+b #=> '
+p a+b
+
+
+print 'a/b #=> '
+p a/b
+
+print 'a/b - b #=> '
+p a/b - b
diff --git a/app/server/vendor/narray-0.6.1.1/test/testpow.rb b/app/server/vendor/narray-0.6.1.1/test/testpow.rb
new file mode 100755
index 0000000..e7360e8
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testpow.rb
@@ -0,0 +1,19 @@
+require "narray"
+
+def test a
+  puts 'a = '
+  p  a
+  puts 'a**[[-3],[0],[7]] = '
+  p  a**[[-3],[0],[7]]
+  puts 'a**[[-3.0],[0],[7.0]] = '
+  p  a**[[-3.0],[0],[7.0]]
+  puts 'a**Complex(1,0) = '
+  p  a**Complex(1,0)
+  puts 'a**1.0 = '
+  p  a**1.0
+  puts
+end
+
+test NArray.int(4).indgen!*2-2
+test NArray.float(4).indgen!*2-2
+test NArray.complex(4).indgen!*2-2
diff --git a/app/server/vendor/narray-0.6.1.1/test/testrandom.rb b/app/server/vendor/narray-0.6.1.1/test/testrandom.rb
new file mode 100755
index 0000000..5bf2c41
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testrandom.rb
@@ -0,0 +1,23 @@
+require 'narray'
+
+def test a
+  print a," #=> "
+  p eval(a)
+  print "\n"
+end
+
+test "NArray.float(5).random(10)"
+
+test "NArray.float(5).random"
+
+test "NArray.int(5).random(10)"
+
+test "NArray.int(1000).random(10)"
+
+a = NArray.int(1000).random(10)
+
+idx = (a.eq 0).where
+print "a.eq 0  :: n=", idx.size, "\n"
+
+idx = (a.eq 10).where
+print "a.eq 10 :: "; p idx
diff --git a/app/server/vendor/narray-0.6.1.1/test/testreverse.rb b/app/server/vendor/narray-0.6.1.1/test/testreverse.rb
new file mode 100755
index 0000000..c6ad046
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testreverse.rb
@@ -0,0 +1,27 @@
+require 'narray'
+
+def px(a)
+  puts a
+  puts "#=> " + eval(a).inspect
+end
+
+px "$a = NArray.int(3,3).indgen!   "
+px "$a.reverse                     "
+px "$a.reverse(0)                  "
+px "$a.reverse(1)                  "
+px "$a.rot90                       "
+px "$a.rot90(2)                    "
+px "$a.rot90(-1)                   "
+px "$a = NArray.int(3,3,3).indgen! "
+px "$a.reverse                     "
+px "$a.reverse(0)                  "
+px "$a.reverse(1)                  "
+px "$a.rot90                       "
+px "$a.rot90(2)                    "
+px "$a.rot90(-1)                   "
+px "$a = NArray.int(3).indgen!     "
+px "$a.reverse                     "
+px "$a.reverse(0)                  "
+puts "..... the next will fail ....."
+px "$a.rot90                       "
+px "$a.rot90(-1)                   "
diff --git a/app/server/vendor/narray-0.6.1.1/test/testround.rb b/app/server/vendor/narray-0.6.1.1/test/testround.rb
new file mode 100755
index 0000000..bdf0b7d
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testround.rb
@@ -0,0 +1,11 @@
+require 'narray'
+
+def testround a
+  print "a = ";  p a
+  print "a.floor = ";  p a.floor
+  print "a.ceil  = ";  p a.ceil
+  print "a.round = ";  p a.round
+  print "\n"
+end
+
+testround NArray.float(4,2).indgen!/4-2
diff --git a/app/server/vendor/narray-0.6.1.1/test/testsort.rb b/app/server/vendor/narray-0.6.1.1/test/testsort.rb
new file mode 100755
index 0000000..c76faf7
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testsort.rb
@@ -0,0 +1,37 @@
+require 'narray'
+
+def test a,b
+  print a," #=> "
+  p b
+end
+
+a = NArray.int(16).random!(100)
+
+test "a",a
+test "a.sort",a.sort
+
+print "\n# as string...\n"
+a = a.to_string
+test "a",a
+test "a.sort",a.sort
+
+print "\n# up to 0-rank...\n"
+a = NArray.int(4,4).random!(100)
+test "a",a
+test "a.sort(0)",a.sort(0)
+
+print "\n# big array test...\n"
+a = NArray.int(10,10,10,10,10).random!(100)
+test "a",a
+test "a.sort(1)",a.sort(1)
+
+print "\n# test sort_index...\n"
+a = NArray.int(7,4).random!(100)
+test "a",a
+test "a.sort_index(0)",idx=a.sort_index(0)
+test "a[a.sort_index]",a[idx]
+
+print "\n# following will fail...\n"
+a = NArray.complex(3,3).random!(100)
+test "a",a
+test "a.sort",a.sort
diff --git a/app/server/vendor/narray-0.6.1.1/test/teststr.rb b/app/server/vendor/narray-0.6.1.1/test/teststr.rb
new file mode 100755
index 0000000..dfe022a
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/teststr.rb
@@ -0,0 +1,13 @@
+require 'narray'
+
+a = NArray.float(3,3)
+p a.indgen!
+p a.to_string
+p NArray.complex(3,3).indgen!.div!(3).to_string
+p NArray.scomplex(3,3).indgen!.div!(3).to_string
+p NArray.byte(3,3).indgen!.add!(32).to_string
+
+a = NArray.int(3,3)
+p a.indgen!
+p a.to_string
+p NArray.sfloat(3,3).indgen!.to_string.to_string
diff --git a/app/server/vendor/narray-0.6.1.1/test/testtrans.rb b/app/server/vendor/narray-0.6.1.1/test/testtrans.rb
new file mode 100755
index 0000000..80bfdba
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testtrans.rb
@@ -0,0 +1,18 @@
+require 'narray'
+
+def test a,b
+  print a," #=> "
+  p b
+end
+
+a = NArray.int(4,3,2).indgen!
+test "a",a
+
+print "\n# transpose first and second...\n"
+test "a.transpose(1,0)",a.transpose(1,0)
+
+print "\n# transpose first and last...\n"
+test "a.transpose(-1,1..-2,0)",a.transpose(-1,1..-2,0)
+
+print "\n# transpose shift forward ...\n"
+test "a.transpose(1..-1,0)",a.transpose(1..-1,0)
diff --git a/app/server/vendor/narray-0.6.1.1/test/testwhere.rb b/app/server/vendor/narray-0.6.1.1/test/testwhere.rb
new file mode 100755
index 0000000..3e977c9
--- /dev/null
+++ b/app/server/vendor/narray-0.6.1.1/test/testwhere.rb
@@ -0,0 +1,27 @@
+require 'narray'
+
+a = NArray.float(8).indgen!
+
+print "a = "
+p a
+
+t,f = ( (a>=5).or(a<2) ).where2
+print "t,f = ( (a>=5).or (a<2) ).where2\n"
+print "t = "; p t
+print "f = "; p f
+
+t,f = ( (a>=5).and(a<2) ).where2
+print "t,f = ( (a>=5).and (a<2) ).where2\n"
+print "t = "; p t
+print "f = "; p f
+
+print "\n vvv no-meaning !! vvv\n"
+t,f = ( (a>=5) && (a<2) ).where2
+print "t,f = ( (a>=5) && (a<2) ).where2\n"
+print "t = "; p t
+print "f = "; p f
+
+t,f = ( (a>=5) || (a<2) ).where2
+print "t,f = ( (a>=5) || (a<2) ).where2\n"
+print "t = "; p t
+print "f = "; p f
diff --git a/app/server/vendor/parser-2.2.2.1/.gitignore b/app/server/vendor/parser-2.2.2.1/.gitignore
new file mode 100644
index 0000000..7461e7d
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/.gitignore
@@ -0,0 +1,24 @@
+*.gem
+*.rbc
+.bundle
+.config
+.yardoc
+Gemfile.lock
+InstalledFiles
+_yardoc
+coverage
+lib/bundler/man
+pkg
+rdoc
+yardoc
+spec/reports
+test/tmp
+test/version_tmp
+tmp
+*.output
+lib/parser/lexer.rb
+lib/parser/ruby18.rb
+lib/parser/ruby19.rb
+lib/parser/ruby20.rb
+lib/parser/ruby21.rb
+lib/parser/ruby22.rb
diff --git a/app/server/vendor/parser-2.2.2.1/.travis.yml b/app/server/vendor/parser-2.2.2.1/.travis.yml
new file mode 100644
index 0000000..f9e49bf
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/.travis.yml
@@ -0,0 +1,22 @@
+language: ruby
+rvm:
+ - 1.8.7
+ - 1.9.2
+ - 1.9.3
+ - 2.0.0
+ - 2.1
+ - 2.2
+ - ruby-head
+ - jruby-18mode
+ - jruby-19mode
+ - rbx-2
+matrix:
+ allow_failures:
+  - rvm: rbx-2
+before_install:
+ - gem update bundler
+ - bundle --version
+ - gem update --system 2.1.11
+ - gem --version
+script:
+ - bundle exec rake test_cov
diff --git a/app/server/vendor/parser-2.2.2.1/.yardopts b/app/server/vendor/parser-2.2.2.1/.yardopts
new file mode 100644
index 0000000..d15e2c3
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/.yardopts
@@ -0,0 +1,16 @@
+./lib/parser/**/*.rb ./lib/parser.rb
+-m markdown
+-M kramdown
+-o ./yardoc
+-r ./README.md
+--asset ./doc/css/common.css:css/common.css
+--verbose
+--api public
+--exclude lib/parser/lexer.rb
+--exclude lib/parser/ruby18.rb
+--exclude lib/parser/ruby19.rb
+--exclude lib/parser/ruby20.rb
+--exclude lib/parser/ruby21.rb
+-
+./doc/*.md
+LICENSE.txt
diff --git a/app/server/vendor/parser-2.2.2.1/CHANGELOG.md b/app/server/vendor/parser-2.2.2.1/CHANGELOG.md
new file mode 100644
index 0000000..644cc49
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/CHANGELOG.md
@@ -0,0 +1,551 @@
+Changelog
+=========
+
+v2.2.2.1 (2015-04-17)
+---------------------
+
+Bugs fixed:
+ * builders/default: don't falsely diagnose multiline regexps (fixes #190). (whitequark)
+
+v2.2.0.4 (2015-04-15)
+---------------------
+
+Features implemented:
+ * Add Parser::Source::Map#node. (whitequark)
+ * Add Parser::Source::Comment.associate_locations. (kubicle)
+
+v2.2.0.1 (2014-12-27)
+---------------------
+
+Bugs fixed:
+ * lexer.rl, lexer/literal: "{'a'::": don't parse as quoted label. (Peter Zotov)
+ * Update syntax deviation warning to reflect 2.2 release. (Peter Zotov)
+
+v2.2.0 (2014-12-25)
+-------------------
+
+Bugs fixed:
+ * lexer.rl: "{'x':1,'y':{}}": fix lex_state after tLABEL_END. (Peter Zotov)
+
+v2.2.0.pre.8 (2014-11-19)
+-------------------------
+
+API modifications:
+ * parser/current: update 2.1 to 2.1.5 (fixes #174). (Peter Zotov)
+
+v2.2.0.pre.7 (2014-11-03)
+-------------------------
+
+Bugs fixed:
+ * parser/meta: add missing nodes (fixes #171). (Peter Zotov)
+
+v2.2.0.pre.6 (2014-10-28)
+-------------------------
+
+API modifications:
+ * parser/current: latest stable 2.1.x is 2.1.4, update warning. (hirocaster)
+
+v2.2.0.pre.5 (2014-10-03)
+-------------------------
+
+Features implemented:
+ * parser/current: add syntax deviation warning for 2.1.2. (Peter Zotov)
+ * lexer.rl, ruby22.y: "{'x':1}": add tLABEL_END. (Peter Zotov)
+
+Bugs fixed:
+ * lexer.rl, ruby{21,22}.y: "def a b:\nreturn": fix #164. (Peter Zotov)
+ * Fix for `ruby-rewrite` not rewriting files if any rewriter was loaded, due to it getting confused about the filename. (Jon Frisby)
+
+v2.2.0.pre.4 (2014-08-09)
+-------------------------
+
+Bugs fixed:
+ * builders/default: "not(x)": fix source map (fixes #158). (Peter Zotov)
+
+v2.2.0.pre.3 (2014-07-02)
+-------------------------
+
+Features implemented:
+ * Raise EncodingError when source includes invalid byte sequence (Yuji Nakayama)
+
+Bugs fixed:
+ * ruby{19,20,21}.y: "x def y; z do end end": save cmdarg stack to isolate command argument state from outer scope. (Peter Zotov)
+ * ruby{19,20,21}.y: "tap (proc do end)": allow parenthesed do-block in cmdarg. (Peter Zotov)
+
+v2.2.0.pre.2 (2014-06-14)
+-------------------------
+
+Bugs fixed:
+ * ruby22.rb: include in gemspec. (Peter Zotov)
+
+v2.2.0.pre.1 (2014-06-12)
+-------------------------
+
+Features implemented:
+ * Add Source::Rewriter#transaction for atomic rewrite actions (Yuji Nakayama)
+ * Raise Parser::ClobberingError for clobbering rewrite error (Yuji Nakayama)
+
+Bugs fixed:
+ * parser/current: fix the fallback case (refs #146). (Peter Zotov)
+ * ruby22.y: "tap (proc do end)": allow parenthesed do-block in cmdarg. (Peter Zotov)
+
+v2.1.9 (2014-04-21)
+-------------------
+
+API modifications:
+ * Extend ast dependency to >= 1.1 \< 3.0. (Peter Zotov)
+ * parser/current: fallback to latest released Ruby instead of raising (fixes #140). (Peter Zotov)
+
+Features implemented:
+ * ruby-rewrite: add a --modify switch for rewriters that modify AST (fixes #143). (Peter Zotov)
+
+Bugs fixed:
+ * lexer.rl: don't fail to parse string literals in huge files (fixes #142). (Peter Zotov)
+
+v2.1.7 (2014-03-05)
+-------------------
+
+Bugs fixed:
+ * lexer.rl: make sure all invalid escapes lead to fatal errors (fixes #136). (Peter Zotov)
+
+v2.1.6 (2014-03-04)
+-------------------
+
+Features implemented:
+ * Add the list of all node types within Parser::Meta. (Markus Schirp)
+
+v2.1.5 (2014-02-24)
+-------------------
+
+Bugs fixed:
+ * Parser::Base, ruby18.y: don't try to lookup Encoding on 1.8 (fixes #133). (Peter Zotov)
+
+v2.1.4 (2014-01-11)
+-------------------
+
+Features implemented:
+ * ruby22.y: "x def y; z do end end": save cmdarg stack to isolate command argument state from outer scope. (Peter Zotov)
+ * Add Ruby 2.2 syntax. (Peter Zotov)
+
+Bugs fixed:
+ * Builders::Default: "super do end": super and zsuper are like send (fixes #131). (Peter Zotov)
+
+v2.1.3 (2014-01-10)
+-------------------
+
+Bugs fixed:
+ * lexer.rl: "/\//": don't include escaped delimiter in AST in its escaped form (fixes #125). (Peter Zotov)
+ * Builders::Default: "return x y do end": correctly build AST for keywords followed by command (closes #129). (Peter Zotov)
+ * Fix a bug where "ambiguous first argument" diagnostic was not emitted (Yuji Nakayama)
+ * Source::Comment::Associator: don't die while associating with "__ENCODING__". (Peter Zotov)
+ * ruby-parse: don't die when invoked with -L -e "__ENCODING__". (Peter Zotov)
+ * Add missing source map for match-current-line (Yuji Nakayama)
+
+v2.1.2 (2014-01-05)
+-------------------
+
+Bugs fixed:
+ * lexer.rl: in "foo!= x", foo is tIDENTIFIER, not tFID (closes #126). (Peter Zotov)
+
+v2.1.1 (2013-12-25)
+-------------------
+
+API modifications:
+ * ruby21.y: Ruby 2.1 is released already. (Peter Zotov)
+
+v2.1.0 (2013-12-25)
+-------------------
+
+API modifications:
+ * Parser::Diagnostic: expose reason symbolically (closes #115, #116). (Ian MacLeod)
+ * lexer.rl: coerce literals to UTF-8 in ASCII-encoded files if they contain \uXXXX (Peter Zotov)
+
+Bugs fixed:
+ * builders/default: represent heredocs with dedicated map (fixes #100). (Peter Zotov)
+
+v2.1.0.pre1 (2013-11-12)
+------------------------
+
+API modifications:
+ * lexer.rl: correctly handle __END__ with non-whitespace after it (Peter Zotov)
+ * lexer.rl: handle \r in middle of a line as mere whitespace (Peter Zotov)
+ * ruby{18,19,20,21}.y, builders/default: precisely point to tUMINUS_NUM. (Peter Zotov)
+
+Features implemented:
+ * lexer.rl, ruby21.y, builders/default: rational/complex literals. (Peter Zotov)
+
+v2.0.0 (2013-10-06)
+-------------------
+
+API modifications:
+ * Source::Rewriter: raise an exception if updates clobber each other. (Peter Zotov)
+ * Source::Range#inspect: use full class name. (Peter Zotov)
+ * lexer.rl: make EOF tokens actually pointing at EOF and zero-length. (Peter Zotov)
+ * Source::Range#column_range: raise RangeError if range spans >1 line. (Peter Zotov)
+ * Source::Comment::Associator: fix argument order. (Peter Zotov)
+
+Features implemented:
+ * Source::Comment: implement #inspect. (Peter Zotov)
+ * Backport Array#bsearch from Ruby 2.0. (Peter Zotov)
+
+v2.0.0.pre8 (2013-09-15)
+------------------------
+
+API modifications:
+ * lexer.rl: make lexing faster and improve parsing speed by ~60%. (Peter Zotov)
+
+v2.0.0.pre7 (2013-09-10)
+------------------------
+
+Features implemented:
+ * Parser::Base: add #parse_with_comments, #parse_file_with_comments. (Trent Ogren)
+ * lexer.rl (Ruby 2.1): "1end": lex non-exponent `e' separate from number. (Peter Zotov)
+
+Bugs fixed:
+ * lexer.rl: "->*{}": tLAMBEG at expr_beg (fixes #103). (Peter Zotov)
+ * Source::Rewriter: apply actions in the insertion order. (Josh Cheek)
+
+v2.0.0.pre5 (2013-07-31)
+------------------------
+
+Bugs fixed:
+ * Remove a forgotten require. (Peter Zotov)
+
+v2.0.0.pre4 (2013-07-31)
+------------------------
+
+API modifications:
+ * source/comment: make #loc/#location return Source::Map for consistency (fixes #96). (Peter Zotov)
+
+Features implemented:
+ * source/comment/associator: skip shebang and encoding line by default (fixes #95). (Peter Zotov)
+
+Bugs fixed:
+ * ruby{19,20,21}.y, lexer.rl, builders/default: correct begin for ?a (fixes #92). (Peter Zotov)
+ * ruby{18,19,20,21}.y, builders/default: don't add spurious begin/end for string parts (refs #92). (Peter Zotov)
+ * Activate `diagnostics.all_errors_are_fatal` on non-MRI Rubies as a workaround (closes #93). (Peter Zotov)
+
+v2.0.0.pre3 (2013-07-26)
+------------------------
+
+API modifications:
+ * lexer.rl: add simple explicit output encoding for strings. (Peter Zotov)
+
+Features implemented:
+ * Source::Buffer: support for -(dos|unix|mac) and utf8-mac encodings. (Peter Zotov)
+ * Source::Range#resize. (Peter Zotov)
+ * Significantly improve speed for large (>100k) and very large (>1M) files. (Peter Zotov)
+
+Bugs fixed:
+ * ruby21.y: fix typos. (Peter Zotov)
+ * builders/default: respect regexp encoding. (Peter Zotov)
+ * lexer.rl: literal EOF (\0, \x04, \x1a) inside literals and comments. (Peter Zotov)
+ * lexer.rl: "meth (lambda do end)" (1.8), "f x: -> do meth do end end": expr_cmdarg. (Peter Zotov)
+ * lexer.rl: "\<\<E\nE\r\r\n": extraneous CRs are ignored after heredoc delimiter. (Peter Zotov)
+ * lexer.rl: "%\nfoo\n": \n can be used as %-literal delimiter. (Peter Zotov)
+ * source/buffer, lexer.rl: convert CRLF to LF prior to lexing. (Peter Zotov)
+ * lexer.rl: "\<\<w; "\nfoo\nw\n"": interleaved heredoc and non-heredoc literals. (Peter Zotov)
+ * builders/default: 1.8 did not descend into &&/|| in conditional context. (Peter Zotov)
+ * lexer.rl: "1+a:a": respect context sensitivity in 1.8 label fallback. (Peter Zotov)
+ * lexer.rl: ruby 1.8 is context-sensitive wrt/ locals as well. (Peter Zotov)
+ * lexer.rl: "eof??a": expr_arg doesn't need space before character literal. (Peter Zotov)
+ * lexer.rl: interleaved heredoc and interpolated double-quoted string. (Peter Zotov)
+ * lexer.rl: "#{f:a}": interpolation starts expr_value, not expr_beg. (Peter Zotov)
+ * lexer.rl: "\cM" is "\r", not an error. (Peter Zotov)
+ * ruby{20,21}.y: constant op-assignment inside a def is not an error. (Peter Zotov)
+ * lexer.rl: "when Date:" fix label fallback for 1.8 mode. (Peter Zotov)
+ * ruby{19,20,21}.y: "->(scope){}; scope :foo": lambda identifier leakage. (Peter Zotov)
+ * lexer.rl: "eh ?\r\n": don't eat tEH if followed by CRLF. (Peter Zotov)
+ * lexer.rl: "f \<\<-TABLE\ndo |a,b|\nTABLE\nend": leave FSM after lexing heredoc. (Peter Zotov)
+ * lexer.rl: "foo %\n bar": don't % at expr_arg as tSTRING_BEG. (Peter Zotov)
+ * lexer.rl, lexer/literal: use lexer encoding for literal buffer. (Peter Zotov)
+ * lexer.rl: "\u{9}": one-digit braced unicode escapes. (Peter Zotov)
+ * Source::Buffer: don't chew \r from source lines. (Peter Zotov)
+ * builders/default: don't die in eh_keyword_map if else branch is empty. (Peter Zotov)
+ * lexer.rl: "0777_333": octal literals with internal underscores. (Peter Zotov)
+ * lexer.rl: "let [] {}": goto tLBRACE_ARG after any closing braces. (Peter Zotov)
+ * lexer.rl: "while not (1) do end": emit proper kDO* when in cond/cmdarg state. (Peter Zotov)
+ * lexer.rl: "rescue=>": correctly handle rescue+assoc at expr_beg. (Peter Zotov)
+ * lexer.rl: "puts 123do end": only trailing `_' and `e' in number are errors. (Peter Zotov)
+ * lexer.rl: "begin; rescue rescue1; end": accept barewords at expr_mid. (Peter Zotov)
+ * lexer.rl: "f.x!if 1": correct modifier handling in expr_arg. (Peter Zotov)
+ * lexer.rl: "=begin\n#=end\n=end": only recognize =end at bol. (Peter Zotov)
+ * builders/default: don't check for duplicate arguments in 1.8 mode. (Peter Zotov)
+ * Don't attempt to parse magic encoding comment in 1.8 mode. (Peter Zotov)
+ * lexer.rl: "\777": octal literals overflow. (Peter Zotov)
+ * lexer.rl: "foo;\n__END__", "\na:b": whitespace in expr_value. (Peter Zotov)
+ * lexer.rl: "\xE2\x80\x99": concatenation of byte escape sequences. (Peter Zotov)
+ * lexer.rl: "E10", "E4U": don't conflate floats and identifiers. (Peter Zotov)
+ * lexer.rl: "foo.bar= {1=>2}": return fid, = as separate tokens in expr_dot. (Peter Zotov)
+ * lexer.rl: "def defined?": properly return defined? in expr_fname. (Peter Zotov)
+ * lexer.rl: "Rainbows! do end", "foo.S?": allow bareword fid in expr_beg/dot. (Peter Zotov)
+
+v2.0.0.pre2 (2013-07-11)
+------------------------
+
+Features implemented:
+ * Allow to differentiate between __FILE__/__LINE__ and literals (closes #89). (Peter Zotov)
+ * Add attribute `diagnostic' to Parser::SyntaxError (closes #88). (Peter Zotov)
+
+Bugs fixed:
+ * Don't treat byte order mark as an identifier (closes #91). (Peter Zotov)
+
+v2.0.0.beta10 (2013-07-02)
+--------------------------
+
+Bugs fixed:
+ * ruby-parse, ruby-rewrite: fix require of removed compatibility shim. (Peter Zotov)
+ * lexer.rl: "def !@; end" unary bang. (Peter Zotov)
+
+v2.0.0.beta9 (2013-06-28)
+-------------------------
+
+API modifications:
+ * ruby{18,19,20,21}.y: removed obsolete warnings and linting. (Peter Zotov)
+
+Features implemented:
+ * builders/default: add keyword source range for BEGIN/END (fixes #85). (Peter Zotov)
+
+Bugs fixed:
+ * lexer.rl: "t=1;(a)?t:T" context sensitivity in expr_value (fixes #87). (Peter Zotov)
+ * lexer.rl: keywords as labels, e.g. "unless:" (fixes #83, #84). (Peter Zotov)
+ * lexer.rl: rectify usage of c_space/c_space_nl (fixes #81). (Peter Zotov)
+ * ruby{18,19,20,21}.y: fix warnings for class/module in method body. (Peter Zotov)
+ * lexer.rl: fix warning for ?\s. (Peter Zotov)
+ * lexer.rl: expr_fname emits expr_beg-like keywords (fixes #82). (Peter Zotov)
+ * lexer.rl: get rid of harmful nondeterminism in w_space (fixes #80). (Peter Zotov)
+ * lexer/explanation: 1.8, 1.9 compatibility (fixes #76). (Peter Zotov)
+
+v2.0.0.beta8 (2013-06-24)
+-------------------------
+
+Bugs fixed:
+ * ast/processor: add missing node handlers (Yuji Nakayama)
+ * ast/processor: rename some obsolete node handlers (Yuji Nakayama)
+
+v2.0.0.beta7 (2013-06-22)
+-------------------------
+
+API modifications:
+ * Implement a much more sane encoding model (closes #60). (Peter Zotov)
+
+Features implemented:
+ * builders/default: (while-post) and (until-post); (kwbegin) (fixes #70). (Peter Zotov)
+
+Bugs fixed:
+ * builders/default: don't swallow (begin) in "if (foo); end" (fixes #75). (Peter Zotov)
+
+v2.0.0.beta6 (2013-06-17)
+-------------------------
+
+API modifications:
+ * Get rid of "synthesized (nil)". If it's not in source, it's not in AST (fixes #71). (Peter Zotov)
+ * lexer.rl, ruby{18,19,20,21}.y: source maps for interpolation (fixes #27). (Peter Zotov)
+
+Features implemented:
+ * ruby{18,19,20,21}.y, builders/default: lvar-injecting match (closes #69). (Peter Zotov)
+ * builders/default: implicit matches (refs #69). (Peter Zotov)
+ * builders/default: flip-flops (refs #69). (Peter Zotov)
+
+Bugs fixed:
+ * lexer.rl: fix an off-by-1 error in heredoc parsing. (Peter Zotov)
+ * lexer.rl: don't fail on "alias $a $b\n# comment\nalias $c $d". (Peter Zotov)
+ * builders/default: fix treatment of masgn in &&/|| (refs #69). (Peter Zotov)
+ * ruby-parse: make -L command line option work again. (Peter Zotov)
+ * ruby{18,19,20,21}.y: begin source map for "if foo\nthen bar end" (fixes #68). (Peter Zotov)
+ * Source::Comment::Associator: gracefully terminate when out of comments (fixes #67). (Peter Zotov)
+
+v2.0.0.beta5 (2013-06-08)
+-------------------------
+
+Bugs fixed:
+ * Source::Buffer: better magic encoding comment recognition (fixes #65). (Peter Zotov)
+ * lexer.rl: "{success?: true}" (fixes #66). (Peter Zotov)
+ * Source::Buffer: if in doubt, treat data as UTF-8 (closes #60). (Peter Zotov)
+
+v2.0.0.beta4 (2013-06-05)
+-------------------------
+
+Bugs fixed:
+ * lexer.rl: fix heredoc parsing with CRLF line endings (closes #61). (Peter Zotov)
+ * lexer.rl: fix premature ending of heredoc "\<\<D\nABCDEF\nD" (fixes #59). (Peter Zotov)
+
+v2.0.0.beta3 (2013-05-29)
+-------------------------
+
+Bugs fixed:
+ * AST::Processor: traverse "A, B = foo" (fixes #55). (Peter Zotov)
+ * lexer.rl: correctly handle CRLF line endings (fixes #56). (Peter Zotov)
+ * Fix traversing of "case; when a?; when b?; end" by AST::Processor. (Peter Zotov)
+ * Correctly lex "foo a, b # comment\nbar" (fixes #54). (Peter Zotov)
+
+v2.0.0.beta2 (2013-05-27)
+-------------------------
+
+Bugs fixed:
+ * Actually return comments from Parser::Base#tokenize instead of nil. (Peter Zotov)
+
+v2.0.0.beta1 (2013-05-25)
+-------------------------
+
+API modifications:
+ * Completely rewrite whitespace handling in lexer (fixes #36). (Peter Zotov)
+ * Rename Parser::AST::Node#source_map to #location, #src to #loc (closes #40). (Peter Zotov)
+ * Rename Parser::Source::Range#to_source to #source (refs #40). (Peter Zotov)
+ * Rename (cdecl) node to (casgn), remove (cvdecl) nodes (fixes #26). (Peter Zotov)
+
+Features implemented:
+ * Add Source::Comment.associate for mapping comments back to nodes (fixes #31). (Peter Zotov)
+ * Return AST and comments from Parser::Base#parse_with_comments. (Peter Zotov)
+ * Return comments from Parser::Base#tokenize (fixes #46). (Peter Zotov)
+ * Add tokenizer, Parser::Base#tokenize (refs #46). (Peter Zotov)
+ * lexer.rl: better location reporting for invalid unicode codepoints (fixes #38). (Peter Zotov)
+ * lexer.rl: better location reporting for unterminated =begin (fixes #37). (Peter Zotov)
+ * Better location reporting for hashes with labels. (Peter Zotov)
+ * Add `dot' source map to (send) nodes (fixes #34). (Peter Zotov)
+ * Significantly improve performance of Source::Buffer (fixes #28). (Peter Zotov)
+
+Bugs fixed:
+ * lexer.rl: fix lexing label at line_begin "foo:bar" (fixes #48). (Peter Zotov)
+ * lexer.rl: "Option /^I/" is a method call (fixes #32). (Peter Zotov)
+ * Don't allow destructive mutation of line cache in Source::Buffer. (Peter Zotov)
+ * Fix quantifier in magic encoding parser (refs #33). (Peter Zotov)
+ * Better handling of magic encoding comment edge cases (fixes #33). (Peter Zotov)
+
+v1.3.2 (2013-05-13)
+-------------------
+
+Features implemented:
+ * lexer.rl: disallow "$-" (dollar, dash, no character) special. (Peter Zotov)
+
+Bugs fixed:
+ * Source::Range: fix #to_source for multiline ranges. (Peter Zotov)
+ * builders/default: source map for class/module name (fixes #24). (Peter Zotov)
+
+v1.3.1 (2013-05-09)
+-------------------
+
+Bugs fixed:
+ * ruby{19,20,21}.y: "def foo\n=begin\n=end\nend" (fixes #22). (Peter Zotov)
+ * lexer.rl: "rescue::Exception" (fixes #23). (Peter Zotov)
+
+v1.3.0 (2013-04-26)
+-------------------
+
+Bugs fixed:
+ * lexer.rl: "alias foo bar \n alias bar baz". (Peter Zotov)
+
+v1.2.0 (2013-04-25)
+-------------------
+
+Bugs fixed:
+ * lexer.rl: lex "def String.foo; end" correctly (fixes #16). (Peter Zotov)
+ * lexer.rl: reject "1end", "1.1end". (Peter Zotov)
+
+v1.1.0 (2013-04-18)
+-------------------
+
+API modifications:
+ * ruby19.y, ruby20.y, ruby21.y: check for Encoding support (fixes #9). (Peter Zotov)
+
+Features implemented:
+ * builders/default: ignore duplicate _ args (>=1.9), _.* args (>1.9) (fixes #5). (Peter Zotov)
+ * builders/default: detect duplicate argument names (refs #5). (Peter Zotov)
+ * lexer.rl: "def foo bar: 1; end" (for ruby 2.1) (fixes #15). (Peter Zotov)
+ * ruby21.y: required keyword arguments. (Peter Zotov)
+
+Bugs fixed:
+ * ruby20.y, ruby21.y: "foo::A += 1" and friends (scoped constant op-asgn). (Peter Zotov)
+
+v1.0.1 (2013-04-18)
+-------------------
+
+Bugs fixed:
+ * builders/default: %Q{#{1}} and friends (fixes #14). (Peter Zotov)
+
+v1.0.0 (2013-04-17)
+-------------------
+
+Features implemented:
+ * ruby20.y: "meth 1 do end.fun(bar) {}" and friends. (Peter Zotov)
+ * ruby20.y: keyword arguments. (Peter Zotov)
+ * ruby20.y: { **kwsplat }. (Peter Zotov)
+
+v0.9.2 (2013-04-16)
+-------------------
+
+Features implemented:
+ * lexer.rl: "-> (a) {}". (Peter Zotov)
+ * builders/default: treat &&/|| lhs/rhs as conditional context. (Peter Zotov)
+ * ruby20.y: "class Foo \< a:b; end". (Peter Zotov)
+ * lexer.rl: "class \<\< a:b". (Peter Zotov)
+ * ruby19.y, ruby20.y: "f { || a:b }". (Peter Zotov)
+ * ruby19.y, ruby20.y: "def foo() a:b end", "def foo\n a:b end". (Peter Zotov)
+ * lexer.rl: %i/%I. (Peter Zotov)
+ * lexer.rl: warn at "foo **bar". (Peter Zotov)
+ * lexer.rl: ** at expr_beg is tDSTAR. (Peter Zotov)
+ * ruby20.y: "f {|;\nvar\n|}". (Peter Zotov)
+ * ruby20.y: "p () {}". (Peter Zotov)
+ * ruby20.y: "p begin 1.times do 1 end end". (Peter Zotov)
+ * ruby20.y: better error message for BEGIN{} in a method body. (Peter Zotov)
+
+Bugs fixed:
+ * lexer.rl, ruby18.y, ruby19.y, ruby20.y: "%W[#{a}#@b foo #{c}]". (Peter Zotov)
+ * lexer.rl: parse "foo=1; foo / bar #/" as method call on 1.8, division on 1.9. (Peter Zotov)
+ * ruby18.y, ruby19.y: BEGIN{} does not introduce a scope. (Peter Zotov)
+ * lexer.rl: improve whitespace handling. (Peter Zotov)
+
+v0.9.0 (2013-04-15)
+-------------------
+
+API modifications:
+ * runtime compatibility with 1.8.7. (Peter Zotov)
+
+Features implemented:
+ * builders/default: check for multiple assignment in conditions (fixes #4). (Peter Zotov)
+ * builders/default: check if actual block and blockarg are passed (fixes #6). (Peter Zotov)
+ * ruby19.y: "foo::A += m foo". (Peter Zotov)
+ * ruby18.y, ruby19.y: "rescue without else is useless" warning. (Peter Zotov)
+ * ruby19.y: 99.16% coverage, 100% sans error recovery. (Peter Zotov)
+ * ruby19.y: mlhs arguments "def foo((a, *, p)) end". (Peter Zotov)
+ * ruby19.y: "fun (1) {}" and friends. (Peter Zotov)
+ * ruby19.y: mlhs post variables "a, *b, c = ...". (Peter Zotov)
+ * builders/default: @@a |= 1; def f; @@a |= 1; end. (Peter Zotov)
+ * ruby18.y: fun (&foo). (Peter Zotov)
+ * ruby18.y: block formal arguments. 99.33% coverage. (Peter Zotov)
+ * ruby18.y: fun(meth 1 do end); fun(1, meth 1 do end). (Peter Zotov)
+ * ruby18.y: "meth 1 do end.fun(bar)" and friends. (Peter Zotov)
+ * ruby18.y: foo () {}; a.foo () {}; a::foo () {}. (Peter Zotov)
+ * ruby18.y: various call argument combinations. (Peter Zotov)
+ * ruby18.y: foo (1, 2); foo (). (Peter Zotov)
+ * ruby18.y: foo (1).to_i. (Peter Zotov)
+ * ruby18.y: fun{}; fun(){}; fun(1){}; fun do end. (Peter Zotov)
+ * ruby18.y: foo.fun bar. (Peter Zotov)
+ * lexer.rl, ruby18.y: add support for cond/cmdarg stack states. (Peter Zotov)
+ * ruby18.y: rescue. (Peter Zotov)
+ * ruby18.y: begin end while|until (tests only). (Peter Zotov)
+ * ruby18.y: case. (Peter Zotov)
+ * ruby18.y: foo[m bar]. (Peter Zotov)
+ * ruby18.y: for..in. (Peter Zotov)
+
+Bugs fixed:
+ * lexer.rl: handle : at expr_beg as a symbol, at expr_end as tCOLON. (Peter Zotov)
+ * lexer.rl: handle "rescue #foo\nbar". (Peter Zotov)
+ * lexer.rl: handle "foo.#bar\nbaz". (Peter Zotov)
+ * lexer.rl: fix location info for symbols. (Peter Zotov)
+ * lexer.rl: handle \<backslash>\<nl> at expr_beg. (Peter Zotov)
+ * lexer.rl: emit tCONSTANT/tIDENTIFIER/tFID in expr_dot. (Peter Zotov)
+ * lexer.rl: correctly disambiguate "x ::Foo" as tIDENT, tCOLON3, ... (Peter Zotov)
+ * lexer.rl: correctly disambiguate ident!= as tIDENTIFIER, tNEQ. (Peter Zotov)
+ * lexer.rl: correctly report the %r%% tREGEXP_BEG value as %r%. (Peter Zotov)
+ * ruby19.y: emit correct error on "nil = 1" and friends. (Peter Zotov)
+ * ruby19.y: 1.9 permits empty symbol literals. (Peter Zotov)
+ * ruby18.y: foo(&bar). (Peter Zotov)
+ * lexer.rl: don't lookahead two tokens on "func %{str} do". (Peter Zotov)
+ * lexer.rl: fix lexing of non-interp heredoc with trailing backslash. (Peter Zotov)
+ * lexer.rl: fix erroneous number and =begin lookahead in expr_beg. (Peter Zotov)
+ * lexer.rl: fix stack corruption. (Peter Zotov)
+ * lexer.rl: /= at expr_beg. (Peter Zotov)
+ * lexer.rl: class\<\<self. (Peter Zotov)
+ * fix lexing comments at expr_beg "{#1\n}". (Peter Zotov)
+
diff --git a/app/server/vendor/parser-2.2.2.1/CONTRIBUTING.md b/app/server/vendor/parser-2.2.2.1/CONTRIBUTING.md
new file mode 100644
index 0000000..0b59863
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/CONTRIBUTING.md
@@ -0,0 +1,10 @@
+Contributing to Parser
+----------------------
+
+Parser uses [Semantic Versioning](http://semver.org). Additionally, Parser employs a script to extract information from VCS (git) log and form a Changelog file. Thus, each commit which affects the public API in any way must be marked with one of the following sigils, or characters at the beginning of line:
+
+ * `-` for bugfixes. For example: `- lexer.rl: fixed lexing of "alias $foo $bar".`
+ * `+` for features. For example: `+ Implemented Parser::Rewriter, a module for non-intrusive rewriting of source code.`
+ * `*` for miscellaneous changes. For example: `* Converted measurement units from metric to imperial.`
+
+These categories map nicely to semantic versioning: `-` bugfixes increment patchlevel, `+` features increment minor version, `*` API changes increment major version.
diff --git a/app/server/vendor/parser-2.2.2.1/Gemfile b/app/server/vendor/parser-2.2.2.1/Gemfile
new file mode 100644
index 0000000..8819a8d
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/Gemfile
@@ -0,0 +1,4 @@
+source 'https://rubygems.org'
+
+# Specify your gem's dependencies in parser.gemspec
+gemspec
diff --git a/app/server/vendor/parser-2.2.2.1/LICENSE.txt b/app/server/vendor/parser-2.2.2.1/LICENSE.txt
new file mode 100644
index 0000000..15d3876
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/LICENSE.txt
@@ -0,0 +1,25 @@
+Copyright (c) 2013 Peter Zotov  <whitequark at whitequark.org>
+
+Parts of the source are derived from ruby_parser:
+Copyright (c) Ryan Davis, seattle.rb
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/parser-2.2.2.1/README.md b/app/server/vendor/parser-2.2.2.1/README.md
new file mode 100644
index 0000000..0476b26
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/README.md
@@ -0,0 +1,278 @@
+# Parser
+
+[![Gem Version](https://badge.fury.io/rb/parser.png)](https://badge.fury.io/rb/parser)
+[![Build Status](https://travis-ci.org/whitequark/parser.png?branch=master)](https://travis-ci.org/whitequark/parser)
+[![Code Climate](https://codeclimate.com/github/whitequark/parser.png)](https://codeclimate.com/github/whitequark/parser)
+[![Coverage Status](https://coveralls.io/repos/whitequark/parser/badge.png?branch=master)](https://coveralls.io/r/whitequark/parser)
+
+_Parser_ is a production-ready Ruby parser written in pure Ruby. It performs on
+par or better than Ripper, Melbourne, JRubyParser or ruby\_parser.
+
+You can also use [unparser](https://github.com/mbj/unparser) to produce
+equivalent source code from Parser's ASTs.
+
+Sponsored by [Evil Martians](http://evilmartians.com).
+
+## Installation
+
+    $ gem install parser
+
+## Usage
+
+Parse a chunk of code:
+
+    require 'parser/current'
+
+    p Parser::CurrentRuby.parse("2 + 2")
+    # (send
+    #   (int 2) :+
+    #   (int 2))
+
+Access the AST's source map:
+
+    p Parser::CurrentRuby.parse("2 + 2").loc
+    # #<Parser::Source::Map::Send:0x007fe5a1ac2388
+    #   @dot=nil,
+    #   @begin=nil,
+    #   @end=nil,
+    #   @selector=#<Source::Range (string) 2...3>,
+    #   @expression=#<Source::Range (string) 0...5>>
+
+    p Parser::CurrentRuby.parse("2 + 2").loc.selector.source
+    # "+"
+
+Traverse the AST: see the documentation for [gem ast](https://whitequark.github.io/ast/).
+
+Parse a chunk of code and display all diagnostics:
+
+    parser = Parser::CurrentRuby.new
+    parser.diagnostics.consumer = lambda do |diag|
+      puts diag.render
+    end
+
+    buffer = Parser::Source::Buffer.new('(string)')
+    buffer.source = "foo *bar"
+
+    p parser.parse(buffer)
+    # (string):1:5: warning: `*' interpreted as argument prefix
+    # foo *bar
+    #     ^
+    # (send nil :foo
+    #   (splat
+    #     (send nil :bar)))
+
+If you reuse the same parser object for multiple `#parse` runs, you need to
+`#reset` it.
+
+You can also use the `ruby-parse` utility (it's bundled with the gem) to play
+with Parser:
+
+    $ ruby-parse -L -e "2+2"
+    (send
+      (int 2) :+
+      (int 2))
+    2+2
+     ~ selector
+    ~~~ expression
+    (int 2)
+    2+2
+    ~ expression
+    (int 2)
+    2+2
+
+    $ ruby-parse -E -e "2+2"
+    2+2
+    ^ tINTEGER 2                                    expr_end     [0 <= cond] [0 <= cmdarg]
+    2+2
+     ^ tPLUS "+"                                    expr_beg     [0 <= cond] [0 <= cmdarg]
+    2+2
+      ^ tINTEGER 2                                  expr_end     [0 <= cond] [0 <= cmdarg]
+    2+2
+      ^ false "$eof"                                expr_end     [0 <= cond] [0 <= cmdarg]
+    (send
+      (int 2) :+
+      (int 2))
+
+## Features
+
+* Precise source location reporting.
+* [Documented](doc/AST_FORMAT.md) AST format which is convenient to work with.
+* A simple interface and a powerful, tweakable one.
+* Parses 1.8, 1.9, 2.0, 2.1 and 2.2 syntax with backwards-compatible
+  AST formats.
+* [Rewriting][rewriting] support.
+* Parsing error recovery.
+* Improved [clang-like][] diagnostic messages with location information.
+* Written in pure Ruby, runs on MRI 1.8.7 or >=1.9.2, JRuby and Rubinius in 1.8
+  and 1.9 mode.
+* Only one runtime dependency: the [ast][] gem.
+* [Insane][insane-lexer] Ruby lexer rewritten from scratch in Ragel.
+* 100% test coverage for Bison grammars (except error recovery).
+* Readable, commented source code.
+
+[clang-like]: http://clang.llvm.org/diagnostics.html
+[ast]: https://rubygems.org/gems/ast
+[insane-lexer]: http://whitequark.org/blog/2013/04/01/ruby-hacking-guide-ch-11-finite-state-lexer/
+[rewriting]: http://whitequark.org/blog/2013/04/26/lets-play-with-ruby-code/
+
+## Documentation
+
+Documentation for parser is available [online](https://whitequark.github.io/parser/).
+
+### Node names
+
+Several Parser nodes seem to be confusing enough to warrant a dedicated README section.
+
+#### (block)
+
+The `(block)` node passes a Ruby block, that is, a closure, to a method call represented by its first child, a `(send)`, `(super)` or `(zsuper)` node. To demonstrate:
+
+```
+$ ruby-parse -e 'foo { |x| x + 2 }'
+(block
+  (send nil :foo)
+  (args
+    (arg :x))
+  (send
+    (lvar :x) :+
+    (int 2)))
+```
+
+#### (begin) and (kwbegin)
+
+**TL;DR: Unless you perform rewriting, treat `(begin)` and `(kwbegin)` as the same node type.**
+
+Both `(begin)` and `(kwbegin)` nodes represent compound statements, that is, several expressions which are executed sequentally and the value of the last one is the value of entire compound statement. They may take several forms in the source code:
+
+  * `foo; bar`: without delimiters
+  * `(foo; bar)`: parenthesized
+  * `begin foo; bar; end`: grouped with `begin` keyword
+  * `def x; foo; bar; end`: grouped inside a method definition
+
+and so on.
+
+```
+$ ruby-parse -e '(foo; bar)'
+(begin
+  (send nil :foo)
+  (send nil :bar))
+$ ruby-parse -e 'def x; foo; bar end'
+(def :x
+  (args)
+  (begin
+    (send nil :foo)
+    (send nil :bar)))
+```
+
+Note that, despite its name, `kwbegin` node only has tangential relation to the `begin` keyword. Normally, Parser AST is semantic, that is, if two constructs look differently but behave identically, they get parsed to the same node. However, there exists a peculiar construct called post-loop in Ruby:
+
+```
+begin
+  body
+end while condition
+```
+
+This specific syntactic construct, that is, keyword `begin..end` block followed by a postfix `while`, [behaves][postloop] very unlike other similar constructs, e.g. `(body) while condition`. While the body itself is wrapped into a `while-post` node, Parser also supports rewriting, and in that context it is important to not accidentally convert one kind of loop into another.
+
+  [postloop]: http://rosettacode.org/wiki/Loops/Do-while#Ruby
+
+```
+$ ruby-parse -e 'begin foo end while cond'
+(while-post
+  (send nil :cond)
+  (kwbegin
+    (send nil :foo)))
+$ ruby-parse -e 'foo while cond'
+(while
+  (send nil :cond)
+  (send nil :foo))
+$ ruby-parse -e '(foo) while cond'
+(while
+  (send nil :cond)
+  (begin
+    (send nil :foo)))
+```
+
+(Parser also needs the `(kwbegin)` node type internally, and it is highly problematic to map it back to `(begin)`.)
+
+## Compatibility with Ruby MRI
+
+Unfortunately, Ruby MRI often changes syntax in patchlevel versions. This has happened, at least, for every release since 1.9; for example, commits [c5013452](https://github.com/ruby/ruby/commit/c501345218dc5fb0fae90d56a0c6fd19d38df5bb) and [04bb9d6b](https://github.com/ruby/ruby/commit/04bb9d6b75a55d4000700769eead5a5cb942c25b) were backported all the way from HEAD to 1.9. Moreover, there is no simple way to track these changes.
+
+This policy makes it all but impossible to make Parser precisely compatible with the Ruby MRI parser. Indeed, at September 2014, it would be necessary to maintain and update ten different parsers together with their lexer quirks in order to be able to emulate any given released Ruby MRI version.
+
+As a result, Parser chooses a different path: the `parser/rubyXY` parsers recognize the syntax of the latest minor version of Ruby MRI X.Y at the time of the gem release.
+
+## Known issues
+
+Adding support for the following Ruby MRI features in Parser would needlessly complicate it, and as they all are very specific and rarely occuring corner cases, this is not done.
+
+Parser has been extensively tested; in particular, it parses almost entire [Rubygems][rg] corpus. For every issue, a breakdown of affected gems is offered.
+
+ [rg]: https://rubygems.org
+
+### Void value expressions
+
+Ruby MRI prohibits so-called "void value expressions". For a description
+of what a void value expression is, see [this
+gist](https://gist.github.com/JoshCheek/5625007) and [this Parser
+issue](https://github.com/whitequark/parser/issues/72).
+
+It is unknown whether any gems are affected by this issue.
+
+### Invalid characters inside comments
+
+Ruby MRI permits arbitrary non-7-bit characters to appear in comments regardless of source encoding.
+
+As of 2013-07-25, there are about 180 affected gems.
+
+### \u escape in 1.8 mode
+
+Ruby MRI 1.8 permits to specify a bare `\u` escape sequence in a string; it treats it like `u`. Ruby MRI 1.9 and later treat `\u` as a prefix for Unicode escape sequence and do not allow it to appear bare. Parser follows 1.9+ behavior.
+
+As of 2013-07-25, affected gems are: activerdf, activerdf_net7, fastreader, gkellog-reddy.
+
+### Invalid Unicode escape sequences
+
+Ruby MRI 1.9+ permits to specify invalid Unicode codepoints in Unicode escape sequences, such as `\u{d800}`.
+
+As of 2013-07-25, affected gems are: aws_cloud_search.
+
+### Dollar-dash
+
+(This one is so obscure I couldn't even think of a saner name for this issue.) Pre-2.1 Ruby allows
+to specify a global variable named `$-`. Ruby 2.1 and later treat it as a syntax error. Parser
+follows 2.1 behavior.
+
+No known code is affected by this issue.
+
+## Contributors
+
+* Peter Zotov ([whitequark][])
+* Markus Schirp ([mbj][])
+* Yorick Peterse ([yorickpeterse][])
+* Magnus Holm ([judofyr][])
+* Bozhidar Batsov ([bbatsov][])
+
+[whitequark]:     https://github.com/whitequark
+[mbj]:            https://github.com/mbj
+[yorickpeterse]:  https://github.com/yorickpeterse
+[judofyr]:        https://github.com/judofyr
+[bbatsov]:        https://github.com/bbatsov
+
+## Acknowledgements
+
+The lexer testsuite is derived from
+[ruby\_parser](https://github.com/seattlerb/ruby_parser).
+
+The Bison parser rules are derived from [Ruby MRI](https://github.com/ruby/ruby)
+parse.y.
+
+## Contributing
+
+1. Make sure you have [Ragel ~> 6.7](http://www.complang.org/ragel/) installed
+2. Fork it
+3. Create your feature branch (`git checkout -b my-new-feature`)
+4. Commit your changes (`git commit -am 'Add some feature'`)
+5. Push to the branch (`git push origin my-new-feature`)
+6. Create new Pull Request
diff --git a/app/server/vendor/parser-2.2.2.1/Rakefile b/app/server/vendor/parser-2.2.2.1/Rakefile
new file mode 100644
index 0000000..e4c1b1a
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/Rakefile
@@ -0,0 +1,146 @@
+# encoding:utf-8
+
+require 'bundler/gem_tasks'
+require 'rake/testtask'
+require 'rake/clean'
+
+task :default => [:test]
+
+Rake::TestTask.new do |t|
+  t.libs       = %w(test/ lib/)
+  t.test_files = FileList["test/**/test_*.rb"]
+end
+
+task :test_cov do
+  ENV['COVERAGE'] = '1'
+  Rake::Task['test'].invoke
+end
+
+task :build => [:generate_release, :changelog]
+
+GENERATED_FILES = %w(lib/parser/lexer.rb
+                     lib/parser/ruby18.rb
+                     lib/parser/ruby19.rb
+                     lib/parser/ruby20.rb
+                     lib/parser/ruby21.rb
+                     lib/parser/ruby22.rb)
+
+CLEAN.include(GENERATED_FILES)
+
+desc 'Generate the Ragel lexer and Bison parser.'
+task :generate => GENERATED_FILES do
+  Rake::Task[:ragel_check].invoke
+  GENERATED_FILES.each do |filename|
+    content = File.read(filename)
+    content = "# -*- encoding:utf-8; warn-indent:false -*-\n" + content
+
+    File.open(filename, 'w') do |io|
+      io.write content
+    end
+  end
+end
+
+task :regenerate => [:clean, :generate]
+
+desc 'Generate the Ragel lexer and Bison parser in release mode.'
+task :generate_release => [:clean_env, :regenerate]
+
+task :clean_env do
+  ENV.delete 'RACC_DEBUG'
+end
+
+task :ragel_check do
+  require 'cliver'
+  Cliver.assert('ragel', '~> 6.7')
+end
+
+desc 'Generate YARD documentation'
+task :yard => :generate do
+  sh('yard doc')
+end
+
+PAGES_REPO = 'git at github.com:whitequark/parser'
+
+desc "Build and deploy documentation to GitHub pages"
+task :pages do
+  system "git clone #{PAGES_REPO} gh-temp/ -b gh-pages; rm gh-temp/* -rf; touch gh-temp/.nojekyll" or abort
+  system "yardoc -o gh-temp/;" or abort
+  system "cd gh-temp/; git add -A; git commit -m 'Updated pages.'; git push -f origin gh-pages" or abort
+  FileUtils.rm_rf 'gh-temp'
+end
+
+desc 'Generate Changelog'
+task :changelog do
+  fs     = "\u{fffd}"
+  format = "%d#{fs}%s#{fs}%an#{fs}%ai"
+
+  # Format: version => { commit-class => changes }
+  changelog = Hash.new do |hash, version|
+    hash[version] = Hash.new do |hash, klass|
+      hash[klass] = []
+    end
+  end
+
+  IO.popen("git log --pretty='#{format}' remotes/origin/2.0 remotes/origin/2.1 master", 'r') do |io|
+    current_version = nil
+
+    io.each_line do |line|
+      version, message, author, date = line.
+            match(/^(?: \((.*)\))?#{fs}(.*)#{fs}(.*)#{fs}(.*)$/o).captures
+      date = Date.parse(date)
+
+      current_version = "#{$1} (#{date})" if version =~ /(v[\d\w.]+)/
+      current_version = "v#{Parser::VERSION} (#{date})" if version =~ /HEAD/
+
+      next if current_version.nil? || message !~ /^[+*-]/
+
+      changelog[current_version][message[0]] << "#{message[1..-1]} (#{author})"
+    end
+  end
+
+  commit_classes = {
+    '*' => 'API modifications:',
+    '+' => 'Features implemented:',
+    '-' => 'Bugs fixed:',
+  }
+
+  File.open('CHANGELOG.md', 'w') do |io|
+    io.puts 'Changelog'
+    io.puts '========='
+    io.puts
+
+    changelog.each do |version, commits|
+      io.puts version
+      io.puts '-' * version.length
+      io.puts
+
+      commit_classes.each do |sigil, description|
+        next unless commits[sigil].any?
+
+        io.puts description
+        commits[sigil].uniq.each do |commit|
+          io.puts " * #{commit.gsub('<', '\<').lstrip}"
+        end
+        io.puts
+      end
+    end
+  end
+
+  sh('git commit CHANGELOG.md -m "Update changelog." || true')
+end
+
+rule '.rb' => '.rl' do |t|
+  sh "ragel -F1 -R #{t.source} -o #{t.name}"
+end
+
+rule '.rb' => '.y' do |t|
+  opts = [ "--superclass=Parser::Base",
+           t.source,
+           "-o", t.name
+         ]
+  opts << "--debug" if ENV['RACC_DEBUG']
+
+  sh "racc", *opts
+end
+
+task :test => [:generate]
diff --git a/app/server/vendor/parser-2.2.2.1/bin/ruby-parse b/app/server/vendor/parser-2.2.2.1/bin/ruby-parse
new file mode 100755
index 0000000..e55c2f4
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/bin/ruby-parse
@@ -0,0 +1,6 @@
+#!/usr/bin/env ruby
+
+$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
+require 'parser/runner/ruby_parse'
+
+Parser::Runner::RubyParse.go(ARGV)
diff --git a/app/server/vendor/parser-2.2.2.1/bin/ruby-rewrite b/app/server/vendor/parser-2.2.2.1/bin/ruby-rewrite
new file mode 100755
index 0000000..08adc64
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/bin/ruby-rewrite
@@ -0,0 +1,6 @@
+#!/usr/bin/env ruby
+
+$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
+require 'parser/runner/ruby_rewrite'
+
+Parser::Runner::RubyRewrite.go(ARGV)
diff --git a/app/server/vendor/parser-2.2.2.1/doc/AST_FORMAT.md b/app/server/vendor/parser-2.2.2.1/doc/AST_FORMAT.md
new file mode 100644
index 0000000..901a606
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/doc/AST_FORMAT.md
@@ -0,0 +1,1578 @@
+AST and Source Location
+=======================
+
+## Literals
+
+### Singletons
+
+Format:
+
+~~~
+(true)
+"true"
+ ~~~~ expression
+
+(false)
+"false"
+ ~~~~~ expression
+
+(nil)
+"nil"
+ ~~~ expression
+~~~
+
+### Integer
+
+Format:
+
+~~~
+(int 123)
+"123"
+ ~~~ expression
+
+(int -123)
+"-123"
+ ^ operator
+ ~~~ expression
+
+(int 1)
+"__LINE__"
+ ~~~~~~~~ expression
+~~~
+
+### Float
+
+Format:
+
+~~~
+(float 1.0)
+"1.0"
+ ~~~ expression
+
+(float -1.0)
+"-1.0"
+ ^ operator
+ ~~~~ expression
+~~~
+
+### Complex
+
+Format:
+
+~~~
+(complex (0+1i))
+"1i"
+ ~~ expression
+
+(complex (0+(1/1)*i))
+"1ri"
+ ~~~ expression
+~~~
+
+### Rational
+
+Format:
+
+~~~
+(rational (2/1))
+"2.0r"
+ ~~~~ expression
+~~~
+
+### String
+
+#### Plain
+
+Format:
+
+~~~
+(str "foo")
+"'foo'"
+ ^ begin
+     ^ end
+ ~~~~~ expresion
+
+(string "foo.rb")
+"__FILE__"
+ ~~~~~~~~ expression
+~~~
+
+#### With interpolation
+
+Format:
+
+~~~
+(dstr (str "foo") (lvar bar) (str "baz"))
+'"foo#{bar}baz"'
+ ^ begin      ^ end
+ ~~~~~~~~~~~~~~ expression
+~~~
+
+#### Here document
+
+Format:
+
+~~~
+(str "foo\nbar\n")
+'<<HERE␊foo␊bar␊HERE'
+ ~~~~~~ expression
+        ~~~~~~~~ heredoc_body
+                ~~~~ heredoc_end
+~~~
+
+### Symbol
+
+#### Plain
+
+Format:
+
+~~~
+(sym :foo)
+":foo"
+ ~~~~ expresion
+
+":'foo'"
+  ^ begin
+      ^ end
+ ~~~~~~ expression
+~~~
+
+#### With interpolation
+
+Format:
+
+~~~
+(dsym (str "foo") (lvar bar) (str "baz"))
+':"foo#{bar}baz"'
+  ^ begin      ^ end
+ ~~~~~~~~~~~~~~~ expression
+~~~
+
+### Execute-string
+
+#### Plain
+
+Format:
+
+~~~
+(xstr (str "foo") (lvar bar))
+"`foo#{bar}`"
+ ^ begin   ^ end
+ ~~~~~~~~~~~ expression
+~~~
+
+#### Here document
+
+Format:
+
+~~~
+(xstr (str "foo\nbar\n"))
+"<<`HERE`␊foo␊bar␊HERE"
+ ~~~~~~~~ expression
+          ~~~~~~~~ heredoc_body
+                  ~~~~ heredoc_end
+~~~
+
+### Regexp
+
+#### Options
+
+Format:
+
+~~~
+(regopt :i :m)
+"im"
+ ~~ expression
+~~~
+
+#### Regexp
+
+Format:
+
+~~~
+(regexp (str "foo") (lvar :bar) (regopt :i))
+"/foo#{bar}/i"
+ ^ begin   ^ end
+ ~~~~~~~~~~~ expression
+~~~
+
+### Array
+
+#### Plain
+
+Format:
+
+~~~
+(array (int 1) (int 2))
+
+"[1, 2]"
+ ^ begin
+      ^ end
+ ~~~~~~ expression
+~~~
+
+#### Splat
+
+Can also be used in argument lists: `foo(bar, *baz)`
+
+Format:
+
+~~~
+(splat (lvar :foo))
+"*foo"
+ ^ operator
+ ~~~~ expression
+~~~
+
+#### With interpolation
+
+Format:
+
+~~~
+(array (int 1) (splat (lvar :foo)) (int 2))
+
+"[1, *foo, 2]"
+ ^ begin    ^ end
+ ~~~~~~~~~~~~ expression
+~~~
+
+### Hash
+
+#### Pair
+
+##### With hashrocket
+
+Format:
+
+~~~
+(pair (int 1) (int 2))
+"1 => 2"
+   ~~ operator
+ ~~~~~~ expression
+~~~
+
+##### With label (1.9)
+
+Format:
+
+~~~
+(pair (sym :answer) (int 42))
+"answer: 42"
+       ^ operator (pair)
+ ~~~~~~ expression (sym)
+ ~~~~~~~~~~ expression (pair)
+~~~
+
+#### Plain
+
+Format:
+
+~~~
+(hash (pair (int 1) (int 2)) (pair (int 3) (int 4)))
+"{1 => 2, 3 => 4}"
+ ^ begin        ^ end
+ ~~~~~~~~~~~~~~~~ expression
+~~~
+
+#### Keyword splat (2.0)
+
+Can also be used in argument lists: `foo(bar, **baz)`
+
+Format:
+
+~~~
+(kwsplat (lvar :foo))
+"**foo"
+ ~~ operator
+ ~~~~~ expression
+~~~
+
+#### With interpolation (2.0)
+
+Format:
+
+~~~
+(hash (pair (sym :foo) (int 2)) (kwsplat (lvar :bar)))
+"{ foo: 2, **bar }"
+ ^ begin         ^ end
+ ~~~~~~~~~~~~~~~~~ expression
+~~~
+
+### Range
+
+#### Inclusive
+
+Format:
+
+~~~
+(irange (int 1) (int 2))
+"1..2"
+  ~~ operator
+ ~~~~ expression
+~~~
+
+#### Exclusive
+
+Format:
+
+~~~
+(erange (int 1) (int 2))
+"1...2"
+  ~~~ operator
+ ~~~~~ expression
+~~~
+
+## Access
+
+### Self
+
+Format:
+
+~~~
+(self)
+"self"
+ ~~~~ expression
+~~~
+
+### Local variable
+
+Format:
+
+~~~
+(lvar :foo)
+"foo"
+ ~~~ expression
+~~~
+
+### Instance variable
+
+Format:
+
+~~~
+(ivar :@foo)
+"@foo"
+ ~~~~ expression
+~~~
+
+### Class variable
+
+Format:
+
+~~~
+(cvar :@@foo)
+"@@foo"
+ ~~~~~ expression
+~~~
+
+### Global variable
+
+#### Regular global variable
+
+Format:
+
+~~~
+(gvar :$foo)
+"$foo"
+ ~~~~ expression
+~~~
+
+#### Regular expression capture groups
+
+Format:
+
+~~~
+(nth-ref 1)
+"$1"
+ ~~ expression
+~~~
+
+#### Regular expression back-references
+
+Format:
+
+~~~
+(back-ref :$&)
+"$&"
+ ~~ expression
+(back-ref :$`)
+"$`"
+(back-ref :$')
+"$'"
+(back-ref :$+)
+"$+"
+~~~
+
+### Constant
+
+#### Top-level constant
+
+Format:
+
+~~~
+(const (cbase) :Foo)
+"::Foo"
+   ~~~ name
+ ~~ double_colon
+ ~~~~~ expression
+~~~
+
+#### Scoped constant
+
+Format:
+
+~~~
+(const (lvar :a) :Foo)
+"a::Foo"
+    ~~~ name
+  ~~ double_colon
+ ~~~~~~ expression
+~~~
+
+#### Unscoped constant
+
+Format:
+
+~~~
+(const nil :Foo)
+"Foo"
+ ~~~ name
+ ~~~ expression
+~~~
+
+### defined?
+
+Format:
+
+~~~
+(defined? (lvar :a))
+"defined? a"
+ ~~~~~~~~ keyword
+ ~~~~~~~~~~ expression
+
+"defined?(a)"
+ ~~~~~~~~ keyword
+         ^ begin
+           ^ end
+ ~~~~~~~~~~~ expression
+~~~
+
+## Assignment
+
+### To local variable
+
+Format:
+
+~~~
+(lvasgn :foo (lvar :bar))
+"foo = bar"
+     ^ operator
+ ~~~~~~~~~ expression
+~~~
+
+### To instance variable
+
+Format:
+
+~~~
+(ivasgn :@foo (lvar :bar))
+"@foo = bar"
+      ^ operator
+ ~~~~~~~~~~ expression
+~~~
+
+### To class variable
+
+Format:
+
+~~~
+(cvasgn :@@foo (lvar :bar))
+"@@foo = bar"
+       ^ operator
+ ~~~~~~~~~~~ expression
+~~~
+
+### To global variable
+
+Format:
+
+~~~
+(gvasgn :$foo (lvar :bar))
+"$foo = bar"
+      ^ operator
+ ~~~~~~~~~~ expression
+~~~
+
+### To constant
+
+#### Top-level constant
+
+Format:
+
+~~~
+(casgn (cbase) :Foo (int 1))
+"::Foo = 1"
+   ~~~ name
+       ~ operator
+ ~~~~~~~ expression
+~~~
+
+#### Scoped constant
+
+Format:
+
+~~~
+(casgn (lvar :a) :Foo (int 1))
+"a::Foo = 1"
+    ~~~ name
+        ~ operator
+ ~~~~~~~~ expression
+~~~
+
+#### Unscoped constant
+
+Format:
+
+~~~
+(casgn nil :Foo (int 1))
+"Foo = 1"
+ ~~~ name
+     ~ operator
+ ~~~~~~~ expression
+~~~
+
+
+### Multiple assignment
+
+#### Multiple left hand side
+
+Format:
+
+~~~
+(mlhs (lvasgn :a) (lvasgn :b))
+"a, b"
+ ~~~~ expression
+"(a, b)"
+ ^ begin
+      ^ end
+ ~~~~~~ expression
+~~~
+
+#### Assignment
+
+Rule of thumb: every node inside `(mlhs)` is "incomplete"; to make
+it "complete", one could imagine that a corresponding node from the
+mrhs is "appended" to the node in question. This applies both to
+side-effect free assignments (`lvasgn`, etc) and side-effectful
+assignments (`send`).
+
+Format:
+
+~~~
+(masgn (mlhs (lvasgn :foo) (lvasgn :bar)) (array (int 1) (int 2)))
+"foo, bar = 1, 2"
+          ^ operator
+ ~~~~~~~~~~~~~~~ expression
+
+(masgn (mlhs (ivasgn :@a) (cvasgn :@@b)) (array (splat (lvar :c))))
+"@a, @@b = *c"
+
+(masgn (mlhs (mlhs (lvasgn :a) (lvasgn :b)) (lvasgn :c)) (lvar :d))
+"a, (b, c) = d"
+
+(masgn (mlhs (send (self) :a=) (send (self) :[]= (int 1))) (lvar :a))
+"self.a, self[1] = a"
+~~~
+
+### Binary operator-assignment
+
+Binary operator-assignment features the same "incomplete assignments" and "incomplete calls" as [multiple assignment](#assignment-1).
+
+#### Variable binary operator-assignment
+
+Format:
+
+~~~
+(op-asgn (lvasgn :a) :+ (int 1))
+"a += 1"
+   ~~ operator
+ ~~~~~~ expression
+
+(op-asgn (ivasgn :a) :+ (int 1))
+"@a += 1"
+~~~
+
+Ruby_parser output for reference:
+~~~
+"a += 1"
+s(:lasgn, :a, s(:call, s(:lvar, :a), :+, s(:int, 1)))
+
+"@a += 1"
+s(:iasgn, :@a, s(:call, s(:ivar, :@a), :+, s(:int, 1)))
+~~~
+
+#### Method binary operator-assignment
+
+Format:
+
+~~~
+(op-asgn (send (ivar :@a) :b) :+ (int 1))
+"@a.b += 1"
+    ~ selector (send)
+ ~~~~ expression (send)
+      ~~ operator (op-asgn)
+ ~~~~~~~~~ expression (op-asgn)
+
+(op-asgn (send (ivar :@a) :[] (int 0) (int 1))) :+ (int 1))
+"@a[0, 1] += 1"
+   ~~~~~~ selector (send)
+ ~~~~~~~~ expression (send)
+          ~~ operator (op-asgn)
+ ~~~~~~~~~~~~~ expression (op-asgn)
+~~~
+
+Ruby_parser output for reference:
+~~~
+"@a.b += 1"
+s(:op_asgn2, s(:ivar, :@a), :b=, :+, s(:int, 1))
+
+"@a[0, 1] += 1"
+s(:op_asgn1, s(:ivar, :@a), s(:arglist, s(:int, 0), s(:int, 1)), :+, s(:int, 1))
+~~~
+
+### Logical operator-assignment
+
+Logical operator-assignment features the same "incomplete assignments" and "incomplete calls" as [multiple assignment](#assignment-1).
+
+#### Variable logical operator-assignment
+
+Format:
+
+~~~
+(or-asgn (ivasgn :@a) (int 1))
+"@a ||= 1"
+    ~~~ operator
+ ~~~~~~~~ expression
+
+(and-asgn (lvasgn :a) (int 1))
+"a &&= 1"
+   ~~~ operator
+ ~~~~~~~ expression
+~~~
+
+Ruby_parser output for reference:
+~~~
+"@a ||= 1"
+s(:op_asgn_or, s(:ivar, :@a), s(:ivasgn, :@a, s(:int, 1)))
+
+"a &&= 1"
+s(:op_asgn_and, s(:lvar, :a), s(:lvasgn, :a, s(:int, 1)))
+~~~
+
+#### Method logical operator-assignment
+
+Format:
+
+~~~
+(or-asgn (send (ivar :@foo) :bar) (int 1))
+"@foo.bar ||= 1"
+      ~~~ selector (send)
+ ~~~~~~~~ expr (send)
+          ~~~ operator (or-asgn)
+ ~~~~~~~~~~~~~~ expression (or-asgn)
+
+(and-asgn (send (lvar :@foo) :bar) (int 1))
+"foo.bar &&= 1"
+     ~~~ selector (send)
+ ~~~~~~~ expr (send)
+         ~~~ operator (and-asgn)
+ ~~~~~~~~~~~~~ expression (and-asgn)
+
+(or-asgn (send (ivar :@foo) :[] (int 1) (int 2)) (int 1))
+"@foo[1, 2] ||= 1"
+     ~~~~~~ selector (send)
+ ~~~~~~~~~~ expr (send)
+            ~~~ operator (or-asgn)
+ ~~~~~~~~~~~~~~~~ expression (or-asgn)
+
+~~~
+
+Ruby_parser output for reference:
+~~~
+"@foo.bar &&= 1"
+s(:op_asgn2, s(:ivar, :@foo), :bar=, :"&&", s(:int, 1))
+
+"@foo[0] ||= 1"
+s(:op_asgn1, s(:ivar, :@foo), s(:arglist, s(:int, 0)), :"||", s(:int, 1))
+
+~~~
+
+## Class and module definition
+
+### Module
+
+Format:
+
+~~~
+(module (const nil :Foo) (nil))
+"module Foo; end"
+ ~~~~~~ keyword
+             ~~~ end
+~~~
+
+### Class
+
+Format:
+
+~~~
+(class (const nil :Foo) (const nil :Bar) (nil))
+"class Foo < Bar; end"
+ ~~~~~ keyword    ~~~ end
+           ~ operator
+ ~~~~~~~~~~~~~~~~~~~~ expression
+
+(class (const nil :Foo) nil (nil))
+"class Foo; end"
+ ~~~~~ keyword
+            ~~~ end
+ ~~~~~~~~~~~~~~ expression
+~~~
+
+### Singleton class
+
+Format:
+
+~~~
+(sclass (lvar :a) (nil))
+"class << a; end"
+ ~~~~~ keyword
+       ~~ operator
+             ~~~ end
+ ~~~~~~~~~~~~~~~ expression
+~~~
+
+## Method (un)definition
+
+### Instance methods
+
+Format:
+
+~~~
+(def :foo (args) nil)
+"def foo; end"
+ ~~~ keyword
+     ~~~ name
+          ~~~ end
+ ~~~~~~~~~~~~ expression
+~~~
+
+### Singleton methods
+
+Format:
+
+~~~
+(defs (self) (args) nil)
+"def self.foo; end"
+ ~~~ keyword
+          ~~~ name
+               ~~~ end
+ ~~~~~~~~~~~~~~~~~ expression
+~~~
+
+### Undefinition
+
+Format:
+
+~~~
+(undef (sym :foo) (sym :bar) (dsym (str "foo") (int 1)))
+"undef foo :bar :"foo#{1}""
+ ~~~~~ keyword
+ ~~~~~~~~~~~~~~~~~~~~~~~~~ expression
+~~~
+
+## Aliasing
+
+### Method aliasing
+
+Format:
+
+~~~
+(alias (sym :foo) (dsym (str "foo") (int 1)))
+"alias foo :"foo#{1}""
+ ~~~~~ keyword
+ ~~~~~~~~~~~~~~~~~~~~ expression
+~~~
+
+### Global variable aliasing
+
+Format:
+
+~~~
+(alias (gvar :$foo) (gvar :$bar))
+"alias $foo $bar"
+ ~~~~~ keyword
+ ~~~~~~~~~~~~~~~ expression
+
+(alias (gvar :$foo) (back-ref :$&))
+"alias $foo $&"
+ ~~~~~ keyword
+ ~~~~~~~~~~~~~~~ expression
+~~~
+
+## Formal arguments
+
+Format:
+
+~~~
+(args (arg :foo))
+"(foo)"
+ ~~~~~ expression
+~~~
+
+### Required argument
+
+Format:
+
+~~~
+(arg :foo)
+"foo"
+ ~~~ expression
+ ~~~ name
+~~~
+
+### Optional argument
+
+Format:
+
+~~~
+(optarg :foo (int 1))
+"foo = 1"
+ ~~~~~~~ expression
+     ^ operator
+ ~~~ name
+~~~
+
+### Named splat argument
+
+Format:
+
+~~~
+(restarg :foo)
+"*foo"
+ ~~~~ expression
+  ~~~ name
+~~~
+
+Begin of the `expression` points to `*`.
+
+### Unnamed splat argument
+
+Format:
+
+~~~
+(restarg)
+"*"
+ ^ expression
+~~~
+
+### Block argument
+
+Format:
+
+~~~
+(blockarg :foo)
+"&foo"
+  ~~~ name
+ ~~~~ expression
+~~~
+
+Begin of the `expression` points to `&`.
+
+### Expression arguments
+
+Ruby 1.8 allows to use arbitrary expressions as block arguments,
+such as `@var` or `foo.bar`. Such expressions should be treated as
+if they were on the lhs of a multiple assignment.
+
+Format:
+
+~~~
+(args (arg_expr (ivasgn :@bar)))
+"|@bar|"
+
+(args (arg_expr (send (send nil :foo) :a=)))
+"|foo.a|"
+
+(args (restarg_expr (ivasgn :@bar)))
+"|*@bar|"
+
+(args (blockarg_expr (ivasgn :@bar)))
+"|&@bar|"
+~~~
+
+### Block shadow arguments
+
+Format:
+
+~~~
+(args (shadowarg :foo) (shadowarg :bar))
+"|; foo, bar|"
+~~~
+
+### Decomposition
+
+Format:
+
+~~~
+(def :f (args (arg :a) (mlhs (arg :foo) (restarg :bar))))
+"def f(a, (foo, *bar)); end"
+          ^ begin   ^ end
+          ~~~~~~~~~~~ expression
+~~~
+
+### Required keyword argument
+
+Format:
+
+~~~
+(kwarg :foo (int 1))
+"foo:"
+ ~~~~ expression
+ ~~~~ name
+~~~
+
+### Optional keyword argument
+
+Format:
+
+~~~
+(kwoptarg :foo (int 1))
+"foo: 1"
+ ~~~~~~ expression
+ ~~~~ name
+~~~
+
+### Named keyword splat argument
+
+Format:
+
+~~~
+(kwrestarg :foo)
+"**foo"
+ ~~~~~ expression
+   ~~~ name
+~~~
+
+### Unnamed keyword splat argument
+
+Format:
+
+~~~
+(kwrestarg)
+"**"
+ ~~ expression
+~~~
+
+## Send
+
+### To self
+
+Format:
+
+~~~
+(send nil :foo (lvar :bar))
+"foo(bar)"
+ ~~~ selector
+    ^ begin
+        ^ end
+ ~~~~~~~~ expression
+~~~
+
+### To receiver
+
+Format:
+
+~~~
+(send (lvar :foo) :bar (int 1))
+"foo.bar(1)"
+     ~~~ selector
+        ^ begin
+          ^ end
+ ~~~~~~~~~~ expression
+
+(send (lvar :foo) :+ (int 1))
+"foo + 1"
+     ^ selector
+ ~~~~~~~ expression
+
+(send (lvar :foo) :-@)
+"-foo"
+ ^ selector
+ ~~~~ expression
+
+(send (lvar :foo) :a= (int 1))
+"foo.a = 1"
+     ~ selector
+       ^ operator
+ ~~~~~~~~~ expression
+
+(send (lvar :foo) :[] (int 1))
+"foo[i]"
+    ~~~ selector
+ ~~~~~~ expression
+
+(send (lvar :bar) :[]= (int 1) (int 2) (lvar :baz))
+"bar[1, 2] = baz"
+    ~~~~~~ selector
+           ^ operator
+ ~~~~~~~~~~~~~~~ expression
+
+~~~
+
+### To superclass
+
+Format of super with arguments:
+~~~
+(super (lvar :a))
+"super a"
+ ~~~~~ keyword
+ ~~~~~~~ expression
+
+(super)
+"super()"
+      ^ begin
+       ^ end
+ ~~~~~ keyword
+ ~~~~~~~ expression
+~~~
+
+Format of super without arguments (**z**ero-arity):
+~~~
+(zsuper)
+"super"
+ ~~~~~ keyword
+ ~~~~~ expression
+~~~
+
+### To block argument
+
+Format:
+
+~~~
+(yield (lvar :foo))
+"yield(foo)"
+ ~~~~~ keyword
+      ^ begin
+          ^ end
+ ~~~~~~~~~~ expression
+~~~
+
+### Passing a literal block
+
+~~~
+(block (send nil :foo) (args (arg :bar)) (begin ...))
+"foo do |bar|; end"
+     ~~ begin
+               ~~~ end
+     ~~~~~~~~~~~~~ expression
+~~~
+
+### Passing expression as block
+
+Used when passing expression as block `foo(&bar)`
+
+~~~
+(send nil :foo (int 1) (block-pass (lvar :foo)))
+"foo(1, &foo)"
+        ^ operator
+        ~~~~ expression
+~~~
+
+## Control flow
+
+### Logical operators
+
+#### Binary (and or && ||)
+
+Format:
+
+~~~
+(and (lvar :foo) (lvar :bar))
+"foo and bar"
+     ~~~ operator
+ ~~~~~~~~~~~ expression
+~~~
+
+~~~
+(or (lvar :foo) (lvar :bar))
+"foo or bar"
+     ~~ operator
+ ~~~~~~~~~~ expression
+~~~
+
+#### Unary (! not) (1.8)
+
+Format:
+
+~~~
+(not (lvar :foo))
+"!foo"
+ ^ operator
+"not foo"
+ ~~~ operator
+~~~
+
+### Branching
+
+#### Without else
+
+Format:
+
+~~~
+(if (lvar :cond) (lvar :iftrue) nil)
+"if cond then iftrue; end"
+ ~~ keyword
+         ~~~~ begin
+                      ~~~ end
+ ~~~~~~~~~~~~~~~~~~~~~~~~ expression
+
+"if cond; iftrue; end"
+ ~~ keyword
+                  ~~~ end
+ ~~~~~~~~~~~~~~~~~~~~ expression
+
+"iftrue if cond"
+        ~~ keyword
+ ~~~~~~~~~~~~~~ expression
+
+(if (lvar :cond) nil (lvar :iftrue))
+"unless cond then iftrue; end"
+ ~~~~~~ keyword
+             ~~~~ begin
+                          ~~~ end
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
+
+"unless cond; iftrue; end"
+ ~~~~~~ keyword
+                      ~~~ end
+ ~~~~~~~~~~~~~~~~~~~~~~~~ expression
+
+"iftrue unless cond"
+        ~~~~~~ keyword
+ ~~~~~~~~~~~~~~~~~~ expression
+~~~
+
+#### With else
+
+Format:
+
+~~~
+(if (lvar :cond) (lvar :iftrue) (lvar :iffalse))
+"if cond then iftrue; else; iffalse; end"
+ ~~ keyword
+         ~~~~ begin
+                      ~~~~ else
+                                 ~~~ end
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
+
+"if cond; iftrue; else; iffalse; end"
+ ~~ keyword
+                  ~~~~ else
+                                 ~~~ end
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
+
+(if (lvar :cond) (lvar :iffalse) (lvar :iftrue))
+"unless cond then iftrue; else; iffalse; end"
+ ~~~~~~ keyword
+             ~~~~ begin
+                          ~~~~ else
+                                     ~~~ end
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
+
+"unless cond; iftrue; else; iffalse; end"
+ ~~~~~~ keyword
+                      ~~~~ else
+                                     ~~~ end
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
+~~~
+
+#### With elsif
+
+Format:
+
+~~~
+(if (lvar :cond1) (int 1) (if (lvar :cond2 (int 2) (int 3))))
+"if cond1; 1; elsif cond2; 2; else 3; end"
+ ~~ keyword (left)
+              ~~~~~ else (left)
+                                      ~~~ end (left)
+              ~~~~~ keyword (right)
+                              ~~~~ else (right)
+                                      ~~~ end (right)
+~~~
+
+#### Ternary
+
+Format:
+
+~~~
+(if (lvar :cond) (lvar :iftrue) (lvar :iffalse))
+"cond ? iftrue : iffalse"
+      ^ question
+               ^ colon
+ ~~~~~~~~~~~~~~~~~~~~~~~ expression
+~~~
+
+### Case matching
+
+#### When clause
+
+Format:
+
+~~~
+(when (regexp "foo" (regopt)) (begin (lvar :bar)))
+"when /foo/ then bar"
+ ~~~~ keyword
+            ~~~~ begin
+ ~~~~~~~~~~~~~~~~~~~ expression
+
+(when (int 1) (int 2) (send nil :meth))
+"when 1, 2; meth"
+
+(when (int 1) (splat (lvar :foo)) (send nil :meth))
+"when 1, *foo; meth"
+
+(when (splat (lvar :foo)) (send nil :meth))
+"when *foo; meth"
+~~~
+
+#### Case-expression clause
+
+##### Without else
+
+Format:
+
+~~~
+(case (lvar :foo) (when (str "bar") (lvar :bar)) nil)
+"case foo; when "bar"; bar; end"
+ ~~~~ keyword               ~~~ end
+~~~
+
+##### With else
+
+Format:
+
+~~~
+(case (lvar :foo) (when (str "bar") (lvar :bar)) (lvar :baz))
+"case foo; when "bar"; bar; else baz; end"
+ ~~~~ keyword               ~~~~ else ~~~ end
+~~~
+
+#### Case-conditions clause
+
+##### Without else
+
+Format:
+
+~~~
+(case nil (when (lvar :bar) (lvar :bar)) nil)
+"case; when bar; bar; end"
+ ~~~~ keyword         ~~~ end
+~~~
+
+##### With else
+
+Format:
+
+~~~
+(case nil (when (lvar :bar) (lvar :bar)) (lvar :baz))
+"case; when bar; bar; else baz; end"
+ ~~~~ keyword         ~~~~ else ~~~ end
+
+(case nil (lvar :baz))
+"case; else baz; end"
+ ~~~~ keyword
+       ~~~~ else
+                 ~~~ end
+~~~
+
+### Looping
+
+#### With precondition
+
+Format:
+
+~~~
+(while (lvar :condition) (send nil :foo))
+"while condition do foo; end"
+ ~~~~~ keyword
+                 ~~ begin
+                         ~~~ end
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
+
+"while condition; foo; end"
+ ~~~~~ keyword
+                       ~~~ end
+ ~~~~~~~~~~~~~~~~~~~~~~~~~ expression
+
+"foo while condition"
+     ~~~~~ keyword
+ ~~~~~~~~~~~~~~~~~~~ expression
+
+(until (lvar :condition) (send nil :foo))
+"until condition do foo; end"
+ ~~~~~ keyword
+                 ~~ begin
+                         ~~~ end
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
+
+(until (lvar :condition) (send nil :foo))
+"until condition; foo; end"
+ ~~~~~ keyword
+                       ~~~ end
+~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
+
+"foo until condition"
+     ~~~~~ keyword
+ ~~~~~~~~~~~~~~~~~~~ expression
+~~~
+
+#### With postcondition
+
+Format:
+
+~~~
+(while-post (lvar :condition) (kwbegin (send nil :foo)))
+"begin; foo; end while condition"
+ ~~~~~ begin (begin)
+             ~~~ end (begin)
+                 ~~~~~ keyword (while-post)
+
+(until-post (lvar :condition) (kwbegin (send nil :foo)))
+"begin; foo; end until condition"
+ ~~~~~ begin (begin)
+             ~~~ end (begin)
+                 ~~~~~ keyword (until-post)
+~~~
+
+#### For-in
+
+Format:
+
+~~~
+(for (lvasgn :a) (lvar :array) (send nil :p (lvar :a)))
+"for a in array do p a; end"
+ ~~~ keyword
+       ~~ in
+                ~~ begin
+                        ~~~ end
+
+"for a in array; p a; end"
+ ~~~ keyword
+       ~~ in
+                      ~~~ end
+
+(for
+  (mlhs (lvasgn :a) (lvasgn :b)) (lvar :array)
+  (send nil :p (lvar :a) (lvar :b)))
+"for a, b in array; p a, b; end"
+~~~
+
+#### Break
+
+Format:
+
+~~~
+(break (int 1))
+"break 1"
+ ~~~~~ keyword
+ ~~~~~~~ expression
+~~~
+
+#### Next
+
+Format:
+
+~~~
+(next (int 1))
+"next 1"
+ ~~~~ keyword
+ ~~~~~~ expression
+~~~
+
+#### Redo
+
+Format:
+
+~~~
+(redo)
+"redo"
+ ~~~~ keyword
+ ~~~~ expression
+~~~
+
+### Return
+
+Format:
+
+~~~
+(return (lvar :foo))
+"return(foo)"
+ ~~~~~~ keyword
+ ~~~~~~~~~~~ expression
+~~~
+
+### Exception handling
+
+#### Rescue body
+
+Format:
+
+~~~
+(resbody (array (const nil :Exception) (const nil :A)) (lvasgn :bar) (int 1))
+"rescue Exception, A => bar; 1"
+ ~~~~~~ keyword      ~~ assoc
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
+
+"rescue Exception, A => bar then 1"
+ ~~~~~~ keyword      ~~ assoc
+                            ~~~~ begin
+
+(resbody (array (const nil :Exception)) (ivasgn :bar) (int 1))
+"rescue Exception => @bar; 1"
+ ~~~~~~ keyword   ~~ assoc
+
+(resbody nil (lvasgn :bar) (int 1))
+"rescue => bar; 1"
+ ~~~~~~ keyword
+        ~~ assoc
+
+(resbody nil nil (int 1))
+"rescue; 1"
+ ~~~~~~ keyword
+~~~
+
+#### Rescue statement
+
+##### Without else
+
+Format:
+
+~~~
+(begin
+  (rescue (send nil :foo) (resbody ...) (resbody ...) nil))
+"begin; foo; rescue Exception; rescue; end"
+ ~~~~~ begin                           ~~~ end
+             ~~~~~~~~~~~~~~~~~ expression (rescue.resbody/1)
+                               ~~~~~~~ expression (rescue.resbody/2)
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression (rescue)
+~~~
+
+##### With else
+
+Format:
+
+~~~
+(begin
+  (rescue (send nil :foo) (resbody ...) (resbody ...) (true)))
+"begin; foo; rescue Exception; rescue; else true end"
+ ~~~~~ begin                           ~~~~ else (rescue)
+                                                 ~~~ end
+~~~
+
+#### Ensure statement
+
+Format:
+
+~~~
+(begin
+  (ensure (send nil :foo) (send nil :bar))
+"begin; foo; ensure; bar; end"
+ ~~~~~ begin ~~~~~~ keyword (ensure)
+                          ~~~ end
+~~~
+
+#### Rescue with ensure
+
+Format:
+
+~~~
+(begin
+  (ensure
+    (rescue (send nil :foo) (resbody ...) (int 1))
+    (send nil :bar))
+"begin; foo; rescue; nil; else; 1; ensure; bar; end"
+ ~~~~~ begin
+                          ~~~~ else (ensure.rescue)
+             ~~~~~~~~~~~~~~~~~~~~~ expression (rescue)
+                                   ~~~~~~ keyword (ensure)
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression (ensure)
+                                                ~~~ end
+~~~
+
+#### Retry
+
+Format:
+
+~~~
+(retry)
+"retry"
+ ~~~~~ keyword
+ ~~~~~ expression
+~~~
+
+### BEGIN and END
+
+Format:
+
+~~~
+(preexe (send nil :puts (str "foo")))
+"BEGIN { puts "foo" }"
+ ~~~~~ keyword
+       ^ begin      ^ end
+ ~~~~~~~~~~~~~~~~~~~~ expression
+
+(postexe (send nil :puts (str "bar")))
+"END { puts "bar" }"
+ ~~~ keyword
+     ^ begin      ^ end
+ ~~~~~~~~~~~~~~~~~~ expression
+~~~
+
+## Miscellanea
+
+### Flip-flops
+
+Format:
+
+~~~
+(iflipflop (lvar :a) (lvar :b))
+"if a..b; end"
+     ~~ operator
+    ~~~~ expression
+
+(eflipflop (lvar :a) (lvar :b))
+"if a...b; end"
+     ~~~ operator
+    ~~~~~ expression
+~~~
+
+### Implicit matches
+
+Format:
+
+~~~
+(match-current-line (regexp (str "a") (regopt)))
+"if /a/; end"
+    ~~~ expression
+~~~
+
+### Local variable injecting matches
+
+Format:
+
+~~~
+(match-with-lvasgn (regexp (str "(?<match>bar)") (regopt)) (lvar :baz))
+"/(?<match>bar)/ =~ baz"
+                 ~~ selector
+ ~~~~~~~~~~~~~~~~~~~~~~ expression
+~~~
diff --git a/app/server/vendor/parser-2.2.2.1/doc/CUSTOMIZATION.md b/app/server/vendor/parser-2.2.2.1/doc/CUSTOMIZATION.md
new file mode 100644
index 0000000..8231fdb
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/doc/CUSTOMIZATION.md
@@ -0,0 +1,37 @@
+# Customizing Parsers
+
+While the default setup of the parsers provided by this Gem should be suitable
+for most some developers might want to change parts of it. An example would be
+the use of a custom class for nodes instead of `Parser::AST::Node`.
+
+Customizing the AST is done by creating a custom builder class and passing it
+to the constructor method of a parser. The default setup comes down to the
+following:
+
+    builder = Parser::Builders::Default.new
+    parser  = Parser::Ruby19.new(builder)
+
+When creating your own builder class it's best to subclass the default one so
+that you don't have to redefine every used method again:
+
+    class MyBuilder < Parser::Builders::Default
+
+    end
+
+    builder = MyBuilder.new
+    parser  = Parser::Ruby19.new(builder)
+
+## Custom Node Classes
+
+To use a custom node class you have to override the method
+`Parser::Builders::Default#n`:
+
+    class MyBuilder < Parser::Builders::Default
+      def n(type, children, location)
+        return MyNodeClass.new(type, children, :location => location)
+      end
+    end
+
+Note that the used class (and corresponding instance) must be compatible with
+`Parser::AST::Node` so it's best to subclass it and override/add code where
+needed.
diff --git a/app/server/vendor/parser-2.2.2.1/doc/INTERNALS.md b/app/server/vendor/parser-2.2.2.1/doc/INTERNALS.md
new file mode 100644
index 0000000..debac9e
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/doc/INTERNALS.md
@@ -0,0 +1,21 @@
+Entry points
+------------
+
+Parser should be kept as slim as possible. This includes not loading
+any potentially large files when they are likely to be unused in practice.
+
+Parser has five main (classes of) `require` entry points:
+
+ * `require 'parser'`. Main entry point, requires all classes which
+   are used across the entire library.
+ * `require 'parser/rubyXX'`. Version-specific entry point. Can raise
+   a NotImplementedError if current Ruby runtime is unable to parse the
+   requested Ruby version.
+ * `require 'parser/all'`. Requires all available parsers for released
+   versions of Ruby. Can raise NotImplementedError.
+ * `require 'parser/runner'`. Requires all the stuff which is useful for
+   command-line tools but not otherwise.
+ * `require 'parser/runner/X'`. Runner-specific entry point.
+
+All non-main entry points internally `require 'parser'`. Additionally, all
+runner-specific entry points internally `requre 'parser/runner'`.
diff --git a/app/server/vendor/parser-2.2.2.1/doc/css/.gitkeep b/app/server/vendor/parser-2.2.2.1/doc/css/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/vendor/parser-2.2.2.1/doc/css/common.css b/app/server/vendor/parser-2.2.2.1/doc/css/common.css
new file mode 100644
index 0000000..5302c5c
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/doc/css/common.css
@@ -0,0 +1,68 @@
+body
+{
+    font-size:   14px;
+    line-height: 1.6;
+    margin:      0 auto;
+    max-width:   960px;
+}
+
+p code
+{
+    background:    #f2f2f2;
+    padding-left:  3px;
+    padding-right: 3px;
+}
+
+pre.code
+{
+    font-size:   13px;
+    line-height: 1.4;
+}
+
+/**
+ * YARD uses generic table styles, using a special class means those tables
+ * don't get messed up.
+ */
+.table
+{
+    border:          1px solid #ccc;
+    border-right:    none;
+    border-collapse: separate;
+    border-spacing:  0;
+    text-align:      left;
+}
+
+.table.full
+{
+    width: 100%;
+}
+
+    .table .field_name
+    {
+        min-width: 160px;
+    }
+
+    .table thead tr th.no_sort:first-child
+    {
+        width: 25px;
+    }
+
+    .table thead tr th, .table tbody tr td
+    {
+        border-bottom:  1px solid #ccc;
+        border-right:   1px solid #ccc;
+        min-width:      20px;
+        padding:        8px 5px;
+        text-align:     left;
+        vertical-align: top;
+    }
+
+    .table tbody tr:last-child td
+    {
+        border-bottom: none;
+    }
+
+    .table tr:nth-child(odd) td
+    {
+        background: #f9f9f9;
+    }
diff --git a/app/server/vendor/parser-2.2.2.1/lib/gauntlet_parser.rb b/app/server/vendor/parser-2.2.2.1/lib/gauntlet_parser.rb
new file mode 100644
index 0000000..aa8b06b
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/gauntlet_parser.rb
@@ -0,0 +1,121 @@
+require 'gauntlet'
+require 'parser/all'
+require 'shellwords'
+
+class ParserGauntlet < Gauntlet
+  RUBY20 = 'ruby'
+  RUBY19 = 'ruby1.9.1'
+  RUBY18 = '/opt/rubies/ruby-1.8.7-p370/bin/ruby'
+
+  def try(parser, ruby, file, show_ok: false)
+    try_ruby = lambda do |e|
+      Process.spawn(%{#{ruby} -c #{Shellwords.escape file}},
+                    :err => '/dev/null', :out => '/dev/null')
+      _, status = Process.wait2
+
+      if status.success?
+        # Bug in Parser.
+        puts "Parser bug."
+        @result[file] = { parser.to_s => "#{e.class}: #{e.to_s}" }
+      else
+        # No, this file is not Ruby.
+        yield if block_given?
+      end
+    end
+
+    begin
+      parser.parse_file(file)
+
+    rescue Parser::SyntaxError => e
+      if e.diagnostic.location.resize(2).is?('<%')
+        puts "ERb."
+        return
+      end
+
+      try_ruby.call(e)
+
+    rescue ArgumentError, RegexpError,
+           Encoding::UndefinedConversionError => e
+      puts "#{file}: #{e.class}: #{e.to_s}"
+
+      try_ruby.call(e)
+
+    rescue Interrupt
+      raise
+
+    rescue Exception => e
+      puts "Parser bug: #{file} #{e.class}: #{e.to_s}"
+      @result[file] = { parser.to_s => "#{e.class}: #{e.to_s}" }
+
+    else
+      puts "Ok." if show_ok
+    end
+  end
+
+  def parse(name)
+    puts "GEM: #{name}"
+
+    @result = {}
+
+    if ENV.include?('FAST')
+      total_size = Dir["**/*.rb"].map(&File.method(:size)).reduce(:+)
+      if total_size > 300_000
+        puts "Skip."
+        return
+      end
+    end
+
+    Dir["**/*.rb"].each do |file|
+      next if File.directory? file
+
+      try(Parser::Ruby20, RUBY20, file) do
+        puts "Trying 1.9:"
+        try(Parser::Ruby19, RUBY19, file, show_ok: true) do
+          puts "Trying 1.8:"
+          try(Parser::Ruby18, RUBY18, file, show_ok: true) do
+            puts "Invalid syntax."
+          end
+        end
+      end
+    end
+
+    @result
+  end
+
+  def run(name)
+    data[name] = parse(name)
+    self.dirty = true
+  end
+
+  def should_skip?(name)
+    data[name] == {}
+  end
+
+  def load_yaml(*)
+    data = super
+    @was_errors = data.count { |_name, errs| errs != {} }
+
+    data
+  end
+
+  def shutdown
+    super
+
+    errors  = data.count { |_name, errs| errs != {} }
+    total   = data.count
+    percent = "%.5f" % [100 - errors.to_f / total * 100]
+    puts "!!! was: #{@was_errors} now: #{errors} total: #{total} frac: #{percent}%"
+  end
+end
+
+filter = ARGV.shift
+filter = Regexp.new filter if filter
+
+gauntlet = ParserGauntlet.new
+
+if ENV.include? 'UPDATE'
+  gauntlet.source_index
+  gauntlet.update_gem_tarballs
+end
+
+gauntlet.run_the_gauntlet filter
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser.rb b/app/server/vendor/parser-2.2.2.1/lib/parser.rb
new file mode 100644
index 0000000..f306b03
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser.rb
@@ -0,0 +1,79 @@
+require 'set'
+require 'racc/parser'
+
+require 'ast'
+
+if RUBY_VERSION < '1.9'
+  require 'parser/compatibility/ruby1_8'
+end
+
+if RUBY_VERSION < '2.0'
+  require 'parser/compatibility/ruby1_9'
+end
+
+##
+# @api public
+#
+module Parser
+  require 'parser/version'
+  require 'parser/messages'
+
+  module AST
+    require 'parser/ast/node'
+    require 'parser/ast/processor'
+    require 'parser/meta'
+  end
+
+  module Source
+    require 'parser/source/buffer'
+    require 'parser/source/range'
+
+    require 'parser/source/comment'
+    require 'parser/source/comment/associator'
+
+    require 'parser/source/rewriter'
+    require 'parser/source/rewriter/action'
+
+    require 'parser/source/map'
+    require 'parser/source/map/operator'
+    require 'parser/source/map/collection'
+    require 'parser/source/map/constant'
+    require 'parser/source/map/variable'
+    require 'parser/source/map/keyword'
+    require 'parser/source/map/definition'
+    require 'parser/source/map/send'
+    require 'parser/source/map/condition'
+    require 'parser/source/map/ternary'
+    require 'parser/source/map/for'
+    require 'parser/source/map/rescue_body'
+    require 'parser/source/map/heredoc'
+  end
+
+  require 'parser/syntax_error'
+  require 'parser/clobbering_error'
+  require 'parser/diagnostic'
+  require 'parser/diagnostic/engine'
+
+  require 'parser/static_environment'
+
+  require 'parser/lexer'
+  require 'parser/lexer/literal'
+  require 'parser/lexer/stack_state'
+
+  module Builders
+    require 'parser/builders/default'
+  end
+
+  require 'parser/base'
+
+  require 'parser/rewriter'
+
+  ##
+  # Verify that the current Ruby implementation supports Encoding.
+  # @raise [RuntimeError]
+  def self.check_for_encoding_support
+    unless defined?(Encoding)
+      raise RuntimeError, 'Parsing 1.9 and later versions of Ruby is not supported on 1.8 due to the lack of Encoding support'
+    end
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/all.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/all.rb
new file mode 100644
index 0000000..0b8846f
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/all.rb
@@ -0,0 +1,4 @@
+require 'parser/ruby18'
+require 'parser/ruby19'
+require 'parser/ruby20'
+require 'parser/ruby21'
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/ast/node.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/ast/node.rb
new file mode 100644
index 0000000..0689605
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/ast/node.rb
@@ -0,0 +1,38 @@
+module Parser
+  module AST
+
+    ##
+    # {Parser::AST::Node} contains information about a single AST node and its
+    # child nodes. It extends the basic [AST::Node](http://rdoc.info/gems/ast/AST/Node)
+    # class provided by gem [ast](http://rdoc.info/gems/ast).
+    #
+    # @api public
+    #
+    # @!attribute [r] location
+    #  Source map for this Node.
+    #  @return [Parser::Source::Map]
+    #
+    class Node < ::AST::Node
+      attr_reader :location
+
+      alias loc location
+
+      ##
+      # Assigns various properties to this AST node. Currently only the
+      # location can be set.
+      #
+      # @param [Hash] properties
+      # @option properties [Parser::Source::Map] :location Location information
+      #  of the node.
+      #
+      def assign_properties(properties)
+        if (location = properties[:location])
+          location = location.dup if location.frozen?
+          location.node = self
+          @location = location
+        end
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/ast/processor.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/ast/processor.rb
new file mode 100644
index 0000000..5a96713
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/ast/processor.rb
@@ -0,0 +1,190 @@
+module Parser
+  module AST
+
+    ##
+    # @api public
+    #
+    class Processor < ::AST::Processor
+      def process_regular_node(node)
+        node.updated(nil, process_all(node))
+      end
+
+      alias on_dstr     process_regular_node
+      alias on_dsym     process_regular_node
+      alias on_regexp   process_regular_node
+      alias on_xstr     process_regular_node
+      alias on_splat    process_regular_node
+      alias on_array    process_regular_node
+      alias on_pair     process_regular_node
+      alias on_hash     process_regular_node
+      alias on_irange   process_regular_node
+      alias on_erange   process_regular_node
+
+      def on_var(node)
+        node
+      end
+
+      def process_variable_node(node)
+        on_var(node)
+      end
+
+      alias on_lvar     process_variable_node
+      alias on_ivar     process_variable_node
+      alias on_gvar     process_variable_node
+      alias on_cvar     process_variable_node
+      alias on_back_ref process_variable_node
+      alias on_nth_ref  process_variable_node
+
+      def on_vasgn(node)
+        name, value_node = *node
+
+        node.updated(nil, [
+          name, process(value_node)
+        ])
+      end
+
+      def process_var_asgn_node(node)
+        on_vasgn(node)
+      end
+
+      alias on_lvasgn   process_var_asgn_node
+      alias on_ivasgn   process_var_asgn_node
+      alias on_gvasgn   process_var_asgn_node
+      alias on_cvasgn   process_var_asgn_node
+
+      alias on_and_asgn process_regular_node
+      alias on_or_asgn  process_regular_node
+
+      def on_op_asgn(node)
+        var_node, method_name, value_node = *node
+
+        node.updated(nil, [
+          process(var_node), method_name, process(value_node)
+        ])
+      end
+
+      alias on_mlhs     process_regular_node
+      alias on_masgn    process_regular_node
+
+      def on_const(node)
+        scope_node, name = *node
+
+        node.updated(nil, [
+          process(scope_node), name
+        ])
+      end
+
+      def on_casgn(node)
+        scope_node, name, value_node = *node
+
+        node.updated(nil, [
+          process(scope_node), name, process(value_node)
+        ])
+      end
+
+      alias on_args     process_regular_node
+
+      def on_argument(node)
+        arg_name, value_node = *node
+
+        node.updated(nil, [
+          arg_name, process(value_node)
+        ])
+      end
+
+      def process_argument_node(node)
+        on_argument(node)
+      end
+
+      alias on_arg            process_argument_node
+      alias on_optarg         process_argument_node
+      alias on_restarg        process_argument_node
+      alias on_blockarg       process_argument_node
+      alias on_shadowarg      process_argument_node
+      alias on_kwarg          process_argument_node
+      alias on_kwoptarg       process_argument_node
+      alias on_kwrestarg      process_argument_node
+
+      alias on_arg_expr       process_regular_node
+      alias on_restarg_expr   process_regular_node
+      alias on_blockarg_expr  process_regular_node
+
+      alias on_module         process_regular_node
+      alias on_class          process_regular_node
+      alias on_sclass         process_regular_node
+
+      def on_def(node)
+        name, args_node, body_node = *node
+
+        node.updated(nil, [
+          name,
+          process(args_node), process(body_node)
+        ])
+      end
+
+      def on_defs(node)
+        definee_node, name, args_node, body_node = *node
+
+        node.updated(nil, [
+          process(definee_node), name,
+          process(args_node), process(body_node)
+        ])
+      end
+
+      alias on_undef    process_regular_node
+      alias on_alias    process_regular_node
+
+      def on_send(node)
+        receiver_node, method_name, *arg_nodes = *node
+
+        receiver_node = process(receiver_node) if receiver_node
+        node.updated(nil, [
+          receiver_node, method_name, *process_all(arg_nodes)
+        ])
+      end
+
+      alias on_block    process_regular_node
+
+      alias on_while      process_regular_node
+      alias on_while_post process_regular_node
+      alias on_until      process_regular_node
+      alias on_until_post process_regular_node
+      alias on_for        process_regular_node
+
+      alias on_return   process_regular_node
+      alias on_break    process_regular_node
+      alias on_next     process_regular_node
+      alias on_redo     process_regular_node
+      alias on_retry    process_regular_node
+      alias on_super    process_regular_node
+      alias on_yield    process_regular_node
+      alias on_defined? process_regular_node
+
+      alias on_not      process_regular_node
+      alias on_and      process_regular_node
+      alias on_or       process_regular_node
+
+      alias on_if       process_regular_node
+
+      alias on_when     process_regular_node
+      alias on_case     process_regular_node
+
+      alias on_iflipflop process_regular_node
+      alias on_eflipflop process_regular_node
+
+      alias on_match_current_line process_regular_node
+      alias on_match_with_lvasgn  process_regular_node
+
+      alias on_resbody  process_regular_node
+      alias on_rescue   process_regular_node
+      alias on_ensure   process_regular_node
+
+      alias on_begin    process_regular_node
+      alias on_kwbegin  process_regular_node
+
+      alias on_preexe   process_regular_node
+      alias on_postexe  process_regular_node
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/base.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/base.rb
new file mode 100644
index 0000000..9dc1669
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/base.rb
@@ -0,0 +1,269 @@
+module Parser
+
+  ##
+  # Base class for version-specific parsers.
+  #
+  # @api public
+  #
+  # @!attribute [r] diagnostics
+  #  @return [Parser::Diagnostic::Engine]
+  #
+  # @!attribute [r] static_env
+  #  @return [Parser::StaticEnvironment]
+  #
+  class Base < Racc::Parser
+    ##
+    # Parses a string of Ruby code and returns the AST. If the source
+    # cannot be parsed, {SyntaxError} is raised and a diagnostic is
+    # printed to `stderr`.
+    #
+    # @example
+    #  Parser::Base.parse('puts "hello"')
+    #
+    # @param [String] string The block of code to parse.
+    # @param [String] file The name of the file the code originated from.
+    # @param [Numeric] line The initial line number.
+    # @return [Parser::AST::Node]
+    #
+    def self.parse(string, file='(string)', line=1)
+      parser = default_parser
+      source_buffer = setup_source_buffer(file, line, string, parser.default_encoding)
+      parser.parse(source_buffer)
+    end
+
+    ##
+    # Parses a string of Ruby code and returns the AST and comments. If the
+    # source cannot be parsed, {SyntaxError} is raised and a diagnostic is
+    # printed to `stderr`.
+    #
+    # @example
+    #  Parser::Base.parse_with_comments('puts "hello"')
+    #
+    # @param [String] string The block of code to parse.
+    # @param [String] file The name of the file the code originated from.
+    # @param [Numeric] line The initial line number.
+    # @return [Array]
+    #
+    def self.parse_with_comments(string, file='(string)', line=1)
+      parser = default_parser
+      source_buffer = setup_source_buffer(file, line, string, parser.default_encoding)
+      parser.parse_with_comments(source_buffer)
+    end
+
+    ##
+    # Parses Ruby source code by reading it from a file. If the source
+    # cannot be parsed, {SyntaxError} is raised and a diagnostic is
+    # printed to `stderr`.
+    #
+    # @param [String] filename Path to the file to parse.
+    # @return [Parser::AST::Node]
+    # @see #parse
+    #
+    def self.parse_file(filename)
+      parse(File.read(filename), filename)
+    end
+
+    ##
+    # Parses Ruby source code by reading it from a file and returns the AST and
+    # comments. If the source cannot be parsed, {SyntaxError} is raised and a
+    # diagnostic is printed to `stderr`.
+    #
+    # @param [String] filename Path to the file to parse.
+    # @return [Array]
+    # @see #parse
+    #
+    def self.parse_file_with_comments(filename)
+      parse_with_comments(File.read(filename), filename)
+    end
+
+    ##
+    # @return [Parser::Base] parser with the default options set.
+    #
+    def self.default_parser
+      parser = new
+
+      parser.diagnostics.all_errors_are_fatal = true
+      parser.diagnostics.ignore_warnings      = true
+
+      parser.diagnostics.consumer = lambda do |diagnostic|
+        $stderr.puts(diagnostic.render)
+      end
+
+      parser
+    end
+
+    def self.setup_source_buffer(file, line, string, encoding)
+      if string.respond_to? :force_encoding
+        string = string.dup.force_encoding(encoding)
+      end
+
+      source_buffer = Source::Buffer.new(file, line)
+
+      if name == 'Parser::Ruby18'
+        source_buffer.raw_source = string
+      else
+        source_buffer.source     = string
+      end
+
+      source_buffer
+    end
+    private_class_method :setup_source_buffer
+
+    attr_reader :diagnostics
+    attr_reader :builder
+    attr_reader :static_env
+    attr_reader :source_buffer
+
+    ##
+    # Create a new parser instance.
+    #
+    # Note that on JRuby and Rubinius the `diagnostics.all_errors_are_fatal`
+    # switch is always turned on as a workaround for a standard library bug.
+    # Do not set it to `false`.
+    #
+    # @param [Parser::Builders::Default] builder The AST builder to use.
+    #
+    def initialize(builder=Parser::Builders::Default.new)
+      @diagnostics = Diagnostic::Engine.new
+
+      if RUBY_PLATFORM != 'ruby'
+        # This is a workaround for a Racc bug. In the pure Ruby Racc runtime,
+        # which gets activated on JRuby/RBX, there is a bug in error token
+        # popping, which results in an infinite loop.
+        @diagnostics.all_errors_are_fatal = true
+      end
+
+      @static_env  = StaticEnvironment.new
+
+      @lexer = Lexer.new(version)
+      @lexer.diagnostics = @diagnostics
+      @lexer.static_env  = @static_env
+
+      @builder = builder
+      @builder.parser = self
+
+      if self.class::Racc_debug_parser && ENV['RACC_DEBUG']
+        @yydebug = true
+      end
+
+      reset
+    end
+
+    ##
+    # Resets the state of the parser.
+    #
+    def reset
+      @source_buffer = nil
+      @def_level     = 0 # count of nested def's.
+
+      @lexer.reset
+      @static_env.reset
+
+      self
+    end
+
+    ##
+    # Parses a source buffer and returns the AST.
+    #
+    # @param [Parser::Source::Buffer] source_buffer The source buffer to parse.
+    # @return [Parser::AST::Node]
+    #
+    def parse(source_buffer)
+      @lexer.source_buffer = source_buffer
+      @source_buffer       = source_buffer
+
+      do_parse
+    ensure
+      # Don't keep references to the source file.
+      @source_buffer       = nil
+      @lexer.source_buffer = nil
+    end
+
+    ##
+    # Parses a source buffer and returns the AST along with the comments of the
+    # Ruby source code.
+    #
+    # @see #parse
+    # @see Parser::Source::Comment#associate
+    # @return [Array]
+    #
+    def parse_with_comments(source_buffer)
+      @lexer.comments = []
+
+      [ parse(source_buffer), @lexer.comments ]
+    ensure
+      @lexer.comments = nil
+    end
+
+    ##
+    # Currently, token stream format returned by #tokenize is not documented,
+    # but is considered part of a public API and only changed according
+    # to Semantic Versioning.
+    #
+    # However, note that the exact token composition of various constructs
+    # might vary. For example, a string `"foo"` is represented equally well
+    # by `:tSTRING_BEG " :tSTRING_CONTENT foo :tSTRING_END "` and
+    # `:tSTRING "foo"`; such details must not be relied upon.
+    #
+    # @param [Parser::Source::Buffer] source_buffer
+    # @return [Array]
+    #
+    def tokenize(source_buffer)
+      @lexer.tokens = []
+
+      ast, comments = parse_with_comments(source_buffer)
+
+      [ ast, comments, @lexer.tokens ]
+    ensure
+      @lexer.tokens = nil
+    end
+
+    ##
+    # @api private
+    # @return [Boolean]
+    #
+    def in_def?
+      @def_level > 0
+    end
+
+    private
+
+    def next_token
+      @lexer.advance
+    end
+
+    def check_kwarg_name(name_t)
+      case name_t[0]
+      when /^[a-z_]/
+        # OK
+      when /^[A-Z]/
+        diagnostic :error, :argument_const, nil, name_t
+      end
+    end
+
+    def diagnostic(level, reason, arguments, location_t, highlights_ts=[])
+      _, location = location_t
+
+      highlights = highlights_ts.map do |token|
+        _, range = token
+        range
+      end
+
+      @diagnostics.process(
+          Diagnostic.new(level, reason, arguments, location, highlights))
+
+      if level == :error
+        yyerror
+      end
+    end
+
+    def on_error(error_token_id, error_value, value_stack)
+      token_name = token_to_str(error_token_id)
+      _, location = error_value
+
+      @diagnostics.process(Diagnostic.new(
+          :error, :unexpected_token, { :token => token_name }, location))
+    end
+  end
+
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/builders/default.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/builders/default.rb
new file mode 100644
index 0000000..ac1b544
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/builders/default.rb
@@ -0,0 +1,1443 @@
+module Parser
+
+  ##
+  # Default AST builder. Uses {AST::Node}s.
+  #
+  class Builders::Default
+    ##
+    # @api private
+    attr_accessor :parser
+
+    ##
+    # If set to true, `__FILE__` and `__LINE__` are transformed to
+    # literal nodes. For example, `s(:str, "lib/foo.rb")` and `s(:int, 10)`.
+    #
+    # If set to false, `__FILE__` and `__LINE__` are emitted as-is,
+    # i.e. as `s(:__FILE__)` and `s(:__LINE__)` nodes.
+    #
+    # Source maps are identical in both cases.
+    #
+    # @return [Boolean]
+    attr_accessor :emit_file_line_as_literals
+
+    ##
+    # Initializes attributes:
+    #
+    #   * `emit_file_line_as_literals`: `true`
+    def initialize
+      @emit_file_line_as_literals = true
+    end
+
+    # @!parse private
+
+    #
+    # Literals
+    #
+
+    # Singletons
+
+    def nil(nil_t)
+      n0(:nil,
+        token_map(nil_t))
+    end
+
+    def true(true_t)
+      n0(:true,
+        token_map(true_t))
+    end
+
+    def false(false_t)
+      n0(:false,
+        token_map(false_t))
+    end
+
+    # Numerics
+
+    def integer(integer_t)
+      numeric(:int, integer_t)
+    end
+
+    def float(float_t)
+      numeric(:float, float_t)
+    end
+
+    def rational(rational_t)
+      numeric(:rational, rational_t)
+    end
+
+    def complex(complex_t)
+      numeric(:complex, complex_t)
+    end
+
+    def numeric(kind, token)
+      n(kind, [ value(token) ],
+        Source::Map::Operator.new(nil, loc(token)))
+    end
+    private :numeric
+
+    def negate(uminus_t, numeric)
+      value, = *numeric
+      operator_loc = loc(uminus_t)
+
+      numeric.updated(nil, [ -value ],
+        :location =>
+          Source::Map::Operator.new(
+            operator_loc,
+            operator_loc.join(numeric.loc.expression)))
+    end
+
+    def __LINE__(__LINE__t)
+      n0(:__LINE__,
+        token_map(__LINE__t))
+    end
+
+    # Strings
+
+    def string(string_t)
+      n(:str, [ value(string_t) ],
+        delimited_string_map(string_t))
+    end
+
+    def string_internal(string_t)
+      n(:str, [ value(string_t) ],
+        unquoted_map(string_t))
+    end
+
+    def string_compose(begin_t, parts, end_t)
+      if collapse_string_parts?(parts)
+        if begin_t.nil? && end_t.nil?
+          parts.first
+        else
+          n(:str, parts.first.children,
+            string_map(begin_t, parts, end_t))
+        end
+      else
+        n(:dstr, [ *parts ],
+          string_map(begin_t, parts, end_t))
+      end
+    end
+
+    def character(char_t)
+      n(:str, [ value(char_t) ],
+        prefix_string_map(char_t))
+    end
+
+    def __FILE__(__FILE__t)
+      n0(:__FILE__,
+        token_map(__FILE__t))
+    end
+
+    # Symbols
+
+    def symbol(symbol_t)
+      n(:sym, [ value(symbol_t).to_sym ],
+        prefix_string_map(symbol_t))
+    end
+
+    def symbol_internal(symbol_t)
+      n(:sym, [ value(symbol_t).to_sym ],
+        unquoted_map(symbol_t))
+    end
+
+    def symbol_compose(begin_t, parts, end_t)
+      if collapse_string_parts?(parts)
+        str = parts.first
+
+        n(:sym, [ str.children.first.to_sym ],
+          collection_map(begin_t, str.loc.expression, end_t))
+      elsif @parser.version == 18 && parts.empty?
+        diagnostic :error, :empty_symbol, nil, loc(begin_t).join(loc(end_t))
+      else
+        n(:dsym, [ *parts ],
+          collection_map(begin_t, parts, end_t))
+      end
+    end
+
+    # Executable strings
+
+    def xstring_compose(begin_t, parts, end_t)
+      n(:xstr, [ *parts ],
+        string_map(begin_t, parts, end_t))
+    end
+
+    # Regular expressions
+
+    def regexp_options(regopt_t)
+      options = value(regopt_t).
+        each_char.sort.uniq.
+        map(&:to_sym)
+
+      n(:regopt, options,
+        token_map(regopt_t))
+    end
+
+    def regexp_compose(begin_t, parts, end_t, options)
+      begin
+        static_regexp(parts, options)
+      rescue RegexpError => e
+        diagnostic :error, :invalid_regexp, { :message => e.message },
+                   loc(begin_t).join(loc(end_t))
+      end
+
+      n(:regexp, (parts << options),
+        regexp_map(begin_t, end_t, options))
+    end
+
+    # Arrays
+
+    def array(begin_t, elements, end_t)
+      n(:array, elements,
+        collection_map(begin_t, elements, end_t))
+    end
+
+    def splat(star_t, arg=nil)
+      if arg.nil?
+        n0(:splat,
+          unary_op_map(star_t))
+      else
+        n(:splat, [ arg ],
+          unary_op_map(star_t, arg))
+      end
+    end
+
+    def word(parts)
+      if collapse_string_parts?(parts)
+        parts.first
+      else
+        n(:dstr, [ *parts ],
+          collection_map(nil, parts, nil))
+      end
+    end
+
+    def words_compose(begin_t, parts, end_t)
+      n(:array, [ *parts ],
+        collection_map(begin_t, parts, end_t))
+    end
+
+    def symbols_compose(begin_t, parts, end_t)
+      parts = parts.map do |part|
+        case part.type
+        when :str
+          value, = *part
+          part.updated(:sym, [ value.to_sym ])
+        when :dstr
+          part.updated(:dsym)
+        else
+          part
+        end
+      end
+
+      n(:array, [ *parts ],
+        collection_map(begin_t, parts, end_t))
+    end
+
+    # Hashes
+
+    def pair(key, assoc_t, value)
+      n(:pair, [ key, value ],
+        binary_op_map(key, assoc_t, value))
+    end
+
+    def pair_list_18(list)
+      if list.size % 2 != 0
+        diagnostic :error, :odd_hash, nil, list.last.loc.expression
+      else
+        list.
+          each_slice(2).map do |key, value|
+            n(:pair, [ key, value ],
+              binary_op_map(key, nil, value))
+          end
+      end
+    end
+
+    def pair_keyword(key_t, value)
+      key_map, pair_map = pair_keyword_map(key_t, value)
+
+      key = n(:sym, [ value(key_t).to_sym ], key_map)
+
+      n(:pair, [ key, value ], pair_map)
+    end
+
+    def pair_quoted(begin_t, parts, end_t, value)
+      end_t, pair_map = pair_quoted_map(begin_t, end_t, value)
+
+      key = symbol_compose(begin_t, parts, end_t)
+
+      n(:pair, [ key, value ], pair_map)
+    end
+
+    def kwsplat(dstar_t, arg)
+      n(:kwsplat, [ arg ],
+        unary_op_map(dstar_t, arg))
+    end
+
+    def associate(begin_t, pairs, end_t)
+      n(:hash, [ *pairs ],
+        collection_map(begin_t, pairs, end_t))
+    end
+
+    # Ranges
+
+    def range_inclusive(lhs, dot2_t, rhs)
+      n(:irange, [ lhs, rhs ],
+        binary_op_map(lhs, dot2_t, rhs))
+    end
+
+    def range_exclusive(lhs, dot3_t, rhs)
+      n(:erange, [ lhs, rhs ],
+        binary_op_map(lhs, dot3_t, rhs))
+    end
+
+    #
+    # Access
+    #
+
+    def self(token)
+      n0(:self,
+        token_map(token))
+    end
+
+    def ident(token)
+      n(:ident, [ value(token).to_sym ],
+        variable_map(token))
+    end
+
+    def ivar(token)
+      n(:ivar, [ value(token).to_sym ],
+        variable_map(token))
+    end
+
+    def gvar(token)
+      n(:gvar, [ value(token).to_sym ],
+        variable_map(token))
+    end
+
+    def cvar(token)
+      n(:cvar, [ value(token).to_sym ],
+        variable_map(token))
+    end
+
+    def back_ref(token)
+      n(:back_ref, [ value(token).to_sym ],
+        token_map(token))
+    end
+
+    def nth_ref(token)
+      n(:nth_ref, [ value(token) ],
+        token_map(token))
+    end
+
+    def accessible(node)
+      case node.type
+      when :__FILE__
+        if @emit_file_line_as_literals
+          n(:str, [ node.loc.expression.source_buffer.name ],
+            node.loc.dup)
+        else
+          node
+        end
+
+      when :__LINE__
+        if @emit_file_line_as_literals
+          n(:int, [ node.loc.expression.line ],
+            node.loc.dup)
+        else
+          node
+        end
+
+      when :__ENCODING__
+        n(:const, [ n(:const, [ nil, :Encoding], nil), :UTF_8 ],
+          node.loc.dup)
+
+      when :ident
+        name, = *node
+
+        if @parser.static_env.declared?(name)
+          node.updated(:lvar)
+        else
+          name, = *node
+          n(:send, [ nil, name ],
+            var_send_map(node))
+        end
+
+      else
+        node
+      end
+    end
+
+    def const(name_t)
+      n(:const, [ nil, value(name_t).to_sym ],
+        constant_map(nil, nil, name_t))
+    end
+
+    def const_global(t_colon3, name_t)
+      cbase = n0(:cbase, token_map(t_colon3))
+
+      n(:const, [ cbase, value(name_t).to_sym ],
+        constant_map(cbase, t_colon3, name_t))
+    end
+
+    def const_fetch(scope, t_colon2, name_t)
+      n(:const, [ scope, value(name_t).to_sym ],
+        constant_map(scope, t_colon2, name_t))
+    end
+
+    def __ENCODING__(__ENCODING__t)
+      n0(:__ENCODING__,
+        token_map(__ENCODING__t))
+    end
+
+    #
+    # Assignment
+    #
+
+    def assignable(node)
+      case node.type
+      when :cvar
+        node.updated(:cvasgn)
+
+      when :ivar
+        node.updated(:ivasgn)
+
+      when :gvar
+        node.updated(:gvasgn)
+
+      when :const
+        if @parser.in_def?
+          diagnostic :error, :dynamic_const, nil, node.loc.expression
+        end
+
+        node.updated(:casgn)
+
+      when :ident
+        name, = *node
+        @parser.static_env.declare(name)
+
+        node.updated(:lvasgn)
+
+      when :nil, :self, :true, :false,
+           :__FILE__, :__LINE__, :__ENCODING__
+        diagnostic :error, :invalid_assignment, nil, node.loc.expression
+
+      when :back_ref, :nth_ref
+        diagnostic :error, :backref_assignment, nil, node.loc.expression
+      end
+    end
+
+    def const_op_assignable(node)
+      node.updated(:casgn)
+    end
+
+    def assign(lhs, eql_t, rhs)
+      (lhs << rhs).updated(nil, nil,
+        :location => lhs.loc.
+          with_operator(loc(eql_t)).
+          with_expression(join_exprs(lhs, rhs)))
+    end
+
+    def op_assign(lhs, op_t, rhs)
+      case lhs.type
+      when :gvasgn, :ivasgn, :lvasgn, :cvasgn, :casgn, :send
+        operator   = value(op_t)[0..-1].to_sym
+        source_map = lhs.loc.
+                        with_operator(loc(op_t)).
+                        with_expression(join_exprs(lhs, rhs))
+
+        case operator
+        when :'&&'
+          n(:and_asgn, [ lhs, rhs ], source_map)
+        when :'||'
+          n(:or_asgn, [ lhs, rhs ], source_map)
+        else
+          n(:op_asgn, [ lhs, operator, rhs ], source_map)
+        end
+
+      when :back_ref, :nth_ref
+        diagnostic :error, :backref_assignment, nil, lhs.loc.expression
+      end
+    end
+
+    def multi_lhs(begin_t, items, end_t)
+      n(:mlhs, [ *items ],
+        collection_map(begin_t, items, end_t))
+    end
+
+    def multi_assign(lhs, eql_t, rhs)
+      n(:masgn, [ lhs, rhs ],
+        binary_op_map(lhs, eql_t, rhs))
+    end
+
+    #
+    # Class and module definition
+    #
+
+    def def_class(class_t, name,
+                  lt_t, superclass,
+                  body, end_t)
+      n(:class, [ name, superclass, body ],
+        module_definition_map(class_t, name, lt_t, end_t))
+    end
+
+    def def_sclass(class_t, lshft_t, expr,
+                   body, end_t)
+      n(:sclass, [ expr, body ],
+        module_definition_map(class_t, nil, lshft_t, end_t))
+    end
+
+    def def_module(module_t, name,
+                   body, end_t)
+      n(:module, [ name, body ],
+        module_definition_map(module_t, name, nil, end_t))
+    end
+
+    #
+    # Method (un)definition
+    #
+
+    def def_method(def_t, name_t, args,
+                   body, end_t)
+      n(:def, [ value(name_t).to_sym, args, body ],
+        definition_map(def_t, nil, name_t, end_t))
+    end
+
+    def def_singleton(def_t, definee, dot_t,
+                      name_t, args,
+                      body, end_t)
+      case definee.type
+      when :int, :str, :dstr, :sym, :dsym,
+           :regexp, :array, :hash
+
+        diagnostic :error, :singleton_literal, nil, definee.loc.expression
+
+      else
+        n(:defs, [ definee, value(name_t).to_sym, args, body ],
+          definition_map(def_t, dot_t, name_t, end_t))
+      end
+    end
+
+    def undef_method(undef_t, names)
+      n(:undef, [ *names ],
+        keyword_map(undef_t, nil, names, nil))
+    end
+
+    def alias(alias_t, to, from)
+      n(:alias, [ to, from ],
+        keyword_map(alias_t, nil, [to, from], nil))
+    end
+
+    #
+    # Formal arguments
+    #
+
+    def args(begin_t, args, end_t, check_args=true)
+      args = check_duplicate_args(args) if check_args
+      n(:args, args,
+        collection_map(begin_t, args, end_t))
+    end
+
+    def arg(name_t)
+      n(:arg, [ value(name_t).to_sym ],
+        variable_map(name_t))
+    end
+
+    def optarg(name_t, eql_t, value)
+      n(:optarg, [ value(name_t).to_sym, value ],
+        variable_map(name_t).
+          with_operator(loc(eql_t)).
+          with_expression(loc(name_t).join(value.loc.expression)))
+    end
+
+    def restarg(star_t, name_t=nil)
+      if name_t
+        n(:restarg, [ value(name_t).to_sym ],
+          arg_prefix_map(star_t, name_t))
+      else
+        n0(:restarg,
+          arg_prefix_map(star_t))
+      end
+    end
+
+    def kwarg(name_t)
+      n(:kwarg, [ value(name_t).to_sym ],
+        kwarg_map(name_t))
+    end
+
+    def kwoptarg(name_t, value)
+      n(:kwoptarg, [ value(name_t).to_sym, value ],
+        kwarg_map(name_t, value))
+    end
+
+    def kwrestarg(dstar_t, name_t=nil)
+      if name_t
+        n(:kwrestarg, [ value(name_t).to_sym ],
+          arg_prefix_map(dstar_t, name_t))
+      else
+        n0(:kwrestarg,
+          arg_prefix_map(dstar_t))
+      end
+    end
+
+    def shadowarg(name_t)
+      n(:shadowarg, [ value(name_t).to_sym ],
+        variable_map(name_t))
+    end
+
+    def blockarg(amper_t, name_t)
+      n(:blockarg, [ value(name_t).to_sym ],
+        arg_prefix_map(amper_t, name_t))
+    end
+
+    # Ruby 1.8 block arguments
+
+    def arg_expr(expr)
+      if expr.type == :lvasgn
+        expr.updated(:arg)
+      else
+        n(:arg_expr, [ expr ],
+          expr.loc.dup)
+      end
+    end
+
+    def restarg_expr(star_t, expr=nil)
+      if expr.nil?
+        n0(:restarg, token_map(star_t))
+      elsif expr.type == :lvasgn
+        expr.updated(:restarg)
+      else
+        n(:restarg_expr, [ expr ],
+          expr.loc.dup)
+      end
+    end
+
+    def blockarg_expr(amper_t, expr)
+      if expr.type == :lvasgn
+        expr.updated(:blockarg)
+      else
+        n(:blockarg_expr, [ expr ],
+          expr.loc.dup)
+      end
+    end
+
+    #
+    # Method calls
+    #
+
+    def call_method(receiver, dot_t, selector_t,
+                    lparen_t=nil, args=[], rparen_t=nil)
+      if selector_t.nil?
+        n(:send, [ receiver, :call, *args ],
+          send_map(receiver, dot_t, nil, lparen_t, args, rparen_t))
+      else
+        n(:send, [ receiver, value(selector_t).to_sym, *args ],
+          send_map(receiver, dot_t, selector_t, lparen_t, args, rparen_t))
+      end
+    end
+
+    def call_lambda(lambda_t)
+      n(:send, [ nil, :lambda ],
+        send_map(nil, nil, lambda_t))
+    end
+
+    def block(method_call, begin_t, args, body, end_t)
+      _receiver, _selector, *call_args = *method_call
+
+      if method_call.type == :yield
+        diagnostic :error, :block_given_to_yield, nil, method_call.loc.keyword, [loc(begin_t)]
+      end
+
+      last_arg = call_args.last
+      if last_arg && last_arg.type == :block_pass
+        diagnostic :error, :block_and_blockarg, nil, last_arg.loc.expression, [loc(begin_t)]
+      end
+
+      if [:send, :super, :zsuper].include?(method_call.type)
+        n(:block, [ method_call, args, body ],
+          block_map(method_call.loc.expression, begin_t, end_t))
+      else
+        # Code like "return foo 1 do end" is reduced in a weird sequence.
+        # Here, method_call is actually (return).
+        actual_send, = *method_call
+        block =
+          n(:block, [ actual_send, args, body ],
+            block_map(actual_send.loc.expression, begin_t, end_t))
+
+        n(method_call.type, [ block ],
+          method_call.loc.with_expression(join_exprs(method_call, block)))
+      end
+    end
+
+    def block_pass(amper_t, arg)
+      n(:block_pass, [ arg ],
+        unary_op_map(amper_t, arg))
+    end
+
+    def attr_asgn(receiver, dot_t, selector_t)
+      method_name = (value(selector_t) + '=').to_sym
+
+      # Incomplete method call.
+      n(:send, [ receiver, method_name ],
+        send_map(receiver, dot_t, selector_t))
+    end
+
+    def index(receiver, lbrack_t, indexes, rbrack_t)
+      n(:send, [ receiver, :[], *indexes ],
+        send_index_map(receiver, lbrack_t, rbrack_t))
+    end
+
+    def index_asgn(receiver, lbrack_t, indexes, rbrack_t)
+      # Incomplete method call.
+      n(:send, [ receiver, :[]=, *indexes ],
+        send_index_map(receiver, lbrack_t, rbrack_t))
+    end
+
+    def binary_op(receiver, operator_t, arg)
+      source_map = send_binary_op_map(receiver, operator_t, arg)
+
+      if @parser.version == 18
+        operator = value(operator_t)
+
+        if operator == '!='
+          method_call = n(:send, [ receiver, :==, arg ], source_map)
+        elsif operator == '!~'
+          method_call = n(:send, [ receiver, :=~, arg ], source_map)
+        end
+
+        if %w(!= !~).include?(operator)
+          return n(:not, [ method_call ],
+                   expr_map(source_map.expression))
+        end
+      end
+
+      n(:send, [ receiver, value(operator_t).to_sym, arg ],
+        source_map)
+    end
+
+    def match_op(receiver, match_t, arg)
+      source_map = send_binary_op_map(receiver, match_t, arg)
+
+      if (regexp = static_regexp_node(receiver))
+        regexp.names.each do |name|
+          @parser.static_env.declare(name)
+        end
+
+        n(:match_with_lvasgn, [ receiver, arg ],
+          source_map)
+      else
+        n(:send, [ receiver, :=~, arg ],
+          source_map)
+      end
+    end
+
+    def unary_op(op_t, receiver)
+      case value(op_t)
+      when '+', '-'
+        method = value(op_t) + '@'
+      else
+        method = value(op_t)
+      end
+
+      n(:send, [ receiver, method.to_sym ],
+        send_unary_op_map(op_t, receiver))
+    end
+
+    def not_op(not_t, begin_t=nil, receiver=nil, end_t=nil)
+      if @parser.version == 18
+        n(:not, [ receiver ],
+          unary_op_map(not_t, receiver))
+      else
+        if receiver.nil?
+          nil_node = n0(:begin, collection_map(begin_t, nil, end_t))
+
+          n(:send, [
+            nil_node, :'!'
+          ], send_unary_op_map(not_t, nil_node))
+        else
+          n(:send, [ receiver, :'!' ],
+            send_map(nil, nil, not_t, begin_t, [receiver], end_t))
+        end
+      end
+    end
+
+    #
+    # Control flow
+    #
+
+    # Logical operations: and, or
+
+    def logical_op(type, lhs, op_t, rhs)
+      n(type, [ lhs, rhs ],
+        binary_op_map(lhs, op_t, rhs))
+    end
+
+    # Conditionals
+
+    def condition(cond_t, cond, then_t,
+                  if_true, else_t, if_false, end_t)
+      n(:if, [ check_condition(cond), if_true, if_false ],
+        condition_map(cond_t, cond, then_t, if_true, else_t, if_false, end_t))
+    end
+
+    def condition_mod(if_true, if_false, cond_t, cond)
+      n(:if, [ check_condition(cond), if_true, if_false ],
+        keyword_mod_map(if_true || if_false, cond_t, cond))
+    end
+
+    def ternary(cond, question_t, if_true, colon_t, if_false)
+      n(:if, [ check_condition(cond), if_true, if_false ],
+        ternary_map(cond, question_t, if_true, colon_t, if_false))
+    end
+
+    # Case matching
+
+    def when(when_t, patterns, then_t, body)
+      children = patterns << body
+      n(:when, children,
+        keyword_map(when_t, then_t, children, nil))
+    end
+
+    def case(case_t, expr, when_bodies, else_t, else_body, end_t)
+      n(:case, [ expr, *(when_bodies << else_body)],
+        condition_map(case_t, expr, nil, nil, else_t, else_body, end_t))
+    end
+
+    # Loops
+
+    def loop(type, keyword_t, cond, do_t, body, end_t)
+      n(type, [ check_condition(cond), body ],
+        keyword_map(keyword_t, do_t, nil, end_t))
+    end
+
+    def loop_mod(type, body, keyword_t, cond)
+      if body.type == :kwbegin
+        type = :"#{type}_post"
+      end
+
+      n(type, [ check_condition(cond), body ],
+        keyword_mod_map(body, keyword_t, cond))
+    end
+
+    def for(for_t, iterator, in_t, iteratee,
+            do_t, body, end_t)
+      n(:for, [ iterator, iteratee, body ],
+        for_map(for_t, in_t, do_t, end_t))
+    end
+
+    # Keywords
+
+    def keyword_cmd(type, keyword_t, lparen_t=nil, args=[], rparen_t=nil)
+      if type == :yield && args.count > 0
+        last_arg = args.last
+        if last_arg.type == :block_pass
+          diagnostic :error, :block_given_to_yield, nil, loc(keyword_t), [last_arg.loc.expression]
+        end
+      end
+
+      n(type, args,
+        keyword_map(keyword_t, lparen_t, args, rparen_t))
+    end
+
+    # BEGIN, END
+
+    def preexe(preexe_t, lbrace_t, compstmt, rbrace_t)
+      n(:preexe, [ compstmt ],
+        keyword_map(preexe_t, lbrace_t, [], rbrace_t))
+    end
+
+    def postexe(postexe_t, lbrace_t, compstmt, rbrace_t)
+      n(:postexe, [ compstmt ],
+        keyword_map(postexe_t, lbrace_t, [], rbrace_t))
+    end
+
+    # Exception handling
+
+    def rescue_body(rescue_t,
+                    exc_list, assoc_t, exc_var,
+                    then_t, compound_stmt)
+      n(:resbody, [ exc_list, exc_var, compound_stmt ],
+        rescue_body_map(rescue_t, exc_list, assoc_t,
+                        exc_var, then_t, compound_stmt))
+    end
+
+    def begin_body(compound_stmt, rescue_bodies=[],
+                   else_t=nil,    else_=nil,
+                   ensure_t=nil,  ensure_=nil)
+      if rescue_bodies.any?
+        if else_t
+          compound_stmt =
+            n(:rescue,
+              [ compound_stmt, *(rescue_bodies + [ else_ ]) ],
+              eh_keyword_map(compound_stmt, nil, rescue_bodies, else_t, else_))
+        else
+          compound_stmt =
+            n(:rescue,
+              [ compound_stmt, *(rescue_bodies + [ nil ]) ],
+              eh_keyword_map(compound_stmt, nil, rescue_bodies, nil, nil))
+        end
+      end
+
+      if ensure_t
+        compound_stmt =
+          n(:ensure,
+            [ compound_stmt, ensure_ ],
+            eh_keyword_map(compound_stmt, ensure_t, [ ensure_ ], nil, nil))
+      end
+
+      compound_stmt
+    end
+
+    #
+    # Expression grouping
+    #
+
+    def compstmt(statements)
+      case
+      when statements.none?
+        nil
+      when statements.one?
+        statements.first
+      else
+        n(:begin, statements,
+          collection_map(nil, statements, nil))
+      end
+    end
+
+    def begin(begin_t, body, end_t)
+      if body.nil?
+        # A nil expression: `()'.
+        n0(:begin,
+          collection_map(begin_t, nil, end_t))
+      elsif body.type == :mlhs  ||
+           (body.type == :begin &&
+            body.loc.begin.nil? && body.loc.end.nil?)
+        # Synthesized (begin) from compstmt "a; b" or (mlhs)
+        # from multi_lhs "(a, b) = *foo".
+        n(body.type, body.children,
+          collection_map(begin_t, body.children, end_t))
+      else
+        n(:begin, [ body ],
+          collection_map(begin_t, [ body ], end_t))
+      end
+    end
+
+    def begin_keyword(begin_t, body, end_t)
+      if body.nil?
+        # A nil expression: `begin end'.
+        n0(:kwbegin,
+          collection_map(begin_t, nil, end_t))
+      elsif (body.type == :begin &&
+             body.loc.begin.nil? && body.loc.end.nil?)
+        # Synthesized (begin) from compstmt "a; b".
+        n(:kwbegin, body.children,
+          collection_map(begin_t, body.children, end_t))
+      else
+        n(:kwbegin, [ body ],
+          collection_map(begin_t, [ body ], end_t))
+      end
+    end
+
+    private
+
+    #
+    # VERIFICATION
+    #
+
+    def check_condition(cond)
+      case cond.type
+      when :masgn
+        diagnostic :error, :masgn_as_condition, nil, cond.loc.expression
+
+      when :begin
+        if cond.children.count == 1
+          cond.updated(nil, [
+            check_condition(cond.children.last)
+          ])
+        else
+          cond
+        end
+
+      when :and, :or, :irange, :erange
+        lhs, rhs = *cond
+
+        type = case cond.type
+        when :irange then :iflipflop
+        when :erange then :eflipflop
+        end
+
+        if [:and, :or].include?(cond.type) &&
+               @parser.version == 18
+          cond
+        else
+          cond.updated(type, [
+            check_condition(lhs),
+            check_condition(rhs)
+          ])
+        end
+
+      when :regexp
+        n(:match_current_line, [ cond ], expr_map(cond.loc.expression))
+
+      else
+        cond
+      end
+    end
+
+    def check_duplicate_args(args, map={})
+      args.each do |this_arg|
+        case this_arg.type
+        when :arg, :optarg, :restarg, :blockarg,
+             :kwarg, :kwoptarg, :kwrestarg,
+             :shadowarg
+
+          this_name, = *this_arg
+
+          that_arg   = map[this_name]
+          that_name, = *that_arg
+
+          if that_arg.nil?
+            map[this_name] = this_arg
+          elsif arg_name_collides?(this_name, that_name)
+            diagnostic :error, :duplicate_argument, nil,
+                       this_arg.loc.name, [ that_arg.loc.name ]
+          end
+
+        when :mlhs
+          check_duplicate_args(this_arg.children, map)
+        end
+      end
+    end
+
+    def arg_name_collides?(this_name, that_name)
+      case @parser.version
+      when 18
+        this_name == that_name
+      when 19
+        # Ignore underscore.
+        this_name != :_ &&
+          this_name == that_name
+      else
+        # Ignore everything beginning with underscore.
+        this_name && this_name[0] != '_' &&
+          this_name == that_name
+      end
+    end
+
+    #
+    # SOURCE MAPS
+    #
+
+    def n(type, children, source_map)
+      AST::Node.new(type, children, :location => source_map)
+    end
+
+    def n0(type, source_map)
+      n(type, [], source_map)
+    end
+
+    def join_exprs(left_expr, right_expr)
+      left_expr.loc.expression.
+        join(right_expr.loc.expression)
+    end
+
+    def token_map(token)
+      Source::Map.new(loc(token))
+    end
+
+    def delimited_string_map(string_t)
+      str_range = loc(string_t)
+
+      begin_l = Source::Range.new(str_range.source_buffer,
+                                  str_range.begin_pos,
+                                  str_range.begin_pos + 1)
+
+      end_l   = Source::Range.new(str_range.source_buffer,
+                                  str_range.end_pos - 1,
+                                  str_range.end_pos)
+
+      Source::Map::Collection.new(begin_l, end_l,
+                                  loc(string_t))
+    end
+
+    def prefix_string_map(symbol)
+      str_range = loc(symbol)
+
+      begin_l = Source::Range.new(str_range.source_buffer,
+                                  str_range.begin_pos,
+                                  str_range.begin_pos + 1)
+
+      Source::Map::Collection.new(begin_l, nil,
+                                  loc(symbol))
+    end
+
+    def unquoted_map(token)
+      Source::Map::Collection.new(nil, nil,
+                                  loc(token))
+    end
+
+    def pair_keyword_map(key_t, value_e)
+      key_range = loc(key_t)
+
+      key_l   = Source::Range.new(key_range.source_buffer,
+                                  key_range.begin_pos,
+                                  key_range.end_pos - 1)
+
+      colon_l = Source::Range.new(key_range.source_buffer,
+                                  key_range.end_pos - 1,
+                                  key_range.end_pos)
+
+      [ # key map
+        Source::Map::Collection.new(nil, nil,
+                                    key_l),
+        # pair map
+        Source::Map::Operator.new(colon_l,
+                                  key_range.join(value_e.loc.expression)) ]
+    end
+
+    def pair_quoted_map(begin_t, end_t, value_e)
+      end_l = loc(end_t)
+
+      quote_l = Source::Range.new(end_l.source_buffer,
+                                  end_l.end_pos - 2,
+                                  end_l.end_pos - 1)
+
+      colon_l = Source::Range.new(end_l.source_buffer,
+                                  end_l.end_pos - 1,
+                                  end_l.end_pos)
+
+      [ # modified end token
+        [ value(end_t), quote_l ],
+        # pair map
+        Source::Map::Operator.new(colon_l,
+                                  loc(begin_t).join(value_e.loc.expression)) ]
+    end
+
+    def expr_map(loc)
+      Source::Map.new(loc)
+    end
+
+    def collection_map(begin_t, parts, end_t)
+      if begin_t.nil? || end_t.nil?
+        if parts.any?
+          expr_l = join_exprs(parts.first, parts.last)
+        end
+      else
+        expr_l = loc(begin_t).join(loc(end_t))
+      end
+
+      Source::Map::Collection.new(loc(begin_t), loc(end_t), expr_l)
+    end
+
+    def string_map(begin_t, parts, end_t)
+      if begin_t && value(begin_t).start_with?('<<')
+        if parts.any?
+          expr_l = join_exprs(parts.first, parts.last)
+        else
+          expr_l = loc(end_t).begin
+        end
+
+        Source::Map::Heredoc.new(loc(begin_t), expr_l, loc(end_t))
+      else
+        collection_map(begin_t, parts, end_t)
+      end
+    end
+
+    def regexp_map(begin_t, end_t, options_e)
+      Source::Map::Collection.new(loc(begin_t), loc(end_t),
+                                  loc(begin_t).join(options_e.loc.expression))
+    end
+
+    def constant_map(scope, colon2_t, name_t)
+      if scope.nil?
+        expr_l = loc(name_t)
+      else
+        expr_l = scope.loc.expression.join(loc(name_t))
+      end
+
+      Source::Map::Constant.new(loc(colon2_t), loc(name_t), expr_l)
+    end
+
+    def variable_map(name_t)
+      Source::Map::Variable.new(loc(name_t))
+    end
+
+    def binary_op_map(left_e, op_t, right_e)
+      Source::Map::Operator.new(loc(op_t), join_exprs(left_e, right_e))
+    end
+
+    def unary_op_map(op_t, arg_e=nil)
+      if arg_e.nil?
+        expr_l = loc(op_t)
+      else
+        expr_l = loc(op_t).join(arg_e.loc.expression)
+      end
+
+      Source::Map::Operator.new(loc(op_t), expr_l)
+    end
+
+    def arg_prefix_map(op_t, name_t=nil)
+      if name_t.nil?
+        expr_l = loc(op_t)
+      else
+        expr_l = loc(op_t).join(loc(name_t))
+      end
+
+      Source::Map::Variable.new(loc(name_t), expr_l)
+    end
+
+    def kwarg_map(name_t, value_e=nil)
+      label_range = loc(name_t)
+      name_range  = Source::Range.new(label_range.source_buffer,
+                                      label_range.begin_pos,
+                                      label_range.end_pos - 1)
+
+      if value_e
+        expr_l = loc(name_t).join(value_e.loc.expression)
+      else
+        expr_l = loc(name_t)
+      end
+
+      Source::Map::Variable.new(name_range, expr_l)
+    end
+
+    def module_definition_map(keyword_t, name_e, operator_t, end_t)
+      if name_e
+        name_l = name_e.loc.expression
+      end
+
+      Source::Map::Definition.new(loc(keyword_t),
+                                  loc(operator_t), name_l,
+                                  loc(end_t))
+    end
+
+    def definition_map(keyword_t, operator_t, name_t, end_t)
+      Source::Map::Definition.new(loc(keyword_t),
+                                  loc(operator_t), loc(name_t),
+                                  loc(end_t))
+    end
+
+    def send_map(receiver_e, dot_t, selector_t, begin_t=nil, args=[], end_t=nil)
+      if receiver_e
+        begin_l = receiver_e.loc.expression
+      elsif selector_t
+        begin_l = loc(selector_t)
+      end
+
+      if end_t
+        end_l   = loc(end_t)
+      elsif args.any?
+        end_l   = args.last.loc.expression
+      elsif selector_t
+        end_l   = loc(selector_t)
+      end
+
+      Source::Map::Send.new(loc(dot_t),   loc(selector_t),
+                            loc(begin_t), loc(end_t),
+                            begin_l.join(end_l))
+    end
+
+    def var_send_map(variable_e)
+      Source::Map::Send.new(nil, variable_e.loc.expression,
+                            nil, nil,
+                            variable_e.loc.expression)
+    end
+
+    def send_binary_op_map(lhs_e, selector_t, rhs_e)
+      Source::Map::Send.new(nil, loc(selector_t),
+                            nil, nil,
+                            join_exprs(lhs_e, rhs_e))
+    end
+
+    def send_unary_op_map(selector_t, arg_e)
+      if arg_e.nil?
+        expr_l = loc(selector_t)
+      else
+        expr_l = loc(selector_t).join(arg_e.loc.expression)
+      end
+
+      Source::Map::Send.new(nil, loc(selector_t),
+                            nil, nil,
+                            expr_l)
+    end
+
+    def send_index_map(receiver_e, lbrack_t, rbrack_t)
+      Source::Map::Send.new(nil, loc(lbrack_t).join(loc(rbrack_t)),
+                            nil, nil,
+                            receiver_e.loc.expression.join(loc(rbrack_t)))
+    end
+
+    def block_map(receiver_l, begin_t, end_t)
+      Source::Map::Collection.new(loc(begin_t), loc(end_t),
+                                  receiver_l.join(loc(end_t)))
+    end
+
+    def keyword_map(keyword_t, begin_t, args, end_t)
+      args ||= []
+
+      if end_t
+        end_l = loc(end_t)
+      elsif args.any? && !args.last.nil?
+        end_l = args.last.loc.expression
+      elsif args.any? && args.count > 1
+        end_l = args[-2].loc.expression
+      else
+        end_l = loc(keyword_t)
+      end
+
+      Source::Map::Keyword.new(loc(keyword_t), loc(begin_t), loc(end_t),
+                               loc(keyword_t).join(end_l))
+    end
+
+    def keyword_mod_map(pre_e, keyword_t, post_e)
+      Source::Map::Keyword.new(loc(keyword_t), nil, nil,
+                               join_exprs(pre_e, post_e))
+    end
+
+    def condition_map(keyword_t, cond_e, begin_t, body_e, else_t, else_e, end_t)
+      if end_t
+        end_l = loc(end_t)
+      elsif else_e && else_e.loc.expression
+        end_l = else_e.loc.expression
+      elsif loc(else_t)
+        end_l = loc(else_t)
+      elsif body_e && body_e.loc.expression
+        end_l = body_e.loc.expression
+      elsif loc(begin_t)
+        end_l = loc(begin_t)
+      else
+        end_l = cond_e.loc.expression
+      end
+
+      Source::Map::Condition.new(loc(keyword_t),
+                                 loc(begin_t), loc(else_t), loc(end_t),
+                                 loc(keyword_t).join(end_l))
+    end
+
+    def ternary_map(begin_e, question_t, mid_e, colon_t, end_e)
+      Source::Map::Ternary.new(loc(question_t), loc(colon_t),
+                               join_exprs(begin_e, end_e))
+    end
+
+    def for_map(keyword_t, in_t, begin_t, end_t)
+      Source::Map::For.new(loc(keyword_t), loc(in_t),
+                           loc(begin_t), loc(end_t),
+                           loc(keyword_t).join(loc(end_t)))
+    end
+
+    def rescue_body_map(keyword_t, exc_list_e, assoc_t,
+                        exc_var_e, then_t,
+                        compstmt_e)
+      end_l = compstmt_e.loc.expression if compstmt_e
+      end_l = loc(then_t)               if end_l.nil? && then_t
+      end_l = exc_var_e.loc.expression  if end_l.nil? && exc_var_e
+      end_l = exc_list_e.loc.expression if end_l.nil? && exc_list_e
+      end_l = loc(keyword_t)            if end_l.nil?
+
+      Source::Map::RescueBody.new(loc(keyword_t), loc(assoc_t), loc(then_t),
+                                  loc(keyword_t).join(end_l))
+    end
+
+    def eh_keyword_map(compstmt_e, keyword_t, body_es,
+                       else_t, else_e)
+      if compstmt_e.nil?
+        if keyword_t.nil?
+          begin_l = body_es.first.loc.expression
+        else
+          begin_l = loc(keyword_t)
+        end
+      else
+        begin_l = compstmt_e.loc.expression
+      end
+
+      if else_t
+        if else_e.nil?
+          end_l = loc(else_t)
+        else
+          end_l = else_e.loc.expression
+        end
+      elsif !body_es.last.nil?
+        end_l = body_es.last.loc.expression
+      else
+        end_l = loc(keyword_t)
+      end
+
+      Source::Map::Condition.new(loc(keyword_t), nil, loc(else_t), nil,
+                                 begin_l.join(end_l))
+    end
+
+    #
+    # HELPERS
+    #
+
+    # Extract a static string from e.g. a regular expression,
+    # honoring the fact that MRI expands interpolations like #{""}
+    # at parse time.
+    def static_string(nodes)
+      nodes.map do |node|
+        case node.type
+        when :str
+          node.children[0]
+        when :begin
+          if (string = static_string(node.children))
+            string
+          else
+            return nil
+          end
+        else
+          return nil
+        end
+      end.join
+    end
+
+    def static_regexp(parts, options)
+      source = static_string(parts)
+      return nil if source.nil?
+
+      if defined?(Encoding)
+        source = case
+        when options.children.include?(:u)
+          source.encode(Encoding::UTF_8)
+        when options.children.include?(:e)
+          source.encode(Encoding::EUC_JP)
+        when options.children.include?(:s)
+          source.encode(Encoding::WINDOWS_31J)
+        when options.children.include?(:n)
+          source.encode(Encoding::BINARY)
+        else
+          source
+        end
+      end
+
+      Regexp.new(source, (Regexp::EXTENDED if options.children.include?(:x)))
+    end
+
+    def static_regexp_node(node)
+      if node.type == :regexp
+        parts, options = node.children[0..-2], node.children[-1]
+        static_regexp(parts, options)
+      end
+    end
+
+    def collapse_string_parts?(parts)
+      parts.one? &&
+          [:str, :dstr].include?(parts.first.type)
+    end
+
+    def value(token)
+      token[0]
+    end
+
+    def loc(token)
+      # Pass through `nil`s and return nil for tNL.
+      token[1] if token && token[0]
+    end
+
+    def diagnostic(type, reason, arguments, location, highlights=[])
+      @parser.diagnostics.process(
+          Diagnostic.new(type, reason, arguments, location, highlights))
+
+      if type == :error
+        @parser.send :yyerror
+      end
+    end
+  end
+
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/clobbering_error.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/clobbering_error.rb
new file mode 100644
index 0000000..bd9a016
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/clobbering_error.rb
@@ -0,0 +1,11 @@
+module Parser
+  ##
+  # {Parser::ClobberingError} is raised when {Parser::Source::Rewriter}
+  # detects a clobbering rewrite action. This class inherits {RuntimeError}
+  # rather than {StandardError} for backward compatibility.
+  #
+  # @api public
+  #
+  class ClobberingError < RuntimeError
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/compatibility/ruby1_8.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/compatibility/ruby1_8.rb
new file mode 100644
index 0000000..68b1924
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/compatibility/ruby1_8.rb
@@ -0,0 +1,20 @@
+##
+# @api public
+#
+# This monkeypatch extends Ruby 1.8 {String#%} with an ability
+# to replace named capture groups, i.e.
+# `"foo: %{bar}" % { :bar => 10 } # => "foo: 10"`.
+#
+class String
+  alias original_percent %
+
+  def %(arg, *args)
+    if arg.is_a?(Hash)
+      gsub(/%\{(\w+)\}/) do
+        arg[$1.to_sym]
+      end
+    else
+      original_percent(arg, *args)
+    end
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/compatibility/ruby1_9.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/compatibility/ruby1_9.rb
new file mode 100644
index 0000000..902da6c
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/compatibility/ruby1_9.rb
@@ -0,0 +1,32 @@
+unless Array.method_defined? :bsearch
+  class Array
+    def bsearch
+      return to_enum(__method__) unless block_given?
+      from = 0
+      to   = size - 1
+      satisfied = nil
+      while from <= to
+        midpoint = (from + to).div(2)
+        result = yield(cur = self[midpoint])
+        case result
+        when Numeric
+          return cur if result == 0
+          result = result < 0
+        when true
+          satisfied = cur
+        when nil, false
+          # nothing to do
+        else
+          fail TypeError, "wrong argument type #{result.class} (must be numeric, true, false or nil)"
+        end
+
+        if result
+          to = midpoint - 1
+        else
+          from = midpoint + 1
+        end
+      end
+      satisfied
+    end
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/current.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/current.rb
new file mode 100644
index 0000000..05ebe08
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/current.rb
@@ -0,0 +1,49 @@
+module Parser
+  class << self
+    def warn_syntax_deviation(feature, version)
+      warn "warning: parser/current is loading #{feature}, which recognizes"
+      warn "warning: #{version}-compliant syntax, but you are running #{RUBY_VERSION}."
+    end
+    private :warn_syntax_deviation
+  end
+
+  case RUBY_VERSION
+  when /^1\.8\./
+    if RUBY_VERSION != '1.8.7'
+      warn_syntax_deviation 'parser/ruby18', '1.8.7'
+    end
+
+    require 'parser/ruby18'
+    CurrentRuby = Ruby18
+
+  when /^1\.9\./
+    if RUBY_VERSION != '1.9.3'
+      warn_syntax_deviation 'parser/ruby19', '1.9.3'
+    end
+
+    require 'parser/ruby19'
+    CurrentRuby = Ruby19
+
+  when /^2\.0\./
+    require 'parser/ruby20'
+    CurrentRuby = Ruby20
+
+  when /^2\.1\./
+    if RUBY_VERSION != '2.1.6'
+      warn_syntax_deviation 'parser/ruby21', '2.1.6'
+    end
+
+    require 'parser/ruby21'
+    CurrentRuby = Ruby21
+
+  when /^2\.2\./
+    require 'parser/ruby22'
+    CurrentRuby = Ruby22
+
+  else # :nocov:
+    # Keep this in sync with released Ruby.
+    warn_syntax_deviation 'parser/ruby22', '2.2'
+    require 'parser/ruby22'
+    CurrentRuby = Ruby22
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/diagnostic.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/diagnostic.rb
new file mode 100644
index 0000000..c799b46
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/diagnostic.rb
@@ -0,0 +1,104 @@
+module Parser
+
+  ##
+  # @api public
+  #
+  # @!attribute [r] level
+  #  @see LEVELS
+  #  @return [Symbol] diagnostic level
+  #
+  # @!attribute [r] reason
+  #  @see Parser::MESSAGES
+  #  @return [Symbol] reason for error
+  #
+  # @!attribute [r] arguments
+  #  @see Parser::MESSAGES
+  #  @return [Symbol] extended arguments that describe the error
+  #
+  # @!attribute [r] message
+  #  @return [String] error message
+  #
+  # @!attribute [r] location
+  #  Main error-related source range.
+  #  @return [Parser::Source::Range]
+  #
+  # @!attribute [r] highlights
+  #  Supplementary error-related source ranges.
+  #  @return [Array<Parser::Source::Range>]
+  #
+  class Diagnostic
+    ##
+    # Collection of the available diagnostic levels.
+    #
+    # @return [Array]
+    #
+    LEVELS = [:note, :warning, :error, :fatal].freeze
+
+    attr_reader :level, :reason, :arguments
+    attr_reader :location, :highlights
+
+    ##
+    # @param [Symbol] level
+    # @param [Symbol] reason
+    # @param [Hash] arguments
+    # @param [Parser::Source::Range] location
+    # @param [Array<Parser::Source::Range>] highlights
+    #
+    def initialize(level, reason, arguments, location, highlights=[])
+      unless LEVELS.include?(level)
+        raise ArgumentError,
+              "Diagnostic#level must be one of #{LEVELS.join(', ')}; " \
+              "#{level.inspect} provided."
+      end
+      raise 'Expected a location' unless location
+
+      @level       = level
+      @reason      = reason
+      @arguments   = (arguments || {}).dup.freeze
+      @location    = location
+      @highlights  = highlights.dup.freeze
+
+      freeze
+    end
+
+    ##
+    # @return [String] the rendered message.
+    #
+    def message
+      MESSAGES[@reason] % @arguments
+    end
+
+    ##
+    # Renders the diagnostic message as a clang-like diagnostic.
+    #
+    # @example
+    #  diagnostic.render # =>
+    #  # [
+    #  #   "(fragment:0):1:5: error: unexpected token $end",
+    #  #   "foo +",
+    #  #   "    ^"
+    #  # ]
+    #
+    # @return [Array<String>]
+    #
+    def render
+      source_line    = @location.source_line
+      highlight_line = ' ' * source_line.length
+
+      @highlights.each do |hilight|
+        range = hilight.column_range
+        highlight_line[range] = '~' * hilight.size
+      end
+
+      range = @location.column_range
+      highlight_line[range] = '^' * @location.size
+
+      [
+        "#{@location.to_s}: #{@level}: #{message}",
+        source_line,
+        highlight_line,
+      ]
+    end
+  end
+
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/diagnostic/engine.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/diagnostic/engine.rb
new file mode 100644
index 0000000..0a6cf46
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/diagnostic/engine.rb
@@ -0,0 +1,103 @@
+module Parser
+
+  ##
+  # {Parser::Diagnostic::Engine} provides a basic API for dealing with
+  # diagnostics by delegating them to registered consumers.
+  #
+  # @example
+  #  buffer      = Parser::Source::Buffer.new(__FILE__)
+  #  buffer.code = 'foobar'
+  #
+  #  consumer = lambda do |diagnostic|
+  #    puts diagnostic.message
+  #  end
+  #
+  #  engine     = Parser::Diagnostic::Engine.new(consumer)
+  #  diagnostic = Parser::Diagnostic.new(
+  #      :warning, :unexpected_token, { :token => 'abc' }, buffer, 1..2)
+  #
+  #  engine.process(diagnostic) # => "unexpected token abc"
+  #
+  # @api public
+  #
+  # @!attribute [rw] consumer
+  #  @return [#call(Diagnostic)]
+  #
+  # @!attribute [rw] all_errors_are_fatal
+  #  When set to `true` any error that is encountered will result in
+  #  {Parser::SyntaxError} being raised.
+  #  @return [Boolean]
+  #
+  # @!attribute [rw] ignore_warnings
+  #  When set to `true` warnings will be ignored.
+  #  @return [Boolean]
+  #
+  class Diagnostic::Engine
+    attr_accessor :consumer
+
+    attr_accessor :all_errors_are_fatal
+    attr_accessor :ignore_warnings
+
+    ##
+    # @param [#call(Diagnostic)] consumer
+    #
+    def initialize(consumer=nil)
+      @consumer             = consumer
+
+      @all_errors_are_fatal = false
+      @ignore_warnings      = false
+    end
+
+    ##
+    # Processes a `diagnostic`:
+    #   * Passes the diagnostic to the consumer, if it's not a warning when
+    #     `ignore_warnings` is set.
+    #   * After that, raises {Parser::SyntaxError} when `all_errors_are_fatal`
+    #     is set to true.
+    #
+    # @param [Parser::Diagnostic] diagnostic
+    # @return [Parser::Diagnostic::Engine]
+    # @see ignore?
+    # @see raise?
+    #
+    def process(diagnostic)
+      if ignore?(diagnostic)
+        # do nothing
+      elsif @consumer
+        @consumer.call(diagnostic)
+      end
+
+      if raise?(diagnostic)
+        raise Parser::SyntaxError, diagnostic
+      end
+
+      self
+    end
+
+    protected
+
+    ##
+    # Checks whether `diagnostic` should be ignored.
+    #
+    # @param [Parser::Diagnostic] diagnostic
+    # @return [Boolean]
+    #
+    def ignore?(diagnostic)
+      @ignore_warnings &&
+            diagnostic.level == :warning
+    end
+
+    ##
+    # Checks whether `diagnostic` should be raised as an exception.
+    #
+    # @param [Parser::Diagnostic] diagnostic
+    # @return [Boolean]
+    #
+    def raise?(diagnostic)
+      (@all_errors_are_fatal &&
+          diagnostic.level == :error) ||
+        diagnostic.level == :fatal
+    end
+  end
+
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/lexer.rl b/app/server/vendor/parser-2.2.2.1/lib/parser/lexer.rl
new file mode 100644
index 0000000..efde186
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/lexer.rl
@@ -0,0 +1,2211 @@
+%%machine lex; # % fix highlighting
+
+#
+# === BEFORE YOU START ===
+#
+# Read the Ruby Hacking Guide chapter 11, available in English at
+# http://whitequark.org/blog/2013/04/01/ruby-hacking-guide-ch-11-finite-state-lexer/
+#
+# Remember two things about Ragel scanners:
+#
+#   1) Longest match wins.
+#
+#   2) If two matches have the same length, the first
+#      in source code wins.
+#
+# General rules of making Ragel and Bison happy:
+#
+#  * `p` (position) and `@te` contain the index of the character
+#    they're pointing to ("current"), plus one. `@ts` contains the index
+#    of the corresponding character. The code for extracting matched token is:
+#
+#       @source[@ts... at te]
+#
+#  * If your input is `foooooooobar` and the rule is:
+#
+#       'f' 'o'+
+#
+#    the result will be:
+#
+#       foooooooobar
+#       ^ ts=0   ^ p=te=9
+#
+#  * A Ragel lexer action should not emit more than one token, unless
+#    you know what you are doing.
+#
+#  * All Ragel commands (fnext, fgoto, ...) end with a semicolon.
+#
+#  * If an action emits the token and transitions to another state, use
+#    these Ragel commands:
+#
+#       emit($whatever)
+#       fnext $next_state; fbreak;
+#
+#    If you perform `fgoto` in an action which does not emit a token nor
+#    rewinds the stream pointer, the parser's side-effectful,
+#    context-sensitive lookahead actions will break in a hard to detect
+#    and debug way.
+#
+#  * If an action does not emit a token:
+#
+#       fgoto $next_state;
+#
+#  * If an action features lookbehind, i.e. matches characters with the
+#    intent of passing them to another action:
+#
+#       p = @ts - 1
+#       fgoto $next_state;
+#
+#    or, if the lookbehind consists of a single character:
+#
+#       fhold; fgoto $next_state;
+#
+#  * Ragel merges actions. So, if you have `e_lparen = '(' %act` and
+#    `c_lparen = '('` and a lexer action `e_lparen | c_lparen`, the result
+#    _will_ invoke the action `act`.
+#
+#    e_something stands for "something with **e**mbedded action".
+#
+#  * EOF is explicit and is matched by `c_eof`. If you want to introspect
+#    the state of the lexer, add this rule to the state:
+#
+#       c_eof => do_eof;
+#
+#  * If you proceed past EOF, the lexer will complain:
+#
+#       NoMethodError: undefined method `ord' for nil:NilClass
+#
+
+class Parser::Lexer
+
+  %% write data nofinal;
+  # %
+
+  ESCAPES = {
+    'a' => "\a", 'b'  => "\b", 'e'  => "\e", 'f' => "\f",
+    'n' => "\n", 'r'  => "\r", 's'  => "\s", 't' => "\t",
+    'v' => "\v", '\\' => "\\"
+  }
+
+  attr_reader   :source_buffer
+  attr_reader   :encoding
+
+  attr_accessor :diagnostics
+  attr_accessor :static_env
+  attr_accessor :force_utf32
+
+  attr_accessor :cond, :cmdarg, :in_kwarg
+
+  attr_accessor :tokens, :comments
+
+  def initialize(version)
+    @version    = version
+    @static_env = nil
+
+    @tokens     = nil
+    @comments   = nil
+
+    reset
+  end
+
+  def reset(reset_state=true)
+    # Ragel state:
+    if reset_state
+      # Unit tests set state prior to resetting lexer.
+      @cs     = self.class.lex_en_line_begin
+
+      @cond   = StackState.new('cond')
+      @cmdarg = StackState.new('cmdarg')
+      @cond_stack   = []
+      @cmdarg_stack = []
+    end
+
+    @force_utf32   = false # Set to true by some tests
+
+    @source        = nil # source string
+    @source_pts    = nil # @source as a codepoint array
+    @encoding      = nil # target encoding for output strings
+
+    @p             = 0   # stream position (saved manually in #advance)
+    @ts            = nil # token start
+    @te            = nil # token end
+    @act           = 0   # next action
+
+    @stack         = []  # state stack
+    @top           = 0   # state stack top pointer
+
+    # Lexer state:
+    @token_queue   = []
+    @literal_stack = []
+
+    @eq_begin_s    = nil # location of last encountered =begin
+    @sharp_s       = nil # location of last encountered #
+
+    @newline_s     = nil # location of last encountered newline
+
+    @num_base      = nil # last numeric base
+    @num_digits_s  = nil # starting position of numeric digits
+    @num_suffix_s  = nil # starting position of numeric suffix
+    @num_xfrm      = nil # numeric suffix-induced transformation
+
+    @escape_s      = nil # starting position of current sequence
+    @escape        = nil # last escaped sequence, as string
+
+    # See below the section on parsing heredocs.
+    @heredoc_e     = nil
+    @herebody_s    = nil
+
+    # Ruby 1.9 ->() lambdas emit a distinct token if do/{ is
+    # encountered after a matching closing parenthesis.
+    @paren_nest    = 0
+    @lambda_stack  = []
+
+    # If the lexer is in `command state' (aka expr_value)
+    # at the entry to #advance, it will transition to expr_cmdarg
+    # instead of expr_arg at certain points.
+    @command_state = false
+
+    # True at the end of "def foo a:"
+    @in_kwarg      = false
+  end
+
+  def source_buffer=(source_buffer)
+    @source_buffer = source_buffer
+
+    if @source_buffer
+      @source = @source_buffer.source
+
+      if defined?(Encoding)
+        @encoding   = @source.encoding
+
+        # This is a workaround for 1.9.2, which (without force_encoding)
+        # would convert the result to UTF-8 (source encoding of lexer.rl).
+        @source    += "\0".force_encoding(@encoding)
+      else
+        @source    += "\0"
+      end
+
+      if defined?(Encoding) && @source.encoding == Encoding::UTF_8
+        @source_pts = @source.unpack('U*')
+      else
+        @source_pts = @source.unpack('C*')
+      end
+
+      if (@source_pts.size > 1_000_000 && @source.respond_to?(:encode)) ||
+         @force_utf32
+        # A heuristic: if the buffer is larger than 1M, then
+        # store it in UTF-32 and convert the tokens as they're
+        # going out. If it's smaller, the conversion overhead
+        # dominates runtime and this stops being beneficial.
+        #
+        # This is not really a good heuristic, as the result
+        # heavily depends on token/character ratio. If it's low,
+        # say the gem consists mostly of long identifiers and
+        # symbols, then storing the source in UTF-8 would be faster.
+        #
+        # Patches accepted.
+        @source = @source.encode(Encoding::UTF_32LE)
+      end
+
+      if @source_pts[0] == 0xfeff
+        # Skip byte order mark.
+        @p = 1
+      end
+    else
+      @source     = nil
+      @source_pts = nil
+    end
+  end
+
+  LEX_STATES = {
+    :line_begin    => lex_en_line_begin,
+    :expr_dot      => lex_en_expr_dot,
+    :expr_fname    => lex_en_expr_fname,
+    :expr_value    => lex_en_expr_value,
+    :expr_beg      => lex_en_expr_beg,
+    :expr_mid      => lex_en_expr_mid,
+    :expr_arg      => lex_en_expr_arg,
+    :expr_cmdarg   => lex_en_expr_cmdarg,
+    :expr_end      => lex_en_expr_end,
+    :expr_endarg   => lex_en_expr_endarg,
+    :expr_endfn    => lex_en_expr_endfn,
+    :expr_labelarg => lex_en_expr_labelarg,
+
+    :interp_string => lex_en_interp_string,
+    :interp_words  => lex_en_interp_words,
+    :plain_string  => lex_en_plain_string,
+    :plain_words   => lex_en_plain_string,
+  }
+
+  def state
+    LEX_STATES.invert.fetch(@cs, @cs)
+  end
+
+  def state=(state)
+    @cs = LEX_STATES.fetch(state)
+  end
+
+  def push_cmdarg
+    @cmdarg_stack.push(@cmdarg)
+    @cmdarg = StackState.new("cmdarg.#{@cmdarg_stack.count}")
+  end
+
+  def pop_cmdarg
+    @cmdarg = @cmdarg_stack.pop
+  end
+
+  def push_cond
+    @cond_stack.push(@cond)
+    @cond = StackState.new("cond.#{@cond_stack.count}")
+  end
+
+  def pop_cond
+    @cond = @cond_stack.pop
+  end
+
+  # Return next token: [type, value].
+  def advance
+    if @token_queue.any?
+      return @token_queue.shift
+    end
+
+    # Ugly, but dependent on Ragel output. Consider refactoring it somehow.
+    _lex_trans_keys         = self.class.send :_lex_trans_keys
+    _lex_key_spans          = self.class.send :_lex_key_spans
+    _lex_index_offsets      = self.class.send :_lex_index_offsets
+    _lex_indicies           = self.class.send :_lex_indicies
+    _lex_trans_targs        = self.class.send :_lex_trans_targs
+    _lex_trans_actions      = self.class.send :_lex_trans_actions
+    _lex_to_state_actions   = self.class.send :_lex_to_state_actions
+    _lex_from_state_actions = self.class.send :_lex_from_state_actions
+    _lex_eof_trans          = self.class.send :_lex_eof_trans
+
+    p, pe, eof = @p, @source.length + 1, @source.length + 1
+
+    @command_state = (@cs == self.class.lex_en_expr_value ||
+                      @cs == self.class.lex_en_line_begin)
+
+    %% write exec;
+    # %
+
+    @p = p
+
+    if @token_queue.any?
+      @token_queue.shift
+    elsif @cs == self.class.lex_error
+      [ false, [ '$error', range(p - 1, p) ] ]
+    else
+      [ false, [ '$eof',   range(p, p)     ] ]
+    end
+  end
+
+  protected
+
+  def eof_codepoint?(point)
+    [0x04, 0x1a, 0x00].include? point
+  end
+
+  def version?(*versions)
+    versions.include?(@version)
+  end
+
+  def stack_pop
+    @top -= 1
+    @stack[@top]
+  end
+
+  if "".respond_to?(:encode)
+    def encode_escape(ord)
+      ord.chr.force_encoding(@encoding)
+    end
+
+    def tok(s = @ts, e = @te)
+      @source[s...e].encode(@encoding)
+    end
+  else
+    def encode_escape(ord)
+      ord.chr
+    end
+
+    def tok(s = @ts, e = @te)
+      @source[s...e]
+    end
+  end
+
+  def range(s = @ts, e = @te)
+    Parser::Source::Range.new(@source_buffer, s, e)
+  end
+
+  def emit(type, value = tok, s = @ts, e = @te)
+    token = [ type, [ value, range(s, e) ] ]
+
+    @token_queue.push(token)
+
+    @tokens.push(token) if @tokens
+
+    token
+  end
+
+  def emit_table(table, s = @ts, e = @te)
+    value = tok(s, e)
+
+    emit(table[value], value, s, e)
+  end
+
+  def emit_do(do_block=false)
+    if @cond.active?
+      emit(:kDO_COND)
+    elsif @cmdarg.active? || do_block
+      emit(:kDO_BLOCK)
+    else
+      emit(:kDO)
+    end
+  end
+
+  def arg_or_cmdarg
+    if @command_state
+      self.class.lex_en_expr_cmdarg
+    else
+      self.class.lex_en_expr_arg
+    end
+  end
+
+  def emit_comment(s = @ts, e = @te)
+    if @comments
+      @comments.push(Parser::Source::Comment.new(range(s, e)))
+    end
+
+    if @tokens
+      @tokens.push([ :tCOMMENT, [ tok(s, e), range(s, e) ] ])
+    end
+
+    nil
+  end
+
+  def diagnostic(type, reason, arguments=nil, location=range, highlights=[])
+    @diagnostics.process(
+        Parser::Diagnostic.new(type, reason, arguments, location, highlights))
+  end
+
+  #
+  # === LITERAL STACK ===
+  #
+
+  def push_literal(*args)
+    new_literal = Literal.new(self, *args)
+    @literal_stack.push(new_literal)
+
+    if new_literal.words?
+      if new_literal.interpolate?
+        self.class.lex_en_interp_words
+      else
+        self.class.lex_en_plain_words
+      end
+    else
+      if new_literal.interpolate?
+        self.class.lex_en_interp_string
+      else
+        self.class.lex_en_plain_string
+      end
+    end
+  end
+
+  def literal
+    @literal_stack.last
+  end
+
+  def pop_literal
+    old_literal = @literal_stack.pop
+
+    if old_literal.type == :tREGEXP_BEG
+      # Fetch modifiers.
+      self.class.lex_en_regexp_modifiers
+    else
+      self.class.lex_en_expr_end
+    end
+  end
+
+  # Mapping of strings to parser tokens.
+
+  PUNCTUATION = {
+    '='   => :tEQL,     '&'   => :tAMPER2,  '|'   => :tPIPE,
+    '!'   => :tBANG,    '^'   => :tCARET,   '+'   => :tPLUS,
+    '-'   => :tMINUS,   '*'   => :tSTAR2,   '/'   => :tDIVIDE,
+    '%'   => :tPERCENT, '~'   => :tTILDE,   ','   => :tCOMMA,
+    ';'   => :tSEMI,    '.'   => :tDOT,     '..'  => :tDOT2,
+    '...' => :tDOT3,    '['   => :tLBRACK2, ']'   => :tRBRACK,
+    '('   => :tLPAREN2, ')'   => :tRPAREN,  '?'   => :tEH,
+    ':'   => :tCOLON,   '&&'  => :tANDOP,   '||'  => :tOROP,
+    '-@'  => :tUMINUS,  '+@'  => :tUPLUS,   '~@'  => :tTILDE,
+    '**'  => :tPOW,     '->'  => :tLAMBDA,  '=~'  => :tMATCH,
+    '!~'  => :tNMATCH,  '=='  => :tEQ,      '!='  => :tNEQ,
+    '>'   => :tGT,      '>>'  => :tRSHFT,   '>='  => :tGEQ,
+    '<'   => :tLT,      '<<'  => :tLSHFT,   '<='  => :tLEQ,
+    '=>'  => :tASSOC,   '::'  => :tCOLON2,  '===' => :tEQQ,
+    '<=>' => :tCMP,     '[]'  => :tAREF,    '[]=' => :tASET,
+    '{'   => :tLCURLY,  '}'   => :tRCURLY,  '`'   => :tBACK_REF2,
+    '!@'  => :tBANG,
+  }
+
+  PUNCTUATION_BEGIN = {
+    '&'   => :tAMPER,   '*'   => :tSTAR,    '**'  => :tDSTAR,
+    '+'   => :tUPLUS,   '-'   => :tUMINUS,  '::'  => :tCOLON3,
+    '('   => :tLPAREN,  '{'   => :tLBRACE,  '['   => :tLBRACK,
+  }
+
+  KEYWORDS = {
+    'if'     => :kIF_MOD,      'unless'   => :kUNLESS_MOD,
+    'while'  => :kWHILE_MOD,   'until'    => :kUNTIL_MOD,
+    'rescue' => :kRESCUE_MOD,  'defined?' => :kDEFINED,
+    'BEGIN'  => :klBEGIN,      'END'      => :klEND,
+  }
+
+  KEYWORDS_BEGIN = {
+    'if'     => :kIF,          'unless'   => :kUNLESS,
+    'while'  => :kWHILE,       'until'    => :kUNTIL,
+    'rescue' => :kRESCUE,      'defined?' => :kDEFINED,
+  }
+
+  %w(class module def undef begin end then elsif else ensure case when
+     for break next redo retry in do return yield super self nil true
+     false and or not alias __FILE__ __LINE__ __ENCODING__).each do |keyword|
+    KEYWORDS_BEGIN[keyword] = KEYWORDS[keyword] = :"k#{keyword.upcase}"
+  end
+
+  %%{
+  # %
+
+  access @;
+  getkey (@source_pts[p] || 0);
+
+  # === CHARACTER CLASSES ===
+  #
+  # Pay close attention to the differences between c_any and any.
+  # c_any does not include EOF and so will cause incorrect behavior
+  # for machine subtraction (any-except rules) and default transitions
+  # for scanners.
+
+  action do_nl {
+    # Record position of a newline for precise location reporting on tNL
+    # tokens.
+    #
+    # This action is embedded directly into c_nl, as it is idempotent and
+    # there are no cases when we need to skip it.
+    @newline_s = p
+  }
+
+  c_nl       = '\n' $ do_nl;
+  c_space    = [ \t\r\f\v];
+  c_space_nl = c_space | c_nl;
+
+  c_eof      = 0x04 | 0x1a | 0 | zlen; # ^D, ^Z, \0, EOF
+  c_eol      = c_nl | c_eof;
+  c_any      = any - c_eof;
+
+  c_nl_zlen  = c_nl | zlen;
+  c_line     = any - c_nl_zlen;
+
+  c_unicode  = c_any - 0x00..0x7f;
+  c_upper    = [A-Z];
+  c_lower    = [a-z_]  | c_unicode;
+  c_alpha    = c_lower | c_upper;
+  c_alnum    = c_alpha | [0-9];
+
+  action do_eof {
+    # Sit at EOF indefinitely. #advance would return $eof each time.
+    # This allows to feed the lexer more data if needed; this is only used
+    # in tests.
+    #
+    # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs
+    # below. This is due to the fact that scanner state at EOF is observed
+    # by tests, and encapsulating it in a rule would break the introspection.
+    fhold; fbreak;
+  }
+
+  #
+  # === TOKEN DEFINITIONS ===
+  #
+
+  # All operators are punctuation. There is more to punctuation
+  # than just operators. Operators can be overridden by user;
+  # punctuation can not.
+
+  # A list of operators which are valid in the function name context, but
+  # have different semantics in others.
+  operator_fname      = '[]' | '[]=' | '`'  | '-@' | '+@' | '~@'  | '!@' ;
+
+  # A list of operators which can occur within an assignment shortcut (+ → +=).
+  operator_arithmetic = '&'  | '|'   | '&&' | '||' | '^'  | '+'   | '-'  |
+                        '*'  | '/'   | '**' | '~'  | '<<' | '>>'  | '%'  ;
+
+  # A list of all user-definable operators not covered by groups above.
+  operator_rest       = '=~' | '!~' | '==' | '!=' | '!'   | '===' |
+                        '<'  | '<=' | '>'  | '>=' | '<=>' | '=>'  ;
+
+  # Note that `{` and `}` need to be referred to as e_lbrace and e_rbrace,
+  # as they are ambiguous with interpolation `#{}` and should be counted.
+  # These braces are not present in punctuation lists.
+
+  # A list of punctuation which has different meaning when used at the
+  # beginning of expression.
+  punctuation_begin   = '-'  | '+'  | '::' | '('  | '['  |
+                        '*'  | '**' | '&'  ;
+
+  # A list of all punctuation except punctuation_begin.
+  punctuation_end     = ','  | '='  | '->' | '('  | '['  | ']'   |
+                        '::' | '?'  | ':'  | '.'  | '..' | '...' ;
+
+  # A list of keywords which have different meaning at the beginning of expression.
+  keyword_modifier    = 'if'     | 'unless' | 'while'  | 'until' | 'rescue' ;
+
+  # A list of keywords which accept an argument-like expression, i.e. have the
+  # same post-processing as method calls or commands. Example: `yield 1`,
+  # `yield (1)`, `yield(1)`, are interpreted as if `yield` was a function.
+  keyword_with_arg    = 'yield'  | 'super'  | 'not'    | 'defined?' ;
+
+  # A list of keywords which accept a literal function name as an argument.
+  keyword_with_fname  = 'def'    | 'undef'  | 'alias'  ;
+
+  # A list of keywords which accept an expression after them.
+  keyword_with_value  = 'else'   | 'case'   | 'ensure' | 'module' | 'elsif' | 'then'  |
+                        'for'    | 'in'     | 'do'     | 'when'   | 'begin' | 'class' |
+                        'and'    | 'or'     ;
+
+  # A list of keywords which accept a value, and treat the keywords from
+  # `keyword_modifier` list as modifiers.
+  keyword_with_mid    = 'rescue' | 'return' | 'break'  | 'next'   ;
+
+  # A list of keywords which do not accept an expression after them.
+  keyword_with_end    = 'end'    | 'self'   | 'true'   | 'false'  | 'retry'    |
+                        'redo'   | 'nil'    | 'BEGIN'  | 'END'    | '__FILE__' |
+                        '__LINE__' | '__ENCODING__';
+
+  # All keywords.
+  keyword             = keyword_with_value | keyword_with_mid |
+                        keyword_with_end   | keyword_with_arg |
+                        keyword_with_fname | keyword_modifier ;
+
+  constant       = c_upper c_alnum*;
+  bareword       = c_alpha c_alnum*;
+
+  call_or_var    = c_lower c_alnum*;
+  class_var      = '@@' bareword;
+  instance_var   = '@' bareword;
+  global_var     = '$'
+      ( bareword | digit+
+      | [`'+~*$&?!@/\\;,.=:<>"] # `
+      | '-' c_alnum
+      )
+  ;
+
+  # Ruby accepts (and fails on) variables with leading digit
+  # in literal context, but not in unquoted symbol body.
+  class_var_v    = '@@' c_alnum+;
+  instance_var_v = '@' c_alnum+;
+
+  label          = bareword [?!]? ':';
+
+  #
+  # === NUMERIC PARSING ===
+  #
+
+  int_hex  = ( xdigit+ '_' )* xdigit* '_'? ;
+  int_dec  = ( digit+ '_' )* digit* '_'? ;
+  int_bin  = ( [01]+ '_' )* [01]* '_'? ;
+
+  flo_int  = [1-9] [0-9]* ( '_' digit+ )* | '0';
+  flo_frac = '.' ( digit+ '_' )* digit+;
+  flo_pow  = [eE] [+\-]? ( digit+ '_' )* digit+;
+
+  int_suffix =
+    ''   % { @num_xfrm = lambda { |chars|  emit(:tINTEGER,   chars) } }
+  | 'r'  % { @num_xfrm = lambda { |chars|  emit(:tRATIONAL,  Rational(chars)) } }
+  | 'i'  % { @num_xfrm = lambda { |chars|  emit(:tIMAGINARY, Complex(0, chars)) } }
+  | 'ri' % { @num_xfrm = lambda { |chars|  emit(:tIMAGINARY, Complex(0, Rational(chars))) } };
+
+  flo_pow_suffix =
+    ''   % { @num_xfrm = lambda { |chars| emit(:tFLOAT,     Float(chars)) } }
+  | 'i'  % { @num_xfrm = lambda { |chars| emit(:tIMAGINARY, Complex(0, Float(chars))) } };
+
+  flo_suffix =
+    flo_pow_suffix
+  | 'r'  % { @num_xfrm = lambda { |chars| emit(:tRATIONAL,  Rational(chars)) } }
+  | 'ri' % { @num_xfrm = lambda { |chars| emit(:tIMAGINARY, Complex(0, Rational(chars))) } };
+
+  #
+  # === ESCAPE SEQUENCE PARSING ===
+  #
+
+  # Escape parsing code is a Ragel pattern, not a scanner, and therefore
+  # it shouldn't directly raise errors or perform other actions with side effects.
+  # In reality this would probably just mess up error reporting in pathological
+  # cases, through.
+
+  # The amount of code required to parse \M\C stuff correctly is ridiculous.
+
+  escaped_nl = "\\" c_nl;
+
+  action unicode_points {
+    @escape = ""
+
+    codepoints  = tok(@escape_s + 2, p - 1)
+    codepoint_s = @escape_s + 2
+
+    codepoints.split(/[ \t]/).each do |codepoint_str|
+      codepoint = codepoint_str.to_i(16)
+
+      if codepoint >= 0x110000
+        @escape = lambda do
+          diagnostic :error, :unicode_point_too_large, nil,
+                     range(codepoint_s, codepoint_s + codepoint_str.length)
+        end
+
+        break
+      end
+
+      @escape     += codepoint.chr(Encoding::UTF_8)
+      codepoint_s += codepoint_str.length + 1
+    end
+  }
+
+  action unescape_char {
+    char = @source[p - 1].chr
+    @escape = ESCAPES.fetch(char, char)
+  }
+
+  action invalid_complex_escape {
+    @escape = lambda do
+      diagnostic :fatal, :invalid_escape
+    end
+  }
+
+  action slash_c_char {
+    @escape = encode_escape(@escape[0].ord & 0x9f)
+  }
+
+  action slash_m_char {
+    @escape = encode_escape(@escape[0].ord | 0x80)
+  }
+
+  maybe_escaped_char = (
+        '\\' c_any      %unescape_char
+    | ( c_any - [\\] )  % { @escape = @source[p - 1].chr }
+  );
+
+  maybe_escaped_ctrl_char = ( # why?!
+        '\\' c_any      %unescape_char %slash_c_char
+    |   '?'             % { @escape = "\x7f" }
+    | ( c_any - [\\?] ) % { @escape = @source[p - 1].chr } %slash_c_char
+  );
+
+  escape = (
+      # \377
+      [0-7]{1,3}
+      % { @escape = encode_escape(tok(@escape_s, p).to_i(8) % 0x100) }
+
+      # \xff
+    | ( 'x' xdigit{1,2}
+        % { @escape = encode_escape(tok(@escape_s + 1, p).to_i(16)) }
+      # \u263a
+      | 'u' xdigit{4}
+        % { @escape = tok(@escape_s + 1, p).to_i(16).chr(Encoding::UTF_8) }
+      )
+
+      # %q[\x]
+    | 'x' ( c_any - xdigit )
+      % {
+        @escape = lambda do
+          diagnostic :fatal, :invalid_hex_escape, nil,
+                     range(@escape_s - 1, p + 2)
+        end
+      }
+
+      # %q[\u123] %q[\u{12]
+    | 'u' ( c_any{0,4}  -
+            xdigit{4}   -           # \u1234 is valid
+            ( '{' xdigit{1,3}       # \u{1 \u{12 \u{123 are valid
+            | '{' xdigit [ \t}] any # \u{1. \u{1} are valid
+            | '{' xdigit{2} [ \t}]  # \u{12. \u{12} are valid
+            )
+          )
+      % {
+        @escape = lambda do
+          diagnostic :fatal, :invalid_unicode_escape, nil,
+                     range(@escape_s - 1, p)
+        end
+      }
+
+      # \u{123 456}
+    | 'u{' ( xdigit{1,6} [ \t] )*
+      ( xdigit{1,6} '}'
+        %unicode_points
+      | ( xdigit* ( c_any - xdigit - '}' )+ '}'
+        | ( c_any - '}' )* c_eof
+        | xdigit{7,}
+        ) % {
+          @escape = lambda do
+            diagnostic :fatal, :unterminated_unicode, nil,
+                       range(p - 1, p)
+          end
+        }
+      )
+
+      # \C-\a \cx
+    | ( 'C-' | 'c' ) escaped_nl?
+      maybe_escaped_ctrl_char
+
+      # \M-a
+    | 'M-' escaped_nl?
+      maybe_escaped_char
+      %slash_m_char
+
+      # \C-\M-f \M-\cf \c\M-f
+    | ( ( 'C-'   | 'c' ) escaped_nl?   '\\M-'
+      |   'M-\\'         escaped_nl? ( 'C-'   | 'c' ) ) escaped_nl?
+      maybe_escaped_ctrl_char
+      %slash_m_char
+
+    | 'C' c_any %invalid_complex_escape
+    | 'M' c_any %invalid_complex_escape
+    | ( 'M-\\C' | 'C-\\M' ) c_any %invalid_complex_escape
+
+    | ( c_any - [0-7xuCMc] ) %unescape_char
+
+    | c_eof % {
+      diagnostic :fatal, :escape_eof, nil, range(p - 1, p)
+    }
+  );
+
+  # Use rules in form of `e_bs escape' when you need to parse a sequence.
+  e_bs = '\\' % {
+    @escape_s = p
+    @escape   = nil
+  };
+
+  #
+  # === STRING AND HEREDOC PARSING ===
+  #
+
+  # Heredoc parsing is quite a complex topic. First, consider that heredocs
+  # can be arbitrarily nested. For example:
+  #
+  #     puts <<CODE
+  #     the result is: #{<<RESULT.inspect
+  #       i am a heredoc
+  #     RESULT
+  #     }
+  #     CODE
+  #
+  # which, incidentally, evaluates to:
+  #
+  #     the result is: "  i am a heredoc\n"
+  #
+  # To parse them, lexer refers to two kinds (remember, nested heredocs)
+  # of positions in the input stream, namely @heredoc_e
+  # (HEREDOC declaration End) and @herebody_s (HEREdoc BODY line Start).
+  #
+  # @heredoc_e is simply contained inside the corresponding Literal, and
+  # when the heredoc is closed, the lexing is restarted from that position.
+  #
+  # @herebody_s is quite more complex. First, @herebody_s changes after each
+  # heredoc line is lexed. This way, at '\n' tok(@herebody_s, @te) always
+  # contains the current line, and also when a heredoc is started, @herebody_s
+  # contains the position from which the heredoc will be lexed.
+  #
+  # Second, as (insanity) there are nested heredocs, we need to maintain a
+  # stack of these positions. Each time #push_literal is called, it saves current
+  # @heredoc_s to literal.saved_herebody_s, and after an interpolation (possibly
+  # containing another heredocs) is closed, the previous value is restored.
+
+  e_heredoc_nl = c_nl % {
+    # After every heredoc was parsed, @herebody_s contains the
+    # position of next token after all heredocs.
+    if @herebody_s
+      p = @herebody_s
+      @herebody_s = nil
+    end
+  };
+
+  action extend_string {
+    string = @source[@ts... at te]
+    string = string.encode(@encoding) if string.respond_to?(:encode)
+
+    # tLABEL_END is only possible in non-cond context on >= 2.2
+    if @version >= 22 && !@cond.active?
+      lookahead = @source[@te... at te+2]
+      lookahead = lookahead.encode(@encoding) if lookahead.respond_to?(:encode)
+    end
+
+    if !literal.heredoc? && (token = literal.nest_and_try_closing(string, @ts, @te, lookahead))
+      if token[0] == :tLABEL_END
+        p += 1
+        pop_literal
+        fnext expr_labelarg;
+      else
+        fnext *pop_literal;
+      end
+       fbreak;
+    else
+      literal.extend_string(string, @ts, @te)
+    end
+  }
+
+  action extend_string_escaped {
+    if literal.nest_and_try_closing('\\', @ts, @ts + 1)
+      # If the literal is actually closed by the backslash,
+      # rewind the input prior to consuming the escape sequence.
+      p = @escape_s - 1
+      fnext *pop_literal; fbreak;
+    else
+      # Get the first character after the backslash.
+      escaped_char = @source[@escape_s].chr
+
+      if literal.munge_escape? escaped_char
+        # If this particular literal uses this character as an opening
+        # or closing delimiter, it is an escape sequence for that
+        # particular character. Write it without the backslash.
+
+        if literal.regexp? && escaped_char == '\\'
+          # Regular expressions should include backslashes in their escaped
+          # form.
+          literal.extend_string(tok, @ts, @te)
+        else
+          literal.extend_string(escaped_char, @ts, @te)
+        end
+      else
+        # It does not. So this is an actual escape sequence, yay!
+        # Two things to consider here.
+        #
+        # 1. The `escape' rule should be pure and so won't raise any
+        #    errors by itself. Instead, it stores them in lambdas.
+        #
+        # 2. Non-interpolated literals do not go through the aforementioned
+        #    rule. As \\ and \' (and variants) are munged, the full token
+        #    should always be written for such literals.
+
+        @escape.call if @escape.respond_to? :call
+
+        if literal.regexp?
+          # Regular expressions should include escape sequences in their
+          # escaped form. On the other hand, escaped newlines are removed.
+          literal.extend_string(tok.gsub("\\\n", ''), @ts, @te)
+        else
+          literal.extend_string(@escape || tok, @ts, @te)
+        end
+      end
+    end
+  }
+
+  # Extend a string with a newline or a EOF character.
+  # As heredoc closing line can immediately precede EOF, this action
+  # has to handle such case specially.
+  action extend_string_eol {
+    if @te == pe
+      diagnostic :fatal, :string_eof, nil,
+                 range(literal.str_s, literal.str_s + 1)
+    end
+
+    if literal.heredoc?
+      line = tok(@herebody_s, @ts).gsub(/\r+$/, '')
+
+      if version?(18, 19, 20)
+        # See ruby:c48b4209c
+        line = line.gsub(/\r.*$/, '')
+      end
+
+      # Try ending the heredoc with the complete most recently
+      # scanned line. @herebody_s always refers to the start of such line.
+      if literal.nest_and_try_closing(line, @herebody_s, @ts)
+        # Adjust @herebody_s to point to the next line.
+        @herebody_s = @te
+
+        # Continue regular lexing after the heredoc reference (<<END).
+        p = literal.heredoc_e - 1
+        fnext *pop_literal; fbreak;
+      else
+        # Ditto.
+        @herebody_s = @te
+      end
+    else
+      # Try ending the literal with a newline.
+      if literal.nest_and_try_closing(tok, @ts, @te)
+        fnext *pop_literal; fbreak;
+      end
+
+      if @herebody_s
+        # This is a regular literal intertwined with a heredoc. Like:
+        #
+        #     p <<-foo+"1
+        #     bar
+        #     foo
+        #     2"
+        #
+        # which, incidentally, evaluates to "bar\n1\n2".
+        p = @herebody_s - 1
+        @herebody_s = nil
+      end
+    end
+
+    if literal.words? && !eof_codepoint?(@source_pts[p])
+      literal.extend_space @ts, @te
+    else
+      # A literal newline is appended if the heredoc was _not_ closed
+      # this time (see fbreak above). See also Literal#nest_and_try_closing
+      # for rationale of calling #flush_string here.
+      literal.extend_string tok, @ts, @te
+      literal.flush_string
+    end
+  }
+
+  action extend_string_space {
+    literal.extend_space @ts, @te
+  }
+
+  #
+  # === INTERPOLATION PARSING ===
+  #
+
+  # Interpolations with immediate variable names simply call into
+  # the corresponding machine.
+
+  interp_var = '#' ( global_var | class_var_v | instance_var_v );
+
+  action extend_interp_var {
+    literal.flush_string
+    literal.extend_content
+
+    emit(:tSTRING_DVAR, nil, @ts, @ts + 1)
+
+    p = @ts
+    fcall expr_variable;
+  }
+
+  # Interpolations with code blocks must match nested curly braces, as
+  # interpolation ending is ambiguous with a block ending. So, every
+  # opening and closing brace should be matched with e_[lr]brace rules,
+  # which automatically perform the counting.
+  #
+  # Note that interpolations can themselves be nested, so brace balance
+  # is tied to the innermost literal.
+  #
+  # Also note that literals themselves should not use e_[lr]brace rules
+  # when matching their opening and closing delimiters, as the amount of
+  # braces inside the characters of a string literal is independent.
+
+  interp_code = '#{';
+
+  e_lbrace = '{' % {
+    @cond.push(false); @cmdarg.push(false)
+
+    if literal
+      literal.start_interp_brace
+    end
+  };
+
+  e_rbrace = '}' % {
+    if literal
+      if literal.end_interp_brace_and_try_closing
+        if version?(18, 19)
+          emit(:tRCURLY, '}', p - 1, p)
+        else
+          emit(:tSTRING_DEND, '}', p - 1, p)
+        end
+
+        if literal.saved_herebody_s
+          @herebody_s = literal.saved_herebody_s
+        end
+
+        fhold;
+        fnext *stack_pop;
+        fbreak;
+      end
+    end
+  };
+
+  action extend_interp_code {
+    literal.flush_string
+    literal.extend_content
+
+    emit(:tSTRING_DBEG, '#{')
+
+    if literal.heredoc?
+      literal.saved_herebody_s = @herebody_s
+      @herebody_s = nil
+    end
+
+    literal.start_interp_brace
+    fcall expr_value;
+  }
+
+  # Actual string parsers are simply combined from the primitives defined
+  # above.
+
+  interp_words := |*
+      interp_code => extend_interp_code;
+      interp_var  => extend_interp_var;
+      e_bs escape => extend_string_escaped;
+      c_space+    => extend_string_space;
+      c_eol       => extend_string_eol;
+      c_any       => extend_string;
+  *|;
+
+  interp_string := |*
+      interp_code => extend_interp_code;
+      interp_var  => extend_interp_var;
+      e_bs escape => extend_string_escaped;
+      c_eol       => extend_string_eol;
+      c_any       => extend_string;
+  *|;
+
+  plain_words := |*
+      e_bs c_any  => extend_string_escaped;
+      c_space+    => extend_string_space;
+      c_eol       => extend_string_eol;
+      c_any       => extend_string;
+  *|;
+
+  plain_string := |*
+      '\\' c_nl   => extend_string_eol;
+      e_bs c_any  => extend_string_escaped;
+      c_eol       => extend_string_eol;
+      c_any       => extend_string;
+  *|;
+
+  regexp_modifiers := |*
+      [A-Za-z]+
+      => {
+        unknown_options = tok.scan(/[^imxouesn]/)
+        if unknown_options.any?
+          diagnostic :error, :regexp_options,
+                     { :options => unknown_options.join }
+        end
+
+        emit(:tREGEXP_OPT)
+        fnext expr_end; fbreak;
+      };
+
+      any
+      => {
+        emit(:tREGEXP_OPT, tok(@ts, @te - 1), @ts, @te - 1)
+        fhold; fgoto expr_end;
+      };
+  *|;
+
+  #
+  # === WHITESPACE HANDLING ===
+  #
+
+  # Various contexts in Ruby allow various kinds of whitespace
+  # to be used. They are grouped to clarify the lexing machines
+  # and ease collection of comments.
+
+  # A line of code with inline #comment at end is always equivalent
+  # to a line of code ending with just a newline, so an inline
+  # comment is deemed equivalent to non-newline whitespace
+  # (c_space character class).
+
+  w_space =
+      c_space+
+    | '\\' e_heredoc_nl
+    ;
+
+  w_comment =
+      '#'     %{ @sharp_s = p - 1 }
+      # The (p == pe) condition compensates for added "\0" and
+      # the way Ragel handles EOF.
+      c_line* %{ emit_comment(@sharp_s, p == pe ? p - 2 : p) }
+    ;
+
+  w_space_comment =
+      w_space
+    | w_comment
+    ;
+
+  # A newline in non-literal context always interoperates with
+  # here document logic and can always be escaped by a backslash,
+  # still interoperating with here document logic in the same way,
+  # yet being invisible to anything else.
+  #
+  # To demonstrate:
+  #
+  #     foo = <<FOO \
+  #     bar
+  #     FOO
+  #      + 2
+  #
+  # is equivalent to `foo = "bar\n" + 2`.
+
+  w_newline =
+      e_heredoc_nl;
+
+  w_any =
+      w_space
+    | w_comment
+    | w_newline
+    ;
+
+
+  #
+  # === EXPRESSION PARSING ===
+  #
+
+  # These rules implement a form of manually defined lookahead.
+  # The default longest-match scanning does not work here due
+  # to sheer ambiguity.
+
+  ambiguous_fid_suffix =       # actual    parsed
+      [?!]  %{ tm = p }      | # a?        a?
+      '!='  %{ tm = p - 2 }    # a!=b      a != b
+  ;
+
+  ambiguous_ident_suffix =     # actual    parsed
+      ambiguous_fid_suffix   |
+      '='   %{ tm = p }      | # a=        a=
+      '=='  %{ tm = p - 2 }  | # a==b      a == b
+      '=~'  %{ tm = p - 2 }  | # a=~b      a =~ b
+      '=>'  %{ tm = p - 2 }  | # a=>b      a => b
+      '===' %{ tm = p - 3 }    # a===b     a === b
+  ;
+
+  ambiguous_symbol_suffix =    # actual    parsed
+      ambiguous_ident_suffix |
+      '==>' %{ tm = p - 2 }    # :a==>b    :a= => b
+  ;
+
+  # Ambiguous with 1.9 hash labels.
+  ambiguous_const_suffix =     # actual    parsed
+      '::'  %{ tm = p - 2 }    # A::B      A :: B
+  ;
+
+  # Resolving kDO/kDO_COND/kDO_BLOCK ambiguity requires embedding
+  # @cond/@cmdarg-related code to e_lbrack, e_lparen and e_lbrace.
+
+  e_lbrack = '[' % {
+    @cond.push(false); @cmdarg.push(false)
+  };
+
+  # Ruby 1.9 lambdas require parentheses counting in order to
+  # emit correct opening kDO/tLBRACE.
+
+  e_lparen = '(' % {
+    @cond.push(false); @cmdarg.push(false)
+
+    @paren_nest += 1
+  };
+
+  e_rparen = ')' % {
+    @paren_nest -= 1
+  };
+
+  # Ruby is context-sensitive wrt/ local identifiers.
+  action local_ident {
+    emit(:tIDENTIFIER)
+
+    if !@static_env.nil? && @static_env.declared?(tok)
+      fnext expr_end; fbreak;
+    else
+      fnext *arg_or_cmdarg; fbreak;
+    end
+  }
+
+  # Variable lexing code is accessed from both expressions and
+  # string interpolation related code.
+  #
+  expr_variable := |*
+      global_var
+      => {
+        if    tok =~ /^\$([1-9][0-9]*)$/
+          emit(:tNTH_REF, tok(@ts + 1).to_i)
+        elsif tok =~ /^\$([&`'+])$/
+          emit(:tBACK_REF)
+        else
+          emit(:tGVAR)
+        end
+
+        fnext *stack_pop; fbreak;
+      };
+
+      class_var_v
+      => {
+        if tok =~ /^@@[0-9]/
+          diagnostic :error, :cvar_name, { :name => tok }
+        end
+
+        emit(:tCVAR)
+        fnext *stack_pop; fbreak;
+      };
+
+      instance_var_v
+      => {
+        if tok =~ /^@[0-9]/
+          diagnostic :error, :ivar_name, { :name => tok }
+        end
+
+        emit(:tIVAR)
+        fnext *stack_pop; fbreak;
+      };
+  *|;
+
+  # Literal function name in definition (e.g. `def class`).
+  # Keywords are returned as their respective tokens; this is used
+  # to support singleton def `def self.foo`. Global variables are
+  # returned as `tGVAR`; this is used in global variable alias
+  # statements `alias $a $b`. Symbols are returned verbatim; this
+  # is used in `alias :a :"b#{foo}"` and `undef :a`.
+  #
+  # Transitions to `expr_endfn` afterwards.
+  #
+  expr_fname := |*
+      keyword
+      => { emit(KEYWORDS_BEGIN[tok]);
+           fnext expr_endfn; fbreak; };
+
+      constant
+      => { emit(:tCONSTANT)
+           fnext expr_endfn; fbreak; };
+
+      bareword [?=!]?
+      => { emit(:tIDENTIFIER)
+           fnext expr_endfn; fbreak; };
+
+      global_var
+      => { p = @ts - 1
+           fnext expr_end; fcall expr_variable; };
+
+      # If the handling was to be delegated to expr_end,
+      # these cases would transition to something else than
+      # expr_endfn, which is incorrect.
+      operator_fname      |
+      operator_arithmetic |
+      operator_rest
+      => { emit_table(PUNCTUATION)
+           fnext expr_endfn; fbreak; };
+
+      '::'
+      => { fhold; fhold; fgoto expr_end; };
+
+      ':'
+      => { fhold; fgoto expr_beg; };
+
+      w_any;
+
+      c_any
+      => { fhold; fgoto expr_end; };
+
+      c_eof => do_eof;
+  *|;
+
+  # After literal function name in definition. Behaves like `expr_end`,
+  # but allows a tLABEL.
+  #
+  # Transitions to `expr_end` afterwards.
+  #
+  expr_endfn := |*
+      label
+      => { emit(:tLABEL, tok(@ts, @te - 1))
+           fnext expr_labelarg; fbreak; };
+
+      w_space_comment;
+
+      c_any
+      => { fhold; fgoto expr_end; };
+
+      c_eof => do_eof;
+  *|;
+
+  # Literal function name in method call (e.g. `a.class`).
+  #
+  # Transitions to `expr_arg` afterwards.
+  #
+  expr_dot := |*
+      constant
+      => { emit(:tCONSTANT)
+           fnext *arg_or_cmdarg; fbreak; };
+
+      call_or_var
+      => { emit(:tIDENTIFIER)
+           fnext *arg_or_cmdarg; fbreak; };
+
+      bareword ambiguous_fid_suffix
+      => { emit(:tFID, tok(@ts, tm), @ts, tm)
+           fnext *arg_or_cmdarg; p = tm - 1; fbreak; };
+
+      # See the comment in `expr_fname`.
+      operator_fname      |
+      operator_arithmetic |
+      operator_rest
+      => { emit_table(PUNCTUATION)
+           fnext expr_arg; fbreak; };
+
+      w_any;
+
+      c_any
+      => { fhold; fgoto expr_end; };
+
+      c_eof => do_eof;
+  *|;
+
+  # The previous token emitted was a `tIDENTIFIER` or `tFID`; no space
+  # is consumed; the current expression is a command or method call.
+  #
+  expr_arg := |*
+      #
+      # COMMAND MODE SPECIFIC TOKENS
+      #
+
+      # cmd (1 + 2)
+      # See below the rationale about expr_endarg.
+      w_space+ e_lparen
+      => {
+        if version?(18)
+          emit(:tLPAREN2, '(', @te - 1, @te)
+          fnext expr_value; fbreak;
+        else
+          emit(:tLPAREN_ARG, '(', @te - 1, @te)
+          fnext expr_beg; fbreak;
+        end
+      };
+
+      # meth(1 + 2)
+      # Regular method call.
+      e_lparen
+      => { emit(:tLPAREN2)
+           fnext expr_beg; fbreak; };
+
+      # meth [...]
+      # Array argument. Compare with indexing `meth[...]`.
+      w_space+ e_lbrack
+      => { emit(:tLBRACK, '[', @te - 1, @te)
+           fnext expr_beg; fbreak; };
+
+      # cmd {}
+      # Command: method call without parentheses.
+      w_space* e_lbrace
+      => {
+        if @lambda_stack.last == @paren_nest
+          p = @ts - 1
+          fgoto expr_end;
+        else
+          emit(:tLCURLY, '{', @te - 1, @te)
+          fnext expr_value; fbreak;
+        end
+      };
+
+      #
+      # AMBIGUOUS TOKENS RESOLVED VIA EXPR_BEG
+      #
+
+      # a ?b
+      # Character literal.
+      w_space* '?'
+      => { fhold; fgoto expr_beg; };
+
+      # a %{1}, a %[1] (but not "a %=1=" or "a % foo")
+      # a /foo/ (but not "a / foo" or "a /=foo")
+      # a <<HEREDOC
+      w_space+ %{ tm = p }
+      ( [%/] ( c_any - c_space_nl - '=' ) # /
+      | '<<'
+      )
+      => {
+        if tok(tm, tm + 1) == '/'
+          # Ambiguous regexp literal.
+          diagnostic :warning, :ambiguous_literal, nil, range(tm, tm + 1)
+        end
+
+        p = tm - 1
+        fgoto expr_beg;
+      };
+
+      # x *1
+      # Ambiguous splat, kwsplat or block-pass.
+      w_space+ %{ tm = p } ( '+' | '-' | '*' | '&' | '**' )
+      => {
+        diagnostic :warning, :ambiguous_prefix, { :prefix => tok(tm, @te) },
+                   range(tm, @te)
+
+        p = tm - 1
+        fgoto expr_beg;
+      };
+
+      # x ::Foo
+      # Ambiguous toplevel constant access.
+      w_space+ '::'
+      => { fhold; fhold; fgoto expr_beg; };
+
+      # x:b
+      # Symbol.
+      w_space* ':'
+      => { fhold; fgoto expr_beg; };
+
+      w_space+ label
+      => { p = @ts - 1; fgoto expr_beg; };
+
+      #
+      # AMBIGUOUS TOKENS RESOLVED VIA EXPR_END
+      #
+
+      # a ? b
+      # Ternary operator.
+      w_space+ %{ tm = p } '?' c_space_nl
+      => { p = tm - 1; fgoto expr_end; };
+
+      # x + 1: Binary operator or operator-assignment.
+      w_space* operator_arithmetic
+                  ( '=' | c_space_nl )?    |
+      # x rescue y: Modifier keyword.
+      w_space* keyword_modifier            |
+      # Miscellanea.
+      w_space* punctuation_end
+      => {
+        p = @ts - 1
+        fgoto expr_end;
+      };
+
+      w_space;
+
+      w_comment
+      => { fgoto expr_end; };
+
+      w_newline
+      => { fhold; fgoto expr_end; };
+
+      c_any
+      => { fhold; fgoto expr_beg; };
+
+      c_eof => do_eof;
+  *|;
+
+  # The previous token was an identifier which was seen while in the
+  # command mode (that is, the state at the beginning of #advance was
+  # expr_value). This state is very similar to expr_arg, but disambiguates
+  # two very rare and specific condition:
+  #   * In 1.8 mode, "foo (lambda do end)".
+  #   * In 1.9+ mode, "f x: -> do foo do end end".
+  expr_cmdarg := |*
+      w_space+ e_lparen
+      => {
+        emit(:tLPAREN_ARG, '(', @te - 1, @te)
+        if version?(18)
+          fnext expr_value; fbreak;
+        else
+          fnext expr_beg; fbreak;
+        end
+      };
+
+      w_space* 'do'
+      => {
+        if @cond.active?
+          emit(:kDO_COND, 'do', @te - 2, @te)
+        else
+          emit(:kDO, 'do', @te - 2, @te)
+        end
+        fnext expr_value; fbreak;
+      };
+
+      c_any             |
+      # Disambiguate with the `do' rule above.
+      w_space* bareword |
+      w_space* label
+      => { p = @ts - 1
+           fgoto expr_arg; };
+
+      c_eof => do_eof;
+  *|;
+
+  # The rationale for this state is pretty complex. Normally, if an argument
+  # is passed to a command and then there is a block (tLCURLY...tRCURLY),
+  # the block is attached to the innermost argument (`f` in `m f {}`), or it
+  # is a parse error (`m 1 {}`). But there is a special case for passing a single
+  # primary expression grouped with parentheses: if you write `m (1) {}` or
+  # (2.0 only) `m () {}`, then the block is attached to `m`.
+  #
+  # Thus, we recognize the opening `(` of a command (remember, a command is
+  # a method call without parens) as a tLPAREN_ARG; then, in parser, we recognize
+  # `tLPAREN_ARG expr rparen` as a `primary_expr` and before rparen, set the
+  # lexer's state to `expr_endarg`, which makes it emit the possibly following
+  # `{` as `tLBRACE_ARG`.
+  #
+  # The default post-`expr_endarg` state is `expr_end`, so this state also handles
+  # `do` (as `kDO_BLOCK` in `expr_beg`).
+  expr_endarg := |*
+      e_lbrace
+      => { emit(:tLBRACE_ARG)
+           fnext expr_value; };
+
+      'do'
+      => { emit_do(true)
+           fnext expr_value; fbreak; };
+
+      w_space_comment;
+
+      c_any
+      => { fhold; fgoto expr_end; };
+
+      c_eof => do_eof;
+  *|;
+
+  # The rationale for this state is that several keywords accept value
+  # (i.e. should transition to `expr_beg`), do not accept it like a command
+  # (i.e. not an `expr_arg`), and must behave like a statement, that is,
+  # accept a modifier if/while/etc.
+  #
+  expr_mid := |*
+      keyword_modifier
+      => { emit_table(KEYWORDS)
+           fnext expr_beg; fbreak; };
+
+      bareword
+      => { p = @ts - 1; fgoto expr_beg; };
+
+      w_space_comment;
+
+      w_newline
+      => { fhold; fgoto expr_end; };
+
+      c_any
+      => { fhold; fgoto expr_beg; };
+
+      c_eof => do_eof;
+  *|;
+
+  # Beginning of an expression.
+  #
+  # Don't fallthrough to this state from `c_any`; make sure to handle
+  # `c_space* c_nl` and let `expr_end` handle the newline.
+  # Otherwise code like `f\ndef x` gets glued together and the parser
+  # explodes.
+  #
+  expr_beg := |*
+      # Numeric processing. Converts:
+      #   +5 to [tINTEGER, 5]
+      #   -5 to [tUMINUS_NUM] [tINTEGER, 5]
+      [+\-][0-9]
+      => {
+        fhold;
+        if tok.start_with? '-'
+          emit(:tUMINUS_NUM, '-', @ts, @ts + 1)
+          fnext expr_end; fbreak;
+        end
+      };
+
+      # splat *a
+      '*'
+      => { emit(:tSTAR)
+           fbreak; };
+
+      #
+      # STRING AND REGEXP LITERALS
+      #
+
+      # /regexp/oui
+      # /=/ (disambiguation with /=)
+      '/' c_any
+      => {
+        type = delimiter = tok[0].chr
+        fhold; fgoto *push_literal(type, delimiter, @ts);
+      };
+
+      # %<string>
+      '%' ( any - [A-Za-z] )
+      => {
+        type, delimiter = tok[0].chr, tok[-1].chr
+        fgoto *push_literal(type, delimiter, @ts);
+      };
+
+      # %w(we are the people)
+      '%' [A-Za-z]+ c_any
+      => {
+        type, delimiter = tok[0..-2], tok[-1].chr
+        fgoto *push_literal(type, delimiter, @ts);
+      };
+
+      '%' c_eof
+      => {
+        diagnostic :fatal, :string_eof, nil, range(@ts, @ts + 1)
+      };
+
+      # Heredoc start.
+      # <<EOF | <<-END | <<"FOOBAR" | <<-`SMTH`
+      '<<' '-'?
+        ( '"' ( c_line - '"' )* '"'
+        | "'" ( c_line - "'" )* "'"
+        | "`" ( c_line - "`" )* "`"
+        | bareword ) % { @heredoc_e     = p }
+        c_line* c_nl % { new_herebody_s = p }
+      => {
+        tok(@ts, @heredoc_e) =~ /^<<(-?)(["'`]?)(.*)\2$/
+
+        indent    = !$1.empty?
+        type      =  '<<' + ($2.empty? ? '"' : $2)
+        delimiter =  $3
+
+        fnext *push_literal(type, delimiter, @ts, @heredoc_e, indent);
+
+        if @herebody_s.nil?
+          @herebody_s = new_herebody_s
+        end
+
+        p = @herebody_s - 1
+      };
+
+      #
+      # SYMBOL LITERALS
+      #
+
+      # :"bar", :'baz'
+      ':' ['"] # '
+      => {
+        type, delimiter = tok, tok[-1].chr
+        fgoto *push_literal(type, delimiter, @ts);
+      };
+
+      ':' bareword ambiguous_symbol_suffix
+      => {
+        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
+        p = tm - 1
+        fnext expr_end; fbreak;
+      };
+
+      ':' ( bareword | global_var | class_var | instance_var |
+            operator_fname | operator_arithmetic | operator_rest )
+      => {
+        emit(:tSYMBOL, tok(@ts + 1), @ts)
+        fnext expr_end; fbreak;
+      };
+
+      #
+      # AMBIGUOUS TERNARY OPERATOR
+      #
+
+      '?' ( e_bs escape
+          | c_any - c_space_nl - e_bs % { @escape = nil }
+          )
+      => {
+        # Show an error if memorized.
+        @escape.call if @escape.respond_to? :call
+
+        value = @escape || tok(@ts + 1)
+
+        if version?(18)
+          emit(:tINTEGER, value[0].ord)
+        else
+          emit(:tCHARACTER, value)
+        end
+
+        fnext expr_end; fbreak;
+      };
+
+      '?' c_space_nl
+      => {
+        escape = { " "  => '\s', "\r" => '\r', "\n" => '\n', "\t" => '\t',
+                   "\v" => '\v', "\f" => '\f' }[tok[1]]
+        diagnostic :warning, :invalid_escape_use, { :escape => escape }, range
+
+        p = @ts - 1
+        fgoto expr_end;
+      };
+
+      '?' c_eof
+      => {
+        diagnostic :fatal, :incomplete_escape, nil, range(@ts, @ts + 1)
+      };
+
+      # f ?aa : b: Disambiguate with a character literal.
+      '?' [A-Za-z_] bareword
+      => {
+        p = @ts - 1
+        fgoto expr_end;
+      };
+
+      #
+      # KEYWORDS AND PUNCTUATION
+      #
+
+      # a({b=>c})
+      e_lbrace
+      => {
+        if @lambda_stack.last == @paren_nest
+          @lambda_stack.pop
+          emit(:tLAMBEG)
+        else
+          emit_table(PUNCTUATION_BEGIN)
+        end
+        fbreak;
+      };
+
+      # a([1, 2])
+      e_lbrack    |
+      # a()
+      e_lparen
+      => { emit_table(PUNCTUATION_BEGIN)
+           fbreak; };
+
+      # a(+b)
+      punctuation_begin
+      => { emit_table(PUNCTUATION_BEGIN)
+           fbreak; };
+
+      # rescue Exception => e: Block rescue.
+      # Special because it should transition to expr_mid.
+      'rescue' %{ tm = p } '=>'?
+      => { emit_table(KEYWORDS_BEGIN, @ts, tm)
+           p = tm - 1
+           fnext expr_mid; fbreak; };
+
+      # if a: Statement if.
+      keyword_modifier
+      => { emit_table(KEYWORDS_BEGIN)
+           fnext expr_value; fbreak; };
+
+      #
+      # RUBY 1.9 HASH LABELS
+      #
+
+      label ( any - ':' )
+      => {
+        fhold;
+
+        if version?(18)
+          ident = tok(@ts, @te - 2)
+
+          emit((tok[0] =~ /[A-Z]/) ? :tCONSTANT : :tIDENTIFIER,
+               ident, @ts, @te - 2)
+          fhold; # continue as a symbol
+
+          if !@static_env.nil? && @static_env.declared?(ident)
+            fnext expr_end;
+          else
+            fnext *arg_or_cmdarg;
+          end
+        else
+          emit(:tLABEL, tok(@ts, @te - 2), @ts, @te - 1)
+          fnext expr_labelarg;
+        end
+
+        fbreak;
+      };
+
+      #
+      # CONTEXT-DEPENDENT VARIABLE LOOKUP OR COMMAND INVOCATION
+      #
+
+      # foo= bar:  Disambiguate with bareword rule below.
+      bareword ambiguous_ident_suffix |
+      # def foo:   Disambiguate with bareword rule below.
+      keyword
+      => { p = @ts - 1
+           fgoto expr_end; };
+
+      # a = 42;     a [42]: Indexing.
+      # def a; end; a [42]: Array argument.
+      call_or_var
+      => local_ident;
+
+      #
+      # WHITESPACE
+      #
+
+      w_any;
+
+      e_heredoc_nl '=begin' ( c_space | c_nl_zlen )
+      => { p = @ts - 1
+           fgoto line_begin; };
+
+      #
+      # DEFAULT TRANSITION
+      #
+
+      # The following rules match most binary and all unary operators.
+      # Rules for binary operators provide better error reporting.
+      operator_arithmetic '='    |
+      operator_rest              |
+      punctuation_end            |
+      c_any
+      => { p = @ts - 1; fgoto expr_end; };
+
+      c_eof => do_eof;
+  *|;
+
+  # Special newline handling for "def a b:"
+  #
+  expr_labelarg := |*
+    w_space_comment;
+
+    w_newline
+    => {
+      if @in_kwarg
+        fhold; fgoto expr_end;
+      else
+        fgoto line_begin;
+      end
+    };
+
+    c_any
+    => { fhold; fgoto expr_beg; };
+
+    c_eof => do_eof;
+  *|;
+
+  # Like expr_beg, but no 1.9 label possible.
+  #
+  expr_value := |*
+      # a:b: a(:b), a::B, A::B
+      label (any - ':')
+      => { p = @ts - 1
+           fgoto expr_end; };
+
+      w_space_comment;
+
+      w_newline
+      => { fgoto line_begin; };
+
+      c_any
+      => { fhold; fgoto expr_beg; };
+
+      c_eof => do_eof;
+  *|;
+
+  expr_end := |*
+      #
+      # STABBY LAMBDA
+      #
+
+      '->'
+      => {
+        emit_table(PUNCTUATION, @ts, @ts + 2)
+
+        @lambda_stack.push @paren_nest
+        fbreak;
+      };
+
+      e_lbrace | 'do'
+      => {
+        if @lambda_stack.last == @paren_nest
+          @lambda_stack.pop
+
+          if tok == '{'
+            emit(:tLAMBEG)
+          else # 'do'
+            emit(:kDO_LAMBDA)
+          end
+        else
+          if tok == '{'
+            emit_table(PUNCTUATION)
+          else # 'do'
+            emit_do
+          end
+        end
+
+        fnext expr_value; fbreak;
+      };
+
+      #
+      # KEYWORDS
+      #
+
+      keyword_with_fname
+      => { emit_table(KEYWORDS)
+           fnext expr_fname; fbreak; };
+
+      'class' w_any* '<<'
+      => { emit(:kCLASS, 'class', @ts, @ts + 5)
+           emit(:tLSHFT, '<<',    @te - 2, @te)
+           fnext expr_value; fbreak; };
+
+      # a if b:c: Syntax error.
+      keyword_modifier
+      => { emit_table(KEYWORDS)
+           fnext expr_beg; fbreak; };
+
+      # elsif b:c: elsif b(:c)
+      keyword_with_value
+      => { emit_table(KEYWORDS)
+           fnext expr_value; fbreak; };
+
+      keyword_with_mid
+      => { emit_table(KEYWORDS)
+           fnext expr_mid; fbreak; };
+
+      keyword_with_arg
+      => {
+        emit_table(KEYWORDS)
+
+        if version?(18) && tok == 'not'
+          fnext expr_beg; fbreak;
+        else
+          fnext expr_arg; fbreak;
+        end
+      };
+
+      '__ENCODING__'
+      => {
+        if version?(18)
+          emit(:tIDENTIFIER)
+
+          if !@static_env.nil? && @static_env.declared?(tok)
+            fnext expr_end;
+          else
+            fnext *arg_or_cmdarg;
+          end
+        else
+          emit_table(KEYWORDS)
+        end
+        fbreak;
+      };
+
+      keyword_with_end
+      => { emit_table(KEYWORDS)
+           fbreak; };
+
+      #
+      # NUMERIC LITERALS
+      #
+
+      ( '0' [Xx] %{ @num_base = 16; @num_digits_s = p } int_hex
+      | '0' [Dd] %{ @num_base = 10; @num_digits_s = p } int_dec
+      | '0' [Oo] %{ @num_base = 8;  @num_digits_s = p } int_dec
+      | '0' [Bb] %{ @num_base = 2;  @num_digits_s = p } int_bin
+      | [1-9] digit* '_'? %{ @num_base = 10; @num_digits_s = @ts } int_dec
+      | '0'   digit* '_'? %{ @num_base = 8;  @num_digits_s = @ts } int_dec
+      ) %{ @num_suffix_s = p } int_suffix
+      => {
+        digits = tok(@num_digits_s, @num_suffix_s)
+
+        if digits.end_with? '_'
+          diagnostic :error, :trailing_in_number, { :character => '_' },
+                     range(@te - 1, @te)
+        elsif digits.empty? && @num_base == 8 && version?(18)
+          # 1.8 did not raise an error on 0o.
+          digits = "0"
+        elsif digits.empty?
+          diagnostic :error, :empty_numeric
+        elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/))
+          invalid_s = @num_digits_s + invalid_idx
+          diagnostic :error, :invalid_octal, nil,
+                     range(invalid_s, invalid_s + 1)
+        end
+
+        if version?(18, 19, 20)
+          emit(:tINTEGER, digits.to_i(@num_base))
+          p = @num_suffix_s - 1
+        else
+          @num_xfrm.call(digits.to_i(@num_base))
+        end
+        fbreak;
+      };
+
+      flo_frac flo_pow?
+      => {
+        diagnostic :error, :no_dot_digit_literal
+      };
+
+      flo_int [eE]
+      => {
+        if version?(18, 19, 20)
+          diagnostic :error,
+                     :trailing_in_number, { :character => tok(@te - 1, @te) },
+                     range(@te - 1, @te)
+        else
+          emit(:tINTEGER, tok(@ts, @te - 1).to_i)
+          fhold; fbreak;
+        end
+      };
+
+      flo_int flo_frac [eE]
+      => {
+        if version?(18, 19, 20)
+          diagnostic :error,
+                     :trailing_in_number, { :character => tok(@te - 1, @te) },
+                     range(@te - 1, @te)
+        else
+          emit(:tFLOAT, tok(@ts, @te - 1).to_f)
+          fhold; fbreak;
+        end
+      };
+
+      flo_int
+      ( flo_frac? flo_pow %{ @num_suffix_s = p } flo_pow_suffix
+      | flo_frac          %{ @num_suffix_s = p } flo_suffix
+      )
+      => {
+        digits = tok(@ts, @num_suffix_s)
+
+        if version?(18, 19, 20)
+          emit(:tFLOAT, Float(digits))
+          p = @num_suffix_s - 1
+        else
+          @num_xfrm.call(digits)
+        end
+        fbreak;
+      };
+
+      #
+      # STRING AND XSTRING LITERALS
+      #
+
+      # `echo foo`, "bar", 'baz'
+      '`' | ['"] # '
+      => {
+        type, delimiter = tok, tok[-1].chr
+        fgoto *push_literal(type, delimiter, @ts);
+      };
+
+      #
+      # CONSTANTS AND VARIABLES
+      #
+
+      constant
+      => { emit(:tCONSTANT)
+           fnext *arg_or_cmdarg; fbreak; };
+
+      constant ambiguous_const_suffix
+      => { emit(:tCONSTANT, tok(@ts, tm), @ts, tm)
+           p = tm - 1; fbreak; };
+
+      global_var | class_var_v | instance_var_v
+      => { p = @ts - 1; fcall expr_variable; };
+
+      #
+      # METHOD CALLS
+      #
+
+      '.' | '::'
+      => { emit_table(PUNCTUATION)
+           fnext expr_dot; fbreak; };
+
+      call_or_var
+      => local_ident;
+
+      bareword ambiguous_fid_suffix
+      => {
+        if tm == @te
+          # Suffix was consumed, e.g. foo!
+          emit(:tFID)
+        else
+          # Suffix was not consumed, e.g. foo!=
+          emit(:tIDENTIFIER, tok(@ts, tm), @ts, tm)
+          p = tm - 1
+        end
+        fnext expr_arg; fbreak;
+      };
+
+      #
+      # OPERATORS
+      #
+
+      ( e_lparen
+      | operator_arithmetic
+      | operator_rest
+      )
+      => { emit_table(PUNCTUATION)
+           fnext expr_beg; fbreak; };
+
+      e_rbrace | e_rparen | ']'
+      => {
+        emit_table(PUNCTUATION)
+        @cond.lexpop; @cmdarg.lexpop
+
+        if %w"} ]".include?(tok)
+          fnext expr_endarg;
+        else # )
+          # fnext expr_endfn; ?
+        end
+
+        fbreak;
+      };
+
+      operator_arithmetic '='
+      => { emit(:tOP_ASGN, tok(@ts, @te - 1))
+           fnext expr_beg; fbreak; };
+
+      '?'
+      => { emit_table(PUNCTUATION)
+           fnext expr_value; fbreak; };
+
+      e_lbrack
+      => { emit_table(PUNCTUATION)
+           fnext expr_beg; fbreak; };
+
+      punctuation_end
+      => { emit_table(PUNCTUATION)
+           fnext expr_beg; fbreak; };
+
+      #
+      # WHITESPACE
+      #
+
+      w_space_comment;
+
+      w_newline
+      => { fgoto leading_dot; };
+
+      ';'
+      => { emit_table(PUNCTUATION)
+           fnext expr_value; fbreak; };
+
+      '\\' c_line {
+        diagnostic :error, :bare_backslash, nil, range(@ts, @ts + 1)
+        fhold;
+      };
+
+      c_any
+      => {
+        diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] }
+      };
+
+      c_eof => do_eof;
+  *|;
+
+  leading_dot := |*
+      # Insane leading dots:
+      # a #comment
+      #  .b: a.b
+      c_space* '.' ( c_any - '.' )
+      => { fhold; fhold;
+           fgoto expr_end; };
+
+      any
+      => { emit(:tNL, nil, @newline_s, @newline_s + 1)
+           fhold; fnext line_begin; fbreak; };
+  *|;
+
+  #
+  # === EMBEDDED DOCUMENT (aka BLOCK COMMENT) PARSING ===
+  #
+
+  line_comment := |*
+      '=end' c_line* c_nl_zlen
+      => {
+        emit_comment(@eq_begin_s, @te)
+        fgoto line_begin;
+      };
+
+      c_line* c_nl;
+
+      c_line* zlen
+      => {
+        diagnostic :fatal, :embedded_document, nil,
+                   range(@eq_begin_s, @eq_begin_s + '=begin'.length)
+      };
+  *|;
+
+  line_begin := |*
+      w_any;
+
+      '=begin' ( c_space | c_nl_zlen )
+      => { @eq_begin_s = @ts
+           fgoto line_comment; };
+
+      '__END__' ( c_eol - zlen )
+      => { p = pe - 3 };
+
+      c_any
+      => { fhold; fgoto expr_value; };
+
+      c_eof => do_eof;
+  *|;
+
+  }%%
+  # %
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/lexer/explanation.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/lexer/explanation.rb
new file mode 100644
index 0000000..a1692d1
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/lexer/explanation.rb
@@ -0,0 +1,53 @@
+module Parser
+
+  module Lexer::Explanation
+
+    def self.included(klass)
+      klass.class_exec do
+        alias_method :state_before_explanation=,  :state=
+        alias_method :advance_before_explanation, :advance
+
+        remove_method :state=, :advance
+      end
+    end
+
+    # Like #advance, but also pretty-print the token and its position
+    # in the stream to `stdout`.
+    def advance
+      type, (val, range) = advance_before_explanation
+
+      more = "(in-kwarg)" if @in_kwarg
+
+      puts decorate(range,
+                    "\e[0;32m#{type} #{val.inspect}\e[0m",
+                    "#{state.to_s.ljust(12)} #{@cond} #{@cmdarg} #{more}\e[0m")
+
+      [ type, [val, range] ]
+    end
+
+    def state=(new_state)
+      puts "  \e[1;33m>>> STATE SET <<<\e[0m " +
+           "#{new_state.to_s.ljust(12)} #{@cond} #{@cmdarg}".rjust(66)
+
+      self.state_before_explanation = new_state
+    end
+
+    private
+
+    def decorate(range, token, info)
+      from, to = range.begin.column, range.end.column
+
+      line = range.source_line + '   '
+      line[from...to] = "\e[4m#{line[from...to]}\e[0m"
+
+      tail_len   = to - from - 1
+      tail       = '~' * (tail_len >= 0 ? tail_len : 0)
+      decoration =  "#{" " * from}\e[1;31m^#{tail}\e[0m #{token} ".
+                        ljust(70) + info
+
+      [ line, decoration ]
+    end
+
+  end
+
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/lexer/literal.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/lexer/literal.rb
new file mode 100644
index 0000000..8b2f030
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/lexer/literal.rb
@@ -0,0 +1,240 @@
+# encoding: binary
+
+module Parser
+
+  class Lexer::Literal
+    DELIMITERS = { '(' => ')', '[' => ']', '{' => '}', '<' => '>' }
+    MONOLITHIC = { :tSTRING_BEG => :tSTRING }
+
+    TYPES = {
+    # type      start token     interpolate?
+      "'"   => [ :tSTRING_BEG,   false ],
+      "<<'" => [ :tSTRING_BEG,   false ],
+      '%q'  => [ :tSTRING_BEG,   false ],
+      '"'   => [ :tSTRING_BEG,   true  ],
+      '<<"' => [ :tSTRING_BEG,   true  ],
+      '%'   => [ :tSTRING_BEG,   true  ],
+      '%Q'  => [ :tSTRING_BEG,   true  ],
+
+      '%w'  => [ :tQWORDS_BEG,   false ],
+      '%W'  => [ :tWORDS_BEG,    true  ],
+
+      '%i'  => [ :tQSYMBOLS_BEG, false ],
+      '%I'  => [ :tSYMBOLS_BEG,  true  ],
+
+      ":'"  => [ :tSYMBEG,       false ],
+      '%s'  => [ :tSYMBEG,       false ],
+      ':"'  => [ :tSYMBEG,       true  ],
+
+      '/'   => [ :tREGEXP_BEG,   true  ],
+      '%r'  => [ :tREGEXP_BEG,   true  ],
+
+      '%x'  => [ :tXSTRING_BEG,  true  ],
+      '`'   => [ :tXSTRING_BEG,  true  ],
+      '<<`' => [ :tXSTRING_BEG,  true  ],
+    }
+
+    attr_reader   :heredoc_e, :str_s
+    attr_accessor :saved_herebody_s
+
+    def initialize(lexer, str_type, delimiter, str_s, heredoc_e = nil, indent = false)
+      @lexer       = lexer
+      @nesting     = 1
+
+      # DELIMITERS and TYPES are hashes with keys encoded in binary.
+      # Coerce incoming data to the same encoding.
+      str_type     = coerce_encoding(str_type)
+      delimiter    = coerce_encoding(delimiter)
+
+      unless TYPES.include?(str_type)
+        lexer.send(:diagnostic, :error, :unexpected_percent_str,
+                   { :type => str_type }, @lexer.send(:range, str_s, str_s + 2))
+      end
+
+      # String type. For :'foo', it is :'
+      @str_type    = str_type
+      # Start of the string type specifier.
+      @str_s       = str_s
+
+      @start_tok, @interpolate = TYPES[str_type]
+      @start_delim = DELIMITERS.include?(delimiter) ? delimiter : nil
+      @end_delim   = DELIMITERS.fetch(delimiter, delimiter)
+
+      @heredoc_e   = heredoc_e
+      @indent      = indent
+
+      @interp_braces = 0
+
+      @space_emitted = true
+
+      # Monolithic strings are glued into a single token, e.g.
+      # tSTRING_BEG tSTRING_CONTENT tSTRING_END -> tSTRING.
+      @monolithic  = (@start_tok == :tSTRING_BEG  &&
+                      %w(' ").include?(str_type) &&
+                      !heredoc?)
+
+      # Capture opening delimiter in percent-literals.
+      unless @heredoc_e || @str_type.end_with?(delimiter)
+        @str_type << delimiter
+      end
+
+      clear_buffer
+
+      emit_start_tok unless @monolithic
+    end
+
+    def interpolate?
+      @interpolate
+    end
+
+    def words?
+      type == :tWORDS_BEG || type == :tQWORDS_BEG ||
+        type == :tSYMBOLS_BEG || type == :tQSYMBOLS_BEG
+    end
+
+    def regexp?
+      type == :tREGEXP_BEG
+    end
+
+    def heredoc?
+      !!@heredoc_e
+    end
+
+    def type
+      @start_tok
+    end
+
+    def munge_escape?(character)
+      character = coerce_encoding(character)
+
+      if words? && character =~ /[ \t\v\r\f\n]/
+        true
+      else
+        ['\\', @start_delim, @end_delim].include?(character)
+      end
+    end
+
+    def nest_and_try_closing(delimiter, ts, te, lookahead=nil)
+      delimiter = coerce_encoding(delimiter)
+
+      if @start_delim && @start_delim == delimiter
+        @nesting += 1
+      elsif delimiter?(delimiter)
+        @nesting -= 1
+      end
+
+      # Finalize if last matching delimiter is closed.
+      if @nesting == 0
+        if words?
+          extend_space(ts, ts)
+        end
+
+        if lookahead && lookahead[0] == ?: && lookahead[1] != ?: &&
+           %w(' ").include?(delimiter) && @start_tok == :tSTRING_BEG
+          # This is a quoted label.
+          flush_string
+          emit(:tLABEL_END, @end_delim, ts, te + 1)
+        elsif @monolithic
+          # Emit the string as a single token.
+          emit(MONOLITHIC[@start_tok], @buffer, @str_s, te)
+        else
+          # If this is a heredoc, @buffer contains the sentinel now.
+          # Just throw it out. Lexer flushes the heredoc after each
+          # non-heredoc-terminating \n anyway, so no data will be lost.
+          flush_string unless heredoc?
+
+          emit(:tSTRING_END, @end_delim, ts, te)
+        end
+      end
+    end
+
+    def start_interp_brace
+      @interp_braces += 1
+    end
+
+    def end_interp_brace_and_try_closing
+      @interp_braces -= 1
+
+      (@interp_braces == 0)
+    end
+
+    def extend_string(string, ts, te)
+      if @buffer_s.nil?
+        @buffer_s = ts
+      end
+
+      @buffer_e = te
+
+      @buffer << string
+    end
+
+    def flush_string
+      if @monolithic
+        emit_start_tok
+        @monolithic = false
+      end
+
+      unless @buffer.empty?
+        emit(:tSTRING_CONTENT, @buffer, @buffer_s, @buffer_e)
+
+        clear_buffer
+        extend_content
+      end
+    end
+
+    def extend_content
+      @space_emitted = false
+    end
+
+    def extend_space(ts, te)
+      flush_string
+
+      unless @space_emitted
+        emit(:tSPACE, nil, ts, te)
+
+        @space_emitted = true
+      end
+    end
+
+    protected
+
+    def delimiter?(delimiter)
+      if @indent
+        @end_delim == delimiter.lstrip
+      else
+        @end_delim == delimiter
+      end
+    end
+
+    def coerce_encoding(string)
+      if defined?(Encoding)
+        string.dup.force_encoding(Encoding::BINARY)
+      else
+        string
+      end
+    end
+
+    def clear_buffer
+      @buffer = ''
+
+      # Prime the buffer with lexer encoding; otherwise,
+      # concatenation will produce varying results.
+      if defined?(Encoding)
+        @buffer.force_encoding(@lexer.encoding)
+      end
+
+      @buffer_s = nil
+      @buffer_e = nil
+    end
+
+    def emit_start_tok
+      str_e = @heredoc_e || @str_s + @str_type.length
+      emit(@start_tok, @str_type, @str_s, str_e)
+    end
+
+    def emit(token, type, s, e)
+      @lexer.send(:emit, token, type, s, e)
+    end
+  end
+
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/lexer/stack_state.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/lexer/stack_state.rb
new file mode 100644
index 0000000..292fb22
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/lexer/stack_state.rb
@@ -0,0 +1,42 @@
+module Parser
+
+  class Lexer::StackState
+    def initialize(name)
+      @name  = name.freeze
+      clear
+    end
+
+    def clear
+      @stack = 0
+    end
+
+    def push(bit)
+      bit_value = bit ? 1 : 0
+      @stack = (@stack << 1) | bit_value
+
+      bit
+    end
+
+    def pop
+      bit_value = @stack & 1
+      @stack  >>= 1
+
+      bit_value == 1
+    end
+
+    def lexpop
+      push(pop || pop)
+    end
+
+    def active?
+      @stack[0] == 1
+    end
+
+    def to_s
+      "[#{@stack.to_s(2)} <= #{@name}]"
+    end
+
+    alias inspect to_s
+  end
+
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/messages.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/messages.rb
new file mode 100644
index 0000000..8d5e1bf
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/messages.rb
@@ -0,0 +1,66 @@
+module Parser
+  ##
+  # Diagnostic messages (errors, warnings and notices) that can be generated.
+  #
+  # @see Diagnostic
+  #
+  # @api public
+  #
+  MESSAGES = {
+    # Lexer errors
+    :unicode_point_too_large => 'invalid Unicode codepoint (too large)',
+    :invalid_escape          => 'invalid escape character syntax',
+    :incomplete_escape       => 'incomplete character syntax',
+    :invalid_hex_escape      => 'invalid hex escape',
+    :invalid_unicode_escape  => 'invalid Unicode escape',
+    :unterminated_unicode    => 'unterminated Unicode escape',
+    :escape_eof              => 'escape sequence meets end of file',
+    :string_eof              => 'unterminated string meets end of file',
+    :regexp_options          => 'unknown regexp options: %{options}',
+    :cvar_name               => "`%{name}' is not allowed as a class variable name",
+    :ivar_name               => "`%{name}' is not allowed as an instance variable name",
+    :trailing_in_number      => "trailing `%{character}' in number",
+    :empty_numeric           => 'numeric literal without digits',
+    :invalid_octal           => 'invalid octal digit',
+    :no_dot_digit_literal    => 'no .<digit> floating literal anymore; put 0 before dot',
+    :bare_backslash          => 'bare backslash only allowed before newline',
+    :unexpected              => "unexpected `%{character}'",
+    :embedded_document       => 'embedded document meets end of file (and they embark on a romantic journey)',
+
+    # Lexer warnings
+    :invalid_escape_use      => 'invalid character syntax; use ?%{escape}',
+    :ambiguous_literal       => 'ambiguous first argument; put parentheses or a space even after the operator',
+    :ambiguous_prefix        => "`%{prefix}' interpreted as argument prefix",
+
+    # Parser errors
+    :nth_ref_alias           => 'cannot define an alias for a back-reference variable',
+    :begin_in_method         => 'BEGIN in method',
+    :backref_assignment      => 'cannot assign to a back-reference variable',
+    :invalid_assignment      => 'cannot assign to a keyword',
+    :module_name_const       => 'class or module name must be a constant literal',
+    :unexpected_token        => 'unexpected token %{token}',
+    :argument_const          => 'formal argument cannot be a constant',
+    :argument_ivar           => 'formal argument cannot be an instance variable',
+    :argument_gvar           => 'formal argument cannot be a global variable',
+    :argument_cvar           => 'formal argument cannot be a class variable',
+    :duplicate_argument      => 'duplicate argument name',
+    :empty_symbol            => 'empty symbol literal',
+    :odd_hash                => 'odd number of entries for a hash',
+    :singleton_literal       => 'cannot define a singleton method for a literal',
+    :dynamic_const           => 'dynamic constant assignment',
+    :module_in_def           => 'module definition in method body',
+    :class_in_def            => 'class definition in method body',
+    :unexpected_percent_str  => '%{type}: unknown type of percent-literal',
+    :block_and_blockarg      => 'both block argument and literal block are passed',
+    :masgn_as_condition      => 'multiple assignment in conditional context',
+    :block_given_to_yield    => 'block given to yield',
+    :invalid_regexp          => '%{message}',
+
+    # Parser warnings
+    :useless_else            => 'else without rescue is useless',
+
+    # Rewriter diagnostics
+    :invalid_action          => 'cannot %{action}',
+    :clobbered               => 'clobbered by: %{action}',
+  }.freeze
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/meta.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/meta.rb
new file mode 100644
index 0000000..c7c469b
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/meta.rb
@@ -0,0 +1,27 @@
+module Parser
+  # Parser metadata
+  module Meta
+
+    # All node types that parser can produce. Not all parser versions
+    # will be able to produce every possible node.
+    NODE_TYPES =
+      %w(
+        true false nil int float str dstr str
+        sym dsym xstr regopt regexp array splat
+        array pair kwsplat hash irange erange self
+        lvar ivar cvar gvar const defined? lvasgn
+        ivasgn cvasgn gvasgn casgn mlhs masgn op_asgn
+        op_asgn and_asgn ensure rescue arg_expr
+        or_asgn and_asgn or_asgn back_ref nth_ref
+        match_with_lvasgn match_current_line
+        module class sclass def defs undef alias args
+        cbase arg optarg restarg blockarg block_pass args def kwarg kwoptarg
+        kwrestarg send super zsuper yield block send
+        and not or if when case while until while_post
+        until_post for break next redo return resbody
+        kwbegin begin retry preexe postexe iflipflop eflipflop
+        shadowarg complex rational __FILE__ __LINE__
+      ).map(&:to_sym).to_set.freeze
+
+  end # Meta
+end # Parser
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/rewriter.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/rewriter.rb
new file mode 100644
index 0000000..47b2df8
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/rewriter.rb
@@ -0,0 +1,119 @@
+module Parser
+
+  ##
+  # {Parser::Rewriter} offers a basic API that makes it easy to rewrite
+  # existing ASTs. It's built on top of {Parser::AST::Processor} and
+  # {Parser::Source::Rewriter}.
+  #
+  # For example, assume you want to remove `do` tokens from a while statement.
+  # You can do this as following:
+  #
+  #     require 'parser/current'
+  #
+  #     class RemoveDo < Parser::Rewriter
+  #       def on_while(node)
+  #         # Check if the statement starts with "do"
+  #         if node.location.begin.is?('do')
+  #           remove(node.location.begin)
+  #         end
+  #       end
+  #     end
+  #
+  #     code = <<-EOF
+  #     while true do
+  #       puts 'hello'
+  #     end
+  #     EOF
+  #
+  #     buffer        = Parser::Source::Buffer.new('(example)')
+  #     buffer.source = code
+  #     parser        = Parser::CurrentRuby.new
+  #     ast           = parser.parse(buffer)
+  #     rewriter      = RemoveDo.new
+  #
+  #     # Rewrite the AST, returns a String with the new form.
+  #     puts rewriter.rewrite(buffer, ast)
+  #
+  # This would result in the following Ruby code:
+  #
+  #     while true
+  #       puts 'hello'
+  #     end
+  #
+  # Keep in mind that {Parser::Rewriter} does not take care of indentation when
+  # inserting/replacing code so you'll have to do this yourself.
+  #
+  # See also [a blog entry](http://whitequark.org/blog/2013/04/26/lets-play-with-ruby-code/)
+  # describing rewriters in greater detail.
+  #
+  # @api public
+  #
+  class Rewriter < Parser::AST::Processor
+    ##
+    # Rewrites the AST/source buffer and returns a String containing the new
+    # version.
+    #
+    # @param [Parser::Source::Buffer] source_buffer
+    # @param [Parser::AST::Node] ast
+    # @return [String]
+    #
+    def rewrite(source_buffer, ast)
+      @source_rewriter = Source::Rewriter.new(source_buffer)
+
+      process(ast)
+
+      @source_rewriter.process
+    end
+
+    ##
+    # Returns `true` if the specified node is an assignment node, returns false
+    # otherwise.
+    #
+    # @param [Parser::AST::Node] node
+    # @return [Boolean]
+    #
+    def assignment?(node)
+      [:lvasgn, :ivasgn, :gvasgn, :cvasgn, :casgn].include?(node.type)
+    end
+
+    ##
+    # Removes the source range.
+    #
+    # @param [Parser::Source::Range] range
+    #
+    def remove(range)
+      @source_rewriter.remove(range)
+    end
+
+    ##
+    # Inserts new code before the given source range.
+    #
+    # @param [Parser::Source::Range] range
+    # @param [String] content
+    #
+    def insert_before(range, content)
+      @source_rewriter.insert_before(range, content)
+    end
+
+    ##
+    # Inserts new code after the given source range.
+    #
+    # @param [Parser::Source::Range] range
+    # @param [String] content
+    #
+    def insert_after(range, content)
+      @source_rewriter.insert_after(range, content)
+    end
+
+    ##
+    # Replaces the code of the source range `range` with `content`.
+    #
+    # @param [Parser::Source::Range] range
+    # @param [String] content
+    #
+    def replace(range, content)
+      @source_rewriter.replace(range, content)
+    end
+  end
+
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/ruby18.y b/app/server/vendor/parser-2.2.2.1/lib/parser/ruby18.y
new file mode 100644
index 0000000..e51016f
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/ruby18.y
@@ -0,0 +1,1917 @@
+class Parser::Ruby18
+
+token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
+      kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
+      kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kRETURN kYIELD kSUPER
+      kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
+      kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
+      k__FILE__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tNTH_REF
+      tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT tREGEXP_END tUPLUS
+      tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ tGEQ tLEQ tANDOP
+      tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF tASET tLSHFT tRSHFT
+      tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN tLPAREN2 tRPAREN tLPAREN_ARG
+      tLBRACK tLBRACK2 tRBRACK tLBRACE tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2
+      tTILDE tPERCENT tDIVIDE tPLUS tMINUS tLT tGT tPIPE tBANG tCARET
+      tLCURLY tRCURLY tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
+      tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END tSTRING
+      tSYMBOL tREGEXP_OPT tNL tEH tCOLON tCOMMA tSPACE tSEMI
+
+prechigh
+  right    tBANG tTILDE tUPLUS
+  right    tPOW
+  right    tUMINUS_NUM tUMINUS
+  left     tSTAR2 tDIVIDE tPERCENT
+  left     tPLUS tMINUS
+  left     tLSHFT tRSHFT
+  left     tAMPER2
+  left     tPIPE tCARET
+  left     tGT tGEQ tLT tLEQ
+  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
+  left     tANDOP
+  left     tOROP
+  nonassoc tDOT2 tDOT3
+  right    tEH tCOLON
+  left     kRESCUE_MOD
+  right    tEQL tOP_ASGN
+  nonassoc kDEFINED
+  right    kNOT
+  left     kOR kAND
+  nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
+  nonassoc tLBRACE_ARG
+  nonassoc tLOWEST
+preclow
+
+rule
+
+         program: compstmt
+                    {
+                      result = val[0]
+                    }
+
+        bodystmt: compstmt opt_rescue opt_else opt_ensure
+                    {
+                      rescue_bodies     = val[1]
+                      else_t,   else_   = val[2]
+                      ensure_t, ensure_ = val[3]
+
+                      if rescue_bodies.empty? && !else_.nil?
+                        diagnostic :warning, :useless_else, nil, else_t
+                      end
+
+                      result = @builder.begin_body(val[0],
+                                  rescue_bodies,
+                                  else_t,   else_,
+                                  ensure_t, ensure_)
+                    }
+
+        compstmt: stmts opt_terms
+                    {
+                      result = @builder.compstmt(val[0])
+                    }
+
+           stmts: # nothing
+                    {
+                      result = []
+                    }
+                | stmt
+                    {
+                      result = [ val[0] ]
+                    }
+                | error stmt
+                    {
+                      result = [ val[1] ]
+                    }
+                | stmts terms stmt
+                    {
+                      result = val[0] << val[2]
+                    }
+
+            stmt: kALIAS fitem
+                    {
+                      @lexer.state = :expr_fname
+                    }
+                    fitem
+                    {
+                      result = @builder.alias(val[0], val[1], val[3])
+                    }
+                | kALIAS tGVAR tGVAR
+                    {
+                      result = @builder.alias(val[0],
+                                  @builder.gvar(val[1]),
+                                  @builder.gvar(val[2]))
+                    }
+                | kALIAS tGVAR tBACK_REF
+                    {
+                      result = @builder.alias(val[0],
+                                  @builder.gvar(val[1]),
+                                  @builder.back_ref(val[2]))
+                    }
+                | kALIAS tGVAR tNTH_REF
+                    {
+                      diagnostic :error, :nth_ref_alias, nil, val[2]
+                    }
+                | kUNDEF undef_list
+                    {
+                      result = @builder.undef_method(val[0], val[1])
+                    }
+                | stmt kIF_MOD expr_value
+                    {
+                      result = @builder.condition_mod(val[0], nil,
+                                                      val[1], val[2])
+                    }
+                | stmt kUNLESS_MOD expr_value
+                    {
+                      result = @builder.condition_mod(nil, val[0],
+                                                      val[1], val[2])
+                    }
+                | stmt kWHILE_MOD expr_value
+                    {
+                      result = @builder.loop_mod(:while, val[0], val[1], val[2])
+                    }
+                | stmt kUNTIL_MOD expr_value
+                    {
+                      result = @builder.loop_mod(:until, val[0], val[1], val[2])
+                    }
+                | stmt kRESCUE_MOD stmt
+                    {
+                      rescue_body = @builder.rescue_body(val[1],
+                                        nil, nil, nil,
+                                        nil, val[2])
+
+                      result = @builder.begin_body(val[0], [ rescue_body ])
+                    }
+                | klBEGIN tLCURLY compstmt tRCURLY
+                    {
+                      if in_def?
+                        diagnostic :error, :begin_in_method, nil, val[0]
+                      end
+
+                      result = @builder.preexe(val[0], val[1], val[2], val[3])
+                    }
+                | klEND tLCURLY compstmt tRCURLY
+                    {
+                      result = @builder.postexe(val[0], val[1], val[2], val[3])
+                    }
+                | lhs tEQL command_call
+                    {
+                      result = @builder.assign(val[0], val[1], val[2])
+                    }
+                | mlhs tEQL command_call
+                    {
+                      result = @builder.multi_assign(val[0], val[1], val[2])
+                    }
+                | var_lhs tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | primary_value tLBRACK2 aref_args tRBRACK tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.index(
+                                    val[0], val[1], val[2], val[3]),
+                                  val[4], val[5])
+                    }
+                | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tDOT tCONSTANT tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | backref tOP_ASGN command_call
+                    {
+                      @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | lhs tEQL mrhs
+                    {
+                      result = @builder.assign(val[0], val[1],
+                                  @builder.array(nil, val[2], nil))
+                    }
+                | mlhs tEQL arg_value
+                    {
+                      result = @builder.multi_assign(val[0], val[1], val[2])
+                    }
+                | mlhs tEQL mrhs
+                    {
+                      result = @builder.multi_assign(val[0], val[1],
+                                  @builder.array(nil, val[2], nil))
+                    }
+                | expr
+
+            expr: command_call
+                | expr kAND expr
+                    {
+                      result = @builder.logical_op(:and, val[0], val[1], val[2])
+                    }
+                | expr kOR expr
+                    {
+                      result = @builder.logical_op(:or, val[0], val[1], val[2])
+                    }
+                | kNOT expr
+                    {
+                      result = @builder.not_op(val[0], nil, val[1], nil)
+                    }
+                | tBANG command_call
+                    {
+                      result = @builder.not_op(val[0], nil, val[1], nil)
+                    }
+                | arg
+
+      expr_value: expr
+
+    command_call: command
+                | block_command
+                | kRETURN call_args
+                    {
+                      result = @builder.keyword_cmd(:return, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kBREAK call_args
+                    {
+                      result = @builder.keyword_cmd(:break, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kNEXT call_args
+                    {
+                      result = @builder.keyword_cmd(:next, val[0],
+                                  nil, val[1], nil)
+                    }
+
+   block_command: block_call
+                | block_call tDOT operation2 command_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | block_call tCOLON2 operation2 command_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+
+ cmd_brace_block: tLBRACE_ARG
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_var compstmt tRCURLY
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+
+         command: operation command_args =tLOWEST
+                    {
+                      lparen_t, args, rparen_t = val[1]
+                      result = @builder.call_method(nil, nil, val[0],
+                                  lparen_t, args, rparen_t)
+                    }
+                | operation command_args cmd_brace_block
+                    {
+                      lparen_t, args, rparen_t = val[1]
+                      method_call = @builder.call_method(nil, nil, val[0],
+                                      lparen_t, args, rparen_t)
+
+                      begin_t, block_args, body, end_t = val[2]
+                      result      = @builder.block(method_call,
+                                      begin_t, block_args, body, end_t)
+                    }
+                | primary_value tDOT operation2 command_args =tLOWEST
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+
+                    }
+                | primary_value tDOT operation2 command_args cmd_brace_block
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                      lparen_t, args, rparen_t)
+
+                      begin_t, block_args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, block_args, body, end_t)
+                    }
+                | primary_value tCOLON2 operation2 command_args =tLOWEST
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tCOLON2 operation2 command_args cmd_brace_block
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                      lparen_t, args, rparen_t)
+
+                      begin_t, block_args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, block_args, body, end_t)
+                    }
+                | kSUPER command_args
+                    {
+                      lparen_t, args, rparen_t = val[1]
+                      result = @builder.keyword_cmd(:super, val[0],
+                                  lparen_t, args, rparen_t)
+                    }
+                | kYIELD command_args
+                    {
+                      lparen_t, args, rparen_t = val[1]
+                      result = @builder.keyword_cmd(:yield, val[0],
+                                  lparen_t, args, rparen_t)
+                    }
+
+            mlhs: mlhs_basic
+                    {
+                      result = @builder.multi_lhs(nil, val[0], nil)
+                    }
+                | tLPAREN mlhs_entry tRPAREN
+                    {
+                      result = @builder.begin(val[0], val[1], val[2])
+                    }
+
+      mlhs_entry: mlhs_basic
+                    {
+                      result = @builder.multi_lhs(nil, val[0], nil)
+                    }
+                | tLPAREN mlhs_entry tRPAREN
+                    {
+                      result = @builder.multi_lhs(val[0], val[1], val[2])
+                    }
+
+      mlhs_basic: mlhs_head
+                    {
+                      result = val[0]
+                    }
+                | mlhs_head mlhs_item
+                    {
+                      result = val[0] << val[1]
+                    }
+                | mlhs_head tSTAR mlhs_node
+                    {
+                      result = val[0] << @builder.splat(val[1], val[2])
+                    }
+                | mlhs_head tSTAR
+                    {
+                      result = val[0] << @builder.splat(val[1])
+                    }
+                | tSTAR mlhs_node
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+                | tSTAR
+                    {
+                      result = [ @builder.splat(val[0]) ]
+                    }
+
+       mlhs_item: mlhs_node
+                | tLPAREN mlhs_entry tRPAREN
+                    {
+                      result = @builder.begin(val[0], val[1], val[2])
+                    }
+
+       mlhs_head: mlhs_item tCOMMA
+                    {
+                      result = [ val[0] ]
+                    }
+                | mlhs_head mlhs_item tCOMMA
+                    {
+                      result = val[0] << val[1]
+                    }
+
+       mlhs_node: variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | primary_value tLBRACK2 aref_args tRBRACK
+                    {
+                      result = @builder.index_asgn(val[0], val[1], val[2], val[3])
+                    }
+                | primary_value tDOT tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tDOT tCONSTANT
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_fetch(val[0], val[1], val[2]))
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_global(val[0], val[1]))
+                    }
+                | backref
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+
+             lhs: variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | primary_value tLBRACK2 aref_args tRBRACK
+                    {
+                      result = @builder.index_asgn(val[0], val[1], val[2], val[3])
+                    }
+                | primary_value tDOT tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tDOT tCONSTANT
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_fetch(val[0], val[1], val[2]))
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_global(val[0], val[1]))
+                    }
+                | backref
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+
+           cname: tIDENTIFIER
+                    {
+                      diagnostic :error, :module_name_const, nil, val[0]
+                    }
+                | tCONSTANT
+
+           cpath: tCOLON3 cname
+                    {
+                      result = @builder.const_global(val[0], val[1])
+                    }
+                | cname
+                    {
+                      result = @builder.const(val[0])
+                    }
+                | primary_value tCOLON2 cname
+                    {
+                      result = @builder.const_fetch(val[0], val[1], val[2])
+                    }
+
+           fname: tIDENTIFIER | tCONSTANT | tFID
+                | op
+                | reswords
+
+            fsym: fname
+                    {
+                      result = @builder.symbol(val[0])
+                    }
+                | symbol
+
+           fitem: fsym
+                | dsym
+
+      undef_list: fitem
+                    {
+                      result = [ val[0] ]
+                    }
+                | undef_list tCOMMA
+                    {
+                      @lexer.state = :expr_fname
+                    }
+                    fitem
+                    {
+                      result = val[0] << val[3]
+                    }
+
+              op: tPIPE    | tCARET     | tAMPER2 | tCMP   | tEQ     | tEQQ
+                | tMATCH   | tGT        | tGEQ    | tLT    | tLEQ    | tLSHFT
+                | tRSHFT   | tPLUS      | tMINUS  | tSTAR2 | tSTAR   | tDIVIDE
+                | tPERCENT | tPOW       | tTILDE  | tUPLUS | tUMINUS | tAREF
+                | tASET    | tBACK_REF2
+
+        reswords: k__LINE__ | k__FILE__   | klBEGIN | klEND  | kALIAS  | kAND
+                | kBEGIN    | kBREAK      | kCASE   | kCLASS | kDEF    | kDEFINED
+                | kDO       | kELSE       | kELSIF  | kEND   | kENSURE | kFALSE
+                | kFOR      | kIN         | kMODULE | kNEXT  | kNIL    | kNOT
+                | kOR       | kREDO       | kRESCUE | kRETRY | kRETURN | kSELF
+                | kSUPER    | kTHEN       | kTRUE   | kUNDEF | kWHEN   | kYIELD
+                | kIF       | kUNLESS     | kWHILE  | kUNTIL
+
+             arg: lhs tEQL arg
+                    {
+                      result = @builder.assign(val[0], val[1], val[2])
+                    }
+                | lhs tEQL arg kRESCUE_MOD arg
+                    {
+                      rescue_body = @builder.rescue_body(val[3],
+                                        nil, nil, nil,
+                                        nil, val[4])
+
+                      rescue_ = @builder.begin_body(val[2], [ rescue_body ])
+
+                      result  = @builder.assign(val[0], val[1], rescue_)
+                    }
+                | var_lhs tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | primary_value tLBRACK2 aref_args tRBRACK tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.index(
+                                    val[0], val[1], val[2], val[3]),
+                                  val[4], val[5])
+                    }
+                | primary_value tDOT tIDENTIFIER tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tDOT tCONSTANT tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
+                    {
+                      diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ]
+                    }
+                | tCOLON3 tCONSTANT tOP_ASGN arg
+                    {
+                      diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ]
+                    }
+                | backref tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | arg tDOT2 arg
+                    {
+                      result = @builder.range_inclusive(val[0], val[1], val[2])
+                    }
+                | arg tDOT3 arg
+                    {
+                      result = @builder.range_exclusive(val[0], val[1], val[2])
+                    }
+                | arg tPLUS arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tMINUS arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tSTAR2 arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tDIVIDE arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tPERCENT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tPOW arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | tUMINUS_NUM tINTEGER tPOW arg
+                    {
+                      result = @builder.unary_op(val[0],
+                                  @builder.binary_op(
+                                    @builder.integer(val[1]),
+                                      val[2], val[3]))
+                    }
+                | tUMINUS_NUM tFLOAT tPOW arg
+                    {
+                      result = @builder.unary_op(val[0],
+                                  @builder.binary_op(
+                                    @builder.float(val[1]),
+                                      val[2], val[3]))
+                    }
+                | tUPLUS arg
+                    {
+                      result = @builder.unary_op(val[0], val[1])
+                    }
+                | tUMINUS arg
+                    {
+                      result = @builder.unary_op(val[0], val[1])
+                    }
+                | arg tPIPE arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tCARET arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tAMPER2 arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tCMP arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tGT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tGEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tLT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tLEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tEQQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tNEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tMATCH arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tNMATCH arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | tBANG arg
+                    {
+                      result = @builder.not_op(val[0], nil, val[1], nil)
+                    }
+                | tTILDE arg
+                    {
+                      result = @builder.unary_op(val[0], val[1])
+                    }
+                | arg tLSHFT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tRSHFT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tANDOP arg
+                    {
+                      result = @builder.logical_op(:and, val[0], val[1], val[2])
+                    }
+                | arg tOROP arg
+                    {
+                      result = @builder.logical_op(:or, val[0], val[1], val[2])
+                    }
+                | kDEFINED opt_nl arg
+                    {
+                      result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
+                    }
+                | arg tEH arg tCOLON arg
+                    {
+                      result = @builder.ternary(val[0], val[1],
+                                                val[2], val[3], val[4])
+                    }
+                | primary
+
+       arg_value: arg
+
+       aref_args: none
+                | command opt_nl
+                    {
+                      result = [ val[0] ]
+                    }
+                | args trailer
+                    {
+                      result = val[0]
+                    }
+                | args tCOMMA tSTAR arg opt_nl
+                    {
+                      result = val[0] << @builder.splat(val[2], val[3])
+                    }
+                | assocs trailer
+                    {
+                      result = [ @builder.associate(nil, val[0], nil) ]
+                    }
+                | tSTAR arg opt_nl
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+
+      paren_args: tLPAREN2 none tRPAREN
+                    {
+                      result = [ val[0], [], val[2] ]
+                    }
+                | tLPAREN2 call_args opt_nl tRPAREN
+                    {
+                      result = [ val[0], val[1], val[3] ]
+                    }
+                | tLPAREN2 block_call opt_nl tRPAREN
+                    {
+                      result = [ val[0], [ val[1] ], val[3] ]
+                    }
+                | tLPAREN2 args tCOMMA block_call opt_nl tRPAREN
+                    {
+                      result = [ val[0], val[1] << val[3], val[5] ]
+                    }
+
+  opt_paren_args: # nothing
+                    {
+                      result = [ nil, [], nil ]
+                    }
+                | paren_args
+
+       call_args: command
+                    {
+                      result = [ val[0] ]
+                    }
+                | args opt_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | args tCOMMA tSTAR arg_value opt_block_arg
+                    {
+                      result = val[0].concat(
+                                [ @builder.splat(val[2], val[3]),
+                                   *val[4] ])
+                    }
+                | assocs opt_block_arg
+                    {
+                      result =  [ @builder.associate(nil, val[0], nil),
+                                  *val[1] ]
+                    }
+                | assocs tCOMMA tSTAR arg_value opt_block_arg
+                    {
+                      result =  [ @builder.associate(nil, val[0], nil),
+                                  @builder.splat(val[2], val[3]),
+                                  *val[4] ]
+                    }
+                | args tCOMMA assocs opt_block_arg
+                    {
+                      result = val[0].concat(
+                                [ @builder.associate(nil, val[2], nil),
+                                  *val[3] ])
+                    }
+                | args tCOMMA assocs tCOMMA tSTAR arg opt_block_arg
+                    {
+                      result = val[0].concat(
+                                [ @builder.associate(nil, val[2], nil),
+                                  @builder.splat(val[4], val[5]),
+                                  *val[6] ])
+                    }
+                | tSTAR arg_value opt_block_arg
+                    {
+                      result =  [ @builder.splat(val[0], val[1]),
+                                  *val[2] ]
+                    }
+                | block_arg
+                    {
+                      result =  [ val[0] ]
+                    }
+
+      call_args2: arg_value tCOMMA args opt_block_arg
+                    {
+                      result = [ val[0], *val[2].concat(val[3]) ]
+                    }
+                | arg_value tCOMMA block_arg
+                    {
+                      result = [ val[0], val[2] ]
+                    }
+                | arg_value tCOMMA tSTAR arg_value opt_block_arg
+                    {
+                      result =  [ val[0],
+                                  @builder.splat(val[2], val[3]),
+                                  *val[4] ]
+                    }
+                | arg_value tCOMMA args tCOMMA tSTAR arg_value opt_block_arg
+                    {
+                      result =  [ val[0],
+                                  *val[2].
+                                    push(@builder.splat(val[4], val[5])).
+                                    concat(val[6]) ]
+                    }
+                | assocs opt_block_arg
+                    {
+                      result =  [ @builder.associate(nil, val[0], nil),
+                                  *val[1] ]
+                    }
+                | assocs tCOMMA tSTAR arg_value opt_block_arg
+                    {
+                      result =  [ @builder.associate(nil, val[0], nil),
+                                  @builder.splat(val[2], val[3]),
+                                  *val[4] ]
+                    }
+                | arg_value tCOMMA assocs opt_block_arg
+                    {
+                      result =  [ val[0],
+                                  @builder.associate(nil, val[2], nil),
+                                  *val[3] ]
+                    }
+                | arg_value tCOMMA args tCOMMA assocs opt_block_arg
+                    {
+                      result =  [ val[0],
+                                  *val[2].
+                                    push(@builder.associate(nil, val[4], nil)).
+                                    concat(val[5]) ]
+                    }
+                | arg_value tCOMMA assocs tCOMMA tSTAR arg_value opt_block_arg
+                    {
+                      result =  [ val[0],
+                                  @builder.associate(nil, val[2], nil),
+                                  @builder.splat(val[4], val[5]),
+                                  *val[6] ]
+                    }
+                | arg_value tCOMMA args tCOMMA assocs tCOMMA tSTAR arg_value opt_block_arg
+                    {
+                      result =  [ val[0],
+                                  *val[2].
+                                    push(@builder.associate(nil, val[4], nil)).
+                                    push(@builder.splat(val[6], val[7])).
+                                    concat(val[8]) ]
+                    }
+                | tSTAR arg_value opt_block_arg
+                    {
+                      result =  [ @builder.splat(val[0], val[1]),
+                                  *val[2] ]
+                    }
+                | block_arg
+                    {
+                      result =  [ val[0] ]
+                    }
+
+    command_args:   {
+                      result = @lexer.cmdarg.dup
+                      @lexer.cmdarg.push(true)
+                    }
+                    open_args
+                    {
+                      @lexer.cmdarg = val[0]
+
+                      result = val[1]
+                    }
+
+       open_args: call_args
+                    {
+                      result = [ nil, val[0], nil ]
+                    }
+                | tLPAREN_ARG
+                    {
+                      @lexer.state = :expr_endarg
+                    }
+                    tRPAREN
+                    {
+                      result = [ val[0], [], val[2] ]
+                    }
+                | tLPAREN_ARG call_args2
+                    {
+                      @lexer.state = :expr_endarg
+                    }
+                    tRPAREN
+                    {
+                      result = [ val[0], val[1], val[3] ]
+                    }
+
+       block_arg: tAMPER arg_value
+                    {
+                      result = @builder.block_pass(val[0], val[1])
+                    }
+
+   opt_block_arg: tCOMMA block_arg
+                    {
+                      result = [ val[1] ]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+            args: arg_value
+                    {
+                      result = [ val[0] ]
+                    }
+                | args tCOMMA arg_value
+                    {
+                      result = val[0] << val[2]
+                    }
+
+            mrhs: args tCOMMA arg_value
+                    {
+                      result = val[0] << val[2]
+                    }
+                | args tCOMMA tSTAR arg_value
+                    {
+                      result = val[0] << @builder.splat(val[2], val[3])
+                    }
+                | tSTAR arg_value
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+
+         primary: literal
+                | strings
+                | xstring
+                | regexp
+                | words
+                | qwords
+                | var_ref
+                | backref
+                | tFID
+                    {
+                      result = @builder.call_method(nil, nil, val[0])
+                    }
+                | kBEGIN bodystmt kEND
+                    {
+                      result = @builder.begin_keyword(val[0], val[1], val[2])
+                    }
+                | tLPAREN_ARG expr
+                    {
+                      @lexer.state = :expr_endarg
+                    }
+                    opt_nl tRPAREN
+                    {
+                      result = @builder.begin(val[0], val[1], val[4])
+                    }
+                | tLPAREN compstmt tRPAREN
+                    {
+                      result = @builder.begin(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      result = @builder.const_fetch(val[0], val[1], val[2])
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      result = @builder.const_global(val[0], val[1])
+                    }
+                | primary_value tLBRACK2 aref_args tRBRACK
+                    {
+                      result = @builder.index(val[0], val[1], val[2], val[3])
+                    }
+                | tLBRACK aref_args tRBRACK
+                    {
+                      result = @builder.array(val[0], val[1], val[2])
+                    }
+                | tLBRACE assoc_list tRCURLY
+                    {
+                      result = @builder.associate(val[0], val[1], val[2])
+                    }
+                | kRETURN
+                    {
+                      result = @builder.keyword_cmd(:return, val[0])
+                    }
+                | kYIELD tLPAREN2 call_args tRPAREN
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
+                    }
+                | kYIELD tLPAREN2 tRPAREN
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
+                    }
+                | kYIELD
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0])
+                    }
+                | kDEFINED opt_nl tLPAREN2 expr tRPAREN
+                    {
+                      result = @builder.keyword_cmd(:defined?, val[0],
+                                                    val[2], [ val[3] ], val[4])
+                    }
+                | operation brace_block
+                    {
+                      method_call = @builder.call_method(nil, nil, val[0])
+
+                      begin_t, args, body, end_t = val[1]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | method_call
+                | method_call brace_block
+                    {
+                      begin_t, args, body, end_t = val[1]
+                      result      = @builder.block(val[0],
+                                      begin_t, args, body, end_t)
+                    }
+                | kIF expr_value then compstmt if_tail kEND
+                    {
+                      else_t, else_ = val[4]
+                      result = @builder.condition(val[0], val[1], val[2],
+                                                  val[3], else_t,
+                                                  else_,  val[5])
+                    }
+                | kUNLESS expr_value then compstmt opt_else kEND
+                    {
+                      else_t, else_ = val[4]
+                      result = @builder.condition(val[0], val[1], val[2],
+                                                  else_,  else_t,
+                                                  val[3], val[5])
+                    }
+                | kWHILE
+                    {
+                      @lexer.cond.push(true)
+                    }
+                    expr_value do
+                    {
+                      @lexer.cond.pop
+                    }
+                    compstmt kEND
+                    {
+                      result = @builder.loop(:while, val[0], val[2], val[3],
+                                             val[5], val[6])
+                    }
+                | kUNTIL
+                    {
+                      @lexer.cond.push(true)
+                    }
+                    expr_value do
+                    {
+                      @lexer.cond.pop
+                    }
+                    compstmt kEND
+                    {
+                      result = @builder.loop(:until, val[0], val[2], val[3],
+                                             val[5], val[6])
+                    }
+                | kCASE expr_value opt_terms case_body kEND
+                    {
+                      when_bodies       = val[3][0..-2]
+                      else_t, else_body = val[3][-1]
+
+                      result = @builder.case(val[0], val[1],
+                                             when_bodies, else_t, else_body,
+                                             val[4])
+                    }
+                | kCASE            opt_terms case_body kEND
+                    {
+                      when_bodies       = val[2][0..-2]
+                      else_t, else_body = val[2][-1]
+
+                      result = @builder.case(val[0], nil,
+                                             when_bodies, else_t, else_body,
+                                             val[3])
+                    }
+                | kCASE opt_terms kELSE compstmt kEND
+                    {
+                      result = @builder.case(val[0], nil,
+                                             [], val[2], val[3],
+                                             val[4])
+                    }
+                | kFOR for_var kIN
+                    {
+                      @lexer.cond.push(true)
+                    }
+                    expr_value do
+                    {
+                      @lexer.cond.pop
+                    }
+                    compstmt kEND
+                    {
+                      result = @builder.for(val[0], val[1],
+                                            val[2], val[4],
+                                            val[5], val[7], val[8])
+                    }
+                | kCLASS cpath superclass
+                    {
+                      @static_env.extend_static
+                    }
+                    bodystmt kEND
+                    {
+                      if in_def?
+                        diagnostic :error, :class_in_def, nil, val[0]
+                      end
+
+                      lt_t, superclass = val[2]
+                      result = @builder.def_class(val[0], val[1],
+                                                  lt_t, superclass,
+                                                  val[4], val[5])
+
+                      @static_env.unextend
+                    }
+                | kCLASS tLSHFT expr term
+                    {
+                      result = @def_level
+                      @def_level = 0
+
+                      @static_env.extend_static
+                    }
+                    bodystmt kEND
+                    {
+                      result = @builder.def_sclass(val[0], val[1], val[2],
+                                                   val[5], val[6])
+
+                      @static_env.unextend
+
+                      @def_level = val[4]
+                    }
+                | kMODULE cpath
+                    {
+                      @static_env.extend_static
+                    }
+                    bodystmt kEND
+                    {
+                      if in_def?
+                        diagnostic :error, :module_in_def, nil, val[0]
+                      end
+
+                      result = @builder.def_module(val[0], val[1],
+                                                   val[3], val[4])
+
+                      @static_env.unextend
+                    }
+                | kDEF fname
+                    {
+                      @def_level += 1
+                      @static_env.extend_static
+                    }
+                    f_arglist bodystmt kEND
+                    {
+                      result = @builder.def_method(val[0], val[1],
+                                  val[3], val[4], val[5])
+
+                      @static_env.unextend
+                      @def_level -= 1
+                    }
+                | kDEF singleton dot_or_colon
+                    {
+                      @lexer.state = :expr_fname
+                    }
+                    fname
+                    {
+                      @def_level += 1
+                      @static_env.extend_static
+                    }
+                    f_arglist bodystmt kEND
+                    {
+                      result = @builder.def_singleton(val[0], val[1], val[2],
+                                  val[4], val[6], val[7], val[8])
+
+                      @static_env.unextend
+                      @def_level -= 1
+                    }
+                | kBREAK
+                    {
+                      result = @builder.keyword_cmd(:break, val[0])
+                    }
+                | kNEXT
+                    {
+                      result = @builder.keyword_cmd(:next, val[0])
+                    }
+                | kREDO
+                    {
+                      result = @builder.keyword_cmd(:redo, val[0])
+                    }
+                | kRETRY
+                    {
+                      result = @builder.keyword_cmd(:retry, val[0])
+                    }
+
+   primary_value: primary
+
+            then: term
+                | tCOLON
+                | kTHEN
+                | term kTHEN
+                    {
+                      result = val[1]
+                    }
+
+              do: term
+                | tCOLON
+                | kDO_COND
+
+         if_tail: opt_else
+                | kELSIF expr_value then compstmt if_tail
+                    {
+                      else_t, else_ = val[4]
+                      result = [ val[0],
+                                 @builder.condition(val[0], val[1], val[2],
+                                                    val[3], else_t,
+                                                    else_,  nil),
+                               ]
+                    }
+
+        opt_else: none
+                | kELSE compstmt
+                    {
+                      result = val
+                    }
+
+         for_var: lhs
+                | mlhs
+
+       block_par: mlhs_item
+                    {
+                      result = [ @builder.arg_expr(val[0]) ]
+                    }
+                | block_par tCOMMA mlhs_item
+                    {
+                      result = val[0] << @builder.arg_expr(val[2])
+                    }
+
+       block_var: block_par
+                | block_par tCOMMA
+                | block_par tCOMMA tAMPER lhs
+                    {
+                      result =  val[0].
+                                  push(@builder.blockarg_expr(val[2], val[3]))
+                    }
+                | block_par tCOMMA tSTAR lhs tCOMMA tAMPER lhs
+                    {
+                      result =  val[0].
+                                  push(@builder.restarg_expr(val[2], val[3])).
+                                  push(@builder.blockarg_expr(val[5], val[6]))
+                    }
+                | block_par tCOMMA tSTAR tCOMMA tAMPER lhs
+                    {
+                      result =  val[0].
+                                  push(@builder.restarg_expr(val[2])).
+                                  push(@builder.blockarg_expr(val[4], val[5]))
+                    }
+                | block_par tCOMMA tSTAR lhs
+                    {
+                      result =  val[0].
+                                  push(@builder.restarg_expr(val[2], val[3]))
+                    }
+                | block_par tCOMMA tSTAR
+                    {
+                      result =  val[0].
+                                  push(@builder.restarg_expr(val[2]))
+                    }
+                | tSTAR lhs tCOMMA tAMPER lhs
+                    {
+                      result =  [ @builder.restarg_expr(val[0], val[1]),
+                                  @builder.blockarg_expr(val[3], val[4]) ]
+                    }
+                | tSTAR tCOMMA tAMPER lhs
+                    {
+                      result =  [ @builder.restarg_expr(val[0]),
+                                  @builder.blockarg_expr(val[2], val[3]) ]
+                    }
+                | tSTAR lhs
+                    {
+                      result =  [ @builder.restarg_expr(val[0], val[1]) ]
+                    }
+                | tSTAR
+                    {
+                      result =  [ @builder.restarg_expr(val[0]) ]
+                    }
+                | tAMPER lhs
+                    {
+                      result =  [ @builder.blockarg_expr(val[0], val[1]) ]
+                    }
+                ;
+
+   opt_block_var: # nothing
+                    {
+                      result = @builder.args(nil, [], nil)
+                    }
+                | tPIPE tPIPE
+                    {
+                      result = @builder.args(val[0], [], val[1])
+                    }
+                | tOROP
+                    {
+                      result = @builder.args(val[0], [], val[0])
+                    }
+                | tPIPE block_var tPIPE
+                    {
+                      result = @builder.args(val[0], val[1], val[2], false)
+                    }
+
+        do_block: kDO_BLOCK
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_var compstmt kEND
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+
+      block_call: command do_block
+                    {
+                      begin_t, block_args, body, end_t = val[1]
+                      result      = @builder.block(val[0],
+                                      begin_t, block_args, body, end_t)
+                    }
+                | block_call tDOT operation2 opt_paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | block_call tCOLON2 operation2 opt_paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+
+     method_call: operation paren_args
+                    {
+                      lparen_t, args, rparen_t = val[1]
+                      result = @builder.call_method(nil, nil, val[0],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tDOT operation2 opt_paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tCOLON2 operation2 paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tCOLON2 operation3
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2])
+                    }
+                | kSUPER paren_args
+                    {
+                      lparen_t, args, rparen_t = val[1]
+                      result = @builder.keyword_cmd(:super, val[0],
+                                  lparen_t, args, rparen_t)
+                    }
+                | kSUPER
+                    {
+                      result = @builder.keyword_cmd(:zsuper, val[0])
+                    }
+
+     brace_block: tLCURLY
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_var compstmt tRCURLY
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+                | kDO
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_var compstmt kEND
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+
+       case_body: kWHEN when_args then compstmt cases
+                    {
+                      result = [ @builder.when(val[0], val[1], val[2], val[3]),
+                                 *val[4] ]
+                    }
+
+       when_args: args
+                | args tCOMMA tSTAR arg_value
+                    {
+                      result = val[0] << @builder.splat(val[2], val[3])
+                    }
+                | tSTAR arg_value
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+
+           cases: opt_else
+                    {
+                      result = [ val[0] ]
+                    }
+                | case_body
+
+      opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
+                    {
+                      assoc_t, exc_var = val[2]
+
+                      if val[1]
+                        exc_list = @builder.array(nil, val[1], nil)
+                      end
+
+                      result = [ @builder.rescue_body(val[0],
+                                      exc_list, assoc_t, exc_var,
+                                      val[3], val[4]),
+                                 *val[5] ]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+        exc_list: arg_value
+                    {
+                      result = [ val[0] ]
+                    }
+                | mrhs
+                | none
+
+         exc_var: tASSOC lhs
+                    {
+                      result = [ val[0], val[1] ]
+                    }
+                | none
+
+      opt_ensure: kENSURE compstmt
+                    {
+                      result = [ val[0], val[1] ]
+                    }
+                | none
+
+         literal: numeric
+                | symbol
+                | dsym
+
+         strings: string
+                    {
+                      result = @builder.string_compose(nil, val[0], nil)
+                    }
+
+          string: string1
+                    {
+                      result = [ val[0] ]
+                    }
+                | string string1
+                    {
+                      result = val[0] << val[1]
+                    }
+
+         string1: tSTRING_BEG string_contents tSTRING_END
+                    {
+                      result = @builder.string_compose(val[0], val[1], val[2])
+                    }
+                | tSTRING
+                    {
+                      result = @builder.string(val[0])
+                    }
+
+         xstring: tXSTRING_BEG xstring_contents tSTRING_END
+                    {
+                      result = @builder.xstring_compose(val[0], val[1], val[2])
+                    }
+
+          regexp: tREGEXP_BEG xstring_contents tSTRING_END tREGEXP_OPT
+                    {
+                      opts   = @builder.regexp_options(val[3])
+                      result = @builder.regexp_compose(val[0], val[1], val[2], opts)
+                    }
+
+           words: tWORDS_BEG word_list tSTRING_END
+                    {
+                      result = @builder.words_compose(val[0], val[1], val[2])
+                    }
+
+       word_list: # nothing
+                    {
+                      result = []
+                    }
+                | word_list word tSPACE
+                    {
+                      result = val[0] << @builder.word(val[1])
+                    }
+
+            word: string_content
+                    {
+                      result = [ val[0] ]
+                    }
+                | word string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+          qwords: tQWORDS_BEG qword_list tSTRING_END
+                    {
+                      result = @builder.words_compose(val[0], val[1], val[2])
+                    }
+
+      qword_list: # nothing
+                    {
+                      result = []
+                    }
+                | qword_list tSTRING_CONTENT tSPACE
+                    {
+                      result = val[0] << @builder.string_internal(val[1])
+                    }
+
+ string_contents: # nothing
+                    {
+                      result = []
+                    }
+                | string_contents string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+xstring_contents: # nothing
+                    {
+                      result = []
+                    }
+                | xstring_contents string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+  string_content: tSTRING_CONTENT
+                    {
+                      result = @builder.string_internal(val[0])
+                    }
+                | tSTRING_DVAR string_dvar
+                    {
+                      result = val[1]
+                    }
+                | tSTRING_DBEG
+                    {
+                      @lexer.cond.push(false)
+                      @lexer.cmdarg.push(false)
+                    }
+                    compstmt tRCURLY
+                    {
+                      @lexer.cond.lexpop
+                      @lexer.cmdarg.lexpop
+
+                      result = @builder.begin(val[0], val[2], val[3])
+                    }
+
+     string_dvar: tGVAR
+                    {
+                      result = @builder.gvar(val[0])
+                    }
+                | tIVAR
+                    {
+                      result = @builder.ivar(val[0])
+                    }
+                | tCVAR
+                    {
+                      result = @builder.cvar(val[0])
+                    }
+                | backref
+
+
+          symbol: tSYMBOL
+                    {
+                      result = @builder.symbol(val[0])
+                    }
+
+            dsym: tSYMBEG xstring_contents tSTRING_END
+                    {
+                      result = @builder.symbol_compose(val[0], val[1], val[2])
+                    }
+
+         numeric: tINTEGER
+                    {
+                      result = @builder.integer(val[0])
+                    }
+                | tFLOAT
+                    {
+                      result = @builder.float(val[0])
+                    }
+                | tUMINUS_NUM tINTEGER =tLOWEST
+                    {
+                      result = @builder.negate(val[0],
+                                  @builder.integer(val[1]))
+                    }
+                | tUMINUS_NUM tFLOAT   =tLOWEST
+                    {
+                      result = @builder.negate(val[0],
+                                  @builder.float(val[1]))
+                    }
+
+        variable: tIDENTIFIER
+                    {
+                      result = @builder.ident(val[0])
+                    }
+                | tIVAR
+                    {
+                      result = @builder.ivar(val[0])
+                    }
+                | tGVAR
+                    {
+                      result = @builder.gvar(val[0])
+                    }
+                | tCVAR
+                    {
+                      result = @builder.cvar(val[0])
+                    }
+                | tCONSTANT
+                    {
+                      result = @builder.const(val[0])
+                    }
+                | kNIL
+                    {
+                      result = @builder.nil(val[0])
+                    }
+                | kSELF
+                    {
+                      result = @builder.self(val[0])
+                    }
+                | kTRUE
+                    {
+                      result = @builder.true(val[0])
+                    }
+                | kFALSE
+                    {
+                      result = @builder.false(val[0])
+                    }
+                | k__FILE__
+                    {
+                      result = @builder.__FILE__(val[0])
+                    }
+                | k__LINE__
+                    {
+                      result = @builder.__LINE__(val[0])
+                    }
+
+         var_ref: variable
+                    {
+                      result = @builder.accessible(val[0])
+                    }
+
+         var_lhs: variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+
+         backref: tNTH_REF
+                    {
+                      result = @builder.nth_ref(val[0])
+                    }
+                | tBACK_REF
+                    {
+                      result = @builder.back_ref(val[0])
+                    }
+
+      superclass: term
+                    {
+                      result = nil
+                    }
+                | tLT expr_value term
+                    {
+                      result = [ val[0], val[1] ]
+                    }
+                | error term
+                    {
+                      yyerrok
+                      result = nil
+                    }
+
+       f_arglist: tLPAREN2 f_args opt_nl tRPAREN
+                    {
+                      result = @builder.args(val[0], val[1], val[3])
+
+                      @lexer.state = :expr_beg
+                    }
+                | f_args term
+                    {
+                      result = @builder.args(nil, val[0], nil)
+                    }
+
+          f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA f_optarg                   opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA                 f_rest_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg                                   opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |              f_optarg tCOMMA f_rest_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |              f_optarg                   opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |                              f_rest_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |                                             f_block_arg
+                    {
+                      result = [ val[0] ]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+      f_norm_arg: tCONSTANT
+                    {
+                      diagnostic :error, :argument_const, nil, val[0]
+                    }
+                | tIVAR
+                    {
+                      diagnostic :error, :argument_ivar, nil, val[0]
+                    }
+                | tGVAR
+                    {
+                      diagnostic :error, :argument_gvar, nil, val[0]
+                    }
+                | tCVAR
+                    {
+                      diagnostic :error, :argument_cvar, nil, val[0]
+                    }
+                | tIDENTIFIER
+                    {
+                      @static_env.declare val[0][0]
+
+                      result = @builder.arg(val[0])
+                    }
+
+           f_arg: f_norm_arg
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_arg tCOMMA f_norm_arg
+                    {
+                      result = val[0] << val[2]
+                    }
+
+           f_opt: tIDENTIFIER tEQL arg_value
+                    {
+                      @static_env.declare val[0][0]
+
+                      result = @builder.optarg(val[0], val[1], val[2])
+                    }
+
+        f_optarg: f_opt
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_optarg tCOMMA f_opt
+                    {
+                      result = val[0] << val[2]
+                    }
+
+    restarg_mark: tSTAR2 | tSTAR
+
+      f_rest_arg: restarg_mark tIDENTIFIER
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = [ @builder.restarg(val[0], val[1]) ]
+                    }
+                | restarg_mark
+                    {
+                      result = [ @builder.restarg(val[0]) ]
+                    }
+
+     blkarg_mark: tAMPER2 | tAMPER
+
+     f_block_arg: blkarg_mark tIDENTIFIER
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = @builder.blockarg(val[0], val[1])
+                    }
+
+ opt_f_block_arg: tCOMMA f_block_arg
+                    {
+                      result = [ val[1] ]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+       singleton: var_ref
+                | tLPAREN2 expr opt_nl tRPAREN
+                    {
+                      result = val[1]
+                    }
+
+      assoc_list: # nothing
+                    {
+                      result = []
+                    }
+                | assocs trailer
+                    {
+                      result = val[0]
+                    }
+                | args trailer
+                    {
+                      result = @builder.pair_list_18(val[0])
+                    }
+
+          assocs: assoc
+                    {
+                      result = [ val[0] ]
+                    }
+                | assocs tCOMMA assoc
+                    {
+                      result = val[0] << val[2]
+                    }
+
+           assoc: arg_value tASSOC arg_value
+                    {
+                      result = @builder.pair(val[0], val[1], val[2])
+                    }
+
+       operation: tIDENTIFIER | tCONSTANT | tFID
+      operation2: tIDENTIFIER | tCONSTANT | tFID | op
+      operation3: tIDENTIFIER | tFID | op
+    dot_or_colon: tDOT | tCOLON2
+       opt_terms:  | terms
+          opt_nl:  | tNL
+         trailer:  | tNL | tCOMMA
+
+            term: tSEMI
+                    {
+                      yyerrok
+                    }
+                | tNL
+
+           terms: term
+                | terms tSEMI
+
+            none: # nothing
+                    {
+                      result = nil
+                    }
+
+end
+
+---- header
+
+require 'parser'
+
+---- inner
+
+  def version
+    18
+  end
+
+  def default_encoding
+    Encoding::BINARY if defined? Encoding
+  end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/ruby19.y b/app/server/vendor/parser-2.2.2.1/lib/parser/ruby19.y
new file mode 100644
index 0000000..0cdc86a
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/ruby19.y
@@ -0,0 +1,2148 @@
+class Parser::Ruby19
+
+token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
+      kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
+      kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
+      kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
+      kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
+      k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
+      tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
+      tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
+      tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
+      tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
+      tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
+      tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
+      tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
+      tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT
+      tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
+      tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG
+      tCHARACTER
+
+prechigh
+  right    tBANG tTILDE tUPLUS
+  right    tPOW
+  right    tUMINUS_NUM tUMINUS
+  left     tSTAR2 tDIVIDE tPERCENT
+  left     tPLUS tMINUS
+  left     tLSHFT tRSHFT
+  left     tAMPER2
+  left     tPIPE tCARET
+  left     tGT tGEQ tLT tLEQ
+  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
+  left     tANDOP
+  left     tOROP
+  nonassoc tDOT2 tDOT3
+  right    tEH tCOLON
+  left     kRESCUE_MOD
+  right    tEQL tOP_ASGN
+  nonassoc kDEFINED
+  right    kNOT
+  left     kOR kAND
+  nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
+  nonassoc tLBRACE_ARG
+  nonassoc tLOWEST
+preclow
+
+rule
+
+         program: top_compstmt
+
+    top_compstmt: top_stmts opt_terms
+                    {
+                      result = @builder.compstmt(val[0])
+                    }
+
+       top_stmts: # nothing
+                    {
+                      result = []
+                    }
+                | top_stmt
+                    {
+                      result = [ val[0] ]
+                    }
+                | top_stmts terms top_stmt
+                    {
+                      result = val[0] << val[2]
+                    }
+                | error top_stmt
+                    {
+                      result = [ val[1] ]
+                    }
+
+        top_stmt: stmt
+                | klBEGIN tLCURLY top_compstmt tRCURLY
+                    {
+                      result = @builder.preexe(val[0], val[1], val[2], val[3])
+                    }
+
+        bodystmt: compstmt opt_rescue opt_else opt_ensure
+                    {
+                      rescue_bodies     = val[1]
+                      else_t,   else_   = val[2]
+                      ensure_t, ensure_ = val[3]
+
+                      if rescue_bodies.empty? && !else_.nil?
+                        diagnostic :warning, :useless_else, nil, else_t
+                      end
+
+                      result = @builder.begin_body(val[0],
+                                  rescue_bodies,
+                                  else_t,   else_,
+                                  ensure_t, ensure_)
+                    }
+
+        compstmt: stmts opt_terms
+                    {
+                      result = @builder.compstmt(val[0])
+                    }
+
+           stmts: # nothing
+                    {
+                      result = []
+                    }
+                | stmt
+                    {
+                      result = [ val[0] ]
+                    }
+                | stmts terms stmt
+                    {
+                      result = val[0] << val[2]
+                    }
+                | error stmt
+                    {
+                      result = [ val[1] ]
+                    }
+
+            stmt: kALIAS fitem
+                    {
+                      @lexer.state = :expr_fname
+                    }
+                    fitem
+                    {
+                      result = @builder.alias(val[0], val[1], val[3])
+                    }
+                | kALIAS tGVAR tGVAR
+                    {
+                      result = @builder.alias(val[0],
+                                  @builder.gvar(val[1]),
+                                  @builder.gvar(val[2]))
+                    }
+                | kALIAS tGVAR tBACK_REF
+                    {
+                      result = @builder.alias(val[0],
+                                  @builder.gvar(val[1]),
+                                  @builder.back_ref(val[2]))
+                    }
+                | kALIAS tGVAR tNTH_REF
+                    {
+                      diagnostic :error, :nth_ref_alias, nil, val[2]
+                    }
+                | kUNDEF undef_list
+                    {
+                      result = @builder.undef_method(val[0], val[1])
+                    }
+                | stmt kIF_MOD expr_value
+                    {
+                      result = @builder.condition_mod(val[0], nil,
+                                                      val[1], val[2])
+                    }
+                | stmt kUNLESS_MOD expr_value
+                    {
+                      result = @builder.condition_mod(nil, val[0],
+                                                      val[1], val[2])
+                    }
+                | stmt kWHILE_MOD expr_value
+                    {
+                      result = @builder.loop_mod(:while, val[0], val[1], val[2])
+                    }
+                | stmt kUNTIL_MOD expr_value
+                    {
+                      result = @builder.loop_mod(:until, val[0], val[1], val[2])
+                    }
+                | stmt kRESCUE_MOD stmt
+                    {
+                      rescue_body = @builder.rescue_body(val[1],
+                                        nil, nil, nil,
+                                        nil, val[2])
+
+                      result = @builder.begin_body(val[0], [ rescue_body ])
+                    }
+                | klEND tLCURLY compstmt tRCURLY
+                    {
+                      result = @builder.postexe(val[0], val[1], val[2], val[3])
+                    }
+                | command_asgn
+                | mlhs tEQL command_call
+                    {
+                      result = @builder.multi_assign(val[0], val[1], val[2])
+                    }
+                | var_lhs tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.index(
+                                    val[0], val[1], val[2], val[3]),
+                                  val[4], val[5])
+                    }
+                | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tDOT tCONSTANT tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | backref tOP_ASGN command_call
+                    {
+                      @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | lhs tEQL mrhs
+                    {
+                      result = @builder.assign(val[0], val[1],
+                                  @builder.array(nil, val[2], nil))
+                    }
+                | mlhs tEQL arg_value
+                    {
+                      result = @builder.multi_assign(val[0], val[1], val[2])
+                    }
+                | mlhs tEQL mrhs
+                    {
+                      result = @builder.multi_assign(val[0], val[1],
+                                  @builder.array(nil, val[2], nil))
+                    }
+                | expr
+
+    command_asgn: lhs tEQL command_call
+                    {
+                      result = @builder.assign(val[0], val[1], val[2])
+                    }
+                | lhs tEQL command_asgn
+                    {
+                      result = @builder.assign(val[0], val[1], val[2])
+                    }
+
+            expr: command_call
+                | expr kAND expr
+                    {
+                      result = @builder.logical_op(:and, val[0], val[1], val[2])
+                    }
+                | expr kOR expr
+                    {
+                      result = @builder.logical_op(:or, val[0], val[1], val[2])
+                    }
+                | kNOT opt_nl expr
+                    {
+                      result = @builder.not_op(val[0], nil, val[2], nil)
+                    }
+                | tBANG command_call
+                    {
+                      result = @builder.not_op(val[0], nil, val[1], nil)
+                    }
+                | arg
+
+      expr_value: expr
+
+    command_call: command
+                | block_command
+
+   block_command: block_call
+                | block_call tDOT operation2 command_args
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  nil, val[3], nil)
+                    }
+                | block_call tCOLON2 operation2 command_args
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  nil, val[3], nil)
+                    }
+
+ cmd_brace_block: tLBRACE_ARG
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_param compstmt tRCURLY
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+
+         command: operation command_args =tLOWEST
+                    {
+                      result = @builder.call_method(nil, nil, val[0],
+                                  nil, val[1], nil)
+                    }
+                | operation command_args cmd_brace_block
+                    {
+                      method_call = @builder.call_method(nil, nil, val[0],
+                                        nil, val[1], nil)
+
+                      begin_t, args, body, end_t = val[2]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | primary_value tDOT operation2 command_args =tLOWEST
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  nil, val[3], nil)
+                    }
+                | primary_value tDOT operation2 command_args cmd_brace_block
+                    {
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                        nil, val[3], nil)
+
+                      begin_t, args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | primary_value tCOLON2 operation2 command_args =tLOWEST
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  nil, val[3], nil)
+                    }
+                | primary_value tCOLON2 operation2 command_args cmd_brace_block
+                    {
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                        nil, val[3], nil)
+
+                      begin_t, args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | kSUPER command_args
+                    {
+                      result = @builder.keyword_cmd(:super, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kYIELD command_args
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kRETURN call_args
+                    {
+                      result = @builder.keyword_cmd(:return, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kBREAK call_args
+                    {
+                      result = @builder.keyword_cmd(:break, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kNEXT call_args
+                    {
+                      result = @builder.keyword_cmd(:next, val[0],
+                                  nil, val[1], nil)
+                    }
+
+            mlhs: mlhs_basic
+                    {
+                      result = @builder.multi_lhs(nil, val[0], nil)
+                    }
+                | tLPAREN mlhs_inner rparen
+                    {
+                      result = @builder.begin(val[0], val[1], val[2])
+                    }
+
+      mlhs_inner: mlhs_basic
+                    {
+                      result = @builder.multi_lhs(nil, val[0], nil)
+                    }
+                | tLPAREN mlhs_inner rparen
+                    {
+                      result = @builder.multi_lhs(val[0], val[1], val[2])
+                    }
+
+      mlhs_basic: mlhs_head
+                | mlhs_head mlhs_item
+                    {
+                      result = val[0].
+                                  push(val[1])
+                    }
+                | mlhs_head tSTAR mlhs_node
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1], val[2]))
+                    }
+                | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1], val[2])).
+                                  concat(val[4])
+                    }
+                | mlhs_head tSTAR
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1]))
+                    }
+                | mlhs_head tSTAR tCOMMA mlhs_post
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1])).
+                                  concat(val[3])
+                    }
+                | tSTAR mlhs_node
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+                | tSTAR mlhs_node tCOMMA mlhs_post
+                    {
+                      result = [ @builder.splat(val[0], val[1]),
+                                 *val[3] ]
+                    }
+                | tSTAR
+                    {
+                      result = [ @builder.splat(val[0]) ]
+                    }
+                | tSTAR tCOMMA mlhs_post
+                    {
+                      result = [ @builder.splat(val[0]),
+                                 *val[2] ]
+                    }
+
+       mlhs_item: mlhs_node
+                | tLPAREN mlhs_inner rparen
+                    {
+                      result = @builder.begin(val[0], val[1], val[2])
+                    }
+
+       mlhs_head: mlhs_item tCOMMA
+                    {
+                      result = [ val[0] ]
+                    }
+                | mlhs_head mlhs_item tCOMMA
+                    {
+                      result = val[0] << val[1]
+                    }
+
+       mlhs_post: mlhs_item
+                    {
+                      result = [ val[0] ]
+                    }
+                | mlhs_post tCOMMA mlhs_item
+                    {
+                      result = val[0] << val[2]
+                    }
+
+       mlhs_node: user_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket
+                    {
+                      result = @builder.index_asgn(val[0], val[1], val[2], val[3])
+                    }
+                | primary_value tDOT tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tDOT tCONSTANT
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_fetch(val[0], val[1], val[2]))
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_global(val[0], val[1]))
+                    }
+                | backref
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+
+             lhs: user_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket
+                    {
+                      result = @builder.index_asgn(val[0], val[1], val[2], val[3])
+                    }
+                | primary_value tDOT tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tDOT tCONSTANT
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_fetch(val[0], val[1], val[2]))
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_global(val[0], val[1]))
+                    }
+                | backref
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+
+           cname: tIDENTIFIER
+                    {
+                      diagnostic :error, :module_name_const, nil, val[0]
+                    }
+                | tCONSTANT
+
+           cpath: tCOLON3 cname
+                    {
+                      result = @builder.const_global(val[0], val[1])
+                    }
+                | cname
+                    {
+                      result = @builder.const(val[0])
+                    }
+                | primary_value tCOLON2 cname
+                    {
+                      result = @builder.const_fetch(val[0], val[1], val[2])
+                    }
+
+           fname: tIDENTIFIER | tCONSTANT | tFID
+                | op
+                | reswords
+
+            fsym: fname
+                    {
+                      result = @builder.symbol(val[0])
+                    }
+                | symbol
+
+           fitem: fsym
+                | dsym
+
+      undef_list: fitem
+                    {
+                      result = [ val[0] ]
+                    }
+                | undef_list tCOMMA
+                    {
+                      @lexer.state = :expr_fname
+                    }
+                    fitem
+                    {
+                      result = val[0] << val[3]
+                    }
+
+              op:   tPIPE    | tCARET  | tAMPER2  | tCMP  | tEQ     | tEQQ
+                |   tMATCH   | tNMATCH | tGT      | tGEQ  | tLT     | tLEQ
+                |   tNEQ     | tLSHFT  | tRSHFT   | tPLUS | tMINUS  | tSTAR2
+                |   tSTAR    | tDIVIDE | tPERCENT | tPOW  | tBANG   | tTILDE
+                |   tUPLUS   | tUMINUS | tAREF    | tASET | tBACK_REF2
+
+        reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
+                | kALIAS    | kAND      | kBEGIN        | kBREAK  | kCASE
+                | kCLASS    | kDEF      | kDEFINED      | kDO     | kELSE
+                | kELSIF    | kEND      | kENSURE       | kFALSE  | kFOR
+                | kIN       | kMODULE   | kNEXT         | kNIL    | kNOT
+                | kOR       | kREDO     | kRESCUE       | kRETRY  | kRETURN
+                | kSELF     | kSUPER    | kTHEN         | kTRUE   | kUNDEF
+                | kWHEN     | kYIELD    | kIF           | kUNLESS | kWHILE
+                | kUNTIL
+
+             arg: lhs tEQL arg
+                    {
+                      result = @builder.assign(val[0], val[1], val[2])
+                    }
+                | lhs tEQL arg kRESCUE_MOD arg
+                    {
+                      rescue_body = @builder.rescue_body(val[3],
+                                        nil, nil, nil,
+                                        nil, val[4])
+
+                      rescue_ = @builder.begin_body(val[2], [ rescue_body ])
+
+                      result  = @builder.assign(val[0], val[1], rescue_)
+                    }
+                | var_lhs tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | var_lhs tOP_ASGN arg kRESCUE_MOD arg
+                    {
+                      rescue_body = @builder.rescue_body(val[3],
+                                        nil, nil, nil,
+                                        nil, val[4])
+
+                      rescue_ = @builder.begin_body(val[2], [ rescue_body ])
+
+                      result = @builder.op_assign(val[0], val[1], rescue_)
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.index(
+                                    val[0], val[1], val[2], val[3]),
+                                  val[4], val[5])
+                    }
+                | primary_value tDOT tIDENTIFIER tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tDOT tCONSTANT tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
+                    {
+                      diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ]
+                    }
+                | tCOLON3 tCONSTANT tOP_ASGN arg
+                    {
+                      diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ]
+                    }
+                | backref tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | arg tDOT2 arg
+                    {
+                      result = @builder.range_inclusive(val[0], val[1], val[2])
+                    }
+                | arg tDOT3 arg
+                    {
+                      result = @builder.range_exclusive(val[0], val[1], val[2])
+                    }
+                | arg tPLUS arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tMINUS arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tSTAR2 arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tDIVIDE arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tPERCENT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tPOW arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | tUMINUS_NUM tINTEGER tPOW arg
+                    {
+                      result = @builder.unary_op(val[0],
+                                  @builder.binary_op(
+                                    @builder.integer(val[1]),
+                                      val[2], val[3]))
+                    }
+                | tUMINUS_NUM tFLOAT tPOW arg
+                    {
+                      result = @builder.unary_op(val[0],
+                                  @builder.binary_op(
+                                    @builder.float(val[1]),
+                                      val[2], val[3]))
+                    }
+                | tUPLUS arg
+                    {
+                      result = @builder.unary_op(val[0], val[1])
+                    }
+                | tUMINUS arg
+                    {
+                      result = @builder.unary_op(val[0], val[1])
+                    }
+                | arg tPIPE arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tCARET arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tAMPER2 arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tCMP arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tGT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tGEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tLT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tLEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tEQQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tNEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tMATCH arg
+                    {
+                      result = @builder.match_op(val[0], val[1], val[2])
+                    }
+                | arg tNMATCH arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | tBANG arg
+                    {
+                      result = @builder.not_op(val[0], nil, val[1], nil)
+                    }
+                | tTILDE arg
+                    {
+                      result = @builder.unary_op(val[0], val[1])
+                    }
+                | arg tLSHFT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tRSHFT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tANDOP arg
+                    {
+                      result = @builder.logical_op(:and, val[0], val[1], val[2])
+                    }
+                | arg tOROP arg
+                    {
+                      result = @builder.logical_op(:or, val[0], val[1], val[2])
+                    }
+                | kDEFINED opt_nl arg
+                    {
+                      result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
+                    }
+
+                | arg tEH arg opt_nl tCOLON arg
+                    {
+                      result = @builder.ternary(val[0], val[1],
+                                                val[2], val[4], val[5])
+                    }
+                | primary
+
+       arg_value: arg
+
+       aref_args: none
+                | args trailer
+                | args tCOMMA assocs trailer
+                    {
+                      result = val[0] << @builder.associate(nil, val[2], nil)
+                    }
+                | assocs trailer
+                    {
+                      result = [ @builder.associate(nil, val[0], nil) ]
+                    }
+
+      paren_args: tLPAREN2 opt_call_args rparen
+                    {
+                      result = val
+                    }
+
+  opt_paren_args: # nothing
+                    {
+                      result = [ nil, [], nil ]
+                    }
+                | paren_args
+
+   opt_call_args: # nothing
+                    {
+                      result = []
+                    }
+                | call_args
+                | args tCOMMA
+                | args tCOMMA assocs tCOMMA
+                    {
+                      result = val[0] << @builder.associate(nil, val[2], nil)
+                    }
+                | assocs tCOMMA
+                    {
+                      result = [ @builder.associate(nil, val[0], nil) ]
+                    }
+
+       call_args: command
+                    {
+                      result = [ val[0] ]
+                    }
+                | args opt_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | assocs opt_block_arg
+                    {
+                      result = [ @builder.associate(nil, val[0], nil) ]
+                      result.concat(val[1])
+                    }
+                | args tCOMMA assocs opt_block_arg
+                    {
+                      assocs = @builder.associate(nil, val[2], nil)
+                      result = val[0] << assocs
+                      result.concat(val[3])
+                    }
+                | block_arg
+                    {
+                      result =  [ val[0] ]
+                    }
+
+    command_args:   {
+                      result = @lexer.cmdarg.dup
+                      @lexer.cmdarg.push(true)
+                    }
+                    call_args
+                    {
+                      @lexer.cmdarg = val[0]
+
+                      result = val[1]
+                    }
+
+       block_arg: tAMPER arg_value
+                    {
+                      result = @builder.block_pass(val[0], val[1])
+                    }
+
+   opt_block_arg: tCOMMA block_arg
+                    {
+                      result = [ val[1] ]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+            args: arg_value
+                    {
+                      result = [ val[0] ]
+                    }
+                | tSTAR arg_value
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+                | args tCOMMA arg_value
+                    {
+                      result = val[0] << val[2]
+                    }
+                | args tCOMMA tSTAR arg_value
+                    {
+                      result = val[0] << @builder.splat(val[2], val[3])
+                    }
+
+            mrhs: args tCOMMA arg_value
+                    {
+                      result = val[0] << val[2]
+                    }
+                | args tCOMMA tSTAR arg_value
+                    {
+                      result = val[0] << @builder.splat(val[2], val[3])
+                    }
+                | tSTAR arg_value
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+
+         primary: literal
+                | strings
+                | xstring
+                | regexp
+                | words
+                | qwords
+                | var_ref
+                | backref
+                | tFID
+                    {
+                      result = @builder.call_method(nil, nil, val[0])
+                    }
+                | kBEGIN bodystmt kEND
+                    {
+                      result = @builder.begin_keyword(val[0], val[1], val[2])
+                    }
+                | tLPAREN_ARG
+                    {
+                      result = @lexer.cmdarg.dup
+                      @lexer.cmdarg.clear
+                    }
+                    expr
+                    {
+                      @lexer.state = :expr_endarg
+                    }
+                    opt_nl tRPAREN
+                    {
+                      @lexer.cmdarg = val[1]
+
+                      result = @builder.begin(val[0], val[2], val[5])
+                    }
+                | tLPAREN compstmt tRPAREN
+                    {
+                      result = @builder.begin(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      result = @builder.const_fetch(val[0], val[1], val[2])
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      result = @builder.const_global(val[0], val[1])
+                    }
+                | tLBRACK aref_args tRBRACK
+                    {
+                      result = @builder.array(val[0], val[1], val[2])
+                    }
+                | tLBRACE assoc_list tRCURLY
+                    {
+                      result = @builder.associate(val[0], val[1], val[2])
+                    }
+                | kRETURN
+                    {
+                      result = @builder.keyword_cmd(:return, val[0])
+                    }
+                | kYIELD tLPAREN2 call_args rparen
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
+                    }
+                | kYIELD tLPAREN2 rparen
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
+                    }
+                | kYIELD
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0])
+                    }
+                | kDEFINED opt_nl tLPAREN2 expr rparen
+                    {
+                      result = @builder.keyword_cmd(:defined?, val[0],
+                                                    val[2], [ val[3] ], val[4])
+                    }
+                | kNOT tLPAREN2 expr rparen
+                    {
+                      result = @builder.not_op(val[0], val[1], val[2], val[3])
+                    }
+                | kNOT tLPAREN2 rparen
+                    {
+                      result = @builder.not_op(val[0], val[1], nil, val[2])
+                    }
+                | operation brace_block
+                    {
+                      method_call = @builder.call_method(nil, nil, val[0])
+
+                      begin_t, args, body, end_t = val[1]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | method_call
+                | method_call brace_block
+                    {
+                      begin_t, args, body, end_t = val[1]
+                      result      = @builder.block(val[0],
+                                      begin_t, args, body, end_t)
+                    }
+                | tLAMBDA lambda
+                    {
+                      lambda_call = @builder.call_lambda(val[0])
+
+                      args, (begin_t, body, end_t) = val[1]
+                      result      = @builder.block(lambda_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | kIF expr_value then compstmt if_tail kEND
+                    {
+                      else_t, else_ = val[4]
+                      result = @builder.condition(val[0], val[1], val[2],
+                                                  val[3], else_t,
+                                                  else_,  val[5])
+                    }
+                | kUNLESS expr_value then compstmt opt_else kEND
+                    {
+                      else_t, else_ = val[4]
+                      result = @builder.condition(val[0], val[1], val[2],
+                                                  else_,  else_t,
+                                                  val[3], val[5])
+                    }
+                | kWHILE
+                    {
+                      @lexer.cond.push(true)
+                    }
+                    expr_value do
+                    {
+                      @lexer.cond.pop
+                    }
+                    compstmt kEND
+                    {
+                      result = @builder.loop(:while, val[0], val[2], val[3],
+                                             val[5], val[6])
+                    }
+                | kUNTIL
+                    {
+                      @lexer.cond.push(true)
+                    }
+                    expr_value do
+                    {
+                      @lexer.cond.pop
+                    }
+                    compstmt kEND
+                    {
+                      result = @builder.loop(:until, val[0], val[2], val[3],
+                                             val[5], val[6])
+                    }
+                | kCASE expr_value opt_terms case_body kEND
+                    {
+                      *when_bodies, (else_t, else_body) = *val[3]
+
+                      result = @builder.case(val[0], val[1],
+                                             when_bodies, else_t, else_body,
+                                             val[4])
+                    }
+                | kCASE            opt_terms case_body kEND
+                    {
+                      *when_bodies, (else_t, else_body) = *val[2]
+
+                      result = @builder.case(val[0], nil,
+                                             when_bodies, else_t, else_body,
+                                             val[3])
+                    }
+                | kFOR for_var kIN
+                    {
+                      @lexer.cond.push(true)
+                    }
+                    expr_value do
+                    {
+                      @lexer.cond.pop
+                    }
+                    compstmt kEND
+                    {
+                      result = @builder.for(val[0], val[1],
+                                            val[2], val[4],
+                                            val[5], val[7], val[8])
+                    }
+                | kCLASS cpath superclass
+                    {
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    bodystmt kEND
+                    {
+                      if in_def?
+                        diagnostic :error, :class_in_def, nil, val[0]
+                      end
+
+                      lt_t, superclass = val[2]
+                      result = @builder.def_class(val[0], val[1],
+                                                  lt_t, superclass,
+                                                  val[4], val[5])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                    }
+                | kCLASS tLSHFT expr term
+                    {
+                      result = @def_level
+                      @def_level = 0
+
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    bodystmt kEND
+                    {
+                      result = @builder.def_sclass(val[0], val[1], val[2],
+                                                   val[5], val[6])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+
+                      @def_level = val[4]
+                    }
+                | kMODULE cpath
+                    {
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    bodystmt kEND
+                    {
+                      if in_def?
+                        diagnostic :error, :module_in_def, nil, val[0]
+                      end
+
+                      result = @builder.def_module(val[0], val[1],
+                                                   val[3], val[4])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                    }
+                | kDEF fname
+                    {
+                      @def_level += 1
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    f_arglist bodystmt kEND
+                    {
+                      result = @builder.def_method(val[0], val[1],
+                                  val[3], val[4], val[5])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                      @def_level -= 1
+                    }
+                | kDEF singleton dot_or_colon
+                    {
+                      @lexer.state = :expr_fname
+                    }
+                    fname
+                    {
+                      @def_level += 1
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    f_arglist bodystmt kEND
+                    {
+                      result = @builder.def_singleton(val[0], val[1], val[2],
+                                  val[4], val[6], val[7], val[8])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                      @def_level -= 1
+                    }
+                | kBREAK
+                    {
+                      result = @builder.keyword_cmd(:break, val[0])
+                    }
+                | kNEXT
+                    {
+                      result = @builder.keyword_cmd(:next, val[0])
+                    }
+                | kREDO
+                    {
+                      result = @builder.keyword_cmd(:redo, val[0])
+                    }
+                | kRETRY
+                    {
+                      result = @builder.keyword_cmd(:retry, val[0])
+                    }
+
+   primary_value: primary
+
+            then: term
+                | kTHEN
+                | term kTHEN
+                    {
+                      result = val[1]
+                    }
+
+              do: term
+                | kDO_COND
+
+         if_tail: opt_else
+                | kELSIF expr_value then compstmt if_tail
+                    {
+                      else_t, else_ = val[4]
+                      result = [ val[0],
+                                 @builder.condition(val[0], val[1], val[2],
+                                                    val[3], else_t,
+                                                    else_,  nil),
+                               ]
+                    }
+
+        opt_else: none
+                | kELSE compstmt
+                    {
+                      result = val
+                    }
+
+         for_var: lhs
+                | mlhs
+
+          f_marg: f_norm_arg
+                    {
+                      @static_env.declare val[0][0]
+
+                      result = @builder.arg(val[0])
+                    }
+                | tLPAREN f_margs rparen
+                    {
+                      result = @builder.multi_lhs(val[0], val[1], val[2])
+                    }
+
+     f_marg_list: f_marg
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_marg_list tCOMMA f_marg
+                    {
+                      result = val[0] << val[2]
+                    }
+
+         f_margs: f_marg_list
+                | f_marg_list tCOMMA tSTAR f_norm_arg
+                    {
+                      @static_env.declare val[3][0]
+
+                      result = val[0].
+                                  push(@builder.restarg(val[2], val[3]))
+                    }
+                | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
+                    {
+                      @static_env.declare val[3][0]
+
+                      result = val[0].
+                                  push(@builder.restarg(val[2], val[3])).
+                                  concat(val[5])
+                    }
+                | f_marg_list tCOMMA tSTAR
+                    {
+                      result = val[0].
+                                  push(@builder.restarg(val[2]))
+                    }
+                | f_marg_list tCOMMA tSTAR            tCOMMA f_marg_list
+                    {
+                      result = val[0].
+                                  push(@builder.restarg(val[2])).
+                                  concat(val[4])
+                    }
+                |                    tSTAR f_norm_arg
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = [ @builder.restarg(val[0], val[1]) ]
+                    }
+                |                    tSTAR f_norm_arg tCOMMA f_marg_list
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = [ @builder.restarg(val[0], val[1]),
+                                 *val[3] ]
+                    }
+                |                    tSTAR
+                    {
+                      result = [ @builder.restarg(val[0]) ]
+                    }
+                |                    tSTAR tCOMMA f_marg_list
+                    {
+                      result = [ @builder.restarg(val[0]),
+                                 *val[2] ]
+                    }
+
+     block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg              opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[6]).
+                                  concat(val[7])
+                    }
+                | f_arg tCOMMA f_block_optarg                                opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA f_block_optarg tCOMMA                   f_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA                       f_rest_arg              opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA
+                | f_arg tCOMMA                       f_rest_arg tCOMMA f_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg                                                      opt_f_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_block_optarg tCOMMA f_rest_arg              opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_block_optarg                                opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                | f_block_optarg tCOMMA                   f_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                       f_rest_arg              opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |                       f_rest_arg tCOMMA f_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                                                   f_block_arg
+                    {
+                      result = [ val[0] ]
+                    }
+
+ opt_block_param: # nothing
+                    {
+                      result = @builder.args(nil, [], nil)
+                    }
+                | block_param_def
+                    {
+                      @lexer.state = :expr_value
+                    }
+
+ block_param_def: tPIPE opt_bv_decl tPIPE
+                    {
+                      result = @builder.args(val[0], val[1], val[2])
+                    }
+                | tOROP
+                    {
+                      result = @builder.args(val[0], [], val[0])
+                    }
+                | tPIPE block_param opt_bv_decl tPIPE
+                    {
+                      result = @builder.args(val[0], val[1].concat(val[2]), val[3])
+                    }
+
+     opt_bv_decl: # nothing
+                    {
+                      result = []
+                    }
+                | tSEMI bv_decls
+                    {
+                      result = val[1]
+                    }
+
+        bv_decls: bvar
+                    {
+                      result = [ val[0] ]
+                    }
+                | bv_decls tCOMMA bvar
+                    {
+                      result = val[0] << val[2]
+                    }
+
+            bvar: tIDENTIFIER
+                    {
+                      result = @builder.shadowarg(val[0])
+                    }
+                | f_bad_arg
+
+          lambda:   {
+                      @static_env.extend_dynamic
+                    }
+                  f_larglist lambda_body
+                    {
+                      result = [ val[1], val[2] ]
+
+                      @static_env.unextend
+                    }
+
+     f_larglist: tLPAREN2 f_args opt_bv_decl rparen
+                    {
+                      result = @builder.args(val[0], val[1].concat(val[2]), val[3])
+                    }
+                | f_args
+                    {
+                      result = @builder.args(nil, val[0], nil)
+                    }
+
+     lambda_body: tLAMBEG compstmt tRCURLY
+                    {
+                      result = [ val[0], val[1], val[2] ]
+                    }
+                | kDO_LAMBDA compstmt kEND
+                    {
+                      result = [ val[0], val[1], val[2] ]
+                    }
+
+        do_block: kDO_BLOCK
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_param compstmt kEND
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+
+      block_call: command do_block
+                    {
+                      begin_t, block_args, body, end_t = val[1]
+                      result      = @builder.block(val[0],
+                                      begin_t, block_args, body, end_t)
+                    }
+                | block_call tDOT operation2 opt_paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | block_call tCOLON2 operation2 opt_paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+
+     method_call: operation paren_args
+                    {
+                      lparen_t, args, rparen_t = val[1]
+                      result = @builder.call_method(nil, nil, val[0],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tDOT operation2 opt_paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tCOLON2 operation2 paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tCOLON2 operation3
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2])
+                    }
+                | primary_value tDOT paren_args
+                    {
+                      lparen_t, args, rparen_t = val[2]
+                      result = @builder.call_method(val[0], val[1], nil,
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tCOLON2 paren_args
+                    {
+                      lparen_t, args, rparen_t = val[2]
+                      result = @builder.call_method(val[0], val[1], nil,
+                                  lparen_t, args, rparen_t)
+                    }
+                | kSUPER paren_args
+                    {
+                      lparen_t, args, rparen_t = val[1]
+                      result = @builder.keyword_cmd(:super, val[0],
+                                  lparen_t, args, rparen_t)
+                    }
+                | kSUPER
+                    {
+                      result = @builder.keyword_cmd(:zsuper, val[0])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket
+                    {
+                      result = @builder.index(val[0], val[1], val[2], val[3])
+                    }
+
+     brace_block: tLCURLY
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_param compstmt tRCURLY
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+                | kDO
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_param compstmt kEND
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+
+       case_body: kWHEN args then compstmt cases
+                    {
+                      result = [ @builder.when(val[0], val[1], val[2], val[3]),
+                                 *val[4] ]
+                    }
+
+           cases: opt_else
+                    {
+                      result = [ val[0] ]
+                    }
+                | case_body
+
+      opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
+                    {
+                      assoc_t, exc_var = val[2]
+
+                      if val[1]
+                        exc_list = @builder.array(nil, val[1], nil)
+                      end
+
+                      result = [ @builder.rescue_body(val[0],
+                                      exc_list, assoc_t, exc_var,
+                                      val[3], val[4]),
+                                 *val[5] ]
+                    }
+                |
+                    {
+                      result = []
+                    }
+
+        exc_list: arg_value
+                    {
+                      result = [ val[0] ]
+                    }
+                | mrhs
+                | none
+
+         exc_var: tASSOC lhs
+                    {
+                      result = [ val[0], val[1] ]
+                    }
+                | none
+
+      opt_ensure: kENSURE compstmt
+                    {
+                      result = [ val[0], val[1] ]
+                    }
+                | none
+
+         literal: numeric
+                | symbol
+                | dsym
+
+         strings: string
+                    {
+                      result = @builder.string_compose(nil, val[0], nil)
+                    }
+
+          string: string1
+                    {
+                      result = [ val[0] ]
+                    }
+                | string string1
+                    {
+                      result = val[0] << val[1]
+                    }
+
+         string1: tSTRING_BEG string_contents tSTRING_END
+                    {
+                      result = @builder.string_compose(val[0], val[1], val[2])
+                    }
+                | tSTRING
+                    {
+                      result = @builder.string(val[0])
+                    }
+                | tCHARACTER
+                    {
+                      result = @builder.character(val[0])
+                    }
+
+         xstring: tXSTRING_BEG xstring_contents tSTRING_END
+                    {
+                      result = @builder.xstring_compose(val[0], val[1], val[2])
+                    }
+
+          regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT
+                    {
+                      opts   = @builder.regexp_options(val[3])
+                      result = @builder.regexp_compose(val[0], val[1], val[2], opts)
+                    }
+
+           words: tWORDS_BEG word_list tSTRING_END
+                    {
+                      result = @builder.words_compose(val[0], val[1], val[2])
+                    }
+
+       word_list: # nothing
+                    {
+                      result = []
+                    }
+                | word_list word tSPACE
+                    {
+                      result = val[0] << @builder.word(val[1])
+                    }
+
+            word: string_content
+                    {
+                      result = [ val[0] ]
+                    }
+                | word string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+          qwords: tQWORDS_BEG qword_list tSTRING_END
+                    {
+                      result = @builder.words_compose(val[0], val[1], val[2])
+                    }
+
+      qword_list: # nothing
+                    {
+                      result = []
+                    }
+                | qword_list tSTRING_CONTENT tSPACE
+                    {
+                      result = val[0] << @builder.string_internal(val[1])
+                    }
+
+ string_contents: # nothing
+                    {
+                      result = []
+                    }
+                | string_contents string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+xstring_contents: # nothing
+                    {
+                      result = []
+                    }
+                | xstring_contents string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+regexp_contents: # nothing
+                    {
+                      result = []
+                    }
+                | regexp_contents string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+  string_content: tSTRING_CONTENT
+                    {
+                      result = @builder.string_internal(val[0])
+                    }
+                | tSTRING_DVAR string_dvar
+                    {
+                      result = val[1]
+                    }
+                | tSTRING_DBEG
+                    {
+                      @lexer.cond.push(false)
+                      @lexer.cmdarg.push(false)
+                    }
+                    compstmt tRCURLY
+                    {
+                      @lexer.cond.lexpop
+                      @lexer.cmdarg.lexpop
+
+                      result = @builder.begin(val[0], val[2], val[3])
+                    }
+
+     string_dvar: tGVAR
+                    {
+                      result = @builder.gvar(val[0])
+                    }
+                | tIVAR
+                    {
+                      result = @builder.ivar(val[0])
+                    }
+                | tCVAR
+                    {
+                      result = @builder.cvar(val[0])
+                    }
+                | backref
+
+
+          symbol: tSYMBOL
+                    {
+                      result = @builder.symbol(val[0])
+                    }
+
+            dsym: tSYMBEG xstring_contents tSTRING_END
+                    {
+                      result = @builder.symbol_compose(val[0], val[1], val[2])
+                    }
+
+         numeric: tINTEGER
+                    {
+                      result = @builder.integer(val[0])
+                    }
+                | tFLOAT
+                    {
+                      result = @builder.float(val[0])
+                    }
+                | tUMINUS_NUM tINTEGER =tLOWEST
+                    {
+                      result = @builder.negate(val[0],
+                                  @builder.integer(val[1]))
+                    }
+                | tUMINUS_NUM tFLOAT   =tLOWEST
+                    {
+                      result = @builder.negate(val[0],
+                                  @builder.float(val[1]))
+                    }
+
+   user_variable: tIDENTIFIER
+                    {
+                      result = @builder.ident(val[0])
+                    }
+                | tIVAR
+                    {
+                      result = @builder.ivar(val[0])
+                    }
+                | tGVAR
+                    {
+                      result = @builder.gvar(val[0])
+                    }
+                | tCONSTANT
+                    {
+                      result = @builder.const(val[0])
+                    }
+                | tCVAR
+                    {
+                      result = @builder.cvar(val[0])
+                    }
+
+keyword_variable: kNIL
+                    {
+                      result = @builder.nil(val[0])
+                    }
+                | kSELF
+                    {
+                      result = @builder.self(val[0])
+                    }
+                | kTRUE
+                    {
+                      result = @builder.true(val[0])
+                    }
+                | kFALSE
+                    {
+                      result = @builder.false(val[0])
+                    }
+                | k__FILE__
+                    {
+                      result = @builder.__FILE__(val[0])
+                    }
+                | k__LINE__
+                    {
+                      result = @builder.__LINE__(val[0])
+                    }
+                | k__ENCODING__
+                    {
+                      result = @builder.__ENCODING__(val[0])
+                    }
+
+         var_ref: user_variable
+                    {
+                      result = @builder.accessible(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.accessible(val[0])
+                    }
+
+         var_lhs: user_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+
+         backref: tNTH_REF
+                    {
+                      result = @builder.nth_ref(val[0])
+                    }
+                | tBACK_REF
+                    {
+                      result = @builder.back_ref(val[0])
+                    }
+
+      superclass: term
+                    {
+                      result = nil
+                    }
+                | tLT expr_value term
+                    {
+                      result = [ val[0], val[1] ]
+                    }
+                | error term
+                    {
+                      yyerrok
+                      result = nil
+                    }
+
+       f_arglist: tLPAREN2 f_args rparen
+                    {
+                      result = @builder.args(val[0], val[1], val[2])
+
+                      @lexer.state = :expr_value
+                    }
+                | f_args term
+                    {
+                      result = @builder.args(nil, val[0], nil)
+                    }
+
+          f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg              opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[6]).
+                                  concat(val[7])
+                    }
+                | f_arg tCOMMA f_optarg                                opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA f_optarg tCOMMA                   f_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA                 f_rest_arg              opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA                 f_rest_arg tCOMMA f_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg                                                opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |              f_optarg tCOMMA f_rest_arg              opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |              f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                |              f_optarg                                opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |              f_optarg tCOMMA                   f_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                              f_rest_arg              opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |                              f_rest_arg tCOMMA f_arg opt_f_block_arg
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                                                          f_block_arg
+                    {
+                      result = [ val[0] ]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+       f_bad_arg: tCONSTANT
+                    {
+                      diagnostic :error, :argument_const, nil, val[0]
+                    }
+                | tIVAR
+                    {
+                      diagnostic :error, :argument_ivar, nil, val[0]
+                    }
+                | tGVAR
+                    {
+                      diagnostic :error, :argument_gvar, nil, val[0]
+                    }
+                | tCVAR
+                    {
+                      diagnostic :error, :argument_cvar, nil, val[0]
+                    }
+
+      f_norm_arg: f_bad_arg
+                | tIDENTIFIER
+
+      f_arg_item: f_norm_arg
+                    {
+                      @static_env.declare val[0][0]
+
+                      result = @builder.arg(val[0])
+                    }
+                | tLPAREN f_margs rparen
+                    {
+                      result = @builder.multi_lhs(val[0], val[1], val[2])
+                    }
+
+           f_arg: f_arg_item
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_arg tCOMMA f_arg_item
+                    {
+                      result = val[0] << val[2]
+                    }
+
+           f_opt: tIDENTIFIER tEQL arg_value
+                    {
+                      @static_env.declare val[0][0]
+
+                      result = @builder.optarg(val[0], val[1], val[2])
+                    }
+
+     f_block_opt: tIDENTIFIER tEQL primary_value
+                    {
+                      @static_env.declare val[0][0]
+
+                      result = @builder.optarg(val[0], val[1], val[2])
+                    }
+
+  f_block_optarg: f_block_opt
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_block_optarg tCOMMA f_block_opt
+                    {
+                      result = val[0] << val[2]
+                    }
+
+        f_optarg: f_opt
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_optarg tCOMMA f_opt
+                    {
+                      result = val[0] << val[2]
+                    }
+
+    restarg_mark: tSTAR2 | tSTAR
+
+      f_rest_arg: restarg_mark tIDENTIFIER
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = [ @builder.restarg(val[0], val[1]) ]
+                    }
+                | restarg_mark
+                    {
+                      result = [ @builder.restarg(val[0]) ]
+                    }
+
+     blkarg_mark: tAMPER2 | tAMPER
+
+     f_block_arg: blkarg_mark tIDENTIFIER
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = @builder.blockarg(val[0], val[1])
+                    }
+
+ opt_f_block_arg: tCOMMA f_block_arg
+                    {
+                      result = [ val[1] ]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+       singleton: var_ref
+                | tLPAREN2 expr rparen
+                    {
+                      result = val[1]
+                    }
+
+      assoc_list: # nothing
+                    {
+                      result = []
+                    }
+                | assocs trailer
+
+          assocs: assoc
+                    {
+                      result = [ val[0] ]
+                    }
+                | assocs tCOMMA assoc
+                    {
+                      result = val[0] << val[2]
+                    }
+
+           assoc: arg_value tASSOC arg_value
+                    {
+                      result = @builder.pair(val[0], val[1], val[2])
+                    }
+                | tLABEL arg_value
+                    {
+                      result = @builder.pair_keyword(val[0], val[1])
+                    }
+
+       operation: tIDENTIFIER | tCONSTANT | tFID
+      operation2: tIDENTIFIER | tCONSTANT | tFID | op
+      operation3: tIDENTIFIER | tFID | op
+    dot_or_colon: tDOT | tCOLON2
+       opt_terms:  | terms
+          opt_nl:  | tNL
+          rparen: opt_nl tRPAREN
+                    {
+                      result = val[1]
+                    }
+        rbracket: opt_nl tRBRACK
+                    {
+                      result = val[1]
+                    }
+         trailer:  | tNL | tCOMMA
+
+            term: tSEMI
+                  {
+                    yyerrok
+                  }
+                | tNL
+
+           terms: term
+                | terms tSEMI
+
+            none: # nothing
+                  {
+                    result = nil
+                  }
+end
+
+---- header
+
+require 'parser'
+
+Parser.check_for_encoding_support
+
+---- inner
+
+  def version
+    19
+  end
+
+  def default_encoding
+    Encoding::BINARY
+  end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/ruby20.y b/app/server/vendor/parser-2.2.2.1/lib/parser/ruby20.y
new file mode 100644
index 0000000..dcf9b42
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/ruby20.y
@@ -0,0 +1,2324 @@
+class Parser::Ruby20
+
+token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
+      kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
+      kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
+      kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
+      kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
+      k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
+      tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
+      tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
+      tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
+      tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
+      tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
+      tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
+      tDSTAR tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
+      tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT
+      tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DBEG
+      tSTRING_DVAR tSTRING_END tSTRING_DEND tSTRING tSYMBOL
+      tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG tCHARACTER
+
+prechigh
+  right    tBANG tTILDE tUPLUS
+  right    tPOW
+  right    tUMINUS_NUM tUMINUS
+  left     tSTAR2 tDIVIDE tPERCENT
+  left     tPLUS tMINUS
+  left     tLSHFT tRSHFT
+  left     tAMPER2
+  left     tPIPE tCARET
+  left     tGT tGEQ tLT tLEQ
+  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
+  left     tANDOP
+  left     tOROP
+  nonassoc tDOT2 tDOT3
+  right    tEH tCOLON
+  left     kRESCUE_MOD
+  right    tEQL tOP_ASGN
+  nonassoc kDEFINED
+  right    kNOT
+  left     kOR kAND
+  nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
+  nonassoc tLBRACE_ARG
+  nonassoc tLOWEST
+preclow
+
+rule
+
+         program: top_compstmt
+
+    top_compstmt: top_stmts opt_terms
+                    {
+                      result = @builder.compstmt(val[0])
+                    }
+
+       top_stmts: # nothing
+                    {
+                      result = []
+                    }
+                | top_stmt
+                    {
+                      result = [ val[0] ]
+                    }
+                | top_stmts terms top_stmt
+                    {
+                      result = val[0] << val[2]
+                    }
+                | error top_stmt
+                    {
+                      result = [ val[1] ]
+                    }
+
+        top_stmt: stmt
+                | klBEGIN tLCURLY top_compstmt tRCURLY
+                    {
+                      result = @builder.preexe(val[0], val[1], val[2], val[3])
+                    }
+
+        bodystmt: compstmt opt_rescue opt_else opt_ensure
+                    {
+                      rescue_bodies     = val[1]
+                      else_t,   else_   = val[2]
+                      ensure_t, ensure_ = val[3]
+
+                      if rescue_bodies.empty? && !else_.nil?
+                        diagnostic :warning, :useless_else, nil, else_t
+                      end
+
+                      result = @builder.begin_body(val[0],
+                                  rescue_bodies,
+                                  else_t,   else_,
+                                  ensure_t, ensure_)
+                    }
+
+        compstmt: stmts opt_terms
+                    {
+                      result = @builder.compstmt(val[0])
+                    }
+
+           stmts: # nothing
+                    {
+                      result = []
+                    }
+                | stmt_or_begin
+                    {
+                      result = [ val[0] ]
+                    }
+                | stmts terms stmt_or_begin
+                    {
+                      result = val[0] << val[2]
+                    }
+                | error stmt
+                    {
+                      result = [ val[1] ]
+                    }
+
+   stmt_or_begin: stmt
+                | klBEGIN tLCURLY top_compstmt tRCURLY
+                    {
+                      if in_def?
+                        diagnostic :error, :begin_in_method, nil, val[0]
+                      end
+
+                      result = @builder.preexe(val[0], val[1], val[2], val[3])
+                    }
+
+            stmt: kALIAS fitem
+                    {
+                      @lexer.state = :expr_fname
+                    }
+                    fitem
+                    {
+                      result = @builder.alias(val[0], val[1], val[3])
+                    }
+                | kALIAS tGVAR tGVAR
+                    {
+                      result = @builder.alias(val[0],
+                                  @builder.gvar(val[1]),
+                                  @builder.gvar(val[2]))
+                    }
+                | kALIAS tGVAR tBACK_REF
+                    {
+                      result = @builder.alias(val[0],
+                                  @builder.gvar(val[1]),
+                                  @builder.back_ref(val[2]))
+                    }
+                | kALIAS tGVAR tNTH_REF
+                    {
+                      diagnostic :error, :nth_ref_alias, nil, val[2]
+                    }
+                | kUNDEF undef_list
+                    {
+                      result = @builder.undef_method(val[0], val[1])
+                    }
+                | stmt kIF_MOD expr_value
+                    {
+                      result = @builder.condition_mod(val[0], nil,
+                                                      val[1], val[2])
+                    }
+                | stmt kUNLESS_MOD expr_value
+                    {
+                      result = @builder.condition_mod(nil, val[0],
+                                                      val[1], val[2])
+                    }
+                | stmt kWHILE_MOD expr_value
+                    {
+                      result = @builder.loop_mod(:while, val[0], val[1], val[2])
+                    }
+                | stmt kUNTIL_MOD expr_value
+                    {
+                      result = @builder.loop_mod(:until, val[0], val[1], val[2])
+                    }
+                | stmt kRESCUE_MOD stmt
+                    {
+                      rescue_body = @builder.rescue_body(val[1],
+                                        nil, nil, nil,
+                                        nil, val[2])
+
+                      result = @builder.begin_body(val[0], [ rescue_body ])
+                    }
+                | klEND tLCURLY compstmt tRCURLY
+                    {
+                      result = @builder.postexe(val[0], val[1], val[2], val[3])
+                    }
+                | command_asgn
+                | mlhs tEQL command_call
+                    {
+                      result = @builder.multi_assign(val[0], val[1], val[2])
+                    }
+                | var_lhs tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.index(
+                                    val[0], val[1], val[2], val[3]),
+                                  val[4], val[5])
+                    }
+                | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tDOT tCONSTANT tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | backref tOP_ASGN command_call
+                    {
+                      @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | lhs tEQL mrhs
+                    {
+                      result = @builder.assign(val[0], val[1],
+                                  @builder.array(nil, val[2], nil))
+                    }
+                | mlhs tEQL arg_value
+                    {
+                      result = @builder.multi_assign(val[0], val[1], val[2])
+                    }
+                | mlhs tEQL mrhs
+                    {
+                      result = @builder.multi_assign(val[0], val[1],
+                                  @builder.array(nil, val[2], nil))
+                    }
+                | expr
+
+    command_asgn: lhs tEQL command_call
+                    {
+                      result = @builder.assign(val[0], val[1], val[2])
+                    }
+                | lhs tEQL command_asgn
+                    {
+                      result = @builder.assign(val[0], val[1], val[2])
+                    }
+
+            expr: command_call
+                | expr kAND expr
+                    {
+                      result = @builder.logical_op(:and, val[0], val[1], val[2])
+                    }
+                | expr kOR expr
+                    {
+                      result = @builder.logical_op(:or, val[0], val[1], val[2])
+                    }
+                | kNOT opt_nl expr
+                    {
+                      result = @builder.not_op(val[0], nil, val[2], nil)
+                    }
+                | tBANG command_call
+                    {
+                      result = @builder.not_op(val[0], nil, val[1], nil)
+                    }
+                | arg
+
+      expr_value: expr
+
+    command_call: command
+                | block_command
+
+   block_command: block_call
+                | block_call dot_or_colon operation2 command_args
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  nil, val[3], nil)
+                    }
+
+ cmd_brace_block: tLBRACE_ARG
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_param compstmt tRCURLY
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+
+           fcall: operation
+
+         command: fcall command_args =tLOWEST
+                    {
+                      result = @builder.call_method(nil, nil, val[0],
+                                  nil, val[1], nil)
+                    }
+                | fcall command_args cmd_brace_block
+                    {
+                      method_call = @builder.call_method(nil, nil, val[0],
+                                        nil, val[1], nil)
+
+                      begin_t, args, body, end_t = val[2]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | primary_value tDOT operation2 command_args =tLOWEST
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  nil, val[3], nil)
+                    }
+                | primary_value tDOT operation2 command_args cmd_brace_block
+                    {
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                        nil, val[3], nil)
+
+                      begin_t, args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | primary_value tCOLON2 operation2 command_args =tLOWEST
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  nil, val[3], nil)
+                    }
+                | primary_value tCOLON2 operation2 command_args cmd_brace_block
+                    {
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                        nil, val[3], nil)
+
+                      begin_t, args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | kSUPER command_args
+                    {
+                      result = @builder.keyword_cmd(:super, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kYIELD command_args
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kRETURN call_args
+                    {
+                      result = @builder.keyword_cmd(:return, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kBREAK call_args
+                    {
+                      result = @builder.keyword_cmd(:break, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kNEXT call_args
+                    {
+                      result = @builder.keyword_cmd(:next, val[0],
+                                  nil, val[1], nil)
+                    }
+
+            mlhs: mlhs_basic
+                    {
+                      result = @builder.multi_lhs(nil, val[0], nil)
+                    }
+                | tLPAREN mlhs_inner rparen
+                    {
+                      result = @builder.begin(val[0], val[1], val[2])
+                    }
+
+      mlhs_inner: mlhs_basic
+                    {
+                      result = @builder.multi_lhs(nil, val[0], nil)
+                    }
+                | tLPAREN mlhs_inner rparen
+                    {
+                      result = @builder.multi_lhs(val[0], val[1], val[2])
+                    }
+
+      mlhs_basic: mlhs_head
+                | mlhs_head mlhs_item
+                    {
+                      result = val[0].
+                                  push(val[1])
+                    }
+                | mlhs_head tSTAR mlhs_node
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1], val[2]))
+                    }
+                | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1], val[2])).
+                                  concat(val[4])
+                    }
+                | mlhs_head tSTAR
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1]))
+                    }
+                | mlhs_head tSTAR tCOMMA mlhs_post
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1])).
+                                  concat(val[3])
+                    }
+                | tSTAR mlhs_node
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+                | tSTAR mlhs_node tCOMMA mlhs_post
+                    {
+                      result = [ @builder.splat(val[0], val[1]),
+                                 *val[3] ]
+                    }
+                | tSTAR
+                    {
+                      result = [ @builder.splat(val[0]) ]
+                    }
+                | tSTAR tCOMMA mlhs_post
+                    {
+                      result = [ @builder.splat(val[0]),
+                                 *val[2] ]
+                    }
+
+       mlhs_item: mlhs_node
+                | tLPAREN mlhs_inner rparen
+                    {
+                      result = @builder.begin(val[0], val[1], val[2])
+                    }
+
+       mlhs_head: mlhs_item tCOMMA
+                    {
+                      result = [ val[0] ]
+                    }
+                | mlhs_head mlhs_item tCOMMA
+                    {
+                      result = val[0] << val[1]
+                    }
+
+       mlhs_post: mlhs_item
+                    {
+                      result = [ val[0] ]
+                    }
+                | mlhs_post tCOMMA mlhs_item
+                    {
+                      result = val[0] << val[2]
+                    }
+
+       mlhs_node: user_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket
+                    {
+                      result = @builder.index_asgn(val[0], val[1], val[2], val[3])
+                    }
+                | primary_value tDOT tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tDOT tCONSTANT
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_fetch(val[0], val[1], val[2]))
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_global(val[0], val[1]))
+                    }
+                | backref
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+
+             lhs: user_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket
+                    {
+                      result = @builder.index_asgn(val[0], val[1], val[2], val[3])
+                    }
+                | primary_value tDOT tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tDOT tCONSTANT
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_fetch(val[0], val[1], val[2]))
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_global(val[0], val[1]))
+                    }
+                | backref
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+
+           cname: tIDENTIFIER
+                    {
+                      diagnostic :error, :module_name_const, nil, val[0]
+                    }
+                | tCONSTANT
+
+           cpath: tCOLON3 cname
+                    {
+                      result = @builder.const_global(val[0], val[1])
+                    }
+                | cname
+                    {
+                      result = @builder.const(val[0])
+                    }
+                | primary_value tCOLON2 cname
+                    {
+                      result = @builder.const_fetch(val[0], val[1], val[2])
+                    }
+
+           fname: tIDENTIFIER | tCONSTANT | tFID
+                | op
+                | reswords
+
+            fsym: fname
+                    {
+                      result = @builder.symbol(val[0])
+                    }
+                | symbol
+
+           fitem: fsym
+                | dsym
+
+      undef_list: fitem
+                    {
+                      result = [ val[0] ]
+                    }
+                | undef_list tCOMMA
+                    {
+                      @lexer.state = :expr_fname
+                    }
+                    fitem
+                    {
+                      result = val[0] << val[3]
+                    }
+
+              op:   tPIPE    | tCARET  | tAMPER2  | tCMP  | tEQ     | tEQQ
+                |   tMATCH   | tNMATCH | tGT      | tGEQ  | tLT     | tLEQ
+                |   tNEQ     | tLSHFT  | tRSHFT   | tPLUS | tMINUS  | tSTAR2
+                |   tSTAR    | tDIVIDE | tPERCENT | tPOW  | tBANG   | tTILDE
+                |   tUPLUS   | tUMINUS | tAREF    | tASET | tDSTAR  | tBACK_REF2
+
+        reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
+                | kALIAS    | kAND      | kBEGIN        | kBREAK  | kCASE
+                | kCLASS    | kDEF      | kDEFINED      | kDO     | kELSE
+                | kELSIF    | kEND      | kENSURE       | kFALSE  | kFOR
+                | kIN       | kMODULE   | kNEXT         | kNIL    | kNOT
+                | kOR       | kREDO     | kRESCUE       | kRETRY  | kRETURN
+                | kSELF     | kSUPER    | kTHEN         | kTRUE   | kUNDEF
+                | kWHEN     | kYIELD    | kIF           | kUNLESS | kWHILE
+                | kUNTIL
+
+             arg: lhs tEQL arg
+                    {
+                      result = @builder.assign(val[0], val[1], val[2])
+                    }
+                | lhs tEQL arg kRESCUE_MOD arg
+                    {
+                      rescue_body = @builder.rescue_body(val[3],
+                                        nil, nil, nil,
+                                        nil, val[4])
+
+                      rescue_ = @builder.begin_body(val[2], [ rescue_body ])
+
+                      result  = @builder.assign(val[0], val[1], rescue_)
+                    }
+                | var_lhs tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | var_lhs tOP_ASGN arg kRESCUE_MOD arg
+                    {
+                      rescue_body = @builder.rescue_body(val[3],
+                                        nil, nil, nil,
+                                        nil, val[4])
+
+                      rescue_ = @builder.begin_body(val[2], [ rescue_body ])
+
+                      result = @builder.op_assign(val[0], val[1], rescue_)
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.index(
+                                    val[0], val[1], val[2], val[3]),
+                                  val[4], val[5])
+                    }
+                | primary_value tDOT tIDENTIFIER tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tDOT tCONSTANT tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
+                    {
+                      const  = @builder.const_op_assignable(
+                                  @builder.const_fetch(val[0], val[1], val[2]))
+                      result = @builder.op_assign(const, val[3], val[4])
+                    }
+                | tCOLON3 tCONSTANT tOP_ASGN arg
+                    {
+                      const  = @builder.const_op_assignable(
+                                  @builder.const_global(val[0], val[1]))
+                      result = @builder.op_assign(const, val[2], val[3])
+                    }
+                | backref tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | arg tDOT2 arg
+                    {
+                      result = @builder.range_inclusive(val[0], val[1], val[2])
+                    }
+                | arg tDOT3 arg
+                    {
+                      result = @builder.range_exclusive(val[0], val[1], val[2])
+                    }
+                | arg tPLUS arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tMINUS arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tSTAR2 arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tDIVIDE arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tPERCENT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tPOW arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | tUMINUS_NUM tINTEGER tPOW arg
+                    {
+                      result = @builder.unary_op(val[0],
+                                  @builder.binary_op(
+                                    @builder.integer(val[1]),
+                                      val[2], val[3]))
+                    }
+                | tUMINUS_NUM tFLOAT tPOW arg
+                    {
+                      result = @builder.unary_op(val[0],
+                                  @builder.binary_op(
+                                    @builder.float(val[1]),
+                                      val[2], val[3]))
+                    }
+                | tUPLUS arg
+                    {
+                      result = @builder.unary_op(val[0], val[1])
+                    }
+                | tUMINUS arg
+                    {
+                      result = @builder.unary_op(val[0], val[1])
+                    }
+                | arg tPIPE arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tCARET arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tAMPER2 arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tCMP arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tGT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tGEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tLT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tLEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tEQQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tNEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tMATCH arg
+                    {
+                      result = @builder.match_op(val[0], val[1], val[2])
+                    }
+                | arg tNMATCH arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | tBANG arg
+                    {
+                      result = @builder.not_op(val[0], nil, val[1], nil)
+                    }
+                | tTILDE arg
+                    {
+                      result = @builder.unary_op(val[0], val[1])
+                    }
+                | arg tLSHFT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tRSHFT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tANDOP arg
+                    {
+                      result = @builder.logical_op(:and, val[0], val[1], val[2])
+                    }
+                | arg tOROP arg
+                    {
+                      result = @builder.logical_op(:or, val[0], val[1], val[2])
+                    }
+                | kDEFINED opt_nl arg
+                    {
+                      result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
+                    }
+
+                | arg tEH arg opt_nl tCOLON arg
+                    {
+                      result = @builder.ternary(val[0], val[1],
+                                                val[2], val[4], val[5])
+                    }
+                | primary
+
+       arg_value: arg
+
+       aref_args: none
+                | args trailer
+                | args tCOMMA assocs trailer
+                    {
+                      result = val[0] << @builder.associate(nil, val[2], nil)
+                    }
+                | assocs trailer
+                    {
+                      result = [ @builder.associate(nil, val[0], nil) ]
+                    }
+
+      paren_args: tLPAREN2 opt_call_args rparen
+                    {
+                      result = val
+                    }
+
+  opt_paren_args: # nothing
+                    {
+                      result = [ nil, [], nil ]
+                    }
+                | paren_args
+
+   opt_call_args: # nothing
+                    {
+                      result = []
+                    }
+                | call_args
+                | args tCOMMA
+                | args tCOMMA assocs tCOMMA
+                    {
+                      result = val[0] << @builder.associate(nil, val[2], nil)
+                    }
+                | assocs tCOMMA
+                    {
+                      result = [ @builder.associate(nil, val[0], nil) ]
+                    }
+
+       call_args: command
+                    {
+                      result = [ val[0] ]
+                    }
+                | args opt_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | assocs opt_block_arg
+                    {
+                      result = [ @builder.associate(nil, val[0], nil) ]
+                      result.concat(val[1])
+                    }
+                | args tCOMMA assocs opt_block_arg
+                    {
+                      assocs = @builder.associate(nil, val[2], nil)
+                      result = val[0] << assocs
+                      result.concat(val[3])
+                    }
+                | block_arg
+                    {
+                      result =  [ val[0] ]
+                    }
+
+    command_args:   {
+                      result = @lexer.cmdarg.dup
+                      @lexer.cmdarg.push(true)
+                    }
+                  call_args
+                    {
+                      @lexer.cmdarg = val[0]
+
+                      result = val[1]
+                    }
+
+       block_arg: tAMPER arg_value
+                    {
+                      result = @builder.block_pass(val[0], val[1])
+                    }
+
+   opt_block_arg: tCOMMA block_arg
+                    {
+                      result = [ val[1] ]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+            args: arg_value
+                    {
+                      result = [ val[0] ]
+                    }
+                | tSTAR arg_value
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+                | args tCOMMA arg_value
+                    {
+                      result = val[0] << val[2]
+                    }
+                | args tCOMMA tSTAR arg_value
+                    {
+                      result = val[0] << @builder.splat(val[2], val[3])
+                    }
+
+            mrhs: args tCOMMA arg_value
+                    {
+                      result = val[0] << val[2]
+                    }
+                | args tCOMMA tSTAR arg_value
+                    {
+                      result = val[0] << @builder.splat(val[2], val[3])
+                    }
+                | tSTAR arg_value
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+
+         primary: literal
+                | strings
+                | xstring
+                | regexp
+                | words
+                | qwords
+                | symbols
+                | qsymbols
+                | var_ref
+                | backref
+                | tFID
+                    {
+                      result = @builder.call_method(nil, nil, val[0])
+                    }
+                | kBEGIN
+                    {
+                      result = @lexer.cmdarg.dup
+                      @lexer.cmdarg.clear
+                    }
+                    bodystmt kEND
+                    {
+                      @lexer.cmdarg = val[1]
+
+                      result = @builder.begin_keyword(val[0], val[2], val[3])
+                    }
+                | tLPAREN_ARG
+                    {
+                      result = @lexer.cmdarg.dup
+                      @lexer.cmdarg.clear
+                    }
+                    expr
+                    {
+                      @lexer.state = :expr_endarg
+                    }
+                    opt_nl tRPAREN
+                    {
+                      @lexer.cmdarg = val[1]
+
+                      result = @builder.begin(val[0], val[2], val[5])
+                    }
+                | tLPAREN_ARG
+                    {
+                      @lexer.state = :expr_endarg
+                    }
+                    opt_nl tRPAREN
+                    {
+                      result = @builder.begin(val[0], nil, val[3])
+                    }
+                | tLPAREN compstmt tRPAREN
+                    {
+                      result = @builder.begin(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      result = @builder.const_fetch(val[0], val[1], val[2])
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      result = @builder.const_global(val[0], val[1])
+                    }
+                | tLBRACK aref_args tRBRACK
+                    {
+                      result = @builder.array(val[0], val[1], val[2])
+                    }
+                | tLBRACE assoc_list tRCURLY
+                    {
+                      result = @builder.associate(val[0], val[1], val[2])
+                    }
+                | kRETURN
+                    {
+                      result = @builder.keyword_cmd(:return, val[0])
+                    }
+                | kYIELD tLPAREN2 call_args rparen
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
+                    }
+                | kYIELD tLPAREN2 rparen
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
+                    }
+                | kYIELD
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0])
+                    }
+                | kDEFINED opt_nl tLPAREN2 expr rparen
+                    {
+                      result = @builder.keyword_cmd(:defined?, val[0],
+                                                    val[2], [ val[3] ], val[4])
+                    }
+                | kNOT tLPAREN2 expr rparen
+                    {
+                      result = @builder.not_op(val[0], val[1], val[2], val[3])
+                    }
+                | kNOT tLPAREN2 rparen
+                    {
+                      result = @builder.not_op(val[0], val[1], nil, val[2])
+                    }
+                | fcall brace_block
+                    {
+                      method_call = @builder.call_method(nil, nil, val[0])
+
+                      begin_t, args, body, end_t = val[1]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | method_call
+                | method_call brace_block
+                    {
+                      begin_t, args, body, end_t = val[1]
+                      result      = @builder.block(val[0],
+                                      begin_t, args, body, end_t)
+                    }
+                | tLAMBDA lambda
+                    {
+                      lambda_call = @builder.call_lambda(val[0])
+
+                      args, (begin_t, body, end_t) = val[1]
+                      result      = @builder.block(lambda_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | kIF expr_value then compstmt if_tail kEND
+                    {
+                      else_t, else_ = val[4]
+                      result = @builder.condition(val[0], val[1], val[2],
+                                                  val[3], else_t,
+                                                  else_,  val[5])
+                    }
+                | kUNLESS expr_value then compstmt opt_else kEND
+                    {
+                      else_t, else_ = val[4]
+                      result = @builder.condition(val[0], val[1], val[2],
+                                                  else_,  else_t,
+                                                  val[3], val[5])
+                    }
+                | kWHILE
+                    {
+                      @lexer.cond.push(true)
+                    }
+                    expr_value do
+                    {
+                      @lexer.cond.pop
+                    }
+                    compstmt kEND
+                    {
+                      result = @builder.loop(:while, val[0], val[2], val[3],
+                                             val[5], val[6])
+                    }
+                | kUNTIL
+                    {
+                      @lexer.cond.push(true)
+                    }
+                    expr_value do
+                    {
+                      @lexer.cond.pop
+                    }
+                    compstmt kEND
+                    {
+                      result = @builder.loop(:until, val[0], val[2], val[3],
+                                             val[5], val[6])
+                    }
+                | kCASE expr_value opt_terms case_body kEND
+                    {
+                      *when_bodies, (else_t, else_body) = *val[3]
+
+                      result = @builder.case(val[0], val[1],
+                                             when_bodies, else_t, else_body,
+                                             val[4])
+                    }
+                | kCASE            opt_terms case_body kEND
+                    {
+                      *when_bodies, (else_t, else_body) = *val[2]
+
+                      result = @builder.case(val[0], nil,
+                                             when_bodies, else_t, else_body,
+                                             val[3])
+                    }
+                | kFOR for_var kIN
+                    {
+                      @lexer.cond.push(true)
+                    }
+                    expr_value do
+                    {
+                      @lexer.cond.pop
+                    }
+                    compstmt kEND
+                    {
+                      result = @builder.for(val[0], val[1],
+                                            val[2], val[4],
+                                            val[5], val[7], val[8])
+                    }
+                | kCLASS cpath superclass
+                    {
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    bodystmt kEND
+                    {
+                      if in_def?
+                        diagnostic :error, :class_in_def, nil, val[0]
+                      end
+
+                      lt_t, superclass = val[2]
+                      result = @builder.def_class(val[0], val[1],
+                                                  lt_t, superclass,
+                                                  val[4], val[5])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                    }
+                | kCLASS tLSHFT expr term
+                    {
+                      result = @def_level
+                      @def_level = 0
+
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    bodystmt kEND
+                    {
+                      result = @builder.def_sclass(val[0], val[1], val[2],
+                                                   val[5], val[6])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+
+                      @def_level = val[4]
+                    }
+                | kMODULE cpath
+                    {
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    bodystmt kEND
+                    {
+                      if in_def?
+                        diagnostic :error, :module_in_def, nil, val[0]
+                      end
+
+                      result = @builder.def_module(val[0], val[1],
+                                                   val[3], val[4])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                    }
+                | kDEF fname
+                    {
+                      @def_level += 1
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    f_arglist bodystmt kEND
+                    {
+                      result = @builder.def_method(val[0], val[1],
+                                  val[3], val[4], val[5])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                      @def_level -= 1
+                    }
+                | kDEF singleton dot_or_colon
+                    {
+                      @lexer.state = :expr_fname
+                    }
+                    fname
+                    {
+                      @def_level += 1
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    f_arglist bodystmt kEND
+                    {
+                      result = @builder.def_singleton(val[0], val[1], val[2],
+                                  val[4], val[6], val[7], val[8])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                      @def_level -= 1
+                    }
+                | kBREAK
+                    {
+                      result = @builder.keyword_cmd(:break, val[0])
+                    }
+                | kNEXT
+                    {
+                      result = @builder.keyword_cmd(:next, val[0])
+                    }
+                | kREDO
+                    {
+                      result = @builder.keyword_cmd(:redo, val[0])
+                    }
+                | kRETRY
+                    {
+                      result = @builder.keyword_cmd(:retry, val[0])
+                    }
+
+   primary_value: primary
+
+            then: term
+                | kTHEN
+                | term kTHEN
+                    {
+                      result = val[1]
+                    }
+
+              do: term
+                | kDO_COND
+
+         if_tail: opt_else
+                | kELSIF expr_value then compstmt if_tail
+                    {
+                      else_t, else_ = val[4]
+                      result = [ val[0],
+                                 @builder.condition(val[0], val[1], val[2],
+                                                    val[3], else_t,
+                                                    else_,  nil),
+                               ]
+                    }
+
+        opt_else: none
+                | kELSE compstmt
+                    {
+                      result = val
+                    }
+
+         for_var: lhs
+                | mlhs
+
+          f_marg: f_norm_arg
+                    {
+                      @static_env.declare val[0][0]
+
+                      result = @builder.arg(val[0])
+                    }
+                | tLPAREN f_margs rparen
+                    {
+                      result = @builder.multi_lhs(val[0], val[1], val[2])
+                    }
+
+     f_marg_list: f_marg
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_marg_list tCOMMA f_marg
+                    {
+                      result = val[0] << val[2]
+                    }
+
+         f_margs: f_marg_list
+                | f_marg_list tCOMMA tSTAR f_norm_arg
+                    {
+                      @static_env.declare val[3][0]
+
+                      result = val[0].
+                                  push(@builder.restarg(val[2], val[3]))
+                    }
+                | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
+                    {
+                      @static_env.declare val[3][0]
+
+                      result = val[0].
+                                  push(@builder.restarg(val[2], val[3])).
+                                  concat(val[5])
+                    }
+                | f_marg_list tCOMMA tSTAR
+                    {
+                      result = val[0].
+                                  push(@builder.restarg(val[2]))
+                    }
+                | f_marg_list tCOMMA tSTAR            tCOMMA f_marg_list
+                    {
+                      result = val[0].
+                                  push(@builder.restarg(val[2])).
+                                  concat(val[4])
+                    }
+                |                    tSTAR f_norm_arg
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = [ @builder.restarg(val[0], val[1]) ]
+                    }
+                |                    tSTAR f_norm_arg tCOMMA f_marg_list
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = [ @builder.restarg(val[0], val[1]),
+                                 *val[3] ]
+                    }
+                |                    tSTAR
+                    {
+                      result = [ @builder.restarg(val[0]) ]
+                    }
+                |                    tSTAR tCOMMA f_marg_list
+                    {
+                      result = [ @builder.restarg(val[0]),
+                                 *val[2] ]
+                    }
+
+ block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
+                    {
+                      result = val[0].concat(val[2]).concat(val[3])
+                    }
+                | f_block_kwarg opt_f_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_kwrest opt_f_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_block_arg
+                    {
+                      result = [ val[0] ]
+                    }
+
+opt_block_args_tail:
+                  tCOMMA block_args_tail
+                    {
+                      result = val[1]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+     block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg              opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[6]).
+                                  concat(val[7])
+                    }
+                | f_arg tCOMMA f_block_optarg                                opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA f_block_optarg tCOMMA                   f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA                       f_rest_arg              opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA
+                | f_arg tCOMMA                       f_rest_arg tCOMMA f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg                                                      opt_block_args_tail
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_block_optarg tCOMMA              f_rest_arg              opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_block_optarg tCOMMA              f_rest_arg tCOMMA f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_block_optarg                                             opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                | f_block_optarg tCOMMA                                f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                                    f_rest_arg              opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |                                    f_rest_arg tCOMMA f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                                                                block_args_tail
+
+ opt_block_param: # nothing
+                    {
+                      result = @builder.args(nil, [], nil)
+                    }
+                | block_param_def
+                    {
+                      @lexer.state = :expr_value
+                    }
+
+ block_param_def: tPIPE opt_bv_decl tPIPE
+                    {
+                      result = @builder.args(val[0], val[1], val[2])
+                    }
+                | tOROP
+                    {
+                      result = @builder.args(val[0], [], val[0])
+                    }
+                | tPIPE block_param opt_bv_decl tPIPE
+                    {
+                      result = @builder.args(val[0], val[1].concat(val[2]), val[3])
+                    }
+
+     opt_bv_decl: opt_nl
+                    {
+                      result = []
+                    }
+                | opt_nl tSEMI bv_decls opt_nl
+                    {
+                      result = val[2]
+                    }
+
+        bv_decls: bvar
+                    {
+                      result = [ val[0] ]
+                    }
+                | bv_decls tCOMMA bvar
+                    {
+                      result = val[0] << val[2]
+                    }
+
+            bvar: tIDENTIFIER
+                    {
+                      result = @builder.shadowarg(val[0])
+                    }
+                | f_bad_arg
+
+          lambda:   {
+                      @static_env.extend_dynamic
+                    }
+                  f_larglist lambda_body
+                    {
+                      result = [ val[1], val[2] ]
+
+                      @static_env.unextend
+                    }
+
+     f_larglist: tLPAREN2 f_args opt_bv_decl tRPAREN
+                    {
+                      result = @builder.args(val[0], val[1].concat(val[2]), val[3])
+                    }
+                | f_args
+                    {
+                      result = @builder.args(nil, val[0], nil)
+                    }
+
+     lambda_body: tLAMBEG compstmt tRCURLY
+                    {
+                      result = [ val[0], val[1], val[2] ]
+                    }
+                | kDO_LAMBDA compstmt kEND
+                    {
+                      result = [ val[0], val[1], val[2] ]
+                    }
+
+        do_block: kDO_BLOCK
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_param compstmt kEND
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+
+      block_call: command do_block
+                    {
+                      begin_t, block_args, body, end_t = val[1]
+                      result      = @builder.block(val[0],
+                                      begin_t, block_args, body, end_t)
+                    }
+                | block_call dot_or_colon operation2 opt_paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | block_call dot_or_colon operation2 opt_paren_args brace_block
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                      lparen_t, args, rparen_t)
+
+                      begin_t, args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | block_call dot_or_colon operation2 command_args do_block
+                    {
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                      nil, val[3], nil)
+
+                      begin_t, args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+
+     method_call: fcall paren_args
+                    {
+                      lparen_t, args, rparen_t = val[1]
+                      result = @builder.call_method(nil, nil, val[0],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tDOT operation2 opt_paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tCOLON2 operation2 paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tCOLON2 operation3
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2])
+                    }
+                | primary_value tDOT paren_args
+                    {
+                      lparen_t, args, rparen_t = val[2]
+                      result = @builder.call_method(val[0], val[1], nil,
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tCOLON2 paren_args
+                    {
+                      lparen_t, args, rparen_t = val[2]
+                      result = @builder.call_method(val[0], val[1], nil,
+                                  lparen_t, args, rparen_t)
+                    }
+                | kSUPER paren_args
+                    {
+                      lparen_t, args, rparen_t = val[1]
+                      result = @builder.keyword_cmd(:super, val[0],
+                                  lparen_t, args, rparen_t)
+                    }
+                | kSUPER
+                    {
+                      result = @builder.keyword_cmd(:zsuper, val[0])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket
+                    {
+                      result = @builder.index(val[0], val[1], val[2], val[3])
+                    }
+
+     brace_block: tLCURLY
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_param compstmt tRCURLY
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+                | kDO
+                    {
+                      @static_env.extend_dynamic
+                    }
+                 opt_block_param compstmt kEND
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+
+       case_body: kWHEN args then compstmt cases
+                    {
+                      result = [ @builder.when(val[0], val[1], val[2], val[3]),
+                                 *val[4] ]
+                    }
+
+           cases: opt_else
+                    {
+                      result = [ val[0] ]
+                    }
+                | case_body
+
+      opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
+                    {
+                      assoc_t, exc_var = val[2]
+
+                      if val[1]
+                        exc_list = @builder.array(nil, val[1], nil)
+                      end
+
+                      result = [ @builder.rescue_body(val[0],
+                                      exc_list, assoc_t, exc_var,
+                                      val[3], val[4]),
+                                 *val[5] ]
+                    }
+                |
+                    {
+                      result = []
+                    }
+
+        exc_list: arg_value
+                    {
+                      result = [ val[0] ]
+                    }
+                | mrhs
+                | none
+
+         exc_var: tASSOC lhs
+                    {
+                      result = [ val[0], val[1] ]
+                    }
+                | none
+
+      opt_ensure: kENSURE compstmt
+                    {
+                      result = [ val[0], val[1] ]
+                    }
+                | none
+
+         literal: numeric
+                | symbol
+                | dsym
+
+         strings: string
+                    {
+                      result = @builder.string_compose(nil, val[0], nil)
+                    }
+
+          string: string1
+                    {
+                      result = [ val[0] ]
+                    }
+                | string string1
+                    {
+                      result = val[0] << val[1]
+                    }
+
+         string1: tSTRING_BEG string_contents tSTRING_END
+                    {
+                      result = @builder.string_compose(val[0], val[1], val[2])
+                    }
+                | tSTRING
+                    {
+                      result = @builder.string(val[0])
+                    }
+                | tCHARACTER
+                    {
+                      result = @builder.character(val[0])
+                    }
+
+         xstring: tXSTRING_BEG xstring_contents tSTRING_END
+                    {
+                      result = @builder.xstring_compose(val[0], val[1], val[2])
+                    }
+
+          regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT
+                    {
+                      opts   = @builder.regexp_options(val[3])
+                      result = @builder.regexp_compose(val[0], val[1], val[2], opts)
+                    }
+
+           words: tWORDS_BEG word_list tSTRING_END
+                    {
+                      result = @builder.words_compose(val[0], val[1], val[2])
+                    }
+
+       word_list: # nothing
+                    {
+                      result = []
+                    }
+                | word_list word tSPACE
+                    {
+                      result = val[0] << @builder.word(val[1])
+                    }
+
+            word: string_content
+                    {
+                      result = [ val[0] ]
+                    }
+                | word string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+         symbols: tSYMBOLS_BEG symbol_list tSTRING_END
+                    {
+                      result = @builder.symbols_compose(val[0], val[1], val[2])
+                    }
+
+     symbol_list: # nothing
+                    {
+                      result = []
+                    }
+                | symbol_list word tSPACE
+                    {
+                      result = val[0] << @builder.word(val[1])
+                    }
+
+          qwords: tQWORDS_BEG qword_list tSTRING_END
+                    {
+                      result = @builder.words_compose(val[0], val[1], val[2])
+                    }
+
+        qsymbols: tQSYMBOLS_BEG qsym_list tSTRING_END
+                    {
+                      result = @builder.symbols_compose(val[0], val[1], val[2])
+                    }
+
+      qword_list: # nothing
+                    {
+                      result = []
+                    }
+                | qword_list tSTRING_CONTENT tSPACE
+                    {
+                      result = val[0] << @builder.string_internal(val[1])
+                    }
+
+       qsym_list: # nothing
+                    {
+                      result = []
+                    }
+                | qsym_list tSTRING_CONTENT tSPACE
+                    {
+                      result = val[0] << @builder.symbol_internal(val[1])
+                    }
+
+ string_contents: # nothing
+                    {
+                      result = []
+                    }
+                | string_contents string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+xstring_contents: # nothing
+                    {
+                      result = []
+                    }
+                | xstring_contents string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+regexp_contents: # nothing
+                    {
+                      result = []
+                    }
+                | regexp_contents string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+  string_content: tSTRING_CONTENT
+                    {
+                      result = @builder.string_internal(val[0])
+                    }
+                | tSTRING_DVAR string_dvar
+                    {
+                      result = val[1]
+                    }
+                | tSTRING_DBEG
+                    {
+                      @lexer.cond.push(false)
+                      @lexer.cmdarg.push(false)
+                    }
+                    compstmt tSTRING_DEND
+                    {
+                      @lexer.cond.lexpop
+                      @lexer.cmdarg.lexpop
+
+                      result = @builder.begin(val[0], val[2], val[3])
+                    }
+
+     string_dvar: tGVAR
+                    {
+                      result = @builder.gvar(val[0])
+                    }
+                | tIVAR
+                    {
+                      result = @builder.ivar(val[0])
+                    }
+                | tCVAR
+                    {
+                      result = @builder.cvar(val[0])
+                    }
+                | backref
+
+
+          symbol: tSYMBOL
+                    {
+                      result = @builder.symbol(val[0])
+                    }
+
+            dsym: tSYMBEG xstring_contents tSTRING_END
+                    {
+                      result = @builder.symbol_compose(val[0], val[1], val[2])
+                    }
+
+         numeric: tINTEGER
+                    {
+                      result = @builder.integer(val[0])
+                    }
+                | tFLOAT
+                    {
+                      result = @builder.float(val[0])
+                    }
+                | tUMINUS_NUM tINTEGER =tLOWEST
+                    {
+                      result = @builder.negate(val[0],
+                                  @builder.integer(val[1]))
+                    }
+                | tUMINUS_NUM tFLOAT   =tLOWEST
+                    {
+                      result = @builder.negate(val[0],
+                                  @builder.float(val[1]))
+                    }
+
+   user_variable: tIDENTIFIER
+                    {
+                      result = @builder.ident(val[0])
+                    }
+                | tIVAR
+                    {
+                      result = @builder.ivar(val[0])
+                    }
+                | tGVAR
+                    {
+                      result = @builder.gvar(val[0])
+                    }
+                | tCONSTANT
+                    {
+                      result = @builder.const(val[0])
+                    }
+                | tCVAR
+                    {
+                      result = @builder.cvar(val[0])
+                    }
+
+keyword_variable: kNIL
+                    {
+                      result = @builder.nil(val[0])
+                    }
+                | kSELF
+                    {
+                      result = @builder.self(val[0])
+                    }
+                | kTRUE
+                    {
+                      result = @builder.true(val[0])
+                    }
+                | kFALSE
+                    {
+                      result = @builder.false(val[0])
+                    }
+                | k__FILE__
+                    {
+                      result = @builder.__FILE__(val[0])
+                    }
+                | k__LINE__
+                    {
+                      result = @builder.__LINE__(val[0])
+                    }
+                | k__ENCODING__
+                    {
+                      result = @builder.__ENCODING__(val[0])
+                    }
+
+         var_ref: user_variable
+                    {
+                      result = @builder.accessible(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.accessible(val[0])
+                    }
+
+         var_lhs: user_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+
+         backref: tNTH_REF
+                    {
+                      result = @builder.nth_ref(val[0])
+                    }
+                | tBACK_REF
+                    {
+                      result = @builder.back_ref(val[0])
+                    }
+
+      superclass: term
+                    {
+                      result = nil
+                    }
+                | tLT
+                    {
+                      @lexer.state = :expr_value
+                    }
+                    expr_value term
+                    {
+                      result = [ val[0], val[2] ]
+                    }
+                | error term
+                    {
+                      yyerrok
+                      result = nil
+                    }
+
+       f_arglist: tLPAREN2 f_args rparen
+                    {
+                      result = @builder.args(val[0], val[1], val[2])
+
+                      @lexer.state = :expr_value
+                    }
+                | f_args term
+                    {
+                      result = @builder.args(nil, val[0], nil)
+                    }
+
+       args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
+                    {
+                      result = val[0].concat(val[2]).concat(val[3])
+                    }
+                | f_kwarg opt_f_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_kwrest opt_f_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_block_arg
+                    {
+                      result = [ val[0] ]
+                    }
+
+   opt_args_tail: tCOMMA args_tail
+                    {
+                      result = val[1]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+          f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg              opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[6]).
+                                  concat(val[7])
+                    }
+                | f_arg tCOMMA f_optarg                                opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA f_optarg tCOMMA                   f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA                 f_rest_arg              opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA                 f_rest_arg tCOMMA f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg                                                opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |              f_optarg tCOMMA f_rest_arg              opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |              f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                |              f_optarg                                opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |              f_optarg tCOMMA                   f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                              f_rest_arg              opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |                              f_rest_arg tCOMMA f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                                                          args_tail
+                    {
+                      result = val[0]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+       f_bad_arg: tCONSTANT
+                    {
+                      diagnostic :error, :argument_const, nil, val[0]
+                    }
+                | tIVAR
+                    {
+                      diagnostic :error, :argument_ivar, nil, val[0]
+                    }
+                | tGVAR
+                    {
+                      diagnostic :error, :argument_gvar, nil, val[0]
+                    }
+                | tCVAR
+                    {
+                      diagnostic :error, :argument_cvar, nil, val[0]
+                    }
+
+      f_norm_arg: f_bad_arg
+                | tIDENTIFIER
+
+      f_arg_item: f_norm_arg
+                    {
+                      @static_env.declare val[0][0]
+
+                      result = @builder.arg(val[0])
+                    }
+                | tLPAREN f_margs rparen
+                    {
+                      result = @builder.multi_lhs(val[0], val[1], val[2])
+                    }
+
+           f_arg: f_arg_item
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_arg tCOMMA f_arg_item
+                    {
+                      result = val[0] << val[2]
+                    }
+
+            f_kw: tLABEL arg_value
+                    {
+                      check_kwarg_name(val[0])
+
+                      @static_env.declare val[0][0]
+
+                      result = @builder.kwoptarg(val[0], val[1])
+                    }
+
+      f_block_kw: tLABEL primary_value
+                    {
+                      check_kwarg_name(val[0])
+
+                      @static_env.declare val[0][0]
+
+                      result = @builder.kwoptarg(val[0], val[1])
+                    }
+
+   f_block_kwarg: f_block_kw
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_block_kwarg tCOMMA f_block_kw
+                    {
+                      result = val[0] << val[2]
+                    }
+
+         f_kwarg: f_kw
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_kwarg tCOMMA f_kw
+                    {
+                      result = val[0] << val[2]
+                    }
+
+     kwrest_mark: tPOW | tDSTAR
+
+        f_kwrest: kwrest_mark tIDENTIFIER
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = [ @builder.kwrestarg(val[0], val[1]) ]
+                    }
+                | kwrest_mark
+                    {
+                      result = [ @builder.kwrestarg(val[0]) ]
+                    }
+
+           f_opt: tIDENTIFIER tEQL arg_value
+                    {
+                      @static_env.declare val[0][0]
+
+                      result = @builder.optarg(val[0], val[1], val[2])
+                    }
+
+     f_block_opt: tIDENTIFIER tEQL primary_value
+                    {
+                      @static_env.declare val[0][0]
+
+                      result = @builder.optarg(val[0], val[1], val[2])
+                    }
+
+  f_block_optarg: f_block_opt
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_block_optarg tCOMMA f_block_opt
+                    {
+                      result = val[0] << val[2]
+                    }
+
+        f_optarg: f_opt
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_optarg tCOMMA f_opt
+                    {
+                      result = val[0] << val[2]
+                    }
+
+    restarg_mark: tSTAR2 | tSTAR
+
+      f_rest_arg: restarg_mark tIDENTIFIER
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = [ @builder.restarg(val[0], val[1]) ]
+                    }
+                | restarg_mark
+                    {
+                      result = [ @builder.restarg(val[0]) ]
+                    }
+
+     blkarg_mark: tAMPER2 | tAMPER
+
+     f_block_arg: blkarg_mark tIDENTIFIER
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = @builder.blockarg(val[0], val[1])
+                    }
+
+ opt_f_block_arg: tCOMMA f_block_arg
+                    {
+                      result = [ val[1] ]
+                    }
+                |
+                    {
+                      result = []
+                    }
+
+       singleton: var_ref
+                | tLPAREN2 expr rparen
+                    {
+                      result = val[1]
+                    }
+
+      assoc_list: # nothing
+                    {
+                      result = []
+                    }
+                | assocs trailer
+
+          assocs: assoc
+                    {
+                      result = [ val[0] ]
+                    }
+                | assocs tCOMMA assoc
+                    {
+                      result = val[0] << val[2]
+                    }
+
+           assoc: arg_value tASSOC arg_value
+                    {
+                      result = @builder.pair(val[0], val[1], val[2])
+                    }
+                | tLABEL arg_value
+                    {
+                      result = @builder.pair_keyword(val[0], val[1])
+                    }
+                | tDSTAR arg_value
+                    {
+                      result = @builder.kwsplat(val[0], val[1])
+                    }
+
+       operation: tIDENTIFIER | tCONSTANT | tFID
+      operation2: tIDENTIFIER | tCONSTANT | tFID | op
+      operation3: tIDENTIFIER | tFID | op
+    dot_or_colon: tDOT | tCOLON2
+       opt_terms:  | terms
+          opt_nl:  | tNL
+          rparen: opt_nl tRPAREN
+                    {
+                      result = val[1]
+                    }
+        rbracket: opt_nl tRBRACK
+                    {
+                      result = val[1]
+                    }
+         trailer:  | tNL | tCOMMA
+
+            term: tSEMI
+                  {
+                    yyerrok
+                  }
+                | tNL
+
+           terms: term
+                | terms tSEMI
+
+            none: # nothing
+                  {
+                    result = nil
+                  }
+end
+
+---- header
+
+require 'parser'
+
+Parser.check_for_encoding_support
+
+---- inner
+
+  def version
+    20
+  end
+
+  def default_encoding
+    Encoding::UTF_8
+  end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/ruby21.y b/app/server/vendor/parser-2.2.2.1/lib/parser/ruby21.y
new file mode 100644
index 0000000..f3a7c49
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/ruby21.y
@@ -0,0 +1,2325 @@
+class Parser::Ruby21
+
+token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
+      kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
+      kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
+      kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
+      kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
+      k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
+      tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
+      tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
+      tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
+      tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
+      tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
+      tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
+      tDSTAR tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
+      tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT
+      tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DBEG
+      tSTRING_DVAR tSTRING_END tSTRING_DEND tSTRING tSYMBOL
+      tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG tCHARACTER
+      tRATIONAL tIMAGINARY
+
+prechigh
+  right    tBANG tTILDE tUPLUS
+  right    tPOW
+  right    tUMINUS_NUM tUMINUS
+  left     tSTAR2 tDIVIDE tPERCENT
+  left     tPLUS tMINUS
+  left     tLSHFT tRSHFT
+  left     tAMPER2
+  left     tPIPE tCARET
+  left     tGT tGEQ tLT tLEQ
+  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
+  left     tANDOP
+  left     tOROP
+  nonassoc tDOT2 tDOT3
+  right    tEH tCOLON
+  left     kRESCUE_MOD
+  right    tEQL tOP_ASGN
+  nonassoc kDEFINED
+  right    kNOT
+  left     kOR kAND
+  nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
+  nonassoc tLBRACE_ARG
+  nonassoc tLOWEST
+preclow
+
+rule
+
+         program: top_compstmt
+
+    top_compstmt: top_stmts opt_terms
+                    {
+                      result = @builder.compstmt(val[0])
+                    }
+
+       top_stmts: # nothing
+                    {
+                      result = []
+                    }
+                | top_stmt
+                    {
+                      result = [ val[0] ]
+                    }
+                | top_stmts terms top_stmt
+                    {
+                      result = val[0] << val[2]
+                    }
+                | error top_stmt
+                    {
+                      result = [ val[1] ]
+                    }
+
+        top_stmt: stmt
+                | klBEGIN tLCURLY top_compstmt tRCURLY
+                    {
+                      result = @builder.preexe(val[0], val[1], val[2], val[3])
+                    }
+
+        bodystmt: compstmt opt_rescue opt_else opt_ensure
+                    {
+                      rescue_bodies     = val[1]
+                      else_t,   else_   = val[2]
+                      ensure_t, ensure_ = val[3]
+
+                      if rescue_bodies.empty? && !else_.nil?
+                        diagnostic :warning, :useless_else, nil, else_t
+                      end
+
+                      result = @builder.begin_body(val[0],
+                                  rescue_bodies,
+                                  else_t,   else_,
+                                  ensure_t, ensure_)
+                    }
+
+        compstmt: stmts opt_terms
+                    {
+                      result = @builder.compstmt(val[0])
+                    }
+
+           stmts: # nothing
+                    {
+                      result = []
+                    }
+                | stmt_or_begin
+                    {
+                      result = [ val[0] ]
+                    }
+                | stmts terms stmt_or_begin
+                    {
+                      result = val[0] << val[2]
+                    }
+                | error stmt
+                    {
+                      result = [ val[1] ]
+                    }
+
+   stmt_or_begin: stmt
+                | klBEGIN tLCURLY top_compstmt tRCURLY
+                    {
+                      diagnostic :error, :begin_in_method, nil, val[0]
+                    }
+
+            stmt: kALIAS fitem
+                    {
+                      @lexer.state = :expr_fname
+                    }
+                    fitem
+                    {
+                      result = @builder.alias(val[0], val[1], val[3])
+                    }
+                | kALIAS tGVAR tGVAR
+                    {
+                      result = @builder.alias(val[0],
+                                  @builder.gvar(val[1]),
+                                  @builder.gvar(val[2]))
+                    }
+                | kALIAS tGVAR tBACK_REF
+                    {
+                      result = @builder.alias(val[0],
+                                  @builder.gvar(val[1]),
+                                  @builder.back_ref(val[2]))
+                    }
+                | kALIAS tGVAR tNTH_REF
+                    {
+                      diagnostic :error, :nth_ref_alias, nil, val[2]
+                    }
+                | kUNDEF undef_list
+                    {
+                      result = @builder.undef_method(val[0], val[1])
+                    }
+                | stmt kIF_MOD expr_value
+                    {
+                      result = @builder.condition_mod(val[0], nil,
+                                                      val[1], val[2])
+                    }
+                | stmt kUNLESS_MOD expr_value
+                    {
+                      result = @builder.condition_mod(nil, val[0],
+                                                      val[1], val[2])
+                    }
+                | stmt kWHILE_MOD expr_value
+                    {
+                      result = @builder.loop_mod(:while, val[0], val[1], val[2])
+                    }
+                | stmt kUNTIL_MOD expr_value
+                    {
+                      result = @builder.loop_mod(:until, val[0], val[1], val[2])
+                    }
+                | stmt kRESCUE_MOD stmt
+                    {
+                      rescue_body = @builder.rescue_body(val[1],
+                                        nil, nil, nil,
+                                        nil, val[2])
+
+                      result = @builder.begin_body(val[0], [ rescue_body ])
+                    }
+                | klEND tLCURLY compstmt tRCURLY
+                    {
+                      result = @builder.postexe(val[0], val[1], val[2], val[3])
+                    }
+                | command_asgn
+                | mlhs tEQL command_call
+                    {
+                      result = @builder.multi_assign(val[0], val[1], val[2])
+                    }
+                | var_lhs tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.index(
+                                    val[0], val[1], val[2], val[3]),
+                                  val[4], val[5])
+                    }
+                | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tDOT tCONSTANT tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | backref tOP_ASGN command_call
+                    {
+                      @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | lhs tEQL mrhs
+                    {
+                      result = @builder.assign(val[0], val[1],
+                                  @builder.array(nil, val[2], nil))
+                    }
+                | mlhs tEQL mrhs_arg
+                    {
+                      result = @builder.multi_assign(val[0], val[1], val[2])
+                    }
+                | expr
+
+    command_asgn: lhs tEQL command_call
+                    {
+                      result = @builder.assign(val[0], val[1], val[2])
+                    }
+                | lhs tEQL command_asgn
+                    {
+                      result = @builder.assign(val[0], val[1], val[2])
+                    }
+
+            expr: command_call
+                | expr kAND expr
+                    {
+                      result = @builder.logical_op(:and, val[0], val[1], val[2])
+                    }
+                | expr kOR expr
+                    {
+                      result = @builder.logical_op(:or, val[0], val[1], val[2])
+                    }
+                | kNOT opt_nl expr
+                    {
+                      result = @builder.not_op(val[0], nil, val[2], nil)
+                    }
+                | tBANG command_call
+                    {
+                      result = @builder.not_op(val[0], nil, val[1], nil)
+                    }
+                | arg
+
+      expr_value: expr
+
+    command_call: command
+                | block_command
+
+   block_command: block_call
+                | block_call dot_or_colon operation2 command_args
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  nil, val[3], nil)
+                    }
+
+ cmd_brace_block: tLBRACE_ARG
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_param compstmt tRCURLY
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+
+           fcall: operation
+
+         command: fcall command_args =tLOWEST
+                    {
+                      result = @builder.call_method(nil, nil, val[0],
+                                  nil, val[1], nil)
+                    }
+                | fcall command_args cmd_brace_block
+                    {
+                      method_call = @builder.call_method(nil, nil, val[0],
+                                        nil, val[1], nil)
+
+                      begin_t, args, body, end_t = val[2]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | primary_value tDOT operation2 command_args =tLOWEST
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  nil, val[3], nil)
+                    }
+                | primary_value tDOT operation2 command_args cmd_brace_block
+                    {
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                        nil, val[3], nil)
+
+                      begin_t, args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | primary_value tCOLON2 operation2 command_args =tLOWEST
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  nil, val[3], nil)
+                    }
+                | primary_value tCOLON2 operation2 command_args cmd_brace_block
+                    {
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                        nil, val[3], nil)
+
+                      begin_t, args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | kSUPER command_args
+                    {
+                      result = @builder.keyword_cmd(:super, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kYIELD command_args
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kRETURN call_args
+                    {
+                      result = @builder.keyword_cmd(:return, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kBREAK call_args
+                    {
+                      result = @builder.keyword_cmd(:break, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kNEXT call_args
+                    {
+                      result = @builder.keyword_cmd(:next, val[0],
+                                  nil, val[1], nil)
+                    }
+
+            mlhs: mlhs_basic
+                    {
+                      result = @builder.multi_lhs(nil, val[0], nil)
+                    }
+                | tLPAREN mlhs_inner rparen
+                    {
+                      result = @builder.begin(val[0], val[1], val[2])
+                    }
+
+      mlhs_inner: mlhs_basic
+                    {
+                      result = @builder.multi_lhs(nil, val[0], nil)
+                    }
+                | tLPAREN mlhs_inner rparen
+                    {
+                      result = @builder.multi_lhs(val[0], val[1], val[2])
+                    }
+
+      mlhs_basic: mlhs_head
+                | mlhs_head mlhs_item
+                    {
+                      result = val[0].
+                                  push(val[1])
+                    }
+                | mlhs_head tSTAR mlhs_node
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1], val[2]))
+                    }
+                | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1], val[2])).
+                                  concat(val[4])
+                    }
+                | mlhs_head tSTAR
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1]))
+                    }
+                | mlhs_head tSTAR tCOMMA mlhs_post
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1])).
+                                  concat(val[3])
+                    }
+                | tSTAR mlhs_node
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+                | tSTAR mlhs_node tCOMMA mlhs_post
+                    {
+                      result = [ @builder.splat(val[0], val[1]),
+                                 *val[3] ]
+                    }
+                | tSTAR
+                    {
+                      result = [ @builder.splat(val[0]) ]
+                    }
+                | tSTAR tCOMMA mlhs_post
+                    {
+                      result = [ @builder.splat(val[0]),
+                                 *val[2] ]
+                    }
+
+       mlhs_item: mlhs_node
+                | tLPAREN mlhs_inner rparen
+                    {
+                      result = @builder.begin(val[0], val[1], val[2])
+                    }
+
+       mlhs_head: mlhs_item tCOMMA
+                    {
+                      result = [ val[0] ]
+                    }
+                | mlhs_head mlhs_item tCOMMA
+                    {
+                      result = val[0] << val[1]
+                    }
+
+       mlhs_post: mlhs_item
+                    {
+                      result = [ val[0] ]
+                    }
+                | mlhs_post tCOMMA mlhs_item
+                    {
+                      result = val[0] << val[2]
+                    }
+
+       mlhs_node: user_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket
+                    {
+                      result = @builder.index_asgn(val[0], val[1], val[2], val[3])
+                    }
+                | primary_value tDOT tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tDOT tCONSTANT
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_fetch(val[0], val[1], val[2]))
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_global(val[0], val[1]))
+                    }
+                | backref
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+
+             lhs: user_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket
+                    {
+                      result = @builder.index_asgn(val[0], val[1], val[2], val[3])
+                    }
+                | primary_value tDOT tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tDOT tCONSTANT
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_fetch(val[0], val[1], val[2]))
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_global(val[0], val[1]))
+                    }
+                | backref
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+
+           cname: tIDENTIFIER
+                    {
+                      diagnostic :error, :module_name_const, nil, val[0]
+                    }
+                | tCONSTANT
+
+           cpath: tCOLON3 cname
+                    {
+                      result = @builder.const_global(val[0], val[1])
+                    }
+                | cname
+                    {
+                      result = @builder.const(val[0])
+                    }
+                | primary_value tCOLON2 cname
+                    {
+                      result = @builder.const_fetch(val[0], val[1], val[2])
+                    }
+
+           fname: tIDENTIFIER | tCONSTANT | tFID
+                | op
+                | reswords
+
+            fsym: fname
+                    {
+                      result = @builder.symbol(val[0])
+                    }
+                | symbol
+
+           fitem: fsym
+                | dsym
+
+      undef_list: fitem
+                    {
+                      result = [ val[0] ]
+                    }
+                | undef_list tCOMMA
+                    {
+                      @lexer.state = :expr_fname
+                    }
+                    fitem
+                    {
+                      result = val[0] << val[3]
+                    }
+
+              op:   tPIPE    | tCARET  | tAMPER2  | tCMP  | tEQ     | tEQQ
+                |   tMATCH   | tNMATCH | tGT      | tGEQ  | tLT     | tLEQ
+                |   tNEQ     | tLSHFT  | tRSHFT   | tPLUS | tMINUS  | tSTAR2
+                |   tSTAR    | tDIVIDE | tPERCENT | tPOW  | tBANG   | tTILDE
+                |   tUPLUS   | tUMINUS | tAREF    | tASET | tDSTAR  | tBACK_REF2
+
+        reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
+                | kALIAS    | kAND      | kBEGIN        | kBREAK  | kCASE
+                | kCLASS    | kDEF      | kDEFINED      | kDO     | kELSE
+                | kELSIF    | kEND      | kENSURE       | kFALSE  | kFOR
+                | kIN       | kMODULE   | kNEXT         | kNIL    | kNOT
+                | kOR       | kREDO     | kRESCUE       | kRETRY  | kRETURN
+                | kSELF     | kSUPER    | kTHEN         | kTRUE   | kUNDEF
+                | kWHEN     | kYIELD    | kIF           | kUNLESS | kWHILE
+                | kUNTIL
+
+             arg: lhs tEQL arg
+                    {
+                      result = @builder.assign(val[0], val[1], val[2])
+                    }
+                | lhs tEQL arg kRESCUE_MOD arg
+                    {
+                      rescue_body = @builder.rescue_body(val[3],
+                                        nil, nil, nil,
+                                        nil, val[4])
+
+                      rescue_ = @builder.begin_body(val[2], [ rescue_body ])
+
+                      result  = @builder.assign(val[0], val[1], rescue_)
+                    }
+                | var_lhs tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | var_lhs tOP_ASGN arg kRESCUE_MOD arg
+                    {
+                      rescue_body = @builder.rescue_body(val[3],
+                                        nil, nil, nil,
+                                        nil, val[4])
+
+                      rescue_ = @builder.begin_body(val[2], [ rescue_body ])
+
+                      result = @builder.op_assign(val[0], val[1], rescue_)
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.index(
+                                    val[0], val[1], val[2], val[3]),
+                                  val[4], val[5])
+                    }
+                | primary_value tDOT tIDENTIFIER tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tDOT tCONSTANT tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
+                    {
+                      const  = @builder.const_op_assignable(
+                                  @builder.const_fetch(val[0], val[1], val[2]))
+                      result = @builder.op_assign(const, val[3], val[4])
+                    }
+                | tCOLON3 tCONSTANT tOP_ASGN arg
+                    {
+                      const  = @builder.const_op_assignable(
+                                  @builder.const_global(val[0], val[1]))
+                      result = @builder.op_assign(const, val[2], val[3])
+                    }
+                | backref tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | arg tDOT2 arg
+                    {
+                      result = @builder.range_inclusive(val[0], val[1], val[2])
+                    }
+                | arg tDOT3 arg
+                    {
+                      result = @builder.range_exclusive(val[0], val[1], val[2])
+                    }
+                | arg tPLUS arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tMINUS arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tSTAR2 arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tDIVIDE arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tPERCENT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tPOW arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | tUMINUS_NUM simple_numeric tPOW arg
+                    {
+                      result = @builder.unary_op(val[0],
+                                  @builder.binary_op(
+                                    val[1], val[2], val[3]))
+                    }
+                | tUPLUS arg
+                    {
+                      result = @builder.unary_op(val[0], val[1])
+                    }
+                | tUMINUS arg
+                    {
+                      result = @builder.unary_op(val[0], val[1])
+                    }
+                | arg tPIPE arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tCARET arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tAMPER2 arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tCMP arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tGT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tGEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tLT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tLEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tEQQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tNEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tMATCH arg
+                    {
+                      result = @builder.match_op(val[0], val[1], val[2])
+                    }
+                | arg tNMATCH arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | tBANG arg
+                    {
+                      result = @builder.not_op(val[0], nil, val[1], nil)
+                    }
+                | tTILDE arg
+                    {
+                      result = @builder.unary_op(val[0], val[1])
+                    }
+                | arg tLSHFT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tRSHFT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tANDOP arg
+                    {
+                      result = @builder.logical_op(:and, val[0], val[1], val[2])
+                    }
+                | arg tOROP arg
+                    {
+                      result = @builder.logical_op(:or, val[0], val[1], val[2])
+                    }
+                | kDEFINED opt_nl arg
+                    {
+                      result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
+                    }
+
+                | arg tEH arg opt_nl tCOLON arg
+                    {
+                      result = @builder.ternary(val[0], val[1],
+                                                val[2], val[4], val[5])
+                    }
+                | primary
+
+       arg_value: arg
+
+       aref_args: none
+                | args trailer
+                | args tCOMMA assocs trailer
+                    {
+                      result = val[0] << @builder.associate(nil, val[2], nil)
+                    }
+                | assocs trailer
+                    {
+                      result = [ @builder.associate(nil, val[0], nil) ]
+                    }
+
+      paren_args: tLPAREN2 opt_call_args rparen
+                    {
+                      result = val
+                    }
+
+  opt_paren_args: # nothing
+                    {
+                      result = [ nil, [], nil ]
+                    }
+                | paren_args
+
+   opt_call_args: # nothing
+                    {
+                      result = []
+                    }
+                | call_args
+                | args tCOMMA
+                | args tCOMMA assocs tCOMMA
+                    {
+                      result = val[0] << @builder.associate(nil, val[2], nil)
+                    }
+                | assocs tCOMMA
+                    {
+                      result = [ @builder.associate(nil, val[0], nil) ]
+                    }
+
+       call_args: command
+                    {
+                      result = [ val[0] ]
+                    }
+                | args opt_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | assocs opt_block_arg
+                    {
+                      result = [ @builder.associate(nil, val[0], nil) ]
+                      result.concat(val[1])
+                    }
+                | args tCOMMA assocs opt_block_arg
+                    {
+                      assocs = @builder.associate(nil, val[2], nil)
+                      result = val[0] << assocs
+                      result.concat(val[3])
+                    }
+                | block_arg
+                    {
+                      result =  [ val[0] ]
+                    }
+
+    command_args:   {
+                      result = @lexer.cmdarg.dup
+                      @lexer.cmdarg.push(true)
+                    }
+                  call_args
+                    {
+                      @lexer.cmdarg = val[0]
+
+                      result = val[1]
+                    }
+
+       block_arg: tAMPER arg_value
+                    {
+                      result = @builder.block_pass(val[0], val[1])
+                    }
+
+   opt_block_arg: tCOMMA block_arg
+                    {
+                      result = [ val[1] ]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+            args: arg_value
+                    {
+                      result = [ val[0] ]
+                    }
+                | tSTAR arg_value
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+                | args tCOMMA arg_value
+                    {
+                      result = val[0] << val[2]
+                    }
+                | args tCOMMA tSTAR arg_value
+                    {
+                      result = val[0] << @builder.splat(val[2], val[3])
+                    }
+
+        mrhs_arg: mrhs
+                    {
+                      result = @builder.array(nil, val[0], nil)
+                    }
+                | arg_value
+
+            mrhs: args tCOMMA arg_value
+                    {
+                      result = val[0] << val[2]
+                    }
+                | args tCOMMA tSTAR arg_value
+                    {
+                      result = val[0] << @builder.splat(val[2], val[3])
+                    }
+                | tSTAR arg_value
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+
+         primary: literal
+                | strings
+                | xstring
+                | regexp
+                | words
+                | qwords
+                | symbols
+                | qsymbols
+                | var_ref
+                | backref
+                | tFID
+                    {
+                      result = @builder.call_method(nil, nil, val[0])
+                    }
+                | kBEGIN
+                    {
+                      result = @lexer.cmdarg.dup
+                      @lexer.cmdarg.clear
+                    }
+                    bodystmt kEND
+                    {
+                      @lexer.cmdarg = val[1]
+
+                      result = @builder.begin_keyword(val[0], val[2], val[3])
+                    }
+                | tLPAREN_ARG
+                    {
+                      result = @lexer.cmdarg.dup
+                      @lexer.cmdarg.clear
+                    }
+                    expr
+                    {
+                      @lexer.state = :expr_endarg
+                    }
+                    opt_nl tRPAREN
+                    {
+                      @lexer.cmdarg = val[1]
+
+                      result = @builder.begin(val[0], val[2], val[5])
+                    }
+                | tLPAREN_ARG
+                    {
+                      @lexer.state = :expr_endarg
+                    }
+                    opt_nl tRPAREN
+                    {
+                      result = @builder.begin(val[0], nil, val[3])
+                    }
+                | tLPAREN compstmt tRPAREN
+                    {
+                      result = @builder.begin(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      result = @builder.const_fetch(val[0], val[1], val[2])
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      result = @builder.const_global(val[0], val[1])
+                    }
+                | tLBRACK aref_args tRBRACK
+                    {
+                      result = @builder.array(val[0], val[1], val[2])
+                    }
+                | tLBRACE assoc_list tRCURLY
+                    {
+                      result = @builder.associate(val[0], val[1], val[2])
+                    }
+                | kRETURN
+                    {
+                      result = @builder.keyword_cmd(:return, val[0])
+                    }
+                | kYIELD tLPAREN2 call_args rparen
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
+                    }
+                | kYIELD tLPAREN2 rparen
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
+                    }
+                | kYIELD
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0])
+                    }
+                | kDEFINED opt_nl tLPAREN2 expr rparen
+                    {
+                      result = @builder.keyword_cmd(:defined?, val[0],
+                                                    val[2], [ val[3] ], val[4])
+                    }
+                | kNOT tLPAREN2 expr rparen
+                    {
+                      result = @builder.not_op(val[0], val[1], val[2], val[3])
+                    }
+                | kNOT tLPAREN2 rparen
+                    {
+                      result = @builder.not_op(val[0], val[1], nil, val[2])
+                    }
+                | fcall brace_block
+                    {
+                      method_call = @builder.call_method(nil, nil, val[0])
+
+                      begin_t, args, body, end_t = val[1]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | method_call
+                | method_call brace_block
+                    {
+                      begin_t, args, body, end_t = val[1]
+                      result      = @builder.block(val[0],
+                                      begin_t, args, body, end_t)
+                    }
+                | tLAMBDA lambda
+                    {
+                      lambda_call = @builder.call_lambda(val[0])
+
+                      args, (begin_t, body, end_t) = val[1]
+                      result      = @builder.block(lambda_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | kIF expr_value then compstmt if_tail kEND
+                    {
+                      else_t, else_ = val[4]
+                      result = @builder.condition(val[0], val[1], val[2],
+                                                  val[3], else_t,
+                                                  else_,  val[5])
+                    }
+                | kUNLESS expr_value then compstmt opt_else kEND
+                    {
+                      else_t, else_ = val[4]
+                      result = @builder.condition(val[0], val[1], val[2],
+                                                  else_,  else_t,
+                                                  val[3], val[5])
+                    }
+                | kWHILE
+                    {
+                      @lexer.cond.push(true)
+                    }
+                    expr_value do
+                    {
+                      @lexer.cond.pop
+                    }
+                    compstmt kEND
+                    {
+                      result = @builder.loop(:while, val[0], val[2], val[3],
+                                             val[5], val[6])
+                    }
+                | kUNTIL
+                    {
+                      @lexer.cond.push(true)
+                    }
+                    expr_value do
+                    {
+                      @lexer.cond.pop
+                    }
+                    compstmt kEND
+                    {
+                      result = @builder.loop(:until, val[0], val[2], val[3],
+                                             val[5], val[6])
+                    }
+                | kCASE expr_value opt_terms case_body kEND
+                    {
+                      *when_bodies, (else_t, else_body) = *val[3]
+
+                      result = @builder.case(val[0], val[1],
+                                             when_bodies, else_t, else_body,
+                                             val[4])
+                    }
+                | kCASE            opt_terms case_body kEND
+                    {
+                      *when_bodies, (else_t, else_body) = *val[2]
+
+                      result = @builder.case(val[0], nil,
+                                             when_bodies, else_t, else_body,
+                                             val[3])
+                    }
+                | kFOR for_var kIN
+                    {
+                      @lexer.cond.push(true)
+                    }
+                    expr_value do
+                    {
+                      @lexer.cond.pop
+                    }
+                    compstmt kEND
+                    {
+                      result = @builder.for(val[0], val[1],
+                                            val[2], val[4],
+                                            val[5], val[7], val[8])
+                    }
+                | kCLASS cpath superclass
+                    {
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    bodystmt kEND
+                    {
+                      if in_def?
+                        diagnostic :error, :class_in_def, nil, val[0]
+                      end
+
+                      lt_t, superclass = val[2]
+                      result = @builder.def_class(val[0], val[1],
+                                                  lt_t, superclass,
+                                                  val[4], val[5])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                    }
+                | kCLASS tLSHFT expr term
+                    {
+                      result = @def_level
+                      @def_level = 0
+
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    bodystmt kEND
+                    {
+                      result = @builder.def_sclass(val[0], val[1], val[2],
+                                                   val[5], val[6])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+
+                      @def_level = val[4]
+                    }
+                | kMODULE cpath
+                    {
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    bodystmt kEND
+                    {
+                      if in_def?
+                        diagnostic :error, :module_in_def, nil, val[0]
+                      end
+
+                      result = @builder.def_module(val[0], val[1],
+                                                   val[3], val[4])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                    }
+                | kDEF fname
+                    {
+                      @def_level += 1
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    f_arglist bodystmt kEND
+                    {
+                      result = @builder.def_method(val[0], val[1],
+                                  val[3], val[4], val[5])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                      @def_level -= 1
+                    }
+                | kDEF singleton dot_or_colon
+                    {
+                      @lexer.state = :expr_fname
+                    }
+                    fname
+                    {
+                      @def_level += 1
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    f_arglist bodystmt kEND
+                    {
+                      result = @builder.def_singleton(val[0], val[1], val[2],
+                                  val[4], val[6], val[7], val[8])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                      @def_level -= 1
+                    }
+                | kBREAK
+                    {
+                      result = @builder.keyword_cmd(:break, val[0])
+                    }
+                | kNEXT
+                    {
+                      result = @builder.keyword_cmd(:next, val[0])
+                    }
+                | kREDO
+                    {
+                      result = @builder.keyword_cmd(:redo, val[0])
+                    }
+                | kRETRY
+                    {
+                      result = @builder.keyword_cmd(:retry, val[0])
+                    }
+
+   primary_value: primary
+
+            then: term
+                | kTHEN
+                | term kTHEN
+                    {
+                      result = val[1]
+                    }
+
+              do: term
+                | kDO_COND
+
+         if_tail: opt_else
+                | kELSIF expr_value then compstmt if_tail
+                    {
+                      else_t, else_ = val[4]
+                      result = [ val[0],
+                                 @builder.condition(val[0], val[1], val[2],
+                                                    val[3], else_t,
+                                                    else_,  nil),
+                               ]
+                    }
+
+        opt_else: none
+                | kELSE compstmt
+                    {
+                      result = val
+                    }
+
+         for_var: lhs
+                | mlhs
+
+          f_marg: f_norm_arg
+                    {
+                      result = @builder.arg(val[0])
+                    }
+                | tLPAREN f_margs rparen
+                    {
+                      result = @builder.multi_lhs(val[0], val[1], val[2])
+                    }
+
+     f_marg_list: f_marg
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_marg_list tCOMMA f_marg
+                    {
+                      result = val[0] << val[2]
+                    }
+
+         f_margs: f_marg_list
+                | f_marg_list tCOMMA tSTAR f_norm_arg
+                    {
+                      result = val[0].
+                                  push(@builder.restarg(val[2], val[3]))
+                    }
+                | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
+                    {
+                      result = val[0].
+                                  push(@builder.restarg(val[2], val[3])).
+                                  concat(val[5])
+                    }
+                | f_marg_list tCOMMA tSTAR
+                    {
+                      result = val[0].
+                                  push(@builder.restarg(val[2]))
+                    }
+                | f_marg_list tCOMMA tSTAR            tCOMMA f_marg_list
+                    {
+                      result = val[0].
+                                  push(@builder.restarg(val[2])).
+                                  concat(val[4])
+                    }
+                |                    tSTAR f_norm_arg
+                    {
+                      result = [ @builder.restarg(val[0], val[1]) ]
+                    }
+                |                    tSTAR f_norm_arg tCOMMA f_marg_list
+                    {
+                      result = [ @builder.restarg(val[0], val[1]),
+                                 *val[3] ]
+                    }
+                |                    tSTAR
+                    {
+                      result = [ @builder.restarg(val[0]) ]
+                    }
+                |                    tSTAR tCOMMA f_marg_list
+                    {
+                      result = [ @builder.restarg(val[0]),
+                                 *val[2] ]
+                    }
+
+ block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
+                    {
+                      result = val[0].concat(val[2]).concat(val[3])
+                    }
+                | f_block_kwarg opt_f_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_kwrest opt_f_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_block_arg
+                    {
+                      result = [ val[0] ]
+                    }
+
+opt_block_args_tail:
+                  tCOMMA block_args_tail
+                    {
+                      result = val[1]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+     block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg              opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[6]).
+                                  concat(val[7])
+                    }
+                | f_arg tCOMMA f_block_optarg                                opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA f_block_optarg tCOMMA                   f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA                       f_rest_arg              opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA
+                | f_arg tCOMMA                       f_rest_arg tCOMMA f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg                                                      opt_block_args_tail
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_block_optarg tCOMMA              f_rest_arg              opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_block_optarg tCOMMA              f_rest_arg tCOMMA f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_block_optarg                                             opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                | f_block_optarg tCOMMA                                f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                                    f_rest_arg              opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |                                    f_rest_arg tCOMMA f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                                                                block_args_tail
+
+ opt_block_param: # nothing
+                    {
+                      result = @builder.args(nil, [], nil)
+                    }
+                | block_param_def
+                    {
+                      @lexer.state = :expr_value
+                    }
+
+ block_param_def: tPIPE opt_bv_decl tPIPE
+                    {
+                      result = @builder.args(val[0], val[1], val[2])
+                    }
+                | tOROP
+                    {
+                      result = @builder.args(val[0], [], val[0])
+                    }
+                | tPIPE block_param opt_bv_decl tPIPE
+                    {
+                      result = @builder.args(val[0], val[1].concat(val[2]), val[3])
+                    }
+
+     opt_bv_decl: opt_nl
+                    {
+                      result = []
+                    }
+                | opt_nl tSEMI bv_decls opt_nl
+                    {
+                      result = val[2]
+                    }
+
+        bv_decls: bvar
+                    {
+                      result = [ val[0] ]
+                    }
+                | bv_decls tCOMMA bvar
+                    {
+                      result = val[0] << val[2]
+                    }
+
+            bvar: tIDENTIFIER
+                    {
+                      result = @builder.shadowarg(val[0])
+                    }
+                | f_bad_arg
+
+          lambda:   {
+                      @static_env.extend_dynamic
+                    }
+                  f_larglist lambda_body
+                    {
+                      result = [ val[1], val[2] ]
+
+                      @static_env.unextend
+                    }
+
+     f_larglist: tLPAREN2 f_args opt_bv_decl tRPAREN
+                    {
+                      result = @builder.args(val[0], val[1].concat(val[2]), val[3])
+                    }
+                | f_args
+                    {
+                      result = @builder.args(nil, val[0], nil)
+                    }
+
+     lambda_body: tLAMBEG compstmt tRCURLY
+                    {
+                      result = [ val[0], val[1], val[2] ]
+                    }
+                | kDO_LAMBDA compstmt kEND
+                    {
+                      result = [ val[0], val[1], val[2] ]
+                    }
+
+        do_block: kDO_BLOCK
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_param compstmt kEND
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+
+      block_call: command do_block
+                    {
+                      begin_t, block_args, body, end_t = val[1]
+                      result      = @builder.block(val[0],
+                                      begin_t, block_args, body, end_t)
+                    }
+                | block_call dot_or_colon operation2 opt_paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | block_call dot_or_colon operation2 opt_paren_args brace_block
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                      lparen_t, args, rparen_t)
+
+                      begin_t, args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | block_call dot_or_colon operation2 command_args do_block
+                    {
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                      nil, val[3], nil)
+
+                      begin_t, args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+
+     method_call: fcall paren_args
+                    {
+                      lparen_t, args, rparen_t = val[1]
+                      result = @builder.call_method(nil, nil, val[0],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tDOT operation2 opt_paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tCOLON2 operation2 paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tCOLON2 operation3
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2])
+                    }
+                | primary_value tDOT paren_args
+                    {
+                      lparen_t, args, rparen_t = val[2]
+                      result = @builder.call_method(val[0], val[1], nil,
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tCOLON2 paren_args
+                    {
+                      lparen_t, args, rparen_t = val[2]
+                      result = @builder.call_method(val[0], val[1], nil,
+                                  lparen_t, args, rparen_t)
+                    }
+                | kSUPER paren_args
+                    {
+                      lparen_t, args, rparen_t = val[1]
+                      result = @builder.keyword_cmd(:super, val[0],
+                                  lparen_t, args, rparen_t)
+                    }
+                | kSUPER
+                    {
+                      result = @builder.keyword_cmd(:zsuper, val[0])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket
+                    {
+                      result = @builder.index(val[0], val[1], val[2], val[3])
+                    }
+
+     brace_block: tLCURLY
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_param compstmt tRCURLY
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+                | kDO
+                    {
+                      @static_env.extend_dynamic
+                    }
+                 opt_block_param compstmt kEND
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+
+       case_body: kWHEN args then compstmt cases
+                    {
+                      result = [ @builder.when(val[0], val[1], val[2], val[3]),
+                                 *val[4] ]
+                    }
+
+           cases: opt_else
+                    {
+                      result = [ val[0] ]
+                    }
+                | case_body
+
+      opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
+                    {
+                      assoc_t, exc_var = val[2]
+
+                      if val[1]
+                        exc_list = @builder.array(nil, val[1], nil)
+                      end
+
+                      result = [ @builder.rescue_body(val[0],
+                                      exc_list, assoc_t, exc_var,
+                                      val[3], val[4]),
+                                 *val[5] ]
+                    }
+                |
+                    {
+                      result = []
+                    }
+
+        exc_list: arg_value
+                    {
+                      result = [ val[0] ]
+                    }
+                | mrhs
+                | none
+
+         exc_var: tASSOC lhs
+                    {
+                      result = [ val[0], val[1] ]
+                    }
+                | none
+
+      opt_ensure: kENSURE compstmt
+                    {
+                      result = [ val[0], val[1] ]
+                    }
+                | none
+
+         literal: numeric
+                | symbol
+                | dsym
+
+         strings: string
+                    {
+                      result = @builder.string_compose(nil, val[0], nil)
+                    }
+
+          string: string1
+                    {
+                      result = [ val[0] ]
+                    }
+                | string string1
+                    {
+                      result = val[0] << val[1]
+                    }
+
+         string1: tSTRING_BEG string_contents tSTRING_END
+                    {
+                      result = @builder.string_compose(val[0], val[1], val[2])
+                    }
+                | tSTRING
+                    {
+                      result = @builder.string(val[0])
+                    }
+                | tCHARACTER
+                    {
+                      result = @builder.character(val[0])
+                    }
+
+         xstring: tXSTRING_BEG xstring_contents tSTRING_END
+                    {
+                      result = @builder.xstring_compose(val[0], val[1], val[2])
+                    }
+
+          regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT
+                    {
+                      opts   = @builder.regexp_options(val[3])
+                      result = @builder.regexp_compose(val[0], val[1], val[2], opts)
+                    }
+
+           words: tWORDS_BEG word_list tSTRING_END
+                    {
+                      result = @builder.words_compose(val[0], val[1], val[2])
+                    }
+
+       word_list: # nothing
+                    {
+                      result = []
+                    }
+                | word_list word tSPACE
+                    {
+                      result = val[0] << @builder.word(val[1])
+                    }
+
+            word: string_content
+                    {
+                      result = [ val[0] ]
+                    }
+                | word string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+         symbols: tSYMBOLS_BEG symbol_list tSTRING_END
+                    {
+                      result = @builder.symbols_compose(val[0], val[1], val[2])
+                    }
+
+     symbol_list: # nothing
+                    {
+                      result = []
+                    }
+                | symbol_list word tSPACE
+                    {
+                      result = val[0] << @builder.word(val[1])
+                    }
+
+          qwords: tQWORDS_BEG qword_list tSTRING_END
+                    {
+                      result = @builder.words_compose(val[0], val[1], val[2])
+                    }
+
+        qsymbols: tQSYMBOLS_BEG qsym_list tSTRING_END
+                    {
+                      result = @builder.symbols_compose(val[0], val[1], val[2])
+                    }
+
+      qword_list: # nothing
+                    {
+                      result = []
+                    }
+                | qword_list tSTRING_CONTENT tSPACE
+                    {
+                      result = val[0] << @builder.string_internal(val[1])
+                    }
+
+       qsym_list: # nothing
+                    {
+                      result = []
+                    }
+                | qsym_list tSTRING_CONTENT tSPACE
+                    {
+                      result = val[0] << @builder.symbol_internal(val[1])
+                    }
+
+ string_contents: # nothing
+                    {
+                      result = []
+                    }
+                | string_contents string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+xstring_contents: # nothing
+                    {
+                      result = []
+                    }
+                | xstring_contents string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+regexp_contents: # nothing
+                    {
+                      result = []
+                    }
+                | regexp_contents string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+  string_content: tSTRING_CONTENT
+                    {
+                      result = @builder.string_internal(val[0])
+                    }
+                | tSTRING_DVAR string_dvar
+                    {
+                      result = val[1]
+                    }
+                | tSTRING_DBEG
+                    {
+                      @lexer.cond.push(false)
+                      @lexer.cmdarg.push(false)
+                    }
+                    compstmt tSTRING_DEND
+                    {
+                      @lexer.cond.lexpop
+                      @lexer.cmdarg.lexpop
+
+                      result = @builder.begin(val[0], val[2], val[3])
+                    }
+
+     string_dvar: tGVAR
+                    {
+                      result = @builder.gvar(val[0])
+                    }
+                | tIVAR
+                    {
+                      result = @builder.ivar(val[0])
+                    }
+                | tCVAR
+                    {
+                      result = @builder.cvar(val[0])
+                    }
+                | backref
+
+
+          symbol: tSYMBOL
+                    {
+                      result = @builder.symbol(val[0])
+                    }
+
+            dsym: tSYMBEG xstring_contents tSTRING_END
+                    {
+                      result = @builder.symbol_compose(val[0], val[1], val[2])
+                    }
+
+         numeric: simple_numeric
+                    {
+                      result = val[0]
+                    }
+                | tUMINUS_NUM simple_numeric =tLOWEST
+                    {
+                      result = @builder.negate(val[0], val[1])
+                    }
+
+  simple_numeric: tINTEGER
+                    {
+                      result = @builder.integer(val[0])
+                    }
+                | tFLOAT
+                    {
+                      result = @builder.float(val[0])
+                    }
+                | tRATIONAL
+                    {
+                      result = @builder.rational(val[0])
+                    }
+                | tIMAGINARY
+                    {
+                      result = @builder.complex(val[0])
+                    }
+
+   user_variable: tIDENTIFIER
+                    {
+                      result = @builder.ident(val[0])
+                    }
+                | tIVAR
+                    {
+                      result = @builder.ivar(val[0])
+                    }
+                | tGVAR
+                    {
+                      result = @builder.gvar(val[0])
+                    }
+                | tCONSTANT
+                    {
+                      result = @builder.const(val[0])
+                    }
+                | tCVAR
+                    {
+                      result = @builder.cvar(val[0])
+                    }
+
+keyword_variable: kNIL
+                    {
+                      result = @builder.nil(val[0])
+                    }
+                | kSELF
+                    {
+                      result = @builder.self(val[0])
+                    }
+                | kTRUE
+                    {
+                      result = @builder.true(val[0])
+                    }
+                | kFALSE
+                    {
+                      result = @builder.false(val[0])
+                    }
+                | k__FILE__
+                    {
+                      result = @builder.__FILE__(val[0])
+                    }
+                | k__LINE__
+                    {
+                      result = @builder.__LINE__(val[0])
+                    }
+                | k__ENCODING__
+                    {
+                      result = @builder.__ENCODING__(val[0])
+                    }
+
+         var_ref: user_variable
+                    {
+                      result = @builder.accessible(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.accessible(val[0])
+                    }
+
+         var_lhs: user_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+
+         backref: tNTH_REF
+                    {
+                      result = @builder.nth_ref(val[0])
+                    }
+                | tBACK_REF
+                    {
+                      result = @builder.back_ref(val[0])
+                    }
+
+      superclass: term
+                    {
+                      result = nil
+                    }
+                | tLT
+                    {
+                      @lexer.state = :expr_value
+                    }
+                    expr_value term
+                    {
+                      result = [ val[0], val[2] ]
+                    }
+                | error term
+                    {
+                      yyerrok
+                      result = nil
+                    }
+
+       f_arglist: tLPAREN2 f_args rparen
+                    {
+                      result = @builder.args(val[0], val[1], val[2])
+
+                      @lexer.state = :expr_value
+                    }
+                |   {
+                      result = @lexer.in_kwarg
+                      @lexer.in_kwarg = true
+                    }
+                  f_args term
+                    {
+                      @lexer.in_kwarg = val[0]
+                      result = @builder.args(nil, val[1], nil)
+                    }
+
+
+       args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
+                    {
+                      result = val[0].concat(val[2]).concat(val[3])
+                    }
+                | f_kwarg opt_f_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_kwrest opt_f_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_block_arg
+                    {
+                      result = [ val[0] ]
+                    }
+
+   opt_args_tail: tCOMMA args_tail
+                    {
+                      result = val[1]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+          f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg              opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[6]).
+                                  concat(val[7])
+                    }
+                | f_arg tCOMMA f_optarg                                opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA f_optarg tCOMMA                   f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA                 f_rest_arg              opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA                 f_rest_arg tCOMMA f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg                                                opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |              f_optarg tCOMMA f_rest_arg              opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |              f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                |              f_optarg                                opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |              f_optarg tCOMMA                   f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                              f_rest_arg              opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |                              f_rest_arg tCOMMA f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                                                          args_tail
+                    {
+                      result = val[0]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+       f_bad_arg: tCONSTANT
+                    {
+                      diagnostic :error, :argument_const, nil, val[0]
+                    }
+                | tIVAR
+                    {
+                      diagnostic :error, :argument_ivar, nil, val[0]
+                    }
+                | tGVAR
+                    {
+                      diagnostic :error, :argument_gvar, nil, val[0]
+                    }
+                | tCVAR
+                    {
+                      diagnostic :error, :argument_cvar, nil, val[0]
+                    }
+
+      f_norm_arg: f_bad_arg
+                | tIDENTIFIER
+                    {
+                      @static_env.declare val[0][0]
+
+                      result = val[0]
+                    }
+
+      f_arg_item: f_norm_arg
+                    {
+                      result = @builder.arg(val[0])
+                    }
+                | tLPAREN f_margs rparen
+                    {
+                      result = @builder.multi_lhs(val[0], val[1], val[2])
+                    }
+
+           f_arg: f_arg_item
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_arg tCOMMA f_arg_item
+                    {
+                      result = val[0] << val[2]
+                    }
+
+         f_label: tLABEL
+                    {
+                      check_kwarg_name(val[0])
+
+                      @static_env.declare val[0][0]
+
+                      result = val[0]
+                    }
+
+            f_kw: f_label arg_value
+                    {
+                      result = @builder.kwoptarg(val[0], val[1])
+                    }
+                | f_label
+                    {
+                      result = @builder.kwarg(val[0])
+                    }
+
+      f_block_kw: f_label primary_value
+                    {
+                      result = @builder.kwoptarg(val[0], val[1])
+                    }
+                | f_label
+                    {
+                      result = @builder.kwarg(val[0])
+                    }
+
+   f_block_kwarg: f_block_kw
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_block_kwarg tCOMMA f_block_kw
+                    {
+                      result = val[0] << val[2]
+                    }
+
+         f_kwarg: f_kw
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_kwarg tCOMMA f_kw
+                    {
+                      result = val[0] << val[2]
+                    }
+
+     kwrest_mark: tPOW | tDSTAR
+
+        f_kwrest: kwrest_mark tIDENTIFIER
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = [ @builder.kwrestarg(val[0], val[1]) ]
+                    }
+                | kwrest_mark
+                    {
+                      result = [ @builder.kwrestarg(val[0]) ]
+                    }
+
+           f_opt: f_norm_arg tEQL arg_value
+                    {
+                      result = @builder.optarg(val[0], val[1], val[2])
+                    }
+
+     f_block_opt: f_norm_arg tEQL primary_value
+                    {
+                      result = @builder.optarg(val[0], val[1], val[2])
+                    }
+
+  f_block_optarg: f_block_opt
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_block_optarg tCOMMA f_block_opt
+                    {
+                      result = val[0] << val[2]
+                    }
+
+        f_optarg: f_opt
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_optarg tCOMMA f_opt
+                    {
+                      result = val[0] << val[2]
+                    }
+
+    restarg_mark: tSTAR2 | tSTAR
+
+      f_rest_arg: restarg_mark tIDENTIFIER
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = [ @builder.restarg(val[0], val[1]) ]
+                    }
+                | restarg_mark
+                    {
+                      result = [ @builder.restarg(val[0]) ]
+                    }
+
+     blkarg_mark: tAMPER2 | tAMPER
+
+     f_block_arg: blkarg_mark tIDENTIFIER
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = @builder.blockarg(val[0], val[1])
+                    }
+
+ opt_f_block_arg: tCOMMA f_block_arg
+                    {
+                      result = [ val[1] ]
+                    }
+                |
+                    {
+                      result = []
+                    }
+
+       singleton: var_ref
+                | tLPAREN2 expr rparen
+                    {
+                      result = val[1]
+                    }
+
+      assoc_list: # nothing
+                    {
+                      result = []
+                    }
+                | assocs trailer
+
+          assocs: assoc
+                    {
+                      result = [ val[0] ]
+                    }
+                | assocs tCOMMA assoc
+                    {
+                      result = val[0] << val[2]
+                    }
+
+           assoc: arg_value tASSOC arg_value
+                    {
+                      result = @builder.pair(val[0], val[1], val[2])
+                    }
+                | tLABEL arg_value
+                    {
+                      result = @builder.pair_keyword(val[0], val[1])
+                    }
+                | tDSTAR arg_value
+                    {
+                      result = @builder.kwsplat(val[0], val[1])
+                    }
+
+       operation: tIDENTIFIER | tCONSTANT | tFID
+      operation2: tIDENTIFIER | tCONSTANT | tFID | op
+      operation3: tIDENTIFIER | tFID | op
+    dot_or_colon: tDOT | tCOLON2
+       opt_terms:  | terms
+          opt_nl:  | tNL
+          rparen: opt_nl tRPAREN
+                    {
+                      result = val[1]
+                    }
+        rbracket: opt_nl tRBRACK
+                    {
+                      result = val[1]
+                    }
+         trailer:  | tNL | tCOMMA
+
+            term: tSEMI
+                  {
+                    yyerrok
+                  }
+                | tNL
+
+           terms: term
+                | terms tSEMI
+
+            none: # nothing
+                  {
+                    result = nil
+                  }
+end
+
+---- header
+
+require 'parser'
+
+Parser.check_for_encoding_support
+
+---- inner
+
+  def version
+    21
+  end
+
+  def default_encoding
+    Encoding::UTF_8
+  end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/ruby22.y b/app/server/vendor/parser-2.2.2.1/lib/parser/ruby22.y
new file mode 100644
index 0000000..60ae154
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/ruby22.y
@@ -0,0 +1,2342 @@
+class Parser::Ruby22
+
+token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
+      kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
+      kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
+      kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
+      kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
+      k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
+      tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
+      tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
+      tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
+      tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
+      tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
+      tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
+      tDSTAR tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
+      tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT
+      tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DBEG
+      tSTRING_DVAR tSTRING_END tSTRING_DEND tSTRING tSYMBOL
+      tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG tCHARACTER
+      tRATIONAL tIMAGINARY tLABEL_END
+
+prechigh
+  right    tBANG tTILDE tUPLUS
+  right    tPOW
+  right    tUMINUS_NUM tUMINUS
+  left     tSTAR2 tDIVIDE tPERCENT
+  left     tPLUS tMINUS
+  left     tLSHFT tRSHFT
+  left     tAMPER2
+  left     tPIPE tCARET
+  left     tGT tGEQ tLT tLEQ
+  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
+  left     tANDOP
+  left     tOROP
+  nonassoc tDOT2 tDOT3
+  right    tEH tCOLON
+  left     kRESCUE_MOD
+  right    tEQL tOP_ASGN
+  nonassoc kDEFINED
+  right    kNOT
+  left     kOR kAND
+  nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
+  nonassoc tLBRACE_ARG
+  nonassoc tLOWEST
+preclow
+
+rule
+
+         program: top_compstmt
+
+    top_compstmt: top_stmts opt_terms
+                    {
+                      result = @builder.compstmt(val[0])
+                    }
+
+       top_stmts: # nothing
+                    {
+                      result = []
+                    }
+                | top_stmt
+                    {
+                      result = [ val[0] ]
+                    }
+                | top_stmts terms top_stmt
+                    {
+                      result = val[0] << val[2]
+                    }
+                | error top_stmt
+                    {
+                      result = [ val[1] ]
+                    }
+
+        top_stmt: stmt
+                | klBEGIN tLCURLY top_compstmt tRCURLY
+                    {
+                      result = @builder.preexe(val[0], val[1], val[2], val[3])
+                    }
+
+        bodystmt: compstmt opt_rescue opt_else opt_ensure
+                    {
+                      rescue_bodies     = val[1]
+                      else_t,   else_   = val[2]
+                      ensure_t, ensure_ = val[3]
+
+                      if rescue_bodies.empty? && !else_.nil?
+                        diagnostic :warning, :useless_else, nil, else_t
+                      end
+
+                      result = @builder.begin_body(val[0],
+                                  rescue_bodies,
+                                  else_t,   else_,
+                                  ensure_t, ensure_)
+                    }
+
+        compstmt: stmts opt_terms
+                    {
+                      result = @builder.compstmt(val[0])
+                    }
+
+           stmts: # nothing
+                    {
+                      result = []
+                    }
+                | stmt_or_begin
+                    {
+                      result = [ val[0] ]
+                    }
+                | stmts terms stmt_or_begin
+                    {
+                      result = val[0] << val[2]
+                    }
+                | error stmt
+                    {
+                      result = [ val[1] ]
+                    }
+
+   stmt_or_begin: stmt
+                | klBEGIN tLCURLY top_compstmt tRCURLY
+                    {
+                      diagnostic :error, :begin_in_method, nil, val[0]
+                    }
+
+            stmt: kALIAS fitem
+                    {
+                      @lexer.state = :expr_fname
+                    }
+                    fitem
+                    {
+                      result = @builder.alias(val[0], val[1], val[3])
+                    }
+                | kALIAS tGVAR tGVAR
+                    {
+                      result = @builder.alias(val[0],
+                                  @builder.gvar(val[1]),
+                                  @builder.gvar(val[2]))
+                    }
+                | kALIAS tGVAR tBACK_REF
+                    {
+                      result = @builder.alias(val[0],
+                                  @builder.gvar(val[1]),
+                                  @builder.back_ref(val[2]))
+                    }
+                | kALIAS tGVAR tNTH_REF
+                    {
+                      diagnostic :error, :nth_ref_alias, nil, val[2]
+                    }
+                | kUNDEF undef_list
+                    {
+                      result = @builder.undef_method(val[0], val[1])
+                    }
+                | stmt kIF_MOD expr_value
+                    {
+                      result = @builder.condition_mod(val[0], nil,
+                                                      val[1], val[2])
+                    }
+                | stmt kUNLESS_MOD expr_value
+                    {
+                      result = @builder.condition_mod(nil, val[0],
+                                                      val[1], val[2])
+                    }
+                | stmt kWHILE_MOD expr_value
+                    {
+                      result = @builder.loop_mod(:while, val[0], val[1], val[2])
+                    }
+                | stmt kUNTIL_MOD expr_value
+                    {
+                      result = @builder.loop_mod(:until, val[0], val[1], val[2])
+                    }
+                | stmt kRESCUE_MOD stmt
+                    {
+                      rescue_body = @builder.rescue_body(val[1],
+                                        nil, nil, nil,
+                                        nil, val[2])
+
+                      result = @builder.begin_body(val[0], [ rescue_body ])
+                    }
+                | klEND tLCURLY compstmt tRCURLY
+                    {
+                      result = @builder.postexe(val[0], val[1], val[2], val[3])
+                    }
+                | command_asgn
+                | mlhs tEQL command_call
+                    {
+                      result = @builder.multi_assign(val[0], val[1], val[2])
+                    }
+                | var_lhs tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.index(
+                                    val[0], val[1], val[2], val[3]),
+                                  val[4], val[5])
+                    }
+                | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tDOT tCONSTANT tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | backref tOP_ASGN command_call
+                    {
+                      @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | lhs tEQL mrhs
+                    {
+                      result = @builder.assign(val[0], val[1],
+                                  @builder.array(nil, val[2], nil))
+                    }
+                | mlhs tEQL mrhs_arg
+                    {
+                      result = @builder.multi_assign(val[0], val[1], val[2])
+                    }
+                | expr
+
+    command_asgn: lhs tEQL command_call
+                    {
+                      result = @builder.assign(val[0], val[1], val[2])
+                    }
+                | lhs tEQL command_asgn
+                    {
+                      result = @builder.assign(val[0], val[1], val[2])
+                    }
+
+            expr: command_call
+                | expr kAND expr
+                    {
+                      result = @builder.logical_op(:and, val[0], val[1], val[2])
+                    }
+                | expr kOR expr
+                    {
+                      result = @builder.logical_op(:or, val[0], val[1], val[2])
+                    }
+                | kNOT opt_nl expr
+                    {
+                      result = @builder.not_op(val[0], nil, val[2], nil)
+                    }
+                | tBANG command_call
+                    {
+                      result = @builder.not_op(val[0], nil, val[1], nil)
+                    }
+                | arg
+
+      expr_value: expr
+
+    command_call: command
+                | block_command
+
+   block_command: block_call
+                | block_call dot_or_colon operation2 command_args
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  nil, val[3], nil)
+                    }
+
+ cmd_brace_block: tLBRACE_ARG
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_param compstmt tRCURLY
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+
+           fcall: operation
+
+         command: fcall command_args =tLOWEST
+                    {
+                      result = @builder.call_method(nil, nil, val[0],
+                                  nil, val[1], nil)
+                    }
+                | fcall command_args cmd_brace_block
+                    {
+                      method_call = @builder.call_method(nil, nil, val[0],
+                                        nil, val[1], nil)
+
+                      begin_t, args, body, end_t = val[2]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | primary_value tDOT operation2 command_args =tLOWEST
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  nil, val[3], nil)
+                    }
+                | primary_value tDOT operation2 command_args cmd_brace_block
+                    {
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                        nil, val[3], nil)
+
+                      begin_t, args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | primary_value tCOLON2 operation2 command_args =tLOWEST
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  nil, val[3], nil)
+                    }
+                | primary_value tCOLON2 operation2 command_args cmd_brace_block
+                    {
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                        nil, val[3], nil)
+
+                      begin_t, args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | kSUPER command_args
+                    {
+                      result = @builder.keyword_cmd(:super, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kYIELD command_args
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kRETURN call_args
+                    {
+                      result = @builder.keyword_cmd(:return, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kBREAK call_args
+                    {
+                      result = @builder.keyword_cmd(:break, val[0],
+                                  nil, val[1], nil)
+                    }
+                | kNEXT call_args
+                    {
+                      result = @builder.keyword_cmd(:next, val[0],
+                                  nil, val[1], nil)
+                    }
+
+            mlhs: mlhs_basic
+                    {
+                      result = @builder.multi_lhs(nil, val[0], nil)
+                    }
+                | tLPAREN mlhs_inner rparen
+                    {
+                      result = @builder.begin(val[0], val[1], val[2])
+                    }
+
+      mlhs_inner: mlhs_basic
+                    {
+                      result = @builder.multi_lhs(nil, val[0], nil)
+                    }
+                | tLPAREN mlhs_inner rparen
+                    {
+                      result = @builder.multi_lhs(val[0], val[1], val[2])
+                    }
+
+      mlhs_basic: mlhs_head
+                | mlhs_head mlhs_item
+                    {
+                      result = val[0].
+                                  push(val[1])
+                    }
+                | mlhs_head tSTAR mlhs_node
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1], val[2]))
+                    }
+                | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1], val[2])).
+                                  concat(val[4])
+                    }
+                | mlhs_head tSTAR
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1]))
+                    }
+                | mlhs_head tSTAR tCOMMA mlhs_post
+                    {
+                      result = val[0].
+                                  push(@builder.splat(val[1])).
+                                  concat(val[3])
+                    }
+                | tSTAR mlhs_node
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+                | tSTAR mlhs_node tCOMMA mlhs_post
+                    {
+                      result = [ @builder.splat(val[0], val[1]),
+                                 *val[3] ]
+                    }
+                | tSTAR
+                    {
+                      result = [ @builder.splat(val[0]) ]
+                    }
+                | tSTAR tCOMMA mlhs_post
+                    {
+                      result = [ @builder.splat(val[0]),
+                                 *val[2] ]
+                    }
+
+       mlhs_item: mlhs_node
+                | tLPAREN mlhs_inner rparen
+                    {
+                      result = @builder.begin(val[0], val[1], val[2])
+                    }
+
+       mlhs_head: mlhs_item tCOMMA
+                    {
+                      result = [ val[0] ]
+                    }
+                | mlhs_head mlhs_item tCOMMA
+                    {
+                      result = val[0] << val[1]
+                    }
+
+       mlhs_post: mlhs_item
+                    {
+                      result = [ val[0] ]
+                    }
+                | mlhs_post tCOMMA mlhs_item
+                    {
+                      result = val[0] << val[2]
+                    }
+
+       mlhs_node: user_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket
+                    {
+                      result = @builder.index_asgn(val[0], val[1], val[2], val[3])
+                    }
+                | primary_value tDOT tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tDOT tCONSTANT
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_fetch(val[0], val[1], val[2]))
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_global(val[0], val[1]))
+                    }
+                | backref
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+
+             lhs: user_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket
+                    {
+                      result = @builder.index_asgn(val[0], val[1], val[2], val[3])
+                    }
+                | primary_value tDOT tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tDOT tCONSTANT
+                    {
+                      result = @builder.attr_asgn(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_fetch(val[0], val[1], val[2]))
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      result = @builder.assignable(
+                                  @builder.const_global(val[0], val[1]))
+                    }
+                | backref
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+
+           cname: tIDENTIFIER
+                    {
+                      diagnostic :error, :module_name_const, nil, val[0]
+                    }
+                | tCONSTANT
+
+           cpath: tCOLON3 cname
+                    {
+                      result = @builder.const_global(val[0], val[1])
+                    }
+                | cname
+                    {
+                      result = @builder.const(val[0])
+                    }
+                | primary_value tCOLON2 cname
+                    {
+                      result = @builder.const_fetch(val[0], val[1], val[2])
+                    }
+
+           fname: tIDENTIFIER | tCONSTANT | tFID
+                | op
+                | reswords
+
+            fsym: fname
+                    {
+                      result = @builder.symbol(val[0])
+                    }
+                | symbol
+
+           fitem: fsym
+                | dsym
+
+      undef_list: fitem
+                    {
+                      result = [ val[0] ]
+                    }
+                | undef_list tCOMMA
+                    {
+                      @lexer.state = :expr_fname
+                    }
+                    fitem
+                    {
+                      result = val[0] << val[3]
+                    }
+
+              op:   tPIPE    | tCARET  | tAMPER2  | tCMP  | tEQ     | tEQQ
+                |   tMATCH   | tNMATCH | tGT      | tGEQ  | tLT     | tLEQ
+                |   tNEQ     | tLSHFT  | tRSHFT   | tPLUS | tMINUS  | tSTAR2
+                |   tSTAR    | tDIVIDE | tPERCENT | tPOW  | tBANG   | tTILDE
+                |   tUPLUS   | tUMINUS | tAREF    | tASET | tDSTAR  | tBACK_REF2
+
+        reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
+                | kALIAS    | kAND      | kBEGIN        | kBREAK  | kCASE
+                | kCLASS    | kDEF      | kDEFINED      | kDO     | kELSE
+                | kELSIF    | kEND      | kENSURE       | kFALSE  | kFOR
+                | kIN       | kMODULE   | kNEXT         | kNIL    | kNOT
+                | kOR       | kREDO     | kRESCUE       | kRETRY  | kRETURN
+                | kSELF     | kSUPER    | kTHEN         | kTRUE   | kUNDEF
+                | kWHEN     | kYIELD    | kIF           | kUNLESS | kWHILE
+                | kUNTIL
+
+             arg: lhs tEQL arg
+                    {
+                      result = @builder.assign(val[0], val[1], val[2])
+                    }
+                | lhs tEQL arg kRESCUE_MOD arg
+                    {
+                      rescue_body = @builder.rescue_body(val[3],
+                                        nil, nil, nil,
+                                        nil, val[4])
+
+                      rescue_ = @builder.begin_body(val[2], [ rescue_body ])
+
+                      result  = @builder.assign(val[0], val[1], rescue_)
+                    }
+                | var_lhs tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | var_lhs tOP_ASGN arg kRESCUE_MOD arg
+                    {
+                      rescue_body = @builder.rescue_body(val[3],
+                                        nil, nil, nil,
+                                        nil, val[4])
+
+                      rescue_ = @builder.begin_body(val[2], [ rescue_body ])
+
+                      result = @builder.op_assign(val[0], val[1], rescue_)
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.index(
+                                    val[0], val[1], val[2], val[3]),
+                                  val[4], val[5])
+                    }
+                | primary_value tDOT tIDENTIFIER tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tDOT tCONSTANT tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(
+                                  @builder.call_method(
+                                    val[0], val[1], val[2]),
+                                  val[3], val[4])
+                    }
+                | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
+                    {
+                      const  = @builder.const_op_assignable(
+                                  @builder.const_fetch(val[0], val[1], val[2]))
+                      result = @builder.op_assign(const, val[3], val[4])
+                    }
+                | tCOLON3 tCONSTANT tOP_ASGN arg
+                    {
+                      const  = @builder.const_op_assignable(
+                                  @builder.const_global(val[0], val[1]))
+                      result = @builder.op_assign(const, val[2], val[3])
+                    }
+                | backref tOP_ASGN arg
+                    {
+                      result = @builder.op_assign(val[0], val[1], val[2])
+                    }
+                | arg tDOT2 arg
+                    {
+                      result = @builder.range_inclusive(val[0], val[1], val[2])
+                    }
+                | arg tDOT3 arg
+                    {
+                      result = @builder.range_exclusive(val[0], val[1], val[2])
+                    }
+                | arg tPLUS arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tMINUS arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tSTAR2 arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tDIVIDE arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tPERCENT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tPOW arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | tUMINUS_NUM simple_numeric tPOW arg
+                    {
+                      result = @builder.unary_op(val[0],
+                                  @builder.binary_op(
+                                    val[1], val[2], val[3]))
+                    }
+                | tUPLUS arg
+                    {
+                      result = @builder.unary_op(val[0], val[1])
+                    }
+                | tUMINUS arg
+                    {
+                      result = @builder.unary_op(val[0], val[1])
+                    }
+                | arg tPIPE arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tCARET arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tAMPER2 arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tCMP arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tGT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tGEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tLT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tLEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tEQQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tNEQ arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tMATCH arg
+                    {
+                      result = @builder.match_op(val[0], val[1], val[2])
+                    }
+                | arg tNMATCH arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | tBANG arg
+                    {
+                      result = @builder.not_op(val[0], nil, val[1], nil)
+                    }
+                | tTILDE arg
+                    {
+                      result = @builder.unary_op(val[0], val[1])
+                    }
+                | arg tLSHFT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tRSHFT arg
+                    {
+                      result = @builder.binary_op(val[0], val[1], val[2])
+                    }
+                | arg tANDOP arg
+                    {
+                      result = @builder.logical_op(:and, val[0], val[1], val[2])
+                    }
+                | arg tOROP arg
+                    {
+                      result = @builder.logical_op(:or, val[0], val[1], val[2])
+                    }
+                | kDEFINED opt_nl arg
+                    {
+                      result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
+                    }
+
+                | arg tEH
+                    {
+                      @lexer.push_cond
+                      @lexer.cond.push(true)
+                    }
+                  arg opt_nl tCOLON
+                    {
+                      @lexer.pop_cond
+                    }
+                  arg
+                    {
+                      result = @builder.ternary(val[0], val[1],
+                                                val[3], val[5], val[7])
+                    }
+                | primary
+
+       arg_value: arg
+
+       aref_args: none
+                | args trailer
+                | args tCOMMA assocs trailer
+                    {
+                      result = val[0] << @builder.associate(nil, val[2], nil)
+                    }
+                | assocs trailer
+                    {
+                      result = [ @builder.associate(nil, val[0], nil) ]
+                    }
+
+      paren_args: tLPAREN2 opt_call_args rparen
+                    {
+                      result = val
+                    }
+
+  opt_paren_args: # nothing
+                    {
+                      result = [ nil, [], nil ]
+                    }
+                | paren_args
+
+   opt_call_args: # nothing
+                    {
+                      result = []
+                    }
+                | call_args
+                | args tCOMMA
+                | args tCOMMA assocs tCOMMA
+                    {
+                      result = val[0] << @builder.associate(nil, val[2], nil)
+                    }
+                | assocs tCOMMA
+                    {
+                      result = [ @builder.associate(nil, val[0], nil) ]
+                    }
+
+       call_args: command
+                    {
+                      result = [ val[0] ]
+                    }
+                | args opt_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | assocs opt_block_arg
+                    {
+                      result = [ @builder.associate(nil, val[0], nil) ]
+                      result.concat(val[1])
+                    }
+                | args tCOMMA assocs opt_block_arg
+                    {
+                      assocs = @builder.associate(nil, val[2], nil)
+                      result = val[0] << assocs
+                      result.concat(val[3])
+                    }
+                | block_arg
+                    {
+                      result =  [ val[0] ]
+                    }
+
+    command_args:   {
+                      result = @lexer.cmdarg.dup
+                      @lexer.cmdarg.push(true)
+                    }
+                  call_args
+                    {
+                      @lexer.cmdarg = val[0]
+
+                      result = val[1]
+                    }
+
+       block_arg: tAMPER arg_value
+                    {
+                      result = @builder.block_pass(val[0], val[1])
+                    }
+
+   opt_block_arg: tCOMMA block_arg
+                    {
+                      result = [ val[1] ]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+            args: arg_value
+                    {
+                      result = [ val[0] ]
+                    }
+                | tSTAR arg_value
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+                | args tCOMMA arg_value
+                    {
+                      result = val[0] << val[2]
+                    }
+                | args tCOMMA tSTAR arg_value
+                    {
+                      result = val[0] << @builder.splat(val[2], val[3])
+                    }
+
+        mrhs_arg: mrhs
+                    {
+                      result = @builder.array(nil, val[0], nil)
+                    }
+                | arg_value
+
+            mrhs: args tCOMMA arg_value
+                    {
+                      result = val[0] << val[2]
+                    }
+                | args tCOMMA tSTAR arg_value
+                    {
+                      result = val[0] << @builder.splat(val[2], val[3])
+                    }
+                | tSTAR arg_value
+                    {
+                      result = [ @builder.splat(val[0], val[1]) ]
+                    }
+
+         primary: literal
+                | strings
+                | xstring
+                | regexp
+                | words
+                | qwords
+                | symbols
+                | qsymbols
+                | var_ref
+                | backref
+                | tFID
+                    {
+                      result = @builder.call_method(nil, nil, val[0])
+                    }
+                | kBEGIN
+                    {
+                      result = @lexer.cmdarg.dup
+                      @lexer.cmdarg.clear
+                    }
+                    bodystmt kEND
+                    {
+                      @lexer.cmdarg = val[1]
+
+                      result = @builder.begin_keyword(val[0], val[2], val[3])
+                    }
+                | tLPAREN_ARG
+                    {
+                      result = @lexer.cmdarg.dup
+                      @lexer.cmdarg.clear
+                    }
+                    expr
+                    {
+                      @lexer.state = :expr_endarg
+                    }
+                    opt_nl tRPAREN
+                    {
+                      @lexer.cmdarg = val[1]
+
+                      result = @builder.begin(val[0], val[2], val[5])
+                    }
+                | tLPAREN_ARG
+                    {
+                      @lexer.state = :expr_endarg
+                    }
+                    opt_nl tRPAREN
+                    {
+                      result = @builder.begin(val[0], nil, val[3])
+                    }
+                | tLPAREN compstmt tRPAREN
+                    {
+                      result = @builder.begin(val[0], val[1], val[2])
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      result = @builder.const_fetch(val[0], val[1], val[2])
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      result = @builder.const_global(val[0], val[1])
+                    }
+                | tLBRACK aref_args tRBRACK
+                    {
+                      result = @builder.array(val[0], val[1], val[2])
+                    }
+                | tLBRACE assoc_list tRCURLY
+                    {
+                      result = @builder.associate(val[0], val[1], val[2])
+                    }
+                | kRETURN
+                    {
+                      result = @builder.keyword_cmd(:return, val[0])
+                    }
+                | kYIELD tLPAREN2 call_args rparen
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
+                    }
+                | kYIELD tLPAREN2 rparen
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
+                    }
+                | kYIELD
+                    {
+                      result = @builder.keyword_cmd(:yield, val[0])
+                    }
+                | kDEFINED opt_nl tLPAREN2 expr rparen
+                    {
+                      result = @builder.keyword_cmd(:defined?, val[0],
+                                                    val[2], [ val[3] ], val[4])
+                    }
+                | kNOT tLPAREN2 expr rparen
+                    {
+                      result = @builder.not_op(val[0], val[1], val[2], val[3])
+                    }
+                | kNOT tLPAREN2 rparen
+                    {
+                      result = @builder.not_op(val[0], val[1], nil, val[2])
+                    }
+                | fcall brace_block
+                    {
+                      method_call = @builder.call_method(nil, nil, val[0])
+
+                      begin_t, args, body, end_t = val[1]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | method_call
+                | method_call brace_block
+                    {
+                      begin_t, args, body, end_t = val[1]
+                      result      = @builder.block(val[0],
+                                      begin_t, args, body, end_t)
+                    }
+                | tLAMBDA lambda
+                    {
+                      lambda_call = @builder.call_lambda(val[0])
+
+                      args, (begin_t, body, end_t) = val[1]
+                      result      = @builder.block(lambda_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | kIF expr_value then compstmt if_tail kEND
+                    {
+                      else_t, else_ = val[4]
+                      result = @builder.condition(val[0], val[1], val[2],
+                                                  val[3], else_t,
+                                                  else_,  val[5])
+                    }
+                | kUNLESS expr_value then compstmt opt_else kEND
+                    {
+                      else_t, else_ = val[4]
+                      result = @builder.condition(val[0], val[1], val[2],
+                                                  else_,  else_t,
+                                                  val[3], val[5])
+                    }
+                | kWHILE
+                    {
+                      @lexer.cond.push(true)
+                    }
+                    expr_value do
+                    {
+                      @lexer.cond.pop
+                    }
+                    compstmt kEND
+                    {
+                      result = @builder.loop(:while, val[0], val[2], val[3],
+                                             val[5], val[6])
+                    }
+                | kUNTIL
+                    {
+                      @lexer.cond.push(true)
+                    }
+                    expr_value do
+                    {
+                      @lexer.cond.pop
+                    }
+                    compstmt kEND
+                    {
+                      result = @builder.loop(:until, val[0], val[2], val[3],
+                                             val[5], val[6])
+                    }
+                | kCASE expr_value opt_terms case_body kEND
+                    {
+                      *when_bodies, (else_t, else_body) = *val[3]
+
+                      result = @builder.case(val[0], val[1],
+                                             when_bodies, else_t, else_body,
+                                             val[4])
+                    }
+                | kCASE            opt_terms case_body kEND
+                    {
+                      *when_bodies, (else_t, else_body) = *val[2]
+
+                      result = @builder.case(val[0], nil,
+                                             when_bodies, else_t, else_body,
+                                             val[3])
+                    }
+                | kFOR for_var kIN
+                    {
+                      @lexer.cond.push(true)
+                    }
+                    expr_value do
+                    {
+                      @lexer.cond.pop
+                    }
+                    compstmt kEND
+                    {
+                      result = @builder.for(val[0], val[1],
+                                            val[2], val[4],
+                                            val[5], val[7], val[8])
+                    }
+                | kCLASS cpath superclass
+                    {
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    bodystmt kEND
+                    {
+                      if in_def?
+                        diagnostic :error, :class_in_def, nil, val[0]
+                      end
+
+                      lt_t, superclass = val[2]
+                      result = @builder.def_class(val[0], val[1],
+                                                  lt_t, superclass,
+                                                  val[4], val[5])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                    }
+                | kCLASS tLSHFT expr term
+                    {
+                      result = @def_level
+                      @def_level = 0
+
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    bodystmt kEND
+                    {
+                      result = @builder.def_sclass(val[0], val[1], val[2],
+                                                   val[5], val[6])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+
+                      @def_level = val[4]
+                    }
+                | kMODULE cpath
+                    {
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    bodystmt kEND
+                    {
+                      if in_def?
+                        diagnostic :error, :module_in_def, nil, val[0]
+                      end
+
+                      result = @builder.def_module(val[0], val[1],
+                                                   val[3], val[4])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                    }
+                | kDEF fname
+                    {
+                      @def_level += 1
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    f_arglist bodystmt kEND
+                    {
+                      result = @builder.def_method(val[0], val[1],
+                                  val[3], val[4], val[5])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                      @def_level -= 1
+                    }
+                | kDEF singleton dot_or_colon
+                    {
+                      @lexer.state = :expr_fname
+                    }
+                    fname
+                    {
+                      @def_level += 1
+                      @static_env.extend_static
+                      @lexer.push_cmdarg
+                    }
+                    f_arglist bodystmt kEND
+                    {
+                      result = @builder.def_singleton(val[0], val[1], val[2],
+                                  val[4], val[6], val[7], val[8])
+
+                      @lexer.pop_cmdarg
+                      @static_env.unextend
+                      @def_level -= 1
+                    }
+                | kBREAK
+                    {
+                      result = @builder.keyword_cmd(:break, val[0])
+                    }
+                | kNEXT
+                    {
+                      result = @builder.keyword_cmd(:next, val[0])
+                    }
+                | kREDO
+                    {
+                      result = @builder.keyword_cmd(:redo, val[0])
+                    }
+                | kRETRY
+                    {
+                      result = @builder.keyword_cmd(:retry, val[0])
+                    }
+
+   primary_value: primary
+
+            then: term
+                | kTHEN
+                | term kTHEN
+                    {
+                      result = val[1]
+                    }
+
+              do: term
+                | kDO_COND
+
+         if_tail: opt_else
+                | kELSIF expr_value then compstmt if_tail
+                    {
+                      else_t, else_ = val[4]
+                      result = [ val[0],
+                                 @builder.condition(val[0], val[1], val[2],
+                                                    val[3], else_t,
+                                                    else_,  nil),
+                               ]
+                    }
+
+        opt_else: none
+                | kELSE compstmt
+                    {
+                      result = val
+                    }
+
+         for_var: lhs
+                | mlhs
+
+          f_marg: f_norm_arg
+                    {
+                      result = @builder.arg(val[0])
+                    }
+                | tLPAREN f_margs rparen
+                    {
+                      result = @builder.multi_lhs(val[0], val[1], val[2])
+                    }
+
+     f_marg_list: f_marg
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_marg_list tCOMMA f_marg
+                    {
+                      result = val[0] << val[2]
+                    }
+
+         f_margs: f_marg_list
+                | f_marg_list tCOMMA tSTAR f_norm_arg
+                    {
+                      result = val[0].
+                                  push(@builder.restarg(val[2], val[3]))
+                    }
+                | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
+                    {
+                      result = val[0].
+                                  push(@builder.restarg(val[2], val[3])).
+                                  concat(val[5])
+                    }
+                | f_marg_list tCOMMA tSTAR
+                    {
+                      result = val[0].
+                                  push(@builder.restarg(val[2]))
+                    }
+                | f_marg_list tCOMMA tSTAR            tCOMMA f_marg_list
+                    {
+                      result = val[0].
+                                  push(@builder.restarg(val[2])).
+                                  concat(val[4])
+                    }
+                |                    tSTAR f_norm_arg
+                    {
+                      result = [ @builder.restarg(val[0], val[1]) ]
+                    }
+                |                    tSTAR f_norm_arg tCOMMA f_marg_list
+                    {
+                      result = [ @builder.restarg(val[0], val[1]),
+                                 *val[3] ]
+                    }
+                |                    tSTAR
+                    {
+                      result = [ @builder.restarg(val[0]) ]
+                    }
+                |                    tSTAR tCOMMA f_marg_list
+                    {
+                      result = [ @builder.restarg(val[0]),
+                                 *val[2] ]
+                    }
+
+ block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
+                    {
+                      result = val[0].concat(val[2]).concat(val[3])
+                    }
+                | f_block_kwarg opt_f_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_kwrest opt_f_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_block_arg
+                    {
+                      result = [ val[0] ]
+                    }
+
+opt_block_args_tail:
+                  tCOMMA block_args_tail
+                    {
+                      result = val[1]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+     block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg              opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[6]).
+                                  concat(val[7])
+                    }
+                | f_arg tCOMMA f_block_optarg                                opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA f_block_optarg tCOMMA                   f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA                       f_rest_arg              opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA
+                | f_arg tCOMMA                       f_rest_arg tCOMMA f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg                                                      opt_block_args_tail
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_block_optarg tCOMMA              f_rest_arg              opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_block_optarg tCOMMA              f_rest_arg tCOMMA f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_block_optarg                                             opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                | f_block_optarg tCOMMA                                f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                                    f_rest_arg              opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |                                    f_rest_arg tCOMMA f_arg opt_block_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                                                                block_args_tail
+
+ opt_block_param: # nothing
+                    {
+                      result = @builder.args(nil, [], nil)
+                    }
+                | block_param_def
+                    {
+                      @lexer.state = :expr_value
+                    }
+
+ block_param_def: tPIPE opt_bv_decl tPIPE
+                    {
+                      result = @builder.args(val[0], val[1], val[2])
+                    }
+                | tOROP
+                    {
+                      result = @builder.args(val[0], [], val[0])
+                    }
+                | tPIPE block_param opt_bv_decl tPIPE
+                    {
+                      result = @builder.args(val[0], val[1].concat(val[2]), val[3])
+                    }
+
+     opt_bv_decl: opt_nl
+                    {
+                      result = []
+                    }
+                | opt_nl tSEMI bv_decls opt_nl
+                    {
+                      result = val[2]
+                    }
+
+        bv_decls: bvar
+                    {
+                      result = [ val[0] ]
+                    }
+                | bv_decls tCOMMA bvar
+                    {
+                      result = val[0] << val[2]
+                    }
+
+            bvar: tIDENTIFIER
+                    {
+                      result = @builder.shadowarg(val[0])
+                    }
+                | f_bad_arg
+
+          lambda:   {
+                      @static_env.extend_dynamic
+                    }
+                  f_larglist lambda_body
+                    {
+                      result = [ val[1], val[2] ]
+
+                      @static_env.unextend
+                    }
+
+     f_larglist: tLPAREN2 f_args opt_bv_decl tRPAREN
+                    {
+                      result = @builder.args(val[0], val[1].concat(val[2]), val[3])
+                    }
+                | f_args
+                    {
+                      result = @builder.args(nil, val[0], nil)
+                    }
+
+     lambda_body: tLAMBEG compstmt tRCURLY
+                    {
+                      result = [ val[0], val[1], val[2] ]
+                    }
+                | kDO_LAMBDA compstmt kEND
+                    {
+                      result = [ val[0], val[1], val[2] ]
+                    }
+
+        do_block: kDO_BLOCK
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_param compstmt kEND
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+
+      block_call: command do_block
+                    {
+                      begin_t, block_args, body, end_t = val[1]
+                      result      = @builder.block(val[0],
+                                      begin_t, block_args, body, end_t)
+                    }
+                | block_call dot_or_colon operation2 opt_paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | block_call dot_or_colon operation2 opt_paren_args brace_block
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                      lparen_t, args, rparen_t)
+
+                      begin_t, args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+                | block_call dot_or_colon operation2 command_args do_block
+                    {
+                      method_call = @builder.call_method(val[0], val[1], val[2],
+                                      nil, val[3], nil)
+
+                      begin_t, args, body, end_t = val[4]
+                      result      = @builder.block(method_call,
+                                      begin_t, args, body, end_t)
+                    }
+
+     method_call: fcall paren_args
+                    {
+                      lparen_t, args, rparen_t = val[1]
+                      result = @builder.call_method(nil, nil, val[0],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tDOT operation2 opt_paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tCOLON2 operation2 paren_args
+                    {
+                      lparen_t, args, rparen_t = val[3]
+                      result = @builder.call_method(val[0], val[1], val[2],
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tCOLON2 operation3
+                    {
+                      result = @builder.call_method(val[0], val[1], val[2])
+                    }
+                | primary_value tDOT paren_args
+                    {
+                      lparen_t, args, rparen_t = val[2]
+                      result = @builder.call_method(val[0], val[1], nil,
+                                  lparen_t, args, rparen_t)
+                    }
+                | primary_value tCOLON2 paren_args
+                    {
+                      lparen_t, args, rparen_t = val[2]
+                      result = @builder.call_method(val[0], val[1], nil,
+                                  lparen_t, args, rparen_t)
+                    }
+                | kSUPER paren_args
+                    {
+                      lparen_t, args, rparen_t = val[1]
+                      result = @builder.keyword_cmd(:super, val[0],
+                                  lparen_t, args, rparen_t)
+                    }
+                | kSUPER
+                    {
+                      result = @builder.keyword_cmd(:zsuper, val[0])
+                    }
+                | primary_value tLBRACK2 opt_call_args rbracket
+                    {
+                      result = @builder.index(val[0], val[1], val[2], val[3])
+                    }
+
+     brace_block: tLCURLY
+                    {
+                      @static_env.extend_dynamic
+                    }
+                    opt_block_param compstmt tRCURLY
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+                | kDO
+                    {
+                      @static_env.extend_dynamic
+                    }
+                 opt_block_param compstmt kEND
+                    {
+                      result = [ val[0], val[2], val[3], val[4] ]
+
+                      @static_env.unextend
+                    }
+
+       case_body: kWHEN args then compstmt cases
+                    {
+                      result = [ @builder.when(val[0], val[1], val[2], val[3]),
+                                 *val[4] ]
+                    }
+
+           cases: opt_else
+                    {
+                      result = [ val[0] ]
+                    }
+                | case_body
+
+      opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
+                    {
+                      assoc_t, exc_var = val[2]
+
+                      if val[1]
+                        exc_list = @builder.array(nil, val[1], nil)
+                      end
+
+                      result = [ @builder.rescue_body(val[0],
+                                      exc_list, assoc_t, exc_var,
+                                      val[3], val[4]),
+                                 *val[5] ]
+                    }
+                |
+                    {
+                      result = []
+                    }
+
+        exc_list: arg_value
+                    {
+                      result = [ val[0] ]
+                    }
+                | mrhs
+                | none
+
+         exc_var: tASSOC lhs
+                    {
+                      result = [ val[0], val[1] ]
+                    }
+                | none
+
+      opt_ensure: kENSURE compstmt
+                    {
+                      result = [ val[0], val[1] ]
+                    }
+                | none
+
+         literal: numeric
+                | symbol
+                | dsym
+
+         strings: string
+                    {
+                      result = @builder.string_compose(nil, val[0], nil)
+                    }
+
+          string: string1
+                    {
+                      result = [ val[0] ]
+                    }
+                | string string1
+                    {
+                      result = val[0] << val[1]
+                    }
+
+         string1: tSTRING_BEG string_contents tSTRING_END
+                    {
+                      result = @builder.string_compose(val[0], val[1], val[2])
+                    }
+                | tSTRING
+                    {
+                      result = @builder.string(val[0])
+                    }
+                | tCHARACTER
+                    {
+                      result = @builder.character(val[0])
+                    }
+
+         xstring: tXSTRING_BEG xstring_contents tSTRING_END
+                    {
+                      result = @builder.xstring_compose(val[0], val[1], val[2])
+                    }
+
+          regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT
+                    {
+                      opts   = @builder.regexp_options(val[3])
+                      result = @builder.regexp_compose(val[0], val[1], val[2], opts)
+                    }
+
+           words: tWORDS_BEG word_list tSTRING_END
+                    {
+                      result = @builder.words_compose(val[0], val[1], val[2])
+                    }
+
+       word_list: # nothing
+                    {
+                      result = []
+                    }
+                | word_list word tSPACE
+                    {
+                      result = val[0] << @builder.word(val[1])
+                    }
+
+            word: string_content
+                    {
+                      result = [ val[0] ]
+                    }
+                | word string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+         symbols: tSYMBOLS_BEG symbol_list tSTRING_END
+                    {
+                      result = @builder.symbols_compose(val[0], val[1], val[2])
+                    }
+
+     symbol_list: # nothing
+                    {
+                      result = []
+                    }
+                | symbol_list word tSPACE
+                    {
+                      result = val[0] << @builder.word(val[1])
+                    }
+
+          qwords: tQWORDS_BEG qword_list tSTRING_END
+                    {
+                      result = @builder.words_compose(val[0], val[1], val[2])
+                    }
+
+        qsymbols: tQSYMBOLS_BEG qsym_list tSTRING_END
+                    {
+                      result = @builder.symbols_compose(val[0], val[1], val[2])
+                    }
+
+      qword_list: # nothing
+                    {
+                      result = []
+                    }
+                | qword_list tSTRING_CONTENT tSPACE
+                    {
+                      result = val[0] << @builder.string_internal(val[1])
+                    }
+
+       qsym_list: # nothing
+                    {
+                      result = []
+                    }
+                | qsym_list tSTRING_CONTENT tSPACE
+                    {
+                      result = val[0] << @builder.symbol_internal(val[1])
+                    }
+
+ string_contents: # nothing
+                    {
+                      result = []
+                    }
+                | string_contents string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+xstring_contents: # nothing
+                    {
+                      result = []
+                    }
+                | xstring_contents string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+regexp_contents: # nothing
+                    {
+                      result = []
+                    }
+                | regexp_contents string_content
+                    {
+                      result = val[0] << val[1]
+                    }
+
+  string_content: tSTRING_CONTENT
+                    {
+                      result = @builder.string_internal(val[0])
+                    }
+                | tSTRING_DVAR string_dvar
+                    {
+                      result = val[1]
+                    }
+                | tSTRING_DBEG
+                    {
+                      @lexer.cond.push(false)
+                      @lexer.cmdarg.push(false)
+                    }
+                    compstmt tSTRING_DEND
+                    {
+                      @lexer.cond.lexpop
+                      @lexer.cmdarg.lexpop
+
+                      result = @builder.begin(val[0], val[2], val[3])
+                    }
+
+     string_dvar: tGVAR
+                    {
+                      result = @builder.gvar(val[0])
+                    }
+                | tIVAR
+                    {
+                      result = @builder.ivar(val[0])
+                    }
+                | tCVAR
+                    {
+                      result = @builder.cvar(val[0])
+                    }
+                | backref
+
+
+          symbol: tSYMBOL
+                    {
+                      result = @builder.symbol(val[0])
+                    }
+
+            dsym: tSYMBEG xstring_contents tSTRING_END
+                    {
+                      result = @builder.symbol_compose(val[0], val[1], val[2])
+                    }
+
+         numeric: simple_numeric
+                    {
+                      result = val[0]
+                    }
+                | tUMINUS_NUM simple_numeric =tLOWEST
+                    {
+                      result = @builder.negate(val[0], val[1])
+                    }
+
+  simple_numeric: tINTEGER
+                    {
+                      result = @builder.integer(val[0])
+                    }
+                | tFLOAT
+                    {
+                      result = @builder.float(val[0])
+                    }
+                | tRATIONAL
+                    {
+                      result = @builder.rational(val[0])
+                    }
+                | tIMAGINARY
+                    {
+                      result = @builder.complex(val[0])
+                    }
+
+   user_variable: tIDENTIFIER
+                    {
+                      result = @builder.ident(val[0])
+                    }
+                | tIVAR
+                    {
+                      result = @builder.ivar(val[0])
+                    }
+                | tGVAR
+                    {
+                      result = @builder.gvar(val[0])
+                    }
+                | tCONSTANT
+                    {
+                      result = @builder.const(val[0])
+                    }
+                | tCVAR
+                    {
+                      result = @builder.cvar(val[0])
+                    }
+
+keyword_variable: kNIL
+                    {
+                      result = @builder.nil(val[0])
+                    }
+                | kSELF
+                    {
+                      result = @builder.self(val[0])
+                    }
+                | kTRUE
+                    {
+                      result = @builder.true(val[0])
+                    }
+                | kFALSE
+                    {
+                      result = @builder.false(val[0])
+                    }
+                | k__FILE__
+                    {
+                      result = @builder.__FILE__(val[0])
+                    }
+                | k__LINE__
+                    {
+                      result = @builder.__LINE__(val[0])
+                    }
+                | k__ENCODING__
+                    {
+                      result = @builder.__ENCODING__(val[0])
+                    }
+
+         var_ref: user_variable
+                    {
+                      result = @builder.accessible(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.accessible(val[0])
+                    }
+
+         var_lhs: user_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+                | keyword_variable
+                    {
+                      result = @builder.assignable(val[0])
+                    }
+
+         backref: tNTH_REF
+                    {
+                      result = @builder.nth_ref(val[0])
+                    }
+                | tBACK_REF
+                    {
+                      result = @builder.back_ref(val[0])
+                    }
+
+      superclass: term
+                    {
+                      result = nil
+                    }
+                | tLT
+                    {
+                      @lexer.state = :expr_value
+                    }
+                    expr_value term
+                    {
+                      result = [ val[0], val[2] ]
+                    }
+                | error term
+                    {
+                      yyerrok
+                      result = nil
+                    }
+
+       f_arglist: tLPAREN2 f_args rparen
+                    {
+                      result = @builder.args(val[0], val[1], val[2])
+
+                      @lexer.state = :expr_value
+                    }
+                |   {
+                      result = @lexer.in_kwarg
+                      @lexer.in_kwarg = true
+                    }
+                  f_args term
+                    {
+                      @lexer.in_kwarg = val[0]
+                      result = @builder.args(nil, val[1], nil)
+                    }
+
+       args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
+                    {
+                      result = val[0].concat(val[2]).concat(val[3])
+                    }
+                | f_kwarg opt_f_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_kwrest opt_f_block_arg
+                    {
+                      result = val[0].concat(val[1])
+                    }
+                | f_block_arg
+                    {
+                      result = [ val[0] ]
+                    }
+
+   opt_args_tail: tCOMMA args_tail
+                    {
+                      result = val[1]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+          f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg              opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[6]).
+                                  concat(val[7])
+                    }
+                | f_arg tCOMMA f_optarg                                opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA f_optarg tCOMMA                   f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg tCOMMA                 f_rest_arg              opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                | f_arg tCOMMA                 f_rest_arg tCOMMA f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                | f_arg                                                opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |              f_optarg tCOMMA f_rest_arg              opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |              f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[4]).
+                                  concat(val[5])
+                    }
+                |              f_optarg                                opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |              f_optarg tCOMMA                   f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                              f_rest_arg              opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[1])
+                    }
+                |                              f_rest_arg tCOMMA f_arg opt_args_tail
+                    {
+                      result = val[0].
+                                  concat(val[2]).
+                                  concat(val[3])
+                    }
+                |                                                          args_tail
+                    {
+                      result = val[0]
+                    }
+                | # nothing
+                    {
+                      result = []
+                    }
+
+       f_bad_arg: tCONSTANT
+                    {
+                      diagnostic :error, :argument_const, nil, val[0]
+                    }
+                | tIVAR
+                    {
+                      diagnostic :error, :argument_ivar, nil, val[0]
+                    }
+                | tGVAR
+                    {
+                      diagnostic :error, :argument_gvar, nil, val[0]
+                    }
+                | tCVAR
+                    {
+                      diagnostic :error, :argument_cvar, nil, val[0]
+                    }
+
+      f_norm_arg: f_bad_arg
+                | tIDENTIFIER
+                    {
+                      @static_env.declare val[0][0]
+
+                      result = val[0]
+                    }
+
+      f_arg_asgn: f_norm_arg
+                    {
+                      result = val[0]
+                    }
+
+      f_arg_item: f_arg_asgn
+                    {
+                      result = @builder.arg(val[0])
+                    }
+                | tLPAREN f_margs rparen
+                    {
+                      result = @builder.multi_lhs(val[0], val[1], val[2])
+                    }
+
+           f_arg: f_arg_item
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_arg tCOMMA f_arg_item
+                    {
+                      result = val[0] << val[2]
+                    }
+
+         f_label: tLABEL
+                    {
+                      check_kwarg_name(val[0])
+
+                      @static_env.declare val[0][0]
+
+                      result = val[0]
+                    }
+
+            f_kw: f_label arg_value
+                    {
+                      result = @builder.kwoptarg(val[0], val[1])
+                    }
+                | f_label
+                    {
+                      result = @builder.kwarg(val[0])
+                    }
+
+      f_block_kw: f_label primary_value
+                    {
+                      result = @builder.kwoptarg(val[0], val[1])
+                    }
+                | f_label
+                    {
+                      result = @builder.kwarg(val[0])
+                    }
+
+   f_block_kwarg: f_block_kw
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_block_kwarg tCOMMA f_block_kw
+                    {
+                      result = val[0] << val[2]
+                    }
+
+         f_kwarg: f_kw
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_kwarg tCOMMA f_kw
+                    {
+                      result = val[0] << val[2]
+                    }
+
+     kwrest_mark: tPOW | tDSTAR
+
+        f_kwrest: kwrest_mark tIDENTIFIER
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = [ @builder.kwrestarg(val[0], val[1]) ]
+                    }
+                | kwrest_mark
+                    {
+                      result = [ @builder.kwrestarg(val[0]) ]
+                    }
+
+           f_opt: f_arg_asgn tEQL arg_value
+                    {
+                      result = @builder.optarg(val[0], val[1], val[2])
+                    }
+
+     f_block_opt: f_arg_asgn tEQL primary_value
+                    {
+                      result = @builder.optarg(val[0], val[1], val[2])
+                    }
+
+  f_block_optarg: f_block_opt
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_block_optarg tCOMMA f_block_opt
+                    {
+                      result = val[0] << val[2]
+                    }
+
+        f_optarg: f_opt
+                    {
+                      result = [ val[0] ]
+                    }
+                | f_optarg tCOMMA f_opt
+                    {
+                      result = val[0] << val[2]
+                    }
+
+    restarg_mark: tSTAR2 | tSTAR
+
+      f_rest_arg: restarg_mark tIDENTIFIER
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = [ @builder.restarg(val[0], val[1]) ]
+                    }
+                | restarg_mark
+                    {
+                      result = [ @builder.restarg(val[0]) ]
+                    }
+
+     blkarg_mark: tAMPER2 | tAMPER
+
+     f_block_arg: blkarg_mark tIDENTIFIER
+                    {
+                      @static_env.declare val[1][0]
+
+                      result = @builder.blockarg(val[0], val[1])
+                    }
+
+ opt_f_block_arg: tCOMMA f_block_arg
+                    {
+                      result = [ val[1] ]
+                    }
+                |
+                    {
+                      result = []
+                    }
+
+       singleton: var_ref
+                | tLPAREN2 expr rparen
+                    {
+                      result = val[1]
+                    }
+
+      assoc_list: # nothing
+                    {
+                      result = []
+                    }
+                | assocs trailer
+
+          assocs: assoc
+                    {
+                      result = [ val[0] ]
+                    }
+                | assocs tCOMMA assoc
+                    {
+                      result = val[0] << val[2]
+                    }
+
+           assoc: arg_value tASSOC arg_value
+                    {
+                      result = @builder.pair(val[0], val[1], val[2])
+                    }
+                | tLABEL arg_value
+                    {
+                      result = @builder.pair_keyword(val[0], val[1])
+                    }
+                | tSTRING_BEG string_contents tLABEL_END arg_value
+                    {
+                      result = @builder.pair_quoted(val[0], val[1], val[2], val[3])
+                    }
+                | tDSTAR arg_value
+                    {
+                      result = @builder.kwsplat(val[0], val[1])
+                    }
+
+       operation: tIDENTIFIER | tCONSTANT | tFID
+      operation2: tIDENTIFIER | tCONSTANT | tFID | op
+      operation3: tIDENTIFIER | tFID | op
+    dot_or_colon: tDOT | tCOLON2
+       opt_terms:  | terms
+          opt_nl:  | tNL
+          rparen: opt_nl tRPAREN
+                    {
+                      result = val[1]
+                    }
+        rbracket: opt_nl tRBRACK
+                    {
+                      result = val[1]
+                    }
+         trailer:  | tNL | tCOMMA
+
+            term: tSEMI
+                  {
+                    yyerrok
+                  }
+                | tNL
+
+           terms: term
+                | terms tSEMI
+
+            none: # nothing
+                  {
+                    result = nil
+                  }
+end
+
+---- header
+
+require 'parser'
+
+Parser.check_for_encoding_support
+
+---- inner
+
+  def version
+    22
+  end
+
+  def default_encoding
+    Encoding::UTF_8
+  end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/runner.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/runner.rb
new file mode 100644
index 0000000..04fbe64
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/runner.rb
@@ -0,0 +1,219 @@
+require 'benchmark'
+require 'find'
+require 'optparse'
+
+require 'parser'
+
+module Parser
+
+  class Runner
+    def self.go(options)
+      new.execute(options)
+    end
+
+    def initialize
+      @option_parser = OptionParser.new { |opts| setup_option_parsing(opts) }
+      @parser_class  = nil
+      @parser        = nil
+      @files         = []
+      @fragments     = []
+      @warnings      = false
+      @benchmark     = false
+
+      @source_count = 0
+      @source_size  = 0
+    end
+
+    def execute(options)
+      parse_options(options)
+      prepare_parser
+
+      process_all_input
+    end
+
+    private
+
+    def runner_name
+      raise NotImplementedError, "implement #{self.class}##{__callee__}"
+    end
+
+    def setup_option_parsing(opts)
+      opts.banner = "Usage: #{runner_name} [options] FILE|DIRECTORY..."
+
+      opts.on_tail '-h', '--help', 'Display this help message and exit' do
+        puts opts.help
+        puts <<-HELP
+
+  If you specify a DIRECTORY, then all *.rb files are fetched
+  from it recursively and appended to the file list.
+
+  The default parsing mode is for current Ruby (#{RUBY_VERSION}).
+        HELP
+        exit
+      end
+
+      opts.on_tail '-V', '--version', 'Output version information and exit' do
+        puts "#{runner_name} based on parser version #{Parser::VERSION}"
+        exit
+      end
+
+      opts.on '--18', 'Parse as Ruby 1.8.7 would' do
+        require 'parser/ruby18'
+        @parser_class = Parser::Ruby18
+      end
+
+      opts.on '--19', 'Parse as Ruby 1.9.3 would' do
+        require 'parser/ruby19'
+        @parser_class = Parser::Ruby19
+      end
+
+      opts.on '--20', 'Parse as Ruby 2.0 would' do
+        require 'parser/ruby20'
+        @parser_class = Parser::Ruby20
+      end
+
+      opts.on '--21', 'Parse as Ruby 2.1 would' do
+        require 'parser/ruby21'
+        @parser_class = Parser::Ruby21
+      end
+
+      opts.on '--22', 'Parse as Ruby 2.2 would' do
+        require 'parser/ruby22'
+        @parser_class = Parser::Ruby22
+      end
+
+      opts.on '-w', '--warnings', 'Enable warnings' do |w|
+        @warnings = w
+      end
+
+      opts.on '-B',  '--benchmark', 'Benchmark the processor' do |b|
+        @benchmark = b
+      end
+
+      opts.on '-e fragment', 'Process a fragment of Ruby code' do |fragment|
+        @fragments << fragment
+      end
+    end
+
+    def parse_options(options)
+      @option_parser.parse!(options)
+
+      # Slop has just removed recognized options from `options`.
+      options.each do |file_or_dir|
+        if File.directory?(file_or_dir)
+          Find.find(file_or_dir) do |path|
+            @files << path if path.end_with? '.rb'
+          end
+        else
+          @files << file_or_dir
+        end
+      end
+
+      if @files.empty? && @fragments.empty?
+        $stderr.puts 'Need something to parse!'
+        exit 1
+      end
+
+      if @parser_class.nil?
+        require 'parser/current'
+        @parser_class = Parser::CurrentRuby
+      end
+    end
+
+    def prepare_parser
+      @parser = @parser_class.new
+
+      @parser.diagnostics.all_errors_are_fatal = true
+      @parser.diagnostics.ignore_warnings      = !@warnings
+
+      @parser.diagnostics.consumer = lambda do |diagnostic|
+        puts(diagnostic.render)
+      end
+    end
+
+    def input_size
+      @files.size + @fragments.size
+    end
+
+    def process_all_input
+      parsing_time =
+        Benchmark.measure do
+          process_fragments
+          process_files
+        end
+
+      if @benchmark
+        report_with_time(parsing_time)
+      end
+    end
+
+    def process_fragments
+      @fragments.each_with_index do |fragment, index|
+        if fragment.respond_to? :force_encoding
+          fragment = fragment.dup.force_encoding(@parser.default_encoding)
+        end
+
+        buffer = Source::Buffer.new("(fragment:#{index})")
+        buffer.source = fragment
+
+        process_buffer(buffer)
+      end
+    end
+
+    def process_files
+      @files.each do |filename|
+        source = File.read(filename)
+        if source.respond_to? :force_encoding
+          source.force_encoding(@parser.default_encoding)
+        end
+
+        buffer = Parser::Source::Buffer.new(filename)
+
+        if @parser.class.name == 'Parser::Ruby18'
+          buffer.raw_source = source
+        else
+          buffer.source     = source
+        end
+
+        process_buffer(buffer)
+      end
+    end
+
+    def process_buffer(buffer)
+      @parser.reset
+
+      process(buffer)
+
+      @source_count += 1
+      @source_size  += buffer.source.size
+
+    rescue Parser::SyntaxError
+      # skip
+
+    rescue StandardError
+      $stderr.puts("Failed on: #{buffer.name}")
+      raise
+    end
+
+    def process(buffer)
+      raise NotImplementedError, "implement #{self.class}##{__callee__}"
+    end
+
+    def report_with_time(parsing_time)
+      cpu_time = parsing_time.utime
+
+      speed = '%.3f' % (@source_size / cpu_time / 1000)
+      puts "Parsed #{@source_count} files (#{@source_size} characters)" \
+           " in #{'%.2f' % cpu_time} seconds (#{speed} kchars/s)."
+
+      if defined?(RUBY_ENGINE)
+        engine = RUBY_ENGINE
+      else
+        engine = 'ruby'
+      end
+
+      puts "Running on #{engine} #{RUBY_VERSION}."
+    end
+  end
+
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/runner/ruby_parse.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/runner/ruby_parse.rb
new file mode 100644
index 0000000..5b58ab8
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/runner/ruby_parse.rb
@@ -0,0 +1,137 @@
+require 'parser/runner'
+require 'parser/lexer/explanation'
+
+module Parser
+
+  class Runner::RubyParse < Parser::Runner
+
+    class LocationProcessor < Parser::AST::Processor
+      def process(node)
+        if node
+          p node
+
+          source_line_no = nil
+          source_line    = ''
+          hilight_line   = ''
+
+          print_line = lambda do
+            unless hilight_line.empty?
+              puts hilight_line.
+                gsub(/[a-z_]+/) { |m| "\e[1;33m#{m}\e[0m" }.
+                gsub(/[~.]+/)   { |m| "\e[1;35m#{m}\e[0m" }
+              hilight_line = ''
+            end
+          end
+
+          print_source = lambda do |range|
+            source_line = range.source_line
+            puts "\e[32m#{source_line}\e[0m"
+            source_line
+          end
+
+          (node.loc || {}).to_hash.
+            sort_by do |name, range|
+              [(range ? range.line : 0),
+               (name == :expression ? 1 : 0)]
+            end.
+            each do |name, range|
+              next if range.nil?
+
+              if source_line_no != range.line
+                print_line.call()
+                source_line    = print_source.call(range)
+                source_line_no = range.line
+              end
+
+              beg_col = range.begin.column
+
+              if beg_col + range.length > source_line.length
+                multiline    = true
+                range_length = source_line.length - beg_col + 3
+              else
+                multiline    = false
+                range_length = range.length
+              end
+
+              length  = range_length + 1 + name.length
+              end_col = beg_col + length
+
+              if beg_col > 0
+                col_range = (beg_col - 1)...end_col
+              else
+                col_range = beg_col...end_col
+              end
+
+              if hilight_line.length < end_col
+                hilight_line = hilight_line.ljust(end_col)
+              end
+
+              if hilight_line[col_range] =~ /^\s*$/
+                if multiline
+                  tail = ('~' * (source_line.length - beg_col)) + '...'
+                else
+                  tail = '~' * range_length
+                end
+
+                tail = ' ' + tail if beg_col > 0
+
+                hilight_line[col_range] = tail + " #{name}"
+              else
+                print_line.call
+                redo
+              end
+            end
+
+          print_line.call
+        end
+
+        super
+      end
+    end
+
+    def initialize
+      super
+
+      @locate = false
+    end
+
+    private
+
+    def runner_name
+      'ruby-parse'
+    end
+
+    def setup_option_parsing(opts)
+      super(opts)
+
+      opts.on '-L', '--locate', 'Explain how source maps for AST nodes are laid out' do |v|
+        @locate = v
+      end
+
+      opts.on '-E', '--explain', 'Explain how the source is tokenized' do
+        ENV['RACC_DEBUG'] = '1'
+
+        Lexer.send :include, Lexer::Explanation
+      end
+    end
+
+    def process_all_input
+      if input_size > 1
+        puts "Using #{@parser_class} to parse #{input_size} files."
+      end
+
+      super
+    end
+
+    def process(buffer)
+      ast = @parser.parse(buffer)
+
+      if @locate
+        LocationProcessor.new.process(ast)
+      elsif !@benchmark
+        p ast
+      end
+    end
+  end
+
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/runner/ruby_rewrite.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/runner/ruby_rewrite.rb
new file mode 100644
index 0000000..7f36dd3
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/runner/ruby_rewrite.rb
@@ -0,0 +1,99 @@
+require 'parser/runner'
+require 'tempfile'
+
+module Parser
+
+  class Runner::RubyRewrite < Runner
+    def initialize
+      super
+
+      @rewriters = []
+      @modify    = false
+    end
+
+    private
+
+    def runner_name
+      'ruby-rewrite'
+    end
+
+    def setup_option_parsing(opts)
+      super(opts)
+
+      opts.on '-l file', '--load', 'Load a rewriter' do |file|
+        load_and_discover(file)
+      end
+
+      opts.on '-m', '--modify', 'Assume rewriters normally modify AST' do
+        @modify = true
+      end
+    end
+
+    def load_and_discover(file)
+      load file
+
+      const_name = file.
+        sub(/\.rb$/, '').
+        gsub(/(^|_)([a-z])/) do |m|
+          "#{$2.upcase}"
+        end
+
+      @rewriters << Object.const_get(const_name)
+    end
+
+    def process(initial_buffer)
+      buffer = initial_buffer
+      original_name = buffer.name
+
+      @rewriters.each do |rewriter_class|
+        @parser.reset
+        ast = @parser.parse(buffer)
+
+        rewriter = rewriter_class.new
+        new_source = rewriter.rewrite(buffer, ast)
+
+        new_buffer = Source::Buffer.new(initial_buffer.name +
+                                    '|after ' + rewriter_class.name)
+        new_buffer.source = new_source
+
+        @parser.reset
+        new_ast = @parser.parse(new_buffer)
+
+        if !@modify && ast != new_ast
+          $stderr.puts 'ASTs do not match:'
+
+          old = Tempfile.new('old')
+          old.write ast.inspect + "\n"; old.flush
+
+          new = Tempfile.new('new')
+          new.write new_ast.inspect + "\n"; new.flush
+
+          IO.popen("diff -u #{old.path} #{new.path}") do |io|
+            diff = io.read.
+              sub(/^---.*/,    "--- #{buffer.name}").
+              sub(/^\+\+\+.*/, "+++ #{new_buffer.name}")
+
+            $stderr.write diff
+          end
+
+          exit 1
+        end
+
+        buffer = new_buffer
+      end
+
+      if File.exist?(original_name)
+        File.open(original_name, 'w') do |file|
+          file.write buffer.source
+        end
+      else
+        if input_size > 1
+          puts "Rewritten content of #{buffer.name}:"
+        end
+
+        puts buffer.source
+      end
+    end
+  end
+
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/buffer.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/buffer.rb
new file mode 100644
index 0000000..bc97b55
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/buffer.rb
@@ -0,0 +1,245 @@
+# encoding: ascii-8bit
+
+module Parser
+  module Source
+
+    ##
+    # A buffer with source code. {Buffer} contains the source code itself,
+    # associated location information (name and first line), and takes care
+    # of encoding.
+    #
+    # A source buffer is immutable once populated.
+    #
+    # @!attribute [r] name
+    #  Buffer name. If the buffer was created from a file, the name corresponds
+    #  to relative path to the file.
+    #  @return [String] buffer name
+    #
+    # @!attribute [r] first_line
+    #  First line of the buffer, 1 by default.
+    #  @return [Integer] first line
+    #
+    # @api public
+    #
+    class Buffer
+      attr_reader :name, :first_line
+
+      ##
+      # @api private
+      #
+      ENCODING_RE =
+        /\#.*coding\s*[:=]\s*
+          (
+            # Special-case: there's a UTF8-MAC encoding.
+            (utf8-mac)
+          |
+            # Chew the suffix; it's there for emacs compat.
+            ([A-Za-z0-9_-]+?)(-unix|-dos|-mac)
+          |
+            ([A-Za-z0-9_-]+)
+          )
+        /x
+
+      ##
+      # Try to recognize encoding of `string` as Ruby would, i.e. by looking for
+      # magic encoding comment or UTF-8 BOM. `string` can be in any encoding.
+      #
+      # @param [String]  string
+      # @return [String|nil] encoding name, if recognized
+      #
+      def self.recognize_encoding(string)
+        return if string.empty?
+
+        # extract the first two lines in an efficient way
+        string =~ /\A(.*)\n?(.*\n)?/
+        first_line, second_line = $1, $2
+
+        if first_line =~ /\A\xef\xbb\xbf/ # BOM
+          return Encoding::UTF_8
+        elsif first_line[0, 2] == '#!'
+          encoding_line = second_line
+        else
+          encoding_line = first_line
+        end
+
+        if (result = ENCODING_RE.match(encoding_line))
+          Encoding.find(result[2] || result[3] || result[5])
+        else
+          nil
+        end
+      end
+
+      ##
+      # Recognize encoding of `input` and process it so it could be lexed.
+      #
+      #  * If `input` does not contain BOM or magic encoding comment, it is
+      #    kept in the original encoding.
+      #  * If the detected encoding is binary, `input` is kept in binary.
+      #  * Otherwise, `input` is re-encoded into UTF-8 and returned as a
+      #    new string.
+      #
+      # This method mutates the encoding of `input`, but not its content.
+      #
+      # @param  [String] input
+      # @return [String]
+      # @raise  [EncodingError]
+      #
+      def self.reencode_string(input)
+        original_encoding = input.encoding
+        detected_encoding = recognize_encoding(input.force_encoding(Encoding::BINARY))
+
+        if detected_encoding.nil?
+          input.force_encoding(original_encoding)
+        elsif detected_encoding == Encoding::BINARY
+          input
+        else
+          input.
+            force_encoding(detected_encoding).
+            encode(Encoding::UTF_8)
+        end
+      end
+
+      def initialize(name, first_line = 1)
+        @name        = name
+        @source      = nil
+        @first_line  = first_line
+
+        @lines       = nil
+        @line_begins = nil
+      end
+
+      ##
+      # Populate this buffer from correspondingly named file.
+      #
+      # @example
+      #  Parser::Source::Buffer.new('foo/bar.rb').read
+      #
+      # @return [Buffer] self
+      # @raise  [ArgumentError] if already populated
+      #
+      def read
+        File.open(@name, 'rb') do |io|
+          self.source = io.read
+        end
+
+        self
+      end
+
+      ##
+      # Source code contained in this buffer.
+      #
+      # @return [String] source code
+      # @raise  [RuntimeError] if buffer is not populated yet
+      #
+      def source
+        if @source.nil?
+          raise RuntimeError, 'Cannot extract source from uninitialized Source::Buffer'
+        end
+
+        @source
+      end
+
+      ##
+      # Populate this buffer from a string with encoding autodetection.
+      # `input` is mutated if not frozen.
+      #
+      # @param [String] input
+      # @raise [ArgumentError] if already populated
+      # @raise [EncodingError] if `input` includes invalid byte sequence for the encoding
+      # @return [String]
+      #
+      def source=(input)
+        if defined?(Encoding)
+          input = input.dup if input.frozen?
+          input = self.class.reencode_string(input)
+
+          unless input.valid_encoding?
+            raise EncodingError, "invalid byte sequence in #{input.encoding.name}"
+          end
+        end
+
+        self.raw_source = input
+      end
+
+      ##
+      # Populate this buffer from a string without encoding autodetection.
+      #
+      # @param [String] input
+      # @raise [ArgumentError] if already populated
+      # @return [String]
+      #
+      def raw_source=(input)
+        if @source
+          raise ArgumentError, 'Source::Buffer is immutable'
+        end
+
+        @source = input.gsub("\r\n", "\n").freeze
+      end
+
+      ##
+      # Convert a character index into the source to a `[line, column]` tuple.
+      #
+      # @param  [Integer] position
+      # @return [[Integer, Integer]] `[line, column]`
+      #
+      def decompose_position(position)
+        line_no, line_begin = line_for(position)
+
+        [ @first_line + line_no, position - line_begin ]
+      end
+
+      ##
+      # Extract line `lineno` from source, taking `first_line` into account.
+      #
+      # @param  [Integer] lineno
+      # @return [String]
+      # @raise  [IndexError] if `lineno` is out of bounds
+      #
+      def source_line(lineno)
+        unless @lines
+          @lines = @source.lines.to_a
+          @lines.each { |line| line.chomp!("\n") }
+
+          # If a file ends with a newline, the EOF token will appear
+          # to be one line further than the end of file.
+          @lines << ""
+        end
+
+        @lines.fetch(lineno - @first_line).dup
+      end
+
+      private
+
+      def line_begins
+        unless @line_begins
+          @line_begins, index = [ [ 0, 0 ] ], 1
+
+          @source.each_char do |char|
+            if char == "\n"
+              @line_begins.unshift [ @line_begins.length, index ]
+            end
+
+            index += 1
+          end
+        end
+
+        @line_begins
+      end
+
+      def line_for(position)
+        if line_begins.respond_to? :bsearch
+          # Fast O(log n) variant for Ruby >=2.0.
+          line_begins.bsearch do |line, line_begin|
+            line_begin <= position
+          end
+        else
+          # Slower O(n) variant for Ruby <2.0.
+          line_begins.find do |line, line_begin|
+            line_begin <= position
+          end
+        end
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/comment.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/comment.rb
new file mode 100644
index 0000000..f4cb8ed
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/comment.rb
@@ -0,0 +1,120 @@
+module Parser
+  module Source
+
+    ##
+    # A comment in the source code.
+    #
+    # @!attribute [r] text
+    #  @return [String]
+    #
+    # @!attribute [r] location
+    #  @return [Parser::Source::Map]
+    #
+    # @api public
+    #
+    class Comment
+      attr_reader  :text
+
+      attr_reader  :location
+      alias_method :loc, :location
+
+      ##
+      # Associate `comments` with `ast` nodes by their corresponding node.
+      #
+      # @param [Parser::AST::Node] ast
+      # @param [Array(Comment)]    comments
+      # @return [Hash(Parser::AST::Node, Array(Comment))]
+      # @see Parser::Source::Comment::Associator#associate
+      # @deprecated Use {associate_locations}.
+      #
+      def self.associate(ast, comments)
+        associator = Associator.new(ast, comments)
+        associator.associate
+      end
+
+      ##
+      # Associate `comments` with `ast` nodes by their location in the
+      # source.
+      #
+      # @param [Parser::AST::Node] ast
+      # @param [Array(Comment)]    comments
+      # @return [Hash(Parser::Source::Map, Array(Comment))]
+      # @see Parser::Source::Comment::Associator#associate_locations
+      #
+      def self.associate_locations(ast, comments)
+        associator = Associator.new(ast, comments)
+        associator.associate_locations
+      end
+
+      ##
+      # @param [Parser::Source::Range] range
+      #
+      def initialize(range)
+        @location = Parser::Source::Map.new(range)
+        @text     = range.source.freeze
+
+        freeze
+      end
+
+      ##
+      # Type of this comment.
+      #
+      #   * Inline comments correspond to `:inline`:
+      #
+      #         # whatever
+      #
+      #   * Block comments correspond to `:document`:
+      #
+      #         =begin
+      #         hi i am a document
+      #         =end
+      #
+      # @return [Symbol]
+      #
+      def type
+        case text
+        when /^#/
+          :inline
+        when /^=begin/
+          :document
+        end
+      end
+
+      ##
+      # @see #type
+      # @return [Boolean] true if this is an inline comment.
+      #
+      def inline?
+        type == :inline
+      end
+
+      ##
+      # @see #type
+      # @return [Boolean] true if this is a block comment.
+      #
+      def document?
+        type == :document
+      end
+
+      ##
+      # Compares comments. Two comments are equal if they
+      # correspond to the same source range.
+      #
+      # @param [Object] other
+      # @return [Boolean]
+      #
+      def ==(other)
+        other.is_a?(Source::Comment) &&
+          @location == other.location
+      end
+
+      ##
+      # @return [String] a human-readable representation of this comment
+      #
+      def inspect
+        "#<Parser::Source::Comment #{@location.expression.to_s} #{text.inspect}>"
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/comment/associator.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/comment/associator.rb
new file mode 100644
index 0000000..d7e81a5
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/comment/associator.rb
@@ -0,0 +1,204 @@
+module Parser
+  module Source
+
+    ##
+    # A processor which associates AST nodes with comments based on their
+    # location in source code. It may be used, for example, to implement
+    # rdoc-style processing.
+    #
+    # @example
+    #   require 'parser/current'
+    #
+    #   ast, comments = Parser::CurrentRuby.parse_with_comments(<<-CODE)
+    #   # Class stuff
+    #   class Foo
+    #     # Attr stuff
+    #     # @see bar
+    #     attr_accessor :foo
+    #   end
+    #   CODE
+    #
+    #   p Parser::Source::Comment.associate(ast, comments)
+    #   # => {
+    #   #   (class (const nil :Foo) ...) =>
+    #   #     [#<Parser::Source::Comment (string):1:1 "# Class stuff">],
+    #   #   (send nil :attr_accessor (sym :foo)) =>
+    #   #     [#<Parser::Source::Comment (string):3:3 "# Attr stuff">,
+    #   #      #<Parser::Source::Comment (string):4:3 "# @see bar">]
+    #   # }
+    #
+    # @see {associate}
+    #
+    # @!attribute skip_directives
+    #  Skip file processing directives disguised as comments.
+    #  Namely:
+    #
+    #    * Shebang line,
+    #    * Magic encoding comment.
+    #
+    #  @return [Boolean]
+    #
+    # @api public
+    #
+    class Comment::Associator
+      attr_accessor :skip_directives
+
+      ##
+      # @param [Parser::AST::Node] ast
+      # @param [Array(Parser::Source::Comment)] comments
+      def initialize(ast, comments)
+        @ast         = ast
+        @comments    = comments
+
+        @skip_directives = true
+      end
+
+      ##
+      # Compute a mapping between AST nodes and comments.
+      #
+      # A comment belongs to a certain node if it begins after end
+      # of the previous node (if one exists) and ends before beginning of
+      # the current node.
+      #
+      # This rule is unambiguous and produces the result
+      # one could reasonably expect; for example, this code
+      #
+      #     # foo
+      #     hoge # bar
+      #       + fuga
+      #
+      # will result in the following association:
+      #
+      #     {
+      #       (send (lvar :hoge) :+ (lvar :fuga)) =>
+      #         [#<Parser::Source::Comment (string):2:1 "# foo">],
+      #       (lvar :fuga) =>
+      #         [#<Parser::Source::Comment (string):3:8 "# bar">]
+      #     }
+      #
+      # Note that {associate} produces unexpected result for nodes which are
+      # equal but have distinct locations; comments for these nodes are merged.
+      #
+      # @return [Hash(Parser::AST::Node, Array(Parser::Source::Comment))]
+      # @deprecated Use {associate_locations}.
+      #
+      def associate
+        @map_using_locations = false
+        do_associate
+      end
+
+      ##
+      # Same as {associate}, but uses `node.loc` instead of `node` as
+      # the hash key, thus producing an unambiguous result even in presence
+      # of equal nodes.
+      #
+      # @return [Hash(Parser::Source::Map, Array(Parser::Source::Comment))]
+      #
+      def associate_locations
+        @map_using_locations = true
+        do_associate
+      end
+
+      private
+
+      def do_associate
+        @mapping     = Hash.new { |h, k| h[k] = [] }
+        @comment_num = -1
+        advance_comment
+
+        advance_through_directives if @skip_directives
+
+        @prev_node = nil
+        visit(@ast)
+
+        @mapping
+      end
+
+      def visit(node)
+        process_node(node)
+
+        if node.children.length > 0
+          node.children.each do |child|
+            next unless child.is_a?(AST::Node) && child.loc && child.loc.expression
+            visit(child)
+          end
+          process_trailing_comments(node)
+          @prev_node = node
+        end
+      end
+
+      def process_node(node)
+        return unless node.type != :begin
+        while current_comment_between?(@prev_node, node)
+          associate_and_advance_comment(@prev_node, node)
+        end
+        @prev_node = node
+      end
+
+      def process_trailing_comments(parent)
+        while current_comment_decorates?(@prev_node)
+          associate_and_advance_comment(@prev_node, nil)
+        end
+        while current_comment_before_end?(parent)
+          associate_and_advance_comment(@prev_node, nil)
+        end
+      end
+
+      def advance_comment
+        @comment_num += 1
+        @current_comment = @comments[@comment_num]
+      end
+
+      def current_comment_between?(prev_node, next_node)
+        return false if !@current_comment
+        comment_loc = @current_comment.location.expression
+
+        if next_node
+          next_loc = next_node.location.expression
+          return false if comment_loc.end_pos > next_loc.begin_pos
+        end
+        if prev_node
+          prev_loc = prev_node.location.expression
+          return false if comment_loc.begin_pos < prev_loc.begin_pos
+        end
+        true
+      end
+
+      def current_comment_decorates?(prev_node)
+        return false if !@current_comment
+        @current_comment.location.line == prev_node.location.line
+      end
+
+      def current_comment_before_end?(parent)
+        return false if !@current_comment
+        comment_loc = @current_comment.location.expression
+        parent_loc = parent.location.expression
+        comment_loc.end_pos <= parent_loc.end_pos
+      end
+
+      def associate_and_advance_comment(prev_node, node)
+        if prev_node && node
+          owner_node = (@current_comment.location.line == prev_node.location.line) ? prev_node : node
+        else
+          owner_node = prev_node ? prev_node : node
+        end
+        key = @map_using_locations ? owner_node.location : owner_node
+        @mapping[key] << @current_comment
+        advance_comment
+      end
+
+      def advance_through_directives
+        # Skip shebang.
+        if @current_comment && @current_comment.text =~ /^#!/
+          advance_comment
+        end
+
+        # Skip encoding line.
+        if @current_comment && @current_comment.text =~ Buffer::ENCODING_RE
+          advance_comment
+        end
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/map.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map.rb
new file mode 100644
index 0000000..2829e23
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map.rb
@@ -0,0 +1,164 @@
+module Parser
+  module Source
+
+    ##
+    # {Map} relates AST nodes to the source code they were parsed from.
+    # More specifically, a {Map} or its subclass contains a set of ranges:
+    #
+    #  * `expression`: smallest range which includes all source corresponding
+    #    to the node and all `expression` ranges of its children.
+    #  * other ranges (`begin`, `end`, `operator`, ...): node-specific ranges
+    #    pointing to various interesting tokens corresponding to the node.
+    #
+    # Note that the {Map::Heredoc} map is the only one whose `expression` does
+    # not include other ranges. It only covers the heredoc marker (`<<HERE`),
+    # not the here document itself.
+    #
+    # All ranges except `expression` are defined by {Map} subclasses.
+    #
+    # Ranges (except `expression`) can be `nil` if the corresponding token is
+    # not present in source. For example, a hash may not have opening/closing
+    # braces, and so would its source map.
+    #
+    #     p Parser::CurrentRuby.parse('[1 => 2]').children[0].loc
+    #     # => <Parser::Source::Map::Collection:0x007f5492b547d8
+    #     #  @end=nil, @begin=nil,
+    #     #  @expression=#<Source::Range (string) 1...7>>
+    #
+    # The {file:doc/AST_FORMAT.md} document describes how ranges associated to source
+    # code tokens. For example, the entry
+    #
+    #     (array (int 1) (int 2))
+    #
+    #     "[1, 2]"
+    #      ^ begin
+    #           ^ end
+    #      ~~~~~~ expression
+    #
+    # means that if `node` is an {Parser::AST::Node} `(array (int 1) (int 2))`,
+    # then `node.loc` responds to `begin`, `end` and `expression`, and
+    # `node.loc.begin` returns a range pointing at the opening bracket, and so on.
+    #
+    # If you want to write code polymorphic by the source map (i.e. accepting
+    # several subclasses of {Map}), use `respond_to?` instead of `is_a?` to
+    # check whether the map features the range you need. Concrete {Map}
+    # subclasses may not be preserved between versions, but their interfaces
+    # will be kept compatible.
+    #
+    # You can visualize the source maps with `ruby-parse -E` command-line tool.
+    #
+    # @example
+    #  require 'parser/current'
+    #
+    #  p Parser::CurrentRuby.parse('[1, 2]').loc
+    #  # => #<Parser::Source::Map::Collection:0x007f14b80eccd8
+    #  #  @end=#<Source::Range (string) 5...6>,
+    #  #  @begin=#<Source::Range (string) 0...1>,
+    #  #  @expression=#<Source::Range (string) 0...6>>
+    #
+    # @!attribute [r] node
+    #  The node that is described by this map. Nodes and maps have 1:1 correspondence.
+    #  @return [Parser::AST::Node]
+    #
+    # @!attribute [r] expression
+    #  @return [Range]
+    #
+    # @api public
+    #
+    class Map
+      attr_reader :node
+      attr_reader :expression
+
+      ##
+      # @param [Range] expression
+      def initialize(expression)
+        @expression = expression
+      end
+
+      ##
+      # @api private
+      def initialize_copy(other)
+        super
+        @node = nil
+      end
+
+      ##
+      # @api private
+      def node=(node)
+        @node = node
+        freeze
+        @node
+      end
+
+      ##
+      # A shortcut for `self.expression.line`.
+      # @return [Integer]
+      #
+      def line
+        @expression.line
+      end
+
+      ##
+      # A shortcut for `self.expression.column`.
+      # @return [Integer]
+      #
+      def column
+        @expression.column
+      end
+
+      ##
+      # @api private
+      #
+      def with_expression(expression_l)
+        with { |map| map.update_expression(expression_l) }
+      end
+
+      ##
+      # Compares source maps.
+      # @return [Boolean]
+      #
+      def ==(other)
+        other.class == self.class &&
+          instance_variables.map do |ivar|
+            instance_variable_get(ivar) ==
+              other.send(:instance_variable_get, ivar)
+          end.reduce(:&)
+      end
+
+      ##
+      # Converts this source map to a hash with keys corresponding to
+      # ranges. For example, if called on an instance of {Collection},
+      # which adds the `begin` and `end` ranges, the resulting hash
+      # will contain keys `:expression`, `:begin` and `:end`.
+      #
+      # @example
+      #  require 'parser/current'
+      #
+      #  p Parser::CurrentRuby.parse('[1, 2]').loc.to_hash
+      #  # => {
+      #  #   :begin => #<Source::Range (string) 0...1>,
+      #  #   :end => #<Source::Range (string) 5...6>,
+      #  #   :expression => #<Source::Range (string) 0...6>
+      #  # }
+      #
+      # @return [Hash(Symbol, Parser::Source::Range)]
+      #
+      def to_hash
+        Hash[instance_variables.map do |ivar|
+          [ ivar[1..-1].to_sym, instance_variable_get(ivar) ]
+        end]
+      end
+
+      protected
+
+      def with(&block)
+        dup.tap(&block)
+      end
+
+      def update_expression(expression_l)
+        @expression = expression_l
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/collection.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/collection.rb
new file mode 100644
index 0000000..4530bb2
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/collection.rb
@@ -0,0 +1,16 @@
+module Parser
+  module Source
+
+    class Map::Collection < Map
+      attr_reader :begin
+      attr_reader :end
+
+      def initialize(begin_l, end_l, expression_l)
+        @begin, @end = begin_l, end_l
+
+        super(expression_l)
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/condition.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/condition.rb
new file mode 100644
index 0000000..ae88387
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/condition.rb
@@ -0,0 +1,19 @@
+module Parser
+  module Source
+
+    class Map::Condition < Map
+      attr_reader :keyword
+      attr_reader :begin
+      attr_reader :else
+      attr_reader :end
+
+      def initialize(keyword_l, begin_l, else_l, end_l, expression_l)
+        @keyword = keyword_l
+        @begin, @else, @end = begin_l, else_l, end_l
+
+        super(expression_l)
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/constant.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/constant.rb
new file mode 100644
index 0000000..e389319
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/constant.rb
@@ -0,0 +1,30 @@
+module Parser
+  module Source
+
+    class Map::Constant < Map
+      attr_reader :double_colon
+      attr_reader :name
+      attr_reader :operator
+
+      def initialize(double_colon, name, expression)
+        @double_colon, @name = double_colon, name
+
+        super(expression)
+      end
+
+      ##
+      # @api private
+      #
+      def with_operator(operator_l)
+        with { |map| map.update_operator(operator_l) }
+      end
+
+      protected
+
+      def update_operator(operator_l)
+        @operator = operator_l
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/definition.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/definition.rb
new file mode 100644
index 0000000..160b5c0
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/definition.rb
@@ -0,0 +1,21 @@
+module Parser
+  module Source
+
+    class Map::Definition < Map
+      attr_reader :keyword
+      attr_reader :operator
+      attr_reader :name
+      attr_reader :end
+
+      def initialize(keyword_l, operator_l, name_l, end_l)
+        @keyword  = keyword_l
+        @operator = operator_l
+        @name     = name_l
+        @end      = end_l
+
+        super(@keyword.join(@end))
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/for.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/for.rb
new file mode 100644
index 0000000..81b38bc
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/for.rb
@@ -0,0 +1,17 @@
+module Parser
+  module Source
+
+    class Map::For < Map
+      attr_reader :keyword, :in
+      attr_reader :begin, :end
+
+      def initialize(keyword_l, in_l, begin_l, end_l, expression_l)
+        @keyword, @in = keyword_l, in_l
+        @begin, @end  = begin_l, end_l
+
+        super(expression_l)
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/heredoc.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/heredoc.rb
new file mode 100644
index 0000000..3a8f335
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/heredoc.rb
@@ -0,0 +1,17 @@
+module Parser
+  module Source
+
+    class Map::Heredoc < Map
+      attr_reader :heredoc_body
+      attr_reader :heredoc_end
+
+      def initialize(begin_l, body_l, end_l)
+        @heredoc_body = body_l
+        @heredoc_end  = end_l
+
+        super(begin_l)
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/keyword.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/keyword.rb
new file mode 100644
index 0000000..efaac52
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/keyword.rb
@@ -0,0 +1,18 @@
+module Parser
+  module Source
+
+    class Map::Keyword < Map
+      attr_reader :keyword
+      attr_reader :begin
+      attr_reader :end
+
+      def initialize(keyword_l, begin_l, end_l, expression_l)
+        @keyword     = keyword_l
+        @begin, @end = begin_l, end_l
+
+        super(expression_l)
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/operator.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/operator.rb
new file mode 100644
index 0000000..9a71543
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/operator.rb
@@ -0,0 +1,15 @@
+module Parser
+  module Source
+
+    class Map::Operator < Map
+      attr_reader :operator
+
+      def initialize(operator, expression)
+        @operator = operator
+
+        super(expression)
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/rescue_body.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/rescue_body.rb
new file mode 100644
index 0000000..3c21ddc
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/rescue_body.rb
@@ -0,0 +1,19 @@
+module Parser
+  module Source
+
+    class Map::RescueBody < Map
+      attr_reader :keyword
+      attr_reader :assoc
+      attr_reader :begin
+
+      def initialize(keyword_l, assoc_l, begin_l, expression_l)
+        @keyword = keyword_l
+        @assoc   = assoc_l
+        @begin   = begin_l
+
+        super(expression_l)
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/send.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/send.rb
new file mode 100644
index 0000000..79b189b
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/send.rb
@@ -0,0 +1,34 @@
+module Parser
+  module Source
+
+    class Map::Send < Map
+      attr_reader :dot
+      attr_reader :selector
+      attr_reader :operator
+      attr_reader :begin
+      attr_reader :end
+
+      def initialize(dot_l, selector_l, begin_l, end_l, expression_l)
+        @dot         = dot_l
+        @selector    = selector_l
+        @begin, @end = begin_l, end_l
+
+        super(expression_l)
+      end
+
+      ##
+      # @api private
+      #
+      def with_operator(operator_l)
+        with { |map| map.update_operator(operator_l) }
+      end
+
+      protected
+
+      def update_operator(operator_l)
+        @operator = operator_l
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/ternary.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/ternary.rb
new file mode 100644
index 0000000..caf4c06
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/ternary.rb
@@ -0,0 +1,16 @@
+module Parser
+  module Source
+
+    class Map::Ternary < Map
+      attr_reader :question
+      attr_reader :colon
+
+      def initialize(question_l, colon_l, expression_l)
+        @question, @colon = question_l, colon_l
+
+        super(expression_l)
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/variable.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/variable.rb
new file mode 100644
index 0000000..149d92d
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/map/variable.rb
@@ -0,0 +1,29 @@
+module Parser
+  module Source
+
+    class Map::Variable < Map
+      attr_reader :name
+      attr_reader :operator
+
+      def initialize(name_l, expression_l=name_l)
+        @name = name_l
+
+        super(expression_l)
+      end
+
+      ##
+      # @api private
+      #
+      def with_operator(operator_l)
+        with { |map| map.update_operator(operator_l) }
+      end
+
+      protected
+
+      def update_operator(operator_l)
+        @operator = operator_l
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/range.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/range.rb
new file mode 100644
index 0000000..db988bd
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/range.rb
@@ -0,0 +1,187 @@
+module Parser
+  module Source
+
+    ##
+    # A range of characters in a particular source buffer.
+    #
+    # The range is always exclusive, i.e. a range with `begin_pos` of 3 and
+    # `end_pos` of 5 will contain the following characters:
+    #
+    #     example
+    #        ^^
+    #
+    # @!attribute [r] source_buffer
+    #  @return [Parser::Diagnostic::Engine]
+    #
+    # @!attribute [r] begin_pos
+    #  @return [Integer] index of the first character in the range
+    #
+    # @!attribute [r] end_pos
+    #  @return [Integer] index of the character after the last character in the range
+    #
+    # @api public
+    #
+    class Range
+      attr_reader :source_buffer
+      attr_reader :begin_pos, :end_pos
+
+      ##
+      # @param [Buffer]  source_buffer
+      # @param [Integer] begin_pos
+      # @param [Integer] end_pos
+      #
+      def initialize(source_buffer, begin_pos, end_pos)
+        @source_buffer       = source_buffer
+        @begin_pos, @end_pos = begin_pos, end_pos
+
+        freeze
+      end
+
+      ##
+      # @return [Range] a zero-length range located just before the beginning
+      #   of this range.
+      #
+      def begin
+        Range.new(@source_buffer, @begin_pos, @begin_pos)
+      end
+
+      ##
+      # @return [Range] a zero-length range located just after the end
+      #   of this range.
+      #
+      def end
+        Range.new(@source_buffer, @end_pos, @end_pos)
+      end
+
+      ##
+      # @return [Integer] amount of characters included in this range.
+      #
+      def size
+        @end_pos - @begin_pos
+      end
+
+      alias length size
+
+      ##
+      # Line number of the beginning of this range. By default, the first line
+      # of a buffer is 1; as such, line numbers are most commonly one-based.
+      #
+      # @see Buffer
+      # @return [Integer] line number of the beginning of this range.
+      #
+      def line
+        line, _ = @source_buffer.decompose_position(@begin_pos)
+
+        line
+      end
+
+      ##
+      # @return [Integer] zero-based column number of the beginning of this range.
+      #
+      def column
+        _, column = @source_buffer.decompose_position(@begin_pos)
+
+        column
+      end
+
+      ##
+      # @return [::Range] a range of columns spanned by this range.
+      # @raise RangeError
+      #
+      def column_range
+        if self.begin.line != self.end.line
+          raise RangeError, "#{self.inspect} spans more than one line"
+        end
+
+        self.begin.column...self.end.column
+      end
+
+      ##
+      # @return [String] a line of source code containing the beginning of this range.
+      #
+      def source_line
+        @source_buffer.source_line(line)
+      end
+
+      ##
+      # @return [String] all source code covered by this range.
+      #
+      def source
+        @source_buffer.source[self.begin_pos...self.end_pos]
+      end
+
+      ##
+      # `is?` provides a concise way to compare the source corresponding to this range.
+      # For example, `r.source == '(' || r.source == 'begin'` is equivalent to
+      # `r.is?('(', 'begin')`.
+      #
+      def is?(*what)
+        what.include?(source)
+      end
+
+      ##
+      # @return [Array(Integer)] a set of character indexes contained in this range.
+      #
+      def to_a
+        (@begin_pos... at end_pos).to_a
+      end
+
+      ##
+      # Composes a GNU/Clang-style string representation of the beginning of this
+      # range.
+      #
+      # For example, for the following range in file `foo.rb`,
+      #
+      #     def foo
+      #         ^^^
+      #
+      # `to_s` will return `foo.rb:1:5`.
+      # Note that the column index is one-based.
+      #
+      # @return [String]
+      #
+      def to_s
+        line, column = @source_buffer.decompose_position(@begin_pos)
+
+        [@source_buffer.name, line, column + 1].join(':')
+      end
+
+      ##
+      # @param [Integer] new_size
+      # @return [Range] a range beginning at the same point as this range and length `new_size`.
+      #
+      def resize(new_size)
+        Range.new(@source_buffer, @begin_pos, @begin_pos + new_size)
+      end
+
+      ##
+      # @param [Range] other
+      # @return [Range] smallest possible range spanning both this range and `other`.
+      #
+      def join(other)
+        Range.new(@source_buffer,
+            [@begin_pos, other.begin_pos].min,
+            [@end_pos,   other.end_pos].max)
+      end
+
+      ##
+      # Compares ranges.
+      # @return [Boolean]
+      #
+      def ==(other)
+        other.is_a?(Range) &&
+          @source_buffer == other.source_buffer &&
+          @begin_pos     == other.begin_pos     &&
+          @end_pos       == other.end_pos
+      end
+
+      ##
+      # @return [String] a human-readable representation of this range.
+      #
+      def inspect
+        "#<Parser::Source::Range #{@source_buffer.name} #{@begin_pos}...#{@end_pos}>"
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/rewriter.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/rewriter.rb
new file mode 100644
index 0000000..e71e2a6
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/rewriter.rb
@@ -0,0 +1,221 @@
+module Parser
+  module Source
+
+    ##
+    # {Rewriter} performs the heavy lifting in the source rewriting process.
+    # It schedules code updates to be performed in the correct order and
+    # verifies that no two updates _clobber_ each other, that is, attempt to
+    # modify the same part of code.
+    #
+    # If it is detected that one update clobbers another one, an `:error` and
+    # a `:note` diagnostics describing both updates are generated and passed to
+    # the diagnostic engine. After that, an exception is raised.
+    #
+    # The default diagnostic engine consumer simply prints the diagnostics to `stderr`.
+    #
+    # @!attribute [r] source_buffer
+    #  @return [Source::Buffer]
+    #
+    # @!attribute [r] diagnostics
+    #  @return [Diagnostic::Engine]
+    #
+    # @api public
+    #
+    class Rewriter
+      attr_reader :source_buffer
+      attr_reader :diagnostics
+
+      ##
+      # @param [Source::Buffer] source_buffer
+      #
+      def initialize(source_buffer)
+        @diagnostics = Diagnostic::Engine.new
+        @diagnostics.consumer = lambda do |diag|
+          $stderr.puts diag.render
+        end
+
+        @source_buffer = source_buffer
+        @queue         = []
+        @clobber       = 0
+      end
+
+      ##
+      # Removes the source range.
+      #
+      # @param [Range] range
+      # @return [Rewriter] self
+      # @raise [ClobberingError] when clobbering is detected
+      #
+      def remove(range)
+        append Rewriter::Action.new(range, '')
+      end
+
+      ##
+      # Inserts new code before the given source range.
+      #
+      # @param [Range] range
+      # @param [String] content
+      # @return [Rewriter] self
+      # @raise [ClobberingError] when clobbering is detected
+      #
+      def insert_before(range, content)
+        append Rewriter::Action.new(range.begin, content)
+      end
+
+      ##
+      # Inserts new code after the given source range.
+      #
+      # @param [Range] range
+      # @param [String] content
+      # @return [Rewriter] self
+      # @raise [ClobberingError] when clobbering is detected
+      #
+      def insert_after(range, content)
+        append Rewriter::Action.new(range.end, content)
+      end
+
+      ##
+      # Replaces the code of the source range `range` with `content`.
+      #
+      # @param [Range] range
+      # @param [String] content
+      # @return [Rewriter] self
+      # @raise [ClobberingError] when clobbering is detected
+      #
+      def replace(range, content)
+        append Rewriter::Action.new(range, content)
+      end
+
+      ##
+      # Applies all scheduled changes to the `source_buffer` and returns
+      # modified source as a new string.
+      #
+      # @return [String]
+      #
+      def process
+        if in_transaction?
+          raise "Do not call #{self.class}##{__method__} inside a transaction"
+        end
+
+        adjustment = 0
+        source     = @source_buffer.source.dup
+
+        sorted_queue = @queue.sort_by.with_index do |action, index|
+          [action.range.begin_pos, index]
+        end
+
+        sorted_queue.each do |action|
+          begin_pos = action.range.begin_pos + adjustment
+          end_pos   = begin_pos + action.range.length
+
+          source[begin_pos...end_pos] = action.replacement
+
+          adjustment += (action.replacement.length - action.range.length)
+        end
+
+        source
+      end
+
+      ##
+      # Provides a protected block where a sequence of multiple rewrite actions
+      # are handled atomic. If any of the action failed by clobbering,
+      # all the actions are rolled back.
+      #
+      # @example
+      #  begin
+      #    rewriter.transaction do
+      #      rewriter.insert_before(range_of_something, '(')
+      #      rewriter.insert_after(range_of_something, ')')
+      #    end
+      #  rescue Parser::ClobberingError
+      #  end
+      #
+      # @raise [RuntimeError] when no block is passed
+      # @raise [RuntimeError] when already in a transaction
+      #
+      def transaction
+        unless block_given?
+          raise "#{self.class}##{__method__} requires block"
+        end
+
+        if in_transaction?
+          raise 'Nested transaction is not supported'
+        end
+
+        @pending_queue = @queue.dup
+        @pending_clobber = @clobber
+
+        yield
+
+        @queue = @pending_queue
+        @clobber = @pending_clobber
+
+        self
+      ensure
+        @pending_queue = nil
+        @pending_clobber = nil
+      end
+
+      private
+
+      def append(action)
+        if (clobber_action = clobbered?(action.range))
+          # cannot replace 3 characters with "foobar"
+          diagnostic = Diagnostic.new(:error,
+                                      :invalid_action,
+                                      { :action => action },
+                                      action.range)
+          @diagnostics.process(diagnostic)
+
+          # clobbered by: remove 3 characters
+          diagnostic = Diagnostic.new(:note,
+                                      :clobbered,
+                                      { :action => clobber_action },
+                                      clobber_action.range)
+          @diagnostics.process(diagnostic)
+
+          raise ClobberingError, "Parser::Source::Rewriter detected clobbering"
+        else
+          clobber(action.range)
+
+          active_queue << action
+        end
+
+        self
+      end
+
+      def clobber(range)
+        self.active_clobber = active_clobber | (2 ** range.size - 1) << range.begin_pos
+      end
+
+      def clobbered?(range)
+        if active_clobber & ((2 ** range.size - 1) << range.begin_pos) != 0
+          active_queue.find do |action|
+            action.range.to_a & range.to_a
+          end
+        end
+      end
+
+      def in_transaction?
+        !@pending_queue.nil?
+      end
+
+      def active_queue
+        @pending_queue || @queue
+      end
+
+      def active_clobber
+        @pending_clobber || @clobber
+      end
+
+      def active_clobber=(value)
+        if @pending_clobber
+          @pending_clobber = value
+        else
+          @clobber = value
+        end
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/source/rewriter/action.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/source/rewriter/action.rb
new file mode 100644
index 0000000..0184c6b
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/source/rewriter/action.rb
@@ -0,0 +1,30 @@
+module Parser
+  module Source
+
+    ##
+    # @api private
+    #
+    class Rewriter::Action
+      attr_reader :range, :replacement
+
+      def initialize(range, replacement='')
+        @range, @replacement = range, replacement
+
+        freeze
+      end
+
+      def to_s
+        if @range.length == 0 && @replacement.empty?
+          'do nothing'
+        elsif @range.length == 0
+          "insert #{@replacement.inspect}"
+        elsif @replacement.empty?
+          "remove #{@range.length} character(s)"
+        else
+          "replace #{@range.length} character(s) with #{@replacement.inspect}"
+        end
+      end
+    end
+
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/static_environment.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/static_environment.rb
new file mode 100644
index 0000000..feb0219
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/static_environment.rb
@@ -0,0 +1,44 @@
+module Parser
+
+  class StaticEnvironment
+    def initialize
+      reset
+    end
+
+    def reset
+      @variables = Set[]
+      @stack     = []
+    end
+
+    def extend_static
+      @stack.push(@variables)
+      @variables = Set[]
+
+      self
+    end
+
+    def extend_dynamic
+      @stack.push(@variables)
+      @variables = @variables.dup
+
+      self
+    end
+
+    def unextend
+      @variables = @stack.pop
+
+      self
+    end
+
+    def declare(name)
+      @variables.add(name.to_sym)
+
+      self
+    end
+
+    def declared?(name)
+      @variables.include?(name.to_sym)
+    end
+  end
+
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/syntax_error.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/syntax_error.rb
new file mode 100644
index 0000000..575a45a
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/syntax_error.rb
@@ -0,0 +1,19 @@
+module Parser
+  ##
+  # {Parser::SyntaxError} is raised whenever parser detects a syntax error,
+  # similar to the standard SyntaxError class.
+  #
+  # @api public
+  #
+  # @!attribute [r] diagnostic
+  #  @return [Parser::Diagnostic]
+  #
+  class SyntaxError < StandardError
+    attr_reader :diagnostic
+
+    def initialize(diagnostic)
+      @diagnostic = diagnostic
+      super(diagnostic.message)
+    end
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/lib/parser/version.rb b/app/server/vendor/parser-2.2.2.1/lib/parser/version.rb
new file mode 100644
index 0000000..638abaf
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/lib/parser/version.rb
@@ -0,0 +1,3 @@
+module Parser
+  VERSION = '2.2.2.1'
+end
diff --git a/app/server/vendor/parser-2.2.2.1/parser.gemspec b/app/server/vendor/parser-2.2.2.1/parser.gemspec
new file mode 100644
index 0000000..daaba31
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/parser.gemspec
@@ -0,0 +1,48 @@
+# encoding: utf-8
+
+require File.expand_path('../lib/parser/version', __FILE__)
+
+Gem::Specification.new do |spec|
+  spec.name          = 'parser'
+  spec.version       = Parser::VERSION
+  spec.authors       = ['Peter Zotov']
+  spec.email         = ['whitequark at whitequark.org']
+  spec.description   = 'A Ruby parser written in pure Ruby.'
+  spec.summary       = spec.description
+  spec.homepage      = 'https://github.com/whitequark/parser'
+  spec.license       = 'MIT'
+  spec.has_rdoc      = 'yard'
+
+  spec.files         = `git ls-files`.split + %w(
+                          lib/parser/lexer.rb
+                          lib/parser/ruby18.rb
+                          lib/parser/ruby19.rb
+                          lib/parser/ruby20.rb
+                          lib/parser/ruby21.rb
+                          lib/parser/ruby22.rb
+                       )
+  spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
+  spec.test_files    = spec.files.grep(%r{^test/})
+  spec.require_paths = ['lib']
+
+  spec.add_dependency             'ast',       ['>= 1.1', '< 3.0']
+
+  spec.add_development_dependency 'bundler',   '~> 1.2'
+  spec.add_development_dependency 'rake',      '~> 10.0'
+  spec.add_development_dependency 'racc',      '= 1.4.9' # update to 1.4.11 when it's done
+  spec.add_development_dependency 'cliver',    '~> 0.3.0'
+
+  spec.add_development_dependency 'yard'
+  spec.add_development_dependency 'kramdown'
+
+  spec.add_development_dependency 'minitest',  '~> 5.0'
+  spec.add_development_dependency 'simplecov', '~> 0.8.2'
+  spec.add_development_dependency 'coveralls'
+  spec.add_development_dependency 'json_pure' # for coveralls on 1.9.2
+  spec.add_development_dependency 'mime-types', '~> 1.25' # for coveralls on 1.8.7
+  spec.add_development_dependency 'rest-client', '~> 1.6.7' # 1.8.7
+
+  spec.add_development_dependency 'simplecov-sublime-ruby-coverage'
+
+  spec.add_development_dependency 'gauntlet'
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/bug_163/fixtures/input.rb b/app/server/vendor/parser-2.2.2.1/test/bug_163/fixtures/input.rb
new file mode 100644
index 0000000..2547c89
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/bug_163/fixtures/input.rb
@@ -0,0 +1,3 @@
+if(true)
+  puts "Hello, world!"
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/bug_163/fixtures/output.rb b/app/server/vendor/parser-2.2.2.1/test/bug_163/fixtures/output.rb
new file mode 100644
index 0000000..4ed170d
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/bug_163/fixtures/output.rb
@@ -0,0 +1,3 @@
+if true
+  puts "Hello, world!"
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/bug_163/rewriter.rb b/app/server/vendor/parser-2.2.2.1/test/bug_163/rewriter.rb
new file mode 100644
index 0000000..3a4bae1
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/bug_163/rewriter.rb
@@ -0,0 +1,18 @@
+class Rewriter < Parser::Rewriter
+  def on_if(node)
+    # Crude, totally-not-usable-in-the-real-world code to remove optional
+    # parens from control keywords.
+    #
+    # In a perfect test scenario we'd simply make this a no-op, to demonstrate
+    # that the bug happens when any rewriter is loaded regardless of whether it
+    # actually changes anything but that makes assertions much harder to get
+    # right.  It's much easier to just show that the file did, or did not
+    # get changed.
+    if node.children[0].type == :begin
+      replace node.children[0].loc.begin, ' '
+      remove node.children[0].loc.end
+    end
+
+    super
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/bug_163/test_runner_rewrite.rb b/app/server/vendor/parser-2.2.2.1/test/bug_163/test_runner_rewrite.rb
new file mode 100644
index 0000000..168e597
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/bug_163/test_runner_rewrite.rb
@@ -0,0 +1,35 @@
+require 'pathname'
+require 'fileutils'
+require 'shellwords'
+
+BASE_DIR = Pathname.new(__FILE__) + '../..'
+require (BASE_DIR + 'helper').expand_path
+
+class TestRunnerRewrite < Minitest::Test
+  def setup
+    @ruby_rewrite = BASE_DIR.expand_path + '../bin/ruby-rewrite'
+    @test_dir     = BASE_DIR + 'bug_163'
+    @fixtures_dir = @test_dir + 'fixtures'
+  end
+
+  def test_rewriter
+    Dir.mktmpdir("parser", BASE_DIR.expand_path.to_s) do |tmp_dir|
+      tmp_dir = Pathname.new(tmp_dir)
+      sample_file = tmp_dir + 'bug_163.rb'
+      sample_file_expanded = sample_file.expand_path
+      expected_file = @fixtures_dir + 'output.rb'
+
+      FileUtils.cp(@fixtures_dir + 'input.rb', tmp_dir + 'bug_163.rb')
+      FileUtils.cd @test_dir do
+        exit_code = system %Q{
+          #{Shellwords.escape(@ruby_rewrite.to_s)} --modify \
+            -l rewriter.rb \
+            #{Shellwords.escape(sample_file_expanded.to_s)}
+        }
+      end
+
+      assert File.read(expected_file.expand_path) == File.read(sample_file),
+        "#{sample_file} should be identical to #{expected_file}"
+    end
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/helper.rb b/app/server/vendor/parser-2.2.2.1/test/helper.rb
new file mode 100644
index 0000000..4d11d88
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/helper.rb
@@ -0,0 +1,46 @@
+require 'tempfile'
+require 'minitest/test'
+
+require 'simplecov'
+require 'coveralls'
+
+if ENV.include?('COVERAGE') && SimpleCov.usable?
+  if defined?(TracePoint)
+    require_relative 'racc_coverage_helper'
+
+    RaccCoverage.start(%w(ruby18.y ruby19.y ruby20.y ruby21.y),
+                       File.expand_path('../../lib/parser', __FILE__))
+
+    # Report results faster.
+    at_exit { RaccCoverage.stop }
+  end
+
+  require 'simplecov-sublime-ruby-coverage'
+
+  SimpleCov.start do
+    self.formatter = SimpleCov::Formatter::MultiFormatter[
+      SimpleCov::Formatter::HTMLFormatter,
+      SimpleCov::Formatter::SublimeRubyCoverageFormatter,
+      Coveralls::SimpleCov::Formatter
+    ]
+
+    add_group 'Grammars' do |source_file|
+      source_file.filename =~ %r{\.y$}
+    end
+
+    # Exclude the testsuite itself.
+    add_filter '/test/'
+
+    # Exclude generated files.
+    add_filter do |source_file|
+      source_file.filename =~ %r{/lib/parser/(lexer|ruby\d+)\.rb$}
+    end
+  end
+end
+
+# minitest/autorun must go after SimpleCov to preserve
+# correct order of at_exit hooks.
+require 'minitest/autorun'
+
+$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
+require 'parser'
diff --git a/app/server/vendor/parser-2.2.2.1/test/parse_helper.rb b/app/server/vendor/parser-2.2.2.1/test/parse_helper.rb
new file mode 100644
index 0000000..f8f4ebe
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/parse_helper.rb
@@ -0,0 +1,243 @@
+module ParseHelper
+  include AST::Sexp
+
+  if RUBY_VERSION == '1.8.7'
+    require 'parser/ruby18'
+
+    ALL_VERSIONS = %w(1.8)
+  else
+    require 'parser/all'
+    require 'parser/ruby22'
+
+    ALL_VERSIONS = %w(1.8 1.9 2.0 2.1 2.2)
+  end
+
+  def setup
+    @diagnostics = []
+
+    super if defined?(super)
+  end
+
+  def parser_for_ruby_version(version)
+    case version
+    when '1.8' then parser = Parser::Ruby18.new
+    when '1.9' then parser = Parser::Ruby19.new
+    when '2.0' then parser = Parser::Ruby20.new
+    when '2.1' then parser = Parser::Ruby21.new
+    when '2.2' then parser = Parser::Ruby22.new
+    else raise "Unrecognized Ruby version #{version}"
+    end
+
+    parser.diagnostics.consumer = lambda do |diagnostic|
+      @diagnostics << diagnostic
+    end
+
+    parser
+  end
+
+  def with_versions(versions)
+    (versions & ALL_VERSIONS).each do |version|
+      @diagnostics.clear
+
+      parser = parser_for_ruby_version(version)
+      yield version, parser
+    end
+  end
+
+  def assert_source_range(begin_pos, end_pos, range, version, what)
+    assert range.is_a?(Parser::Source::Range),
+           "(#{version}) #{range.inspect}.is_a?(Source::Range) for #{what}"
+
+    assert_equal begin_pos, range.begin_pos,
+                 "(#{version}) begin of #{what}"
+
+    assert_equal end_pos, range.end_pos,
+                 "(#{version}) end of #{what}"
+  end
+
+  # Use like this:
+  # ~~~
+  # assert_parses(
+  #   s(:send, s(:lit, 10), :+, s(:lit, 20))
+  #   %q{10 + 20},
+  #   %q{~~~~~~~ expression
+  #     |   ^ operator
+  #     |     ~~ expression (lit)
+  #     },
+  #     %w(1.8 1.9) # optional
+  # )
+  # ~~~
+  def assert_parses(ast, code, source_maps='', versions=ALL_VERSIONS)
+    with_versions(versions) do |version, parser|
+      source_file = Parser::Source::Buffer.new('(assert_parses)')
+      source_file.source = code
+
+      begin
+        parsed_ast = parser.parse(source_file)
+      rescue => exc
+        backtrace = exc.backtrace
+        Exception.instance_method(:initialize).bind(exc).
+          call("(#{version}) #{exc.message}")
+        exc.set_backtrace(backtrace)
+        raise
+      end
+
+      assert_equal ast, parsed_ast,
+                   "(#{version}) AST equality"
+
+      parse_source_map_descriptions(source_maps) \
+          do |begin_pos, end_pos, map_field, ast_path, line|
+
+        astlet = traverse_ast(parsed_ast, ast_path)
+
+        if astlet.nil?
+          # This is a testsuite bug.
+          raise "No entity with AST path #{ast_path} in #{parsed_ast.inspect}"
+        end
+
+        assert astlet.frozen?
+
+        assert astlet.location.respond_to?(map_field),
+               "(#{version}) #{astlet.location.inspect}.respond_to?(#{map_field.inspect}) for:\n#{parsed_ast.inspect}"
+
+        range = astlet.location.send(map_field)
+
+        assert_source_range(begin_pos, end_pos, range, version, line.inspect)
+      end
+    end
+  end
+
+  # Use like this:
+  # ~~~
+  # assert_diagnoses(
+  #   [:warning, :ambiguous_prefix, { prefix: '*' }],
+  #   %q{foo *bar},
+  #   %q{    ^ location
+  #     |     ~~~ highlights (0)})
+  # ~~~
+  def assert_diagnoses(diagnostic, code, source_maps='', versions=ALL_VERSIONS)
+    with_versions(versions) do |version, parser|
+      source_file = Parser::Source::Buffer.new('(assert_diagnoses)')
+      source_file.source = code
+
+      begin
+        parser = parser.parse(source_file)
+      rescue Parser::SyntaxError
+        # do nothing; the diagnostic was reported
+      end
+
+      assert_equal 1, @diagnostics.count,
+                   "(#{version}) emits a single diagnostic, not\n" \
+                   "#{@diagnostics.map(&:render).join("\n")}"
+
+      emitted_diagnostic = @diagnostics.first
+
+      level, reason, arguments = diagnostic
+      arguments ||= {}
+      message     = Parser::MESSAGES[reason] % arguments
+
+      assert_equal level, emitted_diagnostic.level
+      assert_equal reason, emitted_diagnostic.reason
+      assert_equal arguments, emitted_diagnostic.arguments
+      assert_equal message, emitted_diagnostic.message
+
+      parse_source_map_descriptions(source_maps) \
+          do |begin_pos, end_pos, map_field, ast_path, line|
+
+        case map_field
+        when 'location'
+          assert_source_range begin_pos, end_pos,
+                              emitted_diagnostic.location,
+                              version, 'location'
+
+        when 'highlights'
+          index = ast_path.first.to_i
+
+          assert_source_range begin_pos, end_pos,
+                              emitted_diagnostic.highlights[index],
+                              version, "#{index}th highlight"
+
+        else
+          raise "Unknown diagnostic range #{map_field}"
+        end
+      end
+    end
+  end
+
+  def refute_diagnoses(code, versions=ALL_VERSIONS)
+    with_versions(versions) do |version, parser|
+      source_file = Parser::Source::Buffer.new('(refute_diagnoses)')
+      source_file.source = code
+
+      begin
+        parser = parser.parse(source_file)
+      rescue Parser::SyntaxError
+        # do nothing; the diagnostic was reported
+      end
+
+      assert_empty @diagnostics,
+                   "(#{version}) emits no diagnostics, not\n" \
+                   "#{@diagnostics.map(&:render).join("\n")}"
+    end
+  end
+
+  SOURCE_MAP_DESCRIPTION_RE =
+      /(?x)
+       ^(?# $1 skip)            ^(\s*)
+        (?# $2 highlight)        ([~\^]+)
+                                 \s+
+        (?# $3 source_map_field) ([a-z_]+)
+        (?# $5 ast_path)         (\s+\(([a-z_.\/0-9]+)\))?
+                                $/
+
+  def parse_source_map_descriptions(descriptions)
+    unless block_given?
+      return to_enum(:parse_source_map_descriptions, descriptions)
+    end
+
+    descriptions.each_line do |line|
+      # Remove leading "     |", if it exists.
+      line = line.sub(/^\s*\|/, '').rstrip
+
+      next if line.empty?
+
+      if (match = SOURCE_MAP_DESCRIPTION_RE.match(line))
+        begin_pos        = match[1].length
+        end_pos          = begin_pos + match[2].length
+        source_map_field = match[3]
+
+        if match[5]
+          ast_path = match[5].split('.')
+        else
+          ast_path = []
+        end
+
+        yield begin_pos, end_pos, source_map_field, ast_path, line
+      else
+        raise "Cannot parse source map description line: #{line.inspect}."
+      end
+    end
+  end
+
+  def traverse_ast(ast, path)
+    path.inject(ast) do |astlet, path_component|
+      # Split "dstr/2" to :dstr and 1
+      type_str, index_str = path_component.split('/')
+
+      type  = type_str.to_sym
+
+      if index_str.nil?
+        index = 0
+      else
+        index = index_str.to_i - 1
+      end
+
+      matching_children = \
+        astlet.children.select do |child|
+          AST::Node === child && child.type == type
+        end
+
+      matching_children[index]
+    end
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/racc_coverage_helper.rb b/app/server/vendor/parser-2.2.2.1/test/racc_coverage_helper.rb
new file mode 100644
index 0000000..88c8669
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/racc_coverage_helper.rb
@@ -0,0 +1,130 @@
+require 'racc/grammarfileparser'
+
+# Unfortunately, Ruby's Coverage module ignores module_eval statements,
+# which Racc uses to map `parser.y` locations in the generated
+# `parser.rb`.
+module RaccCoverage
+  @coverage  = {}
+  @base_path = nil
+  @trace     = nil
+
+  def self.start(parsers, base_path)
+    @base_path = base_path
+
+    parsers.each do |parser|
+      @coverage[parser] = extract_interesting_lines(parser, base_path)
+    end
+
+    @trace = TracePoint.trace(:line) do |trace|
+      lineno = trace.lineno - 1
+
+      if (line_coverage = @coverage[trace.path])
+        if line_coverage[lineno]
+          line_coverage[lineno] += 1
+        end
+      end
+    end
+  end
+
+  def self.stop
+    @trace.disable
+  end
+
+  # Ruby's TracePoint#lineno will point only on "interesting" lines,
+  # i.e.: only code (no comments or empty lines), no `end` keywords,
+  # and for multi-line statements, only the first line of the statement.
+  #
+  # This method implements a very dumb Ruby parser, which skips empty lines
+  # or lines with just comments, `end` keywords, and correctly handles
+  # multi-line statements of the following form:
+  #
+  #  * All lines of the statement except the last must end with `,`, `.` or `(`.
+  #
+  # Coverage can be disabled for code regions with annotations :nocov: and :cov:.
+  #
+  # Also, for best results, all actions should be delimited by at least
+  # one non-action line.
+  #
+  def self.extract_interesting_lines(parser, base_path)
+    grammar_source = File.join(@base_path, parser)
+    grammar_file   = Racc::GrammarFileParser.parse_file(grammar_source)
+
+    ruby_sources = [
+      # Header and footer aren't passed through module_eval
+      # in Racc-generated file, so the location info is lost.
+      *grammar_file.params.inner,
+    ].compact
+
+    grammar_file.grammar.each_rule do |rule|
+      source = rule.action.source
+      next if source.nil?
+
+      ruby_sources << source
+    end
+
+    lines = []
+
+    ruby_sources.each do |source|
+      first_line = source.lineno
+
+      state = :first_line
+
+      source.text.each_line.with_index do |line, index|
+        line = line.strip
+
+        continues = line.end_with?(',')   ||
+                      line.end_with?('(') ||
+                      line.end_with?('.')
+
+        case state
+        when :first_line
+          if line =~ /:nocov/
+            state = :nocov
+            next
+          elsif line.empty?   ||
+                  line == 'end' ||
+                  line.start_with?('#')
+            next
+          elsif continues
+            state = :mid_line
+          end
+
+          lines[first_line + index - 1] = 0
+
+        when :mid_line
+          unless continues
+            state = :first_line
+          end
+
+        when :nocov
+          if line =~ /:cov:/
+            state = :first_line
+          end
+        end
+      end
+    end
+
+    lines
+  end
+
+  def self.result
+    result =
+      @coverage.map do |parser, coverage|
+        [File.join(@base_path, parser), coverage]
+      end
+
+    Hash[result]
+  end
+end
+
+class << SimpleCov
+  def result_with_racc_coverage
+    @result ||= SimpleCov::Result.new(
+                  Coverage.result.merge(RaccCoverage.result))
+
+    result_without_racc_coverage
+  end
+
+  alias result_without_racc_coverage result
+  alias result result_with_racc_coverage
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_base.rb b/app/server/vendor/parser-2.2.2.1/test/test_base.rb
new file mode 100644
index 0000000..003bc88
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_base.rb
@@ -0,0 +1,29 @@
+require 'helper'
+require 'parser/current'
+
+class TestBase < Minitest::Test
+  include AST::Sexp
+
+  def test_parse
+    ast = Parser::CurrentRuby.parse('1')
+    assert_equal s(:int, 1), ast
+  end
+
+  def test_parse_with_comments
+    ast, comments = Parser::CurrentRuby.parse_with_comments('1 # foo')
+    assert_equal s(:int, 1), ast
+    assert_equal 1, comments.size
+    assert_equal '# foo', comments.first.text
+  end
+
+  def test_loc_to_node
+    ast = Parser::CurrentRuby.parse('1')
+    assert_equal ast.loc.node, ast
+  end
+
+  def test_loc_dup
+    ast = Parser::CurrentRuby.parse('1')
+    assert_equal nil, ast.loc.dup.node
+    Parser::AST::Node.new(:root, [], :location => ast.loc)
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_current.rb b/app/server/vendor/parser-2.2.2.1/test/test_current.rb
new file mode 100644
index 0000000..565a4e6
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_current.rb
@@ -0,0 +1,23 @@
+require 'helper'
+require 'parser/current'
+
+class TestCurrent < Minitest::Test
+  def test_current
+    case RUBY_VERSION
+    when '1.8.7'
+      assert_equal Parser::Ruby18, Parser::CurrentRuby
+    when '1.9.2', '1.9.3'
+      assert_equal Parser::Ruby19, Parser::CurrentRuby
+    when '2.0.0'
+      assert_equal Parser::Ruby20, Parser::CurrentRuby
+    when /^2\.1\.\d+/
+      assert_equal Parser::Ruby21, Parser::CurrentRuby
+    when /^2\.2\.\d+/
+      assert_equal Parser::Ruby22, Parser::CurrentRuby
+    when /^2\.3\.\d+/
+      assert_equal Parser::Ruby22, Parser::CurrentRuby
+    else
+      flunk "Update test_current for #{RUBY_VERSION}"
+    end
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_diagnostic.rb b/app/server/vendor/parser-2.2.2.1/test/test_diagnostic.rb
new file mode 100644
index 0000000..791aa4f
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_diagnostic.rb
@@ -0,0 +1,49 @@
+require 'helper'
+
+class TestDiagnostic < Minitest::Test
+  def setup
+    @buffer = Parser::Source::Buffer.new('(string)')
+    @buffer.source = 'if (this is some bad code + bugs)'
+
+    @range1 = Parser::Source::Range.new(@buffer, 0, 2) # if
+    @range2 = Parser::Source::Range.new(@buffer, 4, 8) # this
+  end
+
+  def test_verifies_levels
+    error = assert_raises ArgumentError do
+      Parser::Diagnostic.new(:foobar, :escape_eof, {}, @range1)
+    end
+
+    assert_match /level/, error.message
+  end
+
+  def test_freezes
+    string     = 'foo'
+    highlights = [@range2]
+
+    diag = Parser::Diagnostic.new(:error, :escape_eof, @range1, highlights)
+    assert diag.frozen?
+    assert diag.arguments.frozen?
+    assert diag.highlights.frozen?
+
+    refute string.frozen?
+    refute highlights.frozen?
+  end
+
+  def test_render
+    location = Parser::Source::Range.new(@buffer, 26, 27)
+
+    highlights = [
+      Parser::Source::Range.new(@buffer, 21, 25),
+      Parser::Source::Range.new(@buffer, 28, 32)
+    ]
+
+    diag  = Parser::Diagnostic.new(:error, :unexpected, { :character => '+' },
+                                   location, highlights)
+    assert_equal([
+      "(string):1:27: error: unexpected `+'",
+      'if (this is some bad code + bugs)',
+      '                     ~~~~ ^ ~~~~ '
+    ], diag.render)
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_diagnostic_engine.rb b/app/server/vendor/parser-2.2.2.1/test/test_diagnostic_engine.rb
new file mode 100644
index 0000000..a0777ee
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_diagnostic_engine.rb
@@ -0,0 +1,60 @@
+require 'helper'
+
+class TestDiagnosticEngine < Minitest::Test
+  def setup
+    @buffer  = Parser::Source::Buffer.new('(source)')
+    @buffer.source = 'foobar'
+
+    @engine = Parser::Diagnostic::Engine.new
+
+    @queue  = []
+    @engine.consumer = lambda { |diag| @queue << diag }
+  end
+
+  def test_process_warnings
+    warn = Parser::Diagnostic.new(:warning, :invalid_escape, @buffer, 1..2)
+    @engine.process(warn)
+
+    assert_equal [warn], @queue
+  end
+
+  def test_ignore_warnings
+    @engine.ignore_warnings = true
+
+    warn = Parser::Diagnostic.new(:warning, :invalid_escape, @buffer, 1..2)
+    @engine.process(warn)
+
+    assert_equal [], @queue
+  end
+
+  def test_all_errors_are_fatal
+    @engine.all_errors_are_fatal = true
+
+    error = Parser::Diagnostic.new(:error, :invalid_escape, @buffer, 1..2)
+
+    err = assert_raises Parser::SyntaxError do
+      @engine.process(error)
+    end
+
+    assert_equal error, err.diagnostic
+
+    assert_equal [error], @queue
+  end
+
+  def test_all_errors_are_collected
+    error = Parser::Diagnostic.new(:error, :invalid_escape, @buffer, 1..2)
+    @engine.process(error)
+
+    assert_equal [error], @queue
+  end
+
+  def test_fatal_error
+    fatal = Parser::Diagnostic.new(:fatal, :invalid_escape, @buffer, 1..2)
+
+    assert_raises Parser::SyntaxError do
+      @engine.process(fatal)
+    end
+
+    assert_equal [fatal], @queue
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_encoding.rb b/app/server/vendor/parser-2.2.2.1/test/test_encoding.rb
new file mode 100644
index 0000000..a3cd7d5
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_encoding.rb
@@ -0,0 +1,78 @@
+# encoding: binary
+
+require 'helper'
+
+class TestEncoding < Minitest::Test
+  include AST::Sexp
+
+  def recognize(string)
+    Parser::Source::Buffer.recognize_encoding(string)
+  end
+
+  if defined?(Encoding)
+    require 'parser/all'
+
+    def test_default
+      assert_equal nil, recognize('foobar')
+    end
+
+    def test_bom
+      assert_equal Encoding::UTF_8, recognize("\xef\xbb\xbf\nfoobar")
+      assert_equal Encoding::UTF_8, recognize("\xef\xbb\xbf# coding:koi8-r\nfoobar")
+    end
+
+    def test_magic_comment
+      assert_equal Encoding::KOI8_R, recognize("# coding:koi8-r\nfoobar")
+    end
+
+    def test_shebang
+      assert_equal Encoding::KOI8_R, recognize("#!/bin/foo\n# coding:koi8-r\nfoobar")
+    end
+
+    def test_case
+      assert_equal Encoding::KOI8_R, recognize("# coding:KoI8-r\nfoobar")
+    end
+
+    def test_space
+      assert_equal Encoding::KOI8_R, recognize("# coding : koi8-r\nfoobar")
+    end
+
+    def test_empty
+      assert_equal nil, recognize('')
+    end
+
+    def test_no_comment
+      assert_equal nil, recognize(%{require 'cane/encoding_aware_iterator'})
+    end
+
+    def test_adjacent
+      assert_equal nil, recognize('# codingkoi8-r')
+      assert_equal nil, recognize('# coding koi8-r')
+    end
+
+    def test_utf8_mac
+      assert_equal Encoding::UTF8_MAC, recognize('# coding: utf8-mac')
+    end
+
+    def test_suffix
+      assert_equal Encoding::UTF_8, recognize('# coding: utf-8-dos')
+      assert_equal Encoding::UTF_8, recognize('# coding: utf-8-unix')
+      assert_equal Encoding::UTF_8, recognize('# coding: utf-8-mac')
+
+      assert_raises(ArgumentError) do
+        assert_equal nil,           recognize('# coding: utf-8-dicks')
+      end
+    end
+
+    def test_parse_18_invalid_enc
+      ast = Parser::Ruby18.parse("# encoding:feynman-diagram\n1")
+      assert_equal ast, s(:int, 1)
+    end
+
+    def test_parse_19_invalid_enc
+      assert_raises(ArgumentError) do
+        Parser::Ruby19.parse("# encoding:feynman-diagram\n1")
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_lexer.rb b/app/server/vendor/parser-2.2.2.1/test/test_lexer.rb
new file mode 100644
index 0000000..dbb4db6
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_lexer.rb
@@ -0,0 +1,3093 @@
+# encoding: ascii-8bit
+
+require 'helper'
+require 'complex'
+
+class TestLexer < Minitest::Test
+  def setup_lexer(version)
+    @lex = Parser::Lexer.new(version)
+
+    @lex.comments = []
+    @lex.diagnostics = Parser::Diagnostic::Engine.new
+    @lex.diagnostics.all_errors_are_fatal = true
+    # @lex.diagnostics.consumer = lambda { |diag| $stderr.puts "", diag.render }
+  end
+
+  def setup
+    setup_lexer 18
+  end
+
+  #
+  # Tools
+  #
+
+  def utf(str)
+    if str.respond_to?(:force_encoding)
+      str.force_encoding(Encoding::UTF_8)
+    else
+      str
+    end
+  end
+
+  #
+  # Additional matchers
+  #
+
+  def refute_scanned(s, *args)
+    assert_raises Parser::SyntaxError do
+      assert_scanned(s, *args)
+    end
+  end
+
+  def assert_escape(expected, input)
+    source_buffer = Parser::Source::Buffer.new('(assert_escape)')
+
+    if defined?(Encoding)
+      source_buffer.source = "\"\\#{input}\"".encode(input.encoding)
+    else
+      source_buffer.source = "\"\\#{input}\""
+    end
+
+    @lex.reset
+    @lex.source_buffer = source_buffer
+
+    lex_token, (lex_value, *) = @lex.advance
+
+    if lex_value.respond_to?(:force_encoding)
+      lex_value.force_encoding(Encoding::BINARY)
+    end
+
+    assert_equal [:tSTRING, expected],
+                 [lex_token, lex_value],
+                 source_buffer.source
+  end
+
+  def refute_escape(input)
+    err = assert_raises Parser::SyntaxError do
+      @lex.state = :expr_beg
+      assert_scanned "%Q[\\#{input}]"
+    end
+    assert_equal :fatal, err.diagnostic.level
+  end
+
+  def assert_lex_fname(name, type)
+    assert_scanned("def #{name} ", :kDEF, 'def', type, name)
+
+    assert_equal :expr_endfn, @lex.state
+  end
+
+  def assert_scanned(input, *args)
+    source_buffer = Parser::Source::Buffer.new('(assert_scanned)')
+    source_buffer.source = input
+
+    @lex.reset(false)
+    @lex.source_buffer = source_buffer
+
+    until args.empty? do
+      token, value = args.shift(2)
+
+      lex_token, (lex_value, *) = @lex.advance
+      assert lex_token, 'no more tokens'
+      assert_operator [lex_token, lex_value], :eql?, [token, value], input
+    end
+
+    lex_token, (lex_value, *) = @lex.advance
+    refute lex_token, "must be empty, but had #{[lex_token, lex_value].inspect}"
+  end
+
+  #
+  # Tests
+  #
+
+  def test_read_escape
+    assert_escape "\\",   "\\"
+    assert_escape "\n",   "n"
+    assert_escape "\t",   "t"
+    assert_escape "\r",   "r"
+    assert_escape "\f",   "f"
+    assert_escape "\13",  "v"
+    assert_escape "\0",   "0"
+    assert_escape "\07",  "a"
+    assert_escape "\007", "a"
+    assert_escape "\033", "e"
+    assert_escape "\377", "377"
+    assert_escape "\377", "xff"
+    assert_escape "\010", "b"
+    assert_escape " ",    "s"
+    assert_escape "q",    "q" # plain vanilla escape
+  end
+
+  def test_read_escape_c
+    assert_escape "\030", "C-x"
+    assert_escape "\030", "cx"
+    assert_escape "\230", 'C-\M-x'
+    assert_escape "\230", 'c\M-x'
+
+    assert_escape "\177", "C-?"
+    assert_escape "\177", "c?"
+    assert_escape "\r",   "cM"
+  end
+
+  def test_read_escape_m
+    assert_escape "\370", "M-x"
+    assert_escape "\230", 'M-\C-x'
+    assert_escape "\230", 'M-\cx'
+  end
+
+  def test_read_escape_errors
+    refute_escape ""
+
+    refute_escape "M"
+    refute_escape "M-"
+    refute_escape "Mx"
+
+    refute_escape "Cx"
+    refute_escape "C"
+    refute_escape "C-"
+
+    refute_escape "c"
+
+    refute_escape "x"
+  end
+
+  def test_read_escape_unicode__19
+    if RUBY_VERSION >= '1.9'
+      assert_escape "\x09", 'u{9}'
+      assert_escape "\x31", 'u{31}'
+      assert_escape "\x09\x01", 'u{9 1}'
+
+      assert_escape "\xc4\xa3", utf('u0123')
+      assert_escape "\xc4\xa3\xc3\xb0\xeb\x84\xa3", utf('u{123 f0 B123}')
+    end
+  end
+
+  def test_read_escape_unicode_bad__19
+    if RUBY_VERSION >= '1.9'
+      refute_escape 'u123'
+      refute_escape 'u{}'
+      refute_escape 'u{123 f0h}'
+      refute_escape 'u{123 f0'
+    end
+  end
+
+  def test_ambiguous_uminus
+    assert_scanned("m -3",
+                   :tIDENTIFIER, "m",
+                   :tUMINUS_NUM, "-",
+                   :tINTEGER, 3)
+  end
+
+  def test_ambiguous_uplus
+    assert_scanned("m +3",
+                   :tIDENTIFIER, "m",
+                   :tINTEGER, 3)
+  end
+
+  def test_and
+    assert_scanned "&", :tAMPER, "&"
+  end
+
+  def test_and2
+    @lex.state = :expr_end
+
+    assert_scanned "&&", :tANDOP, "&&"
+  end
+
+  def test_and2_equals
+    @lex.state = :expr_end
+
+    assert_scanned "&&=", :tOP_ASGN, "&&"
+  end
+
+  def test_and_arg
+    @lex.state = :expr_arg
+
+    assert_scanned(" &y",
+                   :tAMPER, "&",
+                   :tIDENTIFIER, "y")
+  end
+
+  def test_and_equals
+    @lex.state = :expr_end
+
+    assert_scanned "&=", :tOP_ASGN, "&"
+  end
+
+  def test_and_expr
+    @lex.state = :expr_arg
+
+    assert_scanned("x & y",
+                   :tIDENTIFIER, "x",
+                   :tAMPER2, "&",
+                   :tIDENTIFIER, "y")
+  end
+
+  def test_and_meth
+    assert_lex_fname "&", :tAMPER2
+  end
+
+  def test_assoc
+    assert_scanned "=>", :tASSOC, "=>"
+  end
+
+  def test_label__18
+    assert_scanned("{a:b",
+                   :tLBRACE,     "{",
+                   :tIDENTIFIER, "a",
+                   :tSYMBOL,     "b")
+  end
+
+  def test_label_in_params__18
+    assert_scanned("foo(a:b",
+                   :tIDENTIFIER, "foo",
+                   :tLPAREN2,    "(",
+                   :tIDENTIFIER, "a",
+                   :tSYMBOL,     "b")
+  end
+
+  def test_label__19
+    setup_lexer 19
+
+    assert_scanned("{a:b",
+                   :tLBRACE,     "{",
+                   :tLABEL,      "a",
+                   :tIDENTIFIER, "b")
+  end
+
+  def test_label_in_params__19
+    setup_lexer 19
+
+    assert_scanned("foo(a:b",
+                   :tIDENTIFIER, "foo",
+                   :tLPAREN2,    "(",
+                   :tLABEL,      "a",
+                   :tIDENTIFIER, "b")
+  end
+
+  def test_label_fid__19
+    setup_lexer 19
+
+    assert_scanned("{a?:true",
+                   :tLBRACE,     '{',
+                   :tLABEL,      'a?',
+                   :kTRUE,       'true')
+  end
+
+  def test_label__22
+    setup_lexer 22
+
+    assert_scanned("{'a':",
+                   :tLBRACE,          '{',
+                   :tSTRING_BEG,      "'",
+                   :tSTRING_CONTENT,  'a',
+                   :tLABEL_END,       "'")
+  end
+
+  def test_label_nested__22
+    setup_lexer 22
+
+    assert_scanned("{'a\":':",
+                   :tLBRACE,          '{',
+                   :tSTRING_BEG,      "'",
+                   :tSTRING_CONTENT,  'a":',
+                   :tLABEL_END,       "'")
+  end
+
+  def test_label_colon2__22
+    setup_lexer 22
+
+    assert_scanned("{'a'::",
+                   :tLBRACE, '{',
+                   :tSTRING, "a",
+                   :tCOLON2, '::')
+  end
+
+  def test_command_start__19
+    setup_lexer 19
+
+    %w[case elsif for in until when while
+      if unless and or].each do |keyword|
+      token = "k#{keyword.upcase}".to_sym
+
+      @lex.reset
+      assert_scanned("#{keyword} a:b",
+                     token,         keyword,
+                     :tIDENTIFIER,  "a",
+                     :tSYMBOL,      "b")
+    end
+  end
+
+  def test_mod_not_command_start__19
+    setup_lexer 19
+
+    %w[if unless while until rescue].each do |keyword|
+      token = "k#{keyword.upcase}_MOD".to_sym
+
+      @lex.state = :expr_end
+      assert_scanned("#{keyword} a:b",
+                     token,         keyword,
+                     :tLABEL,       "a",
+                     :tIDENTIFIER,  "b")
+    end
+  end
+
+  def test_back_ref
+    assert_scanned("[$&, $`, $', $+]",
+                   :tLBRACK,   "[",
+                   :tBACK_REF, "$&", :tCOMMA, ",",
+                   :tBACK_REF, "$`", :tCOMMA, ",",
+                   :tBACK_REF, "$'", :tCOMMA, ",",
+                   :tBACK_REF, "$+",
+                   :tRBRACK,   "]")
+  end
+
+  def test_backslash
+    assert_scanned("1 \\\n+ 2",
+                   :tINTEGER, 1,
+                   :tPLUS, "+",
+                   :tINTEGER, 2)
+  end
+
+  def test_backslash_bad
+    refute_scanned("1 \\ + 2",
+                   :tINTEGER, 1)
+  end
+
+  def test_backtick
+    assert_scanned("`ls`",
+                   :tXSTRING_BEG, "`",
+                   :tSTRING_CONTENT, "ls",
+                   :tSTRING_END, "`")
+  end
+
+  def test_backtick_cmdarg
+    @lex.state = :expr_dot
+    assert_scanned("\n`", :tBACK_REF2, "`") # \n ensures expr_cmd
+
+    assert_equal :expr_arg, @lex.state
+  end
+
+  def test_backtick_dot
+    @lex.state = :expr_dot
+    assert_scanned("a.`(3)",
+                   :tIDENTIFIER, "a",
+                   :tDOT, ".",
+                   :tBACK_REF2, "`",
+                   :tLPAREN2, "(",
+                   :tINTEGER, 3,
+                   :tRPAREN, ")")
+  end
+
+  def test_backtick_method
+    @lex.state = :expr_fname
+    assert_scanned("`", :tBACK_REF2, "`")
+    assert_equal :expr_endfn, @lex.state
+  end
+
+  def test_bad_char
+    refute_scanned(" \010 ")
+  end
+
+  def test_bang
+    assert_scanned "!", :tBANG, "!"
+  end
+
+  def test_bang_equals
+    assert_scanned "!=", :tNEQ, "!="
+  end
+
+  def test_bang_tilde
+    assert_scanned "!~", :tNMATCH, "!~"
+  end
+
+  def test_def_ubang
+    setup_lexer(20)
+
+    @lex.state = :expr_fname
+    assert_scanned '!@', :tBANG, '!@'
+  end
+
+  def test_carat
+    assert_scanned "^", :tCARET, "^"
+  end
+
+  def test_carat_equals
+    assert_scanned "^=", :tOP_ASGN, "^"
+  end
+
+  def test_colon2
+    assert_scanned("A::B",
+                   :tCONSTANT, "A",
+                   :tCOLON2,   "::",
+                   :tCONSTANT, "B")
+
+    @lex.state = :expr_arg
+    assert_scanned("::Array",
+                   :tCOLON2, "::",
+                   :tCONSTANT, "Array")
+  end
+
+  def test_colon3
+    assert_scanned("::Array",
+                   :tCOLON3, "::",
+                   :tCONSTANT, "Array")
+
+    @lex.state = :expr_arg
+    assert_scanned(" ::Array",
+                   :tCOLON3, "::",
+                   :tCONSTANT, "Array")
+  end
+
+  def test_comma
+    assert_scanned ",", :tCOMMA, ","
+  end
+
+  def test_comment
+    assert_scanned("1 # one\n# two\n2",
+                   :tINTEGER, 1,
+                   :tNL, nil,
+                   :tINTEGER, 2)
+
+    assert_equal 2, @lex.comments.length
+    assert_equal '# one', @lex.comments[0].text
+    assert_equal '# two', @lex.comments[1].text
+  end
+
+  def test_comment_expr_beg
+    assert_scanned("{#1\n}",
+                   :tLBRACE, "{",
+                   :tRCURLY, "}")
+  end
+
+  def test_comment_begin
+    assert_scanned("=begin\nblah\nblah\n=end\n42",
+                   :tINTEGER, 42)
+    assert_equal 1, @lex.comments.length
+    assert_equal "=begin\nblah\nblah\n=end\n", @lex.comments[0].text
+  end
+
+  def test_comment_begin_bad
+    refute_scanned("=begin\nblah\nblah\n")
+  end
+
+  def test_comment_begin_not_comment
+    assert_scanned("beginfoo = 5\np x \\\n=beginfoo",
+                   :tIDENTIFIER, "beginfoo",
+                   :tEQL,          "=",
+                   :tINTEGER,    5,
+                   :tNL,         nil,
+                   :tIDENTIFIER, "p",
+                   :tIDENTIFIER, "x",
+                   :tEQL,          "=",
+                   :tIDENTIFIER, "beginfoo")
+  end
+
+  def test_comment_begin_space
+    assert_scanned("=begin blah\nblah\n=end\n")
+
+    assert_equal 1, @lex.comments.length
+    assert_equal "=begin blah\nblah\n=end\n", @lex.comments[0].text
+  end
+
+  def test_comment_end_space_and_text
+    assert_scanned("=begin blah\nblah\n=end blab\n")
+
+    assert_equal 1, @lex.comments.length
+    assert_equal "=begin blah\nblah\n=end blab\n", @lex.comments[0].text
+  end
+
+  def test_comment_eos
+    assert_scanned("# comment")
+  end
+
+  def test_constant
+    assert_scanned("ArgumentError",
+                   :tCONSTANT, "ArgumentError")
+  end
+
+  def test_constant_semi
+    assert_scanned("ArgumentError;",
+                   :tCONSTANT, "ArgumentError",
+                   :tSEMI, ";")
+  end
+
+  def test_cvar
+    assert_scanned "@@blah", :tCVAR, "@@blah"
+  end
+
+  def test_cvar_bad
+    refute_scanned "@@1"
+  end
+
+  def test_div
+    assert_scanned("a / 2",
+                   :tIDENTIFIER, "a",
+                   :tDIVIDE, "/",
+                   :tINTEGER, 2)
+  end
+
+  def test_div_equals
+    assert_scanned("a /= 2",
+                   :tIDENTIFIER, "a",
+                   :tOP_ASGN, "/",
+                   :tINTEGER, 2)
+  end
+
+  def test_do
+    assert_scanned("x do 42 end",
+                   :tIDENTIFIER, "x",
+                   :kDO, "do",
+                   :tINTEGER, 42,
+                   :kEND, "end")
+  end
+
+  def test_do_cond
+    @lex.cond.push(true)
+
+    assert_scanned("x do 42 end",
+                   :tIDENTIFIER, "x",
+                   :kDO_COND, "do",
+                   :tINTEGER, 42,
+                   :kEND, "end")
+  end
+
+  def test_do_block
+    @lex.state = :expr_endarg
+
+    assert_scanned("do 42 end",
+                   :kDO_BLOCK, "do",
+                   :tINTEGER, 42,
+                   :kEND, "end")
+  end
+
+  def test_do_cond
+    @lex.cond.push true
+
+    assert_scanned("x do 42 end",
+                   :tIDENTIFIER, "x",
+                   :kDO_COND, "do",
+                   :tINTEGER, 42,
+                   :kEND, "end")
+  end
+
+  def test_dot
+    assert_scanned ".", :tDOT, "."
+  end
+
+  def test_dot2
+    assert_scanned "..", :tDOT2, ".."
+  end
+
+  def test_dot3
+    assert_scanned "...", :tDOT3, "..."
+  end
+
+  def test_equals
+    assert_scanned "=", :tEQL, "="
+  end
+
+  def test_equals2
+    assert_scanned "==", :tEQ, "=="
+  end
+
+  def test_equals3
+    assert_scanned "===", :tEQQ, "==="
+  end
+
+  def test_equals_tilde
+    assert_scanned "=~", :tMATCH, "=~"
+  end
+
+  def test_float
+    assert_scanned "1.0", :tFLOAT, 1.0
+  end
+
+  def test_float_bad_no_underscores
+    refute_scanned "1__0.0"
+  end
+
+  def test_float_bad_no_zero_leading
+    refute_scanned ".0"
+  end
+
+  def test_float_bad_trailing_underscore
+    refute_scanned "123_.0"
+  end
+
+  def test_float_call
+    assert_scanned("1.0.to_s",
+                   :tFLOAT, 1.0,
+                   :tDOT, ".",
+                   :tIDENTIFIER, "to_s")
+  end
+
+  def test_float_dot_E
+    assert_scanned "1.0E10", :tFLOAT, 1.0e10
+  end
+
+  def test_float_dot_E_neg
+    assert_scanned("-1.0E10",
+                   :tUMINUS_NUM, "-",
+                   :tFLOAT, 1.0e10)
+  end
+
+  def test_float_dot_e
+    assert_scanned "1.0e10", :tFLOAT, 1.0e10
+  end
+
+  def test_float_dot_e_neg
+    assert_scanned("-1.0e10",
+                   :tUMINUS_NUM, "-",
+                   :tFLOAT, 1.0e10)
+  end
+
+  def test_float_e
+    assert_scanned "1e10", :tFLOAT, 1e10
+  end
+
+  def test_float_e_bad_trailing_underscore
+    refute_scanned "123_e10"
+  end
+
+  def test_float_e_minus
+    assert_scanned "1e-10", :tFLOAT, 1e-10
+  end
+
+  def test_float_e_neg
+    assert_scanned("-1e10",
+                   :tUMINUS_NUM, "-",
+                   :tFLOAT, 1e10)
+  end
+
+  def test_float_e_neg_minus
+    assert_scanned("-1e-10",
+                   :tUMINUS_NUM, "-",
+                   :tFLOAT, 1e-10)
+  end
+
+  def test_float_e_neg_plus
+    assert_scanned("-1e+10",
+                   :tUMINUS_NUM, "-",
+                   :tFLOAT, 1e10)
+  end
+
+  def test_float_e_plus
+    assert_scanned "1e+10", :tFLOAT, 1e10
+  end
+
+  def test_float_e_zero
+    assert_scanned "0e0", :tFLOAT, 0e0
+  end
+
+  def test_float_e_nothing
+    [18, 19, 20].each do |version|
+      setup_lexer version
+
+      refute_scanned "1end"
+      refute_scanned "1.1end"
+    end
+
+    setup_lexer 21
+
+    assert_scanned("1end",
+                   :tINTEGER, 1,
+                   :kEND,     'end')
+    assert_scanned("1.1end",
+                   :tFLOAT,   1.1,
+                   :kEND,     'end')
+  end
+
+  def test_float_neg
+    assert_scanned("-1.0",
+                   :tUMINUS_NUM, "-",
+                   :tFLOAT, 1.0)
+  end
+
+  def test_ge
+    assert_scanned("a >= 2",
+                   :tIDENTIFIER, "a",
+                   :tGEQ, ">=",
+                   :tINTEGER, 2)
+  end
+
+  def test_global
+    assert_scanned("$blah", :tGVAR, "$blah")
+  end
+
+  def test_global_backref
+    assert_scanned("$`", :tBACK_REF, "$`")
+  end
+
+  # This was removed in 2.1.
+  # def test_global_dash_nothing
+  #   assert_scanned("$- ", :tGVAR, "$-")
+  # end
+
+  def test_global_dash_something
+    assert_scanned("$-x", :tGVAR, "$-x")
+  end
+
+  def test_global_number
+    assert_scanned("$10", :tNTH_REF, 10)
+  end
+
+  def test_global_other
+    assert_scanned("[$~, $*, $$, $?, $!, $@, $/, $\\, $;, $,, $., $=, $:, $<, $>, $\"]",
+                   :tLBRACK, "[",
+                   :tGVAR,   "$~",  :tCOMMA, ",",
+                   :tGVAR,   "$*",  :tCOMMA, ",",
+                   :tGVAR,   "$$",  :tCOMMA, ",",
+                   :tGVAR,   "$\?",  :tCOMMA, ",",
+                   :tGVAR,   "$!",  :tCOMMA, ",",
+                   :tGVAR,   "$@",  :tCOMMA, ",",
+                   :tGVAR,   "$/",  :tCOMMA, ",",
+                   :tGVAR,   "$\\", :tCOMMA, ",",
+                   :tGVAR,   "$;",  :tCOMMA, ",",
+                   :tGVAR,   "$,",  :tCOMMA, ",",
+                   :tGVAR,   "$.",  :tCOMMA, ",",
+                   :tGVAR,   "$=",  :tCOMMA, ",",
+                   :tGVAR,   "$:",  :tCOMMA, ",",
+                   :tGVAR,   "$<",  :tCOMMA, ",",
+                   :tGVAR,   "$>",  :tCOMMA, ",",
+                   :tGVAR,   "$\"",
+                   :tRBRACK, "]")
+  end
+
+  def test_global_underscore
+    assert_scanned("$_",
+                   :tGVAR,     "$_")
+  end
+
+  def test_global_wierd
+    assert_scanned("$__blah",
+                   :tGVAR,     "$__blah")
+  end
+
+  def test_global_zero
+    assert_scanned("$0", :tGVAR, "$0")
+  end
+
+  def test_gt
+    assert_scanned("a > 2",
+                   :tIDENTIFIER, "a",
+                   :tGT, ">",
+                   :tINTEGER, 2)
+  end
+
+  def test_heredoc_backtick
+    assert_scanned("a = <<`EOF`\n  blah blah\nEOF\n",
+                   :tIDENTIFIER,     "a",
+                   :tEQL,            "=",
+                   :tXSTRING_BEG,    "<<`",
+                   :tSTRING_CONTENT, "  blah blah\n",
+                   :tSTRING_END,     "EOF",
+                   :tNL,             nil)
+  end
+
+  def test_heredoc_double
+    assert_scanned("a = <<\"EOF\"\n  blah blah\nEOF\n",
+                   :tIDENTIFIER,     "a",
+                   :tEQL,            "=",
+                   :tSTRING_BEG,     "<<\"",
+                   :tSTRING_CONTENT, "  blah blah\n",
+                   :tSTRING_END,     "EOF",
+                   :tNL,             nil)
+  end
+
+  def test_heredoc_double_dash
+    assert_scanned("a = <<-\"EOF\"\n  blah blah\n  EOF\n",
+                   :tIDENTIFIER,     "a",
+                   :tEQL,            "=",
+                   :tSTRING_BEG,     "<<\"",
+                   :tSTRING_CONTENT, "  blah blah\n",
+                   :tSTRING_END,     "EOF",
+                   :tNL,             nil)
+  end
+
+  def test_heredoc_double_eos
+    refute_scanned("a = <<\"EOF\"\nblah",
+                   :tIDENTIFIER,     "a",
+                   :tEQL,            "=",
+                   :tSTRING_BEG,     "<<\"")
+  end
+
+  def test_heredoc_double_eos_nl
+    refute_scanned("a = <<\"EOF\"\nblah\n",
+                   :tIDENTIFIER,     "a",
+                   :tEQL,            "=",
+                   :tSTRING_BEG,     "<<\"")
+  end
+
+  def test_heredoc_double_interp
+    assert_scanned("a = <<\"EOF\"\n#x a \#@a b \#$b c \#{3} \nEOF\n",
+                   :tIDENTIFIER,     "a",
+                   :tEQL,            "=",
+                   :tSTRING_BEG,     "<<\"",
+                   :tSTRING_CONTENT, "#x a ",
+                   :tSTRING_DVAR,    nil,
+                   :tIVAR,           "@a",
+                   :tSTRING_CONTENT, " b ",
+                   :tSTRING_DVAR,    nil,
+                   :tGVAR,           "$b",
+                   :tSTRING_CONTENT, " c ",
+                   :tSTRING_DBEG,    '#{',
+                   :tINTEGER,        3,
+                   :tRCURLY,         "}",
+                   :tSTRING_CONTENT, " \n",
+                   :tSTRING_END,     "EOF",
+                   :tNL,             nil)
+  end
+
+  def test_heredoc_empty
+    assert_scanned("<<\"\"\n\#{x}\nblah2\n\n",
+                   :tSTRING_BEG,     "<<\"",
+                   :tSTRING_DBEG,    "\#{",
+                   :tIDENTIFIER,     "x",
+                   :tRCURLY,         "}",
+                   :tSTRING_CONTENT, "\n",
+                   :tSTRING_CONTENT, "blah2\n",
+                   :tSTRING_END,     "",
+                   :tNL,             nil)
+  end
+
+  def test_heredoc_none
+    assert_scanned("a = <<EOF\nblah\nblah\nEOF",
+                   :tIDENTIFIER,     "a",
+                   :tEQL,            "=",
+                   :tSTRING_BEG,     "<<\"",
+                   :tSTRING_CONTENT, "blah\n",
+                   :tSTRING_CONTENT, "blah\n",
+                   :tSTRING_END,     "EOF",
+                   :tNL,             nil)
+  end
+
+  def test_heredoc_none_dash
+    assert_scanned("a = <<-EOF\nblah\nblah\n  EOF",
+                   :tIDENTIFIER,     "a",
+                   :tEQL,            "=",
+                   :tSTRING_BEG,     "<<\"",
+                   :tSTRING_CONTENT, "blah\n",
+                   :tSTRING_CONTENT, "blah\n",
+                   :tSTRING_END,     "EOF",
+                   :tNL,             nil)
+  end
+
+  def test_heredoc_single
+    assert_scanned("a = <<'EOF'\n  blah blah\nEOF\n",
+                   :tIDENTIFIER,     "a",
+                   :tEQL,            "=",
+                   :tSTRING_BEG,     "<<'",
+                   :tSTRING_CONTENT, "  blah blah\n",
+                   :tSTRING_END,     "EOF",
+                   :tNL,             nil)
+  end
+
+  def test_heredoc_single_bad_eos_body
+    refute_scanned("a = <<'EOF'\nblah",
+                   :tIDENTIFIER,     "a",
+                   :tEQL,              "=",
+                   :tSTRING_BEG,     "'")
+  end
+
+  def test_heredoc_single_dash
+    assert_scanned("a = <<-'EOF'\n  blah blah\n  EOF\n",
+                   :tIDENTIFIER,     "a",
+                   :tEQL,            "=",
+                   :tSTRING_BEG,     "<<'",
+                   :tSTRING_CONTENT, "  blah blah\n",
+                   :tSTRING_END,     "EOF",
+                   :tNL,             nil)
+  end
+
+  def test_heredoc_one_character
+    assert_scanned("a = <<E\nABCDEF\nE\n",
+                   :tIDENTIFIER,     "a",
+                   :tEQL,            "=",
+                   :tSTRING_BEG,     "<<\"",
+                   :tSTRING_CONTENT, "ABCDEF\n",
+                   :tSTRING_END,     "E",
+                   :tNL,             nil)
+  end
+
+  def test_heredoc_cr
+    assert_scanned("a = <<E\r\r\nABCDEF\r\r\nE\r\r\r\n",
+                   :tIDENTIFIER,     "a",
+                   :tEQL,            "=",
+                   :tSTRING_BEG,     "<<\"",
+                   :tSTRING_CONTENT, "ABCDEF\r\n",
+                   :tSTRING_END,     "E",
+                   :tNL,             nil)
+  end
+
+  def test_identifier
+    assert_scanned("identifier",
+                   :tIDENTIFIER, "identifier")
+  end
+
+  def test_identifier_bang
+    assert_scanned("identifier!",
+                   :tFID,        "identifier!")
+
+    assert_scanned("identifier!=",
+                   :tIDENTIFIER, "identifier",
+                   :tNEQ,        "!=")
+  end
+
+  def test_identifier_cmp
+    assert_lex_fname "<=>", :tCMP
+  end
+
+  def test_identifier_def
+    assert_lex_fname "identifier", :tIDENTIFIER
+  end
+
+  def test_identifier_eh
+    assert_scanned("identifier?", :tFID, "identifier?")
+  end
+
+  def test_identifier_equals_arrow
+    assert_scanned(":blah==>",
+                   :tSYMBOL, "blah=",
+                   :tASSOC, "=>")
+  end
+
+  def test_identifier_equals3
+    assert_scanned(":a===b",
+                   :tSYMBOL, "a",
+                   :tEQQ, "===",
+                   :tIDENTIFIER, "b")
+  end
+
+  def test_identifier_equals_equals_arrow
+    assert_scanned(":a==>b",
+                   :tSYMBOL, "a=",
+                   :tASSOC, "=>",
+                   :tIDENTIFIER, "b")
+  end
+
+  def test_identifier_equals_caret
+    assert_lex_fname "^", :tCARET
+  end
+
+  def test_identifier_equals_def
+    assert_lex_fname "identifier=", :tIDENTIFIER
+  end
+
+  def test_identifier_equals_def2
+    assert_lex_fname "==", :tEQ
+  end
+
+  def test_identifier_equals_expr
+    @lex.state = :expr_dot
+    assert_scanned("y = arg",
+                   :tIDENTIFIER, "y",
+                   :tEQL, "=",
+                   :tIDENTIFIER, "arg")
+
+    assert_equal :expr_arg, @lex.state
+  end
+
+  def test_identifier_equals_or
+    assert_lex_fname "|", :tPIPE
+  end
+
+  def test_identifier_equals_slash
+    assert_lex_fname "/", :tDIVIDE
+  end
+
+  def test_identifier_equals_tilde
+    @lex.state = :expr_fname
+    assert_scanned("identifier=~",
+                   :tIDENTIFIER, "identifier=",
+                   :tTILDE,      "~")
+  end
+
+  def test_identifier_gt
+    assert_lex_fname ">", :tGT
+  end
+
+  def test_identifier_le
+    assert_lex_fname "<=", :tLEQ
+  end
+
+  def test_identifier_lt
+    assert_lex_fname "<", :tLT
+  end
+
+  def test_identifier_tilde
+    assert_lex_fname "~", :tTILDE
+  end
+
+  def test_identifier_defined?
+    assert_lex_fname "defined?", :kDEFINED
+  end
+
+  def test_index
+    assert_lex_fname "[]", :tAREF
+  end
+
+  def test_index_equals
+    assert_lex_fname "[]=", :tASET
+  end
+
+  def test_integer
+    assert_scanned "42", :tINTEGER, 42
+  end
+
+  def test_integer_bin
+    assert_scanned "0b101010", :tINTEGER, 42
+  end
+
+  def test_integer_bin_bad_none
+    refute_scanned "0b "
+  end
+
+  def test_integer_bin_bad_underscores
+    refute_scanned "0b10__01"
+  end
+
+  def test_integer_dec
+    assert_scanned "42", :tINTEGER, 42
+  end
+
+  def test_integer_dec_bad_underscores
+    refute_scanned "42__24"
+  end
+
+  def test_integer_dec_d
+    assert_scanned "0d42", :tINTEGER, 42
+  end
+
+  def test_integer_dec_d_bad_none
+    refute_scanned "0d"
+  end
+
+  def test_integer_dec_d_bad_underscores
+    refute_scanned "0d42__24"
+  end
+
+  def test_question_eh_a__18
+    setup_lexer 18
+
+    assert_scanned "?a", :tINTEGER, 97
+  end
+
+  def test_question_eh_a__19
+    setup_lexer 19
+
+    assert_scanned '?a', :tCHARACTER, "a"
+  end
+
+  def test_question_eh_escape_M_escape_C__18
+    setup_lexer 18
+
+    assert_scanned '?\M-\C-a', :tINTEGER, 129
+  end
+
+  def test_question_eh_escape_M_escape_C__19
+    setup_lexer 19
+
+    assert_scanned '?\M-\C-a', :tCHARACTER, "\M-\C-a"
+  end
+
+  def test_integer_hex
+    assert_scanned "0x2a", :tINTEGER, 42
+  end
+
+  def test_integer_hex_bad_none
+    refute_scanned "0x "
+  end
+
+  def test_integer_hex_bad_underscores
+    refute_scanned "0xab__cd"
+  end
+
+  def test_integer_oct
+    assert_scanned "052", :tINTEGER, 42
+  end
+
+  def test_integer_oct_bad_range
+    refute_scanned "08"
+  end
+
+  def test_integer_oct_bad_underscores
+    refute_scanned "01__23"
+  end
+
+  def test_integer_oct_O
+    assert_scanned "0O52", :tINTEGER, 42
+  end
+
+  def test_integer_oct_O_bad_range
+    refute_scanned "0O1238"
+  end
+
+  def test_integer_oct_O_bad_underscores
+    refute_scanned "0O1__23"
+  end
+
+  def test_integer_oct_O_not_bad_none
+    assert_scanned "0O ", :tINTEGER, 0
+  end
+
+  def test_integer_oct_o
+    assert_scanned "0o52", :tINTEGER, 42
+  end
+
+  def test_integer_oct_o_bad_range
+    refute_scanned "0o1283"
+  end
+
+  def test_integer_oct_o_bad_underscores
+    refute_scanned "0o1__23"
+  end
+
+  def test_integer_oct_o_not_bad_none
+    assert_scanned "0o ", :tINTEGER, 0
+  end
+
+  def test_integer_trailing
+    assert_scanned("1.to_s",
+                   :tINTEGER, 1,
+                   :tDOT, '.',
+                   :tIDENTIFIER, 'to_s')
+  end
+
+  def test_integer_underscore
+    assert_scanned "4_2", :tINTEGER, 42
+  end
+
+  def test_integer_underscore_bad
+    refute_scanned "4__2"
+  end
+
+  def test_integer_zero
+    assert_scanned "0", :tINTEGER, 0
+  end
+
+  def test_ivar
+    assert_scanned "@blah", :tIVAR, "@blah"
+  end
+
+  def test_ivar_bad
+    refute_scanned "@1"
+  end
+
+  def test_ivar_bad_0_length
+    refute_scanned "1+@\n", :tINTEGER, 1, :tPLUS, "+"
+  end
+
+  def test_keyword_expr
+    @lex.state = :expr_endarg
+
+    assert_scanned("if", :kIF_MOD, "if")
+
+    assert_equal :expr_beg, @lex.state
+  end
+
+  def test_lt
+    assert_scanned "<", :tLT, "<"
+  end
+
+  def test_lt2
+    assert_scanned("a <\< b",
+                   :tIDENTIFIER, "a",
+                   :tLSHFT, "<\<",
+                   :tIDENTIFIER, "b")
+
+  end
+
+  def test_lt2_equals
+    assert_scanned("a <\<= b",
+                   :tIDENTIFIER, "a",
+                   :tOP_ASGN, "<\<",
+                   :tIDENTIFIER, "b")
+  end
+
+  def test_lt_equals
+    assert_scanned "<=", :tLEQ, "<="
+  end
+
+  def test_minus
+    assert_scanned("1 - 2",
+                   :tINTEGER, 1,
+                   :tMINUS, "-",
+                   :tINTEGER, 2)
+  end
+
+  def test_minus_equals
+    @lex.state = :expr_end
+
+    assert_scanned "-=", :tOP_ASGN, "-"
+  end
+
+  def test_minus_method
+    @lex.state = :expr_fname
+    assert_scanned "-", :tMINUS, "-"
+  end
+
+  def test_minus_unary_method
+    @lex.state = :expr_fname
+    assert_scanned "-@", :tUMINUS, "-@"
+  end
+
+  def test_minus_unary_number
+    assert_scanned("-42",
+                   :tUMINUS_NUM, "-",
+                   :tINTEGER, 42)
+  end
+
+  def test_nth_ref
+    assert_scanned('[$1, $2, $3]',
+                   :tLBRACK,  "[",
+                   :tNTH_REF, 1, :tCOMMA, ",",
+                   :tNTH_REF, 2, :tCOMMA, ",",
+                   :tNTH_REF, 3,
+                   :tRBRACK,  "]")
+  end
+
+  def test_open_bracket
+    assert_scanned("(", :tLPAREN, "(")
+  end
+
+  def test_open_bracket_cmdarg
+    assert_scanned("m (", :tIDENTIFIER, "m",
+                          :tLPAREN_ARG, "(")
+  end
+
+  def test_open_bracket_exprarg
+    assert_scanned("m(", :tIDENTIFIER, "m",
+                          :tLPAREN2, "(")
+  end
+
+  def test_open_curly_bracket
+    assert_scanned("{",
+                   :tLBRACE, "{")
+  end
+
+  def test_open_curly_bracket_arg
+    assert_scanned("m { 3 }",
+                   :tIDENTIFIER, "m",
+                   :tLCURLY, "{",
+                   :tINTEGER, 3,
+                   :tRCURLY, "}")
+  end
+
+  def test_open_curly_bracket_block
+    @lex.state = :expr_endarg # seen m(3)
+
+    assert_scanned("{ 4 }",
+                   :tLBRACE_ARG, "{",
+                   :tINTEGER, 4,
+                   :tRCURLY, "}")
+  end
+
+  def test_open_square_bracket_arg
+    assert_scanned("m [ 3 ]",
+                   :tIDENTIFIER, "m",
+                   :tLBRACK, "[",
+                   :tINTEGER, 3,
+                   :tRBRACK, "]")
+  end
+
+  def test_open_square_bracket_ary
+    assert_scanned("[1, 2, 3]",
+                   :tLBRACK, "[",
+                   :tINTEGER, 1,
+                   :tCOMMA, ",",
+                   :tINTEGER, 2,
+                   :tCOMMA, ",",
+                   :tINTEGER, 3,
+                   :tRBRACK, "]")
+  end
+
+  def test_open_square_bracket_meth
+    assert_scanned("m[3]",
+                   :tIDENTIFIER, "m",
+                   :tLBRACK2, "[",
+                   :tINTEGER, 3,
+                   :tRBRACK, "]")
+  end
+
+  def test_or
+    assert_scanned "|", :tPIPE, "|"
+  end
+
+  def test_or2
+    assert_scanned "||", :tOROP, "||"
+  end
+
+  def test_or2_equals
+    assert_scanned "||=", :tOP_ASGN, "||"
+  end
+
+  def test_or_equals
+    assert_scanned "|=", :tOP_ASGN, "|"
+  end
+
+  def test_percent
+    assert_scanned("a % 2",
+                   :tIDENTIFIER, "a",
+                   :tPERCENT, "%",
+                   :tINTEGER, 2)
+  end
+
+  def test_percent_equals
+    assert_scanned("a %= 2",
+                   :tIDENTIFIER, "a",
+                   :tOP_ASGN, "%",
+                   :tINTEGER, 2)
+  end
+
+  def test_plus
+    assert_scanned("1 + 1",
+                   :tINTEGER, 1,
+                   :tPLUS, "+",
+                   :tINTEGER, 1)
+  end
+
+  def test_plus_equals
+    @lex.state = :expr_end
+
+    assert_scanned "+=", :tOP_ASGN, "+"
+  end
+
+  def test_plus_method
+    @lex.state = :expr_fname
+    assert_scanned "+", :tPLUS, "+"
+  end
+
+  def test_plus_unary_method
+    @lex.state = :expr_fname
+    assert_scanned "+@", :tUPLUS, "+@"
+  end
+
+  def test_numbers
+    assert_scanned "0b10", :tINTEGER, 2
+    assert_scanned "0B10", :tINTEGER, 2
+
+    assert_scanned "0d10", :tINTEGER, 10
+    assert_scanned "0D10", :tINTEGER, 10
+
+    assert_scanned "0x10", :tINTEGER, 16
+    assert_scanned "0X10", :tINTEGER, 16
+
+    assert_scanned "0o10", :tINTEGER, 8
+    assert_scanned "0O10", :tINTEGER, 8
+    assert_scanned "0o",   :tINTEGER, 0
+    assert_scanned "0O",   :tINTEGER, 0
+
+    assert_scanned "0o",   :tINTEGER, 0
+    assert_scanned "0O",   :tINTEGER, 0
+
+    assert_scanned "0777_333", :tINTEGER, 261851
+
+    assert_scanned "0",    :tINTEGER, 0
+
+    refute_scanned "0x"
+    refute_scanned "0X"
+    refute_scanned "0b"
+    refute_scanned "0B"
+    refute_scanned "0d"
+    refute_scanned "0D"
+
+    refute_scanned "08"
+    refute_scanned "09"
+    refute_scanned "0o8"
+    refute_scanned "0o9"
+    refute_scanned "0O8"
+    refute_scanned "0O9"
+
+    refute_scanned "1_e1"
+    refute_scanned "1_.1"
+    refute_scanned "1__1"
+
+    refute_scanned "1end"
+    refute_scanned "1.1end"
+  end
+
+  def test_plus_unary_number
+    assert_scanned("+42",
+                   :tINTEGER, 42)
+  end
+
+  def test_question__18
+    setup_lexer 18
+
+    assert_scanned "?*", :tINTEGER, 42
+  end
+
+  def test_question__19
+    setup_lexer 19
+
+    assert_scanned "?*", :tCHARACTER, "*"
+  end
+
+  def test_question_bad_eos
+    refute_scanned "?"
+  end
+
+  def test_question_bad_ws
+    assert_scanned "? ",  :tEH, "?"
+    assert_scanned "?\n", :tEH, "?"
+    assert_scanned "?\t", :tEH, "?"
+    assert_scanned "?\v", :tEH, "?"
+    assert_scanned "?\r", :tEH, "?"
+    assert_scanned "?\f", :tEH, "?"
+  end
+
+  def test_question_ws_backslashed__18
+    setup_lexer 18
+
+    @lex.state = :expr_beg
+    assert_scanned "?\\ ", :tINTEGER, 32
+    @lex.state = :expr_beg
+    assert_scanned "?\\n", :tINTEGER, 10
+    @lex.state = :expr_beg
+    assert_scanned "?\\t", :tINTEGER, 9
+    @lex.state = :expr_beg
+    assert_scanned "?\\v", :tINTEGER, 11
+    @lex.state = :expr_beg
+    assert_scanned "?\\r", :tINTEGER, 13
+    @lex.state = :expr_beg
+    assert_scanned "?\\f", :tINTEGER, 12
+  end
+
+  def test_question_ws_backslashed__19
+    setup_lexer 19
+
+    @lex.state = :expr_beg
+    assert_scanned "?\\ ", :tCHARACTER, " "
+    @lex.state = :expr_beg
+    assert_scanned "?\\n", :tCHARACTER, "\n"
+    @lex.state = :expr_beg
+    assert_scanned "?\\t", :tCHARACTER, "\t"
+    @lex.state = :expr_beg
+    assert_scanned "?\\v", :tCHARACTER, "\v"
+    @lex.state = :expr_beg
+    assert_scanned "?\\r", :tCHARACTER, "\r"
+    @lex.state = :expr_beg
+    assert_scanned "?\\f", :tCHARACTER, "\f"
+  end
+
+  def test_rbracket
+    assert_scanned "]", :tRBRACK, "]"
+  end
+
+  def test_rcurly
+    assert_scanned "}", :tRCURLY, "}"
+  end
+
+  def test_regexp
+    assert_scanned("/regexp/",
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "regexp",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_ambiguous
+    assert_scanned("method /regexp/",
+                   :tIDENTIFIER,     "method",
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "regexp",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_bad
+    refute_scanned("/.*/xyz",
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, ".*",
+                   :tSTRING_END,     "/")
+  end
+
+  def test_regexp_escape_C
+    assert_scanned('/regex\\C-x/',
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "regex\\C-x",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_C_M
+    assert_scanned('/regex\\C-\\M-x/',
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "regex\\C-\\M-x",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_C_M_craaaazy
+    assert_scanned("/regex\\C-\\\n\\M-x/",
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "regex\\C-\\M-x",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_C_bad_dash
+    refute_scanned '/regex\\Cx/', :tREGEXP_BEG, "/"
+  end
+
+  def test_regexp_escape_C_bad_dash_eos
+    refute_scanned '/regex\\C-/', :tREGEXP_BEG, "/"
+  end
+
+  def test_regexp_escape_C_bad_dash_eos2
+    refute_scanned '/regex\\C-', :tREGEXP_BEG, "/"
+  end
+
+  def test_regexp_escape_C_bad_eos
+    refute_scanned '/regex\\C/', :tREGEXP_BEG, "/"
+  end
+
+  def test_regexp_escape_C_bad_eos2
+    refute_scanned '/regex\\c', :tREGEXP_BEG, "/"
+  end
+
+  def test_regexp_escape_M
+    assert_scanned('/regex\\M-x/',
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "regex\\M-x",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_M_C
+    assert_scanned('/regex\\M-\\C-x/',
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "regex\\M-\\C-x",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_M_bad_dash
+    refute_scanned '/regex\\Mx/', :tREGEXP_BEG, "/"
+  end
+
+  def test_regexp_escape_M_bad_dash_eos
+    refute_scanned '/regex\\M-/', :tREGEXP_BEG, "/"
+  end
+
+  def test_regexp_escape_M_bad_dash_eos2
+    refute_scanned '/regex\\M-', :tREGEXP_BEG, "/"
+  end
+
+  def test_regexp_escape_M_bad_eos
+    refute_scanned '/regex\\M/', :tREGEXP_BEG, "/"
+  end
+
+  def test_regexp_escape_backslash_slash
+    assert_scanned('/\\//',
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, '/',
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_backslash_terminator
+    assert_scanned('%r%blah\\%blah%',
+                   :tREGEXP_BEG,     "%r%",
+                   :tSTRING_CONTENT, "blah%blah",
+                   :tSTRING_END,     "%",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_backslash_terminator_meta1
+    assert_scanned('%r{blah\\}blah}',
+                   :tREGEXP_BEG,     "%r{",
+                   :tSTRING_CONTENT, "blah}blah",
+                   :tSTRING_END,     "}",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_backslash_terminator_meta2
+    assert_scanned('%r/blah\\/blah/',
+                   :tREGEXP_BEG,     "%r/",
+                   :tSTRING_CONTENT, "blah/blah",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_backslash_terminator_meta3
+    assert_scanned('%r/blah\\%blah/',
+                   :tREGEXP_BEG,     "%r/",
+                   :tSTRING_CONTENT, "blah\\%blah",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_bad_eos
+    refute_scanned '/regex\\', :tREGEXP_BEG, "/"
+  end
+
+  def test_regexp_escape_bs
+    assert_scanned('/regex\\\\regex/',
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "regex\\\\regex",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_c
+    assert_scanned('/regex\\cxxx/',
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "regex\\cxxx",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_c_backslash
+    assert_scanned('/regex\\c\\n/',
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "regex\\c\\n",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_chars
+    assert_scanned('/re\\tge\\nxp/',
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "re\\tge\\nxp",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_double_backslash
+    assert_scanned('/[\\/\\\\]$/',
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT,'[/\\\\]$',
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_hex
+    assert_scanned('/regex\\x61xp/',
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "regex\\x61xp",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_hex_bad
+    refute_scanned '/regex\\xzxp/', :tREGEXP_BEG, "/"
+  end
+
+  def test_regexp_escape_hex_one
+    assert_scanned('/^[\\xd\\xa]{2}/on',
+                   :tREGEXP_BEG,     '/',
+                   :tSTRING_CONTENT, '^[\\xd\\xa]{2}',
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     'on')
+  end
+
+  def test_regexp_escape_oct1
+    assert_scanned('/regex\\0xp/',
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "regex\\0xp",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_oct2
+    assert_scanned('/regex\\07xp/',
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "regex\\07xp",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_oct3
+    assert_scanned('/regex\\10142/',
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "regex\\10142",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_escape_return
+    assert_scanned("/regex\\\nregex/",
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "regexregex",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_regexp_nm
+    assert_scanned("/.*/nm",
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, ".*",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "nm")
+  end
+
+  def test_rparen
+    assert_scanned ")", :tRPAREN, ")"
+  end
+
+  def test_rshft
+    assert_scanned("a >> 2",
+                   :tIDENTIFIER, "a",
+                   :tRSHFT, ">>",
+                   :tINTEGER, 2)
+  end
+
+  def test_rshft_equals
+    assert_scanned("a >>= 2",
+                   :tIDENTIFIER, "a",
+                   :tOP_ASGN, ">>",
+                   :tINTEGER, 2)
+  end
+
+  def test_star
+    assert_scanned("a * ",
+                   :tIDENTIFIER, "a",
+                   :tSTAR2, "*")
+
+    assert_equal :expr_beg, @lex.state
+  end
+
+  def test_star2
+    assert_scanned("a ** ",
+                   :tIDENTIFIER, "a",
+                   :tPOW, "**")
+
+    assert_equal :expr_beg, @lex.state
+  end
+
+  def test_star2_equals
+    assert_scanned("a **= ",
+                   :tIDENTIFIER, "a",
+                   :tOP_ASGN, "**")
+
+    assert_equal :expr_beg, @lex.state
+  end
+
+  def test_star2_beg
+    assert_scanned("** ",
+                   :tDSTAR, "**")
+
+    assert_equal :expr_beg, @lex.state
+  end
+
+  def test_star_arg
+    @lex.state = :expr_arg
+
+    assert_scanned(" *a",
+                   :tSTAR, "*",
+                   :tIDENTIFIER, "a")
+
+    assert_equal :expr_arg, @lex.state
+  end
+
+  def test_star_arg_beg
+    @lex.state = :expr_beg
+
+    assert_scanned("*a",
+                   :tSTAR, "*",
+                   :tIDENTIFIER, "a")
+
+    assert_equal :expr_arg, @lex.state
+  end
+
+  def test_star_arg_beg_fname
+    @lex.state = :expr_fname
+
+    assert_scanned("*a",
+                   :tSTAR2, "*",
+                   :tIDENTIFIER, "a")
+
+    assert_equal :expr_arg, @lex.state
+  end
+
+  def test_star_equals
+    assert_scanned("a *= ",
+                   :tIDENTIFIER, "a",
+                   :tOP_ASGN, "*")
+
+    assert_equal :expr_beg, @lex.state
+  end
+
+  def test_string_bad_eos
+    refute_scanned('%',
+                   :tSTRING_BEG,     '%')
+  end
+
+  def test_string_bad_eos_quote
+    refute_scanned('%{nest',
+                   :tSTRING_BEG,     '%}')
+  end
+
+  def test_string_double
+    assert_scanned('"string"',
+                   :tSTRING, "string")
+  end
+
+  def test_string_double_escape_C
+    assert_scanned('"\\C-a"',
+                   :tSTRING, "\001")
+  end
+
+  def test_string_double_escape_C_backslash
+    assert_scanned('"\\C-\\\\"',
+                   :tSTRING, "\034")
+  end
+
+  def test_string_double_escape_C_escape
+    assert_scanned('"\\C-\\M-a"',
+                   :tSTRING, "\201")
+  end
+
+  def test_string_double_escape_C_question
+    assert_scanned('"\\C-?"',
+                   :tSTRING, "\177")
+  end
+
+  def test_string_double_escape_M
+    assert_scanned('"\\M-a"',
+                   :tSTRING, "\341")
+  end
+
+  def test_string_double_escape_M_backslash
+    assert_scanned('"\\M-\\\\"',
+                   :tSTRING, "\334")
+  end
+
+  def test_string_double_escape_M_escape
+    assert_scanned('"\\M-\\C-a"',
+                   :tSTRING, "\201")
+  end
+
+  def test_string_double_escape_bs1
+    assert_scanned('"a\\a\\a"',
+                   :tSTRING, "a\a\a")
+  end
+
+  def test_string_double_escape_bs2
+    assert_scanned('"a\\\\a"',
+                   :tSTRING, "a\\a")
+  end
+
+  def test_string_double_escape_c
+    assert_scanned('"\\ca"',
+                   :tSTRING, "\001")
+  end
+
+  def test_string_double_escape_c_escape
+    assert_scanned('"\\c\\M-a"',
+                   :tSTRING, "\201")
+  end
+
+  def test_string_double_escape_c_question
+    assert_scanned('"\\c?"',
+                   :tSTRING, "\177")
+  end
+
+  def test_string_double_escape_chars
+    assert_scanned('"s\\tri\\ng"',
+                   :tSTRING, "s\tri\ng")
+  end
+
+  def test_string_double_escape_hex
+    assert_scanned('"n = \\x61\\x62\\x63"',
+                   :tSTRING, "n = abc")
+  end
+
+  def test_string_double_escape_octal
+    assert_scanned('"n = \\101\\102\\103"',
+                   :tSTRING, "n = ABC")
+  end
+
+  def test_string_double_escape_octal_wrap
+    assert_scanned('"\\753"',
+                   :tSTRING, "\xEB")
+  end
+
+  def test_string_double_interp
+    assert_scanned("\"blah #x a \#@a b \#$b c \#{3} # \"",
+                   :tSTRING_BEG,     "\"",
+                   :tSTRING_CONTENT, "blah #x a ",
+                   :tSTRING_DVAR,    nil,
+                   :tIVAR,           "@a",
+                   :tSTRING_CONTENT, " b ",
+                   :tSTRING_DVAR,    nil,
+                   :tGVAR,           "$b",
+                   :tSTRING_CONTENT, " c ",
+                   :tSTRING_DBEG,    '#{',
+                   :tINTEGER,        3,
+                   :tRCURLY,         "}",
+                   :tSTRING_CONTENT, " # ",
+                   :tSTRING_END,     "\"")
+  end
+
+  def test_string_double_interp_label
+    assert_scanned('"#{foo:bar}"',
+                   :tSTRING_BEG,   '"',
+                   :tSTRING_DBEG,  '#{',
+                   :tIDENTIFIER,   'foo',
+                   :tSYMBOL,       'bar',
+                   :tRCURLY,       '}',
+                   :tSTRING_END,   '"')
+  end
+
+  def test_string_double_nested_curlies
+    assert_scanned('%{nest{one{two}one}nest}',
+                   :tSTRING_BEG,     '%{',
+                   :tSTRING_CONTENT, "nest{one{two}one}nest",
+                   :tSTRING_END,     '}')
+  end
+
+  def test_string_double_no_interp
+    assert_scanned("\"# blah\"",                                # pound first
+                   :tSTRING, "# blah")
+
+    assert_scanned("\"blah # blah\"",                           # pound not first
+                   :tSTRING, "blah # blah")
+  end
+
+  def test_string_escape_x_single
+    assert_scanned('"\\x0"',
+                   :tSTRING, "\000")
+  end
+
+  def test_string_pct_Q
+    assert_scanned("%Q[s1 s2]",
+                   :tSTRING_BEG,     '%Q[',
+                   :tSTRING_CONTENT, "s1 s2",
+                   :tSTRING_END,     ']')
+  end
+
+  def test_string_pct_W
+    assert_scanned("%W[s1 s2\ns3]",
+                   :tWORDS_BEG,      "%W[",
+                   :tSTRING_CONTENT, "s1",
+                   :tSPACE,              nil,
+                   :tSTRING_CONTENT, "s2",
+                   :tSPACE,              nil,
+                   :tSTRING_CONTENT, "s3",
+                   :tSPACE,              nil,
+                   :tSTRING_END,     ']')
+  end
+
+  def test_string_pct_W_bs_nl
+    assert_scanned("%W[s1 \\\ns2]",
+                   :tWORDS_BEG,      "%W[",
+                   :tSTRING_CONTENT, "s1",
+                   :tSPACE,              nil,
+                   :tSTRING_CONTENT, "\ns2",
+                   :tSPACE,              nil,
+                   :tSTRING_END,     ']')
+  end
+
+  def test_string_pct_W_interp
+    assert_scanned('%W[#{1}#{2} #@a]',
+                   :tWORDS_BEG,    '%W[',
+                   :tSTRING_DBEG,  '#{',
+                   :tINTEGER,      1,
+                   :tRCURLY,       '}',
+                   :tSTRING_DBEG,  '#{',
+                   :tINTEGER,      2,
+                   :tRCURLY,       '}',
+                   :tSPACE,        nil,
+                   :tSTRING_DVAR,  nil,
+                   :tIVAR,         '@a',
+                   :tSPACE,        nil,
+                   :tSTRING_END,   ']')
+  end
+
+  def test_string_pct_I
+    assert_scanned("%I(s1 s2)",
+                   :tSYMBOLS_BEG,    "%I(",
+                   :tSTRING_CONTENT, "s1",
+                   :tSPACE,          nil,
+                   :tSTRING_CONTENT, "s2",
+                   :tSPACE,          nil,
+                   :tSTRING_END,     ')')
+  end
+
+  def test_string_pct_angle
+    assert_scanned("%<blah>",
+                   :tSTRING_BEG,     '%<',
+                   :tSTRING_CONTENT, "blah",
+                   :tSTRING_END,     '>')
+  end
+
+  def test_string_pct_pct
+    assert_scanned("%%blah%",
+                   :tSTRING_BEG,     '%',
+                   :tSTRING_CONTENT, "blah",
+                   :tSTRING_END,     '%')
+  end
+
+  def test_string_pct_w
+    assert_scanned("%w[s1 s2 ]",
+                   :tQWORDS_BEG,     "%w[",
+                   :tSTRING_CONTENT, "s1",
+                   :tSPACE,          nil,
+                   :tSTRING_CONTENT, "s2",
+                   :tSPACE,          nil,
+                   :tSTRING_END,     "]")
+  end
+
+  def test_string_pct_w_incomplete
+    refute_scanned("%w[s1 ",
+                   :tQWORDS_BEG,     "%w[",
+                   :tSTRING_CONTENT, "s1",
+                   :tSPACE,          nil)
+  end
+
+  def test_string_pct_w_bs_nl
+    assert_scanned("%w[s1 \\\ns2]",
+                   :tQWORDS_BEG,     "%w[",
+                   :tSTRING_CONTENT, "s1",
+                   :tSPACE,              nil,
+                   :tSTRING_CONTENT, "\ns2",
+                   :tSPACE,              nil,
+                   :tSTRING_END,     ']')
+  end
+
+  def test_string_pct_w_bs_sp
+    assert_scanned("%w[s\\ 1 s\\ 2]",
+                   :tQWORDS_BEG,     "%w[",
+                   :tSTRING_CONTENT, "s 1",
+                   :tSPACE,              nil,
+                   :tSTRING_CONTENT, "s 2",
+                   :tSPACE,              nil,
+                   :tSTRING_END,     ']')
+  end
+
+  def test_string_pct_w_tab
+    assert_scanned("%w[abc\tdef]",
+                   :tQWORDS_BEG,      "%w[",
+                   :tSTRING_CONTENT, "abc",
+                   :tSPACE,              nil,
+                   :tSTRING_CONTENT, "def",
+                   :tSPACE,              nil,
+                   :tSTRING_END,     ']')
+  end
+
+  def test_string_pct_i
+    assert_scanned("%i(s1 s2)",
+                   :tQSYMBOLS_BEG,   "%i(",
+                   :tSTRING_CONTENT, "s1",
+                   :tSPACE,          nil,
+                   :tSTRING_CONTENT, "s2",
+                   :tSPACE,          nil,
+                   :tSTRING_END,     ')')
+  end
+
+  def test_string_single
+    assert_scanned("'string'",
+                   :tSTRING, "string")
+  end
+
+  def test_string_single_escape_chars
+    assert_scanned("'s\\tri\\ng'",
+                   :tSTRING, "s\\tri\\ng")
+  end
+
+  def test_string_single_nl
+    assert_scanned("'blah\\\nblah'",
+                   :tSTRING_BEG,     "'",
+                   :tSTRING_CONTENT, "blah\\\n",
+                   :tSTRING_CONTENT, "blah",
+                   :tSTRING_END,     "'")
+  end
+
+  def test_symbol
+    assert_scanned(":symbol",
+                   :tSYMBOL, "symbol")
+  end
+
+  def test_symbol_double
+    assert_scanned(":\"symbol\"",
+                   :tSYMBEG,         ":\"",
+                   :tSTRING_CONTENT, "symbol",
+                   :tSTRING_END,     "\"")
+  end
+
+  def test_symbol_single
+    assert_scanned(":'symbol'",
+                   :tSYMBEG,         ":'",
+                   :tSTRING_CONTENT, "symbol",
+                   :tSTRING_END,     "'")
+  end
+
+  def test_ternary
+    assert_scanned("a ? b : c",
+                   :tIDENTIFIER, "a",
+                   :tEH,         "?",
+                   :tIDENTIFIER, "b",
+                   :tCOLON,      ":",
+                   :tIDENTIFIER, "c")
+
+    assert_scanned("a ?b : c",
+                   :tIDENTIFIER, "a",
+                   :tINTEGER,    98,
+                   :tCOLON,      ":",
+                   :tIDENTIFIER, "c")
+
+    assert_scanned("a ?bb : c", # GAH! MATZ!!!
+                   :tIDENTIFIER, "a",
+                   :tEH,         "?",
+                   :tIDENTIFIER, "bb",
+                   :tCOLON,      ":",
+                   :tIDENTIFIER, "c")
+
+    assert_scanned("42 ?", # 42 forces expr_end
+                   :tINTEGER,    42,
+                   :tEH,         "?")
+  end
+
+  def test_tilde
+    assert_scanned "~", :tTILDE, "~"
+  end
+
+  def test_tilde_unary
+    @lex.state = :expr_fname
+    assert_scanned "~@", :tTILDE, "~@"
+  end
+
+  def test_uminus
+    assert_scanned("-blah",
+                   :tUMINUS, "-",
+                   :tIDENTIFIER, "blah")
+  end
+
+  def test_underscore
+    assert_scanned("_var", :tIDENTIFIER, "_var")
+  end
+
+  def test_underscore_end
+    assert_scanned("__END__\n")
+    assert_scanned("__END__")
+    assert_scanned("__END__ foo",
+                   :tIDENTIFIER, '__END__',
+                   :tIDENTIFIER, 'foo')
+    assert_scanned("__END__\rfoo",
+                   :tIDENTIFIER, '__END__',
+                   :tIDENTIFIER, 'foo')
+  end
+
+  def test_uplus
+    assert_scanned("+blah",
+                   :tUPLUS, "+",
+                   :tIDENTIFIER, "blah")
+  end
+
+  def test_if_unless_mod
+    assert_scanned("return if true unless false",
+                   :kRETURN,      "return",
+                   :kIF_MOD,      "if",
+                   :kTRUE,        "true",
+                   :kUNLESS_MOD,  "unless",
+                   :kFALSE,       "false")
+  end
+
+  def test_if_stmt
+    assert_scanned("if true\n return end",
+                   :kIF,          "if",
+                   :kTRUE,        "true",
+                   :tNL,          nil,
+                   :kRETURN,      "return",
+                   :kEND,         "end")
+  end
+
+  def test_sclass_label
+    setup_lexer 20
+    assert_scanned("class << a:b",
+                   :kCLASS,      'class',
+                   :tLSHFT,      '<<',
+                   :tIDENTIFIER, 'a',
+                   :tSYMBOL,     'b')
+  end
+
+  def test_static_env
+    env = Parser::StaticEnvironment.new
+    env.declare "a"
+
+    @lex.static_env = env
+    assert_scanned("a [42]",
+                   :tIDENTIFIER, "a",
+                   :tLBRACK2,    "[",
+                   :tINTEGER,    42,
+                   :tRBRACK,     "]")
+  end
+
+  def test_int_suffix
+    [18, 19, 20].each do |version|
+      setup_lexer version
+
+      assert_scanned("42r",
+                     :tINTEGER,    42,
+                     :tIDENTIFIER, 'r')
+
+      assert_scanned("42if",
+                     :tINTEGER,    42,
+                     :kIF_MOD,     'if')
+    end
+
+    setup_lexer 21
+
+    assert_scanned("42r",  :tRATIONAL,  Rational(42))
+    assert_scanned("42i",  :tIMAGINARY, Complex(0, 42))
+    assert_scanned("42ri", :tIMAGINARY, Complex(0, Rational(42)))
+  end
+
+  def test_float_suffix
+    [18, 19, 20].each do |version|
+      setup_lexer version
+
+      assert_scanned("42.1r",
+                     :tFLOAT,      42.1,
+                     :tIDENTIFIER, 'r')
+
+      assert_scanned("42.1if",
+                     :tFLOAT,      42.1,
+                     :kIF_MOD,     'if')
+
+      assert_scanned("1e1r",
+                     :tFLOAT,      1e1,
+                     :tIDENTIFIER, 'r')
+    end
+
+    begin
+      # Feature-check.
+      Rational("10")
+
+      setup_lexer 21
+
+      assert_scanned("42.1r",  :tRATIONAL,  Rational(421, 10))
+      assert_scanned("42.1i",  :tIMAGINARY, Complex(0, 42.1))
+      assert_scanned("42.1ri", :tIMAGINARY, Complex(0, Rational(421, 10)))
+      assert_scanned("42.1ir",
+                     :tIMAGINARY,  Complex(0, 42.1),
+                     :tIDENTIFIER, 'r')
+
+      assert_scanned("1e1i",   :tIMAGINARY, Complex(0, 1e1))
+      assert_scanned("1e1r",
+                     :tFLOAT,      1e1,
+                     :tIDENTIFIER, 'r')
+      assert_scanned("1e1ri",
+                     :tFLOAT,      1e1,
+                     :tIDENTIFIER, 'ri')
+      assert_scanned("1e1ir",
+                     :tIMAGINARY,  Complex(0, 1e1),
+                     :tIDENTIFIER, 'r')
+    rescue NoMethodError
+      # Ruby not modern enough
+    end
+  end
+
+  #
+  # Tests for whitespace.
+  #
+
+  def test_whitespace_fname
+    @lex.state = :expr_fname
+    assert_scanned('class',
+                   :kCLASS, 'class')
+
+    @lex.state = :expr_fname
+    assert_scanned(' class',
+                   :kCLASS, 'class')
+
+    @lex.state = :expr_fname
+    assert_scanned("\nclass",
+                   :kCLASS, 'class')
+
+    @lex.state = :expr_fname
+    assert_scanned("\\\nclass",
+                   :kCLASS, 'class')
+
+    @lex.state = :expr_fname
+    assert_scanned("#foo\nclass",
+                   :kCLASS, 'class')
+  end
+
+  def test_whitespace_endfn
+    setup_lexer(21)
+
+    @lex.state = :expr_endfn
+    assert_scanned('foo:',
+                   :tLABEL, 'foo')
+
+    @lex.state = :expr_endfn
+    assert_scanned(' foo:',
+                   :tLABEL, 'foo')
+
+    @lex.state = :expr_endfn
+    assert_scanned("\nfoo:",
+                   :tNL,         nil,
+                   :tIDENTIFIER, 'foo',
+                   :tCOLON,      ':')
+
+    @lex.state = :expr_endfn
+    assert_scanned("\nfoo: ",
+                   :tNL,         nil,
+                   :tIDENTIFIER, 'foo',
+                   :tCOLON,      ':')
+
+    @lex.state = :expr_endfn
+    assert_scanned("\\\nfoo:",
+                   :tLABEL, 'foo')
+
+    @lex.state = :expr_endfn
+    assert_scanned("#foo\nfoo:",
+                   :tNL,         nil,
+                   :tIDENTIFIER, 'foo',
+                   :tCOLON,      ':')
+
+    @lex.state = :expr_endfn
+    assert_scanned("#foo\nfoo: ",
+                   :tNL,         nil,
+                   :tIDENTIFIER, 'foo',
+                   :tCOLON,      ':')
+  end
+
+  def test_whitespace_dot
+    @lex.state = :expr_dot
+    assert_scanned('class',
+                   :tIDENTIFIER, 'class')
+
+    @lex.state = :expr_dot
+    assert_scanned(' class',
+                   :tIDENTIFIER, 'class')
+
+    @lex.state = :expr_dot
+    assert_scanned("\nclass",
+                   :tIDENTIFIER, 'class')
+
+    @lex.state = :expr_dot
+    assert_scanned("\\\nclass",
+                   :tIDENTIFIER, 'class')
+
+    @lex.state = :expr_dot
+    assert_scanned("#foo\nclass",
+                   :tIDENTIFIER, 'class')
+  end
+
+  def test_whitespace_arg
+    @lex.state = :expr_arg
+    assert_scanned('+',
+                   :tPLUS,  '+')
+
+    @lex.state = :expr_arg
+    assert_scanned(' +',
+                   :tUPLUS, '+')
+
+    @lex.state = :expr_arg
+    assert_scanned("\n+",
+                   :tNL,    nil,
+                   :tUPLUS, '+')
+
+    @lex.state = :expr_arg
+    assert_scanned("\\\n+",
+                   :tUPLUS, '+')
+
+    @lex.state = :expr_arg
+    assert_scanned("\\\n +",
+                   :tUPLUS, '+')
+
+    @lex.state = :expr_arg
+    assert_scanned("#foo\n+",
+                   :tNL,    nil,
+                   :tUPLUS, '+')
+  end
+
+  def test_whitespace_endarg
+    @lex.state = :expr_endarg
+    assert_scanned('{',
+                   :tLBRACE_ARG, '{')
+
+    @lex.state = :expr_endarg
+    assert_scanned(' {',
+                   :tLBRACE_ARG, '{')
+
+    @lex.state = :expr_endarg
+    assert_scanned("\n{",
+                   :tNL,         nil,
+                   :tLBRACE,     '{')
+
+    @lex.state = :expr_endarg
+    assert_scanned("\\\n{",
+                   :tLBRACE_ARG, '{')
+
+    @lex.state = :expr_endarg
+    assert_scanned("#foo\n{",
+                   :tNL,         nil,
+                   :tLBRACE,     '{')
+  end
+
+  def test_whitespace_mid
+    @lex.state = :expr_mid
+    assert_scanned('+',
+                   :tUPLUS, '+')
+
+    @lex.state = :expr_mid
+    assert_scanned(' +',
+                   :tUPLUS, '+')
+
+    @lex.state = :expr_mid
+    assert_scanned("\n+",
+                   :tNL,    nil,
+                   :tUPLUS, '+')
+
+    @lex.state = :expr_mid
+    assert_scanned("\\\n+",
+                   :tUPLUS, '+')
+
+    @lex.state = :expr_mid
+    assert_scanned("#foo\n+",
+                   :tNL,    nil,
+                   :tUPLUS, '+')
+  end
+
+  def test_whitespace_beg
+    @lex.state = :expr_beg
+    assert_scanned('+',
+                   :tUPLUS, '+')
+
+    @lex.state = :expr_beg
+    assert_scanned(' +',
+                   :tUPLUS, '+')
+
+    @lex.state = :expr_beg
+    assert_scanned("\n+",
+                   :tUPLUS, '+')
+
+    @lex.state = :expr_beg
+    assert_scanned("\\\n+",
+                   :tUPLUS, '+')
+
+    @lex.state = :expr_beg
+    assert_scanned("#foo\n+",
+                   :tUPLUS, '+')
+  end
+
+  def test_whitespace_value
+    setup_lexer(20)
+
+    @lex.state = :expr_value
+    assert_scanned('a:b',
+                   :tIDENTIFIER, 'a',
+                   :tSYMBOL,     'b')
+
+    @lex.state = :expr_value
+    assert_scanned(' a:b',
+                   :tIDENTIFIER, 'a',
+                   :tSYMBOL,     'b')
+
+    @lex.state = :expr_value
+    assert_scanned("\na:b",
+                   :tIDENTIFIER, 'a',
+                   :tSYMBOL,     'b')
+
+    @lex.state = :expr_value
+    assert_scanned("\\\na:b",
+                   :tIDENTIFIER, 'a',
+                   :tSYMBOL,     'b')
+
+    @lex.state = :expr_value
+    assert_scanned("#foo\na:b",
+                   :tIDENTIFIER, 'a',
+                   :tSYMBOL,     'b')
+  end
+
+  def test_whitespace_end
+    @lex.state = :expr_end
+    assert_scanned('+ 1',
+                   :tPLUS,    '+',
+                   :tINTEGER, 1)
+
+    @lex.state = :expr_end
+    assert_scanned(' + 1',
+                   :tPLUS,    '+',
+                   :tINTEGER, 1)
+
+    @lex.state = :expr_end
+    assert_scanned("\n+ 1",
+                   :tNL,      nil,
+                   :tUPLUS,   '+',
+                   :tINTEGER, 1)
+
+    @lex.state = :expr_end
+    assert_scanned("\\\n+ 1",
+                   :tPLUS,    '+',
+                   :tINTEGER, 1)
+
+    @lex.state = :expr_end
+    assert_scanned("#foo\n+ 1",
+                   :tNL,      nil,
+                   :tUPLUS,   '+',
+                   :tINTEGER, 1)
+  end
+
+  def test_whitespace_cr
+    setup_lexer(20)
+    assert_scanned("<<E\nfoo\nE\rO",
+                   :tSTRING_BEG,     '<<"',
+                   :tSTRING_CONTENT, "foo\n",
+                   :tSTRING_END,     'E',
+                   :tNL,             nil)
+
+    setup_lexer(21)
+    refute_scanned("<<E\nfoo\nE\rO",
+                   :tSTRING_BEG,     '<<"',
+                   :tSTRING_CONTENT, "foo\n")
+  end
+
+  #
+  # Tests for bugs.
+  #
+  # These tests should be moved from nursery and properly
+  # categorized when it's clear how to do that.
+  #
+
+  def test_bug_sclass_joined
+    assert_scanned("class<<self",
+                   :kCLASS, "class",
+                   :tLSHFT, "<<",
+                   :kSELF,  "self")
+  end
+
+  def test_bug_const_expr_end
+    assert_scanned("Option",
+                   :tCONSTANT, 'Option')
+
+    assert_equal :expr_cmdarg, @lex.state
+  end
+
+  def test_bug_expr_beg_div
+    @lex.state = :expr_beg
+    assert_scanned("/=/",
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "=",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+
+    @lex.state = :expr_beg
+    assert_scanned("/ = /",
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, " = ",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_bug_expr_beg_percent
+    @lex.state = :expr_beg
+    assert_scanned("%=foo=",
+                   :tSTRING_BEG,     "%=",
+                   :tSTRING_CONTENT, 'foo',
+                   :tSTRING_END,     "=")
+
+    @lex.state = :expr_beg
+    assert_scanned("% = ",
+                   :tSTRING_BEG,     "% ",
+                   :tSTRING_CONTENT, '=',
+                   :tSTRING_END,     ' ')
+  end
+
+  def test_bug_expr_beg_document
+    @lex.state = :expr_beg
+    assert_scanned(" \n=begin\n=end\nend",
+                   :kEND,            "end")
+
+  end
+
+  def test_bug_expr_beg_number
+    @lex.state = :expr_beg
+    assert_scanned("86400_000_000",
+                   :tINTEGER,        86400_000_000)
+  end
+
+  def test_bug_expr_beg_backspace_nl
+    @lex.state = :expr_beg
+    assert_scanned("\n/foo/",
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "foo",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+  end
+
+  def test_bug_expr_beg_heredoc
+    assert_scanned("<<EOL % [\nfoo\nEOL\n]",
+                   :tSTRING_BEG,      '<<"',
+                   :tSTRING_CONTENT,  "foo\n",
+                   :tSTRING_END,      'EOL',
+                   :tPERCENT,         '%',
+                   :tLBRACK,          '[',
+                   :tRBRACK,          ']')
+  end
+
+  def test_bug_expr_beg_fid
+    assert_scanned("Rainbows!",
+                   :tFID, 'Rainbows!')
+  end
+
+  def test_bug_expr_beg_rescue_assoc
+    assert_scanned("rescue=>",
+                   :kRESCUE, 'rescue',
+                   :tASSOC,  '=>')
+  end
+
+  def test_bug_expr_arg_percent
+    @lex.state = :expr_arg
+    assert_scanned("%[",
+                   :tPERCENT, "%",
+                   :tLBRACK,  "[")
+
+    @lex.state = :expr_arg
+    assert_scanned("%=1",
+                   :tOP_ASGN,    "%",
+                   :tINTEGER,    1)
+
+    @lex.state = :expr_arg
+    assert_scanned(" %[1]",
+                   :tSTRING_BEG,     "%[",
+                   :tSTRING_CONTENT, '1',
+                   :tSTRING_END,     ']')
+
+    @lex.state = :expr_arg
+    assert_scanned(" %=1=",
+                   :tOP_ASGN,    "%",
+                   :tINTEGER,    1,
+                   :tEQL,        "=")
+
+    @lex.state = :expr_arg
+    assert_scanned(" %\n",
+                   :tPERCENT,    '%')
+  end
+
+  def test_bug_expr_arg_lt_lt
+    @lex.state = :expr_arg
+    assert_scanned("<<EOS\nEOS",
+                   :tLSHFT,      "<<",
+                   :tCONSTANT,   "EOS",
+                   :tNL,         nil,
+                   :tCONSTANT,   "EOS")
+
+    @lex.state = :expr_arg
+    assert_scanned(" <<EOS\nEOS",
+                   :tSTRING_BEG, "<<\"",
+                   :tSTRING_END, "EOS",
+                   :tNL,         nil)
+  end
+
+  def test_bug_expr_arg_slash
+    @lex.state = :expr_arg
+    assert_scanned("/1",
+                   :tDIVIDE,    "/",
+                   :tINTEGER,   1)
+
+    @lex.state = :expr_arg
+    assert_scanned("/ 1",
+                   :tDIVIDE,    "/",
+                   :tINTEGER,   1)
+
+    @lex.state = :expr_arg
+    assert_scanned(" /1/",
+                   :tREGEXP_BEG,     "/",
+                   :tSTRING_CONTENT, "1",
+                   :tSTRING_END,     "/",
+                   :tREGEXP_OPT,     "")
+
+    @lex.state = :expr_arg
+    assert_scanned(" / 1",
+                   :tDIVIDE,    "/",
+                   :tINTEGER,   1)
+  end
+
+  def test_bug_expr_arg_label
+    setup_lexer 19
+
+    @lex.state = :expr_arg
+    assert_scanned(" unless:",
+                   :tLABEL,     'unless')
+
+    @lex.state = :expr_arg
+    assert_scanned(" unless: ",
+                   :tLABEL,     'unless')
+  end
+
+  def test_bug_heredoc_continuation
+    @lex.state = :expr_arg
+    assert_scanned(" <<EOS\nEOS\nend",
+                   :tSTRING_BEG,     "<<\"",
+                   :tSTRING_END,     "EOS",
+                   :tNL,             nil,
+                   :kEND,            "end")
+  end
+
+  def test_bug_heredoc_cr_lf
+    assert_scanned("<<FIN\r\nfoo\r\nFIN\r\n",
+                   :tSTRING_BEG,     "<<\"",
+                   :tSTRING_CONTENT, "foo\n",
+                   :tSTRING_END,     "FIN",
+                   :tNL,             nil)
+  end
+
+  def test_bug_eh_symbol_no_newline
+    assert_scanned("?\"\nfoo",
+                   :tINTEGER,     34,
+                   :tNL,          nil,
+                   :tIDENTIFIER,  "foo")
+  end
+
+  def test_bug_expr_arg_newline
+    @lex.state = :expr_arg
+    assert_scanned("\nfoo",
+                   :tNL,          nil,
+                   :tIDENTIFIER,  "foo")
+
+    @lex.state = :expr_arg
+    assert_scanned(" \nfoo",
+                   :tNL,          nil,
+                   :tIDENTIFIER,  "foo")
+
+    @lex.state = :expr_arg
+    assert_scanned("#foo\nfoo",
+                   :tNL,          nil,
+                   :tIDENTIFIER,  "foo")
+  end
+
+  def test_bug_expr_arg_comment_newline
+    @lex.state = :expr_arg
+    assert_scanned(" #\nfoo",
+                   :tNL,         nil,
+                   :tIDENTIFIER, 'foo')
+  end
+
+  def test_bug_expr_arg_eh_crlf
+    @lex.state = :expr_arg
+    assert_scanned(" ?\r\n",
+                   :tEH,     '?')
+  end
+
+  def test_bug_heredoc_backspace_nl
+    assert_scanned(" <<'XXX'\nf \\\nXXX\n",
+                   :tSTRING_BEG,     "<<'",
+                   :tSTRING_CONTENT, "f \\\n",
+                   :tSTRING_END,     "XXX",
+                   :tNL,             nil)
+  end
+
+  def test_bug_heredoc_lshft
+    assert_scanned("<<RULES << CLEANINGS\nRULES",
+                   :tSTRING_BEG, '<<"',
+                   :tSTRING_END, 'RULES',
+                   :tLSHFT,      '<<',
+                   :tCONSTANT,   'CLEANINGS')
+  end
+
+  def test_bug_sclass_comment_lshft_label
+    assert_scanned("class # foo\n<< a:b;end",
+                   :kCLASS,      'class',
+                   :tLSHFT,      '<<',
+                   :tIDENTIFIER, 'a',
+                   :tSYMBOL,     'b',
+                   :tSEMI,       ';',
+                   :kEND,        'end')
+  end
+
+  def test_bug_expr_dot_comment
+    assert_scanned("foo. #bar\nbaz",
+                   :tIDENTIFIER, 'foo',
+                   :tDOT,        '.',
+                   :tIDENTIFIER, 'baz')
+  end
+
+  def test_bug_expr_dot_fid
+    assert_scanned("foo.S?",
+                   :tIDENTIFIER, 'foo',
+                   :tDOT,        '.',
+                   :tFID,        'S?')
+  end
+
+  def test_bug_expr_dot_id_eq
+    assert_scanned("foo.x= 1",
+                   :tIDENTIFIER, 'foo',
+                   :tDOT,        '.',
+                   :tIDENTIFIER, 'x',
+                   :tEQL,        '=',
+                   :tINTEGER,    1)
+  end
+
+  def test_bug_expr_dot_fid_mod
+    assert_scanned("foo.x!if 1",
+                   :tIDENTIFIER, 'foo',
+                   :tDOT,        '.',
+                   :tFID,        'x!',
+                   :kIF_MOD,     'if',
+                   :tINTEGER,    1)
+  end
+
+  def test_bug_expr_mid_comment
+    assert_scanned("rescue #bar\nprint",
+                   :kRESCUE,     'rescue',
+                   :tNL,         nil,
+                   :tIDENTIFIER, 'print')
+  end
+
+  def test_bug_expr_mid_bareword
+    assert_scanned("begin; rescue rescue1",
+                   :kBEGIN,       'begin',
+                   :tSEMI,        ';',
+                   :kRESCUE,      'rescue',
+                   :tIDENTIFIER,  'rescue1')
+  end
+
+  def test_bug_expr_value_document
+    assert_scanned("1;\n=begin\n=end",
+                   :tINTEGER, 1,
+                   :tSEMI,    ';')
+  end
+
+  def test_bug_expr_end_colon
+    assert_scanned("'foo':'bar'",
+                   :tSTRING, 'foo',
+                   :tCOLON,  ':',
+                   :tSTRING, 'bar')
+  end
+
+  def test_bug_expr_value_rescue_colon2
+    @lex.state = :expr_value
+    assert_scanned("rescue::Exception",
+                   :kRESCUE,    'rescue',
+                   :tCOLON3,    '::',
+                   :tCONSTANT,  'Exception')
+  end
+
+  def test_bug_expr_endarg_braces
+    assert_scanned("let [] {",
+                   :tIDENTIFIER, 'let',
+                   :tLBRACK,     '[',
+                   :tRBRACK,     ']',
+                   :tLBRACE_ARG, '{')
+  end
+
+  def test_bug_line_begin_label
+    setup_lexer(19)
+    assert_scanned("foo:bar",
+                   :tIDENTIFIER, 'foo',
+                   :tSYMBOL,     'bar')
+  end
+
+  def test_bug_interp_expr_value
+    assert_scanned('"#{f:a}"',
+                   :tSTRING_BEG,  '"',
+                   :tSTRING_DBEG, '#{',
+                   :tIDENTIFIER,  'f',
+                   :tSYMBOL,      'a',
+                   :tRCURLY,      '}',
+                   :tSTRING_END,  '"')
+  end
+
+  def test_bug_const_e
+    assert_scanned('E10',
+                   :tCONSTANT, 'E10')
+    assert_scanned('E4U',
+                   :tCONSTANT, 'E4U')
+  end
+
+  def test_bug_symbol_newline
+    assert_scanned(":foo\n",
+                   :tSYMBOL, 'foo',
+                   :tNL,     nil)
+
+    assert_scanned(":foo=\n",
+                   :tSYMBOL, 'foo=',
+                   :tNL,     nil)
+  end
+
+  def test_bug_interleaved_heredoc
+    assert_scanned(%Q{<<w; "\nfoo\nw\n"},
+                   :tSTRING_BEG,     '<<"',
+                   :tSTRING_CONTENT, "foo\n",
+                   :tSTRING_END,     'w',
+                   :tSEMI,           ';',
+                   :tSTRING_BEG,     '"',
+                   :tSTRING_CONTENT, "\n",
+                   :tSTRING_END,     '"')
+
+    @lex.state = :expr_beg
+    assert_scanned(%Q{<<w; %w[\nfoo\nw\n1]},
+                   :tSTRING_BEG,     '<<"',
+                   :tSTRING_CONTENT, "foo\n",
+                   :tSTRING_END,     'w',
+                   :tSEMI,           ';',
+                   :tQWORDS_BEG,     '%w[',
+                   :tSTRING_CONTENT, "1",
+                   :tSPACE,          nil,
+                   :tSTRING_END,     ']')
+
+                   @lex.state = :expr_beg
+    assert_scanned(%Q{<<w; "\#{\nfoo\nw\n}"},
+                   :tSTRING_BEG,     '<<"',
+                   :tSTRING_CONTENT, "foo\n",
+                   :tSTRING_END,     'w',
+                   :tSEMI,           ';',
+                   :tSTRING_BEG,     '"',
+                   :tSTRING_DBEG,    '#{',
+                   :tRCURLY,         '}',
+                   :tSTRING_END,     '"')
+  end
+
+  def test_bug_fid_char
+    setup_lexer(19)
+    assert_scanned(%Q{eof??a},
+                   :tFID,       'eof?',
+                   :tCHARACTER, 'a')
+  end
+
+  def test_bug_nonlabel_context__18
+    env = Parser::StaticEnvironment.new
+    env.declare "a"
+
+    @lex.static_env = env
+    assert_scanned("1+a:a",
+                   :tINTEGER,    1,
+                   :tPLUS,       '+',
+                   :tIDENTIFIER, 'a',
+                   :tCOLON,      ':',
+                   :tIDENTIFIER, 'a')
+  end
+
+  def test_bug_string_percent_newline
+    assert_scanned(%Q{%\nfoo\n},
+                   :tSTRING_BEG,     "%\n",
+                   :tSTRING_CONTENT, 'foo',
+                   :tSTRING_END,     "\n")
+  end
+
+  def test_bug_string_percent_zero
+    assert_scanned(%Q{%\0foo\0},
+                   :tSTRING_BEG,     "%\0",
+                   :tSTRING_CONTENT, 'foo',
+                   :tSTRING_END,     "\0")
+  end
+
+  def test_bug_string_utf_escape_composition
+    assert_scanned(%q{"\xE2\x80\x99"},
+                   :tSTRING, "\xE2\x80\x99")
+
+    if defined?(Encoding)
+      assert_scanned(%q{"\xE2\x80\x99"}.force_encoding(Encoding::UTF_8),
+                     :tSTRING, '’'.force_encoding(Encoding::UTF_8))
+      assert_scanned(%q{"\342\200\231"}.force_encoding(Encoding::UTF_8),
+                     :tSTRING, '’'.force_encoding(Encoding::UTF_8))
+      assert_scanned(%q{"\M-b\C-\M-@\C-\M-Y"}.force_encoding(Encoding::UTF_8),
+                     :tSTRING, '’'.force_encoding(Encoding::UTF_8))
+    end
+  end
+
+  def test_bug_string_non_utf
+    assert_scanned(%Q{"caf\xE9"},
+                   :tSTRING, "caf\xE9")
+    assert_scanned(%Q{"caf\xC3\xA9"},
+                   :tSTRING, "caf\xC3\xA9")
+
+    if defined?(Encoding)
+      assert_scanned(%q{"café"}.force_encoding(Encoding::UTF_8),
+                     :tSTRING, "café".force_encoding(Encoding::UTF_8))
+    end
+  end
+
+  def test_bug_semi__END__
+    assert_scanned(%Q{foo;\n__END__},
+                   :tIDENTIFIER, 'foo',
+                   :tSEMI,       ';')
+  end
+
+  def test_bug_eql_end
+    assert_scanned(%Q{=begin\n#=end\n=end})
+  end
+
+  def test_bug_hidden_eof
+    @lex.state = :expr_beg
+    assert_scanned(%Q{"foo\0\x1a\x04bar"},
+                   :tSTRING_BEG,     '"',
+                   :tSTRING_CONTENT, "foo\0",
+                   :tSTRING_CONTENT, "\x1a",
+                   :tSTRING_CONTENT, "\x04",
+                   :tSTRING_CONTENT, "bar",
+                   :tSTRING_END,     '"')
+
+    @lex.state = :expr_beg
+    assert_scanned(%Q{'foo\0\x1a\x04bar'},
+                   :tSTRING_BEG,     "'",
+                   :tSTRING_CONTENT, "foo\0",
+                   :tSTRING_CONTENT, "\x1a",
+                   :tSTRING_CONTENT, "\x04",
+                   :tSTRING_CONTENT, "bar",
+                   :tSTRING_END,     "'")
+
+    @lex.state = :expr_beg
+    assert_scanned(%Q{%w[foo\0\x1a\x04bar]},
+                   :tQWORDS_BEG,     '%w[',
+                   :tSTRING_CONTENT, "foo\0",
+                   :tSTRING_CONTENT, "\x1a",
+                   :tSTRING_CONTENT, "\x04",
+                   :tSTRING_CONTENT, "bar",
+                   :tSPACE,          nil,
+                   :tSTRING_END,     ']')
+
+    @lex.state = :expr_beg
+    assert_scanned(%Q{%W[foo\0\x1a\x04bar]},
+                   :tWORDS_BEG,      '%W[',
+                   :tSTRING_CONTENT, "foo\0",
+                   :tSTRING_CONTENT, "\x1a",
+                   :tSTRING_CONTENT, "\x04",
+                   :tSTRING_CONTENT, "bar",
+                   :tSPACE,          nil,
+                   :tSTRING_END,     ']')
+
+    @lex.state = :expr_beg
+    assert_scanned(%Q{# foo\0\nbar},
+                   :tIDENTIFIER, 'bar')
+
+    @lex.state = :line_begin
+    assert_scanned(%Q{=begin\n\0\n=end\nbar},
+                   :tIDENTIFIER, 'bar')
+  end
+
+  def test_bug_num_adj_kw
+    assert_scanned(%q{1if},
+                   :tINTEGER, 1,
+                   :kIF_MOD,  'if')
+
+    assert_scanned(%q{1.0if},
+                   :tFLOAT,   1.0,
+                   :kIF_MOD,  'if')
+  end
+
+  if defined?(Encoding)
+    def test_bug_unicode_in_literal
+      setup_lexer(19)
+      assert_scanned('"\u00a4"',
+                     :tSTRING, "\u00a4")
+    end
+
+    def test_bug_utf32le_leak
+      setup_lexer(19)
+      @lex.force_utf32 = true
+      assert_scanned('"F0"',
+                     :tSTRING, "F0")
+    end
+  end
+
+  def test_bug_ragel_stack
+    assert_scanned("\"\#{$2 ? $2 : 1}\"",
+                   :tSTRING_BEG,      "\"",
+                   :tSTRING_DBEG,     "\#{",
+                   :tNTH_REF,         2,
+                   :tEH,              "?",
+                   :tNTH_REF,         2,
+                   :tCOLON,           ":",
+                   :tINTEGER,         1,
+                   :tRCURLY,          "}",
+                   :tSTRING_END,      "\"")
+  end
+
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_lexer_stack_state.rb b/app/server/vendor/parser-2.2.2.1/test/test_lexer_stack_state.rb
new file mode 100644
index 0000000..b355f48
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_lexer_stack_state.rb
@@ -0,0 +1,76 @@
+require 'helper'
+
+class TestLexerStackState < Minitest::Test
+  def setup
+    @state = Parser::Lexer::StackState.new('state')
+  end
+
+  def test_push
+    refute @state.active?
+
+    assert_equal true, @state.push(true)
+    assert @state.active?
+
+    assert_equal false, @state.push(false)
+    refute @state.active?
+  end
+
+  def test_clear
+    @state.push true
+    @state.clear
+
+    refute @state.active?
+  end
+
+  def test_pop
+    @state.push(true)
+
+    assert_equal true, @state.pop
+    refute @state.active?
+  end
+
+  def test_pop_empty
+    assert_equal false, @state.pop
+    refute @state.active?
+  end
+
+  def test_lexpop_10
+    @state.push(true)
+    @state.push(false)
+
+    assert_equal true, @state.lexpop
+    assert_equal true, @state.pop
+  end
+
+  def test_lexpop_01
+    @state.push(false)
+    @state.push(true)
+
+    assert_equal true, @state.lexpop
+    assert_equal true, @state.pop
+  end
+
+  def test_lexpop_00
+    @state.push(false)
+    @state.push(false)
+
+    assert_equal false, @state.lexpop
+    assert_equal false, @state.pop
+  end
+
+  def test_dup
+    @state.push(true)
+    new_state = @state.dup
+
+    assert_equal true, @state.pop
+    assert_equal true, new_state.pop
+  end
+
+  def test_to_s
+    @state.push(true)
+    @state.push(false)
+    @state.push(false)
+
+    assert_equal '[100 <= state]', @state.to_s
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_parse_helper.rb b/app/server/vendor/parser-2.2.2.1/test/test_parse_helper.rb
new file mode 100644
index 0000000..0c91168
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_parse_helper.rb
@@ -0,0 +1,80 @@
+require 'helper'
+require 'parse_helper'
+
+class TestParseHelper < Minitest::Test
+  include ParseHelper
+
+  def test_parser_for_ruby_version
+    assert_instance_of Parser::Ruby18,
+                       parser_for_ruby_version('1.8')
+
+    unless RUBY_VERSION == '1.8.7'
+      assert_instance_of Parser::Ruby19,
+                         parser_for_ruby_version('1.9')
+
+      assert_instance_of Parser::Ruby20,
+                         parser_for_ruby_version('2.0')
+
+      assert_instance_of Parser::Ruby21,
+                         parser_for_ruby_version('2.1')
+    end
+  end
+
+  def parse_maps(what)
+    parse_source_map_descriptions(what).to_a
+  end
+
+  def test_parse_mapsation_description
+    assert_equal [[0, 4, 'expr', [], '~~~~ expr']],
+                 parse_maps('~~~~ expr')
+
+    assert_equal [[0, 4, 'expr', [], '^~~~ expr']],
+                 parse_maps('^~~~ expr')
+
+    assert_equal [[0, 4, 'expr', [], '^^^^ expr']],
+                 parse_maps('^^^^ expr')
+
+    assert_equal [[2, 3, 'op', [], '  ^ op']],
+                 parse_maps('  ^ op')
+
+    assert_equal [[2, 3, 'op', ['foo'], '  ~ op (foo)']],
+                 parse_maps('  ~ op (foo)')
+
+    assert_equal [[2, 4, 'op', ['foo', 'bar'], '  ~~ op (foo.bar)']],
+                 parse_maps('  ~~ op (foo.bar)')
+
+    assert_equal [[2, 4, 'op', ['foo/2', 'bar'], '  ~~ op (foo/2.bar)']],
+                 parse_maps('  ~~ op (foo/2.bar)')
+
+    assert_equal [[0, 4, 'expr', [], '~~~~ expr'],
+                  [5, 7, 'op', ['str', 'e_h'], '     ~~ op (str.e_h)']],
+                 parse_maps(%{
+                            |~~~~ expr
+                            |     ~~ op (str.e_h)
+                            })
+  end
+
+  def test_traverse_ast
+    ast = s(:send,
+            s(:int, 1), :+,
+            s(:dstr,
+              s(:str, 'foo'),
+              s(:int, 2),
+              s(:int, 3)))
+
+    assert_equal ast, traverse_ast(ast, %w())
+
+    assert_equal s(:int, 1), traverse_ast(ast, %w(int))
+    assert_equal nil, traverse_ast(ast, %w(str))
+
+    assert_equal s(:str, 'foo'), traverse_ast(ast, %w(dstr str))
+    assert_equal s(:int, 2), traverse_ast(ast, %w(dstr int))
+    assert_equal s(:int, 2), traverse_ast(ast, %w(dstr int/1))
+    assert_equal s(:int, 3), traverse_ast(ast, %w(dstr int/2))
+    assert_equal nil, traverse_ast(ast, %w(dstr int/3))
+  end
+
+  def test_assert_parses
+    # Someone more clever and/or motivated than me is going to test this.
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_parser.rb b/app/server/vendor/parser-2.2.2.1/test/test_parser.rb
new file mode 100644
index 0000000..a6382d4
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_parser.rb
@@ -0,0 +1,4959 @@
+# encoding:utf-8
+
+require 'helper'
+require 'parse_helper'
+
+class TestParser < Minitest::Test
+  include ParseHelper
+
+  def parser_for_ruby_version(version)
+    parser = super
+    parser.diagnostics.all_errors_are_fatal = true
+
+    %w(foo bar baz).each do |metasyntactic_var|
+      parser.static_env.declare(metasyntactic_var)
+    end
+
+    parser
+  end
+
+  # Guidelines for test naming:
+  #  * Test structure follows structure of AST_FORMAT.md.
+  #  * Test names follow node names.
+  #  * Structurally similar sources may be grouped into one test.
+  #  * If, following the guidelines above, names clash, append
+  #    an abbreviated disambiguator. E.g. `test_class` and
+  #    `test_class_super`.
+  #  * When writing a test for a bug, append unabbreviated (but
+  #    concise) bug description. E.g. `test_class_bug_missing_newline`.
+  #  * Do not append Ruby language version to the name.
+  #  * When in doubt, look at existing test names.
+  #
+  # Guidelines for writing assertions:
+  #  * Don't check for structurally same source mapping information
+  #    more than once or twice in the entire file. It clutters the
+  #    source for no reason.
+  #  * Don't forget to check for optional delimiters. `()`, `then`, etc.
+  #  * When in doubt, look at existing assertions.
+
+  #
+  # Literals
+  #
+
+  def test_empty_stmt
+    assert_parses(
+      nil,
+      %q{})
+  end
+
+  def test_nil
+    assert_parses(
+      s(:nil),
+      %q{nil},
+      %q{~~~ expression})
+  end
+
+  def test_nil_expression
+    assert_parses(
+      s(:begin),
+      %q{()},
+      %q{^ begin
+        | ^ end
+        |~~ expression})
+
+    assert_parses(
+      s(:kwbegin),
+      %q{begin end},
+      %q{~~~~~ begin
+        |      ~~~ end
+        |~~~~~~~~~ expression})
+  end
+
+  def test_true
+    assert_parses(
+      s(:true),
+      %q{true},
+      %q{~~~~ expression})
+  end
+
+  def test_false
+    assert_parses(
+      s(:false),
+      %q{false},
+      %q{~~~~~ expression})
+  end
+
+  def test_int
+    assert_parses(
+      s(:int, 42),
+      %q{42},
+      %q{~~ expression})
+
+    assert_parses(
+      s(:int, -42),
+      %q{-42},
+      %q{^ operator
+        |~~~ expression})
+  end
+
+  def test_int___LINE__
+    assert_parses(
+      s(:int, 1),
+      %q{__LINE__},
+      %q{~~~~~~~~ expression})
+  end
+
+  def test_float
+    assert_parses(
+      s(:float, 1.33),
+      %q{1.33},
+      %q{~~~~ expression})
+
+    assert_parses(
+      s(:float, -1.33),
+      %q{-1.33},
+      %q{^ operator
+        |~~~~~ expression})
+  end
+
+  def test_rational
+    assert_parses(
+      s(:rational, Rational(42)),
+      %q{42r},
+      %q{~~~ expression},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+
+    assert_parses(
+      s(:rational, Rational(421, 10)),
+      %q{42.1r},
+      %q{~~~~~ expression},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+  end
+
+  def test_complex
+    assert_parses(
+      s(:complex, Complex(0, 42)),
+      %q{42i},
+      %q{~~~ expression},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+
+    assert_parses(
+      s(:complex, Complex(0, Rational(42))),
+      %q{42ri},
+      %q{~~~~ expression},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+
+    assert_parses(
+      s(:complex, Complex(0, 42.1)),
+      %q{42.1i},
+      %q{~~~~~ expression},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+
+    assert_parses(
+      s(:complex, Complex(0, Rational(421, 10))),
+      %q{42.1ri},
+      %q{~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+  end
+
+  # Strings
+
+  def test_string_plain
+    assert_parses(
+      s(:str, 'foobar'),
+      %q{'foobar'},
+      %q{^ begin
+        |       ^ end
+        |~~~~~~~~ expression})
+
+    assert_parses(
+      s(:str, 'foobar'),
+      %q{%q(foobar)},
+      %q{^^^ begin
+        |         ^ end
+        |~~~~~~~~~~ expression})
+  end
+
+  def test_string_interp
+    assert_parses(
+      s(:dstr,
+        s(:str, 'foo'),
+        s(:begin, s(:lvar, :bar)),
+        s(:str, 'baz')),
+      %q{"foo#{bar}baz"},
+      %q{^ begin
+        |             ^ end
+        |    ^^ begin (begin)
+        |         ^ end (begin)
+        |    ~~~~~~ expression (begin)
+        |~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_string_dvar
+    assert_parses(
+      s(:dstr,
+        s(:ivar, :@a),
+        s(:str, ' '),
+        s(:cvar, :@@a),
+        s(:str, ' '),
+        s(:gvar, :$a)),
+      %q{"#@a #@@a #$a"})
+  end
+
+  def test_string_concat
+    assert_parses(
+      s(:dstr,
+        s(:dstr,
+          s(:str, 'foo'),
+          s(:ivar, :@a)),
+        s(:str, 'bar')),
+      %q{"foo#@a" "bar"},
+      %q{^ begin (dstr)
+        |       ^ end (dstr)
+        |         ^ begin (str)
+        |             ^ end (str)
+        |~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_string___FILE__
+    assert_parses(
+      s(:str, '(assert_parses)'),
+      %q{__FILE__},
+      %q{~~~~~~~~ expression})
+  end
+
+  def test_character
+    assert_parses(
+      s(:str, 'a'),
+      %q{?a},
+      %q{^ begin
+        |~~ expression},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:int, 97),
+      %q{?a},
+      %q{~~ expression},
+      %w(1.8))
+  end
+
+  def test_heredoc
+    assert_parses(
+      s(:dstr, s(:str, "foo\n"), s(:str, "bar\n")),
+      %Q{<<HERE!foo!bar!HERE}.gsub('!', "\n"),
+      %q{~~~~~~ expression
+        |       ~~~~~~~~ heredoc_body
+        |               ~~~~ heredoc_end})
+
+    assert_parses(
+      s(:dstr, s(:str, "foo\n"), s(:str, "bar\n")),
+      %Q{<<'HERE'!foo!bar!HERE}.gsub('!', "\n"),
+      %q{~~~~~~~~ expression
+        |         ~~~~~~~~ heredoc_body
+        |                 ~~~~ heredoc_end})
+
+    assert_parses(
+      s(:xstr, s(:str, "foo\n"), s(:str, "bar\n")),
+      %Q{<<`HERE`!foo!bar!HERE}.gsub('!', "\n"),
+      %q{~~~~~~~~ expression
+        |         ~~~~~~~~ heredoc_body
+        |                 ~~~~ heredoc_end})
+  end
+
+  # Symbols
+
+  def test_symbol_plain
+    assert_parses(
+      s(:sym, :foo),
+      %q{:foo},
+      %q{~ begin
+        |~~~~ expression})
+
+    assert_parses(
+      s(:sym, :foo),
+      %q{:'foo'},
+      %q{^^ begin
+        |     ^ end
+        |~~~~~~ expression})
+  end
+
+  def test_symbol_interp
+    assert_parses(
+      s(:dsym,
+        s(:str, 'foo'),
+        s(:begin, s(:lvar, :bar)),
+        s(:str, 'baz')),
+      %q{:"foo#{bar}baz"},
+      %q{^^ begin
+        |              ^ end
+        |     ^^ begin (begin)
+        |          ^ end (begin)
+        |     ~~~~~~ expression (begin)
+        |~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_symbol_empty
+    assert_diagnoses(
+      [:error, :empty_symbol],
+      %q{:''},
+      %q{^^^ location},
+      %w(1.8))
+
+    assert_diagnoses(
+      [:error, :empty_symbol],
+      %q{:""},
+      %q{^^^ location},
+      %w(1.8))
+  end
+
+  # Execute-strings
+
+  def test_xstring_plain
+    assert_parses(
+      s(:xstr, s(:str, 'foobar')),
+      %q{`foobar`},
+      %q{^ begin
+        |       ^ end
+        |~~~~~~~~ expression})
+  end
+
+  def test_xstring_interp
+    assert_parses(
+      s(:xstr,
+        s(:str, 'foo'),
+        s(:begin, s(:lvar, :bar)),
+        s(:str, 'baz')),
+      %q{`foo#{bar}baz`},
+      %q{^ begin
+        |             ^ end
+        |    ^^ begin (begin)
+        |         ^ end (begin)
+        |    ~~~~~~ expression (begin)
+        |~~~~~~~~~~~~~~ expression})
+  end
+
+  # Regexp
+
+  def test_regex_plain
+    assert_parses(
+      s(:regexp, s(:str, 'source'), s(:regopt, :i, :m)),
+      %q{/source/im},
+      %q{^ begin
+        |       ^ end
+        |        ~~ expression (regopt)
+        |~~~~~~~~~~ expression})
+  end
+
+  def test_regex_interp
+    assert_parses(
+      s(:regexp,
+        s(:str, 'foo'),
+        s(:begin, s(:lvar, :bar)),
+        s(:str, 'baz'),
+        s(:regopt)),
+      %q{/foo#{bar}baz/},
+      %q{^ begin
+        |    ^^ begin (begin)
+        |         ^ end (begin)
+        |    ~~~~~~ expression (begin)
+        |             ^ end
+        |~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_regex_error
+    # The tests work on 1.8, but with a different message.
+    assert_diagnoses(
+      [:error, :invalid_regexp, {:message => 'target of repeat operator is not specified: /?/'}],
+      %q[/?/],
+      %q(~~~ location),
+      ALL_VERSIONS - %w(1.8))
+
+    assert_diagnoses(
+      [:error, :invalid_regexp, {:message => 'target of repeat operator is not specified: /?/'}],
+      %q[/#{""}?/],
+      %q(~~~~~~~~ location),
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  # Arrays
+
+  def test_array_plain
+    assert_parses(
+      s(:array, s(:int, 1), s(:int, 2)),
+      %q{[1, 2]},
+      %q{^ begin
+        |     ^ end
+        |~~~~~~ expression})
+  end
+
+  def test_array_splat
+    assert_parses(
+      s(:array,
+        s(:int, 1),
+        s(:splat, s(:lvar, :foo)),
+        s(:int, 2)),
+      %q{[1, *foo, 2]},
+      %q{^ begin
+        |           ^ end
+        |    ^ operator (splat)
+        |    ~~~~ expression (splat)
+        |~~~~~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:array,
+        s(:int, 1),
+        s(:splat, s(:lvar, :foo))),
+      %q{[1, *foo]},
+      %q{^ begin
+        |        ^ end
+        |    ^ operator (splat)
+        |    ~~~~ expression (splat)
+        |~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:array,
+        s(:splat, s(:lvar, :foo))),
+      %q{[*foo]})
+  end
+
+  def test_array_assocs
+    assert_parses(
+      s(:array,
+        s(:hash, s(:pair, s(:int, 1), s(:int, 2)))),
+      %q{[ 1 => 2 ]},
+      %q{    ~~ operator (hash.pair)
+        |  ~~~~~~ expression (hash.pair)
+        |  ~~~~~~ expression (hash)})
+
+    assert_parses(
+      s(:array,
+        s(:int, 1),
+        s(:hash, s(:pair, s(:int, 2), s(:int, 3)))),
+      %q{[ 1, 2 => 3 ]},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_array_words
+    assert_parses(
+      s(:array, s(:str, 'foo'), s(:str, 'bar')),
+      %q{%w[foo bar]},
+      %q{^^^ begin
+        |          ^ end
+        |   ~~~ expression (str)
+        |~~~~~~~~~~~ expression})
+  end
+
+  def test_array_words_interp
+    assert_parses(
+      s(:array,
+        s(:str, 'foo'),
+        s(:dstr, s(:begin, s(:lvar, :bar)))),
+      %q{%W[foo #{bar}]},
+      %q{^^^ begin
+        |       ^^ begin (dstr.begin)
+        |            ^ end (dstr.begin)
+        |       ~~~~~~ expression (dstr.begin)
+        |             ^ end
+        |   ~~~ expression (str)
+        |         ~~~ expression (dstr.begin.lvar)
+        |~~~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:array,
+        s(:str, 'foo'),
+        s(:dstr,
+          s(:begin, s(:lvar, :bar)),
+          s(:str, 'foo'),
+          s(:ivar, :@baz))),
+      %q{%W[foo #{bar}foo#@baz]})
+  end
+
+  def test_array_words_empty
+    assert_parses(
+      s(:array),
+      %q{%w[]},
+      %q{^^^ begin
+        |   ^ end
+        |~~~~ expression})
+
+    assert_parses(
+      s(:array),
+      %q{%W()})
+  end
+
+  def test_array_symbols
+    assert_parses(
+      s(:array, s(:sym, :foo), s(:sym, :bar)),
+      %q{%i[foo bar]},
+      %q{^^^ begin
+        |          ^ end
+        |   ~~~ expression (sym)
+        |~~~~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  def test_array_symbols_interp
+    assert_parses(
+      s(:array,
+        s(:sym, :foo),
+        s(:dsym, s(:begin, s(:lvar, :bar)))),
+      %q{%I[foo #{bar}]},
+      %q{^^^ begin
+        |             ^ end
+        |   ~~~ expression (sym)
+        |       ^^ begin (dsym.begin)
+        |            ^ end (dsym.begin)
+        |       ~~~~~~ expression (dsym.begin)
+        |         ~~~ expression (dsym.begin.lvar)
+        |~~~~~~~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    assert_parses(
+      s(:array,
+        s(:dsym,
+          s(:str, 'foo'),
+          s(:begin, s(:lvar, :bar)))),
+      %q{%I[foo#{bar}]},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  def test_array_symbols_empty
+    assert_parses(
+      s(:array),
+      %q{%i[]},
+      %q{^^^ begin
+        |   ^ end
+        |~~~~ expression},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    assert_parses(
+      s(:array),
+      %q{%I()},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  # Hashes
+
+  def test_hash_empty
+    assert_parses(
+      s(:hash),
+      %q[{ }],
+      %q{^ begin
+        |  ^ end
+        |~~~ expression})
+  end
+
+  def test_hash_hashrocket
+    assert_parses(
+      s(:hash, s(:pair, s(:int, 1), s(:int, 2))),
+      %q[{ 1 => 2 }],
+      %q{^ begin
+        |         ^ end
+        |    ^^ operator (pair)
+        |  ~~~~~~ expression (pair)
+        |~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:hash,
+        s(:pair, s(:int, 1), s(:int, 2)),
+        s(:pair, s(:sym, :foo), s(:str, 'bar'))),
+      %q[{ 1 => 2, :foo => "bar" }])
+  end
+
+  def test_hash_label
+    assert_parses(
+      s(:hash, s(:pair, s(:sym, :foo), s(:int, 2))),
+      %q[{ foo: 2 }],
+      %q{^ begin
+        |         ^ end
+        |     ^ operator (pair)
+        |  ~~~ expression (pair.sym)
+        |  ~~~~~~ expression (pair)
+        |~~~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_hash_label_end
+    assert_parses(
+      s(:hash, s(:pair, s(:sym, :foo), s(:int, 2))),
+      %q[{ 'foo': 2 }],
+      %q{^ begin
+        |           ^ end
+        |       ^ operator (pair)
+        |  ^ begin (pair.sym)
+        |      ^ end (pair.sym)
+        |  ~~~~~ expression (pair.sym)
+        |  ~~~~~~~~ expression (pair)
+        |~~~~~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8 1.9 2.0 2.1))
+
+    assert_parses(
+      s(:hash,
+        s(:pair, s(:sym, :foo), s(:int, 2)),
+        s(:pair, s(:sym, :bar), s(:hash))),
+      %q[{ 'foo': 2, 'bar': {}}],
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9 2.0 2.1))
+
+    assert_parses(
+      s(:send, nil, :f,
+        s(:if, s(:send, nil, :a),
+          s(:str, "a"),
+          s(:int, 1))),
+      %q{f(a ? "a":1)},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9 2.0 2.1))
+  end
+
+  def test_hash_kwsplat
+    assert_parses(
+      s(:hash,
+        s(:pair, s(:sym, :foo), s(:int, 2)),
+        s(:kwsplat, s(:lvar, :bar))),
+      %q[{ foo: 2, **bar }],
+      %q{          ^^ operator (kwsplat)
+        |          ~~~~~ expression (kwsplat)},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  def test_hash_no_hashrocket
+    assert_parses(
+      s(:hash, s(:pair, s(:int, 1), s(:int, 2))),
+      %q[{ 1, 2 }],
+      %q{^ begin
+        |       ^ end
+        |  ~~~~ expression (pair)
+        |~~~~~~~~ expression},
+      %w(1.8))
+  end
+
+  def test_hash_no_hashrocket_odd
+    assert_diagnoses(
+      [:error, :odd_hash],
+      %q[{ 1, 2, 3 }],
+      %q(        ~ location),
+      %w(1.8))
+  end
+
+  # Range
+
+  def test_range_inclusive
+    assert_parses(
+      s(:irange, s(:int, 1), s(:int, 2)),
+      %q{1..2},
+      %q{ ~~ operator
+        |~~~~ expression})
+  end
+
+  def test_range_exclusive
+    assert_parses(
+      s(:erange, s(:int, 1), s(:int, 2)),
+      %q{1...2},
+      %q{ ~~~ operator
+        |~~~~~ expression})
+  end
+
+  #
+  # Access
+  #
+
+  # Variables and pseudovariables
+
+  def test_self
+    assert_parses(
+      s(:self),
+      %q{self},
+      %q{~~~~ expression})
+  end
+
+  def test_lvar
+    assert_parses(
+      s(:lvar, :foo),
+      %q{foo},
+      %q{~~~ expression})
+  end
+
+  def test_ivar
+    assert_parses(
+      s(:ivar, :@foo),
+      %q{@foo},
+      %q{~~~~ expression})
+  end
+
+  def test_cvar
+    assert_parses(
+      s(:cvar, :@@foo),
+      %q{@@foo},
+      %q{~~~~~ expression})
+  end
+
+  def test_gvar
+    assert_parses(
+      s(:gvar, :$foo),
+      %q{$foo},
+      %q{~~~~ expression})
+  end
+
+  def test_gvar_dash_empty
+    assert_diagnoses(
+      [:fatal, :unexpected, { :character => '$' }],
+      %q{$- },
+      %q{^ location},
+      %w(2.1))
+  end
+
+  def test_back_ref
+    assert_parses(
+      s(:back_ref, :$+),
+      %q{$+},
+      %q{~~ expression})
+  end
+
+  def test_nth_ref
+    assert_parses(
+      s(:nth_ref, 10),
+      %q{$10},
+      %q{~~~ expression})
+  end
+
+  # Constants
+
+  def test_const_toplevel
+    assert_parses(
+      s(:const, s(:cbase), :Foo),
+      %q{::Foo},
+      %q{  ~~~ name
+        |~~ double_colon
+        |~~~~~ expression})
+  end
+
+  def test_const_scoped
+    assert_parses(
+      s(:const, s(:const, nil, :Bar), :Foo),
+      %q{Bar::Foo},
+      %q{     ~~~ name
+        |   ~~ double_colon
+        |~~~~~~~~ expression})
+  end
+
+  def test_const_unscoped
+    assert_parses(
+      s(:const, nil, :Foo),
+      %q{Foo},
+      %q{~~~ name
+        |~~~ expression})
+  end
+
+  def test___ENCODING__
+    assert_parses(
+      s(:const, s(:const, nil, :Encoding), :UTF_8),
+      %q{__ENCODING__},
+      %q{~~~~~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  # defined?
+
+  def test_defined
+    assert_parses(
+      s(:defined?, s(:lvar, :foo)),
+      %q{defined? foo},
+      %q{~~~~~~~~ keyword
+        |~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:defined?, s(:lvar, :foo)),
+      %q{defined?(foo)},
+      %q{~~~~~~~~ keyword
+        |        ^ begin
+        |            ^ end
+        |~~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:defined?, s(:ivar, :@foo)),
+      %q{defined? @foo})
+  end
+
+  #
+  # Assignment
+  #
+
+  # Variables
+
+  def test_lvasgn
+    assert_parses(
+      s(:begin,
+        s(:lvasgn, :var, s(:int, 10)),
+        s(:lvar, :var)),
+      %q{var = 10; var},
+      %q{~~~ name (lvasgn)
+        |    ^ operator (lvasgn)
+        |~~~~~~~~ expression (lvasgn)
+        })
+  end
+
+  def test_ivasgn
+    assert_parses(
+      s(:ivasgn, :@var, s(:int, 10)),
+      %q{@var = 10},
+      %q{~~~~ name
+        |     ^ operator
+        |~~~~~~~~~ expression
+        })
+  end
+
+  def test_cvasgn
+    assert_parses(
+      s(:cvasgn, :@@var, s(:int, 10)),
+      %q{@@var = 10},
+      %q{~~~~~ name
+        |      ^ operator
+        |~~~~~~~~~~ expression
+        })
+  end
+
+  def test_gvasgn
+    assert_parses(
+      s(:gvasgn, :$var, s(:int, 10)),
+      %q{$var = 10},
+      %q{~~~~ name
+        |     ^ operator
+        |~~~~~~~~~ expression
+        })
+  end
+
+  def test_asgn_cmd
+    assert_parses(
+      s(:lvasgn, :foo, s(:send, nil, :m, s(:lvar, :foo))),
+      %q{foo = m foo})
+
+    assert_parses(
+      s(:lvasgn, :foo,
+        s(:lvasgn, :bar,
+          s(:send, nil, :m, s(:lvar, :foo)))),
+      %q{foo = bar = m foo},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_asgn_keyword_invalid
+    assert_diagnoses(
+      [:error, :invalid_assignment],
+      %q{nil = foo},
+      %q{~~~ location})
+
+    assert_diagnoses(
+      [:error, :invalid_assignment],
+      %q{self = foo},
+      %q{~~~~ location})
+
+    assert_diagnoses(
+      [:error, :invalid_assignment],
+      %q{true = foo},
+      %q{~~~~ location})
+
+    assert_diagnoses(
+      [:error, :invalid_assignment],
+      %q{false = foo},
+      %q{~~~~~ location})
+
+    assert_diagnoses(
+      [:error, :invalid_assignment],
+      %q{__FILE__ = foo},
+      %q{~~~~~~~~ location})
+
+    assert_diagnoses(
+      [:error, :invalid_assignment],
+      %q{__LINE__ = foo},
+      %q{~~~~~~~~ location})
+  end
+
+  def test_asgn_backref_invalid
+    assert_diagnoses(
+      [:error, :backref_assignment],
+      %q{$1 = foo},
+      %q{~~ location})
+  end
+
+  # Constants
+
+  def test_casgn_toplevel
+    assert_parses(
+      s(:casgn, s(:cbase), :Foo, s(:int, 10)),
+      %q{::Foo = 10},
+      %q{  ~~~ name
+        |      ^ operator
+        |~~ double_colon
+        |~~~~~~~~~~ expression
+        })
+  end
+
+  def test_casgn_scoped
+    assert_parses(
+      s(:casgn, s(:const, nil, :Bar), :Foo, s(:int, 10)),
+      %q{Bar::Foo = 10},
+      %q{     ~~~ name
+        |         ^ operator
+        |   ~~ double_colon
+        |~~~~~~~~~~~~~ expression
+        })
+  end
+
+  def test_casgn_unscoped
+    assert_parses(
+      s(:casgn, nil, :Foo, s(:int, 10)),
+      %q{Foo = 10},
+      %q{~~~ name
+        |    ^ operator
+        |~~~~~~~~ expression
+        })
+  end
+
+  def test_casgn_invalid
+    assert_diagnoses(
+      [:error, :dynamic_const],
+      %q{def f; Foo = 1; end},
+      %q{       ~~~ location})
+
+    assert_diagnoses(
+      [:error, :dynamic_const],
+      %q{def f; Foo::Bar = 1; end},
+      %q{       ~~~~~~~~ location})
+
+    assert_diagnoses(
+      [:error, :dynamic_const],
+      %q{def f; ::Bar = 1; end},
+      %q{       ~~~~~ location})
+  end
+
+  # Multiple assignment
+
+  def test_masgn
+    assert_parses(
+      s(:masgn,
+        s(:mlhs, s(:lvasgn, :foo), s(:lvasgn, :bar)),
+        s(:array, s(:int, 1), s(:int, 2))),
+      %q{foo, bar = 1, 2},
+      %q{         ^ operator
+        |~~~~~~~~ expression (mlhs)
+        |           ~~~~ expression (array)
+        |~~~~~~~~~~~~~~~ expression
+        })
+
+    assert_parses(
+      s(:masgn,
+        s(:mlhs, s(:lvasgn, :foo), s(:lvasgn, :bar)),
+        s(:array, s(:int, 1), s(:int, 2))),
+      %q{(foo, bar) = 1, 2},
+      %q{^ begin (mlhs)
+        |         ^ end (mlhs)
+        |~~~~~~~~~~ expression (mlhs)
+        |~~~~~~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:masgn,
+        s(:mlhs,
+          s(:lvasgn, :foo),
+          s(:lvasgn, :bar),
+          s(:lvasgn, :baz)),
+        s(:array, s(:int, 1), s(:int, 2))),
+      %q{foo, bar, baz = 1, 2})
+  end
+
+  def test_masgn_splat
+    assert_parses(
+      s(:masgn,
+        s(:mlhs, s(:ivasgn, :@foo), s(:cvasgn, :@@bar)),
+        s(:array, s(:splat, s(:lvar, :foo)))),
+      %q{@foo, @@bar = *foo},
+      %q{              ^ operator (array.splat)
+        |              ~~~~ expression (array.splat)
+        })
+
+    assert_parses(
+      s(:masgn,
+        s(:mlhs, s(:lvasgn, :a), s(:lvasgn, :b)),
+        s(:array, s(:splat, s(:lvar, :foo)), s(:lvar, :bar))),
+      %q{a, b = *foo, bar},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:masgn,
+        s(:mlhs, s(:lvasgn, :a), s(:splat, s(:lvasgn, :b))),
+        s(:lvar, :bar)),
+      %q{a, *b = bar})
+
+    assert_parses(
+      s(:masgn,
+        s(:mlhs,
+          s(:lvasgn, :a),
+          s(:splat, s(:lvasgn, :b)),
+          s(:lvasgn, :c)),
+        s(:lvar, :bar)),
+      %q{a, *b, c = bar},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:masgn,
+        s(:mlhs, s(:lvasgn, :a), s(:splat)),
+        s(:lvar, :bar)),
+      %q{a, * = bar})
+
+    assert_parses(
+      s(:masgn,
+        s(:mlhs,
+          s(:lvasgn, :a),
+          s(:splat),
+          s(:lvasgn, :c)),
+        s(:lvar, :bar)),
+      %q{a, *, c = bar},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:masgn,
+        s(:mlhs, s(:splat, s(:lvasgn, :b))),
+        s(:lvar, :bar)),
+      %q{*b = bar})
+
+    assert_parses(
+      s(:masgn,
+        s(:mlhs,
+          s(:splat, s(:lvasgn, :b)),
+          s(:lvasgn, :c)),
+        s(:lvar, :bar)),
+      %q{*b, c = bar},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:masgn,
+        s(:mlhs, s(:splat)),
+        s(:lvar, :bar)),
+      %q{* = bar})
+
+    assert_parses(
+      s(:masgn,
+        s(:mlhs,
+          s(:splat),
+          s(:lvasgn, :c),
+          s(:lvasgn, :d)),
+        s(:lvar, :bar)),
+      %q{*, c, d = bar},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_masgn_nested
+    assert_parses(
+      s(:masgn,
+        s(:mlhs,
+          s(:lvasgn, :a),
+          s(:mlhs,
+            s(:lvasgn, :b),
+            s(:lvasgn, :c))),
+        s(:lvar, :foo)),
+      %q{a, (b, c) = foo},
+      %q{   ^ begin (mlhs.mlhs)
+        |        ^ end (mlhs.mlhs)
+        |   ~~~~~~ expression (mlhs.mlhs)
+        })
+
+    assert_parses(
+      s(:masgn,
+        s(:mlhs,
+          s(:lvasgn, :b)),
+        s(:lvar, :foo)),
+      %q{((b, )) = foo},
+      %q{^ begin (mlhs)
+        |      ^ end (mlhs)})
+  end
+
+  def test_masgn_attr
+    assert_parses(
+      s(:masgn,
+        s(:mlhs,
+          s(:send, s(:self), :a=),
+          s(:send, s(:self), :[]=, s(:int, 1), s(:int, 2))),
+        s(:lvar, :foo)),
+      %q{self.a, self[1, 2] = foo},
+      %q{~~~~~~ expression (mlhs.send/1)
+        |     ~ selector (mlhs.send/1)
+        |            ~~~~~~ selector (mlhs.send/2)
+        |        ~~~~~~~~~~ expression (mlhs.send/2)})
+
+    assert_parses(
+      s(:masgn,
+        s(:mlhs,
+          s(:send, s(:self), :a=),
+          s(:lvasgn, :foo)),
+        s(:lvar, :foo)),
+      %q{self::a, foo = foo})
+
+    assert_parses(
+      s(:masgn,
+        s(:mlhs,
+          s(:send, s(:self), :A=),
+          s(:lvasgn, :foo)),
+        s(:lvar, :foo)),
+      %q{self.A, foo = foo})
+  end
+
+  def test_masgn_const
+    assert_parses(
+      s(:masgn,
+        s(:mlhs,
+          s(:casgn, s(:self), :A),
+          s(:lvasgn, :foo)),
+        s(:lvar, :foo)),
+      %q{self::A, foo = foo})
+
+    assert_parses(
+      s(:masgn,
+        s(:mlhs,
+          s(:casgn, s(:cbase), :A),
+          s(:lvasgn, :foo)),
+        s(:lvar, :foo)),
+      %q{::A, foo = foo})
+  end
+
+  def test_masgn_cmd
+    assert_parses(
+      s(:masgn,
+        s(:mlhs,
+          s(:lvasgn, :foo),
+          s(:lvasgn, :bar)),
+        s(:send, nil, :m, s(:lvar, :foo))),
+      %q{foo, bar = m foo})
+  end
+
+  def test_asgn_mrhs
+    assert_parses(
+      s(:lvasgn, :foo,
+        s(:array, s(:lvar, :bar), s(:int, 1))),
+      %q{foo = bar, 1},
+      %q{      ~~~~~~ expression (array)
+        |~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:lvasgn, :foo,
+        s(:array, s(:splat, s(:lvar, :bar)))),
+      %q{foo = *bar})
+
+    assert_parses(
+      s(:lvasgn, :foo,
+        s(:array,
+          s(:lvar, :baz),
+          s(:splat, s(:lvar, :bar)))),
+      %q{foo = baz, *bar})
+  end
+
+  def test_masgn_keyword_invalid
+    assert_diagnoses(
+      [:error, :invalid_assignment],
+      %q{nil, foo = bar},
+      %q{~~~ location})
+  end
+
+  def test_masgn_backref_invalid
+    assert_diagnoses(
+      [:error, :backref_assignment],
+      %q{$1, = foo},
+      %q{~~ location})
+  end
+
+  def test_masgn_const_invalid
+    assert_diagnoses(
+      [:error, :dynamic_const],
+      %q{def f; self::A, foo = foo; end},
+      %q{       ~~~~~~~ location})
+
+    assert_diagnoses(
+      [:error, :dynamic_const],
+      %q{def f; ::A, foo = foo; end},
+      %q{       ~~~ location})
+  end
+
+  # Variable binary operator-assignment
+
+  def test_var_op_asgn
+    assert_parses(
+      s(:op_asgn, s(:lvasgn, :a), :+, s(:int, 1)),
+      %q{a += 1},
+      %q{  ^^ operator
+        |~~~~~~ expression})
+
+    assert_parses(
+      s(:op_asgn, s(:ivasgn, :@a), :|, s(:int, 1)),
+      %q{@a |= 1},
+      %q{   ^^ operator
+        |~~~~~~~ expression})
+
+    assert_parses(
+      s(:op_asgn, s(:cvasgn, :@@var), :|, s(:int, 10)),
+      %q{@@var |= 10})
+
+    assert_parses(
+      s(:def, :a, s(:args),
+        s(:op_asgn, s(:cvasgn, :@@var), :|, s(:int, 10))),
+      %q{def a; @@var |= 10; end})
+  end
+
+  def test_var_op_asgn_cmd
+    assert_parses(
+      s(:op_asgn,
+        s(:lvasgn, :foo), :+,
+        s(:send, nil, :m, s(:lvar, :foo))),
+      %q{foo += m foo})
+  end
+
+  def test_var_op_asgn_keyword_invalid
+    assert_diagnoses(
+      [:error, :invalid_assignment],
+      %q{nil += foo},
+      %q{~~~ location})
+  end
+
+  def test_const_op_asgn
+    assert_parses(
+      s(:op_asgn,
+        s(:casgn, nil, :A), :+,
+        s(:int, 1)),
+      %q{A += 1})
+
+    assert_parses(
+      s(:op_asgn,
+        s(:casgn, s(:cbase), :A), :+,
+        s(:int, 1)),
+      %q{::A += 1},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    assert_parses(
+      s(:op_asgn,
+        s(:casgn, s(:const, nil, :B), :A), :+,
+        s(:int, 1)),
+      %q{B::A += 1},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    assert_parses(
+      s(:def, :x, s(:args),
+        s(:or_asgn,
+          s(:casgn, s(:self), :A),
+          s(:int, 1))),
+      %q{def x; self::A ||= 1; end},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    assert_parses(
+      s(:def, :x, s(:args),
+        s(:or_asgn,
+          s(:casgn, s(:cbase), :A),
+          s(:int, 1))),
+      %q{def x; ::A ||= 1; end},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  def test_const_op_asgn_invalid
+    assert_diagnoses(
+      [:error, :dynamic_const],
+      %q{Foo::Bar += 1},
+      %q{     ~~~ location},
+      %w(1.8 1.9))
+
+    assert_diagnoses(
+      [:error, :dynamic_const],
+      %q{::Bar += 1},
+      %q{  ~~~ location},
+      %w(1.8 1.9))
+
+    assert_diagnoses(
+      [:error, :dynamic_const],
+      %q{def foo; Foo::Bar += 1; end},
+      %q{              ~~~ location},
+      %w(1.8 1.9))
+
+    assert_diagnoses(
+      [:error, :dynamic_const],
+      %q{def foo; ::Bar += 1; end},
+      %q{           ~~~ location},
+      %w(1.8 1.9))
+  end
+
+  # Method binary operator-assignment
+
+  def test_op_asgn
+    assert_parses(
+      s(:op_asgn,
+        s(:send, s(:lvar, :foo), :a), :+,
+        s(:int, 1)),
+      %q{foo.a += 1},
+      %q{      ^^ operator
+        |    ~ selector (send)
+        |~~~~~ expression (send)
+        |~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:op_asgn,
+        s(:send, s(:lvar, :foo), :a), :+,
+        s(:int, 1)),
+      %q{foo::a += 1})
+
+    assert_parses(
+      s(:op_asgn,
+        s(:send, s(:lvar, :foo), :A), :+,
+        s(:int, 1)),
+      %q{foo.A += 1})
+  end
+
+  def test_op_asgn_cmd
+    assert_parses(
+      s(:op_asgn,
+        s(:send, s(:lvar, :foo), :a), :+,
+        s(:send, nil, :m, s(:lvar, :foo))),
+      %q{foo.a += m foo})
+
+    assert_parses(
+      s(:op_asgn,
+        s(:send, s(:lvar, :foo), :a), :+,
+        s(:send, nil, :m, s(:lvar, :foo))),
+      %q{foo::a += m foo})
+
+    assert_parses(
+      s(:op_asgn,
+        s(:send, s(:lvar, :foo), :A), :+,
+        s(:send, nil, :m, s(:lvar, :foo))),
+      %q{foo.A += m foo})
+
+    assert_parses(
+      s(:op_asgn,
+        s(:send, s(:lvar, :foo), :A), :+,
+        s(:send, nil, :m, s(:lvar, :foo))),
+      %q{foo::A += m foo},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_op_asgn_index
+    assert_parses(
+      s(:op_asgn,
+        s(:send, s(:lvar, :foo), :[],
+          s(:int, 0), s(:int, 1)), :+,
+        s(:int, 2)),
+      %q{foo[0, 1] += 2},
+      %q{          ^^ operator
+        |   ~~~~~~ selector (send)
+        |~~~~~~~~~ expression (send)
+        |~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_op_asgn_index_cmd
+    assert_parses(
+      s(:op_asgn,
+        s(:send, s(:lvar, :foo), :[],
+          s(:int, 0), s(:int, 1)), :+,
+        s(:send, nil, :m, s(:lvar, :foo))),
+      %q{foo[0, 1] += m foo})
+  end
+
+  def test_op_asgn_invalid
+    assert_diagnoses(
+      [:error, :backref_assignment],
+      %q{$1 |= 1},
+      %q{~~ location})
+
+    assert_diagnoses(
+      [:error, :backref_assignment],
+      %q{$+ |= 1},
+      %q{~~ location})
+
+    assert_diagnoses(
+      [:error, :backref_assignment],
+      %q{$+ |= m foo},
+      %q{~~ location})
+  end
+
+  # Variable logical operator-assignment
+
+  def test_var_or_asgn
+    assert_parses(
+      s(:or_asgn, s(:lvasgn, :a), s(:int, 1)),
+      %q{a ||= 1},
+      %q{  ^^^ operator
+        |~~~~~~~ expression})
+  end
+
+  def test_var_and_asgn
+    assert_parses(
+      s(:and_asgn, s(:lvasgn, :a), s(:int, 1)),
+      %q{a &&= 1},
+      %q{  ^^^ operator
+        |~~~~~~~ expression})
+  end
+
+  # Method logical operator-assignment
+
+  def test_or_asgn
+    assert_parses(
+      s(:or_asgn,
+        s(:send, s(:lvar, :foo), :a),
+        s(:int, 1)),
+      %q{foo.a ||= 1},
+      %q{      ^^^ operator
+        |    ~ selector (send)
+        |~~~~~ expression (send)
+        |~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:or_asgn,
+        s(:send, s(:lvar, :foo), :[],
+          s(:int, 0), s(:int, 1)),
+        s(:int, 2)),
+      %q{foo[0, 1] ||= 2},
+      %q{          ^^^ operator
+        |   ~~~~~~ selector (send)
+        |~~~~~~~~~ expression (send)
+        |~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_and_asgn
+    assert_parses(
+      s(:and_asgn,
+        s(:send, s(:lvar, :foo), :a),
+        s(:int, 1)),
+      %q{foo.a &&= 1},
+      %q{      ^^^ operator
+        |    ~ selector (send)
+        |~~~~~ expression (send)
+        |~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:and_asgn,
+        s(:send, s(:lvar, :foo), :[],
+          s(:int, 0), s(:int, 1)),
+        s(:int, 2)),
+      %q{foo[0, 1] &&= 2},
+      %q{          ^^^ operator
+        |   ~~~~~~ selector (send)
+        |~~~~~~~~~ expression (send)
+        |~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_log_asgn_invalid
+    assert_diagnoses(
+      [:error, :backref_assignment],
+      %q{$1 &&= 1},
+      %q{~~ location})
+
+    assert_diagnoses(
+      [:error, :backref_assignment],
+      %q{$+ ||= 1},
+      %q{~~ location})
+  end
+
+
+  #
+  # Class and module definitions
+  #
+
+  def test_module
+    assert_parses(
+      s(:module,
+        s(:const, nil, :Foo),
+        nil),
+      %q{module Foo; end},
+      %q{~~~~~~ keyword
+        |       ~~~ name
+        |            ~~~ end})
+  end
+
+  def test_module_invalid
+    assert_diagnoses(
+      [:error, :module_in_def],
+      %q{def a; module Foo; end; end},
+      %q{       ^^^^^^ location})
+  end
+
+  def test_cpath
+    assert_parses(
+      s(:module,
+        s(:const, s(:cbase), :Foo),
+        nil),
+      %q{module ::Foo; end})
+
+    assert_parses(
+      s(:module,
+        s(:const, s(:const, nil, :Bar), :Foo),
+        nil),
+      %q{module Bar::Foo; end})
+  end
+
+  def test_cpath_invalid
+    assert_diagnoses(
+      [:error, :module_name_const],
+      %q{module foo; end})
+  end
+
+  def test_class
+    assert_parses(
+      s(:class,
+        s(:const, nil, :Foo),
+        nil,
+        nil),
+      %q{class Foo; end},
+      %q{~~~~~ keyword
+        |      ~~~ name
+        |           ~~~ end})
+  end
+
+  def test_class_super
+    assert_parses(
+      s(:class,
+        s(:const, nil, :Foo),
+        s(:const, nil, :Bar),
+        nil),
+      %q{class Foo < Bar; end},
+      %q{~~~~~ keyword
+        |          ^ operator
+        |                 ~~~ end})
+  end
+
+  def test_class_super_label
+    assert_parses(
+      s(:class,
+        s(:const, nil, :Foo),
+        s(:send, nil, :a,
+          s(:sym, :b)),
+        nil),
+      %q{class Foo < a:b; end},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  def test_class_invalid
+    assert_diagnoses(
+      [:error, :class_in_def],
+      %q{def a; class Foo; end; end},
+      %q{       ^^^^^ location})
+  end
+
+  def test_sclass
+    assert_parses(
+      s(:sclass,
+        s(:lvar, :foo),
+        s(:nil)),
+      %q{class << foo; nil; end},
+      %q{~~~~~ keyword
+        |      ^^ operator
+        |                   ~~~ end})
+  end
+
+  #
+  # Method (un)definition
+  #
+
+  def test_def
+    assert_parses(
+      s(:def, :foo, s(:args), nil),
+      %q{def foo; end},
+      %q{~~~ keyword
+        |    ~~~ name
+        |         ~~~ end})
+
+    assert_parses(
+      s(:def, :String, s(:args), nil),
+      %q{def String; end})
+
+    assert_parses(
+      s(:def, :String=, s(:args), nil),
+      %q{def String=; end})
+
+    assert_parses(
+      s(:def, :until, s(:args), nil),
+      %q{def until; end})
+  end
+
+  def test_defs
+    assert_parses(
+      s(:defs, s(:self), :foo, s(:args), nil),
+      %q{def self.foo; end},
+      %q{~~~ keyword
+        |        ^ operator
+        |         ~~~ name
+        |              ~~~ end})
+
+    assert_parses(
+      s(:defs, s(:self), :foo, s(:args), nil),
+      %q{def self::foo; end},
+      %q{~~~ keyword
+        |        ^^ operator
+        |          ~~~ name
+        |               ~~~ end})
+
+    assert_parses(
+      s(:defs, s(:lvar, :foo), :foo, s(:args), nil),
+      %q{def (foo).foo; end})
+
+    assert_parses(
+      s(:defs, s(:const, nil, :String), :foo,
+        s(:args), nil),
+      %q{def String.foo; end})
+
+    assert_parses(
+      s(:defs, s(:const, nil, :String), :foo,
+        s(:args), nil),
+      %q{def String::foo; end})
+  end
+
+  def test_defs_invalid
+    assert_diagnoses(
+      [:error, :singleton_literal],
+      %q{def (1).foo; end},
+      %q{     ~ location})
+
+    assert_diagnoses(
+      [:error, :singleton_literal],
+      %q{def ("foo").foo; end},
+      %q{     ~~~~~ location})
+
+    assert_diagnoses(
+      [:error, :singleton_literal],
+      %q{def ("foo#{bar}").foo; end},
+      %q{     ~~~~~~~~~~~ location})
+
+    assert_diagnoses(
+      [:error, :singleton_literal],
+      %q{def (:foo).foo; end},
+      %q{     ~~~~ location})
+
+    assert_diagnoses(
+      [:error, :singleton_literal],
+      %q{def (:"foo#{bar}").foo; end},
+      %q{     ~~~~~~~~~~~~ location})
+
+    assert_diagnoses(
+      [:error, :singleton_literal],
+      %q{def ([]).foo; end},
+      %q{     ~~ location})
+
+    assert_diagnoses(
+      [:error, :singleton_literal],
+      %q{def ({}).foo; end},
+      %q{     ~~ location})
+
+    assert_diagnoses(
+      [:error, :singleton_literal],
+      %q{def (/foo/).foo; end},
+      %q{     ~~~~~ location})
+  end
+
+  def test_undef
+    assert_parses(
+      s(:undef,
+        s(:sym, :foo),
+        s(:sym, :bar),
+        s(:dsym, s(:str, 'foo'), s(:begin, s(:int, 1)))),
+      %q{undef foo, :bar, :"foo#{1}"},
+      %q{~~~~~ keyword
+        |      ~~~ expression (sym/1)
+        |           ~~~~ expression (sym/2)
+        |~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression})
+  end
+
+  #
+  # Aliasing
+  #
+
+  def test_alias
+    assert_parses(
+      s(:alias, s(:sym, :foo), s(:sym, :bar)),
+      %q{alias :foo bar},
+      %q{~~~~~ keyword
+        |      ~~~~ expression (sym/1)
+        |           ~~~ expression (sym/2)
+        |~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_alias_gvar
+    assert_parses(
+      s(:alias, s(:gvar, :$a), s(:gvar, :$b)),
+      %q{alias $a $b},
+      %q{      ~~ expression (gvar/1)})
+
+    assert_parses(
+      s(:alias, s(:gvar, :$a), s(:back_ref, :$+)),
+      %q{alias $a $+},
+      %q{         ~~ expression (back_ref)})
+  end
+
+  def test_alias_nth_ref
+    assert_diagnoses(
+      [:error, :nth_ref_alias],
+      %q{alias $a $1},
+      %q{         ~~ location})
+  end
+
+  #
+  # Formal arguments
+  #
+
+  def test_arg
+    assert_parses(
+      s(:def, :f,
+        s(:args, s(:arg, :foo)),
+        nil),
+      %q{def f(foo); end},
+      %q{      ~~~ name (args.arg)
+        |      ~~~ expression (args.arg)
+        |     ^ begin (args)
+        |         ^ end (args)
+        |     ~~~~~ expression (args)})
+
+    assert_parses(
+      s(:def, :f,
+        s(:args, s(:arg, :foo), s(:arg, :bar)),
+        nil),
+      %q{def f(foo, bar); end})
+  end
+
+  def test_optarg
+    assert_parses(
+      s(:def, :f,
+        s(:args, s(:optarg, :foo, s(:int, 1))),
+        nil),
+      %q{def f foo = 1; end},
+      %q{      ~~~ name (args.optarg)
+        |          ^ operator (args.optarg)
+        |      ~~~~~~~ expression (args.optarg)
+        |      ~~~~~~~ expression (args)})
+
+    assert_parses(
+      s(:def, :f,
+        s(:args,
+          s(:optarg, :foo, s(:int, 1)),
+          s(:optarg, :bar, s(:int, 2))),
+        nil),
+      %q{def f(foo=1, bar=2); end})
+  end
+
+  def test_restarg_named
+    assert_parses(
+      s(:def, :f,
+        s(:args, s(:restarg, :foo)),
+        nil),
+      %q{def f(*foo); end},
+      %q{       ~~~ name (args.restarg)
+        |      ~~~~ expression (args.restarg)})
+  end
+
+  def test_restarg_unnamed
+    assert_parses(
+      s(:def, :f,
+        s(:args, s(:restarg)),
+        nil),
+      %q{def f(*); end},
+      %q{      ~ expression (args.restarg)})
+  end
+
+  def test_kwarg
+    assert_parses(
+      s(:def, :f,
+        s(:args, s(:kwarg, :foo)),
+        nil),
+      %q{def f(foo:); end},
+      %q{      ~~~ name (args.kwarg)
+        |      ~~~~ expression (args.kwarg)},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+  end
+
+  def test_kwoptarg
+    assert_parses(
+      s(:def, :f,
+        s(:args, s(:kwoptarg, :foo, s(:int, 1))),
+        nil),
+      %q{def f(foo: 1); end},
+      %q{      ~~~ name (args.kwoptarg)
+        |      ~~~~~~ expression (args.kwoptarg)},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  def test_kwrestarg_named
+    assert_parses(
+      s(:def, :f,
+        s(:args, s(:kwrestarg, :foo)),
+        nil),
+      %q{def f(**foo); end},
+      %q{        ~~~ name (args.kwrestarg)
+        |      ~~~~~ expression (args.kwrestarg)},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  def test_kwrestarg_unnamed
+    assert_parses(
+      s(:def, :f,
+        s(:args, s(:kwrestarg)),
+        nil),
+      %q{def f(**); end},
+      %q{      ~~ expression (args.kwrestarg)},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  def test_blockarg
+    assert_parses(
+      s(:def, :f,
+        s(:args, s(:blockarg, :block)),
+        nil),
+      %q{def f(&block); end},
+      %q{       ~~~~~ name (args.blockarg)
+        |      ~~~~~~ expression (args.blockarg)})
+  end
+
+  def test_arg_scope
+    # [ruby-core:61299] [Bug #9593]
+    assert_parses(
+      s(:def, :f,
+        s(:args, s(:optarg, :var, s(:defined?, s(:lvar, :var)))),
+        s(:lvar, :var)),
+      %q{def f(var = defined?(var)) var end},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+
+    assert_parses(
+      s(:def, :f,
+        s(:args, s(:kwoptarg, :var, s(:defined?, s(:lvar, :var)))),
+        s(:lvar, :var)),
+      %q{def f(var: defined?(var)) var end},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+  end
+
+  def assert_parses_args(ast, code, versions=ALL_VERSIONS)
+    assert_parses(
+      s(:def, :f, ast, nil),
+      %Q{def f #{code}; end},
+      %q{},
+      versions)
+  end
+
+  def test_arg_combinations
+    # f_arg tCOMMA f_optarg tCOMMA f_rest_arg              opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:arg, :a),
+        s(:optarg, :o, s(:int, 1)),
+        s(:restarg, :r),
+        s(:blockarg, :b)),
+      %q{a, o=1, *r, &b})
+
+    # f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:arg, :a),
+        s(:optarg, :o, s(:int, 1)),
+        s(:restarg, :r),
+        s(:arg, :p),
+        s(:blockarg, :b)),
+      %q{a, o=1, *r, p, &b},
+      ALL_VERSIONS - %w(1.8))
+
+    # f_arg tCOMMA f_optarg                                opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:arg, :a),
+        s(:optarg, :o, s(:int, 1)),
+        s(:blockarg, :b)),
+      %q{a, o=1, &b})
+
+    # f_arg tCOMMA f_optarg tCOMMA                   f_arg opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:arg, :a),
+        s(:optarg, :o, s(:int, 1)),
+        s(:arg, :p),
+        s(:blockarg, :b)),
+      %q{a, o=1, p, &b},
+      ALL_VERSIONS - %w(1.8))
+
+    # f_arg tCOMMA                 f_rest_arg              opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:arg, :a),
+        s(:restarg, :r),
+        s(:blockarg, :b)),
+      %q{a, *r, &b})
+
+    # f_arg tCOMMA                 f_rest_arg tCOMMA f_arg opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:arg, :a),
+        s(:restarg, :r),
+        s(:arg, :p),
+        s(:blockarg, :b)),
+      %q{a, *r, p, &b},
+      ALL_VERSIONS - %w(1.8))
+
+    # f_arg                                                opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:arg, :a),
+        s(:blockarg, :b)),
+      %q{a, &b})
+
+    #              f_optarg tCOMMA f_rest_arg              opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:optarg, :o, s(:int, 1)),
+        s(:restarg, :r),
+        s(:blockarg, :b)),
+      %q{o=1, *r, &b})
+
+    #              f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:optarg, :o, s(:int, 1)),
+        s(:restarg, :r),
+        s(:arg, :p),
+        s(:blockarg, :b)),
+      %q{o=1, *r, p, &b},
+      ALL_VERSIONS - %w(1.8))
+
+    #              f_optarg                                opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:optarg, :o, s(:int, 1)),
+        s(:blockarg, :b)),
+      %q{o=1, &b})
+
+    #              f_optarg tCOMMA                   f_arg opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:optarg, :o, s(:int, 1)),
+        s(:arg, :p),
+        s(:blockarg, :b)),
+      %q{o=1, p, &b},
+      ALL_VERSIONS - %w(1.8))
+
+    #                              f_rest_arg              opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:restarg, :r),
+        s(:blockarg, :b)),
+      %q{*r, &b})
+
+    #                              f_rest_arg tCOMMA f_arg opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:restarg, :r),
+        s(:arg, :p),
+        s(:blockarg, :b)),
+      %q{*r, p, &b},
+      ALL_VERSIONS - %w(1.8))
+
+    #                                                          f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:blockarg, :b)),
+      %q{&b})
+
+    # (nothing)
+    assert_parses_args(
+      s(:args),
+      %q{})
+  end
+
+  def test_kwarg_combinations
+    # f_kwarg tCOMMA f_kwrest opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:kwoptarg, :foo, s(:int, 1)),
+        s(:kwoptarg, :bar, s(:int, 2)),
+        s(:kwrestarg, :baz),
+        s(:blockarg, :b)),
+      %q{(foo: 1, bar: 2, **baz, &b)},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    # f_kwarg opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:kwoptarg, :foo, s(:int, 1)),
+        s(:blockarg, :b)),
+      %q{(foo: 1, &b)},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    # f_kwrest opt_f_block_arg
+    assert_parses_args(
+      s(:args,
+        s(:kwrestarg, :baz),
+        s(:blockarg, :b)),
+      %q{**baz, &b},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    assert_parses_args(
+      s(:args,
+        s(:restarg),
+        s(:kwrestarg)),
+      %q{*, **},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  def test_kwarg_no_paren
+    assert_parses_args(
+      s(:args,
+        s(:kwarg, :foo)),
+      %Q{foo:\n},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+
+    assert_parses_args(
+      s(:args,
+        s(:kwoptarg, :foo, s(:int, -1))),
+      %Q{foo: -1\n},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+  end
+
+  def assert_parses_margs(ast, code, versions=ALL_VERSIONS - %w(1.8))
+    assert_parses_args(
+      s(:args, ast),
+      %Q{(#{code})},
+      versions)
+  end
+
+  def test_marg_combinations
+    # tLPAREN f_margs rparen
+    assert_parses_margs(
+      s(:mlhs,
+        s(:mlhs, s(:arg, :a))),
+      %q{((a))})
+
+    # f_marg_list
+    assert_parses_margs(
+      s(:mlhs, s(:arg, :a), s(:arg, :a1)),
+      %q{(a, a1)})
+
+    # f_marg_list tCOMMA tSTAR f_norm_arg
+    assert_parses_margs(
+      s(:mlhs, s(:arg, :a), s(:restarg, :r)),
+      %q{(a, *r)})
+
+    # f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
+    assert_parses_margs(
+      s(:mlhs, s(:arg, :a), s(:restarg, :r), s(:arg, :p)),
+      %q{(a, *r, p)})
+
+    # f_marg_list tCOMMA tSTAR
+    assert_parses_margs(
+      s(:mlhs, s(:arg, :a), s(:restarg)),
+      %q{(a, *)})
+
+    # f_marg_list tCOMMA tSTAR            tCOMMA f_marg_list
+    assert_parses_margs(
+      s(:mlhs, s(:arg, :a), s(:restarg), s(:arg, :p)),
+      %q{(a, *, p)})
+
+    # tSTAR f_norm_arg
+    assert_parses_margs(
+      s(:mlhs, s(:restarg, :r)),
+      %q{(*r)})
+
+    # tSTAR f_norm_arg tCOMMA f_marg_list
+    assert_parses_margs(
+      s(:mlhs, s(:restarg, :r), s(:arg, :p)),
+      %q{(*r, p)})
+
+    # tSTAR
+    assert_parses_margs(
+      s(:mlhs, s(:restarg)),
+      %q{(*)})
+
+    # tSTAR tCOMMA f_marg_list
+    assert_parses_margs(
+      s(:mlhs, s(:restarg), s(:arg, :p)),
+      %q{(*, p)})
+  end
+
+  def assert_parses_blockargs(ast, code, versions=ALL_VERSIONS)
+    assert_parses(
+      s(:block,
+        s(:send, nil, :f),
+        ast, nil),
+      %Q{f{ #{code} }},
+      %q{},
+      versions)
+  end
+
+  def test_block_arg_combinations
+    # none
+    assert_parses_blockargs(
+      s(:args),
+      %q{})
+
+    # tPIPE tPIPE
+    # tPIPE opt_bv_decl tPIPE
+    assert_parses_blockargs(
+      s(:args),
+      %q{| |})
+
+    assert_parses_blockargs(
+      s(:args, s(:shadowarg, :a)),
+      %q{|;a|},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses_blockargs(
+      s(:args, s(:shadowarg, :a)),
+      %Q{|;\na\n|},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    # tOROP
+    assert_parses_blockargs(
+      s(:args),
+      %q{||})
+
+    # block_par
+    # block_par tCOMMA
+    # block_par tCOMMA tAMPER lhs
+    # f_arg                                                      opt_f_block_arg
+    # f_arg tCOMMA
+    assert_parses_blockargs(
+      s(:args, s(:arg, :a)),
+      %q{|a|})
+
+    assert_parses_blockargs(
+      s(:args, s(:arg, :a), s(:arg, :c)),
+      %q{|a, c|})
+
+    assert_parses_blockargs(
+      s(:args, s(:arg_expr, s(:ivasgn, :@a))),
+      %q{|@a|},
+      %w(1.8))
+
+    assert_parses_blockargs(
+      s(:args, s(:arg, :a)),
+      %q{|a,|})
+
+    assert_parses_blockargs(
+      s(:args, s(:arg, :a), s(:blockarg, :b)),
+      %q{|a, &b|})
+
+    assert_parses_blockargs(
+      s(:args, s(:arg, :a), s(:blockarg_expr, s(:ivasgn, :@b))),
+      %q{|a, &@b|},
+      %w(1.8))
+
+    # block_par tCOMMA tSTAR lhs tCOMMA tAMPER lhs
+    # block_par tCOMMA tSTAR tCOMMA tAMPER lhs
+    # block_par tCOMMA tSTAR lhs
+    # block_par tCOMMA tSTAR
+    # f_arg tCOMMA                       f_rest_arg              opt_f_block_arg
+    assert_parses_blockargs(
+      s(:args, s(:arg, :a), s(:restarg, :s), s(:blockarg, :b)),
+      %q{|a, *s, &b|})
+
+    assert_parses_blockargs(
+      s(:args, s(:arg, :a),
+        s(:restarg_expr, s(:ivasgn, :@s)),
+        s(:blockarg_expr, s(:ivasgn, :@b))),
+      %q{|a, *@s, &@b|},
+      %w(1.8))
+
+    assert_parses_blockargs(
+      s(:args, s(:arg, :a), s(:restarg), s(:blockarg, :b)),
+      %q{|a, *, &b|})
+
+    assert_parses_blockargs(
+      s(:args, s(:arg, :a),
+        s(:restarg),
+        s(:blockarg_expr, s(:ivasgn, :@b))),
+      %q{|a, *, &@b|},
+      %w(1.8))
+
+    assert_parses_blockargs(
+      s(:args, s(:arg, :a), s(:restarg, :s)),
+      %q{|a, *s|})
+
+    assert_parses_blockargs(
+      s(:args, s(:arg, :a),
+        s(:restarg_expr, s(:ivasgn, :@s))),
+      %q{|a, *@s|},
+      %w(1.8))
+
+    assert_parses_blockargs(
+      s(:args, s(:arg, :a), s(:restarg)),
+      %q{|a, *|})
+
+    # tSTAR lhs tCOMMA tAMPER lhs
+    # tSTAR lhs
+    # tSTAR
+    # tSTAR tCOMMA tAMPER lhs
+    #                                    f_rest_arg              opt_f_block_arg
+    assert_parses_blockargs(
+      s(:args, s(:restarg, :s), s(:blockarg, :b)),
+      %q{|*s, &b|})
+
+    assert_parses_blockargs(
+      s(:args,
+        s(:restarg_expr, s(:ivasgn, :@s)),
+        s(:blockarg_expr, s(:ivasgn, :@b))),
+      %q{|*@s, &@b|},
+      %w(1.8))
+
+    assert_parses_blockargs(
+      s(:args, s(:restarg), s(:blockarg, :b)),
+      %q{|*, &b|})
+
+    assert_parses_blockargs(
+      s(:args,
+        s(:restarg),
+        s(:blockarg_expr, s(:ivasgn, :@b))),
+      %q{|*, &@b|},
+      %w(1.8))
+
+    assert_parses_blockargs(
+      s(:args, s(:restarg, :s)),
+      %q{|*s|})
+
+    assert_parses_blockargs(
+      s(:args,
+        s(:restarg_expr, s(:ivasgn, :@s))),
+      %q{|*@s|},
+      %w(1.8))
+
+    assert_parses_blockargs(
+      s(:args, s(:restarg)),
+      %q{|*|})
+
+    # tAMPER lhs
+    #                                                                f_block_arg
+    assert_parses_blockargs(
+      s(:args, s(:blockarg, :b)),
+      %q{|&b|})
+
+    assert_parses_blockargs(
+      s(:args,
+        s(:blockarg_expr, s(:ivasgn, :@b))),
+      %q{|&@b|},
+      %w(1.8))
+
+    # f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg              opt_f_block_arg
+    assert_parses_blockargs(
+      s(:args,
+        s(:arg, :a),
+        s(:optarg, :o, s(:int, 1)),
+        s(:optarg, :o1, s(:int, 2)),
+        s(:restarg, :r),
+        s(:blockarg, :b)),
+      %q{|a, o=1, o1=2, *r, &b|},
+      ALL_VERSIONS - %w(1.8))
+
+    # f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
+    assert_parses_blockargs(
+      s(:args,
+        s(:arg, :a),
+        s(:optarg, :o, s(:int, 1)),
+        s(:restarg, :r),
+        s(:arg, :p),
+        s(:blockarg, :b)),
+      %q{|a, o=1, *r, p, &b|},
+      ALL_VERSIONS - %w(1.8))
+
+    # f_arg tCOMMA f_block_optarg                                opt_f_block_arg
+    assert_parses_blockargs(
+      s(:args,
+        s(:arg, :a),
+        s(:optarg, :o, s(:int, 1)),
+        s(:blockarg, :b)),
+      %q{|a, o=1, &b|},
+      ALL_VERSIONS - %w(1.8))
+
+    # f_arg tCOMMA f_block_optarg tCOMMA                   f_arg opt_f_block_arg
+    assert_parses_blockargs(
+      s(:args,
+        s(:arg, :a),
+        s(:optarg, :o, s(:int, 1)),
+        s(:arg, :p),
+        s(:blockarg, :b)),
+      %q{|a, o=1, p, &b|},
+      ALL_VERSIONS - %w(1.8))
+
+    # f_arg tCOMMA                       f_rest_arg tCOMMA f_arg opt_f_block_arg
+    assert_parses_blockargs(
+      s(:args,
+        s(:arg, :a),
+        s(:restarg, :r),
+        s(:arg, :p),
+        s(:blockarg, :b)),
+      %q{|a, *r, p, &b|},
+      ALL_VERSIONS - %w(1.8))
+
+    #              f_block_optarg tCOMMA f_rest_arg              opt_f_block_arg
+    assert_parses_blockargs(
+      s(:args,
+        s(:optarg, :o, s(:int, 1)),
+        s(:restarg, :r),
+        s(:blockarg, :b)),
+      %q{|o=1, *r, &b|},
+      ALL_VERSIONS - %w(1.8))
+
+    #              f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
+    assert_parses_blockargs(
+      s(:args,
+        s(:optarg, :o, s(:int, 1)),
+        s(:restarg, :r),
+        s(:arg, :p),
+        s(:blockarg, :b)),
+      %q{|o=1, *r, p, &b|},
+      ALL_VERSIONS - %w(1.8))
+
+    #              f_block_optarg                                opt_f_block_arg
+    assert_parses_blockargs(
+      s(:args,
+        s(:optarg, :o, s(:int, 1)),
+        s(:blockarg, :b)),
+      %q{|o=1, &b|},
+      ALL_VERSIONS - %w(1.8))
+
+    #              f_block_optarg tCOMMA                   f_arg opt_f_block_arg
+    assert_parses_blockargs(
+      s(:args,
+        s(:optarg, :o, s(:int, 1)),
+        s(:arg, :p),
+        s(:blockarg, :b)),
+      %q{|o=1, p, &b|},
+      ALL_VERSIONS - %w(1.8))
+
+    #                                    f_rest_arg tCOMMA f_arg opt_f_block_arg
+    assert_parses_blockargs(
+      s(:args,
+        s(:restarg, :r),
+        s(:arg, :p),
+        s(:blockarg, :b)),
+      %q{|*r, p, &b|},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_block_kwarg_combinations
+    # f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
+    assert_parses_blockargs(
+      s(:args,
+        s(:kwoptarg, :foo, s(:int, 1)),
+        s(:kwoptarg, :bar, s(:int, 2)),
+        s(:kwrestarg, :baz),
+        s(:blockarg, :b)),
+      %q{|foo: 1, bar: 2, **baz, &b|},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    # f_block_kwarg opt_f_block_arg
+    assert_parses_blockargs(
+      s(:args,
+        s(:kwoptarg, :foo, s(:int, 1)),
+        s(:blockarg, :b)),
+      %q{|foo: 1, &b|},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    # f_kwrest opt_f_block_arg
+    assert_parses_blockargs(
+      s(:args,
+        s(:kwrestarg, :baz),
+        s(:blockarg, :b)),
+      %q{|**baz, &b|},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  def test_block_kwarg
+    assert_parses_blockargs(
+      s(:args,
+        s(:kwarg, :foo)),
+      %q{|foo:|},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+  end
+
+  def test_arg_invalid
+    assert_diagnoses(
+      [:error, :argument_const],
+      %q{def foo(Abc); end},
+      %q{        ~~~ location})
+
+    assert_diagnoses(
+      [:error, :argument_ivar],
+      %q{def foo(@abc); end},
+      %q{        ~~~~ location})
+
+    assert_diagnoses(
+      [:error, :argument_gvar],
+      %q{def foo($abc); end},
+      %q{        ~~~~ location})
+
+    assert_diagnoses(
+      [:error, :argument_cvar],
+      %q{def foo(@@abc); end},
+      %q{        ~~~~~ location})
+  end
+
+  def test_arg_duplicate
+    assert_diagnoses(
+      [:error, :duplicate_argument],
+      %q{def foo(aa, aa); end},
+      %q{            ^^ location
+        |        ~~ highlights (0)})
+
+    assert_diagnoses(
+      [:error, :duplicate_argument],
+      %q{def foo(aa, aa=1); end},
+      %q{            ^^ location
+        |        ~~ highlights (0)})
+
+    assert_diagnoses(
+      [:error, :duplicate_argument],
+      %q{def foo(aa, *aa); end},
+      %q{             ^^ location
+        |        ~~ highlights (0)})
+
+    assert_diagnoses(
+      [:error, :duplicate_argument],
+      %q{def foo(aa, &aa); end},
+      %q{             ^^ location
+        |        ~~ highlights (0)})
+
+    assert_diagnoses(
+      [:error, :duplicate_argument],
+      %q{def foo(aa, (bb, aa)); end},
+      %q{                 ^^ location
+        |        ~~ highlights (0)},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_diagnoses(
+      [:error, :duplicate_argument],
+      %q{def foo(aa, *r, aa); end},
+      %q{                ^^ location
+        |        ~~ highlights (0)},
+      ALL_VERSIONS - %w(1.8))
+
+
+    assert_diagnoses(
+      [:error, :duplicate_argument],
+      %q{lambda do |aa; aa| end},
+      %q{               ^^ location
+        |           ~~ highlights (0)},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_diagnoses(
+      [:error, :duplicate_argument],
+      %q{def foo(aa, aa: 1); end},
+      %q{            ^^ location
+        |        ~~ highlights (0)},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    assert_diagnoses(
+      [:error, :duplicate_argument],
+      %q{def foo(aa, **aa); end},
+      %q{              ^^ location
+        |        ~~ highlights (0)},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    assert_diagnoses(
+      [:error, :duplicate_argument],
+      %q{def foo(aa, aa:); end},
+      %q{            ^^ location
+        |        ~~ highlights (0)},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+  end
+
+  def test_arg_duplicate_ignored
+    assert_diagnoses(
+      [:error, :duplicate_argument],
+      %q{def foo(_, _); end},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:def, :foo,
+        s(:args, s(:arg, :_), s(:arg, :_)),
+        nil),
+      %q{def foo(_, _); end},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_diagnoses(
+      [:error, :duplicate_argument],
+      %q{def foo(_a, _a); end},
+      %q{},
+      %w(1.8 1.9))
+
+    assert_parses(
+      s(:def, :foo,
+        s(:args, s(:arg, :_a), s(:arg, :_a)),
+        nil),
+      %q{def foo(_a, _a); end},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  def test_arg_duplicate_proc
+    assert_parses(
+      s(:block, s(:send, nil, :proc),
+        s(:args, s(:arg, :a), s(:arg, :a)),
+        nil),
+      %q{proc{|a,a|}},
+      %q{},
+      %w(1.8))
+
+    assert_diagnoses(
+      [:error, :duplicate_argument],
+      %q{proc{|a,a|}},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_kwarg_invalid
+    assert_diagnoses(
+      [:error, :argument_const],
+      %q{def foo(Abc: 1); end},
+      %q{        ~~~~ location},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    assert_diagnoses(
+      [:error, :argument_const],
+      %q{def foo(Abc:); end},
+      %q{        ~~~~ location},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+  end
+
+  def test_arg_label
+    assert_parses(
+      s(:def, :foo, s(:args),
+        s(:send, nil, :a, s(:sym, :b))),
+      %q{def foo() a:b end},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:def, :foo, s(:args),
+        s(:send, nil, :a, s(:sym, :b))),
+      %Q{def foo\n a:b end},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:block,
+        s(:send, nil, :f),
+        s(:args),
+        s(:send, nil, :a,
+          s(:sym, :b))),
+      %Q{f { || a:b }},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  #
+  # Sends
+  #
+
+  # To self
+
+  def test_send_self
+    assert_parses(
+      s(:send, nil, :fun),
+      %q{fun},
+      %q{~~~ selector
+        |~~~ expression})
+
+    assert_parses(
+      s(:send, nil, :fun!),
+      %q{fun!},
+      %q{~~~~ selector
+        |~~~~ expression})
+
+    assert_parses(
+      s(:send, nil, :fun, s(:int, 1)),
+      %q{fun(1)},
+      %q{~~~ selector
+        |   ^ begin
+        |     ^ end
+        |~~~~~~ expression})
+  end
+
+  def test_send_self_block
+    assert_parses(
+      s(:block, s(:send, nil, :fun), s(:args), nil),
+      %q{fun { }})
+
+    assert_parses(
+      s(:block, s(:send, nil, :fun), s(:args), nil),
+      %q{fun() { }})
+
+    assert_parses(
+      s(:block, s(:send, nil, :fun, s(:int, 1)), s(:args), nil),
+      %q{fun(1) { }})
+
+    assert_parses(
+      s(:block, s(:send, nil, :fun), s(:args), nil),
+      %q{fun do end})
+  end
+
+  def test_send_block_blockarg
+    assert_diagnoses(
+      [:error, :block_and_blockarg],
+      %q{fun(&bar) do end},
+      %q{    ~~~~ location
+        |          ~~ highlights (0)})
+  end
+
+  # To receiver
+
+  def test_send_plain
+    assert_parses(
+      s(:send, s(:lvar, :foo), :fun),
+      %q{foo.fun},
+      %q{    ~~~ selector
+        |   ^ dot
+        |~~~~~~~ expression})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :fun),
+      %q{foo::fun},
+      %q{     ~~~ selector
+        |   ^^ dot
+        |~~~~~~~~ expression})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :Fun),
+      %q{foo::Fun()},
+      %q{     ~~~ selector
+        |   ^^ dot
+        |~~~~~~~~~~ expression})
+  end
+
+  def test_send_plain_cmd
+    assert_parses(
+      s(:send, s(:lvar, :foo), :fun, s(:lvar, :bar)),
+      %q{foo.fun bar},
+      %q{    ~~~ selector
+        |   ^ dot
+        |~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :fun, s(:lvar, :bar)),
+      %q{foo::fun bar},
+      %q{     ~~~ selector
+        |   ^^ dot
+        |~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :Fun, s(:lvar, :bar)),
+      %q{foo::Fun bar},
+      %q{     ~~~ selector
+        |   ^^ dot
+        |~~~~~~~~~~~~ expression})
+  end
+
+  def test_send_plain_cmd_ambiguous_literal
+    assert_diagnoses(
+      [:warning, :ambiguous_literal],
+      %q{m /foo/},
+      %q{  ^ location})
+
+    refute_diagnoses(
+      %q{m %[1]})
+  end
+
+  def test_send_plain_cmd_ambiguous_prefix
+    assert_diagnoses(
+      [:warning, :ambiguous_prefix, { :prefix => '+' }],
+      %q{m +foo},
+      %q{  ^ location})
+
+    assert_diagnoses(
+      [:warning, :ambiguous_prefix, { :prefix => '-' }],
+      %q{m -foo},
+      %q{  ^ location})
+
+    assert_diagnoses(
+      [:warning, :ambiguous_prefix, { :prefix => '&' }],
+      %q{m &foo},
+      %q{  ^ location})
+
+    assert_diagnoses(
+      [:warning, :ambiguous_prefix, { :prefix => '*' }],
+      %q{m *foo},
+      %q{  ^ location})
+
+    assert_diagnoses(
+      [:warning, :ambiguous_prefix, { :prefix => '**' }],
+      %q{m **foo},
+      %q{  ^^ location},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  def test_send_block_chain_cmd
+    assert_parses(
+      s(:send,
+        s(:block,
+          s(:send, nil, :meth, s(:int, 1)),
+          s(:args), nil),
+        :fun, s(:lvar, :bar)),
+      %q{meth 1 do end.fun bar},
+      %q{              ~~~ selector
+        |             ^ dot
+        |~~~~~~~~~~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:send,
+        s(:block,
+          s(:send, nil, :meth, s(:int, 1)),
+          s(:args), nil),
+        :fun, s(:lvar, :bar)),
+      %q{meth 1 do end.fun(bar)},
+      %q{              ~~~ selector
+        |             ^ dot
+        |                 ^ begin
+        |                     ^ end
+        |~~~~~~~~~~~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:send,
+        s(:block,
+          s(:send, nil, :meth, s(:int, 1)),
+          s(:args), nil),
+        :fun, s(:lvar, :bar)),
+      %q{meth 1 do end::fun bar},
+      %q{               ~~~ selector
+        |             ^^ dot
+        |~~~~~~~~~~~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:send,
+        s(:block,
+          s(:send, nil, :meth, s(:int, 1)),
+          s(:args), nil),
+        :fun, s(:lvar, :bar)),
+      %q{meth 1 do end::fun(bar)},
+      %q{               ~~~ selector
+        |                  ^ begin
+        |                      ^ end
+        |             ^^ dot
+        |~~~~~~~~~~~~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:block,
+        s(:send,
+          s(:block,
+            s(:send, nil, :meth, s(:int, 1)),
+            s(:args), nil),
+          :fun, s(:lvar, :bar)),
+        s(:args), nil),
+      %q{meth 1 do end.fun bar do end},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    assert_parses(
+      s(:block,
+        s(:send,
+          s(:block,
+            s(:send, nil, :meth, s(:int, 1)),
+            s(:args), nil),
+          :fun, s(:lvar, :bar)),
+        s(:args), nil),
+      %q{meth 1 do end.fun(bar) {}},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9))
+
+    assert_parses(
+      s(:block,
+        s(:send,
+          s(:block,
+            s(:send, nil, :meth, s(:int, 1)),
+            s(:args), nil),
+          :fun),
+        s(:args), nil),
+      %q{meth 1 do end.fun {}},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  def test_send_paren_block_cmd
+    assert_parses(
+      s(:send, nil, :foo,
+        s(:block,
+          s(:send, nil, :meth, s(:int, 1)),
+          s(:args), nil)),
+      %q{foo(meth 1 do end)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :foo,
+        s(:int, 1),
+        s(:block,
+          s(:send, nil, :meth, s(:int, 1)),
+          s(:args), nil)),
+      %q{foo(1, meth 1 do end)},
+      %q{},
+      %w(1.8))
+  end
+
+  def test_send_binary_op
+    assert_parses(
+      s(:send, s(:lvar, :foo), :+, s(:int, 1)),
+      %q{foo + 1},
+      %q{    ~ selector
+        |~~~~~~~ expression})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :-, s(:int, 1)),
+      %q{foo - 1})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :*, s(:int, 1)),
+      %q{foo * 1})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :/, s(:int, 1)),
+      %q{foo / 1})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :%, s(:int, 1)),
+      %q{foo % 1})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :**, s(:int, 1)),
+      %q{foo ** 1})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :|, s(:int, 1)),
+      %q{foo | 1})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :^, s(:int, 1)),
+      %q{foo ^ 1})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :&, s(:int, 1)),
+      %q{foo & 1})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :<=>, s(:int, 1)),
+      %q{foo <=> 1})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :<, s(:int, 1)),
+      %q{foo < 1})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :<=, s(:int, 1)),
+      %q{foo <= 1})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :>, s(:int, 1)),
+      %q{foo > 1})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :>=, s(:int, 1)),
+      %q{foo >= 1})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :==, s(:int, 1)),
+      %q{foo == 1})
+
+    assert_parses(
+      s(:not, s(:send, s(:lvar, :foo), :==, s(:int, 1))),
+      %q{foo != 1},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :'!=', s(:int, 1)),
+      %q{foo != 1},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :===, s(:int, 1)),
+      %q{foo === 1})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :=~, s(:int, 1)),
+      %q{foo =~ 1})
+
+    assert_parses(
+      s(:not, s(:send, s(:lvar, :foo), :=~, s(:int, 1))),
+      %q{foo !~ 1},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :'!~', s(:int, 1)),
+      %q{foo !~ 1},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :<<, s(:int, 1)),
+      %q{foo << 1})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :>>, s(:int, 1)),
+      %q{foo >> 1})
+  end
+
+  def test_send_unary_op
+    assert_parses(
+      s(:send, s(:lvar, :foo), :-@),
+      %q{-foo},
+      %q{~ selector
+        |~~~~ expression})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :+@),
+      %q{+foo})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :~),
+      %q{~foo})
+  end
+
+  def test_bang
+    assert_parses(
+      s(:not, s(:lvar, :foo)),
+      %q{!foo},
+      %{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :'!'),
+      %q{!foo},
+      %{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_bang_cmd
+    assert_parses(
+      s(:not, s(:send, nil, :m, s(:lvar, :foo))),
+      %q{!m foo},
+      %{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, s(:send, nil, :m, s(:lvar, :foo)), :'!'),
+      %q{!m foo},
+      %{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_not
+    assert_parses(
+      s(:not, s(:lvar, :foo)),
+      %q{not foo},
+      %{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :'!'),
+      %q{not foo},
+      %{},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :'!'),
+      %q{not(foo)},
+      %q{~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:send, s(:begin), :'!'),
+      %q{not()},
+      %q{~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_not_cmd
+    assert_parses(
+      s(:not, s(:send, nil, :m, s(:lvar, :foo))),
+      %q{not m foo},
+      %{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, s(:send, nil, :m, s(:lvar, :foo)), :'!'),
+      %q{not m foo},
+      %{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_pow_precedence
+    assert_parses(
+      s(:send, s(:send, s(:int, 2), :**, s(:int, 10)), :-@),
+      %q{-2 ** 10})
+
+    assert_parses(
+      s(:send, s(:send, s(:float, 2.0), :**, s(:int, 10)), :-@),
+      %q{-2.0 ** 10})
+  end
+
+  def test_send_attr_asgn
+    assert_parses(
+      s(:send, s(:lvar, :foo), :a=, s(:int, 1)),
+      %q{foo.a = 1},
+      %q{    ~ selector
+        |   ^ dot
+        |      ^ operator
+        |~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :a=, s(:int, 1)),
+      %q{foo::a = 1},
+      %q{     ~ selector
+        |   ^^ dot
+        |       ^ operator
+        |~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :A=, s(:int, 1)),
+      %q{foo.A = 1},
+      %q{    ~ selector
+        |   ^ dot
+        |      ^ operator
+        |~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:casgn, s(:lvar, :foo), :A, s(:int, 1)),
+      %q{foo::A = 1},
+      %q{     ~ name
+        |   ^^ double_colon
+        |       ^ operator
+        |~~~~~~~~~~ expression})
+  end
+
+  def test_send_index
+    assert_parses(
+      s(:send, s(:lvar, :foo), :[],
+        s(:int, 1), s(:int, 2)),
+      %q{foo[1, 2]},
+      %q{   ~~~~~~ selector
+        |~~~~~~~~~ expression})
+  end
+
+  def test_send_index_cmd
+    assert_parses(
+      s(:send, s(:lvar, :foo), :[],
+        s(:send, nil, :m, s(:lvar, :bar))),
+      %q{foo[m bar]})
+  end
+
+  def test_send_index_asgn
+    assert_parses(
+      s(:send, s(:lvar, :foo), :[]=,
+        s(:int, 1), s(:int, 2), s(:int, 3)),
+      %q{foo[1, 2] = 3},
+      %q{   ~~~~~~ selector
+        |          ^ operator
+        |~~~~~~~~~~~~~ expression})
+  end
+
+  def test_send_lambda
+    assert_parses(
+      s(:block, s(:send, nil, :lambda),
+        s(:args), nil),
+      %q{->{ }},
+      %q{~~ selector (send)
+        |  ^ begin
+        |    ^ end
+        |~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:block, s(:send, nil, :lambda),
+        s(:args, s(:restarg)), nil),
+      %q{-> * { }},
+      %q{~~ selector (send)
+        |     ^ begin
+        |       ^ end
+        |   ^ expression (args.restarg)
+        |~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:block, s(:send, nil, :lambda),
+        s(:args), nil),
+      %q{-> do end},
+      %q{~~ selector (send)
+        |   ^^ begin
+        |      ^^^ end
+        |~~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_send_lambda_args
+    assert_parses(
+      s(:block, s(:send, nil, :lambda),
+        s(:args,
+          s(:arg, :a)),
+        nil),
+      %q{->(a) { }},
+      %q{~~ selector (send)
+        |  ^ begin (args)
+        |    ^ end (args)
+        |      ^ begin
+        |        ^ end
+        |~~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:block, s(:send, nil, :lambda),
+        s(:args,
+          s(:arg, :a)),
+        nil),
+      %q{-> (a) { }},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  def test_send_lambda_args_shadow
+    assert_parses(
+      s(:block, s(:send, nil, :lambda),
+        s(:args,
+          s(:arg, :a),
+          s(:shadowarg, :foo),
+          s(:shadowarg, :bar)),
+        nil),
+      %q{->(a; foo, bar) { }},
+      %q{      ~~~ expression (args.shadowarg)},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_send_call
+    assert_parses(
+      s(:send, s(:lvar, :foo), :call,
+        s(:int, 1)),
+      %q{foo.(1)},
+      %q{    ^ begin
+        |      ^ end
+        |   ^ dot
+        |~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:send, s(:lvar, :foo), :call,
+        s(:int, 1)),
+      %q{foo::(1)},
+      %q{     ^ begin
+        |       ^ end
+        |   ^^ dot
+        |~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_lvar_injecting_match
+    assert_parses(
+      s(:begin,
+        s(:match_with_lvasgn,
+          s(:regexp,
+            s(:str, '(?<match>bar)'),
+            s(:regopt)),
+          s(:str, 'bar')),
+        s(:lvar, :match)),
+      %q{/(?<match>bar)/ =~ 'bar'; match},
+      %q{                ~~ selector (match_with_lvasgn)
+        |~~~~~~~~~~~~~~~~~~~~~~~~ expression (match_with_lvasgn)},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_non_lvar_injecting_match
+    assert_parses(
+      s(:send,
+        s(:regexp,
+          s(:begin, s(:int, 1)),
+          s(:str, '(?<match>bar)'),
+          s(:regopt)),
+        :=~,
+        s(:str, 'bar')),
+      %q{/#{1}(?<match>bar)/ =~ 'bar'})
+  end
+
+  # To superclass
+
+  def test_super
+    assert_parses(
+      s(:super, s(:lvar, :foo)),
+      %q{super(foo)},
+      %q{~~~~~ keyword
+        |     ^ begin
+        |         ^ end
+        |~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:super, s(:lvar, :foo)),
+      %q{super foo},
+      %q{~~~~~ keyword
+        |~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:super),
+      %q{super()},
+      %q{~~~~~ keyword
+        |     ^ begin
+        |      ^ end
+        |~~~~~~~ expression})
+  end
+
+  def test_zsuper
+    assert_parses(
+      s(:zsuper),
+      %q{super},
+      %q{~~~~~ keyword
+        |~~~~~ expression})
+  end
+
+  def test_super_block
+    assert_parses(
+      s(:block,
+        s(:super, s(:lvar, :foo), s(:lvar, :bar)),
+        s(:args), nil),
+      %q{super foo, bar do end})
+
+    assert_parses(
+      s(:block,
+        s(:zsuper),
+        s(:args), nil),
+      %q{super do end})
+  end
+
+  # To block argument
+
+  def test_yield
+    assert_parses(
+      s(:yield, s(:lvar, :foo)),
+      %q{yield(foo)},
+      %q{~~~~~ keyword
+        |     ^ begin
+        |         ^ end
+        |~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:yield, s(:lvar, :foo)),
+      %q{yield foo},
+      %q{~~~~~ keyword
+        |~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:yield),
+      %q{yield()},
+      %q{~~~~~ keyword
+        |     ^ begin
+        |      ^ end
+        |~~~~~~~ expression})
+
+    assert_parses(
+      s(:yield),
+      %q{yield},
+      %q{~~~~~ keyword
+        |~~~~~ expression})
+  end
+
+  def test_yield_block
+    assert_diagnoses(
+      [:error, :block_given_to_yield],
+      %q{yield foo do end},
+      %q{~~~~~ location
+        |          ~~ highlights (0)})
+
+    assert_diagnoses(
+      [:error, :block_given_to_yield],
+      %q{yield(&foo)},
+      %q{~~~~~ location
+        |      ~~~~ highlights (0)})
+  end
+
+  # Call arguments
+
+  def test_args_cmd
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:send, nil, :f, s(:lvar, :bar))),
+      %q{fun(f bar)})
+  end
+
+  def test_args_args_star
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo), s(:splat, s(:lvar, :bar))),
+      %q{fun(foo, *bar)})
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo), s(:splat, s(:lvar, :bar)),
+        s(:block_pass, s(:lvar, :baz))),
+      %q{fun(foo, *bar, &baz)})
+  end
+
+  def test_args_star
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:splat, s(:lvar, :bar))),
+      %q{fun(*bar)})
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:splat, s(:lvar, :bar)),
+        s(:block_pass, s(:lvar, :baz))),
+      %q{fun(*bar, &baz)})
+  end
+
+  def test_args_block_pass
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:block_pass, s(:lvar, :bar))),
+      %q{fun(&bar)})
+  end
+
+  def test_args_args_comma
+    assert_parses(
+      s(:send, s(:lvar, :foo), :[],
+        s(:lvar, :bar)),
+      %q{foo[bar,]},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_args_assocs
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1)))),
+      %q{fun(:foo => 1)})
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1))),
+        s(:block_pass, s(:lvar, :baz))),
+      %q{fun(:foo => 1, &baz)})
+  end
+
+  def test_args_assocs_star
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1))),
+        s(:splat, s(:lvar, :bar))),
+      %q{fun(:foo => 1, *bar)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1))),
+        s(:splat, s(:lvar, :bar)),
+        s(:block_pass, s(:lvar, :baz))),
+      %q{fun(:foo => 1, *bar, &baz)},
+      %q{},
+      %w(1.8))
+  end
+
+  def test_args_assocs_comma
+    assert_parses(
+      s(:send, s(:lvar, :foo), :[],
+        s(:hash, s(:pair, s(:sym, :baz), s(:int, 1)))),
+      %q{foo[:baz => 1,]},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_args_args_assocs
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo),
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1)))),
+      %q{fun(foo, :foo => 1)})
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo),
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1))),
+        s(:block_pass, s(:lvar, :baz))),
+      %q{fun(foo, :foo => 1, &baz)})
+  end
+
+  def test_args_args_assocs_comma
+    assert_parses(
+      s(:send, s(:lvar, :foo), :[],
+        s(:lvar, :bar),
+        s(:hash, s(:pair, s(:sym, :baz), s(:int, 1)))),
+      %q{foo[bar, :baz => 1,]},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_args_args_assocs_star
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo),
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1))),
+        s(:splat, s(:lvar, :bar))),
+      %q{fun(foo, :foo => 1, *bar)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo),
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1))),
+        s(:splat, s(:lvar, :bar)),
+        s(:block_pass, s(:lvar, :baz))),
+      %q{fun(foo, :foo => 1, *bar, &baz)},
+      %q{},
+      %w(1.8))
+  end
+
+  # Call arguments with whitespace
+
+  def test_space_args_cmd
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:begin, s(:send, nil, :f, s(:lvar, :bar)))),
+      %q{fun (f bar)})
+  end
+
+  def test_space_args_arg
+    assert_parses(
+      s(:send, nil, :fun, s(:begin, s(:int, 1))),
+      %q{fun (1)})
+  end
+
+  def test_space_args_arg_block
+    assert_parses(
+      s(:block,
+        s(:send, nil, :fun, s(:begin, s(:int, 1))),
+        s(:args), nil),
+      %q{fun (1) {}})
+
+    assert_parses(
+      s(:block,
+        s(:send, s(:lvar, :foo), :fun, s(:int, 1)),
+        s(:args), nil),
+      %q{foo.fun (1) {}},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:block,
+        s(:send, s(:lvar, :foo), :fun, s(:begin, s(:int, 1))),
+        s(:args), nil),
+      %q{foo.fun (1) {}},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:block,
+        s(:send, s(:lvar, :foo), :fun, s(:int, 1)),
+        s(:args), nil),
+      %q{foo::fun (1) {}},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:block,
+        s(:send, s(:lvar, :foo), :fun, s(:begin, s(:int, 1))),
+        s(:args), nil),
+      %q{foo::fun (1) {}},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_space_args_arg_call
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:send, s(:begin, s(:int, 1)), :to_i)),
+      %q{fun (1).to_i})
+  end
+
+  def test_space_args_block_pass
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:block_pass, s(:lvar, :foo))),
+      %q{fun (&foo)},
+      %q{},
+      %w(1.8))
+  end
+
+  def test_space_args_arg_block_pass
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo),
+        s(:block_pass, s(:lvar, :bar))),
+      %q{fun (foo, &bar)},
+      %q{},
+      %w(1.8))
+  end
+
+  def test_space_args_args_star
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo), s(:splat, s(:lvar, :bar))),
+      %q{fun (foo, *bar)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo), s(:splat, s(:lvar, :bar)),
+        s(:block_pass, s(:lvar, :baz))),
+      %q{fun (foo, *bar, &baz)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo), s(:int, 1),
+        s(:splat, s(:lvar, :bar))),
+      %q{fun (foo, 1, *bar)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo), s(:int, 1),
+        s(:splat, s(:lvar, :bar)),
+        s(:block_pass, s(:lvar, :baz))),
+      %q{fun (foo, 1, *bar, &baz)},
+      %q{},
+      %w(1.8))
+  end
+
+  def test_space_args_star
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:splat, s(:lvar, :bar))),
+      %q{fun (*bar)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:splat, s(:lvar, :bar)),
+        s(:block_pass, s(:lvar, :baz))),
+      %q{fun (*bar, &baz)},
+      %q{},
+      %w(1.8))
+  end
+
+  def test_space_args_assocs
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1)))),
+      %q{fun (:foo => 1)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1))),
+        s(:block_pass, s(:lvar, :baz))),
+      %q{fun (:foo => 1, &baz)},
+      %q{},
+      %w(1.8))
+  end
+
+  def test_space_args_assocs_star
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1))),
+        s(:splat, s(:lvar, :bar))),
+      %q{fun (:foo => 1, *bar)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1))),
+        s(:splat, s(:lvar, :bar)),
+        s(:block_pass, s(:lvar, :baz))),
+      %q{fun (:foo => 1, *bar, &baz)},
+      %q{},
+      %w(1.8))
+  end
+
+  def test_space_args_args_assocs
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo),
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1)))),
+      %q{fun (foo, :foo => 1)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo),
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1))),
+        s(:block_pass, s(:lvar, :baz))),
+      %q{fun (foo, :foo => 1, &baz)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo), s(:int, 1),
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1)))),
+      %q{fun (foo, 1, :foo => 1)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo), s(:int, 1),
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1))),
+        s(:block_pass, s(:lvar, :baz))),
+      %q{fun (foo, 1, :foo => 1, &baz)},
+      %q{},
+      %w(1.8))
+  end
+
+  def test_space_args_args_assocs_star
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo),
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1))),
+        s(:splat, s(:lvar, :bar))),
+      %q{fun (foo, :foo => 1, *bar)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo),
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1))),
+        s(:splat, s(:lvar, :bar)),
+        s(:block_pass, s(:lvar, :baz))),
+      %q{fun (foo, :foo => 1, *bar, &baz)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo), s(:int, 1),
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1))),
+        s(:splat, s(:lvar, :bar))),
+      %q{fun (foo, 1, :foo => 1, *bar)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :fun,
+        s(:lvar, :foo), s(:int, 1),
+        s(:hash, s(:pair, s(:sym, :foo), s(:int, 1))),
+        s(:splat, s(:lvar, :bar)),
+        s(:block_pass, s(:lvar, :baz))),
+      %q{fun (foo, 1, :foo => 1, *bar, &baz)},
+      %q{},
+      %w(1.8))
+  end
+
+  def test_space_args_arg_arg
+    assert_parses(
+      s(:send, nil, :fun, s(:int, 1), s(:int, 2)),
+      %q{fun (1, 2)},
+      %q{},
+      %w(1.8))
+  end
+
+  def test_space_args_none
+    assert_parses(
+      s(:send, nil, :fun),
+      %q{fun ()},
+      %q{},
+      %w(1.8))
+  end
+
+  def test_space_args_block
+    assert_parses(
+      s(:block,
+        s(:send, nil, :fun),
+        s(:args), nil),
+      %q{fun () {}},
+      %q{    ^ begin (send)
+        |     ^ end (send)},
+      %w(1.8))
+
+    assert_parses(
+      s(:block,
+        s(:send, s(:lvar, :foo), :fun),
+        s(:args), nil),
+      %q{foo.fun () {}},
+      %q{        ^ begin (send)
+        |         ^ end (send)},
+      %w(1.8))
+
+    assert_parses(
+      s(:block,
+        s(:send, s(:lvar, :foo), :fun),
+        s(:args), nil),
+      %q{foo::fun () {}},
+      %q{         ^ begin (send)
+        |          ^ end (send)},
+      %w(1.8))
+
+    assert_parses(
+      s(:block,
+        s(:send, nil, :fun,
+          s(:begin)),
+        s(:args), nil),
+      %q{fun () {}},
+      %q{    ~~ expression (send.begin)},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  #
+  # Control flow
+  #
+
+  # Operators
+
+  def test_and
+    assert_parses(
+      s(:and, s(:lvar, :foo), s(:lvar, :bar)),
+      %q{foo and bar},
+      %q{    ~~~ operator
+        |~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:and, s(:lvar, :foo), s(:lvar, :bar)),
+      %q{foo && bar},
+      %q{    ~~ operator
+        |~~~~~~~~~~ expression})
+  end
+
+  def test_or
+    assert_parses(
+      s(:or, s(:lvar, :foo), s(:lvar, :bar)),
+      %q{foo or bar},
+      %q{    ~~ operator
+        |~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:or, s(:lvar, :foo), s(:lvar, :bar)),
+      %q{foo || bar},
+      %q{    ~~ operator
+        |~~~~~~~~~~ expression})
+  end
+
+  def test_and_or_masgn
+    assert_parses(
+      s(:and,
+        s(:lvar, :foo),
+        s(:begin,
+          s(:masgn,
+            s(:mlhs, s(:lvasgn, :a), s(:lvasgn, :b)),
+            s(:lvar, :bar)))),
+      %q{foo && (a, b = bar)})
+
+    assert_parses(
+      s(:or,
+        s(:lvar, :foo),
+        s(:begin,
+          s(:masgn,
+            s(:mlhs, s(:lvasgn, :a), s(:lvasgn, :b)),
+            s(:lvar, :bar)))),
+      %q{foo || (a, b = bar)})
+  end
+
+  # Branching
+
+  def test_if
+    assert_parses(
+      s(:if, s(:lvar, :foo), s(:lvar, :bar), nil),
+      %q{if foo then bar; end},
+      %q{~~ keyword
+        |       ~~~~ begin
+        |                 ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:if, s(:lvar, :foo), s(:lvar, :bar), nil),
+      %q{if foo; bar; end},
+      %q{~~ keyword
+        |             ~~~ end
+        |~~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_if_nl_then
+    assert_parses(
+      s(:if, s(:lvar, :foo), s(:lvar, :bar), nil),
+      %Q{if foo\nthen bar end},
+       %q{       ~~~~ begin})
+  end
+
+  def test_if_mod
+    assert_parses(
+      s(:if, s(:lvar, :foo), s(:lvar, :bar), nil),
+      %q{bar if foo},
+      %q{    ~~ keyword
+        |~~~~~~~~~~ expression})
+  end
+
+  def test_unless
+    assert_parses(
+      s(:if, s(:lvar, :foo), nil, s(:lvar, :bar)),
+      %q{unless foo then bar; end},
+      %q{~~~~~~ keyword
+        |           ~~~~ begin
+        |                     ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:if, s(:lvar, :foo), nil, s(:lvar, :bar)),
+      %q{unless foo; bar; end},
+      %q{~~~~~~ keyword
+        |                 ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_unless_mod
+    assert_parses(
+      s(:if, s(:lvar, :foo), nil, s(:lvar, :bar)),
+      %q{bar unless foo},
+      %q{    ~~~~~~ keyword
+        |~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_if_else
+    assert_parses(
+      s(:if, s(:lvar, :foo), s(:lvar, :bar), s(:lvar, :baz)),
+      %q{if foo then bar; else baz; end},
+      %q{~~ keyword
+        |       ~~~~ begin
+        |                 ~~~~ else
+        |                           ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:if, s(:lvar, :foo), s(:lvar, :bar), s(:lvar, :baz)),
+      %q{if foo; bar; else baz; end},
+      %q{~~ keyword
+        |             ~~~~ else
+        |                       ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_unless_else
+    assert_parses(
+      s(:if, s(:lvar, :foo), s(:lvar, :baz), s(:lvar, :bar)),
+      %q{unless foo then bar; else baz; end},
+      %q{~~~~~~ keyword
+        |           ~~~~ begin
+        |                     ~~~~ else
+        |                               ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:if, s(:lvar, :foo), s(:lvar, :baz), s(:lvar, :bar)),
+      %q{unless foo; bar; else baz; end},
+      %q{~~~~~~ keyword
+        |                 ~~~~ else
+        |                           ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_if_elsif
+    assert_parses(
+      s(:if, s(:lvar, :foo), s(:lvar, :bar),
+        s(:if, s(:lvar, :baz), s(:int, 1), s(:int, 2))),
+      %q{if foo; bar; elsif baz; 1; else 2; end},
+      %q{~~ keyword
+        |             ~~~~~ else
+        |             ~~~~~ keyword (if)
+        |                           ~~~~ else (if)
+        |                                   ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_ternary
+    assert_parses(
+      s(:if, s(:lvar, :foo), s(:int, 1), s(:int, 2)),
+      %q{foo ? 1 : 2},
+      %q{    ^ question
+        |        ^ colon
+        |~~~~~~~~~~~ expression})
+  end
+
+  def test_ternary_ambiguous_symbol
+    assert_parses(
+      s(:begin,
+        s(:lvasgn, :t, s(:int, 1)),
+        s(:if, s(:begin, s(:lvar, :foo)),
+          s(:lvar, :t),
+          s(:const, nil, :T))),
+      %q{t=1;(foo)?t:T},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_if_masgn
+    assert_diagnoses(
+      [:error, :masgn_as_condition],
+      %q{if (a, b = foo); end},
+      %q{    ~~~~~~~~~~ location})
+  end
+
+  def test_if_mod_masgn
+    assert_diagnoses(
+      [:error, :masgn_as_condition],
+      %q{1 if (a, b = foo)},
+      %q{      ~~~~~~~~~~ location})
+  end
+
+  def test_tern_masgn
+    assert_diagnoses(
+      [:error, :masgn_as_condition],
+      %q{(a, b = foo) ? 1 : 2},
+      %q{ ~~~~~~~~~~ location})
+  end
+
+  def test_cond_begin
+    assert_parses(
+      s(:if,
+        s(:begin, s(:lvar, :bar)),
+        s(:lvar, :foo),
+        nil),
+      %q{if (bar); foo; end})
+  end
+
+  def test_cond_begin_masgn
+    assert_parses(
+      s(:if,
+        s(:begin,
+          s(:lvar, :bar),
+          s(:masgn,
+            s(:mlhs, s(:lvasgn, :a), s(:lvasgn, :b)),
+            s(:lvar, :foo))),
+        nil, nil),
+      %q{if (bar; a, b = foo); end})
+  end
+
+  def test_cond_begin_and_or_masgn
+    assert_diagnoses(
+      [:error, :masgn_as_condition],
+      %q{if foo && (a, b = bar); end},
+      %q{           ~~~~~~~~~~ location},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_diagnoses(
+      [:error, :masgn_as_condition],
+      %q{if foo || (a, b = bar); end},
+      %q{           ~~~~~~~~~~ location},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:if,
+        s(:and,
+          s(:begin,
+            s(:masgn,
+              s(:mlhs,
+                s(:lvasgn, :a), s(:lvasgn, :b)),
+              s(:lvar, :foo))),
+          s(:lvar, :bar)),
+        nil, nil),
+      %q{if (a, b = foo) && bar; end},
+      %q{},
+      %w(1.8))
+  end
+
+  def test_cond_iflipflop
+    assert_parses(
+      s(:if, s(:iflipflop, s(:lvar, :foo), s(:lvar, :bar)),
+        nil, nil),
+      %q{if foo..bar; end},
+      %q{   ~~~~~~~~ expression (iflipflop)
+        |      ~~ operator (iflipflop)})
+  end
+
+  def test_cond_eflipflop
+    assert_parses(
+      s(:if, s(:eflipflop, s(:lvar, :foo), s(:lvar, :bar)),
+        nil, nil),
+      %q{if foo...bar; end},
+      %q{   ~~~~~~~~~ expression (eflipflop)
+        |      ~~~ operator (eflipflop)})
+  end
+
+  def test_cond_match_current_line
+    assert_parses(
+      s(:if,
+        s(:match_current_line,
+          s(:regexp,
+            s(:str, 'wat'),
+            s(:regopt))),
+        nil, nil),
+      %q{if /wat/; end},
+      %q{   ~~~~~ expression (match_current_line)})
+  end
+
+  # Case matching
+
+  def test_case_expr
+    assert_parses(
+      s(:case, s(:lvar, :foo),
+        s(:when, s(:str, 'bar'),
+          s(:lvar, :bar)),
+        nil),
+      %q{case foo; when 'bar'; bar; end},
+      %q{~~~~ keyword
+        |          ~~~~ keyword (when)
+        |                           ~~~ end
+        |          ~~~~~~~~~~~~~~~ expression (when)
+        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_case_expr_else
+    assert_parses(
+      s(:case, s(:lvar, :foo),
+        s(:when, s(:str, 'bar'),
+          s(:lvar, :bar)),
+        s(:lvar, :baz)),
+      %q{case foo; when 'bar'; bar; else baz; end},
+      %q{~~~~ keyword
+        |          ~~~~ keyword (when)
+        |                           ~~~~ else
+        |                                     ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_case_cond
+    assert_parses(
+      s(:case, nil,
+        s(:when, s(:lvar, :foo),
+          s(:str, 'foo')),
+        nil),
+      %q{case; when foo; 'foo'; end},
+      %q{~~~~ keyword
+        |      ~~~~ keyword (when)
+        |                       ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_case_cond_else
+    assert_parses(
+      s(:case, nil,
+        s(:when, s(:lvar, :foo),
+          s(:str, 'foo')),
+        s(:str, 'bar')),
+      %q{case; when foo; 'foo'; else 'bar'; end},
+      %q{~~~~ keyword
+        |      ~~~~ keyword (when)
+        |                       ~~~~ else
+        |                                   ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_case_cond_just_else
+    assert_parses(
+      s(:case, nil,
+        s(:str, 'bar')),
+      %q{case; else 'bar'; end},
+      %q{~~~~ keyword
+        |      ~~~~ else
+        |                  ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~~ expression},
+      %w(1.8))
+  end
+
+  def test_when_then
+    assert_parses(
+      s(:case, s(:lvar, :foo),
+        s(:when, s(:str, 'bar'),
+          s(:lvar, :bar)),
+        nil),
+      %q{case foo; when 'bar' then bar; end},
+      %q{          ~~~~ keyword (when)
+        |                     ~~~~ begin (when)
+        |          ~~~~~~~~~~~~~~~~~~~ expression (when)})
+  end
+
+  def test_when_multi
+    assert_parses(
+      s(:case, s(:lvar, :foo),
+        s(:when, s(:str, 'bar'), s(:str, 'baz'),
+          s(:lvar, :bar)),
+        nil),
+      %q{case foo; when 'bar', 'baz'; bar; end})
+  end
+
+  def test_when_splat
+    assert_parses(
+      s(:case, s(:lvar, :foo),
+        s(:when,
+          s(:int, 1),
+          s(:splat, s(:lvar, :baz)),
+          s(:lvar, :bar)),
+        s(:when,
+          s(:splat, s(:lvar, :foo)),
+          nil),
+        nil),
+      %q{case foo; when 1, *baz; bar; when *foo; end},
+      %q{                  ^ operator (when/1.splat)
+        |                  ~~~~ expression (when/1.splat)
+        |                                  ^ operator (when/2.splat)
+        |                                  ~~~~ expression (when/2.splat)})
+  end
+
+  # Looping
+
+  def test_while
+    assert_parses(
+      s(:while, s(:lvar, :foo), s(:send, nil, :meth)),
+      %q{while foo do meth end},
+      %q{~~~~~ keyword
+        |          ~~ begin
+        |                  ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:while, s(:lvar, :foo), s(:send, nil, :meth)),
+      %q{while foo; meth end},
+      %q{~~~~~ keyword
+        |                ~~~ end
+        |~~~~~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_while_mod
+    assert_parses(
+      s(:while, s(:lvar, :foo), s(:send, nil, :meth)),
+      %q{meth while foo},
+      %q{     ~~~~~ keyword})
+  end
+
+  def test_until
+    assert_parses(
+      s(:until, s(:lvar, :foo), s(:send, nil, :meth)),
+      %q{until foo do meth end},
+      %q{~~~~~ keyword
+        |          ~~ begin
+        |                  ~~~ end})
+
+    assert_parses(
+      s(:until, s(:lvar, :foo), s(:send, nil, :meth)),
+      %q{until foo; meth end},
+      %q{~~~~~ keyword
+        |                ~~~ end})
+  end
+
+  def test_until_mod
+    assert_parses(
+      s(:until, s(:lvar, :foo), s(:send, nil, :meth)),
+      %q{meth until foo},
+      %q{     ~~~~~ keyword})
+  end
+
+  def test_while_post
+    assert_parses(
+      s(:while_post, s(:lvar, :foo),
+        s(:kwbegin, s(:send, nil, :meth))),
+      %q{begin meth end while foo},
+      %q{               ~~~~~ keyword})
+  end
+
+  def test_until_post
+    assert_parses(
+      s(:until_post, s(:lvar, :foo),
+        s(:kwbegin, s(:send, nil, :meth))),
+      %q{begin meth end until foo},
+      %q{               ~~~~~ keyword})
+  end
+
+  def test_while_masgn
+    assert_diagnoses(
+      [:error, :masgn_as_condition],
+      %q{while (a, b = foo); end},
+      %q{       ~~~~~~~~~~ location})
+  end
+
+  def test_while_mod_masgn
+    assert_diagnoses(
+      [:error, :masgn_as_condition],
+      %q{foo while (a, b = foo)},
+      %q{           ~~~~~~~~~~ location})
+  end
+
+  def test_for
+    assert_parses(
+      s(:for,
+        s(:lvasgn, :a),
+        s(:lvar, :foo),
+        s(:send, nil, :p, s(:lvar, :a))),
+      %q{for a in foo do p a; end},
+      %q{~~~ keyword
+        |      ~~ in
+        |             ~~ begin
+        |                     ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:for,
+        s(:lvasgn, :a),
+        s(:lvar, :foo),
+        s(:send, nil, :p, s(:lvar, :a))),
+      %q{for a in foo; p a; end})
+  end
+
+  def test_for_mlhs
+    assert_parses(
+      s(:for,
+        s(:mlhs,
+          s(:lvasgn, :a),
+          s(:lvasgn, :b)),
+        s(:lvar, :foo),
+        s(:send, nil, :p, s(:lvar, :a), s(:lvar, :b))),
+      %q{for a, b in foo; p a, b; end},
+      %q{    ~~~~ expression (mlhs)})
+  end
+
+  # Control flow commands
+
+  def test_break
+    assert_parses(
+      s(:break, s(:begin, s(:lvar, :foo))),
+      %q{break(foo)},
+      %q{~~~~~ keyword
+        |~~~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:break, s(:begin, s(:lvar, :foo))),
+      %q{break(foo)},
+      %q{~~~~~ keyword
+        |~~~~~~~~~~ expression},
+      %w(1.8))
+
+    assert_parses(
+      s(:break, s(:lvar, :foo)),
+      %q{break foo},
+      %q{~~~~~ keyword
+        |~~~~~~~~~ expression})
+
+    assert_parses(
+        s(:break, s(:begin)),
+      %q{break()},
+      %q{~~~~~ keyword
+        |~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:break),
+      %q{break},
+      %q{~~~~~ keyword
+        |~~~~~ expression})
+  end
+
+  def test_break_block
+    assert_parses(
+      s(:break,
+        s(:block,
+          s(:send, nil, :fun, s(:lvar, :foo)),
+          s(:args), nil)),
+      %q{break fun foo do end},
+      %q{      ~~~~~~~~~~~~~~ expression (block)
+        |~~~~~~~~~~~~~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_return
+    assert_parses(
+      s(:return, s(:begin, s(:lvar, :foo))),
+      %q{return(foo)},
+      %q{~~~~~~ keyword
+        |~~~~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:return, s(:begin, s(:lvar, :foo))),
+      %q{return(foo)},
+      %q{~~~~~~ keyword
+        |~~~~~~~~~~~ expression},
+      %w(1.8))
+
+    assert_parses(
+      s(:return, s(:lvar, :foo)),
+      %q{return foo},
+      %q{~~~~~~ keyword
+        |~~~~~~~~~~ expression})
+
+    assert_parses(
+      s(:return, s(:begin)),
+      %q{return()},
+      %q{~~~~~~ keyword
+        |~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:return),
+      %q{return},
+      %q{~~~~~~ keyword
+        |~~~~~~ expression})
+  end
+
+  def test_return_block
+    assert_parses(
+      s(:return,
+        s(:block,
+          s(:send, nil, :fun, s(:lvar, :foo)),
+          s(:args), nil)),
+      %q{return fun foo do end},
+      %q{       ~~~~~~~~~~~~~~ expression (block)
+        |~~~~~~~~~~~~~~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_next
+    assert_parses(
+      s(:next, s(:begin, s(:lvar, :foo))),
+      %q{next(foo)},
+      %q{~~~~ keyword
+        |~~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:next, s(:begin, s(:lvar, :foo))),
+      %q{next(foo)},
+      %q{~~~~ keyword
+        |~~~~~~~~~ expression},
+      %w(1.8))
+
+    assert_parses(
+      s(:next, s(:lvar, :foo)),
+      %q{next foo},
+      %q{~~~~ keyword
+        |~~~~~~~~ expression})
+
+    assert_parses(
+        s(:next, s(:begin)),
+      %q{next()},
+      %q{~~~~ keyword
+        |~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:next),
+      %q{next},
+      %q{~~~~ keyword
+        |~~~~ expression})
+  end
+
+  def test_next_block
+    assert_parses(
+      s(:next,
+        s(:block,
+          s(:send, nil, :fun, s(:lvar, :foo)),
+          s(:args), nil)),
+      %q{next fun foo do end},
+      %q{     ~~~~~~~~~~~~~~ expression (block)
+        |~~~~~~~~~~~~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_redo
+    assert_parses(
+      s(:redo),
+      %q{redo},
+      %q{~~~~ keyword
+        |~~~~ expression})
+  end
+
+  # Exception handling
+
+  def test_rescue
+    assert_parses(
+      s(:kwbegin,
+        s(:rescue, s(:send, nil, :meth),
+          s(:resbody, nil, nil, s(:lvar, :foo)),
+          nil)),
+      %q{begin; meth; rescue; foo; end},
+      %q{~~~~~ begin
+        |             ~~~~~~ keyword (rescue.resbody)
+        |             ~~~~~~~~~~~ expression (rescue.resbody)
+        |       ~~~~~~~~~~~~~~~~~ expression (rescue)
+        |                          ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_rescue_else
+    assert_parses(
+      s(:kwbegin,
+        s(:rescue, s(:send, nil, :meth),
+          s(:resbody, nil, nil, s(:lvar, :foo)),
+          s(:lvar, :bar))),
+      %q{begin; meth; rescue; foo; else; bar; end},
+      %q{                          ~~~~ else (rescue)
+        |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression (rescue)})
+  end
+
+  def test_rescue_else_useless
+    assert_diagnoses(
+      [:warning, :useless_else],
+      %q{begin; 1; else; 2; end},
+      %q{          ~~~~ location})
+  end
+
+  def test_ensure
+    assert_parses(
+      s(:kwbegin,
+        s(:ensure, s(:send, nil, :meth),
+          s(:lvar, :bar))),
+      %q{begin; meth; ensure; bar; end},
+      %q{~~~~~ begin
+        |             ~~~~~~ keyword (ensure)
+        |       ~~~~~~~~~~~~~~~~~ expression (ensure)
+        |                          ~~~ end
+        |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_ensure_empty
+    assert_parses(
+      s(:kwbegin,
+        s(:ensure, nil, nil)),
+      %q{begin ensure end},
+      %q{~~~~~ begin
+        |      ~~~~~~ keyword (ensure)
+        |      ~~~~~~ expression (ensure)
+        |             ~~~ end
+        |~~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_rescue_ensure
+    assert_parses(
+      s(:kwbegin,
+        s(:ensure,
+          s(:rescue,
+            s(:send, nil, :meth),
+            s(:resbody, nil, nil, s(:lvar, :baz)),
+            nil),
+          s(:lvar, :bar))),
+      %q{begin; meth; rescue; baz; ensure; bar; end},
+      %q{                          ~~~~~~ keyword (ensure)
+        |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression (ensure)
+        |             ~~~~~~ keyword (ensure.rescue.resbody)
+        |       ~~~~~~~~~~~~~~~~~ expression (ensure.rescue)})
+  end
+
+  def test_rescue_else_ensure
+    assert_parses(
+      s(:kwbegin,
+        s(:ensure,
+          s(:rescue,
+            s(:send, nil, :meth),
+            s(:resbody, nil, nil, s(:lvar, :baz)),
+            s(:lvar, :foo)),
+          s(:lvar, :bar))),
+      %q{begin; meth; rescue; baz; else foo; ensure; bar end},
+      %q{                                    ~~~~~~ keyword (ensure)
+        |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression (ensure)
+        |             ~~~~~~ keyword (ensure.rescue.resbody)
+        |                          ~~~~ else (ensure.rescue)
+        |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression (ensure.rescue)})
+  end
+
+  def test_rescue_mod
+    assert_parses(
+      s(:rescue,
+        s(:send, nil, :meth),
+        s(:resbody, nil, nil, s(:lvar, :bar)),
+        nil),
+      %q{meth rescue bar},
+      %q{     ~~~~~~ keyword (resbody)
+        |     ~~~~~~~~~~ expression (resbody)
+        |~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_rescue_mod_asgn
+    assert_parses(
+      s(:lvasgn, :foo,
+        s(:rescue,
+          s(:send, nil, :meth),
+          s(:resbody, nil, nil, s(:lvar, :bar)),
+          nil)),
+      %q{foo = meth rescue bar},
+      %q{           ~~~~~~ keyword (rescue.resbody)
+        |           ~~~~~~~~~~ expression (rescue.resbody)
+        |      ~~~~~~~~~~~~~~~ expression (rescue)
+        |~~~~~~~~~~~~~~~~~~~~~ expression})
+  end
+
+  def test_rescue_mod_op_assign
+    assert_parses(
+      s(:op_asgn,
+        s(:lvasgn, :foo), :+,
+        s(:rescue,
+          s(:send, nil, :meth),
+          s(:resbody, nil, nil, s(:lvar, :bar)),
+          nil)),
+      %q{foo += meth rescue bar},
+      %q{            ~~~~~~ keyword (rescue.resbody)
+        |            ~~~~~~~~~~ expression (rescue.resbody)
+        |       ~~~~~~~~~~~~~~~ expression (rescue)
+        |~~~~~~~~~~~~~~~~~~~~~~ expression},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_resbody_list
+    assert_parses(
+      s(:kwbegin,
+        s(:rescue,
+          s(:send, nil, :meth),
+          s(:resbody,
+            s(:array, s(:const, nil, :Exception)),
+            nil,
+            s(:lvar, :bar)),
+          nil)),
+      %q{begin; meth; rescue Exception; bar; end})
+  end
+
+  def test_resbody_list_mrhs
+    assert_parses(
+      s(:kwbegin,
+        s(:rescue,
+          s(:send, nil, :meth),
+          s(:resbody,
+            s(:array,
+              s(:const, nil, :Exception),
+              s(:lvar, :foo)),
+            nil,
+            s(:lvar, :bar)),
+          nil)),
+      %q{begin; meth; rescue Exception, foo; bar; end})
+  end
+
+  def test_resbody_var
+    assert_parses(
+      s(:kwbegin,
+        s(:rescue,
+          s(:send, nil, :meth),
+          s(:resbody, nil, s(:lvasgn, :ex), s(:lvar, :bar)),
+          nil)),
+      %q{begin; meth; rescue => ex; bar; end})
+
+    assert_parses(
+      s(:kwbegin,
+        s(:rescue,
+          s(:send, nil, :meth),
+          s(:resbody, nil, s(:ivasgn, :@ex), s(:lvar, :bar)),
+          nil)),
+      %q{begin; meth; rescue => @ex; bar; end})
+  end
+
+  def test_resbody_list_var
+    assert_parses(
+      s(:kwbegin,
+        s(:rescue,
+          s(:send, nil, :meth),
+          s(:resbody,
+            s(:array, s(:lvar, :foo)),
+            s(:lvasgn, :ex),
+            s(:lvar, :bar)),
+          nil)),
+      %q{begin; meth; rescue foo => ex; bar; end})
+  end
+
+  def test_retry
+    assert_parses(
+      s(:retry),
+      %q{retry},
+      %q{~~~~~ keyword
+        |~~~~~ expression})
+  end
+
+  # BEGIN and END
+
+  def test_preexe
+    assert_parses(
+      s(:preexe, s(:int, 1)),
+      %q{BEGIN { 1 }},
+      %q{~~~~~ keyword
+        |      ^ begin
+        |          ^ end
+        |~~~~~~~~~~~ expression})
+  end
+
+  def test_preexe_invalid
+    assert_diagnoses(
+      [:error, :begin_in_method],
+      %q{def f; BEGIN{}; end},
+      %q{       ~~~~~ location},
+      # Yes. *Exclude 1.9*. Sigh.
+      ALL_VERSIONS - %w(1.9))
+  end
+
+  def test_postexe
+    assert_parses(
+      s(:postexe, s(:int, 1)),
+      %q{END { 1 }},
+      %q{~~~ keyword
+        |    ^ begin
+        |        ^ end
+        |~~~~~~~~~ expression})
+  end
+
+  #
+  # Miscellanea
+  #
+
+  def test_kwbegin_compstmt
+    assert_parses(
+      s(:kwbegin,
+        s(:send, nil, :foo!),
+        s(:send, nil, :bar!)),
+      %q{begin foo!; bar! end})
+  end
+
+  def test_crlf_line_endings
+    with_versions(ALL_VERSIONS) do |_ver, parser|
+      source_file = Parser::Source::Buffer.new('(comments)')
+      source_file.source = "\r\nfoo"
+
+      range = lambda do |from, to|
+        Parser::Source::Range.new(source_file, from, to)
+      end
+
+      ast = parser.parse(source_file)
+
+      assert_equal s(:lvar, :foo),
+                   ast
+
+      assert_equal range.call(1, 4),
+                   ast.loc.expression
+    end
+  end
+
+  def test_begin_cmdarg
+    assert_parses(
+      s(:send, nil, :p,
+        s(:kwbegin,
+          s(:block,
+            s(:send, s(:int, 1), :times),
+            s(:args),
+            s(:int, 1)))),
+      %q{p begin 1.times do 1 end end},
+      %{},
+      ALL_VERSIONS - %w(1.8 1.9))
+  end
+
+  def test_bug_cmdarg
+    assert_parses(
+      s(:send, nil, :meth,
+        s(:begin,
+          s(:block,
+            s(:send, nil, :lambda),
+            s(:args), nil))),
+      %q{meth (lambda do end)},
+      %q{},
+      %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :assert,
+        s(:send, nil, :dogs)),
+      %q{assert dogs})
+
+    assert_parses(
+      s(:send, nil, :assert,
+        s(:hash,
+          s(:pair, s(:sym, :do), s(:true)))),
+      %q{assert do: true},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+
+    assert_parses(
+      s(:send, nil, :f,
+        s(:hash,
+          s(:pair,
+            s(:sym, :x),
+            s(:block,
+              s(:send, nil, :lambda),
+              s(:args),
+              s(:block,
+                s(:send, nil, :meth),
+                s(:args), nil))))),
+      %q{f x: -> do meth do end end},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_file_line_non_literals
+    with_versions(ALL_VERSIONS) do |_ver, parser|
+      parser.builder.emit_file_line_as_literals = false
+
+      source_file = Parser::Source::Buffer.new('(comments)')
+      source_file.source = "[__FILE__, __LINE__]"
+
+      ast = parser.parse(source_file)
+
+      assert_equal s(:array, s(:__FILE__), s(:__LINE__)), ast
+    end
+  end
+
+  if defined?(Encoding)
+    def test_bom
+      assert_parses(
+        s(:int, 1),
+        %Q{\xef\xbb\xbf1}.force_encoding(Encoding::BINARY),
+        %q{},
+        %w(1.9 2.0 2.1))
+    end
+
+    def test_magic_encoding_comment
+      assert_parses(
+        s(:begin,
+          s(:lvasgn, :"проверка", s(:int, 42)),
+          s(:send, nil, :puts, s(:lvar, :"проверка"))),
+        %Q{# coding:koi8-r
+           \xd0\xd2\xcf\xd7\xc5\xd2\xcb\xc1 = 42
+           puts \xd0\xd2\xcf\xd7\xc5\xd2\xcb\xc1}.
+          force_encoding(Encoding::BINARY),
+        %q{},
+        %w(1.9 2.0 2.1))
+    end
+
+    def test_regexp_encoding
+      assert_parses(
+        s(:match_with_lvasgn,
+          s(:regexp,
+            s(:str, "\\xa8"),
+            s(:regopt, :n)),
+          s(:str, "")),
+        %q{/\xa8/n =~ ""}.force_encoding(Encoding::UTF_8),
+        %{},
+        ALL_VERSIONS - %w(1.8))
+    end
+  end
+
+  #
+  # Error recovery
+  #
+
+  def test_unknown_percent_str
+    assert_diagnoses(
+      [:error, :unexpected_percent_str, { :type => '%k' }],
+      %q{%k[foo]},
+      %q{~~ location})
+  end
+
+  def test_unterminated_embedded_doc
+    assert_diagnoses(
+      [:fatal, :embedded_document],
+      %Q{=begin\nfoo\nend},
+      %q{~~~~~~ location})
+
+    assert_diagnoses(
+      [:fatal, :embedded_document],
+      %Q{=begin\nfoo\nend\n},
+      %q{~~~~~~ location})
+  end
+
+  def test_codepoint_too_large
+    assert_diagnoses(
+      [:error, :unicode_point_too_large],
+      %q{"\u{120 120000}"},
+      %q{        ~~~~~~ location},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_on_error
+    assert_diagnoses(
+      [:error, :unexpected_token, { :token => 'tIDENTIFIER' }],
+      %q{def foo(bar baz); end},
+      %q{            ~~~ location})
+  end
+
+  #
+  # Token and comment extraction
+  #
+
+  def assert_parses_with_comments(ast_pattern, source, comments_pattern)
+    with_versions(ALL_VERSIONS) do |_ver, parser|
+      source_file = Parser::Source::Buffer.new('(comments)')
+      source_file.source = source
+
+      comments_pattern_here = comments_pattern.map do |(from, to)|
+        range = Parser::Source::Range.new(source_file, from, to)
+        Parser::Source::Comment.new(range)
+      end
+
+      ast, comments = parser.parse_with_comments(source_file)
+
+      assert_equal ast_pattern, ast
+
+      assert_equal comments_pattern_here, comments
+    end
+  end
+
+  def test_comment_interleaved
+    assert_parses_with_comments(
+      s(:send, s(:int, 1), :+, s(:int, 2)),
+      %Q{1 + # foo\n 2},
+      [ [4, 9] ])
+  end
+
+  def test_comment_single
+    assert_parses_with_comments(
+      s(:send, nil, :puts),
+      %Q{puts # whatever},
+      [ [5, 15] ])
+  end
+
+  def test_tokenize
+    with_versions(ALL_VERSIONS) do |_ver, parser|
+      source_file = Parser::Source::Buffer.new('(tokenize)')
+      source_file.source = "1 + # foo\n 2"
+
+      range = lambda do |from, to|
+        Parser::Source::Range.new(source_file, from, to)
+      end
+
+      ast, comments, tokens = parser.tokenize(source_file)
+
+      assert_equal s(:send, s(:int, 1), :+, s(:int, 2)),
+                   ast
+
+      assert_equal [
+                     Parser::Source::Comment.new(range.call(4, 9))
+                   ], comments
+
+      assert_equal [
+                     [:tINTEGER, [ 1,       range.call(0, 1) ]],
+                     [:tPLUS,    [ '+',     range.call(2, 3) ]],
+                     [:tCOMMENT, [ '# foo', range.call(4, 9) ]],
+                     [:tINTEGER, [ 2,       range.call(11, 12) ]],
+                   ], tokens
+    end
+  end
+
+  #
+  # Bug-specific tests
+  #
+
+  def test_bug_cmd_string_lookahead
+    assert_parses(
+      s(:block,
+        s(:send, nil, :desc,
+          s(:str, 'foo')),
+        s(:args), nil),
+      %q{desc "foo" do end})
+  end
+
+  def test_bug_do_block_in_call_args
+    # [ruby-core:59342] [Bug #9308]
+    assert_parses(
+      s(:send, nil, :bar,
+        s(:def, :foo,
+          s(:args),
+          s(:block,
+            s(:send, s(:self), :each),
+            s(:args),
+            nil))),
+      %q{bar def foo; self.each do end end},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_bug_do_block_in_cmdarg
+    # [ruby-core:61950] [Bug #9726]
+    assert_parses(
+      s(:send, nil, :tap,
+        s(:begin,
+          s(:block,
+            s(:send, nil, :proc),
+            s(:args), nil))),
+      %q{tap (proc do end)},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_bug_interp_single
+    assert_parses(
+      s(:dstr, s(:begin, s(:int, 1))),
+      %q{"#{1}"})
+
+    assert_parses(
+      s(:array, s(:dstr, s(:begin, s(:int, 1)))),
+      %q{%W"#{1}"})
+  end
+
+  def test_bug_def_no_paren_eql_begin
+    assert_parses(
+      s(:def, :foo, s(:args), nil),
+      %Q{def foo\n=begin\n=end\nend})
+  end
+
+  def test_bug_while_not_parens_do
+    assert_parses(
+      s(:while, s(:send, s(:begin, s(:true)), :"!"), nil),
+      %q{while not (true) do end},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_bug_rescue_empty_else
+    assert_parses(
+      s(:kwbegin,
+        s(:rescue, nil,
+          s(:resbody,
+            s(:array,
+              s(:const, nil, :LoadError)), nil, nil), nil)),
+      %q{begin; rescue LoadError; else; end},
+      %q{                         ~~~~ else (rescue)
+        |       ~~~~~~~~~~~~~~~~~~~~~~ expression (rescue)})
+  end
+
+  def test_bug_heredoc_do
+    assert_parses(
+      s(:block,
+        s(:send, nil, :f,
+          s(:dstr)),
+        s(:args), nil),
+      %Q{f <<-TABLE do\nTABLE\nend})
+  end
+
+  def test_ruby_bug_9669
+    assert_parses(
+      s(:def, :a, s(:args, s(:kwarg, :b)), s(:return)),
+      %Q{def a b:\nreturn\nend},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+
+    assert_parses(
+      s(:lvasgn, :o,
+        s(:hash,
+          s(:pair, s(:sym, :a), s(:int, 1)))),
+      %Q{o = {\na:\n1\n}},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+  end
+
+  def test_ruby_bug_10279
+    assert_parses(
+      s(:hash,
+        s(:pair, s(:sym, :a),
+        s(:if, s(:true), s(:int, 42), nil))),
+      %q{{a: if true then 42 end}},
+      %q{},
+      ALL_VERSIONS - %w(1.8 1.9 2.0))
+  end
+
+  def test_bug_lambda_leakage
+    assert_parses(
+      s(:begin,
+        s(:block,
+          s(:send, nil, :lambda),
+          s(:args,
+            s(:arg, :scope)), nil),
+        s(:send, nil, :scope)),
+      %q{->(scope) {}; scope},
+      %q{},
+      ALL_VERSIONS - %w(1.8))
+  end
+
+  def test_bug_regex_verification
+    assert_parses(
+      s(:regexp, s(:str, "#)"), s(:regopt, :x)),
+      %Q{/#)/x})
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_source_buffer.rb b/app/server/vendor/parser-2.2.2.1/test/test_source_buffer.rb
new file mode 100644
index 0000000..8d68e72
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_source_buffer.rb
@@ -0,0 +1,103 @@
+require 'helper'
+
+class TestSourceBuffer < Minitest::Test
+  def setup
+    @buffer = Parser::Source::Buffer.new('(string)')
+  end
+
+  def test_initialize
+    buffer = Parser::Source::Buffer.new('(string)')
+    assert_equal '(string)', buffer.name
+    assert_equal 1, buffer.first_line
+
+    buffer = Parser::Source::Buffer.new('(string)', 5)
+    assert_equal 5, buffer.first_line
+  end
+
+  def test_source_setter
+    @buffer.source = 'foo'
+    assert_equal 'foo', @buffer.source
+
+    assert @buffer.source.frozen?
+  end
+
+  def test_source_double_setter
+    @buffer.source = 'foo'
+
+    assert_raises(ArgumentError) do
+      @buffer.source = 'bar'
+    end
+  end
+
+  if defined?(Encoding)
+    def test_source_setter_encoding_error
+      error = assert_raises EncodingError do
+        @buffer.source = [
+          '# encoding: utf-8',
+          "# \xf9"
+        ].join("\n")
+      end
+
+      assert_match /invalid byte sequence in UTF\-8/, error.message
+    end
+  end
+
+  def test_read
+    tempfile = Tempfile.new('parser')
+    tempfile.write('foobar')
+    tempfile.flush
+
+    buffer = Parser::Source::Buffer.new(tempfile.path)
+    buffer.read
+    assert_equal 'foobar', buffer.source
+
+    assert buffer.source.frozen?
+  end
+
+  def test_uninitialized
+    assert_raises RuntimeError do
+      @buffer.source
+    end
+  end
+
+  def test_decompose_position
+    @buffer.source = "1\nfoo\nbar"
+
+    assert_equal [1, 0], @buffer.decompose_position(0)
+    assert_equal [1, 1], @buffer.decompose_position(1)
+    assert_equal [2, 0], @buffer.decompose_position(2)
+    assert_equal [3, 1], @buffer.decompose_position(7)
+  end
+
+  def test_decompose_position_mapped
+    @buffer = Parser::Source::Buffer.new('(string)', 5)
+    @buffer.source = "1\nfoo\nbar"
+
+    assert_equal [5, 0], @buffer.decompose_position(0)
+    assert_equal [6, 0], @buffer.decompose_position(2)
+  end
+
+  def test_line
+    @buffer.source = "1\nfoo\nbar"
+
+    assert_equal '1', @buffer.source_line(1)
+    assert_equal 'foo', @buffer.source_line(2)
+  end
+
+  def test_line_mutate
+    @buffer.source = "1\nfoo\nbar"
+
+    assert_equal '1', @buffer.source_line(1)
+
+    @buffer.source_line(1)[0] = '2'
+    assert_equal '1', @buffer.source_line(1)
+  end
+
+  def test_line_mapped
+    @buffer = Parser::Source::Buffer.new('(string)', 5)
+    @buffer.source = "1\nfoo\nbar"
+
+    assert_equal '1', @buffer.source_line(5)
+    assert_equal 'foo', @buffer.source_line(6)
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_source_comment.rb b/app/server/vendor/parser-2.2.2.1/test/test_source_comment.rb
new file mode 100644
index 0000000..06e4738
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_source_comment.rb
@@ -0,0 +1,34 @@
+require 'helper'
+
+class TestSourceComment < Minitest::Test
+  def setup
+    @buf = Parser::Source::Buffer.new('(string)')
+    @buf.source = "# foo\n=begin foo\nbar\n=end baz\n"
+  end
+
+  def range(s, e)
+    Parser::Source::Range.new(@buf, s, e)
+  end
+
+  def test_initialize
+    comment = Parser::Source::Comment.new(range(0, 5))
+    assert comment.frozen?
+  end
+
+  def test_text
+    comment = Parser::Source::Comment.new(range(0, 5))
+    assert_equal '# foo', comment.text
+  end
+
+  def test_inline
+    comment = Parser::Source::Comment.new(range(0, 5))
+    assert_equal :inline, comment.type
+    assert comment.inline?
+  end
+
+  def test_document
+    comment = Parser::Source::Comment.new(range(6, 25))
+    assert_equal :document, comment.type
+    assert comment.document?
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_source_comment_associator.rb b/app/server/vendor/parser-2.2.2.1/test/test_source_comment_associator.rb
new file mode 100644
index 0000000..8319e06
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_source_comment_associator.rb
@@ -0,0 +1,208 @@
+require 'helper'
+require 'parser/ruby18'
+
+class TestSourceCommentAssociator < Minitest::Test
+  def parse_with_comments(code)
+    parser = Parser::Ruby18.new
+
+    buffer = Parser::Source::Buffer.new('(comments)')
+    buffer.source = code
+
+    parser.parse_with_comments(buffer)
+  end
+
+  def associate(code)
+    ast, comments = parse_with_comments(code)
+    associations  = Parser::Source::Comment.associate(ast, comments)
+
+    [ ast, associations ]
+  end
+
+  def associate_locations(code)
+    ast, comments = parse_with_comments(code)
+    associations  = Parser::Source::Comment.associate_locations(ast, comments)
+
+    [ ast, associations ]
+  end
+
+  def test_associate
+    ast, associations = associate(<<-END)
+#!/usr/bin/env ruby
+# coding: utf-8
+# Class comment
+# another class comment
+class Foo
+  # attr_accessor comment
+  attr_accessor :foo
+
+  # method comment
+  def bar
+    # expr comment
+    1 + # intermediate comment
+      2
+    # stray comment
+  end
+end
+    END
+
+    klass_node         = ast
+    attr_accessor_node = ast.children[2].children[0]
+    method_node        = ast.children[2].children[1] # def bar
+    expr_node          = method_node.children[2] # 1 + 2
+    intermediate_node  = expr_node.children[0] # 1
+
+    assert_equal 5, associations.size
+    assert_equal ['# Class comment', '# another class comment'],
+                 associations[klass_node].map(&:text)
+    assert_equal ['# attr_accessor comment'],
+                 associations[attr_accessor_node].map(&:text)
+    assert_equal ['# method comment'],
+                 associations[method_node].map(&:text)
+    assert_equal ['# expr comment', "# stray comment"],
+                 associations[expr_node].map(&:text)
+    assert_equal ['# intermediate comment'],
+                 associations[intermediate_node].map(&:text)
+  end
+
+  # The bug below is fixed by using associate_locations
+  def test_associate_dupe_statement
+    ast, associations = associate(<<-END)
+class Foo
+  def bar
+    f1 # comment on 1st call to f1
+    f2
+    f1 # comment on 2nd call to f1
+  end
+end
+    END
+
+    klass_node         = ast
+    method_node        = ast.children[2]
+    body               = method_node.children[2]
+    f1_1_node          = body.children[0]
+    f1_2_node          = body.children[2]
+
+    assert_equal 1, associations.size
+    assert_equal ['# comment on 1st call to f1', '# comment on 2nd call to f1'],
+                 associations[f1_1_node].map(&:text)
+    assert_equal ['# comment on 1st call to f1', '# comment on 2nd call to f1'],
+                 associations[f1_2_node].map(&:text)
+  end
+
+  def test_associate_locations
+    ast, associations = associate_locations(<<-END)
+#!/usr/bin/env ruby
+# coding: utf-8
+# Class comment
+# another class comment
+class Foo
+  # attr_accessor comment
+  attr_accessor :foo
+
+  # method comment
+  def bar
+    # expr comment
+    1 + # intermediate comment
+      2
+    # stray comment
+  end
+end
+    END
+
+    klass_node         = ast
+    attr_accessor_node = ast.children[2].children[0]
+    method_node        = ast.children[2].children[1]
+    expr_node          = method_node.children[2]
+    intermediate_node  = expr_node.children[0]
+
+    assert_equal 5, associations.size
+    assert_equal ['# Class comment', '# another class comment'],
+                 associations[klass_node.loc].map(&:text)
+    assert_equal ['# attr_accessor comment'],
+                 associations[attr_accessor_node.loc].map(&:text)
+    assert_equal ['# method comment'],
+                 associations[method_node.loc].map(&:text)
+    assert_equal ['# expr comment', '# stray comment'],
+                 associations[expr_node.loc].map(&:text)
+    assert_equal ['# intermediate comment'],
+                 associations[intermediate_node.loc].map(&:text)
+  end
+
+  def test_associate_locations_dupe_statement
+    ast, associations = associate_locations(<<-END)
+class Foo
+  def bar
+    f1 # comment on 1st call to f1
+    f2
+    f1 # comment on 2nd call to f1
+  end
+end
+    END
+
+    klass_node         = ast
+    method_node        = ast.children[2]
+    body               = method_node.children[2]
+    f1_1_node          = body.children[0]
+    f1_2_node          = body.children[2]
+
+    assert_equal 2, associations.size
+    assert_equal ['# comment on 1st call to f1'],
+                 associations[f1_1_node.loc].map(&:text)
+    assert_equal ['# comment on 2nd call to f1'],
+                 associations[f1_2_node.loc].map(&:text)
+  end
+
+  def test_associate_no_body
+    ast, associations = associate(<<-END)
+# foo
+class Foo
+end
+    END
+
+    assert_equal 1, associations.size
+    assert_equal ['# foo'],
+                 associations[ast].map(&:text)
+  end
+
+  def test_associate_shebang_only
+    ast, associations = associate(<<-END)
+#!ruby
+class Foo
+end
+    END
+
+    assert_equal 0, associations.size
+  end
+
+  def test_associate_no_comments
+    ast, associations = associate(<<-END)
+class Foo
+end
+    END
+
+    assert_equal 0, associations.size
+  end
+
+  def test_associate_stray_comment
+    ast, associations = associate(<<-END)
+def foo
+  # foo
+end
+    END
+
+    assert_equal 1, associations.size
+    assert_equal ['# foo'],
+                 associations[ast].map(&:text)
+  end
+
+  def test_associate___ENCODING__
+    ast, associations = associate(<<-END)
+# foo
+__ENCODING__
+    END
+
+    assert_equal 1, associations.size
+    assert_equal ['# foo'],
+                 associations[ast].map(&:text)
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_source_range.rb b/app/server/vendor/parser-2.2.2.1/test/test_source_range.rb
new file mode 100644
index 0000000..7a17c2e
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_source_range.rb
@@ -0,0 +1,77 @@
+require 'helper'
+
+class TestSourceRange < Minitest::Test
+  def setup
+    @buf = Parser::Source::Buffer.new('(string)')
+    @buf.source = "foobar\nbaz"
+  end
+
+  def test_initialize
+    sr = Parser::Source::Range.new(@buf, 1, 2)
+    assert_equal 1, sr.begin_pos
+    assert_equal 2, sr.end_pos
+    assert sr.frozen?
+  end
+
+  def test_size
+    sr = Parser::Source::Range.new(@buf, 1, 3)
+    assert_equal 2, sr.size
+  end
+
+  def test_join
+    sr1 = Parser::Source::Range.new(@buf, 1, 2)
+    sr2 = Parser::Source::Range.new(@buf, 5, 8)
+    sr = sr1.join(sr2)
+
+    assert_equal 1, sr.begin_pos
+    assert_equal 8, sr.end_pos
+  end
+
+  def test_line
+    sr = Parser::Source::Range.new(@buf, 7, 8)
+    assert_equal 2, sr.line
+  end
+
+  def test_source_line
+    sr = Parser::Source::Range.new(@buf, 7, 8)
+    assert_equal 'baz', sr.source_line
+  end
+
+  def test_columns
+    sr = Parser::Source::Range.new(@buf, 7, 8)
+    assert_equal 0, sr.begin.column
+    assert_equal 1, sr.end.column
+    assert_equal 0...1, sr.column_range
+  end
+
+  def test_begin_end
+    sr = Parser::Source::Range.new(@buf, 1, 5)
+
+    sr_beg = sr.begin
+    assert_equal 1, sr_beg.begin_pos
+    assert_equal 1, sr_beg.end_pos
+
+    sr_end = sr.end
+    assert_equal 5, sr_end.begin_pos
+    assert_equal 5, sr_end.end_pos
+  end
+
+  def test_source
+    sr = Parser::Source::Range.new(@buf, 0, 3)
+    assert_equal 'foo', sr.source
+
+    sr_multi = Parser::Source::Range.new(@buf, 0, 10)
+    assert_equal "foobar\nbaz", sr_multi.source
+  end
+
+  def test_is?
+    sr = Parser::Source::Range.new(@buf, 0, 3)
+    assert sr.is?('foo')
+    refute sr.is?('bar')
+  end
+
+  def test_to_s
+    sr = Parser::Source::Range.new(@buf, 8, 9)
+    assert_equal '(string):2:2', sr.to_s
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_source_rewriter.rb b/app/server/vendor/parser-2.2.2.1/test/test_source_rewriter.rb
new file mode 100644
index 0000000..e70e15a
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_source_rewriter.rb
@@ -0,0 +1,183 @@
+require 'helper'
+
+class TestSourceRewriter < Minitest::Test
+  def setup
+    @buf = Parser::Source::Buffer.new('(rewriter)')
+    @buf.source = 'foo bar baz'
+
+    @rewriter = Parser::Source::Rewriter.new(@buf)
+  end
+
+  def range(from, len)
+    Parser::Source::Range.new(@buf, from, from + len)
+  end
+
+  def test_remove
+    assert_equal 'foo  baz',
+                 @rewriter.
+                    remove(range(4, 3)).
+                    process
+  end
+
+  def test_insert_before
+    assert_equal 'foo quux bar baz',
+                 @rewriter.
+                    insert_before(range(4, 3), 'quux ').
+                    process
+  end
+
+  def test_insert_after
+    assert_equal 'foo bar quux baz',
+                 @rewriter.
+                    insert_after(range(4, 3), ' quux').
+                    process
+  end
+
+  def test_replace
+    assert_equal 'foo quux baz',
+                 @rewriter.
+                    replace(range(4, 3), 'quux').
+                    process
+  end
+
+  def test_composing_asc
+    assert_equal 'foo---bar---baz',
+                 @rewriter.
+                    replace(range(3, 1), '---').
+                    replace(range(7, 1), '---').
+                    process
+  end
+
+  def test_composing_desc
+    assert_equal 'foo---bar---baz',
+                 @rewriter.
+                    replace(range(7, 1), '---').
+                    replace(range(3, 1), '---').
+                    process
+  end
+
+  def test_multiple_insertions_at_same_location
+    assert_equal '<([foo] bar) baz>',
+                 @rewriter.
+                   insert_before(range(0, 11), '<').
+                   insert_after( range(0, 11), '>').
+                   insert_before(range(0, 7), '(').
+                   insert_after( range(0, 7), ')').
+                   insert_before(range(0, 3), '[').
+                   insert_after( range(0, 3), ']').
+                   process
+  end
+
+  def test_clobber
+    diagnostics = []
+    @rewriter.diagnostics.consumer = lambda do |diag|
+      diagnostics << diag
+    end
+
+    assert_raises Parser::ClobberingError do
+      @rewriter.
+        replace(range(3, 1), '---').
+        remove(range(3, 1))
+    end
+
+    assert_equal 2, diagnostics.count
+
+    assert_equal :error, diagnostics.first.level
+    assert_equal 'cannot remove 1 character(s)',
+                 diagnostics.first.message
+    assert_equal range(3, 1), diagnostics.first.location
+
+    assert_equal :note, diagnostics.last.level
+    assert_equal "clobbered by: replace 1 character(s) with \"---\"",
+                 diagnostics.last.message
+    assert_equal range(3, 1), diagnostics.last.location
+  end
+
+  def test_clobbering_error_backward_compatibility
+    silence_diagnostics
+
+    rescued = false
+
+    # We use begin..rescue..end here rather than #assert_raises
+    # since #assert_raises expects exact error class.
+    begin
+      @rewriter.
+        replace(range(3, 1), '---').
+        remove(range(3, 1))
+    rescue RuntimeError => error
+      rescued = true if error.message.include?('clobber')
+    end
+
+    assert rescued
+  end
+
+  def test_transaction_returns_self
+    assert_equal @rewriter, @rewriter.transaction {}
+  end
+
+  def test_transaction_commit
+    silence_diagnostics
+
+    # Original: 'foo bar baz'
+
+    # Rewrite as 'foo BAR baz'
+    @rewriter.replace(range(4, 3), 'BAR')
+
+    # Rewrite as '( bar )'
+    @rewriter.transaction do
+      @rewriter.replace(range(0, 3), '(')
+      @rewriter.replace(range(8, 3), ')')
+    end
+
+    @rewriter.replace(range(3, 1), '_')
+    @rewriter.replace(range(7, 1), '_')
+
+    assert_equal '(_BAR_)', @rewriter.process
+  end
+
+  def test_transaction_rollback
+    silence_diagnostics
+
+    # Original: 'foo bar baz'
+
+    # Rewrite as 'foo bar BAZ'
+    @rewriter.replace(range(8, 3), 'BAZ')
+
+    assert_raises Parser::ClobberingError do
+      # Trying to rewrite as '( bar )', but it fails
+      @rewriter.transaction do
+        @rewriter.replace(range(0, 3), '(')
+        @rewriter.replace(range(8, 3), ')')
+      end
+    end
+
+    @rewriter.replace(range(0, 3), 'FOO')
+
+    assert_equal 'FOO bar BAZ', @rewriter.process
+  end
+
+  def test_nested_transaction_raises_error
+    error = assert_raises RuntimeError do
+      @rewriter.transaction do
+        @rewriter.transaction do
+        end
+      end
+    end
+
+    assert_match /nested/i, error.message
+  end
+
+  def test_process_in_transaction_raises_error
+    error = assert_raises RuntimeError do
+      @rewriter.transaction do
+        @rewriter.process
+      end
+    end
+
+    assert_match /transaction/, error.message
+  end
+
+  def silence_diagnostics
+    @rewriter.diagnostics.consumer = proc {}
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_source_rewriter_action.rb b/app/server/vendor/parser-2.2.2.1/test/test_source_rewriter_action.rb
new file mode 100644
index 0000000..a0a16a0
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_source_rewriter_action.rb
@@ -0,0 +1,44 @@
+require 'helper'
+
+class TestSourceRewriterAction < Minitest::Test
+  def setup
+    @buf = Parser::Source::Buffer.new('(rewriter_action)')
+    @buf.source = 'foo bar baz'
+  end
+
+  def range(from, len)
+    Parser::Source::Range.new(@buf, from, from + len)
+  end
+
+  def action(range, replacement)
+    Parser::Source::Rewriter::Action.new(range, replacement)
+  end
+
+  def test_accessors
+    action = action(range(1, 10), 'foo')
+
+    assert action.frozen?
+    assert_equal range(1, 10), action.range
+    assert_equal 'foo',        action.replacement
+  end
+
+  def test_to_s_replace
+    action = action(range(3, 1), 'foo')
+    assert_equal "replace 1 character(s) with \"foo\"", action.to_s
+  end
+
+  def test_to_s_insert
+    action = action(range(3, 0), 'foo')
+    assert_equal "insert \"foo\"", action.to_s
+  end
+
+  def test_to_s_remove
+    action = action(range(3, 2), '')
+    assert_equal 'remove 2 character(s)', action.to_s
+  end
+
+  def test_to_s_nop
+    action = action(range(3, 0), '')
+    assert_equal 'do nothing', action.to_s
+  end
+end
diff --git a/app/server/vendor/parser-2.2.2.1/test/test_static_environment.rb b/app/server/vendor/parser-2.2.2.1/test/test_static_environment.rb
new file mode 100644
index 0000000..59678e0
--- /dev/null
+++ b/app/server/vendor/parser-2.2.2.1/test/test_static_environment.rb
@@ -0,0 +1,43 @@
+require 'helper'
+
+class TestStaticEnvironment < Minitest::Test
+  def setup
+    @env = Parser::StaticEnvironment.new
+  end
+
+  def test_declare
+    refute @env.declared?(:foo)
+
+    @env.declare :foo
+
+    assert @env.declared?(:foo)
+  end
+
+  def test_extend_static
+    @env.declare :foo
+    @env.extend_static
+    @env.declare :bar
+
+    refute @env.declared?(:foo)
+    assert @env.declared?(:bar)
+  end
+
+  def test_extend_dynamic
+    @env.declare :foo
+    @env.extend_dynamic
+    @env.declare :bar
+
+    assert @env.declared?(:foo)
+    assert @env.declared?(:bar)
+  end
+
+  def test_unextend
+    @env.declare :foo
+    @env.extend_dynamic
+    @env.declare :bar
+    @env.unextend
+
+    assert @env.declared?(:foo)
+    refute @env.declared?(:bar)
+  end
+end
diff --git a/app/server/vendor/parslet/.gitignore b/app/server/vendor/parslet/.gitignore
new file mode 100755
index 0000000..4c957fc
--- /dev/null
+++ b/app/server/vendor/parslet/.gitignore
@@ -0,0 +1,11 @@
+today
+Gemfile.lock
+*.gem
+website/.sass-cache
+.yardoc
+test.rb
+.rspec
+.bundle
+doc
+pkg
+rdoc
diff --git a/app/server/vendor/parslet/.travis.yml b/app/server/vendor/parslet/.travis.yml
new file mode 100755
index 0000000..0c2ad3a
--- /dev/null
+++ b/app/server/vendor/parslet/.travis.yml
@@ -0,0 +1,7 @@
+language: ruby
+rvm: 
+  - 1.9.3
+  # The rubies below all fail. 
+  # - jruby-19mode # JRuby in 1.9 mode
+  # - rbx-18mode
+  # - rbx-19mode
diff --git a/app/server/vendor/parslet/Gemfile b/app/server/vendor/parslet/Gemfile
new file mode 100755
index 0000000..8871e00
--- /dev/null
+++ b/app/server/vendor/parslet/Gemfile
@@ -0,0 +1,12 @@
+source "http://rubygems.org"
+
+gemspec
+
+group :development do
+  %w(rspec flexmock rdoc sdoc 
+    guard guard-rspec guard-simple_shell 
+    rb-fsevent growl rake 
+    qed ae).
+    each { |gem_name| 
+      gem gem_name }
+end
diff --git a/app/server/vendor/parslet/Guardfile b/app/server/vendor/parslet/Guardfile
new file mode 100755
index 0000000..e7c2ea8
--- /dev/null
+++ b/app/server/vendor/parslet/Guardfile
@@ -0,0 +1,8 @@
+guard 'rspec', :version => 2 do
+  watch(%r(^spec/(.*)_spec.rb))
+  watch(%r(^lib/(.*)\.rb))                { |m| "spec/#{m[1]}_spec.rb" }
+  watch('spec/spec_helper.rb')            { "spec" }
+
+	watch(%r'^lib/parslet/bytecode/(.*)\.rb') { 'spec/acceptance/vm_spec.rb' }
+	watch(%r'^lib/parslet/pattern/(.*)\.rb') { 'spec/parslet/pattern_spec.rb' }
+end
diff --git a/app/server/vendor/parslet/HISTORY.txt b/app/server/vendor/parslet/HISTORY.txt
new file mode 100755
index 0000000..d978f1c
--- /dev/null
+++ b/app/server/vendor/parslet/HISTORY.txt
@@ -0,0 +1,229 @@
+= 2.0 / ?? (future release changes, like a reminder to self)
+  
+  - prsnt? and absnt? are now finally banned into oblivion. Wasting vocals for
+    the win. 
+
+= 1.6 / ??
+
+  + Parslet accelerators permit replacing parts of your parser with optimized
+    atoms using pattern matching. Look at examples/optimized_erb.rb or the
+    introduction to the feature in qed/accelerators.md.
+
+  + infix_expression permits to declare an infix expression parser (think 
+    calculator) directly. This will solve many of the problems we have 
+    more elegantly. 
+
+  - Drops 1.8.7 compatibility. 
+
+  ! A performance anomaly when parsing multibyte characters has been detected
+    and fixed with the help of Zach Moazeni (@zmoazeni).
+
+  ! A few small bug fixes and optimisations have been introduced. API should 
+    remain unchanged. 
+    
+= 1.5 / 27Dec2012
+    
+  + Handles unconsumed input at end of parse completely differently. Instead
+    of generating a toplevel error, it now raises an error in every branch
+    of the parse. More information in the resulting exception ensues! Thanks
+    again to John Mettraux for inspiration & acceptance specs. 
+    
+    NOTE that this means that the UnconsumedInput exception is gone, since the
+    unconsumed input case is nothing special anymore. 
+    
+  * This history now finally reads like the Changelog of the linux kernel. 
+    Meaning that probably no one ever reads this. 
+    
+  + Captures and parsing subsequent input based on captured values. This has
+    been long overdue - finally you can parse HEREdocs with parslet!
+    
+= 1.4.0 / 25May2012
+
+  + Revised documentation. A few new API features have finally made it into
+    the documentation. Examples in the documentation are now curated and
+    run against the current code so that they really really work. 
+    Also, the website generation tools have been replaced with 2012-style
+    tools. Much less pain to update now. 
+
+  + Parslet::Source now doesn't hold a StringIO, it directly holds the 
+    buffer to be parsed. The api of Source has changed a tiny bit. This change
+    has been made for speed optimisation reasons.
+
+  + :reporter argument to parse, allowing to customize error reporting within
+    wide boundaries. See issue #64 for a discussion. 
+    Included are two error reporters, one (default) with the existing error
+    tree functionality, one reporting deepest errors as defined by the above
+    ticket.
+
+  + Optimistic parse: Parsing is two phase, with the first phase assuming 
+    there will be no errors. This yields ~ 20% speed improvement in the 
+    case where the parse succeeds.
+    Also, internal error handling is now using tuples. This and other 
+    optimizations have yielded ~ 30% overall improvement. 
+
+  ! #error_tree and #cause removed from all of parslet. The 
+    Parslet::ParseFailed exception now contains a #cause field that can
+    be asked for an #ascii_tree as before. 
+    Cleaner internal error handling, not stateful in atoms anymore. Some 
+    parsers will see correct error reporting for the first time. (issue #65)
+
+  + Made it possible to pass a custom Parslet::Source implementor to #parse.
+    (see #63)
+    
+  + #parse has now a second argument that is an options hash. See 
+    Parslet::Atoms::Base#parse for documentation.
+
+  - VM engine on the way out. No benefit except for the intellectual
+    challenge.
+    
+= 1.3.0 / 5Mar2012
+
+  ! Parslet::Transform::Context is now much more well-behaved. It has
+    #respond_to? and #method_missing; it now looks like a plain old Ruby
+    object with instance variables and attribute readers.
+
+  - Grammar transforms turned out to be a dead end and have been removed. 
+
+  ! A few problems in error message generation have been fixed. This will
+  	improve diagnostics further.
+	
+  + A VM driven parser engine: Removes the limitation that parsing needs a 
+    lot of stack space, something dearly missing from Ruby 1.9.3 fibers.
+    This engine is experimental and might be removed in the future. 
+
+  ! Interaction with mathn fixed - Line number generation will terminate. 
+	
+  . Internal reorganisation, removing cruft and bit rot.
+    
+= 1.2.3 / 22Sep2011
+
+  + Transform#apply can now be called with a hash as second argument. This 
+    provides bindings and a way to inject context.
+
+  ! Fixes a bug thar modified parslet atoms in place, defeating oop chaining. 
+    (#50)
+    
+= 1.2.1 / 6Jun2011
+
+  ! FIX: Input at the end of a parse raises Parslet::UnconsumedInput. (see
+    issue 18)
+
+  ! FIX: Unicode parsing should now work as expected. (see issue 38)
+  
+  ! FIX: Slice#slice returned wrong bits at times (see issue 36).
+
+= 1.2.0 / 4Feb2011
+  
+  + Parslet::Parser is now also a grammar atom, it can be composed freely with
+    other atoms. (str('f') >> MiniLispParser.new >> str('b'))
+    
+  + No strings, only slices are returned as part of the parser result. 
+    Parslet::Slice is almost a string class, but one that remembers the 
+    source offset. This has also bought us a slight speedup.
+    
+  + require 'parslet/convenience' now brings #parse_with_debug to all parslets.
+    This is a consequence of the above change. 
+  
+  + Deprecates prsnt? and absnt? in favor of the more readable absent? and
+    prsnt?. Uses 3 bytes more RAM. The old variants will exist until we release
+    2.0. 
+  
+  INTERNALLY
+  
+  + Visitors now should have methods that all begin with 'visit_*'. #str 
+    becomes #visit_str.
+
+  + Parslet::Atoms::Entity now takes only a block argument instead of context
+    and block. 
+
+= 1.1.1 / 4Feb2011
+
+  ! FIX: Line counting was broken by performance optimisations. 
+  
+  + Squeezed out another few drops of performance. 
+
+= 1.1.0 / 2Feb2011
+  
+  + Uses return (fail/success), cached line counts, memoizing of parse results 
+    and other tricks internally for at least an order of magnitude increase 
+    in execution speed.
+    
+  + str('foo').maybe will now return an empty string again. Use .as(...) to 
+    name things and get back [] from #repeat and nil from #maybe.
+    
+  + If you require 'parslet/atoms/visitor', you'll get an accept method on
+    all known Parslet::Atoms.
+    
+  + If you require 'parslet/export', you can call #to_citrus and #to_treetop
+    to produce string versions of your grammar in those dialects.
+  
+  + Requiring 'parslet/convenience' will given you a parse_with_debug on 
+    your Parslet::Parser class. This prints some diagnostics on parse failure. 
+    (Thanks to Florian Hanke)
+        
+= 1.0.1 / 17Jan2011
+
+  A happy new year!
+  
+  ! FIX: Parslet::Transform was wrongly fixed earlier - it now wont mangle 
+    hashes anymore. (Blake Sweeney)
+    
+  + parslet/rig/rspec.rb contains useful rspec matchers. (R. Konstantin Haase)
+
+= 1.0.0 / 29Dez2010
+
+  - #each_match was removed. There was some duplication of code that even 
+    confused me - and we should not have 2 methods of achieving the same
+    goal. 
+    
+  + Full documentation. Fixed sdoc. 
+
+= 0.11.0 / 25Nov2010
+
+  ! Bugfixes to tree handling. Let's hope that was the last such significant
+    change to the core.
+
+= 0.10.1 / 22Nov2010
+
+  + Allow match['a-z'], shortcut for match('[a-z]')
+
+  ! Fixed output inconsistencies (behaviour in connection to 'maybe')
+
+= 0.10.0 / 22Nov2010
+
+  + Parslet::Transform now takes a block on initialisation, wherein you can
+    define all the rules directly.
+    
+  + Parslet::Transform now only passes a hash to the block during transform
+    when its arity is 1. Otherwise all hash contents as bound as local     
+    variables.
+    
+  + Both inline and other documentation have been improved. 
+  
+  + You can now use 'subtree(:x)' to bind any subtree to x during tree pattern
+    matching. 
+    
+  + Transform classes can now include rules into class definition. This makes
+    Parser and Transformer behave the same. 
+  
+= 0.9.0 / 28Oct2010
+  * More of everything: Examples, documentation, etc...
+
+  * Breaking change: Ruby's binary or ('|') is now used for alternatives, 
+    instead of the division sign ('/') - this reduces the amount of 
+    parenthesis needed for a grammar overall. 
+
+  * parslet.maybe now yields the result or nil in case of parse failure. This
+    is probably better than the array it did before; the jury is still out on
+    that. 
+    
+  * parslet.repeat(min, max) is now valid syntax
+
+= 0.1.0 / not released.
+
+  * Initial version. Classes for parsing, matching in the resulting trees
+    and transforming the trees into something more useful.  
+    
+  * Parses and outputs intermediary trees
+    
+  * Matching of single elements and sequences
\ No newline at end of file
diff --git a/app/server/vendor/parslet/LICENSE b/app/server/vendor/parslet/LICENSE
new file mode 100755
index 0000000..7384060
--- /dev/null
+++ b/app/server/vendor/parslet/LICENSE
@@ -0,0 +1,22 @@
+ Copyright (c) 2010-2014 Kaspar Schiess
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/parslet/README b/app/server/vendor/parslet/README
new file mode 100755
index 0000000..90444b1
--- /dev/null
+++ b/app/server/vendor/parslet/README
@@ -0,0 +1,73 @@
+INTRODUCTION
+
+Parslet makes developing complex parsers easy. It does so by
+
+* providing the best error reporting possible
+* not generating reams of code for you to debug
+
+Parslet takes the long way around to make your job easier. It allows for
+incremental language construction. Often, you start out small, implementing
+the atoms of your language first; _parslet_ takes pride in making this
+possible.
+
+Eager to try this out? Please see the associated web site:
+http://kschiess.github.com/parslet
+
+SYNOPSIS
+
+  require 'parslet'
+  include Parslet
+
+  # parslet parses strings
+  str('foo').
+    parse('foo') # => "foo"@0
+
+  # it matches character sets
+  match['abc'].parse('a') # => "a"@0
+  match['abc'].parse('b') # => "b"@0
+  match['abc'].parse('c') # => "c"@0
+
+  # and it annotates its output
+  str('foo').as(:important_bit).
+    parse('foo') # => {:important_bit=>"foo"@0}
+
+  # you can construct parsers with just a few lines
+  quote = str('"')
+  simple_string = quote >> (quote.absent? >> any).repeat >> quote
+
+  simple_string.
+    parse('"Simple Simple Simple"') # => "\"Simple Simple Simple\""@0
+
+  # or by making a fuss about it 
+  class Smalltalk < Parslet::Parser
+    root :smalltalk
+
+    rule(:smalltalk) { statements }
+    rule(:statements) { 
+      # insert smalltalk parser here (outside of the scope of this readme)
+    }
+  end
+
+  # and then
+  Smalltalk.new.parse('smalltalk')
+
+FEATURES
+
+  * Tools for every part of the parser chain
+  * Transformers generate Abstract Syntax Trees
+  * Accelerators transform parsers, making them quite a bit faster
+  * Pluggable error reporters
+  * Graphviz export for your parser
+  * Rspec testing support rig
+  * Simply Ruby, composable and hackable
+
+COMPATIBILITY
+
+This library is intended to work with Ruby variants >= 1.9. I've tested it on 
+MRI 1.9, rbx-head, jruby. Please report as a bug if you encounter issues.
+
+STATUS 
+
+Production worthy.
+
+(c) 2010-2014 Kaspar Schiess
diff --git a/app/server/vendor/parslet/Rakefile b/app/server/vendor/parslet/Rakefile
new file mode 100755
index 0000000..cf39b82
--- /dev/null
+++ b/app/server/vendor/parslet/Rakefile
@@ -0,0 +1,30 @@
+require 'rdoc/task'
+require 'sdoc'
+
+require 'rspec/core/rake_task'
+require "rubygems/package_task"
+
+desc "Run all tests: Exhaustive."
+RSpec::Core::RakeTask.new
+
+namespace :spec do
+  desc "Only run unit tests: Fast. "
+  RSpec::Core::RakeTask.new(:unit) do |task|
+    task.pattern = "spec/parslet/**/*_spec.rb"
+  end
+end
+
+task :default => :spec
+
+# This task actually builds the gem. 
+task :gem => :spec
+spec = eval(File.read('parslet.gemspec'))
+
+desc "Prints LOC stats"
+task :stat do
+  %w(lib spec example).each do |dir|
+    loc = %x(find #{dir} -name "*.rb" | xargs wc -l | grep 'total').split.first.to_i
+    printf("%20s %d\n", dir, loc)
+  end
+end
+
diff --git a/app/server/vendor/parslet/example/big.erb b/app/server/vendor/parslet/example/big.erb
new file mode 100755
index 0000000..6a36800
--- /dev/null
+++ b/app/server/vendor/parslet/example/big.erb
@@ -0,0 +1,73 @@
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
+proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
+proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
+proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
+proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
+proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
+proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+
+<%= erb tag %>
+
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
+proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
+proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
+proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
+proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
+proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
+proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
diff --git a/app/server/vendor/parslet/example/boolean_algebra.rb b/app/server/vendor/parslet/example/boolean_algebra.rb
new file mode 100755
index 0000000..bea8634
--- /dev/null
+++ b/app/server/vendor/parslet/example/boolean_algebra.rb
@@ -0,0 +1,70 @@
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require "parslet"
+require "pp"
+
+# Parses strings like "var1 and (var2 or var3)" respecting operator precedence
+# and parentheses. After that transforms the parse tree into an array of
+# arrays like this:
+#
+# [["1", "2"], ["1", "3"]]
+#
+# The array represents a DNF (disjunctive normal form). Elements of outer
+# array are connected with "or" operator, while elements of inner arrays are
+# joined with "and".
+#
+class Parser < Parslet::Parser
+  rule(:space)  { match[" "].repeat(1) }
+  rule(:space?) { space.maybe }
+
+  rule(:lparen) { str("(") >> space? }
+  rule(:rparen) { str(")") >> space? }
+
+  rule(:and_operator) { str("and") >> space? }
+  rule(:or_operator)  { str("or")  >> space? }
+
+  rule(:var) { str("var") >> match["0-9"].repeat(1).as(:var) >> space? }
+
+  # The primary rule deals with parentheses.
+  rule(:primary) { lparen >> or_operation >> rparen | var }
+
+  # Note that following rules are both right-recursive.
+  rule(:and_operation) { 
+    (primary.as(:left) >> and_operator >> 
+      and_operation.as(:right)).as(:and) | 
+    primary }
+    
+  rule(:or_operation)  { 
+    (and_operation.as(:left) >> or_operator >> 
+      or_operation.as(:right)).as(:or) | 
+    and_operation }
+
+  # We start at the lowest precedence rule.
+  root(:or_operation)
+end
+
+class Transformer < Parslet::Transform
+  rule(:var => simple(:var)) { [[String(var)]] }
+
+  rule(:or => { :left => subtree(:left), :right => subtree(:right) }) do
+    (left + right)
+  end
+
+  rule(:and => { :left => subtree(:left), :right => subtree(:right) }) do
+     res = []
+     left.each do |l|
+       right.each do |r|
+         res << (l + r)
+       end
+     end
+     res
+  end
+end
+
+pp tree = Parser.new.parse("var1 and (var2 or var3)")
+# {:and=>
+#   {:left=>{:var=>"1"@3},
+#    :right=>{:or=>{:left=>{:var=>"2"@13}, :right=>{:var=>"3"@21}}}}}
+pp Transformer.new.apply(tree)
+# [["1", "2"], ["1", "3"]]
+
diff --git a/app/server/vendor/parslet/example/calc.rb b/app/server/vendor/parslet/example/calc.rb
new file mode 100755
index 0000000..541d7a5
--- /dev/null
+++ b/app/server/vendor/parslet/example/calc.rb
@@ -0,0 +1,153 @@
+# A simple integer calculator to answer the question about how to do 
+# left and right associativity in parslet (PEG) once and for all. 
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'rspec'
+require 'parslet'
+require 'parslet/rig/rspec'
+
+# This is the parsing stage. It expresses left associativity by compiling
+# list of things that have the same associativity. 
+class CalcParser < Parslet::Parser
+  root :addition
+  
+  rule(:addition) {
+    multiplication.as(:l) >> (add_op >> multiplication.as(:r)).repeat(1) |
+    multiplication
+  }
+  
+  rule(:multiplication) { 
+    integer.as(:l) >> (mult_op >> integer.as(:r)).repeat(1) |
+    integer }
+  
+  rule(:integer) { digit.repeat(1).as(:i) >> space? }
+
+  rule(:mult_op) { match['*/'].as(:o) >> space? }
+  rule(:add_op) { match['+-'].as(:o) >> space? }
+
+  rule(:digit) { match['0-9'] }
+  rule(:space?) { match['\s'].repeat }
+end
+
+# Classes for the abstract syntax tree.
+Int    = Struct.new(:int) {
+  def eval; self end
+  def op(operation, other)
+    left = int
+    right = other.int 
+
+    Int.new(
+      case operation
+        when '+'
+          left + right
+        when '-'
+          left - right
+        when '*'
+          left * right
+        when '/'
+          left / right
+      end)
+  end
+  def to_i
+    int
+  end
+}
+Seq    = Struct.new(:sequence) {
+  def eval
+    sequence.reduce { |accum, operation| 
+      operation.call(accum) }
+  end
+}
+LeftOp = Struct.new(:operation, :right) {
+  def call(left)
+    left = left.eval
+    right = self.right.eval
+
+    left.op(operation, right)
+  end
+}
+
+# Transforming intermediary syntax tree into a real AST.
+class CalcTransform < Parslet::Transform
+  rule(i: simple(:i)) { Int.new(Integer(i)) }
+  rule(o: simple(:o), r: simple(:i)) { LeftOp.new(o, i) }
+  rule(l: simple(:i)) { i }
+  rule(sequence(:seq)) { Seq.new(seq) }
+end
+
+# And this calls everything in the right order.
+def calculate(str)
+  intermediary_tree = CalcParser.new.parse(str)
+  abstract_tree = CalcTransform.new.apply(intermediary_tree)
+  result = abstract_tree.eval
+  
+  result.to_i
+end
+
+# A test suite for the above parser
+describe CalcParser do
+  let(:p) { described_class.new }
+  describe '#integer' do
+    let(:i) { p.integer }
+    it "parses integers" do
+      i.should parse('1')
+      i.should parse('123')
+    end 
+    it "consumes trailing white space" do
+      i.should parse('123   ')
+    end 
+    it "doesn't parse floats" do
+      i.should_not parse('1.3')
+    end 
+  end
+  describe '#multiplication' do
+    let(:m) { p.multiplication }
+    it "parses simple multiplication" do
+      m.should parse('1*2')
+    end
+    it "parses division" do
+      m.should parse('1/2')
+    end 
+  end
+  describe '#addition' do
+    let(:a) { p.addition }
+    
+    it "parses simple addition" do
+      a.should parse('1+2')
+      a.should parse('1+2+3-4')
+    end 
+  end
+end
+describe CalcTransform do
+  def t(obj)
+    described_class.new.apply(obj)
+  end
+  
+  it "transforms integers" do
+    t(i: '1').should == Int.new(1)
+  end 
+  it "unwraps left operand" do
+    t(l: :obj).should == :obj
+  end 
+end
+describe 'whole computation specs' do
+  def self.result_of(str, int)
+    it(str) { calculate(str).should == int } 
+  end
+
+  result_of '1+1', 2
+  result_of '1-1-1', -1
+  result_of '1+1+3*5/2', 9
+  result_of '123*2', 246
+end
+
+
+# Enable these if you want to change the code.
+# RSpec::Core::Runner.run([], $stderr, $stdout)
+
+str = ARGV.join
+str = '123*2' if str.match(/^\s*$/)
+
+print "#{str} (command line): -> "
+puts calculate(str)
diff --git a/app/server/vendor/parslet/example/capture.rb b/app/server/vendor/parslet/example/capture.rb
new file mode 100755
index 0000000..4e4b8d1
--- /dev/null
+++ b/app/server/vendor/parslet/example/capture.rb
@@ -0,0 +1,49 @@
+
+# This example demonstrates how pieces of input can be captured and matched
+# against later on. Without this, you cannot match here-documents and other
+# self-dependent grammars. 
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+require 'parslet'
+require 'parslet/convenience'
+require 'pp'
+
+class CapturingParser < Parslet::Parser
+  root :document
+  
+  # Introduce a scope for each document. This ensures that documents can be
+  # nested. 
+  rule(:document) { scope { doc_start >> text >> doc_end } }
+  
+  # Start of a document is a heredoc marker. This is captured in :marker
+  rule(:doc_start) { str('<') >> marker >> newline }
+  rule(:marker) { match['A-Z'].repeat(1).capture(:marker) }
+
+  # The content of a document can be either lines of text or another 
+  # document, introduced by <HERE, where HERE is the doc marker. 
+  rule(:text) { (document.as(:doc) | text_line.as(:line)).repeat(1) }
+  rule(:text_line) { captured_marker.absent? >> any >> 
+    (newline.absent? >> any).repeat >> newline }
+    
+  # The end of the document is marked by the marker that was at the beginning
+  # of the document, by itself on a line.
+  rule(:doc_end) { captured_marker }
+  rule(:captured_marker) { 
+    dynamic { |source, context|
+      str(context.captures[:marker])
+    }
+  }
+  
+  rule(:newline) { match["\n"] }
+end
+
+parser = CapturingParser.new
+pp parser.parse_with_debug %Q(<CAPTURE
+Text1
+<FOOBAR
+Text3
+Text4
+FOOBAR
+Text2
+CAPTURE)
+
diff --git a/app/server/vendor/parslet/example/comments.rb b/app/server/vendor/parslet/example/comments.rb
new file mode 100755
index 0000000..92db991
--- /dev/null
+++ b/app/server/vendor/parslet/example/comments.rb
@@ -0,0 +1,35 @@
+# A small example on how to parse common types of comments. The example
+# started out with parser code from Stephen Waits. 
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'pp'
+require 'parslet'
+require 'parslet/convenience'
+
+class ALanguage < Parslet::Parser
+  root(:lines)
+  
+  rule(:lines) { line.repeat }
+  rule(:line) { spaces >> expression.repeat >> newline }
+  rule(:newline) { str("\n") >> str("\r").maybe }
+  
+  rule(:expression) { (str('a').as(:a) >> spaces).as(:exp) }
+  
+  rule(:spaces) { space.repeat }
+  rule(:space) { multiline_comment | line_comment | str(' ') }
+  
+  rule(:line_comment) { (str('//') >> (newline.absent? >> any).repeat).as(:line) }
+  rule(:multiline_comment) { (str('/*') >> (str('*/').absent? >> any).repeat >> str('*/')).as(:multi) }
+end
+
+code = %q(
+  a
+  // line comment
+  a a a // line comment
+  a /* inline comment */ a 
+  /* multiline
+  comment */
+)
+
+pp ALanguage.new.parse_with_debug(code)
diff --git a/app/server/vendor/parslet/example/deepest_errors.rb b/app/server/vendor/parslet/example/deepest_errors.rb
new file mode 100755
index 0000000..3573907
--- /dev/null
+++ b/app/server/vendor/parslet/example/deepest_errors.rb
@@ -0,0 +1,131 @@
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+# This example demonstrates how to do deepest error reporting, as invented 
+# by John Mettraux (issue #64).
+
+require 'parslet'
+require 'parslet/convenience'
+
+def prettify(str)
+  puts " "*3 + " "*4 + "." + " "*4 + "10" + " "*3 + "." + " "*4 + "20"
+  str.lines.each_with_index do |line, index|
+    printf "%02d %s\n", 
+      index+1, 
+      line.chomp
+  end
+end
+
+class Parser < Parslet::Parser
+  # commons
+
+  rule(:space) { match('[ \t]').repeat(1) }
+  rule(:space?) { space.maybe }
+
+  rule(:newline) { match('[\r\n]') }
+
+  rule(:comment) { str('#') >> match('[^\r\n]').repeat }
+
+  rule(:line_separator) {
+    (space? >> ((comment.maybe >> newline) | str(';')) >> space?).repeat(1)
+  }
+
+  rule(:blank) { line_separator | space }
+  rule(:blank?) { blank.maybe }
+
+  rule(:identifier) { match('[a-zA-Z0-9_]').repeat(1) }
+
+  # res_statement
+
+  rule(:reference) {
+    (str('@').repeat(1,2) >> identifier).as(:reference)
+  }
+
+  rule(:res_action_or_link) {
+    str('.').as(:dot) >> (identifier >> str('?').maybe ).as(:name) >> str('()')
+  }
+
+  rule(:res_actions) {
+    (
+      reference
+    ).as(:resources) >>
+    (
+      res_action_or_link.as(:res_action)
+    ).repeat(0).as(:res_actions)
+  }
+
+  rule(:res_statement) {
+    res_actions >>
+    (str(':') >> identifier.as(:name)).maybe.as(:res_field)
+  }
+
+  # expression
+
+  rule(:expression) {
+    res_statement
+  }
+
+  # body
+
+  rule(:body) {
+    (line_separator >> (block | expression)).repeat(1).as(:body) >>
+    line_separator
+  }
+
+  # blocks
+
+  rule(:begin_block) {
+    (str('concurrent').as(:type) >> space).maybe.as(:pre) >>
+    str('begin').as(:begin) >>
+    body >>
+    str('end')
+  }
+
+  rule(:define_block) {
+    str('define').as(:define) >> space >>
+    identifier.as(:name) >> str('()') >>
+    body >>
+    str('end')
+  }
+
+  rule(:block) {
+    define_block | begin_block
+  }
+
+  # root
+
+  rule(:radix) {
+    line_separator.maybe >> block >> line_separator.maybe
+  }
+
+  root(:radix)
+end
+
+ds = [
+  %{
+    define f()
+      @res.name
+    end
+  },
+  %{
+    define f()
+      begin
+        @res.name
+      end
+    end
+  }
+]
+
+ds.each do |d|
+
+  puts '-' * 80
+  prettify(d)
+
+  parser = Parser.new
+
+  begin
+    parser.parse_with_debug(d, 
+      :reporter => Parslet::ErrorReporter::Deepest.new)
+  end
+end
+
+puts '-' * 80
\ No newline at end of file
diff --git a/app/server/vendor/parslet/example/documentation.rb b/app/server/vendor/parslet/example/documentation.rb
new file mode 100755
index 0000000..4ce66e4
--- /dev/null
+++ b/app/server/vendor/parslet/example/documentation.rb
@@ -0,0 +1,18 @@
+# A small example that shows a really small parser and what happens on parser
+# errors. 
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'pp'
+require 'parslet'
+
+class MyParser < Parslet::Parser
+  rule(:a) { str('a').repeat }
+  
+  def parse(str)
+    a.parse(str)
+  end
+end
+
+pp MyParser.new.parse('aaaa')
+pp MyParser.new.parse('bbbb')
diff --git a/app/server/vendor/parslet/example/email_parser.rb b/app/server/vendor/parslet/example/email_parser.rb
new file mode 100755
index 0000000..1bfcfea
--- /dev/null
+++ b/app/server/vendor/parslet/example/email_parser.rb
@@ -0,0 +1,54 @@
+#!/usr/bin/env ruby
+
+# Example contributed by Hal Brodigan (postmodern). Thanks!
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+require 'parslet'
+require 'parslet/convenience'
+
+class EmailParser < Parslet::Parser
+  rule(:space) { match('\s').repeat(1) }
+  rule(:space?) { space.maybe }
+  rule(:dash?) { match['_-'].maybe }
+
+  rule(:at) {
+    str('@') |
+    (dash? >> (str('at') | str('AT')) >> dash?)
+  }
+  rule(:dot) {
+    str('.') |
+    (dash? >> (str('dot') | str('DOT')) >> dash?)
+  }
+
+  rule(:word) { match('[a-z0-9]').repeat(1).as(:word) >> space? }
+  rule(:separator) { dot.as(:dot) >> space? | space }
+  rule(:words) { word >> (separator >> word).repeat }
+
+  rule(:email) {
+    (words.as(:username) >> space? >> at >> space? >> words).as(:email)
+  }
+
+  root(:email)
+end
+
+class EmailSanitizer < Parslet::Transform
+  rule(:dot => simple(:dot), :word => simple(:word)) { ".#{word}" }
+  rule(:word => simple(:word)) { word }
+
+  rule(:username => sequence(:username)) { username.join + "@" }
+  rule(:username => simple(:username)) { username.to_s + "@" }
+
+  rule(:email => sequence(:email)) { email.join }
+end
+
+parser = EmailParser.new
+sanitizer = EmailSanitizer.new
+
+input = ARGV[0] || begin
+  default = "a.b.c.d at gmail.com"
+  STDERR.puts "usage: #{$0} \"EMAIL_ADDR\""
+  STDOUT.puts "since you haven't specified any EMAIL_ADDR, for testing purposes we're using #{default}"
+  default
+end
+
+p sanitizer.apply(parser.parse_with_debug(input))
diff --git a/app/server/vendor/parslet/example/empty.rb b/app/server/vendor/parslet/example/empty.rb
new file mode 100755
index 0000000..2b60a7e
--- /dev/null
+++ b/app/server/vendor/parslet/example/empty.rb
@@ -0,0 +1,13 @@
+# Basically just demonstrates that you can leave rules empty and get a nice
+# NotImplementedError. A way to quickly spec out your parser rules?
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'parslet'
+
+class Parser < Parslet::Parser
+  rule(:empty) { }
+end
+
+
+Parser.new.empty.parslet
diff --git a/app/server/vendor/parslet/example/erb.rb b/app/server/vendor/parslet/example/erb.rb
new file mode 100755
index 0000000..c013a8c
--- /dev/null
+++ b/app/server/vendor/parslet/example/erb.rb
@@ -0,0 +1,47 @@
+# Example that demonstrates how a simple erb-like parser could be constructed. 
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'parslet'
+
+class ErbParser < Parslet::Parser
+  rule(:ruby) { (str('%>').absent? >> any).repeat.as(:ruby) }
+  
+  rule(:expression) { (str('=') >> ruby).as(:expression) }
+  rule(:comment) { (str('#') >> ruby).as(:comment) }
+  rule(:code) { ruby.as(:code) }
+  rule(:erb) { expression | comment | code }
+  
+  rule(:erb_with_tags) { str('<%') >> erb >> str('%>') }
+  rule(:text) { (str('<%').absent? >> any).repeat(1) }
+  
+  rule(:text_with_ruby) { (text.as(:text) | erb_with_tags).repeat.as(:text) }
+  root(:text_with_ruby)
+end
+
+parser = ErbParser.new
+p parser.parse "The value of x is <%= x %>."
+p parser.parse "<% 1 + 2 %>"
+p parser.parse "<%# commented %>"
+ 
+
+evaluator = Parslet::Transform.new do
+  
+  erb_binding = binding
+  
+  rule(:code => { :ruby => simple(:ruby) }) { eval(ruby, erb_binding); '' }  
+  rule(:expression => { :ruby => simple(:ruby) }) { eval(ruby, erb_binding) }
+  rule(:comment => { :ruby => simple(:ruby) }) { '' }
+  
+  rule(:text => simple(:text)) { text }
+  rule(:text => sequence(:texts)) { texts.join }
+  
+end
+
+puts evaluator.apply(parser.parse(<<-ERB
+The <% a = 2 %>not printed result of "a = 2".
+The <%# a = 1 %>not printed non-evaluated comment "a = 1", see the value of a below.
+The <%= 'nicely' %> printed result.
+The <% b = 3 %>value of a is <%= a %>, and b is <%= b %>.
+ERB
+))
diff --git a/app/server/vendor/parslet/example/ignore.rb b/app/server/vendor/parslet/example/ignore.rb
new file mode 100755
index 0000000..4b14acb
--- /dev/null
+++ b/app/server/vendor/parslet/example/ignore.rb
@@ -0,0 +1,33 @@
+# A small example on how to make parslet ignore parts of the parse tree. 
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+require 'parslet'
+
+class IgnoreParslet < Parslet::Atoms::Base
+  def initialize(parslet)
+    @parslet = parslet
+  end
+  def to_s_inner(prec)
+    @parslet.to_s(prec)
+  end
+  def try(source, context, consume_all)
+    success, value = result = @parslet.try(source, context, consume_all)
+    
+    return succ(nil) if success
+    return result
+  end
+  
+end
+module IgnoreDSL
+  def ignore
+    IgnoreParslet.new(self)
+  end
+end
+
+class Parslet::Atoms::Base
+  include IgnoreDSL
+end
+
+include Parslet
+p (str('a') >> str('b').ignore >> str('c')).
+  parse('abc')
\ No newline at end of file
diff --git a/app/server/vendor/parslet/example/ip_address.rb b/app/server/vendor/parslet/example/ip_address.rb
new file mode 100755
index 0000000..3873500
--- /dev/null
+++ b/app/server/vendor/parslet/example/ip_address.rb
@@ -0,0 +1,125 @@
+# This example is heavily inspired by citrus' ip.citrus. Have a look at both
+# of these to get some choice!
+
+# The grammars in this file conform to the ABNF given in Appendix A of RFC 3986
+# Uniform Resource Identifier (URI): Generic Syntax.
+#
+# See http://tools.ietf.org/html/rfc3986#appendix-A for more information.
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'pp'
+require 'parslet'
+
+module IPv4
+  include Parslet
+  
+  # A host identified by an IPv4 literal address is represented in
+  # dotted-decimal notation (a sequence of four decimal numbers in the range 0
+  # to 255, separated by "."), as described in [RFC1123] by reference to
+  # [RFC0952].  Note that other forms of dotted notation may be interpreted on
+  # some platforms, as described in Section 7.4, but only the dotted-decimal
+  # form of four octets is allowed by this grammar.
+  rule(:ipv4) {
+    (dec_octet >> str('.') >> dec_octet >> str('.') >>
+      dec_octet >> str('.') >> dec_octet).as(:ipv4)
+  }
+  
+  rule(:dec_octet) {
+    str('25') >> match("[0-5]") |
+    str('2') >> match("[0-4]") >> digit |
+    str('1') >> digit >> digit |
+    match('[1-9]') >> digit |
+    digit
+  }
+  
+  rule(:digit) {
+    match('[0-9]')
+  }
+end
+
+# Must be used in concert with IPv4
+module IPv6 
+  include Parslet
+  
+  rule(:colon) { str(':') }
+  rule(:dcolon) { colon >> colon }
+  
+  # h16 :
+  def h16r(times)
+    (h16 >> colon).repeat(times, times)
+  end
+  
+  # : h16
+  def h16l(times)
+    (colon >> h16).repeat(0,times)
+  end
+  
+  # A 128-bit IPv6 address is divided into eight 16-bit pieces. Each piece is
+  # represented numerically in case-insensitive hexadecimal, using one to four
+  # hexadecimal digits (leading zeroes are permitted). The eight encoded
+  # pieces are given most-significant first, separated by colon characters.
+  # Optionally, the least-significant two pieces may instead be represented in
+  # IPv4 address textual format. A sequence of one or more consecutive
+  # zero-valued 16-bit pieces within the address may be elided, omitting all
+  # their digits and leaving exactly two consecutive colons in their place to
+  # mark the elision.
+  rule(:ipv6) {
+    (
+      (
+        h16r(6) |
+        dcolon >> h16r(5) | 
+        h16.maybe >> dcolon >> h16r(4) |
+        (h16 >> h16l(1)).maybe >> dcolon >> h16r(3) |
+        (h16 >> h16l(2)).maybe >> dcolon >> h16r(2) |
+        (h16 >> h16l(3)).maybe >> dcolon >> h16r(1) |
+        (h16 >> h16l(4)).maybe >> dcolon
+      ) >> ls32 |
+      (h16 >> h16l(5)).maybe >> dcolon >> h16 |
+      (h16 >> h16l(6)).maybe >> dcolon
+    ).as(:ipv6)
+  }
+  
+  rule(:h16) {
+    hexdigit.repeat(1,4)
+  }
+  
+  rule(:ls32) {
+    (h16 >> colon >> h16) |
+    ipv4
+  }
+
+  rule(:hexdigit) {
+    digit | match("[a-fA-F]")
+  }
+end
+
+class Parser
+  include IPv4
+  include IPv6
+  
+  def parse(str)
+    (ipv4 | ipv6).parse(str)
+  end
+end
+
+%W(
+  0.0.0.0
+  255.255.255.255
+  255.255.255
+  1:2:3:4:5:6:7:8
+  12AD:34FC:A453:1922::
+  12AD::34FC
+  12AD::
+  ::
+  1:2
+).each do |address|
+  parser = Parser.new
+  printf "%30s -> ", address
+  begin
+    result = parser.parse(address)
+    puts result.inspect
+  rescue Parslet::ParseFailed => m
+    puts "Failed: #{m}"
+  end
+end
diff --git a/app/server/vendor/parslet/example/json.rb b/app/server/vendor/parslet/example/json.rb
new file mode 100755
index 0000000..1ea1370
--- /dev/null
+++ b/app/server/vendor/parslet/example/json.rb
@@ -0,0 +1,128 @@
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+#
+# MIT License - (c) 2011 John Mettraux
+#
+
+require 'rubygems'
+require 'parslet' # gem install parslet
+
+
+module MyJson
+
+  class Parser < Parslet::Parser
+
+    rule(:spaces) { match('\s').repeat(1) }
+    rule(:spaces?) { spaces.maybe }
+
+    rule(:comma) { spaces? >> str(',') >> spaces? }
+    rule(:digit) { match('[0-9]') }
+
+    rule(:number) {
+      (
+        str('-').maybe >> (
+          str('0') | (match('[1-9]') >> digit.repeat)
+        ) >> (
+          str('.') >> digit.repeat(1)
+        ).maybe >> (
+          match('[eE]') >> (str('+') | str('-')).maybe >> digit.repeat(1)
+        ).maybe
+      ).as(:number)
+    }
+
+    rule(:string) {
+      str('"') >> (
+        str('\\') >> any | str('"').absent? >> any
+      ).repeat.as(:string) >> str('"')
+    }
+
+    rule(:array) {
+      str('[') >> spaces? >>
+      (value >> (comma >> value).repeat).maybe.as(:array) >>
+      spaces? >> str(']')
+    }
+
+    rule(:object) {
+      str('{') >> spaces? >>
+      (entry >> (comma >> entry).repeat).maybe.as(:object) >>
+      spaces? >> str('}')
+    }
+
+    rule(:value) {
+      string | number |
+      object | array |
+      str('true').as(:true) | str('false').as(:false) |
+      str('null').as(:null)
+    }
+
+    rule(:entry) {
+      (
+         string.as(:key) >> spaces? >>
+         str(':') >> spaces? >>
+         value.as(:val)
+      ).as(:entry)
+    }
+
+    rule(:attribute) { (entry | value).as(:attribute) }
+
+    rule(:top) { spaces? >> value >> spaces? }
+
+    root(:top)
+  end
+
+  class Transformer < Parslet::Transform
+
+    class Entry < Struct.new(:key, :val); end
+
+    rule(:array => subtree(:ar)) {
+      ar.is_a?(Array) ? ar : [ ar ]
+    }
+    rule(:object => subtree(:ob)) {
+      (ob.is_a?(Array) ? ob : [ ob ]).inject({}) { |h, e| h[e.key] = e.val; h }
+    }
+
+    rule(:entry => { :key => simple(:ke), :val => simple(:va) }) {
+      Entry.new(ke, va)
+    }
+
+    rule(:string => simple(:st)) {
+      st.to_s
+    }
+    rule(:number => simple(:nb)) {
+      nb.match(/[eE\.]/) ? Float(nb) : Integer(nb)
+    }
+
+    rule(:null => simple(:nu)) { nil }
+    rule(:true => simple(:tr)) { true }
+    rule(:false => simple(:fa)) { false }
+  end
+
+  def self.parse(s)
+
+    parser = Parser.new
+    transformer = Transformer.new
+
+    tree = parser.parse(s)
+    puts; p tree; puts
+    out = transformer.apply(tree)
+
+    out
+  end
+end
+
+
+s = %{
+  [ 1, 2, 3, null,
+    "asdfasdf asdfds", { "a": -1.2 }, { "b": true, "c": false },
+    0.1e24, true, false, [ 1 ] ]
+}
+
+out = MyJson.parse(s)
+
+p out; puts
+
+out == [
+  1, 2, 3, nil,
+  "asdfasdf asdfds", { "a" => -1.2 }, { "b" => true, "c" => false },
+  0.1e24, true, false, [ 1 ]
+] || raise("MyJson is a failure")
diff --git a/app/server/vendor/parslet/example/local.rb b/app/server/vendor/parslet/example/local.rb
new file mode 100755
index 0000000..a944082
--- /dev/null
+++ b/app/server/vendor/parslet/example/local.rb
@@ -0,0 +1,34 @@
+
+# An exploration of two ideas: 
+#   a) Constructing a whole parser inline, without the artificial class around
+#      it. 
+# and:
+#   b) Constructing non-greedy or non-blind parsers by transforming the 
+#      grammar.
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'parslet'
+include Parslet
+
+a =  str('a').repeat >> str('aa')
+
+# E1% E2
+# 
+# S = E2 | E1 S 
+
+def this(name, &block); return Parslet::Atoms::Entity.new(name, &block) end
+def epsilon; any.absent? end 
+
+# Traditional repetition will try as long as the pattern can be matched and 
+# then give up. This is greedy and blind. 
+a = str('a').as(:e) >> this('a') { a }.as(:rec) | epsilon
+
+# Here's a pattern match that is greedy and non-blind. The first pattern
+# 'a'* will be tried as many times as possible, while still matching the 
+# end pattern 'aa'.
+b = str('aa').as(:e2) >> epsilon | str('a').as(:e1) >> this('b') { b }.as(:rec)
+
+p a.parse('aaaa')
+p b
+p b.parse('aaaa')
diff --git a/app/server/vendor/parslet/example/mathn.rb b/app/server/vendor/parslet/example/mathn.rb
new file mode 100755
index 0000000..44c0e5c
--- /dev/null
+++ b/app/server/vendor/parslet/example/mathn.rb
@@ -0,0 +1,44 @@
+# Demonstrates that we have a compatibility fix to mathn's weird idea of 
+# integer mathematics. 
+# This was contributed by Jonathan Hinkle (https://github.com/hynkle). Thanks!
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'parslet'
+require 'parslet/convenience'
+include Parslet
+
+def attempt_parse
+  possible_whitespace = match['\s'].repeat
+
+  cephalopod =
+    str('octopus') |
+    str('squid')
+
+  parenthesized_cephalopod =
+    str('(') >>
+    possible_whitespace >>
+    cephalopod >>
+    possible_whitespace >>
+    str(')')
+
+  parser =
+    possible_whitespace >>
+    parenthesized_cephalopod >>
+    possible_whitespace
+
+  # This parse fails, but that is not the point. When mathn is in the current
+  # ruby environment, it modifies integer division in a way that makes 
+  # parslet loop indefinitely.
+  parser.parse %{(\nsqeed)\n}
+rescue Parslet::ParseFailed
+end
+
+attempt_parse 
+puts 'it terminates before we require mathn'
+
+puts "requiring mathn now"
+require 'mathn'
+puts "and trying again (will hang without the fix)"
+attempt_parse # but it doesn't terminate after requiring mathn
+puts "okay!"
\ No newline at end of file
diff --git a/app/server/vendor/parslet/example/minilisp.rb b/app/server/vendor/parslet/example/minilisp.rb
new file mode 100755
index 0000000..fe7ac4e
--- /dev/null
+++ b/app/server/vendor/parslet/example/minilisp.rb
@@ -0,0 +1,94 @@
+# Reproduces [1] using parslet. 
+# [1] http://thingsaaronmade.com/blog/a-quick-intro-to-writing-a-parser-using-treetop.html
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'pp'
+require 'parslet'
+require 'parslet/convenience'
+
+module MiniLisp
+  class Parser < Parslet::Parser
+    root :expression
+    rule(:expression) {
+      space? >> str('(') >> space? >> body >> str(')') >> space?
+    }
+    
+    rule(:body) {
+      (expression | identifier | float | integer | string).repeat.as(:exp)
+    }
+    
+    rule(:space) {
+      match('\s').repeat(1)
+    }
+    rule(:space?) {
+      space.maybe
+    }
+    
+    rule(:identifier) { 
+      (match('[a-zA-Z=*]') >> match('[a-zA-Z=*_]').repeat).as(:identifier) >> space?
+    }
+    
+    rule(:float) { 
+      (
+        integer >> (
+          str('.') >> match('[0-9]').repeat(1) |
+          str('e') >> match('[0-9]').repeat(1)
+        ).as(:e)
+      ).as(:float) >> space?
+    }
+    
+    rule(:integer) {
+      ((str('+') | str('-')).maybe >> match("[0-9]").repeat(1)).as(:integer) >> space?
+    }
+    
+    rule(:string) {
+      str('"') >> (
+        str('\\') >> any |
+        str('"').absent? >> any 
+      ).repeat.as(:string) >> str('"') >> space?
+    }
+  end
+  
+  class Transform
+    include Parslet
+    
+    attr_reader :t
+    def initialize
+      @t = Parslet::Transform.new
+      
+      # To understand these, take a look at what comes out of the parser. 
+      t.rule(:identifier => simple(:ident)) { ident.to_sym }
+        
+      t.rule(:string => simple(:str))       { str }
+        
+      t.rule(:integer => simple(:int))      { Integer(int) }
+        
+      t.rule(:float=>{:integer=> simple(:a), :e=> simple(:b)}) { Float(a + b) }
+        
+      t.rule(:exp => subtree(:exp))         { exp }
+    end
+    
+    def do(tree)
+      t.apply(tree)
+    end
+  end
+end
+
+parser = MiniLisp::Parser.new
+transform = MiniLisp::Transform.new
+
+result = parser.parse_with_debug %Q{
+  (define test (lambda ()
+    (begin
+      (display "something")
+      (display 1)
+      (display 3.08))))
+}
+
+# Transform the result
+pp transform.do(result) if result
+
+# Thereby reducing it to the earlier problem: 
+# http://github.com/kschiess/toylisp
+
diff --git a/app/server/vendor/parslet/example/modularity.rb b/app/server/vendor/parslet/example/modularity.rb
new file mode 100755
index 0000000..0e655fa
--- /dev/null
+++ b/app/server/vendor/parslet/example/modularity.rb
@@ -0,0 +1,47 @@
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'pp'
+require "parslet"
+
+# Demonstrates modular parsers, split out over many classes. Please look at
+# ip_address.rb as well.
+
+module ALanguage
+  include Parslet
+    
+  # Parslet rules are really a special kind of method. Mix them into your
+  # classes!
+  rule(:a_language) { str('aaa') }
+end
+
+# Parslet parsers are parslet atoms as well. Create an instance and chain them
+# to your other rules. 
+#
+class BLanguage < Parslet::Parser
+  root :blang
+  
+  rule(:blang) { str('bbb') }
+end
+
+# Parslet atoms are really Ruby values, pass them around. 
+c_language = Parslet.str('ccc')
+  
+class Language < Parslet::Parser
+  def initialize(c_language)
+    @c_language = c_language
+    super()
+  end
+  
+  root :root
+
+  include ALanguage
+  
+  rule(:root) { str('a(') >> a_language >> str(')') >> space |
+                str('b(') >> BLanguage.new >> str(')') >> space | 
+                str('c(') >> @c_language >> str(')') >> space }
+  rule(:space) { str(' ').maybe }
+end
+
+Language.new(c_language).parse('a(aaa)')
+Language.new(c_language).parse('b(bbb)')
+Language.new(c_language).parse('c(ccc)')
\ No newline at end of file
diff --git a/app/server/vendor/parslet/example/nested_errors.rb b/app/server/vendor/parslet/example/nested_errors.rb
new file mode 100755
index 0000000..3feafcd
--- /dev/null
+++ b/app/server/vendor/parslet/example/nested_errors.rb
@@ -0,0 +1,132 @@
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'parslet'
+require 'parslet/convenience'
+
+# This example demonstrates tree error reporting in a real life example. 
+# The parser code has been contributed by John Mettraux.
+
+def prettify(str)
+  puts " "*3 + " "*4 + "." + " "*4 + "10" + " "*3 + "." + " "*4 + "20"
+  str.lines.each_with_index do |line, index|
+    printf "%02d %s\n", 
+      index+1, 
+      line.chomp
+  end
+end
+
+class Parser < Parslet::Parser
+
+  # commons
+
+  rule(:space) { match('[ \t]').repeat(1) }
+  rule(:space?) { space.maybe }
+
+  rule(:newline) { match('[\r\n]') }
+
+  rule(:comment) { str('#') >> match('[^\r\n]').repeat }
+
+  rule(:line_separator) {
+    (space? >> ((comment.maybe >> newline) | str(';')) >> space?).repeat(1)
+  }
+
+  rule(:blank) { line_separator | space }
+  rule(:blank?) { blank.maybe }
+
+  rule(:identifier) { match('[a-zA-Z0-9_]').repeat(1) }
+
+  # res_statement
+
+  rule(:reference) {
+    (str('@').repeat(1,2) >> identifier).as(:reference)
+  }
+
+  rule(:res_action_or_link) {
+    str('.').as(:dot) >> (identifier >> str('?').maybe ).as(:name) >> str('()')
+  }
+
+  rule(:res_actions) {
+    (
+      reference
+    ).as(:resources) >>
+    (
+      res_action_or_link.as(:res_action)
+    ).repeat(0).as(:res_actions)
+  }
+
+  rule(:res_statement) {
+    res_actions >>
+    (str(':') >> identifier.as(:name)).maybe.as(:res_field)
+  }
+
+  # expression
+
+  rule(:expression) {
+    res_statement
+  }
+
+  # body
+
+  rule(:body) {
+    (line_separator >> (block | expression)).repeat(1).as(:body) >>
+    line_separator
+  }
+
+  # blocks
+
+  rule(:begin_block) {
+    (str('concurrent').as(:type) >> space).maybe.as(:pre) >>
+    str('begin').as(:begin) >>
+    body >>
+    str('end')
+  }
+
+  rule(:define_block) {
+    str('define').as(:define) >> space >>
+    identifier.as(:name) >> str('()') >>
+    body >>
+    str('end')
+  }
+
+  rule(:block) {
+    define_block | begin_block
+  }
+
+  # root
+
+  rule(:radix) {
+    line_separator.maybe >> block >> line_separator.maybe
+  }
+
+  root(:radix)
+end
+
+
+ds = [
+  %{
+    define f()
+      @res.name
+    end
+  },
+  %{
+    define f()
+      begin
+        @res.name
+      end
+    end
+  }
+]
+
+ds.each do |d|
+
+  puts '-' * 80
+  prettify(d)
+
+  parser = Parser.new
+
+  begin
+    parser.parse_with_debug(d)
+  end
+end
+
+puts '-' * 80
\ No newline at end of file
diff --git a/app/server/vendor/parslet/example/optimized_erb.rb b/app/server/vendor/parslet/example/optimized_erb.rb
new file mode 100755
index 0000000..228619e
--- /dev/null
+++ b/app/server/vendor/parslet/example/optimized_erb.rb
@@ -0,0 +1,42 @@
+# Please also look at the more naive 'erb.rb'. This shows how to optimize an
+# ERB like parser using parslet. 
+
+$:.unshift File.join(File.dirname(__FILE__), "/../lib")
+
+require 'parslet'
+require './qed/applique/gobbleup'
+require 'parslet/accelerator'
+
+class ErbParser < Parslet::Parser
+  rule(:ruby) { (str('%>').absent? >> any).repeat.as(:ruby) }
+  
+  rule(:expression) { (str('=') >> ruby).as(:expression) }
+  rule(:comment) { (str('#') >> ruby).as(:comment) }
+  rule(:code) { ruby.as(:code) }
+  rule(:erb) { expression | comment | code }
+  
+  rule(:erb_with_tags) { str('<%') >> erb >> str('%>') }
+  rule(:text) { (str('<%').absent? >> any).repeat(1) }
+  
+  rule(:text_with_ruby) { (text.as(:text) | erb_with_tags).repeat.as(:text) }
+  root(:text_with_ruby)
+end
+
+parser = ErbParser.new
+
+A = Parslet::Accelerator
+optimized = A.apply(parser, 
+  A.rule((A.str(:x).absent? >> A.any).repeat(1)) { GobbleUp.new(x, 1) }, 
+  A.rule((A.str(:x).absent? >> A.any).repeat(0)) { GobbleUp.new(x, 0) })
+
+input = File.read(File.dirname(__FILE__) + "/big.erb")
+
+# Remove the comment marks here to see what difference the optimisation makes.
+# Commented out for the acceptance tests to run. 
+#
+# require 'benchmark'
+# Benchmark.bm(7) do |bm|
+#   bm.report('original') { parser.parse(input) }
+#   bm.report('gobble') { optimized.parse(input) }
+# end
+p optimized.parse(input)
\ No newline at end of file
diff --git a/app/server/vendor/parslet/example/output/boolean_algebra.out b/app/server/vendor/parslet/example/output/boolean_algebra.out
new file mode 100755
index 0000000..430ed54
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/boolean_algebra.out
@@ -0,0 +1,4 @@
+{:and=>
+  {:left=>{:var=>"1"@3},
+   :right=>{:or=>{:left=>{:var=>"2"@13}, :right=>{:var=>"3"@21}}}}}
+[["1", "2"], ["1", "3"]]
diff --git a/app/server/vendor/parslet/example/output/calc.out b/app/server/vendor/parslet/example/output/calc.out
new file mode 100755
index 0000000..d780a04
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/calc.out
@@ -0,0 +1 @@
+123*2 (command line): -> 246
diff --git a/app/server/vendor/parslet/example/output/capture.out b/app/server/vendor/parslet/example/output/capture.out
new file mode 100755
index 0000000..87519e2
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/capture.out
@@ -0,0 +1,3 @@
+[{:line=>"Text1\n"@9},
+ {:doc=>[{:line=>"Text3\n"@23}, {:line=>"Text4\n"@29}]},
+ {:line=>"\nText2\n"@41}]
diff --git a/app/server/vendor/parslet/example/output/comments.out b/app/server/vendor/parslet/example/output/comments.out
new file mode 100755
index 0000000..4026a30
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/comments.out
@@ -0,0 +1,8 @@
+[{:exp=>{:a=>"a"@3}},
+ {:line=>"// line comment"@7},
+ {:exp=>{:a=>"a"@25}},
+ {:exp=>{:a=>"a"@27}},
+ {:exp=>[{:a=>"a"@29}, {:line=>"// line comment"@31}]},
+ {:exp=>[{:a=>"a"@49}, {:multi=>"/* inline comment */"@51}]},
+ {:exp=>{:a=>"a"@72}},
+ {:multi=>"/* multiline\n  comment */"@77}]
diff --git a/app/server/vendor/parslet/example/output/deepest_errors.out b/app/server/vendor/parslet/example/output/deepest_errors.out
new file mode 100755
index 0000000..6b81f9b
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/deepest_errors.out
@@ -0,0 +1,54 @@
+--------------------------------------------------------------------------------
+       .    10   .    20
+01 
+02     define f()
+03       @res.name
+04     end
+05   
+Failed to match sequence (LINE_SEPARATOR? BLOCK LINE_SEPARATOR?) at line 2 char 5.
+`- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 2 char 5.
+   |- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 2 char 15.
+   |  `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 3 char 11.
+   |     `- Expected at least 1 of SPACE? (COMMENT? NEWLINE / ';') SPACE? at line 3 char 11.
+   |        `- Failed to match sequence (SPACE? (COMMENT? NEWLINE / ';') SPACE?) at line 3 char 11.
+   |           `- Expected one of [COMMENT? NEWLINE, ';'] at line 3 char 11.
+   |              |- Failed to match sequence (COMMENT? NEWLINE) at line 3 char 11.
+   |              |  `- Expected "()", but got "\n " at line 3 char 16.
+   |              `- Expected "()", but got "\n " at line 3 char 16.
+   `- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 2 char 5.
+      `- Expected "()", but got "\n " at line 3 char 16.
+--------------------------------------------------------------------------------
+       .    10   .    20
+01 
+02     define f()
+03       begin
+04         @res.name
+05       end
+06     end
+07   
+Failed to match sequence (LINE_SEPARATOR? BLOCK LINE_SEPARATOR?) at line 2 char 5.
+`- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 2 char 5.
+   |- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 2 char 15.
+   |  `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 2 char 15.
+   |     `- Expected at least 1 of LINE_SEPARATOR (BLOCK / EXPRESSION) at line 2 char 15.
+   |        `- Failed to match sequence (LINE_SEPARATOR (BLOCK / EXPRESSION)) at line 3 char 7.
+   |           `- Expected one of [BLOCK, EXPRESSION] at line 3 char 7.
+   |              |- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 3 char 7.
+   |              |  |- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 3 char 7.
+   |              |  |  `- Expected "define", but got "begin\n" at line 3 char 7.
+   |              |  `- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 3 char 12.
+   |              |     `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 4 char 13.
+   |              |        `- Expected at least 1 of SPACE? (COMMENT? NEWLINE / ';') SPACE? at line 4 char 13.
+   |              |           `- Failed to match sequence (SPACE? (COMMENT? NEWLINE / ';') SPACE?) at line 4 char 13.
+   |              |              `- Expected one of [COMMENT? NEWLINE, ';'] at line 4 char 13.
+   |              |                 |- Failed to match sequence (COMMENT? NEWLINE) at line 4 char 13.
+   |              |                 |  `- Expected "()", but got "\n " at line 4 char 18.
+   |              |                 `- Expected "()", but got "\n " at line 4 char 18.
+   |              `- Failed to match sequence (RES_ACTIONS res_field:((':' name:IDENTIFIER)?)) at line 3 char 7.
+   |                 `- Failed to match sequence (resources:REFERENCE res_actions:(res_action:RES_ACTION_OR_LINK{0, })) at line 3 char 7.
+   |                    `- Failed to match sequence ('@'{1, 2} IDENTIFIER) at line 3 char 7.
+   |                       `- Expected at least 1 of '@' at line 3 char 7.
+   |                          `- Expected "()", but got "\n " at line 4 char 18.
+   `- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 2 char 5.
+      `- Expected "()", but got "\n " at line 4 char 18.
+--------------------------------------------------------------------------------
diff --git a/app/server/vendor/parslet/example/output/documentation.err b/app/server/vendor/parslet/example/output/documentation.err
new file mode 100755
index 0000000..16b382f
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/documentation.err
@@ -0,0 +1,4 @@
+/Users/kaspar/git_work/own/parslet/lib/parslet/atoms/base.rb:326:in `parse_failed': Don't know what to do with bbbb at line 1 char 1. (Parslet::ParseFailed)
+	from /Users/kaspar/git_work/own/parslet/lib/parslet/atoms/base.rb:55:in `parse'
+	from example/documentation.rb:13:in `parse'
+	from example/documentation.rb:18:in `<main>'
diff --git a/app/server/vendor/parslet/example/output/documentation.out b/app/server/vendor/parslet/example/output/documentation.out
new file mode 100755
index 0000000..55aa425
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/documentation.out
@@ -0,0 +1 @@
+"aaaa"@0
diff --git a/app/server/vendor/parslet/example/output/email_parser.out b/app/server/vendor/parslet/example/output/email_parser.out
new file mode 100755
index 0000000..da385c6
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/email_parser.out
@@ -0,0 +1,2 @@
+since you haven't specified any EMAIL_ADDR, for testing purposes we're using a.b.c.d at gmail.com
+"a.b.c.d at gmail.com"
diff --git a/app/server/vendor/parslet/example/output/empty.err b/app/server/vendor/parslet/example/output/empty.err
new file mode 100755
index 0000000..61658ec
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/empty.err
@@ -0,0 +1 @@
+example/empty.rb:13:in `<main>': rule(:empty) { ... }  returns nil. Still not implemented, but already used? (NotImplementedError)
diff --git a/app/server/vendor/parslet/example/output/erb.out b/app/server/vendor/parslet/example/output/erb.out
new file mode 100755
index 0000000..b86db3a
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/erb.out
@@ -0,0 +1,7 @@
+{:text=>[{:text=>"The value of x is "@0}, {:expression=>{:ruby=>" x "@21}}, {:text=>"."@26}]}
+{:text=>[{:code=>{:ruby=>" 1 + 2 "@2}}]}
+{:text=>[{:comment=>{:ruby=>" commented "@3}}]}
+The not printed result of "a = 2".
+The not printed non-evaluated comment "a = 1", see the value of a below.
+The nicely printed result.
+The value of a is 2, and b is 3.
diff --git a/app/server/vendor/parslet/example/output/ignore.out b/app/server/vendor/parslet/example/output/ignore.out
new file mode 100755
index 0000000..450fdfd
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/ignore.out
@@ -0,0 +1 @@
+"ac"@0
diff --git a/app/server/vendor/parslet/example/output/ignore_whitespace.out b/app/server/vendor/parslet/example/output/ignore_whitespace.out
new file mode 100755
index 0000000..f778f09
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/ignore_whitespace.out
@@ -0,0 +1 @@
+[{:a=>"a"@0}, {:a=>"a"@1}, {:a=>"a"@5}, {:a=>"a"@7}]
diff --git a/app/server/vendor/parslet/example/output/ip_address.out b/app/server/vendor/parslet/example/output/ip_address.out
new file mode 100755
index 0000000..a15d777
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/ip_address.out
@@ -0,0 +1,9 @@
+                       0.0.0.0 -> {:ipv4=>"0.0.0.0"@0}
+               255.255.255.255 -> {:ipv4=>"255.255.255.255"@0}
+                   255.255.255 -> Failed: Expected one of [IPV4, IPV6] at line 1 char 1.
+               1:2:3:4:5:6:7:8 -> {:ipv6=>"1:2:3:4:5:6:7:8"@0}
+         12AD:34FC:A453:1922:: -> {:ipv6=>"12AD:34FC:A453:1922::"@0}
+                    12AD::34FC -> {:ipv6=>"12AD::34FC"@0}
+                        12AD:: -> {:ipv6=>"12AD::"@0}
+                            :: -> {:ipv6=>"::"@0}
+                           1:2 -> Failed: Expected one of [IPV4, IPV6] at line 1 char 1.
diff --git a/app/server/vendor/parslet/example/output/json.out b/app/server/vendor/parslet/example/output/json.out
new file mode 100755
index 0000000..c3190ad
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/json.out
@@ -0,0 +1,5 @@
+
+{:array=>[{:number=>"1"@5}, {:number=>"2"@8}, {:number=>"3"@11}, {:null=>"null"@14}, {:string=>"asdfasdf asdfds"@25}, {:object=>{:entry=>{:key=>{:string=>"a"@46}, :val=>{:number=>"-1.2"@50}}}}, {:object=>[{:entry=>{:key=>{:string=>"b"@61}, :val=>{:true=>"true"@65}}}, {:entry=>{:key=>{:string=>"c"@72}, :val=>{:false=>"false"@76}}}]}, {:number=>"0.1e24"@89}, {:true=>"true"@97}, {:false=>"false"@103}, {:array=>{:number=>"1"@112}}]}
+
+[1, 2, 3, nil, "asdfasdf asdfds", {"a"=>-1.2}, {"b"=>true, "c"=>false}, 1.0e+23, true, false, [1]]
+
diff --git a/app/server/vendor/parslet/example/output/local.out b/app/server/vendor/parslet/example/output/local.out
new file mode 100755
index 0000000..f6f44ca
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/local.out
@@ -0,0 +1,3 @@
+{:e=>"a"@0, :rec=>{:e=>"a"@1, :rec=>{:e=>"a"@2, :rec=>{:e=>"a"@3, :rec=>nil}}}}
+e2:'aa' !. / e1:'a' rec:B
+{:e1=>"a"@0, :rec=>{:e1=>"a"@1, :rec=>{:e2=>"aa"@2}}}
diff --git a/app/server/vendor/parslet/example/output/mathn.out b/app/server/vendor/parslet/example/output/mathn.out
new file mode 100755
index 0000000..e1187d0
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/mathn.out
@@ -0,0 +1,4 @@
+it terminates before we require mathn
+requiring mathn now
+and trying again (will hang without the fix)
+okay!
diff --git a/app/server/vendor/parslet/example/output/minilisp.out b/app/server/vendor/parslet/example/output/minilisp.out
new file mode 100755
index 0000000..423431f
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/minilisp.out
@@ -0,0 +1,5 @@
+[:define,
+ :test,
+ [:lambda,
+  [],
+  [:begin, [:display, "something"@54], [:display, 1], [:display, 3.08]]]]
diff --git a/app/server/vendor/parslet/example/output/modularity.out b/app/server/vendor/parslet/example/output/modularity.out
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/parslet/example/output/nested_errors.out b/app/server/vendor/parslet/example/output/nested_errors.out
new file mode 100755
index 0000000..b6bd833
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/nested_errors.out
@@ -0,0 +1,54 @@
+--------------------------------------------------------------------------------
+       .    10   .    20
+01 
+02     define f()
+03       @res.name
+04     end
+05   
+Failed to match sequence (LINE_SEPARATOR? BLOCK LINE_SEPARATOR?) at line 2 char 5.
+`- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 2 char 5.
+   |- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 2 char 15.
+   |  `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 3 char 11.
+   |     `- Expected at least 1 of SPACE? (COMMENT? NEWLINE / ';') SPACE? at line 3 char 11.
+   |        `- Failed to match sequence (SPACE? (COMMENT? NEWLINE / ';') SPACE?) at line 3 char 11.
+   |           `- Expected one of [COMMENT? NEWLINE, ';'] at line 3 char 11.
+   |              |- Failed to match sequence (COMMENT? NEWLINE) at line 3 char 11.
+   |              |  `- Failed to match [\\r\\n] at line 3 char 11.
+   |              `- Expected ";", but got "." at line 3 char 11.
+   `- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 2 char 5.
+      `- Expected "begin", but got "defin" at line 2 char 5.
+--------------------------------------------------------------------------------
+       .    10   .    20
+01 
+02     define f()
+03       begin
+04         @res.name
+05       end
+06     end
+07   
+Failed to match sequence (LINE_SEPARATOR? BLOCK LINE_SEPARATOR?) at line 2 char 5.
+`- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 2 char 5.
+   |- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 2 char 15.
+   |  `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 2 char 15.
+   |     `- Expected at least 1 of LINE_SEPARATOR (BLOCK / EXPRESSION) at line 2 char 15.
+   |        `- Failed to match sequence (LINE_SEPARATOR (BLOCK / EXPRESSION)) at line 3 char 7.
+   |           `- Expected one of [BLOCK, EXPRESSION] at line 3 char 7.
+   |              |- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 3 char 7.
+   |              |  |- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 3 char 7.
+   |              |  |  `- Expected "define", but got "begin\n" at line 3 char 7.
+   |              |  `- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 3 char 12.
+   |              |     `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 4 char 13.
+   |              |        `- Expected at least 1 of SPACE? (COMMENT? NEWLINE / ';') SPACE? at line 4 char 13.
+   |              |           `- Failed to match sequence (SPACE? (COMMENT? NEWLINE / ';') SPACE?) at line 4 char 13.
+   |              |              `- Expected one of [COMMENT? NEWLINE, ';'] at line 4 char 13.
+   |              |                 |- Failed to match sequence (COMMENT? NEWLINE) at line 4 char 13.
+   |              |                 |  `- Failed to match [\\r\\n] at line 4 char 13.
+   |              |                 `- Expected ";", but got "." at line 4 char 13.
+   |              `- Failed to match sequence (RES_ACTIONS res_field:((':' name:IDENTIFIER)?)) at line 3 char 7.
+   |                 `- Failed to match sequence (resources:REFERENCE res_actions:(res_action:RES_ACTION_OR_LINK{0, })) at line 3 char 7.
+   |                    `- Failed to match sequence ('@'{1, 2} IDENTIFIER) at line 3 char 7.
+   |                       `- Expected at least 1 of '@' at line 3 char 7.
+   |                          `- Expected "@", but got "b" at line 3 char 7.
+   `- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 2 char 5.
+      `- Expected "begin", but got "defin" at line 2 char 5.
+--------------------------------------------------------------------------------
diff --git a/app/server/vendor/parslet/example/output/optimized_erb.out b/app/server/vendor/parslet/example/output/optimized_erb.out
new file mode 100755
index 0000000..4aaf516
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/optimized_erb.out
@@ -0,0 +1 @@
+{:text=>[{:text=>"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\n"@0}, {:expression=>{:ruby=>" erb tag "@2685}}, {:text=>"\n\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n"@2696}]}
diff --git a/app/server/vendor/parslet/example/output/parens.out b/app/server/vendor/parslet/example/output/parens.out
new file mode 100755
index 0000000..d635101
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/parens.out
@@ -0,0 +1,8 @@
+                  (): {:l=>"("@0, :m=>nil, :r=>")"@1} (1 parens)
+
+                (()): {:l=>"("@0, :m=>{:l=>"("@1, :m=>nil, :r=>")"@2}, :r=>")"@3} (2 parens)
+
+          ((((())))): {:l=>"("@0, :m=>{:l=>"("@1, :m=>{:l=>"("@2, :m=>{:l=>"("@3, :m=>{:l=>"("@4, :m=>nil, :r=>")"@5}, :r=>")"@6}, :r=>")"@7}, :r=>")"@8}, :r=>")"@9} (5 parens)
+
+               ((()): Failed to match sequence (l:'(' m:(BALANCED?) r:')') at line 1 char 6.
+
diff --git a/app/server/vendor/parslet/example/output/prec_calc.out b/app/server/vendor/parslet/example/output/prec_calc.out
new file mode 100755
index 0000000..02c8403
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/prec_calc.out
@@ -0,0 +1,5 @@
+a = 1
+b = 2
+c = 3 * 25
+d = 100 + 3*4
+{:a=>1, :b=>2, :c=>75, :d=>112}
diff --git a/app/server/vendor/parslet/example/output/readme.out b/app/server/vendor/parslet/example/output/readme.out
new file mode 100755
index 0000000..b04aa33
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/readme.out
@@ -0,0 +1 @@
+String contents: This is a \"String\" in which you can escape stuff
diff --git a/app/server/vendor/parslet/example/output/scopes.out b/app/server/vendor/parslet/example/output/scopes.out
new file mode 100755
index 0000000..8d9b2df
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/scopes.out
@@ -0,0 +1 @@
+parses 'aba'
diff --git a/app/server/vendor/parslet/example/output/seasons.out b/app/server/vendor/parslet/example/output/seasons.out
new file mode 100755
index 0000000..e018f82
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/seasons.out
@@ -0,0 +1,28 @@
+"And when Spring comes"
+{:bud=>{:stem=>[{:branch=>:leaf}]}}
+
+"And when Summer comes"
+{:bud=>{:stem=>[{:branch=>[:leaf, :flower]}]}}
+
+"And when Fall comes"
+Fruit!
+Falling Leaves!
+{:bud=>{:stem=>[{:branch=>[]}]}}
+
+"And when Winter comes"
+{:bud=>{:stem=>[]}}
+
+"And when Spring comes"
+{:bud=>{:stem=>[{:branch=>:leaf}]}}
+
+"And when Summer comes"
+{:bud=>{:stem=>[{:branch=>[:leaf, :flower]}]}}
+
+"And when Fall comes"
+Fruit!
+Falling Leaves!
+{:bud=>{:stem=>[{:branch=>[]}]}}
+
+"And when Winter comes"
+{:bud=>{:stem=>[]}}
+
diff --git a/app/server/vendor/parslet/example/output/sentence.out b/app/server/vendor/parslet/example/output/sentence.out
new file mode 100755
index 0000000..f183a24
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/sentence.out
@@ -0,0 +1 @@
+["RubyKaigi2009のテーマは、「変わる/変える」です。", " 前回のRubyKaigi2008のテーマであった「多様性」の言葉の通り、 2008年はRubyそのものに関しても、またRubyの活躍する舞台に関しても、 ますます多様化が進みつつあります。", "RubyKaigi2008は、そのような Rubyの生態系をあらためて認識する場となりました。", " しかし、こうした多様化が進む中、異なる者同士が単純に距離を 置いたままでは、その違いを認識したところであまり意味がありません。", " 異なる実装、異なる思想、異なる背景といった、様々な多様性を理解しつつ、 すり合わせるべきものをすり合わせ、変えていくべきところを 変えていくことが、豊かな未来へとつながる道に違いありません。"]
diff --git a/app/server/vendor/parslet/example/output/simple_xml.out b/app/server/vendor/parslet/example/output/simple_xml.out
new file mode 100755
index 0000000..015941f
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/simple_xml.out
@@ -0,0 +1,2 @@
+"verified"
+{:o=>{:name=>"b"@1}, :i=>"verified", :c=>{:name=>"a"@33}}
diff --git a/app/server/vendor/parslet/example/output/string_parser.out b/app/server/vendor/parslet/example/output/string_parser.out
new file mode 100755
index 0000000..b7e497f
--- /dev/null
+++ b/app/server/vendor/parslet/example/output/string_parser.out
@@ -0,0 +1,3 @@
+[#<struct IntLit text="123"@0>,
+ #<struct IntLit text="12345"@4>,
+ #<struct StringLit text=" Some String with \\\"escapes\\\""@11>]
diff --git a/app/server/vendor/parslet/example/parens.rb b/app/server/vendor/parslet/example/parens.rb
new file mode 100755
index 0000000..bcc20f4
--- /dev/null
+++ b/app/server/vendor/parslet/example/parens.rb
@@ -0,0 +1,42 @@
+# A small example that demonstrates the power of tree pattern matching. Also
+# uses '.as(:name)' to construct a tree that can reliably be matched
+# afterwards. 
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'pp'
+require 'parslet'
+
+module LISP # as in 'lots of insipid and stupid parenthesis'
+  class Parser < Parslet::Parser
+    rule(:balanced) {
+      str('(').as(:l) >> balanced.maybe.as(:m) >> str(')').as(:r)
+    }
+  
+    root(:balanced)
+  end
+
+  class Transform < Parslet::Transform
+    rule(:l => '(', :m => simple(:x), :r => ')') { 
+      # innermost :m will contain nil
+      x.nil? ? 1 : x+1
+    }
+  end
+end
+
+parser = LISP::Parser.new
+transform = LISP::Transform.new
+%w!
+  ()
+  (())
+  ((((()))))
+  ((())
+!.each do |pexp|
+  begin
+    result = parser.parse(pexp)
+    puts "#{"%20s"%pexp}: #{result.inspect} (#{transform.apply(result)} parens)"
+  rescue Parslet::ParseFailed => m
+    puts "#{"%20s"%pexp}: #{m}"
+  end
+  puts
+end
diff --git a/app/server/vendor/parslet/example/prec_calc.rb b/app/server/vendor/parslet/example/prec_calc.rb
new file mode 100755
index 0000000..889958f
--- /dev/null
+++ b/app/server/vendor/parslet/example/prec_calc.rb
@@ -0,0 +1,71 @@
+
+# A demonstration of the new precedence climbing infix expression parser. 
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'pp'
+require 'rspec'
+require 'parslet'
+require 'parslet/rig/rspec'
+require 'parslet/convenience'
+
+class InfixExpressionParser < Parslet::Parser
+  root :variable_assignment_list
+
+  rule(:space) { match[' '] }
+
+  def cts atom
+    atom >> space.repeat
+  end
+  def infix *args
+    Infix.new(*args)
+  end
+
+  # This is the heart of the infix expression parser: real simple definitions
+  # for all the pieces we need. 
+  rule(:mul_op) { cts match['*/'] }
+  rule(:add_op) { cts match['+-'] }
+  rule(:digit) { match['0-9'] }
+  rule(:integer) { cts digit.repeat(1).as(:int) }
+
+  rule(:expression) { infix_expression(integer, 
+    [mul_op, 2, :left], 
+    [add_op, 1, :right]) }
+
+  # And now adding variable assignments to that, just to a) demonstrate this
+  # embedded in a bigger parser, and b) make the example interesting. 
+  rule(:variable_assignment_list) { 
+    variable_assignment.repeat(1) }
+  rule(:variable_assignment) {
+    identifier.as(:ident) >> equal_sign >> expression.as(:exp) >> eol }
+  rule(:identifier) {
+    cts (match['a-z'] >> match['a-zA-Z0-9'].repeat) }
+  rule(:equal_sign) {
+    cts str('=') }
+  rule(:eol) {
+    cts(str("\n")) | any.absent? }
+end
+
+class InfixInterpreter < Parslet::Transform
+  rule(int: simple(:int)) { Integer(int) }
+  rule(ident: simple(:ident), exp: simple(:result)) { |d| 
+    d[:doc][d[:ident].to_s.strip.to_sym] = d[:result] }
+
+  rule(l: simple(:l), o: /^\*/, r: simple(:r)) { l * r }
+  rule(l: simple(:l), o: /^\+/, r: simple(:r)) { l + r }
+end
+
+input = <<ASSIGNMENTS
+a = 1
+b = 2
+c = 3 * 25
+d = 100 + 3*4
+ASSIGNMENTS
+
+puts input
+
+int_tree = InfixExpressionParser.new.parse_with_debug(input)
+bindings = {}
+result   = InfixInterpreter.new.apply(int_tree, doc: bindings)
+
+pp bindings
diff --git a/app/server/vendor/parslet/example/readme.rb b/app/server/vendor/parslet/example/readme.rb
new file mode 100755
index 0000000..36f38d0
--- /dev/null
+++ b/app/server/vendor/parslet/example/readme.rb
@@ -0,0 +1,30 @@
+# The example from the readme. With this, I am making sure that the readme 
+# 'works'. Is this too messy?
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+# cut here -------------------------------------------------------------------
+require 'parslet'
+include Parslet
+
+# Constructs a parser using a Parser Expression Grammar like DSL: 
+parser =  str('"') >> 
+          (
+            str('\\') >> any |
+            str('"').absent? >> any
+          ).repeat.as(:string) >> 
+          str('"')
+  
+# Parse the string and capture parts of the interpretation (:string above)        
+tree = parser.parse('"This is a \\"String\\" in which you can escape stuff"')
+
+tree # => {:string=>"This is a \\\"String\\\" in which you can escape stuff"}
+
+# Here's how you can grab results from that tree:
+
+transform = Parslet::Transform.new do
+  rule(:string => simple(:x)) { 
+    puts "String contents: #{x}" }
+end
+transform.apply(tree)
+
diff --git a/app/server/vendor/parslet/example/scopes.rb b/app/server/vendor/parslet/example/scopes.rb
new file mode 100755
index 0000000..8de07d9
--- /dev/null
+++ b/app/server/vendor/parslet/example/scopes.rb
@@ -0,0 +1,15 @@
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+require 'parslet'
+
+include Parslet
+
+parser = str('a').capture(:a) >> scope { str('b').capture(:a) } >> 
+  dynamic { |s,c| str(c.captures[:a]) }
+  
+begin
+  parser.parse('aba')
+  puts "parses 'aba'"
+rescue
+  puts "exception!"
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/example/seasons.rb b/app/server/vendor/parslet/example/seasons.rb
new file mode 100755
index 0000000..41c525b
--- /dev/null
+++ b/app/server/vendor/parslet/example/seasons.rb
@@ -0,0 +1,46 @@
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'parslet'
+require 'pp'
+
+tree = {:bud => {:stem => []}}
+
+class Spring < Parslet::Transform
+  rule(:stem => sequence(:branches)) {
+    {:stem => (branches + [{:branch => :leaf}])}
+  }
+end
+class Summer < Parslet::Transform
+  rule(:stem => subtree(:branches)) {
+    new_branches = branches.map { |b| {:branch => [:leaf, :flower]} }
+    {:stem => new_branches}
+  }
+end
+class Fall < Parslet::Transform
+  rule(:branch => sequence(:x)) {
+    x.each { |e| puts "Fruit!" if e==:flower }
+    x.each { |e| puts "Falling Leaves!" if e==:leaf }
+    {:branch => []}
+  }
+end
+class Winter < Parslet::Transform
+  rule(:stem => subtree(:x)) {
+    {:stem => []}
+  }
+end
+
+def do_seasons(tree)
+  [Spring, Summer, Fall, Winter].each do |season|
+    p "And when #{season} comes"
+    tree = season.new.apply(tree)
+    pp tree
+    puts
+  end
+  tree
+end
+
+# What marvel of life!
+tree = do_seasons(tree)
+tree = do_seasons(tree)
+
+
diff --git a/app/server/vendor/parslet/example/sentence.rb b/app/server/vendor/parslet/example/sentence.rb
new file mode 100755
index 0000000..b73d140
--- /dev/null
+++ b/app/server/vendor/parslet/example/sentence.rb
@@ -0,0 +1,36 @@
+# encoding: UTF-8
+
+# A small example contributed by John Mettraux (jmettraux) that demonstrates
+# working with Unicode. This only works on Ruby 1.9.
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'parslet'
+
+class Parser < Parslet::Parser
+  rule(:sentence) { (match('[^。]').repeat(1) >> str("。")).as(:sentence) }
+  rule(:sentences) { sentence.repeat }
+  root(:sentences)
+end
+
+class Transformer < Parslet::Transform
+  rule(:sentence => simple(:sen)) { sen.to_s }
+end
+
+string =
+  "RubyKaigi2009のテーマは、「変わる/変える」です。 前回の" +
+  "RubyKaigi2008のテーマであった「多様性」の言葉の通り、 " +
+  "2008年はRubyそのものに関しても、またRubyの活躍する舞台に関しても、 " +
+  "ますます多様化が進みつつあります。RubyKaigi2008は、そのような " +
+  "Rubyの生態系をあらためて認識する場となりました。 しかし、" +
+  "こうした多様化が進む中、異なる者同士が単純に距離を 置いたままでは、" +
+  "その違いを認識したところであまり意味がありません。 異なる実装、" +
+  "異なる思想、異なる背景といった、様々な多様性を理解しつつ、 " +
+  "すり合わせるべきものをすり合わせ、変えていくべきところを " +
+  "変えていくことが、豊かな未来へとつながる道に違いありません。"
+
+parser = Parser.new
+transformer = Transformer.new
+
+tree = parser.parse(string)
+p transformer.apply(tree)
diff --git a/app/server/vendor/parslet/example/simple.lit b/app/server/vendor/parslet/example/simple.lit
new file mode 100755
index 0000000..fa5a49b
--- /dev/null
+++ b/app/server/vendor/parslet/example/simple.lit
@@ -0,0 +1,3 @@
+123
+12345
+" Some String with \"escapes\""
diff --git a/app/server/vendor/parslet/example/simple_xml.rb b/app/server/vendor/parslet/example/simple_xml.rb
new file mode 100755
index 0000000..d6462e0
--- /dev/null
+++ b/app/server/vendor/parslet/example/simple_xml.rb
@@ -0,0 +1,54 @@
+# A simple xml parser. It is simple in the respect as that it doesn't address
+# any of the complexities of XML. This is ruby 1.9.
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'pp'
+require 'parslet'
+
+class XML < Parslet::Parser
+  root :document
+  
+  rule(:document) {
+    tag(close: false).as(:o) >> document.as(:i) >> tag(close: true).as(:c) |
+    text
+  }
+  
+  # Perhaps we could have some syntax sugar to make this more easy?
+  #
+  def tag(opts={})
+    close = opts[:close] || false
+    
+    parslet = str('<')
+    parslet = parslet >> str('/') if close
+    parslet = parslet >> (str('>').absent? >> match("[a-zA-Z]")).repeat(1).as(:name)
+    parslet = parslet >> str('>')
+    
+    parslet
+  end
+  
+  rule(:text) {
+    match('[^<>]').repeat(0)
+  }
+end
+
+def check(xml)
+  r = XML.new.parse(xml)
+
+  # We'll validate the tree by reducing valid pairs of tags into simply the
+  # string "verified". If the transformation ends on a string, then the
+  # document was 'valid'. 
+  #
+  t = Parslet::Transform.new do
+    rule(
+      o: {name: simple(:tag)}, 
+      c: {name: simple(:tag)}, 
+      i: simple(:t)
+    ) { 'verified' } 
+  end
+
+  t.apply(r)
+end
+
+pp check("<a><b>some text in the tags</b></a>")
+pp check("<b><b>some text in the tags</b></a>")
diff --git a/app/server/vendor/parslet/example/string_parser.rb b/app/server/vendor/parslet/example/string_parser.rb
new file mode 100755
index 0000000..b38bbe0
--- /dev/null
+++ b/app/server/vendor/parslet/example/string_parser.rb
@@ -0,0 +1,77 @@
+# A more complex parser that illustrates how a compiler might be constructed.
+# The parser recognizes strings and integer literals and constructs almost a
+# useful AST from the file contents. 
+
+require 'pp'
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+require 'parslet'
+
+include Parslet
+
+class LiteralsParser < Parslet::Parser
+  rule :space do
+    (match '[ ]').repeat(1)
+  end
+  
+  rule :literals do
+    (literal >> eol).repeat
+  end
+  
+  rule :literal do
+    (integer | string).as(:literal) >> space.maybe
+  end
+  
+  rule :string do
+    str('"') >> 
+    (
+      (str('\\') >> any) |
+      (str('"').absent? >> any)
+    ).repeat.as(:string) >> 
+    str('"')
+  end
+  
+  rule :integer do
+    match('[0-9]').repeat(1).as(:integer)
+  end
+  
+  rule :eol do
+    line_end.repeat(1)
+  end
+  
+  rule :line_end do
+    crlf >> space.maybe
+  end
+  
+  rule :crlf do
+    match('[\r\n]').repeat(1)
+  end
+
+  root :literals
+end
+
+input_name = File.join(File.dirname(__FILE__), 'simple.lit')
+file = File.read(input_name)
+
+parsetree = LiteralsParser.new.parse(file)
+  
+class Lit < Struct.new(:text)
+  def to_s
+    text.inspect
+  end
+end
+class StringLit < Lit
+end
+class IntLit < Lit
+  def to_s
+    text
+  end
+end
+
+transform = Parslet::Transform.new do
+  rule(:literal => {:integer => simple(:x)}) { IntLit.new(x) }
+  rule(:literal => {:string => simple(:s)}) { StringLit.new(s) }
+end
+  
+ast = transform.apply(parsetree)
+pp ast
diff --git a/app/server/vendor/parslet/example/test.lit b/app/server/vendor/parslet/example/test.lit
new file mode 100755
index 0000000..b1edd0d
--- /dev/null
+++ b/app/server/vendor/parslet/example/test.lit
@@ -0,0 +1,4 @@
+"THis is a string"
+"This is another string"
+"This string is escaped \"embedded quoted stuff \" "
+12 // an integer literal and a comment
diff --git a/app/server/vendor/parslet/experiments/error_reporter_variants.rb b/app/server/vendor/parslet/experiments/error_reporter_variants.rb
new file mode 100755
index 0000000..7a8e75c
--- /dev/null
+++ b/app/server/vendor/parslet/experiments/error_reporter_variants.rb
@@ -0,0 +1,15 @@
+
+class NopClass
+  def nop
+  end
+end
+
+nop = NopClass.new
+fal = nil
+
+n = 1000_000
+require 'benchmark'
+Benchmark.bm(9) do |bm|
+  bm.report(:unless)    { n.times do method_call if fal end }
+  bm.report(:nop)       { n.times do nop.nop end }
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/experiments/graphviz.rb b/app/server/vendor/parslet/experiments/graphviz.rb
new file mode 100755
index 0000000..8d78d65
--- /dev/null
+++ b/app/server/vendor/parslet/experiments/graphviz.rb
@@ -0,0 +1,102 @@
+# A small experiment that demonstrates graphivz painting of parsers. The parser
+# here has been taken from the example/ip_parser.rb
+#
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'parslet'
+
+module IPv4
+  include Parslet
+  
+  # A host identified by an IPv4 literal address is represented in
+  # dotted-decimal notation (a sequence of four decimal numbers in the range 0
+  # to 255, separated by "."), as described in [RFC1123] by reference to
+  # [RFC0952].  Note that other forms of dotted notation may be interpreted on
+  # some platforms, as described in Section 7.4, but only the dotted-decimal
+  # form of four octets is allowed by this grammar.
+  rule(:ipv4) {
+    (dec_octet >> str('.') >> dec_octet >> str('.') >>
+      dec_octet >> str('.') >> dec_octet).as(:ipv4)
+  }
+  
+  rule(:dec_octet) {
+    str('25') >> match("[0-5]") |
+    str('2') >> match("[0-4]") >> digit |
+    str('1') >> digit >> digit |
+    match('[1-9]') >> digit |
+    digit
+  }
+  
+  rule(:digit) {
+    match('[0-9]')
+  }
+end
+
+# Must be used in concert with IPv4
+module IPv6 
+  include Parslet
+  
+  rule(:colon) { str(':') }
+  rule(:dcolon) { colon >> colon }
+  
+  # h16 :
+  def h16r(times)
+    (h16 >> colon).repeat(times, times)
+  end
+  
+  # : h16
+  def h16l(times)
+    (colon >> h16).repeat(0,times)
+  end
+  
+  # A 128-bit IPv6 address is divided into eight 16-bit pieces. Each piece is
+  # represented numerically in case-insensitive hexadecimal, using one to four
+  # hexadecimal digits (leading zeroes are permitted). The eight encoded
+  # pieces are given most-significant first, separated by colon characters.
+  # Optionally, the least-significant two pieces may instead be represented in
+  # IPv4 address textual format. A sequence of one or more consecutive
+  # zero-valued 16-bit pieces within the address may be elided, omitting all
+  # their digits and leaving exactly two consecutive colons in their place to
+  # mark the elision.
+  rule(:ipv6) {
+    (
+      (
+        h16r(6) |
+        dcolon >> h16r(5) | 
+        h16.maybe >> dcolon >> h16r(4) |
+        (h16 >> h16l(1)).maybe >> dcolon >> h16r(3) |
+        (h16 >> h16l(2)).maybe >> dcolon >> h16r(2) |
+        (h16 >> h16l(3)).maybe >> dcolon >> h16r(1) |
+        (h16 >> h16l(4)).maybe >> dcolon
+      ) >> ls32 |
+      (h16 >> h16l(5)).maybe >> dcolon >> h16 |
+      (h16 >> h16l(6)).maybe >> dcolon
+    ).as(:ipv6)
+  }
+  
+  rule(:h16) {
+    hexdigit.repeat(1,4)
+  }
+  
+  rule(:ls32) {
+    (h16 >> colon >> h16) |
+    ipv4
+  }
+
+  rule(:hexdigit) {
+    digit | match("[a-fA-F]")
+  }
+end
+
+class IPP < Parslet::Parser
+  include IPv4
+  include IPv6
+
+  rule(:ipp) { ipv4 | ipv6 }
+  root :ipp
+end
+
+require 'parslet/graphviz'
+
+IPP.graph(pdf: 'ip.pdf')
\ No newline at end of file
diff --git a/app/server/vendor/parslet/experiments/heredoc.rb b/app/server/vendor/parslet/experiments/heredoc.rb
new file mode 100755
index 0000000..748c375
--- /dev/null
+++ b/app/server/vendor/parslet/experiments/heredoc.rb
@@ -0,0 +1,126 @@
+# An example that demonstrates how you would parse Ruby heredocs.
+# This is just a hack, however it toys around with some concepts that we 
+# just might use later on. 
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'pp'
+require 'parslet'
+require 'parslet/convenience'
+
+class Parslet::Atoms::Base
+  def space
+    self >> Parslet.str(' ').repeat
+  end
+  
+  def bind(name)
+    BoundParslet.new(self, name)
+  end
+  
+  def matches(name)
+    BindCompare.new(self, name)
+  end
+end
+
+class BoundParslet < Parslet::Atoms::Base
+  attr_reader :parslet, :name
+  def initialize(parslet, name)
+    super()
+    @parslet, @name = parslet, name
+  end
+  
+  def try(source, context)
+    parslet.try(source, context).tap { |result| 
+      set_binding(context, name, 
+        flatten(result.result))
+    }
+  end
+  
+  def set_binding(context, name, value)
+    b = context.instance_variable_get('@bindings') || {}
+    b.store name, value
+    p b
+    context.instance_variable_set('@bindings', b)
+  end
+    
+  def to_s_inner(prec)
+    parslet.to_s(prec)
+  end
+end
+
+class BindCompare < Parslet::Atoms::Base
+  attr_reader :parslet, :name
+  def initialize(parslet, name)
+    super()
+    @parslet, @name = parslet, name
+  end
+  
+  def try(source, context)
+    parslet.try(source, context).tap { |result| 
+      unless result.error?
+        value = flatten(result.result)
+      
+        p [value, bound_value(context, name), value == bound_value(context, name)]
+        unless value == bound_value(context, name)
+          p :error_return
+          return error(source, "Bound value doesn't match.")
+        end
+      end
+    }
+  end
+  
+  def bound_value(context, name)
+    b = context.instance_variable_get('@bindings') || {}
+    b[name]
+  end
+    
+  def to_s_inner(prec)
+    parslet.to_s(prec)
+  end
+end
+
+class HereDocs < Parslet::Parser
+  root(:document)
+  
+  # a document of heredocs
+  rule(:document) { heredoc.repeat }
+  # a whole heredoc led by 'a' or 'b'
+  rule(:heredoc)  { 
+    space? >> 
+      intro.as(:intro) >> 
+      backticks >> 
+      tag.bind(:tag) >> doc.as(:doc) | 
+    space? >> eol
+  }
+  # essentially just 'a' or 'b'
+  rule(:intro) { (str('a') | str('b')).space }
+  # the tag that delimits the heredoc
+  rule(:tag) { match['A-Z'].repeat(1) }
+  # the doc itself, ends when tag is found at start of line
+  rule(:doc) { gobble_eol >> doc_line }
+  # a doc_line is either the stop tag followed by nothing 
+  # or just any kind of line.
+  rule(:doc_line) { 
+    (end_tag.absent? >> gobble_eol).repeat >> end_tag
+  }
+  rule(:end_tag) { tag.matches(:tag) >> space? >> eol }
+  # eats anything until an end of line is found
+  rule(:gobble_eol) { (eol.absent? >> any).repeat >> eol }
+
+  rule(:eol) { match['\n\r'].repeat(1) }
+  rule(:space?) { str(' ').repeat }
+  rule(:backticks) { str('<<').space }
+end
+
+code = %q(
+  a <<HERE
+  b <<THERE
+HERE
+  b <<THEN
+  a <<HERE
+THE
+HERE
+THEN
+)
+
+pp HereDocs.new.parse_with_debug(code)
diff --git a/app/server/vendor/parslet/experiments/optimizer.rb b/app/server/vendor/parslet/experiments/optimizer.rb
new file mode 100755
index 0000000..98f210c
--- /dev/null
+++ b/app/server/vendor/parslet/experiments/optimizer.rb
@@ -0,0 +1,271 @@
+# Example that demonstrates how a simple erb-like parser could be constructed. 
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'parslet'
+require 'parslet/atoms/visitor'
+require 'parslet/convenience'
+require 'blankslate'
+
+class ErbParser < Parslet::Parser
+  rule(:ruby) { (str('%>').absent? >> any).repeat.as(:ruby) }
+  
+  rule(:expression) { (str('=') >> ruby).as(:expression) }
+  rule(:comment) { (str('#') >> ruby).as(:comment) }
+  rule(:code) { ruby.as(:code) }
+  rule(:erb) { expression | comment | code }
+  
+  rule(:erb_with_tags) { str('<%') >> erb >> str('%>') }
+  rule(:text) { (str('<%').absent? >> any).repeat(1) }
+  
+  rule(:text_with_ruby) { (text.as(:text) | erb_with_tags).repeat.as(:text) }
+  root(:text_with_ruby)
+end
+
+class Parslet::Source
+  def match_excluding str
+    slice_str = @str.check_until(Regexp.new(Regexp.escape(str)))
+    return @str.rest_size unless slice_str
+    return slice_str.size - str.size
+  end
+end
+
+class AbsentParser < Parslet::Atoms::Base
+  def initialize absent
+    @absent = absent
+  end
+
+  def try(source, context, consume_all)
+    excluding_length = source.match_excluding(@absent)
+
+    if excluding_length >= 1
+      return succ(source.consume(excluding_length))
+    else
+      return context.err(self, source, "Failed absence #{@absent.inspect}.")
+    end
+  end
+end
+
+class Parslet::Optimizer
+  module DSL
+    def >> other
+      Match::Sequence.new(self, other)
+    end
+    def absent?
+      Match::Lookahead.new(false, self)
+    end
+    def repeat(min=0, max=nil)
+      Match::Repetition.new(self, min, max)
+    end
+  end
+  module Match
+    class Base
+      include DSL
+
+      def visit_parser(root)
+        false
+      end
+      def visit_entity(name, block)
+        false
+      end
+      def visit_named(name, atom)
+        false
+      end
+      def visit_repetition(tag, min, max, atom)
+        false
+      end
+      def visit_alternative(alternatives)
+        false
+      end
+      def visit_sequence(sequence)
+        false
+      end
+      def visit_lookahead(positive, atom)
+        false
+      end
+      def visit_re(regexp)
+        false
+      end
+      def visit_str(str)
+        false
+      end
+      def match(other, bindings)
+        @bindings = bindings
+        other.accept(self)
+      end
+    end
+    class Str < Base
+      def initialize(variable)
+        @variable = variable
+      end
+      def visit_str(str)
+        if bound_value=@bindings[@variable]
+          return bound_value == str
+        else
+          @bindings[@variable] = str
+          return true
+        end
+      end
+    end
+    class Lookahead < Base
+      def initialize(positive, expression)
+        @positive, @expression = positive, expression
+      end
+      def visit_lookahead(positive, atom)
+        positive == @positive && 
+          @expression.match(atom, @bindings)
+      end
+    end
+    class Sequence < Base
+      def initialize(*parslets)
+        @parslets = parslets
+      end
+      def visit_sequence(sequence)
+        sequence.zip(@parslets).all? { |atom, expr| expr.match(atom, @bindings) }
+      end
+    end
+    class Repetition < Base
+      def initialize(expression, min, max)
+        @min, @max, @expression = min, max, expression
+      end
+      def visit_repetition(tag, min, max, atom)
+        @min == min && @max == max && @expression.match(atom, @bindings)
+      end
+    end
+    class Re < Base
+      def initialize(variable)
+        @variable = variable
+      end
+      def visit_re(regexp)
+        case @variable
+          when Symbol
+            p [@variable, regexp]
+            fail
+        else
+          @variable == regexp
+        end
+      end
+    end
+  end
+
+  def self.str(var)
+    Match::Str.new(var)
+  end
+  def self.any
+    Match::Re.new('.')
+  end
+  
+  class Rule
+    def initialize(expression, replacement)
+      @expression, @replacement = expression, replacement
+    end
+
+    class Context < BlankSlate
+      def initialize(bindings)
+        @bindings = bindings
+      end
+      def method_missing(sym, *args, &block)
+        if args.size == 0 && !block && @bindings.has_key?(sym)
+          return @bindings[sym]
+        end
+        
+        super
+      end
+      def call(callable)
+        instance_eval(&callable)
+      end
+    end
+
+    def match other
+      bindings = {}
+      if @expression.match(other, bindings)
+        return bindings
+      end
+    end
+    def call(bindings)
+      context = Context.new(bindings)
+      context.call(@replacement)
+    end
+  end
+  def self.rule(expression, &replacement)
+    rules << Rule.new(expression, replacement)
+  end
+  def self.rules
+    @rules ||= []
+  end
+  def rules
+    self.class.rules
+  end
+
+  class Transform
+    def initialize(rules)
+      @rules = rules
+      @candidates = []
+    end
+
+    def default_parser(root)
+      root.accept(self)
+    end
+    def default_entity(name, block)
+      Parslet::Atoms::Entity.new(name) { block.call.accept(self) }
+    end
+    def default_named(name, atom)
+      Parslet::Atoms::Named.new(atom.accept(self), name)
+    end
+    def default_repetition(tag, min, max, atom)
+      Parslet::Atoms::Repetition.new(atom.accept(self), min, max, tag)
+    end
+    def default_alternative(alternatives)
+      Parslet::Atoms::Alternative.new(
+        *alternatives.map { |atom| atom.accept(self) })
+    end
+    def default_sequence(sequence)
+      Parslet::Atoms::Sequence.new(
+        *sequence.map { |atom| atom.accept(self) })
+    end
+    def default_lookahead(positive, atom)
+      Parslet::Atoms::Lookahead.new(atom, positive)
+    end
+    def default_re(regexp)
+      Parslet::Atoms::Re.new(regexp)
+    end
+    def default_str(str)
+      Parslet::Atoms::Str.new(str)
+    end
+
+    def method_missing(sym, *args, &block)
+      if (md=sym.to_s.match(/visit_([a-z]+)/)) && !block
+        # Obtain the default, which is a completely transformed new parser
+        default = self.send("default_#{md[1]}", *args)
+        # Try transforming this parser again at the current level
+        return transform(default)
+      end
+
+      super
+    end
+    def transform(atom)
+      # Try to match one of the rules against the newly constructed tree.
+      @rules.each do |rule|
+        if bindings=rule.match(atom)
+          return rule.call(bindings)
+        end
+      end
+
+      # No match, returning new atom.
+      return atom
+    end
+  end
+
+  def apply(parser)
+    parser.accept(Transform.new(rules))
+  end
+end
+class Optimizer < Parslet::Optimizer
+  rule((str(:x).absent? >> any).repeat(1)) {
+    AbsentParser.new(x) }
+end
+
+parser = ErbParser.new
+optimized_parser = Optimizer.new.apply(parser)
+# p optimized_parser.parse(File.read(ARGV.first))
+p parser.parse_with_debug(File.read(ARGV.first))
diff --git a/app/server/vendor/parslet/experiments/return_values.rb b/app/server/vendor/parslet/experiments/return_values.rb
new file mode 100755
index 0000000..6f57ccd
--- /dev/null
+++ b/app/server/vendor/parslet/experiments/return_values.rb
@@ -0,0 +1,31 @@
+def pair
+  [true, "123"]
+end
+
+Success = Struct.new(:value)
+def struct
+  Success.new("123")
+end
+
+class SuccessO
+  def initialize(value)
+    @value = value
+  end
+end
+def klass
+  SuccessO.new("123")
+end
+
+def raise_ex
+  fail "123"
+end
+
+
+n = 1000_00
+require 'benchmark'
+Benchmark.bm(9) do |bm|
+  bm.report(:pair)    { n.times do pair end }
+  bm.report(:struct)  { n.times do struct end }
+  bm.report(:klass)  { n.times do klass end }
+  bm.report(:throw)  { n.times do raise_ex rescue nil end }
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet.rb b/app/server/vendor/parslet/lib/parslet.rb
new file mode 100755
index 0000000..2fef5ce
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet.rb
@@ -0,0 +1,302 @@
+# A simple parser generator library. Typical usage would look like this: 
+#
+#   require 'parslet'
+#        
+#   class MyParser < Parslet::Parser
+#     rule(:a) { str('a').repeat }
+#     root(:a)        
+#   end
+#        
+#   pp MyParser.new.parse('aaaa')   # => 'aaaa'@0
+#   pp MyParser.new.parse('bbbb')   # => Parslet::Atoms::ParseFailed: 
+#                                   #    Don't know what to do with bbbb at line 1 char 1.
+#
+# The simple DSL allows you to define grammars in PEG-style. This kind of
+# grammar construction does away with the ambiguities that usually comes with
+# parsers; instead, it allows you to construct grammars that are easier to
+# debug, since less magic is involved. 
+#
+# Parslet is typically used in stages: 
+#
+# 
+# * Parsing the input string; this yields an intermediary tree, see
+#   Parslet.any, Parslet.match, Parslet.str, Parslet::ClassMethods#rule and
+#   Parslet::ClassMethods#root.
+# * Transformation of the tree into something useful to you, see
+#   Parslet::Transform, Parslet.simple, Parslet.sequence and Parslet.subtree.
+#
+# The first stage is traditionally intermingled with the second stage; output
+# from the second stage is usually called the 'Abstract Syntax Tree' or AST. 
+#
+# The stages are completely decoupled; You can change your grammar around and
+# use the second stage to isolate the rest of your code from the changes
+# you've effected. 
+#
+# == Further reading
+# 
+# All parslet atoms are subclasses of {Parslet::Atoms::Base}. You might want to
+# look at all of those: {Parslet::Atoms::Re}, {Parslet::Atoms::Str},
+# {Parslet::Atoms::Repetition}, {Parslet::Atoms::Sequence},
+# {Parslet::Atoms::Alternative}.
+#
+# == When things go wrong
+#
+# A parse that fails will raise {Parslet::ParseFailed}. This exception contains
+# all the details of what went wrong, including a detailed error trace that 
+# can be printed out as an ascii tree. ({Parslet::Cause})
+#
+module Parslet
+  # Extends classes that include Parslet with the module
+  # {Parslet::ClassMethods}.
+  #
+  def self.included(base)
+    base.extend(ClassMethods)
+  end
+  
+  # Raised when the parse failed to match. It contains the message that should
+  # be presented to the user. More details can be extracted from the
+  # exceptions #cause member: It contains an instance of {Parslet::Cause} that
+  # stores all the details of your failed parse in a tree structure. 
+  #
+  #   begin
+  #     parslet.parse(str)
+  #   rescue Parslet::ParseFailed => failure
+  #     puts failure.cause.ascii_tree
+  #   end
+  #
+  # Alternatively, you can just require 'parslet/convenience' and call the
+  # method #parse_with_debug instead of #parse. This method will never raise
+  # and print error trees to stdout.
+  #
+  #   require 'parslet/convenience'
+  #   parslet.parse_with_debug(str)
+  #
+  class ParseFailed < StandardError
+    def initialize(message, cause=nil)
+      super(message)
+      @cause = cause
+    end
+    
+    # Why the parse failed. 
+    #
+    # @return [Parslet::Cause]
+    attr_reader :cause 
+  end
+  
+  module ClassMethods
+    # Define an entity for the parser. This generates a method of the same
+    # name that can be used as part of other patterns. Those methods can be
+    # freely mixed in your parser class with real ruby methods.
+    # 
+    #   class MyParser
+    #     include Parslet
+    #
+    #     rule(:bar) { str('bar') }
+    #     rule(:twobar) do
+    #       bar >> bar
+    #     end
+    #
+    #     root :twobar
+    #   end
+    #
+    def rule(name, &definition)
+      define_method(name) do
+        @rules ||= {}     # <name, rule> memoization
+        return @rules[name] if @rules.has_key?(name)
+        
+        # Capture the self of the parser class along with the definition.
+        definition_closure = proc {
+          self.instance_eval(&definition)
+        }
+        
+        @rules[name] = Atoms::Entity.new(name, &definition_closure)
+      end
+    end
+  end
+
+  # Allows for delayed construction of #match. See also Parslet.match.
+  #
+  # @api private
+  class DelayedMatchConstructor
+    def [](str)
+      Atoms::Re.new("[" + str + "]")
+    end
+  end
+  
+  # Returns an atom matching a character class. All regular expressions can be
+  # used, as long as they match only a single character at a time. 
+  #
+  #   match('[ab]')     # will match either 'a' or 'b'
+  #   match('[\n\s]')   # will match newlines and spaces
+  #
+  # There is also another (convenience) form of this method: 
+  #
+  #   match['a-z']      # synonymous to match('[a-z]')
+  #   match['\n']       # synonymous to match('[\n]')
+  #
+  # @overload match(str)
+  #   @param str [String] character class to match (regexp syntax)
+  #   @return [Parslet::Atoms::Re] a parslet atom
+  #
+  def match(str=nil)
+    return DelayedMatchConstructor.new unless str
+    
+    return Atoms::Re.new(str)
+  end
+  module_function :match
+  
+  # Returns an atom matching the +str+ given:
+  #
+  #   str('class')      # will match 'class' 
+  #
+  # @param str [String] string to match verbatim
+  # @return [Parslet::Atoms::Str] a parslet atom
+  # 
+  def str(str)
+    Atoms::Str.new(str)
+  end
+  module_function :str
+  
+  # Returns an atom matching any character. It acts like the '.' (dot)
+  # character in regular expressions.
+  #
+  #   any.parse('a')    # => 'a'
+  #
+  # @return [Parslet::Atoms::Re] a parslet atom
+  #
+  def any
+    Atoms::Re.new('.')
+  end
+  module_function :any
+  
+  # Introduces a new capture scope. This means that all old captures stay
+  # accessible, but new values stored will only be available during the block
+  # given and the old values will be restored after the block. 
+  #
+  # Example: 
+  #   # :a will be available until the end of the block. Afterwards, 
+  #   # :a from the outer scope will be available again, if such a thing 
+  #   # exists. 
+  #   scope { str('a').capture(:a) }
+  #
+  def scope(&block)
+    Parslet::Atoms::Scope.new(block)
+  end
+  module_function :scope
+  
+  # Designates a piece of the parser as being dynamic. Dynamic parsers can
+  # either return a parser at runtime, which will be applied on the input, or
+  # return a result from a parse. 
+  # 
+  # Dynamic parse pieces are never cached and can introduce performance
+  # abnormalitites - use sparingly where other constructs fail. 
+  # 
+  # Example: 
+  #   # Parses either 'a' or 'b', depending on the weather
+  #   dynamic { rand() < 0.5 ? str('a') : str('b') }
+  #   
+  def dynamic(&block)
+    Parslet::Atoms::Dynamic.new(block)
+  end
+  module_function :dynamic
+
+  # Returns a parslet atom that parses infix expressions. Operations are 
+  # specified as a list of <atom, precedence, associativity> tuples, where 
+  # atom is simply the parslet atom that matches an operator, precedence is 
+  # a number and associativity is either :left or :right. 
+  # 
+  # Higher precedence indicates that the operation should bind tighter than
+  # other operations with lower precedence. In common algebra, '+' has 
+  # lower precedence than '*'. So you would have a precedence of 1 for '+' and
+  # a precedence of 2 for '*'. Only the order relation between these two 
+  # counts, so any number would work. 
+  #
+  # Associativity is what decides what interpretation to take for strings that
+  # are ambiguous like '1 + 2 + 3'. If '+' is specified as left associative, 
+  # the expression would be interpreted as '(1 + 2) + 3'. If right 
+  # associativity is chosen, it would be interpreted as '1 + (2 + 3)'. Note 
+  # that the hash trees output reflect that choice as well. 
+  #
+  # Example:
+  #   infix_expression(integer, [add_op, 1, :left])
+  #   # would parse things like '1 + 2'
+  #
+  # @param element [Parslet::Atoms::Base] elements that take the NUMBER position
+  #    in the expression
+  # @param operations [Array<(Parslet::Atoms::Base, Integer, {:left, :right})>]
+  #  
+  # @see Parslet::Atoms::Infix
+  #
+  def infix_expression(element, *operations)
+    Parslet::Atoms::Infix.new(element, operations)
+  end
+  module_function :infix_expression
+  
+  # A special kind of atom that allows embedding whole treetop expressions
+  # into parslet construction. 
+  #
+  #   # the same as str('a') >> str('b').maybe
+  #   exp(%Q("a" "b"?))     
+  #
+  # @param str [String] a treetop expression
+  # @return [Parslet::Atoms::Base] the corresponding parslet parser
+  #
+  def exp(str)
+    Parslet::Expression.new(str).to_parslet
+  end
+  module_function :exp
+  
+  # Returns a placeholder for a tree transformation that will only match a
+  # sequence of elements. The +symbol+ you specify will be the key for the
+  # matched sequence in the returned dictionary.
+  #
+  #   # This would match a body element that contains several declarations.
+  #   { :body => sequence(:declarations) }
+  #
+  # The above example would match <code>:body => ['a', 'b']</code>, but not
+  # <code>:body => 'a'</code>. 
+  #
+  # see {Parslet::Transform}
+  #
+  def sequence(symbol)
+    Pattern::SequenceBind.new(symbol)
+  end
+  module_function :sequence
+  
+  # Returns a placeholder for a tree transformation that will only match
+  # simple elements. This matches everything that <code>#sequence</code>
+  # doesn't match.
+  #
+  #   # Matches a single header. 
+  #   { :header => simple(:header) }
+  #
+  # see {Parslet::Transform}
+  #
+  def simple(symbol)
+    Pattern::SimpleBind.new(symbol)
+  end
+  module_function :simple
+  
+  # Returns a placeholder for tree transformation patterns that will match 
+  # any kind of subtree. 
+  #
+  #   { :expression => subtree(:exp) }
+  #
+  def subtree(symbol)
+    Pattern::SubtreeBind.new(symbol)
+  end
+  module_function :subtree
+
+  autoload :Expression, 'parslet/expression'
+end
+
+require 'parslet/slice'
+require 'parslet/cause'
+require 'parslet/source'
+require 'parslet/atoms'
+require 'parslet/pattern'
+require 'parslet/pattern/binding'
+require 'parslet/transform'
+require 'parslet/parser'
+require 'parslet/error_reporter'
+require 'parslet/scope'
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/accelerator.rb b/app/server/vendor/parslet/lib/parslet/accelerator.rb
new file mode 100755
index 0000000..79987d3
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/accelerator.rb
@@ -0,0 +1,161 @@
+
+
+# Optimizes the parsers by pattern matching on the parser atoms and replacing
+# matches with better versions. See the file qed/accelerators.md for a more
+# in-depth description.
+#
+# Example: 
+#   quote = str('"')
+#   parser = quote >> (quote.absent? >> any).repeat >> quote
+#
+#   A = Accelerator # for making what follows a bit shorter
+#   optimized_parser = A.apply(parser, 
+#     A.rule( (A.str(:x).absent? >> A.any).repeat ) { GobbleUp.new(x) })
+#
+#   optimized_parser.parse('"Parsing is now fully optimized! (tm)"')
+#
+module Parslet::Accelerator
+
+  # An expression to match against a tree of parser atoms. Normally, an
+  # expression is produced by Parslet::Accelerator.any, 
+  # Parslet::Accelerator.str or Parslet::Accelerator.re.
+  #
+  # Expressions can be chained much like parslet atoms can be: 
+  #
+  #   expr.repeat(1)      # matching repetition
+  #   expr.absent?        # matching absent?
+  #   expr.present?       # matching present?
+  #   expr1 >> expr2      # matching a sequence
+  #   expr1 | expr2       # matching an alternation
+  # 
+  # @see Parslet::Accelerator.str
+  # @see Parslet::Accelerator.re
+  # @see Parslet::Accelerator.any
+  #
+  # @see Parslet::Accelerator
+  # 
+  class Expression
+    attr_reader :type
+    attr_reader :args
+
+    def initialize(type, *args)
+      @type = type
+      @args = args
+    end
+
+    # @return [Expression]
+    def >> other_expr
+      join_or_new :seq, other_expr
+    end
+
+    # @return [Expression]
+    def | other_expr
+      join_or_new :alt, other_expr
+    end
+
+    # @return [Expression]
+    def absent?
+      Expression.new(:absent, self)
+    end
+    # @return [Expression]
+    def present?
+      Expression.new(:present, self)
+    end
+
+    # @return [Expression]
+    def repeat min=0, max=nil
+      Expression.new(:rep, min, max, self)
+    end
+
+    # @return [Expression]
+    def as name
+      Expression.new(:as, name)
+    end
+
+    # @api private
+    # @return [Expression]
+    def join_or_new tag, other_expr
+      if type == tag
+        @args << other_expr
+      else
+        Expression.new(tag, self, other_expr)
+      end
+    end
+  end
+
+module_function 
+  # Returns a match expression that will match `str` parslet atoms.
+  #
+  # @return [Parslet::Accelerator::Expression]
+  #
+  def str variable, *constraints
+    Expression.new(:str, variable, *constraints)
+  end
+
+  # Returns a match expression that will match `match` parslet atoms.
+  #
+  # @return [Parslet::Accelerator::Expression]
+  #
+  def re variable, *constraints
+    Expression.new(:re, variable, *constraints)
+  end
+
+  # Returns a match expression that will match `any` parslet atoms.
+  #
+  # @return [Parslet::Accelerator::Expression]
+  #
+  def any
+    Expression.new(:re, ".")
+  end
+
+  # Given a parslet atom and an expression, will determine if the expression
+  # matches the atom. If successful, returns the bindings into the pattern
+  # that were made. If no bindings had to be made to make the match successful, 
+  # the empty hash is returned. 
+  #
+  # @param atom [Parslet::Atoms::Base] parslet atom to match against
+  # @param expr [Parslet::Accelerator::Expression] expression to match
+  # @return [nil, Hash] bindings for the match, nil on failure
+  #
+  def match atom, expr
+    engine = Engine.new
+
+    return engine.bindings if engine.match(atom, expr)
+  end
+
+  # Constructs an accelerator rule. A rule is a matching expression and the
+  # code that should be executed once the expression could be bound to a 
+  # parser. 
+  #
+  # Example: 
+  #   Accelerator.rule(Accelerator.any) { Parslet.match('.') }
+  #
+  def rule expression, &action
+    [expression, action]
+  end
+
+  # Given a parslet atom and a set of rules, tries to match the rules 
+  # recursively through the parslet atom. Once a rule could be matched, 
+  # its action block will be called.
+  #
+  # Example: 
+  #   quote = str('"')
+  #   parser = quote >> (quote.absent? >> any).repeat >> quote
+  #
+  #   A = Accelerator # for making what follows a bit shorter
+  #   optimized_parser = A.apply(parser, 
+  #     A.rule( (A.str(:x).absent? >> A.any).repeat ) { GobbleUp.new(x) })
+  #
+  #   optimized_parser.parse('"Parsing is now fully optimized! (tm)"')
+  #
+  # @param atom [Parslet::Atoms::Base] a parser to optimize
+  # @param *rules [Parslet::Accelerator::Rule] rules produced by .rule
+  # @return [Parslet::Atoms::Base] optimized parser
+  #
+  def apply atom, *rules
+    Application.new(atom, rules).call
+  end
+end
+
+require 'parslet/accelerator/engine'
+require 'parslet/accelerator/application'
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/accelerator/application.rb b/app/server/vendor/parslet/lib/parslet/accelerator/application.rb
new file mode 100755
index 0000000..8015cc8
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/accelerator/application.rb
@@ -0,0 +1,62 @@
+
+# @api private
+module Parslet::Accelerator
+  class Application
+    def initialize atom, rules
+      @atom = atom
+      @rules = rules
+    end
+
+    def call
+      @atom.accept(self)
+    end
+
+    def visit_parser(root)
+      transform root.accept(self)
+    end
+    def visit_entity(name, block)
+      transform Parslet::Atoms::Entity.new(name) { block.call.accept(self) }
+    end
+    def visit_named(name, atom)
+      transform Parslet::Atoms::Named.new(atom.accept(self), name)
+    end
+    def visit_repetition(tag, min, max, atom)
+      transform Parslet::Atoms::Repetition.new(atom.accept(self), min, max, tag)
+    end
+    def visit_alternative(alternatives)
+      transform Parslet::Atoms::Alternative.new(
+        *alternatives.map { |atom| atom.accept(self) })
+    end
+    def visit_sequence(sequence)
+      transform Parslet::Atoms::Sequence.new(
+        *sequence.map { |atom| atom.accept(self) })
+    end
+    def visit_lookahead(positive, atom)
+      transform Parslet::Atoms::Lookahead.new(atom, positive)
+    end
+    def visit_re(regexp)
+      transform Parslet::Atoms::Re.new(regexp)
+    end
+    def visit_str(str)
+      transform Parslet::Atoms::Str.new(str)
+    end
+
+    def transform atom
+      @rules.each do |expr, action|
+        # Try and match each rule in turn
+        binding = Parslet::Accelerator.match(atom, expr)
+        if binding
+          # On a successful match, allow the rule action to transform the
+          # parslet into something new. 
+          ctx = Parslet::Context.new(binding)
+          return ctx.instance_eval(&action)
+        end
+      end # rules.each 
+
+      # If no rule matches, this is the fallback - a clean new parslet atom.
+      return atom
+    end
+  end
+end
+
+require 'parslet/context'
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/accelerator/engine.rb b/app/server/vendor/parslet/lib/parslet/accelerator/engine.rb
new file mode 100755
index 0000000..1f08181
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/accelerator/engine.rb
@@ -0,0 +1,112 @@
+
+require 'parslet/atoms/visitor'
+
+module Parslet::Accelerator
+  # @api private
+  class Apply
+    def initialize(engine, expr)
+      @engine = engine
+      @expr = expr
+    end
+
+    def visit_parser(root)
+      false
+    end
+    def visit_entity(name, block)
+      false
+    end
+    def visit_named(name, atom)
+      match(:as) do |key|
+        @engine.try_bind(key, name)
+      end
+    end
+    def visit_repetition(tag, min, max, atom)
+      match(:rep) do |e_min, e_max, expr|
+        e_min == min && e_max == max && @engine.match(atom, expr)
+      end
+    end
+    def visit_alternative(alternatives)
+      match(:alt) do |*expressions|
+        return false if alternatives.size != expressions.size
+
+        alternatives.zip(expressions).all? do |atom, expr|
+          @engine.match(atom, expr)
+        end
+      end
+    end
+    def visit_sequence(sequence)
+      match(:seq) do |*expressions|
+        return false if sequence.size != expressions.size
+
+        sequence.zip(expressions).all? do |atom, expr|
+          @engine.match(atom, expr)
+        end
+      end
+    end
+    def visit_lookahead(positive, atom)
+      match(:absent) do |expr|
+        return positive == false && @engine.match(atom, expr)
+      end
+      match(:present) do |expr|
+        return positive == true && @engine.match(atom, expr)
+      end
+    end
+    def visit_re(regexp)
+      match(:re) do |*bind_conditions|
+        bind_conditions.all? { |bind_cond| 
+          @engine.try_bind(bind_cond, regexp) }
+      end
+    end
+    def visit_str(str)
+      match(:str) do |*bind_conditions|
+        bind_conditions.all? { |bind_cond| 
+          @engine.try_bind(bind_cond, str) }
+      end
+    end
+
+    def match(type_tag)
+      expr_tag = @expr.type
+      if expr_tag == type_tag
+        yield *@expr.args
+      end
+    end
+  end
+
+  # @api private
+  class Engine
+    attr_reader :bindings
+
+    def initialize 
+      @bindings = {}
+    end
+
+    def match(atom, expr)
+      atom.accept(
+        Apply.new(self, expr))
+    end
+
+    def try_bind(variable, value)
+      if bound? variable
+        return value == lookup(variable)
+      else
+        case variable
+          when Symbol
+            bind(variable, value)
+        else
+          # This does not look like a variable - let's try matching it against
+          # the value: 
+          variable === value
+        end    
+      end
+    end
+    def bound? var
+      @bindings.has_key? var
+    end
+    def lookup var
+      @bindings[var]
+    end
+    def bind var, val
+      @bindings[var] = val
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/atoms.rb b/app/server/vendor/parslet/lib/parslet/atoms.rb
new file mode 100755
index 0000000..5a4222c
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms.rb
@@ -0,0 +1,35 @@
+
+# This is where parslets name comes from: Small parser atoms.
+#
+module Parslet::Atoms
+  # The precedence module controls parenthesis during the #inspect printing
+  # of parslets. It is not relevant to other aspects of the parsing. 
+  #
+  module Precedence
+    prec = 0
+    BASE       = (prec+=1)    # everything else
+    LOOKAHEAD  = (prec+=1)    # &SOMETHING
+    REPETITION = (prec+=1)    # 'a'+, 'a'?
+    SEQUENCE   = (prec+=1)    # 'a' 'b'
+    ALTERNATE  = (prec+=1)    # 'a' | 'b'
+    OUTER      = (prec+=1)    # printing is done here.
+  end
+  
+  require 'parslet/atoms/can_flatten'
+  require 'parslet/atoms/context'
+  require 'parslet/atoms/dsl'
+  require 'parslet/atoms/base'
+  require 'parslet/atoms/named'
+  require 'parslet/atoms/lookahead'
+  require 'parslet/atoms/alternative'
+  require 'parslet/atoms/sequence'
+  require 'parslet/atoms/repetition'
+  require 'parslet/atoms/re'
+  require 'parslet/atoms/str'
+  require 'parslet/atoms/entity'
+  require 'parslet/atoms/capture'
+  require 'parslet/atoms/dynamic'
+  require 'parslet/atoms/scope'
+  require 'parslet/atoms/infix'
+end
+
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/alternative.rb b/app/server/vendor/parslet/lib/parslet/atoms/alternative.rb
new file mode 100755
index 0000000..c5f2e39
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/alternative.rb
@@ -0,0 +1,50 @@
+
+# Alternative during matching. Contains a list of parslets that is tried each
+# one in turn. Only fails if all alternatives fail. 
+#
+# Example: 
+# 
+#   str('a') | str('b')   # matches either 'a' or 'b'
+#
+class Parslet::Atoms::Alternative < Parslet::Atoms::Base
+  attr_reader :alternatives
+  
+  # Constructs an Alternative instance using all given parslets in the order
+  # given. This is what happens if you call '|' on existing parslets, like 
+  # this: 
+  #
+  #   str('a') | str('b')
+  #
+  def initialize(*alternatives)
+    super()
+    
+    @alternatives = alternatives
+    @error_msg = "Expected one of #{alternatives.inspect}"
+  end
+
+  #---
+  # Don't construct a hanging tree of Alternative parslets, instead store them
+  # all here. This reduces the number of objects created.
+  #+++
+  def |(parslet)
+    self.class.new(*@alternatives + [parslet])
+  end
+  
+  def try(source, context, consume_all)
+    errors = alternatives.map { |a|
+      success, value = result = a.apply(source, context, consume_all)
+      return result if success
+      
+      # Aggregate all errors
+      value
+    }
+    
+    # If we reach this point, all alternatives have failed. 
+    context.err(self, source, @error_msg, errors)
+  end
+
+  precedence ALTERNATE
+  def to_s_inner(prec)
+    alternatives.map { |a| a.to_s(prec) }.join(' / ')
+  end
+end
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/base.rb b/app/server/vendor/parslet/lib/parslet/atoms/base.rb
new file mode 100755
index 0000000..4687905
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/base.rb
@@ -0,0 +1,151 @@
+# Base class for all parslets, handles orchestration of calls and implements
+# a lot of the operator and chaining methods.
+#
+# Also see Parslet::Atoms::DSL chaining parslet atoms together.
+#
+class Parslet::Atoms::Base
+  include Parslet::Atoms::Precedence
+  include Parslet::Atoms::DSL
+  include Parslet::Atoms::CanFlatten
+  
+  # Given a string or an IO object, this will attempt a parse of its contents
+  # and return a result. If the parse fails, a Parslet::ParseFailed exception
+  # will be thrown. 
+  #
+  # @param io [String, Source] input for the parse process
+  # @option options [Parslet::ErrorReporter] :reporter error reporter to use, 
+  #   defaults to Parslet::ErrorReporter::Tree 
+  # @option options [Boolean] :prefix Should a prefix match be accepted? 
+  #   (default: false)
+  # @return [Hash, Array, Parslet::Slice] PORO (Plain old Ruby object) result
+  #   tree
+  #
+  def parse(io, options={})
+    source = io.respond_to?(:line_and_column) ? 
+      io : 
+      Parslet::Source.new(io)
+
+    # Try to cheat. Assuming that we'll be able to parse the input, don't 
+    # run error reporting code. 
+    success, value = setup_and_apply(source, nil, !options[:prefix])
+    
+    # If we didn't succeed the parse, raise an exception for the user. 
+    # Stack trace will be off, but the error tree should explain the reason
+    # it failed.
+    unless success
+      # Cheating has not paid off. Now pay the cost: Rerun the parse,
+      # gathering error information in the process.
+      reporter = options[:reporter] || Parslet::ErrorReporter::Tree.new
+      source.pos = 0
+      success, value = setup_and_apply(source, reporter, !options[:prefix])
+      
+      fail "Assertion failed: success was true when parsing with reporter" \
+        if success
+      
+      # Value is a Parslet::Cause, which can be turned into an exception:
+      value.raise
+      
+      fail "NEVER REACHED"
+    end
+    
+    # assert: success is true
+
+    # Extra input is now handled inline with the rest of the parsing. If 
+    # really we have success == true, prefix: false and still some input 
+    # is left dangling, that is a BUG.
+    if !options[:prefix] && source.chars_left > 0
+      fail "BUG: New error strategy should not reach this point."
+    end
+    
+    return flatten(value)
+  end
+  
+  # Creates a context for parsing and applies the current atom to the input. 
+  # Returns the parse result. 
+  #
+  # @return [<Boolean, Object>] Result of the parse. If the first member is 
+  #   true, the parse has succeeded. 
+  def setup_and_apply(source, error_reporter, consume_all)
+    context = Parslet::Atoms::Context.new(error_reporter)
+    apply(source, context, consume_all)
+  end
+
+  # Calls the #try method of this parslet. Success consumes input, error will 
+  # rewind the input. 
+  #
+  # @param source [Parslet::Source] source to read input from
+  # @param context [Parslet::Atoms::Context] context to use for the parsing
+  # @param consume_all [Boolean] true if the current parse must consume
+  #   all input by itself.
+  def apply(source, context, consume_all=false)
+    old_pos = source.pos
+    
+    success, value = result = context.try_with_cache(self, source, consume_all)
+
+    if success
+      # If a consume_all parse was made and doesn't result in the consumption
+      # of all the input, that is considered an error. 
+      if consume_all && source.chars_left>0
+        # Read 10 characters ahead. Why ten? I don't know. 
+        offending_pos   = source.pos
+        offending_input = source.consume(10)
+        
+        # Rewind input (as happens always in error case)
+        source.pos      = old_pos
+        
+        return context.err_at(
+          self, 
+          source, 
+          "Don't know what to do with #{offending_input.to_s.inspect}", 
+          offending_pos
+        ) 
+      end
+      
+      # Looks like the parse was successful after all. Don't rewind the input.
+      return result
+    end
+    
+    # We only reach this point if the parse has failed. Rewind the input.
+    source.pos = old_pos
+    return result
+  end
+  
+  # Override this in your Atoms::Base subclasses to implement parsing
+  # behaviour. 
+  #
+  def try(source, context, consume_all)
+    raise NotImplementedError, \
+      "Atoms::Base doesn't have behaviour, please implement #try(source, context)."
+  end
+
+  # Returns true if this atom can be cached in the packrat cache. Most parslet
+  # atoms are cached, so this always returns true, unless overridden.
+  #
+  def cached?
+    true
+  end
+
+  # Debug printing - in Treetop syntax. 
+  #
+  def self.precedence(prec)
+    define_method(:precedence) { prec }
+  end
+  precedence BASE
+  def to_s(outer_prec=OUTER)
+    if outer_prec < precedence
+      "("+to_s_inner(precedence)+")"
+    else
+      to_s_inner(precedence)
+    end
+  end
+  def inspect
+    to_s(OUTER)
+  end
+private
+
+  # Produces an instance of Success and returns it. 
+  #
+  def succ(result)
+    [true, result]
+  end
+end
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/can_flatten.rb b/app/server/vendor/parslet/lib/parslet/atoms/can_flatten.rb
new file mode 100755
index 0000000..8f5badc
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/can_flatten.rb
@@ -0,0 +1,137 @@
+
+module Parslet::Atoms
+  # A series of helper functions that have the common topic of flattening 
+  # result values into the intermediary tree that consists of Ruby Hashes and 
+  # Arrays. 
+  #
+  # This module has one main function, #flatten, that takes an annotated 
+  # structure as input and returns the reduced form that users expect from 
+  # Atom#parse. 
+  #
+  # NOTE: Since all of these functions are just that, functions without 
+  # side effects, they are in a module and not in a class. Its hard to draw 
+  # the line sometimes, but this is beyond. 
+  #
+  module CanFlatten
+    # Takes a mixed value coming out of a parslet and converts it to a return
+    # value for the user by dropping things and merging hashes. 
+    #
+    # Named is set to true if this result will be embedded in a Hash result from 
+    # naming something using <code>.as(...)</code>. It changes the folding 
+    # semantics of repetition.
+    #
+    def flatten(value, named=false)
+      # Passes through everything that isn't an array of things
+      return value unless value.instance_of? Array
+
+      # Extracts the s-expression tag
+      tag, *tail = value
+
+      # Merges arrays:
+      result = tail.
+        map { |e| flatten(e) }            # first flatten each element
+
+      case tag
+        when :sequence
+          return flatten_sequence(result)
+        when :maybe
+          return named ? result.first : result.first || ''
+        when :repetition
+          return flatten_repetition(result, named)
+      end
+
+      fail "BUG: Unknown tag #{tag.inspect}."
+    end
+
+    # Lisp style fold left where the first element builds the basis for 
+    # an inject. 
+    #
+    def foldl(list, &block)
+      return '' if list.empty?
+      list[1..-1].inject(list.first, &block)
+    end
+
+    # Flatten results from a sequence of parslets. 
+    #
+    # @api private
+    #
+    def flatten_sequence(list)
+      foldl(list.compact) { |r, e|        # and then merge flat elements
+        merge_fold(r, e)
+      }
+    end
+    # @api private 
+    def merge_fold(l, r)
+      # equal pairs: merge. ----------------------------------------------------
+      if l.class == r.class
+        if l.is_a?(Hash)
+          warn_about_duplicate_keys(l, r)
+          return l.merge(r)
+        else
+          return l + r
+        end
+      end
+
+      # unequal pairs: hoist to same level. ------------------------------------
+
+      # Maybe classes are not equal, but both are stringlike?
+      if l.respond_to?(:to_str) && r.respond_to?(:to_str)
+        # if we're merging a String with a Slice, the slice wins. 
+        return r if r.respond_to? :to_slice
+        return l if l.respond_to? :to_slice
+
+        fail "NOTREACHED: What other stringlike classes are there?"
+      end
+
+      # special case: If one of them is a string/slice, the other is more important 
+      return l if r.respond_to? :to_str
+      return r if l.respond_to? :to_str
+
+      # otherwise just create an array for one of them to live in 
+      return l + [r] if r.class == Hash
+      return [l] + r if l.class == Hash
+
+      fail "Unhandled case when foldr'ing sequence."
+    end
+
+    # Flatten results from a repetition of a single parslet. named indicates
+    # whether the user has named the result or not. If the user has named
+    # the results, we want to leave an empty list alone - otherwise it is 
+    # turned into an empty string. 
+    #
+    # @api private
+    #
+    def flatten_repetition(list, named)
+      if list.any? { |e| e.instance_of?(Hash) }
+        # If keyed subtrees are in the array, we'll want to discard all 
+        # strings inbetween. To keep them, name them. 
+        return list.select { |e| e.instance_of?(Hash) }
+      end
+
+      if list.any? { |e| e.instance_of?(Array) }
+        # If any arrays are nested in this array, flatten all arrays to this
+        # level. 
+        return list.
+          select { |e| e.instance_of?(Array) }.
+          flatten(1)
+      end
+
+      # Consistent handling of empty lists, when we act on a named result        
+      return [] if named && list.empty?
+
+      # If there are only strings, concatenate them and return that. 
+      foldl(list) { |s,e| s+e }
+    end
+
+    # That annoying warning 'Duplicate subtrees while merging result' comes 
+    # from here. You should add more '.as(...)' names to your intermediary tree.
+    #
+    def warn_about_duplicate_keys(h1, h2)
+      d = h1.keys & h2.keys
+      unless d.empty?
+        warn "Duplicate subtrees while merging result of \n  #{self.inspect}\nonly the values"+
+             " of the latter will be kept. (keys: #{d.inspect})"
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/capture.rb b/app/server/vendor/parslet/lib/parslet/atoms/capture.rb
new file mode 100755
index 0000000..58acd83
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/capture.rb
@@ -0,0 +1,38 @@
+
+# Stores the result of matching an atom against input in the #captures in 
+# parse context. Doing so will allow you to pull parts of the ongoing parse
+# out later and use them to match other pieces of input. 
+#
+# Example: 
+#   # After this, context.captures[:an_a] returns 'a'
+#   str('a').capture(:an_a)
+#
+#   # Capture and use of the capture: (matches either 'aa' or 'bb')
+#   match['ab'].capture(:first) >> 
+#     dynamic { |src, ctx| str(ctx.captures[:first]) }
+#   
+class Parslet::Atoms::Capture < Parslet::Atoms::Base
+  attr_reader :parslet, :name
+
+  def initialize(parslet, name)
+    super()
+
+    @parslet, @name = parslet, name
+  end
+
+  def apply(source, context, consume_all)
+    success, value = result = parslet.apply(source, context, consume_all)
+
+    if success
+      context.captures[name.to_sym] = 
+        flatten(value)
+    end
+    
+    return result
+  end
+  
+  def to_s_inner(prec)
+    "(#{name.inspect} = #{parslet.to_s(prec)})"
+  end
+end
+
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/context.rb b/app/server/vendor/parslet/lib/parslet/atoms/context.rb
new file mode 100755
index 0000000..231f5e0
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/context.rb
@@ -0,0 +1,91 @@
+module Parslet::Atoms
+  # Helper class that implements a transient cache that maps position and
+  # parslet object to results. This is used for memoization in the packrat
+  # style. 
+  #
+  # Also, error reporter is stored here and error reporting happens through
+  # this class. This makes the reporting pluggable. 
+  #
+  class Context
+    # @param reporter [#err, #err_at] Error reporter (leave empty for default 
+    #   reporter)
+    def initialize(reporter=Parslet::ErrorReporter::Tree.new)
+      @cache = Hash.new { |h, k| h[k] = {} }
+      @reporter = reporter
+      @captures = Parslet::Scope.new
+    end
+    
+    # Caches a parse answer for obj at source.pos. Applying the same parslet
+    # at one position of input always yields the same result, unless the input
+    # has changed. 
+    #
+    # We need the entire source here so we can ask for how many characters 
+    # were consumed by a successful parse. Imitation of such a parse must 
+    # advance the input pos by the same amount of bytes.
+    #
+    def try_with_cache(obj, source, consume_all)
+      beg = source.pos
+        
+      # Not in cache yet? Return early.
+      unless entry = lookup(obj, beg)
+        result = obj.try(source, self, consume_all)
+    
+        if obj.cached?
+          set obj, beg, [result, source.pos-beg]
+        end
+        
+        return result
+      end
+
+      # the condition in unless has returned true, so entry is not nil.
+      result, advance = entry
+
+      # The data we're skipping here has been read before. (since it is in 
+      # the cache) PLUS the actual contents are not interesting anymore since
+      # we know obj matches at beg. So skip reading.
+      source.pos = beg + advance
+      return result
+    end  
+    
+    # Report an error at a given position. 
+    # @see ErrorReporter
+    #
+    def err_at(*args)
+      return [false, @reporter.err_at(*args)] if @reporter
+      return [false, nil]
+    end
+    
+    # Report an error. 
+    # @see ErrorReporter
+    #
+    def err(*args)
+      return [false, @reporter.err(*args)] if @reporter
+      return [false, nil]
+    end
+  
+    # Returns the current captures made on the input (see
+    # Parslet::Atoms::Base#capture). Use as follows: 
+    # 
+    #   context.captures[:foobar] # => returns capture :foobar
+    #
+    attr_reader :captures
+    
+    # Starts a new scope. Use the #scope method of Parslet::Atoms::DSL
+    # to call this. 
+    #
+    def scope
+      captures.push
+      yield
+    ensure
+      captures.pop
+    end
+    
+  private 
+    def lookup(obj, pos)
+      @cache[pos][obj] 
+    end
+    def set(obj, pos, val)
+      @cache[pos][obj] = val
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/dsl.rb b/app/server/vendor/parslet/lib/parslet/atoms/dsl.rb
new file mode 100755
index 0000000..5e403ae
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/dsl.rb
@@ -0,0 +1,109 @@
+
+# A mixin module that defines operations that can be called on any subclass
+# of Parslet::Atoms::Base. These operations make parslets atoms chainable and 
+# allow combination of parslet atoms to form bigger parsers.
+#
+# Example: 
+#
+#   str('foo') >> str('bar')
+#   str('f').repeat
+#   any.absent?               # also called The Epsilon
+#
+module Parslet::Atoms::DSL
+  # Construct a new atom that repeats the current atom min times at least and
+  # at most max times. max can be nil to indicate that no maximum is present. 
+  #
+  # Example: 
+  #   # match any number of 'a's
+  #   str('a').repeat     
+  #
+  #   # match between 1 and 3 'a's
+  #   str('a').repeat(1,3)
+  #
+  def repeat(min=0, max=nil)
+    Parslet::Atoms::Repetition.new(self, min, max)
+  end
+  
+  # Returns a new parslet atom that is only maybe present in the input. This
+  # is synonymous to calling #repeat(0,1). Generated tree value will be 
+  # either nil (if atom is not present in the input) or the matched subtree. 
+  #
+  # Example: 
+  #   str('foo').maybe
+  #
+  def maybe
+    Parslet::Atoms::Repetition.new(self, 0, 1, :maybe)
+  end
+
+  # Chains two parslet atoms together as a sequence. 
+  #
+  # Example: 
+  #   str('a') >> str('b')
+  #
+  def >>(parslet)
+    Parslet::Atoms::Sequence.new(self, parslet)
+  end
+
+  # Chains two parslet atoms together to express alternation. A match will
+  # always be attempted with the parslet on the left side first. If it doesn't
+  # match, the right side will be tried. 
+  #
+  # Example:
+  #   # matches either 'a' OR 'b'
+  #   str('a') | str('b')
+  #
+  def |(parslet)
+    Parslet::Atoms::Alternative.new(self, parslet)
+  end
+  
+  # Tests for absence of a parslet atom in the input stream without consuming
+  # it. 
+  # 
+  # Example: 
+  #   # Only proceed the parse if 'a' is absent.
+  #   str('a').absent?
+  #
+  def absent?
+    Parslet::Atoms::Lookahead.new(self, false)
+  end
+
+  # Tests for presence of a parslet atom in the input stream without consuming
+  # it. 
+  # 
+  # Example: 
+  #   # Only proceed the parse if 'a' is present.
+  #   str('a').present?
+  #
+  def present?
+    Parslet::Atoms::Lookahead.new(self, true)
+  end
+  
+  # Alias for present? that will disappear in 2.0 (deprecated)
+  #
+  alias prsnt? present?
+
+  # Alias for absent? that will disappear in 2.0 (deprecated)
+  #
+  alias absnt? absent?
+
+  # Marks a parslet atom as important for the tree output. This must be used 
+  # to achieve meaningful output from the #parse method. 
+  #
+  # Example:
+  #   str('a').as(:b) # will produce {:b => 'a'}
+  #
+  def as(name)
+    Parslet::Atoms::Named.new(self, name)
+  end
+
+  # Captures a part of the input and stores it under the name given. This 
+  # is very useful to create self-referential parses. A capture stores
+  # the result of its parse (may be complex) on a successful parse action.
+  # 
+  # Example: 
+  #   str('a').capture(:b)  # will store captures[:b] == 'a'
+  # 
+  def capture(name)
+    Parslet::Atoms::Capture.new(self, name)
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/dynamic.rb b/app/server/vendor/parslet/lib/parslet/atoms/dynamic.rb
new file mode 100755
index 0000000..2dc4a84
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/dynamic.rb
@@ -0,0 +1,32 @@
+# Evaluates a block at parse time. The result from the block must be a parser
+# (something which implements #apply). In the first case, the parser will then
+# be applied to the input, creating the result. 
+#
+# Dynamic parses are never cached. 
+#
+# Example: 
+#   dynamic { rand < 0.5 ? str('a') : str('b') }
+#
+class Parslet::Atoms::Dynamic < Parslet::Atoms::Base
+  attr_reader :block
+  
+  def initialize(block)
+    @block = block
+  end
+  
+  def cached?
+    false
+  end
+  
+  def try(source, context, consume_all)
+    result = block.call(source, context)
+    
+    # Result is a parslet atom.
+    return result.apply(source, context, consume_all)
+  end
+  
+  def to_s_inner(prec)
+    "dynamic { ... }"
+  end
+end
+
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/entity.rb b/app/server/vendor/parslet/lib/parslet/atoms/entity.rb
new file mode 100755
index 0000000..4df6050
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/entity.rb
@@ -0,0 +1,41 @@
+# This wraps pieces of parslet definition and gives them a name. The wrapped
+# piece is lazily evaluated and cached. This has two purposes: 
+#     
+# * Avoid infinite recursion during evaluation of the definition
+# * Be able to print things by their name, not by their sometimes
+#   complicated content.
+#
+# You don't normally use this directly, instead you should generated it by
+# using the structuring method Parslet.rule.
+#
+class Parslet::Atoms::Entity < Parslet::Atoms::Base
+  attr_reader :name, :block
+  def initialize(name, &block)
+    super()
+    
+    @name = name
+    @block = block
+  end
+
+  def try(source, context, consume_all)
+    parslet.apply(source, context, consume_all)
+  end
+  
+  def parslet
+    @parslet ||= @block.call.tap { |p| 
+      raise_not_implemented unless p
+    }
+  end
+
+  def to_s_inner(prec)
+    name.to_s.upcase
+  end  
+private 
+  def raise_not_implemented
+    trace = caller.reject {|l| l =~ %r{#{Regexp.escape(__FILE__)}}} # blatantly stolen from dependencies.rb in activesupport
+    exception = NotImplementedError.new("rule(#{name.inspect}) { ... }  returns nil. Still not implemented, but already used?")
+    exception.set_backtrace(trace)
+    
+    raise exception
+  end
+end
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/infix.rb b/app/server/vendor/parslet/lib/parslet/atoms/infix.rb
new file mode 100755
index 0000000..a78345c
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/infix.rb
@@ -0,0 +1,121 @@
+class Parslet::Atoms::Infix < Parslet::Atoms::Base
+  attr_reader :element, :operations
+
+  def initialize(element, operations)
+    super()
+
+    @element = element
+    @operations = operations
+  end
+  
+  def try(source, context, consume_all)
+    return catch_error {
+      return succ(
+        produce_tree(
+          precedence_climb(source, context, consume_all)))
+    }
+  end
+
+  # Turns an array of the form ['1', '+', ['2', '*', '3']] into a hash that
+  # reflects the same structure.
+  #
+  def produce_tree(ary)
+    return ary unless ary.kind_of? Array
+
+    left = ary.shift
+
+    until ary.empty?
+      op, right = ary.shift(2)
+
+      # p [left, op, right]
+
+      if right.kind_of? Array
+        # Subexpression -> Subhash
+        left = {l: left, o: op, r: produce_tree(right)}
+      else
+        left = {l: left, o: op, r: right}
+      end
+    end
+
+    left
+  end
+
+  # A precedence climbing algorithm married to parslet, as described here
+  #   http://eli.thegreenplace.net/2012/08/02/parsing-expressions-by-precedence-climbing/
+  # 
+  # @note Error handling in this routine is done by throwing :error and 
+  #       as a value the error to return to parslet. This avoids cluttering
+  #       the recursion logic here with parslet error handling. 
+  #
+  def precedence_climb(source, context, consume_all, current_prec=1, needs_element=false)
+    result = []
+
+    # To even begin parsing an arithmetic expression, there needs to be 
+    # at least one @element. 
+    success, value = @element.apply(source, context, false)
+    
+    unless success
+      abort context.err(self, source, "#{@element.inspect} was expected", [value])
+    end
+
+    result << flatten(value, true)
+
+    # Loop until we fail on operator matching or until input runs out.
+    loop do
+      op_pos = source.pos
+      op_match, prec, assoc = match_operation(source, context, false)
+
+      # If no operator could be matched here, one of several cases 
+      # applies: 
+      #
+      # - end of file
+      # - end of expression
+      # - syntax error
+      # 
+      # We abort matching the expression here. 
+      break unless op_match
+
+      if prec >= current_prec
+        next_prec = (assoc == :left) ? prec+1 : prec
+
+        result << op_match
+        result << precedence_climb(
+          source, context, consume_all, next_prec, true)
+      else
+        source.pos = op_pos
+        return unwrap(result)
+      end
+    end
+
+    return unwrap(result)
+  end
+
+  def unwrap expr
+    expr.size == 1 ? expr.first : expr
+  end
+
+  def match_operation(source, context, consume_all)
+    errors = []
+    @operations.each do |op_atom, prec, assoc|
+      success, value = op_atom.apply(source, context, consume_all)
+      return flatten(value, true), prec, assoc if success
+
+      # assert: this was in fact an error, accumulate
+      errors << value
+    end
+
+    return nil
+  end
+
+  def abort(error)
+    throw :error, error
+  end
+  def catch_error
+    catch(:error) { yield }
+  end
+
+  def to_s_inner(prec)
+    ops = @operations.map { |o, _, _| o.inspect }.join(', ')
+    "infix_expression(#{@element.inspect}, [#{ops}])"
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/lookahead.rb b/app/server/vendor/parslet/lib/parslet/atoms/lookahead.rb
new file mode 100755
index 0000000..d50a1b9
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/lookahead.rb
@@ -0,0 +1,49 @@
+# Either positive or negative lookahead, doesn't consume its input. 
+#
+# Example: 
+#
+#   str('foo').present? # matches when the input contains 'foo', but leaves it
+#
+class Parslet::Atoms::Lookahead < Parslet::Atoms::Base
+  attr_reader :positive
+  attr_reader :bound_parslet
+  
+  def initialize(bound_parslet, positive=true)
+    super()
+    
+    # Model positive and negative lookahead by testing this flag.
+    @positive = positive
+    @bound_parslet = bound_parslet
+    
+    @error_msgs = {
+      :positive => ["Input should start with ", bound_parslet], 
+      :negative => ["Input should not start with ", bound_parslet]
+    }
+  end
+  
+  def try(source, context, consume_all)
+    pos = source.pos
+
+    success, value = bound_parslet.apply(source, context, consume_all)
+    
+    if positive
+      return succ(nil) if success
+      return context.err_at(self, source, @error_msgs[:positive], pos)
+    else
+      return succ(nil) unless success
+      return context.err_at(self, source, @error_msgs[:negative], pos)
+    end
+    
+  # This is probably the only parslet that rewinds its input in #try.
+  # Lookaheads NEVER consume their input, even on success, that's why. 
+  ensure 
+    source.pos = pos
+  end
+  
+  precedence LOOKAHEAD
+  def to_s_inner(prec)
+    char = positive ? '&' : '!'
+    
+    "#{char}#{bound_parslet.to_s(prec)}"
+  end
+end
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/named.rb b/app/server/vendor/parslet/lib/parslet/atoms/named.rb
new file mode 100755
index 0000000..b5412ba
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/named.rb
@@ -0,0 +1,32 @@
+# Names a match to influence tree construction. 
+#
+# Example: 
+#
+#   str('foo')            # will return 'foo', 
+#   str('foo').as(:foo)   # will return :foo => 'foo'
+#
+class Parslet::Atoms::Named < Parslet::Atoms::Base
+  attr_reader :parslet, :name
+  def initialize(parslet, name)
+    super()
+
+    @parslet, @name = parslet, name
+  end
+  
+  def apply(source, context, consume_all)
+    success, value = result = parslet.apply(source, context, consume_all)
+
+    return result unless success
+    succ(
+      produce_return_value(
+        value))
+  end
+  
+  def to_s_inner(prec)
+    "#{name}:#{parslet.to_s(prec)}"
+  end
+private
+  def produce_return_value(val)
+    { name => flatten(val, true) }
+  end
+end
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/re.rb b/app/server/vendor/parslet/lib/parslet/atoms/re.rb
new file mode 100755
index 0000000..75b0ac1
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/re.rb
@@ -0,0 +1,38 @@
+# Matches a special kind of regular expression that only ever matches one
+# character at a time. Useful members of this family are: <code>character
+# ranges, \\w, \\d, \\r, \\n, ...</code>
+#
+# Example: 
+#
+#   match('[a-z]')  # matches a-z
+#   match('\s')     # like regexps: matches space characters
+#
+class Parslet::Atoms::Re < Parslet::Atoms::Base
+  attr_reader :match, :re
+  def initialize(match)
+    super()
+
+    @match = match.to_s
+    @re    = Regexp.new(self.match, Regexp::MULTILINE)
+    @error_msgs = {
+      :premature  => "Premature end of input", 
+      :failed     => "Failed to match #{match.inspect[1..-2]}"
+    }
+  end
+
+  def try(source, context, consume_all)
+    return succ(source.consume(1)) if source.matches?(@re)
+    
+    # No string could be read
+    return context.err(self, source, @error_msgs[:premature]) \
+      if source.chars_left < 1
+        
+    # No match
+    return context.err(self, source, @error_msgs[:failed])
+  end
+
+  def to_s_inner(prec)
+    match.inspect[1..-2]
+  end
+end
+
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/repetition.rb b/app/server/vendor/parslet/lib/parslet/atoms/repetition.rb
new file mode 100755
index 0000000..dde129f
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/repetition.rb
@@ -0,0 +1,83 @@
+
+# Matches a parslet repeatedly. 
+#
+# Example: 
+#
+#   str('a').repeat(1,3)  # matches 'a' at least once, but at most three times
+#   str('a').maybe        # matches 'a' if it is present in the input (repeat(0,1))
+#
+class Parslet::Atoms::Repetition < Parslet::Atoms::Base  
+  attr_reader :min, :max, :parslet
+  def initialize(parslet, min, max, tag=:repetition)
+    super()
+
+    raise ArgumentError, 
+      "Asking for zero repetitions of a parslet. (#{parslet.inspect} repeating #{min},#{max})" \
+      if max == 0
+
+
+    @parslet = parslet
+    @min, @max = min, max
+    @tag = tag
+    @error_msgs = {
+      :minrep  => "Expected at least #{min} of #{parslet.inspect}", 
+      :unconsumed => "Extra input after last repetition"
+    }
+  end
+  
+  def try(source, context, consume_all)
+    occ = 0
+    accum = [@tag]   # initialize the result array with the tag (for flattening)
+    start_pos = source.pos
+    
+    break_on = nil
+    loop do
+      success, value = parslet.apply(source, context, false)
+
+      break_on = value
+      break unless success
+
+      occ += 1
+      accum << value
+      
+      # If we're not greedy (max is defined), check if that has been reached. 
+      return succ(accum) if max && occ>=max
+    end
+    
+    # Last attempt to match parslet was a failure, failure reason in break_on.
+    
+    # Greedy matcher has produced a failure. Check if occ (which will
+    # contain the number of successes) is >= min.
+    return context.err_at(
+      self, 
+      source, 
+      @error_msgs[:minrep], 
+      start_pos, 
+      [break_on]) if occ < min
+      
+    # consume_all is true, that means that we're inside the part of the parser
+    # that should consume the input completely. Repetition failing here means
+    # probably that we didn't. 
+    #
+    # We have a special clause to create an error here because otherwise
+    # break_on would get thrown away. It turns out, that contains very
+    # interesting information in a lot of cases. 
+    #
+    return context.err(
+      self, 
+      source, 
+      @error_msgs[:unconsumed], 
+      [break_on]) if consume_all && source.chars_left>0
+      
+    return succ(accum)
+  end
+  
+  precedence REPETITION
+  def to_s_inner(prec)
+    minmax = "{#{min}, #{max}}"
+    minmax = '?' if min == 0 && max == 1
+
+    parslet.to_s(prec) + minmax
+  end
+end
+
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/scope.rb b/app/server/vendor/parslet/lib/parslet/atoms/scope.rb
new file mode 100755
index 0000000..0642601
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/scope.rb
@@ -0,0 +1,26 @@
+# Starts a new scope in the parsing process. Please also see the #captures
+# method. 
+#
+class Parslet::Atoms::Scope < Parslet::Atoms::Base
+  attr_reader :block
+  def initialize(block)
+    super()
+
+    @block = block
+  end
+  
+  def cached?
+    false
+  end
+  
+  def apply(source, context, consume_all)
+    context.scope do
+      parslet = block.call
+      return parslet.apply(source, context, consume_all)
+    end
+  end
+  
+  def to_s_inner(prec)
+    "scope { #{block.call.to_s(prec)} }"
+  end
+end
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/sequence.rb b/app/server/vendor/parslet/lib/parslet/atoms/sequence.rb
new file mode 100755
index 0000000..b556cc9
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/sequence.rb
@@ -0,0 +1,45 @@
+# A sequence of parslets, matched from left to right. Denoted by '>>'
+#
+# Example: 
+#
+#   str('a') >> str('b')  # matches 'a', then 'b'
+#
+class Parslet::Atoms::Sequence < Parslet::Atoms::Base
+  attr_reader :parslets
+  def initialize(*parslets)
+    super()
+
+    @parslets = parslets
+    @error_msgs = {
+      :failed  => "Failed to match sequence (#{self.inspect})"
+    }
+  end
+  
+  def >>(parslet)
+    self.class.new(* @parslets+[parslet])
+  end
+  
+  def try(source, context, consume_all)
+    # Presize an array
+    result = Array.new(parslets.size + 1)
+    result[0] = :sequence
+    
+    parslets.each_with_index do |p, idx|
+      child_consume_all = consume_all && (idx == parslets.size-1)
+      success, value = p.apply(source, context, child_consume_all) 
+
+      unless success
+        return context.err(self, source, @error_msgs[:failed], [value]) 
+      end
+      
+      result[idx+1] = value
+    end
+    
+    return succ(result)
+  end
+      
+  precedence SEQUENCE
+  def to_s_inner(prec)
+    parslets.map { |p| p.to_s(prec) }.join(' ')
+  end
+end
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/str.rb b/app/server/vendor/parslet/lib/parslet/atoms/str.rb
new file mode 100755
index 0000000..a55061f
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/str.rb
@@ -0,0 +1,39 @@
+# Matches a string of characters. 
+#
+# Example: 
+# 
+#   str('foo') # matches 'foo'
+#
+class Parslet::Atoms::Str < Parslet::Atoms::Base
+  attr_reader :str
+  def initialize(str)
+    super()
+
+    @str = str.to_s
+    @pat = Regexp.new(Regexp.escape(str))
+    @len = str.size
+    @error_msgs = {
+      :premature  => "Premature end of input", 
+      :failed     => "Expected #{str.inspect}, but got "
+    }
+  end
+  
+  def try(source, context, consume_all)
+    return succ(source.consume(@len)) if source.matches?(@pat)
+    
+    # Input ending early:
+    return context.err(self, source, @error_msgs[:premature]) \
+      if source.chars_left<@len
+    
+    # Expected something, but got something else instead:  
+    error_pos = source.pos  
+    return context.err_at(
+      self, source, 
+      [@error_msgs[:failed], source.consume(@len)], error_pos) 
+  end
+  
+  def to_s_inner(prec)
+    "'#{str}'"
+  end
+end
+
diff --git a/app/server/vendor/parslet/lib/parslet/atoms/visitor.rb b/app/server/vendor/parslet/lib/parslet/atoms/visitor.rb
new file mode 100755
index 0000000..8cb7375
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/atoms/visitor.rb
@@ -0,0 +1,89 @@
+# Augments all parslet atoms with an accept method that will call back 
+# to the visitor given.
+
+# 
+module Parslet::Atoms
+  class Base
+    def accept(visitor)
+      raise NotImplementedError, "No #accept method on #{self.class.name}."
+    end
+  end
+  
+  class Str
+    # Call back visitors #visit_str method. See parslet/export for an example.
+    #
+    def accept(visitor)
+      visitor.visit_str(str)
+    end
+  end
+  
+  class Entity
+    # Call back visitors #visit_entity method. See parslet/export for an
+    # example. 
+    #
+    def accept(visitor)
+      visitor.visit_entity(name, block)
+    end
+  end
+  
+  class Named
+    # Call back visitors #visit_named method. See parslet/export for an
+    # example. 
+    #
+    def accept(visitor)
+      visitor.visit_named(name, parslet)
+    end
+  end
+  
+  class Sequence
+    # Call back visitors #visit_sequence method. See parslet/export for an
+    # example. 
+    #
+    def accept(visitor)
+      visitor.visit_sequence(parslets)
+    end
+  end
+  
+  class Repetition
+    # Call back visitors #visit_repetition method. See parslet/export for an
+    # example. 
+    #
+    def accept(visitor)
+      visitor.visit_repetition(@tag, min, max, parslet)
+    end
+  end
+  
+  class Alternative
+    # Call back visitors #visit_alternative method. See parslet/export for an
+    # example. 
+    #
+    def accept(visitor)
+      visitor.visit_alternative(alternatives)
+    end
+  end
+  
+  class Lookahead
+    # Call back visitors #visit_lookahead method. See parslet/export for an
+    # example. 
+    #
+    def accept(visitor)
+      visitor.visit_lookahead(positive, bound_parslet)
+    end
+  end
+  
+  class Re
+    # Call back visitors #visit_re method. See parslet/export for an example. 
+    #
+    def accept(visitor)
+      visitor.visit_re(match)
+    end
+  end
+end
+
+class Parslet::Parser
+  # Call back visitors #visit_parser method. 
+  #
+  def accept(visitor)
+    visitor.visit_parser(root)
+  end
+end
diff --git a/app/server/vendor/parslet/lib/parslet/cause.rb b/app/server/vendor/parslet/lib/parslet/cause.rb
new file mode 100755
index 0000000..ce5672c
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/cause.rb
@@ -0,0 +1,94 @@
+module Parslet
+  # Represents a cause why a parse did fail. A lot of these objects are
+  # constructed - not all of the causes turn out to be failures for the whole
+  # parse. 
+  #
+  class Cause
+    def initialize(message, source, pos, children)
+      @message, @source, @pos, @children = 
+        message, source, pos, children
+    end
+    
+    # @return [String, Array] A string or an array of message pieces that 
+    #   provide failure information. Use #to_s to get a formatted string.
+    attr_reader :message
+    
+    # @return [Parslet::Source] Source that was parsed when this error 
+    #   happend. Mainly used for line number information.
+    attr_reader :source
+    
+    # Location of the error. 
+    #
+    # @return [Fixnum] Position where the error happened. (character offset)
+    attr_reader :pos 
+    
+    # When this cause is part of a tree of error causes: child nodes for this
+    # node. Very often carries the reasons for this cause. 
+    #
+    # @return [Array<Parslet::Cause>] A list of reasons for this cause. 
+    def children
+      @children ||= []
+    end
+    
+    # Appends 'at line LINE char CHAR' to the string given. Use +pos+ to
+    # override the position of the +source+. This method returns an object
+    # that can be turned into a string using #to_s.
+    #
+    # @param source [Parslet::Source] source that was parsed when this error
+    #   happened 
+    # @param pos [Fixnum] position of error
+    # @param str [String, Array<String>] message parts
+    # @param children [Array<Parslet::Cause>] child nodes for this error tree
+    # @return [Parslet::Cause] a new instance of {Parslet::Cause}
+    #
+    def self.format(source, pos, str, children=[])
+      self.new(str, source, pos, children)
+    end
+    
+    def to_s
+      line, column = source.line_and_column(pos)
+      # Allow message to be a list of objects. Join them here, since we now
+      # really need it. 
+      Array(message).map { |o| 
+        o.respond_to?(:to_slice) ? 
+          o.str.inspect : 
+          o.to_s }.join + " at line #{line} char #{column}."
+    end
+    
+    # Signals to the outside that the parse has failed. Use this in
+    # conjunction with .format for nice error messages. 
+    #
+    def raise(exception_klass=Parslet::ParseFailed)
+      exception = exception_klass.new(self.to_s, self)
+      Kernel.raise exception
+    end
+
+    # Returns an ascii tree representation of the causes of this node and its
+    # children. 
+    #
+    def ascii_tree
+      StringIO.new.tap { |io| 
+        recursive_ascii_tree(self, io, [true]) }.
+        string
+    end
+
+  private
+    def recursive_ascii_tree(node, stream, curved)
+      append_prefix(stream, curved)
+      stream.puts node.to_s
+
+      node.children.each do |child|
+        last_child = (node.children.last == child)
+
+        recursive_ascii_tree(child, stream, curved + [last_child])
+      end
+    end
+    def append_prefix(stream, curved)
+      return if curved.size < 2
+      curved[1..-2].each do |c|
+        stream.print c ? "   " : "|  "
+      end
+      stream.print curved.last ? "`- " : "|- "
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/context.rb b/app/server/vendor/parslet/lib/parslet/context.rb
new file mode 100755
index 0000000..f61e0bc
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/context.rb
@@ -0,0 +1,33 @@
+require 'blankslate'
+
+# Provides a context for tree transformations to run in. The context allows
+# accessing each of the bindings in the bindings hash as local method.
+#
+# Example: 
+#
+#   ctx = Context.new(:a => :b)
+#   ctx.instance_eval do 
+#     a # => :b
+#   end
+#
+# @api private
+class Parslet::Context < BlankSlate
+  reveal :methods
+  reveal :respond_to?
+  reveal :inspect
+  reveal :to_s
+  reveal :instance_variable_set
+  
+  def meta_def(name, &body)
+    metaclass = class <<self; self; end
+
+    metaclass.send(:define_method, name, &body)
+  end
+  
+  def initialize(bindings)
+    bindings.each do |key, value|
+      meta_def(key.to_sym) { value }
+      instance_variable_set("@#{key}", value)
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/convenience.rb b/app/server/vendor/parslet/lib/parslet/convenience.rb
new file mode 100755
index 0000000..3220bc0
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/convenience.rb
@@ -0,0 +1,33 @@
+class Parslet::Atoms::Base
+  
+  # Packages the common idiom
+  #    
+  #    begin
+  #      tree = parser.parse('something')
+  #    rescue Parslet::ParseFailed => error
+  #      puts parser.cause.ascii_tree
+  #    end
+  #
+  # into a convenient method.
+  #
+  # Usage:
+  #   
+  #   require 'parslet'
+  #   require 'parslet/convenience'
+  #   
+  #   class FooParser < Parslet::Parser
+  #     rule(:foo) { str('foo') }
+  #     root(:foo)
+  #   end
+  #   
+  #   FooParser.new.parse_with_debug('bar')
+  #
+  # @see Parslet::Atoms::Base#parse
+  #
+  def parse_with_debug str, opts={}
+    parse str, opts
+  rescue Parslet::ParseFailed => error
+    puts error.cause.ascii_tree
+  end
+
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/error_reporter.rb b/app/server/vendor/parslet/lib/parslet/error_reporter.rb
new file mode 100755
index 0000000..567c63a
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/error_reporter.rb
@@ -0,0 +1,7 @@
+# A namespace for all error reporters.
+#
+module Parslet::ErrorReporter
+end
+
+require 'parslet/error_reporter/tree'
+require 'parslet/error_reporter/deepest'
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/error_reporter/deepest.rb b/app/server/vendor/parslet/lib/parslet/error_reporter/deepest.rb
new file mode 100755
index 0000000..102b4f8
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/error_reporter/deepest.rb
@@ -0,0 +1,95 @@
+module Parslet
+  module ErrorReporter
+    # Instead of reporting the latest error that happens like {Tree} does,
+    # this class reports the deepest error. Depth is defined here as how
+    # advanced into the input an error happens. The errors close to the
+    # greatest depth tend to be more relevant to the end user, since they
+    # specify what could be done to make them go away. 
+    #
+    # More specifically, errors produced by this reporter won't be related to
+    # the structure of the grammar at all. The positions of the errors will 
+    # be advanced and convey at every grammar level what the deepest rule
+    # was to fail. 
+    #
+    class Deepest
+      def initialize
+        @deepest_cause = nil
+      end
+      
+      # Produces an error cause that combines the message at the current level
+      # with the errors that happened at a level below (children).
+      #
+      # @param atom [Parslet::Atoms::Base] parslet that failed
+      # @param source [Source] Source that we're using for this parse. (line 
+      #   number information...)
+      # @param message [String, Array] Error message at this level.
+      # @param children [Array] A list of errors from a deeper level (or nil).
+      # @return [Cause] An error tree combining children with message.
+      #
+      def err(atom, source, message, children=nil)
+        position = source.pos
+        cause = Cause.format(source, position, message, children)
+        return deepest(cause)
+      end
+
+      # Produces an error cause that combines the message at the current level
+      # with the errors that happened at a level below (children).
+      #
+      # @param atom [Parslet::Atoms::Base] parslet that failed
+      # @param source [Source] Source that we're using for this parse. (line 
+      #   number information...)
+      # @param message [String, Array] Error message at this level.
+      # @param pos [Fixnum] The real position of the error.
+      # @param children [Array] A list of errors from a deeper level (or nil).
+      # @return [Cause] An error tree combining children with message.
+      #
+      def err_at(atom, source, message, pos, children=nil)
+        position = pos
+        cause = Cause.format(source, position, message, children)
+        return deepest(cause)
+      end
+      
+      # Returns the cause that is currently deepest. Mainly for specs. 
+      #
+      attr_reader :deepest_cause
+      
+      # Checks to see if the lineage of the cause given includes a cause with
+      # an error position deeper than the current deepest cause stored. If
+      # yes, it passes the cause through to the caller. If no, it returns the
+      # current deepest error that was saved as a reference.
+      #
+      def deepest(cause)
+        rank, leaf = deepest_child(cause)
+        
+        if !deepest_cause || leaf.pos >= deepest_cause.pos
+          # This error reaches deeper into the input, save it as reference.
+          @deepest_cause = leaf
+          return cause
+        end
+        
+        return deepest_cause
+      end
+      
+    private
+      # Returns the leaf from a given error tree with the biggest rank. 
+      #
+      def deepest_child(cause, rank=0)
+        max_child = cause
+        max_rank  = rank
+        
+        if cause.children && !cause.children.empty?
+          cause.children.each do |child|
+            c_rank, c_cause = deepest_child(child, rank+1)
+            
+            if c_rank > max_rank
+              max_rank = c_rank
+              max_child = c_cause
+            end
+          end
+        end
+        
+        return max_rank, max_child
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/error_reporter/tree.rb b/app/server/vendor/parslet/lib/parslet/error_reporter/tree.rb
new file mode 100755
index 0000000..2fb2750
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/error_reporter/tree.rb
@@ -0,0 +1,57 @@
+module Parslet
+  module ErrorReporter
+    # An error reporter has two central methods, one for reporting errors at
+    # the current parse position (#err) and one for reporting errors at a
+    # given parse position (#err_at). The reporter can return an object (a
+    # 'cause') that will be returned to the caller along with the information
+    # that the parse failed. 
+    # 
+    # When reporting errors on the outer levels of your parser, these methods
+    # get passed a list of error objects ('causes') from the inner levels. In
+    # this default implementation, the inner levels are considered error
+    # subtrees and are appended to the generated tree node at each level,
+    # thereby constructing an error tree. 
+    #
+    # This error tree will report in parallel with the grammar structure that
+    # failed. A one-to-one correspondence exists between each error in the 
+    # tree and the parslet atom that produced that error. 
+    #
+    # The implementor is really free to use these return values as he sees
+    # fit. One example would be to return an error state object from these
+    # methods that is then updated as errors cascade up the parse derivation
+    # tree. 
+    #
+    class Tree
+      # Produces an error cause that combines the message at the current level
+      # with the errors that happened at a level below (children).
+      #
+      # @param atom [Parslet::Atoms::Base] parslet that failed
+      # @param source [Source] Source that we're using for this parse. (line 
+      #   number information...)
+      # @param message [String, Array] Error message at this level.
+      # @param children [Array] A list of errors from a deeper level (or nil).
+      # @return [Cause] An error tree combining children with message.
+      #
+      def err(atom, source, message, children=nil)
+        position = source.pos
+        Cause.format(source, position, message, children)
+      end
+
+      # Produces an error cause that combines the message at the current level
+      # with the errors that happened at a level below (children).
+      #
+      # @param atom [Parslet::Atoms::Base] parslet that failed
+      # @param source [Source] Source that we're using for this parse. (line 
+      #   number information...)
+      # @param message [String, Array] Error message at this level.
+      # @param pos [Fixnum] The real position of the error.
+      # @param children [Array] A list of errors from a deeper level (or nil).
+      # @return [Cause] An error tree combining children with message.
+      #
+      def err_at(atom, source, message, pos, children=nil)
+        position = pos
+        Cause.format(source, position, message, children)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/export.rb b/app/server/vendor/parslet/lib/parslet/export.rb
new file mode 100755
index 0000000..37ab20d
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/export.rb
@@ -0,0 +1,162 @@
+# Allows exporting parslet grammars to other lingos. 
+
+require 'set'
+require 'parslet/atoms/visitor'
+
+class Parslet::Parser
+  module Visitors
+    class Citrus
+      attr_reader :context, :output
+      def initialize(context)
+        @context = context
+      end
+      
+      def visit_str(str)
+        "\"#{str.inspect[1..-2]}\""
+      end
+      def visit_re(match)
+        match.to_s
+      end
+
+      def visit_entity(name, block)
+        context.deferred(name, block)
+
+        "(#{context.mangle_name(name)})"
+      end
+      def visit_named(name, parslet)
+        parslet.accept(self)
+      end
+
+      def visit_sequence(parslets)
+        '(' <<
+        parslets.
+          map { |el| el.accept(self) }.
+          join(' ') <<
+        ')'
+      end
+      def visit_repetition(tag, min, max, parslet)
+        parslet.accept(self) << "#{min}*#{max}"
+      end
+      def visit_alternative(alternatives)
+        '(' <<
+        alternatives.
+          map { |el| el.accept(self) }.
+          join(' | ') <<
+        ')'
+      end
+
+      def visit_lookahead(positive, bound_parslet)
+        (positive ? '&' : '!') <<
+        bound_parslet.accept(self)
+      end
+    end
+
+    class Treetop < Citrus
+      def visit_repetition(tag, min, max, parslet)
+        parslet.accept(self) << "#{min}..#{max}"
+      end
+
+      def visit_alternative(alternatives)
+        '(' <<
+        alternatives.
+          map { |el| el.accept(self) }.
+          join(' / ') <<
+        ')'
+      end
+    end
+  end
+
+  # A helper class that formats Citrus and Treetop grammars as a string. 
+  #
+  class PrettyPrinter
+    attr_reader :visitor
+    def initialize(visitor_klass)
+      @visitor = visitor_klass.new(self)
+    end
+
+    # Pretty prints the given parslet using the visitor that has been
+    # configured in initialize. Returns the string representation of the
+    # Citrus or Treetop grammar.
+    #
+    def pretty_print(name, parslet)
+      output = "grammar #{name}\n"
+      
+      output << rule('root', parslet)
+      
+      seen = Set.new
+      loop do
+        # @todo is constantly filled by the visitor (see #deferred). We 
+        # keep going until it is empty.
+        break if @todo.empty?
+        name, block = @todo.shift
+
+        # Track what rules we've already seen. This breaks loops.
+        next if seen.include?(name)
+        seen << name
+
+        output << rule(name, block.call)
+      end
+      
+      output << "end\n"
+    end
+    
+    # Formats a rule in either dialect. 
+    #
+    def rule(name, parslet)
+      "  rule #{mangle_name name}\n" << 
+      "    " << parslet.accept(visitor) << "\n" <<
+      "  end\n"
+    end
+    
+    # Whenever the visitor encounters an rule in a parslet, it defers the
+    # pretty printing of the rule by calling this method. 
+    #
+    def deferred(name, content)
+      @todo ||= []
+      @todo << [name, content]
+    end
+
+    # Mangles names so that Citrus and Treetop can live with it. This mostly
+    # transforms some of the things that Ruby allows into other patterns. If
+    # there is collision, we will not detect it for now. 
+    #
+    def mangle_name(str)
+      str.to_s.sub(/\?$/, '_p')
+    end
+  end
+
+  # Exports the current parser instance as a string in the Citrus dialect. 
+  #
+  # Example: 
+  #
+  #   require 'parslet/export'
+  #   class MyParser < Parslet::Parser
+  #     root(:expression)
+  #     rule(:expression) { str('foo') }
+  #   end
+  #   
+  #   MyParser.new.to_citrus # => a citrus grammar as a string
+  #
+  def to_citrus
+    PrettyPrinter.new(Visitors::Citrus).
+      pretty_print(self.class.name, root)
+  end
+
+  # Exports the current parser instance as a string in the Treetop dialect. 
+  #
+  # Example: 
+  #
+  #   require 'parslet/export'
+  #   class MyParser < Parslet::Parser
+  #     root(:expression)
+  #     rule(:expression) { str('foo') }
+  #   end
+  #   
+  #   MyParser.new.to_treetop # => a treetop grammar as a string
+  #
+  def to_treetop
+    PrettyPrinter.new(Visitors::Treetop).
+      pretty_print(self.class.name, root)
+  end
+end
+
diff --git a/app/server/vendor/parslet/lib/parslet/expression.rb b/app/server/vendor/parslet/lib/parslet/expression.rb
new file mode 100755
index 0000000..1cd13e4
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/expression.rb
@@ -0,0 +1,51 @@
+
+# Allows specifying rules as strings using the exact same grammar that treetop
+# does, minus the actions. This is on one hand a good example of a fully
+# fledged parser and on the other hand might even turn out really useful. 
+#
+# This can be viewed as an extension to parslet and might even be hosted in
+# its own gem one fine day. 
+# 
+class Parslet::Expression
+  include Parslet
+  
+  autoload :Treetop, 'parslet/expression/treetop'
+  
+  # Creates a parslet from a foreign language expression. 
+  #
+  # Example: 
+  #   
+  #   Parslet::Expression.new("'a' 'b'")
+  #
+  def initialize(str, opts={}, context=self)
+    @type = opts[:type] || :treetop
+    @exp = str
+    @parslet = transform(
+      parse(str))
+  end
+  
+  # Transforms the parse tree into a parslet expression. 
+  #
+  def transform(tree)
+    transform = Treetop::Transform.new
+    
+    # pp tree
+    transform.apply(tree)
+  rescue 
+    warn "Could not transform: " + tree.inspect
+    raise
+  end
+  
+  # Parses the string and returns a parse tree.
+  #
+  def parse(str)
+    parser = Treetop::Parser.new
+    parser.parse(str)
+  end
+
+  # Turns this expression into a parslet.
+  #
+  def to_parslet
+    @parslet
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/expression/treetop.rb b/app/server/vendor/parslet/lib/parslet/expression/treetop.rb
new file mode 100755
index 0000000..35da40b
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/expression/treetop.rb
@@ -0,0 +1,92 @@
+class Parslet::Expression::Treetop
+  class Parser < Parslet::Parser
+    root(:expression)
+    
+    rule(:expression) { alternatives }
+    
+    # alternative 'a' / 'b'
+    rule(:alternatives) {
+      (simple >> (spaced('/') >> simple).repeat).as(:alt)
+    }
+    
+    # sequence by simple concatenation 'a' 'b'
+    rule(:simple) { occurrence.repeat(1).as(:seq) }
+    
+    # occurrence modifiers
+    rule(:occurrence) {
+      atom.as(:repetition) >> spaced('*').as(:sign) |
+      atom.as(:repetition) >> spaced('+').as(:sign) |
+      atom.as(:repetition) >> repetition_spec |
+      
+      atom.as(:maybe) >> spaced('?') | 
+      atom
+    }
+        
+    rule(:atom) { 
+      spaced('(') >> expression.as(:unwrap) >> spaced(')') |
+      dot |
+      string |
+      char_class
+    }
+    
+    # a character class
+    rule(:char_class) {
+      (str('[') >>
+        (str('\\') >> any |
+        str(']').absent? >> any).repeat(1) >>
+      str(']')).as(:match) >> space?
+    }
+    
+    # anything at all
+    rule(:dot) { spaced('.').as(:any) }
+    
+    # recognizing strings
+    rule(:string) {
+      str('\'') >> 
+      (
+        (str('\\') >> any) |
+        (str("'").absent? >> any)
+      ).repeat.as(:string) >> 
+      str('\'') >> space?
+    }
+    
+    # repetition specification like {1, 2}
+    rule(:repetition_spec) {
+      spaced('{') >> 
+        integer.maybe.as(:min) >> spaced(',') >> 
+        integer.maybe.as(:max) >> spaced('}')
+    }
+    rule(:integer) {
+      match['0-9'].repeat(1)
+    }
+    
+    # whitespace handling
+    rule(:space) { match("\s").repeat(1) }
+    rule(:space?) { space.maybe }
+    
+    def spaced(str)
+      str(str) >> space?
+    end
+  end
+  
+  class Transform < Parslet::Transform
+    
+    rule(:repetition => simple(:rep), :sign => simple(:sign)) { 
+      min = sign=='+' ? 1 : 0
+      Parslet::Atoms::Repetition.new(rep, min, nil) }
+    rule(:repetition => simple(:rep), :min => simple(:min), :max => simple(:max)) { 
+      Parslet::Atoms::Repetition.new(rep, 
+        Integer(min || 0), 
+        max && Integer(max) || nil) }
+      
+    rule(:alt => subtree(:alt))       { Parslet::Atoms::Alternative.new(*alt) }
+    rule(:seq => sequence(:s))        { Parslet::Atoms::Sequence.new(*s) }
+    rule(:unwrap => simple(:u))       { u }
+    rule(:maybe => simple(:m))        { |d| d[:m].maybe }
+    rule(:string => simple(:s))       { Parslet::Atoms::Str.new(s) }
+    rule(:match => simple(:m))        { Parslet::Atoms::Re.new(m) }
+    rule(:any => simple(:a))          { Parslet::Atoms::Re.new('.') }
+  end
+  
+end
+
diff --git a/app/server/vendor/parslet/lib/parslet/graphviz.rb b/app/server/vendor/parslet/lib/parslet/graphviz.rb
new file mode 100755
index 0000000..6d6cd75
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/graphviz.rb
@@ -0,0 +1,97 @@
+
+# Paints a graphviz graph of your parser.
+
+begin
+  require 'ruby-graphviz'
+rescue LoadError
+  puts "Please install the 'ruby-graphviz' gem first."
+  fail
+end
+
+require 'set'
+require 'parslet/atoms/visitor'
+
+module Parslet
+  class GraphvizVisitor
+    def initialize g
+      @graph = g
+      @known_links = Set.new
+      @visited = Set.new
+    end
+
+    attr_reader :parent
+
+    def visit_parser(root)
+      recurse root, node('parser')
+    end
+    def visit_entity(name, block)
+      s = node(name)
+
+      downwards s
+
+      return if @visited.include?(name)
+      @visited << name
+
+      recurse block.call, s
+    end
+    def visit_named(name, atom)
+      recurse atom, parent
+    end
+    def visit_repetition(tag, min, max, atom)
+      recurse atom, parent
+    end
+    def visit_alternative(alternatives)
+      p = parent
+      alternatives.each do |atom|
+        recurse atom, p
+      end
+    end
+    def visit_sequence(sequence)
+      p = parent
+      sequence.each do |atom|
+        recurse atom, p
+      end
+    end
+    def visit_lookahead(positive, atom)
+      recurse atom, parent
+    end
+    def visit_re(regexp)
+      # downwards node(regexp.object_id, label: escape("re(#{regexp.inspect})"))
+    end
+    def visit_str(str)
+      # downwards node(str.object_id, label: escape("#{str.inspect}"))
+    end
+
+    def escape str
+      str.gsub('"', "'")
+    end
+    def node name, opts={}
+      @graph.add_nodes name.to_s, opts
+    end
+    def downwards child
+      if @parent && !@known_links.include?([@parent, child])
+        @graph.add_edges(@parent, child)
+        @known_links << [@parent, child]
+      end
+    end
+    def recurse node, current
+      @parent = current
+      node.accept(self)
+    end
+  end
+
+  module Graphable
+    def graph opts
+      g = GraphViz.new(:G, type: :digraph)
+      visitor = GraphvizVisitor.new(g)
+
+      new.accept(visitor)
+
+      g.output opts
+    end
+  end
+
+  class Parser # reopen for introducing the .graph method
+    extend Graphable
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/parser.rb b/app/server/vendor/parslet/lib/parslet/parser.rb
new file mode 100755
index 0000000..a78e443
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/parser.rb
@@ -0,0 +1,67 @@
+
+# The base class for all your parsers. Use as follows: 
+#
+#   require 'parslet'
+#        
+#   class MyParser < Parslet::Parser
+#     rule(:a) { str('a').repeat }
+#     root(:a)        
+#   end
+#        
+#   pp MyParser.new.parse('aaaa')   # => 'aaaa'
+#   pp MyParser.new.parse('bbbb')   # => Parslet::Atoms::ParseFailed: 
+#                                   #    Don't know what to do with bbbb at line 1 char 1.
+#
+# Parslet::Parser is also a grammar atom. This means that you can mix full 
+# fledged parsers freely with small parts of a different parser. 
+#
+# Example: 
+#   class ParserA < Parslet::Parser
+#     root :aaa
+#     rule(:aaa) { str('a').repeat(3,3) }
+#   end
+#   class ParserB < Parslet::Parser
+#     root :expression
+#     rule(:expression) { str('b') >> ParserA.new >> str('b') }
+#   end
+#
+# In the above example, ParserB would parse something like 'baaab'. 
+#
+class Parslet::Parser < Parslet::Atoms::Base
+  include Parslet
+
+  class <<self # class methods
+    # Define the parsers #root function. This is the place where you start 
+    # parsing; if you have a rule for 'file' that describes what should be 
+    # in a file, this would be your root declaration: 
+    #
+    #   class Parser
+    #     root :file
+    #     rule(:file) { ... }
+    #   end
+    #
+    # #root declares a 'parse' function that works just like the parse 
+    # function that you can call on a simple parslet, taking a string as input
+    # and producing parse output. 
+    #
+    # In a way, #root is a shorthand for: 
+    #
+    #   def parse(str)
+    #     your_parser_root.parse(str)
+    #   end
+    #
+    def root(name)
+      define_method(:root) do
+        self.send(name)
+      end
+    end
+  end
+  
+  def try(source, context, consume_all)
+    root.try(source, context, consume_all)
+  end
+  
+  def to_s_inner(prec)
+    root.to_s(prec)
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/pattern.rb b/app/server/vendor/parslet/lib/parslet/pattern.rb
new file mode 100755
index 0000000..6efc5d0
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/pattern.rb
@@ -0,0 +1,114 @@
+# Matches trees against expressions. Trees are formed by arrays and hashes
+# for expressing membership and sequence. The leafs of the tree are other
+# classes. 
+#
+# A tree issued by the parslet library might look like this: 
+#
+#   { 
+#     :function_call => {
+#       :name => 'foobar', 
+#       :args => [1, 2, 3]
+#     }
+#   }
+#
+# A pattern that would match against this tree would be: 
+#
+#   { :function_call => { :name => simple(:name), :args => sequence(:args) }}
+#
+# Note that Parslet::Pattern only matches at a given subtree; it wont try 
+# to match recursively. To do that, please use Parslet::Transform. 
+#
+class Parslet::Pattern  
+  def initialize(pattern)
+    @pattern = pattern
+  end
+
+  # Decides if the given subtree matches this pattern. Returns the bindings
+  # made on a successful match or nil if the match fails. If you specify 
+  # bindings to be a hash, the mappings in it will be treated like bindings
+  # made during an attempted match. 
+  #
+  #   Pattern.new('a').match('a', :foo => 'bar') # => { :foo => 'bar' }
+  #
+  # @param subtree [String, Hash, Array] poro subtree returned by a parse
+  # @param bindings [Hash] variable bindings to be verified
+  # @return [Hash, nil] On success: variable bindings that allow a match. On 
+  #   failure: nil
+  #
+  def match(subtree, bindings=nil)
+    bindings = bindings && bindings.dup || Hash.new
+    return bindings if element_match(subtree, @pattern, bindings)
+  end
+  
+  # Returns true if the tree element given by +tree+ matches the expression
+  # given by +exp+. This match must respect bindings already made in
+  # +bindings+. Note that bindings is carried along and modified. 
+  #
+  # @api private
+  #
+  def element_match(tree, exp, bindings) 
+    # p [:elm, tree, exp]
+    case [tree, exp].map { |e| e.class }
+      when [Hash,Hash]
+        return element_match_hash(tree, exp, bindings)
+      when [Array,Array]
+        return element_match_ary_single(tree, exp, bindings)
+    else
+      # If elements match exactly, then that is good enough in all cases
+      return true if exp === tree
+      
+      # If exp is a bind variable: Check if the binding matches
+      if exp.respond_to?(:can_bind?) && exp.can_bind?(tree)
+        return element_match_binding(tree, exp, bindings)
+      end
+                  
+      # Otherwise: No match (we don't know anything about the element
+      # combination)
+      return false
+    end
+  end
+  
+  # @api private
+  #
+  def element_match_binding(tree, exp, bindings)
+    var_name = exp.variable_name
+
+    # TODO test for the hidden :_ feature.
+    if var_name && bound_value = bindings[var_name]
+      return bound_value == tree
+    end
+    
+    # New binding: 
+    bindings.store var_name, tree
+    
+    return true
+  end
+  
+  # @api private
+  #
+  def element_match_ary_single(sequence, exp, bindings)
+    return false if sequence.size != exp.size
+    
+    return sequence.zip(exp).all? { |elt, subexp|
+      element_match(elt, subexp, bindings) }
+  end
+  
+  # @api private
+  #
+  def element_match_hash(tree, exp, bindings)
+    # Early failure when one hash is bigger than the other
+    return false unless exp.size == tree.size
+    
+    # We iterate over expected pattern, since we demand that the keys that
+    # are there should be in tree as well.
+    exp.each do |expected_key, expected_value|
+      return false unless tree.has_key? expected_key
+      
+      # Recurse into the value and stop early on failure
+      value = tree[expected_key]
+      return false unless element_match(value, expected_value, bindings)
+    end
+    
+    return true
+  end  
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/pattern/binding.rb b/app/server/vendor/parslet/lib/parslet/pattern/binding.rb
new file mode 100755
index 0000000..2197db7
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/pattern/binding.rb
@@ -0,0 +1,49 @@
+
+# Used internally for representing a bind placeholder in a Parslet::Transform
+# pattern. This is the superclass for all bindings. 
+#
+# It defines the most permissive kind of bind, the one that matches any subtree
+# whatever it looks like. 
+#
+class Parslet::Pattern::SubtreeBind < Struct.new(:symbol)
+  def variable_name
+    symbol
+  end
+  
+  def inspect
+    "#{bind_type_name}(#{symbol.inspect})"
+  end
+  
+  def can_bind?(subtree)
+    true
+  end
+
+private 
+  def bind_type_name 
+    if md=self.class.name.match(/(\w+)Bind/)
+      md.captures.first.downcase
+    else
+      # This path should never be used, but since this is for inspection only, 
+      # let's not raise.
+      'unknown_bind'
+    end
+  end
+end
+
+# Binds a symbol to a simple subtree, one that is not either a sequence of
+# elements or a collection of attributes. 
+#
+class Parslet::Pattern::SimpleBind < Parslet::Pattern::SubtreeBind
+  def can_bind?(subtree)
+    not [Hash, Array].include?(subtree.class)
+  end
+end
+
+# Binds a symbol to a sequence of simple leafs ([element1, element2, ...])
+#
+class Parslet::Pattern::SequenceBind < Parslet::Pattern::SubtreeBind
+  def can_bind?(subtree)
+    subtree.kind_of?(Array) &&
+      (not subtree.any? { |el| [Hash, Array].include?(el.class) })
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/rig/rspec.rb b/app/server/vendor/parslet/lib/parslet/rig/rspec.rb
new file mode 100755
index 0000000..0ce2175
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/rig/rspec.rb
@@ -0,0 +1,51 @@
+RSpec::Matchers.define(:parse) do |input, opts|
+  as = block = nil
+  result = trace = nil
+  match do |parser|
+    begin
+      result = parser.parse(input)
+      block ? 
+        block.call(result) : 
+        (as == result || as.nil?)
+    rescue Parslet::ParseFailed => ex
+      trace = ex.cause.ascii_tree if opts && opts[:trace]
+      false
+    end
+  end
+
+  failure_message_for_should do |is|
+    if block
+      "expected output of parsing #{input.inspect}" <<
+      " with #{is.inspect} to meet block conditions, but it didn't"
+    else
+      "expected " << 
+        (as ? 
+          "output of parsing #{input.inspect}"<<
+          " with #{is.inspect} to equal #{as.inspect}, but was #{result.inspect}" : 
+          "#{is.inspect} to be able to parse #{input.inspect}") << 
+        (trace ? 
+          "\n"+trace : 
+          '')
+    end
+  end
+
+  failure_message_for_should_not do |is|
+    if block
+      "expected output of parsing #{input.inspect} with #{is.inspect} not to meet block conditions, but it did"
+    else
+      "expected " << 
+        (as ? 
+          "output of parsing #{input.inspect}"<<
+          " with #{is.inspect} not to equal #{as.inspect}" :
+          
+          "#{is.inspect} to not parse #{input.inspect}, but it did")
+    end
+  end
+
+  # NOTE: This has a nodoc tag since the rdoc parser puts this into 
+  # Object, a thing I would never allow. 
+  chain :as do |expected_output, &block|
+    as = expected_output
+    block = block
+  end
+end
diff --git a/app/server/vendor/parslet/lib/parslet/scope.rb b/app/server/vendor/parslet/lib/parslet/scope.rb
new file mode 100755
index 0000000..3c41e22
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/scope.rb
@@ -0,0 +1,42 @@
+class Parslet::Scope
+  # Raised when the accessed slot has never been assigned a value. 
+  #
+  class NotFound < StandardError
+  end
+  
+  class Binding
+    attr_reader :parent
+    
+    def initialize(parent=nil)
+      @parent = parent
+      @hash = Hash.new
+    end
+    
+    def [](k)
+      @hash.has_key?(k) && @hash[k] ||
+        parent && parent[k] or 
+        raise NotFound
+    end
+    def []=(k,v)
+      @hash.store(k,v)
+    end
+  end
+  
+  def [](k)
+    @current[k]
+  end
+  def []=(k,v)
+    @current[k] = v
+  end
+  
+  def initialize
+    @current = Binding.new
+  end
+  
+  def push
+    @current = Binding.new(@current)
+  end
+  def pop
+    @current = @current.parent
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/slice.rb b/app/server/vendor/parslet/lib/parslet/slice.rb
new file mode 100755
index 0000000..3e2dd46
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/slice.rb
@@ -0,0 +1,101 @@
+
+# A slice is a small part from the parse input. A slice mainly behaves like
+# any other string, except that it remembers where it came from (offset in
+# original input).
+#
+# == Extracting line and column
+#
+# Using the #line_and_column method, you can extract the line and column in
+# the original input where this slice starts.
+#
+# Example:
+#   slice.line_and_column # => [1, 13]
+#   slice.offset          # => 12
+#
+# == Likeness to strings
+#
+# Parslet::Slice behaves in many ways like a Ruby String. This likeness
+# however is not complete - many of the myriad of operations String supports
+# are not yet in Slice. You can always extract the internal string instance by
+# calling #to_s.
+#
+# These omissions are somewhat intentional. Rather than maintaining a full
+# delegation, we opt for a partial emulation that gets the job done.
+#
+class Parslet::Slice
+  attr_reader :str, :offset
+  attr_reader :line_cache
+
+  # Construct a slice using a string, an offset and an optional line cache. 
+  # The line cache should be able to answer to the #line_and_column message. 
+  #
+  def initialize(string, offset, line_cache=nil)
+    @str, @offset = string, offset
+    @line_cache = line_cache
+  end
+
+  # Compares slices to other slices or strings.
+  #
+  def == other
+    str == other
+  end
+
+  # Match regular expressions.
+  #
+  def match(regexp)
+    str.match(regexp)
+  end
+
+  # Returns the slices size in characters.
+  #
+  def size
+    str.size
+  end
+  
+  # Concatenate two slices; it is assumed that the second slice begins 
+  # where the first one ends. The offset of the resulting slice is the same
+  # as the one of this slice. 
+  #
+  def +(other)
+    self.class.new(str + other.to_s, offset, line_cache)
+  end
+
+  # Returns a <line, column> tuple referring to the original input.
+  #
+  def line_and_column
+    raise ArgumentError, "No line cache was given, cannot infer line and column." \
+      unless line_cache
+
+    line_cache.line_and_column(self.offset)
+  end
+
+
+  # Conversion operators -----------------------------------------------------
+  def to_str
+    str
+  end
+  alias to_s to_str
+
+  def to_slice
+    self
+  end
+  def to_sym
+    str.to_sym
+  end
+  def to_int
+    Integer(str)
+  end
+  def to_i
+    str.to_i
+  end
+  def to_f
+    str.to_f
+  end
+
+  # Inspection & Debugging ---------------------------------------------------
+
+  # Prints the slice as <code>"string"@offset</code>.
+  def inspect
+    str.inspect << "@#{offset}"
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/lib/parslet/source.rb b/app/server/vendor/parslet/lib/parslet/source.rb
new file mode 100755
index 0000000..a1b71e1
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/source.rb
@@ -0,0 +1,87 @@
+
+require 'stringio'
+require 'strscan'
+
+require 'parslet/source/line_cache'
+
+module Parslet
+  # Wraps the input string for parslet. 
+  #
+  class Source
+    def initialize(str)
+      raise(
+        ArgumentError, 
+        "Must construct Source with a string like object."
+      ) unless str.respond_to?(:to_str)
+
+      @str = StringScanner.new(str)
+
+      # maps 1 => /./m, 2 => /../m, etc...
+      @re_cache = Hash.new { |h,k| 
+        h[k] = /(.|$){#{k}}/m }
+
+      @line_cache = LineCache.new
+      @line_cache.scan_for_line_endings(0, str)
+    end
+  
+    # Checks if the given pattern matches at the current input position. 
+    #
+    # @param pattern [Regexp] pattern to check for
+    # @return [Boolean] true if the pattern matches at #pos
+    #
+    def matches?(pattern)
+      @str.match?(pattern)
+    end
+    alias match matches?
+    
+    # Consumes n characters from the input, returning them as a slice of the
+    # input. 
+    #
+    def consume(n)
+      original_pos = @str.pos
+      slice_str = @str.scan(@re_cache[n])
+      slice = Parslet::Slice.new(
+        slice_str,
+        original_pos,
+        @line_cache)
+
+      return slice
+    end
+    
+    # Returns how many chars remain in the input. 
+    #
+    def chars_left
+      @str.rest_size
+    end
+
+    # Returns how many chars there are between current position and the 
+    # string given. If the string given doesn't occur in the source, then 
+    # the remaining chars (#chars_left) are returned. 
+    #
+    # @return [Fixnum] count of chars until str or #chars_left
+    #
+    def chars_until str
+      slice_str = @str.check_until(Regexp.new(Regexp.escape(str)))
+      return chars_left unless slice_str
+      return slice_str.size - str.size
+    end
+    
+    # Position of the parse as a character offset into the original string. 
+    # @note: Encodings...
+    def pos
+      @str.pos
+    end
+    def pos=(n)
+      @str.pos = n
+    rescue RangeError
+    end
+
+    # Returns a <line, column> tuple for the given position. If no position is
+    # given, line/column information is returned for the current position
+    # given by #pos. 
+    #
+    def line_and_column(position=nil)
+      @line_cache.line_and_column(position || self.pos)
+    end
+  end
+end
diff --git a/app/server/vendor/parslet/lib/parslet/source/line_cache.rb b/app/server/vendor/parslet/lib/parslet/source/line_cache.rb
new file mode 100755
index 0000000..315193a
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/source/line_cache.rb
@@ -0,0 +1,96 @@
+
+
+class Parslet::Source
+  # A cache for line start positions. 
+  #
+  class LineCache 
+    def initialize
+      # Stores line endings as a simple position number. The first line always
+      # starts at 0; numbers beyond the biggest entry are on any line > size, 
+      # but probably make a scan to that position neccessary.
+      @line_ends = []
+      @line_ends.extend RangeSearch
+    end
+
+    # Returns a <line, column> tuple for the given input position. 
+    # 
+    def line_and_column(pos)
+      eol_idx = @line_ends.lbound(pos)
+
+      if eol_idx
+        # eol_idx points to the offset that ends the current line.
+        # Let's try to find the offset that starts it: 
+        offset = eol_idx>0 && @line_ends[eol_idx-1] || 0
+        return [eol_idx+1, pos-offset+1]
+      else
+        # eol_idx is nil, that means that we're beyond the last line end that
+        # we know about. Pretend for now that we're just on the last line.
+        offset = @line_ends.last || 0
+        return [@line_ends.size+1, pos-offset+1]
+      end
+    end
+
+    def scan_for_line_endings(start_pos, buf)
+      return unless buf
+
+      buf = StringScanner.new(buf)
+      return unless buf.exist?(/\n/)
+
+      ## If we have already read part or all of buf, we already know about
+      ## line ends in that portion. remove it and correct cur (search index)
+      if @last_line_end && start_pos < @last_line_end
+        # Let's not search the range from start_pos to last_line_end again.
+        buf.pos = @last_line_end - start_pos
+      end
+
+      ## Scan the string for line endings; store the positions of all endings
+      ## in @line_ends. 
+      while buf.skip_until(/\n/)
+        @last_line_end = start_pos + buf.pos
+        @line_ends << @last_line_end
+      end
+    end
+  end
+
+  # Mixin for arrays that implicitly give a number of ranges, where one range
+  # begins where the other one ends.
+  # 
+  #   Example: 
+  #
+  #     [10, 20, 30]
+  #     # would describe [0, 10], (10, 20], (20, 30]
+  #
+  module RangeSearch 
+    def find_mid(left, right)
+      # NOTE: Jonathan Hinkle reported that when mathn is required, just
+      # dividing and relying on the integer truncation is not enough.
+      left + ((right - left) / 2).floor
+    end  
+    
+    # Scans the array for the first number that is > than bound. Returns the 
+    # index of that number. 
+    #
+    def lbound(bound)
+      return nil if empty?
+      return nil unless last > bound
+
+      left = 0
+      right = size - 1 
+
+      loop do
+        mid = find_mid(left, right)
+
+        if self[mid] > bound
+          right = mid
+        else
+          # assert: self[mid] <= bound
+          left = mid+1
+        end
+
+        if right <= left
+          return right
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/parslet/lib/parslet/transform.rb b/app/server/vendor/parslet/lib/parslet/transform.rb
new file mode 100755
index 0000000..b04fa29
--- /dev/null
+++ b/app/server/vendor/parslet/lib/parslet/transform.rb
@@ -0,0 +1,236 @@
+
+require 'parslet/pattern'
+
+# Transforms an expression tree into something else. The transformation
+# performs a depth-first, post-order traversal of the expression tree. During
+# that traversal, each time a rule matches a node, the node is replaced by the
+# result of the block associated to the rule. Otherwise the node is accepted
+# as is into the result tree.
+#
+# This is almost what you would generally do with a tree visitor, except that
+# you can match several levels of the tree at once. 
+#
+# As a consequence of this, the resulting tree will contain pieces of the
+# original tree and new pieces. Most likely, you will want to transform the
+# original tree wholly, so this isn't a problem.
+#
+# You will not be able to create a loop, given that each node will be replaced
+# only once and then left alone. This means that the results of a replacement
+# will not be acted upon. 
+#
+# Example: 
+#
+#   class Example < Parslet::Transform
+#     rule(:string => simple(:x)) {  # (1)
+#       StringLiteral.new(x)
+#     }
+#   end
+#
+# A tree transform (Parslet::Transform) is defined by a set of rules. Each
+# rule can be defined by calling #rule with the pattern as argument. The block
+# given will be called every time the rule matches somewhere in the tree given
+# to #apply. It is passed a Hash containing all the variable bindings of this
+# pattern match. 
+#   
+# In the above example, (1) illustrates a simple matching rule. 
+#
+# Let's say you want to parse matching parentheses and distill a maximum nest
+# depth. You would probably write a parser like the one in example/parens.rb;
+# here's the relevant part: 
+#
+#   rule(:balanced) {
+#     str('(').as(:l) >> balanced.maybe.as(:m) >> str(')').as(:r)
+#   }
+#
+# If you now apply this to a string like '(())', you get a intermediate parse
+# tree that looks like this: 
+#
+#   {
+#     l: '(', 
+#     m: {
+#       l: '(', 
+#       m: nil, 
+#       r: ')' 
+#     }, 
+#     r: ')' 
+#   }
+#
+# This parse tree is good for debugging, but what we would really like to have
+# is just the nesting depth. This transformation rule will produce that: 
+#
+#   rule(:l => '(', :m => simple(:x), :r => ')') { 
+#     # innermost :m will contain nil
+#     x.nil? ? 1 : x+1
+#   }
+#
+# = Usage patterns
+#
+# There are four ways of using this class. The first one is very much
+# recommended, followed by the second one for generality. The other ones are
+# omitted here. 
+#
+# Recommended usage is as follows: 
+#
+#   class MyTransformator < Parslet::Transform
+#     rule(...) { ... }
+#     rule(...) { ... }
+#     # ...
+#   end
+#   MyTransformator.new.apply(tree)
+#
+# Alternatively, you can use the Transform class as follows: 
+#
+#   transform = Parslet::Transform.new do
+#     rule(...) { ... }
+#   end
+#   transform.apply(tree)
+#
+# = Execution context
+#
+# The execution context of action blocks differs depending on the arity of 
+# said blocks. This can be confusing. It is however somewhat intentional. You 
+# should not create fat Transform descendants containing a lot of helper methods, 
+# instead keep your AST class construction in global scope or make it available
+# through a factory. The following piece of code illustrates usage of global
+# scope: 
+#
+#   transform = Parslet::Transform.new do
+#     rule(...) { AstNode.new(a_variable) }
+#     rule(...) { Ast.node(a_variable) } # modules are nice
+#   end
+#   transform.apply(tree)
+#
+# And here's how you would use a class builder (a factory):
+#
+#   transform = Parslet::Transform.new do
+#     rule(...) { builder.add_node(a_variable) }
+#     rule(...) { |d| d[:builder].add_node(d[:a_variable]) }
+#   end
+#   transform.apply(tree, :builder => Builder.new)
+#
+# As you can see, Transform allows you to inject local context for your rule
+# action blocks to use. 
+#
+class Parslet::Transform
+  # FIXME: Maybe only part of it? Or maybe only include into constructor
+  # context?
+  include Parslet   
+  
+  class << self
+    # FIXME: Only do this for subclasses?
+    include Parslet
+    
+    # Define a rule for the transform subclass. 
+    #
+    def rule(expression, &block)
+      @__transform_rules ||= []
+      @__transform_rules << [Parslet::Pattern.new(expression), block]
+    end
+    
+    # Allows accessing the class' rules
+    #
+    def rules 
+      @__transform_rules || []
+    end
+  end
+  
+  def initialize(&block) 
+    @rules = []
+    
+    if block
+      instance_eval(&block)
+    end
+  end
+  
+  # Defines a rule to be applied whenever apply is called on a tree. A rule
+  # is composed of two parts: 
+  # 
+  # * an *expression pattern*
+  # * a *transformation block*
+  #
+  def rule(expression, &block)
+    @rules << [
+      Parslet::Pattern.new(expression), 
+      block
+    ]
+  end
+  
+  # Applies the transformation to a tree that is generated by Parslet::Parser
+  # or a simple parslet. Transformation will proceed down the tree, replacing
+  # parts/all of it with new objects. The resulting object will be returned. 
+  #
+  def apply(obj, context=nil)
+    transform_elt(
+      case obj
+        when Hash
+          recurse_hash(obj, context)
+        when Array
+          recurse_array(obj, context)
+      else
+        obj
+      end, 
+      context
+    )
+  end
+  
+  # Executes the block on the bindings obtained by Pattern#match, if such a match
+  # can be made. Depending on the arity of the given block, it is called in 
+  # one of two environments: the current one or a clean toplevel environment.
+  #
+  # If you would like the current environment preserved, please use the 
+  # arity 1 variant of the block. Alternatively, you can inject a context object
+  # and call methods on it (think :ctx => self).
+  #
+  #   # the local variable a is simulated
+  #   t.call_on_match(:a => :b) { a } 
+  #   # no change of environment here
+  #   t.call_on_match(:a => :b) { |d| d[:a] }
+  #
+  def call_on_match(bindings, block)
+    if block
+      if block.arity == 1
+        return block.call(bindings)
+      else
+        context = Context.new(bindings)
+        return context.instance_eval(&block)
+      end
+    end
+  end
+  
+  # Allow easy access to all rules, the ones defined in the instance and the 
+  # ones predefined in a subclass definition. 
+  #
+  def rules 
+    self.class.rules + @rules
+  end
+  
+  # @api private 
+  #
+  def transform_elt(elt, context) 
+    rules.each do |pattern, block|
+      if bindings=pattern.match(elt, context)
+        # Produces transformed value
+        return call_on_match(bindings, block)
+      end
+    end
+    
+    # No rule matched - element is not transformed
+    return elt
+  end
+
+  # @api private 
+  #
+  def recurse_hash(hsh, ctx) 
+    hsh.inject({}) do |new_hsh, (k,v)|
+      new_hsh[k] = apply(v, ctx)
+      new_hsh
+    end
+  end
+  # @api private 
+  #
+  def recurse_array(ary, ctx) 
+    ary.map { |elt| apply(elt, ctx) }
+  end
+end
+
+require 'parslet/context'
\ No newline at end of file
diff --git a/app/server/vendor/parslet/parslet.gemspec b/app/server/vendor/parslet/parslet.gemspec
new file mode 100755
index 0000000..793074f
--- /dev/null
+++ b/app/server/vendor/parslet/parslet.gemspec
@@ -0,0 +1,18 @@
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
+  s.name = 'parslet'
+  s.version = '1.5.0'
+
+  s.authors = ['Kaspar Schiess']
+  s.email = 'kaspar.schiess at absurd.li'
+  s.extra_rdoc_files = ['README']
+  s.files = %w(HISTORY.txt LICENSE Rakefile README) + Dir.glob("{lib,example}/**/*")
+  s.homepage = 'http://kschiess.github.com/parslet'
+  s.license = 'MIT'
+  s.rdoc_options = ['--main', 'README']
+  s.require_paths = ['lib']
+  s.summary = 'Parser construction library with great error reporting in Ruby.'  
+  
+  s.add_dependency 'blankslate', '~> 2.0'
+end
diff --git a/app/server/vendor/parslet/qed/accelerators.md b/app/server/vendor/parslet/qed/accelerators.md
new file mode 100755
index 0000000..ff54374
--- /dev/null
+++ b/app/server/vendor/parslet/qed/accelerators.md
@@ -0,0 +1,206 @@
+# Parslet Accelerator
+
+## Synopsis
+
+Reading this all the way is worth it. But don't despair; if your attention span is short, read this and zap away! The TLDR: 
+
+Parslet is slow because of the way it is constructed internally. Optimisation helps, but makes your parser harder to read. Don't go there. Use parser accelerators instead - optimize parts of your parser without changing its definition. This is what it looks like: 
+
+    slow_parser = something >> slow_part >> other
+    
+    include Parslet::Accelerator
+    optimized_parser = apply(
+      rule( slow_part ) { faster_part })
+    
+    optimized_parser.parse('"Parsing is now fully optimized! (tm)"')    
+    
+Thus parslet allows you to write cristal clear parsers that are also as fast as you can make them. (But still slower than C!)
+
+## Introduction
+
+The goals of parslet are simple: make writing PEG parsers a predictable and straightforward endeavour. Some people have since claimed the word 'fun' for writing parsers, a connotation that we don't entirely oppose - otherwise why would we spend our time extending parslet?
+
+### Dark Clouds ahead
+
+Writing your first thousand line parser that works is easy – IF you use parslet. But very often, the resulting parser is rather slow - having execution times in the second range instead of the subsecond range. 
+
+You fire up your email client and drop us a mail to the mailing list, asking: "Why is parslet so slow?" You'll receive the following answers: 
+
+* Parslet is not a parser generator, but a parser engine based on Ruby. As such, it will be slower than parsers written in languages such as C. 
+* Parslet's internal structure is simple and clear. We've invested a lot of effort in making everything it does obvious and extendable. The downside of this somewhat OO-heavy approach is that we've got many objects juggling data and deep callstacks. Read: Bad use of caches and CPU time. 
+* Very few big languages have parsers written in high level languages such as Ruby. For good reasons. Depending on how serious you are about writing a new language (as opposed to fiddling around), you might want to _not start with parslet at all_.
+
+It's not like we haven't done anything to fix the above reasons; rather, we're doing everything we can, provided the main goal of *simplicity and understandability* is not in danger! If you look up what has been done over the years you will find a lot of small and large optimisations. But we have always refused to sacrifice simplicity of design to the god of optimisation, especially when it came to making a single parser faster. We want parslet to be fast in general, and frankly, your parser of language X is not our concern - only insofar as it uses parslet.
+
+But parslet needs to be useful for something. If not, what is the point? We would like to make parslet as useful as possible for smaller languages and for places where execution speed isn't your only concern. A lot of languages have rapidly evolving grammars and are developed by programmers that don't have the time for hand-writing parsers in C. 
+
+Still, what should you do once you've written your parser and speed becomes the issue? Until now, you had no real options short of rewriting the damn thing in C. That has changed: we've come up with Parslet Accelerator. The Accelerator will allow you to pattern match bits of your _parser_ and replace them with bits that do the same work, but faster. Really just hot spot optimisation, but without sacrificing readability of the original parser grammar.
+
+### An Example
+
+Let's consider the parser for quoted strings as an example, usually written to look something like this: 
+
+    quote = str('"')
+    quote >> (quote.absent? >> any).repeat >> quote
+    
+If we spell out the work parslet needs to do when matching a 1000 character string using this method, the performance problems will become obvious to you. Parslet will: 
+
+* Match a quote
+* In a loop: 
+  * Try to match a quote
+  * If that fails, continue, otherwise break from the loop
+  * Gobble up a single char
+* Match the final quote
+
+The inner loop will be executed a 1000 times; that's a 1000 times reading a char, checking to see if it's a quote, then reading it again, etc... As a programmer, this should disturb you deeply. And the fix, pseudo-code wise, should be obvious to you. Let's look at this revised flow: 
+
+* Match a quote
+* Gobble up as many chars as possible, until we hit a quote
+* Match the final quote
+
+Ok, we've sort of cheated there in the middle - we've transformed something into a single step that is really still a loop. But as a Ruby programmer, you will not see this as a loop, but rather as a call to a more efficient library like `StringScanner`, which underlies `Parslet::Source`.
+
+So we're pretty confident that this new parser will work faster; maybe fast even. Let's assume that we've got a `GobbleUp` atom that gobbles up chars until it hits a stop char. Our faster parser would have to look something like this: 
+
+    quote = str('"')
+    quote >> GobbleUp.new('"') >> quote
+    
+And all is fine, right? We don't think so. You've chosen to use parslet, so you don't want to end up sprinkling your grammar which is as much specification as it is implementation with things like `GobbleUp`. Wouldn't it be nice if you could keep the parser as it is, but somehow replace the pattern of `(quote.absent? >> any).repeat` with `GobbleUp.new('"')` before doing any work with your parser? Well, you can.
+
+    quote = str('"')
+    parser = quote >> (quote.absent? >> any).repeat >> quote
+    
+    A = Accelerator # for making what follows a bit shorter
+    optimized_parser = A.apply(parser, 
+      A.rule( (A.str(:x).absent? >> A.any).repeat ) { GobbleUp.new(x) })
+    
+    optimized_parser.parse('"Parsing is now fully optimized! (tm)"')
+    
+(If you're interested in a bit of history, the example that triggered the discussion around accelerators is preserved in [optimizer.rb](https://github.com/kschiess/parslet/blob/master/experiments/optimizer.rb). If you look past the hacks and the optimism, you'll recognize some of the things we talk about in this document.)
+
+### About this Document
+
+Now that the goal is defined, let us expose the details of the system proposed above. We'll start with explaining what these `Accelerator.rule` things are, how they match against your parser and how binding of variables work. (*Parslet Pattern Matching*) Then we'll explain what actions you can take once you've matched part of your parser. (*Binding and Actions*)
+
+## Parser Pattern Matching
+
+We'll demonstrate how pattern detection is constructed by showing what the smallest parts do first. Let's require needed libraries.
+
+    require 'parslet'
+    require 'parslet/accelerator'
+    
+    include Parslet
+    
+The whole optimizer code is inside the `Parslet::Accelerator` module. If you read that, read 'particle accelerator', not 'will make my code fast'. It is very possible to make things worse using `Parslet::Accelerator`. 
+    
+The simplest parser I can think of would be the one matching a simple string.
+
+    atom = str('foo')
+    expression = Accelerator.str(:x)
+    binding = Accelerator.match(atom, expression)
+
+    binding[:x].assert == 'foo'
+    
+Note that the above was somewhat verbose, with all these variables and all that. We'll write shorter examples from now on. 
+
+Another simple parser is the one that matches against variants of the `match(...)` atom. Multiple forms of this exist, so we'll go through all of them. First comes a simple character range match.
+
+    binding = Accelerator.match(
+      match['a-z'],
+      Accelerator.re(:x))
+      
+    binding[:x].assert == '[a-z]'
+
+Note how the internal regular expression value used for the match atom is really bound to :x – we'll keep this as a convention. This also means that some parslet internas are leaked through the Accelerator API here. We consider that a feature, since working with accelerators will bring you into close contact with the atoms internas.
+
+Also the Accelerator matcher for `Parslet.match` is called `Accelerator.re` - the reason for this should be obvious from what stands above. 
+
+Just to make this complete, a special case for the `match(...)` atom is the `any` atom. 
+
+    binding = Accelerator.match(any, Accelerator.any)
+    binding.assert != nil
+
+## Composite Parsers
+
+Let's start assembling these simple parsers into more complex patterns and match those. As our first pattern, we'll consider sequences.
+
+    binding = Accelerator.match(
+      str('a') >> str('b'), 
+      Accelerator.str(:x) >> Accelerator.str(:y))
+      
+    binding.values_at(:x, :y).assert == %w(a b)
+
+Also, alternatives should correctly bind. 
+
+    binding = Accelerator.match(
+      str('a') | str('b'), 
+      Accelerator.str(:x) | Accelerator.str(:y))
+
+    binding.values_at(:x, :y).assert == %w(a b)
+
+Note that this means that we bind to the whole alternative subtree, not either to the left or to the right. We're matching the parslet tree, so the meaning of the alternative is irrelevant. 
+
+Let's quickly skip through the list of other composite parsers here: First off is repetition. 
+
+    Accelerator.match(
+      str('a').repeat(1,2), 
+      A.str('a').repeat(1,2)).assert != nil
+
+And then there is positive and negative lookahead.
+
+    Accelerator.match(
+      str('a').present?, 
+      A.str('a').present?).assert != nil
+
+    Accelerator.match(
+      str('a').absent?, 
+      A.str('a').absent?).assert != nil
+      
+And named values.
+
+    Accelerator.match(
+      str('a').as(:a), 
+      A.str('a').as(:a)).assert != nil
+      
+Which we also want to be able to bind.
+
+    Accelerator.match(
+      str('a').as(:a), 
+      A.str('a').as(:b)).assert == {:b => :a}
+    
+## Binding to Values
+
+As a side note, our parser should also respect literal value matches in the pattern and only bind to subsequent locations when the values match up. 
+
+    binding = Accelerator.match(
+      str('a') >> str('b'), 
+      Accelerator.str(:x) >> Accelerator.str(:x))
+  
+    binding.assert == nil
+    
+Another property should be that literal strings passed to the pattern should be matched using ===. 
+
+    binding = Accelerator.match(
+      str('abc') >> str('bcd'), 
+      Accelerator.str(/b/) >> Accelerator.str('bcd'))
+  
+    binding.assert == {}
+
+The binding is empty here, since no variables were given. But lets also implement constrained variable bindings, that seems useful. The way this works is that you specify a variable you want to bind to first, and then a list of constraints that are matched by `#===`.
+
+    A.match(str('abc'), A.str(:x, /c/))[:x].assert == 'abc'
+    A.match(str('abc'), A.str(:x, /d/)).assert == nil
+   
+    A.match(str('abc'), A.str(:x, /a/, /c/))[:x].assert == 'abc'
+    A.match(str('abc'), A.str(:x, /a/, /d/)).assert == nil
+    
+Here's a quick demonstration that demonstrates that this feature equally applies to both `Accelerator.re` and `Parslet.match`. 
+
+    A.match(match['abc'], A.re(:x, /d/)).assert == nil
+    A.match(match['abc'], A.re(:x, /c/))[:x].assert == '[abc]'
+   
+## Bindings and Actions
+   
+## Closing Note
+
+* not a panacea
diff --git a/app/server/vendor/parslet/qed/applique/ae.rb b/app/server/vendor/parslet/qed/applique/ae.rb
new file mode 100755
index 0000000..614b388
--- /dev/null
+++ b/app/server/vendor/parslet/qed/applique/ae.rb
@@ -0,0 +1 @@
+require 'ae'
\ No newline at end of file
diff --git a/app/server/vendor/parslet/qed/applique/gobbleup.rb b/app/server/vendor/parslet/qed/applique/gobbleup.rb
new file mode 100755
index 0000000..e30a76b
--- /dev/null
+++ b/app/server/vendor/parslet/qed/applique/gobbleup.rb
@@ -0,0 +1,26 @@
+
+require 'parslet'
+
+# This is where the famous GobbleUp atom is defined. This parslet atom consumes
+# all chars until a given string (absent) is encountered.
+#
+class GobbleUp < Parslet::Atoms::Base
+  def initialize absent, min_chars=0
+    @absent = absent
+    @min_chars = min_chars
+  end
+
+  def try(source, context, consume_all)
+    excluding_length = source.chars_until(@absent)
+
+    if excluding_length >= @min_chars
+      return succ(source.consume(excluding_length))
+    else
+      return context.err(self, source, "No such string in input: #{@absent.inspect}.")
+    end
+  end
+
+  def to_s_inner(prec)
+    "until('#{@absent}')"
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/qed/applique/parslet.rb b/app/server/vendor/parslet/qed/applique/parslet.rb
new file mode 100755
index 0000000..f3d5588
--- /dev/null
+++ b/app/server/vendor/parslet/qed/applique/parslet.rb
@@ -0,0 +1,4 @@
+require 'parslet'
+require 'parslet/accelerator'
+
+include Parslet
\ No newline at end of file
diff --git a/app/server/vendor/parslet/readme.rb b/app/server/vendor/parslet/readme.rb
new file mode 100755
index 0000000..f29d249
--- /dev/null
+++ b/app/server/vendor/parslet/readme.rb
@@ -0,0 +1,38 @@
+require 'parslet'
+include Parslet
+
+# parslet parses strings
+str('foo').
+  parse('foo') # => "foo"@0
+  
+# it matches character sets
+match['abc'].parse('a') # => "a"@0
+match['abc'].parse('b') # => "b"@0
+match['abc'].parse('c') # => "c"@0
+
+# and it annotates its output
+str('foo').as(:important_bit).
+  parse('foo') # => {:important_bit=>"foo"@0}
+  
+# you can construct parsers with just a few lines
+quote = str('"')
+simple_string = quote >> (quote.absent? >> any).repeat >> quote
+
+simple_string.
+  parse('"Simple Simple Simple"') # => "\"Simple Simple Simple\""@0
+  
+# or by making a fuss about it 
+class Smalltalk < Parslet::Parser
+  root :smalltalk
+  
+  rule(:smalltalk) { statements }
+  rule(:statements) { 
+    # insert smalltalk parser here (outside of the scope of this readme)
+  }
+end
+
+# and then
+Smalltalk.new.parse('smalltalk')
+
+# be sure to read our 'Get started' tutorial at 
+# http://kschiess.github.com/parslet/get-started.html
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/acceptance/examples_spec.rb b/app/server/vendor/parslet/spec/acceptance/examples_spec.rb
new file mode 100755
index 0000000..7e0eae4
--- /dev/null
+++ b/app/server/vendor/parslet/spec/acceptance/examples_spec.rb
@@ -0,0 +1,37 @@
+require 'spec_helper'
+require 'open3'
+
+describe "Regression on" do
+  Dir["example/*.rb"].each do |example|
+    context example do
+      # Generates a product path for a given example file. 
+      def product_path(str, ext)
+        str.
+          gsub('.rb', ".#{ext}").
+          gsub('example/','example/output/')
+      end
+      
+      it "runs successfully" do
+        stdin, stdout, stderr = Open3.popen3("ruby #{example}")
+        
+        handle_map = {
+          stdout => :out, 
+          stderr => :err
+        }
+        expectation_found = handle_map.any? do |io, ext|
+          name = product_path(example, ext)
+          
+          if File.exists?(name)
+            io.read.strip.should == File.read(name).strip
+            true
+          end
+        end
+        
+        unless expectation_found
+          fail "Example doesn't have either an .err or an .out file. "+
+            "Please create in examples/output!"
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/parslet/spec/acceptance/infix_parser_spec.rb b/app/server/vendor/parslet/spec/acceptance/infix_parser_spec.rb
new file mode 100755
index 0000000..c676a29
--- /dev/null
+++ b/app/server/vendor/parslet/spec/acceptance/infix_parser_spec.rb
@@ -0,0 +1,112 @@
+require 'spec_helper'
+
+describe 'Infix expression parsing' do
+  class InfixExpressionParser < Parslet::Parser
+    rule(:space) { match['\s'] }
+
+    def cts atom
+      atom >> space.repeat
+    end
+    def infix *args
+      Infix.new(*args)
+    end
+
+    rule(:mul_op) { match['*/'] >> str(' ').maybe }
+    rule(:add_op) { match['+-'] >> str(' ').maybe }
+    rule(:digit) { match['0-9'] }
+    rule(:integer) { cts digit.repeat(1) }
+
+    rule(:expression) { infix_expression(integer, 
+      [mul_op, 2, :left], 
+      [add_op, 1, :right]) }
+  end
+
+  let(:p) { InfixExpressionParser.new }
+  describe '#integer' do
+    let(:i) { p.integer }
+    it "parses integers" do
+      i.should parse('1')
+      i.should parse('123')
+    end 
+    it "consumes trailing white space" do
+      i.should parse('1   ')
+      i.should parse('134   ')
+    end 
+    it "doesn't parse floats" do
+      i.should_not parse('1.3')
+    end 
+  end
+  describe '#multiplication' do
+    let(:m) { p.expression }
+    it "parses simple multiplication" do
+      m.should parse('1*2').as(l: '1', o: '*', r: '2')
+    end
+    it "parses simple multiplication with spaces" do
+      m.should parse('1 * 2').as(l: '1 ', o: '* ', r: '2')
+    end
+    it "parses division" do
+      m.should parse('1/2')
+    end 
+  end
+  describe '#addition' do
+    let(:a) { p.expression }
+    
+    it "parses simple addition" do
+      a.should parse('1+2')
+    end 
+    it "parses complex addition" do
+      a.should parse('1+2+3-4')
+    end
+    it "parses a single element" do
+      a.should parse('1')
+    end
+  end
+
+  describe 'mixed operations' do
+    let(:mo) { p.expression }
+
+    describe 'inspection' do
+      it 'produces useful expressions' do
+        p.expression.parslet.inspect.should == 
+          "infix_expression(INTEGER, [MUL_OP, ADD_OP])"
+      end
+    end
+    describe 'right associativity' do
+      it 'produces trees that lean right' do
+        mo.should parse('1+2+3').as(
+          l: '1', o: '+', r: {l: '2', o: '+', r: '3'})
+      end      
+    end
+    describe 'left associativity' do
+      it 'produces trees that lean left' do
+        mo.should parse('1*2*3').as(
+          l: {l:'1', o:'*', r:'2'}, o:'*', r:'3')
+      end      
+    end
+    describe 'error handling' do
+      describe 'incomplete expression' do
+        it 'produces the right error' do
+          cause = catch_failed_parse {
+            mo.parse('1+') }
+
+          cause.ascii_tree.to_s.should == <<-ERROR
+INTEGER was expected at line 1 char 3.
+`- Failed to match sequence (DIGIT{1, } SPACE{0, }) at line 1 char 3.
+   `- Expected at least 1 of DIGIT at line 1 char 3.
+      `- Premature end of input at line 1 char 3.
+          ERROR
+        end
+      end
+      describe 'invalid operator' do
+        it 'produces the right error' do
+          cause = catch_failed_parse {
+            mo.parse('1%') }
+
+          cause.ascii_tree.to_s.should == <<-ERROR
+Don't know what to do with "%" at line 1 char 2.
+          ERROR
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/acceptance/regression_spec.rb b/app/server/vendor/parslet/spec/acceptance/regression_spec.rb
new file mode 100755
index 0000000..7cd668c
--- /dev/null
+++ b/app/server/vendor/parslet/spec/acceptance/regression_spec.rb
@@ -0,0 +1,314 @@
+# Encoding: UTF-8
+
+require 'spec_helper'
+
+require 'parslet'
+
+describe "Regressions from real examples" do
+  # This parser piece produces on the left a subtree that is keyed (a hash)
+  # and on the right a subtree that is a repetition of such subtrees. I've
+  # for now decided that these would merge into the repetition such that the
+  # return value is an array. This avoids maybe loosing keys/values in a 
+  # hash merge. 
+  #
+  class ArgumentListParser
+    include Parslet
+
+    rule :argument_list do
+      expression.as(:argument) >> 
+        (comma >> expression.as(:argument)).repeat
+    end
+    rule :expression do
+      string
+    end
+    rule :string do
+      str('"') >> 
+      (
+        str('\\') >> any |
+        str('"').absent? >> any
+      ).repeat.as(:string) >>
+      str('"') >> space?
+    end
+    rule :comma do
+      str(',') >> space?
+    end
+    rule :space? do
+      space.maybe
+    end
+    rule :space do
+      match("[ \t]").repeat(1)
+    end
+    
+    def parse(str)
+      argument_list.parse(str)
+    end
+  end
+  describe ArgumentListParser do
+    let(:instance) { ArgumentListParser.new }
+    it "should have method expression" do
+      instance.should respond_to(:expression)
+    end 
+    it 'should parse "arg1", "arg2"' do
+      result = ArgumentListParser.new.parse('"arg1", "arg2"')
+      
+      result.should have(2).elements
+      result.each do |r|
+        r[:argument]
+      end
+    end
+    it 'should parse "arg1", "arg2", "arg3"' do
+      result = ArgumentListParser.new.parse('"arg1", "arg2", "arg3"')
+      
+      result.should have(3).elements
+      result.each do |r|
+        r[:argument]
+      end
+    end
+  end
+
+  class ParensParser < Parslet::Parser
+    rule(:balanced) {
+      str('(').as(:l) >> balanced.maybe.as(:m) >> str(')').as(:r)
+    }
+  
+    root(:balanced)
+  end
+  describe ParensParser do
+    let(:instance) { ParensParser.new }
+    
+    context "statefulness: trying several expressions in sequence" do
+      it "should not be stateful" do
+        # NOTE: Since you've come here to read this, I'll explain why
+        # this is broken and not fixed: You're looking at the tuning branch, 
+        # which rewrites a bunch of stuff - so I have failing tests to 
+        # remind me of what is left to be done. And to remind you not to 
+        # trust this code. 
+        instance.parse('(())')
+        lambda {
+          instance.parse('((()))')
+          instance.parse('(((())))')
+        }.should_not raise_error
+      end 
+    end
+    context "expression '(())'" do
+      let(:result) { instance.parse('(())') }
+
+      it "should yield a doubly nested hash" do
+        result.should be_a(Hash)
+        result.should have_key(:m)
+        result[:m].should be_a(Hash)   # This was an array earlier
+      end 
+      context "inner hash" do
+        let(:inner) { result[:m] }
+        
+        it "should have nil as :m" do
+          inner[:m].should be_nil
+        end 
+      end
+    end
+  end
+
+  class ALanguage < Parslet::Parser
+    root(:expressions)
+
+    rule(:expressions) { (line >> eol).repeat(1) | line }
+    rule(:line) { space? >> an_expression.as(:exp).repeat }
+    rule(:an_expression) { str('a').as(:a) >> space? }
+
+    rule(:eol) { space? >> match["\n\r"].repeat(1) >> space? }
+
+    rule(:space?) { space.repeat }
+    rule(:space) { multiline_comment.as(:multi) | line_comment.as(:line) | str(' ') }
+
+    rule(:line_comment) { str('//') >> (match["\n\r"].absent? >> any).repeat }
+    rule(:multiline_comment) { str('/*') >> (str('*/').absent? >> any).repeat >> str('*/') }
+  end
+  describe ALanguage do
+    def remove_indent(s)
+      s.to_s.lines.map { |l| l.chomp.strip }.join("\n")
+    end
+    
+    it "should count lines correctly" do
+      cause = catch_failed_parse {
+        subject.parse('a
+          a a a 
+          aaa // ff
+          /* 
+          a
+          */
+          b
+        ')
+      }
+
+      remove_indent(cause.ascii_tree).should == remove_indent(%q(
+      Expected one of [(LINE EOL){1, }, LINE] at line 1 char 1.
+      |- Extra input after last repetition at line 7 char 11.
+      |  `- Failed to match sequence (LINE EOL) at line 7 char 11.
+      |     `- Failed to match sequence (SPACE? [\n\r]{1, } SPACE?) at line 7 char 11.
+      |        `- Expected at least 1 of [\n\r] at line 7 char 11.
+      |           `- Failed to match [\n\r] at line 7 char 11.
+      `- Don't know what to do with "\n         " at line 1 char 2.).strip)
+    end 
+  end
+
+  class BLanguage < Parslet::Parser
+    root :expression
+    rule(:expression) { b.as(:one) >> b.as(:two) }
+    rule(:b) { str('b') }
+  end
+  describe BLanguage do
+    it "should parse 'bb'" do
+      subject.should parse('bb').as(:one => 'b', :two => 'b')
+    end 
+    it "should transform with binding constraint" do
+      transform = Parslet::Transform.new do |t|
+        t.rule(:one => simple(:b), :two => simple(:b)) { :ok }
+      end
+      transform.apply(subject.parse('bb')).should == :ok
+    end 
+  end
+
+  class UnicodeLanguage < Parslet::Parser
+    root :gobble
+    rule(:gobble) { any.repeat }
+  end
+  describe UnicodeLanguage do
+    it "should parse UTF-8 strings" do
+      subject.should parse('éèäöü').as('éèäöü')
+      subject.should parse('RubyKaigi2009のテーマは、「変わる/変える」です。 前回の').as('RubyKaigi2009のテーマは、「変わる/変える」です。 前回の')
+    end 
+  end
+  
+  class UnicodeSentenceLanguage < Parslet::Parser
+    rule(:sentence) { (match('[^。]').repeat(1) >> str("。")).as(:sentence) }
+    rule(:sentences) { sentence.repeat }
+    root(:sentences)
+  end
+  describe UnicodeSentenceLanguage do
+    let(:string) {
+      "RubyKaigi2009のテーマは、「変わる/変える」です。 前回の" +
+      "RubyKaigi2008のテーマであった「多様性」の言葉の通り、 " +
+      "2008年はRubyそのものに関しても、またRubyの活躍する舞台に関しても、 " +
+      "ますます多様化が進みつつあります。RubyKaigi2008は、そのような " +
+      "Rubyの生態系をあらためて認識する場となりました。 しかし、" +
+      "こうした多様化が進む中、異なる者同士が単純に距離を 置いたままでは、" +
+      "その違いを認識したところであまり意味がありません。 異なる実装、" +
+      "異なる思想、異なる背景といった、様々な多様性を理解しつつ、 " +
+      "すり合わせるべきものをすり合わせ、変えていくべきところを " +
+      "変えていくことが、豊かな未来へとつながる道に違いありません。"
+    }
+    
+    it "should parse sentences" do
+      subject.should parse(string)
+    end 
+  end
+
+  class TwoCharLanguage < Parslet::Parser
+    root :twochar
+    rule(:twochar) { any >> str('2') }
+  end
+  describe TwoCharLanguage do
+    def di(s)
+      s.strip.to_s.lines.map { |l| l.chomp.strip }.join("\n")
+    end
+
+    it "should raise an error" do
+      error = catch_failed_parse {
+        subject.parse('123') }
+      di(error.ascii_tree).should == di(%q(
+        Failed to match sequence (. '2') at line 1 char 2.
+        `- Don't know what to do with "3" at line 1 char 3.
+      ))
+    end 
+  end
+
+  # Issue #68: Extra input reporting, written by jmettraux
+  class RepetitionParser < Parslet::Parser
+    rule(:nl)      { match('[\s]').repeat(1) }
+    rule(:nl?)     { nl.maybe }
+    rule(:sp)      { str(' ').repeat(1) }
+    rule(:sp?)     { str(' ').repeat(0) }
+    rule(:line)    { sp >> str('line') }
+    rule(:body)    { ((line | block) >> nl).repeat(0) }
+    rule(:block)   { sp? >> str('begin') >> sp >> match('[a-z]') >> nl >>
+                     body >> sp? >> str('end') }
+    rule(:blocks)  { nl? >> block >> (nl >> block).repeat(0) >> nl? }
+
+    root(:blocks)
+  end
+  describe RepetitionParser do
+    def di(s)
+      s.strip.to_s.lines.map { |l| l.chomp.strip }.join("\n")
+    end
+
+    it 'parses a block' do
+      subject.parse(%q{
+        begin a
+        end
+      })
+    end
+    it 'parses nested blocks' do
+      subject.parse(%q{
+        begin a
+          begin b
+          end
+        end
+      })
+    end
+    it 'parses successive blocks' do
+      subject.parse(%q{
+        begin a
+        end
+        begin b
+        end
+      })
+    end
+    it 'fails gracefully on a missing end' do
+      error = catch_failed_parse {
+        subject.parse(%q{
+          begin a
+            begin b
+          end
+        }) }
+      
+      di(error.ascii_tree).should == di(%q(
+        Failed to match sequence (NL? BLOCK (NL BLOCK){0, } NL?) at line 2 char 11.
+        `- Failed to match sequence (SP? 'begin' SP [a-z] NL BODY SP? 'end') at line 5 char 9.
+           `- Premature end of input at line 5 char 9.
+        ))
+    end
+    it 'fails gracefully on a missing end (2)' do
+      error = catch_failed_parse {
+        subject.parse(%q{
+          begin a
+          end
+          begin b
+            begin c
+          end
+        }) }
+
+      di(error.ascii_tree).should == di(%q(
+        Failed to match sequence (NL? BLOCK (NL BLOCK){0, } NL?) at line 3 char 14.
+        `- Don't know what to do with "begin b\n  " at line 4 char 11.
+        ))
+    end
+    it 'fails gracefully on a missing end (deepest reporter)' do
+      error = catch_failed_parse {
+        subject.parse(%q{
+            begin a
+            end
+            begin b
+              begin c
+                li
+              end
+            end
+          },
+          :reporter => Parslet::ErrorReporter::Deepest.new) }
+
+      di(error.ascii_tree).should == di(%q(
+        Failed to match sequence (NL? BLOCK (NL BLOCK){0, } NL?) at line 3 char 16.
+        `- Expected "end", but got "li\n" at line 6 char 17.
+        ))
+    end
+  end
+end
diff --git a/app/server/vendor/parslet/spec/acceptance/repetition_and_maybe_spec.rb b/app/server/vendor/parslet/spec/acceptance/repetition_and_maybe_spec.rb
new file mode 100755
index 0000000..8bfcab5
--- /dev/null
+++ b/app/server/vendor/parslet/spec/acceptance/repetition_and_maybe_spec.rb
@@ -0,0 +1,42 @@
+require 'spec_helper'
+
+describe "Tree output" do
+  extend Parslet
+
+  def self.hash_examples(h)
+    h.each do |atom, expected|
+      it "should convert #{atom} to #{expected.inspect}" do
+        atom.parse(input).should == expected
+      end
+    end
+  end
+
+  context "when parsing the empty string" do
+    let(:input) { '' }
+    hash_examples( 
+      # No naming 
+      str('a').maybe              => '', 
+      str('a').repeat             => '',
+      
+      # Named contents: maybe yields nil
+      str('a').maybe.as(:f)       => {:f => nil},
+      str('a').repeat.as(:f)      => {:f => []}, 
+      
+      # Contents that aren't simple strings
+      (str('a') >> str('b')).maybe.as(:f)     => {:f => nil},
+      (str('a') >> str('b')).repeat.as(:f)    => {:f => []}, 
+      
+      # The other way around: Contents would be tagged, but nil result isn't
+      (str('a') >> str('b')).as(:f).maybe     => '',
+      (str('a') >> str('b')).as(:f).repeat    => ''
+    )
+  end
+  
+  context "when parsing 'aa'" do
+    let(:input) { 'aa' }
+    hash_examples(
+      # since they're not named, repetitions get merged together.
+      str('a').as(:a).repeat >> str('a').as(:a).repeat => [{:a=>'a'},{:a=>'a'}]
+    )
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/acceptance/unconsumed_input_spec.rb b/app/server/vendor/parslet/spec/acceptance/unconsumed_input_spec.rb
new file mode 100755
index 0000000..ffc48f8
--- /dev/null
+++ b/app/server/vendor/parslet/spec/acceptance/unconsumed_input_spec.rb
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+describe "Unconsumed input:" do
+  class RepeatingBlockParser < Parslet::Parser
+    root :expressions
+    rule(:expressions) { expression.repeat }
+    rule(:expression) { str('(') >> aab >> str(')') }
+    rule(:aab) { str('a').repeat(1) >> str('b') }
+  end
+  describe RepeatingBlockParser do
+    let(:parser) { described_class.new }
+    it "throws annotated error" do
+      error = catch_failed_parse { parser.parse('(aaac)') }
+    end
+    it "doesn't error out if prefix is true" do
+      expect {
+        parser.parse('(aaac)', :prefix => true)
+      }.not_to raise_error
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atom_results_spec.rb b/app/server/vendor/parslet/spec/parslet/atom_results_spec.rb
new file mode 100755
index 0000000..1dcfafa
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atom_results_spec.rb
@@ -0,0 +1,39 @@
+require 'spec_helper'
+
+describe 'Result of a Parslet#parse' do
+  include Parslet; extend Parslet
+  
+  describe "regression" do
+    [
+      # Behaviour with maybe-nil
+      [str('foo').maybe >> str('bar'), "bar", "bar"],
+      [str('bar') >> str('foo').maybe, "bar", 'bar'], 
+      
+      # These might be hard to understand; look at the result of 
+      #   str.maybe >> str
+      # and 
+      #   str.maybe >> str first. 
+      [(str('f').maybe >> str('b')).repeat, "bb", "bb"],
+      [(str('b') >> str('f').maybe).repeat, "bb", 'bb'], 
+      
+      [str('a').as(:a) >> (str('b') >> str('c').as(:a)).repeat, 'abc', 
+        [{:a=>'a'}, {:a=>'c'}]], 
+      
+      [str('a').as(:a).repeat >> str('b').as(:b).repeat, 'ab', [{:a=>'a'}, {:b=>'b'}]], 
+      
+      # Repetition behaviour / named vs. unnamed
+      [str('f').repeat, '', ''], 
+      [str('f').repeat.as(:f), '', {:f => []}],
+
+      # Maybe behaviour / named vs. unnamed
+      [str('f').maybe, '', ''], 
+      [str('f').maybe.as(:f), '', {:f => nil}],
+    ].each do |parslet, input, result|
+      context "#{parslet.inspect}" do
+        it "should parse \"#{input}\" into \"#{result}\"" do
+          parslet.parse(input).should == result
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atoms/alternative_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms/alternative_spec.rb
new file mode 100755
index 0000000..79bd296
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms/alternative_spec.rb
@@ -0,0 +1,26 @@
+require 'spec_helper'
+
+describe Parslet::Atoms::Alternative do
+  include Parslet
+  
+  describe '| shortcut' do
+    let(:alternative) { str('a') | str('b') }
+    
+    context "when chained with different atoms" do
+      before(:each) { 
+        # Chain something else to the alternative parslet. If it modifies the
+        # parslet atom in place, we'll notice: 
+        
+        alternative | str('d')
+      }
+      let!(:chained) { alternative | str('c') }
+      
+      
+      it "is side-effect free" do
+        chained.should parse('c')
+        chained.should parse('a')
+        chained.should_not parse('d')
+      end 
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atoms/base_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms/base_spec.rb
new file mode 100755
index 0000000..d94bd81
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms/base_spec.rb
@@ -0,0 +1,124 @@
+require 'spec_helper'
+
+describe Parslet::Atoms::Base do
+  let(:parslet) { Parslet::Atoms::Base.new }
+  let(:context) { Parslet::Atoms::Context.new }
+
+  describe "<- #try(io)" do
+    it "should raise NotImplementedError" do
+      lambda {
+        parslet.try(flexmock(:io), context, false)
+      }.should raise_error(NotImplementedError)
+    end 
+  end
+  describe "<- #flatten_sequence" do
+    [
+      # 9 possibilities for making a word of 2 letters from the alphabeth of
+      # A(rray), H(ash) and S(tring). Make sure that all results are valid.
+      #
+      ['a', 'b'], 'ab',                             # S S
+      [['a'], ['b']], ['a', 'b'],                   # A A
+      [{:a=>'a'}, {:b=>'b'}], {:a=>'a',:b=>'b'},    # H H
+      
+      [{:a=>'a'}, ['a']], [{:a=>'a'}, 'a'],         # H A
+      [{:a=>'a'}, 's'],   {:a=>'a'},                # H S
+
+      [['a'], {:a=>'a'}], ['a', {:a=>'a'}],         # A H (symmetric to H A)
+      [['a'], 'b'], ['a'],                          # A S 
+
+      ['a', {:b=>'b'}], {:b=>'b'},                  # S H (symmetric to H S)
+      ['a', ['b']], ['b'],                          # S A (symmetric to A S)
+      
+      [nil, ['a']], ['a'],                          # handling of lhs nil
+      [nil, {:a=>'a'}], {:a=>'a'},
+      [['a'], nil], ['a'],                          # handling of rhs nil
+      [{:a=>'a'}, nil], {:a=>'a'}
+    ].each_slice(2) do |sequence, result|
+      context "for " + sequence.inspect do
+        it "should equal #{result.inspect}" do
+          parslet.flatten_sequence(sequence).should == result
+        end
+      end
+    end
+  end
+  describe "<- #flatten_repetition" do
+    def unnamed(obj)
+      parslet.flatten_repetition(obj, false)
+    end
+    
+    it "should give subtrees precedence" do
+      unnamed([[{:a=>"a"}, {:m=>"m"}], {:a=>"a"}]).should == [{:a=>"a"}]
+    end 
+  end
+  describe '#parse(source)' do
+    context "when given something that looks like a source" do
+      let(:source) { flexmock("source lookalike", 
+        :line_and_column => [1,2], 
+        :pos => 1, 
+        :chars_left => 0) }
+      
+      it "should not rewrap in a source" do
+        flexmock(Parslet::Source).
+          should_receive(:new => :source_created).never
+        
+        begin
+          parslet.parse(source) 
+        rescue NotImplementedError
+        end
+      end 
+    end
+  end
+  
+  context "when the parse fails, the exception" do
+    it "should contain a string" do
+      begin
+        Parslet.str('foo').parse('bar')
+      rescue Parslet::ParseFailed => ex
+        ex.message.should be_kind_of(String)
+      end
+    end 
+  end
+  context "when not all input is consumed" do
+    let(:parslet) { Parslet.str('foo') }
+    
+    it "should raise with a proper error message" do
+      error = catch_failed_parse {
+        parslet.parse('foobar') }
+      
+      error.to_s.should == "Don't know what to do with \"bar\" at line 1 char 4."
+    end 
+  end
+  context "when only parsing string prefix" do
+    let(:parslet) { Parslet.str('foo') >> Parslet.str('bar') }
+    
+    it "returns the first half on a prefix parse" do
+      parslet.parse('foobarbaz', :prefix => true).should == 'foobar'
+    end 
+  end
+
+  describe ':reporter option' do
+    let(:parslet) { Parslet.str('test') >> Parslet.str('ing') }
+    let(:reporter) { flexmock(:reporter) }
+    
+    it "replaces the default reporter" do
+      cause = flexmock(:cause)
+      
+      # Two levels of the parse, calling two different error reporting
+      # methods.
+      reporter.
+        should_receive(:err_at).once
+      reporter.
+        should_receive(:err => cause).once
+      
+      # The final cause will be sent the #raise method.
+      cause.
+        should_receive(:raise).once.and_throw(:raise)
+      
+      catch(:raise) {
+        parslet.parse('testung', :reporter => reporter)
+        
+        fail "NEVER REACHED"
+      }
+    end 
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atoms/capture_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms/capture_spec.rb
new file mode 100755
index 0000000..2f3a68a
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms/capture_spec.rb
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+describe Parslet::Atoms::Capture do
+  include Parslet
+  
+  let(:context) { Parslet::Atoms::Context.new(nil) }
+  
+  def inject string, parser
+    source = Parslet::Source.new(string)
+    parser.apply(source, context, true)
+  end
+  
+  it "should capture simple results" do
+    inject 'a', str('a').capture(:a)
+    context.captures[:a].should == 'a'
+  end 
+  it "should capture complex results" do
+    inject 'a', str('a').as(:b).capture(:a)
+    context.captures[:a].should == {:b => 'a'}
+  end 
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atoms/combinations_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms/combinations_spec.rb
new file mode 100755
index 0000000..5edbfff
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms/combinations_spec.rb
@@ -0,0 +1,5 @@
+require 'spec_helper'
+
+describe "Parslet combinations" do
+  include Parslet
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atoms/dsl_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms/dsl_spec.rb
new file mode 100755
index 0000000..8eee35a
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms/dsl_spec.rb
@@ -0,0 +1,17 @@
+require 'spec_helper'
+
+describe Parslet::Atoms::DSL do
+  describe "deprecated methods" do
+    let(:parslet) { Parslet.str('foo') }
+    describe "<- #absnt?" do
+      subject { parslet.absnt? }
+      its(:bound_parslet) { should == parslet }
+      its(:positive) { should == false }
+    end
+    describe "<- #prsnt?" do
+      subject { parslet.prsnt? }
+      its(:bound_parslet) { should == parslet }
+      its(:positive) { should == true }
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atoms/entity_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms/entity_spec.rb
new file mode 100755
index 0000000..a5499bc
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms/entity_spec.rb
@@ -0,0 +1,52 @@
+require 'spec_helper'
+
+describe Parslet::Atoms::Entity do
+  context "when constructed with str('bar') inside" do
+    let(:named) { Parslet::Atoms::Entity.new('name', &proc { Parslet.str('bar') }) }
+
+    it "should parse 'bar' without raising exceptions" do
+      named.parse('bar')
+    end 
+    it "should raise when applied to 'foo'" do
+      lambda {
+        named.parse('foo')
+      }.should raise_error(Parslet::ParseFailed)
+    end 
+
+    describe "#inspect" do
+      it "should return the name of the entity" do
+        named.inspect.should == 'NAME'
+      end 
+    end
+  end
+  context "when constructed with empty block" do
+    let(:entity) { Parslet::Atoms::Entity.new('name', &proc { }) }
+    
+    it "should raise NotImplementedError" do
+      lambda {
+        entity.parse('some_string')
+      }.should raise_error(NotImplementedError)
+    end 
+  end
+  
+  context "recursive definition parser" do
+    class RecDefParser
+      include Parslet
+      rule :recdef do
+        str('(') >> atom >> str(')')
+      end
+      rule :atom do
+        str('a') | str('b') | recdef
+      end
+    end
+    let(:parser) { RecDefParser.new }
+    
+    it "should parse balanced parens" do
+      parser.recdef.parse("(((a)))")
+    end
+    it "should not throw 'stack level too deep' when printing errors" do
+      cause = catch_failed_parse { parser.recdef.parse('(((a))') }
+      cause.ascii_tree
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atoms/infix_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms/infix_spec.rb
new file mode 100755
index 0000000..203a3ff
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms/infix_spec.rb
@@ -0,0 +1,5 @@
+require 'spec_helper'
+
+describe Parslet::Atoms::Infix do
+
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atoms/lookahead_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms/lookahead_spec.rb
new file mode 100755
index 0000000..ac54ecd
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms/lookahead_spec.rb
@@ -0,0 +1,22 @@
+require 'spec_helper'
+
+describe Parslet::Atoms::Lookahead do
+  include Parslet
+  
+  describe 'negative lookahead' do
+    it "influences the error tree" do
+      parser = str('f').absent? >> str('b')
+      cause = catch_failed_parse { parser.parse('f') }
+      
+      cause.ascii_tree.should == "Failed to match sequence (!'f' 'b') at line 1 char 1.\n`- Input should not start with 'f' at line 1 char 1.\n"
+    end 
+  end
+  describe 'positive lookahead' do
+    it "influences the error tree" do
+      parser = str('f').present? >> str('b')
+      cause = catch_failed_parse { parser.parse('b') }
+      
+      cause.ascii_tree.should == "Failed to match sequence (&'f' 'b') at line 1 char 1.\n`- Input should start with 'f' at line 1 char 1.\n"
+    end 
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atoms/named_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms/named_spec.rb
new file mode 100755
index 0000000..98ce14d
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms/named_spec.rb
@@ -0,0 +1,4 @@
+require 'spec_helper'
+
+describe Parslet::Atoms::Named do
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atoms/re_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms/re_spec.rb
new file mode 100755
index 0000000..44f9cd7
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms/re_spec.rb
@@ -0,0 +1,14 @@
+require 'spec_helper'
+
+describe Parslet::Atoms::Re do
+  describe "construction" do
+    include Parslet
+    
+    it "should allow match(str) form" do
+      match('[a]').should be_a(Parslet::Atoms::Re)
+    end 
+    it "should allow match[str] form" do
+      match['a'].should be_a(Parslet::Atoms::Re)
+    end 
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atoms/repetition_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms/repetition_spec.rb
new file mode 100755
index 0000000..0f6a8c1
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms/repetition_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+describe Parslet::Atoms::Repetition do
+  include Parslet
+
+  describe "repeat" do
+    let(:parslet) { str('a') }
+    
+    describe "(min, max)" do
+      subject { parslet.repeat(1,2) }
+      
+      it { should_not parse("") }
+      it { should parse("a") }
+      it { should parse("aa") }
+    end
+    describe "0 times" do
+      it "raises an ArgumentError" do
+        expect {
+          parslet.repeat(0,0)
+        }.to raise_error(ArgumentError)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atoms/scope_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms/scope_spec.rb
new file mode 100755
index 0000000..2664bc8
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms/scope_spec.rb
@@ -0,0 +1,26 @@
+require 'spec_helper'
+
+describe Parslet::Atoms::Scope do
+  include Parslet
+  include Parslet::Atoms::DSL
+  
+  
+  let(:context) { Parslet::Atoms::Context.new(nil) }
+  let(:captures) { context.captures }
+  
+  def inject string, parser
+    source = Parslet::Source.new(string)
+    parser.apply(source, context, true)
+  end
+  
+  let(:aabb) { 
+    scope {
+      match['ab'].capture(:f) >> dynamic { |s,c| str(c.captures[:f]) }
+    }
+  }
+  it "keeps values of captures outside" do
+    captures[:f] = 'old_value'
+    inject 'aa', aabb
+    captures[:f].should == 'old_value'
+  end 
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atoms/sequence_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms/sequence_spec.rb
new file mode 100755
index 0000000..c2cec13
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms/sequence_spec.rb
@@ -0,0 +1,28 @@
+require 'spec_helper'
+
+describe Parslet::Atoms::Sequence do
+  include Parslet
+  
+  let(:sequence) { described_class.new }
+  
+  describe '>> shortcut' do
+    let(:sequence) { str('a') >> str('b') }
+    
+    context "when chained with different atoms" do
+      before(:each) { 
+        # Chain something else to the sequence parslet. If it modifies the
+        # parslet atom in place, we'll notice: 
+        
+        sequence >> str('d')
+      }
+      let!(:chained) { sequence >> str('c') }
+      
+      
+      it "is side-effect free" do
+        chained.should parse('abc')
+        chained.should_not parse('abdc')
+      end 
+    end
+    
+  end
+end
diff --git a/app/server/vendor/parslet/spec/parslet/atoms/str_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms/str_spec.rb
new file mode 100755
index 0000000..455f82d
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms/str_spec.rb
@@ -0,0 +1,15 @@
+# Encoding: UTF-8
+
+require 'spec_helper'
+
+describe Parslet::Atoms::Str do
+  def str(s)
+    described_class.new(s)
+  end
+  
+  describe 'regression #1: multibyte characters' do
+    it "parses successfully (length check works)" do
+      str('あああ').should parse('あああ')
+    end 
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atoms/visitor_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms/visitor_spec.rb
new file mode 100755
index 0000000..c195cee
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms/visitor_spec.rb
@@ -0,0 +1,80 @@
+require 'spec_helper'
+
+describe Parslet::Atoms do
+  include Parslet
+  let(:visitor) { flexmock(:visitor) }
+  
+  describe Parslet::Atoms::Str do
+    let(:parslet) { str('foo') }
+    it "should call back visitor" do
+      visitor.should_receive(:visit_str).with('foo').once
+      
+      parslet.accept(visitor)
+    end 
+  end
+  describe Parslet::Atoms::Re do
+    let(:parslet) { match['abc'] }
+    it "should call back visitor" do
+      visitor.should_receive(:visit_re).with('[abc]').once
+      
+      parslet.accept(visitor)
+    end 
+  end
+  describe Parslet::Atoms::Sequence do
+    let(:parslet) { str('a') >> str('b') }
+    it "should call back visitor" do
+      visitor.should_receive(:visit_sequence).with(Array).once
+      
+      parslet.accept(visitor)
+    end 
+  end
+  describe Parslet::Atoms::Repetition do
+    let(:parslet) { str('a').repeat(1,2) }
+    it "should call back visitor" do
+      visitor.should_receive(:visit_repetition).with(:repetition, 1, 2, Parslet::Atoms::Base).once
+      
+      parslet.accept(visitor)
+    end 
+  end
+  describe Parslet::Atoms::Alternative do
+    let(:parslet) { str('a') | str('b') }
+    it "should call back visitor" do
+      visitor.should_receive(:visit_alternative).with(Array).once
+      
+      parslet.accept(visitor)
+    end 
+  end
+  describe Parslet::Atoms::Named do
+    let(:parslet) { str('a').as(:a) }
+    it "should call back visitor" do
+      visitor.should_receive(:visit_named).with(:a, Parslet::Atoms::Base).once
+      
+      parslet.accept(visitor)
+    end 
+  end
+  describe Parslet::Atoms::Entity do
+    let(:parslet) { Parslet::Atoms::Entity.new('foo', &lambda {}) }
+    it "should call back visitor" do
+      visitor.should_receive(:visit_entity).with('foo', Proc).once
+      
+      parslet.accept(visitor)
+    end 
+  end
+  describe Parslet::Atoms::Lookahead do
+    let(:parslet) { str('a').absent? }
+    it "should call back visitor" do
+      visitor.should_receive(:visit_lookahead).with(false, Parslet::Atoms::Base).once
+      
+      parslet.accept(visitor)
+    end 
+  end
+  describe "< Parslet::Parser" do
+    let(:parslet) { Parslet::Parser.new }
+    it "calls back to visitor" do
+      visitor.should_receive(:visit_parser).with(:root).once
+      
+      flexmock(parslet, :root => :root)
+      parslet.accept(visitor)
+    end 
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/atoms_spec.rb b/app/server/vendor/parslet/spec/parslet/atoms_spec.rb
new file mode 100755
index 0000000..a1aba74
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/atoms_spec.rb
@@ -0,0 +1,429 @@
+require 'spec_helper'
+
+require 'timeout'
+require 'parslet'
+
+describe Parslet do
+  def not_parse
+    raise_error(Parslet::ParseFailed)
+  end
+  
+  include Parslet
+  extend Parslet
+
+  def src(str); Parslet::Source.new str; end
+  let(:context) { Parslet::Atoms::Context.new }
+  
+  describe "match('[abc]')" do
+    attr_reader :parslet
+    before(:each) do
+      @parslet = match('[abc]')
+    end
+    
+    it "should parse {a,b,c}" do
+      parslet.parse('a')
+      parslet.parse('b')
+      parslet.parse('c')
+    end 
+    it "should not parse d" do
+      cause = catch_failed_parse {
+        parslet.parse('d')
+      }
+      cause.to_s.should == "Failed to match [abc] at line 1 char 1."
+    end 
+    it "should print as [abc]" do
+      parslet.inspect.should == "[abc]"
+    end 
+  end
+  describe "match(['[a]').repeat(3)" do
+    attr_reader :parslet
+    before(:each) do
+      @parslet = match('[a]').repeat(3)
+    end
+    
+    context "when failing on input 'aa'" do
+      let!(:cause) {
+        catch_failed_parse { parslet.parse('aa') }
+      }
+      it "should have a relevant cause" do
+        cause.to_s.should == "Expected at least 3 of [a] at line 1 char 1."
+      end 
+      it "should have a tree with 2 nodes" do
+        cause.children.should have(1).elements
+      end 
+    end
+    it "should succeed on 'aaa'" do
+      parslet.parse('aaa')
+    end 
+    it "should succeed on many 'a'" do
+      parslet.parse('a'*100)
+    end 
+    it "should inspect as [a]{3, }" do
+      parslet.inspect.should == "[a]{3, }"
+    end
+  end
+  describe "str('foo')" do
+    attr_reader :parslet
+    before(:each) do
+      @parslet = str('foo')
+    end
+    
+    it "should parse 'foo'" do
+      parslet.parse('foo')
+    end
+    it "should not parse 'bar'"  do
+      cause = catch_failed_parse { parslet.parse('bar') }
+      cause.to_s.should == 
+        "Expected \"foo\", but got \"bar\" at line 1 char 1."
+    end
+    it "should inspect as 'foo'" do
+      parslet.inspect.should == "'foo'"
+    end 
+  end
+  describe "str('foo').maybe" do
+    let(:parslet) { str('foo').maybe }
+
+    it "should parse a foo" do
+      parslet.parse('foo')
+    end
+    it "should leave pos untouched if there is no foo" do
+      source = src('bar')
+      parslet.apply(source, context)
+      source.pos.should == 0
+    end
+    it "should inspect as 'foo'?" do
+      parslet.inspect.should == "'foo'?"
+    end 
+    context "when parsing 'foo'" do
+      subject { parslet.parse('foo') }
+      
+      it { should == 'foo' }
+    end
+    context "when parsing ''" do
+      subject { parslet.parse('') } 
+      
+      it { should == '' } 
+    end
+  end
+  describe "str('foo') >> str('bar')" do
+    let(:parslet) { str('foo') >> str('bar') }
+    
+    context "when it fails on input 'foobaz'" do
+      let!(:cause) {
+        catch_failed_parse { parslet.parse('foobaz') }
+      }
+
+      it "should not parse 'foobaz'" do
+        cause.to_s.should == "Failed to match sequence ('foo' 'bar') at line 1 char 4."
+      end
+      it "should have 2 nodes in error tree" do
+        cause.should have(1).children
+      end 
+    end
+    it "should parse 'foobar'" do
+      parslet.parse('foobar')
+    end
+    it "should inspect as ('foo' 'bar')" do
+      parslet.inspect.should == "'foo' 'bar'"
+    end 
+  end
+  describe "str('foo') | str('bar')" do
+    attr_reader :parslet
+    before(:each) do
+      @parslet = str('foo') | str('bar')
+    end
+    
+    context "when failing on input 'baz'" do
+      let!(:cause) {
+        catch_failed_parse { parslet.parse('baz') }
+      }
+
+      it "should have a sensible cause" do
+        cause.to_s.should == "Expected one of ['foo', 'bar'] at line 1 char 1."
+      end   
+      it "should have an error tree with 3 nodes" do
+        cause.should have(2).children
+      end 
+    end
+    
+    it "should accept 'foo'" do
+      parslet.parse('foo')
+    end
+    it "should accept 'bar'" do
+      parslet.parse('bar')
+    end
+    it "should inspect as ('foo' / 'bar')" do
+      parslet.inspect.should == "'foo' / 'bar'"
+    end 
+  end
+  describe "str('foo').present? (positive lookahead)" do
+    attr_reader :parslet
+    before(:each) do
+      @parslet = str('foo').present?
+    end
+    
+    it "should inspect as &'foo'" do
+      parslet.inspect.should == "&'foo'"
+    end 
+    context "when fed 'foo'" do
+      it "should parse" do
+        success, _ = parslet.apply(src('foo'), context)
+        success.should == true
+      end
+      it "should not change input position" do
+        source = src('foo')
+        parslet.apply(source, context)
+        source.pos.should == 0
+      end
+    end
+    context "when fed 'bar'" do
+      it "should not parse" do
+        lambda { parslet.parse('bar') }.should not_parse
+      end
+    end
+    describe "<- #parse" do
+      it "should return nil" do
+        parslet.apply(src('foo'), context).should == [true, nil]
+      end 
+    end
+  end
+  describe "str('foo').absent? (negative lookahead)" do
+    attr_reader :parslet
+    before(:each) do
+      @parslet = str('foo').absent?
+    end
+    
+    it "should inspect as !'foo'" do
+      parslet.inspect.should == "!'foo'"
+    end 
+    context "when fed 'bar'" do
+      it "should parse" do
+        parslet.apply(src('bar'), context).should == [true, nil]
+      end
+      it "should not change input position" do
+        source = src('bar')
+        parslet.apply(source, context)
+        source.pos.should == 0
+      end
+    end
+    context "when fed 'foo'" do
+      it "should not parse" do
+        lambda { parslet.parse('foo') }.should not_parse
+      end
+    end
+  end
+  describe "non greedy matcher combined with greedy matcher (possible loop)" do
+    attr_reader :parslet
+    before(:each) do
+      # repeat will always succeed, since it has a minimum of 0. It will not
+      # modify input position in that case. absent? will, depending on
+      # implementation, match as much as possible and call its inner element
+      # again. This leads to an infinite loop. This example tests for the 
+      # absence of that loop. 
+      @parslet = str('foo').repeat.maybe
+    end
+    
+    it "should not loop infinitely" do
+      lambda {
+        timeout(1) { parslet.parse('bar') }
+      }.should raise_error(Parslet::ParseFailed)
+    end 
+  end
+  describe "any" do
+    attr_reader :parslet
+    before(:each) do
+      @parslet = any
+    end
+    
+    it "should match" do
+      parslet.parse('.')
+    end 
+    it "should consume one char" do
+      source = src('foo')
+      parslet.apply(source, context)
+      source.pos.should == 1
+    end 
+  end
+  describe "eof behaviour" do
+    context "when the pattern just doesn't consume the input" do
+      let (:parslet) { any }
+
+      it "should fail the parse" do
+        cause = catch_failed_parse { parslet.parse('..') }
+        cause.to_s.should == "Don't know what to do with \".\" at line 1 char 2."
+      end 
+    end
+    context "when the pattern doesn't match the input" do
+      let (:parslet) { (str('a')).repeat(1) }
+      attr_reader :exception
+      before(:each) do
+        begin 
+          parslet.parse('a.')
+        rescue => @exception
+        end
+      end
+
+      it "raises Parslet::ParseFailed" do
+        # ParseFailed here, because the input doesn't match the parser grammar. 
+        exception.should be_kind_of(Parslet::ParseFailed)
+      end 
+      it "has the correct error message" do
+        exception.message.should == \
+          "Extra input after last repetition at line 1 char 2."
+      end 
+    end
+  end
+  
+  describe "<- #as(name)" do
+    context "str('foo').as(:bar)" do
+      it "should return :bar => 'foo'" do
+        str('foo').as(:bar).parse('foo').should == { :bar => 'foo' }
+      end 
+    end
+    context "match('[abc]').as(:name)" do
+      it "should return :name => 'b'" do
+        match('[abc]').as(:name).parse('b').should == { :name => 'b' }
+      end 
+    end
+    context "match('[abc]').repeat.as(:name)" do
+      it "should return collated result ('abc')" do
+        match('[abc]').repeat.as(:name).
+          parse('abc').should == { :name => 'abc' }
+      end
+    end
+    context "(str('a').as(:a) >> str('b').as(:b)).as(:c)" do
+      it "should return a hash of hashes" do
+        (str('a').as(:a) >> str('b').as(:b)).as(:c).
+          parse('ab').should == {
+            :c => {
+              :a => 'a', 
+              :b => 'b'
+            }
+          }
+      end 
+    end
+    context "(str('a').as(:a) >> str('ignore') >> str('b').as(:b))" do
+      it "should correctly flatten (leaving out 'ignore')" do
+        (str('a').as(:a) >> str('ignore') >> str('b').as(:b)).
+          parse('aignoreb').should == 
+          {
+            :a => 'a', 
+            :b => 'b'
+          }
+      end
+    end
+    
+    context "(str('a') >> str('ignore') >> str('b')) (no .as(...))" do
+      it "should return simply the original string" do
+        (str('a') >> str('ignore') >> str('b')).
+          parse('aignoreb').should == 'aignoreb'
+      end 
+    end
+    context "str('a').as(:a) >> str('b').as(:a)" do
+      attr_reader :parslet
+      before(:each) do
+        @parslet = str('a').as(:a) >> str('b').as(:a)
+      end
+      
+      it "should issue a warning that a key is being overwritten in merge" do
+        flexmock(parslet).
+          should_receive(:warn).once
+        parslet.parse('ab').should == { :a => 'b' }
+      end
+      it "should return :a => 'b'" do
+        flexmock(parslet).
+          should_receive(:warn)
+          
+        parslet.parse('ab').should == { :a => 'b' }
+      end  
+    end
+    context "str('a').absent?" do
+      it "should return something in merge, even though it is nil" do
+        (str('a').absent? >> str('b').as(:b)).
+          parse('b').should == {:b => 'b'}
+      end
+    end
+    context "str('a').as(:a).repeat" do
+      it "should return an array of subtrees" do
+        str('a').as(:a).repeat.
+          parse('aa').should == [{:a=>'a'}, {:a=>'a'}]
+      end 
+    end
+  end
+  describe "<- #flatten(val)" do
+    def call(val)
+      dummy = str('a')
+      flexmock(dummy, :warn => nil)
+      dummy.flatten(val)
+    end
+    
+    [
+      # In absence of named subtrees: ----------------------------------------
+      # Sequence or Repetition
+      [ [:sequence, 'a', 'b'], 'ab' ], 
+      [ [:repetition, 'a', 'a'], 'aa' ],
+            
+      # Nested inside another node
+      [ [:sequence, [:sequence, 'a', 'b']], 'ab' ],
+      # Combined with lookahead (nil)
+      [ [:sequence, nil, 'a'], 'a' ],
+                  
+      # Including named subtrees ---------------------------------------------
+      # Atom: A named subtree
+      [ {:a=>'a'}, {:a=>'a'} ],
+      # Composition of subtrees
+      [ [:sequence, {:a=>'a'},{:b=>'b'}], {:a=>'a',:b=>'b'} ],
+      # Mixed subtrees :sequence of :repetition yields []
+      [ [:sequence, [:repetition, {:a => 'a'}], {:a => 'a'} ], [{:a=>'a'}, {:a=>'a'}]],
+      [ [:sequence, {:a => 'a'},[:repetition, {:a => 'a'}] ], [{:a=>'a'}, {:a=>'a'}]],
+      [ [:sequence, [:repetition, {:a => 'a'}],[:repetition, {:a => 'a'}] ], [{:a=>'a'}, {:a=>'a'}]],
+      # Repetition
+      [ [:repetition, [:repetition, {:a=>'a'}], [:repetition, {:a=>'a'}]], 
+        [{:a => 'a'}, {:a => 'a'}]],
+      [ [:repetition, {:a=>'a'}, 'a', {:a=>'a'}], [{:a=>'a'}, {:a=>'a'}]],
+      [ [:repetition, {:a=>'a'}, [:repetition, {:b=>'b'}]], [{:a=>'a'}] ],
+      
+      # Some random samples --------------------------------------------------
+      [ [:sequence, {:a => :b, :b => :c}], {:a=>:b, :b=>:c} ], 
+      [ [:sequence, {:a => :b}, 'a', {:c=>:d}], {:a => :b, :c=>:d} ], 
+      [ [:repetition, {:a => :b}, 'a', {:c=>:d}], [{:a => :b}, {:c=>:d}] ], 
+      [ [:sequence, {:a => :b}, {:a=>:d}], {:a => :d} ], 
+      [ [:sequence, {:a=>:b}, [:sequence, [:sequence, "\n", nil]]], {:a=>:b} ], 
+      [ [:sequence, nil, " "], ' ' ], 
+    ].each do |input, output|
+      it "should transform #{input.inspect} to #{output.inspect}" do
+        call(input).should == output
+      end
+    end
+  end
+
+  describe "combinations thereof (regression)" do
+    success=[
+      [(str('a').repeat >> str('b').repeat), 'aaabbb'] 
+    ].each do |(parslet, input)|
+      describe "#{parslet.inspect} applied to #{input.inspect}" do
+        it "should parse successfully" do
+          parslet.parse(input)
+        end
+      end 
+    end
+
+    inspection=[
+      [str('a'),                              "'a'"                 ], 
+      [(str('a') | str('b')).maybe,           "('a' / 'b')?"        ], 
+      [(str('a') >> str('b')).maybe,          "('a' 'b')?"          ], 
+      [str('a').maybe.maybe,                  "'a'??"               ], 
+      [(str('a')>>str('b')).maybe.maybe,      "('a' 'b')??"         ], 
+      [(str('a') >> (str('b') | str('c'))),   "'a' ('b' / 'c')"], 
+      
+      [str('a') >> str('b').repeat,           "'a' 'b'{0, }"        ], 
+      [(str('a')>>str('b')).repeat,           "('a' 'b'){0, }"      ]  
+    ].each do |(parslet, inspect_output)|
+      context "regression for #{parslet.inspect}" do
+        it "should inspect correctly as #{inspect_output}" do
+          parslet.inspect.should == inspect_output
+        end 
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/convenience_spec.rb b/app/server/vendor/parslet/spec/parslet/convenience_spec.rb
new file mode 100755
index 0000000..8ba95ec
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/convenience_spec.rb
@@ -0,0 +1,48 @@
+require 'spec_helper'
+
+describe 'parslet/convenience' do
+  require 'parslet/convenience'
+  include Parslet
+  
+  class FooParser < Parslet::Parser
+    rule(:foo) { str('foo') }
+    root(:foo)
+  end
+  
+  describe 'parse_with_debug' do
+    let(:parser) { flexmock FooParser.new }
+    context 'internal' do
+      before(:each) do
+        # Suppress output.
+        #
+        parser.should_receive(:puts)
+      end
+      it 'should exist' do
+        lambda { parser.parse_with_debug('anything') }.should_not raise_error
+      end
+      it 'should catch ParseFailed exceptions' do
+        lambda { parser.parse_with_debug('bar') }.should_not raise_error
+      end
+      it 'should parse correct input like #parse' do
+        lambda { parser.parse_with_debug('foo') }.should_not raise_error
+      end
+    end
+    context 'output' do
+      it 'should puts once for tree output' do
+        parser.should_receive(:puts).once
+        
+        parser.parse_with_debug('incorrect')
+      end
+      it "should puts once for the error on unconsumed input" do
+        parser.should_receive(:puts).once
+
+        parser.parse_with_debug('foobar')
+      end 
+    end
+    
+    it "should work for all parslets" do
+      str('foo').parse_with_debug('foo')
+      match['bar'].parse_with_debug('a')
+    end 
+  end
+end
diff --git a/app/server/vendor/parslet/spec/parslet/error_reporter/deepest_spec.rb b/app/server/vendor/parslet/spec/parslet/error_reporter/deepest_spec.rb
new file mode 100755
index 0000000..e3000f0
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/error_reporter/deepest_spec.rb
@@ -0,0 +1,73 @@
+require 'spec_helper'
+
+describe Parslet::ErrorReporter::Deepest do
+  let(:reporter) { described_class.new }
+  let(:fake_source) { flexmock('source') }
+  
+  describe '#err' do
+    before(:each) { fake_source.should_receive(
+      :pos => 13, 
+      :line_and_column => [1,1]) }
+    
+    it "returns the deepest cause" do
+      flexmock(reporter).
+        should_receive(:deepest).and_return(:deepest)
+      reporter.err('parslet', fake_source, 'message').
+        should == :deepest
+    end 
+  end
+  describe '#err_at' do
+    before(:each) { fake_source.should_receive(
+      :pos => 13, 
+      :line_and_column => [1,1]) }
+
+    it "returns the deepest cause" do
+      flexmock(reporter).
+        should_receive(:deepest).and_return(:deepest)
+      reporter.err('parslet', fake_source, 'message', 13).
+        should == :deepest
+    end
+  end
+  describe '#deepest(cause)' do
+    def fake_cause(pos=13, children=nil)
+      flexmock('cause' + pos.to_s, :pos => pos, :children => children)
+    end
+    
+    context "when there is no deepest cause yet" do
+      let(:cause) { fake_cause }
+      it "returns the given cause" do
+        reporter.deepest(cause).should == cause
+      end
+    end
+    context "when the previous cause is deeper (no relationship)" do
+      let(:previous) { fake_cause }
+      before(:each) { 
+        reporter.deepest(previous) }
+      
+      it "returns the previous cause" do
+        reporter.deepest(fake_cause(12)).
+          should == previous
+      end 
+    end
+    context "when the previous cause is deeper (child)" do
+      let(:previous) { fake_cause }
+      before(:each) { 
+        reporter.deepest(previous) }
+        
+      it "returns the given cause" do
+        given = fake_cause(12, [previous])
+        reporter.deepest(given).should == given
+      end 
+    end
+    context "when the previous cause is shallower" do
+      before(:each) { 
+        reporter.deepest(fake_cause) }
+      
+      it "stores the cause as deepest" do
+        deeper = fake_cause(14)
+        reporter.deepest(deeper)
+        reporter.deepest_cause.should == deeper
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/error_reporter/tree_spec.rb b/app/server/vendor/parslet/spec/parslet/error_reporter/tree_spec.rb
new file mode 100755
index 0000000..a8b08ab
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/error_reporter/tree_spec.rb
@@ -0,0 +1,7 @@
+require 'spec_helper'
+
+require 'parslet/error_reporter'
+
+describe Parslet::ErrorReporter::Tree do
+  
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/export_spec.rb b/app/server/vendor/parslet/spec/parslet/export_spec.rb
new file mode 100755
index 0000000..8f12152
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/export_spec.rb
@@ -0,0 +1,67 @@
+require 'spec_helper'
+
+describe Parslet::Parser, "exporting to other lingos" do
+  class MiniLisp < Parslet::Parser
+    root :expression
+    rule(:expression) {
+      space? >> str('(') >> space? >> body >> str(')')
+    }
+    
+    rule(:body) {
+      (expression | identifier | float | integer | string).repeat.as(:exp)
+    }
+    
+    rule(:space) {
+      match('\s').repeat(1)
+    }
+    rule(:space?) {
+      space.maybe
+    }
+    
+    rule(:identifier) { 
+      (match('[a-zA-Z=*]') >> match('[a-zA-Z=*_]').repeat).as(:identifier) >> space?
+    }
+    
+    rule(:float) { 
+      (
+        integer >> (
+          str('.') >> match('[0-9]').repeat(1) |
+          str('e') >> match('[0-9]').repeat(1)
+        ).as(:e)
+      ).as(:float) >> space?
+    }
+    
+    rule(:integer) {
+      ((str('+') | str('-')).maybe >> match("[0-9]").repeat(1)).as(:integer) >> space?
+    }
+    
+    rule(:string) {
+      str('"') >> (
+        str('\\') >> any |
+        str('"').absent? >> any 
+      ).repeat.as(:string) >> str('"') >> space?
+    }
+  end
+
+  # I only update the files once I've verified the new syntax to work with 
+  # the respective tools. This is more an acceptance test than a real spec. 
+
+  describe "<- #to_citrus" do
+    let(:citrus) { File.read(
+      File.join(File.dirname(__FILE__), 'minilisp.citrus'))
+    }
+    it "should be valid citrus syntax" do
+      # puts MiniLisp.new.to_citrus
+      MiniLisp.new.to_citrus.should == citrus 
+    end 
+  end
+  describe "<- #to_treetop" do
+    let(:treetop) { File.read(
+      File.join(File.dirname(__FILE__), 'minilisp.tt'))
+    }
+    it "should be valid treetop syntax" do
+      # puts MiniLisp.new.to_treetop
+      MiniLisp.new.to_treetop.should == treetop
+    end 
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/expression/treetop_spec.rb b/app/server/vendor/parslet/spec/parslet/expression/treetop_spec.rb
new file mode 100755
index 0000000..0c0340f
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/expression/treetop_spec.rb
@@ -0,0 +1,74 @@
+require 'spec_helper'
+
+require 'parslet'
+
+describe Parslet::Expression::Treetop do
+  include Parslet
+
+  describe "positive samples" do
+    [ # pattern             # input
+      "'abc'",              'abc', 
+      "...",                'abc', 
+      "[1-4]",              '3',
+      
+      "'abc'?",             'abc', 
+      "'abc'?",             '', 
+      
+      "('abc')",            'abc', 
+      
+      "'a' 'b'",            'ab', 
+      "'a' ('b')",          'ab', 
+      
+      "'a' / 'b'",          'a', 
+      "'a' / 'b'",          'b', 
+      
+      "'a'*",               'aaa', 
+      "'a'*",               '', 
+
+      "'a'+",               'aa', 
+      "'a'+",               'a', 
+      
+      "'a'{1,2}",           'a',
+      "'a'{1,2}",           'aa',
+
+      "'a'{1,}",            'a',
+      "'a'{1,}",            'aa',
+
+      "'a'{,2}",            '',
+      "'a'{,2}",            'a',
+      "'a'{,2}",            'aa',
+    ].each_slice(2) do |pattern, input|
+      context "exp(#{pattern.inspect})" do
+        let(:parslet) { exp(pattern) }
+        subject { parslet }
+        it { should parse(input) }
+        context "string representation" do
+          subject { exp(parslet.to_s) }
+          it { should parse(input, :trace => true) }
+        end
+      end
+    end
+  end
+  describe "negative samples" do
+    [ # pattern             # input
+      "'abc'",              'cba', 
+      "[1-4]",              '5',
+      
+      "'a' / 'b'",          'c', 
+      
+      "'a'+",               '',
+      
+      "'a'{1,2}",           '',
+      "'a'{1,2}",           'aaa',
+      
+      "'a'{1,}",            '',
+
+      "'a'{,2}",            'aaa',
+    ].each_slice(2) do |pattern, input|
+      context "exp(#{pattern.inspect})" do
+        subject { exp(pattern) }
+        it { should_not parse(input) }
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/minilisp.citrus b/app/server/vendor/parslet/spec/parslet/minilisp.citrus
new file mode 100755
index 0000000..fea3d2e
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/minilisp.citrus
@@ -0,0 +1,29 @@
+grammar MiniLisp
+  rule root
+    (expression)
+  end
+  rule expression
+    ((space_p) "(" (space_p) (body) ")")
+  end
+  rule space_p
+    (space)0*1
+  end
+  rule body
+    ((expression) | (identifier) | (float) | (integer) | (string))0*
+  end
+  rule space
+    \s1*
+  end
+  rule identifier
+    (([a-zA-Z=*] [a-zA-Z=*_]0*) (space_p))
+  end
+  rule float
+    (((integer) (("." [0-9]1*) | ("e" [0-9]1*))) (space_p))
+  end
+  rule integer
+    ((("+" | "-")0*1 [0-9]1*) (space_p))
+  end
+  rule string
+    ("\"" (("\\" .) | (!"\"" .))0* "\"" (space_p))
+  end
+end
diff --git a/app/server/vendor/parslet/spec/parslet/minilisp.tt b/app/server/vendor/parslet/spec/parslet/minilisp.tt
new file mode 100755
index 0000000..e0ada6d
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/minilisp.tt
@@ -0,0 +1,29 @@
+grammar MiniLisp
+  rule root
+    (expression)
+  end
+  rule expression
+    ((space_p) "(" (space_p) (body) ")")
+  end
+  rule space_p
+    (space)0..1
+  end
+  rule body
+    ((expression) / (identifier) / (float) / (integer) / (string))0..
+  end
+  rule space
+    \s1..
+  end
+  rule identifier
+    (([a-zA-Z=*] [a-zA-Z=*_]0..) (space_p))
+  end
+  rule float
+    (((integer) (("." [0-9]1..) / ("e" [0-9]1..))) (space_p))
+  end
+  rule integer
+    ((("+" / "-")0..1 [0-9]1..) (space_p))
+  end
+  rule string
+    ("\"" (("\\" .) / (!"\"" .))0.. "\"" (space_p))
+  end
+end
diff --git a/app/server/vendor/parslet/spec/parslet/parser_spec.rb b/app/server/vendor/parslet/spec/parslet/parser_spec.rb
new file mode 100755
index 0000000..c7e67b8
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/parser_spec.rb
@@ -0,0 +1,31 @@
+require 'spec_helper'
+
+describe Parslet::Parser do
+  include Parslet
+  class FooParser < Parslet::Parser
+    rule(:foo) { str('foo') }
+    root(:foo)
+  end
+  
+  describe "<- .root" do
+    parser = Class.new(Parslet::Parser)
+    parser.root :root_parslet
+    
+    it "should have defined a 'root' method, returning the root" do
+      parser_instance = parser.new
+      flexmock(parser_instance).should_receive(:root_parslet => :answer)
+      
+      parser_instance.root.should == :answer
+    end 
+  end
+  it "should parse 'foo'" do
+    FooParser.new.parse('foo').should == 'foo'
+  end 
+  context "composition" do
+    let(:parser) { FooParser.new }
+    it "should allow concatenation" do
+      composite = parser >> str('bar')
+      composite.should parse('foobar')
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/parslet_spec.rb b/app/server/vendor/parslet/spec/parslet/parslet_spec.rb
new file mode 100755
index 0000000..aea9ec4
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/parslet_spec.rb
@@ -0,0 +1,38 @@
+require 'spec_helper'
+
+describe Parslet do
+  include Parslet
+  
+  describe Parslet::ParseFailed do
+    it "should be caught by an empty rescue" do
+      begin
+        raise Parslet::ParseFailed
+      rescue
+        # Success! Ignore this.
+      end
+    end 
+  end
+  describe "<- .rule" do
+    # Rules define methods. This can be easily tested by defining them right 
+    # here. 
+    context "empty rule" do
+      rule(:empty) { }
+      
+      it "should raise a NotImplementedError" do
+        lambda {
+          empty.parslet
+        }.should raise_error(NotImplementedError)
+      end 
+    end
+    
+    context "containing 'any'" do
+      rule(:any_rule) { any }
+      subject { any_rule }
+      
+      it { should be_a Parslet::Atoms::Entity }
+      it "should memoize the returned instance" do
+        any_rule.object_id.should == any_rule.object_id
+      end 
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/pattern_spec.rb b/app/server/vendor/parslet/spec/parslet/pattern_spec.rb
new file mode 100755
index 0000000..2b4756f
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/pattern_spec.rb
@@ -0,0 +1,268 @@
+require 'spec_helper'
+
+require 'parslet'
+
+describe Parslet::Pattern do
+  include Parslet
+  
+  # These two factory methods help make the specs more robust to interface
+  # changes. They also help to label trees (t) and patterns (p).
+  def p(pattern)
+    Parslet::Pattern.new(pattern)
+  end
+  def t(obj)
+    obj
+  end
+  
+  # Tries to match pattern to the tree, and verifies the bindings hash. Don't
+  # use this for new examples.
+  #
+  RSpec::Matchers.define :match_with_bind do |pattern, exp_bindings|
+    failure_message_for_should do |tree|
+      "expected #{pattern.inspect} to match #{tree.inspect}, but didn't. (block wasn't called or not correctly)"
+    end
+    match do |tree|
+      bindings = Parslet::Pattern.new(pattern).match(tree)
+      bindings && bindings == exp_bindings
+    end
+  end
+
+  # This is the more modern version of verifying a match: (uses 'exp'
+  # implicitly). Checks for a match of pattern in +exp+ and yields the
+  # matched variables.
+  #
+  def with_match_locals(pattern, &block) 
+    bindings = p(pattern).match(exp)
+    bindings.should_not be_nil
+    
+    block.call(bindings) if block
+  end
+  
+  # Can't use #match here, so I went to the Thesaurus.
+  #
+  RSpec::Matchers.define :detect do |pattern|
+    match do |tree|
+      bindings = Parslet::Pattern.new(pattern).match(tree)
+
+      bindings ? true : false
+    end
+  end
+  
+  describe "<- #match" do
+    context "injecting bindings" do
+      let(:pattern) { p(simple(:x)) }
+      
+      it "should not modify the original bindings hash" do
+        h = {}
+        b=pattern.match('a', h)
+        h.size.should == 0
+        b.size.should == 1
+      end
+      it "should return nil when no match succeeds" do
+        pattern.match([], :foo => :bar).should be_nil
+      end
+      context "when matching simple(:x) against 'a'" do
+        let(:bindings) { pattern.match(t('a'), :foo => :bar) }
+        
+        before(:each) { bindings.should_not be_nil }
+        it "should return the injected bindings" do
+          bindings[:foo].should == :bar
+        end
+        it "should return the new bindings" do  
+          bindings[:x].should == 'a'
+        end
+      end
+    end
+    context "simple strings" do
+      let(:exp) { 'aaaa' }
+
+      it "should match simple strings" do
+        exp.should match_with_bind(simple(:x), :x => 'aaaa')
+      end 
+    end
+    context "simple hash {:a => 'b'}" do
+      attr_reader :exp
+      before(:each) do
+        @exp = t(:a => 'b')
+      end
+
+      it "should not match {:a => simple(:x), :b => simple(:y)}" do
+        exp.should_not detect(:a => simple(:x), :b => simple(:y))
+      end
+      it "should match {:a => simple(:x)}, binding 'x' to the first argument" do
+        exp.should match_with_bind({:a => simple(:x)}, :x => 'b')
+      end 
+      it "should match {:a => 'b'} with no binds" do
+        exp.should match_with_bind({:a => 'b'}, {})
+      end 
+    end
+    context "a more complex hash {:a => {:b => 'c'}}" do
+      attr_reader :exp
+      before(:each) do
+        @exp = t(:a => {:b => 'c'})
+      end
+      
+      it "should match wholly with {:a => {:b => simple(:x)}}" do
+        exp.should match_with_bind({:a => {:b => simple(:x)}}, :x => 'c')
+      end
+      it "should match wholly with {:a => subtree(:t)}" do
+        with_match_locals(:a => subtree(:t)) do |dict|
+          dict[:t].should == {:b => 'c'}
+        end
+      end
+      it "should not bind subtrees to variables in {:a => simple(:x)}" do
+        p(:a => simple(:x)).should_not detect(exp)
+      end
+    end
+    context "a more complex hash {:a => 'a', :b => 'b'}" do
+      attr_reader :exp
+      before(:each) do
+        @exp = t({:a => 'a', :b => 'b'})
+      end
+
+      it "should not match partially" do
+        Parslet::Pattern.new(:a => simple(:x)).match(exp).should be_nil
+      end 
+      it "should match completely" do
+        exp.should match_with_bind({:a => simple(:x), :b => simple(:y)}, 
+          :x => 'a', 
+          :y => 'b')
+      end 
+    end
+    context "an array of 'a', 'b', 'c'" do
+      let(:exp) { ['a', 'b', 'c'] }
+
+      it "should match all elements at once" do
+        exp.should match_with_bind(
+          [simple(:x), simple(:y), simple(:z)], 
+          :x => 'a', :y => 'b', :z => 'c')
+      end 
+    end
+    context "{:a => 'a', :b => 'b'}" do
+      attr_reader :exp
+      before(:each) do
+        @exp = t(:a => 'a', :b => 'b')
+      end
+
+      it "should match both elements simple(:x), simple(:y)" do
+        exp.should match_with_bind(
+          {:a => simple(:x), :b => simple(:y)}, 
+          :x => 'a', :y => 'b')
+      end
+      it "should not match a constrained match (simple(:x) != simple(:y))"  do
+        exp.should_not detect({:a => simple(:x), :b => simple(:x)})
+      end
+    end
+    context "{:a => 'a', :b => 'a'}" do
+      attr_reader :exp
+      before(:each) do
+        @exp = t(:a => 'a', :b => 'a')
+      end
+
+      it "should match constrained pattern" do
+        exp.should match_with_bind(
+          {:a => simple(:x), :b => simple(:x)}, 
+          :x => 'a')
+      end
+    end
+    context "{:sub1 => {:a => 'a'}, :sub2 => {:a => 'a'}}" do
+      attr_reader :exp
+      before(:each) do
+        @exp = t({
+          :sub1 => {:a => 'a'}, 
+          :sub2 => {:a => 'a'} 
+        })
+      end
+
+      it "should verify constraints over several subtrees" do
+        exp.should match_with_bind({
+          :sub1 => {:a => simple(:x)}, 
+          :sub2 => {:a => simple(:x)} 
+        }, :x => 'a')
+      end
+      it "should return both bind variables simple(:x), simple(:y)" do
+        exp.should match_with_bind({
+          :sub1 => {:a => simple(:x)}, 
+          :sub2 => {:a => simple(:y)} 
+        }, :x => 'a', :y => 'a')
+      end  
+    end
+    context "{:sub1 => {:a => 'a'}, :sub2 => {:a => 'b'}}" do
+      attr_reader :exp
+      before(:each) do
+        @exp = t({
+          :sub1 => {:a => 'a'}, 
+          :sub2 => {:a => 'b'} 
+        })
+      end
+
+      it "should verify constraints over several subtrees" do
+        exp.should_not match_with_bind({
+          :sub1 => {:a => simple(:x)}, 
+          :sub2 => {:a => simple(:x)} 
+        }, :x => 'a')
+      end
+      it "should return both bind variables simple(:x), simple(:y)" do
+        exp.should match_with_bind({
+          :sub1 => {:a => simple(:x)}, 
+          :sub2 => {:a => simple(:y)} 
+        }, :x => 'a', :y => 'b')
+      end  
+    end
+    context "[{:a => 'x'}, {:a => 'y'}]" do
+      attr_reader :exp  
+      before(:each) do
+        @exp = t([{:a => 'x'}, {:a => 'y'}])
+      end
+      
+      it "should not match sequence(:x) (as a whole)" do
+        exp.should_not detect(sequence(:x))
+      end
+    end
+    context "['x', 'y', 'z']" do
+      attr_reader :exp  
+      before(:each) do
+        @exp = t(['x', 'y', 'z'])
+      end
+
+      it "should match [simple(:x), simple(:y), simple(:z)]" do
+        with_match_locals([simple(:x), simple(:y), simple(:z)]) do |dict|
+          dict[:x].should == 'x'
+          dict[:y].should == 'y'
+          dict[:z].should == 'z'
+        end
+      end
+      it "should match %w(x y z)" do
+        exp.should match_with_bind(%w(x y z), { })
+      end 
+      it "should not match [simple(:x), simple(:y), simple(:x)]" do
+        exp.should_not detect([simple(:x), simple(:y), simple(:x)])
+      end
+      it "should not match [simple(:x), simple(:y)]" do
+        exp.should_not detect([simple(:x), simple(:y), simple(:x)])
+      end
+      it "should match sequence(:x) (as array)" do
+        exp.should match_with_bind(sequence(:x), :x => ['x', 'y', 'z'])
+      end
+    end
+    context "{:a => [1,2,3]}" do
+      attr_reader :exp  
+      before(:each) do
+        @exp = t(:a => [1,2,3])
+      end
+
+      it "should match :a => sequence(:x) (binding x to the whole array)" do
+        exp.should match_with_bind({:a => sequence(:x)}, {:x => [1,2,3]})
+      end
+    end
+    context "with differently ordered hashes" do
+      it "should still match" do
+        t(:a => 'a', :b => 'b').should detect(:a => 'a', :b => 'b')
+        t(:a => 'a', :b => 'b').should detect(:b => 'b', :a => 'a')
+
+        t(:b => 'b', :a => 'a').should detect(:b => 'b', :a => 'a')
+        t(:b => 'b', :a => 'a').should detect(:a => 'a', :b => 'b')
+      end 
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/rig/rspec_spec.rb b/app/server/vendor/parslet/spec/parslet/rig/rspec_spec.rb
new file mode 100755
index 0000000..3e78449
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/rig/rspec_spec.rb
@@ -0,0 +1,35 @@
+require 'spec_helper'
+require 'parslet/rig/rspec'
+
+describe 'rspec integration' do
+  include Parslet
+  subject { str('example') }
+
+  it { should parse('example') }
+  it { should_not parse('foo') }
+  it { should parse('example').as('example') }
+  it { should_not parse('foo').as('example') }
+  it { should_not parse('example').as('foo') }
+
+  it { str('foo').as(:bar).should parse('foo').as({:bar => 'foo'}) }
+  it { str('foo').as(:bar).should_not parse('foo').as({:b => 'f'}) }
+
+  it 'accepts a block to assert more specific details about the parsing output' do
+    str('foo').as(:bar).should(parse('foo').as { |output|
+      output.should have_key(:bar)
+      output.values.first.should == 'foo'
+    })
+  end
+
+  # Uncomment to test error messages manually: 
+  # it { str('foo').should parse('foo', :trace => true).as('bar') }
+  # it { str('foo').should parse('food', :trace => true) }
+  # it { str('foo').should_not parse('foo', :trace => true).as('foo') }
+  # it { str('foo').should_not parse('foo', :trace => true) }
+  # it 'accepts a block to assert more specific details about the parsing output' do
+  #   str('foo').as(:bar).should(parse('foo', :trace => true).as { |output|
+  #     output.should_not have_key(:bar)
+  #   })
+  # end
+  
+end
diff --git a/app/server/vendor/parslet/spec/parslet/scope_spec.rb b/app/server/vendor/parslet/spec/parslet/scope_spec.rb
new file mode 100755
index 0000000..398c3be
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/scope_spec.rb
@@ -0,0 +1,45 @@
+require 'spec_helper'
+
+describe Parslet::Scope do
+  let(:scope) { described_class.new }
+  
+  describe 'simple store/retrieve' do
+    before(:each) { scope[:foo] = :bar }
+    it "allows storing objects" do
+      scope[:obj] = 42
+    end 
+    it "raises on access of empty slots" do
+      expect {
+        scope[:empty]
+      }.to raise_error(Parslet::Scope::NotFound)
+    end 
+    it "allows retrieval of stored values" do
+      scope[:foo].should == :bar
+    end 
+  end
+  
+  describe 'scoping' do
+    before(:each) { scope[:depth] = 1 }
+    before(:each) { scope.push }
+    
+    let(:depth) { scope[:depth] }
+    subject { depth }
+    
+    it { should == 1 }
+    describe 'after a push' do
+      before(:each) { scope.push }
+      it { should == 1 }
+      
+      describe 'and reassign' do
+        before(:each) { scope[:depth] = 2 }
+        
+        it { should == 2 }
+
+        describe 'and a pop' do
+          before(:each) { scope.pop }
+          it { should == 1 }
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/slice_spec.rb b/app/server/vendor/parslet/spec/parslet/slice_spec.rb
new file mode 100755
index 0000000..ef41d35
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/slice_spec.rb
@@ -0,0 +1,134 @@
+require 'spec_helper'
+
+describe Parslet::Slice do
+  describe "construction" do
+    it "should construct from an offset and a string" do
+      described_class.new('foobar', 40)
+    end
+  end
+  context "('foobar', 40)" do
+    let(:slice) { described_class.new('foobar', 40) }
+    describe "comparison" do
+      it "should be equal to other slices with the same attributes" do
+        other = described_class.new('foobar', 40)
+        slice.should == other
+        other.should == slice
+      end 
+      it "should be equal to other slices (offset is irrelevant for comparison)" do
+        other = described_class.new('foobar', 41)
+        slice.should == other
+        other.should == slice
+      end 
+      it "should be equal to a string with the same content" do
+        slice.should == 'foobar'
+      end
+      it "should be equal to a string (inversed operands)" do
+        'foobar'.should == slice
+      end 
+      it "should not be equal to a string" do
+        slice.should_not equal('foobar')
+      end 
+      it "should not be eql to a string" do
+        slice.should_not eql('foobar')
+      end 
+      it "should not hash to the same number" do
+        slice.hash.should_not == 'foobar'.hash
+      end 
+    end
+    describe "offset" do
+      it "should return the associated offset" do
+        slice.offset.should == 40
+      end
+      it "should fail to return a line and column" do
+        lambda {
+          slice.line_and_column
+        }.should raise_error(ArgumentError)
+      end 
+      
+      context "when constructed with a source" do
+        let(:slice) { described_class.new(
+          'foobar', 40,  
+          flexmock(:cache, :line_and_column => [13, 14])) }
+        it "should return proper line and column" do
+          slice.line_and_column.should == [13, 14]
+        end
+      end
+    end
+    describe "string methods" do
+      describe "matching" do
+        it "should match as a string would" do
+          slice.should match(/bar/)
+          slice.should match(/foo/)
+
+          md = slice.match(/f(o)o/)
+          md.captures.first.should == 'o'
+        end
+      end
+      describe "<- #size" do
+        subject { slice.size }
+        it { should == 6 } 
+      end
+      describe "<- #+" do
+        let(:other) { described_class.new('baz', 10) }
+        subject { slice + other }
+        
+        it "should concat like string does" do
+          subject.size.should == 9
+          subject.should == 'foobarbaz'
+          subject.offset.should == 40
+        end 
+      end
+    end
+    describe "conversion" do
+      describe "<- #to_slice" do
+        it "should return self" do
+          slice.to_slice.should eq(slice)
+        end 
+      end
+      describe "<- #to_sym" do
+        it "should return :foobar" do
+          slice.to_sym.should == :foobar
+        end 
+      end
+      describe "cast to Float" do
+        it "should return a float" do
+          Float(described_class.new('1.345', 11)).should == 1.345
+        end 
+      end
+      describe "cast to Integer" do
+        it "should cast to integer as a string would" do
+          s = described_class.new('1234', 40)
+          Integer(s).should == 1234
+          s.to_i.should == 1234
+        end 
+        it "should fail when Integer would fail on a string" do
+          lambda { Integer(slice) }.should raise_error
+        end 
+        it "should turn into zero when a string would" do
+          slice.to_i.should == 0
+        end 
+      end
+    end
+    describe "inspection and string conversion" do
+      describe "#inspect" do
+        subject { slice.inspect }
+        it { should == '"foobar"@40' }
+      end
+      describe "#to_s" do
+        subject { slice.to_s }
+        it { should == 'foobar' }
+      end
+    end
+    describe "serializability" do
+      it "should serialize" do
+        Marshal.dump(slice)
+      end
+      context "when storing a line cache" do
+        let(:slice) { described_class.new('foobar', 40, Parslet::Source::LineCache.new()) }
+        it "should serialize" do
+          Marshal.dump(slice)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/source/line_cache_spec.rb b/app/server/vendor/parslet/spec/parslet/source/line_cache_spec.rb
new file mode 100755
index 0000000..b1fa978
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/source/line_cache_spec.rb
@@ -0,0 +1,74 @@
+require 'spec_helper'
+
+describe Parslet::Source::RangeSearch do
+  describe "<- #lbound" do
+    context "for a simple array" do
+      let(:ary) { [10, 20, 30, 40, 50] }
+      before(:each) { ary.extend Parslet::Source::RangeSearch }
+
+      it "should return correct answers for numbers not in the array" do
+        ary.lbound(5).should == 0
+        ary.lbound(15).should == 1
+        ary.lbound(25).should == 2
+        ary.lbound(35).should == 3
+        ary.lbound(45).should == 4
+      end
+      it "should return correct answers for numbers in the array" do
+        ary.lbound(10).should == 1
+        ary.lbound(20).should == 2
+        ary.lbound(30).should == 3
+        ary.lbound(40).should == 4
+      end
+      it "should cover right edge case" do
+        ary.lbound(50).should be_nil
+        ary.lbound(51).should be_nil
+      end 
+      it "should cover left edge case" do
+        ary.lbound(0).should == 0
+      end
+    end
+    context "for an empty array" do
+      let(:ary) { [] }
+      before(:each) { ary.extend Parslet::Source::RangeSearch }
+
+      it "should return nil" do
+        ary.lbound(1).should be_nil
+      end 
+    end
+  end
+end
+
+describe Parslet::Source::LineCache do
+  describe "<- scan_for_line_endings" do
+    context "calculating the line_and_columns" do
+      let(:str) { "foo\nbar\nbazd" }
+
+      it "should return the first line if we have no line ends" do
+        subject.scan_for_line_endings(0, nil)
+        subject.line_and_column(3).should == [1, 4]
+
+        subject.scan_for_line_endings(0, "")
+        subject.line_and_column(5).should == [1, 6]
+      end
+
+      it "should find the right line starting from pos 0" do
+        subject.scan_for_line_endings(0, str)
+        subject.line_and_column(5).should == [2, 2]
+        subject.line_and_column(9).should == [3, 2]
+      end
+
+      it "should find the right line starting from pos 5" do
+        subject.scan_for_line_endings(5, str)
+        subject.line_and_column(11).should == [2, 3]
+      end
+
+      it "should find the right line if scannning the string multiple times" do
+        subject.scan_for_line_endings(0, str)
+        subject.scan_for_line_endings(0, "#{str}\nthe quick\nbrown fox")
+        subject.line_and_column(10).should == [3,3]
+        subject.line_and_column(24).should == [5,2]
+      end
+    end
+  end
+end
+
diff --git a/app/server/vendor/parslet/spec/parslet/source_spec.rb b/app/server/vendor/parslet/spec/parslet/source_spec.rb
new file mode 100755
index 0000000..00de23a
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/source_spec.rb
@@ -0,0 +1,165 @@
+# Encoding: UTF-8
+
+require 'spec_helper'
+
+describe Parslet::Source do
+  describe "using simple input" do
+    let(:str)     { "a"*100 + "\n" + "a"*100 + "\n" }
+    let(:source)  { described_class.new(str) }
+  
+    describe "<- #read(n)" do
+      it "should not raise error when the return value is nil" do
+        described_class.new('').consume(1)
+      end 
+      it "should return 100 'a's when reading 100 chars" do
+        source.consume(100).should == 'a'*100
+      end
+    end
+    describe "<- #chars_left" do
+      subject { source.chars_left }
+  
+      it { should == 202 }
+      context "after depleting the source" do
+        before(:each) { source.consume(10000) }
+  
+        it { should == 0 }
+      end
+    end
+    describe "<- #pos" do
+      subject { source.pos }
+  
+      it { should == 0 }
+      context "after reading a few bytes" do
+        it "should still be correct" do
+          pos = 0
+          10.times do
+            pos += (n = rand(10)+1)
+            source.consume(n)
+  
+            source.pos.should == pos
+          end
+        end 
+      end
+    end
+    describe "<- #pos=(n)" do
+      subject { source.pos }
+      10.times do
+        pos = rand(200)
+        context "setting position #{pos}" do
+          before(:each) { source.pos = pos }
+  
+          it { should == pos }
+        end
+      end
+    end
+    describe '#chars_until' do
+      it 'should return 100 chars before line end' do
+        source.chars_until("\n").should == 100
+      end
+    end
+    describe "<- #column & #line" do
+      subject { source.line_and_column }
+  
+      it { should == [1,1] }
+  
+      context "on the first line" do
+        it "should increase column with every read" do
+          10.times do |i|
+            source.line_and_column.last.should == 1+i
+            source.consume(1)
+          end
+        end 
+      end
+      context "on the second line" do
+        before(:each) { source.consume(101) }
+        it { should == [2, 1]}
+      end
+      context "after reading everything" do
+        before(:each) { source.consume(10000) }
+  
+        context "when seeking to 9" do
+          before(:each) { source.pos = 9 }
+          it { should == [1, 10] }
+        end
+        context "when seeking to 100" do
+          before(:each) { source.pos = 100 }
+          it { should == [1, 101] }
+        end
+        context "when seeking to 101" do
+          before(:each) { source.pos = 101 }
+          it { should == [2, 1] }
+        end
+        context "when seeking to 102" do
+          before(:each) { source.pos = 102 }
+          it { should == [2, 2] }
+        end
+        context "when seeking beyond eof" do
+          it "should not throw an error" do
+            source.pos = 1000
+          end 
+        end
+      end
+      context "reading char by char, storing the results" do
+        attr_reader :results
+        before(:each) { 
+          @results = {}
+          while source.chars_left>0
+            pos = source.pos
+            @results[pos] = source.line_and_column
+            source.consume(1)
+          end
+  
+          @results.should have(202).entries
+          @results
+        }
+  
+        context "when using pos argument" do
+          it "should return the same results" do
+            results.each do |pos, result|
+              source.line_and_column(pos).should == result
+            end
+          end 
+        end
+        it "should give the same results when seeking" do
+          results.each do |pos, result|
+            source.pos = pos
+            source.line_and_column.should == result
+          end
+        end
+        it "should give the same results when reading" do
+          cur = source.pos = 0
+          while source.chars_left>0
+            source.line_and_column.should == results[cur]
+            cur += 1
+            source.consume(1)
+          end
+        end 
+      end
+    end
+    
+  end
+  
+  describe "reading encoded input" do
+    let(:source) { described_class.new("éö変わる") }
+
+    def r str
+      Regexp.new(Regexp.escape(str))
+    end
+    
+    it "should read characters, not bytes" do
+      source.should match(r("é"))
+      source.consume(1)
+      source.pos.should == 2
+      
+      source.should match(r("ö"))
+      source.consume(1)
+      source.pos.should == 4
+      
+      source.should match(r("変"))
+      source.consume(1)
+      
+      source.consume(2)
+      source.chars_left.should == 0
+    end 
+  end
+end
diff --git a/app/server/vendor/parslet/spec/parslet/transform/context_spec.rb b/app/server/vendor/parslet/spec/parslet/transform/context_spec.rb
new file mode 100755
index 0000000..d6f6ddb
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/transform/context_spec.rb
@@ -0,0 +1,35 @@
+require 'spec_helper'
+
+describe Parslet::Context do
+  def context(*args)
+    described_class.new(*args)
+  end
+  
+  it "binds hash keys as variable like things" do
+    context(:a => 'value').instance_eval { a }.
+      should == 'value'
+  end
+  describe 'when a method in BlankSlate is inherited from the environment somehow' do
+    before(:each) { BlankSlate.send(:define_method, :a) { 'c' } }
+    after(:each) { BlankSlate.send(:undef_method, :a) }
+    
+    it "masks what is already on blank slate" do
+      context(:a => 'b').instance_eval { a }.
+        should == 'b'
+    end  
+  end
+  it "should not reveal define_singleton_method for all users of blankslate, just for us" do
+    expect {
+      BlankSlate.new.instance_eval {
+        define_singleton_method(:foo) { 'foo' }
+      }
+    }.to raise_error(NoMethodError)
+  end 
+  it "one contexts variables aren't the next ones" do
+    ca = context(:a => 'b')
+    cb = context(:b => 'c')
+
+    ca.methods.should_not include(:b)
+    cb.methods.should_not include(:a)
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/parslet/transform_spec.rb b/app/server/vendor/parslet/spec/parslet/transform_spec.rb
new file mode 100755
index 0000000..0a3af5a
--- /dev/null
+++ b/app/server/vendor/parslet/spec/parslet/transform_spec.rb
@@ -0,0 +1,144 @@
+require 'spec_helper'
+
+require 'parslet'
+
+describe Parslet::Transform do
+  include Parslet
+  
+  let(:transform) { Parslet::Transform.new }
+  attr_reader :transform
+  before(:each) do
+    @transform = Parslet::Transform.new
+  end
+  
+  class A < Struct.new(:elt); end
+  class B < Struct.new(:elt); end
+  class C < Struct.new(:elt); end
+  class Bi < Struct.new(:a, :b); end
+
+  describe "delayed construction" do
+    context "given simple(:x) => A.new(x)" do
+      before(:each) do
+        transform.rule(simple(:x)) { |d| A.new(d[:x]) }
+      end
+
+      it "should transform 'a' into A.new('a')" do
+        transform.apply('a').should == A.new('a')
+      end 
+      it "should transform ['a', 'b'] into [A.new('a'), A.new('b')]" do
+        transform.apply(['a', 'b']).should == 
+          [A.new('a'), A.new('b')]
+      end
+    end
+    context "given rules on {:a => simple(:x)} and {:b => :_x}" do
+      before(:each) do
+        transform.rule(:a => simple(:x)) { |d| A.new(d[:x]) }
+        transform.rule(:b => simple(:x)) { |d| B.new(d[:x]) }
+      end
+
+      it "should transform {:d=>{:b=>'c'}} into d => B('c')" do
+        transform.apply({:d=>{:b=>'c'}}).should == {:d => B.new('c')}
+      end
+      it "should transform {:a=>{:b=>'c'}} into A(B('c'))" do
+        transform.apply({:a=>{:b=>'c'}}).should == A.new(B.new('c'))
+      end
+    end
+    describe "pulling out subbranches" do
+      before(:each) do
+        transform.rule(:a => {:b => simple(:x)}, :d => {:e => simple(:y)}) { |d|
+          Bi.new(*d.values_at(:x, :y))
+        }
+      end
+
+      it "should yield Bi.new('c', 'f')" do
+        transform.apply(:a => {:b => 'c'}, :d => {:e => 'f'}).should ==
+          Bi.new('c', 'f')
+      end 
+    end
+  end
+  describe "dsl construction" do
+    let(:transform) { Parslet::Transform.new do
+        rule(simple(:x)) { A.new(x) }
+      end 
+    }
+    
+    it "should still evaluate rules correctly" do
+      transform.apply('a').should == A.new('a')
+    end 
+  end
+  describe "class construction" do
+    class OptimusPrime < Parslet::Transform 
+      rule(simple(:x)) { A.new(x) }
+    end
+    let(:transform) { OptimusPrime.new }
+    
+    it "should evaluate rules" do
+      transform.apply('a').should == A.new('a')
+    end 
+  end
+  describe "<- #call_on_match" do
+    let(:bindings) { { :foo => 'test' } }
+    context "when given a block of arity 1" do
+      it "should call the block" do
+        called = false
+        transform.call_on_match(bindings, lambda do |dict|
+          called = true
+        end)
+        
+        called.should == true
+      end 
+      it "should yield the bindings" do
+        transform.call_on_match(bindings, lambda do |dict|
+          dict.should == bindings
+        end)
+      end
+      it "should execute in the current context"  do
+        foo = 'test'
+        transform.call_on_match(bindings, lambda do |dict|
+          foo.should == 'test'
+        end)
+      end
+    end
+    context "when given a block of arity 0" do
+      it "should call the block" do
+        called = false
+        transform.call_on_match(bindings, proc do 
+          called = true
+        end)
+        
+        called.should == true
+      end 
+      it "should have bindings as local variables" do
+        transform.call_on_match(bindings, proc do
+          foo.should == 'test'
+        end)
+      end
+      it "should execute in its own context" do
+        @bar = 'test'
+        transform.call_on_match(bindings, proc do
+          @bar.should_not == 'test'
+        end)
+      end
+    end
+  end
+  
+  context "various transformations (regression)" do
+    context "hashes" do
+      it "are matched completely" do
+        transform.rule(:a => simple(:x)) { fail }
+        transform.apply(:a => 'a', :b => 'b')
+      end 
+    end
+  end
+  
+  context "when not using the bindings as hash, but as local variables" do
+    it "should access the variables" do
+      transform.rule(simple(:x)) { A.new(x) }
+      transform.apply('a').should == A.new('a')
+    end
+    it "should allow context as local variable" do
+      transform.rule(simple(:x)) { foo }
+      transform.apply('a', :foo => 'bar').should == 'bar'
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/spec/spec_helper.rb b/app/server/vendor/parslet/spec/spec_helper.rb
new file mode 100755
index 0000000..a2f1fc1
--- /dev/null
+++ b/app/server/vendor/parslet/spec/spec_helper.rb
@@ -0,0 +1,24 @@
+
+require 'parslet'
+
+require 'parslet/rig/rspec'
+require 'parslet/atoms/visitor'
+require 'parslet/export'
+
+RSpec.configure do |config|
+  config.mock_with :flexmock
+  
+  # Exclude other ruby versions by giving :ruby => 1.8 or :ruby => 1.9
+  #
+  config.filter_run_excluding :ruby => lambda { |version|
+    RUBY_VERSION.to_s !~ /^#{Regexp.escape(version.to_s)}/
+  }
+end
+
+def catch_failed_parse
+  begin
+    yield
+  rescue Parslet::ParseFailed => exception
+  end
+  exception.cause
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/Gemfile b/app/server/vendor/parslet/website/Gemfile
new file mode 100755
index 0000000..282847e
--- /dev/null
+++ b/app/server/vendor/parslet/website/Gemfile
@@ -0,0 +1,13 @@
+source "https://rubygems.org"
+
+gem "middleman"
+gem 'rb-fsevent'
+gem 'RedCloth'
+gem 'slim'
+
+gem 'cod'
+gem 'case'
+gem 'text-highlight'
+
+gem 'parslet'
+gem 'rspec'
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/README_website b/app/server/vendor/parslet/website/README_website
new file mode 100755
index 0000000..21ba7c0
--- /dev/null
+++ b/app/server/vendor/parslet/website/README_website
@@ -0,0 +1,9 @@
+Parslets website is built with middleman. Just do a 'bundle install' in this
+directory and you should be good to go. 'middleman server' will give you
+a development server. 
+
+Once you want to publish the website to github, you need to set the gh-pages
+branch to the build directory below this website directory. The script
+publish-gh-pages.sh will do this using a little black git magic. (Panic!)
+
+ 
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/build/contribute.html b/app/server/vendor/parslet/website/build/contribute.html
new file mode 100755
index 0000000..cd43592
--- /dev/null
+++ b/app/server/vendor/parslet/website/build/contribute.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta content="text/html;charset=UTF-8" http-equiv="Content-type" />
+    <title>parslet -Contribute</title>
+    <meta content="Kaspar Schiess (http://absurd.li)" name="author" />
+    <link href="images/favicon3.ico" rel="shortcut icon" /><link href="/parslet/stylesheets/site.css" media="screen" rel="stylesheet" type="text/css" /><link href="/parslet/stylesheets/sh_whitengrey.css" media="screen" rel="stylesheet" type="text/css" /><script src="/parslet/javascripts/sh_main.min.js" type="text/javascript"></script><script src="/parslet/javascripts/sh_ruby.min.js" type="text/javascript"></script></head>
+  <body class="code" onload="sh_highlightDocument();">
+    <div id="everything">
+      <div class="main_menu"><img alt="Parslet Logo" src="/parslet/images/parsley_logo.png" /><ul>
+          <li><a href="/parslet/">about</a></li>
+          <li><a href="/parslet/get-started.html">get started</a></li>
+          <li><a href="/parslet/install.html">install</a></li>
+          <li><a href="/parslet/documentation.html">documentation</a></li>
+          <li><a href="/parslet/contribute.html">contribute</a></li>
+        </ul>
+      </div>
+      <div class="content">
+        <h1>Contribute</h1><p>Find parslet to be really useful? Or just found a bug that is really ruining
+the day for you? Please contribute! Find the code on 
+<a href="http://github.com/kschiess/parslet">github</a>.</p>
+<h2>Contact</h2>
+<p>Join us on <span class="caps">IRC</span> in #parslet on irc.freenode.net.</p>
+<p>Discussion and patches (or the odd cry for ‘Help! How can I parse X?’) should
+go to our mailing list at
+<a href="mailto:ruby.parslet at librelist.com">ruby.parslet at librelist.com</a>. Just write a
+short message to that address and <a href="http://librelist.com">librelist</a> will
+subscribe you. <span class="caps">NNTP</span>/web interface can be had through
+<a href="http://dir.gmane.org/gmane.comp.lang.ruby.parslet">gmane.org</a>:
+<code>gmane.comp.lang.ruby.parslet</code>.</p>
+<h2>Bugs</h2>
+<p>Log in to github and open a bug ticket
+<a href="https://github.com/kschiess/parslet/issues">here</a>. Please be sure to include
+the version of parslet and Ruby; maybe you can even provide some code that
+exhibits the bug?</p>
+<p>And of course if you provide a properly tested patch, you’ll be our hero and 
+get a place in the space below for lifetime.</p>
+<h2>Projects</h2>
+<p>Have you got a project that uses parslet? Please write
+<a href="mailto:kaspar.schiess at absurd.li">us</a> about it.</p>
+<p><a href="https://github.com/relevance/edn-ruby"><strong>edn-ruby</strong></a></p>
+<p>edn-ruby is a Ruby library to read and write <a href="https://github.com/edn-format/edn">edn</a> 
+(extensible data notation), a subset of Clojure used for transferring data between 
+applications, much like <span class="caps">JSON</span>, <span class="caps">YAML</span>, or <span class="caps">XML</span>.</p>
+<p><a href="https://github.com/kschiess/parslet/tree/master/example/"><strong>Examples</strong></a></p>
+<p>In here, you can find a parser for a lisp like language and much more.</p>
+<p><a href="https://github.com/postmodern/net-http-server"><strong>Net::<span class="caps">HTTP</span>::Server</strong></a></p>
+<p>A really small and elegant <span class="caps">HTTP</span> server written in Ruby. Think Webrick. Using
+parslet. (Postmodern)</p>
+<p><a href="https://github.com/Hal9000/regexador"><strong>regexador</strong></a></p>
+<p>An external <span class="caps">DSL</span> for Ruby that tries to make regular expressions readable and maintainable. (Hal Fulton)</p>
+<p><a href="https://github.com/self-ml/selfml"><strong>self-ml</strong></a></p>
+<p>A <a href="http://self-ml.github.io/">self-ml</a> implementation using parslet. 
+(Ricardo Mendes)</p>
+<p><a href="https://github.com/undees/thnad"><strong>thnad</strong></a></p>
+<p>Thnad is a tiny programming language with so few features that it is not
+useful for anything at all — except showing how to write a compiler in half
+an hour.</p>
+<p><a href="https://github.com/rk/werd"><strong>Werd.rb</strong></a></p>
+<p>A variant of Chris Pound’s word generator written in Ruby, with some
+improvements. (Robert Kosek)</p>
+<p><a href="https://github.com/meh/versionub"><strong>versionub</strong></a></p>
+<p>A semantic version parser. (meh)</p>
+<h2>Thanks for all the fish — Contributions</h2>
+<ul>
+	<li><strong>Rory O’Kane</strong> (<a href="https://github.com/roryokane">roryokane</a>) for a careful code 
+  review!</li>
+</ul>
+<ul>
+	<li><strong>Zach Moazeni</strong> (<a href="https://github.com/zmoazeni">zmoazeni</a>) for his work on
+  Unicode performance.</li>
+</ul>
+<ul>
+	<li><strong>rogerbraun</strong> (<a href="https://github.com/rogerbraun">rogerbraun</a>) for being my
+  unicode tester.</li>
+</ul>
+<ul>
+	<li><strong>meh</strong> (<a href="http://meh.paranoid.pk/">meh</a>) for taking a real close look.</li>
+</ul>
+<ul>
+	<li><strong>John Mettraux</strong> (<a href="http://jmettraux.wordpress.com/">jmettraux</a>) for the really
+  nice <span class="caps">JSON</span> example and for pushing parslet beyond its limits.</li>
+</ul>
+<ul>
+	<li><strong>Josep M. Bach</strong> (<a href="http://www.txustice.me/">txus</a>) for minding the small 
+  things that make a big difference.</li>
+</ul>
+<ul>
+	<li><strong>Matthew Draper</strong> (<a href="http://matthewd.net/">matthewd</a>) for bothering with my 
+  broken <span class="caps">CSS</span>.</li>
+</ul>
+<ul>
+	<li><strong>Hal Brodigan</strong> (<a href="http://postmodern.github.com/">postmodern</a>) for solving our
+  email parsing needs!</li>
+</ul>
+<ul>
+	<li><strong>R. Konstantin Haase</strong> (<a href="http://rkh.im/">rhk</a>) for rspec matchers that help
+  stamp out, eliminate and abolish redundancy.</li>
+</ul>
+<ul>
+	<li><strong>Florian Hanke</strong> (<a href="http://floere.github.com">floere</a>) has given a lot of very
+  inspiring input for parslet. His questions have been key to rounding off the
+  corners and making the library as aesthetic as it is. And just look at the 
+  logo.</li>
+</ul>
+<ul>
+	<li><strong>Kaspar Schiess</strong> (<a href="http://www.absurd.li">absurd.li</a>) for being brave enough
+  to actually add another parser library to a field that’s already bursting
+  at the seams.</li>
+</ul></div>
+      <div class="copyright"><p><span class="caps">MIT</span> License, 2010-2012, © <a href="http://absurd.li">Kaspar Schiess</a><br/>
+        Logo by <a href="http://floere.github.com">Florian Hanke</a>, <a href="http://creativecommons.org/licenses/by/1.0/">CC Attribution</a> license</p></div>
+      <script type="text/javascript">var _gaq = _gaq || [];
+        _gaq.push(['_setAccount', 'UA-16365074-2']);
+        _gaq.push(['_trackPageview']); 
+        (function() {
+          var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+          ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+          var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+        })();</script>
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/build/documentation.html b/app/server/vendor/parslet/website/build/documentation.html
new file mode 100755
index 0000000..a484891
--- /dev/null
+++ b/app/server/vendor/parslet/website/build/documentation.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta content="text/html;charset=UTF-8" http-equiv="Content-type" />
+    <title>parslet -Documentation</title>
+    <meta content="Kaspar Schiess (http://absurd.li)" name="author" />
+    <link href="images/favicon3.ico" rel="shortcut icon" /><link href="/parslet/stylesheets/site.css" media="screen" rel="stylesheet" type="text/css" /><link href="/parslet/stylesheets/sh_whitengrey.css" media="screen" rel="stylesheet" type="text/css" /><script src="/parslet/javascripts/sh_main.min.js" type="text/javascript"></script><script src="/parslet/javascripts/sh_ruby.min.js" type="text/javascript"></script></head>
+  <body class="code" onload="sh_highlightDocument();">
+    <div id="everything">
+      <div class="main_menu"><img alt="Parslet Logo" src="/parslet/images/parsley_logo.png" /><ul>
+          <li><a href="/parslet/">about</a></li>
+          <li><a href="/parslet/get-started.html">get started</a></li>
+          <li><a href="/parslet/install.html">install</a></li>
+          <li><a href="/parslet/documentation.html">documentation</a></li>
+          <li><a href="/parslet/contribute.html">contribute</a></li>
+        </ul>
+      </div>
+      <div class="content">
+        <h1>Documentation</h1><p><a href="get-started.html"><strong>Getting Started</strong></a></p>
+        <p>Are you brand new to parslet? Well then let’s introduce you guys. This is what
+        you should read and try out first.</p>
+        <p><a href="https://github.com/kschiess/parslet/tree/master/example/"><strong>Examples</strong></a></p>
+        <p>Parslet comes with a lot of examples that explain how to use various aspects. 
+        Take a look at those.</p>
+        <p><a href="overview.html"><strong>In depth</strong></a></p>
+        <p>This is the real technical documentation, showing you how to use all aspects
+        of parslet. Especially:</p>
+        <ul>
+        	<li><a href="overview.html">Overview</a> explains parslet’s goals and gives you a bigger
+          picture.</li>
+        	<li>Using <a href="parser.html">Parslet::Parser</a> to <strong>write parsers</strong>.</li>
+        	<li>Using <a href="transform.html">Parslet::Transform</a> to <strong>transmogrify your intermediary
+          trees</strong>.</li>
+        	<li><a href="tricks.html">Tricks</a> for common situations.</li>
+        </ul>
+        <p><strong>Presentations</strong></p>
+        <ul>
+        	<li><a href="https://docs.google.com/present/view?id=0AfXgUAUtzyc7ZGZrcG1mNXNfMzIwZ3JjY2c3NW0">Parslet, An Introduction</a> introduces parslet in a few poignant slides. (Bo Jeanes and David Pick)</li>
+        </ul>
+        <p><strong>Videos</strong></p>
+        <ul>
+        	<li><a href="http://www.confreaks.com/videos/2730-wickedgoodruby-writing-dsl-s-with-parslet">Writing DSL’s with Parslet</a> Talk given by Jason Garber at the Wicked Good Ruby Conference 2013.</li>
+        </ul>
+        <p><strong>Blogs</strong></p>
+        <ul>
+        	<li><a href="http://florianhanke.com/blog/2011/02/01/parslet-intro.html">Parslet Intro</a>
+          explains quite a few things on how parsers work and on parser
+          metaprogramming. Besides, Florian Hanke also explains how to create an <span class="caps">ERB</span>
+          parser in just a few lines!</li>
+        </ul>
+        <ul>
+        	<li><a href="http://jmettraux.wordpress.com/2011/05/11/parslet-and-json/">Parslet and
+          <span class="caps">JSON</span></a> shows how
+          to construct a <span class="caps">JSON</span> parser in a few lines.
+          <a href="http://jmettraux.wordpress.com/about/">John</a> does a great job of explaining
+          how parslet ties back in with railroad diagrams.</li>
+        </ul>
+        <ul>
+        	<li><a href="http://zerowidth.com/2013/02/24/parsing-toml-in-ruby-with-parslet.html">Parsing <span class="caps">TOML</span> in Ruby with Parslet</a>
+          shows how to parse <span class="caps">TOML</span> (<a href="https://github.com/mojombo/toml">Tom’s Obvious Minimal Language</a>)
+          using parslet. I sense a theme here. Code is on github – this is the first
+          article in a series, linked from the article.</li>
+        </ul>
+        <ul>
+        	<li><a href="http://viget.com/extend/write-you-a-parser-for-fun-and-win">Write You a Parser for Fun and Win</a>
+          a succinct writeup on parsing text formats by David Eisinger.</li>
+        </ul>
+        <p><a href="http://rubydoc.info/gems/parslet/frames"><strong><span class="caps">YARD</span> Class Documentation</strong></a></p>
+        <p>The <a href="http://rubydoc.info/gems/parslet/frames"><span class="caps">YARD</span> documentation</a> will help you
+        with the nitty gritty. This documentation is real important too. It will be
+        constantly improved! (Thanks linode.com and DockYard for sponsoring this tool.)</p></div>
+      <div class="copyright"><p><span class="caps">MIT</span> License, 2010-2012, © <a href="http://absurd.li">Kaspar Schiess</a><br/>
+        Logo by <a href="http://floere.github.com">Florian Hanke</a>, <a href="http://creativecommons.org/licenses/by/1.0/">CC Attribution</a> license</p></div>
+      <script type="text/javascript">var _gaq = _gaq || [];
+        _gaq.push(['_setAccount', 'UA-16365074-2']);
+        _gaq.push(['_trackPageview']); 
+        (function() {
+          var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+          ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+          var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+        })();</script>
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/build/get-started.html b/app/server/vendor/parslet/website/build/get-started.html
new file mode 100755
index 0000000..7437e20
--- /dev/null
+++ b/app/server/vendor/parslet/website/build/get-started.html
@@ -0,0 +1,338 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta content="text/html;charset=UTF-8" http-equiv="Content-type" />
+    <title>parslet -Get Started</title>
+    <meta content="Kaspar Schiess (http://absurd.li)" name="author" />
+    <link href="images/favicon3.ico" rel="shortcut icon" /><link href="/parslet/stylesheets/site.css" media="screen" rel="stylesheet" type="text/css" /><link href="/parslet/stylesheets/sh_whitengrey.css" media="screen" rel="stylesheet" type="text/css" /><script src="/parslet/javascripts/sh_main.min.js" type="text/javascript"></script><script src="/parslet/javascripts/sh_ruby.min.js" type="text/javascript"></script></head>
+  <body class="code" onload="sh_highlightDocument();">
+    <div id="everything">
+      <div class="main_menu"><img alt="Parslet Logo" src="/parslet/images/parsley_logo.png" /><ul>
+          <li><a href="/parslet/">about</a></li>
+          <li><a href="/parslet/get-started.html">get started</a></li>
+          <li><a href="/parslet/install.html">install</a></li>
+          <li><a href="/parslet/documentation.html">documentation</a></li>
+          <li><a href="/parslet/contribute.html">contribute</a></li>
+        </ul>
+      </div>
+      <div class="content">
+        <h1>Get Started</h1><p>Let’s develop a small language that allows for simple computation together. 
+Here’s a valid input file for that language:</p>
+<pre class="sh_ruby"><code> 
+  puts(1 + 2)
+  puts(4 + 2)
+</code></pre>
+<p>To install the parslet library, please do a</p>
+<pre><code> 
+  gem install parslet
+</code></pre>
+<p>Now let’s write the first part of our parser. For now, we’ll just recognize
+simple numbers like ‘1’ or ‘42’.</p>
+<pre class="sh_ruby"><code title="mini_parser"> 
+  require 'parslet' 
+
+  class Mini < Parslet::Parser
+    rule(:integer) { match('[0-9]').repeat(1) }
+    root(:integer)
+  end
+
+  Mini.new.parse("132432")  # => "132432"@0
+</code></pre>
+<p>Running this example will print “132432 at 0”. Congratulations! You just have
+written your first parser. Running it on the input ‘<code>puts(1)</code>’ will
+not work yet. Let’s see what happens in case of a failure:</p>
+<pre class="sh_ruby"><code> 
+  Mini.new.parse("puts(1)") # raises Parslet::ParseFailed
+</code></pre>
+<p>Here’s the error message provided by that exception: “Expected at least 1 of
+[0-9] at line 1 char 1.” parslet tries to find a number there, but can’t find
+one.</p>
+<p>There are just two lines to the definition of this parser, let’s go through
+them:</p>
+<pre class="sh_ruby"><code> 
+  rule(:integer) { match('[0-9]').repeat(1) }
+</code></pre>
+<p><code>rule</code> lets you create a new parser rule. Inside the block of that
+<code>:integer</code> rule, you find <code>match('[0-9]').repeat(1)</code>.
+This says: “match a character that is in the range <code>0-9</code>, then
+match any number of those, but at least match one.”</p>
+<pre class="sh_ruby"><code> 
+  root(:integer)
+</code></pre>
+<p>That second line just says: Start parsing at the rule called
+<code>:integer</code>.</p>
+<h2>Addition</h2>
+<p>Let’s go for simple addition. We’ll have to allow for spaces in our input,
+since those help make code readable.</p>
+<pre class="sh_ruby"><code> 
+  rule(:space)  { match('\s').repeat(1) }
+  rule(:space?) { space.maybe }
+</code></pre>
+<p>Two things are new here: (and both in the second line)</p>
+<ul>
+	<li>you can use (‘call’) other rules in your rules</li>
+	<li><code>.maybe</code>, the same as <code>.repeat(0,1)</code><sup class="footnote" id="fnr1"><a href="#fn1">1</a></sup>, indicating 
+  that the thing before it is maybe present once in the input.</li>
+</ul>
+<p>Essentially, you can think about parslet rules as instructing Ruby to “parse
+this” and “parse that”. Calling other rules can be looked at in the same way;
+you tell Ruby to go off, parse that subrule and then come back with the
+results. This helps when thinking about rule recursion. For example, a
+self-recursive rule like this one will of course create an endless loop:</p>
+<pre class="sh_ruby"><code> 
+  rule(:infinity) {
+    infinity >> str(';')
+  }
+</code></pre>
+<p>Even though infinity seems to be delimited by ‘;’, in reality, infinity is
+very long, especially towards the end. There is no way of knowing for the
+parser when to stop processing <code>infinity</code> and start reading
+semicolons. Ergo, we need to make sure we talk about concrete items that
+consume input first, and then do recursion. This way we ensure that our
+grammar terminates, since in a way, it is like a normal program.</p>
+<p>Here’s the full parser:</p>
+<pre class="sh_ruby"><code title="full_parser">  
+  class Mini < Parslet::Parser
+    rule(:integer)    { match('[0-9]').repeat(1) >> space? }
+  
+    rule(:space)      { match('\s').repeat(1) }
+    rule(:space?)     { space.maybe }
+  
+    rule(:operator)   { match('[+]') >> space? }
+  
+    rule(:sum)        { integer >> operator >> expression }
+    rule(:expression) { sum | integer }
+
+    root :expression
+  end
+
+  def parse(str)
+    mini = Mini.new
+  
+    mini.parse(str)
+  rescue Parslet::ParseFailed => failure
+    puts failure.cause.ascii_tree
+  end
+
+  parse "1 + 2 + 3"  # => "1 + 2 + 3"@0
+  parse "a + 2"      # fails, see below
+</code></pre>
+<p>As you can see, the parser got decorated with the <code>space?</code> idiom.
+Every atom of our language consumes the space right after it. This is a useful
+convention that makes top level rules (the important ones) look cleaner.</p>
+<p>Note also the addition of <code>:operator</code>, <code>:sum</code> and
+<code>:expression</code>. The runner code has been extended a bit, so as to
+throw nice explanations of what went wrong when a parse failure is
+encountered. Running the code on ‘<code>a + 2</code>’ for example outputs:</p>
+<pre class="output">  
+Expected one of [SUM, INTEGER] at line 1 char 1.
+|- Failed to match sequence (INTEGER OPERATOR EXPRESSION) at line 1 char 1.
+|  `- Failed to match sequence ([0-9]{1, } SPACE?) at line 1 char 1.
+|     `- Expected at least 1 of [0-9] at line 1 char 1.
+|        `- Failed to match [0-9] at line 1 char 1.
+`- Failed to match sequence ([0-9]{1, } SPACE?) at line 1 char 1.
+   `- Expected at least 1 of [0-9] at line 1 char 1.
+      `- Failed to match [0-9] at line 1 char 1.
+</pre>
+<p>This is what parslet calls an <code>#error_tree</code>. Not only the output of
+your parser, but also its grammar is constructed like a tree. When things go
+wrong, every branch of the tree has its own reasons for not accepting a given
+input. The <code>#cause</code> method returns those reasons.</p>
+<p>Our grammar has essentially two branches, <code>SUM</code> and
+<code>INTEGER</code>. Can you see why all rules expect a number as the first
+character?</p>
+<h2>Tree output (and what to do about it)</h2>
+<p>But if we leave the negative examples for a second; what happens if the parse
+succeeds? It turns out, not much:</p>
+<pre class="sh_ruby"><code>
+  parse "1 + 2 + 3"  # => "1 + 2 + 3"@0
+</code></pre>
+<p>The only notable difference between input and output is that the output has an
+extra ‘@0’ appended to it. This is related to line number tracking and will be
+explained later on (or you can skip ahead and look up
+<code>Parslet::Slice</code>).</p>
+<p>The code we now have parses the input successfully, but doesn’t do much else. 
+Parslet hasn’t got its own opinion on what to do with your input. By default, 
+it will just play it back to you. But parslet provides also a method of 
+structuring its output:</p>
+<pre class="sh_ruby"><code title="output_samples"> 
+  # Without structure: just strings.
+  str('ooo').parse('ooo')                           # => "ooo"@0
+  str('o').repeat.parse('ooo')                      # => "ooo"@0
+
+  # Added structure: .as(...)
+  str('ooo').as(:ex1).parse('ooo')                  # => {:ex1=>"ooo"@0}
+  
+  long = str('o').as(:ex2a).repeat.as(:ex2b).parse('ooo')  
+  long # => {:ex2b=>[{:ex2a=>"o"@0}, {:ex2a=>"o"@1}, {:ex2a=>"o"@2}]}
+</code></pre>
+<p>You get to name things the way you want! This is also free. Seriously: parslet
+requires you to add all the structure to its output. Annotate important parts
+of your grammar with <code>.as(:symbol)</code> and get back a tree-like
+structure composed of hashes (sequence), arrays (repetition) and strings (like
+we had initially).</p>
+<p>Once you start naming things, you’ll notice that what you don’t name,
+disappears. Parslet assumes that <em>what you don’t name is unimportant</em>.</p>
+<pre class="sh_ruby"><code title="inline_parser"> 
+parser =  str('a').as(:a) >> str(' ').maybe >> 
+          str('+').as(:o) >> str(' ').maybe >> 
+          str('b').as(:b)
+parser.parse('a + b') # => {:a=>"a"@0, :o=>"+"@2, :b=>"b"@4}
+</code></pre>
+<p>Think of this like using a highlighter on your input: What is there not to
+like about neon yellow?</p>
+<h2>Making the parser complete</h2>
+<p>Let’s look at the complete parser definition that also allows for function
+calls:</p>
+<pre class="sh_ruby"><code title="full_parser"> 
+class MiniP < Parslet::Parser
+  # Single character rules
+  rule(:lparen)     { str('(') >> space? }
+  rule(:rparen)     { str(')') >> space? }
+  rule(:comma)      { str(',') >> space? }
+
+  rule(:space)      { match('\s').repeat(1) }
+  rule(:space?)     { space.maybe }
+
+  # Things
+  rule(:integer)    { match('[0-9]').repeat(1).as(:int) >> space? }
+  rule(:identifier) { match['a-z'].repeat(1) }
+  rule(:operator)   { match('[+]') >> space? }
+  
+  # Grammar parts
+  rule(:sum)        { integer.as(:left) >> operator.as(:op) >> expression.as(:right) }
+  rule(:arglist)    { expression >> (comma >> expression).repeat }
+  rule(:funcall)    { identifier.as(:funcall) >> lparen >> arglist.as(:arglist) >> rparen }
+  
+  rule(:expression) { funcall | sum | integer }
+  root :expression
+end
+
+require 'pp'
+pp MiniP.new.parse("puts(1 + 2 + 3, 45)")
+</code></pre>
+<p>That’s really all there is to it — our language is a really simple language. 
+When fed with a string like ’<code>puts(1 + 2 + 3, 45)</code>, our parser outputs
+the following:</p>
+<pre class="output"> 
+{:funcall=>"puts"@0,
+ :arglist=>
+  [{:left=>{:int=>"1"@5},
+    :op=>"+ "@7,
+    :right=>{:left=>{:int=>"2"@9}, :op=>"+ "@11, :right=>{:int=>"3"@13}}},
+   {:int=>"45"@16}]}
+</code></pre>
+<p>Parslet calls this the <em>intermediary tree</em>. There are three types of nodes in
+this tree:</p>
+<ul>
+	<li><strong>Hashes</strong>: a node that has named subtrees</li>
+	<li><strong>Arrays</strong>: a node storing a collection of sub-nodes</li>
+	<li><strong>Strings</strong> are the leaves, containing the <em>accepted source</em></li>
+</ul>
+<p>The format of this tree is easy to work with and to read. Here’s what the
+above tree would look like as a graphic:</p>
+<p><img src="images/ast.png" alt="" /></p>
+<h2>Where to go from here: An Interpreter</h2>
+<p>As nice as the format above is for printing and looking at – it may be
+difficult at times to get the information out of it again. Let’s look at how
+to transform the tree:</p>
+<pre class="sh_ruby"><code> 
+class SimpleTransform < Parslet::Transform
+  rule(funcall: 'puts', arglist: sequence(:args)) {
+    "puts(#{args.inspect})"
+  }
+  # ... other rules
+end
+
+tree = {funcall: 'puts', arglist: [1,2,3]}
+SimpleTransform.new.apply(tree) # => "puts([1, 2, 3])"
+</code></pre>
+<p>Transformation is an entire topic by itself; this will be covered in detail
+<a href="transform.html">later on</a>. To whet your appetite, let me just give you a few
+teasers:</p>
+<ul>
+	<li>Transformations match portions of your tree at any depth, replacing them
+  with whatever you decide.</li>
+	<li>In addition to <code>sequence(sym)</code>, there is also
+  <code>simple(sym)</code> and <code>subtree(sym)</code>. Those match simple
+  strings and entire subtrees respectively. Caution with the latter.</li>
+</ul>
+<p>Here’s how you would write a somewhat classical interpreter for our little 
+language by using a transformation. Note that from this point on, there is
+not one way to go about this, but thousands; you are really free (and on
+your own):</p>
+<pre class="sh_ruby"><code title="putting it all together"> 
+class MiniP < Parslet::Parser
+  # Single character rules
+  rule(:lparen)     { str('(') >> space? }
+  rule(:rparen)     { str(')') >> space? }
+  rule(:comma)      { str(',') >> space? }
+
+  rule(:space)      { match('\s').repeat(1) }
+  rule(:space?)     { space.maybe }
+
+  # Things
+  rule(:integer)    { match('[0-9]').repeat(1).as(:int) >> space? }
+  rule(:identifier) { match['a-z'].repeat(1) }
+  rule(:operator)   { match('[+]') >> space? }
+  
+  # Grammar parts
+  rule(:sum)        { 
+    integer.as(:left) >> operator.as(:op) >> expression.as(:right) }
+  rule(:arglist)    { expression >> (comma >> expression).repeat }
+  rule(:funcall)    { 
+    identifier.as(:funcall) >> lparen >> arglist.as(:arglist) >> rparen }
+  
+  rule(:expression) { funcall | sum | integer }
+  root :expression
+end
+
+class IntLit   < Struct.new(:int)
+  def eval; int.to_i; end
+end
+class Addition < Struct.new(:left, :right) 
+  def eval; left.eval + right.eval; end
+end
+class FunCall < Struct.new(:name, :args); 
+  def eval
+    p args.map { |s| s.eval }
+  end
+end
+
+class MiniT < Parslet::Transform
+  rule(:int => simple(:int))        { IntLit.new(int) }
+  rule(
+    :left => simple(:left), 
+    :right => simple(:right), 
+    :op => '+')                     { Addition.new(left, right) }
+  rule(
+    :funcall => 'puts', 
+    :arglist => subtree(:arglist))  { FunCall.new('puts', arglist) }
+end
+
+parser = MiniP.new
+transf = MiniT.new
+
+ast = transf.apply(
+  parser.parse(
+    'puts(1,2,3, 4+5)'))
+        
+ast.eval # => [1, 2, 3, 9]
+</code></pre>
+<p>That’s a bunch of code for printing <code>[1, 2, 3, 9]</code>. Welcome to the
+fantastic world of compiler and interpreter writing!</p>
+<p><sup class="footnote" id="fnr1"><a href="#fn1">1</a></sup> As far as parsing goes. There is a subtle difference between
+<code>#repeat(0,1)</code> and <code>#maybe</code>. Can you figure it out?</p></div>
+      <div class="copyright"><p><span class="caps">MIT</span> License, 2010-2012, © <a href="http://absurd.li">Kaspar Schiess</a><br/>
+        Logo by <a href="http://floere.github.com">Florian Hanke</a>, <a href="http://creativecommons.org/licenses/by/1.0/">CC Attribution</a> license</p></div>
+      <script type="text/javascript">var _gaq = _gaq || [];
+        _gaq.push(['_setAccount', 'UA-16365074-2']);
+        _gaq.push(['_trackPageview']); 
+        (function() {
+          var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+          ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+          var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+        })();</script>
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/build/images/ast.png b/app/server/vendor/parslet/website/build/images/ast.png
new file mode 100755
index 0000000..c0a3443
Binary files /dev/null and b/app/server/vendor/parslet/website/build/images/ast.png differ
diff --git a/app/server/vendor/parslet/website/build/images/favicon1.ico b/app/server/vendor/parslet/website/build/images/favicon1.ico
new file mode 100755
index 0000000..500b9e7
Binary files /dev/null and b/app/server/vendor/parslet/website/build/images/favicon1.ico differ
diff --git a/app/server/vendor/parslet/website/build/images/favicon2.ico b/app/server/vendor/parslet/website/build/images/favicon2.ico
new file mode 100755
index 0000000..57fc370
Binary files /dev/null and b/app/server/vendor/parslet/website/build/images/favicon2.ico differ
diff --git a/app/server/vendor/parslet/website/build/images/favicon3.ico b/app/server/vendor/parslet/website/build/images/favicon3.ico
new file mode 100755
index 0000000..c016837
Binary files /dev/null and b/app/server/vendor/parslet/website/build/images/favicon3.ico differ
diff --git a/app/server/vendor/parslet/website/build/images/parsley_logo.png b/app/server/vendor/parslet/website/build/images/parsley_logo.png
new file mode 100755
index 0000000..7baefe9
Binary files /dev/null and b/app/server/vendor/parslet/website/build/images/parsley_logo.png differ
diff --git a/app/server/vendor/parslet/website/build/index.html b/app/server/vendor/parslet/website/build/index.html
new file mode 100755
index 0000000..93e5e22
--- /dev/null
+++ b/app/server/vendor/parslet/website/build/index.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta content="text/html;charset=UTF-8" http-equiv="Content-type" />
+    <title>parslet -About</title>
+    <meta content="Kaspar Schiess (http://absurd.li)" name="author" />
+    <link href="images/favicon3.ico" rel="shortcut icon" /><link href="/parslet/stylesheets/site.css" media="screen" rel="stylesheet" type="text/css" /><link href="/parslet/stylesheets/sh_whitengrey.css" media="screen" rel="stylesheet" type="text/css" /><script src="/parslet/javascripts/sh_main.min.js" type="text/javascript"></script><script src="/parslet/javascripts/sh_ruby.min.js" type="text/javascript"></script></head>
+  <body class="code" onload="sh_highlightDocument();">
+    <div id="everything">
+      <div class="main_menu"><img alt="Parslet Logo" src="/parslet/images/parsley_logo.png" /><ul>
+          <li><a href="/parslet/">about</a></li>
+          <li><a href="/parslet/get-started.html">get started</a></li>
+          <li><a href="/parslet/install.html">install</a></li>
+          <li><a href="/parslet/documentation.html">documentation</a></li>
+          <li><a href="/parslet/contribute.html">contribute</a></li>
+        </ul>
+      </div>
+      <div class="content">
+        <h1>About</h1><pre class="sh_ruby"><code>
+  require 'parslet'
+  include Parslet
+
+  # Constructs a parser using a Parser Expression Grammar 
+  parser =  str('"') >> 
+            (
+              str('\\') >> any |
+              str('"').absent? >> any
+            ).repeat.as(:string) >> 
+            str('"')
+
+  result = parser.parse %Q("this is a valid string") 
+  result # => {:string=>"this is a valid string"@1}
+</code></pre>
+<p>A small Ruby library for constructing parsers in the
+<a href="http://en.wikipedia.org/wiki/Parsing_expression_grammar"><span class="caps">PEG</span></a> (Parsing
+Expression Grammar) fashion.</p>
+<p>Parslet makes developing complex parsers easy. It does so by</p>
+<ul>
+	<li>providing the best <strong>error reporting</strong> possible</li>
+	<li><strong>not generating</strong> reams of code for you to debug</li>
+</ul>
+<p>Parslet takes the long way around to make <strong>your job</strong> easier. It allows for
+incremental language construction. Often, you start out small, implementing
+the atoms of your language first; <em>parslet</em> takes pride in making this
+possible.</p>
+<p>Eager to try this out? <a href="get-started.html">Get started</a>!</p></div>
+      <div class="copyright"><p><span class="caps">MIT</span> License, 2010-2012, © <a href="http://absurd.li">Kaspar Schiess</a><br/>
+        Logo by <a href="http://floere.github.com">Florian Hanke</a>, <a href="http://creativecommons.org/licenses/by/1.0/">CC Attribution</a> license</p></div>
+      <script type="text/javascript">var _gaq = _gaq || [];
+        _gaq.push(['_setAccount', 'UA-16365074-2']);
+        _gaq.push(['_trackPageview']); 
+        (function() {
+          var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+          ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+          var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+        })();</script>
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/build/install.html b/app/server/vendor/parslet/website/build/install.html
new file mode 100755
index 0000000..bc8bd90
--- /dev/null
+++ b/app/server/vendor/parslet/website/build/install.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta content="text/html;charset=UTF-8" http-equiv="Content-type" />
+    <title>parslet -Install</title>
+    <meta content="Kaspar Schiess (http://absurd.li)" name="author" />
+    <link href="images/favicon3.ico" rel="shortcut icon" /><link href="/parslet/stylesheets/site.css" media="screen" rel="stylesheet" type="text/css" /><link href="/parslet/stylesheets/sh_whitengrey.css" media="screen" rel="stylesheet" type="text/css" /><script src="/parslet/javascripts/sh_main.min.js" type="text/javascript"></script><script src="/parslet/javascripts/sh_ruby.min.js" type="text/javascript"></script></head>
+  <body class="code" onload="sh_highlightDocument();">
+    <div id="everything">
+      <div class="main_menu"><img alt="Parslet Logo" src="/parslet/images/parsley_logo.png" /><ul>
+          <li><a href="/parslet/">about</a></li>
+          <li><a href="/parslet/get-started.html">get started</a></li>
+          <li><a href="/parslet/install.html">install</a></li>
+          <li><a href="/parslet/documentation.html">documentation</a></li>
+          <li><a href="/parslet/contribute.html">contribute</a></li>
+        </ul>
+      </div>
+      <div class="content">
+        <h1>Install</h1><p>Parslet is at version <em>1.5.0</em>.</p>
+<p><strong>Rubygems</strong></p>
+<pre>
+  gem install parslet
+</pre>
+<p><strong>Bundler</strong></p>
+<pre>
+  gem 'parslet', '~> 1.5'
+</pre>
+<p>or if you want to track the edge:</p>
+<pre>
+  gem 'parslet', :git => 'git://github.com/kschiess/parslet.git'
+</pre></div>
+      <div class="copyright"><p><span class="caps">MIT</span> License, 2010-2012, © <a href="http://absurd.li">Kaspar Schiess</a><br/>
+        Logo by <a href="http://floere.github.com">Florian Hanke</a>, <a href="http://creativecommons.org/licenses/by/1.0/">CC Attribution</a> license</p></div>
+      <script type="text/javascript">var _gaq = _gaq || [];
+        _gaq.push(['_setAccount', 'UA-16365074-2']);
+        _gaq.push(['_trackPageview']); 
+        (function() {
+          var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+          ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+          var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+        })();</script>
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/build/javascripts/sh_main.min.js b/app/server/vendor/parslet/website/build/javascripts/sh_main.min.js
new file mode 100755
index 0000000..eaa2d0b
--- /dev/null
+++ b/app/server/vendor/parslet/website/build/javascripts/sh_main.min.js
@@ -0,0 +1,5 @@
+/* Copyright (C) 2007, 2008 gnombat at users.sourceforge.net */
+/* License: http://shjs.sourceforge.net/doc/gplv3.html */
+
+
+if(!this.sh_languages){this.sh_languages={}}var sh_requests={};function sh_isEmailAddress(a){if(/^mailto:/.test(a)){return false}return a.indexOf("@")!==-1}function sh_setHref(b,c,d){var a=d.substring(b[c-2].pos,b[c-1].pos);if(a.length>=2&&a.charAt(0)==="<"&&a.charAt(a.length-1)===">"){a=a.substr(1,a.length-2)}if(sh_isEmailAddress(a)){a="mailto:"+a}b[c-2].node.href=a}function sh_konquerorExec(b){var a=[""];a.index=b.length;a.input=b;return a}function sh_highlightString(B,o){if(/Konqueror/.test(navigator.userAgent)){if(!o.konquered){for(var F=0;F<o.length;F++){for(var H=0;H<o[F].length;H++){var G=o[F][H][0];if(G.source==="$"){G.exec=sh_konquerorExec}}}o.konquered=true}}var N=document.createElement("a");var q=document.createElement("span");var A=[];var j=0;var n=[];var C=0;var k=null;var x=function(i,a){var p=i.length;if(p===0){return}if(!a){var Q=n.length;if(Q!==0){var r=n[Q-1];if(!r[3]){a=r[1]}}}if(k!==a){if(k){A[j++]={pos:C};if(k==="sh_url"){sh_setHref(A,j,B)}}if(a){var P;if(a==="sh_url"){P=N.cloneNode(false)}else{P=q.cloneNode(false)}P.className=a;A[j++]={node:P,pos:C}}}C+=p;k=a};var t=/\r\n|\r|\n/g;t.lastIndex=0;var d=B.length;while(C<d){var v=C;var l;var w;var h=t.exec(B);if(h===null){l=d;w=d}else{l=h.index;w=t.lastIndex}var g=B.substring(v,l);var M=[];for(;;){var I=C-v;var D;var y=n.length;if(y===0){D=0}else{D=n[y-1][2]}var O=o[D];var z=O.length;var m=M[D];if(!m){m=M[D]=[]}var E=null;var u=-1;for(var K=0;K<z;K++){var f;if(K<m.length&&(m[K]===null||I<=m[K].index)){f=m[K]}else{var c=O[K][0];c.lastIndex=I;f=c.exec(g);m[K]=f}if(f!==null&&(E===null||f.index<E.index)){E=f;u=K;if(f.index===I){break}}}if(E===null){x(g.substring(I),null);break}else{if(E.index>I){x(g.substring(I,E.index),null)}var e=O[u];var J=e[1];var b;if(J instanceof Array){for(var L=0;L<J.length;L++){b=E[L+1];x(b,J[L])}}else{b=E[0];x(b,J)}switch(e[2]){case -1:break;case -2:n.pop();break;case -3:n.length=0;break;default:n.push(e);break}}}if(k){A[j++]={pos:C};if(k==="sh_url"){sh_setHref(A,j,B)}k=null}C=w}return A}function sh_getClasses(d){var a=[];var b=d.className;if(b&&b.length>0){var e=b.split(" ");for(var c=0;c<e.length;c++){if(e[c].length>0){a.push(e[c])}}}return a}function sh_addClass(c,a){var d=sh_getClasses(c);for(var b=0;b<d.length;b++){if(a.toLowerCase()===d[b].toLowerCase()){return}}d.push(a);c.className=d.join(" ")}function sh_extractTagsFromNodeList(c,a){var f=c.length;for(var d=0;d<f;d++){var e=c.item(d);switch(e.nodeType){case 1:if(e.nodeName.toLowerCase()==="br"){var b;if(/MSIE/.test(navigator.userAgent)){b="\r"}else{b="\n"}a.text.push(b);a.pos++}else{a.tags.push({node:e.cloneNode(false),pos:a.pos});sh_extractTagsFromNodeList(e.childNodes,a);a.tags.push({pos:a.pos})}break;case 3:case 4:a.text.push(e.data);a.pos+=e.length;break}}}function sh_extractTags(c,b){var a={};a.text=[];a.tags=b;a.pos=0;sh_extractTagsFromNodeList(c.childNodes,a);return a.text.join("")}function sh_mergeTags(d,f){var a=d.length;if(a===0){return f}var c=f.length;if(c===0){return d}var i=[];var e=0;var b=0;while(e<a&&b<c){var h=d[e];var g=f[b];if(h.pos<=g.pos){i.push(h);e++}else{i.push(g);if(f[b+1].pos<=h.pos){b++;i.push(f[b]);b++}else{i.push({pos:h.pos});f[b]={node:g.node.cloneNode(false),pos:h.pos}}}}while(e<a){i.push(d[e]);e++}while(b<c){i.push(f[b]);b++}return i}function sh_insertTags(k,h){var g=document;var l=document.createDocumentFragment();var e=0;var d=k.length;var b=0;var j=h.length;var c=l;while(b<j||e<d){var i;var a;if(e<d){i=k[e];a=i.pos}else{a=j}if(a<=b){if(i.node){var f=i.node;c.appendChild(f);c=f}else{c=c.parentNode}e++}else{c.appendChild(g.createTextNode(h.substring(b,a)));b=a}}return l}function sh_highlightElement(d,g){sh_addClass(d,"sh_sourceCode");var c=[];var e=sh_extractTags(d,c);var f=sh_highlightString(e,g);var b=sh_mergeTags(c,f);var a=sh_insertTags(b,e);while(d.hasChildNodes()){d.removeChild(d.firstChild)}d.appendChild(a)}function sh_getXMLHttpRequest(){if(window.ActiveXObject){return new ActiveXObject("Msxml2.XMLHTTP")}else{if(window.XMLHttpRequest){return new XMLHttpRequest()}}throw"No XMLHttpRequest implementation available"}function sh_load(language,element,prefix,suffix){if(language in sh_requests){sh_requests[language].push(element);return}sh_requests[language]=[element];var request=sh_getXMLHttpRequest();var url=prefix+"sh_"+language+suffix;request.open("GET",url,true);request.onreadystatechange=function(){if(request.readyState===4){try{if(!request.status||request.status===200){eval(request.responseText);var elements=sh_requests[language];for(var i=0;i<elements.length;i++){sh_highlightElement(elements[i],sh_languages[language])}}else{throw"HTTP error: status "+request.status}}finally{request=null}}};request.send(null)}function sh_highlightDocument(g,k){var b=document.getElementsByTagName("pre");for(var e=0;e<b.length;e++){var f=b.item(e);var a=sh_getClasses(f);for(var c=0;c<a.length;c++){var h=a[c].toLowerCase();if(h==="sh_sourcecode"){continue}if(h.substr(0,3)==="sh_"){var d=h.substring(3);if(d in sh_languages){sh_highlightElement(f,sh_languages[d])}else{if(typeof(g)==="string"&&typeof(k)==="string"){sh_load(d,f,g,k)}else{throw'Found <pre> element with class="'+h+'", but no such language exists'}}break}}}};
diff --git a/app/server/vendor/parslet/website/build/javascripts/sh_ruby.min.js b/app/server/vendor/parslet/website/build/javascripts/sh_ruby.min.js
new file mode 100755
index 0000000..b766750
--- /dev/null
+++ b/app/server/vendor/parslet/website/build/javascripts/sh_ruby.min.js
@@ -0,0 +1 @@
+if(!this.sh_languages){this.sh_languages={}}sh_languages.ruby=[[[/\b(?:require)\b/g,"sh_preproc",-1],[/\b[+-]?(?:(?:0x[A-Fa-f0-9]+)|(?:(?:[\d]*\.)?[\d]+(?:[eE][+-]?[\d]+)?))u?(?:(?:int(?:8|16|32|64))|L)?\b/g,"sh_number",-1],[/"/g,"sh_string",1],[/'/g,"sh_string",2],[/</g,"sh_string",3],[/\/[^\n]*\//g,"sh_regexp",-1],[/(%r)(\{(?:\\\}|#\{[A-Za-z0-9]+\}|[^}])*\})/g,["sh_symbol","sh_regexp"],-1],[/\b(?:alias|begin|BEGIN|break|case|defined|do|else|elsif|end|END|ensure|for|if|in|include|loop|next|raise|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield|false|nil|self|true|__FILE__|__LINE__|and|not|or|def|class|module|catch|fail|load|throw)\b/g,"sh_keyword",-1],[/(?:^\=begin)/g,"sh_comment",4],[/(?:\$[#]?|@@|@)(?:[A-Za-z0-9_]+|'|\"|\/)/g,"sh_type",-1],[/[A-Za-z0-9]+(?:\?|!)/g,"sh_normal",-1],[/~|!|%|\^|\*|\(|\)|-|\+|=|\[|\]|\\|:|;|,|\.|\/|\?|&|<|>|\|/g,"sh_symbol",-1],[/(#)(\{)/g,["sh_symbol","sh_cbracket"],-1],[/#/g,"sh_comment",5],[/\{|\}/g,"sh_cbracket",-1]],[[/$/g,null,-2],[/\\(?:\\|")/g,null,-1],[/"/g,"sh_string",-2]],[[/$/g,null,-2],[/\\(?:\\|')/g,null,-1],[/'/g,"sh_string",-2]],[[/$/g,null,-2],[/>/g,"sh_string",-2]],[[/^(?:\=end)/g,"sh_comment",-2]],[[/$/g,null,-2]]];
diff --git a/app/server/vendor/parslet/website/build/overview.html b/app/server/vendor/parslet/website/build/overview.html
new file mode 100755
index 0000000..cc53bbc
--- /dev/null
+++ b/app/server/vendor/parslet/website/build/overview.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta content="text/html;charset=UTF-8" http-equiv="Content-type" />
+    <title>parslet -Overview</title>
+    <meta content="Kaspar Schiess (http://absurd.li)" name="author" />
+    <link href="images/favicon3.ico" rel="shortcut icon" /><link href="/parslet/stylesheets/site.css" media="screen" rel="stylesheet" type="text/css" /><link href="/parslet/stylesheets/sh_whitengrey.css" media="screen" rel="stylesheet" type="text/css" /><script src="/parslet/javascripts/sh_main.min.js" type="text/javascript"></script><script src="/parslet/javascripts/sh_ruby.min.js" type="text/javascript"></script></head>
+  <body class="code" onload="sh_highlightDocument();">
+    <div id="everything">
+      <div class="main_menu"><img alt="Parslet Logo" src="/parslet/images/parsley_logo.png" /><ul>
+          <li><a href="/parslet/">about</a></li>
+          <li><a href="/parslet/get-started.html">get started</a></li>
+          <li><a href="/parslet/install.html">install</a></li>
+          <li><a href="/parslet/documentation.html">documentation</a></li>
+          <li><a href="/parslet/contribute.html">contribute</a></li>
+        </ul>
+      </div>
+      <div class="content">
+        <h1>Overview</h1><p>Parslet is a library with a clear philosophy: It makes parser writing easy and
+        testable. On top of that, it provides understandable error messages (“General
+        Protection Fault”) to you, the language writer. In extension, you will
+        hopefully manage to provide good error messages to your users. Together, we 
+        can create a better world!</p>
+        <p>Traditional texts on the subject will have you write a compiler or interpreter
+        for a language in several stages:</p>
+        <ul>
+        	<li>Parsing or Lexing/Parsing</li>
+        	<li>Abstract Syntax Tree construction</li>
+        	<li>Optimization and checking of the tree</li>
+        	<li>Generation of code / Execution</li>
+        </ul>
+        <p>This library will be good for the first two stages only. After that, you’ll
+        be on your own.</p>
+        <p>The parsing step has literally been implemented by hundreds (thousands) of
+        clever people; No lack of alternatives. Even in Ruby, you’ll have the choice 
+        among a handful of libraries. There’s a distinction to make on this level as
+        well:</p>
+        <p><strong>LRk parsers and related fields</strong> Parsers in this class use a lexical analyzer
+        (a <em>lexer</em> ) to transform the input text into tokens (<em>tokenizing</em> ). They
+        then check if your stream of tokens has a corresponding tree that conforms to
+        the grammar. Most of these parsers allow grammars that are ambiguous and will
+        provide a mechanism for resolving the arising ambiguities. These are the
+        earliest parser generators and the most widely used (<em>yacc</em>, <em>bison</em>, …) —
+        chances are, you’ll have more than one of these libraries installed on your
+        system.</p>
+        <p><strong><span class="caps">PEG</span> or packrat parsers</strong> Parsers in this class are based on a slightly more
+        modern algorithm, which translates what one does when writing a parser by hand
+        in top-down fashion. This is what we programmers do all over, methods calling
+        methods – and its also (grossly) what these parsers do to recognize input.
+        Left recursion is impossible to express in these grammars. No lexers are
+        required – lexical tokenizing and parsing are one single step. Ruby has
+        several implementations of this algorithm in library form:
+        <a href="http://github.com/nathansobo/treetop">Treetop</a>,
+        <a href="http://github.com/mjijackson/citrus">Citrus</a>,
+        <a href="http://wiki.github.com/luikore/rsec/">rsec</a> and of course
+        <a href="http://kschiess.github.com/parslet">Parslet</a>.</p>
+        <p>All of these generators are different in small ways; yet most implement common
+        patterns and provide almost identical APIs. We believe this is an error:
+        choice is good, but there should be visible attributes distinguishing the
+        choices.</p>
+        <p>Parslet is not like the others, in fact it is radically different on some
+        key elements.</p>
+        <h2>Writing a language</h2>
+        <p>Whether you write a language for a configuration file or a new computer
+        language (the holy grail), the steps are always the same:</p>
+        <ol>
+        	<li>Create a grammar: <em>What should be legal syntax?</em></li>
+        	<li>Annotate the grammar: <em>What is important data?</em></li>
+        	<li>Create a transformation: <em>How do I want to work with that data?</em></li>
+        </ol>
+        <p>The creation of grammars and the various concepts that are associated are treated
+        in <a href="parser.html">Parslet::Parser</a>.</p>
+        <p>Transformation of the resulting intermediary tree is treated in
+        <a href="transform.html">Parslet::Transform</a></p></div>
+      <div class="copyright"><p><span class="caps">MIT</span> License, 2010-2012, © <a href="http://absurd.li">Kaspar Schiess</a><br/>
+        Logo by <a href="http://floere.github.com">Florian Hanke</a>, <a href="http://creativecommons.org/licenses/by/1.0/">CC Attribution</a> license</p></div>
+      <script type="text/javascript">var _gaq = _gaq || [];
+        _gaq.push(['_setAccount', 'UA-16365074-2']);
+        _gaq.push(['_trackPageview']); 
+        (function() {
+          var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+          ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+          var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+        })();</script>
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/build/parser.html b/app/server/vendor/parslet/website/build/parser.html
new file mode 100755
index 0000000..922d909
--- /dev/null
+++ b/app/server/vendor/parslet/website/build/parser.html
@@ -0,0 +1,288 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta content="text/html;charset=UTF-8" http-equiv="Content-type" />
+    <title>parslet -Parser construction</title>
+    <meta content="Kaspar Schiess (http://absurd.li)" name="author" />
+    <link href="images/favicon3.ico" rel="shortcut icon" /><link href="/parslet/stylesheets/site.css" media="screen" rel="stylesheet" type="text/css" /><link href="/parslet/stylesheets/sh_whitengrey.css" media="screen" rel="stylesheet" type="text/css" /><script src="/parslet/javascripts/sh_main.min.js" type="text/javascript"></script><script src="/parslet/javascripts/sh_ruby.min.js" type="text/javascript"></script></head>
+  <body class="code" onload="sh_highlightDocument();">
+    <div id="everything">
+      <div class="main_menu"><img alt="Parslet Logo" src="/parslet/images/parsley_logo.png" /><ul>
+          <li><a href="/parslet/">about</a></li>
+          <li><a href="/parslet/get-started.html">get started</a></li>
+          <li><a href="/parslet/install.html">install</a></li>
+          <li><a href="/parslet/documentation.html">documentation</a></li>
+          <li><a href="/parslet/contribute.html">contribute</a></li>
+        </ul>
+      </div>
+      <div class="content">
+        <h1>Parser construction</h1><p>A parser is nothing more than a class that derives from
+<code>Parslet::Parser</code>. The simplest parser that one could write would
+look like this:</p>
+<pre class="sh_ruby"><code>
+  class SimpleParser < Parslet::Parser
+    rule(:a_rule) { str('simple_parser') }
+    root(:a_rule)
+  end
+</code></pre>
+<p>The language recognized by this parser is simply the string “simple_parser”. 
+Parser rules do look a lot like methods and are defined by</p>
+<pre class="sh_ruby"><code>
+  rule(name) { definition_block }
+</code></pre>
+<p>Behind the scenes, this really defines a method that returns whatever you 
+return from it.</p>
+<p>Every parser has a root. This designates where parsing should start. It is like
+an entry point to your parser. With a root defined like this:</p>
+<pre class="sh_ruby"><code>
+  root(:my_root)
+</code></pre>
+<p>you create a <code>#parse</code> method in your parser that will start parsing
+by calling the <code>#my_root</code> method. You’ll also have a <code>#root</code>
+(instance) method that is an alias of the root method. The following things are
+really one and the same:</p>
+<pre class="sh_ruby"><code>
+  SimpleParser.new.parse(string)
+  SimpleParser.new.root.parse(string)
+  SimpleParser.new.a_rule.parse(string)
+</code></pre>
+<p>Knowing these things gives you a lot of flexibility; I’ll explain why at the
+end of the chapter. For now, just let me point out that because all of this is
+Ruby, your favorite editor will syntax highlight parser code just fine.</p>
+<h2>Atoms: The inside of a parser</h2>
+<h3>Matching strings of characters</h3>
+<p>A parser is constructed from parser atoms (or parslets, hence the name). The
+atoms are what appear inside your rules (and maybe elsewhere). We’ve already
+encountered an atom, the string atom:</p>
+<pre class="sh_ruby"><code>
+  str('simple_parser')
+</code></pre>
+<p>This returns a <code>Parslet::Atoms::Str</code> instance. These parser atoms
+all derive from <code>Parslet::Atoms::Base</code> and have essentially just
+one method you can call: <code>#parse</code>. So this works:</p>
+<pre class="sh_ruby"><code title="parser atoms">
+  str('foobar').parse('foobar') # => "foobar"@0
+</code></pre>
+<p>The atoms are small parsers that can recognize languages and throw errors, just
+like real <code>Parslet::Parser</code> subclasses.</p>
+<h3>Matching character ranges</h3>
+<p>The second parser atom you will have to know about allows you to match
+character ranges:</p>
+<pre class="sh_ruby"><code>
+  match('[0-9a-f]')
+</code></pre>
+<p>The above atom would match the numbers zero through nine and the letters ‘a’ 
+to ‘f’ – yeah, you guessed right – hexadecimal numbers for example. The inside
+of such a match parslet is essentially a regular expression that matches 
+a single character of input. Because we’ll be using ranges so much with 
+<code>#match</code> and because typing (‘[]’) is tiresome, here’s another way
+to write the above <code>#match</code> atom:</p>
+<pre class="sh_ruby"><code>
+  match['0-9a-f']
+</code></pre>
+<p>Character matches are instances of <code>Parslet::Atoms::Re</code>. Here are 
+some more examples of character ranges:</p>
+<pre class="sh_ruby"><code>
+  match['[:alnum:]']      # letters and numbers
+  match['\\n']            # newlines
+  match('\\w')            # word characters
+  match('.')              # any character
+</code></pre>
+<h3>The wild wild <code>#any</code></h3>
+<p>The last example above corresponds to the regular expression <code>/./</code> that matches
+any one character. There is a special atom for that:</p>
+<pre class="sh_ruby"><code>
+  any 
+</code></pre>
+<h2>Composition of Atoms</h2>
+<p>These basic atoms can be composed to form complex grammars. The following
+few sections will tell you about the various ways atoms can be composed.</p>
+<h3>Simple Sequences</h3>
+<p>Match ‘foo’ and then ‘bar’:</p>
+<pre class="sh_ruby"><code>
+  str('foo') >> str('bar')    # same as str('foobar')
+</code></pre>
+<p>Sequences correspond to instances of the class
+<code>Parslet::Atoms::Sequence</code>.</p>
+<h3>Repetition and its Special Cases</h3>
+<p>To model atoms that can be repeated, you should use <code>#repeat</code>:</p>
+<pre class="sh_ruby"><code>
+  str('foo').repeat
+</code></pre>
+<p>This will allow foo to repeat any number of times, including zero. If you
+look at the signature for <code>#repeat</code> in <code>Parslet::Atoms::Base</code>, 
+you’ll see that it has really two arguments: <em>min</em> and <em>max</em>. So the following
+code all makes sense:</p>
+<pre class="sh_ruby"><code>
+  str('foo').repeat(1)      # match 'foo' at least once
+  str('foo').repeat(1,3)    # at least once and at most 3 times
+  str('foo').repeat(0, nil) # the default: same as str('foo').repeat
+</code></pre>
+<p>Repetition has a special case that is used frequently: Matching something
+once or not at all can be achieved by <code>repeat(0,1)</code>, but also 
+through the prettier:</p>
+<pre class="sh_ruby"><code>
+  str('foo').maybe          # same as str('foo').repeat(0,1)
+</code></pre>
+<p>These all map to <code>Parslet::Atoms::Repetition</code>. Please note this
+little twist to <code>#maybe</code>:</p>
+<pre class="sh_ruby"><code title="maybes twist">
+  str('foo').maybe.as(:f).parse('')         # => {:f=>nil}
+  str('foo').repeat(0,1).as(:f).parse('')   # => {:f=>[]}
+</code></pre>
+<p>The ‘nil’-value of <code>#maybe</code> is nil. This is catering to the
+intuition that <code>foo.maybe</code> either gives me <code>foo</code> or
+nothing at all, not an empty array. But have it your way!</p>
+<h3>Alternation</h3>
+<p>The most important composition method for grammars is alternation. Without
+it, your grammars would only vary in the amount of things matched, but not
+in content. Here’s how this looks:</p>
+<pre class="sh_ruby"><code>
+  str('foo') | str('bar')   # matches 'foo' OR 'bar'
+</code></pre>
+<p>This reads naturally as “‘foo’ or ‘bar’”.</p>
+<h3>Operator precedence</h3>
+<p>The operators we have chosen for parslet atom combination have the operator
+precedence that you would expect. No parenthesis are needed to express
+alternation of sequences:</p>
+<pre class="sh_ruby"><code>
+  str('s') >> str('equence') | 
+    str('se') >> str('quence')
+</code></pre>
+<h3>And more</h3>
+<p>Parslet atoms are not as pretty as Treetop atoms. There you go, we said it. 
+However, there seems to be a different kind of aesthetic about them; they 
+are pure Ruby and integrate well with the rest of your environment. Have a 
+look at this:</p>
+<pre class="sh_ruby"><code>
+  # Also consumes the space after important things like ';' or ':'. Call this
+  # giving the character you want to match as argument: 
+  #
+  #   arg >> (spaced(',') >> arg).repeat
+  #
+  def spaced(character)
+    str(character) >> match["\s"]
+  end
+</code></pre>
+<p>or even this:</p>
+<pre class="sh_ruby"><code>
+  # Turns any atom into an expression that matches a left parenthesis, the 
+  # atom and then a right parenthesis.
+  #
+  #   bracketed(sum)
+  #
+  def bracketed(atom)
+    spaced('(') >> atom >> spaced(')')
+  end
+</code></pre>
+<p>You might say that because parslet is just plain old Ruby objects itself (<span class="caps">PORO</span>
+™), it allows for very tight code. Module inclusion, class inheritance, …
+all your tools should work well with parslet.</p>
+<h2>Tree construction</h2>
+<p>By default, parslet will just echo back to you the strings you feed into it. 
+Parslet will not generate a parser for you and neither will it generate your
+abstract syntax tree for you. The method <code>#as(name)</code> allows you
+to specify exactly how you want your tree to look like:</p>
+<pre class="sh_ruby"><code title="using as">
+  str('foo').parse('foo')             # => "foo"@0
+  str('foo').as(:bar).parse('foo')    # => {:bar=>"foo"@0}
+</code></pre>
+<p>So you think: <code>#as(name)</code> allows me to create a hash, big deal.
+That’s not all. You’ll notice that annotating everything that you want to keep
+in your grammar with <code>#as(name)</code> autocreates a sensible tree
+composed of hashes and arrays and strings. It’s really somewhat magic: Parslet
+has a set of clever rules that merge the annotated output from your atoms into
+a tree. Here are some more examples, with the atom on the left and the resulting
+tree (assuming a successful parse) on the right:</p>
+<pre class="sh_ruby"><code>
+  # Normal strings just map to strings
+  str('a').repeat                         "aaa"@0                                 
+
+  # Arrays capture repetition of non-strings
+  str('a').repeat.as(:b)                  {:b=>"aaa"@0}                           
+  str('a').as(:b).repeat                  [{:b=>"a"@0}, {:b=>"a"@1}, {:b=>"a"@2}] 
+
+  # Subtrees get merged - unlabeled strings discarded
+  str('a').as(:a) >> str('b').as(:b)      {:a=>"a"@0, :b=>"b"@1}                  
+  str('a') >> str('b').as(:b) >> str('c') {:b=>"b"@1}                             
+
+  # #maybe will return nil, not the empty array
+  str('a').maybe.as(:a)                   {:a=>"a"@0}                             
+  str('a').maybe.as(:a)                   {:a=>nil}
+</code></pre>
+<h2>Capturing input</h2>
+<p><em>Advanced reading material – feel free to skip this.</em></p>
+<p>Sometimes a parser needs to match against something that was already matched
+against. Think about Ruby heredocs for example:</p>
+<pre class="sh_ruby"><code>
+  str = <-HERE
+    This is part of the heredoc.
+  HERE
+</code></pre>
+<p>The key to matching this kind of document is to capture part of the input
+first and then construct the rest of the parser based on the captured part.
+This is what it looks like in its simplest form:</p>
+<pre class="sh_ruby"><code>
+  match['ab'].capture(:capt) >>               # create the capture
+    dynamic { |s,c| str(c.captures[:capt]) }  # and match using the capture
+</code></pre>
+<p>This parser matches either ‘aa’ or ‘bb’, but not mixed forms ‘ab’ or ‘ba’. The
+last sample introduced two new concepts for this kind of complex parser: the 
+<code>#capture(name)</code> method and the <code>dynamic { ... }</code> code
+block.</p>
+<p>Appending <code>#capture(name)</code> to any parser will capture that parsers
+result in the captures hash in the parse context. If and only if the parser
+<code>match['ab']</code> succeeds, it stores either ‘a’ or ‘b’ in 
+<code>context.captures[:capt]</code>.</p>
+<p>The only way to get at that hash during the parse process is in a
+<code>dynamic { ... }</code> code block. (for reasons that are out of the
+scope of this document) In such a block, you can:</p>
+<pre class="sh_ruby"><code>
+  dynamic { |source, context|
+    # construct parsers by using randomness
+    rand < 0.5 ? str('a') : str('b')
+    
+    # Or by using context information 
+    str( context.captures[:capt] )
+    
+    # Or by .. doing other kind of work (consumes 100 chars and then 'a')
+    source.consume(100)
+    return str('a')
+  }
+</code></pre>
+<h3>Scopes</h3>
+<p>What if you want to parse heredocs contained within heredocs? It’s turtles all
+the way down, after all. To be able to remember what string was used to
+construct the outer heredoc, you would use the <code>#scope { ... }</code>
+block that was introduced in parslet 1.5. Like opening a Ruby block, it allows
+you to capture results (assign values to variables) to the same names you’ve 
+already used in outer scope – <em>without destroying the outer scopes values for 
+these captures!</em>.</p>
+<p>Here’s an example for this: 
+<pre class="sh_ruby"><code>
+  str('a').capture(:a) >> scope { str('b').capture(:a) } >> 
+    dynamic { |s,c| str(c.captures[:a]) }
+</code></pre></p>
+<p>This parses ‘aba’ – if you understand that, you understand scopes and
+captures. Congrats.</p>
+<h2>And more</h2>
+<p>Now you know exactly how to create parsers using Parslet. Your parsers
+will output intricate structures made of endless arrays, complex hashes and 
+a few string leftovers. But your programming skills fail you when you try
+to put all this data to use. Selecting keys upon keys in hash after hash, you
+feel like a cockroach that has just read Kafka’s works. This is no fun. This 
+is not what you signed up for.</p>
+<p>Time to introduce you to <a href="transform.html">Parslet::Transform</a> and its workings.</p></div>
+      <div class="copyright"><p><span class="caps">MIT</span> License, 2010-2012, © <a href="http://absurd.li">Kaspar Schiess</a><br/>
+        Logo by <a href="http://floere.github.com">Florian Hanke</a>, <a href="http://creativecommons.org/licenses/by/1.0/">CC Attribution</a> license</p></div>
+      <script type="text/javascript">var _gaq = _gaq || [];
+        _gaq.push(['_setAccount', 'UA-16365074-2']);
+        _gaq.push(['_trackPageview']); 
+        (function() {
+          var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+          ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+          var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+        })();</script>
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/build/stylesheets/sh_whitengrey.css b/app/server/vendor/parslet/website/build/stylesheets/sh_whitengrey.css
new file mode 100755
index 0000000..41df0e2
--- /dev/null
+++ b/app/server/vendor/parslet/website/build/stylesheets/sh_whitengrey.css
@@ -0,0 +1,139 @@
+pre.sh_sourceCode {
+  background-color: #ffffff;
+  color: #696969;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_keyword {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_type {
+  color: #696969;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_string {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_regexp {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_specialchar {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_comment {
+  color: #1326a2;
+  font-weight: normal;
+  font-style: italic;
+}
+
+pre.sh_sourceCode .sh_number {
+  color: #bb00ff;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_preproc {
+  color: #470000;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_function {
+  color: #000000;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_url {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_date {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_time {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_file {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_ip {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_name {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_variable {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_oldfile {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_newfile {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_difflines {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_selector {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_property {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_value {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
diff --git a/app/server/vendor/parslet/website/build/stylesheets/site.css b/app/server/vendor/parslet/website/build/stylesheets/site.css
new file mode 100755
index 0000000..b6d6822
--- /dev/null
+++ b/app/server/vendor/parslet/website/build/stylesheets/site.css
@@ -0,0 +1,106 @@
+/* line 15, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+body {
+  font-size: 17px;
+  font-family: Helvetica;
+  background-color: white; }
+
+/* line 22, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+a {
+  color: black; }
+
+/* line 25, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+.main_menu {
+  font-size: 1.2em;
+  width: 50em;
+  margin-bottom: 1cm; }
+  /* line 31, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+  .main_menu ul {
+    display: inline-block;
+    list-style-type: none;
+    font-size: 1.33em;
+    margin-left: -8em; }
+    /* line 5, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+    .main_menu ul:after {
+      content: ".";
+      display: block;
+      height: 0;
+      clear: both;
+      visibility: hidden; }
+    /* line 12, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+    * html .main_menu ul {
+      height: 1px; }
+  /* line 37, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+  .main_menu li {
+    float: left;
+    font-variant: small-caps;
+    padding-left: 1em; }
+  /* line 42, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+  .main_menu a, .main_menu:visited {
+    text-decoration: none;
+    color: #7c7c7c; }
+
+/* line 46, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+.content {
+  font-size: 1em;
+  width: 50em;
+  line-height: 1.4em;
+  margin-left: 1cm; }
+  /* line 53, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+  .content p {
+    margin: 1em; }
+  /* line 56, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+  .content img {
+    margin-left: 3em; }
+
+/* line 59, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+.copyright {
+  font-variant: small-caps;
+  font-size: 0.6em;
+  color: #00ad00;
+  margin-left: 22em;
+  margin-top: 3cm; }
+  /* line 67, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+  .copyright a {
+    text-decoration: none;
+    color: #00ad00; }
+
+/* line 72, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+body.code code {
+  font-size: 0.9em;
+  font-family: "Monaco", monospace; }
+  /* line 78, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+  body.code code .sh_keyword {
+    color: #761a47; }
+  /* line 81, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+  body.code code .sh_comment {
+    color: #686868; }
+  /* line 84, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+  body.code code .sh_string {
+    color: #42aa7a;
+    background-color: #edf7f7; }
+  /* line 88, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+  body.code code .sh_constant {
+    color: #551e03; }
+  /* line 91, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+  body.code code .sh_method {
+    color: #4679a9; }
+  /* line 94, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+  body.code code .sh_symbol {
+    color: #551e03; }
+  /* line 97, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+  body.code code .sh_number {
+    color: #42aa7a; }
+/* line 101, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+body.code pre {
+  font-size: 1em;
+  font-family: "Monaco", monospace;
+  background-color: #f8f8f8;
+  color: #4679a9;
+  line-height: 1.1em;
+  margin-left: 1em;
+  padding: -1em 0 -1em 0; }
+  /* line 115, /Users/kschiess/git/own/parslet/website/source/stylesheets/site.css.sass */
+  body.code pre.sh_sourceCode {
+    border-radius: 0.5em;
+    background-color: #f8f8f8;
+    padding-bottom: 1.4em; }
diff --git a/app/server/vendor/parslet/website/build/transform.html b/app/server/vendor/parslet/website/build/transform.html
new file mode 100755
index 0000000..9ff22b5
--- /dev/null
+++ b/app/server/vendor/parslet/website/build/transform.html
@@ -0,0 +1,250 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta content="text/html;charset=UTF-8" http-equiv="Content-type" />
+    <title>parslet -Transformation</title>
+    <meta content="Kaspar Schiess (http://absurd.li)" name="author" />
+    <link href="images/favicon3.ico" rel="shortcut icon" /><link href="/parslet/stylesheets/site.css" media="screen" rel="stylesheet" type="text/css" /><link href="/parslet/stylesheets/sh_whitengrey.css" media="screen" rel="stylesheet" type="text/css" /><script src="/parslet/javascripts/sh_main.min.js" type="text/javascript"></script><script src="/parslet/javascripts/sh_ruby.min.js" type="text/javascript"></script></head>
+  <body class="code" onload="sh_highlightDocument();">
+    <div id="everything">
+      <div class="main_menu"><img alt="Parslet Logo" src="/parslet/images/parsley_logo.png" /><ul>
+          <li><a href="/parslet/">about</a></li>
+          <li><a href="/parslet/get-started.html">get started</a></li>
+          <li><a href="/parslet/install.html">install</a></li>
+          <li><a href="/parslet/documentation.html">documentation</a></li>
+          <li><a href="/parslet/contribute.html">contribute</a></li>
+        </ul>
+      </div>
+      <div class="content">
+        <h1>Transformation</h1><p>Parslet parsers output deep nested hashes. Those are nice for printing, but 
+hard to work with. The structure of the nested hashes is determined by the
+grammar and can thus vary largely. Testing for the presence of individual 
+keys would produce code that is hard to read and maintain.</p>
+<p>This is why parslet also comes with a hash transformation engine. To construct
+such a transform, you have to derive from <code>Parslet::Transform</code>:</p>
+<pre class="sh_ruby"><code title="simple transform">
+  class MyTransform < Parslet::Transform
+    rule('a') { 'b' }
+  end
+  MyTransform.new.apply('a') # => "b"
+</code></pre>
+<p>This is a transformation that replaces all ’a’s with ’b’s. A transformation
+rule has two parts: A <strong>pattern</strong> (here: <code>'a'</code>) and an <strong>action block</strong>
+(<code>{ 'b' }</code>).</p>
+<p>The engine will go through the input and traverse the tree in depth-first
+post-order fashion. This means that for a given tree node, it will first visit
+the children and only then look at the node itself. While traversing, all
+rules are tested in the order in which they are defined. If a rule matches, the
+corresponding tree is <em>replaced</em> by whatever the action block returns.</p>
+<p>Here’s another way of saying the same thing, perhaps more in line with what
+you need as a user of Parslet: <code>Parslet::Transform</code> is what allows
+you to transform the <span class="caps">PORO</span>-trees magically into a real abstract syntax tree.
+The rule definitions are the futuristic nano-machines that act on tree leaves
+first, eating them away and replacing them with contraptions of your own
+design. Here’s how that might look like in Ruby:</p>
+<pre class="sh_ruby"><code title="poro magic">
+  tree = {:left => {:int => '1'}, 
+          :op   => '+', 
+          :right => {:int => '2'}}
+        
+  class Trans < Parslet::Transform
+    rule(:int => simple(:x)) { Integer(x) }
+  end
+  Trans.new.apply(tree)     # => {:left=>1, :op=>"+", :right=>2}
+</code></pre>
+<p>You can start thinking about the leaves first, transforming those <code>:int
+=> '1'</code> into real Ruby integers. This incremental (test driven!)
+approach will prevent your intermediary tree from turning into grey goo
+from too many nano-machines. Rules should in general be simple and transform
+a small part of the tree into a more useful variant. Turns out that if we were
+looking for an interpreter, one more rule will give us evaluation:</p>
+<pre class="sh_ruby"><code title="building up">
+  tree = {:left => {:int => '1'}, 
+          :op   => '+', 
+          :right => {:int => '2'}}
+
+  class Trans < Parslet::Transform
+    rule(:int => simple(:x)) { Integer(x) }
+    rule(:op => '+', :left => simple(:l), :right => simple(:r)) { l + r }
+  end
+  Trans.new.apply(tree)     # => 3
+</code></pre>
+<p>Cool, isn’t it? To recap: parslet intentionally spits out deep nested hashes, 
+because it also gives you the tool to work with those. Turning the intermediary
+trees into something useful is really easy.</p>
+<h2></h2>
+<h2>Working with Captures</h2>
+<p>What is this <code>simple(symbol)</code> business all about, you might ask.
+Glad you do.</p>
+<h3>Simple captures</h3>
+<p>Transform allows you to specify patterns that have wildcards in them. The
+wildcards match part of the tree, but at the same time capture it for working
+on it in your action block. The wildcard</p>
+<pre class="sh_ruby"><code>
+  simple(:x)
+</code></pre>
+<p>will match any object <span class="caps">BUT</span> hashes or arrays. While this is obviously useful
+for capturing strings, you can also capture other ‘simple’ (as opposed to 
+composed) objects of your own creation. <code>simple(:x)</code> would thus match
+all of these objects:</p>
+<pre class="sh_ruby"><code>
+  "a string"
+  123
+  Foo.new(:some, :class, :instance)
+</code></pre>
+<p>If you think about what you’ll be doing to your intermediary trees, replacing
+leaves with more useful objects, <code>simple</code> really makes good sense, 
+since it will stop you from matching entire subtrees.</p>
+<h3>Matching Repetitions and Sequences</h3>
+<p>Some patterns (like repetitions and sequences) produce arrays of objects as
+result. You can use <code>simple(...)</code> to replace all parts of these
+arrays with your own objects, but you cannot replace the array as a whole. 
+This is the purpose of <code>sequence(symbol)</code>:</p>
+<pre class="sh_ruby"><code>
+  sequence(:x)
+</code></pre>
+<p>will match all of these:</p>
+<pre class="sh_ruby"><code>
+  ['a', 'b', 'c']
+  ['a', 'a', 'a']
+  [Foo.new, Bar.new]
+</code></pre>
+<p>but not</p>
+<pre class="sh_ruby"><code>
+  [{:a => :b}]
+  [['a', 'b']]
+</code></pre>
+<p>Like its smaller brother, <code>sequence</code> is very picky about what it
+consumes and what not. All for the same reasons.</p>
+<h3>Matching entire subtrees</h3>
+<p>So you don’t want to listen and really want that big gun with the foot aiming
+addon. You’ll be needing <code>subtree(symbol)</code>. It always matches. 
+Nuff said.</p>
+<h3>Matching context</h3>
+<p>A match always binds in a context. The context consists of all bindings
+that were previously made. If you reuse the same symbol for two consecutive
+matches within the same pattern, the engine will assume that you want these
+two matched objects to be equal (under <code>==</code>). This allows to 
+specify constraints on your matches that would need code to express otherwise:</p>
+<pre class="sh_ruby"><code>
+  # The following code is an excerpt from example/simple_xml.rb in the distro
+  t.rule(
+    open: {name: simple(:tag)}, 
+    close: {name: simple(:tag)}, 
+    inner: simple(:t)
+  ) { 'verified' }
+</code></pre>
+<p>This replaces <em>matching</em> open and close tags with the word ‘verified’,
+consuming them from the tree and allowing the same rule to match higher up. A
+valid <span class="caps">XML</span> tree will leave only the word ‘verified’ behind, while the parser
+will stop at the problem nodes in invalid trees.</p>
+<h2>Transformation rules</h2>
+<p>In this chapter, we’ll look more closely at transformation rules and the
+different ways they can be laid out in your code.</p>
+<h3>Usage Patterns</h3>
+<p>The way the transformation engine is constructed, there is not one, but three
+ways to use it. Since at least one of those is inconvenient for you, the user,
+I am going to show only the remaining two, Variant 1 that produces an instance
+of the transform for direct use:</p>
+<pre class="sh_ruby"><code>
+  # Variant 1
+  transform = Parslet::Transform.new do
+    rule(...) { ... } 
+    rule(...) { ... } 
+    rule(...) { ... } 
+  end
+  transform.apply(tree)
+</code></pre>
+<p>and Variant 2 that allows constructing the transformation as a class:</p>
+<pre class="sh_ruby"><code>
+  # Variant 2
+  class MyTransform < Parslet::Transform
+    rule(...) { ... } 
+    rule(...) { ... } 
+    rule(...) { ... } 
+  end
+  MyTransform.new.apply(tree)
+</code></pre>
+<p>I guess both have their sweet spot.</p>
+<h3>Action blocks: Two flavors</h3>
+<p>As you might have noticed by now, parslet provides choice as well as nice
+parsers. To recap: Rules have a left side called <em>pattern</em> and a right side 
+called <em>action block</em>:</p>
+<pre class="sh_ruby"><code>
+  rule(PATTERN) {ACTION_BLOCK}
+</code></pre>
+<p>There are two ways of writing action blocks, and the difference might be 
+fundamental to know to you one day. If written like this:</p>
+<pre class="sh_ruby"><code>
+  rule(:foo => simple(:x)) { puts x }
+</code></pre>
+<p>the block will be able to access <code>x</code> as a local variable. This is 
+very convenient and shortens the action code, often to the point of being
+very expressive.</p>
+<p>But there is a <em>big downside</em> to this way of writing things: The action block
+must be executed in the context of some magic instance that has <code>x</code>
+as a local method (aka accessor). You can only have one self at any one time; 
+variable access to the binding of the block isn’t possible inside this kind
+of action blocks:</p>
+<pre class="sh_ruby"><code>
+  y = 12
+  rule(:foo => simple(:x)) { Integer(x) + y }
+</code></pre>
+<p>This will (depending on the context) throw a <code>NameError</code> or a
+<code>NoMethodError</code>.</p>
+<p>But this can be fixed by using the other, less elegant style for action
+blocks:</p>
+<pre class="sh_ruby"><code>
+  y = 12
+  rule(:foo => simple(:x)) { |dictionary| Integer(dictionary[:x]) + y }
+</code></pre>
+<p>In this second flavor, the block gets executed in the context of definition, 
+whatever that was. This means that it can capture and access local variables
+just fine. Access to the bindings (called <code>dictionary</code> here) is 
+more clumsy, but hey, you can’t have your cake and eat it too, I guess. Even 
+though that is a pity.</p>
+<h2>A word on patterns</h2>
+<p>Given the <span class="caps">PORO</span> hash</p>
+<pre class="sh_ruby"><code>
+  { 
+    :dog => 'terrier', 
+    :cat => 'suit' }
+</code></pre>
+<p>one might assume that the following rule matches <code>:dog</code> and
+replaces it by <code>'foo'</code>:</p>
+<pre class="sh_ruby"><code>
+  rule(:dog => 'terrier') { 'foo' }
+</code></pre>
+<p>This is frankly impossible. How would <code>'foo'</code> live besides
+<code>:cat => 'suit'</code> inside the hash? It cannot. This is why hashes are
+either matched completely, cats n’ all, or not at all.</p>
+<p>Transformations are there for one thing: Getting out of the hash/array/slice
+mess parslet creates (on purpose) into the realm of your own beautifully
+crafted <span class="caps">AST</span> classes. Such
+<a href="http://en.wikipedia.org/wiki/Abstract_syntax_tree"><span class="caps">AST</span></a> nodes will generally
+correspond 1:1 to hashes inside your intermediary tree.</p>
+<p>If transformations get you into a mess, remember this simple truth: They have
+been designed for the above purpose. Abusing them is fun (and almost all the
+examples in the project do so) but the mess you get when you do is all yours.</p>
+<p>If you are really desperate, try to look at the example in <a href="get-started.html">Get Started</a> or at the parser in the sample project
+<a href="https://github.com/kschiess/wt">wt</a>. Imitating them would be a good first step. And if all else fails, we’re there for you, see the ‘Contact’ section in <a href="contribute.html">Contribute</a>.</p>
+<h2>Summary</h2>
+<p>This concludes this (three part) introduction to parslet and leaves you with a
+good knowledge of most tricky parts. If you are missing some detail, maybe
+you can find it in the texts referenced <a href="documentation.html">here</a>? There is 
+also an entire page on the tricks useful in practice here: <a href="tricks.html">Tricks</a>.</p>
+<p>If not, please tell us about it. We’ll include it in this documentation in no 
+time.</p></div>
+      <div class="copyright"><p><span class="caps">MIT</span> License, 2010-2012, © <a href="http://absurd.li">Kaspar Schiess</a><br/>
+        Logo by <a href="http://floere.github.com">Florian Hanke</a>, <a href="http://creativecommons.org/licenses/by/1.0/">CC Attribution</a> license</p></div>
+      <script type="text/javascript">var _gaq = _gaq || [];
+        _gaq.push(['_setAccount', 'UA-16365074-2']);
+        _gaq.push(['_trackPageview']); 
+        (function() {
+          var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+          ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+          var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+        })();</script>
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/build/tricks.html b/app/server/vendor/parslet/website/build/tricks.html
new file mode 100755
index 0000000..fbd22ab
--- /dev/null
+++ b/app/server/vendor/parslet/website/build/tricks.html
@@ -0,0 +1,197 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta content="text/html;charset=UTF-8" http-equiv="Content-type" />
+    <title>parslet -Tricks for common situations</title>
+    <meta content="Kaspar Schiess (http://absurd.li)" name="author" />
+    <link href="images/favicon3.ico" rel="shortcut icon" /><link href="/parslet/stylesheets/site.css" media="screen" rel="stylesheet" type="text/css" /><link href="/parslet/stylesheets/sh_whitengrey.css" media="screen" rel="stylesheet" type="text/css" /><script src="/parslet/javascripts/sh_main.min.js" type="text/javascript"></script><script src="/parslet/javascripts/sh_ruby.min.js" type="text/javascript"></script></head>
+  <body class="code" onload="sh_highlightDocument();">
+    <div id="everything">
+      <div class="main_menu"><img alt="Parslet Logo" src="/parslet/images/parsley_logo.png" /><ul>
+          <li><a href="/parslet/">about</a></li>
+          <li><a href="/parslet/get-started.html">get started</a></li>
+          <li><a href="/parslet/install.html">install</a></li>
+          <li><a href="/parslet/documentation.html">documentation</a></li>
+          <li><a href="/parslet/contribute.html">contribute</a></li>
+        </ul>
+      </div>
+      <div class="content">
+        <h1>Tricks for common situations</h1><h2>Matching <span class="caps">EOF</span> (End Of File)</h2>
+<p>Ahh Sir, you’ll be needin what us parsers call <em>epsilon</em>:</p>
+<pre class="sh_ruby"><code>
+  rule(:eof) { any.absent? }
+</code></pre>
+<p>Of course, most of us don’t use this at all, since any parser has <span class="caps">EOF</span> as
+implicit last input.</p>
+<h2>Matching Strings Case Insensitive</h2>
+<p>Parslet is fully hackable: You can use code to create parsers easily. Here’s
+how I would match a string in case insensitive manner:</p>
+<pre class="sh_ruby"><code title="case insensitive match">
+  def stri(str)
+    key_chars = str.split(//)
+    key_chars.
+      collect! { |char| match["#{char.upcase}#{char.downcase}"] }.
+      reduce(:>>)
+  end
+
+  # Constructs a parser using a Parser Expression Grammar 
+  stri('keyword').parse "kEyWoRd"     # => "kEyWoRd"@0
+</code></pre>
+<h2>Testing</h2>
+<p>Parslet helps you to create parsers that are in turn created out of many small
+parsers. It is really turtles all the way down. Imagine you have a complex 
+parser:</p>
+<pre class="sh_ruby"><code>
+  class ComplexParser < Parslet::Parser
+    root :lots_of_stuff
+  
+    rule(:lots_of_stuff) { ... }
+  
+    # and many lines later: 
+    rule(:simple_rule) { str('a') }
+  end
+</code></pre>
+<p>Also imagine that the parser (as a whole) fails to consume the ‘a’ that 
+<code>simple_rule</code> is talking about.</p>
+<p>This kind of problem can very often be fixed by bisecting it into two possible
+problems. Either:</p>
+<ol>
+	<li>the <code>lots_of_stuff</code> rule somehow doesn’t place <code>simple_rule</code>
+  in the right context or</li>
+	<li>the <code>simple_rule</code> simply (hah!) fails to match its input.</li>
+</ol>
+<p>I find it very useful in this situation to eliminate 2. from our options:</p>
+<pre class="sh_ruby"><code title="rspec">
+  require 'rspec'
+  require 'parslet/rig/rspec'
+  
+  class ComplexParser < Parslet::Parser
+    rule(:simple_rule) { str('a') }
+  end
+
+  describe ComplexParser  do
+    let(:parser) { ComplexParser.new }
+    context "simple_rule" do
+      it "should consume 'a'" do
+        parser.simple_rule.should parse('a')
+      end 
+    end
+  end
+  
+  RSpec::Core::Runner.run([])
+</code></pre>
+<p>Output is: 
+<pre class="output"></p>
+<p>Example::ComplexParser
+  simple_rule
+    should consume ‘a’</p>
+<p>Finished in 0.00115 seconds
+1 example, 0 failures
+</pre></p>
+<p>Parslet parsers have one method per rule. These methods return valid parsers
+for a subset of your grammar.</p>
+<h2>Error reports</h2>
+<p>If your grammar fails and you’re aching to know why, here’s a bit of exception
+handling code that will help you out:</p>
+<pre class="sh_ruby"><code title="exception handling">
+  parser = str('foo')
+  begin
+    parser.parse('bar')
+  rescue Parslet::ParseFailed => error
+    puts error.cause.ascii_tree
+  end
+</code></pre>
+<p>This should print something akin to:</p>
+<pre class="output"> 
+Expected "foo", but got "bar" at line 1 char 1.
+</pre>
+<p>These error reports are probably the fastest way to know exactly where you
+went wrong (or where your input is wrong, which is aequivalent).</p>
+<p>And since this is such a common idiom, we provide you with a shortcut: to
+get the above, just:</p>
+<pre class="sh_ruby"><code>
+require 'parslet/convenience'
+parser.parse_with_debug(input)
+</code></pre>
+<h3>Reporter engines</h3>
+<p>Note that there is currently not one, but two error reporting engines! The 
+default engine will report errors in a structure that looks exactly like the
+grammar structure:</p>
+<pre class="sh_ruby"><code title="error reporter 1">
+  class P < Parslet::Parser
+    root(:body)
+    rule(:body) { elements }
+    rule(:elements) { (call | element).repeat(2) }
+    rule(:element) { str('bar') }
+    rule(:call) { str('baz') >> str('()') }
+  end
+  
+  begin
+    P.new.parse('barbaz')
+  rescue Parslet::ParseFailed => error
+    puts error.cause.ascii_tree
+  end
+</code></pre>
+<p>Outputs:</p>
+<pre class="output"> 
+Expected at least 2 of CALL / ELEMENT at line 1 char 1.
+`- Expected one of [CALL, ELEMENT] at line 1 char 4.
+   |- Failed to match sequence ('baz' '()') at line 1 char 7.
+   |  `- Premature end of input at line 1 char 7.
+   `- Expected "bar", but got "baz" at line 1 char 4.
+</pre>
+<p>Let’s switch out the ‘grammar structure’ engine (called ‘<code>Tree</code>’)
+with the ‘deepest error position’ engine:</p>
+<pre class="sh_ruby"><code title="error reporter 2">
+  class P < Parslet::Parser
+    root(:body)
+    rule(:body) { elements }
+    rule(:elements) { (call | element).repeat(2) }
+    rule(:element) { str('bar') }
+    rule(:call) { str('baz') >> str('()') }
+  end
+  
+  begin
+    P.new.parse('barbaz', reporter: Parslet::ErrorReporter::Deepest.new)
+  rescue Parslet::ParseFailed => error
+    puts error.cause.ascii_tree
+  end
+</code></pre>
+<p>Outputs:</p>
+<pre class="output"> 
+Expected at least 2 of CALL / ELEMENT at line 1 char 1.
+`- Expected one of [CALL, ELEMENT] at line 1 char 4.
+   |- Failed to match sequence ('baz' '()') at line 1 char 7.
+   |  `- Premature end of input at line 1 char 7.
+   `- Premature end of input at line 1 char 7.
+</pre>
+<p>The <code>'Deepest'</code> position engine will store errors that are the
+farthest into the input. In some examples, this produces more readable output
+for the end user.</p>
+<h2>Line numbers from parser output</h2>
+<p>A traditional parser would parse and then perform several checking phases,
+like for example verifying all type constraints are respected in the input.
+During this checking phase, you will most likely want to report screens full
+of type errors back to the user (‘cause that’s what types are for, right?).
+Now where did that ‘int’ come from?</p>
+<p>Parslet gives you slices (Parslet::Slice) of input as part of your tree. These
+are essentially strings with line numbers. Here’s how to print that error
+message:</p>
+<pre class="sh_ruby"><code>
+  # assume that type == "int"@0 - a piece from your parser output
+  line, col = type.line_and_column
+  puts "Sorry. Can't have #{type} at #{line}:#{col}!"
+</code></pre></div>
+      <div class="copyright"><p><span class="caps">MIT</span> License, 2010-2012, © <a href="http://absurd.li">Kaspar Schiess</a><br/>
+        Logo by <a href="http://floere.github.com">Florian Hanke</a>, <a href="http://creativecommons.org/licenses/by/1.0/">CC Attribution</a> license</p></div>
+      <script type="text/javascript">var _gaq = _gaq || [];
+        _gaq.push(['_setAccount', 'UA-16365074-2']);
+        _gaq.push(['_trackPageview']); 
+        (function() {
+          var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+          ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+          var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+        })();</script>
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/config.rb b/app/server/vendor/parslet/website/config.rb
new file mode 100755
index 0000000..723df71
--- /dev/null
+++ b/app/server/vendor/parslet/website/config.rb
@@ -0,0 +1,20 @@
+require 'slim'
+require 'tilt'
+require 'RedCloth'
+
+class NBRedClothTemplate < Tilt::RedClothTemplate
+  def prepare
+    super
+    @engine.hard_breaks = false
+  end
+end
+Tilt.register NBRedClothTemplate, 'textile'
+Tilt.prefer NBRedClothTemplate
+
+Slim::Engine.set_default_options :pretty => true
+
+set :textile, :layout_engine => :slim
+
+configure :build do
+  set :http_prefix, "/parslet/"
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/example_runner b/app/server/vendor/parslet/website/example_runner
new file mode 100755
index 0000000..c47dd53
--- /dev/null
+++ b/app/server/vendor/parslet/website/example_runner
@@ -0,0 +1,9 @@
+#!/usr/bin/env ruby
+
+require 'bundler/setup'
+
+$:.unshift File.expand_path(File.dirname(__FILE__) + "/lib")
+require 'prelude'
+require 'example_runner'
+
+ExampleRunner.new.run(ARGV)
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/lib/document.rb b/app/server/vendor/parslet/website/lib/document.rb
new file mode 100755
index 0000000..7de78b8
--- /dev/null
+++ b/app/server/vendor/parslet/website/lib/document.rb
@@ -0,0 +1,88 @@
+class Document
+  def initialize(name)
+    @name = name
+    @state = :outside
+    @line_count = 1
+  end
+  
+  def process
+    @target = Tempfile.new('erdoc')
+
+    File.open(@name, 'r') do |original|
+      while line = original.gets
+        consume(line.chomp)
+      end
+    end
+    
+    @target.close(false)
+    FileUtils.mv(@target.path, @name)
+  end
+  
+  def consume(line)
+    @line_count += 1
+    
+    a = lambda { |*args| Case::Array[*args] }
+    any = Case::Any
+    
+    case [@state, line]
+      when a[:outside, /<pre class="sh_ruby"><code title="(.*)">/]
+        @target.puts(line)
+        @state = :inside
+        extract_title(line)        
+      when a[:inside, %r(</code></pre>)]
+        @state = :outside
+        run_example
+        
+      when a[:outside, /<pre class="output">/]
+        @target.puts(line)
+        @state = :inside_old_output
+      when a[:inside_old_output, %r(</pre>)]
+        @target.puts(@last_output) if @last_output
+        @state = :outside
+
+      when a[:inside, any]
+        @example << line
+    else
+      # do nothing
+    end
+    
+    # Write lines outside a code block directly to target.
+    @target.puts(line) if @state == :outside
+  end
+  
+  def run_example
+    String.highlighter = Text::ANSIHighlighter.new
+    print " Running #@example... "
+    
+    if @example.skip?
+      puts "Skipped, no inspection points."
+      return
+    end
+    
+    # Prevent Ruby from buffering the script for too long. After a fork, 
+    # Ruby buffers become a problem. 
+    @target.flush
+    
+    unless @example.run
+      puts "error".red
+      @example.output[:err].lines.each { |line| 
+        print "   " + line.magenta }
+    else
+      puts 'ok.'.green
+      
+      # Stores last output for an eventual <pre class="output"> that might 
+      # come somewhere.
+      @last_output = @example.output[:out]
+    end
+    
+    @example.check_expectations
+
+    @target.puts @example.produce_modified_code
+    @example = nil
+  end
+  def extract_title(line)
+    if md=line.match(/title="(.*)"/)
+      @example = Example.new(md[1], @name, @line_count)
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/lib/example.rb b/app/server/vendor/parslet/website/lib/example.rb
new file mode 100755
index 0000000..b12253d
--- /dev/null
+++ b/app/server/vendor/parslet/website/lib/example.rb
@@ -0,0 +1,121 @@
+require 'tempfile'
+require 'cod'
+
+require 'site'
+require 'fail_site'
+
+class Example
+  def initialize(title, file, line)
+    @title = title
+    @file, @line = file, line
+    
+    @lines = []
+    
+    @sites = {}
+    @site_by_line = {}
+  end
+  
+  def to_s
+    "'#@title'"
+  end
+  
+  def <<(line)
+    @lines << line
+  end
+  
+  attr_reader :output
+  
+  def skip?
+    !@lines.grep(/# =>/)
+  end
+  
+  def run
+    # Create a tempfile per output
+    tempfiles = [:err, :out].inject({}) { |h, name| 
+      h[name] = Tempfile.new(name.to_s); h }
+    
+    # Where code results are communicated.  
+    $instrumentation = Cod.pipe
+    
+    code = produce_example_code
+    pid = fork do
+      redirect_streams(tempfiles)
+      # puts example_code
+      eval(code, nil, @file, @line-2) 
+    end
+    Process.wait(pid)
+
+    # Read these tempfiles.
+    @output = tempfiles.inject({}) { |h, (name, io)| 
+      io.rewind
+      h[name] = io.read; 
+      io.close 
+      h }
+            
+    loop do
+      begin
+        site_id, probe_value = $instrumentation.get
+      rescue Exception => ex
+        break if ex.message.match(/All pipe ends/)
+      end
+      fail "No such site #{site_id}." unless @sites.has_key?(site_id)
+
+      @sites[site_id].store probe_value
+    end
+    
+    $instrumentation.close; $instrumentation = nil
+
+    return $?.success?
+  end
+  
+  def redirect_streams(io_hash)
+    {
+      out: $stdout, 
+      err: $stderr
+    }.each do |name, io|
+      io.reopen(io_hash[name])
+    end
+  end
+  
+  def produce_example_code
+    root = File.expand_path(File.dirname(__FILE__))
+
+    '' <<
+      "$:.unshift #{root.inspect}\n" <<
+      "load 'prelude.rb'\n" <<
+      instrument(@lines).join("\n") <<
+      "\nload 'postscriptum.rb'\n"
+  end
+  def instrument(code)
+    code.map { |line| 
+      md = line.match(/(?<pre>.*)# (?<type>=>|raises) (?<expectation>.*)/) 
+      next line unless md
+      
+      if md[:type] == 'raises'
+        site = FailSite.new(line, md[:pre], md[:expectation].strip)
+      else
+        site = Site.new(line, md[:pre], md[:expectation].strip) 
+      end
+
+      add_site site
+      site.to_instrumented_line }
+  end
+  def add_site(site)
+    @sites[site.id] = site
+    @site_by_line[site.original_line] = site
+  end
+  
+  def produce_modified_code
+    @lines.map { |line| 
+      site = @site_by_line[line]
+      next line unless site 
+      
+      site.format_documentation_line }
+  end
+  
+  def check_expectations
+    @sites.each do |_, site|
+      site.check
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/lib/example_runner.rb b/app/server/vendor/parslet/website/lib/example_runner.rb
new file mode 100755
index 0000000..4ddba93
--- /dev/null
+++ b/app/server/vendor/parslet/website/lib/example_runner.rb
@@ -0,0 +1,19 @@
+
+require 'case'
+require 'text/highlight'
+
+require 'document'
+require 'example'
+
+class ExampleRunner
+  def run(args)
+    Dir[File.join(args.last, '*.textile')].each do |name|
+      puts name.white
+      Document.new(name).process
+    end
+  end
+end
+
+if $0 == __FILE__
+  ExampleRunner.new.run(ARGV)
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/lib/fail_site.rb b/app/server/vendor/parslet/website/lib/fail_site.rb
new file mode 100755
index 0000000..fa507b9
--- /dev/null
+++ b/app/server/vendor/parslet/website/lib/fail_site.rb
@@ -0,0 +1,34 @@
+require 'site'
+
+class FailSite < Site
+  def format_documentation_line
+    value_str = format_values
+    "#@code# raises #{value_str}"
+  end
+  def format_values
+    return 'NOT REACHED!' if @values.empty?
+    
+    v = @values.last
+    s = v.inspect
+    
+    s = s[1..-1]
+    
+    max_len = 60
+    s.size > max_len ? s[0,max_len] + '...' : s
+  end
+
+  def check
+    return true if !@expectation || @expectation.match(/^\s*$/)
+
+    str = format_values
+    if str != @expectation
+      puts "      #{@code.strip} # raises #{str.red}"
+      puts "      #{' '*@code.strip.size} # expected: #@expectation"
+    else
+      puts "      #{@code.strip} # raises #{str.green}"
+    end
+  end
+  def store(msg)
+    store_if(:raised, msg)
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/lib/postscriptum.rb b/app/server/vendor/parslet/website/lib/postscriptum.rb
new file mode 100755
index 0000000..96b3865
--- /dev/null
+++ b/app/server/vendor/parslet/website/lib/postscriptum.rb
@@ -0,0 +1 @@
+Process.waitall
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/lib/prelude.rb b/app/server/vendor/parslet/website/lib/prelude.rb
new file mode 100755
index 0000000..b142f6d
--- /dev/null
+++ b/app/server/vendor/parslet/website/lib/prelude.rb
@@ -0,0 +1,2 @@
+require 'parslet'
+include Parslet
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/lib/site.rb b/app/server/vendor/parslet/website/lib/site.rb
new file mode 100755
index 0000000..43fd155
--- /dev/null
+++ b/app/server/vendor/parslet/website/lib/site.rb
@@ -0,0 +1,56 @@
+class Site
+  attr_reader :original_line
+  
+  def initialize(original_line, code, expectation)
+    @original_line = original_line
+    @code = code
+    @expectation = expectation
+    @values = []
+  end
+  def id
+    object_id
+  end
+  
+  def to_instrumented_line
+    "begin "+
+      "(#@code).tap { |o| $instrumentation.put [#{id}, [:ok, o]] }; "+
+    "rescue Exception => exception; "+
+      "$instrumentation.put [#{id}, [:raised, exception]];"+
+      "raise;"+
+    "end"
+  end
+  
+  def format_documentation_line
+    value_str = format_values
+    "#@code# => #{value_str}"
+  end
+  def format_values
+    return 'NOT REACHED!' if @values.empty?
+    
+    v = @values.size == 1 ? @values.first : @values
+    s = v.inspect
+    
+    max_len = 60 - 3
+    s.size > max_len ? s[0,max_len] + '...' : s
+  end
+  def check
+    return true if !@expectation || @expectation.match(/^\s*$/)
+
+    str = format_values
+    if str != @expectation
+      puts "      #{@code.strip} # => #{str.red}"
+      puts "      #{' '*@code.strip.size} # expected: #@expectation"
+    else
+      puts "      #{@code.strip} # => #{str.green}"
+    end
+  end
+  def store(msg)
+    store_if(:ok, msg)
+  end
+  
+private
+  def store_if(cond, msg)
+    code, value = msg 
+    @values << value if code == cond
+  end
+end
diff --git a/app/server/vendor/parslet/website/publish-gh-pages.sh b/app/server/vendor/parslet/website/publish-gh-pages.sh
new file mode 100755
index 0000000..f5c1b8a
--- /dev/null
+++ b/app/server/vendor/parslet/website/publish-gh-pages.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+doc_sha=$(git ls-tree -d HEAD build | awk '{print $3}')
+git cat-file -p $doc_sha
+new_commit=$(echo "Auto-update docs." | git commit-tree $doc_sha -p gh-pages)
+git update-ref refs/heads/gh-pages $new_commit
diff --git a/app/server/vendor/parslet/website/source/contribute.html.textile b/app/server/vendor/parslet/website/source/contribute.html.textile
new file mode 100755
index 0000000..df54a89
--- /dev/null
+++ b/app/server/vendor/parslet/website/source/contribute.html.textile
@@ -0,0 +1,110 @@
+---
+title: Contribute
+---
+
+Find parslet to be really useful? Or just found a bug that is really ruining
+the day for you? Please contribute! Find the code on 
+"github":http://github.com/kschiess/parslet.
+
+h2. Contact
+
+Join us on IRC in #parslet on irc.freenode.net.
+
+Discussion and patches (or the odd cry for 'Help! How can I parse X?') should
+go to our mailing list at
+"ruby.parslet at librelist.com":mailto:ruby.parslet at librelist.com. Just write a
+short message to that address and "librelist":http://librelist.com will
+subscribe you. NNTP/web interface can be had through
+"gmane.org":http://dir.gmane.org/gmane.comp.lang.ruby.parslet:
+<code>gmane.comp.lang.ruby.parslet</code>.
+
+h2. Bugs 
+
+Log in to github and open a bug ticket
+"here":https://github.com/kschiess/parslet/issues. Please be sure to include
+the version of parslet and Ruby; maybe you can even provide some code that
+exhibits the bug?
+
+And of course if you provide a properly tested patch, you'll be our hero and 
+get a place in the space below for lifetime. 
+
+h2. Projects
+
+Have you got a project that uses parslet? Please write
+"us":mailto:kaspar.schiess at absurd.li about it. 
+
+"*edn-ruby*":https://github.com/relevance/edn-ruby
+
+edn-ruby is a Ruby library to read and write "edn":https://github.com/edn-format/edn 
+(extensible data notation), a subset of Clojure used for transferring data between 
+applications, much like JSON, YAML, or XML.
+
+"*Examples*":https://github.com/kschiess/parslet/tree/master/example/
+
+In here, you can find a parser for a lisp like language and much more. 
+
+"*Net::HTTP::Server*":https://github.com/postmodern/net-http-server
+
+A really small and elegant HTTP server written in Ruby. Think Webrick. Using
+parslet. (Postmodern)
+
+"*regexador*":https://github.com/Hal9000/regexador
+
+An external DSL for Ruby that tries to make regular expressions readable and maintainable. (Hal Fulton)
+
+"*self-ml*":https://github.com/self-ml/selfml
+
+A "self-ml":http://self-ml.github.io/ implementation using parslet. 
+(Ricardo Mendes)
+
+"*thnad*":https://github.com/undees/thnad 
+
+Thnad is a tiny programming language with so few features that it is not
+useful for anything at all -- except showing how to write a compiler in half
+an hour.
+
+"*Werd.rb*":https://github.com/rk/werd
+
+A variant of Chris Pound's word generator written in Ruby, with some
+improvements. (Robert Kosek)
+
+"*versionub*":https://github.com/meh/versionub
+
+A semantic version parser. (meh)
+
+h2. Thanks for all the fish -- Contributions
+
+* *Rory O’Kane* ("roryokane":https://github.com/roryokane) for a careful code 
+  review!
+
+* *Zach Moazeni* ("zmoazeni":https://github.com/zmoazeni) for his work on
+  Unicode performance.
+
+* *rogerbraun* ("rogerbraun":https://github.com/rogerbraun) for being my
+  unicode tester. 
+
+* *meh* ("meh":http://meh.paranoid.pk/) for taking a real close look. 
+
+* *John Mettraux* ("jmettraux":http://jmettraux.wordpress.com/) for the really
+  nice JSON example and for pushing parslet beyond its limits.
+
+* *Josep M. Bach* ("txus":http://www.txustice.me/) for minding the small 
+  things that make a big difference.
+
+* *Matthew Draper* ("matthewd":http://matthewd.net/) for bothering with my 
+  broken CSS.
+
+* *Hal Brodigan* ("postmodern":http://postmodern.github.com/) for solving our
+  email parsing needs!
+
+* *R. Konstantin Haase* ("rhk":http://rkh.im/) for rspec matchers that help
+  stamp out, eliminate and abolish redundancy.
+
+* *Florian Hanke* ("floere":http://floere.github.com) has given a lot of very
+  inspiring input for parslet. His questions have been key to rounding off the
+  corners and making the library as aesthetic as it is. And just look at the 
+  logo. 
+  
+* *Kaspar Schiess* ("absurd.li":http://www.absurd.li) for being brave enough
+  to actually add another parser library to a field that's already bursting
+  at the seams.
diff --git a/app/server/vendor/parslet/website/source/documentation.html.textile b/app/server/vendor/parslet/website/source/documentation.html.textile
new file mode 100755
index 0000000..f865bc2
--- /dev/null
+++ b/app/server/vendor/parslet/website/source/documentation.html.textile
@@ -0,0 +1,60 @@
+---
+title: Documentation
+---
+
+"*Getting Started*":get-started.html
+
+Are you brand new to parslet? Well then let's introduce you guys. This is what
+you should read and try out first. 
+
+"*Examples*":https://github.com/kschiess/parslet/tree/master/example/
+
+Parslet comes with a lot of examples that explain how to use various aspects. 
+Take a look at those. 
+
+"*In depth*":overview.html
+
+This is the real technical documentation, showing you how to use all aspects
+of parslet. Especially: 
+
+* "Overview":overview.html explains parslet's goals and gives you a bigger
+  picture.
+* Using "Parslet::Parser":parser.html to *write parsers*.
+* Using "Parslet::Transform":transform.html to *transmogrify your intermediary
+  trees*.
+* "Tricks":tricks.html for common situations.
+
+*Presentations*
+
+* "Parslet, An Introduction":https://docs.google.com/present/view?id=0AfXgUAUtzyc7ZGZrcG1mNXNfMzIwZ3JjY2c3NW0 introduces parslet in a few poignant slides. (Bo Jeanes and David Pick)
+
+*Videos*
+
+* "Writing DSL's with Parslet":http://www.confreaks.com/videos/2730-wickedgoodruby-writing-dsl-s-with-parslet Talk given by Jason Garber at the Wicked Good Ruby Conference 2013.
+
+*Blogs*
+
+* "Parslet Intro":http://florianhanke.com/blog/2011/02/01/parslet-intro.html
+  explains quite a few things on how parsers work and on parser
+  metaprogramming. Besides, Florian Hanke also explains how to create an ERB
+  parser in just a few lines!
+  
+* "Parslet and
+  JSON":http://jmettraux.wordpress.com/2011/05/11/parslet-and-json/ shows how
+  to construct a JSON parser in a few lines.
+  "John":http://jmettraux.wordpress.com/about/ does a great job of explaining
+  how parslet ties back in with railroad diagrams.
+
+* "Parsing TOML in Ruby with Parslet":http://zerowidth.com/2013/02/24/parsing-toml-in-ruby-with-parslet.html
+  shows how to parse TOML ("Tom's Obvious Minimal Language":https://github.com/mojombo/toml)
+  using parslet. I sense a theme here. Code is on github - this is the first
+  article in a series, linked from the article.
+
+* "Write You a Parser for Fun and Win":http://viget.com/extend/write-you-a-parser-for-fun-and-win
+  a succinct writeup on parsing text formats by David Eisinger.
+ 
+"*YARD Class Documentation*":http://rubydoc.info/gems/parslet/frames
+
+The "YARD documentation":http://rubydoc.info/gems/parslet/frames will help you
+with the nitty gritty. This documentation is real important too. It will be
+constantly improved! (Thanks linode.com and DockYard for sponsoring this tool.)
diff --git a/app/server/vendor/parslet/website/source/get-started.html.textile b/app/server/vendor/parslet/website/source/get-started.html.textile
new file mode 100755
index 0000000..a09ac23
--- /dev/null
+++ b/app/server/vendor/parslet/website/source/get-started.html.textile
@@ -0,0 +1,361 @@
+---
+title: Get Started
+---
+
+Let's develop a small language that allows for simple computation together. 
+Here's a valid input file for that language: 
+
+<pre class="sh_ruby"><code> 
+  puts(1 + 2)
+  puts(4 + 2)
+</code></pre>
+
+To install the parslet library, please do a 
+
+<pre><code> 
+  gem install parslet
+</code></pre>
+
+Now let's write the first part of our parser. For now, we'll just recognize
+simple numbers like '1' or '42'.
+
+<pre class="sh_ruby"><code title="mini_parser"> 
+  require 'parslet' 
+
+  class Mini < Parslet::Parser
+    rule(:integer) { match('[0-9]').repeat(1) }
+    root(:integer)
+  end
+
+  Mini.new.parse("132432")  # => "132432"@0
+</code></pre>
+
+Running this example will print "132432 at 0". Congratulations! You just have
+written your first parser. Running it on the input '<code>puts(1)</code>' will
+not work yet. Let's see what happens in case of a failure:
+
+<pre class="sh_ruby"><code> 
+  Mini.new.parse("puts(1)") # raises Parslet::ParseFailed
+</code></pre>
+
+Here's the error message provided by that exception: "Expected at least 1 of
+[0-9] at line 1 char 1." parslet tries to find a number there, but can't find
+one.
+
+There are just two lines to the definition of this parser, let's go through
+them:
+
+<pre class="sh_ruby"><code> 
+  rule(:integer) { match('[0-9]').repeat(1) }
+</code></pre>
+
+<code>rule</code> lets you create a new parser rule. Inside the block of that
+<code>:integer</code> rule, you find <code>match('[0-9]').repeat(1)</code>.
+This says: "match a character that is in the range <code>0-9</code>, then
+match any number of those, but at least match one."
+
+<pre class="sh_ruby"><code> 
+  root(:integer)
+</code></pre>
+
+That second line just says: Start parsing at the rule called
+<code>:integer</code>.
+
+h2. Addition
+
+Let's go for simple addition. We'll have to allow for spaces in our input,
+since those help make code readable. 
+
+<pre class="sh_ruby"><code> 
+  rule(:space)  { match('\s').repeat(1) }
+  rule(:space?) { space.maybe }
+</code></pre>
+
+Two things are new here: (and both in the second line)
+
+* you can use ('call') other rules in your rules 
+* <code>.maybe</code>, the same as <code>.repeat(0,1)</code>[1], indicating 
+  that the thing before it is maybe present once in the input.
+  
+Essentially, you can think about parslet rules as instructing Ruby to "parse
+this" and "parse that". Calling other rules can be looked at in the same way;
+you tell Ruby to go off, parse that subrule and then come back with the
+results. This helps when thinking about rule recursion. For example, a
+self-recursive rule like this one will of course create an endless loop:
+
+<pre class="sh_ruby"><code> 
+  rule(:infinity) {
+    infinity >> str(';')
+  }
+</code></pre>
+
+Even though infinity seems to be delimited by ';', in reality, infinity is
+very long, especially towards the end. There is no way of knowing for the
+parser when to stop processing <code>infinity</code> and start reading
+semicolons. Ergo, we need to make sure we talk about concrete items that
+consume input first, and then do recursion. This way we ensure that our
+grammar terminates, since in a way, it is like a normal program.
+
+Here's the full parser:
+
+<pre class="sh_ruby"><code title="full_parser">  
+  class Mini < Parslet::Parser
+    rule(:integer)    { match('[0-9]').repeat(1) >> space? }
+  
+    rule(:space)      { match('\s').repeat(1) }
+    rule(:space?)     { space.maybe }
+  
+    rule(:operator)   { match('[+]') >> space? }
+  
+    rule(:sum)        { integer >> operator >> expression }
+    rule(:expression) { sum | integer }
+
+    root :expression
+  end
+
+  def parse(str)
+    mini = Mini.new
+  
+    mini.parse(str)
+  rescue Parslet::ParseFailed => failure
+    puts failure.cause.ascii_tree
+  end
+
+  parse "1 + 2 + 3"  # => "1 + 2 + 3"@0
+  parse "a + 2"      # fails, see below
+</code></pre>
+
+As you can see, the parser got decorated with the <code>space?</code> idiom.
+Every atom of our language consumes the space right after it. This is a useful
+convention that makes top level rules (the important ones) look cleaner.
+
+Note also the addition of <code>:operator</code>, <code>:sum</code> and
+<code>:expression</code>. The runner code has been extended a bit, so as to
+throw nice explanations of what went wrong when a parse failure is
+encountered. Running the code on '<code>a + 2</code>' for example outputs:
+
+<pre class="output">  
+Expected one of [SUM, INTEGER] at line 1 char 1.
+|- Failed to match sequence (INTEGER OPERATOR EXPRESSION) at line 1 char 1.
+|  `- Failed to match sequence ([0-9]{1, } SPACE?) at line 1 char 1.
+|     `- Expected at least 1 of [0-9] at line 1 char 1.
+|        `- Failed to match [0-9] at line 1 char 1.
+`- Failed to match sequence ([0-9]{1, } SPACE?) at line 1 char 1.
+   `- Expected at least 1 of [0-9] at line 1 char 1.
+      `- Failed to match [0-9] at line 1 char 1.
+</pre>
+
+This is what parslet calls an <code>#error_tree</code>. Not only the output of
+your parser, but also its grammar is constructed like a tree. When things go
+wrong, every branch of the tree has its own reasons for not accepting a given
+input. The <code>#cause</code> method returns those reasons.
+
+Our grammar has essentially two branches, <code>SUM</code> and
+<code>INTEGER</code>. Can you see why all rules expect a number as the first
+character?
+
+h2. Tree output (and what to do about it)
+
+But if we leave the negative examples for a second; what happens if the parse
+succeeds? It turns out, not much: 
+
+<pre class="sh_ruby"><code>
+  parse "1 + 2 + 3"  # => "1 + 2 + 3"@0
+</code></pre>
+
+The only notable difference between input and output is that the output has an
+extra '@0' appended to it. This is related to line number tracking and will be
+explained later on (or you can skip ahead and look up
+<code>Parslet::Slice</code>).
+
+The code we now have parses the input successfully, but doesn't do much else. 
+Parslet hasn't got its own opinion on what to do with your input. By default, 
+it will just play it back to you. But parslet provides also a method of 
+structuring its output: 
+
+<pre class="sh_ruby"><code title="output_samples"> 
+  # Without structure: just strings.
+  str('ooo').parse('ooo')                           # => "ooo"@0
+  str('o').repeat.parse('ooo')                      # => "ooo"@0
+
+  # Added structure: .as(...)
+  str('ooo').as(:ex1).parse('ooo')                  # => {:ex1=>"ooo"@0}
+  
+  long = str('o').as(:ex2a).repeat.as(:ex2b).parse('ooo')  
+  long # => {:ex2b=>[{:ex2a=>"o"@0}, {:ex2a=>"o"@1}, {:ex2a=>"o"@2}]}
+</code></pre>
+
+You get to name things the way you want! This is also free. Seriously: parslet
+requires you to add all the structure to its output. Annotate important parts
+of your grammar with <code>.as(:symbol)</code> and get back a tree-like
+structure composed of hashes (sequence), arrays (repetition) and strings (like
+we had initially).
+
+Once you start naming things, you'll notice that what you don't name,
+disappears. Parslet assumes that _what you don't name is unimportant_.
+
+<pre class="sh_ruby"><code title="inline_parser"> 
+parser =  str('a').as(:a) >> str(' ').maybe >> 
+          str('+').as(:o) >> str(' ').maybe >> 
+          str('b').as(:b)
+parser.parse('a + b') # => {:a=>"a"@0, :o=>"+"@2, :b=>"b"@4}
+</code></pre>
+
+Think of this like using a highlighter on your input: What is there not to
+like about neon yellow?
+
+h2. Making the parser complete
+
+Let's look at the complete parser definition that also allows for function
+calls:
+
+<pre class="sh_ruby"><code title="full_parser"> 
+class MiniP < Parslet::Parser
+  # Single character rules
+  rule(:lparen)     { str('(') >> space? }
+  rule(:rparen)     { str(')') >> space? }
+  rule(:comma)      { str(',') >> space? }
+
+  rule(:space)      { match('\s').repeat(1) }
+  rule(:space?)     { space.maybe }
+
+  # Things
+  rule(:integer)    { match('[0-9]').repeat(1).as(:int) >> space? }
+  rule(:identifier) { match['a-z'].repeat(1) }
+  rule(:operator)   { match('[+]') >> space? }
+  
+  # Grammar parts
+  rule(:sum)        { integer.as(:left) >> operator.as(:op) >> expression.as(:right) }
+  rule(:arglist)    { expression >> (comma >> expression).repeat }
+  rule(:funcall)    { identifier.as(:funcall) >> lparen >> arglist.as(:arglist) >> rparen }
+  
+  rule(:expression) { funcall | sum | integer }
+  root :expression
+end
+
+require 'pp'
+pp MiniP.new.parse("puts(1 + 2 + 3, 45)")
+</code></pre>
+
+That's really all there is to it -- our language is a really simple language. 
+When fed with a string like '<code>puts(1 + 2 + 3, 45)</code>, our parser outputs
+the following: 
+
+<pre class="output"> 
+{:funcall=>"puts"@0,
+ :arglist=>
+  [{:left=>{:int=>"1"@5},
+    :op=>"+ "@7,
+    :right=>{:left=>{:int=>"2"@9}, :op=>"+ "@11, :right=>{:int=>"3"@13}}},
+   {:int=>"45"@16}]}
+</code></pre>
+
+Parslet calls this the _intermediary tree_. There are three types of nodes in
+this tree:
+
+* *Hashes*: a node that has named subtrees
+* *Arrays*: a node storing a collection of sub-nodes
+* *Strings* are the leaves, containing the _accepted source_
+
+The format of this tree is easy to work with and to read. Here's what the
+above tree would look like as a graphic:
+
+!images/ast.png!
+
+h2. Where to go from here: An Interpreter
+
+As nice as the format above is for printing and looking at - it may be
+difficult at times to get the information out of it again. Let's look at how
+to transform the tree:
+
+<pre class="sh_ruby"><code> 
+class SimpleTransform < Parslet::Transform
+  rule(funcall: 'puts', arglist: sequence(:args)) {
+    "puts(#{args.inspect})"
+  }
+  # ... other rules
+end
+
+tree = {funcall: 'puts', arglist: [1,2,3]}
+SimpleTransform.new.apply(tree) # => "puts([1, 2, 3])"
+</code></pre>
+
+Transformation is an entire topic by itself; this will be covered in detail
+"later on":transform.html. To whet your appetite, let me just give you a few
+teasers:
+
+* Transformations match portions of your tree at any depth, replacing them
+  with whatever you decide.
+* In addition to <code>sequence(sym)</code>, there is also
+  <code>simple(sym)</code> and <code>subtree(sym)</code>. Those match simple
+  strings and entire subtrees respectively. Caution with the latter.
+
+Here's how you would write a somewhat classical interpreter for our little 
+language by using a transformation. Note that from this point on, there is
+not one way to go about this, but thousands; you are really free (and on
+your own): 
+
+<pre class="sh_ruby"><code title="putting it all together"> 
+class MiniP < Parslet::Parser
+  # Single character rules
+  rule(:lparen)     { str('(') >> space? }
+  rule(:rparen)     { str(')') >> space? }
+  rule(:comma)      { str(',') >> space? }
+
+  rule(:space)      { match('\s').repeat(1) }
+  rule(:space?)     { space.maybe }
+
+  # Things
+  rule(:integer)    { match('[0-9]').repeat(1).as(:int) >> space? }
+  rule(:identifier) { match['a-z'].repeat(1) }
+  rule(:operator)   { match('[+]') >> space? }
+  
+  # Grammar parts
+  rule(:sum)        { 
+    integer.as(:left) >> operator.as(:op) >> expression.as(:right) }
+  rule(:arglist)    { expression >> (comma >> expression).repeat }
+  rule(:funcall)    { 
+    identifier.as(:funcall) >> lparen >> arglist.as(:arglist) >> rparen }
+  
+  rule(:expression) { funcall | sum | integer }
+  root :expression
+end
+
+class IntLit   < Struct.new(:int)
+  def eval; int.to_i; end
+end
+class Addition < Struct.new(:left, :right) 
+  def eval; left.eval + right.eval; end
+end
+class FunCall < Struct.new(:name, :args); 
+  def eval
+    p args.map { |s| s.eval }
+  end
+end
+
+class MiniT < Parslet::Transform
+  rule(:int => simple(:int))        { IntLit.new(int) }
+  rule(
+    :left => simple(:left), 
+    :right => simple(:right), 
+    :op => '+')                     { Addition.new(left, right) }
+  rule(
+    :funcall => 'puts', 
+    :arglist => subtree(:arglist))  { FunCall.new('puts', arglist) }
+end
+
+parser = MiniP.new
+transf = MiniT.new
+
+ast = transf.apply(
+  parser.parse(
+    'puts(1,2,3, 4+5)'))
+        
+ast.eval # => [1, 2, 3, 9]
+</code></pre>
+
+That's a bunch of code for printing <code>[1, 2, 3, 9]</code>. Welcome to the
+fantastic world of compiler and interpreter writing!
+
+[1] As far as parsing goes. There is a subtle difference between
+<code>#repeat(0,1)</code> and <code>#maybe</code>. Can you figure it out?
diff --git a/app/server/vendor/parslet/website/source/images/ast.png b/app/server/vendor/parslet/website/source/images/ast.png
new file mode 100755
index 0000000..c0a3443
Binary files /dev/null and b/app/server/vendor/parslet/website/source/images/ast.png differ
diff --git a/app/server/vendor/parslet/website/source/images/favicon1.ico b/app/server/vendor/parslet/website/source/images/favicon1.ico
new file mode 100755
index 0000000..500b9e7
Binary files /dev/null and b/app/server/vendor/parslet/website/source/images/favicon1.ico differ
diff --git a/app/server/vendor/parslet/website/source/images/favicon2.ico b/app/server/vendor/parslet/website/source/images/favicon2.ico
new file mode 100755
index 0000000..57fc370
Binary files /dev/null and b/app/server/vendor/parslet/website/source/images/favicon2.ico differ
diff --git a/app/server/vendor/parslet/website/source/images/favicon3.ico b/app/server/vendor/parslet/website/source/images/favicon3.ico
new file mode 100755
index 0000000..c016837
Binary files /dev/null and b/app/server/vendor/parslet/website/source/images/favicon3.ico differ
diff --git a/app/server/vendor/parslet/website/source/images/parsley_logo.png b/app/server/vendor/parslet/website/source/images/parsley_logo.png
new file mode 100755
index 0000000..7baefe9
Binary files /dev/null and b/app/server/vendor/parslet/website/source/images/parsley_logo.png differ
diff --git a/app/server/vendor/parslet/website/source/index.html.textile b/app/server/vendor/parslet/website/source/index.html.textile
new file mode 100755
index 0000000..fdc6009
--- /dev/null
+++ b/app/server/vendor/parslet/website/source/index.html.textile
@@ -0,0 +1,38 @@
+---
+layout: layout
+title: About
+---
+
+
+<pre class="sh_ruby"><code>
+  require 'parslet'
+  include Parslet
+
+  # Constructs a parser using a Parser Expression Grammar 
+  parser =  str('"') >> 
+            (
+              str('\\') >> any |
+              str('"').absent? >> any
+            ).repeat.as(:string) >> 
+            str('"')
+
+  result = parser.parse %Q("this is a valid string") 
+  result # => {:string=>"this is a valid string"@1}
+</code></pre>
+
+A small Ruby library for constructing parsers in the
+"PEG":http://en.wikipedia.org/wiki/Parsing_expression_grammar (Parsing
+Expression Grammar) fashion.
+
+
+Parslet makes developing complex parsers easy. It does so by
+
+* providing the best *error reporting* possible
+* *not generating* reams of code for you to debug
+
+Parslet takes the long way around to make *your job* easier. It allows for
+incremental language construction. Often, you start out small, implementing
+the atoms of your language first; _parslet_ takes pride in making this
+possible. 
+
+Eager to try this out? "Get started":get-started.html!
diff --git a/app/server/vendor/parslet/website/source/install.html.textile b/app/server/vendor/parslet/website/source/install.html.textile
new file mode 100755
index 0000000..424d4e4
--- /dev/null
+++ b/app/server/vendor/parslet/website/source/install.html.textile
@@ -0,0 +1,23 @@
+---
+title: Install
+---
+
+Parslet is at version _1.5.0_. 
+
+*Rubygems*
+
+<pre>
+  gem install parslet
+</pre>
+
+*Bundler*
+
+<pre>
+  gem 'parslet', '~> 1.5'
+</pre>
+
+or if you want to track the edge: 
+
+<pre>
+  gem 'parslet', :git => 'git://github.com/kschiess/parslet.git'
+</pre>
diff --git a/app/server/vendor/parslet/website/source/javascripts/sh_main.min.js b/app/server/vendor/parslet/website/source/javascripts/sh_main.min.js
new file mode 100755
index 0000000..31d1ba0
--- /dev/null
+++ b/app/server/vendor/parslet/website/source/javascripts/sh_main.min.js
@@ -0,0 +1,4 @@
+/* Copyright (C) 2007, 2008 gnombat at users.sourceforge.net */
+/* License: http://shjs.sourceforge.net/doc/gplv3.html */
+
+if(!this.sh_languages){this.sh_languages={}}var sh_requests={};function sh_isEmailAddress(a){if(/^mailto:/.test(a)){return false}return a.indexOf("@")!==-1}function sh_setHref(b,c,d){var a=d.substring(b[c-2].pos,b[c-1].pos);if(a.length>=2&&a.charAt(0)==="<"&&a.charAt(a.length-1)===">"){a=a.substr(1,a.length-2)}if(sh_isEmailAddress(a)){a="mailto:"+a}b[c-2].node.href=a}function sh_konquerorExec(b){var a=[""];a.index=b.length;a.input=b;return a}function sh_highlightString(B,o){if(/Konqueror/.test(navigator.userAgent)){if(!o.konquered){for(var F=0;F<o.length;F++){for(var H=0;H<o[F].length;H++){var G=o[F][H][0];if(G.source==="$"){G.exec=sh_konquerorExec}}}o.konquered=true}}var N=document.createElement("a");var q=document.createElement("span");var A=[];var j=0;var n=[];var C=0;var k=null;var x=function(i,a){var p=i.length;if(p===0){return}if(!a){var Q=n.length;if(Q!==0){var r=n[Q-1];if(!r[3]){a=r[1]}}}if(k!==a){if(k){A[j++]={pos:C};if(k==="sh_url"){sh_setHref(A,j,B)}}if(a){var P;if(a==="sh_url"){P=N.cloneNode(false)}else{P=q.cloneNode(false)}P.className=a;A[j++]={node:P,pos:C}}}C+=p;k=a};var t=/\r\n|\r|\n/g;t.lastIndex=0;var d=B.length;while(C<d){var v=C;var l;var w;var h=t.exec(B);if(h===null){l=d;w=d}else{l=h.index;w=t.lastIndex}var g=B.substring(v,l);var M=[];for(;;){var I=C-v;var D;var y=n.length;if(y===0){D=0}else{D=n[y-1][2]}var O=o[D];var z=O.length;var m=M[D];if(!m){m=M[D]=[]}var E=null;var u=-1;for(var K=0;K<z;K++){var f;if(K<m.length&&(m[K]===null||I<=m[K].index)){f=m[K]}else{var c=O[K][0];c.lastIndex=I;f=c.exec(g);m[K]=f}if(f!==null&&(E===null||f.index<E.index)){E=f;u=K;if(f.index===I){break}}}if(E===null){x(g.substring(I),null);break}else{if(E.index>I){x(g.substring(I,E.index),null)}var e=O[u];var J=e[1];var b;if(J instanceof Array){for(var L=0;L<J.length;L++){b=E[L+1];x(b,J[L])}}else{b=E[0];x(b,J)}switch(e[2]){case -1:break;case -2:n.pop();break;case -3:n.length=0;break;default:n.push(e);break}}}if(k){A[j++]={pos:C};if(k==="sh_url"){sh_setHref(A,j,B)}k=null}C=w}return A}function sh_getClasses(d){var a=[];var b=d.className;if(b&&b.length>0){var e=b.split(" ");for(var c=0;c<e.length;c++){if(e[c].length>0){a.push(e[c])}}}return a}function sh_addClass(c,a){var d=sh_getClasses(c);for(var b=0;b<d.length;b++){if(a.toLowerCase()===d[b].toLowerCase()){return}}d.push(a);c.className=d.join(" ")}function sh_extractTagsFromNodeList(c,a){var f=c.length;for(var d=0;d<f;d++){var e=c.item(d);switch(e.nodeType){case 1:if(e.nodeName.toLowerCase()==="br"){var b;if(/MSIE/.test(navigator.userAgent)){b="\r"}else{b="\n"}a.text.push(b);a.pos++}else{a.tags.push({node:e.cloneNode(false),pos:a.pos});sh_extractTagsFromNodeList(e.childNodes,a);a.tags.push({pos:a.pos})}break;case 3:case 4:a.text.push(e.data);a.pos+=e.length;break}}}function sh_extractTags(c,b){var a={};a.text=[];a.tags=b;a.pos=0;sh_extractTagsFromNodeList(c.childNodes,a);return a.text.join("")}function sh_mergeTags(d,f){var a=d.length;if(a===0){return f}var c=f.length;if(c===0){return d}var i=[];var e=0;var b=0;while(e<a&&b<c){var h=d[e];var g=f[b];if(h.pos<=g.pos){i.push(h);e++}else{i.push(g);if(f[b+1].pos<=h.pos){b++;i.push(f[b]);b++}else{i.push({pos:h.pos});f[b]={node:g.node.cloneNode(false),pos:h.pos}}}}while(e<a){i.push(d[e]);e++}while(b<c){i.push(f[b]);b++}return i}function sh_insertTags(k,h){var g=document;var l=document.createDocumentFragment();var e=0;var d=k.length;var b=0;var j=h.length;var c=l;while(b<j||e<d){var i;var a;if(e<d){i=k[e];a=i.pos}else{a=j}if(a<=b){if(i.node){var f=i.node;c.appendChild(f);c=f}else{c=c.parentNode}e++}else{c.appendChild(g.createTextNode(h.substring(b,a)));b=a}}return l}function sh_highlightElement(d,g){sh_addClass(d,"sh_sourceCode");var c=[];var e=sh_extractTags(d,c);var f=sh_highlightString(e,g);var b=sh_mergeTags(c,f);var a=sh_insertTags(b,e);while(d.hasChildNodes()){d.removeChild(d.firstChild)}d.appendChild(a)}function sh_getXMLHttpRequest(){if(window.ActiveXObject){return new ActiveXObject("Msxml2.XMLHTTP")}else{if(window.XMLHttpRequest){return new XMLHttpRequest()}}throw"No XMLHttpRequest implementation available"}function sh_load(language,element,prefix,suffix){if(language in sh_requests){sh_requests[language].push(element);return}sh_requests[language]=[element];var request=sh_getXMLHttpRequest();var url=prefix+"sh_"+language+suffix;request.open("GET",url,true);request.onreadystatechange=function(){if(request.readyState===4){try{if(!request.status||request.status===200){eval(request.responseText);var elements=sh_requests[language];for(var i=0;i<elements.length;i++){sh_highlightElement(elements[i],sh_languages[language])}}else{throw"HTTP error: status "+request.status}}finally{request=null}}};request.send(null)}function sh_highlightDocument(g,k){var b=document.getElementsByTagName("pre");for(var e=0;e<b.length;e++){var f=b.item(e);var a=sh_getClasses(f);for(var c=0;c<a.length;c++){var h=a[c].toLowerCase();if(h==="sh_sourcecode"){continue}if(h.substr(0,3)==="sh_"){var d=h.substring(3);if(d in sh_languages){sh_highlightElement(f,sh_languages[d])}else{if(typeof(g)==="string"&&typeof(k)==="string"){sh_load(d,f,g,k)}else{throw'Found <pre> element with class="'+h+'", but no such language exists'}}break}}}};
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/source/javascripts/sh_ruby.min.js b/app/server/vendor/parslet/website/source/javascripts/sh_ruby.min.js
new file mode 100755
index 0000000..30928e6
--- /dev/null
+++ b/app/server/vendor/parslet/website/source/javascripts/sh_ruby.min.js
@@ -0,0 +1 @@
+if(!this.sh_languages){this.sh_languages={}}sh_languages.ruby=[[[/\b(?:require)\b/g,"sh_preproc",-1],[/\b[+-]?(?:(?:0x[A-Fa-f0-9]+)|(?:(?:[\d]*\.)?[\d]+(?:[eE][+-]?[\d]+)?))u?(?:(?:int(?:8|16|32|64))|L)?\b/g,"sh_number",-1],[/"/g,"sh_string",1],[/'/g,"sh_string",2],[/</g,"sh_string",3],[/\/[^\n]*\//g,"sh_regexp",-1],[/(%r)(\{(?:\\\}|#\{[A-Za-z0-9]+\}|[^}])*\})/g,["sh_symbol","sh_regexp"],-1],[/\b(?:alias|begin|BEGIN|break|case|defined|do|else|elsif|end|END|ensure|for|if|in|include|loop|next|raise|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield|false|nil|self|true|__FILE__|__LINE__|and|not|or|def|class|module|catch|fail|load|throw)\b/g,"sh_keyword",-1],[/(?:^\=begin)/g,"sh_comment",4],[/(?:\$[#]?|@@|@)(?:[A-Za-z0-9_]+|'|\"|\/)/g,"sh_type",-1],[/[A-Za-z0-9]+(?:\?|!)/g,"sh_normal",-1],[/~|!|%|\^|\*|\(|\)|-|\+|=|\[|\]|\\|:|;|,|\.|\/|\?|&|<|>|\|/g,"sh_symbol",-1],[/(#)(\{)/g,["sh_symbol","sh_cbracket"],-1],[/#/g,"sh_comment",5],[/\{|\}/g,"sh_cbracket",-1]],[[/$/g,null,-2],[/\\(?:\\|")/g,null,-1],[/"/g,"sh_string",-2]],[[/$/g,null,-2],[/\\(?:\\|')/g,null,-1],[/'/g,"sh_string",-2]],[[/$/g,null,-2],[/>/g,"sh_string",-2]],[[/^(?:\=end)/g,"sh_comment",-2]],[[/$/g,null,-2]]];
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/source/layout.slim b/app/server/vendor/parslet/website/source/layout.slim
new file mode 100755
index 0000000..2ada6ae
--- /dev/null
+++ b/app/server/vendor/parslet/website/source/layout.slim
@@ -0,0 +1,48 @@
+doctype 5
+html
+  head
+    meta(http-equiv="Content-type" content="text/html;charset=UTF-8")
+    title
+      | parslet -
+      = data.page.title || 'parslet - beautiful parsers.'
+      
+    meta name='author' content="Kaspar Schiess (http://absurd.li)"
+
+    link rel='shortcut icon' href='images/favicon3.ico'
+    == stylesheet_link_tag 'site'
+    == stylesheet_link_tag 'sh_whitengrey'
+    
+    == javascript_include_tag 'sh_main.min.js'
+    == javascript_include_tag 'sh_ruby.min.js'
+    
+    
+  body.code onload="sh_highlightDocument();"
+    #everything
+      .main_menu
+        == image_tag 'parsley_logo.png', alt: 'Parslet Logo'
+        ul
+          li== link_to('about', 'index.html')
+          li== link_to('get started', 'get-started.html')
+          li== link_to('install', 'install.html')
+          li== link_to('documentation', 'documentation.html')
+          li== link_to('contribute', 'contribute.html')
+          
+      .content
+        h1= data.page.title || 'parslet - beautiful parsers.'
+        == yield
+    
+      .copyright
+        textile:
+          MIT License, 2010-2012, (c) <a href="http://absurd.li">Kaspar Schiess</a><br/>
+          Logo by "Florian Hanke":http://floere.github.com, "CC Attribution":http://creativecommons.org/licenses/by/1.0/ license
+      
+      javascript:
+        var _gaq = _gaq || [];
+        _gaq.push(['_setAccount', 'UA-16365074-2']);
+        _gaq.push(['_trackPageview']);
+
+        (function() {
+          var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+          ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+          var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+        })();
\ No newline at end of file
diff --git a/app/server/vendor/parslet/website/source/overview.html.textile b/app/server/vendor/parslet/website/source/overview.html.textile
new file mode 100755
index 0000000..971e56a
--- /dev/null
+++ b/app/server/vendor/parslet/website/source/overview.html.textile
@@ -0,0 +1,72 @@
+---
+title: Overview
+---
+
+Parslet is a library with a clear philosophy: It makes parser writing easy and
+testable. On top of that, it provides understandable error messages ("General
+Protection Fault") to you, the language writer. In extension, you will
+hopefully manage to provide good error messages to your users. Together, we 
+can create a better world!
+
+Traditional texts on the subject will have you write a compiler or interpreter
+for a language in several stages: 
+
+* Parsing or Lexing/Parsing
+* Abstract Syntax Tree construction
+* Optimization and checking of the tree
+* Generation of code / Execution
+
+This library will be good for the first two stages only. After that, you'll
+be on your own. 
+
+The parsing step has literally been implemented by hundreds (thousands) of
+clever people; No lack of alternatives. Even in Ruby, you'll have the choice 
+among a handful of libraries. There's a distinction to make on this level as
+well: 
+
+*LRk parsers and related fields* Parsers in this class use a lexical analyzer
+(a _lexer_ ) to transform the input text into tokens (_tokenizing_ ). They
+then check if your stream of tokens has a corresponding tree that conforms to
+the grammar. Most of these parsers allow grammars that are ambiguous and will
+provide a mechanism for resolving the arising ambiguities. These are the
+earliest parser generators and the most widely used (_yacc_, _bison_, ...) --
+chances are, you'll have more than one of these libraries installed on your
+system.
+
+*PEG or packrat parsers* Parsers in this class are based on a slightly more
+modern algorithm, which translates what one does when writing a parser by hand
+in top-down fashion. This is what we programmers do all over, methods calling
+methods - and its also (grossly) what these parsers do to recognize input.
+Left recursion is impossible to express in these grammars. No lexers are
+required - lexical tokenizing and parsing are one single step. Ruby has
+several implementations of this algorithm in library form:
+"Treetop":http://github.com/nathansobo/treetop,
+"Citrus":http://github.com/mjijackson/citrus,
+"rsec":http://wiki.github.com/luikore/rsec/ and of course
+"Parslet":http://kschiess.github.com/parslet.
+
+All of these generators are different in small ways; yet most implement common
+patterns and provide almost identical APIs. We believe this is an error:
+choice is good, but there should be visible attributes distinguishing the
+choices.
+
+Parslet is not like the others, in fact it is radically different on some
+key elements. 
+
+h2. Writing a language
+
+Whether you write a language for a configuration file or a new computer
+language (the holy grail), the steps are always the same: 
+
+# Create a grammar: _What should be legal syntax?_
+# Annotate the grammar: _What is important data?_
+# Create a transformation: _How do I want to work with that data?_
+
+The creation of grammars and the various concepts that are associated are treated
+in "Parslet::Parser":parser.html.
+
+Transformation of the resulting intermediary tree is treated in
+"Parslet::Transform":transform.html
+
+
+
diff --git a/app/server/vendor/parslet/website/source/parser.html.textile b/app/server/vendor/parslet/website/source/parser.html.textile
new file mode 100755
index 0000000..0314ffb
--- /dev/null
+++ b/app/server/vendor/parslet/website/source/parser.html.textile
@@ -0,0 +1,339 @@
+---
+title: Parser construction
+---
+
+A parser is nothing more than a class that derives from
+<code>Parslet::Parser</code>. The simplest parser that one could write would
+look like this: 
+
+<pre class="sh_ruby"><code>
+  class SimpleParser < Parslet::Parser
+    rule(:a_rule) { str('simple_parser') }
+    root(:a_rule)
+  end
+</code></pre>
+
+The language recognized by this parser is simply the string "simple_parser". 
+Parser rules do look a lot like methods and are defined by 
+
+<pre class="sh_ruby"><code>
+  rule(name) { definition_block }
+</code></pre>
+
+Behind the scenes, this really defines a method that returns whatever you 
+return from it. 
+
+Every parser has a root. This designates where parsing should start. It is like
+an entry point to your parser. With a root defined like this: 
+
+<pre class="sh_ruby"><code>
+  root(:my_root)
+</code></pre>
+
+you create a <code>#parse</code> method in your parser that will start parsing
+by calling the <code>#my_root</code> method. You'll also have a <code>#root</code>
+(instance) method that is an alias of the root method. The following things are
+really one and the same: 
+
+<pre class="sh_ruby"><code>
+  SimpleParser.new.parse(string)
+  SimpleParser.new.root.parse(string)
+  SimpleParser.new.a_rule.parse(string)
+</code></pre>
+
+Knowing these things gives you a lot of flexibility; I'll explain why at the
+end of the chapter. For now, just let me point out that because all of this is
+Ruby, your favorite editor will syntax highlight parser code just fine.
+
+h2. Atoms: The inside of a parser
+
+h3. Matching strings of characters
+
+A parser is constructed from parser atoms (or parslets, hence the name). The
+atoms are what appear inside your rules (and maybe elsewhere). We've already
+encountered an atom, the string atom: 
+
+<pre class="sh_ruby"><code>
+  str('simple_parser')
+</code></pre>
+
+This returns a <code>Parslet::Atoms::Str</code> instance. These parser atoms
+all derive from <code>Parslet::Atoms::Base</code> and have essentially just
+one method you can call: <code>#parse</code>. So this works: 
+
+<pre class="sh_ruby"><code title="parser atoms">
+  str('foobar').parse('foobar') # => "foobar"@0
+</code></pre>
+
+The atoms are small parsers that can recognize languages and throw errors, just
+like real <code>Parslet::Parser</code> subclasses. 
+
+h3. Matching character ranges
+
+The second parser atom you will have to know about allows you to match
+character ranges: 
+
+<pre class="sh_ruby"><code>
+  match('[0-9a-f]')
+</code></pre>
+
+The above atom would match the numbers zero through nine and the letters 'a' 
+to 'f' - yeah, you guessed right - hexadecimal numbers for example. The inside
+of such a match parslet is essentially a regular expression that matches 
+a single character of input. Because we'll be using ranges so much with 
+<code>#match</code> and because typing ('[]') is tiresome, here's another way
+to write the above <code>#match</code> atom:
+
+<pre class="sh_ruby"><code>
+  match['0-9a-f']
+</code></pre>
+
+Character matches are instances of <code>Parslet::Atoms::Re</code>. Here are 
+some more examples of character ranges: 
+
+<pre class="sh_ruby"><code>
+  match['[:alnum:]']      # letters and numbers
+  match['\\n']            # newlines
+  match('\\w')            # word characters
+  match('.')              # any character
+</code></pre>
+
+h3. The wild wild <code>#any</code>
+
+The last example above corresponds to the regular expression <code>/./</code> that matches
+any one character. There is a special atom for that: 
+
+<pre class="sh_ruby"><code>
+  any 
+</code></pre>
+
+h2. Composition of Atoms
+
+These basic atoms can be composed to form complex grammars. The following
+few sections will tell you about the various ways atoms can be composed.
+
+h3. Simple Sequences
+
+Match 'foo' and then 'bar': 
+
+<pre class="sh_ruby"><code>
+  str('foo') >> str('bar')    # same as str('foobar')
+</code></pre>
+
+Sequences correspond to instances of the class
+<code>Parslet::Atoms::Sequence</code>.
+
+h3. Repetition and its Special Cases
+
+To model atoms that can be repeated, you should use <code>#repeat</code>: 
+
+<pre class="sh_ruby"><code>
+  str('foo').repeat
+</code></pre>
+
+This will allow foo to repeat any number of times, including zero. If you
+look at the signature for <code>#repeat</code> in <code>Parslet::Atoms::Base</code>, 
+you'll see that it has really two arguments: _min_ and _max_. So the following
+code all makes sense: 
+
+<pre class="sh_ruby"><code>
+  str('foo').repeat(1)      # match 'foo' at least once
+  str('foo').repeat(1,3)    # at least once and at most 3 times
+  str('foo').repeat(0, nil) # the default: same as str('foo').repeat
+</code></pre>
+
+Repetition has a special case that is used frequently: Matching something
+once or not at all can be achieved by <code>repeat(0,1)</code>, but also 
+through the prettier: 
+
+<pre class="sh_ruby"><code>
+  str('foo').maybe          # same as str('foo').repeat(0,1)
+</code></pre>
+
+These all map to <code>Parslet::Atoms::Repetition</code>. Please note this
+little twist to <code>#maybe</code>:
+
+<pre class="sh_ruby"><code title="maybes twist">
+  str('foo').maybe.as(:f).parse('')         # => {:f=>nil}
+  str('foo').repeat(0,1).as(:f).parse('')   # => {:f=>[]}
+</code></pre>
+
+The 'nil'-value of <code>#maybe</code> is nil. This is catering to the
+intuition that <code>foo.maybe</code> either gives me <code>foo</code> or
+nothing at all, not an empty array. But have it your way!
+
+h3. Alternation
+
+The most important composition method for grammars is alternation. Without
+it, your grammars would only vary in the amount of things matched, but not
+in content. Here's how this looks: 
+
+<pre class="sh_ruby"><code>
+  str('foo') | str('bar')   # matches 'foo' OR 'bar'
+</code></pre>
+
+This reads naturally as "'foo' or 'bar'". 
+
+h3. Operator precedence
+
+The operators we have chosen for parslet atom combination have the operator
+precedence that you would expect. No parenthesis are needed to express
+alternation of sequences:
+
+<pre class="sh_ruby"><code>
+  str('s') >> str('equence') | 
+    str('se') >> str('quence')
+</code></pre>
+
+h3. And more
+
+Parslet atoms are not as pretty as Treetop atoms. There you go, we said it. 
+However, there seems to be a different kind of aesthetic about them; they 
+are pure Ruby and integrate well with the rest of your environment. Have a 
+look at this: 
+
+<pre class="sh_ruby"><code>
+  # Also consumes the space after important things like ';' or ':'. Call this
+  # giving the character you want to match as argument: 
+  #
+  #   arg >> (spaced(',') >> arg).repeat
+  #
+  def spaced(character)
+    str(character) >> match["\s"]
+  end
+</code></pre>
+
+or even this: 
+
+<pre class="sh_ruby"><code>
+  # Turns any atom into an expression that matches a left parenthesis, the 
+  # atom and then a right parenthesis.
+  #
+  #   bracketed(sum)
+  #
+  def bracketed(atom)
+    spaced('(') >> atom >> spaced(')')
+  end
+</code></pre>
+
+You might say that because parslet is just plain old Ruby objects itself (PORO
+(tm)), it allows for very tight code. Module inclusion, class inheritance, ...
+all your tools should work well with parslet.
+
+h2. Tree construction
+
+By default, parslet will just echo back to you the strings you feed into it. 
+Parslet will not generate a parser for you and neither will it generate your
+abstract syntax tree for you. The method <code>#as(name)</code> allows you
+to specify exactly how you want your tree to look like: 
+
+<pre class="sh_ruby"><code title="using as">
+  str('foo').parse('foo')             # => "foo"@0
+  str('foo').as(:bar).parse('foo')    # => {:bar=>"foo"@0}
+</code></pre>
+
+So you think: <code>#as(name)</code> allows me to create a hash, big deal.
+That's not all. You'll notice that annotating everything that you want to keep
+in your grammar with <code>#as(name)</code> autocreates a sensible tree
+composed of hashes and arrays and strings. It's really somewhat magic: Parslet
+has a set of clever rules that merge the annotated output from your atoms into
+a tree. Here are some more examples, with the atom on the left and the resulting
+tree (assuming a successful parse) on the right: 
+
+<pre class="sh_ruby"><code>
+  # Normal strings just map to strings
+  str('a').repeat                         "aaa"@0                                 
+
+  # Arrays capture repetition of non-strings
+  str('a').repeat.as(:b)                  {:b=>"aaa"@0}                           
+  str('a').as(:b).repeat                  [{:b=>"a"@0}, {:b=>"a"@1}, {:b=>"a"@2}] 
+
+  # Subtrees get merged - unlabeled strings discarded
+  str('a').as(:a) >> str('b').as(:b)      {:a=>"a"@0, :b=>"b"@1}                  
+  str('a') >> str('b').as(:b) >> str('c') {:b=>"b"@1}                             
+
+  # #maybe will return nil, not the empty array
+  str('a').maybe.as(:a)                   {:a=>"a"@0}                             
+  str('a').maybe.as(:a)                   {:a=>nil}
+</code></pre>
+
+h2. Capturing input
+
+_Advanced reading material - feel free to skip this._
+
+Sometimes a parser needs to match against something that was already matched
+against. Think about Ruby heredocs for example: 
+
+<pre class="sh_ruby"><code>
+  str = <-HERE
+    This is part of the heredoc.
+  HERE
+</code></pre>
+
+The key to matching this kind of document is to capture part of the input
+first and then construct the rest of the parser based on the captured part.
+This is what it looks like in its simplest form: 
+
+<pre class="sh_ruby"><code>
+  match['ab'].capture(:capt) >>               # create the capture
+    dynamic { |s,c| str(c.captures[:capt]) }  # and match using the capture
+</code></pre>
+
+This parser matches either 'aa' or 'bb', but not mixed forms 'ab' or 'ba'. The
+last sample introduced two new concepts for this kind of complex parser: the 
+<code>#capture(name)</code> method and the <code>dynamic { ... }</code> code
+block. 
+
+Appending <code>#capture(name)</code> to any parser will capture that parsers
+result in the captures hash in the parse context. If and only if the parser
+<code>match['ab']</code> succeeds, it stores either 'a' or 'b' in 
+<code>context.captures[:capt]</code>.
+
+The only way to get at that hash during the parse process is in a
+<code>dynamic { ... }</code> code block. (for reasons that are out of the
+scope of this document) In such a block, you can: 
+
+<pre class="sh_ruby"><code>
+  dynamic { |source, context|
+    # construct parsers by using randomness
+    rand < 0.5 ? str('a') : str('b')
+    
+    # Or by using context information 
+    str( context.captures[:capt] )
+    
+    # Or by .. doing other kind of work (consumes 100 chars and then 'a')
+    source.consume(100)
+    return str('a')
+  }
+</code></pre>
+
+h3. Scopes
+
+What if you want to parse heredocs contained within heredocs? It's turtles all
+the way down, after all. To be able to remember what string was used to
+construct the outer heredoc, you would use the <code>#scope { ... }</code>
+block that was introduced in parslet 1.5. Like opening a Ruby block, it allows
+you to capture results (assign values to variables) to the same names you've 
+already used in outer scope - _without destroying the outer scopes values for 
+these captures!_.
+
+Here's an example for this: 
+<pre class="sh_ruby"><code>
+  str('a').capture(:a) >> scope { str('b').capture(:a) } >> 
+    dynamic { |s,c| str(c.captures[:a]) }
+</code></pre>
+
+This parses 'aba' - if you understand that, you understand scopes and
+captures. Congrats.
+
+h2. And more
+
+Now you know exactly how to create parsers using Parslet. Your parsers
+will output intricate structures made of endless arrays, complex hashes and 
+a few string leftovers. But your programming skills fail you when you try
+to put all this data to use. Selecting keys upon keys in hash after hash, you
+feel like a cockroach that has just read Kafka's works. This is no fun. This 
+is not what you signed up for. 
+
+Time to introduce you to "Parslet::Transform":transform.html and its workings.
+
diff --git a/app/server/vendor/parslet/website/source/stylesheets/sh_whitengrey.css b/app/server/vendor/parslet/website/source/stylesheets/sh_whitengrey.css
new file mode 100755
index 0000000..41df0e2
--- /dev/null
+++ b/app/server/vendor/parslet/website/source/stylesheets/sh_whitengrey.css
@@ -0,0 +1,139 @@
+pre.sh_sourceCode {
+  background-color: #ffffff;
+  color: #696969;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_keyword {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_type {
+  color: #696969;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_string {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_regexp {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_specialchar {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_comment {
+  color: #1326a2;
+  font-weight: normal;
+  font-style: italic;
+}
+
+pre.sh_sourceCode .sh_number {
+  color: #bb00ff;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_preproc {
+  color: #470000;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_function {
+  color: #000000;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_url {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_date {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_time {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_file {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_ip {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_name {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_variable {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_oldfile {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_newfile {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_difflines {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_selector {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_property {
+  color: #696969;
+  font-weight: bold;
+  font-style: normal;
+}
+
+pre.sh_sourceCode .sh_value {
+  color: #008800;
+  font-weight: normal;
+  font-style: normal;
+}
+
diff --git a/app/server/vendor/parslet/website/source/stylesheets/site.css.sass b/app/server/vendor/parslet/website/source/stylesheets/site.css.sass
new file mode 100755
index 0000000..1cd497a
--- /dev/null
+++ b/app/server/vendor/parslet/website/source/stylesheets/site.css.sass
@@ -0,0 +1,119 @@
+// main site styling
+=clearfix 
+  display: inline-block
+  
+  &:after 
+    content: "."
+    display: block
+    height: 0
+    clear: both
+    visibility: hidden
+  
+  * html & 
+    height: 1px
+    
+body
+  font:
+    size: 17px
+    family: Helvetica
+    
+  background-color: white
+  
+a
+  color: black
+  
+.main_menu  
+  font-size: 1.2em
+  width: 50em
+  margin:
+    bottom: 1cm
+  
+  ul
+    +clearfix
+    list-style-type: none
+    font-size: 1.33em
+    margin-left: -8em
+
+  li
+    float: left
+    font-variant: small-caps
+    padding-left: 1em
+    
+  a, &:visited
+    text-decoration: none
+    color: #7c7c7c
+    
+.content
+  font-size: 1em
+  width: 50em
+  line-height: 1.4em
+  margin: 
+    left: 1cm
+    
+  p
+    margin: 1em
+    
+  img
+    margin-left: 3em
+    
+.copyright
+  font-variant: small-caps
+  font-size: 0.6em
+  color: #00ad00
+  margin:
+    left: 22em
+    top: 3cm
+    
+  a
+    text-decoration: none
+    color: #00ad00
+  
+body.code
+  code
+    font: 
+      size: 0.9em 
+      family: "Monaco", monospace
+  
+    // _why's poignant guide theme
+    .sh_keyword  // keyword
+      color: #761A47
+
+    .sh_comment // comment
+      color: #686868
+
+    .sh_string // string
+      color: #42aa7a
+      background-color: #edf7f7
+
+    .sh_constant // constant
+      color: #551e03
+
+    .sh_method // method
+      color: #4679a9
+
+    .sh_symbol // symbol
+      color: #551e03
+
+    .sh_number
+      color: #42aa7a
+  
+      
+  pre
+    font: 
+      size: 1em 
+      family: "Monaco", monospace
+    
+    background-color: #f8f8f8
+    color: #4679a9
+
+    line-height: 1.1em
+
+    margin: 
+      left: 1em
+    padding: -1em 0 -1em 0
+
+    &.sh_sourceCode
+      border-radius: 0.5em
+      background-color: #f8f8f8
+      padding-bottom: 1.4em
+    
diff --git a/app/server/vendor/parslet/website/source/transform.html.textile b/app/server/vendor/parslet/website/source/transform.html.textile
new file mode 100755
index 0000000..b5f79a6
--- /dev/null
+++ b/app/server/vendor/parslet/website/source/transform.html.textile
@@ -0,0 +1,288 @@
+---
+title: Transformation
+---
+
+Parslet parsers output deep nested hashes. Those are nice for printing, but 
+hard to work with. The structure of the nested hashes is determined by the
+grammar and can thus vary largely. Testing for the presence of individual 
+keys would produce code that is hard to read and maintain. 
+
+This is why parslet also comes with a hash transformation engine. To construct
+such a transform, you have to derive from <code>Parslet::Transform</code>: 
+
+<pre class="sh_ruby"><code title="simple transform">
+  class MyTransform < Parslet::Transform
+    rule('a') { 'b' }
+  end
+  MyTransform.new.apply('a') # => "b"
+</code></pre>
+
+This is a transformation that replaces all 'a's with 'b's. A transformation
+rule has two parts: A *pattern* (here: <code>'a'</code>) and an *action block*
+(<code>{ 'b' }</code>).
+
+The engine will go through the input and traverse the tree in depth-first
+post-order fashion. This means that for a given tree node, it will first visit
+the children and only then look at the node itself. While traversing, all
+rules are tested in the order in which they are defined. If a rule matches, the
+corresponding tree is _replaced_ by whatever the action block returns.
+
+Here's another way of saying the same thing, perhaps more in line with what
+you need as a user of Parslet: <code>Parslet::Transform</code> is what allows
+you to transform the PORO-trees magically into a real abstract syntax tree.
+The rule definitions are the futuristic nano-machines that act on tree leaves
+first, eating them away and replacing them with contraptions of your own
+design. Here's how that might look like in Ruby:
+
+<pre class="sh_ruby"><code title="poro magic">
+  tree = {:left => {:int => '1'}, 
+          :op   => '+', 
+          :right => {:int => '2'}}
+        
+  class Trans < Parslet::Transform
+    rule(:int => simple(:x)) { Integer(x) }
+  end
+  Trans.new.apply(tree)     # => {:left=>1, :op=>"+", :right=>2}
+</code></pre>
+
+You can start thinking about the leaves first, transforming those <code>:int
+=> '1'</code> into real Ruby integers. This incremental (test driven!)
+approach will prevent your intermediary tree from turning into grey goo
+from too many nano-machines. Rules should in general be simple and transform
+a small part of the tree into a more useful variant. Turns out that if we were
+looking for an interpreter, one more rule will give us evaluation: 
+
+<pre class="sh_ruby"><code title="building up">
+  tree = {:left => {:int => '1'}, 
+          :op   => '+', 
+          :right => {:int => '2'}}
+
+  class Trans < Parslet::Transform
+    rule(:int => simple(:x)) { Integer(x) }
+    rule(:op => '+', :left => simple(:l), :right => simple(:r)) { l + r }
+  end
+  Trans.new.apply(tree)     # => 3
+</code></pre>
+
+Cool, isn't it? To recap: parslet intentionally spits out deep nested hashes, 
+because it also gives you the tool to work with those. Turning the intermediary
+trees into something useful is really easy. 
+
+h2. 
+
+h2. Working with Captures
+
+What is this <code>simple(symbol)</code> business all about, you might ask.
+Glad you do.
+
+h3. Simple captures
+
+Transform allows you to specify patterns that have wildcards in them. The
+wildcards match part of the tree, but at the same time capture it for working
+on it in your action block. The wildcard
+
+<pre class="sh_ruby"><code>
+  simple(:x)
+</code></pre>
+
+will match any object BUT hashes or arrays. While this is obviously useful
+for capturing strings, you can also capture other 'simple' (as opposed to 
+composed) objects of your own creation. <code>simple(:x)</code> would thus match
+all of these objects: 
+
+<pre class="sh_ruby"><code>
+  "a string"
+  123
+  Foo.new(:some, :class, :instance)
+</code></pre>
+
+If you think about what you'll be doing to your intermediary trees, replacing
+leaves with more useful objects, <code>simple</code> really makes good sense, 
+since it will stop you from matching entire subtrees. 
+
+h3. Matching Repetitions and Sequences
+
+Some patterns (like repetitions and sequences) produce arrays of objects as
+result. You can use <code>simple(...)</code> to replace all parts of these
+arrays with your own objects, but you cannot replace the array as a whole. 
+This is the purpose of <code>sequence(symbol)</code>: 
+
+<pre class="sh_ruby"><code>
+  sequence(:x)
+</code></pre>
+
+will match all of these: 
+
+<pre class="sh_ruby"><code>
+  ['a', 'b', 'c']
+  ['a', 'a', 'a']
+  [Foo.new, Bar.new]
+</code></pre>
+
+but not
+
+<pre class="sh_ruby"><code>
+  [{:a => :b}]
+  [['a', 'b']]
+</code></pre>
+
+Like its smaller brother, <code>sequence</code> is very picky about what it
+consumes and what not. All for the same reasons. 
+
+h3. Matching entire subtrees
+
+So you don't want to listen and really want that big gun with the foot aiming
+addon. You'll be needing <code>subtree(symbol)</code>. It always matches. 
+Nuff said. 
+
+h3. Matching context
+
+A match always binds in a context. The context consists of all bindings
+that were previously made. If you reuse the same symbol for two consecutive
+matches within the same pattern, the engine will assume that you want these
+two matched objects to be equal (under <code>==</code>). This allows to 
+specify constraints on your matches that would need code to express otherwise: 
+
+<pre class="sh_ruby"><code>
+  # The following code is an excerpt from example/simple_xml.rb in the distro
+  t.rule(
+    open: {name: simple(:tag)}, 
+    close: {name: simple(:tag)}, 
+    inner: simple(:t)
+  ) { 'verified' }
+</code></pre>
+
+This replaces _matching_ open and close tags with the word 'verified',
+consuming them from the tree and allowing the same rule to match higher up. A
+valid XML tree will leave only the word 'verified' behind, while the parser
+will stop at the problem nodes in invalid trees.
+
+h2. Transformation rules
+
+In this chapter, we'll look more closely at transformation rules and the
+different ways they can be laid out in your code.
+
+h3. Usage Patterns
+
+The way the transformation engine is constructed, there is not one, but three
+ways to use it. Since at least one of those is inconvenient for you, the user,
+I am going to show only the remaining two, Variant 1 that produces an instance
+of the transform for direct use:
+
+<pre class="sh_ruby"><code>
+  # Variant 1
+  transform = Parslet::Transform.new do
+    rule(...) { ... } 
+    rule(...) { ... } 
+    rule(...) { ... } 
+  end
+  transform.apply(tree)
+</code></pre>
+
+and Variant 2 that allows constructing the transformation as a class: 
+
+<pre class="sh_ruby"><code>
+  # Variant 2
+  class MyTransform < Parslet::Transform
+    rule(...) { ... } 
+    rule(...) { ... } 
+    rule(...) { ... } 
+  end
+  MyTransform.new.apply(tree)
+</code></pre>
+
+I guess both have their sweet spot. 
+
+h3. Action blocks: Two flavors 
+
+As you might have noticed by now, parslet provides choice as well as nice
+parsers. To recap: Rules have a left side called _pattern_ and a right side 
+called _action block_:
+
+<pre class="sh_ruby"><code>
+  rule(PATTERN) {ACTION_BLOCK}
+</code></pre>
+
+There are two ways of writing action blocks, and the difference might be 
+fundamental to know to you one day. If written like this: 
+
+<pre class="sh_ruby"><code>
+  rule(:foo => simple(:x)) { puts x }
+</code></pre>
+
+the block will be able to access <code>x</code> as a local variable. This is 
+very convenient and shortens the action code, often to the point of being
+very expressive.
+
+But there is a _big downside_ to this way of writing things: The action block
+must be executed in the context of some magic instance that has <code>x</code>
+as a local method (aka accessor). You can only have one self at any one time; 
+variable access to the binding of the block isn't possible inside this kind
+of action blocks: 
+
+<pre class="sh_ruby"><code>
+  y = 12
+  rule(:foo => simple(:x)) { Integer(x) + y }
+</code></pre>
+
+This will (depending on the context) throw a <code>NameError</code> or a
+<code>NoMethodError</code>.
+
+But this can be fixed by using the other, less elegant style for action
+blocks:
+
+<pre class="sh_ruby"><code>
+  y = 12
+  rule(:foo => simple(:x)) { |dictionary| Integer(dictionary[:x]) + y }
+</code></pre>
+
+In this second flavor, the block gets executed in the context of definition, 
+whatever that was. This means that it can capture and access local variables
+just fine. Access to the bindings (called <code>dictionary</code> here) is 
+more clumsy, but hey, you can't have your cake and eat it too, I guess. Even 
+though that is a pity. 
+
+h2. A word on patterns
+
+Given the PORO hash
+
+<pre class="sh_ruby"><code>
+  { 
+    :dog => 'terrier', 
+    :cat => 'suit' }
+</code></pre>
+
+one might assume that the following rule matches <code>:dog</code> and
+replaces it by <code>'foo'</code>:
+
+<pre class="sh_ruby"><code>
+  rule(:dog => 'terrier') { 'foo' }
+</code></pre>
+
+This is frankly impossible. How would <code>'foo'</code> live besides
+<code>:cat => 'suit'</code> inside the hash? It cannot. This is why hashes are
+either matched completely, cats n' all, or not at all. 
+
+Transformations are there for one thing: Getting out of the hash/array/slice
+mess parslet creates (on purpose) into the realm of your own beautifully
+crafted AST classes. Such
+"AST":http://en.wikipedia.org/wiki/Abstract_syntax_tree nodes will generally
+correspond 1:1 to hashes inside your intermediary tree. 
+
+If transformations get you into a mess, remember this simple truth: They have
+been designed for the above purpose. Abusing them is fun (and almost all the
+examples in the project do so) but the mess you get when you do is all yours.
+
+If you are really desperate, try to look at the example in "Get Started":get-started.html or at the parser in the sample project
+"wt":https://github.com/kschiess/wt. Imitating them would be a good first step. And if all else fails, we're there for you, see the 'Contact' section in "Contribute":contribute.html.
+
+h2. Summary
+
+This concludes this (three part) introduction to parslet and leaves you with a
+good knowledge of most tricky parts. If you are missing some detail, maybe
+you can find it in the texts referenced "here":documentation.html? There is 
+also an entire page on the tricks useful in practice here: "Tricks":tricks.html.
+
+If not, please tell us about it. We'll include it in this documentation in no 
+time. 
+
diff --git a/app/server/vendor/parslet/website/source/tricks.html.textile b/app/server/vendor/parslet/website/source/tricks.html.textile
new file mode 100755
index 0000000..06e5fbe
--- /dev/null
+++ b/app/server/vendor/parslet/website/source/tricks.html.textile
@@ -0,0 +1,211 @@
+---
+title: Tricks for common situations
+---
+
+h2. Matching EOF (End Of File)
+
+Ahh Sir, you'll be needin what us parsers call _epsilon_: 
+
+<pre class="sh_ruby"><code>
+  rule(:eof) { any.absent? }
+</code></pre>
+
+Of course, most of us don't use this at all, since any parser has EOF as
+implicit last input.
+
+h2. Matching Strings Case Insensitive
+
+Parslet is fully hackable: You can use code to create parsers easily. Here's
+how I would match a string in case insensitive manner: 
+
+<pre class="sh_ruby"><code title="case insensitive match">
+  def stri(str)
+    key_chars = str.split(//)
+    key_chars.
+      collect! { |char| match["#{char.upcase}#{char.downcase}"] }.
+      reduce(:>>)
+  end
+
+  # Constructs a parser using a Parser Expression Grammar 
+  stri('keyword').parse "kEyWoRd"     # => "kEyWoRd"@0
+</code></pre>
+
+h2. Testing
+
+Parslet helps you to create parsers that are in turn created out of many small
+parsers. It is really turtles all the way down. Imagine you have a complex 
+parser: 
+
+<pre class="sh_ruby"><code>
+  class ComplexParser < Parslet::Parser
+    root :lots_of_stuff
+  
+    rule(:lots_of_stuff) { ... }
+  
+    # and many lines later: 
+    rule(:simple_rule) { str('a') }
+  end
+</code></pre>
+
+Also imagine that the parser (as a whole) fails to consume the 'a' that 
+<code>simple_rule</code> is talking about. 
+
+This kind of problem can very often be fixed by bisecting it into two possible
+problems. Either: 
+
+# the <code>lots_of_stuff</code> rule somehow doesn't place <code>simple_rule</code>
+  in the right context or
+# the <code>simple_rule</code> simply (hah!) fails to match its input. 
+
+I find it very useful in this situation to eliminate 2. from our options: 
+
+<pre class="sh_ruby"><code title="rspec">
+  require 'rspec'
+  require 'parslet/rig/rspec'
+  
+  class ComplexParser < Parslet::Parser
+    rule(:simple_rule) { str('a') }
+  end
+
+  describe ComplexParser  do
+    let(:parser) { ComplexParser.new }
+    context "simple_rule" do
+      it "should consume 'a'" do
+        parser.simple_rule.should parse('a')
+      end 
+    end
+  end
+  
+  RSpec::Core::Runner.run([])
+</code></pre>
+
+Output is: 
+<pre class="output">
+
+Example::ComplexParser
+  simple_rule
+    should consume 'a'
+
+Finished in 0.00115 seconds
+1 example, 0 failures
+</pre>
+
+Parslet parsers have one method per rule. These methods return valid parsers
+for a subset of your grammar. 
+
+h2. Error reports
+
+If your grammar fails and you're aching to know why, here's a bit of exception
+handling code that will help you out: 
+
+<pre class="sh_ruby"><code title="exception handling">
+  parser = str('foo')
+  begin
+    parser.parse('bar')
+  rescue Parslet::ParseFailed => error
+    puts error.cause.ascii_tree
+  end
+</code></pre>
+
+This should print something akin to: 
+
+<pre class="output"> 
+Expected "foo", but got "bar" at line 1 char 1.
+</pre>
+
+These error reports are probably the fastest way to know exactly where you
+went wrong (or where your input is wrong, which is aequivalent).
+
+And since this is such a common idiom, we provide you with a shortcut: to
+get the above, just: 
+
+<pre class="sh_ruby"><code>
+require 'parslet/convenience'
+parser.parse_with_debug(input)
+</code></pre>
+
+
+h3. Reporter engines
+
+Note that there is currently not one, but two error reporting engines! The 
+default engine will report errors in a structure that looks exactly like the
+grammar structure: 
+
+<pre class="sh_ruby"><code title="error reporter 1">
+  class P < Parslet::Parser
+    root(:body)
+    rule(:body) { elements }
+    rule(:elements) { (call | element).repeat(2) }
+    rule(:element) { str('bar') }
+    rule(:call) { str('baz') >> str('()') }
+  end
+  
+  begin
+    P.new.parse('barbaz')
+  rescue Parslet::ParseFailed => error
+    puts error.cause.ascii_tree
+  end
+</code></pre>
+
+Outputs: 
+
+<pre class="output"> 
+Expected at least 2 of CALL / ELEMENT at line 1 char 1.
+`- Expected one of [CALL, ELEMENT] at line 1 char 4.
+   |- Failed to match sequence ('baz' '()') at line 1 char 7.
+   |  `- Premature end of input at line 1 char 7.
+   `- Expected "bar", but got "baz" at line 1 char 4.
+</pre>
+
+Let's switch out the 'grammar structure' engine (called '<code>Tree</code>')
+with the 'deepest error position' engine:
+
+<pre class="sh_ruby"><code title="error reporter 2">
+  class P < Parslet::Parser
+    root(:body)
+    rule(:body) { elements }
+    rule(:elements) { (call | element).repeat(2) }
+    rule(:element) { str('bar') }
+    rule(:call) { str('baz') >> str('()') }
+  end
+  
+  begin
+    P.new.parse('barbaz', reporter: Parslet::ErrorReporter::Deepest.new)
+  rescue Parslet::ParseFailed => error
+    puts error.cause.ascii_tree
+  end
+</code></pre>
+
+Outputs: 
+
+<pre class="output"> 
+Expected at least 2 of CALL / ELEMENT at line 1 char 1.
+`- Expected one of [CALL, ELEMENT] at line 1 char 4.
+   |- Failed to match sequence ('baz' '()') at line 1 char 7.
+   |  `- Premature end of input at line 1 char 7.
+   `- Premature end of input at line 1 char 7.
+</pre>
+
+The <code>'Deepest'</code> position engine will store errors that are the
+farthest into the input. In some examples, this produces more readable output
+for the end user. 
+
+h2. Line numbers from parser output
+
+A traditional parser would parse and then perform several checking phases,
+like for example verifying all type constraints are respected in the input.
+During this checking phase, you will most likely want to report screens full
+of type errors back to the user ('cause that's what types are for, right?).
+Now where did that 'int' come from?
+
+Parslet gives you slices (Parslet::Slice) of input as part of your tree. These
+are essentially strings with line numbers. Here's how to print that error
+message:
+
+<pre class="sh_ruby"><code>
+  # assume that type == "int"@0 - a piece from your parser output
+  line, col = type.line_and_column
+  puts "Sorry. Can't have #{type} at #{line}:#{col}!"
+</code></pre>
+
+
diff --git a/app/server/vendor/rouge/.gitignore b/app/server/vendor/rouge/.gitignore
new file mode 100755
index 0000000..6ab7ebc
--- /dev/null
+++ b/app/server/vendor/rouge/.gitignore
@@ -0,0 +1,9 @@
+# it's a gem, ignore the lockfile
+Gemfile.lock
+
+# build artifacts
+*.gem
+
+# docs
+/.yardoc
+/doc
diff --git a/app/server/vendor/rouge/.travis.yml b/app/server/vendor/rouge/.travis.yml
new file mode 100755
index 0000000..47b7e34
--- /dev/null
+++ b/app/server/vendor/rouge/.travis.yml
@@ -0,0 +1,9 @@
+language: ruby
+rvm:
+  - "1.9.3"
+  - "2.0"
+  - "2.1"
+  # - jruby-19mode # JRuby in 1.9 mode
+  # - rbx-2.1.1
+bundler_args: --without development
+before_install: gem update bundler
diff --git a/app/server/vendor/rouge/.yardopts b/app/server/vendor/rouge/.yardopts
new file mode 100755
index 0000000..2d5dda3
--- /dev/null
+++ b/app/server/vendor/rouge/.yardopts
@@ -0,0 +1,3 @@
+--no-private
+--markup-provider=redcarpet
+--markup=markdown
diff --git a/app/server/vendor/rouge/CHANGELOG.md b/app/server/vendor/rouge/CHANGELOG.md
new file mode 100755
index 0000000..a66302f
--- /dev/null
+++ b/app/server/vendor/rouge/CHANGELOG.md
@@ -0,0 +1,356 @@
+## version 1.6.2: 2014-08-16
+
+  * swift: updates for beta 5 (thanks @radex!)
+
+## version 1.6.1: 2014-07-26
+
+  * hotfix release for common lisp, php, objective c, and qml lexers
+
+## version 1.6.0: 2014-07-26
+
+  * haml: balance braces in interpolation
+  * new lexer: slim (thanks @knutaldrin and @greggroth!)
+  * javascript: inner tokens in regexes are now lexed, as well as improvments to
+    the block / object distinction.
+
+## version 1.5.1: 2014-07-13
+
+  * ruby bugfixes for symbol edgecases and one-letter constants
+  * utf-8 all of the things
+  * update all builtins
+  * rust: add `box` keyword and associated builtins
+
+## version 1.5.0: 2014-07-11
+
+  * new lexer: swift (thanks @totocaster!)
+  * update elixir for new upstream features (thanks @splattael!)
+  * ruby bugfixes:
+    - add support for method calls with trailing dots
+    - fix for `foo[bar] / baz` being highlighted as a regex
+  * terminal256 formatter: re-style each line - some platforms reset on each line
+
+## version 1.4.0: 2014-05-28
+
+  * breaking: wrap code in `<pre ...><code>...</code></pre>` if `:wrap` is not overridden
+    (thanks @Arcovion)
+  * Allow passing a theme name as a string to `:inline_theme` (thanks @Arcovion)
+  * Add `:start_line` option for html line numbers (thanks @sencer)
+  * List available themes in `rougify help style`
+
+## version 1.3.4: 2014-05-03
+
+  * New lexers:
+    - QML (thanks @seanchas116)
+    - Applescript (thanks @joshhepworth)
+    - Properties (thanks @pkuczynski)
+  * Ruby bugfix for `{ key: /regex/ }` (#134)
+  * JSON bugfix: properly highlight null (thanks @zsalzbank)
+  * Implement a noop formatter for perf testing (thanks @splattael)
+
+## version 1.3.3: 2014-03-02
+
+  * prolog bugfix: was raising an error on some inputs (#126)
+  * python bugfix: was inconsistently highlighting keywords/builtins mid-word (#127)
+  * html formatter: always end output with a newline (#125)
+
+## version 1.3.2: 2014-01-13
+
+  * Now tested in Ruby 2.1
+  * C family bugfix: allow exponential floats without decimals (`1e-2`)
+  * cpp: allow single quotes as digit separators (`100'000'000`)
+  * ruby: highlight `%=` as an operator in the right context
+
+## version 1.3.1: 2013-12-23
+
+  * fill in some lexer descriptions and add the behat alias for gherkin
+
+## version 1.3.0: 2013-12-23
+
+  * assorted CLI bugfixes: better error handling, CGI-style options, no loadpath munging
+  * html: support multiline doctypes
+  * ocaml: bugfix for OO code: allows `#` as an operator
+  * inline some styles in tableized output instead of relying on the theme
+  * redcarpet: add overrideable `#rouge_formatter` for custom formatting options
+
+## version 1.2.0: 2013-11-26
+
+  * New lexers:
+    - MATLAB (thanks @adambard!)
+    - Scala (thanks @sgrif!)
+    - Standard ML (sml)
+    - OCaml
+  * Major performance overhaul, now ~2x faster (see [#114][]) (thanks @korny!)
+  * Deprecate `RegexLexer#group` (internal).  Use `#groups` instead.
+  * Updated PHP builtins
+  * CLI now responds to `rougify --version`
+
+[#114]: https://github.com/jayferd/rouge/pull/114
+
+## version 1.1.0: 2013-11-04
+
+  * For tableized line numbers, the table is no longer surrounded by a `<pre>`
+    tag, which is invalid HTML.  This was previously causing issues with HTML
+    post-processors such as loofah.  This may break some stylesheets, as it
+    changes the generated markup, but stylesheets only referring to the scope
+    passed to the formatter should be unaffected.
+  * New lexer: moonscript (thanks @nilnor!)
+  * New theme: monokai, for real this time! (thanks @3100!)
+  * Fix intermittent loading errors for good with `Lexer.load_const`, which
+    closes the long-standing #66
+
+## version 1.0.0: 2013-09-28
+
+  * lua: encoding bugfix, and a performance tweak for string literals
+  * The Big 1.0!  From now on, strict semver will apply, and new lexers and
+    features will be introduced in minor releases, reserving patch releases
+    for bugfixes.
+
+## version 0.5.4: 2013-09-21
+
+  * Cleaned up stray invalid error tokens
+  * Fix C++/objc loading bug in `rougify`
+  * Guessing alg tweaks: don't give up if no filename or mimetype matches
+  * Rebuilt the CLI without thor (removed the thor dependency)
+  * objc: Bugfix for `:forward_classname` error tokens
+
+## version 0.5.3: 2013-09-15
+
+  * Critical bugfixes (#98 and #99) for Ruby and Markdown. Some inputs
+    would throw errors. (thanks @hrysd!)
+
+## version 0.5.2: 2013-09-15
+
+  * Bugfixes for C/C++
+  * Major bugfix: YAML was in a broken state :\ (thanks @hrysd!)
+  * Implement lexer subclassing, with `append` and `prepend`
+  * new lexer: objective c (!)
+
+## version 0.5.1: 2013-09-15
+
+  * Fix non-default themes (thanks @tiroc!)
+  * Minor lexing bugfixes in ruby
+
+## version 0.5.0: 2013-09-02
+
+  * [Various performance optimizations][perf-0.5]
+  * javascript:
+    - quoted object keys were not being highlighted correctly
+    - multiline comments were not being highlighted
+  * common lisp: fix commented forms
+  * golang: performance bump
+  * ruby: fix edge case for `def-@`
+  * c: fix a pathological performance case
+  * fix line number alignment on non-newline-terminated code (#91)
+
+### Breaking API Changes in v0.5.0
+
+  * `Rouge::Lexers::Text` renamed to `Rouge::Lexers::PlainText`
+  * Tokens are now constants, rather than strings.  This only affects
+    you if you've written a custom lexer, formatter, or theme.
+
+[perf-0.5]: https://github.com/jayferd/rouge/pull/41#issuecomment-23561787
+
+## version 0.4.0: 2013-08-14
+
+  * Add the `:inline_theme` option to `Formatters::HTML` for environments
+    that don't support stylesheets (like super-old email clients)
+  * Improve documentation of `Formatters::HTML` options
+  * bugfix: don't include subsequent whitespace in an elixir keyword.
+    In certain fonts/themes, this can cause inconsistent indentation if
+    bold spaces are wider than non-bold spaces.  (thanks @splattael!)
+
+## version 0.3.10: 2013-07-31
+
+  * Add the `license` key in the gemspec
+  * new lexer: R
+
+## version 0.3.9: 2013-07-19
+
+  * new lexers:
+    - elixir (thanks @splattael!)
+    - racket (thanks @greghendershott!)
+
+## version 0.3.8: 2013-07-02
+
+  * new lexers:
+    - erlang! (thanks @potomak!)
+    - http (with content-type based delegation)
+  * bugfix: highlight true and false in JSON
+
+## version 0.3.7: 2013-06-07
+
+  * bugfix: Add the local lib dir to the path in ./bin/rougify
+    so the internal `require` works properly.
+  * php: Properly lex variables in double-quoted strings and provide the
+    correct token for heredocs (thanks @hrysd!)
+  * Add a `:wrap` option to the html formatter (default true) to provide
+    the `<pre>` wrapper.  This allows skipping the wrapper entirely for
+    postprocessing.  (thanks @cjohansen!)
+
+## version 0.3.6: 2013-05-27
+
+  * fixed bad release that included unfinished D and wdiff lexers :\
+
+## version 0.3.5: 2013-05-24
+
+  * Added a github theme (thanks @simonc!) (#75)
+  * Correctly highlight ruby 1.9-style symbols and %i() syntax
+    (thanks @simonc!) (#74)
+  * Fixed a performance bug in the C++ lexer (#73)
+    reported by @jeffgran
+
+## version 0.3.4: 2013-05-02
+
+  * New lexer: go (thanks @hashmal!)
+  * Clojure bugfix: allow # in keywords and symbols
+
+## version 0.3.3: 2013-04-09
+
+  * Basic prompt support in the shell lexer
+  * Add CSS3 attributes to CSS/Sass/SCSS lexers
+  * Bugfix for a crash in the vim lexer
+
+## version 0.3.2: 2013-03-11
+
+  * Another hotfix release for the Sass/SCSS lexers, because I am being dumb
+
+## version 0.3.1: 2013-03-11
+
+  * Hotfix release: fix errors loading the SCSS lexer on some systems.
+
+## version 0.3.0: 2013-03-06
+
+  * Refactor source guessing to return fewer false positives, and
+    to be better at disambiguating between filename matches (such as
+    `nginx.conf` vs. `*.conf`, or `*.pl` for both prolog and perl)
+  * Added `Lexer.guesses` which can return multiple or zero results for a
+    guess.
+  * Fix number literals in C#
+  * New lexers:
+    - Gherkin (cucumber)
+    - Prolog (@coffeejunk)
+    - LLVM (@coffeejunk)
+
+## version 0.2.15: 2013-03-03
+
+  * New lexer: lua (thanks, @nathany!)
+  * Add extra filetypes that map to Ruby (`Capfile`, `Vagrantfile`,
+    `*.ru` and `*.prawn`) (@nathany)
+  * Bugfix: add demos for ini and toml
+  * The `thankful_eyes` theme now colors `Literal.Date`
+  * No more gigantic load list in `lib/rouge.rb`
+
+## version 0.2.14: 2013-02-28
+
+  * New lexers:
+    - puppet
+    - literate coffeescript
+    - literate haskell
+    - ini
+    - toml (@coffeejunk)
+  * clojure: `cljs` alias, and make it more visually balanced by using
+    `Name` instead of `Name.Variable`.
+  * Stop trying to read /etc/bash.bashrc in the specs (@coffeejunk)
+
+## version 0.2.13: 2013-02-12
+
+  * Highlight ClojureScipt files (`*.cljs`) as Clojure (@blom)
+  * README and doc enhancements (plus an actual wiki!) (@robin850)
+  * Don't open `Regexp`, especially if we're not adding anything to it.
+
+## version 0.2.12: 2013-02-07
+
+  * Python: bugfix for lone quotes in triple-quoted strings
+  * Ruby: bugfix for `#` in `%`-delimited strings
+
+## version 0.2.11: 2013-02-04
+
+  * New lexer: C# (csharp)
+  * rust: better macro handling
+  * Python bugfix for "'" and '"' (@garybernhardt)
+
+## version 0.2.10: 2013-01-14
+
+  * New lexer: rust (rust-lang.org)
+  * Include rouge.gemspec with the built gem
+  * Update the PHP builtins
+
+## version 0.2.9: 2012-11-28
+
+  * New lexers: io, sed, conf, and nginx
+  * fixed an error on numbers in the shell lexer
+  * performance bumps for shell and ruby by prioritizing more
+    common patterns
+  * (@korny) Future-proofed the regexes in the Perl lexer
+  * `rougify` now streams the formatted text to stdout as it's
+    available instead of waiting for the lex to be done.
+
+## version 0.2.8: 2012-10-30
+
+  * Bugfix for tableized line numbers when the code doesn't end
+    with a newline.
+
+## version 0.2.7: 2012-10-22
+
+  * Major performance improvements.  80% running time reduction for
+    some files since v0.2.5 (thanks again @korny!)
+  * Deprecated `postprocess` for performance reasons - it wasn't that
+    useful in the first place.
+  * The shell lexer should now recognize .bashrc, .profile and friends
+
+## version 0.2.6: 2012-10-21
+  * coffeescript: don't yield error tokens for keywords as attributes
+  * add the `--scope=SELECTOR` option to `rougify style`
+  * Add the `:line_numbers` option to the HTML formatter to get line
+    numbers!  The styling for the line numbers is determined by
+    the theme's styling for `'Generic.Lineno'`
+  * Massive performance improvements by reducing calls to `option`
+    and to `Regexp#source` (@korny)
+
+## version 0.2.5: 2012-10-20
+  * hotfix: ship the demos with the gem.
+
+## version 0.2.4: 2012-10-20
+
+  * Several improvements to the javasript and scheme lexers
+  * Lexer.demo, with small demos for each lexer
+  * Rouge.highlight takes a string for the formatter
+  * Formatter.format delegates to the instance
+  * sass: Support the @extend syntax, fix new-style attributes, and
+    support 3.2 placeholder syntax
+
+## version 0.2.3: 2012-10-16
+
+  * Fixed several postprocessing-related bugs
+  * New lexers: coffeescript, sass, smalltalk, handlebars/mustache
+
+## version 0.2.2: 2012-10-13
+
+  * In terminal256, stop highlighting backgrounds of text-like tokens
+  * Fix a bug which was breaking guessing with filenames beginning with .
+  * Fix the require path for redcarpet in the README (@JustinCampbell)
+  * New lexers: clojure, groovy, sass, scss
+  * YAML: detect files with the %YAML directive
+  * Fail fast for non-UTF-8 strings
+  * Formatter#render deprecated, renamed to Formatter#format.
+    To be removed in v0.3.
+  * Lexer#tag delegates to the class
+  * Better keyword/builtin highlighting for CSS
+  * Add the `:token` option to the text lexer
+
+## version 0.2.1: 2012-10-11
+
+  * Began the changelog
+  * Removed several unused methods and features from Lexer and RegexLexer
+  * Added a lexer for SQL
+  * Added a lexer for VimL, along with `rake builtins:vim`
+  * Added documentation for RegexLexer, TextAnalyzer, and the formatters
+  * Refactored `rake phpbuiltins` - renamed to `rake builtins:php`
+  * Fixed a major bug in the Ruby lexer that prevented highlighting the
+    `module` keyword.
+  * Changed the default formatter for the `rougify` executable to
+    `terminal256`.
+  * Implemented `rougify list`, and added short descriptions to all of
+    the lexers.
+  * Fixed a bug in the C lexer that was yielding error tokens in case
+    statements.
diff --git a/app/server/vendor/rouge/Gemfile b/app/server/vendor/rouge/Gemfile
new file mode 100755
index 0000000..918c4cb
--- /dev/null
+++ b/app/server/vendor/rouge/Gemfile
@@ -0,0 +1,23 @@
+source 'http://rubygems.org'
+
+gemspec
+
+gem 'minitest', '~> 4.0'
+gem 'wrong'
+
+gem 'rake'
+
+# don't try to install redcarpet under jruby
+gem 'redcarpet', :platforms => :ruby
+
+group :development do
+  gem 'pry'
+
+  # docs
+  gem 'yard'
+  gem 'github-markup'
+
+  # for visual tests
+  gem 'sinatra'
+  gem 'shotgun'
+end
diff --git a/app/server/vendor/rouge/Guardfile b/app/server/vendor/rouge/Guardfile
new file mode 100755
index 0000000..757b163
--- /dev/null
+++ b/app/server/vendor/rouge/Guardfile
@@ -0,0 +1,3 @@
+guard :shell do
+  watch(/\.rb$/) { `rake` }
+end
diff --git a/app/server/vendor/rouge/LICENSE b/app/server/vendor/rouge/LICENSE
new file mode 100755
index 0000000..30fce01
--- /dev/null
+++ b/app/server/vendor/rouge/LICENSE
@@ -0,0 +1,186 @@
+# MIT license.  See http://www.opensource.org/licenses/mit-license.php
+
+Copyright (c) 2012 Jay Adkisson.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+# SPECIAL NOTE:
+Many of the lexers in this project are adaptations of those in Pygments
+(pygments.org).  The license for Pygments is as follows:
+
+# BEGIN pygments/LICENSE #
+
+Copyright (c) 2006-2012 by the respective authors (see AUTHORS file).
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# END pygments/LICENSE #
+
+The contents of the AUTHORS file at the time of porting was:
+
+# BEGIN pygments/AUTHORS #
+
+Pygments is written and maintained by Georg Brandl <georg at python.org>.
+
+Major developers are Tim Hatch <tim at timhatch.com> and Armin Ronacher
+<armin.ronacher at active-4.com>.
+
+Other contributors, listed alphabetically, are:
+
+* Sam Aaron -- Ioke lexer
+* Kumar Appaiah -- Debian control lexer
+* Ali Afshar -- image formatter
+* Andreas Amann -- AppleScript lexer
+* Jeffrey Arnold -- R/S lexer, BUGS lexers
+* Jeremy Ashkenas -- CoffeeScript lexer
+* Stefan Matthias Aust -- Smalltalk lexer
+* Ben Bangert -- Mako lexers
+* Max Battcher -- Darcs patch lexer
+* Paul Baumgart, 280 North, Inc. -- Objective-J lexer
+* Michael Bayer -- Myghty lexers
+* John Benediktsson -- Factor lexer
+* Christopher Bertels -- Fancy lexer
+* Jarrett Billingsley -- MiniD lexer
+* Adam Blinkinsop -- Haskell, Redcode lexers
+* Frits van Bommel -- assembler lexers
+* Pierre Bourdon -- bugfixes
+* Hiram Chirino -- Scaml and Jade lexers
+* Leaf Corcoran -- MoonScript lexer
+* Christopher Creutzig -- MuPAD lexer
+* Pete Curry -- bugfixes
+* Owen Durni -- haXe lexer
+* Nick Efford -- Python 3 lexer
+* Sven Efftinge -- Xtend lexer
+* Artem Egorkine -- terminal256 formatter
+* James H. Fisher -- PostScript lexer
+* Carlos Galdino -- Elixir and Elixir Console lexers
+* Naveen Garg -- Autohotkey lexer
+* Laurent Gautier -- R/S lexer
+* Alex Gaynor -- PyPy log lexer
+* Bertrand Goetzmann -- Groovy lexer
+* Krzysiek Goj -- Scala lexer
+* Matt Good -- Genshi, Cheetah lexers
+* Patrick Gotthardt -- PHP namespaces support
+* Olivier Guibe -- Asymptote lexer
+* Martin Harriman -- SNOBOL lexer
+* Matthew Harrison -- SVG formatter
+* Steven Hazel -- Tcl lexer
+* Aslak Hellesøy -- Gherkin lexer
+* Greg Hendershott -- Racket lexer
+* Jordi Gutiérrez Hermoso -- Octave lexer
+* David Hess, Fish Software, Inc. -- Objective-J lexer
+* Varun Hiremath -- Debian control lexer
+* Doug Hogan -- Mscgen lexer
+* Ben Hollis -- Mason lexer
+* Tim Howard -- BlitzMax lexer
+* Ivan Inozemtsev -- Fantom lexer
+* Brian R. Jackson -- Tea lexer
+* Dennis Kaarsemaker -- sources.list lexer
+* Igor Kalnitsky -- vhdl lexer
+* Eric Knibbe -- Lasso lexer
+* Adam Koprowski -- Opa lexer
+* Benjamin Kowarsch -- Modula-2 lexer
+* Alexander Kriegisch -- Kconfig and AspectJ lexers
+* Marek Kubica -- Scheme lexer
+* Jochen Kupperschmidt -- Markdown processor
+* Gerd Kurzbach -- Modelica lexer
+* Olov Lassus -- Dart lexer
+* Sylvestre Ledru -- Scilab lexer
+* Mark Lee -- Vala lexer
+* Ben Mabey -- Gherkin lexer
+* Simone Margaritelli -- Hybris lexer
+* Kirk McDonald -- D lexer
+* Gordon McGregor -- SystemVerilog lexer
+* Stephen McKamey -- Duel/JBST lexer
+* Brian McKenna -- F# lexer
+* Lukas Meuser -- BBCode formatter, Lua lexer
+* Paul Miller -- LiveScript lexer
+* Hong Minhee -- HTTP lexer
+* Michael Mior -- Awk lexer
+* Jon Morton -- Rust lexer
+* Paulo Moura -- Logtalk lexer
+* Mher Movsisyan -- DTD lexer
+* Ana Nelson -- Ragel, ANTLR, R console lexers
+* Nam T. Nguyen -- Monokai style
+* Jesper Noehr -- HTML formatter "anchorlinenos"
+* Mike Nolta -- Julia lexer
+* Jonas Obrist -- BBCode lexer
+* David Oliva -- Rebol lexer
+* Jon Parise -- Protocol buffers lexer
+* Ronny Pfannschmidt -- BBCode lexer
+* Benjamin Peterson -- Test suite refactoring
+* Dominik Picheta -- Nimrod lexer
+* Clément Prévost -- UrbiScript lexer
+* Kashif Rasul -- CUDA lexer
+* Justin Reidy -- MXML lexer
+* Norman Richards -- JSON lexer
+* Lubomir Rintel -- GoodData MAQL and CL lexers
+* Andre Roberge -- Tango style
+* Konrad Rudolph -- LaTeX formatter enhancements
+* Mario Ruggier -- Evoque lexers
+* Stou Sandalski -- NumPy, FORTRAN, tcsh and XSLT lexers
+* Matteo Sasso -- Common Lisp lexer
+* Joe Schafer -- Ada lexer
+* Ken Schutte -- Matlab lexers
+* Tassilo Schweyer -- Io, MOOCode lexers
+* Joerg Sieker -- ABAP lexer
+* Robert Simmons -- Standard ML lexer
+* Kirill Simonov -- YAML lexer
+* Steve Spigarelli -- XQuery lexer
+* Jerome St-Louis -- eC lexer
+* James Strachan -- Kotlin lexer
+* Tiberius Teng -- default style overhaul
+* Jeremy Thurgood -- Erlang, Squid config lexers
+* Erick Tryzelaar -- Felix lexer
+* Daniele Varrazzo -- PostgreSQL lexers
+* Abe Voelker -- OpenEdge ABL lexer
+* Whitney Young -- ObjectiveC lexer
+* Matthias Vallentin -- Bro lexer
+* Nathan Weizenbaum -- Haml and Sass lexers
+* Dietmar Winkler -- Modelica lexer
+* Nils Winter -- Smalltalk lexer
+* Davy Wybiral -- Clojure lexer
+* Diego Zamboni -- CFengine3 lexer
+* Alex Zimin -- Nemerle lexer
+
+Many thanks for all contributions!
+
+# END pygments/AUTHORS #
diff --git a/app/server/vendor/rouge/README.md b/app/server/vendor/rouge/README.md
new file mode 100755
index 0000000..257e9ee
--- /dev/null
+++ b/app/server/vendor/rouge/README.md
@@ -0,0 +1,190 @@
+# Rouge
+
+[![Build Status](https://secure.travis-ci.org/jneen/rouge.png)](http://travis-ci.org/jneen/rouge)
+[![Gem Version](https://badge.fury.io/rb/rouge.png)](http://badge.fury.io/rb/rouge)
+
+Rouge is a pure-ruby syntax highlighter.  It can highlight over 60 languages, and output HTML or ANSI 256-color text.  Its HTML output is compatible with stylesheets designed for [pygments][].
+
+If you'd like to help out with this project, assign yourself something from the [issues][] page, and send me a pull request (even if it's not done yet!).  Bonus points for feature branches.  In particular, I would appreciate help with the following lexers, from someone who has more experience with the language than I do:
+
+* Delphi/Pascal
+
+Also, if anyone with design skills feels like helping me make a website for rouge, I'd really appreciate the help.  So far all I've got is the [demo page][pretty colors].
+
+[issues]: https://github.com/jayferd/rouge/issues "Help Out"
+[pygments]: http://pygments.org/ "Pygments"
+
+## Usage
+
+First, take a look at the [pretty colors][].
+
+[pretty colors]: http://rouge.jayferd.us/demo
+
+``` ruby
+# make some nice lexed html
+source = File.read('/etc/bashrc')
+formatter = Rouge::Formatters::HTML.new(css_class: 'highlight')
+lexer = Rouge::Lexers::Shell.new
+formatter.format(lexer.lex(source))
+
+# Get some CSS
+Rouge::Themes::Base16.mode(:light).render(scope: '.highlight')
+# Or use Theme#find with string input
+Rouge::Theme.find('base16.light').render(scope: '.highlight')
+```
+
+####Full options:
+
+Formatter options:
+
+      css_class: 'highlight'  #  Apply a class to the syntax-highlighted output.
+                              #  Set to false to not apply any css class
+      line_numbers: false     #  Generate line numbers.
+      start_line: 1           #  Index to start line numbers.
+      inline_theme: nil       #  A Rouge::CSSTheme used to highlight the output with inline styles
+                              #  instead of classes. Allows string inputs (separate mode with a dot):
+                              #  %w[colorful github monokai monokai.sublime thankful_eyes base16
+                              #     base16.dark base16.light base16.solarized base16.monokai]
+      wrap: true              #  Wrap the highlighted content in a container.
+                              #  Defaults to <pre><code>, or <div> if line numbers are enabled.
+
+Lexer options:
+
+      debug: false            #  Print a trace of the lex on stdout
+      parent: ''              #  Allows you to specify which language the template is inside
+
+CSS theme options:
+
+      scope: '.highlight'     #  CSS selector that styles are applied to
+                              #  E.g. Rouge::Themes::Monokai.mode(:sublime).render(scope: 'code')
+
+Rouge aims to be simple to extend, and to be a drop-in replacement for pygments, with the same quality of output.
+
+Also, Rouge ships with a `rougify` command which allows you to easily highlight files in your terminal:
+
+``` bash
+$ rougify foo.rb
+$ rougify style monokai.sublime > syntax.css
+```
+
+### Advantages to pygments.rb
+* No need to [spawn Python processes](https://github.com/tmm1/pygments.rb).
+
+### Advantages to CodeRay
+* The HTML output from Rouge is fully compatible with stylesheets designed for pygments.
+* The lexers are implemented with a dedicated DSL, rather than being hand-coded.
+* Rouge supports every language CodeRay does except for Pascal/Delphi (pull requests happily accepted!), and more.
+
+## You can even use it with Redcarpet
+
+``` ruby
+require 'redcarpet'
+require 'rouge'
+require 'rouge/plugins/redcarpet'
+
+class HTML < Redcarpet::Render::HTML
+  include Rouge::Plugins::Redcarpet # yep, that's it.
+end
+```
+
+If you have `:fenced_code_blocks` enabled, you can specify languages, and even options with CGI syntax, like `php?start_inline=1`, or `erb?parent=javascript`.
+
+## Encodings
+
+Rouge is only for UTF-8 strings.  If you'd like to highlight a string with a different encoding, please convert it to UTF-8 first.
+
+## Other integrations
+
+* Middleman: [middleman-syntax](https://github.com/middleman/middleman-syntax) (@bhollis)
+* Middleman: [middleman-rouge][] (@Linuus)
+* RDoc: [rdoc-rouge][] (@zzak)
+
+[middleman-rouge]: https://github.com/Linuus/middleman-rouge
+[rdoc-rouge]: https://github.com/zzak/rdoc-rouge
+
+## Contributing
+
+### Installing Ruby
+
+If you're here to implement a lexer for your awesome language, there's a good chance you don't already have a ruby development environment set up.  Follow the [instructions on the wiki](https://github.com/jayferd/rouge/wiki/Setting-up-Ruby) to get up and running.  If you have trouble getting set up, let me know - I'm always happy to help.
+
+### Run the tests
+
+You can test the core of Rouge simply by running `rake` (no `bundle exec` required).  It's also set up with `guard`, if you like.
+
+To test a lexer visually, run `rackup` from the root and go to `localhost:9292/#{some_lexer}` where `some_lexer` is the tag or an alias of a lexer you'd like to test.  If you add `?debug=1`, helpful debugging info will be printed on stdout.
+
+### API Documentation
+
+is at http://rubydoc.info/gems/rouge/frames.
+
+### Using the lexer DSL
+
+You can probably learn a lot just by reading through the existing lexers.  Basically, a lexer consists of a collection of states, each of which has several rules.  A rule consists of a regular expression and an action, which yields tokens and manipulates the state stack.  Each rule in the state on top of the stack is tried *in order* until a match is found, at which point the action is run, the match consumed from the stream, and the process repeated with the new lexer on the top of the stack.  Each lexer has a special state called `:root`, and the initial state stack consists of just this state.
+
+Here's how you might use it:
+
+``` ruby
+class MyLexer < Rouge::RegexLexer
+  state :root do
+    # the "easy way"
+
+    # simple rules
+    rule /0x[0-9a-f]+/, Num::Hex
+
+    # simple state stack manipulation
+    rule /{-/, Comment, :next_state
+    rule /-}/, Comment, :pop!
+
+    # the "flexible way"
+    rule /abc/ do |m|
+      # m is the match, for accessing match groups manually
+
+      # you can do the following things:
+      pop!
+      push :another_state
+      push # assumed to be the current state
+      state? :some_state # check if the current state is :some_state
+      in_state? :some_state # check if :some_state is in the state stack
+
+      # yield a token.  if no second argument is supplied, the value is
+      # taken to be the whole match.
+      # The sum of all the tokens yielded must be equivalent to the whole
+      # match - otherwise characters will go missing from the user's input.
+      token Generic::Output, m[0]
+
+      # calls SomeOtherLexer.lex(str) and yields its output.  See the
+      # HTML lexer for a nice example of this.
+      # if no second argument is supplied, it is assumed to be the whole
+      # match string.
+      delegate SomeOtherLexer, str
+
+      # the context object is the lexer itself, so you can stash state here
+      @count ||= 0
+      @count += 1
+
+      # advanced: push a dynamically created anonymous state
+      push do
+        rule /.../, Generic::Output
+      end
+    end
+
+    rule /(\w+)(:)/
+      # "groups" yields the matched groups in order
+      groups Name::Label, Punctuation
+    end
+  end
+
+  start do
+    # this is run whenever a fresh lex is started
+  end
+end
+```
+
+## Tips
+
+I don't get paid to maintain rouge.  [If you've found this software useful, consider dropping a tip in the bucket](http://www.gittip.com/jayferd).
+
+## License
+
+Rouge is released under the MIT license. Please see the `LICENSE` file for more information.
diff --git a/app/server/vendor/rouge/Rakefile b/app/server/vendor/rouge/Rakefile
new file mode 100755
index 0000000..b8baf7d
--- /dev/null
+++ b/app/server/vendor/rouge/Rakefile
@@ -0,0 +1,34 @@
+require 'rake/clean'
+require 'pathname'
+
+task :spec do
+  spec_files = FileList.new(ENV['files'] || './spec/**/*_spec.rb')
+  switch_spec_files = spec_files.map { |x| "-r#{x}" }.join(' ')
+  sh "ruby -I./lib -r ./spec/spec_helper #{switch_spec_files} -e Minitest::Unit.autorun"
+end
+
+task :doc do
+  sh 'bundle exec yard'
+end
+
+namespace :doc do
+  task :server do
+    sh 'bundle exec yard server --reload'
+  end
+
+  task :clean do
+    sh 'rm -rf ./doc/ ./.yardoc/'
+  end
+end
+
+CLEAN.include('*.gem')
+task :build => [:clean, :spec] do
+  puts
+  sh "gem build rouge.gemspec"
+end
+
+task :default => :spec
+
+Dir.glob(Pathname.new(__FILE__).dirname.join('tasks/*.rake')).each do |f|
+  load f
+end
diff --git a/app/server/vendor/rouge/bin/rougify b/app/server/vendor/rouge/bin/rougify
new file mode 100755
index 0000000..bee4b0a
--- /dev/null
+++ b/app/server/vendor/rouge/bin/rougify
@@ -0,0 +1,16 @@
+#!/usr/bin/env ruby
+
+require 'pathname'
+ROOT_DIR = Pathname.new(__FILE__).dirname.parent
+load ROOT_DIR.join('lib/rouge.rb')
+load ROOT_DIR.join('lib/rouge/cli.rb')
+
+begin
+  Rouge::CLI.parse(ARGV).run
+rescue Rouge::CLI::Error => e
+  puts e.message
+  exit e.status
+rescue Interrupt
+  $stderr.puts "\nrouge: interrupted"
+  exit 2
+end
diff --git a/app/server/vendor/rouge/config.ru b/app/server/vendor/rouge/config.ru
new file mode 100755
index 0000000..7754f04
--- /dev/null
+++ b/app/server/vendor/rouge/config.ru
@@ -0,0 +1,6 @@
+require 'pathname'
+
+here = Pathname.new(__FILE__).dirname
+load here.join('spec/visual/app.rb')
+
+run VisualTestApp
diff --git a/app/server/vendor/rouge/lib/rouge.rb b/app/server/vendor/rouge/lib/rouge.rb
new file mode 100755
index 0000000..6b32e4e
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge.rb
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*- #
+
+# stdlib
+require 'pathname'
+
+# The containing module for Rouge
+module Rouge
+  class << self
+    # Highlight some text with a given lexer and formatter.
+    #
+    # @example
+    #   Rouge.highlight('@foo = 1', 'ruby', 'html')
+    #   Rouge.highlight('var foo = 1;', 'js', 'terminal256')
+    #
+    #   # streaming - chunks become available as they are lexed
+    #   Rouge.highlight(large_string, 'ruby', 'html') do |chunk|
+    #     $stdout.print chunk
+    #   end
+    def highlight(text, lexer, formatter, &b)
+      lexer = Lexer.find(lexer) unless lexer.respond_to? :lex
+      raise "unknown lexer #{lexer}" unless lexer
+
+      formatter = Formatter.find(formatter) unless formatter.respond_to? :format
+      raise "unknown formatter #{formatter}" unless formatter
+
+      formatter.format(lexer.lex(text), &b)
+    end
+  end
+end
+
+load_dir = Pathname.new(__FILE__).dirname
+load load_dir.join('rouge/version.rb')
+
+load load_dir.join('rouge/util.rb')
+
+load load_dir.join('rouge/text_analyzer.rb')
+load load_dir.join('rouge/token.rb')
+
+load load_dir.join('rouge/lexer.rb')
+load load_dir.join('rouge/regex_lexer.rb')
+load load_dir.join('rouge/template_lexer.rb')
+
+Dir.glob(load_dir.join('rouge/lexers/*.rb')).each { |f| load f }
+
+load load_dir.join('rouge/formatter.rb')
+load load_dir.join('rouge/formatters/html.rb')
+load load_dir.join('rouge/formatters/terminal256.rb')
+load load_dir.join('rouge/formatters/null.rb')
+
+load load_dir.join('rouge/theme.rb')
+load load_dir.join('rouge/themes/thankful_eyes.rb')
+load load_dir.join('rouge/themes/colorful.rb')
+load load_dir.join('rouge/themes/base16.rb')
+load load_dir.join('rouge/themes/github.rb')
+load load_dir.join('rouge/themes/monokai.rb')
+load load_dir.join('rouge/themes/monokai_sublime.rb')
diff --git a/app/server/vendor/rouge/lib/rouge/cli.rb b/app/server/vendor/rouge/lib/rouge/cli.rb
new file mode 100755
index 0000000..0ae971a
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/cli.rb
@@ -0,0 +1,359 @@
+# -*- coding: utf-8 -*- #
+
+# not required by the main lib.
+# to use this module, require 'rouge/cli'.
+
+module Rouge
+  class FileReader
+    attr_reader :input
+    def initialize(input)
+      @input = input
+    end
+
+    def file
+      case input
+      when '-'
+        $stdin
+      when String
+        File.new(input)
+      when ->(i){ i.respond_to? :read }
+        input
+      end
+    end
+
+    def read
+      @read ||= begin
+        file.read
+      rescue => e
+        $stderr.puts "unable to open #{input}: #{e.message}"
+        exit 1
+      ensure
+        file.close
+      end
+    end
+  end
+
+  class CLI
+    def self.doc
+      return enum_for(:doc) unless block_given?
+
+      yield %|usage: rougify [command] [args...]|
+      yield %||
+      yield %|where <command> is one of:|
+      yield %|	highlight	#{Highlight.desc}|
+      yield %|	help		#{Help.desc}|
+      yield %|	style		#{Style.desc}|
+      yield %|	list		#{List.desc}|
+      yield %|	version		#{Version.desc}|
+      yield %||
+      yield %|See `rougify help <command>` for more info.|
+    end
+
+    class Error < StandardError
+      attr_reader :message, :status
+      def initialize(message, status=1)
+        @message = message
+        @status = status
+      end
+    end
+
+    def self.parse(argv=ARGV)
+      argv = normalize_syntax(argv)
+
+      mode = argv.shift
+
+      klass = class_from_arg(mode)
+      return klass.parse(argv) if klass
+
+      case mode
+      when '-h', '--help', 'help', '-help'
+        Help.parse(argv)
+      else
+        argv.unshift(mode) if mode
+        Highlight.parse(argv)
+      end
+    end
+
+    def initialize(options={})
+    end
+
+    def self.error!(msg, status=1)
+      raise Error.new(msg, status)
+    end
+
+    def error!(*a)
+      self.class.error!(*a)
+    end
+
+    def self.class_from_arg(arg)
+      case arg
+      when 'version', '--version'
+        Version
+      when 'help'
+        Help
+      when 'highlight', 'hi'
+        Highlight
+      when 'style'
+        Style
+      when 'list'
+        List
+      end
+    end
+
+    class Version < CLI
+      def self.desc
+        "print the rouge version number"
+      end
+
+      def self.parse(*); new; end
+
+      def run
+        puts Rouge.version
+      end
+    end
+
+    class Help < CLI
+      def self.desc
+        "print help info"
+      end
+
+      def self.doc
+        return enum_for(:doc) unless block_given?
+
+        yield %|usage: rougify help <command>|
+        yield %||
+        yield %|print help info for <command>.|
+      end
+
+      def self.parse(argv)
+        opts = { :mode => CLI }
+        until argv.empty?
+          arg = argv.shift
+          klass = class_from_arg(arg)
+          if klass
+            opts[:mode] = klass
+            next
+          end
+        end
+        new(opts)
+      end
+
+      def initialize(opts={})
+        @mode = opts[:mode]
+      end
+
+      def run
+        @mode.doc.each(&method(:puts))
+      end
+    end
+
+    class Highlight < CLI
+      def self.desc
+        "highlight code"
+      end
+
+      def self.doc
+        return enum_for(:doc) unless block_given?
+
+        yield %[usage: rougify highlight <filename> [options...]]
+        yield %[       rougify highlight [options...]]
+        yield %[]
+        yield %[--input-file|-i <filename>  specify a file to read, or - to use stdin]
+        yield %[]
+        yield %[--lexer|-l <lexer>          specify the lexer to use.]
+        yield %[                            If not provided, rougify will try to guess]
+        yield %[                            based on --mimetype, the filename, and the]
+        yield %[                            file contents.]
+        yield %[]
+        yield %[--mimetype|-m <mimetype>    specify a mimetype for lexer guessing]
+        yield %[]
+        yield %[--lexer-opts|-L <opts>      specify lexer options in CGI format]
+        yield %[                            (opt1=val1&opt2=val2)]
+        yield %[]
+        yield %[--formatter-opts|-F <opts>  specify formatter options in CGI format]
+        yield %[                            (opt1=val1&opt2=val2)]
+      end
+
+      def self.parse(argv)
+        opts = {
+          :formatter => 'terminal256',
+          :input_file => '-',
+          :lexer_opts => {},
+          :formatter_opts => {},
+        }
+
+        until argv.empty?
+          arg = argv.shift
+          case arg
+          when '--input-file', '-i'
+            opts[:input_file] = argv.shift
+          when '--mimetype', '-m'
+            opts[:mimetype] = argv.shift
+          when '--lexer', '-l'
+            opts[:lexer] = argv.shift
+          when '--formatter', '-f'
+            opts[:formatter] = argv.shift
+          when '--lexer-opts', '-L'
+            opts[:lexer_opts] = parse_cgi(argv.shift)
+          when '--formatter-opts', '-F'
+            opts[:formatter_opts] = parse_cgi(argv.shift)
+          when /^--/
+            error! "unknown option #{arg.inspect}"
+          else
+            opts[:input_file] = arg
+          end
+        end
+
+        new(opts)
+      end
+
+      def input_stream
+        @input_stream ||= FileReader.new(@input_file)
+      end
+
+      def input
+        @input ||= input_stream.read
+      end
+
+      def lexer_class
+        @lexer_class ||= Lexer.guess(
+          :filename => @input_file,
+          :mimetype => @mimetype,
+          :source => input_stream,
+        )
+      end
+
+      def lexer
+        @lexer ||= lexer_class.new(@lexer_opts)
+      end
+
+      attr_reader :input_file, :lexer_name, :mimetype, :formatter
+
+      def initialize(opts={})
+        @input_file = opts[:input_file]
+
+        if opts[:lexer]
+          @lexer_class = Lexer.find(opts[:lexer]) \
+            or error! "unkown lexer #{opts[:lexer].inspect}"
+        else
+          @lexer_name = opts[:lexer]
+          @mimetype = opts[:mimetype]
+        end
+
+        @lexer_opts = opts[:lexer_opts]
+
+        formatter_class = Formatter.find(opts[:formatter]) \
+          or error! "unknown formatter #{opts[:formatter]}"
+
+        @formatter = formatter_class.new(opts[:formatter_opts])
+      end
+
+      def run
+        formatter.format(lexer.lex(input), &method(:print))
+      end
+
+    private
+      def self.parse_cgi(str)
+        pairs = CGI.parse(str).map { |k, v| [k.to_sym, v.first] }
+        Hash[pairs]
+      end
+    end
+
+    class Style < CLI
+      def self.desc
+        "print CSS styles"
+      end
+
+      def self.doc
+        return enum_for(:doc) unless block_given?
+
+        yield %|usage: rougify style [<theme-name>] [<options>]|
+        yield %||
+        yield %|Print CSS styles for the given theme.  Extra options are|
+        yield %|passed to the theme.  Theme defaults to thankful_eyes.|
+        yield %||
+        yield %|options:|
+        yield %|  --scope	(default: .highlight) a css selector to scope by|
+        yield %||
+        yield %|available themes:|
+        yield %|  #{Theme.registry.keys.sort.join(', ')}|
+      end
+
+      def self.parse(argv)
+        opts = { :theme_name => 'thankful_eyes' }
+
+        until argv.empty?
+          arg = argv.shift
+          case arg
+          when /--(\w+)/
+            opts[$1.tr('-', '_').to_sym] = argv.shift
+          else
+            opts[:theme_name] = arg
+          end
+        end
+
+        new(opts)
+      end
+
+      def initialize(opts)
+        theme_name = opts.delete(:theme_name)
+        theme_class = Theme.find(theme_name) \
+          or error! "unknown theme: #{theme_name}"
+
+        @theme = theme_class.new(opts)
+      end
+
+      def run
+        @theme.render(&method(:puts))
+      end
+    end
+
+    class List < CLI
+      def self.desc
+        "list available lexers"
+      end
+
+      def self.doc
+        return enum_for(:doc) unless block_given?
+
+        yield %|usage: rouge list|
+        yield %||
+        yield %|print a list of all available lexers with their descriptions.|
+      end
+
+      def self.parse(argv)
+        new
+      end
+
+      def run
+        puts "== Available Lexers =="
+
+        Lexer.all.sort_by(&:tag).each do |lexer|
+          desc = "#{lexer.desc}"
+          if lexer.aliases.any?
+            desc << " [aliases: #{lexer.aliases.join(',')}]"
+          end
+          puts "%s: %s" % [lexer.tag, desc]
+          puts
+        end
+      end
+    end
+
+  private
+    def self.normalize_syntax(argv)
+      out = []
+      argv.each do |arg|
+        case arg
+        when /^(--\w+)=(.*)$/
+          out << $1 << $2
+        when /^(-\w)(.+)$/
+          out << $1 << $2
+        else
+          out << arg
+        end
+      end
+
+      out
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/demos/applescript b/app/server/vendor/rouge/lib/rouge/demos/applescript
new file mode 100755
index 0000000..c824919
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/applescript
@@ -0,0 +1,2 @@
+-- AppleScript playing with iTunes
+tell application "iTunes" to get current selection
diff --git a/app/server/vendor/rouge/lib/rouge/demos/c b/app/server/vendor/rouge/lib/rouge/demos/c
new file mode 100755
index 0000000..34771c8
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/c
@@ -0,0 +1,8 @@
+#include "ruby/ruby.h"
+
+static int
+clone_method_i(st_data_t key, st_data_t value, st_data_t data)
+{
+    clone_method((VALUE)data, (ID)key, (const rb_method_entry_t *)value);
+    return ST_CONTINUE;
+}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/clojure b/app/server/vendor/rouge/lib/rouge/demos/clojure
new file mode 100755
index 0000000..a9b682e
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/clojure
@@ -0,0 +1,5 @@
+(defn make-adder [x]
+  (let [y x]
+    (fn [z] (+ y z))))
+(def add2 (make-adder 2))
+(add2 4)
diff --git a/app/server/vendor/rouge/lib/rouge/demos/coffeescript b/app/server/vendor/rouge/lib/rouge/demos/coffeescript
new file mode 100755
index 0000000..a562db6
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/coffeescript
@@ -0,0 +1,5 @@
+# Objects:
+math =
+  root:   Math.sqrt
+  square: square
+  cube:   (x) -> x * square x
diff --git a/app/server/vendor/rouge/lib/rouge/demos/common_lisp b/app/server/vendor/rouge/lib/rouge/demos/common_lisp
new file mode 100755
index 0000000..c6d2861
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/common_lisp
@@ -0,0 +1 @@
+(defun square (x) (* x x))
diff --git a/app/server/vendor/rouge/lib/rouge/demos/conf b/app/server/vendor/rouge/lib/rouge/demos/conf
new file mode 100755
index 0000000..5386d4e
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/conf
@@ -0,0 +1,4 @@
+# A generic configuration file
+option1 "val1"
+option2 23
+option3 'val3'
diff --git a/app/server/vendor/rouge/lib/rouge/demos/cpp b/app/server/vendor/rouge/lib/rouge/demos/cpp
new file mode 100755
index 0000000..c20cf27
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/cpp
@@ -0,0 +1,8 @@
+#include<iostream>
+
+using namespace std;
+
+int main()
+{
+    cout << "Hello World" << endl;
+}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/csharp b/app/server/vendor/rouge/lib/rouge/demos/csharp
new file mode 100755
index 0000000..04e4a8e
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/csharp
@@ -0,0 +1,5 @@
+// reverse byte order (16-bit)
+public static UInt16 ReverseBytes(UInt16 value)
+{
+  return (UInt16)((value & 0xFFU) << 8 | (value & 0xFF00U) >> 8);
+}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/css b/app/server/vendor/rouge/lib/rouge/demos/css
new file mode 100755
index 0000000..0d1fe74
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/css
@@ -0,0 +1,4 @@
+body {
+    font-size: 12pt;
+    background: #fff url(temp.png) top left no-repeat;
+}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/diff b/app/server/vendor/rouge/lib/rouge/demos/diff
new file mode 100755
index 0000000..ab4f316
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/diff
@@ -0,0 +1,7 @@
+--- file1	2012-10-16 15:07:58.086886874 +0100
++++ file2	2012-10-16 15:08:07.642887236 +0100
+@@ -1,3 +1,3 @@
+ a b c
+-d e f
++D E F
+ g h i
diff --git a/app/server/vendor/rouge/lib/rouge/demos/elixir b/app/server/vendor/rouge/lib/rouge/demos/elixir
new file mode 100755
index 0000000..f81d641
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/elixir
@@ -0,0 +1 @@
+Enum.map([1,2,3], fn(x) -> x * 2 end)
diff --git a/app/server/vendor/rouge/lib/rouge/demos/erb b/app/server/vendor/rouge/lib/rouge/demos/erb
new file mode 100755
index 0000000..1f922b6
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/erb
@@ -0,0 +1 @@
+<title><%= @title %></title>
diff --git a/app/server/vendor/rouge/lib/rouge/demos/erlang b/app/server/vendor/rouge/lib/rouge/demos/erlang
new file mode 100755
index 0000000..c942b60
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/erlang
@@ -0,0 +1,7 @@
+%%% Geometry module.
+-module(geometry).
+-export([area/1]).
+
+%% Compute rectangle and circle area.
+area({rectangle, Width, Ht}) -> Width * Ht;
+area({circle, R})            -> 3.14159 * R * R.
\ No newline at end of file
diff --git a/app/server/vendor/rouge/lib/rouge/demos/factor b/app/server/vendor/rouge/lib/rouge/demos/factor
new file mode 100755
index 0000000..2538dff
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/factor
@@ -0,0 +1,5 @@
+USING: io kernel sequences ;
+
+4 iota [
+    "Happy Birthday " write 2 = "dear NAME" "to You" ? print
+] each
diff --git a/app/server/vendor/rouge/lib/rouge/demos/gherkin b/app/server/vendor/rouge/lib/rouge/demos/gherkin
new file mode 100755
index 0000000..6db139c
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/gherkin
@@ -0,0 +1,17 @@
+# language: en
+Feature: Addition
+  In order to avoid silly mistakes
+  As a math idiot
+  I want to be told the sum of two numbers
+
+  Scenario Outline: Add two numbers
+    Given I have entered <input_1> into the calculator
+    And I have entered <input_2> into the calculator
+    When I press <button>
+    Then the result should be <output> on the screen
+
+  Examples:
+    | input_1 | input_2 | button | output |
+    | 20      | 30      | add    | 50     |
+    | 2       | 5       | add    | 7      |
+    | 0       | 40      | add    | 40     |
diff --git a/app/server/vendor/rouge/lib/rouge/demos/go b/app/server/vendor/rouge/lib/rouge/demos/go
new file mode 100755
index 0000000..078ddff
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/go
@@ -0,0 +1,7 @@
+package main
+
+import "fmt"
+
+func main() {
+	fmt.Println("Hello, 世界")
+}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/groovy b/app/server/vendor/rouge/lib/rouge/demos/groovy
new file mode 100755
index 0000000..6be7311
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/groovy
@@ -0,0 +1,9 @@
+class Greet {
+  def name
+  Greet(who) { name = who[0].toUpperCase() +
+                      who[1..-1] }
+  def salute() { println "Hello $name!" }
+}
+
+g = new Greet('world')  // create object
+g.salute()               // output "Hello World!"
diff --git a/app/server/vendor/rouge/lib/rouge/demos/haml b/app/server/vendor/rouge/lib/rouge/demos/haml
new file mode 100755
index 0000000..4dcb687
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/haml
@@ -0,0 +1,5 @@
+%section.container
+  %h1= post.title
+  %h2= post.subtitle
+  .content
+    = post.content
diff --git a/app/server/vendor/rouge/lib/rouge/demos/handlebars b/app/server/vendor/rouge/lib/rouge/demos/handlebars
new file mode 100755
index 0000000..6dc4a7e
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/handlebars
@@ -0,0 +1,7 @@
+<div class="entry">
+  <h1>{{title}}</h1>
+  {{#with story}}
+    <div class="intro">{{{intro}}}</div>
+    <div class="body">{{{body}}}</div>
+  {{/with}}
+</div>
diff --git a/app/server/vendor/rouge/lib/rouge/demos/haskell b/app/server/vendor/rouge/lib/rouge/demos/haskell
new file mode 100755
index 0000000..2672159
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/haskell
@@ -0,0 +1,6 @@
+quicksort :: Ord a => [a] -> [a]
+quicksort []     = []
+quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
+    where
+        lesser  = filter (< p) xs
+        greater = filter (>= p) xs
diff --git a/app/server/vendor/rouge/lib/rouge/demos/html b/app/server/vendor/rouge/lib/rouge/demos/html
new file mode 100755
index 0000000..9329a37
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/html
@@ -0,0 +1,8 @@
+<html>
+  <head><title>Title!</title></head>
+  <body>
+    <p id="foo">Hello, World!</p>
+    <script type="text/javascript">var a = 1;</script>
+    <style type="text/css">#foo { font-weight: bold; }</style>
+  </body>
+</html>
diff --git a/app/server/vendor/rouge/lib/rouge/demos/http b/app/server/vendor/rouge/lib/rouge/demos/http
new file mode 100755
index 0000000..1b45b10
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/http
@@ -0,0 +1,14 @@
+POST /demo/submit/ HTTP/1.1
+Host: rouge.jayferd.us
+Cache-Control: max-age=0
+Origin: http://rouge.jayferd.us
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2)
+    AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7
+Content-Type: application/json
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
+Referer: http://pygments.org/
+Accept-Encoding: gzip,deflate,sdch
+Accept-Language: en-US,en;q=0.8
+Accept-Charset: windows-949,utf-8;q=0.7,*;q=0.3
+
+{"name":"test","lang":"text","boring":true}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/ini b/app/server/vendor/rouge/lib/rouge/demos/ini
new file mode 100755
index 0000000..f600c91
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/ini
@@ -0,0 +1,4 @@
+; last modified 1 April 2001 by John Doe
+[owner]
+name=John Doe
+organization=Acme Widgets Inc.
diff --git a/app/server/vendor/rouge/lib/rouge/demos/io b/app/server/vendor/rouge/lib/rouge/demos/io
new file mode 100755
index 0000000..05f0a20
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/io
@@ -0,0 +1,11 @@
+bottle := method(i,
+  if(i==0, return "no more bottles of beer")
+  if(i==1, return "1 bottle of beer")
+  return i asString .. " bottles of beer"
+)
+
+for(i, 99, 1, -1,
+  write(bottle(i), " on the wall, ", bottle(i), ",\n")
+  write("take one down, pass it around,\n")
+  write(bottle(i - 1), " on the wall.\n\n")
+)
diff --git a/app/server/vendor/rouge/lib/rouge/demos/java b/app/server/vendor/rouge/lib/rouge/demos/java
new file mode 100755
index 0000000..0cca61e
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/java
@@ -0,0 +1,5 @@
+public class java {
+    public static void main(String[] args) {
+        System.out.println("Hello World");
+    }
+}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/javascript b/app/server/vendor/rouge/lib/rouge/demos/javascript
new file mode 100755
index 0000000..134a70e
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/javascript
@@ -0,0 +1 @@
+$(document).ready(function() { alert('ready!'); });
diff --git a/app/server/vendor/rouge/lib/rouge/demos/json b/app/server/vendor/rouge/lib/rouge/demos/json
new file mode 100755
index 0000000..eead967
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/json
@@ -0,0 +1 @@
+{ "one": 1, "two": 2, "null": null, "simple": true }
diff --git a/app/server/vendor/rouge/lib/rouge/demos/literate_coffeescript b/app/server/vendor/rouge/lib/rouge/demos/literate_coffeescript
new file mode 100755
index 0000000..0e5f25f
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/literate_coffeescript
@@ -0,0 +1,3 @@
+Import the helpers we plan to use.
+
+    {extend, last} = require './helpers'
diff --git a/app/server/vendor/rouge/lib/rouge/demos/literate_haskell b/app/server/vendor/rouge/lib/rouge/demos/literate_haskell
new file mode 100755
index 0000000..10e7535
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/literate_haskell
@@ -0,0 +1,7 @@
+In Bird-style you have to leave a blank before the code.
+
+> fact :: Integer -> Integer
+> fact 0 = 1
+> fact n = n * fact (n-1)
+
+And you have to leave a blank line after the code as well.
diff --git a/app/server/vendor/rouge/lib/rouge/demos/llvm b/app/server/vendor/rouge/lib/rouge/demos/llvm
new file mode 100755
index 0000000..c4596a8
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/llvm
@@ -0,0 +1,20 @@
+; copied from http://llvm.org/docs/LangRef.html#module-structure
+; Declare the string constant as a global constant.
+ at .str = private unnamed_addr constant [13 x i8] c"hello world\0A\00"
+
+; External declaration of the puts function
+declare i32 @puts(i8* nocapture) nounwind
+
+; Definition of main function
+define i32 @main() {   ; i32()*
+  ; Convert [13 x i8]* to i8  *...
+  %cast210 = getelementptr [13 x i8]* @.str, i64 0, i64 0
+
+  ; Call puts function to write out the string to stdout.
+  call i32 @puts(i8* %cast210)
+  ret i32 0
+}
+
+; Named metadata
+!1 = metadata !{i32 42}
+!foo = !{!1, null}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/lua b/app/server/vendor/rouge/lib/rouge/demos/lua
new file mode 100755
index 0000000..2abebae
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/lua
@@ -0,0 +1,12 @@
+-- defines a factorial function
+function fact (n)
+  if n == 0 then
+    return 1
+  else
+    return n * fact(n-1)
+  end
+end
+    
+print("enter a number:")
+a = io.read("*number")        -- read a number
+print(fact(a))
diff --git a/app/server/vendor/rouge/lib/rouge/demos/make b/app/server/vendor/rouge/lib/rouge/demos/make
new file mode 100755
index 0000000..cdac715
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/make
@@ -0,0 +1,6 @@
+.PHONY: all
+all: $(OBJ)
+
+$(OBJ): $(SOURCE)
+	@echo "compiling..."
+	$(GCC) $(CFLAGS) $< > $@
diff --git a/app/server/vendor/rouge/lib/rouge/demos/markdown b/app/server/vendor/rouge/lib/rouge/demos/markdown
new file mode 100755
index 0000000..5e36314
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/markdown
@@ -0,0 +1,4 @@
+Markdown has cool [reference links][ref 1]
+and [regular links too](http://example.com)
+
+[ref 1]: http://example.com
diff --git a/app/server/vendor/rouge/lib/rouge/demos/matlab b/app/server/vendor/rouge/lib/rouge/demos/matlab
new file mode 100755
index 0000000..3777fb5
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/matlab
@@ -0,0 +1,6 @@
+A = cat( 3, [1 2 3; 9 8 7; 4 6 5], [0 3 2; 8 8 4; 5 3 5], ...
+                 [6 4 7; 6 8 5; 5 4 3]);
+% The EIG function is applied to each of the horizontal 'slices' of A.
+for i = 1:3
+    eig(squeeze(A(i,:,:)))
+end
diff --git a/app/server/vendor/rouge/lib/rouge/demos/moonscript b/app/server/vendor/rouge/lib/rouge/demos/moonscript
new file mode 100755
index 0000000..4c8511d
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/moonscript
@@ -0,0 +1,16 @@
+util = require "my.module"
+
+a_table = {
+  foo: 'bar'
+  interpolated: "foo-#{other.stuff 2 + 3}"
+  "string": 2
+  do: 'keyword'
+}
+
+class MyClass extends SomeClass
+  new: (@init, arg2 = 'default') =>
+    @derived = @init + 2
+    super!
+
+  other: =>
+    @foo + 2
diff --git a/app/server/vendor/rouge/lib/rouge/demos/nginx b/app/server/vendor/rouge/lib/rouge/demos/nginx
new file mode 100755
index 0000000..0288770
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/nginx
@@ -0,0 +1,5 @@
+server {
+  listen          80;
+  server_name     example.com *.example.com;
+  rewrite ^       http://www.domain.com$request_uri? permanent;
+}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/objective_c b/app/server/vendor/rouge/lib/rouge/demos/objective_c
new file mode 100755
index 0000000..15566f3
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/objective_c
@@ -0,0 +1,12 @@
+ at interface Person : NSObject {
+  @public
+  NSString *name;
+  @private
+  int age;
+}
+
+ at property(copy) NSString *name;
+ at property(readonly) int age;
+
+-(id)initWithAge:(int)age;
+ at end
diff --git a/app/server/vendor/rouge/lib/rouge/demos/ocaml b/app/server/vendor/rouge/lib/rouge/demos/ocaml
new file mode 100755
index 0000000..e09cf09
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/ocaml
@@ -0,0 +1,12 @@
+(* Binary tree with leaves car­rying an integer. *)
+type tree = Leaf of int | Node of tree * tree
+
+let rec exists_leaf test tree =
+  match tree with
+  | Leaf v -> test v
+  | Node (left, right) ->
+      exists_leaf test left
+      || exists_leaf test right
+
+let has_even_leaf tree =
+  exists_leaf (fun n -> n mod 2 = 0) tree
diff --git a/app/server/vendor/rouge/lib/rouge/demos/perl b/app/server/vendor/rouge/lib/rouge/demos/perl
new file mode 100755
index 0000000..a966445
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/perl
@@ -0,0 +1,5 @@
+#!/usr/bin/env perl
+use warnings;
+print "a: ";
+my $a = "foo";
+print $a;
diff --git a/app/server/vendor/rouge/lib/rouge/demos/php b/app/server/vendor/rouge/lib/rouge/demos/php
new file mode 100755
index 0000000..7ca7fe6
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/php
@@ -0,0 +1,3 @@
+<?php
+  print("Hello {$world}");
+?>
diff --git a/app/server/vendor/rouge/lib/rouge/demos/plaintext b/app/server/vendor/rouge/lib/rouge/demos/plaintext
new file mode 100755
index 0000000..60180f7
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/plaintext
@@ -0,0 +1 @@
+plain text :)
diff --git a/app/server/vendor/rouge/lib/rouge/demos/prolog b/app/server/vendor/rouge/lib/rouge/demos/prolog
new file mode 100755
index 0000000..8430e6b
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/prolog
@@ -0,0 +1,9 @@
+diff(plus(A,B), X, plus(DA, DB))
+   <= diff(A, X, DA) and diff(B, X, DB).
+
+diff(times(A,B), X, plus(times(A, DB), times(DA, B)))
+   <= diff(A, X, DA) and diff(B, X, DB).
+
+equal(X, X).
+diff(X, X, 1).
+diff(Y, X, 0) <= not equal(Y, X).
diff --git a/app/server/vendor/rouge/lib/rouge/demos/properties b/app/server/vendor/rouge/lib/rouge/demos/properties
new file mode 100755
index 0000000..b5b717d
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/properties
@@ -0,0 +1,7 @@
+# You are reading the ".properties" entry.
+! The exclamation mark can also mark text as comments.
+website = http\://en.wikipedia.org/
+language = English
+country : Poland
+continent=Europe
+key.with.dots=This is the value that could be looked up with the key "key.with.dots".
diff --git a/app/server/vendor/rouge/lib/rouge/demos/puppet b/app/server/vendor/rouge/lib/rouge/demos/puppet
new file mode 100755
index 0000000..621d9c9
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/puppet
@@ -0,0 +1,6 @@
+service { 'ntp':
+  name      => $service_name,
+  ensure    => running,
+  enable    => true,
+  subscribe => File['ntp.conf'],
+}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/python b/app/server/vendor/rouge/lib/rouge/demos/python
new file mode 100755
index 0000000..77a5cb3
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/python
@@ -0,0 +1,6 @@
+def fib(n):    # write Fibonacci series up to n
+    """Print a Fibonacci series up to n."""
+    a, b = 0, 1
+    while a < n:
+        print a,
+        a, b = b, a+b
diff --git a/app/server/vendor/rouge/lib/rouge/demos/qml b/app/server/vendor/rouge/lib/rouge/demos/qml
new file mode 100755
index 0000000..9aacda6
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+Item {
+    width: 200
+    height: 100
+    MouseArea {
+        anchors.fill: parent
+        onClicked: Qt.quit()
+    }
+}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/r b/app/server/vendor/rouge/lib/rouge/demos/r
new file mode 100755
index 0000000..b6804b0
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/r
@@ -0,0 +1,8 @@
+dbenford <- function(x){
+    log10(1 + 1/x)
+}
+
+pbenford <- function(q){
+    cumprobs <- cumsum(dbenford(1:9))
+    return(cumprobs[q])
+}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/racket b/app/server/vendor/rouge/lib/rouge/demos/racket
new file mode 100755
index 0000000..bd99818
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/racket
@@ -0,0 +1,24 @@
+#lang racket
+
+;; draw a graph of cos and deriv^3(cos)
+(require plot)
+(define ((deriv f) x)
+  (/ (- (f x) (f (- x 0.001))) 0.001))
+(define (thrice f) (lambda (x) (f (f (f x)))))
+(plot (list (function ((thrice deriv) sin) -5 5)
+            (function cos -5 5 #:color 'blue)))
+
+;; Print the Greek alphabet
+(for ([i (in-range 25)])
+  (displayln
+   (integer->char
+    (+ i (char->integer #\u3B1)))))
+
+;; An echo server
+(define listener (tcp-listen 12345))
+(let echo-server ()
+  (define-values (in out) (tcp-accept listener))
+  (thread (λ ()
+             (copy-port in out)
+             (close-output-port out)))
+  (echo-server))
diff --git a/app/server/vendor/rouge/lib/rouge/demos/ruby b/app/server/vendor/rouge/lib/rouge/demos/ruby
new file mode 100755
index 0000000..be609a1
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/ruby
@@ -0,0 +1,9 @@
+class Greeter
+  def initialize(name="World")
+    @name = name
+  end
+
+  def say_hi
+    puts "Hi #{@name}!"
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/demos/rust b/app/server/vendor/rouge/lib/rouge/demos/rust
new file mode 100755
index 0000000..b73b162
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/rust
@@ -0,0 +1,12 @@
+use core::*;
+
+fn main() {
+    for ["Alice", "Bob", "Carol"].each |&name| {
+        do task::spawn {
+            let v = rand::Rng().shuffle([1, 2, 3]);
+            for v.each |&num| {
+                io::print(fmt!("%s says: '%d'\n", name, num))
+            }
+        }
+    }
+}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/sass b/app/server/vendor/rouge/lib/rouge/demos/sass
new file mode 100755
index 0000000..1e768de
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/sass
@@ -0,0 +1,3 @@
+ at for $i from 1 through 3
+  .item-#{$i}
+    width: 2em * $i
diff --git a/app/server/vendor/rouge/lib/rouge/demos/scala b/app/server/vendor/rouge/lib/rouge/demos/scala
new file mode 100755
index 0000000..75f19ee
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/scala
@@ -0,0 +1,3 @@
+class Greeter(name: String = "World") {
+  def sayHi() { println("Hi " + name + "!") }
+}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/scheme b/app/server/vendor/rouge/lib/rouge/demos/scheme
new file mode 100755
index 0000000..c9c4dbd
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/scheme
@@ -0,0 +1,4 @@
+(define Y
+  (lambda (m)
+    ((lambda (f) (m (lambda (a) ((f f) a))))
+     (lambda (f) (m (lambda (a) ((f f) a)))))))
diff --git a/app/server/vendor/rouge/lib/rouge/demos/scss b/app/server/vendor/rouge/lib/rouge/demos/scss
new file mode 100755
index 0000000..3f259a7
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/scss
@@ -0,0 +1,5 @@
+ at for $i from 1 through 3 {
+  .item-#{$i} {
+    width: 2em * $i;
+  }
+}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/sed b/app/server/vendor/rouge/lib/rouge/demos/sed
new file mode 100755
index 0000000..4683cd3
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/sed
@@ -0,0 +1,4 @@
+/begin/,/end/ {
+  /begin/n # skip over the line that has "begin" on it
+  s/old/new/
+}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/shell b/app/server/vendor/rouge/lib/rouge/demos/shell
new file mode 100755
index 0000000..f01fe48
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/shell
@@ -0,0 +1,2 @@
+# If not running interactively, don't do anything
+[[ -z "$PS1" ]] && return
diff --git a/app/server/vendor/rouge/lib/rouge/demos/slim b/app/server/vendor/rouge/lib/rouge/demos/slim
new file mode 100755
index 0000000..215a4e2
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/slim
@@ -0,0 +1,17 @@
+doctype html
+html
+  body
+    h1 Markup examples   
+    #content
+      p 
+      | Slim can have #{ruby_code} interpolated!
+      /[if IE]
+        javascript:
+          alert('Slim supports embedded javascript!')
+
+      - unless items.empty?
+        table
+          - for item in items do
+            tr
+              td.name = item.name
+              td.price = item.price
diff --git a/app/server/vendor/rouge/lib/rouge/demos/smalltalk b/app/server/vendor/rouge/lib/rouge/demos/smalltalk
new file mode 100755
index 0000000..af97161
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/smalltalk
@@ -0,0 +1,6 @@
+quadMultiply: i1 and: i2 
+    "This method multiplies the given numbers by each other
+    and the result by 4."
+    | mul |
+    mul := i1 * i2.
+    ^mul * 4
diff --git a/app/server/vendor/rouge/lib/rouge/demos/sml b/app/server/vendor/rouge/lib/rouge/demos/sml
new file mode 100755
index 0000000..02a57d3
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/sml
@@ -0,0 +1,4 @@
+datatype shape
+   = Circle   of loc * real      (* center and radius *)
+   | Square   of loc * real      (* upper-left corner and side length; axis-aligned *)
+   | Triangle of loc * loc * loc (* corners *)
diff --git a/app/server/vendor/rouge/lib/rouge/demos/sql b/app/server/vendor/rouge/lib/rouge/demos/sql
new file mode 100755
index 0000000..45a7a17
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/sql
@@ -0,0 +1 @@
+SELECT * FROM `users` WHERE `user`.`id` = 1
diff --git a/app/server/vendor/rouge/lib/rouge/demos/swift b/app/server/vendor/rouge/lib/rouge/demos/swift
new file mode 100755
index 0000000..0c54ed2
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/swift
@@ -0,0 +1,5 @@
+// Say hello to poeple
+func sayHello(personName: String) -> String {
+    let greeting = "Hello, " + personName + "!"
+    return greeting
+}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/tcl b/app/server/vendor/rouge/lib/rouge/demos/tcl
new file mode 100755
index 0000000..9bbe87c
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/tcl
@@ -0,0 +1 @@
+proc cross_sum {s} {expr [join [split $s ""] +]}
diff --git a/app/server/vendor/rouge/lib/rouge/demos/tex b/app/server/vendor/rouge/lib/rouge/demos/tex
new file mode 100755
index 0000000..430510f
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/tex
@@ -0,0 +1 @@
+To write \LaTeX\ you would type \verb:\LaTeX:.
diff --git a/app/server/vendor/rouge/lib/rouge/demos/toml b/app/server/vendor/rouge/lib/rouge/demos/toml
new file mode 100755
index 0000000..40c11c1
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/toml
@@ -0,0 +1,9 @@
+# This is a TOML document. Boom.
+
+title = "TOML Example"
+
+[owner]
+name = "Tom Preston-Werner"
+organization = "GitHub"
+bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
+dob = 1979-05-27T07:32:00Z # First class dates? Why not?
diff --git a/app/server/vendor/rouge/lib/rouge/demos/vb b/app/server/vendor/rouge/lib/rouge/demos/vb
new file mode 100755
index 0000000..f7e323d
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/vb
@@ -0,0 +1,4 @@
+Private Sub Form_Load()
+    ' Execute a simple message box that says "Hello, World!"
+    MsgBox "Hello, World!"
+End Sub
diff --git a/app/server/vendor/rouge/lib/rouge/demos/viml b/app/server/vendor/rouge/lib/rouge/demos/viml
new file mode 100755
index 0000000..9393d9b
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/viml
@@ -0,0 +1,5 @@
+set encoding=utf-8
+
+filetype off
+call pathogen#runtime_append_all_bundles()
+filetype plugin indent on
diff --git a/app/server/vendor/rouge/lib/rouge/demos/xml b/app/server/vendor/rouge/lib/rouge/demos/xml
new file mode 100755
index 0000000..149844b
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:template match="/"></xsl:template>
diff --git a/app/server/vendor/rouge/lib/rouge/demos/yaml b/app/server/vendor/rouge/lib/rouge/demos/yaml
new file mode 100755
index 0000000..2f622de
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/demos/yaml
@@ -0,0 +1,4 @@
+---
+one: Mark McGwire
+two: Sammy Sosa
+three: Ken Griffey
diff --git a/app/server/vendor/rouge/lib/rouge/formatter.rb b/app/server/vendor/rouge/lib/rouge/formatter.rb
new file mode 100755
index 0000000..646ae8d
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/formatter.rb
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  # A Formatter takes a token stream and formats it for human viewing.
+  class Formatter
+    # @private
+    REGISTRY = {}
+
+    # Specify or get the unique tag for this formatter.  This is used
+    # for specifying a formatter in `rougify`.
+    def self.tag(tag=nil)
+      return @tag unless tag
+      REGISTRY[tag] = self
+
+      @tag = tag
+    end
+
+    # Find a formatter class given a unique tag.
+    def self.find(tag)
+      REGISTRY[tag]
+    end
+
+    # Format a token stream.  Delegates to {#format}.
+    def self.format(tokens, opts={}, &b)
+      new(opts).format(tokens, &b)
+    end
+
+    # Format a token stream.
+    def format(tokens, &b)
+      return stream(tokens, &b) if block_given?
+
+      out = ''
+      stream(tokens) { |piece| out << piece }
+
+      out
+    end
+
+    # @deprecated Use {#format} instead.
+    def render(tokens)
+      warn 'Formatter#render is deprecated, use #format instead.'
+      format(tokens)
+    end
+
+    # @abstract
+    # yield strings that, when concatenated, form the formatted output
+    def stream(tokens, &b)
+      raise 'abstract'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/formatters/html.rb b/app/server/vendor/rouge/lib/rouge/formatters/html.rb
new file mode 100755
index 0000000..0f4092d
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/formatters/html.rb
@@ -0,0 +1,117 @@
+# -*- coding: utf-8 -*- #
+
+# stdlib
+require 'cgi'
+
+module Rouge
+  module Formatters
+    # Transforms a token stream into HTML output.
+    class HTML < Formatter
+      tag 'html'
+
+      # @option opts [String] :css_class ('highlight')
+      # @option opts [true/false] :line_numbers (false)
+      # @option opts [Rouge::CSSTheme] :inline_theme (nil)
+      # @option opts [true/false] :wrap (true)
+      #
+      # Initialize with options.
+      #
+      # If `:inline_theme` is given, then instead of rendering the
+      # tokens as <span> tags with CSS classes, the styles according to
+      # the given theme will be inlined in "style" attributes.  This is
+      # useful for formats in which stylesheets are not available.
+      #
+      # Content will be wrapped in a tag (`div` if tableized, `pre` if
+      # not) with the given `:css_class` unless `:wrap` is set to `false`.
+      def initialize(opts={})
+        @css_class = opts.fetch(:css_class, 'highlight')
+        @css_class = " class=#{@css_class.inspect}" if @css_class
+
+        @line_numbers = opts.fetch(:line_numbers, false)
+        @start_line = opts.fetch(:start_line, 1)
+        @inline_theme = opts.fetch(:inline_theme, nil)
+        @inline_theme = Theme.find(@inline_theme).new if @inline_theme.is_a? String
+
+        @wrap = opts.fetch(:wrap, true)
+      end
+
+      # @yield the html output.
+      def stream(tokens, &b)
+        if @line_numbers
+          stream_tableized(tokens, &b)
+        else
+          stream_untableized(tokens, &b)
+        end
+      end
+
+    private
+      def stream_untableized(tokens, &b)
+        yield "<pre><code#@css_class>" if @wrap
+        tokens.each{ |tok, val| span(tok, val, &b) }
+        yield "</code></pre>\n" if @wrap
+      end
+
+      def stream_tableized(tokens)
+        num_lines = 0
+        last_val = ''
+        formatted = ''
+
+        tokens.each do |tok, val|
+          last_val = val
+          num_lines += val.scan(/\n/).size
+          span(tok, val) { |str| formatted << str }
+        end
+
+        # add an extra line for non-newline-terminated strings
+        if last_val[-1] != "\n"
+          num_lines += 1
+          span(Token::Tokens::Text::Whitespace, "\n") { |str| formatted << str }
+        end
+
+        # generate a string of newline-separated line numbers for the gutter>
+        numbers = %<<pre class="lineno">#{(@start_line..num_lines+ at start_line-1)
+          .to_a.join("\n")}</pre>>
+
+        yield "<div#@css_class>" if @wrap
+        yield '<table style="border-spacing: 0"><tbody><tr>'
+
+        # the "gl" class applies the style for Generic.Lineno
+        yield '<td class="gutter gl" style="text-align: right">'
+        yield numbers
+        yield '</td>'
+
+        yield '<td class="code">'
+        yield '<pre>'
+        yield formatted
+        yield '</pre>'
+        yield '</td>'
+
+        yield "</tr></tbody></table>\n"
+        yield "</div>\n" if @wrap
+      end
+
+      TABLE_FOR_ESCAPE_HTML = {
+        '&' => '&',
+        '<' => '<',
+        '>' => '>',
+      }
+
+      def span(tok, val)
+        val = val.gsub(/[&<>]/, TABLE_FOR_ESCAPE_HTML)
+        shortname = tok.shortname or raise "unknown token: #{tok.inspect} for #{val.inspect}"
+
+        if shortname.empty?
+          yield val
+        else
+          if @inline_theme
+            rules = @inline_theme.style_for(tok).rendered_rules
+
+            yield "<span style=\"#{rules.to_a.join(';')}\">#{val}</span>"
+          else
+            yield "<span class=\"#{shortname}\">#{val}</span>"
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/formatters/null.rb b/app/server/vendor/rouge/lib/rouge/formatters/null.rb
new file mode 100755
index 0000000..4805ae2
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/formatters/null.rb
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Formatters
+    # A formatter which renders nothing.
+    class Null < Formatter
+      tag 'null'
+
+      def initialize(*)
+      end
+
+      def stream(tokens, &b)
+        tokens.to_a
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/formatters/terminal256.rb b/app/server/vendor/rouge/lib/rouge/formatters/terminal256.rb
new file mode 100755
index 0000000..5a2e6e5
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/formatters/terminal256.rb
@@ -0,0 +1,176 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Formatters
+    # A formatter for 256-color terminals
+    class Terminal256 < Formatter
+      tag 'terminal256'
+
+      # @private
+      attr_reader :theme
+
+
+      # @option opts :theme
+      #   (default is thankful_eyes) the theme to render with.
+      def initialize(opts={})
+        @theme = opts[:theme] || 'thankful_eyes'
+        @theme = Theme.find(@theme) if @theme.is_a? String
+      end
+
+      def stream(tokens, &b)
+        tokens.each do |tok, val|
+          escape = escape_sequence(tok)
+          yield escape.style_string
+          yield val.gsub("\n", "\n#{escape.style_string}")
+          yield escape.reset_string
+        end
+      end
+
+      class EscapeSequence
+        attr_reader :style
+        def initialize(style)
+          @style = style
+        end
+
+        def self.xterm_colors
+          @xterm_colors ||= [].tap do |out|
+            # colors 0..15: 16 basic colors
+            out << [0x00, 0x00, 0x00] # 0
+            out << [0xcd, 0x00, 0x00] # 1
+            out << [0x00, 0xcd, 0x00] # 2
+            out << [0xcd, 0xcd, 0x00] # 3
+            out << [0x00, 0x00, 0xee] # 4
+            out << [0xcd, 0x00, 0xcd] # 5
+            out << [0x00, 0xcd, 0xcd] # 6
+            out << [0xe5, 0xe5, 0xe5] # 7
+            out << [0x7f, 0x7f, 0x7f] # 8
+            out << [0xff, 0x00, 0x00] # 9
+            out << [0x00, 0xff, 0x00] # 10
+            out << [0xff, 0xff, 0x00] # 11
+            out << [0x5c, 0x5c, 0xff] # 12
+            out << [0xff, 0x00, 0xff] # 13
+            out << [0x00, 0xff, 0xff] # 14
+            out << [0xff, 0xff, 0xff] # 15
+
+            # colors 16..232: the 6x6x6 color cube
+            valuerange = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]
+
+            217.times do |i|
+              r = valuerange[(i / 36) % 6]
+              g = valuerange[(i / 6) % 6]
+              b = valuerange[i % 6]
+              out << [r, g, b]
+            end
+
+            # colors 233..253: grayscale
+            1.upto 22 do |i|
+              v = 8 + i * 10
+              out << [v, v, v]
+            end
+          end
+        end
+
+        def fg
+          return @fg if instance_variable_defined? :@fg
+          @fg = style.fg && self.class.color_index(style.fg)
+        end
+
+        def bg
+          return @bg if instance_variable_defined? :@bg
+          @bg = style.bg && self.class.color_index(style.bg)
+        end
+
+        def style_string
+          @style_string ||= begin
+            attrs = []
+
+            attrs << ['38', '5', fg.to_s] if fg
+            attrs << ['48', '5', bg.to_s] if bg
+            attrs << '01' if style[:bold]
+            attrs << '04' if style[:italic] # underline, but hey, whatevs
+            escape(attrs)
+          end
+        end
+
+        def reset_string
+          @reset_string ||= begin
+            attrs = []
+            attrs << '39' if fg # fg reset
+            attrs << '49' if bg # bg reset
+            attrs << '00' if style[:bold] || style[:italic]
+
+            escape(attrs)
+          end
+        end
+
+      private
+        def escape(attrs)
+          return '' if attrs.empty?
+          "\e[#{attrs.join(';')}m"
+        end
+
+        def self.color_index(color)
+          @color_index_cache ||= {}
+          @color_index_cache[color] ||= closest_color(*get_rgb(color))
+        end
+
+        def self.get_rgb(color)
+          color = $1 if color =~ /#([0-9a-f]+)/i
+          hexes = case color.size
+          when 3
+            color.chars.map { |c| "#{c}#{c}" }
+          when 6
+            color.scan(/../)
+          else
+            raise "invalid color: #{color}"
+          end
+
+          hexes.map { |h| h.to_i(16) }
+        end
+
+        # max distance between two colors, #000000 to #ffffff
+        MAX_DISTANCE = 257 * 257 * 3
+
+        def self.closest_color(r, g, b)
+          @@colors_cache ||= {}
+          key = (r << 16) + (g << 8) + b
+          @@colors_cache.fetch(key) do
+            distance = MAX_DISTANCE
+
+            match = 0
+
+            xterm_colors.each_with_index do |(cr, cg, cb), i|
+              d = (r - cr)**2 + (g - cg)**2 + (b - cb)**2
+              next if d >= distance
+
+              match = i
+              distance = d
+            end
+
+            match
+          end
+        end
+      end
+
+    # private
+      def escape_sequence(token)
+        @escape_sequences ||= {}
+        @escape_sequences[token.name] ||=
+          EscapeSequence.new(get_style(token))
+      end
+
+      def get_style(token)
+        return text_style if token.ancestors.include? Token::Tokens::Text
+
+        theme.get_own_style(token) || text_style
+      end
+
+      def text_style
+        style = theme.get_style(Token['Text'])
+        # don't highlight text backgrounds
+        style.delete :bg
+        style
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexer.rb b/app/server/vendor/rouge/lib/rouge/lexer.rb
new file mode 100755
index 0000000..dab976e
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexer.rb
@@ -0,0 +1,435 @@
+# -*- coding: utf-8 -*- #
+
+# stdlib
+require 'strscan'
+require 'cgi'
+require 'set'
+
+module Rouge
+  # @abstract
+  # A lexer transforms text into a stream of `[token, chunk]` pairs.
+  class Lexer
+    include Token::Tokens
+
+    class << self
+      # Lexes `stream` with the given options.  The lex is delegated to a
+      # new instance.
+      #
+      # @see #lex
+      def lex(stream, opts={}, &b)
+        new(opts).lex(stream, &b)
+      end
+
+      def default_options(o={})
+        @default_options ||= {}
+        @default_options.merge!(o)
+        @default_options
+      end
+
+      # Given a string, return the correct lexer class.
+      def find(name)
+        registry[name.to_s]
+      end
+
+      # Find a lexer, with fancy shiny features.
+      #
+      # * The string you pass can include CGI-style options
+      #
+      #     Lexer.find_fancy('erb?parent=tex')
+      #
+      # * You can pass the special name 'guess' so we guess for you,
+      #   and you can pass a second argument of the code to guess by
+      #
+      #     Lexer.find_fancy('guess', "#!/bin/bash\necho Hello, world")
+      #
+      # This is used in the Redcarpet plugin as well as Rouge's own
+      # markdown lexer for highlighting internal code blocks.
+      #
+      def find_fancy(str, code=nil)
+        name, opts = str ? str.split('?', 2) : [nil, '']
+
+        # parse the options hash from a cgi-style string
+        opts = CGI.parse(opts || '').map do |k, vals|
+          [ k.to_sym, vals.empty? ? true : vals[0] ]
+        end
+
+        opts = Hash[opts]
+
+        lexer_class = case name
+        when 'guess', nil
+          self.guess(:source => code, :mimetype => opts[:mimetype])
+        when String
+          self.find(name)
+        end
+
+        lexer_class && lexer_class.new(opts)
+      end
+
+      # Specify or get this lexer's description.
+      def desc(arg=:absent)
+        if arg == :absent
+          @desc
+        else
+          @desc = arg
+        end
+      end
+
+      # Specify or get the path name containing a small demo for
+      # this lexer (can be overriden by {demo}).
+      def demo_file(arg=:absent)
+        return @demo_file = Pathname.new(arg) unless arg == :absent
+
+        @demo_file = Pathname.new(__FILE__).dirname.join('demos', tag)
+      end
+
+      # Specify or get a small demo string for this lexer
+      def demo(arg=:absent)
+        return @demo = arg unless arg == :absent
+
+        @demo = File.read(demo_file, encoding: 'utf-8')
+      end
+
+      # @return a list of all lexers.
+      def all
+        registry.values.uniq
+      end
+
+      # Guess which lexer to use based on a hash of info.
+      #
+      # This accepts the same arguments as Lexer.guess, but will never throw
+      # an error.  It will return a (possibly empty) list of potential lexers
+      # to use.
+      def guesses(info={})
+        mimetype, filename, source = info.values_at(:mimetype, :filename, :source)
+        lexers = registry.values.uniq
+        total_size = lexers.size
+
+        lexers = filter_by_mimetype(lexers, mimetype) if mimetype
+        return lexers if lexers.size == 1
+
+        lexers = filter_by_filename(lexers, filename) if filename
+        return lexers if lexers.size == 1
+
+        if source
+          # If we're filtering against *all* lexers, we only use confident return
+          # values from analyze_text.  But if we've filtered down already, we can trust
+          # the analysis more.
+          source_threshold = lexers.size < total_size ? 0 : 0.5
+          return [best_by_source(lexers, source, source_threshold)].compact
+        end
+
+        []
+      end
+
+      class AmbiguousGuess < StandardError
+        attr_reader :alternatives
+        def initialize(alternatives); @alternatives = alternatives; end
+
+        def message
+          "Ambiguous guess: can't decide between #{alternatives.map(&:tag).inspect}"
+        end
+      end
+
+      # Guess which lexer to use based on a hash of info.
+      #
+      # @option info :mimetype
+      #   A mimetype to guess by
+      # @option info :filename
+      #   A filename to guess by
+      # @option info :source
+      #   The source itself, which, if guessing by mimetype or filename
+      #   fails, will be searched for shebangs, <!DOCTYPE ...> tags, and
+      #   other hints.
+      #
+      # @see Lexer.analyze_text
+      # @see Lexer.multi_guess
+      def guess(info={})
+        lexers = guesses(info)
+
+        return Lexers::PlainText if lexers.empty?
+        return lexers[0] if lexers.size == 1
+
+        raise AmbiguousGuess.new(lexers)
+      end
+
+      def guess_by_mimetype(mt)
+        guess :mimetype => mt
+      end
+
+      def guess_by_filename(fname)
+        guess :filename => fname
+      end
+
+      def guess_by_source(source)
+        guess :source => source
+      end
+
+    private
+      def filter_by_mimetype(lexers, mt)
+        filtered = lexers.select { |lexer| lexer.mimetypes.include? mt }
+        filtered.any? ? filtered : lexers
+      end
+
+      # returns a list of lexers that match the given filename with
+      # equal specificity (i.e. number of wildcards in the pattern).
+      # This helps disambiguate between, e.g. the Nginx lexer, which
+      # matches `nginx.conf`, and the Conf lexer, which matches `*.conf`.
+      # In this case, nginx will win because the pattern has no wildcards,
+      # while `*.conf` has one.
+      def filter_by_filename(lexers, fname)
+        fname = File.basename(fname)
+
+        out = []
+        best_seen = nil
+        lexers.each do |lexer|
+          score = lexer.filenames.map do |pattern|
+            if File.fnmatch?(pattern, fname, File::FNM_DOTMATCH)
+              # specificity is better the fewer wildcards there are
+              pattern.scan(/[*?\[]/).size
+            end
+          end.compact.min
+
+          next unless score
+
+          if best_seen.nil? || score < best_seen
+            best_seen = score
+            out = [lexer]
+          elsif score == best_seen
+            out << lexer
+          end
+        end
+
+        out.any? ? out : lexers
+      end
+
+      def best_by_source(lexers, source, threshold=0)
+        source = case source
+        when String
+          source
+        when ->(s){ s.respond_to? :read }
+          source.read
+        else
+          raise 'invalid source'
+        end
+
+        assert_utf8!(source)
+
+        source = TextAnalyzer.new(source)
+
+        best_result = threshold
+        best_match = nil
+        lexers.each do |lexer|
+          result = lexer.analyze_text(source) || 0
+          return lexer if result == 1
+
+          if result > best_result
+            best_match = lexer
+            best_result = result
+          end
+        end
+
+        best_match
+      end
+
+    protected
+      # @private
+      def register(name, lexer)
+        registry[name.to_s] = lexer
+      end
+
+    public
+      # Used to specify or get the canonical name of this lexer class.
+      #
+      # @example
+      #   class MyLexer < Lexer
+      #     tag 'foo'
+      #   end
+      #
+      #   MyLexer.tag # => 'foo'
+      #
+      #   Lexer.find('foo') # => MyLexer
+      def tag(t=nil)
+        return @tag if t.nil?
+
+        @tag = t.to_s
+        Lexer.register(@tag, self)
+      end
+
+      # Used to specify alternate names this lexer class may be found by.
+      #
+      # @example
+      #   class Erb < Lexer
+      #     tag 'erb'
+      #     aliases 'eruby', 'rhtml'
+      #   end
+      #
+      #   Lexer.find('eruby') # => Erb
+      def aliases(*args)
+        args.map!(&:to_s)
+        args.each { |arg| Lexer.register(arg, self) }
+        (@aliases ||= []).concat(args)
+      end
+
+      # Specify a list of filename globs associated with this lexer.
+      #
+      # @example
+      #   class Ruby < Lexer
+      #     filenames '*.rb', '*.ruby', 'Gemfile', 'Rakefile'
+      #   end
+      def filenames(*fnames)
+        (@filenames ||= []).concat(fnames)
+      end
+
+      # Specify a list of mimetypes associated with this lexer.
+      #
+      # @example
+      #   class Html < Lexer
+      #     mimetypes 'text/html', 'application/xhtml+xml'
+      #   end
+      def mimetypes(*mts)
+        (@mimetypes ||= []).concat(mts)
+      end
+
+      # @private
+      def assert_utf8!(str)
+        return if %w(US-ASCII UTF-8 ASCII-8BIT).include? str.encoding.name
+        raise EncodingError.new(
+          "Bad encoding: #{str.encoding.names.join(',')}. " +
+          "Please convert your string to UTF-8."
+        )
+      end
+
+    private
+      def registry
+        @registry ||= {}
+      end
+    end
+
+    # -*- instance methods -*- #
+
+    # Create a new lexer with the given options.  Individual lexers may
+    # specify extra options.  The only current globally accepted option
+    # is `:debug`.
+    #
+    # @option opts :debug
+    #   Prints debug information to stdout.  The particular info depends
+    #   on the lexer in question.  In regex lexers, this will log the
+    #   state stack at the beginning of each step, along with each regex
+    #   tried and each stream consumed.  Try it, it's pretty useful.
+    def initialize(opts={})
+      options(opts)
+
+      @debug = option(:debug)
+    end
+
+    # get and/or specify the options for this lexer.
+    def options(o={})
+      (@options ||= {}).merge!(o)
+
+      self.class.default_options.merge(@options)
+    end
+
+    # get or specify one option for this lexer
+    def option(k, v=:absent)
+      if v == :absent
+        options[k]
+      else
+        options({ k => v })
+      end
+    end
+
+    # @deprecated
+    # Instead of `debug { "foo" }`, simply `puts "foo" if @debug`.
+    #
+    # Leave a debug message if the `:debug` option is set.  The message
+    # is given as a block because some debug messages contain calculated
+    # information that is unnecessary for lexing in the real world.
+    #
+    # Calls to this method should be guarded with "if @debug" for best
+    # performance when debugging is turned off.
+    #
+    # @example
+    #   debug { "hello, world!" } if @debug
+    def debug
+      warn "Lexer#debug is deprecated.  Simply puts if @debug instead."
+      puts yield if @debug
+    end
+
+    # @abstract
+    #
+    # Called after each lex is finished.  The default implementation
+    # is a noop.
+    def reset!
+    end
+
+    # Given a string, yield [token, chunk] pairs.  If no block is given,
+    # an enumerator is returned.
+    #
+    # @option opts :continue
+    #   Continue the lex from the previous state (i.e. don't call #reset!)
+    def lex(string, opts={}, &b)
+      return enum_for(:lex, string) unless block_given?
+
+      Lexer.assert_utf8!(string)
+
+      reset! unless opts[:continue]
+
+      # consolidate consecutive tokens of the same type
+      last_token = nil
+      last_val = nil
+      stream_tokens(string) do |tok, val|
+        next if val.empty?
+
+        if tok == last_token
+          last_val << val
+          next
+        end
+
+        b.call(last_token, last_val) if last_token
+        last_token = tok
+        last_val = val
+      end
+
+      b.call(last_token, last_val) if last_token
+    end
+
+    # delegated to {Lexer.tag}
+    def tag
+      self.class.tag
+    end
+
+    # @abstract
+    #
+    # Yield `[token, chunk]` pairs, given a prepared input stream.  This
+    # must be implemented.
+    #
+    # @param [StringScanner] stream
+    #   the stream
+    def stream_tokens(stream, &b)
+      raise 'abstract'
+    end
+
+    # @abstract
+    #
+    # Return a number between 0 and 1 indicating the likelihood that
+    # the text given should be lexed with this lexer.  The default
+    # implementation returns 0.  Values under 0.5 will only be used
+    # to disambiguate filename or mimetype matches.
+    #
+    # @param [TextAnalyzer] text
+    #   the text to be analyzed, with a couple of handy methods on it,
+    #   like {TextAnalyzer#shebang?} and {TextAnalyzer#doctype?}
+    def self.analyze_text(text)
+      0
+    end
+  end
+
+  module Lexers
+    def self.load_const(const_name, relpath)
+      return if const_defined?(const_name)
+
+      root = Pathname.new(__FILE__).dirname.join('lexers')
+      load root.join(relpath)
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/apple_script.rb b/app/server/vendor/rouge/lib/rouge/lexers/apple_script.rb
new file mode 100755
index 0000000..4c93001
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/apple_script.rb
@@ -0,0 +1,366 @@
+# -*- coding: utf-8 -*- #
+module Rouge
+  module Lexers
+    class AppleScript < RegexLexer
+      desc "The AppleScript scripting language by Apple Inc. (http://developer.apple.com/applescript/)"
+
+      tag 'applescript'
+      aliases 'applescript'
+
+      filenames '*.applescript', '*.scpt'
+
+      mimetypes 'application/x-applescript'
+
+      def self.literals
+        @literals ||= ['AppleScript', 'current application', 'false', 'linefeed',
+                       'missing value', 'pi','quote', 'result', 'return', 'space',
+                       'tab', 'text item delimiters', 'true', 'version']
+      end
+
+      def self.classes
+        @classes ||= ['alias ', 'application ', 'boolean ', 'class ', 'constant ',
+                      'date ', 'file ', 'integer ', 'list ', 'number ', 'POSIX file ',
+                      'real ', 'record ', 'reference ', 'RGB color ', 'script ',
+                      'text ', 'unit types', '(?:Unicode )?text', 'string']
+      end
+
+      def self.builtins
+        @builtins ||= ['attachment', 'attribute run', 'character', 'day', 'month',
+                       'paragraph', 'word', 'year']
+      end
+
+      def self.handler_params
+        @handler_params ||= ['about', 'above', 'against', 'apart from', 'around',
+                             'aside from', 'at', 'below', 'beneath', 'beside',
+                             'between', 'for', 'given', 'instead of', 'on', 'onto',
+                             'out of', 'over', 'since']
+      end
+
+      def self.commands
+        @commands ||= ['ASCII (character|number)', 'activate', 'beep', 'choose URL',
+                'choose application', 'choose color', 'choose file( name)?',
+                'choose folder', 'choose from list',
+                'choose remote application', 'clipboard info',
+                'close( access)?', 'copy', 'count', 'current date', 'delay',
+                'delete', 'display (alert|dialog)', 'do shell script',
+                'duplicate', 'exists', 'get eof', 'get volume settings',
+                'info for', 'launch', 'list (disks|folder)', 'load script',
+                'log', 'make', 'mount volume', 'new', 'offset',
+                'open( (for access|location))?', 'path to', 'print', 'quit',
+                'random number', 'read', 'round', 'run( script)?',
+                'say', 'scripting components',
+                'set (eof|the clipboard to|volume)', 'store script',
+                'summarize', 'system attribute', 'system info',
+                'the clipboard', 'time to GMT', 'write', 'quoted form']
+      end
+
+      def self.references
+        @references ||= ['(in )?back of', '(in )?front of', '[0-9]+(st|nd|rd|th)',
+                  'first', 'second', 'third', 'fourth', 'fifth', 'sixth',
+                  'seventh', 'eighth', 'ninth', 'tenth', 'after', 'back',
+                  'before', 'behind', 'every', 'front', 'index', 'last',
+                  'middle', 'some', 'that', 'through', 'thru', 'where', 'whose']
+      end
+
+      def self.operators
+        @operators ||= ["and", "or", "is equal", "equals", "(is )?equal to", "is not",
+                 "isn't", "isn't equal( to)?", "is not equal( to)?",
+                 "doesn't equal", "does not equal", "(is )?greater than",
+                 "comes after", "is not less than or equal( to)?",
+                 "isn't less than or equal( to)?", "(is )?less than",
+                 "comes before", "is not greater than or equal( to)?",
+                 "isn't greater than or equal( to)?",
+                 "(is  )?greater than or equal( to)?", "is not less than",
+                 "isn't less than", "does not come before",
+                 "doesn't come before", "(is )?less than or equal( to)?",
+                 "is not greater than", "isn't greater than",
+                 "does not come after", "doesn't come after", "starts? with",
+                 "begins? with", "ends? with", "contains?", "does not contain",
+                 "doesn't contain", "is in", "is contained by", "is not in",
+                 "is not contained by", "isn't contained by", "div", "mod",
+                 "not", "(a  )?(ref( to)?|reference to)", "is", "does"]
+      end
+
+      def self.controls
+        @controls ||= ['considering', 'else', 'error', 'exit', 'from', 'if',
+               'ignoring', 'in', 'repeat', 'tell', 'then', 'times', 'to',
+               'try', 'until', 'using terms from', 'while', 'whith',
+               'with timeout( of)?', 'with transaction', 'by', 'continue',
+               'end', 'its?', 'me', 'my', 'return', 'of' , 'as']
+      end
+
+      def self.declarations
+        @declarations ||= ['global', 'local', 'prop(erty)?', 'set', 'get']
+      end
+
+      def self.reserved
+        @reserved ||= ['but', 'put', 'returning', 'the']
+      end
+
+      def self.studio_classes
+        @studio_classes ||= ['action cell', 'alert reply', 'application', 'box',
+                     'browser( cell)?', 'bundle', 'button( cell)?', 'cell',
+                     'clip view', 'color well', 'color-panel',
+                     'combo box( item)?', 'control',
+                     'data( (cell|column|item|row|source))?', 'default entry',
+                     'dialog reply', 'document', 'drag info', 'drawer',
+                     'event', 'font(-panel)?', 'formatter',
+                     'image( (cell|view))?', 'matrix', 'menu( item)?', 'item',
+                     'movie( view)?', 'open-panel', 'outline view', 'panel',
+                     'pasteboard', 'plugin', 'popup button',
+                     'progress indicator', 'responder', 'save-panel',
+                     'scroll view', 'secure text field( cell)?', 'slider',
+                     'sound', 'split view', 'stepper', 'tab view( item)?',
+                     'table( (column|header cell|header view|view))',
+                     'text( (field( cell)?|view))?', 'toolbar( item)?',
+                     'user-defaults', 'view', 'window']
+      end
+
+      def self.studio_events
+        @studio_events ||= ['accept outline drop', 'accept table drop', 'action',
+                    'activated', 'alert ended', 'awake from nib', 'became key',
+                    'became main', 'begin editing', 'bounds changed',
+                    'cell value', 'cell value changed', 'change cell value',
+                    'change item value', 'changed', 'child of item',
+                    'choose menu item', 'clicked', 'clicked toolbar item',
+                    'closed', 'column clicked', 'column moved',
+                    'column resized', 'conclude drop', 'data representation',
+                    'deminiaturized', 'dialog ended', 'document nib name',
+                    'double clicked', 'drag( (entered|exited|updated))?',
+                    'drop', 'end editing', 'exposed', 'idle', 'item expandable',
+                    'item value', 'item value changed', 'items changed',
+                    'keyboard down', 'keyboard up', 'launched',
+                    'load data representation', 'miniaturized', 'mouse down',
+                    'mouse dragged', 'mouse entered', 'mouse exited',
+                    'mouse moved', 'mouse up', 'moved',
+                    'number of browser rows', 'number of items',
+                    'number of rows', 'open untitled', 'opened', 'panel ended',
+                    'parameters updated', 'plugin loaded', 'prepare drop',
+                    'prepare outline drag', 'prepare outline drop',
+                    'prepare table drag', 'prepare table drop',
+                    'read from file', 'resigned active', 'resigned key',
+                    'resigned main', 'resized( sub views)?',
+                    'right mouse down', 'right mouse dragged',
+                    'right mouse up', 'rows changed', 'scroll wheel',
+                    'selected tab view item', 'selection changed',
+                    'selection changing', 'should begin editing',
+                    'should close', 'should collapse item',
+                    'should end editing', 'should expand item',
+                    'should open( untitled)?',
+                    'should quit( after last window closed)?',
+                    'should select column', 'should select item',
+                    'should select row', 'should select tab view item',
+                    'should selection change', 'should zoom', 'shown',
+                    'update menu item', 'update parameters',
+                    'update toolbar item', 'was hidden', 'was miniaturized',
+                    'will become active', 'will close', 'will dismiss',
+                    'will display browser cell', 'will display cell',
+                    'will display item cell', 'will display outline cell',
+                    'will finish launching', 'will hide', 'will miniaturize',
+                    'will move', 'will open', 'will pop up', 'will quit',
+                    'will resign active', 'will resize( sub views)?',
+                    'will select tab view item', 'will show', 'will zoom',
+                    'write to file', 'zoomed']
+      end
+
+      def self.studio_commands
+        @studio_commands ||= ['animate', 'append', 'call method', 'center',
+                      'close drawer', 'close panel', 'display',
+                      'display alert', 'display dialog', 'display panel', 'go',
+                      'hide', 'highlight', 'increment', 'item for',
+                      'load image', 'load movie', 'load nib', 'load panel',
+                      'load sound', 'localized string', 'lock focus', 'log',
+                      'open drawer', 'path for', 'pause', 'perform action',
+                      'play', 'register', 'resume', 'scroll', 'select( all)?',
+                      'show', 'size to fit', 'start', 'step back',
+                      'step forward', 'stop', 'synchronize', 'unlock focus',
+                      'update']
+      end
+
+      def self.studio_properties
+        @studio_properties ||= ['accepts arrow key', 'action method', 'active',
+                        'alignment', 'allowed identifiers',
+                        'allows branch selection', 'allows column reordering',
+                        'allows column resizing', 'allows column selection',
+                        'allows customization', 'allows editing text attributes',
+                        'allows empty selection', 'allows mixed state',
+                        'allows multiple selection', 'allows reordering',
+                        'allows undo', 'alpha( value)?', 'alternate image',
+                        'alternate increment value', 'alternate title',
+                        'animation delay', 'associated file name',
+                        'associated object', 'auto completes', 'auto display',
+                        'auto enables items', 'auto repeat', 'auto resizes( outline column)?',
+                        'auto save expanded items', 'auto save name',
+                        'auto save table columns', 'auto saves configuration',
+                        'auto scroll', 'auto sizes all columns to fit',
+                        'auto sizes cells', 'background color', 'bezel state',
+                        'bezel style', 'bezeled', 'border rect', 'border type',
+                        'bordered', 'bounds( rotation)?', 'box type',
+                        'button returned', 'button type',
+                        'can choose directories', 'can choose files', 'can draw', 'can hide',
+                        'cell( (background color|size|type))?', 'characters',
+                        'class', 'click count', 'clicked( data)? column',
+                        'clicked data item', 'clicked( data)? row',
+                        'closeable', 'collating', 'color( (mode|panel))',
+                        'command key down', 'configuration',
+                        'content(s| (size|view( margins)?))?', 'context',
+                        'continuous', 'control key down', 'control size',
+                        'control tint', 'control view',
+                        'controller visible', 'coordinate system',
+                        'copies( on scroll)?', 'corner view', 'current cell',
+                        'current column', 'current( field)?  editor',
+                        'current( menu)? item', 'current row',
+                        'current tab view item', 'data source',
+                        'default identifiers', 'delta (x|y|z)',
+                        'destination window', 'directory', 'display mode',
+                        'displayed cell', 'document( (edited|rect|view))?',
+                        'double value', 'dragged column', 'dragged distance',
+                        'dragged items', 'draws( cell)? background',
+                        'draws grid', 'dynamically scrolls', 'echos bullets',
+                        'edge', 'editable', 'edited( data)? column',
+                        'edited data item', 'edited( data)? row', 'enabled',
+                        'enclosing scroll view', 'ending page',
+                        'error handling', 'event number', 'event type',
+                        'excluded from windows menu', 'executable path',
+                        'expanded', 'fax number', 'field editor', 'file kind',
+                        'file name', 'file type', 'first responder',
+                        'first visible column', 'flipped', 'floating',
+                        'font( panel)?', 'formatter', 'frameworks path',
+                        'frontmost', 'gave up', 'grid color', 'has data items',
+                        'has horizontal ruler', 'has horizontal scroller',
+                        'has parent data item', 'has resize indicator',
+                        'has shadow', 'has sub menu', 'has vertical ruler',
+                        'has vertical scroller', 'header cell', 'header view',
+                        'hidden', 'hides when deactivated', 'highlights by',
+                        'horizontal line scroll', 'horizontal page scroll',
+                        'horizontal ruler view', 'horizontally resizable',
+                        'icon image', 'id', 'identifier',
+                        'ignores multiple clicks',
+                        'image( (alignment|dims when disabled|frame style|scaling))?',
+                        'imports graphics', 'increment value',
+                        'indentation per level', 'indeterminate', 'index',
+                        'integer value', 'intercell spacing', 'item height',
+                        'key( (code|equivalent( modifier)?|window))?',
+                        'knob thickness', 'label', 'last( visible)? column',
+                        'leading offset', 'leaf', 'level', 'line scroll',
+                        'loaded', 'localized sort', 'location', 'loop mode',
+                        'main( (bunde|menu|window))?', 'marker follows cell',
+                        'matrix mode', 'maximum( content)? size',
+                        'maximum visible columns',
+                        'menu( form representation)?', 'miniaturizable',
+                        'miniaturized', 'minimized image', 'minimized title',
+                        'minimum column width', 'minimum( content)? size',
+                        'modal', 'modified', 'mouse down state',
+                        'movie( (controller|file|rect))?', 'muted', 'name',
+                        'needs display', 'next state', 'next text',
+                        'number of tick marks', 'only tick mark values',
+                        'opaque', 'open panel', 'option key down',
+                        'outline table column', 'page scroll', 'pages across',
+                        'pages down', 'palette label', 'pane splitter',
+                        'parent data item', 'parent window', 'pasteboard',
+                        'path( (names|separator))?', 'playing',
+                        'plays every frame', 'plays selection only', 'position',
+                        'preferred edge', 'preferred type', 'pressure',
+                        'previous text', 'prompt', 'properties',
+                        'prototype cell', 'pulls down', 'rate',
+                        'released when closed', 'repeated',
+                        'requested print time', 'required file type',
+                        'resizable', 'resized column', 'resource path',
+                        'returns records', 'reuses columns', 'rich text',
+                        'roll over', 'row height', 'rulers visible',
+                        'save panel', 'scripts path', 'scrollable',
+                        'selectable( identifiers)?', 'selected cell',
+                        'selected( data)? columns?', 'selected data items?',
+                        'selected( data)? rows?', 'selected item identifier',
+                        'selection by rect', 'send action on arrow key',
+                        'sends action when done editing', 'separates columns',
+                        'separator item', 'sequence number', 'services menu',
+                        'shared frameworks path', 'shared support path',
+                        'sheet', 'shift key down', 'shows alpha',
+                        'shows state by', 'size( mode)?',
+                        'smart insert delete enabled', 'sort case sensitivity',
+                        'sort column', 'sort order', 'sort type',
+                        'sorted( data rows)?', 'sound', 'source( mask)?',
+                        'spell checking enabled', 'starting page', 'state',
+                        'string value', 'sub menu', 'super menu', 'super view',
+                        'tab key traverses cells', 'tab state', 'tab type',
+                        'tab view', 'table view', 'tag', 'target( printer)?',
+                        'text color', 'text container insert',
+                        'text container origin', 'text returned',
+                        'tick mark position', 'time stamp',
+                        'title(d| (cell|font|height|position|rect))?',
+                        'tool tip', 'toolbar', 'trailing offset', 'transparent',
+                        'treat packages as directories', 'truncated labels',
+                        'types', 'unmodified characters', 'update views',
+                        'use sort indicator', 'user defaults',
+                        'uses data source', 'uses ruler', 'uses threaded animation',
+                        'uses title from previous column', 'value wraps', 'version',
+                        'vertical( (line scroll|page scroll|ruler view))?', 'vertically resizable', 'view',
+                        'visible( document rect)?', 'volume', 'width', 'window',
+                        'windows menu', 'wraps', 'zoomable', 'zoomed']
+      end
+
+      operators = %r(\b(#{self.operators.to_a.join('|')})\b)
+      classes = %r(\b(as )(#{self.classes.to_a.join('|')})\b)
+      literals = %r(\b(#{self.literals.to_a.join('|')})\b)
+      commands = %r(\b(#{self.commands.to_a.join('|')})\b)
+      controls = %r(\b(#{self.controls.to_a.join('|')})\b)
+      declarations = %r(\b(#{self.declarations.to_a.join('|')})\b)
+      reserved = %r(\b(#{self.reserved.to_a.join('|')})\b)
+      builtins = %r(\b(#{self.builtins.to_a.join('|')})s?\b)
+      handler_params = %r(\b(#{self.handler_params.to_a.join('|')})\b)
+      references = %r(\b(#{self.references.to_a.join('|')})\b)
+      studio_properties = %r(\b(#{self.studio_properties.to_a.join('|')})\b)
+      studio_classes = %r(\b(#{self.studio_classes.to_a.join('|')})s?\b)
+      studio_commands = %r(\b(#{self.studio_commands.to_a.join('|')})\b)
+      identifiers = %r(\b([a-zA-Z]\w*)\b)
+
+      state :root do
+        rule /\s+/, Text::Whitespace
+        rule /¬\n/, Literal::String::Escape
+        rule /'s\s+/, Text
+        rule /(--|#).*?$/, Comment::Single
+        rule /\(\*/, Comment::Multiline
+        rule /[\(\){}!,.:]/, Punctuation
+        rule /(«)([^»]+)(»)/ do |match|
+          token Text, match[1]
+          token Name::Builtin, match[2]
+          token Text, match[3]
+        end
+        rule /\b((?:considering|ignoring)\s*)(application responses|case|diacriticals|hyphens|numeric strings|punctuation|white space)/ do |match|
+          token Keyword, match[1]
+          token Name::Builtin, match[2]
+        end
+        rule /(-|\*|\+|&|≠|>=?|<=?|=|≥|≤|\/|÷|\^)/, Operator
+        rule operators, Operator::Word
+        rule /^(\s*(?:on|end)\s+)'r'(%s)/ do |match|
+          token Keyword, match[1]
+          token Name::Function, match[2]
+        end
+        rule /^(\s*)(in|on|script|to)(\s+)/ do |match|
+          token Text, match[1]
+          token Keyword, match[2]
+          token Text, match[3]
+        end
+        rule classes do |match|
+          token Keyword, match[1]
+          token Name::Class, match[2]
+        end
+        rule commands, Name::Builtin
+        rule controls, Keyword
+        rule declarations, Keyword
+        rule reserved, Name::Builtin
+        rule builtins, Name::Builtin
+        rule handler_params, Name::Builtin
+        rule studio_properties, Name::Attribute
+        rule studio_classes, Name::Builtin
+        rule studio_commands, Name::Builtin
+        rule references, Name::Builtin
+        rule /"(\\\\|\\"|[^"])*"/, Literal::String::Double
+        rule identifiers, Name::Variable
+        rule /[-+]?(\d+\.\d*|\d*\.\d+)(E[-+][0-9]+)?/, Literal::Number::Float
+        rule /[-+]?\d+/, Literal::Number::Integer
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/c.rb b/app/server/vendor/rouge/lib/rouge/lexers/c.rb
new file mode 100755
index 0000000..0abe739
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/c.rb
@@ -0,0 +1,211 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class C < RegexLexer
+      tag 'c'
+      filenames '*.c', '*.h', '*.idc'
+      mimetypes 'text/x-chdr', 'text/x-csrc'
+
+      desc "The C programming language"
+
+      # optional comment or whitespace
+      ws = %r((?:\s|//.*?\n|/[*].*?[*]/)+)
+      id = /[a-zA-Z_][a-zA-Z0-9_]*/
+
+      def self.keywords
+        @keywords ||= Set.new %w(
+          auto break case const continue default do else enum extern
+          for goto if register restricted return sizeof static struct
+          switch typedef union volatile virtual while
+        )
+      end
+
+      def self.keywords_type
+        @keywords_type ||= Set.new %w(
+          int long float short double char unsigned signed void
+
+          jmp_buf FILE DIR div_t ldiv_t mbstate_t sig_atomic_t fpos_t
+          clock_t time_t va_list size_t ssize_t off_t wchar_t ptrdiff_t
+          wctrans_t wint_t wctype_t
+
+          _Bool _Complex int8_t int16_t int32_t int64_t
+          uint8_t uint16_t uint32_t uint64_t int_least8_t
+          int_least16_t int_least32_t int_least64_t
+          uint_least8_t uint_least16_t uint_least32_t
+          uint_least64_t int_fast8_t int_fast16_t int_fast32_t
+          int_fast64_t uint_fast8_t uint_fast16_t uint_fast32_t
+          uint_fast64_t intptr_t uintptr_t intmax_t
+          uintmax_t
+        )
+      end
+
+      def self.reserved
+        @reserved ||= Set.new %w(
+          __asm __int8 __based __except __int16 __stdcall __cdecl
+          __fastcall __int32 __declspec __finally __int61 __try __leave
+          inline _inline __inline naked _naked __naked restrict _restrict
+          __restrict thread _thread __thread typename _typename __typename
+        )
+      end
+
+      # high priority for filename matches
+      def self.analyze_text(*)
+        0.3
+      end
+
+      def self.builtins
+        @builtins ||= []
+      end
+
+      start { push :bol }
+
+      state :expr_bol do
+        mixin :inline_whitespace
+
+        rule /#if\s0/, Comment, :if_0
+        rule /#/, Comment::Preproc, :macro
+
+        rule(//) { pop! }
+      end
+
+      # :expr_bol is the same as :bol but without labels, since
+      # labels can only appear at the beginning of a statement.
+      state :bol do
+        rule /#{id}:(?!:)/, Name::Label
+        mixin :expr_bol
+      end
+
+      state :inline_whitespace do
+        rule /[ \t\r]+/, Text
+        rule /\\\n/, Text # line continuation
+        rule %r(/(\\\n)?[*].*?[*](\\\n)?/)m, Comment::Multiline
+      end
+
+      state :whitespace do
+        rule /\n+/m, Text, :bol
+        rule %r(//(\\.|.)*?\n), Comment::Single, :bol
+        mixin :inline_whitespace
+      end
+
+      state :expr_whitespace do
+        rule /\n+/m, Text, :expr_bol
+        mixin :whitespace
+      end
+
+      state :statements do
+        mixin :whitespace
+        rule /L?"/, Str, :string
+        rule %r(L?'(\\.|\\[0-7]{1,3}|\\x[a-f0-9]{1,2}|[^\\'\n])')i, Str::Char
+        rule %r((\d+[.]\d*|[.]?\d+)e[+-]?\d+[lu]*)i, Num::Float
+        rule %r(\d+e[+-]?\d+[lu]*)i, Num::Float
+        rule /0x[0-9a-f]+[lu]*/i, Num::Hex
+        rule /0[0-7]+[lu]*/i, Num::Oct
+        rule /\d+[lu]*/i, Num::Integer
+        rule %r(\*/), Error
+        rule %r([~!%^&*+=\|?:<>/-]), Operator
+        rule /[()\[\],.]/, Punctuation
+        rule /\bcase\b/, Keyword, :case
+        rule /(?:true|false|NULL)\b/, Name::Builtin
+        rule id do |m|
+          name = m[0]
+
+          if self.class.keywords.include? name
+            token Keyword
+          elsif self.class.keywords_type.include? name
+            token Keyword::Type
+          elsif self.class.reserved.include? name
+            token Keyword::Reserved
+          elsif self.class.builtins.include? name
+            token Name::Builtin
+          else
+            token Name
+          end
+        end
+      end
+
+      state :case do
+        rule /:/, Punctuation, :pop!
+        mixin :statements
+      end
+
+      state :root do
+        mixin :expr_whitespace
+
+        # functions
+        rule %r(
+          ([\w*\s]+?[\s*]) # return arguments
+          (#{id})          # function name
+          (\s*\([^;]*?\))  # signature
+          (#{ws})({)         # open brace
+        )mx do |m|
+          # TODO: do this better.
+          recurse m[1]
+          token Name::Function, m[2]
+          recurse m[3]
+          recurse m[4]
+          token Punctuation, m[5]
+          push :function
+        end
+
+        # function declarations
+        rule %r(
+          ([\w*\s]+?[\s*]) # return arguments
+          (#{id})          # function name
+          (\s*\([^;]*?\))  # signature
+          (#{ws})(;)       # semicolon
+        )mx do |m|
+          # TODO: do this better.
+          recurse m[1]
+          token Name::Function
+          recurse m[3]
+          recurse m[4]
+          token Punctuation
+          push :statement
+        end
+
+        rule(//) { push :statement }
+      end
+
+      state :statement do
+        rule /;/, Punctuation, :pop!
+        mixin :expr_whitespace
+        mixin :statements
+        rule /[{}]/, Punctuation
+      end
+
+      state :function do
+        mixin :whitespace
+        mixin :statements
+        rule /;/, Punctuation
+        rule /{/, Punctuation, :function
+        rule /}/, Punctuation, :pop!
+      end
+
+      state :string do
+        rule /"/, Str, :pop!
+        rule /\\([\\abfnrtv"']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})/, Str::Escape
+        rule /[^\\"\n]+/, Str
+        rule /\\\n/, Str
+        rule /\\/, Str # stray backslash
+      end
+
+      state :macro do
+        # NB: pop! goes back to :bol
+        rule /\n/, Comment::Preproc, :pop!
+        rule %r([^/\n\\]+), Comment::Preproc
+        rule /\\./m, Comment::Preproc
+        mixin :inline_whitespace
+        rule %r(/), Comment::Preproc
+      end
+
+      state :if_0 do
+        # NB: no \b here, to cover #ifdef and #ifndef
+        rule /^\s*#if/, Comment, :if_0
+        rule /^\s*#\s*el(?:se|if)/, Comment, :pop!
+        rule /^\s*#\s*endif\b.*?(?<!\\)\n/m, Comment, :pop!
+        rule /.*?\n/, Comment
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/clojure.rb b/app/server/vendor/rouge/lib/rouge/lexers/clojure.rb
new file mode 100755
index 0000000..2420a9d
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/clojure.rb
@@ -0,0 +1,111 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Clojure < RegexLexer
+      desc "The Clojure programming language (clojure.org)"
+
+      tag 'clojure'
+      aliases 'clj', 'cljs'
+
+      filenames '*.clj', '*.cljs'
+
+      mimetypes 'text/x-clojure', 'application/x-clojure'
+
+      def self.keywords
+        @keywords ||= Set.new %w(
+          fn def defn defmacro defmethod defmulti defn- defstruct if
+          cond let for
+        )
+      end
+
+      def self.builtins
+        @builtins ||= Set.new %w(
+          . ..  * + - -> / < <= = == > >= accessor agent agent-errors
+          aget alength all-ns alter and append-child apply array-map
+          aset aset-boolean aset-byte aset-char aset-double aset-float
+          aset-int aset-long aset-short assert assoc await await-for bean
+          binding bit-and bit-not bit-or bit-shift-left bit-shift-right
+          bit-xor boolean branch?  butlast byte cast char children
+          class clear-agent-errors comment commute comp comparator
+          complement concat conj cons constantly construct-proxy
+          contains? count create-ns create-struct cycle dec  deref
+          difference disj dissoc distinct doall doc dorun doseq dosync
+          dotimes doto double down drop drop-while edit end? ensure eval
+          every? false? ffirst file-seq filter find find-doc find-ns
+          find-var first float flush fnseq frest gensym get-proxy-class
+          get hash-map hash-set identical? identity if-let import in-ns
+          inc index insert-child insert-left insert-right inspect-table
+          inspect-tree instance? int interleave intersection into
+          into-array iterate join key keys keyword keyword? last lazy-cat
+          lazy-cons left lefts line-seq list* list load load-file locking
+          long loop macroexpand macroexpand-1 make-array make-node map
+          map-invert map? mapcat max max-key memfn merge merge-with meta
+          min min-key name namespace neg? new newline next nil? node not
+          not-any? not-every? not= ns-imports ns-interns ns-map ns-name
+          ns-publics ns-refers ns-resolve ns-unmap nth nthrest or parse
+          partial path peek pop pos? pr pr-str print print-str println
+          println-str prn prn-str project proxy proxy-mappings quot
+          rand rand-int range re-find re-groups re-matcher re-matches
+          re-pattern re-seq read read-line reduce ref ref-set refer rem
+          remove remove-method remove-ns rename rename-keys repeat replace
+          replicate resolve rest resultset-seq reverse rfirst right
+          rights root rrest rseq second select select-keys send send-off
+          seq seq-zip seq? set short slurp some sort sort-by sorted-map
+          sorted-map-by sorted-set special-symbol? split-at split-with
+          str string?  struct struct-map subs subvec symbol symbol?
+          sync take take-nth take-while test time to-array to-array-2d
+          tree-seq true? union up update-proxy val vals var-get var-set
+          var? vector vector-zip vector? when when-first when-let
+          when-not with-local-vars with-meta with-open with-out-str
+          xml-seq xml-zip zero? zipmap zipper'
+        )
+      end
+
+      identifier = %r([\w!$%*+,<=>?/.-]+)
+      keyword = %r([\w!\#$%*+,<=>?/.-]+)
+
+      def name_token(name)
+        return Keyword if self.class.keywords.include?(name)
+        return Name::Builtin if self.class.builtins.include?(name)
+        nil
+      end
+
+      state :root do
+        rule /;.*?\n/, Comment::Single
+        rule /\s+/m, Text::Whitespace
+
+        rule /-?\d+\.\d+/, Num::Float
+        rule /-?\d+/, Num::Integer
+        rule /0x-?[0-9a-fA-F]+/, Num::Hex
+
+        rule /"(\\.|[^"])*"/, Str
+        rule /'#{keyword}/, Str::Symbol
+        rule /:#{keyword}/, Name::Constant
+        rule /\\(.|[a-z]+)/i, Str::Char
+
+
+        rule /~@|[`\'#^~&]/, Operator
+
+        rule /(\()(\s*)(#{identifier})/m do |m|
+          token Punctuation, m[1]
+          token Text::Whitespace, m[2]
+          token(name_token(m[3]) || Name::Function, m[3])
+        end
+
+        rule identifier do |m|
+          token name_token(m[0]) || Name
+        end
+
+        # vectors
+        rule /[\[\]]/, Punctuation
+
+        # maps
+        rule /[{}]/, Punctuation
+
+        # parentheses
+        rule /[()]/, Punctuation
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/coffeescript.rb b/app/server/vendor/rouge/lib/rouge/lexers/coffeescript.rb
new file mode 100755
index 0000000..53bec69
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/coffeescript.rb
@@ -0,0 +1,173 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Coffeescript < RegexLexer
+      tag 'coffeescript'
+      aliases 'coffee', 'coffee-script'
+      filenames '*.coffee', 'Cakefile'
+      mimetypes 'text/coffeescript'
+
+      desc 'The Coffeescript programming language (coffeescript.org)'
+
+      def self.analyze_text(text)
+        return 1 if text.shebang? 'coffee'
+      end
+
+      def self.keywords
+        @keywords ||= Set.new %w(
+          for in of while break return continue switch when then if else
+          throw try catch finally new delete typeof instanceof super
+          extends this class by
+        )
+      end
+
+      def self.constants
+        @constants ||= Set.new %w(
+          true false yes no on off null NaN Infinity undefined
+        )
+      end
+
+      def self.builtins
+        @builtins ||= Set.new %w(
+          Array Boolean Date Error Function Math netscape Number Object
+          Packages RegExp String sun decodeURI decodeURIComponent
+          encodeURI encodeURIComponent eval isFinite isNaN parseFloat
+          parseInt document window
+        )
+      end
+
+      id = /[$a-zA-Z_][a-zA-Z0-9_]*/
+
+      state :comments_and_whitespace do
+        rule /\s+/m, Text
+        rule /###.*?###/m, Comment::Multiline
+        rule /#.*?\n/, Comment::Single
+      end
+
+      state :multiline_regex do
+        # this order is important, so that #{ isn't interpreted
+        # as a comment
+        mixin :has_interpolation
+        mixin :comments_and_whitespace
+
+        rule %r(///([gim]+\b|\B)), Str::Regex, :pop!
+        rule %r(/), Str::Regex
+        rule %r([^/#]+), Str::Regex
+      end
+
+      state :slash_starts_regex do
+        mixin :comments_and_whitespace
+        rule %r(///) do
+          token Str::Regex
+          goto :multiline_regex
+        end
+
+        rule %r(
+          /(\\.|[^\[/\\\n]|\[(\\.|[^\]\\\n])*\])+/ # a regex
+          ([gim]+\b|\B)
+        )x, Str::Regex, :pop!
+
+        rule(//) { pop! }
+      end
+
+      state :root do
+        rule(%r(^(?=\s|/|<!--))) { push :slash_starts_regex }
+        mixin :comments_and_whitespace
+        rule %r(
+          [+][+]|--|~|&&|\band\b|\bor\b|\bis\b|\bisnt\b|\bnot\b|[?]|:|=|
+          [|][|]|\\(?=\n)|(<<|>>>?|==?|!=?|[-<>+*`%&|^/])=?
+        )x, Operator, :slash_starts_regex
+
+        rule /[-=]>/, Name::Function
+
+        rule /(@)([ \t]*)(#{id})/ do
+          groups Name::Variable::Instance, Text, Name::Attribute
+          push :slash_starts_regex
+        end
+
+        rule /([.])([ \t]*)(#{id})/ do
+          groups Punctuation, Text, Name::Attribute
+          push :slash_starts_regex
+        end
+
+        rule /#{id}(?=\s*:)/, Name::Attribute, :slash_starts_regex
+
+        rule /#{id}/ do |m|
+          if self.class.keywords.include? m[0]
+            token Keyword
+          elsif self.class.constants.include? m[0]
+            token Name::Constant
+          elsif self.class.builtins.include? m[0]
+            token Name::Builtin
+          else
+            token Name::Other
+          end
+
+          push :slash_starts_regex
+        end
+
+        rule /[{(\[;,]/, Punctuation, :slash_starts_regex
+        rule /[})\].]/, Punctuation
+
+        rule /\d+[.]\d+([eE]\d+)?[fd]?/, Num::Float
+        rule /0x[0-9a-fA-F]+/, Num::Hex
+        rule /\d+/, Num::Integer
+        rule /"""/, Str, :tdqs
+        rule /'''/, Str, :tsqs
+        rule /"/, Str, :dqs
+        rule /'/, Str, :sqs
+      end
+
+      state :strings do
+        # all coffeescript strings are multi-line
+        rule /[^#\\'"]+/m, Str
+
+        rule /\\./, Str::Escape
+        rule /#/, Str
+      end
+
+      state :double_strings do
+        rule /'/, Str
+        mixin :has_interpolation
+        mixin :strings
+      end
+
+      state :single_strings do
+        rule /"/, Str
+        mixin :strings
+      end
+
+      state :interpolation do
+        rule /}/, Str::Interpol, :pop!
+        mixin :root
+      end
+
+      state :has_interpolation do
+        rule /[#][{]/, Str::Interpol, :interpolation
+      end
+
+      state :dqs do
+        rule /"/, Str, :pop!
+        mixin :double_strings
+      end
+
+      state :tdqs do
+        rule /"""/, Str, :pop!
+        rule /"/, Str
+        mixin :double_strings
+      end
+
+      state :sqs do
+        rule /'/, Str, :pop!
+        mixin :single_strings
+      end
+
+      state :tsqs do
+        rule /'''/, Str, :pop!
+        rule /'/, Str
+        mixin :single_strings
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/common_lisp.rb b/app/server/vendor/rouge/lib/rouge/lexers/common_lisp.rb
new file mode 100755
index 0000000..1014c0c
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/common_lisp.rb
@@ -0,0 +1,344 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class CommonLisp < RegexLexer
+      desc "The Common Lisp variant of Lisp (common-lisp.net)"
+      tag 'common_lisp'
+      aliases 'cl', 'common-lisp'
+
+      filenames '*.cl', '*.lisp', '*.el' # used for Elisp too
+      mimetypes 'text/x-common-lisp'
+
+      # 638 functions
+      BUILTIN_FUNCTIONS = Set.new %w(
+        < <= = > >= - / /= * + 1- 1+ abort abs acons acos acosh add-method
+        adjoin adjustable-array-p adjust-array allocate-instance
+        alpha-char-p alphanumericp append apply apropos apropos-list
+        aref arithmetic-error-operands arithmetic-error-operation
+        array-dimension array-dimensions array-displacement
+        array-element-type array-has-fill-pointer-p array-in-bounds-p
+        arrayp array-rank array-row-major-index array-total-size
+        ash asin asinh assoc assoc-if assoc-if-not atan atanh atom
+        bit bit-and bit-andc1 bit-andc2 bit-eqv bit-ior bit-nand
+        bit-nor bit-not bit-orc1 bit-orc2 bit-vector-p bit-xor boole
+        both-case-p boundp break broadcast-stream-streams butlast
+        byte byte-position byte-size caaaar caaadr caaar caadar
+        caaddr caadr caar cadaar cadadr cadar caddar cadddr caddr
+        cadr call-next-method car cdaaar cdaadr cdaar cdadar cdaddr
+        cdadr cdar cddaar cddadr cddar cdddar cddddr cdddr cddr cdr
+        ceiling cell-error-name cerror change-class char char< char<=
+        char= char> char>= char/= character characterp char-code
+        char-downcase char-equal char-greaterp char-int char-lessp
+        char-name char-not-equal char-not-greaterp char-not-lessp
+        char-upcase cis class-name class-of clear-input clear-output
+        close clrhash code-char coerce compile compiled-function-p
+        compile-file compile-file-pathname compiler-macro-function
+        complement complex complexp compute-applicable-methods
+        compute-restarts concatenate concatenated-stream-streams conjugate
+        cons consp constantly constantp continue copy-alist copy-list
+        copy-pprint-dispatch copy-readtable copy-seq copy-structure
+        copy-symbol copy-tree cos cosh count count-if count-if-not
+        decode-float decode-universal-time delete delete-duplicates
+        delete-file delete-if delete-if-not delete-package denominator
+        deposit-field describe describe-object digit-char digit-char-p
+        directory directory-namestring disassemble documentation dpb
+        dribble echo-stream-input-stream echo-stream-output-stream
+        ed eighth elt encode-universal-time endp enough-namestring
+        ensure-directories-exist ensure-generic-function eq
+        eql equal equalp error eval evenp every exp export expt
+        fboundp fceiling fdefinition ffloor fifth file-author
+        file-error-pathname file-length file-namestring file-position
+        file-string-length file-write-date fill fill-pointer find
+        find-all-symbols find-class find-if find-if-not find-method
+        find-package find-restart find-symbol finish-output first
+        float float-digits floatp float-precision float-radix
+        float-sign floor fmakunbound force-output format fourth
+        fresh-line fround ftruncate funcall function-keywords
+        function-lambda-expression functionp gcd gensym gentemp get
+        get-decoded-time get-dispatch-macro-character getf gethash
+        get-internal-real-time get-internal-run-time get-macro-character
+        get-output-stream-string get-properties get-setf-expansion
+        get-universal-time graphic-char-p hash-table-count hash-table-p
+        hash-table-rehash-size hash-table-rehash-threshold
+        hash-table-size hash-table-test host-namestring identity
+        imagpart import initialize-instance input-stream-p inspect
+        integer-decode-float integer-length integerp interactive-stream-p
+        intern intersection invalid-method-error invoke-debugger
+        invoke-restart invoke-restart-interactively isqrt keywordp
+        last lcm ldb ldb-test ldiff length lisp-implementation-type
+        lisp-implementation-version list list* list-all-packages listen
+        list-length listp load load-logical-pathname-translations
+        log logand logandc1 logandc2 logbitp logcount logeqv
+        logical-pathname logical-pathname-translations logior
+        lognand lognor lognot logorc1 logorc2 logtest logxor
+        long-site-name lower-case-p machine-instance machine-type
+        machine-version macroexpand macroexpand-1 macro-function
+        make-array make-broadcast-stream make-concatenated-stream
+        make-condition make-dispatch-macro-character make-echo-stream
+        make-hash-table make-instance make-instances-obsolete make-list
+        make-load-form make-load-form-saving-slots make-package
+        make-pathname make-random-state make-sequence make-string
+        make-string-input-stream make-string-output-stream make-symbol
+        make-synonym-stream make-two-way-stream makunbound map mapc
+        mapcan mapcar mapcon maphash map-into mapl maplist mask-field
+        max member member-if member-if-not merge merge-pathnames
+        method-combination-error method-qualifiers min minusp mismatch mod
+        muffle-warning name-char namestring nbutlast nconc next-method-p
+        nintersection ninth no-applicable-method no-next-method not notany
+        notevery nreconc nreverse nset-difference nset-exclusive-or
+        nstring-capitalize nstring-downcase nstring-upcase nsublis
+        nsubst nsubst-if nsubst-if-not nsubstitute nsubstitute-if
+        nsubstitute-if-not nth nthcdr null numberp numerator nunion
+        oddp open open-stream-p output-stream-p package-error-package
+        package-name package-nicknames packagep package-shadowing-symbols
+        package-used-by-list package-use-list pairlis parse-integer
+        parse-namestring pathname pathname-device pathname-directory
+        pathname-host pathname-match-p pathname-name pathnamep
+        pathname-type pathname-version peek-char phase plusp
+        position position-if position-if-not pprint pprint-dispatch
+        pprint-fill pprint-indent pprint-linear pprint-newline pprint-tab
+        pprint-tabular prin1 prin1-to-string princ princ-to-string print
+        print-object probe-file proclaim provide random random-state-p
+        rassoc rassoc-if rassoc-if-not rational rationalize rationalp
+        read read-byte read-char read-char-no-hang read-delimited-list
+        read-from-string read-line read-preserving-whitespace
+        read-sequence readtable-case readtablep realp realpart
+        reduce reinitialize-instance rem remhash remove
+        remove-duplicates remove-if remove-if-not remove-method
+        remprop rename-file rename-package replace require rest
+        restart-name revappend reverse room round row-major-aref
+        rplaca rplacd sbit scale-float schar search second set
+        set-difference set-dispatch-macro-character set-exclusive-or
+        set-macro-character set-pprint-dispatch set-syntax-from-char
+        seventh shadow shadowing-import shared-initialize
+        short-site-name signal signum simple-bit-vector-p
+        simple-condition-format-arguments simple-condition-format-control
+        simple-string-p simple-vector-p sin sinh sixth sleep slot-boundp
+        slot-exists-p slot-makunbound slot-missing slot-unbound slot-value
+        software-type software-version some sort special-operator-p
+        sqrt stable-sort standard-char-p store-value stream-element-type
+        stream-error-stream stream-external-format streamp string string<
+        string<= string= string> string>= string/= string-capitalize
+        string-downcase string-equal string-greaterp string-left-trim
+        string-lessp string-not-equal string-not-greaterp string-not-lessp
+        stringp string-right-trim string-trim string-upcase sublis subseq
+        subsetp subst subst-if subst-if-not substitute substitute-if
+        substitute-if-not subtypepsvref sxhash symbol-function
+        symbol-name symbolp symbol-package symbol-plist symbol-value
+        synonym-stream-symbol syntax: tailp tan tanh tenth terpri third
+        translate-logical-pathname translate-pathname tree-equal truename
+        truncate two-way-stream-input-stream two-way-stream-output-stream
+        type-error-datum type-error-expected-type type-of
+        typep unbound-slot-instance unexport unintern union
+        unread-char unuse-package update-instance-for-different-class
+        update-instance-for-redefined-class upgraded-array-element-type
+        upgraded-complex-part-type upper-case-p use-package
+        user-homedir-pathname use-value values values-list vector vectorp
+        vector-pop vector-push vector-push-extend warn wild-pathname-p
+        write write-byte write-char write-line write-sequence write-string
+        write-to-string yes-or-no-p y-or-n-p zerop
+      ).freeze
+
+      SPECIAL_FORMS = Set.new %w(
+        block catch declare eval-when flet function go if labels lambda
+        let let* load-time-value locally macrolet multiple-value-call
+        multiple-value-prog1 progn progv quote return-from setq
+        symbol-macrolet tagbody the throw unwind-protect
+      )
+
+      MACROS = Set.new %w(
+        and assert call-method case ccase check-type cond ctypecase decf
+        declaim defclass defconstant defgeneric define-compiler-macro
+        define-condition define-method-combination define-modify-macro
+        define-setf-expander define-symbol-macro defmacro defmethod
+        defpackage defparameter defsetf defstruct deftype defun defvar
+        destructuring-bind do do* do-all-symbols do-external-symbols
+        dolist do-symbols dotimes ecase etypecase formatter
+        handler-bind handler-case ignore-errors incf in-package
+        lambda loop loop-finish make-method multiple-value-bind
+        multiple-value-list multiple-value-setq nth-value or pop
+        pprint-exit-if-list-exhausted pprint-logical-block pprint-pop
+        print-unreadable-object prog prog* prog1 prog2 psetf psetq
+        push pushnew remf restart-bind restart-case return rotatef
+        setf shiftf step time trace typecase unless untrace when
+        with-accessors with-compilation-unit with-condition-restarts
+        with-hash-table-iterator with-input-from-string with-open-file
+        with-open-stream with-output-to-string with-package-iterator
+        with-simple-restart with-slots with-standard-io-syntax
+      )
+
+      LAMBDA_LIST_KEYWORDS = Set.new %w(
+        &allow-other-keys &aux &body &environment &key &optional &rest
+        &whole
+      )
+
+      DECLARATIONS = Set.new %w(
+        dynamic-extent ignore optimize ftype inline special ignorable
+        notinline type
+      )
+
+      BUILTIN_TYPES = Set.new %w(
+        atom boolean base-char base-string bignum bit compiled-function
+        extended-char fixnum keyword nil signed-byte short-float
+        single-float double-float long-float simple-array
+        simple-base-string simple-bit-vector simple-string simple-vector
+        standard-char unsigned-byte
+
+        arithmetic-error cell-error condition control-error
+        division-by-zero end-of-file error file-error
+        floating-point-inexact floating-point-overflow
+        floating-point-underflow floating-point-invalid-operation
+        parse-error package-error print-not-readable program-error
+        reader-error serious-condition simple-condition simple-error
+        simple-type-error simple-warning stream-error storage-condition
+        style-warning type-error unbound-variable unbound-slot
+        undefined-function warning
+      )
+
+      BUILTIN_CLASSES = Set.new %w(
+        array broadcast-stream bit-vector built-in-class character
+        class complex concatenated-stream cons echo-stream file-stream
+        float function generic-function hash-table integer list
+        logical-pathname method-combination method null number package
+        pathname ratio rational readtable real random-state restart
+        sequence standard-class standard-generic-function standard-method
+        standard-object string-stream stream string structure-class
+        structure-object symbol synonym-stream t two-way-stream vector
+      )
+
+      nonmacro = /\\.|[a-zA-Z0-9!$%&*+-\/<=>?@\[\]^_{}~]/
+      constituent = /#{nonmacro}|[#.:]/
+      terminated = /(?=[ "'()\n,;`])/ # whitespace or terminating macro chars
+      symbol = /(\|[^\|]+\||#{nonmacro}#{constituent}*)/
+
+      state :root do
+        rule /\s+/m, Text
+        rule /;.*$/, Comment::Single
+        rule /#\|/, Comment::Multiline, :multiline_comment
+
+        # encoding comment
+        rule /#\d*Y.*$/, Comment::Special
+        rule /"(\\.|[^"\\])*"/, Str
+
+        rule /[:']#{symbol}/, Str::Symbol
+        rule /['`]/, Operator
+
+        # numbers
+        rule /[-+]?\d+\.?#{terminated}/, Num::Integer
+        rule %r([-+]?\d+/\d+#{terminated}), Num::Integer
+        rule %r(
+          [-+]?
+          (\d*\.\d+([defls][-+]?\d+)?
+          |\d+(\.\d*)?[defls][-+]?\d+)
+          #{terminated}
+        )x, Num::Float
+
+        # sharpsign strings and characters
+        rule /#\\.#{terminated}/, Str::Char
+        rule /#\\#{symbol}/, Str::Char
+
+        rule /#\(/, Operator, :root
+
+        # bitstring
+        rule /#\d*\*[01]*/, Other
+
+        # uninterned symbol
+        rule /#:#{symbol}/, Str::Symbol
+
+        # read-time and load-time evaluation
+        rule /#[.,]/, Operator
+
+        # function shorthand
+        rule /#'/, Name::Function
+
+        # binary rational
+        rule /#b[+-]?[01]+(\/[01]+)?/i, Num
+
+        # octal rational
+        rule /#o[+-]?[0-7]+(\/[0-7]+)?/i, Num::Oct
+
+        # hex rational
+        rule /#x[+-]?[0-9a-f]+(\/[0-9a-f]+)?/i, Num
+
+        # complex
+        rule /(#c)(\()/i do
+          groups Num, Punctuation
+          push :root
+        end
+
+        # arrays and structures
+        rule /(#(?:\d+a|s))(\()/i do
+          groups Literal::Other, Punctuation
+          push :root
+        end
+
+        # path
+        rule /#p?"(\\.|[^"])*"/i, Str::Symbol
+
+        # reference
+        rule /#\d+[=#]/, Operator
+
+        # read-time comment
+        rule /#+nil#{terminated}\s*\(/, Comment, :commented_form
+
+        # read-time conditional
+        rule /#[+-]/, Operator
+
+        # special operators that should have been parsed already
+        rule /(,@|,|\.)/, Operator
+
+        # special constants
+        rule /(t|nil)#{terminated}/, Name::Constant
+
+        # functions and variables
+        # note that these get filtered through in stream_tokens
+        rule /\*#{symbol}\*/, Name::Variable::Global
+        rule symbol do |m|
+          sym = m[0]
+
+          if BUILTIN_FUNCTIONS.include? sym
+            token Name::Builtin
+          elsif SPECIAL_FORMS.include? sym
+            token Keyword
+          elsif MACROS.include? sym
+            token Name::Builtin
+          elsif LAMBDA_LIST_KEYWORDS.include? sym
+            token Keyword
+          elsif DECLARATIONS.include? sym
+            token Keyword
+          elsif BUILTIN_TYPES.include? sym
+            token Keyword::Type
+          elsif BUILTIN_CLASSES.include? sym
+            token Name::Class
+          else
+            token Name::Variable
+          end
+        end
+
+        rule /\(/, Punctuation, :root
+        rule /\)/, Punctuation do
+          if stack.empty?
+            token Error
+          else
+            token Punctuation
+            pop!
+          end
+        end
+      end
+
+      state :multiline_comment do
+        rule /#\|/, Comment::Multiline, :multiline_comment
+        rule /\|#/, Comment::Multiline, :pop!
+        rule /[^\|#]+/, Comment::Multiline
+        rule /[\|#]/, Comment::Multiline
+      end
+
+      state :commented_form do
+        rule /\(/, Comment, :commented_form
+        rule /\)/, Comment, :pop!
+        rule /[^()]+/, Comment
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/conf.rb b/app/server/vendor/rouge/lib/rouge/lexers/conf.rb
new file mode 100755
index 0000000..ee98e8c
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/conf.rb
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Conf < RegexLexer
+      tag 'conf'
+      aliases 'config', 'configuration'
+
+      desc 'A generic lexer for configuration files'
+      filenames '*.conf', '*.config'
+
+      # short and sweet
+      state :root do
+        rule /#.*?\n/, Comment
+        rule /".*?"/, Str::Double
+        rule /'.*?'/, Str::Single
+        rule /[a-z]\w*/i, Name
+        rule /\d+/, Num
+        rule /[^\d\w#"']+/, Text
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/cpp.rb b/app/server/vendor/rouge/lib/rouge/lexers/cpp.rb
new file mode 100755
index 0000000..586c28a
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/cpp.rb
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    load_const :C, 'c.rb'
+
+    class Cpp < C
+      desc "The C++ programming language"
+
+      tag 'cpp'
+      aliases 'c++'
+      # the many varied filenames of c++ source files...
+      filenames '*.cpp', '*.hpp',
+                '*.c++', '*.h++',
+                '*.cc',  '*.hh',
+                '*.cxx', '*.hxx'
+      mimetypes 'text/x-c++hdr', 'text/x-c++src'
+
+      def self.keywords
+        @keywords ||= super + Set.new(%w(
+          asm catch const_cast delete dynamic_cast explicit export
+          friend mutable namespace new operator private protected public
+          reinterpret_cast restrict static_cast template this throw
+          throws typeid typename using virtual
+        ))
+      end
+
+      def self.reserved
+        @reserved ||= super + Set.new(%w(
+          __virtual_inheritance __uuidof __super __single_inheritance
+          __multiple_inheritance __interface __event
+        ))
+      end
+
+      id = /[a-zA-Z_][a-zA-Z0-9]*/
+
+      prepend :root do
+        # Offload C++ extensions, http://offload.codeplay.com/
+        rule /(?:__offload|__blockingoffload|__outer)\b/, Keyword::Pseudo
+      end
+
+      # digits with optional inner quotes
+      # see www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3781.pdf
+      dq = /\d('?\d)*/
+
+      prepend :statements do
+        rule /class\b/, Keyword, :classname
+        rule %r((#{dq}[.]#{dq}?|[.]#{dq})(e[+-]?#{dq}[lu]*)?)i, Num::Float
+        rule %r(#{dq}e[+-]?#{dq}[lu]*)i, Num::Float
+        rule /0x\h('?\h)*[lu]*/i, Num::Hex
+        rule /0[0-7]('?[0-7])*[lu]*/i, Num::Oct
+        rule /#{dq}[lu]*/i, Num::Integer
+      end
+
+      state :classname do
+        rule id, Name::Class, :pop!
+
+        # template specification
+        rule /\s*(?=>)/m, Text, :pop!
+        mixin :whitespace
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/csharp.rb b/app/server/vendor/rouge/lib/rouge/lexers/csharp.rb
new file mode 100755
index 0000000..71c95c7
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/csharp.rb
@@ -0,0 +1,87 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class CSharp < RegexLexer
+      tag 'csharp'
+      aliases 'c#', 'cs'
+      filenames '*.cs'
+      mimetypes 'text/x-csharp'
+
+      desc 'a multi-paradigm language targeting .NET'
+
+      # TODO: support more of unicode
+      id = /@?[_a-z]\w*/i
+
+      keywords = %w(
+        abstract alias as base break case catch checked const continue
+        default delegate do else enum event explicit extern false
+        finally fixed for foreach global goto if implicit in interface
+        internal is lock new null operator out override params private
+        protected public readonly ref return sealed sizeof stackalloc
+        static switch this throw true try typeof unchecked unsafe
+        virtual void while get set new partial yield add remove value
+      )
+
+      keywords_type = %w(
+        bool byte char decimal double float int long object sbyte
+        short string uint ulong ushort
+      )
+
+      cpp_keywords = %w(
+        if endif else elif define undef line error warning region
+        endregion pragma
+      )
+
+      state :whitespace do
+        rule /\s+/m, Text
+        rule %r(//.*?\n), Comment::Single
+        rule %r(/[*].*?[*]/)m, Comment::Multiline
+      end
+
+      state :root do
+        mixin :whitespace
+
+        rule /^\s*\[.*?\]/, Name::Attribute
+        rule /[$]\s*"/, Str, :splice_string
+        rule /[$]\s*<#/, Str, :splice_recstring
+        rule /<#/, Str, :recstring
+
+        rule /(<\[)\s*(#{id}:)?/, Keyword
+        rule /\]>/, Keyword
+
+        rule /[~!%^&*()+=|\[\]{}:;,.<>\/?-]/, Punctuation
+        rule /@"(\\.|.)*?"/, Str
+        rule /"(\\.|.)*?["\n]/, Str
+        rule /'(\\.|.)'/, Str::Char
+        rule /0x[0-9a-f]+[lu]?/i, Num
+        rule %r(
+          [0-9]
+          ([.][0-9]*)? # decimal
+          (e[+-][0-9]+)? # exponent
+          [fldu]? # type
+        )ix, Num
+        rule /^#[ \t]*(#{cpp_keywords.join('|')})\b.*?\n/,
+          Comment::Preproc
+        rule /\b(#{keywords.join('|')})\b/, Keyword
+        rule /\b(#{keywords_type.join('|')})\b/, Keyword::Type
+        rule /class|struct/, Keyword, :class
+        rule /namespace|using/, Keyword, :namespace
+        rule /#{id}(?=\s*[(])/, Name::Function
+        rule id, Name
+      end
+
+      state :class do
+        mixin :whitespace
+        rule id, Name::Class, :pop!
+      end
+
+      state :namespace do
+        mixin :whitespace
+        rule /(?=[(])/, Text, :pop!
+        rule /(#{id}|[.])+/, Name::Namespace, :pop!
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/css.rb b/app/server/vendor/rouge/lib/rouge/lexers/css.rb
new file mode 100755
index 0000000..8eee4f0
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/css.rb
@@ -0,0 +1,270 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class CSS < RegexLexer
+      desc "Cascading Style Sheets, used to style web pages"
+
+      tag 'css'
+      filenames '*.css'
+      mimetypes 'text/css'
+
+      identifier = /[a-zA-Z0-9_-]+/
+      number = /-?(?:[0-9]+(\.[0-9]+)?|\.[0-9]+)/
+
+      def self.attributes
+        @attributes ||= Set.new %w(
+          align-content align-items align-self alignment-adjust
+          alignment-baseline all anchor-point animation
+          animation-delay animation-direction animation-duration
+          animation-fill-mode animation-iteration-count animation-name
+          animation-play-state animation-timing-function appearance
+          azimuth backface-visibility background background-attachment
+          background-clip background-color background-image
+          background-origin background-position background-repeat
+          background-size baseline-shift binding bleed bookmark-label
+          bookmark-level bookmark-state bookmark-target border
+          border-bottom border-bottom-color border-bottom-left-radius
+          border-bottom-right-radius border-bottom-style
+          border-bottom-width border-collapse border-color
+          border-image border-image-outset border-image-repeat
+          border-image-slice border-image-source border-image-width
+          border-left border-left-color border-left-style
+          border-left-width border-radius border-right
+          border-right-color border-right-style border-right-width
+          border-spacing border-style border-top border-top-color
+          border-top-left-radius border-top-right-radius
+          border-top-style border-top-width border-width bottom
+          box-align box-decoration-break box-direction box-flex
+          box-flex-group box-lines box-ordinal-group box-orient
+          box-pack box-shadow box-sizing break-after break-before
+          break-inside caption-side clear clip clip-path
+          clip-rule color color-profile columns column-count
+          column-fill column-gap column-rule column-rule-color
+          column-rule-style column-rule-width column-span
+          column-width content counter-increment counter-reset
+          crop cue cue-after cue-before cursor direction display
+          dominant-baseline drop-initial-after-adjust
+          drop-initial-after-align drop-initial-before-adjust
+          drop-initial-before-align drop-initial-size
+          drop-initial-value elevation empty-cells filter fit
+          fit-position flex flex-basis flex-direction flex-flow
+          flex-grow flex-shrink flex-wrap float float-offset
+          font font-family font-feature-settings
+          font-kerning font-language-override font-size
+          font-size-adjust font-stretch font-style font-synthesis
+          font-variant font-variant-alternates font-variant-caps
+          font-variant-east-asian font-variant-ligatures
+          font-variant-numeric font-variant-position font-weight
+          grid-cell grid-column grid-column-align grid-column-sizing
+          grid-column-span grid-columns grid-flow grid-row
+          grid-row-align grid-row-sizing grid-row-span
+          grid-rows grid-template hanging-punctuation height
+          hyphenate-after hyphenate-before hyphenate-character
+          hyphenate-lines hyphenate-resource hyphens icon
+          image-orientation image-rendering image-resolution
+          ime-mode inline-box-align justify-content
+          left letter-spacing line-break line-height
+          line-stacking line-stacking-ruby line-stacking-shift
+          line-stacking-strategy list-style list-style-image
+          list-style-position list-style-type margin
+          margin-bottom margin-left margin-right margin-top
+          mark marker-offset marks mark-after mark-before
+          marquee-direction marquee-loop marquee-play-count
+          marquee-speed marquee-style mask max-height max-width
+          min-height min-width move-to nav-down
+          nav-index nav-left nav-right nav-up object-fit
+          object-position opacity order orphans outline
+          outline-color outline-offset outline-style
+          outline-width overflow overflow-style overflow-wrap
+          overflow-x overflow-y padding padding-bottom
+          padding-left padding-right padding-top
+          page page-break-after page-break-before
+          page-break-inside page-policy pause pause-after
+          pause-before perspective perspective-origin
+          phonemes pitch pitch-range play-during pointer-events
+          position presentation-level punctuation-trim quotes
+          rendering-intent resize rest rest-after rest-before
+          richness right rotation rotation-point ruby-align
+          ruby-overhang ruby-position ruby-span size speak
+          speak-as speak-header speak-numeral speak-punctuation
+          speech-rate src stress string-set
+          tab-size table-layout target target-name
+          target-new target-position text-align
+          text-align-last text-combine-horizontal
+          text-decoration text-decoration-color
+          text-decoration-line text-decoration-skip
+          text-decoration-style text-emphasis
+          text-emphasis-color text-emphasis-position
+          text-emphasis-style text-height text-indent
+          text-justify text-orientation text-outline
+          text-overflow text-rendering text-shadow
+          text-space-collapse text-transform
+          text-underline-position text-wrap top
+          transform transform-origin transform-style
+          transition transition-delay transition-duration
+          transition-property transition-timing-function
+          unicode-bidi vertical-align
+          visibility voice-balance voice-duration
+          voice-family voice-pitch voice-pitch-range
+          voice-range voice-rate voice-stress voice-volume
+          volume white-space widows width word-break
+          word-spacing word-wrap writing-mode z-index
+        )
+      end
+
+      def self.builtins
+        @builtins ||= Set.new %w(
+          above absolute always armenian aural auto avoid left bottom
+          baseline behind below bidi-override blink block bold bolder
+          both bottom capitalize center center-left center-right circle
+          cjk-ideographic close-quote collapse condensed continuous crop
+          cross crosshair cursive dashed decimal decimal-leading-zero
+          default digits disc dotted double e-resize embed expanded
+          extra-condensed extra-expanded fantasy far-left far-right fast
+          faster fixed georgian groove hebrew help hidden hide high higher
+          hiragana hiragana-iroha icon inherit inline inline-table inset
+          inside invert italic justify katakana katakana-iroha landscape
+          large larger left left-side leftwards level lighter line-through
+          list-item loud low lower lower-alpha lower-greek lower-roman
+          lowercase ltr medium message-box middle mix monospace n-resize
+          narrower ne-resize no-close-quote no-open-quote no-repeat none
+          normal nowrap nw-resize oblique once open-quote outset outside
+          overline pointer portrait px relative repeat repeat-x repeat-y
+          rgb ridge right right-side rightwards s-resize sans-serif scroll
+          se-resize semi-condensed semi-expanded separate serif show
+          silent slow slower small-caps small-caption smaller soft solid
+          spell-out square static status-bar super sw-resize table-caption
+          table-cell table-column table-column-group table-footer-group
+          table-header-group table-row table-row-group text text-bottom
+          text-top thick thin top transparent ultra-condensed
+          ultra-expanded underline upper-alpha upper-latin upper-roman
+          uppercase url visible w-resize wait wider x-fast x-high x-large
+          x-loud x-low x-small x-soft xx-large xx-small yes
+        )
+      end
+
+      def self.constants
+        @constants ||= Set.new %w(
+          indigo gold firebrick indianred yellow darkolivegreen
+          darkseagreen mediumvioletred mediumorchid chartreuse
+          mediumslateblue black springgreen crimson lightsalmon brown
+          turquoise olivedrab cyan silver skyblue gray darkturquoise
+          goldenrod darkgreen darkviolet darkgray lightpink teal
+          darkmagenta lightgoldenrodyellow lavender yellowgreen thistle
+          violet navy orchid blue ghostwhite honeydew cornflowerblue
+          darkblue darkkhaki mediumpurple cornsilk red bisque slategray
+          darkcyan khaki wheat deepskyblue darkred steelblue aliceblue
+          gainsboro mediumturquoise floralwhite coral purple lightgrey
+          lightcyan darksalmon beige azure lightsteelblue oldlace
+          greenyellow royalblue lightseagreen mistyrose sienna lightcoral
+          orangered navajowhite lime palegreen burlywood seashell
+          mediumspringgreen fuchsia papayawhip blanchedalmond peru
+          aquamarine white darkslategray ivory dodgerblue lemonchiffon
+          chocolate orange forestgreen slateblue olive mintcream
+          antiquewhite darkorange cadetblue moccasin limegreen saddlebrown
+          darkslateblue lightskyblue deeppink plum aqua darkgoldenrod
+          maroon sandybrown magenta tan rosybrown pink lightblue
+          palevioletred mediumseagreen dimgray powderblue seagreen snow
+          mediumblue midnightblue paleturquoise palegoldenrod whitesmoke
+          darkorchid salmon lightslategray lawngreen lightgreen tomato
+          hotpink lightyellow lavenderblush linen mediumaquamarine green
+          blueviolet peachpuff
+        )
+      end
+
+      # source: http://www.w3.org/TR/CSS21/syndata.html#vendor-keyword-history
+      def self.vendor_prefixes
+        @vendor_prefixes ||= Set.new %w(
+          -ah- -atsc- -hp- -khtml- -moz- -ms- -o- -rim- -ro- -tc- -wap-
+          -webkit- -xv- mso- prince-
+        )
+      end
+
+      state :root do
+        mixin :basics
+        rule /{/, Punctuation, :stanza
+        rule /:#{identifier}/, Name::Decorator
+        rule /\.#{identifier}/, Name::Class
+        rule /##{identifier}/, Name::Function
+        rule /@#{identifier}/, Keyword, :at_rule
+        rule identifier, Name::Tag
+        rule %r([~^*!%&\[\]()<>|+=@:;,./?-]), Operator
+      end
+
+      state :value do
+        mixin :basics
+        rule /url\(.*?\)/, Str::Other
+        rule /#[0-9a-f]{1,6}/i, Num # colors
+        rule /#{number}(?:em|px|%|pt|pc|in|mm|m|ex|s)?\b/, Num
+        rule /[\[\]():\/.,]/, Punctuation
+        rule /"(\\\\|\\"|[^"])*"/, Str::Single
+        rule /'(\\\\|\\'|[^'])*'/, Str::Double
+        rule(identifier) do |m|
+          if self.class.constants.include? m[0]
+            token Name::Constant
+          elsif self.class.builtins.include? m[0]
+            token Name::Builtin
+          else
+            token Name
+          end
+        end
+      end
+
+      state :at_rule do
+        rule /{(?=\s*#{identifier}\s*:)/m, Punctuation, :at_stanza
+        rule /{/, Punctuation, :at_body
+        rule /;/, Punctuation, :pop!
+        mixin :value
+      end
+
+      state :at_body do
+        mixin :at_content
+        mixin :root
+      end
+
+      state :at_stanza do
+        mixin :at_content
+        mixin :stanza
+      end
+
+      state :at_content do
+        rule /}/ do
+          token Punctuation
+          pop! 2
+        end
+      end
+
+      state :basics do
+        rule /\s+/m, Text
+        rule %r(/\*(?:.*?)\*/)m, Comment
+      end
+
+      state :stanza do
+        mixin :basics
+        rule /}/, Punctuation, :pop!
+        rule /(#{identifier})(\s*)(:)/m do |m|
+          name_tok = if self.class.attributes.include? m[1]
+            Name::Label
+          elsif self.class.vendor_prefixes.any? { |p| m[1].start_with?(p) }
+            Name::Label
+          else
+            Name::Property
+          end
+
+          groups name_tok, Text, Punctuation
+
+          push :stanza_value
+        end
+      end
+
+      state :stanza_value do
+        rule /;/, Punctuation, :pop!
+        rule(/(?=})/) { pop! }
+        rule /!important\b/, Comment::Preproc
+        rule /^@.*?$/, Comment::Preproc
+        mixin :value
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/diff.rb b/app/server/vendor/rouge/lib/rouge/lexers/diff.rb
new file mode 100755
index 0000000..c4efcb3
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/diff.rb
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Diff < RegexLexer
+      desc "Lexes unified diffs or patches"
+
+      tag 'diff'
+      aliases 'patch', 'udiff'
+      filenames '*.diff', '*.patch'
+      mimetypes 'text/x-diff', 'text/x-patch'
+
+      def self.analyze_text(text)
+        return 1   if text.start_with?('Index: ')
+        return 1   if text.start_with?('diff ')
+
+        return 0.9 if text =~ /\A---.*?\n\+\+\+/m
+      end
+
+      state :header do
+        rule /^diff .*?\n(?=---|\+\+\+)/m, Generic::Heading
+        rule /^--- .*?\n/, Generic::Deleted
+        rule /^\+\+\+ .*?\n/, Generic::Inserted
+      end
+
+      state :diff do
+        rule /@@ -\d+,\d+ \+\d+,\d+ @@.*?\n/, Generic::Heading
+        rule /^\+.*?\n/, Generic::Inserted
+        rule /^-.*?\n/,  Generic::Deleted
+        rule /^ .*?\n/,  Text
+        rule /^.*?\n/,   Error
+      end
+
+      state :root do
+        mixin :header
+        mixin :diff
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/elixir.rb b/app/server/vendor/rouge/lib/rouge/lexers/elixir.rb
new file mode 100755
index 0000000..9f9de1c
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/elixir.rb
@@ -0,0 +1,106 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    # Direct port of pygments Lexer.
+    # See: https://bitbucket.org/birkenfeld/pygments-main/src/7304e4759ae65343d89a51359ca538912519cc31/pygments/lexers/functional.py?at=default#cl-2362
+    class Elixir < RegexLexer
+      desc "Elixir language (elixir-lang.org)"
+
+      tag 'elixir'
+
+      filenames '*.ex', '*.exs'
+
+      mimetypes 'text/x-elixir', 'application/x-elixir'
+
+      BRACES = [
+        ['\{', '\}', 'cb'],
+        ['\[', '\]', 'sb'],
+        ['\(', '\)', 'pa'],
+        ['\<', '\>', 'lt']
+      ]
+
+      state :root do
+        rule /\s+/m, Text
+        rule /#.*$/, Comment::Single
+        rule %r{\b(case|cond|end|bc|lc|if|unless|try|loop|receive|fn|defmodule|
+             defp?|defprotocol|defimpl|defrecord|defmacrop?|defdelegate|
+             defexception|exit|raise|throw|unless|after|rescue|catch|else)\b(?![?!])|
+             (?<!\.)\b(do|\-\>)\b}x, Keyword
+        rule /\b(import|require|use|recur|quote|unquote|super|refer)\b(?![?!])/, Keyword::Namespace
+        rule /(?<!\.)\b(and|not|or|when|xor|in)\b/, Operator::Word
+        rule %r{%=|\*=|\*\*=|\+=|\-=|\^=|\|\|=|
+             <=>|<(?!<|=)|>(?!<|=|>)|<=|>=|===|==|=~|!=|!~|(?=[\s\t])\?|
+             (?<=[\s\t])!+|&(&&?|(?!\d))|\|\||\^|\*|\+|\-|/|
+             \||\+\+|\-\-|\*\*|\/\/|\<\-|\<\>|<<|>>|=|\.|~~~}x, Operator
+        rule %r{(?<!:)(:)([a-zA-Z_]\w*([?!]|=(?![>=]))?|\<\>|===?|>=?|<=?|
+             <=>|&&?|%\(\)|%\[\]|%\{\}|\+\+?|\-\-?|\|\|?|\!|//|[%&`/\|]|
+             \*\*?|=?~|<\-)|([a-zA-Z_]\w*([?!])?)(:)(?!:)}, Str::Symbol
+        rule /:"/, Str::Symbol, :interpoling_symbol
+        rule /\b(nil|true|false)\b(?![?!])|\b[A-Z]\w*\b/, Name::Constant
+        rule /\b(__(FILE|LINE|MODULE|MAIN|FUNCTION)__)\b(?![?!])/, Name::Builtin::Pseudo
+        rule /[a-zA-Z_!][\w_]*[!\?]?/, Name
+        rule %r{::|[%(){};,/\|:\\\[\]]}, Punctuation
+        rule /@[a-zA-Z_]\w*|&\d/, Name::Variable
+        rule %r{\b(0[xX][0-9A-Fa-f]+|\d(_?\d)*(\.(?![^\d\s])
+             (_?\d)*)?([eE][-+]?\d(_?\d)*)?|0[bB][01]+)\b}x, Num
+        rule %r{~r\/.*\/}, Str::Regex
+
+        mixin :strings
+      end
+
+      state :strings do
+        rule /(%[A-Ba-z])?"""(?:.|\n)*?"""/, Str::Doc
+        rule /'''(?:.|\n)*?'''/, Str::Doc
+        rule /"/, Str::Doc, :dqs
+        rule /'.*?'/, Str::Single
+        rule %r{(?<!\w)\?(\\(x\d{1,2}|\h{1,2}(?!\h)\b|0[0-7]{0,2}(?![0-7])\b[^x0MC])|(\\[MC]-)+\w|[^\s\\])}, Str::Other
+
+        BRACES.each do |_, _, name|
+          mixin :"braces_#{name}"
+        end
+      end
+
+      BRACES.each do |lbrace, rbrace, name|
+        state :"braces_#{name}" do
+          rule /%[a-z]#{lbrace}/, Str::Double, :"braces_#{name}_intp"
+          rule /%[A-Z]#{lbrace}/, Str::Double, :"braces_#{name}_no_intp"
+        end
+
+        state :"braces_#{name}_intp" do
+          rule /#{rbrace}[a-z]*/, Str::Double, :pop!
+          mixin :enddoublestr
+        end
+
+        state :"braces_#{name}_no_intp" do
+          rule /.*#{rbrace}[a-z]*/, Str::Double, :pop!
+        end
+      end
+
+      state :dqs do
+        rule /"/, Str::Double, :pop!
+        mixin :enddoublestr
+      end
+
+      state :interpoling do
+        rule /#\{/, Str::Interpol, :interpoling_string
+      end
+
+      state :interpoling_string do
+        rule /\}/, Str::Interpol, :pop!
+        mixin :root
+      end
+
+      state :interpoling_symbol do
+        rule /"/, Str::Symbol, :pop!
+        mixin :interpoling
+        rule /[^#"]+/, Str::Symbol
+      end
+
+      state :enddoublestr do
+        mixin :interpoling
+        rule /[^#"]+/, Str::Double
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/erb.rb b/app/server/vendor/rouge/lib/rouge/lexers/erb.rb
new file mode 100755
index 0000000..d85ddc5
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/erb.rb
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class ERB < TemplateLexer
+      desc "Embedded ruby template files"
+
+      tag 'erb'
+      aliases 'eruby', 'rhtml'
+
+      filenames '*.erb', '*.erubis', '*.rhtml', '*.eruby'
+
+      def self.analyze_text(text)
+        return 0.4 if text =~ /<%.*%>/
+      end
+
+      def initialize(opts={})
+        @ruby_lexer = Ruby.new(opts)
+
+        super(opts)
+      end
+
+      start do
+        parent.reset!
+        @ruby_lexer.reset!
+      end
+
+      open  = /<%%|<%=|<%#|<%-|<%/
+      close = /%%>|-%>|%>/
+
+      state :root do
+        rule /<%#/, Comment, :comment
+
+        rule open, Comment::Preproc, :ruby
+
+        rule /.+?(?=#{open})|.+/m do
+          delegate parent
+        end
+      end
+
+      state :comment do
+        rule close, Comment, :pop!
+        rule /.+(?=#{close})|.+/m, Comment
+      end
+
+      state :ruby do
+        rule close, Comment::Preproc, :pop!
+
+        rule /.+?(?=#{close})|.+/m do
+          delegate @ruby_lexer
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/erlang.rb b/app/server/vendor/rouge/lib/rouge/lexers/erlang.rb
new file mode 100755
index 0000000..b194ea7
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/erlang.rb
@@ -0,0 +1,117 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Erlang < RegexLexer
+      desc "The Erlang programming language (erlang.org)"
+      tag 'erlang'
+      aliases 'erl'
+      filenames '*.erl', '*.hrl'
+
+      mimetypes 'text/x-erlang', 'application/x-erlang'
+
+      def self.analyze_text(text)
+        return 0.3 if text =~ /^-module[(]\w+[)][.]/
+      end
+
+      keywords = %w(
+        after begin case catch cond end fun if
+        let of query receive try when
+      )
+
+      builtins = %w(
+        abs append_element apply atom_to_list binary_to_list
+        bitstring_to_list binary_to_term bit_size bump_reductions
+        byte_size cancel_timer check_process_code delete_module
+        demonitor disconnect_node display element erase exit
+        float float_to_list fun_info fun_to_list
+        function_exported garbage_collect get get_keys
+        group_leader hash hd integer_to_list iolist_to_binary
+        iolist_size is_atom is_binary is_bitstring is_boolean
+        is_builtin is_float is_function is_integer is_list
+        is_number is_pid is_port is_process_alive is_record
+        is_reference is_tuple length link list_to_atom
+        list_to_binary list_to_bitstring list_to_existing_atom
+        list_to_float list_to_integer list_to_pid list_to_tuple
+        load_module localtime_to_universaltime make_tuple md5
+        md5_final md5_update memory module_loaded monitor
+        monitor_node node nodes open_port phash phash2
+        pid_to_list port_close port_command port_connect
+        port_control port_call port_info port_to_list
+        process_display process_flag process_info purge_module
+        put read_timer ref_to_list register resume_process
+        round send send_after send_nosuspend set_cookie
+        setelement size spawn spawn_link spawn_monitor
+        spawn_opt split_binary start_timer statistics
+        suspend_process system_flag system_info system_monitor
+        system_profile term_to_binary tl trace trace_delivered
+        trace_info trace_pattern trunc tuple_size tuple_to_list
+        universaltime_to_localtime unlink unregister whereis
+      )
+
+      operators = %r{(\+\+?|--?|\*|/|<|>|/=|=:=|=/=|=<|>=|==?|<-|!|\?)}
+      word_operators = %w(
+        and andalso band bnot bor bsl bsr bxor
+        div not or orelse rem xor
+      )
+
+      atom_re = %r{(?:[a-z][a-zA-Z0-9_]*|'[^\n']*[^\\]')}
+
+      variable_re = %r{(?:[A-Z_][a-zA-Z0-9_]*)}
+
+      escape_re = %r{(?:\\(?:[bdefnrstv\'"\\/]|[0-7][0-7]?[0-7]?|\^[a-zA-Z]))}
+
+      macro_re = %r{(?:#{variable_re}|#{atom_re})}
+
+      base_re = %r{(?:[2-9]|[12][0-9]|3[0-6])}
+
+      state :root do
+        rule(/\s+/, Text)
+        rule(/%.*\n/, Comment)
+        rule(%r{(#{keywords.join('|')})\b}, Keyword)
+        rule(%r{(#{builtins.join('|')})\b}, Name::Builtin)
+        rule(%r{(#{word_operators.join('|')})\b}, Operator::Word)
+        rule(/^-/, Punctuation, :directive)
+        rule(operators, Operator)
+        rule(/"/, Str, :string)
+        rule(/<</, Name::Label)
+        rule(/>>/, Name::Label)
+        rule %r{(#{atom_re})(:)} do
+          groups Name::Namespace, Punctuation
+        end
+        rule %r{(?:^|(?<=:))(#{atom_re})(\s*)(\()} do
+          groups Name::Function, Text, Punctuation
+        end
+        rule(%r{[+-]?#{base_re}#[0-9a-zA-Z]+}, Num::Integer)
+        rule(/[+-]?\d+/, Num::Integer)
+        rule(/[+-]?\d+.\d+/, Num::Float)
+        rule(%r{[\]\[:_@\".{}()|;,]}, Punctuation)
+        rule(variable_re, Name::Variable)
+        rule(atom_re, Name)
+        rule(%r{\?#{macro_re}}, Name::Constant)
+        rule(%r{\$(?:#{escape_re}|\\[ %]|[^\\])}, Str::Char)
+        rule(%r{##{atom_re}(:?\.#{atom_re})?}, Name::Label)
+      end
+
+      state :string do
+        rule(escape_re, Str::Escape)
+        rule(/"/, Str, :pop!)
+        rule(%r{~[0-9.*]*[~#+bBcdefginpPswWxX]}, Str::Interpol)
+        rule(%r{[^"\\~]+}, Str)
+        rule(/~/, Str)
+      end
+
+      state :directive do
+        rule %r{(define)(\s*)(\()(#{macro_re})} do
+          groups Name::Entity, Text, Punctuation, Name::Constant
+          pop!
+        end
+        rule %r{(record)(\s*)(\()(#{macro_re})} do
+          groups Name::Entity, Text, Punctuation, Name::Label
+          pop!
+        end
+        rule(atom_re, Name::Entity, :pop!)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/factor.rb b/app/server/vendor/rouge/lib/rouge/lexers/factor.rb
new file mode 100755
index 0000000..e2fdbd6
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/factor.rb
@@ -0,0 +1,301 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Factor < RegexLexer
+      desc "Factor, the practical stack language (factorcode.org)"
+      tag 'factor'
+      filenames '*.factor'
+      mimetypes 'text/x-factor'
+
+      def self.analyze_text(text)
+        return 1 if text.shebang? 'factor'
+      end
+
+      def self.builtins
+        @builtins ||= {}.tap do |builtins|
+          builtins[:kernel] = Set.new %w(
+            or 2bi 2tri while wrapper nip 4dip wrapper? bi*
+            callstack>array both? hashcode die dupd callstack
+            callstack? 3dup tri@ pick curry build ?execute 3bi prepose
+            >boolean if clone eq? tri* ? = swapd 2over 2keep 3keep clear
+            2dup when not tuple? dup 2bi* 2tri* call tri-curry object bi@
+            do unless* if* loop bi-curry* drop when* assert= retainstack
+            assert? -rot execute 2bi@ 2tri@ boa with either? 3drop bi
+            curry?  datastack until 3dip over 3curry tri-curry* tri-curry@
+            swap and 2nip throw bi-curry (clone) hashcode* compose 2dip if
+            3tri unless compose? tuple keep 2curry equal? assert tri 2drop
+            most <wrapper> boolean? identity-hashcode identity-tuple?
+            null new dip bi-curry@ rot xor identity-tuple boolean
+          )
+
+          builtins[:assocs] = Set.new %w(
+            ?at assoc? assoc-clone-like assoc= delete-at* assoc-partition
+            extract-keys new-assoc value? assoc-size map>assoc push-at
+            assoc-like key? assoc-intersect assoc-refine update
+            assoc-union assoc-combine at* assoc-empty? at+ set-at
+            assoc-all? assoc-subset?  assoc-hashcode change-at assoc-each
+            assoc-diff zip values value-at rename-at inc-at enum? at cache
+            assoc>map <enum> assoc assoc-map enum value-at* assoc-map-as
+            >alist assoc-filter-as clear-assoc assoc-stack maybe-set-at
+            substitute assoc-filter 2cache delete-at assoc-find keys
+            assoc-any? unzip
+          )
+
+          builtins[:combinators] = Set.new %w(
+            case execute-effect no-cond no-case? 3cleave>quot 2cleave
+            cond>quot wrong-values? no-cond? cleave>quot no-case case>quot
+            3cleave wrong-values to-fixed-point alist>quot case-find
+            cond cleave call-effect 2cleave>quot recursive-hashcode
+            linear-case-quot spread spread>quot
+          )
+
+          builtins[:math] = Set.new %w(
+            number= if-zero next-power-of-2 each-integer ?1+
+            fp-special? imaginary-part unless-zero float>bits number?
+            fp-infinity? bignum? fp-snan? denominator fp-bitwise= *
+            + power-of-2? - u>= / >= bitand log2-expects-positive <
+            log2 > integer? number bits>double 2/ zero? (find-integer)
+            bits>float float? shift ratio? even? ratio fp-sign bitnot
+            >fixnum complex? /i /f byte-array>bignum when-zero sgn >bignum
+            next-float u< u> mod recip rational find-last-integer >float
+            (all-integers?) 2^ times integer fixnum? neg fixnum sq bignum
+            (each-integer) bit? fp-qnan? find-integer complex <fp-nan>
+            real double>bits bitor rem fp-nan-payload all-integers?
+            real-part log2-expects-positive? prev-float align unordered?
+            float fp-nan? abs bitxor u<= odd? <= /mod rational? >integer
+            real? numerator
+          )
+
+          builtins[:sequences] = Set.new %w(
+            member-eq? append assert-sequence= find-last-from
+            trim-head-slice clone-like 3sequence assert-sequence? map-as
+            last-index-from reversed index-from cut* pad-tail
+            remove-eq! concat-as but-last snip trim-tail nths
+            nth 2selector sequence slice?  <slice> partition
+            remove-nth tail-slice empty? tail* if-empty
+            find-from virtual-sequence? member? set-length
+            drop-prefix unclip unclip-last-slice iota map-sum
+            bounds-error? sequence-hashcode-step selector-for
+            accumulate-as map start midpoint@ (accumulate) rest-slice
+            prepend fourth sift accumulate! new-sequence follow map! like
+            first4 1sequence reverse slice unless-empty padding virtual@
+            repetition? set-last index 4sequence max-length set-second
+            immutable-sequence first2 first3 replicate-as reduce-index
+            unclip-slice supremum suffix! insert-nth trim-tail-slice
+            tail 3append short count suffix concat flip filter sum
+            immutable? reverse! 2sequence map-integers delete-all start*
+            indices snip-slice check-slice sequence?  head map-find
+            filter! append-as reduce sequence= halves collapse-slice
+            interleave 2map filter-as binary-reduce slice-error? product
+            bounds-check? bounds-check harvest immutable virtual-exemplar
+            find produce remove pad-head last replicate set-fourth
+            remove-eq shorten reversed?  map-find-last 3map-as
+            2unclip-slice shorter? 3map find-last head-slice pop* 2map-as
+            tail-slice* but-last-slice 2map-reduce iota? collector-for
+            accumulate each selector append! new-resizable cut-slice
+            each-index head-slice* 2reverse-each sequence-hashcode
+            pop set-nth ?nth <flat-slice> second join when-empty
+            collector immutable-sequence? <reversed> all? 3append-as
+            virtual-sequence subseq? remove-nth! push-either new-like
+            length last-index push-if 2all? lengthen assert-sequence
+            copy map-reduce move third first 3each tail? set-first prefix
+            bounds-error any? <repetition> trim-slice exchange surround
+            2reduce cut change-nth min-length set-third produce-as
+            push-all head? delete-slice rest sum-lengths 2each head*
+            infimum remove! glue slice-error subseq trim replace-slice
+            push repetition map-index trim-head unclip-last mismatch
+          )
+
+          builtins[:namespaces] = Set.new %w(
+            global +@ change set-namestack change-global init-namespaces
+            on off set-global namespace set with-scope bind with-variable
+            inc dec counter initialize namestack get get-global make-assoc
+          )
+
+          builtins[:arrays] = Set.new %w(
+            <array> 2array 3array pair >array 1array 4array pair?
+            array resize-array array?
+          )
+
+          builtins[:io] = Set.new %w(
+            +character+ bad-seek-type? readln each-morsel
+            stream-seek read print with-output-stream contents
+            write1 stream-write1 stream-copy stream-element-type
+            with-input-stream stream-print stream-read stream-contents
+            stream-tell tell-output bl seek-output bad-seek-type nl
+            stream-nl write flush stream-lines +byte+ stream-flush
+            read1 seek-absolute? stream-read1 lines stream-readln
+            stream-read-until each-line seek-end with-output-stream*
+            seek-absolute with-streams seek-input seek-relative?
+            input-stream stream-write read-partial seek-end?
+            seek-relative error-stream read-until with-input-stream*
+            with-streams* tell-input each-block output-stream
+            stream-read-partial each-stream-block each-stream-line
+          )
+
+          builtins[:strings] = Set.new %w(
+            resize-string >string <string> 1string string string?
+          )
+
+          builtins[:vectors] = Set.new %w(
+            with-return restarts return-continuation with-datastack
+            recover rethrow-restarts <restart> ifcc set-catchstack
+            >continuation< cleanup ignore-errors restart?
+            compute-restarts attempt-all-error error-thread
+            continue <continuation> attempt-all-error? condition?
+            <condition> throw-restarts error catchstack continue-with
+            thread-error-hook continuation rethrow callcc1
+            error-continuation callcc0 attempt-all condition
+            continuation? restart return
+          )
+
+          builtins[:continuations] = Set.new %w(
+            with-return restarts return-continuation with-datastack
+            recover rethrow-restarts <restart> ifcc set-catchstack
+            >continuation< cleanup ignore-errors restart?
+            compute-restarts attempt-all-error error-thread
+            continue <continuation> attempt-all-error? condition?
+            <condition> throw-restarts error catchstack continue-with
+            thread-error-hook continuation rethrow callcc1
+            error-continuation callcc0 attempt-all condition
+            continuation? restart return
+          )
+        end
+      end
+
+      state :root do
+        rule /\s+/m, Text
+
+        rule /(:|::|MACRO:|MEMO:|GENERIC:|HELP:)(\s+)(\S+)/m do
+          groups Keyword, Text, Name::Function
+        end
+
+        rule /(M:|HOOK:|GENERIC#)(\s+)(\S+)(\s+)(\S+)/m do
+          groups Keyword, Text, Name::Class, Text, Name::Function
+        end
+
+        rule /\((?=\s)/, Name::Function, :stack_effect
+        rule /;(?=\s)/, Keyword
+
+        rule /(USING:)((?:\s|\\\s)+)/m do
+          groups Keyword::Namespace, Text
+          push :import
+        end
+
+        rule /(IN:|USE:|UNUSE:|QUALIFIED:|QUALIFIED-WITH:)(\s+)(\S+)/m do
+          groups Keyword::Namespace, Text, Name::Namespace
+        end
+
+        rule /(FROM:|EXCLUDE:)(\s+)(\S+)(\s+)(=>)/m do
+          groups Keyword::Namespace, Text, Name::Namespace, Text, Punctuation
+        end
+
+        rule /(?:ALIAS|DEFER|FORGET|POSTPONE):/, Keyword::Namespace
+
+        rule /(TUPLE:)(\s+)(\S+)(\s+)(<)(\s+)(\S+)/m do
+          groups(
+            Keyword, Text,
+            Name::Class, Text,
+            Punctuation, Text,
+            Name::Class
+          )
+          push :slots
+        end
+
+        rule /(TUPLE:)(\s+)(\S+)/m do
+          groups Keyword, Text, Name::Class
+          push :slots
+        end
+
+        rule /(UNION:|INTERSECTION:)(\s+)(\S+)/m do
+          groups Keyword, Text, Name::Class
+        end
+
+        rule /(PREDICATE:)(\s+)(\S+)(\s+)(<)(\s+)(\S+)/m do
+          groups(
+            Keyword, Text,
+            Name::Class, Text,
+            Punctuation, Text,
+            Name::Class
+          )
+        end
+
+        rule /(C:)(\s+)(\S+)(\s+)(\S+)/m do
+          groups(
+            Keyword, Text,
+            Name::Function, Text,
+            Name::Class
+          )
+        end
+
+        rule %r(
+          (INSTANCE|SLOT|MIXIN|SINGLETONS?|CONSTANT|SYMBOLS?|ERROR|SYNTAX
+           |ALIEN|TYPEDEF|FUNCTION|STRUCT):
+        )x, Keyword
+
+        rule /(?:<PRIVATE|PRIVATE>)/, Keyword::Namespace
+
+        rule /(MAIN:)(\s+)(\S+)/ do
+          groups Keyword::Namespace, Text, Name::Function
+        end
+
+        # strings
+        rule /"""\s+.*?\s+"""/, Str
+        rule /"(\\.|[^\\])*?"/, Str
+        rule /(CHAR:)(\s+)(\\[\\abfnrstv]*|\S)(?=\s)/, Str::Char
+
+        # comments
+        rule /!\s+.*$/, Comment
+        rule /#!\s+.*$/, Comment
+
+        # booleans
+        rule /[tf](?=\s)/, Name::Constant
+
+        # numbers
+        rule /-?\d+\.\d+(?=\s)/, Num::Float
+        rule /-?\d+(?=\s)/, Num::Integer
+
+        rule /HEX:\s+[a-fA-F\d]+(?=\s)/m, Num::Hex
+        rule /BIN:\s+[01]+(?=\s)/, Num::Bin
+        rule /OCT:\s+[0-7]+(?=\s)/, Num::Oct
+
+        rule %r([-+/*=<>^](?=\s)), Operator
+
+        rule /(?:deprecated|final|foldable|flushable|inline|recursive)(?=\s)/,
+          Keyword
+
+        rule /\S+/ do |m|
+          name = m[0]
+
+          if self.class.builtins.values.any? { |b| b.include? name }
+            token Name::Builtin
+          else
+            token Name
+          end
+        end
+      end
+
+      state :stack_effect do
+        rule /\s+/, Text
+        rule /\(/, Name::Function, :stack_effect
+        rule /\)/, Name::Function, :pop!
+
+        rule /--/, Name::Function
+        rule /\S+/, Name::Variable
+      end
+
+      state :slots do
+        rule /\s+/, Text
+        rule /;(?=\s)/, Keyword, :pop!
+        rule /\S+/, Name::Variable
+      end
+
+      state :import do
+        rule /;(?=\s)/, Keyword, :pop!
+        rule /\s+/, Text
+        rule /\S+/, Name::Namespace
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/gherkin.rb b/app/server/vendor/rouge/lib/rouge/lexers/gherkin.rb
new file mode 100755
index 0000000..d21f69e
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/gherkin.rb
@@ -0,0 +1,137 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Gherkin < RegexLexer
+      tag 'gherkin'
+      aliases 'cucumber', 'behat'
+
+      desc 'A business-readable spec DSL ( github.com/cucumber/cucumber/wiki/Gherkin )'
+
+      filenames '*.feature'
+      mimetypes 'text/x-gherkin'
+
+      def self.analyze_text(text)
+        return 1 if text.shebang? 'cucumber'
+      end
+
+      # self-modifying method that loads the keywords file
+      def self.keywords
+        load Pathname.new(__FILE__).dirname.join('gherkin/keywords.rb')
+        keywords
+      end
+
+      def self.step_regex
+        # in Gherkin's config, keywords that end in < don't
+        # need word boundaries at the ends - all others do.
+        @step_regex ||= Regexp.new(
+          keywords[:step].map do |w|
+            if w.end_with? '<'
+              Regexp.escape(w.chop)
+            else
+              "#{Regexp.escape(w)}\\b"
+            end
+          end.join('|')
+        )
+      end
+
+      rest_of_line = /.*?(?=[#\n])/
+
+      state :basic do
+        rule %r(#.*$), Comment
+        rule /[ \r\t]+/, Text
+      end
+
+      state :root do
+        mixin :basic
+        rule %r(\n), Text
+        rule %r(""".*?""")m, Str
+        rule %r(@[^\s@]+), Name::Tag
+        mixin :has_table
+        mixin :has_examples
+      end
+
+      state :has_scenarios do
+        rule %r((.*?)(:)) do |m|
+          reset_stack
+
+          keyword = m[1]
+          keyword_tok = if self.class.keywords[:element].include? keyword
+            push :description; Keyword::Namespace
+          elsif self.class.keywords[:feature].include? keyword
+            push :feature_description; Keyword::Declaration
+          elsif self.class.keywords[:examples].include? keyword
+            push :example_description; Name::Namespace
+          else
+            Error
+          end
+
+          groups keyword_tok, Punctuation
+        end
+      end
+
+      state :has_examples do
+        mixin :has_scenarios
+        rule Gherkin.step_regex, Name::Function do
+          token Name::Function
+          reset_stack; push :step
+        end
+      end
+
+      state :has_table do
+        rule(/(?=[|])/) { push :table_header }
+      end
+
+      state :table_header do
+        rule /[^|\s]+/, Name::Variable
+        rule /\n/ do
+          token Text
+          goto :table
+        end
+        mixin :table
+      end
+
+      state :table do
+        mixin :basic
+        rule /\n/, Text, :table_bol
+        rule /[|]/, Punctuation
+        rule /[^|\s]+/, Name
+      end
+
+      state :table_bol do
+        rule(/(?=\s*[^\s|])/) { reset_stack }
+        rule(//) { pop! }
+      end
+
+      state :description do
+        mixin :basic
+        mixin :has_examples
+        rule /\n/, Text
+        rule rest_of_line, Text
+      end
+
+      state :feature_description do
+        mixin :basic
+        mixin :has_scenarios
+        rule /\n/, Text
+        rule rest_of_line, Text
+      end
+
+      state :example_description do
+        mixin :basic
+        mixin :has_table
+        rule /\n/, Text
+        rule rest_of_line, Text
+      end
+
+      state :step do
+        mixin :basic
+        rule /<.*?>/, Name::Variable
+        rule /".*?"/, Str
+        rule /\S+/, Text
+        rule rest_of_line, Text, :pop!
+      end
+    end
+  end
+end
+
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/gherkin/keywords.rb b/app/server/vendor/rouge/lib/rouge/lexers/gherkin/keywords.rb
new file mode 100755
index 0000000..4f5ab35
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/gherkin/keywords.rb
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*- #
+# automatically generated by `rake builtins:gherkin`
+module Rouge
+  module Lexers
+    def Gherkin.keywords
+      @keywords ||= {}.tap do |k|
+        k[:feature] = Set.new ["Ability", "Ahoy matey!", "Arwedd", "Aspekt", "Besigheid Behoefte", "Business Need", "Caracteristica", "Característica", "Egenskab", "Egenskap", "Eiginleiki", "Feature", "Fitur", "Fonctionnalité", "Fonksyonalite", "Funcionalidade", "Funcionalitat", "Functionalitate", "Functionaliteit", "Funcţionalitate", "Funcționalitate", "Fungsi", "Funkcia", "Funkcija", "Funkcionalitāte", "Funkcionalnost", "Funkcja", "Funksie", "Funktionalität", "Funktionalitéit", "Funzionalità", "Fīča", "Hwaet", "Hwæt", "Jellemző", "Karakteristik", "Lastnost", "Mak", "Mogucnost", "Mogućnost", "Moznosti", "Možnosti", "OH HAI", "Omadus", "Ominaisuus", "Osobina", "Potrzeba biznesowa", "Požadavek", "Požiadavka", "Pretty much", "Qap", "Qu'meH 'ut", "Savybė", "Trajto", "Tính năng", "Vermoë", "Vlastnosť", "Właściwość", "Značilnost", "laH", "perbogh", "poQbogh malja'", "Özellik", "Δυνατότητα", "Λειτουργία", "Могућност", "Мөмкинлек", "Особина", "Свойство", "Функционал", "Функционалност", "Функция", "Функціонал", "Үзенчәлеклелек", "תכונה", "خاصية", "خصوصیت", "صلاحیت", "وِیژگی", "کاروبار کی ضرورت", "रूप लेख", "ਖਾਸੀਅਤ", "ਨਕਸ਼ ਨੁਹਾਰ", "ਮੁਹਾਂਦਰਾ", "గుణము", "ಹೆಚ್ಚಳ", "ความต้องการทางธุรกิจ", "ความสามารถ", "โครงหลัก", "フィーチャ", "功能", "機能", "기능"]
+        k[:element] = Set.new ["Abstract Scenario", "Abstrakt Scenario", "Achtergrond", "Aer", "Agtergrond", "All y'all", "Antecedentes", "Antecedents", "Atburðarás", "Awww, look mate", "B4", "Background", "Baggrund", "Bakgrund", "Bakgrunn", "Bakgrunnur", "Bối cảnh", "Cefndir", "Cenario", "Cenario de Fundo", "Cenário", "Cenário de Fundo", "Contesto", "Context", "Contexte", "Contexto", "Dasar", "Delineacao do Cenario", "Delineação do Cenário", "Dis is what went down", "Dyagram Senaryo", "Dyagram senaryo", "Esbozo do escenario", "Escenari", "Escenario", "Esquema de l'escenari", "Esquema del escenario", "Esquema do Cenario", "Esquema do Cenário", "First off", "Fono", "Forgatókönyv", "Forgatókönyv vázlat", "Fundo", "Geçmiş", "Grundlage", "Hannergrond", "Heave to", "Háttér", "Istorik", "Keadaan", "Khung kịch bản", "Khung tình huống", "Koncept", "Konsep skenario", "Kontekst", "Kontekstas", "Konteksts", "Kontext", "Konturo de la scenaro", "Kontèks", "Kịch bản", "Latar Belakang", "Lýsing Atburðarásar", "Lýsing Dæma", "MISHUN", "MISHUN SRSLY", "Menggariskan Senario", "Náčrt Scenára", "Náčrt Scenáru", "Náčrt Scénáře", "Oris scenarija", "Osnova", "Osnova Scenára", "Osnova scénáře", "Osnutek", "Ozadje", "Plan Senaryo", "Plan du Scénario", "Plan du scénario", "Plan senaryo", "Plang vum Szenario", "Pozadie", "Pozadina", "Pozadí", "Primer", "Raamstsenaarium", "Reckon it's like", "Rerefons", "Scenarie", "Scenarij", "Scenarijaus šablonas", "Scenarijus", "Scenario", "Scenario Amlinellol", "Scenario Outline", "Scenario Template", "Scenariomal", "Scenariomall", "Scenariu", "Scenariusz", "Scenaro", "Scenár", "Scenārijs", "Scenārijs pēc parauga", "Schema dello scenario", "Scénario", "Scénář", "Senario", "Senaryo", "Senaryo Deskripsyon", "Senaryo deskripsyon", "Senaryo taslağı", "Shiver me timbers", "Situai", "Situasie", "Situasie Uiteensetting", "Situācija", "Skenario", "Skenario konsep", "Skica", "Structura scenariu", "Structură scenariu", "Struktura scenarija", "Stsenaarium", "Swa", "Swa hwaer swa", "Swa hwær swa", "Szablon scenariusza", "Szenario", "Szenariogrundriss", "Tapaus", "Tapausaihio", "Taust", "Tausta", "Template Keadaan", "Template Senario", "Template Situai", "The thing of it is", "Tình huống", "Wharrimean is", "Yo-ho-ho", "Założenia", "lut", "lut chovnatlh", "mo'", "Ær", "Περιγραφή Σεναρίου", "Σενάριο", "Υπόβαθρο", "Кереш", "Контекст", "Концепт", "Основа", "Передумова", "Позадина", "Предистория", "Предыстория", "Пример", "Рамка на сценарий", "Скица", "Структура сценария", "Структура сценарија", "Структура сценарію", "Сценарий", "Сценарий структураси", "Сценарийның төзелеше", "Сценарио", "Сценарій", "Тарих", "רקע", "תבנית תרחיש", "תרחיש", "الخلفية", "الگوی سناریو", "زمینه", "سناریو", "سيناريو", "سيناريو مخطط", "منظر نامے کا خاکہ", "منظرنامہ", "پس منظر", "परिदृश्य", "परिदृश्य रूपरेखा", "पृष्ठभूमि", "ਪਟਕਥਾ", "ਪਟਕਥਾ ਢਾਂਚਾ", "ਪਟਕਥਾ ਰੂਪ ਰੇਖਾ", "ਪਿਛੋਕੜ", "కథనం", "నేపథ్యం", "సన్నివేశం", "ಕಥಾಸಾರಾಂಶ", "ವಿವರಣೆ", "ಹಿನ್ನೆಲೆ", "สรุปเหตุการณ์", "เหตุการณ์", "แนวคิด", "โครงสร้างของเหตุการณ์", "シナリオ", "シナリオアウトライン", "シナリオテンプレ", "シナリオテンプレート", "テンプレ", "剧本", "剧本大纲", "劇本", "劇本大綱", "场景", "场景大纲", "場景", "場景大綱", "背景", "배경", "시나리오", "시나리오 개요"]
+        k[:examples] = Set.new ["Atburðarásir", "Beispiele", "Beispiller", "Cenarios", "Cenários", "Conto", "Contoh", "Contone", "Dead men tell no tales", "Dæmi", "Dữ liệu", "EXAMPLZ", "Egzanp", "Ejemplos", "Eksempler", "Ekzemploj", "Enghreifftiau", "Esempi", "Examples", "Exempel", "Exemple", "Exemples", "Exemplos", "Juhtumid", "Paraugs", "Pavyzdžiai", "Piemēri", "Primeri", "Primjeri", "Przykłady", "Príklady", "Példák", "Příklady", "Scenarijai", "Scenariji", "Scenarios", "Se the", "Se ðe", "Se þe", "Tapaukset", "Variantai", "Voorbeelde", "Voorbeelden", "You'll wanna", "ghantoH", "lutmey", "Örnekler", "Παραδείγματα", "Σενάρια", "Мисаллар", "Мисоллар", "Приклади", "Примери", "Примеры", "Сценарији", "Үрнәкләр", "דוגמאות", "امثلة", "مثالیں", "نمونه ها", "उदाहरण", "ਉਦਾਹਰਨਾਂ", "ఉదాహరణలు", "ಉದಾಹರಣೆಗಳು", "ชุดของตัวอย่าง", "ชุดของเหตุการณ์", "サンプル", "例", "例子", "예"]
+        k[:step] = Set.new ["'a", "'ach", "'ej", "*", "7", "A", "A taktiež", "A také", "A tiež", "A zároveň", "AN", "Aber", "Ac", "Adott", "Ak", "Akkor", "Ale", "Aleshores", "Ali", "Allora", "Alors", "Als", "Ama", "Amennyiben", "Amikor", "Ampak", "An", "Ananging", "And", "And y'all", "Angenommen", "Anrhegedig a", "Apabila", "Atesa", "Atunci", "Atès", "Avast!", "Aye", "BUT", "Bagi", "Banjur", "Bet", "Biết", "Blimey!", "Buh", "But", "But at the end of the day I reckon", "But y'all", "Cal", "Cand", "Cando", "Ce", "Cho", "Cuando", "Când", "DEN", "DaH ghu' bejlu'", "Dada", "Dadas", "Dado", "Dados", "Dan", "Dann", "Dano", "Dar", "Dat fiind", "Data", "Date", "Date fiind", "Dati", "Dati fiind", "Dato", "Daţi fiind", "Dați fiind", "De", "Den youse gotta", "Dengan", "Diberi", "Diyelim ki", "Do", "Donada", "Donat", "Donitaĵo", "Dun", "Duota", "E", "Eeldades", "Ef", "En", "Entao", "Entonces", "Então", "Entón", "Epi", "Et", "Etant donné", "Etant donnée", "Etant données", "Etant donnés", "Eğer ki", "Fakat", "Gangway!", "Gdy", "Gegeben sei", "Gegeben seien", "Gegeven", "Gegewe", "Gitt", "Given", "Given y'all", "Givet", "Givun", "Ha", "I", "I CAN HAZ", "In", "Ir", "It's just unbelievable", "Ja", "Jeśli", "Jeżeli", "Kad", "Kada", "Kadar", "Kai", "Kaj", "Když", "Kemudian", "Ketika", "Keď", "Khi", "Kiedy", "Ko", "Kui", "Kuid", "Kun", "Lan", "Le", "Le sa a", "Let go and haul", "Logo", "Lorsqu'<", "Lorsque", "Lè", "Lè sa a", "Ma", "Maar", "Mais", "Majd", "Mając", "Maka", "Manawa", "Mas", "Men", "Menawa", "Mutta", "Nalika", "Nalikaning", "Nanging", "Nato", "Nhưng", "Niin", "Njuk", "När", "Når", "O zaman", "Och", "Og", "Oletetaan", "Ond", "Onda", "Oraz", "Pak", "Pero", "Però", "Podano", "Pokiaľ", "Pokud", "Potem", "Potom", "Privzeto", "Pryd", "Quan", "Quand", "Quando", "Se", "Sed", "Si", "Siis", "Sipoze", "Sipoze Ke", "Sipoze ke", "Soit", "Stel", "Så", "Tad", "Tada", "Tak", "Takrat", "Tapi", "Ter", "Tetapi", "Tha", "Tha the", "Then", "Then y'all", "Thurh", "Thì", "Toda", "Too right", "Un", "Und", "Ve", "Vendar", "Và", "WEN", "Wanneer", "Wenn", "When", "When y'all", "Wtedy", "Wun", "Y", "Y'know", "Yeah nah", "Yna", "Youse know like when", "Youse know when youse got", "Za predpokladu", "Za předpokladu", "Zadan", "Zadani", "Zadano", "Zadate", "Zadato", "Zakładając", "Zaradi", "Zatati", "a", "an", "awer", "dann", "ghu' noblu'", "latlh", "mä", "qaSDI'", "ugeholl", "vaj", "wann", "És", "Étant donné", "Étant donnée", "Étant données", "Étant donnés", "Ða", "Ða ðe", "Ðurh", "Þa", "Þa þe", "Þegar", "Þurh", "Þá", "Če", "Şi", "Și", "Όταν", "Αλλά", "Δεδομένου", "Και", "Τότε", "І", "А", "А також", "Агар", "Але", "Али", "Аммо", "Бирок", "Ва", "Вә", "Дадено", "Дано", "Допустим", "Если", "Задате", "Задати", "Задато", "И", "К тому же", "Кад", "Када", "Когато", "Когда", "Коли", "Лекин", "Ләкин", "Нехай", "Но", "Нәтиҗәдә", "Онда", "Припустимо", "Припустимо, що", "Пусть", "Та", "Также", "То", "Тогда", "Тоді", "Унда", "Якщо", "Һәм", "Әгәр", "Әйтик", "Әмма", "אבל", "אז", "אזי", "בהינתן", "וגם", "כאשר", "آنگاه", "اذاً", "اما", "اور", "اگر", "با فرض", "بالفرض", "بفرض", "تب", "ثم", "جب", "عندما", "فرض کیا", "لكن", "لیکن", "متى", "هنگامی", "و", "پھر", "अगर", "और", "कदा", "किन्तु", "चूंकि", "जब", "तथा", "तदा", "तब", "पर", "परन्तु", "यदि", "ਅਤੇ", "ਜਦੋਂ", "ਜਿਵੇਂ ਕਿ", "ਜੇਕਰ", "ਤਦ", "ਪਰ", "అప్పుడు", "ఈ పరిస్థితిలో", "కాని", "చెప్పబడినది", "మరియు", "ಆದರೆ", "ನಂತರ", "ನೀಡಿದ", "ಮತ್ತು", "ಸ್ಥಿತಿಯನ್ನು", "กำหนดให้", "ดังนั้น", "เมื่อ", "แต่", "และ", "かつ<", "しかし<", "ただし<", "ならば<", "もし<", "並且<", "但し<", "但是<", "假如<", "假定<", "假設<", "假设<", "前提<", "同时<", "同時<", "并且<", "当<", "當<", "而且<", "那么<", "那麼<", "그러면<", "그리고<", "단<", "만약<", "만일<", "먼저<", "조건<", "하지만<"]
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/go.rb b/app/server/vendor/rouge/lib/rouge/lexers/go.rb
new file mode 100755
index 0000000..ed38b68
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/go.rb
@@ -0,0 +1,177 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Go < RegexLexer
+      desc 'The Go programming language (http://golang.org)'
+      tag 'go'
+      aliases 'go', 'golang'
+      filenames '*.go'
+
+      mimetypes 'text/x-go', 'application/x-go'
+
+      def self.analyze_text(text)
+        return 0
+      end
+
+      # Characters
+
+      WHITE_SPACE            = /[\s\t\r\n]+/
+
+      NEWLINE                = /\n/
+      UNICODE_CHAR           = /[^\n]/
+      UNICODE_LETTER         = /[[:alpha:]]/
+      UNICODE_DIGIT          = /[[:digit:]]/
+
+      # Letters and digits
+
+      LETTER                 = /#{UNICODE_LETTER}|_/
+      DECIMAL_DIGIT          = /[0-9]/
+      OCTAL_DIGIT            = /[0-7]/
+      HEX_DIGIT              = /[0-9A-Fa-f]/
+
+      # Comments
+
+      LINE_COMMENT           = /\/\/(?:(?!#{NEWLINE}).)*/
+      GENERAL_COMMENT        = /\/\*(?:(?!\*\/).)*\*\//m
+      COMMENT                = /#{LINE_COMMENT}|#{GENERAL_COMMENT}/
+
+      # Keywords
+
+      KEYWORD                = /\b(?:
+                                 break       | default     | func
+                               | interface   | select      | case
+                               | defer       | go          | map
+                               | struct      | chan        | else
+                               | goto        | package     | switch
+                               | const       | fallthrough | if
+                               | range       | type        | continue
+                               | for         | import      | return
+                               | var
+                               )\b/x
+
+      # Identifiers
+
+      IDENTIFIER             = / (?!#{KEYWORD})
+                                 #{LETTER}(?:#{LETTER}|#{UNICODE_DIGIT})* /x
+
+      # Operators and delimiters
+
+      OPERATOR               = / \+=    | \+\+   | \+     | &\^=   | &\^
+                               | &=     | &&     | &      | ==     | =
+                               | \!=    | \!     | -=     | --     | -
+                               | \|=    | \|\|   | \|     | <=     | <-
+                               | <<=    | <<     | <      | \*=    | \*
+                               | \^=    | \^     | >>=    | >>     | >=
+                               | >      | \/     | \/=    | :=     | %
+                               | %=     | \.\.\. | \.     | :
+                               /x
+
+      SEPARATOR              = / \(     | \)     | \[     | \]     | \{
+                               | \}     | ,      | ;
+                               /x
+
+      # Integer literals
+
+      DECIMAL_LIT            = /[0-9]#{DECIMAL_DIGIT}*/
+      OCTAL_LIT              = /0#{OCTAL_DIGIT}*/
+      HEX_LIT                = /0[xX]#{HEX_DIGIT}+/
+      INT_LIT                = /#{HEX_LIT}|#{DECIMAL_LIT}|#{OCTAL_LIT}/
+
+      # Floating-point literals
+
+      DECIMALS               = /#{DECIMAL_DIGIT}+/
+      EXPONENT               = /[eE][+\-]?#{DECIMALS}/
+      FLOAT_LIT              = / #{DECIMALS} \. #{DECIMALS}? #{EXPONENT}?
+                               | #{DECIMALS} #{EXPONENT}
+                               | \. #{DECIMALS} #{EXPONENT}?
+                               /x
+
+      # Imaginary literals
+
+      IMAGINARY_LIT          = /(?:#{DECIMALS}|#{FLOAT_LIT})i/
+
+      # Rune literals
+
+      ESCAPED_CHAR           = /\\[abfnrtv\\'"]/
+      LITTLE_U_VALUE         = /\\u#{HEX_DIGIT}{4}/
+      BIG_U_VALUE            = /\\U#{HEX_DIGIT}{8}/
+      UNICODE_VALUE          = / #{UNICODE_CHAR} | #{LITTLE_U_VALUE}
+                               | #{BIG_U_VALUE}  | #{ESCAPED_CHAR}
+                               /x
+      OCTAL_BYTE_VALUE       = /\\#{OCTAL_DIGIT}{3}/
+      HEX_BYTE_VALUE         = /\\x#{HEX_DIGIT}{2}/
+      BYTE_VALUE             = /#{OCTAL_BYTE_VALUE}|#{HEX_BYTE_VALUE}/
+      CHAR_LIT               = /'(?:#{UNICODE_VALUE}|#{BYTE_VALUE})'/
+      ESCAPE_SEQUENCE        = / #{ESCAPED_CHAR}
+                               | #{LITTLE_U_VALUE}
+                               | #{BIG_U_VALUE}
+                               | #{HEX_BYTE_VALUE}
+                               /x
+
+      # String literals
+
+      RAW_STRING_LIT         = /`(?:#{UNICODE_CHAR}|#{NEWLINE})*`/
+      INTERPRETED_STRING_LIT = / "(?: (?!")
+                                      (?: #{UNICODE_VALUE} | #{BYTE_VALUE} )
+                                  )*" /x
+      STRING_LIT             = /#{RAW_STRING_LIT}|#{INTERPRETED_STRING_LIT}/
+
+      # Predeclared identifiers
+
+      PREDECLARED_TYPES      = /\b(?:
+                                 bool       | byte       | complex64
+                               | complex128 | error      | float32
+                               | float64    | int8       | int16
+                               | int32      | int64      | int
+                               | rune       | string     | uint8
+                               | uint16     | uint32     | uint64
+                               | uintptr    | uint
+      	                       )\b/x
+
+      PREDECLARED_CONSTANTS  = /\b(?:true|false|iota|nil)\b/
+
+      PREDECLARED_FUNCTIONS  = /\b(?:
+                                 append  | cap     | close   | complex
+                               | copy    | delete  | imag    | len
+                               | make    | new     | panic   | print
+                               | println | real    | recover
+                               )\b/x
+
+      state :simple_tokens do
+        rule(COMMENT,               Comment)
+        rule(KEYWORD,               Keyword)
+        rule(PREDECLARED_TYPES,     Keyword::Type)
+        rule(PREDECLARED_FUNCTIONS, Name::Builtin)
+        rule(PREDECLARED_CONSTANTS, Name::Constant)
+        rule(IMAGINARY_LIT,         Num)
+        rule(FLOAT_LIT,             Num)
+        rule(INT_LIT,               Num)
+        rule(CHAR_LIT,              Str::Char)
+        rule(OPERATOR,              Operator)
+        rule(SEPARATOR,             Punctuation)
+        rule(IDENTIFIER,            Name)
+        rule(WHITE_SPACE,           Other)
+      end
+
+      state :root do
+        mixin :simple_tokens
+
+        rule(/`/,             Str, :raw_string)
+        rule(/"/,             Str, :interpreted_string)
+      end
+
+      state :interpreted_string do
+        rule(ESCAPE_SEQUENCE, Str::Escape)
+        rule(/\\./,           Error)
+        rule(/"/,             Str, :pop!)
+        rule(/[^"\\]+/,       Str)
+      end
+
+      state :raw_string do
+        rule(/`/,             Str, :pop!)
+        rule(/[^`]+/m,        Str)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/groovy.rb b/app/server/vendor/rouge/lib/rouge/lexers/groovy.rb
new file mode 100755
index 0000000..b8a4ba0
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/groovy.rb
@@ -0,0 +1,103 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Groovy < RegexLexer
+      desc 'The Groovy programming language (groovy.codehaus.org)'
+      tag 'groovy'
+      filenames '*.groovy'
+      mimetypes 'text/x-groovy'
+
+      ws = %r((?:\s|//.*?\n|/[*].*?[*]/)+)
+
+      def self.keywords
+        @keywords ||= Set.new %w(
+          assert break case catch continue default do else finally for
+          if goto instanceof new return switch this throw try while in as
+        )
+      end
+
+      def self.declarations
+        @declarations ||= Set.new %w(
+          abstract const enum extends final implements native private
+          protected public static strictfp super synchronized throws
+          transient volatile
+        )
+      end
+
+      def self.types
+        @types ||= Set.new %w(
+          def boolean byte char double float int long short void
+        )
+      end
+
+      def self.constants
+        @constants ||= Set.new %w(true false null)
+      end
+
+      state :root do
+        rule %r(^
+          (\s*(?:\w[\w\d.\[\]]*\s+)+?) # return arguments
+          (\w[\w\d]*) # method name
+          (\s*) (\() # signature start
+        )x do |m|
+          delegate self.clone, m[1]
+          token Name::Function, m[2]
+          token Text, m[3]
+          token Operator, m[4]
+        end
+
+        # whitespace
+        rule /[^\S\n]+/, Text
+        rule %r(//.*?\n), Comment::Single
+        rule %r(/[*].*?[*]/)m, Comment::Multiline
+        rule /@\w[\w\d.]*/, Name::Decorator
+        rule /(class|interface)\b/,  Keyword::Declaration, :class
+        rule /package\b/, Keyword::Namespace, :import
+        rule /import\b/, Keyword::Namespace, :import
+
+        rule /"(\\\\|\\"|[^"])*"/, Str::Double
+        rule /'(\\\\|\\'|[^'])*'/, Str::Single
+        rule %r(\$/((?!/\$).)*/\$), Str
+        rule %r(/(\\\\|\\"|[^/])*/), Str
+        rule /'\\.'|'[^\\]'|'\\u[0-9a-f]{4}'/, Str::Char
+        rule /(\.)([a-zA-Z_][a-zA-Z0-9_]*)/ do
+          groups Operator, Name::Attribute
+        end
+
+        rule /[a-zA-Z_][a-zA-Z0-9_]*:/, Name::Label
+        rule /[a-zA-Z_\$][a-zA-Z0-9_]*/ do |m|
+          if self.class.keywords.include? m[0]
+            token Keyword
+          elsif self.class.declarations.include? m[0]
+            token Keyword::Declaration
+          elsif self.class.types.include? m[0]
+            token Keyword::Type
+          elsif self.class.constants.include? m[0]
+            token Keyword::Constant
+          else
+            token Name
+          end
+        end
+
+        rule %r([~^*!%&\[\](){}<>\|+=:;,./?-]), Operator
+
+        # numbers
+        rule /\d+\.\d+([eE]\d+)?[fd]?/, Num::Float
+        rule /0x[0-9a-f]+/, Num::Hex
+        rule /[0-9]+L?/, Num::Integer
+        rule /\n/, Text
+      end
+
+      state :class do
+        rule /\s+/, Text
+        rule /\w[\w\d]*/, Name::Class, :pop!
+      end
+
+      state :import do
+        rule /\s+/, Text
+        rule /[\w\d.]+[*]?/, Name::Namespace, :pop!
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/haml.rb b/app/server/vendor/rouge/lib/rouge/lexers/haml.rb
new file mode 100755
index 0000000..5dfc442
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/haml.rb
@@ -0,0 +1,227 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    # A lexer for the Haml templating system for Ruby.
+    # @see http://haml.info
+    class Haml < RegexLexer
+      include Indentation
+
+      desc "The Haml templating system for Ruby (haml.info)"
+
+      tag 'haml'
+      aliases 'HAML'
+
+      filenames '*.haml'
+      mimetypes 'text/x-haml'
+
+      def self.analyze_text(text)
+        return 0.1 if text.start_with? '!!!'
+      end
+
+      # @option opts :filters
+      #   A hash of filter name to lexer of how various filters should be
+      #   highlighted.  By default, :javascript, :css, :ruby, and :erb
+      #   are supported.
+      def initialize(opts={})
+        (opts.delete(:filters) || {}).each do |name, lexer|
+          unless lexer.respond_to? :lex
+            lexer = Lexer.find(lexer) or raise "unknown lexer: #{lexer}"
+            lexer = lexer.new(options)
+          end
+
+          self.filters[name.to_s] = lexer
+        end
+
+        super(opts)
+      end
+
+      def ruby
+        @ruby ||= Ruby.new(options)
+      end
+
+      def html
+        @html ||= HTML.new(options)
+      end
+
+      def filters
+        @filters ||= {
+          'javascript' => Javascript.new(options),
+          'css' => CSS.new(options),
+          'ruby' => ruby,
+          'erb' => ERB.new(options),
+          'markdown' => Markdown.new(options),
+          # TODO
+          # 'sass' => Sass.new(options),
+          # 'textile' => Textile.new(options),
+          # 'maruku' => Maruku.new(options),
+        }
+      end
+
+      start { ruby.reset!; html.reset! }
+
+      identifier = /[\w:-]+/
+      ruby_var = /[a-z]\w*/
+
+      # Haml can include " |\n" anywhere,
+      # which is ignored and used to wrap long lines.
+      # To accomodate this, use this custom faux dot instead.
+      dot = /[ ]\|\n(?=.*[ ]\|)|./
+
+      # In certain places, a comma at the end of the line
+      # allows line wrapping as well.
+      comma_dot = /,\s*\n|#{dot}/
+
+      state :root do
+        rule /\s*\n/, Text
+        rule(/\s*/) { |m| token Text; indentation(m[0]) }
+      end
+
+      state :content do
+        mixin :css
+        rule(/%#{identifier}/) { token Name::Tag; goto :tag }
+        rule /!!!#{dot}*\n/, Name::Namespace, :pop!
+        rule %r(
+          (/) (\[#{dot}*?\]) (#{dot}*\n)
+        )x do
+          groups Comment, Comment::Special, Comment
+          pop!
+        end
+
+        rule %r(/#{dot}*\n) do
+          token Comment
+          pop!
+          starts_block :html_comment_block
+        end
+
+        rule /-##{dot}*\n/ do
+          token Comment
+          pop!
+          starts_block :haml_comment_block
+        end
+
+        rule /-/ do
+          token Punctuation
+          reset_stack
+          push :ruby_line
+        end
+
+        # filters
+        rule /:(#{dot}*)\n/ do |m|
+          token Name::Decorator
+          pop!
+          starts_block :filter_block
+
+          filter_name = m[1].strip
+
+          @filter_lexer = self.filters[filter_name]
+          @filter_lexer.reset! unless @filter_lexer.nil?
+
+          puts "    haml: filter #{filter_name.inspect} #{@filter_lexer.inspect}" if @debug
+        end
+
+        mixin :eval_or_plain
+      end
+
+      state :css do
+        rule(/\.#{identifier}/) { token Name::Class; goto :tag }
+        rule(/##{identifier}/) { token Name::Function; goto :tag }
+      end
+
+      state :tag do
+        mixin :css
+        rule(/\{#{comma_dot}*?\}/) { delegate ruby }
+        rule(/\[#{dot}*?\]/) { delegate ruby }
+        rule /\(/, Punctuation, :html_attributes
+        rule /\s*\n/, Text, :pop!
+
+        # whitespace chompers
+        rule /[<>]{1,2}(?=[ \t=])/, Punctuation
+
+        mixin :eval_or_plain
+      end
+
+      state :plain do
+        rule(/([^#\n]|#[^{\n]|(\\\\)*\\#\{)+/) { delegate html }
+        mixin :interpolation
+        rule(/\n/) { token Text; reset_stack }
+      end
+
+      state :eval_or_plain do
+        rule /[&!]?==/, Punctuation, :plain
+        rule /[&!]?[=!]/ do
+          token Punctuation
+          reset_stack
+          push :ruby_line
+        end
+
+        rule(//) { push :plain }
+      end
+
+      state :ruby_line do
+        rule /\n/, Text, :pop!
+        rule(/,[ \t]*\n/) { delegate ruby }
+        rule /[ ]\|[ \t]*\n/, Str::Escape
+        rule(/.*?(?=(,$| \|)?[ \t]*$)/) { delegate ruby }
+      end
+
+      state :html_attributes do
+        rule /\s+/, Text
+        rule /#{identifier}\s*=/, Name::Attribute, :html_attribute_value
+        rule identifier, Name::Attribute
+        rule /\)/, Text, :pop!
+      end
+
+      state :html_attribute_value do
+        rule /\s+/, Text
+        rule ruby_var, Name::Variable, :pop!
+        rule /@#{ruby_var}/, Name::Variable::Instance, :pop!
+        rule /\$#{ruby_var}/, Name::Variable::Global, :pop!
+        rule /'(\\\\|\\'|[^'\n])*'/, Str, :pop!
+        rule /"(\\\\|\\"|[^"\n])*"/, Str, :pop!
+      end
+
+      state :html_comment_block do
+        rule /#{dot}+/, Comment
+        mixin :indented_block
+      end
+
+      state :haml_comment_block do
+        rule /#{dot}+/, Comment::Preproc
+        mixin :indented_block
+      end
+
+      state :filter_block do
+        rule /([^#\n]|#[^{\n]|(\\\\)*\\#\{)+/ do
+          if @filter_lexer
+            delegate @filter_lexer
+          else
+            token Name::Decorator
+          end
+        end
+
+        mixin :interpolation
+        mixin :indented_block
+      end
+
+      state :interpolation do
+        rule /#[{]/, Str::Interpol, :ruby
+      end
+
+      state :ruby do
+        rule /[}]/, Str::Interpol, :pop!
+        mixin :ruby_inner
+      end
+
+      state :ruby_inner do
+        rule(/[{]/) { delegate ruby; push :ruby_inner }
+        rule(/[}]/) { delegate ruby; pop! }
+        rule(/[^{}]+/) { delegate ruby }
+      end
+
+      state :indented_block do
+        rule(/\n/) { token Text; reset_stack }
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/handlebars.rb b/app/server/vendor/rouge/lib/rouge/lexers/handlebars.rb
new file mode 100755
index 0000000..dcf19be
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/handlebars.rb
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Handlebars < TemplateLexer
+      desc 'the Handlebars and Mustache templating languages'
+      tag 'handlebars'
+      aliases 'hbs', 'mustache'
+      filenames '*.handlebars', '*.hbs', '*.mustache'
+      mimetypes 'text/x-handlebars', 'text/x-mustache'
+
+      id = %r([\w$-]+)
+
+      state :root do
+        # escaped slashes
+        rule(/\\{+/) { delegate parent }
+
+        # block comments
+        rule /{{!--/, Comment, :comment
+        rule /{{!.*?}}/, Comment
+
+        rule /{{{?/ do
+          token Keyword
+          push :stache
+          push :open_sym
+        end
+
+        rule(/(.+?)(?=\\|{{)/m) { delegate parent }
+
+        # if we get here, there's no more mustache tags, so we eat
+        # the rest of the doc
+        rule(/.+/m) { delegate parent }
+      end
+
+      state :comment do
+        rule(/{{/) { token Comment; push }
+        rule(/}}/) { token Comment; pop! }
+        rule(/[^{}]+/m) { token Comment }
+        rule(/[{}]/) { token Comment }
+      end
+
+      state :stache do
+        rule /}}}?/, Keyword, :pop!
+        rule /\s+/m, Text
+        rule /[=]/, Operator
+        rule /[\[\]]/, Punctuation
+        rule /[.](?=[}\s])/, Name::Variable
+        rule /[.][.]/, Name::Variable
+        rule %r([/.]), Punctuation
+        rule /"(\\.|.)*?"/, Str::Double
+        rule /'(\\.|.)*?'/, Str::Single
+        rule /\d+(?=}\s)/, Num
+        rule /(true|false)(?=[}\s])/, Keyword::Constant
+        rule /else(?=[}\s])/, Keyword
+        rule /this(?=[}\s])/, Name::Builtin::Pseudo
+        rule /@#{id}/, Name::Attribute
+        rule id, Name::Variable
+      end
+
+      state :open_sym do
+        rule %r([#/]) do
+          token Keyword
+          goto :block_name
+        end
+
+        rule /[>^&]/, Keyword
+
+        rule(//) { pop! }
+      end
+
+      state :block_name do
+        rule /if(?=[}\s])/, Keyword
+        rule id, Name::Namespace, :pop!
+        rule(//) { pop! }
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/haskell.rb b/app/server/vendor/rouge/lib/rouge/lexers/haskell.rb
new file mode 100755
index 0000000..5bef4e0
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/haskell.rb
@@ -0,0 +1,182 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Haskell < RegexLexer
+      desc "The Haskell programming language (haskell.org)"
+
+      tag 'haskell'
+      aliases 'hs'
+      filenames '*.hs'
+      mimetypes 'text/x-haskell'
+
+      def self.analyze_text(text)
+        return 1 if text.shebang?('runhaskell')
+      end
+
+      reserved = %w(
+        _ case class data default deriving do else if in
+        infix[lr]? instance let newtype of then type where
+      )
+
+      ascii = %w(
+        NUL SOH [SE]TX EOT ENQ ACK BEL BS HT LF VT FF CR S[OI] DLE
+        DC[1-4] NAK SYN ETB CAN EM SUB ESC [FGRU]S SP DEL
+      )
+
+      state :basic do
+        rule /\s+/m, Text
+        rule /{-#/, Comment::Preproc, :comment_preproc
+        rule /{-/, Comment::Multiline, :comment
+        rule /^--\s+\|.*?$/, Comment::Doc
+        # this is complicated in order to support custom symbols
+        # like -->
+        rule /--(?![!#\$\%&*+.\/<=>?@\^\|_~]).*?$/, Comment::Single
+      end
+
+      # nested commenting
+      state :comment do
+        rule /-}/, Comment::Multiline, :pop!
+        rule /{-/, Comment::Multiline, :comment
+        rule /[^-{}]+/, Comment::Multiline
+        rule /[-{}]/, Comment::Multiline
+      end
+
+      state :comment_preproc do
+        rule /-}/, Comment::Preproc, :pop!
+        rule /{-/, Comment::Preproc, :comment
+        rule /[^-{}]+/, Comment::Preproc
+        rule /[-{}]/, Comment::Preproc
+      end
+
+      state :root do
+        mixin :basic
+
+        rule /\bimport\b/, Keyword::Reserved, :import
+        rule /\bmodule\b/, Keyword::Reserved, :module
+        rule /\berror\b/, Name::Exception
+        rule /\b(?:#{reserved.join('|')})\b/, Keyword::Reserved
+        # not sure why, but ^ doesn't work here
+        # rule /^[_a-z][\w']*/, Name::Function
+        rule /[_a-z][\w']*/, Name
+        rule /[A-Z][\w']*/, Keyword::Type
+
+        # lambda operator
+        rule %r(\\(?![:!#\$\%&*+.\\/<=>?@^\|~-]+)), Name::Function
+        # special operators
+        rule %r((<-|::|->|=>|=)(?![:!#\$\%&*+.\\/<=>?@^\|~-]+)), Operator
+        # constructor/type operators
+        rule %r(:[:!#\$\%&*+.\\/<=>?@^\|~-]*), Operator
+        # other operators
+        rule %r([:!#\$\%&*+.\\/<=>?@^\|~-]+), Operator
+
+        rule /\d+e[+-]?\d+/i, Num::Float
+        rule /\d+\.\d+(e[+-]?\d+)?/i, Num::Float
+        rule /0o[0-7]+/i, Num::Oct
+        rule /0x[\da-f]+/i, Num::Hex
+        rule /\d+/, Num::Integer
+
+        rule /'/, Str::Char, :character
+        rule /"/, Str, :string
+
+        rule /\[\s*\]/, Keyword::Type
+        rule /\(\s*\)/, Name::Builtin
+        rule /[\[\](),;`{}]/, Punctuation
+      end
+
+      state :import do
+        rule /\s+/, Text
+        rule /"/, Str, :string
+        rule /\bqualified\b/, Keyword
+        # import X as Y
+        rule /([A-Z][\w.]*)(\s+)(as)(\s+)([A-Z][a-zA-Z0-9_.]*)/ do
+          groups(
+            Name::Namespace, # X
+            Text, Keyword, # as
+            Text, Name # Y
+          )
+          pop!
+        end
+
+        # import X hiding (functions)
+        rule /([A-Z][\w.]*)(\s+)(hiding)(\s+)(\()/ do
+          groups(
+            Name::Namespace, # X
+            Text, Keyword, # hiding
+            Text, Punctuation # (
+          )
+          goto :funclist
+        end
+
+        # import X (functions)
+        rule /([A-Z][\w.]*)(\s+)(\()/ do
+          groups(
+            Name::Namespace, # X
+            Text,
+            Punctuation # (
+          )
+          goto :funclist
+        end
+
+        rule /[\w.]+/, Name::Namespace, :pop!
+      end
+
+      state :module do
+        rule /\s+/, Text
+        # module Foo (functions)
+        rule /([A-Z][\w.]*)(\s+)(\()/ do
+          groups Name::Namespace, Text, Punctuation
+          push :funclist
+        end
+
+        rule /\bwhere\b/, Keyword::Reserved, :pop!
+
+        rule /[A-Z][a-zA-Z0-9_.]*/, Name::Namespace, :pop!
+      end
+
+      state :funclist do
+        mixin :basic
+        rule /[A-Z]\w*/, Keyword::Type
+        rule /(_[\w\']+|[a-z][\w\']*)/, Name::Function
+        rule /,/, Punctuation
+        rule /[:!#\$\%&*+.\\\/<=>?@^\|~-]+/, Operator
+        rule /\(/, Punctuation, :funclist
+        rule /\)/, Punctuation, :pop!
+      end
+
+      state :character do
+        rule /\\/ do
+          token Str::Escape
+          push :character_end
+          push :escape
+        end
+
+        rule /./ do
+          token Str::Char
+          goto :character_end
+        end
+      end
+
+      state :character_end do
+        rule /'/, Str::Char, :pop!
+        rule /./, Error, :pop!
+      end
+
+      state :string do
+        rule /"/, Str, :pop!
+        rule /\\/, Str::Escape, :escape
+        rule /[^\\"]+/, Str
+      end
+
+      state :escape do
+        rule /[abfnrtv"'&\\]/, Str::Escape, :pop!
+        rule /\^[\]\[A-Z@\^_]/, Str::Escape, :pop!
+        rule /#{ascii.join('|')}/, Str::Escape, :pop!
+        rule /o[0-7]+/i, Str::Escape, :pop!
+        rule /x[\da-f]/i, Str::Escape, :pop!
+        rule /\d+/, Str::Escape, :pop!
+        rule /\s+\\/, Str::Escape, :pop!
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/html.rb b/app/server/vendor/rouge/lib/rouge/lexers/html.rb
new file mode 100755
index 0000000..54d07de
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/html.rb
@@ -0,0 +1,93 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class HTML < RegexLexer
+      desc "HTML, the markup language of the web"
+      tag 'html'
+      filenames '*.htm', '*.html', '*.xhtml'
+      mimetypes 'text/html', 'application/xhtml+xml'
+
+      def self.analyze_text(text)
+        return 1 if text.doctype?(/\bhtml\b/i)
+        return 1 if text =~ /<\s*html\b/
+      end
+
+      state :root do
+        rule /[^<&]+/m, Text
+        rule /&\S*?;/, Name::Entity
+        rule /<!DOCTYPE .*?>/im, Comment::Preproc
+        rule /<!\[CDATA\[.*?\]\]>/m, Comment::Preproc
+        rule /<!--/, Comment, :comment
+        rule /<\?.*?\?>/m, Comment::Preproc # php? really?
+
+        rule /<\s*script\s*/m do
+          token Name::Tag
+          push :script_content
+          push :tag
+        end
+
+        rule /<\s*style\s*/m do
+          token Name::Tag
+          push :style_content
+          push :tag
+        end
+
+        rule %r(<\s*[a-zA-Z0-9:-]+), Name::Tag, :tag # opening tags
+        rule %r(<\s*/\s*[a-zA-Z0-9:-]+\s*>), Name::Tag # closing tags
+      end
+
+      state :comment do
+        rule /[^-]+/, Comment
+        rule /-->/, Comment, :pop!
+        rule /-/, Comment
+      end
+
+      state :tag do
+        rule /\s+/m, Text
+        rule /[a-zA-Z0-9_:-]+\s*=/m, Name::Attribute, :attr
+        rule /[a-zA-Z0-9_:-]+/, Name::Attribute
+        rule %r(/?\s*>)m, Name::Tag, :pop!
+      end
+
+      state :attr do
+        # TODO: are backslash escapes valid here?
+        rule /"/ do
+          token Str
+          goto :dq
+        end
+
+        rule /'/ do
+          token Str
+          goto :sq
+        end
+
+        rule /[^\s>]+/, Str, :pop!
+      end
+
+      state :dq do
+        rule /"/, Str, :pop!
+        rule /[^"]+/, Str
+      end
+
+      state :sq do
+        rule /'/, Str, :pop!
+        rule /[^']+/, Str
+      end
+
+      state :script_content do
+        rule %r(<\s*/\s*script\s*>)m, Name::Tag, :pop!
+        rule %r(.*?(?=<\s*/\s*script\s*>))m do
+          delegate Javascript
+        end
+      end
+
+      state :style_content do
+        rule %r(<\s*/\s*style\s*>)m, Name::Tag, :pop!
+        rule %r(.*(?=<\s*/\s*style\s*>))m do
+          delegate CSS
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/http.rb b/app/server/vendor/rouge/lib/rouge/lexers/http.rb
new file mode 100755
index 0000000..f599b75
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/http.rb
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class HTTP < RegexLexer
+      tag 'http'
+      desc 'http requests and responses'
+
+      def self.methods
+        @methods ||= %w(GET POST PUT DELETE HEAD OPTIONS TRACE)
+      end
+
+      def content_lexer
+        return Lexers::PlainText unless @content_type
+
+        @content_lexer ||= Lexer.guess_by_mimetype(@content_type)
+      rescue Lexer::AmbiguousGuess
+        @content_lexer = Lexers::PlainText
+      end
+
+      start { @content_type = 'text/plain' }
+
+      state :root do
+        # request
+        rule %r(
+          (#{HTTP.methods.join('|')})([ ]+) # method
+          ([^ ]+)([ ]+)                     # path
+          (HTTPS?)(/)(1[.][01])(\r?\n|$)  # http version
+        )ox do
+          groups(
+            Name::Function, Text,
+            Name::Namespace, Text,
+            Keyword, Operator, Num, Text
+          )
+
+          push :headers
+        end
+
+        # response
+        rule %r(
+          (HTTPS?)(/)(1[.][01])([ ]+) # http version
+          (\d{3})([ ]+)               # status
+          ([^\r\n]+)(\r?\n|$)       # status message
+        )x do
+          groups(
+            Keyword, Operator, Num, Text,
+            Num, Text,
+            Name::Exception, Text
+          )
+          push :headers
+        end
+      end
+
+      state :headers do
+        rule /([^\s:]+)( *)(:)( *)([^\r\n]+)(\r?\n|$)/ do |m|
+          key = m[1]
+          value = m[5]
+          if key.strip.downcase == 'content-type'
+            @content_type = value.split(';')[0].downcase
+          end
+
+          groups Name::Attribute, Text, Punctuation, Text, Str, Text
+        end
+
+        rule /([^\r\n]+)(\r?\n|$)/ do
+          groups Str, Text
+        end
+
+        rule /\r?\n/, Text, :content
+      end
+
+      state :content do
+        rule /.+/m do |m|
+          delegate(content_lexer)
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/ini.rb b/app/server/vendor/rouge/lib/rouge/lexers/ini.rb
new file mode 100755
index 0000000..bd5b691
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/ini.rb
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class INI < RegexLexer
+      desc 'the INI configuration format'
+      tag 'ini'
+
+      # TODO add more here
+      filenames '*.ini', '*.INI', '*.gitconfig'
+      mimetypes 'text/x-ini'
+
+      def self.analyze_text(text)
+        return 0.1 if text =~ /\A\[[\w.]+\]\s*\w+=\w+/
+      end
+
+      identifier = /[\w.]+/
+
+      state :basic do
+        rule /[;#].*?\n/, Comment
+        rule /\s+/, Text
+        rule /\\\n/, Str::Escape
+      end
+
+      state :root do
+        mixin :basic
+
+        rule /(#{identifier})(\s*)(=)/ do
+          groups Name::Property, Text, Punctuation
+          push :value
+        end
+
+        rule /\[.*?\]/, Name::Namespace
+      end
+
+      state :value do
+        rule /\n/, Text, :pop!
+        mixin :basic
+        rule /"/, Str, :dq
+        rule /'.*?'/, Str
+        mixin :esc_str
+        rule /[^\\\n]+/, Str
+      end
+
+      state :dq do
+        rule /"/, Str, :pop!
+        mixin :esc_str
+        rule /[^\\"]+/m, Str
+      end
+
+      state :esc_str do
+        rule /\\./m, Str::Escape
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/io.rb b/app/server/vendor/rouge/lib/rouge/lexers/io.rb
new file mode 100755
index 0000000..59c7ad1
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/io.rb
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class IO < RegexLexer
+      tag 'io'
+      desc 'The IO programming language (http://iolanguage.com)'
+      mimetypes 'text/x-iosrc'
+      filenames '*.io'
+
+      def self.analyze_text(text)
+        return 1 if text.shebang? 'io'
+      end
+
+      def self.constants
+        @constants ||= Set.new %w(nil false true)
+      end
+
+      def self.builtins
+        @builtins ||= Set.new %w(
+          args call clone do doFile doString else elseif for if list
+          method return super then
+        )
+      end
+
+      state :root do
+        rule /\s+/m, Text
+        rule %r(//.*?\n), Comment::Single
+        rule %r(#.*?\n), Comment::Single
+        rule %r(/(\\\n)?[*].*?[*](\\\n)?/)m, Comment::Multiline
+        rule %r(/[+]), Comment::Multiline, :nested_comment
+
+        rule /"(\\\\|\\"|[^"])*"/, Str
+
+        rule %r(:?:=), Keyword
+        rule /[()]/, Punctuation
+
+        rule %r([-=;,*+><!/|^.%&\[\]{}]), Operator
+
+        rule /[A-Z]\w*/, Name::Class
+
+        rule /[a-z_]\w*/ do |m|
+          name = m[0]
+
+          if self.class.constants.include? name
+            token Keyword::Constant
+          elsif self.class.builtins.include? name
+            token Name::Builtin
+          else
+            token Name
+          end
+        end
+
+        rule %r((\d+[.]?\d*|\d*[.]\d+)(e[+-]?[0-9]+)?)i, Num::Float
+        rule /\d+/, Num::Integer
+
+        rule /@@?/, Keyword
+      end
+
+      state :nested_comment do
+        rule %r([^/+]+)m, Comment::Multiline
+        rule %r(/[+]), Comment::Multiline, :nested_comment
+        rule %r([+]/), Comment::Multiline, :pop!
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/java.rb b/app/server/vendor/rouge/lib/rouge/lexers/java.rb
new file mode 100755
index 0000000..0b854ce
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/java.rb
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Java < RegexLexer
+      desc "The Java programming language (java.com)"
+
+      tag 'java'
+      filenames '*.java'
+      mimetypes 'text/x-java'
+
+      keywords = %w(
+        assert break case catch continue default do else finally for
+        if goto instanceof new return switch this throw try while
+      )
+
+      declarations = %w(
+        abstract const enum extends final implements native private protected
+        public static strictfp super synchronized throws transient volatile
+      )
+
+      types = %w(boolean byte char double float int long short void)
+
+      id = /[a-zA-Z_][a-zA-Z0-9_]*/
+
+      state :root do
+        rule %r(^
+          (\s*(?:[a-zA-Z_][a-zA-Z0-9_.\[\]]*\s+)+?) # return arguments
+          ([a-zA-Z_][a-zA-Z0-9_]*)                  # method name
+          (\s*)(\()                                 # signature start
+        )mx do |m|
+          # TODO: do this better, this shouldn't need a delegation
+          delegate Java, m[1]
+          token Name::Function, m[2]
+          token Text, m[3]
+          token Punctuation, m[4]
+        end
+
+        rule /\s+/, Text
+        rule %r(//.*?$), Comment::Single
+        rule %r(/\*.*?\*/)m, Comment::Multiline
+        rule /@#{id}/, Name::Decorator
+        rule /(?:#{keywords.join('|')})\b/, Keyword
+        rule /(?:#{declarations.join('|')})\b/, Keyword::Declaration
+        rule /(?:#{types.join('|')})\b/, Keyword::Type
+        rule /package\b/, Keyword::Namespace
+        rule /(?:true|false|null)\b/, Keyword::Constant
+        rule /(?:class|interface)\b/, Keyword::Declaration, :class
+        rule /import\b/, Keyword::Namespace, :import
+        rule /"(\\\\|\\"|[^"])*"/, Str
+        rule /'(?:\\.|[^\\]|\\u[0-9a-f]{4})'/, Str::Char
+        rule /(\.)(#{id})/ do
+          groups Operator, Name::Attribute
+        end
+        rule /#{id}:/, Name::Label
+        rule /\$?#{id}/, Name
+        rule /[~^*!%&\[\](){}<>\|+=:;,.\/?-]/, Operator
+        rule /[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?/, Num::Float
+        rule /0x[0-9a-f]+/, Num::Hex
+        rule /[0-9]+L?/, Num::Integer
+        # rule /\n/, Text
+      end
+
+      state :class do
+        rule /\s+/m, Text
+        rule id, Name::Class, :pop!
+      end
+
+      state :import do
+        rule /\s+/m, Text
+        rule /[a-z0-9_.]+\*?/i, Name::Namespace, :pop!
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/javascript.rb b/app/server/vendor/rouge/lib/rouge/lexers/javascript.rb
new file mode 100755
index 0000000..757e4be
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/javascript.rb
@@ -0,0 +1,257 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Javascript < RegexLexer
+      desc "JavaScript, the browser scripting language"
+
+      tag 'javascript'
+      aliases 'js'
+      filenames '*.js'
+      mimetypes 'application/javascript', 'application/x-javascript',
+                'text/javascript', 'text/x-javascript'
+
+      def self.analyze_text(text)
+        return 1 if text.shebang?('node')
+        return 1 if text.shebang?('jsc')
+        # TODO: rhino, spidermonkey, etc
+      end
+
+      state :comments_and_whitespace do
+        rule /\s+/, Text
+        rule /<!--/, Comment # really...?
+        rule %r(//.*?$), Comment::Single
+        rule %r(/\*.*?\*/)m, Comment::Multiline
+      end
+
+      state :expr_start do
+        mixin :comments_and_whitespace
+
+        rule %r(/) do
+          token Str::Regex
+          goto :regex
+        end
+
+        rule /[{]/, Punctuation, :object
+
+        rule //, Text, :pop!
+      end
+
+      state :regex do
+        rule %r(/) do
+          token Str::Regex
+          goto :regex_end
+        end
+
+        rule %r([^/]\n), Error, :pop!
+
+        rule /\n/, Error, :pop!
+        rule /\[\^/, Str::Escape, :regex_group
+        rule /\[/, Str::Escape, :regex_group
+        rule /\\./, Str::Escape
+        rule %r{[(][?][:=<!]}, Str::Escape
+        rule /[{][\d,]+[}]/, Str::Escape
+        rule /[()?]/, Str::Escape
+        rule /./, Str::Regex
+      end
+
+      state :regex_end do
+        rule /[gim]+/, Str::Regex, :pop!
+        rule(//) { pop! }
+      end
+
+      state :regex_group do
+        # specially highlight / in a group to indicate that it doesn't
+        # close the regex
+        rule /\//, Str::Escape
+
+        rule %r([^/]\n) do
+          token Error
+          pop! 2
+        end
+
+        rule /\]/, Str::Escape, :pop!
+        rule /\\./, Str::Escape
+        rule /./, Str::Regex
+      end
+
+      state :bad_regex do
+        rule /[^\n]+/, Error, :pop!
+      end
+
+      def self.keywords
+        @keywords ||= Set.new %w(
+          for in while do break return continue switch case default
+          if else throw try catch finally new delete typeof instanceof
+          void this
+        )
+      end
+
+      def self.declarations
+        @declarations ||= Set.new %w(var let with function)
+      end
+
+      def self.reserved
+        @reserved ||= Set.new %w(
+          abstract boolean byte char class const debugger double enum
+          export extends final float goto implements import int interface
+          long native package private protected public short static
+          super synchronized throws transient volatile
+        )
+      end
+
+      def self.constants
+        @constants ||= Set.new %w(true false null NaN Infinity undefined)
+      end
+
+      def self.builtins
+        @builtins ||= %w(
+          Array Boolean Date Error Function Math netscape
+          Number Object Packages RegExp String sun decodeURI
+          decodeURIComponent encodeURI encodeURIComponent
+          Error eval isFinite isNaN parseFloat parseInt document this
+          window
+        )
+      end
+
+      id = /[$a-zA-Z_][a-zA-Z0-9_]*/
+
+      state :root do
+        rule /\A\s*#!.*?\n/m, Comment::Preproc, :statement
+        rule /\n/, Text, :statement
+        rule %r((?<=\n)(?=\s|/|<!--)), Text, :expr_start
+        mixin :comments_and_whitespace
+        rule %r(\+\+ | -- | ~ | && | \|\| | \\(?=\n) | << | >>>? | ===
+               | !== )x,
+          Operator, :expr_start
+        rule %r([-<>+*%&|\^/!=]=?), Operator, :expr_start
+        rule /[(\[,]/, Punctuation, :expr_start
+        rule /;/, Punctuation, :statement
+        rule /[)\].]/, Punctuation
+
+        rule /[?]/ do
+          token Punctuation
+          push :ternary
+          push :expr_start
+        end
+
+        rule /[{}]/, Punctuation, :statement
+
+        rule id do |m|
+          if self.class.keywords.include? m[0]
+            token Keyword
+            push :expr_start
+          elsif self.class.declarations.include? m[0]
+            token Keyword::Declaration
+            push :expr_start
+          elsif self.class.reserved.include? m[0]
+            token Keyword::Reserved
+          elsif self.class.constants.include? m[0]
+            token Keyword::Constant
+          elsif self.class.builtins.include? m[0]
+            token Name::Builtin
+          else
+            token Name::Other
+          end
+        end
+
+        rule /[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?/, Num::Float
+        rule /0x[0-9a-fA-F]+/, Num::Hex
+        rule /[0-9]+/, Num::Integer
+        rule /"(\\\\|\\"|[^"])*"/, Str::Double
+        rule /'(\\\\|\\'|[^'])*'/, Str::Single
+      end
+
+      # braced parts that aren't object literals
+      state :statement do
+        rule /(#{id})(\s*)(:)/ do
+          groups Name::Label, Text, Punctuation
+        end
+
+        mixin :expr_start
+      end
+
+      # object literals
+      state :object do
+        mixin :comments_and_whitespace
+        rule /[}]/ do
+          token Punctuation
+          goto :statement
+        end
+
+        rule /(#{id})(\s*)(:)/ do
+          groups Name::Attribute, Text, Punctuation
+          push :expr_start
+        end
+
+        rule /:/, Punctuation
+        mixin :root
+      end
+
+      # ternary expressions, where <id>: is not a label!
+      state :ternary do
+        rule /:/ do
+          token Punctuation
+          goto :expr_start
+        end
+
+        mixin :root
+      end
+    end
+
+    class JSON < RegexLexer
+      desc "JavaScript Object Notation (json.org)"
+      tag 'json'
+      filenames '*.json'
+      mimetypes 'application/json'
+
+      # TODO: is this too much of a performance hit?  JSON is quite simple,
+      # so I'd think this wouldn't be too bad, but for large documents this
+      # could mean doing two full lexes.
+      def self.analyze_text(text)
+        return 0.8 if text =~ /\A\s*{/m && text.lexes_cleanly?(self)
+      end
+
+      state :root do
+        mixin :whitespace
+        # special case for empty objects
+        rule /(\{)(\s*)(\})/m do
+          groups Punctuation, Text::Whitespace, Punctuation
+        end
+        rule /(?:true|false|null)\b/, Keyword::Constant
+        rule /{/,  Punctuation, :object_key
+        rule /\[/, Punctuation, :array
+        rule /-?(?:0|[1-9]\d*)\.\d+(?:e[+-]\d+)?/i, Num::Float
+        rule /-?(?:0|[1-9]\d*)(?:e[+-]\d+)?/i, Num::Integer
+        mixin :has_string
+      end
+
+      state :whitespace do
+        rule /\s+/m, Text::Whitespace
+      end
+
+      state :has_string do
+        rule /"(\\.|[^"])*"/, Str::Double
+      end
+
+      state :object_key do
+        mixin :whitespace
+        mixin :has_string
+        rule /:/, Punctuation, :object_val
+        rule /}/, Error, :pop!
+      end
+
+      state :object_val do
+        rule /,/, Punctuation, :pop!
+        rule(/}/) { token Punctuation; pop!(2) }
+        mixin :root
+      end
+
+      state :array do
+        rule /\]/, Punctuation, :pop!
+        rule /,/, Punctuation
+        mixin :root
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/literate_coffeescript.rb b/app/server/vendor/rouge/lib/rouge/lexers/literate_coffeescript.rb
new file mode 100755
index 0000000..dfc9a8d
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/literate_coffeescript.rb
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class LiterateCoffeescript < RegexLexer
+      tag 'literate_coffeescript'
+      desc 'Literate coffeescript'
+      aliases 'litcoffee'
+      filenames '*.litcoffee'
+
+      def markdown
+        @markdown ||= Markdown.new(options)
+      end
+
+      def coffee
+        @coffee ||= Coffeescript.new(options)
+      end
+
+      start { markdown.reset!; coffee.reset! }
+
+      state :root do
+        rule /^(    .*?\n)+/m do
+          delegate coffee
+        end
+
+        rule /^([ ]{0,3}(\S.*?|)\n)*/m do
+          delegate markdown
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/literate_haskell.rb b/app/server/vendor/rouge/lib/rouge/lexers/literate_haskell.rb
new file mode 100755
index 0000000..d61c62b
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/literate_haskell.rb
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class LiterateHaskell < RegexLexer
+      desc 'Literate haskell'
+      tag 'literate_haskell'
+      aliases 'lithaskell', 'lhaskell', 'lhs'
+      filenames '*.lhs'
+      mimetypes 'text/x-literate-haskell'
+
+      def haskell
+        @haskell ||= Haskell.new(options)
+      end
+
+      start { haskell.reset! }
+
+      # TODO: support TeX versions as well.
+      # TODO: enforce a blank line before and after code
+      state :root do
+        rule /\s*?\n(?=>)/, Text, :code
+        rule /.*?\n/, Text
+        rule /.+\z/, Text
+      end
+
+      state :code do
+        rule /(>)( .*?\n)/ do |m|
+          token Name::Label, m[1]
+          delegate haskell, m[2]
+        end
+
+        rule /\s*\n(?=\s*[^>])/, Text, :pop!
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/llvm.rb b/app/server/vendor/rouge/lib/rouge/lexers/llvm.rb
new file mode 100755
index 0000000..c6d9b9d
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/llvm.rb
@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class LLVM < RegexLexer
+      desc 'The LLVM Compiler Infrastructure (http://llvm.org/)'
+      tag 'llvm'
+
+      filenames '*.ll'
+      mimetypes 'text/x-llvm'
+
+      def self.analyze_text(text)
+        return 0.1 if text =~ /\A%\w+\s=\s/
+      end
+
+      string = /"[^"]*?"/
+      identifier = /([-a-zA-Z$._][-a-zA-Z$._0-9]*|#{string})/
+
+      state :basic do
+        rule /;.*?$/, Comment::Single
+        rule /\s+/, Text
+
+        rule /#{identifier}\s*:/, Name::Label
+
+        rule /@(#{identifier}|\d+)/, Name::Variable::Global
+        rule /(%|!)#{identifier}/, Name::Variable
+        rule /(%|!)\d+/, Name::Variable
+
+        rule /c?#{string}/, Str
+
+        rule /0[xX][a-fA-F0-9]+/, Num
+        rule /-?\d+(?:[.]\d+)?(?:[eE][-+]?\d+(?:[.]\d+)?)?/, Num
+
+        rule /[=<>{}\[\]()*.,!]|x/, Punctuation
+      end
+
+      builtin_types = %w(
+        void float double half x86_fp80 x86mmx fp128 ppc_fp128 label metadata
+      )
+
+      state :types do
+        rule /i[1-9]\d*/, Keyword::Type
+        rule /#{builtin_types.join('|')}/, Keyword::Type
+      end
+
+      builtin_keywords = %w(
+        begin end true false declare define global constant personality private
+        landingpad linker_private internal available_externally linkonce_odr
+        linkonce weak weak_odr appending dllimport dllexport common default
+        hidden protected extern_weak external thread_local zeroinitializer
+        undef null to tail target triple datalayout volatile nuw nsw nnan ninf
+        nsz arcp fast exact inbounds align addrspace section alias module asm
+        sideeffect gc dbg ccc fastcc coldcc x86_stdcallcc x86_fastcallcc
+        arm_apcscc arm_aapcscc arm_aapcs_vfpcc ptx_device ptx_kernel cc
+        c signext zeroext inreg sret nounwind noreturn noalias nocapture byval
+        nest readnone readonly inlinehint noinline alwaysinline optsize ssp
+        sspreq noredzone noimplicitfloat naked type opaque eq ne slt sgt sle
+        sge ult ugt ule uge oeq one olt ogt ole oge ord uno unnamed_addr ueq
+        une uwtable x
+      )
+
+      builtin_instructions = %w(
+        add fadd sub fsub mul fmul udiv sdiv fdiv urem srem frem shl lshr ashr
+        and or xor icmp fcmp phi call catch trunc zext sext fptrunc fpext
+        uitofp sitofp fptoui fptosi inttoptr ptrtoint bitcast select va_arg ret
+        br switch invoke unwind unreachable malloc alloca free load store
+        getelementptr extractelement insertelement shufflevector getresult
+        extractvalue insertvalue cleanup resume
+      )
+
+      state :keywords do
+        rule /#{builtin_instructions.join('|')}/, Keyword
+        rule /#{builtin_keywords.join('|')}/, Keyword
+      end
+
+      state :root do
+        mixin :basic
+        mixin :keywords
+        mixin :types
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/lua.rb b/app/server/vendor/rouge/lib/rouge/lexers/lua.rb
new file mode 100755
index 0000000..df7311c
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/lua.rb
@@ -0,0 +1,121 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Lua < RegexLexer
+      desc "Lua (http://www.lua.org)"
+      tag 'lua'
+      filenames '*.lua', '*.wlua'
+
+      mimetypes 'text/x-lua', 'application/x-lua'
+
+      def initialize(opts={})
+        @function_highlighting = opts.delete(:function_highlighting) { true }
+        @disabled_modules = opts.delete(:disabled_modules) { [] }
+        super(opts)
+      end
+
+      def self.analyze_text(text)
+        return 1 if text.shebang? 'lua'
+      end
+
+      def self.builtins
+        load Pathname.new(__FILE__).dirname.join('lua/builtins.rb')
+        self.builtins
+      end
+
+      def builtins
+        return [] unless @function_highlighting
+
+        @builtins ||= Set.new.tap do |builtins|
+          self.class.builtins.each do |mod, fns|
+            next if @disabled_modules.include? mod
+            builtins.merge(fns)
+          end
+        end
+      end
+
+      state :root do
+        # lua allows a file to start with a shebang
+        rule %r(#!(.*?)$), Comment::Preproc
+        rule //, Text, :base
+      end
+
+      state :base do
+        rule %r(--\[(=*)\[.*?\]\1\])m, Comment::Multiline
+        rule %r(--.*$), Comment::Single
+
+        rule %r((?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?'), Num::Float
+        rule %r((?i)\d+e[+-]?\d+), Num::Float
+        rule %r((?i)0x[0-9a-f]*), Num::Hex
+        rule %r(\d+), Num::Integer
+
+        rule %r(\n), Text
+        rule %r([^\S\n]), Text
+        # multiline strings
+        rule %r(\[(=*)\[.*?\]\1\])m, Str
+
+        rule %r((==|~=|<=|>=|\.\.\.|\.\.|[=+\-*/%^<>#])), Operator
+        rule %r([\[\]\{\}\(\)\.,:;]), Punctuation
+        rule %r((and|or|not)\b), Operator::Word
+
+        rule %r((break|do|else|elseif|end|for|if|in|repeat|return|then|until|while)\b), Keyword
+        rule %r((local)\b), Keyword::Declaration
+        rule %r((true|false|nil)\b), Keyword::Constant
+
+        rule %r((function)\b), Keyword, :function_name
+
+        rule %r([A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?) do |m|
+          name = m[0]
+          if self.builtins.include?(name)
+            token Name::Builtin
+          elsif name =~ /\./
+            a, b = name.split('.', 2)
+            token Name, a
+            token Punctuation, '.'
+            token Name, b
+          else
+            token Name
+          end
+        end
+
+        rule %r('), Str::Single, :escape_sqs
+        rule %r("), Str::Double, :escape_dqs
+      end
+
+      state :function_name do
+        rule /\s+/, Text
+        rule %r((?:([A-Za-z_][A-Za-z0-9_]*)(\.))?([A-Za-z_][A-Za-z0-9_]*)) do
+          groups Name::Class, Punctuation, Name::Function
+          pop!
+        end
+        # inline function
+        rule %r(\(), Punctuation, :pop!
+      end
+
+      state :escape_sqs do
+        mixin :string_escape
+        mixin :sqs
+      end
+
+      state :escape_dqs do
+        mixin :string_escape
+        mixin :dqs
+      end
+
+      state :string_escape do
+        rule %r(\\([abfnrtv\\"']|\d{1,3})), Str::Escape
+      end
+
+      state :sqs do
+        rule %r('), Str::Single, :pop!
+        rule %r([^']+), Str::Single
+      end
+
+      state :dqs do
+        rule %r("), Str::Double, :pop!
+        rule %r([^"]+), Str::Double
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/lua/builtins.rb b/app/server/vendor/rouge/lib/rouge/lexers/lua/builtins.rb
new file mode 100755
index 0000000..0ac1551
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/lua/builtins.rb
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*- #
+# automatically generated by `rake builtins:lua`
+module Rouge
+  module Lexers
+    class Lua
+      def self.builtins
+        @builtins ||= {}.tap do |b|
+          b["basic"] = Set.new %w(_G _VERSION assert collectgarbage dofile error getmetatable ipairs load loadfile next pairs pcall print rawequal rawget rawlen rawset select setmetatable tonumber tostring type xpcall file:close file:flush file:lines file:read file:seek file:setvbuf file:write)
+          b["modules"] = Set.new %w(require package.config package.cpath package.loaded package.loadlib package.path package.preload package.searchers package.searchpath)
+          b["bit32"] = Set.new %w(bit32.arshift bit32.band bit32.bnot bit32.bor bit32.btest bit32.bxor bit32.extract bit32.lrotate bit32.lshift bit32.replace bit32.rrotate bit32.rshift)
+          b["coroutine"] = Set.new %w(coroutine.create coroutine.resume coroutine.running coroutine.status coroutine.wrap coroutine.yield)
+          b["debug"] = Set.new %w(debug.debug debug.getuservalue debug.gethook debug.getinfo debug.getlocal debug.getmetatable debug.getregistry debug.getupvalue debug.setuservalue debug.sethook debug.setlocal debug.setmetatable debug.setupvalue debug.traceback debug.upvalueid debug.upvaluejoin)
+          b["io"] = Set.new %w(io.close io.flush io.input io.lines io.open io.output io.popen io.read io.stderr io.stdin io.stdout io.tmpfile io.type io.write)
+          b["math"] = Set.new %w(math.abs math.acos math.asin math.atan math.atan2 math.ceil math.cos math.cosh math.deg math.exp math.floor math.fmod math.frexp math.huge math.ldexp math.log math.max math.min math.modf math.pi math.pow math.rad math.random math.randomseed math.sin math.sinh math.sqrt math.tan math.tanh)
+          b["os"] = Set.new %w(os.clock os.date os.difftime os.execute os.exit os.getenv os.remove os.rename os.setlocale os.time os.tmpname)
+          b["string"] = Set.new %w(string.byte string.char string.dump string.find string.format string.gmatch string.gsub string.len string.lower string.match string.rep string.reverse string.sub string.upper)
+          b["table"] = Set.new %w(table.concat table.insert table.pack table.remove table.sort table.unpack)
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/make.rb b/app/server/vendor/rouge/lib/rouge/lexers/make.rb
new file mode 100755
index 0000000..dfa8878
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/make.rb
@@ -0,0 +1,115 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Make < RegexLexer
+      desc "Makefile syntax"
+      tag 'make'
+      aliases 'makefile', 'mf', 'gnumake', 'bsdmake'
+      filenames '*.make', 'Makefile', 'makefile', 'Makefile.*', 'GNUmakefile'
+      mimetypes 'text/x-makefile'
+
+      def self.analyze_text(text)
+        return 0.6 if text =~ /^\.PHONY:/
+      end
+
+      bsd_special = %w(
+        include undef error warning if else elif endif for endfor
+      )
+
+      gnu_special = %w(
+        ifeq ifneq ifdef ifndef else endif include -include define endef :
+      )
+
+      line = /(?:\\.|\\\n|[^\\\n])*/m
+
+      def initialize(opts={})
+        super
+        @shell = Shell.new(opts)
+      end
+
+      start { @shell.reset! }
+
+      state :root do
+        rule /\s+/, Text
+
+        rule /#.*?\n/, Comment
+
+        rule /(export)(\s+)(?=[a-zA-Z0-9_\${}\t -]+\n)/ do
+          groups Keyword, Text
+          push :export
+        end
+
+        rule /export\s+/, Keyword
+
+        # assignment
+        rule /([a-zA-Z0-9_${}.-]+)(\s*)([!?:+]?=)/m do |m|
+          token Name::Variable, m[1]
+          token Text, m[2]
+          token Operator, m[3]
+          push :shell_line
+        end
+
+        rule /"(\\\\|\\.|[^"\\])*"/, Str::Double
+        rule /'(\\\\|\\.|[^'\\])*'/, Str::Single
+        rule /([^\n:]+)(:+)([ \t]*)/ do
+          groups Name::Label, Operator, Text
+          push :block_header
+        end
+      end
+
+      state :export do
+        rule /[\w\${}-]/, Name::Variable
+        rule /\n/, Text, :pop!
+        rule /\s+/, Text
+      end
+
+      state :block_header do
+        rule /[^,\\\n#]+/, Name::Function
+        rule /,/, Punctuation
+        rule /#.*?/, Comment
+        rule /\\\n/, Text
+        rule /\\./, Text
+        rule /\n/ do
+          token Text
+          goto :block_body
+        end
+      end
+
+      state :block_body do
+        rule /(\t[\t ]*)([@-]?)/ do |m|
+          groups Text, Punctuation
+          push :shell_line
+        end
+
+        rule(//) { @shell.reset!; pop! }
+      end
+
+      state :shell do
+        # macro interpolation
+        rule /\$\(\s*[a-z_]\w*\s*\)/i, Name::Variable
+        # $(shell ...)
+        rule /(\$\()(\s*)(shell)(\s+)/m do
+          groups Name::Function, Text, Name::Builtin, Text
+          push :shell_expr
+        end
+
+        rule(/\\./m) { delegate @shell }
+        stop = /\$\(|\(|\)|\n|\\/
+        rule(/.+?(?=#{stop})/m) { delegate @shell }
+        rule(stop) { delegate @shell }
+      end
+
+      state :shell_expr do
+        rule(/\(/) { delegate @shell; push }
+        rule /\)/, Name::Variable, :pop!
+        mixin :shell
+      end
+
+      state :shell_line do
+        rule /\n/, Text, :pop!
+        mixin :shell
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/markdown.rb b/app/server/vendor/rouge/lib/rouge/lexers/markdown.rb
new file mode 100755
index 0000000..af0bfbd
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/markdown.rb
@@ -0,0 +1,153 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Markdown < RegexLexer
+      desc "Markdown, a light-weight markup language for authors"
+
+      tag 'markdown'
+      aliases 'md', 'mkd'
+      filenames '*.markdown', '*.md', '*.mkd'
+      mimetypes 'text/x-markdown'
+
+      def html
+        @html ||= HTML.new(options)
+      end
+
+      start { html.reset! }
+
+      edot = /\\.|[^\\\n]/
+
+      state :root do
+        # YAML frontmatter
+        rule(/\A(---\s*\n.*?\n?)^(---\s*$\n?)/m) { delegate YAML }
+
+        rule /\\./, Str::Escape
+
+        rule /^[\S ]+\n(?:---*)\n/, Generic::Heading
+        rule /^[\S ]+\n(?:===*)\n/, Generic::Subheading
+
+        rule /^#(?=[^#]).*?$/, Generic::Heading
+        rule /^##*.*?$/, Generic::Subheading
+
+        # TODO: syntax highlight the code block, github style
+        rule /(\n[ \t]*)(```|~~~)(.*?)(\n.*?)(\2)/m do |m|
+          sublexer = Lexer.find_fancy(m[3].strip, m[4])
+          sublexer ||= PlainText.new(:token => Str::Backtick)
+
+          token Text, m[1]
+          token Punctuation, m[2]
+          token Name::Label, m[3]
+          delegate sublexer, m[4]
+          token Punctuation, m[5]
+        end
+
+        rule /\n\n((    |\t).*?\n|\n)+/, Str::Backtick
+
+        rule /(`+)#{edot}*\1/, Str::Backtick
+
+        # various uses of * are in order of precedence
+
+        # line breaks
+        rule /^(\s*[*]){3,}\s*$/, Punctuation
+        rule /^(\s*[-]){3,}\s*$/, Punctuation
+
+        # bulleted lists
+        rule /^\s*[*+-](?=\s)/, Punctuation
+
+        # numbered lists
+        rule /^\s*\d+\./, Punctuation
+
+        # blockquotes
+        rule /^\s*>.*?$/, Generic::Traceback
+
+        # link references
+        # [foo]: bar "baz"
+        rule %r(^
+          (\s*) # leading whitespace
+          (\[) (#{edot}+?) (\]) # the reference
+          (\s*) (:) # colon
+        )x do
+          groups Text, Punctuation, Str::Symbol, Punctuation, Text, Punctuation
+
+          push :title
+          push :url
+        end
+
+        # links and images
+        rule /(!?\[)(#{edot}+?)(\])/ do
+          groups Punctuation, Name::Variable, Punctuation
+          push :link
+        end
+
+        rule /[*][*]#{edot}*?[*][*]/, Generic::Strong
+        rule /__#{edot}*?__/, Generic::Strong
+
+        rule /[*]#{edot}*?[*]/, Generic::Emph
+        rule /_#{edot}*?_/, Generic::Emph
+
+        # Automatic links
+        rule /<.*?@.+[.].+>/, Name::Variable
+        rule %r[<(https?|mailto|ftp)://#{edot}*?>], Name::Variable
+
+
+        rule /[^\\`\[*\n&<]+/, Text
+
+        # inline html
+        rule(/&\S*;/) { delegate html }
+        rule(/<#{edot}*?>/) { delegate html }
+        rule /[&<]/, Text
+
+        rule /\n/, Text
+      end
+
+      state :link do
+        rule /(\[)(#{edot}*?)(\])/ do
+          groups Punctuation, Str::Symbol, Punctuation
+          pop!
+        end
+
+        rule /[(]/ do
+          token Punctuation
+          push :inline_title
+          push :inline_url
+        end
+
+        rule /[ \t]+/, Text
+
+        rule(//) { pop! }
+      end
+
+      state :url do
+        rule /[ \t]+/, Text
+
+        # the url
+        rule /(<)(#{edot}*?)(>)/ do
+          groups Name::Tag, Str::Other, Name::Tag
+          pop!
+        end
+
+        rule /\S+/, Str::Other, :pop!
+      end
+
+      state :title do
+        rule /"#{edot}*?"/, Name::Namespace
+        rule /'#{edot}*?'/, Name::Namespace
+        rule /[(]#{edot}*?[)]/, Name::Namespace
+        rule /\s*(?=["'()])/, Text
+        rule(//) { pop! }
+      end
+
+      state :inline_title do
+        rule /[)]/, Punctuation, :pop!
+        mixin :title
+      end
+
+      state :inline_url do
+        rule /[^<\s)]+/, Str::Other, :pop!
+        rule /\s+/m, Text
+        mixin :url
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/matlab.rb b/app/server/vendor/rouge/lib/rouge/lexers/matlab.rb
new file mode 100755
index 0000000..6a599b8
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/matlab.rb
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Matlab < RegexLexer
+      desc "Matlab"
+      tag 'matlab'
+      aliases 'm'
+      filenames '*.m'
+      mimetypes 'text/x-matlab', 'application/x-matlab'
+
+      def self.analyze_text(text)
+        return 0.4 if text.match(/^\s*% /) # % comments are a dead giveaway
+      end
+
+      def self.keywords
+        @keywords = Set.new %w(
+          break case catch classdef continue else elseif end for function
+          global if otherwise parfor persistent return spmd switch try while
+        )
+      end
+
+      def self.builtins
+        load Pathname.new(__FILE__).dirname.join('matlab/builtins.rb')
+        self.builtins
+      end
+
+      state :root do
+        rule /\s+/m, Text # Whitespace
+        rule %r([{]%.*?%[}])m, Comment::Multiline
+        rule /%.*$/, Comment::Single
+        rule /([.][.][.])(.*?)$/ do
+          groups(Keyword, Comment)
+        end
+
+        rule /^(!)(.*?)(?=%|$)/ do |m|
+          token Keyword, m[1]
+          delegate Shell, m[2]
+        end
+
+
+        rule /[a-zA-Z][_a-zA-Z0-9]*/m do |m|
+          match = m[0]
+          if self.class.keywords.include? match
+            token Keyword
+          elsif self.class.builtins.include? match
+            token Name::Builtin
+          else
+            token Name
+          end
+        end
+
+        rule %r{[(){};:,\/\\\]\[]}, Punctuation
+
+        rule /~=|==|<<|>>|[-~+\/*%=<>&^|.]/, Operator
+
+
+        rule /(\d+\.\d*|\d*\.\d+)(e[+-]?[0-9]+)?/i, Num::Float
+        rule /\d+e[+-]?[0-9]+/i, Num::Float
+        rule /\d+L/, Num::Integer::Long
+        rule /\d+/, Num::Integer
+
+        rule /'/, Str::Single, :string
+      end
+
+      state :string do
+        rule /[^']+/, Str::Single
+        rule /''/, Str::Escape
+        rule /'/, Str::Single, :pop!
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/matlab/builtins.rb b/app/server/vendor/rouge/lib/rouge/lexers/matlab/builtins.rb
new file mode 100755
index 0000000..3b78998
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/matlab/builtins.rb
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*- #
+# automatically generated by `rake builtins:matlab`
+module Rouge
+  module Lexers
+    class Matlab
+      def self.builtins
+        @builtins ||= Set.new %w(ans clc diary format home iskeyword more accumarray blkdiag diag eye false freqspace linspace logspace meshgrid ndgrid ones rand true zeros cat horzcat vertcat colon end ind2sub sub2ind length ndims numel size height width iscolumn isempty ismatrix isrow isscalar isvector blkdiag circshift ctranspose diag flip fliplr flipud ipermute permute repmat reshape rot90 shiftdim issorted sort sortrows squeeze transpose vectorize plus uplus minus uminus times rdivide ldivide power mtimes mrdivide mldivide mpower cumprod cumsum diff prod sum ceil fix floor idivide mod rem round relationaloperators eq ge gt le lt ne isequal isequaln logicaloperatorsshortcircuit and not or xor all any false find islogical logical true intersect ismember issorted setdiff setxor union unique join innerjoin outerjoin bitand bitcmp bitget bitor bitset bitshift bitxor swapbytes specialcharacters colon double single int8 int16 int32 int64 uint8 uint16 uint32 uint64 cast typecast isinteger isfloat isnumeric isreal isfinite isinf isnan eps flintmax inf intmax intmin nan realmax realmin blanks cellstr char iscellstr ischar sprintf strcat strjoin ischar isletter isspace isstrprop sscanf strfind strrep strsplit strtok validatestring symvar regexp regexpi regexprep regexptranslate strcmp strcmpi strncmp strncmpi blanks deblank strtrim lower upper strjust categorical iscategorical categories iscategory isordinal isprotected addcats mergecats removecats renamecats reordercats summary countcats isundefined table array2table cell2table struct2table table2array table2cell table2struct readtable writetable istable height width summary intersect ismember setdiff setxor unique union join innerjoin outerjoin sortrows stack unstack ismissing standardizemissing varfun rowfun struct fieldnames getfield isfield isstruct orderfields rmfield setfield arrayfun structfun table2struct struct2table cell2struct struct2cell cell cell2mat cell2struct cell2table celldisp cellfun cellplot cellstr iscell iscellstr mat2cell num2cell strjoin strsplit struct2cell table2cell function_handle feval func2str str2func localfunctions functions addevent delevent gettsafteratevent gettsafterevent gettsatevent gettsbeforeatevent gettsbeforeevent gettsbetweenevents gettscollection isemptytscollection lengthtscollection settscollection sizetscollection tscollection addsampletocollection addts delsamplefromcollection getabstimetscollection getsampleusingtimetscollection gettimeseriesnames horzcattscollection removets resampletscollection setabstimetscollection settimeseriesnames vertcattscollection is isa iscategorical iscell iscellstr ischar isfield isfloat ishghandle isinteger isjava islogical isnumeric isobject isreal isscalar isstr isstruct istable isvector class validateattributes whos char int2str mat2str num2str str2double str2num native2unicode unicode2native base2dec bin2dec dec2base dec2bin dec2hex hex2dec hex2num num2hex table2array table2cell table2struct array2table cell2table struct2table cell2mat cell2struct cellstr mat2cell num2cell struct2cell datenum datevec datestr now clock date calendar eomday weekday addtodate etime plus uplus minus uminus times rdivide ldivide power mtimes mrdivide mldivide mpower cumprod cumsum diff prod sum ceil fix floor idivide mod rem round sin sind asin asind sinh asinh cos cosd acos acosd cosh acosh tan tand atan atand atan2 atan2d tanh atanh csc cscd acsc acscd csch acsch sec secd asec asecd sech asech cot cotd acot acotd coth acoth hypot exp expm1 log log10 log1p log2 nextpow2 nthroot pow2 reallog realpow realsqrt sqrt abs angle complex conj cplxpair i imag isreal j real sign unwrap factor factorial gcd isprime lcm nchoosek perms primes rat rats poly polyder polyeig polyfit polyint polyval polyvalm residue roots airy besselh besseli besselj besselk bessely beta betainc betaincinv betaln ellipj ellipke erf erfc erfcinv erfcx erfinv expint gamma gammainc gammaincinv gammaln legendre psi cart2pol cart2sph pol2cart sph2cart eps flintmax i j inf pi nan isfinite isinf isnan compan gallery hadamard hankel hilb invhilb magic pascal rosser toeplitz vander wilkinson cross dot kron surfnorm tril triu transpose cond condest funm inv linsolve lscov lsqnonneg pinv rcond sylvester mldivide mrdivide chol ichol cholupdate ilu lu qr qrdelete qrinsert qrupdate planerot ldl cdf2rdf rsf2csf gsvd svd balance cdf2rdf condeig eig eigs gsvd hess ordeig ordqz ordschur poly polyeig qz rsf2csf schur sqrtm ss2tf svd svds bandwidth cond condeig det isbanded isdiag ishermitian issymmetric istril istriu norm normest null orth rank rcond rref subspace trace expm logm sqrtm bsxfun arrayfun accumarray mpower corrcoef cov max mean median min mode std var rand randn randi randperm rng interp1 pchip spline ppval mkpp unmkpp padecoef interpft interp2 interp3 interpn ndgrid meshgrid griddata griddatan fminbnd fminsearch fzero lsqnonneg optimget optimset ode45 ode15s ode23 ode113 ode23t ode23tb ode23s ode15i decic odextend odeget odeset deval bvp4c bvp5c bvpinit bvpxtend bvpget bvpset deval dde23 ddesd ddensd ddeget ddeset deval pdepe pdeval integral integral2 integral3 quadgk quad2d cumtrapz trapz polyint del2 diff gradient polyder abs angle cplxpair fft fft2 fftn fftshift fftw ifft ifft2 ifftn ifftshift nextpow2 unwrap conv conv2 convn deconv detrend filter filter2 spdiags speye sprand sprandn sprandsym sparse spconvert issparse nnz nonzeros nzmax spalloc spfun spones spparms spy find full amd colamd colperm dmperm randperm symamd symrcm condest eigs ichol ilu normest spaugment sprank svds bicg bicgstab bicgstabl cgs gmres lsqr minres pcg qmr symmlq tfqmr etree etreeplot gplot symbfact treelayout treeplot unmesh tetramesh trimesh triplot trisurf delaunay delaunayn tetramesh trimesh triplot trisurf dsearchn tsearchn delaunay delaunayn convhull convhulln patch trisurf patch voronoi voronoin polyarea inpolygon rectint plot plotyy plot3 loglog semilogx semilogy errorbar fplot ezplot ezplot3 linespec colorspec bar bar3 barh bar3h hist histc rose pareto area pie pie3 stem stairs stem3 scatter scatter3 spy plotmatrix polar rose compass ezpolar linespec colorspec contour contourf contourc contour3 contourslice ezcontour ezcontourf feather quiver compass quiver3 streamslice streamline surf surfc surface surfl surfnorm mesh meshc meshz waterfall ribbon contour3 peaks cylinder ellipsoid sphere pcolor surf2patch ezsurf ezsurfc ezmesh ezmeshc contourslice flow isocaps isocolors isonormals isosurface reducepatch reducevolume shrinkfaces slice smooth3 subvolume volumebounds coneplot curl divergence interpstreamspeed stream2 stream3 streamline streamparticles streamribbon streamslice streamtube fill fill3 patch surf2patch movie noanimate drawnow refreshdata frame2im getframe im2frame comet comet3 title xlabel ylabel zlabel clabel datetick texlabel legend colorbar xlim ylim zlim box grid daspect pbaspect axes axis subplot hold gca cla annotation text legend title xlabel ylabel zlabel datacursormode ginput gtext colormap colormapeditor colorbar brighten contrast shading graymon caxis hsv2rgb rgb2hsv rgbplot spinmap colordef whitebg hidden pan reset rotate rotate3d selectmoveresize zoom datacursormode figurepalette plotbrowser plotedit plottools propertyeditor showplottool brush datacursormode linkdata refreshdata view makehgtform viewmtx cameratoolbar campan camzoom camdolly camlookat camorbit campos camproj camroll camtarget camup camva camlight light lightangle lighting diffuse material specular alim alpha alphamap image imagesc imread imwrite imfinfo imformats frame2im im2frame im2java ind2rgb rgb2ind imapprox dither cmpermute cmunique print printopt printdlg printpreview orient savefig openfig hgexport hgsave hgload saveas gca gcf gcbf gcbo gco ancestor allchild findall findfigs findobj gobjects ishghandle ishandle copyobj delete get set propedit rootobject figure axes image light line patch rectangle surface text annotation set get hggroup hgtransform makehgtform figure gcf close clf refresh newplot shg closereq dragrect drawnow rbbox opengl axes hold ishold newplot linkaxes linkprop refreshdata waitfor get set if for parfor switch try while break continue end pause return edit input publish notebook grabcode snapnow function nargin nargout varargin varargout narginchk nargoutchk validateattributes validatestring inputname persistent isvarname namelengthmax assignin global isglobal try error warning lastwarn assert oncleanup dbclear dbcont dbdown dbquit dbstack dbstatus dbstep dbstop dbtype dbup checkcode keyboard mlintrpt edit echo eval evalc evalin feval run builtin mfilename pcode clear clearvars disp openvar who whos load save matfile importdata uiimport csvread csvwrite dlmread dlmwrite textscan readtable writetable type xlsfinfo xlsread xlswrite readtable writetable fclose feof ferror fgetl fgets fileread fopen fprintf fread frewind fscanf fseek ftell fwrite im2java imfinfo imread imwrite nccreate ncdisp ncinfo ncread ncreadatt ncwrite ncwriteatt ncwriteschema netcdf h5create h5disp h5info h5read h5readatt h5write h5writeatt hdfinfo hdfread imread imwrite hdfan hdfhx hdfh hdfhd hdfhe hdfml hdfpt hdfv hdfvf hdfvh hdfvs hdfdf24 hdfdfr8 fitsdisp fitsinfo fitsread fitswrite multibandread multibandwrite cdfepoch cdfinfo cdfread cdfwrite todatenum cdflib audioinfo audioread audiowrite mmfileinfo movie2avi audiodevinfo audioplayer audiorecorder sound soundsc beep lin2mu mu2lin xmlread xmlwrite xslt memmapfile dir ls pwd fileattrib exist isdir type visdiff what which cd copyfile delete recycle mkdir movefile rmdir open winopen fileparts fullfile filemarker filesep tempdir tempname matlabroot toolboxdir zip unzip gzip gunzip tar untar addpath rmpath path savepath userpath genpath pathsep pathtool restoredefaultpath clipboard computer dos getenv perl setenv system unix winqueryreg sendmail urlread urlwrite web instrcallback instrfind instrfindall readasync record serial serialbreak stopasync supportpackageinstaller raspi_examples targetupdater raspi raspi writeled showleds raspi configuredigitalpin readdigitalpin writedigitalpin showpins raspi raspi scani2cbus i2cdev readregister writeregister enablei2c disablei2c raspi spidev writeread enablespi disablespi raspi cameraboard raspi openshell getfile putfile deletefile webcamlist webcam preview snapshot closepreview guide inspect figure axes uicontrol uitable uipanel uibuttongroup actxcontrol uimenu uicontextmenu uitoolbar uipushtool uitoggletool dialog errordlg helpdlg msgbox questdlg uigetpref uisetpref waitbar warndlg export2wsdlg inputdlg listdlg uisetcolor uisetfont printdlg printpreview uigetdir uigetfile uiopen uiputfile uisave menu align movegui getpixelposition setpixelposition listfonts textwrap uistack uiwait uiresume waitfor waitforbuttonpress getappdata setappdata isappdata rmappdata guidata guihandles classdef class isa isequal isobject enumeration events methods properties classdef import properties isprop dynamicprops methods ismethod handle hgsetget dynamicprops isa events empty superclasses enumeration save load saveobj loadobj cat horzcat vertcat empty disp display numel size end subsref subsasgn subsindex substruct disp display details metaclass mexext inmem loadlibrary unloadlibrary libisloaded calllib libfunctions libfunctionsview libstruct libpointer javaarray javaclasspath javaaddpath javarmpath javachk isjava usejava javamethod javamethodedt javaobject javaobjectedt cell class clear depfun exist fieldnames im2java import inmem inspect isa methods methodsview which net enablenetfromnetworkdrive cell begininvoke endinvoke combine remove removeall bitand bitor bitxor bitnot actxserver actxcontrol actxcontrollist actxcontrolselect iscom addproperty deleteproperty inspect fieldnames methods methodsview invoke isevent eventlisteners registerevent unregisterallevents unregisterevent isinterface interfaces release move callsoapservice createclassfromwsdl createsoapmessage parsesoapresponse try addcausemexception getreportmexception lastmexception rethrowmexception throwmexception throwascallermexception mexception functiontests runtests bench cputime memory profile profsave tic timeit toc clear inmem memory pack whos commandhistory commandwindow filebrowser workspace getpref setpref addpref rmpref ispref builddocsearchdb mex execute getchararray putchararray getfullmatrix putfullmatrix getvariable getworkspacedata putworkspacedata maximizecommandwindow minimizecommandwindow actxgetrunningserver enableservice mex dbmex mexext inmem ver computer mexext dbmex inmem mex mexext checkin checkout cmopts customverctrl undocheckout verctrl matlabwindows matlabunix exit quit matlabrc startup finish prefdir preferences ismac ispc isstudent isunix javachk license usejava ver verlessthan version doc help docsearch lookfor demo echodemo)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/moonscript.rb b/app/server/vendor/rouge/lib/rouge/lexers/moonscript.rb
new file mode 100755
index 0000000..7f03bef
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/moonscript.rb
@@ -0,0 +1,109 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    load_const :Lua, 'lua.rb'
+
+    class Moonscript < RegexLexer
+      desc "Moonscript (http://www.moonscript.org)"
+      tag 'moonscript'
+      aliases 'moon'
+      filenames '*.moon'
+      mimetypes 'text/x-moonscript', 'application/x-moonscript'
+
+      def initialize(opts={})
+        @function_highlighting = opts.delete(:function_highlighting) { true }
+        @disabled_modules = opts.delete(:disabled_modules) { [] }
+        super(opts)
+      end
+
+      def self.analyze_text(text)
+        return 1 if text.shebang? 'moon'
+      end
+
+      def builtins
+        return [] unless @function_highlighting
+
+        @builtins ||= Set.new.tap do |builtins|
+          Rouge::Lexers::Lua.builtins.each do |mod, fns|
+            next if @disabled_modules.include? mod
+            builtins.merge(fns)
+          end
+        end
+      end
+
+      state :root do
+        rule %r(#!(.*?)$), Comment::Preproc # shebang
+        rule //, Text, :main
+      end
+
+      state :base do
+        ident = '(?:[\w_][\w\d_]*)'
+
+        rule %r((?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?'), Num::Float
+        rule %r((?i)\d+e[+-]?\d+), Num::Float
+        rule %r((?i)0x[0-9a-f]*), Num::Hex
+        rule %r(\d+), Num::Integer
+        rule %r(@#{ident}*), Name::Variable::Instance
+        rule %r([A-Z][\w\d_]*), Name::Class
+        rule %r("?[^"]+":), Literal::String::Symbol
+        rule %r(#{ident}:), Literal::String::Symbol
+        rule %r(:#{ident}), Literal::String::Symbol
+
+        rule %r(\s+), Text::Whitespace
+        rule %r((==|~=|!=|<=|>=|\.\.\.|\.\.|->|=>|[=+\-*/%^<>#!\\])), Operator
+        rule %r([\[\]\{\}\(\)\.,:;]), Punctuation
+        rule %r((and|or|not)\b), Operator::Word
+
+        keywords = %w{
+          break class continue do else elseif end extends for if import in
+          repeat return switch super then unless until using when with while
+        }
+        rule %r((#{keywords.join('|')})\b), Keyword
+        rule %r((local|export)\b), Keyword::Declaration
+        rule %r((true|false|nil)\b), Keyword::Constant
+
+        rule %r([A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?) do |m|
+          name = m[0]
+          if self.builtins.include?(name)
+            token Name::Builtin
+          elsif name =~ /\./
+            a, b = name.split('.', 2)
+            token Name, a
+            token Punctuation, '.'
+            token Name, b
+          else
+            token Name
+          end
+        end
+      end
+
+      state :main do
+        rule %r(--.*$), Comment::Single
+        rule %r(\[(=*)\[.*?\]\1\])m, Str::Heredoc
+
+        mixin :base
+
+        rule %r('), Str::Single, :sqs
+        rule %r("), Str::Double, :dqs
+      end
+
+      state :sqs do
+        rule %r('), Str::Single, :pop!
+        rule %r([^']+), Str::Single
+      end
+
+      state :interpolation do
+        rule %r(\}), Str::Interpol, :pop!
+        mixin :base
+      end
+
+      state :dqs do
+        rule %r(#\{), Str::Interpol, :interpolation
+        rule %r("), Str::Double, :pop!
+        rule %r(#[^{]), Str::Double
+        rule %r([^"#]+), Str::Double
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/nginx.rb b/app/server/vendor/rouge/lib/rouge/lexers/nginx.rb
new file mode 100755
index 0000000..1bd4619
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/nginx.rb
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Nginx < RegexLexer
+      desc 'configuration files for the nginx web server (nginx.org)'
+      tag 'nginx'
+      mimetypes 'text/x-nginx-conf'
+      filenames 'nginx.conf'
+
+      id = /[^\s$;{}()#]+/
+
+      state :root do
+        rule /(include)(\s+)([^\s;]+)/ do
+          groups Keyword, Text, Name
+        end
+
+        rule id, Keyword, :statement
+
+        mixin :base
+      end
+
+      state :block do
+        rule /}/, Punctuation, :pop!
+        rule id, Keyword::Namespace, :statement
+        mixin :base
+      end
+
+      state :statement do
+        rule /{/ do
+          token Punctuation; pop!; push :block
+        end
+
+        rule /;/, Punctuation, :pop!
+
+        mixin :base
+      end
+
+      state :base do
+        rule /\s+/, Text
+
+        rule /#.*?\n/, Comment::Single
+        rule /(?:on|off)\b/, Name::Constant
+        rule /[$][\w-]+/, Name::Variable
+
+        # host/port
+        rule /([a-z0-9.-]+)(:)([0-9]+)/i do
+          groups Name::Function, Punctuation, Num::Integer
+        end
+
+        # mimetype
+        rule %r([a-z-]+/[a-z-]+)i, Name::Class
+
+        rule /[0-9]+[kmg]?\b/i, Num::Integer
+        rule /(~)(\s*)([^\s{]+)/ do
+          groups Punctuation, Text, Str::Regex
+        end
+
+        rule /[:=~]/, Punctuation
+
+        # pathname
+        rule %r(/#{id}?), Name
+
+        rule /[^#\s;{}$\\]+/, Str # catchall
+
+        rule /[$;]/, Text
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/objective_c.rb b/app/server/vendor/rouge/lib/rouge/lexers/objective_c.rb
new file mode 100755
index 0000000..52651f5
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/objective_c.rb
@@ -0,0 +1,190 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    load_const :C, 'c.rb'
+
+    class ObjectiveC < C
+      tag 'objective_c'
+      desc 'an extension of C commonly used to write Apple software'
+      aliases 'objc'
+      filenames '*.m', '*.h'
+
+      mimetypes 'text/x-objective_c', 'application/x-objective_c'
+
+      def self.at_keywords
+        @at_keywords ||= %w(
+          selector private protected public encode synchronized try
+          throw catch finally end property synthesize dynamic optional
+          interface implementation import
+        )
+      end
+
+      def self.at_builtins
+        @at_builtins ||= %w(true false YES NO)
+      end
+
+      def self.builtins
+        @builtins ||= %w(YES NO nil)
+      end
+
+      def self.analyze_text(text)
+        return 1 if text =~ /@(end|implementation|protocol|property)\b/
+
+        id = /[a-z$_][a-z0-9$_]*/i
+        return 0.4 if text =~ %r(
+          \[ \s* #{id} \s+
+          (?:
+            #{id} \s* \]
+            | #{id}? :
+          )
+        )x
+        return 0.4 if text.include? '@"'
+      end
+
+      id = /[a-z$_][a-z0-9$_]*/i
+
+      prepend :statements do
+        rule /@"/, Str, :string
+        rule /@'(\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|\\.|[^\\'\n]')/,
+          Str::Char
+        rule /@(\d+[.]\d*|[.]\d+|\d+)e[+-]?\d+l?/i,
+          Num::Float
+        rule /@(\d+[.]\d*|[.]\d+|\d+f)f?/i, Num::Float
+        rule /@0x\h+[lL]?/, Num::Hex
+        rule /@0[0-7]+l?/i, Num::Oct
+        rule /@\d+l?/, Num::Integer
+        rule /\bin\b/, Keyword
+
+        rule /@(?:interface|implementation)\b/ do
+          token Keyword
+          goto :classname
+        end
+
+        rule /@(?:class|protocol)\b/ do
+          token Keyword
+          goto :forward_classname
+        end
+
+        rule /@([[:alnum:]]+)/ do |m|
+          if self.class.at_keywords.include? m[1]
+            token Keyword
+          elsif self.class.at_builtins.include? m[1]
+            token Name::Builtin
+          else
+            token Error
+          end
+        end
+
+        rule /[?]/, Punctuation, :ternary
+        rule /\[/,  Punctuation, :message
+      end
+
+      state :ternary do
+        rule /:/, Punctuation, :pop!
+        mixin :statements
+      end
+
+      state :message_shared do
+        rule /\]/, Punctuation, :pop!
+        rule /;/, Error
+
+        mixin :statement
+      end
+
+      state :message do
+        rule /(#{id})(\s*)(:)/ do
+          groups(Name::Function, Text, Punctuation)
+          goto :message_with_args
+        end
+
+        rule /(#{id})(\s*)(\])/ do
+          groups(Name::Function, Text, Punctuation)
+          pop!
+        end
+
+        mixin :message_shared
+      end
+
+      state :message_with_args do
+        rule /(#{id})(\s*)(:)/ do
+          groups(Name::Function, Text, Punctuation)
+        end
+
+        mixin :message_shared
+      end
+
+      state :classname do
+        mixin :whitespace
+
+        rule /(#{id})(\s*)(:)(\s*)(#{id})/ do
+          groups(Name::Class, Text,
+                 Punctuation, Text,
+                 Name::Class)
+          pop!
+        end
+
+        rule /(#{id})(\s*)([(])(\s*)(#{id})(\s*)([)])/ do
+          groups(Name::Class, Text,
+                 Punctuation, Text,
+                 Name::Label, Text,
+                 Punctuation)
+        end
+
+        rule id, Name::Class, :pop!
+      end
+
+      state :forward_classname do
+        mixin :whitespace
+
+        rule /(#{id})(\s*)(,)(\s*)/ do
+          groups(Name::Class, Text, Punctuation, Text)
+          push
+        end
+
+        rule /(#{id})(\s*)(;?)/ do
+          groups(Name::Class, Text, Punctuation)
+          pop!
+        end
+      end
+
+      prepend :root do
+        rule %r(
+          ([-+])(\s*)
+          ([(].*?[)])?(\s*)
+          (?=#{id}:?)
+        )ix do |m|
+          token Keyword, m[1]; token Text, m[2]
+          recurse m[3]; token Text, m[4]
+          push :method_definition
+        end
+      end
+
+      state :method_definition do
+        rule /,/, Punctuation
+        rule /[.][.][.]/, Punctuation
+        rule /([(].*?[)])(#{id})/ do |m|
+          recurse m[1]; token Name::Variable, m[2]
+        end
+
+        rule /(#{id})(\s*)(:)/m do
+          groups(Name::Function, Text, Punctuation)
+        end
+
+        rule /;/, Punctuation, :pop!
+
+        rule /{/ do
+          token Punctuation
+          goto :function
+        end
+
+        mixin :inline_whitespace
+        rule %r(//.*?\n), Comment::Single
+        rule /\s+/m, Text
+
+        rule(//) { pop! }
+      end
+    end
+  end
+end
+
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/ocaml.rb b/app/server/vendor/rouge/lib/rouge/lexers/ocaml.rb
new file mode 100755
index 0000000..83112c6
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/ocaml.rb
@@ -0,0 +1,111 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class OCaml < RegexLexer
+      desc 'Objective CAML (ocaml.org)'
+      tag 'ocaml'
+      filenames '*.ml', '*.mli', '*.mll', '*.mly'
+      mimetypes 'text/x-ocaml'
+
+      def self.keywords
+        @keywords ||= Set.new %w(
+          as assert begin class constraint do done downto else end
+          exception external false for fun function functor if in include
+          inherit initializer lazy let match method module mutable new
+          object of open private raise rec sig struct then to true try
+          type value val virtual when while with
+        )
+      end
+
+      def self.keyopts
+        @keyopts ||= Set.new %w(
+          != # & && ( ) * \+ , - -. -> . .. : :: := :> ; ;; < <- =
+          > >] >} ? ?? [ [< [> [| ] _ ` { {< | |] } ~
+        )
+      end
+
+      def self.word_operators
+        @word_operators ||= Set.new %w(and asr land lor lsl lxor mod or)
+      end
+
+      def self.primitives
+        @primitives ||= Set.new %w(unit int float bool string char list array)
+      end
+
+      operator = %r([\[\];,{}_()!$%&*+./:<=>?@^|~#-]+)
+      id = /[a-z][\w']*/i
+      upper_id = /[A-Z][\w']*/
+
+      state :root do
+        rule /\s+/m, Text
+        rule /false|true|[(][)]|\[\]/, Name::Builtin::Pseudo
+        rule /#{upper_id}(?=\s*[.])/, Name::Namespace, :dotted
+        rule upper_id, Name::Class
+        rule /[(][*](?![)])/, Comment, :comment
+        rule id do |m|
+          match = m[0]
+          if self.class.keywords.include? match
+            token Keyword
+          elsif self.class.word_operators.include? match
+            token Operator::Word
+          elsif self.class.primitives.include? match
+            token Keyword::Type
+          else
+            token Name
+          end
+        end
+
+        rule operator do |m|
+          match = m[0]
+          if self.class.keyopts.include? match
+            token Punctuation
+          else
+            token Operator
+          end
+        end
+
+        rule /-?\d[\d_]*(.[\d_]*)?(e[+-]?\d[\d_]*)/i, Num::Float
+        rule /0x\h[\h_]*/i, Num::Hex
+        rule /0o[0-7][0-7_]*/i, Num::Oct
+        rule /0b[01][01_]*/i, Num::Bin
+        rule /\d[\d_]*/, Num::Integer
+
+        rule /'(?:(\\[\\"'ntbr ])|(\\[0-9]{3})|(\\x\h{2}))'/, Str::Char
+        rule /'[.]'/, Str::Char
+        rule /'/, Keyword
+        rule /"/, Str::Double, :string
+        rule /[~?]#{id}/, Name::Variable
+      end
+
+      state :comment do
+        rule /[^(*)]+/, Comment
+        rule(/[(][*]/) { token Comment; push }
+        rule /[*][)]/, Comment, :pop!
+        rule /[(*)]/, Comment
+      end
+
+      state :string do
+        rule /[^\\"]+/, Str::Double
+        mixin :escape_sequence
+        rule /\\\n/, Str::Double
+        rule /"/, Str::Double, :pop!
+      end
+
+      state :escape_sequence do
+        rule /\\[\\"'ntbr]/, Str::Escape
+        rule /\\\d{3}/, Str::Escape
+        rule /\\x\h{2}/, Str::Escape
+      end
+
+      state :dotted do
+        rule /\s+/m, Text
+        rule /[.]/, Punctuation
+        rule /#{upper_id}(?=\s*[.])/, Name::Namespace
+        rule upper_id, Name::Class, :pop!
+        rule id, Name, :pop!
+      end
+    end
+  end
+end
+
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/perl.rb b/app/server/vendor/rouge/lib/rouge/lexers/perl.rb
new file mode 100755
index 0000000..35a7d0f
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/perl.rb
@@ -0,0 +1,196 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Perl < RegexLexer
+      desc "The Perl scripting language (perl.org)"
+
+      tag 'perl'
+      aliases 'pl'
+
+      filenames '*.pl', '*.pm'
+      mimetypes 'text/x-perl', 'application/x-perl'
+
+      def self.analyze_text(text)
+        return 1 if text.shebang? 'perl'
+        return 0.4 if text.include? 'my $'
+      end
+
+      keywords = %w(
+        case continue do else elsif for foreach if last my next our
+        redo reset then unless until while use print new BEGIN CHECK
+        INIT END return
+      )
+
+      builtins = %w(
+        abs accept alarm atan2 bind binmode bless caller chdir chmod
+        chomp chop chown chr chroot close closedir connect continue cos
+        crypt dbmclose dbmopen defined delete die dump each endgrent
+        endhostent endnetent endprotoent endpwent endservent eof eval
+        exec exists exit exp fcntl fileno flock fork format formline getc
+        getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent
+        getlogin getnetbyaddr getnetbyname getnetent getpeername
+        getpgrp getppid getpriority getprotobyname getprotobynumber
+        getprotoent getpwent getpwnam getpwuid getservbyname getservbyport
+        getservent getsockname getsockopt glob gmtime goto grep hex
+        import index int ioctl join keys kill last lc lcfirst length
+        link listen local localtime log lstat map mkdir msgctl msgget
+        msgrcv msgsnd my next no oct open opendir ord our pack package
+        pipe pop pos printf prototype push quotemeta rand read readdir
+        readline readlink readpipe recv redo ref rename require reverse
+        rewinddir rindex rmdir scalar seek seekdir select semctl semget
+        semop send setgrent sethostent setnetent setpgrp setpriority
+        setprotoent setpwent setservent setsockopt shift shmctl shmget
+        shmread shmwrite shutdown sin sleep socket socketpair sort splice
+        split sprintf sqrt srand stat study substr symlink syscall sysopen
+        sysread sysseek system syswrite tell telldir tie tied time times
+        tr truncate uc ucfirst umask undef unlink unpack unshift untie
+        utime values vec wait waitpid wantarray warn write
+      )
+
+      re_tok = Str::Regex
+
+      state :balanced_regex do
+        rule %r(/(\\\\|\\/|[^/])*/[egimosx]*)m, re_tok, :pop!
+        rule %r(!(\\\\|\\!|[^!])*![egimosx]*)m, re_tok, :pop!
+        rule %r(\\(\\\\|[^\\])*\\[egimosx]*)m, re_tok, :pop!
+        rule %r({(\\\\|\\}|[^}])*}[egimosx]*), re_tok, :pop!
+        rule %r(<(\\\\|\\>|[^>])*>[egimosx]*), re_tok, :pop!
+        rule %r(\[(\\\\|\\\]|[^\]])*\][egimosx]*), re_tok, :pop!
+        rule %r[\((\\\\|\\\)|[^\)])*\)[egimosx]*], re_tok, :pop!
+        rule %r(@(\\\\|\\\@|[^\@])*@[egimosx]*), re_tok, :pop!
+        rule %r(%(\\\\|\\\%|[^\%])*%[egimosx]*), re_tok, :pop!
+        rule %r(\$(\\\\|\\\$|[^\$])*\$[egimosx]*), re_tok, :pop!
+      end
+
+      state :root do
+        rule /#.*?$/, Comment::Single
+        rule /^=[a-zA-Z0-9]+\s+.*?\n=cut/, Comment::Multiline
+        rule /(?:#{keywords.join('|')})\b/, Keyword
+
+        rule /(format)(\s+)([a-zA-Z0-9_]+)(\s*)(=)(\s*\n)/ do
+          groups Keyword, Text, Name, Text, Punctuation, Text
+
+          push :format
+        end
+
+        rule /(?:eq|lt|gt|le|ge|ne|not|and|or|cmp)\b/, Operator::Word
+
+        # common delimiters
+        rule %r(s/(\\\\|\\/|[^/])*/(\\\\|\\/|[^/])*/[egimosx]*), re_tok
+        rule %r(s!(\\\\|\\!|[^!])*!(\\\\|\\!|[^!])*![egimosx]*), re_tok
+        rule %r(s\\(\\\\|[^\\])*\\(\\\\|[^\\])*\\[egimosx]*), re_tok
+        rule %r(s@(\\\\|\\@|[^@])*@(\\\\|\\@|[^@])*@[egimosx]*), re_tok
+        rule %r(s%(\\\\|\\%|[^%])*%(\\\\|\\%|[^%])*%[egimosx]*), re_tok
+
+        # balanced delimiters
+        rule %r(s{(\\\\|\\}|[^}])*}\s*), re_tok, :balanced_regex
+        rule %r(s<(\\\\|\\>|[^>])*>\s*), re_tok, :balanced_regex
+        rule %r(s\[(\\\\|\\\]|[^\]])*\]\s*), re_tok, :balanced_regex
+        rule %r[s\((\\\\|\\\)|[^\)])*\)\s*], re_tok, :balanced_regex
+
+        rule %r(m?/(\\\\|\\/|[^/\n])*/[gcimosx]*), re_tok
+        rule %r(m(?=[/!\\{<\[\(@%\$])), re_tok, :balanced_regex
+        rule %r(((?<==~)|(?<=\())\s*/(\\\\|\\/|[^/])*/[gcimosx]*),
+          re_tok, :balanced_regex
+
+        rule /\s+/, Text
+        rule /(?:#{builtins.join('|')})\b/, Name::Builtin
+        rule /((__(DATA|DIE|WARN)__)|(STD(IN|OUT|ERR)))\b/,
+          Name::Builtin::Pseudo
+
+        rule /<<([\'"]?)([a-zA-Z_][a-zA-Z0-9_]*)\1;?\n.*?\n\2\n/m, Str
+
+        rule /__END__\b/, Comment::Preproc, :end_part
+        rule /\$\^[ADEFHILMOPSTWX]/, Name::Variable::Global
+        rule /\$[\\"'\[\]&`+*.,;=%~?@$!<>(^\|\/-](?!\w)/, Name::Variable::Global
+        rule /[$@%#]+/, Name::Variable, :varname
+
+        rule /0_?[0-7]+(_[0-7]+)*/, Num::Oct
+        rule /0x[0-9A-Fa-f]+(_[0-9A-Fa-f]+)*/, Num::Hex
+        rule /0b[01]+(_[01]+)*/, Num::Bin
+        rule /(\d*(_\d*)*\.\d+(_\d*)*|\d+(_\d*)*\.\d+(_\d*)*)(e[+-]?\d+)?/i,
+          Num::Float
+        rule /\d+(_\d*)*e[+-]?\d+(_\d*)*/i, Num::Float
+        rule /\d+(_\d+)*/, Num::Integer
+
+        rule /'(\\\\|\\'|[^'])*'/, Str
+        rule /"(\\\\|\\"|[^"])*"/, Str
+        rule /`(\\\\|\\`|[^`])*`/, Str::Backtick
+        rule /<([^\s>]+)>/, re_tok
+        rule /(q|qq|qw|qr|qx)\{/, Str::Other, :cb_string
+        rule /(q|qq|qw|qr|qx)\(/, Str::Other, :rb_string
+        rule /(q|qq|qw|qr|qx)\[/, Str::Other, :sb_string
+        rule /(q|qq|qw|qr|qx)</, Str::Other, :lt_string
+        rule /(q|qq|qw|qr|qx)([^a-zA-Z0-9])(.|\n)*?\2/, Str::Other
+
+        rule /package\s+/, Keyword, :modulename
+        rule /sub\s+/, Keyword, :funcname
+        rule /\[\]|\*\*|::|<<|>>|>=|<=|<=>|={3}|!=|=~|!~|&&?|\|\||\.{1,3}/,
+          Operator
+        rule /[-+\/*%=<>&^\|!\\~]=?/, Operator
+        rule /[()\[\]:;,<>\/?{}]/, Punctuation
+        rule(/(?=\w)/) { push :name }
+      end
+
+      state :format do
+        rule /\.\n/, Str::Interpol, :pop!
+        rule /.*?\n/, Str::Interpol
+      end
+
+      state :name_common do
+        rule /\w+::/, Name::Namespace
+        rule /[\w:]+/, Name::Variable, :pop!
+      end
+
+      state :varname do
+        rule /\s+/, Text
+        rule /\{/, Punctuation, :pop! # hash syntax
+        rule /\)|,/, Punctuation, :pop! # arg specifier
+        mixin :name_common
+      end
+
+      state :name do
+        mixin :name_common
+        rule /[A-Z_]+(?=[^a-zA-Z0-9_])/, Name::Constant, :pop!
+        rule(/(?=\W)/) { pop! }
+      end
+
+      state :modulename do
+        rule /[a-z_]\w*/i, Name::Namespace, :pop!
+      end
+
+      state :funcname do
+        rule /[a-zA-Z_]\w*[!?]?/, Name::Function
+        rule /\s+/, Text
+
+        # argument declaration
+        rule /(\([$@%]*\))(\s*)/ do
+          groups Punctuation, Text
+        end
+
+        rule /.*?{/, Punctuation, :pop!
+        rule /;/, Punctuation, :pop!
+      end
+
+      [[:cb, '\{', '\}'],
+       [:rb, '\(', '\)'],
+       [:sb, '\[', '\]'],
+       [:lt, '<',  '>']].each do |name, open, close|
+        tok = Str::Other
+        state :"#{name}_string" do
+          rule /\\[#{open}#{close}\\]/, tok
+          rule /\\/, tok
+          rule(/#{open}/) { token tok; push }
+          rule /#{close}/, tok, :pop!
+          rule /[^#{open}#{close}\\]+/, tok
+        end
+      end
+
+      state :end_part do
+        # eat the rest of the stream
+        rule /.+/m, Comment::Preproc, :pop!
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/php.rb b/app/server/vendor/rouge/lib/rouge/lexers/php.rb
new file mode 100755
index 0000000..45b95fb
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/php.rb
@@ -0,0 +1,163 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class PHP < TemplateLexer
+      desc "The PHP scripting language (php.net)"
+      tag 'php'
+      aliases 'php', 'php3', 'php4', 'php5'
+      filenames '*.php', '*.php[345]'
+      mimetypes 'text/x-php'
+
+      default_options :parent => 'html'
+
+      def initialize(opts={})
+        # if truthy, the lexer starts highlighting with php code
+        # (no <?php required)
+        @start_inline = opts.delete(:start_inline)
+        @funcnamehighlighting = opts.delete(:funcnamehighlighting) { true }
+        @disabledmodules = opts.delete(:disabledmodules) { [] }
+
+        super(opts)
+      end
+
+      def self.builtins
+        load Pathname.new(__FILE__).dirname.join('php/builtins.rb')
+        self.builtins
+      end
+
+      def builtins
+        return [] unless @funcnamehighlighting
+
+        @builtins ||= Set.new.tap do |builtins|
+          self.class.builtins.each do |mod, fns|
+            next if @disabledmodules.include? mod
+            builtins.merge(fns)
+          end
+        end
+      end
+
+      def start_inline?
+        !!@start_inline
+      end
+
+      start do
+        push :php if start_inline?
+      end
+
+      def self.keywords
+        @keywords ||= Set.new %w(
+          and E_PARSE old_function E_ERROR or as E_WARNING parent eval
+          PHP_OS break exit case extends PHP_VERSION cfunction FALSE
+          print for require continue foreach require_once declare return
+          default static do switch die stdClass echo else TRUE elseif
+          var empty if xor enddeclare include virtual endfor include_once
+          while endforeach global __FILE__ endif list __LINE__ endswitch
+          new __sleep endwhile not array __wakeup E_ALL NULL final
+          php_user_filter interface implements public private protected
+          abstract clone try catch throw this use namespace
+        )
+      end
+
+      state :root do
+        rule /<\?(php|=)?/, Comment::Preproc, :php
+        rule(/.*?(?=<\?)|.*/m) { delegate parent }
+      end
+
+      state :php do
+        rule /\?>/, Comment::Preproc, :pop!
+        # heredocs
+        rule /<<<('?)([a-z_]\w*)\1\n.*?\n\2;?\n/im, Str::Heredoc
+        rule /\s+/, Text
+        rule /#.*?\n/, Comment::Single
+        rule %r(//.*?\n), Comment::Single
+        # empty comment, otherwise seen as the start of a docstring
+        rule %r(/\*\*/), Comment::Multiline
+        rule %r(/\*\*.*?\*/)m, Str::Doc
+        rule %r(/\*.*?\*/)m, Comment::Multiline
+        rule /(->|::)(\s*)([a-zA-Z_][a-zA-Z0-9_]*)/ do
+          groups Operator, Text, Name::Attribute
+        end
+
+        rule /[~!%^&*+=\|:.<>\/?@-]+/, Operator
+        rule /[\[\]{}();,]+/, Punctuation
+        rule /class\b/, Keyword, :classname
+        # anonymous functions
+        rule /(function)(\s*)(?=\()/ do
+          groups Keyword, Text
+        end
+
+        # named functions
+        rule /(function)(\s+)(&?)(\s*)/ do
+          groups Keyword, Text, Operator, Text
+          push :funcname
+        end
+
+        rule /(const)(\s+)([a-zA-Z_]\w*)/i do
+          groups Keyword, Text, Name::Constant
+        end
+
+        rule /(true|false|null)\b/, Keyword::Constant
+        rule /\$\{\$+[a-z_]\w*\}/i, Name::Variable
+        rule /\$+[a-z_]\w*/i, Name::Variable
+
+        # may be intercepted for builtin highlighting
+        rule /[\\a-z_][\\\w]*/i do |m|
+          name = m[0]
+
+          if self.class.keywords.include? name
+            token Keyword
+          elsif self.builtins.include? name
+            token Name::Builtin
+          else
+            token Name::Other
+          end
+        end
+
+        rule /(\d+\.\d*|\d*\.\d+)(e[+-]?\d+)?/i, Num::Float
+        rule /\d+e[+-]?\d+/i, Num::Float
+        rule /0[0-7]+/, Num::Oct
+        rule /0x[a-f0-9]+/i, Num::Hex
+        rule /\d+/, Num::Integer
+        rule /'([^'\\]*(?:\\.[^'\\]*)*)'/, Str::Single
+        rule /`([^`\\]*(?:\\.[^`\\]*)*)`/, Str::Backtick
+        rule /"/, Str::Double, :string
+      end
+
+      state :classname do
+        rule /\s+/, Text
+        rule /[a-z_][\\\w]*/i, Name::Class, :pop!
+      end
+
+      state :funcname do
+        rule /[a-z_]\w*/i, Name::Function, :pop!
+      end
+
+      state :string do
+        rule /"/, Str::Double, :pop!
+        rule /[^\\{$"]+/, Str::Double
+        rule /\\([nrt\"$\\]|[0-7]{1,3}|x[0-9A-Fa-f]{1,2})/,
+          Str::Escape
+        rule /\$[a-zA-Z_][a-zA-Z0-9_]*(\[\S+\]|->[a-zA-Z_][a-zA-Z0-9_]*)?/, Name::Variable
+
+        rule /\{\$\{/, Str::Interpol, :interp_double
+        rule /\{(?=\$)/, Str::Interpol, :interp_single
+        rule /(\{)(\S+)(\})/ do
+          groups Str::Interpol, Name::Variable, Str::Interpol
+        end
+
+        rule /[${\\]+/, Str::Double
+      end
+
+      state :interp_double do
+        rule /\}\}/, Str::Interpol, :pop!
+        mixin :php
+      end
+
+      state :interp_single do
+        rule /\}/, Str::Interpol, :pop!
+        mixin :php
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/php/builtins.rb b/app/server/vendor/rouge/lib/rouge/lexers/php/builtins.rb
new file mode 100755
index 0000000..9939ee6
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/php/builtins.rb
@@ -0,0 +1,204 @@
+# -*- coding: utf-8 -*- #
+# automatically generated by `rake builtins:php`
+module Rouge
+  module Lexers
+    class PHP
+      def self.builtins
+        @builtins ||= {}.tap do |b|
+          b["Apache"] = Set.new %w(apache_child_terminate apache_child_terminate apache_get_modules apache_get_version apache_getenv apache_lookup_uri apache_note apache_request_headers apache_reset_timeout apache_response_headers apache_setenv getallheaders virtual apache_child_terminate)
+          b["APC"] = Set.new %w(apc_add apc_add apc_bin_dump apc_bin_dumpfile apc_bin_load apc_bin_loadfile apc_cache_info apc_cas apc_clear_cache apc_compile_file apc_dec apc_define_constants apc_delete_file apc_delete apc_exists apc_fetch apc_inc apc_load_constants apc_sma_info apc_store apc_add)
+          b["APD"] = Set.new %w(apd_breakpoint apd_breakpoint apd_callstack apd_clunk apd_continue apd_croak apd_dump_function_table apd_dump_persistent_resources apd_dump_regular_resources apd_echo apd_get_active_symbols apd_set_pprof_trace apd_set_session_trace_socket apd_set_session_trace apd_set_session override_function rename_function apd_breakpoint)
+          b["Array"] = Set.new %w(array_change_key_case array_change_key_case array_chunk array_column array_combine array_count_values array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_diff array_fill_keys array_fill array_filter array_flip array_intersect_assoc array_intersect_key array_intersect_uassoc array_intersect_ukey array_intersect array_key_exists array_keys array_map array_merge_recursive array_merge array_multisort array_pad array_pop array_product array_push array_rand array_reduce array_replace_recursive array_replace array_reverse array_search array_shift array_slice array_splice array_sum array_udiff_assoc array_udiff_uassoc array_udiff array_uintersect_assoc array_uintersect_uassoc array_uintersect array_unique array_unshift array_values array_walk_recursive array_walk array arsort asort compact count current each end extract in_array key_exists key krsort ksort list natcasesort natsort next pos prev range reset rsort shuffle sizeof sort uasort uksort usort array_change_key_case)
+          b["BBCode"] = Set.new %w(bbcode_add_element bbcode_add_element bbcode_add_smiley bbcode_create bbcode_destroy bbcode_parse bbcode_set_arg_parser bbcode_set_flags bbcode_add_element)
+          b["BC Math"] = Set.new %w(bcadd bcadd bccomp bcdiv bcmod bcmul bcpow bcpowmod bcscale bcsqrt bcsub bcadd)
+          b["bcompiler"] = Set.new %w(bcompiler_load_exe bcompiler_load_exe bcompiler_load bcompiler_parse_class bcompiler_read bcompiler_write_class bcompiler_write_constant bcompiler_write_exe_footer bcompiler_write_file bcompiler_write_footer bcompiler_write_function bcompiler_write_functions_from_file bcompiler_write_header bcompiler_write_included_filename bcompiler_load_exe)
+          b["Blenc"] = Set.new %w(blenc_encrypt blenc_encrypt blenc_encrypt)
+          b["Bzip2"] = Set.new %w(bzclose bzclose bzcompress bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite bzclose)
+          b["Cairo"] = Set.new %w(cairo_create cairo_create cairo_font_face_get_type cairo_font_face_status cairo_font_options_create cairo_font_options_equal cairo_font_options_get_antialias cairo_font_options_get_hint_metrics cairo_font_options_get_hint_style cairo_font_options_get_subpixel_order cairo_font_options_hash cairo_font_options_merge cairo_font_options_set_antialias cairo_font_options_set_hint_metrics cairo_font_options_set_hint_style cairo_font_options_set_subpixel_order cairo_font_options_status cairo_format_stride_for_width cairo_image_surface_create_for_data cairo_image_surface_create_from_png cairo_image_surface_create cairo_image_surface_get_data cairo_image_surface_get_format cairo_image_surface_get_height cairo_image_surface_get_stride cairo_image_surface_get_width cairo_matrix_create_scale cairo_matrix_create_translate cairo_matrix_invert cairo_matrix_multiply cairo_matrix_rotate cairo_matrix_transform_distance cairo_matrix_transform_point cairo_matrix_translate cairo_pattern_add_color_stop_rgb cairo_pattern_add_color_stop_rgba cairo_pattern_create_for_surface cairo_pattern_create_linear cairo_pattern_create_radial cairo_pattern_create_rgb cairo_pattern_create_rgba cairo_pattern_get_color_stop_count cairo_pattern_get_color_stop_rgba cairo_pattern_get_extend cairo_pattern_get_filter cairo_pattern_get_linear_points cairo_pattern_get_matrix cairo_pattern_get_radial_circles cairo_pattern_get_rgba cairo_pattern_get_surface cairo_pattern_get_type cairo_pattern_set_extend cairo_pattern_set_filter cairo_pattern_set_matrix cairo_pattern_status cairo_pdf_surface_create cairo_pdf_surface_set_size cairo_ps_get_levels cairo_ps_level_to_string cairo_ps_surface_create cairo_ps_surface_dsc_begin_page_setup cairo_ps_surface_dsc_begin_setup cairo_ps_surface_dsc_comment cairo_ps_surface_get_eps cairo_ps_surface_restrict_to_level cairo_ps_surface_set_eps cairo_ps_surface_set_size cairo_scaled_font_create cairo_scaled_font_extents cairo_scaled_font_get_ctm cairo_scaled_font_get_font_face cairo_scaled_font_get_font_matrix cairo_scaled_font_get_font_options cairo_scaled_font_get_scale_matrix cairo_scaled_font_get_type cairo_scaled_font_glyph_extents cairo_scaled_font_status cairo_scaled_font_text_extents cairo_surface_copy_page cairo_surface_create_similar cairo_surface_finish cairo_surface_flush cairo_surface_get_content cairo_surface_get_device_offset cairo_surface_get_font_options cairo_surface_get_type cairo_surface_mark_dirty_rectangle cairo_surface_mark_dirty cairo_surface_set_device_offset cairo_surface_set_fallback_resolution cairo_surface_show_page cairo_surface_status cairo_surface_write_to_png cairo_svg_surface_create cairo_svg_surface_restrict_to_version cairo_svg_version_to_string cairo_create)
+          b["Calendar"] = Set.new %w(cal_days_in_month cal_days_in_month cal_from_jd cal_info cal_to_jd easter_date easter_days FrenchToJD GregorianToJD JDDayOfWeek JDMonthName JDToFrench JDToGregorian jdtojewish JDToJulian jdtounix JewishToJD JulianToJD unixtojd cal_days_in_month)
+          b["chdb"] = Set.new %w(chdb_create chdb_create chdb_create)
+          b["Classkit"] = Set.new %w(classkit_import classkit_import classkit_method_add classkit_method_copy classkit_method_redefine classkit_method_remove classkit_method_rename classkit_import)
+          b["Classes/Object"] = Set.new %w(__autoload __autoload call_user_method_array call_user_method class_alias class_exists get_called_class get_class_methods get_class_vars get_class get_declared_classes get_declared_interfaces get_declared_traits get_object_vars get_parent_class interface_exists is_a is_subclass_of method_exists property_exists trait_exists __autoload)
+          b["COM"] = Set.new %w(com_addref com_addref com_create_guid com_event_sink com_get_active_object com_get com_invoke com_isenum com_load_typelib com_load com_message_pump com_print_typeinfo com_propget com_propput com_propset com_release com_set variant_abs variant_add variant_and variant_cast variant_cat variant_cmp variant_date_from_timestamp variant_date_to_timestamp variant_div variant_eqv variant_fix variant_get_type variant_idiv variant_imp variant_int variant_mod variant_mul variant_neg variant_not variant_or variant_pow variant_round variant_set_type variant_set variant_sub variant_xor com_addref)
+          b["Crack"] = Set.new %w(crack_check crack_check crack_closedict crack_getlastmessage crack_opendict crack_check)
+          b["Ctype"] = Set.new %w(ctype_alnum ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_graph ctype_lower ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit ctype_alnum)
+          b["CUBRID"] = Set.new %w(cubrid_bind cubrid_bind cubrid_close_prepare cubrid_close_request cubrid_col_get cubrid_col_size cubrid_column_names cubrid_column_types cubrid_commit cubrid_connect_with_url cubrid_connect cubrid_current_oid cubrid_disconnect cubrid_drop cubrid_error_code_facility cubrid_error_code cubrid_error_msg cubrid_execute cubrid_fetch cubrid_free_result cubrid_get_autocommit cubrid_get_charset cubrid_get_class_name cubrid_get_client_info cubrid_get_db_parameter cubrid_get_query_timeout cubrid_get_server_info cubrid_get cubrid_insert_id cubrid_is_instance cubrid_lob_close cubrid_lob_export cubrid_lob_get cubrid_lob_send cubrid_lob_size cubrid_lob2_bind cubrid_lob2_close cubrid_lob2_export cubrid_lob2_import cubrid_lob2_new cubrid_lob2_read cubrid_lob2_seek64 cubrid_lob2_seek cubrid_lob2_size64 cubrid_lob2_size cubrid_lob2_tell64 cubrid_lob2_tell cubrid_lob2_write cubrid_lock_read cubrid_lock_write cubrid_move_cursor cubrid_next_result cubrid_num_cols cubrid_num_rows cubrid_pconnect_with_url cubrid_pconnect cubrid_prepare cubrid_put cubrid_rollback cubrid_schema cubrid_seq_drop cubrid_seq_insert cubrid_seq_put cubrid_set_add cubrid_set_autocommit cubrid_set_db_parameter cubrid_set_drop cubrid_set_query_timeout cubrid_version cubrid_bind)
+          b["cURL"] = Set.new %w(curl_close curl_close curl_copy_handle curl_errno curl_error curl_escape curl_exec curl_file_create curl_getinfo curl_init curl_multi_add_handle curl_multi_close curl_multi_exec curl_multi_getcontent curl_multi_info_read curl_multi_init curl_multi_remove_handle curl_multi_select curl_multi_setopt curl_multi_strerror curl_pause curl_reset curl_setopt_array curl_setopt curl_share_close curl_share_init curl_share_setopt curl_strerror curl_unescape curl_version curl_close)
+          b["Cyrus"] = Set.new %w(cyrus_authenticate cyrus_authenticate cyrus_bind cyrus_close cyrus_connect cyrus_query cyrus_unbind cyrus_authenticate)
+          b["Date/Time"] = Set.new %w(checkdate checkdate date_add date_create_from_format date_create_immutable_from_format date_create_immutable date_create date_date_set date_default_timezone_get date_default_timezone_set date_diff date_format date_get_last_errors date_interval_create_from_date_string date_interval_format date_isodate_set date_modify date_offset_get date_parse_from_format date_parse date_sub date_sun_info date_sunrise date_sunset date_time_set date_timestamp_get date_timestamp_set date_timezone_get date_timezone_set date getdate gettimeofday gmdate gmmktime gmstrftime idate localtime microtime mktime strftime strptime strtotime time timezone_abbreviations_list timezone_identifiers_list timezone_location_get timezone_name_from_abbr timezone_name_get timezone_offset_get timezone_open timezone_transitions_get timezone_version_get checkdate)
+          b["DBA"] = Set.new %w(dba_close dba_close dba_delete dba_exists dba_fetch dba_firstkey dba_handlers dba_insert dba_key_split dba_list dba_nextkey dba_open dba_optimize dba_popen dba_replace dba_sync dba_close)
+          b["dBase"] = Set.new %w(dbase_add_record dbase_add_record dbase_close dbase_create dbase_delete_record dbase_get_header_info dbase_get_record_with_names dbase_get_record dbase_numfields dbase_numrecords dbase_open dbase_pack dbase_replace_record dbase_add_record)
+          b["DB++"] = Set.new %w(dbplus_add dbplus_add dbplus_aql dbplus_chdir dbplus_close dbplus_curr dbplus_errcode dbplus_errno dbplus_find dbplus_first dbplus_flush dbplus_freealllocks dbplus_freelock dbplus_freerlocks dbplus_getlock dbplus_getunique dbplus_info dbplus_last dbplus_lockrel dbplus_next dbplus_open dbplus_prev dbplus_rchperm dbplus_rcreate dbplus_rcrtexact dbplus_rcrtlike dbplus_resolve dbplus_restorepos dbplus_rkeys dbplus_ropen dbplus_rquery dbplus_rrename dbplus_rsecindex dbplus_runlink dbplus_rzap dbplus_savepos dbplus_setindex dbplus_setindexbynumber dbplus_sql dbplus_tcl dbplus_tremove dbplus_undo dbplus_undoprepare dbplus_unlockrel dbplus_unselect dbplus_update dbplus_xlockrel dbplus_xunlockrel dbplus_add)
+          b["dbx"] = Set.new %w(dbx_close dbx_close dbx_compare dbx_connect dbx_error dbx_escape_string dbx_fetch_row dbx_query dbx_sort dbx_close)
+          b["Direct IO"] = Set.new %w(dio_close dio_close dio_fcntl dio_open dio_read dio_seek dio_stat dio_tcsetattr dio_truncate dio_write dio_close)
+          b["Directory"] = Set.new %w(chdir chdir chroot closedir dir getcwd opendir readdir rewinddir scandir chdir)
+          b["DOM"] = Set.new %w(dom_import_simplexml dom_import_simplexml dom_import_simplexml)
+          b[".NET"] = Set.new %w(dotnet_load dotnet_load dotnet_load)
+          b["Eio"] = Set.new %w(eio_busy eio_busy eio_cancel eio_chmod eio_chown eio_close eio_custom eio_dup2 eio_event_loop eio_fallocate eio_fchmod eio_fchown eio_fdatasync eio_fstat eio_fstatvfs eio_fsync eio_ftruncate eio_futime eio_get_event_stream eio_get_last_error eio_grp_add eio_grp_cancel eio_grp_limit eio_grp eio_init eio_link eio_lstat eio_mkdir eio_mknod eio_nop eio_npending eio_nready eio_nreqs eio_nthreads eio_open eio_poll eio_read eio_readahead eio_readdir eio_readlink eio_realpath eio_rename eio_rmdir eio_seek eio_sendfile eio_set_max_idle eio_set_max_parallel eio_set_max_poll_reqs eio_set_max_poll_time eio_set_min_parallel eio_stat eio_statvfs eio_symlink eio_sync_file_range eio_sync eio_syncfs eio_truncate eio_unlink eio_utime eio_write eio_busy)
+          b["Enchant"] = Set.new %w(enchant_broker_describe enchant_broker_describe enchant_broker_dict_exists enchant_broker_free_dict enchant_broker_free enchant_broker_get_error enchant_broker_init enchant_broker_list_dicts enchant_broker_request_dict enchant_broker_request_pwl_dict enchant_broker_set_ordering enchant_dict_add_to_personal enchant_dict_add_to_session enchant_dict_check enchant_dict_describe enchant_dict_get_error enchant_dict_is_in_session enchant_dict_quick_check enchant_dict_store_replacement enchant_dict_suggest enchant_broker_describe)
+          b["Error Handling"] = Set.new %w(debug_backtrace debug_backtrace debug_print_backtrace error_get_last error_log error_reporting restore_error_handler restore_exception_handler set_error_handler set_exception_handler trigger_error user_error debug_backtrace)
+          b["Program execution"] = Set.new %w(escapeshellarg escapeshellarg escapeshellcmd exec passthru proc_close proc_get_status proc_nice proc_open proc_terminate shell_exec system escapeshellarg)
+          b["Exif"] = Set.new %w(exif_imagetype exif_imagetype exif_read_data exif_tagname exif_thumbnail read_exif_data exif_imagetype)
+          b["Expect"] = Set.new %w(expect_expectl expect_expectl expect_popen expect_expectl)
+          b["FAM"] = Set.new %w(fam_cancel_monitor fam_cancel_monitor fam_close fam_monitor_collection fam_monitor_directory fam_monitor_file fam_next_event fam_open fam_pending fam_resume_monitor fam_suspend_monitor fam_cancel_monitor)
+          b["Fann"] = Set.new %w(fann_cascadetrain_on_data fann_cascadetrain_on_data fann_cascadetrain_on_file fann_clear_scaling_params fann_copy fann_create_from_file fann_create_shortcut_array fann_create_shortcut fann_create_sparse_array fann_create_sparse fann_create_standard_array fann_create_standard fann_create_train_from_callback fann_create_train fann_descale_input fann_descale_output fann_descale_train fann_destroy_train fann_destroy fann_duplicate_train_data fann_get_activation_function fann_get_activation_steepness fann_get_bias_array fann_get_bit_fail_limit fann_get_bit_fail fann_get_cascade_activation_functions_count fann_get_cascade_activation_functions fann_get_cascade_activation_steepnesses_count fann_get_cascade_activation_steepnesses fann_get_cascade_candidate_change_fraction fann_get_cascade_candidate_limit fann_get_cascade_candidate_stagnation_epochs fann_get_cascade_max_cand_epochs fann_get_cascade_max_out_epochs fann_get_cascade_min_cand_epochs fann_get_cascade_min_out_epochs fann_get_cascade_num_candidate_groups fann_get_cascade_num_candidates fann_get_cascade_output_change_fraction fann_get_cascade_output_stagnation_epochs fann_get_cascade_weight_multiplier fann_get_connection_array fann_get_connection_rate fann_get_errno fann_get_errstr fann_get_layer_array fann_get_learning_momentum fann_get_learning_rate fann_get_MSE fann_get_network_type fann_get_num_input fann_get_num_layers fann_get_num_output fann_get_quickprop_decay fann_get_quickprop_mu fann_get_rprop_decrease_factor fann_get_rprop_delta_max fann_get_rprop_delta_min fann_get_rprop_delta_zero fann_get_rprop_increase_factor fann_get_sarprop_step_error_shift fann_get_sarprop_step_error_threshold_factor fann_get_sarprop_temperature fann_get_sarprop_weight_decay_shift fann_get_total_connections fann_get_total_neurons fann_get_train_error_function fann_get_train_stop_function fann_get_training_algorithm fann_init_weights fann_length_train_data fann_merge_train_data fann_num_input_train_data fann_num_output_train_data fann_print_error fann_randomize_weights fann_read_train_from_file fann_reset_errno fann_reset_errstr fann_reset_MSE fann_run fann_save_train fann_save fann_scale_input_train_data fann_scale_input fann_scale_output_train_data fann_scale_output fann_scale_train_data fann_scale_train fann_set_activation_function_hidden fann_set_activation_function_layer fann_set_activation_function_output fann_set_activation_function fann_set_activation_steepness_hidden fann_set_activation_steepness_layer fann_set_activation_steepness_output fann_set_activation_steepness fann_set_bit_fail_limit fann_set_callback fann_set_cascade_activation_functions fann_set_cascade_activation_steepnesses fann_set_cascade_candidate_change_fraction fann_set_cascade_candidate_limit fann_set_cascade_candidate_stagnation_epochs fann_set_cascade_max_cand_epochs fann_set_cascade_max_out_epochs fann_set_cascade_min_cand_epochs fann_set_cascade_min_out_epochs fann_set_cascade_num_candidate_groups fann_set_cascade_output_change_fraction fann_set_cascade_output_stagnation_epochs fann_set_cascade_weight_multiplier fann_set_error_log fann_set_input_scaling_params fann_set_learning_momentum fann_set_learning_rate fann_set_output_scaling_params fann_set_quickprop_decay fann_set_quickprop_mu fann_set_rprop_decrease_factor fann_set_rprop_delta_max fann_set_rprop_delta_min fann_set_rprop_delta_zero fann_set_rprop_increase_factor fann_set_sarprop_step_error_shift fann_set_sarprop_step_error_threshold_factor fann_set_sarprop_temperature fann_set_sarprop_weight_decay_shift fann_set_scaling_params fann_set_train_error_function fann_set_train_stop_function fann_set_training_algorithm fann_set_weight_array fann_set_weight fann_shuffle_train_data fann_subset_train_data fann_test_data fann_test fann_train_epoch fann_train_on_data fann_train_on_file fann_train fann_cascadetrain_on_data)
+          b["FrontBase"] = Set.new %w(fbsql_affected_rows fbsql_affected_rows fbsql_autocommit fbsql_blob_size fbsql_change_user fbsql_clob_size fbsql_close fbsql_commit fbsql_connect fbsql_create_blob fbsql_create_clob fbsql_create_db fbsql_data_seek fbsql_database_password fbsql_database fbsql_db_query fbsql_db_status fbsql_drop_db fbsql_errno fbsql_error fbsql_fetch_array fbsql_fetch_assoc fbsql_fetch_field fbsql_fetch_lengths fbsql_fetch_object fbsql_fetch_row fbsql_field_flags fbsql_field_len fbsql_field_name fbsql_field_seek fbsql_field_table fbsql_field_type fbsql_free_result fbsql_get_autostart_info fbsql_hostname fbsql_insert_id fbsql_list_dbs fbsql_list_fields fbsql_list_tables fbsql_next_result fbsql_num_fields fbsql_num_rows fbsql_password fbsql_pconnect fbsql_query fbsql_read_blob fbsql_read_clob fbsql_result fbsql_rollback fbsql_rows_fetched fbsql_select_db fbsql_set_characterset fbsql_set_lob_mode fbsql_set_password fbsql_set_transaction fbsql_start_db fbsql_stop_db fbsql_table_name fbsql_tablename fbsql_username fbsql_warnings fbsql_affected_rows)
+          b["FDF"] = Set.new %w(fdf_add_doc_javascript fdf_add_doc_javascript fdf_add_template fdf_close fdf_create fdf_enum_values fdf_errno fdf_error fdf_get_ap fdf_get_attachment fdf_get_encoding fdf_get_file fdf_get_flags fdf_get_opt fdf_get_status fdf_get_value fdf_get_version fdf_header fdf_next_field_name fdf_open_string fdf_open fdf_remove_item fdf_save_string fdf_save fdf_set_ap fdf_set_encoding fdf_set_file fdf_set_flags fdf_set_javascript_action fdf_set_on_import_javascript fdf_set_opt fdf_set_status fdf_set_submit_form_action fdf_set_target_frame fdf_set_value fdf_set_version fdf_add_doc_javascript)
+          b["Fileinfo"] = Set.new %w(finfo_buffer finfo_buffer finfo_close finfo_file finfo_open finfo_set_flags mime_content_type finfo_buffer)
+          b["filePro"] = Set.new %w(filepro_fieldcount filepro_fieldcount filepro_fieldname filepro_fieldtype filepro_fieldwidth filepro_retrieve filepro_rowcount filepro filepro_fieldcount)
+          b["Filesystem"] = Set.new %w(basename basename chgrp chmod chown clearstatcache copy delete dirname disk_free_space disk_total_space diskfreespace fclose feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents file fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype flock fnmatch fopen fpassthru fputcsv fputs fread fscanf fseek fstat ftell ftruncate fwrite glob is_dir is_executable is_file is_link is_readable is_uploaded_file is_writable is_writeable lchgrp lchown link linkinfo lstat mkdir move_uploaded_file parse_ini_file parse_ini_string pathinfo pclose popen readfile readlink realpath_cache_get realpath_cache_size realpath rename rewind rmdir set_file_buffer stat symlink tempnam tmpfile touch umask unlink basename)
+          b["Filter"] = Set.new %w(filter_has_var filter_has_var filter_id filter_input_array filter_input filter_list filter_var_array filter_var filter_has_var)
+          b["FPM"] = Set.new %w(fastcgi_finish_request fastcgi_finish_request fastcgi_finish_request)
+          b["FriBiDi"] = Set.new %w(fribidi_log2vis fribidi_log2vis fribidi_log2vis)
+          b["FTP"] = Set.new %w(ftp_alloc ftp_alloc ftp_cdup ftp_chdir ftp_chmod ftp_close ftp_connect ftp_delete ftp_exec ftp_fget ftp_fput ftp_get_option ftp_get ftp_login ftp_mdtm ftp_mkdir ftp_nb_continue ftp_nb_fget ftp_nb_fput ftp_nb_get ftp_nb_put ftp_nlist ftp_pasv ftp_put ftp_pwd ftp_quit ftp_raw ftp_rawlist ftp_rename ftp_rmdir ftp_set_option ftp_site ftp_size ftp_ssl_connect ftp_systype ftp_alloc)
+          b["Function handling"] = Set.new %w(call_user_func_array call_user_func_array call_user_func create_function forward_static_call_array forward_static_call func_get_arg func_get_args func_num_args function_exists get_defined_functions register_shutdown_function register_tick_function unregister_tick_function call_user_func_array)
+          b["GeoIP"] = Set.new %w(geoip_asnum_by_name geoip_asnum_by_name geoip_continent_code_by_name geoip_country_code_by_name geoip_country_code3_by_name geoip_country_name_by_name geoip_database_info geoip_db_avail geoip_db_filename geoip_db_get_all_info geoip_domain_by_name geoip_id_by_name geoip_isp_by_name geoip_netspeedcell_by_name geoip_org_by_name geoip_record_by_name geoip_region_by_name geoip_region_name_by_code geoip_setup_custom_directory geoip_time_zone_by_country_and_region geoip_asnum_by_name)
+          b["Gettext"] = Set.new %w(bind_textdomain_codeset bind_textdomain_codeset bindtextdomain dcgettext dcngettext dgettext dngettext gettext ngettext textdomain bind_textdomain_codeset)
+          b["GMP"] = Set.new %w(gmp_abs gmp_abs gmp_add gmp_and gmp_clrbit gmp_cmp gmp_com gmp_div_q gmp_div_qr gmp_div_r gmp_div gmp_divexact gmp_fact gmp_gcd gmp_gcdext gmp_hamdist gmp_init gmp_intval gmp_invert gmp_jacobi gmp_legendre gmp_mod gmp_mul gmp_neg gmp_nextprime gmp_or gmp_perfect_square gmp_popcount gmp_pow gmp_powm gmp_prob_prime gmp_random gmp_scan0 gmp_scan1 gmp_setbit gmp_sign gmp_sqrt gmp_sqrtrem gmp_strval gmp_sub gmp_testbit gmp_xor gmp_abs)
+          b["GnuPG"] = Set.new %w(gnupg_adddecryptkey gnupg_adddecryptkey gnupg_addencryptkey gnupg_addsignkey gnupg_cleardecryptkeys gnupg_clearencryptkeys gnupg_clearsignkeys gnupg_decrypt gnupg_decryptverify gnupg_encrypt gnupg_encryptsign gnupg_export gnupg_geterror gnupg_getprotocol gnupg_import gnupg_init gnupg_keyinfo gnupg_setarmor gnupg_seterrormode gnupg_setsignmode gnupg_sign gnupg_verify gnupg_adddecryptkey)
+          b["Gupnp"] = Set.new %w(gupnp_context_get_host_ip gupnp_context_get_host_ip gupnp_context_get_port gupnp_context_get_subscription_timeout gupnp_context_host_path gupnp_context_new gupnp_context_set_subscription_timeout gupnp_context_timeout_add gupnp_context_unhost_path gupnp_control_point_browse_start gupnp_control_point_browse_stop gupnp_control_point_callback_set gupnp_control_point_new gupnp_device_action_callback_set gupnp_device_info_get_service gupnp_device_info_get gupnp_root_device_get_available gupnp_root_device_get_relative_location gupnp_root_device_new gupnp_root_device_set_available gupnp_root_device_start gupnp_root_device_stop gupnp_service_action_get gupnp_service_action_return_error gupnp_service_action_return gupnp_service_action_set gupnp_service_freeze_notify gupnp_service_info_get_introspection gupnp_service_info_get gupnp_service_introspection_get_state_variable gupnp_service_notify gupnp_service_proxy_action_get gupnp_service_proxy_action_set gupnp_service_proxy_add_notify gupnp_service_proxy_callback_set gupnp_service_proxy_get_subscribed gupnp_service_proxy_remove_notify gupnp_service_proxy_set_subscribed gupnp_service_thaw_notify gupnp_context_get_host_ip)
+          b["Hash"] = Set.new %w(hash_algos hash_algos hash_copy hash_file hash_final hash_hmac_file hash_hmac hash_init hash_pbkdf2 hash_update_file hash_update_stream hash_update hash hash_algos)
+          b["HTTP"] = Set.new %w(http_cache_etag http_cache_etag http_cache_last_modified http_chunked_decode http_deflate http_inflate http_build_cookie http_date http_get_request_body_stream http_get_request_body http_get_request_headers http_match_etag http_match_modified http_match_request_header http_support http_negotiate_charset http_negotiate_content_type http_negotiate_language ob_deflatehandler ob_etaghandler ob_inflatehandler http_parse_cookie http_parse_headers http_parse_message http_parse_params http_persistent_handles_clean http_persistent_handles_count http_persistent_handles_ident http_get http_head http_post_data http_post_fields http_put_data http_put_file http_put_stream http_request_body_encode http_request_method_exists http_request_method_name http_request_method_register http_request_method_unregister http_request http_redirect http_send_content_disposition http_send_content_type http_send_data http_send_file http_send_last_modified http_send_status http_send_stream http_throttle http_build_str http_build_url http_cache_etag)
+          b["Hyperwave"] = Set.new %w(hw_Array2Objrec hw_Array2Objrec hw_changeobject hw_Children hw_ChildrenObj hw_Close hw_Connect hw_connection_info hw_cp hw_Deleteobject hw_DocByAnchor hw_DocByAnchorObj hw_Document_Attributes hw_Document_BodyTag hw_Document_Content hw_Document_SetContent hw_Document_Size hw_dummy hw_EditText hw_Error hw_ErrorMsg hw_Free_Document hw_GetAnchors hw_GetAnchorsObj hw_GetAndLock hw_GetChildColl hw_GetChildCollObj hw_GetChildDocColl hw_GetChildDocCollObj hw_GetObject hw_GetObjectByQuery hw_GetObjectByQueryColl hw_GetObjectByQueryCollObj hw_GetObjectByQueryObj hw_GetParents hw_GetParentsObj hw_getrellink hw_GetRemote hw_getremotechildren hw_GetSrcByDestObj hw_GetText hw_getusername hw_Identify hw_InCollections hw_Info hw_InsColl hw_InsDoc hw_insertanchors hw_InsertDocument hw_InsertObject hw_mapid hw_Modifyobject hw_mv hw_New_Document hw_objrec2array hw_Output_Document hw_pConnect hw_PipeDocument hw_Root hw_setlinkroot hw_stat hw_Unlock hw_Who hw_Array2Objrec)
+          b["Hyperwave API"] = Set.new %w(hwapi_attribute_new hwapi_content_new hwapi_hgcsp hwapi_object_new)
+          b["Firebird/InterBase"] = Set.new %w(ibase_add_user ibase_add_user ibase_affected_rows ibase_backup ibase_blob_add ibase_blob_cancel ibase_blob_close ibase_blob_create ibase_blob_echo ibase_blob_get ibase_blob_import ibase_blob_info ibase_blob_open ibase_close ibase_commit_ret ibase_commit ibase_connect ibase_db_info ibase_delete_user ibase_drop_db ibase_errcode ibase_errmsg ibase_execute ibase_fetch_assoc ibase_fetch_object ibase_fetch_row ibase_field_info ibase_free_event_handler ibase_free_query ibase_free_result ibase_gen_id ibase_maintain_db ibase_modify_user ibase_name_result ibase_num_fields ibase_num_params ibase_param_info ibase_pconnect ibase_prepare ibase_query ibase_restore ibase_rollback_ret ibase_rollback ibase_server_info ibase_service_attach ibase_service_detach ibase_set_event_handler ibase_trans ibase_wait_event ibase_add_user)
+          b["IBM DB2"] = Set.new %w(db2_autocommit db2_autocommit db2_bind_param db2_client_info db2_close db2_column_privileges db2_columns db2_commit db2_conn_error db2_conn_errormsg db2_connect db2_cursor_type db2_escape_string db2_exec db2_execute db2_fetch_array db2_fetch_assoc db2_fetch_both db2_fetch_object db2_fetch_row db2_field_display_size db2_field_name db2_field_num db2_field_precision db2_field_scale db2_field_type db2_field_width db2_foreign_keys db2_free_result db2_free_stmt db2_get_option db2_last_insert_id db2_lob_read db2_next_result db2_num_fields db2_num_rows db2_pclose db2_pconnect db2_prepare db2_primary_keys db2_procedure_columns db2_procedures db2_result db2_rollback db2_server_info db2_set_option db2_special_columns db2_statistics db2_stmt_error db2_stmt_errormsg db2_table_privileges db2_tables db2_autocommit)
+          b["iconv"] = Set.new %w(iconv_get_encoding iconv_get_encoding iconv_mime_decode_headers iconv_mime_decode iconv_mime_encode iconv_set_encoding iconv_strlen iconv_strpos iconv_strrpos iconv_substr iconv ob_iconv_handler iconv_get_encoding)
+          b["ID3"] = Set.new %w(id3_get_frame_long_name id3_get_frame_long_name id3_get_frame_short_name id3_get_genre_id id3_get_genre_list id3_get_genre_name id3_get_tag id3_get_version id3_remove_tag id3_set_tag id3_get_frame_long_name)
+          b["Informix"] = Set.new %w(ifx_affected_rows ifx_affected_rows ifx_blobinfile_mode ifx_byteasvarchar ifx_close ifx_connect ifx_copy_blob ifx_create_blob ifx_create_char ifx_do ifx_error ifx_errormsg ifx_fetch_row ifx_fieldproperties ifx_fieldtypes ifx_free_blob ifx_free_char ifx_free_result ifx_get_blob ifx_get_char ifx_getsqlca ifx_htmltbl_result ifx_nullformat ifx_num_fields ifx_num_rows ifx_pconnect ifx_prepare ifx_query ifx_textasvarchar ifx_update_blob ifx_update_char ifxus_close_slob ifxus_create_slob ifxus_free_slob ifxus_open_slob ifxus_read_slob ifxus_seek_slob ifxus_tell_slob ifxus_write_slob ifx_affected_rows)
+          b["IIS"] = Set.new %w(iis_add_server iis_add_server iis_get_dir_security iis_get_script_map iis_get_server_by_comment iis_get_server_by_path iis_get_server_rights iis_get_service_state iis_remove_server iis_set_app_settings iis_set_dir_security iis_set_script_map iis_set_server_rights iis_start_server iis_start_service iis_stop_server iis_stop_service iis_add_server)
+          b["GD and Image"] = Set.new %w(gd_info gd_info getimagesize getimagesizefromstring image_type_to_extension image_type_to_mime_type image2wbmp imageaffine imageaffinematrixconcat imageaffinematrixget imagealphablending imageantialias imagearc imagechar imagecharup imagecolorallocate imagecolorallocatealpha imagecolorat imagecolorclosest imagecolorclosestalpha imagecolorclosesthwb imagecolordeallocate imagecolorexact imagecolorexactalpha imagecolormatch imagecolorresolve imagecolorresolvealpha imagecolorset imagecolorsforindex imagecolorstotal imagecolortransparent imageconvolution imagecopy imagecopymerge imagecopymergegray imagecopyresampled imagecopyresized imagecreate imagecreatefromgd2 imagecreatefromgd2part imagecreatefromgd imagecreatefromgif imagecreatefromjpeg imagecreatefrompng imagecreatefromstring imagecreatefromwbmp imagecreatefromwebp imagecreatefromxbm imagecreatefromxpm imagecreatetruecolor imagecrop imagecropauto imagedashedline imagedestroy imageellipse imagefill imagefilledarc imagefilledellipse imagefilledpolygon imagefilledrectangle imagefilltoborder imagefilter imageflip imagefontheight imagefontwidth imageftbbox imagefttext imagegammacorrect imagegd2 imagegd imagegif imagegrabscreen imagegrabwindow imageinterlace imageistruecolor imagejpeg imagelayereffect imageline imageloadfont imagepalettecopy imagepalettetotruecolor imagepng imagepolygon imagepsbbox imagepsencodefont imagepsextendfont imagepsfreefont imagepsloadfont imagepsslantfont imagepstext imagerectangle imagerotate imagesavealpha imagescale imagesetbrush imagesetinterpolation imagesetpixel imagesetstyle imagesetthickness imagesettile imagestring imagestringup imagesx imagesy imagetruecolortopalette imagettfbbox imagettftext imagetypes imagewbmp imagewebp imagexbm iptcembed iptcparse jpeg2wbmp png2wbmp gd_info)
+          b["IMAP"] = Set.new %w(imap_8bit imap_8bit imap_alerts imap_append imap_base64 imap_binary imap_body imap_bodystruct imap_check imap_clearflag_full imap_close imap_create imap_createmailbox imap_delete imap_deletemailbox imap_errors imap_expunge imap_fetch_overview imap_fetchbody imap_fetchheader imap_fetchmime imap_fetchstructure imap_fetchtext imap_gc imap_get_quota imap_get_quotaroot imap_getacl imap_getmailboxes imap_getsubscribed imap_header imap_headerinfo imap_headers imap_last_error imap_list imap_listmailbox imap_listscan imap_listsubscribed imap_lsub imap_mail_compose imap_mail_copy imap_mail_move imap_mail imap_mailboxmsginfo imap_mime_header_decode imap_msgno imap_num_msg imap_num_recent imap_open imap_ping imap_qprint imap_rename imap_renamemailbox imap_reopen imap_rfc822_parse_adrlist imap_rfc822_parse_headers imap_rfc822_write_address imap_savebody imap_scan imap_scanmailbox imap_search imap_set_quota imap_setacl imap_setflag_full imap_sort imap_status imap_subscribe imap_thread imap_timeout imap_uid imap_undelete imap_unsubscribe imap_utf7_decode imap_utf7_encode imap_utf8 imap_8bit)
+          b["inclued"] = Set.new %w(inclued_get_data inclued_get_data inclued_get_data)
+          b["PHP Options/Info"] = Set.new %w(assert_options assert_options assert cli_get_process_title cli_set_process_title dl extension_loaded gc_collect_cycles gc_disable gc_enable gc_enabled get_cfg_var get_current_user get_defined_constants get_extension_funcs get_include_path get_included_files get_loaded_extensions get_magic_quotes_gpc get_magic_quotes_runtime get_required_files getenv getlastmod getmygid getmyinode getmypid getmyuid getopt getrusage ini_alter ini_get_all ini_get ini_restore ini_set magic_quotes_runtime main memory_get_peak_usage memory_get_usage php_ini_loaded_file php_ini_scanned_files php_logo_guid php_sapi_name php_uname phpcredits phpinfo phpversion putenv restore_include_path set_include_path set_magic_quotes_runtime set_time_limit sys_get_temp_dir version_compare zend_logo_guid zend_thread_id zend_version assert_options)
+          b["Ingres"] = Set.new %w(ingres_autocommit_state ingres_autocommit_state ingres_autocommit ingres_charset ingres_close ingres_commit ingres_connect ingres_cursor ingres_errno ingres_error ingres_errsqlstate ingres_escape_string ingres_execute ingres_fetch_array ingres_fetch_assoc ingres_fetch_object ingres_fetch_proc_return ingres_fetch_row ingres_field_length ingres_field_name ingres_field_nullable ingres_field_precision ingres_field_scale ingres_field_type ingres_free_result ingres_next_error ingres_num_fields ingres_num_rows ingres_pconnect ingres_prepare ingres_query ingres_result_seek ingres_rollback ingres_set_environment ingres_unbuffered_query ingres_autocommit_state)
+          b["Inotify"] = Set.new %w(inotify_add_watch inotify_add_watch inotify_init inotify_queue_len inotify_read inotify_rm_watch inotify_add_watch)
+          b["Grapheme"] = Set.new %w(grapheme_extract grapheme_extract grapheme_stripos grapheme_stristr grapheme_strlen grapheme_strpos grapheme_strripos grapheme_strrpos grapheme_strstr grapheme_substr grapheme_extract)
+          b["intl"] = Set.new %w(intl_error_name intl_error_name intl_get_error_code intl_get_error_message intl_is_failure intl_error_name)
+          b["IDN"] = Set.new %w(grapheme_substr idn_to_ascii idn_to_ascii idn_to_unicode idn_to_utf8 grapheme_substr idn_to_ascii)
+          b["Java"] = Set.new %w(java_last_exception_clear java_last_exception_clear java_last_exception_get java_last_exception_clear)
+          b["JSON"] = Set.new %w(json_decode json_decode json_encode json_last_error_msg json_last_error json_decode)
+          b["Judy"] = Set.new %w(judy_type judy_type judy_version judy_type)
+          b["KADM5"] = Set.new %w(kadm5_chpass_principal kadm5_chpass_principal kadm5_create_principal kadm5_delete_principal kadm5_destroy kadm5_flush kadm5_get_policies kadm5_get_principal kadm5_get_principals kadm5_init_with_password kadm5_modify_principal kadm5_chpass_principal)
+          b["LDAP"] = Set.new %w(ldap_8859_to_t61 ldap_8859_to_t61 ldap_add ldap_bind ldap_close ldap_compare ldap_connect ldap_control_paged_result_response ldap_control_paged_result ldap_count_entries ldap_delete ldap_dn2ufn ldap_err2str ldap_errno ldap_error ldap_explode_dn ldap_first_attribute ldap_first_entry ldap_first_reference ldap_free_result ldap_get_attributes ldap_get_dn ldap_get_entries ldap_get_option ldap_get_values_len ldap_get_values ldap_list ldap_mod_add ldap_mod_del ldap_mod_replace ldap_modify ldap_next_attribute ldap_next_entry ldap_next_reference ldap_parse_reference ldap_parse_result ldap_read ldap_rename ldap_sasl_bind ldap_search ldap_set_option ldap_set_rebind_proc ldap_sort ldap_start_tls ldap_t61_to_8859 ldap_unbind ldap_8859_to_t61)
+          b["Libevent"] = Set.new %w(event_add event_add event_base_free event_base_loop event_base_loopbreak event_base_loopexit event_base_new event_base_priority_init event_base_reinit event_base_set event_buffer_base_set event_buffer_disable event_buffer_enable event_buffer_fd_set event_buffer_free event_buffer_new event_buffer_priority_set event_buffer_read event_buffer_set_callback event_buffer_timeout_set event_buffer_watermark_set event_buffer_write event_del event_free event_new event_priority_set event_set event_timer_add event_timer_del event_timer_new event_timer_set event_add)
+          b["libxml"] = Set.new %w(libxml_clear_errors libxml_clear_errors libxml_disable_entity_loader libxml_get_errors libxml_get_last_error libxml_set_external_entity_loader libxml_set_streams_context libxml_use_internal_errors libxml_clear_errors)
+          b["LZF"] = Set.new %w(lzf_compress lzf_compress lzf_decompress lzf_optimized_for lzf_compress)
+          b["Mail"] = Set.new %w(ezmlm_hash ezmlm_hash mail ezmlm_hash)
+          b["Mailparse"] = Set.new %w(mailparse_determine_best_xfer_encoding mailparse_determine_best_xfer_encoding mailparse_msg_create mailparse_msg_extract_part_file mailparse_msg_extract_part mailparse_msg_extract_whole_part_file mailparse_msg_free mailparse_msg_get_part_data mailparse_msg_get_part mailparse_msg_get_structure mailparse_msg_parse_file mailparse_msg_parse mailparse_rfc822_parse_addresses mailparse_stream_encode mailparse_uudecode_all mailparse_determine_best_xfer_encoding)
+          b["Math"] = Set.new %w(abs abs acos acosh asin asinh atan2 atan atanh base_convert bindec ceil cos cosh decbin dechex decoct deg2rad exp expm1 floor fmod getrandmax hexdec hypot is_finite is_infinite is_nan lcg_value log10 log1p log max min mt_getrandmax mt_rand mt_srand octdec pi pow rad2deg rand round sin sinh sqrt srand tan tanh abs)
+          b["MaxDB"] = Set.new %w(maxdb_affected_rows maxdb_affected_rows maxdb_autocommit maxdb_bind_param maxdb_bind_result maxdb_change_user maxdb_character_set_name maxdb_client_encoding maxdb_close_long_data maxdb_close maxdb_commit maxdb_connect_errno maxdb_connect_error maxdb_connect maxdb_data_seek maxdb_debug maxdb_disable_reads_from_master maxdb_disable_rpl_parse maxdb_dump_debug_info maxdb_embedded_connect maxdb_enable_reads_from_master maxdb_enable_rpl_parse maxdb_errno maxdb_error maxdb_escape_string maxdb_execute maxdb_fetch_array maxdb_fetch_assoc maxdb_fetch_field_direct maxdb_fetch_field maxdb_fetch_fields maxdb_fetch_lengths maxdb_fetch_object maxdb_fetch_row maxdb_fetch maxdb_field_count maxdb_field_seek maxdb_field_tell maxdb_free_result maxdb_get_client_info maxdb_get_client_version maxdb_get_host_info maxdb_get_metadata maxdb_get_proto_info maxdb_get_server_info maxdb_get_server_version maxdb_info maxdb_init maxdb_insert_id maxdb_kill maxdb_master_query maxdb_more_results maxdb_multi_query maxdb_next_result maxdb_num_fields maxdb_num_rows maxdb_options maxdb_param_count maxdb_ping maxdb_prepare maxdb_query maxdb_real_connect maxdb_real_escape_string maxdb_real_query maxdb_report maxdb_rollback maxdb_rpl_parse_enabled maxdb_rpl_probe maxdb_rpl_query_type maxdb_select_db maxdb_send_long_data maxdb_send_query maxdb_server_end maxdb_server_init maxdb_set_opt maxdb_sqlstate maxdb_ssl_set maxdb_stat maxdb_stmt_affected_rows maxdb_stmt_bind_param maxdb_stmt_bind_result maxdb_stmt_close_long_data maxdb_stmt_close maxdb_stmt_data_seek maxdb_stmt_errno maxdb_stmt_error maxdb_stmt_execute maxdb_stmt_fetch maxdb_stmt_free_result maxdb_stmt_init maxdb_stmt_num_rows maxdb_stmt_param_count maxdb_stmt_prepare maxdb_stmt_reset maxdb_stmt_result_metadata maxdb_stmt_send_long_data maxdb_stmt_sqlstate maxdb_stmt_store_result maxdb_store_result maxdb_thread_id maxdb_thread_safe maxdb_use_result maxdb_warning_count maxdb_affected_rows)
+          b["Multibyte String"] = Set.new %w(mb_check_encoding mb_check_encoding mb_convert_case mb_convert_encoding mb_convert_kana mb_convert_variables mb_decode_mimeheader mb_decode_numericentity mb_detect_encoding mb_detect_order mb_encode_mimeheader mb_encode_numericentity mb_encoding_aliases mb_ereg_match mb_ereg_replace_callback mb_ereg_replace mb_ereg_search_getpos mb_ereg_search_getregs mb_ereg_search_init mb_ereg_search_pos mb_ereg_search_regs mb_ereg_search_setpos mb_ereg_search mb_ereg mb_eregi_replace mb_eregi mb_get_info mb_http_input mb_http_output mb_internal_encoding mb_language mb_list_encodings mb_output_handler mb_parse_str mb_preferred_mime_name mb_regex_encoding mb_regex_set_options mb_send_mail mb_split mb_strcut mb_strimwidth mb_stripos mb_stristr mb_strlen mb_strpos mb_strrchr mb_strrichr mb_strripos mb_strrpos mb_strstr mb_strtolower mb_strtoupper mb_strwidth mb_substitute_character mb_substr_count mb_substr mb_check_encoding)
+          b["Mcrypt"] = Set.new %w(mcrypt_cbc mcrypt_cbc mcrypt_cfb mcrypt_create_iv mcrypt_decrypt mcrypt_ecb mcrypt_enc_get_algorithms_name mcrypt_enc_get_block_size mcrypt_enc_get_iv_size mcrypt_enc_get_key_size mcrypt_enc_get_modes_name mcrypt_enc_get_supported_key_sizes mcrypt_enc_is_block_algorithm_mode mcrypt_enc_is_block_algorithm mcrypt_enc_is_block_mode mcrypt_enc_self_test mcrypt_encrypt mcrypt_generic_deinit mcrypt_generic_end mcrypt_generic_init mcrypt_generic mcrypt_get_block_size mcrypt_get_cipher_name mcrypt_get_iv_size mcrypt_get_key_size mcrypt_list_algorithms mcrypt_list_modes mcrypt_module_close mcrypt_module_get_algo_block_size mcrypt_module_get_algo_key_size mcrypt_module_get_supported_key_sizes mcrypt_module_is_block_algorithm_mode mcrypt_module_is_block_algorithm mcrypt_module_is_block_mode mcrypt_module_open mcrypt_module_self_test mcrypt_ofb mdecrypt_generic mcrypt_cbc)
+          b["MCVE"] = Set.new %w(m_checkstatus m_checkstatus m_completeauthorizations m_connect m_connectionerror m_deletetrans m_destroyconn m_destroyengine m_getcell m_getcellbynum m_getcommadelimited m_getheader m_initconn m_initengine m_iscommadelimited m_maxconntimeout m_monitor m_numcolumns m_numrows m_parsecommadelimited m_responsekeys m_responseparam m_returnstatus m_setblocking m_setdropfile m_setip m_setssl_cafile m_setssl_files m_setssl m_settimeout m_sslcert_gen_hash m_transactionssent m_transinqueue m_transkeyval m_transnew m_transsend m_uwait m_validateidentifier m_verifyconnection m_verifysslcert m_checkstatus)
+          b["Memcache"] = Set.new %w(memcache_debug memcache_debug memcache_debug)
+          b["Mhash"] = Set.new %w(mhash_count mhash_count mhash_get_block_size mhash_get_hash_name mhash_keygen_s2k mhash mhash_count)
+          b["Ming"] = Set.new %w(ming_keypress ming_keypress ming_setcubicthreshold ming_setscale ming_setswfcompression ming_useconstants ming_useswfversion ming_keypress)
+          b["Misc."] = Set.new %w(connection_aborted connection_aborted connection_status connection_timeout constant define defined die eval exit get_browser __halt_compiler highlight_file highlight_string ignore_user_abort pack php_check_syntax php_strip_whitespace show_source sleep sys_getloadavg time_nanosleep time_sleep_until uniqid unpack usleep connection_aborted)
+          b["mnoGoSearch"] = Set.new %w(udm_add_search_limit udm_add_search_limit udm_alloc_agent_array udm_alloc_agent udm_api_version udm_cat_list udm_cat_path udm_check_charset udm_check_stored udm_clear_search_limits udm_close_stored udm_crc32 udm_errno udm_error udm_find udm_free_agent udm_free_ispell_data udm_free_res udm_get_doc_count udm_get_res_field udm_get_res_param udm_hash32 udm_load_ispell_data udm_open_stored udm_set_agent_param udm_add_search_limit)
+          b["Mongo"] = Set.new %w(bson_decode bson_decode bson_encode bson_decode)
+          b["mqseries"] = Set.new %w(mqseries_back mqseries_back mqseries_begin mqseries_close mqseries_cmit mqseries_conn mqseries_connx mqseries_disc mqseries_get mqseries_inq mqseries_open mqseries_put1 mqseries_put mqseries_set mqseries_strerror mqseries_back)
+          b["Msession"] = Set.new %w(msession_connect msession_connect msession_count msession_create msession_destroy msession_disconnect msession_find msession_get_array msession_get_data msession_get msession_inc msession_list msession_listvar msession_lock msession_plugin msession_randstr msession_set_array msession_set_data msession_set msession_timeout msession_uniq msession_unlock msession_connect)
+          b["mSQL"] = Set.new %w(msql_affected_rows msql_affected_rows msql_close msql_connect msql_create_db msql_createdb msql_data_seek msql_db_query msql_dbname msql_drop_db msql_error msql_fetch_array msql_fetch_field msql_fetch_object msql_fetch_row msql_field_flags msql_field_len msql_field_name msql_field_seek msql_field_table msql_field_type msql_fieldflags msql_fieldlen msql_fieldname msql_fieldtable msql_fieldtype msql_free_result msql_list_dbs msql_list_fields msql_list_tables msql_num_fields msql_num_rows msql_numfields msql_numrows msql_pconnect msql_query msql_regcase msql_result msql_select_db msql_tablename msql msql_affected_rows)
+          b["Mssql"] = Set.new %w(mssql_bind mssql_bind mssql_close mssql_connect mssql_data_seek mssql_execute mssql_fetch_array mssql_fetch_assoc mssql_fetch_batch mssql_fetch_field mssql_fetch_object mssql_fetch_row mssql_field_length mssql_field_name mssql_field_seek mssql_field_type mssql_free_result mssql_free_statement mssql_get_last_message mssql_guid_string mssql_init mssql_min_error_severity mssql_min_message_severity mssql_next_result mssql_num_fields mssql_num_rows mssql_pconnect mssql_query mssql_result mssql_rows_affected mssql_select_db mssql_bind)
+          b["MySQL"] = Set.new %w(mysql_affected_rows mysql_affected_rows mysql_client_encoding mysql_close mysql_connect mysql_create_db mysql_data_seek mysql_db_name mysql_db_query mysql_drop_db mysql_errno mysql_error mysql_escape_string mysql_fetch_array mysql_fetch_assoc mysql_fetch_field mysql_fetch_lengths mysql_fetch_object mysql_fetch_row mysql_field_flags mysql_field_len mysql_field_name mysql_field_seek mysql_field_table mysql_field_type mysql_free_result mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql_insert_id mysql_list_dbs mysql_list_fields mysql_list_processes mysql_list_tables mysql_num_fields mysql_num_rows mysql_pconnect mysql_ping mysql_query mysql_real_escape_string mysql_result mysql_select_db mysql_set_charset mysql_stat mysql_tablename mysql_thread_id mysql_unbuffered_query mysql_affected_rows)
+          b["Aliases and deprecated Mysqli"] = Set.new %w(mysqli_bind_param mysqli_bind_param mysqli_bind_result mysqli_client_encoding mysqli_connect mysqli::disable_reads_from_master mysqli_disable_rpl_parse mysqli_enable_reads_from_master mysqli_enable_rpl_parse mysqli_escape_string mysqli_execute mysqli_fetch mysqli_get_cache_stats mysqli_get_metadata mysqli_master_query mysqli_param_count mysqli_report mysqli_rpl_parse_enabled mysqli_rpl_probe mysqli_send_long_data mysqli::set_opt mysqli_slave_query mysqli_bind_param)
+          b["Mysqlnd_memcache"] = Set.new %w(mysqlnd_memcache_get_config mysqlnd_memcache_get_config mysqlnd_memcache_set mysqlnd_memcache_get_config)
+          b["Mysqlnd_ms"] = Set.new %w(mysqlnd_ms_dump_servers mysqlnd_ms_dump_servers mysqlnd_ms_fabric_select_global mysqlnd_ms_fabric_select_shard mysqlnd_ms_get_last_gtid mysqlnd_ms_get_last_used_connection mysqlnd_ms_get_stats mysqlnd_ms_match_wild mysqlnd_ms_query_is_select mysqlnd_ms_set_qos mysqlnd_ms_set_user_pick_server mysqlnd_ms_xa_begin mysqlnd_ms_xa_commit mysqlnd_ms_xa_gc mysqlnd_ms_xa_rollback mysqlnd_ms_dump_servers)
+          b["mysqlnd_qc"] = Set.new %w(mysqlnd_qc_clear_cache mysqlnd_qc_clear_cache mysqlnd_qc_get_available_handlers mysqlnd_qc_get_cache_info mysqlnd_qc_get_core_stats mysqlnd_qc_get_normalized_query_trace_log mysqlnd_qc_get_query_trace_log mysqlnd_qc_set_cache_condition mysqlnd_qc_set_is_select mysqlnd_qc_set_storage_handler mysqlnd_qc_set_user_handlers mysqlnd_qc_clear_cache)
+          b["Mysqlnd_uh"] = Set.new %w(mysqlnd_uh_convert_to_mysqlnd mysqlnd_uh_convert_to_mysqlnd mysqlnd_uh_set_connection_proxy mysqlnd_uh_set_statement_proxy mysqlnd_uh_convert_to_mysqlnd)
+          b["Ncurses"] = Set.new %w(ncurses_addch ncurses_addch ncurses_addchnstr ncurses_addchstr ncurses_addnstr ncurses_addstr ncurses_assume_default_colors ncurses_attroff ncurses_attron ncurses_attrset ncurses_baudrate ncurses_beep ncurses_bkgd ncurses_bkgdset ncurses_border ncurses_bottom_panel ncurses_can_change_color ncurses_cbreak ncurses_clear ncurses_clrtobot ncurses_clrtoeol ncurses_color_content ncurses_color_set ncurses_curs_set ncurses_def_prog_mode ncurses_def_shell_mode ncurses_define_key ncurses_del_panel ncurses_delay_output ncurses_delch ncurses_deleteln ncurses_delwin ncurses_doupdate ncurses_echo ncurses_echochar ncurses_end ncurses_erase ncurses_erasechar ncurses_filter ncurses_flash ncurses_flushinp ncurses_getch ncurses_getmaxyx ncurses_getmouse ncurses_getyx ncurses_halfdelay ncurses_has_colors ncurses_has_ic ncurses_has_il ncurses_has_key ncurses_hide_panel ncurses_hline ncurses_inch ncurses_init_color ncurses_init_pair ncurses_init ncurses_insch ncurses_insdelln ncurses_insertln ncurses_insstr ncurses_instr ncurses_isendwin ncurses_keyok ncurses_keypad ncurses_killchar ncurses_longname ncurses_meta ncurses_mouse_trafo ncurses_mouseinterval ncurses_mousemask ncurses_move_panel ncurses_move ncurses_mvaddch ncurses_mvaddchnstr ncurses_mvaddchstr ncurses_mvaddnstr ncurses_mvaddstr ncurses_mvcur ncurses_mvdelch ncurses_mvgetch ncurses_mvhline ncurses_mvinch ncurses_mvvline ncurses_mvwaddstr ncurses_napms ncurses_new_panel ncurses_newpad ncurses_newwin ncurses_nl ncurses_nocbreak ncurses_noecho ncurses_nonl ncurses_noqiflush ncurses_noraw ncurses_pair_content ncurses_panel_above ncurses_panel_below ncurses_panel_window ncurses_pnoutrefresh ncurses_prefresh ncurses_putp ncurses_qiflush ncurses_raw ncurses_refresh ncurses_replace_panel ncurses_reset_prog_mode ncurses_reset_shell_mode ncurses_resetty ncurses_savetty ncurses_scr_dump ncurses_scr_init ncurses_scr_restore ncurses_scr_set ncurses_scrl ncurses_show_panel ncurses_slk_attr ncurses_slk_attroff ncurses_slk_attron ncurses_slk_attrset ncurses_slk_clear ncurses_slk_color ncurses_slk_init ncurses_slk_noutrefresh ncurses_slk_refresh ncurses_slk_restore ncurses_slk_set ncurses_slk_touch ncurses_standend ncurses_standout ncurses_start_color ncurses_termattrs ncurses_termname ncurses_timeout ncurses_top_panel ncurses_typeahead ncurses_ungetch ncurses_ungetmouse ncurses_update_panels ncurses_use_default_colors ncurses_use_env ncurses_use_extended_names ncurses_vidattr ncurses_vline ncurses_waddch ncurses_waddstr ncurses_wattroff ncurses_wattron ncurses_wattrset ncurses_wborder ncurses_wclear ncurses_wcolor_set ncurses_werase ncurses_wgetch ncurses_whline ncurses_wmouse_trafo ncurses_wmove ncurses_wnoutrefresh ncurses_wrefresh ncurses_wstandend ncurses_wstandout ncurses_wvline ncurses_addch)
+          b["Gopher"] = Set.new %w(gopher_parsedir gopher_parsedir gopher_parsedir)
+          b["Network"] = Set.new %w(checkdnsrr checkdnsrr closelog define_syslog_variables dns_check_record dns_get_mx dns_get_record fsockopen gethostbyaddr gethostbyname gethostbynamel gethostname getmxrr getprotobyname getprotobynumber getservbyname getservbyport header_register_callback header_remove header headers_list headers_sent http_response_code inet_ntop inet_pton ip2long long2ip openlog pfsockopen setcookie setrawcookie socket_get_status socket_set_blocking socket_set_timeout syslog checkdnsrr)
+          b["Newt"] = Set.new %w(newt_bell newt_bell newt_button_bar newt_button newt_centered_window newt_checkbox_get_value newt_checkbox_set_flags newt_checkbox_set_value newt_checkbox_tree_add_item newt_checkbox_tree_find_item newt_checkbox_tree_get_current newt_checkbox_tree_get_entry_value newt_checkbox_tree_get_multi_selection newt_checkbox_tree_get_selection newt_checkbox_tree_multi newt_checkbox_tree_set_current newt_checkbox_tree_set_entry_value newt_checkbox_tree_set_entry newt_checkbox_tree_set_width newt_checkbox_tree newt_checkbox newt_clear_key_buffer newt_cls newt_compact_button newt_component_add_callback newt_component_takes_focus newt_create_grid newt_cursor_off newt_cursor_on newt_delay newt_draw_form newt_draw_root_text newt_entry_get_value newt_entry_set_filter newt_entry_set_flags newt_entry_set newt_entry newt_finished newt_form_add_component newt_form_add_components newt_form_add_hot_key newt_form_destroy newt_form_get_current newt_form_run newt_form_set_background newt_form_set_height newt_form_set_size newt_form_set_timer newt_form_set_width newt_form_watch_fd newt_form newt_get_screen_size newt_grid_add_components_to_form newt_grid_basic_window newt_grid_free newt_grid_get_size newt_grid_h_close_stacked newt_grid_h_stacked newt_grid_place newt_grid_set_field newt_grid_simple_window newt_grid_v_close_stacked newt_grid_v_stacked newt_grid_wrapped_window_at newt_grid_wrapped_window newt_init newt_label_set_text newt_label newt_listbox_append_entry newt_listbox_clear_selection newt_listbox_clear newt_listbox_delete_entry newt_listbox_get_current newt_listbox_get_selection newt_listbox_insert_entry newt_listbox_item_count newt_listbox_select_item newt_listbox_set_current_by_key newt_listbox_set_current newt_listbox_set_data newt_listbox_set_entry newt_listbox_set_width newt_listbox newt_listitem_get_data newt_listitem_set newt_listitem newt_open_window newt_pop_help_line newt_pop_window newt_push_help_line newt_radio_get_current newt_radiobutton newt_redraw_help_line newt_reflow_text newt_refresh newt_resize_screen newt_resume newt_run_form newt_scale_set newt_scale newt_scrollbar_set newt_set_help_callback newt_set_suspend_callback newt_suspend newt_textbox_get_num_lines newt_textbox_reflowed newt_textbox_set_height newt_textbox_set_text newt_textbox newt_vertical_scrollbar newt_wait_for_key newt_win_choice newt_win_entries newt_win_menu newt_win_message newt_win_messagev newt_win_ternary newt_bell)
+          b["YP/NIS"] = Set.new %w(yp_all yp_all yp_cat yp_err_string yp_errno yp_first yp_get_default_domain yp_master yp_match yp_next yp_order yp_all)
+          b["Lotus Notes"] = Set.new %w(notes_body notes_body notes_copy_db notes_create_db notes_create_note notes_drop_db notes_find_note notes_header_info notes_list_msgs notes_mark_read notes_mark_unread notes_nav_create notes_search notes_unread notes_version notes_body)
+          b["NSAPI"] = Set.new %w(nsapi_request_headers nsapi_request_headers nsapi_response_headers nsapi_virtual nsapi_request_headers)
+          b["OAuth"] = Set.new %w(oauth_get_sbs oauth_get_sbs oauth_urlencode oauth_get_sbs)
+          b["Object Aggregation"] = Set.new %w(aggregate_info aggregate_info aggregate_methods_by_list aggregate_methods_by_regexp aggregate_methods aggregate_properties_by_list aggregate_properties_by_regexp aggregate_properties aggregate aggregation_info deaggregate aggregate_info)
+          b["OCI8"] = Set.new %w(oci_bind_array_by_name oci_bind_array_by_name oci_bind_by_name oci_cancel oci_client_version oci_close oci_commit oci_connect oci_define_by_name oci_error oci_execute oci_fetch_all oci_fetch_array oci_fetch_assoc oci_fetch_object oci_fetch_row oci_fetch oci_field_is_null oci_field_name oci_field_precision oci_field_scale oci_field_size oci_field_type_raw oci_field_type oci_free_descriptor oci_free_statement oci_get_implicit_resultset oci_internal_debug oci_lob_copy oci_lob_is_equal oci_new_collection oci_new_connect oci_new_cursor oci_new_descriptor oci_num_fields oci_num_rows oci_parse oci_password_change oci_pconnect oci_result oci_rollback oci_server_version oci_set_action oci_set_client_identifier oci_set_client_info oci_set_edition oci_set_module_name oci_set_prefetch oci_statement_type oci_bind_array_by_name)
+          b["OPcache"] = Set.new %w(opcache_compile_file opcache_compile_file opcache_get_configuration opcache_get_status opcache_invalidate opcache_reset opcache_compile_file)
+          b["OpenAL"] = Set.new %w(openal_buffer_create openal_buffer_create openal_buffer_data openal_buffer_destroy openal_buffer_get openal_buffer_loadwav openal_context_create openal_context_current openal_context_destroy openal_context_process openal_context_suspend openal_device_close openal_device_open openal_listener_get openal_listener_set openal_source_create openal_source_destroy openal_source_get openal_source_pause openal_source_play openal_source_rewind openal_source_set openal_source_stop openal_stream openal_buffer_create)
+          b["OpenSSL"] = Set.new %w(openssl_cipher_iv_length openssl_cipher_iv_length openssl_csr_export_to_file openssl_csr_export openssl_csr_get_public_key openssl_csr_get_subject openssl_csr_new openssl_csr_sign openssl_decrypt openssl_dh_compute_key openssl_digest openssl_encrypt openssl_error_string openssl_free_key openssl_get_cipher_methods openssl_get_md_methods openssl_get_privatekey openssl_get_publickey openssl_open openssl_pbkdf2 openssl_pkcs12_export_to_file openssl_pkcs12_export openssl_pkcs12_read openssl_pkcs7_decrypt openssl_pkcs7_encrypt openssl_pkcs7_sign openssl_pkcs7_verify openssl_pkey_export_to_file openssl_pkey_export openssl_pkey_free openssl_pkey_get_details openssl_pkey_get_private openssl_pkey_get_public openssl_pkey_new openssl_private_decrypt openssl_private_encrypt openssl_public_decrypt openssl_public_encrypt openssl_random_pseudo_bytes openssl_seal openssl_sign openssl_spki_export_challenge openssl_spki_export openssl_spki_new openssl_spki_verify openssl_verify openssl_x509_check_private_key openssl_x509_checkpurpose openssl_x509_export_to_file openssl_x509_export openssl_x509_free openssl_x509_parse openssl_x509_read openssl_cipher_iv_length)
+          b["Output Control"] = Set.new %w(flush flush ob_clean ob_end_clean ob_end_flush ob_flush ob_get_clean ob_get_contents ob_get_flush ob_get_length ob_get_level ob_get_status ob_gzhandler ob_implicit_flush ob_list_handlers ob_start output_add_rewrite_var output_reset_rewrite_vars flush)
+          b["Ovrimos SQL"] = Set.new %w(ovrimos_close ovrimos_close ovrimos_commit ovrimos_connect ovrimos_cursor ovrimos_exec ovrimos_execute ovrimos_fetch_into ovrimos_fetch_row ovrimos_field_len ovrimos_field_name ovrimos_field_num ovrimos_field_type ovrimos_free_result ovrimos_longreadlen ovrimos_num_fields ovrimos_num_rows ovrimos_prepare ovrimos_result_all ovrimos_result ovrimos_rollback ovrimos_close)
+          b["Paradox"] = Set.new %w(px_close px_close px_create_fp px_date2string px_delete_record px_delete px_get_field px_get_info px_get_parameter px_get_record px_get_schema px_get_value px_insert_record px_new px_numfields px_numrecords px_open_fp px_put_record px_retrieve_record px_set_blob_file px_set_parameter px_set_tablename px_set_targetencoding px_set_value px_timestamp2string px_update_record px_close)
+          b["Parsekit"] = Set.new %w(parsekit_compile_file parsekit_compile_file parsekit_compile_string parsekit_func_arginfo parsekit_compile_file)
+          b["Password Hashing"] = Set.new %w(password_get_info password_get_info password_hash password_needs_rehash password_verify password_get_info)
+          b["PCNTL"] = Set.new %w(pcntl_alarm pcntl_alarm pcntl_errno pcntl_exec pcntl_fork pcntl_get_last_error pcntl_getpriority pcntl_setpriority pcntl_signal_dispatch pcntl_signal pcntl_sigprocmask pcntl_sigtimedwait pcntl_sigwaitinfo pcntl_strerror pcntl_wait pcntl_waitpid pcntl_wexitstatus pcntl_wifexited pcntl_wifsignaled pcntl_wifstopped pcntl_wstopsig pcntl_wtermsig pcntl_alarm)
+          b["PCRE"] = Set.new %w(preg_filter preg_filter preg_grep preg_last_error preg_match_all preg_match preg_quote preg_replace_callback preg_replace preg_split preg_filter)
+          b["PDF"] = Set.new %w(PDF_activate_item PDF_activate_item PDF_add_annotation PDF_add_bookmark PDF_add_launchlink PDF_add_locallink PDF_add_nameddest PDF_add_note PDF_add_outline PDF_add_pdflink PDF_add_table_cell PDF_add_textflow PDF_add_thumbnail PDF_add_weblink PDF_arc PDF_arcn PDF_attach_file PDF_begin_document PDF_begin_font PDF_begin_glyph PDF_begin_item PDF_begin_layer PDF_begin_page_ext PDF_begin_page PDF_begin_pattern PDF_begin_template_ext PDF_begin_template PDF_circle PDF_clip PDF_close_image PDF_close_pdi_page PDF_close_pdi PDF_close PDF_closepath_fill_stroke PDF_closepath_stroke PDF_closepath PDF_concat PDF_continue_text PDF_create_3dview PDF_create_action PDF_create_annotation PDF_create_bookmark PDF_create_field PDF_create_fieldgroup PDF_create_gstate PDF_create_pvf PDF_create_textflow PDF_curveto PDF_define_layer PDF_delete_pvf PDF_delete_table PDF_delete_textflow PDF_delete PDF_encoding_set_char PDF_end_document PDF_end_font PDF_end_glyph PDF_end_item PDF_end_layer PDF_end_page_ext PDF_end_page PDF_end_pattern PDF_end_template PDF_endpath PDF_fill_imageblock PDF_fill_pdfblock PDF_fill_stroke PDF_fill_textblock PDF_fill PDF_findfont PDF_fit_image PDF_fit_pdi_page PDF_fit_table PDF_fit_textflow PDF_fit_textline PDF_get_apiname PDF_get_buffer PDF_get_errmsg PDF_get_errnum PDF_get_font PDF_get_fontname PDF_get_fontsize PDF_get_image_height PDF_get_image_width PDF_get_majorversion PDF_get_minorversion PDF_get_parameter PDF_get_pdi_parameter PDF_get_pdi_value PDF_get_value PDF_info_font PDF_info_matchbox PDF_info_table PDF_info_textflow PDF_info_textline PDF_initgraphics PDF_lineto PDF_load_3ddata PDF_load_font PDF_load_iccprofile PDF_load_image PDF_makespotcolor PDF_moveto PDF_new PDF_open_ccitt PDF_open_file PDF_open_gif PDF_open_image_file PDF_open_image PDF_open_jpeg PDF_open_memory_image PDF_open_pdi_document PDF_open_pdi_page PDF_open_pdi PDF_open_tiff PDF_pcos_get_number PDF_pcos_get_stream PDF_pcos_get_string PDF_place_image PDF_place_pdi_page PDF_process_pdi PDF_rect PDF_restore PDF_resume_page PDF_rotate PDF_save PDF_scale PDF_set_border_color PDF_set_border_dash PDF_set_border_style PDF_set_char_spacing PDF_set_duration PDF_set_gstate PDF_set_horiz_scaling PDF_set_info_author PDF_set_info_creator PDF_set_info_keywords PDF_set_info_subject PDF_set_info_title PDF_set_info PDF_set_layer_dependency PDF_set_leading PDF_set_parameter PDF_set_text_matrix PDF_set_text_pos PDF_set_text_rendering PDF_set_text_rise PDF_set_value PDF_set_word_spacing PDF_setcolor PDF_setdash PDF_setdashpattern PDF_setflat PDF_setfont PDF_setgray_fill PDF_setgray_stroke PDF_setgray PDF_setlinecap PDF_setlinejoin PDF_setlinewidth PDF_setmatrix PDF_setmiterlimit PDF_setpolydash PDF_setrgbcolor_fill PDF_setrgbcolor_stroke PDF_setrgbcolor PDF_shading_pattern PDF_shading PDF_shfill PDF_show_boxed PDF_show_xy PDF_show PDF_skew PDF_stringwidth PDF_stroke PDF_suspend_page PDF_translate PDF_utf16_to_utf8 PDF_utf32_to_utf16 PDF_utf8_to_utf16 PDF_activate_item)
+          b["PostgreSQL"] = Set.new %w(pg_affected_rows pg_affected_rows pg_cancel_query pg_client_encoding pg_close pg_connect pg_connection_busy pg_connection_reset pg_connection_status pg_convert pg_copy_from pg_copy_to pg_dbname pg_delete pg_end_copy pg_escape_bytea pg_escape_identifier pg_escape_literal pg_escape_string pg_execute pg_fetch_all_columns pg_fetch_all pg_fetch_array pg_fetch_assoc pg_fetch_object pg_fetch_result pg_fetch_row pg_field_is_null pg_field_name pg_field_num pg_field_prtlen pg_field_size pg_field_table pg_field_type_oid pg_field_type pg_free_result pg_get_notify pg_get_pid pg_get_result pg_host pg_insert pg_last_error pg_last_notice pg_last_oid pg_lo_close pg_lo_create pg_lo_export pg_lo_import pg_lo_open pg_lo_read_all pg_lo_read pg_lo_seek pg_lo_tell pg_lo_truncate pg_lo_unlink pg_lo_write pg_meta_data pg_num_fields pg_num_rows pg_options pg_parameter_status pg_pconnect pg_ping pg_port pg_prepare pg_put_line pg_query_params pg_query pg_result_error_field pg_result_error pg_result_seek pg_result_status pg_select pg_send_execute pg_send_prepare pg_send_query_params pg_send_query pg_set_client_encoding pg_set_error_verbosity pg_trace pg_transaction_status pg_tty pg_unescape_bytea pg_untrace pg_update pg_version pg_affected_rows)
+          b["POSIX"] = Set.new %w(posix_access posix_access posix_ctermid posix_errno posix_get_last_error posix_getcwd posix_getegid posix_geteuid posix_getgid posix_getgrgid posix_getgrnam posix_getgroups posix_getlogin posix_getpgid posix_getpgrp posix_getpid posix_getppid posix_getpwnam posix_getpwuid posix_getrlimit posix_getsid posix_getuid posix_initgroups posix_isatty posix_kill posix_mkfifo posix_mknod posix_setegid posix_seteuid posix_setgid posix_setpgid posix_setsid posix_setuid posix_strerror posix_times posix_ttyname posix_uname posix_access)
+          b["Printer"] = Set.new %w(printer_abort printer_abort printer_close printer_create_brush printer_create_dc printer_create_font printer_create_pen printer_delete_brush printer_delete_dc printer_delete_font printer_delete_pen printer_draw_bmp printer_draw_chord printer_draw_elipse printer_draw_line printer_draw_pie printer_draw_rectangle printer_draw_roundrect printer_draw_text printer_end_doc printer_end_page printer_get_option printer_list printer_logical_fontheight printer_open printer_select_brush printer_select_font printer_select_pen printer_set_option printer_start_doc printer_start_page printer_write printer_abort)
+          b["Proctitle"] = Set.new %w(setproctitle setproctitle setthreadtitle setproctitle)
+          b["PS"] = Set.new %w(ps_add_bookmark ps_add_bookmark ps_add_launchlink ps_add_locallink ps_add_note ps_add_pdflink ps_add_weblink ps_arc ps_arcn ps_begin_page ps_begin_pattern ps_begin_template ps_circle ps_clip ps_close_image ps_close ps_closepath_stroke ps_closepath ps_continue_text ps_curveto ps_delete ps_end_page ps_end_pattern ps_end_template ps_fill_stroke ps_fill ps_findfont ps_get_buffer ps_get_parameter ps_get_value ps_hyphenate ps_include_file ps_lineto ps_makespotcolor ps_moveto ps_new ps_open_file ps_open_image_file ps_open_image ps_open_memory_image ps_place_image ps_rect ps_restore ps_rotate ps_save ps_scale ps_set_border_color ps_set_border_dash ps_set_border_style ps_set_info ps_set_parameter ps_set_text_pos ps_set_value ps_setcolor ps_setdash ps_setflat ps_setfont ps_setgray ps_setlinecap ps_setlinejoin ps_setlinewidth ps_setmiterlimit ps_setoverprintmode ps_setpolydash ps_shading_pattern ps_shading ps_shfill ps_show_boxed ps_show_xy2 ps_show_xy ps_show2 ps_show ps_string_geometry ps_stringwidth ps_stroke ps_symbol_name ps_symbol_width ps_symbol ps_translate ps_add_bookmark)
+          b["Pspell"] = Set.new %w(pspell_add_to_personal pspell_add_to_personal pspell_add_to_session pspell_check pspell_clear_session pspell_config_create pspell_config_data_dir pspell_config_dict_dir pspell_config_ignore pspell_config_mode pspell_config_personal pspell_config_repl pspell_config_runtogether pspell_config_save_repl pspell_new_config pspell_new_personal pspell_new pspell_save_wordlist pspell_store_replacement pspell_suggest pspell_add_to_personal)
+          b["qtdom"] = Set.new %w(qdom_error qdom_error qdom_tree qdom_error)
+          b["Radius"] = Set.new %w(radius_acct_open radius_acct_open radius_add_server radius_auth_open radius_close radius_config radius_create_request radius_cvt_addr radius_cvt_int radius_cvt_string radius_demangle_mppe_key radius_demangle radius_get_attr radius_get_tagged_attr_data radius_get_tagged_attr_tag radius_get_vendor_attr radius_put_addr radius_put_attr radius_put_int radius_put_string radius_put_vendor_addr radius_put_vendor_attr radius_put_vendor_int radius_put_vendor_string radius_request_authenticator radius_salt_encrypt_attr radius_send_request radius_server_secret radius_strerror radius_acct_open)
+          b["Rar"] = Set.new %w(rar_wrapper_cache_stats rar_wrapper_cache_stats rar_wrapper_cache_stats)
+          b["Readline"] = Set.new %w(readline_add_history readline_add_history readline_callback_handler_install readline_callback_handler_remove readline_callback_read_char readline_clear_history readline_completion_function readline_info readline_list_history readline_on_new_line readline_read_history readline_redisplay readline_write_history readline readline_add_history)
+          b["Recode"] = Set.new %w(recode_file recode_file recode_string recode recode_file)
+          b["POSIX Regex"] = Set.new %w(ereg_replace ereg_replace ereg eregi_replace eregi split spliti sql_regcase ereg_replace)
+          b["RPM Reader"] = Set.new %w(rpm_close rpm_close rpm_get_tag rpm_is_valid rpm_open rpm_version rpm_close)
+          b["RRD"] = Set.new %w(rrd_create rrd_create rrd_error rrd_fetch rrd_first rrd_graph rrd_info rrd_last rrd_lastupdate rrd_restore rrd_tune rrd_update rrd_version rrd_xport rrdc_disconnect rrd_create)
+          b["runkit"] = Set.new %w(runkit_class_adopt runkit_class_emancipate runkit_constant_add runkit_constant_redefine runkit_constant_remove runkit_function_add runkit_function_copy runkit_function_redefine runkit_function_remove runkit_function_rename runkit_import runkit_lint_file runkit_lint runkit_method_add runkit_method_copy runkit_method_redefine runkit_method_remove runkit_method_rename runkit_return_value_used runkit_sandbox_output_handler runkit_superglobals)
+          b["SAM"] = Set.new %w()
+          b["SCA"] = Set.new %w()
+          b["SDO DAS XML"] = Set.new %w()
+          b["SDO"] = Set.new %w()
+          b["SDO-DAS-Relational"] = Set.new %w()
+          b["Semaphore"] = Set.new %w(ftok ftok msg_get_queue msg_queue_exists msg_receive msg_remove_queue msg_send msg_set_queue msg_stat_queue sem_acquire sem_get sem_release sem_remove shm_attach shm_detach shm_get_var shm_has_var shm_put_var shm_remove_var shm_remove ftok)
+          b["Session PgSQL"] = Set.new %w(session_pgsql_add_error session_pgsql_add_error session_pgsql_get_error session_pgsql_get_field session_pgsql_reset session_pgsql_set_field session_pgsql_status session_pgsql_add_error)
+          b["Session"] = Set.new %w(session_cache_expire session_cache_expire session_cache_limiter session_commit session_decode session_destroy session_encode session_get_cookie_params session_id session_is_registered session_module_name session_name session_regenerate_id session_register_shutdown session_register session_save_path session_set_cookie_params session_set_save_handler session_start session_status session_unregister session_unset session_write_close session_cache_expire)
+          b["Shared Memory"] = Set.new %w(shmop_close shmop_close shmop_delete shmop_open shmop_read shmop_size shmop_write shmop_close)
+          b["SimpleXML"] = Set.new %w(simplexml_import_dom simplexml_import_dom simplexml_load_file simplexml_load_string simplexml_import_dom)
+          b["SNMP"] = Set.new %w(snmp_get_quick_print snmp_get_quick_print snmp_get_valueretrieval snmp_read_mib snmp_set_enum_print snmp_set_oid_numeric_print snmp_set_oid_output_format snmp_set_quick_print snmp_set_valueretrieval snmp2_get snmp2_getnext snmp2_real_walk snmp2_set snmp2_walk snmp3_get snmp3_getnext snmp3_real_walk snmp3_set snmp3_walk snmpget snmpgetnext snmprealwalk snmpset snmpwalk snmpwalkoid snmp_get_quick_print)
+          b["SOAP"] = Set.new %w(is_soap_fault is_soap_fault use_soap_error_handler is_soap_fault)
+          b["Socket"] = Set.new %w(socket_accept socket_accept socket_bind socket_clear_error socket_close socket_cmsg_space socket_connect socket_create_listen socket_create_pair socket_create socket_get_option socket_getpeername socket_getsockname socket_import_stream socket_last_error socket_listen socket_read socket_recv socket_recvfrom socket_recvmsg socket_select socket_send socket_sendmsg socket_sendto socket_set_block socket_set_nonblock socket_set_option socket_shutdown socket_strerror socket_write socket_accept)
+          b["Solr"] = Set.new %w(solr_get_version solr_get_version solr_get_version)
+          b["SPL"] = Set.new %w(class_implements class_implements class_parents class_uses iterator_apply iterator_count iterator_to_array spl_autoload_call spl_autoload_extensions spl_autoload_functions spl_autoload_register spl_autoload_unregister spl_autoload spl_classes spl_object_hash class_implements)
+          b["SPPLUS"] = Set.new %w(calcul_hmac calcul_hmac calculhmac nthmac signeurlpaiement calcul_hmac)
+          b["SQLite"] = Set.new %w(sqlite_array_query sqlite_array_query sqlite_busy_timeout sqlite_changes sqlite_close sqlite_column sqlite_create_aggregate sqlite_create_function sqlite_current sqlite_error_string sqlite_escape_string sqlite_exec sqlite_factory sqlite_fetch_all sqlite_fetch_array sqlite_fetch_column_types sqlite_fetch_object sqlite_fetch_single sqlite_fetch_string sqlite_field_name sqlite_has_more sqlite_has_prev sqlite_key sqlite_last_error sqlite_last_insert_rowid sqlite_libencoding sqlite_libversion sqlite_next sqlite_num_fields sqlite_num_rows sqlite_open sqlite_popen sqlite_prev sqlite_query sqlite_rewind sqlite_seek sqlite_single_query sqlite_udf_decode_binary sqlite_udf_encode_binary sqlite_unbuffered_query sqlite_valid sqlite_array_query)
+          b["SQLSRV"] = Set.new %w(sqlsrv_begin_transaction sqlsrv_begin_transaction sqlsrv_cancel sqlsrv_client_info sqlsrv_close sqlsrv_commit sqlsrv_configure sqlsrv_connect sqlsrv_errors sqlsrv_execute sqlsrv_fetch_array sqlsrv_fetch_object sqlsrv_fetch sqlsrv_field_metadata sqlsrv_free_stmt sqlsrv_get_config sqlsrv_get_field sqlsrv_has_rows sqlsrv_next_result sqlsrv_num_fields sqlsrv_num_rows sqlsrv_prepare sqlsrv_query sqlsrv_rollback sqlsrv_rows_affected sqlsrv_send_stream_data sqlsrv_server_info sqlsrv_begin_transaction)
+          b["ssdeep"] = Set.new %w(ssdeep_fuzzy_compare ssdeep_fuzzy_compare ssdeep_fuzzy_hash_filename ssdeep_fuzzy_hash ssdeep_fuzzy_compare)
+          b["SSH2"] = Set.new %w(ssh2_auth_agent ssh2_auth_agent ssh2_auth_hostbased_file ssh2_auth_none ssh2_auth_password ssh2_auth_pubkey_file ssh2_connect ssh2_exec ssh2_fetch_stream ssh2_fingerprint ssh2_methods_negotiated ssh2_publickey_add ssh2_publickey_init ssh2_publickey_list ssh2_publickey_remove ssh2_scp_recv ssh2_scp_send ssh2_sftp_chmod ssh2_sftp_lstat ssh2_sftp_mkdir ssh2_sftp_readlink ssh2_sftp_realpath ssh2_sftp_rename ssh2_sftp_rmdir ssh2_sftp_stat ssh2_sftp_symlink ssh2_sftp_unlink ssh2_sftp ssh2_shell ssh2_tunnel ssh2_auth_agent)
+          b["Statistic"] = Set.new %w(stats_absolute_deviation stats_absolute_deviation stats_cdf_beta stats_cdf_binomial stats_cdf_cauchy stats_cdf_chisquare stats_cdf_exponential stats_cdf_f stats_cdf_gamma stats_cdf_laplace stats_cdf_logistic stats_cdf_negative_binomial stats_cdf_noncentral_chisquare stats_cdf_noncentral_f stats_cdf_poisson stats_cdf_t stats_cdf_uniform stats_cdf_weibull stats_covariance stats_den_uniform stats_dens_beta stats_dens_cauchy stats_dens_chisquare stats_dens_exponential stats_dens_f stats_dens_gamma stats_dens_laplace stats_dens_logistic stats_dens_negative_binomial stats_dens_normal stats_dens_pmf_binomial stats_dens_pmf_hypergeometric stats_dens_pmf_poisson stats_dens_t stats_dens_weibull stats_harmonic_mean stats_kurtosis stats_rand_gen_beta stats_rand_gen_chisquare stats_rand_gen_exponential stats_rand_gen_f stats_rand_gen_funiform stats_rand_gen_gamma stats_rand_gen_ibinomial_negative stats_rand_gen_ibinomial stats_rand_gen_int stats_rand_gen_ipoisson stats_rand_gen_iuniform stats_rand_gen_noncenral_chisquare stats_rand_gen_noncentral_f stats_rand_gen_noncentral_t stats_rand_gen_normal stats_rand_gen_t stats_rand_get_seeds stats_rand_phrase_to_seeds stats_rand_ranf stats_rand_setall stats_skew stats_standard_deviation stats_stat_binomial_coef stats_stat_correlation stats_stat_gennch stats_stat_independent_t stats_stat_innerproduct stats_stat_noncentral_t stats_stat_paired_t stats_stat_percentile stats_stat_powersum stats_variance stats_absolute_deviation)
+          b["Stomp"] = Set.new %w(stomp_connect_error stomp_connect_error stomp_version stomp_connect_error)
+          b["Stream"] = Set.new %w(set_socket_blocking set_socket_blocking stream_bucket_append stream_bucket_make_writeable stream_bucket_new stream_bucket_prepend stream_context_create stream_context_get_default stream_context_get_options stream_context_get_params stream_context_set_default stream_context_set_option stream_context_set_params stream_copy_to_stream stream_encoding stream_filter_append stream_filter_prepend stream_filter_register stream_filter_remove stream_get_contents stream_get_filters stream_get_line stream_get_meta_data stream_get_transports stream_get_wrappers stream_is_local stream_notification_callback stream_register_wrapper stream_resolve_include_path stream_select stream_set_blocking stream_set_chunk_size stream_set_read_buffer stream_set_timeout stream_set_write_buffer stream_socket_accept stream_socket_client stream_socket_enable_crypto stream_socket_get_name stream_socket_pair stream_socket_recvfrom stream_socket_sendto stream_socket_server stream_socket_shutdown stream_supports_lock stream_wrapper_register stream_wrapper_restore stream_wrapper_unregister set_socket_blocking)
+          b["String"] = Set.new %w(addcslashes addcslashes addslashes bin2hex chop chr chunk_split convert_cyr_string convert_uudecode convert_uuencode count_chars crc32 crypt echo explode fprintf get_html_translation_table hebrev hebrevc hex2bin html_entity_decode htmlentities htmlspecialchars_decode htmlspecialchars implode join lcfirst levenshtein localeconv ltrim md5_file md5 metaphone money_format nl_langinfo nl2br number_format ord parse_str print printf quoted_printable_decode quoted_printable_encode quotemeta rtrim setlocale sha1_file sha1 similar_text soundex sprintf sscanf str_getcsv str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split str_word_count strcasecmp strchr strcmp strcoll strcspn strip_tags stripcslashes stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk strpos strrchr strrev strripos strrpos strspn strstr strtok strtolower strtoupper strtr substr_compare substr_count substr_replace substr trim ucfirst ucwords vfprintf vprintf vsprintf wordwrap addcslashes)
+          b["SVN"] = Set.new %w(svn_add svn_add svn_auth_get_parameter svn_auth_set_parameter svn_blame svn_cat svn_checkout svn_cleanup svn_client_version svn_commit svn_delete svn_diff svn_export svn_fs_abort_txn svn_fs_apply_text svn_fs_begin_txn2 svn_fs_change_node_prop svn_fs_check_path svn_fs_contents_changed svn_fs_copy svn_fs_delete svn_fs_dir_entries svn_fs_file_contents svn_fs_file_length svn_fs_is_dir svn_fs_is_file svn_fs_make_dir svn_fs_make_file svn_fs_node_created_rev svn_fs_node_prop svn_fs_props_changed svn_fs_revision_prop svn_fs_revision_root svn_fs_txn_root svn_fs_youngest_rev svn_import svn_log svn_ls svn_mkdir svn_repos_create svn_repos_fs_begin_txn_for_commit svn_repos_fs_commit_txn svn_repos_fs svn_repos_hotcopy svn_repos_open svn_repos_recover svn_revert svn_status svn_update svn_add)
+          b["SWF"] = Set.new %w(swf_actiongeturl swf_actiongeturl swf_actiongotoframe swf_actiongotolabel swf_actionnextframe swf_actionplay swf_actionprevframe swf_actionsettarget swf_actionstop swf_actiontogglequality swf_actionwaitforframe swf_addbuttonrecord swf_addcolor swf_closefile swf_definebitmap swf_definefont swf_defineline swf_definepoly swf_definerect swf_definetext swf_endbutton swf_enddoaction swf_endshape swf_endsymbol swf_fontsize swf_fontslant swf_fonttracking swf_getbitmapinfo swf_getfontinfo swf_getframe swf_labelframe swf_lookat swf_modifyobject swf_mulcolor swf_nextid swf_oncondition swf_openfile swf_ortho2 swf_ortho swf_perspective swf_placeobject swf_polarview swf_popmatrix swf_posround swf_pushmatrix swf_removeobject swf_rotate swf_scale swf_setfont swf_setframe swf_shapearc swf_shapecurveto3 swf_shapecurveto swf_shapefillbitmapclip swf_shapefillbitmaptile swf_shapefilloff swf_shapefillsolid swf_shapelinesolid swf_shapelineto swf_shapemoveto swf_showframe swf_startbutton swf_startdoaction swf_startshape swf_startsymbol swf_textwidth swf_translate swf_viewport swf_actiongeturl)
+          b["Swish"] = Set.new %w()
+          b["Sybase"] = Set.new %w(sybase_affected_rows sybase_affected_rows sybase_close sybase_connect sybase_data_seek sybase_deadlock_retry_count sybase_fetch_array sybase_fetch_assoc sybase_fetch_field sybase_fetch_object sybase_fetch_row sybase_field_seek sybase_free_result sybase_get_last_message sybase_min_client_severity sybase_min_error_severity sybase_min_message_severity sybase_min_server_severity sybase_num_fields sybase_num_rows sybase_pconnect sybase_query sybase_result sybase_select_db sybase_set_message_handler sybase_unbuffered_query sybase_affected_rows)
+          b["Taint"] = Set.new %w(is_tainted is_tainted taint untaint is_tainted)
+          b["TCP"] = Set.new %w(tcpwrap_check tcpwrap_check tcpwrap_check)
+          b["Tidy"] = Set.new %w(ob_tidyhandler ob_tidyhandler tidy_access_count tidy_config_count tidy_error_count tidy_get_output tidy_load_config tidy_reset_config tidy_save_config tidy_set_encoding tidy_setopt tidy_warning_count ob_tidyhandler)
+          b["Tokenizer"] = Set.new %w(token_get_all token_get_all token_name token_get_all)
+          b["Trader"] = Set.new %w(trader_acos trader_acos trader_ad trader_add trader_adosc trader_adx trader_adxr trader_apo trader_aroon trader_aroonosc trader_asin trader_atan trader_atr trader_avgprice trader_bbands trader_beta trader_bop trader_cci trader_cdl2crows trader_cdl3blackcrows trader_cdl3inside trader_cdl3linestrike trader_cdl3outside trader_cdl3starsinsouth trader_cdl3whitesoldiers trader_cdlabandonedbaby trader_cdladvanceblock trader_cdlbelthold trader_cdlbreakaway trader_cdlclosingmarubozu trader_cdlconcealbabyswall trader_cdlcounterattack trader_cdldarkcloudcover trader_cdldoji trader_cdldojistar trader_cdldragonflydoji trader_cdlengulfing trader_cdleveningdojistar trader_cdleveningstar trader_cdlgapsidesidewhite trader_cdlgravestonedoji trader_cdlhammer trader_cdlhangingman trader_cdlharami trader_cdlharamicross trader_cdlhighwave trader_cdlhikkake trader_cdlhikkakemod trader_cdlhomingpigeon trader_cdlidentical3crows trader_cdlinneck trader_cdlinvertedhammer trader_cdlkicking trader_cdlkickingbylength trader_cdlladderbottom trader_cdllongleggeddoji trader_cdllongline trader_cdlmarubozu trader_cdlmatchinglow trader_cdlmathold trader_cdlmorningdojistar trader_cdlmorningstar trader_cdlonneck trader_cdlpiercing trader_cdlrickshawman trader_cdlrisefall3methods trader_cdlseparatinglines trader_cdlshootingstar trader_cdlshortline trader_cdlspinningtop trader_cdlstalledpattern trader_cdlsticksandwich trader_cdltakuri trader_cdltasukigap trader_cdlthrusting trader_cdltristar trader_cdlunique3river trader_cdlupsidegap2crows trader_cdlxsidegap3methods trader_ceil trader_cmo trader_correl trader_cos trader_cosh trader_dema trader_div trader_dx trader_ema trader_errno trader_exp trader_floor trader_get_compat trader_get_unstable_period trader_ht_dcperiod trader_ht_dcphase trader_ht_phasor trader_ht_sine trader_ht_trendline trader_ht_trendmode trader_kama trader_linearreg_angle trader_linearreg_intercept trader_linearreg_slope trader_linearreg trader_ln trader_log10 trader_ma trader_macd trader_macdext trader_macdfix trader_mama trader_mavp trader_max trader_maxindex trader_medprice trader_mfi trader_midpoint trader_midprice trader_min trader_minindex trader_minmax trader_minmaxindex trader_minus_di trader_minus_dm trader_mom trader_mult trader_natr trader_obv trader_plus_di trader_plus_dm trader_ppo trader_roc trader_rocp trader_rocr100 trader_rocr trader_rsi trader_sar trader_sarext trader_set_compat trader_set_unstable_period trader_sin trader_sinh trader_sma trader_sqrt trader_stddev trader_stoch trader_stochf trader_stochrsi trader_sub trader_sum trader_t3 trader_tan trader_tanh trader_tema trader_trange trader_trima trader_trix trader_tsf trader_typprice trader_ultosc trader_var trader_wclprice trader_willr trader_wma trader_acos)
+          b["ODBC"] = Set.new %w(odbc_autocommit odbc_autocommit odbc_binmode odbc_close_all odbc_close odbc_columnprivileges odbc_columns odbc_commit odbc_connect odbc_cursor odbc_data_source odbc_do odbc_error odbc_errormsg odbc_exec odbc_execute odbc_fetch_array odbc_fetch_into odbc_fetch_object odbc_fetch_row odbc_field_len odbc_field_name odbc_field_num odbc_field_precision odbc_field_scale odbc_field_type odbc_foreignkeys odbc_free_result odbc_gettypeinfo odbc_longreadlen odbc_next_result odbc_num_fields odbc_num_rows odbc_pconnect odbc_prepare odbc_primarykeys odbc_procedurecolumns odbc_procedures odbc_result_all odbc_result odbc_rollback odbc_setoption odbc_specialcolumns odbc_statistics odbc_tableprivileges odbc_tables odbc_autocommit)
+          b["Uopz"] = Set.new %w(uopz_backup uopz_backup uopz_compose uopz_copy uopz_delete uopz_extend uopz_flags uopz_function uopz_implement uopz_overload uopz_redefine uopz_rename uopz_restore uopz_undefine uopz_backup)
+          b["URL"] = Set.new %w(base64_decode base64_decode base64_encode get_headers get_meta_tags http_build_query parse_url rawurldecode rawurlencode urldecode urlencode base64_decode)
+          b["Variable handling"] = Set.new %w(boolval boolval debug_zval_dump doubleval empty floatval get_defined_vars get_resource_type gettype import_request_variables intval is_array is_bool is_callable is_double is_float is_int is_integer is_long is_null is_numeric is_object is_real is_resource is_scalar is_string isset print_r serialize settype strval unserialize unset var_dump var_export boolval)
+          b["vpopmail"] = Set.new %w(vpopmail_add_alias_domain_ex vpopmail_add_alias_domain_ex vpopmail_add_alias_domain vpopmail_add_domain_ex vpopmail_add_domain vpopmail_add_user vpopmail_alias_add vpopmail_alias_del_domain vpopmail_alias_del vpopmail_alias_get_all vpopmail_alias_get vpopmail_auth_user vpopmail_del_domain_ex vpopmail_del_domain vpopmail_del_user vpopmail_error vpopmail_passwd vpopmail_set_user_quota vpopmail_add_alias_domain_ex)
+          b["W32api"] = Set.new %w(w32api_deftype w32api_deftype w32api_init_dtype w32api_invoke_function w32api_register_function w32api_set_call_method w32api_deftype)
+          b["WDDX"] = Set.new %w(wddx_add_vars wddx_add_vars wddx_deserialize wddx_packet_end wddx_packet_start wddx_serialize_value wddx_serialize_vars wddx_add_vars)
+          b["win32ps"] = Set.new %w(win32_ps_list_procs win32_ps_list_procs win32_ps_stat_mem win32_ps_stat_proc win32_ps_list_procs)
+          b["win32service"] = Set.new %w(win32_continue_service win32_continue_service win32_create_service win32_delete_service win32_get_last_control_message win32_pause_service win32_query_service_status win32_set_service_status win32_start_service_ctrl_dispatcher win32_start_service win32_stop_service win32_continue_service)
+          b["WinCache"] = Set.new %w(wincache_fcache_fileinfo wincache_fcache_fileinfo wincache_fcache_meminfo wincache_lock wincache_ocache_fileinfo wincache_ocache_meminfo wincache_refresh_if_changed wincache_rplist_fileinfo wincache_rplist_meminfo wincache_scache_info wincache_scache_meminfo wincache_ucache_add wincache_ucache_cas wincache_ucache_clear wincache_ucache_dec wincache_ucache_delete wincache_ucache_exists wincache_ucache_get wincache_ucache_inc wincache_ucache_info wincache_ucache_meminfo wincache_ucache_set wincache_unlock wincache_fcache_fileinfo)
+          b["xattr"] = Set.new %w(xattr_get xattr_get xattr_list xattr_remove xattr_set xattr_supported xattr_get)
+          b["xdiff"] = Set.new %w(xdiff_file_bdiff_size xdiff_file_bdiff_size xdiff_file_bdiff xdiff_file_bpatch xdiff_file_diff_binary xdiff_file_diff xdiff_file_merge3 xdiff_file_patch_binary xdiff_file_patch xdiff_file_rabdiff xdiff_string_bdiff_size xdiff_string_bdiff xdiff_string_bpatch xdiff_string_diff_binary xdiff_string_diff xdiff_string_merge3 xdiff_string_patch_binary xdiff_string_patch xdiff_string_rabdiff xdiff_file_bdiff_size)
+          b["Xhprof"] = Set.new %w(xhprof_disable xhprof_disable xhprof_enable xhprof_sample_disable xhprof_sample_enable xhprof_disable)
+          b["XML Parser"] = Set.new %w(utf8_decode utf8_decode utf8_encode xml_error_string xml_get_current_byte_index xml_get_current_column_number xml_get_current_line_number xml_get_error_code xml_parse_into_struct xml_parse xml_parser_create_ns xml_parser_create xml_parser_free xml_parser_get_option xml_parser_set_option xml_set_character_data_handler xml_set_default_handler xml_set_element_handler xml_set_end_namespace_decl_handler xml_set_external_entity_ref_handler xml_set_notation_decl_handler xml_set_object xml_set_processing_instruction_handler xml_set_start_namespace_decl_handler xml_set_unparsed_entity_decl_handler utf8_decode)
+          b["XML-RPC"] = Set.new %w(xmlrpc_decode_request xmlrpc_decode_request xmlrpc_decode xmlrpc_encode_request xmlrpc_encode xmlrpc_get_type xmlrpc_is_fault xmlrpc_parse_method_descriptions xmlrpc_server_add_introspection_data xmlrpc_server_call_method xmlrpc_server_create xmlrpc_server_destroy xmlrpc_server_register_introspection_callback xmlrpc_server_register_method xmlrpc_set_type xmlrpc_decode_request)
+          b["XMLWriter"] = Set.new %w(XMLWriter::endAttribute XMLWriter::endAttribute XMLWriter::endCData XMLWriter::endComment XMLWriter::endDocument XMLWriter::endDTDAttlist XMLWriter::endDTDElement XMLWriter::endDTDEntity XMLWriter::endDTD XMLWriter::endElement XMLWriter::endPI XMLWriter::flush XMLWriter::fullEndElement XMLWriter::openMemory XMLWriter::openURI XMLWriter::outputMemory XMLWriter::setIndentString XMLWriter::setIndent XMLWriter::startAttributeNS XMLWriter::startAttribute XMLWriter::startCData XMLWriter::startComment XMLWriter::startDocument XMLWriter::startDTDAttlist XMLWriter::startDTDElement XMLWriter::startDTDEntity XMLWriter::startDTD XMLWriter::startElementNS XMLWriter::startElement XMLWriter::startPI XMLWriter::text XMLWriter::writeAttributeNS XMLWriter::writeAttribute XMLWriter::writeCData XMLWriter::writeComment XMLWriter::writeDTDAttlist XMLWriter::writeDTDElement XMLWriter::writeDTDEntity XMLWriter::writeDTD XMLWriter::writeElementNS XMLWriter::writeElement XMLWriter::writePI XMLWriter::writeRaw XMLWriter::endAttribute)
+          b["XSLT (PHP 4)"] = Set.new %w(xslt_backend_info xslt_backend_info xslt_backend_name xslt_backend_version xslt_create xslt_errno xslt_error xslt_free xslt_getopt xslt_process xslt_set_base xslt_set_encoding xslt_set_error_handler xslt_set_log xslt_set_object xslt_set_sax_handler xslt_set_sax_handlers xslt_set_scheme_handler xslt_set_scheme_handlers xslt_setopt xslt_backend_info)
+          b["Yaml"] = Set.new %w(yaml_emit_file yaml_emit_file yaml_emit yaml_parse_file yaml_parse_url yaml_parse yaml_emit_file)
+          b["YAZ"] = Set.new %w(yaz_addinfo yaz_addinfo yaz_ccl_conf yaz_ccl_parse yaz_close yaz_connect yaz_database yaz_element yaz_errno yaz_error yaz_es_result yaz_es yaz_get_option yaz_hits yaz_itemorder yaz_present yaz_range yaz_record yaz_scan_result yaz_scan yaz_schema yaz_search yaz_set_option yaz_sort yaz_syntax yaz_wait yaz_addinfo)
+          b["Zip"] = Set.new %w(zip_close zip_close zip_entry_close zip_entry_compressedsize zip_entry_compressionmethod zip_entry_filesize zip_entry_name zip_entry_open zip_entry_read zip_open zip_read zip_close)
+          b["Zlib"] = Set.new %w(gzclose gzclose gzcompress gzdecode gzdeflate gzencode gzeof gzfile gzgetc gzgets gzgetss gzinflate gzopen gzpassthru gzputs gzread gzrewind gzseek gztell gzuncompress gzwrite readgzfile zlib_decode zlib_encode zlib_get_coding_type gzclose)
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/plain_text.rb b/app/server/vendor/rouge/lib/rouge/lexers/plain_text.rb
new file mode 100755
index 0000000..ba5f1f1
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/plain_text.rb
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class PlainText < Lexer
+      desc "A boring lexer that doesn't highlight anything"
+
+      tag 'plaintext'
+      aliases 'text'
+      filenames '*.txt'
+      mimetypes 'text/plain'
+
+      default_options :token => 'Text'
+
+      def token
+        @token ||= Token[option :token]
+      end
+
+      def stream_tokens(string, &b)
+        yield self.token, string
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/prolog.rb b/app/server/vendor/rouge/lib/rouge/lexers/prolog.rb
new file mode 100755
index 0000000..5264a67
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/prolog.rb
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Prolog < RegexLexer
+      desc "The Prolog programming language (http://en.wikipedia.org/wiki/Prolog)"
+      tag 'prolog'
+      aliases 'prolog'
+      filenames '*.pro', '*.P', '*.prolog', '*.pl'
+      mimetypes 'text/x-prolog'
+
+      def self.analyze_text(text)
+        return 0.1 if text =~ /\A\w+(\(\w+\,\s*\w+\))*\./
+        return 0.1 if text.include? ':-'
+      end
+
+      state :basic do
+        rule /\s+/, Text
+        rule /^#.*/, Comment::Single
+        rule /\/\*/, Comment::Multiline, :nested_comment
+
+        rule /[\[\](){}|.,;!]/, Punctuation
+        rule /:-|-->/, Punctuation
+
+        rule /"[^"]*"/, Str::Double
+
+        rule /\d+\.\d+/, Num::Float
+        rule /\d+/, Num
+      end
+
+      state :atoms do
+        rule /[[:lower:]]([_[:lower:][:digit:]])*/, Str::Symbol
+        rule /'[^']*'/, Str::Symbol
+      end
+
+      state :operators do
+        rule /(<|>|=<|>=|==|=:=|=|\/|\/\/|\*|\+|-)(?=\s|[a-zA-Z0-9\[])/,
+          Operator
+        rule /is/, Operator
+        rule /(mod|div|not)/, Operator
+        rule /[#&*+-.\/:<=>?@^~]+/, Operator
+      end
+
+      state :variables do
+        rule /[A-Z]+\w*/, Name::Variable
+        rule /_[[:word:]]*/, Name::Variable
+      end
+
+      state :root do
+        mixin :basic
+        mixin :atoms
+        mixin :variables
+        mixin :operators
+      end
+
+      state :nested_comment do
+        rule /\/\*/, Comment::Multiline, :push
+        rule /\s*\*[^*\/]+/, Comment::Multiline
+        rule /\*\//, Comment::Multiline, :pop!
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/properties.rb b/app/server/vendor/rouge/lib/rouge/lexers/properties.rb
new file mode 100755
index 0000000..a20ba85
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/properties.rb
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Properties < RegexLexer
+      desc '.properties config files for Java'
+      tag 'properties'
+
+      filenames '*.properties'
+      mimetypes 'text/x-java-properties'
+
+      def self.analyze_text(text)
+        return 0.1 if text =~ /\A\[[\w.]+\]\s*\w+=\w+/
+      end
+
+      identifier = /[\w.]+/
+
+      state :basic do
+        rule /[!#].*?\n/, Comment
+        rule /\s+/, Text
+        rule /\\\n/, Str::Escape
+      end
+
+      state :root do
+        mixin :basic
+
+        rule /(#{identifier})(\s*)([=:])/ do
+          groups Name::Property, Text, Punctuation
+          push :value
+        end
+      end
+
+      state :value do
+        rule /\n/, Text, :pop!
+        mixin :basic
+        rule /"/, Str, :dq
+        rule /'.*?'/, Str
+        mixin :esc_str
+        rule /[^\\\n]+/, Str
+      end
+
+      state :dq do
+        rule /"/, Str, :pop!
+        mixin :esc_str
+        rule /[^\\"]+/m, Str
+      end
+
+      state :esc_str do
+        rule /\\u[0-9]{4}/, Str::Escape
+        rule /\\./m, Str::Escape
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/puppet.rb b/app/server/vendor/rouge/lib/rouge/lexers/puppet.rb
new file mode 100755
index 0000000..06103b2
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/puppet.rb
@@ -0,0 +1,127 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Puppet < RegexLexer
+      desc 'The Puppet configuration management language (puppetlabs.org)'
+      tag 'puppet'
+      aliases 'pp'
+      filenames '*.pp'
+
+      def self.analyze_text(text)
+        return 1 if text.shebang? 'puppet-apply'
+        return 1 if text.shebang? 'puppet'
+      end
+
+      def self.keywords
+        @keywords ||= Set.new %w(
+          and case class default define else elsif if in import inherits
+          node unless
+        )
+      end
+
+      def self.constants
+        @constants ||= Set.new %w(
+          false true undef
+        )
+      end
+
+      def self.metaparameters
+        @metaparameters ||= Set.new %w(
+          before require notify subscribe
+        )
+      end
+
+      id = /[a-z]\w*/
+      cap_id = /[A-Z]\w*/
+      qualname = /(::)?(#{id}::)*\w+/
+
+      state :whitespace do
+        rule /\s+/m, Text
+        rule /#.*?\n/, Comment
+      end
+
+      state :root do
+        mixin :whitespace
+
+        rule /[$]#{qualname}/, Name::Variable
+        rule /(#{id})(?=\s*[=+]>)/m do |m|
+          if self.class.metaparameters.include? m[0]
+            token Keyword::Pseudo
+          else
+            token Name::Property
+          end
+        end
+
+        rule /(#{qualname})(?=\s*[(])/m, Name::Function
+        rule cap_id, Name::Class
+
+        rule /[+=|~-]>|<[|~-]/, Punctuation
+        rule /[:}();\[\]]/, Punctuation
+
+        # HACK for case statements and selectors
+        rule /{/, Punctuation, :regex_allowed
+        rule /,/, Punctuation, :regex_allowed
+
+        rule /(in|and|or)\b/, Operator::Word
+        rule /[=!<>]=/, Operator
+        rule /[=!]~/, Operator, :regex_allowed
+        rule %r([<>!+*/-]), Operator
+
+        rule /(class|include)(\s*)(#{qualname})/ do
+          groups Keyword, Text, Name::Class
+        end
+
+        rule /node\b/, Keyword, :regex_allowed
+
+        rule /'(\\[\\']|[^'])*'/m, Str::Single
+        rule /"/, Str::Double, :dquotes
+
+        rule /\d+([.]\d+)?(e[+-]\d+)?/, Num
+
+        # a valid regex.  TODO: regexes are only allowed
+        # in certain places in puppet.
+        rule qualname do |m|
+          if self.class.keywords.include? m[0]
+            token Keyword
+          elsif self.class.constants.include? m[0]
+            token Keyword::Constant
+          else
+            token Name
+          end
+        end
+      end
+
+      state :regex_allowed do
+        mixin :whitespace
+        rule %r(/), Str::Regex, :regex
+
+        rule(//) { pop! }
+      end
+
+      state :regex do
+        rule %r(/), Str::Regex, :pop!
+        rule /\\./, Str::Escape
+        rule /[(){}]/, Str::Interpol
+        rule /\[/, Str::Interpol, :regex_class
+        rule /./, Str::Regex
+      end
+
+      state :regex_class do
+        rule /\]/, Str::Interpol, :pop!
+        rule /(?<!\[)-(?=\])/, Str::Regex
+        rule /-/, Str::Interpol
+        rule /\\./, Str::Escape
+        rule /[^\\\]-]+/, Str::Regex
+      end
+
+      state :dquotes do
+        rule /"/, Str::Double, :pop!
+        rule /[^$\\"]+/m, Str::Double
+        rule /\\./m, Str::Escape
+        rule /[$]#{qualname}/, Name::Variable
+        rule /[$][{]#{qualname}[}]/, Name::Variable
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/python.rb b/app/server/vendor/rouge/lib/rouge/lexers/python.rb
new file mode 100755
index 0000000..ba8d512
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/python.rb
@@ -0,0 +1,227 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Python < RegexLexer
+      desc "The Python programming language (python.org)"
+      tag 'python'
+      aliases 'py'
+      filenames '*.py', '*.pyw', '*.sc', 'SConstruct', 'SConscript', '*.tac'
+      mimetypes 'text/x-python', 'application/x-python'
+
+      def self.analyze_text(text)
+        return 1 if text.shebang?(/pythonw?(3|2(\.\d)?)?/)
+      end
+
+      def self.keywords
+        @keywords ||= %w(
+          assert break continue del elif else except exec
+          finally for global if lambda pass print raise
+          return try while yield as with
+        )
+      end
+
+      def self.builtins
+        @builtins ||= %w(
+          __import__ abs all any apply basestring bin bool buffer
+          bytearray bytes callable chr classmethod cmp coerce compile
+          complex delattr dict dir divmod enumerate eval execfile exit
+          file filter float frozenset getattr globals hasattr hash hex id
+          input int intern isinstance issubclass iter len list locals
+          long map max min next object oct open ord pow property range
+          raw_input reduce reload repr reversed round set setattr slice
+          sorted staticmethod str sum super tuple type unichr unicode
+          vars xrange zip
+        )
+      end
+
+      def self.builtins_pseudo
+        @builtins_pseudo ||= %w(self None Ellipsis NotImplemented False True)
+      end
+
+      def self.exceptions
+        @exceptions ||= %w(
+          ArithmeticError AssertionError AttributeError
+          BaseException DeprecationWarning EOFError EnvironmentError
+          Exception FloatingPointError FutureWarning GeneratorExit IOError
+          ImportError ImportWarning IndentationError IndexError KeyError
+          KeyboardInterrupt LookupError MemoryError NameError
+          NotImplemented NotImplementedError OSError OverflowError
+          OverflowWarning PendingDeprecationWarning ReferenceError
+          RuntimeError RuntimeWarning StandardError StopIteration
+          SyntaxError SyntaxWarning SystemError SystemExit TabError
+          TypeError UnboundLocalError UnicodeDecodeError
+          UnicodeEncodeError UnicodeError UnicodeTranslateError
+          UnicodeWarning UserWarning ValueError VMSError Warning
+          WindowsError ZeroDivisionError
+        )
+      end
+
+      identifier =        /[a-z_][a-z0-9_]*/i
+      dotted_identifier = /[a-z_.][a-z0-9_.]*/i
+      state :root do
+        rule /\n+/m, Text
+        rule /^(:)(\s*)([ru]{,2}""".*?""")/mi do
+          groups Punctuation, Text, Str::Doc
+        end
+
+        rule /[^\S\n]+/, Text
+        rule /#.*$/, Comment
+        rule /[\[\]{}:(),;]/, Punctuation
+        rule /\\\n/, Text
+        rule /\\/, Text
+
+        rule /(in|is|and|or|not)\b/, Operator::Word
+        rule /!=|==|<<|>>|[-~+\/*%=<>&^|.]/, Operator
+
+        rule /(def)((?:\s|\\\s)+)/ do
+          groups Keyword, Text
+          push :funcname
+        end
+
+        rule /(class)((?:\s|\\\s)+)/ do
+          groups Keyword, Text
+          push :classname
+        end
+
+        rule /(from)((?:\s|\\\s)+)/ do
+          groups Keyword::Namespace, Text
+          push :fromimport
+        end
+
+        rule /(import)((?:\s|\\\s)+)/ do
+          groups Keyword::Namespace, Text
+          push :import
+        end
+
+        # TODO: not in python 3
+        rule /`.*?`/, Str::Backtick
+        rule /(?:r|ur|ru)"""/i, Str, :tdqs
+        rule /(?:r|ur|ru)'''/i, Str, :tsqs
+        rule /(?:r|ur|ru)"/i,   Str, :dqs
+        rule /(?:r|ur|ru)'/i,   Str, :sqs
+        rule /u?"""/i,          Str, :escape_tdqs
+        rule /u?'''/i,          Str, :escape_tsqs
+        rule /u?"/i,            Str, :escape_dqs
+        rule /u?'/i,            Str, :escape_sqs
+
+        rule /@#{dotted_identifier}/i, Name::Decorator
+
+        # using negative lookbehind so we don't match property names
+        rule /(?<!\.)#{identifier}/ do |m|
+          if self.class.keywords.include? m[0]
+            token Keyword
+          elsif self.class.exceptions.include? m[0]
+            token Name::Builtin
+          elsif self.class.builtins.include? m[0]
+            token Name::Builtin
+          elsif self.class.builtins_pseudo.include? m[0]
+            token Name::Builtin::Pseudo
+          else
+            token Name
+          end
+        end
+
+        rule identifier, Name
+
+        rule /(\d+\.\d*|\d*\.\d+)(e[+-]?[0-9]+)?/i, Num::Float
+        rule /\d+e[+-]?[0-9]+/i, Num::Float
+        rule /0[0-7]+/, Num::Oct
+        rule /0x[a-f0-9]+/i, Num::Hex
+        rule /\d+L/, Num::Integer::Long
+        rule /\d+/, Num::Integer
+      end
+
+      state :funcname do
+        rule identifier, Name::Function, :pop!
+      end
+
+      state :classname do
+        rule identifier, Name::Class, :pop!
+      end
+
+      state :import do
+        # non-line-terminating whitespace
+        rule /(?:[ \t]|\\\n)+/, Text
+
+        rule /as\b/, Keyword::Namespace
+        rule /,/, Operator
+        rule dotted_identifier, Name::Namespace
+        rule(//) { pop! } # anything else -> go back
+      end
+
+      state :fromimport do
+        # non-line-terminating whitespace
+        rule /(?:[ \t]|\\\n)+/, Text
+
+        rule /import\b/, Keyword::Namespace, :pop!
+        rule dotted_identifier, Name::Namespace
+      end
+
+      state :strings do
+        rule /%(\([a-z0-9_]+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?/i, Str::Interpol
+      end
+
+      state :strings_double do
+        rule /[^\\"%\n]+/, Str
+        mixin :strings
+      end
+
+      state :strings_single do
+        rule /[^\\'%\n]+/, Str
+        mixin :strings
+      end
+
+      state :nl do
+        rule /\n/, Str
+      end
+
+      state :escape do
+        rule %r(\\
+          ( [\\abfnrtv"']
+          | \n
+          | N{.*?}
+          | u[a-fA-F0-9]{4}
+          | U[a-fA-F0-9]{8}
+          | x[a-fA-F0-9]{2}
+          | [0-7]{1,3}
+          )
+        )x, Str::Escape
+      end
+
+      state :dqs do
+        rule /"/, Str, :pop!
+        rule /\\\\|\\"|\\\n/, Str::Escape
+        mixin :strings_double
+      end
+
+      state :sqs do
+        rule /'/, Str, :pop!
+        rule /\\\\|\\'|\\\n/, Str::Escape
+        mixin :strings_single
+      end
+
+      state :tdqs do
+        rule /"""/, Str, :pop!
+        rule /"/, Str
+        mixin :strings_double
+        mixin :nl
+      end
+
+      state :tsqs do
+        rule /'''/, Str, :pop!
+        rule /'/, Str
+        mixin :strings_single
+        mixin :nl
+      end
+
+      %w(tdqs tsqs dqs sqs).each do |qtype|
+        state :"escape_#{qtype}" do
+          mixin :escape
+          mixin :"#{qtype}"
+        end
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/qml.rb b/app/server/vendor/rouge/lib/rouge/lexers/qml.rb
new file mode 100755
index 0000000..b489c6c
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/qml.rb
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    load_const :Javascript, 'javascript.rb'
+    class Qml < Javascript
+      desc 'QML, a UI markup language'
+      tag 'qml'
+      aliases 'qml'
+      filenames '*.qml'
+
+      mimetypes 'application/x-qml', 'text/x-qml'
+
+      id_with_dots = /[$a-zA-Z_][a-zA-Z0-9_.]*/
+
+      prepend :root do
+        rule /(#{id_with_dots})(\s*)({)/ do
+          groups Keyword::Type, Text, Punctuation
+          push :type_block
+        end
+        rule /(#{id_with_dots})(\s+)(on)(\s+)(#{id_with_dots})(\s*)({)/ do
+          groups Keyword::Type, Text, Keyword, Text, Name::Label, Text, Punctuation
+          push :type_block
+        end
+
+        rule /[{]/, Punctuation, :push
+      end
+
+      state :type_block do
+        rule /(id)(\s*)(:)(\s*)(#{id_with_dots})/ do
+          groups Name::Label, Text, Punctuation, Text, Keyword::Declaration
+        end
+
+        rule /(#{id_with_dots})(\s*)(:)/ do
+          groups Name::Label, Text, Punctuation
+          push :expr_start
+        end
+
+        rule /(signal)(\s+)(#{id_with_dots})/ do
+          groups Keyword::Declaration, Text, Name::Label
+          push :signal
+        end
+
+        rule /(property)(\s+)(#{id_with_dots})(\s+)(#{id_with_dots})(\s*)(:?)/ do
+          groups Keyword::Declaration, Text, Keyword::Type, Text, Name::Label, Text, Punctuation
+          push :expr_start
+        end
+
+        rule /[}]/, Punctuation, :pop!
+        mixin :root
+      end
+
+      state :signal do
+        mixin :comments_and_whitespace
+        rule /\(/ do
+          token Punctuation
+          goto :signal_args
+        end
+        rule //, Text, :pop!
+      end
+
+      state :signal_args do
+        mixin :comments_and_whitespace
+        rule /(#{id_with_dots})(\s+)(#{id_with_dots})(\s*)(,?)/ do
+          groups Keyword::Type, Text, Name, Text, Punctuation
+        end
+        rule /\)/ , Punctuation, :pop!
+      end
+    end
+  end
+end
+
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/r.rb b/app/server/vendor/rouge/lib/rouge/lexers/r.rb
new file mode 100755
index 0000000..a9ff42d
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/r.rb
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class R < RegexLexer
+      desc 'The R statistics language (r-project.org)'
+      tag 'r'
+      aliases 'r', 'R', 's', 'S'
+      filenames '*.R', '*.S', '.Rhistory', '.Rprofile'
+      mimetypes 'text/x-r-source', 'text/x-r', 'text/x-R'
+
+      mimetypes 'text/x-r', 'application/x-r'
+
+      def self.keywords
+        @keywords ||= %w(
+          if else for while repeat in next break return switch function
+        )
+      end
+
+      def self.analyze_text(text)
+        return 1 if text.shebang? 'Rscript'
+        return 0.1 if text.include? '->'
+      end
+
+      state :root do
+        rule /#.*?\n/, Comment::Single
+        rule /\s+/m, Text
+        rule /[.]?[a-zA-Z_][\w.]*/ do |m|
+          if self.class.keywords.include? m[0]
+            token Keyword
+          else
+            token Name
+          end
+        end
+
+        rule /`.*?`/, Str::Backtick
+        rule /'(\\.|.)*?'/m, Str::Single
+        rule /"(\\.|.)*?"/m, Str::Double
+
+        rule /\b(NULL|Inf|TRUE|FALSE|NaN)\b/, Keyword::Constant
+        rule /\bNA(_(integer|real|complex|character)_)?\b/,
+          Keyword::Constant
+        rule /\b[TF]\b/, Keyword::Variable
+
+        rule /0[xX][a-fA-F0-9]+([pP][0-9]+)?[Li]?/, Num::Hex
+        rule /[+-]?(\d+([.]\d+)?|[.]\d+)([eE][+-]?\d+)?[Li]?/,
+          Num
+
+        rule /[\[\]{}();,]/, Punctuation
+
+        rule %r([-<>?*+^/!=~$@:%&|]), Operator
+        rule /[.][.][.]/, Keyword
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/racket.rb b/app/server/vendor/rouge/lib/rouge/lexers/racket.rb
new file mode 100755
index 0000000..2eff60a
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/racket.rb
@@ -0,0 +1,541 @@
+# -*- coding: utf-8 -*- #
+module Rouge
+  module Lexers
+    class Racket < RegexLexer
+      desc "Racket is a Lisp descended from Scheme (racket-lang.org)"
+
+      tag 'racket'
+      filenames '*.rkt', '*.rktd', '*.rktl'
+      mimetypes 'text/x-racket', 'application/x-racket'
+
+      def self.analyze_text(text)
+        text = text.strip
+        return 1 if text.start_with? '#lang racket'
+        return 0.6 if text =~ %r(\A#lang [a-z/-]+$)i
+      end
+
+      def self.keywords
+        @keywords ||= Set.new %w(
+          ... and begin begin-for-syntax begin0 case case-lambda cond
+          datum->syntax-object define define-for-syntax define-logger
+          define-struct define-syntax define-syntax-rule
+          define-syntaxes define-values define-values-for-syntax delay
+          do expand-path fluid-let force hash-table-copy
+          hash-table-count hash-table-for-each hash-table-get
+          hash-table-iterate-first hash-table-iterate-key
+          hash-table-iterate-next hash-table-iterate-value
+          hash-table-map hash-table-put! hash-table-remove!
+          hash-table? if lambda let let* let*-values let-struct
+          let-syntax let-syntaxes let-values let/cc let/ec letrec
+          letrec-syntax letrec-syntaxes letrec-syntaxes+values
+          letrec-values list-immutable make-hash-table
+          make-immutable-hash-table make-namespace module module*
+          module-identifier=? module-label-identifier=?
+          module-template-identifier=? module-transformer-identifier=?
+          namespace-transformer-require or parameterize parameterize*
+          parameterize-break promise? prop:method-arity-error provide
+          provide-for-label provide-for-syntax quasiquote quasisyntax
+          quasisyntax/loc quote quote-syntax quote-syntax/prune
+          require require-for-label require-for-syntax
+          require-for-template set! set!-values syntax syntax-case
+          syntax-case* syntax-id-rules syntax-object->datum
+          syntax-rules syntax/loc tcp-abandon-port tcp-accept
+          tcp-accept-evt tcp-accept-ready? tcp-accept/enable-break
+          tcp-addresses tcp-close tcp-connect tcp-connect/enable-break
+          tcp-listen tcp-listener? tcp-port? time transcript-off
+          transcript-on udp-addresses udp-bind! udp-bound? udp-close
+          udp-connect! udp-connected? udp-multicast-interface
+          udp-multicast-join-group! udp-multicast-leave-group!
+          udp-multicast-loopback? udp-multicast-set-interface!
+          udp-multicast-set-loopback! udp-multicast-set-ttl!
+          udp-multicast-ttl udp-open-socket udp-receive! udp-receive!*
+          udp-receive!-evt udp-receive!/enable-break
+          udp-receive-ready-evt udp-send udp-send* udp-send-evt
+          udp-send-ready-evt udp-send-to udp-send-to* udp-send-to-evt
+          udp-send-to/enable-break udp-send/enable-break udp? unless
+          unquote unquote-splicing unsyntax unsyntax-splicing when
+          with-continuation-mark with-handlers with-handlers*
+          with-syntax λ)
+      end
+
+      def self.builtins
+        @builtins ||= Set.new %w(
+          * + - / < <= = > >=
+          abort-current-continuation abs absolute-path? acos add1
+          alarm-evt always-evt andmap angle append apply
+          arithmetic-shift arity-at-least arity-at-least-value
+          arity-at-least? asin assoc assq assv atan banner bitwise-and
+          bitwise-bit-field bitwise-bit-set? bitwise-ior bitwise-not
+          bitwise-xor boolean? bound-identifier=? box box-cas!
+          box-immutable box? break-enabled break-thread build-path
+          build-path/convention-type byte-pregexp byte-pregexp?
+          byte-ready? byte-regexp byte-regexp? byte? bytes
+          bytes->immutable-bytes bytes->list bytes->path
+          bytes->path-element bytes->string/latin-1
+          bytes->string/locale bytes->string/utf-8 bytes-append
+          bytes-close-converter bytes-convert bytes-convert-end
+          bytes-converter? bytes-copy bytes-copy!
+          bytes-environment-variable-name? bytes-fill! bytes-length
+          bytes-open-converter bytes-ref bytes-set! bytes-utf-8-index
+          bytes-utf-8-length bytes-utf-8-ref bytes<? bytes=? bytes>?
+          bytes? caaaar caaadr caaar caadar caaddr caadr caar cadaar
+          cadadr cadar caddar cadddr caddr cadr call-in-nested-thread
+          call-with-break-parameterization
+          call-with-composable-continuation
+          call-with-continuation-barrier call-with-continuation-prompt
+          call-with-current-continuation
+          call-with-default-reading-parameterization
+          call-with-escape-continuation call-with-exception-handler
+          call-with-immediate-continuation-mark call-with-input-file
+          call-with-output-file call-with-parameterization
+          call-with-semaphore call-with-semaphore/enable-break
+          call-with-values call/cc call/ec car cdaaar cdaadr cdaar
+          cdadar cdaddr cdadr cdar cddaar cddadr cddar cdddar cddddr
+          cdddr cddr cdr ceiling channel-get channel-put
+          channel-put-evt channel-put-evt? channel-try-get channel?
+          chaperone-box chaperone-continuation-mark-key chaperone-evt
+          chaperone-hash chaperone-of? chaperone-procedure
+          chaperone-prompt-tag chaperone-struct chaperone-struct-type
+          chaperone-vector chaperone? char->integer char-alphabetic?
+          char-blank? char-ci<=? char-ci<? char-ci=? char-ci>=?
+          char-ci>? char-downcase char-foldcase char-general-category
+          char-graphic? char-iso-control? char-lower-case?
+          char-numeric? char-punctuation? char-ready? char-symbolic?
+          char-title-case? char-titlecase char-upcase char-upper-case?
+          char-utf-8-length char-whitespace? char<=? char<? char=?
+          char>=? char>? char? check-duplicate-identifier
+          checked-procedure-check-and-extract choice-evt cleanse-path
+          close-input-port close-output-port collect-garbage
+          collection-file-path collection-path compile
+          compile-allow-set!-undefined
+          compile-context-preservation-enabled
+          compile-enforce-module-constants compile-syntax
+          compiled-expression? compiled-module-expression?
+          complete-path? complex? cons continuation-mark-key?
+          continuation-mark-set->context continuation-mark-set->list
+          continuation-mark-set->list* continuation-mark-set-first
+          continuation-mark-set? continuation-marks
+          continuation-prompt-available? continuation-prompt-tag?
+          continuation? copy-file cos current-break-parameterization
+          current-code-inspector current-command-line-arguments
+          current-compile current-compiled-file-roots
+          current-continuation-marks current-custodian
+          current-directory current-directory-for-user current-drive
+          current-environment-variables current-error-port
+          current-eval current-evt-pseudo-random-generator
+          current-gc-milliseconds current-get-interaction-input-port
+          current-inexact-milliseconds current-input-port
+          current-inspector current-library-collection-paths
+          current-load current-load-extension
+          current-load-relative-directory current-load/use-compiled
+          current-locale current-memory-use current-milliseconds
+          current-module-declare-name current-module-declare-source
+          current-module-name-resolver current-module-path-for-load
+          current-namespace current-output-port
+          current-parameterization
+          current-preserved-thread-cell-values current-print
+          current-process-milliseconds current-prompt-read
+          current-pseudo-random-generator current-read-interaction
+          current-reader-guard current-readtable current-seconds
+          current-security-guard current-subprocess-custodian-mode
+          current-thread current-thread-group
+          current-thread-initial-stack-size
+          current-write-relative-directory custodian-box-value
+          custodian-box? custodian-limit-memory custodian-managed-list
+          custodian-memory-accounting-available?
+          custodian-require-memory custodian-shutdown-all custodian?
+          custom-print-quotable-accessor custom-print-quotable?
+          custom-write-accessor custom-write? date date*
+          date*-nanosecond date*-time-zone-name date*? date-day
+          date-dst? date-hour date-minute date-month date-second
+          date-time-zone-offset date-week-day date-year date-year-day
+          date? datum-intern-literal default-continuation-prompt-tag
+          delete-directory delete-file denominator directory-exists?
+          directory-list display displayln dump-memory-stats
+          dynamic-require dynamic-require-for-syntax dynamic-wind
+          environment-variables-copy environment-variables-names
+          environment-variables-ref environment-variables-set!
+          environment-variables? eof eof-object? ephemeron-value
+          ephemeron? eprintf eq-hash-code eq? equal-hash-code
+          equal-secondary-hash-code equal? equal?/recur eqv-hash-code
+          eqv? error error-display-handler error-escape-handler
+          error-print-context-length error-print-source-location
+          error-print-width error-value->string-handler eval
+          eval-jit-enabled eval-syntax even? evt? exact->inexact
+          exact-integer? exact-nonnegative-integer?
+          exact-positive-integer? exact? executable-yield-handler exit
+          exit-handler exn exn-continuation-marks exn-message
+          exn:break exn:break-continuation exn:break:hang-up
+          exn:break:hang-up? exn:break:terminate exn:break:terminate?
+          exn:break? exn:fail exn:fail:contract
+          exn:fail:contract:arity exn:fail:contract:arity?
+          exn:fail:contract:continuation
+          exn:fail:contract:continuation?
+          exn:fail:contract:divide-by-zero
+          exn:fail:contract:divide-by-zero?
+          exn:fail:contract:non-fixnum-result
+          exn:fail:contract:non-fixnum-result?
+          exn:fail:contract:variable exn:fail:contract:variable-id
+          exn:fail:contract:variable? exn:fail:contract?
+          exn:fail:filesystem exn:fail:filesystem:errno
+          exn:fail:filesystem:errno-errno exn:fail:filesystem:errno?
+          exn:fail:filesystem:exists exn:fail:filesystem:exists?
+          exn:fail:filesystem:missing-module
+          exn:fail:filesystem:missing-module-path
+          exn:fail:filesystem:missing-module?
+          exn:fail:filesystem:version exn:fail:filesystem:version?
+          exn:fail:filesystem? exn:fail:network exn:fail:network:errno
+          exn:fail:network:errno-errno exn:fail:network:errno?
+          exn:fail:network? exn:fail:out-of-memory
+          exn:fail:out-of-memory? exn:fail:read exn:fail:read-srclocs
+          exn:fail:read:eof exn:fail:read:eof? exn:fail:read:non-char
+          exn:fail:read:non-char? exn:fail:read? exn:fail:syntax
+          exn:fail:syntax-exprs exn:fail:syntax:missing-module
+          exn:fail:syntax:missing-module-path
+          exn:fail:syntax:missing-module? exn:fail:syntax:unbound
+          exn:fail:syntax:unbound? exn:fail:syntax?
+          exn:fail:unsupported exn:fail:unsupported? exn:fail:user
+          exn:fail:user? exn:fail? exn:missing-module-accessor
+          exn:missing-module? exn:srclocs-accessor exn:srclocs? exn?
+          exp expand expand-once expand-syntax expand-syntax-once
+          expand-syntax-to-top-form expand-to-top-form
+          expand-user-path explode-path expt file-exists?
+          file-or-directory-identity file-or-directory-modify-seconds
+          file-or-directory-permissions file-position file-position*
+          file-size file-stream-buffer-mode file-stream-port?
+          file-truncate filesystem-change-evt
+          filesystem-change-evt-cancel filesystem-change-evt?
+          filesystem-root-list find-executable-path
+          find-library-collection-paths find-system-path fixnum?
+          floating-point-bytes->real flonum? floor flush-output
+          for-each format fprintf free-identifier=? gcd
+          generate-temporaries gensym get-output-bytes
+          get-output-string getenv global-port-print-handler guard-evt
+          handle-evt handle-evt? hash hash-equal? hash-eqv?
+          hash-has-key? hash-placeholder? hash-ref! hasheq hasheqv
+          identifier-binding identifier-binding-symbol
+          identifier-label-binding identifier-prune-lexical-context
+          identifier-prune-to-source-module
+          identifier-remove-from-definition-context
+          identifier-template-binding identifier-transformer-binding
+          identifier? imag-part immutable? impersonate-box
+          impersonate-continuation-mark-key impersonate-hash
+          impersonate-procedure impersonate-prompt-tag
+          impersonate-struct impersonate-vector impersonator-ephemeron
+          impersonator-of? impersonator-prop:application-mark
+          impersonator-property-accessor-procedure?
+          impersonator-property? impersonator? inexact->exact
+          inexact-real? inexact? input-port? inspector? integer->char
+          integer->integer-bytes integer-bytes->integer integer-length
+          integer-sqrt integer-sqrt/remainder integer?
+          internal-definition-context-seal
+          internal-definition-context? keyword->string keyword<?
+          keyword? kill-thread lcm length liberal-define-context?
+          link-exists? list list* list->bytes list->string
+          list->vector list-ref list-tail list? load load-extension
+          load-on-demand-enabled load-relative load-relative-extension
+          load/cd load/use-compiled local-expand
+          local-expand/capture-lifts local-transformer-expand
+          local-transformer-expand/capture-lifts
+          locale-string-encoding log log-max-level magnitude
+          make-arity-at-least make-bytes make-channel
+          make-continuation-mark-key make-continuation-prompt-tag
+          make-custodian make-custodian-box make-date make-date*
+          make-derived-parameter make-directory
+          make-environment-variables make-ephemeron make-exn
+          make-exn:break make-exn:break:hang-up
+          make-exn:break:terminate make-exn:fail
+          make-exn:fail:contract make-exn:fail:contract:arity
+          make-exn:fail:contract:continuation
+          make-exn:fail:contract:divide-by-zero
+          make-exn:fail:contract:non-fixnum-result
+          make-exn:fail:contract:variable make-exn:fail:filesystem
+          make-exn:fail:filesystem:errno
+          make-exn:fail:filesystem:exists
+          make-exn:fail:filesystem:missing-module
+          make-exn:fail:filesystem:version make-exn:fail:network
+          make-exn:fail:network:errno make-exn:fail:out-of-memory
+          make-exn:fail:read make-exn:fail:read:eof
+          make-exn:fail:read:non-char make-exn:fail:syntax
+          make-exn:fail:syntax:missing-module
+          make-exn:fail:syntax:unbound make-exn:fail:unsupported
+          make-exn:fail:user make-file-or-directory-link
+          make-hash-placeholder make-hasheq-placeholder make-hasheqv
+          make-hasheqv-placeholder make-immutable-hasheqv
+          make-impersonator-property make-input-port make-inspector
+          make-known-char-range-list make-output-port make-parameter
+          make-phantom-bytes make-pipe make-placeholder make-polar
+          make-prefab-struct make-pseudo-random-generator
+          make-reader-graph make-readtable make-rectangular
+          make-rename-transformer make-resolved-module-path
+          make-security-guard make-semaphore make-set!-transformer
+          make-shared-bytes make-sibling-inspector
+          make-special-comment make-srcloc make-string
+          make-struct-field-accessor make-struct-field-mutator
+          make-struct-type make-struct-type-property
+          make-syntax-delta-introducer make-syntax-introducer
+          make-thread-cell make-thread-group make-vector make-weak-box
+          make-weak-hasheqv make-will-executor map max mcar mcdr mcons
+          member memq memv min module->exports module->imports
+          module->language-info module->namespace
+          module-compiled-cross-phase-persistent?
+          module-compiled-exports module-compiled-imports
+          module-compiled-language-info module-compiled-name
+          module-compiled-submodules module-declared?
+          module-path-index-join module-path-index-resolve
+          module-path-index-split module-path-index-submodule
+          module-path-index? module-path? module-predefined?
+          module-provide-protected? modulo mpair? nack-guard-evt
+          namespace-attach-module namespace-attach-module-declaration
+          namespace-base-phase namespace-mapped-symbols
+          namespace-module-identifier namespace-module-registry
+          namespace-require namespace-require/constant
+          namespace-require/copy namespace-require/expansion-time
+          namespace-set-variable-value! namespace-symbol->identifier
+          namespace-syntax-introduce namespace-undefine-variable!
+          namespace-unprotect-module namespace-variable-value
+          namespace? negative? never-evt newline normal-case-path not
+          null null? number->string number? numerator object-name odd?
+          open-input-bytes open-input-file open-input-output-file
+          open-input-string open-output-bytes open-output-file
+          open-output-string ormap output-port? pair?
+          parameter-procedure=? parameter? parameterization?
+          path->bytes path->complete-path path->directory-path
+          path->string path-add-suffix path-convention-type
+          path-element->bytes path-element->string
+          path-for-some-system? path-list-string->path-list
+          path-replace-suffix path-string? path? peek-byte
+          peek-byte-or-special peek-bytes peek-bytes!
+          peek-bytes-avail! peek-bytes-avail!*
+          peek-bytes-avail!/enable-break peek-char
+          peek-char-or-special peek-string peek-string! phantom-bytes?
+          pipe-content-length placeholder-get placeholder-set!
+          placeholder? poll-guard-evt port-closed-evt port-closed?
+          port-commit-peeked port-count-lines!
+          port-count-lines-enabled port-counts-lines?
+          port-display-handler port-file-identity port-file-unlock
+          port-next-location port-print-handler port-progress-evt
+          port-provides-progress-evts? port-read-handler
+          port-try-file-lock? port-write-handler port-writes-atomic?
+          port-writes-special? port? positive? prefab-key->struct-type
+          prefab-key? prefab-struct-key pregexp pregexp?
+          primitive-closure? primitive-result-arity primitive? print
+          print-as-expression print-boolean-long-form print-box
+          print-graph print-hash-table print-mpair-curly-braces
+          print-pair-curly-braces print-reader-abbreviations
+          print-struct print-syntax-width print-unreadable
+          print-vector-length printf procedure->method procedure-arity
+          procedure-arity-includes? procedure-arity?
+          procedure-closure-contents-eq? procedure-extract-target
+          procedure-reduce-arity procedure-rename
+          procedure-struct-type? procedure? progress-evt?
+          prop:arity-string prop:checked-procedure
+          prop:custom-print-quotable prop:custom-write prop:equal+hash
+          prop:evt prop:exn:missing-module prop:exn:srclocs
+          prop:impersonator-of prop:input-port
+          prop:liberal-define-context prop:output-port prop:procedure
+          prop:rename-transformer prop:set!-transformer
+          pseudo-random-generator->vector
+          pseudo-random-generator-vector? pseudo-random-generator?
+          putenv quotient quotient/remainder raise
+          raise-argument-error raise-arguments-error raise-arity-error
+          raise-mismatch-error raise-range-error raise-result-error
+          raise-syntax-error raise-type-error raise-user-error random
+          random-seed rational? rationalize read read-accept-bar-quote
+          read-accept-box read-accept-compiled read-accept-dot
+          read-accept-graph read-accept-infix-dot read-accept-lang
+          read-accept-quasiquote read-accept-reader read-byte
+          read-byte-or-special read-bytes read-bytes!
+          read-bytes-avail! read-bytes-avail!*
+          read-bytes-avail!/enable-break read-bytes-line
+          read-case-sensitive read-char read-char-or-special
+          read-curly-brace-as-paren read-decimal-as-inexact
+          read-eval-print-loop read-language read-line
+          read-on-demand-source read-square-bracket-as-paren
+          read-string read-string! read-syntax read-syntax/recursive
+          read/recursive readtable-mapping readtable?
+          real->double-flonum real->floating-point-bytes
+          real->single-flonum real-part real? regexp regexp-match
+          regexp-match-peek regexp-match-peek-immediate
+          regexp-match-peek-positions
+          regexp-match-peek-positions-immediate
+          regexp-match-peek-positions-immediate/end
+          regexp-match-peek-positions/end regexp-match-positions
+          regexp-match-positions/end regexp-match/end regexp-match?
+          regexp-max-lookbehind regexp-replace regexp-replace* regexp?
+          relative-path? remainder rename-file-or-directory
+          rename-transformer-target rename-transformer? reroot-path
+          resolve-path resolved-module-path-name resolved-module-path?
+          reverse round seconds->date security-guard?
+          semaphore-peek-evt semaphore-peek-evt? semaphore-post
+          semaphore-try-wait? semaphore-wait
+          semaphore-wait/enable-break semaphore?
+          set!-transformer-procedure set!-transformer? set-box!
+          set-mcar! set-mcdr! set-phantom-bytes!
+          set-port-next-location! shared-bytes shell-execute
+          simplify-path sin single-flonum? sleep special-comment-value
+          special-comment? split-path sqrt srcloc srcloc->string
+          srcloc-column srcloc-line srcloc-position srcloc-source
+          srcloc-span srcloc? string string->bytes/latin-1
+          string->bytes/locale string->bytes/utf-8
+          string->immutable-string string->keyword string->list
+          string->number string->path string->path-element
+          string->symbol string->uninterned-symbol
+          string->unreadable-symbol string-append string-ci<=?
+          string-ci<? string-ci=? string-ci>=? string-ci>? string-copy
+          string-copy! string-downcase
+          string-environment-variable-name? string-fill!
+          string-foldcase string-length string-locale-ci<?
+          string-locale-ci=? string-locale-ci>? string-locale-downcase
+          string-locale-upcase string-locale<? string-locale=?
+          string-locale>? string-normalize-nfc string-normalize-nfd
+          string-normalize-nfkc string-normalize-nfkd string-ref
+          string-set! string-titlecase string-upcase
+          string-utf-8-length string<=? string<? string=? string>=?
+          string>? string? struct->vector struct-accessor-procedure?
+          struct-constructor-procedure? struct-info
+          struct-mutator-procedure? struct-predicate-procedure?
+          struct-type-info struct-type-make-constructor
+          struct-type-make-predicate
+          struct-type-property-accessor-procedure?
+          struct-type-property? struct-type? struct:arity-at-least
+          struct:date struct:date* struct:exn struct:exn:break
+          struct:exn:break:hang-up struct:exn:break:terminate
+          struct:exn:fail struct:exn:fail:contract
+          struct:exn:fail:contract:arity
+          struct:exn:fail:contract:continuation
+          struct:exn:fail:contract:divide-by-zero
+          struct:exn:fail:contract:non-fixnum-result
+          struct:exn:fail:contract:variable struct:exn:fail:filesystem
+          struct:exn:fail:filesystem:errno
+          struct:exn:fail:filesystem:exists
+          struct:exn:fail:filesystem:missing-module
+          struct:exn:fail:filesystem:version struct:exn:fail:network
+          struct:exn:fail:network:errno struct:exn:fail:out-of-memory
+          struct:exn:fail:read struct:exn:fail:read:eof
+          struct:exn:fail:read:non-char struct:exn:fail:syntax
+          struct:exn:fail:syntax:missing-module
+          struct:exn:fail:syntax:unbound struct:exn:fail:unsupported
+          struct:exn:fail:user struct:srcloc struct? sub1 subbytes
+          subprocess subprocess-group-enabled subprocess-kill
+          subprocess-pid subprocess-status subprocess-wait subprocess?
+          substring symbol->string symbol-interned? symbol-unreadable?
+          symbol? sync sync/enable-break sync/timeout
+          sync/timeout/enable-break syntax->list syntax-arm
+          syntax-column syntax-disarm syntax-e syntax-line
+          syntax-local-bind-syntaxes syntax-local-certifier
+          syntax-local-context syntax-local-expand-expression
+          syntax-local-get-shadower syntax-local-introduce
+          syntax-local-lift-context syntax-local-lift-expression
+          syntax-local-lift-module-end-declaration
+          syntax-local-lift-provide syntax-local-lift-require
+          syntax-local-lift-values-expression
+          syntax-local-make-definition-context
+          syntax-local-make-delta-introducer
+          syntax-local-module-defined-identifiers
+          syntax-local-module-exports
+          syntax-local-module-required-identifiers syntax-local-name
+          syntax-local-phase-level syntax-local-submodules
+          syntax-local-transforming-module-provides?
+          syntax-local-value syntax-local-value/immediate
+          syntax-original? syntax-position syntax-property
+          syntax-property-symbol-keys syntax-protect syntax-rearm
+          syntax-recertify syntax-shift-phase-level syntax-source
+          syntax-source-module syntax-span syntax-taint
+          syntax-tainted? syntax-track-origin
+          syntax-transforming-module-expression? syntax-transforming?
+          syntax? system-big-endian? system-idle-evt
+          system-language+country system-library-subpath
+          system-path-convention-type system-type tan terminal-port?
+          thread thread-cell-ref thread-cell-set! thread-cell-values?
+          thread-cell? thread-dead-evt thread-dead? thread-group?
+          thread-resume thread-resume-evt thread-rewind-receive
+          thread-running? thread-suspend thread-suspend-evt
+          thread-wait thread/suspend-to-kill thread? time-apply
+          truncate unbox uncaught-exception-handler
+          use-collection-link-paths use-compiled-file-paths
+          use-user-specific-search-paths values
+          variable-reference->empty-namespace
+          variable-reference->module-base-phase
+          variable-reference->module-declaration-inspector
+          variable-reference->module-path-index
+          variable-reference->module-source
+          variable-reference->namespace variable-reference->phase
+          variable-reference->resolved-module-path
+          variable-reference-constant? variable-reference? vector
+          vector->immutable-vector vector->list
+          vector->pseudo-random-generator
+          vector->pseudo-random-generator! vector->values vector-fill!
+          vector-immutable vector-length vector-ref vector-set!
+          vector-set-performance-stats! vector? version void void?
+          weak-box-value weak-box? will-execute will-executor?
+          will-register will-try-execute with-input-from-file
+          with-output-to-file wrap-evt write write-byte write-bytes
+          write-bytes-avail write-bytes-avail* write-bytes-avail-evt
+          write-bytes-avail/enable-break write-char write-special
+          write-special-avail* write-special-evt write-string zero?
+        )
+      end
+
+      # Since Racket allows identifiers to consist of nearly anything,
+      # it's simpler to describe what an ID is _not_.
+      id = /[^\s\(\)\[\]\{\}'`,.]+/i
+
+      state :root do
+        # comments
+        rule /;.*$/, Comment::Single
+        rule /\s+/m, Text
+
+        rule /[+-]inf[.][f0]/, Num::Float
+        rule /[+-]nan[.]0/, Num::Float
+        rule /[-]min[.]0/, Num::Float
+        rule /[+]max[.]0/, Num::Float
+
+        rule /-?\d+\.\d+/, Num::Float
+        rule /-?\d+/, Num::Integer
+
+        rule /#:#{id}+/, Name::Tag  # keyword
+
+        rule /#b[01]+/, Num::Bin
+        rule /#o[0-7]+/, Num::Oct
+        rule /#d[0-9]+/, Num::Integer
+        rule /#x[0-9a-f]+/i, Num::Hex
+        rule /#[ei][\d.]+/, Num::Other
+
+        rule /"(\\\\|\\"|[^"])*"/, Str
+        rule /['`]#{id}/i, Str::Symbol
+        rule /#\\([()\/'"._!\$%& ?=+-]{1}|[a-z0-9]+)/i,
+          Str::Char
+        rule /#t|#f/, Name::Constant
+        rule /(?:'|#|`|,@|,|\.)/, Operator
+
+        rule /(['#])(\s*)(\()/m do
+          groups Str::Symbol, Text, Punctuation
+        end
+
+        # () [] {} are all permitted as like pairs
+        rule /\(|\[|\{/, Punctuation, :command
+        rule /\)|\]|\}/, Punctuation
+
+        rule id, Name::Variable
+      end
+
+      state :command do
+        rule id, Name::Function do |m|
+          if self.class.keywords.include? m[0]
+            token Keyword
+          elsif self.class.builtins.include? m[0]
+            token Name::Builtin
+          else
+            token Name::Function
+          end
+
+          pop!
+        end
+
+        rule(//) { pop! }
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/ruby.rb b/app/server/vendor/rouge/lib/rouge/lexers/ruby.rb
new file mode 100755
index 0000000..3190038
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/ruby.rb
@@ -0,0 +1,399 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Ruby < RegexLexer
+      desc "The Ruby programming language (ruby-lang.org)"
+      tag 'ruby'
+      aliases 'rb'
+      filenames '*.rb', '*.ruby', '*.rbw', '*.rake', '*.gemspec',
+                'Rakefile', 'Guardfile', 'Gemfile', 'Capfile',
+                'Vagrantfile', '*.ru', '*.prawn'
+
+      mimetypes 'text/x-ruby', 'application/x-ruby'
+
+      def self.analyze_text(text)
+        return 1 if text.shebang? 'ruby'
+      end
+
+      state :sigil_strings do
+        # symbols
+        rule %r(
+          :  # initial :
+          @{0,2} # optional ivar, for :@foo and :@@foo
+          [a-z_]\w*[!?]? # the symbol
+        )xi, Str::Symbol
+
+        # special symbols
+        rule %r(:(?:\*\*|[-+]@|[/\%&\|^`~]|\[\]=?|<<|>>|<=?>|<=?|===?)),
+          Str::Symbol
+
+        rule /:'(\\\\|\\'|[^'])*'/, Str::Symbol
+        rule /:"/, Str::Symbol, :simple_sym
+
+        # %-sigiled strings
+        # %(abc), %[abc], %<abc>, %.abc., %r.abc., etc
+        delimiter_map = { '{' => '}', '[' => ']', '(' => ')', '<' => '>' }
+        rule /%([rqswQWxiI])?([^\w\s])/ do |m|
+          open = Regexp.escape(m[2])
+          close = Regexp.escape(delimiter_map[m[2]] || m[2])
+          interp = /[rQWxI]/ === m[1]
+          toktype = Str::Other
+
+          puts "    open: #{open.inspect}" if @debug
+          puts "    close: #{close.inspect}" if @debug
+
+          # regexes
+          if m[1] == 'r'
+            toktype = Str::Regex
+            push :regex_flags
+          end
+
+          token toktype
+
+          push do
+            rule /\\[##{open}#{close}\\]/, Str::Escape
+            # nesting rules only with asymmetric delimiters
+            if open != close
+              rule /#{open}/ do
+                token toktype
+                push
+              end
+            end
+            rule /#{close}/, toktype, :pop!
+
+            if interp
+              mixin :string_intp_escaped
+              rule /#/, toktype
+            else
+              rule /[\\#]/, toktype
+            end
+
+            rule /[^##{open}#{close}\\]+/m, toktype
+          end
+        end
+      end
+
+      state :strings do
+        rule /\b[a-z_]\w*?:\s+/, Str::Symbol, :expr_start
+        rule /'(\\\\|\\'|[^'])*'/, Str::Single
+        rule /"/, Str::Double, :simple_string
+        rule /(?<!\.)`/, Str::Backtick, :simple_backtick
+      end
+
+      state :regex_flags do
+        rule /[mixounse]*/, Str::Regex, :pop!
+      end
+
+      # double-quoted string and symbol
+      [[:string, Str::Double, '"'],
+       [:sym, Str::Symbol, '"'],
+       [:backtick, Str::Backtick, '`']].each do |name, tok, fin|
+        state :"simple_#{name}" do
+          mixin :string_intp_escaped
+          rule /[^\\#{fin}#]+/m, tok
+          rule /[\\#]/, tok
+          rule /#{fin}/, tok, :pop!
+        end
+      end
+
+      keywords = %w(
+        BEGIN END alias begin break case defined\? do else elsif end
+        ensure for if in next redo rescue raise retry return super then
+        undef unless until when while yield
+      )
+
+      keywords_pseudo = %w(
+        initialize new loop include extend raise attr_reader attr_writer
+        attr_accessor attr catch throw private module_function public
+        protected true false nil __FILE__ __LINE__
+      )
+
+      builtins_g = %w(
+        Array Float Integer Str __id__ __send__ abort ancestors
+        at_exit autoload binding callcc caller catch chomp chop
+        class_eval class_variables clone const_defined\? const_get
+        const_missing const_set constants display dup eval exec exit
+        extend fail fork format freeze getc gets global_variables gsub
+        hash id included_modules inspect instance_eval instance_method
+        instance_methods instance_variable_get instance_variable_set
+        instance_variables lambda load local_variables loop method
+        method_missing methods module_eval name object_id open p
+        print printf private_class_method private_instance_methods
+        private_methods proc protected_instance_methods protected_methods
+        public_class_method public_instance_methods public_methods putc
+        puts raise rand readline readlines require scan select self send
+        set_trace_func singleton_methods sleep split sprintf srand sub
+        syscall system taint test throw to_a to_s trace_var trap untaint
+        untrace_var warn
+      )
+
+      builtins_q = %w(
+        autoload block_given const_defined eql equal frozen
+        include instance_of is_a iterator kind_of method_defined
+        nil private_method_defined protected_method_defined
+        public_method_defined respond_to tainted
+      )
+
+      builtins_b = %w(chomp chop exit gsub sub)
+
+      start do
+        push :expr_start
+        @heredoc_queue = []
+      end
+
+      state :whitespace do
+        mixin :inline_whitespace
+        rule /\n\s*/m, Text, :expr_start
+        rule /#.*$/, Comment::Single
+
+        rule %r(=begin\b.*?end\b)m, Comment::Multiline
+      end
+
+      state :inline_whitespace do
+        rule /[ \t\r]+/, Text
+      end
+
+      state :root do
+        mixin :whitespace
+        rule /__END__/, Comment::Preproc, :end_part
+
+        rule /0_?[0-7]+(?:_[0-7]+)*/, Num::Oct
+        rule /0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*/, Num::Hex
+        rule /0b[01]+(?:_[01]+)*/, Num::Bin
+        rule /[\d]+(?:_\d+)*/, Num::Integer
+
+        # names
+        rule /@@[a-z_]\w*/i, Name::Variable::Class
+        rule /@[a-z_]\w*/i, Name::Variable::Instance
+        rule /\$\w+/, Name::Variable::Global
+        rule %r(\$[!@&`'+~=/\\,;.<>_*\$?:"]), Name::Variable::Global
+        rule /\$-[0adFiIlpvw]/, Name::Variable::Global
+        rule /::/, Operator
+
+        mixin :strings
+
+        rule /(?:#{keywords.join('|')})\b/, Keyword, :expr_start
+        rule /(?:#{keywords_pseudo.join('|')})\b/, Keyword::Pseudo, :expr_start
+
+        rule %r(
+          (module)
+          (\s+)
+          ([a-zA-Z_][a-zA-Z0-9_]*(::[a-zA-Z_][a-zA-Z0-9_]*)*)
+        )x do
+          groups Keyword, Text, Name::Namespace
+        end
+
+        rule /(def\b)(\s*)/ do
+          groups Keyword, Text
+          push :funcname
+        end
+
+        rule /(class\b)(\s*)/ do
+          groups Keyword, Text
+          push :classname
+        end
+
+        rule /(?:#{builtins_q.join('|')})[?]/, Name::Builtin, :expr_start
+        rule /(?:#{builtins_b.join('|')})!/,  Name::Builtin, :expr_start
+        rule /(?<!\.)(?:#{builtins_g.join('|')})\b/,
+          Name::Builtin, :method_call
+
+        # char operator.  ?x evaulates to "x", unless there's a digit
+        # beforehand like x>=0?n[x]:""
+        rule %r(
+          [?](\\[MC]-)*     # modifiers
+          (\\([\\abefnrstv\#"']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})|\S)
+          (?!\w)
+        )x, Str::Char
+
+        mixin :has_heredocs
+
+        rule /[A-Z][a-zA-Z0-9_]*/, Name::Constant, :method_call
+        rule /(\.|::)(\s*)([a-z_]\w*[!?]?|[*%&^`~+-\/\[<>=])/ do
+          groups Punctuation, Text, Name::Function
+          push :expr_start
+        end
+
+        rule /[a-zA-Z_]\w*[?!]/, Name, :expr_start
+        rule /[a-zA-Z_]\w*/, Name, :method_call
+        rule /\*\*|<<?|>>?|>=|<=|<=>|=~|={3}|!~|&&?|\|\||\.{1,3}/,
+          Operator, :expr_start
+        rule /[-+\/*%=<>&!^|~]=?/, Operator, :expr_start
+        rule %r<[\[({,?:\\;/]>, Punctuation, :expr_start
+        rule %r<[\])}]>, Punctuation
+      end
+
+      state :has_heredocs do
+        rule /(?<!\w)(<<-?)(["`']?)([a-zA-Z_]\w*)(\2)/ do |m|
+          token Operator, m[1]
+          token Name::Constant, "#{m[2]}#{m[3]}#{m[4]}"
+          @heredoc_queue << [m[1] == '<<-', m[3]]
+          push :heredoc_queue unless state? :heredoc_queue
+        end
+
+        rule /(<<-?)(["'])(\2)/ do |m|
+          token Operator, m[1]
+          token Name::Constant, "#{m[2]}#{m[3]}#{m[4]}"
+          @heredoc_queue << [m[1] == '<<-', '']
+          push :heredoc_queue unless state? :heredoc_queue
+        end
+      end
+
+      state :heredoc_queue do
+        rule /(?=\n)/ do
+          goto :resolve_heredocs
+        end
+
+        mixin :root
+      end
+
+      state :resolve_heredocs do
+        mixin :string_intp_escaped
+
+        rule /(\n)([^#\\\n]*)$/ do |m|
+          tolerant, heredoc_name = @heredoc_queue.first
+          check = tolerant ? m[2].strip : m[2].rstrip
+
+          # check if we found the end of the heredoc
+          line_tok = if check == heredoc_name
+            @heredoc_queue.shift
+            # if there's no more, we're done looking.
+            pop! if @heredoc_queue.empty?
+            Name::Constant
+          else
+            Str::Heredoc
+          end
+
+          groups(Str::Heredoc, line_tok)
+        end
+
+        rule /[#\\\n]/, Str::Heredoc
+        rule /[^#\\\n]+/, Str::Heredoc
+      end
+
+      state :funcname do
+        rule /\s+/, Text
+        rule /\(/, Punctuation, :defexpr
+        rule %r(
+          (?:([a-zA-Z_][\w_]*)(\.))?
+          (
+            [a-zA-Z_][\w_]*[!?]? |
+            \*\*? | [-+]@? | [/%&\|^`~] | \[\]=? |
+            <<? | >>? | <=>? | >= | ===?
+          )
+        )x do |m|
+          puts "matches: #{[m[0], m[1], m[2], m[3]].inspect}" if @debug
+          groups Name::Class, Operator, Name::Function
+          pop!
+        end
+
+        rule(//) { pop! }
+      end
+
+      state :classname do
+        rule /\s+/, Text
+        rule /\(/ do
+          token Punctuation
+          push :defexpr
+          push :expr_start
+        end
+
+        # class << expr
+        rule /<</ do
+          token Operator
+          goto :expr_start
+        end
+
+        rule /[A-Z_]\w*/, Name::Class
+
+        rule(//) { pop! }
+      end
+
+      state :defexpr do
+        rule /(\))(\.|::)?/ do
+          groups Punctuation, Operator
+          pop!
+        end
+        rule /\(/ do
+          token Punctuation
+          push :defexpr
+          push :expr_start
+        end
+
+        mixin :root
+      end
+
+      state :in_interp do
+        rule /}/, Str::Interpol, :pop!
+        mixin :root
+      end
+
+      state :string_intp do
+        rule /\#{/, Str::Interpol, :in_interp
+        rule /#(@@?|\$)[a-z_]\w*/i, Str::Interpol
+      end
+
+      state :string_intp_escaped do
+        mixin :string_intp
+        rule /\\([\\abefnrstv#"']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})/,
+          Str::Escape
+        rule /\\./, Str::Escape
+      end
+
+      state :method_call do
+        rule %r((\s+)(/)(?=\S|\s*/)) do
+          groups Text, Str::Regex
+          goto :slash_regex
+        end
+
+        rule /(\s*)(%=)/ do
+          groups Text, Operator
+          goto :expr_start
+        end
+
+        rule(%r((?=\s*/))) { pop! }
+
+        rule(/\s+/) { token Text; goto :expr_start }
+        rule(//) { pop! }
+      end
+
+      state :expr_start do
+        mixin :inline_whitespace
+
+        rule %r(/) do
+          token Str::Regex
+          goto :slash_regex
+        end
+
+        # special case for using a single space.  Ruby demands that
+        # these be in a single line, otherwise it would make no sense.
+        rule /(\s*)(%[rqswQWxiI]? \S* )/ do
+          groups Text, Str::Other
+          pop!
+        end
+
+        mixin :sigil_strings
+
+        rule(//) { pop! }
+      end
+
+      state :slash_regex do
+        mixin :string_intp
+        rule %r(\\\\), Str::Regex
+        rule %r(\\/), Str::Regex
+        rule %r([\\#]), Str::Regex
+        rule %r([^\\/#]+)m, Str::Regex
+        rule %r(/) do
+          token Str::Regex
+          goto :regex_flags
+        end
+      end
+
+      state :end_part do
+        # eat up the rest of the stream as Comment::Preproc
+        rule /.+/m, Comment::Preproc, :pop!
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/rust.rb b/app/server/vendor/rouge/lib/rouge/lexers/rust.rb
new file mode 100755
index 0000000..057f293
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/rust.rb
@@ -0,0 +1,190 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Rust < RegexLexer
+      desc 'The Rust programming language (rust-lang.org)'
+      tag 'rust'
+      aliases 'rs'
+      # TODO: *.rc conflicts with the rc shell...
+      filenames '*.rs', '*.rc'
+      mimetypes 'text/x-rust'
+
+      def self.analyze_text(text)
+        return 1 if text.shebang? 'rustc'
+      end
+
+      def self.keywords
+        @keywords ||= %w(
+          as assert break const copy do drop else enum extern fail false
+          fn for if impl let log loop match mod move mut priv pub pure
+          ref return self static struct true trait type unsafe use while
+          box
+        )
+      end
+
+      def self.builtins
+        @builtins ||= Set.new %w(
+          Add BitAnd BitOr BitXor bool c_char c_double c_float char
+          c_int clock_t c_long c_longlong Cons Const Copy c_schar c_short
+          c_uchar c_uint c_ulong c_ulonglong c_ushort c_void dev_t DIR
+          dirent Div Either Eq Err f32 f64 Failure FILE float fpos_t
+          i16 i32 i64 i8 Index ino_t int intptr_t Left mode_t Modulo Mul
+          Neg Nil None Num off_t Ok Option Ord Owned pid_t Ptr ptrdiff_t
+          Right Send Shl Shr size_t Some ssize_t str Sub Success time_t
+          u16 u32 u64 u8 uint uintptr_t
+          Box Vec String Gc Rc Arc
+        )
+      end
+
+      def macro_closed?
+        @macro_delims.values.all?(&:zero?)
+      end
+
+      start {
+        @macro_delims = { ']' => 0, ')' => 0, '}' => 0 }
+      }
+
+      delim_map = { '[' => ']', '(' => ')', '{' => '}' }
+
+      id = /[a-z_]\w*/i
+      hex = /[0-9a-f]/i
+      escapes = %r(
+        \\ ([nrt'\\] | x#{hex}{2} | u#{hex}{4} | U#{hex}{8})
+      )x
+      size = /8|16|32|64/
+
+      state :start_line do
+        mixin :whitespace
+        rule /\s+/, Text
+        rule /#\[/ do
+          token Comment::Preproc; push :attribute
+        end
+        rule(//) { pop! }
+      end
+
+      state :attribute do
+        mixin :whitespace
+        mixin :has_literals
+        rule /[(,)=]/, Comment::Preproc
+        rule /\]/, Comment::Preproc, :pop!
+        rule id, Comment::Preproc
+      end
+
+      state :whitespace do
+        rule /\s+/, Text
+        rule %r(//[^\n]*), Comment
+        rule %r(/[*].*?[*]/)m, Comment::Multiline
+      end
+
+      state :root do
+        rule /\n/, Text, :start_line
+        mixin :whitespace
+        rule /\b(?:#{Rust.keywords.join('|')})\b/, Keyword
+        mixin :has_literals
+
+        rule %r([=-]>), Keyword
+        rule %r(<->), Keyword
+        rule /[()\[\]{}|,:;]/, Punctuation
+        rule /[*!@~&+%^<>=-]/, Operator
+
+        rule /([.]\s*)?#{id}(?=\s*[(])/m, Name::Function
+        rule /[.]\s*#{id}/, Name::Property
+        rule /(#{id})(::)/m do
+          groups Name::Namespace, Punctuation
+        end
+
+        # macros
+        rule /\bmacro_rules!/, Name::Decorator, :macro_rules
+        rule /#{id}!/, Name::Decorator, :macro
+
+        rule /#{id}/ do |m|
+          name = m[0]
+          if self.class.builtins.include? name
+            token Name::Builtin
+          else
+            token Name
+          end
+        end
+      end
+
+      state :macro do
+        mixin :has_literals
+
+        rule /[\[{(]/ do |m|
+          @macro_delims[delim_map[m[0]]] += 1
+          puts "    macro_delims: #{@macro_delims.inspect}" if @debug
+          token Punctuation
+        end
+
+        rule /[\]})]/ do |m|
+          @macro_delims[m[0]] -= 1
+          puts "    macro_delims: #{@macro_delims.inspect}" if @debug
+          pop! if macro_closed?
+          token Punctuation
+        end
+
+        # same as the rule in root, but don't push another macro state
+        rule /#{id}!/, Name::Decorator
+        mixin :root
+
+        # No syntax errors in macros
+        rule /./, Text
+      end
+
+      state :macro_rules do
+        rule /[$]#{id}(:#{id})?/, Name::Variable
+        rule /[$]/, Name::Variable
+
+        mixin :macro
+      end
+
+      state :has_literals do
+        # constants
+        rule /\b(?:true|false|nil)\b/, Keyword::Constant
+        # characters
+        rule %r(
+          ' (?: #{escapes} | [^\\] ) '
+        )x, Str::Char
+
+        rule /"/, Str, :string
+
+        # numbers
+        dot = /[.][0-9_]+/
+        exp = /e[-+]?[0-9_]+/
+        flt = /f32|f64/
+
+        rule %r(
+          [0-9]+
+          (#{dot}  #{exp}? #{flt}?
+          |#{dot}? #{exp}  #{flt}?
+          |#{dot}? #{exp}? #{flt}
+          )
+        )x, Num::Float
+
+        rule %r(
+          ( 0b[10_]+
+          | 0x[0-9a-fA-F-]+
+          | [0-9]+
+          ) (u#{size}?|i#{size})?
+        )x, Num::Integer
+
+      end
+
+      state :string do
+        rule /"/, Str, :pop!
+        rule escapes, Str::Escape
+        rule /%%/, Str::Interpol
+        rule %r(
+          %
+          ( [0-9]+ [$] )?  # Parameter
+          [0#+-]*          # Flag
+          ( [0-9]+ [$]? )? # Width
+          ( [.] [0-9]+ )?  # Precision
+          [bcdfiostuxX?]   # Type
+        )x, Str::Interpol
+        rule /[^%"\\]+/m, Str
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/sass.rb b/app/server/vendor/rouge/lib/rouge/lexers/sass.rb
new file mode 100755
index 0000000..c749962
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/sass.rb
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    load_const :SassCommon, 'sass/common.rb'
+
+    class Sass < SassCommon
+      include Indentation
+
+      desc 'The Sass stylesheet language language (sass-lang.com)'
+
+      tag 'sass'
+      filenames '*.sass'
+      mimetypes 'text/x-sass'
+
+      id = /[\w-]+/
+
+      state :root do
+        rule /[ \t]*\n/, Text
+        rule(/[ \t]*/) { |m| token Text; indentation(m[0]) }
+      end
+
+      state :content do
+        # block comments
+        rule %r(//.*?\n) do
+          token Comment::Single
+          pop!; starts_block :single_comment
+        end
+
+        rule %r(/[*].*?\n) do
+          token Comment::Multiline
+          pop!; starts_block :multi_comment
+        end
+
+        rule /@import\b/, Keyword, :import
+
+        mixin :content_common
+
+        rule %r(=#{id}), Name::Function, :value
+        rule %r([+]#{id}), Name::Decorator, :value
+
+        rule /:/, Name::Attribute, :old_style_attr
+
+        rule(/(?=.+?:([^a-z]|$))/) { push :attribute }
+
+        rule(//) { push :selector }
+      end
+
+      state :single_comment do
+        rule /.*?\n/, Comment::Single, :pop!
+      end
+
+      state :multi_comment do
+        rule /.*?\n/, Comment::Multiline, :pop!
+      end
+
+      state :import do
+        rule /[ \t]+/, Text
+        rule /\S+/, Str
+        rule /\n/, Text, :pop!
+      end
+
+      state :old_style_attr do
+        mixin :attr_common
+        rule(//) { pop!; push :value }
+      end
+
+      state :end_section do
+        rule(/\n/) { token Text; reset_stack }
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/sass/common.rb b/app/server/vendor/rouge/lib/rouge/lexers/sass/common.rb
new file mode 100755
index 0000000..f87853b
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/sass/common.rb
@@ -0,0 +1,174 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    # shared states with SCSS
+    class SassCommon < RegexLexer
+      id = /[\w-]+/
+
+      state :content_common do
+        rule /@for\b/, Keyword, :for
+        rule /@(debug|warn|if|while)/, Keyword, :value
+        rule /(@mixin)(\s+)(#{id})/ do
+          groups Keyword, Text, Name::Function
+          push :value
+        end
+
+        rule /@extend\b/, Keyword, :selector
+
+        rule /(@include)(\s+)(#{id})/ do
+          groups Keyword, Text, Name::Decorator
+          push :value
+        end
+
+        rule /@#{id}/, Keyword, :selector
+
+        # $variable: assignment
+        rule /([$]#{id})([ \t]*)(:)/ do
+          groups Name::Variable, Text, Punctuation
+          push :value
+        end
+      end
+
+      state :value do
+        mixin :end_section
+        rule /[ \t]+/, Text
+        rule /[$]#{id}/, Name::Variable
+        rule /url[(]/, Str::Other, :string_url
+        rule /#{id}(?=\s*[(])/, Name::Function
+        rule /%#{id}/, Name::Decorator
+
+        # named literals
+        rule /(true|false)\b/, Name::Builtin::Pseudo
+        rule /(and|or|not)\b/, Operator::Word
+
+        # colors and numbers
+        rule /#[a-z0-9]{1,6}/i, Num::Hex
+        rule /-?\d+(%|[a-z]+)?/, Num
+        rule /-?\d*\.\d+(%|[a-z]+)?/, Num::Integer
+
+        mixin :has_strings
+        mixin :has_interp
+
+        rule /[~^*!&%<>\|+=@:,.\/?-]+/, Operator
+        rule /[\[\]()]+/, Punctuation
+        rule %r(/[*]), Comment::Multiline, :inline_comment
+        rule %r(//[^\n]*), Comment::Single
+
+        # identifiers
+        rule(id) do |m|
+          if CSS.builtins.include? m[0]
+            token Name::Builtin
+          elsif CSS.constants.include? m[0]
+            token Name::Constant
+          else
+            token Name
+          end
+        end
+      end
+
+      state :has_interp do
+        rule /[#][{]/, Str::Interpol, :interpolation
+      end
+
+      state :has_strings do
+        rule /"/, Str::Double, :dq
+        rule /'/, Str::Single, :sq
+      end
+
+      state :interpolation do
+        rule /}/, Str::Interpol, :pop!
+        mixin :value
+      end
+
+      state :selector do
+        mixin :end_section
+
+        mixin :has_strings
+        mixin :has_interp
+        rule /[ \t]+/, Text
+        rule /:/, Name::Decorator, :pseudo_class
+        rule /[.]/, Name::Class, :class
+        rule /#/, Name::Namespace, :id
+        rule /%/, Name::Variable, :placeholder
+        rule id, Name::Tag
+        rule /&/, Keyword
+        rule /[~^*!&\[\]()<>\|+=@:;,.\/?-]/, Operator
+      end
+
+      state :dq do
+        rule /"/, Str::Double, :pop!
+        mixin :has_interp
+        rule /(\\.|#(?![{])|[^\n"#])+/, Str::Double
+      end
+
+      state :sq do
+        rule /'/, Str::Single, :pop!
+        mixin :has_interp
+        rule /(\\.|#(?![{])|[^\n'#])+/, Str::Single
+      end
+
+      state :string_url do
+        rule /[)]/, Str::Other, :pop!
+        rule /(\\.|#(?![{])|[^\n)#])+/, Str::Other
+        mixin :has_interp
+      end
+
+      state :selector_piece do
+        mixin :has_interp
+        rule(//) { pop! }
+      end
+
+      state :pseudo_class do
+        rule id, Name::Decorator
+        mixin :selector_piece
+      end
+
+      state :class do
+        rule id, Name::Class
+        mixin :selector_piece
+      end
+
+      state :id do
+        rule id, Name::Namespace
+        mixin :selector_piece
+      end
+
+      state :placeholder do
+        rule id, Name::Variable
+        mixin :selector_piece
+      end
+
+      state :for do
+        rule /(from|to|through)/, Operator::Word
+        mixin :value
+      end
+
+      state :attr_common do
+        mixin :has_interp
+        rule id do |m|
+          if CSS.attributes.include? m[0]
+            token Name::Label
+          else
+            token Name::Attribute
+          end
+        end
+      end
+
+      state :attribute do
+        mixin :attr_common
+
+        rule /([ \t]*)(:)/ do
+          groups Text, Punctuation
+          push :value
+        end
+      end
+
+      state :inline_comment do
+        rule /(\\#|#(?=[^\n{])|\*(?=[^\n\/])|[^\n#*])+/, Comment::Multiline
+        mixin :has_interp
+        rule %r([*]/), Comment::Multiline, :pop!
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/scala.rb b/app/server/vendor/rouge/lib/rouge/lexers/scala.rb
new file mode 100755
index 0000000..0d1b591
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/scala.rb
@@ -0,0 +1,141 @@
+# -*- coding: utf-8 #
+
+module Rouge
+  module Lexers
+    class Scala < RegexLexer
+      desc "The Scala programming language (scala-lang.org)"
+      tag 'scala'
+      aliases 'scala'
+      filenames '*.scala', '*.sbt'
+
+      mimetypes 'text/x-scala', 'application/x-scala'
+
+      # As documented in the ENBF section of the scala specification
+      # http://www.scala-lang.org/docu/files/ScalaReference.pdf
+      whitespace = /\p{Space}/
+      letter = /[\p{L}$_]/
+      upper = /[\p{Lu}$_]/
+      digits = /[0-9]/
+      parens = /[(){}\[\]]/
+      delims = %r([‘’".;,])
+
+      # negative lookahead to filter out other classes
+      op = %r(
+        (?!#{whitespace}|#{letter}|#{digits}|#{parens}|#{delims})
+        [\u0020-\u007F\p{Sm}\p{So}]
+      )x
+
+      idrest = %r(#{letter}(?:#{letter}|#{digits})*(?:(?<=_)#{op}+)?)x
+
+      keywords = %w(
+        abstract case catch def do else extends final finally for forSome
+        if implicit lazy match new override private protected requires return
+        sealed super this throw try val var while with yield
+      )
+
+      state :root do
+        rule /(class|trait|object)(\s+)/ do
+          groups Keyword, Text
+          push :class
+        end
+        rule /'#{idrest}[^']/, Str::Symbol
+        rule /[^\S\n]+/, Text
+
+        rule %r(//.*?\n), Comment::Single
+        rule %r(/\*), Comment::Multiline, :comment
+
+        rule /@#{idrest}/, Name::Decorator
+        rule %r(
+          (#{keywords.join("|")})\b|
+          (<[%:-]|=>|>:|[#=@_\u21D2\u2190])(\b|(?=\s)|$)
+        )x, Keyword
+        rule /:(?!#{op})/, Keyword, :type
+        rule /#{upper}#{idrest}\b/, Name::Class
+        rule /(true|false|null)\b/, Keyword::Constant
+        rule /(import|package)(\s+)/ do
+          groups Keyword, Text
+          push :import
+        end
+
+        rule /(type)(\s+)/ do
+          groups Keyword, Text
+          push :type
+        end
+
+        rule /""".*?"""(?!")/m, Str
+        rule /"(\\\\|\\"|[^"])*"/, Str
+        rule /'\\.'|'[^\\]'|'\\u[0-9a-fA-F]{4}'/, Str::Char
+
+        rule idrest, Name
+        rule /`[^`]+`/, Name
+
+        rule /\[/, Operator, :typeparam
+        rule /[\(\)\{\};,.#]/, Operator
+        rule /#{op}+/, Operator
+
+        rule /([0-9][0-9]*\.[0-9]*|\.[0-9]+)([eE][+-]?[0-9]+)?[fFdD]?/, Num::Float
+        rule /([0-9][0-9]*[fFdD])/, Num::Float
+        rule /0x[0-9a-fA-F]+/, Num::Hex
+        rule /[0-9]+L?/, Num::Integer
+        rule /\n/, Text
+      end
+
+      state :class do
+        rule /(#{idrest}|#{op}+|`[^`]+`)(\s*)(\[)/ do
+          groups Name::Class, Text, Operator
+          push :typeparam
+        end
+
+        rule /\s+/, Text
+        rule /{/, Operator, :pop!
+        rule /\(/, Operator, :pop!
+        rule %r(//.*?\n), Comment::Single, :pop!
+        rule %r(#{idrest}|#{op}+|`[^`]+`), Name::Class, :pop!
+      end
+
+      state :type do
+        rule /\s+/, Text
+        rule /<[%:]|>:|[#_\u21D2]|forSome|type/, Keyword
+        rule /([,\);}]|=>|=)(\s*)/ do
+          groups Operator, Text
+          pop!
+        end
+        rule /[\(\{]/, Operator, :type
+
+        typechunk = /(?:#{idrest}|#{op}+\`[^`]+`)/
+        rule /(#{typechunk}(?:\.#{typechunk})*)(\s*)(\[)/ do
+          groups Keyword::Type, Text, Operator
+          pop!
+          push :typeparam
+        end
+
+        rule /(#{typechunk}(?:\.#{typechunk})*)(\s*)$/ do
+          groups Keyword::Type, Text
+          pop!
+        end
+
+        rule %r(//.*?\n), Comment::Single, :pop!
+        rule /\.|#{idrest}|#{op}+|`[^`]+`/, Keyword::Type
+      end
+
+      state :typeparam do
+        rule /[\s,]+/, Text
+        rule /<[%:]|=>|>:|[#_\u21D2]|forSome|type/, Keyword
+        rule /([\]\)\}])/, Operator, :pop!
+        rule /[\(\[\{]/, Operator, :typeparam
+        rule /\.|#{idrest}|#{op}+|`[^`]+`/, Keyword::Type
+      end
+
+      state :comment do
+        rule %r([^/\*]+), Comment::Multiline
+        rule %r(/\*), Comment::Multiline, :comment
+        rule %r(\*/), Comment::Multiline, :pop!
+        rule %r([*/]), Comment::Multiline
+      end
+
+      state :import do
+        rule %r((#{idrest}|\.)+), Name::Namespace, :pop!
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/scheme.rb b/app/server/vendor/rouge/lib/rouge/lexers/scheme.rb
new file mode 100755
index 0000000..9f2f016
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/scheme.rb
@@ -0,0 +1,111 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Scheme < RegexLexer
+      desc "The Scheme variant of Lisp"
+
+      tag 'scheme'
+      filenames '*.scm', '*.ss'
+      mimetypes 'text/x-scheme', 'application/x-scheme'
+
+      def self.keywords
+        @keywords ||= Set.new %w(
+          lambda define if else cond and or case let let* letrec begin
+          do delay set! => quote quasiquote unquote unquote-splicing
+          define-syntax let-syntax letrec-syntax syntax-rules
+        )
+      end
+
+      def self.builtins
+        @builtins ||= Set.new %w(
+          * + - / < <= = > >= abs acos angle append apply asin
+          assoc assq assv atan boolean? caaaar caaadr caaar caadar
+          caaddr caadr caar cadaar cadadr cadar caddar cadddr caddr
+          cadr call-with-current-continuation call-with-input-file
+          call-with-output-file call-with-values call/cc car cdaaar cdaadr
+          cdaar cdadar cdaddr cdadr cdar cddaar cddadr cddar cdddar cddddr
+          cdddr cddr cdr ceiling char->integer char-alphabetic? char-ci<=?
+          char-ci<? char-ci=? char-ci>=? char-ci>? char-downcase
+          char-lower-case? char-numeric? char-ready? char-upcase
+          char-upper-case? char-whitespace? char<=? char<? char=? char>=?
+          char>? char? close-input-port close-output-port complex? cons
+          cos current-input-port current-output-port denominator
+          display dynamic-wind eof-object? eq?  equal? eqv? eval
+          even? exact->inexact exact? exp expt floor for-each force gcd
+          imag-part inexact->exact inexact? input-port? integer->char
+          integer? interaction-environment lcm length list list->string
+          list->vector list-ref list-tail list?  load log magnitude
+          make-polar make-rectangular make-string make-vector map
+          max member memq memv min modulo negative? newline not
+          null-environment null? number->string number? numerator odd?
+          open-input-file open-output-file output-port? pair?  peek-char
+          port? positive? procedure? quotient rational? rationalize
+          read read-char real-part real?  remainder reverse round
+          scheme-report-environment set-car! set-cdr! sin sqrt string
+          string->list string->number string->symbol string-append
+          string-ci<=?  string-ci<? string-ci=? string-ci>=? string-ci>?
+          string-copy string-fill! string-length string-ref
+          string-set! string<=? string<? string=? string>=?
+          string>? string? substring symbol->string symbol?
+          tan transcript-off transcript-on truncate values vector
+          vector->list vector-fill! vector-length vector-ref
+          vector-set! vector? with-input-from-file with-output-to-file
+          write write-char zero?
+        )
+      end
+
+      id = /[a-z0-9!$\%&*+,\/:<=>?@^_~|-]+/i
+
+      state :root do
+        # comments
+        rule /;.*$/, Comment::Single
+        rule /\s+/m, Text
+        rule /-?\d+\.\d+/, Num::Float
+        rule /-?\d+/, Num::Integer
+
+        # Racket infinitites
+        rule /[+-]inf[.][f0]/, Num
+
+        rule /#b[01]+/, Num::Bin
+        rule /#o[0-7]+/, Num::Oct
+        rule /#d[0-9]+/, Num::Integer
+        rule /#x[0-9a-f]+/i, Num::Hex
+        rule /#[ei][\d.]+/, Num::Other
+
+        rule /"(\\\\|\\"|[^"])*"/, Str
+        rule /'#{id}/i, Str::Symbol
+        rule /#\\([()\/'"._!\$%& ?=+-]{1}|[a-z0-9]+)/i,
+          Str::Char
+        rule /#t|#f/, Name::Constant
+        rule /(?:'|#|`|,@|,|\.)/, Operator
+
+        rule /(['#])(\s*)(\()/m do
+          groups Str::Symbol, Text, Punctuation
+        end
+
+        rule /\(/, Punctuation, :command
+        rule /\)/, Punctuation
+
+        rule id, Name::Variable
+      end
+
+      state :command do
+        rule id, Name::Function do |m|
+          if self.class.keywords.include? m[0]
+            token Keyword
+          elsif self.class.builtins.include? m[0]
+            token Name::Builtin
+          else
+            token Name::Function
+          end
+
+          pop!
+        end
+
+        rule(//) { pop! }
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/scss.rb b/app/server/vendor/rouge/lib/rouge/lexers/scss.rb
new file mode 100755
index 0000000..6c300ac
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/scss.rb
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    load_const :SassCommon, 'sass/common.rb'
+
+    class Scss < SassCommon
+      desc "SCSS stylesheets (sass-lang.com)"
+      tag 'scss'
+      filenames '*.scss'
+      mimetypes 'text/x-scss'
+
+      state :root do
+        rule /\s+/, Text
+        rule %r(//.*?\n), Comment::Single
+        rule %r(/[*].*?[*]/)m, Comment::Multiline
+        rule /@import\b/, Keyword, :value
+
+        mixin :content_common
+
+        rule(/(?=[^;{}][;}])/) { push :attribute }
+        rule(/(?=[^;{}:]+:[^a-z])/) { push :attribute }
+
+        rule(//) { push :selector }
+      end
+
+      state :end_section do
+        rule /\n/, Text
+        rule(/[;{}]/) { token Punctuation; reset_stack }
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/sed.rb b/app/server/vendor/rouge/lib/rouge/lexers/sed.rb
new file mode 100755
index 0000000..cef57e8
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/sed.rb
@@ -0,0 +1,169 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Sed < RegexLexer
+      desc 'sed, the ultimate stream editor'
+
+      tag 'sed'
+      filenames '*.sed'
+      mimetypes 'text/x-sed'
+
+      def self.analyze_text(text)
+        return 1 if text.shebang? 'sed'
+      end
+
+      class Regex < RegexLexer
+        state :root do
+          rule /\\./, Str::Escape
+          rule /\[/, Punctuation, :brackets
+          rule /[$^.*]/, Operator
+          rule /[()]/, Punctuation
+          rule /./, Str::Regex
+        end
+
+        state :brackets do
+          rule /\^?/ do
+            token Punctuation
+            goto :brackets_int
+          end
+        end
+
+        state :brackets_int do
+          # ranges
+          rule /.-./, Name::Variable
+          rule /\]/, Punctuation, :pop!
+          rule /./, Str::Regex
+        end
+      end
+
+      class Replacement < RegexLexer
+        state :root do
+          rule /\\./m, Str::Escape
+          rule /&/, Operator
+          rule /[^\\&]+/m, Text
+        end
+      end
+
+      def regex
+        @regex ||= Regex.new(options)
+      end
+
+      def replacement
+        @replacement ||= Replacement.new(options)
+      end
+
+      start { regex.reset!; replacement.reset! }
+
+      state :whitespace do
+        rule /\s+/m, Text
+        rule(/#.*?\n/) { token Comment; reset_stack }
+        rule(/\n/) { token Text; reset_stack }
+        rule(/;/) { token Punctuation; reset_stack }
+      end
+
+      state :root do
+        mixin :addr_range
+      end
+
+      edot = /\\.|./m
+
+      state :command do
+        mixin :whitespace
+
+        # subst and transliteration
+        rule /(s)(.)(#{edot}*?)(\2)(#{edot}*?)(\2)/m do |m|
+          token Keyword, m[1]
+          token Punctuation, m[2]
+          delegate regex, m[3]
+          token Punctuation, m[4]
+          delegate replacement, m[5]
+          token Punctuation, m[6]
+
+
+          goto :flags
+        end
+
+        rule /(y)(.)(#{edot}*?)(\2)(#{edot}*?)(\2)/m do |m|
+          token Keyword, m[1]
+          token Punctuation, m[2]
+          delegate replacement, m[3]
+          token Punctuation, m[4]
+          delegate replacement, m[5]
+          token Punctuation, m[6]
+
+          pop!
+        end
+
+        # commands that take a text segment as an argument
+        rule /([aic])(\s*)/ do
+          groups Keyword, Text; goto :text
+        end
+
+        rule /[pd]/, Keyword
+
+        # commands that take a number argument
+        rule /([qQl])(\s+)(\d+)/i do
+          groups Keyword, Text, Num
+          pop!
+        end
+
+        # no-argument commands
+        rule /[={}dDgGhHlnpPqx]/, Keyword, :pop!
+
+        # commands that take a filename argument
+        rule /([rRwW])(\s+)(\S+)/ do
+          groups Keyword, Text, Name
+          pop!
+        end
+
+        # commands that take a label argument
+        rule /([:btT])(\s+)(\S+)/ do
+          groups Keyword, Text, Name::Label
+          pop!
+        end
+      end
+
+      state :addr_range do
+        mixin :whitespace
+
+        ### address ranges ###
+        addr_tok = Keyword::Namespace
+        rule /\d+/, addr_tok
+        rule /[$,~+!]/, addr_tok
+
+        rule %r((/)(\\.|.)*?(/)) do |m|
+          token addr_tok, m[1]; delegate regex, m[2]; token addr_tok, m[3]
+        end
+
+        # alternate regex rage delimiters
+        rule %r((\\)(.)(\\.|.)*?(\2)) do |m|
+          token addr_tok, m[1] + m[2]
+          delegate regex, m[3]
+          token addr_tok, m[4]
+        end
+
+        rule(//) { push :command }
+      end
+
+      state :text do
+        rule /[^\\\n]+/, Str
+        rule /\\\n/, Str::Escape
+        rule /\\/, Str
+        rule /\n/, Text, :pop!
+      end
+
+      state :flags do
+        rule /[gp]+/, Keyword, :pop!
+
+        # writing to a file with the subst command.
+        # who'da thunk...?
+        rule /([wW])(\s+)(\S+)/ do
+          token Keyword; token Text; token Name
+        end
+
+        rule(//) { pop! }
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/shell.rb b/app/server/vendor/rouge/lib/rouge/lexers/shell.rb
new file mode 100755
index 0000000..12f08b9
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/shell.rb
@@ -0,0 +1,151 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Shell < RegexLexer
+      desc "Various shell languages, including sh and bash"
+
+      tag 'shell'
+      aliases 'bash', 'zsh', 'ksh', 'sh'
+      filenames '*.sh', '*.bash', '*.zsh', '*.ksh',
+                '.bashrc', '.zshrc', '.kshrc', '.profile'
+
+      mimetypes 'application/x-sh', 'application/x-shellscript'
+
+      def self.analyze_text(text)
+        text.shebang?(/(ba|z|k)?sh/) ? 1 : 0
+      end
+
+      KEYWORDS = %w(
+        if fi else while do done for then return function
+        select continue until esac elif in
+      ).join('|')
+
+      BUILTINS = %w(
+        alias bg bind break builtin caller cd command compgen
+        complete declare dirs disown echo enable eval exec exit
+        export false fc fg getopts hash help history jobs kill let
+        local logout popd printf pushd pwd read readonly set shift
+        shopt source suspend test time times trap true type typeset
+        ulimit umask unalias unset wait
+      ).join('|')
+
+      state :basic do
+        rule /#.*$/, Comment
+
+        rule /\b(#{KEYWORDS})\s*\b/, Keyword
+        rule /\bcase\b/, Keyword, :case
+
+        rule /\b(#{BUILTINS})\s*\b(?!\.)/, Name::Builtin
+
+        rule /^\S*[\$%>#] +/, Generic::Prompt
+
+        rule /(\b\w+)(=)/ do |m|
+          groups Name::Variable, Operator
+        end
+
+        rule /[\[\]{}()=]/, Operator
+        rule /&&|\|\|/, Operator
+        # rule /\|\|/, Operator
+
+        rule /<<</, Operator # here-string
+        rule /<<-?\s*(\'?)\\?(\w+)\1/ do |m|
+          lsh = Str::Heredoc
+          token lsh
+          heredocstr = Regexp.escape(m[2])
+
+          push do
+            rule /\s*#{heredocstr}\s*\n/, lsh, :pop!
+            rule /.*?\n/, lsh
+          end
+        end
+      end
+
+      state :double_quotes do
+        # NB: "abc$" is literally the string abc$.
+        # Here we prevent :interp from interpreting $" as a variable.
+        rule /(?:\$#?)?"/, Str::Double, :pop!
+        mixin :interp
+        rule /[^"`\\$]+/, Str::Double
+      end
+
+      state :single_quotes do
+        rule /'/, Str::Single, :pop!
+        rule /[^']+/, Str::Single
+      end
+
+      state :data do
+        rule /\s+/, Text
+        rule /\\./, Str::Escape
+        rule /\$?"/, Str::Double, :double_quotes
+
+        # single quotes are much easier than double quotes - we can
+        # literally just scan until the next single quote.
+        # POSIX: Enclosing characters in single-quotes ( '' )
+        # shall preserve the literal value of each character within the
+        # single-quotes. A single-quote cannot occur within single-quotes.
+        rule /$?'/, Str::Single, :single_quotes
+
+        rule /\*/, Keyword
+
+        rule /;/, Text
+        rule /[^=\*\s{}()$"'`\\<]+/, Text
+        rule /\d+(?= |\Z)/, Num
+        rule /</, Text
+        mixin :interp
+      end
+
+      state :curly do
+        rule /}/, Keyword, :pop!
+        rule /:-/, Keyword
+        rule /[a-zA-Z0-9_]+/, Name::Variable
+        rule /[^}:"`'$]+/, Punctuation
+        mixin :root
+      end
+
+      state :paren do
+        rule /\)/, Keyword, :pop!
+        mixin :root
+      end
+
+      state :math do
+        rule /\)\)/, Keyword, :pop!
+        rule %r([-+*/%^|&]|\*\*|\|\|), Operator
+        rule /\d+/, Num
+        mixin :root
+      end
+
+      state :case do
+        rule /\besac\b/, Keyword, :pop!
+        rule /\|/, Punctuation
+        rule /\)/, Punctuation, :case_stanza
+        mixin :root
+      end
+
+      state :case_stanza do
+        rule /;;/, Punctuation, :pop!
+        mixin :root
+      end
+
+      state :backticks do
+        rule /`/, Str::Backtick, :pop!
+        mixin :root
+      end
+
+      state :interp do
+        rule /\\$/, Str::Escape # line continuation
+        rule /\\./, Str::Escape
+        rule /\$\(\(/, Keyword, :math
+        rule /\$\(/, Keyword, :paren
+        rule /\${#?/, Keyword, :curly
+        rule /`/, Str::Backtick, :backticks
+        rule /\$#?(\w+|.)/, Name::Variable
+      end
+
+      state :root do
+        mixin :basic
+        mixin :data
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/slim.rb b/app/server/vendor/rouge/lib/rouge/lexers/slim.rb
new file mode 100755
index 0000000..cb07d36
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/slim.rb
@@ -0,0 +1,224 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    # A lexer for the Slim tempalte language
+    # @see http://slim-lang.org
+    class Slim < RegexLexer
+      include Indentation
+
+      desc 'The Slim template language'
+
+      tag 'slim'
+
+      filenames '*.slim'
+
+      # Ruby identifier characters
+      ruby_chars = /[\w\!\?\@\$]/
+
+      # Since you are allowed to wrap lines with a backslash, include \\\n in characters
+      dot = /(\\\n|.)/
+
+      def self.analyze_text(text)
+        return 1 if text.start_with? 'doctype'
+        return 1 if text =~ /(\*)(\{.+?\})/ # Contans a hash splat
+      end
+
+      def ruby
+        @ruby ||= Ruby.new(options)
+      end
+
+      def html
+        @html ||= HTML.new(options)
+      end
+
+      def filters
+        @filters ||= {
+          'ruby' => ruby,
+          'erb' => ERB.new(options),
+          'javascript' => Javascript.new(options),
+          'css' => CSS.new(options),
+          'coffee' => Coffeescript.new(options),
+          'markdown' => Markdown.new(options),
+          'scss' => Scss.new(options),
+          'sass' => Sass.new(options)
+        }
+      end
+
+      state :root do
+        rule /\s*\n/, Text
+        rule(/\s*/) { |m| token Text; indentation(m[0]) }
+      end
+
+      state :content do
+        mixin :css
+
+        rule /\/#{dot}*/, Comment, :indented_block
+
+        rule /(doctype)(\s+)(.*)/ do
+          groups Name::Namespace, Text::Whitespace, Text
+          pop!
+        end
+
+        # filters, shamelessly ripped from HAML
+        rule /(\w*):\s*\n/ do |m|
+          token Name::Decorator
+          pop!
+          starts_block :filter_block
+
+          filter_name = m[1].strip
+
+          @filter_lexer = self.filters[filter_name]
+          @filter_lexer.reset! unless @filter_lexer.nil?
+
+          puts "    slim: filter #{filter_name.inspect} #{@filter_lexer.inspect}" if @debug
+        end
+
+        # Text
+        rule %r([\|'](?=\s)) do
+          token Punctuation
+          pop!
+          starts_block :plain_block
+          goto :plain_block
+        end
+
+        rule /-|==|=/, Punctuation, :ruby_line
+
+        # Dynamic tags
+        rule /(\*)(#{ruby_chars}+\(.*?\))/ do |m|
+          token Punctuation, m[1]
+          delegate ruby, m[2]
+          push :tag
+        end
+
+        rule /(\*)(#{ruby_chars}+)/ do |m|
+          token Punctuation, m[1]
+          delegate ruby, m[2]
+          push :tag
+        end
+
+        #rule /<\w+(?=.*>)/, Keyword::Constant, :tag # Maybe do this, look ahead and stuff
+        rule %r((</?[\w\s\=\'\"]+?/?>)) do |m| # Dirty html
+          delegate html, m[1]
+          pop!
+        end
+
+        # Ordinary slim tags
+        rule /\w+/, Name::Tag, :tag
+
+      end
+
+      state :tag do
+        mixin :css
+        mixin :indented_block
+        mixin :interpolation
+
+        # Whitespace control
+        rule /[<>]/, Punctuation
+
+        # Trim whitespace
+        rule /\s+?/, Text::Whitespace
+
+        # Splats, these two might be mergable?
+        rule /(\*)(#{ruby_chars}+)/ do |m|
+          token Punctuation, m[1]
+          delegate ruby, m[2]
+        end
+
+        rule /(\*)(\{#{dot}+?\})/ do |m|
+          token Punctuation, m[1]
+          delegate ruby, m[2]
+        end
+
+        # Attributes
+        rule /([\w\-]+)(\s*)(\=)/ do |m|
+          token Name::Attribute, m[1]
+          token Text::Whitespace, m[2]
+          token Punctuation, m[3]
+          push :html_attr
+        end
+
+        # Ruby value
+        rule /(\=)(#{dot}+)/ do |m|
+          token Punctuation, m[1]
+          #token Keyword::Constant, m[2]
+          delegate ruby, m[2]
+        end
+
+        rule /#{dot}+?/, Text
+
+        rule /\s*\n/, Text::Whitespace, :pop!
+      end
+
+      state :css do
+        rule(/\.\w+/) { token Name::Class; goto :tag }
+        rule(/#\w+/) { token Name::Function; goto :tag }
+      end
+
+      state :html_attr do
+        # Strings, double/single quoted
+        rule %r(\s*(['"])#{dot}*\1), Literal::String, :pop!
+
+        # Ruby stuff
+        rule(/(#{ruby_chars}+\(.*?\))/) { |m| delegate ruby, m[1]; pop! }
+        rule(/(#{ruby_chars}+)/) { |m| delegate ruby, m[1]; pop! }
+
+        rule /\s+/, Text::Whitespace
+      end
+
+      state :ruby_line do
+        # Need at top
+        mixin :indented_block
+
+        rule(/,\s*\n/) { delegate ruby }
+        rule /[ ]\|[ \t]*\n/, Str::Escape
+        rule(/.*?(?=(,$| \|)?[ \t]*$)/) { delegate ruby }
+      end
+
+      state :filter_block do
+        rule /([^#\n]|#[^{\n]|(\\\\)*\\#\{)+/ do
+          if @filter_lexer
+            delegate @filter_lexer
+          else
+            token Name::Decorator
+          end
+        end
+
+        mixin :interpolation
+        mixin :indented_block
+      end
+
+      state :plain_block do
+        mixin :interpolation
+
+        rule %r((</?[\w\s\=\'\"]+?/?>)) do |m| # Dirty html
+          delegate html, m[1]
+        end
+
+        #rule /([^#\n]|#[^{\n]|(\\\\)*\\#\{)+/ do
+        rule /#{dot}+?/, Text
+
+        mixin :indented_block
+      end
+
+      state :interpolation do
+        rule /#[{]/, Str::Interpol, :ruby_interp
+      end
+
+      state :ruby_interp do
+        rule /[}]/, Str::Interpol, :pop!
+        mixin :ruby_interp_inner
+      end
+
+      state :ruby_interp_inner do
+        rule(/[{]/) { delegate ruby; push :ruby_interp_inner }
+        rule(/[}]/) { delegate ruby; pop! }
+        rule(/[^{}]+/) { delegate ruby }
+      end
+
+      state :indented_block do
+        rule(/(?<!\\)\n/) { token Text; reset_stack }
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/smalltalk.rb b/app/server/vendor/rouge/lib/rouge/lexers/smalltalk.rb
new file mode 100755
index 0000000..7a3cd27
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/smalltalk.rb
@@ -0,0 +1,115 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Smalltalk < RegexLexer
+      desc 'The Smalltalk programming language'
+
+      tag 'smalltalk'
+      aliases 'st', 'squeak'
+      filenames '*.st'
+      mimetypes 'text/x-smalltalk'
+
+      ops = %r([-+*/\\~<>=|&!?,@%])
+
+      state :root do
+        rule /(<)(\w+:)(.*?)(>)/ do
+          groups Punctuation, Keyword, Text, Punctuation
+        end
+
+        # mixin :squeak_fileout
+        mixin :whitespaces
+        mixin :method_definition
+        rule /([|])([\w\s]*)([|])/ do
+          groups Punctuation, Name::Variable, Punctuation
+        end
+        mixin :objects
+        rule /\^|:=|_/, Operator
+
+        rule /[)}\]]/, Punctuation, :after_object
+        rule /[({\[!]/, Punctuation
+      end
+
+      state :method_definition do
+        rule /([a-z]\w*:)(\s*)(\w+)/i do
+          groups Name::Function, Text, Name::Variable
+        end
+
+        rule /^(\s*)(\b[a-z]\w*\b)(\s*)$/i do
+          groups Text, Name::Function, Text
+        end
+
+        rule %r(^(\s*)(#{ops}+)(\s*)(\w+)(\s*)$) do
+          groups Text, Name::Function, Text, Name::Variable, Text
+        end
+      end
+
+      state :block_variables do
+        mixin :whitespaces
+        rule /(:)(\s*)(\w+)/ do
+          groups Operator, Text, Name::Variable
+        end
+
+        rule /[|]/, Punctuation, :pop!
+
+        rule(//) { pop! }
+      end
+
+      state :literals do
+        rule /'(''|.)*?'/m, Str, :after_object
+        rule /[$]./, Str::Char, :after_object
+        rule /#[(]/, Str::Symbol, :parenth
+        rule /(\d+r)?-?\d+(\.\d+)?(e-?\d+)?/,
+          Num, :after_object
+        rule /#("[^"]*"|#{ops}+|[\w:]+)/,
+          Str::Symbol, :after_object
+      end
+
+      state :parenth do
+        rule /[)]/ do
+          token Str::Symbol
+          goto :after_object
+        end
+
+        mixin :inner_parenth
+      end
+
+      state :inner_parenth do
+        rule /#[(]/, Str::Symbol, :inner_parenth
+        rule /[)]/, Str::Symbol, :pop!
+        mixin :whitespaces
+        mixin :literals
+        rule /(#{ops}|[\w:])+/, Str::Symbol
+      end
+
+      state :whitespaces do
+        rule /! !$/, Keyword # squeak chunk delimiter
+        rule /\s+/m, Text
+        rule /".*?"/m, Comment
+      end
+
+      state :objects do
+        rule /\[/, Punctuation, :block_variables
+        rule /(self|super|true|false|nil|thisContext)\b/,
+          Name::Builtin::Pseudo, :after_object
+        rule /[A-Z]\w*(?!:)\b/, Name::Class, :after_object
+        rule /[a-z]\w*(?!:)\b/, Name::Variable, :after_object
+        mixin :literals
+      end
+
+      state :after_object do
+        mixin :whitespaces
+        rule /(ifTrue|ifFalse|whileTrue|whileFalse|timesRepeat):/,
+          Name::Builtin, :pop!
+        rule /new(?!:)\b/, Name::Builtin
+        rule /:=|_/, Operator, :pop!
+        rule /[a-z]+\w*:/i, Name::Function, :pop!
+        rule /[a-z]+\w*/i, Name::Function
+        rule /#{ops}+/, Name::Function, :pop!
+        rule /[.]/, Punctuation, :pop!
+        rule /;/, Punctuation
+        rule(//) { pop! }
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/sml.rb b/app/server/vendor/rouge/lib/rouge/lexers/sml.rb
new file mode 100755
index 0000000..318ea52
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/sml.rb
@@ -0,0 +1,347 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class SML < RegexLexer
+      desc 'Standard ML'
+      tag 'sml'
+      aliases 'ml'
+      filenames '*.sml', '*.sig', '*.fun'
+
+      mimetypes 'text/x-standardml', 'application/x-standardml'
+
+      def self.keywords
+        @keywords ||= Set.new %w(
+          abstype and andalso as case datatype do else end exception
+          fn fun handle if in infix infixr let local nonfix of op open
+          orelse raise rec then type val with withtype while
+          eqtype functor include sharing sig signature struct structure
+          where
+        )
+      end
+
+      def self.symbolic_reserved
+        @symbolic_reserved ||= Set.new %w(: | = => -> # :>)
+      end
+
+      id = /[\w']+/i
+      symbol = %r([!%&$#/:<=>?@\\~`^|*+-]+)
+
+      def self.analyze_text(text)
+        return 0
+      end
+
+      state :whitespace do
+        rule /\s+/m, Text
+        rule /[(][*]/, Comment, :comment
+      end
+
+      state :delimiters do
+        rule /[(\[{]/, Punctuation, :main
+        rule /[)\]}]/, Punctuation, :pop!
+
+        rule /\b(let|if|local)\b(?!')/, Keyword::Reserved do
+          push; push
+        end
+
+        rule /\b(struct|sig|while)\b(?!')/ do
+          token Keyword::Reserved
+          push
+        end
+
+        rule /\b(do|else|end|in|then)\b(?!')/, Keyword::Reserved, :pop!
+      end
+
+      def token_for_id_with_dot(id)
+        if self.class.keywords.include? id
+          Error
+        else
+          Name::Namespace
+        end
+      end
+
+      def token_for_final_id(id)
+        if self.class.keywords.include? id or self.class.symbolic_reserved.include? id
+          Error
+        else
+          Name
+        end
+      end
+
+      def token_for_id(id)
+        if self.class.keywords.include? id
+          Keyword::Reserved
+        elsif self.class.symbolic_reserved.include? id
+          Punctuation
+        else
+          Name
+        end
+      end
+
+      state :core do
+        rule /[()\[\]{},;_]|[.][.][.]/, Punctuation
+        rule /#"/, Str::Char, :char
+        rule /"/, Str::Double, :string
+        rule /~?0x[0-9a-fA-F]+/, Num::Hex
+        rule /0wx[0-9a-fA-F]+/, Num::Hex
+        rule /0w\d+/, Num::Integer
+        rule /~?\d+([.]\d+)?[eE]~?\d+/, Num::Float
+        rule /~?\d+[.]\d+/, Num::Float
+        rule /~?\d+/, Num::Integer
+
+        rule /#\s*[1-9][0-9]*/, Name::Label
+        rule /#\s*#{id}/, Name::Label
+        rule /#\s+#{symbol}/, Name::Label
+
+        rule /\b(datatype|abstype)\b(?!')/, Keyword::Reserved, :dname
+        rule(/(?=\bexception\b(?!'))/) { push :ename }
+        rule /\b(functor|include|open|signature|structure)\b(?!')/,
+          Keyword::Reserved, :sname
+        rule /\b(type|eqtype)\b(?!')/, Keyword::Reserved, :tname
+
+        rule /'#{id}/, Name::Decorator
+        rule /(#{id})([.])/ do |m|
+          groups(token_for_id_with_dot(m[1]), Punctuation)
+          push :dotted
+        end
+
+        rule id do |m|
+          token token_for_id(m[0])
+        end
+
+        rule symbol do |m|
+          token token_for_id(m[0])
+        end
+      end
+
+      state :dotted do
+        rule /(#{id})([.])/ do |m|
+          groups(token_for_id_with_dot(m[1]), Punctuation)
+        end
+
+        rule id do |m|
+          token token_for_id(m[0])
+          pop!
+        end
+
+        rule symbol do |m|
+          token token_for_id(m[0])
+          pop!
+        end
+      end
+
+      state :root do
+        rule /#!.*?\n/, Comment::Preproc
+        rule(//) { push :main }
+      end
+
+      state :main do
+        mixin :whitespace
+
+        rule /\b(val|and)\b(?!')/, Keyword::Reserved, :vname
+        rule /\b(fun)\b(?!')/ do
+          token Keyword::Reserved
+          goto :main_fun
+          push :fname
+        end
+
+        mixin :delimiters
+        mixin :core
+      end
+
+      state :main_fun do
+        mixin :whitespace
+        rule /\b(fun|and)\b(?!')/, Keyword::Reserved, :fname
+        rule /\bval\b(?!')/ do
+          token Keyword::Reserved
+          goto :main
+          push :vname
+        end
+
+        rule /[|]/, Punctuation, :fname
+        rule /\b(case|handle)\b(?!')/ do
+          token Keyword::Reserved
+          goto :main
+        end
+
+        mixin :delimiters
+        mixin :core
+      end
+
+      state :has_escapes do
+        rule /\\[\\"abtnvfr]/, Str::Escape
+        rule /\\\^[\x40-\x5e]/, Str::Escape
+        rule /\\[0-9]{3}/, Str::Escape
+        rule /\\u\h{4}/, Str::Escape
+        rule /\\\s+\\/, Str::Interpol
+      end
+
+      state :string do
+        rule /[^"\\]+/, Str::Double
+        rule /"/, Str::Double, :pop!
+        mixin :has_escapes
+      end
+
+      state :char do
+        rule /[^"\\]+/, Str::Char
+        rule /"/, Str::Char, :pop!
+        mixin :has_escapes
+      end
+
+      state :breakout do
+        rule /(?=\w+\b(#{SML.keywords.to_a.join('|')})\b(?!'))/ do
+          pop!
+        end
+      end
+
+      state :sname do
+        mixin :whitespace
+        mixin :breakout
+        rule id, Name::Namespace
+        rule(//) { pop! }
+      end
+
+      state :has_annotations do
+        rule /'[\w']*/, Name::Decorator
+        rule /[(]/, Punctuation, :tyvarseq
+      end
+
+      state :fname do
+        mixin :whitespace
+        mixin :has_annotations
+
+        rule id, Name::Function, :pop!
+        rule symbol, Name::Function, :pop!
+      end
+
+      state :vname do
+        mixin :whitespace
+        mixin :has_annotations
+
+        rule /(#{id})(\s*)(=(?!#{symbol}))/m do
+          groups Name::Variable, Text, Punctuation
+          pop!
+        end
+
+        rule /(#{symbol})(\s*)(=(?!#{symbol}))/m do
+          groups Name::Variable, Text, Punctuation
+        end
+
+        rule id, Name::Variable, :pop!
+        rule symbol, Name::Variable, :pop!
+
+        rule(//) { pop! }
+      end
+
+      state :tname do
+        mixin :whitespace
+        mixin :breakout
+        mixin :has_annotations
+
+        rule /'[\w']*/, Name::Decorator
+        rule /[(]/, Punctuation, :tyvarseq
+
+        rule %r(=(?!#{symbol})) do
+          token Punctuation
+          goto :typbind
+        end
+
+        rule id, Keyword::Type
+        rule symbol, Keyword::Type
+      end
+
+      state :typbind do
+        mixin :whitespace
+
+        rule /\b(and)\b(?!')/ do
+          token Keyword::Reserved
+          goto :tname
+        end
+
+        mixin :breakout
+        mixin :core
+      end
+
+      state :dname do
+        mixin :whitespace
+        mixin :breakout
+        mixin :has_annotations
+
+        rule /(=)(\s*)(datatype)\b/ do
+          groups Punctuation, Text, Keyword::Reserved
+          pop!
+        end
+
+        rule %r(=(?!#{symbol})) do
+          token Punctuation
+          goto :datbind
+          push :datcon
+        end
+
+        rule id, Keyword::Type
+        rule symbol, Keyword::Type
+      end
+
+      state :datbind do
+        mixin :whitespace
+        rule /\b(and)\b(?!')/ do
+          token Keyword::Reserved; goto :dname
+        end
+        rule /\b(withtype)\b(?!')/ do
+          token Keyword::Reserved; goto :tname
+        end
+        rule /\bof\b(?!')/, Keyword::Reserved
+        rule /([|])(\s*)(#{id})/ do
+          groups(Punctuation, Text, Name::Class)
+        end
+
+        rule /([|])(\s+)(#{symbol})/ do
+          groups(Punctuation, Text, Name::Class)
+        end
+
+        mixin :breakout
+        mixin :core
+      end
+
+      state :ename do
+        mixin :whitespace
+        rule /(exception|and)(\s+)(#{id})/ do
+          groups Keyword::Reserved, Text, Name::Class
+        end
+
+        rule /(exception|and)(\s*)(#{symbol})/ do
+          groups Keyword::Reserved, Text, Name::Class
+        end
+
+        rule /\b(of)\b(?!')/, Keyword::Reserved
+        mixin :breakout
+        mixin :core
+      end
+
+      state :datcon do
+        mixin :whitespace
+        rule id, Name::Class, :pop!
+        rule symbol, Name::Class, :pop!
+      end
+
+      state :tyvarseq do
+        mixin :whitespace
+        rule /'[\w']*/, Name::Decorator
+        rule id, Name
+        rule /,/, Punctuation
+        rule /[)]/, Punctuation, :pop!
+        rule symbol, Name
+      end
+
+      state :comment do
+        rule /[^(*)]+/, Comment::Multiline
+        rule /[(][*]/ do
+          token Comment::Multiline; push
+        end
+        rule /[*][)]/, Comment::Multiline, :pop!
+        rule /[(*)]/, Comment::Multiline
+      end
+    end
+  end
+end
+
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/sql.rb b/app/server/vendor/rouge/lib/rouge/lexers/sql.rb
new file mode 100755
index 0000000..c36bf00
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/sql.rb
@@ -0,0 +1,139 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class SQL < RegexLexer
+      desc "Structured Query Language, for relational databases"
+      tag 'sql'
+      filenames '*.sql'
+      mimetypes 'text/x-sql'
+
+      def self.keywords
+        @keywords ||= Set.new %w(
+          ABORT ABS ABSOLUTE ACCESS ADA ADD ADMIN AFTER AGGREGATE ALIAS
+          ALL ALLOCATE ALTER ANALYSE ANALYZE AND ANY ARE AS ASC ASENSITIVE
+          ASSERTION ASSIGNMENT ASYMMETRIC AT ATOMIC AUTHORIZATION
+          AVG BACKWARD BEFORE BEGIN BETWEEN BITVAR BIT_LENGTH BOTH
+          BREADTH BY C CACHE CALL CALLED CARDINALITY CASCADE CASCADED
+          CASE CAST CATALOG CATALOG_NAME CHAIN CHARACTERISTICS
+          CHARACTER_LENGTH CHARACTER_SET_CATALOG CHARACTER_SET_NAME
+          CHARACTER_SET_SCHEMA CHAR_LENGTH CHECK CHECKED CHECKPOINT
+          CLASS CLASS_ORIGIN CLOB CLOSE CLUSTER COALSECE COBOL COLLATE
+          COLLATION COLLATION_CATALOG COLLATION_NAME COLLATION_SCHEMA
+          COLUMN COLUMN_NAME COMMAND_FUNCTION COMMAND_FUNCTION_CODE
+          COMMENT COMMIT COMMITTED COMPLETION CONDITION_NUMBER
+          CONNECT CONNECTION CONNECTION_NAME CONSTRAINT CONSTRAINTS
+          CONSTRAINT_CATALOG CONSTRAINT_NAME CONSTRAINT_SCHEMA
+          CONSTRUCTOR CONTAINS CONTINUE CONVERSION CONVERT COPY
+          CORRESPONTING COUNT CREATE CREATEDB CREATEUSER CROSS CUBE
+          CURRENT CURRENT_DATE CURRENT_PATH CURRENT_ROLE CURRENT_TIME
+          CURRENT_TIMESTAMP CURRENT_USER CURSOR CURSOR_NAME CYCLE DATA
+          DATABASE DATETIME_INTERVAL_CODE DATETIME_INTERVAL_PRECISION
+          DAY DEALLOCATE DECLARE DEFAULT DEFAULTS DEFERRABLE DEFERRED
+          DEFINED DEFINER DELETE DELIMITER DELIMITERS DEREF DESC DESCRIBE
+          DESCRIPTOR DESTROY DESTRUCTOR DETERMINISTIC DIAGNOSTICS
+          DICTIONARY DISCONNECT DISPATCH DISTINCT DO DOMAIN DROP
+          DYNAMIC DYNAMIC_FUNCTION DYNAMIC_FUNCTION_CODE EACH ELSE
+          ENCODING ENCRYPTED END END-EXEC EQUALS ESCAPE EVERY EXCEPT
+          ESCEPTION EXCLUDING EXCLUSIVE EXEC EXECUTE EXISTING EXISTS
+          EXPLAIN EXTERNAL EXTRACT FALSE FETCH FINAL FIRST FOR FORCE
+          FOREIGN FORTRAN FORWARD FOUND FREE FREEZE FROM FULL FUNCTION
+          G GENERAL GENERATED GET GLOBAL GO GOTO GRANT GRANTED GROUP
+          GROUPING HANDLER HAVING HIERARCHY HOLD HOST IDENTITY IGNORE
+          ILIKE IMMEDIATE IMMUTABLE IMPLEMENTATION IMPLICIT IN INCLUDING
+          INCREMENT INDEX INDITCATOR INFIX INHERITS INITIALIZE INITIALLY
+          INNER INOUT INPUT INSENSITIVE INSERT INSTANTIABLE INSTEAD
+          INTERSECT INTO INVOKER IS ISNULL ISOLATION ITERATE JOIN KEY
+          KEY_MEMBER KEY_TYPE LANCOMPILER LANGUAGE LARGE LAST LATERAL
+          LEADING LEFT LENGTH LESS LEVEL LIKE LIMIT LISTEN LOAD LOCAL
+          LOCALTIME LOCALTIMESTAMP LOCATION LOCATOR LOCK LOWER MAP MATCH
+          MAX MAXVALUE MESSAGE_LENGTH MESSAGE_OCTET_LENGTH MESSAGE_TEXT
+          METHOD MIN MINUTE MINVALUE MOD MODE MODIFIES MODIFY MONTH
+          MORE MOVE MUMPS NAMES NATIONAL NATURAL NCHAR NCLOB NEW NEXT
+          NO NOCREATEDB NOCREATEUSER NONE NOT NOTHING NOTIFY NOTNULL
+          NULL NULLABLE NULLIF OBJECT OCTET_LENGTH OF OFF OFFSET OIDS
+          OLD ON ONLY OPEN OPERATION OPERATOR OPTION OPTIONS OR ORDER
+          ORDINALITY OUT OUTER OUTPUT OVERLAPS OVERLAY OVERRIDING
+          OWNER PAD PARAMETER PARAMETERS PARAMETER_MODE PARAMATER_NAME
+          PARAMATER_ORDINAL_POSITION PARAMETER_SPECIFIC_CATALOG
+          PARAMETER_SPECIFIC_NAME PARAMATER_SPECIFIC_SCHEMA PARTIAL PASCAL
+          PENDANT PLACING PLI POSITION POSTFIX PRECISION PREFIX PREORDER
+          PREPARE PRESERVE PRIMARY PRIOR PRIVILEGES PROCEDURAL PROCEDURE
+          PUBLIC READ READS RECHECK RECURSIVE REF REFERENCES REFERENCING
+          REINDEX RELATIVE RENAME REPEATABLE REPLACE RESET RESTART
+          RESTRICT RESULT RETURN RETURNED_LENGTH RETURNED_OCTET_LENGTH
+          RETURNED_SQLSTATE RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP
+          ROUTINE ROUTINE_CATALOG ROUTINE_NAME ROUTINE_SCHEMA ROW ROWS
+          ROW_COUNT RULE SAVE_POINT SCALE SCHEMA SCHEMA_NAME SCOPE SCROLL
+          SEARCH SECOND SECURITY SELECT SELF SENSITIVE SERIALIZABLE
+          SERVER_NAME SESSION SESSION_USER SET SETOF SETS SHARE SHOW
+          SIMILAR SIMPLE SIZE SOME SOURCE SPACE SPECIFIC SPECIFICTYPE
+          SPECIFIC_NAME SQL SQLCODE SQLERROR SQLEXCEPTION SQLSTATE
+          SQLWARNINIG STABLE START STATE STATEMENT STATIC STATISTICS
+          STDIN STDOUT STORAGE STRICT STRUCTURE STYPE SUBCLASS_ORIGIN
+          SUBLIST SUBSTRING SUM SYMMETRIC SYSID SYSTEM SYSTEM_USER
+          TABLE TABLE_NAME  TEMP TEMPLATE TEMPORARY TERMINATE THAN THEN
+          TIMESTAMP TIMEZONE_HOUR TIMEZONE_MINUTE TO TOAST TRAILING
+          TRANSATION TRANSACTIONS_COMMITTED TRANSACTIONS_ROLLED_BACK
+          TRANSATION_ACTIVE TRANSFORM TRANSFORMS TRANSLATE TRANSLATION
+          TREAT TRIGGER TRIGGER_CATALOG TRIGGER_NAME TRIGGER_SCHEMA TRIM
+          TRUE TRUNCATE TRUSTED TYPE UNCOMMITTED UNDER UNENCRYPTED UNION
+          UNIQUE UNKNOWN UNLISTEN UNNAMED UNNEST UNTIL UPDATE UPPER
+          USAGE USER USER_DEFINED_TYPE_CATALOG USER_DEFINED_TYPE_NAME
+          USER_DEFINED_TYPE_SCHEMA USING VACUUM VALID VALIDATOR VALUES
+          VARIABLE VERBOSE VERSION VIEW VOLATILE WHEN WHENEVER WHERE
+          WITH WITHOUT WORK WRITE YEAR ZONE
+        )
+      end
+
+      state :root do
+        rule /\s+/m, Text
+        rule /--.*?\n/, Comment::Single
+        rule %r(/\*), Comment::Multiline, :multiline_comments
+        rule /\d+/, Num::Integer
+        rule /'/, Str::Single, :single_string
+        rule /"/, Name::Variable, :double_string
+        rule /`/, Name::Variable, :backtick
+
+        rule /\w[\w\d]*/ do |m|
+          if self.class.keywords.include? m[0].upcase
+            token Keyword
+          else
+            token Name
+          end
+        end
+
+        rule %r([+*/<>=~!@#%^&|?^-]), Operator
+        rule /[;:()\[\],.]/, Punctuation
+      end
+
+      state :multiline_comments do
+        rule %r(/[*]), Comment::Multiline, :multiline_comments
+        rule %r([*]/), Comment::Multiline, :pop!
+        rule %r([^/*]+), Comment::Multiline
+        rule %r([/*]), Comment::Multiline
+      end
+
+      state :backtick do
+        rule /\\./, Str::Escape
+        rule /``/, Str::Escape
+        rule /`/, Name::Variable, :pop!
+        rule /[^\\`]+/, Name::Variable
+      end
+
+      state :single_string do
+        rule /\\./, Str::Escape
+        rule /''/, Str::Escape
+        rule /'/, Str::Single, :pop!
+        rule /[^\\']+/, Str::Single
+      end
+
+      state :double_string do
+        rule /\\./, Str::Escape
+        rule /""/, Str::Escape
+        rule /"/, Name::Variable, :pop!
+        rule /[^\\"]+/, Name::Variable
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/swift.rb b/app/server/vendor/rouge/lib/rouge/lexers/swift.rb
new file mode 100755
index 0000000..7a83a66
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/swift.rb
@@ -0,0 +1,189 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class Swift < RegexLexer
+      tag 'swift'
+      filenames '*.swift'
+
+      desc 'Multi paradigm, compiled programming language developed by Apple for iOS and OS X development. (developer.apple.com/swift)'
+
+      id_head = /_|(?!\p{Mc})\p{Alpha}|[^\u0000-\uFFFF]/
+      id_rest = /[\p{Alnum}_]|[^\u0000-\uFFFF]/
+      id = /#{id_head}#{id_rest}*/
+
+      def self.keywords
+        @keywords ||= Set.new %w(
+          break case continue default do else fallthrough if in for return switch where while
+
+          as dynamicType is new super self Self Type __COLUMN__ __FILE__ __FUNCTION__ __LINE__
+
+          associativity didSet get infix inout left mutating none nonmutating operator override postfix precedence prefix right set unowned weak willSet
+        )
+      end
+
+      def self.declarations
+        @declarations ||= Set.new %w(
+          class deinit enum extension final func import init internal lazy let optional private protocol public required static struct subscript typealias var dynamic
+        )
+      end
+
+      def self.at_keywords
+        @at_keywords ||= %w(
+          autoclosure IBAction IBDesignable IBInspectable IBOutlet noreturn NSCopying NSManaged objc UIApplicationMain
+        )
+      end
+
+      def self.types
+        @types ||= Set.new %w(
+          Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Int
+          Double Float
+          Bool
+          String Character
+          AnyObject Any
+        )
+      end
+
+      def self.constants
+        @constants ||= Set.new %w(
+          true false nil
+        )
+      end
+
+      state :whitespace do
+        rule /\s+/m, Text
+        rule %r(\/\/.*?\n), Comment::Single
+        rule %r((?<re>\/\*(?:(?>[^\/\*\*\/]+)|\g<re>)*\*\/))m, Comment::Multiline
+      end
+
+      state :root do
+        mixin :whitespace
+        rule /\$(([1-9]\d*)?\d)/, Name::Variable
+
+        rule %r{[()\[\]{}:;,?]}, Punctuation
+        rule %r([-/=+*%<>!&|^.~]+), Operator
+        rule /@?"/, Str, :dq
+        rule /'(\\.|.)'/, Str::Char
+        rule /(\d+\*|\d*\.\d+)(e[+-]?[0-9]+)?/i, Num::Float
+        rule /\d+e[+-]?[0-9]+/i, Num::Float
+        rule /0_?[0-7]+(?:_[0-7]+)*/, Num::Oct
+        rule /0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*/, Num::Hex
+        rule /0b[01]+(?:_[01]+)*/, Num::Bin
+        rule %r{[\d]+(?:_\d+)*}, Num::Integer
+
+        rule /(?!\b(if|while|for|private|internal|unowned|@objc)\b)\b#{id}(?=(\?|!)?\s*[(])/ do |m|
+          if m[0] =~ /^[[:upper:]]/
+            token Name::Constant
+          else
+            token Name::Function
+          end
+        end
+
+        rule /(#?(?!default)#{id})(\s*)(:)/ do
+          groups Name::Variable, Text, Punctuation
+        end
+
+        rule /(let|var)\b(\s*)(#{id})/ do
+          groups Keyword, Text, Name::Variable
+        end
+
+        rule /@availability[(][^)]+[)]/, Keyword::Declaration
+
+        rule /(@objc[(])([^)]+)([)])/ do
+          groups Keyword::Declaration, Name::Class, Keyword::Declaration
+        end
+
+        rule /@(#{id})/ do |m|
+          if self.class.at_keywords.include? m[1]
+            token Keyword
+          else
+            token Error
+          end
+        end
+
+        rule /(private|internal)(\([ ]*)(\w+)([ ]*\))/ do |m|
+          if m[3] == 'set'
+            token Keyword::Declaration
+          else
+            groups Keyword::Declaration, Keyword::Declaration, Error, Keyword::Declaration
+          end
+        end
+
+        rule /(unowned\([ ]*)(\w+)([ ]*\))/ do |m|
+          if m[2] == 'safe' || m[2] == 'unsafe'
+            token Keyword::Declaration
+          else
+            groups Keyword::Declaration, Error, Keyword::Declaration
+          end
+        end
+
+        rule id do |m|
+          if self.class.keywords.include? m[0]
+            token Keyword
+          elsif self.class.declarations.include? m[0]
+            token Keyword::Declaration
+            if %w(protocol class extension struct enum).include? m[0]
+              push :type_definition
+            end
+          elsif self.class.types.include? m[0]
+            token Keyword::Type
+          elsif self.class.constants.include? m[0]
+            token Keyword::Constant
+          else
+            token Name
+          end
+        end
+        rule id, Name
+      end
+
+      state :dq do
+        rule /\\[\\0tnr'"]/, Str::Escape
+        rule /\\[(]/, Str::Escape, :interp
+        rule /\\u\{\h{1,8}\}/, Str::Escape
+        rule /[^\\"]+/, Str
+        rule /"/, Str, :pop!
+      end
+
+      state :interp do
+        rule /[(]/, Punctuation, :interp_inner
+        rule /[)]/, Str::Escape, :pop!
+        mixin :root
+      end
+
+      state :interp_inner do
+        rule /[(]/, Punctuation, :push
+        rule /[)]/, Punctuation, :pop!
+        mixin :root
+      end
+
+      state :type_definition do
+        mixin :whitespace
+        rule id, Name::Constant
+        rule /</, Punctuation, :type_param_list
+        rule /:/, Punctuation, :supertype_list
+        rule(//) { pop! }
+      end
+
+      state :supertype_list do
+        mixin :whitespace
+        rule id, Name::Constant
+        rule /,/, Punctuation, :push
+        rule(//) { pop! }
+      end
+
+      state :type_param_list do
+        mixin :whitespace
+        rule id, Text
+        rule /,/, Punctuation, :type_param_list
+        rule />/, Punctuation, :pop!
+        rule(//) { pop! }
+      end
+
+      state :namespace do
+        mixin :whitespace
+        rule /(?=[(])/, Text, :pop!
+        rule /(#{id}|[.])+/, Name::Namespace, :pop!
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/tcl.rb b/app/server/vendor/rouge/lib/rouge/lexers/tcl.rb
new file mode 100755
index 0000000..221bea1
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/tcl.rb
@@ -0,0 +1,191 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class TCL < RegexLexer
+      desc "The Tool Command Language (tcl.tk)"
+      tag 'tcl'
+      filenames '*.tcl'
+      mimetypes 'text/x-tcl', 'text/x-script.tcl', 'application/x-tcl'
+
+      def self.analyze_text(text)
+        return 1 if text.shebang? 'tclsh'
+        return 1 if text.shebang? 'wish'
+        return 1 if text.shebang? 'jimsh'
+      end
+
+      KEYWORDS = %w(
+        after apply array break catch continue elseif else error
+        eval expr for foreach global if namespace proc rename return
+        set switch then trace unset update uplevel upvar variable
+        vwait while
+      )
+
+      BUILTINS = %w(
+        append bgerror binary cd chan clock close concat dde dict
+        encoding eof exec exit fblocked fconfigure fcopy file
+        fileevent flush format gets glob history http incr info interp
+        join lappend lassign lindex linsert list llength load loadTk
+        lrange lrepeat lreplace lreverse lsearch lset lsort mathfunc
+        mathop memory msgcat open package pid pkg::create pkg_mkIndex
+        platform platform::shell puts pwd re_syntax read refchan
+        regexp registry regsub scan seek socket source split string
+        subst tell time tm unknown unload
+      )
+
+      OPEN =  %w| \( \[ \{ " |
+      CLOSE = %w| \) \] \} |
+      ALL = OPEN + CLOSE
+      END_LINE = CLOSE + %w(; \n)
+      END_WORD = END_LINE + %w(\s)
+
+      CHARS =     lambda { |list| Regexp.new %/[#{list.join}]/  }
+      NOT_CHARS = lambda { |list| Regexp.new %/[^#{list.join}]/ }
+
+      state :word do
+        rule /\{\*\}/, Keyword
+
+        mixin :brace_abort
+        mixin :interp
+        rule /\{/, Punctuation, :brace
+        rule /\(/, Punctuation,   :paren
+        rule /"/,  Str::Double, :string
+        rule /#{NOT_CHARS[END_WORD]}+?(?=#{CHARS[OPEN+['\\\\']]})/, Text
+      end
+
+      def self.gen_command_state(name='')
+        state(:"command#{name}") do
+          mixin :word
+
+          rule /##{NOT_CHARS[END_LINE]}+/, Comment::Single
+
+          rule /(?=#{CHARS[END_WORD]})/ do
+            push :"params#{name}"
+          end
+
+          rule /#{NOT_CHARS[END_WORD]}+/ do |m|
+            if KEYWORDS.include? m[0]
+              token Keyword
+            elsif BUILTINS.include? m[0]
+              token Name::Builtin
+            else
+              token Text
+            end
+          end
+
+          mixin :whitespace
+        end
+      end
+
+      def self.gen_delimiter_states(name, close, opts={})
+        gen_command_state("_in_#{name}")
+
+        state :"params_in_#{name}" do
+          rule close do
+            token Punctuation
+            pop! 2
+          end
+
+          # mismatched delimiters.  Braced strings with mismatched
+          # closing delimiters should be okay, since this is standard
+          # practice, like {]]]]}
+          if opts[:strict]
+            rule CHARS[CLOSE - [close]], Error
+          else
+            rule CHARS[CLOSE - [close]], Text
+          end
+
+          mixin :params
+        end
+
+        state name do
+          rule close, Punctuation, :pop!
+          mixin :"command_in_#{name}"
+        end
+      end
+
+
+      # tcl is freaking impossible.  If we're in braces and we encounter
+      # a close brace, we have to drop everything and close the brace.
+      # This is so silly things like {abc"def} and {abc]def} don't b0rk
+      # everything after them.
+
+      # TODO: TCL seems to have this aborting behavior quite a lot.
+      # such things as [ abc" ] are a runtime error, but will still
+      # parse.  Currently something like this will muck up the lex.
+      state :brace_abort do
+        rule /}/ do
+          if in_state? :brace
+            pop! until state? :brace
+            pop!
+            token Punctuation
+          else
+            token Error
+          end
+        end
+      end
+
+      state :params do
+        rule /;/, Punctuation, :pop!
+        rule /\n/, Text, :pop!
+        rule /else|elseif|then/, Keyword
+        mixin :word
+        mixin :whitespace
+        rule /#{NOT_CHARS[END_WORD]}+/, Text
+      end
+
+      gen_delimiter_states :brace,   /\}/, :strict => false
+      gen_delimiter_states :paren,   /\)/, :strict => true
+      gen_delimiter_states :bracket, /\]/, :strict => true
+      gen_command_state
+
+      state :root do
+        mixin :command
+      end
+
+      state :whitespace do
+        # not a multiline regex because we want to capture \n sometimes
+        rule /\s+/, Text
+      end
+
+      state :interp do
+        rule /\[/, Punctuation, :bracket
+        rule /\$[a-z0-9.:-]+/, Name::Variable
+        rule /\$\{.*?\}/m, Name::Variable
+        rule /\$/, Text
+
+        # escape sequences
+        rule /\\[0-7]{3}/, Str::Escape
+        rule /\\x[0-9a-f]{2}/i, Str::Escape
+        rule /\\u[0-9a-f]{4}/i, Str::Escape
+        rule /\\./m, Str::Escape
+      end
+
+      state :string do
+        rule /"/, Str::Double, :pop!
+        mixin :interp
+        rule /[^\\\[\$"{}]+/m, Str::Double
+
+        # strings have to keep count of their internal braces, to support
+        # for example { "{ }" }.
+        rule /{/ do
+          @brace_count ||= 0
+          @brace_count += 1
+
+          token Str::Double
+        end
+
+        rule /}/ do
+          if in_state? :brace and @brace_count.to_i == 0
+            pop! until state? :brace
+            pop!
+            token Punctuation
+          else
+            @brace_count -= 1
+            token Str::Double
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/tex.rb b/app/server/vendor/rouge/lib/rouge/lexers/tex.rb
new file mode 100755
index 0000000..3af746c
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/tex.rb
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class TeX < RegexLexer
+      desc "The TeX typesetting system"
+      tag 'tex'
+      aliases 'TeX', 'LaTeX', 'latex'
+
+      filenames '*.tex', '*.aux', '*.toc'
+      mimetypes 'text/x-tex', 'text/x-latex'
+
+      def self.analyze_text(text)
+        return 1 if text =~ /\A\s*\\documentclass/
+        return 1 if text =~ /\A\s*\\input/
+        return 1 if text =~ /\A\s*\\documentstyle/
+        return 1 if text =~ /\A\s*\\relax/
+      end
+
+      command = /\\([a-z]+|\s+|.)/i
+
+      state :general do
+        rule /%.*$/, Comment
+        rule /[{}&_^]/, Punctuation
+      end
+
+      state :root do
+        rule /\\\[/, Punctuation, :displaymath
+        rule /\\\(/, Punctuation, :inlinemath
+        rule /\$\$/, Punctuation, :displaymath
+        rule /\$/, Punctuation, :inlinemath
+        rule /\\(begin|end)\{.*?\}/, Name::Tag
+
+        rule /(\\verb)\b(\S)(.*?)(\2)/ do |m|
+          groups Name::Builtin, Keyword::Pseudo, Str::Other, Keyword::Pseudo
+        end
+
+        rule command, Keyword, :command
+        mixin :general
+        rule /[^\\$%&_^{}]+/, Text
+      end
+
+      state :math do
+        rule command, Name::Variable
+        mixin :general
+        rule /[0-9]+/, Num
+        rule /[-=!+*\/()\[\]]/, Operator
+        rule /[^=!+*\/()\[\]\\$%&_^{}0-9-]+/, Name::Builtin
+      end
+
+      state :inlinemath do
+        rule /\\\)/, Punctuation, :pop!
+        rule /\$/, Punctuation, :pop!
+        mixin :math
+      end
+
+      state :displaymath do
+        rule /\\\]/, Punctuation, :pop!
+        rule /\$\$/, Punctuation, :pop!
+        rule /\$/, Name::Builtin
+        mixin :math
+      end
+
+      state :command do
+        rule /\[.*?\]/, Name::Attribute
+        rule /\*/, Keyword
+        rule(//) { pop! }
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/toml.rb b/app/server/vendor/rouge/lib/rouge/lexers/toml.rb
new file mode 100755
index 0000000..dbceb18
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/toml.rb
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class TOML < RegexLexer
+      desc 'the TOML configuration format (https://github.com/mojombo/toml)'
+      tag 'toml'
+
+      filenames '*.toml'
+      mimetypes 'text/x-toml'
+
+      def self.analyze_text(text)
+        return 0.1 if text =~ /\A\[[\w.]+\]\s*\w+\s*=\s*("\w+")+/
+      end
+
+      identifier = /[\w.\S]+/
+
+      state :basic do
+        rule /\s+/, Text
+        rule /#.*?$/, Comment
+        rule /(true|false)/, Keyword::Constant
+        rule /(?<!=)\s*\[[\w\d\S]+\]/, Name::Namespace
+
+        rule /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/, Literal::Date
+
+        rule /(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?j?/, Num::Float
+        rule /\d+[eE][+-]?[0-9]+j?/, Num::Float
+        rule /\-?\d+/, Num::Integer
+      end
+
+      state :root do
+        mixin :basic
+
+        rule /(#{identifier})(\s*)(=)/ do
+          groups Name::Property, Text, Punctuation
+          push :value
+        end
+
+      end
+
+      state :value do
+        rule /\n/, Text, :pop!
+        mixin :content
+      end
+
+      state :content do
+        mixin :basic
+        rule /"/, Str, :dq
+        mixin :esc_str
+        rule /\,/, Punctuation
+        rule /\[/, Punctuation, :array
+      end
+
+      state :dq do
+        rule /"/, Str, :pop!
+        mixin :esc_str
+        rule /[^\\"]+/, Str
+      end
+
+      state :esc_str do
+        rule /\\[0t\tn\n "\\ r]/, Str::Escape
+      end
+
+      state :array do
+        mixin :content
+        rule /\]/, Punctuation, :pop!
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/vb.rb b/app/server/vendor/rouge/lib/rouge/lexers/vb.rb
new file mode 100755
index 0000000..7b5d7a7
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/vb.rb
@@ -0,0 +1,164 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class VisualBasic < RegexLexer
+      desc "Visual Basic"
+      tag 'vb'
+      aliases 'visualbasic'
+      filenames '*.vbs'
+      mimetypes 'text/x-visualbasic', 'application/x-visualbasic'
+
+      def self.keywords
+        @keywords ||= Set.new %w(
+          AddHandler Alias ByRef ByVal CBool CByte CChar CDate CDbl CDec
+          CInt CLng CObj CSByte CShort CSng CStr CType CUInt CULng CUShort
+          Call Case Catch Class Const Continue Declare Default Delegate
+          Dim DirectCast Do Each Else ElseIf End EndIf Enum Erase Error
+          Event Exit False Finally For Friend Function Get Global GoSub
+          GoTo Handles If Implements Imports Inherits Interface Let
+          Lib Loop Me Module MustInherit MustOverride MyBase MyClass
+          Namespace Narrowing New Next Not NotInheritable NotOverridable
+          Nothing Of On Operator Option Optional Overloads Overridable
+          Overrides ParamArray Partial Private Property Protected Public
+          RaiseEvent ReDim ReadOnly RemoveHandler Resume Return Select Set
+          Shadows Shared Single Static Step Stop Structure Sub SyncLock
+          Then Throw To True Try TryCast Using Wend When While Widening
+          With WithEvents WriteOnly
+        )
+      end
+
+      def self.keywords_type
+        @keywords_type ||= Set.new %w(
+          Boolean Byte Char Date Decimal Double Integer Long Object
+          SByte Short Single String Variant UInteger ULong UShort
+        )
+      end
+
+      def self.operator_words
+        @operator_words ||= Set.new %w(
+          AddressOf And AndAlso As GetType In Is IsNot Like Mod Or OrElse
+          TypeOf Xor
+        )
+      end
+
+      def self.builtins
+        @builtins ||= Set.new %w(
+          Console ConsoleColor
+        )
+      end
+
+      id = /[a-z_]\w*/i
+      upper_id = /[A-Z]\w*/
+
+      state :whitespace do
+        rule /\s+/, Text
+        rule /\n/, Text, :bol
+        rule /rem\b.*?$/i, Comment::Single
+        rule %r(%\{.*?%\})m, Comment::Multiline
+        rule /'.*$/, Comment::Single
+      end
+
+      state :bol do
+        rule /\s+/, Text
+        rule /<.*?>/, Name::Attribute
+        rule(//) { :pop! }
+      end
+
+      state :root do
+        mixin :whitespace
+        rule %r(
+            [#]If\b .*? \bThen
+          | [#]ElseIf\b .*? \bThen
+          | [#]End \s+ If
+          | [#]Const
+          | [#]ExternalSource .*? \n
+          | [#]End \s+ ExternalSource
+          | [#]Region .*? \n
+          | [#]End \s+ Region
+          | [#]ExternalChecksum
+        )x, Comment::Preproc
+        rule /[.]/, Punctuation, :dotted
+        rule /[(){}!#,:]/, Punctuation
+        rule /Option\s+(Strict|Explicit|Compare)\s+(On|Off|Binary|Text)/,
+          Keyword::Declaration
+        rule /End\b/, Keyword, :end
+        rule /(Dim|Const)\b/, Keyword, :dim
+        rule /(Function|Sub|Property)\b/, Keyword, :funcname
+        rule /(Class|Structure|Enum)\b/, Keyword, :classname
+        rule /(Module|Namespace|Imports)\b/, Keyword, :namespace
+
+        rule upper_id do |m|
+          match = m[0]
+          if self.class.keywords.include? match
+            token Keyword
+          elsif self.class.keywords_type.include? match
+            token Keyword::Type
+          elsif self.class.operator_words.include? match
+            token Operator::Word
+          elsif self.class.builtins.include? match
+            token Name::Builtin
+          else
+            token Name
+          end
+        end
+
+        rule(
+          %r(&=|[*]=|/=|\\=|\^=|\+=|-=|<<=|>>=|<<|>>|:=|<=|>=|<>|[-&*/\\^+=<>.]),
+          Operator
+        )
+
+        rule /"/, Str, :string
+        rule /#{id}[%&@!#\$]?/, Name
+        rule /#.*?#/, Literal::Date
+
+        rule /(\d+\.\d*|\d*\.\d+)(f[+-]?\d+)?/i, Num::Float
+        rule /\d+([SILDFR]|US|UI|UL)?/, Num::Integer
+        rule /&H[0-9a-f]+([SILDFR]|US|UI|UL)?/, Num::Integer
+        rule /&O[0-7]+([SILDFR]|US|UI|UL)?/, Num::Integer
+
+        rule /_\n/, Keyword
+      end
+
+      state :dotted do
+        mixin :whitespace
+        rule id, Name, :pop!
+      end
+
+      state :string do
+        rule /""/, Str::Escape
+        rule /"C?/, Str, :pop!
+        rule /[^"]+/, Str
+      end
+
+      state :dim do
+        mixin :whitespace
+        rule id, Name::Variable, :pop!
+        rule(//) { pop! }
+      end
+
+      state :funcname do
+        mixin :whitespace
+        rule id, Name::Function, :pop!
+      end
+
+      state :classname do
+        mixin :whitespace
+        rule id, Name::Class, :pop!
+      end
+
+      state :namespace do
+        mixin :whitespace
+        rule /#{id}([.]#{id})*/, Name::Namespace, :pop!
+      end
+
+      state :end do
+        mixin :whitespace
+        rule /(Function|Sub|Property|Class|Structure|Enum|Module|Namespace)\b/,
+          Keyword, :pop!
+        rule(//) { pop! }
+      end
+    end
+  end
+end
+
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/viml.rb b/app/server/vendor/rouge/lib/rouge/lexers/viml.rb
new file mode 100755
index 0000000..21ffdcf
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/viml.rb
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class VimL < RegexLexer
+      desc "VimL, the scripting language for the Vim editor (vim.org)"
+      tag 'viml'
+      aliases 'vim', 'vimscript', 'ex'
+      filenames '*.vim', '*.vba', '.vimrc', '.exrc', '.gvimrc',
+                '_vimrc', '_exrc', '_gvimrc' # _ names for windows
+
+      mimetypes 'text/x-vim'
+
+      def self.keywords
+        load Pathname.new(__FILE__).dirname.join('viml/keywords.rb')
+        self.keywords
+      end
+
+      state :root do
+        rule /^(\s*)(".*?)$/ do
+          groups Text, Comment
+        end
+
+        rule /^\s*\\/, Str::Escape
+
+        rule /[ \t]+/, Text
+
+        # TODO: regexes can have other delimiters
+        rule %r(/(\\\\|\\/|[^\n/])*/), Str::Regex
+        rule %r("(\\\\|\\"|[^\n"])*"), Str::Double
+        rule %r('(\\\\|\\'|[^\n'])*'), Str::Single
+
+        # if it's not a string, it's a comment.
+        rule /(?<=\s)"[^-:.%#=*].*?$/, Comment
+
+        rule /-?\d+/, Num
+        rule /#[0-9a-f]{6}/i, Num::Hex
+        rule /^:/, Punctuation
+        rule /[():<>+=!\[\]{}\|,~.-]/, Punctuation
+        rule /\b(let|if|else|endif|elseif|fun|function|endfunction)\b/,
+          Keyword
+
+        rule /\b(NONE|bold|italic|underline|dark|light)\b/, Name::Builtin
+
+        rule /[absg]:\w+\b/, Name::Variable
+        rule /\b\w+\b/ do |m|
+          name = m[0]
+          keywords = self.class.keywords
+
+          if mapping_contains?(keywords[:command], name)
+            token Keyword
+          elsif mapping_contains?(keywords[:option], name)
+            token Name::Builtin
+          elsif mapping_contains?(keywords[:auto], name)
+            token Name::Builtin
+          else
+            token Text
+          end
+        end
+
+        # no errors in VimL!
+        rule /./m, Text
+      end
+
+      def mapping_contains?(mapping, word)
+        shortest, longest = find_likely_mapping(mapping, word)
+
+        shortest and word.start_with?(shortest) and
+        longest and longest.start_with?(word)
+      end
+
+      # binary search through the mappings to find the one that's likely
+      # to actually work.
+      def find_likely_mapping(mapping, word)
+        min = 0
+        max = mapping.size
+
+        until max == min
+          mid = (max + min) / 2
+
+          cmp, _ = mapping[mid]
+
+          case word <=> cmp
+          when 1
+            # too low
+            min = mid + 1
+          when -1
+            # too high
+            max = mid
+          when 0
+            # just right, abort!
+            return mapping[mid]
+          end
+        end
+
+        mapping[max - 1]
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/viml/keywords.rb b/app/server/vendor/rouge/lib/rouge/lexers/viml/keywords.rb
new file mode 100755
index 0000000..6dbba0e
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/viml/keywords.rb
@@ -0,0 +1,12 @@
+# encoding: utf-8
+# DO NOT EDIT: automatically generated by `rake builtins:vim`.
+# see tasks/vim.rake for more info.
+module Rouge
+  module Lexers
+    class VimL
+      def self.keywords
+        @keywords ||= {:command=>[["a", "a"], ["ab", "ab"], ["abc", "abclear"], ["abo", "aboveleft"], ["al", "all"], ["ar", "ar"], ["ar", "args"], ["arga", "argadd"], ["argd", "argdelete"], ["argdo", "argdo"], ["arge", "argedit"], ["argg", "argglobal"], ["argl", "arglocal"], ["argu", "argument"], ["as", "ascii"], ["au", "au"], ["b", "buffer"], ["bN", "bNext"], ["ba", "ball"], ["bad", "badd"], ["bd", "bdelete"], ["bel", "belowright"], ["bf", "bfirst"], ["bl", "blast"], ["bm", "bmodified"], ["bn", "bnext"], ["bo", "botright"], ["bp", "bprevious"], ["br", "br"], ["br", "brewind"], ["brea", "break"], ["breaka", "breakadd"], ["breakd", "breakdel"], ["breakl", "breaklist"], ["bro", "browse"], ["bu", "bu"], ["buf", "buf"], ["bufdo", "bufdo"], ["buffers", "buffers"], ["bun", "bunload"], ["bw", "bwipeout"], ["c", "c"], ["c", "change"], ["cN", "cN"], ["cN", "cNext"], ["cNf", "cNf"], ["cNf", "cNfile"], ["cabc", "cabclear"], ["cad", "cad"], ["cad", "caddexpr"], ["caddb", "caddbuffer"], ["caddf", "caddfile"], ["cal", "call"], ["cat", "catch"], ["cb", "cbuffer"], ["cc", "cc"], ["ccl", "cclose"], ["cd", "cd"], ["ce", "center"], ["cex", "cexpr"], ["cf", "cfile"], ["cfir", "cfirst"], ["cg", "cgetfile"], ["cgetb", "cgetbuffer"], ["cgete", "cgetexpr"], ["changes", "changes"], ["chd", "chdir"], ["che", "checkpath"], ["checkt", "checktime"], ["cl", "cl"], ["cl", "clist"], ["cla", "clast"], ["clo", "close"], ["cmapc", "cmapclear"], ["cn", "cn"], ["cn", "cnext"], ["cnew", "cnewer"], ["cnf", "cnf"], ["cnf", "cnfile"], ["co", "copy"], ["col", "colder"], ["colo", "colorscheme"], ["com", "com"], ["comc", "comclear"], ["comp", "compiler"], ["con", "con"], ["con", "continue"], ["conf", "confirm"], ["cope", "copen"], ["cp", "cprevious"], ["cpf", "cpfile"], ["cq", "cquit"], ["cr", "crewind"], ["cs", "cs"], ["cscope", "cscope"], ["cstag", "cstag"], ["cuna", "cunabbrev"], ["cw", "cwindow"], ["d", "d"], ["d", "delete"], ["de", "de"], ["debug", "debug"], ["debugg", "debuggreedy"], ["del", "del"], ["delc", "delcommand"], ["delel", "delel"], ["delep", "delep"], ["deletel", "deletel"], ["deletep", "deletep"], ["deletl", "deletl"], ["deletp", "deletp"], ["delf", "delf"], ["delf", "delfunction"], ["dell", "dell"], ["delm", "delmarks"], ["delp", "delp"], ["dep", "dep"], ["di", "di"], ["di", "display"], ["diffg", "diffget"], ["diffo", "diffoff"], ["diffp", "diffpatch"], ["diffpu", "diffput"], ["diffs", "diffsplit"], ["difft", "diffthis"], ["diffu", "diffupdate"], ["dig", "dig"], ["dig", "digraphs"], ["dir", "dir"], ["dj", "djump"], ["dl", "dl"], ["dli", "dlist"], ["do", "do"], ["doau", "doau"], ["dp", "dp"], ["dr", "drop"], ["ds", "dsearch"], ["dsp", "dsplit"], ["e", "e"], ["e", "edit"], ["ea", "ea"], ["earlier", "earlier"], ["ec", "ec"], ["echoe", "echoerr"], ["echom", "echomsg"], ["echon", "echon"], ["el", "else"], ["elsei", "elseif"], ["em", "emenu"], ["en", "en"], ["en", "endif"], ["endf", "endf"], ["endf", "endfunction"], ["endfo", "endfor"], ["endfun", "endfun"], ["endt", "endtry"], ["endw", "endwhile"], ["ene", "enew"], ["ex", "ex"], ["exi", "exit"], ["exu", "exusage"], ["f", "f"], ["f", "file"], ["files", "files"], ["filet", "filet"], ["filetype", "filetype"], ["fin", "fin"], ["fin", "find"], ["fina", "finally"], ["fini", "finish"], ["fir", "first"], ["fix", "fixdel"], ["fo", "fold"], ["foldc", "foldclose"], ["foldd", "folddoopen"], ["folddoc", "folddoclosed"], ["foldo", "foldopen"], ["for", "for"], ["fu", "fu"], ["fu", "function"], ["fun", "fun"], ["g", "g"], ["go", "goto"], ["gr", "grep"], ["grepa", "grepadd"], ["gui", "gui"], ["gvim", "gvim"], ["h", "h"], ["h", "help"], ["ha", "hardcopy"], ["helpf", "helpfind"], ["helpg", "helpgrep"], ["helpt", "helptags"], ["hi", "hi"], ["hid", "hide"], ["his", "history"], ["i", "i"], ["ia", "ia"], ["iabc", "iabclear"], ["if", "if"], ["ij", "ijump"], ["il", "ilist"], ["imapc", "imapclear"], ["in", "in"], ["intro", "intro"], ["is", "isearch"], ["isp", "isplit"], ["iuna", "iunabbrev"], ["j", "join"], ["ju", "jumps"], ["k", "k"], ["kee", "keepmarks"], ["keepa", "keepa"], ["keepalt", "keepalt"], ["keepj", "keepjumps"], ["keepp", "keeppatterns"], ["l", "l"], ["l", "list"], ["lN", "lN"], ["lN", "lNext"], ["lNf", "lNf"], ["lNf", "lNfile"], ["la", "la"], ["la", "last"], ["lad", "lad"], ["lad", "laddexpr"], ["laddb", "laddbuffer"], ["laddf", "laddfile"], ["lan", "lan"], ["lan", "language"], ["lat", "lat"], ["later", "later"], ["lb", "lbuffer"], ["lc", "lcd"], ["lch", "lchdir"], ["lcl", "lclose"], ["lcs", "lcs"], ["lcscope", "lcscope"], ["le", "left"], ["lefta", "leftabove"], ["lex", "lexpr"], ["lf", "lfile"], ["lfir", "lfirst"], ["lg", "lgetfile"], ["lgetb", "lgetbuffer"], ["lgete", "lgetexpr"], ["lgr", "lgrep"], ["lgrepa", "lgrepadd"], ["lh", "lhelpgrep"], ["ll", "ll"], ["lla", "llast"], ["lli", "llist"], ["lmak", "lmake"], ["lmapc", "lmapclear"], ["lne", "lne"], ["lne", "lnext"], ["lnew", "lnewer"], ["lnf", "lnf"], ["lnf", "lnfile"], ["lo", "lo"], ["lo", "loadview"], ["loadk", "loadk"], ["loadkeymap", "loadkeymap"], ["loc", "lockmarks"], ["lockv", "lockvar"], ["lol", "lolder"], ["lop", "lopen"], ["lp", "lprevious"], ["lpf", "lpfile"], ["lr", "lrewind"], ["ls", "ls"], ["lt", "ltag"], ["lua", "lua"], ["luado", "luado"], ["luafile", "luafile"], ["lv", "lvimgrep"], ["lvimgrepa", "lvimgrepadd"], ["lw", "lwindow"], ["m", "move"], ["ma", "ma"], ["ma", "mark"], ["mak", "make"], ["marks", "marks"], ["mat", "match"], ["menut", "menut"], ["menut", "menutranslate"], ["mes", "mes"], ["messages", "messages"], ["mk", "mk"], ["mk", "mkexrc"], ["mks", "mksession"], ["mksp", "mkspell"], ["mkv", "mkv"], ["mkv", "mkvimrc"], ["mkvie", "mkview"], ["mo", "mo"], ["mod", "mode"], ["mz", "mz"], ["mz", "mzscheme"], ["mzf", "mzfile"], ["n", "n"], ["n", "next"], ["nb", "nbkey"], ["nbc", "nbclose"], ["nbs", "nbstart"], ["ne", "ne"], ["new", "new"], ["nmapc", "nmapclear"], ["noa", "noa"], ["noautocmd", "noautocmd"], ["noh", "nohlsearch"], ["nu", "number"], ["o", "o"], ["o", "open"], ["ol", "oldfiles"], ["omapc", "omapclear"], ["on", "only"], ["opt", "options"], ["ownsyntax", "ownsyntax"], ["p", "p"], ["p", "print"], ["pc", "pclose"], ["pe", "pe"], ["pe", "perl"], ["ped", "pedit"], ["perld", "perldo"], ["po", "pop"], ["popu", "popu"], ["popu", "popup"], ["pp", "ppop"], ["pr", "pr"], ["pre", "preserve"], ["prev", "previous"], ["pro", "pro"], ["prof", "profile"], ["profd", "profdel"], ["promptf", "promptfind"], ["promptr", "promptrepl"], ["ps", "psearch"], ["ptN", "ptN"], ["ptN", "ptNext"], ["pta", "ptag"], ["ptf", "ptfirst"], ["ptj", "ptjump"], ["ptl", "ptlast"], ["ptn", "ptn"], ["ptn", "ptnext"], ["ptp", "ptprevious"], ["ptr", "ptrewind"], ["pts", "ptselect"], ["pu", "put"], ["pw", "pwd"], ["py", "py"], ["py", "python"], ["py3", "py3"], ["py3", "py3"], ["py3do", "py3do"], ["pydo", "pydo"], ["pyf", "pyfile"], ["python3", "python3"], ["q", "q"], ["q", "quit"], ["qa", "qall"], ["quita", "quitall"], ["r", "r"], ["r", "read"], ["re", "re"], ["rec", "recover"], ["red", "red"], ["red", "redo"], ["redi", "redir"], ["redr", "redraw"], ["redraws", "redrawstatus"], ["reg", "registers"], ["res", "resize"], ["ret", "retab"], ["retu", "return"], ["rew", "rewind"], ["ri", "right"], ["rightb", "rightbelow"], ["ru", "ru"], ["ru", "runtime"], ["rub", "ruby"], ["rubyd", "rubydo"], ["rubyf", "rubyfile"], ["rundo", "rundo"], ["rv", "rviminfo"], ["sN", "sNext"], ["sa", "sargument"], ["sal", "sall"], ["san", "sandbox"], ["sav", "saveas"], ["sb", "sbuffer"], ["sbN", "sbNext"], ["sba", "sball"], ["sbf", "sbfirst"], ["sbl", "sblast"], ["sbm", "sbmodified"], ["sbn", "sbnext"], ["sbp", "sbprevious"], ["sbr", "sbrewind"], ["scrip", "scrip"], ["scrip", "scriptnames"], ["scripte", "scriptencoding"], ["scs", "scs"], ["scscope", "scscope"], ["se", "set"], ["setf", "setfiletype"], ["setg", "setglobal"], ["setl", "setlocal"], ["sf", "sfind"], ["sfir", "sfirst"], ["sh", "shell"], ["si", "si"], ["sig", "sig"], ["sign", "sign"], ["sil", "silent"], ["sim", "simalt"], ["sl", "sl"], ["sl", "sleep"], ["sla", "slast"], ["sm", "smagic"], ["sm", "smap"], ["sme", "sme"], ["smenu", "smenu"], ["sn", "snext"], ["sni", "sniff"], ["sno", "snomagic"], ["snoreme", "snoreme"], ["snoremenu", "snoremenu"], ["so", "so"], ["so", "source"], ["sor", "sort"], ["sp", "split"], ["spe", "spe"], ["spe", "spellgood"], ["spelld", "spelldump"], ["spelli", "spellinfo"], ["spellr", "spellrepall"], ["spellu", "spellundo"], ["spellw", "spellwrong"], ["spr", "sprevious"], ["sre", "srewind"], ["st", "st"], ["st", "stop"], ["sta", "stag"], ["star", "star"], ["star", "startinsert"], ["start", "start"], ["startg", "startgreplace"], ["startr", "startreplace"], ["stj", "stjump"], ["stopi", "stopinsert"], ["sts", "stselect"], ["sun", "sunhide"], ["sunme", "sunme"], ["sunmenu", "sunmenu"], ["sus", "suspend"], ["sv", "sview"], ["sw", "swapname"], ["sy", "sy"], ["syn", "syn"], ["sync", "sync"], ["syncbind", "syncbind"], ["syntime", "syntime"], ["t", "t"], ["tN", "tN"], ["tN", "tNext"], ["ta", "ta"], ["ta", "tag"], ["tab", "tab"], ["tabN", "tabN"], ["tabN", "tabNext"], ["tabc", "tabclose"], ["tabd", "tabdo"], ["tabe", "tabedit"], ["tabf", "tabfind"], ["tabfir", "tabfirst"], ["tabl", "tablast"], ["tabm", "tabmove"], ["tabn", "tabnext"], ["tabnew", "tabnew"], ["tabo", "tabonly"], ["tabp", "tabprevious"], ["tabr", "tabrewind"], ["tabs", "tabs"], ["tags", "tags"], ["tc", "tcl"], ["tcld", "tcldo"], ["tclf", "tclfile"], ["te", "tearoff"], ["tf", "tfirst"], ["th", "throw"], ["tj", "tjump"], ["tl", "tlast"], ["tm", "tm"], ["tm", "tmenu"], ["tn", "tn"], ["tn", "tnext"], ["to", "topleft"], ["tp", "tprevious"], ["tr", "tr"], ["tr", "trewind"], ["try", "try"], ["ts", "tselect"], ["tu", "tu"], ["tu", "tunmenu"], ["u", "u"], ["u", "undo"], ["un", "un"], ["una", "unabbreviate"], ["undoj", "undojoin"], ["undol", "undolist"], ["unh", "unhide"], ["unl", "unl"], ["unlo", "unlockvar"], ["uns", "unsilent"], ["up", "update"], ["v", "v"], ["ve", "ve"], ["ve", "version"], ["verb", "verbose"], ["vert", "vertical"], ["vi", "vi"], ["vi", "visual"], ["vie", "view"], ["vim", "vimgrep"], ["vimgrepa", "vimgrepadd"], ["viu", "viusage"], ["vmapc", "vmapclear"], ["vne", "vnew"], ["vs", "vsplit"], ["w", "w"], ["w", "write"], ["wN", "wNext"], ["wa", "wall"], ["wh", "while"], ["win", "win"], ["win", "winsize"], ["winc", "wincmd"], ["windo", "windo"], ["winp", "winpos"], ["wn", "wnext"], ["wp", "wprevious"], ["wq", "wq"], ["wqa", "wqall"], ["ws", "wsverb"], ["wundo", "wundo"], ["wv", "wviminfo"], ["x", "x"], ["x", "xit"], ["xa", "xall"], ["xmapc", "xmapclear"], ["xme", "xme"], ["xmenu", "xmenu"], ["xnoreme", "xnoreme"], ["xnoremenu", "xnoremenu"], ["xunme", "xunme"], ["xunmenu", "xunmenu"], ["xwininfo", "xwininfo"], ["y", "yank"]], :option=>[], :auto=>[["BufAdd", "BufAdd"], ["BufCreate", "BufCreate"], ["BufDelete", "BufDelete"], ["BufEnter", "BufEnter"], ["BufFilePost", "BufFilePost"], ["BufFilePre", "BufFilePre"], ["BufHidden", "BufHidden"], ["BufLeave", "BufLeave"], ["BufNew", "BufNew"], ["BufNewFile", "BufNewFile"], ["BufRead", "BufRead"], ["BufReadCmd", "BufReadCmd"], ["BufReadPost", "BufReadPost"], ["BufReadPre", "BufReadPre"], ["BufUnload", "BufUnload"], ["BufWinEnter", "BufWinEnter"], ["BufWinLeave", "BufWinLeave"], ["BufWipeout", "BufWipeout"], ["BufWrite", "BufWrite"], ["BufWriteCmd", "BufWriteCmd"], ["BufWritePost", "BufWritePost"], ["BufWritePre", "BufWritePre"], ["Cmd", "Cmd"], ["CmdwinEnter", "CmdwinEnter"], ["CmdwinLeave", "CmdwinLeave"], ["ColorScheme", "ColorScheme"], ["CompleteDone", "CompleteDone"], ["CursorHold", "CursorHold"], ["CursorHoldI", "CursorHoldI"], ["CursorMoved", "CursorMoved"], ["CursorMovedI", "CursorMovedI"], ["EncodingChanged", "EncodingChanged"], ["FileAppendCmd", "FileAppendCmd"], ["FileAppendPost", "FileAppendPost"], ["FileAppendPre", "FileAppendPre"], ["FileChangedRO", "FileChangedRO"], ["FileChangedShell", "FileChangedShell"], ["FileChangedShellPost", "FileChangedShellPost"], ["FileEncoding", "FileEncoding"], ["FileReadCmd", "FileReadCmd"], ["FileReadPost", "FileReadPost"], ["FileReadPre", "FileReadPre"], ["FileType", "FileType"], ["FileWriteCmd", "FileWriteCmd"], ["FileWritePost", "FileWritePost"], ["FileWritePre", "FileWritePre"], ["FilterReadPost", "FilterReadPost"], ["FilterReadPre", "FilterReadPre"], ["FilterWritePost", "FilterWritePost"], ["FilterWritePre", "FilterWritePre"], ["FocusGained", "FocusGained"], ["FocusLost", "FocusLost"], ["FuncUndefined", "FuncUndefined"], ["GUIEnter", "GUIEnter"], ["GUIFailed", "GUIFailed"], ["InsertChange", "InsertChange"], ["InsertCharPre", "InsertCharPre"], ["InsertEnter", "InsertEnter"], ["InsertLeave", "InsertLeave"], ["MenuPopup", "MenuPopup"], ["QuickFixCmdPost", "QuickFixCmdPost"], ["QuickFixCmdPre", "QuickFixCmdPre"], ["QuitPre", "QuitPre"], ["RemoteReply", "RemoteReply"], ["SessionLoadPost", "SessionLoadPost"], ["ShellCmdPost", "ShellCmdPost"], ["ShellFilterPost", "ShellFilterPost"], ["SourceCmd", "SourceCmd"], ["SourcePre", "SourcePre"], ["SpellFileMissing", "SpellFileMissing"], ["StdinReadPost", "StdinReadPost"], ["StdinReadPre", "StdinReadPre"], ["SwapExists", "SwapExists"], ["Syntax", "Syntax"], ["TabEnter", "TabEnter"], ["TabLeave", "TabLeave"], ["TermChanged", "TermChanged"], ["TermResponse", "TermResponse"], ["TextChanged", "TextChanged"], ["TextChangedI", "TextChangedI"], ["User", "User"], ["UserGettingBored", "UserGettingBored"], ["VimEnter", "VimEnter"], ["VimLeave", "VimLeave"], ["VimLeavePre", "VimLeavePre"], ["VimResized", "VimResized"], ["WinEnter", "WinEnter"], ["WinLeave", "WinLeave"], ["event", "event"]]}
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/xml.rb b/app/server/vendor/rouge/lib/rouge/lexers/xml.rb
new file mode 100755
index 0000000..577cc75
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/xml.rb
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class XML < RegexLexer
+      desc %q(<desc for="this-lexer">XML</desc>)
+      tag 'xml'
+      filenames *%w(*.xml *.xsl *.rss *.xslt *.xsd *.wsdl)
+      mimetypes *%w(
+        text/xml
+        application/xml
+        image/svg+xml
+        application/rss+xml
+        application/atom+xml
+      )
+
+      def self.analyze_text(text)
+        return 0.9 if text.doctype?
+        return 0.8 if text =~ /\A<\?xml\b/
+        start = text[0..1000]
+        return 0.6 if start =~ %r(<xml\b)
+        return 0.3 if start =~ %r(<.+?>.*?</.+?>)m
+      end
+
+      state :root do
+        rule /[^<&]+/, Text
+        rule /&\S*?;/, Name::Entity
+        rule /<!\[CDATA\[.*?\]\]\>/, Comment::Preproc
+        rule /<!--/, Comment, :comment
+        rule /<\?.*?\?>/, Comment::Preproc
+        rule /<![^>]*>/, Comment::Preproc
+
+        # open tags
+        rule %r(<\s*[\w:.-]+)m, Name::Tag, :tag
+
+        # self-closing tags
+        rule %r(<\s*/\s*[\w:.-]+\s*>)m, Name::Tag
+      end
+
+      state :comment do
+        rule /[^-]+/m, Comment
+        rule /-->/, Comment, :pop!
+        rule /-/, Comment
+      end
+
+      state :tag do
+        rule /\s+/m, Text
+        rule /[\w.:-]+\s*=/m, Name::Attribute, :attr
+        rule %r(/?\s*>), Name::Tag, :pop!
+      end
+
+      state :attr do
+        rule /\s+/m, Text
+        rule /".*?"|'.*?'|[^\s>]+/, Str, :pop!
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/lexers/yaml.rb b/app/server/vendor/rouge/lib/rouge/lexers/yaml.rb
new file mode 100755
index 0000000..dd655fe
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/lexers/yaml.rb
@@ -0,0 +1,363 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Lexers
+    class YAML < RegexLexer
+      desc "Yaml Ain't Markup Language (yaml.org)"
+      mimetypes 'text/x-yaml'
+      tag 'yaml'
+      aliases 'yml'
+
+      def self.analyze_text(text)
+        # look for the %YAML directive
+        return 1 if text =~ /\A\s*%YAML/m
+      end
+
+      filenames '*.yaml', '*.yml'
+      # NB: Tabs are forbidden in YAML, which is why you see things
+      # like /[ ]+/.
+
+      # reset the indentation levels
+      def reset_indent
+        puts "    yaml: reset_indent" if @debug
+        @indent_stack = [0]
+        @next_indent = 0
+        @block_scalar_indent = nil
+      end
+
+      def indent
+        raise 'empty indent stack!' if @indent_stack.empty?
+        @indent_stack.last
+      end
+
+      def dedent?(level)
+        level < self.indent
+      end
+
+      def indent?(level)
+        level > self.indent
+      end
+
+      # Save a possible indentation level
+      def save_indent(match)
+        @next_indent = match.size
+        puts "    yaml: indent: #{self.indent}/#@next_indent" if @debug
+        puts "    yaml: popping indent stack - before: #@indent_stack" if @debug
+        if dedent?(@next_indent)
+          @indent_stack.pop while dedent?(@next_indent)
+          puts "    yaml: popping indent stack - after: #@indent_stack" if @debug
+          puts "    yaml: indent: #{self.indent}/#@next_indent" if @debug
+
+          # dedenting to a state not previously indented to is an error
+          [match[0...self.indent], match[self.indent..-1]]
+        else
+          [match, '']
+        end
+      end
+
+      def continue_indent(match)
+        puts "    yaml: continue_indent" if @debug
+        @next_indent += match.size
+      end
+
+      def set_indent(match, opts={})
+        if indent < @next_indent
+          @indent_stack << @next_indent
+        end
+
+        @next_indent += match.size unless opts[:implicit]
+      end
+
+      plain_scalar_start = /[^ \t\n\r\f\v?:,\[\]{}#&*!\|>'"%@`]/
+
+      start { reset_indent }
+
+      state :basic do
+        rule /#.*$/, Comment::Single
+      end
+
+      state :root do
+        mixin :basic
+
+        rule /\n+/, Text
+
+        # trailing or pre-comment whitespace
+        rule /[ ]+(?=#|$)/, Text
+
+        rule /^%YAML\b/ do
+          token Name::Tag
+          reset_indent
+          push :yaml_directive
+        end
+
+        rule /^%TAG\b/ do
+          token Name::Tag
+          reset_indent
+          push :tag_directive
+        end
+
+        # doc-start and doc-end indicators
+        rule /^(?:---|\.\.\.)(?= |$)/ do
+          token Name::Namespace
+          reset_indent
+          push :block_line
+        end
+
+        # indentation spaces
+        rule /[ ]*(?!\s|$)/ do |m|
+          text, err = save_indent(m[0])
+          token Text, text
+          token Error, err
+          push :block_line; push :indentation
+        end
+      end
+
+      state :indentation do
+        rule(/\s*?\n/) { token Text; pop! 2 }
+        # whitespace preceding block collection indicators
+        rule /[ ]+(?=[-:?](?:[ ]|$))/ do |m|
+          token Text
+          continue_indent(m[0])
+        end
+
+        # block collection indicators
+        rule(/[?:-](?=[ ]|$)/) { |m| token Punctuation::Indicator; set_indent m[0] }
+
+        # the beginning of a block line
+        rule(/[ ]*/) { |m| token Text; continue_indent(m[0]); pop! }
+      end
+
+      # indented line in the block context
+      state :block_line do
+        # line end
+        rule /[ ]*(?=#|$)/, Text, :pop!
+        rule /[ ]+/, Text
+        # tags, anchors, and aliases
+        mixin :descriptors
+        # block collections and scalars
+        mixin :block_nodes
+        # flow collections and quoed scalars
+        mixin :flow_nodes
+
+        # a plain scalar
+        rule /(?=#{plain_scalar_start}|[?:-][^ \t\n\r\f\v])/ do
+          token Name::Variable
+          push :plain_scalar_in_block_context
+        end
+      end
+
+      state :descriptors do
+        # a full-form tag
+        rule /!<[0-9A-Za-z;\/?:@&=+$,_.!~*'()\[\]%-]+>/, Keyword::Type
+
+        # a tag in the form '!', '!suffix' or '!handle!suffix'
+        rule %r(
+          (?:![\w-]+)? # handle
+          !(?:[\w;/?:@&=+$,.!~*\'()\[\]%-]*) # suffix
+        )x, Keyword::Type
+
+        # an anchor
+        rule /&[\w-]+/, Name::Label
+
+        # an alias
+        rule /\*[\w-]+/, Name::Variable
+      end
+
+      state :block_nodes do
+        # implicit key
+        rule /:(?=\s|$)/ do |m|
+          token Punctuation::Indicator
+          set_indent m[0], :implicit => true
+        end
+
+        # literal and folded scalars
+        rule /[\|>]/ do
+          token Punctuation::Indicator
+          push :block_scalar_content
+          push :block_scalar_header
+        end
+      end
+
+      state :flow_nodes do
+        rule /\[/, Punctuation::Indicator, :flow_sequence
+        rule /\{/, Punctuation::Indicator, :flow_mapping
+        rule /'/, Str::Single, :single_quoted_scalar
+        rule /"/, Str::Double, :double_quoted_scalar
+      end
+
+      state :flow_collection do
+        rule /\s+/m, Text
+        mixin :basic
+        rule /[?:,]/, Punctuation::Indicator
+        mixin :descriptors
+        mixin :flow_nodes
+
+        rule /(?=#{plain_scalar_start})/ do
+          push :plain_scalar_in_flow_context
+        end
+      end
+
+      state :flow_sequence do
+        rule /\]/, Punctuation::Indicator, :pop!
+        mixin :flow_collection
+      end
+
+      state :flow_mapping do
+        rule /\}/, Punctuation::Indicator, :pop!
+        mixin :flow_collection
+      end
+
+      state :block_scalar_content do
+        rule /\n+/, Text
+
+        # empty lines never dedent, but they might be part of the scalar.
+        rule /^[ ]+$/ do |m|
+          text = m[0]
+          indent_size = text.size
+
+          indent_mark = @block_scalar_indent || indent_size
+
+          token Text, text[0...indent_mark]
+          token Name::Constant, text[indent_mark..-1]
+        end
+
+        # TODO: ^ doesn't actually seem to affect the match at all.
+        # Find a way to work around this limitation.
+        rule /^[ ]*/ do |m|
+          token Text
+
+          indent_size = m[0].size
+
+          dedent_level = @block_scalar_indent || self.indent
+          @block_scalar_indent ||= indent_size
+
+          if indent_size < dedent_level
+            pop! 2
+          end
+        end
+
+        rule /[^\n\r\f\v]+/, Name::Constant
+      end
+
+      state :block_scalar_header do
+        # optional indentation indicator and chomping flag, in either order
+        rule %r(
+          (
+            ([1-9])[+-]? | [+-]?([1-9])?
+          )(?=[ ]|$)
+        )x do |m|
+          @block_scalar_indent = nil
+          goto :ignored_line
+          next if m[0].empty?
+
+          increment = m[1] || m[2]
+          if increment
+            @block_scalar_indent = indent + increment.to_i
+          end
+
+          token Punctuation::Indicator
+        end
+      end
+
+      state :ignored_line do
+        mixin :basic
+        rule /[ ]+/, Text
+        rule /\n/, Text, :pop!
+      end
+
+      state :quoted_scalar_whitespaces do
+        # leading and trailing whitespace is ignored
+        rule /^[ ]+/, Text
+        rule /[ ]+$/, Text
+
+        rule /\n+/m, Text
+
+        rule /[ ]+/, Name::Variable
+      end
+
+      state :single_quoted_scalar do
+        mixin :quoted_scalar_whitespaces
+        rule /\\'/, Str::Escape
+        rule /'/, Str, :pop!
+        rule /[^\s']+/, Str
+      end
+
+      state :double_quoted_scalar do
+        rule /"/, Str, :pop!
+        mixin :quoted_scalar_whitespaces
+        # escapes
+        rule /\\[0abt\tn\nvfre "\\N_LP]/, Str::Escape
+        rule /\\(?:x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
+          Str::Escape
+        rule /[^ \t\n\r\f\v"\\]+/, Str
+      end
+
+      state :plain_scalar_in_block_context_new_line do
+        rule /^[ ]+\n/, Text
+        rule /\n+/m, Text
+        rule /^(?=---|\.\.\.)/ do
+          pop! 3
+        end
+
+        # dedent detection
+        rule /^[ ]*/ do |m|
+          token Text
+          pop!
+
+          indent_size = m[0].size
+
+          # dedent = end of scalar
+          if indent_size <= self.indent
+            pop!
+            save_indent(m[0])
+            push :indentation
+          end
+        end
+      end
+
+      state :plain_scalar_in_block_context do
+        # the : indicator ends a scalar
+        rule /[ ]*(?=:[ \n]|:$)/, Text, :pop!
+        rule /[ ]*:/, Str
+        rule /[ ]+(?=#)/, Text, :pop!
+        rule /[ ]+$/, Text
+        # check for new documents or dedents at the new line
+        rule /\n+/ do
+          token Text
+          push :plain_scalar_in_block_context_new_line
+        end
+
+        rule /[ ]+/, Str
+        # regular non-whitespace characters
+        rule /[^\s:]+/, Str
+      end
+
+      state :plain_scalar_in_flow_context do
+        rule /[ ]*(?=[,:?\[\]{}])/, Text, :pop!
+        rule /[ ]+(?=#)/, Text, :pop!
+        rule /^[ ]+/, Text
+        rule /[ ]+$/, Text
+        rule /\n+/, Text
+        rule /[ ]+/, Name::Variable
+        rule /[^\s,:?\[\]{}]+/, Name::Variable
+      end
+
+      state :yaml_directive do
+        rule /([ ]+)(\d+\.\d+)/ do
+          groups Text, Num
+          goto :ignored_line
+        end
+      end
+
+      state :tag_directive do
+        rule %r(
+          ([ ]+)(!|![\w-]*!) # prefix
+          ([ ]+)(!|!?[\w;/?:@&=+$,.!~*'()\[\]%-]+) # tag handle
+        )x do
+          groups Text, Keyword::Type, Text, Keyword::Type
+          goto :ignored_line
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/plugins/redcarpet.rb b/app/server/vendor/rouge/lib/rouge/plugins/redcarpet.rb
new file mode 100755
index 0000000..f27511b
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/plugins/redcarpet.rb
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*- #
+
+# this file is not require'd from the root.  To use this plugin, run:
+#
+#    require 'rouge/plugins/redcarpet'
+
+module Rouge
+  module Plugins
+    module Redcarpet
+      def block_code(code, language)
+        lexer = Lexer.find_fancy(language, code) || Lexers::PlainText
+
+        # XXX HACK: Redcarpet strips hard tabs out of code blocks,
+        # so we assume you're not using leading spaces that aren't tabs,
+        # and just replace them here.
+        if lexer.tag == 'make'
+          code.gsub! /^    /, "\t"
+        end
+
+        formatter = rouge_formatter(lexer)
+        formatter.format(lexer.lex(code))
+      end
+
+      # override this method for custom formatting behavior
+      def rouge_formatter(lexer)
+        Formatters::HTML.new(:css_class => "highlight #{lexer.tag}")
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/regex_lexer.rb b/app/server/vendor/rouge/lib/rouge/regex_lexer.rb
new file mode 100755
index 0000000..3b9022e
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/regex_lexer.rb
@@ -0,0 +1,439 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  # @abstract
+  # A stateful lexer that uses sets of regular expressions to
+  # tokenize a string.  Most lexers are instances of RegexLexer.
+  class RegexLexer < Lexer
+    # A rule is a tuple of a regular expression to test, and a callback
+    # to perform if the test succeeds.
+    #
+    # @see StateDSL#rule
+    class Rule
+      attr_reader :callback
+      attr_reader :re
+      attr_reader :beginning_of_line
+      def initialize(re, callback)
+        @re = re
+        @callback = callback
+        @beginning_of_line = re.source[0] == ?^
+      end
+
+      def inspect
+        "#<Rule #{@re.inspect}>"
+      end
+    end
+
+    # a State is a named set of rules that can be tested for or
+    # mixed in.
+    #
+    # @see RegexLexer.state
+    class State
+      attr_reader :name, :rules
+      def initialize(name, rules)
+        @name = name
+        @rules = rules
+      end
+
+      def inspect
+        "#<#{self.class.name} #{@name.inspect}>"
+      end
+    end
+
+    class StateDSL
+      attr_reader :rules
+      def initialize(name, &defn)
+        @name = name
+        @defn = defn
+        @rules = []
+      end
+
+      def to_state(lexer_class)
+        load!
+        rules = @rules.map do |rule|
+          rule.is_a?(String) ? lexer_class.get_state(rule) : rule
+        end
+        State.new(@name, rules)
+      end
+
+      def prepended(&defn)
+        parent_defn = @defn
+        StateDSL.new(@name) do
+          instance_eval(&defn)
+          instance_eval(&parent_defn)
+        end
+      end
+
+      def appended(&defn)
+        parent_defn = @defn
+        StateDSL.new(@name) do
+          instance_eval(&parent_defn)
+          instance_eval(&defn)
+        end
+      end
+
+    protected
+      # Define a new rule for this state.
+      #
+      # @overload rule(re, token, next_state=nil)
+      # @overload rule(re, &callback)
+      #
+      # @param [Regexp] re
+      #   a regular expression for this rule to test.
+      # @param [String] tok
+      #   the token type to yield if `re` matches.
+      # @param [#to_s] next_state
+      #   (optional) a state to push onto the stack if `re` matches.
+      #   If `next_state` is `:pop!`, the state stack will be popped
+      #   instead.
+      # @param [Proc] callback
+      #   a block that will be evaluated in the context of the lexer
+      #   if `re` matches.  This block has access to a number of lexer
+      #   methods, including {RegexLexer#push}, {RegexLexer#pop!},
+      #   {RegexLexer#token}, and {RegexLexer#delegate}.  The first
+      #   argument can be used to access the match groups.
+      def rule(re, tok=nil, next_state=nil, &callback)
+        if tok.nil? && callback.nil?
+          raise "please pass `rule` a token to yield or a callback"
+        end
+
+        callback ||= case next_state
+        when :pop!
+          proc do |stream|
+            puts "    yielding #{tok.qualname}, #{stream[0].inspect}" if @debug
+            @output_stream.call(tok, stream[0])
+            puts "    popping stack: #{1}" if @debug
+            @stack.pop or raise 'empty stack!'
+          end
+        when :push
+          proc do |stream|
+            puts "    yielding #{tok.qualname}, #{stream[0].inspect}" if @debug
+            @output_stream.call(tok, stream[0])
+            puts "    pushing #{@stack.last.name}" if @debug
+            @stack.push(@stack.last)
+          end
+        when Symbol
+          proc do |stream|
+            puts "    yielding #{tok.qualname}, #{stream[0].inspect}" if @debug
+            @output_stream.call(tok, stream[0])
+            state = @states[next_state] || self.class.get_state(next_state)
+            puts "    pushing #{state.name}" if @debug
+            @stack.push(state)
+          end
+        when nil
+          proc do |stream|
+            puts "    yielding #{tok.qualname}, #{stream[0].inspect}" if @debug
+            @output_stream.call(tok, stream[0])
+          end
+        else
+          raise "invalid next state: #{next_state.inspect}"
+        end
+
+        rules << Rule.new(re, callback)
+      end
+
+      # Mix in the rules from another state into this state.  The rules
+      # from the mixed-in state will be tried in order before moving on
+      # to the rest of the rules in this state.
+      def mixin(state)
+        rules << state.to_s
+      end
+
+    private
+      def load!
+        return if @loaded
+        @loaded = true
+        instance_eval(&@defn)
+      end
+    end
+
+    # The states hash for this lexer.
+    # @see state
+    def self.states
+      @states ||= {}
+    end
+
+    def self.state_definitions
+      @state_definitions ||= InheritableHash.new(superclass.state_definitions)
+    end
+    @state_definitions = {}
+
+    def self.replace_state(name, new_defn)
+      states[name] = nil
+      state_definitions[name] = new_defn
+    end
+
+    # The routines to run at the beginning of a fresh lex.
+    # @see start
+    def self.start_procs
+      @start_procs ||= InheritableList.new(superclass.start_procs)
+    end
+    @start_procs = []
+
+    # Specify an action to be run every fresh lex.
+    #
+    # @example
+    #   start { puts "I'm lexing a new string!" }
+    def self.start(&b)
+      start_procs << b
+    end
+
+    # Define a new state for this lexer with the given name.
+    # The block will be evaluated in the context of a {StateDSL}.
+    def self.state(name, &b)
+      name = name.to_s
+      state_definitions[name] = StateDSL.new(name, &b)
+    end
+
+    def self.prepend(name, &b)
+      name = name.to_s
+      dsl = state_definitions[name] or raise "no such state #{name.inspect}"
+      replace_state(name, dsl.prepended(&b))
+    end
+
+    def self.append(state, &b)
+      name = name.to_s
+      dsl = state_definitions[name] or raise "no such state #{name.inspect}"
+      replace_state(name, dsl.appended(&b))
+    end
+
+    # @private
+    def self.get_state(name)
+      return name if name.is_a? State
+
+      states[name.to_sym] ||= begin
+        defn = state_definitions[name.to_s] or raise "unknown state: #{name.inspect}"
+        defn.to_state(self)
+      end
+    end
+
+    # @private
+    def get_state(state_name)
+      self.class.get_state(state_name)
+    end
+
+    # The state stack.  This is initially the single state `[:root]`.
+    # It is an error for this stack to be empty.
+    # @see #state
+    def stack
+      @stack ||= [get_state(:root)]
+    end
+
+    # The current state - i.e. one on top of the state stack.
+    #
+    # NB: if the state stack is empty, this will throw an error rather
+    # than returning nil.
+    def state
+      stack.last or raise 'empty stack!'
+    end
+
+    # reset this lexer to its initial state.  This runs all of the
+    # start_procs.
+    def reset!
+      @stack = nil
+      @current_stream = nil
+
+      self.class.start_procs.each do |pr|
+        instance_eval(&pr)
+      end
+    end
+
+    # This implements the lexer protocol, by yielding [token, value] pairs.
+    #
+    # The process for lexing works as follows, until the stream is empty:
+    #
+    # 1. We look at the state on top of the stack (which by default is
+    #    `[:root]`).
+    # 2. Each rule in that state is tried until one is successful.  If one
+    #    is found, that rule's callback is evaluated - which may yield
+    #    tokens and manipulate the state stack.  Otherwise, one character
+    #    is consumed with an `'Error'` token, and we continue at (1.)
+    #
+    # @see #step #step (where (2.) is implemented)
+    def stream_tokens(str, &b)
+      stream = StringScanner.new(str)
+
+      @current_stream = stream
+      @output_stream  = b
+      @states         = self.class.states
+      @null_steps     = 0
+
+      until stream.eos?
+        if @debug
+          puts "lexer: #{self.class.tag}"
+          puts "stack: #{stack.map(&:name).inspect}"
+          puts "stream: #{stream.peek(20).inspect}"
+        end
+
+        success = step(state, stream)
+
+        if !success
+          puts "    no match, yielding Error" if @debug
+          b.call(Token::Tokens::Error, stream.getch)
+        end
+      end
+    end
+
+    # The number of successive scans permitted without consuming
+    # the input stream.  If this is exceeded, the match fails.
+    MAX_NULL_SCANS = 5
+
+    # Runs one step of the lex.  Rules in the current state are tried
+    # until one matches, at which point its callback is called.
+    #
+    # @return true if a rule was tried successfully
+    # @return false otherwise.
+    def step(state, stream)
+      state.rules.each do |rule|
+        if rule.is_a?(State)
+          puts "  entering mixin #{rule.name}" if @debug
+          return true if step(rule, stream)
+          puts "  exiting  mixin #{rule.name}" if @debug
+        else
+          puts "  trying #{rule.inspect}" if @debug
+
+          # XXX HACK XXX
+          # StringScanner's implementation of ^ is b0rken.
+          # see http://bugs.ruby-lang.org/issues/7092
+          # TODO: this doesn't cover cases like /(a|^b)/, but it's
+          # the most common, for now...
+          next if rule.beginning_of_line && !stream.beginning_of_line?
+
+          if size = stream.skip(rule.re)
+            puts "    got #{stream[0].inspect}" if @debug
+
+            instance_exec(stream, &rule.callback)
+
+            if size.zero?
+              @null_steps += 1
+              if @null_steps > MAX_NULL_SCANS
+                puts "    too many scans without consuming the string!" if @debug
+                return false
+              end
+            else
+              @null_steps = 0
+            end
+
+            return true
+          end
+        end
+      end
+
+      false
+    end
+
+    # Yield a token.
+    #
+    # @param tok
+    #   the token type
+    # @param val
+    #   (optional) the string value to yield.  If absent, this defaults
+    #   to the entire last match.
+    def token(tok, val=@current_stream[0])
+      yield_token(tok, val)
+    end
+
+    # @deprecated
+    #
+    # Yield a token with the next matched group.  Subsequent calls
+    # to this method will yield subsequent groups.
+    def group(tok)
+      raise "RegexLexer#group is deprecated: use #groups instead"
+    end
+
+    # Yield tokens corresponding to the matched groups of the current
+    # match.
+    def groups(*tokens)
+      tokens.each_with_index do |tok, i|
+        yield_token(tok, @current_stream[i+1])
+      end
+    end
+
+    # Delegate the lex to another lexer.  The #lex method will be called
+    # with `:continue` set to true, so that #reset! will not be called.
+    # In this way, a single lexer can be repeatedly delegated to while
+    # maintaining its own internal state stack.
+    #
+    # @param [#lex] lexer
+    #   The lexer or lexer class to delegate to
+    # @param [String] text
+    #   The text to delegate.  This defaults to the last matched string.
+    def delegate(lexer, text=nil)
+      puts "    delegating to #{lexer.inspect}" if @debug
+      text ||= @current_stream[0]
+
+      lexer.lex(text, :continue => true) do |tok, val|
+        puts "    delegated token: #{tok.inspect}, #{val.inspect}" if @debug
+        yield_token(tok, val)
+      end
+    end
+
+    def recurse(text=nil)
+      delegate(self.class, text)
+    end
+
+    # Push a state onto the stack.  If no state name is given and you've
+    # passed a block, a state will be dynamically created using the
+    # {StateDSL}.
+    def push(state_name=nil, &b)
+      push_state = if state_name
+        get_state(state_name)
+      elsif block_given?
+        StateDSL.new(b.inspect, &b).to_state(self.class)
+      else
+        # use the top of the stack by default
+        self.state
+      end
+
+      puts "    pushing #{push_state.name}" if @debug
+      stack.push(push_state)
+    end
+
+    # Pop the state stack.  If a number is passed in, it will be popped
+    # that number of times.
+    def pop!(times=1)
+      raise 'empty stack!' if stack.empty?
+
+      puts "    popping stack: #{times}" if @debug
+
+      stack.pop(times)
+
+      nil
+    end
+
+    # replace the head of the stack with the given state
+    def goto(state_name)
+      raise 'empty stack!' if stack.empty?
+
+      puts "    going to state #{state_name} " if @debug
+      stack[-1] = get_state(state_name)
+    end
+
+    # reset the stack back to `[:root]`.
+    def reset_stack
+      puts '    resetting stack' if @debug
+      stack.clear
+      stack.push get_state(:root)
+    end
+
+    # Check if `state_name` is in the state stack.
+    def in_state?(state_name)
+      state_name = state_name.to_s
+      stack.any? do |state|
+        state.name == state_name.to_s
+      end
+    end
+
+    # Check if `state_name` is the state on top of the state stack.
+    def state?(state_name)
+      state_name.to_s == state.name
+    end
+
+  private
+    def yield_token(tok, val)
+      return if val.nil? || val.empty?
+      puts "    yielding #{tok.qualname}, #{val.inspect}" if @debug
+      @output_stream.yield(tok, val)
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/template_lexer.rb b/app/server/vendor/rouge/lib/rouge/template_lexer.rb
new file mode 100755
index 0000000..11f69fc
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/template_lexer.rb
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  # @abstract
+  # A TemplateLexer is one that accepts a :parent option, to specify
+  # which language is being templated.  The lexer class can specify its
+  # own default for the parent lexer, which is otherwise defaulted to
+  # HTML.
+  class TemplateLexer < RegexLexer
+    # the parent lexer - the one being templated.
+    def parent
+      return @parent if instance_variable_defined? :@parent
+      @parent = option(:parent) || 'html'
+      if @parent.is_a? ::String
+        lexer_class = Lexer.find(@parent)
+        @parent = lexer_class.new(self.options)
+      end
+    end
+
+    start { parent.reset! }
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/text_analyzer.rb b/app/server/vendor/rouge/lib/rouge/text_analyzer.rb
new file mode 100755
index 0000000..f4434d3
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/text_analyzer.rb
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  class TextAnalyzer < String
+    # Find a shebang.  Returns nil if no shebang is present.
+    def shebang
+      return @shebang if instance_variable_defined? :@shebang
+
+      self =~ /\A\s*#!(.*)$/
+      @shebang = $1
+    end
+
+    # Check if the given shebang is present.
+    #
+    # This normalizes things so that `text.shebang?('bash')` will detect
+    # `#!/bash`, '#!/bin/bash', '#!/usr/bin/env bash', and '#!/bin/bash -x'
+    def shebang?(match)
+      match = /\b#{match}(\s|$)/
+      match === shebang
+    end
+
+    # Return the contents of the doctype tag if present, nil otherwise.
+    def doctype
+      return @doctype if instance_variable_defined? :@doctype
+
+      self =~ %r(\A\s*
+        (?:<\?.*?\?>\s*)? # possible <?xml...?> tag
+        <!DOCTYPE\s+(.+?)>
+      )xm
+      @doctype = $1
+    end
+
+    # Check if the doctype matches a given regexp or string
+    def doctype?(type=//)
+      type === doctype
+    end
+
+    # Return true if the result of lexing with the given lexer contains no
+    # error tokens.
+    def lexes_cleanly?(lexer)
+      lexer.lex(self) do |(tok, _)|
+        return false if tok.name == 'Error'
+      end
+
+      true
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/theme.rb b/app/server/vendor/rouge/lib/rouge/theme.rb
new file mode 100755
index 0000000..3015b0a
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/theme.rb
@@ -0,0 +1,195 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  class Theme
+    include Token::Tokens
+
+    class Style < Hash
+      def initialize(theme, hsh={})
+        super()
+        @theme = theme
+        merge!(hsh)
+      end
+
+      [:fg, :bg].each do |mode|
+        define_method mode do
+          return self[mode] unless @theme
+          @theme.palette(self[mode]) if self[mode]
+        end
+      end
+
+      def render(selector, &b)
+        return enum_for(:render, selector).to_a.join("\n") unless b
+
+        return if empty?
+
+        yield "#{selector} {"
+        rendered_rules.each do |rule|
+          yield "  #{rule};"
+        end
+        yield "}"
+      end
+
+      def rendered_rules(&b)
+        return enum_for(:rendered_rules) unless b
+        yield "color: #{fg}" if fg
+        yield "background-color: #{bg}" if bg
+        yield "font-weight: bold" if self[:bold]
+        yield "font-style: italic" if self[:italic]
+        yield "text-decoration: underline" if self[:underline]
+
+        (self[:rules] || []).each(&b)
+      end
+    end
+
+    def styles
+      @styles ||= self.class.styles.dup
+    end
+
+    @palette = {}
+    def self.palette(arg={})
+      @palette ||= InheritableHash.new(superclass.palette)
+
+      if arg.is_a? Hash
+        @palette.merge! arg
+        @palette
+      else
+        case arg
+        when /#[0-9a-f]+/i
+          arg
+        else
+          @palette[arg] or raise "not in palette: #{arg.inspect}"
+        end
+      end
+    end
+
+    @styles = {}
+    def self.styles
+      @styles ||= InheritableHash.new(superclass.styles)
+    end
+
+    def self.render(opts={}, &b)
+      new(opts).render(&b)
+    end
+
+    class << self
+      def style(*tokens)
+        style = tokens.last.is_a?(Hash) ? tokens.pop : {}
+
+        style = Style.new(self, style)
+
+        tokens.each do |tok|
+          styles[tok] = style
+        end
+      end
+
+      def get_own_style(token)
+        token.token_chain.each do |anc|
+          return styles[anc] if styles[anc]
+        end
+
+        nil
+      end
+
+      def get_style(token)
+        get_own_style(token) || base_style
+      end
+
+      def base_style
+        styles[Token::Tokens::Text]
+      end
+
+      def name(n=nil)
+        return @name if n.nil?
+
+        @name = n.to_s
+        Theme.registry[@name] = self
+      end
+
+      def find(n)
+        registry[n.to_s]
+      end
+
+      def registry
+        @registry ||= {}
+      end
+    end
+  end
+
+  module HasModes
+    def mode(arg=:absent)
+      return @mode if arg == :absent
+
+      @modes ||= {}
+      @modes[arg] ||= get_mode(arg)
+    end
+
+    def get_mode(mode)
+      return self if self.mode == mode
+
+      new_name = "#{self.name}.#{mode}"
+      Class.new(self) { name(new_name); mode!(mode) }
+    end
+
+    def mode!(arg)
+      @mode = arg
+      send("make_#{arg}!")
+    end
+  end
+
+  class CSSTheme < Theme
+    def initialize(opts={})
+      @scope = opts[:scope] || '.highlight'
+    end
+
+    def render(&b)
+      return enum_for(:render).to_a.join("\n") unless b
+
+      # shared styles for tableized line numbers
+      yield "#{@scope} table td { padding: 5px; }"
+      yield "#{@scope} table pre { margin: 0; }"
+
+      styles.each do |tok, style|
+        style.render(css_selector(tok), &b)
+      end
+    end
+
+    def render_base(selector, &b)
+      self.class.base_style.render(selector, &b)
+    end
+
+    def style_for(tok)
+      self.class.get_style(tok)
+    end
+
+  private
+    def css_selector(token)
+      inflate_token(token).map do |tok|
+        raise "unknown token: #{tok.inspect}" if tok.shortname.nil?
+
+        single_css_selector(tok)
+      end.join(', ')
+    end
+
+    def single_css_selector(token)
+      return @scope if token == Text
+
+      "#{@scope} .#{token.shortname}"
+    end
+
+    # yield all of the tokens that should be styled the same
+    # as the given token.  Essentially this recursively all of
+    # the subtokens, except those which are more specifically
+    # styled.
+    def inflate_token(tok, &b)
+      return enum_for(:inflate_token, tok) unless block_given?
+
+      yield tok
+      tok.sub_tokens.each do |(_, st)|
+        next if styles[st]
+
+        inflate_token(st, &b)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/themes/base16.rb b/app/server/vendor/rouge/lib/rouge/themes/base16.rb
new file mode 100755
index 0000000..9fea1c8
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/themes/base16.rb
@@ -0,0 +1,130 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Themes
+    # default base16 theme
+    # by Chris Kempson (http://chriskempson.com)
+    class Base16 < CSSTheme
+      name 'base16'
+
+      palette base00: "#151515"
+      palette base01: "#202020"
+      palette base02: "#303030"
+      palette base03: "#505050"
+      palette base04: "#b0b0b0"
+      palette base05: "#d0d0d0"
+      palette base06: "#e0e0e0"
+      palette base07: "#f5f5f5"
+      palette base08: "#ac4142"
+      palette base09: "#d28445"
+      palette base0A: "#f4bf75"
+      palette base0B: "#90a959"
+      palette base0C: "#75b5aa"
+      palette base0D: "#6a9fb5"
+      palette base0E: "#aa759f"
+      palette base0F: "#8f5536"
+
+      extend HasModes
+
+      def self.light!
+        mode :dark # indicate that there is a dark variant
+        mode! :light
+      end
+
+      def self.dark!
+        mode :light # indicate that there is a light variant
+        mode! :dark
+      end
+
+      def self.make_dark!
+        style Text, :fg => :base05, :bg => :base00
+      end
+
+      def self.make_light!
+        style Text, :fg => :base02
+      end
+
+      light!
+
+      style Error, :fg => :base00, :bg => :base08
+      style Comment, :fg => :base03
+
+      style Comment::Preproc,
+            Name::Tag, :fg => :base0A
+
+      style Operator,
+            Punctuation, :fg => :base05
+
+      style Generic::Inserted, :fg => :base0B
+      style Generic::Deleted, :fg => :base08
+      style Generic::Heading, :fg => :base0D, :bg => :base00, :bold => true
+
+      style Keyword, :fg => :base0E
+      style Keyword::Constant,
+            Keyword::Type, :fg => :base09
+
+      style Keyword::Declaration, :fg => :base09
+
+      style Literal::String, :fg => :base0B
+      style Literal::String::Regex, :fg => :base0C
+
+      style Literal::String::Interpol,
+            Literal::String::Escape, :fg => :base0F
+
+      style Name::Namespace,
+            Name::Class,
+            Name::Constant, :fg => :base0A
+
+      style Name::Attribute, :fg => :base0D
+
+      style Literal::Number,
+            Literal::String::Symbol, :fg => :base0B
+
+      class Solarized < Base16
+        name 'base16.solarized'
+        light!
+        # author "Ethan Schoonover (http://ethanschoonover.com/solarized)"
+
+        palette base00: "#002b36"
+        palette base01: "#073642"
+        palette base02: "#586e75"
+        palette base03: "#657b83"
+        palette base04: "#839496"
+        palette base05: "#93a1a1"
+        palette base06: "#eee8d5"
+        palette base07: "#fdf6e3"
+        palette base08: "#dc322f"
+        palette base09: "#cb4b16"
+        palette base0A: "#b58900"
+        palette base0B: "#859900"
+        palette base0C: "#2aa198"
+        palette base0D: "#268bd2"
+        palette base0E: "#6c71c4"
+        palette base0F: "#d33682"
+      end
+
+      class Monokai < Base16
+        name 'base16.monokai'
+        dark!
+
+        # author "Wimer Hazenberg (http://www.monokai.nl)"
+        palette base00: "#272822"
+        palette base01: "#383830"
+        palette base02: "#49483e"
+        palette base03: "#75715e"
+        palette base04: "#a59f85"
+        palette base05: "#f8f8f2"
+        palette base06: "#f5f4f1"
+        palette base07: "#f9f8f5"
+        palette base08: "#f92672"
+        palette base09: "#fd971f"
+        palette base0A: "#f4bf75"
+        palette base0B: "#a6e22e"
+        palette base0C: "#a1efe4"
+        palette base0D: "#66d9ef"
+        palette base0E: "#ae81ff"
+        palette base0F: "#cc6633"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/themes/colorful.rb b/app/server/vendor/rouge/lib/rouge/themes/colorful.rb
new file mode 100755
index 0000000..b108fe6
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/themes/colorful.rb
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Themes
+    # stolen from pygments
+    class Colorful < CSSTheme
+      name 'colorful'
+
+      style Text,                        :fg => "#bbbbbb", :bg => '#000'
+
+      style Comment,                     :fg => "#888"
+      style Comment::Preproc,            :fg => "#579"
+      style Comment::Special,            :fg => "#cc0000", :bold => true
+
+      style Keyword,                     :fg => "#080", :bold => true
+      style Keyword::Pseudo,             :fg => "#038"
+      style Keyword::Type,               :fg => "#339"
+
+      style Operator,                    :fg => "#333"
+      style Operator::Word,              :fg => "#000", :bold => true
+
+      style Name::Builtin,               :fg => "#007020"
+      style Name::Function,              :fg => "#06B", :bold => true
+      style Name::Class,                 :fg => "#B06", :bold => true
+      style Name::Namespace,             :fg => "#0e84b5", :bold => true
+      style Name::Exception,             :fg => "#F00", :bold => true
+      style Name::Variable,              :fg => "#963"
+      style Name::Variable::Instance,    :fg => "#33B"
+      style Name::Variable::Class,       :fg => "#369"
+      style Name::Variable::Global,      :fg => "#d70", :bold => true
+      style Name::Constant,              :fg => "#036", :bold => true
+      style Name::Label,                 :fg => "#970", :bold => true
+      style Name::Entity,                :fg => "#800", :bold => true
+      style Name::Attribute,             :fg => "#00C"
+      style Name::Tag,                   :fg => "#070"
+      style Name::Decorator,             :fg => "#555", :bold => true
+
+      style Literal::String,             :bg => "#fff0f0"
+      style Literal::String::Char,       :fg => "#04D"
+      style Literal::String::Doc,        :fg => "#D42"
+      style Literal::String::Interpol,   :bg => "#eee"
+      style Literal::String::Escape,     :fg => "#666", :bold => true
+      style Literal::String::Regex,      :fg => "#000", :bg => "#fff0ff"
+      style Literal::String::Symbol,     :fg => "#A60"
+      style Literal::String::Other,      :fg => "#D20"
+
+      style Literal::Number,             :fg => "#60E", :bold => true
+      style Literal::Number::Integer,    :fg => "#00D", :bold => true
+      style Literal::Number::Float,      :fg => "#60E", :bold => true
+      style Literal::Number::Hex,        :fg => "#058", :bold => true
+      style Literal::Number::Oct,        :fg => "#40E", :bold => true
+
+      style Generic::Heading,            :fg => "#000080", :bold => true
+      style Generic::Subheading,         :fg => "#800080", :bold => true
+      style Generic::Deleted,            :fg => "#A00000"
+      style Generic::Inserted,           :fg => "#00A000"
+      style Generic::Error,              :fg => "#FF0000"
+      style Generic::Emph,               :italic => true
+      style Generic::Strong,             :bold => true
+      style Generic::Prompt,             :fg => "#c65d09", :bold => true
+      style Generic::Output,             :fg => "#888"
+      style Generic::Traceback,          :fg => "#04D"
+
+      style Error,                       :fg => "#F00", :bg => "#FAA"
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/themes/github.rb b/app/server/vendor/rouge/lib/rouge/themes/github.rb
new file mode 100755
index 0000000..bc875a8
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/themes/github.rb
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Themes
+    class Github < CSSTheme
+      name 'github'
+
+      style Comment::Multiline,               :fg => '#999988', :italic => true
+      style Comment::Preproc,                 :fg => '#999999', :bold => true
+      style Comment::Single,                  :fg => '#999988', :italic => true
+      style Comment::Special,                 :fg => '#999999', :italic => true, :bold => true
+      style Comment,                          :fg => '#999988', :italic => true
+      style Error,                            :fg => '#a61717', :bg => '#e3d2d2'
+      style Generic::Deleted,                 :fg => '#000000', :bg => '#ffdddd'
+      style Generic::Emph,                    :fg => '#000000', :italic => true
+      style Generic::Error,                   :fg => '#aa0000'
+      style Generic::Heading,                 :fg => '#999999'
+      style Generic::Inserted,                :fg => '#000000', :bg => '#ddffdd'
+      style Generic::Output,                  :fg => '#888888'
+      style Generic::Prompt,                  :fg => '#555555'
+      style Generic::Strong,                  :bold => true
+      style Generic::Subheading,              :fg => '#aaaaaa'
+      style Generic::Traceback,               :fg => '#aa0000'
+      style Keyword::Constant,                :fg => '#000000', :bold => true
+      style Keyword::Declaration,             :fg => '#000000', :bold => true
+      style Keyword::Namespace,               :fg => '#000000', :bold => true
+      style Keyword::Pseudo,                  :fg => '#000000', :bold => true
+      style Keyword::Reserved,                :fg => '#000000', :bold => true
+      style Keyword::Type,                    :fg => '#445588', :bold => true
+      style Keyword,                          :fg => '#000000', :bold => true
+      style Literal::Number::Float,           :fg => '#009999'
+      style Literal::Number::Hex,             :fg => '#009999'
+      style Literal::Number::Integer::Long,   :fg => '#009999'
+      style Literal::Number::Integer,         :fg => '#009999'
+      style Literal::Number::Oct,             :fg => '#009999'
+      style Literal::Number,                  :fg => '#009999'
+      style Literal::String::Backtick,        :fg => '#d14'
+      style Literal::String::Char,            :fg => '#d14'
+      style Literal::String::Doc,             :fg => '#d14'
+      style Literal::String::Double,          :fg => '#d14'
+      style Literal::String::Escape,          :fg => '#d14'
+      style Literal::String::Heredoc,         :fg => '#d14'
+      style Literal::String::Interpol,        :fg => '#d14'
+      style Literal::String::Other,           :fg => '#d14'
+      style Literal::String::Regex,           :fg => '#009926'
+      style Literal::String::Single,          :fg => '#d14'
+      style Literal::String::Symbol,          :fg => '#990073'
+      style Literal::String,                  :fg => '#d14'
+      style Name::Attribute,                  :fg => '#008080'
+      style Name::Builtin::Pseudo,            :fg => '#999999'
+      style Name::Builtin,                    :fg => '#0086B3'
+      style Name::Class,                      :fg => '#445588', :bold => true
+      style Name::Constant,                   :fg => '#008080'
+      style Name::Decorator,                  :fg => '#3c5d5d', :bold => true
+      style Name::Entity,                     :fg => '#800080'
+      style Name::Exception,                  :fg => '#990000', :bold => true
+      style Name::Function,                   :fg => '#990000', :bold => true
+      style Name::Label,                      :fg => '#990000', :bold => true
+      style Name::Namespace,                  :fg => '#555555'
+      style Name::Tag,                        :fg => '#000080'
+      style Name::Variable::Class,            :fg => '#008080'
+      style Name::Variable::Global,           :fg => '#008080'
+      style Name::Variable::Instance,         :fg => '#008080'
+      style Name::Variable,                   :fg => '#008080'
+      style Operator::Word,                   :fg => '#000000', :bold => true
+      style Operator,                         :fg => '#000000', :bold => true
+      style Text::Whitespace,                 :fg => '#bbbbbb'
+      style Text,                             :bg => '#f8f8f8'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/themes/monokai.rb b/app/server/vendor/rouge/lib/rouge/themes/monokai.rb
new file mode 100755
index 0000000..a9c7891
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/themes/monokai.rb
@@ -0,0 +1,90 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Themes
+    class Monokai < CSSTheme
+      name 'monokai'
+
+      palette :black          => '#000000'
+      palette :bright_green   => '#a6e22e'
+      palette :bright_pink    => '#f92672'
+      palette :carmine        => '#960050'
+      palette :dark           => '#49483e'
+      palette :dark_grey      => '#888888'
+      palette :dark_red       => '#aa0000'
+      palette :dimgrey        => '#75715e'
+      palette :emperor        => '#555555'
+      palette :grey           => '#999999'
+      palette :light_grey     => '#aaaaaa'
+      palette :light_violet   => '#ae81ff'
+      palette :soft_cyan      => '#66d9ef'
+      palette :soft_yellow    => '#e6db74'
+      palette :very_dark      => '#1e0010'
+      palette :whitish        => '#f8f8f2'
+      palette :orange         => '#f6aa11'
+      palette :white          => '#ffffff'
+
+      style Comment,
+            Comment::Multiline,
+            Comment::Single,                  :fg => :dimgrey, :italic => true
+      style Comment::Preproc,                 :fg => :dimgrey, :bold => true
+      style Comment::Special,                 :fg => :dimgrey, :italic => true, :bold => true
+      style Error,                            :fg => :carmine, :bg => :very_dark
+      style Generic::Deleted,
+            Generic::Inserted,                :fg => :black
+      style Generic::Emph,                    :fg => :black, :italic => true
+      style Generic::Error,
+            Generic::Traceback,               :fg => :dark_red
+      style Generic::Heading,                 :fg => :grey
+      style Generic::Output,                  :fg => :dark_grey
+      style Generic::Prompt,                  :fg => :emperor
+      style Generic::Strong,                  :bold => true
+      style Generic::Subheading,              :fg => :light_grey
+      style Keyword,
+            Keyword::Constant,
+            Keyword::Declaration,
+            Keyword::Pseudo,
+            Keyword::Reserved,
+            Keyword::Type,                    :fg => :soft_cyan, :bold => true
+      style Keyword::Namespace,
+            Operator::Word,
+            Operator,                         :fg => :bright_pink, :bold => true
+      style Literal::Number::Float,
+            Literal::Number::Hex,
+            Literal::Number::Integer::Long,
+            Literal::Number::Integer,
+            Literal::Number::Oct,
+            Literal::Number,
+            Literal::String::Escape,          :fg => :light_violet
+      style Literal::String::Backtick,
+            Literal::String::Char,
+            Literal::String::Doc,
+            Literal::String::Double,
+            Literal::String::Heredoc,
+            Literal::String::Interpol,
+            Literal::String::Other,
+            Literal::String::Regex,
+            Literal::String::Single,
+            Literal::String::Symbol,
+            Literal::String,                  :fg => :soft_yellow
+      style Name::Attribute,                  :fg => :bright_green
+      style Name::Class,
+            Name::Decorator,
+            Name::Exception,
+            Name::Function,                   :fg => :bright_green, :bold => true
+      style Name::Constant,                   :fg => :soft_cyan
+      style Name::Builtin::Pseudo,
+            Name::Builtin,
+            Name::Entity,
+            Name::Namespace,
+            Name::Variable::Class,
+            Name::Variable::Global,
+            Name::Variable::Instance,
+            Name::Variable,
+            Text::Whitespace,                 :fg => :whitish
+      style Name::Label,                      :fg => :whitish, :bold => true
+      style Name::Tag,                        :fg => :bright_pink
+      style Text,                             :fg => :whitish, :bg => :dark
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/themes/monokai_sublime.rb b/app/server/vendor/rouge/lib/rouge/themes/monokai_sublime.rb
new file mode 100755
index 0000000..5c700e7
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/themes/monokai_sublime.rb
@@ -0,0 +1,90 @@
+# -*- coding: utf-8 -*- #
+module Rouge
+  module Themes
+    class MonokaiSublime < CSSTheme
+      name 'monokai.sublime'
+
+      palette :black          => '#000000'
+      palette :bright_green   => '#a6e22e'
+      palette :bright_pink    => '#f92672'
+      palette :carmine        => '#960050'
+      palette :dark           => '#49483e'
+      palette :dark_grey      => '#888888'
+      palette :dark_red       => '#aa0000'
+      palette :dimgrey        => '#75715e'
+      palette :emperor        => '#555555'
+      palette :grey           => '#999999'
+      palette :light_grey     => '#aaaaaa'
+      palette :light_violet   => '#ae81ff'
+      palette :soft_cyan      => '#66d9ef'
+      palette :soft_yellow    => '#e6db74'
+      palette :very_dark      => '#1e0010'
+      palette :whitish        => '#f8f8f2'
+      palette :orange         => '#f6aa11'
+      palette :white          => '#ffffff'
+
+      style Generic::Heading,                 :fg => :grey
+      style Literal::String::Regex,           :fg => :orange
+      style Generic::Output,                  :fg => :dark_grey
+      style Generic::Prompt,                  :fg => :emperor
+      style Generic::Strong,                  :bold => false
+      style Generic::Subheading,              :fg => :light_grey
+      style Name::Builtin,                    :fg => :orange
+      style Comment::Multiline,
+            Comment::Preproc,
+            Comment::Single,
+            Comment::Special,
+            Comment,                          :fg => :dimgrey
+      style Error,
+            Generic::Error,
+            Generic::Traceback,               :fg => :carmine
+      style Generic::Deleted,
+            Generic::Inserted,
+            Generic::Emph,                    :fg => :dark
+      style Keyword::Constant,
+            Keyword::Declaration,
+            Keyword::Reserved,
+            Name::Constant,
+            Keyword::Type,                    :fg => :soft_cyan
+      style Literal::Number::Float,
+            Literal::Number::Hex,
+            Literal::Number::Integer::Long,
+            Literal::Number::Integer,
+            Literal::Number::Oct,
+            Literal::Number,
+            Literal::String::Char,
+            Literal::String::Escape,
+            Literal::String::Symbol,          :fg => :light_violet
+      style Literal::String::Doc,
+            Literal::String::Double,
+            Literal::String::Backtick,
+            Literal::String::Heredoc,
+            Literal::String::Interpol,
+            Literal::String::Other,
+            Literal::String::Single,
+            Literal::String,                  :fg => :soft_yellow
+      style Name::Attribute,
+            Name::Class,
+            Name::Decorator,
+            Name::Exception,
+            Name::Function,                   :fg => :bright_green
+      style Name::Variable::Class,
+            Name::Namespace,
+            Name::Label,
+            Name::Entity,
+            Name::Builtin::Pseudo,
+            Name::Variable::Global,
+            Name::Variable::Instance,
+            Name::Variable,
+            Text::Whitespace,
+            Text,
+            Name,                             :fg => :white
+      style Operator::Word,
+            Name::Tag,
+            Keyword,
+            Keyword::Namespace,
+            Keyword::Pseudo,
+            Operator,                         :fg => :bright_pink
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/themes/thankful_eyes.rb b/app/server/vendor/rouge/lib/rouge/themes/thankful_eyes.rb
new file mode 100755
index 0000000..d041b38
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/themes/thankful_eyes.rb
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  module Themes
+    class ThankfulEyes < CSSTheme
+      name 'thankful_eyes'
+
+      # pallette, from GTKSourceView's ThankfulEyes
+      palette :cool_as_ice    => '#6c8b9f'
+      palette :slate_blue     => '#4e5d62'
+      palette :eggshell_cloud => '#dee5e7'
+      palette :krasna         => '#122b3b'
+      palette :aluminum1      => '#fefeec'
+      palette :scarletred2    => '#cc0000'
+      palette :butter3        => '#c4a000'
+      palette :go_get_it      => '#b2fd6d'
+      palette :chilly         => '#a8e1fe'
+      palette :unicorn        => '#faf6e4'
+      palette :sandy          => '#f6dd62'
+      palette :pink_merengue  => '#f696db'
+      palette :dune           => '#fff0a6'
+      palette :backlit        => '#4df4ff'
+      palette :schrill        => '#ffb000'
+
+      style Text, :fg => :unicorn, :bg => :krasna
+      style Generic::Lineno, :fg => :eggshell_cloud, :bg => :slate_blue
+
+      style Comment, :fg => :cool_as_ice, :italic => true
+      style Comment::Preproc, :fg => :go_get_it, :bold => true, :italic => true
+      style Error,
+            Generic::Error, :fg => :aluminum1, :bg => :scarletred2
+      style Keyword, :fg => :sandy, :bold => true
+      style Operator,
+            Punctuation, :fg => :backlit
+      style Generic::Deleted, :fg => :scarletred2
+      style Generic::Inserted, :fg => :go_get_it
+      style Generic::Emph, :italic => true
+      style Generic::Strong, :bold => true
+      style Generic::Traceback, :fg => :eggshell_cloud, :bg => :slate_blue
+      style Keyword::Constant, :fg => :pink_merengue, :bold => true
+      style Keyword::Namespace,
+            Keyword::Pseudo,
+            Keyword::Reserved,
+            Generic::Heading,
+            Generic::Subheading, :fg => :schrill, :bold => true
+      style Keyword::Type,
+            Name::Constant,
+            Name::Class,
+            Name::Decorator,
+            Name::Namespace,
+            Name::Builtin::Pseudo,
+            Name::Exception, :fg => :go_get_it, :bold => true
+      style Name::Label,
+            Name::Tag, :fg => :schrill, :bold => true
+      style Literal::Number,
+            Literal::Date,
+            Literal::String::Symbol, :fg => :pink_merengue, :bold => true
+      style Literal::String, :fg => :dune, :bold => true
+      style Literal::String::Escape,
+            Literal::String::Char,
+            Literal::String::Interpol, :fg => :backlit, :bold => true
+      style Name::Builtin, :bold => true
+      style Name::Entity, :fg => '#999999', :bold => true
+      style Text::Whitespace, :fg => '#BBBBBB'
+      style Name::Function,
+            Name::Property,
+            Name::Attribute, :fg => :chilly
+      style Name::Variable, :fg => :chilly, :bold => true
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/token.rb b/app/server/vendor/rouge/lib/rouge/token.rb
new file mode 100755
index 0000000..f9ea383
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/token.rb
@@ -0,0 +1,182 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  class Token
+    class << self
+      attr_reader :name
+      attr_reader :parent
+      attr_reader :shortname
+
+      def cache
+        @cache ||= {}
+      end
+
+      def sub_tokens
+        @sub_tokens ||= {}
+      end
+
+      def [](qualname)
+        return qualname unless qualname.is_a? ::String
+
+        Token.cache[qualname]
+      end
+
+      def inspect
+        "<Token #{qualname}>"
+      end
+
+      def matches?(other)
+        other.token_chain.include? self
+      end
+
+      def token_chain
+        @token_chain ||= ancestors.take_while { |x| x != Token }.reverse
+      end
+
+      def qualname
+        @qualname ||= token_chain.map(&:name).join('.')
+      end
+
+      def register!
+        Token.cache[self.qualname] = self
+        parent.sub_tokens[self.name] = self
+      end
+
+      def make_token(name, shortname, &b)
+        parent = self
+        Class.new(parent) do
+          @parent = parent
+          @name = name
+          @shortname = shortname
+          register!
+          class_eval(&b) if b
+        end
+      end
+
+      def token(name, shortname, &b)
+        tok = make_token(name, shortname, &b)
+        const_set(name, tok)
+      end
+
+      def each_token(&b)
+        Token.cache.each do |(_, t)|
+          b.call(t)
+        end
+      end
+    end
+
+    module Tokens
+      def self.token(name, shortname, &b)
+        tok = Token.make_token(name, shortname, &b)
+        const_set(name, tok)
+      end
+
+      # XXX IMPORTANT XXX
+      # For compatibility, this list must be kept in sync with
+      # pygments.token.STANDARD_TYPES
+      # please see https://github.com/jayferd/rouge/wiki/List-of-tokens
+      token :Text, '' do
+        token :Whitespace, 'w'
+      end
+
+      token :Error, 'err'
+      token :Other, 'x'
+
+      token :Keyword, 'k' do
+        token :Constant,    'kc'
+        token :Declaration, 'kd'
+        token :Namespace,   'kn'
+        token :Pseudo,      'kp'
+        token :Reserved,    'kr'
+        token :Type,        'kt'
+        token :Variable,    'kv'
+      end
+
+      token :Name, 'n' do
+        token :Attribute,    'na'
+        token :Builtin,      'nb' do
+          token :Pseudo,     'bp'
+        end
+        token :Class,        'nc'
+        token :Constant,     'no'
+        token :Decorator,    'nd'
+        token :Entity,       'ni'
+        token :Exception,    'ne'
+        token :Function,     'nf'
+        token :Property,     'py'
+        token :Label,        'nl'
+        token :Namespace,    'nn'
+        token :Other,        'nx'
+        token :Tag,          'nt'
+        token :Variable,     'nv' do
+          token :Class,      'vc'
+          token :Global,     'vg'
+          token :Instance,   'vi'
+        end
+      end
+
+      token :Literal,      'l' do
+        token :Date,       'ld'
+
+        token :String,     's' do
+          token :Backtick, 'sb'
+          token :Char,     'sc'
+          token :Doc,      'sd'
+          token :Double,   's2'
+          token :Escape,   'se'
+          token :Heredoc,  'sh'
+          token :Interpol, 'si'
+          token :Other,    'sx'
+          token :Regex,    'sr'
+          token :Single,   's1'
+          token :Symbol,   'ss'
+        end
+
+        token :Number,     'm' do
+          token :Float,    'mf'
+          token :Hex,      'mh'
+          token :Integer,  'mi' do
+            token :Long,   'il'
+          end
+          token :Oct,      'mo'
+          token :Bin,      'mb'
+          token :Other,    'mx'
+        end
+      end
+
+      token :Operator, 'o' do
+        token :Word,   'ow'
+      end
+
+      token :Punctuation, 'p' do
+        token :Indicator, 'pi'
+      end
+
+      token :Comment,     'c' do
+        token :Doc,       'cd'
+        token :Multiline, 'cm'
+        token :Preproc,   'cp'
+        token :Single,    'c1'
+        token :Special,   'cs'
+      end
+
+      token :Generic,      'g' do
+        token :Deleted,    'gd'
+        token :Emph,       'ge'
+        token :Error,      'gr'
+        token :Heading,    'gh'
+        token :Inserted,   'gi'
+        token :Output,     'go'
+        token :Prompt,     'gp'
+        token :Strong,     'gs'
+        token :Subheading, 'gu'
+        token :Traceback,  'gt'
+        token :Lineno,     'gl'
+      end
+
+      # convenience
+      Num = Literal::Number
+      Str = Literal::String
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/util.rb b/app/server/vendor/rouge/lib/rouge/util.rb
new file mode 100755
index 0000000..77168f6
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/util.rb
@@ -0,0 +1,101 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  class InheritableHash < Hash
+    def initialize(parent=nil)
+      @parent = parent
+    end
+
+    def [](k)
+      _sup = super
+      return _sup if own_keys.include?(k)
+
+      _sup || parent[k]
+    end
+
+    def parent
+      @parent ||= {}
+    end
+
+    def include?(k)
+      super or parent.include?(k)
+    end
+
+    def each(&b)
+      keys.each do |k|
+        b.call(k, self[k])
+      end
+    end
+
+    alias own_keys keys
+    def keys
+      keys = own_keys.concat(parent.keys)
+      keys.uniq!
+      keys
+    end
+  end
+
+  class InheritableList
+    include Enumerable
+
+    def initialize(parent=nil)
+      @parent = parent
+    end
+
+    def parent
+      @parent ||= []
+    end
+
+    def each(&b)
+      return enum_for(:each) unless block_given?
+
+      parent.each(&b)
+      own_entries.each(&b)
+    end
+
+    def own_entries
+      @own_entries ||= []
+    end
+
+    def push(o)
+      own_entries << o
+    end
+    alias << push
+  end
+
+  # shared methods for some indentation-sensitive lexers
+  module Indentation
+    def reset!
+      super
+      @block_state = @block_indentation = nil
+    end
+
+    # push a state for the next indented block
+    def starts_block(block_state)
+      @block_state = block_state
+      @block_indentation = @last_indentation || ''
+      puts "    starts_block #{block_state.inspect}" if @debug
+      puts "    block_indentation: #{@block_indentation.inspect}" if @debug
+    end
+
+    # handle a single indented line
+    def indentation(indent_str)
+      puts "    indentation #{indent_str.inspect}" if @debug
+      puts "    block_indentation: #{@block_indentation.inspect}" if @debug
+      @last_indentation = indent_str
+
+      # if it's an indent and we know where to go next,
+      # push that state.  otherwise, push content and
+      # clear the block state.
+      if (@block_state &&
+          indent_str.start_with?(@block_indentation) &&
+          indent_str != @block_indentation
+      )
+        push @block_state
+      else
+        @block_state = @block_indentation = nil
+        push :content
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/lib/rouge/version.rb b/app/server/vendor/rouge/lib/rouge/version.rb
new file mode 100755
index 0000000..7afb092
--- /dev/null
+++ b/app/server/vendor/rouge/lib/rouge/version.rb
@@ -0,0 +1,7 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+  def self.version
+    "1.6.2"
+  end
+end
diff --git a/app/server/vendor/rouge/rouge.gemspec b/app/server/vendor/rouge/rouge.gemspec
new file mode 100755
index 0000000..8798d62
--- /dev/null
+++ b/app/server/vendor/rouge/rouge.gemspec
@@ -0,0 +1,18 @@
+require './lib/rouge/version'
+
+Gem::Specification.new do |s|
+  s.name = "rouge"
+  s.version = Rouge.version
+  s.authors = ["Jeanine Adkisson"]
+  s.email = ["jneen at jneen.net"]
+  s.summary = "A pure-ruby colorizer based on pygments"
+  s.description = <<-desc.strip.gsub(/\s+/, ' ')
+    Rouge aims to a be a simple, easy-to-extend drop-in replacement
+    for pygments.
+  desc
+  s.homepage = "http://github.com/jneen/rouge"
+  s.rubyforge_project = "rouge"
+  s.files = Dir['Gemfile', 'LICENSE', 'rouge.gemspec', 'lib/**/*.rb', 'bin/rougify', 'lib/rouge/demos/*']
+  s.executables = %w(rougify)
+  s.license = 'MIT (see LICENSE file)'
+end
diff --git a/app/server/vendor/rouge/spec/cli_spec.rb b/app/server/vendor/rouge/spec/cli_spec.rb
new file mode 100755
index 0000000..cb7e1cb
--- /dev/null
+++ b/app/server/vendor/rouge/spec/cli_spec.rb
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*- #
+
+require 'rouge/cli'
+
+describe Rouge::CLI do
+  let(:argv) { [] }
+  subject { Rouge::CLI.parse(argv) }
+
+  describe Rouge::CLI::Help do
+    describe '-h' do
+      let(:argv) { %w(-h) }
+      it('parses') { assert { Rouge::CLI::Help === subject } }
+    end
+
+    describe '--help' do
+      let(:argv) { %w(--help) }
+      it('parses') { assert { Rouge::CLI::Help === subject } }
+    end
+
+    describe 'help' do
+      let(:argv) { %w(help) }
+      it('parses') { assert { Rouge::CLI::Help === subject } }
+    end
+  end
+
+  describe Rouge::CLI::Highlight do
+    describe 'specifying a lexer' do
+      let(:argv) { %w(highlight -l ruby) }
+      it('parses') {
+        assert { Rouge::CLI::Highlight === subject }
+        assert { Rouge::Lexers::Ruby === subject.lexer }
+      }
+    end
+
+    describe 'guessing a lexer by mimetype' do
+      let(:argv) { %w(highlight -m application/javascript) }
+      it('parses') {
+        assert { Rouge::Lexers::Javascript === subject.lexer }
+      }
+    end
+
+    describe 'guessing a lexer by file contents' do
+      let(:argv) { %w(highlight -i bin/rougify) }
+      it('parses') {
+        assert { Rouge::Lexers::Ruby === subject.lexer }
+      }
+    end
+  end
+
+  describe Rouge::CLI::List do
+    describe 'list' do
+      let(:argv) { %w(list) }
+      it('parses') { assert { Rouge::CLI::List === subject } }
+
+      it 'lists available lexers' do
+        out, err = capture_io { subject.run }
+
+        expected_tags = Rouge::Lexer.all.map(&:tag).sort
+        actual_tags = out.scan(/^(.*?):/).flatten
+
+        assert_equal expected_tags, actual_tags, "err: #{err.inspect}"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/formatters/html_spec.rb b/app/server/vendor/rouge/spec/formatters/html_spec.rb
new file mode 100755
index 0000000..3187672
--- /dev/null
+++ b/app/server/vendor/rouge/spec/formatters/html_spec.rb
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Formatters::HTML do
+  let(:subject) { Rouge::Formatters::HTML.new(options) }
+  let(:options) { {} }
+  Token = Rouge::Token
+
+  it 'formats a simple token stream' do
+    out = subject.format([[Token['Name'], 'foo']])
+    assert { out == %(<pre><code class="highlight"><span class="n">foo</span></code></pre>\n) }
+  end
+
+  describe 'skipping the wrapper' do
+    let(:options) { { :wrap => false } }
+    let(:output) { subject.format([[Token['Name'], 'foo']]) }
+
+    it 'skips the wrapper' do
+      assert { output == '<span class="n">foo</span>' }
+    end
+  end
+
+  describe '#inline_theme' do
+    class InlineTheme < Rouge::CSSTheme
+      style Name, :bold => true
+    end
+
+    let(:options) { { :inline_theme => InlineTheme.new, :wrap => false } }
+
+    let(:output) {
+      subject.format([[Token['Name'], 'foo']])
+    }
+
+    it 'inlines styles given a theme' do
+      assert { output == '<span style="font-weight: bold">foo</span>' }
+    end
+  end
+
+  describe 'tableized line numbers' do
+    let(:options) { { :line_numbers => true } }
+
+    let(:text) { Rouge::Lexers::Clojure.demo }
+    let(:tokens) { Rouge::Lexers::Clojure.lex(text) }
+
+    let(:output) { subject.format(tokens) }
+    let(:line_numbers) { output[%r[<pre class="lineno".*?</pre>]m].scan(/\d+/m).size }
+
+    let(:output_code) {
+      output =~ %r(<td class="code">(.*?)</td>)m
+      $1
+    }
+
+    let(:code_lines) { output_code.scan(/\n/).size }
+
+    it 'preserves the number of lines' do
+      assert { code_lines == line_numbers }
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/formatters/null_spec.rb b/app/server/vendor/rouge/spec/formatters/null_spec.rb
new file mode 100755
index 0000000..46d0585
--- /dev/null
+++ b/app/server/vendor/rouge/spec/formatters/null_spec.rb
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Formatters::Null do
+  let(:subject) { Rouge::Formatters::Null.new }
+
+  it 'renders nothing' do
+    result = subject.format([[Token['Text'], 'foo']])
+
+    assert { result == '' }
+  end
+
+  it 'consumes tokens' do
+    consumed = false
+    tokens = Enumerator.new { consumed = true }
+
+    subject.format(tokens)
+
+    assert consumed
+  end
+end
diff --git a/app/server/vendor/rouge/spec/formatters/terminal256_spec.rb b/app/server/vendor/rouge/spec/formatters/terminal256_spec.rb
new file mode 100755
index 0000000..58da022
--- /dev/null
+++ b/app/server/vendor/rouge/spec/formatters/terminal256_spec.rb
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Formatters::Terminal256 do
+  let(:subject) { Rouge::Formatters::Terminal256.new }
+
+  it 'renders a thing' do
+    result = subject.format([[Token['Text'], 'foo']])
+
+    assert { result == "\e[38;5;230mfoo\e[39m" }
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexer_spec.rb b/app/server/vendor/rouge/spec/lexer_spec.rb
new file mode 100755
index 0000000..916e372
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexer_spec.rb
@@ -0,0 +1,148 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexer do
+  include Support::Lexing
+
+  it 'makes a simple lexer' do
+    a_lexer = Class.new(Rouge::RegexLexer) do
+      state :root do
+        rule /a/, 'A'
+        rule /b/, 'B'
+      end
+    end
+
+    # consolidation
+    result = a_lexer.lex('aa').to_a
+    assert { result.size == 1 }
+    assert { result == [['A', 'aa']] }
+
+    result = a_lexer.lex('abab').to_a
+    assert { result.size == 4 }
+    assert { result == [['A', 'a'], ['B', 'b']] * 2 }
+  end
+
+  it 'pushes and pops states' do
+    a_lexer = Class.new(Rouge::RegexLexer) do
+      state :brace do
+        rule /b/, 'B'
+        rule /}/, 'Brace', :pop!
+      end
+
+      state :root do
+        rule /{/, 'Brace', :brace
+        rule /a/, 'A'
+      end
+    end
+
+    result = a_lexer.lex('a{b}a').to_a
+    assert { result.size == 5 }
+
+    # failed parses
+
+    t = Rouge::Token
+    assert {
+      a_lexer.lex('{a}').to_a ==
+        [['Brace', '{'], [t['Error'], 'a'], ['Brace', '}']]
+    }
+
+    assert { a_lexer.lex('b').to_a == [[t['Error'], 'b']] }
+    assert { a_lexer.lex('}').to_a == [[t['Error'], '}']] }
+  end
+
+  it 'does callbacks and grouping' do
+    callback_lexer = Class.new(Rouge::RegexLexer) do
+      state :root do
+        rule /(a)(b)/ do |s|
+          groups('A', 'B')
+        end
+      end
+    end
+
+    result = callback_lexer.lex('ab').to_a
+
+    assert { result.size == 2 }
+    assert { result[0] == ['A', 'a'] }
+    assert { result[1] == ['B', 'b'] }
+  end
+
+  it 'pops from the callback' do
+    callback_lexer = Class.new(Rouge::RegexLexer) do
+      state :root do
+        rule /a/, 'A', :a
+        rule /d/, 'D'
+      end
+
+      state :a do
+        rule /b/, 'B', :b
+      end
+
+      state :b do
+        rule /c/ do |ss|
+          token 'C'
+          pop!; pop! # go back to the root
+        end
+      end
+    end
+
+    assert_no_errors 'abcd', callback_lexer
+  end
+
+  it 'supports stateful lexes' do
+    stateful = Class.new(Rouge::RegexLexer) do
+      def incr
+        @count += 1
+      end
+
+      state :root do
+        rule /\d+/ do |ss|
+          token 'digit'
+          @count = ss[0].to_i
+        end
+
+        rule /\+/ do |ss|
+          incr
+          token(@count <= 5 ? 'lt' : 'gt')
+        end
+      end
+    end
+
+    result = stateful.lex('4++')
+    types = result.map { |(t,_)| t }
+    assert { types == %w(digit lt gt) }
+  end
+
+  it 'delegates' do
+    class MasterLexer < Rouge::RegexLexer
+      state :root do
+        rule /a/, 'A'
+        rule /{(.*?)}/ do |m|
+          token 'brace', '{'
+          delegate BracesLexer.new, m[1]
+          token 'brace', '}'
+        end
+      end
+    end
+
+    class BracesLexer < Rouge::RegexLexer
+      state :root do
+        rule /b/, 'B'
+      end
+    end
+
+    assert_no_errors 'a{b}a', MasterLexer
+  end
+
+  it 'detects the beginnings of lines with ^ rules' do
+    class MyLexer < Rouge::RegexLexer
+      state :root do
+        rule /^a/, 'start'
+        rule /a/, 'not-start'
+      end
+    end
+
+    assert_has_token('start', 'a', MyLexer)
+    assert_has_token('start', "\na", MyLexer)
+    deny_has_token('not-start', 'a', MyLexer)
+    assert_has_token('not-start', 'aa', MyLexer)
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/apple_script_spec.rb b/app/server/vendor/rouge/spec/lexers/apple_script_spec.rb
new file mode 100755
index 0000000..9cb0747
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/apple_script_spec.rb
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::AppleScript do
+  let(:subject) { Rouge::Lexers::AppleScript.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.applescript'
+      assert_guess :filename => 'foo.scpt'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'application/x-applescript'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/c_spec.rb b/app/server/vendor/rouge/spec/lexers/c_spec.rb
new file mode 100755
index 0000000..50047e7
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/c_spec.rb
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::C do
+  let(:subject) { Rouge::Lexers::C.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.c'
+      assert_guess :filename => 'foo.h', :source => 'foo'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-csrc'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/clojure_spec.rb b/app/server/vendor/rouge/spec/lexers/clojure_spec.rb
new file mode 100755
index 0000000..3ce690c
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/clojure_spec.rb
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Clojure do
+  let(:subject) { Rouge::Lexers::Clojure.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.clj'
+      assert_guess :filename => 'foo.cljs'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-clojure'
+      assert_guess :mimetype => 'application/x-clojure'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/coffeescript_spec.rb b/app/server/vendor/rouge/spec/lexers/coffeescript_spec.rb
new file mode 100755
index 0000000..a28997e
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/coffeescript_spec.rb
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Coffeescript do
+  let(:subject) { Rouge::Lexers::Coffeescript.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.coffee'
+      assert_guess :filename => 'Cakefile'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/coffeescript'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/bin/env coffee'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/common_lisp_spec.rb b/app/server/vendor/rouge/spec/lexers/common_lisp_spec.rb
new file mode 100755
index 0000000..ab83921
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/common_lisp_spec.rb
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::CommonLisp do
+  let(:subject) { Rouge::Lexers::CommonLisp.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.cl'
+      assert_guess :filename => 'foo.lisp'
+      assert_guess :filename => 'foo.el'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-common-lisp'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/conf_spec.rb b/app/server/vendor/rouge/spec/lexers/conf_spec.rb
new file mode 100755
index 0000000..0363da2
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/conf_spec.rb
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Conf do
+  let(:subject) { Rouge::Lexers::Conf.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess   :filename => 'foo.conf'
+
+      # this should be lexed with the special nginx lexer
+      # instead.
+      deny_guess :filename => 'nginx.conf'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/cpp_spec.rb b/app/server/vendor/rouge/spec/lexers/cpp_spec.rb
new file mode 100755
index 0000000..b899944
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/cpp_spec.rb
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Cpp do
+  let(:subject) { Rouge::Lexers::Cpp.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.cpp'
+      assert_guess :filename => 'foo.c++'
+      assert_guess :filename => 'foo.cc'
+      assert_guess :filename => 'foo.cxx'
+
+      assert_guess :filename => 'foo.hpp'
+      assert_guess :filename => 'foo.h++'
+      assert_guess :filename => 'foo.hh'
+      assert_guess :filename => 'foo.hxx'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-c++hdr'
+      assert_guess :mimetype => 'text/x-c++src'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/csharp_spec.rb b/app/server/vendor/rouge/spec/lexers/csharp_spec.rb
new file mode 100755
index 0000000..d228704
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/csharp_spec.rb
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::CSharp do
+  let(:subject) { Rouge::Lexers::CSharp.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.cs'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-csharp'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/css_spec.rb b/app/server/vendor/rouge/spec/lexers/css_spec.rb
new file mode 100755
index 0000000..1fef32f
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/css_spec.rb
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::CSS do
+  let(:subject) { Rouge::Lexers::CSS.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.css'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/css'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/diff_spec.rb b/app/server/vendor/rouge/spec/lexers/diff_spec.rb
new file mode 100755
index 0000000..836e510
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/diff_spec.rb
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Diff do
+  let(:subject) { Rouge::Lexers::Diff.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.diff'
+      assert_guess :filename => 'foo.patch'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-diff'
+      assert_guess :mimetype => 'text/x-patch'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => <<-source
+diff --git a/lib/rouge.rb b/lib/rouge.rb
+index d228e4b..560b687 100644
+--- a/lib/rouge.rb
++++ b/lib/rouge.rb
+@@ -13,6 +13,7 @@ module Rouge
+ end
+ 
+ load_dir = Pathname.new(__FILE__).dirname
++load load_dir.join('rouge/text_analyzer.rb')
+ load load_dir.join('rouge/token.rb')
+ load load_dir.join('rouge/lexer.rb')
+ load load_dir.join('rouge/lexers/text.rb')
+      source
+
+      assert_guess :source => <<-source
+--- a/lib/rouge.rb
++++ b/lib/rouge.rb
+@@ -13,6 +13,7 @@ module Rouge
+ end
+ 
+ load_dir = Pathname.new(__FILE__).dirname
++load load_dir.join('rouge/text_analyzer.rb')
+ load load_dir.join('rouge/token.rb')
+ load load_dir.join('rouge/lexer.rb')
+ load load_dir.join('rouge/lexers/text.rb')
+      source
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/elixir_spec.rb b/app/server/vendor/rouge/spec/lexers/elixir_spec.rb
new file mode 100755
index 0000000..58badfb
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/elixir_spec.rb
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Elixir do
+  let(:subject) { Rouge::Lexers::Elixir.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.ex'
+      assert_guess :filename => 'foo.exs'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-elixir'
+      assert_guess :mimetype => 'application/x-elixir'
+    end
+  end
+
+  describe 'lexing' do
+    include Support::Lexing
+
+    it 'lexes double colon as punctuation' do
+      assert_tokens_equal 'Elixir::Builtin',
+        ['Name.Constant', 'Elixir'],
+        ['Punctuation',   '::'],
+        ['Name.Constant', 'Builtin']
+    end
+
+    it 'lexes keywords without following whitespaces' do
+      assert_tokens_equal %{cond do\nend},
+        ['Keyword', 'cond'],
+        ['Text',    ' '],
+        ['Keyword', 'do'],
+        ['Text',    "\n"],
+        ['Keyword', 'end']
+    end
+
+    it 'lexes bitwise operators' do
+      assert_tokens_equal %{~~~1\n2&&&3},
+        ['Operator', '~~~'],
+        ['Literal.Number', '1'],
+        ['Text', "\n"],
+        ['Literal.Number', '2'],
+        ['Operator', '&&&'],
+        ['Literal.Number', '3']
+    end
+
+    it 'lexes structs' do
+      assert_tokens_equal %{%Struct{}},
+        ['Punctuation', '%'],
+        ['Name.Constant', 'Struct'],
+        ['Punctuation', '{}']
+    end
+
+    it 'lexes map' do
+      assert_tokens_equal %{%{key: 1}},
+        ['Punctuation', '%{'],
+        ['Literal.String.Symbol', 'key:'],
+        ['Text', ' '],
+        ['Literal.Number', '1'],
+        ['Punctuation', '}']
+    end
+
+    it 'lexes regexp sigils' do
+      assert_tokens_equal %{~r//},
+        ['Literal.String.Regex', '~r//']
+    end
+
+    it 'lexes & operator' do
+      assert_tokens_equal %{&(&1)},
+        ['Operator', '&'],
+        ['Punctuation', '('],
+        ['Name.Variable', '&1'],
+        ['Punctuation', ')']
+
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/erb_spec.rb b/app/server/vendor/rouge/spec/lexers/erb_spec.rb
new file mode 100755
index 0000000..c20dc91
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/erb_spec.rb
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::ERB do
+  let(:subject) { Rouge::Lexers::ERB.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.html.erb'
+      assert_guess :filename => 'foo.eruby'
+      assert_guess :filename => 'foo.rhtml'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/erlang_spec.rb b/app/server/vendor/rouge/spec/lexers/erlang_spec.rb
new file mode 100755
index 0000000..713e32e
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/erlang_spec.rb
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Erlang do
+  let(:subject) { Rouge::Lexers::Erlang.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.erl'
+      assert_guess :filename => 'foo.hrl'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-erlang'
+      assert_guess :mimetype => 'application/x-erlang'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/factor_spec.rb b/app/server/vendor/rouge/spec/lexers/factor_spec.rb
new file mode 100755
index 0000000..81b5e47
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/factor_spec.rb
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Factor do
+  let(:subject) { Rouge::Lexers::Factor.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.factor'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-factor'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/local/bin/factor'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/gherkin_spec.rb b/app/server/vendor/rouge/spec/lexers/gherkin_spec.rb
new file mode 100755
index 0000000..4aaf065
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/gherkin_spec.rb
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Gherkin do
+  let(:subject) { Rouge::Lexers::Gherkin.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.feature'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-gherkin'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/bin/env cucumber'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/go_spec.rb b/app/server/vendor/rouge/spec/lexers/go_spec.rb
new file mode 100755
index 0000000..52f45b6
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/go_spec.rb
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Go do
+  let(:subject) { Rouge::Lexers::Go.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.go'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-go'
+      assert_guess :mimetype => 'application/x-go'
+    end
+  end
+end
+
diff --git a/app/server/vendor/rouge/spec/lexers/groovy_spec.rb b/app/server/vendor/rouge/spec/lexers/groovy_spec.rb
new file mode 100755
index 0000000..6f9d155
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/groovy_spec.rb
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Groovy do
+  let(:subject) { Rouge::Lexers::Groovy.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.groovy'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-groovy'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/haml_spec.rb b/app/server/vendor/rouge/spec/lexers/haml_spec.rb
new file mode 100755
index 0000000..1e8ee53
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/haml_spec.rb
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Haml do
+  let(:subject) { Rouge::Lexers::Haml.new }
+  include Support::Lexing
+
+  it 'lexes custom filters' do
+    lexer = Rouge::Lexers::Haml.new(:filters => { :tex => 'tex' })
+
+    assert_has_token 'Comment', <<-tex, lexer
+      :tex
+        % this is a tex comment!
+    tex
+  end
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.html.haml'
+      assert_guess :filename => 'foo.haml'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-haml'
+    end
+  end
+
+end
diff --git a/app/server/vendor/rouge/spec/lexers/handlebars_spec.rb b/app/server/vendor/rouge/spec/lexers/handlebars_spec.rb
new file mode 100755
index 0000000..9b3d09d
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/handlebars_spec.rb
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Handlebars do
+  let(:subject) { Rouge::Lexers::Handlebars.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.handlebars'
+      assert_guess :filename => 'foo.hbs'
+      assert_guess :filename => 'foo.mustache'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-handlebars'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/haskell_spec.rb b/app/server/vendor/rouge/spec/lexers/haskell_spec.rb
new file mode 100755
index 0000000..9514b06
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/haskell_spec.rb
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Haskell do
+  let(:subject) { Rouge::Lexers::Haskell.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.hs'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-haskell'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/bin/env runhaskell'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/html_spec.rb b/app/server/vendor/rouge/spec/lexers/html_spec.rb
new file mode 100755
index 0000000..12f8c51
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/html_spec.rb
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::HTML do
+  let(:subject) { Rouge::Lexers::HTML.new }
+  include Support::Lexing
+
+  it 'lexes embedded script tags' do
+    assert_no_errors '<script>x && x < y;</script>'
+  end
+
+  describe 'lexing' do
+    include Support::Lexing
+
+    describe 'element names' do
+      it 'allow dashes to support custom elements' do
+        assert_tokens_equal '<custom-element></custom-element>',
+                            ['Name.Tag', '<custom-element></custom-element>']
+      end
+    end
+  end
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.html'
+      assert_guess :filename => 'foo.htm'
+      assert_guess :filename => 'foo.xhtml'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/html'
+      assert_guess :mimetype => 'application/xhtml+xml'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '<!DOCTYPE html>'
+      assert_guess :source => <<-source
+        <?xml version="1.0" encoding="UTF-8"?>
+        <!DOCTYPE html
+            PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+        <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+        </html>
+      source
+
+      assert_guess :source => <<-source
+        <!DOCTYPE html PUBLIC
+          "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+        <html lang="ar" dir="rtl" xmlns="http://www.w3.org/1999/xhtml">
+        </html>
+      source
+
+      assert_guess :source => '<html></html>'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/ini_spec.rb b/app/server/vendor/rouge/spec/lexers/ini_spec.rb
new file mode 100755
index 0000000..d3415d8
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/ini_spec.rb
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::INI do
+  let(:subject) { Rouge::Lexers::INI.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.ini'
+      assert_guess :filename => '.gitconfig'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-ini'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/io_spec.rb b/app/server/vendor/rouge/spec/lexers/io_spec.rb
new file mode 100755
index 0000000..01be439
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/io_spec.rb
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::IO do
+  let(:subject) { Rouge::Lexers::IO.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.io'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-iosrc'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/local/bin/io'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/java_spec.rb b/app/server/vendor/rouge/spec/lexers/java_spec.rb
new file mode 100755
index 0000000..64af5d4
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/java_spec.rb
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Java do
+  let(:subject) { Rouge::Lexers::Java.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.java'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-java'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/javascript_spec.rb b/app/server/vendor/rouge/spec/lexers/javascript_spec.rb
new file mode 100755
index 0000000..66dd10f
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/javascript_spec.rb
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Javascript do
+  let(:subject) { Rouge::Lexers::Javascript.new }
+
+  describe 'lexing' do
+    include Support::Lexing
+
+    it %(doesn't let a bad regex mess up the whole lex) do
+      assert_has_token 'Error',          "var a = /foo;\n1"
+      assert_has_token 'Literal.Number', "var a = /foo;\n1"
+    end
+  end
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.js'
+      assert_guess Rouge::Lexers::JSON, :filename => 'foo.json'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/javascript'
+      assert_guess Rouge::Lexers::JSON, :mimetype => 'application/json'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/bin/env node'
+      assert_guess :source => '#!/usr/local/bin/jsc'
+      assert_guess Rouge::Lexers::JSON, :source => '{ "foo": "bar" }'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/literate_coffeescript_spec.rb b/app/server/vendor/rouge/spec/lexers/literate_coffeescript_spec.rb
new file mode 100755
index 0000000..d6ca386
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/literate_coffeescript_spec.rb
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::LiterateCoffeescript do
+  let(:subject) { Rouge::Lexers::LiterateCoffeescript.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.litcoffee'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/literate_haskell_spec.rb b/app/server/vendor/rouge/spec/lexers/literate_haskell_spec.rb
new file mode 100755
index 0000000..a91a35f
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/literate_haskell_spec.rb
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::LiterateHaskell do
+  let(:subject) { Rouge::Lexers::LiterateHaskell.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.lhs'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-literate-haskell'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/llvm_spec.rb b/app/server/vendor/rouge/spec/lexers/llvm_spec.rb
new file mode 100755
index 0000000..d359d49
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/llvm_spec.rb
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::LLVM do
+  let(:subject) { Rouge::Lexers::LLVM.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.ll'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-llvm'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/lua_spec.rb b/app/server/vendor/rouge/spec/lexers/lua_spec.rb
new file mode 100755
index 0000000..ac84f37
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/lua_spec.rb
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Lua do
+  let(:subject) { Rouge::Lexers::Lua.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.lua'
+      assert_guess :filename => 'foo.wlua'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-lua'
+      assert_guess :mimetype => 'application/x-lua'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/local/bin/lua'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/make_spec.rb b/app/server/vendor/rouge/spec/lexers/make_spec.rb
new file mode 100755
index 0000000..c71be17
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/make_spec.rb
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Make do
+  let(:subject) { Rouge::Lexers::Make.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.make'
+      assert_guess :filename => 'Makefile'
+      assert_guess :filename => 'makefile'
+      assert_guess :filename => 'Makefile.in'
+      assert_guess :filename => 'GNUmakefile'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-makefile'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '.PHONY: all'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/markdown_spec.rb b/app/server/vendor/rouge/spec/lexers/markdown_spec.rb
new file mode 100755
index 0000000..dc7c41a
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/markdown_spec.rb
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Markdown do
+  let(:subject) { Rouge::Lexers::Markdown.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.md'
+      assert_guess :filename => 'foo.mkd'
+      assert_guess :filename => 'foo.markdown'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-markdown'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/matlab_spec.rb b/app/server/vendor/rouge/spec/lexers/matlab_spec.rb
new file mode 100755
index 0000000..c116213
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/matlab_spec.rb
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Matlab do
+  let(:subject) { Rouge::Lexers::Matlab.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.m', :source => '% comment'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-matlab'
+      assert_guess :mimetype => 'application/x-matlab'
+    end
+  end
+end
+
diff --git a/app/server/vendor/rouge/spec/lexers/moonscript_spec.rb b/app/server/vendor/rouge/spec/lexers/moonscript_spec.rb
new file mode 100755
index 0000000..131ba80
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/moonscript_spec.rb
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Moonscript do
+  let(:subject) { Rouge::Lexers::Moonscript.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.moon'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-moonscript'
+      assert_guess :mimetype => 'application/x-moonscript'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/local/bin/moon'
+      assert_guess :source => '#! /usr/bin/env moon'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/nginx_spec.rb b/app/server/vendor/rouge/spec/lexers/nginx_spec.rb
new file mode 100755
index 0000000..937e02e
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/nginx_spec.rb
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Nginx do
+  let(:subject) { Rouge::Lexers::Nginx.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'nginx.conf'
+      deny_guess   :filename => 'foo.conf'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-nginx-conf'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/objective_c_spec.rb b/app/server/vendor/rouge/spec/lexers/objective_c_spec.rb
new file mode 100755
index 0000000..db496cc
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/objective_c_spec.rb
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::ObjectiveC do
+  let(:subject) { Rouge::Lexers::ObjectiveC.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.m', :source => '@property'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-objective_c'
+      assert_guess :mimetype => 'application/x-objective_c'
+    end
+
+    it 'guesses by source' do
+      assert_guess :filename => 'foo.h', :source => '[foo bar: baz]'
+      assert_guess :filename => 'foo.h', :source => '@"foo"'
+      assert_guess :source => '@implementation Foo'
+    end
+  end
+end
+
diff --git a/app/server/vendor/rouge/spec/lexers/ocaml_spec.rb b/app/server/vendor/rouge/spec/lexers/ocaml_spec.rb
new file mode 100755
index 0000000..7a8ce3f
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/ocaml_spec.rb
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::OCaml do
+  let(:subject) { Rouge::Lexers::OCaml.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.ml'
+      assert_guess :filename => 'foo.mli'
+      assert_guess :filename => 'foo.mll'
+      assert_guess :filename => 'foo.mly'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-ocaml'
+    end
+  end
+end
+
diff --git a/app/server/vendor/rouge/spec/lexers/perl_spec.rb b/app/server/vendor/rouge/spec/lexers/perl_spec.rb
new file mode 100755
index 0000000..71742da
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/perl_spec.rb
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Perl do
+  let(:subject) { Rouge::Lexers::Perl.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      # *.pl needs source hints because it's also used by Prolog
+      assert_guess :filename => 'foo.pl', :source => 'my $foo = 1'
+      assert_guess :filename => 'foo.pm'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-perl'
+      assert_guess :mimetype => 'application/x-perl'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/local/bin/perl'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/plain_text_spec.rb b/app/server/vendor/rouge/spec/lexers/plain_text_spec.rb
new file mode 100755
index 0000000..c26dc48
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/plain_text_spec.rb
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::PlainText do
+  let(:subject) { Rouge::Lexers::PlainText.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo'
+      assert_guess :filename => 'foo.txt'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/plain'
+      assert_guess :mimetype => 'text/x-something-else'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => 'zorbl'
+      assert_guess :source => '-:-:-:-:-'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/prolog_spec.rb b/app/server/vendor/rouge/spec/lexers/prolog_spec.rb
new file mode 100755
index 0000000..ebb0501
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/prolog_spec.rb
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Prolog do
+  let(:subject) { Rouge::Lexers::Prolog.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.pro'
+      assert_guess :filename => 'foo.P'
+      assert_guess :filename => 'foo.prolog'
+      assert_guess :filename => 'foo.pl', :source => ':-'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-prolog'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/properties_spec.rb b/app/server/vendor/rouge/spec/lexers/properties_spec.rb
new file mode 100755
index 0000000..ebb64a0
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/properties_spec.rb
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Properties do
+  let(:subject) { Rouge::Lexers::Properties.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.properties'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-java-properties'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/puppet_spec.rb b/app/server/vendor/rouge/spec/lexers/puppet_spec.rb
new file mode 100755
index 0000000..a36474a
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/puppet_spec.rb
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Puppet do
+  let(:subject) { Rouge::Lexers::Puppet.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.pp'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/local/bin/puppet apply'
+      assert_guess :source => '#!/usr/bin/puppet-apply'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/python_spec.rb b/app/server/vendor/rouge/spec/lexers/python_spec.rb
new file mode 100755
index 0000000..b3c2296
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/python_spec.rb
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Python do
+  let(:subject) { Rouge::Lexers::Python.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.py'
+      assert_guess :filename => 'foo.pyw'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-python'
+      assert_guess :mimetype => 'application/x-python'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/bin/env python'
+      assert_guess :source => '#!/usr/local/bin/python3'
+      assert_guess :source => '#!/usr/bin/python2'
+      assert_guess :source => '#!/usr/bin/python2.7'
+      deny_guess   :source => '#!/usr/bin/env python4'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/qml_spec.rb b/app/server/vendor/rouge/spec/lexers/qml_spec.rb
new file mode 100755
index 0000000..1e7ed0c
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/qml_spec.rb
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Qml do
+  let(:subject) { Rouge::Lexers::Qml.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.qml'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'application/x-qml'
+      assert_guess :mimetype => 'text/x-qml'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/r_spec.rb b/app/server/vendor/rouge/spec/lexers/r_spec.rb
new file mode 100755
index 0000000..f7c6666
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/r_spec.rb
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::R do
+  let(:subject) { Rouge::Lexers::R.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.R'
+      assert_guess :filename => 'foo.S'
+      assert_guess :filename => '.Rhistory'
+      assert_guess :filename => '.Rprofile'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-r'
+      assert_guess :mimetype => 'application/x-r'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/bin/Rscript'
+    end
+  end
+end
+
diff --git a/app/server/vendor/rouge/spec/lexers/racket_spec.rb b/app/server/vendor/rouge/spec/lexers/racket_spec.rb
new file mode 100755
index 0000000..a900417
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/racket_spec.rb
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Racket do
+  let(:subject) { Rouge::Lexers::Racket.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.rkt'
+      assert_guess :filename => 'foo.rktd'
+      assert_guess :filename => 'foo.rktl'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-racket'
+      assert_guess :mimetype => 'application/x-racket'
+    end
+
+    it 'guesses by text' do
+      assert_guess :source => "#lang racket\n(define x 2)"
+      assert_guess :source => '#lang scribble'
+      assert_guess :source => '#lang typed/racket'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/ruby_spec.rb b/app/server/vendor/rouge/spec/lexers/ruby_spec.rb
new file mode 100755
index 0000000..707eb58
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/ruby_spec.rb
@@ -0,0 +1,84 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Ruby do
+  let(:subject) { Rouge::Lexers::Ruby.new }
+
+  describe 'lexing' do
+    include Support::Lexing
+
+    describe 'method calling' do
+      describe 'leading dot' do
+        it 'handles whitespace between the receiver and the method' do
+          assert_tokens_equal "foo\n  .bar()",
+            ['Name', 'foo'],
+            ['Text', "\n  "],
+            ['Punctuation', '.'],
+            ['Name.Function', 'bar'],
+            ['Punctuation', '()']
+        end
+
+        it 'handles whitespace between the receiver and multiple chained methods' do
+          assert_tokens_equal "foo\n  .bar()\n  .baz",
+            ['Name', 'foo'],
+            ['Text', "\n  "],
+            ['Punctuation', '.'],
+            ['Name.Function', 'bar'],
+            ['Punctuation', '()'],
+            ['Text', "\n  "],
+            ['Punctuation', '.'],
+            ['Name.Function', 'baz']
+        end
+      end
+
+      describe 'trailing dot' do
+        it 'handles whitespace between the receiver and the method' do
+          assert_tokens_equal "foo.\n  bar()",
+            ['Name', 'foo'],
+            ['Punctuation', '.'],
+            ['Text', "\n  "],
+            ['Name.Function', 'bar'],
+            ['Punctuation', '()']
+        end
+
+        it 'handles whitespace between the receiver and multiple chained methods' do
+          assert_tokens_equal "foo.\n  bar().\n  baz",
+            ['Name', 'foo'],
+            ['Punctuation', '.'],
+            ['Text', "\n  "],
+            ['Name.Function', 'bar'],
+            ['Punctuation', '().'],
+            ['Text', "\n  "],
+            ['Name.Function', 'baz']
+        end
+      end
+    end
+  end
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.rb'
+      assert_guess :filename => 'foo.ruby'
+      assert_guess :filename => 'foo.rbw'
+      assert_guess :filename => 'foo.gemspec'
+      assert_guess :filename => 'Rakefile'
+      assert_guess :filename => 'Guardfile'
+      assert_guess :filename => 'Gemfile'
+      assert_guess :filename => 'foo.rake'
+      assert_guess :filename => 'Capfile'
+      assert_guess :filename => 'Vagrantfile'
+      assert_guess :filename => 'config.ru'
+      assert_guess :filename => 'foo.pdf.prawn'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-ruby'
+      assert_guess :mimetype => 'application/x-ruby'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/local/bin/ruby'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/rust_spec.rb b/app/server/vendor/rouge/spec/lexers/rust_spec.rb
new file mode 100755
index 0000000..b4b7da7
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/rust_spec.rb
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Rust do
+  let(:subject) { Rouge::Lexers::Rust.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.rs'
+      assert_guess :filename => 'foo.rc'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-rust'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/bin/env rustc --jit'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/scala_spec.rb b/app/server/vendor/rouge/spec/lexers/scala_spec.rb
new file mode 100755
index 0000000..da3f05b
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/scala_spec.rb
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Scala do
+  let(:subject) { Rouge::Lexers::Scala.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.scala'
+      assert_guess :filename => 'foo.sbt'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-scala'
+      assert_guess :mimetype => 'application/x-scala'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/scheme_spec.rb b/app/server/vendor/rouge/spec/lexers/scheme_spec.rb
new file mode 100755
index 0000000..be72031
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/scheme_spec.rb
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Scheme do
+  let(:subject) { Rouge::Lexers::Scheme.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.scm'
+      assert_guess :filename => 'foo.ss'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-scheme'
+      assert_guess :mimetype => 'application/x-scheme'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/sed_spec.rb b/app/server/vendor/rouge/spec/lexers/sed_spec.rb
new file mode 100755
index 0000000..1e30932
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/sed_spec.rb
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Sed do
+  let(:subject) { Rouge::Lexers::Sed.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.sed'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-sed'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/bin/sed'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/shell_spec.rb b/app/server/vendor/rouge/spec/lexers/shell_spec.rb
new file mode 100755
index 0000000..6cd1eeb
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/shell_spec.rb
@@ -0,0 +1,103 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Shell do
+  let(:subject) { Rouge::Lexers::Shell.new }
+
+  include Support::Lexing
+  it 'parses a basic shell string' do
+    tokens = subject.lex('foo=bar').to_a
+    assert { tokens.size == 3 }
+    assert { tokens.first[0] == Token['Name.Variable'] }
+  end
+
+  it 'parses case statements correctly' do
+    assert_no_errors <<-sh
+      case $foo in
+        a) echo "LOL" ;;
+      esac
+    sh
+  end
+
+  it 'parses case statement with globs correctly' do
+    assert_no_errors <<-sh
+      case $foo in
+        a[b]) echo "LOL" ;;
+      esac
+    sh
+  end
+
+  it 'parses comments correctly' do
+    tokens = subject.lex('foo=bar # this is a comment').to_a
+    assert { tokens.size == 4 }
+    assert { tokens.last[0] == Token['Comment'] }
+  end
+
+  it 'parses a basic shell string with a prompt' do
+    # Single '$' prompt
+    tokens = subject.lex('$ foo=bar').to_a
+    assert { tokens.size == 4 }
+    assert { tokens.first[0] == Token['Generic.Prompt'] }
+    # Single '>' prompt
+    tokens = subject.lex('> foo=bar').to_a
+    assert { tokens.size == 4 }
+    assert { tokens.first[0] == Token['Generic.Prompt'] }
+    # Single '%' prompt
+    tokens = subject.lex('% foo=bar').to_a
+    assert { tokens.size == 4 }
+    assert { tokens.first[0] == Token['Generic.Prompt'] }
+    # Complex prompt with trailing '$'
+    tokens = subject.lex('me at host:~$ foo=bar').to_a
+    assert { tokens.size == 4 }
+    assert { tokens.first[0] == Token['Generic.Prompt'] }
+    # Complex prompt with trailing '>'
+    tokens = subject.lex('me at host:~> foo=bar').to_a
+    assert { tokens.size == 4 }
+    assert { tokens.first[0] == Token['Generic.Prompt'] }
+    # Complex prompt with trailing '%'
+    tokens = subject.lex('me at host:~% foo=bar').to_a
+    assert { tokens.size == 4 }
+    assert { tokens.first[0] == Token['Generic.Prompt'] }
+    # Complex prompt with trailing '#'
+    tokens = subject.lex('root at host:/root# foo=bar').to_a
+    assert { tokens.size == 4 }
+    assert { tokens.first[0] == Token['Generic.Prompt'] }
+  end
+
+  it 'does not confuse a prompt with a variable' do
+    tokens = subject.lex('$foo').to_a
+    assert { tokens.size == 1 }
+    assert { tokens.first[0] == Token['Name.Variable'] }
+  end
+
+  it 'does not confuse a prompt with a comment' do
+    tokens = subject.lex('# commentaire').to_a
+    assert { tokens.size == 1 }
+    assert { tokens.first[0] == Token['Comment'] }
+  end
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.sh'
+      assert_guess :filename => 'foo.zsh'
+      assert_guess :filename => 'foo.ksh'
+      assert_guess :filename => 'foo.bash'
+      deny_guess   :filename => 'foo'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'application/x-shellscript'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/bin/bash'
+      assert_guess :source => '   #!   /bin/bash'
+      assert_guess :source => '#!/usr/bin/env bash'
+      assert_guess :source => '#!/usr/bin/env bash -i'
+      deny_guess   :source => '#!/bin/smash'
+      # not sure why you would do this, but hey, whatevs
+      deny_guess   :source => '#!/bin/bash/python'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/slim_spec.rb b/app/server/vendor/rouge/spec/lexers/slim_spec.rb
new file mode 100755
index 0000000..716b243
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/slim_spec.rb
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Slim do
+  let(:subject) { Rouge::Lexers::Slim.new }
+  include Support::Lexing
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.slim'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => 'doctype html'
+
+      assert_guess :source => <<-source
+        html
+          body
+            p Some text
+            a *{ :href => "Somewhere" } Link to somewhere
+      source
+    end
+  end
+
+end
diff --git a/app/server/vendor/rouge/spec/lexers/smalltalk_spec.rb b/app/server/vendor/rouge/spec/lexers/smalltalk_spec.rb
new file mode 100755
index 0000000..10ac2da
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/smalltalk_spec.rb
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::Smalltalk do
+  let(:subject) { Rouge::Lexers::Smalltalk.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.st'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-smalltalk'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/sml_spec.rb b/app/server/vendor/rouge/spec/lexers/sml_spec.rb
new file mode 100755
index 0000000..0cfb51b
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/sml_spec.rb
@@ -0,0 +1,23 @@
+# # -*- coding: utf-8 -*- #
+
+# describe Rouge::Lexers::Sml do
+#   let(:subject) { Rouge::Lexers::Sml.new }
+# 
+#   describe 'guessing' do
+#     include Support::Guessing
+# 
+#     it 'guesses by filename' do
+#       assert_guess :filename => 'foo.???'
+#     end
+# 
+#     it 'guesses by mimetype' do
+#       assert_guess :mimetype => 'text/x-sml'
+#       assert_guess :mimetype => 'application/x-sml'
+#     end
+# 
+#     it 'guesses by source' do
+#       assert_guess :source => '????'
+#     end
+#   end
+# end
+# 
diff --git a/app/server/vendor/rouge/spec/lexers/sql_spec.rb b/app/server/vendor/rouge/spec/lexers/sql_spec.rb
new file mode 100755
index 0000000..73ab3b5
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/sql_spec.rb
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::SQL do
+  let(:subject) { Rouge::Lexers::SQL.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.sql'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-sql'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/tcl_spec.rb b/app/server/vendor/rouge/spec/lexers/tcl_spec.rb
new file mode 100755
index 0000000..f678770
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/tcl_spec.rb
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::TCL do
+  let(:subject) { Rouge::Lexers::TCL.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.tcl'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-tcl'
+      assert_guess :mimetype => 'application/x-tcl'
+      assert_guess :mimetype => 'text/x-script.tcl'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '#!/usr/bin/env tclsh'
+      assert_guess :source => '#!/usr/bin/jimsh'
+      assert_guess :source => '#!/usr/bin/wish'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/tex_spec.rb b/app/server/vendor/rouge/spec/lexers/tex_spec.rb
new file mode 100755
index 0000000..f7f94bb
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/tex_spec.rb
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::TeX do
+  let(:subject) { Rouge::Lexers::TeX.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.tex'
+      assert_guess :filename => 'foo.toc'
+      assert_guess :filename => 'foo.aux'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-tex'
+      assert_guess :mimetype => 'text/x-latex'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '\\documentclass{article}'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/toml_spec.rb b/app/server/vendor/rouge/spec/lexers/toml_spec.rb
new file mode 100755
index 0000000..d5cdc8c
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/toml_spec.rb
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::TOML do
+  let(:subject) { Rouge::Lexers::TOML.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.toml'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-toml'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/viml_spec.rb b/app/server/vendor/rouge/spec/lexers/viml_spec.rb
new file mode 100755
index 0000000..e167659
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/viml_spec.rb
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::VimL do
+  let(:subject) { Rouge::Lexers::VimL.new }
+
+  describe 'mapping binary search' do
+    let(:mapping) {
+      [['aa', 'aaa'],
+       ['bb', 'bb'],
+       ['cc', 'ccc']]
+    }
+
+    it 'finds a likely mapping' do
+      likely = subject.find_likely_mapping(mapping, 'aa')
+      assert { likely == ['aa', 'aaa'] }
+
+      likely = subject.find_likely_mapping(mapping, 'abc')
+      assert { likely == ['aa', 'aaa'] }
+
+      likely = subject.find_likely_mapping(mapping, 'bbbbb')
+      assert { likely == ['bb', 'bb'] }
+
+      likely = subject.find_likely_mapping(mapping, 'z')
+      assert { likely == ['cc', 'ccc'] }
+    end
+  end
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.vim'
+      assert_guess :filename => 'foo.vba'
+      assert_guess :filename => '~/.vimrc'
+      assert_guess :filename => '.exrc'
+      assert_guess :filename => '.gvimrc'
+      assert_guess :filename => '_vimrc'
+      assert_guess :filename => '_gvimrc'
+      assert_guess :filename => '_exrc'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-vim'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/xml_spec.rb b/app/server/vendor/rouge/spec/lexers/xml_spec.rb
new file mode 100755
index 0000000..2a11527
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/xml_spec.rb
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::XML do
+  let(:subject) { Rouge::Lexers::XML.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.xml'
+      assert_guess :filename => 'foo.xsl'
+      assert_guess :filename => 'foo.rss'
+      assert_guess :filename => 'foo.xslt'
+      assert_guess :filename => 'foo.xsd'
+      assert_guess :filename => 'foo.wsdl'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/xml'
+      assert_guess :mimetype => 'application/xml'
+      assert_guess :mimetype => 'image/svg+xml'
+      assert_guess :mimetype => 'application/rss+xml'
+      assert_guess :mimetype => 'application/atom+xml'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '<xml></xml>'
+      assert_guess :source => '<?xml version="1.0" encoding="utf-8"?>'
+      assert_guess :source => '<!DOCTYPE xml>'
+      deny_guess   :source => '<!DOCTYPE html>'
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers/yaml_spec.rb b/app/server/vendor/rouge/spec/lexers/yaml_spec.rb
new file mode 100755
index 0000000..7cec05e
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers/yaml_spec.rb
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::YAML do
+  let(:subject) { Rouge::Lexers::YAML.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.yml'
+      assert_guess :filename => 'foo.yaml'
+      assert_guess :filename => '.travis.yml'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-yaml'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => "\n\n%YAML 1.2"
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/lexers_spec.rb b/app/server/vendor/rouge/spec/lexers_spec.rb
new file mode 100755
index 0000000..f5c0b13
--- /dev/null
+++ b/app/server/vendor/rouge/spec/lexers_spec.rb
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers do
+  spec_dir = Pathname.new(__FILE__).dirname
+  samples_dir = spec_dir.join('visual/samples')
+
+  Rouge::Lexer.all.each do |lexer_class|
+    describe lexer_class do
+      include Support::Lexing
+
+      subject { lexer_class.new }
+
+      it 'lexes the demo with no errors' do
+        assert_no_errors(lexer_class.demo)
+      end
+
+      it 'lexes the sample without throwing' do
+        sample = File.read(samples_dir.join(lexer_class.tag), encoding: 'utf-8')
+        subject.lex(sample).to_a
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/plugins/redcarpet_spec.rb b/app/server/vendor/rouge/spec/plugins/redcarpet_spec.rb
new file mode 100755
index 0000000..63061e3
--- /dev/null
+++ b/app/server/vendor/rouge/spec/plugins/redcarpet_spec.rb
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*- #
+
+require 'rouge/plugins/redcarpet'
+describe Rouge::Plugins::Redcarpet do
+  # skip if redcarpet isn't loaded
+  next unless Object.const_defined? :Redcarpet
+
+  let(:redcarpet) {
+    Class.new(Redcarpet::Render::HTML) do
+      include Rouge::Plugins::Redcarpet
+    end
+  }
+
+  let(:markdown) {
+    Redcarpet::Markdown.new(redcarpet.new, :fenced_code_blocks => true)
+  }
+
+  it 'renders a thing' do
+    result = markdown.render <<-mkd
+``` javascript
+var foo = 1;
+```
+
+``` shell
+foo=1
+```
+    mkd
+
+    assert { result.include?(%<<code class="highlight shell">>) }
+    assert { result.include?(%<<code class="highlight javascript">>) }
+  end
+
+  it 'guesses' do
+    result = markdown.render <<-mkd
+``` guess
+<xml>an xml code block</xml>
+```
+    mkd
+
+    assert { result.include?(%<<code class="highlight xml">>) }
+  end
+
+  it 'passes options' do
+    result = markdown.render <<-mkd
+``` shell?k=v
+foo=1
+```
+    mkd
+
+    # TODO: test that an option is actually there
+    assert { result.include?(%<<code class="highlight shell">>) }
+  end
+
+  it 'works when no language is provided' do
+    result = markdown.render <<-mkd
+```
+#!/usr/bin/env ruby
+$stdin.each { |l| $stdout.puts l.reverse }
+```
+    mkd
+    assert { result.include?(%(<code class="highlight ruby">)) }
+  end
+end
diff --git a/app/server/vendor/rouge/spec/spec_helper.rb b/app/server/vendor/rouge/spec/spec_helper.rb
new file mode 100755
index 0000000..69f624f
--- /dev/null
+++ b/app/server/vendor/rouge/spec/spec_helper.rb
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*- #
+
+require 'rubygems'
+require 'bundler'
+Bundler.require
+
+require 'rouge'
+require 'minitest/spec'
+require 'wrong/adapters/minitest'
+
+Wrong.config[:color] = true
+
+Dir[File.expand_path('support/**/*.rb', File.dirname(__FILE__))].each {|f|
+  require f
+}
diff --git a/app/server/vendor/rouge/spec/support/guessing.rb b/app/server/vendor/rouge/spec/support/guessing.rb
new file mode 100755
index 0000000..58539a6
--- /dev/null
+++ b/app/server/vendor/rouge/spec/support/guessing.rb
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*- #
+
+module Support
+  module Guessing
+    def assert_guess(type=nil, info={})
+      if type.is_a? Hash
+        info = type
+        type = nil
+      end
+
+      type ||= subject.class
+
+      assert { Rouge::Lexer.guess(info) == type }
+    end
+
+    def deny_guess(type=nil, info={})
+      if type.is_a? Hash
+        info = type
+        type = nil
+      end
+
+      type ||= subject.class
+
+      deny { Rouge::Lexer.guess(info) == type }
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/support/lexing.rb b/app/server/vendor/rouge/spec/support/lexing.rb
new file mode 100755
index 0000000..3311d05
--- /dev/null
+++ b/app/server/vendor/rouge/spec/support/lexing.rb
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*- #
+
+module Support
+  module Lexing
+    def filter_by_token(target_token, text, lexer=nil)
+      lexer ||= subject
+
+      tokens = lexer.lex(text)
+
+      tokens.select do |(tok, _)|
+        same_token?(tok, target_token)
+      end
+    end
+
+    def same_token?(token, target)
+      if token.respond_to? :token_chain
+        token.token_chain.include?(Rouge::Token[target])
+      else
+        token == target
+      end
+    end
+
+    def deny_has_token(tokname, text, lexer=nil)
+      deny { filter_by_token(tokname, text, lexer).any? }
+    end
+
+    def assert_has_token(tokname, text, lexer=nil)
+      assert { filter_by_token(tokname, text, lexer).any? }
+    end
+
+    def assert_no_errors(*a)
+      deny_has_token('Error', *a)
+    end
+
+    def assert_tokens_equal(text, *expected)
+      if expected.first.is_a? Rouge::Lexer
+        lexer = expected.shift
+      else
+        lexer = subject
+      end
+
+      actual = lexer.lex(text).map { |token, value| [ token.qualname, value ] }
+      assert { expected == actual }
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/spec/theme_spec.rb b/app/server/vendor/rouge/spec/theme_spec.rb
new file mode 100755
index 0000000..34b9209
--- /dev/null
+++ b/app/server/vendor/rouge/spec/theme_spec.rb
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Theme do
+  def squish(str)
+    str.strip.gsub(/\s+/, ' ')
+  end
+
+  class MyTheme < Rouge::CSSTheme
+    style Literal::String, :bold => true
+    style Literal::String::Backtick, :italic => true
+  end
+
+  let(:theme) { MyTheme.new }
+
+  it 'auto-fills css classes' do
+    rendered = theme.render
+
+    # should also style, for example, String.Char
+    assert { rendered =~ /\.sc/ }
+
+    # and it should only style String.Backtick once
+    assert { rendered =~ /\.sb/ }
+    assert { $~.size == 1 }
+  end
+
+  it 'renders a style' do
+    output = Rouge::Theme::Style[:bold => true].render('.foo')
+    expected = <<-css
+      .foo {
+        font-weight: bold;
+      }
+    css
+
+    assert { squish(output) == squish(expected) }
+  end
+
+  it 'fetches a style for a token' do
+    bold = theme.style_for(Token['Literal.String'])
+    assert { bold == { :bold => true } }
+  end
+
+  it 'fetches a the closest style for a token' do
+    bold = theme.style_for(Token['Literal.String.Double'])
+    assert { bold == { :bold => true } }
+  end
+end
diff --git a/app/server/vendor/rouge/spec/token_spec.rb b/app/server/vendor/rouge/spec/token_spec.rb
new file mode 100755
index 0000000..7a4182f
--- /dev/null
+++ b/app/server/vendor/rouge/spec/token_spec.rb
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Token do
+  it 'has a name' do
+    assert { Rouge::Token['Text'].qualname == 'Text' }
+    assert { Rouge::Token['Literal.String'].qualname == 'Literal.String' }
+  end
+
+  it 'has shortnames' do
+    assert { Rouge::Token['Name'].shortname == 'n' }
+    assert { Rouge::Token['Literal.String.Backtick'].shortname == 'sb' }
+  end
+
+  it 'calculates ancestors' do
+    chain = Rouge::Token['Literal.String.Backtick'].token_chain.map(&:qualname)
+
+    assert { chain == %w(Literal Literal.String Literal.String.Backtick) }
+  end
+end
diff --git a/app/server/vendor/rouge/spec/visual/app.rb b/app/server/vendor/rouge/spec/visual/app.rb
new file mode 100755
index 0000000..dc534c9
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/app.rb
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*- #
+
+require 'rubygems'
+require 'bundler'
+Bundler.require :development
+
+# stdlib
+require 'pathname'
+
+class VisualTestApp < Sinatra::Application
+  BASE = Pathname.new(__FILE__).dirname
+  SAMPLES = BASE.join('samples')
+  ROOT = BASE.parent.parent
+
+  ROUGE_LIB = ROOT.join('lib/rouge.rb')
+
+  def reload_source!
+    Object.send :remove_const, :Rouge
+    load ROUGE_LIB
+  end
+
+  configure do
+    set :root, BASE
+    set :views, BASE.join('templates')
+  end
+
+  before do
+    reload_source!
+
+    theme_class = Rouge::Theme.find(params[:theme] || 'thankful_eyes')
+    halt 404 unless theme_class
+    @theme = theme_class.new
+
+    formatter_opts = { :line_numbers => params[:line_numbers] }
+    formatter_opts[:inline_theme] = @theme if params[:inline]
+
+    @formatter = Rouge::Formatters::HTML.new(formatter_opts)
+  end
+
+  get '/:lexer' do |lexer_name|
+    lexer_class = Rouge::Lexer.find(lexer_name)
+    halt 404 unless lexer_class
+    @sample = File.read(SAMPLES.join(lexer_class.tag), encoding: 'utf-8')
+
+    lexer_options = {}
+    params.each do |k, v|
+      lexer_options[k.to_sym] = v
+    end
+
+    @title = "#{lexer_class.tag} | Visual Test"
+    @lexer = lexer_class.new(lexer_options)
+    @highlighted = Rouge.highlight(@sample, @lexer, @formatter)
+
+    erb :lexer
+  end
+
+
+  get '/' do
+    @samples = SAMPLES.entries.reject { |s| s.basename.to_s =~ /^\.|~$/ }
+    @samples.map!(&Rouge::Lexer.method(:find))
+
+    erb :index
+  end
+end
diff --git a/app/server/vendor/rouge/spec/visual/samples/applescript b/app/server/vendor/rouge/spec/visual/samples/applescript
new file mode 100755
index 0000000..a70ce11
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/applescript
@@ -0,0 +1,58 @@
+-- Multi-word commands
+do shell script "date"
+display dialog "Does this work?"
+
+-- Some special kind of syntax for builtins
+«NoIdea»
+
+-- Multi-word constant
+set text item delimiters to "|"
+
+-- Types and properties
+tell application "iTunes" to get current selection
+get character 5 from "abcdefghij"
+
+-- Multi-word keyword (greater than)
+if 5 is greater than 4 then
+  set thing to 6
+end if
+
+-- "return" as a constant
+set a to return & "abc" & return & "def" & linefeed & "ghi"
+
+-- "return" as a command
+return a
+
+-- "return" as a command and constant
+if 4 is less than 5 then
+  return thing & return & a
+end if
+
+-- "return" inside string is properly identified
+set c to "abc is not a
+  return to def"
+
+-- Multi-line string escaping
+set b to "abc" & ¬
+  return & "def"
+
+-- Application dictionaries can redefine words
+tell application "BBEdit" to set show tab stops to true
+
+tell application "System Events"
+    tell network preferences
+        tell current location
+            set aPPPoEService to a reference to (first service whose kind is 10)
+            if exists aPPPoEService then
+                connect aPPPoEService
+            end if
+        end tell
+    end tell
+end tell
+
+set jp to "日本語"
+
+set ru to "Русский"
+
+jp & " and " & ru -- returns "日本語 and Русский"
+
diff --git a/app/server/vendor/rouge/spec/visual/samples/c b/app/server/vendor/rouge/spec/visual/samples/c
new file mode 100755
index 0000000..30d9a9d
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/c
@@ -0,0 +1,2637 @@
+/* it shouldn't hang */	/* trying to lex this */
+/*{"ahg/awn/xan?",	HB_TAG('A','G','W',' ')},*/	/* Agaw */
+/*{"gsw?/gsw-FR?",	HB_TAG('A','L','S',' ')},*/	/* Alsatian */
+/*{"krc",	HB_TAG('B','A','L',' ')},*/	/* Balkar */
+/*{"??",	HB_TAG('B','C','R',' ')},*/	/* Bible Cree */
+/*{"sgw?",	HB_TAG('C','H','G',' ')},*/	/* Chaha Gurage */
+/*{"acf/gcf?",	HB_TAG('F','A','N',' ')},*/	/* French Antillean */
+/*{"vls/nl-be",	HB_TAG('F','L','E',' ')},*/	/* Flemish */
+/*{"enf?/yrk?",	HB_TAG('F','N','E',' ')},*/	/* Forest Nenets */
+/*{"fuf?",	HB_TAG('F','T','A',' ')},*/	/* Futa */
+/*{"ar-Syrc?",	HB_TAG('G','A','R',' ')},*/	/* Garshuni */
+/*{"cfm/rnl?",	HB_TAG('H','A','L',' ')},*/	/* Halam */
+/*{"ga-Latg?/Latg?",	HB_TAG('I','R','T',' ')},*/	/* Irish Traditional */
+/*{"krc",	HB_TAG('K','A','R',' ')},*/	/* Karachay */
+/*{"alw?/ktb?",	HB_TAG('K','E','B',' ')},*/	/* Kebena */
+/*{"Geok",	HB_TAG('K','G','E',' ')},*/	/* Khutsuri Georgian */
+/*{"kca",	HB_TAG('K','H','K',' ')},*/	/* Khanty-Kazim */
+/*{"kca",	HB_TAG('K','H','S',' ')},*/	/* Khanty-Shurishkar */
+
+#if 0
+this should be commented
+#if THING
+this should also be commented
+#endif
+also comments
+#else
+#  if thing
+static int not_a_comment();
+#  endif
+#endif
+
+#macro
+
+
+/* Execute compiled code */
+
+/* XXX TO DO:
+   XXX speed up searching for keywords by using a dictionary
+   XXX document it!
+   */
+
+/* enable more aggressive intra-module optimizations, where available */
+#define PY_LOCAL_AGGRESSIVE
+
+#include "Python.h"
+
+#include "code.h"
+#include "frameobject.h"
+#include "eval.h"
+#include "opcode.h"
+#include "structmember.h"
+
+#include <ctype.h>
+
+#ifndef WITH_TSC
+
+#define READ_TIMESTAMP(var)
+
+#else
+
+typedef unsigned long long uint64;
+
+#if defined(__ppc__) /* <- Don't know if this is the correct symbol; this
+			   section should work for GCC on any PowerPC platform,
+			   irrespective of OS.  POWER?  Who knows :-) */
+
+#define READ_TIMESTAMP(var) ppc_getcounter(&var)
+
+static void
+ppc_getcounter(uint64 *v)
+{
+	register unsigned long tbu, tb, tbu2;
+
+  loop:
+	asm volatile ("mftbu %0" : "=r" (tbu) );
+	asm volatile ("mftb  %0" : "=r" (tb)  );
+	asm volatile ("mftbu %0" : "=r" (tbu2));
+	if (__builtin_expect(tbu != tbu2, 0)) goto loop;
+
+	/* The slightly peculiar way of writing the next lines is
+	   compiled better by GCC than any other way I tried. */
+	((long*)(v))[0] = tbu;
+	((long*)(v))[1] = tb;
+}
+
+#else /* this is for linux/x86 (and probably any other GCC/x86 combo) */
+
+#define READ_TIMESTAMP(val) \
+     __asm__ __volatile__("rdtsc" : "=A" (val))
+
+#endif
+
+void dump_tsc(int opcode, int ticked, uint64 inst0, uint64 inst1,
+	      uint64 loop0, uint64 loop1, uint64 intr0, uint64 intr1)
+{
+	uint64 intr, inst, loop;
+	PyThreadState *tstate = PyThreadState_Get();
+	if (!tstate->interp->tscdump)
+		return;
+	intr = intr1 - intr0;
+	inst = inst1 - inst0 - intr;
+	loop = loop1 - loop0 - intr;
+	fprintf(stderr, "opcode=%03d t=%d inst=%06lld loop=%06lld\n",
+		opcode, ticked, inst, loop);
+}
+
+#endif
+
+/* Turn this on if your compiler chokes on the big switch: */
+/* #define CASE_TOO_BIG 1 */
+
+#ifdef Py_DEBUG
+/* For debugging the interpreter: */
+#define LLTRACE  1	/* Low-level trace feature */
+#define CHECKEXC 1	/* Double-check exception checking */
+#endif
+
+typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *);
+
+/* Forward declarations */
+#ifdef WITH_TSC
+static PyObject * call_function(PyObject ***, int, uint64*, uint64*);
+#else
+static PyObject * call_function(PyObject ***, int);
+#endif
+static PyObject * fast_function(PyObject *, PyObject ***, int, int, int);
+static PyObject * do_call(PyObject *, PyObject ***, int, int);
+static PyObject * ext_do_call(PyObject *, PyObject ***, int, int, int);
+static PyObject * update_keyword_args(PyObject *, int, PyObject ***,PyObject *);
+static PyObject * update_star_args(int, int, PyObject *, PyObject ***);
+static PyObject * load_args(PyObject ***, int);
+#define CALL_FLAG_VAR 1
+#define CALL_FLAG_KW 2
+
+#ifdef LLTRACE
+static int lltrace;
+static int prtrace(PyObject *, char *);
+#endif
+static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *,
+		      int, PyObject *);
+static void call_trace_protected(Py_tracefunc, PyObject *,
+				 PyFrameObject *, int, PyObject *);
+static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *);
+static int maybe_call_line_trace(Py_tracefunc, PyObject *,
+				  PyFrameObject *, int *, int *, int *);
+
+static PyObject * apply_slice(PyObject *, PyObject *, PyObject *);
+static int assign_slice(PyObject *, PyObject *,
+			PyObject *, PyObject *);
+static PyObject * cmp_outcome(int, PyObject *, PyObject *);
+static PyObject * import_from(PyObject *, PyObject *);
+static int import_all_from(PyObject *, PyObject *);
+static PyObject * build_class(PyObject *, PyObject *, PyObject *);
+static int exec_statement(PyFrameObject *,
+			  PyObject *, PyObject *, PyObject *);
+static void set_exc_info(PyThreadState *, PyObject *, PyObject *, PyObject *);
+static void reset_exc_info(PyThreadState *);
+static void format_exc_check_arg(PyObject *, char *, PyObject *);
+static PyObject * string_concatenate(PyObject *, PyObject *,
+				    PyFrameObject *, unsigned char *);
+
+#define NAME_ERROR_MSG \
+	"name '%.200s' is not defined"
+#define GLOBAL_NAME_ERROR_MSG \
+	"global name '%.200s' is not defined"
+#define UNBOUNDLOCAL_ERROR_MSG \
+	"local variable '%.200s' referenced before assignment"
+#define UNBOUNDFREE_ERROR_MSG \
+	"free variable '%.200s' referenced before assignment" \
+        " in enclosing scope"
+
+/* Dynamic execution profile */
+#ifdef DYNAMIC_EXECUTION_PROFILE
+#ifdef DXPAIRS
+static long dxpairs[257][256];
+#define dxp dxpairs[256]
+#else
+static long dxp[256];
+#endif
+#endif
+
+/* Function call profile */
+#ifdef CALL_PROFILE
+#define PCALL_NUM 11
+static int pcall[PCALL_NUM];
+
+#define PCALL_ALL 0
+#define PCALL_FUNCTION 1
+#define PCALL_FAST_FUNCTION 2
+#define PCALL_FASTER_FUNCTION 3
+#define PCALL_METHOD 4
+#define PCALL_BOUND_METHOD 5
+#define PCALL_CFUNCTION 6
+#define PCALL_TYPE 7
+#define PCALL_GENERATOR 8
+#define PCALL_OTHER 9
+#define PCALL_POP 10
+
+/* Notes about the statistics
+
+   PCALL_FAST stats
+
+   FAST_FUNCTION means no argument tuple needs to be created.
+   FASTER_FUNCTION means that the fast-path frame setup code is used.
+
+   If there is a method call where the call can be optimized by changing
+   the argument tuple and calling the function directly, it gets recorded
+   twice.
+
+   As a result, the relationship among the statistics appears to be
+   PCALL_ALL == PCALL_FUNCTION + PCALL_METHOD - PCALL_BOUND_METHOD +
+                PCALL_CFUNCTION + PCALL_TYPE + PCALL_GENERATOR + PCALL_OTHER
+   PCALL_FUNCTION > PCALL_FAST_FUNCTION > PCALL_FASTER_FUNCTION
+   PCALL_METHOD > PCALL_BOUND_METHOD
+*/
+
+#define PCALL(POS) pcall[POS]++
+
+PyObject *
+PyEval_GetCallStats(PyObject *self)
+{
+	return Py_BuildValue("iiiiiiiiii",
+			     pcall[0], pcall[1], pcall[2], pcall[3],
+			     pcall[4], pcall[5], pcall[6], pcall[7],
+			     pcall[8], pcall[9]);
+}
+#else
+#define PCALL(O)
+
+PyObject *
+PyEval_GetCallStats(PyObject *self)
+{
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif
+
+
+#ifdef WITH_THREAD
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include "pythread.h"
+
+static PyThread_type_lock interpreter_lock = 0; /* This is the GIL */
+static long main_thread = 0;
+
+int
+PyEval_ThreadsInitialized(void)
+{
+	return interpreter_lock != 0;
+}
+
+void
+PyEval_InitThreads(void)
+{
+	if (interpreter_lock)
+		return;
+	interpreter_lock = PyThread_allocate_lock();
+	PyThread_acquire_lock(interpreter_lock, 1);
+	main_thread = PyThread_get_thread_ident();
+}
+
+void
+PyEval_AcquireLock(void)
+{
+	PyThread_acquire_lock(interpreter_lock, 1);
+}
+
+void
+PyEval_ReleaseLock(void)
+{
+	PyThread_release_lock(interpreter_lock);
+}
+
+void
+PyEval_AcquireThread(PyThreadState *tstate)
+{
+	if (tstate == NULL)
+		Py_FatalError("PyEval_AcquireThread: NULL new thread state");
+	/* Check someone has called PyEval_InitThreads() to create the lock */
+	assert(interpreter_lock);
+	PyThread_acquire_lock(interpreter_lock, 1);
+	if (PyThreadState_Swap(tstate) != NULL)
+		Py_FatalError(
+			"PyEval_AcquireThread: non-NULL old thread state");
+}
+
+void
+PyEval_ReleaseThread(PyThreadState *tstate)
+{
+	if (tstate == NULL)
+		Py_FatalError("PyEval_ReleaseThread: NULL thread state");
+	if (PyThreadState_Swap(NULL) != tstate)
+		Py_FatalError("PyEval_ReleaseThread: wrong thread state");
+	PyThread_release_lock(interpreter_lock);
+}
+
+/* This function is called from PyOS_AfterFork to ensure that newly
+   created child processes don't hold locks referring to threads which
+   are not running in the child process.  (This could also be done using
+   pthread_atfork mechanism, at least for the pthreads implementation.) */
+
+void
+PyEval_ReInitThreads(void)
+{
+	if (!interpreter_lock)
+		return;
+	/*XXX Can't use PyThread_free_lock here because it does too
+	  much error-checking.  Doing this cleanly would require
+	  adding a new function to each thread_*.h.  Instead, just
+	  create a new lock and waste a little bit of memory */
+	interpreter_lock = PyThread_allocate_lock();
+	PyThread_acquire_lock(interpreter_lock, 1);
+	main_thread = PyThread_get_thread_ident();
+}
+#endif
+
+/* Functions save_thread and restore_thread are always defined so
+   dynamically loaded modules needn't be compiled separately for use
+   with and without threads: */
+
+PyThreadState *
+PyEval_SaveThread(void)
+{
+	PyThreadState *tstate = PyThreadState_Swap(NULL);
+	if (tstate == NULL)
+		Py_FatalError("PyEval_SaveThread: NULL tstate");
+#ifdef WITH_THREAD
+	if (interpreter_lock)
+		PyThread_release_lock(interpreter_lock);
+#endif
+	return tstate;
+}
+
+void
+PyEval_RestoreThread(PyThreadState *tstate)
+{
+	if (tstate == NULL)
+		Py_FatalError("PyEval_RestoreThread: NULL tstate");
+#ifdef WITH_THREAD
+	if (interpreter_lock) {
+		int err = errno;
+		PyThread_acquire_lock(interpreter_lock, 1);
+		errno = err;
+	}
+#endif
+	PyThreadState_Swap(tstate);
+}
+
+
+/* Mechanism whereby asynchronously executing callbacks (e.g. UNIX
+   signal handlers or Mac I/O completion routines) can schedule calls
+   to a function to be called synchronously.
+   The synchronous function is called with one void* argument.
+   It should return 0 for success or -1 for failure -- failure should
+   be accompanied by an exception.
+
+   If registry succeeds, the registry function returns 0; if it fails
+   (e.g. due to too many pending calls) it returns -1 (without setting
+   an exception condition).
+
+   Note that because registry may occur from within signal handlers,
+   or other asynchronous events, calling malloc() is unsafe!
+
+#ifdef WITH_THREAD
+   Any thread can schedule pending calls, but only the main thread
+   will execute them.
+#endif
+
+   XXX WARNING!  ASYNCHRONOUSLY EXECUTING CODE!
+   There are two possible race conditions:
+   (1) nested asynchronous registry calls;
+   (2) registry calls made while pending calls are being processed.
+   While (1) is very unlikely, (2) is a real possibility.
+   The current code is safe against (2), but not against (1).
+   The safety against (2) is derived from the fact that only one
+   thread (the main thread) ever takes things out of the queue.
+
+   XXX Darn!  With the advent of thread state, we should have an array
+   of pending calls per thread in the thread state!  Later...
+*/
+
+#define NPENDINGCALLS 32
+static struct {
+	int (*func)(void *);
+	void *arg;
+} pendingcalls[NPENDINGCALLS];
+static volatile int pendingfirst = 0;
+static volatile int pendinglast = 0;
+static volatile int things_to_do = 0;
+
+int
+Py_AddPendingCall(int (*func)(void *), void *arg)
+{
+	static volatile int busy = 0;
+	int i, j;
+	/* XXX Begin critical section */
+	/* XXX If you want this to be safe against nested
+	   XXX asynchronous calls, you'll have to work harder! */
+	if (busy)
+		return -1;
+	busy = 1;
+	i = pendinglast;
+	j = (i + 1) % NPENDINGCALLS;
+	if (j == pendingfirst) {
+		busy = 0;
+		return -1; /* Queue full */
+	}
+	pendingcalls[i].func = func;
+	pendingcalls[i].arg = arg;
+	pendinglast = j;
+
+	_Py_Ticker = 0;
+	things_to_do = 1; /* Signal main loop */
+	busy = 0;
+	/* XXX End critical section */
+	return 0;
+}
+
+int
+Py_MakePendingCalls(void)
+{
+	static int busy = 0;
+#ifdef WITH_THREAD
+	if (main_thread && PyThread_get_thread_ident() != main_thread)
+		return 0;
+#endif
+	if (busy)
+		return 0;
+	busy = 1;
+	things_to_do = 0;
+	for (;;) {
+		int i;
+		int (*func)(void *);
+		void *arg;
+		i = pendingfirst;
+		if (i == pendinglast)
+			break; /* Queue empty */
+		func = pendingcalls[i].func;
+		arg = pendingcalls[i].arg;
+		pendingfirst = (i + 1) % NPENDINGCALLS;
+		if (func(arg) < 0) {
+			busy = 0;
+			things_to_do = 1; /* We're not done yet */
+			return -1;
+		}
+	}
+	busy = 0;
+	return 0;
+}
+
+
+/* The interpreter's recursion limit */
+
+#ifndef Py_DEFAULT_RECURSION_LIMIT
+#define Py_DEFAULT_RECURSION_LIMIT 1000
+#endif
+static int recursion_limit = Py_DEFAULT_RECURSION_LIMIT;
+int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT;
+
+int
+Py_GetRecursionLimit(void)
+{
+	return recursion_limit;
+}
+
+void
+Py_SetRecursionLimit(int new_limit)
+{
+	recursion_limit = new_limit;
+        _Py_CheckRecursionLimit = recursion_limit;
+}
+
+/* the macro Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall()
+   if the recursion_depth reaches _Py_CheckRecursionLimit.
+   If USE_STACKCHECK, the macro decrements _Py_CheckRecursionLimit
+   to guarantee that _Py_CheckRecursiveCall() is regularly called.
+   Without USE_STACKCHECK, there is no need for this. */
+int
+_Py_CheckRecursiveCall(char *where)
+{
+	PyThreadState *tstate = PyThreadState_GET();
+
+#ifdef USE_STACKCHECK
+	if (PyOS_CheckStack()) {
+		--tstate->recursion_depth;
+		PyErr_SetString(PyExc_MemoryError, "Stack overflow");
+		return -1;
+	}
+#endif
+	if (tstate->recursion_depth > recursion_limit) {
+		--tstate->recursion_depth;
+		PyErr_Format(PyExc_RuntimeError,
+			     "maximum recursion depth exceeded%s",
+			     where);
+		return -1;
+	}
+        _Py_CheckRecursionLimit = recursion_limit;
+	return 0;
+}
+
+/* Status code for main loop (reason for stack unwind) */
+enum why_code {
+		WHY_NOT =	0x0001,	/* No error */
+		WHY_EXCEPTION = 0x0002,	/* Exception occurred */
+		WHY_RERAISE =	0x0004,	/* Exception re-raised by 'finally' */
+		WHY_RETURN =	0x0008,	/* 'return' statement */
+		WHY_BREAK =	0x0010,	/* 'break' statement */
+		WHY_CONTINUE =	0x0020,	/* 'continue' statement */
+		WHY_YIELD =	0x0040	/* 'yield' operator */
+};
+
+static enum why_code do_raise(PyObject *, PyObject *, PyObject *);
+static int unpack_iterable(PyObject *, int, PyObject **);
+
+/* for manipulating the thread switch and periodic "stuff" - used to be
+   per thread, now just a pair o' globals */
+int _Py_CheckInterval = 100;
+volatile int _Py_Ticker = 100;
+
+PyObject *
+PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
+{
+	/* XXX raise SystemError if globals is NULL */
+	return PyEval_EvalCodeEx(co,
+			  globals, locals,
+			  (PyObject **)NULL, 0,
+			  (PyObject **)NULL, 0,
+			  (PyObject **)NULL, 0,
+			  NULL);
+}
+
+
+/* Interpreter main loop */
+
+PyObject *
+PyEval_EvalFrame(PyFrameObject *f) {
+	/* This is for backward compatibility with extension modules that
+           used this API; core interpreter code should call PyEval_EvalFrameEx() */
+	return PyEval_EvalFrameEx(f, 0);
+}
+
+PyObject *
+PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
+{
+#ifdef DXPAIRS
+	int lastopcode = 0;
+#endif
+	register PyObject **stack_pointer;   /* Next free slot in value stack */
+	register unsigned char *next_instr;
+	register int opcode;	/* Current opcode */
+	register int oparg;	/* Current opcode argument, if any */
+	register enum why_code why; /* Reason for block stack unwind */
+	register int err;	/* Error status -- nonzero if error */
+	register PyObject *x;	/* Result object -- NULL if error */
+	register PyObject *v;	/* Temporary objects popped off stack */
+	register PyObject *w;
+	register PyObject *u;
+	register PyObject *t;
+	register PyObject *stream = NULL;    /* for PRINT opcodes */
+	register PyObject **fastlocals, **freevars;
+	PyObject *retval = NULL;	/* Return value */
+	PyThreadState *tstate = PyThreadState_GET();
+	PyCodeObject *co;
+
+	/* when tracing we set things up so that
+
+               not (instr_lb <= current_bytecode_offset < instr_ub)
+
+	   is true when the line being executed has changed.  The
+           initial values are such as to make this false the first
+           time it is tested. */
+	int instr_ub = -1, instr_lb = 0, instr_prev = -1;
+
+	unsigned char *first_instr;
+	PyObject *names;
+	PyObject *consts;
+#if defined(Py_DEBUG) || defined(LLTRACE)
+	/* Make it easier to find out where we are with a debugger */
+	char *filename;
+#endif
+
+/* Tuple access macros */
+
+#ifndef Py_DEBUG
+#define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i))
+#else
+#define GETITEM(v, i) PyTuple_GetItem((v), (i))
+#endif
+
+#ifdef WITH_TSC
+/* Use Pentium timestamp counter to mark certain events:
+   inst0 -- beginning of switch statement for opcode dispatch
+   inst1 -- end of switch statement (may be skipped)
+   loop0 -- the top of the mainloop
+   loop1 -- place where control returns again to top of mainloop
+            (may be skipped)
+   intr1 -- beginning of long interruption
+   intr2 -- end of long interruption
+
+   Many opcodes call out to helper C functions.  In some cases, the
+   time in those functions should be counted towards the time for the
+   opcode, but not in all cases.  For example, a CALL_FUNCTION opcode
+   calls another Python function; there's no point in charge all the
+   bytecode executed by the called function to the caller.
+
+   It's hard to make a useful judgement statically.  In the presence
+   of operator overloading, it's impossible to tell if a call will
+   execute new Python code or not.
+
+   It's a case-by-case judgement.  I'll use intr1 for the following
+   cases:
+
+   EXEC_STMT
+   IMPORT_STAR
+   IMPORT_FROM
+   CALL_FUNCTION (and friends)
+
+ */
+	uint64 inst0, inst1, loop0, loop1, intr0 = 0, intr1 = 0;
+	int ticked = 0;
+
+	READ_TIMESTAMP(inst0);
+	READ_TIMESTAMP(inst1);
+	READ_TIMESTAMP(loop0);
+	READ_TIMESTAMP(loop1);
+
+	/* shut up the compiler */
+	opcode = 0;
+#endif
+
+/* Code access macros */
+
+#define INSTR_OFFSET()	((int)(next_instr - first_instr))
+#define NEXTOP()	(*next_instr++)
+#define NEXTARG()	(next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
+#define PEEKARG()	((next_instr[2]<<8) + next_instr[1])
+#define JUMPTO(x)	(next_instr = first_instr + (x))
+#define JUMPBY(x)	(next_instr += (x))
+
+/* OpCode prediction macros
+	Some opcodes tend to come in pairs thus making it possible to predict
+	the second code when the first is run.  For example, COMPARE_OP is often
+	followed by JUMP_IF_FALSE or JUMP_IF_TRUE.  And, those opcodes are often
+	followed by a POP_TOP.
+
+	Verifying the prediction costs a single high-speed test of register
+	variable against a constant.  If the pairing was good, then the
+	processor has a high likelihood of making its own successful branch
+	prediction which results in a nearly zero overhead transition to the
+	next opcode.
+
+	A successful prediction saves a trip through the eval-loop including
+	its two unpredictable branches, the HASARG test and the switch-case.
+
+        If collecting opcode statistics, turn off prediction so that
+	statistics are accurately maintained (the predictions bypass
+	the opcode frequency counter updates).
+*/
+
+#ifdef DYNAMIC_EXECUTION_PROFILE
+#define PREDICT(op)		if (0) goto PRED_##op
+#else
+#define PREDICT(op)		if (*next_instr == op) goto PRED_##op
+#endif
+
+#define PREDICTED(op)		PRED_##op: next_instr++
+#define PREDICTED_WITH_ARG(op)	PRED_##op: oparg = PEEKARG(); next_instr += 3
+
+/* Stack manipulation macros */
+
+/* The stack can grow at most MAXINT deep, as co_nlocals and
+   co_stacksize are ints. */
+#define STACK_LEVEL()	((int)(stack_pointer - f->f_valuestack))
+#define EMPTY()		(STACK_LEVEL() == 0)
+#define TOP()		(stack_pointer[-1])
+#define SECOND()	(stack_pointer[-2])
+#define THIRD() 	(stack_pointer[-3])
+#define FOURTH()	(stack_pointer[-4])
+#define SET_TOP(v)	(stack_pointer[-1] = (v))
+#define SET_SECOND(v)	(stack_pointer[-2] = (v))
+#define SET_THIRD(v)	(stack_pointer[-3] = (v))
+#define SET_FOURTH(v)	(stack_pointer[-4] = (v))
+#define BASIC_STACKADJ(n)	(stack_pointer += n)
+#define BASIC_PUSH(v)	(*stack_pointer++ = (v))
+#define BASIC_POP()	(*--stack_pointer)
+
+#ifdef LLTRACE
+#define PUSH(v)		{ (void)(BASIC_PUSH(v), \
+                               lltrace && prtrace(TOP(), "push")); \
+                               assert(STACK_LEVEL() <= co->co_stacksize); }
+#define POP()		((void)(lltrace && prtrace(TOP(), "pop")), BASIC_POP())
+#define STACKADJ(n)	{ (void)(BASIC_STACKADJ(n), \
+                               lltrace && prtrace(TOP(), "stackadj")); \
+                               assert(STACK_LEVEL() <= co->co_stacksize); }
+#define EXT_POP(STACK_POINTER) (lltrace && prtrace(*(STACK_POINTER), "ext_pop"), *--(STACK_POINTER))
+#else
+#define PUSH(v)		BASIC_PUSH(v)
+#define POP()		BASIC_POP()
+#define STACKADJ(n)	BASIC_STACKADJ(n)
+#define EXT_POP(STACK_POINTER) (*--(STACK_POINTER))
+#endif
+
+/* Local variable macros */
+
+#define GETLOCAL(i)	(fastlocals[i])
+
+/* The SETLOCAL() macro must not DECREF the local variable in-place and
+   then store the new value; it must copy the old value to a temporary
+   value, then store the new value, and then DECREF the temporary value.
+   This is because it is possible that during the DECREF the frame is
+   accessed by other code (e.g. a __del__ method or gc.collect()) and the
+   variable would be pointing to already-freed memory. */
+#define SETLOCAL(i, value)	do { PyObject *tmp = GETLOCAL(i); \
+				     GETLOCAL(i) = value; \
+                                     Py_XDECREF(tmp); } while (0)
+
+/* Start of code */
+
+	if (f == NULL)
+		return NULL;
+
+	/* push frame */
+	if (Py_EnterRecursiveCall(""))
+		return NULL;
+
+	tstate->frame = f;
+
+	if (tstate->use_tracing) {
+		if (tstate->c_tracefunc != NULL) {
+			/* tstate->c_tracefunc, if defined, is a
+			   function that will be called on *every* entry
+			   to a code block.  Its return value, if not
+			   None, is a function that will be called at
+			   the start of each executed line of code.
+			   (Actually, the function must return itself
+			   in order to continue tracing.)  The trace
+			   functions are called with three arguments:
+			   a pointer to the current frame, a string
+			   indicating why the function is called, and
+			   an argument which depends on the situation.
+			   The global trace function is also called
+			   whenever an exception is detected. */
+			if (call_trace(tstate->c_tracefunc, tstate->c_traceobj,
+				       f, PyTrace_CALL, Py_None)) {
+				/* Trace function raised an error */
+				goto exit_eval_frame;
+			}
+		}
+		if (tstate->c_profilefunc != NULL) {
+			/* Similar for c_profilefunc, except it needn't
+			   return itself and isn't called for "line" events */
+			if (call_trace(tstate->c_profilefunc,
+				       tstate->c_profileobj,
+				       f, PyTrace_CALL, Py_None)) {
+				/* Profile function raised an error */
+				goto exit_eval_frame;
+			}
+		}
+	}
+
+	co = f->f_code;
+	names = co->co_names;
+	consts = co->co_consts;
+	fastlocals = f->f_localsplus;
+	freevars = f->f_localsplus + co->co_nlocals;
+	first_instr = (unsigned char*) PyString_AS_STRING(co->co_code);
+	/* An explanation is in order for the next line.
+
+	   f->f_lasti now refers to the index of the last instruction
+	   executed.  You might think this was obvious from the name, but
+	   this wasn't always true before 2.3!  PyFrame_New now sets
+	   f->f_lasti to -1 (i.e. the index *before* the first instruction)
+	   and YIELD_VALUE doesn't fiddle with f_lasti any more.  So this
+	   does work.  Promise. */
+	next_instr = first_instr + f->f_lasti + 1;
+	stack_pointer = f->f_stacktop;
+	assert(stack_pointer != NULL);
+	f->f_stacktop = NULL;	/* remains NULL unless yield suspends frame */
+
+#ifdef LLTRACE
+	lltrace = PyDict_GetItemString(f->f_globals, "__lltrace__") != NULL;
+#endif
+#if defined(Py_DEBUG) || defined(LLTRACE)
+	filename = PyString_AsString(co->co_filename);
+#endif
+
+	why = WHY_NOT;
+	err = 0;
+	x = Py_None;	/* Not a reference, just anything non-NULL */
+	w = NULL;
+
+	if (throwflag) { /* support for generator.throw() */
+		why = WHY_EXCEPTION;
+		goto on_error;
+	}
+
+	for (;;) {
+#ifdef WITH_TSC
+		if (inst1 == 0) {
+			/* Almost surely, the opcode executed a break
+			   or a continue, preventing inst1 from being set
+			   on the way out of the loop.
+			*/
+			READ_TIMESTAMP(inst1);
+			loop1 = inst1;
+		}
+		dump_tsc(opcode, ticked, inst0, inst1, loop0, loop1,
+			 intr0, intr1);
+		ticked = 0;
+		inst1 = 0;
+		intr0 = 0;
+		intr1 = 0;
+		READ_TIMESTAMP(loop0);
+#endif
+		assert(stack_pointer >= f->f_valuestack); /* else underflow */
+		assert(STACK_LEVEL() <= co->co_stacksize);  /* else overflow */
+
+		/* Do periodic things.  Doing this every time through
+		   the loop would add too much overhead, so we do it
+		   only every Nth instruction.  We also do it if
+		   ``things_to_do'' is set, i.e. when an asynchronous
+		   event needs attention (e.g. a signal handler or
+		   async I/O handler); see Py_AddPendingCall() and
+		   Py_MakePendingCalls() above. */
+
+		if (--_Py_Ticker < 0) {
+                        if (*next_instr == SETUP_FINALLY) {
+                                /* Make the last opcode before
+                                   a try: finally: block uninterruptable. */
+                                goto fast_next_opcode;
+                        }
+			_Py_Ticker = _Py_CheckInterval;
+			tstate->tick_counter++;
+#ifdef WITH_TSC
+			ticked = 1;
+#endif
+			if (things_to_do) {
+				if (Py_MakePendingCalls() < 0) {
+					why = WHY_EXCEPTION;
+					goto on_error;
+				}
+				if (things_to_do)
+					/* MakePendingCalls() didn't succeed.
+					   Force early re-execution of this
+					   "periodic" code, possibly after
+					   a thread switch */
+					_Py_Ticker = 0;
+			}
+#ifdef WITH_THREAD
+			if (interpreter_lock) {
+				/* Give another thread a chance */
+
+				if (PyThreadState_Swap(NULL) != tstate)
+					Py_FatalError("ceval: tstate mix-up");
+				PyThread_release_lock(interpreter_lock);
+
+				/* Other threads may run now */
+
+				PyThread_acquire_lock(interpreter_lock, 1);
+				if (PyThreadState_Swap(tstate) != NULL)
+					Py_FatalError("ceval: orphan tstate");
+
+				/* Check for thread interrupts */
+
+				if (tstate->async_exc != NULL) {
+					x = tstate->async_exc;
+					tstate->async_exc = NULL;
+					PyErr_SetNone(x);
+					Py_DECREF(x);
+					why = WHY_EXCEPTION;
+					goto on_error;
+				}
+			}
+#endif
+		}
+
+	fast_next_opcode:
+		f->f_lasti = INSTR_OFFSET();
+
+		/* line-by-line tracing support */
+
+		if (tstate->c_tracefunc != NULL && !tstate->tracing) {
+			/* see maybe_call_line_trace
+			   for expository comments */
+			f->f_stacktop = stack_pointer;
+
+			err = maybe_call_line_trace(tstate->c_tracefunc,
+						    tstate->c_traceobj,
+						    f, &instr_lb, &instr_ub,
+						    &instr_prev);
+			/* Reload possibly changed frame fields */
+			JUMPTO(f->f_lasti);
+			if (f->f_stacktop != NULL) {
+				stack_pointer = f->f_stacktop;
+				f->f_stacktop = NULL;
+			}
+			if (err) {
+				/* trace function raised an exception */
+				goto on_error;
+			}
+		}
+
+		/* Extract opcode and argument */
+
+		opcode = NEXTOP();
+		oparg = 0;   /* allows oparg to be stored in a register because
+			it doesn't have to be remembered across a full loop */
+		if (HAS_ARG(opcode))
+			oparg = NEXTARG();
+	  dispatch_opcode:
+#ifdef DYNAMIC_EXECUTION_PROFILE
+#ifdef DXPAIRS
+		dxpairs[lastopcode][opcode]++;
+		lastopcode = opcode;
+#endif
+		dxp[opcode]++;
+#endif
+
+#ifdef LLTRACE
+		/* Instruction tracing */
+
+		if (lltrace) {
+			if (HAS_ARG(opcode)) {
+				printf("%d: %d, %d\n",
+				       f->f_lasti, opcode, oparg);
+			}
+			else {
+				printf("%d: %d\n",
+				       f->f_lasti, opcode);
+			}
+		}
+#endif
+
+		/* Main switch on opcode */
+		READ_TIMESTAMP(inst0);
+
+		switch (opcode) {
+
+		/* BEWARE!
+		   It is essential that any operation that fails sets either
+		   x to NULL, err to nonzero, or why to anything but WHY_NOT,
+		   and that no operation that succeeds does this! */
+
+		/* case STOP_CODE: this is an error! */
+
+		case NOP:
+			goto fast_next_opcode;
+
+		case LOAD_FAST:
+			x = GETLOCAL(oparg);
+			if (x != NULL) {
+				Py_INCREF(x);
+				PUSH(x);
+				goto fast_next_opcode;
+			}
+			format_exc_check_arg(PyExc_UnboundLocalError,
+				UNBOUNDLOCAL_ERROR_MSG,
+				PyTuple_GetItem(co->co_varnames, oparg));
+			break;
+
+		case LOAD_CONST:
+			x = GETITEM(consts, oparg);
+			Py_INCREF(x);
+			PUSH(x);
+			goto fast_next_opcode;
+
+		PREDICTED_WITH_ARG(STORE_FAST);
+		case STORE_FAST:
+			v = POP();
+			SETLOCAL(oparg, v);
+			goto fast_next_opcode;
+
+		PREDICTED(POP_TOP);
+		case POP_TOP:
+			v = POP();
+			Py_DECREF(v);
+			goto fast_next_opcode;
+
+		case ROT_TWO:
+			v = TOP();
+			w = SECOND();
+			SET_TOP(w);
+			SET_SECOND(v);
+			goto fast_next_opcode;
+
+		case ROT_THREE:
+			v = TOP();
+			w = SECOND();
+			x = THIRD();
+			SET_TOP(w);
+			SET_SECOND(x);
+			SET_THIRD(v);
+			goto fast_next_opcode;
+
+		case ROT_FOUR:
+			u = TOP();
+			v = SECOND();
+			w = THIRD();
+			x = FOURTH();
+			SET_TOP(v);
+			SET_SECOND(w);
+			SET_THIRD(x);
+			SET_FOURTH(u);
+			goto fast_next_opcode;
+
+		case DUP_TOP:
+			v = TOP();
+			Py_INCREF(v);
+			PUSH(v);
+			goto fast_next_opcode;
+
+		case DUP_TOPX:
+			if (oparg == 2) {
+				x = TOP();
+				Py_INCREF(x);
+				w = SECOND();
+				Py_INCREF(w);
+				STACKADJ(2);
+				SET_TOP(x);
+				SET_SECOND(w);
+				goto fast_next_opcode;
+			} else if (oparg == 3) {
+				x = TOP();
+				Py_INCREF(x);
+				w = SECOND();
+				Py_INCREF(w);
+				v = THIRD();
+				Py_INCREF(v);
+				STACKADJ(3);
+				SET_TOP(x);
+				SET_SECOND(w);
+				SET_THIRD(v);
+				goto fast_next_opcode;
+			}
+			Py_FatalError("invalid argument to DUP_TOPX"
+				      " (bytecode corruption?)");
+			break;
+
+		case UNARY_POSITIVE:
+			v = TOP();
+			x = PyNumber_Positive(v);
+			Py_DECREF(v);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case UNARY_NEGATIVE:
+			v = TOP();
+			x = PyNumber_Negative(v);
+			Py_DECREF(v);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case UNARY_NOT:
+			v = TOP();
+			err = PyObject_IsTrue(v);
+			Py_DECREF(v);
+			if (err == 0) {
+				Py_INCREF(Py_True);
+				SET_TOP(Py_True);
+				continue;
+			}
+			else if (err > 0) {
+				Py_INCREF(Py_False);
+				SET_TOP(Py_False);
+				err = 0;
+				continue;
+			}
+			STACKADJ(-1);
+			break;
+
+		case UNARY_CONVERT:
+			v = TOP();
+			x = PyObject_Repr(v);
+			Py_DECREF(v);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case UNARY_INVERT:
+			v = TOP();
+			x = PyNumber_Invert(v);
+			Py_DECREF(v);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_POWER:
+			w = POP();
+			v = TOP();
+			x = PyNumber_Power(v, w, Py_None);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_MULTIPLY:
+			w = POP();
+			v = TOP();
+			x = PyNumber_Multiply(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_DIVIDE:
+			if (!_Py_QnewFlag) {
+				w = POP();
+				v = TOP();
+				x = PyNumber_Divide(v, w);
+				Py_DECREF(v);
+				Py_DECREF(w);
+				SET_TOP(x);
+				if (x != NULL) continue;
+				break;
+			}
+			/* -Qnew is in effect:	fall through to
+			   BINARY_TRUE_DIVIDE */
+		case BINARY_TRUE_DIVIDE:
+			w = POP();
+			v = TOP();
+			x = PyNumber_TrueDivide(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_FLOOR_DIVIDE:
+			w = POP();
+			v = TOP();
+			x = PyNumber_FloorDivide(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_MODULO:
+			w = POP();
+			v = TOP();
+			x = PyNumber_Remainder(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_ADD:
+			w = POP();
+			v = TOP();
+			if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
+				/* INLINE: int + int */
+				register long a, b, i;
+				a = PyInt_AS_LONG(v);
+				b = PyInt_AS_LONG(w);
+				i = a + b;
+				if ((i^a) < 0 && (i^b) < 0)
+					goto slow_add;
+				x = PyInt_FromLong(i);
+			}
+			else if (PyString_CheckExact(v) &&
+				 PyString_CheckExact(w)) {
+				x = string_concatenate(v, w, f, next_instr);
+				/* string_concatenate consumed the ref to v */
+				goto skip_decref_vx;
+			}
+			else {
+			  slow_add:
+				x = PyNumber_Add(v, w);
+			}
+			Py_DECREF(v);
+		  skip_decref_vx:
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_SUBTRACT:
+			w = POP();
+			v = TOP();
+			if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
+				/* INLINE: int - int */
+				register long a, b, i;
+				a = PyInt_AS_LONG(v);
+				b = PyInt_AS_LONG(w);
+				i = a - b;
+				if ((i^a) < 0 && (i^~b) < 0)
+					goto slow_sub;
+				x = PyInt_FromLong(i);
+			}
+			else {
+			  slow_sub:
+				x = PyNumber_Subtract(v, w);
+			}
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_SUBSCR:
+			w = POP();
+			v = TOP();
+			if (PyList_CheckExact(v) && PyInt_CheckExact(w)) {
+				/* INLINE: list[int] */
+				Py_ssize_t i = PyInt_AsSsize_t(w);
+				if (i < 0)
+					i += PyList_GET_SIZE(v);
+				if (i >= 0 && i < PyList_GET_SIZE(v)) {
+					x = PyList_GET_ITEM(v, i);
+					Py_INCREF(x);
+				}
+				else
+					goto slow_get;
+			}
+			else
+			  slow_get:
+				x = PyObject_GetItem(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_LSHIFT:
+			w = POP();
+			v = TOP();
+			x = PyNumber_Lshift(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_RSHIFT:
+			w = POP();
+			v = TOP();
+			x = PyNumber_Rshift(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_AND:
+			w = POP();
+			v = TOP();
+			x = PyNumber_And(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_XOR:
+			w = POP();
+			v = TOP();
+			x = PyNumber_Xor(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case BINARY_OR:
+			w = POP();
+			v = TOP();
+			x = PyNumber_Or(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case LIST_APPEND:
+			w = POP();
+			v = POP();
+			err = PyList_Append(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			if (err == 0) {
+				PREDICT(JUMP_ABSOLUTE);
+				continue;
+			}
+			break;
+
+		case INPLACE_POWER:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlacePower(v, w, Py_None);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_MULTIPLY:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceMultiply(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_DIVIDE:
+			if (!_Py_QnewFlag) {
+				w = POP();
+				v = TOP();
+				x = PyNumber_InPlaceDivide(v, w);
+				Py_DECREF(v);
+				Py_DECREF(w);
+				SET_TOP(x);
+				if (x != NULL) continue;
+				break;
+			}
+			/* -Qnew is in effect:	fall through to
+			   INPLACE_TRUE_DIVIDE */
+		case INPLACE_TRUE_DIVIDE:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceTrueDivide(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_FLOOR_DIVIDE:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceFloorDivide(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_MODULO:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceRemainder(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_ADD:
+			w = POP();
+			v = TOP();
+			if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
+				/* INLINE: int + int */
+				register long a, b, i;
+				a = PyInt_AS_LONG(v);
+				b = PyInt_AS_LONG(w);
+				i = a + b;
+				if ((i^a) < 0 && (i^b) < 0)
+					goto slow_iadd;
+				x = PyInt_FromLong(i);
+			}
+			else if (PyString_CheckExact(v) &&
+				 PyString_CheckExact(w)) {
+				x = string_concatenate(v, w, f, next_instr);
+				/* string_concatenate consumed the ref to v */
+				goto skip_decref_v;
+			}
+			else {
+			  slow_iadd:
+				x = PyNumber_InPlaceAdd(v, w);
+			}
+			Py_DECREF(v);
+		  skip_decref_v:
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_SUBTRACT:
+			w = POP();
+			v = TOP();
+			if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
+				/* INLINE: int - int */
+				register long a, b, i;
+				a = PyInt_AS_LONG(v);
+				b = PyInt_AS_LONG(w);
+				i = a - b;
+				if ((i^a) < 0 && (i^~b) < 0)
+					goto slow_isub;
+				x = PyInt_FromLong(i);
+			}
+			else {
+			  slow_isub:
+				x = PyNumber_InPlaceSubtract(v, w);
+			}
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_LSHIFT:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceLshift(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_RSHIFT:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceRshift(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_AND:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceAnd(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_XOR:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceXor(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case INPLACE_OR:
+			w = POP();
+			v = TOP();
+			x = PyNumber_InPlaceOr(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case SLICE+0:
+		case SLICE+1:
+		case SLICE+2:
+		case SLICE+3:
+			if ((opcode-SLICE) & 2)
+				w = POP();
+			else
+				w = NULL;
+			if ((opcode-SLICE) & 1)
+				v = POP();
+			else
+				v = NULL;
+			u = TOP();
+			x = apply_slice(u, v, w);
+			Py_DECREF(u);
+			Py_XDECREF(v);
+			Py_XDECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case STORE_SLICE+0:
+		case STORE_SLICE+1:
+		case STORE_SLICE+2:
+		case STORE_SLICE+3:
+			if ((opcode-STORE_SLICE) & 2)
+				w = POP();
+			else
+				w = NULL;
+			if ((opcode-STORE_SLICE) & 1)
+				v = POP();
+			else
+				v = NULL;
+			u = POP();
+			t = POP();
+			err = assign_slice(u, v, w, t); /* u[v:w] = t */
+			Py_DECREF(t);
+			Py_DECREF(u);
+			Py_XDECREF(v);
+			Py_XDECREF(w);
+			if (err == 0) continue;
+			break;
+
+		case DELETE_SLICE+0:
+		case DELETE_SLICE+1:
+		case DELETE_SLICE+2:
+		case DELETE_SLICE+3:
+			if ((opcode-DELETE_SLICE) & 2)
+				w = POP();
+			else
+				w = NULL;
+			if ((opcode-DELETE_SLICE) & 1)
+				v = POP();
+			else
+				v = NULL;
+			u = POP();
+			err = assign_slice(u, v, w, (PyObject *)NULL);
+							/* del u[v:w] */
+			Py_DECREF(u);
+			Py_XDECREF(v);
+			Py_XDECREF(w);
+			if (err == 0) continue;
+			break;
+
+		case STORE_SUBSCR:
+			w = TOP();
+			v = SECOND();
+			u = THIRD();
+			STACKADJ(-3);
+			/* v[w] = u */
+			err = PyObject_SetItem(v, w, u);
+			Py_DECREF(u);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			if (err == 0) continue;
+			break;
+
+		case DELETE_SUBSCR:
+			w = TOP();
+			v = SECOND();
+			STACKADJ(-2);
+			/* del v[w] */
+			err = PyObject_DelItem(v, w);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			if (err == 0) continue;
+			break;
+
+		case PRINT_EXPR:
+			v = POP();
+			w = PySys_GetObject("displayhook");
+			if (w == NULL) {
+				PyErr_SetString(PyExc_RuntimeError,
+						"lost sys.displayhook");
+				err = -1;
+				x = NULL;
+			}
+			if (err == 0) {
+				x = PyTuple_Pack(1, v);
+				if (x == NULL)
+					err = -1;
+			}
+			if (err == 0) {
+				w = PyEval_CallObject(w, x);
+				Py_XDECREF(w);
+				if (w == NULL)
+					err = -1;
+			}
+			Py_DECREF(v);
+			Py_XDECREF(x);
+			break;
+
+		case PRINT_ITEM_TO:
+			w = stream = POP();
+			/* fall through to PRINT_ITEM */
+
+		case PRINT_ITEM:
+			v = POP();
+			if (stream == NULL || stream == Py_None) {
+				w = PySys_GetObject("stdout");
+				if (w == NULL) {
+					PyErr_SetString(PyExc_RuntimeError,
+							"lost sys.stdout");
+					err = -1;
+				}
+			}
+			/* PyFile_SoftSpace() can exececute arbitrary code
+			   if sys.stdout is an instance with a __getattr__.
+			   If __getattr__ raises an exception, w will
+			   be freed, so we need to prevent that temporarily. */
+			Py_XINCREF(w);
+			if (w != NULL && PyFile_SoftSpace(w, 0))
+				err = PyFile_WriteString(" ", w);
+			if (err == 0)
+				err = PyFile_WriteObject(v, w, Py_PRINT_RAW);
+			if (err == 0) {
+			    /* XXX move into writeobject() ? */
+			    if (PyString_Check(v)) {
+				char *s = PyString_AS_STRING(v);
+				Py_ssize_t len = PyString_GET_SIZE(v);
+				if (len == 0 ||
+				    !isspace(Py_CHARMASK(s[len-1])) ||
+				    s[len-1] == ' ')
+					PyFile_SoftSpace(w, 1);
+			    }
+#ifdef Py_USING_UNICODE
+			    else if (PyUnicode_Check(v)) {
+				Py_UNICODE *s = PyUnicode_AS_UNICODE(v);
+				Py_ssize_t len = PyUnicode_GET_SIZE(v);
+				if (len == 0 ||
+				    !Py_UNICODE_ISSPACE(s[len-1]) ||
+				    s[len-1] == ' ')
+				    PyFile_SoftSpace(w, 1);
+			    }
+#endif
+			    else
+			    	PyFile_SoftSpace(w, 1);
+			}
+			Py_XDECREF(w);
+			Py_DECREF(v);
+			Py_XDECREF(stream);
+			stream = NULL;
+			if (err == 0)
+				continue;
+			break;
+
+		case PRINT_NEWLINE_TO:
+			w = stream = POP();
+			/* fall through to PRINT_NEWLINE */
+
+		case PRINT_NEWLINE:
+			if (stream == NULL || stream == Py_None) {
+				w = PySys_GetObject("stdout");
+				if (w == NULL)
+					PyErr_SetString(PyExc_RuntimeError,
+							"lost sys.stdout");
+			}
+			if (w != NULL) {
+				err = PyFile_WriteString("\n", w);
+				if (err == 0)
+					PyFile_SoftSpace(w, 0);
+			}
+			Py_XDECREF(stream);
+			stream = NULL;
+			break;
+
+
+#ifdef CASE_TOO_BIG
+		default: switch (opcode) {
+#endif
+		case RAISE_VARARGS:
+			u = v = w = NULL;
+			switch (oparg) {
+			case 3:
+				u = POP(); /* traceback */
+				/* Fallthrough */
+			case 2:
+				v = POP(); /* value */
+				/* Fallthrough */
+			case 1:
+				w = POP(); /* exc */
+			case 0: /* Fallthrough */
+				why = do_raise(w, v, u);
+				break;
+			default:
+				PyErr_SetString(PyExc_SystemError,
+					   "bad RAISE_VARARGS oparg");
+				why = WHY_EXCEPTION;
+				break;
+			}
+			break;
+
+		case LOAD_LOCALS:
+			if ((x = f->f_locals) != NULL) {
+				Py_INCREF(x);
+				PUSH(x);
+				continue;
+			}
+			PyErr_SetString(PyExc_SystemError, "no locals");
+			break;
+
+		case RETURN_VALUE:
+			retval = POP();
+			why = WHY_RETURN;
+			goto fast_block_end;
+
+		case YIELD_VALUE:
+			retval = POP();
+			f->f_stacktop = stack_pointer;
+			why = WHY_YIELD;
+			goto fast_yield;
+
+		case EXEC_STMT:
+			w = TOP();
+			v = SECOND();
+			u = THIRD();
+			STACKADJ(-3);
+			READ_TIMESTAMP(intr0);
+			err = exec_statement(f, u, v, w);
+			READ_TIMESTAMP(intr1);
+			Py_DECREF(u);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			break;
+
+		case POP_BLOCK:
+			{
+				PyTryBlock *b = PyFrame_BlockPop(f);
+				while (STACK_LEVEL() > b->b_level) {
+					v = POP();
+					Py_DECREF(v);
+				}
+			}
+			continue;
+
+		case END_FINALLY:
+			v = POP();
+			if (PyInt_Check(v)) {
+				why = (enum why_code) PyInt_AS_LONG(v);
+				assert(why != WHY_YIELD);
+				if (why == WHY_RETURN ||
+				    why == WHY_CONTINUE)
+					retval = POP();
+			}
+			else if (PyExceptionClass_Check(v) || PyString_Check(v)) {
+				w = POP();
+				u = POP();
+				PyErr_Restore(v, w, u);
+				why = WHY_RERAISE;
+				break;
+			}
+			else if (v != Py_None) {
+				PyErr_SetString(PyExc_SystemError,
+					"'finally' pops bad exception");
+				why = WHY_EXCEPTION;
+			}
+			Py_DECREF(v);
+			break;
+
+		case BUILD_CLASS:
+			u = TOP();
+			v = SECOND();
+			w = THIRD();
+			STACKADJ(-2);
+			x = build_class(u, v, w);
+			SET_TOP(x);
+			Py_DECREF(u);
+			Py_DECREF(v);
+			Py_DECREF(w);
+			break;
+
+		case STORE_NAME:
+			w = GETITEM(names, oparg);
+			v = POP();
+			if ((x = f->f_locals) != NULL) {
+				if (PyDict_CheckExact(x))
+					err = PyDict_SetItem(x, w, v);
+				else
+					err = PyObject_SetItem(x, w, v);
+				Py_DECREF(v);
+				if (err == 0) continue;
+				break;
+			}
+			PyErr_Format(PyExc_SystemError,
+				     "no locals found when storing %s",
+				     PyObject_REPR(w));
+			break;
+
+		case DELETE_NAME:
+			w = GETITEM(names, oparg);
+			if ((x = f->f_locals) != NULL) {
+				if ((err = PyObject_DelItem(x, w)) != 0)
+					format_exc_check_arg(PyExc_NameError,
+								NAME_ERROR_MSG ,w);
+				break;
+			}
+			PyErr_Format(PyExc_SystemError,
+				     "no locals when deleting %s",
+				     PyObject_REPR(w));
+			break;
+
+		PREDICTED_WITH_ARG(UNPACK_SEQUENCE);
+		case UNPACK_SEQUENCE:
+			v = POP();
+			if (PyTuple_CheckExact(v) && PyTuple_GET_SIZE(v) == oparg) {
+				PyObject **items = ((PyTupleObject *)v)->ob_item;
+				while (oparg--) {
+					w = items[oparg];
+					Py_INCREF(w);
+					PUSH(w);
+				}
+				Py_DECREF(v);
+				continue;
+			} else if (PyList_CheckExact(v) && PyList_GET_SIZE(v) == oparg) {
+				PyObject **items = ((PyListObject *)v)->ob_item;
+				while (oparg--) {
+					w = items[oparg];
+					Py_INCREF(w);
+					PUSH(w);
+				}
+			} else if (unpack_iterable(v, oparg,
+						 stack_pointer + oparg))
+				stack_pointer += oparg;
+			else {
+				if (PyErr_ExceptionMatches(PyExc_TypeError))
+					PyErr_SetString(PyExc_TypeError,
+						"unpack non-sequence");
+				why = WHY_EXCEPTION;
+			}
+			Py_DECREF(v);
+			break;
+
+		case STORE_ATTR:
+			w = GETITEM(names, oparg);
+			v = TOP();
+			u = SECOND();
+			STACKADJ(-2);
+			err = PyObject_SetAttr(v, w, u); /* v.w = u */
+			Py_DECREF(v);
+			Py_DECREF(u);
+			if (err == 0) continue;
+			break;
+
+		case DELETE_ATTR:
+			w = GETITEM(names, oparg);
+			v = POP();
+			err = PyObject_SetAttr(v, w, (PyObject *)NULL);
+							/* del v.w */
+			Py_DECREF(v);
+			break;
+
+		case STORE_GLOBAL:
+			w = GETITEM(names, oparg);
+			v = POP();
+			err = PyDict_SetItem(f->f_globals, w, v);
+			Py_DECREF(v);
+			if (err == 0) continue;
+			break;
+
+		case DELETE_GLOBAL:
+			w = GETITEM(names, oparg);
+			if ((err = PyDict_DelItem(f->f_globals, w)) != 0)
+				format_exc_check_arg(
+				    PyExc_NameError, GLOBAL_NAME_ERROR_MSG, w);
+			break;
+
+		case LOAD_NAME:
+			w = GETITEM(names, oparg);
+			if ((v = f->f_locals) == NULL) {
+				PyErr_Format(PyExc_SystemError,
+					     "no locals when loading %s",
+					     PyObject_REPR(w));
+				break;
+			}
+			if (PyDict_CheckExact(v)) {
+				x = PyDict_GetItem(v, w);
+				Py_XINCREF(x);
+			}
+			else {
+				x = PyObject_GetItem(v, w);
+				if (x == NULL && PyErr_Occurred()) {
+					if (!PyErr_ExceptionMatches(PyExc_KeyError))
+						break;
+					PyErr_Clear();
+				}
+			}
+			if (x == NULL) {
+				x = PyDict_GetItem(f->f_globals, w);
+				if (x == NULL) {
+					x = PyDict_GetItem(f->f_builtins, w);
+					if (x == NULL) {
+						format_exc_check_arg(
+							    PyExc_NameError,
+							    NAME_ERROR_MSG ,w);
+						break;
+					}
+				}
+				Py_INCREF(x);
+			}
+			PUSH(x);
+			continue;
+
+		case LOAD_GLOBAL:
+			w = GETITEM(names, oparg);
+			if (PyString_CheckExact(w)) {
+				/* Inline the PyDict_GetItem() calls.
+				   WARNING: this is an extreme speed hack.
+				   Do not try this at home. */
+				long hash = ((PyStringObject *)w)->ob_shash;
+				if (hash != -1) {
+					PyDictObject *d;
+					PyDictEntry *e;
+					d = (PyDictObject *)(f->f_globals);
+					e = d->ma_lookup(d, w, hash);
+					if (e == NULL) {
+						x = NULL;
+						break;
+					}
+					x = e->me_value;
+					if (x != NULL) {
+						Py_INCREF(x);
+						PUSH(x);
+						continue;
+					}
+					d = (PyDictObject *)(f->f_builtins);
+					e = d->ma_lookup(d, w, hash);
+					if (e == NULL) {
+						x = NULL;
+						break;
+					}
+					x = e->me_value;
+					if (x != NULL) {
+						Py_INCREF(x);
+						PUSH(x);
+						continue;
+					}
+					goto load_global_error;
+				}
+			}
+			/* This is the un-inlined version of the code above */
+			x = PyDict_GetItem(f->f_globals, w);
+			if (x == NULL) {
+				x = PyDict_GetItem(f->f_builtins, w);
+				if (x == NULL) {
+				  load_global_error:
+					format_exc_check_arg(
+						    PyExc_NameError,
+						    GLOBAL_NAME_ERROR_MSG, w);
+					break;
+				}
+			}
+			Py_INCREF(x);
+			PUSH(x);
+			continue;
+
+		case DELETE_FAST:
+			x = GETLOCAL(oparg);
+			if (x != NULL) {
+				SETLOCAL(oparg, NULL);
+				continue;
+			}
+			format_exc_check_arg(
+				PyExc_UnboundLocalError,
+				UNBOUNDLOCAL_ERROR_MSG,
+				PyTuple_GetItem(co->co_varnames, oparg)
+				);
+			break;
+
+		case LOAD_CLOSURE:
+			x = freevars[oparg];
+			Py_INCREF(x);
+			PUSH(x);
+			if (x != NULL) continue;
+			break;
+
+		case LOAD_DEREF:
+			x = freevars[oparg];
+			w = PyCell_Get(x);
+			if (w != NULL) {
+				PUSH(w);
+				continue;
+			}
+			err = -1;
+			/* Don't stomp existing exception */
+			if (PyErr_Occurred())
+				break;
+			if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) {
+				v = PyTuple_GET_ITEM(co->co_cellvars,
+						       oparg);
+			       format_exc_check_arg(
+				       PyExc_UnboundLocalError,
+				       UNBOUNDLOCAL_ERROR_MSG,
+				       v);
+			} else {
+			       v = PyTuple_GET_ITEM(
+					      co->co_freevars,
+					      oparg - PyTuple_GET_SIZE(co->co_cellvars));
+			       format_exc_check_arg(
+				       PyExc_NameError,
+				       UNBOUNDFREE_ERROR_MSG,
+				       v);
+			}
+			break;
+
+		case STORE_DEREF:
+			w = POP();
+			x = freevars[oparg];
+			PyCell_Set(x, w);
+			Py_DECREF(w);
+			continue;
+
+		case BUILD_TUPLE:
+			x = PyTuple_New(oparg);
+			if (x != NULL) {
+				for (; --oparg >= 0;) {
+					w = POP();
+					PyTuple_SET_ITEM(x, oparg, w);
+				}
+				PUSH(x);
+				continue;
+			}
+			break;
+
+		case BUILD_LIST:
+			x =  PyList_New(oparg);
+			if (x != NULL) {
+				for (; --oparg >= 0;) {
+					w = POP();
+					PyList_SET_ITEM(x, oparg, w);
+				}
+				PUSH(x);
+				continue;
+			}
+			break;
+
+		case BUILD_MAP:
+			x = PyDict_New();
+			PUSH(x);
+			if (x != NULL) continue;
+			break;
+
+		case LOAD_ATTR:
+			w = GETITEM(names, oparg);
+			v = TOP();
+			x = PyObject_GetAttr(v, w);
+			Py_DECREF(v);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case COMPARE_OP:
+			w = POP();
+			v = TOP();
+			if (PyInt_CheckExact(w) && PyInt_CheckExact(v)) {
+				/* INLINE: cmp(int, int) */
+				register long a, b;
+				register int res;
+				a = PyInt_AS_LONG(v);
+				b = PyInt_AS_LONG(w);
+				switch (oparg) {
+				case PyCmp_LT: res = a <  b; break;
+				case PyCmp_LE: res = a <= b; break;
+				case PyCmp_EQ: res = a == b; break;
+				case PyCmp_NE: res = a != b; break;
+				case PyCmp_GT: res = a >  b; break;
+				case PyCmp_GE: res = a >= b; break;
+				case PyCmp_IS: res = v == w; break;
+				case PyCmp_IS_NOT: res = v != w; break;
+				default: goto slow_compare;
+				}
+				x = res ? Py_True : Py_False;
+				Py_INCREF(x);
+			}
+			else {
+			  slow_compare:
+				x = cmp_outcome(oparg, v, w);
+			}
+			Py_DECREF(v);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x == NULL) break;
+			PREDICT(JUMP_IF_FALSE);
+			PREDICT(JUMP_IF_TRUE);
+			continue;
+
+		case IMPORT_NAME:
+			w = GETITEM(names, oparg);
+			x = PyDict_GetItemString(f->f_builtins, "__import__");
+			if (x == NULL) {
+				PyErr_SetString(PyExc_ImportError,
+						"__import__ not found");
+				break;
+			}
+			v = POP();
+			u = TOP();
+			if (PyInt_AsLong(u) != -1 || PyErr_Occurred())
+				w = PyTuple_Pack(5,
+					    w,
+					    f->f_globals,
+					    f->f_locals == NULL ?
+						  Py_None : f->f_locals,
+					    v,
+					    u);
+			else
+				w = PyTuple_Pack(4,
+					    w,
+					    f->f_globals,
+					    f->f_locals == NULL ?
+						  Py_None : f->f_locals,
+					    v);
+			Py_DECREF(v);
+			Py_DECREF(u);
+			if (w == NULL) {
+				u = POP();
+				x = NULL;
+				break;
+			}
+			READ_TIMESTAMP(intr0);
+			x = PyEval_CallObject(x, w);
+			READ_TIMESTAMP(intr1);
+			Py_DECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case IMPORT_STAR:
+			v = POP();
+			PyFrame_FastToLocals(f);
+			if ((x = f->f_locals) == NULL) {
+				PyErr_SetString(PyExc_SystemError,
+					"no locals found during 'import *'");
+				break;
+			}
+			READ_TIMESTAMP(intr0);
+			err = import_all_from(x, v);
+			READ_TIMESTAMP(intr1);
+			PyFrame_LocalsToFast(f, 0);
+			Py_DECREF(v);
+			if (err == 0) continue;
+			break;
+
+		case IMPORT_FROM:
+			w = GETITEM(names, oparg);
+			v = TOP();
+			READ_TIMESTAMP(intr0);
+			x = import_from(v, w);
+			READ_TIMESTAMP(intr1);
+			PUSH(x);
+			if (x != NULL) continue;
+			break;
+
+		case JUMP_FORWARD:
+			JUMPBY(oparg);
+			goto fast_next_opcode;
+
+		PREDICTED_WITH_ARG(JUMP_IF_FALSE);
+		case JUMP_IF_FALSE:
+			w = TOP();
+			if (w == Py_True) {
+				PREDICT(POP_TOP);
+				goto fast_next_opcode;
+			}
+			if (w == Py_False) {
+				JUMPBY(oparg);
+				goto fast_next_opcode;
+			}
+			err = PyObject_IsTrue(w);
+			if (err > 0)
+				err = 0;
+			else if (err == 0)
+				JUMPBY(oparg);
+			else
+				break;
+			continue;
+
+		PREDICTED_WITH_ARG(JUMP_IF_TRUE);
+		case JUMP_IF_TRUE:
+			w = TOP();
+			if (w == Py_False) {
+				PREDICT(POP_TOP);
+				goto fast_next_opcode;
+			}
+			if (w == Py_True) {
+				JUMPBY(oparg);
+				goto fast_next_opcode;
+			}
+			err = PyObject_IsTrue(w);
+			if (err > 0) {
+				err = 0;
+				JUMPBY(oparg);
+			}
+			else if (err == 0)
+				;
+			else
+				break;
+			continue;
+
+		PREDICTED_WITH_ARG(JUMP_ABSOLUTE);
+		case JUMP_ABSOLUTE:
+			JUMPTO(oparg);
+			continue;
+
+		case GET_ITER:
+			/* before: [obj]; after [getiter(obj)] */
+			v = TOP();
+			x = PyObject_GetIter(v);
+			Py_DECREF(v);
+			if (x != NULL) {
+				SET_TOP(x);
+				PREDICT(FOR_ITER);
+				continue;
+			}
+			STACKADJ(-1);
+			break;
+
+		PREDICTED_WITH_ARG(FOR_ITER);
+		case FOR_ITER:
+			/* before: [iter]; after: [iter, iter()] *or* [] */
+			v = TOP();
+			x = (*v->ob_type->tp_iternext)(v);
+			if (x != NULL) {
+				PUSH(x);
+				PREDICT(STORE_FAST);
+				PREDICT(UNPACK_SEQUENCE);
+				continue;
+			}
+			if (PyErr_Occurred()) {
+				if (!PyErr_ExceptionMatches(PyExc_StopIteration))
+					break;
+				PyErr_Clear();
+			}
+			/* iterator ended normally */
+ 			x = v = POP();
+			Py_DECREF(v);
+			JUMPBY(oparg);
+			continue;
+
+		case BREAK_LOOP:
+			why = WHY_BREAK;
+			goto fast_block_end;
+
+		case CONTINUE_LOOP:
+			retval = PyInt_FromLong(oparg);
+			if (!retval) {
+				x = NULL;
+				break;
+			}
+			why = WHY_CONTINUE;
+			goto fast_block_end;
+
+		case SETUP_LOOP:
+		case SETUP_EXCEPT:
+		case SETUP_FINALLY:
+			/* NOTE: If you add any new block-setup opcodes that are not try/except/finally
+			   handlers, you may need to update the PyGen_NeedsFinalizing() function. */
+
+			PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg,
+					   STACK_LEVEL());
+			continue;
+
+		case WITH_CLEANUP:
+		{
+			/* TOP is the context.__exit__ bound method.
+			   Below that are 1-3 values indicating how/why
+			   we entered the finally clause:
+			   - SECOND = None
+			   - (SECOND, THIRD) = (WHY_{RETURN,CONTINUE}), retval
+			   - SECOND = WHY_*; no retval below it
+			   - (SECOND, THIRD, FOURTH) = exc_info()
+			   In the last case, we must call
+			     TOP(SECOND, THIRD, FOURTH)
+			   otherwise we must call
+			     TOP(None, None, None)
+
+			   In addition, if the stack represents an exception,
+			   *and* the function call returns a 'true' value, we
+			   "zap" this information, to prevent END_FINALLY from
+			   re-raising the exception.  (But non-local gotos
+			   should still be resumed.)
+			*/
+
+			x = TOP();
+			u = SECOND();
+			if (PyInt_Check(u) || u == Py_None) {
+				u = v = w = Py_None;
+			}
+			else {
+				v = THIRD();
+				w = FOURTH();
+			}
+			/* XXX Not the fastest way to call it... */
+			x = PyObject_CallFunctionObjArgs(x, u, v, w, NULL);
+			if (x == NULL)
+				break; /* Go to error exit */
+			if (u != Py_None && PyObject_IsTrue(x)) {
+				/* There was an exception and a true return */
+				Py_DECREF(x);
+				x = TOP(); /* Again */
+				STACKADJ(-3);
+				Py_INCREF(Py_None);
+				SET_TOP(Py_None);
+				Py_DECREF(x);
+				Py_DECREF(u);
+				Py_DECREF(v);
+				Py_DECREF(w);
+			} else {
+				/* Let END_FINALLY do its thing */
+				Py_DECREF(x);
+				x = POP();
+				Py_DECREF(x);
+			}
+			break;
+		}
+
+		case CALL_FUNCTION:
+		{
+			PyObject **sp;
+			PCALL(PCALL_ALL);
+			sp = stack_pointer;
+#ifdef WITH_TSC
+			x = call_function(&sp, oparg, &intr0, &intr1);
+#else
+			x = call_function(&sp, oparg);
+#endif
+			stack_pointer = sp;
+			PUSH(x);
+			if (x != NULL)
+				continue;
+			break;
+		}
+
+		case CALL_FUNCTION_VAR:
+		case CALL_FUNCTION_KW:
+		case CALL_FUNCTION_VAR_KW:
+		{
+		    int na = oparg & 0xff;
+		    int nk = (oparg>>8) & 0xff;
+		    int flags = (opcode - CALL_FUNCTION) & 3;
+		    int n = na + 2 * nk;
+		    PyObject **pfunc, *func, **sp;
+		    PCALL(PCALL_ALL);
+		    if (flags & CALL_FLAG_VAR)
+			    n++;
+		    if (flags & CALL_FLAG_KW)
+			    n++;
+		    pfunc = stack_pointer - n - 1;
+		    func = *pfunc;
+
+		    if (PyMethod_Check(func)
+			&& PyMethod_GET_SELF(func) != NULL) {
+			    PyObject *self = PyMethod_GET_SELF(func);
+			    Py_INCREF(self);
+			    func = PyMethod_GET_FUNCTION(func);
+			    Py_INCREF(func);
+			    Py_DECREF(*pfunc);
+			    *pfunc = self;
+			    na++;
+			    n++;
+		    } else
+			    Py_INCREF(func);
+		    sp = stack_pointer;
+		    READ_TIMESTAMP(intr0);
+		    x = ext_do_call(func, &sp, flags, na, nk);
+		    READ_TIMESTAMP(intr1);
+		    stack_pointer = sp;
+		    Py_DECREF(func);
+
+		    while (stack_pointer > pfunc) {
+			    w = POP();
+			    Py_DECREF(w);
+		    }
+		    PUSH(x);
+		    if (x != NULL)
+			    continue;
+		    break;
+		}
+
+		case MAKE_FUNCTION:
+			v = POP(); /* code object */
+			x = PyFunction_New(v, f->f_globals);
+			Py_DECREF(v);
+			/* XXX Maybe this should be a separate opcode? */
+			if (x != NULL && oparg > 0) {
+				v = PyTuple_New(oparg);
+				if (v == NULL) {
+					Py_DECREF(x);
+					x = NULL;
+					break;
+				}
+				while (--oparg >= 0) {
+					w = POP();
+					PyTuple_SET_ITEM(v, oparg, w);
+				}
+				err = PyFunction_SetDefaults(x, v);
+				Py_DECREF(v);
+			}
+			PUSH(x);
+			break;
+
+		case MAKE_CLOSURE:
+		{
+			v = POP(); /* code object */
+			x = PyFunction_New(v, f->f_globals);
+			Py_DECREF(v);
+			if (x != NULL) {
+				v = POP();
+				err = PyFunction_SetClosure(x, v);
+				Py_DECREF(v);
+			}
+			if (x != NULL && oparg > 0) {
+				v = PyTuple_New(oparg);
+				if (v == NULL) {
+					Py_DECREF(x);
+					x = NULL;
+					break;
+				}
+				while (--oparg >= 0) {
+					w = POP();
+					PyTuple_SET_ITEM(v, oparg, w);
+				}
+				err = PyFunction_SetDefaults(x, v);
+				Py_DECREF(v);
+			}
+			PUSH(x);
+			break;
+		}
+
+		case BUILD_SLICE:
+			if (oparg == 3)
+				w = POP();
+			else
+				w = NULL;
+			v = POP();
+			u = TOP();
+			x = PySlice_New(u, v, w);
+			Py_DECREF(u);
+			Py_DECREF(v);
+			Py_XDECREF(w);
+			SET_TOP(x);
+			if (x != NULL) continue;
+			break;
+
+		case EXTENDED_ARG:
+			opcode = NEXTOP();
+			oparg = oparg<<16 | NEXTARG();
+			goto dispatch_opcode;
+
+		default:
+			fprintf(stderr,
+				"XXX lineno: %d, opcode: %d\n",
+				PyCode_Addr2Line(f->f_code, f->f_lasti),
+				opcode);
+			PyErr_SetString(PyExc_SystemError, "unknown opcode");
+			why = WHY_EXCEPTION;
+			break;
+
+#ifdef CASE_TOO_BIG
+		}
+#endif
+
+		} /* switch */
+
+	    on_error:
+
+		READ_TIMESTAMP(inst1);
+
+		/* Quickly continue if no error occurred */
+
+		if (why == WHY_NOT) {
+			if (err == 0 && x != NULL) {
+#ifdef CHECKEXC
+				/* This check is expensive! */
+				if (PyErr_Occurred())
+					fprintf(stderr,
+						"XXX undetected error\n");
+				else {
+#endif
+					READ_TIMESTAMP(loop1);
+					continue; /* Normal, fast path */
+#ifdef CHECKEXC
+				}
+#endif
+			}
+			why = WHY_EXCEPTION;
+			x = Py_None;
+			err = 0;
+		}
+
+		/* Double-check exception status */
+
+		if (why == WHY_EXCEPTION || why == WHY_RERAISE) {
+			if (!PyErr_Occurred()) {
+				PyErr_SetString(PyExc_SystemError,
+					"error return without exception set");
+				why = WHY_EXCEPTION;
+			}
+		}
+#ifdef CHECKEXC
+		else {
+			/* This check is expensive! */
+			if (PyErr_Occurred()) {
+				char buf[1024];
+				sprintf(buf, "Stack unwind with exception "
+					"set and why=%d", why);
+				Py_FatalError(buf);
+			}
+		}
+#endif
+
+		/* Log traceback info if this is a real exception */
+
+		if (why == WHY_EXCEPTION) {
+			PyTraceBack_Here(f);
+
+			if (tstate->c_tracefunc != NULL)
+				call_exc_trace(tstate->c_tracefunc,
+					       tstate->c_traceobj, f);
+		}
+
+		/* For the rest, treat WHY_RERAISE as WHY_EXCEPTION */
+
+		if (why == WHY_RERAISE)
+			why = WHY_EXCEPTION;
+
+		/* Unwind stacks if a (pseudo) exception occurred */
+
+fast_block_end:
+		while (why != WHY_NOT && f->f_iblock > 0) {
+			PyTryBlock *b = PyFrame_BlockPop(f);
+
+			assert(why != WHY_YIELD);
+			if (b->b_type == SETUP_LOOP && why == WHY_CONTINUE) {
+				/* For a continue inside a try block,
+				   don't pop the block for the loop. */
+				PyFrame_BlockSetup(f, b->b_type, b->b_handler,
+						   b->b_level);
+				why = WHY_NOT;
+				JUMPTO(PyInt_AS_LONG(retval));
+				Py_DECREF(retval);
+				break;
+			}
+
+			while (STACK_LEVEL() > b->b_level) {
+				v = POP();
+				Py_XDECREF(v);
+			}
+			if (b->b_type == SETUP_LOOP && why == WHY_BREAK) {
+				why = WHY_NOT;
+				JUMPTO(b->b_handler);
+				break;
+			}
+			if (b->b_type == SETUP_FINALLY ||
+			    (b->b_type == SETUP_EXCEPT &&
+			     why == WHY_EXCEPTION)) {
+				if (why == WHY_EXCEPTION) {
+					PyObject *exc, *val, *tb;
+					PyErr_Fetch(&exc, &val, &tb);
+					if (val == NULL) {
+						val = Py_None;
+						Py_INCREF(val);
+					}
+					/* Make the raw exception data
+					   available to the handler,
+					   so a program can emulate the
+					   Python main loop.  Don't do
+					   this for 'finally'. */
+					if (b->b_type == SETUP_EXCEPT) {
+						PyErr_NormalizeException(
+							&exc, &val, &tb);
+						set_exc_info(tstate,
+							     exc, val, tb);
+					}
+					if (tb == NULL) {
+						Py_INCREF(Py_None);
+						PUSH(Py_None);
+					} else
+						PUSH(tb);
+					PUSH(val);
+					PUSH(exc);
+				}
+				else {
+					if (why & (WHY_RETURN | WHY_CONTINUE))
+						PUSH(retval);
+					v = PyInt_FromLong((long)why);
+					PUSH(v);
+				}
+				why = WHY_NOT;
+				JUMPTO(b->b_handler);
+				break;
+			}
+		} /* unwind stack */
+
+		/* End the loop if we still have an error (or return) */
+
+		if (why != WHY_NOT)
+			break;
+		READ_TIMESTAMP(loop1);
+
+	} /* main loop */
+
+	assert(why != WHY_YIELD);
+	/* Pop remaining stack entries. */
+	while (!EMPTY()) {
+		v = POP();
+		Py_XDECREF(v);
+	}
+
+	if (why != WHY_RETURN)
+		retval = NULL;
+
+fast_yield:
+	if (tstate->use_tracing) {
+		if (tstate->c_tracefunc) {
+			if (why == WHY_RETURN || why == WHY_YIELD) {
+				if (call_trace(tstate->c_tracefunc,
+					       tstate->c_traceobj, f,
+					       PyTrace_RETURN, retval)) {
+					Py_XDECREF(retval);
+					retval = NULL;
+					why = WHY_EXCEPTION;
+				}
+			}
+			else if (why == WHY_EXCEPTION) {
+				call_trace_protected(tstate->c_tracefunc,
+						     tstate->c_traceobj, f,
+						     PyTrace_RETURN, NULL);
+			}
+		}
+		if (tstate->c_profilefunc) {
+			if (why == WHY_EXCEPTION)
+				call_trace_protected(tstate->c_profilefunc,
+						     tstate->c_profileobj, f,
+						     PyTrace_RETURN, NULL);
+			else if (call_trace(tstate->c_profilefunc,
+					    tstate->c_profileobj, f,
+					    PyTrace_RETURN, retval)) {
+				Py_XDECREF(retval);
+				retval = NULL;
+				why = WHY_EXCEPTION;
+			}
+		}
+	}
+
+	if (tstate->frame->f_exc_type != NULL)
+		reset_exc_info(tstate);
+	else {
+		assert(tstate->frame->f_exc_value == NULL);
+		assert(tstate->frame->f_exc_traceback == NULL);
+	}
+
+	/* pop frame */
+    exit_eval_frame:
+	Py_LeaveRecursiveCall();
+	tstate->frame = f->f_back;
+
+	return retval;
+}
+
diff --git a/app/server/vendor/rouge/spec/visual/samples/clojure b/app/server/vendor/rouge/spec/visual/samples/clojure
new file mode 100755
index 0000000..493406a
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/clojure
@@ -0,0 +1,526 @@
+;;; dommy example
+
+(-> (sel1 :#my-button)
+    (remove-attr! :disabled)
+    do-something
+    (add-class! :action)
+    (listen! :click (fn [e] (js/console.log e)))))
+
+'#this-is-a-valid-symbol###
+
+;;; escape_semicolon.clj
+
+(= c (int \;)) (do (.readLine s) :line-start)
+
+;;; genclass.clj
+
+;   Copyright (c) Rich Hickey. All rights reserved.
+;   The use and distribution terms for this software are covered by the
+;   Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
+;   which can be found in the file CPL.TXT at the root of this distribution.
+;   By using this software in any fashion, you are agreeing to be bound by
+;   the terms of this license.
+;   You must not remove this notice, or any other, from this software.
+
+(in-ns 'clojure)
+
+(import '(java.lang.reflect Modifier Constructor)
+        '(clojure.asm ClassWriter ClassVisitor Opcodes Type)
+        '(clojure.asm.commons Method GeneratorAdapter)
+        '(clojure.lang IPersistentMap))
+
+;(defn method-sig [#^java.lang.reflect.Method meth]
+;  [(. meth (getName)) (seq (. meth (getParameterTypes)))])
+
+(defn- non-private-methods [#^Class c]
+  (loop [mm {}
+         considered #{}
+         c c]
+    (if c
+      (let [[mm considered]
+            (loop [mm mm
+                   considered considered
+                   meths (concat
+                          (seq (. c (getDeclaredMethods)))
+                          (seq (. c (getMethods))))]
+              (if meths
+                (let [#^Method meth (first meths)
+                      mods (. meth (getModifiers))
+                      mk (method-sig meth)]
+                  (if (or (considered mk)
+                          (. Modifier (isPrivate mods))
+                          (. Modifier (isStatic mods))
+                          (. Modifier (isFinal mods)))
+                    (recur mm (conj considered mk) (rest meths))
+                    (recur (assoc mm mk meth) (conj considered mk) (rest meths))))
+                [mm considered]))]
+        (recur mm considered (. c (getSuperclass))))
+      mm)))
+
+(defn- ctor-sigs [super]
+  (for [#^Constructor ctor (. super (getDeclaredConstructors))
+        :when (not (. Modifier (isPrivate (. ctor (getModifiers)))))]
+    (apply vector (. ctor (getParameterTypes)))))
+
+(defn- escape-class-name [c]
+  (.. (.getSimpleName c) 
+      (replace "[]" "<>")))
+
+(defn- overload-name [mname pclasses]
+  (if (seq pclasses)
+    (apply str mname (interleave (repeat \-) 
+                                 (map escape-class-name pclasses)))
+    (str mname "-void")))
+
+;(distinct (map first(keys (mapcat non-private-methods [Object IPersistentMap]))))
+
+(defn gen-class 
+  "Generates compiled bytecode for a class with the given
+  package-qualified cname (which, as all names in these parameters, can
+  be a string or symbol). The gen-class construct contains no
+  implementation, as the implementation will be dynamically sought by
+  the generated class in functions in a corresponding Clojure
+  namespace. Given a generated class org.mydomain.MyClass, methods
+  will be implemented that look for same-named functions in a Clojure
+  namespace called org.domain.MyClass. The init and main
+  functions (see below) will be found similarly. The static
+  initializer for the generated class will attempt to load the Clojure
+  support code for the class as a resource from the claspath, e.g. in
+  the example case, org/mydomain/MyClass.clj
+
+  Returns a map containing :name and :bytecode. Most uses will be
+  satisfied by the higher-level gen-and-load-class and
+  gen-and-store-class functions, which generate and immediately load,
+  or generate and store to disk, respectively.
+
+  Options should be a set of key/value pairs, all of which are optional:
+
+  :extends aclass
+
+  Specifies the superclass, the non-private methods of which will be
+  overridden by the class. If not provided, defaults to Object.
+
+  :implements [interface ...]
+
+  One or more interfaces, the methods of which will be implemented by the class.
+
+  :init name
+
+  If supplied, names a function that will be called with the arguments
+  to the constructor. Must return [[superclass-constructor-args] state] 
+  If not supplied, the constructor args are passed directly to
+  the superclass constructor and the state will be nil
+
+  :constructors {[param-types] [super-param-types], ...}
+
+  By default, constructors are created for the generated class which
+  match the signature(s) of the constructors for the superclass. This
+  parameter may be used to explicitly specify constructors, each entry
+  providing a mapping from a constructor signature to a superclass
+  constructor signature. When you supply this, you must supply an :init
+  specifier.
+
+  :methods [[name [param-types] return-type], ...]
+
+  The generated class automatically defines all of the non-private
+  methods of its superclasses/interfaces. This parameter can be used
+  to specify the signatures of additional methods of the generated
+  class. Do not repeat superclass/interface signatures here.
+
+  :main boolean
+
+  If supplied and true, a static public main function will be
+  generated. It will pass each string of the String[] argument as a
+  separate argument to a function called 'main.
+
+  :factory name
+
+  If supplied, a (set of) public static factory function(s) will be
+  created with the given name, and the same signature(s) as the
+  constructor(s).
+  
+  :state name
+
+  If supplied, a public final instance field with the given name will be
+  created. You must supply an :init function in order to provide a
+  value for the state. Note that, though final, the state can be a ref
+  or agent, supporting the creation of Java objects with transactional
+  or asynchronous mutation semantics.
+
+  :exposes {protected-field-name {:get name :set name}, ...}
+
+  Since the implementations of the methods of the generated class
+  occur in Clojure functions, they have no access to the inherited
+  protected fields of the superclass. This parameter can be used to
+  generate public getter/setter methods exposing the protected field(s)
+  for use in the implementation."
+
+  [cname & options]
+  (let [name (str cname)
+        {:keys [extends implements constructors methods main factory state init exposes]} (apply hash-map options)
+        super (or extends Object)
+        interfaces implements
+        supers (cons super (seq interfaces))
+        ctor-sig-map (or constructors (zipmap (ctor-sigs super) (ctor-sigs super)))
+        cv (new ClassWriter (. ClassWriter COMPUTE_MAXS))
+        cname (. name (replace "." "/"))
+        ctype (. Type (getObjectType cname))
+        iname (fn [c] (.. Type (getType c) (getInternalName)))
+        totype (fn [c] (. Type (getType c)))
+        to-types (fn [cs] (if (pos? (count cs))
+                            (into-array (map totype cs))
+                            (make-array Type 0)))
+        obj-type (totype Object)
+        arg-types (fn [n] (if (pos? n)
+                            (into-array (replicate n obj-type))
+                            (make-array Type 0)))
+        super-type (totype super)
+        init-name (str init)
+        factory-name (str factory)
+        state-name (str state)
+        main-name "main"
+        var-name (fn [s] (str s "__var"))
+        rt-type  (totype clojure.lang.RT)
+        var-type  (totype clojure.lang.Var)
+        ifn-type (totype clojure.lang.IFn)
+        iseq-type (totype clojure.lang.ISeq)
+        ex-type  (totype java.lang.UnsupportedOperationException)
+        all-sigs (distinct (concat (map #(let[[m p] (key %)] {m [p]}) (mapcat non-private-methods supers))
+                                   (map (fn [[m p]] {(str m) [p]}) methods)))
+        sigs-by-name (apply merge-with concat {} all-sigs)
+        overloads (into {} (filter (fn [[m s]] (rest s)) sigs-by-name))
+        var-fields (concat (and init [init-name]) 
+                           (and main [main-name])
+                           (distinct (concat (keys sigs-by-name)
+                                             (mapcat (fn [[m s]] (map #(overload-name m %) s)) overloads)
+                                             (mapcat (comp (partial map str) vals val) exposes))))
+        emit-get-var (fn [gen v]
+                       (let [false-label (. gen newLabel)
+                             end-label (. gen newLabel)]
+                         (. gen getStatic ctype (var-name v) var-type)
+                         (. gen dup)
+                         (. gen invokeVirtual var-type (. Method (getMethod "boolean isBound()")))
+                         (. gen ifZCmp (. GeneratorAdapter EQ) false-label)
+                         (. gen invokeVirtual var-type (. Method (getMethod "Object get()")))
+                         (. gen goTo end-label)
+                         (. gen mark false-label)
+                         (. gen pop)
+                         (. gen visitInsn (. Opcodes ACONST_NULL))
+                         (. gen mark end-label)))
+        emit-forwarding-method
+        (fn [mname pclasses rclass else-gen]
+          (let [ptypes (to-types pclasses)
+                rtype (totype rclass)
+                m (new Method mname rtype ptypes)
+                is-overload (overloads mname)
+                gen (new GeneratorAdapter (. Opcodes ACC_PUBLIC) m nil nil cv)
+                found-label (. gen (newLabel))
+                else-label (. gen (newLabel))
+                end-label (. gen (newLabel))]
+            (. gen (visitCode))
+            (when is-overload
+              (emit-get-var gen (overload-name mname pclasses))
+              (. gen (dup))
+              (. gen (ifNonNull found-label))
+              (. gen (pop)))
+            (emit-get-var gen mname)
+            (. gen (dup))
+            (. gen (ifNull else-label))
+            (when is-overload
+              (. gen (mark found-label)))
+                                        ;if found
+            (. gen (loadThis))
+                                        ;box args
+            (dotimes i (count ptypes)
+              (. gen (loadArg i))
+              (. clojure.lang.Compiler$HostExpr (emitBoxReturn nil gen (nth pclasses i))))
+                                        ;call fn
+            (. gen (invokeInterface ifn-type (new Method "invoke" obj-type 
+                                                  (into-array (cons obj-type 
+                                                                    (replicate (count ptypes) obj-type))))))
+                                        ;unbox return
+            (. gen (unbox rtype))
+            (when (= (. rtype (getSort)) (. Type VOID))
+              (. gen (pop)))
+            (. gen (goTo end-label))
+            
+                                        ;else call supplied alternative generator
+            (. gen (mark else-label))
+            (. gen (pop))
+            
+            (else-gen gen m)
+            
+            (. gen (mark end-label))
+            (. gen (returnValue))
+            (. gen (endMethod))))
+        ]
+                                        ;start class definition
+    (. cv (visit (. Opcodes V1_5) (. Opcodes ACC_PUBLIC)
+                 cname nil (iname super)
+                 (when interfaces
+                   (into-array (map iname interfaces)))))
+    
+                                        ;static fields for vars
+    (doseq v var-fields
+      (. cv (visitField (+ (. Opcodes ACC_PUBLIC) (. Opcodes ACC_FINAL) (. Opcodes ACC_STATIC))
+                        (var-name v) 
+                        (. var-type getDescriptor)
+                        nil nil)))
+    
+                                        ;instance field for state
+    (when state
+      (. cv (visitField (+ (. Opcodes ACC_PUBLIC) (. Opcodes ACC_FINAL))
+                        state-name 
+                        (. obj-type getDescriptor)
+                        nil nil)))
+    
+                                        ;static init to set up var fields and load clj
+    (let [gen (new GeneratorAdapter (+ (. Opcodes ACC_PUBLIC) (. Opcodes ACC_STATIC)) 
+                   (. Method getMethod "void <clinit> ()")
+                   nil nil cv)]
+      (. gen (visitCode))
+      (doseq v var-fields
+        (. gen push name)
+        (. gen push v)
+        (. gen (invokeStatic rt-type (. Method (getMethod "clojure.lang.Var var(String,String)"))))
+        (. gen putStatic ctype (var-name v) var-type))
+      
+      (. gen push ctype)
+      (. gen push (str (. name replace \. (. java.io.File separatorChar)) ".clj"))
+      (. gen (invokeStatic rt-type (. Method (getMethod "void loadResourceScript(Class,String)"))))
+      
+      (. gen (returnValue))
+      (. gen (endMethod)))
+    
+                                        ;ctors
+    (doseq [pclasses super-pclasses] ctor-sig-map
+      (let [ptypes (to-types pclasses)
+            super-ptypes (to-types super-pclasses)
+            m (new Method "<init>" (. Type VOID_TYPE) ptypes)
+            super-m (new Method "<init>" (. Type VOID_TYPE) super-ptypes)
+            gen (new GeneratorAdapter (. Opcodes ACC_PUBLIC) m nil nil cv)
+            no-init-label (. gen newLabel)
+            end-label (. gen newLabel)
+            nth-method (. Method (getMethod "Object nth(Object,int)"))
+            local (. gen newLocal obj-type)]
+        (. gen (visitCode))
+        
+        (if init
+          (do
+            (emit-get-var gen init-name)
+            (. gen dup)
+            (. gen ifNull no-init-label)
+                                        ;box init args
+            (dotimes i (count pclasses)
+              (. gen (loadArg i))
+              (. clojure.lang.Compiler$HostExpr (emitBoxReturn nil gen (nth pclasses i))))
+                                        ;call init fn
+            (. gen (invokeInterface ifn-type (new Method "invoke" obj-type 
+                                                  (arg-types (count ptypes)))))
+                                        ;expecting [[super-ctor-args] state] returned
+            (. gen dup)
+            (. gen push 0)
+            (. gen (invokeStatic rt-type nth-method))
+            (. gen storeLocal local)
+            
+            (. gen (loadThis))
+            (. gen dupX1)
+            (dotimes i (count super-pclasses)
+              (. gen loadLocal local)
+              (. gen push i)
+              (. gen (invokeStatic rt-type nth-method))
+              (. clojure.lang.Compiler$HostExpr (emitUnboxArg nil gen (nth super-pclasses i))))
+            (. gen (invokeConstructor super-type super-m))
+            
+            (if state
+              (do
+                (. gen push 1)
+                (. gen (invokeStatic rt-type nth-method))
+                (. gen (putField ctype state-name obj-type)))
+              (. gen pop))
+            
+            (. gen goTo end-label)
+                                        ;no init found
+            (. gen mark no-init-label)
+            (. gen (throwException ex-type (str init-name " not defined")))
+            (. gen mark end-label))
+          (if (= pclasses super-pclasses)
+            (do
+              (. gen (loadThis))
+              (. gen (loadArgs))
+              (. gen (invokeConstructor super-type super-m)))
+            (throw (new Exception ":init not specified, but ctor and super ctor args differ"))))
+
+        (. gen (returnValue))
+        (. gen (endMethod))
+                                        ;factory
+        (when factory
+          (let [fm (new Method factory-name ctype ptypes)
+                gen (new GeneratorAdapter (+ (. Opcodes ACC_PUBLIC) (. Opcodes ACC_STATIC)) 
+                         fm nil nil cv)]
+            (. gen (visitCode))
+            (. gen newInstance ctype)
+            (. gen dup)
+            (. gen (loadArgs))
+            (. gen (invokeConstructor ctype m))            
+            (. gen (returnValue))
+            (. gen (endMethod))))))
+    
+                                        ;add methods matching supers', if no fn -> call super
+    (let [mm (non-private-methods super)]
+      (doseq #^java.lang.reflect.Method meth (vals mm)
+             (emit-forwarding-method (.getName meth) (.getParameterTypes meth) (.getReturnType meth) 
+                                     (fn [gen m]
+                                       (. gen (loadThis))
+                                        ;push args
+                                       (. gen (loadArgs))
+                                        ;call super
+                                       (. gen (visitMethodInsn (. Opcodes INVOKESPECIAL) 
+                                                               (. super-type (getInternalName))
+                                                               (. m (getName))
+                                                               (. m (getDescriptor)))))))
+                                        ;add methods matching interfaces', if no fn -> throw
+       (doseq #^Class iface interfaces
+              (doseq #^java.lang.reflect.Method meth (. iface (getMethods))
+                     (when-not (contains? mm (method-sig meth))
+                       (emit-forwarding-method (.getName meth) (.getParameterTypes meth) (.getReturnType meth) 
+                                               (fn [gen m]
+                                                 (. gen (throwException ex-type (. m (getName)))))))))
+                                        ;extra methods
+       (doseq [mname pclasses rclass :as msig] methods
+         (emit-forwarding-method (str mname) pclasses rclass 
+                                 (fn [gen m]
+                                     (. gen (throwException ex-type (. m (getName))))))))
+
+                                        ;main
+    (when main
+      (let [m (. Method getMethod "void main (String[])")
+            gen (new GeneratorAdapter (+ (. Opcodes ACC_PUBLIC) (. Opcodes ACC_STATIC)) 
+                     m nil nil cv)
+            no-main-label (. gen newLabel)
+            end-label (. gen newLabel)]
+        (. gen (visitCode))
+
+        (emit-get-var gen main-name)
+        (. gen dup)
+        (. gen ifNull no-main-label)
+        (. gen loadArgs)
+        (. gen (invokeStatic rt-type (. Method (getMethod "clojure.lang.ISeq seq(Object)"))))
+        (. gen (invokeInterface ifn-type (new Method "applyTo" obj-type 
+                                              (into-array [iseq-type]))))
+        (. gen pop)
+        (. gen goTo end-label)
+                                        ;no main found
+        (. gen mark no-main-label)
+        (. gen (throwException ex-type (str main-name " not defined")))
+        (. gen mark end-label)
+        (. gen (returnValue))
+        (. gen (endMethod))))
+                                        ;field exposers
+    (doseq [f {getter :get setter :set}] exposes
+      (let [fld (.getField super (str f))
+            ftype (totype (.getType fld))]
+        (when getter
+          (let [m (new Method (str getter) ftype (to-types []))
+                gen (new GeneratorAdapter (. Opcodes ACC_PUBLIC) m nil nil cv)]
+            (. gen (visitCode))
+            (. gen loadThis)
+            (. gen getField ctype (str f) ftype)
+            (. gen (returnValue))
+            (. gen (endMethod))))
+        (when setter
+          (let [m (new Method (str setter) (. Type VOID_TYPE) (into-array [ftype]))
+                gen (new GeneratorAdapter (. Opcodes ACC_PUBLIC) m nil nil cv)]
+            (. gen (visitCode))
+            (. gen loadThis)
+            (. gen loadArgs)
+            (. gen putField ctype (str f) ftype)
+            (. gen (returnValue))
+            (. gen (endMethod))))))
+                                        ;finish class def
+    (. cv (visitEnd))
+    {:name name :bytecode (. cv (toByteArray))}))
+
+(defn gen-and-load-class 
+  "Generates and immediately loads the bytecode for the specified
+  class. Note that a class generated this way can be loaded only once
+  - the JVM supports only one class with a given name per
+  classloader. Subsequent to generation you can import it into any
+  desired namespaces just like any other class. See gen-class for a
+  description of the options."
+
+  [name & options]
+  (let [{:keys [name bytecode]}
+        (apply gen-class (str name) options)]
+    (.. clojure.lang.RT ROOT_CLASSLOADER (defineClass (str name) bytecode))))
+
+(defn gen-and-save-class 
+  "Generates the bytecode for the named class and stores in a .class
+  file in a subpath of the supplied path, the directories for which
+  must already exist. See gen-class for a description of the options"
+
+  [path name & options]
+  (let [{:keys [name bytecode]} (apply gen-class (str name) options)
+        file (java.io.File. path (str (. name replace \. (. java.io.File separatorChar)) ".class"))]
+    (.createNewFile file)
+    (with-open f (java.io.FileOutputStream. file)
+      (.write f bytecode))))
+
+(comment
+;usage
+(gen-class 
+ package-qualified-name
+  ;all below are optional
+ :extends aclass
+ :implements [interface ...]
+ :constructors {[param-types] [super-param-types], }
+ :methods [[name [param-types] return-type], ]
+ :main boolean
+ :factory name
+ :state name
+ :init name
+ :exposes {protected-field {:get name :set name}, })
+ 
+;(gen-and-load-class 
+(clojure/gen-and-save-class 
+ "/Users/rich/Downloads"
+ 'fred.lucy.Ethel 
+ :extends clojure.lang.Box ;APersistentMap
+ :implements [clojure.lang.IPersistentMap]
+ :state 'state
+                                        ;:constructors {[Object] [Object]}
+                                        ;:init 'init
+ :main true
+ :factory 'create
+ :methods [['foo [Object] Object]
+           ['foo [] Object]]
+ :exposes {'val {:get 'getVal :set 'setVal}})
+
+(in-ns 'fred.lucy.Ethel__2276)
+(clojure/refer 'clojure :exclude '(assoc seq count cons))
+(defn init [n] [[] n])
+(defn foo 
+  ([this] :foo) 
+  ([this x] x))
+(defn main [x y] (println x y))
+(in-ns 'user)
+(def ethel (new fred.lucy.Ethel__2276 42))
+(def ethel (fred.lucy.Ethel__2276.create 21))
+(fred.lucy.Ethel__2276.main (into-array ["lucy" "ricky"]))
+(.state ethel)
+(.foo ethel 7)
+(.foo ethel)
+(.getVal ethel)
+(.setVal ethel 12)
+
+(gen-class org.clojure.MyComparator :implements [Comparator])
+(in-ns 'org.clojure.MyComparator)
+(defn compare [this x y] ...)
+
+(load-file "/Users/rich/dev/clojure/src/genclass.clj")
+
+(clojure/gen-and-save-class "/Users/rich/dev/clojure/gen/" 
+ 'org.clojure.ClojureServlet 
+ :extends javax.servlet.http.HttpServlet)
+
+)
diff --git a/app/server/vendor/rouge/spec/visual/samples/coffeescript b/app/server/vendor/rouge/spec/visual/samples/coffeescript
new file mode 100755
index 0000000..5e2225f
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/coffeescript
@@ -0,0 +1,733 @@
+###
+a multiline comment
+###
+
+{ property         : 1 }
+
+# these shouldn't be highlighted as constants, since this is
+# totally legit in coffeescript
+{ true: 1, false: 0 }
+foo.true = foo.false = @undefined = @null
+{ if: 0, try: 1, in: 2 }
+foo.instanceof = foo.typeof = @finally = @super
+
+# these should
+{ 1: true, 0: false }
+1 instanceof Number
+typeof "foo"
+
+# these refer to builtins
+window.foo = bar(Array)
+
+# these are properties
+foo.window = bar.Array
+
+# The CoffeeScript Lexer. Uses a series of token-matching regexes to attempt
+# matches against the beginning of the source code. When a match is found,
+# a token is produced, we consume the match, and start again. Tokens are in the
+# form:
+#
+#     [tag, value, lineNumber]
+#
+# Which is a format that can be fed directly into [Jison](http://github.com/zaach/jison).
+
+{Rewriter, INVERSES} = require './rewriter'
+
+# Import the helpers we need.
+{count, starts, compact, last} = require './helpers'
+
+# The Lexer Class
+# ---------------
+
+# The Lexer class reads a stream of CoffeeScript and divvies it up into tagged
+# tokens. Some potential ambiguity in the grammar has been avoided by
+# pushing some extra smarts into the Lexer.
+exports.Lexer = class Lexer
+
+  # **tokenize** is the Lexer's main method. Scan by attempting to match tokens
+  # one at a time, using a regular expression anchored at the start of the
+  # remaining code, or a custom recursive token-matching method
+  # (for interpolations). When the next token has been recorded, we move forward
+  # within the code past the token, and begin again.
+  #
+  # Each tokenizing method is responsible for returning the number of characters
+  # it has consumed.
+  #
+  # Before returning the token stream, run it through the [Rewriter](rewriter.html)
+  # unless explicitly asked not to.
+  tokenize: (code, opts = {}) ->
+    code     = "\n#{code}" if WHITESPACE.test code
+    code     = code.replace(/\r/g, '').replace TRAILING_SPACES, ''
+
+    @code    = code           # The remainder of the source code.
+    @line    = opts.line or 0 # The current line.
+    @indent  = 0              # The current indentation level.
+    @indebt  = 0              # The over-indentation at the current level.
+    @outdebt = 0              # The under-outdentation at the current level.
+    @indents = []             # The stack of all current indentation levels.
+    @ends    = []             # The stack for pairing up tokens.
+    @tokens  = []             # Stream of parsed tokens in the form `['TYPE', value, line]`.
+
+    # At every position, run through this list of attempted matches,
+    # short-circuiting if any of them succeed. Their order determines precedence:
+    # `@literalToken` is the fallback catch-all.
+    i = 0
+    while @chunk = code[i..]
+      i += @identifierToken() or
+           @commentToken()    or
+           @whitespaceToken() or
+           @lineToken()       or
+           @heredocToken()    or
+           @stringToken()     or
+           @numberToken()     or
+           @regexToken()      or
+           @jsToken()         or
+           @literalToken()
+
+    @closeIndentation()
+    @error "missing #{tag}" if tag = @ends.pop()
+    return @tokens if opts.rewrite is off
+    (new Rewriter).rewrite @tokens
+
+  # Tokenizers
+  # ----------
+
+  # Matches identifying literals: variables, keywords, method names, etc.
+  # Check to ensure that JavaScript reserved words aren't being used as
+  # identifiers. Because CoffeeScript reserves a handful of keywords that are
+  # allowed in JavaScript, we're careful not to tag them as keywords when
+  # referenced as property names here, so you can still do `jQuery.is()` even
+  # though `is` means `===` otherwise.
+  identifierToken: ->
+    return 0 unless match = IDENTIFIER.exec @chunk
+    [input, id, colon] = match
+
+    if id is 'own' and @tag() is 'FOR'
+      @token 'OWN', id
+      return id.length
+    forcedIdentifier = colon or
+      (prev = last @tokens) and (prev[0] in ['.', '?.', '::'] or
+      not prev.spaced and prev[0] is '@')
+    tag = 'IDENTIFIER'
+
+    if not forcedIdentifier and (id in JS_KEYWORDS or id in COFFEE_KEYWORDS)
+      tag = id.toUpperCase()
+      if tag is 'WHEN' and @tag() in LINE_BREAK
+        tag = 'LEADING_WHEN'
+      else if tag is 'FOR'
+        @seenFor = yes
+      else if tag is 'UNLESS'
+        tag = 'IF'
+      else if tag in UNARY
+        tag = 'UNARY'
+      else if tag in RELATION
+        if tag isnt 'INSTANCEOF' and @seenFor
+          tag = 'FOR' + tag
+          @seenFor = no
+        else
+          tag = 'RELATION'
+          if @value() is '!'
+            @tokens.pop()
+            id = '!' + id
+
+    if id in JS_FORBIDDEN
+      if forcedIdentifier
+        tag = 'IDENTIFIER'
+        id  = new String id
+        id.reserved = yes
+      else if id in RESERVED
+        @error "reserved word \"#{id}\""
+
+    unless forcedIdentifier
+      id  = COFFEE_ALIAS_MAP[id] if id in COFFEE_ALIASES
+      tag = switch id
+        when '!'                 then 'UNARY'
+        when '==', '!='          then 'COMPARE'
+        when '&&', '||'          then 'LOGIC'
+        when 'true', 'false'     then 'BOOL'
+        when 'break', 'continue' then 'STATEMENT'
+        else  tag
+
+    @token tag, id
+    @token ':', ':' if colon
+    input.length
+
+  # Matches numbers, including decimals, hex, and exponential notation.
+  # Be careful not to interfere with ranges-in-progress.
+  numberToken: ->
+    return 0 unless match = NUMBER.exec @chunk
+    number = match[0]
+    if /^0[BOX]/.test number
+      @error "radix prefix '#{number}' must be lowercase"
+    else if /E/.test(number) and not /^0x/.test number
+      @error "exponential notation '#{number}' must be indicated with a lowercase 'e'"
+    else if /^0\d*[89]/.test number
+      @error "decimal literal '#{number}' must not be prefixed with '0'"
+    else if /^0\d+/.test number
+      @error "octal literal '#{number}' must be prefixed with '0o'"
+    lexedLength = number.length
+    if octalLiteral = /^0o([0-7]+)/.exec number
+      number = '0x' + (parseInt octalLiteral[1], 8).toString 16
+    if binaryLiteral = /^0b([01]+)/.exec number
+      number = '0x' + (parseInt binaryLiteral[1], 2).toString 16
+    @token 'NUMBER', number
+    lexedLength
+
+  # Matches strings, including multi-line strings. Ensures that quotation marks
+  # are balanced within the string's contents, and within nested interpolations.
+  stringToken: ->
+    switch @chunk.charAt 0
+      when "'"
+        return 0 unless match = SIMPLESTR.exec @chunk
+        @token 'STRING', (string = match[0]).replace MULTILINER, '\\\n'
+      when '"'
+        return 0 unless string = @balancedString @chunk, '"'
+        if 0 < string.indexOf '#{', 1
+          @interpolateString string[1...-1]
+        else
+          @token 'STRING', @escapeLines string
+      else
+        return 0
+    if octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test string
+      @error "octal escape sequences #{string} are not allowed"
+    @line += count string, '\n'
+    string.length
+
+  # Matches heredocs, adjusting indentation to the correct level, as heredocs
+  # preserve whitespace, but ignore indentation to the left.
+  heredocToken: ->
+    return 0 unless match = HEREDOC.exec @chunk
+    heredoc = match[0]
+    quote = heredoc.charAt 0
+    doc = @sanitizeHeredoc match[2], quote: quote, indent: null
+    if quote is '"' and 0 <= doc.indexOf '#{'
+      @interpolateString doc, heredoc: yes
+    else
+      @token 'STRING', @makeString doc, quote, yes
+    @line += count heredoc, '\n'
+    heredoc.length
+
+  # Matches and consumes comments.
+  commentToken: ->
+    return 0 unless match = @chunk.match COMMENT
+    [comment, here] = match
+    if here
+      @token 'HERECOMMENT', @sanitizeHeredoc here,
+        herecomment: true, indent: Array(@indent + 1).join(' ')
+    @line += count comment, '\n'
+    comment.length
+
+  # Matches JavaScript interpolated directly into the source via backticks.
+  jsToken: ->
+    return 0 unless @chunk.charAt(0) is '`' and match = JSTOKEN.exec @chunk
+    @token 'JS', (script = match[0])[1...-1]
+    @line += count script, '\n'
+    script.length
+
+  # Matches regular expression literals. Lexing regular expressions is difficult
+  # to distinguish from division, so we borrow some basic heuristics from
+  # JavaScript and Ruby.
+  regexToken: ->
+    return 0 if @chunk.charAt(0) isnt '/'
+    if match = HEREGEX.exec @chunk
+      length = @heregexToken match
+      @line += count match[0], '\n'
+      return length
+
+    prev = last @tokens
+    return 0 if prev and (prev[0] in (if prev.spaced then NOT_REGEX else NOT_SPACED_REGEX))
+    return 0 unless match = REGEX.exec @chunk
+    [match, regex, flags] = match
+    if regex[..1] is '/*' then @error 'regular expressions cannot begin with `*`'
+    if regex is '//' then regex = '/(?:)/'
+    @token 'REGEX', "#{regex}#{flags}"
+    match.length
+
+  # Matches multiline extended regular expressions.
+  heregexToken: (match) ->
+    [heregex, body, flags] = match
+    if 0 > body.indexOf '#{'
+      re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/')
+      if re.match /^\*/ then @error 'regular expressions cannot begin with `*`'
+      @token 'REGEX', "/#{ re or '(?:)' }/#{flags}"
+      return heregex.length
+    @token 'IDENTIFIER', 'RegExp'
+    @tokens.push ['CALL_START', '(']
+    tokens = []
+    for [tag, value] in @interpolateString(body, regex: yes)
+      if tag is 'TOKENS'
+        tokens.push value...
+      else
+        continue unless value = value.replace HEREGEX_OMIT, ''
+        value = value.replace /\\/g, '\\\\'
+        tokens.push ['STRING', @makeString(value, '"', yes)]
+      tokens.push ['+', '+']
+    tokens.pop()
+    @tokens.push ['STRING', '""'], ['+', '+'] unless tokens[0]?[0] is 'STRING'
+    @tokens.push tokens...
+    @tokens.push [',', ','], ['STRING', '"' + flags + '"'] if flags
+    @token ')', ')'
+    heregex.length
+
+  # Matches newlines, indents, and outdents, and determines which is which.
+  # If we can detect that the current line is continued onto the the next line,
+  # then the newline is suppressed:
+  #
+  #     elements
+  #       .each( ... )
+  #       .map( ... )
+  #
+  # Keeps track of the level of indentation, because a single outdent token
+  # can close multiple indents, so we need to know how far in we happen to be.
+  lineToken: ->
+    return 0 unless match = MULTI_DENT.exec @chunk
+    indent = match[0]
+    @line += count indent, '\n'
+    @seenFor = no
+    size = indent.length - 1 - indent.lastIndexOf '\n'
+    noNewlines = @unfinished()
+    if size - @indebt is @indent
+      if noNewlines then @suppressNewlines() else @newlineToken()
+      return indent.length
+    if size > @indent
+      if noNewlines
+        @indebt = size - @indent
+        @suppressNewlines()
+        return indent.length
+      diff = size - @indent + @outdebt
+      @token 'INDENT', diff
+      @indents.push diff
+      @ends.push 'OUTDENT'
+      @outdebt = @indebt = 0
+    else
+      @indebt = 0
+      @outdentToken @indent - size, noNewlines
+    @indent = size
+    indent.length
+
+  # Record an outdent token or multiple tokens, if we happen to be moving back
+  # inwards past several recorded indents.
+  outdentToken: (moveOut, noNewlines) ->
+    while moveOut > 0
+      len = @indents.length - 1
+      if @indents[len] is undefined
+        moveOut = 0
+      else if @indents[len] is @outdebt
+        moveOut -= @outdebt
+        @outdebt = 0
+      else if @indents[len] < @outdebt
+        @outdebt -= @indents[len]
+        moveOut  -= @indents[len]
+      else
+        dent = @indents.pop() - @outdebt
+        moveOut -= dent
+        @outdebt = 0
+        @pair 'OUTDENT'
+        @token 'OUTDENT', dent
+    @outdebt -= moveOut if dent
+    @tokens.pop() while @value() is ';'
+    @token 'TERMINATOR', '\n' unless @tag() is 'TERMINATOR' or noNewlines
+    this
+
+  # Matches and consumes non-meaningful whitespace. Tag the previous token
+  # as being "spaced", because there are some cases where it makes a difference.
+  whitespaceToken: ->
+    return 0 unless (match = WHITESPACE.exec @chunk) or
+                    (nline = @chunk.charAt(0) is '\n')
+    prev = last @tokens
+    prev[if match then 'spaced' else 'newLine'] = true if prev
+    if match then match[0].length else 0
+
+  # Generate a newline token. Consecutive newlines get merged together.
+  newlineToken: ->
+    @tokens.pop() while @value() is ';'
+    @token 'TERMINATOR', '\n' unless @tag() is 'TERMINATOR'
+    this
+
+  # Use a `\` at a line-ending to suppress the newline.
+  # The slash is removed here once its job is done.
+  suppressNewlines: ->
+    @tokens.pop() if @value() is '\\'
+    this
+
+  # We treat all other single characters as a token. E.g.: `( ) , . !`
+  # Multi-character operators are also literal tokens, so that Jison can assign
+  # the proper order of operations. There are some symbols that we tag specially
+  # here. `;` and newlines are both treated as a `TERMINATOR`, we distinguish
+  # parentheses that indicate a method call from regular parentheses, and so on.
+  literalToken: ->
+    if match = OPERATOR.exec @chunk
+      [value] = match
+      @tagParameters() if CODE.test value
+    else
+      value = @chunk.charAt 0
+    tag  = value
+    prev = last @tokens
+    if value is '=' and prev
+      if not prev[1].reserved and prev[1] in JS_FORBIDDEN
+        @error "reserved word \"#{@value()}\" can't be assigned"
+      if prev[1] in ['||', '&&']
+        prev[0] = 'COMPOUND_ASSIGN'
+        prev[1] += '='
+        return value.length
+    if value is ';'
+      @seenFor = no
+      tag = 'TERMINATOR'
+    else if value in MATH            then tag = 'MATH'
+    else if value in COMPARE         then tag = 'COMPARE'
+    else if value in COMPOUND_ASSIGN then tag = 'COMPOUND_ASSIGN'
+    else if value in UNARY           then tag = 'UNARY'
+    else if value in SHIFT           then tag = 'SHIFT'
+    else if value in LOGIC or value is '?' and prev?.spaced then tag = 'LOGIC'
+    else if prev and not prev.spaced
+      if value is '(' and prev[0] in CALLABLE
+        prev[0] = 'FUNC_EXIST' if prev[0] is '?'
+        tag = 'CALL_START'
+      else if value is '[' and prev[0] in INDEXABLE
+        tag = 'INDEX_START'
+        switch prev[0]
+          when '?'  then prev[0] = 'INDEX_SOAK'
+    switch value
+      when '(', '{', '[' then @ends.push INVERSES[value]
+      when ')', '}', ']' then @pair value
+    @token tag, value
+    value.length
+
+  # Token Manipulators
+  # ------------------
+
+  # Sanitize a heredoc or herecomment by
+  # erasing all external indentation on the left-hand side.
+  sanitizeHeredoc: (doc, options) ->
+    {indent, herecomment} = options
+    if herecomment
+      if HEREDOC_ILLEGAL.test doc
+        @error "block comment cannot contain \"*/\", starting"
+      return doc if doc.indexOf('\n') <= 0
+    else
+      while match = HEREDOC_INDENT.exec doc
+        attempt = match[1]
+        indent = attempt if indent is null or 0 < attempt.length < indent.length
+    doc = doc.replace /// \n #{indent} ///g, '\n' if indent
+    doc = doc.replace /^\n/, '' unless herecomment
+    doc
+
+  # A source of ambiguity in our grammar used to be parameter lists in function
+  # definitions versus argument lists in function calls. Walk backwards, tagging
+  # parameters specially in order to make things easier for the parser.
+  tagParameters: ->
+    return this if @tag() isnt ')'
+    stack = []
+    {tokens} = this
+    i = tokens.length
+    tokens[--i][0] = 'PARAM_END'
+    while tok = tokens[--i]
+      switch tok[0]
+        when ')'
+          stack.push tok
+        when '(', 'CALL_START'
+          if stack.length then stack.pop()
+          else if tok[0] is '('
+            tok[0] = 'PARAM_START'
+            return this
+          else return this
+    this
+
+  # Close up all remaining open blocks at the end of the file.
+  closeIndentation: ->
+    @outdentToken @indent
+
+  # Matches a balanced group such as a single or double-quoted string. Pass in
+  # a series of delimiters, all of which must be nested correctly within the
+  # contents of the string. This method allows us to have strings within
+  # interpolations within strings, ad infinitum.
+  balancedString: (str, end) ->
+    continueCount = 0
+    stack = [end]
+    for i in [1...str.length]
+      if continueCount
+        --continueCount
+        continue
+      switch letter = str.charAt i
+        when '\\'
+          ++continueCount
+          continue
+        when end
+          stack.pop()
+          unless stack.length
+            return str[0..i]
+          end = stack[stack.length - 1]
+          continue
+      if end is '}' and letter in ['"', "'"]
+        stack.push end = letter
+      else if end is '}' and letter is '/' and match = (HEREGEX.exec(str[i..]) or REGEX.exec(str[i..]))
+        continueCount += match[0].length - 1
+      else if end is '}' and letter is '{'
+        stack.push end = '}'
+      else if end is '"' and prev is '#' and letter is '{'
+        stack.push end = '}'
+      prev = letter
+    @error "missing #{ stack.pop() }, starting"
+
+  # Expand variables and expressions inside double-quoted strings using
+  # Ruby-like notation for substitution of arbitrary expressions.
+  #
+  #     "Hello #{name.capitalize()}."
+  #
+  # If it encounters an interpolation, this method will recursively create a
+  # new Lexer, tokenize the interpolated contents, and merge them into the
+  # token stream.
+  interpolateString: (str, options = {}) ->
+    {heredoc, regex} = options
+    tokens = []
+    pi = 0
+    i  = -1
+    while letter = str.charAt i += 1
+      if letter is '\\'
+        i += 1
+        continue
+      unless letter is '#' and str.charAt(i+1) is '{' and
+             (expr = @balancedString str[i + 1..], '}')
+        continue
+      tokens.push ['NEOSTRING', str[pi...i]] if pi < i
+      inner = expr[1...-1]
+      if inner.length
+        nested = new Lexer().tokenize inner, line: @line, rewrite: off
+        nested.pop()
+        nested.shift() if nested[0]?[0] is 'TERMINATOR'
+        if len = nested.length
+          if len > 1
+            nested.unshift ['(', '(', @line]
+            nested.push    [')', ')', @line]
+          tokens.push ['TOKENS', nested]
+      i += expr.length
+      pi = i + 1
+    tokens.push ['NEOSTRING', str[pi..]] if i > pi < str.length
+    return tokens if regex
+    return @token 'STRING', '""' unless tokens.length
+    tokens.unshift ['', ''] unless tokens[0][0] is 'NEOSTRING'
+    @token '(', '(' if interpolated = tokens.length > 1
+    for [tag, value], i in tokens
+      @token '+', '+' if i
+      if tag is 'TOKENS'
+        @tokens.push value...
+      else
+        @token 'STRING', @makeString value, '"', heredoc
+    @token ')', ')' if interpolated
+    tokens
+
+  # Pairs up a closing token, ensuring that all listed pairs of tokens are
+  # correctly balanced throughout the course of the token stream.
+  pair: (tag) ->
+    unless tag is wanted = last @ends
+      @error "unmatched #{tag}" unless 'OUTDENT' is wanted
+      # Auto-close INDENT to support syntax like this:
+      #
+      #     el.click((event) ->
+      #       el.hide())
+      #
+      @indent -= size = last @indents
+      @outdentToken size, true
+      return @pair tag
+    @ends.pop()
+
+  # Helpers
+  # -------
+
+  # Add a token to the results, taking note of the line number.
+  token: (tag, value) ->
+    @tokens.push [tag, value, @line]
+
+  # Peek at a tag in the current token stream.
+  tag: (index, tag) ->
+    (tok = last @tokens, index) and if tag then tok[0] = tag else tok[0]
+
+  # Peek at a value in the current token stream.
+  value: (index, val) ->
+    (tok = last @tokens, index) and if val then tok[1] = val else tok[1]
+
+  # Are we in the midst of an unfinished expression?
+  unfinished: ->
+    LINE_CONTINUER.test(@chunk) or
+    @tag() in ['\\', '.', '?.', 'UNARY', 'MATH', '+', '-', 'SHIFT', 'RELATION'
+               'COMPARE', 'LOGIC', 'THROW', 'EXTENDS']
+
+  # Converts newlines for string literals.
+  escapeLines: (str, heredoc) ->
+    str.replace MULTILINER, if heredoc then '\\n' else ''
+
+  # Constructs a string token by escaping quotes and newlines.
+  makeString: (body, quote, heredoc) ->
+    return quote + quote unless body
+    body = body.replace /\\([\s\S])/g, (match, contents) ->
+      if contents in ['\n', quote] then contents else match
+    body = body.replace /// #{quote} ///g, '\\$&'
+    quote + @escapeLines(body, heredoc) + quote
+
+  # Throws a syntax error on the current `@line`.
+  error: (message) ->
+    throw SyntaxError "#{message} on line #{ @line + 1}"
+
+# Constants
+# ---------
+
+# Keywords that CoffeeScript shares in common with JavaScript.
+JS_KEYWORDS = [
+  'true', 'false', 'null', 'this'
+  'new', 'delete', 'typeof', 'in', 'instanceof'
+  'return', 'throw', 'break', 'continue', 'debugger'
+  'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally'
+  'class', 'extends', 'super'
+]
+
+# CoffeeScript-only keywords.
+COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when']
+
+COFFEE_ALIAS_MAP =
+  and  : '&&'
+  or   : '||'
+  is   : '=='
+  isnt : '!='
+  not  : '!'
+  yes  : 'true'
+  no   : 'false'
+  on   : 'true'
+  off  : 'false'
+
+COFFEE_ALIASES  = (key for key of COFFEE_ALIAS_MAP)
+COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat COFFEE_ALIASES
+
+# The list of keywords that are reserved by JavaScript, but not used, or are
+# used by CoffeeScript internally. We throw an error when these are encountered,
+# to avoid having a JavaScript error at runtime.
+RESERVED = [
+  'case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum'
+  'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind'
+  '__indexOf', 'implements', 'interface', 'package', 'private', 'protected'
+  'public', 'static', 'yield'
+]
+
+STRICT_PROSCRIBED = ['arguments', 'eval']
+
+# The superset of both JavaScript keywords and reserved words, none of which may
+# be used as identifiers or properties.
+JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED).concat(STRICT_PROSCRIBED)
+
+exports.RESERVED = RESERVED.concat(JS_KEYWORDS).concat(COFFEE_KEYWORDS).concat(STRICT_PROSCRIBED)
+exports.STRICT_PROSCRIBED = STRICT_PROSCRIBED
+
+# Token matching regexes.
+IDENTIFIER = /// ^
+  ( [$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]* )
+  ( [^\n\S]* : (?!:) )?  # Is this a property name?
+///
+
+NUMBER     = ///
+  ^ 0b[01]+    |              # binary
+  ^ 0o[0-7]+   |              # octal
+  ^ 0x[\da-f]+ |              # hex
+  ^ \d*\.?\d+ (?:e[+-]?\d+)?  # decimal
+///i
+
+HEREDOC    = /// ^ ("""|''') ([\s\S]*?) (?:\n[^\n\S]*)? \1 ///
+
+OPERATOR   = /// ^ (
+  ?: [-=]>             # function
+   | [-+*/%<>&|^!?=]=  # compound assign / compare
+   | >>>=?             # zero-fill right shift
+   | ([-+:])\1         # doubles
+   | ([&|<>])\2=?      # logic / shift
+   | \?\.              # soak access
+   | \.{2,3}           # range or splat
+) ///
+
+WHITESPACE = /^[^\n\S]+/
+
+COMMENT    = /^###([^#][\s\S]*?)(?:###[^\n\S]*|(?:###)?$)|^(?:\s*#(?!##[^#]).*)+/
+
+CODE       = /^[-=]>/
+
+MULTI_DENT = /^(?:\n[^\n\S]*)+/
+
+SIMPLESTR  = /^'[^\\']*(?:\\.[^\\']*)*'/
+
+JSTOKEN    = /^`[^\\`]*(?:\\.[^\\`]*)*`/
+
+# Regex-matching-regexes.
+REGEX = /// ^
+  (/ (?! [\s=] )   # disallow leading whitespace or equals signs
+  [^ [ / \n \\ ]*  # every other thing
+  (?:
+    (?: \\[\s\S]   # anything escaped
+      | \[         # character class
+           [^ \] \n \\ ]*
+           (?: \\[\s\S] [^ \] \n \\ ]* )*
+         ]
+    ) [^ [ / \n \\ ]*
+  )*
+  /) ([imgy]{0,4}) (?!\w)
+///
+
+HEREGEX      = /// ^ /{3} ([\s\S]+?) /{3} ([imgy]{0,4}) (?!\w) ///
+
+HEREGEX_OMIT = /\s+(?:#.*)?/g
+
+# Token cleaning regexes.
+MULTILINER      = /\n/g
+
+HEREDOC_INDENT  = /\n+([^\n\S]*)/g
+
+HEREDOC_ILLEGAL = /\*\//
+
+LINE_CONTINUER  = /// ^ \s* (?: , | \??\.(?![.\d]) | :: ) ///
+
+TRAILING_SPACES = /\s+$/
+
+# Compound assignment tokens.
+COMPOUND_ASSIGN = [
+  '-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|='
+]
+
+# Unary tokens.
+UNARY   = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO']
+
+# Logical tokens.
+LOGIC   = ['&&', '||', '&', '|', '^']
+
+# Bit-shifting tokens.
+SHIFT   = ['<<', '>>', '>>>']
+
+# Comparison tokens.
+COMPARE = ['==', '!=', '<', '>', '<=', '>=']
+
+# Mathematical tokens.
+MATH    = ['*', '/', '%']
+
+# Relational tokens that are negatable with `not` prefix.
+RELATION = ['IN', 'OF', 'INSTANCEOF']
+
+# Boolean tokens.
+BOOL = ['TRUE', 'FALSE']
+
+# Tokens which a regular expression will never immediately follow, but which
+# a division operator might.
+#
+# See: http://www.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions
+#
+# Our list is shorter, due to sans-parentheses method calls.
+NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--', ']']
+
+# If the previous token is not spaced, there are more preceding tokens that
+# force a division parse:
+NOT_SPACED_REGEX = NOT_REGEX.concat ')', '}', 'THIS', 'IDENTIFIER', 'STRING'
+
+# Tokens which could legitimately be invoked or indexed. An opening
+# parentheses or bracket following these tokens will be recorded as the start
+# of a function invocation or indexing operation.
+CALLABLE  = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER']
+INDEXABLE = CALLABLE.concat 'NUMBER', 'BOOL', 'NULL', 'UNDEFINED'
+
+# Tokens that, when immediately preceding a `WHEN`, indicate that the `WHEN`
+# occurs at the start of a line. We disambiguate these from trailing whens to
+# avoid an ambiguity in the grammar.
+LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR']
diff --git a/app/server/vendor/rouge/spec/visual/samples/common_lisp b/app/server/vendor/rouge/spec/visual/samples/common_lisp
new file mode 100755
index 0000000..c153916
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/common_lisp
@@ -0,0 +1,1204 @@
+#nil (commented (form ftw))
+
+;;;; TYPEP und Verwandtes
+;;;; Michael Stoll, 21. 10. 1988
+;;;; Bruno Haible, 10.6.1989
+;;;; Sam Steingold 2000-2005
+
+;;; Datenstrukturen für TYPEP:
+;;; - Ein Type-Specifier-Symbol hat auf seiner Propertyliste unter dem
+;;;   Indikator SYS::TYPE-SYMBOL eine Funktion von einem Argument, die
+;;;   testet, ob ein Objekt vom richtigen Typ ist.
+;;; - Ein Symbol, das eine Type-Specifier-Liste beginnen kann, hat auf seiner
+;;;   Propertyliste unter dem Indikator SYS::TYPE-LIST eine Funktion von
+;;;   einem Argument für das zu testende Objekt und zusätzlichen Argumenten
+;;;   für die Listenelemente.
+;;; - Ein Symbol, das als Typmacro definiert wurde, hat auf seiner Property-
+;;;   liste unter dem Indikator SYSTEM::DEFTYPE-EXPANDER den zugehörigen
+;;;   Expander: eine Funktion, die den zu expandierenden Type-Specifier (eine
+;;;   mindestens einelementige Liste) als Argument bekommt.
+
+(in-package "EXT")
+(export '(type-expand))
+(in-package "SYSTEM")
+
+; vorläufig, solange bis clos.lisp geladen wird:
+(eval-when (eval)
+  (predefun clos::built-in-class-p (object) (declare (ignore object)) nil))
+(unless (fboundp 'clos::class-name)
+  (defun clos::class-name (c) (declare (ignore c)) nil)
+)
+
+(defun typespec-error (fun type)
+  (error-of-type 'error
+    (TEXT "~S: invalid type specification ~S")
+    fun type
+) )
+
+;; ============================================================================
+
+;; return the CLOS class named by TYPESPEC or NIL
+(defun clos-class (typespec)
+  (let ((cc (get typespec 'CLOS::CLOSCLASS)))
+    (when (and cc (clos::defined-class-p cc) (eq (clos:class-name cc) typespec))
+      cc)))
+
+;;; TYPEP, CLTL S. 72, S. 42-51
+(defun typep (x y &optional env &aux f) ; x = Objekt, y = Typ
+  (declare (ignore env))
+  (setq y (expand-deftype y))
+  (cond
+    ((symbolp y)
+       (cond ((setq f (get y 'TYPE-SYMBOL)) (funcall f x))
+             ((setq f (get y 'TYPE-LIST)) (funcall f x))
+             ((setq f (get y 'DEFSTRUCT-DESCRIPTION)) (ds-typep x y f))
+             ((setq f (clos-class y))
+              ; It's not worth handling structure classes specially here.
+              (clos::typep-class x f))
+             (t (typespec-error 'typep y))
+    )  )
+    ((and (consp y) (symbolp (first y)))
+       (cond
+         ((and (eq (first y) 'SATISFIES) (eql (length y) 2))
+            (unless (symbolp (second y))
+              (error-of-type 'error
+                (TEXT "~S: argument to SATISFIES must be a symbol: ~S")
+                'typep (second y)
+            ) )
+            (if (funcall (symbol-function (second y)) x) t nil)
+         )
+         ((eq (first y) 'MEMBER)
+            (if (member x (rest y)) t nil)
+         )
+         ((and (eq (first y) 'EQL) (eql (length y) 2))
+            (eql x (second y))
+         )
+         ((and (eq (first y) 'NOT) (eql (length y) 2))
+            (not (typep x (second y)))
+         )
+         ((eq (first y) 'AND)
+            (dolist (type (rest y) t)
+              (unless (typep x type) (return nil))
+         )  )
+         ((eq (first y) 'OR)
+            (dolist (type (rest y) nil)
+              (when (typep x type) (return t))
+         )  )
+         ((setq f (get (first y) 'TYPE-LIST)) (apply f x (rest y)))
+         (t (typespec-error 'typep y))
+    )  )
+    ((clos::defined-class-p y) (clos::typep-class x y))
+    ((clos::eql-specializer-p y) (eql x (clos::eql-specializer-singleton y)))
+    ((encodingp y) (charset-typep x y))
+    (t (typespec-error 'typep y))
+) )
+
+;; ----------------------------------------------------------------------------
+
+;; UPGRADED-ARRAY-ELEMENT-TYPE is a lattice homomorphism, see
+;; ANSI CL 15.1.2.1.
+(defun upgraded-array-element-type (type &optional environment)
+  (declare (ignore environment))
+  ;; see array.d
+  (case type
+    ((BIT) 'BIT)
+    ((CHARACTER) 'CHARACTER)
+    ((T) 'T)
+    ((NIL) 'NIL)
+    (t (if (subtypep type 'NIL)
+         'NIL
+         (multiple-value-bind (low high) (sys::subtype-integer type)
+           ; Es gilt (or (null low) (subtypep type `(INTEGER ,low ,high)))
+           (if (and (integerp low) (not (minusp low)) (integerp high))
+             (let ((l (integer-length high)))
+               ; Es gilt (subtypep type `(UNSIGNED-BYTE ,l))
+               (cond ((<= l 1) 'BIT)
+                     ((<= l 2) '(UNSIGNED-BYTE 2))
+                     ((<= l 4) '(UNSIGNED-BYTE 4))
+                     ((<= l 8) '(UNSIGNED-BYTE 8))
+                     ((<= l 16) '(UNSIGNED-BYTE 16))
+                     ((<= l 32) '(UNSIGNED-BYTE 32))
+                     (t 'T)))
+             (if (subtypep type 'CHARACTER)
+               'CHARACTER
+               'T)))))))
+
+;; ----------------------------------------------------------------------------
+
+;; UPGRADED-COMPLEX-PART-TYPE is a lattice homomorphism, see
+;; HyperSpec/Body/fun_complex.html and HyperSpec/Body/syscla_complex.html,
+;; and an idempotent. Therefore
+;;   (subtypep (upgraded-complex-part-type T1) (upgraded-complex-part-type T2))
+;; is equivalent to
+;;   (subtypep T1 (upgraded-complex-part-type T2))
+;; (Proof: Let U T be an abbreviation for (upgraded-complex-part-type T).
+;;  If U T1 <= U T2, then T1 <= U T1 <= U T2.
+;;  If T1 <= U T2, then by homomorphism U T1 <= U U T2 = U T2.)
+;;
+;; For _any_ CL implementation, you could define
+;;   (defun upgraded-complex-part-type (type) 'REAL)
+;; Likewise for _any_ CL implementation, you could define
+;;   (defun upgraded-complex-part-type (type) type)
+;; or - again for _any_ CL implementation:
+;;   (defun upgraded-complex-part-type (type)
+;;     (cond ((subtypep type 'NIL) 'NIL)
+;;           ((subtypep type 'SHORT-FLOAT) 'SHORT-FLOAT)
+;;           ((subtypep type 'SINGLE-FLOAT) 'SINGLE-FLOAT)
+;;           ((subtypep type 'DOUBLE-FLOAT) 'DOUBLE-FLOAT)
+;;           ((subtypep type 'LONG-FLOAT) 'LONG-FLOAT)
+;;           ((subtypep type 'RATIONAL) 'RATIONAL)
+;;           ((subtypep type 'REAL) 'REAL)
+;;           (t (error ...))))
+;; The reason is that a complex number is immutable: no setters for the
+;; realpart and imagpart exist.
+;;
+;; We choose the second implementation because it allows the most precise
+;; type inference.
+(defun upgraded-complex-part-type (type &optional environment)
+  (declare (ignore environment))
+  (if (subtypep type 'REAL)
+    type
+    (error-of-type 'error
+      (TEXT "~S: type ~S is not a subtype of ~S")
+      'upgraded-complex-part-type type 'real)))
+
+;; ----------------------------------------------------------------------------
+
+;; Macros for defining the various built-in "atomic type specifier"s and
+;; "compound type specifier"s. The following macros add information for both
+;; the TYPEP function above and the c-TYPEP in the compiler.
+
+; Alist symbol -> funname, used by the compiler.
+(defparameter c-typep-alist1 '())
+; Alist symbol -> lambdabody, used by the compiler.
+(defparameter c-typep-alist2 '())
+; Alist symbol -> expander function, used by the compiler.
+(defparameter c-typep-alist3 '())
+
+; (def-atomic-type symbol function-name)
+; defines an atomic type. The function-name designates a function taking one
+; argument and returning a generalized boolean value. It can be either a
+; symbol or a lambda expression.
+(defmacro def-atomic-type (symbol funname)
+  (let ((lambdap (and (consp funname) (eq (car funname) 'LAMBDA))))
+    `(PROGN
+       (SETF (GET ',symbol 'TYPE-SYMBOL)
+             ,(if lambdap
+                `(FUNCTION ,(concat-pnames "TYPE-SYMBOL-" symbol) ,funname)
+                `(FUNCTION ,funname)
+              )
+       )
+       ,(if lambdap
+          `(SETQ C-TYPEP-ALIST2
+                 (NCONC C-TYPEP-ALIST2 (LIST (CONS ',symbol ',(cdr funname))))
+           )
+          `(SETQ C-TYPEP-ALIST1
+                 (NCONC C-TYPEP-ALIST1 (LIST (CONS ',symbol ',funname)))
+           )
+        )
+       ',symbol
+     )
+) )
+
+; (def-compound-type symbol lambda-list (x) check-form typep-form c-typep-form)
+; defines a compound type. The lambda-list is of the form (&optional ...)
+; where the arguments come from the CDR of the type specifier.
+; For typep-form, x is an object.
+; For c-typep-form, x is a multiply evaluatable form (actually a gensym).
+; check-form is a form performing error checking, may call `error'.
+; typep-form should return a generalized boolean value.
+; c-typep-form should produce a form returning a generalized boolean value.
+(defmacro def-compound-type (symbol lambdalist (var) check-form typep-form c-typep-form)
+  `(PROGN
+     (SETF (GET ',symbol 'TYPE-LIST)
+           (FUNCTION ,(concat-pnames "TYPE-LIST-" symbol)
+             (LAMBDA (,var , at lambdalist)
+               ,@(if check-form
+                   `((MACROLET ((ERROR (&REST ERROR-ARGS)
+                                  (LIST* 'ERROR-OF-TYPE ''ERROR ERROR-ARGS)
+                               ))
+                       ,check-form
+                    ))
+                 )
+               ,typep-form
+     )     ) )
+     (SETQ C-TYPEP-ALIST3
+           (NCONC C-TYPEP-ALIST3
+                  (LIST (CONS ',symbol
+                              #'(LAMBDA (,var , at lambdalist &REST ILLEGAL-ARGS)
+                                  (DECLARE (IGNORE ILLEGAL-ARGS))
+                                  ,@(if check-form
+                                      `((MACROLET ((ERROR (&REST ERROR-ARGS)
+                                                     (LIST 'PROGN
+                                                           (LIST* 'C-WARN ERROR-ARGS)
+                                                           '(THROW 'C-TYPEP NIL)
+                                                  )) )
+                                          ,check-form
+                                       ))
+                                    )
+                                  ,c-typep-form
+                                )
+     )     )      )     )
+     ',symbol
+   )
+)
+
+; CLtL1 p. 43
+(def-atomic-type ARRAY arrayp)
+(def-atomic-type ATOM atom)
+(def-atomic-type BASE-CHAR
+  #+BASE-CHAR=CHARACTER
+  characterp
+  #-BASE-CHAR=CHARACTER
+  (lambda (x) (and (characterp x) (base-char-p x)))
+)
+(def-atomic-type BASE-STRING
+  (lambda (x)
+    (and (stringp x)
+         (eq (array-element-type x)
+             #+BASE-CHAR=CHARACTER 'CHARACTER #-BASE-CHAR=CHARACTER 'BASE-CHAR
+) ) )    )
+(def-atomic-type BIGNUM
+  (lambda (x) (and (integerp x) (not (fixnump x))))
+)
+(def-atomic-type BIT
+  (lambda (x) (or (eql x 0) (eql x 1)))
+)
+(def-atomic-type BIT-VECTOR bit-vector-p)
+(def-atomic-type BOOLEAN
+  (lambda (x) (or (eq x 'nil) (eq x 't)))
+)
+(def-atomic-type CHARACTER characterp)
+(def-atomic-type COMPILED-FUNCTION compiled-function-p)
+(def-atomic-type COMPLEX complexp)
+(def-atomic-type CONS consp)
+(def-atomic-type DOUBLE-FLOAT double-float-p)
+(def-atomic-type ENCODING encodingp)
+(def-atomic-type EXTENDED-CHAR
+  #+BASE-CHAR=CHARACTER
+  (lambda (x) (declare (ignore x)) nil)
+  #-BASE-CHAR=CHARACTER
+  (lambda (x) (and (characterp x) (not (base-char-p x))))
+)
+(def-atomic-type FIXNUM fixnump)
+(def-atomic-type FLOAT floatp)
+(def-atomic-type FUNCTION functionp)
+(def-atomic-type HASH-TABLE hash-table-p)
+(def-atomic-type INTEGER integerp)
+(def-atomic-type KEYWORD keywordp)
+(def-atomic-type LIST listp)
+#+LOGICAL-PATHNAMES
+(def-atomic-type LOGICAL-PATHNAME logical-pathname-p)
+(def-atomic-type LONG-FLOAT long-float-p)
+(def-atomic-type NIL
+  (lambda (x) (declare (ignore x)) nil)
+)
+(def-atomic-type NULL null)
+(def-atomic-type NUMBER numberp)
+(def-atomic-type PACKAGE packagep)
+(def-atomic-type PATHNAME pathnamep)
+(def-atomic-type RANDOM-STATE random-state-p)
+(def-atomic-type RATIO
+  (lambda (x) (and (rationalp x) (not (integerp x))))
+)
+(def-atomic-type RATIONAL rationalp)
+(def-atomic-type READTABLE readtablep)
+(def-atomic-type REAL realp)
+(def-atomic-type SEQUENCE sequencep)
+(def-atomic-type SHORT-FLOAT short-float-p)
+(def-atomic-type SIMPLE-ARRAY simple-array-p)
+(def-atomic-type SIMPLE-BASE-STRING
+  (lambda (x)
+    (and (simple-string-p x)
+         (eq (array-element-type x)
+             #+BASE-CHAR=CHARACTER 'CHARACTER #-BASE-CHAR=CHARACTER 'BASE-CHAR
+) ) )    )
+(def-atomic-type SIMPLE-BIT-VECTOR simple-bit-vector-p)
+(def-atomic-type SIMPLE-STRING simple-string-p)
+(def-atomic-type SIMPLE-VECTOR simple-vector-p)
+(def-atomic-type SINGLE-FLOAT single-float-p)
+(defun %standard-char-p (x) (and (characterp x) (standard-char-p x))) ; ABI
+(def-atomic-type STANDARD-CHAR %standard-char-p)
+(def-atomic-type CLOS:STANDARD-OBJECT clos::std-instance-p)
+(def-atomic-type STREAM streamp)
+(def-atomic-type FILE-STREAM file-stream-p)
+(def-atomic-type SYNONYM-STREAM synonym-stream-p)
+(def-atomic-type BROADCAST-STREAM broadcast-stream-p)
+(def-atomic-type CONCATENATED-STREAM concatenated-stream-p)
+(def-atomic-type TWO-WAY-STREAM two-way-stream-p)
+(def-atomic-type ECHO-STREAM echo-stream-p)
+(def-atomic-type STRING-STREAM string-stream-p)
+(def-atomic-type STRING stringp)
+(def-atomic-type STRING-CHAR characterp)
+(def-atomic-type CLOS:STRUCTURE-OBJECT clos::structure-object-p)
+(def-atomic-type SYMBOL symbolp)
+(def-atomic-type T (lambda (x) (declare (ignore x)) t))
+;; foreign1.lisp is loaded after this file,
+;; so these symbols are not external yet
+#+ffi
+(def-atomic-type ffi::foreign-function
+  (lambda (x) (eq 'ffi::foreign-function (type-of x))))
+#+ffi
+(def-atomic-type ffi::foreign-variable
+  (lambda (x) (eq 'ffi::foreign-variable (type-of x))))
+#+ffi
+(def-atomic-type ffi::foreign-address
+  (lambda (x) (eq 'ffi::foreign-address (type-of x))))
+;; see lispbibl.d (#define FOREIGN) and predtype.d (TYPE-OF):
+#+(or unix ffi affi win32)
+(def-atomic-type foreign-pointer
+  (lambda (x) (eq 'foreign-pointer (type-of x))))
+(def-atomic-type VECTOR vectorp)
+(def-atomic-type PLIST
+    (lambda (x) (multiple-value-bind (length tail) (list-length-dotted x)
+                  (and (null tail) (evenp length)))))
+
+(defmacro ensure-dim (type dim)
+  ;; make sure DIM is a valid dimension
+  `(unless (or (eq ,dim '*) (typep ,dim `(INTEGER 0 (,ARRAY-DIMENSION-LIMIT))))
+     (error (TEXT "~S: dimension ~S is invalid") ',type ,dim)))
+
+(defmacro ensure-rank (type rank)
+  ;; make sure RANK is a valid rank
+  `(unless (typep ,rank `(INTEGER 0 (,ARRAY-RANK-LIMIT)))
+     (error (TEXT "~S: rank ~S is invalid") ',type ,rank)))
+
+; CLtL1 p. 46-50
+(defun c-typep-array (tester el-type dims x)
+  `(AND (,tester ,x)
+        ,@(if (eq el-type '*)
+            '()
+            `((EQUAL (ARRAY-ELEMENT-TYPE ,x) ',(upgraded-array-element-type el-type)))
+          )
+        ,@(if (eq dims '*)
+            '()
+            (if (numberp dims)
+              `((EQL ,dims (ARRAY-RANK ,x)))
+              `((EQL ,(length dims) (ARRAY-RANK ,x))
+                ,@(let ((i 0))
+                    (mapcap #'(lambda (dim)
+                                (prog1
+                                  (if (eq dim '*)
+                                    '()
+                                    `((EQL ',dim (ARRAY-DIMENSION ,x ,i)))
+                                  )
+                                  (incf i)
+                              ) )
+                            dims
+                  ) )
+               )
+          ) )
+   )
+)
+(defun c-typep-vector (tester size x)
+  `(AND (,tester ,x)
+        ,@(if (eq size '*)
+            '()
+            `((EQL ',size (ARRAY-DIMENSION ,x 0)))
+          )
+   )
+)
+(defun typep-number-test (x low high test type)
+  (and (funcall test x)
+       (cond ((eq low '*))
+             ((funcall test low) (<= low x))
+             ((and (consp low) (null (rest low)) (funcall test (first low)))
+                (< (first low) x)
+             )
+             (t (error-of-type 'error
+                  #1=(TEXT "~S: argument to ~S must be *, ~S or a list of ~S: ~S")
+                  'typep type type type low
+       )     )  )
+       (cond ((eq high '*))
+             ((funcall test high) (>= high x))
+             ((and (consp high) (null (rest high)) (funcall test (first high)))
+                (> (first high) x)
+             )
+             (t (error-of-type 'error
+                  #1# 'typep type type type high
+) )    )     )  )
+(defun c-typep-number (caller tester low high x)
+  `(AND (,tester ,x)
+        ,@(cond ((eq low '*) '())
+                ((funcall tester low) `((<= ,low ,x)))
+                ((and (consp low) (null (rest low)) (funcall tester (first low)))
+                 `((< ,(first low) ,x))
+                )
+                (t (c-warn #1=(TEXT "~S: argument to ~S must be *, ~S or a list of ~S: ~S")
+                           'typep caller caller caller low
+                   )
+                   (throw 'c-TYPEP nil)
+          )     )
+        ,@(cond ((eq high '*) '())
+                ((funcall tester high) `((>= ,high ,x)))
+                ((and (consp high) (null (rest high)) (funcall tester (first high)))
+                 `((> ,(first high) ,x))
+                )
+                (t (c-warn #1# 'typep caller caller caller high)
+                   (throw 'c-TYPEP nil)
+          )     )
+   )
+)
+(def-compound-type ARRAY (&optional (el-type '*) (dims '*)) (x)
+  (unless (eq dims '*)
+    (if (numberp dims)
+      (ensure-rank ARRAY dims)
+      (dolist (dim dims) (ensure-dim ARRAY dim))))
+  (and (arrayp x)
+       (or (eq el-type '*)
+           (equal (array-element-type x) (upgraded-array-element-type el-type))
+       )
+       (or (eq dims '*)
+           (if (numberp dims)
+             (eql dims (array-rank x))
+             (and (eql (length dims) (array-rank x))
+                  (every #'(lambda (a b) (or (eq a '*) (eql a b)))
+                         dims (array-dimensions x)
+  )    )   ) )    )
+  (c-typep-array 'ARRAYP el-type dims x)
+)
+(def-compound-type SIMPLE-ARRAY (&optional (el-type '*) (dims '*)) (x)
+  (unless (eq dims '*)
+    (if (numberp dims)
+      (ensure-rank SIMPLE-ARRAY dims)
+      (dolist (dim dims) (ensure-dim SIMPLE-ARRAY dim))))
+  (and (simple-array-p x)
+       (or (eq el-type '*)
+           (equal (array-element-type x) (upgraded-array-element-type el-type))
+       )
+       (or (eq dims '*)
+           (if (numberp dims)
+             (eql dims (array-rank x))
+             (and (eql (length dims) (array-rank x))
+                  (every #'(lambda (a b) (or (eq a '*) (eql a b)))
+                         dims (array-dimensions x)
+  )    )   ) )    )
+  (c-typep-array 'SIMPLE-ARRAY-P el-type dims x)
+)
+(def-compound-type VECTOR (&optional (el-type '*) (size '*)) (x)
+  (ensure-dim VECTOR size)
+  (and (vectorp x)
+       (or (eq el-type '*)
+           (equal (array-element-type x) (upgraded-array-element-type el-type))
+       )
+       (or (eq size '*) (eql (array-dimension x 0) size))
+  )
+  `(AND (VECTORP ,x)
+        ,@(if (eq el-type '*)
+            '()
+            `((EQUAL (ARRAY-ELEMENT-TYPE ,x) ',(upgraded-array-element-type el-type)))
+          )
+        ,@(if (eq size '*)
+            '()
+            `((EQL (ARRAY-DIMENSION ,x 0) ',size))
+          )
+   )
+)
+(def-compound-type SIMPLE-VECTOR (&optional (size '*)) (x)
+  (ensure-dim SIMLPE-VECTOR size)
+  (and (simple-vector-p x)
+       (or (eq size '*) (eql size (array-dimension x 0)))
+  )
+  (c-typep-vector 'SIMPLE-VECTOR-P size x)
+)
+(def-compound-type COMPLEX (&optional (rtype '*) (itype rtype)) (x)
+  nil
+  (and (complexp x)
+       (or (eq rtype '*)
+           (typep (realpart x) (upgraded-complex-part-type rtype)))
+       (or (eq itype '*)
+           (typep (imagpart x) (upgraded-complex-part-type itype))))
+  `(AND (COMPLEXP ,x)
+        ,@(if (eq rtype '*)
+            '()
+            `((TYPEP (REALPART ,x) ',(upgraded-complex-part-type rtype))))
+        ,@(if (eq itype '*)
+            '()
+            `((TYPEP (IMAGPART ,x) ',(upgraded-complex-part-type itype))))))
+(def-compound-type INTEGER (&optional (low '*) (high '*)) (x)
+  nil
+  (typep-number-test x low high #'integerp 'INTEGER)
+  (c-typep-number 'INTEGER 'INTEGERP low high x)
+)
+(def-compound-type MOD (n) (x)
+  (unless (integerp n)
+    (error (TEXT "~S: argument to MOD must be an integer: ~S")
+           'typep n
+  ) )
+  (and (integerp x) (<= 0 x) (< x n))
+  `(AND (INTEGERP ,x) (NOT (MINUSP ,x)) (< ,x ,n))
+)
+(def-compound-type SIGNED-BYTE (&optional (n '*)) (x)
+  (unless (or (eq n '*) (integerp n))
+    (error (TEXT "~S: argument to SIGNED-BYTE must be an integer or * : ~S")
+           'typep n
+  ) )
+  (and (integerp x) (or (eq n '*) (< (integer-length x) n)))
+  `(AND (INTEGERP ,x)
+        ,@(if (eq n '*) '() `((< (INTEGER-LENGTH ,x) ,n)))
+   )
+)
+(def-compound-type UNSIGNED-BYTE (&optional (n '*)) (x)
+  (unless (or (eq n '*) (integerp n))
+    (error (TEXT "~S: argument to UNSIGNED-BYTE must be an integer or * : ~S")
+           'typep n
+  ) )
+  (and (integerp x)
+       (not (minusp x))
+       (or (eq n '*) (<= (integer-length x) n))
+  )
+  `(AND (INTEGERP ,x) (NOT (MINUSP ,x))
+        ,@(if (eq n '*) '() `((<= (INTEGER-LENGTH ,x) ,n)))
+   )
+)
+(def-compound-type REAL (&optional (low '*) (high '*)) (x)
+  nil
+  (typep-number-test x low high #'realp 'REAL)
+  (c-typep-number 'REAL 'REALP low high x)
+)
+(def-compound-type RATIONAL (&optional (low '*) (high '*)) (x)
+  nil
+  (typep-number-test x low high #'rationalp 'RATIONAL)
+  (c-typep-number 'RATIONAL 'RATIONALP low high x)
+)
+(def-compound-type FLOAT (&optional (low '*) (high '*)) (x)
+  nil
+  (typep-number-test x low high #'floatp 'FLOAT)
+  (c-typep-number 'FLOAT 'FLOATP low high x)
+)
+(def-compound-type SHORT-FLOAT (&optional (low '*) (high '*)) (x)
+  nil
+  (typep-number-test x low high #'short-float-p 'SHORT-FLOAT)
+  (c-typep-number 'SHORT-FLOAT 'SHORT-FLOAT-P low high x)
+)
+(def-compound-type SINGLE-FLOAT (&optional (low '*) (high '*)) (x)
+  nil
+  (typep-number-test x low high #'single-float-p 'SINGLE-FLOAT)
+  (c-typep-number 'SINGLE-FLOAT 'SINGLE-FLOAT-P low high x)
+)
+(def-compound-type DOUBLE-FLOAT (&optional (low '*) (high '*)) (x)
+  nil
+  (typep-number-test x low high #'double-float-p 'DOUBLE-FLOAT)
+  (c-typep-number 'DOUBLE-FLOAT 'DOUBLE-FLOAT-P low high x)
+)
+(def-compound-type LONG-FLOAT (&optional (low '*) (high '*)) (x)
+  nil
+  (typep-number-test x low high #'long-float-p 'LONG-FLOAT)
+  (c-typep-number 'LONG-FLOAT 'LONG-FLOAT-P low high x)
+)
+(def-compound-type STRING (&optional (size '*)) (x)
+  (ensure-dim STRING size)
+  (and (stringp x)
+       (or (eq size '*) (eql size (array-dimension x 0)))
+  )
+  (c-typep-vector 'STRINGP size x)
+)
+(def-compound-type SIMPLE-STRING (&optional (size '*)) (x)
+  (ensure-dim SIMPLE-STRING size)
+  (and (simple-string-p x)
+       (or (eq size '*) (eql size (array-dimension x 0)))
+  )
+  (c-typep-vector 'SIMPLE-STRING-P size x)
+)
+(def-compound-type BASE-STRING (&optional (size '*)) (x)
+  (ensure-dim BASE-STRING size)
+  (and (stringp x)
+       (or (eq size '*) (eql size (array-dimension x 0)))
+  )
+  (c-typep-vector 'STRINGP size x)
+)
+(def-compound-type SIMPLE-BASE-STRING (&optional (size '*)) (x)
+  (ensure-dim SIMPLE-BASE-STRING size)
+  (and (simple-string-p x)
+       (or (eq size '*) (eql size (array-dimension x 0)))
+  )
+  (c-typep-vector 'SIMPLE-STRING-P size x)
+)
+(def-compound-type BIT-VECTOR (&optional (size '*)) (x)
+  (ensure-dim BIT-VECTOR size)
+  (and (bit-vector-p x)
+       (or (eq size '*) (eql size (array-dimension x 0)))
+  )
+  (c-typep-vector 'BIT-VECTOR-P size x)
+)
+(def-compound-type SIMPLE-BIT-VECTOR (&optional (size '*)) (x)
+  (ensure-dim SIMPLE-BIT-VECTOR size)
+  (and (simple-bit-vector-p x)
+       (or (eq size '*) (eql size (array-dimension x 0)))
+  )
+  (c-typep-vector 'SIMPLE-BIT-VECTOR-P size x)
+)
+(def-compound-type CONS (&optional (car-type '*) (cdr-type '*)) (x)
+  nil
+  (and (consp x)
+       (or (eq car-type '*) (typep (car x) car-type))
+       (or (eq cdr-type '*) (typep (cdr x) cdr-type))
+  )
+  `(AND (CONSP ,x)
+        ,@(if (eq car-type '*) '() `((TYPEP (CAR ,x) ',car-type)))
+        ,@(if (eq cdr-type '*) '() `((TYPEP (CDR ,x) ',cdr-type)))
+   )
+)
+
+(fmakunbound 'def-compound-type)
+
+;; ----------------------------------------------------------------------------
+
+; Typtest ohne Gefahr einer Fehlermeldung. Für SIGNAL und HANDLER-BIND.
+(defun safe-typep (x y &optional env)
+  (let ((*error-handler*
+          #'(lambda (&rest error-args)
+              (declare (ignore error-args))
+              (return-from safe-typep (values nil nil))
+       ))   )
+    (values (typep x y env) t)
+) )
+
+; Umwandlung eines "type for declaration" in einen "type for discrimination".
+(defun type-for-discrimination (y &optional (notp nil) &aux f)
+  (cond ((symbolp y)
+           (cond ((get y 'TYPE-SYMBOL) y)
+                 ((get y 'TYPE-LIST) y)
+                 ((setq f (get y 'DEFTYPE-EXPANDER))
+                  (let* ((z (funcall f (list y)))
+                         (zx (type-for-discrimination z notp)))
+                    (if (eql zx z) y zx)
+                 ))
+                 (t y)
+        )  )
+        ((and (consp y) (symbolp (first y)))
+           (case (first y)
+             ((SATISFIES MEMBER EQL) y)
+             (NOT
+              (let* ((z (second y))
+                     (zx (type-for-discrimination z (not notp))))
+                (if (eql zx z) y `(NOT ,zx))
+             ))
+             ((AND OR COMPLEX VALUES)
+              (let* ((z (rest y))
+                     (zx (mapcar #'(lambda (x) (type-for-discrimination x notp)) z)))
+                (if (every #'eql z zx) y (cons (first y) zx))
+             ))
+             (FUNCTION
+              ;; (FUNCTION arg-types res-type) is somewhere between
+              ;; NIL and FUNCTION, but undecidable.
+              (if notp 'NIL 'FUNCTION)
+             )
+             (t (cond ((get (first y) 'TYPE-LIST) y)
+                      ((setq f (get (first y) 'DEFTYPE-EXPANDER))
+                       (let* ((z (funcall f y))
+                              (zx (type-for-discrimination z notp)))
+                         (if (eql zx z) y zx)
+                      ))
+                      (t y)
+        )  ) )  )
+        (t y)
+) )
+
+; Testet eine Liste von Werten auf Erfüllen eines Type-Specifiers. Für THE.
+(defun %the (values type) ; ABI
+  (macrolet ((near-typep (objform typform)
+               ;; near-typep ist wie typep, nur dass das Objekt auch ein
+               ;; Read-Label sein darf. Das tritt z.B. auf bei
+               ;; (read-from-string "#1=#S(FOO :X #1#)")
+               ;; im Konstruktor MAKE-FOO. Die Implementation ist aber
+               ;; nicht gezwungen, bei fehlerhaftem THE zwingend einen
+               ;; Fehler zu melden, darum ist ein lascherer Typcheck hier
+               ;; erlaubt.
+               (let ((g (gensym)))
+                 `(let ((,g ,objform))
+                    (or (typep ,g ,typform) (eq (type-of ,g) 'READ-LABEL))))))
+    (if (and (consp type) (eq (car type) 'VALUES))
+      ;; The VALUES type specifier is ill-defined in ANSI CL.
+      ;;
+      ;; There are two possibilities to define a VALUES type specifier in a
+      ;; sane way:
+      ;; - (EXACT-VALUES type1 ... [&optional ...]) describes the exact shape
+      ;;   of the values list, as received by MULTIPLE-VALUE-LIST.
+      ;;   For example, (EXACT-VALUES SYMBOL) is matched by (values 'a) but not
+      ;;   by (values 'a 'b) or (values).
+      ;; - (ASSIGNABLE-VALUES type1 ... [&optional ...]) describes the values
+      ;;   as received by a set of variables through MULTIPLE-VALUE-BIND or
+      ;;   MULTIPLE-VALUE-SETQ. For example, (ASSIGNABLE-VALUES SYMBOL) is
+      ;;   defined by whether
+      ;;     (MULTIPLE-VALUE-BIND (var1) values (DECLARE (TYPE SYMBOL var1)) ...)
+      ;;   is valid or not; therefore (ASSIGNABLE-VALUES SYMBOL) is matched by
+      ;;   (values 'a) and (values 'a 'b) and (values).
+      ;;   Note that &OPTIONAL is actually redundant here:
+      ;;     (ASSIGNABLE-VALUES type1 ... &optional otype1 ...)
+      ;;   is equivalent to
+      ;;     (ASSIGNABLE-VALUES type1 ... (OR NULL otype1) ...)
+      ;; HyperSpec/Body/typspe_values.html indicates that VALUES means
+      ;; EXACT-VALUES; however, HyperSpec/Body/speope_the.html indicates that
+      ;; VALUES means ASSIGNABLE-VALUES.
+      ;;
+      ;; SBCL interprets the VALUES type specifier to mean EXACT-VALUES when
+      ;; it contains &OPTIONAL or &REST, but ASSIGNABLE-VALUES when it has
+      ;; only a tuple of type specifiers. This is utter nonsense, in particular
+      ;; because it makes (VALUES type1 ... typek &OPTIONAL)
+      ;; different from   (VALUES type1 ... typek).
+      ;;
+      ;; Here we use the ASSIGNABLE-VALUES interpretation.
+      ;; In SUBTYPEP we just punt and don't assume any interpretation.
+      (let ((vals values) (types (cdr type)))
+        ;; required:
+        (loop
+          (when (or (atom types) (atom vals)) (return-from %the t))
+          (when (memq (car types) lambda-list-keywords) (return))
+          (unless (near-typep (pop vals) (pop types))
+            (return-from %the nil)))
+        ;; &optional:
+        (when (and (consp types) (eq (car types) '&optional))
+          (setq types (cdr types))
+          (loop
+            (when (or (atom types) (atom vals)) (return-from %the t))
+            (when (memq (car types) lambda-list-keywords) (return))
+            (unless (near-typep (pop vals) (pop types))
+              (return-from %the nil))))
+        ;; &rest &key:
+        (case (car types)
+          (&rest
+           (setq types (cdr types))
+           (when (atom types) (typespec-error 'the type))
+           (unless (near-typep (pop vals) (pop types))
+             (return-from %the nil)))
+          (&key)
+          (t (typespec-error 'the type)))
+        (if (eq (car types) '&key)
+          (progn
+            (setq types (cdr types))
+            (when (oddp (length vals)) (return-from %the nil))
+            (let ((keywords nil))
+              (loop
+                (when (or (atom types) (atom vals)) (return-from %the t))
+                (when (memq (car types) lambda-list-keywords) (return))
+                (let ((item (pop types)))
+                  (unless (and (listp item) (eql (length item) 2)
+                               (symbolp (first item)))
+                    (typespec-error 'the type))
+                  (let ((kw (symbol-to-keyword (first item))))
+                    (unless (near-typep (getf vals kw) (second item))
+                      (return-from %the nil))
+                    (push kw keywords))))
+              (if (and (consp types) (eq (car types) '&allow-other-keys))
+                (setq types (cdr types))
+                (unless (getf vals ':allow-other-keys)
+                  (do ((L vals (cddr L)))
+                      ((atom L))
+                    (unless (memq (car L) keywords)
+                      (return-from %the nil)))))))
+          (when (consp types) (typespec-error 'the type)))
+        t)
+      (near-typep (if (consp values) (car values) nil) type))))
+
+;;; ===========================================================================
+
+;; SUBTYPEP
+(load "subtypep")
+
+
+;; Returns the number of bytes that are needed to represent #\Null in a
+;; given encoding.
+(defun encoding-zeroes (encoding)
+  #+UNICODE
+  ;; this should use min_bytes_per_char for cache, not the hash table
+  (let ((name (ext:encoding-charset encoding))
+        (table #.(make-hash-table :key-type '(or string symbol) :value-type 'fixnum
+                                  :test 'stablehash-equal :warn-if-needs-rehash-after-gc t
+                                  :initial-contents '(("UTF-7" . 1))))
+        (tester #.(make-string 2 :initial-element (code-char 0))))
+    (or (gethash name table)
+        (setf (gethash name table)
+              (- (length (ext:convert-string-to-bytes tester encoding))
+                 (length (ext:convert-string-to-bytes tester encoding
+                                                      :end 1))))))
+  #-UNICODE 1)
+
+;; Determines two values low,high such that
+;;   (subtypep type `(INTEGER ,low ,high))
+;; holds and low is as large as possible and high is as small as possible.
+;; low = * means -infinity, high = * means infinity.
+;; When (subtypep type 'INTEGER) is false, the values NIL,NIL are returned.
+;; We need this function only for MAKE-ARRAY, UPGRADED-ARRAY-ELEMENT-TYPE and
+;; OPEN and can therefore w.l.o.g. replace
+;;   type  with  `(OR ,type (MEMBER 0))
+#| ;; The original implementation calls canonicalize-type and then applies
+   ;; a particular SUBTYPE variant:
+ (defun subtype-integer (type)
+  (macrolet ((yes () '(return-from subtype-integer (values low high)))
+             (no () '(return-from subtype-integer nil))
+             (unknown () '(return-from subtype-integer nil)))
+    (setq type (canonicalize-type type))
+    (if (consp type)
+      (case (first type)
+        (MEMBER ; (MEMBER &rest objects)
+          ;; All elements must be of type INTEGER.
+          (let ((low 0) (high 0)) ; wlog!
+            (dolist (x (rest type) (yes))
+              (unless (typep x 'INTEGER) (return (no)))
+              (setq low (min low x) high (max high x)))))
+        (OR ; (OR type*)
+          ;; Every type must be subtype of INTEGER.
+          (let ((low 0) (high 0)) ; wlog!
+            (dolist (type1 (rest type) (yes))
+              (multiple-value-bind (low1 high1) (subtype-integer type1)
+                (unless low1 (return (no)))
+                (setq low (if (or (eq low '*) (eq low1 '*)) '* (min low low1))
+                      high (if (or (eq high '*) (eq high1 '*))
+                               '* (max high high1)))))))
+        (AND ; (AND type*)
+          ;; If one of the types is subtype of INTEGER, then yes,
+          ;; otherwise unknown.
+          (let ((low nil) (high nil))
+            (dolist (type1 (rest type))
+              (multiple-value-bind (low1 high1) (subtype-integer type1)
+                (when low1
+                  (if low
+                    (setq low (if (eq low '*) low1 (if (eq low1 '*) low (max low low1)))
+                          high (if (eq high '*) high1 (if (eq high1 '*) high (min high high1))))
+                    (setq low low1 high high1)))))
+            (if low
+              (progn
+                (when (and (numberp low) (numberp high) (not (<= low high)))
+                  (setq low 0 high 0) ; type equivalent to NIL)
+                (yes))
+              (unknown)))))
+      (setq type (list type)))
+    (if (eq (first type) 'INTEGER)
+      (let ((low (if (rest type) (second type) '*))
+            (high (if (cddr type) (third type) '*)))
+        (when (consp low)
+          (setq low (first low))
+          (when (numberp low) (incf low)))
+        (when (consp high)
+          (setq high (first high))
+          (when (numberp high) (decf high)))
+        (when (and (numberp low) (numberp high) (not (<= low high))) ; type leer?
+          (setq low 0 high 0))
+        (yes))
+      (if (and (eq (first type) 'INTERVALS) (eq (second type) 'INTEGER))
+        (let ((low (third type))
+              (high (car (last type))))
+          (when (consp low)
+            (setq low (first low))
+            (when (numberp low) (incf low)))
+          (when (consp high)
+            (setq high (first high))
+            (when (numberp high) (decf high)))
+          (yes))
+        (unknown)))))
+|# ;; This implementation inlines the (tail-recursive) canonicalize-type
+   ;; function. Its advantage is that it doesn't cons as much.
+   ;; (For example, (subtype-integer '(UNSIGNED-BYTE 8)) doesn't cons.)
+(defun subtype-integer (type)
+  (macrolet ((yes () '(return-from subtype-integer (values low high)))
+             (no () '(return-from subtype-integer nil))
+             (unknown () '(return-from subtype-integer nil)))
+    (setq type (expand-deftype type))
+    (cond ((symbolp type)
+           (case type
+             (BIT (let ((low 0) (high 1)) (yes)))
+             (FIXNUM
+              (let ((low '#,most-negative-fixnum)
+                    (high '#,most-positive-fixnum))
+                (yes)))
+             ((INTEGER BIGNUM SIGNED-BYTE)
+              (let ((low '*) (high '*)) (yes)))
+             (UNSIGNED-BYTE
+              (let ((low 0) (high '*)) (yes)))
+             ((NIL)
+              (let ((low 0) (high 0)) (yes))) ; wlog!
+             (t (no))))
+          ((and (consp type) (symbolp (first type)))
+           (unless (and (list-length type) (null (cdr (last type))))
+             (typespec-error 'subtypep type))
+           (case (first type)
+             (MEMBER ; (MEMBER &rest objects)
+              ;; All elements must be of type INTEGER.
+              (let ((low 0) (high 0)) ; wlog!
+                (dolist (x (rest type) (yes))
+                  (unless (typep x 'INTEGER) (return (no)))
+                  (setq low (min low x) high (max high x)))))
+             (EQL ; (EQL object)
+              (let ((x (second type)))
+                (if (typep x 'INTEGER)
+                  (let ((low (min 0 x)) (high (max 0 x))) (yes))
+                  (no))))
+             (OR ; (OR type*)
+              ;; Every type must be subtype of INTEGER.
+              (let ((low 0) (high 0)) ; wlog!
+                (dolist (type1 (rest type) (yes))
+                  (multiple-value-bind (low1 high1) (subtype-integer type1)
+                    (unless low1 (return (no)))
+                    (setq low (if (or (eq low '*) (eq low1 '*))
+                                  '* (min low low1))
+                          high (if (or (eq high '*) (eq high1 '*))
+                                   '* (max high high1)))))))
+             (AND ; (AND type*)
+              ;; If one of the types is subtype of INTEGER, then yes,
+              ;; otherwise unknown.
+              (let ((low nil) (high nil))
+                (dolist (type1 (rest type))
+                  (multiple-value-bind (low1 high1) (subtype-integer type1)
+                    (when low1
+                      (if low
+                        (setq low (if (eq low '*) low1
+                                      (if (eq low1 '*) low
+                                          (max low low1)))
+                              high (if (eq high '*) high1
+                                       (if (eq high1 '*) high
+                                           (min high high1))))
+                        (setq low low1
+                              high high1)))))
+                (if low
+                  (progn
+                    (when (and (numberp low) (numberp high)
+                               (not (<= low high)))
+                      (setq low 0 high 0)) ; type equivalent to NIL
+                    (yes))
+                  (unknown))))
+             (INTEGER
+              (let ((low (if (rest type) (second type) '*))
+                    (high (if (cddr type) (third type) '*)))
+                (when (consp low)
+                  (setq low (first low))
+                  (when (numberp low) (incf low)))
+                (when (consp high)
+                  (setq high (first high))
+                  (when (numberp high) (decf high)))
+                (when (and (numberp low) (numberp high) (not (<= low high)))
+                  (setq low 0 high 0)) ; type equivalent to NIL
+                (yes)))
+             (INTERVALS
+              (if (eq (second type) 'INTEGER)
+                (let ((low (third type))
+                      (high (car (last type))))
+                  (when (consp low)
+                    (setq low (first low))
+                    (when (numberp low) (incf low)))
+                  (when (consp high)
+                    (setq high (first high))
+                    (when (numberp high) (decf high)))
+                  (yes))
+                (unknown)))
+             (MOD ; (MOD n)
+              (let ((n (second type)))
+                (unless (and (integerp n) (>= n 0))
+                  (typespec-error 'subtypep type))
+                (if (eql n 0)
+                  (no)
+                  (let ((low 0) (high (1- n)))
+                    (yes)))))
+             (SIGNED-BYTE ; (SIGNED-BYTE &optional s)
+              (let ((s (if (cdr type) (second type) '*)))
+                (if (eq s '*)
+                  (let ((low '*) (high '*)) (yes))
+                  (progn
+                    (unless (and (integerp s) (plusp s))
+                      (typespec-error 'subtypep type))
+                    (let ((n (ash 1 (1- s)))) ; (ash 1 *) == (expt 2 *)
+                      (let ((low (- n)) (high (1- n)))
+                        (yes)))))))
+             (UNSIGNED-BYTE ; (UNSIGNED-BYTE &optional s)
+              (let ((s (if (cdr type) (second type) '*)))
+                (if (eq s '*)
+                    (let ((low 0) (high '*)) (yes))
+                    (progn
+                      (unless (and (integerp s) (>= s 0))
+                        (typespec-error 'subtypep type))
+                      (let ((n (ash 1 s))) ; (ash 1 *) == (expt 2 *)
+                        (let ((low 0) (high (1- n)))
+                          (yes)))))))
+             (t (no))))
+          ((clos::defined-class-p type)
+           (if (and (clos::built-in-class-p type)
+                    (eq (get (clos:class-name type) 'CLOS::CLOSCLASS) type))
+             (return-from subtype-integer
+               (subtype-integer (clos:class-name type)))
+             (no)))
+          ((clos::eql-specializer-p type)
+           (let ((x (clos::eql-specializer-singleton type)))
+             (if (typep x 'INTEGER)
+               (let ((low (min 0 x)) (high (max 0 x))) (yes))
+               (no))))
+          ((encodingp type) (no))
+          (t (typespec-error 'subtypep type)))))
+
+#| TODO: Fix subtype-integer such that this works.
+Henry Baker:
+ (defun type-null (x)
+  (values (and (eq 'bit (upgraded-array-element-type `(or bit ,x)))
+               (not (typep 0 x))
+               (not (typep 1 x)))
+          t))
+ (type-null '(and symbol number))
+ (type-null '(and integer symbol))
+ (type-null '(and integer character))
+|#
+
+;; Determines a sequence kind (an atom, as defined in defseq.lisp: one of
+;;   LIST - stands for LIST
+;;   VECTOR - stands for (VECTOR T)
+;;   STRING - stands for (VECTOR CHARACTER)
+;;   1, 2, 4, 8, 16, 32 - stands for (VECTOR (UNSIGNED-BYTE n))
+;;   0 - stands for (VECTOR NIL))
+;; that indicates the sequence type meant by the given type. Other possible
+;; return values are
+;;   SEQUENCE - denoting a type whose intersection with (OR LIST VECTOR) is not
+;;              subtype of LIST or VECTOR, or
+;;   NIL - indicating a type whose intersection with (OR LIST VECTOR) is empty.
+;; When the type is (OR (VECTOR eltype1) ... (VECTOR eltypeN)), the chosen
+;; element type is the smallest element type that contains all of eltype1 ...
+;; eltypeN.
+;;
+;; User-defined sequence types are not supported here.
+;;
+;; This implementation inlines the (tail-recursive) canonicalize-type
+;; function. Its advantage is that it doesn't cons as much. Also it employs
+;; some heuristics and does not have the full power of SUBTYPEP.
+(defun subtype-sequence (type)
+  (setq type (expand-deftype type))
+  (cond ((symbolp type)
+         (case type
+           ((LIST CONS NULL) 'LIST)
+           ((NIL) 'NIL)
+           ((BIT-VECTOR SIMPLE-BIT-VECTOR) '1)
+           ((STRING SIMPLE-STRING BASE-STRING SIMPLE-BASE-STRING) 'STRING)
+           ((VECTOR SIMPLE-VECTOR ARRAY SIMPLE-ARRAY) 'VECTOR)
+           ((SEQUENCE) 'SEQUENCE)
+           (t 'NIL)))
+        ((and (consp type) (symbolp (first type)))
+         (unless (and (list-length type) (null (cdr (last type))))
+           (typespec-error 'subtypep type))
+         (case (first type)
+           (MEMBER ; (MEMBER &rest objects)
+            (let ((kind 'NIL))
+              (dolist (x (rest type))
+                (setq kind (sequence-type-union kind (type-of-sequence x))))
+              kind))
+           (EQL ; (EQL object)
+            (unless (eql (length type) 2)
+              (typespec-error 'subtypep type))
+            (type-of-sequence (second type)))
+           (OR ; (OR type*)
+            (let ((kind 'NIL))
+              (dolist (x (rest type))
+                (setq kind (sequence-type-union kind (subtype-sequence x))))
+              kind))
+           (AND ; (AND type*)
+            (let ((kind 'SEQUENCE))
+              (dolist (x (rest type))
+                (setq kind (sequence-type-intersection kind (subtype-sequence x))))
+              kind))
+           ((SIMPLE-BIT-VECTOR BIT-VECTOR) ; (SIMPLE-BIT-VECTOR &optional size)
+            (when (cddr type)
+              (typespec-error 'subtypep type))
+            '1)
+           ((SIMPLE-STRING STRING SIMPLE-BASE-STRING BASE-STRING) ; (SIMPLE-STRING &optional size)
+            (when (cddr type)
+              (typespec-error 'subtypep type))
+            'STRING)
+           (SIMPLE-VECTOR ; (SIMPLE-VECTOR &optional size)
+            (when (cddr type)
+              (typespec-error 'subtypep type))
+            'VECTOR)
+           ((VECTOR ARRAY SIMPLE-ARRAY) ; (VECTOR &optional el-type size), (ARRAY &optional el-type dimensions)
+            (when (cdddr type)
+              (typespec-error 'subtypep type))
+            (let ((el-type (if (cdr type) (second type) '*)))
+              (if (eq el-type '*)
+                'VECTOR
+                (let ((eltype (upgraded-array-element-type el-type)))
+                  (cond ((eq eltype 'T) 'VECTOR)
+                        ((eq eltype 'CHARACTER) 'STRING)
+                        ((eq eltype 'BIT) '1)
+                        ((and (consp eltype) (eq (first eltype) 'UNSIGNED-BYTE)) (second eltype))
+                        ((eq eltype 'NIL) '0)
+                        (t (error (TEXT "~S is not up-to-date with ~S for element type ~S")
+                                  'subtypep-sequence 'upgraded-array-element-type eltype)))))))
+           ((CONS) ; (CONS &optional cartype cdrtype)
+            (when (cdddr type)
+              (typespec-error 'subtypep type))
+            'LIST)
+           (t 'NIL)))
+        ((clos::defined-class-p type)
+         (if (and (clos::built-in-class-p type)
+                  (eq (get (clos:class-name type) 'CLOS::CLOSCLASS) type))
+           (subtype-sequence (clos:class-name type))
+           'NIL))
+        ((clos::eql-specializer-p type)
+         (type-of-sequence (clos::eql-specializer-singleton type)))
+        (t 'NIL)))
+(defun type-of-sequence (x)
+  (cond ((listp x) 'LIST)
+        ((vectorp x)
+         (let ((eltype (array-element-type x)))
+           (cond ((eq eltype 'T) 'VECTOR)
+                 ((eq eltype 'CHARACTER) 'STRING)
+                 ((eq eltype 'BIT) '1)
+                 ((and (consp eltype) (eq (first eltype) 'UNSIGNED-BYTE)) (second eltype))
+                 ((eq eltype 'NIL) '0)
+                 (t (error (TEXT "~S is not up-to-date with ~S for element type ~S")
+                           'type-of-sequence 'array-element-type eltype)))))
+        (t 'NIL)))
+(defun sequence-type-union (t1 t2)
+  (cond ; Simple general rules.
+        ((eql t1 t2) t1)
+        ((eq t1 'NIL) t2)
+        ((eq t2 'NIL) t1)
+        ; Now the union of two different types.
+        ((or (eq t1 'SEQUENCE) (eq t2 'SEQUENCE)) 'SEQUENCE)
+        ((or (eq t1 'LIST) (eq t2 'LIST))
+         ; union of LIST and a vector type
+         'SEQUENCE)
+        ((or (eq t1 'VECTOR) (eq t2 'VECTOR)) 'VECTOR)
+        ((eql t1 0) t2)
+        ((eql t2 0) t1)
+        ((or (eq t1 'STRING) (eq t2 'STRING))
+         ; union of STRING and an integer-vector type
+         'VECTOR)
+        (t (max t1 t2))))
+(defun sequence-type-intersection (t1 t2)
+  (cond ; Simple general rules.
+        ((eql t1 t2) t1)
+        ((or (eq t1 'NIL) (eq t2 'NIL)) 'NIL)
+        ; Now the intersection of two different types.
+        ((eq t1 'SEQUENCE) t2)
+        ((eq t2 'SEQUENCE) t1)
+        ((or (eq t1 'LIST) (eq t2 'LIST))
+         ; intersection of LIST and a vector type
+         'NIL)
+        ((eq t1 'VECTOR) t2)
+        ((eq t2 'VECTOR) t1)
+        ((or (eql t1 0) (eql t2 0)) '0)
+        ((or (eq t1 'STRING) (eq t2 'STRING))
+         ; intersection of STRING and an integer-vector type
+         '0)
+        (t (min t1 t2))))
+
+;; ============================================================================
+
+(defun type-expand (typespec &optional once-p)
+  (multiple-value-bind (expanded user-defined-p)
+      (expand-deftype typespec once-p)
+    (if user-defined-p (values expanded user-defined-p)
+      (cond ((symbolp typespec)
+             (cond ((or (get typespec 'TYPE-SYMBOL) (get typespec 'TYPE-LIST))
+                    (values typespec nil))
+                   ((or (get typespec 'DEFSTRUCT-DESCRIPTION)
+                        (clos-class typespec))
+                    (values typespec nil))
+                   (t (typespec-error 'type-expand typespec))))
+            ((and (consp typespec) (symbolp (first typespec)))
+             (case (first typespec)
+               ((SATISFIES MEMBER EQL NOT AND OR) (values typespec nil))
+               (t (cond ((get (first typespec) 'TYPE-LIST)
+                         (values typespec nil))
+                        (t (typespec-error 'type-expand typespec))))))
+            ((clos::defined-class-p typespec) (values typespec nil))
+            (t (typespec-error 'type-expand typespec))))))
+
+;; ============================================================================
+
+(unless (clos::funcallable-instance-p #'clos::class-name)
+  (fmakunbound 'clos::class-name))
diff --git a/app/server/vendor/rouge/spec/visual/samples/conf b/app/server/vendor/rouge/spec/visual/samples/conf
new file mode 100755
index 0000000..73af793
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/conf
@@ -0,0 +1,55 @@
+# Configuration file for /sbin/dhclient, which is included in Debian's
+#	dhcp3-client package.
+#
+# This is a sample configuration file for dhclient. See dhclient.conf's
+#	man page for more information about the syntax of this file
+#	and a more comprehensive list of the parameters understood by
+#	dhclient.
+#
+# Normally, if the DHCP server provides reasonable information and does
+#	not leave anything out (like the domain name, for example), then
+#	few changes must be made to this file, if any.
+#
+
+option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;
+
+send host-name "<hostname>";
+#send dhcp-client-identifier 1:0:a0:24:ab:fb:9c;
+#send dhcp-lease-time 3600;
+#supersede domain-name "fugue.com home.vix.com";
+#prepend domain-name-servers 127.0.0.1;
+request subnet-mask, broadcast-address, time-offset, routers,
+	domain-name, domain-name-servers, domain-search, host-name,
+	netbios-name-servers, netbios-scope, interface-mtu,
+	rfc3442-classless-static-routes, ntp-servers,
+	dhcp6.domain-search, dhcp6.fqdn,
+	dhcp6.name-servers, dhcp6.sntp-servers;
+#require subnet-mask, domain-name-servers;
+#timeout 60;
+#retry 60;
+#reboot 10;
+#select-timeout 5;
+#initial-interval 2;
+#script "/etc/dhcp3/dhclient-script";
+#media "-link0 -link1 -link2", "link0 link1";
+#reject 192.33.137.209;
+
+alias {
+  interface "eth0";
+  fixed-address 192.5.5.213;
+  option subnet-mask 255.255.255.255;
+}
+
+#lease {
+#  interface "eth0";
+#  fixed-address 192.33.137.200;
+#  medium "link0 link1";
+#  option host-name "andare.swiftmedia.com";
+#  option subnet-mask 255.255.255.0;
+#  option broadcast-address 192.33.137.255;
+#  option routers 192.33.137.250;
+#  option domain-name-servers 127.0.0.1;
+#  renew 2 2000/1/12 00:00:01;
+#  rebind 2 2000/1/12 00:00:01;
+#  expire 2 2000/1/12 00:00:01;
+#}
diff --git a/app/server/vendor/rouge/spec/visual/samples/cpp b/app/server/vendor/rouge/spec/visual/samples/cpp
new file mode 100755
index 0000000..542b96e
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/cpp
@@ -0,0 +1,60 @@
+int quote_delims = 100'000'000
+int float_delims = 100.00'00
+int hex_delims = 0xFF'Fa12
+
+/* foo */ #if 0
+ this is commented
+#endif
+
+/* it shouldn't hang */	/* trying to lex this */
+/*{"ahg/awn/xan?",	HB_TAG('A','G','W',' ')},*/	/* Agaw */
+/*{"gsw?/gsw-FR?",	HB_TAG('A','L','S',' ')},*/	/* Alsatian */
+/*{"krc",	HB_TAG('B','A','L',' ')},*/	/* Balkar */
+/*{"??",	HB_TAG('B','C','R',' ')},*/	/* Bible Cree */
+/*{"sgw?",	HB_TAG('C','H','G',' ')},*/	/* Chaha Gurage */
+/*{"acf/gcf?",	HB_TAG('F','A','N',' ')},*/	/* French Antillean */
+/*{"vls/nl-be",	HB_TAG('F','L','E',' ')},*/	/* Flemish */
+/*{"enf?/yrk?",	HB_TAG('F','N','E',' ')},*/	/* Forest Nenets */
+/*{"fuf?",	HB_TAG('F','T','A',' ')},*/	/* Futa */
+/*{"ar-Syrc?",	HB_TAG('G','A','R',' ')},*/	/* Garshuni */
+/*{"cfm/rnl?",	HB_TAG('H','A','L',' ')},*/	/* Halam */
+/*{"ga-Latg?/Latg?",	HB_TAG('I','R','T',' ')},*/	/* Irish Traditional */
+/*{"krc",	HB_TAG('K','A','R',' ')},*/	/* Karachay */
+/*{"alw?/ktb?",	HB_TAG('K','E','B',' ')},*/	/* Kebena */
+/*{"Geok",	HB_TAG('K','G','E',' ')},*/	/* Khutsuri Georgian */
+/*{"kca",	HB_TAG('K','H','K',' ')},*/	/* Khanty-Kazim */
+/*{"kca",	HB_TAG('K','H','S',' ')},*/	/* Khanty-Shurishkar */
+
+#define foo bar
+#define baz zot
+
+class Highlighter : public QSyntaxHighlighter
+{
+   class InnerClass {}
+
+   Q_OBJECT
+
+public:
+   Highlighter(QTextDocument *parent = 0);
+
+protected:
+   void highlightBlock(const QString &text);
+
+private:
+   struct HighlightingRule
+   {
+       QRegExp pattern;
+       QTextCharFormat format;
+   };
+   QVector<HighlightingRule> highlightingRules;
+
+   QRegExp commentStartExpression;
+   QRegExp commentEndExpression;
+
+   QTextCharFormat keywordFormat;
+   QTextCharFormat classFormat;
+   QTextCharFormat singleLineCommentFormat;
+   QTextCharFormat multiLineCommentFormat;
+   QTextCharFormat quotationFormat;
+   QTextCharFormat functionFormat;
+};
diff --git a/app/server/vendor/rouge/spec/visual/samples/csharp b/app/server/vendor/rouge/spec/visual/samples/csharp
new file mode 100755
index 0000000..ffa9bfe
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/csharp
@@ -0,0 +1,351 @@
+////////////////////////////////////////////////////////////////////////////////
+//                                                                            //
+// MIT X11 license, Copyright (c) 2005-2006 by:                               //
+//                                                                            //
+// Authors:                                                                   //
+//      Michael Dominic K. <michaldominik at gmail.com>                          //
+//                                                                            //
+// Permission is hereby granted, free of charge, to any person obtaining a    //
+// copy of this software and associated documentation files (the "Software"), //
+// to deal in the Software without restriction, including without limitation  //
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,   //
+// and/or sell copies of the Software, and to permit persons to whom the      //
+// Software is furnished to do so, subject to the following conditions:       //
+//                                                                            //
+// The above copyright notice and this permission notice shall be included    //
+// in all copies or substantial portions of the Software.                     //
+//                                                                            //
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS    //
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF                 //
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN  //
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   //
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      //
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  //
+// USE OR OTHER DEALINGS IN THE SOFTWARE.                                     //
+//                                                                            //
+////////////////////////////////////////////////////////////////////////////////
+
+namespace Diva.Core {
+        
+        using System;
+        using Widgets;
+        using System.Xml;
+        using Util;
+        using System.Collections.Generic;
+        using System.Collections;
+        using Basics;
+
+        public class OpenerTask : Task, IBoilProvider {
+
+                // Private structs ////////////////////////////////////////////
+                
+                struct ObjectInfo {
+
+                        public ObjectContainer Container;
+                        public int[] Depends;
+                        public string SystemType;
+                        public int RefId;
+                        
+                        /* CONSTRUCTOR */
+                        public ObjectInfo (ObjectContainer container)
+                        {
+                                Container = container;
+                                Depends = container.Depends.ToArray ();
+                                SystemType = container.SystemType;
+                                RefId = container.RefId;
+                        }
+                        
+                        public override string ToString ()
+                        {
+                                return String.Format ("Type: {0} Deps count: {1} Id: {2}",
+                                                      SystemType, Depends.Length, RefId);
+                        }
+                        
+                        public bool IsUnBoilable (IBoilProvider provider)
+                        {
+                                if (Depends.Length == 0)
+                                        return true;
+                                
+                                foreach (int id in Depends)
+                                        if (! (provider.Contains (id)))
+                                                return false;
+                                
+                                return true;
+                        }
+                        
+                }
+                                 
+                // Enums //////////////////////////////////////////////////////
+                
+                enum OpenerTaskStep { Init, Header, ProjectInfoRead, ObjectListRead,
+                                      ObjectListParse, ObjectListUnBoil, FindRoots,
+                                      Finished };
+                
+                // Fields /////////////////////////////////////////////////////
+                
+                string fileName;                         // Filename we're reading
+                XmlDocument xmlDocument;                 // Our document
+                //XmlNode projectInfoNode;               // <projectinfo> node
+                IEnumerator objectsEnumerator;           // Enumerator
+                List <ObjectInfo> objectsList;           // Objects list
+                ObjectListContainer objectListContainer;
+                OpenerTaskStep currentStep;              // Our current step
+                
+                Dictionary <int, object> idToObject;     // Id -> object
+                Dictionary <object, int> objectToId;     // Object -> Id
+
+                string projectName = String.Empty;
+                string projectDirectory = String.Empty;
+                TagList projectTagList;
+                StuffList projectStuffList;
+                TrackList projectTrackList;
+                ClipList projectClipList;
+                MediaItemList projectMediaItemList;
+                Commander projectCommander;
+                Gdv.Pipeline projectPipeline;
+                Gdv.ProjectFormat projectFormat;
+                
+                // Properties /////////////////////////////////////////////////
+                
+                public string ProjectName {
+                        get { return projectName; }
+                }
+                
+                public string ProjectDirectory {
+                        get { return projectDirectory; }
+                }
+                
+                public TagList ProjectTagList {
+                        get { return projectTagList; }
+                }
+                
+                public StuffList ProjectStuffList {
+                        get { return projectStuffList; }
+                }
+                
+                public TrackList ProjectTrackList {
+                        get { return projectTrackList; }
+                }
+
+                public ClipList ProjectClipList {
+                        get { return projectClipList; }
+                }
+                
+                public MediaItemList ProjectMediaItemList {
+                        get { return projectMediaItemList; }
+                }
+                
+                public Commander ProjectCommander {
+                        get { return projectCommander; }
+                }
+                
+                public Gdv.Pipeline ProjectPipeline {
+                        get { return projectPipeline; }
+                }
+
+                public Gdv.ProjectFormat ProjectFormat {
+                        get { return projectFormat; }
+                }
+
+                // Public methods /////////////////////////////////////////////
+                
+                /* CONSTRUCTOR */
+                public OpenerTask (string fileName)
+                {
+                        this.fileName = fileName;
+                }
+                
+                public override void Reset ()
+                {
+                        objectToId = new Dictionary <object, int> ();
+                        idToObject = new Dictionary <int, object> ();
+                        
+                        xmlDocument = null;
+                        //projectInfoNode = null;
+                        
+                        currentStep = OpenerTaskStep.Init;
+                        
+                        base.Reset ();
+                }
+                
+                public int GetIdForObject (object o)
+                {
+                        return objectToId [o];
+                }
+                
+                public object GetObjectForId (int id)
+                {
+                        return idToObject [id];
+                }
+                
+                public bool Contains (int id)
+                {
+                        return idToObject.ContainsKey (id);
+                }
+                
+                // Private methods ////////////////////////////////////////////
+                
+                protected override TaskStatus ExecuteStep (int s)
+                {
+                        bool cont = true;
+                        
+                        // Main
+                        switch (currentStep) {
+                                        
+                                case OpenerTaskStep.Init:
+                                        objectsList = new List <ObjectInfo> ();
+                                        xmlDocument = new XmlDocument ();
+                                        xmlDocument.Load (fileName);
+                                        currentStep = OpenerTaskStep.Header;
+                                        break;
+                                        
+                                case OpenerTaskStep.Header:
+                                        //ReadHeader ();
+                                        currentStep = OpenerTaskStep.ProjectInfoRead;
+                                        break;
+
+                                case OpenerTaskStep.ProjectInfoRead:
+                                        foreach (XmlNode node in xmlDocument.DocumentElement.ChildNodes)
+                                                if (node.Name == "projectinfo") 
+                                                        ResolveProjectInfoNode (node);
+
+                                        // FIXME: Fail if not found/not resolved
+                                        currentStep = OpenerTaskStep.ObjectListRead;
+                                        break;
+                                        
+                                case OpenerTaskStep.ObjectListRead:
+                                        foreach (XmlNode node in xmlDocument.DocumentElement.ChildNodes)
+                                                if (node.Name == "objectlist") 
+                                                        objectListContainer = (ObjectListContainer)
+                                                                DataFactory.MakeDataElement  (node as XmlElement);
+                                                        
+                                        if (objectListContainer == null)
+                                                throw new Exception ("ObjectListContainer not found!");
+
+                                        currentStep = OpenerTaskStep.ObjectListParse;
+                                        break;
+
+                                case OpenerTaskStep.ObjectListParse:
+                                        bool flush = EnumerateSomeObjects ();
+                                        if (flush)
+                                                currentStep = OpenerTaskStep.ObjectListUnBoil;
+                                        break;
+
+                                case OpenerTaskStep.ObjectListUnBoil:
+                                        bool done = UnBoilSomeObjects ();
+                                        if (done)
+                                                currentStep = OpenerTaskStep.FindRoots;
+                                        break;
+                                        
+                                        
+                                case OpenerTaskStep.FindRoots:
+                                        projectTrackList = (TrackList) FindRoot ("tracklist");
+                                        projectTagList = (TagList) FindRoot ("taglist");
+                                        projectStuffList = (StuffList) FindRoot ("stufflist");
+                                        projectClipList = (ClipList) FindRoot ("cliplist");
+                                        projectMediaItemList = (MediaItemList) FindRoot ("mediaitemlist");
+                                        projectPipeline = (Gdv.Pipeline) FindRoot ("pipeline");
+                                        projectCommander = (Commander) FindRoot ("commander");
+                                        projectFormat = (Gdv.ProjectFormat) FindRoot ("projectformat");
+                                        
+                                        currentStep = OpenerTaskStep.Finished;
+                                        break;
+                                        
+                                case OpenerTaskStep.Finished:
+                                        cont = false;
+                                        break;
+                                        
+                                default:
+                                        break;
+                        }
+                                                
+                        // Post 
+                        if (cont) 
+                                return TaskStatus.Running;
+                        else
+                                return TaskStatus.Done;
+                }
+
+                /*
+                void ReadHeader ()
+                {
+                        // FIXME: Read all the attributes from the <divaproject> element
+                        }*/
+
+                void ResolveProjectInfoNode (XmlNode node)
+                {
+                        foreach (XmlNode childNode in node) {
+                                
+                                switch (childNode.Name) {
+                                        
+                                        case "name":
+                                                projectName = childNode.FirstChild.Value;
+                                                break;
+                                        
+                                        case "directory":
+                                                projectDirectory = childNode.FirstChild.Value;
+                                                break;
+
+                                                // FIXME: Duration etc.
+                                }
+                        }
+                }
+                
+                bool EnumerateSomeObjects ()
+                {
+                        if (objectsEnumerator == null)
+                                objectsEnumerator = objectListContainer.FindAllObjects ().GetEnumerator ();
+                        
+                        for (int i = 0; i < 10; i++) {
+                                if (objectsEnumerator.MoveNext () == false)
+                                        return true;
+
+                                ObjectContainer container = (ObjectContainer)
+                                        objectsEnumerator.Current;
+                                
+                                ObjectInfo newInfo = new ObjectInfo (container);
+                                objectsList.Add (newInfo);
+                        }
+                        
+                        return false;
+                }
+
+                ObjectInfo GetNextCandidate ()
+                {
+                        foreach (ObjectInfo objInfo in objectsList)
+                                if (objInfo.IsUnBoilable (this))
+                                        return objInfo;
+                        
+                        throw new Exception ("FIXME: No more unboilable objects found. Recursive?");
+                }
+                
+                bool UnBoilSomeObjects ()
+                {
+                        for (int i = 0; i < 5; i++) {
+                                // All unboiled
+                                if (objectsList.Count == 0)
+                                        return true;
+                                
+                                ObjectInfo objInfo = GetNextCandidate ();
+
+                                object o = BoilFactory.UnBoil (objInfo.Container, this);
+                                objectsList.Remove (objInfo);
+
+                                // Add
+                                idToObject [objInfo.RefId] = o;
+                                objectToId [o] = objInfo.RefId;
+
+                        }
+                        
+                        return false;
+                }
+
+                object FindRoot (string rootString)
+                {
+                        ObjectContainer container = objectListContainer.FindObjectContainer (rootString);
+                        return idToObject [container.RefId];
+                }
+                
+        }
+        
+}
diff --git a/app/server/vendor/rouge/spec/visual/samples/css b/app/server/vendor/rouge/spec/visual/samples/css
new file mode 100755
index 0000000..33516f1
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/css
@@ -0,0 +1,56 @@
+body {
+    font-size: 12pt;
+    background   : #fff url(temp.png) top left no-repeat;
+}
+
+* html body {
+    font-size: 14pt;
+}
+
+#nav .new {
+    display: block;
+}
+
+ul#nav li.new {
+    font-weight: bold;
+}
+
+:link {
+    color: #f00;
+}
+
+:link:hover {
+    color: #0f0;
+}
+
+#thing {
+  font: normal 400 12px/35px Helvetica, Arial, sans-serif;
+}
+
+ at media screen {
+  body {
+    background: #ccc;
+  }
+}
+
+ at namespace "http://www.w3.org/1999/xhtml";
+
+ at import url("mystyle.css");
+
+ at charset "ISO-8859-1";
+
+ at font-face { font-family: "Example Font"; src: url("http://www.example.com/fonts/example"); }
+
+ at media screen { body { font-size: 16px } } @media print { body { font-size: 12pt } }
+
+
+ at page { body { margin: 1in 1.5in; } }
+
+ at page linke-seite:left { body { margin:20mm; margin-right:25mm; } }
+
+ at -moz-document url-prefix(http://pygments.org) {  a {font-style: normal !important;} }
+
+#foo {
+  unrecognized-prop: 1;
+  -moz-prefixed-prop: 2;
+}
diff --git a/app/server/vendor/rouge/spec/visual/samples/diff b/app/server/vendor/rouge/spec/visual/samples/diff
new file mode 100755
index 0000000..2f346d3
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/diff
@@ -0,0 +1,55 @@
+diff --git a/README.md b/README.md
+index 87f10f4..09ba8c0 100644
+--- a/README.md
++++ b/README.md
+@@ -1,10 +1,23 @@
+ # Rouge
+ 
+-This project is not yet finished, but this works:
++This project needs your help!  There are lots of lexers to be implemented / ported / fixed, and features that need to be added or implemented.  If you'd like to help out, send me a pull request (even if it's not done yet!).  Bonus points for feature branches.
++
++## Usage
+ 
+ ``` ruby
+-formatter = Rouge::Formatters::HTML.new
++# make some nice lexed html, compatible with pygments stylesheets
++formatter = Rouge::Formatters::HTML.new(:css_class => '.highlight')
+ Rouge.highlight(File.read('/etc/bash.bashrc'), 'shell', formatter)
++
++# apply a theme
++Rouge::Themes::ThankfulEyes.new(:scope => '.highlight').render
+ ```
+ 
+-More features, documentation, lexers, and formatters to come.  Help is appreciated, too, if you think this is awesome :)
++Rouge aims to be simple to extend, and to be a drop-in replacement pygments, with the same quality of output.
++
++### Advantages to pygments.rb
++* No python bridge is necessary - you can deploy it on Heroku effortlessly, without the need for [epic hacks][].
++
++### Advantages to CodeRay
++
++[epic hacks]: https://github.com/rumblelabs/pygments-heroku
+diff --git a/lib/rouge.rb b/lib/rouge.rb
+index e86da00..c947a8b 100644
+--- a/lib/rouge.rb
++++ b/lib/rouge.rb
+@@ -16,6 +16,7 @@ load_dir = Pathname.new(__FILE__).dirname
+ load load_dir.join('rouge/token.rb')
+ load load_dir.join('rouge/lexer.rb')
+ load load_dir.join('rouge/lexers/text.rb')
++load load_dir.join('rouge/lexers/diff.rb')
+ load load_dir.join('rouge/lexers/shell.rb')
+ load load_dir.join('rouge/lexers/javascript.rb')
+ 
+diff --git a/lib/rouge/token.rb b/lib/rouge/token.rb
+index ab1701b..155fa52 100644
+--- a/lib/rouge/token.rb
++++ b/lib/rouge/token.rb
+@@ -112,6 +112,7 @@ module Rouge
+     token 'Keyword.Type',                'kt'
+ 
+     token 'Name',                        'n'
++
+     token 'Name.Attribute',              'na'
+     token 'Name.Builtin',                'nb'
+     token 'Name.Builtin.Pseudo',         'bp'
diff --git a/app/server/vendor/rouge/spec/visual/samples/elixir b/app/server/vendor/rouge/spec/visual/samples/elixir
new file mode 100755
index 0000000..3c60246
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/elixir
@@ -0,0 +1,380 @@
+# We cannot use to_char_list because it depends on inspect,
+# which depends on protocol, which depends on this module.
+import Elixir::Builtin, except: [to_char_list: 1]
+
+defmodule Module do
+  require Erlang.ets, as: ETS
+
+  @moduledoc """
+  This module provides many functions to deal with modules during
+  compilation time. It allows a developer to dynamically attach
+  documentation, merge data, register attributes and so forth.
+
+  After the module is compiled, using many of the functions in
+  this module will raise errors, since it is out of their purpose
+  to inspect runtime data. Most of the runtime data can be inspected
+  via the `__info__(attr)` function attached to each compiled module.
+  """
+
+  @doc """
+  Evalutes the quotes contents in the given module context.
+  Raises an error if the module was already compiled.
+
+  ## Examples
+
+      defmodule Foo do
+        contents = quote do: (def sum(a, b), do: a + b)
+        Module.eval_quoted __MODULE__, contents, [], __FILE__, __LINE__
+      end
+
+      Foo.sum(1, 2) #=> 3
+  """
+  def eval_quoted(module, quoted, binding, filename, line) do
+    assert_not_compiled!(:eval_quoted, module)
+    { binding, scope } = Erlang.elixir_module.binding_and_scope_for_eval(line, to_char_list(filename), module, binding)
+    Erlang.elixir_def.reset_last(module)
+    Erlang.elixir.eval_quoted([quoted], binding, line, scope)
+  end
+
+  @doc """
+  Checks if the module is compiled or not.
+
+  ## Examples
+
+      defmodule Foo do
+        Module.compiled?(__MODULE__) #=> false
+      end
+
+      Module.compiled?(Foo) #=> true
+
+  """
+  def compiled?(module) do
+    table = data_table_for(module)
+    table == ETS.info(table, :name)
+  end
+
+  @doc """
+  Reads the data for the given module. This is used
+  to read data of uncompiled modules. If the module
+  was already compiled, you shoul access the data
+  directly by invoking `__info__(:data)` in that module.
+
+  ## Examples
+
+      defmodule Foo do
+        Module.merge_data __MODULE__, value: 1
+        Module.read_data __MODULE__ #=> [value: 1]
+      end
+
+  """
+  def read_data(module) do
+    assert_not_compiled!(:read_data, module)
+    ETS.lookup_element(data_table_for(module), :data, 2)
+  end
+
+  @doc """
+  Reads the data from `module` at the given key `at`.
+
+  ## Examples
+
+      defmodule Foo do
+        Module.merge_data __MODULE__, value: 1
+        Module.read_data __MODULE__, :value #=> 1
+      end
+
+  """
+  def read_data(module, at) do
+    Orddict.get read_data(module), at
+  end
+
+  @doc """
+  Merge the given data into the module, overriding any
+  previous one.
+
+  If any of the given data is a registered attribute, it is
+  automatically added to the attribute set, instead of marking
+  it as data. See register_attribute/2 and add_attribute/3 for
+  more info.
+
+  ## Examples
+
+      defmodule Foo do
+        Module.merge_data __MODULE__, value: 1
+      end
+
+      Foo.__info__(:data) #=> [value: 1]
+
+  """
+  def merge_data(module, data) do
+    assert_not_compiled!(:merge_data, module)
+
+    table      = data_table_for(module)
+    old        = ETS.lookup_element(table, :data, 2)
+    registered = ETS.lookup_element(table, :registered_attributes, 2)
+
+    { attrs, new } = Enum.partition data, fn({k,_}) -> List.member?(registered, k) end
+    Enum.each attrs, fn({k,v}) -> add_attribute(module, k, v) end
+    ETS.insert(table, { :data,  Orddict.merge(old, new) })
+  end
+
+  @doc """
+  Attaches documentation to a given function. It expects
+  the module the function belongs to, the line (a non negative
+  integer), the kind (def or defmacro), a tuple representing
+  the function and its arity and the documentation, which should
+  be either a binary or a boolean.
+
+  ## Examples
+
+      defmodule MyModule do
+        Module.add_doc(__MODULE__, __LINE__ + 1, :def, { :version, 0 }, "Manually added docs")
+        def version, do: 1
+      end
+
+  """
+  def add_doc(module, line, kind, tuple, doc) when
+      is_binary(doc) or is_boolean(doc) do
+    assert_not_compiled!(:add_doc, module)
+    case kind do
+    match: :defp
+      :warn
+    else:
+      table = docs_table_for(module)
+      ETS.insert(table, { tuple, line, kind, doc })
+      :ok
+    end
+  end
+
+  @doc """
+  Checks if a function was defined, regardless if it is
+  a macro or a private function. Use function_defined?/3
+  to assert for an specific type.
+
+  ## Examples
+
+      defmodule Example do
+        Module.function_defined? __MODULE__, { :version, 0 } #=> false
+        def version, do: 1
+        Module.function_defined? __MODULE__, { :version, 0 } #=> true
+      end
+
+  """
+  def function_defined?(module, tuple) when is_tuple(tuple) do
+    assert_not_compiled!(:function_defined?, module)
+    table = function_table_for(module)
+    ETS.lookup(table, tuple) != []
+  end
+
+  @doc """
+  Checks if a function was defined and also for its `kind`.
+  `kind` can be either :def, :defp or :defmacro.
+
+  ## Examples
+
+      defmodule Example do
+        Module.function_defined? __MODULE__, { :version, 0 }, :defp #=> false
+        def version, do: 1
+        Module.function_defined? __MODULE__, { :version, 0 }, :defp #=> false
+      end
+
+  """
+  def function_defined?(module, tuple, kind) do
+    List.member? defined_functions(module, kind), tuple
+  end
+
+  @doc """
+  Return all functions defined in the given module.
+
+  ## Examples
+
+      defmodule Example do
+        def version, do: 1
+        Module.defined_functions __MODULE__ #=> [{:version,1}]
+      end
+
+  """
+  def defined_functions(module) do
+    assert_not_compiled!(:defined_functions, module)
+    table = function_table_for(module)
+    lc { tuple, _, _ } in ETS.tab2list(table), do: tuple
+  end
+
+  @doc """
+  Returns all functions defined in te given module according
+  to its kind.
+
+  ## Examples
+
+      defmodule Example do
+        def version, do: 1
+        Module.defined_functions __MODULE__, :def  #=> [{:version,1}]
+        Module.defined_functions __MODULE__, :defp #=> []
+      end
+
+  """
+  def defined_functions(module, kind) do
+    assert_not_compiled!(:defined_functions, module)
+    table = function_table_for(module)
+    entry = kind_to_entry(kind)
+    ETS.lookup_element(table, entry, 2)
+  end
+
+  @doc """
+  Adds a compilation callback hook that is invoked
+  exactly before the module is compiled.
+
+  This callback is useful when used with `use` as a mechanism
+  to clean up any internal data in the module before it is compiled.
+
+  ## Examples
+
+  Imagine you are creating a module/library that is meant for
+  external usage called `MyLib`. It could be defined as:
+
+      defmodule MyLib do
+        def __using__(target) do
+          Module.merge_data target, some_data: true
+          Module.add_compile_callback(target, __MODULE__, :__callback__)
+        end
+
+        defmacro __callback__(target) do
+          value = Orddict.get(Module.read_data(target), :some_data, [])
+          quote do: (def my_lib_value, do: unquote(value))
+        end
+      end
+
+  And a module could use `MyLib` with:
+
+      defmodule App do
+        use ModuleTest::ToBeUsed
+      end
+
+  In the example above, `MyLib` defines a data to the target. This data
+  can be updated throughout the module definition and therefore, the final
+  value of the data can only be compiled using a compiation callback,
+  which will read the final value of :some_data and compile to a function.
+  """
+  def add_compile_callback(module, target, fun // :__compiling__) do
+    assert_not_compiled!(:add_compile_callback, module)
+    new   = { target, fun }
+    table = data_table_for(module)
+    old   = ETS.lookup_element(table, :compile_callbacks, 2)
+    ETS.insert(table, { :compile_callbacks,  [new|old] })
+  end
+
+  @doc """
+  Adds an Erlang attribute to the given module with the given
+  key and value. The same attribute can be added more than once.
+
+  ## Examples
+
+      defmodule MyModule do
+        Module.add_attribute __MODULE__, :custom_threshold_for_lib, 10
+      end
+
+  """
+  def add_attribute(module, key, value) when is_atom(key) do
+    assert_not_compiled!(:add_attribute, module)
+    table = data_table_for(module)
+    attrs = ETS.lookup_element(table, :attributes, 2)
+    ETS.insert(table, { :attributes, [{key, value}|attrs] })
+  end
+
+  @doc """
+  Deletes all attributes that matches the given key.
+
+  ## Examples
+
+      defmodule MyModule do
+        Module.add_attribute __MODULE__, :custom_threshold_for_lib, 10
+        Module.delete_attribute __MODULE__, :custom_threshold_for_lib
+      end
+
+  """
+  def delete_attribute(module, key) when is_atom(key) do
+    assert_not_compiled!(:delete_attribute, module)
+    table = data_table_for(module)
+    attrs = ETS.lookup_element(table, :attributes, 2)
+    final = lc {k,v} in attrs, k != key, do: {k,v}
+    ETS.insert(table, { :attributes, final })
+  end
+
+  @doc """
+  Registers an attribute. This allows a developer to use the data API
+  but Elixir will register the data as an attribute automatically.
+  By default, `vsn`, `behavior` and other Erlang attributes are
+  automatically registered.
+
+  ## Examples
+
+      defmodule MyModule do
+        Module.register_attribute __MODULE__, :custom_threshold_for_lib
+        @custom_threshold_for_lib 10
+      end
+
+  """
+  def register_attribute(module, new) do
+    assert_not_compiled!(:register_attribute, module)
+    table = data_table_for(module)
+    old = ETS.lookup_element(table, :registered_attributes, 2)
+    ETS.insert(table, { :registered_attributes,  [new|old] })
+  end
+
+  @doc false
+  # Used internally to compile documentation. This function
+  # is private and must be used only internally.
+  def compile_doc(module, line, kind, pair) do
+    case read_data(module, :doc) do
+    match: nil
+      # We simply discard nil
+    match: doc
+      result = add_doc(module, line, kind, pair, doc)
+      merge_data(module, doc: nil)
+      result
+    end
+  end
+
+  ## Helpers
+
+  defp kind_to_entry(:def),      do: :public
+  defp kind_to_entry(:defp),     do: :private
+  defp kind_to_entry(:defmacro), do: :macros
+
+  defp to_char_list(list) when is_list(list),  do: list
+  defp to_char_list(bin)  when is_binary(bin), do: binary_to_list(bin)
+
+  defp data_table_for(module) do
+    list_to_atom Erlang.lists.concat([:d, module])
+  end
+
+  defp function_table_for(module) do
+    list_to_atom Erlang.lists.concat([:f, module])
+  end
+
+  defp docs_table_for(module) do
+    list_to_atom Erlang.lists.concat([:o, module])
+  end
+
+  defp assert_not_compiled!(fun, module) do
+    compiled?(module) ||
+      raise ArgumentError, message:
+        "could not call #{fun} on module #{module} because it was already compiled"
+  end
+end
+
+defp interpret(input) do
+  cond do
+    is_empty? input -> :silence
+    all_caps? input -> :exclamation
+    question? input -> :question
+    true            -> :statement
+  end
+end
+
+use Bitwise
+~~~1
+1 &&& 2
+%{key: 1}
+%Struct{name: "value"}
+~r/^(.+):(\d+)$/
+doubler = &(&1 * 2)
diff --git a/app/server/vendor/rouge/spec/visual/samples/erb b/app/server/vendor/rouge/spec/visual/samples/erb
new file mode 100755
index 0000000..f0ed27a
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/erb
@@ -0,0 +1,14 @@
+<h3>List</h3>
+<% if !@list || @list.empty? %>
+<p>not found.</p>
+<% else %>
+<table>
+  <tbody>
+    <% @list.each_with_index do |item, i| %>
+    <tr bgcolor="<%= i%2 == 0 ? '#FFCCCC' : '#CCCCFF' %>">
+      <td><%= item %></td>
+    </tr>
+    <% end %>
+  </tbody>
+</table>
+<% end %>
diff --git a/app/server/vendor/rouge/spec/visual/samples/erlang b/app/server/vendor/rouge/spec/visual/samples/erlang
new file mode 100755
index 0000000..ea90945
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/erlang
@@ -0,0 +1,223 @@
+% Percent sign start a one-line comment.
+
+%% Two percent characters shall be used to comment functions.
+
+%%% Three percent characters shall be used to comment modules.
+
+% We use three types of punctuation in Erlang.
+% Commas (`,`) separate arguments in function calls, data constructors, and
+% patterns.
+% Periods (`.`) (followed by whitespace) separate entire functions and
+% expressions in the shell.
+% Semicolons (`;`) separate clauses. We find clauses in several contexts: in kn
+% function definitions and in `case`, `if`, `try..catch` and `receive`
+% expressions.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 1. Variables and pattern matching.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Num = 42.  % All variable names must start with an uppercase letter.
+% Erlang has single assignment variables, if you try to assign a different value
+% to the variable `Num`, you’ll get an error.
+
+% In most languages, `=` denotes an assignment statement. In Erlang, however,
+% `=` denotes a pattern matching operation. `Lhs = Rhs` really means this:
+% evaluate the right side (Rhs), and then match the result against the pattern
+% on the left side (Lhs).
+Num = 7 * 6.
+
+% Floating point number.
+Pi = 3.14159.
+
+% Atoms, are used to represent different non-numerical constant values. Atoms
+% start with lowercase letters, followed by a sequence of alphanumeric
+% characters or the underscore (`_`) or at (`@`) sign.
+Hello = hello.
+
+% Tuples are similar to structs in C.
+Point = {point, 10, 45}.
+
+% If we want to extract some values from a tuple, we use the pattern matching
+% operator `=`.
+{point, X, Y} = Point.  % X = 10, Y = 45
+
+% We can use `_` as a placeholder for variables that we’re not interested in.
+% The symbol `_` is called an anonymous variable. Unlike regular variables,
+% several occurrences of _ in the same pattern don’t have to bind to the same
+% value.
+Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.
+{_, {_, {_, Who}, _}, _} = Person.  % Who = joe
+
+% We create a list by enclosing the list elements in square brackets and
+% separating them with commas.
+% The individual elements of a list can be of any type.
+% The first element of a list the head of the list. If you imagine removing the
+% head from the list, what’s left is called the tail of the list.
+ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}].
+
+% If `T` is a list, then `[H|T]` is also a list, with head H and tail T.
+% The vertical bar (`|`) separates the head of a list from its tail.
+% `[]` is the empty list.
+% We can extract elements from a list with a pattern matching operation. If we
+% have the nonempty list `L`, then the expression `[X|Y] = L`, where `X` and `Y`
+% are unbound variables, will extract the head of the list into `X` and the tail
+% of the list into `Y`.
+[FirstThing|OtherThingsToBuy] = ThingsToBuy.
+% FirstThing = {apples, 10}
+% OtherThingsToBuy = {pears, 6}, {milk, 3}
+
+% There are no strings in Erlang. Strings are really just lists of integers.
+% Strings are enclosed in double quotation marks (`"`).
+Name = "Hello".
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 2. Sequential programming.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Modules are the basic unit of code in Erlang. All the functions we write are
+% stored in modules. Modules are stored in files with `.erl` extensions.
+% Modules must be compiled before the code can be run. A compiled module has the
+% extension `.beam`.
+-module(geometry).
+-export([area/1]).
+
+% The function area consists of two clauses. The clauses are separated by a
+% semicolon, and the final clause is terminated by dot-whitespace.
+% Each clause has a head and a body; the head consists of a function name
+% followed by a pattern (in parentheses), and the body consists of a sequence of
+% expressions, which are evaluated if the pattern in the head is successfully
+% matched against the calling arguments. The patterns are matched in the order
+% they appear in the function definition.
+area({rectangle, Width, Ht}) -> Width * Ht;
+area({circle, R})            -> 3.14159 * R * R.
+
+% Compile the code in the file geometry.erl.
+c(geometry).  % {ok,geometry}
+
+% We need to include the module name together with the function name in order to
+% identify exactly which function we want to call.
+geometry:area({rectangle, 10, 5}).  % 50
+geometry:area({circle, 1.4}).  % 6.15752
+
+% In Erlang, two functions with the same name and different arity in the same
+% module represent entirely different functions.
+-module(lib_misc).
+-export([sum/1]).
+sum(L) -> sum(L, 0).
+sum([], N)    -> N;
+sum([H|T], N) -> sum(T, H+N).
+
+% Funs are "anonymous" functions. They are called this because they have no
+% name.
+Double = fun(X) -> 2*X end.
+Double(2).  % 4
+
+% Functions accept funs as their arguments and can return funs.
+Mult = fun(Times) -> ( fun(X) -> X * Times end ) end.
+Triple = Mult(3).
+Triple(5).  % 15
+
+% List comprehensions are expressions that create lists without having to use
+% funs, maps, or filters.
+% The notation `[F(X) || X <- L]` means "the list of `F(X)` where `X` is taken
+% from the list `L`."
+L = [1,2,3,4,5].
+[2*X || X <- L].  % [2,4,6,8,10]
+
+% Guards are constructs that we can use to increase the power of pattern
+% matching. Using guards, we can perform simple tests and comparisons on the
+% variables in a pattern.
+% You can use guards in the heads of function definitions where they are
+% introduced by the `when` keyword, or you can use them at any place in the
+% language where an expression is allowed.
+max(X, Y) when X > Y -> X;
+max(X, Y) -> Y.
+
+% A guard is a series of guard expressions, separated by commas (`,`).
+% The guard `GuardExpr1, GuardExpr2, ..., GuardExprN` is true if all the guard
+% expressions `GuardExpr1, GuardExpr2, ...` evaluate to true.
+is_cat(A) when is_atom(A), A =:= cat -> true;
+is_cat(A) -> false.
+is_dog(A) when is_atom(A), A =:= dog -> true;
+is_dog(A) -> false.
+
+% A `guard sequence` is either a single guard or a series of guards, separated
+%by semicolons (`;`). The guard sequence `G1; G2; ...; Gn` is true if at least
+% one of the guards `G1, G2, ...` evaluates to true.
+is_pet(A) when is_dog(A); is_cat(A) -> true;
+is_pet(A) -> false.
+
+% Records provide a method for associating a name with a particular element in a
+% tuple.
+% Record definitions can be included in Erlang source code files or put in files
+% with the extension `.hrl`, which are then included by Erlang source code
+% files.
+-record(todo, {
+  status = reminder,  % Default value
+  who = joe,
+  text
+}).
+
+% We have to read the record definitions into the shell before we can define a
+% record. We use the shell function `rr` (short for read records) to do this.
+rr("records.hrl").  % [todo]
+
+% Creating and updating records:
+X = #todo{}.
+% #todo{status = reminder, who = joe, text = undefined}
+X1 = #todo{status = urgent, text = "Fix errata in book"}.
+% #todo{status = urgent, who = joe, text = "Fix errata in book"}
+X2 = X1#todo{status = done}.
+% #todo{status = done,who = joe,text = "Fix errata in book"}
+
+% `case` expressions.
+% `filter` returns a list of all those elements `X` in `L` for which `P(X)` is
+% true.
+filter(P, [H|T]) ->
+  case P(H) of
+    true -> [H|filter(P, T)];
+    false -> filter(P, T)
+  end;
+filter(P, []) -> [].
+
+% `if` expressions.
+max(X, Y) ->
+  if
+    X > Y -> X;
+    X < Y -> Y;
+    true -> nil;
+  end.
+
+% Warning: at least one of the guards in the if expression must evaluate to true;
+% otherwise, an exception will be raised.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 3. Exceptions.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Exceptions are raised by the system when internal errors are encountered or
+% explicitly in code by calling `throw(Exception)`, `exit(Exception)` or
+% `erlang:error(Exception)`.
+generate_exception(1) -> a;
+generate_exception(2) -> throw(a);
+generate_exception(3) -> exit(a);
+generate_exception(4) -> {'EXIT', a};
+generate_exception(5) -> erlang:error(a).
+
+% Erlang has two methods of catching an exception. One is to enclose the call to
+% the function, which raised the exception within a `try...catch` expression.
+catcher(N) ->
+  try generate_exception(N) of
+    Val -> {N, normal, Val}
+  catch
+    throw:X -> {N, caught, thrown, X};
+    exit:X -> {N, caught, exited, X};
+    error:X -> {N, caught, error, X}
+  end.
+
+% The other is to enclose the call in a `catch` expression. When you catch an
+% exception, it is converted into a tuple that describes the error.
+catcher(N) -> catch generate_exception(N).
\ No newline at end of file
diff --git a/app/server/vendor/rouge/spec/visual/samples/factor b/app/server/vendor/rouge/spec/visual/samples/factor
new file mode 100755
index 0000000..f3a3784
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/factor
@@ -0,0 +1,384 @@
+! Copyright (C) 2008 Slava Pestov
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel hashtables calendar random assocs
+namespaces make splitting sequences sorting math.order present
+io.files io.directories io.encodings.ascii
+syndication farkup
+html.components html.forms
+http.server
+http.server.dispatchers
+furnace.actions
+furnace.utilities
+furnace.redirection
+furnace.auth
+furnace.auth.login
+furnace.boilerplate
+furnace.syndication
+validators
+db.types db.tuples lcs urls ;
+IN: webapps.wiki
+
+: wiki-url ( rest path -- url )
+    [ "$wiki/" % % "/" % present % ] "" make
+    <url> swap >>path ;
+
+: view-url ( title -- url ) "view" wiki-url ;
+
+: edit-url ( title -- url ) "edit" wiki-url ;
+
+: revisions-url ( title -- url ) "revisions" wiki-url ;
+
+: revision-url ( id -- url ) "revision" wiki-url ;
+
+: user-edits-url ( author -- url ) "user-edits" wiki-url ;
+
+TUPLE: wiki < dispatcher ;
+
+SYMBOL: can-delete-wiki-articles?
+
+can-delete-wiki-articles? define-capability
+
+TUPLE: article title revision ;
+
+article "ARTICLES" {
+    { "title" "TITLE" { VARCHAR 256 } +not-null+ +user-assigned-id+ }
+    { "revision" "REVISION" INTEGER +not-null+ } ! revision id
+} define-persistent
+
+: <article> ( title -- article ) article new swap >>title ;
+
+TUPLE: revision id title author date content description ;
+
+revision "REVISIONS" {
+    { "id" "ID" INTEGER +db-assigned-id+ }
+    { "title" "TITLE" { VARCHAR 256 } +not-null+ } ! article id
+    { "author" "AUTHOR" { VARCHAR 256 } +not-null+ } ! uid
+    { "date" "DATE" TIMESTAMP +not-null+ }
+    { "content" "CONTENT" TEXT +not-null+ }
+    { "description" "DESCRIPTION" TEXT }
+} define-persistent
+
+M: revision feed-entry-title
+    [ title>> ] [ drop " by " ] [ author>> ] tri 3append ;
+
+M: revision feed-entry-date date>> ;
+
+M: revision feed-entry-url id>> revision-url ;
+
+: reverse-chronological-order ( seq -- sorted )
+    [ date>> ] inv-sort-with ;
+
+: <revision> ( id -- revision )
+    revision new swap >>id ;
+
+: validate-title ( -- )
+    { { "title" [ v-one-line ] } } validate-params ;
+
+: validate-author ( -- )
+    { { "author" [ v-username ] } } validate-params ;
+
+: <article-boilerplate> ( responder -- responder' )
+    <boilerplate>
+        { wiki "page-common" } >>template ;
+
+: <main-article-action> ( -- action )
+    <action>
+        [ "Front Page" view-url <redirect> ] >>display ;
+
+: latest-revision ( title -- revision/f )
+    <article> select-tuple
+    dup [ revision>> <revision> select-tuple ] when ;
+
+: <view-article-action> ( -- action )
+    <action>
+
+        "title" >>rest
+
+        [ validate-title ] >>init
+
+        [
+            "title" value dup latest-revision [
+                from-object
+                { wiki "view" } <chloe-content>
+            ] [
+                edit-url <redirect>
+            ] ?if
+        ] >>display
+
+    <article-boilerplate> ;
+
+: <view-revision-action> ( -- action )
+    <page-action>
+
+        "id" >>rest
+
+        [
+            validate-integer-id
+            "id" value <revision>
+            select-tuple from-object
+        ] >>init
+
+        { wiki "view" } >>template
+    
+    <article-boilerplate> ;
+
+: <random-article-action> ( -- action )
+    <action>
+        [
+            article new select-tuples random
+            [ title>> ] [ "Front Page" ] if*
+            view-url <redirect>
+        ] >>display ;
+
+: amend-article ( revision article -- )
+    swap id>> >>revision update-tuple ;
+
+: add-article ( revision -- )
+    [ title>> ] [ id>> ] bi article boa insert-tuple ;
+
+: add-revision ( revision -- )
+    [ insert-tuple ]
+    [
+        dup title>> <article> select-tuple
+        [ amend-article ] [ add-article ] if*
+    ]
+    bi ;
+
+: <edit-article-action> ( -- action )
+    <page-action>
+
+        "title" >>rest
+
+        [
+            validate-title
+
+            "title" value <article> select-tuple
+            [ revision>> <revision> select-tuple ]
+            [ f <revision> "title" value >>title ]
+            if*
+
+            [ title>> "title" set-value ]
+            [ content>> "content" set-value ]
+            bi
+        ] >>init
+
+        { wiki "edit" } >>template
+
+    <article-boilerplate> ;
+
+: <submit-article-action> ( -- action )
+    <action>
+        [
+            validate-title
+
+            {
+                { "content" [ v-required ] }
+                { "description" [ [ v-one-line ] v-optional ] }
+            } validate-params
+
+            f <revision>
+                "title" value >>title
+                now >>date
+                username >>author
+                "content" value >>content
+                "description" value >>description
+            [ add-revision ] [ title>> view-url <redirect> ] bi
+        ] >>submit
+
+    <protected>
+        "edit wiki articles" >>description ;
+
+: <revisions-boilerplate> ( responder -- responder )
+    <boilerplate>
+        { wiki "revisions-common" } >>template ;
+
+: list-revisions ( -- seq )
+    f <revision> "title" value >>title select-tuples
+    reverse-chronological-order ;
+
+: <list-revisions-action> ( -- action )
+    <page-action>
+
+        "title" >>rest
+
+        [
+            validate-title
+            list-revisions "revisions" set-value
+        ] >>init
+
+        { wiki "revisions" } >>template
+
+    <revisions-boilerplate>
+    <article-boilerplate> ;
+
+: <list-revisions-feed-action> ( -- action )
+    <feed-action>
+
+        "title" >>rest
+
+        [ validate-title ] >>init
+
+        [ "Revisions of " "title" value append ] >>title
+
+        [ "title" value revisions-url ] >>url
+
+        [ list-revisions ] >>entries ;
+
+: rollback-description ( description -- description' )
+    [ "Rollback of '" "'" surround ] [ "Rollback" ] if* ;
+
+: <rollback-action> ( -- action )
+    <action>
+
+        [ validate-integer-id ] >>validate
+
+        [
+            "id" value <revision> select-tuple
+                f >>id
+                now >>date
+                username >>author
+                [ rollback-description ] change-description
+            [ add-revision ]
+            [ title>> revisions-url <redirect> ] bi
+        ] >>submit
+    
+    <protected>
+        "rollback wiki articles" >>description ;
+
+: list-changes ( -- seq )
+    f <revision> select-tuples
+    reverse-chronological-order ;
+
+: <list-changes-action> ( -- action )
+    <page-action>
+        [ list-changes "revisions" set-value ] >>init
+        { wiki "changes" } >>template
+
+    <revisions-boilerplate> ;
+
+: <list-changes-feed-action> ( -- action )
+    <feed-action>
+        [ URL" $wiki/changes" ] >>url
+        [ "All changes" ] >>title
+        [ list-changes ] >>entries ;
+
+: <delete-action> ( -- action )
+    <action>
+
+        [ validate-title ] >>validate
+
+        [
+            "title" value <article> delete-tuples
+            f <revision> "title" value >>title delete-tuples
+            URL" $wiki" <redirect>
+        ] >>submit
+
+     <protected>
+        "delete wiki articles" >>description
+        { can-delete-wiki-articles? } >>capabilities ;
+
+: <diff-action> ( -- action )
+    <page-action>
+
+        [
+            {
+                { "old-id" [ v-integer ] }
+                { "new-id" [ v-integer ] }
+            } validate-params
+
+            "old-id" "new-id"
+            [ value <revision> select-tuple ] bi@
+            [
+                over title>> "title" set-value
+                [ "old" [ from-object ] nest-form ]
+                [ "new" [ from-object ] nest-form ]
+                bi*
+            ]
+            [ [ content>> string-lines ] bi@ diff "diff" set-value ]
+            2bi
+        ] >>init
+
+        { wiki "diff" } >>template
+
+    <article-boilerplate> ;
+
+: <list-articles-action> ( -- action )
+    <page-action>
+
+        [
+            f <article> select-tuples
+            [ title>> ] sort-with
+            "articles" set-value
+        ] >>init
+
+        { wiki "articles" } >>template ;
+
+: list-user-edits ( -- seq )
+    f <revision> "author" value >>author select-tuples
+    reverse-chronological-order ;
+
+: <user-edits-action> ( -- action )
+    <page-action>
+
+        "author" >>rest
+
+        [
+            validate-author
+            list-user-edits "revisions" set-value
+        ] >>init
+
+        { wiki "user-edits" } >>template
+
+    <revisions-boilerplate> ;
+
+: <user-edits-feed-action> ( -- action )
+    <feed-action>
+        "author" >>rest
+        [ validate-author ] >>init
+        [ "Edits by " "author" value append ] >>title
+        [ "author" value user-edits-url ] >>url
+        [ list-user-edits ] >>entries ;
+
+: init-sidebars ( -- )
+    "Contents" latest-revision [ "contents" [ from-object ] nest-form ] when*
+    "Footer" latest-revision [ "footer" [ from-object ] nest-form ] when* ;
+
+: init-relative-link-prefix ( -- )
+    URL" $wiki/view/" adjust-url present relative-link-prefix set ;
+
+: <wiki> ( -- dispatcher )
+    wiki new-dispatcher
+        <main-article-action> "" add-responder
+        <view-article-action> "view" add-responder
+        <view-revision-action> "revision" add-responder
+        <random-article-action> "random" add-responder
+        <list-revisions-action> "revisions" add-responder
+        <list-revisions-feed-action> "revisions.atom" add-responder
+        <diff-action> "diff" add-responder
+        <edit-article-action> "edit" add-responder
+        <submit-article-action> "submit" add-responder
+        <rollback-action> "rollback" add-responder
+        <user-edits-action> "user-edits" add-responder
+        <list-articles-action> "articles" add-responder
+        <list-changes-action> "changes" add-responder
+        <user-edits-feed-action> "user-edits.atom" add-responder
+        <list-changes-feed-action> "changes.atom" add-responder
+        <delete-action> "delete" add-responder
+    <boilerplate>
+        [ init-sidebars init-relative-link-prefix ] >>init
+        { wiki "wiki-common" } >>template ;
+
+: init-wiki ( -- )
+    "resource:extra/webapps/wiki/initial-content" [
+        [
+            dup ".txt" ?tail [
+                swap ascii file-contents
+                f <revision>
+                    swap >>content
+                    swap >>title
+                    "slava" >>author
+                    now >>date
+                add-revision
+            ] [ 2drop ] if
+        ] each
+    ] with-directory-files ;
diff --git a/app/server/vendor/rouge/spec/visual/samples/gherkin b/app/server/vendor/rouge/spec/visual/samples/gherkin
new file mode 100755
index 0000000..e26a0e9
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/gherkin
@@ -0,0 +1,55 @@
+#Comment on line 1
+#Comment on line 2
+ at tag1 @tag2
+Feature: Feature Text
+  In order to test multiline forms
+  As a ragel writer
+  I need to check for complex combinations
+
+  #Comment on line 9
+
+  #Comment on line 11
+
+  Background:
+    Given this is a background step
+    And this is another one
+
+  @tag3 @tag4
+  Scenario: Reading a Scenario
+    Given there is a step
+    But not another step
+
+  @tag3
+  Scenario: Reading a second scenario
+    With two lines of text
+    #Comment on line 24
+    Given a third step with a table
+    |a|b|
+    |c|d|
+    |e|f|
+    And I am still testing things
+      |g|h|
+      |e|r|
+      |k|i|
+      |n|| 
+    And I am done testing these tables
+    #Comment on line 29
+    Then I am happy
+
+  Scenario: Hammerzeit
+    Given All work and no play
+      """
+      Makes Homer something something
+      And something else
+      """
+    Then crazy
+
+#language:zh-CN
+功能:加法
+
+  场景: 两个数相加
+    假如我已经在计算器里输入6
+    而且我已经在计算器里输入7
+    当我按相加按钮
+    那么我应该在屏幕上看到的结果是13
+
diff --git a/app/server/vendor/rouge/spec/visual/samples/go b/app/server/vendor/rouge/spec/visual/samples/go
new file mode 100755
index 0000000..a29fd7b
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/go
@@ -0,0 +1,181 @@
+// A line comment.
+
+/*
+A general comment.
+*/
+
+// Keywords
+
+	break        default      func         interface    select
+	case         defer        go           map          struct
+	chan         else         goto         package      switch
+	const        fallthrough  if           range        type
+	continue     for          import       return       var
+
+// Operators, delimiters and special tokens
+
+	+    &     +=    &=     &&    ==    !=    (    )
+	-    |     -=    |=     ||    <     <=    [    ]
+	*    ^     *=    ^=     <-    >     >=    {    }
+	/    <<    /=    <<=    ++    =     :=    ,    ;
+	%    >>    %=    >>=    --    !     ...   .    :
+	     &^          &^=
+
+// Integer literals
+
+	42
+	0600
+	0xBadFace
+	170141183460469231731687303715884105727
+
+// Floating-point literals
+
+	0.
+	72.40
+	072.40
+	2.71828
+	1.e+0
+	6.67428e-11
+	1E6
+	.25
+	.12345E+5
+
+// Imaginary literals
+
+	0i
+	011i
+	0.i
+	2.71828i
+	1.e+0i
+	6.67428e-11i
+	1E6i
+	.25i
+	.12345E+5i
+
+// Character literals
+
+	'a'
+	'ä'
+	'本'
+	'\t'
+	'\000'
+	'\007'
+	'\377'
+	'\x07'
+	'\xff'
+	'\u12e4'
+	'\U00101234'
+
+// String literals
+
+	`abc`
+	`\n
+	\n`
+	"\n"
+	""
+	"Hello, world!\n"
+	"日本語"
+	"\u65e5本\U00008a9e"
+	"\xff\u00FF"
+	"\uD800"       // illegal: surrogate half
+	"\U00110000"   // illegal: invalid Unicode code point
+	"\z"           // illegal
+
+// Predeclared identifiers
+
+	// Types:
+	bool byte complex64 complex128 error float32 float64
+	int int8 int16 int32 int64 rune string
+	uint uint8 uint16 uint32 uint64 uintptr
+
+	// Constants:
+	true false iota
+
+	// Zero value:
+	nil
+
+	// Functions:
+	append cap close complex copy delete imag len
+	make new panic print println real recover
+
+// Types
+
+	type T1 string
+	type T2 T1
+	type T3 []T1
+	type T4 T3
+
+// Array types
+
+	[32]byte
+	[2*N] struct { x, y int32 }
+	[1000]*float64
+	[3][5]int
+	[2][2][2]float64
+
+// Struct types
+
+	struct {}
+
+	struct {
+		x, y int
+		u float32
+		_ float32
+		A *[]int
+		F func()
+	}
+
+	struct {
+		T1
+		*T2
+		P.T3
+		*P.T4
+		x, y int
+	}
+
+	struct {
+		T
+		*T
+		*P.T
+	}
+
+	struct {
+		microsec  uint64 "field 1"
+		serverIP6 uint64 "field 2"
+		process   string "field 3"
+	}
+
+// Function types
+
+	func()
+	func(x int) int
+	func(a, _ int, z float32) bool
+	func(a, b int, z float32) (bool)
+	func(prefix string, values ...int)
+	func(a, b int, z float64, opt ...interface{}) (success bool)
+	func(int, int, float64) (float64, *[]int)
+	func(n int) func(p *T)
+
+// Interface types
+
+	interface {
+		Read(b Buffer) bool
+		Write(b Buffer) bool
+		Close()
+	}
+
+	type Lock interface {
+		Lock()
+		Unlock()
+	}
+
+// Channel types
+
+	chan T
+	chan<- float64
+	<-chan int
+
+	chan<- chan int
+	chan<- <-chan int
+	<-chan <-chan int
+	chan (<-chan int)
diff --git a/app/server/vendor/rouge/spec/visual/samples/groovy b/app/server/vendor/rouge/spec/visual/samples/groovy
new file mode 100755
index 0000000..9ff76c0
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/groovy
@@ -0,0 +1,97 @@
+// This source code comes from http://www.odelia-technologies.com/node/200
+
+package com.odelia.groovy.simpleworkflow
+
+
+class SimpleWorkflowEngine {
+    def workflowMap = [:]
+    def context = [:]
+    def beforeActivityName = 'beforeActivity'
+    def afterActivityName = 'afterActivity'
+
+    SimpleWorkflowEngine(workflow, context = [:]) {
+        this.context = context
+        parseWorkflow(workflow)
+    }
+
+    def parseWorkflow(workflow) {
+        workflowMap = new WorkflowParser().parse(workflow)
+    }
+
+    def getActivityValue(activity) {
+        assert activity instanceof String
+        if (!workflowMap[activity])
+            throw new RuntimeException("$activity activity doesn't exist")
+        workflowMap[activity]
+    }
+
+    def execute(activity, pause) {
+        if (workflowMap[beforeActivityName]) {
+            getActivityValue(beforeActivityName)(context, activity)
+        }
+
+        def activityValue = getActivityValue(activity)
+
+        // Determine the next activity to execute
+        def nextActivity
+        switch (activityValue) {
+            case String: nextActivity = activityValue; break
+            case Closure: nextActivity = activityValue(context); break
+            case Class: nextActivity = activityValue.newInstance()(context)
+        }
+
+        if (workflowMap[afterActivityName]) {
+            getActivityValue(afterActivityName)(context, activity, nextActivity)
+        }
+
+        if (!pause && nextActivity)
+            call(nextActivity)
+        else
+            nextActivity
+    }
+
+    def call(activity) {
+        execute(activity, false)
+    }
+
+    def nextActivity(activity) {
+        execute(activity, true)
+    }
+
+    static void main(String[] args) {
+        if (args.size() != 2) {
+            println 'Usage: com.odelia.groovy.simpleworkflow.SimpleWorkflowEngine <dsl_filename> <activity_name>'
+            return
+        }
+        SimpleWorkflowEngine.newInstance(new File(args[0]))(args[1])
+    }
+
+}
+
+private class WorkflowParser {
+    def map = [:]
+
+    def methodMissing(String name, args) {
+        map[name] = args[0]
+    }
+
+    def parse(Closure wf) {
+        wf.delegate = this
+        wf.resolveStrategy = Closure.DELEGATE_FIRST
+        wf()
+        map
+    }
+
+    def workflow = { it ->
+        it.delegate = this
+        it.resolveStrategy = Closure.DELEGATE_FIRST
+        it()
+    }
+
+    def parse(File workflowDef) {
+        def binding = new Binding([workflow: workflow])
+        def shell = new GroovyShell(binding)
+        shell.evaluate(workflowDef)
+        map
+    }
+}
diff --git a/app/server/vendor/rouge/spec/visual/samples/haml b/app/server/vendor/rouge/spec/visual/samples/haml
new file mode 100755
index 0000000..d4a773d
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/haml
@@ -0,0 +1,103 @@
+-# standard.haml
+!!!
+%html{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en-US", "lang" => "en-US"}
+  %head
+    %title Hampton Catlin Is Totally Awesome
+    %meta{"http-equiv" => "Content-Type", :content => "text/html; charset=utf-8"}
+  %body
+    / You're In my house now!
+    .header
+      Yes, ladies and gentileman. He is just that egotistical.
+      Fantastic! This should be multi-line output
+      With <b id="awesome">HTML in it!</b>
+      = 1 + 9 + 8 + 2 #numbers should work and this should be ignored
+    #body= " Quotes should be loved! Just like people!"
+    - 120.times do |number|
+      = number
+    Wow.|
+    %p{:code => 1 + 2}
+      = "Holy cow        " + |
+        "multiline       " + |      
+        "tags!           " + |
+        "A pipe (|) even!"   |
+      = [1, 2, 3].collect { |n| "PipesIgnored|" }.join
+      = [1, 2, 3].collect { |n|     |
+          n.to_s                    |
+        }.join("|")                 |
+    - bar = 17
+    %div.silent{:foo => bar}
+      - foo = String.new
+      - foo << "this"
+      - foo << " shouldn't"
+      - foo << " evaluate"
+      = foo + " but now it should!"
+      -# Woah crap a comment!
+
+    -# That was a line that shouldn't close everything.
+    %ul.really.cool
+      - ('a'..'f').each do |a|
+        %li= a
+    #combo.of_divs_with_underscore= @should_eval = "with this text"
+    = "foo".each_line do |line|
+      - nil
+
+-# tag_parsing.haml
+%div.tags
+  %foo 1
+  %FOO 2
+  %fooBAR 3
+  %fooBar 4
+  %foo_bar 5
+  %foo-bar 6
+  %foo:bar 7
+  %foo.bar 8
+  %fooBAr_baz:boom_bar 9
+  %foo13 #{quuz { zot }.map(&:zombo)}
+  %foo2u 11
+%div.classes
+  %p.foo.bar#baz#boom
+  .fooBar a
+  .foo-bar b
+  .foo_bar c
+  .FOOBAR d
+  .foo16 e
+  .123 f
+  .foo2u g
+
+-# filters
+%pre
+  :preserve
+
+                                                     ___
+                                                  ,o88888
+                                               ,o8888888'
+                         ,:o:o:oooo.        ,8O88Pd8888"
+                     ,.::.::o:ooooOoOoO. ,oO8O8Pd888'"
+                   ,.:.::o:ooOoOoOO8O8OOo.8OOPd8O8O"
+                  , ..:.::o:ooOoOOOO8OOOOo.FdO8O8"
+                 , ..:.::o:ooOoOO8O888O8O,COCOO"
+                , . ..:.::o:ooOoOOOO8OOOOCOCO"
+                 . ..:.::o:ooOoOoOO8O8OCCCC"o
+                    . ..:.::o:ooooOoCoCCC"o:o
+                    . ..:.::o:o:,cooooCo"oo:o:
+                 `   . . ..:.:cocoooo"'o:o:::'
+                 .`   . ..::ccccoc"'o:o:o:::'
+                :.:.    ,c:cccc"':.:.:.:.:.'
+              ..:.:"'`::::c:"'..:.:.:.:.:.'  http://www.chris.com/ASCII/
+            ...:.'.:.::::"'    . . . . .'
+           .. . ....:."' `   .  . . ''
+         . . . ...."'
+         .. . ."'     -hrr-
+        .
+
+  :javascript
+    var a = { foo: 1 };
+
+  :css
+    .foo { font-weight: bold; }
+
+  :ruby
+    puts "Hello, World!"
+
+  :erb
+    <p><%= @foo %></p>
diff --git a/app/server/vendor/rouge/spec/visual/samples/handlebars b/app/server/vendor/rouge/spec/visual/samples/handlebars
new file mode 100755
index 0000000..f1c7447
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/handlebars
@@ -0,0 +1,72 @@
+{{foo}}
+
+{{! "bar" should be regular HTML }}
+{{foo}} \{{bar}} {{baz}}
+
+{{foo}} \{{bar}} \{{baz}}
+
+{{foo}} \{{{bar}}} {{baz}}
+
+{{foo/bar}}
+
+{{foo.bar}}
+{{foo.bar.baz}}
+{{foo.[bar]}}
+{{foo.[bar]}}{{foo.[baz]}}
+{{.}}
+{{../foo/bar}}
+{{../foo.bar}}
+{{this/foo}}
+{{  foo  }}
+{{  foo  
+bar }}
+foo {{ bar }} baz
+{{> foo}}
+{{> foo bar }}
+{{>foo}}
+{{>foo  }}
+foo {{! this is a comment }} bar {{ baz }}
+foo {{!-- this is a {{comment}} --}} bar {{ baz }}
+
+foo {{!-- this is a
+{{comment}}
+--}} bar {{ baz }}
+
+{{#foo}}content{{/foo}}
+
+{{^}}
+{{else}}
+{{ else }}
+
+{{^foo}}
+{{^ foo  }}
+{{ foo bar baz }}
+{{ foo bar "baz" }}
+{{ foo bar 'baz' }}
+{{ foo bar "baz bat" }}
+{{ foo "bar\"baz" }}
+
+{{ foo 'bar\'baz' }}
+
+{{ foo 1 }}
+{{ foo true }}
+{{ foo false }}
+
+{{ foo bar=baz }}
+{{ foo bar baz=bat }}
+{{ foo bar baz=1 }}
+{{ foo bar baz=true }}
+{{ foo bar baz=false }}
+{{ foo bar
+   baz=bat }}
+
+{{ foo bar baz="bat" }}
+{{ foo bar baz="bat" bam=wot }}
+{{foo omg bar=baz bat="bam"}}
+
+{{ @foo }}
+{{ foo @bar }}
+{{ foo bar=@baz }}
+
+{{#foo bar}}
+{{/foo}}
diff --git a/app/server/vendor/rouge/spec/visual/samples/haskell b/app/server/vendor/rouge/spec/visual/samples/haskell
new file mode 100755
index 0000000..ec6f366
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/haskell
@@ -0,0 +1,379 @@
+---------------------------------------------------------------------
+-- SmallCheck: another lightweight testing library.
+-- Colin Runciman, August 2006
+-- Version 0.2 (November 2006)
+--
+-- After QuickCheck, by Koen Claessen and John Hughes (2000-2004).
+---------------------------------------------------------------------
+
+module SmallCheck (
+  smallCheck, depthCheck,
+  Property, Testable,
+  forAll, forAllElem,
+  exists, existsDeeperBy, thereExists, thereExistsElem,
+  (==>),
+  Series, Serial(..),
+  (\/), (><), two, three, four,
+  cons0, cons1, cons2, cons3, cons4,
+  alts0, alts1, alts2, alts3, alts4,
+  N(..), Nat, Natural,
+  depth, inc, dec
+  ) where
+
+import Data.List (intersperse)
+import Control.Monad (when)
+import System.IO (stdout, hFlush)
+
+------------------ <Series of depth-bounded values> -----------------
+
+-- Series arguments should be interpreted as a depth bound (>=0)
+-- Series results should have finite length
+
+type Series a = Int -> [a]
+
+-- sum
+infixr 7 \/
+(\/) :: Series a -> Series a -> Series a
+s1 \/ s2 = \d -> s1 d ++ s2 d
+
+-- product
+infixr 8 ><
+(><) :: Series a -> Series b -> Series (a,b)
+s1 >< s2 = \d -> [(x,y) | x <- s1 d, y <- s2 d]
+
+------------------- <methods for type enumeration> ------------------
+
+-- enumerated data values should be finite and fully defined
+-- enumerated functional values should be total and strict
+
+-- bounds:
+-- for data values, the depth of nested constructor applications
+-- for functional values, both the depth of nested case analysis
+-- and the depth of results
+ 
+class Serial a where
+  series   :: Series a
+  coseries :: Serial b => Series (a->b)
+
+instance Serial () where
+  series   _ = [()]
+  coseries d = [ \() -> b
+               | b <- series d ]
+
+instance Serial Int where
+  series   d = [(-d)..d]
+  coseries d = [ \i -> if i > 0 then f (N (i - 1))
+                       else if i < 0 then g (N (abs i - 1))
+                       else z
+               | z <- alts0 d, f <- alts1 d, g <- alts1 d ]
+
+instance Serial Integer where
+  series   d = [ toInteger (i :: Int)
+               | i <- series d ]
+  coseries d = [ f . (fromInteger :: Integer->Int)
+               | f <- series d ]
+
+newtype N a = N a
+
+instance Show a => Show (N a) where
+  show (N i) = show i
+
+instance (Integral a, Serial a) => Serial (N a) where
+  series   d = map N [0..d']
+               where
+               d' = fromInteger (toInteger d)
+  coseries d = [ \(N i) -> if i > 0 then f (N (i - 1))
+                           else z
+               | z <- alts0 d, f <- alts1 d ]
+
+type Nat = N Int
+type Natural = N Integer
+
+instance Serial Float where
+  series d   = [ encodeFloat sig exp
+               | (sig,exp) <- series d,
+                 odd sig || sig==0 && exp==0 ]
+  coseries d = [ f . decodeFloat
+               | f <- series d ]
+             
+instance Serial Double where
+  series   d = [ frac (x :: Float)
+               | x <- series d ]
+  coseries d = [ f . (frac :: Double->Float)
+               | f <- series d ]
+
+frac :: (Real a, Fractional a, Real b, Fractional b) => a -> b
+frac = fromRational . toRational
+
+instance Serial Char where
+  series d   = take (d+1) ['a'..'z']
+  coseries d = [ \c -> f (N (fromEnum c - fromEnum 'a'))
+               | f <- series d ]
+
+instance (Serial a, Serial b) =>
+         Serial (a,b) where
+  series   = series >< series
+  coseries = map uncurry . coseries
+
+instance (Serial a, Serial b, Serial c) =>
+         Serial (a,b,c) where
+  series   = \d -> [(a,b,c) | (a,(b,c)) <- series d]
+  coseries = map uncurry3 . coseries
+
+instance (Serial a, Serial b, Serial c, Serial d) =>
+         Serial (a,b,c,d) where
+  series   = \d -> [(a,b,c,d) | (a,(b,(c,d))) <- series d]
+  coseries = map uncurry4 . coseries
+
+uncurry3 :: (a->b->c->d) -> ((a,b,c)->d)
+uncurry3 f (x,y,z) = f x y z
+
+uncurry4 :: (a->b->c->d->e) -> ((a,b,c,d)->e)
+uncurry4 f (w,x,y,z) = f w x y z
+
+two   :: Series a -> Series (a,a)
+two   s = s >< s
+
+three :: Series a -> Series (a,a,a)
+three s = \d -> [(x,y,z) | (x,(y,z)) <- (s >< s >< s) d]
+
+four  :: Series a -> Series (a,a,a,a)
+four  s = \d -> [(w,x,y,z) | (w,(x,(y,z))) <- (s >< s >< s >< s) d]
+
+cons0 :: 
+         a -> Series a
+cons0 c _ = [c]
+
+cons1 :: Serial a =>
+         (a->b) -> Series b
+cons1 c d = [c z | d > 0, z <- series (d-1)]
+
+cons2 :: (Serial a, Serial b) =>
+         (a->b->c) -> Series c
+cons2 c d = [c y z | d > 0, (y,z) <- series (d-1)]
+
+cons3 :: (Serial a, Serial b, Serial c) =>
+         (a->b->c->d) -> Series d
+cons3 c d = [c x y z | d > 0, (x,y,z) <- series (d-1)]
+
+cons4 :: (Serial a, Serial b, Serial c, Serial d) =>
+         (a->b->c->d->e) -> Series e
+cons4 c d = [c w x y z | d > 0, (w,x,y,z) <- series (d-1)]
+
+alts0 ::  Serial a =>
+            Series a
+alts0 d = series d
+
+alts1 ::  (Serial a, Serial b) =>
+            Series (a->b)
+alts1 d = if d > 0 then series (dec d)
+          else [\_ -> x | x <- series d]
+
+alts2 ::  (Serial a, Serial b, Serial c) =>
+            Series (a->b->c)
+alts2 d = if d > 0 then series (dec d)
+          else [\_ _ -> x | x <- series d]
+
+alts3 ::  (Serial a, Serial b, Serial c, Serial d) =>
+            Series (a->b->c->d)
+alts3 d = if d > 0 then series (dec d)
+          else [\_ _ _ -> x | x <- series d]
+
+alts4 ::  (Serial a, Serial b, Serial c, Serial d, Serial e) =>
+            Series (a->b->c->d->e)
+alts4 d = if d > 0 then series (dec d)
+          else [\_ _ _ _ -> x | x <- series d]
+
+instance Serial Bool where
+  series     = cons0 True \/ cons0 False
+  coseries d = [ \x -> if x then b1 else b2
+               | (b1,b2) <- series d ]
+
+instance Serial a => Serial (Maybe a) where
+  series     = cons0 Nothing \/ cons1 Just
+  coseries d = [ \m -> case m of
+                       Nothing -> z
+                       Just x  -> f x
+               |  z <- alts0 d ,
+                  f <- alts1 d ]
+
+instance (Serial a, Serial b) => Serial (Either a b) where
+  series     = cons1 Left \/ cons1 Right
+  coseries d = [ \e -> case e of
+                       Left x  -> f x
+                       Right y -> g y
+               |  f <- alts1 d ,
+                  g <- alts1 d ]
+
+instance Serial a => Serial [a] where
+  series     = cons0 [] \/ cons2 (:)
+  coseries d = [ \xs -> case xs of
+                        []      -> y
+                        (x:xs') -> f x xs'
+               |   y <- alts0 d ,
+                   f <- alts2 d ]
+
+-- Warning: the coseries instance here may generate duplicates.
+instance (Serial a, Serial b) => Serial (a->b) where
+  series = coseries
+  coseries d = [ \f -> g [f x | x <- series d]
+               | g <- series d ]              
+
+-- For customising the depth measure.  Use with care!
+
+depth :: Int -> Int -> Int
+depth d d' | d >= 0    = d'+1-d
+           | otherwise = error "SmallCheck.depth: argument < 0"
+
+dec :: Int -> Int
+dec d | d > 0     = d-1
+      | otherwise = error "SmallCheck.dec: argument <= 0"
+
+inc :: Int -> Int
+inc d = d+1
+
+-- show the extension of a function (in part, bounded both by
+-- the number and depth of arguments)
+instance (Serial a, Show a, Show b) => Show (a->b) where
+  show f = 
+    if maxarheight == 1
+    && sumarwidth + length ars * length "->;" < widthLimit then
+      "{"++(
+      concat $ intersperse ";" $ [a++"->"++r | (a,r) <- ars]
+      )++"}"
+    else
+      concat $ [a++"->\n"++indent r | (a,r) <- ars]
+    where
+    ars = take lengthLimit [ (show x, show (f x))
+                           | x <- series depthLimit ]
+    maxarheight = maximum  [ max (height a) (height r)
+                           | (a,r) <- ars ]
+    sumarwidth = sum       [ length a + length r 
+                           | (a,r) <- ars]
+    indent = unlines . map ("  "++) . lines
+    height = length . lines
+    (widthLimit,lengthLimit,depthLimit) = (80,20,3)::(Int,Int,Int)
+
+---------------- <properties and their evaluation> ------------------
+
+-- adapted from QuickCheck originals: here results come in lists,
+-- properties have depth arguments, stamps (for classifying random
+-- tests) are omitted, existentials are introduced
+
+newtype PR = Prop [Result]
+
+data Result = Result {ok :: Maybe Bool, arguments :: [String]}
+
+nothing :: Result
+nothing = Result {ok = Nothing, arguments = []}
+
+result :: Result -> PR
+result res = Prop [res]
+
+newtype Property = Property (Int -> PR)
+
+class Testable a where
+  property :: a -> Int -> PR
+
+instance Testable Bool where
+  property b _ = Prop [Result (Just b) []]
+
+instance Testable PR where
+  property prop _ = prop
+
+instance (Serial a, Show a, Testable b) => Testable (a->b) where
+  property f = f' where Property f' = forAll series f
+
+instance Testable Property where
+  property (Property f) d = f d
+
+evaluate :: Testable a => a -> Series Result
+evaluate x d = rs where Prop rs = property x d
+
+forAll :: (Show a, Testable b) => Series a -> (a->b) -> Property
+forAll xs f = Property $ \d -> Prop $
+  [ r{arguments = show x : arguments r}
+  | x <- xs d, r <- evaluate (f x) d ]
+
+forAllElem :: (Show a, Testable b) => [a] -> (a->b) -> Property
+forAllElem xs = forAll (const xs)
+
+thereExists :: Testable b => Series a -> (a->b) -> Property
+thereExists xs f = Property $ \d -> Prop $
+  [ Result
+      ( Just $ or [ all pass (evaluate (f x) d)
+                  | x <- xs d ] )
+      [] ] 
+  where
+  pass (Result Nothing _)  = True
+  pass (Result (Just b) _) = b
+
+thereExistsElem :: Testable b => [a] -> (a->b) -> Property
+thereExistsElem xs = thereExists (const xs)
+
+exists :: (Serial a, Testable b) =>
+            (a->b) -> Property
+exists = thereExists series
+
+existsDeeperBy :: (Serial a, Testable b) =>
+                    (Int->Int) -> (a->b) -> Property
+existsDeeperBy f = thereExists (series . f)
+ 
+infixr 0 ==>
+
+(==>) :: Testable a => Bool -> a -> Property
+True ==>  x = Property (property x)
+False ==> x = Property (const (result nothing))
+
+--------------------- <top-level test drivers> ----------------------
+
+-- similar in spirit to QuickCheck but with iterative deepening
+
+-- test for values of depths 0..d stopping when a property
+-- fails or when it has been checked for all these values
+smallCheck :: Testable a => Int -> a -> IO String
+smallCheck d = iterCheck 0 (Just d)
+
+depthCheck :: Testable a => Int -> a -> IO String
+depthCheck d = iterCheck d (Just d)
+
+iterCheck :: Testable a => Int -> Maybe Int -> a -> IO String
+iterCheck dFrom mdTo t = iter dFrom
+  where
+  iter :: Int -> IO String
+  iter d = do
+    let Prop results = property t d
+    (ok,s) <- check (mdTo==Nothing) 0 0 True results
+    maybe (iter (d+1))
+          (\dTo -> if ok && d < dTo
+                        then iter (d+1)
+                        else return s)
+          mdTo
+
+check :: Bool -> Int -> Int -> Bool -> [Result] -> IO (Bool, String)
+check i n x ok rs | null rs = do
+  let s = "  Completed "++show n++" test(s)"
+      y = if i then "." else " without failure."
+      z | x > 0     = "  But "++show x++" did not meet ==> condition."
+        | otherwise = ""
+  return (ok, s ++ y ++ z)
+
+check i n x ok (Result Nothing _ : rs) = do
+  progressReport i n x
+  check i (n+1) (x+1) ok rs
+
+check i n x f (Result (Just True) _ : rs) = do
+  progressReport i n x
+  check i (n+1) x f rs
+
+check i n x f (Result (Just False) args : rs) = do
+  let s = "  Failed test no. "++show (n+1)++". Test values follow."
+      s' = s ++ ": " ++ concat (intersperse ", " args)
+  if i then
+      check i (n+1) x False rs
+    else
+      return (False, s')
+
+progressReport :: Bool -> Int -> Int -> IO ()
+progressReport _ _ _ = return ()
+
diff --git a/app/server/vendor/rouge/spec/visual/samples/html b/app/server/vendor/rouge/spec/visual/samples/html
new file mode 100755
index 0000000..d34fd1d
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/html
@@ -0,0 +1,340 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+    function initCodeBlock(id); {
+        var el = document.getElementById(id);
+    }
+</script>
+<style>
+.syntax { border: 1px solid #d0d0d0; background-color: #f0f0f0;
+          margin-left: 10px; margin-right: 10px; }
+
+.syntaxheader { margin-top: 15px; margin-bottom: 0px;
+                text-align: right; font-size: 11px;
+                border-bottom: 0; padding: 3px; }
+
+.linenos { float: left; display: block; }
+.linenos pre { padding-right: 7px; padding-left: 7px;
+               color: #666; }
+
+pre.syntax { padding: 5px; margin-top: 0px; }
+
+.syntax .cm { color: #60a0b0; font-style: italic; }              /* comments */
+.syntax .cm-proc { color: #007020; font-style: normal; }          /* preproc */
+.syntax .kw { color: #007020; font-weight: bold; }               /* keywords */
+.syntax .kw-pseudo { font-weight: normal; }               /* pseudo keywords */
+.syntax .op { color: #666666; }                                 /* operators */
+.syntax .op-word { color: #007020; font-weight: bold; }    /* word operators */
+.syntax .bn { color: #007020; }                                  /* builtins */
+.syntax .fun { color: #06287e; }                                /* func name */
+.syntax .cls { color: #0e84b5; font-weight: bold; }           /* class names */
+.syntax .exc { color: #007020; }                               /* exceptions */
+.syntax .var { color: #bb60d5; }                                /* variables */
+.syntax .const { color: #60add5; }                              /* constants */
+.syntax .entity { color: #d55537; font-weight: bold; }           /* entities */
+.syntax .attr { color: #4070a0; }                              /* attributes */
+.syntax .tag { color: #062873; font-weight: bold; }             /* tag names */
+.syntax .deco { color: #555555; font-weight: bold; }           /* decorators */
+.syntax .st { color: #4070a0; }                                   /* strings */
+.syntax .st-int { color: #70a0d0; font-style: italic; }  /* interpolated str */
+.syntax .st-esc { color: #4070a0; font-weight: bold; }        /* escaped str */
+.syntax .st-re { color: #235388; }                           /* regular expr */
+.syntax .st-sym { color: #517918; }                               /* symbols */
+.syntax .st-oth { color: #c65d09; }                         /* other strings */
+.syntax .nb { color: #40a070; }                                   /* numbers */
+
+.syntax .gen-hd { font-weight: bold; color: blue; }              /* headings */
+.syntax .gen-sh { font-weight: bold; color: purple; }         /* subheadings */
+.syntax .gen-del { color: red; }                             /* deleted text */
+.syntax .gen-ins { color: green; }                          /* inserted text */
+.syntax .gen-em { font-style: italic; }                   /* emphasized text */
+.syntax .gen-sr { font-weight: bold; }                  /* strong emph. text */
+
+.syntax .err { border: 1px solid red; }                     /* parser errors */
+</style>
+</head>
+<body>
+<pre id="code-block" class="syntax"><span class="cm"># -*- coding: utf-8 -*-</span>
+<span class="st st-db">"""</span><span class="st">
+    pocoo.pkg.core.acl
+    ~~~~~~~~~~~~~~~~~~
+
+    Pocoo ACL System.
+
+</span><span class="st st-db">"""</span>
+
+<span class="kw">from </span><span class="cls">pocoo.db</span><span class="kw"> import</span> <span class="name">meta</span>
+
+<span class="kw">from </span><span class="cls">pocoo.pkg.core.forum</span><span class="kw"> import</span> <span class="name">Site</span>, <span class="name">Forum</span>, <span class="name">Thread</span>
+<span class="kw">from </span><span class="cls">pocoo.pkg.core.user</span><span class="kw"> import</span> <span class="name">User</span>, <span class="name">Group</span>
+
+<span class="kw">from </span><span class="cls">pocoo.pkg.core.db</span><span class="kw"> import</span> <span class="name">users</span>, <span class="name">groups</span>, <span class="name">group_members</span>, <span class="name">privileges</span>, \
+     <span class="name">forums</span>, <span class="name">posts</span>, <span class="name">acl_mapping</span>, <span class="name">acl_subjects</span>, <span class="name">acl_objects</span>
+
+
+<span class="kw">class </span><span class="cls">AclManager</span>(<span class="bn">object</span>):
+    <span class="st st-db">"""</span><span class="st">
+    Manager object to manage ALCs.
+    </span><span class="st st-db">"""</span>
+    <span class="name">STRONG_NO</span> <span class="op">=</span> <span class="op">-</span><span class="nb nb-int">1</span>
+
+    <span class="name">WEAK_NO</span> <span class="op">=</span> <span class="nb nb-int">0</span>
+    <span class="name">WEAK_YES</span> <span class="op">=</span> <span class="nb nb-int">1</span>
+    <span class="name">STRONG_YES</span> <span class="op">=</span> <span class="nb nb-int">2</span>
+
+    <span class="kw">def </span><span class="fun">__init__</span>(<span class="bn bn-pseudo">self</span>, <span class="name">ctx</span>, <span class="name">subject</span>):
+        <span class="bn bn-pseudo">self</span>.<span class="name">ctx</span> <span class="op">=</span> <span class="name">ctx</span>
+
+        <span class="bn bn-pseudo">self</span>.<span class="name">subject</span> <span class="op">=</span> <span class="name">subject</span>
+        <span class="kw">if</span> <span class="bn">isinstance</span>(<span class="name">subject</span>, <span class="name">User</span>):
+            <span class="bn bn-pseudo">self</span>.<span class="name">_type</span> <span class="op">=</span> <span class="st st-sg">'</span><span class="st">user</span><span class="st st-sg">'</span>
+
+        <span class="kw">elif</span> <span class="bn">isinstance</span>(<span class="name">subject</span>, <span class="name">Group</span>):
+            <span class="bn bn-pseudo">self</span>.<span class="name">_type</span> <span class="op">=</span> <span class="st st-sg">'</span><span class="st">group</span><span class="st st-sg">'</span>
+
+        <span class="kw">else</span>:
+            <span class="kw">raise</span> <span class="exc">ValueError</span>(<span class="st st-sg">'</span><span class="st">neither user or group specified</span><span class="st st-sg">'</span>)
+
+    <span class="kw">def </span><span class="fun">allow</span>(<span class="bn bn-pseudo">self</span>, <span class="name">privilege</span>, <span class="name">obj</span>, <span class="name">force</span><span class="op">=</span><span class="bn bn-pseudo">False</span>):
+        <span class="st st-db">"""</span><span class="st">Allows the subject privilege on obj.</span><span class="st st-db">"""</span>
+
+        <span class="kw">return</span> <span class="bn bn-pseudo">self</span>.<span class="name">_set</span>(<span class="name">privilege</span>, <span class="name">obj</span>, <span class="nb nb-int">1</span> <span class="op">+</span> <span class="bn">bool</span>(<span class="name">force</span>))
+
+    <span class="kw">def </span><span class="fun">default</span>(<span class="bn bn-pseudo">self</span>, <span class="name">privilege</span>, <span class="name">obj</span>):
+        <span class="st st-db">"""</span><span class="st">Sets the state for privilege on obj back to weak yes.</span><span class="st st-db">"""</span>
+
+        <span class="kw">return</span> <span class="bn bn-pseudo">self</span>.<span class="name">_set</span>(<span class="name">privilege</span>, <span class="name">obj</span>, <span class="nb nb-int">0</span>)
+
+    <span class="kw">def </span><span class="fun">deny</span>(<span class="bn bn-pseudo">self</span>, <span class="name">privilege</span>, <span class="name">obj</span>, <span class="name">force</span><span class="op">=</span><span class="bn bn-pseudo">False</span>):
+        <span class="st st-db">"""</span><span class="st">Denies the subject privilege on obj.</span><span class="st st-db">"""</span>
+
+        <span class="kw">return</span> <span class="bn bn-pseudo">self</span>.<span class="name">_set</span>(<span class="name">privilege</span>, <span class="name">obj</span>, <span class="op">-</span><span class="nb nb-int">1</span> <span class="op">-</span> <span class="bn">bool</span>(<span class="name">force</span>))
+
+    <span class="kw">def </span><span class="fun">can_access</span>(<span class="bn bn-pseudo">self</span>, <span class="name">privilege</span>, <span class="name">obj</span>):
+        <span class="st st-db">"""</span><span class="st">Checks if the current subject with the required privilege
+        somehow. Either directly or when the subject is a user and
+        one of its groups can access it.</span><span class="st st-db">"""</span>
+
+        <span class="cm">#XXX: maybe this could be one big query instead of 4</span>
+        <span class="cm">#XXX: this currently does not work correctly, therefore return True</span>
+        <span class="kw">return</span> <span class="bn bn-pseudo">True</span>
+
+        <span class="kw">if</span> <span class="op op-word">not</span> <span class="bn">isinstance</span>(<span class="name">obj</span>, (<span class="name">Forum</span>, <span class="name">Thread</span>, <span class="name">Site</span>.<span class="name">__class__</span>)):
+            <span class="kw">raise</span> <span class="exc">TypeError</span>(<span class="st st-sg">'</span><span class="st">obj must be a forum, thread or site</span><span class="st st-sg">'</span>)
+        <span class="name">privilege</span> <span class="op">=</span> <span class="name">privilege</span>.<span class="name">upper</span>()
+        <span class="name">s</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">_get_subject_join</span>().<span class="name">alias</span>(<span class="st st-sg">'</span><span class="st">s</span><span class="st st-sg">'</span>).<span class="name">c</span>
+
+        <span class="kw">def </span><span class="fun">do_check</span>(<span class="name">obj</span>, <span class="name">tendency</span>):
+            <span class="name">db</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">ctx</span>.<span class="name">engine</span>
+
+            <span class="name">o</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">_get_object_join</span>(<span class="name">obj</span>).<span class="name">alias</span>(<span class="st st-sg">'</span><span class="st">o</span><span class="st st-sg">'</span>).<span class="name">c</span>
+
+            <span class="cm"># self check</span>
+            <span class="name">r</span> <span class="op">=</span> <span class="name">db</span>.<span class="name">execute</span>(<span class="name">meta</span>.<span class="name">select</span>([<span class="name">acl_mapping</span>.<span class="name">c</span>.<span class="name">state</span>],
+                (<span class="name">acl_mapping</span>.<span class="name">c</span>.<span class="name">priv_id</span> <span class="op">==</span> <span class="name">privileges</span>.<span class="name">c</span>.<span class="name">priv_id</span>) <span class="op">&</span>
+
+                (<span class="name">acl_mapping</span>.<span class="name">c</span>.<span class="name">subject_id</span> <span class="op">==</span> <span class="name">s</span>.<span class="name">subject_id</span>) <span class="op">&</span>
+                (<span class="name">acl_mapping</span>.<span class="name">c</span>.<span class="name">object_id</span> <span class="op">==</span> <span class="name">o</span>.<span class="name">object_id</span>) <span class="op">&</span>
+
+                (<span class="name">privileges</span>.<span class="name">c</span>.<span class="name">name</span> <span class="op">==</span> <span class="name">privilege</span>)
+            ))
+            <span class="name">row</span> <span class="op">=</span> <span class="name">r</span>.<span class="name">fetchone</span>()
+            <span class="kw">if</span> <span class="name">row</span> <span class="op op-word">is</span> <span class="op op-word">not</span> <span class="bn bn-pseudo">None</span>:
+                <span class="kw">if</span> <span class="name">row</span>[<span class="st st-sg">'</span><span class="st">state</span><span class="st st-sg">'</span>] <span class="op op-word">in</span> (<span class="bn bn-pseudo">self</span>.<span class="name">STRONG_NO</span>, <span class="bn bn-pseudo">self</span>.<span class="name">STRONG_YES</span>):
+                    <span class="kw">return</span> <span class="name">row</span>[<span class="st st-sg">'</span><span class="st">state</span><span class="st st-sg">'</span>] <span class="op">==</span> <span class="bn bn-pseudo">self</span>.<span class="name">STRONG_YES</span>
+
+                <span class="name">tendency</span> <span class="op">=</span> <span class="name">row</span>[<span class="st st-sg">'</span><span class="st">state</span><span class="st st-sg">'</span>]
+
+            <span class="cm"># if the controlled subject is a user check all groups</span>
+            <span class="kw">if</span> <span class="bn">isinstance</span>(<span class="bn bn-pseudo">self</span>.<span class="name">subject</span>, <span class="name">User</span>):
+                <span class="name">r</span> <span class="op">=</span> <span class="name">db</span>.<span class="name">execute</span>(<span class="name">meta</span>.<span class="name">select</span>([<span class="name">acl_mapping</span>.<span class="name">c</span>.<span class="name">state</span>],
+                    (<span class="name">acl_mapping</span>.<span class="name">c</span>.<span class="name">object_id</span> <span class="op">==</span> <span class="name">o</span>.<span class="name">object_id</span>) <span class="op">&</span>
+
+                    (<span class="name">acl_mapping</span>.<span class="name">c</span>.<span class="name">subject_id</span> <span class="op">==</span> <span class="name">groups</span>.<span class="name">c</span>.<span class="name">subject_id</span>) <span class="op">&</span>
+
+                    (<span class="name">groups</span>.<span class="name">c</span>.<span class="name">group_id</span> <span class="op">==</span> <span class="name">group_members</span>.<span class="name">c</span>.<span class="name">group_id</span>) <span class="op">&</span>
+
+                    (<span class="name">group_members</span>.<span class="name">c</span>.<span class="name">user_id</span> <span class="op">==</span> <span class="bn bn-pseudo">self</span>.<span class="name">subject</span>.<span class="name">user_id</span>)
+                ))
+                <span class="kw">while</span> <span class="bn bn-pseudo">True</span>:
+                    <span class="name">row</span> <span class="op">=</span> <span class="name">r</span>.<span class="name">fetchone</span>()
+                    <span class="kw">if</span> <span class="name">row</span> <span class="op op-word">is</span> <span class="bn bn-pseudo">None</span>:
+                        <span class="kw">break</span>
+
+                    <span class="name">state</span> <span class="op">=</span> <span class="name">row</span>[<span class="nb nb-int">0</span>]
+                    <span class="kw">if</span> <span class="name">state</span> <span class="op op-word">in</span> (<span class="bn bn-pseudo">self</span>.<span class="name">STRONG_YES</span>, <span class="bn bn-pseudo">self</span>.<span class="name">STRONG_NO</span>):
+                        <span class="kw">return</span> <span class="name">state</span> <span class="op">==</span> <span class="bn bn-pseudo">self</span>.<span class="name">STRONG_YES</span>
+
+                    <span class="kw">if</span> <span class="name">tendency</span> <span class="op op-word">is</span> <span class="bn bn-pseudo">None</span>:
+                        <span class="name">tendency</span> <span class="op">=</span> <span class="name">state</span>
+                    <span class="kw">elif</span> <span class="name">tendency</span> <span class="op">==</span> <span class="bn bn-pseudo">self</span>.<span class="name">WEAK_NO</span> <span class="op op-word">and</span> <span class="name">state</span> <span class="op">==</span> <span class="bn bn-pseudo">self</span>.<span class="name">WEAK_YES</span>:
+                        <span class="name">tendency</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">WEAK_YES</span>
+
+            <span class="cm"># check related objects</span>
+            <span class="kw">if</span> <span class="bn">isinstance</span>(<span class="name">obj</span>, <span class="name">Thread</span>):
+                <span class="kw">return</span> <span class="name">do_check</span>(<span class="name">obj</span>.<span class="name">forum</span>, <span class="name">tendency</span>)
+            <span class="kw">elif</span> <span class="bn">isinstance</span>(<span class="name">obj</span>, <span class="name">Forum</span>):
+                <span class="kw">return</span> <span class="name">do_check</span>(<span class="name">Site</span>, <span class="name">tendency</span>)
+            <span class="kw">else</span>:
+                <span class="kw">return</span> <span class="name">tendency</span>
+
+        <span class="kw">return</span> <span class="name">do_check</span>(<span class="name">obj</span>, <span class="bn bn-pseudo">None</span>) <span class="op op-word">in</span> (<span class="bn bn-pseudo">self</span>.<span class="name">WEAK_YES</span>, <span class="bn bn-pseudo">self</span>.<span class="name">STRONG_YES</span>)
+
+    <span class="kw">def </span><span class="fun">_set</span>(<span class="bn bn-pseudo">self</span>, <span class="name">privilege</span>, <span class="name">obj</span>, <span class="name">state</span>):
+        <span class="st st-db">"""</span><span class="st">Helper functions for settings privileges.</span><span class="st st-db">"""</span>
+
+        <span class="name">privilege</span> <span class="op">=</span> <span class="name">privilege</span>.<span class="name">upper</span>()
+        <span class="kw">if</span> <span class="bn bn-pseudo">self</span>.<span class="name">subject</span>.<span class="name">subject_id</span> <span class="op op-word">is</span> <span class="bn bn-pseudo">None</span>:
+            <span class="bn bn-pseudo">self</span>.<span class="name">_bootstrap</span>()
+        <span class="kw">if</span> <span class="name">obj</span>.<span class="name">object_id</span> <span class="op op-word">is</span> <span class="bn bn-pseudo">None</span>:
+            <span class="bn bn-pseudo">self</span>.<span class="name">_bootstrap_object</span>(<span class="name">obj</span>)
+        <span class="cm"># special state "0" which means delete</span>
+
+        <span class="kw">if</span> <span class="op op-word">not</span> <span class="name">state</span>:
+            <span class="name">p</span> <span class="op">=</span> <span class="name">meta</span>.<span class="name">select</span>([<span class="name">privileges</span>.<span class="name">c</span>.<span class="name">priv_id</span>], <span class="name">privileges</span>.<span class="name">c</span>.<span class="name">name</span> <span class="op">==</span> <span class="name">privilege</span>)
+            <span class="bn bn-pseudo">self</span>.<span class="name">ctx</span>.<span class="name">engine</span>.<span class="name">execute</span>(<span class="name">acl_mapping</span>.<span class="name">delete</span>(
+                (<span class="name">acl_mapping</span>.<span class="name">c</span>.<span class="name">priv_id</span> <span class="op">==</span> <span class="name">p</span>.<span class="name">c</span>.<span class="name">priv_id</span>) <span class="op">&</span>
+
+                (<span class="name">acl_mapping</span>.<span class="name">c</span>.<span class="name">subject_id</span> <span class="op">==</span> <span class="bn bn-pseudo">self</span>.<span class="name">subject</span>.<span class="name">subject_id</span>) <span class="op">&</span>
+
+                (<span class="name">acl_mapping</span>.<span class="name">c</span>.<span class="name">object_id</span> <span class="op">==</span> <span class="name">obj</span>.<span class="name">object_id</span>)
+            ))
+            <span class="kw">return</span>
+        <span class="cm"># touch privilege and check existing mapping</span>
+
+        <span class="name">priv_id</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">_fetch_privilege</span>(<span class="name">privilege</span>)
+        <span class="name">r</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">ctx</span>.<span class="name">engine</span>.<span class="name">execute</span>(<span class="name">meta</span>.<span class="name">select</span>([<span class="name">acl_mapping</span>.<span class="name">c</span>.<span class="name">state</span>],
+            (<span class="name">acl_mapping</span>.<span class="name">c</span>.<span class="name">priv_id</span> <span class="op">==</span> <span class="name">priv_id</span>) <span class="op">&</span>
+
+            (<span class="name">acl_mapping</span>.<span class="name">c</span>.<span class="name">subject_id</span> <span class="op">==</span> <span class="bn bn-pseudo">self</span>.<span class="name">subject</span>.<span class="name">subject_id</span>) <span class="op">&</span>
+
+            (<span class="name">acl_mapping</span>.<span class="name">c</span>.<span class="name">object_id</span> <span class="op">==</span> <span class="name">obj</span>.<span class="name">object_id</span>)
+        ))
+        <span class="name">row</span> <span class="op">=</span> <span class="name">r</span>.<span class="name">fetchone</span>()
+        <span class="kw">if</span> <span class="name">row</span> <span class="op op-word">is</span> <span class="op op-word">not</span> <span class="bn bn-pseudo">None</span>:
+            <span class="cm"># this rule exists already</span>
+
+            <span class="kw">if</span> <span class="name">row</span>[<span class="st st-sg">'</span><span class="st">state</span><span class="st st-sg">'</span>] <span class="op">==</span> <span class="name">state</span>:
+                <span class="kw">return</span>
+            <span class="cm"># goddamn, same rule - different state, delete old first</span>
+            <span class="bn bn-pseudo">self</span>.<span class="name">_set</span>(<span class="name">privilege</span>, <span class="name">obj</span>, <span class="nb nb-int">0</span>)
+        <span class="cm"># insert new rule</span>
+
+        <span class="bn bn-pseudo">self</span>.<span class="name">ctx</span>.<span class="name">engine</span>.<span class="name">execute</span>(<span class="name">acl_mapping</span>.<span class="name">insert</span>(),
+            <span class="name">priv_id</span> <span class="op">=</span> <span class="name">priv_id</span>,
+            <span class="name">subject_id</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">subject</span>.<span class="name">subject_id</span>,
+            <span class="name">object_id</span> <span class="op">=</span> <span class="name">obj</span>.<span class="name">object_id</span>,
+            <span class="name">state</span> <span class="op">=</span> <span class="name">state</span>
+
+        )
+
+    <span class="kw">def </span><span class="fun">_bootstrap</span>(<span class="bn bn-pseudo">self</span>):
+        <span class="st st-db">"""</span><span class="st">This method is automatically called when subject_id is
+        None and an subject_id is required.</span><span class="st st-db">"""</span>
+        <span class="name">r</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">ctx</span>.<span class="name">engine</span>.<span class="name">execute</span>(<span class="name">acl_subjects</span>.<span class="name">insert</span>(),
+            <span class="name">subject_type</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">_type</span>
+
+        )
+        <span class="bn bn-pseudo">self</span>.<span class="name">subject</span>.<span class="name">subject_id</span> <span class="op">=</span> <span class="name">r</span>.<span class="name">last_inserted_ids</span>()[<span class="nb nb-int">0</span>]
+        <span class="bn bn-pseudo">self</span>.<span class="name">subject</span>.<span class="name">save</span>()
+
+    <span class="kw">def </span><span class="fun">_bootstrap_object</span>(<span class="bn bn-pseudo">self</span>, <span class="name">obj</span>):
+        <span class="st st-db">"""</span><span class="st">Like _bootstrap but works for objects.</span><span class="st st-db">"""</span>
+
+        <span class="name">objtype</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">_get_object_type</span>(<span class="name">obj</span>)
+        <span class="name">r</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">ctx</span>.<span class="name">engine</span>.<span class="name">execute</span>(<span class="name">acl_objects</span>.<span class="name">insert</span>(),
+            <span class="name">object_type</span> <span class="op">=</span> <span class="name">objtype</span>
+
+        )
+        <span class="name">obj</span>.<span class="name">object_id</span> <span class="op">=</span> <span class="name">r</span>.<span class="name">last_inserted_ids</span>()[<span class="nb nb-int">0</span>]
+        <span class="name">obj</span>.<span class="name">save</span>()
+
+    <span class="kw">def </span><span class="fun">_get_object_type</span>(<span class="bn bn-pseudo">self</span>, <span class="name">obj</span>):
+        <span class="kw">if</span> <span class="bn">isinstance</span>(<span class="name">obj</span>, <span class="name">Forum</span>):
+            <span class="kw">return</span> <span class="st st-sg">'</span><span class="st">forum</span><span class="st st-sg">'</span>
+
+        <span class="kw">elif</span> <span class="bn">isinstance</span>(<span class="name">obj</span>, <span class="name">Thread</span>):
+            <span class="kw">return</span> <span class="st st-sg">'</span><span class="st">thread</span><span class="st st-sg">'</span>
+        <span class="kw">elif</span> <span class="name">obj</span> <span class="op op-word">is</span> <span class="name">Site</span>:
+            <span class="kw">return</span> <span class="st st-sg">'</span><span class="st">site</span><span class="st st-sg">'</span>
+
+        <span class="kw">raise</span> <span class="exc">TypeError</span>(<span class="st st-sg">'</span><span class="st">obj isn</span><span class="st st-esc">\'</span><span class="st">t a forum or thread</span><span class="st st-sg">'</span>)
+
+    <span class="kw">def </span><span class="fun">_get_object_join</span>(<span class="bn bn-pseudo">self</span>, <span class="name">obj</span>):
+        <span class="st st-db">"""</span><span class="st">Returns a subjoin for the object id.</span><span class="st st-db">"""</span>
+
+        <span class="name">t</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">_get_object_type</span>(<span class="name">obj</span>)
+        <span class="kw">if</span> <span class="name">t</span> <span class="op">==</span> <span class="st st-sg">'</span><span class="st">forum</span><span class="st st-sg">'</span>:
+            <span class="kw">return</span> <span class="name">meta</span>.<span class="name">select</span>([<span class="name">forums</span>.<span class="name">c</span>.<span class="name">object_id</span>],
+                <span class="name">forums</span>.<span class="name">c</span>.<span class="name">forum_id</span> <span class="op">==</span> <span class="name">obj</span>.<span class="name">forum_id</span>
+
+            )
+        <span class="kw">elif</span> <span class="name">t</span> <span class="op">==</span> <span class="st st-sg">'</span><span class="st">thread</span><span class="st st-sg">'</span>:
+            <span class="kw">return</span> <span class="name">meta</span>.<span class="name">select</span>([<span class="name">posts</span>.<span class="name">c</span>.<span class="name">object_id</span>],
+                <span class="name">posts</span>.<span class="name">c</span>.<span class="name">post_id</span> <span class="op">==</span> <span class="name">obj</span>.<span class="name">post_id</span>
+
+            )
+        <span class="kw">else</span>:
+            <span class="cm"># XXX: it works ^^</span>
+            <span class="cm"># i really want something like meta.select('0 as group_id')</span>
+            <span class="kw">class </span><span class="cls">Fake</span>(<span class="bn">object</span>):
+                <span class="kw">def </span><span class="fun">alias</span>(<span class="bn bn-pseudo">self</span>, <span class="name">n</span>):
+                    <span class="kw">class </span><span class="cls">_C</span>(<span class="bn">object</span>):
+                        <span class="kw">class </span><span class="cls">c</span>(<span class="bn">object</span>):
+                            <span class="name">object_id</span> <span class="op">=</span> <span class="nb nb-int">0</span>
+
+                    <span class="kw">return</span> <span class="name">_C</span>
+            <span class="kw">return</span> <span class="name">Fake</span>()
+
+    <span class="kw">def </span><span class="fun">_get_subject_join</span>(<span class="bn bn-pseudo">self</span>):
+        <span class="st st-db">"""</span><span class="st">Returns a subjoin for the subject id.</span><span class="st st-db">"""</span>
+
+        <span class="kw">if</span> <span class="bn bn-pseudo">self</span>.<span class="name">_type</span> <span class="op">==</span> <span class="st st-sg">'</span><span class="st">user</span><span class="st st-sg">'</span>:
+            <span class="kw">return</span> <span class="name">meta</span>.<span class="name">select</span>([<span class="name">users</span>.<span class="name">c</span>.<span class="name">subject_id</span>],
+                <span class="name">users</span>.<span class="name">c</span>.<span class="name">user_id</span> <span class="op">==</span> <span class="bn bn-pseudo">self</span>.<span class="name">subject</span>.<span class="name">user_id</span>
+
+            )
+        <span class="kw">return</span> <span class="name">meta</span>.<span class="name">select</span>([<span class="name">groups</span>.<span class="name">c</span>.<span class="name">subject_id</span>],
+            <span class="name">groups</span>.<span class="name">c</span>.<span class="name">group_id</span> <span class="op">==</span> <span class="bn bn-pseudo">self</span>.<span class="name">subject</span>.<span class="name">group_id</span>
+
+        )
+
+    <span class="kw">def </span><span class="fun">_fetch_privilege</span>(<span class="bn bn-pseudo">self</span>, <span class="name">name</span>):
+        <span class="st st-db">"""</span><span class="st">Returns the priv_id for the given privilege. If it
+        doesn</span><span class="st st-esc">\'</span><span class="st">t exist by now the system will create a new
+        privilege.</span><span class="st st-db">"""</span>
+        <span class="name">r</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">ctx</span>.<span class="name">engine</span>.<span class="name">execute</span>(<span class="name">meta</span>.<span class="name">select</span>([<span class="name">privileges</span>.<span class="name">c</span>.<span class="name">priv_id</span>],
+            <span class="name">privileges</span>.<span class="name">c</span>.<span class="name">name</span> <span class="op">==</span> <span class="name">name</span>
+
+        ))
+        <span class="name">row</span> <span class="op">=</span> <span class="name">r</span>.<span class="name">fetchone</span>()
+        <span class="kw">if</span> <span class="name">row</span> <span class="op op-word">is</span> <span class="op op-word">not</span> <span class="bn bn-pseudo">None</span>:
+            <span class="kw">return</span> <span class="name">row</span>[<span class="nb nb-int">0</span>]
+        <span class="name">r</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">ctx</span>.<span class="name">engine</span>.<span class="name">execute</span>(<span class="name">privileges</span>.<span class="name">insert</span>(),
+            <span class="name">name</span> <span class="op">=</span> <span class="name">name</span>
+
+        )
+        <span class="kw">return</span> <span class="name">r</span>.<span class="name">last_inserted_ids</span>()[<span class="nb nb-int">0</span>]
+
+    <span class="kw">def </span><span class="fun">__repr__</span>(<span class="bn bn-pseudo">self</span>):
+        <span class="kw">if</span> <span class="bn bn-pseudo">self</span>.<span class="name">_type</span> <span class="op">==</span> <span class="st st-sg">'</span><span class="st">user</span><span class="st st-sg">'</span>:
+            <span class="name">id_</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">subject</span>.<span class="name">user_id</span>
+
+        <span class="kw">else</span>:
+            <span class="name">id_</span> <span class="op">=</span> <span class="bn bn-pseudo">self</span>.<span class="name">subject</span>.<span class="name">group_id</span>
+        <span class="kw">if</span> <span class="bn bn-pseudo">self</span>.<span class="name">subject</span>.<span class="name">subject_id</span> <span class="op op-word">is</span> <span class="bn bn-pseudo">None</span>:
+            <span class="kw">return</span> <span class="st st-sg">'</span><span class="st"><</span><span class="st st-int">%s</span><span class="st"> </span><span class="st st-int">%s</span><span class="st">:</span><span class="st st-int">%d</span><span class="st"> inactive></span><span class="st st-sg">'</span> <span class="op">%</span> (
+                <span class="bn bn-pseudo">self</span>.<span class="name">__class__</span>.<span class="name">__name__</span>,
+                <span class="bn bn-pseudo">self</span>.<span class="name">_type</span>,
+                <span class="name">id_</span>
+
+            )
+        <span class="kw">return</span> <span class="st st-sg">'</span><span class="st"><</span><span class="st st-int">%s</span><span class="st"> </span><span class="st st-int">%s</span><span class="st">:</span><span class="st st-int">%d</span><span class="st"> active as </span><span class="st st-int">%d</span><span class="st">></span><span class="st st-sg">'</span> <span class="op">%</span> (
+            <span class="bn bn-pseudo">self</span>.<span class="name">__class__</span>.<span class="name">__name__</span>,
+            <span class="bn bn-pseudo">self</span>.<span class="name">_type</span>,
+            <span class="name">id_</span>,
+            <span class="bn bn-pseudo">self</span>.<span class="name">subject</span>.<span class="name">subject_id</span>
+
+        )
+
diff --git a/app/server/vendor/rouge/spec/visual/samples/http b/app/server/vendor/rouge/spec/visual/samples/http
new file mode 100755
index 0000000..bf6ac8b
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/http
@@ -0,0 +1,29 @@
+HTTP/1.1 200 OK
+Date: Tue, 13 Dec 2011 00:11:44 GMT
+Status: 200 OK
+X-Transaction: 50b85fff78dab4a3
+X-RateLimit-Limit: 150
+ETag: "b31143be48ebfe7512b65fe64fe092f3"
+X-Frame-Options: SAMEORIGIN
+Last-Modified: Tue, 13 Dec 2011 00:11:44 GMT
+X-RateLimit-Remaining: 145
+X-Runtime: 0.01190
+X-Transaction-Mask: a6183ffa5f8ca943ff1b53b5644ef1145f6f285d
+Content-Type: application/json; charset=utf-8
+Content-Length: 2389
+Pragma: no-cache
+X-RateLimit-Class: api
+X-Revision: DEV
+Expires: Tue, 31 Mar 1981 05:00:00 GMT
+Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+X-MID: a55f21733bc52bb11d1fc58f9b51b4974fbb8f83
+X-RateLimit-Reset: 1323738416
+Set-Cookie: k=10.34.234.116.1323735104238974; path=/;
+	expires=Tue, 20-Dec-11 00:11:44 GMT; domain=.twitter.com
+Set-Cookie: guest_id=v1%3A13237351042425496; domain=.twitter.com; path=/;
+	expires=Thu, 12-Dec-2013 12:11:44 GMT
+Set-Cookie: _twitter_sess=BAh7CDoPY3JlYXRlZF9hdGwrCPS6wjQ0AToHaWQiJTFiMTlhY2E1ZjczYThk%250ANDUwMWQxNjMwZGU2YTQ1ODBhIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy%250AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--6b502f30a083e8a41a64f10930e142ea362b1561; domain=.twitter.com; path=/; HttpOnly
+Vary: Accept-Encoding
+Server: tfe
+
+[{"contributors_enabled":false,"profile_background_tile":true,"followers_count":644,"protected":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/69064242\/gb_normal.jpg","screen_name":"birkenfeld","default_profile_image":false,"following":null,"friends_count":88,"profile_sidebar_fill_color":"7AC3EE","url":"http:\/\/pythonic.pocoo.org\/","name":"Georg Brandl","default_profile":false,"is_translator":false,"utc_offset":3600,"profile_sidebar_border_color":"65B0DA","description":"","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme10\/bg.gif","favourites_count":0,"profile_use_background_image":true,"created_at":"Tue Dec 30 22:25:11 +0000 2008","status":{"retweet_count":10,"favorited":false,"geo":null,"possibly_sensitive":false,"coordinates":null,"in_reply_to_screen_name":null,"in_reply_to_status_id_str":null,"retweeted":false,"in_reply_to_status_id":null,"in_reply_to_user_id_str":null,"created_at":"Sat Jul 09 13:42:35 +0000 2011","truncated":false,"id_str":"89690914515206144","contributors":null,"place":null,"source":"web","in_reply_to_user_id":null,"id":89690914515206144,"retweeted_status":{"retweet_count":10,"favorited":false,"geo":null,"possibly_sensitive":false,"coordinates":null,"in_reply_to_screen_name":null,"in_reply_to_status_id_str":null,"retweeted":false,"in_reply_to_status_id":null,"in_reply_to_user_id_str":null,"created_at":"Sat Jul 09 13:07:04 +0000 2011","truncated":false,"id_str":"89681976755372032","contributors":null,"place":null,"source":"web","in_reply_to_user_id":null,"id":89681976755372032,"text":"Excellent Python posts from @mitsuhiko - http:\/\/t.co\/k1wt6e4 and @ncoghlan_dev - http:\/\/t.co\/eTxacgZ (links fixed)"},"text":"RT @jessenoller: Excellent Python posts from @mitsuhiko - http:\/\/t.co\/k1wt6e4 and @ncoghlan_dev - http:\/\/t.co\/eTxacgZ (links fixed)"},"follow_request_sent":null,"statuses_count":553,"geo_enabled":false,"notifications":null,"profile_text_color":"3D1957","id_str":"18490730","lang":"en","profile_background_image_url":"http:\/\/a1.twimg.com\/images\/themes\/theme10\/bg.gif","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/69064242\/gb_normal.jpg","show_all_inline_media":true,"listed_count":65,"profile_link_color":"FF0000","verified":false,"id":18490730,"time_zone":"Berlin","profile_background_color":"642D8B","location":"Bavaria, Germany"}]
diff --git a/app/server/vendor/rouge/spec/visual/samples/ini b/app/server/vendor/rouge/spec/visual/samples/ini
new file mode 100755
index 0000000..7016b56
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/ini
@@ -0,0 +1,71 @@
+##### a gitconfig #####
+[core]
+  editor = gvim -v
+  excludesfile = ~/.gitignore
+  # autocrlf = input
+[user]
+  name = Jay Adkisson
+  email = jjmadkisson at gmail.com
+[github]
+  user = jayferd
+  token = "ee14fce5546288e00fc0d6dc456fb3ec"
+[color]
+  branch = auto
+  diff = auto
+  interactive = auto
+  status = auto
+[merge]
+  defaultToUpstream = true
+  conflictStyle = diff3
+[push]
+  default = upstream
+[alias]
+  co = checkout
+
+  rs = reset
+
+  ci = commit -v
+  c  = commit -v
+
+  st = status
+  s  = status
+
+  b = branch
+  br = branch
+  d = diff
+  dc = diff --cached
+
+  a  = add
+  ap = add --patch
+  ae = add --edit
+
+  ps = push
+  fe = fetch
+
+  sh = stash
+
+  # fast-forward
+  ff = merge --ff-only
+  # merge-commit
+  mc = merge --no-ff
+
+  rr = rebase origin
+
+  lg = log --decorate --graph --date=local
+
+  root = rev-parse --show-toplevel
+  head = rev-parse HEAD
+
+;;;;;;  SYSTEM.INI ;;;;;;
+; for 16-bit app support
+[drivers]
+wave=mmdrv.dll
+timer=timer.drv
+[mci]
+[driver32]
+[386enh]
+woafont=dosapp.FON
+EGA80WOA.FON=EGA80WOA.FON
+EGA40WOA.FON=EGA40WOA.FON
+CGA80WOA.FON=CGA80WOA.FON
+CGA40WOA.FON=CGA40WOA.FON
diff --git a/app/server/vendor/rouge/spec/visual/samples/io b/app/server/vendor/rouge/spec/visual/samples/io
new file mode 100755
index 0000000..89ed824
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/io
@@ -0,0 +1,39 @@
+/+ nested /+ comments +/ ftw +/
+
+foo @bar
+foo @@bar(baz)
+
+#!/usr/bin/env io
+
+/* The Computer Language Shootout
+   http://shootout.alioth.debian.org
+   contributed by Robert Brandner */
+
+
+mkbuf := method(n,
+	b := List clone
+	b preallocateToSize(n)
+	n repeat(b append(true))
+	return b
+)
+
+nsieve := method(n,
+	primes := mkbuf(n)
+	cnt := 0
+	for(i, 2, n,
+		if(primes at(i),
+			k := i + i
+			while (k < n,
+				primes atPut(k, false)
+				k = k + i
+			)
+			cnt = cnt + 1
+		)
+	)
+	writeln("Primes up to", n asString alignRight(9, " "), cnt asString alignRight(9, " "))
+)
+
+n := System args at(1) asNumber
+nsieve( (2^n)*10000 )
+nsieve( (2^(n-1))*10000 )
+nsieve( (2^(n-2))*10000 )
diff --git a/app/server/vendor/rouge/spec/visual/samples/java b/app/server/vendor/rouge/spec/visual/samples/java
new file mode 100755
index 0000000..0df1fb5
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/java
@@ -0,0 +1,659 @@
+////// badcase.java //////
+
+// this used to take ages
+void foo() throws xxxxxxxxxxxxxxxxxxxxxx{ }
+
+////// test.java /////////
+/*
+ * Created on 13-Mar-2004
+ * Created by James Yeh
+ * Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * 
+ * AELITIS, SAS au capital de 46,603.30 euros
+ * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
+ *
+ */
+
+package org.gudy.azureus2.platform.macosx;
+
+import org.gudy.azureus2.core3.logging.*;
+import org.gudy.azureus2.core3.util.AEMonitor;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.SystemProperties;
+import org.gudy.azureus2.platform.PlatformManager;
+import org.gudy.azureus2.platform.PlatformManagerCapabilities;
+import org.gudy.azureus2.platform.PlatformManagerListener;
+import org.gudy.azureus2.platform.macosx.access.jnilib.OSXAccess;
+
+import org.gudy.azureus2.plugins.platform.PlatformManagerException;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.text.MessageFormat;
+import java.util.HashSet;
+
+
+/**
+ * Performs platform-specific operations with Mac OS X
+ *
+ * @author James Yeh
+ * @version 1.0 Initial Version
+ * @see PlatformManager
+ */
+public class PlatformManagerImpl implements PlatformManager
+{
+    private static final LogIDs LOGID = LogIDs.CORE;
+
+    protected static PlatformManagerImpl singleton;
+    protected static AEMonitor class_mon = new AEMonitor("PlatformManager");
+
+    private static final String USERDATA_PATH = new File(System.getProperty("user.home") + "/Library/Application Support/").getPath();
+
+    //T: PlatformManagerCapabilities
+    private final HashSet capabilitySet = new HashSet();
+
+    /**
+     * Gets the platform manager singleton, which was already initialized
+     */
+    public static PlatformManagerImpl getSingleton()
+    {
+        return singleton;
+    }
+
+    /**
+     * Tries to enable cocoa-java access and instantiates the singleton
+     */
+    static
+    {
+        initializeSingleton();
+    }
+
+    /**
+     * Instantiates the singleton
+     */
+    private static void initializeSingleton()
+    {
+        try
+        {
+            class_mon.enter();
+            singleton = new PlatformManagerImpl();
+        }
+        catch (Throwable e)
+        {
+        	Logger.log(new LogEvent(LOGID, "Failed to initialize platform manager"
+					+ " for Mac OS X", e));
+        }
+        finally
+        {
+            class_mon.exit();
+        }
+    }
+
+    /**
+     * Creates a new PlatformManager and initializes its capabilities
+     */
+    public PlatformManagerImpl()
+    {
+        capabilitySet.add(PlatformManagerCapabilities.RecoverableFileDelete);
+        capabilitySet.add(PlatformManagerCapabilities.ShowFileInBrowser);
+        capabilitySet.add(PlatformManagerCapabilities.ShowPathInCommandLine);
+        capabilitySet.add(PlatformManagerCapabilities.CreateCommandLineProcess);
+        capabilitySet.add(PlatformManagerCapabilities.GetUserDataDirectory);
+        capabilitySet.add(PlatformManagerCapabilities.UseNativeScripting);
+        capabilitySet.add(PlatformManagerCapabilities.PlaySystemAlert);
+        
+        if (OSXAccess.isLoaded()) {
+	        capabilitySet.add(PlatformManagerCapabilities.GetVersion);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int getPlatformType()
+    {
+        return PT_MACOSX;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getVersion() throws PlatformManagerException
+    {
+    	if (!OSXAccess.isLoaded()) {
+        throw new PlatformManagerException("Unsupported capability called on platform manager");
+    	}
+    	
+    	return OSXAccess.getVersion();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see org.gudy.azureus2.core3.util.SystemProperties#getUserPath()
+     */
+    public String getUserDataDirectory() throws PlatformManagerException
+    {
+        return USERDATA_PATH;
+    }
+
+	public File
+	getLocation(
+		long	location_id )
+	
+		throws PlatformManagerException
+	{
+		if ( location_id == LOC_USER_DATA ){
+			
+			return( new File( USERDATA_PATH ));
+		}
+		
+		return( null );
+	}
+    /**
+     * Not implemented; returns True
+     */
+    public boolean isApplicationRegistered() throws PlatformManagerException
+    {
+        return true;
+    }
+
+    
+	public String
+	getApplicationCommandLine()
+		throws PlatformManagerException
+	{
+		try{	    
+			String	bundle_path = System.getProperty("user.dir") +SystemProperties.SEP+ SystemProperties.getApplicationName() + ".app";
+
+			File osx_app_bundle = new File( bundle_path ).getAbsoluteFile();
+			
+			if( !osx_app_bundle.exists() ) {
+				String msg = "OSX app bundle not found: [" +osx_app_bundle.toString()+ "]";
+				System.out.println( msg );
+				if (Logger.isEnabled())
+					Logger.log(new LogEvent(LOGID, msg));		
+				throw new PlatformManagerException( msg );
+			}
+			
+			return "open -a \"" +osx_app_bundle.toString()+ "\"";
+			//return osx_app_bundle.toString() +"/Contents/MacOS/JavaApplicationStub";
+			
+		}
+		catch( Throwable t ){	
+			t.printStackTrace();
+			return null;
+		}
+	}
+	
+	
+	public boolean
+	isAdditionalFileTypeRegistered(
+		String		name,				// e.g. "BitTorrent"
+		String		type )				// e.g. ".torrent"
+	
+		throws PlatformManagerException
+	{
+	    throw new PlatformManagerException("Unsupported capability called on platform manager");
+	}
+	
+	public void
+	unregisterAdditionalFileType(
+		String		name,				// e.g. "BitTorrent"
+		String		type )				// e.g. ".torrent"
+		
+		throws PlatformManagerException
+	{
+		throw new PlatformManagerException("Unsupported capability called on platform manager");
+	}
+	
+	public void
+	registerAdditionalFileType(
+		String		name,				// e.g. "BitTorrent"
+		String		description,		// e.g. "BitTorrent File"
+		String		type,				// e.g. ".torrent"
+		String		content_type )		// e.g. "application/x-bittorrent"
+	
+		throws PlatformManagerException
+	{
+	   throw new PlatformManagerException("Unsupported capability called on platform manager");
+	}
+	
+    /**
+     * Not implemented; does nothing
+     */
+    public void registerApplication() throws PlatformManagerException
+    {
+        // handled by LaunchServices and/0r user interaction
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void createProcess(String cmd, boolean inheritsHandles) throws PlatformManagerException
+    {
+        try
+        {
+            performRuntimeExec(cmd.split(" "));
+        }
+        catch (Throwable e)
+        {
+            throw new PlatformManagerException("Failed to create process", e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void performRecoverableFileDelete(String path) throws PlatformManagerException
+    {
+        File file = new File(path);
+        if(!file.exists())
+        {
+	        	if (Logger.isEnabled())
+							Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING, "Cannot find "
+									+ file.getName()));
+            return;
+        }
+
+        boolean useOSA = !NativeInvocationBridge.sharedInstance().isEnabled() || !NativeInvocationBridge.sharedInstance().performRecoverableFileDelete(file);
+
+        if(useOSA)
+        {
+            try
+            {
+                StringBuffer sb = new StringBuffer();
+                sb.append("tell application \"");
+                sb.append("Finder");
+                sb.append("\" to move (posix file \"");
+                sb.append(path);
+                sb.append("\" as alias) to the trash");
+
+                performOSAScript(sb);
+            }
+            catch (Throwable e)
+            {
+                throw new PlatformManagerException("Failed to move file", e);
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean hasCapability(PlatformManagerCapabilities capability)
+    {
+        return capabilitySet.contains(capability);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void dispose()
+    {
+        NativeInvocationBridge.sharedInstance().dispose();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setTCPTOSEnabled(boolean enabled) throws PlatformManagerException
+    {
+        throw new PlatformManagerException("Unsupported capability called on platform manager");
+    }
+
+	public void
+    copyFilePermissions(
+		String	from_file_name,
+		String	to_file_name )
+	
+		throws PlatformManagerException
+	{
+	    throw new PlatformManagerException("Unsupported capability called on platform manager");		
+	}
+	
+    /**
+     * {@inheritDoc}
+     */
+    public void showFile(String path) throws PlatformManagerException
+    {
+        File file = new File(path);
+        if(!file.exists())
+        {
+        	if (Logger.isEnabled())
+        		Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING, "Cannot find "
+        				+ file.getName()));
+            throw new PlatformManagerException("File not found");
+        }
+
+        showInFinder(file);
+    }
+
+    // Public utility methods not shared across the interface
+
+    /**
+     * Plays the system alert (the jingle is specified by the user in System Preferences)
+     */
+    public void playSystemAlert()
+    {
+        try
+        {
+            performRuntimeExec(new String[]{"beep"});
+        }
+        catch (IOException e)
+        {
+        	if (Logger.isEnabled())
+        		Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING,
+						"Cannot play system alert"));
+        	Logger.log(new LogEvent(LOGID, "", e));
+        }
+    }
+
+    /**
+     * <p>Shows the given file or directory in Finder</p>
+     * @param path Absolute path to the file or directory
+     */
+    public void showInFinder(File path)
+    {
+        boolean useOSA = !NativeInvocationBridge.sharedInstance().isEnabled() || !NativeInvocationBridge.sharedInstance().showInFinder(path);
+
+        if(useOSA)
+        {
+            StringBuffer sb = new StringBuffer();
+            sb.append("tell application \"");
+            sb.append(getFileBrowserName());
+            sb.append("\" to reveal (posix file \"");
+            sb.append(path);
+            sb.append("\" as alias)");
+
+            try
+            {
+                performOSAScript(sb);
+            }
+            catch (IOException e)
+            {
+                Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, e
+						.getMessage()));
+            }
+        }
+    }
+
+    /**
+     * <p>Shows the given file or directory in Terminal by executing cd /absolute/path/to</p>
+     * @param path Absolute path to the file or directory
+     */
+    public void showInTerminal(String path)
+    {
+        showInTerminal(new File(path));
+    }
+
+    /**
+     * <p>Shows the given file or directory in Terminal by executing cd /absolute/path/to</p>
+     * @param path Absolute path to the file or directory
+     */
+    public void showInTerminal(File path)
+    {
+        if (path.isFile())
+        {
+            path = path.getParentFile();
+        }
+
+        if (path != null && path.isDirectory())
+        {
+            StringBuffer sb = new StringBuffer();
+            sb.append("tell application \"");
+            sb.append("Terminal");
+            sb.append("\" to do script \"cd ");
+            sb.append(path.getAbsolutePath().replaceAll(" ", "\\ "));
+            sb.append("\"");
+
+            try
+            {
+                performOSAScript(sb);
+            }
+            catch (IOException e)
+            {
+                Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, e
+						.getMessage()));
+            }
+        }
+        else
+        {
+        	if (Logger.isEnabled())
+        		Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING, "Cannot find "
+        				+ path.getName()));
+        }
+    }
+
+    // Internal utility methods
+
+    /**
+     * Compiles a new AppleScript instance and runs it
+     * @param cmd AppleScript command to execute; do not surround command with extra quotation marks
+     * @return Output of the script
+     * @throws IOException If the script failed to execute
+     */
+    protected static String performOSAScript(CharSequence cmd) throws IOException
+    {
+        return performOSAScript(new CharSequence[]{cmd});
+    }
+
+    /**
+     * Compiles a new AppleScript instance and runs it
+     * @param cmds AppleScript Sequence of commands to execute; do not surround command with extra quotation marks
+     * @return Output of the script
+     * @throws IOException If the script failed to execute
+     */
+    protected static String performOSAScript(CharSequence[] cmds) throws IOException
+    {
+        long start = System.currentTimeMillis();
+        Debug.outNoStack("Executing OSAScript: ");
+        for (int i = 0; i < cmds.length; i++)
+        {
+            Debug.outNoStack("\t" + cmds[i]);
+        }
+
+        String[] cmdargs = new String[2 * cmds.length + 1];
+        cmdargs[0] = "osascript";
+        for (int i = 0; i < cmds.length; i++)
+        {
+            cmdargs[i * 2 + 1] = "-e";
+            cmdargs[i * 2 + 2] = String.valueOf(cmds[i]);
+        }
+
+        Process osaProcess = performRuntimeExec(cmdargs);
+        BufferedReader reader = new BufferedReader(new InputStreamReader(osaProcess.getInputStream()));
+        String line = reader.readLine();
+        reader.close();
+        Debug.outNoStack("OSAScript Output: " + line);
+
+        reader = new BufferedReader(new InputStreamReader(osaProcess.getErrorStream()));
+        String errorMsg = reader.readLine();
+        reader.close();
+
+        Debug.outNoStack("OSAScript Error (if any): " + errorMsg);
+
+        Debug.outNoStack(MessageFormat.format("OSAScript execution ended ({0}ms)", new Object[]{String.valueOf(System.currentTimeMillis() - start)}));
+
+        if (errorMsg != null)
+        {
+            throw new IOException(errorMsg);
+        }
+
+        return line;
+    }
+
+    /**
+     * Compiles a new AppleScript instance and runs it
+     * @param script AppleScript file (.scpt) to execute
+     * @return Output of the script
+     * @throws IOException If the script failed to execute
+     */
+    protected static String performOSAScript(File script) throws IOException
+    {
+        long start = System.currentTimeMillis();
+        Debug.outNoStack("Executing OSAScript from file: " + script.getPath());
+
+        Process osaProcess = performRuntimeExec(new String[]{"osascript", script.getPath()});
+        BufferedReader reader = new BufferedReader(new InputStreamReader(osaProcess.getInputStream()));
+        String line = reader.readLine();
+        reader.close();
+        Debug.outNoStack("OSAScript Output: " + line);
+
+        reader = new BufferedReader(new InputStreamReader(osaProcess.getErrorStream()));
+        String errorMsg = reader.readLine();
+        reader.close();
+
+        Debug.outNoStack("OSAScript Error (if any): " + errorMsg);
+
+        Debug.outNoStack(MessageFormat.format("OSAScript execution ended ({0}ms)", new Object[]{String.valueOf(System.currentTimeMillis() - start)}));
+
+        if (errorMsg != null)
+        {
+            throw new IOException(errorMsg);
+        }
+
+        return line;
+    }
+
+    /**
+     * Compiles a new AppleScript instance to the specified location
+     * @param cmd         Command to compile; do not surround command with extra quotation marks
+     * @param destination Destination location of the AppleScript file
+     * @return True if compiled successfully
+     */
+    protected static boolean compileOSAScript(CharSequence cmd, File destination)
+    {
+        return compileOSAScript(new CharSequence[]{cmd}, destination);
+    }
+
+    /**
+     * Compiles a new AppleScript instance to the specified location
+     * @param cmds Sequence of commands to compile; do not surround command with extra quotation marks
+     * @param destination Destination location of the AppleScript file
+     * @return True if compiled successfully
+     */
+    protected static boolean compileOSAScript(CharSequence[] cmds, File destination)
+    {
+        long start = System.currentTimeMillis();
+        Debug.outNoStack("Compiling OSAScript: " + destination.getPath());
+        for (int i = 0; i < cmds.length; i++)
+        {
+            Debug.outNoStack("\t" + cmds[i]);
+        }
+
+        String[] cmdargs = new String[2 * cmds.length + 3];
+        cmdargs[0] = "osacompile";
+        for (int i = 0; i < cmds.length; i++)
+        {
+            cmdargs[i * 2 + 1] = "-e";
+            cmdargs[i * 2 + 2] = String.valueOf(cmds[i]);
+        }
+
+        cmdargs[cmdargs.length - 2] = "-o";
+        cmdargs[cmdargs.length - 1] = destination.getPath();
+
+        String errorMsg;
+        try
+        {
+            Process osaProcess = performRuntimeExec(cmdargs);
+
+            BufferedReader reader = new BufferedReader(new InputStreamReader(osaProcess.getErrorStream()));
+            errorMsg = reader.readLine();
+            reader.close();
+        }
+        catch (IOException e)
+        {
+            Debug.outNoStack("OSACompile Execution Failed: " + e.getMessage());
+            Debug.printStackTrace(e);
+            return false;
+        }
+
+        Debug.outNoStack("OSACompile Error (if any): " + errorMsg);
+
+        Debug.outNoStack(MessageFormat.format("OSACompile execution ended ({0}ms)", new Object[]{String.valueOf(System.currentTimeMillis() - start)}));
+
+        return (errorMsg == null);
+    }
+
+    /**
+     * @see Runtime#exec(String[])
+     */
+    protected static Process performRuntimeExec(String[] cmdargs) throws IOException
+    {
+        try
+        {
+            return Runtime.getRuntime().exec(cmdargs);
+        }
+        catch (IOException e)
+        {
+            Logger.log(new LogAlert(LogAlert.UNREPEATABLE, e.getMessage(), e));
+            throw e;
+        }
+    }
+
+    /**
+     * <p>Gets the preferred file browser name</p>
+     * <p>Currently supported browsers are Path Finder and Finder. If Path Finder is currently running
+     * (not just installed), then "Path Finder is returned; else, "Finder" is returned.</p>
+     * @return "Path Finder" if it is currently running; else "Finder"
+     */
+    private static String getFileBrowserName()
+    {
+        try
+        {
+            // slowwwwwwww
+            if ("true".equalsIgnoreCase(performOSAScript("tell application \"System Events\" to exists process \"Path Finder\"")))
+            {
+                Debug.outNoStack("Path Finder is running");
+
+                return "Path Finder";
+            }
+            else
+            {
+                return "Finder";
+            }
+        }
+        catch (IOException e)
+        {
+            Debug.printStackTrace(e);
+            Logger.log(new LogEvent(LOGID, e.getMessage(), e));
+
+            return "Finder";
+        }
+    }
+    
+	public boolean
+	testNativeAvailability(
+		String	name )
+	
+		throws PlatformManagerException
+	{
+	    throw new PlatformManagerException("Unsupported capability called on platform manager");		
+	}
+    
+    public void
+    addListener(
+    	PlatformManagerListener		listener )
+    {
+    }
+    
+    public void
+    removeListener(
+    	PlatformManagerListener		listener )
+    {
+    }
+}
diff --git a/app/server/vendor/rouge/spec/visual/samples/javascript b/app/server/vendor/rouge/spec/visual/samples/javascript
new file mode 100755
index 0000000..dc52f1f
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/javascript
@@ -0,0 +1,129 @@
+// vim: ft=javascript
+
+var myFloat = 0.123;
+var myOctal = 0x123;
+var myRegex = /asdf/;
+var myComplicatedRegex = /.[.](?=x\h\[[)])[^.{}abc]{foo}{3,}x{2,3}/
+var myObject = { a: 1, b: 2 }
+
+var ternary = 0 ? 1 : {object_key : 2 ? variable : 3 };
+var ternary2 = a ? { object_key : c } + variable : e;
+var ternary3 = a ? {
+  key1 : var1,
+  key2: var2 ? function() {
+    label1: // break label, not an object key!
+    while(true) {
+      break myLabel;
+    }
+  } + var3: var4
+} : 2
+
+var obj =
+  {
+    // comment
+    key: val
+  }
+
+/*!
+ * multiline comment
+ */
+
+var quotedKeys = {
+  "one": 1,
+  "two": 2,
+  "three": 3,
+};
+
+Blag = {};
+jQuery.noConflict();
+
+if (cond)
+{
+  label1:
+  while (cond) break label1;
+}
+
+Blag.ReadMore = (function($) {
+  function getFold(button) {
+    return $(button).siblings('.fold');
+  }
+
+  function expand(e) {
+    e.preventDefault();
+
+    var self = $(this);
+
+    getFold(self).show();
+    self.html('« less');
+  }
+
+  function contract(e) {
+    e.preventDefault();
+
+    var self = $(this);
+
+    getFold(self).hide();
+    self.html('more »')
+  }
+
+  function init() {
+    $('a.read-more').toggle(expand, contract);
+  }
+
+  $(document).ready(init);
+})(jQuery);
+
+// evil regexes, from pygments
+
+/regexp/.test(foo) || x = [/regexp/,/regexp/, /regexp/, // comment
+// comment
+/regexp/];
+if (/regexp/.test(string))
+{/regexp/.test(string);};
+x =/regexp/;
+x = /regexp/;
+if (0</regexp/.exec(string) || 1>/regexp/.exec(string))
+x = { u:/regexp/, v: /regexp/ };
+foo();/regexp/.test(string); /regexp/.test(string);
+if (!/regexp/) foobar();
+x = u %/regexp/.exec(string) */regexp/.exec(string) / /regexp/.exec(string);
+x = u?/regexp/.exec(string) : v +/regexp/.exec(string) -/regexp/.exec(string);
+a = u^/regexp/.exec(string) &/regexp/.exec(string) |/regexp/.exec(string) +~/regexp/.exec(string);
+x = /regexp/ /* a comment */ ;
+x = /[reg/exp]/;
+x = 4/2/i;
+x = (a == b) ?/* this is a comment */ c : d;
+/// a comment //
+a = /regex//2/1; //syntactically correct, returns NaN
+
+// bad regexen - should have an error token at the last char and recover
+// on the next line
+var a = /foo
+var b = /[foo
+var c = /valid-regex/
+
+var template = "{{current}} of beer on the wall";
+var stanza = template.replace(/{{current}}/g, "99 bottles");
+
+/* original examples */
+
+// regex
+
+blah(/abc/);
+x = /abc/;
+x = /abc/.match;
+
+// math
+
+blah(1/2); //comment
+x = 1 / 2 / 3;
+x = 1/1/.1;
+
+x=/1/; // regex
+x=1/a/g; // division
+x=a/a/g; // division
+
+// real-world
+
+var x = 1/(1+Math.sqrt(sum)); // convert to number between 1-0
+return Math.round((num / den) * 100)/100;
diff --git a/app/server/vendor/rouge/spec/visual/samples/json b/app/server/vendor/rouge/spec/visual/samples/json
new file mode 100755
index 0000000..9c847f1
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/json
@@ -0,0 +1,25 @@
+{
+    "firstName": "John",
+    "lastName": "Smith",
+    "age": 25,
+    "address": {
+        "streetAddress": "21 2nd Street",
+        "city": "New York",
+        "state": "NY",
+        "postalCode": "10021"
+    },
+    "phoneNumber": [
+        {
+            "type": "home",
+            "number": "212 555-1234"
+        },
+        {
+            "type": "fax",
+            "number": "646 555-4567"
+        }
+    ],
+    "errors": {
+        "object": { "a", "b" }
+    },
+    "emptyObject": {}
+}
diff --git a/app/server/vendor/rouge/spec/visual/samples/literate_coffeescript b/app/server/vendor/rouge/spec/visual/samples/literate_coffeescript
new file mode 100755
index 0000000..06a2407
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/literate_coffeescript
@@ -0,0 +1,116 @@
+The **Scope** class regulates lexical scoping within CoffeeScript. As you
+generate code, you create a tree of scopes in the same shape as the nested
+function bodies. Each scope knows about the variables declared within it,
+and has a reference to its parent enclosing scope. In this way, we know which
+variables are new and need to be declared with `var`, and which are shared
+with external scopes.
+
+Import the helpers we plan to use.
+
+    {extend, last} = require './helpers'
+
+    exports.Scope = class Scope
+
+The `root` is the top-level **Scope** object for a given file.
+
+      @root: null
+
+Initialize a scope with its parent, for lookups up the chain,
+as well as a reference to the **Block** node it belongs to, which is
+where it should declare its variables, and a reference to the function that
+it belongs to.
+
+      constructor: (@parent, @expressions, @method) ->
+        @variables = [{name: 'arguments', type: 'arguments'}]
+        @positions = {}
+        Scope.root = this unless @parent
+
+Adds a new variable or overrides an existing one.
+
+      add: (name, type, immediate) ->
+        return @parent.add name, type, immediate if @shared and not immediate
+        if Object::hasOwnProperty.call @positions, name
+          @variables[@positions[name]].type = type
+        else
+          @positions[name] = @variables.push({name, type}) - 1
+
+When `super` is called, we need to find the name of the current method we're
+in, so that we know how to invoke the same method of the parent class. This
+can get complicated if super is being called from an inner function.
+`namedMethod` will walk up the scope tree until it either finds the first
+function object that has a name filled in, or bottoms out.
+
+      namedMethod: ->
+        return @method if @method.name or !@parent
+        @parent.namedMethod()
+
+Look up a variable name in lexical scope, and declare it if it does not
+already exist.
+
+      find: (name) ->
+        return yes if @check name
+        @add name, 'var'
+        no
+
+Reserve a variable name as originating from a function parameter for this
+scope. No `var` required for internal references.
+
+      parameter: (name) ->
+        return if @shared and @parent.check name, yes
+        @add name, 'param'
+
+Just check to see if a variable has already been declared, without reserving,
+walks up to the root scope.
+
+      check: (name) ->
+        !!(@type(name) or @parent?.check(name))
+
+Generate a temporary variable name at the given index.
+
+      temporary: (name, index) ->
+        if name.length > 1
+          '_' + name + if index > 1 then index - 1 else ''
+        else
+          '_' + (index + parseInt name, 36).toString(36).replace /\d/g, 'a'
+
+Gets the type of a variable.
+
+      type: (name) ->
+        return v.type for v in @variables when v.name is name
+        null
+
+If we need to store an intermediate result, find an available name for a
+compiler-generated variable. `_var`, `_var2`, and so on...
+
+      freeVariable: (name, reserve=true) ->
+        index = 0
+        index++ while @check((temp = @temporary name, index))
+        @add temp, 'var', yes if reserve
+        temp
+
+Ensure that an assignment is made at the top of this scope
+(or at the top-level scope, if requested).
+
+      assign: (name, value) ->
+        @add name, {value, assigned: yes}, yes
+        @hasAssignments = yes
+
+Does this scope have any declared variables?
+
+      hasDeclarations: ->
+        !!@declaredVariables().length
+
+Return the list of variables first declared in this scope.
+
+      declaredVariables: ->
+        realVars = []
+        tempVars = []
+        for v in @variables when v.type is 'var'
+          (if v.name.charAt(0) is '_' then tempVars else realVars).push v.name
+        realVars.sort().concat tempVars.sort()
+
+Return the list of assignments that are supposed to be made at the top
+of this scope.
+
+      assignedVariables: ->
+        "#{v.name} = #{v.type.value}" for v in @variables when v.type.assigned
diff --git a/app/server/vendor/rouge/spec/visual/samples/literate_haskell b/app/server/vendor/rouge/spec/visual/samples/literate_haskell
new file mode 100755
index 0000000..2f9bbbe
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/literate_haskell
@@ -0,0 +1,11 @@
+In Bird-style you have to leave a blank before the code.
+
+> fact :: Integer -> Integer
+> fact 0 = 1
+> fact n = n * fact (n-1)
+ 
+And you have to leave a blank line after the code as well.  Unless
+> 0 lines of blank space are left, this won't be highlighted as code.
+    
+> main = do
+>   putStrLn "Hello World!"
diff --git a/app/server/vendor/rouge/spec/visual/samples/llvm b/app/server/vendor/rouge/spec/visual/samples/llvm
new file mode 100755
index 0000000..004e972
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/llvm
@@ -0,0 +1,73 @@
+; copied from http://llvm.org/docs/LangRef.html#module-structure
+
+; Declare the string constant as a global constant.
+ at .str = private unnamed_addr constant [13 x i8] c"hello world\0A\00"
+
+; External declaration of the puts function
+declare i32 @puts(i8* nocapture) nounwind
+
+; Definition of main function
+define i32 @main() {   ; i32()*
+  ; Convert [13 x i8]* to i8  *...
+  %cast210 = getelementptr [13 x i8]* @.str, i64 0, i64 0
+
+  ; Call puts function to write out the string to stdout.
+  call i32 @puts(i8* %cast210)
+  ret i32 0
+}
+
+; Named metadata
+!1 = metadata !{i32 42}
+!foo = !{!1, null}
+
+
+; copied from http://llvm.org/docs/LangRef.html#poison-values
+
+entry:
+  %poison = sub nuw i32 0, 1           ; Results in a poison value.
+  %still_poison = and i32 %poison, 0   ; 0, but also poison.
+  %poison_yet_again = getelementptr i32* @h, i32 %still_poison
+  store i32 0, i32* %poison_yet_again  ; memory at @h[0] is poisoned
+
+  store i32 %poison, i32* @g           ; Poison value stored to memory.
+  %poison2 = load i32* @g              ; Poison value loaded back from memory.
+
+  store volatile i32 %poison, i32* @g  ; External observation; undefined behavior.
+
+  %narrowaddr = bitcast i32* @g to i16*
+  %wideaddr = bitcast i32* @g to i64*
+  %poison3 = load i16* %narrowaddr     ; Returns a poison value.
+  %poison4 = load i64* %wideaddr       ; Returns a poison value.
+
+  %cmp = icmp slt i32 %poison, 0       ; Returns a poison value.
+  br i1 %cmp, label %true, label %end  ; Branch to either destination.
+
+true:
+  store volatile i32 0, i32* @g        ; This is control-dependent on %cmp, so
+                                       ; it has undefined behavior.
+  br label %end
+
+end:
+  %p = phi i32 [ 0, %entry ], [ 1, %true ]
+                                       ; Both edges into this PHI are
+                                       ; control-dependent on %cmp, so this
+                                       ; always results in a poison value.
+
+  store volatile i32 0, i32* @g        ; This would depend on the store in %true
+                                       ; if %cmp is true, or the store in %entry
+                                       ; otherwise, so this is undefined behavior.
+
+  br i1 %cmp, label %second_true, label %second_end
+                                       ; The same branch again, but this time the
+                                       ; true block doesn't have side effects.
+
+second_true:
+  ; No side effects!
+  ret void
+
+second_end:
+  store volatile i32 0, i32* @g        ; This time, the instruction always depends
+                                       ; on the store in %end. Also, it is
+                                       ; control-equivalent to %end, so this is
+                                       ; well-defined (ignoring earlier undefined
+                                       ; behavior in this example).
diff --git a/app/server/vendor/rouge/spec/visual/samples/lua b/app/server/vendor/rouge/spec/visual/samples/lua
new file mode 100755
index 0000000..23dfbaa
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/lua
@@ -0,0 +1,260 @@
+#!/usr/local/bin/lua
+
+--[[ Example code by Steve Donovan from luanova.org ]]
+
+-- basic1.lua
+require"orbit"
+
+-- declaration
+module("basic1", package.seeall, orbit.new)
+
+-- handler
+function index(web)
+  return render_index()
+end
+
+snowman('☃')
+
+-- dispatch
+basic1:dispatch_get(index, "/", "/index")
+
+-- render
+function render_index()
+   return [[
+    <head></head>
+    <html>
+    <h2>Pretty Easy!</h2>
+    </html>
+    ]]
+end
+
+-- basic3.lua
+require"orbit"
+
+module("basic3", package.seeall, orbit.new)
+
+basic3:dispatch_get(function(web)
+    local ls = {}
+    for k,v in pairs(web.GET) do
+        table.insert(ls,('<li>%s = %s</li>'):format(k,v))
+    end
+    ls = '<ul>'..table.concat(ls,'\n')..'</ul>'
+    return ([[
+    <html><head></head><body>
+    Web Variables <br/>
+    %s
+    </body></html>
+    ]]):format(ls)
+end, "/", "/index")
+
+-- basic2.lua
+require"orbit"
+
+module("basic2", package.seeall, orbit.new)
+
+function index(web)
+  return render_index(collectgarbage("count"))
+end
+
+basic2:dispatch_get(index, "/", "/index")
+-- any file in this directory will be served statically
+basic2:dispatch_static ("/images/.+")
+
+local template = [[
+<head></head>
+<html>
+%s
+</html>
+]]
+
+function render_page(contents)
+    return template:format(contents)
+end
+
+function render_index(mem)
+   return ([[
+    <img src="/images/lua.png"/>
+    <h2>Memory used by Lua is %6.0f kB<h2>
+   ]]):format(mem)
+end
+
+-- html1.lua
+require"orbit"
+
+function generate()
+    return html {
+        head{title "HTML Example"},
+        body{
+            h2{"Here we go again!"}
+        }
+    }
+end
+
+orbit.htmlify(generate)
+
+print(generate())
+
+function generate()
+    return sensors {
+        sensor {name="one"},
+        sensor {name="two"},
+    }
+end
+
+function generate (web)
+    local list = {}
+    for name,value in pairs(web.GET) do
+        table.insert(list,li(name.." = "..value))
+    end
+    return ul(list)
+end
+
+require"orbit"
+
+function wrap (inner)
+    return html{ head(), body(inner) }
+end
+
+function test ()
+    return wrap(form (H'table' {
+        tr{td"First name",td( input{type='text', name='first'})},
+        tr{td"Second name",td(input{type='text', name='second'})},
+        tr{ td(input{type='submit', value='Submit!'}),
+            td(input{type='submit',value='Cancel'})
+        },
+    }))
+end
+
+
+orbit.htmlify(wrap,test)
+
+print(test())
+
+function show_form (web)
+    return wrap(form {
+        htable {
+            {text("First name",'first')},
+            {text("Second name",'second')},
+            {submit 'Submit', submit 'Cancel'},
+        }
+    })
+end
+
+-- ORM1.lua
+require "orbit"
+require "luasql.sqlite3"
+local env = luasql.sqlite3()
+
+function dump (t)
+    if #t > 0 then
+        for _,row in ipairs(t) do
+            dump(row)
+        end
+    else
+        for field,value in pairs(t) do
+            if type(value) == 'string' then
+                value = value:sub(1,60)
+            end
+            print(field,type(value),value)
+        end
+        print '-----'
+    end
+end
+
+mapper = orbit.model.new()
+mapper.conn = env:connect("../blog/blog.db")
+mapper.driver = "sqlite3"
+mapper.table_prefix = 'blog_'
+
+posts = mapper:new 'post'  -- maps to blog_post table
+
+-- print out the second post
+second = posts:find(2)
+
+dump(second)
+
+dump(posts:find_all("id = ? or id = ?",
+    {2,4,order = "published_at asc"}))
+
+orbit.htmlify(blog1,'render_.+')
+
+function index(web)
+  return render_index(posts:find_all())
+end
+
+blog1:dispatch_get(index, "/", "/index")
+
+local function limit (s,maxlen)
+    if #s > maxlen then
+        return s:sub(1,maxlen)..'...'
+    else
+        return s
+    end
+end
+
+function render_page(contents)
+    return html {
+        head { title 'Blog Example' },
+        body (contents)
+    }
+end
+
+function render_post(post)
+    return div {
+        h3 (post.id .. ' ' .. post.title),
+        p (limit(post.body,128)),
+        em(os.date('%a %b %d %H:%M %Y',post.published_at)),
+        ' ',post.n_comments,' comments'
+    }
+end
+
+function render_index(posts)
+    local res = {}
+    for i,post in ipairs(posts) do
+        res[i] = render_post(post)
+    end
+    return render_page(res)
+end
+
+function index(web)
+  local keyword = web.GET.keyword or ''
+  if keyword == '' then return {}
+  else
+    return render_index(posts:find_all('title like ?',{'%'..keyword..'%'}))
+  end
+end
+
+function render_index(posts)
+    local res = {}
+    append(res,p (form {
+        input {type='text',name='keyword'},
+        input {type='submit',value='Submit'},
+    }))
+    append(res,hr())
+    append(res,h2(('Found %d posts'):format(#posts)))
+    for _,post in ipairs(posts) do
+        append(res,render_post(post))
+    end
+    return render_page(res)
+end
+
+
+--[[ Example code from http://lua-users.org/wiki/SimpleLuaClasses ]]
+Account = {}
+Account.__index = Account
+
+function Account.create(balance)
+   local acnt = {}             -- our new object
+   setmetatable(acnt,Account)  -- make Account handle lookup
+   acnt.balance = balance      -- initialize our object
+   return acnt
+end
+
+function Account:withdraw(amount)
+   self.balance = self.balance - amount
+end
+
+-- create and use an Account
+acc = Account.create(1000)
+acc:withdraw(100)
+
diff --git a/app/server/vendor/rouge/spec/visual/samples/make b/app/server/vendor/rouge/spec/visual/samples/make
new file mode 100755
index 0000000..e2a7681
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/make
@@ -0,0 +1,1133 @@
+VERSION := 0.1.$(shell git log --oneline | wc -l | sed -e "s/ //g")
+
+# Generated automatically from Makefile.pre by makesetup.
+# Top-level Makefile for Python
+#
+# As distributed, this file is called Makefile.pre.in; it is processed
+# into the real Makefile by running the script ./configure, which
+# replaces things like @spam@ with values appropriate for your system.
+# This means that if you edit Makefile, your changes get lost the next
+# time you run the configure script.  Ideally, you can do:
+#
+#	./configure
+#	make
+#	make test
+#	make install
+#
+# If you have a previous version of Python installed that you don't
+# want to overwrite, you can use "make altinstall" instead of "make
+# install".  Refer to the "Installing" section in the README file for
+# additional details.
+#
+# See also the section "Build instructions" in the README file.
+
+# === Variables set by makesetup ===
+
+MODOBJS=          Modules/threadmodule.o  Modules/signalmodule.o  Modules/posixmodule.o  Modules/errnomodule.o  Modules/pwdmodule.o  Modules/_sre.o  Modules/_codecsmodule.o  Modules/zipimport.o  Modules/symtablemodule.o  Modules/xxsubtype.o
+MODLIBS=        $(LOCALMODLIBS) $(BASEMODLIBS)
+
+# === Variables set by configure
+VERSION=	2.6
+srcdir=		.
+
+
+CC=		gcc -pthread
+CXX=		g++ -pthread
+MAINCC=		$(CC)
+LINKCC=		$(PURIFY) $(MAINCC)
+AR=		ar
+RANLIB=		ranlib
+SVNVERSION=	svnversion $(srcdir)
+
+# Shell used by make (some versions default to the login shell, which is bad)
+SHELL=		/bin/sh
+
+# Use this to make a link between python$(VERSION) and python in $(BINDIR)
+LN=		ln
+
+# Portable install script (configure doesn't always guess right)
+INSTALL=	/usr/bin/install -c
+INSTALL_PROGRAM=${INSTALL}
+INSTALL_SCRIPT= ${INSTALL}
+INSTALL_DATA=	${INSTALL} -m 644
+# Shared libraries must be installed with executable mode on some systems;
+# rather than figuring out exactly which, we always give them executable mode.
+# Also, making them read-only seems to be a good idea...
+INSTALL_SHARED= ${INSTALL} -m 555
+
+MAKESETUP=      $(srcdir)/Modules/makesetup
+
+# Compiler options
+OPT=		-g -Wall -Wstrict-prototypes
+BASECFLAGS=	 -fno-strict-aliasing
+CFLAGS=		$(BASECFLAGS) $(OPT) $(EXTRA_CFLAGS)
+# Both CPPFLAGS and LDFLAGS need to contain the shell's value for setup.py to
+# be able to build extension modules using the directories specified in the
+# environment variables
+CPPFLAGS=	-I. -I$(srcdir)/Include 
+LDFLAGS=	
+LDLAST=		
+SGI_ABI=	
+CCSHARED=	-fPIC
+LINKFORSHARED=	-Xlinker -export-dynamic
+# Extra C flags added for building the interpreter object files.
+CFLAGSFORSHARED=
+# C flags used for building the interpreter object files
+PY_CFLAGS=	$(CFLAGS) $(CPPFLAGS) $(CFLAGSFORSHARED) -DPy_BUILD_CORE
+
+
+# Machine-dependent subdirectories
+MACHDEP=	linux2
+
+# Install prefix for architecture-independent files
+prefix=		/usr/local
+
+# Install prefix for architecture-dependent files
+exec_prefix=	${prefix}
+
+# Expanded directories
+BINDIR=		$(exec_prefix)/bin
+LIBDIR=		$(exec_prefix)/lib
+MANDIR=		${prefix}/man
+INCLUDEDIR=	${prefix}/include
+CONFINCLUDEDIR=	$(exec_prefix)/include
+SCRIPTDIR=	$(prefix)/lib
+
+# Detailed destination directories
+BINLIBDEST=	$(LIBDIR)/python$(VERSION)
+LIBDEST=	$(SCRIPTDIR)/python$(VERSION)
+INCLUDEPY=	$(INCLUDEDIR)/python$(VERSION)
+CONFINCLUDEPY=	$(CONFINCLUDEDIR)/python$(VERSION)
+LIBP=		$(LIBDIR)/python$(VERSION)
+
+# Symbols used for using shared libraries
+SO=		.so
+LDSHARED=	$(CC) -shared
+BLDSHARED=	$(CC) -shared
+DESTSHARED=	$(BINLIBDEST)/lib-dynload
+
+# Executable suffix (.exe on Windows and Mac OS X)
+EXE=		
+BUILDEXE=	
+
+# Short name and location for Mac OS X Python framework
+UNIVERSALSDK=
+PYTHONFRAMEWORK=	
+PYTHONFRAMEWORKDIR=	no-framework
+PYTHONFRAMEWORKPREFIX=	
+PYTHONFRAMEWORKINSTALLDIR= 
+# Deployment target selected during configure, to be checked
+# by distutils. The export statement is needed to ensure that the
+# deployment target is active during build.
+MACOSX_DEPLOYMENT_TARGET=
+#export MACOSX_DEPLOYMENT_TARGET
+
+# Options to enable prebinding (for fast startup prior to Mac OS X 10.3)
+OTHER_LIBTOOL_OPT=
+
+# Environment to run shared python without installed libraries
+RUNSHARED=       
+
+# Modes for directories, executables and data files created by the
+# install process.  Default to user-only-writable for all file types.
+DIRMODE=	755
+EXEMODE=	755
+FILEMODE=	644
+
+# configure script arguments
+CONFIG_ARGS=	'--with-pydebug'
+
+
+# Subdirectories with code
+SRCDIRS= 	Parser Grammar Objects Python Modules Mac
+
+# Other subdirectories
+SUBDIRSTOO=	Include Lib Misc Demo
+
+# Files and directories to be distributed
+CONFIGFILES=	configure configure.in acconfig.h pyconfig.h.in Makefile.pre.in
+DISTFILES=	README ChangeLog $(CONFIGFILES)
+DISTDIRS=	$(SUBDIRS) $(SUBDIRSTOO) Ext-dummy
+DIST=		$(DISTFILES) $(DISTDIRS)
+
+
+LIBRARY=	libpython$(VERSION).a
+LDLIBRARY=      libpython$(VERSION).a
+BLDLIBRARY=     $(LDLIBRARY)
+DLLLIBRARY=	
+LDLIBRARYDIR=   
+INSTSONAME=	$(LDLIBRARY)
+
+
+LIBS=		-lpthread -ldl  -lutil
+LIBM=		-lm
+LIBC=		
+SYSLIBS=	$(LIBM) $(LIBC)
+SHLIBS=		$(LIBS)
+
+THREADOBJ=	Python/thread.o
+DLINCLDIR=	.
+DYNLOADFILE=	dynload_shlib.o
+MACHDEP_OBJS=	
+UNICODE_OBJS=   Objects/unicodeobject.o Objects/unicodectype.o
+
+PYTHON=		python$(EXE)
+BUILDPYTHON=	python$(BUILDEXE)
+
+# === Definitions added by makesetup ===
+
+LOCALMODLIBS=          
+BASEMODLIBS=
+GLHACK=-Dclear=__GLclear
+PYTHONPATH=$(COREPYTHONPATH)
+COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(EXTRAMACHDEPPATH)$(TKPATH)
+TKPATH=:lib-tk
+EXTRAMACHDEPPATH=
+MACHDEPPATH=:plat-$(MACHDEP)
+TESTPATH=
+SITEPATH=
+DESTPATH=
+MACHDESTLIB=$(BINLIBDEST)
+DESTLIB=$(LIBDEST)
+
+
+
+##########################################################################
+# Modules
+MODULE_OBJS=	\
+		Modules/config.o \
+		Modules/getpath.o \
+		Modules/main.o \
+		Modules/gcmodule.o
+
+# Used of signalmodule.o is not available
+SIGNAL_OBJS=	
+
+
+##########################################################################
+# Grammar
+GRAMMAR_H=	$(srcdir)/Include/graminit.h
+GRAMMAR_C=	$(srcdir)/Python/graminit.c
+GRAMMAR_INPUT=	$(srcdir)/Grammar/Grammar
+
+
+##########################################################################
+# Parser
+PGEN=		Parser/pgen$(EXE)
+
+POBJS=		\
+		Parser/acceler.o \
+		Parser/grammar1.o \
+		Parser/listnode.o \
+		Parser/node.o \
+		Parser/parser.o \
+		Parser/parsetok.o \
+		Parser/bitset.o \
+		Parser/metagrammar.o \
+		Parser/firstsets.o \
+		Parser/grammar.o \
+		Parser/pgen.o
+
+PARSER_OBJS=	$(POBJS) Parser/myreadline.o Parser/tokenizer.o
+
+PGOBJS=		\
+		Objects/obmalloc.o \
+		Python/mysnprintf.o \
+		Parser/tokenizer_pgen.o \
+		Parser/printgrammar.o \
+		Parser/pgenmain.o
+
+PGENOBJS=	$(PGENMAIN) $(POBJS) $(PGOBJS)
+
+##########################################################################
+# AST
+AST_H_DIR=	$(srcdir)/Include
+AST_H=		$(AST_H_DIR)/Python-ast.h
+AST_C_DIR=	$(srcdir)/Python
+AST_C=		$(AST_C_DIR)/Python-ast.c
+AST_ASDL=	$(srcdir)/Parser/Python.asdl
+
+ASDLGEN_FILES=	$(srcdir)/Parser/asdl.py $(srcdir)/Parser/asdl_c.py
+# XXX Note that a build now requires Python exist before the build starts
+ASDLGEN=	$(srcdir)/Parser/asdl_c.py
+
+##########################################################################
+# Python
+PYTHON_OBJS=	\
+		Python/Python-ast.o \
+		Python/asdl.o \
+		Python/ast.o \
+		Python/bltinmodule.o \
+		Python/ceval.o \
+		Python/compile.o \
+		Python/codecs.o \
+		Python/errors.o \
+		Python/frozen.o \
+		Python/frozenmain.o \
+		Python/future.o \
+		Python/getargs.o \
+		Python/getcompiler.o \
+		Python/getcopyright.o \
+		Python/getmtime.o \
+		Python/getplatform.o \
+		Python/getversion.o \
+		Python/graminit.o \
+		Python/import.o \
+		Python/importdl.o \
+		Python/marshal.o \
+		Python/modsupport.o \
+		Python/mystrtoul.o \
+		Python/mysnprintf.o \
+		Python/peephole.o \
+		Python/pyarena.o \
+		Python/pyfpe.o \
+		Python/pystate.o \
+		Python/pythonrun.o \
+		Python/structmember.o \
+		Python/symtable.o \
+		Python/sysmodule.o \
+		Python/traceback.o \
+		Python/getopt.o \
+		Python/pystrtod.o \
+		Python/$(DYNLOADFILE) \
+		$(MACHDEP_OBJS) \
+		$(THREADOBJ)
+
+
+##########################################################################
+# Objects
+OBJECT_OBJS=	\
+		Objects/abstract.o \
+		Objects/boolobject.o \
+		Objects/bufferobject.o \
+		Objects/cellobject.o \
+		Objects/classobject.o \
+		Objects/cobject.o \
+		Objects/codeobject.o \
+		Objects/complexobject.o \
+		Objects/descrobject.o \
+		Objects/enumobject.o \
+		Objects/exceptions.o \
+		Objects/genobject.o \
+		Objects/fileobject.o \
+		Objects/floatobject.o \
+		Objects/frameobject.o \
+		Objects/funcobject.o \
+		Objects/intobject.o \
+		Objects/iterobject.o \
+		Objects/listobject.o \
+		Objects/longobject.o \
+		Objects/dictobject.o \
+		Objects/methodobject.o \
+		Objects/moduleobject.o \
+		Objects/object.o \
+		Objects/obmalloc.o \
+		Objects/rangeobject.o \
+                Objects/setobject.o \
+		Objects/sliceobject.o \
+		Objects/stringobject.o \
+		Objects/structseq.o \
+		Objects/tupleobject.o \
+		Objects/typeobject.o \
+		Objects/weakrefobject.o \
+		$(UNICODE_OBJS)
+
+
+##########################################################################
+# objects that get linked into the Python library
+LIBRARY_OBJS=	\
+		Modules/_typesmodule.o \
+		Modules/getbuildinfo.o \
+		$(PARSER_OBJS) \
+		$(OBJECT_OBJS) \
+		$(PYTHON_OBJS) \
+		$(MODULE_OBJS) \
+		$(SIGNAL_OBJS) \
+		$(MODOBJS)
+
+#########################################################################
+# Rules
+
+# Default target
+all:		$(BUILDPYTHON) oldsharedmods sharedmods
+
+# Build the interpreter
+$(BUILDPYTHON):	Modules/python.o $(LIBRARY) $(LDLIBRARY)
+		$(LINKCC) $(LDFLAGS) $(LINKFORSHARED) -o $@ \
+			Modules/python.o \
+			$(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
+
+platform: $(BUILDPYTHON)
+	$(RUNSHARED) ./$(BUILDPYTHON) -E -c 'import sys ; from distutils.util import get_platform ; print get_platform()+"-"+sys.version[0:3]' >platform
+
+
+# Build the shared modules
+sharedmods: $(BUILDPYTHON)
+	@case $$MAKEFLAGS in \
+	*-s*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py -q build;; \
+	*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py build;; \
+	esac
+
+# Build static library
+# avoid long command lines, same as LIBRARY_OBJS
+$(LIBRARY): $(LIBRARY_OBJS)
+	-rm -f $@
+	$(AR) cr $@ Modules/getbuildinfo.o
+	$(AR) cr $@ Modules/_typesmodule.o
+	$(AR) cr $@ $(PARSER_OBJS)
+	$(AR) cr $@ $(OBJECT_OBJS)
+	$(AR) cr $@ $(PYTHON_OBJS)
+	$(AR) cr $@ $(MODULE_OBJS) $(SIGNAL_OBJS)
+	$(AR) cr $@ $(MODOBJS)
+	$(RANLIB) $@
+
+libpython$(VERSION).so: $(LIBRARY_OBJS)
+	if test $(INSTSONAME) != $(LDLIBRARY); then \
+		$(LDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \
+		$(LN) -f $(INSTSONAME) $@; \
+	else\
+		$(LDSHARED) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \
+	fi
+
+libpython$(VERSION).sl: $(LIBRARY_OBJS)
+	$(LDSHARED) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM)
+
+# This rule is here for OPENSTEP/Rhapsody/MacOSX. It builds a temporary
+# minimal framework (not including the Lib directory and such) in the current
+# directory.
+RESSRCDIR=$(srcdir)/Mac/Resources/framework
+$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \
+		$(LIBRARY) \
+		$(RESSRCDIR)/Info.plist \
+                $(RESSRCDIR)/version.plist \
+                $(RESSRCDIR)/English.lproj/InfoPlist.strings
+	$(INSTALL) -d -m $(DIRMODE) $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)
+	if test "${UNIVERSALSDK}"; then \
+		$(CC) -o $(LDLIBRARY) -arch i386 -arch ppc -dynamiclib \
+			-isysroot "${UNIVERSALSDK}" \
+			-all_load $(LIBRARY) -Wl,-single_module \
+			-install_name $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/Python \
+			-compatibility_version $(VERSION) \
+			-current_version $(VERSION); \
+        else \
+		libtool -o $(LDLIBRARY) -dynamic $(OTHER_LIBTOOL_OPT) $(LIBRARY) \
+			 ;\
+	fi
+	$(INSTALL) -d -m $(DIRMODE)  \
+		$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/English.lproj
+	$(INSTALL_DATA) $(RESSRCDIR)/Info.plist \
+		$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/Info.plist
+	$(INSTALL_DATA) $(RESSRCDIR)/version.plist \
+		$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/version.plist
+	$(INSTALL_DATA) $(RESSRCDIR)/English.lproj/InfoPlist.strings \
+		$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/English.lproj/InfoPlist.strings
+	$(LN) -fsn $(VERSION) $(PYTHONFRAMEWORKDIR)/Versions/Current
+	$(LN) -fsn Versions/Current/$(PYTHONFRAMEWORK) $(PYTHONFRAMEWORKDIR)/$(PYTHONFRAMEWORK)
+	$(LN) -fsn Versions/Current/Headers $(PYTHONFRAMEWORKDIR)/Headers
+	$(LN) -fsn Versions/Current/Resources $(PYTHONFRAMEWORKDIR)/Resources
+
+# This rule builds the Cygwin Python DLL and import library if configured
+# for a shared core library; otherwise, this rule is a noop.
+$(DLLLIBRARY) libpython$(VERSION).dll.a: $(LIBRARY_OBJS)
+	if test -n "$(DLLLIBRARY)"; then \
+		$(LDSHARED) -Wl,--out-implib=$@ -o $(DLLLIBRARY) $^ \
+			$(LIBS) $(MODLIBS) $(SYSLIBS); \
+	else true; \
+	fi
+
+
+oldsharedmods: $(SHAREDMODS)
+
+
+Makefile Modules/config.c: Makefile.pre \
+				$(srcdir)/Modules/config.c.in \
+				$(MAKESETUP) \
+				Modules/Setup.config \
+				Modules/Setup \
+				Modules/Setup.local
+	$(SHELL) $(MAKESETUP) -c $(srcdir)/Modules/config.c.in \
+				-s Modules \
+				Modules/Setup.config \
+				Modules/Setup.local \
+				Modules/Setup
+	@mv config.c Modules
+	@echo "The Makefile was updated, you may need to re-run make."
+
+
+Modules/Setup: $(srcdir)/Modules/Setup.dist
+	@if test -f Modules/Setup; then \
+		echo "-----------------------------------------------"; \
+		echo "Modules/Setup.dist is newer than Modules/Setup;"; \
+		echo "check to make sure you have all the updates you"; \
+		echo "need in your Modules/Setup file."; \
+		echo "Usually, copying Setup.dist to Setup will work."; \
+		echo "-----------------------------------------------"; \
+	fi
+
+############################################################################
+# Special rules for object files
+
+Modules/getbuildinfo.o: $(PARSER_OBJS) \
+		$(OBJECT_OBJS) \
+		$(PYTHON_OBJS) \
+		$(MODULE_OBJS) \
+		$(SIGNAL_OBJS) \
+		$(MODOBJS) \
+		$(srcdir)/Modules/getbuildinfo.c
+	$(CC) -c $(PY_CFLAGS) -DSVNVERSION=\"`LC_ALL=C $(SVNVERSION)`\" -o $@ $(srcdir)/Modules/getbuildinfo.c
+
+Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile
+	$(CC) -c $(PY_CFLAGS) -DPYTHONPATH='"$(PYTHONPATH)"' \
+		-DPREFIX='"$(prefix)"' \
+		-DEXEC_PREFIX='"$(exec_prefix)"' \
+		-DVERSION='"$(VERSION)"' \
+		-DVPATH='"$(VPATH)"' \
+		-o $@ $(srcdir)/Modules/getpath.c
+
+Modules/python.o: $(srcdir)/Modules/python.c
+	$(MAINCC) -c $(PY_CFLAGS) -o $@ $(srcdir)/Modules/python.c
+
+
+$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
+		-$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
+
+$(PGEN):	$(PGENOBJS)
+		$(CC) $(OPT) $(LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN)
+
+Parser/grammar.o:	$(srcdir)/Parser/grammar.c \
+				$(srcdir)/Include/token.h \
+				$(srcdir)/Include/grammar.h
+Parser/metagrammar.o:	$(srcdir)/Parser/metagrammar.c
+
+Parser/tokenizer_pgen.o:	$(srcdir)/Parser/tokenizer.c
+
+Parser/pgenmain.o:	$(srcdir)/Include/parsetok.h
+
+$(AST_H): $(AST_ASDL) $(ASDLGEN_FILES)
+	$(ASDLGEN) -h $(AST_H_DIR) $(AST_ASDL)
+
+$(AST_C): $(AST_ASDL) $(ASDLGEN_FILES)
+	$(ASDLGEN) -c $(AST_C_DIR) $(AST_ASDL)
+
+Python/compile.o Python/symtable.o: $(GRAMMAR_H) $(AST_H)
+
+Python/getplatform.o: $(srcdir)/Python/getplatform.c
+		$(CC) -c $(PY_CFLAGS) -DPLATFORM='"$(MACHDEP)"' -o $@ $(srcdir)/Python/getplatform.c
+
+Python/importdl.o: $(srcdir)/Python/importdl.c
+		$(CC) -c $(PY_CFLAGS) -I$(DLINCLDIR) -o $@ $(srcdir)/Python/importdl.c
+
+Objects/unicodectype.o:	$(srcdir)/Objects/unicodectype.c \
+				$(srcdir)/Objects/unicodetype_db.h
+
+############################################################################
+# Header files
+
+PYTHON_HEADERS= \
+		Include/Python.h \
+		Include/Python-ast.h \
+		Include/asdl.h \
+		Include/abstract.h \
+		Include/boolobject.h \
+		Include/bufferobject.h \
+		Include/ceval.h \
+		Include/classobject.h \
+		Include/cobject.h \
+		Include/code.h \
+		Include/codecs.h \
+		Include/compile.h \
+		Include/complexobject.h \
+		Include/descrobject.h \
+		Include/dictobject.h \
+		Include/enumobject.h \
+		Include/genobject.h \
+		Include/fileobject.h \
+		Include/floatobject.h \
+		Include/funcobject.h \
+		Include/import.h \
+		Include/intobject.h \
+		Include/intrcheck.h \
+		Include/iterobject.h \
+		Include/listobject.h \
+		Include/longobject.h \
+		Include/methodobject.h \
+		Include/modsupport.h \
+		Include/moduleobject.h \
+		Include/object.h \
+		Include/objimpl.h \
+		Include/parsetok.h \
+		Include/patchlevel.h \
+		Include/pyarena.h \
+		Include/pydebug.h \
+		Include/pyerrors.h \
+		Include/pyfpe.h \
+		Include/pymem.h \
+		Include/pyport.h \
+		Include/pystate.h \
+		Include/pythonrun.h \
+		Include/rangeobject.h \
+                Include/setobject.h \
+		Include/sliceobject.h \
+		Include/stringobject.h \
+		Include/structseq.h \
+		Include/structmember.h \
+		Include/symtable.h \
+		Include/sysmodule.h \
+		Include/traceback.h \
+		Include/tupleobject.h \
+		Include/unicodeobject.h \
+		Include/weakrefobject.h \
+		pyconfig.h
+
+$(LIBRARY_OBJS) $(MODOBJS) Modules/python.o: $(PYTHON_HEADERS)
+
+
+######################################################################
+
+# Test the interpreter (twice, once without .pyc files, once with)
+# In the past, we've had problems where bugs in the marshalling or
+# elsewhere caused bytecode read from .pyc files to behave differently
+# than bytecode generated directly from a .py source file.  Sometimes
+# the bytecode read from a .pyc file had the bug, somtimes the directly
+# generated bytecode.  This is sometimes a very shy bug needing a lot of
+# sample data.
+
+TESTOPTS=	-l $(EXTRATESTOPTS)
+TESTPROG=	$(srcdir)/Lib/test/regrtest.py
+TESTPYTHON=	$(RUNSHARED) ./$(BUILDPYTHON) -E -tt
+test:		all platform
+		-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
+		-$(TESTPYTHON) $(TESTPROG) $(TESTOPTS)
+		$(TESTPYTHON) $(TESTPROG) $(TESTOPTS)
+
+testall:	all platform
+		-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
+		-$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
+		$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
+
+#  Run the unitests for both architectures in a Universal build on OSX
+#  Must be run on an Intel box.
+testuniversal:	all platform
+		if [ `arch` != 'i386' ];then \
+			echo "This can only be used on OSX/i386" ;\
+			exit 1 ;\
+		fi
+		-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
+		-$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
+		$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
+		$(RUNSHARED) /usr/libexec/oah/translate ./$(BUILDPYTHON) -E -tt $(TESTPROG) $(TESTOPTS) -uall
+
+
+# Like testall, but with a single pass only
+buildbottest:	all platform
+		$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall -rw
+
+QUICKTESTOPTS=	$(TESTOPTS) -x test_thread test_signal test_strftime \
+		test_unicodedata test_re test_sre test_select test_poll \
+		test_linuxaudiodev test_struct test_sunaudiodev test_zlib
+quicktest:	all platform
+		-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
+		-$(TESTPYTHON) $(TESTPROG) $(QUICKTESTOPTS)
+		$(TESTPYTHON) $(TESTPROG) $(QUICKTESTOPTS)
+
+MEMTESTOPTS=    $(QUICKTESTOPTS) -x test_dl test___all__ test_fork1 \
+		test_longexp
+memtest:	all platform
+		-rm -f $(srcdir)/Lib/test/*.py[co]
+		-$(TESTPYTHON) $(TESTPROG) $(MEMTESTOPTS)
+		$(TESTPYTHON) $(TESTPROG) $(MEMTESTOPTS)
+
+# Install everything
+install:	 altinstall bininstall maninstall 
+
+# Install almost everything without disturbing previous versions
+altinstall:	 altbininstall libinstall inclinstall libainstall \
+                sharedinstall oldsharedinstall 
+
+# Install shared libraries enabled by Setup
+DESTDIRS=	$(exec_prefix) $(LIBDIR) $(BINLIBDEST) $(DESTSHARED)
+
+oldsharedinstall: $(DESTSHARED) $(SHAREDMODS)
+		@for i in X $(SHAREDMODS); do \
+		  if test $$i != X; then \
+		    echo $(INSTALL_SHARED) $$i $(DESTSHARED)/`basename $$i`; \
+		    $(INSTALL_SHARED) $$i $(DESTDIR)$(DESTSHARED)/`basename $$i`; \
+		  fi; \
+		done
+
+$(DESTSHARED):
+		@for i in $(DESTDIRS); \
+		do \
+			if test ! -d $(DESTDIR)$$i; then \
+				echo "Creating directory $$i"; \
+				$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
+			else    true; \
+			fi; \
+		done
+
+
+# Install the interpreter (by creating a hard link to python$(VERSION))
+bininstall:	altbininstall
+	-if test -f $(DESTDIR)$(BINDIR)/$(PYTHON) -o -h $(DESTDIR)$(BINDIR)/$(PYTHON); \
+	then rm -f $(DESTDIR)$(BINDIR)/$(PYTHON); \
+	else true; \
+	fi
+	(cd $(DESTDIR)$(BINDIR); $(LN) python$(VERSION)$(EXE) $(PYTHON))
+	(cd $(DESTDIR)$(BINDIR); $(LN) -sf python$(VERSION)-config python-config)
+
+# Install the interpreter with $(VERSION) affixed
+# This goes into $(exec_prefix)
+altbininstall:	$(BUILDPYTHON)
+	@for i in $(BINDIR) $(LIBDIR); \
+	do \
+		if test ! -d $(DESTDIR)$$i; then \
+			echo "Creating directory $$i"; \
+			$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
+		else	true; \
+		fi; \
+	done
+	$(INSTALL_PROGRAM) $(BUILDPYTHON) $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE)
+	if test -f libpython$(VERSION)$(SO); then \
+		if test "$(SO)" = .dll; then \
+			$(INSTALL_SHARED) libpython$(VERSION)$(SO) $(DESTDIR)$(BINDIR); \
+		else \
+			$(INSTALL_SHARED) libpython$(VERSION)$(SO) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \
+			if test libpython$(VERSION)$(SO) != $(INSTSONAME); then \
+				(cd $(DESTDIR)$(LIBDIR); $(LN) -sf $(INSTSONAME) libpython$(VERSION)$(SO)); \
+			fi \
+		fi; \
+	else	true; \
+	fi
+
+# Install the manual page
+maninstall:
+	@for i in $(MANDIR) $(MANDIR)/man1; \
+	do \
+		if test ! -d $(DESTDIR)$$i; then \
+			echo "Creating directory $$i"; \
+			$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
+		else	true; \
+		fi; \
+	done
+	$(INSTALL_DATA) $(srcdir)/Misc/python.man \
+		$(DESTDIR)$(MANDIR)/man1/python.1
+
+# Install the library
+PLATDIR=	plat-$(MACHDEP)
+EXTRAPLATDIR= 
+EXTRAMACHDEPPATH=
+MACHDEPS=	$(PLATDIR) $(EXTRAPLATDIR)
+XMLLIBSUBDIRS=  xml xml/dom xml/etree xml/parsers xml/sax
+PLATMACDIRS= plat-mac plat-mac/Carbon plat-mac/lib-scriptpackages \
+	plat-mac/lib-scriptpackages/_builtinSuites \
+	plat-mac/lib-scriptpackages/CodeWarrior \
+	plat-mac/lib-scriptpackages/Explorer \
+	plat-mac/lib-scriptpackages/Finder \
+	plat-mac/lib-scriptpackages/Netscape \
+	plat-mac/lib-scriptpackages/StdSuites \
+	plat-mac/lib-scriptpackages/SystemEvents \
+	plat-mac/lib-scriptpackages/Terminal 
+PLATMACPATH=:plat-mac:plat-mac/lib-scriptpackages
+LIBSUBDIRS=	lib-tk site-packages test test/output test/data \
+		test/decimaltestdata \
+		encodings compiler hotshot \
+		email email/mime email/test email/test/data \
+		sqlite3 sqlite3/test \
+		logging bsddb bsddb/test csv wsgiref \
+		ctypes ctypes/test ctypes/macholib idlelib idlelib/Icons \
+		distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \
+		setuptools setuptools/command setuptools/tests setuptools.egg-info \
+		curses $(MACHDEPS)
+libinstall:	$(BUILDPYTHON) $(srcdir)/Lib/$(PLATDIR)
+	@for i in $(SCRIPTDIR) $(LIBDEST); \
+	do \
+		if test ! -d $(DESTDIR)$$i; then \
+			echo "Creating directory $$i"; \
+			$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
+		else	true; \
+		fi; \
+	done
+	@for d in $(LIBSUBDIRS); \
+	do \
+		a=$(srcdir)/Lib/$$d; \
+		if test ! -d $$a; then continue; else true; fi; \
+		b=$(LIBDEST)/$$d; \
+		if test ! -d $(DESTDIR)$$b; then \
+			echo "Creating directory $$b"; \
+			$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$b; \
+		else	true; \
+		fi; \
+	done
+	@for i in $(srcdir)/Lib/*.py $(srcdir)/Lib/*.doc $(srcdir)/Lib/*.egg-info ; \
+	do \
+		if test -x $$i; then \
+			$(INSTALL_SCRIPT) $$i $(DESTDIR)$(LIBDEST); \
+			echo $(INSTALL_SCRIPT) $$i $(LIBDEST); \
+		else \
+			$(INSTALL_DATA) $$i $(DESTDIR)$(LIBDEST); \
+			echo $(INSTALL_DATA) $$i $(LIBDEST); \
+		fi; \
+	done
+	@for d in $(LIBSUBDIRS); \
+	do \
+		a=$(srcdir)/Lib/$$d; \
+		if test ! -d $$a; then continue; else true; fi; \
+		if test `ls $$a | wc -l` -lt 1; then continue; fi; \
+		b=$(LIBDEST)/$$d; \
+		for i in $$a/*; \
+		do \
+			case $$i in \
+			*CVS) ;; \
+			*.py[co]) ;; \
+			*.orig) ;; \
+			*~) ;; \
+			*) \
+				if test -d $$i; then continue; fi; \
+				if test -x $$i; then \
+				    echo $(INSTALL_SCRIPT) $$i $$b; \
+				    $(INSTALL_SCRIPT) $$i $(DESTDIR)$$b; \
+				else \
+				    echo $(INSTALL_DATA) $$i $$b; \
+				    $(INSTALL_DATA) $$i $(DESTDIR)$$b; \
+				fi;; \
+			esac; \
+		done; \
+	done
+	$(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt
+	PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
+		./$(BUILDPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
+		-d $(LIBDEST) -f \
+		-x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
+	PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+		./$(BUILDPYTHON) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
+		-d $(LIBDEST) -f \
+		-x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
+	-PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
+		./$(BUILDPYTHON) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \
+		-d $(LIBDEST)/site-packages -f \
+		-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
+	-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+		./$(BUILDPYTHON) -Wi -t -O $(DESTDIR)$(LIBDEST)/compileall.py \
+		-d $(LIBDEST)/site-packages -f \
+		-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
+
+# Create the PLATDIR source directory, if one wasn't distributed..
+$(srcdir)/Lib/$(PLATDIR):
+	mkdir $(srcdir)/Lib/$(PLATDIR)
+	cp $(srcdir)/Lib/plat-generic/regen $(srcdir)/Lib/$(PLATDIR)/regen
+	export PATH; PATH="`pwd`:$$PATH"; \
+	export PYTHONPATH; PYTHONPATH="`pwd`/Lib"; \
+	export DYLD_FRAMEWORK_PATH; DYLD_FRAMEWORK_PATH="`pwd`"; \
+	export EXE; EXE="$(BUILDEXE)"; \
+	cd $(srcdir)/Lib/$(PLATDIR); ./regen
+
+# Install the include files
+INCLDIRSTOMAKE=$(INCLUDEDIR) $(CONFINCLUDEDIR) $(INCLUDEPY) $(CONFINCLUDEPY)
+inclinstall:
+	@for i in $(INCLDIRSTOMAKE); \
+	do \
+		if test ! -d $(DESTDIR)$$i; then \
+			echo "Creating directory $$i"; \
+			$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
+		else	true; \
+		fi; \
+	done
+	@for i in $(srcdir)/Include/*.h; \
+	do \
+		echo $(INSTALL_DATA) $$i $(INCLUDEPY); \
+		$(INSTALL_DATA) $$i $(DESTDIR)$(INCLUDEPY); \
+	done
+	$(INSTALL_DATA) pyconfig.h $(DESTDIR)$(CONFINCLUDEPY)/pyconfig.h
+
+# Install the library and miscellaneous stuff needed for extending/embedding
+# This goes into $(exec_prefix)
+LIBPL=		$(LIBP)/config
+libainstall:	all
+	@for i in $(LIBDIR) $(LIBP) $(LIBPL); \
+	do \
+		if test ! -d $(DESTDIR)$$i; then \
+			echo "Creating directory $$i"; \
+			$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
+		else	true; \
+		fi; \
+	done
+	@if test -d $(LIBRARY); then :; else \
+		if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \
+			if test "$(SO)" = .dll; then \
+				$(INSTALL_DATA) $(LDLIBRARY) $(DESTDIR)$(LIBPL) ; \
+			else \
+				$(INSTALL_DATA) $(LIBRARY) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \
+				$(RANLIB) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \
+			fi; \
+		else \
+			echo Skip install of $(LIBRARY) - use make frameworkinstall; \
+		fi; \
+	fi
+	$(INSTALL_DATA) Modules/config.c $(DESTDIR)$(LIBPL)/config.c
+	$(INSTALL_DATA) Modules/python.o $(DESTDIR)$(LIBPL)/python.o
+	$(INSTALL_DATA) $(srcdir)/Modules/config.c.in $(DESTDIR)$(LIBPL)/config.c.in
+	$(INSTALL_DATA) Makefile $(DESTDIR)$(LIBPL)/Makefile
+	$(INSTALL_DATA) Modules/Setup $(DESTDIR)$(LIBPL)/Setup
+	$(INSTALL_DATA) Modules/Setup.local $(DESTDIR)$(LIBPL)/Setup.local
+	$(INSTALL_DATA) Modules/Setup.config $(DESTDIR)$(LIBPL)/Setup.config
+	$(INSTALL_SCRIPT) $(srcdir)/Modules/makesetup $(DESTDIR)$(LIBPL)/makesetup
+	$(INSTALL_SCRIPT) $(srcdir)/install-sh $(DESTDIR)$(LIBPL)/install-sh
+	# Substitution happens here, as the completely-expanded BINDIR
+	# is not available in configure
+	sed -e "s, at EXENAME@,$(BINDIR)/python$(VERSION)$(EXE)," < $(srcdir)/Misc/python-config.in >python-config
+	$(INSTALL_SCRIPT) python-config $(DESTDIR)$(BINDIR)/python$(VERSION)-config
+	rm python-config
+	@if [ -s Modules/python.exp -a \
+		"`echo $(MACHDEP) | sed 's/^\(...\).*/\1/'`" = "aix" ]; then \
+		echo; echo "Installing support files for building shared extension modules on AIX:"; \
+		$(INSTALL_DATA) Modules/python.exp		\
+				$(DESTDIR)$(LIBPL)/python.exp;		\
+		echo; echo "$(LIBPL)/python.exp";		\
+		$(INSTALL_SCRIPT) $(srcdir)/Modules/makexp_aix	\
+				$(DESTDIR)$(LIBPL)/makexp_aix;		\
+		echo "$(LIBPL)/makexp_aix";			\
+		$(INSTALL_SCRIPT) $(srcdir)/Modules/ld_so_aix	\
+				$(DESTDIR)$(LIBPL)/ld_so_aix;		\
+		echo "$(LIBPL)/ld_so_aix";			\
+		echo; echo "See Misc/AIX-NOTES for details.";	\
+	else true; \
+	fi
+	@case "$(MACHDEP)" in beos*) \
+		echo; echo "Installing support files for building shared extension modules on BeOS:"; \
+		$(INSTALL_DATA) Misc/BeOS-NOTES $(DESTDIR)$(LIBPL)/README;	\
+		echo; echo "$(LIBPL)/README";			\
+		$(INSTALL_SCRIPT) Modules/ar_beos $(DESTDIR)$(LIBPL)/ar_beos; \
+		echo "$(LIBPL)/ar_beos";			\
+		$(INSTALL_SCRIPT) Modules/ld_so_beos $(DESTDIR)$(LIBPL)/ld_so_beos; \
+		echo "$(LIBPL)/ld_so_beos";			\
+		echo; echo "See Misc/BeOS-NOTES for details.";	\
+		;; \
+	esac
+
+# Install the dynamically loadable modules
+# This goes into $(exec_prefix)
+sharedinstall:
+	$(RUNSHARED) ./$(BUILDPYTHON) -E $(srcdir)/setup.py install \
+	   	--prefix=$(prefix) \
+		--install-scripts=$(BINDIR) \
+		--install-platlib=$(DESTSHARED) \
+		--root=/$(DESTDIR)
+
+# Here are a couple of targets for MacOSX again, to install a full
+# framework-based Python. frameworkinstall installs everything, the
+# subtargets install specific parts. Much of the actual work is offloaded to
+# the Makefile in Mac
+#
+#
+# This target is here for backward compatiblity, previous versions of Python
+# hadn't integrated framework installation in the normal install process.
+frameworkinstall: install
+
+# On install, we re-make the framework
+# structure in the install location, /Library/Frameworks/ or the argument to
+# --enable-framework. If --enable-framework has been specified then we have
+# automatically set prefix to the location deep down in the framework, so we
+# only have to cater for the structural bits of the framework.
+
+frameworkinstallframework: frameworkinstallstructure install frameworkinstallmaclib
+
+frameworkinstallstructure:	$(LDLIBRARY)
+	@if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \
+		echo Not configured with --enable-framework; \
+		exit 1; \
+	else true; \
+	fi
+	@for i in $(prefix)/Resources/English.lproj $(prefix)/lib; do\
+		if test ! -d $(DESTDIR)$$i; then \
+			echo "Creating directory $(DESTDIR)$$i"; \
+			$(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
+		else	true; \
+		fi; \
+	done
+	$(LN) -fsn include/python$(VERSION) $(DESTDIR)$(prefix)/Headers
+	$(INSTALL_DATA) $(RESSRCDIR)/Info.plist $(DESTDIR)$(prefix)/Resources/Info.plist
+	$(INSTALL_DATA) $(RESSRCDIR)/version.plist $(DESTDIR)$(prefix)/Resources/version.plist
+	$(INSTALL_DATA) $(RESSRCDIR)/English.lproj/InfoPlist.strings \
+		$(DESTDIR)$(prefix)/Resources/English.lproj/InfoPlist.strings
+	$(LN) -fsn $(VERSION) $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/Current
+	$(LN) -fsn Versions/Current/Python $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Python
+	$(LN) -fsn Versions/Current/Headers $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Headers
+	$(LN) -fsn Versions/Current/Resources $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Resources
+	$(INSTALL_SHARED) $(LDLIBRARY) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(LDLIBRARY)
+
+# This installs Mac/Lib into the framework
+# Install a number of symlinks to keep software that expects a normal unix
+# install (which includes python-config) happy.
+frameworkinstallmaclib:
+	ln -fs "../../../Python" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).a"
+	cd Mac && $(MAKE) installmacsubtree DESTDIR="$(DESTDIR)"
+
+# This installs the IDE, the Launcher and other apps into /Applications
+frameworkinstallapps:
+	cd Mac && $(MAKE) installapps DESTDIR="$(DESTDIR)"
+
+# This install the unix python and pythonw tools in /usr/local/bin
+frameworkinstallunixtools:
+	cd Mac && $(MAKE) installunixtools DESTDIR="$(DESTDIR)"
+
+frameworkaltinstallunixtools:
+	cd Mac && $(MAKE) altinstallunixtools DESTDIR="$(DESTDIR)"
+
+# This installs the Demos and Tools into the applications directory.
+# It is not part of a normal frameworkinstall
+frameworkinstallextras:
+	cd Mac && Make installextras DESTDIR="$(DESTDIR)"
+
+# This installs a few of the useful scripts in Tools/scripts
+scriptsinstall:
+	SRCDIR=$(srcdir) $(RUNSHARED) \
+	./$(BUILDPYTHON) $(srcdir)/Tools/scripts/setup.py install \
+	--prefix=$(prefix) \
+	--install-scripts=$(BINDIR) \
+	--root=/$(DESTDIR)
+
+# Build the toplevel Makefile
+Makefile.pre: Makefile.pre.in config.status
+	CONFIG_FILES=Makefile.pre CONFIG_HEADERS= $(SHELL) config.status
+	$(MAKE) -f Makefile.pre Makefile
+
+# Run the configure script.
+config.status:	$(srcdir)/configure
+	$(SHELL) $(srcdir)/configure $(CONFIG_ARGS)
+
+.PRECIOUS: config.status $(BUILDPYTHON) Makefile Makefile.pre
+
+# Some make's put the object file in the current directory
+.c.o:
+	$(CC) -c $(PY_CFLAGS) -o $@ $<
+
+# Run reindent on the library
+reindent:
+	./python$(EXEEXT) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib
+
+# Rerun configure with the same options as it was run last time,
+# provided the config.status script exists
+recheck:
+	$(SHELL) config.status --recheck
+	$(SHELL) config.status
+
+# Rebuild the configure script from configure.in; also rebuild pyconfig.h.in
+autoconf:
+	(cd $(srcdir); autoconf)
+	(cd $(srcdir); autoheader)
+
+# Create a tags file for vi
+tags::
+	cd $(srcdir); \
+	ctags -w -t Include/*.h; \
+	for i in $(SRCDIRS); do ctags -w -t -a $$i/*.[ch]; \
+	done; \
+	sort -o tags tags
+
+# Create a tags file for GNU Emacs
+TAGS::
+	cd $(srcdir); \
+	etags Include/*.h; \
+	for i in $(SRCDIRS); do etags -a $$i/*.[ch]; done
+
+# Sanitation targets -- clean leaves libraries, executables and tags
+# files, which clobber removes those as well
+pycremoval:
+	find $(srcdir) -name '*.py[co]' -exec rm -f {} ';'
+
+clean: pycremoval
+	find . -name '*.o' -exec rm -f {} ';'
+	find . -name '*.s[ol]' -exec rm -f {} ';'
+	find $(srcdir)/build -name 'fficonfig.h' -exec rm -f {} ';' || true
+	find $(srcdir)/build -name 'fficonfig.py' -exec rm -f {} ';' || true
+
+clobber: clean
+	-rm -f $(BUILDPYTHON) $(PGEN) $(LIBRARY) $(LDLIBRARY) $(DLLLIBRARY) \
+		tags TAGS \
+		config.cache config.log pyconfig.h Modules/config.c
+	-rm -rf build platform
+	-rm -rf $(PYTHONFRAMEWORKDIR)
+
+# Make things extra clean, before making a distribution:
+# remove all generated files, even Makefile[.pre]
+# Keep configure and Python-ast.[ch], it's possible they can't be generated
+distclean: clobber
+	-rm -f core Makefile Makefile.pre config.status \
+		Modules/Setup Modules/Setup.local Modules/Setup.config
+	find $(srcdir) '(' -name '*.fdc' -o -name '*~' \
+			   -o -name '[@,#]*' -o -name '*.old' \
+			   -o -name '*.orig' -o -name '*.rej' \
+			   -o -name '*.bak' ')' \
+			   -exec rm -f {} ';'
+
+# Check for smelly exported symbols (not starting with Py/_Py)
+smelly: all
+	nm -p $(LIBRARY) | \
+		sed -n "/ [TDB] /s/.* //p" | grep -v "^_*Py" | sort -u; \
+
+# Find files with funny names
+funny:
+	find $(DISTDIRS) -type d \
+		-o -name '*.[chs]' \
+		-o -name '*.py' \
+		-o -name '*.doc' \
+		-o -name '*.sty' \
+		-o -name '*.bib' \
+		-o -name '*.dat' \
+		-o -name '*.el' \
+		-o -name '*.fd' \
+		-o -name '*.in' \
+		-o -name '*.tex' \
+		-o -name '*,[vpt]' \
+		-o -name 'Setup' \
+		-o -name 'Setup.*' \
+		-o -name README \
+		-o -name Makefile \
+		-o -name ChangeLog \
+		-o -name Repository \
+		-o -name Root \
+		-o -name Entries \
+		-o -name Tag \
+		-o -name tags \
+		-o -name TAGS \
+		-o -name .cvsignore \
+		-o -name MANIFEST \
+		-o -print
+
+# Dependencies
+
+Python/thread.o:  $(srcdir)/Python/thread_atheos.h $(srcdir)/Python/thread_beos.h $(srcdir)/Python/thread_cthread.h $(srcdir)/Python/thread_foobar.h $(srcdir)/Python/thread_lwp.h $(srcdir)/Python/thread_nt.h $(srcdir)/Python/thread_os2.h $(srcdir)/Python/thread_pth.h $(srcdir)/Python/thread_pthread.h $(srcdir)/Python/thread_sgi.h $(srcdir)/Python/thread_solaris.h $(srcdir)/Python/thread_wince.h
+
+# Declare targets that aren't real files
+.PHONY: all sharedmods oldsharedmods test quicktest memtest
+.PHONY: install altinstall oldsharedinstall bininstall altbininstall
+.PHONY: maninstall libinstall inclinstall libainstall sharedinstall
+.PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure
+.PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools
+.PHONY: frameworkaltinstallunixtools recheck autoconf clean clobber distclean 
+.PHONY: smelly funny
+
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
+
+# Rules appended by makedepend
+
+Modules/threadmodule.o: $(srcdir)/Modules/threadmodule.c; $(CC) $(PY_CFLAGS)  -c $(srcdir)/Modules/threadmodule.c -o Modules/threadmodule.o
+Modules/threadmodule$(SO):  Modules/threadmodule.o; $(LDSHARED)  Modules/threadmodule.o   -o Modules/threadmodule$(SO)
+Modules/signalmodule.o: $(srcdir)/Modules/signalmodule.c; $(CC) $(PY_CFLAGS)  -c $(srcdir)/Modules/signalmodule.c -o Modules/signalmodule.o
+Modules/signalmodule$(SO):  Modules/signalmodule.o; $(LDSHARED)  Modules/signalmodule.o   -o Modules/signalmodule$(SO)
+Modules/posixmodule.o: $(srcdir)/Modules/posixmodule.c; $(CC) $(PY_CFLAGS)  -c $(srcdir)/Modules/posixmodule.c -o Modules/posixmodule.o
+Modules/posixmodule$(SO):  Modules/posixmodule.o; $(LDSHARED)  Modules/posixmodule.o   -o Modules/posixmodule$(SO)
+Modules/errnomodule.o: $(srcdir)/Modules/errnomodule.c; $(CC) $(PY_CFLAGS)  -c $(srcdir)/Modules/errnomodule.c -o Modules/errnomodule.o
+Modules/errnomodule$(SO):  Modules/errnomodule.o; $(LDSHARED)  Modules/errnomodule.o   -o Modules/errnomodule$(SO)
+Modules/pwdmodule.o: $(srcdir)/Modules/pwdmodule.c; $(CC) $(PY_CFLAGS)  -c $(srcdir)/Modules/pwdmodule.c -o Modules/pwdmodule.o
+Modules/pwdmodule$(SO):  Modules/pwdmodule.o; $(LDSHARED)  Modules/pwdmodule.o   -o Modules/pwdmodule$(SO)
+Modules/_sre.o: $(srcdir)/Modules/_sre.c; $(CC) $(PY_CFLAGS)  -c $(srcdir)/Modules/_sre.c -o Modules/_sre.o
+Modules/_sre$(SO):  Modules/_sre.o; $(LDSHARED)  Modules/_sre.o   -o Modules/_sre$(SO)
+Modules/_codecsmodule.o: $(srcdir)/Modules/_codecsmodule.c; $(CC) $(PY_CFLAGS)  -c $(srcdir)/Modules/_codecsmodule.c -o Modules/_codecsmodule.o
+Modules/_codecsmodule$(SO):  Modules/_codecsmodule.o; $(LDSHARED)  Modules/_codecsmodule.o   -o Modules/_codecsmodule$(SO)
+Modules/zipimport.o: $(srcdir)/Modules/zipimport.c; $(CC) $(PY_CFLAGS)  -c $(srcdir)/Modules/zipimport.c -o Modules/zipimport.o
+Modules/zipimport$(SO):  Modules/zipimport.o; $(LDSHARED)  Modules/zipimport.o   -o Modules/zipimport$(SO)
+Modules/symtablemodule.o: $(srcdir)/Modules/symtablemodule.c; $(CC) $(PY_CFLAGS)  -c $(srcdir)/Modules/symtablemodule.c -o Modules/symtablemodule.o
+Modules/_symtablemodule$(SO):  Modules/symtablemodule.o; $(LDSHARED)  Modules/symtablemodule.o   -o Modules/_symtablemodule$(SO)
+Modules/xxsubtype.o: $(srcdir)/Modules/xxsubtype.c; $(CC) $(PY_CFLAGS)  -c $(srcdir)/Modules/xxsubtype.c -o Modules/xxsubtype.o
+Modules/xxsubtype$(SO):  Modules/xxsubtype.o; $(LDSHARED)  Modules/xxsubtype.o   -o Modules/xxsubtype$(SO)
diff --git a/app/server/vendor/rouge/spec/visual/samples/markdown b/app/server/vendor/rouge/spec/visual/samples/markdown
new file mode 100755
index 0000000..9fa435e
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/markdown
@@ -0,0 +1,1061 @@
+---
+title: "Markdown: Syntax"
+author: daringfireball.net
+---
+
+Markdown: Syntax
+================
+
+<ul id="ProjectSubmenu">
+    <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
+    <li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li>
+    <li><a class="selected" title="Markdown Syntax Documentation">Syntax</a></li>
+    <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
+    <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
+</ul>
+
+
+*   [Overview](#overview)
+    *   [Philosophy](#philosophy)
+    *   [Inline HTML](#html)
+    *   [Automatic Escaping for Special Characters](#autoescape)
+*   [Block Elements](#block)
+    *   [Paragraphs and Line Breaks](#p)
+    *   [Headers](#header)
+    *   [Blockquotes](#blockquote)
+    *   [Lists](#list)
+    *   [Code Blocks](#precode)
+    *   [Horizontal Rules](#hr)
+*   [Span Elements](#span)
+    *   [Links](#link)
+    *   [Emphasis](#em)
+    *   [Code](#code)
+    *   [Images](#img)
+*   [Miscellaneous](#misc)
+    *   [Backslash Escapes](#backslash)
+    *   [Automatic Links](#autolink)
+
+
+**Note:** This document is itself written using Markdown; you
+can [see the source for it by adding '.text' to the URL][src].
+
+  [src]: /projects/markdown/syntax.text
+
+* * *
+
+<h2 id="overview">Overview</h2>
+
+<h3 id="philosophy">Philosophy</h3>
+
+Markdown is intended to be as easy-to-read and easy-to-write as is feasible.
+
+Readability, however, is emphasized above all else. A Markdown-formatted
+document should be publishable as-is, as plain text, without looking
+like it's been marked up with tags or formatting instructions. While
+Markdown's syntax has been influenced by several existing text-to-HTML
+filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4],
+[Grutatext] [5], and [EtText] [6] -- the single biggest source of
+inspiration for Markdown's syntax is the format of plain text email.
+
+  [1]: http://docutils.sourceforge.net/mirror/setext.html
+  [2]: http://www.aaronsw.com/2002/atx/
+  [3]: http://textism.com/tools/textile/
+  [4]: http://docutils.sourceforge.net/rst.html
+  [5]: http://www.triptico.com/software/grutatxt.html
+  [6]: http://ettext.taint.org/doc/
+
+To this end, Markdown's syntax is comprised entirely of punctuation
+characters, which punctuation characters have been carefully chosen so
+as to look like what they mean. E.g., asterisks around a word actually
+look like \*emphasis\*. Markdown lists look like, well, lists. Even
+blockquotes look like quoted passages of text, assuming you've ever
+used email.
+
+
+
+<h3 id="html">Inline HTML</h3>
+
+Markdown's syntax is intended for one purpose: to be used as a
+format for *writing* for the web.
+
+Markdown is not a replacement for HTML, or even close to it. Its
+syntax is very small, corresponding only to a very small subset of
+HTML tags. The idea is *not* to create a syntax that makes it easier
+to insert HTML tags. In my opinion, HTML tags are already easy to
+insert. The idea for Markdown is to make it easy to read, write, and
+edit prose. HTML is a *publishing* format; Markdown is a *writing*
+format. Thus, Markdown's formatting syntax only addresses issues that
+can be conveyed in plain text.
+
+For any markup that is not covered by Markdown's syntax, you simply
+use HTML itself. There's no need to preface it or delimit it to
+indicate that you're switching from Markdown to HTML; you just use
+the tags.
+
+The only restrictions are that block-level HTML elements -- e.g. `<div>`,
+`<table>`, `<pre>`, `<p>`, etc. -- must be separated from surrounding
+content by blank lines, and the start and end tags of the block should
+not be indented with tabs or spaces. Markdown is smart enough not
+to add extra (unwanted) `<p>` tags around HTML block-level tags.
+
+For example, to add an HTML table to a Markdown article:
+
+    This is a regular paragraph.
+
+    <table>
+        <tr>
+            <td>Foo</td>
+        </tr>
+    </table>
+
+    This is another regular paragraph.
+
+highlighted:
+
+This is a regular paragraph.
+
+<table>
+    <tr>
+        <td>Foo</td>
+    </tr>
+</table>
+
+This is another regular paragraph.
+
+Note that Markdown formatting syntax is not processed within block-level
+HTML tags. E.g., you can't use Markdown-style `*emphasis*` inside an
+HTML block.
+
+Span-level HTML tags -- e.g. `<span>`, `<cite>`, or `<del>` -- can be
+used anywhere in a Markdown paragraph, list item, or header. If you
+want, you can even use HTML tags instead of Markdown formatting; e.g. if
+you'd prefer to use HTML `<a>` or `<img>` tags instead of Markdown's
+link or image syntax, go right ahead.
+
+Unlike block-level HTML tags, Markdown syntax *is* processed within
+span-level tags.
+
+
+<h3 id="autoescape">Automatic Escaping for Special Characters</h3>
+
+In HTML, there are two characters that demand special treatment: `<`
+and `&`. Left angle brackets are used to start tags; ampersands are
+used to denote HTML entities. If you want to use them as literal
+characters, you must escape them as entities, e.g. `<`, and
+`&`.
+
+Ampersands in particular are bedeviling for web writers. If you want to
+write about 'AT&T', you need to write '`AT&T`'. You even need to
+escape ampersands within URLs. Thus, if you want to link to:
+
+    http://images.google.com/images?num=30&q=larry+bird
+
+http://images.google.com/images?num=30&q=larry+bird
+
+you need to encode the URL as:
+
+    http://images.google.com/images?num=30&q=larry+bird
+
+in your anchor tag `href` attribute. Needless to say, this is easy to
+forget, and is probably the single most common source of HTML validation
+errors in otherwise well-marked-up web sites.
+
+Markdown allows you to use these characters naturally, taking care of
+all the necessary escaping for you. If you use an ampersand as part of
+an HTML entity, it remains unchanged; otherwise it will be translated
+into `&`.
+
+So, if you want to include a copyright symbol in your article, you can write:
+
+    ©
+
+©
+
+and Markdown will leave it alone. But if you write:
+
+    AT&T
+
+AT&T
+
+Markdown will translate it to:
+
+    AT&T
+
+Similarly, because Markdown supports [inline HTML](#html), if you use
+angle brackets as delimiters for HTML tags, Markdown will treat them as
+such. But if you write:
+
+    4 < 5
+
+highlighted:
+
+4 < 5
+
+Markdown will translate it to:
+
+    4 < 5
+
+However, inside Markdown code spans and blocks, angle brackets and
+ampersands are *always* encoded automatically. This makes it easy to use
+Markdown to write about HTML code. (As opposed to raw HTML, which is a
+terrible format for writing about HTML syntax, because every single `<`
+and `&` in your example code needs to be escaped.)
+
+
+* * *
+
+
+<h2 id="block">Block Elements</h2>
+
+
+<h3 id="p">Paragraphs and Line Breaks</h3>
+
+A paragraph is simply one or more consecutive lines of text, separated
+by one or more blank lines. (A blank line is any line that looks like a
+blank line -- a line containing nothing but spaces or tabs is considered
+blank.) Normal paragraphs should not be indented with spaces or tabs.
+
+The implication of the "one or more consecutive lines of text" rule is
+that Markdown supports "hard-wrapped" text paragraphs. This differs
+significantly from most other text-to-HTML formatters (including Movable
+Type's "Convert Line Breaks" option) which translate every line break
+character in a paragraph into a `<br />` tag.
+
+When you *do* want to insert a `<br />` break tag using Markdown, you
+end a line with two or more spaces, then type return.
+
+Yes, this takes a tad more effort to create a `<br />`, but a simplistic
+"every line break is a `<br />`" rule wouldn't work for Markdown.
+Markdown's email-style [blockquoting][bq] and multi-paragraph [list items][l]
+work best -- and look better -- when you format them with hard breaks.
+
+  [bq]: #blockquote
+  [l]:  #list
+
+
+
+<h3 id="header">Headers</h3>
+
+Markdown supports two styles of headers, [Setext] [1] and [atx] [2].
+
+Setext-style headers are "underlined" using equal signs (for first-level
+headers) and dashes (for second-level headers). For example:
+
+    This is an H1
+    =============
+
+    This is an H2
+    -------------
+
+highlighted:
+
+This is an H1
+=============
+
+This is an H2
+-------------
+
+Any number of underlining `=`'s or `-`'s will work.
+
+Atx-style headers use 1-6 hash characters at the start of the line,
+corresponding to header levels 1-6. For example:
+
+    # This is an H1
+
+    ## This is an H2
+
+    ###### This is an H6
+
+highlighted:
+
+# This is an H1
+
+## This is an H2
+
+###### This is an H6
+
+Optionally, you may "close" atx-style headers. This is purely
+cosmetic -- you can use this if you think it looks better. The
+closing hashes don't even need to match the number of hashes
+used to open the header. (The number of opening hashes
+determines the header level.) :
+
+    # This is an H1 #
+
+    ## This is an H2 ##
+
+    ### This is an H3 ######
+
+
+<h3 id="blockquote">Blockquotes</h3>
+
+Markdown uses email-style `>` characters for blockquoting. If you're
+familiar with quoting passages of text in an email message, then you
+know how to create a blockquote in Markdown. It looks best if you hard
+wrap the text and put a `>` before every line:
+
+    > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
+    > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
+    > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
+    > 
+    > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
+    > id sem consectetuer libero luctus adipiscing.
+
+> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
+> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
+> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
+> 
+> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
+> id sem consectetuer libero luctus adipiscing.
+
+Markdown allows you to be lazy and only put the `>` before the first
+line of a hard-wrapped paragraph:
+
+    > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
+    consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
+    Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
+
+    > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
+    id sem consectetuer libero luctus adipiscing.
+
+Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by
+adding additional levels of `>`:
+
+    > This is the first level of quoting.
+    >
+    > > This is nested blockquote.
+    >
+    > Back to the first level.
+
+renders as:
+
+> This is the first level of quoting.
+>
+> > This is nested blockquote.
+>
+> Back to the first level.
+
+Blockquotes can contain other Markdown elements, including headers, lists,
+and code blocks:
+
+	> ## This is a header.
+	> 
+	> 1.   This is the first list item.
+	> 2.   This is the second list item.
+	> 
+	> Here's some example code:
+	> 
+	>     return shell_exec("echo $input | $markdown_script");
+
+Any decent text editor should make email-style quoting easy. For
+example, with BBEdit, you can make a selection and choose Increase
+Quote Level from the Text menu.
+
+
+<h3 id="list">Lists</h3>
+
+Markdown supports ordered (numbered) and unordered (bulleted) lists.
+
+Unordered lists use asterisks, pluses, and hyphens -- interchangably
+-- as list markers:
+
+    *   Red
+    *   Green
+    *   Blue
+
+*   Red
+*   Green
+*   Blue
+
+is equivalent to:
+
+    +   Red
+    +   Green
+    +   Blue
+
++   Red
++   Green
++   Blue
+
+and:
+
+    -   Red
+    -   Green
+    -   Blue
+
+-   Red
+-   Green
+-   Blue
+
+Ordered lists use numbers followed by periods:
+
+    1.  Bird
+    2.  McHale
+    3.  Parish
+
+1.  Bird
+2.  McHale
+3.  Parish
+
+It's important to note that the actual numbers you use to mark the
+list have no effect on the HTML output Markdown produces. The HTML
+Markdown produces from the above list is:
+
+    <ol>
+    <li>Bird</li>
+    <li>McHale</li>
+    <li>Parish</li>
+    </ol>
+
+If you instead wrote the list in Markdown like this:
+
+    1.  Bird
+    1.  McHale
+    1.  Parish
+
+or even:
+
+    3. Bird
+    1. McHale
+    8. Parish
+
+you'd get the exact same HTML output. The point is, if you want to,
+you can use ordinal numbers in your ordered Markdown lists, so that
+the numbers in your source match the numbers in your published HTML.
+But if you want to be lazy, you don't have to.
+
+If you do use lazy list numbering, however, you should still start the
+list with the number 1. At some point in the future, Markdown may support
+starting ordered lists at an arbitrary number.
+
+List markers typically start at the left margin, but may be indented by
+up to three spaces. List markers must be followed by one or more spaces
+or a tab.
+
+To make lists look nice, you can wrap items with hanging indents:
+
+    *   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+        Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
+        viverra nec, fringilla in, laoreet vitae, risus.
+    *   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
+        Suspendisse id sem consectetuer libero luctus adipiscing.
+
+*   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+    Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
+    viverra nec, fringilla in, laoreet vitae, risus.
+*   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
+    Suspendisse id sem consectetuer libero luctus adipiscing.
+
+But if you want to be lazy, you don't have to:
+
+    *   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+    Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
+    viverra nec, fringilla in, laoreet vitae, risus.
+    *   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
+    Suspendisse id sem consectetuer libero luctus adipiscing.
+
+If list items are separated by blank lines, Markdown will wrap the
+items in `<p>` tags in the HTML output. For example, this input:
+
+    *   Bird
+    *   Magic
+
+will turn into:
+
+    <ul>
+    <li>Bird</li>
+    <li>Magic</li>
+    </ul>
+
+But this:
+
+    *   Bird
+
+    *   Magic
+
+will turn into:
+
+    <ul>
+    <li><p>Bird</p></li>
+    <li><p>Magic</p></li>
+    </ul>
+
+List items may consist of multiple paragraphs. Each subsequent
+paragraph in a list item must be indented by either 4 spaces
+or one tab:
+
+    1.  This is a list item with two paragraphs. Lorem ipsum dolor
+        sit amet, consectetuer adipiscing elit. Aliquam hendrerit
+        mi posuere lectus.
+
+        Vestibulum enim wisi, viverra nec, fringilla in, laoreet
+        vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
+        sit amet velit.
+
+    2.  Suspendisse id sem consectetuer libero luctus adipiscing.
+
+It looks nice if you indent every line of the subsequent
+paragraphs, but here again, Markdown will allow you to be
+lazy:
+
+    *   This is a list item with two paragraphs.
+
+        This is the second paragraph in the list item. You're
+    only required to indent the first line. Lorem ipsum dolor
+    sit amet, consectetuer adipiscing elit.
+
+    *   Another item in the same list.
+
+To put a blockquote within a list item, the blockquote's `>`
+delimiters need to be indented:
+
+    *   A list item with a blockquote:
+
+        > This is a blockquote
+        > inside a list item.
+
+To put a code block within a list item, the code block needs
+to be indented *twice* -- 8 spaces or two tabs:
+
+    *   A list item with a code block:
+
+            <code goes here>
+
+
+It's worth noting that it's possible to trigger an ordered list by
+accident, by writing something like this:
+
+    1986. What a great season.
+
+In other words, a *number-period-space* sequence at the beginning of a
+line. To avoid this, you can backslash-escape the period:
+
+    1986\. What a great season.
+
+1986\. What a great season.
+
+
+<h3 id="precode">Code Blocks</h3>
+
+Pre-formatted code blocks are used for writing about programming or
+markup source code. Rather than forming normal paragraphs, the lines
+of a code block are interpreted literally. Markdown wraps a code block
+in both `<pre>` and `<code>` tags.
+
+To produce a code block in Markdown, simply indent every line of the
+block by at least 4 spaces or 1 tab. For example, given this input:
+
+    This is a normal paragraph:
+
+        This is a code block.
+
+This is a normal paragraph:
+
+    This is a code block.
+
+Markdown will generate:
+
+    <p>This is a normal paragraph:</p>
+
+    <pre><code>This is a code block.
+    </code></pre>
+
+One level of indentation -- 4 spaces or 1 tab -- is removed from each
+line of the code block. For example, this:
+
+    Here is an example of AppleScript:
+
+        tell application "Foo"
+            beep
+        end tell
+
+will turn into:
+
+    <p>Here is an example of AppleScript:</p>
+
+    <pre><code>tell application "Foo"
+        beep
+    end tell
+    </code></pre>
+
+A code block continues until it reaches a line that is not indented
+(or the end of the article).
+
+Within a code block, ampersands (`&`) and angle brackets (`<` and `>`)
+are automatically converted into HTML entities. This makes it very
+easy to include example HTML source code using Markdown -- just paste
+it and indent it, and Markdown will handle the hassle of encoding the
+ampersands and angle brackets. For example, this:
+
+        <div class="footer">
+            © 2004 Foo Corporation
+        </div>
+
+will turn into:
+
+    <pre><code><div class="footer">
+        &copy; 2004 Foo Corporation
+    </div>
+    </code></pre>
+
+Regular Markdown syntax is not processed within code blocks. E.g.,
+asterisks are just literal asterisks within a code block. This means
+it's also easy to use Markdown to write about Markdown's own syntax.
+
+
+
+<h3 id="hr">Horizontal Rules</h3>
+
+You can produce a horizontal rule tag (`<hr />`) by placing three or
+more hyphens, asterisks, or underscores on a line by themselves. If you
+wish, you may use spaces between the hyphens or asterisks. Each of the
+following lines will produce a horizontal rule:
+
+    * * *
+
+    ***
+
+    *****
+
+    - - -
+
+    ---------------------------------------
+
+highlighted:
+
+* * *
+
+***
+
+*****
+
+- - -
+
+---------------------------------------
+
+* * *
+
+<h2 id="span">Span Elements</h2>
+
+<h3 id="link">Links</h3>
+
+Markdown supports two style of links: *inline* and *reference*.
+
+In both styles, the link text is delimited by [square brackets].
+
+To create an inline link, use a set of regular parentheses immediately
+after the link text's closing square bracket. Inside the parentheses,
+put the URL where you want the link to point, along with an *optional*
+title for the link, surrounded in quotes. For example:
+
+    This is [an example](http://example.com/ "Title") inline link.
+
+    [This link](http://example.net/) has no title attribute.
+
+This is [an example](http://example.com/ "Title") inline link.
+
+[This link](http://example.net/) has no title attribute.
+
+Will produce:
+
+    <p>This is <a href="http://example.com/" title="Title">
+    an example</a> inline link.</p>
+
+    <p><a href="http://example.net/">This link</a> has no
+    title attribute.</p>
+
+If you're referring to a local resource on the same server, you can
+use relative paths:
+
+    See my [About](/about/) page for details.   
+
+See my [About](/about/) page for details.   
+
+Reference-style links use a second set of square brackets, inside
+which you place a label of your choosing to identify the link:
+
+    This is [an example][id] reference-style link.
+
+This is [an example][id] reference-style link.
+
+You can optionally use a space to separate the sets of brackets:
+
+    This is [an example] [id] reference-style link.
+
+This is [an example] [id] reference-style link.
+
+Then, anywhere in the document, you define your link label like this,
+on a line by itself:
+
+    [id]: http://example.com/  "Optional Title Here"
+
+highlighted:
+
+[id]: http://example.com/  "Optional Title Here"
+
+That is:
+
+*   Square brackets containing the link identifier (optionally
+    indented from the left margin using up to three spaces);
+*   followed by a colon;
+*   followed by one or more spaces (or tabs);
+*   followed by the URL for the link;
+*   optionally followed by a title attribute for the link, enclosed
+    in double or single quotes, or enclosed in parentheses.
+
+The following three link definitions are equivalent:
+
+	[foo]: http://example.com/  "Optional Title Here"
+	[foo]: http://example.com/  'Optional Title Here'
+	[foo]: http://example.com/  (Optional Title Here)
+
+[foo]: http://example.com/  "Optional Title Here"
+[foo]: http://example.com/  'Optional Title Here'
+[foo]: http://example.com/  (Optional Title Here)
+
+**Note:** There is a known bug in Markdown.pl 1.0.1 which prevents
+single quotes from being used to delimit link titles.
+
+The link URL may, optionally, be surrounded by angle brackets:
+
+    [id]: <http://example.com/>  "Optional Title Here"
+
+[id]: <http://example.com/>  "Optional Title Here"
+
+You can put the title attribute on the next line and use extra spaces
+or tabs for padding, which tends to look better with longer URLs:
+
+    [id]: http://example.com/longish/path/to/resource/here
+        "Optional Title Here"
+
+[id]: http://example.com/longish/path/to/resource/here
+    "Optional Title Here"
+
+Link definitions are only used for creating links during Markdown
+processing, and are stripped from your document in the HTML output.
+
+Link definition names may consist of letters, numbers, spaces, and
+punctuation -- but they are *not* case sensitive. E.g. these two
+links:
+
+	[link text][a]
+	[link text][A]
+
+are equivalent.
+
+The *implicit link name* shortcut allows you to omit the name of the
+link, in which case the link text itself is used as the name.
+Just use an empty set of square brackets -- e.g., to link the word
+"Google" to the google.com web site, you could simply write:
+
+	[Google][]
+
+And then define the link:
+
+	[Google]: http://google.com/
+
+Because link names may contain spaces, this shortcut even works for
+multiple words in the link text:
+
+	Visit [Daring Fireball][] for more information.
+
+And then define the link:
+	
+	[Daring Fireball]: http://daringfireball.net/
+
+Link definitions can be placed anywhere in your Markdown document. I
+tend to put them immediately after each paragraph in which they're
+used, but if you want, you can put them all at the end of your
+document, sort of like footnotes.
+
+Here's an example of reference links in action:
+
+    I get 10 times more traffic from [Google] [1] than from
+    [Yahoo] [2] or [MSN] [3].
+
+      [1]: http://google.com/        "Google"
+      [2]: http://search.yahoo.com/  "Yahoo Search"
+      [3]: http://search.msn.com/    "MSN Search"
+
+Using the implicit link name shortcut, you could instead write:
+
+    I get 10 times more traffic from [Google][] than from
+    [Yahoo][] or [MSN][].
+
+      [google]: http://google.com/        "Google"
+      [yahoo]:  http://search.yahoo.com/  "Yahoo Search"
+      [msn]:    http://search.msn.com/    "MSN Search"
+
+Both of the above examples will produce the following HTML output:
+
+    <p>I get 10 times more traffic from <a href="http://google.com/"
+    title="Google">Google</a> than from
+    <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>
+    or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
+
+For comparison, here is the same paragraph written using
+Markdown's inline link style:
+
+    I get 10 times more traffic from [Google](http://google.com/ "Google")
+    than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
+    [MSN](http://search.msn.com/ "MSN Search").
+
+The point of reference-style links is not that they're easier to
+write. The point is that with reference-style links, your document
+source is vastly more readable. Compare the above examples: using
+reference-style links, the paragraph itself is only 81 characters
+long; with inline-style links, it's 176 characters; and as raw HTML,
+it's 234 characters. In the raw HTML, there's more markup than there
+is text.
+
+With Markdown's reference-style links, a source document much more
+closely resembles the final output, as rendered in a browser. By
+allowing you to move the markup-related metadata out of the paragraph,
+you can add links without interrupting the narrative flow of your
+prose.
+
+
+<h3 id="em">Emphasis</h3>
+
+Markdown treats asterisks (`*`) and underscores (`_`) as indicators of
+emphasis. Text wrapped with one `*` or `_` will be wrapped with an
+HTML `<em>` tag; double `*`'s or `_`'s will be wrapped with an HTML
+`<strong>` tag. E.g., this input:
+
+    *single asterisks*
+
+    _single underscores_
+
+    **double asterisks**
+
+    __double underscores__
+
+will produce:
+
+    <em>single asterisks</em>
+
+    <em>single underscores</em>
+
+    <strong>double asterisks</strong>
+
+    <strong>double underscores</strong>
+
+You can use whichever style you prefer; the lone restriction is that
+the same character must be used to open and close an emphasis span.
+
+Emphasis can be used in the middle of a word:
+
+    un*frigging*believable
+
+un*frigging*believable
+
+But if you surround an `*` or `_` with spaces, it'll be treated as a
+literal asterisk or underscore.
+
+To produce a literal asterisk or underscore at a position where it
+would otherwise be used as an emphasis delimiter, you can backslash
+escape it:
+
+    \*this text is surrounded by literal asterisks\*
+
+\*this text is surrounded by literal asterisks\*
+
+
+
+<h3 id="code">Code</h3>
+
+To indicate a span of code, wrap it with backtick quotes (`` ` ``).
+Unlike a pre-formatted code block, a code span indicates code within a
+normal paragraph. For example:
+
+    Use the `printf()` function.
+
+Use the `printf()` function.
+
+will produce:
+
+    <p>Use the <code>printf()</code> function.</p>
+
+To include a literal backtick character within a code span, you can use
+multiple backticks as the opening and closing delimiters:
+
+    ``There is a literal backtick (`) here.``
+
+``There is a literal backtick (`) here.``
+
+which will produce this:
+
+    <p><code>There is a literal backtick (`) here.</code></p>
+
+The backtick delimiters surrounding a code span may include spaces --
+one after the opening, one before the closing. This allows you to place
+literal backtick characters at the beginning or end of a code span:
+
+	A single backtick in a code span: `` ` ``
+	
+	A backtick-delimited string in a code span: `` `foo` ``
+
+A single backtick in a code span: `` ` ``
+
+A backtick-delimited string in a code span: `` `foo` ``
+
+will produce:
+
+	<p>A single backtick in a code span: <code>`</code></p>
+	
+	<p>A backtick-delimited string in a code span: <code>`foo`</code></p>
+
+With a code span, ampersands and angle brackets are encoded as HTML
+entities automatically, which makes it easy to include example HTML
+tags. Markdown will turn this:
+
+    Please don't use any `<blink>` tags.
+
+Please don't use any `<blink>` tags.
+
+into:
+
+    <p>Please don't use any <code><blink></code> tags.</p>
+
+You can write this:
+
+    `—` is the decimal-encoded equivalent of `—`.
+
+`—` is the decimal-encoded equivalent of `—`.
+
+to produce:
+
+    <p><code>&#8212;</code> is the decimal-encoded
+    equivalent of <code>&mdash;</code>.</p>
+
+
+
+<h3 id="img">Images</h3>
+
+Admittedly, it's fairly difficult to devise a "natural" syntax for
+placing images into a plain text document format.
+
+Markdown uses an image syntax that is intended to resemble the syntax
+for links, allowing for two styles: *inline* and *reference*.
+
+Inline image syntax looks like this:
+
+    ![Alt text](/path/to/img.jpg)
+
+    ![Alt text](/path/to/img.jpg "Optional title")
+
+![Alt text](/path/to/img.jpg)
+
+![Alt text](/path/to/img.jpg "Optional title")
+
+That is:
+
+*   An exclamation mark: `!`;
+*   followed by a set of square brackets, containing the `alt`
+    attribute text for the image;
+*   followed by a set of parentheses, containing the URL or path to
+    the image, and an optional `title` attribute enclosed in double
+    or single quotes.
+
+Reference-style image syntax looks like this:
+
+    ![Alt text][id]
+
+Where "id" is the name of a defined image reference. Image references
+are defined using syntax identical to link references:
+
+    [id]: url/to/image  "Optional title attribute"
+
+As of this writing, Markdown has no syntax for specifying the
+dimensions of an image; if this is important to you, you can simply
+use regular HTML `<img>` tags.
+
+
+* * *
+
+
+<h2 id="misc">Miscellaneous</h2>
+
+<h3 id="autolink">Automatic Links</h3>
+
+Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:
+
+    <http://example.com/>
+
+<http://example.com/>
+    
+Markdown will turn this into:
+
+    <a href="http://example.com/">http://example.com/</a>
+
+Automatic links for email addresses work similarly, except that
+Markdown will also perform a bit of randomized decimal and hex
+entity-encoding to help obscure your address from address-harvesting
+spambots. For example, Markdown will turn this:
+
+    <address at example.com>
+
+<address at example.com>
+
+into something like this:
+
+    <a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65;
+    ss@ex&#x61;m&#x70;&#x6C;e&#x2E;co
+    m">&#x61;&#x64;&#x64;&#x72;&#x65;ss@ex&#x61;
+    m&#x70;&#x6C;e&#x2E;com</a>
+
+which will render in a browser as a clickable link to "address at example.com".
+
+(This sort of entity-encoding trick will indeed fool many, if not
+most, address-harvesting bots, but it definitely won't fool all of
+them. It's better than nothing, but an address published in this way
+will probably eventually start receiving spam.)
+
+
+
+<h3 id="backslash">Backslash Escapes</h3>
+
+Markdown allows you to use backslash escapes to generate literal
+characters which would otherwise have special meaning in Markdown's
+formatting syntax. For example, if you wanted to surround a word
+with literal asterisks (instead of an HTML `<em>` tag), you can use
+backslashes before the asterisks, like this:
+
+    \*literal asterisks\*
+
+Markdown provides backslash escapes for the following characters:
+
+    \   backslash
+    `   backtick
+    *   asterisk
+    _   underscore
+    {}  curly braces
+    []  square brackets
+    ()  parentheses
+    #   hash mark
+	+	plus sign
+	-	minus sign (hyphen)
+    .   dot
+    !   exclamation mark
+
+extensions:
+
+``` ruby
+puts @foo
+```
+
+~~~ latex
+{\it holy cow, it's \LaTeX!}
+~~~
+
+``` erb?parent=latex
+{\it holy cow, it's \LaTex with <%= @erb %>!}
+```
+
+``` markdown
+It's **markdownception** [wtf](/omg)
+```
+
+``` somefakelexer
+can't highlight me
+```
diff --git a/app/server/vendor/rouge/spec/visual/samples/matlab b/app/server/vendor/rouge/spec/visual/samples/matlab
new file mode 100755
index 0000000..cb20f83
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/matlab
@@ -0,0 +1,35 @@
+function zz=sample(aa)
+%%%%%%%%%%%%%%%%%%
+% some comments
+%%%%%%%%%%%%%%%%%%
+
+x = 'a string';    % some 'ticks' in a comment
+y = 'a string with ''interal'' quotes';
+
+for i=1:20
+  disp(i);
+end
+
+a = rand(30);
+b = rand(30);
+
+c = a .* b ./ a \ ... comment at end of line and continuation
+    (b .* a + b - a);
+
+c = a' * b';  % note: these ticks are for transpose, not quotes.
+
+disp('a comment symbol, %, in a string');
+
+!echo abc % this isn't a comment - it's passed to system command
+
+function y=myfunc(x)
+y = exp(x);
+
+ {%
+a block comment
+ %}
+
+
+function myfunc(s)
+    a = 1;
+end
diff --git a/app/server/vendor/rouge/spec/visual/samples/moonscript b/app/server/vendor/rouge/spec/visual/samples/moonscript
new file mode 100755
index 0000000..630e941
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/moonscript
@@ -0,0 +1,63 @@
+#! /usr/bin/moon
+
+-- A heap of sample Moonscript syntax
+
+util = require "my.module"
+
+import SomeClass, member from util
+import other from require "my.other_module"
+
+a_table = {
+  foo: 'bar'
+  interpolated: "foo-#{other.stuff 2 + 3}"
+  "string-key": 2
+  do: 'keyword'
+}
+
+short_table_def = foo: 'bar', interpolated: "foo-#{other.stuff 2 + 3}"
+scoped_table = :util, :a_table
+
+multiline_string = "line 1
+  for the alliance!
+line2"
+
+other_multiline_string = [[ for
+the
+win
+]]
+
+local x
+export y
+
+x or= 1
+x += 1
+y and= x
+
+empty_function ->
+args_function (arg1, arg2) -> arg1 + arg2
+var_args_function (...) -> table.concat {...}, '|'
+
+while cond == true do empty_function!
+
+comprehension = [item * 2 for i, item in ipairs items when item != 3]
+
+for i = 1,10
+  continue unless i != 2
+
+SomeClass(0xdeadbeef)\method 'foo'
+
+with a_table
+  .foobar = {}
+
+switch i
+  when 2
+    "not first"
+
+class MyClass extends SomeClass
+  new: (@init, arg2 = 'default') =>
+    @derived = @init + 2
+    super!
+
+  other: =>
+    @@foo + 2
+    @
diff --git a/app/server/vendor/rouge/spec/visual/samples/nginx b/app/server/vendor/rouge/spec/visual/samples/nginx
new file mode 100755
index 0000000..50bd689
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/nginx
@@ -0,0 +1,117 @@
+#user  nobody;
+worker_processes  1;
+
+#error_log  logs/error.log;
+#error_log  logs/error.log  notice;
+#error_log  logs/error.log  info;
+
+#pid        logs/nginx.pid;
+
+
+events {
+    worker_connections  1024;
+}
+
+
+http {
+    include       mime.types;
+    default_type  application/octet-stream;
+
+    log_format  main  '$remote_addr - $remote_user [$time_local] $request '
+                      '"$status" $body_bytes_sent "$http_referer" '
+                      '"$http_user_agent" "$http_x_forwarded_for"';
+
+    #access_log  logs/access.log  main;
+
+    sendfile        on;
+    #tcp_nopush     on;
+
+    #keepalive_timeout  0;
+    keepalive_timeout  65;
+
+    #gzip  on;
+
+    server {
+        listen       80;
+        server_name  localhost;
+
+        charset koi8-r;
+
+        #access_log  logs/host.access.log  main;
+
+        location / {
+            root   html;
+            index  index.html index.htm;
+        }
+
+        #error_page  404              /404.html;
+
+        # redirect server error pages to the static page /50x.html
+        #
+        error_page   500 502 503 504  /50x.html;
+        location = /50x.html {
+            root   html;
+        }
+
+        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
+        #
+        location ~ \.php$ {
+            proxy_pass   http://127.0.0.1;
+        }
+
+        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
+        #
+        location ~ \.php$ {
+            root           html;
+            fastcgi_pass   127.0.0.1:9000;
+            fastcgi_index  index.php;
+            fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
+            include        fastcgi_params;
+        }
+
+        # deny access to .htaccess files, if Apache's document root
+        # concurs with nginx's one
+        #
+        location ~ /\.ht {
+            deny  all;
+        }
+    }
+
+
+    # another virtual host using mix of IP-, name-, and port-based configuration
+    #
+    server {
+        listen       8000;
+        listen       somename:8080;
+        server_name  somename  alias  another.alias;
+
+        location / {
+            root   html;
+            index  index.html index.htm;
+        }
+    }
+
+
+    # HTTPS server
+    #
+    server {
+        listen       443;
+        server_name  localhost;
+
+        ssl                  on;
+        ssl_certificate      cert.pem;
+        ssl_certificate_key  cert.key;
+
+        ssl_session_timeout  5m;
+
+        ssl_protocols  SSLv2 SSLv3 TLSv1;
+        ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
+        ssl_prefer_server_ciphers   on;
+
+        location / {
+            root   html;
+            index  index.html index.htm;
+        }
+    }
+
+}
diff --git a/app/server/vendor/rouge/spec/visual/samples/objective_c b/app/server/vendor/rouge/spec/visual/samples/objective_c
new file mode 100755
index 0000000..51813eb
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/objective_c
@@ -0,0 +1,139 @@
+#import "Somefile.h"
+
+ at implementation ABC
+
+- (id) a: (A)a
+       b: (B)b
+       c: (C)c... {
+
+  // ternary expressions and message passing
+  a = b ? c : d;
+  [a b: c ? d : e];
+  a ? [b c: d] + e : f;
+  [a b];
+  [[a b: c] d];
+  label:
+  [a b:c
+     d:e];
+  other_label:
+  return 1;
+
+  YES @YES NO @NO nil true @true false @false;
+}
+
+ at end
+
+ at implementation ABC
+
+- (void)xyz;
+
+ at end
+
+NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
+    @"quattuor", @"four", @"quinque", @"five", @"sex", @"six", nil];
+
+
+NSString *key;
+for (key in dictionary) {
+    NSLog(@"English: %@, Latin: %@", key, [dictionary valueForKey:key]);
+}
+
+// MyClass.h
+ at import Foundation;
+
+ at interface MyClass : NSObject
+{
+    NSString *value;
+    NSTextField *textField;
+ at private
+    NSDate *lastModifiedDate;
+}
+ at property(copy, readwrite) NSString *value;
+ at property(retain) IBOutlet NSTextField *textField;
+ at end
+
+// To look up: are these comma-delimited?
+// interface definition for a category
+ at interface Foo (Bar, Baz, Zot) {
+}
+
+// MyClass.m
+// Class extension to declare private property
+ at interface MyClass ()
+ at property(retain) NSDate *lastModifiedDate;
+ at end
+
+ at implementation MyClass
+ at synthesize value;
+ at synthesize textField;
+ at synthesize lastModifiedDate;
+// implementation continues
+ at end
+
+ at class myProtocols;
+ at protocol myProtocol1 <NSObject>
+// list of methods and properties
+  doStuff:(float) myValue;
+ at end
+ at protocol myProtocol2 <NSObject>
+// list of methods and properties
+   doOtherStuff:(float) myValue2 andText:(NSString *)myText andType:(NSString *)myType;
+ at end
+ at interface  myProtocols:NSObject
+{
+   __unsafe_unretained id <myProtocol1> _myDelegate1;
+    __unsafe_unretained id <myProtocol2> _myDelegate2;
+}
+ at property (nonatomic, assign) id <myProtocol1> myDelegate1;
+ at property (nonatomic, assign) id <myProtocol2> myDelegate2;
+ at end
+
+#import myProtocols.h
+ at implementation myProtocols
+ at synthesize myDelegate1 = _myDelegate1
+ at synthesize myDelegate2 = _myDelegate2
+if ([_myDelegate1 respondsToSelector:@selector(doStuff:)])
+   [_myDelegate1 doStuff:3.5];
+if ([_myDelegate2 respondsToSelector:@selector(doOtherStuff:andText:andType:)])
+   [_myDelegate2 doOtherStuff:4.5 andText:@"YES MAN" andType:@"YES BRO"];
+ at end
+
+#import "myProtocols.h"
+ at interface classA: UIViewController <myProtocol1>
+ at property(strong, nonatomic) myProtocols *myProtoVC;
+ at end
+
+#import "classA.h"
+ at interface classA ()
+ at end
+ at implementation classA
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+    _myProtoVC = [[myProtocols alloc] init];
+    _myProtoVC.myDelegate1 = self;
+}
+-(void) doStuff:(float) myValue
+{
+  NSLog(@" YES VALUE IS %f",myValue);
+}
+
+#import "myProtocols.h"
+ at interface classB: UIViewController <myProtocol2>
+ at property(strong, nonatomic) myProtocols *myProtoVC;
+ at end
+
+#import "classB.h"
+ at interface classB ()
+ at end
+ at implementation classB
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+    _myProtoVC = [[myProtocols alloc] init];
+    _myProtoVC.myDelegate2 = self;
+}
+-(void) doOtherStuff:(float) myValue2 andText:(NSString *)myText andType:(NSString *)myType; 
+{
+  NSLog(@" YES VALUE IS %f and text %@ and type %@",myValue2,myText,myType);
+}end
diff --git a/app/server/vendor/rouge/spec/visual/samples/ocaml b/app/server/vendor/rouge/spec/visual/samples/ocaml
new file mode 100755
index 0000000..529016a
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/ocaml
@@ -0,0 +1,1232 @@
+(* method callse *)
+let s = object
+  val mutable v = [0; 2]
+
+  method pop =
+    match v with
+    | hd :: tl ->
+      v <- tl;
+      Some hd
+    | [] -> None
+
+  method push hd =
+    v <- hd :: v
+end ;;
+
+s#pop ;;
+s#push 4 ;;
+
+
+(***********************************************************************)
+(*                                                                     *)
+(*                           Objective Caml                            *)
+(*                                                                     *)
+(*            Pierre Weis, projet Cristal, INRIA Rocquencourt          *)
+(*                                                                     *)
+(*  Copyright 1996 Institut National de Recherche en Informatique et   *)
+(*  en Automatique.  All rights reserved.  This file is distributed    *)
+(*  under the terms of the GNU Library General Public License, with    *)
+(*  the special exception on linking described in file ../LICENSE.     *)
+(*                                                                     *)
+(***********************************************************************)
+
+(* $Id: format.ml,v 1.65 2005/09/26 10:13:08 weis Exp $ *)
+
+(**************************************************************
+
+  Data structures definitions.
+
+ **************************************************************)
+
+type size;;
+
+external size_of_int : int -> size = "%identity";;
+external int_of_size : size -> int = "%identity";;
+
+(* Tokens are one of the following : *)
+
+type pp_token =
+| Pp_text of string            (* normal text *)
+| Pp_break of int * int        (* complete break *)
+| Pp_tbreak of int * int       (* go to next tabulation *)
+| Pp_stab                      (* set a tabulation *)
+| Pp_begin of int * block_type (* beginning of a block *)
+| Pp_end                       (* end of a block *)
+| Pp_tbegin of tblock          (* beginning of a tabulation block *)
+| Pp_tend                      (* end of a tabulation block *)
+| Pp_newline                   (* to force a newline inside a block *)
+| Pp_if_newline                (* to do something only if this very
+                                  line has been broken *)
+| Pp_open_tag of string        (* opening a tag name *)
+| Pp_close_tag                 (* closing the most recently opened tag *)
+
+and tag = string
+
+and block_type =
+| Pp_hbox   (* Horizontal block no line breaking *)
+| Pp_vbox   (* Vertical block each break leads to a new line *)
+| Pp_hvbox  (* Horizontal-vertical block: same as vbox, except if this block
+               is small enough to fit on a single line *)
+| Pp_hovbox (* Horizontal or Vertical block: breaks lead to new line
+               only when necessary to print the content of the block *)
+| Pp_box    (* Horizontal or Indent block: breaks lead to new line
+               only when necessary to print the content of the block, or
+               when it leads to a new indentation of the current line *)
+| Pp_fits   (* Internal usage: when a block fits on a single line *)
+
+and tblock = Pp_tbox of int list ref  (* Tabulation box *)
+;;
+
+(* The Queue:
+   contains all formatting elements.
+   elements are tuples (size, token, length), where
+   size is set when the size of the block is known
+   len is the declared length of the token. *)
+type pp_queue_elem = {
+  mutable elem_size : size; token : pp_token; length : int
+};;
+
+(* Scan stack:
+   each element is (left_total, queue element) where left_total
+   is the value of pp_left_total when the element has been enqueued. *)
+type pp_scan_elem = Scan_elem of int * pp_queue_elem;;
+
+(* Formatting stack:
+   used to break the lines while printing tokens.
+   The formatting stack contains the description of
+   the currently active blocks. *)
+type pp_format_elem = Format_elem of block_type * int;;
+
+(* General purpose queues, used in the formatter. *)
+type 'a queue_elem = | Nil | Cons of 'a queue_cell
+and 'a queue_cell = {mutable head : 'a; mutable tail : 'a queue_elem};;
+
+type 'a queue = {
+ mutable insert : 'a queue_elem;
+ mutable body : 'a queue_elem
+};;
+
+(* The formatter specific tag handling functions. *)
+type formatter_tag_functions = {
+ mark_open_tag : tag -> string;
+ mark_close_tag : tag -> string;
+ print_open_tag : tag -> unit;
+ print_close_tag : tag -> unit;
+
+};;
+
+(* A formatter with all its machinery. *)
+type formatter = {
+ mutable pp_scan_stack : pp_scan_elem list;
+ mutable pp_format_stack : pp_format_elem list;
+ mutable pp_tbox_stack : tblock list;
+ mutable pp_tag_stack : tag list;
+ mutable pp_mark_stack : tag list;
+ (* Global variables: default initialization is
+    set_margin 78
+    set_min_space_left 0. *)
+ (* Value of right margin. *)
+ mutable pp_margin : int;
+ (* Minimal space left before margin, when opening a block. *)
+ mutable pp_min_space_left : int;
+ (* Maximum value of indentation:
+    no blocks can be opened further. *)
+ mutable pp_max_indent : int;
+ (* Space remaining on the current line. *)
+ mutable pp_space_left : int;
+ (* Current value of indentation. *)
+ mutable pp_current_indent : int;
+ (* True when the line has been broken by the pretty-printer. *)
+ mutable pp_is_new_line : bool;
+ (* Total width of tokens already printed. *)
+ mutable pp_left_total : int;
+ (* Total width of tokens ever put in queue. *)
+ mutable pp_right_total : int;
+ (* Current number of opened blocks. *)
+ mutable pp_curr_depth : int;
+ (* Maximum number of blocks which can be simultaneously opened. *)
+ mutable pp_max_boxes : int;
+ (* Ellipsis string. *)
+ mutable pp_ellipsis : string;
+ (* Output function. *)
+ mutable pp_output_function : string -> int -> int -> unit;
+ (* Flushing function. *)
+ mutable pp_flush_function : unit -> unit;
+ (* Output of new lines. *)
+ mutable pp_output_newline : unit -> unit;
+ (* Output of indentation spaces. *)
+ mutable pp_output_spaces : int -> unit;
+ (* Are tags printed ? *)
+ mutable pp_print_tags : bool;
+ (* Are tags marked ? *)
+ mutable pp_mark_tags : bool;
+ (* Find opening and closing markers of tags. *)
+ mutable pp_mark_open_tag : tag -> string;
+ mutable pp_mark_close_tag : tag -> string;
+ mutable pp_print_open_tag : tag -> unit;
+ mutable pp_print_close_tag : tag -> unit;
+ (* The pretty-printer queue. *)
+ mutable pp_queue : pp_queue_elem queue
+};;
+
+(**************************************************************
+
+  Auxilliaries and basic functions.
+
+ **************************************************************)
+
+
+(* Queues auxilliaries. *)
+let make_queue () = {insert = Nil; body = Nil};;
+
+let clear_queue q = q.insert <- Nil; q.body <- Nil;;
+
+let add_queue x q =
+ let c = Cons {head = x; tail = Nil} in
+ match q with
+ | {insert = Cons cell} -> q.insert <- c; cell.tail <- c
+ (* Invariant: when insert is Nil body should be Nil. *)
+ | _ -> q.insert <- c; q.body <- c;;
+
+exception Empty_queue;;
+
+let peek_queue = function
+ | {body = Cons {head = x}} -> x
+ | _ -> raise Empty_queue;;
+
+let take_queue = function
+ | {body = Cons {head = x; tail = tl}} as q ->
+    q.body <- tl;
+    if tl = Nil then q.insert <- Nil; (* Maintain the invariant. *)
+    x
+ | _ -> raise Empty_queue;;
+
+(* Enter a token in the pretty-printer queue. *)
+let pp_enqueue state ({length = len} as token) =
+    state.pp_right_total <- state.pp_right_total + len;
+    add_queue token state.pp_queue;;
+
+let pp_clear_queue state =
+    state.pp_left_total <- 1; state.pp_right_total <- 1;
+    clear_queue state.pp_queue;;
+
+(* Pp_infinity: large value for default tokens size.
+
+   Pp_infinity is documented as being greater than 1e10; to avoid
+   confusion about the word ``greater'', we choose pp_infinity greater
+   than 1e10 + 1; for correct handling of tests in the algorithm,
+   pp_infinity must be even one more than 1e10 + 1; let's stand on the
+   safe side by choosing 1.e10+10.
+
+   Pp_infinity could probably be 1073741823 that is 2^30 - 1, that is
+   the minimal upper bound for integers; now that max_int is defined,
+   this limit could also be defined as max_int - 1.
+
+   However, before setting pp_infinity to something around max_int, we
+   must carefully double-check all the integer arithmetic operations
+   that involve pp_infinity, since any overflow would wreck havoc the
+   pretty-printing algorithm's invariants. Given that this arithmetic
+   correctness check is difficult and error prone and given that 1e10
+   + 1 is in practice large enough, there is no need to attempt to set
+   pp_infinity to the theoretically maximum limit. Is it not worth the
+   burden ! *)
+
+let pp_infinity = 1000000010;;
+
+(* Output functions for the formatter. *)
+let pp_output_string state s = state.pp_output_function s 0 (String.length s)
+and pp_output_newline state = state.pp_output_newline ();;
+
+let pp_display_blanks state n = state.pp_output_spaces n;;
+
+(* To format a break, indenting a new line. *)
+let break_new_line state offset width =
+    pp_output_newline state;
+    state.pp_is_new_line <- true;
+    let indent = state.pp_margin - width + offset in
+    (* Don't indent more than pp_max_indent. *)
+    let real_indent = min state.pp_max_indent indent in
+    state.pp_current_indent <- real_indent;
+    state.pp_space_left <- state.pp_margin - state.pp_current_indent;
+    pp_display_blanks state state.pp_current_indent;;
+
+(* To force a line break inside a block: no offset is added. *)
+let break_line state width = break_new_line state 0 width;;
+
+(* To format a break that fits on the current line. *)
+let break_same_line state width =
+    state.pp_space_left <- state.pp_space_left - width;
+    pp_display_blanks state width;;
+
+(* To indent no more than pp_max_indent, if one tries to open a block
+   beyond pp_max_indent, then the block is rejected on the left
+   by simulating a break. *)
+let pp_force_break_line state =
+    match state.pp_format_stack with
+    | Format_elem (bl_ty, width) :: _ ->
+        if width > state.pp_space_left then
+         (match bl_ty with
+          | Pp_fits -> () | Pp_hbox -> () | _ -> break_line state width)
+    | _ -> pp_output_newline state;;
+
+(* To skip a token, if the previous line has been broken. *)
+let pp_skip_token state =
+    (* When calling pp_skip_token the queue cannot be empty. *)
+    match take_queue state.pp_queue with
+    {elem_size = size; length = len} ->
+       state.pp_left_total <- state.pp_left_total - len;
+       state.pp_space_left <- state.pp_space_left + int_of_size size;;
+
+(**************************************************************
+
+  The main pretting printing functions.
+
+ **************************************************************)
+
+(* To format a token. *)
+let format_pp_token state size = function
+
+  | Pp_text s ->
+      state.pp_space_left <- state.pp_space_left - size;
+      pp_output_string state s;
+      state.pp_is_new_line <- false
+
+  | Pp_begin (off, ty) ->
+      let insertion_point = state.pp_margin - state.pp_space_left in
+      if insertion_point > state.pp_max_indent then
+         (* can't open a block right there. *)
+         begin pp_force_break_line state end;
+      let offset = state.pp_space_left - off in
+      let bl_type =
+       begin match ty with
+        | Pp_vbox -> Pp_vbox
+        | _ -> if size > state.pp_space_left then ty else Pp_fits
+       end in
+       state.pp_format_stack <-
+        Format_elem (bl_type, offset) :: state.pp_format_stack
+
+  | Pp_end ->
+      begin match state.pp_format_stack with
+        | x :: (y :: l as ls) -> state.pp_format_stack <- ls
+        | _ -> () (* No more block to close. *)
+      end
+
+  | Pp_tbegin (Pp_tbox _ as tbox) ->
+      state.pp_tbox_stack <- tbox :: state.pp_tbox_stack
+
+  | Pp_tend ->
+      begin match state.pp_tbox_stack with
+        | x :: ls -> state.pp_tbox_stack <- ls
+        | _ -> () (* No more tabulation block to close. *)
+      end
+
+  | Pp_stab ->
+     begin match state.pp_tbox_stack with
+     | Pp_tbox tabs :: _ ->
+        let rec add_tab n = function
+          | [] -> [n]
+          | x :: l as ls -> if n < x then n :: ls else x :: add_tab n l in
+        tabs := add_tab (state.pp_margin - state.pp_space_left) !tabs
+     | _ -> () (* No opened tabulation block. *)
+     end
+
+  | Pp_tbreak (n, off) ->
+      let insertion_point = state.pp_margin - state.pp_space_left in
+      begin match state.pp_tbox_stack with
+      | Pp_tbox tabs :: _ ->
+         let rec find n = function
+           | x :: l -> if x >= n then x else find n l
+           | [] -> raise Not_found in
+         let tab =
+             match !tabs with
+             | x :: l ->
+                begin try find insertion_point !tabs with Not_found -> x end
+             | _ -> insertion_point in
+         let offset = tab - insertion_point in
+         if offset >= 0 then break_same_line state (offset + n) else
+          break_new_line state (tab + off) state.pp_margin
+      | _ -> () (* No opened tabulation block. *)
+      end
+
+  | Pp_newline ->
+     begin match state.pp_format_stack with
+     | Format_elem (_, width) :: _ -> break_line state width
+     | _ -> pp_output_newline state
+     end
+
+  | Pp_if_newline ->
+     if state.pp_current_indent != state.pp_margin - state.pp_space_left
+     then pp_skip_token state
+
+  | Pp_break (n, off) ->
+     begin match state.pp_format_stack with
+     | Format_elem (ty, width) :: _ ->
+        begin match ty with
+        | Pp_hovbox ->
+           if size > state.pp_space_left
+           then break_new_line state off width
+           else break_same_line state n
+        | Pp_box ->
+           (* Have the line just been broken here ? *)
+           if state.pp_is_new_line then break_same_line state n else
+           if size > state.pp_space_left
+            then break_new_line state off width else
+           (* break the line here leads to new indentation ? *)
+           if state.pp_current_indent > state.pp_margin - width + off
+           then break_new_line state off width
+           else break_same_line state n
+        | Pp_hvbox -> break_new_line state off width
+        | Pp_fits -> break_same_line state n
+        | Pp_vbox -> break_new_line state off width
+        | Pp_hbox -> break_same_line state n
+        end
+     | _ -> () (* No opened block. *)
+     end
+
+   | Pp_open_tag tag_name ->
+      let marker = state.pp_mark_open_tag tag_name in
+      pp_output_string state marker;
+      state.pp_mark_stack <- tag_name :: state.pp_mark_stack
+
+   | Pp_close_tag ->
+      begin match state.pp_mark_stack with
+      | tag_name :: tags ->
+          let marker = state.pp_mark_close_tag tag_name in
+          pp_output_string state marker;
+          state.pp_mark_stack <- tags
+      | _ -> () (* No more tag to close. *)
+      end;;
+
+(* Print if token size is known or printing is delayed.
+   Size is known when not negative.
+   Printing is delayed when the text waiting in the queue requires
+   more room to format than exists on the current line. *)
+let rec advance_left state =
+    try
+     match peek_queue state.pp_queue with
+      {elem_size = size; token = tok; length = len} ->
+       let size = int_of_size size in
+       if not
+        (size < 0 &&
+         (state.pp_right_total - state.pp_left_total < state.pp_space_left))
+        then begin
+         ignore(take_queue state.pp_queue);
+         format_pp_token state (if size < 0 then pp_infinity else size) tok;
+         state.pp_left_total <- len + state.pp_left_total;
+         advance_left state
+        end
+    with Empty_queue -> ();;
+
+let enqueue_advance state tok = pp_enqueue state tok; advance_left state;;
+
+(* To enqueue a string : try to advance. *)
+let make_queue_elem size tok len =
+ {elem_size = size; token = tok; length = len};;
+
+let enqueue_string_as state size s =
+  let len = int_of_size size in
+  enqueue_advance state (make_queue_elem size (Pp_text s) len);;
+
+let enqueue_string state s =
+  let len = String.length s in
+  enqueue_string_as state (size_of_int len) s;;
+
+(* Routines for scan stack
+   determine sizes of blocks. *)
+
+(* The scan_stack is never empty. *)
+let scan_stack_bottom =
+  let q_elem = make_queue_elem (size_of_int (-1)) (Pp_text "") 0 in
+  [Scan_elem (-1, q_elem)];;
+
+(* Set size of blocks on scan stack:
+   if ty = true then size of break is set else size of block is set;
+   in each case pp_scan_stack is popped. *)
+let clear_scan_stack state = state.pp_scan_stack <- scan_stack_bottom;;
+
+(* Pattern matching on scan stack is exhaustive,
+   since scan_stack is never empty.
+   Pattern matching on token in scan stack is also exhaustive,
+   since scan_push is used on breaks and opening of boxes. *)
+let set_size state ty =
+    match state.pp_scan_stack with
+    | Scan_elem
+        (left_tot,
+         ({elem_size = size; token = tok} as queue_elem)) :: t ->
+       let size = int_of_size size in
+       (* test if scan stack contains any data that is not obsolete. *)
+       if left_tot < state.pp_left_total then clear_scan_stack state else
+        begin match tok with
+        | Pp_break (_, _) | Pp_tbreak (_, _) ->
+           if ty then
+            begin
+             queue_elem.elem_size <- size_of_int (state.pp_right_total + size);
+             state.pp_scan_stack <- t
+            end
+        | Pp_begin (_, _) ->
+           if not ty then
+            begin
+             queue_elem.elem_size <- size_of_int (state.pp_right_total + size);
+             state.pp_scan_stack <- t
+            end
+        | _ -> () (* scan_push is only used for breaks and boxes. *)
+        end
+    | _ -> () (* scan_stack is never empty. *);;
+
+(* Push a token on scan stack. If b is true set_size is called. *)
+let scan_push state b tok =
+    pp_enqueue state tok;
+    if b then set_size state true;
+    state.pp_scan_stack <-
+     Scan_elem (state.pp_right_total, tok) :: state.pp_scan_stack;;
+
+(* To open a new block :
+   the user may set the depth bound pp_max_boxes
+   any text nested deeper is printed as the ellipsis string. *)
+let pp_open_box_gen state indent br_ty =
+    state.pp_curr_depth <- state.pp_curr_depth + 1;
+    if state.pp_curr_depth < state.pp_max_boxes then
+      let elem =
+        make_queue_elem
+          (size_of_int (- state.pp_right_total))
+          (Pp_begin (indent, br_ty))
+          0 in
+      scan_push state false elem else
+    if state.pp_curr_depth = state.pp_max_boxes
+    then enqueue_string state state.pp_ellipsis;;
+
+(* The box which is always opened. *)
+let pp_open_sys_box state = pp_open_box_gen state 0 Pp_hovbox;;
+
+(* Close a block, setting sizes of its subblocks. *)
+let pp_close_box state () =
+    if state.pp_curr_depth > 1 then
+     begin
+      if state.pp_curr_depth < state.pp_max_boxes then
+       begin
+        pp_enqueue state
+          {elem_size = size_of_int 0; token = Pp_end; length = 0};
+        set_size state true; set_size state false
+       end;
+      state.pp_curr_depth <- state.pp_curr_depth - 1;
+     end;;
+
+(* Open a tag, pushing it on the tag stack. *)
+let pp_open_tag state tag_name =
+    if state.pp_print_tags then begin
+      state.pp_tag_stack <- tag_name :: state.pp_tag_stack;
+      state.pp_print_open_tag tag_name end;
+    if state.pp_mark_tags then
+      pp_enqueue state
+        {elem_size = size_of_int 0; token = Pp_open_tag tag_name; length = 0};;
+
+(* Close a tag, popping it from the tag stack. *)
+let pp_close_tag state () =
+    if state.pp_mark_tags then
+      pp_enqueue state
+        {elem_size = size_of_int 0; token = Pp_close_tag; length = 0};
+    if state.pp_print_tags then
+      begin match state.pp_tag_stack with
+      | tag_name :: tags ->
+          state.pp_print_close_tag tag_name;
+          state.pp_tag_stack <- tags
+      | _ -> () (* No more tag to close. *)
+      end;;
+
+let pp_set_print_tags state b = state.pp_print_tags <- b;;
+let pp_set_mark_tags state b = state.pp_mark_tags <- b;;
+let pp_get_print_tags state () = state.pp_print_tags;;
+let pp_get_mark_tags state () = state.pp_mark_tags;;
+let pp_set_tags state b = pp_set_print_tags state b; pp_set_mark_tags state b;;
+
+let pp_get_formatter_tag_functions state () = {
+   mark_open_tag = state.pp_mark_open_tag;
+   mark_close_tag = state.pp_mark_close_tag;
+   print_open_tag = state.pp_print_open_tag;
+   print_close_tag = state.pp_print_close_tag;
+};;
+
+let pp_set_formatter_tag_functions state {
+     mark_open_tag = mot;
+     mark_close_tag = mct;
+     print_open_tag = pot;
+     print_close_tag = pct;
+  } =
+   state.pp_mark_open_tag <- mot;
+   state.pp_mark_close_tag <- mct;
+   state.pp_print_open_tag <- pot;
+   state.pp_print_close_tag <- pct;;
+
+(* Initialize pretty-printer. *)
+let pp_rinit state =
+    pp_clear_queue state;
+    clear_scan_stack state;
+    state.pp_format_stack <- [];
+    state.pp_tbox_stack <- [];
+    state.pp_tag_stack <- [];
+    state.pp_mark_stack <- [];
+    state.pp_current_indent <- 0;
+    state.pp_curr_depth <- 0;
+    state.pp_space_left <- state.pp_margin;
+    pp_open_sys_box state;;
+
+(* Flushing pretty-printer queue. *)
+let pp_flush_queue state b =
+    while state.pp_curr_depth > 1 do
+     pp_close_box state ()
+    done;
+    state.pp_right_total <- pp_infinity;
+    advance_left state;
+    if b then pp_output_newline state;
+    pp_rinit state;;
+
+(**************************************************************
+
+  Procedures to format objects, and use boxes
+
+ **************************************************************)
+
+(* To format a string. *)
+let pp_print_as_size state size s =
+  if state.pp_curr_depth < state.pp_max_boxes
+  then enqueue_string_as state size s;;
+
+let pp_print_as state isize s =
+  pp_print_as_size state (size_of_int isize) s;;
+
+let pp_print_string state s =
+  pp_print_as state (String.length s) s;;
+
+(* To format an integer. *)
+let pp_print_int state i = pp_print_string state (string_of_int i);;
+
+(* To format a float. *)
+let pp_print_float state f = pp_print_string state (string_of_float f);;
+
+(* To format a boolean. *)
+let pp_print_bool state b = pp_print_string state (string_of_bool b);;
+
+(* To format a char. *)
+let pp_print_char state c =
+  let s = String.create 1 in
+  s.[0] <- c;
+  pp_print_as state 1 s;;
+
+(* Opening boxes. *)
+let pp_open_hbox state () = pp_open_box_gen state 0 Pp_hbox
+and pp_open_vbox state indent = pp_open_box_gen state indent Pp_vbox
+
+and pp_open_hvbox state indent = pp_open_box_gen state indent Pp_hvbox
+and pp_open_hovbox state indent = pp_open_box_gen state indent Pp_hovbox
+and pp_open_box state indent = pp_open_box_gen state indent Pp_box;;
+
+(* Print a new line after printing all queued text
+   (same for print_flush but without a newline). *)
+let pp_print_newline state () =
+    pp_flush_queue state true; state.pp_flush_function ()
+and pp_print_flush state () =
+    pp_flush_queue state false; state.pp_flush_function ();;
+
+(* To get a newline when one does not want to close the current block. *)
+let pp_force_newline state () =
+  if state.pp_curr_depth < state.pp_max_boxes then
+    enqueue_advance state (make_queue_elem (size_of_int 0) Pp_newline 0);;
+
+(* To format something if the line has just been broken. *)
+let pp_print_if_newline state () =
+  if state.pp_curr_depth < state.pp_max_boxes then
+    enqueue_advance state (make_queue_elem (size_of_int 0) Pp_if_newline 0);;
+
+(* Breaks: indicate where a block may be broken.
+   If line is broken then offset is added to the indentation of the current
+   block else (the value of) width blanks are printed.
+   To do (?) : add a maximum width and offset value. *)
+let pp_print_break state width offset =
+  if state.pp_curr_depth < state.pp_max_boxes then
+    let elem =
+      make_queue_elem
+        (size_of_int (- state.pp_right_total))
+        (Pp_break (width, offset))
+        width in
+    scan_push state true elem;;
+
+let pp_print_space state () = pp_print_break state 1 0
+and pp_print_cut state () = pp_print_break state 0 0;;
+
+(* Tabulation boxes. *)
+let pp_open_tbox state () =
+  state.pp_curr_depth <- state.pp_curr_depth + 1;
+  if state.pp_curr_depth < state.pp_max_boxes then
+    let elem =
+      make_queue_elem (size_of_int 0) (Pp_tbegin (Pp_tbox (ref []))) 0 in
+    enqueue_advance state elem;;
+
+(* Close a tabulation block. *)
+let pp_close_tbox state () =
+  if state.pp_curr_depth > 1 then begin
+   if state.pp_curr_depth < state.pp_max_boxes then
+     let elem = make_queue_elem (size_of_int 0) Pp_tend 0 in
+     enqueue_advance state elem;
+     state.pp_curr_depth <- state.pp_curr_depth - 1 end;;
+
+(* Print a tabulation break. *)
+let pp_print_tbreak state width offset =
+  if state.pp_curr_depth < state.pp_max_boxes then
+    let elem =
+      make_queue_elem
+        (size_of_int (- state.pp_right_total))
+        (Pp_tbreak (width, offset))
+        width in
+    scan_push state true elem;;
+
+let pp_print_tab state () = pp_print_tbreak state 0 0;;
+
+let pp_set_tab state () =
+  if state.pp_curr_depth < state.pp_max_boxes then
+    let elem =
+      make_queue_elem (size_of_int 0) Pp_stab 0 in
+    enqueue_advance state elem;;
+
+(**************************************************************
+
+  Procedures to control the pretty-printers
+
+ **************************************************************)
+
+(* Fit max_boxes. *)
+let pp_set_max_boxes state n = if n > 1 then state.pp_max_boxes <- n;;
+
+(* To know the current maximum number of boxes allowed. *)
+let pp_get_max_boxes state () = state.pp_max_boxes;;
+
+let pp_over_max_boxes state () = state.pp_curr_depth = state.pp_max_boxes;;
+
+(* Ellipsis. *)
+let pp_set_ellipsis_text state s = state.pp_ellipsis <- s
+and pp_get_ellipsis_text state () = state.pp_ellipsis;;
+
+(* To set the margin of pretty-printer. *)
+let pp_limit n =
+  if n < pp_infinity then n else pred pp_infinity;;
+
+let pp_set_min_space_left state n =
+  if n >= 1 then
+    let n = pp_limit n in
+    state.pp_min_space_left <- n;
+    state.pp_max_indent <- state.pp_margin - state.pp_min_space_left;
+    pp_rinit state;;
+
+(* Initially, we have :
+  pp_max_indent = pp_margin - pp_min_space_left, and
+  pp_space_left = pp_margin. *)
+let pp_set_max_indent state n =
+  pp_set_min_space_left state (state.pp_margin - n);;
+let pp_get_max_indent state () = state.pp_max_indent;;
+
+let pp_set_margin state n =
+  if n >= 1 then
+    let n = pp_limit n in
+    state.pp_margin <- n;
+    let new_max_indent =
+        (* Try to maintain max_indent to its actual value. *)
+        if state.pp_max_indent <= state.pp_margin
+        then state.pp_max_indent else
+        (* If possible maintain pp_min_space_left to its actual value,
+           if this leads to a too small max_indent, take half of the
+           new margin, if it is greater than 1. *)
+         max (max (state.pp_margin - state.pp_min_space_left)
+                  (state.pp_margin / 2)) 1 in
+    (* Rebuild invariants. *)
+    pp_set_max_indent state new_max_indent;;
+
+let pp_get_margin state () = state.pp_margin;;
+
+let pp_set_formatter_output_functions state f g =
+  state.pp_output_function <- f; state.pp_flush_function <- g;;
+let pp_get_formatter_output_functions state () =
+  (state.pp_output_function, state.pp_flush_function);;
+
+let pp_set_all_formatter_output_functions state
+    ~out:f ~flush:g ~newline:h ~spaces:i =
+  pp_set_formatter_output_functions state f g;
+  state.pp_output_newline <- (function () -> h ());
+  state.pp_output_spaces <- (function n -> i n);;
+let pp_get_all_formatter_output_functions state () =
+  (state.pp_output_function, state.pp_flush_function,
+   state.pp_output_newline, state.pp_output_spaces);;
+
+let pp_set_formatter_out_channel state os =
+  state.pp_output_function <- output os;
+  state.pp_flush_function <- (fun () -> flush os);;
+
+(**************************************************************
+
+  Creation of specific formatters
+
+ **************************************************************)
+
+let default_pp_mark_open_tag s = "<" ^ s ^ ">";;
+let default_pp_mark_close_tag s = "</" ^ s ^ ">";;
+
+let default_pp_print_open_tag s = ();;
+let default_pp_print_close_tag = default_pp_print_open_tag;;
+
+let pp_make_formatter f g h i =
+ (* The initial state of the formatter contains a dummy box. *)
+ let pp_q = make_queue () in
+ let sys_tok =
+   make_queue_elem (size_of_int (-1)) (Pp_begin (0, Pp_hovbox)) 0 in
+ add_queue sys_tok pp_q;
+ let sys_scan_stack =
+     (Scan_elem (1, sys_tok)) :: scan_stack_bottom in
+ {pp_scan_stack = sys_scan_stack;
+  pp_format_stack = [];
+  pp_tbox_stack = [];
+  pp_tag_stack = [];
+  pp_mark_stack = [];
+  pp_margin = 78;
+  pp_min_space_left = 10;
+  pp_max_indent = 78 - 10;
+  pp_space_left = 78;
+  pp_current_indent = 0;
+  pp_is_new_line = true;
+  pp_left_total = 1;
+  pp_right_total = 1;
+  pp_curr_depth = 1;
+  pp_max_boxes = max_int;
+  pp_ellipsis = ".";
+  pp_output_function = f;
+  pp_flush_function = g;
+  pp_output_newline = h;
+  pp_output_spaces = i;
+  pp_print_tags = false;
+  pp_mark_tags = false;
+  pp_mark_open_tag = default_pp_mark_open_tag;
+  pp_mark_close_tag = default_pp_mark_close_tag;
+  pp_print_open_tag = default_pp_print_open_tag;
+  pp_print_close_tag = default_pp_print_close_tag;
+  pp_queue = pp_q
+ };;
+
+(* Default function to output spaces. *)
+let blank_line = String.make 80 ' ';;
+let rec display_blanks state n =
+    if n > 0 then
+    if n <= 80 then state.pp_output_function blank_line 0 n else
+     begin
+      state.pp_output_function blank_line 0 80;
+      display_blanks state (n - 80)
+     end;;
+
+(* Default function to output new lines. *)
+let display_newline state () = state.pp_output_function "\n" 0  1;;
+
+let make_formatter f g =
+  let ff = pp_make_formatter f g ignore ignore in
+  ff.pp_output_newline <- display_newline ff;
+  ff.pp_output_spaces <- display_blanks ff;
+  ff;;
+
+let formatter_of_out_channel oc =
+  make_formatter (output oc) (fun () -> flush oc);;
+
+let formatter_of_buffer b =
+  make_formatter (Buffer.add_substring b) ignore;;
+
+let stdbuf = Buffer.create 512;;
+
+let str_formatter = formatter_of_buffer stdbuf;;
+let std_formatter = formatter_of_out_channel stdout;;
+let err_formatter = formatter_of_out_channel stderr;;
+
+let flush_str_formatter () =
+  pp_flush_queue str_formatter false;
+  let s = Buffer.contents stdbuf in
+  Buffer.reset stdbuf;
+  s;;
+
+(**************************************************************
+
+  Basic functions on the standard formatter
+
+ **************************************************************)
+
+let open_hbox = pp_open_hbox std_formatter
+and open_vbox = pp_open_vbox std_formatter
+and open_hvbox = pp_open_hvbox std_formatter
+and open_hovbox = pp_open_hovbox std_formatter
+and open_box = pp_open_box std_formatter
+and close_box = pp_close_box std_formatter
+and open_tag = pp_open_tag std_formatter
+and close_tag = pp_close_tag std_formatter
+and print_as = pp_print_as std_formatter
+and print_string = pp_print_string std_formatter
+and print_int = pp_print_int std_formatter
+and print_float = pp_print_float std_formatter
+and print_char = pp_print_char std_formatter
+and print_bool = pp_print_bool std_formatter
+and print_break = pp_print_break std_formatter
+and print_cut = pp_print_cut std_formatter
+and print_space = pp_print_space std_formatter
+and force_newline = pp_force_newline std_formatter
+and print_flush = pp_print_flush std_formatter
+and print_newline = pp_print_newline std_formatter
+and print_if_newline = pp_print_if_newline std_formatter
+
+and open_tbox = pp_open_tbox std_formatter
+and close_tbox = pp_close_tbox std_formatter
+and print_tbreak = pp_print_tbreak std_formatter
+
+and set_tab = pp_set_tab std_formatter
+and print_tab = pp_print_tab std_formatter
+
+and set_margin = pp_set_margin std_formatter
+and get_margin = pp_get_margin std_formatter
+
+and set_max_indent = pp_set_max_indent std_formatter
+and get_max_indent = pp_get_max_indent std_formatter
+
+and set_max_boxes = pp_set_max_boxes std_formatter
+and get_max_boxes = pp_get_max_boxes std_formatter
+and over_max_boxes = pp_over_max_boxes std_formatter
+
+and set_ellipsis_text = pp_set_ellipsis_text std_formatter
+and get_ellipsis_text = pp_get_ellipsis_text std_formatter
+
+and set_formatter_out_channel =
+    pp_set_formatter_out_channel std_formatter
+
+and set_formatter_output_functions =
+    pp_set_formatter_output_functions std_formatter
+and get_formatter_output_functions =
+    pp_get_formatter_output_functions std_formatter
+
+and set_all_formatter_output_functions =
+    pp_set_all_formatter_output_functions std_formatter
+and get_all_formatter_output_functions =
+    pp_get_all_formatter_output_functions std_formatter
+
+and set_formatter_tag_functions =
+    pp_set_formatter_tag_functions std_formatter
+and get_formatter_tag_functions =
+    pp_get_formatter_tag_functions std_formatter
+and set_print_tags =
+    pp_set_print_tags std_formatter
+and get_print_tags =
+    pp_get_print_tags std_formatter
+and set_mark_tags =
+    pp_set_mark_tags std_formatter
+and get_mark_tags =
+    pp_get_mark_tags std_formatter
+and set_tags =
+    pp_set_tags std_formatter
+;;
+
+
+(**************************************************************
+
+  Printf implementation.
+
+ **************************************************************)
+
+(* Error messages when processing formats. *)
+
+(* Trailer: giving up at character number ... *)
+let giving_up mess fmt i =
+  "fprintf: " ^ mess ^ " ``" ^ fmt ^ "'', \
+   giving up at character number " ^ string_of_int i ^
+  (if i < String.length fmt
+   then " (" ^ String.make 1 fmt.[i] ^ ")."
+   else String.make 1 '.');;
+
+(* When an invalid format deserves a special error explanation. *)
+let format_invalid_arg mess fmt i = invalid_arg (giving_up mess fmt i);;
+
+(* Standard invalid format. *)
+let invalid_format fmt i = format_invalid_arg "bad format" fmt i;;
+
+(* Cannot find a valid integer into that format. *)
+let invalid_integer fmt i =
+  invalid_arg (giving_up "bad integer specification" fmt i);;
+
+(* Finding an integer out of a sub-string of the format. *)
+let format_int_of_string fmt i s =
+  let sz =
+    try int_of_string s with
+    | Failure s -> invalid_integer fmt i in
+  size_of_int sz;;
+
+(* Getting strings out of buffers. *)
+let get_buffer_out b =
+ let s = Buffer.contents b in
+ Buffer.reset b;
+ s;;
+
+(* [ppf] is supposed to be a pretty-printer that outputs in buffer [b]:
+   to extract contents of [ppf] as a string we flush [ppf] and get the string
+   out of [b]. *)
+let string_out b ppf =
+ pp_flush_queue ppf false;
+ get_buffer_out b;;
+
+(* Applies [printer] to a formatter that outputs on a fresh buffer,
+   then returns the resulting material. *)
+let exstring printer arg =
+ let b = Buffer.create 512 in
+ let ppf = formatter_of_buffer b in
+ printer ppf arg;
+ string_out b ppf;;
+
+(* To turn out a character accumulator into the proper string result. *)
+let implode_rev s0 = function
+  | [] -> s0
+  | l -> String.concat "" (List.rev (s0 :: l));;
+
+external format_to_string : ('a, 'b, 'c, 'd) format4 -> string = "%identity";;
+
+(* [fprintf_out] is the printf-like function generator: given the
+   - [str] flag that tells if we are printing into a string,
+   - the [out] function that has to be called at the end of formatting,
+   it generates a [fprintf] function that takes as arguments a [ppf]
+   formatter and a printing format to print the rest of arguments
+   according to the format.
+   Regular [fprintf]-like functions of this module are obtained via partial
+   applications of [fprintf_out]. *)
+let mkprintf str get_out =
+  let rec kprintf k fmt =
+    let fmt = format_to_string fmt in
+    let len = String.length fmt in
+
+    let kpr fmt v =
+      let ppf = get_out fmt in
+      let print_as = ref None in
+      let pp_print_as_char c =
+          match !print_as with
+          | None -> pp_print_char ppf c
+          | Some size ->
+             pp_print_as_size ppf size (String.make 1 c);
+             print_as := None
+      and pp_print_as_string s =
+          match !print_as with
+          | None -> pp_print_string ppf s
+          | Some size ->
+             pp_print_as_size ppf size s;
+             print_as := None in
+
+      let rec doprn n i =
+        if i >= len then Obj.magic (k ppf) else
+        match fmt.[i] with
+        | '%' ->
+            Printf.scan_format fmt v n i cont_s cont_a cont_t cont_f cont_m
+        | '@' ->
+            let i = succ i in
+            if i >= len then invalid_format fmt i else
+            begin match fmt.[i] with
+            | '[' ->
+               do_pp_open_box ppf n (succ i)
+            | ']' ->
+               pp_close_box ppf ();
+               doprn n (succ i)
+            | '{' ->
+               do_pp_open_tag ppf n (succ i)
+            | '}' ->
+               pp_close_tag ppf ();
+               doprn n (succ i)
+            | ' ' ->
+               pp_print_space ppf ();
+               doprn n (succ i)
+            | ',' ->
+               pp_print_cut ppf ();
+               doprn n (succ i)
+            | '?' ->
+               pp_print_flush ppf ();
+               doprn n (succ i)
+            | '.' ->
+               pp_print_newline ppf ();
+               doprn n (succ i)
+            | '\n' ->
+               pp_force_newline ppf ();
+               doprn n (succ i)
+            | ';' ->
+               do_pp_break ppf n (succ i)
+            | '<' ->
+               let got_size size n i =
+                 print_as := Some size;
+                 doprn n (skip_gt i) in
+               get_int n (succ i) got_size
+            | '@' as c ->
+               pp_print_as_char c;
+               doprn n (succ i)
+            | c -> invalid_format fmt i
+            end
+        | c ->
+           pp_print_as_char c;
+           doprn n (succ i)
+
+      and cont_s n s i =
+        pp_print_as_string s; doprn n i
+      and cont_a n printer arg i =
+        if str then
+          pp_print_as_string ((Obj.magic printer : unit -> _ -> string) () arg)
+        else
+          printer ppf arg;
+        doprn n i
+      and cont_t n printer i =
+        if str then
+          pp_print_as_string ((Obj.magic printer : unit -> string) ())
+        else
+          printer ppf;
+        doprn n i
+      and cont_f n i =
+        pp_print_flush ppf (); doprn n i
+
+      and cont_m n sfmt i =
+        kprintf (Obj.magic (fun _ -> doprn n i)) sfmt
+
+      and get_int n i c =
+       if i >= len then invalid_integer fmt i else
+       match fmt.[i] with
+       | ' ' -> get_int n (succ i) c
+       | '%' ->
+          let cont_s n s i = c (format_int_of_string fmt i s) n i
+          and cont_a n printer arg i = invalid_integer fmt i
+          and cont_t n printer i = invalid_integer fmt i
+          and cont_f n i = invalid_integer fmt i
+          and cont_m n sfmt i = invalid_integer fmt i in
+          Printf.scan_format fmt v n i cont_s cont_a cont_t cont_f cont_m
+       | _ ->
+          let rec get j =
+           if j >= len then invalid_integer fmt j else
+           match fmt.[j] with
+           | '0' .. '9' | '-' -> get (succ j)
+           | _ ->
+             let size =
+             if j = i then size_of_int 0 else
+                format_int_of_string fmt j (String.sub fmt i (j - i)) in
+             c size n j in
+          get i
+
+      and skip_gt i =
+       if i >= len then invalid_format fmt i else
+       match fmt.[i] with
+       | ' ' -> skip_gt (succ i)
+       | '>' -> succ i
+       | _ -> invalid_format fmt i
+
+      and get_box_kind i =
+       if i >= len then Pp_box, i else
+       match fmt.[i] with
+       | 'h' ->
+          let i = succ i in
+          if i >= len then Pp_hbox, i else
+          begin match fmt.[i] with
+          | 'o' ->
+             let i = succ i in
+             if i >= len then format_invalid_arg "bad box format" fmt i else
+             begin match fmt.[i] with
+             | 'v' -> Pp_hovbox, succ i
+             | c ->
+                format_invalid_arg
+                  ("bad box name ho" ^ String.make 1 c) fmt i end
+          | 'v' -> Pp_hvbox, succ i
+          | c -> Pp_hbox, i
+          end
+       | 'b' -> Pp_box, succ i
+       | 'v' -> Pp_vbox, succ i
+       | _ -> Pp_box, i
+
+      and get_tag_name n i c =
+       let rec get accu n i j =
+        if j >= len
+        then c (implode_rev (String.sub fmt i (j - i)) accu) n j else
+        match fmt.[j] with
+        | '>' -> c (implode_rev (String.sub fmt i (j - i)) accu) n j
+        | '%' ->
+          let s0 = String.sub fmt i (j - i) in
+          let cont_s n s i = get (s :: s0 :: accu) n i i
+          and cont_a n printer arg i =
+            let s =
+              if str
+              then (Obj.magic printer : unit -> _ -> string) () arg
+              else exstring printer arg in
+            get (s :: s0 :: accu) n i i
+          and cont_t n printer i =
+            let s =
+              if str
+              then (Obj.magic printer : unit -> string) ()
+              else exstring (fun ppf () -> printer ppf) () in
+            get (s :: s0 :: accu) n i i
+          and cont_f n i =
+            format_invalid_arg "bad tag name specification" fmt i
+          and cont_m n sfmt i =
+            format_invalid_arg "bad tag name specification" fmt i in
+          Printf.scan_format fmt v n j cont_s cont_a cont_t cont_f cont_m
+        | c -> get accu n i (succ j) in
+       get [] n i i
+
+      and do_pp_break ppf n i =
+       if i >= len then begin pp_print_space ppf (); doprn n i end else
+       match fmt.[i] with
+       | '<' ->
+          let rec got_nspaces nspaces n i =
+            get_int n i (got_offset nspaces)
+          and got_offset nspaces offset n i =
+            pp_print_break ppf (int_of_size nspaces) (int_of_size offset);
+            doprn n (skip_gt i) in
+          get_int n (succ i) got_nspaces
+       | c -> pp_print_space ppf (); doprn n i
+
+      and do_pp_open_box ppf n i =
+       if i >= len then begin pp_open_box_gen ppf 0 Pp_box; doprn n i end else
+       match fmt.[i] with
+       | '<' ->
+          let kind, i = get_box_kind (succ i) in
+          let got_size size n i =
+            pp_open_box_gen ppf (int_of_size size) kind;
+            doprn n (skip_gt i) in
+          get_int n i got_size
+       | c -> pp_open_box_gen ppf 0 Pp_box; doprn n i
+
+      and do_pp_open_tag ppf n i =
+       if i >= len then begin pp_open_tag ppf ""; doprn n i end else
+       match fmt.[i] with
+       | '<' ->
+          let got_name tag_name n i =
+            pp_open_tag ppf tag_name;
+            doprn n (skip_gt i) in
+          get_tag_name n (succ i) got_name
+       | c -> pp_open_tag ppf ""; doprn n i in
+
+      doprn (Printf.index_of_int 0) 0 in
+
+   Printf.kapr kpr fmt in
+
+  kprintf;;
+
+(**************************************************************
+
+  Defining [fprintf] and various flavors of [fprintf].
+
+ **************************************************************)
+
+let kfprintf k ppf = mkprintf false (fun _ -> ppf) k;;
+
+let fprintf ppf = kfprintf ignore ppf;;
+let printf fmt = fprintf std_formatter fmt;;
+let eprintf fmt = fprintf err_formatter fmt;;
+
+let kbprintf k b =
+  mkprintf false (fun _ -> formatter_of_buffer b) k;;
+
+let bprintf b = kbprintf ignore b;;
+
+let ksprintf k =
+  let b = Buffer.create 512 in
+  let k ppf = k (string_out b ppf) in
+  mkprintf true (fun _ -> formatter_of_buffer b) k;;
+
+let kprintf = ksprintf;;
+
+let sprintf fmt = ksprintf (fun s -> s) fmt;;
+
+at_exit print_flush;;
diff --git a/app/server/vendor/rouge/spec/visual/samples/perl b/app/server/vendor/rouge/spec/visual/samples/perl
new file mode 100755
index 0000000..4e3c548
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/perl
@@ -0,0 +1,187 @@
+#! /usr/bin/env perl
+
+#### regex_delimiters
+
+use strict;
+use warnings;
+
+# common delimiters
+print "a: ";
+my $a = "foo";
+print $a, " - ";
+$a =~ s/foo/bar/;
+print $a, "\n";
+
+print "b: ";
+my $b = "foo";
+print $b, " - ";
+$b =~ s!foo!bar!;
+print $b, "\n";
+
+print "c: ";
+my $c = "foo";
+print $c, " - ";
+$c =~ s at foo@bar@;
+print $c, "\n";
+
+print "d: ";
+my $d = "foo";
+print $d, " - ";
+$d =~ s\foo\bar\;
+print $d, "\n";
+
+print "\n";
+
+# balanced delimiters
+print "e: ";
+my $e = "foo";
+print $e, " - ";
+$e =~ s{foo}{bar};
+print $e, "\n";
+
+print "f: ";
+my $f = "foo";
+print $f, " - ";
+$f =~ s(foo)(bar);
+print $f, "\n";
+
+print "g: ";
+my $g = "foo";
+print $g, " - ";
+$g =~ s<foo><bar>;
+print $g, "\n";
+
+print "h: ";
+my $h = "foo";
+print $h, " - ";
+$h =~ s[foo][bar];
+print $h, "\n";
+
+print "\n";
+
+# balanced delimiters with whitespace
+print "i: ";
+my $i = "foo";
+print $i, " - ";
+$i =~ s{foo} {bar};
+print $i, "\n";
+
+print "j: ";
+my $j = "foo";
+print $j, " - ";
+$j =~ s<foo>		<bar>;
+print $j, "\n";
+
+print "k: ";
+my $k = "foo";
+print $k, " - ";
+$k =~
+	s(foo)
+
+	(bar);
+print $k, "\n";
+
+print "\n";
+
+# mixed delimiters
+print "l: ";
+my $l = "foo";
+print $l, " - ";
+$l =~ s{foo} <bar>;
+print $l, "\n";
+
+print "m: ";
+my $m = "foo";
+print $m, " - ";
+$m =~ s(foo) !bar!;
+print $m, "\n";
+
+print "n: ";
+my $n = "foo";
+print $n, " - ";
+$n =~ s[foo] $bar$;
+print $n, "\n";
+
+print "\n";
+
+# /x modifier
+print "o: ";
+my $o = "foo";
+print $o, " - ";
+$o =~ s{
+				foo
+			 } {bar}x;
+print $o, "\n";
+
+print "p: ";
+my $p = "foo";
+print $p, " - ";
+$p =~ s%
+  foo
+  %bar%x;
+print $p, "\n";
+
+###### perl_misc ########
+
+# from http://gist.github.com/485595
+use strict;
+use warnings;
+use Time::HiRes 'usleep';
+
+for (1..5) {
+    open my $in, '<', '/proc/sys/kernel/random/entropy_avail' or die;
+    print <$in>;
+    close $in;
+    usleep 100_000;
+}
+
+# other miscellaneous tests of numbers separated by _
+#usleep 100_000;
+100_000_000;
+my $nichts = 0.005_006;
+print "$nichts\n";
+my $nichts2 = 0.005_006_007;
+print 900_800_700.005_006_007, $/;
+
+# numbers from `man 1 perlnumber`
+my $n;
+$n = 1234;              # decimal integer
+$n = 0b1110011;         # binary integer
+$n = 01234;             # octal integer
+$n = 0x1234;            # hexadecimal integer
+$n = 12.34e-56;         # exponential notation
+$n = "-12.34e56";       # number specified as a string
+$n = "1234";            # number specified as a string
+
+# other numbers
+for (
+    -9876,
+    +8765,
+    -9876.02,
+    -9876.02e+10,
+    +765_432e30,
+    2002.,
+    .2002,
+) {
+    print $_, "\n";
+}
+
+# operators on numbers
+for (
+    $n + 300,
+    $n - 300,
+    $n / 300 + 10,
+    $n * 250 / 2.0,
+    $n == 100,
+    $n != 100,
+    $n > 100,
+    $n >= 100,
+    $n < 100,
+    $n <= 100,
+    $n % 2,
+    abs $n,
+) {
+    print $_, "\n";
+}
+
+
diff --git a/app/server/vendor/rouge/spec/visual/samples/php b/app/server/vendor/rouge/spec/visual/samples/php
new file mode 100755
index 0000000..2566e48
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/php
@@ -0,0 +1,524 @@
+<p>It's html outside php!</p>
+<?php
+
+$test = function($a) { $lambda = 1; }
+
+?><a href="<?= $url ?>">I can close php tags and get html!</a><?php
+
+/** snippet from wordpress */
+if (! isset($wp_did_header)):
+if ( !file_exists( dirname(__FILE__) . '/wp-config.php') ) {
+    if ( strstr( $_SERVER['PHP_SELF'], 'wp-admin') ) $path = '';
+    else $path = 'wp-admin/';
+    die("There doesn't seem to be a <code>wp-config.php</code>" .
+        "file. I need this before we can get started. Need more" .
+        "help? <a href='http://wordpress.org/docs/faq/#wp-config'>We" .
+        "got it</a>. You can <a href='{$path}setup-config.php'>create" .
+        "a <code>wp-config.php</code> file through a web interface</a>," .
+        "but this doesn't work for all server setups. The safest way is" .
+        "to manually create the file."
+    );
+}
+
+/**
+ *  Zip class file
+ *
+ *  @package     fnord.bb
+ *  @subpackage  archive
+ */
+
+// Unlock?
+if(!defined('UNLOCK') || !UNLOCK)
+  die();
+  
+// Load the parent archive class
+require_once(ROOT_PATH.'/classes/archive.class.php');
+
+class Zip\Zipp {
+
+}
+
+/**
+ *  Zip class
+ *
+ *  @author      Manni <manni at fnord.name>
+ *  @copyright   Copyright (c) 2006, Manni
+ *  @version     1.0
+ *  @link        http://www.pkware.com/business_and_developers/developer/popups/appnote.txt
+ *  @link        http://mannithedark.is-a-geek.net/
+ *  @since       1.0
+ *  @package     fnord.bb
+ *  @subpackage  archive
+ */
+class Zip extends Archive {
+ /**
+  *  Outputs the zip file
+  *
+  *  This function creates the zip file with the dirs and files given.
+  *  If the optional parameter $file is given, the zip file is will be
+  *  saved at that location. Otherwise the function returns the zip file's content.
+  *
+  *  @access                   public
+  *
+  *  @link                     http://www.pkware.com/business_and_developers/developer/popups/appnote.txt
+  *  @param  string $filename  The path where the zip file will be saved
+  *
+  *  @return bool|string       Returns either true if the fil is sucessfully created or the content of the zip file
+  */
+  function out($filename = false) {
+    // Empty output
+    $file_data = array(); // Data of the file part
+    $cd_data   = array(); // Data of the central directory
+
+    // Sort dirs and files by path length
+    uksort($this->dirs,  'sort_by_length');
+    uksort($this->files, 'sort_by_length');
+
+    // Handle dirs
+    foreach($this->dirs as $dir) {
+      $dir .= '/';
+      // File part
+
+      // Reset dir data
+      $dir_data = '';
+
+      // Local file header
+      $dir_data .= "\x50\x4b\x03\x04";      // Local file header signature
+      $dir_data .= pack("v", 10);           // Version needed to extract
+      $dir_data .= pack("v", 0);            // General purpose bit flag
+      $dir_data .= pack("v", 0);            // Compression method
+      $dir_data .= pack("v", 0);            // Last mod file time
+      $dir_data .= pack("v", 0);            // Last mod file date
+      $dir_data .= pack("V", 0);            // crc-32
+      $dir_data .= pack("V", 0);            // Compressed size
+      $dir_data .= pack("V", 0);            // Uncompressed size
+      $dir_data .= pack("v", strlen($dir)); // File name length
+      $dir_data .= pack("v", 0);            // Extra field length
+
+      $dir_data .= $dir;                    // File name
+      $dir_data .= '';                      // Extra field (is empty)
+
+      // File data
+      $dir_data .= '';                      // Dirs have no file data
+
+      // Data descriptor
+      $dir_data .= pack("V", 0);            // crc-32
+      $dir_data .= pack("V", 0);            // Compressed size
+      $dir_data .= pack("V", 0);            // Uncompressed size
+
+      // Save current offset
+      $offset = strlen(implode('', $file_data));
+
+      // Append dir data to the file part
+      $file_data[] = $dir_data;
+
+      // Central directory
+
+      // Reset dir data
+      $dir_data = '';
+
+      // File header
+      $dir_data .= "\x50\x4b\x01\x02";      // Local file header signature
+      $dir_data .= pack("v", 0);            // Version made by
+      $dir_data .= pack("v", 10);           // Version needed to extract
+      $dir_data .= pack("v", 0);            // General purpose bit flag
+      $dir_data .= pack("v", 0);            // Compression method
+      $dir_data .= pack("v", 0);            // Last mod file time
+      $dir_data .= pack("v", 0);            // Last mod file date
+      $dir_data .= pack("V", 0);            // crc-32
+      $dir_data .= pack("V", 0);            // Compressed size
+      $dir_data .= pack("V", 0);            // Uncompressed size
+      $dir_data .= pack("v", strlen($dir)); // File name length
+      $dir_data .= pack("v", 0);            // Extra field length
+      $dir_data .= pack("v", 0);            // File comment length
+      $dir_data .= pack("v", 0);            // Disk number start
+      $dir_data .= pack("v", 0);            // Internal file attributes
+      $dir_data .= pack("V", 16);           // External file attributes
+      $dir_data .= pack("V", $offset);      // Relative offset of local header
+
+      $dir_data .= $dir;                    // File name
+      $dir_data .= '';                      // Extra field (is empty)
+      $dir_data .= '';                      // File comment (is empty)
+
+      /*
+      // Data descriptor
+      $dir_data .= pack("V", 0);            // crc-32
+      $dir_data .= pack("V", 0);            // Compressed size
+      $dir_data .= pack("V", 0);            // Uncompressed size
+      */
+      
+      // Append dir data to the central directory data
+      $cd_data[] = $dir_data;
+    }
+
+    // Handle files
+    foreach($this->files as $name => $file) {
+      // Get values
+      $content = $file[0];
+    
+      // File part
+
+      // Reset file data
+      $fd = '';
+      
+      // Detect possible compressions
+      // Use deflate
+      if(function_exists('gzdeflate')) {
+        $method = 8;
+
+        // Compress file content
+        $compressed_data = gzdeflate($content);
+
+      // Use bzip2
+      } elseif(function_exists('bzcompress')) {
+        $method = 12;
+
+        // Compress file content
+        $compressed_data = bzcompress($content);
+
+      // No compression
+      } else {
+        $method = 0;
+
+        // Do not compress the content :P
+        $compressed_data = $content;
+      }
+
+      // Local file header
+      $fd .= "\x50\x4b\x03\x04";                  // Local file header signature
+      $fd .= pack("v", 20);                       // Version needed to extract
+      $fd .= pack("v", 0);                        // General purpose bit flag
+      $fd .= pack("v", $method);                  // Compression method
+      $fd .= pack("v", 0);                        // Last mod file time
+      $fd .= pack("v", 0);                        // Last mod file date
+      $fd .= pack("V", crc32($content));          // crc-32
+      $fd .= pack("V", strlen($compressed_data)); // Compressed size
+      $fd .= pack("V", strlen($content));         // Uncompressed size
+      $fd .= pack("v", strlen($name));            // File name length
+      $fd .= pack("v", 0);                        // Extra field length
+
+      $fd .= $name;                               // File name
+      $fd .= '';                                  // Extra field (is empty)
+
+      // File data
+      $fd .= $compressed_data;
+      
+      // Data descriptor
+      $fd .= pack("V", crc32($content));          // crc-32
+      $fd .= pack("V", strlen($compressed_data)); // Compressed size
+      $fd .= pack("V", strlen($content));         // Uncompressed size
+
+      // Save current offset
+      $offset = strlen(implode('', $file_data));
+
+      // Append file data to the file part
+      $file_data[] = $fd;
+
+      // Central directory
+
+      // Reset file data
+      $fd = '';
+
+      // File header
+      $fd .= "\x50\x4b\x01\x02";                  // Local file header signature
+      $fd .= pack("v", 0);                        // Version made by
+      $fd .= pack("v", 20);                       // Version needed to extract
+      $fd .= pack("v", 0);                        // General purpose bit flag
+      $fd .= pack("v", $method);                  // Compression method
+      $fd .= pack("v", 0);                        // Last mod file time
+      $fd .= pack("v", 0);                        // Last mod file date
+      $fd .= pack("V", crc32($content));          // crc-32
+      $fd .= pack("V", strlen($compressed_data)); // Compressed size
+      $fd .= pack("V", strlen($content));         // Uncompressed size
+      $fd .= pack("v", strlen($name));            // File name length
+      $fd .= pack("v", 0);                        // Extra field length
+      $fd .= pack("v", 0);                        // File comment length
+      $fd .= pack("v", 0);                        // Disk number start
+      $fd .= pack("v", 0);                        // Internal file attributes
+      $fd .= pack("V", 32);                       // External file attributes
+      $fd .= pack("V", $offset);                  // Relative offset of local header
+
+      $fd .= $name;                               // File name
+      $fd .= '';                                  // Extra field (is empty)
+      $fd .= '';                                  // File comment (is empty)
+
+      /*
+      // Data descriptor
+      $fd .= pack("V", crc32($content));          // crc-32
+      $fd .= pack("V", strlen($compressed_data)); // Compressed size
+      $fd .= pack("V", strlen($content));         // Uncompressed size
+      */
+
+      // Append file data to the central directory data
+      $cd_data[] = $fd;
+    }
+
+    // Digital signature
+    $digital_signature = '';
+    $digital_signature .= "\x50\x4b\x05\x05";  // Header signature
+    $digital_signature .= pack("v", 0);        // Size of data
+    $digital_signature .= '';                  // Signature data (is empty)
+
+    $tmp_file_data = implode('', $file_data);  // File data
+    $tmp_cd_data   = implode('', $cd_data).    // Central directory
+                     $digital_signature;       // Digital signature
+
+    // End of central directory
+    $eof_cd = '';
+    $eof_cd .= "\x50\x4b\x05\x06";                // End of central dir signature
+    $eof_cd .= pack("v", 0);                      // Number of this disk
+    $eof_cd .= pack("v", 0);                      // Number of the disk with the start of the central directory
+    $eof_cd .= pack("v", count($cd_data));        // Total number of entries in the central directory on this disk
+    $eof_cd .= pack("v", count($cd_data));        // Total number of entries in the central directory
+    $eof_cd .= pack("V", strlen($tmp_cd_data));   // Size of the central directory
+    $eof_cd .= pack("V", strlen($tmp_file_data)); // Offset of start of central directory with respect to the starting disk number
+    $eof_cd .= pack("v", 0);                      // .ZIP file comment length
+    $eof_cd .= '';                                // .ZIP file comment (is empty)
+
+    // Content of the zip file
+    $data = $tmp_file_data.
+            // $extra_data_record.
+            $tmp_cd_data.
+            $eof_cd;
+
+    // Return content?
+    if(!$filename)
+      return $data;
+      
+    // Write to file
+    return file_put_contents($filename, $data);
+  }
+  
+ /**
+  *  Load a zip file
+  *
+  *  This function loads the files and dirs from a zip file from the harddrive.
+  *
+  *  @access                public
+  *
+  *  @param  string $file   The path to the zip file
+  *  @param  bool   $reset  Reset the files and dirs before adding the zip file's content?
+  *
+  *  @return bool           Returns true if the file was loaded sucessfully
+  */
+  function load_file($file, $reset = true) {
+    // Check whether the file exists
+    if(!file_exists($file))
+      return false;
+
+    // Load the files content
+    $content = @file_get_contents($file);
+
+    // Return false if the file cannot be opened
+    if(!$content)
+      return false;
+
+    // Read the zip
+    return $this->load_string($content, $reset);
+  }
+  
+ /**
+  *  Load a zip string
+  *
+  *  This function loads the files and dirs from a string
+  *
+  *  @access                 public
+  *
+  *  @param  string $string  The string the zip is generated from
+  *  @param  bool   $reset   Reset the files and dirs before adding the zip file's content?
+  *
+  *  @return bool            Returns true if the string was loaded sucessfully
+  */
+  function load_string($string, $reset = true) {
+    // Reset the zip?
+    if($reset) {
+      $this->dirs  = array();
+      $this->files = array();
+    }
+
+    // Get the starting position of the end of central directory record
+    $start = strpos($string, "\x50\x4b\x05\x06");
+
+    // Error
+    if($start === false)
+      die('Could not find the end of central directory record');
+
+    // Get the ecdr
+    $eof_cd = substr($string, $start+4, 18);
+
+    // Unpack the ecdr infos
+    $eof_cd = unpack('vdisc1/'.
+                     'vdisc2/'.
+                     'ventries1/'.
+                     'ventries2/'.
+                     'Vsize/'.
+                     'Voffset/'.
+                     'vcomment_lenght', $eof_cd);
+
+    // Do not allow multi disc zips
+    if($eof_cd['disc1'] != 0)
+      die('multi disk stuff is not yet implemented :/');
+
+    // Save the interesting values
+    $cd_entries = $eof_cd['entries1'];
+    $cd_size    = $eof_cd['size'];
+    $cd_offset  = $eof_cd['offset'];
+
+    // Get the central directory record
+    $cdr = substr($string, $cd_offset, $cd_size);
+
+    // Reset the position and the list of the entries
+    $pos     = 0;
+    $entries = array();
+
+    // Handle cdr
+    while($pos < strlen($cdr)) {
+      // Check header signature
+      // Digital signature
+      if(substr($cdr, $pos, 4) == "\x50\x4b\x05\x05") {
+        // Get digital signature size
+        $tmp_info = unpack('vsize', substr($cdr, $pos + 4, 2));
+
+        // Read out the digital signature
+        $digital_sig = substr($header, $pos + 6, $tmp_info['size']);
+
+        break;
+      }
+
+      // Get file header
+      $header = substr($cdr, $pos, 46);
+
+      // Unpack the header information
+      $header_info = @unpack('Vheader/'.
+                             'vversion_made_by/'.
+                             'vversion_needed/'.
+                             'vgeneral_purpose/'.
+                             'vcompression_method/'.
+                             'vlast_mod_time/'.
+                             'vlast_mod_date/'.
+                             'Vcrc32/'.
+                             'Vcompressed_size/'.
+                             'Vuncompressed_size/'.
+                             'vname_length/'.
+                             'vextra_length/'.
+                             'vcomment_length/'.
+                             'vdisk_number/'.
+                             'vinternal_attributes/'.
+                             'Vexternal_attributes/'.
+                             'Voffset',
+                             $header);
+
+      // Valid header?
+      if($header_info['header'] != 33639248)
+        return false;
+
+      // New position
+      $pos += 46;
+
+      // Read out the file name
+      $header_info['name'] = substr($cdr, $pos, $header_info['name_length']);
+
+      // New position
+      $pos += $header_info['name_length'];
+
+      // Read out the extra stuff
+      $header_info['extra'] = substr($cdr, $pos, $header_info['extra_length']);
+
+      // New position
+      $pos += $header_info['extra_length'];
+
+      // Read out the comment
+      $header_info['comment'] = substr($cdr, $pos, $header_info['comment_length']);
+
+      // New position
+      $pos += $header_info['comment_length'];
+
+      // Append this file/dir to the entry list
+      $entries[] = $header_info;
+    }
+
+    // Check whether all entries where read sucessfully
+    if(count($entries) != $cd_entries)
+      return false;
+
+    // Handle files/dirs
+    foreach($entries as $entry) {
+      // Is a dir?
+      if($entry['external_attributes'] & 16) {
+        $this->add_dir($entry['name']);
+        continue;
+      }
+
+      // Get local file header
+      $header = substr($string, $entry['offset'], 30);
+
+      // Unpack the header information
+      $header_info = @unpack('Vheader/'.
+                             'vversion_needed/'.
+                             'vgeneral_purpose/'.
+                             'vcompression_method/'.
+                             'vlast_mod_time/'.
+                             'vlast_mod_date/'.
+                             'Vcrc32/'.
+                             'Vcompressed_size/'.
+                             'Vuncompressed_size/'.
+                             'vname_length/'.
+                             'vextra_length',
+                             $header);
+
+      // Valid header?
+      if($header_info['header'] != 67324752)
+        return false;
+
+      // Get content start position
+      $start = $entry['offset'] + 30 + $header_info['name_length'] + $header_info['extra_length'];
+
+      // Get the compressed data
+      $data = substr($string, $start, $header_info['compressed_size']);
+
+      // Detect compression type
+      switch($header_info['compression_method']) {
+        // No compression
+        case 0:
+          // Ne decompression needed
+          $content = $data;
+          break;
+
+        // Gzip
+        case 8:
+          if(!function_exists('gzinflate'))
+            return false;
+
+          // Uncompress data
+          $content = gzinflate($data);
+          break;
+
+        // Bzip2
+        case 12:
+          if(!function_exists('bzdecompress'))
+            return false;
+
+          // Decompress data
+          $content = bzdecompress($data);
+          break;
+
+        // Compression not supported -> error
+        default:
+          return false;
+      }
+
+      // Try to add file
+      if(!$this->add_file($entry['name'], $content))
+        return false;
+    }
+
+    return true;
+  }
+}
+
+function &byref() {
+    $x = array();
+    return $x;
+}
+?>
+<p>it's html here at the end, too.</p>
diff --git a/app/server/vendor/rouge/spec/visual/samples/plaintext b/app/server/vendor/rouge/spec/visual/samples/plaintext
new file mode 100755
index 0000000..a43a006
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/plaintext
@@ -0,0 +1,11 @@
+1
+2
+3
+4
+5
+6
+7
+
+Lorem Ipsum and et cetera.
+
+This is just plain text, no highlighting here.
diff --git a/app/server/vendor/rouge/spec/visual/samples/prolog b/app/server/vendor/rouge/spec/visual/samples/prolog
new file mode 100755
index 0000000..cafef34
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/prolog
@@ -0,0 +1,81 @@
+# Atoms
+
+x
+blue
+'Burrito'
+'some atom'
+
+# Numbers
+
+1
+123123123123
+12312.1231
+0.1
+
+# Variables
+
+Hello
+How_are_you_doing
+_amazing
+Wow123
+
+# Compound terms
+
+truck_year('Mazda', 1986)
+'Person_Friends'(zelda,[tom,jim])
+
+# List
+
+[]
+[1,2,3]
+[red,green,blue]
+
+# Strings
+
+"to be, or not to be"
+"東京都"
+
+# This example was taken from
+# http://en.wikipedia.org/wiki/Prolog#Turing_completeness
+turing(Tape0, Tape) :-
+    perform(q0, [], Ls, Tape0, Rs),
+    reverse(Ls, Ls1),
+    append(Ls1, Rs, Tape).
+
+/*
+*
+ * This is a multiline comment.
+*/
+
+perform(qf, Ls, Ls, Rs, Rs) :- !.
+perform(Q0, Ls0, Ls, Rs0, Rs) :-
+    symbol(Rs0, Sym, RsRest),
+    once(rule(Q0, Sym, Q1, NewSym, Action)),
+    action(Action, Ls0, Ls1, [NewSym|RsRest], Rs1),
+    perform(Q1, Ls1, Ls, Rs1, Rs).
+
+symbol([], b, []).
+symbol([Sym|Rs], Sym, Rs).
+
+action(left, Ls0, Ls, Rs0, Rs) :- left(Ls0, Ls, Rs0, Rs).
+action(stay, Ls, Ls, Rs, Rs).
+action(right, Ls0, [Sym|Ls0], [Sym|Rs], Rs).
+
+left([], [], Rs0, [b|Rs0]).
+left([L|Ls], Ls, Rs, [L|Rs]).
+
+## Example from pygments
+
+partition([], _, [], []).
+partition([X|Xs], Pivot, Smalls, Bigs) :-
+    (   X @< Pivot ->
+        Smalls = [X|Rest],
+        partition(Xs, Pivot, Rest, Bigs)
+    ;   Bigs = [X|Rest],
+        partition(Xs, Pivot, Smalls, Rest)
+    ).
+
+quicksort([])     --> [].
+quicksort([X|Xs]) --> 
+    { partition(Xs, X, Smaller, Bigger) },
+    quicksort(Smaller), [X], quicksort(Bigger).
diff --git a/app/server/vendor/rouge/spec/visual/samples/properties b/app/server/vendor/rouge/spec/visual/samples/properties
new file mode 100755
index 0000000..3e124b8
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/properties
@@ -0,0 +1,16 @@
+# You are reading the ".properties" entry.
+! The exclamation mark can also mark text as comments.
+# The key and element characters #, !, =, and : are written with
+# a preceding backslash to ensure that they are properly loaded.
+website = http\://en.wikipedia.org/
+language = English
+# The backslash below tells the application to continue reading
+# the value onto the next line.
+message = Welcome to \
+          Wikipedia\!
+# Add spaces to the key
+key\ with\ spaces = This is the value that could be looked up with the key "key with spaces".
+# Add dots to the key
+key.with.dots = This is the value that could be looked up with the key "key.with.dots".
+# Unicode
+tab : \u0009
\ No newline at end of file
diff --git a/app/server/vendor/rouge/spec/visual/samples/puppet b/app/server/vendor/rouge/spec/visual/samples/puppet
new file mode 100755
index 0000000..e9451f7
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/puppet
@@ -0,0 +1,12 @@
+node /www\.example\.com/ {
+  include foo::bar
+
+  file {"foo.txt":
+    require +> Thing::Package["bar-package"],
+    contents => case $::operatingsystem {
+      /Linux/: $linux_contents,
+      /Windows/: $windows_module::windows_contents,
+      default: undef
+    }
+  }
+}
diff --git a/app/server/vendor/rouge/spec/visual/samples/python b/app/server/vendor/rouge/spec/visual/samples/python
new file mode 100755
index 0000000..480ec24
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/python
@@ -0,0 +1,96 @@
+def lex(code, lexer):
+    """
+    Lex ``code`` with ``lexer`` and return an iterable of tokens.
+    """
+    try:
+        return lexer.get_tokens(code)
+    except TypeError, err:
+        if isinstance(err.args[0], str) and \
+           'unbound method get_tokens' in err.args[0]:
+            raise TypeError('lex() argument must be a lexer instance, '
+                            'not a class')
+        raise
+
+# quotes in strings
+def foo():
+    "it's working"
+
+def foo():
+    'he said "hi"'
+
+def foo():
+    """it's working"""
+    """he said "hi" """
+
+def foo():
+    '''he said "hi"'''
+    '''it's working'''
+
+# unicode docstrings
+def foo():
+    ur"""unicode-raw"""
+
+def bar():
+    u"""unicode"""
+
+def baz():
+    r'raw'
+
+def zap():
+    """docstring"""
+
+# line continuations
+apple.filter(x, y)
+apple.\
+    filter(x, y)
+
+1 \
+    . \
+    __str__
+
+from os import path
+from \
+        os \
+        import \
+        path
+
+import os.path as something
+
+import \
+        os.path \
+        as \
+        something
+
+class \
+ Spam:
+    pass
+
+class Spam: pass
+
+class Spam(object):
+    pass
+
+class \
+ Spam \
+  (
+   object
+ ) \
+ :
+ pass
+
+
+def \
+ spam \
+  ( \
+  ) \
+  : \
+  pass
+
+def the_word_strand():
+    a = b.strip()
+    a = strand
+    b = band
+    c = strand
+    b = error
+    c = stror
+    c = string
diff --git a/app/server/vendor/rouge/spec/visual/samples/qml b/app/server/vendor/rouge/spec/visual/samples/qml
new file mode 100755
index 0000000..e88dd12
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/qml
@@ -0,0 +1,77 @@
+import QtQuick 2.0
+import QtQuick.Controls 1.0 as Controls
+import 'logic.js' as Logic
+
+Item {
+    // id
+    id: root
+
+    // property
+    width: 128; height: 64
+    enabled: true
+    objectName: 'rootItem'
+    anchors.centerIn: parent
+    // property (spaced)
+    opacity  :  1.0
+
+    // property definitions
+    property var value
+    property int number: 10
+    property bool checked: false
+    property string text: 'Root Item'
+    property var regex: /button/
+    property var color: checked ? '#000000' : '#FFFFFF'
+
+    // default property
+    default property var textItem
+
+    // signal
+    signal pressed
+    signal clicked()
+    signal clickedAt(int x, int y, string text)
+
+    // object property
+    property var object: QtObject {
+        objectName: "object"
+        property var value
+        function action() {
+            console.log('action')
+        }
+    }
+
+    // value source
+    NumberAnimation on opacity {
+        id: animation
+        from: 0.0
+        to: 1.0
+    }
+    // inline object
+    Text { text: root.text }
+
+    // qualified type
+    Controls.Button { text: 'button' }
+
+    // function
+    function startAnimation(duration) {
+        animation.duration = duration
+        animation.start()
+    }
+
+    // signal handler
+    onClickedAt: {
+        if (x === 10 && y === 10) {
+          console.log('clicked at x=10, y=10')
+        }
+    }
+
+    // attached signal handler
+    Component.onCompleted: {
+        console.log('completed')
+    }
+
+    // states
+    states: [
+        State { name: 'default' },
+        State { name: 'pressed' }
+    ]
+}
diff --git a/app/server/vendor/rouge/spec/visual/samples/r b/app/server/vendor/rouge/spec/visual/samples/r
new file mode 100755
index 0000000..5432533
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/r
@@ -0,0 +1,153 @@
+#!/usr/bin/env Rscript
+### Example R script for syntax highlighting
+
+# This is also a comment
+
+## Valid names
+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV0123456789._a <- NULL
+.foo_ <- NULL
+._foo <- NULL
+
+## Invalid names
+0abc <- NULL
+.0abc <- NULL
+abc+cde <- NULL
+
+## Reserved Words
+NA
+NA_integer_
+NA_real_
+NA_character_
+NA_complex_
+NULL
+NaN
+Inf
+## Not reserved
+NULLa <- NULL
+NULL1 <- NULL
+NULL. <- NULL
+NA_foo_ <- NULL
+
+## Numbers
+12345678901
+123456.78901
+123e3
+123E3
+1.23e-3
+1.23e3
+1.23e-3
+## integer constants
+123L
+1.23L
+## imaginary numbers
+123i
+-123i
+123e4i
+123e-4i
+## Hex numbers
+0xabcdefABCDEF01234
+0xabcp123
+0xabcP123
+## Not hex
+0xg
+
+## Special operators %xyz%
+## %xyz%
+1 %% 2
+diag(2) %*% diag(2)
+1 %/% 2
+1 %in% 1:10
+diag(2) %o% diag(2)
+diag(2) %x% diag(2)
+`%foo bar%` <- function(x, y) x + y
+1 %foo bar% 2
+
+## Control Structures (3.2) and Function
+## if, else
+if (TRUE) print("foo") else print("bar")
+## For, in
+for(i in 1:5) {
+    print(i)
+}
+## While, break
+i <- 1
+while (TRUE) {
+    i <- i + 1
+    if (i > 3) break
+}
+## Repeat
+repeat {1+1}
+## Switch
+x <- 3
+switch(x, 2+2, mean(1:10), rnorm(5))
+## Function, dot-dot-dot, return
+foo <- function(...) {
+    return(sum(...))
+}
+# Not keywords
+functiona <- 2 + 2
+function. <- 2 + 2
+function1 <- 2 + 2
+
+
+## Grouping Tokens 10.3.7
+## Parentheses
+1 + (2 + 3)
+## brackets
+foo <- function(a) {
+    a + 1
+}
+
+## Indexing 10.3.8
+## []
+bar <- 1:10
+bar[3]
+## [[]]
+foo <- list(a=1, b=2, c=3)
+foo[["a"]]
+## $
+foo$a
+foo$"a"
+
+## Operators
+2 - 2
+2 + 2
+2 ~ 2
+! TRUE
+?"help"
+1:2
+2 * 2
+2 / 2
+2^2
+2 < 2
+2 > 2
+2 == 2
+2 >= 2
+2 <= 2
+2 != 2
+TRUE & FALSE
+TRUE && FALSE
+TRUE | FALSE
+TRUE || FALSE
+foo <- 2 + 2
+foo = 2 + 2
+2 + 2 -> foo
+foo <<- 2 + 2
+2 + 2 ->> foo
+base:::sum
+base::sum
+
+## Strings
+foo <- "hello, world!"
+foo <- 'hello, world!'
+foo <- "Hello, 'world!"
+foo <- 'Hello, "world!'
+foo <- 'Hello, \'world!\''
+foo <- "Hello, \"world!\""
+foo <- "Hello,
+world!"
+foo <- 'Hello,
+world!'
+
+## Backtick strings
+`foo123 +!"bar'baz` <- 2 + 2
diff --git a/app/server/vendor/rouge/spec/visual/samples/racket b/app/server/vendor/rouge/spec/visual/samples/racket
new file mode 100755
index 0000000..9887372
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/racket
@@ -0,0 +1,326 @@
+#lang racket
+
+;; Single-line comment
+
+#| Multi-line comment on one line |#
+
+#| Multi-line comment on
+   two lines |#
+
+'symbol
+`symbol
+'(a quoted list)
+`(a quasiquoted expr with ,unquasiquoted item)
+#:keyword
+-inf.f
++inf.f
+-inf.0
++inf.0
+-min.0
++max.0
+-nan.0
++nan.0
+
+(define (1-crazy-identifier-疯狂的标识符-τρελό-αναγνωριστικό x)
+  (add1 x))
+(check-equal? (1-crazy-identifier-疯狂的标识符-τρελό-αναγνωριστικό 1) 2)
+
+(require xml net/url
+         racket/control) ;; <<< new import
+
+(define (serve port-no)
+  (define main-cust (make-custodian))
+  (parameterize ([current-custodian main-cust])
+    (define listener (tcp-listen port-no 5 #t))
+    (define (loop)
+      (accept-and-handle listener)
+      (loop))
+    (thread loop))
+  (λ ()
+    (custodian-shutdown-all main-cust)))
+
+(define (accept-and-handle listener)
+  (define cust (make-custodian))
+  (custodian-limit-memory cust (* 50 1024 1024))
+  (parameterize ([current-custodian cust])
+    (define-values (in out) (tcp-accept listener))
+    (thread (λ ()
+              (handle in out)
+              (close-input-port in)
+              (close-output-port out))))
+  ;; Watcher thread:
+  (thread (λ ()
+            (sleep 10)
+            (custodian-shutdown-all cust))))
+
+(define (handle in out)
+  (define req
+    ;; Match the first line to extract the request:
+    (regexp-match #rx"^GET (.+) HTTP/[0-9]+\\.[0-9]+"
+                  (read-line in)))
+  (when req
+    ;; Discard the rest of the header (up to blank line):
+    (regexp-match #rx"(\r\n|^)\r\n" in)
+    ;; Dispatch:
+    (let ([xexpr (prompt (dispatch (list-ref req 1)))]) ;; <<< changed
+      ;; Send reply:
+      (display "HTTP/1.0 200 Okay\r\n" out)
+      (display "Server: k\r\nContent-Type: text/html\r\n\r\n" out)
+      (display (xexpr->string xexpr) out))))
+
+(define (dispatch str-path)
+  ;; Parse the request as a URL:
+  (define url (string->url str-path))
+  ;; Extract the path part:
+  (define path (map path/param-path (url-path url)))
+  ;; Find a handler based on the path's first element:
+  (define h (hash-ref dispatch-table (car path) #f))
+  (if h
+      ;; Call a handler:
+      (h (url-query url))
+      ;; No handler found:
+      `(html (head (title "Error"))
+             (body
+              (font ((color "red"))
+                    "Unknown page: "
+                    ,str-path)))))
+
+(define dispatch-table (make-hash))
+
+(hash-set! dispatch-table "hello"
+           (λ (query)
+             `(html (body "Hello, World!"))))
+
+;; ----------------------------------------
+
+(define (build-request-page label next-url hidden)
+  `(html
+    (head (title "Enter a Number to Add"))
+    (body ([bgcolor "white"])
+          (form ([action ,next-url] [method "get"])
+                ,label
+                (input ([type "text"] [name "number"]
+                        [value ""]))
+                (input ([type "hidden"] [name "hidden"]
+                        [value ,hidden]))
+                (input ([type "submit"] [name "enter"]
+                        [value "Enter"]))))))
+
+(define (many query)
+  ;; Create a page containing the form:
+  (build-request-page "Number of greetings:" "/reply" ""))
+
+(define (reply query)
+  ;; Extract and use the form results:
+  (define n (string->number (cdr (assq 'number query))))
+  `(html (body ,@(for/list ([i (in-range n)])
+                   " hello"))))
+
+(hash-set! dispatch-table "many" many)
+(hash-set! dispatch-table "reply" reply)
+
+;; ----------------------------------------
+;; Old, awkward version:
+
+(define (sum query)
+  (build-request-page "First number:" "/one" ""))
+
+(define (one query)
+  (build-request-page "Second number:"
+                      "/two"
+                      (cdr (assq 'number query))))
+
+(define (two query)
+  (let ([n (string->number (cdr (assq 'hidden query)))]
+        [m (string->number (cdr (assq 'number query)))])
+    `(html (body "The sum is " ,(number->string (+ m n))))))
+
+(hash-set! dispatch-table "sum" sum)
+(hash-set! dispatch-table "one" one)
+(hash-set! dispatch-table "two" two)
+
+;; ----------------------------------------
+
+;; Helper to grab a computation and generate a handler for it:
+
+(define (send/suspend mk-page)
+  (let/cc k
+    (define tag (format "k~a" (current-inexact-milliseconds)))
+    (hash-set! dispatch-table tag k)
+    (abort (mk-page (string-append "/" tag)))))
+
+;; Helper to run the number-getting page via `send/suspend':
+
+(define (get-number label)
+  (define query
+    ;; Generate a URL for the current computation:
+    (send/suspend
+     ;; Receive the computation-as-URL here:
+     (λ (k-url)
+       ;; Generate the query-page result for this connection.
+       ;; Send the query result to the saved-computation URL:
+       (build-request-page label k-url ""))))
+  ;; We arrive here later, in a new connection
+  (string->number (cdr (assq 'number query))))
+
+;; ----------------------------------------
+
+;; New direct-style servlet:
+
+(define (sum2 query)
+  (define m (get-number "First number:"))
+  (define n (get-number "Second number:"))
+  `(html (body "The sum is " ,(number->string (+ m n)))))
+
+(hash-set! dispatch-table "sum2" sum2)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+#lang web-server/insta
+
+(require web-server/formlets
+         "model-3.rkt")
+
+; start: request -> doesn't return
+; Consumes a request and produces a page that displays
+; all of the web content.
+(define (start request)
+  (render-blog-page
+   (initialize-blog!
+    (build-path (current-directory)
+                "the-blog-data.sqlite"))
+   request))
+
+; new-post-formlet : formlet (values string? string?)
+; A formlet for requesting a title and body of a post
+(define new-post-formlet
+  (formlet
+   (#%# ,{input-string . => . title}
+        ,{input-string . => . body})
+   (values title body)))
+
+; render-blog-page: blog request -> doesn't return
+; Produces an HTML page of the content of the
+; blog.
+(define (render-blog-page a-blog request)
+  (local [(define (response-generator embed/url)
+            (response/xexpr
+             `(html (head (title "My Blog"))
+                    (body
+                     (h1 "My Blog")
+                     ,(render-posts a-blog embed/url)
+                     (form ([action
+                             ,(embed/url insert-post-handler)])
+                           ,@(formlet-display new-post-formlet)
+                           (input ([type "submit"])))))))
+
+          (define (insert-post-handler request)
+            (define-values (title body)
+              (formlet-process new-post-formlet request))
+            (blog-insert-post! a-blog title body)
+            (render-blog-page a-blog (redirect/get)))]
+
+    (send/suspend/dispatch response-generator)))
+
+; new-comment-formlet : formlet string
+; A formlet for requesting a comment
+(define new-comment-formlet
+  input-string)
+
+; render-post-detail-page: post request -> doesn't return
+; Consumes a post and produces a detail page of the post.
+; The user will be able to either insert new comments
+; or go back to render-blog-page.
+(define (render-post-detail-page a-blog a-post request)
+  (local [(define (response-generator embed/url)
+            (response/xexpr
+             `(html (head (title "Post Details"))
+                    (body
+                     (h1 "Post Details")
+                     (h2 ,(post-title a-post))
+                     (p ,(post-body a-post))
+                     ,(render-as-itemized-list
+                       (post-comments a-post))
+                     (form ([action
+                             ,(embed/url insert-comment-handler)])
+                           ,@(formlet-display new-comment-formlet)
+                           (input ([type "submit"])))
+                     (a ([href ,(embed/url back-handler)])
+                        "Back to the blog")))))
+
+          (define (insert-comment-handler request)
+            (render-confirm-add-comment-page
+             a-blog
+             (formlet-process new-comment-formlet request)
+             a-post
+             request))
+
+          (define (back-handler request)
+            (render-blog-page a-blog request))]
+
+    (send/suspend/dispatch response-generator)))
+
+; render-confirm-add-comment-page :
+; blog comment post request -> doesn't return
+; Consumes a comment that we intend to add to a post, as well
+; as the request. If the user follows through, adds a comment
+; and goes back to the display page. Otherwise, goes back to
+; the detail page of the post.
+(define (render-confirm-add-comment-page a-blog a-comment
+                                         a-post request)
+  (local [(define (response-generator embed/url)
+            (response/xexpr
+             `(html (head (title "Add a Comment"))
+                    (body
+                     (h1 "Add a Comment")
+                     "The comment: " (div (p ,a-comment))
+                     "will be added to "
+                     (div ,(post-title a-post))
+
+                     (p (a ([href ,(embed/url yes-handler)])
+                           "Yes, add the comment."))
+                     (p (a ([href ,(embed/url cancel-handler)])
+                           "No, I changed my mind!"))))))
+
+          (define (yes-handler request)
+            (post-insert-comment! a-blog a-post a-comment)
+            (render-post-detail-page a-blog a-post (redirect/get)))
+
+          (define (cancel-handler request)
+            (render-post-detail-page a-blog a-post request))]
+
+    (send/suspend/dispatch response-generator)))
+
+; render-post: post (handler -> string) -> xexpr
+; Consumes a post, produces an xexpr fragment of the post.
+; The fragment contains a link to show a detailed view of the post.
+(define (render-post a-blog a-post embed/url)
+  (local [(define (view-post-handler request)
+            (render-post-detail-page a-blog a-post request))]
+    `(div ([class "post"])
+          (a ([href ,(embed/url view-post-handler)])
+             ,(post-title a-post))
+          (p ,(post-body a-post))
+          (div ,(number->string (length (post-comments a-post)))
+               " comment(s)"))))
+
+; render-posts: blog (handler -> string) -> xexpr
+; Consumes a embed/url, produces an xexpr fragment
+; of all its posts.
+(define (render-posts a-blog embed/url)
+  (local [(define (render-post/embed/url a-post)
+            (render-post a-blog a-post embed/url))]
+    `(div ([class "posts"])
+          ,@(map render-post/embed/url (blog-posts a-blog)))))
+
+; render-as-itemized-list: (listof xexpr) -> xexpr
+; Consumes a list of items, and produces a rendering as
+; an unorderered list.
+(define (render-as-itemized-list fragments)
+  `(ul ,@(map render-as-item fragments)))
+
+; render-as-item: xexpr -> xexpr
+; Consumes an xexpr, and produces a rendering
+; as a list item.
+(define (render-as-item a-fragment)
+  `(li ,a-fragment))
diff --git a/app/server/vendor/rouge/spec/visual/samples/ruby b/app/server/vendor/rouge/spec/visual/samples/ruby
new file mode 100755
index 0000000..44d1c32
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/ruby
@@ -0,0 +1,327 @@
+#######
+# ruby 1.9 examples
+#######
+
+%i(this is an array of symbols)
+%I(this is too, but with #{@interpolation})
+hash = { answer: 42 }
+link_to 'new', new_article_path, class: 'btn'
+# not a symbol
+a ? b:c
+
+########
+# method calls
+########
+
+foo.bar
+foo.bar.baz
+foo.bar(123).baz()
+
+foo.
+  bar
+
+foo
+  .bar()
+  .baz
+
+foo.
+  bar
+
+foo.
+  bar().
+  baz
+
+########
+# function definitions
+########
+
+class (get_foo("blub"))::Foo
+  def (foo("bar") + bar("baz")).something argh, aaahaa
+    42
+  end
+end
+
+def -@
+  0 - self
+end
+
+class get_the_fuck("out")::Of::My
+  def parser_definition
+    ruby!
+  end
+end
+
+###############
+# General
+###############
+
+a.each{|el|anz[el]=anz[el]?anz[el]+1:1}
+while x<10000
+#a bis f dienen dazu die Nachbarschaft festzulegen. Man stelle sich die #Zahl von 1 bis 64 im Binärcode vor 1 bedeutet an 0 aus
+  b=(p[x]%32)/16<1 ? 0 : 1
+
+  (x-102>=0? n[x-102].to_i : 0)*a+(x-101>=0?n[x-101].to_i : 0)*e+n[x-100].to_i+(x-99>=0? n[x-99].to_i : 0)*f+(x-98>=0? n[x-98].to_i : 0)*a+
+  n[x+199].to_i*b+n[x+200].to_i*d+n[x+201].to_i*b
+
+#und die Ausgabe folgt
+g=%w{}
+x=0
+
+#leere regex
+test //, 123
+
+{staples: /\ASTAPLE?S?\s*[0-9]/i,
+ target: "^TARGET "}
+
+while x<100
+ puts"#{g[x]}"
+ x+=1
+end
+
+puts""
+sleep(10)
+
+1E1E1
+puts 30.send(:/, 5) # prints 6
+
+# fun with class attributes
+class Foo
+  def self.blub x
+    if not x.nil?
+      self.new
+    end
+  end
+  def another_way_to_get_class
+    self.class
+  end
+end
+
+# ruby 1.9 "call operator"
+a = Proc.new { 42 }
+a.()
+
+"instance variables can be #@included, #@@class_variables\n and #$globals as well."
+`instance variables can be #@included, #@@class_variables\n and #$globals as well.`
+'instance variables can be #@included, #@@class_variables\n and #$globals as well.'
+/instance variables can be #@included, #@@class_variables\n and #$globals as well./mousenix
+:"instance variables can be #@included, #@@class_variables\n and #$globals as well."
+:'instance variables can be #@included, #@@class_variables\n and #$globals as well.'
+%'instance variables can be #@included, #@@class_variables\n and #$globals as well.'
+%q'instance variables can be #@included, #@@class_variables\n and #$globals as well.'
+%Q'instance variables can be #@included, #@@class_variables\n and #$globals as well.'
+%w'instance variables can be #@included, #@@class_variables\n and #$globals as well.'
+%W'instance variables can be #@included, #@@class_variables\n and #$globals as well.'
+%s'instance variables can be #@included, #@@class_variables\n and #$globals as well.'
+%r'instance variables can be #@included, #@@class_variables\n and #$globals as well.'
+%x'instance variables can be #@included, #@@class_variables\n and #$globals as well.'
+
+#%W[ but #@0illegal_values look strange.]
+
+%s#ruby allows strange#{constructs}
+%s#ruby allows strange#$constructs
+%s#ruby allows strange#@@constructs
+
+%( hash mark: # )
+%r( hash mark: # )
+%w( ! $ % # )
+
+##################################################################
+# HEREDOCS
+foo(<<-A, <<-B)
+this is the text of a
+A
+and this is the text of b
+B
+
+a = <<"EOF"
+This is a multiline #$here document
+terminated by EOF on a line by itself
+EOF
+
+a = <<'EOF'
+This is a multiline #$here document
+terminated by EOF on a line by itself
+EOF
+
+b=(p[x] %32)/16<1 ? 0 : 1
+
+<<""
+#{test}
+#@bla
+#die suppe!!!
+\xfffff
+
+
+super <<-EOE % [
+    foo
+EOE
+
+<<X
+X
+X "foo" # This is a method call, heredoc ends at the prev line
+
+%s(uninter\)pre\ted)            # comment here
+%q(uninter\)pre\ted)            # comment here
+%Q(inter\)pre\ted)              # comment here
+:"inter\)pre\ted"               # comment here
+:'uninter\'pre\ted'             # comment here
+
+%q[haha! [nesting [rocks] ! ] ] # commeht here
+
+
+##################################################################
+class                                                  NP
+def  initialize a=@p=[], b=@b=[];                      end
+def +@;@b<<1;b2c end;def-@;@b<<0;b2c                   end
+def  b2c;if @b.size==8;c=0;@b.each{|b|c<<=1;c|=b};send(
+     'lave'.reverse,(@p.join))if c==0;@p<< c.chr;@b=[] end
+     self end end ; begin _ = NP.new                   end
+
+
+# Regexes
+/
+this is a
+mutliline
+regex
+/
+
+this /is a
+multiline regex too/
+
+also /4
+is one/
+
+this(/
+too
+/)
+
+# this not
+2 /4
+asfsadf/
+
+foo[:bar] / baz[:zot]
+
+
+#from: http://coderay.rubychan.de/rays/show/383
+class Object
+  alias  :xeq :`
+  def `(cmd, p2)
+    self.method(cmd.to_sym).call(p2)
+  end
+end
+p [1,2,3].`('concat', [4,5,6]) # => [1, 2, 3, 4, 5, 6]
+p [1,2,3].`(:concat, [4,5,6]) # => [1, 2, 3, 4, 5, 6]
+p "Hurra! ".`(:*, 3) # => "Hurra! Hurra! Hurra! "
+p "Hurra! ".`('*', 3) # => "Hurra! Hurra! Hurra! "
+# Leider geht nicht die Wunschform
+# [1,2,3] `concat` [4,5,6]
+
+class Object
+  @@infixops = []
+  alias :xeq :`
+  def addinfix(operator)
+    @@infixops << operator
+  end
+  def `(expression)
+    @@infixops.each{|op|break if expression.match(/^(.*?) (#{op}) (.*)$/)}
+    raise "unknown infix operator in expression: #{expression}" if $2 == nil
+    eval($1).method($2.to_sym).call(eval($3))
+  end
+end
+addinfix("concat")
+p `[1,2,3] concat [4,5,6]` # => [1, 2, 3, 4, 5, 6]
+
+
+# HEREDOC FUN!!!!!!!1111
+foo(<<A, <<-B, <<C)
+this is the text of a
+   A!!!!
+A
+and this is text of B!!!!!!111
+   B
+and here some C
+C
+###################################
+
+######
+# testing the __END__ content and % as an operator
+######
+
+events = Hash.new { |h, k| h[k] = [] }
+DATA.read.split(/\n\n\n\s*/).each do |event|
+	name = event[/^.*/].sub(/http:.*/, '')
+	event[/\n.*/m].scan(/^([A-Z]{2}\S*)\s*(\S*)\s*(\S*)(\s*\S*)/) do |kind, day, daytime, comment|
+		events[ [day, daytime] ] << [kind, name + comment]
+	end
+end
+
+foo = 3
+foo %= 2
+
+conflicts = 0
+events.to_a.sort_by do |(day, daytime),|
+	[%w(Mo Di Mi Do Fr).index(day) || 0, daytime]
+end.each do |(day, daytime), names|
+	if names.size > 1
+		conflicts += 1
+		print '!!! '
+	end
+	print "#{day} #{daytime}: "
+	names.each { |kind, name| puts "  #{kind}  #{name}" }
+	puts
+end
+
+puts '%d conflicts' % conflicts
+puts '%d SWS' % (events.inject(0) { |sum, ((day, daytime),)| sum + (daytime[/\d+$/].to_i - daytime[/^\d+/].to_i) })
+
+string = % foo     # strange. huh?
+print "Escape here: \n"
+print 'Dont escape here: \n'
+
+__END__
+Informatik und Informationsgesellschaft I: Digitale Medien (32 214)
+Computer lassen ihre eigentliche Bestimmung durch Multimedia und Vernetzung erkennen: Es sind digitale Medien, die alle bisherigen Massen- und Kommunikationsmedien simulieren, kopieren oder ersetzen können. Die kurze Geschichte elektronischer Medien vom Telegramm bis zum Fernsehen wird so zur Vorgeschichte des Computers als Medium. Der Prozess der Mediatisierung der Rechnernetze soll in Technik, Theorie und Praxis untersucht werden. Das PR soll die Techniken der ortsverteilten und zeitversetzten Lehre an Hand praktischer Übungen vorführen und untersuchen.
+VL 	Di	15-17	wöch.	RUD 25, 3.101	J. Koubek
+VL	Do	15-17	wöch.	RUD 25, 3.101
+UE/PR	Do	17-19	wöch.	RUD 25, 3.101	J.-M. Loebel
+
+
+Methoden und Modelle des Systementwurfs (32 223)
+Gute Methoden zum Entwurf und zur Verifikation von Systemen sind ein Schlüssel für gute Software. Dieses Seminar betrachtet moderne Entwurfsmethoden.
+ VL	Di	09-11	wöch.	RUD 26, 0’313	W. Reisig
+ VL	Do	09-11	wöch.	RUD 26, 0’313	
+ UE	Di	11-13	wöch.	RUD 26, 0’313	
+ PR	Di	13-15	wöch.	RUD 26, 0’313	D. Weinberg
+
+
+Komplexitätstheorie (32 229)
+In dieser Vorlesung untersuchen wir eine Reihe von wichtigen algorithmischen Problemstellungen aus verschiedenen Bereichen der Informatik. Unser besonderes Interesse gilt dabei der Abschätzung der Rechenressourcen, die zu ihrer Lösung aufzubringen sind.  Die Vorlesung bildet eine wichtige Grundlage für weiterführende Veranstaltungen in den Bereichen Algorithmen, Kryptologie, Algorithmisches Lernen und Algorithmisches Beweisen.
+ VL 	Di	09-11	wöch.	RUD 26, 1’303	J. Köbler
+ VL	Do	09-11	wöch.	RUD 26, 1’305	
+ UE	Do	11-13	wöch.	RUD 26, 1’305	
+
+
+Zuverlässige Systeme (32 234)
+Mit zunehmender Verbreitung der Computertechnologie in immer mehr Bereichen des menschlichen Lebens wird die Zuverlässigkeit solcher Systeme zu einer immer zentraleren Frage.
+Der Halbkurs "Zuverlässige Systeme" konzentriert sich auf folgende Schwerpunkte: Zuverlässigkeit, Fehlertoleranz, Responsivität, Messungen, Anwendungen, Systemmodelle und Techniken, Ausfallverhalten, Fehlermodelle, Schedulingtechniken, Software/Hardware - responsives Systemdesign, Analyse und Synthese, Bewertung, Fallstudien in Forschung und Industrie.
+Der Halbkurs kann mit dem Halbkurs "Eigenschaften mobiler und eingebetteter Systeme" zu einem Projektkurs kombiniert werden. Ein gemeinsames Projekt begleitet beide Halbkurse.
+VL 	Di	09-11	wöch.	RUD 26, 1’308	M. Malek
+VL	Do	09-11	wöch.	RUD 26, 1’308
+PR	n.V.
+
+
+Stochastik für InformatikerInnen (32 239)
+Grundlagen der Wahrscheinlichkeitsrechnung, Diskrete und stetige Wahrscheinlichkeitsmodelle in der Informatik, Grenzwertsätze, Simulationsverfahren, Zufallszahlen, Statistische Schätz- und Testverfahren, Markoffsche Ketten, Simulated Annealing, Probabilistische Analyse von Algorithmen.
+VL	Mo	09-11	wöch.	RUD 25, 3.101	W. Kössler
+VL	Mi	09-11	wöch.	RUD 25, 3.101
+UE	Mo	11-13	wöch.	RUD 25, 3.101
+ UE	Mi	11-13	wöch.	RUD 25. 3.101
+
+
+Geschichte der Informatik – Ausgewählte Kapitel (32 243)
+VL	Mi	13-15	wöch.	RUD 25, 3.113	W. Coy
+
+
+Aktuelle Themen der Theoretischen Informatik (32 260)
+In diesem Seminar sollen wichtige aktuelle Veröffentlichungen aus der theoretischen Informatik gemeinsam erarbeitet werden. Genaueres wird erst kurz vor dem Seminar entschieden. Bei Interesse wenden Sie sich bitte möglichst frühzeitig an den Veranstalter.
+ SE	Fr	09-11	wöch.	RUD 26, 1’307	M. Grohe 
diff --git a/app/server/vendor/rouge/spec/visual/samples/rust b/app/server/vendor/rouge/spec/visual/samples/rust
new file mode 100755
index 0000000..ba67d4b
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/rust
@@ -0,0 +1,376 @@
+fn f() {
+    let a = ~"hello";
+    let b: &str = a;
+    io::println(b);
+}
+
+fn g() {
+    let c = ~"world";
+    let d: &str;
+    d = c;
+    io::println(d);
+}
+
+fn main() {
+    f();
+    g();
+}
+
+debug!("test %?", a.b);
+debug!("test %u", a.c);
+debug!("test %i", a.d);
+debug!("test %c", a.e);
+debug!("test %f", a.f);
+debug!("test %b", a.g);
+
+trait iterable<A> {
+    fn iterate(blk: fn(x: &A) -> bool);
+}
+
+impl<A> &[A]: iterable<A> {
+    fn iterate(f: fn(x: &A) -> bool) {
+        for vec::each(self) |e| {
+            if !f(e) { break; }
+        }
+    }
+}
+
+impl<A> ~[A]: iterable<A> {
+    fn iterate(f: fn(x: &A) -> bool) {
+        for vec::each(self) |e| {
+            if !f(e) { break; }
+        }
+    }
+}
+
+fn length<A, T: iterable<A>>(x: T) -> uint {
+    let mut len = 0;
+    for x.iterate() |_y| { len += 1 }
+    return len;
+}
+
+fn main() {
+    let x = ~[0,1,2,3];
+    // Call a method
+    for x.iterate() |y| { assert x[*y] == *y; }
+    // Call a parameterized function
+    assert length(x) == vec::len(x);
+    // Call a parameterized function, with type arguments that require
+    // a borrow
+    assert length::<int, &[int]>(x) == vec::len(x);
+
+    // Now try it with a type that *needs* to be borrowed
+    let z = [0,1,2,3];
+    // Call a method
+    for z.iterate() |y| { assert z[*y] == *y; }
+    // Call a parameterized function
+    assert length::<int, &[int]>(z) == vec::len(z);
+}
+
+
+#[attr1 = "val"];
+#[attr2 = "val"];
+#[attr3];
+#[attr4(attr5)];
+
+// Special linkage attributes for the crate
+#[link(name = "std",
+       vers = "0.1",
+       uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297",
+       url = "http://rust-lang.org/src/std")];
+
+// These are are attributes of the following mod
+#[attr1 = "val"]
+#[attr2 = "val"]
+mod test_first_item_in_file_mod {
+    #[legacy_exports]; }
+
+mod test_single_attr_outer {
+    #[legacy_exports];
+
+    #[attr = "val"]
+    const x: int = 10;
+
+    #[attr = "val"]
+    fn f() { }
+
+    #[attr = "val"]
+    mod mod1 {
+        #[legacy_exports]; }
+
+    #[attr = "val"]
+    #[abi = "cdecl"]
+    extern mod rustrt {
+        #[legacy_exports]; }
+}
+
+mod test_multi_attr_outer {
+    #[legacy_exports];
+
+    #[attr1 = "val"]
+    #[attr2 = "val"]
+    const x: int = 10;
+
+    #[attr1 = "val"]
+    #[attr2 = "val"]
+    fn f() { }
+
+    #[attr1 = "val"]
+    #[attr2 = "val"]
+    mod mod1 {
+        #[legacy_exports]; }
+
+    #[attr1 = "val"]
+    #[attr2 = "val"]
+    #[abi = "cdecl"]
+    extern mod rustrt {
+        #[legacy_exports]; }
+
+    #[attr1 = "val"]
+    #[attr2 = "val"]
+    type t = {x: int};
+}
+
+mod test_stmt_single_attr_outer {
+    #[legacy_exports];
+
+    fn f() {
+
+        #[attr = "val"]
+        const x: int = 10;
+
+        #[attr = "val"]
+        fn f() { }
+
+        #[attr = "val"]
+        mod mod1 {
+            #[legacy_exports];
+        }
+
+        #[attr = "val"]
+        #[abi = "cdecl"]
+        extern mod rustrt {
+            #[legacy_exports];
+        }
+    }
+}
+
+mod test_stmt_multi_attr_outer {
+    #[legacy_exports];
+
+    fn f() {
+
+        #[attr1 = "val"]
+        #[attr2 = "val"]
+        const x: int = 10;
+
+        #[attr1 = "val"]
+        #[attr2 = "val"]
+        fn f() { }
+
+        /* FIXME: Issue #493
+        #[attr1 = "val"]
+        #[attr2 = "val"]
+        mod mod1 {
+            #[legacy_exports];
+        }
+
+        #[attr1 = "val"]
+        #[attr2 = "val"]
+        #[abi = "cdecl"]
+        extern mod rustrt {
+            #[legacy_exports];
+        }
+        */
+    }
+}
+
+mod test_attr_inner {
+    #[legacy_exports];
+
+    mod m {
+        #[legacy_exports];
+        // This is an attribute of mod m
+        #[attr = "val"];
+    }
+}
+
+mod test_attr_inner_then_outer {
+    #[legacy_exports];
+
+    mod m {
+        #[legacy_exports];
+        // This is an attribute of mod m
+        #[attr = "val"];
+        // This is an attribute of fn f
+        #[attr = "val"]
+        fn f() { }
+    }
+}
+
+mod test_attr_inner_then_outer_multi {
+    #[legacy_exports];
+    mod m {
+        #[legacy_exports];
+        // This is an attribute of mod m
+        #[attr1 = "val"];
+        #[attr2 = "val"];
+        // This is an attribute of fn f
+        #[attr1 = "val"]
+        #[attr2 = "val"]
+        fn f() { }
+    }
+}
+
+mod test_distinguish_syntax_ext {
+    #[legacy_exports];
+
+    extern mod std;
+
+    fn f() {
+        fmt!("test%s", ~"s");
+        #[attr = "val"]
+        fn g() { }
+    }
+}
+
+mod test_other_forms {
+    #[legacy_exports];
+    #[attr]
+    #[attr(word)]
+    #[attr(attr(word))]
+    #[attr(key1 = "val", key2 = "val", attr)]
+    fn f() { }
+}
+
+mod test_foreign_items {
+    #[legacy_exports];
+    #[abi = "cdecl"]
+    extern mod rustrt {
+        #[legacy_exports];
+        #[attr];
+
+        #[attr]
+        fn get_task_id() -> libc::intptr_t;
+    }
+}
+
+mod test_literals {
+    #[legacy_exports];
+    #[str = "s"];
+    #[char = 'c'];
+    #[int = 100];
+    #[uint = 100u];
+    #[mach_int = 100u32];
+    #[float = 1.0];
+    #[mach_float = 1.0f32];
+    #[nil = ()];
+    #[bool = true];
+    mod m {
+        #[legacy_exports]; }
+}
+
+fn test_fn_inner() {
+    #[inner_fn_attr];
+}
+
+fn main() { }
+
+//
+// Local Variables:
+// mode: rust
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// End:
+//
+
+/*
+
+This is an HTML parser written as a macro. It's all CPS, and we have
+to carry around a bunch of state. The arguments to macros all look like this:
+
+{ tag_stack* # expr* # tokens }
+
+The stack keeps track of where we are in the tree. The expr is a list
+of children of the current node. The tokens are everything that's
+left.
+
+*/
+
+macro_rules! html (
+    ( $($body:tt)* ) => (
+        parse_node!( []; []; $($body)* )
+    )
+)
+
+macro_rules! parse_node (
+    (
+        [:$head:ident ($(:$head_nodes:expr),*)
+         $(:$tags:ident ($(:$tag_nodes:expr),*))*];
+        [$(:$nodes:expr),*];
+        </$tag:ident> $($rest:tt)*
+    ) => (
+        parse_node!(
+            [$(: $tags ($(:$tag_nodes),*))*];
+            [$(:$head_nodes,)* :tag(stringify!($head).to_owned(),
+                                    ~[$($nodes),*])];
+            $($rest)*
+        )
+    );
+
+    (
+        [$(:$tags:ident ($(:$tag_nodes:expr),*) )*];
+        [$(:$nodes:expr),*];
+        <$tag:ident> $($rest:tt)*
+    ) => (
+        parse_node!(
+            [:$tag ($(:$nodes)*) $(: $tags ($(:$tag_nodes),*) )*];
+            [];
+            $($rest)*
+        )
+    );
+
+    (
+        [$(:$tags:ident ($(:$tag_nodes:expr),*) )*];
+        [$(:$nodes:expr),*];
+        . $($rest:tt)*
+    ) => (
+        parse_node!(
+            [$(: $tags ($(:$tag_nodes),*))*];
+            [$(:$nodes,)* :text(~".")];
+            $($rest)*
+        )
+    );
+
+    (
+        [$(:$tags:ident ($(:$tag_nodes:expr),*) )*];
+        [$(:$nodes:expr),*];
+        $word:ident $($rest:tt)*
+    ) => (
+        parse_node!(
+            [$(: $tags ($(:$tag_nodes),*))*];
+            [$(:$nodes,)* :text(stringify!($word).to_owned())];
+            $($rest)*
+        )
+    );
+
+    ( []; [:$e:expr]; ) => ( $e );
+)
+
+fn main() {
+    let page = html! (
+        <html>
+            <head><title>This is the title.</title></head>
+            <body>
+            <p>This is some text</p>
+            </body>
+        </html>
+    );
+}
+
+enum HTMLFragment {
+    tag(~str, ~[HTMLFragment]),
+    text(~str),
+}
diff --git a/app/server/vendor/rouge/spec/visual/samples/sass b/app/server/vendor/rouge/spec/visual/samples/sass
new file mode 100755
index 0000000..db8fd80
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/sass
@@ -0,0 +1,391 @@
+ at for $i from 1 through 3
+  .item-#{$i}
+    width: 2em * $i
+
+%a-placeholder
+  @extend #foo%another-placeholder
+
+// mixins.sass
+$yellow: #fc0
+
+=bordered
+  :border
+    :top
+      :width 2px
+      :color $yellow
+    :left
+      :width 1px
+      :color #000
+  -moz-border-radius: 10px
+
+=header-font
+  :color #f00
+  :font
+    :size 20px
+
+=compound
+  +header-font
+  +bordered
+
+=complex
+  +header-font
+  text:
+    decoration: none
+  &:after
+    content: "."
+    display: block
+    height: 0
+    clear: both
+    visibility: hidden
+  * html &
+    height: 1px
+    +header-font
+=deep
+  a:hover
+    :text-decoration underline
+    +compound
+
+
+#main
+  :width 15em
+  :color #0000ff
+  p
+    +bordered
+    :border
+      :style dotted
+      :width 2px
+  .cool
+    :width 100px
+
+#left
+  +bordered
+  :font
+    :size 2em
+    :weight bold
+  :float left
+
+#right
+  +bordered
+  +header-font
+  :float right
+
+.bordered
+  +bordered
+
+.complex
+  +complex
+
+.more-complex
+  +complex
+  +deep
+  display: inline
+  -webkit-nonsense:
+    top-right: 1px
+    bottom-left: 1px
+// complex.sass
+
+body
+  :margin 0
+  :font   0.85em "Lucida Grande", "Trebuchet MS", Verdana, sans-serif
+  :color #fff
+  :background url(/images/global_bg.gif)
+
+#page
+  :width      900px
+  :margin     0 auto
+  :background #440008
+  :border-top
+    :width 5px
+    :style solid
+    :color #ff8500
+
+#header
+  :height  75px
+  :padding 0
+  h1
+    :float  left
+    :width  274px
+    :height 75px
+    :margin 0
+    :background
+      :image url(/images/global_logo.gif)
+      /* Crazy nested comment
+      :repeat no-repeat
+    :text-indent -9999px
+  .status
+    :float   right
+    :padding
+      :top .5em
+      :left .5em
+      :right .5em
+      :bottom 0
+    p
+      :float  left
+      :margin
+        :top 0
+        :right 0.5em
+        :bottom 0
+        :left 0
+    ul
+      :float   left
+      :margin  0
+      :padding 0
+    li
+      :list-style-type none
+      :display inline
+      :margin 0 5px
+    a:link, a:visited
+      :color #ff8500
+      :text-decoration none
+    a:hover
+      :text-decoration underline
+  .search
+    :float  right
+    :clear  right
+    :margin 12px 0 0 0
+    form
+      :margin 0
+    input
+      :margin 0 3px 0 0
+      :padding 2px
+      :border none
+
+#menu 
+  :clear both
+  :text-align right
+  :height 20px
+  :border-bottom 5px solid #006b95
+  :background #00a4e4
+  .contests
+    ul
+      :margin 0 5px 0 0
+      :padding 0
+      li 
+        :list-style-type none
+        :margin 0 5px
+        :padding 5px 5px 0 5px
+        :display inline
+        :font-size 1.1em
+        // This comment is properly indented
+        :color #fff
+        :background #00a4e4
+    a:link, a:visited
+      :color #fff
+      :text-decoration none
+      :font-weight bold
+    a:hover
+      :text-decoration underline
+
+//General content information
+#content
+  :clear both
+  .container
+    :clear both
+    .column
+      :float left
+      .right
+        :float right
+  a:link, a:visited
+    :color #93d700
+    :text-decoration none
+  a:hover
+    :text-decoration underline
+
+// A hard tab:
+
+
+#content
+  p, div
+    :width 40em
+    li, dt, dd
+      :color #ddffdd
+      :background-color #4792bb
+  .container.video
+    .column.left
+      :width 200px
+      .box
+        :margin-top 10px
+        p 
+          :margin 0 1em auto 1em
+      .box.participants 
+        img
+          :float  left
+          :margin 0 1em auto 1em
+          :border 1px solid #6e000d
+            :style solid
+        h2
+          :margin 0 0 10px 0
+          :padding 0.5em
+          /* The background image is a gif!
+          :background #6e000d url(/images/hdr_participant.gif) 2px 2px no-repeat
+          /* Okay check this out
+            Multiline comments
+            Wow dude
+            I mean seriously, WOW
+          :text-indent -9999px
+          // And also...
+            Multiline comments that don't output!
+            Snazzy, no?
+          :border
+            :top
+              :width 5px
+              :style solid
+              :color #a20013
+            :right
+              :width 1px
+              :style dotted
+    .column.middle
+      :width 500px
+    .column.right
+      :width 200px
+      .box
+        :margin-top 0
+        p
+          :margin 0 1em auto 1em
+    .column
+      p
+        :margin-top 0
+
+#content.contests
+  .container.information 
+    .column.right 
+      .box
+        :margin 1em 0
+      .box.videos
+        .thumbnail img 
+          :width         200px
+          :height        150px
+          :margin-bottom 5px
+        a:link, a:visited
+          :color #93d700
+          :text-decoration none
+        a:hover
+          :text-decoration underline
+      .box.votes 
+        a
+          :display block
+          :width  200px
+          :height 60px
+          :margin 15px 0
+          :background url(/images/btn_votenow.gif) no-repeat
+          :text-indent -9999px
+          :outline none
+          :border  none
+        h2
+          :margin  52px 0 10px 0
+          :padding 0.5em
+          :background #6e000d url(/images/hdr_videostats.gif) 2px 2px no-repeat
+          :text-indent -9999px
+          :border-top 5px solid #a20013
+
+#content.contests 
+  .container.video
+    .box.videos
+      h2
+        :margin  0
+        :padding 0.5em
+        :background #6e000d url(/images/hdr_newestclips.gif) 2px 2px no-repeat
+        :text-indent -9999px
+        :border-top 5px solid #a20013
+      table
+        :width 100
+        td 
+          :padding 1em
+          :width 25
+          :vertical-align top
+          p
+            :margin 0 0 5px 0
+          a:link, a:visited    
+            :color #93d700
+            :text-decoration none
+          a:hover
+            :text-decoration underline
+      .thumbnail
+        :float left
+        img
+          :width  80px
+          :height 60px
+          :margin 0 10px 0 0
+          :border 1px solid #6e000d
+
+#content 
+  .container.comments 
+    .column
+      :margin-top 15px
+    .column.left
+      :width 600px
+      .box 
+        ol
+          :margin  0
+          :padding 0
+        li
+          :list-style-type none
+          :padding 10px
+          :margin 0 0 1em 0
+          :background #6e000d
+          :border-top 5px solid #a20013
+          div
+            :margin-bottom 1em
+          ul
+            :text-align right
+            li
+              :display inline
+              :border none
+              :padding 0
+    .column.right
+      :width        290px
+      :padding-left 10px
+      h2
+        :margin 0
+        :padding 0.5em
+        :background #6e000d url(/images/hdr_addcomment.gif) 2px 2px no-repeat
+        :text-indent -9999px
+        :border-top 5px solid #a20013
+      .box
+        textarea
+          :width  290px
+          :height 100px
+          :border none
+
+#footer
+  :margin-top 10px
+  :padding    1.2em 1.5em
+  :background #ff8500
+  ul
+    :margin 0
+    :padding 0
+    :list-style-type none
+    li
+      :display inline
+      :margin  0 0.5em
+      :color   #440008
+  ul.links
+    :float left
+    a:link, a:visited
+      :color #440008
+      :text-decoration none
+    a:hover
+      :text-decoration underline
+  ul.copyright
+    :float right
+
+
+.clear 
+  :clear both
+
+.centered 
+  :text-align center
+
+img
+  :border none
+
+button.short 
+  :width   60px
+  :height  22px
+  :padding 0 0 2px 0
+  :color   #fff
+  :border  none
+  :background url(/images/btn_short.gif) no-repeat
+
+table
+  :border-collapse collapse
diff --git a/app/server/vendor/rouge/spec/visual/samples/scala b/app/server/vendor/rouge/spec/visual/samples/scala
new file mode 100755
index 0000000..a0f696d
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/scala
@@ -0,0 +1,49 @@
+package whatever.mine
+
+import foo.bar.{Foo, Bar => Baz}
+
+/* This file /* which is totally legal scala */ should be highlighted
+   correcty by rouge */
+
+object ⌘ {
+  val `interface` = """
+A
+"Multiline"
+String
+"""
+
+  val s = 'symbol
+
+  @tailrec
+  val foo_+ = "foo plus"
+  val foo_⌬⌬ = "double benzene"
+
+  def main(argv: Array[String]) {
+    println(⌘.interface + " " + foo_+ + " " + foo_⌬⌬ )
+  }
+
+  def noWhitespaceType[Foo](arg:ClassName[Foo])(implicit evidence: Foo =:= Int) {}
+
+  val char = 'a'
+  var unicodeChar = '\uAB23'
+
+  val constant = true
+
+  import more.stuff._
+}
+
+abstract case class Foo[+A, B <: List[A]](a: A) {
+  type Bar = Baz
+
+  def apply[C >: A](c: Foo[C]): Foo[C]
+}
+
+class why_would_you_name_a_class_this_way_oh_well_we_need_to_highlight_it(a: Int) extends Foo(a) {
+  def this(b: Float) = this(b.toInt)
+
+  def ints = 4
+  def floats = 4f
+  def doubles = 0.4
+  def longs = 4L
+  def hex = 0x123
+}
diff --git a/app/server/vendor/rouge/spec/visual/samples/scheme b/app/server/vendor/rouge/spec/visual/samples/scheme
new file mode 100755
index 0000000..567b232
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/scheme
@@ -0,0 +1,1564 @@
+(define my-hex #x10c)
+(define my-bin #b1001011101)
+(define my-oct #o1234)
+(define my-dec #d10)
+(define my-exact #e10.2)
+(define my-inexact #i10.2)
+
+;;; installed-scm-file
+
+;;;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+;;;;
+;;;; This program is free software; you can redistribute it and/or modify
+;;;; it under the terms of the GNU General Public License as published by
+;;;; the Free Software Foundation; either version 2, or (at your option)
+;;;; any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this software; see the file COPYING.  If not, write to
+;;;; the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+;;;; Boston, MA 02111-1307 USA
+;;;;
+;;;; As a special exception, the Free Software Foundation gives permission
+;;;; for additional uses of the text contained in its release of GUILE.
+;;;;
+;;;; The exception is that, if you link the GUILE library with other files
+;;;; to produce an executable, this does not by itself cause the
+;;;; resulting executable to be covered by the GNU General Public License.
+;;;; Your use of that executable is in no way restricted on account of
+;;;; linking the GUILE library code into it.
+;;;;
+;;;; This exception does not however invalidate any other reasons why
+;;;; the executable file might be covered by the GNU General Public License.
+;;;;
+;;;; This exception applies only to the code released by the
+;;;; Free Software Foundation under the name GUILE.  If you copy
+;;;; code from other Free Software Foundation releases into a copy of
+;;;; GUILE, as the General Public License permits, the exception does
+;;;; not apply to the code that you add in this way.  To avoid misleading
+;;;; anyone as to the status of such modified files, you must delete
+;;;; this exception notice from them.
+;;;;
+;;;; If you write modifications of your own for GUILE, it is your choice
+;;;; whether to permit this exception to apply to your modifications.
+;;;; If you do not wish that, delete this exception notice.
+;;;;
+
+
+;;; Commentary:
+
+;;; This file is the first thing loaded into Guile.  It adds many mundane
+;;; definitions and a few that are interesting.
+;;;
+;;; The module system (hence the hierarchical namespace) are defined in this
+;;; file.
+;;;
+
+;;; Code:
+
+
+;;; {Deprecation}
+;;;
+
+;; We don't have macros here, but we do want to define
+;; `begin-deprecated' early.
+
+(define begin-deprecated
+  (procedure->memoizing-macro
+   (lambda (exp env)
+     (if (include-deprecated-features)
+	 `(begin ,@(cdr exp))
+	 `#f))))
+
+
+;;; {Features}
+;;
+
+(define (provide sym)
+  (if (not (memq sym *features*))
+      (set! *features* (cons sym *features*))))
+
+;;; Return #t iff FEATURE is available to this Guile interpreter.
+;;; In SLIB, provided? also checks to see if the module is available.
+;;; We should do that too, but don't.
+(define (provided? feature)
+  (and (memq feature *features*) #t))
+
+(begin-deprecated
+ (define (feature? sym)
+   (issue-deprecation-warning
+    "`feature?' is deprecated.  Use `provided?' instead.")
+   (provided? sym)))
+
+;;; let format alias simple-format until the more complete version is loaded
+(define format simple-format)
+
+
+;;; {R4RS compliance}
+
+(primitive-load-path "ice-9/r4rs.scm")
+
+
+;;; {Simple Debugging Tools}
+;;
+
+
+;; peek takes any number of arguments, writes them to the
+;; current ouput port, and returns the last argument.
+;; It is handy to wrap around an expression to look at
+;; a value each time is evaluated, e.g.:
+;;
+;;	(+ 10 (troublesome-fn))
+;;	=> (+ 10 (pk 'troublesome-fn-returned (troublesome-fn)))
+;;
+
+(define (peek . stuff)
+  (newline)
+  (display ";;; ")
+  (write stuff)
+  (newline)
+  (car (last-pair stuff)))
+
+(define pk peek)
+
+(define (warn . stuff)
+  (with-output-to-port (current-error-port)
+    (lambda ()
+      (newline)
+      (display ";;; WARNING ")
+      (display stuff)
+      (newline)
+      (car (last-pair stuff)))))
+
+
+;;; {Trivial Functions}
+;;;
+
+(define (identity x) x)
+(define (1+ n) (+ n 1))
+(define (1- n) (+ n -1))
+(define (and=> value procedure) (and value (procedure value)))
+(define (make-hash-table k) (make-vector k '()))
+
+(begin-deprecated
+ (define (id x)
+   (issue-deprecation-warning "`id' is deprecated.  Use `identity' instead.")
+   (identity x))
+ (define (-1+ n)
+   (issue-deprecation-warning "`-1+' is deprecated.  Use `1-' instead.")
+   (1- n))
+ (define (return-it . args)
+   (issue-deprecation-warning "`return-it' is deprecated.  Use `noop' instead.")
+   (apply noop args)))
+
+;;; apply-to-args is functionally redundant with apply and, worse,
+;;; is less general than apply since it only takes two arguments.
+;;;
+;;; On the other hand, apply-to-args is a syntacticly convenient way to
+;;; perform binding in many circumstances when the "let" family of
+;;; of forms don't cut it.  E.g.:
+;;;
+;;;	(apply-to-args (return-3d-mouse-coords)
+;;;	  (lambda (x y z)
+;;;		...))
+;;;
+
+(define (apply-to-args args fn) (apply fn args))
+
+
+
+;;; {Integer Math}
+;;;
+
+(define (ipow-by-squaring x k acc proc)
+  (cond ((zero? k) acc)
+	((= 1 k) (proc acc x))
+	(else (ipow-by-squaring (proc x x)
+				(quotient k 2)
+				(if (even? k) acc (proc acc x))
+				proc))))
+
+(begin-deprecated
+ (define (string-character-length s)
+   (issue-deprecation-warning "`string-character-length' is deprecated.  Use `string-length' instead.")
+   (string-length s))
+ (define (flags . args)
+   (issue-deprecation-warning "`flags' is deprecated.  Use `logior' instead.")
+   (apply logior args)))
+
+
+;;; {Symbol Properties}
+;;;
+
+(define (symbol-property sym prop)
+  (let ((pair (assoc prop (symbol-pref sym))))
+    (and pair (cdr pair))))
+
+(define (set-symbol-property! sym prop val)
+  (let ((pair (assoc prop (symbol-pref sym))))
+    (if pair
+	(set-cdr! pair val)
+	(symbol-pset! sym (acons prop val (symbol-pref sym))))))
+
+(define (symbol-property-remove! sym prop)
+  (let ((pair (assoc prop (symbol-pref sym))))
+    (if pair
+	(symbol-pset! sym (delq! pair (symbol-pref sym))))))
+
+;;; {General Properties}
+;;;
+
+;; This is a more modern interface to properties.  It will replace all
+;; other property-like things eventually.
+
+(define (make-object-property)
+  (let ((prop (primitive-make-property #f)))
+    (make-procedure-with-setter
+     (lambda (obj) (primitive-property-ref prop obj))
+     (lambda (obj val) (primitive-property-set! prop obj val)))))
+
+
+
+;;; {Arrays}
+;;;
+
+(if (provided? 'array)
+    (primitive-load-path "ice-9/arrays.scm"))
+
+
+;;; {Keywords}
+;;;
+
+(define (symbol->keyword symbol)
+  (make-keyword-from-dash-symbol (symbol-append '- symbol)))
+
+(define (keyword->symbol kw)
+  (let ((sym (symbol->string (keyword-dash-symbol kw))))
+    (string->symbol (substring sym 1 (string-length sym)))))
+
+(define (kw-arg-ref args kw)
+  (let ((rem (member kw args)))
+    (and rem (pair? (cdr rem)) (cadr rem))))
+
+
+
+;;; {Structs}
+
+(define (struct-layout s)
+  (struct-ref (struct-vtable s) vtable-index-layout))
+
+
+
+;;; Environments
+
+(define the-environment
+  (procedure->syntax
+   (lambda (x e)
+     e)))
+
+(define the-root-environment (the-environment))
+
+(define (environment-module env)
+  (let ((closure (and (pair? env) (car (last-pair env)))))
+    (and closure (procedure-property closure 'module))))
+
+
+;;; {Records}
+;;;
+
+;; Printing records: by default, records are printed as
+;;
+;;   #<type-name field1: val1 field2: val2 ...>
+;;
+;; You can change that by giving a custom printing function to
+;; MAKE-RECORD-TYPE (after the list of field symbols).  This function
+;; will be called like
+;;
+;;   (<printer> object port)
+;;
+;; It should print OBJECT to PORT.
+
+(define (inherit-print-state old-port new-port)
+  (if (get-print-state old-port)
+      (port-with-print-state new-port (get-print-state old-port))
+      new-port))
+
+;; 0: type-name, 1: fields
+(define record-type-vtable
+  (make-vtable-vtable "prpr" 0
+		      (lambda (s p)
+			(cond ((eq? s record-type-vtable)
+			       (display "#<record-type-vtable>" p))
+			      (else
+			       (display "#<record-type " p)
+			       (display (record-type-name s) p)
+			       (display ">" p))))))
+
+(define (record-type? obj)
+  (and (struct? obj) (eq? record-type-vtable (struct-vtable obj))))
+
+(define (make-record-type type-name fields . opt)
+  (let ((printer-fn (and (pair? opt) (car opt))))
+    (let ((struct (make-struct record-type-vtable 0
+			       (make-struct-layout
+				(apply string-append
+				       (map (lambda (f) "pw") fields)))
+			       (or printer-fn
+				   (lambda (s p)
+				     (display "#<" p)
+				     (display type-name p)
+				     (let loop ((fields fields)
+						(off 0))
+				       (cond
+					((not (null? fields))
+					 (display " " p)
+					 (display (car fields) p)
+					 (display ": " p)
+					 (display (struct-ref s off) p)
+					 (loop (cdr fields) (+ 1 off)))))
+				     (display ">" p)))
+			       type-name
+			       (copy-tree fields))))
+      ;; Temporary solution: Associate a name to the record type descriptor
+      ;; so that the object system can create a wrapper class for it.
+      (set-struct-vtable-name! struct (if (symbol? type-name)
+					  type-name
+					  (string->symbol type-name)))
+      struct)))
+
+(define (record-type-name obj)
+  (if (record-type? obj)
+      (struct-ref obj vtable-offset-user)
+      (error 'not-a-record-type obj)))
+
+(define (record-type-fields obj)
+  (if (record-type? obj)
+      (struct-ref obj (+ 1 vtable-offset-user))
+      (error 'not-a-record-type obj)))
+
+(define (record-constructor rtd . opt)
+  (let ((field-names (if (pair? opt) (car opt) (record-type-fields rtd))))
+    (local-eval `(lambda ,field-names
+		   (make-struct ',rtd 0 ,@(map (lambda (f)
+						 (if (memq f field-names)
+						     f
+						     #f))
+					       (record-type-fields rtd))))
+		the-root-environment)))
+
+(define (record-predicate rtd)
+  (lambda (obj) (and (struct? obj) (eq? rtd (struct-vtable obj)))))
+
+(define (record-accessor rtd field-name)
+  (let* ((pos (list-index (record-type-fields rtd) field-name)))
+    (if (not pos)
+	(error 'no-such-field field-name))
+    (local-eval `(lambda (obj)
+		   (and (eq? ',rtd (record-type-descriptor obj))
+			(struct-ref obj ,pos)))
+		the-root-environment)))
+
+(define (record-modifier rtd field-name)
+  (let* ((pos (list-index (record-type-fields rtd) field-name)))
+    (if (not pos)
+	(error 'no-such-field field-name))
+    (local-eval `(lambda (obj val)
+		   (and (eq? ',rtd (record-type-descriptor obj))
+			(struct-set! obj ,pos val)))
+		the-root-environment)))
+
+
+(define (record? obj)
+  (and (struct? obj) (record-type? (struct-vtable obj))))
+
+(define (record-type-descriptor obj)
+  (if (struct? obj)
+      (struct-vtable obj)
+      (error 'not-a-record obj)))
+
+(provide 'record)
+
+
+;;; {Booleans}
+;;;
+
+(define (->bool x) (not (not x)))
+
+
+;;; {Symbols}
+;;;
+
+(define (symbol-append . args)
+  (string->symbol (apply string-append (map symbol->string args))))
+
+(define (list->symbol . args)
+  (string->symbol (apply list->string args)))
+
+(define (symbol . args)
+  (string->symbol (apply string args)))
+
+
+;;; {Lists}
+;;;
+
+(define (list-index l k)
+  (let loop ((n 0)
+	     (l l))
+    (and (not (null? l))
+	 (if (eq? (car l) k)
+	     n
+	     (loop (+ n 1) (cdr l))))))
+
+(define (make-list n . init)
+  (if (pair? init) (set! init (car init)))
+  (let loop ((answer '())
+	     (n n))
+    (if (<= n 0)
+	answer
+	(loop (cons init answer) (- n 1)))))
+
+
+;;; {and-map and or-map}
+;;;
+;;; (and-map fn lst) is like (and (fn (car lst)) (fn (cadr lst)) (fn...) ...)
+;;; (or-map fn lst) is like (or (fn (car lst)) (fn (cadr lst)) (fn...) ...)
+;;;
+
+;; and-map f l
+;;
+;; Apply f to successive elements of l until exhaustion or f returns #f.
+;; If returning early, return #f.  Otherwise, return the last value returned
+;; by f.  If f has never been called because l is empty, return #t.
+;;
+(define (and-map f lst)
+  (let loop ((result #t)
+	     (l lst))
+    (and result
+	 (or (and (null? l)
+		  result)
+	     (loop (f (car l)) (cdr l))))))
+
+;; or-map f l
+;;
+;; Apply f to successive elements of l until exhaustion or while f returns #f.
+;; If returning early, return the return value of f.
+;;
+(define (or-map f lst)
+  (let loop ((result #f)
+	     (l lst))
+    (or result
+	(and (not (null? l))
+	     (loop (f (car l)) (cdr l))))))
+
+
+
+(if (provided? 'posix)
+    (primitive-load-path "ice-9/posix.scm"))
+
+(if (provided? 'socket)
+    (primitive-load-path "ice-9/networking.scm"))
+
+(define file-exists?
+  (if (provided? 'posix)
+      (lambda (str)
+	(->bool (false-if-exception (stat str))))
+      (lambda (str)
+	(let ((port (catch 'system-error (lambda () (open-file str OPEN_READ))
+			   (lambda args #f))))
+	  (if port (begin (close-port port) #t)
+	      #f)))))
+
+(define file-is-directory?
+  (if (provided? 'posix)
+      (lambda (str)
+	(eq? (stat:type (stat str)) 'directory))
+      (lambda (str)
+	(let ((port (catch 'system-error
+			   (lambda () (open-file (string-append str "/.")
+						 OPEN_READ))
+			   (lambda args #f))))
+	  (if port (begin (close-port port) #t)
+	      #f)))))
+
+(define (has-suffix? str suffix)
+  (let ((sufl (string-length suffix))
+	(sl (string-length str)))
+    (and (> sl sufl)
+	 (string=? (substring str (- sl sufl) sl) suffix))))
+
+(define (system-error-errno args)
+  (if (eq? (car args) 'system-error)
+      (car (list-ref args 4))
+      #f))
+
+
+;;; {Error Handling}
+;;;
+
+(define (error . args)
+  (save-stack)
+  (if (null? args)
+      (scm-error 'misc-error #f "?" #f #f)
+      (let loop ((msg "~A")
+		 (rest (cdr args)))
+	(if (not (null? rest))
+	    (loop (string-append msg " ~S")
+		  (cdr rest))
+	    (scm-error 'misc-error #f msg args #f)))))
+
+;; bad-throw is the hook that is called upon a throw to a an unhandled
+;; key (unless the throw has four arguments, in which case
+;; it's usually interpreted as an error throw.)
+;; If the key has a default handler (a throw-handler-default property),
+;; it is applied to the throw.
+;;
+(define (bad-throw key . args)
+  (let ((default (symbol-property key 'throw-handler-default)))
+    (or (and default (apply default key args))
+	(apply error "unhandled-exception:" key args))))
+
+
+
+(define (tm:sec obj) (vector-ref obj 0))
+(define (tm:min obj) (vector-ref obj 1))
+(define (tm:hour obj) (vector-ref obj 2))
+(define (tm:mday obj) (vector-ref obj 3))
+(define (tm:mon obj) (vector-ref obj 4))
+(define (tm:year obj) (vector-ref obj 5))
+(define (tm:wday obj) (vector-ref obj 6))
+(define (tm:yday obj) (vector-ref obj 7))
+(define (tm:isdst obj) (vector-ref obj 8))
+(define (tm:gmtoff obj) (vector-ref obj 9))
+(define (tm:zone obj) (vector-ref obj 10))
+
+(define (set-tm:sec obj val) (vector-set! obj 0 val))
+(define (set-tm:min obj val) (vector-set! obj 1 val))
+(define (set-tm:hour obj val) (vector-set! obj 2 val))
+(define (set-tm:mday obj val) (vector-set! obj 3 val))
+(define (set-tm:mon obj val) (vector-set! obj 4 val))
+(define (set-tm:year obj val) (vector-set! obj 5 val))
+(define (set-tm:wday obj val) (vector-set! obj 6 val))
+(define (set-tm:yday obj val) (vector-set! obj 7 val))
+(define (set-tm:isdst obj val) (vector-set! obj 8 val))
+(define (set-tm:gmtoff obj val) (vector-set! obj 9 val))
+(define (set-tm:zone obj val) (vector-set! obj 10 val))
+
+(define (tms:clock obj) (vector-ref obj 0))
+(define (tms:utime obj) (vector-ref obj 1))
+(define (tms:stime obj) (vector-ref obj 2))
+(define (tms:cutime obj) (vector-ref obj 3))
+(define (tms:cstime obj) (vector-ref obj 4))
+
+(define file-position ftell)
+(define (file-set-position port offset . whence)
+  (let ((whence (if (eq? whence '()) SEEK_SET (car whence))))
+    (seek port offset whence)))
+
+(define (move->fdes fd/port fd)
+  (cond ((integer? fd/port)
+	 (dup->fdes fd/port fd)
+	 (close fd/port)
+	 fd)
+	(else
+	 (primitive-move->fdes fd/port fd)
+	 (set-port-revealed! fd/port 1)
+	 fd/port)))
+
+(define (release-port-handle port)
+  (let ((revealed (port-revealed port)))
+    (if (> revealed 0)
+	(set-port-revealed! port (- revealed 1)))))
+
+(define (dup->port port/fd mode . maybe-fd)
+  (let ((port (fdopen (apply dup->fdes port/fd maybe-fd)
+		      mode)))
+    (if (pair? maybe-fd)
+	(set-port-revealed! port 1))
+    port))
+
+(define (dup->inport port/fd . maybe-fd)
+  (apply dup->port port/fd "r" maybe-fd))
+
+(define (dup->outport port/fd . maybe-fd)
+  (apply dup->port port/fd "w" maybe-fd))
+
+(define (dup port/fd . maybe-fd)
+  (if (integer? port/fd)
+      (apply dup->fdes port/fd maybe-fd)
+      (apply dup->port port/fd (port-mode port/fd) maybe-fd)))
+
+(define (duplicate-port port modes)
+  (dup->port port modes))
+
+(define (fdes->inport fdes)
+  (let loop ((rest-ports (fdes->ports fdes)))
+    (cond ((null? rest-ports)
+	   (let ((result (fdopen fdes "r")))
+	     (set-port-revealed! result 1)
+	     result))
+	  ((input-port? (car rest-ports))
+	   (set-port-revealed! (car rest-ports)
+			       (+ (port-revealed (car rest-ports)) 1))
+	   (car rest-ports))
+	  (else
+	   (loop (cdr rest-ports))))))
+
+(define (fdes->outport fdes)
+  (let loop ((rest-ports (fdes->ports fdes)))
+    (cond ((null? rest-ports)
+	   (let ((result (fdopen fdes "w")))
+	     (set-port-revealed! result 1)
+	     result))
+	  ((output-port? (car rest-ports))
+	   (set-port-revealed! (car rest-ports)
+			       (+ (port-revealed (car rest-ports)) 1))
+	   (car rest-ports))
+	  (else
+	   (loop (cdr rest-ports))))))
+
+(define (port->fdes port)
+  (set-port-revealed! port (+ (port-revealed port) 1))
+  (fileno port))
+
+(define (setenv name value)
+  (if value
+      (putenv (string-append name "=" value))
+      (putenv name)))
+
+
+;;; {Load Paths}
+;;;
+
+;;; Here for backward compatability
+;;
+(define scheme-file-suffix (lambda () ".scm"))
+
+(define (in-vicinity vicinity file)
+  (let ((tail (let ((len (string-length vicinity)))
+		(if (zero? len)
+		    #f
+		    (string-ref vicinity (- len 1))))))
+    (string-append vicinity
+		   (if (or (not tail)
+			   (eq? tail #\/))
+		       ""
+		       "/")
+		   file)))
+
+
+;;; {Help for scm_shell}
+;;; The argument-processing code used by Guile-based shells generates
+;;; Scheme code based on the argument list.  This page contains help
+;;; functions for the code it generates.
+
+(define (command-line) (program-arguments))
+
+;; This is mostly for the internal use of the code generated by
+;; scm_compile_shell_switches.
+(define (load-user-init)
+  (let* ((home (or (getenv "HOME")
+		   (false-if-exception (passwd:dir (getpwuid (getuid))))
+		   "/"))  ;; fallback for cygwin etc.
+	 (init-file (in-vicinity home ".guile")))
+    (if (file-exists? init-file)
+	(primitive-load init-file))))
+
+
+;;; {Loading by paths}
+
+;;; Load a Scheme source file named NAME, searching for it in the
+;;; directories listed in %load-path, and applying each of the file
+;;; name extensions listed in %load-extensions.
+(define (load-from-path name)
+  (start-stack 'load-stack
+	       (primitive-load-path name)))
+
+
+
+;;; {Transcendental Functions}
+;;;
+;;; Derived from "Transcen.scm", Complex trancendental functions for SCM.
+;;; Written by Jerry D. Hedden, (C) FSF.
+;;; See the file `COPYING' for terms applying to this program.
+;;;
+
+(define (exp z)
+  (if (real? z) ($exp z)
+      (make-polar ($exp (real-part z)) (imag-part z))))
+
+(define (log z)
+  (if (and (real? z) (>= z 0))
+      ($log z)
+      (make-rectangular ($log (magnitude z)) (angle z))))
+
+(define (sqrt z)
+  (if (real? z)
+      (if (negative? z) (make-rectangular 0 ($sqrt (- z)))
+	  ($sqrt z))
+      (make-polar ($sqrt (magnitude z)) (/ (angle z) 2))))
+
+(define expt
+  (let ((integer-expt integer-expt))
+    (lambda (z1 z2)
+      (cond ((integer? z2)
+             (if (negative? z2)
+		 (/ 1 (integer-expt z1 (- z2)))
+		 (integer-expt z1 z2)))
+	    ((and (real? z2) (real? z1) (>= z1 0))
+	     ($expt z1 z2))
+	    (else
+	     (exp (* z2 (log z1))))))))
+
+(define (sinh z)
+  (if (real? z) ($sinh z)
+      (let ((x (real-part z)) (y (imag-part z)))
+	(make-rectangular (* ($sinh x) ($cos y))
+			  (* ($cosh x) ($sin y))))))
+(define (cosh z)
+  (if (real? z) ($cosh z)
+      (let ((x (real-part z)) (y (imag-part z)))
+	(make-rectangular (* ($cosh x) ($cos y))
+			  (* ($sinh x) ($sin y))))))
+(define (tanh z)
+  (if (real? z) ($tanh z)
+      (let* ((x (* 2 (real-part z)))
+	     (y (* 2 (imag-part z)))
+	     (w (+ ($cosh x) ($cos y))))
+	(make-rectangular (/ ($sinh x) w) (/ ($sin y) w)))))
+
+(define (asinh z)
+  (if (real? z) ($asinh z)
+      (log (+ z (sqrt (+ (* z z) 1))))))
+
+(define (acosh z)
+  (if (and (real? z) (>= z 1))
+      ($acosh z)
+      (log (+ z (sqrt (- (* z z) 1))))))
+
+(define (atanh z)
+  (if (and (real? z) (> z -1) (< z 1))
+      ($atanh z)
+      (/ (log (/ (+ 1 z) (- 1 z))) 2)))
+
+(define (sin z)
+  (if (real? z) ($sin z)
+      (let ((x (real-part z)) (y (imag-part z)))
+	(make-rectangular (* ($sin x) ($cosh y))
+			  (* ($cos x) ($sinh y))))))
+(define (cos z)
+  (if (real? z) ($cos z)
+      (let ((x (real-part z)) (y (imag-part z)))
+	(make-rectangular (* ($cos x) ($cosh y))
+			  (- (* ($sin x) ($sinh y)))))))
+(define (tan z)
+  (if (real? z) ($tan z)
+      (let* ((x (* 2 (real-part z)))
+	     (y (* 2 (imag-part z)))
+	     (w (+ ($cos x) ($cosh y))))
+	(make-rectangular (/ ($sin x) w) (/ ($sinh y) w)))))
+
+(define (asin z)
+  (if (and (real? z) (>= z -1) (<= z 1))
+      ($asin z)
+      (* -i (asinh (* +i z)))))
+
+(define (acos z)
+  (if (and (real? z) (>= z -1) (<= z 1))
+      ($acos z)
+      (+ (/ (angle -1) 2) (* +i (asinh (* +i z))))))
+
+(define (atan z . y)
+  (if (null? y)
+      (if (real? z) ($atan z)
+	  (/ (log (/ (- +i z) (+ +i z))) +2i))
+      ($atan2 z (car y))))
+
+(define (log10 arg)
+  (/ (log arg) (log 10)))
+
+
+
+;;; {Reader Extensions}
+;;;
+
+;;; Reader code for various "#c" forms.
+;;;
+
+(read-hash-extend #\' (lambda (c port)
+			(read port)))
+
+(define read-eval? (make-fluid))
+(fluid-set! read-eval? #f)
+(read-hash-extend #\.
+                  (lambda (c port)
+                    (if (fluid-ref read-eval?)
+                        (eval (read port) (interaction-environment))
+                        (error
+                         "#. read expansion found and read-eval? is #f."))))
+
+
+;;; {Command Line Options}
+;;;
+
+(define (get-option argv kw-opts kw-args return)
+  (cond
+   ((null? argv)
+    (return #f #f argv))
+
+   ((or (not (eq? #\- (string-ref (car argv) 0)))
+	(eq? (string-length (car argv)) 1))
+    (return 'normal-arg (car argv) (cdr argv)))
+
+   ((eq? #\- (string-ref (car argv) 1))
+    (let* ((kw-arg-pos (or (string-index (car argv) #\=)
+			   (string-length (car argv))))
+	   (kw (symbol->keyword (substring (car argv) 2 kw-arg-pos)))
+	   (kw-opt? (member kw kw-opts))
+	   (kw-arg? (member kw kw-args))
+	   (arg (or (and (not (eq? kw-arg-pos (string-length (car argv))))
+			 (substring (car argv)
+				    (+ kw-arg-pos 1)
+				    (string-length (car argv))))
+		    (and kw-arg?
+			 (begin (set! argv (cdr argv)) (car argv))))))
+      (if (or kw-opt? kw-arg?)
+	  (return kw arg (cdr argv))
+	  (return 'usage-error kw (cdr argv)))))
+
+   (else
+    (let* ((char (substring (car argv) 1 2))
+	   (kw (symbol->keyword char)))
+      (cond
+
+       ((member kw kw-opts)
+	(let* ((rest-car (substring (car argv) 2 (string-length (car argv))))
+	       (new-argv (if (= 0 (string-length rest-car))
+			     (cdr argv)
+			     (cons (string-append "-" rest-car) (cdr argv)))))
+	  (return kw #f new-argv)))
+
+       ((member kw kw-args)
+	(let* ((rest-car (substring (car argv) 2 (string-length (car argv))))
+	       (arg (if (= 0 (string-length rest-car))
+			(cadr argv)
+			rest-car))
+	       (new-argv (if (= 0 (string-length rest-car))
+			     (cddr argv)
+			     (cdr argv))))
+	  (return kw arg new-argv)))
+
+       (else (return 'usage-error kw argv)))))))
+
+(define (for-next-option proc argv kw-opts kw-args)
+  (let loop ((argv argv))
+    (get-option argv kw-opts kw-args
+		(lambda (opt opt-arg argv)
+		  (and opt (proc opt opt-arg argv loop))))))
+
+(define (display-usage-report kw-desc)
+  (for-each
+   (lambda (kw)
+     (or (eq? (car kw) #t)
+	 (eq? (car kw) 'else)
+	 (let* ((opt-desc kw)
+		(help (cadr opt-desc))
+		(opts (car opt-desc))
+		(opts-proper (if (string? (car opts)) (cdr opts) opts))
+		(arg-name (if (string? (car opts))
+			      (string-append "<" (car opts) ">")
+			      ""))
+		(left-part (string-append
+			    (with-output-to-string
+			      (lambda ()
+				(map (lambda (x) (display (keyword->symbol x)) (display " "))
+				     opts-proper)))
+			    arg-name))
+		(middle-part (if (and (< (string-length left-part) 30)
+				      (< (string-length help) 40))
+				 (make-string (- 30 (string-length left-part)) #\ )
+				 "\n\t")))
+	   (display left-part)
+	   (display middle-part)
+	   (display help)
+	   (newline))))
+   kw-desc))
+
+
+
+(define (transform-usage-lambda cases)
+  (let* ((raw-usage (delq! 'else (map car cases)))
+	 (usage-sans-specials (map (lambda (x)
+				    (or (and (not (list? x)) x)
+					(and (symbol? (car x)) #t)
+					(and (boolean? (car x)) #t)
+					x))
+				  raw-usage))
+	 (usage-desc (delq! #t usage-sans-specials))
+	 (kw-desc (map car usage-desc))
+	 (kw-opts (apply append (map (lambda (x) (and (not (string? (car x))) x)) kw-desc)))
+	 (kw-args (apply append (map (lambda (x) (and (string? (car x)) (cdr x))) kw-desc)))
+	 (transmogrified-cases (map (lambda (case)
+				      (cons (let ((opts (car case)))
+					      (if (or (boolean? opts) (eq? 'else opts))
+						  opts
+						  (cond
+						   ((symbol? (car opts))  opts)
+						   ((boolean? (car opts)) opts)
+						   ((string? (caar opts)) (cdar opts))
+						   (else (car opts)))))
+					    (cdr case)))
+				    cases)))
+    `(let ((%display-usage (lambda () (display-usage-report ',usage-desc))))
+       (lambda (%argv)
+	 (let %next-arg ((%argv %argv))
+	   (get-option %argv
+		       ',kw-opts
+		       ',kw-args
+		       (lambda (%opt %arg %new-argv)
+			 (case %opt
+			   ,@ transmogrified-cases))))))))
+
+
+
+
+;;; {Low Level Modules}
+;;;
+;;; These are the low level data structures for modules.
+;;;
+;;; !!! warning: The interface to lazy binder procedures is going
+;;; to be changed in an incompatible way to permit all the basic
+;;; module ops to be virtualized.
+;;;
+;;; (make-module size use-list lazy-binding-proc) => module
+;;; module-{obarray,uses,binder}[|-set!]
+;;; (module? obj) => [#t|#f]
+;;; (module-locally-bound? module symbol) => [#t|#f]
+;;; (module-bound? module symbol) => [#t|#f]
+;;; (module-symbol-locally-interned? module symbol) => [#t|#f]
+;;; (module-symbol-interned? module symbol) => [#t|#f]
+;;; (module-local-variable module symbol) => [#<variable ...> | #f]
+;;; (module-variable module symbol) => [#<variable ...> | #f]
+;;; (module-symbol-binding module symbol opt-value)
+;;;		=> [ <obj> | opt-value | an error occurs ]
+;;; (module-make-local-var! module symbol) => #<variable...>
+;;; (module-add! module symbol var) => unspecified
+;;; (module-remove! module symbol) =>  unspecified
+;;; (module-for-each proc module) => unspecified
+;;; (make-scm-module) => module ; a lazy copy of the symhash module
+;;; (set-current-module module) => unspecified
+;;; (current-module) => #<module...>
+;;;
+;;;
+
+
+;;; {Printing Modules}
+;; This is how modules are printed.  You can re-define it.
+;; (Redefining is actually more complicated than simply redefining
+;; %print-module because that would only change the binding and not
+;; the value stored in the vtable that determines how record are
+;; printed. Sigh.)
+
+(define (%print-module mod port)  ; unused args: depth length style table)
+  (display "#<" port)
+  (display (or (module-kind mod) "module") port)
+  (let ((name (module-name mod)))
+    (if name
+	(begin
+	  (display " " port)
+	  (display name port))))
+  (display " " port)
+  (display (number->string (object-address mod) 16) port)
+  (display ">" port))
+
+;; module-type
+;;
+;; A module is characterized by an obarray in which local symbols
+;; are interned, a list of modules, "uses", from which non-local
+;; bindings can be inherited, and an optional lazy-binder which
+;; is a (CLOSURE module symbol) which, as a last resort, can provide
+;; bindings that would otherwise not be found locally in the module.
+;;
+;; NOTE: If you change here, you also need to change libguile/modules.h.
+;;
+(define module-type
+  (make-record-type 'module
+		    '(obarray uses binder eval-closure transformer name kind
+			      observers weak-observers observer-id)
+		    %print-module))
+
+;; make-module &opt size uses binder
+;;
+;; Create a new module, perhaps with a particular size of obarray,
+;; initial uses list, or binding procedure.
+;;
+(define make-module
+    (lambda args
+
+      (define (parse-arg index default)
+	(if (> (length args) index)
+	    (list-ref args index)
+	    default))
+
+      (if (> (length args) 3)
+	  (error "Too many args to make-module." args))
+
+      (let ((size (parse-arg 0 1021))
+	    (uses (parse-arg 1 '()))
+	    (binder (parse-arg 2 #f)))
+
+	(if (not (integer? size))
+	    (error "Illegal size to make-module." size))
+	(if (not (and (list? uses)
+		      (and-map module? uses)))
+	    (error "Incorrect use list." uses))
+	(if (and binder (not (procedure? binder)))
+	    (error
+	     "Lazy-binder expected to be a procedure or #f." binder))
+
+	(let ((module (module-constructor (make-vector size '())
+					  uses binder #f #f #f #f
+					  '()
+					  (make-weak-value-hash-table 31)
+					  0)))
+
+	  ;; We can't pass this as an argument to module-constructor,
+	  ;; because we need it to close over a pointer to the module
+	  ;; itself.
+	  (set-module-eval-closure! module (standard-eval-closure module))
+
+	  module))))
+
+(define module-constructor (record-constructor module-type))
+(define module-obarray  (record-accessor module-type 'obarray))
+(define set-module-obarray! (record-modifier module-type 'obarray))
+(define module-uses  (record-accessor module-type 'uses))
+(define set-module-uses! (record-modifier module-type 'uses))
+(define module-binder (record-accessor module-type 'binder))
+(define set-module-binder! (record-modifier module-type 'binder))
+
+;; NOTE: This binding is used in libguile/modules.c.
+(define module-eval-closure (record-accessor module-type 'eval-closure))
+
+(define module-transformer (record-accessor module-type 'transformer))
+(define set-module-transformer! (record-modifier module-type 'transformer))
+(define module-name (record-accessor module-type 'name))
+(define set-module-name! (record-modifier module-type 'name))
+(define module-kind (record-accessor module-type 'kind))
+(define set-module-kind! (record-modifier module-type 'kind))
+(define module-observers (record-accessor module-type 'observers))
+(define set-module-observers! (record-modifier module-type 'observers))
+(define module-weak-observers (record-accessor module-type 'weak-observers))
+(define module-observer-id (record-accessor module-type 'observer-id))
+(define set-module-observer-id! (record-modifier module-type 'observer-id))
+(define module? (record-predicate module-type))
+
+(define set-module-eval-closure!
+  (let ((setter (record-modifier module-type 'eval-closure)))
+    (lambda (module closure)
+      (setter module closure)
+      ;; Make it possible to lookup the module from the environment.
+      ;; This implementation is correct since an eval closure can belong
+      ;; to maximally one module.
+      (set-procedure-property! closure 'module module))))
+
+(begin-deprecated
+ (define (eval-in-module exp mod)
+   (issue-deprecation-warning
+    "`eval-in-module' is deprecated.  Use `eval' instead.")
+   (eval exp mod)))
+
+
+;;; {Observer protocol}
+;;;
+
+(define (module-observe module proc)
+  (set-module-observers! module (cons proc (module-observers module)))
+  (cons module proc))
+
+(define (module-observe-weak module proc)
+  (let ((id (module-observer-id module)))
+    (hash-set! (module-weak-observers module) id proc)
+    (set-module-observer-id! module (+ 1 id))
+    (cons module id)))
+
+(define (module-unobserve token)
+  (let ((module (car token))
+	(id (cdr token)))
+    (if (integer? id)
+	(hash-remove! (module-weak-observers module) id)
+	(set-module-observers! module (delq1! id (module-observers module)))))
+  *unspecified*)
+
+(define (module-modified m)
+  (for-each (lambda (proc) (proc m)) (module-observers m))
+  (hash-fold (lambda (id proc res) (proc m)) #f (module-weak-observers m)))
+
+
+;;; {Module Searching in General}
+;;;
+;;; We sometimes want to look for properties of a symbol
+;;; just within the obarray of one module.  If the property
+;;; holds, then it is said to hold ``locally'' as in, ``The symbol
+;;; DISPLAY is locally rebound in the module `safe-guile'.''
+;;;
+;;;
+;;; Other times, we want to test for a symbol property in the obarray
+;;; of M and, if it is not found there, try each of the modules in the
+;;; uses list of M.  This is the normal way of testing for some
+;;; property, so we state these properties without qualification as
+;;; in: ``The symbol 'fnord is interned in module M because it is
+;;; interned locally in module M2 which is a member of the uses list
+;;; of M.''
+;;;
+
+;; module-search fn m
+;;
+;; return the first non-#f result of FN applied to M and then to
+;; the modules in the uses of m, and so on recursively.  If all applications
+;; return #f, then so does this function.
+;;
+(define (module-search fn m v)
+  (define (loop pos)
+    (and (pair? pos)
+	 (or (module-search fn (car pos) v)
+	     (loop (cdr pos)))))
+  (or (fn m v)
+      (loop (module-uses m))))
+
+
+;;; {Is a symbol bound in a module?}
+;;;
+;;; Symbol S in Module M is bound if S is interned in M and if the binding
+;;; of S in M has been set to some well-defined value.
+;;;
+
+;; module-locally-bound? module symbol
+;;
+;; Is a symbol bound (interned and defined) locally in a given module?
+;;
+(define (module-locally-bound? m v)
+  (let ((var (module-local-variable m v)))
+    (and var
+	 (variable-bound? var))))
+
+;; module-bound? module symbol
+;;
+;; Is a symbol bound (interned and defined) anywhere in a given module
+;; or its uses?
+;;
+(define (module-bound? m v)
+  (module-search module-locally-bound? m v))
+
+;;; {Is a symbol interned in a module?}
+;;;
+;;; Symbol S in Module M is interned if S occurs in
+;;; of S in M has been set to some well-defined value.
+;;;
+;;; It is possible to intern a symbol in a module without providing
+;;; an initial binding for the corresponding variable.  This is done
+;;; with:
+;;;       (module-add! module symbol (make-undefined-variable))
+;;;
+;;; In that case, the symbol is interned in the module, but not
+;;; bound there.  The unbound symbol shadows any binding for that
+;;; symbol that might otherwise be inherited from a member of the uses list.
+;;;
+
+(define (module-obarray-get-handle ob key)
+  ((if (symbol? key) hashq-get-handle hash-get-handle) ob key))
+
+(define (module-obarray-ref ob key)
+  ((if (symbol? key) hashq-ref hash-ref) ob key))
+
+(define (module-obarray-set! ob key val)
+  ((if (symbol? key) hashq-set! hash-set!) ob key val))
+
+(define (module-obarray-remove! ob key)
+  ((if (symbol? key) hashq-remove! hash-remove!) ob key))
+
+;; module-symbol-locally-interned? module symbol
+;;
+;; is a symbol interned (not neccessarily defined) locally in a given module
+;; or its uses?  Interned symbols shadow inherited bindings even if
+;; they are not themselves bound to a defined value.
+;;
+(define (module-symbol-locally-interned? m v)
+  (not (not (module-obarray-get-handle (module-obarray m) v))))
+
+;; module-symbol-interned? module symbol
+;;
+;; is a symbol interned (not neccessarily defined) anywhere in a given module
+;; or its uses?  Interned symbols shadow inherited bindings even if
+;; they are not themselves bound to a defined value.
+;;
+(define (module-symbol-interned? m v)
+  (module-search module-symbol-locally-interned? m v))
+
+
+;;; {Mapping modules x symbols --> variables}
+;;;
+
+;; module-local-variable module symbol
+;; return the local variable associated with a MODULE and SYMBOL.
+;;
+;;; This function is very important. It is the only function that can
+;;; return a variable from a module other than the mutators that store
+;;; new variables in modules.  Therefore, this function is the location
+;;; of the "lazy binder" hack.
+;;;
+;;; If symbol is defined in MODULE, and if the definition binds symbol
+;;; to a variable, return that variable object.
+;;;
+;;; If the symbols is not found at first, but the module has a lazy binder,
+;;; then try the binder.
+;;;
+;;; If the symbol is not found at all, return #f.
+;;;
+(define (module-local-variable m v)
+;  (caddr
+;   (list m v
+	 (let ((b (module-obarray-ref (module-obarray m) v)))
+	   (or (and (variable? b) b)
+	       (and (module-binder m)
+		    ((module-binder m) m v #f)))))
+;))
+
+;; module-variable module symbol
+;;
+;; like module-local-variable, except search the uses in the
+;; case V is not found in M.
+;;
+;; NOTE: This function is superseded with C code (see modules.c)
+;;;      when using the standard eval closure.
+;;
+(define (module-variable m v)
+  (module-search module-local-variable m v))
+
+
+;;; {Mapping modules x symbols --> bindings}
+;;;
+;;; These are similar to the mapping to variables, except that the
+;;; variable is dereferenced.
+;;;
+
+;; module-symbol-binding module symbol opt-value
+;;
+;; return the binding of a variable specified by name within
+;; a given module, signalling an error if the variable is unbound.
+;; If the OPT-VALUE is passed, then instead of signalling an error,
+;; return OPT-VALUE.
+;;
+(define (module-symbol-local-binding m v . opt-val)
+  (let ((var (module-local-variable m v)))
+    (if var
+	(variable-ref var)
+	(if (not (null? opt-val))
+	    (car opt-val)
+	    (error "Locally unbound variable." v)))))
+
+;; module-symbol-binding module symbol opt-value
+;;
+;; return the binding of a variable specified by name within
+;; a given module, signalling an error if the variable is unbound.
+;; If the OPT-VALUE is passed, then instead of signalling an error,
+;; return OPT-VALUE.
+;;
+(define (module-symbol-binding m v . opt-val)
+  (let ((var (module-variable m v)))
+    (if var
+	(variable-ref var)
+	(if (not (null? opt-val))
+	    (car opt-val)
+	    (error "Unbound variable." v)))))
+
+
+
+;;; {Adding Variables to Modules}
+;;;
+;;;
+
+
+;; module-make-local-var! module symbol
+;;
+;; ensure a variable for V in the local namespace of M.
+;; If no variable was already there, then create a new and uninitialzied
+;; variable.
+;;
+(define (module-make-local-var! m v)
+  (or (let ((b (module-obarray-ref (module-obarray m) v)))
+	(and (variable? b)
+	     (begin
+	       (module-modified m)
+	       b)))
+      (and (module-binder m)
+	   ((module-binder m) m v #t))
+      (begin
+	(let ((answer (make-undefined-variable)))
+	  (variable-set-name-hint! answer v)
+	  (module-obarray-set! (module-obarray m) v answer)
+	  (module-modified m)
+	  answer))))
+
+;; module-ensure-local-variable! module symbol
+;;
+;; Ensure that there is a local variable in MODULE for SYMBOL.  If
+;; there is no binding for SYMBOL, create a new uninitialized
+;; variable.  Return the local variable.
+;;
+(define (module-ensure-local-variable! module symbol)
+  (or (module-local-variable module symbol)
+      (let ((var (make-undefined-variable)))
+	(variable-set-name-hint! var symbol)
+	(module-add! module symbol var)
+	var)))
+
+;; module-add! module symbol var
+;;
+;; ensure a particular variable for V in the local namespace of M.
+;;
+(define (module-add! m v var)
+  (if (not (variable? var))
+      (error "Bad variable to module-add!" var))
+  (module-obarray-set! (module-obarray m) v var)
+  (module-modified m))
+
+;; module-remove!
+;;
+;; make sure that a symbol is undefined in the local namespace of M.
+;;
+(define (module-remove! m v)
+  (module-obarray-remove!  (module-obarray m) v)
+  (module-modified m))
+
+(define (module-clear! m)
+  (vector-fill! (module-obarray m) '())
+  (module-modified m))
+
+;; MODULE-FOR-EACH -- exported
+;;
+;; Call PROC on each symbol in MODULE, with arguments of (SYMBOL VARIABLE).
+;;
+(define (module-for-each proc module)
+  (let ((obarray (module-obarray module)))
+    (do ((index 0 (+ index 1))
+	 (end (vector-length obarray)))
+	((= index end))
+      (for-each
+       (lambda (bucket)
+	 (proc (car bucket) (cdr bucket)))
+       (vector-ref obarray index)))))
+
+
+(define (module-map proc module)
+  (let* ((obarray (module-obarray module))
+	 (end (vector-length obarray)))
+
+    (let loop ((i 0)
+	       (answer '()))
+      (if (= i end)
+	  answer
+	  (loop (+ 1 i)
+		(append!
+		 (map (lambda (bucket)
+			(proc (car bucket) (cdr bucket)))
+		      (vector-ref obarray i))
+		 answer))))))
+
+
+;;; {Low Level Bootstrapping}
+;;;
+
+;; make-root-module
+
+;; A root module uses the pre-modules-obarray as its obarray.  This
+;; special obarray accumulates all bindings that have been established
+;; before the module system is fully booted.
+;;
+;; (The obarray continues to be used by code that has been closed over
+;;  before the module system has been booted.)
+
+(define (make-root-module)
+  (let ((m (make-module 0)))
+    (set-module-obarray! m (%get-pre-modules-obarray))
+    m))
+
+;; make-scm-module
+
+;; The root interface is a module that uses the same obarray as the
+;; root module.  It does not allow new definitions, tho.
+
+(define (make-scm-module)
+  (let ((m (make-module 0)))
+    (set-module-obarray! m (%get-pre-modules-obarray))
+    (set-module-eval-closure! m (standard-interface-eval-closure m))
+    m))
+
+
+
+;;; {Module-based Loading}
+;;;
+
+(define (save-module-excursion thunk)
+  (let ((inner-module (current-module))
+	(outer-module #f))
+    (dynamic-wind (lambda ()
+		    (set! outer-module (current-module))
+		    (set-current-module inner-module)
+		    (set! inner-module #f))
+		  thunk
+		  (lambda ()
+		    (set! inner-module (current-module))
+		    (set-current-module outer-module)
+		    (set! outer-module #f)))))
+
+(define basic-load load)
+
+(define (load-module filename)
+  (save-module-excursion
+   (lambda ()
+     (let ((oldname (and (current-load-port)
+			 (port-filename (current-load-port)))))
+       (basic-load (if (and oldname
+			    (> (string-length filename) 0)
+			    (not (char=? (string-ref filename 0) #\/))
+			    (not (string=? (dirname oldname) ".")))
+		       (string-append (dirname oldname) "/" filename)
+		       filename))))))
+
+
+
+;;; {MODULE-REF -- exported}
+;;
+;; Returns the value of a variable called NAME in MODULE or any of its
+;; used modules.  If there is no such variable, then if the optional third
+;; argument DEFAULT is present, it is returned; otherwise an error is signaled.
+;;
+(define (module-ref module name . rest)
+  (let ((variable (module-variable module name)))
+    (if (and variable (variable-bound? variable))
+	(variable-ref variable)
+	(if (null? rest)
+	    (error "No variable named" name 'in module)
+	    (car rest)			; default value
+	    ))))
+
+;; MODULE-SET! -- exported
+;;
+;; Sets the variable called NAME in MODULE (or in a module that MODULE uses)
+;; to VALUE; if there is no such variable, an error is signaled.
+;;
+(define (module-set! module name value)
+  (let ((variable (module-variable module name)))
+    (if variable
+	(variable-set! variable value)
+	(error "No variable named" name 'in module))))
+
+;; MODULE-DEFINE! -- exported
+;;
+;; Sets the variable called NAME in MODULE to VALUE; if there is no such
+;; variable, it is added first.
+;;
+(define (module-define! module name value)
+  (let ((variable (module-local-variable module name)))
+    (if variable
+	(begin
+	  (variable-set! variable value)
+	  (module-modified module))
+	(let ((variable (make-variable value)))
+	  (variable-set-name-hint! variable name)
+	  (module-add! module name variable)))))
+
+;; MODULE-DEFINED? -- exported
+;;
+;; Return #t iff NAME is defined in MODULE (or in a module that MODULE
+;; uses)
+;;
+(define (module-defined? module name)
+  (let ((variable (module-variable module name)))
+    (and variable (variable-bound? variable))))
+
+;; MODULE-USE! module interface
+;;
+;; Add INTERFACE to the list of interfaces used by MODULE.
+;;
+(define (module-use! module interface)
+  (set-module-uses! module
+		    (cons interface (delq! interface (module-uses module))))
+  (module-modified module))
+
+
+;;; {Recursive Namespaces}
+;;;
+;;;
+;;; A hierarchical namespace emerges if we consider some module to be
+;;; root, and variables bound to modules as nested namespaces.
+;;;
+;;; The routines in this file manage variable names in hierarchical namespace.
+;;; Each variable name is a list of elements, looked up in successively nested
+;;; modules.
+;;;
+;;;		(nested-ref some-root-module '(foo bar baz))
+;;;		=> <value of a variable named baz in the module bound to bar in
+;;;		    the module bound to foo in some-root-module>
+;;;
+;;;
+;;; There are:
+;;;
+;;;	;; a-root is a module
+;;;	;; name is a list of symbols
+;;;
+;;;	nested-ref a-root name
+;;;	nested-set! a-root name val
+;;;	nested-define! a-root name val
+;;;	nested-remove! a-root name
+;;;
+;;;
+;;; (current-module) is a natural choice for a-root so for convenience there are
+;;; also:
+;;;
+;;;	local-ref name		==	nested-ref (current-module) name
+;;;	local-set! name val	==	nested-set! (current-module) name val
+;;;	local-define! name val	==	nested-define! (current-module) name val
+;;;	local-remove! name	==	nested-remove! (current-module) name
+;;;
+
+
+(define (nested-ref root names)
+  (let loop ((cur root)
+	     (elts names))
+    (cond
+     ((null? elts)		cur)
+     ((not (module? cur))	#f)
+     (else (loop (module-ref cur (car elts) #f) (cdr elts))))))
+
+(define (nested-set! root names val)
+  (let loop ((cur root)
+	     (elts names))
+    (if (null? (cdr elts))
+	(module-set! cur (car elts) val)
+	(loop (module-ref cur (car elts)) (cdr elts)))))
+
+(define (nested-define! root names val)
+  (let loop ((cur root)
+	     (elts names))
+    (if (null? (cdr elts))
+	(module-define! cur (car elts) val)
+	(loop (module-ref cur (car elts)) (cdr elts)))))
+
+(define (nested-remove! root names)
+  (let loop ((cur root)
+	     (elts names))
+    (if (null? (cdr elts))
+	(module-remove! cur (car elts))
+	(loop (module-ref cur (car elts)) (cdr elts)))))
+
+(define (local-ref names) (nested-ref (current-module) names))
+(define (local-set! names val) (nested-set! (current-module) names val))
+(define (local-define names val) (nested-define! (current-module) names val))
+(define (local-remove names) (nested-remove! (current-module) names))
+;;; boot-9.scm ends here
diff --git a/app/server/vendor/rouge/spec/visual/samples/scss b/app/server/vendor/rouge/spec/visual/samples/scss
new file mode 100755
index 0000000..af25a6f
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/scss
@@ -0,0 +1,281 @@
+ at import "compass";
+ at import "blueprint";
+ at import "blueprint/fancy_type";
+
+$blueprint-grid-columns:     5;
+$blueprint-grid-width:       150px;
+$blueprint-grid-margin:      20px;
+
+$blueprint-font-family:      Helvetica Neue, Arial, Helvetica, sans-serif;
+$blueprint-fixed-font-family:'andale mono', 'lucida console', monospace;
+$blueprint-font-size:        12px;
+
+$text-color:                 #555555;
+$light-text-color:           #a0a0a0;
+$quote-text-color:           #f27a00;
+$disclosure-text-color:      #ed7c06;
+
+$thick-border:               8px solid black;
+$dotted-border:              1px dotted #999999;
+
+$header-background-color:    #f07c05;
+$paging-background-color:    black;
+$unfocused-background-color: #f1f0ec;
+$quote-background-color:     #f1f0ec;
+
+$story-title-color:          #f07c05;
+
+ at include global-reset;
+ at include blueprint-typography;
+
+body {
+  background: $unfocused-background-color image_url("white-bg.jpg") repeat-y 50% 0;
+  color: $text-color;
+}
+
+.content_wrapper {
+  @include container;
+  width: 910px;
+}
+
+#header {
+  height: 72px;
+  background: $header-background-color;
+  @include clearfix;
+
+  h1 {
+    color: white;
+    @include float-left;
+    a {
+      @include replace-text("logo.jpg");
+      width: 116px;
+      height: 72px;
+      display: block;
+      text-decoration: none;
+    }
+  }
+
+  ul {
+    @include horizontal-list; 
+    padding: 0 0 0 25px;
+    li {
+      @include incr(18px);
+      padding: 0 20px 0 0;
+      text-transform: uppercase;
+      a { 
+        color: #febf0f;
+        text-decoration: none;
+        width: 100px;
+        height: 72px;
+        display: block;
+      }
+      &#header-threads a {
+        @include replace-text("header-threads-text.jpg");
+      }
+      &#header-timeline a {
+        @include replace-text("header-timeline-text.jpg");
+      }
+    }
+  } 
+}
+
+#paging {
+  background: $paging-background-color;
+  height: 33px;
+  padding: 15px 0 0 0;
+
+  h6 {
+    @include float-left;
+    color: #908f8b;
+    padding-right: 20px;
+    text-transform: uppercase;
+    a { 
+      color: #f07b07; 
+      text-decoration: none;
+    }
+  }
+
+  ul {
+    @include horizontal-list;
+    li {
+      padding: 3px 4px;
+      a { 
+        color: #4c4c4c;
+        @include replace-text("thread-paging-inactive-bullet.jpg");
+        width: 10px;
+        height: 10px;
+        display: block;
+      }
+      &.active a { 
+        color: #f17d06;
+        background-image: image_ at import "compass";
+      }
+    } 
+  }
+}
+
+#content {
+    position: relative;
+    #previous {
+      position: absolute;
+      top: 0;
+      left: 0;
+      text-align: right;
+    }
+    #next {
+      position: absolute;
+      top: 0;
+      right: 0;
+      text-align: left;
+    }
+}
+
+#thread {
+    @include container;
+  width: 910px;
+    top: 0px;
+    left: 0px;
+
+    @include transition-property(left);
+    @include transition-duration(0.5s);
+    @include transition-timing-function(ease-in-out);
+
+    @for $i from 0 through 30 {
+    &.position#{$i} {
+      left: ($i * -910px); 
+    }
+  }
+}
+
+.js {
+  #content {
+    overflow: hidden;
+    width: 100%;
+  }
+
+  #thread { 
+    padding: 0;
+    width: 5000px;
+    position: absolute;
+  }
+}
+
+.story {
+  @include float-left;
+  width: 810px;
+  padding: 0 50px;
+
+  h4.date {
+    @include float-right;
+    @include span(1);
+    background: $unfocused-background-color;
+    padding: 10px 20px;
+    @include border-radius(3px);
+  }
+
+  h1 {
+    padding: 40px 0 20px 0;
+    border-bottom: $thick-border;
+    color: $story-title-color;
+    @include incr(30px);
+  }
+
+  .artifacts {
+    @include column(3);
+
+    .row {
+      @include clearfix;
+      border-bottom: $dotted-border;
+      margin-bottom: $blueprint-grid-margin;
+    }
+
+    .artifact {
+      color: $light-text-color;
+      img {
+        margin-bottom: 0.5em;
+      }
+      a {
+        font-weight: bold;
+        text-decoration: none;
+        color: #0a83e0;
+      }
+    }
+
+    .threecol { @include column(3); }
+    .twocol   { @include column(2); }
+    .onecol   { @include column(1); }
+    .last     { @include last;      }
+  }
+
+  .information {
+    @include column(1.6, true);
+    border-bottom: $dotted-border;
+    margin-left: 40px;
+
+    h2 {
+      @include incr(20px, $blueprint-font-size, 35px);
+    }
+
+    .textblock p {
+      @include incr(13px, $blueprint-font-size, 26px);
+    }
+
+    .quote {
+      color: $quote-text-color;
+      blockquote {
+        @include incr(18px, $blueprint-font-size, 30px);
+        color: $quote-text-color;
+        margin: 0;
+        padding: 12px 18px;
+        background: $quote-background-color;
+        @include border-radius(5px);
+      }
+      cite {
+        display: block;
+        padding: 0.5em 18px 1.5em 18px;
+      }
+    }
+
+    .disclosure {
+      border-top: $dotted-border;
+      h5 {
+        padding: 10px 0;
+        margin: 0;
+        color: $disclosure-text-color;
+      }
+      p {
+        color: #a8a8a8;
+      }
+    }
+  }
+}
+
+#footer {
+  @include container;
+  background: white;
+  width: 810px;
+  padding: $blueprint-grid-margin 0;
+
+  .inner {
+    border-top: $thick-border;
+    padding: 30px 0;
+  }
+
+  p {
+    @include float-right;
+    @include incr(10px);
+    color: #b3b3b3;
+  }
+
+  ul {
+    @include horizontal-list; 
+
+    li {
+      padding: 0 30px 0 0;
+      a { 
+        text-decoration: none;
+        color: #ef7a06; 
+      }
+    } 
+  }
+}
diff --git a/app/server/vendor/rouge/spec/visual/samples/sed b/app/server/vendor/rouge/spec/visual/samples/sed
new file mode 100755
index 0000000..0b7bb36
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/sed
@@ -0,0 +1,2304 @@
+#!/bin/sed -nf
+# sokoban.sed  <http://aurelio.net/sed/sokoban>
+#   by Aurelio Marinho Jargas <verde (a) aurelio net>
+#
+# Motivated by reading the amazing Adventure (Colossal Cave) history
+#      <http://www.rickadams.org/adventure/a_history.html>
+# GPL levels took from Mike Sharpe's sokoban.vim <http://vim.sourceforge.net>
+#
+# IMPORTANT
+# This script has terminal control chars, so you must DOWNLOAD this
+# file. Just copy/paste or printing it to a file (lynx) will NOT work.
+#
+# THE GAME
+# You know sokoban. Everybody knows sokoban.
+# Right, if you don't, it's a box pushing game. You have a mess, boxes
+# all over the room and must place them on the boxes place. To move a
+# box you must push it. You can only push a box if the path is clear
+# with no wall or other box on the way (You are not that strong).
+#
+#   COMMANDS                       MOVING AROUND
+#     :q   quit                      h or <left-arrow>  - move left
+#     :r   restart level             j or <down-arrow>  - move down
+#     :z   refresh screen            k or <up-arrow>    - move up
+#     :gN  go to level N             l or <right-arrow> - move right
+#
+#   ACTORS
+#     o box                  % wall
+#     . box place            @ you
+#     O box placed right     ! you over a box place
+#
+#
+# RUNNING
+# prompt$ ./sokoban.sed <enter>
+# <enter>
+# 1
+# Now just move! (:q quits)
+#
+# DETAILS
+# It's all written in SED, so we've got some limitations:
+# - As a line-oriented editor, you MUST hit <ENTER> after *any* move.
+#   Yes, that sucks. But you can accumulate various movements and hit
+#   <ENTER> just once.
+# - When you run sokoban.sed, you must first press any key to feed SED
+#   and then you'll see the welcome message.
+# - If your sed is not on /bin, edit the first line of this script,
+#   or call it as: sed -nf sokoban.sed 
+# - This script is 'sedcheck' <http://lvogel.free.fr/sed/sedcheck.sed>
+#   compliant, so it must run fine in *any* SED version
+#
+# And always remember, it's cool because it's SED. If you don't like it
+# you can try xsokoban instead <http://www.cs.cornell.edu/andru/xsokoban.html>
+#
+# CHANGES
+# 20020315 v0.0 debut release
+# 20020321 v0.1 clear screen, download note, fancy victory, sound ^G, lvl0
+#               fixed * on map bug, added :g, :r and :z commands
+#               pseudo-functions (now it's faster!)
+# 20020709 v0.2 comments prefix '#r' changed to plain '#'. dummy me.
+# 20031011 v0.3 now sokoban is 'sedcheck' compliant, so it will run in
+#               most (all?) SED versions out there (thanks Laurent!)
+
+
+# skip functions
+b zero
+
+# function welcome
+: welcome
+i \
+       Welcome to the SED Sokoban\
+\
+Please select a level to begin [1-90]:
+d  
+
+# function loadmap
+: loadmap
+
+# clear screen
+i \
+
+
+/^0$/ {
+  s/.*/\
+SED Sokoban - LEVEL 0 (victory test)\
+\
+     %%%%%            \
+     %@o.%            \
+     %%%%%            \
+/
+  b endmap
+}  
+/^1$/ {
+  s/.*/\
+SED Sokoban - LEVEL 1\
+\
+     %%%%%            \
+     %   %            \
+     %o  %            \
+   %%%  o%%           \
+   %  o o %           \
+ %%% % %% %   %%%%%%  \
+ %   % %% %%%%%  ..%  \
+ % o  o          ..%  \
+ %%%%% %%% %@%%  ..%  \
+     %     %%%%%%%%%  \
+     %%%%%%%          \
+/
+  b endmap
+}  
+/^2$/ {
+  s/.*/\
+SED Sokoban - LEVEL 2\
+\
+ %%%%%%%%%%%%         \
+ %..  %     %%%       \
+ %..  % o  o  %       \
+ %..  %o%%%%  %       \
+ %..    @ %%  %       \
+ %..  % %  o %%       \
+ %%%%%% %%o o %       \
+   % o  o o o %       \
+   %    %     %       \
+   %%%%%%%%%%%%       \
+/
+  b endmap
+}  
+/^3$/ {
+  s/.*/\
+SED Sokoban - LEVEL 3\
+\
+         %%%%%%%%     \
+         %     @%     \
+         % o%o %%     \
+         % o  o%      \
+         %%o o %      \
+ %%%%%%%%% o % %%%    \
+ %....  %% o  o  %    \
+ %%...    o  o   %    \
+ %....  %%%%%%%%%%    \
+ %%%%%%%%             \
+/
+  b endmap
+}  
+/^4$/ {
+  s/.*/\
+SED Sokoban - LEVEL 4\
+\
+            %%%%%%%%  \
+            %  ....%  \
+ %%%%%%%%%%%%  ....%  \
+ %    %  o o   ....%  \
+ % ooo%o  o %  ....%  \
+ %  o     o %  ....%  \
+ % oo %o o o%%%%%%%%  \
+ %  o %     %         \
+ %% %%%%%%%%%         \
+ %    %    %%         \
+ %     o   %%         \
+ %  oo%oo  @%         \
+ %    %    %%         \
+ %%%%%%%%%%%          \
+/
+  b endmap
+}  
+/^5$/ {
+  s/.*/\
+SED Sokoban - LEVEL 5\
+\
+         %%%%%        \
+         %   %%%%%    \
+         % %o%%  %    \
+         %     o %    \
+ %%%%%%%%% %%%   %    \
+ %....  %% o  o%%%    \
+ %....    o oo %%     \
+ %....  %%o  o @%     \
+ %%%%%%%%%  o  %%     \
+         % o o  %     \
+         %%% %% %     \
+           %    %     \
+           %%%%%%     \
+/
+  b endmap
+}  
+/^6$/ {
+  s/.*/\
+SED Sokoban - LEVEL 6\
+\
+ %%%%%%  %%%          \
+ %..  % %%@%%         \
+ %..  %%%   %         \
+ %..     oo %         \
+ %..  % % o %         \
+ %..%%% % o %         \
+ %%%% o %o  %         \
+    %  o% o %         \
+    % o  o  %         \
+    %  %%   %         \
+    %%%%%%%%%         \
+/
+  b endmap
+}  
+/^7$/ {
+  s/.*/\
+SED Sokoban - LEVEL 7\
+\
+        %%%%%         \
+  %%%%%%%   %%        \
+ %% % @%% oo %        \
+ %    o      %        \
+ %  o  %%%   %        \
+ %%% %%%%%o%%%        \
+ % o  %%% ..%         \
+ % o o o ...%         \
+ %    %%%...%         \
+ % oo % %...%         \
+ %  %%% %%%%%         \
+ %%%%                 \
+/
+  b endmap
+}  
+/^8$/ {
+  s/.*/\
+SED Sokoban - LEVEL 8\
+\
+   %%%%               \
+   %  %%%%%%%%%%%     \
+   %    o   o o %     \
+   % o% o %  o  %     \
+   %  o o  %    %     \
+ %%% o% %  %%%% %     \
+ %@%o o o  %%   %     \
+ %    o %o%   % %     \
+ %   o    o o o %     \
+ %%%%%  %%%%%%%%%     \
+   %      %           \
+   %      %           \
+   %......%           \
+   %......%           \
+   %......%           \
+   %%%%%%%%           \
+/
+  b endmap
+}  
+/^9$/ {
+  s/.*/\
+SED Sokoban - LEVEL 9\
+\
+           %%%%%%%    \
+           %  ...%    \
+       %%%%%  ...%    \
+       %      . .%    \
+       %  %%  ...%    \
+       %% %%  ...%    \
+      %%% %%%%%%%%    \
+      % ooo %%        \
+  %%%%%  o o %%%%%    \
+ %%   %o o   %   %    \
+ %@ o  o    o  o %    \
+ %%%%%% oo o %%%%%    \
+      %      %        \
+      %%%%%%%%        \
+/
+  b endmap
+}  
+/^10$/ {
+  s/.*/\
+SED Sokoban - LEVEL 10\
+\
+  %%%  %%%%%%%%%%%%%  \
+ %%@%%%%       %   %  \
+ % oo   oo  o o ...%  \
+ %  ooo%    o  %...%  \
+ % o   % oo oo %...%  \
+ %%%   %  o    %...%  \
+ %     % o o o %...%  \
+ %    %%%%%% %%%...%  \
+ %% %  %  o o  %...%  \
+ %  %% % oo o o%%..%  \
+ % ..% %  o      %.%  \
+ % ..% % ooo ooo %.%  \
+ %%%%% %       % %.%  \
+     % %%%%%%%%% %.%  \
+     %           %.%  \
+     %%%%%%%%%%%%%%%  \
+/
+  b endmap
+}  
+/^11$/ {
+  s/.*/\
+SED Sokoban - LEVEL 11\
+\
+           %%%%       \
+      %%%% %  %       \
+    %%% @%%%o %       \
+   %%      o  %       \
+  %%  o oo%% %%       \
+  %  %o%%     %       \
+  % % o oo % %%%      \
+  %   o %  % o %%%%%  \
+ %%%%    %  oo %   %  \
+ %%%% %% o         %  \
+ %.    %%%  %%%%%%%%  \
+ %.. ..% %%%%         \
+ %...%.%              \
+ %.....%              \
+ %%%%%%%              \
+/
+  b endmap
+}  
+/^12$/ {
+  s/.*/\
+SED Sokoban - LEVEL 12\
+\
+ %%%%%%%%%%%%%%%%     \
+ %              %     \
+ % % %%%%%%     %     \
+ % %  o o o o%  %     \
+ % %   o at o   %% %%    \
+ % %  o o o%%%...%    \
+ % %   o o  %%...%    \
+ % %%%ooo o %%...%    \
+ %     % %% %%...%    \
+ %%%%%   %% %%...%    \
+     %%%%%     %%%    \
+         %     %      \
+         %%%%%%%      \
+/
+  b endmap
+}  
+/^13$/ {
+  s/.*/\
+SED Sokoban - LEVEL 13\
+\
+    %%%%%%%%%         \
+   %%   %%  %%%%%     \
+ %%%     %  %    %%%  \
+ %  o %o %  %  ... %  \
+ % % o%@o%% % %.%. %  \
+ %  % %o  %    . . %  \
+ % o    o % % %.%. %  \
+ %   %%  %%o o . . %  \
+ % o %   %  %o%.%. %  \
+ %% o  o   o  o... %  \
+  %o %%%%%%    %%  %  \
+  %  %    %%%%%%%%%%  \
+  %%%%                \
+/
+  b endmap
+}  
+/^14$/ {
+  s/.*/\
+SED Sokoban - LEVEL 14\
+\
+        %%%%%%%       \
+  %%%%%%%     %       \
+  %     % o at o %       \
+  %oo %   %%%%%%%%%   \
+  % %%%......%%   %   \
+  %   o......%% % %   \
+  % %%%......     %   \
+ %%   %%%% %%% %o%%   \
+ %  %o   %  o  % %    \
+ %  o ooo  % o%% %    \
+ %   o o %%%oo % %    \
+ %%%%%     o   % %    \
+     %%% %%%   % %    \
+       %     %   %    \
+       %%%%%%%%  %    \
+              %%%%    \
+/
+  b endmap
+}  
+/^15$/ {
+  s/.*/\
+SED Sokoban - LEVEL 15\
+\
+    %%%%%%%%          \
+    %   %  %          \
+    %  o   %          \
+  %%% %o   %%%%       \
+  %  o  %%o   %       \
+  %  % @ o % o%       \
+  %  %      o %%%%    \
+  %% %%%%o%%     %    \
+  % o%.....% %   %    \
+  %  o..OO. o% %%%    \
+ %%  %.....%   %      \
+ %   %%% %%%%%%%      \
+ % oo  %  %           \
+ %  %     %           \
+ %%%%%%   %           \
+      %%%%%           \
+/
+  b endmap
+}  
+/^16$/ {
+  s/.*/\
+SED Sokoban - LEVEL 16\
+\
+ %%%%%                \
+ %   %%               \
+ %    %  %%%%         \
+ % o  %%%%  %         \
+ %  oo o   o%         \
+ %%%@ %o    %%        \
+  %  %%  o o %%       \
+  % o  %% %% .%       \
+  %  %o%%o  %.%       \
+  %%%   o..%%.%       \
+   %    %.O...%       \
+   % oo %.....%       \
+   %  %%%%%%%%%       \
+   %  %               \
+   %%%%               \
+/
+  b endmap
+}  
+/^17$/ {
+  s/.*/\
+SED Sokoban - LEVEL 17\
+\
+    %%%%%%%%%%        \
+    %..  %   %        \
+    %..      %        \
+    %..  %  %%%%      \
+   %%%%%%%  %  %%     \
+   %            %     \
+   %  %  %%  %  %     \
+ %%%% %%  %%%% %%     \
+ %  o  %%%%% %  %     \
+ % % o  o  % o  %     \
+ % @o  o   %   %%     \
+ %%%% %% %%%%%%%      \
+    %    %            \
+    %%%%%%            \
+/
+  b endmap
+}  
+/^18$/ {
+  s/.*/\
+SED Sokoban - LEVEL 18\
+\
+      %%%%%%%%%%%     \
+      %  .  %   %     \
+      % %.    @ %     \
+  %%%%% %%..% %%%%    \
+ %%  % ..%%%     %%%  \
+ % o %...   o %  o %  \
+ %    .. %%  %% %% %  \
+ %%%%o%%o% o %   % %  \
+   %% %    %o oo % %  \
+   %  o % %  % o%% %  \
+   %               %  \
+   %  %%%%%%%%%%%  %  \
+   %%%%         %%%%  \
+/
+  b endmap
+}  
+/^19$/ {
+  s/.*/\
+SED Sokoban - LEVEL 19\
+\
+   %%%%%%             \
+   %   @%%%%          \
+ %%%%% o   %          \
+ %   %%    %%%%       \
+ % o %  %%    %       \
+ % o %  %%%%% %       \
+ %% o  o    % %       \
+ %% o o %%% % %       \
+ %% %  o  % % %       \
+ %% % %o%   % %       \
+ %% %%%   % % %%%%%%  \
+ %  o  %%%% % %....%  \
+ %    o    o   ..%.%  \
+ %%%%o  o% o   ....%  \
+ %       %  %% ....%  \
+ %%%%%%%%%%%%%%%%%%%  \
+/
+  b endmap
+}  
+/^20$/ {
+  s/.*/\
+SED Sokoban - LEVEL 20\
+\
+     %%%%%%%%%%       \
+ %%%%%        %%%%    \
+ %     %   o  %@ %    \
+ % %%%%%%%o%%%%  %%%  \
+ % %    %% %  %o ..%  \
+ % % o     %  %  %.%  \
+ % % o  %     %o ..%  \
+ % %  %%% %%     %.%  \
+ % %%%  %  %  %o ..%  \
+ % %    %  %%%%  %.%  \
+ % %o   o  o  %o ..%  \
+ %    o % o o %  %.%  \
+ %%%% o%%%    %o ..%  \
+    %    oo %%%....%  \
+    %      %% %%%%%%  \
+    %%%%%%%%          \
+/
+  b endmap
+}  
+/^21$/ {
+  s/.*/\
+SED Sokoban - LEVEL 21\
+\
+ %%%%%%%%%            \
+ %       %            \
+ %       %%%%         \
+ %% %%%% %  %         \
+ %% %@%%    %         \
+ % ooo o  oo%         \
+ %  % %% o  %         \
+ %  % %%  o %%%%      \
+ %%%%  ooo o%  %      \
+  %   %%   ....%      \
+  % %   % %.. .%      \
+  %   % % %%...%      \
+  %%%%% o  %...%      \
+      %%   %%%%%      \
+       %%%%%          \
+/
+  b endmap
+}  
+/^22$/ {
+  s/.*/\
+SED Sokoban - LEVEL 22\
+\
+ %%%%%%     %%%%      \
+ %    %%%%%%%  %%%%%  \
+ %   o%  %  o  %   %  \
+ %  o  o  o % o o  %  \
+ %%o o   % @% o    %  \
+ %  o %%%%%%%%%%% %%  \
+ % %   %.......% o%   \
+ % %%  % ......%  %   \
+ % %   o........o %   \
+ % % o %.... ..%  %   \
+ %  o o%%%%o%%%% o%   \
+ % o   %%% o   o  %%  \
+ % o     o o  o    %  \
+ %% %%%%%% o %%%%% %  \
+ %         %       %  \
+ %%%%%%%%%%%%%%%%%%%  \
+/
+  b endmap
+}  
+/^23$/ {
+  s/.*/\
+SED Sokoban - LEVEL 23\
+\
+     %%%%%%%          \
+     %  %  %%%%       \
+ %%%%% o%o %  %%      \
+ %.. %  %  %   %      \
+ %.. % o%o %  o%%%%   \
+ %.  %     %o  %  %   \
+ %..   o%  % o    %   \
+ %..@%  %o %o  %  %   \
+ %.. % o%     o%  %   \
+ %.. %  %oo%o  %  %%  \
+ %.. % o%  %  o%o  %  \
+ %.. %  %  %   %   %  \
+ %%. %%%%  %%%%%   %  \
+  %%%%  %%%%   %%%%%  \
+/
+  b endmap
+}  
+/^24$/ {
+  s/.*/\
+SED Sokoban - LEVEL 24\
+\
+ %%%%%%%%%%%%%%%      \
+ %..........  .%%%%   \
+ %..........oo.%  %   \
+ %%%%%%%%%%%o %   %%  \
+ %      o  o     o %  \
+ %% %%%%   %  o %  %  \
+ %      %   %%  % %%  \
+ %  o%  % %%  %%% %%  \
+ % o %o%%%    %%% %%  \
+ %%%  o %  %  %%% %%  \
+ %%%    o %% %  % %%  \
+  % o  %  o  o o   %  \
+  %  o  o%ooo  %   %  \
+  %  %  o      %%%%%  \
+  % @%%  %  %  %      \
+  %%%%%%%%%%%%%%      \
+/
+  b endmap
+}  
+/^25$/ {
+  s/.*/\
+SED Sokoban - LEVEL 25\
+\
+ %%%%                 \
+ %  %%%%%%%%%%%%%%    \
+ %  %   ..%......%    \
+ %  % % %%%%% ...%    \
+ %%o%    ........%    \
+ %   %%o%%%%%%  %%%%  \
+ % o %     %%%%%%@ %  \
+ %%o % o   %%%%%%  %  \
+ %  o %ooo%%       %  \
+ %      %    %o%o%%%  \
+ % %%%% %ooooo    %   \
+ % %    o     %   %   \
+ % %   %%        %%%  \
+ % %%%%%%o%%%%%% o %  \
+ %        %    %   %  \
+ %%%%%%%%%%    %%%%%  \
+/
+  b endmap
+}  
+/^26$/ {
+  s/.*/\
+SED Sokoban - LEVEL 26\
+\
+  %%%%%%%             \
+  %  %  %%%%%         \
+ %%  %  %...%%%       \
+ %  o%  %...  %       \
+ % o %oo ...  %       \
+ %  o%  %... .%       \
+ %   % o%%%%%%%%      \
+ %%o       o o %      \
+ %%  %  oo %   %      \
+  %%%%%%  %%oo@%      \
+       %      %%      \
+       %%%%%%%%       \
+/
+  b endmap
+}  
+/^27$/ {
+  s/.*/\
+SED Sokoban - LEVEL 27\
+\
+  %%%%%%%%%%%%%%%%%   \
+  %...   %    %   %%  \
+ %%.....  o%% % %o %  \
+ %......%  o  %    %  \
+ %......%  %  % %  %  \
+ %%%%%%%%% o  o o  %  \
+   %     %o%%o %%o%%  \
+  %%   o    % o    %  \
+  %  %% %%% %  %%o %  \
+  % o oo     o  o  %  \
+  % o    o%%o %%%%%%  \
+  %%%%%%%  @ %%       \
+        %%%%%%        \
+/
+  b endmap
+}  
+/^28$/ {
+  s/.*/\
+SED Sokoban - LEVEL 28\
+\
+          %%%%%       \
+      %%%%%   %       \
+     %% o  o  %%%%    \
+ %%%%% o  o o %%.%    \
+ %       oo  %%..%    \
+ %  %%%%%% %%%.. %    \
+ %% %  %    %... %    \
+ % o   %    %... %    \
+ %@ %o %% %%%%...%    \
+ %%%%  o oo  %%..%    \
+    %%  o o  o...%    \
+     % oo  o %  .%    \
+     %   o o  %%%%    \
+     %%%%%%   %       \
+          %%%%%       \
+/
+  b endmap
+}  
+/^29$/ {
+  s/.*/\
+SED Sokoban - LEVEL 29\
+\
+ %%%%%                \
+ %   %%               \
+ % o  %%%%%%%%%       \
+ %% % %       %%%%%%  \
+ %% %   o%o%@  %   %  \
+ %  %      o %   o %  \
+ %  %%% %%%%%%%%% %%  \
+ %  %% ..O..... % %%  \
+ %% %% O.O..O.O % %%  \
+ % o%%%%%%%%%% %%o %  \
+ %  o   o  o    o  %  \
+ %  %   %   %   %  %  \
+ %%%%%%%%%%%%%%%%%%%  \
+/
+  b endmap
+}  
+/^30$/ {
+  s/.*/\
+SED Sokoban - LEVEL 30\
+\
+        %%%%%%%%%%%   \
+        %   %     %   \
+ %%%%%  %     o o %   \
+ %   %%%%% o%% % %%   \
+ % o %%   % %% o  %   \
+ % o  @oo % %%ooo %   \
+ %% %%%   % %%    %   \
+ %% %   %%% %%%%%o%   \
+ %% %     o  %....%   \
+ %  %%% %% o %....%%  \
+ % o   o %   %..o. %  \
+ %  %% o %  %%.... %  \
+ %%%%%   %%%%%%...%%  \
+     %%%%%    %%%%%   \
+/
+  b endmap
+}  
+/^31$/ {
+  s/.*/\
+SED Sokoban - LEVEL 31\
+\
+   %%%%               \
+   %  %%%%%%%%%       \
+  %%  %%  %   %       \
+  %  o% o at o   %%%%    \
+  %o  o  % o o%  %%   \
+ %%  o%% %o o     %   \
+ %  %  % %   ooo  %   \
+ % o    o  o%% %%%%   \
+ % o o %o%  %  %      \
+ %%  %%%  %%%o %      \
+  %  %....     %      \
+  %%%%......%%%%      \
+    %....%%%%         \
+    %...%%            \
+    %...%             \
+    %%%%%             \
+/
+  b endmap
+}  
+/^32$/ {
+  s/.*/\
+SED Sokoban - LEVEL 32\
+\
+       %%%%           \
+   %%%%%  %           \
+  %%     o%           \
+ %% o  %% %%%         \
+ %@o o % o  %         \
+ %%%% %%   o%         \
+  %....%o o %         \
+  %....%   o%         \
+  %....  oo %%        \
+  %... % o   %        \
+  %%%%%%o o  %        \
+       %   %%%        \
+       %o %%%         \
+       %  %           \
+       %%%%           \
+/
+  b endmap
+}  
+/^33$/ {
+  s/.*/\
+SED Sokoban - LEVEL 33\
+\
+  %%%%%%%%%%%         \
+  %     %%  %         \
+  %   o   o %         \
+ %%%% %% oo %         \
+ %   o %    %         \
+ % ooo % %%%%         \
+ %   % % o %%         \
+ %  %  %  o %         \
+ % o% o%    %         \
+ %   ..% %%%%         \
+ %%%%.. o %@%         \
+ %.....% o% %         \
+ %%....%  o %         \
+  %%..%%    %         \
+   %%%%%%%%%%         \
+/
+  b endmap
+}  
+/^34$/ {
+  s/.*/\
+SED Sokoban - LEVEL 34\
+\
+  %%%%%%%%%           \
+  %....   %%          \
+  %.%.%  o %%         \
+ %%....% % @%%        \
+ % ....%  %  %%       \
+ %     %o %%o %       \
+ %% %%%  o    %       \
+  %o  o o o%  %       \
+  % %  o o %% %       \
+  %  %%%  %%  %       \
+  %    %% %% %%       \
+  %  o %  o  %        \
+  %%%o o   %%%        \
+    %  %%%%%          \
+    %%%%              \
+/
+  b endmap
+}  
+/^35$/ {
+  s/.*/\
+SED Sokoban - LEVEL 35\
+\
+ %%%%%%%%%%%% %%%%%%  \
+ %   %    % %%%....%  \
+ %   oo%   @  .....%  \
+ %   % %%%   % ....%  \
+ %% %% %%%  %  ....%  \
+  % o o     % % %%%%  \
+  %  o o%%  %      %  \
+ %%%% %  %%%% % %% %  \
+ %  % %o   %% %    %  \
+ % o  o  % %% %   %%  \
+ % % o o    % %   %   \
+ %  o %% %% % %%%%%   \
+ % oo     oo  %       \
+ %% %% %%% o  %       \
+  %    % %    %       \
+  %%%%%% %%%%%%       \
+/
+  b endmap
+}  
+/^36$/ {
+  s/.*/\
+SED Sokoban - LEVEL 36\
+\
+             %%%%%    \
+ %%%%%  %%%%%%   %    \
+ %   %%%%  o o o %    \
+ % o   %% %% %%  %%   \
+ %   o o     o  o %   \
+ %%% o  %% %%     %%  \
+   % %%%%% %%%%%oo %  \
+  %%o%%%%% @%%     %  \
+  % o  %%%o%%% o  %%  \
+  % o  %   %%%  %%%   \
+  % oo o %   oo %     \
+  %     %   %%  %     \
+  %%%%%%%.. .%%%      \
+     %.........%      \
+     %.........%      \
+     %%%%%%%%%%%      \
+/
+  b endmap
+}  
+/^37$/ {
+  s/.*/\
+SED Sokoban - LEVEL 37\
+\
+ %%%%%%%%%%%          \
+ %......   %%%%%%%%%  \
+ %......   %  %%   %  \
+ %..%%% o    o     %  \
+ %... o o %   %%   %  \
+ %...%o%%%%%    %  %  \
+ %%%    %   %o  %o %  \
+   %  oo o o  o%%  %  \
+   %  o   %o%o %%o %  \
+   %%% %% %    %%  %  \
+    %  o o %% %%%%%%  \
+    %    o  o  %      \
+    %%   % %   %      \
+     %%%%%@%%%%%      \
+         %%%          \
+/
+  b endmap
+}  
+/^38$/ {
+  s/.*/\
+SED Sokoban - LEVEL 38\
+\
+       %%%%           \
+ %%%%%%% @%           \
+ %     o  %           \
+ %   o%% o%           \
+ %%o%...% %           \
+  % o...  %           \
+  % %. .% %%          \
+  %   % %o %          \
+  %o  o    %          \
+  %  %%%%%%%          \
+  %%%%                \
+/
+  b endmap
+}  
+/^39$/ {
+  s/.*/\
+SED Sokoban - LEVEL 39\
+\
+              %%%%%%  \
+  %%%%%%%%%%%%%....%  \
+ %%   %%     %%....%  \
+ %  oo%%  o @%%....%  \
+ %      oo o%  ....%  \
+ %  o %% oo % % ...%  \
+ %  o %% o  %  ....%  \
+ %% %%%%% %%% %%.%%%  \
+ %%   o  o %%   .  %  \
+ % o%%%  % %%%%% %%%  \
+ %   o   %       %    \
+ %  o %o o o%%%  %    \
+ % ooo% o   % %%%%    \
+ %    %  oo %         \
+ %%%%%%   %%%         \
+      %%%%%           \
+/
+  b endmap
+}  
+/^40$/ {
+  s/.*/\
+SED Sokoban - LEVEL 40\
+\
+     %%%%%%%%%%%%     \
+     %          %%    \
+     %  % %oo o  %    \
+     %o %o%  %% @%    \
+    %% %% % o % %%    \
+    %   o %o  % %     \
+    %   % o   % %     \
+    %% o o   %% %     \
+    %  %  %%  o %     \
+    %    %% oo% %     \
+ %%%%%%oo   %   %     \
+ %....%  %%%%%%%%     \
+ %.%... %%            \
+ %....   %            \
+ %....   %            \
+ %%%%%%%%%            \
+/
+  b endmap
+}  
+/^41$/ {
+  s/.*/\
+SED Sokoban - LEVEL 41\
+\
+            %%%%%     \
+           %%   %%    \
+          %%     %    \
+         %%  oo  %    \
+        %% oo  o %    \
+        % o    o %    \
+ %%%%   %   oo %%%%%  \
+ %  %%%%%%%% %%    %  \
+ %.            ooo@%  \
+ %.% %%%%%%% %%   %%  \
+ %.% %%%%%%%. %o o%%  \
+ %........... %    %  \
+ %%%%%%%%%%%%%%  o %  \
+              %%  %%  \
+               %%%%   \
+/
+  b endmap
+}  
+/^42$/ {
+  s/.*/\
+SED Sokoban - LEVEL 42\
+\
+      %%%%%%%%        \
+   %%%%      %%%%%%   \
+   %    %% o o   @%   \
+   % %% %%o%o o o%%   \
+ %%% ......%  oo %%   \
+ %   ......%  %   %   \
+ % % ......%o  o  %   \
+ % %o...... oo% o %   \
+ %   %%% %%%o  o %%   \
+ %%%  o  o  o  o %    \
+   %  o  o  o  o %    \
+   %%%%%%   %%%%%%    \
+        %%%%%         \
+/
+  b endmap
+}  
+/^43$/ {
+  s/.*/\
+SED Sokoban - LEVEL 43\
+\
+         %%%%%%%      \
+     %%%%%  %  %%%%   \
+     %   %   o    %   \
+  %%%% %oo %% %%  %   \
+ %%      % %  %% %%%  \
+ %  %%% o%o  o  o  %  \
+ %...    % %%  %   %  \
+ %...%    @ % %%% %%  \
+ %...%  %%%  o  o  %  \
+ %%%%%%%% %%   %   %  \
+           %%%%%%%%%  \
+/
+  b endmap
+}  
+/^44$/ {
+  s/.*/\
+SED Sokoban - LEVEL 44\
+\
+  %%%%%               \
+  %   %               \
+  % % %%%%%%%         \
+  %      o@%%%%%%     \
+  % o %%o %%%   %     \
+  % %%%% o    o %     \
+  % %%%%% %  %o %%%%  \
+ %%  %%%% %%o      %  \
+ %  o%  o  % %% %% %  \
+ %         % %...% %  \
+ %%%%%%  %%%  ...  %  \
+      %%%% % %...% %  \
+           % %%% % %  \
+           %       %  \
+           %%%%%%%%%  \
+/
+  b endmap
+}  
+/^45$/ {
+  s/.*/\
+SED Sokoban - LEVEL 45\
+\
+ %%%%% %%%%           \
+ %...% %  %%%%        \
+ %...%%%  o  %        \
+ %....%% o  o%%%      \
+ %%....%%   o  %      \
+ %%%... %% o o %      \
+ % %%    %  o  %      \
+ %  %% % %%% %%%%     \
+ % o % %o  o    %     \
+ %  o @ o    o  %     \
+ %   % o oo o %%%     \
+ %  %%%%%%  %%%       \
+ % %%    %%%%         \
+ %%%                  \
+/
+  b endmap
+}  
+/^46$/ {
+  s/.*/\
+SED Sokoban - LEVEL 46\
+\
+ %%%%%%%%%%           \
+ %        %%%%        \
+ % %%%%%% %  %%       \
+ % % o o o  o %       \
+ %       %o   %       \
+ %%%o  oo%  %%%       \
+   %  %% % o%%        \
+   %%o%   o @%        \
+    %  o o %%%        \
+    % %   o  %        \
+    % %%   % %        \
+   %%  %%%%% %        \
+   %         %        \
+   %.......%%%        \
+   %.......%          \
+   %%%%%%%%%          \
+/
+  b endmap
+}  
+/^47$/ {
+  s/.*/\
+SED Sokoban - LEVEL 47\
+\
+          %%%%        \
+  %%%%%%%%%  %%       \
+ %%  o      o %%%%%   \
+ %   %% %%   %%...%   \
+ % %oo o oo%o%%...%   \
+ % %   @   %   ...%   \
+ %  o% %%%oo   ...%   \
+ % o  oo  o %%....%   \
+ %%%o       %%%%%%%   \
+   %  %%%%%%%         \
+   %%%%               \
+/
+  b endmap
+}  
+/^48$/ {
+  s/.*/\
+SED Sokoban - LEVEL 48\
+\
+   %%%%%%%%%          \
+   %O.O%O.O%          \
+   %.O.O.O.%          \
+   %O.O.O.O%          \
+   %.O.O.O.%          \
+   %O.O.O.O%          \
+   %%%   %%%          \
+     %   %            \
+ %%%%%% %%%%%%        \
+ %           %        \
+ % o o o o o %        \
+ %% o o o o %%        \
+  %o o o o o%         \
+  %   o at o   %         \
+  %  %%%%%  %         \
+  %%%%   %%%%         \
+/
+  b endmap
+}  
+/^49$/ {
+  s/.*/\
+SED Sokoban - LEVEL 49\
+\
+        %%%%          \
+        %  %%         \
+        %   %%        \
+        % oo %%       \
+      %%%o  o %%      \
+   %%%%    o   %      \
+ %%%  % %%%%%  %      \
+ %    % %....o %      \
+ % %   o ....% %      \
+ %  o % %.O..% %      \
+ %%%  %%%% %%% %      \
+   %%%% @o  %%o%%     \
+      %%% o     %     \
+        %  %%   %     \
+        %%%%%%%%%     \
+/
+  b endmap
+}  
+/^50$/ {
+  s/.*/\
+SED Sokoban - LEVEL 50\
+\
+       %%%%%%%%%%%%   \
+      %%..    %   %   \
+     %%..O o    o %   \
+    %%..O.% % % o%%   \
+    %..O.% % % o  %   \
+ %%%%...%  %    % %   \
+ %  %% %          %   \
+ % @o o %%%  %   %%   \
+ % o   o   % %   %    \
+ %%%oo   % % % % %    \
+   %   o   % % %%%%%  \
+   % o% %%%%%      %  \
+   %o   %   %    % %  \
+   %  %%%   %%     %  \
+   %  %      %    %%  \
+   %%%%      %%%%%%   \
+/
+  b endmap
+}  
+/^51$/ {
+  s/.*/\
+SED Sokoban - LEVEL 51\
+\
+  %%%%%%%%%           \
+  %       %           \
+  % o oo o%           \
+ %%% %  o %           \
+ %.%   oo %%          \
+ %.%%%   o %          \
+ %.%. o %% %%%%       \
+ %...  o%% o  %       \
+ %...o   o    %       \
+ %..%%%o%%% %@%       \
+ %..% %     %%%       \
+ %%%% %%%%%%%         \
+/
+  b endmap
+}  
+/^52$/ {
+  s/.*/\
+SED Sokoban - LEVEL 52\
+\
+            %%%%%%%%  \
+            %......%  \
+    %%%%    %......%  \
+    %  %%%%%%%%%...%  \
+    % o   o    %...%  \
+    %  % % % % %   %  \
+ %%%%% % % %@% %   %  \
+ %   % %%% %%% %% %%  \
+ %    o % o o o % %   \
+ % ooo  o   %     %   \
+ %   % %%%o%%%o%% %   \
+ %%% %  o   %     %   \
+  %% o  % o o o %%%   \
+  %  % %%% %%% %%     \
+  % o          %      \
+  %  %%%%%%%%%%%      \
+  %%%%                \
+/
+  b endmap
+}  
+/^53$/ {
+  s/.*/\
+SED Sokoban - LEVEL 53\
+\
+ %%%%%%%%%%%%%%%%%%   \
+ %                %%  \
+ % o%   o %%  o    %  \
+ %    o%%%    % oo %  \
+ %.%%%     o o %%  %% \
+ %...%  %  %    %o  % \
+ %..%%oo%%%% o  %   % \
+ %...%      o %%  %%% \
+ %...o  %%%  %    % % \
+ %%..  o%  %%   %%@ % \
+  %%.%              % \
+   %%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^54$/ {
+  s/.*/\
+SED Sokoban - LEVEL 54\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %   %    %   %   %@% \
+ % o      o   o   % % \
+ %% %%%..%% %%%     % \
+ %   %....%o%  o%%% % \
+ % o %....%  o  o o % \
+ %   %....% % % o o % \
+ %   %%..%%   %o%   % \
+ %%o%%    %%  %  %o%% \
+ %   o  o     %  %  % \
+ %   %    %   %     % \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^55$/ {
+  s/.*/\
+SED Sokoban - LEVEL 55\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %    @%%      %   %% \
+ %    %%    o    o %% \
+ %  %%%....% % %  %%% \
+ %   %....% % % o   % \
+ %%% %...%  %       % \
+ %%  %%.%     o   o % \
+ %%  o o %%%  % % %%% \
+ %% o       % % o   % \
+ %%%% o  o% % % % o % \
+ %%%%         % %  %% \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^56$/ {
+  s/.*/\
+SED Sokoban - LEVEL 56\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %  %  %%    %   @%%% \
+ %%    o    % o%%%  % \
+ %%o% o %%o% o o    % \
+ %   o%    o      %%% \
+ % %%   o %%%  %....% \
+ % % o% % % % %....%% \
+ %    o o %  %....%%% \
+ %%o %%%  o %....%%%% \
+ %  % o        %%%%%% \
+ %      % %    %%%%%% \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^57$/ {
+  s/.*/\
+SED Sokoban - LEVEL 57\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %@     %%%   %  %  % \
+ % % %  %  o  o     % \
+ %%%%%     % o o%o% % \
+ %.%..%    %%o o    % \
+ %.....    o   %   %% \
+ %.....    %%%o%%o%%% \
+ %.%..%    o    %   % \
+ %%%%%     %  %o  o % \
+ %%%%%  %  o    o o % \
+ %%%%%  %  %  %  %  % \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^58$/ {
+  s/.*/\
+SED Sokoban - LEVEL 58\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %%...   %% %    %  % \
+ %....         o %% % \
+ %....% % %o%%%o    % \
+ %...%    %       % % \
+ %%.%  %o %     o%% % \
+ %  %  % o o %%%  o % \
+ %     o  o %  % %% % \
+ %% % %% %oo% o%  % % \
+ %  %   o o %      %% \
+ %    %     %  %   @% \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^59$/ {
+  s/.*/\
+SED Sokoban - LEVEL 59\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %   %  %@% %%  %%%%% \
+ % % %  o    o  %%%%% \
+ % %    %%%%%% o  %%% \
+ %   %  %....%  oo  % \
+ %%o%%o%%....%      % \
+ %      %....%%o%%o%% \
+ %  oo  %....%      % \
+ % o  o  %  %  %%%  % \
+ %%%%%  o   o    o  % \
+ %%%%% %    %  %   %% \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^60$/ {
+  s/.*/\
+SED Sokoban - LEVEL 60\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ % %     %          % \
+ %       o  %% %%% %% \
+ %%%%%  %%   o  o   % \
+ %%..%%  % % o % %  % \
+ %....  o     %%o% %% \
+ %....  o%%%%%   %o%% \
+ %%..% %  %   %  o  % \
+ %%%.% %  o   o  % @% \
+ %%  o  o %   %  %%%% \
+ %%       %%%%%%%%%%% \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^61$/ {
+  s/.*/\
+SED Sokoban - LEVEL 61\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %     %%%..%%%     % \
+ % oo  %%%..%%%  o@ % \
+ %  % %%......%  o  % \
+ %     %......%  o  % \
+ %%%%  %%%..%%%%%%o % \
+ %   ooo %..%    %  % \
+ % o%   o  o  oo %o % \
+ %  %  %% o  %%  %  % \
+ % o    o %% o    o % \
+ %  %  %%    %%  %  % \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^62$/ {
+  s/.*/\
+SED Sokoban - LEVEL 62\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %    %  % %  %  %  % \
+ % @% % %% o   o   %% \
+ %%%% %    %  % o   % \
+ %    % %% %o %% %% % \
+ %      o   o   o   % \
+ %..%%%oo%% o%%o %% % \
+ %..%.%  % o   o %  % \
+ %....% oo   %%o %%%% \
+ %....%  %%%%%      % \
+ %...%%%        %%  % \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^63$/ {
+  s/.*/\
+SED Sokoban - LEVEL 63\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %....%       %  %  % \
+ %....% % o  o      % \
+ %.... %%  o% % o%o % \
+ %...%   o   o%  o  % \
+ %..%%%%  % o   oo  % \
+ %      %%%% %%%% %%% \
+ %        %   %     % \
+ % %%   %   o % o o % \
+ % %%    o %% o  o  % \
+ %     @%     %   % % \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^64$/ {
+  s/.*/\
+SED Sokoban - LEVEL 64\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %....%%%           % \
+ %....%%%%% %  %o% %% \
+ %....%%%   %o  o   % \
+ %....%%%    o  %oo%% \
+ %%  %%%% o%  %o o  % \
+ %%  %%%%  o  o  %  % \
+ %@  %%%%o%%%o%% o  % \
+ %%        %  %  o  % \
+ %%   %%%  %  o  %%%% \
+ %%%%%%%%  %  %     % \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^65$/ {
+  s/.*/\
+SED Sokoban - LEVEL 65\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %     %     @%...%%% \
+ %     %      %%...%% \
+ % % % %%o%% %% ....% \
+ %   o %   ooo  ....% \
+ %%%o%%% oo  %%% %%.% \
+ %     o  %    % %%%% \
+ %  o  %  %%%  % %  % \
+ %% %o%%    o  oo   % \
+ %   o %%   %  % %  % \
+ %     %    %  %    % \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^66$/ {
+  s/.*/\
+SED Sokoban - LEVEL 66\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %     %  %...%@    % \
+ % %       ....%    % \
+ %  o  %   %....%   % \
+ % %%o%%%% %%....%  % \
+ % o   o  %  %...%  % \
+ % oo %   %   % oo  % \
+ %%%  ooo%   oo  o  % \
+ % o  %  %    % o%  % \
+ %   o%  %       o  % \
+ %  %    %    %  %  % \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^67$/ {
+  s/.*/\
+SED Sokoban - LEVEL 67\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %%%%%@%%%.%%...%%  % \
+ %%%%%o  ..%...%    % \
+ %%%%    ......%  o % \
+ %%%  o %.....%% % %% \
+ %%  oo% %%%%%  o o % \
+ %% o% o    %%  oo  % \
+ %%  %  %    % o  o % \
+ %%   oo %%% %o%%   % \
+ %% o%      o o  o %% \
+ %%%    %    %    %%% \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^68$/ {
+  s/.*/\
+SED Sokoban - LEVEL 68\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %@     %   %       % \
+ %% %%% %%  %%%% % %% \
+ %    % %  oo       % \
+ %  % % % o % o %% %% \
+ %     o %  %oo %   % \
+ %  %%%  %      %% %% \
+ %..%.% o %  o %    % \
+ %..%.%  o % %% oo  % \
+ %....%%   oo  o  % % \
+ %.....%%        %  % \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^69$/ {
+  s/.*/\
+SED Sokoban - LEVEL 69\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %  %      %   %   %% \
+ % o% o o %%...o  o % \
+ %  o  % %%....% o  % \
+ % %% o %%....%   o % \
+ % o    %....%% o   % \
+ % o%%  %...%       % \
+ %   ooo%%o%%  %%% %% \
+ % % %  %   %  %    % \
+ % o %  o  %%       % \
+ %    %    %@       % \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^70$/ {
+  s/.*/\
+SED Sokoban - LEVEL 70\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %  %  % %    %  %  % \
+ %   o      o o     % \
+ %% %  %o%%%o%%  %% % \
+ %   o     o  %  o  % \
+ % %%%o%%o%   % o   % \
+ % %   o o  %%%%%% o% \
+ % o  oo o  %@%.%...% \
+ % %     %  % %.%...% \
+ % %%%%%%%%%% %.....% \
+ %            %.....% \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^71$/ {
+  s/.*/\
+SED Sokoban - LEVEL 71\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %  %     %  %%    %% \
+ % o%   o %     %%  % \
+ % o  o  %..%     o % \
+ % o o  %....%   % %% \
+ % o%  %......%%% o % \
+ %   %  %....%  %o  % \
+ % o  %%%%..%   %   % \
+ %% o   %% % % o  o%% \
+ %%% o    o%@o o%   % \
+ %%%%   %       %   % \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^72$/ {
+  s/.*/\
+SED Sokoban - LEVEL 72\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %      ....%    %%%% \
+ %      ....        % \
+ % % %%%%%%%%%%     % \
+ % %o   %      %%%..% \
+ %  o   %oo%%%   %..% \
+ % o %%% o   o   %..% \
+ % o %   o o %  %%..% \
+ %  %  oo % o %%   %% \
+ %@%% o%  o  o     %% \
+ %%       %%   %  %%% \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^73$/ {
+  s/.*/\
+SED Sokoban - LEVEL 73\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %        %   %@ %  % \
+ % oo  %oo% % %  %% % \
+ %  % o o %oo %     % \
+ %% %  %  % % %  %  % \
+ %   %%       %     % \
+ %   % o %   %   %  % \
+ % o %o %   %  o %..% \
+ %%o %  %%%%    %...% \
+ %  o          %....% \
+ %   %  %     %.....% \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^74$/ {
+  s/.*/\
+SED Sokoban - LEVEL 74\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %     %   %%%%%    % \
+ %% o  %   %%%%  o  % \
+ %%%% oo   %..%  %  % \
+ %  o  o  %%..%%%% %% \
+ % o   %%%....   oo % \
+ %  %o%   ....% % o % \
+ % %  % o ..%%%o%   % \
+ % %   o %..%   %%  % \
+ %   o%  %%%%   % o%% \
+ % %  %    @%      %% \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^75$/ {
+  s/.*/\
+SED Sokoban - LEVEL 75\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %   %   %    %   %@% \
+ %   o  o     % o % % \
+ %%o% o%%% %    oo% % \
+ %  %  %.%%%  %o o  % \
+ %  %o%....%  % %%% % \
+ % o  %.....%%    % % \
+ %%o  %.%....%oo o  % \
+ %  %%%%%%..%% %  % % \
+ %  o         o %%% % \
+ %   %   %        % % \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^76$/ {
+  s/.*/\
+SED Sokoban - LEVEL 76\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ % % % %   %@%%   % % \
+ %             o    % \
+ %  %%o% %%%%% o % %% \
+ %%    %%.....%  %  % \
+ %%o%%o%.....%%%o%o % \
+ %   % %%.....%  % %% \
+ %  o    %%..%%  %  % \
+ % o %   o   o  ooo % \
+ %% o  o% %  %  o   % \
+ %   %%   %  %      % \
+ %%%%%%%%%%%%%%%%%%%% \
+/
+  b endmap
+}  
+/^77$/ {
+  s/.*/\
+SED Sokoban - LEVEL 77\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %    %%   %    %   % \
+ %  o  o     %% o   % \
+ %% %%%%%  .%%%%%% %% \
+  % %%  %%....%%%% %% \
+ %% %%o %%%..%%     % \
+ %      %... .% o o % \
+ % o %% %% . %%% %%%% \
+ % % o    %.%% % %    \
+ % o o %   .%%%% %%   \
+ % %  %% % %%  %  %%  \
+ %%%%%%%  o%%o   o %  \
+       %%      o %@%  \
+        %  %% %%%%%%  \
+        %%%%%%%       \
+/
+  b endmap
+}  
+/^78$/ {
+  s/.*/\
+SED Sokoban - LEVEL 78\
+\
+        %%%%%%%%%%%   \
+        %         %   \
+        %    o o  %   \
+ %%%%%% % o %%%%% %   \
+ %    %%%%% o  %%o%   \
+ %       o o      %   \
+ %          %% %% %   \
+ %    %%@%%%%% %% %   \
+ %    %%%%   % %% %%  \
+ %....%      % o   %  \
+ %....%      %     %  \
+ %%%%%%      %%%%%%%  \
+/
+  b endmap
+}  
+/^79$/ {
+  s/.*/\
+SED Sokoban - LEVEL 79\
+\
+ %%%%%%%%%%%%%        \
+ %           %        \
+ % %%% oo    %        \
+ %   % o  o  %        \
+ %  o%%%%o%%%%%%      \
+ % o %%        %%%%%  \
+ %  oo o        ...%  \
+ %%% %% oo%     ...%  \
+   % %%   %     ...%  \
+   %      %     ...%  \
+   %%%@%%%%%%%%%%%%%  \
+     %%%              \
+/
+  b endmap
+}  
+/^80$/ {
+  s/.*/\
+SED Sokoban - LEVEL 80\
+\
+   %%%%%%%%%%%%%%%%%  \
+ %%%@%%         ...%  \
+ %    %         ...%  \
+ % o  %         ...%  \
+ % oo %         ...%  \
+ %% o %%%o%%%%%%%%%%  \
+  % %%%  o %          \
+ %%   o  o %          \
+ %  o %  o %          \
+ % o  %    %          \
+ %  o %    %          \
+ %    %    %          \
+ %%%%%%%%%%%          \
+/
+  b endmap
+}  
+/^81$/ {
+  s/.*/\
+SED Sokoban - LEVEL 81\
+\
+               %%%%%  \
+      %%%%%%%%%%   %  \
+      %        %   %  \
+      %  o o    oo %  \
+      % %%%%% %% o %  \
+      %oo   %o%% o %  \
+      % %%% % %%o  %  \
+ %%%%%% %%% o o    %  \
+ %....        %%   %  \
+ %....        %%%%%%  \
+ %....        %       \
+ %%%%%%%%%%%@%%       \
+           %%%        \
+/
+  b endmap
+}  
+/^82$/ {
+  s/.*/\
+SED Sokoban - LEVEL 82\
+\
+     %%%%%%           \
+  %%%%    %           \
+  %    %% %           \
+  % o     %           \
+ %%% %%%% %%%%%%%%    \
+ %  o   o %%  ...%    \
+ %   oo oo    ...%    \
+ %    o  o%%  ...%    \
+ %%@%% %% %%  ...%    \
+  %%%  o  %%%%%%%%    \
+  %   oo  %           \
+  %    %  %           \
+  %%%%%%%%%           \
+/
+  b endmap
+}  
+/^83$/ {
+  s/.*/\
+SED Sokoban - LEVEL 83\
+\
+ %%%%%%% %%%%%%%%%    \
+ %     % %   %%  %    \
+ % %%% % %   o   %    \
+ % % o %%%   o   %    \
+ %   oo      %%o %    \
+ %    %%%%   %%  %    \
+ %@%%%%%%%%%%%% %%    \
+ %%%..    %%%%%o %    \
+   %..    %%%%   %    \
+   %..       oo  %    \
+   %..    %%%% o %    \
+   %..    %  %   %    \
+   %%%%%%%%  %%%%%    \
+/
+  b endmap
+}  
+/^84$/ {
+  s/.*/\
+SED Sokoban - LEVEL 84\
+\
+ %%%%%%%              \
+ %     %%%%%%%%%%     \
+ %     %    %  %%     \
+ % o   %   o o  %     \
+ %  o  %  o %%  %     \
+ % oo  %%o o    %     \
+ %% %  %% %%%%%%%     \
+ %% %  %%    ...%     \
+ %  %o       ...%     \
+ %   oo      ...%     \
+ %     %%@%  ...%     \
+ %%%%%%%%%%%%%%%%     \
+/
+  b endmap
+}  
+/^85$/ {
+  s/.*/\
+SED Sokoban - LEVEL 85\
+\
+ %%%%%%%%%%%%         \
+ %      %   %%        \
+ % o  o   %  %%%%%%   \
+ %%%%  %%%%%      %   \
+  %..  %     %%%% %   \
+  %.%%%%  %%%%    %   \
+  %....    %  o %%%%  \
+  % ...%   % ooo%  %% \
+ %%%.%%%% %%  o at o   % \
+ %     %%%%% o %    % \
+ % %.% o      o%%%o % \
+ % %.%%%%%%%%  %  o % \
+ % %..        %%  o % \
+ % % %%%%%%% o % %  % \
+ %   %     %       %% \
+ %%%%%     %%%%%%%%%% \
+/
+  b endmap
+}  
+/^86$/ {
+  s/.*/\
+SED Sokoban - LEVEL 86\
+\
+ %%%%%%%%%%%%%%%%     \
+ %       %@ %   %     \
+ % % % % % o  oo%     \
+ % %...% %ooo   %     \
+ %  ...% % o  oo%%    \
+ % %%.%% % %%    %    \
+ % %...     o    %    \
+ % %% %%%  %%%%%%%    \
+ %    % %%%%          \
+ %%%%%%               \
+/
+  b endmap
+}  
+/^87$/ {
+  s/.*/\
+SED Sokoban - LEVEL 87\
+\
+     %%%%%            \
+  %%%%   %% %%%%%     \
+  %  o    %%%   %     \
+  % o at o o    o  %     \
+  % %o%%%%%%%% %%     \
+  % %  o  %     %     \
+  % % o o % %   %     \
+ %% %  o% % %%%%%     \
+ %  %%    %     %     \
+ %    o % %%%   %     \
+ %%%%% %%  %....%     \
+ %    o     ....%     \
+ %         %....%     \
+ %%%%%%%%%%%%%%%%     \
+/
+  b endmap
+}  
+/^88$/ {
+  s/.*/\
+SED Sokoban - LEVEL 88\
+\
+ %%%%%%%%%%%%%        \
+ %........%%%%        \
+ %...%%%% %  %%%%%    \
+ %...%  %%%    o %    \
+ %...oo     o o  %    \
+ %  .%  o o% o  %%    \
+ %...% %o%   o  %     \
+ %.% % o   o    %     \
+ %.  %o%%%o%%%%o%     \
+ %%  %   o o    %     \
+  %  %  o at o  %  %     \
+  %  % %%%% o  o%     \
+  %  %    %%%   %     \
+  %  % oo % %%%%%     \
+  %  %    %           \
+  %%%%%%%%%           \
+/
+  b endmap
+}  
+/^89$/ {
+  s/.*/\
+SED Sokoban - LEVEL 89\
+\
+  %%%%%%%%%%%%%%%%%%  \
+  %   o       ...%.%% \
+  %       %%%%..... % \
+  % %%%%%%%  %..... % \
+  % %    o o %%....%% \
+  % %  o % % %%%...%  \
+  % % o at o o  %%%%% %  \
+ %% %  o  o oo   o %  \
+ %  %o% o%   % o%% %  \
+ % %%    %% %% o % %  \
+ % % o% o o  %     %  \
+ % %         %%%%%%%  \
+ % %%%%%%%%o%%   %    \
+ %        %  o   %    \
+ %%%%%%%%    %%%%%    \
+        %%%  %        \
+          %%%%        \
+/
+  b endmap
+}  
+/^90$/ {
+  s/.*/\
+SED Sokoban - LEVEL 90\
+\
+ %%%%%%%%%%%%%%%%%%%% \
+ %..%    %          % \
+ %.o  o  %oo  o%% o%% \
+ %.o%  %%%  %% %%   % \
+ %  % o %  oo   o   % \
+ % %%%  % %  %o  %%%% \
+ %  %% % o   %@ %   % \
+ % o    o  %%.%%  o % \
+ %  % o% o% o     %%% \
+ %  %  %  %   %%%   % \
+ %  %%%%%%%% %      % \
+ %           %  %.%.% \
+ %%o%%%%%%%%o%   ...% \
+ %    .O  %    %%.%.% \
+ % .O...O   o  .....% \
+ %%%%%%%%%%%%%%%%%%%% \
+                      \
+/
+  b endmap
+}  
+/SED Soko/ !{
+  s/.*/there is no '&' level!/p
+  q
+}  
+
+: endmap
+# back to line 1 col 1
+s/^//
+# show available commands
+s,\(\n\)$,\1\1[ h j k l :q :r :z :gN ],
+x  
+/:p / !s/.*//
+b ini
+
+
+: zero
+
+# welcome message
+1 b welcome
+
+# first map loading
+2 b loadmap
+
+# supporting arrow keys also
+// {
+  s/\[A/k/g
+  s/\[B/j/g
+  s/\[C/l/g
+  s/\[D/h/g
+}  
+
+# command aliases
+s//:z/g
+
+# lowercase commands
+y/HJKLQGZR/hjklqgzr/
+
+# wipe trash (anything that is not command)
+s/[^hjklqgzr:0-9]//g
+
+# commands!
+/^:/ {
+  # quit
+  /^:q/ q
+
+  # refresh screen
+  /^:z/ {
+    s/.*//p
+    s/.*/:p [refresh]/
+    b ini
+  }
+  # goto level N (optional g)
+  /^:g\{0,1\}\([0-9]\{1,\}\)$/ {
+    s//\1/
+    h
+    x
+    s/.*/:p [goto level &]/
+    x
+    b loadmap
+  }
+  # restarting level
+  /^:r/ {
+    s/.*/:p [restart]/
+    x
+    s/.*LEVEL \([0-9]\{1,\}\).*/\1/
+    b loadmap
+  }
+}  
+
+
+# here the party begins
+: ini
+
+# print message (XXX bad idea)
+/^:p / {
+  s/.*//
+  #s//last command: /; s/$/       /p;
+  #s/last .*// 
+}  
+
+# empty command, jump to end
+/./ !{
+  x
+  b x
+}  
+
+
+# -------------[ LEFT ]--------------------------
+
+/^h/ {
+
+  # del current move and save others
+  s///
+  x
+
+  # reset 't' status
+  t zeroleft
+  : zeroleft
+
+  # clear path
+  s/ @/@ /
+  t x
+  # push load
+  s/ o@/o@ /
+  t x
+
+  # enter overdot
+  s/\.@/! /
+  t x
+  # continue overdot
+  s/\.!/!./
+  t x
+  # out overdot
+  s/ !/@./
+  t x
+
+  # enter load overdot
+  s/\.o@/O@ /
+  t x
+  # enter overdot with load
+  s/\.O@/O! /
+  t x
+  # continue overdot with load
+  s/\.O!/O!./
+  t x
+  # out load overdot / enter overdot
+  s/ O@/o! /
+  t x
+  # out load overdot / continue overdot
+  s/ O!/o!./
+  t x
+  # out overdot with load
+  s/ o!/o at ./
+  t x
+  # out overdot with load / enter overdot
+  s/\.o!/O at ./
+  t x
+
+  # can't pass
+  b x
+
+}  
+
+
+# -------------[ RIGHT ]-------------------------
+
+/^l/ {
+
+  # del current move and save others
+  s///
+  x
+
+  # reset 't' status
+  t zerorght
+  : zerorght
+
+  # clear path
+  s/@ / @/
+  t x
+  # push load
+  s/@o / @o/
+  t x
+
+  # enter overdot
+  s/@\./ !/
+  t x
+  # continue overdot
+  s/!\./.!/
+  t x
+  # out overdot
+  s/! /.@/
+  t x
+
+  # enter load overdot
+  s/@o\./ @O/
+  t x
+  # enter overdot with load
+  s/@O\./ !O/
+  t x
+  # continue overdot with load
+  s/!O\./.!O/
+  t x
+  # out load overdot / enter overdot
+  s/@O / !o/
+  t x
+  # out load overdot / continue overdot
+  s/!O /.!o/
+  t x
+  # out overdot with load
+  s/!o /. at o/
+  t x
+  # out overdot with load / enter overdot
+  s/!o\./. at O/
+  t x
+
+  # can't pass
+  b x
+}  
+
+
+# -------------[ DOWN ]--------------------------
+
+/^j/ {
+
+  # del current move and save others
+  s///
+  x
+
+  # reset 't' status
+  t zerodown
+  : zerodown
+
+  # clear path
+  s/@\(.\{22\}\) / \1@/
+  t x
+  # push load
+  s/@\(.\{22\}\)o\(.\{22\}\) / \1@\2o/
+  t x
+
+  # enter overdot
+  s/@\(.\{22\}\)\./ \1!/
+  t x
+  # continue overdot
+  s/!\(.\{22\}\)\./.\1!/
+  t x
+  # out overdot
+  s/!\(.\{22\}\) /.\1@/
+  t x
+
+  # enter load overdot
+  s/@\(.\{22\}\)o\(.\{22\}\)\./ \1@\2O/
+  t x
+  # enter overdot with load
+  s/@\(.\{22\}\)O\(.\{22\}\)\./ \1!\2O/
+  t x
+  # continue overdot with load
+  s/!\(.\{22\}\)O\(.\{22\}\)\./.\1!\2O/
+  t x
+  # out load overdot / enter overdot
+  s/@\(.\{22\}\)O\(.\{22\}\) / \1!\2o/
+  t x
+  # out load overdot / continue overdot
+  s/!\(.\{22\}\)O\(.\{22\}\) /.\1!\2o/
+  t x
+  # out overdot with load
+  s/!\(.\{22\}\)o\(.\{22\}\) /.\1@\2o/
+  t x
+  # out overdot with load / enter overdot
+  s/!\(.\{22\}\)o\(.\{22\}\)\./.\1@\2O/
+  t x
+
+  # target not free
+  b x
+}  
+
+
+# ---------------[ UP ]--------------------------
+
+/^k/ {
+
+  # del current move and save others
+  s///
+  x
+
+  # reset 't' status
+  t zeroup
+  : zeroup
+
+  # clear path
+  s/ \(.\{22\}\)@/@\1 /
+  t x
+  # push load
+  s/ \(.\{22\}\)o\(.\{22\}\)@/o\1@\2 /
+  t x
+
+  # enter overdot
+  s/\.\(.\{22\}\)@/!\1 /
+  t x
+  # continue overdot
+  s/\.\(.\{22\}\)!/!\1./
+  t x
+  # out overdot
+  s/ \(.\{22\}\)!/@\1./
+  t x
+
+  # enter load overdot
+  s/\.\(.\{22\}\)o\(.\{22\}\)@/O\1@\2 /
+  t x
+  # enter overdot with load
+  s/\.\(.\{22\}\)O\(.\{22\}\)@/O\1!\2 /
+  t x
+  # continue overdot with load
+  s/\.\(.\{22\}\)O\(.\{22\}\)!/O\1!\2./
+  t x
+  # out load overdot / enter overdot
+  s/ \(.\{22\}\)O\(.\{22\}\)@/o\1!\2 /
+  t x
+  # out load overdot / continue overdot
+  s/ \(.\{22\}\)O\(.\{22\}\)!/o\1!\2./
+  t x
+  # out overdot with load
+  s/ \(.\{22\}\)o\(.\{22\}\)!/o\1@\2./
+  t x
+  # out overdot with load / enter overdot
+  s/\.\(.\{22\}\)o\(.\{22\}\)!/O\1@\2./
+  t x
+
+  # target not free
+  b x
+}  
+
+# wrong command, do nothing
+s/^.//
+x  
+
+
+# ----------------[ THE END ]-----------------
+: x
+
+# adding color codes
+s/%/&/g
+s/[!@]/&/g
+s/O/&/g
+s/\./&/g
+
+
+# uncomment this line if you DON'T want colorized output (why not?)
+### s/\[[0-9;]*m//g
+
+# update screen
+p  
+
+# removing color codes from maze
+s/\[[0-9;]*m//g
+
+# no more messy boxes ('o'), level finished!
+/%%%.*o.*%%%/ !{
+  s/.*/(( VICT/
+  s/$/ORY! ))/
+  s/$/                                                   /
+  # uncomment here if you DON'T want color or sound on victory
+  # s///g ; s/\[[0-9;]*m//g
+  p
+  i \
+  You're a master of this level. Try the next!
+  q
+}  
+
+# save current position on hold space
+x  
+
+# skipping loop
+2 d
+
+# nice loop for accumulated moves
+/./ {
+  p
+  b ini
+}  
+
+# The End ;(
+
+### colorized by sedsed, a sed script debugger/indenter/tokenizer/HTMLizer
diff --git a/app/server/vendor/rouge/spec/visual/samples/shell b/app/server/vendor/rouge/spec/visual/samples/shell
new file mode 100755
index 0000000..2778668
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/shell
@@ -0,0 +1,2859 @@
+ry::setup() {
+cat <<sh
+export PATH="$(ry fullpath "$@")";
+if [ -n "\$BASH_VERSION" ]; then . "$RY_PREFIX/lib/ry.bash_completion"; fi
+sh
+}
+
+export PATH="$(ry fullpath "$@")";
+if [ -n "$BASH_VERSION" ]; then . "$RY_PREFIX/lib/ry.bash_completion"; fi
+
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun configure.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+basename="s,^.*/,,g"
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+# define SED for historic ltconfig's generated by Libtool 1.3
+test -z "$SED" && SED=sed
+
+# The name of this program:
+progname=`echo "$progpath" | $SED $basename`
+modename="$progname"
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.5.22
+TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)"
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes.
+if test -n "${ZSH_VERSION+set}" ; then
+  setopt NO_GLOB_SUBST
+fi
+# Same for EGREP, and just to be sure, do LTCC as well
+if test "X$EGREP" = X ; then
+    EGREP=egrep
+fi
+if test "X$LTCC" = X ; then
+    LTCC=${CC-gcc}
+fi
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell, and then maybe $echo will work.
+  exec $SHELL "$progpath" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit $EXIT_SUCCESS
+fi
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  SP2NL='tr \040 \012'
+  NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  SP2NL='tr \100 \n'
+  NL2SP='tr \r\n \100\100'
+  ;;
+esac
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+  save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+  save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" 	$lt_nl"
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  $echo "$modename: not configured to build any kind of library" 1>&2
+  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit $EXIT_FAILURE
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+duplicate_deps=no
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+if test -z "$max_cmd_len"; then
+  i=0
+  testring="ABCD"
+  new_result=
+  
+  # If test is not a shell built-in, we'll probably end up computing a
+  # maximum length that is only half of the actual maximum length, but
+  # we can't tell.
+  while (test "X"`$SHELL $0 --fallback-echo "X$testring" 2>/dev/null` \
+             = "XX$testring") >/dev/null 2>&1 &&
+          new_result=`expr "X$testring" : ".*" 2>&1` &&
+          max_cmd_len="$new_result" &&
+          test "$i" != 17 # 1/2 MB should be enough
+  do
+    i=`expr $i + 1`
+    testring="$testring$testring"
+  done
+  testring=
+  # Add a significant safety factor because C++ compilers can tack on massive
+  # amounts of additional arguments before passing them to the linker.
+  # It appears as though 1/2 is a usable value.
+  max_cmd_len=`expr $max_cmd_len \/ 2`
+fi
+
+#####################################
+# Shell function definitions:
+# This seems to be the best place for them
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+    if test "$run" = ":"; then
+      # Return a directory name, but don't create it in dry-run mode
+      my_tmpdir="${my_template}-$$"
+    else
+
+      # If mktemp works, use that first and foremost
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+      if test ! -d "$my_tmpdir"; then
+	# Failing that, at least try and use $RANDOM to avoid a race
+	my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+	save_mktempdir_umask=`umask`
+	umask 0077
+	$mkdir "$my_tmpdir"
+	umask $save_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$my_tmpdir" || {
+        $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2
+	exit $EXIT_FAILURE
+      }
+    fi
+
+    $echo "X$my_tmpdir" | $Xsed
+}
+
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+func_win32_libid ()
+{
+  win32_libid_type="unknown"
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
+      $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+      win32_nmres=`eval $NM -f posix -A $1 | \
+	$SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'`
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $echo $win32_libid_type
+}
+
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+	case $arg in
+	  *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+	CC_quoted="$CC_quoted $arg"
+      done
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+	for z in $available_tags; do
+	  if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+	    # Evaluate the configuration.
+	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    CC_quoted=
+	    for arg in $CC; do
+	    # Double-quote args containing other shell metacharacters.
+	    case $arg in
+	      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	      arg="\"$arg\""
+	      ;;
+	    esac
+	    CC_quoted="$CC_quoted $arg"
+	  done
+	    # user sometimes does CC=<HOST>-gcc so we need to match that to 'gcc'
+	    trimedcc=`echo ${CC} | $SED -e "s/${host}-//g"`
+	    # and sometimes libtool has CC=<HOST>-gcc but user does CC=gcc
+	    extendcc=${host}-${CC}
+	    # and sometimes libtool has CC=<OLDHOST>-gcc but user has CC=<NEWHOST>-gcc  
+	    # (Gentoo-specific hack because we always export $CHOST)
+	    mungedcc=${CHOST-${host}}-${trimedcc}
+	    case "$@ " in
+	      "cc "* | " cc "* | "${host}-cc "* | " ${host}-cc "*|\
+	      "gcc "* | " gcc "* | "${host}-gcc "* | " ${host}-gcc "*)
+	      tagname=CC
+	      break ;;
+	      "$trimedcc "* | " $trimedcc "* | "`$echo $trimedcc` "* | " `$echo $trimedcc` "*|\
+	      "$extendcc "* | " $extendcc "* | "`$echo $extendcc` "* | " `$echo $extendcc` "*|\
+	      "$mungedcc "* | " $mungedcc "* | "`$echo $mungedcc` "* | " `$echo $mungedcc` "*|\
+	      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*)
+	      # The compiler in the base compile command matches
+	      # the one in the tagged configuration.
+	      # Assume this is the tagged configuration we want.
+	      tagname=$z
+	      break
+	      ;;
+	    esac
+	  fi
+	done
+	# If $tagname still isn't set, then no tagged configuration
+	# was found and let the user know that the "--tag" command
+	# line option must be used.
+	if test -z "$tagname"; then
+	  $echo "$modename: unable to infer tagged configuration"
+	  $echo "$modename: specify a tag with \`--tag'" 1>&2
+	  exit $EXIT_FAILURE
+#        else
+#          $echo "$modename: using $tagname tagged configuration"
+	fi
+	;;
+      esac
+    fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+
+    $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)"
+    $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $?
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2
+      exit $EXIT_FAILURE
+    fi
+}
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    my_gentop="$1"; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
+    my_status=""
+
+    $show "${rm}r $my_gentop"
+    $run ${rm}r "$my_gentop"
+    $show "$mkdir $my_gentop"
+    $run $mkdir "$my_gentop"
+    my_status=$?
+    if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then
+      exit $my_status
+    fi
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+	*) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'`
+      my_xdir="$my_gentop/$my_xlib"
+
+      $show "${rm}r $my_xdir"
+      $run ${rm}r "$my_xdir"
+      $show "$mkdir $my_xdir"
+      $run $mkdir "$my_xdir"
+      exit_status=$?
+      if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then
+	exit $exit_status
+      fi
+      case $host in
+      *-darwin*)
+	$show "Extracting $my_xabs"
+	# Do not bother doing anything if just a dry run
+	if test -z "$run"; then
+	  darwin_orig_dir=`pwd`
+	  cd $my_xdir || exit $?
+	  darwin_archive=$my_xabs
+	  darwin_curdir=`pwd`
+	  darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'`
+	  darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null`
+	  if test -n "$darwin_arches"; then 
+	    darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'`
+	    darwin_arch=
+	    $show "$darwin_base_archive has multiple architectures $darwin_arches"
+	    for darwin_arch in  $darwin_arches ; do
+	      mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+	      cd "$darwin_curdir"
+	      $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+	    done # $darwin_arches
+      ## Okay now we have a bunch of thin objects, gotta fatten them up :)
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP`
+	    darwin_file=
+	    darwin_files=
+	    for darwin_file in $darwin_filelist; do
+	      darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
+	      lipo -create -output "$darwin_file" $darwin_files
+	    done # $darwin_filelist
+	    ${rm}r unfat-$$
+	    cd "$darwin_orig_dir"
+	  else
+	    cd "$darwin_orig_dir"
+ 	    func_extract_an_archive "$my_xdir" "$my_xabs"
+	  fi # $darwin_arches
+	fi # $run
+	;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+        ;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+    done
+    func_extract_archives_result="$my_oldobjs"
+}
+# End of Shell function definitions
+#####################################
+
+# Darwin sucks
+eval std_shrext=\"$shrext_cmds\"
+
+disable_libs=no
+
+# Parse our command line options once, thoroughly.
+while test "$#" -gt 0
+do
+  arg="$1"
+  shift
+
+  case $arg in
+  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case $prev in
+    execute_dlfiles)
+      execute_dlfiles="$execute_dlfiles $arg"
+      ;;
+    tag)
+      tagname="$arg"
+      preserve_args="${preserve_args}=$arg"
+
+      # Check whether tagname contains only valid characters
+      case $tagname in
+      *[!-_A-Za-z0-9,/]*)
+	$echo "$progname: invalid tag name: $tagname" 1>&2
+	exit $EXIT_FAILURE
+	;;
+      esac
+
+      case $tagname in
+      CC)
+	# Don't test for the "default" C tag, as we know, it's there, but
+	# not specially marked.
+	;;
+      *)
+	if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then
+	  taglist="$taglist $tagname"
+	  # Evaluate the configuration.
+	  eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`"
+	else
+	  $echo "$progname: ignoring unknown tag $tagname" 1>&2
+	fi
+	;;
+      esac
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case $arg in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+    $echo
+    $echo "Copyright (C) 2005  Free Software Foundation, Inc."
+    $echo "This is free software; see the source for copying conditions.  There is NO"
+    $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+    exit $?
+    ;;
+
+  --config)
+    ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath"
+    done
+    exit $?
+    ;;
+
+  --debug)
+    $echo "$progname: enabling shell trace mode"
+    set -x
+    preserve_args="$preserve_args $arg"
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    $echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      $echo "enable shared libraries"
+    else
+      $echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      $echo "enable static libraries"
+    else
+      $echo "disable static libraries"
+    fi
+    exit $?
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --preserve-dup-deps) duplicate_deps="yes" ;;
+
+  --quiet | --silent)
+    show=:
+    preserve_args="$preserve_args $arg"
+    ;;
+
+  --tag)
+    prevopt="--tag"
+    prev=tag
+    preserve_args="$preserve_args --tag"
+    ;;
+  --tag=*)
+    set tag "$optarg" ${1+"$@"}
+    shift
+    prev=tag
+    preserve_args="$preserve_args --tag"
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$modename: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit $EXIT_FAILURE
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit $EXIT_FAILURE
+fi
+
+case $disable_libs in
+no) 
+  ;;
+shared)
+  build_libtool_libs=no
+  build_old_libs=yes
+  ;;
+static)
+  build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+  ;;
+esac
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2
+    $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2
+    case $nonopt in
+    *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*)
+      mode=link
+      for arg
+      do
+	case $arg in
+	-c)
+	   mode=compile
+	   break
+	   ;;
+	esac
+      done
+      ;;
+    *db | *dbx | *strace | *truss)
+      mode=execute
+      ;;
+    *install*|cp|mv)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+	if test -n "$nonopt"; then
+	  $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+	else
+	  $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+	fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit $EXIT_FAILURE
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$modename --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case $mode in
+  # libtool compile mode
+  compile)
+    modename="$modename: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+	# do not "continue".  Instead, add this to base_compile
+	lastarg="$arg"
+	arg_mode=normal
+	;;
+
+      target )
+	libobj="$arg"
+	arg_mode=normal
+	continue
+	;;
+
+      normal )
+	# Accept any command-line options.
+	case $arg in
+	-o)
+	  if test -n "$libobj" ; then
+	    $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+	  arg_mode=target
+	  continue
+	  ;;
+
+	-static | -prefer-pic | -prefer-non-pic)
+	  later="$later $arg"
+	  continue
+	  ;;
+
+	-no-suppress)
+	  suppress_opt=no
+	  continue
+	  ;;
+
+	-Xcompiler)
+	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
+	  continue      #  The current "srcfile" will either be retained or
+	  ;;            #  replaced later.  I would guess that would be a bug.
+
+	-Wc,*)
+	  args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
+	  lastarg=
+	  save_ifs="$IFS"; IFS=','
+ 	  for arg in $args; do
+	    IFS="$save_ifs"
+
+	    # Double-quote args containing other shell metacharacters.
+	    # Many Bourne shells cannot handle close brackets correctly
+	    # in scan sets, so we specify it separately.
+	    case $arg in
+	      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	      arg="\"$arg\""
+	      ;;
+	    esac
+	    lastarg="$lastarg $arg"
+	  done
+	  IFS="$save_ifs"
+	  lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
+
+	  # Add the arguments to base_compile.
+	  base_compile="$base_compile $lastarg"
+	  continue
+	  ;;
+
+	* )
+	  # Accept the current argument as the source file.
+	  # The previous "srcfile" becomes the current argument.
+	  #
+	  lastarg="$srcfile"
+	  srcfile="$arg"
+	  ;;
+	esac  #  case $arg
+	;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+      case $lastarg in
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, and some SunOS ksh mistreat backslash-escaping
+      # in scan sets (worked around with variable expansion),
+      # and furthermore cannot handle '|' '&' '(' ')' in scan sets 
+      # at all, so we specify them separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	lastarg="\"$lastarg\""
+	;;
+      esac
+
+      base_compile="$base_compile $lastarg"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      $echo "$modename: you must specify an argument for -Xcompile"
+      exit $EXIT_FAILURE
+      ;;
+    target)
+      $echo "$modename: you must specify a target with \`-o'" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    *)
+      # Get the name of the library object.
+      [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    xform='[cCFSifmso]'
+    case $libobj in
+    *.ada) xform=ada ;;
+    *.adb) xform=adb ;;
+    *.ads) xform=ads ;;
+    *.asm) xform=asm ;;
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.ii) xform=ii ;;
+    *.class) xform=class ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    *.java) xform=java ;;
+    esac
+
+    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+    case $libobj in
+    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+    *)
+      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -static)
+	build_old_libs=yes
+	continue
+	;;
+
+      -prefer-pic)
+	pic_mode=yes
+	continue
+	;;
+
+      -prefer-non-pic)
+	pic_mode=no
+	continue
+	;;
+      esac
+    done
+
+    qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"`
+    case $qlibobj in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	qlibobj="\"$qlibobj\"" ;;
+    esac
+    test "X$libobj" != "X$qlibobj" \
+	&& $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' 	&()|`$[]' \
+	&& $echo "$modename: libobj name \`$libobj' may not contain shell special characters."
+    objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+    xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+    if test "X$xdir" = "X$obj"; then
+      xdir=
+    else
+      xdir=$xdir/
+    fi
+    lobj=${xdir}$objdir/$objname
+
+    if test -z "$base_compile"; then
+      $echo "$modename: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    $run $rm $removelist
+    trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2*)
+      pic_mode=default
+      ;;
+    esac
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+      removelist="$removelist $output_obj $lockfile"
+      trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $run ln "$srcfile" "$lockfile" 2>/dev/null; do
+	$show "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+	$echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit $EXIT_FAILURE
+      fi
+      $echo "$srcfile" > "$lockfile"
+    fi
+
+    if test -n "$fix_srcfile_path"; then
+      eval srcfile=\"$fix_srcfile_path\"
+    fi
+    qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"`
+    case $qsrcfile in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+      qsrcfile="\"$qsrcfile\"" ;;
+    esac
+
+    $run $rm "$libobj" "${libobj}T"
+
+    # Create a libtool object file (analogous to a ".la" file),
+    # but don't create it if we're doing a dry run.
+    test -z "$run" && cat > ${libobj}T <<EOF
+# $libobj - a libtool object file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+EOF
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test "$pic_mode" != no; then
+	command="$base_compile $qsrcfile $pic_flag"
+      else
+	# Don't build PIC code
+	command="$base_compile $qsrcfile"
+      fi
+
+      if test ! -d "${xdir}$objdir"; then
+	$show "$mkdir ${xdir}$objdir"
+	$run $mkdir ${xdir}$objdir
+	exit_status=$?
+	if test "$exit_status" -ne 0 && test ! -d "${xdir}$objdir"; then
+	  exit $exit_status
+	fi
+      fi
+
+      if test -z "$output_obj"; then
+	# Place PIC objects in $objdir
+	command="$command -o $lobj"
+      fi
+
+      $run $rm "$lobj" "$output_obj"
+
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+	test -n "$output_obj" && $run $rm $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+	$show "$mv $output_obj $lobj"
+	if $run $mv $output_obj $lobj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # Append the name of the PIC object to the libtool object file.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object='$objdir/$objname'
+
+EOF
+
+      # Allow error messages only from the first compilation.
+      if test "$suppress_opt" = yes; then
+        suppress_output=' >/dev/null 2>&1'
+      fi
+    else
+      # No PIC object so indicate it doesn't exist in the libtool
+      # object file.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object=none
+
+EOF
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+	# Don't build PIC code
+	command="$base_compile $qsrcfile"
+      else
+	command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+	command="$command -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      command="$command$suppress_output"
+      $run $rm "$obj" "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+	$run $rm $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+	$show "$mv $output_obj $obj"
+	if $run $mv $output_obj $obj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # Append the name of the non-PIC object the libtool object file.
+      # Only append if the libtool object file exists.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object='$objname'
+
+EOF
+    else
+      # Append the name of the non-PIC object the libtool object file.
+      # Only append if the libtool object file exists.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object=none
+
+EOF
+    fi
+
+    $run $mv "${libobj}T" "${libobj}"
+
+    # Unlock the critical section if it was locked
+    if test "$need_locks" != no; then
+      $run $rm "$lockfile"
+    fi
+
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool link mode
+  link | relink)
+    modename="$modename: link"
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args="$nonopt"
+    base_compile="$nonopt $@"
+    compile_command="$nonopt"
+    finalize_command="$nonopt"
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+
+    avoid_version=no
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    notinst_path= # paths that contain not-installed libtool libraries
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -all-static | -static)
+	if test "X$arg" = "X-all-static"; then
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	else
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=built
+	fi
+	build_libtool_libs=no
+	build_old_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg="$1"
+      shift
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
+	;;
+      *) qarg=$arg ;;
+      esac
+      libtool_args="$libtool_args $qarg"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  compile_command="$compile_command @OUTPUT@"
+	  finalize_command="$finalize_command @OUTPUT@"
+	  ;;
+	esac
+
+	case $prev in
+	dlfiles|dlprefiles)
+	  if test "$preload" = no; then
+	    # Add the symbol object into the linking commands.
+	    compile_command="$compile_command @SYMFILE@"
+	    finalize_command="$finalize_command @SYMFILE@"
+	    preload=yes
+	  fi
+	  case $arg in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test "$dlself" = no; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test "$prev" = dlprefiles; then
+	      dlself=yes
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test "$prev" = dlfiles; then
+	      dlfiles="$dlfiles $arg"
+	    else
+	      dlprefiles="$dlprefiles $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols="$arg"
+	  if test ! -f "$arg"; then
+	    $echo "$modename: symbol file \`$arg' does not exist"
+	    exit $EXIT_FAILURE
+	  fi
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	inst_prefix)
+	  inst_prefix_dir="$arg"
+	  prev=
+	  continue
+	  ;;
+	precious_regex)
+	  precious_files_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release="-$arg"
+	  prev=
+	  continue
+	  ;;
+	objectlist)
+	  if test -f "$arg"; then
+	    save_arg=$arg
+	    moreargs=
+	    for fil in `cat $save_arg`
+	    do
+#	      moreargs="$moreargs $fil"
+	      arg=$fil
+	      # A libtool-controlled object.
+
+	      # Check to see that this really is a libtool object.
+	      if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+		pic_object=
+		non_pic_object=
+
+		# Read the .lo file
+		# If there is no directory component, then add one.
+		case $arg in
+		*/* | *\\*) . $arg ;;
+		*) . ./$arg ;;
+		esac
+
+		if test -z "$pic_object" || \
+		   test -z "$non_pic_object" ||
+		   test "$pic_object" = none && \
+		   test "$non_pic_object" = none; then
+		  $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+		  exit $EXIT_FAILURE
+		fi
+
+		# Extract subdirectory from the argument.
+		xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+		if test "X$xdir" = "X$arg"; then
+		  xdir=
+		else
+		  xdir="$xdir/"
+		fi
+
+		if test "$pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  pic_object="$xdir$pic_object"
+
+		  if test "$prev" = dlfiles; then
+		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		      dlfiles="$dlfiles $pic_object"
+		      prev=
+		      continue
+		    else
+		      # If libtool objects are unsupported, then we need to preload.
+		      prev=dlprefiles
+		    fi
+		  fi
+
+		  # CHECK ME:  I think I busted this.  -Ossama
+		  if test "$prev" = dlprefiles; then
+		    # Preload the old-style object.
+		    dlprefiles="$dlprefiles $pic_object"
+		    prev=
+		  fi
+
+		  # A PIC object.
+		  libobjs="$libobjs $pic_object"
+		  arg="$pic_object"
+		fi
+
+		# Non-PIC object.
+		if test "$non_pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  non_pic_object="$xdir$non_pic_object"
+
+		  # A standard non-PIC object
+		  non_pic_objects="$non_pic_objects $non_pic_object"
+		  if test -z "$pic_object" || test "$pic_object" = none ; then
+		    arg="$non_pic_object"
+		  fi
+		else
+		  # If the PIC object exists, use it instead.
+		  # $xdir was prepended to $pic_object above.
+		  non_pic_object="$pic_object"
+		  non_pic_objects="$non_pic_objects $non_pic_object"
+		fi
+	      else
+		# Only an error if not doing a dry-run.
+		if test -z "$run"; then
+		  $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+		  exit $EXIT_FAILURE
+		else
+		  # Dry-run case.
+
+		  # Extract subdirectory from the argument.
+		  xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+		  if test "X$xdir" = "X$arg"; then
+		    xdir=
+		  else
+		    xdir="$xdir/"
+		  fi
+
+		  pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+		  non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+		  libobjs="$libobjs $pic_object"
+		  non_pic_objects="$non_pic_objects $non_pic_object"
+		fi
+	      fi
+	    done
+	  else
+	    $echo "$modename: link input file \`$save_arg' does not exist"
+	    exit $EXIT_FAILURE
+	  fi
+	  arg=$save_arg
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    $echo "$modename: only absolute run-paths are allowed" 1>&2
+	    exit $EXIT_FAILURE
+	    ;;
+	  esac
+	  if test "$prev" = rpath; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) rpath="$rpath $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) xrpath="$xrpath $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	xcompiler)
+	  compiler_flags="$compiler_flags $qarg"
+	  prev=
+	  compile_command="$compile_command $qarg"
+	  finalize_command="$finalize_command $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  linker_flags="$linker_flags $qarg"
+	  compiler_flags="$compiler_flags $wl$qarg"
+	  prev=
+	  compile_command="$compile_command $wl$qarg"
+	  finalize_command="$finalize_command $wl$qarg"
+	  continue
+	  ;;
+	xcclinker)
+	  linker_flags="$linker_flags $qarg"
+	  compiler_flags="$compiler_flags $qarg"
+	  prev=
+	  compile_command="$compile_command $qarg"
+	  finalize_command="$finalize_command $qarg"
+	  continue
+	  ;;
+	shrext)
+  	  shrext_cmds="$arg"
+	  prev=
+	  continue
+	  ;;
+	darwin_framework|darwin_framework_skip)
+	  test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg"
+	  compile_command="$compile_command $arg"
+	  finalize_command="$finalize_command $arg"
+	  prev=
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi # test -n "$prev"
+
+      prevarg="$arg"
+
+      case $arg in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  compile_command="$compile_command $link_static_flag"
+	  finalize_command="$finalize_command $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	$echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+	continue
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  $echo "$modename: more than one -exported-symbols argument is not allowed"
+	  exit $EXIT_FAILURE
+	fi
+	if test "X$arg" = "X-export-symbols"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -framework|-arch|-isysroot)
+	case " $CC " in
+	  *" ${arg} ${1} "* | *" ${arg}	${1} "*) 
+		prev=darwin_framework_skip ;;
+	  *) compiler_flags="$compiler_flags $arg"
+	     prev=darwin_framework ;;
+	esac
+	compile_command="$compile_command $arg"
+	finalize_command="$finalize_command $arg"
+	continue
+	;;
+
+      -inst-prefix-dir)
+	prev=inst_prefix
+	continue
+	;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+	case $with_gcc/$host in
+	no/*-*-irix* | /*-*-irix*)
+	  compile_command="$compile_command $arg"
+	  finalize_command="$finalize_command $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  if test -z "$absdir"; then
+	    $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+	    absdir="$dir"
+	    notinst_path="$notinst_path $dir"
+	  fi
+	  dir="$absdir"
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "*) ;;
+	*)
+	  deplibs="$deplibs -L$dir"
+	  lib_search_path="$lib_search_path $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+	  testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$dir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$testbindir";;
+	  esac
+	  ;;
+	esac
+	continue
+	;;
+
+      -l*)
+	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*)
+	    # These systems don't actually have a C or math library (as such)
+	    continue
+	    ;;
+	  *-*-os2*)
+	    # These systems don't actually have a C library (as such)
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C and math libraries are in the System framework
+	    deplibs="$deplibs -framework System"
+	    continue
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  esac
+	elif test "X$arg" = "X-lc_r"; then
+	 case $host in
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	   # Do not include libc_r directly, use -pthread flag.
+	   continue
+	   ;;
+	 esac
+	fi
+	deplibs="$deplibs $arg"
+	continue
+	;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      -model)
+	compile_command="$compile_command $arg"
+	compiler_flags="$compiler_flags $arg"
+	finalize_command="$finalize_command $arg"
+	prev=xcompiler
+	continue
+	;;
+
+     -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
+	compiler_flags="$compiler_flags $arg"
+	compile_command="$compile_command $arg"
+	finalize_command="$finalize_command $arg"
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
+      # -r[0-9][0-9]* specifies the processor on the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
+      # +DA*, +DD* enable 64-bit mode on the HP compiler
+      # -q* pass through compiler args for the IBM compiler
+      # -m* pass through architecture-specific compiler args for GCC
+      # -m*, -t[45]*, -txscale* pass through architecture-specific
+      # compiler args for GCC
+      # -pg pass through profiling flag for GCC
+      # @file GCC response files
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \
+      -t[45]*|-txscale*|@*)
+
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case $arg in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+        compile_command="$compile_command $arg"
+        finalize_command="$finalize_command $arg"
+        compiler_flags="$compiler_flags $arg"
+        continue
+        ;;
+
+      -shrext)
+	prev=shrext
+	continue
+	;;
+
+      -no-fast-install)
+	fast_install=no
+	continue
+	;;
+
+      -no-install)
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+	  # The PATH hackery in wrapper scripts is required on Windows
+	  # in order for the loader to find any dlls it needs.
+	  $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
+	  $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
+	  fast_install=no
+	  ;;
+	*) no_install=yes ;;
+	esac
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -objectlist)
+	prev=objectlist
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+	prev=precious_regex
+	continue
+	;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  $echo "$modename: only absolute run-paths are allowed" 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) xrpath="$xrpath $dir" ;;
+	esac
+	continue
+	;;
+
+      -static)
+	# The effects of -static are defined in a previous loop.
+	# We used to do the same as -all-static on platforms that
+	# didn't have a PIC flag, but the assumption that the effects
+	# would be equivalent was wrong.  It would break on at least
+	# Digital Unix and AIX.
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+      -version-number)
+	prev=vinfo
+	vinfo_number=yes
+	continue
+	;;
+
+      -Wc,*)
+	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+	  case $flag in
+	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	    flag="\"$flag\""
+	    ;;
+	  esac
+	  arg="$arg $wl$flag"
+	  compiler_flags="$compiler_flags $flag"
+	done
+	IFS="$save_ifs"
+	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+	;;
+
+      -Wl,*)
+	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+	  case $flag in
+	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	    flag="\"$flag\""
+	    ;;
+	  esac
+	  arg="$arg $wl$flag"
+	  compiler_flags="$compiler_flags $wl$flag"
+	  linker_flags="$linker_flags $flag"
+	done
+	IFS="$save_ifs"
+	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Xlinker)
+	prev=xlinker
+	continue
+	;;
+
+      -XCClinker)
+	prev=xcclinker
+	continue
+	;;
+
+      # Some other compiler flag.
+      -* | +*)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case $arg in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+	;;
+
+      *.$objext)
+	# A standard object.
+	objs="$objs $arg"
+	;;
+
+      *.lo)
+	# A libtool-controlled object.
+
+	# Check to see that this really is a libtool object.
+	if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  pic_object=
+	  non_pic_object=
+
+	  # Read the .lo file
+	  # If there is no directory component, then add one.
+	  case $arg in
+	  */* | *\\*) . $arg ;;
+	  *) . ./$arg ;;
+	  esac
+
+	  if test -z "$pic_object" || \
+	     test -z "$non_pic_object" ||
+	     test "$pic_object" = none && \
+	     test "$non_pic_object" = none; then
+	    $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+
+	  # Extract subdirectory from the argument.
+	  xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+	  if test "X$xdir" = "X$arg"; then
+	    xdir=
+ 	  else
+	    xdir="$xdir/"
+	  fi
+
+	  if test "$pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    pic_object="$xdir$pic_object"
+
+	    if test "$prev" = dlfiles; then
+	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		dlfiles="$dlfiles $pic_object"
+		prev=
+		continue
+	      else
+		# If libtool objects are unsupported, then we need to preload.
+		prev=dlprefiles
+	      fi
+	    fi
+
+	    # CHECK ME:  I think I busted this.  -Ossama
+	    if test "$prev" = dlprefiles; then
+	      # Preload the old-style object.
+	      dlprefiles="$dlprefiles $pic_object"
+	      prev=
+	    fi
+
+	    # A PIC object.
+	    libobjs="$libobjs $pic_object"
+	    arg="$pic_object"
+	  fi
+
+	  # Non-PIC object.
+	  if test "$non_pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    non_pic_object="$xdir$non_pic_object"
+
+	    # A standard non-PIC object
+	    non_pic_objects="$non_pic_objects $non_pic_object"
+	    if test -z "$pic_object" || test "$pic_object" = none ; then
+	      arg="$non_pic_object"
+	    fi
+	  else
+	    # If the PIC object exists, use it instead.
+	    # $xdir was prepended to $pic_object above.
+	    non_pic_object="$pic_object"
+	    non_pic_objects="$non_pic_objects $non_pic_object"
+	  fi
+	else
+	  # Only an error if not doing a dry-run.
+	  if test -z "$run"; then
+	    $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+	    exit $EXIT_FAILURE
+	  else
+	    # Dry-run case.
+
+	    # Extract subdirectory from the argument.
+	    xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+	    if test "X$xdir" = "X$arg"; then
+	      xdir=
+	    else
+	      xdir="$xdir/"
+	    fi
+
+	    pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+	    non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+	    libobjs="$libobjs $pic_object"
+	    non_pic_objects="$non_pic_objects $non_pic_object"
+	  fi
+	fi
+	;;
+
+      *.$libext)
+	# An archive.
+	deplibs="$deplibs $arg"
+	old_deplibs="$old_deplibs $arg"
+	continue
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	if test "$prev" = dlfiles; then
+	  # This library was specified with -dlopen.
+	  dlfiles="$dlfiles $arg"
+	  prev=
+	elif test "$prev" = dlprefiles; then
+	  # The library was specified with -dlpreopen.
+	  dlprefiles="$dlprefiles $arg"
+	  prev=
+	else
+	  deplibs="$deplibs $arg"
+	fi
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case $arg in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+	;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	compile_command="$compile_command $arg"
+	finalize_command="$finalize_command $arg"
+      fi
+    done # argument parsing loop
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      compile_command="$compile_command $arg"
+      finalize_command="$finalize_command $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+    if test "X$output_objdir" = "X$output"; then
+      output_objdir="$objdir"
+    else
+      output_objdir="$output_objdir/$objdir"
+    fi
+    # Create the object directory.
+    if test ! -d "$output_objdir"; then
+      $show "$mkdir $output_objdir"
+      $run $mkdir $output_objdir
+      exit_status=$?
+      if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then
+	exit $exit_status
+      fi
+    fi
+
+    # Determine the type of output
+    case $output in
+    "")
+      $echo "$modename: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    case $host in
+    *cygwin* | *mingw* | *pw32*)
+      # don't eliminate duplications in $postdeps and $predeps
+      duplicate_compiler_generated_deps=yes
+      ;;
+    *)
+      duplicate_compiler_generated_deps=$duplicate_deps
+      ;;
+    esac
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if test "X$duplicate_deps" = "Xyes" ; then
+	case "$libs " in
+	*" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	esac
+      fi
+      libs="$libs $deplib"
+    done
+
+    if test "$linkmode" = lib; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then
+	for pre_post_dep in $predeps $postdeps; do
+	  case "$pre_post_deps " in
+	  *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+	  esac
+	  pre_post_deps="$pre_post_deps $pre_post_dep"
+	done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    case $linkmode in
+    lib)
+	passes="conv link"
+	for file in $dlfiles $dlprefiles; do
+	  case $file in
+	  *.la) ;;
+	  *)
+	    $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
+	    exit $EXIT_FAILURE
+	    ;;
+	  esac
+	done
+	;;
+    prog)
+	compile_deplibs=
+	finalize_deplibs=
+	alldeplibs=no
+	newdlfiles=
+	newdlprefiles=
+	passes="conv scan dlopen dlpreopen link"
+	;;
+    *)  passes="conv"
+	;;
+    esac
+    for pass in $passes; do
+      if test "$linkmode,$pass" = "lib,link" ||
+	 test "$linkmode,$pass" = "prog,scan"; then
+	libs="$deplibs"
+	deplibs=
+      fi
+      if test "$linkmode" = prog; then
+	case $pass in
+	dlopen) libs="$dlfiles" ;;
+	dlpreopen) libs="$dlprefiles" ;;
+	link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+	esac
+      fi
+      if test "$pass" = dlopen; then
+	# Collect dlpreopened libraries
+	save_deplibs="$deplibs"
+	deplibs=
+      fi
+      for deplib in $libs; do
+	lib=
+	found=no
+	case $deplib in
+	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    compiler_flags="$compiler_flags $deplib"
+	  fi
+	  continue
+	  ;;
+	-l*)
+	  if test "$linkmode" != lib && test "$linkmode" != prog; then
+	    $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2
+	    continue
+	  fi
+	  name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
+	  for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do
+	    for search_ext in .la $std_shrext .so .a; do
+	      # Search the libtool library
+	      lib="$searchdir/lib${name}${search_ext}"
+	      if test -f "$lib"; then
+		if test "$search_ext" = ".la"; then
+		  found=yes
+		else
+		  found=no
+		fi
+		break 2
+	      fi
+	    done
+	  done
+	  if test "$found" != yes; then
+	    # deplib doesn't seem to be a libtool library
+	    if test "$linkmode,$pass" = "prog,link"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  else # deplib is a libtool library
+	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+	    # We need to do some special things here, and not later.
+	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	      case " $predeps $postdeps " in
+	      *" $deplib "*)
+		if (${SED} -e '2q' $lib |
+                    grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+		  library_names=
+		  old_library=
+		  case $lib in
+		  */* | *\\*) . $lib ;;
+		  *) . ./$lib ;;
+		  esac
+		  for l in $old_library $library_names; do
+		    ll="$l"
+		  done
+		  if test "X$ll" = "X$old_library" ; then # only static version available
+		    found=no
+		    ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+		    test "X$ladir" = "X$lib" && ladir="."
+		    lib=$ladir/$old_library
+		    if test "$linkmode,$pass" = "prog,link"; then
+		      compile_deplibs="$deplib $compile_deplibs"
+		      finalize_deplibs="$deplib $finalize_deplibs"
+		    else
+		      deplibs="$deplib $deplibs"
+		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+		    fi
+		    continue
+		  fi
+		fi
+	        ;;
+	      *) ;;
+	      esac
+	    fi
+	  fi
+	  ;; # -l
+	-L*)
+	  case $linkmode in
+	  lib)
+	    deplibs="$deplib $deplibs"
+	    test "$pass" = conv && continue
+	    newdependency_libs="$deplib $newdependency_libs"
+	    newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+	    ;;
+	  prog)
+	    if test "$pass" = conv; then
+	      deplibs="$deplib $deplibs"
+	      continue
+	    fi
+	    if test "$pass" = scan; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+	    ;;
+	  *)
+	    $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2
+	    ;;
+	  esac # linkmode
+	  continue
+	  ;; # -L
+	-R*)
+	  if test "$pass" = link; then
+	    dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+	    # Make sure the xrpath contains only unique directories.
+	    case "$xrpath " in
+	    *" $dir "*) ;;
+	    *) xrpath="$xrpath $dir" ;;
+	    esac
+	  fi
+	  deplibs="$deplib $deplibs"
+	  continue
+	  ;;
+	*.la) lib="$deplib" ;;
+	*.$libext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  case $linkmode in
+	  lib)
+	    valid_a_lib=no
+	    case $deplibs_check_method in
+	      match_pattern*)
+		set dummy $deplibs_check_method
+	        match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+		if eval $echo \"$deplib\" 2>/dev/null \
+		    | $SED 10q \
+		    | $EGREP "$match_pattern_regex" > /dev/null; then
+		  valid_a_lib=yes
+		fi
+		;;
+	      pass_all)
+		valid_a_lib=yes
+		;;
+            esac
+	    if test "$valid_a_lib" != yes; then
+	      $echo
+	      $echo "*** Warning: Trying to link with static lib archive $deplib."
+	      $echo "*** I have the capability to make that library automatically link in when"
+	      $echo "*** you link to this library.  But I can only do this if you have a"
+	      $echo "*** shared version of the library, which you do not appear to have"
+	      $echo "*** because the file extensions .$libext of this argument makes me believe"
+	      $echo "*** that it is just a static archive that I should not used here."
+	    else
+	      $echo
+	      $echo "*** Warning: Linking the shared library $output against the"
+	      $echo "*** static library $deplib is not portable!"
+	      deplibs="$deplib $deplibs"
+	    fi
+	    continue
+	    ;;
+	  prog)
+	    if test "$pass" != link; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    continue
+	    ;;
+	  esac # linkmode
+	  ;; # *.$libext
+	*.lo | *.$objext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	  elif test "$linkmode" = prog; then
+	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+	      # If there is no dlopen support or we're linking statically,
+	      # we need to preload.
+	      newdlprefiles="$newdlprefiles $deplib"
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      newdlfiles="$newdlfiles $deplib"
+	    fi
+	  fi
+	  continue
+	  ;;
+	%DEPLIBS%)
+	  alldeplibs=yes
+	  continue
+	  ;;
+	esac # case $deplib
+	if test "$found" = yes || test -f "$lib"; then :
+	else
+	  $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	# Check to see that this really is a libtool archive.
+	if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$ladir" = "X$lib" && ladir="."
+
+	dlname=
+	dlopen=
+	dlpreopen=
+	libdir=
+	library_names=
+	old_library=
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variables installed, or shouldnotlink
+	installed=yes
+	shouldnotlink=no
+	avoidtemprpath=
+
+
+	# Read the .la file
+	case $lib in
+	*/* | *\\*) . $lib ;;
+	*) . ./$lib ;;
+	esac
+
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+	  test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+	  test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+	fi
+
+	if test "$pass" = conv; then
+	  # Only check for convenience libraries
+	  deplibs="$lib $deplibs"
+	  if test -z "$libdir"; then
+	    if test -z "$old_library"; then
+	      $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+	      exit $EXIT_FAILURE
+	    fi
+	    # It is a libtool convenience library, so add in its objects.
+	    convenience="$convenience $ladir/$objdir/$old_library"
+	    old_convenience="$old_convenience $ladir/$objdir/$old_library"
+	    tmp_libs=
+	    for deplib in $dependency_libs; do
+	      deplibs="$deplib $deplibs"
+              if test "X$duplicate_deps" = "Xyes" ; then
+	        case "$tmp_libs " in
+	        *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	        esac
+              fi
+	      tmp_libs="$tmp_libs $deplib"
+	    done
+	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+	    $echo "$modename: \`$lib' is not a convenience library" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+	  continue
+	fi # $pass = conv
+
+
+	# Get the name of the library we link against.
+	linklib=
+	for l in $old_library $library_names; do
+	  linklib="$l"
+	done
+	if test -z "$linklib"; then
+	  $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	# This library was specified with -dlopen.
+	if test "$pass" = dlopen; then
+	  if test -z "$libdir"; then
+	    $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+	  if test -z "$dlname" ||
+	     test "$dlopen_support" != yes ||
+	     test "$build_libtool_libs" = no; then
+	    # If there is no dlname, no dlopen support or we're linking
+	    # statically, we need to preload.  We also need to preload any
+	    # dependent libraries so libltdl's deplib preloader doesn't
+	    # bomb out in the load deplibs phase.
+	    dlprefiles="$dlprefiles $lib $dependency_libs"
+	  else
+	    newdlfiles="$newdlfiles $lib"
+	  fi
+	  continue
+	fi # $pass = dlopen
+
+	# We need an absolute path.
+	case $ladir in
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+	*)
+	  abs_ladir=`cd "$ladir" && pwd`
+	  if test -z "$abs_ladir"; then
+	    $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
+	    $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+	    abs_ladir="$ladir"
+	  fi
+	  ;;
+	esac
+	laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+
+	# Find the relevant object directory and library name.
+	if test "X$installed" = Xyes; then
+	  if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    $echo "$modename: warning: library \`$lib' was moved." 1>&2
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
+	  else
+	    dir="$libdir"
+	    absdir="$libdir"
+	  fi
+	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+	else
+	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    # Remove this search path later
+	    notinst_path="$notinst_path $abs_ladir"
+	  else
+	    dir="$ladir/$objdir"
+	    absdir="$abs_ladir/$objdir"
+	    # Remove this search path later
+	    notinst_path="$notinst_path $abs_ladir"
+	  fi
+	fi # $installed = yes
+	name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+
+	# This library was specified with -dlpreopen.
+	if test "$pass" = dlpreopen; then
+	  if test -z "$libdir"; then
+	    $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+	  # Prefer using a static library (so that no silly _DYNAMIC symbols
+	  # are required to link).
+	  if test -n "$old_library"; then
+	    newdlprefiles="$newdlprefiles $dir/$old_library"
+	  # Otherwise, use the dlname, so that lt_dlopen finds it.
+	  elif test -n "$dlname"; then
+	    newdlprefiles="$newdlprefiles $dir/$dlname"
+	  else
+	    newdlprefiles="$newdlprefiles $dir/$linklib"
+	  fi
+	fi # $pass = dlpreopen
+
+	if test -z "$libdir"; then
+	  # Link the convenience library
+	  if test "$linkmode" = lib; then
+	    deplibs="$dir/$old_library $deplibs"
+	  elif test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$dir/$old_library $compile_deplibs"
+	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
+	  else
+	    deplibs="$lib $deplibs" # used for prog,scan pass
+	  fi
+	  continue
+	fi
+
+
+	if test "$linkmode" = prog && test "$pass" != link; then
+	  newlib_search_path="$newlib_search_path $ladir"
+	  deplibs="$lib $deplibs"
+
+	  linkalldeplibs=no
+	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
+	     test "$build_libtool_libs" = no; then
+	    linkalldeplibs=yes
+	  fi
+
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    case $deplib in
+	    -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
+	    esac
+	    # Need to link against all dependency_libs?
+	    if test "$linkalldeplibs" = yes; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      # Need to hardcode shared library paths
+	      # or/and link against static libraries
+	      newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    if test "X$duplicate_deps" = "Xyes" ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	      esac
+	    fi
+	    tmp_libs="$tmp_libs $deplib"
+	  done # for deplib
+	  continue
+	fi # $linkmode = prog...
+
+	if test "$linkmode,$pass" = "prog,link"; then
+	  if test -n "$library_names" &&
+	     { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+	    # We need to hardcode the library path
+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+	      # Make sure the rpath contains only unique directories.
+	      case "$temp_rpath " in
+	      *" $dir "*) ;;
+	      *" $absdir "*) ;;
+	      *) temp_rpath="$temp_rpath $absdir" ;;
+	      esac
+	    fi
+
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) compile_rpath="$compile_rpath $absdir"
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) finalize_rpath="$finalize_rpath $libdir"
+	      esac
+	      ;;
+	    esac
+	  fi # $linkmode,$pass = prog,link...
+
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
+		 test -n "$library_names"; }; }; then
+	    # We only need to search for static libraries
+	    continue
+	  fi
+	fi
+
+	link_static=no # Whether the deplib will be linked statically
+	use_static_libs=$prefer_static_libs
+	if test "$use_static_libs" = built && test "$installed" = yes ; then
+	  use_static_libs=no
+	fi
+	if test -n "$library_names" &&
+	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
+	  if test "$installed" = no; then
+	    notinst_deplibs="$notinst_deplibs $lib"
+	    need_relink=yes
+	  fi
+	  # This is a shared library
+
+	  # Warn about portability, can't link against -module's on
+	  # some systems (darwin)
+	  if test "$shouldnotlink" = yes && test "$pass" = link ; then
+	    $echo
+	    if test "$linkmode" = prog; then
+	      $echo "*** Warning: Linking the executable $output against the loadable module"
+	    else
+	      $echo "*** Warning: Linking the shared library $output against the loadable module"
+	    fi
+	    $echo "*** $linklib is not portable!"
+	  fi
+	  if test "$linkmode" = lib &&
+	     test "$hardcode_into_libs" = yes; then
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) compile_rpath="$compile_rpath $absdir"
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) finalize_rpath="$finalize_rpath $libdir"
+	      esac
+	      ;;
+	    esac
+	  fi
+
+	  if test -n "$old_archive_from_expsyms_cmds"; then
+	    # figure out the soname
+	    set dummy $library_names
+	    realname="$2"
+	    shift; shift
+	    libname=`eval \\$echo \"$libname_spec\"`
+	    # use dlname if we got it. it's perfectly good, no?
+	    if test -n "$dlname"; then
+	      soname="$dlname"
+	    elif test -n "$soname_spec"; then
+	      # bleh windows
+	      case $host in
+	      *cygwin* | mingw*)
+		major=`expr $current - $age`
+		versuffix="-$major"
+		;;
+	      esac
+	      eval soname=\"$soname_spec\"
+	    else
+	      soname="$realname"
+	    fi
+
+	    # Make a new name for the extract_expsyms_cmds to use
+	    soroot="$soname"
+	    soname=`$echo $soroot | ${SED} -e 's/^.*\///'`
+	    newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a"
+
+	    # If the library has no export list, then create one now
+	    if test -f "$output_objdir/$soname-def"; then :
+	    else
+	      $show "extracting exported symbol list from \`$soname'"
+	      save_ifs="$IFS"; IFS='~'
+	      cmds=$extract_expsyms_cmds
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		eval cmd=\"$cmd\"
+		$show "$cmd"
+		$run eval "$cmd" || exit $?
+	      done
+	      IFS="$save_ifs"
+	    fi
+
+	    # Create $newlib
+	    if test -f "$output_objdir/$newlib"; then :; else
+	      $show "generating import library for \`$soname'"
+	      save_ifs="$IFS"; IFS='~'
+	      cmds=$old_archive_from_expsyms_cmds
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		eval cmd=\"$cmd\"
+		$show "$cmd"
+		$run eval "$cmd" || exit $?
+	      done
+	      IFS="$save_ifs"
+	    fi
+	    # make sure the library variables are pointing to the new library
+	    dir=$output_objdir
+	    linklib=$newlib
+	  fi # test -n "$old_archive_from_expsyms_cmds"
+
+	  if test "$linkmode" = prog || test "$mode" != relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    lib_linked=yes
+	    case $hardcode_action in
+	    immediate | unsupported)
+	      if test "$hardcode_direct" = no; then
+		add="$dir/$linklib"
+		case $host in
+		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+		    *-*-unixware7*) add_dir="-L$dir" ;;
+		  *-*-darwin* )
+		    # if the lib is a module then we can not link against
+		    # it, someone is ignoring the new warnings I added
+		    if /usr/bin/file -L $add 2> /dev/null |
+                      $EGREP ": [^:]* bundle" >/dev/null ; then
+		      $echo "** Warning, lib $linklib is a module, not a shared library"
+		      if test -z "$old_library" ; then
+		        $echo
+		        $echo "** And there doesn't seem to be a static archive available"
+		        $echo "** The link will probably fail, sorry"
+		      else
+		        add="$dir/$old_library"
+		      fi
+		    fi
+		esac
+	      elif test "$hardcode_minus_L" = no; then
+		case $host in
+		*-*-sunos*) add_shlibpath="$dir" ;;
+		esac
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = no; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    relink)
+	      if test "$hardcode_direct" = yes; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$dir"
+		# Try looking first in the location we're being installed to.
+		if test -n "$inst_prefix_dir"; then
+		  case $libdir in
+		    [\\/]*)
+		      add_dir="$add_dir -L$inst_prefix_dir$libdir"
+		      ;;
+		  esac
+		fi
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = yes; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    *) lib_linked=no ;;
+	    esac
+
+	    if test "$lib_linked" != yes; then
+	      $echo "$modename: configuration error: unsupported hardcode properties"
+	      exit $EXIT_FAILURE
+	    fi
+
+	    if test -n "$add_shlibpath"; then
+	      case :$compile_shlibpath: in
+	      *":$add_shlibpath:"*) ;;
+	      *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+	      esac
+	    fi
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	      if test "$hardcode_direct" != yes && \
+		 test "$hardcode_minus_L" != yes && \
+		 test "$hardcode_shlibpath_var" = yes; then
+		case :$finalize_shlibpath: in
+		*":$libdir:"*) ;;
+		*) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+		esac
+	      fi
+	    fi
+	  fi
+
+	  if test "$linkmode" = prog || test "$mode" = relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    # Finalize command for both is simple: just hardcode it.
+	    if test "$hardcode_direct" = yes; then
+	      add="$libdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
+	      case :$finalize_shlibpath: in
+	      *":$libdir:"*) ;;
+	      *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+	      esac
+	      add="-l$name"
+	    elif test "$hardcode_automatic" = yes; then
+	      if test -n "$inst_prefix_dir" &&
+		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
+	        add="$inst_prefix_dir$libdir/$linklib"
+	      else
+	        add="$libdir/$linklib"
+	      fi
+	    else
+	      # We cannot seem to hardcode it, guess we'll fake it.
+	      add_dir="-L$libdir"
+	      # Try looking first in the location we're being installed to.
+	      if test -n "$inst_prefix_dir"; then
+		case $libdir in
+		  [\\/]*)
+		    add_dir="$add_dir -L$inst_prefix_dir$libdir"
+		    ;;
+		esac
+	      fi
+	      add="-l$name"
+	    fi
+
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	    fi
+	  fi
+	elif test "$linkmode" = prog; then
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
+	    compile_deplibs="$dir/$linklib $compile_deplibs"
+	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
+	  else
+	    compile_deplibs="-l$name -L$dir $compile_deplibs"
+	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+	  fi
+	elif test "$build_libtool_libs" = yes; then
+	  # Not a shared library
+	  if test "$deplibs_check_method" != pass_all; then
+	    # We're trying link a shared library against a static one
+	    # but the system doesn't support it.
+
diff --git a/app/server/vendor/rouge/spec/visual/samples/slim b/app/server/vendor/rouge/spec/visual/samples/slim
new file mode 100755
index 0000000..adaffcf
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/slim
@@ -0,0 +1,80 @@
+doctype html
+html
+  head
+    title Slim Examples
+
+  / This is a comment for the body
+  body
+    h1 Markup examples
+
+    / Inline nested ruby expressions
+    p Nested interp #{list.map { |x| x + 1 }.inject(&:+)} parses ok
+    
+    /! HTML comment
+    #content
+      p This example shows you how a basic Slim file looks like.
+      span class=ruby_method data-something='hmmm' = some_other_ruby_method
+
+      / Splats
+      .csclass data-attr=RUBY_CONSTANT width = "23px" Woot!
+      .card *method_which_return_hash! = place.name
+      .herp *@hash_instance_variable = place.name
+      #derp*{'data-url'=>place_path(place), 'data-id'=>place.id} = place.name
+
+      / Dynamic tags
+      *ruby_tag Some text for it
+      *some_tag_method( CONSTANT, "string", 1234.3 ) Woot!
+
+      p
+        ' Some text with <bold>bold text</bold>
+
+      <p attr="something">
+        ' Some other text with #{interp}
+
+
+      javascript:
+        var foo = 23;
+        function bar( lel ) {
+          return lel * 4;
+        }
+
+      / And this is a \
+        wrapping comment
+      / And a
+        p non-wrapping one
+
+      /[if IE]
+        p Get a better browser
+
+      a href='http://google.com/' To Google!
+
+      css:
+        p {
+          font-family: #{font_family( "Tahoma" ) && Time.now};
+        }
+
+      == yield
+
+      - unless items.empty?
+        table
+          - for item in items do
+            tr
+              td.name = item.name
+              td.price = item.price
+      - else
+        p<
+         | No items found.  Please add some inventory.
+           Thank you! a href="lol"
+           a lol
+         a lol
+
+
+      coffee:
+        square = (x) -> x * x
+
+      markdown:
+        - Hello from #{SomeClass.interpolation_works!}
+
+    div id="footer"
+      = 3.times { render 'footer' }
+      | Copyright © #{year} #{author}
diff --git a/app/server/vendor/rouge/spec/visual/samples/smalltalk b/app/server/vendor/rouge/spec/visual/samples/smalltalk
new file mode 100755
index 0000000..ca02862
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/smalltalk
@@ -0,0 +1,251 @@
+"======================================================================
+|
+|   Python-like Generators
+|
+|
+ ======================================================================"
+
+
+"======================================================================
+|
+| Copyright 2003 Free Software Foundation, Inc.
+| Written by Paolo Bonzini.
+|
+| This file is part of GNU Smalltalk.
+|
+| GNU Smalltalk is free software; you can redistribute it and/or modify it
+| under the terms of the GNU General Public License as published by the Free
+| Software Foundation; either version 2, or (at your option) any later version.
+| 
+| GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
+| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+| FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+| details.
+| 
+| You should have received a copy of the GNU General Public License along with
+| GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
+| Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  
+|
+ ======================================================================"
+
+Stream subclass: #Generator
+	  instanceVariableNames: 'next topContext bottomContext contexts suspendedContext atEnd'
+	  classVariableNames: ''
+	  poolDictionaries: ''
+	  category: 'Streams-Generators'
+!
+
+Generator comment:
+'A Generator object provides a way to define a Generator method: such
+a method does not return a single value, instead it returns an object
+(the Generator) that uses a Stream interface to access multiple
+return values.  The return values are computed one at a time, as
+needed, and hence need not even be finite.
+
+A generator methods starts by creating a Generator object with
+"Generator new" and saving it into a temporary variable.  As soon as
+this is executed, even though it is not apparent, the method exits
+returning the newly created Generator.  As soon as a message like
+#next, #peek, #atEnd or #peekFor: is sent to the generator, execution
+of the method that created it resumes and goes on until the
+generator''s #yield: method is called: then the argument of #yield:
+will be the Generator''s next element.  If the generator method goes
+on to the end without calling #yield:, the Generator will produce no
+more elements and #atEnd will return true.
+
+Alternatively, a generator block can be converted to a Generator with
+"Generator on: [...]".  The Generator itself is passed to the block
+and, again, the block starts its execution when a message like
+#next, #peek, #atEnd or #peekFor: is sent to the generator.  Again,
+the block''s execution is temporarily suspended when the
+generator''s #yield: method is called.
+
+Returning a value from the generator method makes no sense at least
+after "Generator new" is invoked.  Before, you can use it to return a
+different kind of Stream, or nil, or whatever else; after, the value
+returned will not matter and the return will put an end to the
+Generator''s production of elements.
+
+You could achieve the effect of generators manually by writing your
+own class and storing all the local variables of the generator as
+instance variables.  For example, returning a list of integers could
+be done by setting a variable to 0, and having the #next method
+increment it and return it.  However, for a moderately complicated
+generator, writing a corresponding class would be much messier (and
+might lead to code duplication or inefficiency if you want to support
+#peek, #peekFor: and/or #atEnd): in general, providing a #do:-like
+interface is easy, but not providing a Stream-like one (think binary
+trees).
+
+The idea of generators comes from other programming languages, in
+particular this interface looks much like Scheme streams and Python
+generators.  But Python in turn mutuated the idea for example from
+Icon, where the idea of generators is central.  In Icon, every
+expression and function call behaves like a generator, and if a
+statement manages scalars, it automatically uses up all the results
+that the corresponding generator provides; on the other hand, Icon
+does not represent generators as first-class objects like Python and
+Smalltalk do.'!
+
+!Generator class methodsFor: 'instance creation'!
+
+new
+    "Return a generator, and also suspend the execution of the
+     sender by returning the new generator to the method that
+     invoked the sender.  More easily seen by looking at an
+     example:
+
+     Integer>>evenNumbersUpTo: n
+         | gen |
+         gen := Generator new.
+         self to: n do: [ :each |
+             each even ifTrue: [ gen yield: each ]
+         ]
+
+     Although there is no return statement in the method, evaluating
+     it returns a Generator for the even numbers between the receiver
+     and the argument."
+    ^super new
+	context: thisContext parentContext
+!
+
+on: aBlock
+    | gen |
+    gen := self new.
+    aBlock value: gen.
+! !
+
+!Generator methodsFor: 'stream protocol'!
+
+atEnd
+    "Answer whether more data can be generated."
+    atEnd isNil ifTrue: [ self generateNext ].
+    ^atEnd
+!
+
+next
+    "Evaluate the generator until it generates the next value or
+     decides that nothing else can be generated."
+    | result |
+    self atEnd ifTrue: [ ^self pastEnd ].
+    atEnd := nil.
+    result := next.
+    next := nil.
+    ^result
+!
+
+peek
+    "Evaluate the generator until it generates the next value or
+     decides that nothing else can be generated, and save the value
+     so that #peek or #next will return it again."
+    self atEnd ifTrue: [ ^nil ].
+    ^next
+!
+
+peekFor: anObject
+    "Evaluate the generator until it generates the next value or
+     decides that nothing else can be generated, and if it is not equal
+     to anObject, save the value so that #peek or #next will return it
+     again."
+    self atEnd ifTrue: [ self pastEnd. ^false ].
+    ^next = anObject
+        ifTrue: [ next := nil. atEnd := nil. true ]
+        ifFalse: [ false ]
+! !
+
+!Generator methodsFor: 'private - continuations'!
+
+context: aContext
+    "Initialize the state of the generator.  Its execution will
+     resume from the context, aContext.  Then return the generator
+     itself to the sender of aContext: this method is called by
+     Generator class>>#new, and this has the side effect of
+     returning the Generator from the sender."
+    contexts := OrderedCollection new.
+    topContext := bottomContext := aContext.
+    bottomContext parentContext continue: self
+!
+
+yield: anObject
+    "Save the object returned by the continuation in the next
+     instance variable, then save the execution state of the
+     continuation in topContext, bottomContext and contexts.
+     This is because resuming execution in #invokeGenerator
+     will cause returned blocks to be marked as non-returnable,
+     and we want to preserve the chain."
+    next := anObject.
+    atEnd := false.
+    topContext := bottomContext := thisContext parentContext.
+    [
+	contexts addLast: bottomContext.
+	bottomContext parentContext == suspendedContext
+    ] whileFalse: [
+	bottomContext := bottomContext parentContext.
+    ].
+    suspendedContext continue: self.
+!
+
+generateNext
+    "Invoke the continuation via #invokeGenerator,
+     then resume execution when #yield: is invoked.  Then,
+     use the information in the contexts instance variable
+     to reconstruct the continuation's chain of contexts."
+    | ctx |
+    self invokeGenerator.
+    ctx := topContext.
+    [ contexts isEmpty ] whileFalse: [
+	ctx parentContext: contexts removeFirst.
+	ctx := ctx parentContext.
+    ].
+!
+
+invokeGenerator
+    "This swizzles the contexts, inserting the execution state of
+     the continuation between the #invokeGenerator context and
+     the #generateNext context, then starts evaluating the code
+     in the continuation."
+
+    atEnd := true.
+    suspendedContext := thisContext parentContext.
+    bottomContext parentContext: suspendedContext.
+    thisContext parentContext: topContext.
+! !
+
+!Integer methodsFor: 'examples of generators'!
+
+generatorForGeneratorExample
+    | gen |
+    gen := Generator new.
+    'Entering gen' displayNl.
+    1 to: self do: [ :each |
+	('Yielding ', each printString, '... ') display.
+	gen yield: each.
+	'Resuming gen' displayNl
+    ]!
+
+generatorBlockExample
+    ^Generator on: [ :gen |
+        'Entering gen' displayNl.
+        1 to: self do: [ :each |
+	    ('Yielding ', each printString, '... ') display.
+	    gen yield: each.
+	    'Resuming gen' displayNl
+        ] ]!
+
+generatorExample: gen
+    | n |
+    ('Running on ', gen printString) displayNl.
+    [
+	'Calling next... ' display.
+	n := gen next.
+	n notNil
+    ] whileTrue: [
+	('Got ', n printString) displayNl
+    ]! !
+
+10 generatorExample: 10 generatorForGeneratorExample!
+Eval [
+    Smalltalk byteCodeCounter printNl.
+    10 generatorExample: 10 generatorBlockExample.
+    Smalltalk byteCodeCounter printNl
+]
diff --git a/app/server/vendor/rouge/spec/visual/samples/sml b/app/server/vendor/rouge/spec/visual/samples/sml
new file mode 100755
index 0000000..31db47d
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/sml
@@ -0,0 +1,156 @@
+structure C = struct
+   val a = 12
+   fun f x = x + 5
+end
+
+(*(*(*(*(* This file is all pretty strange Standard ML *)*)*)*) (**)*)
+(* Robert J. Simmons *)
+
+(* Comments (* can be nested *) *)
+structure S = struct
+  val x = (1, 2, "three")
+end
+
+structure Sv = struct
+  (* These look good *)
+  val x = (1, 2, "three")
+  val z = #2 x
+
+  (* Although these look bad (not all the numbers are constants),       *
+   * they never occur in practice, as they are equivalent to the above. *)
+  val x = {1 = 1, 3 = "three", 2 = 2}
+  val z = #
+            2 x
+
+  val || = 12
+end
+
+signature S = sig end
+
+structure S = struct
+  val x = (1, 2, "three")
+  datatype 'a t = T of 'a
+       and u = U of v * v
+  withtype v = {left: int t, right: int t}
+  exception E1 of int and E2
+  fun 'a id (x: 'a) : 'a = x
+
+  val 
+      'a id = fn (x : 'a) => x
+end
+
+signature R = sig
+  type t
+  val x : t
+  val f : t * int -> int
+end
+structure R : R = struct
+  datatype t = T of int
+  val x : t = T 0
+  fun f (T x, i : int) : int = x + i
+  fun 'a id (x: 'a) : 'a = x
+end
+
+signature BA_Z = sig 
+   val s: int
+   include S R
+end 
+
+structure b______ = struct (* What (* A * strange * name *) for ) a ( struct *)
+
+val !%&$#+-/:<=>?@\~`^|* = 3
+
+type struct' = int list
+and 'a sig' = 'a list
+and ('a, 'b) end' = 'b option * 'a list
+
+structure baz = struct
+  structure Bar = struct 
+    val foo = !%&$#+-/:<=>?@\~`^|*
+  end  
+end
+
+infixr +!+ 
+fun (a +!+ b) = (op +) (a, b)
+
+open baz S R
+
+val$$$ = fn x => fn y => fn z => fn w => w
+val (foo, ++, bar, ||) = (4, baz.Bar.foo, !%&$#+-/:<=>?@\~`^|*, Bar.foo)
+val _ = $$$foo++bar||
+
+val val'ue : ' list = []
+val struct3 : (' -> ') = fn x => x
+val end_struct_' : ('a -> 'a) = fn x => x
+val x : (''a -> ''a) = fn x => x
+val x : ('''' -> '''') = fn x => x
+val x : unit = print "Weird, huh?\n"
+val w = {x=1,y=2,##= =3,4=3}
+val {##=, x, 4=a,...} = w
+val z = #4 w
+val z = # ##= w
+
+fun f x y 0 = 4 
+  | f x y z = 4 + Sv.||
+
+exception Foo of int
+datatype ('0, 'b, '_, ') f'o'o = Bar | baZ12' | dsfa_fad | #@$ | Bug
+and (', ''', '''', ''''') bar = 
+   Bee of unit
+ | Ben of (', ''', '''', ''''') f'o'o * int
+ | X of ''' list
+
+fun q x = raise Foo x
+and h x = raise Foo (~x)
+
+val x = 4
+and y = 5
+
+fun q 0 = 4
+  | q 1 = (case 1 of 1 => 2 | 3 => 4 | x => y)
+  | q y = case y of 1 => 2 | 3 => 4 | x => y
+
+val x = ref true
+fun q 0 = 4
+  | q 1 = if false then case 1 of 1 => 2 | 3 => 4 | x => y else 19
+  | q 2 = (while !x handle Match => !x | Fail _ => !x do () ; 2)
+  | q x = (raise Match) handle Domain => 9 | Match => 3
+
+fun p 0 = 12
+  | p 1 = 8
+  | p 2 = r false
+  | p x = r true
+and r true = 19
+  | r false = 12
+
+val _ = 123
+val _ = 0001
+val _ = ~123
+val _ = ~0001
+val _ = 0w12412
+val _ = 0w12412
+val _ = 0xfA0
+val _ = ~0xfA0
+val _ = 0wxfA0
+val _ = 1.4
+val _ = ~1.4
+val _ = 1e~2
+val _ = 1E~2
+val _ = 1e2
+val _ = 1E2
+val _ = 1.4e~2
+val _ = 1.4E~2
+val _ = 1.4e2
+val _ = 1.4E2
+
+val c = #"\000"
+val st = "foo \
+ 	 \ bar" ^ "baz \        
+  	 \ and \ 
+   	 \ such\n"
+
+val () = print st
+
+val _ = foo::bar::4::[++]
+
+end
diff --git a/app/server/vendor/rouge/spec/visual/samples/sql b/app/server/vendor/rouge/spec/visual/samples/sql
new file mode 100755
index 0000000..e06972f
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/sql
@@ -0,0 +1,5 @@
+SELECT e.first_name, e.last_name, d.department_name
+FROM   employees e
+JOIN   departments d ON e.department_id = d.department_id;
+
+update `table` set name='abc' where xyz is null;
diff --git a/app/server/vendor/rouge/spec/visual/samples/swift b/app/server/vendor/rouge/spec/visual/samples/swift
new file mode 100755
index 0000000..aa36ae0
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/swift
@@ -0,0 +1,241 @@
+import Foundation
+
+func sayHello(person:String) -> String {
+    return "Hello, \(capitalize(word:person)). \"How're are you doin\'?\""
+}
+
+func capitalize(#word:String) -> String {
+    //TODO: test this
+    return word.capitalizedString
+}
+
+sayHello("Toto")
+
+var pi = 3.1415
+
+func halfOpenRangeLength(start:Int, end:Int) -> Int {
+    return end - start
+}
+
+halfOpenRangeLength(3, 8)
+
+func count(string:String) -> (vowels:Int, consonants:Int, others:Int) {
+    var vowels = 0, consonants = 0, emoji = 0, whitespace = 0, others = 0
+
+    for character in string {
+
+        switch String(character).lowercaseString {
+        case "a","o","i","u","e":
+            ++vowels
+        case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
+            ++consonants
+        //TODO: Add more emoji
+        case "\u{1F604}":
+            ++emoji
+        case "\n", "\r", "\t", "\0", "\u{A0}", "\u{205F}":
+            ++whitespace
+        default:
+            ++others
+        }
+    }
+
+    return (vowels,consonants,others)
+}
+
+count(sayHello("John"))
+
+// Unicode and Emoji support
+let 😄face = "Happy Face"
+let ქართულადაც = "This is Georgian"
+let こんにちは = "...and Japanese"
+let ð“‚€ = "and hieroglyphs"
+
+
+func join(#firstString:String,#secondString:String,joiner:String = " & ") -> String {
+    return "\(firstString)\(joiner)\(secondString)"
+}
+
+join(firstString: "Toto", secondString: "Someone Other", joiner: " + ")
+
+func alignedRight(inout #string:String, count:Int, pad:Character) -> String {
+    let amountToPad = count - countElements(string)
+
+    for _ in 1...amountToPad {
+        string = pad + string
+    }
+
+    return string;
+}
+
+/* This is a multiline comment
+/*
+This part is nested into the parent comment
+*/
+Trailing part of parent comment
+*/
+
+let thisIsNotAComment = true
+
+/* Singleline Comment */
+
+var textToAlign = "Toto"
+alignedRight(string: &textToAlign, 10, "-")
+textToAlign
+
+//MARK: Function Types
+func addToInts(a:Int,b:Int) -> Int {
+    return a + b
+}
+
+let addNumbers: (Int,Int)->(Int) = addToInts;
+addNumbers(3,2)
+
+func printMathProblem(mathFunction:(Int,Int)->Int,a:Int,b:Int)->String {
+    return "Result " + String(mathFunction(a,b))
+}
+printMathProblem(addNumbers, 5, 10)
+
+// Function return types + Nested Functions
+func chooseSteperFunction(backward:Bool) -> (Int) -> Int {
+    func stepForward(input:Int)->Int {
+        return input + 1
+    }
+
+    func stepBackward(input:Int)->Int {
+        return input + 1
+    }
+
+    return backward ? stepBackward : stepForward
+}
+let currentValue = 5
+chooseSteperFunction(currentValue > 0)(currentValue)
+
+// Closures
+func comparator(s1:String,s2:String)->Bool {
+    return s2 > s1
+}
+let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
+let revised = sorted(names, comparator)
+
+let revised2 = sorted(names, {
+    (s1:String,s2:String)->Bool in
+        return s2 > s1
+    })
+
+let revised3 = sorted(names, { s1, s2 in s1 > s2 })
+revised3
+
+let revised4 = sorted(names) { $0 > $1 } // This is also a trailing closure
+revised4
+
+let revised5 = sorted(names, >)
+
+// Long closures
+let digitNames = [
+    0: "Zero", 1: "One", 2: "Two",   3: "Three", 4: "Four",
+    5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
+]
+let numbers = [16, 58, 510]
+
+let strings = numbers.map {
+    (var number) -> String in
+    var output = ""
+    while number > 0 {
+        output = digitNames[number % 10]! + output
+        number /= 10
+    }
+    return output
+}
+strings
+
+// Closure Value Capturing
+func makeIncrementor(firstNumber number:Int) -> () -> Int
+{
+    var runningTotal = 0
+    func incrementor()->Int {
+        runningTotal += number
+        return runningTotal
+    }
+    return incrementor
+}
+
+let incrementor = makeIncrementor(firstNumber: 4)
+incrementor()
+
+// @autoclosure
+func simpleAssert(condition: @autoclosure () -> Bool, message: String = "Assertion failed") {
+    if !condition() {
+        println(message)
+    }
+}
+
+// optional function call
+
+let maybeFunction: (() -> ())? = nil
+maybeFunction?()
+maybeFunction!()
+
+//MARK: Classes
+public class Person : NSObject {
+    let firstName: String
+
+    private var lastName: String
+
+    private(set) var age: Int {
+    didSet {
+        println("Happy Birthday")
+    }
+    }
+
+    internal(set) var doubleAge = 0.0
+    unowned(safe) var safeUnowned = nil
+    unowned(unsafe) var unsafeUnowned = nil
+
+    lazy var phoneNumbers = [String]()
+    @NSCopying var modificationDate: NSDate = NSDate()
+
+    required public init(name: String, age: Int) {
+        self.name = name
+        self.age = age
+        super.init()
+    }
+
+    internal var isAdmin: Bool { return false }
+
+    final func doSomething() {
+        //TODO: Do something
+    }
+
+    dynamic func somethingDynamic() { }
+}
+
+ at objc(MYCustomView) class CustomView: NSView, SomeProtocol , OtherProtocol {
+    @IBOutlet var button: AnyObject!
+
+    @IBAction func doSomething(sender: AnyObject) {
+        //TODO: Do something
+    }
+}
+
+//MARK: Protocols
+ at objc protocol Random {
+    func random() -> Self
+    optional func seed(seed: Int)
+}
+
+extension SomeClass {
+
+}
+
+struct Stack<T, U>: Equatable {
+    var items = [T]()
+}
+
+typealias Speed = Double
+
+enum State: Equatable {
+    case Stopped, Paused
+    case Running(Speed)
+}
+
+ at availability(OSX, introduced=10.10) func localizedCaseInsensitiveContainsString(aString: String) -> Bool
diff --git a/app/server/vendor/rouge/spec/visual/samples/tcl b/app/server/vendor/rouge/spec/visual/samples/tcl
new file mode 100755
index 0000000..76b684f
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/tcl
@@ -0,0 +1,325 @@
+# taken from jimtcl:tests/parse.test
+
+source [file dirname [info script]]/testing.tcl
+
+test parse-1.1 "Quoted closing bracket" {
+	set x [string length "]"]
+} {1}
+
+test parse-1.2 "Quoted opening bracket" {
+	set x [string length "\["]
+} {1}
+
+test parse-1.3 "Quoted open brace" {
+	set x [string length "\{"]
+} {1}
+
+test parse-1.4 "Quoted open brace via var" {
+	set lb \{
+	set x [string length "$lb"]
+} {1}
+
+test parse-1.5 "Braced bracket" {
+	set x [string length {]}]
+} {1}
+
+test parse-1.6 "Dict sugar" -body {
+    unset -nocomplain a
+    array set a {a 1 b 2 c 3}
+    set x $a(
+} -returnCodes error -match glob -result "*"
+
+test parse-1.8 "Dict sugar" {
+    unset -nocomplain a
+    array set a {a 1 b 2 c 3}
+    set x $a([set y b])
+} 2
+
+test parse-1.9 "Backslash newline" {
+	set x 123;\
+	set y 456
+	list $x $y
+} {123 456}
+
+test parse-1.10 "Backslash newline in quotes" {
+	set x "abc\
+def"
+} "abc def"
+
+test parse-1.11 "Backslash newline in quotes after var" {
+	set y 1
+	set x "abc$y\
+def"
+} "abc1 def"
+
+test parse-1.12 "Backslash newline in quotes after var" {
+	set y 1
+	set x "abc$y\
+def"
+} "abc1 def"
+
+test parse-1.13 "Newline in quotes" {
+	set y 1
+	set x "abc
+def"
+} "abc\ndef"
+
+test parse-1.14 "Newline in quotes after var" {
+	set y 1
+	set x "abc$y
+def"
+} "abc1\ndef"
+
+test parse-1.15 "Space in quotes" {
+	set y 1
+	set x "abc def"
+} "abc def"
+
+test parse-1.16 "Space in quotes after var" {
+	set y 1
+	set x "abc${y} def"
+} "abc1 def"
+
+test parse-1.17 "Command and var in quotes" {
+	set y 1
+	set x "[set z 2][set y]"
+} 21
+
+test parse-1.18 "Command and var in bare context" {
+	set y 1
+	set x [set z 2][set y]
+} 21
+
+test parse-1.19 "Lone dollar sign in quotes" {
+	set y 1
+	set x "6$[set y]"
+} 6\$1
+
+test parse-1.20 "Command and var in bare context" {
+	set y 1
+	set x 6$[set y]
+} 6\$1
+
+test parse-1.21 "Comment" {
+	set y 1
+# A comment one a line
+	set x [set y] ;# comment after semicolon
+} 1
+
+test parse-1.22 "# char" {
+	set y 1
+	append y #
+	set x "[set y]#"
+} {1##}
+
+test parse-1.23 "newline in command" {
+	set y 1
+	set z 2
+	set x [incr y
+	incr z]
+	list $x $y $z
+} {3 2 3}
+
+test parse-1.24 "semicolon in command" {
+	set x [list a; list b c; list d e f]
+} {d e f}
+
+# Note that Tcl complains about the missing brace here
+# while Jim ignores it
+test parse-1.25 "missing brace in var" jim {
+	unset -nocomplain a
+	set a 3
+	set brace \{
+	set x [subst \$${brace}a]
+} 3
+
+test parse-1.26 "newline in braced var" {
+	set "a\nb" var1
+	set x ${a
+b}
+} var1
+
+test parse-1.27 "backslash escape in dict sugar" {
+	unset -nocomplain a
+	set a(b\x55d) 5
+	set x $a(b\x55d)
+} 5
+
+test parse-1.28 "nested dict sugar" {
+	unset -nocomplain a b
+	set a(V) 5
+	set b(5) five
+	set x $b($a(V))
+} five
+
+set dq {"}
+set script "set x ${dq}hello"
+
+test parse-1.29 "missing quote" jim {
+	eval $script
+} hello
+
+test parse-1.30 "missing quote" {
+	info complete $script
+} 0
+
+test parse-1.31 "backslash newline in bare context" {
+	list abc\
+	123
+} {abc 123}
+
+test parse-1.32 "comment as last line of script" {
+	set script {set x 3; # this is a comment}
+	eval $script
+} 3
+
+test parse-1.33 "upper case hex escapes" {
+	list \x4A \x4F \x3C
+} {J O <}
+
+test parse-1.34 "octal escapes" {
+	list \112 \117 \074
+} {J O <}
+
+test parse-1.35 "invalid hex escape" {
+	list \xZZ
+} xZZ
+
+test parse-1.36 "unicode escape" jim {
+	list \u00b5
+} \xc2\xb5
+
+test parse-1.37 "invalid unicode escape after unicode" jim {
+	list \ub5x
+} \xc2\xb5x
+
+test parse-1.38 "invalid unicode escape" {
+	list \ux
+} ux
+
+test parse-1.39 "octal escape followed by invalid" {
+	list \76x
+} >x
+
+test parse-1.40 "list containing quoted trailing backslash" jim {
+	set x "abc \"def\\"
+	lindex $x 1
+} def\\
+
+test parse-1.41 "list containing quoted newline" {
+	set x {abc "def
+ghi"}
+	lindex $x 1
+} def\nghi
+
+test parse-1.42 "list containing missing quote" jim {
+	set x {abc "def}
+	lindex $x 1
+} def
+
+test parse-1.43 "list containing trailing backslash" {
+	set x "abc def\\"
+	lindex $x 1
+} def\\
+
+test parse-1.44 "list creation" {
+	list "a{ }d"
+} {{a{ }d}}
+
+test parse-1.45 "spaces before expr function args" {
+	expr {round  (3.2)}
+} 3
+
+test parse-1.46 "expr function missing paren" {
+	catch {expr {round 3.2}}
+} 1
+
+test parse-1.47 "backslash newline in quotes" {
+	# spaces
+	set x "abc\
+      def"
+} "abc def"
+
+test parse-1.48 "backslash newline in quotes" {
+	# tabs
+	set x "abc\
+		def"
+} "abc def"
+
+test parse-1.49 "backslash newline in quotes" {
+	# tabs plus newline
+	set x "abc\
+
+def"
+} "abc \ndef"
+
+test parse-1.50 "backslash newline in quotes" {
+	# tabs plus newline
+	set x "abc\
+def"
+} "abc def"
+
+test parse-1.51 "special chars in dict sugar" {
+	unset -nocomplain a
+	set a(x$) 5
+	array names a
+} {{x$}}
+
+test parse-1.52 "special chars in dict sugar" {
+	set x $a(x$)
+} 5
+
+test parse-1.53 "special chars in dict sugar" {
+	unset -nocomplain a
+	set a(x\[) 5
+	array names a
+} {{x[}}
+
+test parse-1.54 "special chars in dict sugar" {
+	set x $a(x\[)
+} 5
+
+test parse-1.55 "special chars in dict sugar" {
+	unset -nocomplain a
+	set a(x\() 5
+	array names a
+} {x(}
+
+test parse-1.56 "special chars in dict sugar" {
+	set x $a(x\()
+} 5
+
+test parse-1.57 "special chars in dict sugar" {
+	unset -nocomplain a
+	set a(x() 5
+	array names a
+} {x(}
+
+test parse-1.58 "special chars in dict sugar" {
+	set x $a(x()
+} 5
+
+test parse-1.59 "special chars in dict sugar" {
+	unset -nocomplain a
+	set a(x") 5
+	lindex [array names a] 0
+} {x"}
+
+test parse-1.60 "special chars in dict sugar" {
+	set x $a(x")
+} 5
+
+test parse-1.61 "quote in command" {
+	set x [list \\" x]
+	lindex $x end
+} x
+
+test parse-1.62 "quoted orphan dollar sign" {
+	set x "x$"
+} {x$}
+
+test parse-1.63 "unquoted dollar sign" {
+	set x x$
+} {x$}
+
+testreport
diff --git a/app/server/vendor/rouge/spec/visual/samples/tex b/app/server/vendor/rouge/spec/visual/samples/tex
new file mode 100755
index 0000000..37a140b
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/tex
@@ -0,0 +1,132 @@
+\documentclass{article}
+
+\begin{document}
+
+
+
+\centerline{\sc \large A Simple Sample \LaTeX\ File}
+\vspace{.5pc}
+\centerline{\sc Stupid Stuff I Wish Someone Had Told Me Four Years Ago}
+\centerline{\it (Read the .tex file along with this or it won't 
+            make much sense)}
+\vspace{2pc}
+
+The first thing to realize about \LaTeX\ is that it is not ``WYSIWYG''. 
+In other words, it isn't a word processor; what you type into your 
+.tex file is not what you'll see in your .dvi file.  For example, 
+\LaTeX\ will      completely     ignore               extra
+spaces    within                             a line of your .tex file.
+Pressing return
+in 
+the 
+middle 
+of
+a
+line
+will not register in your .dvi file. However, a double carriage-return
+is read as a paragraph break.
+
+Like this.  But any carriage-returns after the first two will be 
+completely ignored; in other words, you 
+
+
+can't 
+
+add
+
+
+
+
+
+
+more 
+
+
+
+
+space 
+
+
+between 
+
+
+
+
+lines, no matter how many times you press return in your .tex file.
+
+In order to add vertical space you have to use ``vspace''; for example, 
+you could add an inch of space by typing \verb|\vspace{1in}|, like this:
+\vspace{1in}
+
+To get three lines of space you would type \verb|\vspace{3pc}|
+(``pc'' stands for ``pica'', a font-relative size), like this:
+\vspace{3pc}
+
+Notice that \LaTeX\ commands are always preceeded by a backslash.  
+Some commands, like \verb|\vspace|, take arguments (here, a length) in
+curly brackets.  
+
+The second important thing to notice about \LaTeX\ is that you type 
+in various ``environments''...so far we've just been typing regular 
+text (except for a few inescapable usages of \verb|\verb| and the
+centered, smallcaps, large title).  There are basically two ways that 
+you can enter and/or exit an environment;
+\vspace{1pc}
+
+\centerline{this is the first way...}
+
+\begin{center}
+this is the second way.
+\end{center}
+
+\noindent Actually there is one more way, used above; for example, 
+{\sc this way}.  The way that you get in and out of environment varies
+depending on which kind of environment you want; for example, you use 
+\verb|\underline| ``outside'', but \verb|\it| ``inside''; 
+notice \underline{this} versus {\it this}.
+
+The real power of \LaTeX\ (for us) is in the math environment. You 
+push and pop out of the math environment by typing \verb|$|. For 
+example, $2x^3 - 1 = 5$ is typed between dollar signs as
+\verb|$2x^3 - 1 = 5$|. Perhaps a more interesting example is
+$\lim_{N \to \infty} \sum_{k=1}^N f(t_k) \Delta t$.
+
+You can get a fancier, display-style math 
+environment by enclosing your equation with double dollar signs.  
+This will center your equation, and display sub- and super-scripts in 
+a more readable fashion:
+
+$$\lim_{N \to \infty} \sum_{k=1}^N f(t_k) \Delta t.$$
+
+If you don't want your equation to be centered, but you want the nice 
+indicies and all that, you can use \verb|\displaystyle| and get your 
+formula ``in-line''; using our example this is 
+$\displaystyle \lim_{N \to \infty} \sum_{k=1}^N f(t_k) \Delta t.$  Of 
+course this can screw up your line spacing a little bit.
+
+There are many more things to know about \LaTeX\ and we can't 
+possibly talk about them all here.
+You can use \LaTeX\ to get tables, commutative diagrams, figures, 
+aligned equations, cross-references, labels, matrices, and all manner 
+of strange things into your documents.  You can control margins, 
+spacing, alignment, {\it et cetera} to higher degrees of accuracy than 
+the human eye can percieve.  You can waste entire days typesetting 
+documents to be ``just so''.  In short, \LaTeX\ rules.
+
+The best way to learn \LaTeX\ is by example. Get yourself a bunch
+of .tex files, see what kind of output they produce, and figure out how
+to modify them to do what you want.  There are many template and 
+sample files on the department \LaTeX\ page and in real life in the 
+big binder that should be in the computer lab somewhere.  Good luck!
+
+
+
+
+
+
+
+
+
+
+
+\end{document}
diff --git a/app/server/vendor/rouge/spec/visual/samples/toml b/app/server/vendor/rouge/spec/visual/samples/toml
new file mode 100755
index 0000000..0ec5680
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/toml
@@ -0,0 +1,64 @@
+# This is a TOML document. Boom.
+
+title = "TOML Example"
+
+[owner]
+name = "Tom Preston-Werner"
+organization = "GitHub"
+bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
+dob = 1979-05-27T07:32:00Z # First class dates? Why not?
+
+[database]
+server = "192.168.1.1"
+ports = [ 8001, 8001, 8002 ]
+connection_max = 5000
+enabled = true
+
+[servers]
+
+  # You can indent as you please. Tabs or spaces. TOML don't care.
+  [servers.alpha]
+  ip = "10.0.0.1"
+  dc = "eqdc10"
+
+  [servers.beta]
+  ip = "10.0.0.2"
+  dc = "eqdc10"
+
+[clients]
+data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it
+
+# Line breaks are OK when inside arrays
+hosts = [
+  "alpha",
+  "omega"
+]
+
+funky = "I'm a string. \"You can quote me\". Tab \t newline \n you get it."
+right = "C:\\Users\\nodejs\\templates"
+wrong = "C:\Users\nodejs\templates" # note: doesn't produce a valid path
+
+# Test file for TOML
+# Only this one tries to emulate a TOML file written by a user of the kind of parser writers probably hate
+# This part you'll really hate
+
+[the]
+test_string = "You'll hate me after this - #"          # " Annoying, isn't it?
+
+    [the.hard]
+    test_array = [ "] ", " # "]      # ] There you go, parse this!
+    test_array2 = [ "Test #11 ]proved that", "Experiment #9 was a success" ]
+    # You didn't think it'd as easy as chucking out the last #, did you?
+    another_test_string = " Same thing, but with a string #"
+    harder_test_string = " And when \"'s are in the string, along with # \""   # "and comments are there too"
+    # Things will get harder
+    
+        [the.hard.bit#]
+        what? = "You don't think some user won't do that?"
+        multi_line_array = [
+            "]",
+            "Oi!\n",
+            # ] Oh yes I did
+            ]
+
+東京都 = 123
diff --git a/app/server/vendor/rouge/spec/visual/samples/vb b/app/server/vendor/rouge/spec/visual/samples/vb
new file mode 100755
index 0000000..e7252e9
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/vb
@@ -0,0 +1,407 @@
+' Copyright (c) 2008 Silken Web - Free BSD License
+' All rights reserved.
+'
+' Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+' * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer
+' * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+' * Neither the name of Silken Web nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+'
+' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+' THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+' BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+' GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+' LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+' DAMAGE.
+
+Imports System.Net.Mail
+Imports SilkenWeb.Entities
+Imports System.Text.RegularExpressions
+Imports System.Reflection
+Imports SilkenWeb.Validation
+Imports System.Globalization
+Imports SilkenWeb.Reflection
+
+Namespace SilkenWeb
+
+    ''' <summary>
+    ''' Represents an Email and what you can do with it.
+    ''' </summary>
+    ''' <remarks>
+    ''' Keith Jackson
+    ''' 11/04/2008
+    '''
+    ''' This class is intended to be inherrited for providing all manner of system generated emails, each represented by it's own class.
+    ''' </remarks>
+    Public MustInherit Class EmailBase : Implements IValidatable, IDisposable
+
+#Region " Constants "
+
+        Public Const LenientRegexPattern As String = "\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
+        Public Const StrictRegexPattern As String = "^(([^<>()[\]\\.,;:\s@\""]+(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$"
+        Public Const InvalidEmailAddressError As String = "The Email address provided was invalid"
+        Public Const InvalidEmailAddressErrorWithAddress As String = "The Email address, {0}, provided was invalid"
+        Public Const NullEmailAddressError As String = "The Email address was not provided"
+
+#End Region
+
+#Region " Fields "
+
+        Private disposedValue As Boolean
+
+        Private _message As MailMessage = New MailMessage()
+        Private _mailClient As SmtpClient
+
+        Private _useStrictValidation As Boolean
+
+#End Region
+
+#Region " Construction "
+
+        ''' <summary>
+        ''' Instantiates a new Email of the derived type.
+        ''' </summary>
+        ''' <param name="sender">The email address of the sender of the message.</param>
+        ''' <param name="recipients">The email addresses of the recipients of the message.</param>
+        ''' <param name="subject">The subject of the message.</param>
+        ''' <param name="body">The body of the message.</param>
+        Protected Sub New(ByVal sender As String, ByVal subject As String, ByVal body As String, ByVal ParamArray recipients As String())
+            _message.From = New MailAddress(sender)
+            For i As Integer = 0 To recipients.Length - 1
+                _message.To.Add(recipients(i))
+            Next
+            _message.Subject = subject
+            _message.Body = body
+        End Sub
+
+#End Region
+
+#Region " Properties "
+
+        ''' <summary>
+        ''' Gets the Attachments for the message.
+        ''' </summary>
+        Protected Overridable ReadOnly Property Attachments() As AttachmentCollection
+            Get
+                Return _message.Attachments
+            End Get
+        End Property
+
+        ''' <summary>
+        ''' The email addresses of the BCC recipients of the message.
+        ''' </summary>
+        Public Property BccRecipients() As String()
+            Get
+                Return _message.Bcc.ToAddressStringArray()
+            End Get
+            Set(ByVal value As String())
+                _message.Bcc.Clear()
+                _message.Bcc.Add(value.ToDelimitedString())
+            End Set
+        End Property
+
+        ''' <summary>
+        ''' The body of the message.
+        ''' </summary>
+        Protected Overridable Property Body() As String
+            Get
+                Return _message.Body
+            End Get
+            Set(ByVal value As String)
+                _message.Body = value
+            End Set
+        End Property
+
+        ''' <summary>
+        ''' The email addresses of the CC recipients of the message.
+        ''' </summary>
+        Public Property CCRecipients() As String()
+            Get
+                Return _message.CC.ToAddressStringArray()
+            End Get
+            Set(ByVal value As String())
+                _message.CC.Clear()
+                _message.CC.Add(value.ToDelimitedString())
+            End Set
+        End Property
+
+        ''' <summary>
+        ''' Gets or Sets a flag to indicate if the body of the message is HTML.
+        ''' </summary>
+        Public Property IsBodyHtml() As Boolean
+            Get
+                Return _message.IsBodyHtml
+            End Get
+            Set(ByVal value As Boolean)
+                _message.IsBodyHtml = value
+            End Set
+        End Property
+
+        ''' <summary>
+        ''' Gets the Mail message wrapped by the EmailBase class.
+        ''' </summary>
+        Protected ReadOnly Property Message() As MailMessage
+            Get
+                Return _message
+            End Get
+        End Property
+
+        ''' <summary>
+        ''' Gets or Sets the Priority of the message.
+        ''' </summary>
+        Public Property Priority() As MailPriority
+            Get
+                Return _message.Priority
+            End Get
+            Set(ByVal value As MailPriority)
+                _message.Priority = value
+            End Set
+        End Property
+
+        ''' <summary>
+        ''' The email addresses of the recipients of the message.
+        ''' </summary>
+        Public Property Recipients() As String()
+            Get
+                Return _message.To.ToAddressStringArray()
+            End Get
+            Set(ByVal value As String())
+                _message.To.Clear()
+                _message.To.Add(value.ToDelimitedString())
+            End Set
+        End Property
+
+        ''' <summary>
+        ''' The reply email address of the sender of the message.
+        ''' </summary>
+        Public Property ReplyTo() As String
+            Get
+                If _message.ReplyTo Is Nothing Then
+                    Return String.Empty
+                Else
+                    Return _message.ReplyTo.Address
+                End If
+            End Get
+            Set(ByVal value As String)
+                If _message.ReplyTo Is Nothing Then
+                    _message.ReplyTo = New MailAddress(value)
+                Else
+                    _message.ReplyTo = New MailAddress(value, _message.ReplyTo.DisplayName)
+                End If
+            End Set
+        End Property
+
+        ''' <summary>
+        ''' The reply display name of the sender of the message.
+        ''' </summary>
+        Public Property ReplyToDisplayName() As String
+            Get
+                If _message.ReplyTo Is Nothing Then
+                    Return String.Empty
+                Else
+                    Return _message.ReplyTo.DisplayName
+                End If
+            End Get
+            Set(ByVal value As String)
+                If _message.ReplyTo Is Nothing Then
+                    _message.ReplyTo = New MailAddress(_message.From.Address, value)
+                Else
+                    _message.ReplyTo = New MailAddress(_message.ReplyTo.Address, value)
+                End If
+            End Set
+        End Property
+
+        ''' <summary>
+        ''' The email address of the sender of the message.
+        ''' </summary>
+        Public Overridable Property Sender() As String
+            Get
+                Return _message.From.Address
+            End Get
+            Protected Set(ByVal value As String)
+                _message.From = New MailAddress(value, _message.From.DisplayName)
+            End Set
+        End Property
+
+        ''' <summary>
+        ''' The display name of the sender of the message.
+        ''' </summary>
+        Public Overridable Property SenderDisplayName() As String
+            Get
+                Return _message.From.DisplayName
+            End Get
+            Protected Set(ByVal value As String)
+                _message.From = New MailAddress(_message.From.Address, value)
+            End Set
+        End Property
+
+        ''' <summary>
+        ''' The subject of the message.
+        ''' </summary>
+        Public Overridable Property Subject() As String
+            Get
+                Return _message.Subject
+            End Get
+            Protected Set(ByVal value As String)
+                _message.Subject = value
+            End Set
+        End Property
+
+#End Region
+
+#Region " Methods "
+
+#Region " Send Methods "
+
+        ''' <summary>
+        ''' Sends this email
+        ''' </summary>
+        ''' <param name="mailServer">The SMTP server to use to send the email.</param>
+        Public Sub Send(ByVal mailServer As String)
+            _mailClient = New SmtpClient(mailServer)
+            _mailClient.Send(_message)
+        End Sub
+
+        ''' <summary>
+        ''' Sends this email asynchronously.
+        ''' </summary>
+        ''' <param name="mailServer">The SMTP server to use to send the email.</param>
+        ''' <param name="userToken">A user defined token passed to the recieving method on completion of the asynchronous task.</param>
+        Public Sub SendAsync(ByVal mailServer As String, ByVal userToken As Object)
+            _mailClient = New SmtpClient(mailServer)
+            _mailClient.SendAsync(_message, userToken)
+        End Sub
+
+        ''' <summary>
+        ''' Cancels an attempt to send this email asynchronously.
+        ''' </summary>
+        Public Sub SendAsyncCancel()
+            _mailClient.SendAsyncCancel()
+        End Sub
+
+#End Region
+
+#End Region
+
+#Region " IValidatable Implementation "
+
+        ''' <summary>
+        ''' gets and Sets a flag to indicate whether to use strict validation.
+        ''' </summary>
+        Public Property UseStrictValidation() As Boolean
+            Get
+                Return _useStrictValidation
+            End Get
+            Set(ByVal value As Boolean)
+                _useStrictValidation = value
+            End Set
+        End Property
+
+        ''' <summary>
+        ''' Validates this email.
+        ''' </summary>
+        ''' <returns>A ValidationResponse, containing a flag to indicate if validation was passed and a collection of Property Names and validation errors.</returns>
+        Public Function Validate() As ValidationResponse Implements IValidatable.Validate
+
+            Dim retVal As New ValidationResponse()
+            Dim mailRegEx As String = If(_useStrictValidation, StrictRegexPattern, LenientRegexPattern)
+
+            ValidateAddress("Sender", retVal, mailRegEx, True)
+            ValidateAddresses("Recipients", retVal, mailRegEx, True)
+            ValidateAddresses("CcRecipients", retVal, mailRegEx)
+            ValidateAddresses("BccRecipients", retVal, mailRegEx)
+            ValidateAddress("ReplyTo", retVal, mailRegEx)
+
+            Return retVal
+
+        End Function
+
+        ''' <summary>
+        ''' Validates a single Email Address property.
+        ''' </summary>
+        ''' <param name="propertyName">The name of the property to validate.</param>
+        ''' <param name="retVal">The validation response object.</param>
+        ''' <param name="mailRegEx">The regular expression pattern to use for validation.</param>
+        Private Overloads Sub ValidateAddress(ByVal propertyName As String, ByRef retVal As ValidationResponse, ByVal mailRegEx As String)
+            ValidateAddress(propertyName, retVal, mailRegEx, False)
+        End Sub
+
+        ''' <summary>
+        ''' Validates a single Email Address property.
+        ''' </summary>
+        ''' <param name="propertyName">The name of the property to validate.</param>
+        ''' <param name="retVal">The validation response object.</param>
+        ''' <param name="mailRegEx">The regular expression pattern to use for validation.</param>
+        ''' <param name="required">Indicates if the address is required; False if not specified.</param>
+        Private Overloads Sub ValidateAddress(ByVal propertyName As String, ByRef retVal As ValidationResponse, ByVal mailRegEx As String, ByVal required As Boolean)
+
+            Dim emailAddress As String = ReflectionHelper.Properties.GetProperty(Of String)(Me, propertyName)
+
+            If emailAddress Is Nothing OrElse emailAddress.Length = 0 Then
+                If required Then retVal.Add(New KeyValuePair(Of String, String)(propertyName, NullEmailAddressError))
+            Else
+                If (Not Regex.IsMatch(emailAddress, mailRegEx)) Then
+                    retVal.Add(New KeyValuePair(Of String, String)(propertyName, InvalidEmailAddressError))
+                End If
+            End If
+
+        End Sub
+
+        ''' <summary>
+        ''' Validates a string array of Email Address property.
+        ''' </summary>
+        ''' <param name="propertyName">The name of the property to validate.</param>
+        ''' <param name="retVal">The validation response object.</param>
+        ''' <param name="mailRegEx">The regular expression pattern to use for validation.</param>
+        Private Overloads Sub ValidateAddresses(ByVal propertyName As String, ByRef retVal As ValidationResponse, ByVal mailRegEx As String)
+            ValidateAddresses(propertyName, retVal, mailRegEx, False)
+        End Sub
+
+        ''' <summary>
+        ''' Validates a string array of Email Address property.
+        ''' </summary>
+        ''' <param name="propertyName">The name of the property to validate.</param>
+        ''' <param name="retVal">The validation response object.</param>
+        ''' <param name="mailRegEx">The regular expression pattern to use for validation.</param>
+        ''' <param name="required">Indicates if the address is required; False if not specified.</param>
+        Private Overloads Sub ValidateAddresses(ByVal propertyName As String, ByRef retVal As ValidationResponse, ByVal mailRegEx As String, ByVal required As Boolean)
+
+            Dim emailAddresses() As String = ReflectionHelper.Properties.GetProperty(Of String())(Me, propertyName)
+
+            If emailAddresses Is Nothing OrElse emailAddresses.Length = 0 Then
+                If required Then retVal.Add(New KeyValuePair(Of String, String)(propertyName, String.Format(CultureInfo.CurrentCulture, NullEmailAddressError)))
+            Else
+                For i As Integer = 0 To emailAddresses.Length - 1
+                    If (Not Regex.IsMatch(emailAddresses(i), mailRegEx)) Then
+                        retVal.Add(New KeyValuePair(Of String, String)(propertyName, String.Format(CultureInfo.CurrentCulture, InvalidEmailAddressErrorWithAddress, emailAddresses(i))))
+                    End If
+                Next
+            End If
+
+        End Sub
+
+#End Region
+
+#Region " IDisposable Implementation "
+
+        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
+            If Not Me.disposedValue Then
+                If disposing Then
+                    _message.Dispose()
+                End If
+                _mailClient = Nothing
+                _message = Nothing
+            End If
+            Me.disposedValue = True
+        End Sub
+
+        Public Sub Dispose() Implements IDisposable.Dispose
+            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
+            Dispose(True)
+            GC.SuppressFinalize(Me)
+        End Sub
+
+#End Region
+
+    End Class
+
+End Namespace
diff --git a/app/server/vendor/rouge/spec/visual/samples/viml b/app/server/vendor/rouge/spec/visual/samples/viml
new file mode 100755
index 0000000..17d74fd
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/viml
@@ -0,0 +1,567 @@
+" Vim completion script
+" Language:	PHP
+" Maintainer:	Mikolaj Machowski ( mikmach AT wp DOT pl )
+" Last Change:	2006 May 9
+"
+"   TODO:
+"   - Class aware completion:
+"      a) caching?
+"   - Switching to HTML (XML?) completion (SQL) inside of phpStrings
+"   - allow also for XML completion <- better do html_flavor for HTML
+"     completion
+"   - outside of <?php?> getting parent tag may cause problems. Heh, even in
+"     perfect conditions GetLastOpenTag doesn't cooperate... Inside of
+"     phpStrings this can be even a bonus but outside of <?php?> it is not the
+"     best situation
+
+function! phpcomplete#CompletePHP(findstart, base)
+	if a:findstart
+		unlet! b:php_menu
+		" Check if we are inside of PHP markup
+		let pos = getpos('.')
+		let phpbegin = searchpairpos('<?', '', '?>', 'bWn',
+				\ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\|comment"')
+		let phpend   = searchpairpos('<?', '', '?>', 'Wn',
+				\ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\|comment"')
+
+		if phpbegin == [0,0] && phpend == [0,0]
+			" We are outside of any PHP markup. Complete HTML
+			let htmlbegin = htmlcomplete#CompleteTags(1, '')
+			let cursor_col = pos[2]
+			let base = getline('.')[htmlbegin : cursor_col]
+			let b:php_menu = htmlcomplete#CompleteTags(0, base)
+			return htmlbegin
+		else
+			" locate the start of the word
+			let line = getline('.')
+			let start = col('.') - 1
+			let curline = line('.')
+			let compl_begin = col('.') - 2
+			while start >= 0 && line[start - 1] =~ '[a-zA-Z_0-9\x7f-\xff$]'
+				let start -= 1
+			endwhile
+			let b:compl_context = getline('.')[0:compl_begin]
+			return start
+
+			" We can be also inside of phpString with HTML tags. Deal with
+			" it later (time, not lines).
+		endif
+
+	endif
+	" If exists b:php_menu it means completion was already constructed we
+	" don't need to do anything more
+	if exists("b:php_menu")
+		return b:php_menu
+	endif
+	" Initialize base return lists
+	let res = []
+	let res2 = []
+	" a:base is very short - we need context
+	if exists("b:compl_context")
+		let context = b:compl_context
+		unlet! b:compl_context
+	endif
+
+	if !exists('g:php_builtin_functions')
+		call phpcomplete#LoadData()
+	endif
+
+	let scontext = substitute(context, '\$\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*$', '', '')
+
+	if scontext =~ '\(=\s*new\|extends\)\s\+$'
+		" Complete class name
+		" Internal solution for finding classes in current file.
+		let file = getline(1, '$')
+		call filter(file,
+				\ 'v:val =~ "class\\s\\+[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*("')
+		let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+		let jfile = join(file, ' ')
+		let int_values = split(jfile, 'class\s\+')
+		let int_classes = {}
+		for i in int_values
+			let c_name = matchstr(i, '^[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*')
+			if c_name != ''
+				let int_classes[c_name] = ''
+			endif
+		endfor
+
+		" Prepare list of classes from tags file
+		let ext_classes = {}
+		let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+		if fnames != ''
+			exe 'silent! vimgrep /^'.a:base.'.*\tc\(\t\|$\)/j '.fnames
+			let qflist = getqflist()
+			if len(qflist) > 0
+				for field in qflist
+					" [:space:] thing: we don't have to be so strict when
+					" dealing with tags files - entries there were already
+					" checked by ctags.
+					let item = matchstr(field['text'], '^[^[:space:]]\+')
+					let ext_classes[item] = ''
+				endfor
+			endif
+		endif
+
+		" Prepare list of built in classes from g:php_builtin_functions
+		if !exists("g:php_omni_bi_classes")
+			let g:php_omni_bi_classes = {}
+			for i in keys(g:php_builtin_object_functions)
+				let g:php_omni_bi_classes[substitute(i, '::.*$', '', '')] = ''
+			endfor
+		endif
+
+		let classes = sort(keys(int_classes))
+		let classes += sort(keys(ext_classes))
+		let classes += sort(keys(g:php_omni_bi_classes))
+
+		for m in classes
+			if m =~ '^'.a:base
+				call add(res, m)
+			endif
+		endfor
+
+		let final_menu = []
+		for i in res
+			let final_menu += [{'word':i, 'kind':'c'}]
+		endfor
+
+		return final_menu
+
+	elseif scontext =~ '\(->\|::\)$'
+		" Complete user functions and variables
+		" Internal solution for current file.
+		" That seems as unnecessary repeating of functions but there are
+		" few not so subtle differences as not appending of $ and addition
+		" of 'kind' tag (not necessary in regular completion)
+
+		if scontext =~ '->$' && scontext !~ '\$this->$'
+
+			" Get name of the class
+			let classname = phpcomplete#GetClassName(scontext)
+
+			" Get location of class definition, we have to iterate through all
+			" tags files separately because we need relative path from current
+			" file to the exact file (tags file can be in different dir)
+			if classname != ''
+				let classlocation = phpcomplete#GetClassLocation(classname)
+			else
+				let classlocation = ''
+			endif
+
+			if classlocation == 'VIMPHP_BUILTINOBJECT'
+
+				for object in keys(g:php_builtin_object_functions)
+					if object =~ '^'.classname
+						let res += [{'word':substitute(object, '.*::', '', ''),
+							   	\    'info': g:php_builtin_object_functions[object]}]
+					endif
+				endfor
+
+				return res
+
+			endif
+
+			if filereadable(classlocation)
+				let classfile = readfile(classlocation)
+				let classcontent = ''
+				let classcontent .= "\n".phpcomplete#GetClassContents(classfile, classname)
+				let sccontent = split(classcontent, "\n")
+
+				" YES, YES, YES! - we have whole content including extends!
+				" Now we need to get two elements: public functions and public
+				" vars
+				" NO, NO, NO! - third separate filtering looking for content
+				" :(, but all of them have differences. To squeeze them into
+				" one implementation would require many additional arguments
+				" and ifs. No good solution
+				" Functions declared with public keyword or without any
+				" keyword are public
+				let functions = filter(deepcopy(sccontent),
+						\ 'v:val =~ "^\\s*\\(static\\s\\+\\|public\\s\\+\\)*function"')
+				let jfuncs = join(functions, ' ')
+				let sfuncs = split(jfuncs, 'function\s\+')
+				let c_functions = {}
+				for i in sfuncs
+					let f_name = matchstr(i,
+							\ '^&\?\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze')
+					let f_args = matchstr(i,
+							\ '^&\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*(\zs.\{-}\ze)\_s*{')
+					if f_name != ''
+						let c_functions[f_name.'('] = f_args
+					endif
+				endfor
+				" Variables declared with var or with public keyword are
+				" public
+				let variables = filter(deepcopy(sccontent),
+						\ 'v:val =~ "^\\s*\\(public\\|var\\)\\s\\+\\$"')
+				let jvars = join(variables, ' ')
+				let svars = split(jvars, '\$')
+				let c_variables = {}
+				for i in svars
+					let c_var = matchstr(i,
+							\ '^\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze')
+					if c_var != ''
+						let c_variables[c_var] = ''
+					endif
+				endfor
+
+				let all_values = {}
+				call extend(all_values, c_functions)
+				call extend(all_values, c_variables)
+
+				for m in sort(keys(all_values))
+					if m =~ '^'.a:base && m !~ '::'
+						call add(res, m)
+					elseif m =~ '::'.a:base
+						call add(res2, m)
+					endif
+				endfor
+
+				let start_list = res + res2
+
+				let final_list = []
+				for i in start_list
+					if has_key(c_variables, i)
+						let class = ' '
+						if all_values[i] != ''
+							let class = i.' class '
+						endif
+						let final_list +=
+								\ [{'word':i,
+								\   'info':class.all_values[i],
+								\   'kind':'v'}]
+					else
+						let final_list +=
+								\ [{'word':substitute(i, '.*::', '', ''),
+								\   'info':i.all_values[i].')',
+								\   'kind':'f'}]
+					endif
+				endfor
+
+				return final_list
+
+			endif
+
+		endif
+
+		if a:base =~ '^\$'
+			let adddollar = '$'
+		else
+			let adddollar = ''
+		endif
+		let file = getline(1, '$')
+		let jfile = join(file, ' ')
+		let sfile = split(jfile, '\$')
+		let int_vars = {}
+		for i in sfile
+			if i =~ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*=\s*new'
+				let val = matchstr(i, '^[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*').'->'
+			else
+				let val = matchstr(i, '^[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*')
+			endif
+			if val !~ ''
+				let int_vars[adddollar.val] = ''
+			endif
+		endfor
+
+		" ctags has good support for PHP, use tags file for external
+		" variables
+		let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+		let ext_vars = {}
+		if fnames != ''
+			let sbase = substitute(a:base, '^\$', '', '')
+			exe 'silent! vimgrep /^'.sbase.'.*\tv\(\t\|$\)/j '.fnames
+			let qflist = getqflist()
+			if len(qflist) > 0
+				for field in qflist
+					let item = matchstr(field['text'], '^[^[:space:]]\+')
+					" Add -> if it is possible object declaration
+					let classname = ''
+					if field['text'] =~ item.'\s*=\s*new\s\+'
+						let item = item.'->'
+						let classname = matchstr(field['text'],
+								\ '=\s*new\s\+\zs[a-zA-Z_0-9\x7f-\xff]\+\ze')
+					endif
+					let ext_vars[adddollar.item] = classname
+				endfor
+			endif
+		endif
+
+		" Now we have all variables in int_vars dictionary
+		call extend(int_vars, ext_vars)
+
+		" Internal solution for finding functions in current file.
+		let file = getline(1, '$')
+		call filter(file,
+				\ 'v:val =~ "function\\s\\+&\\?[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*("')
+		let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+		let jfile = join(file, ' ')
+		let int_values = split(jfile, 'function\s\+')
+		let int_functions = {}
+		for i in int_values
+			let f_name = matchstr(i,
+					\ '^&\?\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze')
+			let f_args = matchstr(i,
+					\ '^&\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*(\zs.\{-}\ze)\_s*{')
+			let int_functions[f_name.'('] = f_args.')'
+		endfor
+
+		" Prepare list of functions from tags file
+		let ext_functions = {}
+		if fnames != ''
+			exe 'silent! vimgrep /^'.a:base.'.*\tf\(\t\|$\)/j '.fnames
+			let qflist = getqflist()
+			if len(qflist) > 0
+				for field in qflist
+					" File name
+					let item = matchstr(field['text'], '^[^[:space:]]\+')
+					let fname = matchstr(field['text'], '\t\zs\f\+\ze')
+					let prototype = matchstr(field['text'],
+							\ 'function\s\+&\?[^[:space:]]\+\s*(\s*\zs.\{-}\ze\s*)\s*{\?')
+					let ext_functions[item.'('] = prototype.') - '.fname
+				endfor
+			endif
+		endif
+
+		let all_values = {}
+		call extend(all_values, int_functions)
+		call extend(all_values, ext_functions)
+		call extend(all_values, int_vars) " external variables are already in
+		call extend(all_values, g:php_builtin_object_functions)
+
+		for m in sort(keys(all_values))
+			if m =~ '\(^\|::\)'.a:base
+				call add(res, m)
+			endif
+		endfor
+
+		let start_list = res
+
+		let final_list = []
+		for i in start_list
+			if has_key(int_vars, i)
+				let class = ' '
+				if all_values[i] != ''
+					let class = i.' class '
+				endif
+				let final_list += [{'word':i, 'info':class.all_values[i], 'kind':'v'}]
+			else
+				let final_list +=
+						\ [{'word':substitute(i, '.*::', '', ''),
+						\   'info':i.all_values[i],
+						\   'kind':'f'}]
+			endif
+		endfor
+
+		return final_list
+	endif
+
+	if a:base =~ '^\$'
+		" Complete variables
+		" Built-in variables {{{
+		let g:php_builtin_vars = {'$GLOBALS':'',
+								\ '$_SERVER':'',
+								\ '$_GET':'',
+								\ '$_POST':'',
+								\ '$_COOKIE':'',
+								\ '$_FILES':'',
+								\ '$_ENV':'',
+								\ '$_REQUEST':'',
+								\ '$_SESSION':'',
+								\ '$HTTP_SERVER_VARS':'',
+								\ '$HTTP_ENV_VARS':'',
+								\ '$HTTP_COOKIE_VARS':'',
+								\ '$HTTP_GET_VARS':'',
+								\ '$HTTP_POST_VARS':'',
+								\ '$HTTP_POST_FILES':'',
+								\ '$HTTP_SESSION_VARS':'',
+								\ '$php_errormsg':'',
+								\ '$this':''
+								\ }
+		" }}}
+
+		" Internal solution for current file.
+		let file = getline(1, '$')
+		let jfile = join(file, ' ')
+		let int_vals = split(jfile, '\ze\$')
+		let int_vars = {}
+		for i in int_vals
+			if i =~ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*=\s*new'
+				let val = matchstr(i,
+						\ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*').'->'
+			else
+				let val = matchstr(i,
+						\ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*')
+			endif
+			if val != ''
+				let int_vars[val] = ''
+			endif
+		endfor
+
+		call extend(int_vars,g:php_builtin_vars)
+
+		" ctags has support for PHP, use tags file for external variables
+		let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+		let ext_vars = {}
+		if fnames != ''
+			let sbase = substitute(a:base, '^\$', '', '')
+			exe 'silent! vimgrep /^'.sbase.'.*\tv\(\t\|$\)/j '.fnames
+			let qflist = getqflist()
+			if len(qflist) > 0
+				for field in qflist
+					let item = '$'.matchstr(field['text'], '^[^[:space:]]\+')
+					let m_menu = ''
+					" Add -> if it is possible object declaration
+					if field['text'] =~ item.'\s*=\s*new\s\+'
+						let item = item.'->'
+						let m_menu = matchstr(field['text'],
+								\ '=\s*new\s\+\zs[a-zA-Z_0-9\x7f-\xff]\+\ze')
+					endif
+					let ext_vars[item] = m_menu
+				endfor
+			endif
+		endif
+
+		call extend(int_vars, ext_vars)
+		let g:a0 = keys(int_vars)
+
+		for m in sort(keys(int_vars))
+			if m =~ '^\'.a:base
+				call add(res, m)
+			endif
+		endfor
+
+		let int_list = res
+
+		let int_dict = []
+		for i in int_list
+			if int_vars[i] != ''
+				let class = ' '
+				if int_vars[i] != ''
+					let class = i.' class '
+				endif
+				let int_dict += [{'word':i, 'info':class.int_vars[i], 'kind':'v'}]
+			else
+				let int_dict += [{'word':i, 'kind':'v'}]
+			endif
+		endfor
+
+		return int_dict
+
+	else
+		" Complete everything else -
+		"  + functions,  DONE
+		"  + keywords of language DONE
+		"  + defines (constant definitions), DONE
+		"  + extend keywords for predefined constants, DONE
+		"  + classes (after new), DONE
+		"  + limit choice after -> and :: to funcs and vars DONE
+
+		" Internal solution for finding functions in current file.
+		let file = getline(1, '$')
+		call filter(file,
+				\ 'v:val =~ "function\\s\\+&\\?[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*("')
+		let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+		let jfile = join(file, ' ')
+		let int_values = split(jfile, 'function\s\+')
+		let int_functions = {}
+		for i in int_values
+			let f_name = matchstr(i,
+					\ '^&\?\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze')
+			let f_args = matchstr(i,
+					\ '^&\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*(\s*\zs.\{-}\ze\s*)\_s*{')
+			let int_functions[f_name.'('] = f_args.')'
+		endfor
+
+		" Prepare list of functions from tags file
+		let ext_functions = {}
+		if fnames != ''
+			exe 'silent! vimgrep /^'.a:base.'.*\tf\(\t\|$\)/j '.fnames
+			let qflist = getqflist()
+			if len(qflist) > 0
+				for field in qflist
+					" File name
+					let item = matchstr(field['text'], '^[^[:space:]]\+')
+					let fname = matchstr(field['text'], '\t\zs\f\+\ze')
+					let prototype = matchstr(field['text'],
+							\ 'function\s\+&\?[^[:space:]]\+\s*(\s*\zs.\{-}\ze\s*)\s*{\?')
+					let ext_functions[item.'('] = prototype.') - '.fname
+				endfor
+			endif
+		endif
+
+		" All functions
+		call extend(int_functions, ext_functions)
+		call extend(int_functions, g:php_builtin_functions)
+
+		" Internal solution for finding constants in current file
+		let file = getline(1, '$')
+		call filter(file, 'v:val =~ "define\\s*("')
+		let jfile = join(file, ' ')
+		let int_values = split(jfile, 'define\s*(\s*')
+		let int_constants = {}
+		for i in int_values
+			let c_name = matchstr(i, '\(["'']\)\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze\1')
+			" let c_value = matchstr(i,
+			" \ '\(["'']\)[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\1\s*,\s*\zs.\{-}\ze\s*)')
+			if c_name != ''
+				let int_constants[c_name] = '' " c_value
+			endif
+		endfor
+
+		" Prepare list of constants from tags file
+		let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
+		let ext_constants = {}
+		if fnames != ''
+			exe 'silent! vimgrep /^'.a:base.'.*\td\(\t\|$\)/j '.fnames
+			let qflist = getqflist()
+			if len(qflist) > 0
+				for field in qflist
+					let item = matchstr(field['text'], '^[^[:space:]]\+')
+					let ext_constants[item] = ''
+				endfor
+			endif
+		endif
+
+		" All constants
+		call extend(int_constants, ext_constants)
+		" Treat keywords as constants
+
+		let all_values = {}
+
+		" One big dictionary of functions
+		call extend(all_values, int_functions)
+
+		" Add constants
+		call extend(all_values, int_constants)
+		" Add keywords
+		call extend(all_values, g:php_keywords)
+
+		for m in sort(keys(all_values))
+			if m =~ '^'.a:base
+				call add(res, m)
+			endif
+		endfor
+
+		let int_list = res
+
+		let final_list = []
+		for i in int_list
+			if has_key(int_functions, i)
+				let final_list +=
+						\ [{'word':i,
+						\   'info':i.int_functions[i],
+						\   'kind':'f'}]
+			elseif has_key(int_constants, i)
+				let final_list += [{'word':i, 'kind':'d'}]
+			else
+				let final_list += [{'word':i}]
+			endif
+		endfor
+
+		return final_list
+
+	endif
+
+endfunction
+" vim:set foldmethod=marker:
diff --git a/app/server/vendor/rouge/spec/visual/samples/xml b/app/server/vendor/rouge/spec/visual/samples/xml
new file mode 100755
index 0000000..9c9cb21
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- from test.xsl -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+	<xsl:output method="xml"/>
+	<xsl:template match="/">
+		<customers>
+			<xsl:apply-templates select="customers/customer[@Country='Germany']"/>
+		</customers>
+	</xsl:template>
+	<xsl:template match="customers">
+		<xsl:apply-templates/>
+
+	</xsl:template>
+	<xsl:template match="customer">
+		<customer>
+			<xsl:attribute name="CompanyName"><xsl:value-of select="@CompanyName"/></xsl:attribute>
+			<xsl:attribute name="CustomerID"><xsl:value-of select="@CustomerID"/></xsl:attribute>
+			<xsl:attribute name="Country"><xsl:value-of select="@Country"/></xsl:attribute>
+		</customer>
+		<xsl:apply-templates/>
+	</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/app/server/vendor/rouge/spec/visual/samples/yaml b/app/server/vendor/rouge/spec/visual/samples/yaml
new file mode 100755
index 0000000..c7606a8
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/samples/yaml
@@ -0,0 +1,301 @@
+#
+# Examples from the Preview section of the YAML specification
+# (http://yaml.org/spec/1.2/#Preview)
+#
+
+# Sequence of scalars
+---
+- Mark McGwire
+- Sammy Sosa
+- Ken Griffey
+
+# Mapping scalars to scalars
+---
+hr:  65    # Home runs
+avg: 0.278 # Batting average
+rbi: 147   # Runs Batted In
+
+# Mapping scalars to sequences
+---
+american:
+  - Boston Red Sox
+  - Detroit Tigers
+  - New York Yankees
+national:
+  - New York Mets
+  - Chicago Cubs
+  - Atlanta Braves
+
+# Sequence of mappings
+---
+-
+  name: Mark McGwire
+  hr:   65
+  avg:  0.278
+-
+  name: Sammy Sosa
+  hr:   63
+  avg:  0.288
+
+# Sequence of sequences
+---
+- [name        , hr, avg  ]
+- [Mark McGwire, 65, 0.278]
+- [Sammy Sosa  , 63, 0.288]
+
+# Mapping of mappings
+---
+Mark McGwire: {hr: 65, avg: 0.278}
+Sammy Sosa: {
+    hr: 63,
+    avg: 0.288
+  }
+
+# Two documents in a stream
+--- # Ranking of 1998 home runs
+- Mark McGwire
+- Sammy Sosa
+- Ken Griffey
+--- # Team ranking
+- Chicago Cubs
+- St Louis Cardinals
+
+# Documents with the end indicator
+---
+time: 20:03:20
+player: Sammy Sosa
+action: strike (miss)
+...
+---
+time: 20:03:47
+player: Sammy Sosa
+action: grand slam
+...
+
+# Comments
+---
+hr: # 1998 hr ranking
+  - Mark McGwire
+  - Sammy Sosa
+rbi:
+  # 1998 rbi ranking
+  - Sammy Sosa
+  - Ken Griffey
+
+# Anchors and aliases
+---
+hr:
+  - Mark McGwire
+  # Following node labeled SS
+  - &SS Sammy Sosa
+rbi:
+  - *SS # Subsequent occurrence
+  - Ken Griffey
+
+# Mapping between sequences
+---
+? - Detroit Tigers
+  - Chicago cubs
+:
+  - 2001-07-23
+? [ New York Yankees,
+    Atlanta Braves ]
+: [ 2001-07-02, 2001-08-12,
+    2001-08-14 ]
+
+# Inline nested mapping
+---
+# products purchased
+- item    : Super Hoop
+  quantity: 1
+- item    : Basketball
+  quantity: 4
+- item    : Big Shoes
+  quantity: 1
+
+# Literal scalars
+--- | # ASCII art
+  \//||\/||
+  // ||  ||__
+
+# Folded scalars
+--- >
+  Mark McGwire's
+  year was crippled
+  by a knee injury.
+
+# Preserved indented block in a folded scalar
+---
+>
+ Sammy Sosa completed another
+ fine season with great stats.
+
+   63 Home Runs
+   0.288 Batting Average
+
+ What a year!
+
+# Indentation determines scope
+---
+name: Mark McGwire
+accomplishment: >
+  Mark set a major league
+  home run record in 1998.
+stats: |
+  65 Home Runs
+  0.278 Batting Average
+
+# Quoted scalars
+---
+unicode: "Sosa did fine.\u263A"
+control: "\b1998\t1999\t2000\n"
+hex esc: "\x0d\x0a is \r\n"
+single: '"Howdy!" he cried.'
+quoted: ' # not a ''comment''.'
+tie-fighter: '|\-*-/|'
+
+# Multi-line flow scalars
+---
+plain:
+  This unquoted scalar
+  spans many lines.
+quoted: "So does this
+  quoted scalar.\n"
+
+# Integers
+---
+canonical: 12345
+decimal: +12_345
+sexagesimal: 3:25:45
+octal: 014
+hexadecimal: 0xC
+
+# Floating point
+---
+canonical: 1.23015e+3
+exponential: 12.3015e+02
+sexagesimal: 20:30.15
+fixed: 1_230.15
+negative infinity: -.inf
+not a number: .NaN
+
+# Miscellaneous
+---
+null: ~
+true: boolean
+false: boolean
+string: '12345'
+
+# Timestamps
+---
+canonical: 2001-12-15T02:59:43.1Z
+iso8601: 2001-12-14t21:59:43.10-05:00
+spaced: 2001-12-14 21:59:43.10 -5
+date: 2002-12-14
+
+# Various explicit tags
+---
+not-date: !!str 2002-04-28
+picture: !!binary |
+ R0lGODlhDAAMAIQAAP//9/X
+ 17unp5WZmZgAAAOfn515eXv
+ Pz7Y6OjuDg4J+fn5OTk6enp
+ 56enmleECcgggoBADs=
+application specific tag: !something |
+ The semantics of the tag
+ above may be different for
+ different documents.
+
+# Global tags
+%TAG ! tag:clarkevans.com,2002:
+--- !shape
+  # Use the ! handle for presenting
+  # tag:clarkevans.com,2002:circle
+- !circle
+  center: &ORIGIN {x: 73, y: 129}
+  radius: 7
+- !line
+  start: *ORIGIN
+  finish: { x: 89, y: 102 }
+- !label
+  start: *ORIGIN
+  color: 0xFFEEBB
+  text: Pretty vector drawing.
+
+# Unordered sets
+--- !!set
+# sets are represented as a
+# mapping where each key is
+# associated with the empty string
+? Mark McGwire
+? Sammy Sosa
+? Ken Griff
+
+# Ordered mappings
+--- !!omap
+# ordered maps are represented as
+# a sequence of mappings, with
+# each mapping having one key
+- Mark McGwire: 65
+- Sammy Sosa: 63
+- Ken Griffy: 58
+
+# Full length example
+--- !<tag:clarkevans.com,2002:invoice>
+invoice: 34843
+date   : 2001-01-23
+bill-to: &id001
+    given  : Chris
+    family : Dumars
+    address:
+        lines: |
+            458 Walkman Dr.
+            Suite #292
+        city    : Royal Oak
+        state   : MI
+        postal  : 48046
+ship-to: *id001
+product:
+    - sku         : BL394D
+      quantity    : 4
+      description : Basketball
+      price       : 450.00
+    - sku         : BL4438H
+      quantity    : 1
+      description : Super Hoop
+      price       : 2392.00
+tax  : 251.42
+total: 4443.52
+comments:
+    Late afternoon is best.
+    Backup contact is Nancy
+    Billsmer @ 338-4338.
+
+# Another full-length example
+---
+Time: 2001-11-23 15:01:42 -5
+User: ed
+Warning:
+  This is an error message
+  for the log file
+---
+Time: 2001-11-23 15:02:31 -5
+User: ed
+Warning:
+  A slightly different error
+  message.
+---
+Date: 2001-11-23 15:03:17 -5
+User: ed
+Fatal:
+  Unknown variable "bar"
+Stack:
+  - file: TopClass.py
+    line: 23
+    code: |
+      x = MoreObject("345\n")
+  - file: MoreClass.py
+    line: 58
+    code: |-
+      foo = bar
+
diff --git a/app/server/vendor/rouge/spec/visual/templates/index.erb b/app/server/vendor/rouge/spec/visual/templates/index.erb
new file mode 100755
index 0000000..5ef3312
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/templates/index.erb
@@ -0,0 +1,21 @@
+<style type="text/css">
+  body {
+    column-count: 2;
+    -webkit-column-count: 2;
+    -moz-column-count: 2;
+  }
+  div {
+    break-inside: avoid-column;
+    -webkit-column-break-inside: avoid;
+    }
+</style>
+
+<h1>Lexers supported by Rouge v<%= Rouge.version %></h1>
+
+<% @samples.each do |sample| %>
+<div>
+<h2><a href="/<%= sample.tag %>"><%= sample.tag %></a></h2>
+<%= Rouge.highlight(sample.demo, sample, @formatter) %>
+<br />
+</div>
+<% end %>
diff --git a/app/server/vendor/rouge/spec/visual/templates/layout.erb b/app/server/vendor/rouge/spec/visual/templates/layout.erb
new file mode 100755
index 0000000..23a7432
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/templates/layout.erb
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title><%= @title %></title>
+
+  <style type="text/css">
+    <%= @theme.render %>
+    <%= @theme.render_base('body') %>
+    <%= @theme.render_base('a') %>
+
+    pre, code {
+      font-family: 'Source Code Pro', 'Menlo', 'Ubuntu Mono', 'Monaco', monospace;
+      font-size: 14px;
+    }
+    a { text-decoration: none }
+
+  </style>
+</head>
+
+<body>
+  <%= yield %>
+</body>
+
+
+
+</html>
diff --git a/app/server/vendor/rouge/spec/visual/templates/lexer.erb b/app/server/vendor/rouge/spec/visual/templates/lexer.erb
new file mode 100755
index 0000000..57fe714
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual/templates/lexer.erb
@@ -0,0 +1,21 @@
+<style type="text/css">
+  .legend {
+    width: 200px;
+    margin-right: 30px;
+    float: right;
+  }
+</style>
+
+<section class="legend">
+  <h2>Legend</h2>
+  <pre class="highlight"><%
+    Rouge::Token.each_token do |token|
+      %><span class="<%= token.shortname %>"><%= token.qualname %></span>
+<%      end
+  %></pre>
+</section>
+<h2>Highlighted</h2>
+<%= @highlighted %>
+
+<h2>Raw</h2>
+<pre><%= CGI.escape_html(@sample) %></pre>
diff --git a/app/server/vendor/rouge/spec/visual_spec.rb b/app/server/vendor/rouge/spec/visual_spec.rb
new file mode 100755
index 0000000..ae9aa24
--- /dev/null
+++ b/app/server/vendor/rouge/spec/visual_spec.rb
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*- #
+
+puts <<-msg
+
+============
+Run `rackup` and visit localhost:9292/:lexer_name to visually test a lexer.
+============
+
+msg
diff --git a/app/server/vendor/rouge/tasks/gherkin.rake b/app/server/vendor/rouge/tasks/gherkin.rake
new file mode 100755
index 0000000..27e1924
--- /dev/null
+++ b/app/server/vendor/rouge/tasks/gherkin.rake
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*- #
+require 'open-uri'
+require 'json'
+
+I18N_CONFIG_URL = 'https://raw.github.com/cucumber/gherkin/master/lib/gherkin/i18n.json'
+
+module GherkinKeywords
+  extend self
+
+  def gherkin_i18n
+    @gherkin_i18n ||= JSON.load(open(I18N_CONFIG_URL))
+  end
+
+  def keywords_for(*keys)
+    gherkin_i18n.values.map do |lang|
+      lang.values_at(*keys).map { |w| w.split('|') }
+    end.flatten.sort.uniq
+  end
+
+  def keywords
+    @keywords ||= {
+      :feature => keywords_for('feature'),
+      :element => keywords_for('background', 'scenario', 'scenario_outline'),
+      :examples => keywords_for('examples'),
+      :step => keywords_for('given', 'when', 'then', 'and', 'but')
+    }
+  end
+
+  def source(&b)
+    yield   '# -*- coding: utf-8 -*- #'
+    yield   '# automatically generated by `rake builtins:gherkin`'
+    yield   'module Rouge'
+    yield   '  module Lexers'
+    yield   '    def Gherkin.keywords'
+    yield   '      @keywords ||= {}.tap do |k|'
+    keywords.each do |t, kws|
+      yield "        k[#{t.inspect}] = Set.new #{kws.inspect}"
+    end
+    yield   '      end'
+    yield   '    end'
+    yield   '  end'
+    yield   'end'
+  end
+end
+
+namespace :builtins do
+  task :gherkin do
+    File.open('lib/rouge/lexers/gherkin/keywords.rb', 'w') do |f|
+      GherkinKeywords.source { |line| f.puts line }
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/tasks/lex.rake b/app/server/vendor/rouge/tasks/lex.rake
new file mode 100755
index 0000000..9e2ddaa
--- /dev/null
+++ b/app/server/vendor/rouge/tasks/lex.rake
@@ -0,0 +1,57 @@
+desc "Creates all necessary files for a new lexer"
+task :lex, [:language] do |t, args|
+  language = args.language
+  sh "touch lib/rouge/demos/#{language}"
+  sh "touch spec/visual/samples/#{language}"
+  sh "echo \"#{lexer_template(language)}\" > lib/rouge/lexers/#{language}.rb"
+  sh "echo \"#{spec_template(language)}\" > spec/lexers/#{language}_spec.rb"
+end
+
+def lexer_template(language)
+  <<-LEX
+module Rouge
+  module Lexers
+    class #{language.capitalize} < RegexLexer
+      desc '#{language}'
+      tag '#{language}'
+      aliases '#{language}'
+      filenames '*.???'
+
+      mimetypes 'text/x-#{language}', 'application/x-#{language}'
+
+      def self.analyze_text(text)
+        return 0
+      end
+
+      state :root do
+      end
+    end
+  end
+end
+  LEX
+end
+
+def spec_template(language)
+  <<-SPEC
+describe Rouge::Lexers::#{language.capitalize} do
+  let(:subject) { Rouge::Lexers::#{language.capitalize}.new }
+
+  describe 'guessing' do
+    include Support::Guessing
+
+    it 'guesses by filename' do
+      assert_guess :filename => 'foo.???'
+    end
+
+    it 'guesses by mimetype' do
+      assert_guess :mimetype => 'text/x-#{language}'
+      assert_guess :mimetype => 'application/x-#{language}'
+    end
+
+    it 'guesses by source' do
+      assert_guess :source => '????'
+    end
+  end
+end
+  SPEC
+end
diff --git a/app/server/vendor/rouge/tasks/lua.rake b/app/server/vendor/rouge/tasks/lua.rake
new file mode 100755
index 0000000..8c9162e
--- /dev/null
+++ b/app/server/vendor/rouge/tasks/lua.rake
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*- #
+
+require 'open-uri'
+
+def lua_builtins_source(lua_functions)
+  yield   "# -*- coding: utf-8 -*- #"
+  yield   "# automatically generated by `rake builtins:lua`"
+  yield   "module Rouge"
+  yield   "  module Lexers"
+  yield   "    class Lua"
+  yield   "      def self.builtins"
+  yield   "        @builtins ||= {}.tap do |b|"
+  lua_functions.each do |n, fs|
+    yield "          b[#{n.inspect}] = Set.new %w(#{fs.join(' ')})"
+  end
+  yield   "        end"
+  yield   "      end"
+  yield   "    end"
+  yield   "  end"
+  yield   "end"
+end
+
+def get_lua_functions(manual_url)
+  open(manual_url) do |f|
+    f.map do |line|
+      line[%r(^<A HREF="manual.html#pdf-(.+)">\1</A>), 1]
+    end.compact
+  end
+end
+
+def get_function_module(name)
+  if name =~ /\./
+    m = name.split('.').first
+    m = 'modules' if m == 'package'
+    m
+  elsif %w(require module).include?(name)
+    'modules'
+  else
+    'basic'
+  end
+end
+
+namespace :builtins do
+  task :lua do
+    version = "5.2"
+    lua_manual_url = "http://www.lua.org/manual/#{version}/"
+    puts "Downloading function index for Lua #{version}" 
+    functions = get_lua_functions(lua_manual_url)
+    puts "#{functions.length} functions found:"
+
+    modules = {}
+    functions.each do |full_function_name|
+      m = get_function_module(full_function_name)
+      (modules[m] ||= []) << full_function_name
+      puts "  #{full_function_name}"
+    end
+
+    File.open('lib/rouge/lexers/lua/builtins.rb', 'w') do |f|
+      lua_builtins_source(modules) do |line|
+        f.puts line
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/tasks/matlab.rake b/app/server/vendor/rouge/tasks/matlab.rake
new file mode 100755
index 0000000..94f133c
--- /dev/null
+++ b/app/server/vendor/rouge/tasks/matlab.rake
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*- #
+
+require 'open-uri'
+
+def matlab_builtins(&b)
+  return enum_for :matlab_builtins unless block_given?
+
+  matlab_doc_url = 'http://www.mathworks.com/help/matlab/functionlist.html'
+
+  matlab_docs = open(matlab_doc_url).read
+
+  p :docs => matlab_docs
+
+  matlab_docs.scan %r(<a href="[.][.]/matlab/ref/(\w+)[.]html">)m do |word|
+    p :word => word
+    yield word
+  end
+end
+
+def matlab_builtins_source
+  yield   "# -*- coding: utf-8 -*- #"
+  yield   "# automatically generated by `rake builtins:matlab`"
+  yield   "module Rouge"
+  yield   "  module Lexers"
+  yield   "    class Matlab"
+  yield   "      def self.builtins"
+  yield   "        @builtins ||= Set.new %w(#{matlab_builtins.to_a.join(' ')})"
+  yield   "      end"
+  yield   "    end"
+  yield   "  end"
+  yield   "end"
+end
+
+namespace :builtins do
+  task :matlab do
+    File.open('lib/rouge/lexers/matlab/builtins.rb', 'w') do |f|
+      matlab_builtins_source do |line|
+        f.puts line
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/tasks/php.rake b/app/server/vendor/rouge/tasks/php.rake
new file mode 100755
index 0000000..9005418
--- /dev/null
+++ b/app/server/vendor/rouge/tasks/php.rake
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*- #
+
+def php_references(&b)
+  return enum_for :php_references unless block_given?
+
+  php_manual_url = 'http://us3.php.net/distributions/manual/php_manual_en.tar.gz'
+
+  sh 'mkdir -p /tmp/rouge'
+  Dir.chdir '/tmp/rouge' do
+    sh "wget -O- #{php_manual_url} | tar -xz"
+    Dir.chdir './php-chunked-xhtml' do
+      Dir.glob('./ref.*').sort.each { |x| yield File.read(x) }
+    end
+  end
+end
+
+def php_functions(&b)
+  return enum_for :php_functions unless block_given?
+
+  php_references do |file|
+    file =~ %r(<title>(.*?) Functions</title>)
+    name = $1
+
+    next unless name
+
+    functions = file.scan %r(<a href="function\..*?\.html">(.*?)</a>)
+
+    yield [name, functions]
+  end
+end
+
+def php_builtins_source
+  yield   "# -*- coding: utf-8 -*- #"
+  yield   "# automatically generated by `rake builtins:php`"
+  yield   "module Rouge"
+  yield   "  module Lexers"
+  yield   "    class PHP"
+  yield   "      def self.builtins"
+  yield   "        @builtins ||= {}.tap do |b|"
+  php_functions do |n, fs|
+    yield "          b[#{n.inspect}] = Set.new %w(#{fs.join(' ')})"
+  end
+  yield   "        end"
+  yield   "      end"
+  yield   "    end"
+  yield   "  end"
+  yield   "end"
+end
+
+namespace :builtins do
+  task :php do
+    File.open('lib/rouge/lexers/php/builtins.rb', 'w') do |f|
+      php_builtins_source do |line|
+        f.puts line
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rouge/tasks/vim.rake b/app/server/vendor/rouge/tasks/vim.rake
new file mode 100755
index 0000000..3acd465
--- /dev/null
+++ b/app/server/vendor/rouge/tasks/vim.rake
@@ -0,0 +1,68 @@
+# encoding: utf-8
+
+def get_keywords(input)
+  out = { command: [], option: [], auto: [] }
+  input.each do |line|
+    line =~ %r(^
+      (?: syn[ ]keyword[ ](vimCommand|vimOpt|vimAutoEvent)[ ]contained )
+      (.*)
+    $)x
+
+    next unless $1
+
+    out_list = case $1
+    when 'vimCommand'
+      out[:command]
+    when 'vimAutoEvent'
+      out[:auto]
+    when 'vimOpt'
+      out[:option]
+    end
+
+    $2.scan(/([\w:]+)(?:\[(\w+)\])?/) do
+      out_list << [$1, "#{$1}#{$2}"]
+    end
+
+    out_list.sort!
+  end
+
+  out
+end
+
+def render_keywords(keywords, &b)
+  return enum_for(:render_keywords, keywords).to_a.join("\n") unless b
+
+  yield '# encoding: utf-8'
+  yield '# DO NOT EDIT: automatically generated by `rake builtins:vim`.'
+  yield '# see tasks/vim.rake for more info.'
+  yield 'module Rouge'
+  yield '  module Lexers'
+  yield '    class VimL'
+  yield '      def self.keywords'
+  yield "        @keywords ||= #{keywords.inspect}"
+  yield '      end'
+  yield '    end'
+  yield '  end'
+  yield 'end'
+end
+
+def vim_keywords
+  syntax_file = ENV['syntax_file'] || '/usr/share/vim/vimcurrent/syntax/vim.vim'
+  out = nil
+
+  File.open(syntax_file, 'r') do |f|
+    out = render_keywords(get_keywords(f))
+  end
+
+  out
+end
+
+namespace :builtins do
+  task :vim do
+    keywords = vim_keywords
+
+    File.open('./lib/rouge/lexers/viml/keywords.rb', 'w') do |f|
+      f << keywords
+    end
+  end
+end
diff --git a/app/server/vendor/rubame/.gitignore b/app/server/vendor/rubame/.gitignore
new file mode 100755
index 0000000..2d15f22
--- /dev/null
+++ b/app/server/vendor/rubame/.gitignore
@@ -0,0 +1,29 @@
+# Editors #
+###########
+*.sublime-workspace
+*.*~
+*.texpadtmp
+
+# Citadels #
+############
+
+*.log
+*.dat
+
+# Project specific #
+####################
+
+*.gem
+test_fiddle.rb
+Gemfile.lock
+
+# OS generated files #
+######################
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+Icon?
+ehthumbs.db
+Thumbs.db
diff --git a/app/server/vendor/rubame/Gemfile b/app/server/vendor/rubame/Gemfile
new file mode 100755
index 0000000..c80ee36
--- /dev/null
+++ b/app/server/vendor/rubame/Gemfile
@@ -0,0 +1,3 @@
+source "http://rubygems.org"
+
+gemspec
diff --git a/app/server/vendor/rubame/README.md b/app/server/vendor/rubame/README.md
new file mode 100755
index 0000000..a977ffe
--- /dev/null
+++ b/app/server/vendor/rubame/README.md
@@ -0,0 +1,58 @@
+# Rubame
+
+Rubame is a simple Ruby websocket game server.  I was originally using EventMachine for a private project, but it became apparent that EM may not be the most suitable tool.  EM is designed (as I understand it) for servers that will handle lots of low duration connections, whereas my project will involve only a small handful (between 1 and 20, likely) that are long lasting.  However, the primary concern I had was how EM takes over the thread.  In order to have game logic run, it seemed the options were to create a new thread, or use periodic timers to have a game loop called.
+
+Neither seemed ideal, and I wanted to have more control in order to better manage cpu usage.  Rubame allows me to run the network loop when it suits me, allowing the game logic/engine to be the primary tool.
+
+Rubame makes use of [WebSocket Ruby](https://github.com/imanel/websocket-ruby) to handle the websocket protocol, and the standard ruby sockets libraries for the actual network connections.
+
+I am by no means a Ruby expert, so I expect there to be many ways I could improve this.  I also expect there are ways I have done this that will make someone proficient in Ruby cringe.  If you have such comments, please [email me](mailto:me at marksaward.com).  I also expect to improve the code as my project progresses, and my needs grow.  However, I will keep improvements to only be those that are of general use, and not specific to my project.
+
+## Example Use
+
+```ruby
+require 'rubame'
+
+server = Rubame::Server.new("0.0.0.0", 25252)
+while true
+  server.run do |client|
+    client.onopen do
+      puts "Server reports:  client open"
+    end
+    client.onmessage do |mess|
+      puts "Server reports:  message received: #{mess}"
+      client.send "You sent me #{mess}"
+    end
+    client.onclose do
+      puts "Server reports:  client closed"
+    end
+  end
+end
+```
+
+A useful Chrome plugin to help test connections is this [Simple Websocket Client](https://chrome.google.com/webstore/detail/simple-websocket-client/pfdhoblngboilpfeibdedpjgfnlcodoo).
+
+Each time the loop is run, it checks with ruby IO to see if any sockets have any new data.  It then reads up to (currently) 2000 bytes from that socket.  If there is more data than that waiting, it will have to wait until the next time the loop is called.  Once enough data has been received for a complete frame, that frame will be read and returned as a message, via client.onmessage as seen in the example.
+
+## Possible Future Features
+
+* Binary data - Currently, Rubame only deals with text network traffic.  This is not ideal, and so I hope to add the ability to send binary data, along with examples here showing how to communicate with a javascript client.
+* Lazy send - Currently, Rubame sends a message as soon as the message is requested to be sent.  Sometimes, a game may want to send some traffic whenever it is convenient, and some traffic immediately.  I may add the ability to lazy send data.
+
+__Please Note:__ The lazy send code currently is broken, so do not use it!
+
+## RSpec
+
+The RSpec is quite incomplete for now.  I expect to add more tests later.
+
+## License
+
+(The MIT License)
+
+Copyright © 2013 Mark Saward
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/rubame/Rakefile b/app/server/vendor/rubame/Rakefile
new file mode 100755
index 0000000..4afbfa0
--- /dev/null
+++ b/app/server/vendor/rubame/Rakefile
@@ -0,0 +1,11 @@
+require 'bundler'
+Bundler::GemHelper.install_tasks
+
+require 'rspec/core/rake_task'
+
+RSpec::Core::RakeTask.new do |t|
+  t.rspec_opts = ["-c", "-f progress"]
+  t.pattern = 'spec/**/*_spec.rb'
+end
+
+task :default => :spec
diff --git a/app/server/vendor/rubame/lib/rubame.rb b/app/server/vendor/rubame/lib/rubame.rb
new file mode 100755
index 0000000..9f1efbc
--- /dev/null
+++ b/app/server/vendor/rubame/lib/rubame.rb
@@ -0,0 +1,223 @@
+require 'websocket'
+require 'socket'
+require 'fiber'
+
+module Rubame
+  class Server
+    def initialize(host, port)
+      Socket.do_not_reverse_lookup
+      @hostname = host
+      @port = port
+
+      @reading = []
+      @writing = []
+
+      @clients = {} # Socket as key, and Client as value
+
+      @socket = TCPServer.new(@hostname, @port)
+      @reading.push @socket
+    end
+
+    def accept
+      socket = @socket.accept_nonblock
+      @reading.push socket
+      handshake = WebSocket::Handshake::Server.new
+      client = Rubame::Client.new(socket, handshake, self)
+      
+      while line = socket.gets
+        client.handshake << line
+        break if client.handshake.finished?
+      end
+      if client.handshake.valid?
+        @clients[socket] = client
+        client.write handshake.to_s
+        client.opened = true
+        return client
+      else
+        close(client)
+      end
+      return nil
+    end
+
+    def read(client)
+
+      pairs = client.socket.recvfrom(2000)
+      messages = []
+
+      if pairs[0].length == 0
+        close(client)
+      else
+        client.frame << pairs[0]
+
+        while f = client.frame.next
+          if (f.type == :close)
+            close(client)
+            return messages
+          else
+            messages.push f
+          end
+        end
+        
+      end
+
+      return messages
+
+    end
+
+    def close(client)
+      @reading.delete client.socket
+      @clients.delete client.socket
+      begin
+        client.socket.close
+      rescue
+      end
+      client.closed = true
+    end
+
+    def run(time = 0, &blk)
+      readable, writable = IO.select(@reading, @writing, nil, 0)
+
+      if readable
+        readable.each do |socket|
+          client = @clients[socket]
+          if socket == @socket
+            client = accept
+          else
+            msg = read(client)
+            client.messaged = msg
+          end
+
+          blk.call(client) if client and blk
+        end
+      end
+
+      # Check for lazy send items
+      timer_start = Time.now
+      time_passed = 0
+      begin
+        @clients.each do |s, c|
+          c.send_some_lazy(5)
+        end
+        time_passed = Time.now - timer_start
+      end while time_passed < time
+    end
+
+    def stop
+      @socket.close
+    end
+  end
+
+  class Client
+    attr_accessor :socket, :handshake, :frame, :opened, :messaged, :closed
+
+    def initialize(socket, handshake, server)
+      @socket = socket
+      @handshake = handshake
+      @frame = WebSocket::Frame::Incoming::Server.new(:version => @handshake.version)
+      @opened = false
+      @messaged = []
+      @lazy_queue = []
+      @lazy_current_queue = nil
+      @closed = false
+      @server = server
+    end
+
+    def write(data)
+      @socket.write data
+    end
+
+    def send(data)
+      frame = WebSocket::Frame::Outgoing::Server.new(:version => @handshake.version, :data => data, :type => :text)
+      begin
+        @socket.write frame
+        @socket.flush
+      rescue
+        @server.close(self) unless @closed
+      end
+    end
+
+    def lazy_send(data)
+      @lazy_queue.push data
+    end
+
+    def get_lazy_fiber
+      # Create the fiber if needed
+      if @lazy_fiber == nil or !@lazy_fiber.alive?
+        @lazy_fiber = Fiber.new do
+          @lazy_current_queue.each do |data|
+            send(data)
+            Fiber.yield unless @lazy_current_queue[-1] == data
+          end
+        end
+      end
+
+      return @lazy_fiber
+    end
+
+    def send_some_lazy(count)
+      # To save on cpu cycles, we don't want to be chopping and changing arrays, which could get quite large.  Instead,
+      # we iterate over an array which we are sure won't change out from underneath us.
+      unless @lazy_current_queue
+        @lazy_current_queue = @lazy_queue
+        @lazy_queue = []
+      end
+
+      completed = 0
+      begin
+        get_lazy_fiber.resume
+        completed += 1
+      end while (@lazy_queue.count > 0 or @lazy_current_queue.count > 0) and completed < count
+
+    end
+
+    def onopen(&blk)
+      if @opened
+        begin
+          blk.call
+        ensure
+          @opened = false
+        end
+      end
+    end
+
+    def onmessage(&blk)
+      if @messaged.size > 0
+        begin
+          @messaged.each do |x|
+            blk.call(x.to_s)
+          end
+        ensure
+          @messaged = []
+        end
+      end
+    end
+
+    def onclose(&blk)
+      if @closed
+        begin
+          blk.call
+        ensure
+        end
+      end
+    end
+  end
+
+  line = 0
+end
+
+if __FILE__==$0
+  server = Rubame::Server.new("0.0.0.0", 25222)
+  while (!$quit)
+    server.run do |client|
+      client.onopen do
+        puts "Server reports:  client open"
+      end
+      client.onmessage do |mess|
+        puts "Server reports:  message received: #{mess}"
+      end
+      client.onclose do
+        puts "Server reports:  client closed"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rubame/rubame.gemspec b/app/server/vendor/rubame/rubame.gemspec
new file mode 100755
index 0000000..2fb67ab
--- /dev/null
+++ b/app/server/vendor/rubame/rubame.gemspec
@@ -0,0 +1,14 @@
+Gem::Specification.new do |s|
+  s.name        = 'rubame'
+  s.version     = '0.0.3'
+  s.date        = '2013-01-07'
+  s.summary     = "Rubame"
+  s.description = "Ruby Websocket Game Server"
+  s.authors     = ["Mark Saward"]
+  s.email       = 'me at marksaward.com'
+  s.files       = ["lib/rubame.rb"]
+  s.homepage    =
+    'http://github.com/saward/Rubame'
+
+  s.add_dependency 'websocket', '~> 1.0'
+end
diff --git a/app/server/vendor/rubame/spec/rubame_spec.rb b/app/server/vendor/rubame/spec/rubame_spec.rb
new file mode 100755
index 0000000..8241d7f
--- /dev/null
+++ b/app/server/vendor/rubame/spec/rubame_spec.rb
@@ -0,0 +1,168 @@
+require 'spec_helper'
+
+describe Rubame::Server do
+  it 'should create a new server' do
+    server = Rubame::Server.new("0.0.0.0", 29929)
+    server.class.should == Rubame::Server
+    server.stop
+  end
+
+  it 'should receive a new client connecting' do
+    server = Rubame::Server.new("0.0.0.0", 29929)
+
+    client = TCPSocket.new 'localhost', 29929
+    handshake = WebSocket::Handshake::Client.new(:url => 'ws://127.0.0.1:29929')
+    client.write handshake.to_s
+    connected = false
+
+    server.run do |client|
+      client.onopen do
+        connected = true
+      end
+    end
+    connected.should == true
+
+    server.stop
+  end
+
+  it 'should send handshake replies to 10 clients' do
+    server = Rubame::Server.new("0.0.0.0", 29929)
+
+    clients = {}
+    finished = false
+
+    Thread.new do
+      while server
+        server.run
+      end
+    end
+
+    sleep(0.3)
+
+    10.times do
+      client = TCPSocket.new 'localhost', 29929
+      handshake = WebSocket::Handshake::Client.new(:url => 'ws://127.0.0.1:29929')
+      clients[client] = handshake
+      client.write handshake.to_s
+      while line = client.gets
+        handshake << line
+        break if handshake.finished?
+      end
+      handshake.finished?.should == true
+    end
+
+    clients.each do |s, h|
+      s.close
+    end
+    server.stop
+    server = nil
+    finished = true
+  end
+
+  it 'should be able to send a message to a client' do
+    server = Rubame::Server.new("0.0.0.0", 29929)
+
+    finished = false
+
+    Thread.new do
+      while server
+        server.run do |client|
+          client.onopen do
+            client.send "Tester"
+          end
+        end
+      end
+    end
+
+    sleep(0.3)
+
+    client = TCPSocket.new 'localhost', 29929
+    handshake = WebSocket::Handshake::Client.new(:url => 'ws://127.0.0.1:29929')
+    client.write handshake.to_s
+    while line = client.gets
+      handshake << line
+      break if handshake.finished?
+    end
+    handshake.finished?.should == true
+
+    frame = WebSocket::Frame::Incoming::Client.new(:version => handshake)
+    waiting = true
+    time_started = Time.now
+    time_passed = 0.0
+    while waiting
+      r, w = IO.select([client], [], nil, 0)
+      time_passed = Time.now - time_started
+      if r
+        r.each do |s|
+          pairs = client.recvfrom(20000)
+          frame << pairs[0]
+          # puts frame.next
+          waiting = false
+        end
+      end
+      waiting = false if time_passed > 4
+    end
+
+    (/Tester/ =~ frame.to_s).class.should eq(Fixnum)
+
+    client.close
+    server.stop
+    server = nil
+    finished = true
+  end
+
+  it 'should send lazy items after immediate ones' do
+    server = Rubame::Server.new("0.0.0.0", 29929)
+
+    finished = false
+
+    Thread.new do
+      while server
+        server.run do |client|
+          client.onopen do
+            (0..3).each do |x|
+              client.lazy_send("#{x}")
+            end
+            client.send("4")
+          end
+        end
+      end
+    end
+
+    sleep(0.3)
+
+    client = TCPSocket.new 'localhost', 29929
+    handshake = WebSocket::Handshake::Client.new(:url => 'ws://127.0.0.1:29929')
+    client.write handshake.to_s
+    while line = client.gets
+      handshake << line
+      break if handshake.finished?
+    end
+    handshake.finished?.should == true
+
+    frame = WebSocket::Frame::Incoming::Client.new(:version => handshake)
+    waiting = true
+    time_started = Time.now
+    time_passed = 0.0
+    while waiting
+      r, w = IO.select([client], [], nil, 0)
+      time_passed = Time.now - time_started
+      if r
+        r.each do |s|
+          pairs = client.recvfrom(20000)
+          frame << pairs[0]
+          # puts frame.next
+          waiting = false if (/.*4.*0.*1.*2.*3.*/ =~ frame.to_s)
+        end
+      end
+      waiting = false if time_passed > 4
+    end
+
+    (/.*4.*0.*1.*2.*3.*/ =~ frame.to_s).class.should eq(Fixnum)
+
+    client.close
+    server.stop
+    server = nil
+    finished = true
+  end
+end
diff --git a/app/server/vendor/rubame/spec/spec_helper.rb b/app/server/vendor/rubame/spec/spec_helper.rb
new file mode 100755
index 0000000..75f62e0
--- /dev/null
+++ b/app/server/vendor/rubame/spec/spec_helper.rb
@@ -0,0 +1,3 @@
+require 'rspec'
+
+require 'rubame'
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/.document b/app/server/vendor/ruby-coreaudio-0.0.11/.document
new file mode 100755
index 0000000..3d618dd
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/.document
@@ -0,0 +1,5 @@
+lib/**/*.rb
+bin/*
+- 
+features/**/*.feature
+LICENSE.txt
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/.gitignore b/app/server/vendor/ruby-coreaudio-0.0.11/.gitignore
new file mode 100755
index 0000000..88b8f9d
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/.gitignore
@@ -0,0 +1,54 @@
+ext/Makefile
+ext/extconf.h
+
+*.gem
+/Gemfile.lock
+
+tmp/
+pkg/
+
+# rcov generated
+coverage
+
+# rdoc generated
+rdoc
+
+# yard generated
+doc/
+.yardoc
+
+# bundler
+.bundle
+lib/bundler/man
+vendor/bundle
+
+# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore: 
+#
+# * Create a file at ~/.gitignore
+# * Include files you want ignored
+# * Run: git config --global core.excludesfile ~/.gitignore
+#
+# After doing this, these files will be ignored in all your git projects,
+# saving you from having to 'pollute' every project you touch with them
+#
+# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
+#
+# For MacOS:
+#
+.DS_Store
+
+# For TextMate
+#*.tmproj
+#tmtags
+
+# For emacs:
+#*~
+#\#*
+#.\#*
+
+# For vim:
+#*.swp
+
+# For redcar:
+#.redcar
+
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/ChangeLog b/app/server/vendor/ruby-coreaudio-0.0.11/ChangeLog
new file mode 100755
index 0000000..6c7837d
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/ChangeLog
@@ -0,0 +1,89 @@
+Wed Jan 14 13:55:46 2015  CHIKANAGA Tomoyuki  <nagachika at ruby-lang.org>
+
+	* examples/set_def_out_sample_rate.rb: add example for set output
+	  device sampling rate. patched by @xavriley
+
+Thu May 15 20:05:15 2014  CHIKANAGA Tomoyuki  <nagachika at ruby-lang.org>
+
+	* release 0.0.10
+	* remove stale dependencies.
+	* add a new feature.
+	  CoreAudio.set_default_output_device - set default output device,
+	  thank to kinushu.
+
+Sat Mar 10 19:16:03 2012  CHIKANAGA Tomoyuki  <nagachika00 at gmail.com>
+
+	* change gem generate tool from jeweler to Bundler.
+
+Tue Mar  6 12:39:59 2012  CHIKANAGA Tomoyuki  <nagachika00 at gmail.com>
+
+	* coreaudio.gemspec: fix dependency. narray should runtime dependency.
+
+	* ext/coreaudio.m (ca_buffer_space): add AudioBuffer#space.
+	  it tells space of ring buffer in frame number.
+
+Tue Mar  6 12:13:01 2012  CHIKANAGA Tomoyuki  <nagachika00 at gmail.com>
+
+	* coreaudio.gemspec: Version bump to 0.0.9.
+
+Fri Feb 24 01:06:20 2012  CHIKANAGA Tomoyuki  <nagachika00 at gmail.com>
+
+	* release 0.0.8
+	  0.0.7 has invalid dependency.
+
+Fri Feb 24 00:47:07 2012  CHIKANAGA Tomoyuki  <nagachika00 at gmail.com>
+
+	* release 0.0.7
+
+	* ext/coreaudio.m (ca_out_buffer_data_append): fix last 1 frame
+	  is overwritten by next buffer's first frame. fixes issue #7.
+	  reported by dturnbull. Thank you!
+
+Fri Feb 23 23:24:00 2012  CHIKANAGA Tomoyuki  <nagachika00 at gmail.com>
+
+	* Gemfile: use 'gemspec'
+	* Gemfile.lock: delete from reository
+	* .gitignore: add Gemfile.lock for ignore list
+	* coreaudio.gemspec: udpate dependent version of jeweler
+
+Fri Nov 25 01:03:49 2011  CHIKANAGA Tomoyuki  <nagachika00 at gmail.com>
+
+	* examples/fft_shift_pitch.rb: ignore first element of fft result.
+
+Tue Nov 22 00:09:30 2011  CHIKANAGA Tomoyuki  <nagachika00 at gmail.com>
+
+	* ext/audiofile.m(ca_audio_file_initialize): convert first argument
+	  to String if necessary.
+
+Sat Nov 12 18:23:10 2011  CHIKANAGA Tomoyuki  <nagachika00 at gmail.com>
+
+	* release 0.0.6
+	* change usage of rb_scan_args() in AudioFile.new. support ruby 1.9.2.
+
+Tue Nov 1 22:01:39 2011  CHIKANAGA Tomoyuki  <nagachika00 at gmail.com>
+
+	* release 0.0.5
+	* fix an error in get name of audio device on some environment.
+	  (use CFStringGetCString() instead of CFStringGetCStringPtr())
+
+Sat Oct 29 00:55:11 2011  CHIKANAGA Tomoyuki  <nagachika00 at gmail.com>
+
+	* release 0.0.4
+	* use NArray for audio data.
+	* rename AudioFile.new option keyword(:channel -> :channels)
+	* add some examples.
+
+Mon Oct 17 01:19:36 2011  CHIKANAGA Tomoyuki  <nagachika00 at gmail.com>
+
+	* release 0.0.2
+	* add CoreAudio::AudioFile, ability to read/write audio file.
+
+Mon Oct 10 23:01:23 2011  CHIKANAGA Tomoyuki  <nagachika00 at gmail.com>
+
+	* release 0.0.2
+	* fix build error with 1.9.2
+
+Sat Oct 8 02:52:38 2011 CHIKANAGA Tomoyuki  <nagachika00 at gmail.com>
+
+	* release 0.0.1
+	* initial release
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/Gemfile b/app/server/vendor/ruby-coreaudio-0.0.11/Gemfile
new file mode 100755
index 0000000..b4e2a20
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/Gemfile
@@ -0,0 +1,3 @@
+source "https://rubygems.org"
+
+gemspec
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/LICENSE.txt b/app/server/vendor/ruby-coreaudio-0.0.11/LICENSE.txt
new file mode 100755
index 0000000..f9e807e
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/LICENSE.txt
@@ -0,0 +1,22 @@
+Copyright (C) 2011 Tomoyuki Chikanaga. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/README.rdoc b/app/server/vendor/ruby-coreaudio-0.0.11/README.rdoc
new file mode 100755
index 0000000..abcc8a3
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/README.rdoc
@@ -0,0 +1,31 @@
+= coreaudio
+
+CoreAudio (Audio Framework of Mac OS X) wrapper library for ruby 1.9
+
+== Features
+* HAL (Hardware Abstraction Layer) wrapper
+* Detect audio devices
+* Get/Set device properties (numbers of channels, sample rate, frame size...)
+* Output audio data (Loop buffer, Stream buffer)
+* Input audio data (Stream buffer)
+* Save audio data to WAV/M4A file (wrapper for ExtAudioFile)
+* Ream audio file (WAV/M4A)
+
+== ToDo
+* Wrapper for AudioUnit/AudioGraph
+
+== Contributing to coreaudio
+
+* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
+* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
+* Fork the project
+* Start a feature/bugfix branch
+* Commit and push until you are happy with your contribution
+* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
+* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
+
+== Copyright
+
+Copyright (c) 2011 CHIKANAGA Tomoyuki. See LICENSE.txt for
+further details.
+
diff --git a/app/server/vendor/ruby-beautify/Rakefile b/app/server/vendor/ruby-coreaudio-0.0.11/Rakefile
similarity index 100%
copy from app/server/vendor/ruby-beautify/Rakefile
copy to app/server/vendor/ruby-coreaudio-0.0.11/Rakefile
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/coreaudio.gemspec b/app/server/vendor/ruby-coreaudio-0.0.11/coreaudio.gemspec
new file mode 100755
index 0000000..0aa6c19
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/coreaudio.gemspec
@@ -0,0 +1,49 @@
+# -*- encoding: utf-8 -*-
+require File.expand_path('../lib/coreaudio/version', __FILE__)
+
+Gem::Specification.new do |gem|
+  gem.required_rubygems_version = Gem::Requirement.new(">= 0") if gem.respond_to? :required_rubygems_version=
+
+  gem.authors       = ["CHIKANAGA Tomoyuki"]
+  gem.email         = ["nagachika00 at gmail.com"]
+  gem.description   = "Mac OS X CoreAudio wrapper library"
+  gem.summary       = "Mac OS X CoreAudio wrapper library"
+  gem.homepage      = "https://github.com/nagachika/ruby-coreaudio"
+
+  gem.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+  gem.files         = `git ls-files`.split("\n")
+  gem.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
+  gem.name          = "coreaudio"
+  gem.require_paths = ["lib"]
+  gem.version       = CoreAudio::VERSION
+
+  gem.extensions = ["ext/extconf.rb"]
+  gem.extra_rdoc_files = [
+    "ChangeLog",
+    "LICENSE.txt",
+    "README.rdoc"
+  ]
+  gem.licenses = ["BSDL"]
+
+  if gem.respond_to? :specification_version then
+    gem.specification_version = 3
+
+    if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+      gem.add_runtime_dependency(%q<narray>, ["~> 0.6.0.0"])
+      gem.add_development_dependency(%q<bundler>, [">= 0"])
+      gem.add_development_dependency(%q<rake>, [">= 0"])
+      gem.add_development_dependency(%q<rdoc>, [">= 0"])
+    else
+      gem.add_dependency(%q<narray>, ["~> 0.6.0.0"])
+      gem.add_dependency(%q<bundler>, [">= 0"])
+      gem.add_dependency(%q<rake>, [">= 0"])
+      gem.add_dependency(%q<rdoc>, [">= 0"])
+    end
+  else
+    gem.add_dependency(%q<narray>, ["~> 0.6.0.0"])
+    gem.add_dependency(%q<bundler>, [">= 0"])
+    gem.add_dependency(%q<rake>, [">= 0"])
+    gem.add_dependency(%q<rdoc>, [">= 0"])
+  end
+end
+
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/examples/.gitignore b/app/server/vendor/ruby-coreaudio-0.0.11/examples/.gitignore
new file mode 100755
index 0000000..66f8ed3
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/examples/.gitignore
@@ -0,0 +1 @@
+/Gemfile.lock
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/examples/Gemfile b/app/server/vendor/ruby-coreaudio-0.0.11/examples/Gemfile
new file mode 100755
index 0000000..ba5cd66
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/examples/Gemfile
@@ -0,0 +1,4 @@
+source "https://rubygems.org"
+
+gem "coreaudio"
+gem "fftw3"
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/examples/convert_wav_to_m4a.rb b/app/server/vendor/ruby-coreaudio-0.0.11/examples/convert_wav_to_m4a.rb
new file mode 100755
index 0000000..1152911
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/examples/convert_wav_to_m4a.rb
@@ -0,0 +1,19 @@
+#!/usr/bin/env ruby
+
+require "coreaudio"
+
+wav = CoreAudio::AudioFile.new("sample.wav", :read)
+
+m4a = CoreAudio::AudioFile.new("sample.m4a", :write, :format => :m4a,
+                               :rate => wav.rate,
+                               :channels => wav.channels)
+
+loop do
+  buf = wav.read(1024)
+  break if buf.nil?
+  m4a.write(buf)
+end
+
+wav.close
+m4a.close
+
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/examples/fft_shift_pitch.rb b/app/server/vendor/ruby-coreaudio-0.0.11/examples/fft_shift_pitch.rb
new file mode 100755
index 0000000..ba41dc5
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/examples/fft_shift_pitch.rb
@@ -0,0 +1,47 @@
+
+require "thread"
+require "fftw3"
+require "coreaudio"
+
+Thread.abort_on_exception = true
+
+inbuf = CoreAudio.default_input_device.input_buffer(1024)
+outbuf = CoreAudio.default_output_device.output_buffer(1024)
+
+queue = Queue.new
+pitch_shift_th = Thread.start do
+  while w = queue.pop
+    half = w.shape[1] / 2
+    f = FFTW3.fft(w, 1)
+    shift = 12
+    f.shape[0].times do |ch|
+      f[ch, (shift+1)...half] = f[ch, 1...(half-shift)]
+      f[ch, 1..shift] = 0
+      f[ch, (half+1)...(w.shape[1]-shift)] = f[ch, (half+shift+1)..-1]
+      f[ch, -shift..-1] = 0
+    end
+    outbuf << FFTW3.ifft(f, 1) / w.shape[1]
+  end
+end
+
+th = Thread.start do
+  loop do
+    wav = inbuf.read(1024)
+    queue.push(wav)
+  end
+end
+
+inbuf.start
+outbuf.start
+$stdout.print "loopback..."
+$stdout.flush
+sleep 10;
+queue.push(nil)
+inbuf.stop
+outbuf.stop
+$stdout.puts "done."
+th.kill.join
+pitch_shift_th.kill.join
+
+puts "#{inbuf.dropped_frame} frame dropped at input buffer."
+puts "#{outbuf.dropped_frame} frame dropped at output buffer."
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/examples/loopback_delay.rb b/app/server/vendor/ruby-coreaudio-0.0.11/examples/loopback_delay.rb
new file mode 100755
index 0000000..4ee03f6
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/examples/loopback_delay.rb
@@ -0,0 +1,30 @@
+
+require "coreaudio"
+
+inbuf = CoreAudio.default_input_device.input_buffer(1024)
+outbuf = CoreAudio.default_output_device.output_buffer(1024)
+
+th = Thread.start do
+  ary = []
+  loop do
+    wav = inbuf.read(1024)
+    ary.push(wav)
+    # 1024*43 frames delayed. about 1 sec when sample rate = 44100Hz
+    if ary.size > 43
+      outbuf << ary.shift
+    end
+  end
+end
+
+inbuf.start
+outbuf.start
+$stdout.print "loopback..."
+$stdout.flush
+sleep 10;
+inbuf.stop
+outbuf.stop
+$stdout.puts "done."
+th.kill.join
+
+puts "#{inbuf.dropped_frame} frame dropped at input buffer."
+puts "#{outbuf.dropped_frame} frame dropped at output buffer."
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/examples/outbuffer_sine.rb b/app/server/vendor/ruby-coreaudio-0.0.11/examples/outbuffer_sine.rb
new file mode 100755
index 0000000..b7d17d3
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/examples/outbuffer_sine.rb
@@ -0,0 +1,23 @@
+require "coreaudio"
+
+dev = CoreAudio.default_output_device
+buf = dev.output_buffer(1024)
+
+phase = Math::PI * 2.0 * 440.0 / dev.nominal_rate
+th = Thread.start do
+  i = 0
+  wav = NArray.sint(1024)
+  loop do
+    1024.times {|j| wav[j] = (0.4 * Math.sin(phase*(i+j)) * 0x7FFF).round }
+    i += 1024
+    buf << wav
+  end
+end
+
+buf.start
+sleep 2
+buf.stop
+
+puts "#{buf.dropped_frame} frame dropped."
+
+th.kill.join
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/examples/outloop_sine.rb b/app/server/vendor/ruby-coreaudio-0.0.11/examples/outloop_sine.rb
new file mode 100755
index 0000000..e97e634
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/examples/outloop_sine.rb
@@ -0,0 +1,14 @@
+require "coreaudio"
+
+dev = CoreAudio.default_output_device
+buf = dev.output_loop(44000)
+
+phase = Math::PI * 2.0 * 440.0 / 44000.0
+44000.times do |i|
+  buf[i] = ((0.4 * Math.sin(phase*i)) * 0x7FFF).round
+end
+
+buf.start
+sleep 2
+buf.stop
+
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/examples/record_to_wave.rb b/app/server/vendor/ruby-coreaudio-0.0.11/examples/record_to_wave.rb
new file mode 100755
index 0000000..4b69c75
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/examples/record_to_wave.rb
@@ -0,0 +1,31 @@
+
+require "coreaudio"
+
+dev = CoreAudio.default_input_device
+buf = dev.input_buffer(1024)
+
+wav = CoreAudio::AudioFile.new("sample.wav", :write, :format => :wav,
+                               :rate => dev.nominal_rate,
+                               :channels => dev.input_stream.channels)
+
+samples = 0
+th = Thread.start do
+  loop do
+    w = buf.read(4096)
+    samples += w.size / dev.input_stream.channels
+    wav.write(w)
+  end
+end
+
+buf.start;
+$stdout.print "RECORDING..."
+$stdout.flush
+sleep 5;
+buf.stop
+$stdout.puts "done."
+th.kill.join
+
+wav.close
+
+puts "#{samples} samples read."
+puts "#{buf.dropped_frame} frame dropped."
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/examples/ring_modulator.rb b/app/server/vendor/ruby-coreaudio-0.0.11/examples/ring_modulator.rb
new file mode 100755
index 0000000..9bebcb6
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/examples/ring_modulator.rb
@@ -0,0 +1,42 @@
+
+require "thread"
+require "coreaudio"
+
+Thread.abort_on_exception = true
+
+inbuf = CoreAudio.default_input_device.input_buffer(1024)
+outbuf = CoreAudio.default_output_device.output_buffer(1024)
+
+queue = Queue.new
+output_th = Thread.start do
+  filter = NArray.float(2, 1024)
+  filter.shape[1].times do |i|
+    filter[true, i] = (i % 256 - 128) / 128.0
+  end
+
+  while w = queue.pop
+    outbuf << w * filter
+  end
+end
+
+input_th = Thread.start do
+  loop do
+    wav = inbuf.read(1024)
+    queue.push(wav)
+  end
+end
+
+inbuf.start
+outbuf.start
+$stdout.print "loopback..."
+$stdout.flush
+sleep 10;
+queue.push(nil)
+inbuf.stop
+outbuf.stop
+$stdout.puts "done."
+input_th.kill.join
+output_th.kill.join
+
+puts "#{inbuf.dropped_frame} frame dropped at input buffer."
+puts "#{outbuf.dropped_frame} frame dropped at output buffer."
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/examples/set_def_out_dev.rb b/app/server/vendor/ruby-coreaudio-0.0.11/examples/set_def_out_dev.rb
new file mode 100755
index 0000000..78d3918
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/examples/set_def_out_dev.rb
@@ -0,0 +1,22 @@
+require "coreaudio"
+
+# Select option name device as default output device 
+def set_interface(name)
+	if !name
+		puts 'please enter audio output interface name.'
+		return -1
+	end
+
+	devs = CoreAudio.devices
+
+	tgt = devs.find{|dev| dev.name.index(name)}
+	if !tgt
+		p "no match interface #{name}"
+		return -1
+	end
+
+	CoreAudio.set_default_output_device(tgt)
+	p "select default output audio interface #{tgt.name}"
+end
+
+set_interface(ARGV[0])
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/examples/set_def_out_sample_rate.rb b/app/server/vendor/ruby-coreaudio-0.0.11/examples/set_def_out_sample_rate.rb
new file mode 100755
index 0000000..241d702
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/examples/set_def_out_sample_rate.rb
@@ -0,0 +1,16 @@
+require "coreaudio"
+
+# Select option name device as default output device
+def set_nominal_rate(rate)
+  available_rates = CoreAudio.default_output_device.available_sample_rate.flatten.uniq
+  rate = rate.to_f
+  if (!rate || !available_rates.member?(rate))
+    puts "Please enter a valid sample rate. Choose one of the following: #{available_rates.join(', ')}"
+    return -1
+  end
+
+  CoreAudio.default_output_device(nominal_rate: rate)
+  puts "Output device sample rate set to #{rate}"
+end
+
+set_nominal_rate(ARGV[0])
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/ext/audiofile.m b/app/server/vendor/ruby-coreaudio-0.0.11/ext/audiofile.m
new file mode 100755
index 0000000..0b65d41
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/ext/audiofile.m
@@ -0,0 +1,442 @@
+#include <stdio.h>
+#include <unistd.h>
+
+#include <Foundation/Foundation.h>
+#include <CoreAudio/CoreAudio.h>
+
+#include <ruby.h>
+
+#include <AudioToolbox/AudioToolbox.h>
+
+#include "coreaudio.h"
+
+
+VALUE rb_cAudioFile;
+
+static VALUE sym_read, sym_write, sym_format;
+static VALUE sym_rate, sym_file_rate, sym_channels, sym_file_channels;
+static VALUE sym_wav, sym_m4a;
+
+static void
+setASBD(AudioStreamBasicDescription *asbd,
+        Float64 rate,
+        UInt32 format,
+        UInt32 flags,
+        UInt32 channels,
+        UInt32 bitsPerChannel,
+        UInt32 framePerPacket)
+{
+    asbd->mSampleRate = rate;
+    asbd->mFormatID = format;
+    asbd->mFormatFlags = flags;
+    asbd->mBitsPerChannel = bitsPerChannel;
+    asbd->mChannelsPerFrame = channels;
+    asbd->mFramesPerPacket = framePerPacket;
+    asbd->mBytesPerFrame = bitsPerChannel/8*channels;
+    asbd->mBytesPerPacket = bitsPerChannel/8*channels*framePerPacket;
+}
+
+typedef struct {
+  AudioStreamBasicDescription file_desc;
+  AudioStreamBasicDescription inner_desc;
+  Boolean                     for_write;
+  ExtAudioFileRef             file;
+} ca_audio_file_t;
+
+static void
+ca_audio_file_free(void *ptr)
+{
+    ca_audio_file_t *data = ptr;
+
+    if ( data->file ) {
+      ExtAudioFileDispose(data->file);
+      data->file = NULL;
+    }
+}
+
+static size_t
+ca_audio_file_memsize(const void *ptr)
+{
+    (void)ptr;
+    return sizeof(ca_audio_file_t);
+}
+
+static const rb_data_type_t ca_audio_file_type = {
+  "ca_audio_file",
+  {NULL, ca_audio_file_free, ca_audio_file_memsize}
+};
+
+static VALUE
+ca_audio_file_alloc(VALUE klass)
+{
+    VALUE obj;
+    ca_audio_file_t *ptr;
+
+    obj = TypedData_Make_Struct(klass, ca_audio_file_t, &ca_audio_file_type, ptr);
+
+    return obj;
+}
+
+static void
+parse_audio_file_options(VALUE opt, Boolean for_write,
+                         Float64 *rate, Float64 *file_rate,
+                         UInt32 *channels, UInt32 *file_channels)
+{
+    if (NIL_P(opt) || NIL_P(rb_hash_aref(opt, sym_rate))) {
+      if (for_write)
+        *rate = 44100.0;
+      else
+        *rate = *file_rate;
+    } else {
+      *rate = NUM2DBL(rb_hash_aref(opt, sym_rate));
+    }
+    if (NIL_P(opt) || NIL_P(rb_hash_aref(opt, sym_channels))) {
+      if (for_write)
+        *channels = 2;
+      else
+        *channels = *file_channels;
+    } else {
+      *channels = NUM2UINT(rb_hash_aref(opt, sym_channels));
+    }
+
+    if (for_write) {
+      if (NIL_P(opt) || NIL_P(rb_hash_aref(opt, sym_file_rate))) {
+        *file_rate = *rate;
+      } else {
+        *file_rate = NUM2DBL(rb_hash_aref(opt, sym_file_rate));
+      }
+      if (NIL_P(opt) || NIL_P(rb_hash_aref(opt, sym_file_channels))) {
+        *file_channels = *channels;
+      } else {
+        *file_channels = NUM2UINT(rb_hash_aref(opt, sym_file_channels));
+      }
+    }
+}
+
+/*
+ * call-seq:
+ *   AudioFile.new(filepath, mode, opt)
+ *
+ * open audio file at +filepath+. +mode+ should be :read or :write
+ * corresponding to file mode argument of Kernel#open.
+ * +opt+ must contain :format key.
+ *
+ * 'client data' means audio data pass to AudioFile#write or from
+ * AudioFile#read method.
+ *
+ * :format :: audio file format. currently audio file format and
+ *            codec type is hardcoded. (:wav, :m4a)
+ * :rate :: sample rate of data pass from AudioFile#read or to AudioFile#write
+ *          If not specified, :file_rate value is used. (Float)
+ * :channels :: number of channels
+ * :file_rate :: file data sample rate. only work when open for output. (Float)
+ * :file_channels :: file data number of channels. only work when open for
+ *                  output.
+ */
+static VALUE
+ca_audio_file_initialize(int argc, VALUE *argv, VALUE self)
+{
+    ca_audio_file_t *data;
+    VALUE path, mode, opt, format;
+    Float64 rate, file_rate;
+    UInt32 channels, file_channels;
+    CFURLRef url = NULL;
+    AudioFileTypeID filetype = 0;
+    OSStatus err = noErr;
+
+    TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, data);
+
+    rb_scan_args(argc, argv, "12", &path, &mode, &opt);
+
+    StringValue(path);
+
+    /* check mode */
+    if (NIL_P(mode) || mode == sym_read)
+      data->for_write = FALSE;
+    else if (mode == sym_write)
+      data->for_write = TRUE;
+    else
+      rb_raise(rb_eArgError, "coreaudio: mode should be :read or :write");
+
+    if (data->for_write) {
+      /* when open for write, parse options before open ExtAudioFile */
+      parse_audio_file_options(opt, data->for_write, &rate, &file_rate,
+                               &channels, &file_channels);
+
+      format = rb_hash_aref(opt, sym_format);
+      if (NIL_P(format))
+        rb_raise(rb_eArgError, "coreaudio: :format option must be specified");
+
+      if (format == sym_wav) {
+        filetype = kAudioFileWAVEType;
+        setASBD(&data->file_desc, file_rate, kAudioFormatLinearPCM,
+                kLinearPCMFormatFlagIsSignedInteger |
+                kAudioFormatFlagIsPacked,
+                file_channels, 16, 1);
+      } else if (format == sym_m4a) {
+        filetype = kAudioFileM4AType;
+        setASBD(&data->file_desc, file_rate, kAudioFormatMPEG4AAC,
+                0, file_channels, 0, 0);
+      } else {
+        volatile VALUE str = rb_inspect(format);
+        RB_GC_GUARD(str);
+        rb_raise(rb_eArgError, "coreaudio: unsupported format (%s)",
+                 RSTRING_PTR(str));
+      }
+    }
+
+    /* create URL represent the target filepath */
+    url = CFURLCreateFromFileSystemRepresentation(
+                NULL, StringValueCStr(path), (CFIndex)RSTRING_LEN(path), FALSE);
+
+    /* open ExtAudioFile */
+    if (data->for_write)
+      err = ExtAudioFileCreateWithURL(url, filetype, &data->file_desc,
+                                      NULL, kAudioFileFlags_EraseFile,
+                                      &data->file);
+    else
+      err = ExtAudioFileOpenURL(url, &data->file);
+    CFRelease(url);
+    url = NULL;
+    if (err != noErr) {
+      rb_raise(rb_eArgError,
+               "coreaudio: fail to open ExtAudioFile: %d", (int)err);
+    }
+
+    /* get Audio Stream Basic Description (ASBD) from input file */
+    if (!data->for_write) {
+      UInt32 size = sizeof(data->file_desc);
+      err = ExtAudioFileGetProperty(data->file,
+                                    kExtAudioFileProperty_FileDataFormat,
+                                    &size, &data->file_desc);
+      if (err != noErr)
+        rb_raise(rb_eRuntimeError,
+                 "coreaudio: fail to Get ExtAudioFile Property %d", err);
+
+      /* parse options */
+      file_rate = data->file_desc.mSampleRate;
+      file_channels = data->file_desc.mChannelsPerFrame;
+      parse_audio_file_options(opt, data->for_write, &rate, &file_rate,
+                               &channels, &file_channels);
+    }
+
+    setASBD(&data->inner_desc, rate, kAudioFormatLinearPCM,
+            kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked,
+            channels, 16, 1);
+
+    err = ExtAudioFileSetProperty(
+            data->file, kExtAudioFileProperty_ClientDataFormat,
+            sizeof(data->inner_desc), &data->inner_desc);
+    if (err != noErr) {
+      ExtAudioFileDispose(data->file);
+      data->file = NULL;
+      rb_raise(rb_eArgError, "coreaudio: fail to set client data format: %d",
+               (int)err);
+    }
+
+    return self;
+}
+
+static VALUE
+ca_audio_file_close(VALUE self)
+{
+    ca_audio_file_t *data;
+
+    TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, data);
+    if (data->file) {
+      ExtAudioFileDispose(data->file);
+      data->file = NULL;
+    }
+
+    return self;
+}
+
+static VALUE
+ca_audio_file_write(VALUE self, VALUE data)
+{
+    ca_audio_file_t *file;
+    UInt32 n_ch;
+    int rank;
+    short *buf = NULL;
+    AudioBufferList buf_list;
+    UInt32 frames;
+    size_t alloc_size;
+    volatile VALUE tmpstr = Qundef;
+    OSStatus err = noErr;
+
+    /* cast to NArray of SINT and check rank of NArray */
+    data = na_cast_object(data, NA_SINT);
+    rank = NA_RANK(data);
+    if (rank > 3)
+      rb_raise(rb_eArgError, "coreaudio: audio buffer rank must be 1 or 2.");
+
+    TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, file);
+
+    if (file->file == NULL)
+      rb_raise(rb_eIOError, "coreaudio: already closed file");
+
+    if (!file->for_write)
+      rb_raise(rb_eRuntimeError, "coreaudio: audio file opened for reading");
+
+    n_ch = file->inner_desc.mChannelsPerFrame;
+
+    if (rank == 2 && NA_SHAPE0(data) != (int)n_ch)
+      rb_raise(rb_eArgError,
+               "coreaudio: audio buffer size of first dimension must be "
+               "equal to number of channels");
+
+    frames = rank == 1 ? NA_SHAPE0(data) : NA_SHAPE1(data);
+    alloc_size = (file->inner_desc.mBitsPerChannel/8) * frames * n_ch;
+
+    /* prepare interleaved audio buffer */
+    buf_list.mNumberBuffers = 1;
+    buf_list.mBuffers[0].mNumberChannels = n_ch;
+    buf_list.mBuffers[0].mDataByteSize = (UInt32)alloc_size;
+
+    if ((rank == 1 && n_ch == 1) || rank == 2) {
+      /* no need to allocate buffer. NArray buffer can be used as mData */
+      buf_list.mBuffers[0].mData = NA_PTR_TYPE(data, void *);
+    } else {
+      UInt32 i, j;
+      short *na_buf = NA_PTR_TYPE(data, short *);
+
+      buf_list.mBuffers[0].mData = rb_alloc_tmp_buffer(&tmpstr, alloc_size);
+      buf = buf_list.mBuffers[0].mData;
+
+      for (i = 0; i < frames; i++) {
+        for (j = 0; j < n_ch; j++) {
+          buf[i*n_ch+j] = na_buf[i];
+        }
+      }
+    }
+
+    err = ExtAudioFileWrite(file->file, frames, &buf_list);
+
+    if (tmpstr != Qundef)
+      rb_free_tmp_buffer(&tmpstr);
+
+    if (err != noErr) {
+      rb_raise(rb_eRuntimeError,
+               "coreaudio: ExtAudioFileWrite() fails: %d", (int)err);
+    }
+
+    return self;
+}
+
+static VALUE
+ca_audio_file_read_frames(VALUE self, VALUE frame_val)
+{
+    ca_audio_file_t *file;
+    UInt32 channels, frames, read_frames;
+    AudioBufferList buf_list;
+    size_t alloc_size;
+    VALUE nary;
+    int shape[2];
+    OSStatus err = noErr;
+
+    frames = NUM2UINT(frame_val);
+
+    TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, file);
+
+    if (file->file == NULL)
+      rb_raise(rb_eIOError, "coreaudio: already closend file");
+
+    if (file->for_write)
+      rb_raise(rb_eRuntimeError, "coreaudio: audio file open for writing");
+
+    channels = file->inner_desc.mChannelsPerFrame;
+
+    shape[0] = channels;
+    shape[1] = frames;
+    nary = na_make_object(NA_SINT, 2, shape, cNArray);
+
+    alloc_size = (file->inner_desc.mBitsPerChannel/8) * channels * frames;
+
+    /* prepare interleaved audio buffer */
+    buf_list.mNumberBuffers = 1;
+    buf_list.mBuffers[0].mNumberChannels = channels;
+    buf_list.mBuffers[0].mDataByteSize = (UInt32)alloc_size;
+    buf_list.mBuffers[0].mData = NA_PTR_TYPE(nary, void *);
+
+    read_frames = frames;
+    err = ExtAudioFileRead(file->file, &read_frames, &buf_list);
+
+    if (err != noErr) {
+      rb_raise(rb_eRuntimeError,
+               "coreaudio: ExtAudioFileRead() fails: %d", (int)err);
+    }
+
+    if (read_frames == 0)
+      return Qnil;
+
+    NA_SHAPE1(nary) = read_frames;
+
+    return nary;
+}
+
+static VALUE
+ca_audio_file_rate(VALUE self)
+{
+    ca_audio_file_t *data;
+
+    TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, data);
+
+    return DBL2NUM(data->file_desc.mSampleRate);
+}
+
+static VALUE
+ca_audio_file_channels(VALUE self)
+{
+    ca_audio_file_t *data;
+
+    TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, data);
+
+    return UINT2NUM((unsigned int)data->file_desc.mChannelsPerFrame);
+}
+
+static VALUE
+ca_audio_file_inner_rate(VALUE self)
+{
+    ca_audio_file_t *data;
+
+    TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, data);
+
+    return DBL2NUM(data->inner_desc.mSampleRate);
+}
+
+static VALUE
+ca_audio_file_inner_channels(VALUE self)
+{
+    ca_audio_file_t *data;
+
+    TypedData_Get_Struct(self, ca_audio_file_t, &ca_audio_file_type, data);
+
+    return UINT2NUM((unsigned int)data->inner_desc.mChannelsPerFrame);
+}
+
+void
+Init_coreaudio_audiofile(void)
+{
+    sym_read = ID2SYM(rb_intern("read"));
+    sym_write = ID2SYM(rb_intern("write"));
+    sym_format = ID2SYM(rb_intern("format"));
+    sym_rate = ID2SYM(rb_intern("rate"));
+    sym_file_rate = ID2SYM(rb_intern("file_rate"));
+    sym_channels = ID2SYM(rb_intern("channels"));
+    sym_file_channels = ID2SYM(rb_intern("file_channels"));
+    sym_wav = ID2SYM(rb_intern("wav"));
+    sym_m4a = ID2SYM(rb_intern("m4a"));
+
+    rb_cAudioFile = rb_define_class_under(rb_mCoreAudio, "AudioFile",
+                                          rb_cObject);
+
+    rb_define_alloc_func(rb_cAudioFile, ca_audio_file_alloc);
+    rb_define_method(rb_cAudioFile, "initialize", ca_audio_file_initialize, -1);
+    rb_define_method(rb_cAudioFile, "close", ca_audio_file_close, 0);
+    rb_define_method(rb_cAudioFile, "write", ca_audio_file_write, 1);
+    rb_define_method(rb_cAudioFile, "read_frames", ca_audio_file_read_frames, 1);
+    rb_define_method(rb_cAudioFile, "rate", ca_audio_file_rate, 0);
+    rb_define_method(rb_cAudioFile, "channels", ca_audio_file_channels, 0);
+    rb_define_method(rb_cAudioFile, "inner_rate", ca_audio_file_inner_rate, 0);
+    rb_define_method(rb_cAudioFile, "inner_channels", ca_audio_file_inner_channels, 0);
+}
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/ext/coreaudio.h b/app/server/vendor/ruby-coreaudio-0.0.11/ext/coreaudio.h
new file mode 100755
index 0000000..288ae66
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/ext/coreaudio.h
@@ -0,0 +1,30 @@
+#ifndef COREAUDIO_H
+#define COREAUDIO_H 1
+
+#include <ruby.h>
+
+#include "narray.h"
+#include "extconf.h"
+
+extern VALUE rb_mCoreAudio;
+extern VALUE rb_mAudioFile;
+
+extern void Init_coreaudio_audiofile(void);
+
+/*-- Utility Macros --*/
+#define CROPF(F) ((F) > 1.0 ? 1.0 : (((F) < -1.0) ? -1.0 : (F)))
+#define FLOAT2SHORT(F) ((short)(CROPF(F)*0x7FFF))
+#define SHORT2FLOAT(S) ((float)(S) / (float)32767.0)
+
+/*-- prototypes for missing functions --*/
+
+#ifndef HAVE_RB_ALLOC_TMP_BUFFER
+extern void *rb_alloc_tmp_buffer(volatile VALUE *store, long len);
+#endif
+
+#ifndef HAVE_RB_FREE_TMP_BUFFER
+extern void rb_free_tmp_buffer(volatile VALUE *store);
+#endif
+
+
+#endif
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/ext/coreaudio.m b/app/server/vendor/ruby-coreaudio-0.0.11/ext/coreaudio.m
new file mode 100755
index 0000000..237b992
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/ext/coreaudio.m
@@ -0,0 +1,1178 @@
+#include <stdio.h>
+#include <unistd.h>
+
+#include <pthread.h>
+
+#include <Foundation/Foundation.h>
+#include <CoreAudio/CoreAudio.h>
+
+#include <ruby.h>
+
+#include "coreaudio.h"
+
+VALUE rb_mCoreAudio;
+
+static VALUE rb_cAudioDevice;
+static VALUE rb_cAudioStream;
+static VALUE rb_cOutLoop;
+static VALUE rb_cAudioBuffer;
+static VALUE rb_cOutputBuffer;
+static VALUE rb_cInputBuffer;
+static ID sym_iv_devid;
+static ID sym_iv_name;
+static ID sym_iv_available_sample_rate;
+static ID sym_iv_nominal_rate;
+static ID sym_iv_input_stream;
+static ID sym_iv_output_stream;
+static ID sym_iv_channels;
+static ID sym_iv_buffer_frame_size;
+
+/* utility macro */
+#define PropertyAddress { \
+  .mScope = kAudioObjectPropertyScopeGlobal,    \
+  .mElement = kAudioObjectPropertyElementMaster \
+}
+
+/*--- CoreAudio::AudioStream ---*/
+static VALUE
+ca_get_stream_channel_num(AudioDeviceID devID,
+                          AudioObjectPropertyScope scope)
+{
+    AudioObjectPropertyAddress address = PropertyAddress;
+    UInt32 size;
+    AudioChannelLayout *layout;
+    OSStatus status;
+    UInt32 ch_num;
+
+    address.mSelector = kAudioDevicePropertyPreferredChannelLayout;
+    address.mScope = scope;
+    if (!AudioObjectHasProperty(devID, &address))
+      return INT2NUM(0);
+
+    status = AudioObjectGetPropertyDataSize(devID, &address, 0, NULL, &size);
+
+    if (status != noErr) {
+      rb_raise(rb_eArgError,
+               "coreaudio: get preferred channel layout size failed: %d", status);
+    }
+
+    layout = alloca(size);
+
+    status = AudioObjectGetPropertyData(devID, &address, 0, NULL, &size, layout);
+    if (status != noErr) {
+      rb_raise(rb_eArgError,
+               "coreaudio: get preferred channel layout failed: %d", status);
+    }
+
+    if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions) {
+      ch_num = layout->mNumberChannelDescriptions;
+    } else if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap) {
+      UInt32 i;
+      ch_num = 0;
+      for ( i = 0; i < sizeof(layout->mChannelBitmap)*8; i++ ) {
+        if ( (layout->mChannelBitmap >> i) & 0x01 )
+          ch_num++;
+      }
+    } else {
+      ch_num = AudioChannelLayoutTag_GetNumberOfChannels(layout->mChannelLayoutTag);
+    }
+    return UINT2NUM(ch_num);
+}
+
+static VALUE
+ca_get_stream_buffer_frame(AudioDeviceID devID, AudioObjectPropertyScope scope)
+{
+    AudioObjectPropertyAddress address = PropertyAddress;
+    UInt32 size, framesize;
+    OSStatus status;
+
+    address.mSelector = kAudioDevicePropertyBufferFrameSize;
+    address.mScope = scope;
+
+    if (!AudioObjectHasProperty(devID, &address))
+      return INT2NUM(0);
+
+    size = sizeof(framesize);
+    status = AudioObjectGetPropertyData(devID, &address, 0, NULL, &size, &framesize);
+    if (status != noErr) {
+      rb_raise(rb_eArgError,
+               "coreaudio: get buffer frame size failed: %d", status);
+    }
+    return UINT2NUM(framesize);
+}
+
+static VALUE
+ca_stream_initialize(VALUE self, VALUE devid_val, VALUE is_input)
+{
+    AudioDeviceID devID = (AudioDeviceID)NUM2UINT(devid_val);
+    AudioObjectPropertyScope scope;
+
+    if (RTEST(is_input))
+      scope = kAudioDevicePropertyScopeInput;
+    else
+      scope = kAudioDevicePropertyScopeOutput;
+    rb_ivar_set(self, sym_iv_channels, ca_get_stream_channel_num(devID, scope));
+    rb_ivar_set(self, sym_iv_buffer_frame_size, ca_get_stream_buffer_frame(devID, scope));
+
+    return self;
+}
+
+static VALUE
+ca_stream_new(VALUE devid, VALUE is_input)
+{
+    VALUE stream;
+    stream = rb_obj_alloc(rb_cAudioStream);
+    ca_stream_initialize(stream, devid, is_input);
+    return stream;
+}
+
+/*--- CoreAudio::AudioDevice ---*/
+static VALUE
+ca_get_device_name(AudioDeviceID devID)
+{
+    AudioObjectPropertyAddress address = PropertyAddress;
+    UInt32 size;
+    OSStatus status;
+    CFStringRef deviceName = NULL;
+    char cbuf[256];
+    VALUE str;
+
+    address.mSelector = kAudioObjectPropertyName;
+    size = sizeof(deviceName);
+
+    status = AudioObjectGetPropertyData(devID, &address, 0, NULL, &size, &deviceName);
+    if ( status != noErr ) {
+      rb_raise(rb_eArgError, "coreaudio: get device name failed: %d", status);
+    }
+    if (!CFStringGetCString(deviceName, cbuf, (CFIndex)sizeof(cbuf),
+                            kCFStringEncodingUTF8)) {
+      /* String conversion failed. Ignore an error and return empty String */
+      cbuf[0] = '\0';
+    }
+    CFRelease(deviceName);
+    str = rb_str_new2(cbuf);
+
+    return str;
+}
+
+static VALUE
+ca_get_device_available_sample_rate(AudioDeviceID devID)
+{
+    AudioObjectPropertyAddress address = PropertyAddress;
+    UInt32 size;
+    UInt32 n_rates;
+    AudioValueRange *sample_rates;
+    OSStatus status;
+    VALUE ary;
+    UInt32 i;
+
+    address.mSelector = kAudioDevicePropertyAvailableNominalSampleRates;
+    status = AudioObjectGetPropertyDataSize(devID, &address, 0, NULL, &size);
+
+    if (status != noErr) {
+      rb_raise(rb_eArgError,
+               "coreaudio: get available sample rates size failed: %d", status);
+    }
+
+    n_rates = size / (UInt32)sizeof(AudioValueRange);
+    sample_rates = ALLOCA_N(AudioValueRange, n_rates);
+
+    status = AudioObjectGetPropertyData(devID, &address, 0, NULL, &size, sample_rates);
+    if (status != noErr) {
+      rb_raise(rb_eArgError,
+               "coreaudio: get available sample rates failed: %d", status);
+    }
+
+    ary = rb_ary_new();
+    for ( i = 0; i < n_rates; i++ ) {
+      rb_ary_push(ary,
+                  rb_ary_new3(2,
+                              DBL2NUM((double)sample_rates[i].mMinimum),
+                              DBL2NUM((double)sample_rates[i].mMaximum)));
+    }
+
+    return ary;
+}
+
+static VALUE
+ca_set_device_nominal_sample_rate(AudioDeviceID devID, VALUE sampleRateVal)
+{
+    AudioObjectPropertyAddress address = PropertyAddress;
+    UInt32 size;
+    OSStatus status;
+    Float64 rate = NUM2DBL(sampleRateVal);
+
+    address.mSelector = kAudioDevicePropertyNominalSampleRate;
+    status = AudioObjectGetPropertyDataSize(devID, &address, 0, NULL, &size);
+
+    if (status != noErr) {
+      rb_raise(rb_eArgError,
+               "coreaudio: get nominal sample rates size failed: %d", status);
+    }
+    status = AudioObjectSetPropertyData(devID, &address, 0, NULL, size, &rate);
+    if (status != noErr) {
+      rb_raise(rb_eArgError,
+               "coreaudio: set nominal sample rates failed: %d", status);
+    }
+    return sampleRateVal;
+}
+
+static VALUE
+ca_get_device_nominal_sample_rate(AudioDeviceID devID)
+{
+    AudioObjectPropertyAddress address = PropertyAddress;
+    UInt32 size;
+    Float64 rate;
+    OSStatus status;
+
+    address.mSelector = kAudioDevicePropertyNominalSampleRate;
+    status = AudioObjectGetPropertyDataSize(devID, &address, 0, NULL, &size);
+
+    if (status != noErr) {
+      rb_raise(rb_eArgError,
+               "coreaudio: get nominal sample rates size failed: %d", status);
+    }
+
+    status = AudioObjectGetPropertyData(devID, &address, 0, NULL, &size, &rate);
+    if (status != noErr) {
+      rb_raise(rb_eArgError,
+               "coreaudio: get nominal sample rates failed: %d", status);
+    }
+    return DBL2NUM((double)rate);
+}
+
+static VALUE
+ca_get_device_actual_sample_rate(VALUE self)
+{
+    AudioDeviceID devID = NUM2UINT(rb_ivar_get(self, sym_iv_devid));
+    AudioObjectPropertyAddress address = PropertyAddress;
+    UInt32 size;
+    Float64 rate;
+    OSStatus status;
+
+    address.mSelector = kAudioDevicePropertyActualSampleRate;
+    status = AudioObjectGetPropertyDataSize(devID, &address, 0, NULL, &size);
+
+    size = sizeof(rate);
+    status = AudioObjectGetPropertyData(devID, &address, 0, NULL, &size, &rate);
+    if (status != noErr) {
+      rb_raise(rb_eArgError,
+               "coreaudio: get actual sample rates failed: %d", status);
+    }
+    return DBL2NUM((double)rate);
+}
+
+static VALUE
+ca_device_initialize(VALUE self, VALUE devIdVal, VALUE options)
+{
+    AudioDeviceID devID = (AudioDeviceID)NUM2LONG(devIdVal);
+    VALUE device_name;
+    VALUE available_sample_rate;
+    VALUE nominal_rate;
+    VALUE input_stream, output_stream;
+    VALUE option_nominal_rate;
+
+    device_name = ca_get_device_name(devID);
+    available_sample_rate = ca_get_device_available_sample_rate(devID);
+    rb_obj_freeze(available_sample_rate);
+
+    if (options != Qnil) {
+      option_nominal_rate = rb_funcall(options, rb_intern("[]"), 1, ID2SYM(rb_intern("nominal_rate")));
+      if (option_nominal_rate != Qnil) {
+        nominal_rate = ca_set_device_nominal_sample_rate(devID, option_nominal_rate);
+      }
+    } else {
+      nominal_rate = ca_get_device_nominal_sample_rate(devID);
+    }
+
+    input_stream = ca_stream_new(devIdVal, Qtrue);
+    output_stream = ca_stream_new(devIdVal, Qfalse);
+
+    rb_ivar_set(self, sym_iv_devid, devIdVal);
+    rb_ivar_set(self, sym_iv_name, device_name);
+    rb_ivar_set(self, sym_iv_available_sample_rate, available_sample_rate);
+    rb_ivar_set(self, sym_iv_nominal_rate, nominal_rate);
+    rb_ivar_set(self, sym_iv_input_stream, input_stream);
+    rb_ivar_set(self, sym_iv_output_stream, output_stream);
+
+    return self;
+}
+
+static VALUE
+ca_device_new(AudioDeviceID devid, VALUE options)
+{
+    VALUE devIdVal = UINT2NUM(devid);
+    VALUE device;
+
+    device = rb_obj_alloc(rb_cAudioDevice);
+    ca_device_initialize(device, devIdVal, options);
+
+    return device;
+}
+
+/*
+ * Document-method: CoreAudio.devices
+ * call-seq:
+ *   CoreAudio.devices(options = nil)
+ *
+ * Get available all audio devices (CoreAudio::AudioDevice object).
+ * if options[:nominal_rate] is given, set device nominal rate as given one.
+ */
+static VALUE
+ca_devices(int argc, VALUE *argv, VALUE mod)
+{
+    AudioObjectPropertyAddress address = PropertyAddress;
+    AudioDeviceID *devIDs = NULL;
+    UInt32 size = 0, devnum = 0;
+    OSStatus status = noErr;
+    VALUE ary;
+    UInt32 i;
+    VALUE options;
+
+    rb_scan_args(argc, argv, "01", &options);
+
+    address.mSelector = kAudioHardwarePropertyDevices;
+
+    status = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
+                                            &address, 0, NULL, &size);
+    if (status != noErr)
+      rb_raise(rb_eRuntimeError, "coreaudio: get devices size failed: %d", status);
+
+    devnum = size / (UInt32)sizeof(AudioDeviceID);
+    devIDs = ALLOCA_N(AudioDeviceID, devnum);
+
+    status = AudioObjectGetPropertyData(kAudioObjectSystemObject,
+                                        &address, 0, NULL, &size, devIDs);
+    if (status != noErr)
+      rb_raise(rb_eRuntimeError, "coreaudio: get devices failed: %d", status);
+
+    ary = rb_ary_new();
+    for (i = 0; i < devnum; i++) {
+      rb_ary_push(ary, ca_device_new(devIDs[i], options));
+    }
+    return ary;
+}
+
+/*
+ * Document-method: CoreAudio.default_input_device
+ * call-seq:
+ *   CoreAudio.default_input_device(options = nil)
+ *
+ * Get system default audio input device as CoreAudio::AudioDevice object.
+ * if options[:nominal_rate] is given, set device nominal rate as given one.
+ */
+static VALUE
+ca_default_input_device(int argc, VALUE *argv, VALUE mod)
+{
+    AudioDeviceID devID;
+    AudioObjectPropertyAddress address = PropertyAddress;
+    UInt32 size;
+    OSStatus status;
+    VALUE options;
+
+    rb_scan_args(argc, argv, "01", &options);
+
+    address.mSelector = kAudioHardwarePropertyDefaultInputDevice;
+    size = sizeof(devID);
+
+    status = AudioObjectGetPropertyData(kAudioObjectSystemObject,
+                                        &address, 0, NULL, &size, &devID);
+
+    if (status != noErr)
+      rb_raise(rb_eArgError, "coreaudio: get default input device failed: %d", status);
+
+    return ca_device_new(devID, options);
+}
+
+
+/*
+ * Document-method: CoreAudio.default_output_device
+ * call-seq:
+ *   CoreAudio.default_output_device(options = nil)
+ *
+ * Get system default audio output device as CoreAudio::AudioDevice object.
+ * if options[:nominal_rate] is given, set device nominal rate as given one.
+ */
+static VALUE
+ca_default_output_device(int argc, VALUE *argv, VALUE mod)
+{
+    AudioDeviceID devID;
+    AudioObjectPropertyAddress address = PropertyAddress;
+    UInt32 size;
+    OSStatus status;
+    VALUE options;
+
+    rb_scan_args(argc, argv, "01", &options);
+
+    address.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
+    size = sizeof(devID);
+
+    status = AudioObjectGetPropertyData(kAudioObjectSystemObject,
+                                        &address, 0, NULL, &size, &devID);
+
+    if (status != noErr)
+      rb_raise(rb_eArgError, "coreaudio: get default output device failed: %d", status);
+
+    return ca_device_new(devID, options);
+}
+
+/*
+ * Document-method: CoreAudio.set_default_output_device
+ * call-seq:
+ *   CoreAudio.set_default_output_device(audio_device)
+ *
+ * Set system default audio output device as CoreAudio::AudioDevice object.
+ */
+static VALUE
+ca_set_default_output_device(VALUE self, VALUE device)
+{
+    AudioDeviceID devID = NUM2UINT(rb_ivar_get(device, sym_iv_devid));    
+    AudioObjectPropertyAddress address = PropertyAddress;
+    UInt32 size;
+    OSStatus status;
+
+    address.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
+    address.mScope    = kAudioObjectPropertyScopeGlobal;
+    address.mElement  = kAudioObjectPropertyElementMaster;
+
+    status = AudioObjectSetPropertyData(kAudioObjectSystemObject, &address, 0, NULL, sizeof(devID), &devID);
+    if (status != noErr) {
+      rb_raise(rb_eArgError,
+               "coreaudio: set default output deveice failed: %d", status);
+    }
+
+    return Qtrue;
+}
+
+/*
+ * Document-class: CoreAudio::OutLoop
+ *
+ * CoreAudio::OutLoop is an class for loop waveform to output audio stream.
+ */
+typedef struct {
+  AudioDeviceID       devID;
+  AudioDeviceIOProcID procID;
+  UInt32              frame;
+  UInt32              channels;
+  short               *buf;
+} ca_out_loop_data;
+
+static void
+ca_out_loop_data_free(void *ptr)
+{
+    if (ptr) {
+      ca_out_loop_data *data = ptr;
+      if (data->procID)
+        AudioDeviceDestroyIOProcID(data->devID, data->procID);
+      if (data->buf)
+        free(data->buf);
+      free(ptr);
+    }
+}
+
+static size_t
+ca_out_loop_data_memsize(const void *ptr)
+{
+    const ca_out_loop_data *data = ptr;
+    return sizeof(ca_out_loop_data) + data->channels * data->frame * sizeof(short);
+}
+
+static const rb_data_type_t ca_out_loop_data_type = {
+  "ca_out_loop_data",
+  {NULL, ca_out_loop_data_free, ca_out_loop_data_memsize},
+};
+
+static OSStatus
+ca_out_loop_proc(
+        AudioDeviceID           inDevice,
+        const AudioTimeStamp*   inNow,
+        const AudioBufferList*  inInputData,
+        const AudioTimeStamp*   inInputTime,
+        AudioBufferList*        outOutputData,
+        const AudioTimeStamp*   inOutputTime,
+        void*                   inClientData)
+{
+    NSUInteger i;
+    UInt32 buffers = outOutputData->mNumberBuffers;
+    ca_out_loop_data *loop_data = inClientData;
+    UInt32 channels = loop_data->channels;
+
+    for (i = 0; i < buffers; i++) {
+      float *ptr = outOutputData->mBuffers[i].mData;
+      UInt32 size = outOutputData->mBuffers[i].mDataByteSize / (UInt32)sizeof(float) / channels;
+      UInt32 offset = (UInt32)inOutputTime->mSampleTime % loop_data->frame;
+      UInt32 copied = 0;
+
+      if (outOutputData->mBuffers[i].mNumberChannels != channels) {
+        memset(ptr, 0, size * channels * sizeof(float));
+        continue;
+      }
+
+      while ( copied < size ) {
+        UInt32 len = loop_data->frame - offset;
+        UInt32 j;
+        if ( len > size - copied )
+          len = size - copied;
+        for (j = 0; j < len*channels; j++) {
+          ptr[copied*channels+j] = SHORT2FLOAT(loop_data->buf[offset*channels+j]);
+        }
+        offset = (offset + len) % loop_data->frame;
+        copied += len;
+      }
+    }
+
+    return 0;
+}
+
+static VALUE
+ca_out_loop_data_alloc(VALUE klass)
+{
+    VALUE obj;
+    ca_out_loop_data *ptr;
+
+    obj = TypedData_Make_Struct(klass, ca_out_loop_data, &ca_out_loop_data_type, ptr);
+    return obj;
+}
+
+static VALUE
+ca_out_loop_data_initialize(VALUE self, VALUE devID, VALUE frame, VALUE channels)
+{
+    ca_out_loop_data *data;
+    OSStatus status;
+
+    TypedData_Get_Struct(self, ca_out_loop_data, &ca_out_loop_data_type, data);
+    data->devID = NUM2UINT(devID);
+    status = AudioDeviceCreateIOProcID(data->devID, ca_out_loop_proc, data, &data->procID);
+    if ( status != noErr )
+    {
+      rb_raise(rb_eRuntimeError, "coreaudio: create proc ID fail: %d", status);
+    }
+    data->frame = NUM2UINT(frame);
+    data->channels = NUM2UINT(channels);
+    data->buf = malloc(sizeof(short)*data->frame*data->channels);
+    if (data->buf == NULL)
+      rb_raise(rb_eNoMemError, "coreaudio: fail to alloc out loop data buffer");
+    return self;
+}
+
+/*
+ * Document-method: CoreAudio::AudioDevice#out_loop
+ * call-seq:
+ *   device.out_loop(frame)
+ *
+ * Create output audio loop buffer.
+ *
+ * == Parameters
+ * * +frame+ is an integer value indicate loop buffer size in number of
+ *   sample/frame. The number of channel is considered automatically.
+ */
+static VALUE
+ca_device_create_out_loop_proc(VALUE self, VALUE frame)
+{
+    VALUE proc;
+    VALUE out_stream = rb_ivar_get(self, sym_iv_output_stream);
+
+    proc = ca_out_loop_data_alloc(rb_cOutLoop);
+    ca_out_loop_data_initialize(proc, rb_ivar_get(self, sym_iv_devid), frame,
+                                rb_ivar_get(out_stream, sym_iv_channels));
+    return proc;
+}
+
+/*
+ * call-seq:
+ *   outloop.start
+ *
+ * Start play of output audio loop.
+ */
+static VALUE
+ca_out_loop_data_start(VALUE self)
+{
+    ca_out_loop_data *data;
+    OSStatus status;
+
+    TypedData_Get_Struct(self, ca_out_loop_data, &ca_out_loop_data_type, data);
+
+    status = AudioDeviceStart(data->devID, data->procID);
+    if ( status != noErr )
+    {
+      rb_raise(rb_eRuntimeError, "coreaudio: audio device start fail: %d", status);
+    }
+    return self;
+}
+
+/*
+ * call-seq:
+ *   outloop.stop
+ *
+ * Stop play of output audio loop.
+ */
+static VALUE
+ca_out_loop_data_stop(VALUE self)
+{
+    ca_out_loop_data *data;
+    OSStatus status;
+
+    TypedData_Get_Struct(self, ca_out_loop_data, &ca_out_loop_data_type, data);
+
+    status = AudioDeviceStop(data->devID, data->procID);
+    if ( status != noErr )
+    {
+      rb_raise(rb_eRuntimeError, "coreaudio: audio device stop fail: %d", status);
+    }
+    return self;
+}
+
+/*
+ * call-seq:
+ *   outloop[frame] = sample
+ *   outloop[frame] = [sample1, sample2]
+ *
+ * Assign audio loop buffer frame value.
+ * If assigned value is an Fixnum (-32767..32767, signed 16bit),
+ * the value is stored to all channels.
+ * The +sample+ should be normalize to -32767 <= sample <= 32767 range.
+ * If assigned value is an Array of Fixnum, each value is stored to each
+ * correponding channel. If size of array is not equal to the AudioDevice's
+ * output stream channel number, raise ArgumentError.
+ */
+static VALUE
+ca_out_loop_data_assign(VALUE self, VALUE index, VALUE val)
+{
+    ca_out_loop_data *data;
+    size_t idx;
+    UInt32 i;
+
+    TypedData_Get_Struct(self, ca_out_loop_data, &ca_out_loop_data_type, data);
+
+    idx = NUM2UINT(index) % data->frame;
+    if (TYPE(val) == T_ARRAY) {
+      if (RARRAY_LEN(val) != data->channels) {
+        rb_raise(rb_eArgError, "size of array and channel size mismatch");
+      }
+      for (i = 0; i < data->channels; i++) {
+        data->buf[idx*data->channels+i] = (short)NUM2INT(RARRAY_PTR(val)[i]);
+      }
+    } else {
+      for (i = 0; i < data->channels; i++) {
+        data->buf[idx*data->channels+i] = (short)NUM2INT(val);
+      }
+    }
+    return val;
+}
+
+typedef struct {
+  AudioDeviceID       devID;
+  AudioDeviceIOProcID procID;
+  UInt32              frame;
+  UInt32              channels;
+  short               *buf;
+  UInt32              start;
+  UInt32              end;
+  long                dropped_frame;
+  pthread_mutex_t     mutex;
+  pthread_cond_t      cond;
+} ca_buffer_data;
+
+static void
+ca_buffer_data_free(void *ptr)
+{
+    if (ptr) {
+      ca_buffer_data *data = ptr;
+      if (data->procID)
+        AudioDeviceDestroyIOProcID(data->devID, data->procID);
+      pthread_cond_destroy(&data->cond);
+      pthread_mutex_destroy(&data->mutex);
+      if (data->buf)
+        free(data->buf);
+      free(ptr);
+    }
+}
+
+static size_t
+ca_buffer_data_memsize(const void *ptr)
+{
+    const ca_buffer_data *data = ptr;
+    return sizeof(ca_buffer_data) + data->channels * data->frame * sizeof(short);
+}
+
+static const rb_data_type_t ca_buffer_data_type = {
+  "ca_buffer_data",
+  {NULL, ca_buffer_data_free, ca_buffer_data_memsize},
+};
+
+static VALUE
+ca_buffer_data_alloc(VALUE klass)
+{
+    VALUE obj;
+    ca_buffer_data *ptr;
+
+    obj = TypedData_Make_Struct(klass, ca_buffer_data, &ca_buffer_data_type, ptr);
+    pthread_mutex_init(&ptr->mutex, NULL);
+    pthread_cond_init(&ptr->cond, NULL);
+    return obj;
+}
+
+static VALUE
+ca_buffer_data_start(VALUE self)
+{
+    ca_buffer_data *data;
+    OSStatus status;
+
+    TypedData_Get_Struct(self, ca_buffer_data, &ca_buffer_data_type, data);
+
+    data->dropped_frame = 0;
+    status = AudioDeviceStart(data->devID, data->procID);
+    if ( status != noErr )
+    {
+      rb_raise(rb_eRuntimeError, "coreaudio: audio device start fail: %d", status);
+    }
+    return self;
+}
+
+static VALUE
+ca_buffer_data_stop(VALUE self)
+{
+    ca_buffer_data *data;
+    OSStatus status;
+
+    TypedData_Get_Struct(self, ca_buffer_data, &ca_buffer_data_type, data);
+
+    status = AudioDeviceStop(data->devID, data->procID);
+    if ( status != noErr )
+    {
+      rb_raise(rb_eRuntimeError, "coreaudio: audio device stop fail: %d", status);
+    }
+    return self;
+}
+
+static VALUE
+ca_buffer_wait(void *ptr)
+{
+    ca_buffer_data *data = ptr;
+    int ret;
+
+    ret = pthread_cond_wait(&data->cond, &data->mutex);
+
+    return (VALUE)ret;
+}
+
+#if 0
+/* use pthread_mutex_lock in unblocking function cause deadlock.
+ * because calling thread have GVL lock and interrupted thread could
+ * be waiting mutex lock for GVL.
+ * So use RUBY_UBF_IO for unblocking function.
+ * Although pthread_cond_wait() shouldn't return EINTR acoording to POSIX,
+ * on Mac OS X pthread_cond_wait() actually returns when received signals. */
+static void
+ca_buffer_unblocking_func(void *ptr)
+{
+    ca_buffer_data *data = ptr;
+
+    pthread_mutex_lock(&data->mutex);
+    pthread_cond_broadcast(&data->cond);
+    pthread_mutex_unlock(&data->mutex);
+}
+#endif
+
+static VALUE
+ca_buffer_wait_blocking(VALUE value)
+{
+    void *ptr = (void *)value;
+#if 0
+    return rb_thread_call_without_gvl(ca_buffer_wait, ptr,
+                                      ca_buffer_unblocking_func, ptr);
+#endif
+    return rb_thread_call_without_gvl(ca_buffer_wait, ptr,
+                                      RUBY_UBF_IO, NULL);
+}
+
+static size_t
+buffer_space(ca_buffer_data *data)
+{
+    UInt32 nxt;
+    size_t space;
+
+    pthread_mutex_lock(&data->mutex);
+    nxt = (data->end+1) % data->frame;
+    if ( nxt <= data->start )
+      space = (size_t)(data->start - nxt);
+    else
+      space = (size_t)(data->start + data->frame - nxt);
+    pthread_mutex_unlock(&data->mutex);
+    return space;
+}
+
+static VALUE
+ca_buffer_space(VALUE self)
+{
+    ca_buffer_data *data;
+    size_t space;
+
+    TypedData_Get_Struct(self, ca_buffer_data, &ca_buffer_data_type, data);
+
+    space = buffer_space(data);
+    return SIZET2NUM(space);
+}
+
+static VALUE
+ca_buffer_dropped_frame(VALUE self)
+{
+    ca_buffer_data *data;
+    long dropped;
+
+    TypedData_Get_Struct(self, ca_buffer_data, &ca_buffer_data_type, data);
+
+    pthread_mutex_lock(&data->mutex);
+    dropped = data->dropped_frame;
+    pthread_mutex_unlock(&data->mutex);
+    return LONG2NUM(dropped);
+}
+
+static VALUE
+ca_buffer_reset_dropped_frame(VALUE self)
+{
+    ca_buffer_data *data;
+    long dropped;
+
+    TypedData_Get_Struct(self, ca_buffer_data, &ca_buffer_data_type, data);
+
+    pthread_mutex_lock(&data->mutex);
+    dropped = data->dropped_frame;
+    data->dropped_frame = 0;
+    pthread_mutex_unlock(&data->mutex);
+    return LONG2NUM(dropped);
+}
+
+/*
+ * Document-class: CoreAudio::OutputBuffer
+ *
+ * CoreAudio::OutputBuffer is a class for stream waveform to output audio stream.
+ */
+static OSStatus
+ca_out_buffer_proc(
+        AudioDeviceID           inDevice,
+        const AudioTimeStamp*   inNow,
+        const AudioBufferList*  inInputData,
+        const AudioTimeStamp*   inInputTime,
+        AudioBufferList*        outOutputData,
+        const AudioTimeStamp*   inOutputTime,
+        void*                   inClientData)
+{
+    NSUInteger n_buf;
+    UInt32 buffers = outOutputData->mNumberBuffers;
+    ca_buffer_data *buffer_data = inClientData;
+    UInt32 channels = buffer_data->channels;
+
+    for (n_buf = 0; n_buf < buffers; n_buf++) {
+      float *ptr = outOutputData->mBuffers[n_buf].mData;
+      UInt32 size = outOutputData->mBuffers[n_buf].mDataByteSize / (UInt32)sizeof(float) / channels;
+      UInt32 copied = 0;
+      UInt32 i;
+
+      if (outOutputData->mBuffers[n_buf].mNumberChannels != channels) {
+        memset(ptr, 0, size * channels * sizeof(float));
+        continue;
+      }
+
+      pthread_mutex_lock(&buffer_data->mutex);
+      for ( copied = 0, i = buffer_data->start; copied < size && i != buffer_data->end; copied++, i = (i+1) % buffer_data->frame ) {
+        UInt32 ch;
+        for (ch = 0; ch < channels; ch++) {
+          ptr[copied*channels+ch] = SHORT2FLOAT(buffer_data->buf[i*channels+ch]);
+        }
+      }
+      buffer_data->start = i;
+      pthread_cond_broadcast(&buffer_data->cond);
+      pthread_mutex_unlock(&buffer_data->mutex);
+      if ( copied < size ) {
+        memset(ptr+(copied*channels), 0, sizeof(float)*channels*(size-copied));
+        buffer_data->dropped_frame += size - copied;
+      }
+    }
+
+    return 0;
+}
+
+static VALUE
+ca_out_buffer_data_initialize(VALUE self, VALUE devID, VALUE frame, VALUE channels)
+{
+    ca_buffer_data *data;
+    OSStatus status;
+
+    TypedData_Get_Struct(self, ca_buffer_data, &ca_buffer_data_type, data);
+    data->devID = NUM2UINT(devID);
+    status = AudioDeviceCreateIOProcID(data->devID, ca_out_buffer_proc, data, &data->procID);
+    if ( status != noErr )
+    {
+      rb_raise(rb_eRuntimeError, "coreaudio: create proc ID fail: %d", status);
+    }
+    data->frame = NUM2UINT(frame);
+    data->channels = NUM2UINT(channels);
+    data->buf = malloc(sizeof(short)*data->frame*data->channels);
+    if (data->buf == NULL)
+      rb_raise(rb_eNoMemError, "coreaudio: fail to alloc out buffer data buffer");
+    return self;
+}
+
+static VALUE
+ca_device_create_out_buffer_proc(VALUE self, VALUE frame)
+{
+    VALUE proc;
+    VALUE out_stream = rb_ivar_get(self, sym_iv_output_stream);
+
+    proc = ca_buffer_data_alloc(rb_cOutputBuffer);
+    ca_out_buffer_data_initialize(proc, rb_ivar_get(self, sym_iv_devid), frame,
+                                  rb_ivar_get(out_stream, sym_iv_channels));
+    return proc;
+}
+
+static VALUE
+ca_out_buffer_data_append(VALUE self, VALUE nary)
+{
+    ca_buffer_data *data;
+    int rank;
+    short *buf;
+    UInt32 frames;
+    UInt32 idx;
+    long i;
+    UInt32 j;
+
+    TypedData_Get_Struct(self, ca_buffer_data, &ca_buffer_data_type, data);
+
+    nary = na_cast_object(nary, NA_SINT);
+    rank = NA_RANK(nary);
+    if (rank == 1) {
+      frames = NA_SHAPE0(nary);
+    } else if (rank == 2) {
+      frames = NA_SHAPE1(nary);
+      if (NA_SHAPE0(nary) != (int)data->channels)
+        rb_raise(rb_eArgError,
+                 "coreaudio: audio buffer NArray size of first dim. must be "
+                 "number of channels");
+    } else {
+      rb_raise(rb_eArgError,
+               "coreaudio: audio buffer NArray rank must be 1 or 2");
+    }
+    buf = NA_PTR_TYPE(nary, short *);
+    pthread_mutex_lock(&data->mutex);
+    idx = (data->end + 1) % data->frame;
+    for ( i = 0; i < frames; i++, idx = (idx+1)%data->frame) {
+      while ( idx == data->start ) {
+        int ret, state;
+        data->end = (idx == 0) ? data->frame-1 : idx - 1;
+        ret = (int)rb_protect(ca_buffer_wait_blocking, (VALUE)data, &state);
+        if (state) {
+          pthread_mutex_unlock(&data->mutex);
+          rb_jump_tag(state);
+        }
+        switch(ret) {
+          case 0:
+          case EINTR:
+          case EAGAIN:
+            break;
+          default:
+            pthread_mutex_unlock(&data->mutex);
+            rb_sys_fail("pthread_cond_wait");
+            break;
+        }
+      }
+
+      if (rank == 2) {
+        memcpy(data->buf + idx * data->channels,
+               buf + i * data->channels,
+               sizeof(short) * data->channels);
+      } else {
+        for (j = 0; j < data->channels; j++) {
+          data->buf[idx*data->channels+j] = buf[i];
+        }
+      }
+      data->end = idx;
+    }
+    pthread_mutex_unlock(&data->mutex);
+    return self;
+}
+
+/*
+ * Document-class: CoreAudio::InputBuffer
+ *
+ * CoreAudio::InputBuffer is a class for stream waveform to input audio stream.
+ */
+static OSStatus
+ca_in_buffer_proc(
+        AudioDeviceID           inDevice,
+        const AudioTimeStamp*   inNow,
+        const AudioBufferList*  inInputData,
+        const AudioTimeStamp*   inInputTime,
+        AudioBufferList*        outOutputData,
+        const AudioTimeStamp*   inOutputTime,
+        void*                   inClientData)
+{
+    NSUInteger n_buf;
+    UInt32 buffers = inInputData->mNumberBuffers;
+    ca_buffer_data *buffer_data = inClientData;
+    UInt32 channels = buffer_data->channels;
+
+    for (n_buf = 0; n_buf < buffers; n_buf++) {
+      float *ptr = inInputData->mBuffers[n_buf].mData;
+      UInt32 size = inInputData->mBuffers[n_buf].mDataByteSize / (UInt32)sizeof(float) / channels;
+      UInt32 copied, idx;
+
+      if (inInputData->mBuffers[n_buf].mNumberChannels != channels) {
+        continue;
+      }
+
+      pthread_mutex_lock(&buffer_data->mutex);
+
+      copied = 0;
+      for (idx = buffer_data->end;
+           copied < size && (idx+1) % buffer_data->frame != buffer_data->start;
+           copied++, idx = (idx+1) % buffer_data->frame) {
+        UInt32 ch;
+        for (ch = 0; ch < channels; ch++) {
+          buffer_data->buf[idx*channels+ch] = FLOAT2SHORT(ptr[copied*channels+ch]);
+        }
+      }
+      buffer_data->end = idx;
+      buffer_data->dropped_frame += size - copied;
+
+      pthread_cond_broadcast(&buffer_data->cond);
+      pthread_mutex_unlock(&buffer_data->mutex);
+    }
+
+    return 0;
+}
+
+static VALUE
+ca_in_buffer_data_initialize(VALUE self, VALUE devID, VALUE frame, VALUE channels)
+{
+    ca_buffer_data *data;
+    OSStatus status;
+
+    TypedData_Get_Struct(self, ca_buffer_data, &ca_buffer_data_type, data);
+    data->devID = NUM2UINT(devID);
+    status = AudioDeviceCreateIOProcID(data->devID, ca_in_buffer_proc, data, &data->procID);
+    if ( status != noErr )
+    {
+      rb_raise(rb_eRuntimeError, "coreaudio: create proc ID fail: %d", status);
+    }
+    data->frame = NUM2UINT(frame);
+    data->channels = NUM2UINT(channels);
+    data->buf = malloc(sizeof(short)*data->frame*data->channels);
+    if (data->buf == NULL)
+      rb_raise(rb_eNoMemError, "coreaudio: fail to alloc input buffer data buffer");
+    return self;
+}
+
+static VALUE
+ca_device_create_in_buffer_proc(VALUE self, VALUE frame)
+{
+    VALUE proc;
+    VALUE in_stream = rb_ivar_get(self, sym_iv_input_stream);
+
+    proc = ca_buffer_data_alloc(rb_cInputBuffer);
+    ca_in_buffer_data_initialize(proc, rb_ivar_get(self, sym_iv_devid), frame,
+                                 rb_ivar_get(in_stream, sym_iv_channels));
+    return proc;
+}
+
+static VALUE
+ca_in_buffer_data_read(VALUE self, VALUE num)
+{
+    ca_buffer_data *data;
+    UInt32 frame = NUM2UINT(num);
+    VALUE nary;
+    int shape[2];
+    short *buf;
+    UInt32 i;
+
+    TypedData_Get_Struct(self, ca_buffer_data, &ca_buffer_data_type, data);
+
+    shape[0] = data->channels;
+    shape[1] = frame;
+    nary = na_make_object(NA_SINT, 2, shape, cNArray);
+    buf = NA_PTR_TYPE(nary, short *);
+
+    pthread_mutex_lock(&data->mutex);
+    for ( i = 0; i < frame; i++, data->start = (data->start+1)%data->frame) {
+      while (data->start == data->end) {
+        int ret, state;
+        ret = (int)rb_protect(ca_buffer_wait_blocking, (VALUE)data, &state);
+        if (state) {
+          pthread_mutex_unlock(&data->mutex);
+          rb_jump_tag(state);
+        }
+        switch(ret) {
+          case 0:
+          case EINTR:
+          case EAGAIN:
+            break;
+          default:
+            pthread_mutex_unlock(&data->mutex);
+            rb_sys_fail("pthread_cond_wait");
+            break;
+        }
+      }
+      memcpy(buf + i * data->channels, data->buf + data->start*data->channels,
+             sizeof(short) * data->channels);
+    }
+    pthread_mutex_unlock(&data->mutex);
+    return nary;
+}
+
+void
+Init_coreaudio_ext(void)
+{
+    sym_iv_devid = rb_intern("@devid");
+    sym_iv_name = rb_intern("@name");
+    sym_iv_available_sample_rate = rb_intern("@available_sample_rate");
+    sym_iv_nominal_rate = rb_intern("@nominal_rate");
+    sym_iv_input_stream = rb_intern("@input_stream");
+    sym_iv_output_stream = rb_intern("@output_stream");
+    sym_iv_channels = rb_intern("@channels");
+    sym_iv_buffer_frame_size = rb_intern("@buffer_frame_size");
+
+    rb_mCoreAudio = rb_define_module("CoreAudio");
+    rb_cAudioDevice = rb_define_class_under(rb_mCoreAudio, "AudioDevice", rb_cObject);
+    rb_cAudioStream = rb_define_class_under(rb_mCoreAudio, "AudioStream", rb_cObject);
+    rb_cOutLoop = rb_define_class_under(rb_mCoreAudio, "OutLoop", rb_cObject);
+    rb_cAudioBuffer = rb_define_class_under(rb_mCoreAudio, "AudioBuffer", rb_cObject);
+    rb_cOutputBuffer = rb_define_class_under(rb_mCoreAudio, "OutputBuffer", rb_cAudioBuffer);
+    rb_cInputBuffer = rb_define_class_under(rb_mCoreAudio, "InputBuffer", rb_cAudioBuffer);
+
+    rb_define_method(rb_cAudioDevice, "initialize", ca_device_initialize, 1);
+    rb_define_method(rb_cAudioDevice, "actual_rate", ca_get_device_actual_sample_rate, 0);
+    rb_define_method(rb_cAudioDevice, "output_loop", ca_device_create_out_loop_proc, 1);
+    rb_define_method(rb_cAudioDevice, "output_buffer", ca_device_create_out_buffer_proc, 1);
+    rb_define_method(rb_cAudioDevice, "input_buffer", ca_device_create_in_buffer_proc, 1);
+    rb_define_attr(rb_cAudioDevice, "devid", 1, 0);
+    rb_define_attr(rb_cAudioDevice, "name", 1, 0);
+    rb_define_attr(rb_cAudioDevice, "available_sample_rate", 1, 0);
+    rb_define_attr(rb_cAudioDevice, "nominal_rate", 1, 0);
+    rb_define_attr(rb_cAudioDevice, "input_stream", 1, 0);
+    rb_define_attr(rb_cAudioDevice, "output_stream", 1, 0);
+
+    rb_define_method(rb_cAudioStream, "initialize", ca_stream_initialize, 2);
+    rb_define_attr(rb_cAudioStream, "channels", 1, 0);
+    rb_define_attr(rb_cAudioStream, "buffer_frame_size", 1, 0);
+
+    rb_define_singleton_method(rb_mCoreAudio, "devices", ca_devices, -1);
+    rb_define_singleton_method(rb_mCoreAudio, "default_input_device", ca_default_input_device, -1);
+    rb_define_singleton_method(rb_mCoreAudio, "default_output_device", ca_default_output_device, -1);
+    rb_define_singleton_method(rb_mCoreAudio, "set_default_output_device", ca_set_default_output_device, 1);
+
+    rb_define_method(rb_cOutLoop, "[]=", ca_out_loop_data_assign, 2);
+    rb_define_method(rb_cOutLoop, "start", ca_out_loop_data_start, 0);
+    rb_define_method(rb_cOutLoop, "stop", ca_out_loop_data_stop, 0);
+
+    rb_define_method(rb_cAudioBuffer, "start", ca_buffer_data_start, 0);
+    rb_define_method(rb_cAudioBuffer, "stop", ca_buffer_data_stop, 0);
+    rb_define_method(rb_cAudioBuffer, "dropped_frame", ca_buffer_dropped_frame, 0);
+    rb_define_method(rb_cAudioBuffer, "reset_dropped_frame", ca_buffer_reset_dropped_frame, 0);
+    rb_define_method(rb_cAudioBuffer, "space",  ca_buffer_space, 0);
+
+    rb_define_method(rb_cOutputBuffer, "<<", ca_out_buffer_data_append, 1);
+
+    rb_define_method(rb_cInputBuffer, "read", ca_in_buffer_data_read, 1);
+
+    Init_coreaudio_audiofile();
+}
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/ext/coreaudio_missing.c b/app/server/vendor/ruby-coreaudio-0.0.11/ext/coreaudio_missing.c
new file mode 100755
index 0000000..c4f7ade
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/ext/coreaudio_missing.c
@@ -0,0 +1,24 @@
+
+#include "ruby.h"
+#include "coreaudio.h"
+
+#ifndef HAVE_RB_ALLOC_TMP_BUFFER
+void *
+rb_alloc_tmp_buffer(volatile VALUE *store, long len)
+{
+	VALUE s = rb_str_tmp_new(len);
+	*store = s;
+	return RSTRING_PTR(s);
+}
+#endif
+
+#ifndef HAVE_RB_FREE_TMP_BUFFER
+void
+rb_free_tmp_buffer(volatile VALUE *store)
+{
+    VALUE s = *store;
+    *store = 0;
+        if (s) rb_str_clear(s);
+}
+#endif
+
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/ext/depend b/app/server/vendor/ruby-coreaudio-0.0.11/ext/depend
new file mode 100755
index 0000000..7c61c8b
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/ext/depend
@@ -0,0 +1,2 @@
+coreaudio.o: coreaudio.m coreaudio.h
+audiofile.o: audiofile.m coreaudio.h
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/ext/extconf.rb b/app/server/vendor/ruby-coreaudio-0.0.11/ext/extconf.rb
new file mode 100755
index 0000000..cb08867
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/ext/extconf.rb
@@ -0,0 +1,70 @@
+require 'mkmf'
+
+$CFLAGS << " " << "-ObjC"
+
+unless defined?(have_framework)
+  def have_framework(fw, &b)
+    checking_for fw do
+      src = cpp_include("#{fw}/#{fw}.h") << "\n" "int main(void){return 0;}"
+      if try_link(src, opt = "-ObjC -framework #{fw}", &b)
+        $defs.push(format("-DHAVE_FRAMEWORK_%s", fw.tr_cpp))
+        $LDFLAGS << " " << opt
+        true
+      else
+        false
+      end
+    end
+  end
+end
+
+begin
+  files = Gem.find_files("narray.h")
+  if files.empty?
+    narray_dir = $sitearchdir
+  else
+    narray_dir = File.dirname(files.first)
+  end
+rescue
+  narray_dir = $sitearchdir
+end
+dir_config("narray", narray_dir, narray_dir)
+
+if not(have_header("narray.h") and have_header("narray_config.h"))
+  print <<-EOS
+** configure error **
+narray.h or narray_config.h is not found.
+If you have installed narray to /path/to/narray, try the following:
+
+ % ruby extconf.rb --with-narray-dir=/path/to/narray
+
+or
+ % gem install coreaudio -- --with-narray-dir=/path/to/narray
+
+  EOS
+  exit false
+end
+
+if have_framework("CoreAudio") and
+   have_framework("AudioToolbox") and
+   have_framework("CoreFoundation") and
+   have_framework("Cocoa")
+
+  # check ruby API
+  have_func("rb_alloc_tmp_buffer", "ruby.h")
+  have_func("rb_free_tmp_buffer", "ruby.h")
+
+  create_header
+
+  # create Makefile
+  create_makefile("coreaudio/coreaudio_ext")
+
+  # workaround for mkmf.rb in 1.9.2
+  if RUBY_VERSION < "1.9.3"
+    open("Makefile", "a") do |f|
+      f.puts <<-EOS
+.m.o:
+	$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
+      EOS
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/ext/narray.h b/app/server/vendor/ruby-coreaudio-0.0.11/ext/narray.h
new file mode 100755
index 0000000..eaa860f
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/ext/narray.h
@@ -0,0 +1,184 @@
+/*
+  narray.h
+  Numerical Array Extention for Ruby
+    (C) Copyright 1999-2011 by Masahiro TANAKA
+
+  This program is free software.
+  You can distribute/modify this program
+  under the same terms as Ruby itself.
+  NO WARRANTY.
+*/
+#ifndef NARRAY_H
+#define NARRAY_H
+
+#include <math.h>
+
+#include "narray_config.h"
+
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#define NARRAY_VERSION "0.6.1.1"
+#define NARRAY_VERSION_CODE 611
+
+/*
+  Data types used in NArray :
+  Please modify these types if your system has any different type.
+*/
+
+
+/* NA_BYTE : unsigned 8-bit integer */
+#ifndef HAVE_U_INT8_T
+# ifdef HAVE_UINT8_T
+typedef uint8_t			u_int8_t;
+# else
+typedef unsigned char		u_int8_t;
+# endif
+#endif
+
+#ifndef HAVE_INT16_T
+# if SIZEOF_SHORT == 2
+typedef short                  int16_t;  /* NA_SINT */
+# else
+---->> Please define int16_t manually because sizeof(short) != 2. <<----
+# endif
+#endif /* HAVE_INT16_T */
+
+#ifndef HAVE_INT32_T
+# if SIZEOF_LONG == 4
+typedef long                   int32_t;  /* NA_LINT */
+# else
+#  if SIZEOF_INT == 4
+typedef int                    int32_t;  /* NA_LINT */
+#  else
+---->> Please define int32_t manually because sizeof(long) != 4. <<----
+#  endif
+# endif
+#endif /* HAVE_INT32_T */
+
+/* unsigned 32-bit integer */
+#ifndef HAVE_U_INT32_T
+# ifdef HAVE_UINT32_T
+typedef uint32_t			u_int32_t;
+# else
+#  if SIZEOF_LONG == 4
+typedef unsigned long                   u_int32_t;
+#  else
+#   if SIZEOF_INT == 4
+typedef unsigned int                    u_int32_t;
+#   else
+---->> Please define u_int32_t manually because sizeof(long) != 4. <<----
+#   endif
+#  endif
+# endif
+#endif /* HAVE_U_INT32_T */
+
+typedef struct { float r,i; }  scomplex;
+typedef struct { double r,i; } dcomplex;
+
+enum NArray_Types {
+  NA_NONE,
+  NA_BYTE,	/* 1 */
+  NA_SINT,	/* 2 */
+  NA_LINT,	/* 3 */
+  NA_SFLOAT,	/* 4 */
+  NA_DFLOAT,	/* 5 */
+  NA_SCOMPLEX,	/* 6 */
+  NA_DCOMPLEX,	/* 7 */
+  NA_ROBJ,	/* 8 */
+  NA_NTYPES	/* 9 */
+};
+
+/* struct for Numerical Array */
+struct NARRAY {
+  int    rank;	  /* # of dimension */
+  int    total;	  /* # of total element */
+  int    type;	  /* data type */
+  int   *shape;
+  char  *ptr;	  /* pointer to data */
+  VALUE  ref;	  /* NArray object wrapping this structure */
+};
+
+#ifndef NARRAY_C
+extern VALUE cNArray;
+
+extern const int na_sizeof[NA_NTYPES+1];
+#endif
+
+#define GetNArray(obj,var)  Data_Get_Struct(obj, struct NARRAY, var)
+#define IsNArray(obj) (rb_obj_is_kind_of(obj,cNArray)==Qtrue)
+
+#define NA_PTR(a,p)    ((a)->ptr+(p)*na_sizeof[(a)->type])
+#define NA_STRUCT(val) ((struct NARRAY*)DATA_PTR(val))
+#define NA_PTR_TYPE(val,type) (type)(((struct NARRAY*)DATA_PTR(val))->ptr)
+#define NA_RANK(val)   (((struct NARRAY*)DATA_PTR(val))->rank)
+#define NA_TYPE(val)   (((struct NARRAY*)DATA_PTR(val))->type)
+#define NA_TOTAL(val)  (((struct NARRAY*)DATA_PTR(val))->total)
+#define NA_SHAPE0(val) (((struct NARRAY*)DATA_PTR(val))->shape[0])
+#define NA_SHAPE1(val) (((struct NARRAY*)DATA_PTR(val))->shape[1])
+
+#define NA_IsNArray(obj) \
+  (rb_obj_is_kind_of(obj,cNArray)==Qtrue)
+#define NA_IsArray(obj) \
+  (TYPE(obj)==T_ARRAY || rb_obj_is_kind_of(obj,cNArray)==Qtrue)
+#define NA_IsROBJ(d) ((d)->type==NA_ROBJ)
+#define NA_IsINTEGER(a) \
+  ((a)->type==NA_BYTE || (a)->type==NA_SINT || (a)->type==NA_LINT )
+#define NA_IsCOMPLEX(a) \
+  ((a)->type==NA_SCOMPLEX || (a)->type==NA_DCOMPLEX)
+#define NA_MAX(a,b) (((a)>(b))?(a):(b))
+#define NA_SWAP(a,b,tmp) {(tmp)=(a);(a)=(b);(b)=(tmp);}
+
+#define na_class_dim(klass) NUM2INT(rb_const_get(klass, na_id_class_dim))
+
+#define NUM2REAL(v)  NUM2DBL( rb_funcall((v),na_id_real,0) )
+#define NUM2IMAG(v)  NUM2DBL( rb_funcall((v),na_id_imag,0) )
+
+#define NA_ALLOC_SLICE(slc,nc,shp,np) \
+{ slc = (struct slice*)xmalloc( sizeof(struct slice)*(nc) + \
+				sizeof(int)*(np) );\
+  shp = (int*)&( (slc)[nc] ); }
+
+
+/* Function Prototypes */
+
+/* narray.c */
+VALUE na_make_object(int type, int rank, int *shape, VALUE klass);
+VALUE na_make_scalar(VALUE obj, int type);
+VALUE na_make_empty(int type, VALUE klass);
+int   na_get_typecode(VALUE v);
+void  na_clear_data(struct NARRAY *ary);
+VALUE na_clone(VALUE self);
+VALUE na_fill(VALUE self, volatile VALUE obj);
+void  na_copy_nary(struct NARRAY *dst, struct NARRAY *src);
+
+/* na_array.c */
+VALUE na_to_array(VALUE obj);
+VALUE na_make_inspect(VALUE self);
+VALUE na_ary_to_nary(VALUE ary, VALUE klass);
+int   na_object_type(VALUE v);
+
+VALUE na_cast_object(VALUE obj, int type);
+VALUE na_cast_unless_narray(VALUE obj, int type);
+VALUE na_cast_unless_array(VALUE obj, int type);
+VALUE na_upcast_object(VALUE obj, int type);
+VALUE na_dup_w_type(VALUE obj, int type);
+VALUE na_change_type(VALUE obj, int type);
+VALUE na_upcast_type(VALUE obj, int type);
+VALUE na_to_narray(VALUE obj);
+
+/* na_index.c */
+VALUE na_aset(int argc, VALUE *argv, VALUE self);
+VALUE na_aref(int argc, VALUE *argv, VALUE self);
+VALUE na_slice(int argc, VALUE *argv, VALUE self);
+VALUE na_count_true(VALUE self);
+VALUE na_count_false(VALUE self);
+VALUE na_aref_mask(VALUE self, VALUE mask);
+void  na_aset_mask(VALUE self, VALUE mask, VALUE v);
+
+#endif /* ifndef NARRAY_H */
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/ext/narray_config.h b/app/server/vendor/ruby-coreaudio-0.0.11/ext/narray_config.h
new file mode 100644
index 0000000..334366c
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/ext/narray_config.h
@@ -0,0 +1,7 @@
+#define HAVE_STDINT_H 1
+#define HAVE_U_INT8_T 1
+#define HAVE_UINT8_T 1
+#define HAVE_INT16_T 1
+#define HAVE_INT32_T 1
+#define HAVE_U_INT32_T 1
+#define HAVE_UINT32_T 1
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/lib/coreaudio.rb b/app/server/vendor/ruby-coreaudio-0.0.11/lib/coreaudio.rb
new file mode 100755
index 0000000..4f3d51f
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/lib/coreaudio.rb
@@ -0,0 +1,5 @@
+require "narray"
+require "coreaudio/version"
+#require "coreaudio/coreaudio_ext"
+require "coreaudio_ext"
+require "coreaudio/audiofile"
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/lib/coreaudio/audiofile.rb b/app/server/vendor/ruby-coreaudio-0.0.11/lib/coreaudio/audiofile.rb
new file mode 100755
index 0000000..018434e
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/lib/coreaudio/audiofile.rb
@@ -0,0 +1,38 @@
+
+module CoreAudio
+  class AudioFile
+    def read(frames=nil)
+      if frames
+        frames = Integer(frames)
+        if frames and frames > 0
+          return read_frames(frames)
+        elsif frames == 0
+          return NArray.sint(0)
+        else
+          raise ArgumentError,
+            "coreaudio: read frame number must be zero or positive"
+        end
+      end
+
+      # read all frames
+      chunk = self.inner_rate.to_i * 10
+      total = nil
+      loop do
+        tmp = read_frames(chunk)
+        if tmp.nil?
+          break
+        end
+        if total.nil?
+          total = tmp
+        else
+          new_na = NArray.sint(total.shape[0], tmp.shape[1] + total.shape[1])
+          new_na[false, 0...total.shape[1]] = total
+          new_na[false, total.shape[1]..-1] = tmp
+          total = new_na
+        end
+      end
+
+      total
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-coreaudio-0.0.11/lib/coreaudio/version.rb b/app/server/vendor/ruby-coreaudio-0.0.11/lib/coreaudio/version.rb
new file mode 100755
index 0000000..4fe7234
--- /dev/null
+++ b/app/server/vendor/ruby-coreaudio-0.0.11/lib/coreaudio/version.rb
@@ -0,0 +1,3 @@
+module CoreAudio
+  VERSION = "0.0.11"
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/.gitignore b/app/server/vendor/ruby-prof-0.15.8/.gitignore
new file mode 100755
index 0000000..54e7b23
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/.gitignore
@@ -0,0 +1,18 @@
+doc
+ext/ruby_prof/Makefile
+heap.dump
+nbproject/
+pkg/
+/ext/ruby_prof/vc/ruby_prof/ipch
+/ext/ruby_prof/vc/ruby_prof/Debug
+/ext/ruby_prof/vc/Debug
+/.idea
+*.bundle
+*.so
+tmp
+.*.swp
+ipch
+/ext/ruby_prof/vc/*.user
+examples2
+.rvmrc
+Gemfile.lock
diff --git a/app/server/vendor/ruby-prof-0.15.8/.travis.yml b/app/server/vendor/ruby-prof-0.15.8/.travis.yml
new file mode 100755
index 0000000..d7ee824
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/.travis.yml
@@ -0,0 +1,8 @@
+language: ruby
+rvm:
+  - 1.9.3
+  - 2.0.0
+  - 2.1.5
+  - 2.2.0
+script: "bundle exec rake clean compile test"
+
diff --git a/app/server/vendor/ruby-prof-0.15.8/CHANGES b/app/server/vendor/ruby-prof-0.15.8/CHANGES
new file mode 100755
index 0000000..9d6ec0e
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/CHANGES
@@ -0,0 +1,428 @@
+0.15.8 (2015-04-24)
+======================
+* added missing assets to gem build
+* fixed randomly failing test
+
+0.15.7 (2015-04-23)
+======================
+* html profiles are now single page (thx to Thomas Leishman)
+
+0.15.6 (2015-02-22)
+======================
+* improved upon computing children time in graph printers
+
+0.15.5 (2015-02-22)
+======================
+* changed output format of flat_printer_with_line_number
+* support using multi printer from command line (Dov Murik)
+
+0.15.4 (2015-02-14)
+======================
+* using env variable to specify mesaurement mode work again
+* measuring memory/object allocations works for 2.1 adn 2.2 again
+
+0.15.3 (2015-01-16)
+======================
+* support ruby 2.2.0
+
+0.15.2 (2014-05-20)
+======================
+* rack middleware creates print dir for profile result (Neng)
+
+0.15.1 (2014-05-20)
+======================
+* added license to gemspec
+
+0.15.0 (2014-05-02)
+======================
+* improved cpu time measurement (Charlie Somerville)
+
+0.14.2 (2014-01-05)
+======================
+* hopefully fixed compile problem under Windows
+
+0.14.0 (2014-01-02)
+======================
+* support ruby 2.1.0
+* dropped support for 1.8.x, 1.9.1 and 1.9.2
+
+0.13.1 (2013-12-14)
+======================
+* speed up for displaying large call stacks (Benjamin Quoming)
+
+0.13 (2013-03-10)
+======================
+* support fibers on 1.9.x+
+* improved display for very wide call stacks (Sammy Larbi)
+
+0.12.2 (2013-02-13)
+======================
+* Fixed segfault when using falcon or railsexpress patches for 1.9.3
+
+0.12.1 (2013-01-07)
+======================
+* Add back in pause/resume support since Rails uses it
+
+0.12.0 (2013-01-06)
+======================
+* Ruby 2.0.0 support (Charlie Savage)
+* Fix issue where profiling results could exceed 100% if profile code had multiple top level methods (Charlie Savage)
+* Replaced RubyProf::Thread#top_method with RubyProf::Thread#top_methods (Charlie Savage)
+* Added RubyProf::Thread#total_time (Charlie Savage)
+* Remove the -r and -e command line options.  If you need specific libraries or code profiled then add them
+  to your code (Charlie Savage).
+* Rewrite ruby-prof script to be more self-contained (Gary Weaver)
+* Fix list formatting in readme (Thilo Rusche)
+* Remove pause/resume support since its buggy and complicates the code
+
+0.11.3 (2012-12-27)
+======================
+* Prefix c functions with prof_ to avoid name conflicts (Kenta Murata)
+* Update ruby-prof script to avoid seg faults (Gary Weaver)
+* Rakefile updates (Roger Pack)
+* Fix regexp file reading (Gilbert Roulot)
+* Update documentation (Timo Schilling)
+* Fix up ruby warnings (Mike Gehard)
+* Remove duplicate code (Chas Lemley)
+
+
+0.11.2 (2012-05-06)
+======================
+* Fix compile issue with BOOL.  Should be _Bool for C99.
+
+
+0.11.1 (2012-05-06)
+======================
+* Added option --exclude-common-callbacks, plus exclude #map and #inject in common cycles (Vasily Fedoseyev)
+* Add option --exclude-common-cycles to exclude common iterators (Vasily Fedoseyev)
+* Allow method elimination from command line via '-x' and '-X' keys (Vasily Fedoseyev)
+
+
+0.11.0 (2012-05-05)
+======================
+* Fix pause/resume so it actually works and add tests (David Barri)
+* Resume now returns the result of the block when given (David Barri)
+* Make recursive method explanation more clear (Charlie Savage)
+* Fix ruby warnings (Charlie Savage)
+* Toggle GC.enable_stats when profiling for memory to get the data (Vasily Fedoseyev)
+* Fix patched ruby support and remove some warnings (Vasily Fedoseyev)
+* Fix tests on 1.8.7 (rogerdpack)
+
+
+0.11.0.rc3 (2012-03-26)
+======================
+* Include missing files in gemspec (Charlie Savage).
+
+
+0.11.0.rc2 (2012-03-25)
+======================
+* Lots of improvements to Rack handler - this can be used to profile requests
+  in Rails and other rack-based ruby web frameworks (Charlie Savage).
+* Reimplemented handling of recursive calls using CallInfoVisitor (Charlie Savage).
+* Fix bug where child times were not correctly reported in complicated
+  call graphs with recursion like in frameworks like Rails (Charlie Savage).
+* Add in recursive call information to Flat, Graph and Graph HTML reports (Charlie Savage).
+* Add in new thread class add added RubyProf::Thread#top_method to
+  make report generation easier (Charlie Savage).
+* Add in CallInfoVisitor class to make it easy to iterate over a call graph (Charlie Savage).
+* Add in CallInfoPrinter to make it visualize RubyProf's internal call graphs (Charlie Savage).
+* Significant updates to documentation (Charlie Savage).
+* More c code cleanup (Charlie Savage).
+
+0.11.0.rc1 (2012-03-24)
+======================
+* Big internal refactoring of C code to make RubyProf easier to understand and extend (Charlie Savage).
+* Profile results are now returned as instances of a new class RubyProf::Profile.  The old api
+  is supported via a compatability layer that at some point will be deprecated.  (Charlie Savage).
+* On Windows, use QueryPerformanceCounter and QueryPerformanceFrequency to measure CPU time instead
+  of rdtsc.  This change is based on Microsoft's recommendation (Charlie Savage).
+* On Windows use GetProcessTimes to return real PROCESS_TIME times instead of wall times (Charlie Savage).
+* Split out tests for each time of measurement (cpu_time, process_time, etc.) (Charlie Savage).
+* Dropped support for Ruby 1.8.4 and 1.8.6 and 1.9.0 (Charlie Savage).
+* Added support for sorting results by total, self, wait and child times (Jan Suchal)
+* Added tests for sorting behaviour & removed options from constructor to print method (Jan Suchal)
+* Fix line number tests due to changes at top of file (Charlie Savage).
+* Add encoding statement to top of all files for Ruby 1.9.x compatability (Charlie Savage).
+* Add def file for VC to avoid the whole declspec annoyance (Charlie Savage).
+* Update test suite to ensure current working directory is correct (Charlie Savage).
+* Modernize gem file and remove various custom/home grown solutions that aren't needed anymore (Charlie Savage).
+* Remove custom mingw build scripts, use rake compiler instead  (Charlie Savage).
+* Fixes for compiling with VC 2010 (Charlie Savage).
+
+0.10.8 (2011-07-06)
+======================
+* 1.9.3 super class (Roger Pack)
+
+0.10.7 (2011-05-09)
+======================
+* Fix a bug with REE's GC stats. Issue #53 [thanks graaff]
+
+0.10.6 (2011-04-29)
+======================
+* Slightly more normalized url for linux/windows links to files.
+
+0.10.5 (2011-04-20)
+=======================
+* 1.8.6 compat for -v command (bug fix)
+
+0.10.4 (2011-04-20)
+=======================
+* Faster load time for ruby-prof itself.
+
+0.10.3
+=======================
+* Can cleanly load before rubygems now.
+
+0.10.2
+=======================
+* Fix for 1.9.2, os x for latest commits (thanks skaes!)
+
+0.10.1
+=======================
+* Fix bug in linux wall time, also load with only relative paths so that you can use it to benchmark rubygems startup overhead,
+  itself.
+
+0.10.0
+=======================
+* Some rdoc changes, for linux wall time attempt to use higher granularity (thanks to all the contributors for this round!)
+
+0.9.2
+=======================
+* Make graphviz work on 1.8.6
+* Roll back some 1.9.2 optimizations until I can figure out what caused them.
+
+0.9.1
+=======================
+* Add a graphviz output
+
+0.9.0
+=======================
+* measurements for recursive methods are now correct
+* gave up on splitting up recursive methods according to call depth
+* made it possible to eliminate methods from profiling results
+* new printer for call stack visualization
+* new printer to print several profiles in one run
+* HTML profiles contain Textmate links so you can jump to the source code easily
+* producing an event log is now a runtime option
+
+0.7.10 (2009-01-22)
+=======================
+* fix SEGFAULT in 1.9
+* add new printer flat_printer_with_line_numbers
+
+0.7.7 (2009-01-13)
+======================
+* "fix" multi threading support for 1.9 http://redmine.ruby-lang.org/issues/show/2012
+* speedups
+
+0.7.6 (2009-12-31)
+======================
+* fix some tests for 1.9 (no real code changes)
+
+0.7.5 (2009-12)
+========================
+* fix a GC collection bug (nobu's patch).
+* correctly report recursive call depths (Kevin Scaldeferri).
+* sort methods on output (Kevin Scaldeferri).
+
+0.7.3 (2008-12-09)
+========================
+* Fixed compile error with new x86_64 code using GCC.
+
+0.7.2 (2008-12-08)
+========================
+* Fixed major bug in printing child methods in graph reports.
+
+* Fixes for supporting x86_64 machines (Diego Pettenò)
+
+
+0.7.1 (2008-11-28)
+========================
+* Added new AggregateCallInfo class for printers to
+  make results easier to read.  Take this call sequence
+  for example:
+
+   A   B   C
+   |   |   |
+   Z   A   A
+       |   |
+       Z   Z
+
+  By default, ruby-prof will show that Z was called by 3 separate
+  instances of A.  In an IDE that is helpful but in a text report
+  it is not since it makes the report much harder to read.
+  As a result, printers now aggregate together callers (and children),
+  matching ruby-prof's output from versions prior to 0.7.0.
+
+* Fixes for supporting x86_64 machines (Matt Sanford)
+
+
+0.7.0 (2008-11-04)
+========================
+
+Features
+--------
+* Added two new methods - RubyProf.resume and RubyProf.pause.
+  RubyProf.resume takes an optional block, which ensures that
+  RubyProf.pause is called.  For example:
+
+  10.times do |i|
+    RubyProf.resume do
+      # Some long process
+    end
+  end
+
+  result = RubyProf.stop
+
+* Added support for profiling tests that use Ruby's built-in
+  unit test framework (ie, test derived from
+  Test::Unit::TestCase).  To enable profiling simply add
+  the following line of code to your test class:
+
+    include RubyProf::Test
+
+  By default, profiling results are written to the current
+  processes working directory.  To change this, or other
+  profiling options, simply modify the PROFILE_OPTIONS hash
+  table as needed.
+
+* Used the new support for profiling test cases to revamp
+  the way that Rails profiling works.  For more information
+  please refer to RubyProf's documentation.
+
+* Keep track of call stack for each method to enable more
+  powerful profile visualizations in Integrated Development
+  Environments (Hin Boean, work supported by CodeGear).
+
+* Expose measurements to Ruby (Jeremy Kemper).
+
+* Add support for additional memory measurements modes in Ruby 1.9 (Jeremy Kemper).
+
+* Add support for Lloyd Hilaiel's Ruby patch for measuring total heap size.
+   See http://lloydforge.org/projects/ruby. (Jeremy Kemper).
+
+
+Fixes
+-------
+* RubyProf.profile no longer crashes if an exception is
+  thrown during a profiling run.
+
+* Measure memory in fractional kilobytes rather than rounding down (Jeremy Kemper)
+
+
+0.6.0 (2008-02-03)
+========================
+
+ruby-prof 0.6.0 adds support for Ruby 1.9 and memory profiling.
+
+Features
+--------
+* Added support for ruby 1.9 (Shugo Maeda)
+* Added support for outputting printer results to a String, Array or IO
+  object (Michael Granger)
+* Add new memory profiling mode.  Note this mode depends on a
+  patched Ruby interpreter (Alexander Dymo)
+
+Fixes
+-------
+* Improvements to GraphHtmlPrinter including updated documentation,
+  fixes for min_time support, ability to specify templates using
+  strings or filenames, and table layout fixes (Makoto Kuwata)
+* Fixes to scaling factor for calltrees so that precision is not lost
+  due to the conversion to doubles (Sylvain Joyeux)
+* Changed constant ALLOCATED_OBJECTS to ALLOCATIONS in the C code to
+  match the Ruby code (Sylvain Joyeux)
+* Added support for calltree printer to ruby-prof binary script (Sylvain Joyeux)
+* Fix support for the allocator measure mode to extconf.rb (Sylvain Joyeux)
+* Honor measure mode when specified on the command line (Sylvain Joyeux)
+* Sorting of methods by total time was incorrect (Dan Fitch, Charlie Savage)
+* Fix ruby-prof to work with the latest version of GEMS (Alexander Dymo)
+* Always define MEASURE_CPU_TIME and MEASURE_ALLOCATIONS in Ruby code, but
+  set their values to nil if the functionality is not available.
+
+
+0.5.2 (2007-07-19)
+========================
+
+ruby-prof 0.5.2 is a bug fix release.
+
+Fixes
+-------
+* Include missing rails plugin
+
+
+0.5.1 (2007-07-18)
+========================
+
+ruby-prof 0.5.1 is a bug fix and performance release.
+
+Performance
+--------
+* Significantly reduced the number of thread lookups by
+  caching the last executed thread.
+
+Fixes
+-------
+* Properly escape method names in HTML reports
+* Fix use of -m and --min-percent command line switches
+* Default source file information to ruby_runtime#0 for c calls
+* Moved rails_plugin to top level so it is more obvious
+* Updated rails_plugin to write reports to the current
+  Rails log directory
+* Added additional tests
+
+
+0.5.0 (2007-07-09)
+========================
+
+Features
+--------
+* Added support for timing multi-threaded applications
+* Added support for 64 bit systems (patch from Diego 'Flameeyes' Petten)
+* Added suport for outputting data in the format used by
+  KCacheGrind (patch from Carl Shimer)
+* Add filename and line numbers to call tree information (patch from Carl Shimer)
+* Added Visual Studio 2005 project file.
+* Added replace-progname switch, als rcov.
+* Added better support for recursive methods
+* Added better support for profiling Rails applications
+
+Fixes
+-------
+* Fixes bug when the type of an attached object (singleton) is inherited
+  from T_OBJECT as opposed to being a T_OBJECT (identified by Francis Cianfrocca)
+* ruby-prof now works in IRB.
+* Fix sort order in reports.
+* Fixed rdoc compile error.
+* Fix tabs in erb template for graph html report on windows.
+
+0.4.1 (2006-06-26)
+========================
+
+Features
+--------
+* Added a RubyProf.running? method to indicate whether a profile is in progress.
+* Added tgz and zip archives to release
+
+Fixes
+-------
+* Duplicate method names are now allowed
+* The documentation has been updated to show the correct API usage is RubyProf.stop not RubyProf.end
+
+
+0.4.0 (2006-06-16)
+========================
+Features
+--------
+* added support for call graphs
+* added support for printers.  Currently there is a FlatPrinter,
+  GraphPrinter and GraphHtmlPrinter.
+* added support for recursive methods
+* added Windows support
+* now packaged as a RubyGem
+
+Fixes
+-------
+* Fixes bug where RubyProf would crash depending on the
+  way it was invoked - for example, it did not run when
+  used with Arachno Ruby's customized version of Ruby.
diff --git a/app/server/vendor/ruby-prof-0.15.8/Gemfile b/app/server/vendor/ruby-prof-0.15.8/Gemfile
new file mode 100755
index 0000000..16a0e12
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/Gemfile
@@ -0,0 +1,3 @@
+source 'https://rubygems.org'
+puts "bundler version: #{Bundler::VERSION}" if ENV['TRAVIS'] == "true"
+gemspec
diff --git a/app/server/vendor/ruby-prof-0.15.8/LICENSE b/app/server/vendor/ruby-prof-0.15.8/LICENSE
new file mode 100755
index 0000000..62aad2a
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/LICENSE
@@ -0,0 +1,25 @@
+Copyright (C) 2005 - 2014 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+Copyright (C) 2010 - 2014 Stefan Kaes <skaes at railsepxress.de>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
\ No newline at end of file
diff --git a/app/server/vendor/ruby-prof-0.15.8/README.rdoc b/app/server/vendor/ruby-prof-0.15.8/README.rdoc
new file mode 100755
index 0000000..c925ffa
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/README.rdoc
@@ -0,0 +1,400 @@
+= ruby-prof
+{<img src="https://travis-ci.org/ruby-prof/ruby-prof.png?branch=master" alt="Build Status" />}[https://travis-ci.org/ruby-prof/ruby-prof]
+
+== Overview
+
+ruby-prof is a fast code profiler for Ruby.  Its features include:
+
+* Speed - it is a C extension and therefore many times faster than the standard Ruby profiler.
+* Modes - Ruby prof can measure a number of different parameters, including call times, memory usage and object allocations.
+* Reports - can generate text and cross-referenced html reports
+  - Flat Profiles - similar to the reports generated by the standard Ruby profiler
+  - Graph profiles - similar to GProf, these show how long a method runs, which methods call it and which methods it calls.
+  - Call tree profiles - outputs results in the calltree format suitable for the KCacheGrind profiling tool.
+  - Many more -- see reports section of this README.
+* Threads - supports profiling multiple threads simultaneously
+
+== Requirements
+
+ruby-prof requires Ruby 1.9.3 or higher. Please note some ruby
+releases have known bugs which cause ruby-prof problems, like
+incorrect measurements. We suggest to use the latest minor patch level
+release if possible. In particular, on the 2.1 branch of ruby you
+should use 2.1.5.
+
+If you are running Linux or Unix you'll need a C compiler so the extension
+can be compiled when it is installed.
+
+If you are running Windows, then you may need to install the
+Windows specific RubyGem which includes an already built extension (see Install section).
+
+== Install
+
+The easiest way to install ruby-prof is by using Ruby Gems.  To install:
+
+  gem install ruby-prof
+
+If you're on windows then please install the devkit first so that it can compile.
+
+== Usage
+
+There are two ways of running ruby-prof, via the command line or via its API.
+
+=== ruby-prof executable
+
+The first is to use ruby-prof to run the Ruby program you want to
+profile. For more information refer to the documentation of the
+ruby-prof command.
+
+
+=== ruby-prof API
+
+The second way is to use the ruby-prof API to profile
+particular segments of code.
+
+  require 'ruby-prof'
+
+  # Profile the code
+  RubyProf.start
+  ...
+  [code to profile]
+  ...
+  result = RubyProf.stop
+
+  # Print a flat profile to text
+  printer = RubyProf::FlatPrinter.new(result)
+  printer.print(STDOUT)
+
+Alternatively, you can use a block to tell ruby-prof what
+to profile:
+
+  require 'ruby-prof'
+
+  # Profile the code
+  result = RubyProf.profile do
+    ...
+    [code to profile]
+    ...
+  end
+
+  # Print a graph profile to text
+  printer = RubyProf::GraphPrinter.new(result)
+  printer.print(STDOUT, {})
+
+ruby-prof also supports pausing and resuming profiling runs.
+
+  require 'ruby-prof'
+
+  # Profile the code
+  RubyProf.start
+  [code to profile]
+  RubyProf.pause
+  [other code]
+  RubyProf.resume
+  [code to profile]
+  result = RubyProf.stop
+
+Note that resume will automatically call start if a profiling run
+has not yet started.  In addition, resume can also take a block:
+
+  require 'ruby-prof'
+
+  # Profile the code
+  RubyProf.resume do
+    [code to profile]
+  end
+
+  data = RubyProf.stop
+
+With this usage, resume will automatically call pause at the
+end of the block.
+
+
+== Method and Thread Elimination
+
+ruby-prof supports eliminating specific methods and threads from profiling
+results. This is useful for reducing connectivity in the call graph, making it easier to
+identify the source of performance problems when using a graph printer.
+
+For example, consider Integer#times: it's hardly ever useful to know how much time is
+spent in the method itself. We're much more interested in how much the passed in block
+contributes to the time spent in the method which contains the Integer#times call.
+
+Methods are eliminated from the collected data by calling `eliminate_methods!` on the
+profiling result, before submitting it to a printer.
+
+  result = RubyProf.stop
+  result.eliminate_methods!([/Integer#times/])
+
+The argument given to `eliminate_methods!` is either an array of regular expressions, or
+the name of a file containing a list of regular expressions (line separated text).
+
+After eliminating methods the resulting profile will appear exactly as if those methods
+had been inlined at their call sites.
+
+In a similar manner, threads can be excluded so they are not profiled at all.  To do this,
+pass an array of threads to exclude to ruby-prof:
+
+  RubyProf::exclude_threads = [ thread2 ]
+  RubyProf.start
+
+Note that the excluded threads must be specified *before* profiling.
+
+
+== Benchmarking full load time including rubygems startup cost
+
+If you want to get a more accurate measurement of what takes all of a gem's bin/xxx
+command to load, you may want to also measure rubygems' startup penalty.
+You can do this by calling into bin/ruby-prof directly, ex:
+
+  $ gem which ruby-prof
+  g:/192/lib/ruby/gems/1.9.1/gems/ruby-prof-0.10.2/lib/ruby-prof.rb
+
+now run it thus (substitute lib/ruby-prof.rb with bin/ruby-prof):
+
+  $ ruby g:/192/lib/ruby/gems/1.9.1/gems/ruby-prof-0.10.2/bin/ruby-prof g:\192\bin\some_installed_gem_command
+
+or
+
+  $ ruby g:/192/lib/ruby/gems/1.9.1/gems/ruby-prof-0.10.2/bin/ruby-prof ./some_file_that_does_a_require_rubygems_at_the_beginning.rb
+
+
+== Profiling Rails
+
+To profile a Rails application it is vital to run it using production like
+settings (cache classes, cache view lookups, etc.).  Otherwise, Rail's
+dependency loading code will overwhelm any time spent in the application
+itself (our tests show that Rails dependency loading causes a roughly 6x
+slowdown).  The best way to do this is create a new Rails environment,
+profile.rb.
+
+So to profile Rails:
+
+1.  Create a new profile.rb environment.  Make sure to turn on cache_classes
+    and cache_template_loading.  Otherwise your profiling results will be
+    overwhelemed by the time Rails spends loading required files.  You should
+    likely turn off caching.
+
+2.  Add the ruby-prof to your gemfile:
+
+      group :profile do
+        gem 'ruby-prof'
+      end
+
+3.  Add the ruby prof rack adapter to your middleware stack.  One way to
+    do this is by adding the following code to config.ru:
+
+      if Rails.env.profile?
+        use Rack::RubyProf, :path => '/temp/profile'
+      end
+
+    The path is where you want profiling results to be stored.  By default the
+    rack adapter will generate a html call graph report and flat text report.
+
+4.  Now make a request to your running server.  New profiling information will
+    be generated for each request.  Note that each request will overwrite
+    the profiling reports created by the previous request!
+
+== Reports
+
+ruby-prof can generate a number of different reports:
+
+* Flat Reports
+* Graph Reports
+* HTML Graph Reports
+* Call graphs
+* Call stack reports
+* More!
+
+Flat profiles show the overall time spent in each method. They
+are a good way of quickly identifying which methods take the most time.
+An example of a flat profile and an explanation can be found in
+{examples/flat.txt}[http://github.com/ruby-prof/ruby-prof/tree/master/examples/flat.txt].
+
+There are several varieties of these -- run $ ruby-prof --help
+
+Graph profiles also show the overall time spent in each method. In
+addition, they also show which methods call the current method and which
+methods its calls.  Thus they are good for understanding how methods
+gets called and provide insight into the flow of your program. An
+example text graph profile is located at
+{examples/graph.txt}[http://github.com/ruby-prof/ruby-prof/tree/master/examples/graph.txt].
+
+HTML Graph profiles are the same as graph profiles, except output is
+generated in hyper-linked HTML. Since graph profiles can be quite large,
+the embedded links make it much easier to navigate the results. An
+example html graph profile is located at
+{examples/graph.html}[http://github.com/ruby-prof/ruby-prof/tree/master/examples/graph.html].
+
+Call graphs output results in the calltree profile format which is used
+by KCachegrind. Call graph support was generously donated by Carl
+Shimer. More information about the format can be found at the
+{KCachegrind}[http://kcachegrind.sourceforge.net/cgi-bin/show.cgi/KcacheGrindCalltreeFormat]
+site.
+
+Call stack reports produce a HTML visualization of the time spent in
+each execution path of the profiled code. An example can be found at
+{examples/stack.html}[http://github.com/ruby-prof/ruby-prof/tree/master/examples/stack.html].
+
+Another good example: [http://twitpic.com/28z94a]
+
+Finally, there's a so called MultiPrinter which can generate several
+reports in one profiling run. See
+{examples/multi.stack.html}[http://github.com/ruby-prof/ruby-prof/tree/master/examples/multi.stack.html].
+
+There is also a graphviz .dot visualiser.
+
+== Printers
+
+Reports are created by printers.  Supported printers include:
+
+* RubyProf::FlatPrinter - Creates a flat report in text format
+* RubyProf::FlatPrinterWithLineNumbers - same as above but more verbose
+* RubyProf::GraphPrinter - Creates a call graph report in text format
+* RubyProf::GraphHtmlPrinter - Creates a call graph report in HTML (separate files per thread)
+* RubyProf::DotPrinter - Creates a call graph report in GraphViz's DOT format which can be converted to an image
+* RubyProf::CallTreePrinter - Creates a call tree report compatible with KCachegrind.
+* RubyProf::CallStackPrinter - Creates a HTML visualization of the Ruby stack
+* RubyProf::MultiPrinter - Uses the other printers to create several reports in one profiling run
+* More!
+
+To use a printer:
+
+  ...
+  result = RubyProf.stop
+  printer = RubyProf::GraphPrinter.new(result)
+  printer.print(STDOUT, :min_percent => 2)
+
+The first parameter is any writable IO object such as STDOUT or a file.
+The second parameter, specifies the minimum percentage a method must take
+to be printed.  Percentages should be specified as integers in the range 0 to 100.
+For more information please see the documentation for the different printers.
+
+The other option is :print_file => true (default false), which adds the filename to the
+output (GraphPrinter only).
+
+The MultiPrinter differs from the other printers in that it requires a directory path
+and a basename for the files it produces.
+
+   printer = RubyProf::MultiPrinter.new(result)
+   printer.print(:path => ".", :profile => "profile")
+
+
+== Measurements
+
+Depending on the mode and platform, ruby-prof can measure various
+aspects of a Ruby program.  Supported measurements include:
+
+* wall time (RubyProf::WALL_TIME)
+* process time (RubyProf::PROCESS_TIME)
+* cpu time (RubyProf::CPU_TIME)
+* object allocations (RubyProf::ALLOCATIONS)
+* memory usage (RubyProf::MEMORY)
+* garbage collection time (RubyProf::GC_TIME)
+* garbage collections runs (RubyProf::GC_RUNS)
+
+Wall time measures the real-world time elapsed between any two moments.
+If there are other processes concurrently running on the system
+that use significant CPU or disk time during a profiling run
+then the reported results will be larger than expected.
+
+Process time measures the time used by a process between any two moments.
+It is unaffected by other processes concurrently running
+on the system. Note that Windows does not support measuring process
+times.
+
+CPU time uses the CPU clock counter to measure time.  The returned
+values are dependent on the correctly setting the CPU's frequency.
+This mode is only supported on Pentium or PowerPC platforms (linux only).
+
+Object allocation reports show how many objects each method in
+a program allocates.  This support was added by Sylvain Joyeux
+and requires a patched Ruby interpreter. See below.
+
+Memory usage reports show how much memory each method in a program
+uses.  This support was added by Alexander Dymo and requires a
+patched Ruby interpreter. See below.
+
+Garbage collection time reports how much time is spent in Ruby's
+garbage collector during a profiling session. This support was added
+by Jeremy Kemper and requires a patched Ruby interpreter. See below.
+
+Garbage collection runs report how many times Ruby's garbage collector
+is invoked during a profiling session. This support was added by
+Jeremy Kemper and requires a patched Ruby interpreter. See below.
+
+Ruby patches: all of the patches to Ruby are included in the
+railsexpress patchsets for rvm, see https://github.com/skaes/rvm-patchsets
+
+To set the measurement:
+
+* RubyProf.measure_mode = RubyProf::WALL_TIME
+* RubyProf.measure_mode = RubyProf::PROCESS_TIME
+* RubyProf.measure_mode = RubyProf::CPU_TIME
+* RubyProf.measure_mode = RubyProf::ALLOCATIONS
+* RubyProf.measure_mode = RubyProf::MEMORY
+* RubyProf.measure_mode = RubyProf::GC_TIME
+* RubyProf.measure_mode = RubyProf::GC_RUNS
+
+The default value is RubyProf::WALL_TIME.
+
+You may also specify the measure_mode by using the RUBY_PROF_MEASURE_MODE
+environment variable:
+
+* export RUBY_PROF_MEASURE_MODE=wall
+* export RUBY_PROF_MEASURE_MODE=process
+* export RUBY_PROF_MEASURE_MODE=cpu
+* export RUBY_PROF_MEASURE_MODE=allocations
+* export RUBY_PROF_MEASURE_MODE=memory
+* export RUBY_PROF_MEASURE_MODE=gc_time
+* export RUBY_PROF_MEASURE_MODE=gc_runs
+
+On Linux, process time is measured using the clock method provided
+by the C runtime library. Note that the clock method does not
+report time spent in the kernel or child processes and therefore
+does not measure time spent in methods such as Kernel.sleep method.
+If you need to measure these values, then use wall time.  Wall time
+is measured using the gettimeofday kernel method.
+
+If you set the clock mode to PROCESS_TIME, then timings are read using
+the clock method provided by the C runtime library.  Note though,
+these values are wall times on Windows and not process times like on
+Linux.  Wall time is measured using the GetLocalTime API.
+
+If you use wall time, the results will be affected by other
+processes running on your computer, network delays, disk access,
+etc.  As result, for the best results, try to make sure your
+computer is only performing your profiling run and is
+otherwise quiescent.
+
+== Multi-threaded Applications
+
+Unfortunately, Ruby does not provide an internal api
+for detecting thread context switches in 1.8.  As a result, the
+timings ruby-prof reports for each thread may be slightly
+inaccurate.  In particular, this will happen for newly
+spawned threads that go to sleep immediately (their first call).
+For instance, if you use Ruby's timeout library to wait for 2 seconds,
+the 2 seconds will be assigned to the foreground thread
+and not the newly created background thread.  These errors
+can largely be avoided if the background thread performs any
+operation before going to sleep.
+
+== Performance
+
+Significant effort has been put into reducing ruby-prof's overhead
+as much as possible.  Our tests show that the overhead associated
+with profiling code varies considerably with the code being
+profiled.  Most programs will run approximately twice as slow
+while highly recursive programs (like the fibonacci series test)
+will run three times slower.
+
+== License
+
+See LICENSE for license information.
+
+== Development
+
+Code is located at https://github.com/ruby-prof/ruby-prof
+
+Google group/mailing list: http://groups.google.com/group/ruby-optimization or start a github issue.
diff --git a/app/server/vendor/ruby-prof-0.15.8/Rakefile b/app/server/vendor/ruby-prof-0.15.8/Rakefile
new file mode 100755
index 0000000..d567bb6
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/Rakefile
@@ -0,0 +1,113 @@
+# encoding: utf-8
+
+require "rubygems/package_task"
+require "rake/extensiontask"
+require "rake/testtask"
+require "rdoc/task"
+require "date"
+require "rake/clean"
+begin
+  require "bundler/setup"
+  Bundler::GemHelper.install_tasks
+  [:build, :install, :release].each {|t| Rake::Task[t].enhance [:rdoc] }
+rescue LoadError
+  $stderr.puts "Install bundler to get support for simplified gem publishing"
+end
+
+# To release a version of ruby-prof:
+#   * Update lib/ruby-prof/version.rb
+#   * Update CHANGES
+#   * git commit to commit files
+#   * rake clobber to remove extra files
+#   * rake compile to build windows gems
+#   * rake package to create the gems
+#   * Tag the release (git tag 0.10.1)
+#   * Push to ruybgems.org (gem push pkg/<gem files>)
+# For a ruby only release, just run
+#   * rake release
+# it will push changes to github, tag the release, build the package and upload it to rubygems.org
+# and in case you forgot to increment the version number or have uncommitted changes, it will refuse to work
+
+GEM_NAME = 'ruby-prof'
+SO_NAME = 'ruby_prof'
+
+default_spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
+
+# specify which versions/builds to cross compile
+Rake::ExtensionTask.new do |ext|
+  ext.gem_spec = default_spec
+  ext.name = SO_NAME
+  ext.ext_dir = "ext/#{SO_NAME}"
+  ext.lib_dir = "lib/#{RUBY_VERSION.sub(/\.\d$/, '')}"
+  ext.cross_compile = true
+  ext.cross_platform = ['x86-mswin32-60', 'x86-mingw32-60']
+end
+
+# Rake task to build the default package
+Gem::PackageTask.new(default_spec) do |pkg|
+  pkg.need_tar = true
+end
+
+# make sure rdoc has been built when packaging
+# why do we ship rdoc as part of the gem?
+Rake::Task[:package].enhance [:rdoc]
+
+# Setup Windows Gem
+if RUBY_PLATFORM.match(/win32|mingw32/)
+  # Windows specification
+  win_spec = default_spec.clone
+  win_spec.platform = Gem::Platform::CURRENT
+  win_spec.files += Dir.glob('lib/**/*.so')
+  win_spec.instance_variable_set(:@cache_file, nil) # Hack to work around gem issue
+
+  # Unset extensions
+  win_spec.extensions = nil
+
+  # Rake task to build the windows package
+  Gem::PackageTask.new(win_spec) do |pkg|
+    pkg.need_tar = false
+  end
+end
+
+# ---------  RDoc Documentation ------
+desc "Generate rdoc documentation"
+RDoc::Task.new("rdoc") do |rdoc|
+  rdoc.rdoc_dir = 'doc'
+  rdoc.title    = "ruby-prof"
+  # Show source inline with line numbers
+  rdoc.options << "--line-numbers"
+  # Make the readme file the start page for the generated html
+  rdoc.options << '--main' << 'README.rdoc'
+  rdoc.rdoc_files.include('bin/*',
+                          'doc/*.rdoc',
+                          'examples/flat.txt',
+                          'examples/graph.txt',
+                          'examples/graph.html',
+                          'lib/**/*.rb',
+                          'ext/ruby_prof/ruby_prof.c',
+                          'ext/ruby_prof/measure_*.h',
+                          'README.rdoc',
+                          'LICENSE')
+end
+
+task :default => :test
+
+for file in Dir['lib/**/*.{o,so,bundle}']
+  CLEAN.include file
+end
+for file in Dir['doc/**/*.{txt,dat,png,html}']
+  CLEAN.include file
+end
+CLEAN.reject!{|f| !File.exist?(f)}
+task :clean do
+  # remove tmp dir contents completely after cleaning
+  FileUtils.rm_rf('tmp/*')
+end
+
+desc 'Run the ruby-prof test suite'
+Rake::TestTask.new do |t|
+  t.libs += %w(lib ext test)
+  t.test_files = Dir['test/**_test.rb']
+  t.verbose = true
+  t.warning = true
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/benchmarks/benchmark.rb b/app/server/vendor/ruby-prof-0.15.8/benchmarks/benchmark.rb
new file mode 100755
index 0000000..048eb11
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/benchmarks/benchmark.rb
@@ -0,0 +1,20 @@
+require 'ruby-prof'
+require 'benchmark'
+
+def go
+end
+
+puts Benchmark.realtime {
+ RubyProf.profile do
+  100000.times { go }
+ end
+}
+
+for n in [5, 100] do
+ n.times { Thread.new { sleep }}
+ puts Benchmark.realtime {
+  RubyProf.profile do
+    100000.times { go }
+  end
+ }
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/bin/ruby-prof b/app/server/vendor/ruby-prof-0.15.8/bin/ruby-prof
new file mode 100755
index 0000000..807a123
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/bin/ruby-prof
@@ -0,0 +1,340 @@
+#! /usr/bin/env ruby
+
+# == Synopsis
+#
+# Profiles a Ruby program.
+#
+# == Usage
+#
+# ruby_prof [options] <script.rb> [--] [script-options]"
+#
+# Various options:
+#        run "$ ruby-prof --help" to see them
+#
+# See also the readme "reports" section for the various outputs
+
+# First require ruby-prof
+require 'rubygems'
+require 'ruby-prof'
+
+# Now setup option parser
+require 'ostruct'
+require 'optparse'
+
+module RubyProf
+  class Cmd
+    attr_accessor :options
+
+    def initialize
+      setup_options
+      parse_args
+
+      load_pre_libs
+      load_pre_execs
+    end
+
+    def setup_options
+      @options = OpenStruct.new
+      options.printer = RubyProf::FlatPrinter
+      options.min_percent = 0
+      options.file = nil
+      options.replace_prog_name = false
+      options.specialized_instruction = false
+
+      options.pre_libs = Array.new
+      options.pre_execs = Array.new
+    end
+
+    def option_parser
+      OptionParser.new do |opts|
+        opts.banner = "ruby_prof #{RubyProf::VERSION}\n" +
+            "Usage: ruby-prof [options] <script.rb> [--] [profiled-script-command-line-options]"
+
+        opts.separator ""
+        opts.separator "Options:"
+
+        opts.on('-p printer', '--printer=printer', [:flat, :flat_with_line_numbers, :graph, :graph_html, :call_tree, :call_stack, :dot, :multi],
+                'Select a printer:',
+                '  flat - Prints a flat profile as text (default).',
+                '  flat_with_line_numbers - same as flat, with line numbers.',
+                '  graph - Prints a graph profile as text.',
+                '  graph_html - Prints a graph profile as html.',
+                '  call_tree - format for KCacheGrind',
+                '  call_stack - prints a HTML visualization of the call tree',
+                '  dot - Prints a graph profile as a dot file',
+                '  multi - Creates several reports in output directory'
+        ) do |printer|
+
+
+          case printer
+          when :flat
+            options.printer = RubyProf::FlatPrinter
+          when :flat_with_line_numbers
+            options.printer = RubyProf::FlatPrinterWithLineNumbers
+          when :graph
+            options.printer = RubyProf::GraphPrinter
+          when :graph_html
+            options.printer = RubyProf::GraphHtmlPrinter
+          when :call_tree
+            options.printer = RubyProf::CallTreePrinter
+          when :call_stack
+            options.printer = RubyProf::CallStackPrinter
+          when :dot
+            options.printer = RubyProf::DotPrinter
+          when :multi
+            options.printer = RubyProf::MultiPrinter
+          end
+        end
+
+        opts.on('-m min_percent', '--min_percent=min_percent', Float,
+                'The minimum percent a method must take before ',
+                '  being included in output reports.',
+                '  this option is not supported for call tree.') do |min_percent|
+          options.min_percent = min_percent
+        end
+
+        opts.on('-f path', '--file=path',
+                'Output results to a file instead of standard out.') do |file|
+          options.file = file
+          options.old_wd = Dir.pwd
+        end
+
+        opts.on('--mode=measure_mode',
+                [:process, :wall, :cpu, :allocations, :memory, :gc_runs, :gc_time],
+                'Select what ruby-prof should measure:',
+                '  process - Process time (default).',
+                '  wall - Wall time.',
+                '  cpu - CPU time (Pentium and PowerPCs only).',
+                '  allocations - Object allocations (requires patched Ruby interpreter).',
+                '  memory - Allocated memory in KB (requires patched Ruby interpreter).',
+                '  gc_runs - Number of garbage collections (requires patched Ruby interpreter).',
+                '  gc_time - Time spent in garbage collection (requires patched Ruby interpreter).') do |measure_mode|
+
+          case measure_mode
+          when :process
+            options.measure_mode = RubyProf::PROCESS_TIME
+          when :wall
+            options.measure_mode = RubyProf::WALL_TIME
+          when :cpu
+            options.measure_mode = RubyProf::CPU_TIME
+          when :allocations
+            options.measure_mode = RubyProf::ALLOCATIONS
+          when :memory
+            options.measure_mode = RubyProf::MEMORY
+          when :gc_runs
+            options.measure_mode = RubyProf::GC_RUNS
+          when :gc_time
+            options.measure_mode = RubyProf::GC_TIME
+          end
+        end
+
+        opts.on('-s sort_mode', '--sort=sort_mode', [:total, :self, :wait, :child],
+                'Select how ruby-prof results should be sorted:',
+                '  total - Total time',
+                '  self - Self time',
+                '  wait - Wait time',
+                '  child - Child time') do |sort_mode|
+
+          options.sort_method = case sort_mode
+                                when :total
+                                  :total_time
+                                when :self
+                                  :self_time
+                                when :wait
+                                  :wait_time
+                                when :child
+                                  :children_time
+                                end
+        end
+
+        opts.on("--replace-progname", "Replace $0 when loading the .rb files.") do
+          options.replace_prog_name = true
+        end
+
+        if defined?(RubyVM)
+          opts.on("--specialized-instruction", "Turn on specified instruction.") do
+            options.specialized_instruction = true
+          end
+        end
+
+        opts.on_tail("-h", "--help", "Show help message") do
+          puts opts
+          exit
+        end
+
+        opts.on_tail("--version", "Show version #{RubyProf::VERSION}") do
+          puts "ruby_prof " + RubyProf::VERSION
+          exit
+        end
+
+        opts.on("-v","Show version, set $VERBOSE to true, profile script if option given") do
+          puts "ruby version: " + [RUBY_PATCHLEVEL, RUBY_PLATFORM, RUBY_VERSION].join(' ')
+          $VERBOSE = true
+        end
+
+        opts.on("-d", "Set $DEBUG to true") do
+          $DEBUG = true
+        end
+
+        opts.on('-R lib', '--require-noprof lib', 'require a specific library (not profiled)') do |lib|
+          options.pre_libs << lib
+        end
+
+        opts.on('-E code', '--eval-noprof code', 'execute the ruby statements (not profiled)') do |code|
+          options.pre_execs << code
+        end
+
+        opts.on('-x regexp', '--exclude regexp', 'exclude methods by regexp (see method elimination)') do|meth|
+          options.eliminate_methods ||= []
+          options.eliminate_methods << Regexp.new(meth)
+        end
+
+        opts.on('-X file', '--exclude-file file', 'exclude methods by regexp listed in file (see method elimination)') do|file|
+          options.eliminate_methods_files ||= []
+          options.eliminate_methods_files << file
+        end
+
+        opts.on('--exclude-common-cycles', 'make common iterators like Integer#times appear inlined') do |meth|
+          options.eliminate_methods ||= []
+          options.eliminate_methods += %w{
+            Integer#times
+            Integer#upto
+            Integer#downto
+            Enumerator#each
+            Enumerator#each_with_index
+            Enumerator#each_with_object
+
+            Array#each
+            Array#each_index
+            Array#reverse_each
+            Array#map
+
+            Hash#each
+            Hash#each_pair
+            Hash#each_key
+            Hash#each_value
+
+            Range#each
+            Enumerable#each_cons
+            Enumerable#each_entry
+            Enumerable#each_slice
+            Enumerable#each_with_index
+            Enumerable#each_with_object
+            Enumerable#reverse_each
+            Enumerable#inject
+            Enumerable#collect
+            Enumerable#reduce
+          }
+          #TODO: may be the whole Enumerable module should be excluded via 'Enumerable#.*', we need feedback on use cases.
+        end
+
+        opts.on('--exclude-common-callbacks', 'make common callbacks invocations like Integer#times appear inlined so you can see call origins in graph') do|meth|
+          options.eliminate_methods ||= []
+          options.eliminate_methods += %w{
+            Method#call
+            Proc#call
+            ActiveSupport::Callbacks::ClassMethods#__run_callback
+          }
+        end
+      end
+    end
+
+    def parse_args
+      # Make sure the user specified at least one file
+      if ARGV.length < 1 and not options.exec
+        puts self.option_parser
+        puts ""
+        puts "Must specify a script to run"
+        exit(-1)
+      end
+
+      self.option_parser.parse! ARGV
+
+      if options.printer == RubyProf::MultiPrinter
+        options.file ||= "."
+        options.old_wd ||= Dir.pwd
+      end
+    rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, OptionParser::MissingArgument => e
+      puts self.option_parser
+      puts e.message
+      exit(-1)
+    end
+
+    def load_pre_libs
+      options.pre_libs.each do |lib|
+        require lib
+      end
+    end
+
+    def load_pre_execs
+      options.pre_execs.each do |exec|
+        eval(exec)
+      end
+    end
+
+    def run
+      # Get the script we will execute
+      script = ARGV.shift
+      if options.replace_prog_name
+        $0 = File.expand_path(script)
+      end
+
+      # Set VM compile option
+      if defined?(RubyVM)
+        RubyVM::InstructionSequence.compile_option = {
+            :trace_instruction => true,
+            :specialized_instruction => options.specialized_instruction
+        }
+      end
+
+      # Set the measure mode
+      RubyProf.measure_mode = options.measure_mode if options.measure_mode
+      RubyProf.start_script(script)
+    end
+  end
+end
+
+# Parse command line options
+cmd = RubyProf::Cmd.new
+
+# Install at_exit handler.  It is important that we do this
+# before loading the scripts so our at_exit handler run
+# *after* any other one that will be installed.
+
+at_exit {
+  # Stop profiling
+  result = RubyProf.stop
+
+  # Eliminate unwanted methods from call graph
+  if cmd.options.eliminate_methods
+    result.eliminate_methods!(cmd.options.eliminate_methods)
+  end
+
+  if cmd.options.eliminate_methods_files
+    cmd.options.eliminate_methods_files.each {|f| result.eliminate_methods!(f)}
+  end
+
+  # Create a printer
+  printer = cmd.options.printer.new(result)
+  printer_options = {:min_percent => cmd.options.min_percent, :sort_method => cmd.options.sort_method}
+
+  # Get output
+  if cmd.options.file
+    # write it relative to the dir they *started* in, as it's a bit surprising to write it in the dir they end up in.
+    Dir.chdir(cmd.options.old_wd) do
+      if printer.is_a?(RubyProf::MultiPrinter)
+        printer.print(printer_options.merge(:path => cmd.options.file))
+      else
+        File.open(cmd.options.file, 'w') do |file|
+          printer.print(file, printer_options)
+        end
+      end
+    end
+  else
+    # Print out results
+    printer.print(STDOUT, printer_options)
+  end
+}
+
+# Now profile some code
+cmd.run
diff --git a/app/server/vendor/ruby-prof-0.15.8/bin/ruby-prof-check-trace b/app/server/vendor/ruby-prof-0.15.8/bin/ruby-prof-check-trace
new file mode 100755
index 0000000..9405a71
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/bin/ruby-prof-check-trace
@@ -0,0 +1,45 @@
+#!/usr/bin/env ruby
+
+stacks = Hash.new{|h,k| h[k] = Hash.new{|h,k| h[k] = []}}
+i = 0
+File.open(ARGV[0]).each_line do |l|
+  i += 1
+  unless l =~ /^(\d+):(\d+): *\d+ms *([^ ]+) *(.*): *(\d+) *(.+)$/
+    next if l =~/^ *$/
+    puts "line doesn't match: #{l}"
+    next
+  end
+  details = $1.to_i, $2.to_i, $3, $4, $5.to_i, $6
+  thread, fiber, event, file, line, method = *details
+  # puts method
+  stack = stacks[thread][fiber]
+  case event
+  when 'call', 'c-call'
+    stack << method
+  when 'return', 'c-return'
+    last_method = stack.pop
+    if last_method != method
+      puts "LINE #{i}: return event without call: #{method}"
+      puts "STACK: #{stack.inspect}"
+      if stack.find(method)
+        puts "fixing stack"
+        while (popped = stack.pop) && (popped != method)
+          puts "popped #{popped}"
+        end
+      else
+        raise "stack unfixable"
+      end
+      # stack << last_method
+    end
+  when 'line'
+    last_method = stack[-1]
+    if last_method != method
+      unless stack.find(method)
+        raise "LINE #{i}: line event without call: #{method}"
+      end
+    end
+  else
+    puts "unkown event"
+  end
+end
+puts stacks.inspect
diff --git a/app/server/vendor/ruby-prof-0.15.8/examples/flat.txt b/app/server/vendor/ruby-prof-0.15.8/examples/flat.txt
new file mode 100755
index 0000000..28d9afe
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/examples/flat.txt
@@ -0,0 +1,55 @@
+= Flat Profiles
+
+Flat profiles show the total amount of time spent in each method.
+As an example, here is the output from running printers_test.rb.
+
+Thread ID: 21277412
+ %self  cumulative  total     self   children  calls self/call total/call  name
+ 46.34     4.06      8.72     4.06     4.66      501     0.01     0.02     Integer#upto
+ 23.89     6.16      2.09     2.09     0.00       61     0.03     0.03     Kernel.sleep
+ 15.12     7.48      1.33     1.33     0.00   250862     0.00     0.00     Fixnum#%
+ 14.13     8.72      1.24     1.24     0.00   250862     0.00     0.00     Fixnum#==
+  0.18     8.74      0.02     0.02     0.00        1     0.02     0.02     Array#each_index
+  0.17     8.75      6.64     0.01     6.63      500     0.00     0.01     Object#is_prime
+  0.17     8.77      6.66     0.01     6.64        1     0.01     6.66     Array#select
+  0.00     8.77      0.00     0.00     0.00      501     0.00     0.00     Fixnum#-
+  0.00     8.77      0.00     0.00     0.00        1     0.00     0.00     Array#first
+  0.00     8.77      0.00     0.00     0.00        1     0.00     0.00     Array#length
+  0.00     8.77      0.00     0.00     0.00        1     0.00     0.00     Array#initialize
+  0.00     8.77      8.77     0.00     8.77        1     0.00     8.77     Object#run_primes
+  0.00     8.77      0.00     0.00     0.00        1     0.00     0.00     Integer#to_int
+  0.00     8.77      6.66     0.00     6.66        1     0.00     6.66     Object#find_primes
+  0.00     8.77      2.09     0.00     2.09        1     0.00     2.09     Object#find_largest
+  0.00     8.77      0.02     0.00     0.02        1     0.00     0.02     Object#make_random_array
+  0.00     8.77      0.00     0.00     0.00        1     0.00     0.00     Class#new
+  0.00     8.77      0.00     0.00     0.00      500     0.00     0.00     Array#[]=
+  0.00     8.77      0.00     0.00     0.00       61     0.00     0.00     Fixnum#>
+  0.00     8.77      0.00     0.00     0.00       61     0.00     0.00     Array#[]
+  0.00     8.77      8.77     0.00     8.77        1     0.00     8.77     #toplevel
+  0.00     8.77      0.00     0.00     0.00      500     0.00     0.00     Kernel.rand
+
+All values are in seconds. 
+
+The columns are:
+
+	%self        - The percentage of time spent in this method, derived from self_time/total_time
+	cumulative   - The sum of the time spent in this method and all the methods listed above it.
+	total        - The time spent in this method and its children.
+	self         - The time spent in this method.
+	children     - The time spent in this method's children.
+	calls        - The number of times this method was called.
+	self/call    - The average time spent per call in this method.
+  total/call   - The average time spent per call in this method and its children.
+  name         - The name of the method.
+
+Methods are sorted based on %self, therefore the methods that execute the longest are listed
+first.
+
+The interpretation of method names is:
+* #toplevel - The root method that calls all other methods
+* MyObject#test - An instance method "test" of the class "MyObject"
+* <Object:MyObject>#test - The <> characters indicate a singleton method on a singleton class.
+
+For example, wee can see that Integer#upto took the most time, 4.06 seconds.  An additional
+4.66 seconds were spent in its children, for a total time of 8.72 seconds.
+
diff --git a/app/server/vendor/ruby-prof-0.15.8/examples/graph.dot b/app/server/vendor/ruby-prof-0.15.8/examples/graph.dot
new file mode 100755
index 0000000..ed48ef4
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/examples/graph.dot
@@ -0,0 +1,84 @@
+digraph "Profile" {
+labelloc=t;
+labeljust=l;
+subgraph "Thread 70140045951280" {
+70140046535720 [label="setup\n(100%)"];
+70140046535720 -> 70140046535660 [label="1/1" fontsize=10 fontcolor="#666666"];
+70140046535660 [label="run_primes\n(100%)"];
+70140046535660 -> 70140046534940 [label="1/1" fontsize=10 fontcolor="#666666"];
+70140046535660 -> 70140046535640 [label="1/1" fontsize=10 fontcolor="#666666"];
+70140046535660 -> 70140046534640 [label="1/1" fontsize=10 fontcolor="#666666"];
+70140046534940 [label="find_primes\n(93%)"];
+70140046534940 -> 70140046534920 [label="1/1" fontsize=10 fontcolor="#666666"];
+70140046534920 [label="select\n(93%)"];
+70140046534920 -> 70140046534840 [label="200/200" fontsize=10 fontcolor="#666666"];
+70140046534840 [label="is_prime\n(90%)"];
+70140046534840 -> 70140046534820 [label="200/201" fontsize=10 fontcolor="#666666"];
+70140046534820 [label="upto\n(87%)"];
+70140046535640 [label="make_random_array\n(7%)"];
+70140046535640 -> 70140046535500 [label="1/1" fontsize=10 fontcolor="#666666"];
+70140046535640 -> 70140046535600 [label="1/1" fontsize=10 fontcolor="#666666"];
+70140046535500 [label="each_index\n(6%)"];
+70140046535500 -> 70140046535140 [label="200/200" fontsize=10 fontcolor="#666666"];
+70140046535140 [label="rand\n(4%)"];
+70140046535140 -> 70140046535100 [label="200/200" fontsize=10 fontcolor="#666666"];
+70140046535100 [label="respond_to_missing?\n(1%)"];
+70140046534640 [label="find_largest\n(1%)"];
+70140046534640 -> 70140046534820 [label="1/201" fontsize=10 fontcolor="#666666"];
+70140046534640 -> 70140046534620 [label="1/1" fontsize=10 fontcolor="#666666"];
+70140046535600 [label="new\n(0%)"];
+70140046535600 -> 70140046535580 [label="1/1" fontsize=10 fontcolor="#666666"];
+70140046535580 [label="initialize\n(0%)"];
+70140046534620 [label="first\n(0%)"];
+}
+subgraph cluster_70140046962360 {
+label = "PrintersTest";
+fontcolor = "#666666";
+fontsize = 16;
+color = "#666666";
+70140046535720;
+}
+subgraph cluster_70140046962240 {
+label = "Object";
+fontcolor = "#666666";
+fontsize = 16;
+color = "#666666";
+70140046535660;
+70140046535640;
+70140046534940;
+70140046534840;
+70140046534640;
+}
+subgraph cluster_70140046962040 {
+label = "Class";
+fontcolor = "#666666";
+fontsize = 16;
+color = "#666666";
+70140046535600;
+}
+subgraph cluster_70140046961920 {
+label = "Array";
+fontcolor = "#666666";
+fontsize = 16;
+color = "#666666";
+70140046535580;
+70140046535500;
+70140046534920;
+70140046534620;
+}
+subgraph cluster_70140046961720 {
+label = "Kernel";
+fontcolor = "#666666";
+fontsize = 16;
+color = "#666666";
+70140046535140;
+70140046535100;
+}
+subgraph cluster_70140046961280 {
+label = "Integer";
+fontcolor = "#666666";
+fontsize = 16;
+color = "#666666";
+70140046534820;
+}
+}
diff --git a/app/server/vendor/ruby-prof-0.15.8/examples/graph.html b/app/server/vendor/ruby-prof-0.15.8/examples/graph.html
new file mode 100755
index 0000000..46b1f9f
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/examples/graph.html
@@ -0,0 +1,823 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<style media="all" type="text/css">
+    table {
+	    border-collapse: collapse;
+	    border: 1px solid #CCC;
+	    font-family: Verdana, Arial, Helvetica, sans-serif;
+	    font-size: 9pt;
+	    line-height: normal;
+    }
+
+    th {
+	    text-align: center;
+	    border-top: 1px solid #FB7A31;
+	    border-bottom: 1px solid #FB7A31;
+	    background: #FFC;
+	    padding: 0.3em;
+	    border-left: 1px solid silver;
+    }
+
+		tr.break td {
+		  border: 0;
+	    border-top: 1px solid #FB7A31;
+			padding: 0;
+			margin: 0;
+		}
+
+    tr.method td {
+			font-weight: bold;
+    }
+
+    td {
+	    padding: 0.3em;
+    }
+
+    td:first-child {
+	    width: 190px;
+	    }
+
+    td {
+	    border-left: 1px solid #CCC;
+	    text-align: center;
+    }	
+  </style>
+</head>
+<body>
+<h1> Graph Profile</h1>
+<p>Graph profiles show how long each method runs, which methods call it
+  and which methods it calls. To understand how to read a graph profile, refer to
+   the <a href="graph.txt">documentation</a> for the text graph report. </p>
+<p>The main advantage of an HTML graph format versus the text format is the use of
+  hyperlinks to jump between methods. This makes it easier to understand the flow
+of control through a program and which methods take the most time.</p>
+<p>Below is the  output from running printers_test.rb reproduced in HTML. </p>
+<p>Profile Report</p>
+
+<table>
+  <tr>
+    <th>Thread ID</th>
+    <th>Total Time</th>
+  </tr>
+  <tr>
+    <td><a href="#21277412">21277412</a></td>
+    <td>8.766</td>
+  </tr>
+</table>
+
+<h2><a name="21277412">Thread 21277412</a></h2>
+<table>
+  <tr>
+    <th> %Total</th>
+    <th> %Self</th>
+    <th> Total</th>
+    <th> Self</th>
+    <th> Children</th>
+    <th> Calls</th>
+    <th>Name</th>
+  </tr>
+
+  <tr class="method">
+    <td> 100.00%</td>
+    <td> 0.00%</td>
+    <td> 8.77</td>
+    <td> 0.00</td>
+    <td> 8.77</td>
+    <td> 1</td>
+    <td><a name="_toplevel_21277412">#toplevel</a></td>
+  </tr>
+
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 8.77</td>
+    <td> 0.00</td>
+    <td> 8.77</td>
+    <td> 1/1</td>
+    <td><a href="#Object_run_primes_21277412">Object#run_primes</a></td>
+  </tr>
+
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 8.77</td>
+    <td> 0.00</td>
+    <td> 8.77</td>
+    <td> 1/1</td>
+    <td><a href="#_toplevel_21277412">#toplevel</a></td>
+  </tr>
+  <tr class="method">
+    <td> 100.00%</td>
+    <td> 0.00%</td>
+    <td> 8.77</td>
+    <td> 0.00</td>
+    <td> 8.77</td>
+    <td> 1</td>
+    <td><a name="Object_run_primes_21277412">Object#run_primes</a></td>
+  </tr>
+
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.02</td>
+    <td> 0.00</td>
+    <td> 0.02</td>
+    <td> 1/1</td>
+    <td><a href="#Object_make_random_array_21277412">Object#make_random_array</a></td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 2.09</td>
+    <td> 0.00</td>
+    <td> 2.09</td>
+    <td> 1/1</td>
+    <td><a href="#Object_find_largest_21277412">Object#find_largest</a></td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 6.66</td>
+    <td> 0.00</td>
+    <td> 6.66</td>
+    <td> 1/1</td>
+    <td><a href="#Object_find_primes_21277412">Object#find_primes</a></td>
+  </tr>
+
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 6.63</td>
+    <td> 4.06</td>
+    <td> 2.56</td>
+    <td> 500/501</td>
+    <td><a href="#Object_is_prime_21277412">Object#is_prime</a></td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 2.09</td>
+    <td> 0.00</td>
+    <td> 2.09</td>
+    <td> 1/501</td>
+    <td><a href="#Object_find_largest_21277412">Object#find_largest</a></td>
+  </tr>
+  <tr class="method">
+    <td> 99.48%</td>
+    <td> 46.34%</td>
+    <td> 8.72</td>
+    <td> 4.06</td>
+    <td> 4.66</td>
+    <td> 501</td>
+    <td><a name="Integer_upto_21277412">Integer#upto</a></td>
+  </tr>
+
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 61/61</td>
+    <td><a href="#Array_[]_21277412">Array#[]</a></td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 61/61</td>
+    <td><a href="#Fixnum_>_21277412">Fixnum#_</a></td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 2.09</td>
+    <td> 2.09</td>
+    <td> 0.00</td>
+    <td> 61/61</td>
+    <td><a href="#Kernel_sleep_21277412">Kernel.sleep</a></td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 1.24</td>
+    <td> 1.24</td>
+    <td> 0.00</td>
+    <td> 250862/250862</td>
+    <td><a href="#Fixnum____21277412">Fixnum#==</a></td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 1.33</td>
+    <td> 1.33</td>
+    <td> 0.00</td>
+    <td> 250862/250862</td>
+    <td><a href="#Fixnum_%_21277412">Fixnum#%</a></td>
+  </tr>
+
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 6.66</td>
+    <td> 0.01</td>
+    <td> 6.64</td>
+    <td> 1/1</td>
+    <td><a href="#Object_find_primes_21277412">Object#find_primes</a></td>
+  </tr>
+  <tr class="method">
+    <td> 75.93%</td>
+    <td> 0.17%</td>
+    <td> 6.66</td>
+    <td> 0.01</td>
+    <td> 6.64</td>
+    <td> 1</td>
+    <td><a name="Array_select_21277412">Array#select</a></td>
+  </tr>
+
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 6.64</td>
+    <td> 0.01</td>
+    <td> 6.63</td>
+    <td> 500/500</td>
+    <td><a href="#Object_is_prime_21277412">Object#is_prime</a></td>
+  </tr>
+
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 6.66</td>
+    <td> 0.00</td>
+    <td> 6.66</td>
+    <td> 1/1</td>
+    <td><a href="#Object_run_primes_21277412">Object#run_primes</a></td>
+  </tr>
+  <tr class="method">
+    <td> 75.93%</td>
+    <td> 0.00%</td>
+    <td> 6.66</td>
+    <td> 0.00</td>
+    <td> 6.66</td>
+    <td> 1</td>
+    <td><a name="Object_find_primes_21277412">Object#find_primes</a></td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 6.66</td>
+    <td> 0.01</td>
+    <td> 6.64</td>
+    <td> 1/1</td>
+    <td><a href="#Array_select_21277412">Array#select</a></td>
+  </tr>
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 6.64</td>
+    <td> 0.01</td>
+    <td> 6.63</td>
+    <td> 500/500</td>
+    <td><a href="#Array_select_21277412">Array#select</a></td>
+  </tr>
+  <tr class="method">
+    <td> 75.76%</td>
+    <td> 0.17%</td>
+    <td> 6.64</td>
+    <td> 0.01</td>
+    <td> 6.63</td>
+    <td> 500</td>
+    <td><a name="Object_is_prime_21277412">Object#is_prime</a></td>
+  </tr>
+
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 500/501</td>
+    <td><a href="#Fixnum_-_21277412">Fixnum#-</a></td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 6.63</td>
+    <td> 4.06</td>
+    <td> 2.56</td>
+    <td> 500/501</td>
+    <td><a href="#Integer_upto_21277412">Integer#upto</a></td>
+  </tr>
+
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 2.09</td>
+    <td> 0.00</td>
+    <td> 2.09</td>
+    <td> 1/1</td>
+    <td><a href="#Object_run_primes_21277412">Object#run_primes</a></td>
+  </tr>
+  <tr class="method">
+    <td> 23.89%</td>
+    <td> 0.00%</td>
+    <td> 2.09</td>
+    <td> 0.00</td>
+    <td> 2.09</td>
+    <td> 1</td>
+    <td><a name="Object_find_largest_21277412">Object#find_largest</a></td>
+  </tr>
+
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1/501</td>
+    <td><a href="#Fixnum_-_21277412">Fixnum#-</a></td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 2.09</td>
+    <td> 0.00</td>
+    <td> 2.09</td>
+    <td> 1/501</td>
+    <td><a href="#Integer_upto_21277412">Integer#upto</a></td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1/1</td>
+    <td><a href="#Array_first_21277412">Array#first</a></td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1/1</td>
+    <td><a href="#Array_length_21277412">Array#length</a></td>
+  </tr>
+
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 2.09</td>
+    <td> 2.09</td>
+    <td> 0.00</td>
+    <td> 61/61</td>
+    <td><a href="#Integer_upto_21277412">Integer#upto</a></td>
+  </tr>
+  <tr class="method">
+    <td> 23.89%</td>
+    <td> 23.89%</td>
+    <td> 2.09</td>
+    <td> 2.09</td>
+    <td> 0.00</td>
+    <td> 61</td>
+    <td><a name="Kernel_sleep_21277412">Kernel.sleep</a></td>
+  </tr>
+
+
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 1.33</td>
+    <td> 1.33</td>
+    <td> 0.00</td>
+    <td> 250862/250862</td>
+    <td><a href="#Integer_upto_21277412">Integer#upto</a></td>
+  </tr>
+  <tr class="method">
+    <td> 15.12%</td>
+    <td> 15.12%</td>
+    <td> 1.33</td>
+    <td> 1.33</td>
+    <td> 0.00</td>
+    <td> 250862</td>
+    <td><a name="Fixnum_%_21277412">Fixnum#%</a></td>
+  </tr>
+  
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 1.24</td>
+    <td> 1.24</td>
+    <td> 0.00</td>
+    <td> 250862/250862</td>
+    <td><a href="#Integer_upto_21277412">Integer#upto</a></td>
+  </tr>
+  <tr class="method">
+    <td> 14.13%</td>
+    <td> 14.13%</td>
+    <td> 1.24</td>
+    <td> 1.24</td>
+    <td> 0.00</td>
+    <td> 250862</td>
+    <td><a name="Fixnum____21277412">Fixnum#==</a></td>
+  </tr>
+  
+  
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.02</td>
+    <td> 0.00</td>
+    <td> 0.02</td>
+    <td> 1/1</td>
+    <td><a href="#Object_run_primes_21277412">Object#run_primes</a></td>
+  </tr>
+  <tr class="method">
+    <td> 0.18%</td>
+    <td> 0.00%</td>
+    <td> 0.02</td>
+    <td> 0.00</td>
+    <td> 0.02</td>
+    <td> 1</td>
+    <td><a name="Object_make_random_array_21277412">Object#make_random_array</a></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.02</td>
+    <td> 0.02</td>
+    <td> 0.00</td>
+    <td> 1/1</td>
+    <td><a href="#Array_each_index_21277412">Array#each_index</a></td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1/1</td>
+    <td><a href="#Class_new_21277412">Class#new</a></td>
+  </tr>
+  
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.02</td>
+    <td> 0.02</td>
+    <td> 0.00</td>
+    <td> 1/1</td>
+    <td><a href="#Object_make_random_array_21277412">Object#make_random_array</a></td>
+  </tr>
+  <tr class="method">
+    <td> 0.18%</td>
+    <td> 0.18%</td>
+    <td> 0.02</td>
+    <td> 0.02</td>
+    <td> 0.00</td>
+    <td> 1</td>
+    <td><a name="Array_each_index_21277412">Array#each_index</a></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 500/500</td>
+    <td><a href="#Kernel_rand_21277412">Kernel.rand</a></td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 500/500</td>
+    <td><a href="#Array_[]__21277412">Array#[]=</a></td>
+  </tr>
+  
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 500/501</td>
+    <td><a href="#Object_is_prime_21277412">Object#is_prime</a></td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1/501</td>
+    <td><a href="#Object_find_largest_21277412">Object#find_largest</a></td>
+  </tr>
+  <tr class="method">
+    <td> 0.00%</td>
+    <td> 0.00%</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 501</td>
+    <td><a name="Fixnum_-_21277412">Fixnum#-</a></td>
+  </tr>
+  
+  
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1/1</td>
+    <td><a href="#Kernel_rand_21277412">Kernel.rand</a></td>
+  </tr>
+  <tr class="method">
+    <td> 0.00%</td>
+    <td> 0.00%</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1</td>
+    <td><a name="Integer_to_int_21277412">Integer#to_int</a></td>
+  </tr>
+  
+  
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1/1</td>
+    <td><a href="#Object_find_largest_21277412">Object#find_largest</a></td>
+  </tr>
+  <tr class="method">
+    <td> 0.00%</td>
+    <td> 0.00%</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1</td>
+    <td><a name="Array_first_21277412">Array#first</a></td>
+  </tr>
+  
+  
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1/1</td>
+    <td><a href="#Class_new_21277412">Class#new</a></td>
+  </tr>
+  <tr class="method">
+    <td> 0.00%</td>
+    <td> 0.00%</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1</td>
+    <td><a name="Array_initialize_21277412">Array#initialize</a></td>
+  </tr>
+  
+  
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1/1</td>
+    <td><a href="#Object_find_largest_21277412">Object#find_largest</a></td>
+  </tr>
+  <tr class="method">
+    <td> 0.00%</td>
+    <td> 0.00%</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1</td>
+    <td><a name="Array_length_21277412">Array#length</a></td>
+  </tr>
+  
+  
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1/1</td>
+    <td><a href="#Object_make_random_array_21277412">Object#make_random_array</a></td>
+  </tr>
+  <tr class="method">
+    <td> 0.00%</td>
+    <td> 0.00%</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1</td>
+    <td><a name="Class_new_21277412">Class#new</a></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1/1</td>
+    <td><a href="#Array_initialize_21277412">Array#initialize</a></td>
+  </tr>
+  
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 61/61</td>
+    <td><a href="#Integer_upto_21277412">Integer#upto</a></td>
+  </tr>
+  <tr class="method">
+    <td> 0.00%</td>
+    <td> 0.00%</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 61</td>
+    <td><a name="Fixnum_>_21277412">Fixnum#_</a></td>
+  </tr>
+  
+  
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 61/61</td>
+    <td><a href="#Integer_upto_21277412">Integer#upto</a></td>
+  </tr>
+  <tr class="method">
+    <td> 0.00%</td>
+    <td> 0.00%</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 61</td>
+    <td><a name="Array_[]_21277412">Array#[]</a></td>
+  </tr>
+  
+  
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 500/500</td>
+    <td><a href="#Array_each_index_21277412">Array#each_index</a></td>
+  </tr>
+  <tr class="method">
+    <td> 0.00%</td>
+    <td> 0.00%</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 500</td>
+    <td><a name="Array_[]__21277412">Array#[]=</a></td>
+  </tr>
+  
+  
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 500/500</td>
+    <td><a href="#Array_each_index_21277412">Array#each_index</a></td>
+  </tr>
+  <tr class="method">
+    <td> 0.00%</td>
+    <td> 0.00%</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 500</td>
+    <td><a name="Kernel_rand_21277412">Kernel.rand</a></td>
+  </tr>
+  
+  <tr>
+    <td> </td>
+    <td> </td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 0.00</td>
+    <td> 1/1</td>
+    <td><a href="#Integer_to_int_21277412">Integer#to_int</a></td>
+  </tr>
+  
+  <tr class="break">
+    <td colspan="7"></td>
+  </tr>
+</table>
+</body>
+</html>
diff --git a/app/server/vendor/ruby-prof-0.15.8/examples/graph.txt b/app/server/vendor/ruby-prof-0.15.8/examples/graph.txt
new file mode 100755
index 0000000..99c071d
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/examples/graph.txt
@@ -0,0 +1,170 @@
+= Graph Profiles
+
+Graph profiles show how long each method runs, which methods call it
+and which methods it calls.
+
+As an example, here is the output from running printers_test.rb:
+
+
+Thread ID: 21277412
+  %total   %self     total      self    children               calls   Name
+ --------------------------------------------------------------------------------
+ 100.00%   0.00%      8.77      0.00      8.77                   1     #toplevel
+                      8.77      0.00      8.77                 1/1     Object#run_primes
+ --------------------------------------------------------------------------------
+                      8.77      0.00      8.77                 1/1     #toplevel
+ 100.00%   0.00%      8.77      0.00      8.77                   1     Object#run_primes
+                      0.02      0.00      0.02                 1/1     Object#make_random_array
+                      2.09      0.00      2.09                 1/1     Object#find_largest
+                      6.66      0.00      6.66                 1/1     Object#find_primes
+ --------------------------------------------------------------------------------
+                      6.63      4.06      2.56             500/501     Object#is_prime
+                      2.09      0.00      2.09               1/501     Object#find_largest
+  99.48%  46.34%      8.72      4.06      4.66                 501     Integer#upto
+                      0.00      0.00      0.00               61/61     Array#[]
+                      0.00      0.00      0.00               61/61     Fixnum#>
+                      2.09      2.09      0.00               61/61     Kernel.sleep
+                      1.24      1.24      0.00       250862/250862     Fixnum#==
+                      1.33      1.33      0.00       250862/250862     Fixnum#%
+ --------------------------------------------------------------------------------
+                      6.66      0.01      6.64                 1/1     Object#find_primes
+  75.93%   0.17%      6.66      0.01      6.64                   1     Array#select
+                      6.64      0.01      6.63             500/500     Object#is_prime
+ --------------------------------------------------------------------------------
+                      6.66      0.00      6.66                 1/1     Object#run_primes
+  75.93%   0.00%      6.66      0.00      6.66                   1     Object#find_primes
+                      6.66      0.01      6.64                 1/1     Array#select
+ --------------------------------------------------------------------------------
+                      6.64      0.01      6.63             500/500     Array#select
+  75.76%   0.17%      6.64      0.01      6.63                 500     Object#is_prime
+                      0.00      0.00      0.00             500/501     Fixnum#-
+                      6.63      4.06      2.56             500/501     Integer#upto
+ --------------------------------------------------------------------------------
+                      2.09      0.00      2.09                 1/1     Object#run_primes
+  23.89%   0.00%      2.09      0.00      2.09                   1     Object#find_largest
+                      0.00      0.00      0.00               1/501     Fixnum#-
+                      2.09      0.00      2.09               1/501     Integer#upto
+                      0.00      0.00      0.00                 1/1     Array#first
+                      0.00      0.00      0.00                 1/1     Array#length
+ --------------------------------------------------------------------------------
+                      2.09      2.09      0.00               61/61     Integer#upto
+  23.89%  23.89%      2.09      2.09      0.00                  61     Kernel.sleep
+ --------------------------------------------------------------------------------
+                      1.33      1.33      0.00       250862/250862     Integer#upto
+  15.12%  15.12%      1.33      1.33      0.00              250862     Fixnum#%
+ --------------------------------------------------------------------------------
+                      1.24      1.24      0.00       250862/250862     Integer#upto
+  14.13%  14.13%      1.24      1.24      0.00              250862     Fixnum#==
+ --------------------------------------------------------------------------------
+                      0.02      0.00      0.02                 1/1     Object#run_primes
+   0.18%   0.00%      0.02      0.00      0.02                   1     Object#make_random_array
+                      0.02      0.02      0.00                 1/1     Array#each_index
+                      0.00      0.00      0.00                 1/1     Class#new
+ --------------------------------------------------------------------------------
+                      0.02      0.02      0.00                 1/1     Object#make_random_array
+   0.18%   0.18%      0.02      0.02      0.00                   1     Array#each_index
+                      0.00      0.00      0.00             500/500     Kernel.rand
+                      0.00      0.00      0.00             500/500     Array#[]=
+ --------------------------------------------------------------------------------
+                      0.00      0.00      0.00             500/501     Object#is_prime
+                      0.00      0.00      0.00               1/501     Object#find_largest
+   0.00%   0.00%      0.00      0.00      0.00                 501     Fixnum#-
+ --------------------------------------------------------------------------------
+                      0.00      0.00      0.00                 1/1     Kernel.rand
+   0.00%   0.00%      0.00      0.00      0.00                   1     Integer#to_int
+ --------------------------------------------------------------------------------
+                      0.00      0.00      0.00                 1/1     Object#find_largest
+   0.00%   0.00%      0.00      0.00      0.00                   1     Array#first
+ --------------------------------------------------------------------------------
+                      0.00      0.00      0.00                 1/1     Class#new
+   0.00%   0.00%      0.00      0.00      0.00                   1     Array#initialize
+ --------------------------------------------------------------------------------
+                      0.00      0.00      0.00                 1/1     Object#find_largest
+   0.00%   0.00%      0.00      0.00      0.00                   1     Array#length
+ --------------------------------------------------------------------------------
+                      0.00      0.00      0.00                 1/1     Object#make_random_array
+   0.00%   0.00%      0.00      0.00      0.00                   1     Class#new
+                      0.00      0.00      0.00                 1/1     Array#initialize
+ --------------------------------------------------------------------------------
+                      0.00      0.00      0.00               61/61     Integer#upto
+   0.00%   0.00%      0.00      0.00      0.00                  61     Fixnum#>
+ --------------------------------------------------------------------------------
+                      0.00      0.00      0.00               61/61     Integer#upto
+   0.00%   0.00%      0.00      0.00      0.00                  61     Array#[]
+ --------------------------------------------------------------------------------
+                      0.00      0.00      0.00             500/500     Array#each_index
+   0.00%   0.00%      0.00      0.00      0.00                 500     Array#[]=
+ --------------------------------------------------------------------------------
+                      0.00      0.00      0.00             500/500     Array#each_index
+   0.00%   0.00%      0.00      0.00      0.00                 500     Kernel.rand
+                      0.00      0.00      0.00                 1/1     Integer#to_int
+
+
+
+== Overview
+Dashed lines divide the report into entries, with one entry
+per method.  Entries are sorted by total time which is the 
+time spent in the method plus its children. 
+
+Each entry has a primary line demarked by values in the 
+%total and %self columns.  The primary line represents 
+the method being profiled.  Lines above it are the methods
+that called this method (parents) while the lines below it
+are the methods it called (children).
+
+All values are in seconds.  For the primary line, the columns represent:
+
+	%total       - The percentage of time spent in this method and its children
+	%self        - The percentage of time spent in this method
+	total        - The time spent in this method and its children.
+	self         - The time spent in this method.
+	children     - The time spent in this method's children.
+	calls        - The number of times this method was called.
+	name         - The name of the method.
+  
+The interpretation of method names is:
+* #toplevel - The root method that calls all other methods
+* MyObject#test - An instance method "test" of the class "MyObject"
+* <Object:MyObject>#test - The <> characters indicate a singleton method on a singleton class.
+
+For example, we see that 99.48% of the time was spent in Integer#upto and its children.
+Of that time, 4.06 seconds was spent in Integer#upto itself and 4.66 in its children.
+Overall, Integer#upto was called 501 times.
+
+== Parents
+In each entry, the lines above the primary line are the methods that 
+called the current method.  If the current method is a root method then
+no parents are shown.
+
+
+For parent lines, the columns represent:
+
+	total        - The time spent in the current method and it children on behalf of the parent method.
+	self         - The time spent in this method on behalf of the parent method.
+	children     - The time spent in this method's children on behalf of the parent.
+	calls        - The number of times the parent method called this child
+  
+Looking at Integer#upto again, we see that it was called 500 times from Object#is_prime
+and 1 time from find_largest.  Of the 8.72 total seconds spent in Integer#upto, 6.63
+were done for Object#is_prime and 2.09 for Object#find_largest.
+
+
+== Children
+In each entry, the lines below the primary line are the methods that 
+the current method called.  If the current method is a leaf method then
+no children are shown.
+
+For children lines, the columns represent:
+
+	total        - The time spent in the child, and its children, on behalf of the current method
+	self         - The time spent in the child on behalf of the current method.
+	children     - The time spent in the child's children (ie, granchildren) in behalf of the current method
+	calls        - The number of times the child method was called by the current method.
+
+Taking our example of Integer#upto, we see that it called five other methods - Array#[],
+Fixnum#>, Kernel.sleep, Fixnum#= and Fixnum#%.  Looking at Kernel.sleep, we see that 
+its spent 2.09 seconds working for Integer#upto and its children spent 0 time working for
+Integer#upto.  To see the overall time Kernel.sleep took we would have to look up its entry
+in the graph table.
+
+
diff --git a/app/server/vendor/ruby-prof-0.15.8/examples/multi.flat.txt b/app/server/vendor/ruby-prof-0.15.8/examples/multi.flat.txt
new file mode 100755
index 0000000..ca3ac10
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/examples/multi.flat.txt
@@ -0,0 +1,23 @@
+Measure Mode: wall_time
+Thread ID: 70140045951280
+Fiber ID: 70140054192180
+Total: 0.002968
+Sort by: self_time
+
+ %self      total      self      wait     child     calls  name
+ 86.99      0.003     0.003     0.000     0.000      201   Integer#upto
+  3.11      0.003     0.000     0.000     0.003      200   Object#is_prime
+  2.94      0.000     0.000     0.000     0.000      200   Kernel#rand
+  2.82      0.003     0.000     0.000     0.003        1   Array#select
+  2.37      0.000     0.000     0.000     0.000        1   Array#each_index
+  1.02      0.000     0.000     0.000     0.000      200   Kernel#respond_to_missing?
+  0.18      0.003     0.000     0.000     0.003        1   PrintersTest#setup
+  0.14      0.000     0.000     0.000     0.000        1   Class#new
+  0.10      0.000     0.000     0.000     0.000        1   Object#find_largest
+  0.10      0.000     0.000     0.000     0.000        1   Object#make_random_array
+  0.06      0.003     0.000     0.000     0.003        1   Object#find_primes
+  0.06      0.000     0.000     0.000     0.000        1   Array#initialize
+  0.06      0.003     0.000     0.000     0.003        1   Object#run_primes
+  0.03      0.000     0.000     0.000     0.000        1   Array#first
+
+* indicates recursively called methods
diff --git a/app/server/vendor/ruby-prof-0.15.8/examples/multi.graph.html b/app/server/vendor/ruby-prof-0.15.8/examples/multi.graph.html
new file mode 100755
index 0000000..145e0c4
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/examples/multi.graph.html
@@ -0,0 +1,760 @@
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <style media="all" type="text/css">
+    table {
+      border-collapse: collapse;
+      border: 1px solid #CCC;
+      font-family: Verdana, Arial, Helvetica, sans-serif;
+      font-size: 9pt;
+      line-height: normal;
+      width: 100%;
+    }
+
+    th {
+      text-align: center;
+      border-top: 1px solid #FB7A31;
+      border-bottom: 1px solid #FB7A31;
+      background: #FFC;
+      padding: 0.3em;
+      border-left: 1px solid silver;
+    }
+
+    tr.break td {
+      border: 0;
+      border-top: 1px solid #FB7A31;
+      padding: 0;
+      margin: 0;
+    }
+
+    tr.method td {
+      font-weight: bold;
+    }
+
+    td {
+      padding: 0.3em;
+    }
+
+    td:first-child {
+      width: 190px;
+      }
+
+    td {
+      border-left: 1px solid #CCC;
+      text-align: center;
+    }
+
+    .method_name {
+      text-align: left;
+    }
+
+    tfoot td {
+      text-align: left;
+    }
+  </style>
+  </head>
+  <body>
+    <h1>Profile Report: wall_time</h1>
+    <!-- Threads Table -->
+    <table>
+      <tr>
+        <th>Thread ID</th>
+        <th>Fiber ID</th>
+        <th>Total Time</th>
+      </tr>
+
+      <tr>
+        <td>70140045951280</td>
+        <td><a href="#70140054192180">70140054192180</a></td>
+        <td>0.0029680728912353516</td>
+      </tr>
+
+    </table>
+    <!-- Methods Tables -->
+
+      <h2><a name="70140054192180">Thread 70140045951280, Fiber: 70140054192180</a></h2>
+      <table>
+        <thead>
+          <tr>
+            <th>%Total</th>
+            <th>%Self</th>
+            <th>Total</th>
+            <th>Self</th>
+            <th>Wait</th>
+            <th>Child</th>
+            <th>Calls</th>
+            <th class="method_name">Name</th>
+            <th>Line</th>
+          </tr>
+        </thead>
+        <tbody>
+
+               <!-- Parents -->
+
+               <tr class="method">
+                 <td>100.00%</td>
+                 <td>0.18%</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>1</td>
+                 <td class="method_name">
+                   <a name="PrintersTest_setup_70140054192180">
+                      PrintersTest#setup
+                   </a>
+                 </td>
+                 <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/printers_test.rb&line=14" title="/Users/stefan.kaes/src/ruby-prof/test/printers_test.rb:14">14</a></td>
+               </tr>
+               <!-- Children -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Object_run_primes_70140054192180">Object#run_primes</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/printers_test.rb&line=14" title="/Users/stefan.kaes/src/ruby-prof/test/printers_test.rb:14">14</a></td>
+                 </tr>
+
+               <!-- Create divider row -->
+               <tr class="break"><td colspan="9"></td></tr>
+
+
+               <!-- Parents -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#PrintersTest_setup_70140054192180">PrintersTest#setup</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/printers_test.rb&line=14" title="/Users/stefan.kaes/src/ruby-prof/test/printers_test.rb:14">14</a></td>
+                 </tr>
+
+               <tr class="method">
+                 <td>99.82%</td>
+                 <td>0.06%</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>1</td>
+                 <td class="method_name">
+                   <a name="Object_run_primes_70140054192180">
+                      Object#run_primes
+                   </a>
+                 </td>
+                 <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=45" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:45">45</a></td>
+               </tr>
+               <!-- Children -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Object_find_primes_70140054192180">Object#find_primes</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=50" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:50">50</a></td>
+                 </tr>
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Object_make_random_array_70140054192180">Object#make_random_array</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=47" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:47">47</a></td>
+                 </tr>
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Object_find_largest_70140054192180">Object#find_largest</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=53" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:53">53</a></td>
+                 </tr>
+
+               <!-- Create divider row -->
+               <tr class="break"><td colspan="9"></td></tr>
+
+
+               <!-- Parents -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Object_run_primes_70140054192180">Object#run_primes</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=50" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:50">50</a></td>
+                 </tr>
+
+               <tr class="method">
+                 <td>92.62%</td>
+                 <td>0.06%</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>1</td>
+                 <td class="method_name">
+                   <a name="Object_find_primes_70140054192180">
+                      Object#find_primes
+                   </a>
+                 </td>
+                 <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=24" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:24">24</a></td>
+               </tr>
+               <!-- Children -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Array_select_70140054192180">Array#select</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=25" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:25">25</a></td>
+                 </tr>
+
+               <!-- Create divider row -->
+               <tr class="break"><td colspan="9"></td></tr>
+
+
+               <!-- Parents -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Object_find_primes_70140054192180">Object#find_primes</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=25" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:25">25</a></td>
+                 </tr>
+
+               <tr class="method">
+                 <td>92.55%</td>
+                 <td>2.82%</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>1</td>
+                 <td class="method_name">
+                   <a name="Array_select_70140054192180">
+                      Array#select
+                   </a>
+                 </td>
+                 <td></td>
+               </tr>
+               <!-- Children -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>200/200</td>
+                   <td class="method_name"><a href="#Object_is_prime_70140054192180">Object#is_prime</a></td>
+                   <td></td>
+                 </tr>
+
+               <!-- Create divider row -->
+               <tr class="break"><td colspan="9"></td></tr>
+
+
+               <!-- Parents -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>200/200</td>
+                   <td class="method_name"><a href="#Array_select_70140054192180">Array#select</a></td>
+                   <td></td>
+                 </tr>
+
+               <tr class="method">
+                 <td>89.73%</td>
+                 <td>3.11%</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>200</td>
+                 <td class="method_name">
+                   <a name="Object_is_prime_70140054192180">
+                      Object#is_prime
+                   </a>
+                 </td>
+                 <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=16" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:16">16</a></td>
+               </tr>
+               <!-- Children -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>200/201</td>
+                   <td class="method_name"><a href="#Integer_upto_70140054192180">Integer#upto</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=18" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:18">18</a></td>
+                 </tr>
+
+               <!-- Create divider row -->
+               <tr class="break"><td colspan="9"></td></tr>
+
+
+               <!-- Parents -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/201</td>
+                   <td class="method_name"><a href="#Object_find_largest_70140054192180">Object#find_largest</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=36" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:36">36</a></td>
+                 </tr>
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>200/201</td>
+                   <td class="method_name"><a href="#Object_is_prime_70140054192180">Object#is_prime</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=18" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:18">18</a></td>
+                 </tr>
+
+               <tr class="method">
+                 <td>86.99%</td>
+                 <td>86.99%</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>201</td>
+                 <td class="method_name">
+                   <a name="Integer_upto_70140054192180">
+                      Integer#upto
+                   </a>
+                 </td>
+                 <td></td>
+               </tr>
+               <!-- Children -->
+
+               <!-- Create divider row -->
+               <tr class="break"><td colspan="9"></td></tr>
+
+
+               <!-- Parents -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Object_run_primes_70140054192180">Object#run_primes</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=47" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:47">47</a></td>
+                 </tr>
+
+               <tr class="method">
+                 <td>6.64%</td>
+                 <td>0.10%</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>1</td>
+                 <td class="method_name">
+                   <a name="Object_make_random_array_70140054192180">
+                      Object#make_random_array
+                   </a>
+                 </td>
+                 <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=7" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:7">7</a></td>
+               </tr>
+               <!-- Children -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Array_each_index_70140054192180">Array#each_index</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=9" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:9">9</a></td>
+                 </tr>
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Class_new_70140054192180">Class#new</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=8" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:8">8</a></td>
+                 </tr>
+
+               <!-- Create divider row -->
+               <tr class="break"><td colspan="9"></td></tr>
+
+
+               <!-- Parents -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Object_make_random_array_70140054192180">Object#make_random_array</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=9" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:9">9</a></td>
+                 </tr>
+
+               <tr class="method">
+                 <td>6.33%</td>
+                 <td>2.37%</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>1</td>
+                 <td class="method_name">
+                   <a name="Array_each_index_70140054192180">
+                      Array#each_index
+                   </a>
+                 </td>
+                 <td></td>
+               </tr>
+               <!-- Children -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>200/200</td>
+                   <td class="method_name"><a href="#Kernel_rand_70140054192180">Kernel#rand</a></td>
+                   <td></td>
+                 </tr>
+
+               <!-- Create divider row -->
+               <tr class="break"><td colspan="9"></td></tr>
+
+
+               <!-- Parents -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>200/200</td>
+                   <td class="method_name"><a href="#Array_each_index_70140054192180">Array#each_index</a></td>
+                   <td></td>
+                 </tr>
+
+               <tr class="method">
+                 <td>3.96%</td>
+                 <td>2.94%</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>200</td>
+                 <td class="method_name">
+                   <a name="Kernel_rand_70140054192180">
+                      Kernel#rand
+                   </a>
+                 </td>
+                 <td></td>
+               </tr>
+               <!-- Children -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>200/200</td>
+                   <td class="method_name"><a href="#Kernel_respond_to_missing__70140054192180">Kernel#respond_to_missing?</a></td>
+                   <td></td>
+                 </tr>
+
+               <!-- Create divider row -->
+               <tr class="break"><td colspan="9"></td></tr>
+
+
+               <!-- Parents -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>200/200</td>
+                   <td class="method_name"><a href="#Kernel_rand_70140054192180">Kernel#rand</a></td>
+                   <td></td>
+                 </tr>
+
+               <tr class="method">
+                 <td>1.02%</td>
+                 <td>1.02%</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>200</td>
+                 <td class="method_name">
+                   <a name="Kernel_respond_to_missing__70140054192180">
+                      Kernel#respond_to_missing?
+                   </a>
+                 </td>
+                 <td></td>
+               </tr>
+               <!-- Children -->
+
+               <!-- Create divider row -->
+               <tr class="break"><td colspan="9"></td></tr>
+
+
+               <!-- Parents -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Object_run_primes_70140054192180">Object#run_primes</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=53" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:53">53</a></td>
+                 </tr>
+
+               <tr class="method">
+                 <td>0.51%</td>
+                 <td>0.10%</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>1</td>
+                 <td class="method_name">
+                   <a name="Object_find_largest_70140054192180">
+                      Object#find_largest
+                   </a>
+                 </td>
+                 <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=31" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:31">31</a></td>
+               </tr>
+               <!-- Children -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/201</td>
+                   <td class="method_name"><a href="#Integer_upto_70140054192180">Integer#upto</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=36" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:36">36</a></td>
+                 </tr>
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Array_first_70140054192180">Array#first</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=32" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:32">32</a></td>
+                 </tr>
+
+               <!-- Create divider row -->
+               <tr class="break"><td colspan="9"></td></tr>
+
+
+               <!-- Parents -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Object_make_random_array_70140054192180">Object#make_random_array</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=8" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:8">8</a></td>
+                 </tr>
+
+               <tr class="method">
+                 <td>0.20%</td>
+                 <td>0.14%</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>1</td>
+                 <td class="method_name">
+                   <a name="Class_new_70140054192180">
+                      Class#new
+                   </a>
+                 </td>
+                 <td></td>
+               </tr>
+               <!-- Children -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Array_initialize_70140054192180">Array#initialize</a></td>
+                   <td></td>
+                 </tr>
+
+               <!-- Create divider row -->
+               <tr class="break"><td colspan="9"></td></tr>
+
+
+               <!-- Parents -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Class_new_70140054192180">Class#new</a></td>
+                   <td></td>
+                 </tr>
+
+               <tr class="method">
+                 <td>0.06%</td>
+                 <td>0.06%</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>1</td>
+                 <td class="method_name">
+                   <a name="Array_initialize_70140054192180">
+                      Array#initialize
+                   </a>
+                 </td>
+                 <td></td>
+               </tr>
+               <!-- Children -->
+
+               <!-- Create divider row -->
+               <tr class="break"><td colspan="9"></td></tr>
+
+
+               <!-- Parents -->
+
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>0.00</td>
+                   <td>1/1</td>
+                   <td class="method_name"><a href="#Object_find_largest_70140054192180">Object#find_largest</a></td>
+                   <td><a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=32" title="/Users/stefan.kaes/src/ruby-prof/test/prime.rb:32">32</a></td>
+                 </tr>
+
+               <tr class="method">
+                 <td>0.03%</td>
+                 <td>0.03%</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>0.00</td>
+                 <td>1</td>
+                 <td class="method_name">
+                   <a name="Array_first_70140054192180">
+                      Array#first
+                   </a>
+                 </td>
+                 <td></td>
+               </tr>
+               <!-- Children -->
+
+               <!-- Create divider row -->
+               <tr class="break"><td colspan="9"></td></tr>
+
+
+        </tbody>
+        <tfoot>
+          <tr>
+            <td colspan="9">* indicates recursively called methods</td>
+          </tr>
+        </tfoot>
+      </table>
+
+  </body>
+</html>
diff --git a/app/server/vendor/ruby-prof-0.15.8/examples/multi.grind.dat b/app/server/vendor/ruby-prof-0.15.8/examples/multi.grind.dat
new file mode 100755
index 0000000..1968515
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/examples/multi.grind.dat
@@ -0,0 +1,114 @@
+events: wall_time
+
+fl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+fn=Array#first
+0 1
+
+fl=/Users/stefan.kaes/src/ruby-prof/test/prime.rb
+fn=Object#find_largest
+31 3
+cfl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+cfn=Array#first
+calls=1 32
+32 1
+cfl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+cfn=Integer#upto
+calls=1 36
+36 11
+
+fl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+fn=Integer#upto
+0 2582
+
+fl=/Users/stefan.kaes/src/ruby-prof/test/prime.rb
+fn=Object#is_prime
+16 92
+cfl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+cfn=Integer#upto
+calls=200 18
+18 2571
+
+fl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+fn=Array#select
+0 84
+cfl=/Users/stefan.kaes/src/ruby-prof/test/prime.rb
+cfn=Object#is_prime
+calls=200 26
+26 2663
+
+fl=/Users/stefan.kaes/src/ruby-prof/test/prime.rb
+fn=Object#find_primes
+24 2
+cfl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+cfn=Array#select
+calls=1 25
+25 2747
+
+fl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+fn=Kernel#respond_to_missing?
+0 30
+
+fl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+fn=Kernel#rand
+0 87
+cfl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+cfn=Kernel#respond_to_missing?
+calls=200 10
+10 30
+
+fl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+fn=Array#each_index
+0 70
+cfl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+cfn=Kernel#rand
+calls=200 10
+10 118
+
+fl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+fn=Array#initialize
+0 2
+
+fl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+fn=Class#new
+0 4
+cfl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+cfn=Array#initialize
+calls=1 8
+8 2
+
+fl=/Users/stefan.kaes/src/ruby-prof/test/prime.rb
+fn=Object#make_random_array
+7 3
+cfl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+cfn=Class#new
+calls=1 8
+8 6
+cfl=/Users/stefan.kaes/src/ruby-prof/ruby_runtime
+cfn=Array#each_index
+calls=1 9
+9 188
+
+fl=/Users/stefan.kaes/src/ruby-prof/test/prime.rb
+fn=Object#run_primes
+45 2
+cfl=/Users/stefan.kaes/src/ruby-prof/test/prime.rb
+cfn=Object#make_random_array
+calls=1 47
+47 197
+cfl=/Users/stefan.kaes/src/ruby-prof/test/prime.rb
+cfn=Object#find_primes
+calls=1 50
+50 2749
+cfl=/Users/stefan.kaes/src/ruby-prof/test/prime.rb
+cfn=Object#find_largest
+calls=1 53
+53 15
+
+fl=/Users/stefan.kaes/src/ruby-prof/test/printers_test.rb
+fn=PrintersTest#setup
+14 5
+cfl=/Users/stefan.kaes/src/ruby-prof/test/prime.rb
+cfn=Object#run_primes
+calls=1 14
+14 2963
+
diff --git a/app/server/vendor/ruby-prof-0.15.8/examples/multi.stack.html b/app/server/vendor/ruby-prof-0.15.8/examples/multi.stack.html
new file mode 100755
index 0000000..e3ceb46
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/examples/multi.stack.html
@@ -0,0 +1,547 @@
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8">
+<title>ruby-prof call tree</title>
+<style type="text/css">
+<!--
+  body {
+    font-size:70%;
+    padding:0;
+    margin:5px;
+    margin-right:0px;
+    margin-left:0px;
+    background: #ffffff;
+  }
+  ul {
+    margin-left:0px;
+    margin-top:0px;
+    margin-bottom:0px;
+    padding-left:0px;
+    list-style-type:none;
+  }
+  li {
+    margin-left:11px;
+    padding:0px;
+    white-space:nowrap;
+    border-top:1px solid #cccccc;
+    border-left:1px solid #cccccc;
+    border-bottom:none;
+  }
+  .thread {
+    margin-left:11px;
+    background:#708090;
+    padding-top:3px;
+    padding-left:12px;
+    padding-bottom:2px;
+    border-left:1px solid #CCCCCC;
+    border-top:1px solid #CCCCCC;
+    font-weight:bold;
+  }
+  .hidden {
+    display:none;
+    width:0px;
+    height:0px;
+    margin:0px;
+    padding:0px;
+    border-style:none;
+  }
+  .color01 { background:#adbdeb }
+  .color05 { background:#9daddb }
+  .color0 { background:#8d9dcb }
+  .color1 { background:#89bccb }
+  .color2 { background:#56e3e7 }
+  .color3 { background:#32cd70 }
+  .color4 { background:#a3d53c }
+  .color5 { background:#c4cb34 }
+  .color6 { background:#dcb66d }
+  .color7 { background:#cda59e }
+  .color8 { background:#be9d9c }
+  .color9 { background:#cf947a }
+  #commands {
+    font-size:10pt;
+    padding:10px;
+    margin-left:11px;
+    margin-bottom:0px;
+    margin-top:0px;
+    background:#708090;
+    border-top:1px solid #cccccc;
+    border-left:1px solid #cccccc;
+    border-bottom:none;
+  }
+  #titlebar {
+    font-size:10pt;
+    padding:10px;
+    margin-left:11px;
+    margin-bottom:0px;
+    margin-top:10px;
+    background:#8090a0;
+    border-top:1px solid #cccccc;
+    border-left:1px solid #cccccc;
+    border-bottom:none;
+  }
+  #help {
+    font-size:10pt;
+    padding:10px;
+    margin-left:11px;
+    margin-bottom:0px;
+    margin-top:0px;
+    background:#8090a0;
+    display:none;
+    border-top:1px solid #cccccc;
+    border-left:1px solid #cccccc;
+    border-bottom:none;
+  }
+  #sentinel {
+    height: 400px;
+    margin-left:11px;
+    background:#8090a0;
+    border-top:1px solid #cccccc;
+    border-left:1px solid #cccccc;
+    border-bottom:none;
+  }
+  input { margin-left:10px; }
+
+  .toggle {
+    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAJCAMAAAD0FKf3AAAAA3NCSVQICAjb4U/gAAAAb1BMVEX///98jcR8jMV4jMB7jcR7jcR8jcT////7/f/3/P/0+vzx+v7s9vzq9Pzm8Prk7vzi7fnj5/Pc5vTb5vbg5PHW4fHV3/XS3fLM1+3K1e/G0e3EzuzCzey8x+m8xuystuSqtt98jsR8jcR7jcQAAADWswcWAAAAJXRSTlMAVVVV3e7u////////////////////////////////////////Vv4VOQAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAACVSURBVAiZPc/hDoIwDATgobCWgZsWgSGidOz9n9F1CPfrki+5tIqPXHSQVMVZFH8/sx/Is16X9zR2vtQPAMC6LxVnco5Dpvtt40QRGrspnueBqDUcdmrEMILtknkiQkQOU5RAsn9RPGRKNkLOxiibIEauNSYZy2CNyerGRngtsilkiLXP9Cx1bzuAZU13Himq/a3rWX4VVRPEuDWiLQAAAABJRU5ErkJggg==) no-repeat left center;
+    float:left;
+    width:9px;
+    height:9px;
+    margin:2px 1px 1px 1px;
+  }
+
+  .toggle.minus {
+    background-position: -9px 0;
+  }
+
+  .toggle.plus {
+    background-position: -18px 0;
+  }
+
+-->
+</style>
+<script type="text/javascript">
+  /*
+   Copyright (C) 2005,2009  Stefan Kaes
+   skaes at railsexpress.de
+   */
+
+  function rootNode() {
+    return currentThread;
+  }
+
+  function showUL(node, show) {
+    var lis = node.childNodes;
+    var l = lis.length;
+    for (var i=0; i < l ; i++ ) {
+      toggle(lis[i], show);
+    }
+  }
+
+  function findUlChild(li){
+    var ul = li.childNodes[2];
+    while (ul && ul.nodeName != "UL") {
+      ul = ul.nextSibling;
+    }
+    return ul;
+  }
+
+  function isLeafNode(li) {
+    var img = li.firstChild;
+    return (img.className.indexOf('empty') > -1);
+  }
+
+  function toggle(li, show) {
+    if (isLeafNode(li))
+      return;
+
+    var img = li.firstChild;
+    img.className = 'toggle ';
+    img.className += show ? 'minus' : 'plus';
+
+    var ul = findUlChild(li);
+    if (ul) {
+      ul.style.display = show ? 'block' : 'none';
+      showUL(ul, true);
+    }
+  }
+
+  function toggleLI(li) {
+    var img = li.firstChild;
+    if (img.className.indexOf("minus")>-1)
+      toggle(li, false);
+    else {
+      if (img.className.indexOf("plus")>-1)
+        toggle(li, true);
+    }
+  }
+
+  function aboveThreshold(text, threshold) {
+    var match = text.match(/\d+[.,]\d+/);
+    return (match && parseFloat(match[0].replace(/,/, '.'))>=threshold);
+  }
+
+  function setThresholdLI(li, threshold) {
+    var img = li.firstChild;
+    var text = img.nextSibling;
+    var ul = findUlChild(li);
+
+    var visible = aboveThreshold(text.nodeValue, threshold) ? 1 : 0;
+
+    var count = 0;
+    if (ul) {
+      count = setThresholdUL(ul, threshold);
+    }
+    if (count>0) {
+      img.className = 'toggle minus';
+    }
+    else {
+      img.className = 'toggle empty';
+    }
+    if (visible) {
+      li.style.display = 'block'
+    }
+    else {
+      li.style.display = 'none'
+    }
+    return visible;
+  }
+
+  function setThresholdUL(node, threshold) {
+    var lis = node.childNodes;
+    var l = lis.length;
+
+    var count = 0;
+    for ( var i = 0; i < l ; i++ ) {
+      count = count + setThresholdLI(lis[i], threshold);
+    }
+
+    var visible = (count > 0) ? 1 : 0;
+    if (visible) {
+      node.style.display = 'block';
+    }
+    else {
+      node.style.display = 'none';
+    }
+    return visible;
+  }
+
+  function toggleChildren(img, event) {
+    event.cancelBubble=true;
+    if (img.className.indexOf('empty') > -1)
+      return;
+
+    var minus = (img.className.indexOf('minus') > -1);
+
+    if (minus) {
+      img.className = 'toggle plus';
+    }
+    else
+      img.className = 'toggle minus';
+
+    var li = img.parentNode;
+    var ul = findUlChild(li);
+    if (ul) {
+      if (minus)
+        ul.style.display = 'none';
+      else
+        ul.style.display = 'block';
+    }
+    if (minus)
+      moveSelectionIfNecessary(li);
+  }
+
+  function showChildren(li) {
+    var img = li.firstChild;
+    if (img.className.indexOf('empty') > -1)
+      return;
+    img.className = 'toggle minus';
+
+    var ul = findUlChild(li);
+    if (ul) {
+      ul.style.display = 'block';
+    }
+  }
+
+  function setThreshold() {
+    var tv = document.getElementById("threshold").value;
+    if (tv.match(/[0-9]+([.,][0-9]+)?/)) {
+      var f = parseFloat(tv.replace(/,/, '.'));
+      var threads = document.getElementsByName("thread");
+      var l = threads.length;
+      for ( var i = 0; i < l ; i++ ) {
+        setThresholdUL(threads[i], f);
+      }
+      var p = selectedNode;
+      while (p && p.style.display=='none')
+        p=p.parentNode.parentNode;
+      if (p && p.nodeName=="LI")
+        selectNode(p);
+    }
+    else {
+      alert("Please specify a decimal number as threshold value!");
+    }
+  }
+
+  function expandAll(event) {
+    toggleAll(event, true);
+  }
+
+  function collapseAll(event) {
+    toggleAll(event, false);
+    selectNode(rootNode(), null);
+  }
+
+  function toggleAll(event, show) {
+    event.cancelBubble=true;
+    var threads = document.getElementsByName("thread");
+    var l = threads.length;
+    for ( var i = 0; i < l ; i++ ) {
+      showUL(threads[i], show);
+    }
+  }
+
+  function toggleHelp(node) {
+    var help = document.getElementById("help");
+    if (node.value == "Show Help") {
+      node.value = "Hide Help";
+      help.style.display = 'block';
+    }
+    else {
+      node.value = "Show Help";
+      help.style.display = 'none';
+    }
+  }
+
+  var selectedNode = null;
+  var selectedColor = null;
+  var selectedThread = null;
+
+  function descendentOf(a,b){
+    while (a!=b && b!=null)
+      b=b.parentNode;
+    return (a==b);
+  }
+
+  function moveSelectionIfNecessary(node){
+    if (descendentOf(node, selectedNode))
+      selectNode(node, null);
+  }
+
+  function selectNode(node, event) {
+    if (event) {
+      event.cancelBubble = true;
+      thread = findThread(node);
+      selectThread(thread);
+    }
+    if (selectedNode) {
+      selectedNode.style.background = selectedColor;
+    }
+    selectedNode = node;
+    selectedColor = node.style.background;
+    selectedNode.style.background = "red";
+    selectedNode.scrollIntoView();
+    window.scrollBy(0,-400);
+  }
+
+  function moveUp(){
+    move(selectedNode.previousSibling);
+  }
+
+  function moveDown(){
+    move(selectedNode.nextSibling);
+  }
+
+  function move(p) {
+    while (p && p.style.display == 'none')
+      p = p.nextSibling;
+    if (p && p.nodeName == "LI") {
+      selectNode(p, null);
+    }
+  }
+
+  function moveLeft(){
+    var p = selectedNode.parentNode.parentNode;
+    if (p && p.nodeName=="LI") {
+      selectNode(p, null);
+    }
+  }
+
+  function moveRight(){
+    if (!isLeafNode(selectedNode)) {
+      showChildren(selectedNode);
+      var ul = findUlChild(selectedNode);
+      if (ul) {
+        selectNode(ul.firstChild, null);
+      }
+    }
+  }
+
+  function moveForward(){
+    if (isLeafNode(selectedNode)) {
+      var p = selectedNode;
+      while ((p.nextSibling == null || p.nextSibling.style.display=='none') && p.nodeName=="LI") {
+        p = p.parentNode.parentNode;
+      }
+      if (p.nodeName=="LI")
+        selectNode(p.nextSibling, null);
+    }
+    else {
+      moveRight();
+    }
+  }
+
+  function isExpandedNode(li){
+    var img = li.firstChild;
+    return(img.className.indexOf('minus')>-1);
+  }
+
+  function moveBackward(){
+    var p = selectedNode;
+    var q = p.previousSibling;
+    while (q != null && q.style.display=='none')
+      q = q.previousSibling;
+    if (q == null) {
+      p = p.parentNode.parentNode;
+    } else {
+      while (!isLeafNode(q) && isExpandedNode(q)) {
+        q = findUlChild(q).lastChild;
+        while (q.style.display=='none')
+          q = q.previousSibling;
+      }
+      p = q;
+    }
+    if (p.nodeName=="LI")
+      selectNode(p, null);
+  }
+
+  function moveHome() {
+    selectNode(currentThread);
+  }
+
+  var currentThreadIndex = null;
+
+  function findThread(node){
+    while (node && !node.parentNode.nodeName.match(/BODY|DIV/g)) {
+      node = node.parentNode;
+    }
+    return node.firstChild;
+  }
+
+  function selectThread(node){
+    var threads = document.getElementsByName("thread");
+    currentThread = node;
+    for (var i=0; i<threads.length; i++) {
+      if (threads[i]==currentThread.parentNode)
+        currentThreadIndex = i;
+    }
+  }
+
+  function nextThread(){
+    var threads = document.getElementsByName("thread");
+    if (currentThreadIndex==threads.length-1)
+      currentThreadIndex = 0;
+    else
+      currentThreadIndex += 1
+    currentThread = threads[currentThreadIndex].firstChild;
+    selectNode(currentThread, null);
+  }
+
+  function previousThread(){
+    var threads = document.getElementsByName("thread");
+    if (currentThreadIndex==0)
+      currentThreadIndex = threads.length-1;
+    else
+      currentThreadIndex -= 1
+    currentThread = threads[currentThreadIndex].firstChild;
+    selectNode(currentThread, null);
+  }
+
+  function switchThread(node, event){
+    event.cancelBubble = true;
+    selectThread(node.nextSibling.firstChild);
+    selectNode(currentThread, null);
+  }
+
+  function handleKeyEvent(event){
+    var code = event.charCode ? event.charCode : event.keyCode;
+    var str = String.fromCharCode(code);
+    switch (str) {
+      case "a": moveLeft();  break;
+      case "s": moveDown();  break;
+      case "d": moveRight(); break;
+      case "w": moveUp();    break;
+      case "f": moveForward(); break;
+      case "b": moveBackward(); break;
+      case "x": toggleChildren(selectedNode.firstChild, event); break;
+      case "*": toggleLI(selectedNode); break;
+      case "n": nextThread(); break;
+      case "h": moveHome(); break;
+      case "p": previousThread(); break;
+    }
+  }
+  document.onkeypress=function(event){ handleKeyEvent(event) };
+
+  window.onload=function(){
+    var images = document.querySelectorAll(".toggle");
+    for (var i=0; i<images.length; i++) {
+      var img = images[i];
+        img.onclick = function(event){ toggleChildren(this, event); return false; };
+    }
+    var divs = document.getElementsByTagName("div");
+    for (i=0; i<divs.length; i++) {
+      var div = divs[i];
+      if (div.className == "thread")
+        div.onclick = function(event){ switchThread(this, event) };
+    }
+    var lis = document.getElementsByTagName("li");
+    for (var i=0; i<lis.length; i++) {
+      lis[i].onclick = function(event){ selectNode(this, event); };
+    }
+    var threads = document.getElementsByName("thread");;
+    currentThreadIndex = 0;
+    currentThread = threads[0].firstChild;
+    selectNode(currentThread, null);
+  };
+
+</script>
+</head><body><div style="display: inline-block;">
+<div id="titlebar">
+Call tree for application <b>primes </b><br/>
+Generated on 2015-04-24 11:52:24 +0200 with options {:application=>"primes"}<br/>
+</div>
+<div id="commands">
+<span style="font-size: 11pt; font-weight: bold;">Threshold:</span>
+<input value="1.0" size="3" id="threshold" type="text">
+<input value="Apply" onclick="setThreshold();" type="submit">
+<input value="Expand All" onclick="expandAll(event);" type="submit">
+<input value="Collapse All" onclick="collapseAll(event);" type="submit">
+<input value="Show Help" onclick="toggleHelp(this);" type="submit">
+</div>
+<div style="display: none;" id="help">
+• Enter a decimal value <i>d</i> into the threshold field and click "Apply"
+        to hide all nodes marked with time values lower than <i>d</i>.<br>
+• Click on "Expand All" for full tree expansion.<br>
+• Click on "Collapse All" to show only top level nodes.<br>
+• Use a, s, d, w as in Quake or Urban Terror to navigate the tree.<br>
+• Use f and b to navigate the tree in preorder forward and backwards.<br>
+• Use x to toggle visibility of a subtree.<br>
+• Use * to expand/collapse a whole subtree.<br>
+• Use h to navigate to thread root.<br>
+• Use n and p to navigate between threads.<br>
+• Click on background to move focus to a subtree.<br>
+</div>
+<div class="thread">Thread: 70140045951280, Fiber: 70140054192180 (100.00% ~ 0.0029680728912353516)</div><ul name="thread"><li class="color9" style="display:block"><a href="#" class="toggle minus" ></a><span> 100.00% (100.00%) <a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/printers_test.rb&line=14">PrintersTest#setup</a> [1 calls, <a href='multi.graph.html#PrintersTest_setup_70140054192180'>1</a> total]</span>
+<ul><li class="color9" style="display:block"><a href="#" class="toggle minus" ></a><span> 99.82% (99.82%) <a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=45">Object#run_primes</a> [1 calls, <a href='multi.graph.html#Object_run_primes_70140054192180'>1</a> total]</span>
+<ul><li class="color9" style="display:block"><a href="#" class="toggle minus" ></a><span> 92.62% (92.78%) <a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=24">Object#find_primes</a> [1 calls, <a href='multi.graph.html#Object_find_primes_70140054192180'>1</a> total]</span>
+<ul><li class="color9" style="display:block"><a href="#" class="toggle minus" ></a><span> 92.55% (99.93%) Array#select [1 calls, <a href='multi.graph.html#Array_select_70140054192180'>1</a> total]</span>
+<ul><li class="color8" style="display:block"><a href="#" class="toggle minus" ></a><span> 89.73% (96.95%) <a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=16">Object#is_prime</a> [200 calls, <a href='multi.graph.html#Object_is_prime_70140054192180'>200</a> total]</span>
+<ul><li class="color8" style="display:block"><a href="#" class="toggle empty" ></a><span> 86.63% (96.54%) Integer#upto [200 calls, <a href='multi.graph.html#Integer_upto_70140054192180'>201</a> total]</span>
+</li></ul></li></ul></li></ul></li><li class="color05" style="display:block"><a href="#" class="toggle plus" ></a><span> 6.64% (6.65%) <a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=7">Object#make_random_array</a> [1 calls, <a href='multi.graph.html#Object_make_random_array_70140054192180'>1</a> total]</span>
+<ul style="display:none"><li class="color05" style="display:block"><a href="#" class="toggle plus" ></a><span> 6.33% (95.40%) Array#each_index [1 calls, <a href='multi.graph.html#Array_each_index_70140054192180'>1</a> total]</span>
+<ul style="display:none"><li class="color01" style="display:block"><a href="#" class="toggle plus" ></a><span> 3.96% (62.56%) Kernel#rand [200 calls, <a href='multi.graph.html#Kernel_rand_70140054192180'>200</a> total]</span>
+<ul style="display:none"><li class="color01" style="display:block"><a href="#" class="toggle empty" ></a><span> 1.02% (25.76%) Kernel#respond_to_missing? [200 calls, <a href='multi.graph.html#Kernel_respond_to_missing__70140054192180'>200</a> total]</span>
+</li></ul></li></ul></li><li class="color01" style="display:none"><a href="#" class="toggle empty" ></a><span> 0.20% (3.03%) Class#new [1 calls, <a href='multi.graph.html#Class_new_70140054192180'>1</a> total]</span>
+<ul style="display:none"><li class="color01" style="display:none"><a href="#" class="toggle empty" ></a><span> 0.06% (32.00%) Array#initialize [1 calls, <a href='multi.graph.html#Array_initialize_70140054192180'>1</a> total]</span>
+</li></ul></li></ul></li><li class="color01" style="display:none"><a href="#" class="toggle empty" ></a><span> 0.51% (0.51%) <a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=31">Object#find_largest</a> [1 calls, <a href='multi.graph.html#Object_find_largest_70140054192180'>1</a> total]</span>
+<ul style="display:none"><li class="color01" style="display:none"><a href="#" class="toggle empty" ></a><span> 0.37% (73.02%) Integer#upto [1 calls, <a href='multi.graph.html#Integer_upto_70140054192180'>201</a> total]</span>
+</li><li class="color01" style="display:none"><a href="#" class="toggle empty" ></a><span> 0.03% (6.35%) Array#first [1 calls, <a href='multi.graph.html#Array_first_70140054192180'>1</a> total]</span>
+</li></ul></li></ul></li></ul></li></ul><div id="sentinel"></div></div></body></html>
diff --git a/app/server/vendor/ruby-prof-0.15.8/examples/stack.html b/app/server/vendor/ruby-prof-0.15.8/examples/stack.html
new file mode 100755
index 0000000..19529e1
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/examples/stack.html
@@ -0,0 +1,547 @@
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8">
+<title>ruby-prof call tree</title>
+<style type="text/css">
+<!--
+  body {
+    font-size:70%;
+    padding:0;
+    margin:5px;
+    margin-right:0px;
+    margin-left:0px;
+    background: #ffffff;
+  }
+  ul {
+    margin-left:0px;
+    margin-top:0px;
+    margin-bottom:0px;
+    padding-left:0px;
+    list-style-type:none;
+  }
+  li {
+    margin-left:11px;
+    padding:0px;
+    white-space:nowrap;
+    border-top:1px solid #cccccc;
+    border-left:1px solid #cccccc;
+    border-bottom:none;
+  }
+  .thread {
+    margin-left:11px;
+    background:#708090;
+    padding-top:3px;
+    padding-left:12px;
+    padding-bottom:2px;
+    border-left:1px solid #CCCCCC;
+    border-top:1px solid #CCCCCC;
+    font-weight:bold;
+  }
+  .hidden {
+    display:none;
+    width:0px;
+    height:0px;
+    margin:0px;
+    padding:0px;
+    border-style:none;
+  }
+  .color01 { background:#adbdeb }
+  .color05 { background:#9daddb }
+  .color0 { background:#8d9dcb }
+  .color1 { background:#89bccb }
+  .color2 { background:#56e3e7 }
+  .color3 { background:#32cd70 }
+  .color4 { background:#a3d53c }
+  .color5 { background:#c4cb34 }
+  .color6 { background:#dcb66d }
+  .color7 { background:#cda59e }
+  .color8 { background:#be9d9c }
+  .color9 { background:#cf947a }
+  #commands {
+    font-size:10pt;
+    padding:10px;
+    margin-left:11px;
+    margin-bottom:0px;
+    margin-top:0px;
+    background:#708090;
+    border-top:1px solid #cccccc;
+    border-left:1px solid #cccccc;
+    border-bottom:none;
+  }
+  #titlebar {
+    font-size:10pt;
+    padding:10px;
+    margin-left:11px;
+    margin-bottom:0px;
+    margin-top:10px;
+    background:#8090a0;
+    border-top:1px solid #cccccc;
+    border-left:1px solid #cccccc;
+    border-bottom:none;
+  }
+  #help {
+    font-size:10pt;
+    padding:10px;
+    margin-left:11px;
+    margin-bottom:0px;
+    margin-top:0px;
+    background:#8090a0;
+    display:none;
+    border-top:1px solid #cccccc;
+    border-left:1px solid #cccccc;
+    border-bottom:none;
+  }
+  #sentinel {
+    height: 400px;
+    margin-left:11px;
+    background:#8090a0;
+    border-top:1px solid #cccccc;
+    border-left:1px solid #cccccc;
+    border-bottom:none;
+  }
+  input { margin-left:10px; }
+
+  .toggle {
+    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAJCAMAAAD0FKf3AAAAA3NCSVQICAjb4U/gAAAAb1BMVEX///98jcR8jMV4jMB7jcR7jcR8jcT////7/f/3/P/0+vzx+v7s9vzq9Pzm8Prk7vzi7fnj5/Pc5vTb5vbg5PHW4fHV3/XS3fLM1+3K1e/G0e3EzuzCzey8x+m8xuystuSqtt98jsR8jcR7jcQAAADWswcWAAAAJXRSTlMAVVVV3e7u////////////////////////////////////////Vv4VOQAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAACVSURBVAiZPc/hDoIwDATgobCWgZsWgSGidOz9n9F1CPfrki+5tIqPXHSQVMVZFH8/sx/Is16X9zR2vtQPAMC6LxVnco5Dpvtt40QRGrspnueBqDUcdmrEMILtknkiQkQOU5RAsn9RPGRKNkLOxiibIEauNSYZy2CNyerGRngtsilkiLXP9Cx1bzuAZU13Himq/a3rWX4VVRPEuDWiLQAAAABJRU5ErkJggg==) no-repeat left center;
+    float:left;
+    width:9px;
+    height:9px;
+    margin:2px 1px 1px 1px;
+  }
+
+  .toggle.minus {
+    background-position: -9px 0;
+  }
+
+  .toggle.plus {
+    background-position: -18px 0;
+  }
+
+-->
+</style>
+<script type="text/javascript">
+  /*
+   Copyright (C) 2005,2009  Stefan Kaes
+   skaes at railsexpress.de
+   */
+
+  function rootNode() {
+    return currentThread;
+  }
+
+  function showUL(node, show) {
+    var lis = node.childNodes;
+    var l = lis.length;
+    for (var i=0; i < l ; i++ ) {
+      toggle(lis[i], show);
+    }
+  }
+
+  function findUlChild(li){
+    var ul = li.childNodes[2];
+    while (ul && ul.nodeName != "UL") {
+      ul = ul.nextSibling;
+    }
+    return ul;
+  }
+
+  function isLeafNode(li) {
+    var img = li.firstChild;
+    return (img.className.indexOf('empty') > -1);
+  }
+
+  function toggle(li, show) {
+    if (isLeafNode(li))
+      return;
+
+    var img = li.firstChild;
+    img.className = 'toggle ';
+    img.className += show ? 'minus' : 'plus';
+
+    var ul = findUlChild(li);
+    if (ul) {
+      ul.style.display = show ? 'block' : 'none';
+      showUL(ul, true);
+    }
+  }
+
+  function toggleLI(li) {
+    var img = li.firstChild;
+    if (img.className.indexOf("minus")>-1)
+      toggle(li, false);
+    else {
+      if (img.className.indexOf("plus")>-1)
+        toggle(li, true);
+    }
+  }
+
+  function aboveThreshold(text, threshold) {
+    var match = text.match(/\d+[.,]\d+/);
+    return (match && parseFloat(match[0].replace(/,/, '.'))>=threshold);
+  }
+
+  function setThresholdLI(li, threshold) {
+    var img = li.firstChild;
+    var text = img.nextSibling;
+    var ul = findUlChild(li);
+
+    var visible = aboveThreshold(text.nodeValue, threshold) ? 1 : 0;
+
+    var count = 0;
+    if (ul) {
+      count = setThresholdUL(ul, threshold);
+    }
+    if (count>0) {
+      img.className = 'toggle minus';
+    }
+    else {
+      img.className = 'toggle empty';
+    }
+    if (visible) {
+      li.style.display = 'block'
+    }
+    else {
+      li.style.display = 'none'
+    }
+    return visible;
+  }
+
+  function setThresholdUL(node, threshold) {
+    var lis = node.childNodes;
+    var l = lis.length;
+
+    var count = 0;
+    for ( var i = 0; i < l ; i++ ) {
+      count = count + setThresholdLI(lis[i], threshold);
+    }
+
+    var visible = (count > 0) ? 1 : 0;
+    if (visible) {
+      node.style.display = 'block';
+    }
+    else {
+      node.style.display = 'none';
+    }
+    return visible;
+  }
+
+  function toggleChildren(img, event) {
+    event.cancelBubble=true;
+    if (img.className.indexOf('empty') > -1)
+      return;
+
+    var minus = (img.className.indexOf('minus') > -1);
+
+    if (minus) {
+      img.className = 'toggle plus';
+    }
+    else
+      img.className = 'toggle minus';
+
+    var li = img.parentNode;
+    var ul = findUlChild(li);
+    if (ul) {
+      if (minus)
+        ul.style.display = 'none';
+      else
+        ul.style.display = 'block';
+    }
+    if (minus)
+      moveSelectionIfNecessary(li);
+  }
+
+  function showChildren(li) {
+    var img = li.firstChild;
+    if (img.className.indexOf('empty') > -1)
+      return;
+    img.className = 'toggle minus';
+
+    var ul = findUlChild(li);
+    if (ul) {
+      ul.style.display = 'block';
+    }
+  }
+
+  function setThreshold() {
+    var tv = document.getElementById("threshold").value;
+    if (tv.match(/[0-9]+([.,][0-9]+)?/)) {
+      var f = parseFloat(tv.replace(/,/, '.'));
+      var threads = document.getElementsByName("thread");
+      var l = threads.length;
+      for ( var i = 0; i < l ; i++ ) {
+        setThresholdUL(threads[i], f);
+      }
+      var p = selectedNode;
+      while (p && p.style.display=='none')
+        p=p.parentNode.parentNode;
+      if (p && p.nodeName=="LI")
+        selectNode(p);
+    }
+    else {
+      alert("Please specify a decimal number as threshold value!");
+    }
+  }
+
+  function expandAll(event) {
+    toggleAll(event, true);
+  }
+
+  function collapseAll(event) {
+    toggleAll(event, false);
+    selectNode(rootNode(), null);
+  }
+
+  function toggleAll(event, show) {
+    event.cancelBubble=true;
+    var threads = document.getElementsByName("thread");
+    var l = threads.length;
+    for ( var i = 0; i < l ; i++ ) {
+      showUL(threads[i], show);
+    }
+  }
+
+  function toggleHelp(node) {
+    var help = document.getElementById("help");
+    if (node.value == "Show Help") {
+      node.value = "Hide Help";
+      help.style.display = 'block';
+    }
+    else {
+      node.value = "Show Help";
+      help.style.display = 'none';
+    }
+  }
+
+  var selectedNode = null;
+  var selectedColor = null;
+  var selectedThread = null;
+
+  function descendentOf(a,b){
+    while (a!=b && b!=null)
+      b=b.parentNode;
+    return (a==b);
+  }
+
+  function moveSelectionIfNecessary(node){
+    if (descendentOf(node, selectedNode))
+      selectNode(node, null);
+  }
+
+  function selectNode(node, event) {
+    if (event) {
+      event.cancelBubble = true;
+      thread = findThread(node);
+      selectThread(thread);
+    }
+    if (selectedNode) {
+      selectedNode.style.background = selectedColor;
+    }
+    selectedNode = node;
+    selectedColor = node.style.background;
+    selectedNode.style.background = "red";
+    selectedNode.scrollIntoView();
+    window.scrollBy(0,-400);
+  }
+
+  function moveUp(){
+    move(selectedNode.previousSibling);
+  }
+
+  function moveDown(){
+    move(selectedNode.nextSibling);
+  }
+
+  function move(p) {
+    while (p && p.style.display == 'none')
+      p = p.nextSibling;
+    if (p && p.nodeName == "LI") {
+      selectNode(p, null);
+    }
+  }
+
+  function moveLeft(){
+    var p = selectedNode.parentNode.parentNode;
+    if (p && p.nodeName=="LI") {
+      selectNode(p, null);
+    }
+  }
+
+  function moveRight(){
+    if (!isLeafNode(selectedNode)) {
+      showChildren(selectedNode);
+      var ul = findUlChild(selectedNode);
+      if (ul) {
+        selectNode(ul.firstChild, null);
+      }
+    }
+  }
+
+  function moveForward(){
+    if (isLeafNode(selectedNode)) {
+      var p = selectedNode;
+      while ((p.nextSibling == null || p.nextSibling.style.display=='none') && p.nodeName=="LI") {
+        p = p.parentNode.parentNode;
+      }
+      if (p.nodeName=="LI")
+        selectNode(p.nextSibling, null);
+    }
+    else {
+      moveRight();
+    }
+  }
+
+  function isExpandedNode(li){
+    var img = li.firstChild;
+    return(img.className.indexOf('minus')>-1);
+  }
+
+  function moveBackward(){
+    var p = selectedNode;
+    var q = p.previousSibling;
+    while (q != null && q.style.display=='none')
+      q = q.previousSibling;
+    if (q == null) {
+      p = p.parentNode.parentNode;
+    } else {
+      while (!isLeafNode(q) && isExpandedNode(q)) {
+        q = findUlChild(q).lastChild;
+        while (q.style.display=='none')
+          q = q.previousSibling;
+      }
+      p = q;
+    }
+    if (p.nodeName=="LI")
+      selectNode(p, null);
+  }
+
+  function moveHome() {
+    selectNode(currentThread);
+  }
+
+  var currentThreadIndex = null;
+
+  function findThread(node){
+    while (node && !node.parentNode.nodeName.match(/BODY|DIV/g)) {
+      node = node.parentNode;
+    }
+    return node.firstChild;
+  }
+
+  function selectThread(node){
+    var threads = document.getElementsByName("thread");
+    currentThread = node;
+    for (var i=0; i<threads.length; i++) {
+      if (threads[i]==currentThread.parentNode)
+        currentThreadIndex = i;
+    }
+  }
+
+  function nextThread(){
+    var threads = document.getElementsByName("thread");
+    if (currentThreadIndex==threads.length-1)
+      currentThreadIndex = 0;
+    else
+      currentThreadIndex += 1
+    currentThread = threads[currentThreadIndex].firstChild;
+    selectNode(currentThread, null);
+  }
+
+  function previousThread(){
+    var threads = document.getElementsByName("thread");
+    if (currentThreadIndex==0)
+      currentThreadIndex = threads.length-1;
+    else
+      currentThreadIndex -= 1
+    currentThread = threads[currentThreadIndex].firstChild;
+    selectNode(currentThread, null);
+  }
+
+  function switchThread(node, event){
+    event.cancelBubble = true;
+    selectThread(node.nextSibling.firstChild);
+    selectNode(currentThread, null);
+  }
+
+  function handleKeyEvent(event){
+    var code = event.charCode ? event.charCode : event.keyCode;
+    var str = String.fromCharCode(code);
+    switch (str) {
+      case "a": moveLeft();  break;
+      case "s": moveDown();  break;
+      case "d": moveRight(); break;
+      case "w": moveUp();    break;
+      case "f": moveForward(); break;
+      case "b": moveBackward(); break;
+      case "x": toggleChildren(selectedNode.firstChild, event); break;
+      case "*": toggleLI(selectedNode); break;
+      case "n": nextThread(); break;
+      case "h": moveHome(); break;
+      case "p": previousThread(); break;
+    }
+  }
+  document.onkeypress=function(event){ handleKeyEvent(event) };
+
+  window.onload=function(){
+    var images = document.querySelectorAll(".toggle");
+    for (var i=0; i<images.length; i++) {
+      var img = images[i];
+        img.onclick = function(event){ toggleChildren(this, event); return false; };
+    }
+    var divs = document.getElementsByTagName("div");
+    for (i=0; i<divs.length; i++) {
+      var div = divs[i];
+      if (div.className == "thread")
+        div.onclick = function(event){ switchThread(this, event) };
+    }
+    var lis = document.getElementsByTagName("li");
+    for (var i=0; i<lis.length; i++) {
+      lis[i].onclick = function(event){ selectNode(this, event); };
+    }
+    var threads = document.getElementsByName("thread");;
+    currentThreadIndex = 0;
+    currentThread = threads[0].firstChild;
+    selectNode(currentThread, null);
+  };
+
+</script>
+</head><body><div style="display: inline-block;">
+<div id="titlebar">
+Call tree for application <b>primes </b><br/>
+Generated on 2015-04-24 11:52:24 +0200 with options {:application=>"primes"}<br/>
+</div>
+<div id="commands">
+<span style="font-size: 11pt; font-weight: bold;">Threshold:</span>
+<input value="1.0" size="3" id="threshold" type="text">
+<input value="Apply" onclick="setThreshold();" type="submit">
+<input value="Expand All" onclick="expandAll(event);" type="submit">
+<input value="Collapse All" onclick="collapseAll(event);" type="submit">
+<input value="Show Help" onclick="toggleHelp(this);" type="submit">
+</div>
+<div style="display: none;" id="help">
+• Enter a decimal value <i>d</i> into the threshold field and click "Apply"
+        to hide all nodes marked with time values lower than <i>d</i>.<br>
+• Click on "Expand All" for full tree expansion.<br>
+• Click on "Collapse All" to show only top level nodes.<br>
+• Use a, s, d, w as in Quake or Urban Terror to navigate the tree.<br>
+• Use f and b to navigate the tree in preorder forward and backwards.<br>
+• Use x to toggle visibility of a subtree.<br>
+• Use * to expand/collapse a whole subtree.<br>
+• Use h to navigate to thread root.<br>
+• Use n and p to navigate between threads.<br>
+• Click on background to move focus to a subtree.<br>
+</div>
+<div class="thread">Thread: 70140045951280, Fiber: 70140054192180 (100.00% ~ 0.0029680728912353516)</div><ul name="thread"><li class="color9" style="display:block"><a href="#" class="toggle minus" ></a><span> 100.00% (100.00%) <a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/printers_test.rb&line=14">PrintersTest#setup</a> [1 calls, 1 total]</span>
+<ul><li class="color9" style="display:block"><a href="#" class="toggle minus" ></a><span> 99.82% (99.82%) <a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=45">Object#run_primes</a> [1 calls, 1 total]</span>
+<ul><li class="color9" style="display:block"><a href="#" class="toggle minus" ></a><span> 92.62% (92.78%) <a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=24">Object#find_primes</a> [1 calls, 1 total]</span>
+<ul><li class="color9" style="display:block"><a href="#" class="toggle minus" ></a><span> 92.55% (99.93%) Array#select [1 calls, 1 total]</span>
+<ul><li class="color8" style="display:block"><a href="#" class="toggle minus" ></a><span> 89.73% (96.95%) <a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=16">Object#is_prime</a> [200 calls, 200 total]</span>
+<ul><li class="color8" style="display:block"><a href="#" class="toggle empty" ></a><span> 86.63% (96.54%) Integer#upto [200 calls, 201 total]</span>
+</li></ul></li></ul></li></ul></li><li class="color05" style="display:block"><a href="#" class="toggle plus" ></a><span> 6.64% (6.65%) <a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=7">Object#make_random_array</a> [1 calls, 1 total]</span>
+<ul style="display:none"><li class="color05" style="display:block"><a href="#" class="toggle plus" ></a><span> 6.33% (95.40%) Array#each_index [1 calls, 1 total]</span>
+<ul style="display:none"><li class="color01" style="display:block"><a href="#" class="toggle plus" ></a><span> 3.96% (62.56%) Kernel#rand [200 calls, 200 total]</span>
+<ul style="display:none"><li class="color01" style="display:block"><a href="#" class="toggle empty" ></a><span> 1.02% (25.76%) Kernel#respond_to_missing? [200 calls, 200 total]</span>
+</li></ul></li></ul></li><li class="color01" style="display:none"><a href="#" class="toggle empty" ></a><span> 0.20% (3.03%) Class#new [1 calls, 1 total]</span>
+<ul style="display:none"><li class="color01" style="display:none"><a href="#" class="toggle empty" ></a><span> 0.06% (32.00%) Array#initialize [1 calls, 1 total]</span>
+</li></ul></li></ul></li><li class="color01" style="display:none"><a href="#" class="toggle empty" ></a><span> 0.51% (0.51%) <a href="txmt://open?url=file:///Users/stefan.kaes/src/ruby-prof/test/prime.rb&line=31">Object#find_largest</a> [1 calls, 1 total]</span>
+<ul style="display:none"><li class="color01" style="display:none"><a href="#" class="toggle empty" ></a><span> 0.37% (73.02%) Integer#upto [1 calls, 201 total]</span>
+</li><li class="color01" style="display:none"><a href="#" class="toggle empty" ></a><span> 0.03% (6.35%) Array#first [1 calls, 1 total]</span>
+</li></ul></li></ul></li></ul></li></ul><div id="sentinel"></div></div></body></html>
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/.gitignore b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/.gitignore
new file mode 100755
index 0000000..9d22eb4
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/.gitignore
@@ -0,0 +1,2 @@
+*.o
+*.so
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/extconf.rb b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/extconf.rb
new file mode 100755
index 0000000..e367f1e
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/extconf.rb
@@ -0,0 +1,55 @@
+require "mkmf"
+
+if RUBY_VERSION < "1.9.3"
+  STDERR.puts("Ruby version #{RUBY_VERSION} is no longer supported. Please upgrade to 1.9.3 or higher")
+  exit(1)
+end
+
+# standard ruby methods
+have_func("rb_gc_stat")
+have_func("rb_gc_count")
+
+# Alexander Dymo GC patch
+have_func("rb_os_allocated_objects")
+have_func("rb_gc_allocated_size")
+
+# Stefan Kaes GC patches
+have_func("rb_gc_collections")
+have_func("rb_gc_time")
+# for ruby 2.1
+have_func("rb_gc_total_time")
+have_func("rb_gc_total_mallocs")
+have_func("rb_gc_total_malloced_bytes")
+
+# Lloyd Hilaiel's heap info patch
+have_func("rb_heap_total_mem")
+have_func("rb_gc_heap_info")
+
+def add_define(name, value = nil)
+  if value
+    $defs.push("-D#{name}=#{value}")
+  else
+    $defs.push("-D#{name}")
+  end
+end
+
+if !Gem.win_platform? && RUBY_PLATFORM !~ /(darwin|openbsd)/
+  $LDFLAGS += " -lrt" # for clock_gettime
+end
+add_define("RUBY_VERSION", RUBY_VERSION.gsub('.', ''))
+
+# for ruby 1.9, determine whether threads inherit trace flags (latest 1.9.2 and later should work correctly)
+if RUBY_VERSION > "1.9"
+  require 'set'
+  threads = Set.new
+  set_trace_func lambda { |*args| threads << Thread.current.object_id }
+  Thread.new{1}.join
+  set_trace_func nil
+  if threads.size < 2
+    # if we end up here, ruby does not automatically active tracing in spawned threads
+    STDERR.puts("Ruby #{RUBY_VERSION} does not activate tracing in spawned threads. Consider upgrading.")
+    exit(1)
+  end
+end
+
+create_makefile("ruby_prof")
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_call_info.c b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_call_info.c
new file mode 100755
index 0000000..e032039
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_call_info.c
@@ -0,0 +1,407 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+#include "ruby_prof.h"
+
+#define INITIAL_CALL_INFOS_SIZE 2
+
+VALUE cCallInfo;
+
+
+// Forward declarations
+st_table * call_info_table_create();
+
+
+/* =======  prof_call_info_t   ========*/
+prof_call_info_t *
+prof_call_info_create(prof_method_t* method, prof_call_info_t* parent)
+{
+    prof_call_info_t *result = ALLOC(prof_call_info_t);
+    result->object = Qnil;
+    result->target = method;
+    result->parent = parent;
+    result->call_infos = call_info_table_create();
+    result->children = Qnil;
+
+    result->called = 0;
+    result->total_time = 0;
+    result->self_time = 0;
+    result->wait_time = 0;
+    result->line = 0;
+    return result;
+}
+static void
+prof_call_info_ruby_gc_free(prof_call_info_t *call_info)
+{
+	/* Has this thread object been accessed by Ruby?  If
+	   yes clean it up so to avoid a segmentation fault. */
+	if (call_info->object != Qnil)
+	{
+		RDATA(call_info->object)->data = NULL;
+		RDATA(call_info->object)->dfree = NULL;
+		RDATA(call_info->object)->dmark = NULL;
+    }
+	call_info->object = Qnil;
+}
+
+static void
+prof_call_info_free(prof_call_info_t *call_info)
+{
+	prof_call_info_ruby_gc_free(call_info);
+	st_free_table(call_info->call_infos);
+	xfree(call_info);
+}
+
+static void
+prof_call_info_mark(prof_call_info_t *call_info)
+{
+	if (call_info->object)
+		rb_gc_mark(call_info->object);
+
+	if (call_info->children)
+		rb_gc_mark(call_info->children);
+
+	/* We don't mark the call info child table since that will be done
+	   via the appropriate method */
+}
+
+VALUE
+prof_call_info_wrap(prof_call_info_t *call_info)
+{
+  if (call_info->object == Qnil)
+  {
+    call_info->object = Data_Wrap_Struct(cCallInfo, prof_call_info_mark, prof_call_info_ruby_gc_free, call_info);
+  }
+  return call_info->object;
+}
+
+static prof_call_info_t *
+prof_get_call_info(VALUE self)
+{
+    /* Can't use Data_Get_Struct because that triggers the event hook
+       ending up in endless recursion. */
+	prof_call_info_t* result = DATA_PTR(self);
+
+	if (!result)
+	    rb_raise(rb_eRuntimeError, "This RubyProf::CallInfo instance has already been freed, likely because its profile has been freed.");
+
+   return result;
+}
+
+/* =======  Call Info Table   ========*/
+st_table *
+call_info_table_create()
+{
+  return st_init_table(&type_method_hash);
+}
+
+size_t
+call_info_table_insert(st_table *table, const prof_method_key_t *key, prof_call_info_t *val)
+{
+  return st_insert(table, (st_data_t) key, (st_data_t) val);
+}
+
+prof_call_info_t *
+call_info_table_lookup(st_table *table, const prof_method_key_t *key)
+{
+    st_data_t val;
+    if (st_lookup(table, (st_data_t) key, &val))
+    {
+      return (prof_call_info_t *) val;
+    }
+    else
+    {
+      return NULL;
+    }
+}
+
+
+/* =======  RubyProf::CallInfo   ========*/
+
+/* Document-class: RubyProf::CallInfo
+RubyProf::CallInfo is a helper class used by RubyProf::MethodInfo
+to keep track of which child methods were called and how long
+they took to execute. */
+
+
+/* call-seq:
+   called -> MethodInfo
+
+Returns the target method. */
+static VALUE
+prof_call_info_target(VALUE self)
+{
+    /* Target is a pointer to a method_info - so we have to be careful
+       about the GC.  We will wrap the method_info but provide no
+       free method so the underlying object is not freed twice! */
+
+    prof_call_info_t *result = prof_get_call_info(self);
+    return prof_method_wrap(result->target);
+}
+
+/* call-seq:
+   called -> int
+
+Returns the total amount of times this method was called. */
+static VALUE
+prof_call_info_called(VALUE self)
+{
+    prof_call_info_t *result = prof_get_call_info(self);
+    return INT2NUM(result->called);
+}
+
+/* call-seq:
+   called=n -> n
+
+Sets the call count to n. */
+static VALUE
+prof_call_info_set_called(VALUE self, VALUE called)
+{
+    prof_call_info_t *result = prof_get_call_info(self);
+    result->called = NUM2INT(called);
+    return called;
+}
+
+/* call-seq:
+   depth -> int
+
+   returns the depth of this call info in the call graph */
+static VALUE
+prof_call_info_depth(VALUE self)
+{
+  prof_call_info_t *result = prof_get_call_info(self);
+  return rb_int_new(result->depth);
+}
+
+/* call-seq:
+   line_no -> int
+
+   returns the line number of the method */
+static VALUE
+prof_call_info_line(VALUE self)
+{
+  prof_call_info_t *result = prof_get_call_info(self);
+  return rb_int_new(result->line);
+}
+
+/* call-seq:
+   total_time -> float
+
+Returns the total amount of time spent in this method and its children. */
+static VALUE
+prof_call_info_total_time(VALUE self)
+{
+    prof_call_info_t *result = prof_get_call_info(self);
+    return rb_float_new(result->total_time);
+}
+
+/* call-seq:
+   add_total_time(call_info) -> nil
+
+adds total time time from call_info to self. */
+static VALUE
+prof_call_info_add_total_time(VALUE self, VALUE other)
+{
+    prof_call_info_t *result = prof_get_call_info(self);
+    prof_call_info_t *other_info = prof_get_call_info(other);
+
+    result->total_time += other_info->total_time;
+    return Qnil;
+}
+
+/* call-seq:
+   self_time -> float
+
+Returns the total amount of time spent in this method. */
+static VALUE
+prof_call_info_self_time(VALUE self)
+{
+    prof_call_info_t *result = prof_get_call_info(self);
+
+    return rb_float_new(result->self_time);
+}
+
+/* call-seq:
+   add_self_time(call_info) -> nil
+
+adds self time from call_info to self. */
+static VALUE
+prof_call_info_add_self_time(VALUE self, VALUE other)
+{
+    prof_call_info_t *result = prof_get_call_info(self);
+    prof_call_info_t *other_info = prof_get_call_info(other);
+
+    result->self_time += other_info->self_time;
+    return Qnil;
+}
+
+/* call-seq:
+   wait_time -> float
+
+Returns the total amount of time this method waited for other threads. */
+static VALUE
+prof_call_info_wait_time(VALUE self)
+{
+    prof_call_info_t *result = prof_get_call_info(self);
+
+    return rb_float_new(result->wait_time);
+}
+
+/* call-seq:
+   add_wait_time(call_info) -> nil
+
+adds wait time from call_info to self. */
+
+static VALUE
+prof_call_info_add_wait_time(VALUE self, VALUE other)
+{
+    prof_call_info_t *result = prof_get_call_info(self);
+    prof_call_info_t *other_info = prof_get_call_info(other);
+
+    result->wait_time += other_info->wait_time;
+    return Qnil;
+}
+
+/* call-seq:
+   parent -> call_info
+
+Returns the call_infos parent call_info object (the method that called this method).*/
+static VALUE
+prof_call_info_parent(VALUE self)
+{
+    prof_call_info_t *result = prof_get_call_info(self);
+    if (result->parent)
+      return prof_call_info_wrap(result->parent);
+    else
+      return Qnil;
+}
+
+/* call-seq:
+   parent=new_parent -> new_parent
+
+Changes the parent of self to new_parent and returns it.*/
+static VALUE
+prof_call_info_set_parent(VALUE self, VALUE new_parent)
+{
+    prof_call_info_t *result = prof_get_call_info(self);
+    if (new_parent == Qnil)
+      result->parent = NULL;
+    else
+      result->parent = prof_get_call_info(new_parent);
+    return prof_call_info_parent(self);
+}
+
+static int
+prof_call_info_collect_children(st_data_t key, st_data_t value, st_data_t result)
+{
+    prof_call_info_t *call_info = (prof_call_info_t *) value;
+    VALUE arr = (VALUE) result;
+    rb_ary_push(arr, prof_call_info_wrap(call_info));
+    return ST_CONTINUE;
+}
+
+/* call-seq:
+   children -> hash
+
+Returns an array of call info objects of methods that this method
+called (ie, children).*/
+static VALUE
+prof_call_info_children(VALUE self)
+{
+    prof_call_info_t *call_info = prof_get_call_info(self);
+    if (call_info->children == Qnil)
+    {
+      call_info->children = rb_ary_new();
+      st_foreach(call_info->call_infos, prof_call_info_collect_children, call_info->children);
+    }
+    return call_info->children;
+}
+
+/* =======  Call Infos   ========*/
+prof_call_infos_t*
+prof_call_infos_create()
+{
+   prof_call_infos_t *result = ALLOC(prof_call_infos_t);
+   result->start = ALLOC_N(prof_call_info_t*, INITIAL_CALL_INFOS_SIZE);
+   result->end = result->start + INITIAL_CALL_INFOS_SIZE;
+   result->ptr = result->start;
+   result->object = Qnil;
+   return result;
+}
+
+void
+prof_call_infos_mark(prof_call_infos_t *call_infos)
+{
+    prof_call_info_t **call_info;
+
+	if (call_infos->object)
+		rb_gc_mark(call_infos->object);
+
+    for(call_info=call_infos->start; call_info<call_infos->ptr; call_info++)
+    {
+		prof_call_info_mark(*call_info);
+    }
+}
+
+void
+prof_call_infos_free(prof_call_infos_t *call_infos)
+{
+    prof_call_info_t **call_info;
+
+    for(call_info=call_infos->start; call_info<call_infos->ptr; call_info++)
+    {
+		prof_call_info_free(*call_info);
+    }
+}
+
+void
+prof_add_call_info(prof_call_infos_t *call_infos, prof_call_info_t *call_info)
+{
+  if (call_infos->ptr == call_infos->end)
+  {
+    size_t len = call_infos->ptr - call_infos->start;
+    size_t new_capacity = (call_infos->end - call_infos->start) * 2;
+    REALLOC_N(call_infos->start, prof_call_info_t*, new_capacity);
+    call_infos->ptr = call_infos->start + len;
+    call_infos->end = call_infos->start + new_capacity;
+  }
+  *call_infos->ptr = call_info;
+  call_infos->ptr++;
+}
+
+VALUE
+prof_call_infos_wrap(prof_call_infos_t *call_infos)
+{
+  if (call_infos->object == Qnil)
+  {
+    prof_call_info_t **i;
+    call_infos->object = rb_ary_new();
+    for(i=call_infos->start; i<call_infos->ptr; i++)
+    {
+      VALUE call_info = prof_call_info_wrap(*i);
+      rb_ary_push(call_infos->object, call_info);
+    }
+  }
+  return call_infos->object;
+}
+
+void rp_init_call_info()
+{
+    /* CallInfo */
+    cCallInfo = rb_define_class_under(mProf, "CallInfo", rb_cObject);
+    rb_undef_method(CLASS_OF(cCallInfo), "new");
+    rb_define_method(cCallInfo, "parent", prof_call_info_parent, 0);
+    rb_define_method(cCallInfo, "parent=", prof_call_info_set_parent, 1);
+    rb_define_method(cCallInfo, "children", prof_call_info_children, 0);
+    rb_define_method(cCallInfo, "target", prof_call_info_target, 0);
+    rb_define_method(cCallInfo, "called", prof_call_info_called, 0);
+    rb_define_method(cCallInfo, "called=", prof_call_info_set_called, 1);
+    rb_define_method(cCallInfo, "total_time", prof_call_info_total_time, 0);
+    rb_define_method(cCallInfo, "add_total_time", prof_call_info_add_total_time, 1);
+    rb_define_method(cCallInfo, "self_time", prof_call_info_self_time, 0);
+    rb_define_method(cCallInfo, "add_self_time", prof_call_info_add_self_time, 1);
+    rb_define_method(cCallInfo, "wait_time", prof_call_info_wait_time, 0);
+    rb_define_method(cCallInfo, "add_wait_time", prof_call_info_add_wait_time, 1);
+    rb_define_method(cCallInfo, "depth", prof_call_info_depth, 0);
+    rb_define_method(cCallInfo, "line", prof_call_info_line, 0);
+}
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_call_info.h b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_call_info.h
new file mode 100755
index 0000000..f3ce1ac
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_call_info.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RP_CALL_INFO_H__
+#define __RP_CALL_INFO_H__
+
+#include "rp_measure.h"
+#include "rp_method.h"
+
+extern VALUE cCallInfo;
+
+/* Callers and callee information for a method. */
+typedef struct prof_call_info_t
+{
+    prof_method_t *target; /* Use target instead of method to avoid conflict with Ruby method */
+    struct prof_call_info_t *parent;
+    st_table *call_infos;
+    int called;
+	int depth;
+    double total_time;
+    double self_time;
+    double wait_time;
+    int line;
+    VALUE object;
+    VALUE children;
+} prof_call_info_t;
+
+/* Array of call_info objects */
+typedef struct prof_call_infos_t
+{
+    prof_call_info_t **start;
+    prof_call_info_t **end;
+    prof_call_info_t **ptr;
+    VALUE object;
+} prof_call_infos_t;
+
+
+void rp_init_call_info(void);
+prof_call_infos_t* prof_call_infos_create();
+void prof_call_infos_mark(prof_call_infos_t *call_infos);
+void prof_call_infos_free(prof_call_infos_t *call_infos);
+void prof_add_call_info(prof_call_infos_t *call_infos, prof_call_info_t *call_info);
+VALUE prof_call_infos_wrap(prof_call_infos_t *call_infos);
+prof_call_info_t * prof_call_info_create(prof_method_t* method, prof_call_info_t* parent);
+prof_call_info_t * call_info_table_lookup(st_table *table, const prof_method_key_t *key);
+size_t call_info_table_insert(st_table *table, const prof_method_key_t *key, prof_call_info_t *val);
+
+#endif //__RP_CALL_INFO_H__
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure.c b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure.c
new file mode 100755
index 0000000..bf45692
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+#include "ruby_prof.h"
+
+VALUE mMeasure;
+
+prof_measurer_t* prof_get_measurer(prof_measure_mode_t measure)
+{
+    switch (measure) {
+    case MEASURE_WALL_TIME:
+        return prof_measurer_wall_time();
+    case MEASURE_PROCESS_TIME:
+        return prof_measurer_process_time();
+    case MEASURE_CPU_TIME:
+        return prof_measurer_cpu_time();
+    case MEASURE_ALLOCATIONS:
+        return prof_measurer_allocations();
+    case MEASURE_MEMORY:
+        return prof_measurer_memory();
+    case MEASURE_GC_TIME:
+        return prof_measurer_gc_time();
+    case MEASURE_GC_RUNS:
+        return prof_measurer_gc_runs();
+    default:
+        rb_raise(rb_eArgError, "Unknown measure mode: %d", measure);
+    }
+};
+
+void rp_init_measure()
+{
+    mMeasure = rb_define_module_under(mProf, "Measure");
+    rp_init_measure_wall_time();
+    rp_init_measure_cpu_time();
+    rp_init_measure_process_time();
+    rp_init_measure_allocations();
+    rp_init_measure_memory();
+    rp_init_measure_gc_time();
+    rp_init_measure_gc_runs();
+}
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure.h b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure.h
new file mode 100755
index 0000000..ce0f96e
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure.h
@@ -0,0 +1,45 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RP_MEASUREMENT_H__
+#define __RP_MEASUREMENT_H__
+
+extern VALUE mMeasure;
+
+typedef double (*get_measurement)();
+
+typedef struct
+{
+    get_measurement measure;
+} prof_measurer_t;
+
+typedef enum
+{
+    MEASURE_WALL_TIME,
+    MEASURE_PROCESS_TIME,
+    MEASURE_CPU_TIME,
+    MEASURE_ALLOCATIONS,
+    MEASURE_MEMORY,
+    MEASURE_GC_TIME,
+    MEASURE_GC_RUNS,
+} prof_measure_mode_t;
+
+prof_measurer_t* prof_get_measurer(prof_measure_mode_t measure);
+prof_measurer_t* prof_measurer_allocations();
+prof_measurer_t* prof_measurer_cpu_time();
+prof_measurer_t* prof_measurer_gc_runs();
+prof_measurer_t* prof_measurer_gc_time();
+prof_measurer_t* prof_measurer_memory();
+prof_measurer_t* prof_measurer_process_time();
+prof_measurer_t* prof_measurer_wall_time();
+
+void rp_init_measure();
+void rp_init_measure_allocations();
+void rp_init_measure_cpu_time();
+void rp_init_measure_gc_runs();
+void rp_init_measure_gc_time();
+void rp_init_measure_memory();
+void rp_init_measure_process_time();
+void rp_init_measure_wall_time();
+
+#endif //__RP_MEASUREMENT_H__
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_allocations.c b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_allocations.c
new file mode 100755
index 0000000..4ecfc20
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_allocations.c
@@ -0,0 +1,76 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+/* :nodoc: */
+
+#include "ruby_prof.h"
+
+static VALUE cMeasureAllocations;
+
+#if defined(HAVE_RB_OS_ALLOCATED_OBJECTS)
+  unsigned LONG_LONG rb_os_allocated_objects();
+#endif
+
+#if defined(HAVE_RB_GC_STAT)
+size_t rb_gc_stat(VALUE key);
+
+#if RUBY_VERSION >= 220
+#define TOTAL_ALLOCATED_OBJECTS_STRING "total_allocated_objects"
+#else
+#define TOTAL_ALLOCATED_OBJECTS_STRING "total_allocated_object"
+#endif
+
+#endif
+
+static double
+measure_allocations()
+{
+#if defined(HAVE_RB_OS_ALLOCATED_OBJECTS)
+#define MEASURE_ALLOCATIONS_ENABLED Qtrue
+    return rb_os_allocated_objects();
+
+#elif defined(HAVE_RB_GC_STAT) && RUBY_VERSION >= 210
+#define MEASURE_ALLOCATIONS_ENABLED Qtrue
+    static VALUE total_alloc_symbol = 0;
+    if (!total_alloc_symbol) {
+      total_alloc_symbol = ID2SYM(rb_intern_const(TOTAL_ALLOCATED_OBJECTS_STRING));
+    }
+    return rb_gc_stat(total_alloc_symbol);
+
+#else
+#define MEASURE_ALLOCATIONS_ENABLED Qfalse
+    return 0;
+#endif
+}
+
+
+prof_measurer_t* prof_measurer_allocations()
+{
+  prof_measurer_t* measure = ALLOC(prof_measurer_t);
+  measure->measure = measure_allocations;
+  return measure;
+}
+
+/* call-seq:
+     measure -> int
+
+Returns the number of Ruby object allocations. */
+
+static VALUE
+prof_measure_allocations(VALUE self)
+{
+#if defined(HAVE_LONG_LONG)
+    return ULL2NUM(measure_allocations());
+#else
+    return ULONG2NUM(measure_allocations());
+#endif
+}
+
+void rp_init_measure_allocations()
+{
+    rb_define_const(mProf, "ALLOCATIONS", INT2NUM(MEASURE_ALLOCATIONS));
+    rb_define_const(mProf, "ALLOCATIONS_ENABLED", MEASURE_ALLOCATIONS_ENABLED);
+
+    cMeasureAllocations = rb_define_class_under(mMeasure, "Allocations", rb_cObject);
+    rb_define_singleton_method(cMeasureAllocations, "measure", prof_measure_allocations, 0);
+}
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_cpu_time.c b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_cpu_time.c
new file mode 100755
index 0000000..b9678a1
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_cpu_time.c
@@ -0,0 +1,138 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+#include "ruby_prof.h"
+
+static VALUE cMeasureCpuTime;
+
+/* The _WIN32 check is needed for msys (and maybe cygwin?) */
+#if defined(__GNUC__) && !defined(_WIN32)
+
+#include <sys/resource.h>
+#include <stdint.h>
+#include <time.h>
+
+static unsigned long long get_cpu_time()
+{
+#if defined(__i386__) || defined(__x86_64__)
+    uint32_t a, d;
+    __asm__ volatile("rdtsc" : "=a" (a), "=d" (d));
+    return ((uint64_t)d << 32) + a;
+#elif defined(__powerpc__) || defined(__ppc__)
+    unsigned long long x, y;
+
+    __asm__ __volatile__ ("\n\
+    1:  mftbu   %1\n\
+        mftb    %L0\n\
+        mftbu   %0\n\
+        cmpw    %0,%1\n\
+        bne-    1b"
+        : "=r" (x), "=r" (y));
+
+    return x;
+#endif
+}
+
+static unsigned long long get_cpu_frequency()
+{
+    static unsigned long long cpu_frequency;
+
+    if(!cpu_frequency) {
+        unsigned long long x, y;
+
+        struct timespec ts;
+        ts.tv_sec = 0;
+        ts.tv_nsec = 500000000;
+        x = get_cpu_time();
+        nanosleep(&ts, NULL);
+        y = get_cpu_time();
+        cpu_frequency = (y - x) * 2;
+    }
+
+    return cpu_frequency;
+}
+
+static double
+measure_cpu_time()
+{
+    struct rusage rusage;
+    getrusage(RUSAGE_SELF, &rusage);
+
+    double seconds = 0;
+
+    seconds += rusage.ru_utime.tv_sec;
+    seconds += rusage.ru_stime.tv_sec;
+
+    seconds += rusage.ru_utime.tv_usec / 1000000.0;
+    seconds += rusage.ru_stime.tv_usec / 1000000.0;
+
+    return seconds;
+}
+
+#elif defined(_WIN32)
+
+static unsigned long long get_cpu_time()
+{
+    LARGE_INTEGER time;
+    QueryPerformanceCounter(&time);
+    return time.QuadPart;
+}
+
+static unsigned long long get_cpu_frequency()
+{
+    static unsigned long long cpu_frequency;
+
+    if(!cpu_frequency) {
+        LARGE_INTEGER cpu_frequency_struct;
+        QueryPerformanceFrequency(&cpu_frequency_struct);
+        cpu_frequency = cpu_frequency_struct.QuadPart;
+    }
+
+    return cpu_frequency;
+}
+
+static double
+measure_cpu_time()
+{
+    return ((double)get_cpu_time()) / get_cpu_frequency();
+}
+#endif
+
+
+prof_measurer_t* prof_measurer_cpu_time()
+{
+    prof_measurer_t* measure = ALLOC(prof_measurer_t);
+    measure->measure = measure_cpu_time;
+    return measure;
+}
+
+/* call-seq:
+   measure -> float
+
+Returns the cpu time.*/
+static VALUE
+prof_measure_cpu_time(VALUE self)
+{
+    return rb_float_new(measure_cpu_time());
+}
+
+/* call-seq:
+   cpu_frequency -> int
+
+Returns the cpu's frequency.  This value is needed when
+RubyProf::measure_mode is set to CPU_TIME. */
+static VALUE
+prof_get_cpu_frequency(VALUE self)
+{
+    return ULL2NUM(get_cpu_frequency());
+}
+
+void rp_init_measure_cpu_time()
+{
+    rb_define_const(mProf, "CPU_TIME", INT2NUM(MEASURE_CPU_TIME));
+    rb_define_const(mProf, "CPU_TIME_ENABLED", Qtrue);
+
+    cMeasureCpuTime = rb_define_class_under(mMeasure, "CpuTime", rb_cObject);
+    rb_define_singleton_method(cMeasureCpuTime, "measure", prof_measure_cpu_time, 0);
+    rb_define_singleton_method(cMeasureCpuTime, "frequency", prof_get_cpu_frequency, 0);
+}
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_gc_runs.c b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_gc_runs.c
new file mode 100755
index 0000000..4efb76b
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_gc_runs.c
@@ -0,0 +1,73 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+/* :nodoc: */
+
+#include "ruby_prof.h"
+
+static VALUE cMeasureGcRuns;
+
+#if defined(HAVE_RB_GC_COLLECTIONS)
+  VALUE rb_gc_collections(void);
+#endif
+
+#if defined(HAVE_RB_GC_COUNT)
+  size_t rb_gc_count(void);
+#endif
+
+#if defined(HAVE_RB_GC_HEAP_INFO)
+  VALUE rb_gc_heap_info(void);
+#endif
+
+
+static double
+measure_gc_runs()
+{
+#if defined(HAVE_RB_GC_COLLECTIONS)
+#define MEASURE_GC_RUNS_ENABLED Qtrue
+  return NUM2INT(rb_gc_collections());
+
+#elif defined(HAVE_RB_GC_COUNT)
+#define MEASURE_GC_RUNS_ENABLED Qtrue
+  return rb_gc_count();
+
+#elif defined(HAVE_RB_GC_HEAP_INFO)
+#define MEASURE_GC_RUNS_ENABLED Qtrue
+  VALUE h = rb_gc_heap_info();
+  return NUM2UINT(rb_hash_aref(h, rb_str_new2("num_gc_passes")));
+
+#else
+#define MEASURE_GC_RUNS_ENABLED Qfalse
+  return 0;
+#endif
+}
+
+prof_measurer_t* prof_measurer_gc_runs()
+{
+  prof_measurer_t* measure = ALLOC(prof_measurer_t);
+  measure->measure = measure_gc_runs;
+  return measure;
+}
+
+/* call-seq:
+   measure -> int
+
+Returns the number of GC runs.*/
+static VALUE
+prof_measure_gc_runs(VALUE self)
+{
+#if defined(HAVE_LONG_LONG)
+    return ULL2NUM(measure_gc_runs());
+#else
+    return ULONG2NUM(measure_gc_runs());
+#endif
+}
+
+void rp_init_measure_gc_runs()
+{
+    rb_define_const(mProf, "GC_RUNS", INT2NUM(MEASURE_GC_RUNS));
+    rb_define_const(mProf, "GC_RUNS_ENABLED", MEASURE_GC_RUNS_ENABLED);
+    
+    cMeasureGcRuns = rb_define_class_under(mMeasure, "GcRuns", rb_cObject);
+    rb_define_singleton_method(cMeasureGcRuns, "measure", prof_measure_gc_runs, 0);
+}
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_gc_time.c b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_gc_time.c
new file mode 100755
index 0000000..17968ea
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_gc_time.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+/* :nodoc: */
+
+#include "ruby_prof.h"
+
+static VALUE cMeasureGcTimes;
+
+#if defined(HAVE_RB_GC_TIME)
+  VALUE rb_gc_time();
+#endif
+
+static double
+measure_gc_time()
+{
+#if defined(HAVE_RB_GC_TOTAL_TIME)
+#define MEASURE_GC_TIME_ENABLED Qtrue
+    return rb_gc_total_time();
+
+#elif defined(HAVE_RB_GC_TIME)
+#define MEASURE_GC_TIME_ENABLED Qtrue
+    const double conversion = 1000000.0;
+#if HAVE_LONG_LONG
+    return NUM2LL(rb_gc_time()) / conversion;
+#else
+    return NUM2LONG(rb_gc_time()) / conversion;
+#endif
+
+#else
+#define MEASURE_GC_TIME_ENABLED Qfalse
+    return 0.0;
+#endif
+}
+
+prof_measurer_t* prof_measurer_gc_time()
+{
+  prof_measurer_t* measure = ALLOC(prof_measurer_t);
+  measure->measure = measure_gc_time;
+  return measure;
+}
+
+/* call-seq:
+   measure -> float
+
+Returns the time spent performing GC.*/
+static VALUE
+prof_measure_gc_time(VALUE self)
+{
+    return rb_float_new(measure_gc_time());
+}
+
+void rp_init_measure_gc_time()
+{
+    rb_define_const(mProf, "GC_TIME", INT2NUM(MEASURE_GC_TIME));
+    rb_define_const(mProf, "GC_TIME_ENABLED", MEASURE_GC_TIME_ENABLED);
+
+    cMeasureGcTimes = rb_define_class_under(mMeasure, "GcTime", rb_cObject);
+    rb_define_singleton_method(cMeasureGcTimes, "measure", prof_measure_gc_time, 0);
+}
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_memory.c b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_memory.c
new file mode 100755
index 0000000..f73cfaa
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_memory.c
@@ -0,0 +1,77 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+/* :nodoc: */
+
+#include "ruby_prof.h"
+
+static VALUE cMeasureMemory;
+
+
+#if defined(HAVE_RB_GC_ALLOCATED_SIZE)
+  VALUE rb_gc_allocated_size();
+#endif
+
+#if defined(HAVE_RB_GC_MALLOC_ALLOCATED_SIZE)
+  size_t rb_gc_malloc_allocated_size();
+#endif
+
+#if defined(HAVE_RB_HEAP_TOTAL_MEM)
+  //FIXME: did not find the patch to check prototype, assuming it to return size_t
+  size_t rb_heap_total_mem();
+#endif
+
+static double
+measure_memory()
+{
+#if defined(HAVE_RB_GC_ALLOCATED_SIZE)
+#define MEASURE_MEMORY_ENABLED Qtrue
+#if defined(HAVE_LONG_LONG)
+    return NUM2LL(rb_gc_allocated_size()) / 1024.0;
+#else
+    return NUM2ULONG(rb_gc_allocated_size()) / 1024.0;
+#endif
+
+#elif defined(HAVE_RB_GC_MALLOC_ALLOCATED_SIZE)
+#define MEASURE_MEMORY_ENABLED Qtrue
+    return rb_gc_malloc_allocated_size() / 1024.0;
+
+#elif defined(HAVE_RB_GC_TOTAL_MALLOCED_BYTES)
+#define MEASURE_MEMORY_ENABLED Qtrue
+    return rb_gc_total_malloced_bytes() / 1024.0;
+
+#elif defined(HAVE_RB_HEAP_TOTAL_MEM)
+#define MEASURE_MEMORY_ENABLED Qtrue
+    return rb_heap_total_mem() / 1024.0;
+
+#else
+#define MEASURE_MEMORY_ENABLED Qfalse
+    return 0;
+#endif
+}
+
+prof_measurer_t* prof_measurer_memory()
+{
+  prof_measurer_t* measure = ALLOC(prof_measurer_t);
+  measure->measure = measure_memory;
+  return measure;
+}
+
+/* call-seq:
+   measure_process_time -> float
+
+Returns the process time.*/
+static VALUE
+prof_measure_memory(VALUE self)
+{
+    return rb_float_new(measure_memory());
+}
+
+void rp_init_measure_memory()
+{
+    rb_define_const(mProf, "MEMORY", INT2NUM(MEASURE_MEMORY));
+    rb_define_const(mProf, "MEMORY_ENABLED", MEASURE_MEMORY_ENABLED);
+
+    cMeasureMemory = rb_define_class_under(mMeasure, "Memory", rb_cObject);
+    rb_define_singleton_method(cMeasureMemory, "measure", prof_measure_memory, 0);
+}
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_process_time.c b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_process_time.c
new file mode 100755
index 0000000..c3a1c3f
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_process_time.c
@@ -0,0 +1,71 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+#include "ruby_prof.h"
+#include <time.h>
+
+static VALUE cMeasureProcessTime;
+
+static double
+measure_process_time()
+{
+#if defined(__linux__)
+    struct timespec clock;
+    clock_gettime(CLOCK_PROCESS_CPUTIME_ID , &clock);
+    return clock.tv_sec + (clock.tv_nsec/1000000000.0);
+#elif defined(_win32)
+	FILETIME createTime;
+	FILETIME exitTime;
+	FILETIME sysTime;
+	FILETIME cpuTime;
+
+	ULARGE_INTEGER sysTimeInt;
+	ULARGE_INTEGER cpuTimeInt;
+	ULONGLONG totalTime;
+
+	GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &sysTime, &cpuTime); 
+
+	/* Doing this based on MSFT's recommendation in the FILETIME structure documentation at
+	  http://msdn.microsoft.com/en-us/library/ms724284%28VS.85%29.aspx*/
+
+	sysTimeInt.LowPart = sysTime.dwLowDateTime;
+	sysTimeInt.HighPart = sysTime.dwHighDateTime;
+	cpuTimeInt.LowPart = cpuTime.dwLowDateTime;
+	cpuTimeInt.HighPart = cpuTime.dwHighDateTime;
+
+	totalTime = sysTimeInt.QuadPart + cpuTimeInt.QuadPart;
+
+	// Times are in 100-nanosecond time units.  So instead of 10-9 use 10-7
+	return totalTime / 10000000.0;
+#else
+    return ((double)clock()) / CLOCKS_PER_SEC;
+#endif
+}
+
+/* call-seq:
+   measure_process_time -> float
+
+Returns the process time.*/
+static VALUE
+prof_measure_process_time(VALUE self)
+{
+    return rb_float_new(measure_process_time());
+}
+
+prof_measurer_t* prof_measurer_process_time()
+{
+  prof_measurer_t* measure = ALLOC(prof_measurer_t);
+  measure->measure = measure_process_time;
+  return measure;
+}
+
+
+void rp_init_measure_process_time()
+{
+    rb_define_const(mProf, "CLOCKS_PER_SEC", INT2NUM(CLOCKS_PER_SEC));
+    rb_define_const(mProf, "PROCESS_TIME", INT2NUM(MEASURE_PROCESS_TIME));
+	rb_define_const(mProf, "PROCESS_TIME_ENABLED", Qtrue);
+
+    cMeasureProcessTime = rb_define_class_under(mMeasure, "ProcessTime", rb_cObject);
+    rb_define_singleton_method(cMeasureProcessTime, "measure", prof_measure_process_time, 0);
+}
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_wall_time.c b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_wall_time.c
new file mode 100755
index 0000000..f521c03
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_measure_wall_time.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+/* :nodoc: */
+#include "ruby_prof.h"
+#if HAVE_GETTIMEOFDAY && !defined(_WIN32)
+#include <sys/time.h>
+#endif
+
+static VALUE cMeasureWallTime;
+
+static double
+measure_wall_time()
+{
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec + (tv.tv_usec/1000000.0);
+}
+
+prof_measurer_t* prof_measurer_wall_time()
+{
+  prof_measurer_t* measure = ALLOC(prof_measurer_t);
+  measure->measure = measure_wall_time;
+  return measure;
+}
+
+/* Document-method: prof_measure_wall_time
+   call-seq:
+     measure_wall_time -> float
+
+Returns the wall time.*/
+static VALUE
+prof_measure_wall_time(VALUE self)
+{
+    return rb_float_new(measure_wall_time());
+}
+
+void rp_init_measure_wall_time()
+{
+    rb_define_const(mProf, "WALL_TIME", INT2NUM(MEASURE_WALL_TIME));
+    rb_define_const(mProf, "WALL_TIME_ENABLED", Qtrue);
+
+    cMeasureWallTime = rb_define_class_under(mMeasure, "WallTime", rb_cObject);
+    rb_define_singleton_method(cMeasureWallTime, "measure", prof_measure_wall_time, 0);
+}
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_method.c b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_method.c
new file mode 100755
index 0000000..5fa5aed
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_method.c
@@ -0,0 +1,411 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+#include "ruby_prof.h"
+
+VALUE cMethodInfo;
+
+/* ================  Helper Functions  =================*/
+static VALUE
+figure_singleton_name(VALUE klass)
+{
+    VALUE result = Qnil;
+
+    /* We have come across a singleton object. First
+       figure out what it is attached to.*/
+    VALUE attached = rb_iv_get(klass, "__attached__");
+
+    /* Is this a singleton class acting as a metaclass? */
+    if (BUILTIN_TYPE(attached) == T_CLASS)
+    {
+        result = rb_str_new2("<Class::");
+        rb_str_append(result, rb_inspect(attached));
+        rb_str_cat2(result, ">");
+    }
+
+    /* Is this for singleton methods on a module? */
+    else if (BUILTIN_TYPE(attached) == T_MODULE)
+    {
+        result = rb_str_new2("<Module::");
+        rb_str_append(result, rb_inspect(attached));
+        rb_str_cat2(result, ">");
+    }
+
+    /* Is this for singleton methods on an object? */
+    else if (BUILTIN_TYPE(attached) == T_OBJECT)
+    {
+        /* Make sure to get the super class so that we don't
+           mistakenly grab a T_ICLASS which would lead to
+           unknown method errors. */
+        VALUE super = rb_class_superclass(klass);
+        result = rb_str_new2("<Object::");
+        rb_str_append(result, rb_inspect(super));
+        rb_str_cat2(result, ">");
+    }
+
+    /* Ok, this could be other things like an array made put onto
+       a singleton object (yeah, it happens, see the singleton
+       objects test case). */
+    else
+    {
+        result = rb_inspect(klass);
+    }
+
+    return result;
+}
+
+static VALUE
+klass_name(VALUE klass)
+{
+    VALUE result = Qnil;
+
+    if (klass == 0 || klass == Qnil)
+    {
+        result = rb_str_new2("Global");
+    }
+    else if (BUILTIN_TYPE(klass) == T_MODULE)
+    {
+        result = rb_inspect(klass);
+    }
+    else if (BUILTIN_TYPE(klass) == T_CLASS && FL_TEST(klass, FL_SINGLETON))
+    {
+        result = figure_singleton_name(klass);
+    }
+    else if (BUILTIN_TYPE(klass) == T_CLASS)
+    {
+        result = rb_inspect(klass);
+    }
+    else
+    {
+        /* Should never happen. */
+        result = rb_str_new2("Unknown");
+    }
+
+    return result;
+}
+
+static VALUE
+method_name(ID mid)
+{
+    VALUE result;
+
+    if (mid == 0)
+        result = rb_str_new2("[No method]");
+#ifdef ID_ALLOCATOR
+    else if (mid == ID_ALLOCATOR)
+        result = rb_str_new2("allocate");
+#endif
+    else
+        result = rb_String(ID2SYM(mid));
+
+    return result;
+}
+
+static VALUE
+full_name(VALUE klass, ID mid)
+{
+    VALUE result = rb_str_dup(klass_name(klass));
+    rb_str_cat2(result, "#");
+    rb_str_append(result, method_name(mid));
+
+    return result;
+}
+
+void
+method_key(prof_method_key_t* key, VALUE klass, ID mid)
+{
+    /* Is this an include for a module?  If so get the actual
+        module class since we want to combine all profiling
+        results for that module. */
+    if (klass != 0)
+        klass = (BUILTIN_TYPE(klass) == T_ICLASS ? RBASIC(klass)->klass : klass);
+
+    key->klass = klass;
+    key->mid = mid;
+    key->key = (klass << 4) + (mid << 2);
+}
+
+/* ================  prof_method_t   =================*/
+prof_method_t*
+prof_method_create(VALUE klass, ID mid, const char* source_file, int line)
+{
+    prof_method_t *result = ALLOC(prof_method_t);
+    result->object = Qnil;
+    result->call_infos = prof_call_infos_create();
+
+    result->key = ALLOC(prof_method_key_t);
+    method_key(result->key, klass, mid);
+
+    //result->call_info_table = call_info_table_create();
+
+    if (source_file != NULL)
+    {
+      size_t len = strlen(source_file) + 1;
+      char *buffer = ALLOC_N(char, len);
+
+      MEMCPY(buffer, source_file, char, len);
+      result->source_file = buffer;
+    }
+    else
+    {
+      result->source_file = source_file;
+    }
+    result->line = line;
+
+    return result;
+}
+
+/* The underlying c structures are freed when the parent profile is freed.  
+   However, on shutdown the Ruby GC frees objects in any will-nilly order.
+   That means the ruby thread object wrapping the c thread struct may
+   be freed before the parent profile.  Thus we add in a free function
+   for the garbage collector so that if it does get called will nil 
+   out our Ruby object reference.*/
+static void
+prof_method_ruby_gc_free(prof_method_t* method)
+{
+	/* Has this thread object been accessed by Ruby?  If
+	   yes clean it up so to avoid a segmentation fault. */
+	if (method->object != Qnil)
+	{
+		RDATA(method->object)->data = NULL;
+		RDATA(method->object)->dfree = NULL;
+		RDATA(method->object)->dmark = NULL;
+    }
+	method->object = Qnil;
+}
+
+static void
+prof_method_free(prof_method_t* method)
+{
+	prof_method_ruby_gc_free(method);
+	prof_call_infos_free(method->call_infos);
+	xfree(method->call_infos);
+
+	xfree(method->key);
+	method->key = NULL;
+
+	xfree(method);
+}
+
+void
+prof_method_mark(prof_method_t *method)
+{
+	if (method->object)
+		rb_gc_mark(method->object);
+
+	prof_call_infos_mark(method->call_infos);
+}
+
+VALUE
+prof_method_wrap(prof_method_t *result)
+{
+  if (result->object == Qnil)
+  {
+    result->object = Data_Wrap_Struct(cMethodInfo, prof_method_mark, prof_method_ruby_gc_free, result);
+  }
+  return result->object;
+}
+
+static prof_method_t *
+get_prof_method(VALUE self)
+{
+    /* Can't use Data_Get_Struct because that triggers the event hook
+       ending up in endless recursion. */
+	prof_method_t* result = DATA_PTR(self);
+
+	if (!result)
+	    rb_raise(rb_eRuntimeError, "This RubyProf::MethodInfo instance has already been freed, likely because its profile has been freed.");
+
+   return result;
+}
+
+/* ================  Method Table   =================*/
+int
+method_table_cmp(prof_method_key_t *key1, prof_method_key_t *key2)
+{
+    return (key1->klass != key2->klass) || (key1->mid != key2->mid);
+}
+
+st_index_t
+method_table_hash(prof_method_key_t *key)
+{
+    return key->key;
+}
+
+struct st_hash_type type_method_hash = {
+    method_table_cmp,
+    method_table_hash
+};
+
+st_table *
+method_table_create()
+{
+  return st_init_table(&type_method_hash);
+}
+
+static int
+method_table_free_iterator(st_data_t key, st_data_t value, st_data_t dummy)
+{
+    prof_method_free((prof_method_t*)value);
+    return ST_CONTINUE;
+}
+
+void
+method_table_free(st_table *table)
+{
+    st_foreach(table, method_table_free_iterator, 0);
+    st_free_table(table);
+}
+
+
+size_t
+method_table_insert(st_table *table, const prof_method_key_t *key, prof_method_t *val)
+{
+  return st_insert(table, (st_data_t) key, (st_data_t) val);
+}
+
+prof_method_t *
+method_table_lookup(st_table *table, const prof_method_key_t* key)
+{
+    st_data_t val;
+    if (st_lookup(table, (st_data_t)key, &val))
+    {
+      return (prof_method_t *) val;
+    }
+    else
+    {
+      return NULL;
+    }
+}
+
+/* ================  Method Info   =================*/
+/* Document-class: RubyProf::MethodInfo
+The RubyProf::MethodInfo class stores profiling data for a method.
+One instance of the RubyProf::MethodInfo class is created per method
+called per thread.  Thus, if a method is called in two different
+thread then there will be two RubyProf::MethodInfo objects
+created.  RubyProf::MethodInfo objects can be accessed via
+the RubyProf::Result object.
+*/
+
+/* call-seq:
+   line_no -> int
+
+   returns the line number of the method */
+static VALUE
+prof_method_line(VALUE self)
+{
+    return rb_int_new(get_prof_method(self)->line);
+}
+
+/* call-seq:
+   source_file => string
+
+return the source file of the method
+*/
+static VALUE prof_method_source_file(VALUE self)
+{
+    const char* sf = get_prof_method(self)->source_file;
+    if(!sf)
+    {
+      return rb_str_new2("ruby_runtime");
+    }
+    else
+    {
+      return rb_str_new2(sf);
+    }
+}
+
+
+/* call-seq:
+   method_class -> klass
+
+Returns the Ruby klass that owns this method. */
+static VALUE
+prof_method_klass(VALUE self)
+{
+    prof_method_t *result = get_prof_method(self);
+    return result->key->klass;
+}
+
+/* call-seq:
+   method_id -> ID
+
+Returns the id of this method. */
+static VALUE
+prof_method_id(VALUE self)
+{
+    prof_method_t *result = get_prof_method(self);
+    return ID2SYM(result->key->mid);
+}
+
+/* call-seq:
+   klass_name -> string
+
+Returns the name of this method's class.  Singleton classes
+will have the form <Object::Object>. */
+
+static VALUE
+prof_klass_name(VALUE self)
+{
+    prof_method_t *method = get_prof_method(self);
+    return klass_name(method->key->klass);
+}
+
+/* call-seq:
+   method_name -> string
+
+Returns the name of this method in the format Object#method.  Singletons
+methods will be returned in the format <Object::Object>#method.*/
+
+static VALUE
+prof_method_name(VALUE self)
+{
+    prof_method_t *method = get_prof_method(self);
+    return method_name(method->key->mid);
+}
+
+/* call-seq:
+   full_name -> string
+
+Returns the full name of this method in the format Object#method.*/
+
+static VALUE
+prof_full_name(VALUE self)
+{
+    prof_method_t *method = get_prof_method(self);
+    return full_name(method->key->klass, method->key->mid);
+}
+
+/* call-seq:
+   call_infos -> Array of call_info
+
+Returns an array of call info objects that contain profiling information
+about the current method.*/
+static VALUE
+prof_method_call_infos(VALUE self)
+{
+    prof_method_t *method = get_prof_method(self);
+	if (method->call_infos->object == Qnil)
+	{
+		method->call_infos->object = prof_call_infos_wrap(method->call_infos);
+	}
+	return method->call_infos->object;
+}
+
+void rp_init_method_info()
+{
+    /* MethodInfo */
+    cMethodInfo = rb_define_class_under(mProf, "MethodInfo", rb_cObject);
+    rb_undef_method(CLASS_OF(cMethodInfo), "new");
+
+    rb_define_method(cMethodInfo, "klass", prof_method_klass, 0);
+    rb_define_method(cMethodInfo, "klass_name", prof_klass_name, 0);
+    rb_define_method(cMethodInfo, "method_name", prof_method_name, 0);
+    rb_define_method(cMethodInfo, "full_name", prof_full_name, 0);
+    rb_define_method(cMethodInfo, "method_id", prof_method_id, 0);
+    rb_define_method(cMethodInfo, "source_file", prof_method_source_file,0);
+    rb_define_method(cMethodInfo, "line", prof_method_line, 0);
+    rb_define_method(cMethodInfo, "call_infos", prof_method_call_infos, 0);
+}
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_method.h b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_method.h
new file mode 100755
index 0000000..4f3acf1
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_method.h
@@ -0,0 +1,52 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RP_METHOD_INFO__
+#define __RP_METHOD_INFO__
+
+#include <ruby.h>
+
+extern VALUE cMethodInfo;
+
+/* A key used to identify each method */
+typedef struct
+{
+    VALUE klass;                            /* The method's class. */
+    ID mid;                                 /* The method id. */
+    st_index_t key;                         /* Cache calculated key */
+} prof_method_key_t;
+
+
+/* Forward declaration, see rp_call_info.h */
+struct prof_call_infos_t;
+
+/* Profiling information for each method. */
+typedef struct 
+{
+    prof_method_key_t *key;                 /* Method key */
+    const char *source_file;                /* The method's source file */
+    int line;                               /* The method's line number. */
+    struct prof_call_infos_t *call_infos;   /* Call info objects for this method */
+    VALUE object;                           /* Cached ruby object */
+} prof_method_t;
+
+void rp_init_method_info(void);
+
+void method_key(prof_method_key_t* key, VALUE klass, ID mid);
+
+st_table * method_table_create();
+prof_method_t * method_table_lookup(st_table *table, const prof_method_key_t* key);
+size_t method_table_insert(st_table *table, const prof_method_key_t *key, prof_method_t *val);
+void method_table_free(st_table *table);
+
+prof_method_t* prof_method_create(VALUE klass, ID mid, const char* source_file, int line);
+VALUE prof_method_wrap(prof_method_t *result);
+void prof_method_mark(prof_method_t *method);
+
+/* Setup infrastructure to use method keys as hash comparisons */
+int method_table_cmp(prof_method_key_t *key1, prof_method_key_t *key2);
+st_index_t method_table_hash(prof_method_key_t *key);
+
+extern struct st_hash_type type_method_hash;
+
+#endif
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_stack.c b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_stack.c
new file mode 100755
index 0000000..777b4c5
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_stack.c
@@ -0,0 +1,128 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+#include "rp_stack.h"
+
+#define INITIAL_STACK_SIZE 8
+
+void
+prof_frame_pause(prof_frame_t *frame, double current_measurement)
+{
+    if (frame && prof_frame_is_unpaused(frame))
+        frame->pause_time = current_measurement;
+}
+
+void
+prof_frame_unpause(prof_frame_t *frame, double current_measurement)
+{
+    if (frame && prof_frame_is_paused(frame)) {
+        frame->dead_time += (current_measurement - frame->pause_time);
+        frame->pause_time = -1;
+    }
+}
+
+
+/* Creates a stack of prof_frame_t to keep track
+   of timings for active methods. */
+prof_stack_t *
+prof_stack_create()
+{
+    prof_stack_t *stack = ALLOC(prof_stack_t);
+    stack->start = ALLOC_N(prof_frame_t, INITIAL_STACK_SIZE);
+    stack->ptr = stack->start;
+    stack->end = stack->start + INITIAL_STACK_SIZE;
+
+    return stack;
+}
+
+void
+prof_stack_free(prof_stack_t *stack)
+{
+    xfree(stack->start);
+    xfree(stack);
+}
+
+prof_frame_t *
+prof_stack_push(prof_stack_t *stack, double measurement)
+{
+  prof_frame_t* result = NULL;
+
+  /* Is there space on the stack?  If not, double
+     its size. */
+  if (stack->ptr == stack->end  )   
+  {
+    size_t len = stack->ptr - stack->start;
+    size_t new_capacity = (stack->end - stack->start) * 2;
+    REALLOC_N(stack->start, prof_frame_t, new_capacity);
+    /* Memory just got moved, reset pointers */
+    stack->ptr = stack->start + len;
+    stack->end = stack->start + new_capacity;
+  }
+
+  // Setup returned stack pointer to be valid
+  result = stack->ptr;
+  result->child_time = 0;
+  result->switch_time = 0;
+  result->wait_time = 0;
+  result->dead_time = 0;
+  result->depth = (int)(stack->ptr - stack->start); // shortening of 64 bit into 32
+  result->start_time = measurement;
+
+  // Increment the stack ptr for next time
+  stack->ptr++;
+
+  // Return the result
+  return result;
+}
+
+prof_frame_t *
+prof_stack_pop(prof_stack_t *stack, double measurement)
+{
+  prof_frame_t *frame = NULL;
+  prof_frame_t* parent_frame = NULL;
+  prof_call_info_t *call_info;
+
+  double total_time;
+  double self_time;
+
+  /* Frame can be null.  This can happen if RubProf.start is called from
+     a method that exits.  And it can happen if an exception is raised
+     in code that is being profiled and the stack unwinds (RubyProf is
+     not notified of that by the ruby runtime. */
+  if (stack->ptr == stack->start)
+    return NULL;
+  
+  frame = --stack->ptr;
+
+  /* Calculate the total time this method took */
+  prof_frame_unpause(frame, measurement);
+  total_time = measurement - frame->start_time - frame->dead_time;
+  self_time = total_time - frame->child_time - frame->wait_time;
+
+  /* Update information about the current method */
+  call_info = frame->call_info;
+  call_info->called++;
+  call_info->total_time += total_time;
+  call_info->self_time += self_time;
+  call_info->wait_time += frame->wait_time;
+
+  parent_frame = prof_stack_peek(stack);
+  if (parent_frame)
+  {
+      parent_frame->child_time += total_time;
+      parent_frame->dead_time += frame->dead_time;
+
+      call_info->line = parent_frame->line;
+  }
+
+  return frame;
+}
+
+prof_frame_t *
+prof_stack_peek(prof_stack_t *stack)
+{
+    if (stack->ptr == stack->start)
+      return NULL;
+    else
+      return stack->ptr - 1;
+}
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_stack.h b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_stack.h
new file mode 100755
index 0000000..b18c3eb
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_stack.h
@@ -0,0 +1,51 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RP_STACK__
+#define __RP_STACK__
+
+#include <ruby.h>
+
+#include "rp_measure.h"
+#include "rp_call_info.h"
+
+
+/* Temporary object that maintains profiling information
+   for active methods.  They are created and destroyed
+   as the program moves up and down its stack. */
+typedef struct 
+{
+    /* Caching prof_method_t values significantly
+       increases performance. */
+    prof_call_info_t *call_info;
+    double start_time;
+    double switch_time;  /* Time at switch to different thread */
+    double wait_time;
+    double child_time;
+    double pause_time; // Time pause() was initiated
+    double dead_time; // Time to ignore (i.e. total amount of time between pause/resume blocks)
+    int depth;
+    unsigned int line;
+} prof_frame_t;
+
+#define prof_frame_is_paused(f) (f->pause_time >= 0)
+#define prof_frame_is_unpaused(f) (f->pause_time < 0)
+void prof_frame_pause(prof_frame_t*, double current_measurement);
+void prof_frame_unpause(prof_frame_t*, double current_measurement);
+
+
+/* Current stack of active methods.*/
+typedef struct 
+{
+    prof_frame_t *start;
+    prof_frame_t *end;
+    prof_frame_t *ptr;
+} prof_stack_t;
+
+prof_stack_t * prof_stack_create();
+void prof_stack_free(prof_stack_t *stack);
+prof_frame_t * prof_stack_push(prof_stack_t *stack, double measurement);
+prof_frame_t * prof_stack_pop(prof_stack_t *stack, double measurement);
+prof_frame_t * prof_stack_peek(prof_stack_t *stack);
+
+#endif //__RP_STACK__
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_thread.c b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_thread.c
new file mode 100755
index 0000000..f742d39
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_thread.c
@@ -0,0 +1,268 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+#include "ruby_prof.h"
+
+VALUE cRpThread;
+
+/* ======   thread_data_t  ====== */
+thread_data_t*
+thread_data_create()
+{
+    thread_data_t* result = ALLOC(thread_data_t);
+    result->stack = prof_stack_create();
+    result->method_table = method_table_create();
+	result->object = Qnil;
+	result->methods = Qnil;
+    return result;
+}
+
+/* The underlying c structures are freed when the parent profile is freed.  
+   However, on shutdown the Ruby GC frees objects in any will-nilly order.
+   That means the ruby thread object wrapping the c thread struct may
+   be freed before the parent profile.  Thus we add in a free function
+   for the garbage collector so that if it does get called will nil 
+   out our Ruby object reference.*/
+static void
+thread_data_ruby_gc_free(thread_data_t* thread_data)
+{
+	/* Has this thread object been accessed by Ruby?  If
+	  yes clean it up so to avoid a segmentation fault. */
+	if (thread_data->object != Qnil)
+	{
+		RDATA(thread_data->object)->data = NULL;
+		RDATA(thread_data->object)->dfree = NULL;
+		RDATA(thread_data->object)->dmark = NULL;
+    }
+	thread_data->object = Qnil;
+}
+
+static void
+thread_data_free(thread_data_t* thread_data)
+{
+	thread_data_ruby_gc_free(thread_data);
+    method_table_free(thread_data->method_table);
+    prof_stack_free(thread_data->stack);
+
+    thread_data->thread_id = Qnil;
+
+	xfree(thread_data);
+}
+
+static int
+mark_methods(st_data_t key, st_data_t value, st_data_t result)
+{
+    prof_method_t *method = (prof_method_t *) value;
+    prof_method_mark(method);
+    return ST_CONTINUE;
+}
+
+void
+prof_thread_mark(thread_data_t *thread)
+{
+	if (thread->object != Qnil)
+		rb_gc_mark(thread->object);
+	
+	if (thread->methods != Qnil)
+		rb_gc_mark(thread->methods);
+
+	if (thread->thread_id != Qnil)
+		rb_gc_mark(thread->thread_id);
+
+	if (thread->fiber_id != Qnil)
+		rb_gc_mark(thread->fiber_id);
+
+	st_foreach(thread->method_table, mark_methods, 0);
+}
+
+VALUE
+prof_thread_wrap(thread_data_t *thread)
+{
+  if (thread->object == Qnil)
+  {
+    thread->object = Data_Wrap_Struct(cRpThread, prof_thread_mark, thread_data_ruby_gc_free, thread);
+  }
+  return thread->object;
+}
+
+static thread_data_t*
+prof_get_thread(VALUE self)
+{
+    /* Can't use Data_Get_Struct because that triggers the event hook
+       ending up in endless recursion. */
+	thread_data_t* result = DATA_PTR(self);
+	if (!result)
+	    rb_raise(rb_eRuntimeError, "This RubyProf::Thread instance has already been freed, likely because its profile has been freed.");
+
+   return result;
+}
+
+/* ======   Thread Table  ====== */
+/* The thread table is hash keyed on ruby thread_id that stores instances
+   of thread_data_t. */
+
+st_table *
+threads_table_create()
+{
+    return st_init_numtable();
+}
+
+static int
+thread_table_free_iterator(st_data_t key, st_data_t value, st_data_t dummy)
+{
+    thread_data_free((thread_data_t*)value);
+    return ST_CONTINUE;
+}
+
+void
+threads_table_free(st_table *table)
+{
+    st_foreach(table, thread_table_free_iterator, 0);
+    st_free_table(table);
+}
+
+size_t
+threads_table_insert(prof_profile_t* profile, VALUE fiber, thread_data_t *thread_data)
+{
+    /* Its too slow to key on the real thread id so just typecast thread instead. */
+    return st_insert(profile->threads_tbl, (st_data_t) fiber, (st_data_t) thread_data);
+}
+
+thread_data_t *
+threads_table_lookup(prof_profile_t* profile, VALUE thread_id, VALUE fiber_id)
+{
+    thread_data_t* result;
+    st_data_t val;
+
+    /* Its too slow to key on the real thread id so just typecast thread instead. */
+    if (st_lookup(profile->threads_tbl, (st_data_t) fiber_id, &val))
+    {
+      result = (thread_data_t *) val;
+    }
+    else
+    {
+        result = thread_data_create();
+        result->thread_id = thread_id;
+        result->fiber_id = fiber_id;
+
+        /* Insert the table */
+        threads_table_insert(profile, fiber_id, result);
+    }
+    return result;
+}
+
+thread_data_t *
+switch_thread(void* prof, VALUE thread_id, VALUE fiber_id)
+{
+    prof_profile_t* profile = (prof_profile_t*)prof;
+    double measurement = profile->measurer->measure();
+
+    /* Get new thread information. */
+    thread_data_t *thread_data = threads_table_lookup(profile, thread_id, fiber_id);
+
+    /* Get current frame for this thread */
+    prof_frame_t *frame = prof_stack_peek(thread_data->stack);
+
+    /* Update the time this thread waited for another thread */
+    if (frame)
+    {
+        frame->wait_time += measurement - frame->switch_time;
+        frame->switch_time = measurement;
+    }
+
+    /* Save on the last thread the time of the context switch
+       and reset this thread's last context switch to 0.*/
+    if (profile->last_thread_data)
+    {
+       prof_frame_t *last_frame = prof_stack_peek(profile->last_thread_data->stack);
+       if (last_frame)
+         last_frame->switch_time = measurement;
+    }
+
+    profile->last_thread_data = thread_data;
+    return thread_data;
+}
+
+int pause_thread(st_data_t key, st_data_t value, st_data_t data) 
+{
+    thread_data_t* thread_data = (thread_data_t *) value;
+	prof_profile_t* profile = (prof_profile_t*)data;
+
+    prof_frame_t* frame = prof_stack_peek(thread_data->stack);
+	prof_frame_pause(frame, profile->measurement_at_pause_resume);
+
+    return ST_CONTINUE;
+}
+
+int unpause_thread(st_data_t key, st_data_t value, st_data_t data) 
+{
+    thread_data_t* thread_data = (thread_data_t *) value;
+	prof_profile_t* profile = (prof_profile_t*)data;
+
+    prof_frame_t* frame = prof_stack_peek(thread_data->stack);
+	prof_frame_unpause(frame, profile->measurement_at_pause_resume);
+
+    return ST_CONTINUE;
+}
+
+static int
+collect_methods(st_data_t key, st_data_t value, st_data_t result)
+{
+    /* Called for each method stored in a thread's method table.
+       We want to store the method info information into an array.*/
+    VALUE methods = (VALUE) result;
+    prof_method_t *method = (prof_method_t *) value;
+    rb_ary_push(methods, prof_method_wrap(method));
+
+    return ST_CONTINUE;
+}
+
+
+/* call-seq:
+   id -> number
+
+Returns the id of this thread. */
+static VALUE
+prof_thread_id(VALUE self)
+{
+    thread_data_t* thread = prof_get_thread(self);
+	return thread->thread_id;
+}
+
+/* call-seq:
+   fiber_id -> number
+
+Returns the fiber id of this thread. */
+static VALUE
+prof_fiber_id(VALUE self)
+{
+    thread_data_t* thread = prof_get_thread(self);
+	return thread->fiber_id;
+}
+
+/* call-seq:
+   methods -> Array of MethodInfo
+
+Returns an array of methods that were called from this
+thread during program execution. */
+static VALUE
+prof_thread_methods(VALUE self)
+{
+    thread_data_t* thread = prof_get_thread(self);
+	if (thread->methods == Qnil)
+	{
+		thread->methods = rb_ary_new();
+	    st_foreach(thread->method_table, collect_methods, thread->methods);
+	}
+	return thread->methods;
+}
+
+void rp_init_thread()
+{
+    cRpThread = rb_define_class_under(mProf, "Thread", rb_cObject);
+    rb_undef_method(CLASS_OF(cRpThread), "new");
+
+    rb_define_method(cRpThread, "id", prof_thread_id, 0);
+    rb_define_method(cRpThread, "fiber_id", prof_fiber_id, 0);
+    rb_define_method(cRpThread, "methods", prof_thread_methods, 0);
+}
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_thread.h b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_thread.h
new file mode 100755
index 0000000..11a8a75
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/rp_thread.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RP_THREAD__
+#define __RP_THREAD__
+
+/* Profiling information for a thread. */
+typedef struct
+{
+    VALUE object;                     /* Cache to wrapped object */
+    VALUE methods;                    /* Array of RubyProf::MethodInfo */
+    VALUE thread_id;                  /* Thread id */
+    VALUE fiber_id;                   /* Fiber id */
+    st_table* method_table;           /* Methods called in the thread */
+    prof_stack_t* stack;              /* Stack of frames */
+} thread_data_t;
+
+void rp_init_thread();
+st_table * threads_table_create();
+thread_data_t* switch_thread(void* prof, VALUE thread_id, VALUE fiber_id);
+void threads_table_free(st_table *table);
+VALUE prof_thread_wrap(thread_data_t *thread);
+void prof_thread_mark(thread_data_t *thread);
+int pause_thread(st_data_t key, st_data_t value, st_data_t data);
+int unpause_thread(st_data_t key, st_data_t value, st_data_t data);
+
+#endif //__RP_THREAD__
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/ruby_prof.c b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/ruby_prof.c
new file mode 100755
index 0000000..ce3be3e
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/ruby_prof.c
@@ -0,0 +1,615 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+/* ruby-prof tracks the time spent executing every method in ruby programming.
+   The main players are:
+
+     profile_t         - This represents 1 profile.
+     thread_data_t     - Stores data about a single thread.
+     prof_stack_t      - The method call stack in a particular thread
+     prof_method_t     - Profiling information about each method
+     prof_call_info_t  - Keeps track a method's callers and callees.
+
+  The final result is an instance of a profile object which has a hash table of
+  thread_data_t, keyed on the thread id.  Each thread in turn has a hash table
+  of prof_method_t, keyed on the method id.  A hash table is used for quick 
+  look up when doing a profile.  However, it is exposed to Ruby as an array.
+
+  Each prof_method_t has two hash tables, parent and children, of prof_call_info_t.
+  These objects keep track of a method's callers (who called the method) and its
+  callees (who the method called).  These are keyed the method id, but once again,
+  are exposed to Ruby as arrays.  Each prof_call_into_t maintains a pointer to the
+  caller or callee method, thereby making it easy to navigate through the call
+  hierarchy in ruby - which is very helpful for creating call graphs.
+*/
+
+#include "ruby_prof.h"
+#include <assert.h>
+
+VALUE mProf;
+VALUE cProfile;
+
+static prof_profile_t*
+prof_get_profile(VALUE self)
+{
+    /* Can't use Data_Get_Struct because that triggers the event hook
+       ending up in endless recursion. */
+    return (prof_profile_t*)RDATA(self)->data;
+}
+
+/* support tracing ruby events from ruby-prof. useful for getting at
+   what actually happens inside the ruby interpreter (and ruby-prof).
+   set environment variable RUBY_PROF_TRACE to filename you want to
+   find the trace in.
+ */
+static FILE* trace_file = NULL;
+
+/* Copied from thread.c (1.9.3) */
+static const char *
+get_event_name(rb_event_flag_t event)
+{
+  switch (event) {
+  case RUBY_EVENT_LINE:
+    return "line";
+  case RUBY_EVENT_CLASS:
+    return "class";
+  case RUBY_EVENT_END:
+    return "end";
+  case RUBY_EVENT_CALL:
+    return "call";
+  case RUBY_EVENT_RETURN:
+    return "return";
+  case RUBY_EVENT_C_CALL:
+    return "c-call";
+  case RUBY_EVENT_C_RETURN:
+    return "c-return";
+  case RUBY_EVENT_RAISE:
+    return "raise";
+  default:
+    return "unknown";
+  }
+}
+
+static prof_method_t*
+create_method(rb_event_flag_t event, VALUE klass, ID mid, const char* source_file, int line)
+{
+    /* Line numbers are not accurate for c method calls */
+    if (event == RUBY_EVENT_C_CALL)
+    {
+		line = 0;
+		source_file = NULL;
+    }
+
+    return prof_method_create(klass, mid, source_file, line);
+}
+
+
+static prof_method_t*
+get_method(rb_event_flag_t event, VALUE klass, ID mid, thread_data_t* thread_data)
+{
+    prof_method_key_t key;
+    prof_method_t *method = NULL;
+
+    method_key(&key, klass, mid);
+    method = method_table_lookup(thread_data->method_table, &key);
+
+    if (!method)
+    {
+ 	  const char* source_file = rb_sourcefile();
+      int line = rb_sourceline();
+
+	  method = create_method(event, klass, mid, source_file, line);
+      method_table_insert(thread_data->method_table, method->key, method);
+    }
+    return method;
+}
+
+static int
+pop_frames(st_data_t key, st_data_t value, st_data_t data)
+{
+    VALUE fiber_id = (VALUE)key;
+    thread_data_t* thread_data = (thread_data_t *) value;
+    prof_profile_t* profile = (prof_profile_t*) data;
+	double measurement = profile->measurer->measure();
+
+    if (!profile->last_thread_data || profile->last_thread_data->fiber_id != fiber_id)
+      thread_data = switch_thread(profile, Qnil, fiber_id);
+    else
+      thread_data = profile->last_thread_data;
+
+    while (prof_stack_pop(thread_data->stack, measurement))
+    {
+    }
+
+    return ST_CONTINUE;
+}
+
+static void
+prof_pop_threads(prof_profile_t* profile)
+{
+    st_foreach(profile->threads_tbl, pop_frames, (st_data_t) profile);
+}
+
+/* ===========  Profiling ================= */
+static void
+prof_trace(prof_profile_t* profile, rb_event_flag_t event, ID mid, VALUE klass, double measurement)
+{
+    static VALUE last_fiber_id = Qnil;
+
+    VALUE thread = rb_thread_current();
+    VALUE thread_id = rb_obj_id(thread);
+    VALUE fiber = rb_fiber_current();
+    VALUE fiber_id = rb_obj_id(fiber);
+    const char* class_name = NULL;
+    const char* method_name = rb_id2name(mid);
+    const char* source_file = rb_sourcefile();
+    unsigned int source_line = rb_sourceline();
+
+    const char* event_name = get_event_name(event);
+
+    if (klass != 0)
+        klass = (BUILTIN_TYPE(klass) == T_ICLASS ? RBASIC(klass)->klass : klass);
+
+    class_name = rb_class2name(klass);
+
+    if (last_fiber_id != fiber_id)
+    {
+        fprintf(trace_file, "\n");
+    }
+
+    fprintf(trace_file, "%2lu:%2lu:%2ums %-8s %s:%2d  %s#%s\n",
+            (unsigned long) thread_id, (unsigned long) fiber_id, (unsigned int) measurement*1000,
+            event_name, source_file, source_line, class_name, method_name);
+    fflush(trace_file);
+    last_fiber_id = fiber_id;
+}
+
+static void
+prof_event_hook(rb_event_flag_t event, VALUE data, VALUE self, ID mid, VALUE klass)
+{
+    prof_profile_t* profile = prof_get_profile(data);
+    VALUE thread = Qnil;
+    VALUE thread_id = Qnil;
+    VALUE fiber = Qnil;
+    VALUE fiber_id = Qnil;
+    thread_data_t* thread_data = NULL;
+    prof_frame_t *frame = NULL;
+    double measurement;
+
+    /* if we don't have a valid method id, try to retrieve one */
+    if (mid == 0) {
+        rb_frame_method_id_and_class(&mid, &klass);
+    }
+
+    /* Get current measurement */
+    measurement = profile->measurer->measure();
+
+    /* Special case - skip any methods from the mProf
+       module or cProfile class since they clutter
+       the results but aren't important to them results. */
+    if (self == mProf || klass == cProfile)
+		return;
+
+    if (trace_file != NULL)
+    {
+        prof_trace(profile, event, mid, klass, measurement);
+    }
+
+    /* Get the current thread and fiber information. */
+    thread = rb_thread_current();
+    thread_id = rb_obj_id(thread);
+    fiber = rb_fiber_current();
+    fiber_id = rb_obj_id(fiber);
+
+    if (st_lookup(profile->exclude_threads_tbl, (st_data_t) thread_id, 0))
+    {
+      return;
+    }
+
+    /* Was there a context switch? */
+    if (!profile->last_thread_data || profile->last_thread_data->fiber_id != fiber_id)
+      thread_data = switch_thread(profile, thread_id, fiber_id);
+    else
+      thread_data = profile->last_thread_data;
+
+    /* Get the current frame for the current thread. */
+    frame = prof_stack_peek(thread_data->stack);
+
+    switch (event) {
+    case RUBY_EVENT_LINE:
+    {
+      /* Keep track of the current line number in this method.  When
+         a new method is called, we know what line number it was
+         called from. */
+
+      if (frame)
+      {
+        frame->line = rb_sourceline();
+        break;
+      }
+
+      /* If we get here there was no frame, which means this is
+         the first method seen for this thread, so fall through
+         to below to create it. */
+    }
+    case RUBY_EVENT_CALL:
+    case RUBY_EVENT_C_CALL:
+    {
+        prof_call_info_t *call_info = NULL;
+        prof_method_t *method = NULL;
+
+        method = get_method(event, klass, mid, thread_data);
+
+        if (!frame)
+        {
+          call_info = prof_call_info_create(method, NULL);
+          prof_add_call_info(method->call_infos, call_info);
+        }
+        else
+        {
+          call_info = call_info_table_lookup(frame->call_info->call_infos, method->key);
+
+          if (!call_info)
+          {
+            /* This call info does not yet exist.  So create it, then add
+               it to previous callinfo's children and to the current method .*/
+            call_info = prof_call_info_create(method, frame->call_info);
+            call_info_table_insert(frame->call_info->call_infos, method->key, call_info);
+            prof_add_call_info(method->call_infos, call_info);
+          }
+
+          // Unpause the parent frame. If currently paused then:
+          // 1) The child frame will begin paused.
+          // 2) The parent will inherit the child's dead time.
+          prof_frame_unpause(frame, measurement);
+        }
+
+        /* Push a new frame onto the stack for a new c-call or ruby call (into a method) */
+        frame = prof_stack_push(thread_data->stack, measurement);
+        frame->call_info = call_info;
+		frame->call_info->depth = frame->depth;
+        frame->pause_time = profile->paused == Qtrue ? measurement : -1;
+        frame->line = rb_sourceline();
+        break;
+    }
+    case RUBY_EVENT_RETURN:
+    case RUBY_EVENT_C_RETURN:
+    {
+	  prof_stack_pop(thread_data->stack, measurement);
+      break;
+    }
+  }
+}
+
+void
+prof_install_hook(VALUE self)
+{
+    rb_add_event_hook(prof_event_hook,
+          RUBY_EVENT_CALL | RUBY_EVENT_RETURN |
+          RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN |
+          RUBY_EVENT_LINE, self);
+}
+
+void
+prof_remove_hook()
+{
+    rb_remove_event_hook(prof_event_hook);
+}
+
+static int
+collect_threads(st_data_t key, st_data_t value, st_data_t result)
+{
+    thread_data_t* thread_data = (thread_data_t*) value;
+    VALUE threads_array = (VALUE) result;
+	rb_ary_push(threads_array, prof_thread_wrap(thread_data));
+    return ST_CONTINUE;
+}
+
+/* ========  Profile Class ====== */
+static int
+mark_threads(st_data_t key, st_data_t value, st_data_t result)
+{
+    thread_data_t *thread = (thread_data_t *) value;
+    prof_thread_mark(thread);
+    return ST_CONTINUE;
+}
+
+static void
+prof_mark(prof_profile_t *profile)
+{
+	st_foreach(profile->threads_tbl, mark_threads, 0);
+}
+
+/* Freeing the profile creates a cascade of freeing.
+   It fress the thread table, which frees its methods,
+   which frees its call infos. */
+static void
+prof_free(prof_profile_t *profile)
+{
+	profile->last_thread_data = NULL;
+
+	threads_table_free(profile->threads_tbl);
+    profile->threads_tbl = NULL;
+
+    st_free_table(profile->exclude_threads_tbl);
+    profile->exclude_threads_tbl = NULL;
+
+	xfree(profile->measurer);
+	profile->measurer = NULL;
+
+    xfree(profile);
+}
+
+static VALUE
+prof_allocate(VALUE klass)
+{
+    VALUE result;
+    prof_profile_t* profile;
+    result = Data_Make_Struct(klass, prof_profile_t, prof_mark, prof_free, profile);
+    profile->threads_tbl = threads_table_create();
+	profile->exclude_threads_tbl = threads_table_create();
+    profile->running = Qfalse;
+    return result;
+}
+
+/* call-seq:
+   RubyProf::Profile.new(mode, exclude_threads) -> instance
+
+   Returns a new profiler.
+   
+   == Parameters
+   mode::  Measure mode (optional). Specifies the profile measure mode.  If not specified, defaults
+           to RubyProf::WALL_TIME.
+   exclude_threads:: Threads to exclude from the profiling results (optional). */
+static VALUE
+prof_initialize(int argc,  VALUE *argv, VALUE self)
+{
+    prof_profile_t* profile = prof_get_profile(self);
+    VALUE mode;
+    prof_measure_mode_t measurer = MEASURE_WALL_TIME;
+    VALUE exclude_threads;
+    int i;
+    
+    switch (rb_scan_args(argc, argv, "02", &mode, &exclude_threads))
+    {
+      case 0:
+      {
+        measurer = MEASURE_WALL_TIME;
+        exclude_threads = rb_ary_new();
+        break;
+      }
+      case 1:
+      {
+        measurer = (prof_measure_mode_t)NUM2INT(mode);
+        exclude_threads = rb_ary_new();
+        break;
+      }
+      case 2:
+      {
+        Check_Type(exclude_threads, T_ARRAY);
+        measurer = (prof_measure_mode_t)NUM2INT(mode);
+        break;
+      }
+    }
+
+    profile->measurer = prof_get_measurer(measurer);
+
+    for (i = 0; i < RARRAY_LEN(exclude_threads); i++)
+    {
+        VALUE thread = rb_ary_entry(exclude_threads, i);
+        VALUE thread_id = rb_obj_id(thread);
+        st_insert(profile->exclude_threads_tbl, thread_id, Qtrue);
+    }
+
+    return self;
+}
+
+/* call-seq:
+   paused? -> boolean
+
+   Returns whether a profile is currently paused.*/
+static VALUE
+prof_paused(VALUE self)
+{
+    prof_profile_t* profile = prof_get_profile(self);
+    return profile->paused;
+}
+
+/* call-seq:
+   running? -> boolean
+
+   Returns whether a profile is currently running.*/
+static VALUE
+prof_running(VALUE self)
+{
+    prof_profile_t* profile = prof_get_profile(self);
+    return profile->running;
+}
+
+/* call-seq:
+   start -> RubyProf
+
+   Starts recording profile data.*/
+static VALUE
+prof_start(VALUE self)
+{
+    char* trace_file_name;
+
+    prof_profile_t* profile = prof_get_profile(self);
+
+    if (profile->running == Qtrue)
+    {
+        rb_raise(rb_eRuntimeError, "RubyProf.start was already called");
+    }
+
+    profile->running = Qtrue;
+    profile->paused = Qfalse;
+    profile->last_thread_data = NULL;
+
+
+    /* open trace file if environment wants it */
+    trace_file_name = getenv("RUBY_PROF_TRACE");
+    if (trace_file_name != NULL) 
+    {
+      if (strcmp(trace_file_name, "stdout") == 0) 
+      {
+        trace_file = stdout;
+      } 
+      else if (strcmp(trace_file_name, "stderr") == 0)
+      {
+        trace_file = stderr;
+      }
+      else 
+      {
+        trace_file = fopen(trace_file_name, "w");
+      }
+    }
+
+    prof_install_hook(self);
+    return self;
+}
+
+/* call-seq:
+   pause -> RubyProf
+
+   Pauses collecting profile data. */
+static VALUE
+prof_pause(VALUE self)
+{
+    prof_profile_t* profile = prof_get_profile(self);
+    if (profile->running == Qfalse)
+    {
+        rb_raise(rb_eRuntimeError, "RubyProf is not running.");
+    }
+
+    if (profile->paused == Qfalse)
+    {
+        profile->paused = Qtrue;
+        profile->measurement_at_pause_resume = profile->measurer->measure();
+        st_foreach(profile->threads_tbl, pause_thread, (st_data_t) profile);
+    }
+
+    return self;
+}
+
+/* call-seq:
+   resume {block} -> RubyProf
+
+   Resumes recording profile data.*/
+static VALUE
+prof_resume(VALUE self)
+{
+    prof_profile_t* profile = prof_get_profile(self);
+    if (profile->running == Qfalse)
+    {
+        rb_raise(rb_eRuntimeError, "RubyProf is not running.");
+    }
+
+    if (profile->paused == Qtrue)
+    {
+        profile->paused = Qfalse;
+        profile->measurement_at_pause_resume = profile->measurer->measure();
+        st_foreach(profile->threads_tbl, unpause_thread, (st_data_t) profile);
+    }
+
+    return rb_block_given_p() ? rb_ensure(rb_yield, self, prof_pause, self) : self;
+}
+
+/* call-seq:
+   stop -> self
+
+   Stops collecting profile data.*/
+static VALUE
+prof_stop(VALUE self)
+{
+    prof_profile_t* profile = prof_get_profile(self);
+
+    if (profile->running == Qfalse)
+    {
+        rb_raise(rb_eRuntimeError, "RubyProf.start was not yet called");
+    }
+  
+    prof_remove_hook();
+
+    /* close trace file if open */
+    if (trace_file != NULL) 
+    {
+      if (trace_file !=stderr && trace_file != stdout)
+      {
+#ifdef _MSC_VER
+          _fcloseall();
+#else
+        fclose(trace_file);
+#endif
+      }
+      trace_file = NULL;
+    }
+    
+    prof_pop_threads(profile);
+
+    /* Unset the last_thread_data (very important!)
+       and the threads table */
+    profile->running = profile->paused = Qfalse;
+    profile->last_thread_data = NULL;
+
+    /* Post process result */
+    rb_funcall(self, rb_intern("post_process") , 0);
+
+    return self;
+}
+
+/* call-seq:
+   profile {block} -> RubyProf::Result
+
+Profiles the specified block and returns a RubyProf::Result object. */
+static VALUE
+prof_profile(int argc,  VALUE *argv, VALUE klass)
+{
+    int result;
+    VALUE profile = rb_class_new_instance(argc, argv, cProfile);
+
+    if (!rb_block_given_p())
+    {
+        rb_raise(rb_eArgError, "A block must be provided to the profile method.");
+    }
+
+    prof_start(profile);
+    rb_protect(rb_yield, profile, &result);
+    return prof_stop(profile);
+}
+
+/* call-seq:
+   threads -> Array of RubyProf::Thread
+
+Returns an array of RubyProf::Thread instances that were executed
+while the the program was being run. */
+static VALUE
+prof_threads(VALUE self)
+{
+	VALUE result = rb_ary_new();
+    prof_profile_t* profile = prof_get_profile(self);
+    st_foreach(profile->threads_tbl, collect_threads, result);
+    return result;
+}
+
+void Init_ruby_prof()
+{
+    mProf = rb_define_module("RubyProf");
+
+    rp_init_measure();
+    rp_init_method_info();
+    rp_init_call_info();
+    rp_init_thread();
+
+    cProfile = rb_define_class_under(mProf, "Profile", rb_cObject);
+    rb_define_singleton_method(cProfile, "profile", prof_profile, -1);
+    rb_define_alloc_func (cProfile, prof_allocate);
+    rb_define_method(cProfile, "initialize", prof_initialize, -1);
+    rb_define_method(cProfile, "start", prof_start, 0);
+    rb_define_method(cProfile, "stop", prof_stop, 0);
+    rb_define_method(cProfile, "resume", prof_resume, 0);
+    rb_define_method(cProfile, "pause", prof_pause, 0);
+    rb_define_method(cProfile, "running?", prof_running, 0);
+    rb_define_method(cProfile, "paused?", prof_paused, 0);
+    rb_define_method(cProfile, "threads", prof_threads, 0);
+}
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/ruby_prof.h b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/ruby_prof.h
new file mode 100755
index 0000000..a893c24
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/ruby_prof.h
@@ -0,0 +1,54 @@
+/* Copyright (C) 2005-2013 Shugo Maeda <shugo at ruby-lang.org> and Charlie Savage <cfis at savagexi.com>
+   Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_PROF_H__
+#define __RUBY_PROF_H__
+
+#include <ruby.h>
+#include <stdio.h>
+
+#if RUBY_VERSION == 186
+# error 1.8.6 is not supported. Please upgrade to 1.9.3 or higher.
+#endif
+
+#if RUBY_VERSION == 187
+# error 1.8.7 is not supported. Please upgrade to 1.9.3 or higher.
+#endif
+
+#if RUBY_VERSION == 190
+# error 1.9.0 is not supported. Please upgrade to 1.9.3 or higher.
+#endif
+
+#if RUBY_VERSION == 191
+# error 1.9.1 is not supported. Please upgrade to 1.9.3 or higher.
+#endif
+
+#if RUBY_VERSION == 192
+# error 1.9.2 is not supported. Please upgrade to 1.9.3 or higher.
+#endif
+
+#include "rp_measure.h"
+#include "rp_method.h"
+#include "rp_call_info.h"
+#include "rp_stack.h"
+#include "rp_thread.h"
+
+extern VALUE mProf;
+extern VALUE cProfile;
+
+void method_key(prof_method_key_t* key, VALUE klass, ID mid);
+
+typedef struct
+{
+    VALUE running;
+    VALUE paused;
+    prof_measurer_t* measurer;
+    VALUE threads;
+    st_table* threads_tbl;
+    st_table* exclude_threads_tbl;
+    thread_data_t* last_thread_data;
+    double measurement_at_pause_resume;
+} prof_profile_t;
+
+
+#endif //__RUBY_PROF_H__
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/vc/ruby_prof.def b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/vc/ruby_prof.def
new file mode 100755
index 0000000..5da2fad
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/vc/ruby_prof.def
@@ -0,0 +1,3 @@
+LIBRARY ruby_prof
+EXPORTS
+  Init_ruby_prof
\ No newline at end of file
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/vc/ruby_prof.sln b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/vc/ruby_prof.sln
new file mode 100755
index 0000000..ba39463
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/vc/ruby_prof.sln
@@ -0,0 +1,32 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ruby_prof_18", "ruby_prof_18.vcxproj", "{7789FC23-D053-4733-9ED1-D6CE099E1237}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ruby_prof_19", "ruby_prof_19.vcxproj", "{5AF7F29A-B100-4D61-95DA-DB21D7C8C1B8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ruby_prof_20", "ruby_prof_20.vcxproj", "{6B4978F4-3B5F-4D38-81A8-069EC28CC069}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{7789FC23-D053-4733-9ED1-D6CE099E1237}.Debug|Win32.ActiveCfg = Debug|Win32
+		{7789FC23-D053-4733-9ED1-D6CE099E1237}.Debug|Win32.Build.0 = Debug|Win32
+		{7789FC23-D053-4733-9ED1-D6CE099E1237}.Release|Win32.ActiveCfg = Release|Win32
+		{7789FC23-D053-4733-9ED1-D6CE099E1237}.Release|Win32.Build.0 = Release|Win32
+		{5AF7F29A-B100-4D61-95DA-DB21D7C8C1B8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5AF7F29A-B100-4D61-95DA-DB21D7C8C1B8}.Debug|Win32.Build.0 = Debug|Win32
+		{5AF7F29A-B100-4D61-95DA-DB21D7C8C1B8}.Release|Win32.ActiveCfg = Release|Win32
+		{5AF7F29A-B100-4D61-95DA-DB21D7C8C1B8}.Release|Win32.Build.0 = Release|Win32
+		{6B4978F4-3B5F-4D38-81A8-069EC28CC069}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6B4978F4-3B5F-4D38-81A8-069EC28CC069}.Debug|Win32.Build.0 = Debug|Win32
+		{6B4978F4-3B5F-4D38-81A8-069EC28CC069}.Release|Win32.ActiveCfg = Release|Win32
+		{6B4978F4-3B5F-4D38-81A8-069EC28CC069}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/vc/ruby_prof_18.vcxproj b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/vc/ruby_prof_18.vcxproj
new file mode 100755
index 0000000..8edf619
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/vc/ruby_prof_18.vcxproj
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\rp_call_info.h" />
+    <ClInclude Include="..\rp_measure.h" />
+    <ClInclude Include="..\rp_method.h" />
+    <ClInclude Include="..\rp_stack.h" />
+    <ClInclude Include="..\rp_thread.h" />
+    <ClInclude Include="..\ruby_prof.h" />
+    <ClInclude Include="..\version.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\rp_call_info.c" />
+    <ClCompile Include="..\rp_measure.c" />
+    <ClCompile Include="..\rp_measure_allocations.c" />
+    <ClCompile Include="..\rp_measure_cpu_time.c" />
+    <ClCompile Include="..\rp_measure_gc_runs.c" />
+    <ClCompile Include="..\rp_measure_gc_time.c" />
+    <ClCompile Include="..\rp_measure_memory.c" />
+    <ClCompile Include="..\rp_measure_process_time.c" />
+    <ClCompile Include="..\rp_measure_wall_time.c" />
+    <ClCompile Include="..\rp_method.c" />
+    <ClCompile Include="..\rp_stack.c" />
+    <ClCompile Include="..\rp_thread.c" />
+    <ClCompile Include="..\ruby_prof.c" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{7789FC23-D053-4733-9ED1-D6CE099E1237}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>ruby_prof_18</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>C:\MinGW\local\src\ruby-prof\lib\1.8</OutDir>
+    <TargetExt>.so</TargetExt>
+    <TargetName>ruby_prof</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;RUBY_PROF_18_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>C:\MinGW\local\ruby187vc\lib\ruby\1.8\i386-mswin32_100</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>C:\MinGW\local\ruby187vc\lib</AdditionalLibraryDirectories>
+      <AdditionalDependencies>msvcr100-ruby18.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ModuleDefinitionFile>ruby_prof.def</ModuleDefinitionFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;RUBY_PROF_18_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/vc/ruby_prof_19.vcxproj b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/vc/ruby_prof_19.vcxproj
new file mode 100755
index 0000000..bb58988
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/vc/ruby_prof_19.vcxproj
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{5AF7F29A-B100-4D61-95DA-DB21D7C8C1B8}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>ruby_prof</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>..\..\..\lib\1.9</OutDir>
+    <TargetExt>.so</TargetExt>
+    <TargetName>ruby_prof</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;RUBY_PROF_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>C:\MinGW\local\ruby193vc\include\ruby-1.9.1;C:\MinGW\local\ruby193vc\include\ruby-1.9.1\i386-mswin32_100;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>C:\MinGW\local\ruby193vc\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>msvcr100-ruby191.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ModuleDefinitionFile>ruby_prof.def</ModuleDefinitionFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;RUBY_PROF_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="..\rp_call_info.h" />
+    <ClInclude Include="..\rp_measure.h" />
+    <ClInclude Include="..\rp_method.h" />
+    <ClInclude Include="..\rp_stack.h" />
+    <ClInclude Include="..\rp_thread.h" />
+    <ClInclude Include="..\ruby_prof.h" />
+    <ClInclude Include="..\version.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\rp_call_info.c" />
+    <ClCompile Include="..\rp_measure.c" />
+    <ClCompile Include="..\rp_measure_allocations.c" />
+    <ClCompile Include="..\rp_measure_cpu_time.c" />
+    <ClCompile Include="..\rp_measure_gc_runs.c" />
+    <ClCompile Include="..\rp_measure_gc_time.c" />
+    <ClCompile Include="..\rp_measure_memory.c" />
+    <ClCompile Include="..\rp_measure_process_time.c" />
+    <ClCompile Include="..\rp_measure_wall_time.c" />
+    <ClCompile Include="..\rp_method.c" />
+    <ClCompile Include="..\rp_stack.c" />
+    <ClCompile Include="..\rp_thread.c" />
+    <ClCompile Include="..\ruby_prof.c" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/vc/ruby_prof_20.vcxproj b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/vc/ruby_prof_20.vcxproj
new file mode 100755
index 0000000..d620c4e
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ext/ruby_prof/vc/ruby_prof_20.vcxproj
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{6B4978F4-3B5F-4D38-81A8-069EC28CC069}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>ruby_prof</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>..\..\..\lib\2.0</OutDir>
+    <TargetExt>.so</TargetExt>
+    <TargetName>ruby_prof</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;RUBY_PROF_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>C:\MinGW\local\ruby200vc\include\ruby-2.0.0;C:\MinGW\local\ruby200vc\include\ruby-2.0.0\i386-mswin32_100;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>C:\MinGW\local\ruby200vc\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>msvcr100-ruby200.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ModuleDefinitionFile>ruby_prof.def</ModuleDefinitionFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;RUBY_PROF_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="..\rp_call_info.h" />
+    <ClInclude Include="..\rp_measure.h" />
+    <ClInclude Include="..\rp_method.h" />
+    <ClInclude Include="..\rp_stack.h" />
+    <ClInclude Include="..\rp_thread.h" />
+    <ClInclude Include="..\ruby_prof.h" />
+    <ClInclude Include="..\version.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\rp_call_info.c" />
+    <ClCompile Include="..\rp_measure.c" />
+    <ClCompile Include="..\rp_measure_allocations.c" />
+    <ClCompile Include="..\rp_measure_cpu_time.c" />
+    <ClCompile Include="..\rp_measure_gc_runs.c" />
+    <ClCompile Include="..\rp_measure_gc_time.c" />
+    <ClCompile Include="..\rp_measure_memory.c" />
+    <ClCompile Include="..\rp_measure_process_time.c" />
+    <ClCompile Include="..\rp_measure_wall_time.c" />
+    <ClCompile Include="..\rp_method.c" />
+    <ClCompile Include="..\rp_stack.c" />
+    <ClCompile Include="..\rp_thread.c" />
+    <ClCompile Include="..\ruby_prof.c" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof.rb
new file mode 100755
index 0000000..c83a7af
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof.rb
@@ -0,0 +1,81 @@
+# encoding: utf-8
+
+# Load the C-based binding.
+begin
+  RUBY_VERSION =~ /(\d+.\d+)/
+  require "#{$1}/ruby_prof"
+rescue LoadError
+  # Start modifications
+  #
+  # Original code:
+  begin
+    require "ruby_prof"
+  rescue LoadError
+    # Modifications made for Sonic Pi multi-platform compatibility:
+    require 'rbconfig'
+    ruby_api = RbConfig::CONFIG['ruby_version']
+    os = case RUBY_PLATFORM
+         when /.*arm.*-linux.*/
+           :raspberry
+         when /.*linux.*/
+           :linux
+         when /.*darwin.*/
+           :osx
+         when /.*mingw.*/
+           :windows
+         else
+           RUBY_PLATFORM
+         end
+    require_relative "../../../rb-native/#{os}/#{ruby_api}/ruby_prof"
+  end
+  # End modifications
+
+end
+
+require 'ruby-prof/version'
+require 'ruby-prof/aggregate_call_info'
+require 'ruby-prof/call_info'
+require 'ruby-prof/call_info_visitor'
+require 'ruby-prof/compatibility'
+require 'ruby-prof/method_info'
+require 'ruby-prof/profile'
+require 'ruby-prof/rack'
+require 'ruby-prof/thread'
+
+require 'ruby-prof/printers/abstract_printer'
+require 'ruby-prof/printers/call_info_printer'
+require 'ruby-prof/printers/call_stack_printer'
+require 'ruby-prof/printers/call_tree_printer'
+require 'ruby-prof/printers/dot_printer'
+require 'ruby-prof/printers/flat_printer'
+require 'ruby-prof/printers/flat_printer_with_line_numbers'
+require 'ruby-prof/printers/graph_html_printer'
+require 'ruby-prof/printers/graph_printer'
+require 'ruby-prof/printers/multi_printer'
+
+module RubyProf
+  # Checks if the user specified the clock mode via
+  # the RUBY_PROF_MEASURE_MODE environment variable
+  def self.figure_measure_mode
+    case ENV["RUBY_PROF_MEASURE_MODE"]
+    when "wall", "wall_time"
+      RubyProf.measure_mode = RubyProf::WALL_TIME
+    when "cpu", "cpu_time"
+      RubyProf.measure_mode = RubyProf::CPU_TIME
+    when "allocations"
+      RubyProf.measure_mode = RubyProf::ALLOCATIONS
+    when "memory"
+      RubyProf.measure_mode = RubyProf::MEMORY
+    when "process", "process_time"
+      RubyProf.measure_mode = RubyProf::PROCESS_TIME
+    when "gc_time"
+      RubyProf.measure_mode = RubyProf::GC_TIME
+    when "gc_runs"
+      RubyProf.measure_mode = RubyProf::GC_RUNS
+    else
+      # the default is defined in the measure_mode reader
+    end
+  end
+end
+
+RubyProf::figure_measure_mode
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/aggregate_call_info.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/aggregate_call_info.rb
new file mode 100755
index 0000000..59a9094
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/aggregate_call_info.rb
@@ -0,0 +1,70 @@
+# encoding: utf-8
+
+module RubyProf
+  class AggregateCallInfo
+    attr_reader :call_infos
+
+    def initialize(call_infos)
+      if call_infos.length == 0
+        raise(ArgumentError, "Must specify at least one call info.")
+      end
+      @call_infos = call_infos
+    end
+
+    def target
+      call_infos.first.target
+    end
+
+    def parent
+      call_infos.first.parent
+    end
+
+    def line
+      call_infos.first.line
+    end
+
+    def children
+      call_infos.inject(Array.new) do |result, call_info|
+        result.concat(call_info.children)
+      end
+    end
+
+    def total_time
+      aggregate_without_recursion(:total_time)
+    end
+
+    def self_time
+      aggregate_without_recursion(:self_time)
+    end
+
+    def wait_time
+      aggregate_without_recursion(:wait_time)
+    end
+
+    def children_time
+      aggregate_without_recursion(:children_time)
+    end
+
+    def called
+      aggregate(:called)
+    end
+
+    def to_s
+      "#{call_infos.first.target.full_name}"
+    end
+
+    private
+
+    def aggregate(method_name)
+      call_infos.inject(0) do |sum, call_info|
+        sum + call_info.send(method_name)
+      end
+    end
+
+    def aggregate_without_recursion(method_name)
+      call_infos.inject(0) do |sum, call_info|
+        call_info.recursive ? sum : sum + call_info.send(method_name)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/assets/call_stack_printer.css.html b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/assets/call_stack_printer.css.html
new file mode 100755
index 0000000..5aaf71d
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/assets/call_stack_printer.css.html
@@ -0,0 +1,117 @@
+<style type="text/css">
+<!--
+  body {
+    font-size:70%;
+    padding:0;
+    margin:5px;
+    margin-right:0px;
+    margin-left:0px;
+    background: #ffffff;
+  }
+  ul {
+    margin-left:0px;
+    margin-top:0px;
+    margin-bottom:0px;
+    padding-left:0px;
+    list-style-type:none;
+  }
+  li {
+    margin-left:11px;
+    padding:0px;
+    white-space:nowrap;
+    border-top:1px solid #cccccc;
+    border-left:1px solid #cccccc;
+    border-bottom:none;
+  }
+  .thread {
+    margin-left:11px;
+    background:#708090;
+    padding-top:3px;
+    padding-left:12px;
+    padding-bottom:2px;
+    border-left:1px solid #CCCCCC;
+    border-top:1px solid #CCCCCC;
+    font-weight:bold;
+  }
+  .hidden {
+    display:none;
+    width:0px;
+    height:0px;
+    margin:0px;
+    padding:0px;
+    border-style:none;
+  }
+  .color01 { background:#adbdeb }
+  .color05 { background:#9daddb }
+  .color0 { background:#8d9dcb }
+  .color1 { background:#89bccb }
+  .color2 { background:#56e3e7 }
+  .color3 { background:#32cd70 }
+  .color4 { background:#a3d53c }
+  .color5 { background:#c4cb34 }
+  .color6 { background:#dcb66d }
+  .color7 { background:#cda59e }
+  .color8 { background:#be9d9c }
+  .color9 { background:#cf947a }
+  #commands {
+    font-size:10pt;
+    padding:10px;
+    margin-left:11px;
+    margin-bottom:0px;
+    margin-top:0px;
+    background:#708090;
+    border-top:1px solid #cccccc;
+    border-left:1px solid #cccccc;
+    border-bottom:none;
+  }
+  #titlebar {
+    font-size:10pt;
+    padding:10px;
+    margin-left:11px;
+    margin-bottom:0px;
+    margin-top:10px;
+    background:#8090a0;
+    border-top:1px solid #cccccc;
+    border-left:1px solid #cccccc;
+    border-bottom:none;
+  }
+  #help {
+    font-size:10pt;
+    padding:10px;
+    margin-left:11px;
+    margin-bottom:0px;
+    margin-top:0px;
+    background:#8090a0;
+    display:none;
+    border-top:1px solid #cccccc;
+    border-left:1px solid #cccccc;
+    border-bottom:none;
+  }
+  #sentinel {
+    height: 400px;
+    margin-left:11px;
+    background:#8090a0;
+    border-top:1px solid #cccccc;
+    border-left:1px solid #cccccc;
+    border-bottom:none;
+  }
+  input { margin-left:10px; }
+
+  .toggle {
+    background: url(data:image/png;base64,%s) no-repeat left center;
+    float:left;
+    width:9px;
+    height:9px;
+    margin:2px 1px 1px 1px;
+  }
+
+  .toggle.minus {
+    background-position: -9px 0;
+  }
+
+  .toggle.plus {
+    background-position: -18px 0;
+  }
+
+-->
+</style>
\ No newline at end of file
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/assets/call_stack_printer.js.html b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/assets/call_stack_printer.js.html
new file mode 100755
index 0000000..1153540
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/assets/call_stack_printer.js.html
@@ -0,0 +1,385 @@
+<script type="text/javascript">
+  /*
+   Copyright (C) 2005,2009  Stefan Kaes
+   skaes at railsexpress.de
+   */
+
+  function rootNode() {
+    return currentThread;
+  }
+
+  function showUL(node, show) {
+    var lis = node.childNodes;
+    var l = lis.length;
+    for (var i=0; i < l ; i++ ) {
+      toggle(lis[i], show);
+    }
+  }
+
+  function findUlChild(li){
+    var ul = li.childNodes[2];
+    while (ul && ul.nodeName != "UL") {
+      ul = ul.nextSibling;
+    }
+    return ul;
+  }
+
+  function isLeafNode(li) {
+    var img = li.firstChild;
+    return (img.className.indexOf('empty') > -1);
+  }
+
+  function toggle(li, show) {
+    if (isLeafNode(li))
+      return;
+
+    var img = li.firstChild;
+    img.className = 'toggle ';
+    img.className += show ? 'minus' : 'plus';
+
+    var ul = findUlChild(li);
+    if (ul) {
+      ul.style.display = show ? 'block' : 'none';
+      showUL(ul, true);
+    }
+  }
+
+  function toggleLI(li) {
+    var img = li.firstChild;
+    if (img.className.indexOf("minus")>-1)
+      toggle(li, false);
+    else {
+      if (img.className.indexOf("plus")>-1)
+        toggle(li, true);
+    }
+  }
+
+  function aboveThreshold(text, threshold) {
+    var match = text.match(/\d+[.,]\d+/);
+    return (match && parseFloat(match[0].replace(/,/, '.'))>=threshold);
+  }
+
+  function setThresholdLI(li, threshold) {
+    var img = li.firstChild;
+    var text = img.nextSibling;
+    var ul = findUlChild(li);
+
+    var visible = aboveThreshold(text.nodeValue, threshold) ? 1 : 0;
+
+    var count = 0;
+    if (ul) {
+      count = setThresholdUL(ul, threshold);
+    }
+    if (count>0) {
+      img.className = 'toggle minus';
+    }
+    else {
+      img.className = 'toggle empty';
+    }
+    if (visible) {
+      li.style.display = 'block'
+    }
+    else {
+      li.style.display = 'none'
+    }
+    return visible;
+  }
+
+  function setThresholdUL(node, threshold) {
+    var lis = node.childNodes;
+    var l = lis.length;
+
+    var count = 0;
+    for ( var i = 0; i < l ; i++ ) {
+      count = count + setThresholdLI(lis[i], threshold);
+    }
+
+    var visible = (count > 0) ? 1 : 0;
+    if (visible) {
+      node.style.display = 'block';
+    }
+    else {
+      node.style.display = 'none';
+    }
+    return visible;
+  }
+
+  function toggleChildren(img, event) {
+    event.cancelBubble=true;
+    if (img.className.indexOf('empty') > -1)
+      return;
+
+    var minus = (img.className.indexOf('minus') > -1);
+
+    if (minus) {
+      img.className = 'toggle plus';
+    }
+    else
+      img.className = 'toggle minus';
+
+    var li = img.parentNode;
+    var ul = findUlChild(li);
+    if (ul) {
+      if (minus)
+        ul.style.display = 'none';
+      else
+        ul.style.display = 'block';
+    }
+    if (minus)
+      moveSelectionIfNecessary(li);
+  }
+
+  function showChildren(li) {
+    var img = li.firstChild;
+    if (img.className.indexOf('empty') > -1)
+      return;
+    img.className = 'toggle minus';
+
+    var ul = findUlChild(li);
+    if (ul) {
+      ul.style.display = 'block';
+    }
+  }
+
+  function setThreshold() {
+    var tv = document.getElementById("threshold").value;
+    if (tv.match(/[0-9]+([.,][0-9]+)?/)) {
+      var f = parseFloat(tv.replace(/,/, '.'));
+      var threads = document.getElementsByName("thread");
+      var l = threads.length;
+      for ( var i = 0; i < l ; i++ ) {
+        setThresholdUL(threads[i], f);
+      }
+      var p = selectedNode;
+      while (p && p.style.display=='none')
+        p=p.parentNode.parentNode;
+      if (p && p.nodeName=="LI")
+        selectNode(p);
+    }
+    else {
+      alert("Please specify a decimal number as threshold value!");
+    }
+  }
+
+  function expandAll(event) {
+    toggleAll(event, true);
+  }
+
+  function collapseAll(event) {
+    toggleAll(event, false);
+    selectNode(rootNode(), null);
+  }
+
+  function toggleAll(event, show) {
+    event.cancelBubble=true;
+    var threads = document.getElementsByName("thread");
+    var l = threads.length;
+    for ( var i = 0; i < l ; i++ ) {
+      showUL(threads[i], show);
+    }
+  }
+
+  function toggleHelp(node) {
+    var help = document.getElementById("help");
+    if (node.value == "Show Help") {
+      node.value = "Hide Help";
+      help.style.display = 'block';
+    }
+    else {
+      node.value = "Show Help";
+      help.style.display = 'none';
+    }
+  }
+
+  var selectedNode = null;
+  var selectedColor = null;
+  var selectedThread = null;
+
+  function descendentOf(a,b){
+    while (a!=b && b!=null)
+      b=b.parentNode;
+    return (a==b);
+  }
+
+  function moveSelectionIfNecessary(node){
+    if (descendentOf(node, selectedNode))
+      selectNode(node, null);
+  }
+
+  function selectNode(node, event) {
+    if (event) {
+      event.cancelBubble = true;
+      thread = findThread(node);
+      selectThread(thread);
+    }
+    if (selectedNode) {
+      selectedNode.style.background = selectedColor;
+    }
+    selectedNode = node;
+    selectedColor = node.style.background;
+    selectedNode.style.background = "red";
+    selectedNode.scrollIntoView();
+    window.scrollBy(0,-400);
+  }
+
+  function moveUp(){
+    move(selectedNode.previousSibling);
+  }
+
+  function moveDown(){
+    move(selectedNode.nextSibling);
+  }
+
+  function move(p) {
+    while (p && p.style.display == 'none')
+      p = p.nextSibling;
+    if (p && p.nodeName == "LI") {
+      selectNode(p, null);
+    }
+  }
+
+  function moveLeft(){
+    var p = selectedNode.parentNode.parentNode;
+    if (p && p.nodeName=="LI") {
+      selectNode(p, null);
+    }
+  }
+
+  function moveRight(){
+    if (!isLeafNode(selectedNode)) {
+      showChildren(selectedNode);
+      var ul = findUlChild(selectedNode);
+      if (ul) {
+        selectNode(ul.firstChild, null);
+      }
+    }
+  }
+
+  function moveForward(){
+    if (isLeafNode(selectedNode)) {
+      var p = selectedNode;
+      while ((p.nextSibling == null || p.nextSibling.style.display=='none') && p.nodeName=="LI") {
+        p = p.parentNode.parentNode;
+      }
+      if (p.nodeName=="LI")
+        selectNode(p.nextSibling, null);
+    }
+    else {
+      moveRight();
+    }
+  }
+
+  function isExpandedNode(li){
+    var img = li.firstChild;
+    return(img.className.indexOf('minus')>-1);
+  }
+
+  function moveBackward(){
+    var p = selectedNode;
+    var q = p.previousSibling;
+    while (q != null && q.style.display=='none')
+      q = q.previousSibling;
+    if (q == null) {
+      p = p.parentNode.parentNode;
+    } else {
+      while (!isLeafNode(q) && isExpandedNode(q)) {
+        q = findUlChild(q).lastChild;
+        while (q.style.display=='none')
+          q = q.previousSibling;
+      }
+      p = q;
+    }
+    if (p.nodeName=="LI")
+      selectNode(p, null);
+  }
+
+  function moveHome() {
+    selectNode(currentThread);
+  }
+
+  var currentThreadIndex = null;
+
+  function findThread(node){
+    while (node && !node.parentNode.nodeName.match(/BODY|DIV/g)) {
+      node = node.parentNode;
+    }
+    return node.firstChild;
+  }
+
+  function selectThread(node){
+    var threads = document.getElementsByName("thread");
+    currentThread = node;
+    for (var i=0; i<threads.length; i++) {
+      if (threads[i]==currentThread.parentNode)
+        currentThreadIndex = i;
+    }
+  }
+
+  function nextThread(){
+    var threads = document.getElementsByName("thread");
+    if (currentThreadIndex==threads.length-1)
+      currentThreadIndex = 0;
+    else
+      currentThreadIndex += 1
+    currentThread = threads[currentThreadIndex].firstChild;
+    selectNode(currentThread, null);
+  }
+
+  function previousThread(){
+    var threads = document.getElementsByName("thread");
+    if (currentThreadIndex==0)
+      currentThreadIndex = threads.length-1;
+    else
+      currentThreadIndex -= 1
+    currentThread = threads[currentThreadIndex].firstChild;
+    selectNode(currentThread, null);
+  }
+
+  function switchThread(node, event){
+    event.cancelBubble = true;
+    selectThread(node.nextSibling.firstChild);
+    selectNode(currentThread, null);
+  }
+
+  function handleKeyEvent(event){
+    var code = event.charCode ? event.charCode : event.keyCode;
+    var str = String.fromCharCode(code);
+    switch (str) {
+      case "a": moveLeft();  break;
+      case "s": moveDown();  break;
+      case "d": moveRight(); break;
+      case "w": moveUp();    break;
+      case "f": moveForward(); break;
+      case "b": moveBackward(); break;
+      case "x": toggleChildren(selectedNode.firstChild, event); break;
+      case "*": toggleLI(selectedNode); break;
+      case "n": nextThread(); break;
+      case "h": moveHome(); break;
+      case "p": previousThread(); break;
+    }
+  }
+  document.onkeypress=function(event){ handleKeyEvent(event) };
+
+  window.onload=function(){
+    var images = document.querySelectorAll(".toggle");
+    for (var i=0; i<images.length; i++) {
+      var img = images[i];
+        img.onclick = function(event){ toggleChildren(this, event); return false; };
+    }
+    var divs = document.getElementsByTagName("div");
+    for (i=0; i<divs.length; i++) {
+      var div = divs[i];
+      if (div.className == "thread")
+        div.onclick = function(event){ switchThread(this, event) };
+    }
+    var lis = document.getElementsByTagName("li");
+    for (var i=0; i<lis.length; i++) {
+      lis[i].onclick = function(event){ selectNode(this, event); };
+    }
+    var threads = document.getElementsByName("thread");;
+    currentThreadIndex = 0;
+    currentThread = threads[0].firstChild;
+    selectNode(currentThread, null);
+  };
+
+</script>
\ No newline at end of file
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/assets/call_stack_printer.png b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/assets/call_stack_printer.png
new file mode 100755
index 0000000..7cb721b
Binary files /dev/null and b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/assets/call_stack_printer.png differ
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/call_info.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/call_info.rb
new file mode 100755
index 0000000..d015c5e
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/call_info.rb
@@ -0,0 +1,141 @@
+# encoding: utf-8
+
+module RubyProf
+  class CallInfo
+    # part of this class is defined in C code.
+    # it provides the following attributes pertaining to tree structure:
+    # depth:      tree level (0 == root)
+    # parent:     parent call info (can be nil)
+    # children:   array of call info children (can be empty)
+    # target:     method info (containing an array of call infos)
+
+    attr_reader :recursive
+
+    def non_recursive?
+      @non_recursive
+    end
+
+    def detect_recursion(visited_methods = Hash.new(0))
+      @recursive = (visited_methods[target] += 1) > 1
+      @non_recursive = true
+      children.each do |child|
+        @non_recursive = false if child.detect_recursion(visited_methods)
+      end
+      visited_methods.delete(target) if (visited_methods[target] -= 1) == 0
+      return !@non_recursive
+    end
+
+    def recalc_recursion(visited_methods = Hash.new(0))
+      return if @non_recursive
+      target.clear_cached_values_which_depend_on_recursiveness
+      @recursive = (visited_methods[target] += 1) > 1
+      children.each do |child|
+        child.recalc_recursion(visited_methods)
+      end
+      visited_methods.delete(target) if (visited_methods[target] -= 1) == 0
+    end
+
+    def children_time
+      children.inject(0) do |sum, call_info|
+        sum += call_info.total_time
+      end
+    end
+
+    def stack
+      @stack ||= begin
+        methods = Array.new
+        call_info = self
+
+        while call_info
+          methods << call_info.target
+          call_info = call_info.parent
+        end
+        methods.reverse
+      end
+    end
+
+    def call_sequence
+      @call_sequence ||= begin
+        stack.map {|method| method.full_name}.join('->')
+      end
+    end
+
+    def root?
+      self.parent.nil?
+    end
+
+    def descendent_of(other)
+      p = self.parent
+      while p && p != other && p.depth > other.depth
+        p = p.parent
+      end
+      p == other
+    end
+
+    def self.roots_of(call_infos)
+      roots = []
+      sorted = call_infos.sort_by(&:depth).reverse
+      while call_info = sorted.shift
+        roots << call_info unless sorted.any?{|p| call_info.descendent_of(p)}
+      end
+      roots
+    end
+
+    def to_s
+      "#{target.full_name} (c: #{called}, tt: #{total_time}, st: #{self_time}, ct: #{children_time})"
+    end
+
+    def inspect
+      super + "(#{target.full_name}, d: #{depth}, c: #{called}, tt: #{total_time}, st: #{self_time}, ct: #{children_time})"
+    end
+
+    # eliminate call info from the call tree.
+    # adds self and wait time to parent and attaches called methods to parent.
+    # merges call trees for methods called from both praent end self.
+    def eliminate!
+      # puts "eliminating #{self}"
+      return unless parent
+      parent.add_self_time(self)
+      parent.add_wait_time(self)
+      children.each do |kid|
+        if call = parent.find_call(kid)
+          call.merge_call_tree(kid)
+        else
+          parent.children << kid
+          # $stderr.puts "setting parent of #{kid}\nto #{parent}"
+          kid.parent = parent
+        end
+      end
+      parent.children.delete(self)
+    end
+
+    # find a specific call in list of children. returns nil if not found.
+    # note: there can't be more than one child with a given target method. in other words:
+    # x.children.grep{|y|y.target==m}.size <= 1 for all method infos m and call infos x
+    def find_call(other)
+      matching = children.select { |kid| kid.target == other.target }
+      raise "inconsistent call tree" unless matching.size <= 1
+      matching.first
+    end
+
+    # merge two call trees. adds self, wait, and total time of other to self and merges children of other into children of self.
+    def merge_call_tree(other)
+      # $stderr.puts "merging #{self}\nand #{other}"
+      self.called += other.called
+      add_self_time(other)
+      add_wait_time(other)
+      add_total_time(other)
+      other.children.each do |other_kid|
+        if kid = find_call(other_kid)
+          # $stderr.puts "merging kids"
+          kid.merge_call_tree(other_kid)
+        else
+          other_kid.parent = self
+          children << other_kid
+        end
+      end
+      other.children.clear
+      other.target.call_infos.delete(other)
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/call_info_visitor.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/call_info_visitor.rb
new file mode 100755
index 0000000..7eb0338
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/call_info_visitor.rb
@@ -0,0 +1,40 @@
+# The call info visitor class does a depth-first traversal across a
+# list of method infos. At each call_info node, the visitor executes
+# the block provided in the #visit method. The block is passed two
+# parameters, the event and the call_info instance. Event will be
+# either :enter or :exit.
+#
+#   visitor = RubyProf::CallInfoVisitor.new(result.threads.first.top_call_infos)
+#
+#   method_names = Array.new
+#
+#   visitor.visit do |call_info, event|
+#     method_names << call_info.target.full_name if event == :enter
+#   end
+#
+#   puts method_names
+
+module RubyProf
+  class CallInfoVisitor
+
+    def initialize(call_infos)
+      @call_infos = CallInfo.roots_of(call_infos)
+    end
+
+    def visit(&block)
+      @call_infos.each do |call_info|
+        visit_call_info(call_info, &block)
+      end
+    end
+
+    private
+    def visit_call_info(call_info, &block)
+      yield call_info, :enter
+      call_info.children.each do |child|
+        visit_call_info(child, &block)
+      end
+      yield call_info, :exit
+    end
+  end
+
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/compatibility.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/compatibility.rb
new file mode 100755
index 0000000..8f67b01
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/compatibility.rb
@@ -0,0 +1,177 @@
+# encoding: utf-8
+
+# These methods are here for backwards compatability with previous RubyProf releases
+module RubyProf
+  # Measurements
+  def self.cpu_frequency
+    Measure::CpuTime.frequency
+  end
+
+  def self.measure_allocations
+    Measure::Allocations.measure
+  end
+
+  def self.measure_cpu_time
+    Measure::CpuTime.measure
+  end
+
+  def self.measure_gc_runs
+    Measure::GcRuns.measure
+  end
+
+  def self.measure_gc_time
+    Measure::GcTime.measure
+  end
+
+  def self.measure_memory
+    Measure::Memory.measure
+  end
+
+  def self.measure_process_time
+    Measure::ProcessTime.measure
+  end
+
+  def self.measure_wall_time
+    Measure::WallTime.measure
+  end
+
+  # call-seq:
+  # measure_mode -> measure_mode
+  #
+  # Returns what ruby-prof is measuring.  Valid values include:
+  #
+  # *RubyProf::PROCESS_TIME - Measure process time.  This is default.  It is implemented using the clock functions in the C Runtime library.
+  # *RubyProf::WALL_TIME - Measure wall time using gettimeofday on Linx and GetLocalTime on Windows
+  # *RubyProf::CPU_TIME - Measure time using the CPU clock counter.  This mode is only supported on Pentium or PowerPC platforms.
+  # *RubyProf::ALLOCATIONS - Measure object allocations.  This requires a patched Ruby interpreter.
+  # *RubyProf::MEMORY - Measure memory size.  This requires a patched Ruby interpreter.
+  # *RubyProf::GC_RUNS - Measure number of garbage collections.  This requires a patched Ruby interpreter.
+  # *RubyProf::GC_TIME - Measure time spent doing garbage collection.  This requires a patched Ruby interpreter.*/
+
+  def self.measure_mode
+    @measure_mode ||= RubyProf::WALL_TIME
+  end
+
+  # call-seq:
+  # measure_mode=value -> void
+  #
+  # Specifies what ruby-prof should measure.  Valid values include:
+  #
+  # *RubyProf::PROCESS_TIME - Measure process time.  This is default.  It is implemented using the clock functions in the C Runtime library.
+  # *RubyProf::WALL_TIME - Measure wall time using gettimeofday on Linx and GetLocalTime on Windows
+  # *RubyProf::CPU_TIME - Measure time using the CPU clock counter.  This mode is only supported on Pentium or PowerPC platforms.
+  # *RubyProf::ALLOCATIONS - Measure object allocations.  This requires a patched Ruby interpreter.
+  # *RubyProf::MEMORY - Measure memory size.  This requires a patched Ruby interpreter.
+  # *RubyProf::GC_RUNS - Measure number of garbage collections.  This requires a patched Ruby interpreter.
+  # *RubyProf::GC_TIME - Measure time spent doing garbage collection.  This requires a patched Ruby interpreter.*/
+  def self.measure_mode=(value)
+    @measure_mode = value
+  end
+
+  def self.measure_mode_string
+    case measure_mode
+    when WALL_TIME    then "wall_time"
+    when CPU_TIME     then "cpu_time"
+    when PROCESS_TIME then "process_time_time"
+    when ALLOCATIONS  then "allocations"
+    when MEMORY       then "memory"
+    when GC_TIME      then "gc_time"
+    when GC_RUNS      then "gc_runs"
+    end
+  end
+
+  # call-seq:
+  # exclude_threads -> exclude_threads
+  #
+  # Returns threads ruby-prof should exclude from profiling
+
+  def self.exclude_threads
+    @exclude_threads ||= Array.new
+  end
+
+  # call-seq:
+  # exclude_threads= -> void
+  #
+  # Specifies what threads ruby-prof should exclude from profiling
+
+  def self.exclude_threads=(value)
+    @exclude_threads = value
+  end
+
+  # Profiling
+  def self.start_script(script)
+    start
+    load script
+  end
+
+  def self.start
+    ensure_not_running!
+    @profile = Profile.new(self.measure_mode, self.exclude_threads)
+    enable_gc_stats_if_needed
+    @profile.start
+  end
+
+  def self.pause
+    ensure_running!
+    disable_gc_stats_if_needed
+    @profile.pause
+  end
+
+  def self.running?
+    if defined?(@profile) and @profile
+      @profile.running?
+    else
+      false
+    end
+  end
+
+  def self.resume
+    ensure_running!
+    enable_gc_stats_if_needed
+    @profile.resume
+  end
+
+  def self.stop
+    ensure_running!
+    result = @profile.stop
+    disable_gc_stats_if_needed
+    @profile = nil
+    result
+  end
+
+  # Profile a block
+  def self.profile(&block)
+    ensure_not_running!
+    gc_stat_was_enabled = enable_gc_stats_if_needed
+    res = Profile.profile(self.measure_mode, self.exclude_threads, &block)
+    disable_gc_stats_if_needed(gc_stat_was_enabled)
+    res
+  end
+
+
+private
+  def self.ensure_running!
+    raise(RuntimeError, "RubyProf.start was not yet called") unless running?
+  end
+
+  def self.ensure_not_running!
+    raise(RuntimeError, "RubyProf is already running") if running?
+  end
+
+  # for GC.allocated_size to work GC statistics should be enabled
+  def self.enable_gc_stats_if_needed
+    if measure_mode_requires_gc_stats_enabled?
+      @gc_stat_was_enabled = GC.enable_stats
+    end
+  end
+
+  def self.disable_gc_stats_if_needed(was_enabled=nil)
+    was_enabled ||= defined?(@gc_stat_was_enabled) && @gc_stat_was_enabled
+    GC.disable_stats if measure_mode_requires_gc_stats_enabled? && !was_enabled
+  end
+
+  def self.measure_mode_requires_gc_stats_enabled?
+    GC.respond_to?(:enable_stats) &&
+      [RubyProf::MEMORY, RubyProf::GC_TIME, RubyProf::GC_RUNS].include?(measure_mode)
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/method_info.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/method_info.rb
new file mode 100755
index 0000000..ba8380f
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/method_info.rb
@@ -0,0 +1,145 @@
+# encoding: utf-8
+
+module RubyProf
+  class MethodInfo
+    include Comparable
+
+    def <=>(other)
+      if self.total_time < other.total_time
+        -1
+      elsif self.total_time > other.total_time
+        1
+      elsif self.min_depth < other.min_depth
+        1
+      elsif self.min_depth > other.min_depth
+        -1
+      else
+        self.full_name <=> other.full_name
+      end
+    end
+
+    def detect_recursion
+      call_infos.each(&:detect_recursion)
+    end
+
+    def recalc_recursion
+      call_infos.each(&:recalc_recursion)
+    end
+
+    def clear_cached_values_which_depend_on_recursiveness
+      @total_time = @self_time = @wait_time = @children_time = nil
+    end
+
+    def called
+      @called ||= begin
+        call_infos.inject(0) do |sum, call_info|
+          sum += call_info.called
+        end
+      end
+    end
+
+    def total_time
+      @total_time ||= begin
+        call_infos.inject(0) do |sum, call_info|
+          sum += call_info.total_time unless call_info.recursive
+          sum
+        end
+      end
+    end
+
+    def self_time
+      @self_time ||= begin
+        call_infos.inject(0) do |sum, call_info|
+          sum += call_info.self_time unless call_info.recursive
+          sum
+        end
+      end
+    end
+
+    def wait_time
+      @wait_time ||= begin
+        call_infos.inject(0) do |sum, call_info|
+          sum += call_info.wait_time unless call_info.recursive
+          sum
+        end
+      end
+    end
+
+    def children_time
+      @children_time ||= begin
+        call_infos.inject(0) do |sum, call_info|
+          sum += call_info.children_time unless call_info.recursive
+          sum
+        end
+      end
+    end
+
+    def min_depth
+      @min_depth ||= call_infos.map(&:depth).min
+    end
+
+    def root?
+      @root ||= begin
+        call_infos.find do |call_info|
+          not call_info.root?
+        end.nil?
+      end
+    end
+
+    def recursive?
+      call_infos.detect(&:recursive)
+    end
+
+    def non_recursive?
+      non_recursive == 1
+    end
+
+    def non_recursive
+      @non_recursive ||= call_infos.all?(&:non_recursive?) ? 1 : 0
+    end
+
+    def children
+      @children ||= call_infos.map(&:children).flatten
+    end
+
+    def parents
+      @parents ||= call_infos.map(&:parent)
+    end
+
+    def aggregate_parents
+      # Group call info's based on their parents
+      groups = self.call_infos.each_with_object({}) do |call_info, hash|
+        key = call_info.parent ? call_info.parent.target : self
+        (hash[key] ||= []) << call_info
+      end
+
+      groups.map do |key, value|
+        AggregateCallInfo.new(value)
+      end
+    end
+
+    def aggregate_children
+      # Group call info's based on their targets
+      groups = self.children.each_with_object({}) do |call_info, hash|
+        key = call_info.target
+        (hash[key] ||= []) << call_info
+      end
+
+      groups.map do |key, value|
+        AggregateCallInfo.new(value)
+      end
+    end
+
+    def to_s
+      "#{self.full_name} (c: #{self.called}, tt: #{self.total_time}, st: #{self.self_time}, ct: #{self.children_time})"
+    end
+
+    # remove method from the call graph. should not be called directly.
+    def eliminate!
+      # $stderr.puts "eliminating #{self}"
+      call_infos.each{ |call_info| call_info.eliminate! }
+      call_infos.clear
+    end
+
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/abstract_printer.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/abstract_printer.rb
new file mode 100755
index 0000000..d56e18a
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/abstract_printer.rb
@@ -0,0 +1,85 @@
+# encoding: utf-8
+
+module RubyProf
+  class AbstractPrinter
+    # Create a new printer.
+    #
+    # result should be the output generated from a profiling run
+    def initialize(result)
+      @result = result
+      @output = nil
+    end
+
+    # Specify print options.
+    #
+    # options - Hash table
+    #   :min_percent - Number 0 to 100 that specifes the minimum
+    #                  %self (the methods self time divided by the
+    #                  overall total time) that a method must take
+    #                  for it to be printed out in the report.
+    #                  Default value is 0.
+    #
+    #   :print_file  - True or false. Specifies if a method's source
+    #                  file should be printed.  Default value if false.
+    #
+    #   :sort_method - Specifies method used for sorting method infos.
+    #                  Available values are :total_time, :self_time,
+    #                  :wait_time, :children_time
+    #                  Default value is :total_time
+    def setup_options(options = {})
+      @options = options
+    end
+
+    def min_percent
+      @options[:min_percent] || 0
+    end
+
+    def print_file
+      @options[:print_file] || false
+    end
+
+    def sort_method
+      @options[:sort_method] || :total_time
+    end
+
+    def method_name(method)
+      name = method.full_name
+      if print_file
+        name += " (#{method.source_file}:#{method.line}}"
+      end
+      name
+    end
+
+    # Print a profiling report to the provided output.
+    #
+    # output - Any IO object, including STDOUT or a file.
+    # The default value is STDOUT.
+    #
+    # options - Hash of print options.  See #setup_options
+    # for more information.  Note that each printer can
+    # define its own set of options.
+    def print(output = STDOUT, options = {})
+      @output = output
+      setup_options(options)
+      print_threads
+    end
+
+    def print_threads
+      @result.threads.each do |thread|
+        print_thread(thread)
+      end
+    end
+
+    def print_thread(thread)
+      print_header(thread)
+      print_methods(thread)
+      print_footer(thread)
+    end
+
+    def print_header(thread)
+    end
+
+    def print_footer(thread)
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/call_info_printer.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/call_info_printer.rb
new file mode 100755
index 0000000..e996258
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/call_info_printer.rb
@@ -0,0 +1,41 @@
+# encoding: utf-8
+
+module RubyProf
+  # Prints out the call graph based on CallInfo instances. This
+  # is mainly for debugging purposes as it provides access into
+  # into RubyProf's internals.
+
+  class CallInfoPrinter < AbstractPrinter
+    TIME_WIDTH = 0
+
+    private
+
+    def print_header(thread)
+      @output << "Thread ID: #{thread.id}\n"
+      @output << "Fiber ID: #{thread.fiber_id}\n"
+      @output << "Total Time: #{thread.total_time}\n"
+      @output << "Sort by: #{sort_method}\n"
+      @output << "\n"
+    end
+
+    def print_methods(thread)
+      visitor = CallInfoVisitor.new(thread.top_call_infos)
+
+      visitor.visit do |call_info, event|
+        if event == :enter
+          @output << "  " * call_info.depth
+          @output << call_info.target.full_name
+          @output << " ("
+          @output << "tt:#{sprintf("%#{TIME_WIDTH}.2f", call_info.total_time)}, "
+          @output << "st:#{sprintf("%#{TIME_WIDTH}.2f", call_info.self_time)}, "
+          @output << "wt:#{sprintf("%#{TIME_WIDTH}.2f", call_info.wait_time)}, "
+          @output << "ct:#{sprintf("%#{TIME_WIDTH}.2f", call_info.children_time)}, "
+          @output << "call:#{call_info.called}, "
+          @output << "rec:#{call_info.recursive}"
+          @output << ")"
+          @output << "\n"
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/call_stack_printer.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/call_stack_printer.rb
new file mode 100755
index 0000000..4e66ae2
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/call_stack_printer.rb
@@ -0,0 +1,260 @@
+# encoding: utf-8
+
+require 'erb'
+require 'fileutils'
+require 'base64'
+
+module RubyProf
+  # prints a HTML visualization of the call tree
+  class CallStackPrinter < AbstractPrinter
+    include ERB::Util
+
+    # Specify print options.
+    #
+    # options - Hash table
+    #   :min_percent - Number 0 to 100 that specifes the minimum
+    #                  %self (the methods self time divided by the
+    #                  overall total time) that a method must take
+    #                  for it to be printed out in the report.
+    #                  Default value is 0.
+    #
+    #   :print_file  - True or false. Specifies if a method's source
+    #                  file should be printed.  Default value if false.
+    #
+    #   :threshold   - a float from 0 to 100 that sets the threshold of
+    #                  results displayed.
+    #                  Default value is 1.0
+    #
+    #   :title       - a String to overide the default "ruby-prof call tree"
+    #                  title of the report.
+    #
+    #   :expansion   - a float from 0 to 100 that sets the threshold of
+    #                  results that are expanded, if the percent_total
+    #                  exceeds it.
+    #                  Default value is 10.0
+    #
+    #   :application - a String to overide the name of the application,
+    #                  as it appears on the report.
+    #
+    def print(output = STDOUT, options = {})
+      @output = output
+      setup_options(options)
+      if @graph_html = options.delete(:graph)
+        @graph_html = "file://" + @graph_html if @graph_html[0]=="/"
+      end
+
+      print_header
+
+      @overall_threads_time = @result.threads.inject(0) do |val, thread|
+        val += thread.total_time
+      end
+
+      @result.threads.each do |thread|
+        @current_thread_id = thread.fiber_id
+        @overall_time = thread.total_time
+        thread_info = "Thread: #{thread.id}"
+        thread_info << ", Fiber: #{thread.fiber_id}" unless thread.id == thread.fiber_id
+        thread_info << " (#{"%4.2f%%" % ((@overall_time/@overall_threads_time)*100)} ~ #{@overall_time})"
+        @output.print "<div class=\"thread\">#{thread_info}</div>"
+        @output.print "<ul name=\"thread\">"
+        thread.methods.each do |m|
+          # $stderr.print m.dump
+          next unless m.root?
+          m.call_infos.each do |ci|
+            next unless ci.root?
+            print_stack ci, thread.total_time
+          end
+        end
+        @output.print "</ul>"
+      end
+
+      print_footer
+
+    end
+
+    def print_stack(call_info, parent_time)
+      total_time = call_info.total_time
+      percent_parent = (total_time/parent_time)*100
+      percent_total = (total_time/@overall_time)*100
+      return unless percent_total > min_percent
+      color = self.color(percent_total)
+      kids = call_info.children
+      visible = percent_total >= threshold
+      expanded = percent_total >= expansion
+      display = visible ? "block" : "none"
+      @output.print "<li class=\"color#{color}\" style=\"display:#{display}\">"
+      if kids.empty?
+        @output.print "<a href=\"#\" class=\"toggle empty\" ></a>"
+      else
+        visible_children = kids.any?{|ci| (ci.total_time/@overall_time)*100 >= threshold}
+        image = visible_children ? (expanded ? "minus" : "plus") : "empty"
+        @output.print "<a href=\"#\" class=\"toggle #{image}\" ></a>"
+      end
+      @output.printf "<span> %4.2f%% (%4.2f%%) %s %s</span>\n", percent_total, percent_parent, link(call_info), graph_link(call_info)
+      unless kids.empty?
+        if expanded
+          @output.print "<ul>"
+        else
+          @output.print '<ul style="display:none">'
+        end
+        kids.sort_by{|c| -c.total_time}.each do |callinfo|
+          print_stack callinfo, total_time
+        end
+        @output.print "</ul>"
+      end
+      @output.print "</li>"
+    end
+
+    def name(call_info)
+      method = call_info.target
+      method.full_name
+    end
+
+    def link(call_info)
+      method = call_info.target
+      file = File.expand_path(method.source_file)
+      if file =~ /\/ruby_runtime$/
+        h(name(call_info))
+      else
+        if RUBY_PLATFORM =~ /darwin/
+          "<a href=\"txmt://open?url=file://#{file}&line=#{method.line}\">#{h(name(call_info))}</a>"
+        else
+          "<a href=\"file://#{file}##{method.line}\">#{h(name(call_info))}</a>"
+        end
+      end
+    end
+
+    def graph_link(call_info)
+      total_calls = call_info.target.call_infos.inject(0){|t, ci| t += ci.called}
+      href = "#{@graph_html}##{method_href(call_info.target)}"
+      totals = @graph_html ? "<a href='#{href}'>#{total_calls}</a>" : total_calls.to_s
+      "[#{call_info.called} calls, #{totals} total]"
+    end
+
+    def method_href(method)
+      h(method.full_name.gsub(/[><#\.\?=:]/,"_") + "_" + @current_thread_id.to_s)
+    end
+
+    def total_time(call_infos)
+      sum(call_infos.map{|ci| ci.total_time})
+    end
+
+    def sum(a)
+      a.inject(0.0){|s,t| s+=t}
+    end
+
+    def dump(ci)
+      $stderr.printf "%s/%d t:%f s:%f w:%f  \n", ci, ci.object_id, ci.total_time, ci.self_time, ci.wait_time
+    end
+
+    def color(p)
+      case i = p.to_i
+      when 0..5
+        "01"
+      when 5..10
+        "05"
+      when 100
+        "9"
+      else
+        "#{i/10}"
+      end
+    end
+
+    def application
+      @options[:application] || $PROGRAM_NAME
+    end
+
+    def arguments
+      ARGV.join(' ')
+    end
+
+    def title
+      @title ||= @options.delete(:title) || "ruby-prof call tree"
+    end
+
+    def threshold
+      @options[:threshold] || 1.0
+    end
+
+    def expansion
+      @options[:expansion] || 10.0
+    end
+
+    def print_header
+      @output.puts "<html><head>"
+      @output.puts '<meta http-equiv="content-type" content="text/html; charset=utf-8">'
+      @output.puts "<title>#{h title}</title>"
+      print_css
+      print_java_script
+      @output.puts '</head><body><div style="display: inline-block;">'
+      print_title_bar
+      print_commands
+      print_help
+    end
+
+    def print_footer
+      @output.puts '<div id="sentinel"></div></div></body></html>'
+    end
+
+    def open_asset(file)
+      path = File.join(File.expand_path('../../assets', __FILE__), file)
+      File.open(path, 'rb').read
+    end
+
+    def print_css
+      html = open_asset('call_stack_printer.css.html')
+      @output.puts html.gsub('%s', base64_image)
+    end
+
+    def base64_image
+      file = open_asset('call_stack_printer.png')
+      Base64.encode64(file).gsub(/\n/, '')
+    end
+
+    def print_java_script
+      html = open_asset('call_stack_printer.js.html')
+      @output.puts html
+    end
+
+    def print_title_bar
+      @output.puts <<-"end_title_bar"
+<div id="titlebar">
+Call tree for application <b>#{h application} #{h arguments}</b><br/>
+Generated on #{Time.now} with options #{h @options.inspect}<br/>
+</div>
+end_title_bar
+    end
+
+    def print_commands
+      @output.puts <<-"end_commands"
+<div id=\"commands\">
+<span style=\"font-size: 11pt; font-weight: bold;\">Threshold:</span>
+<input value=\"#{h threshold}\" size=\"3\" id=\"threshold\" type=\"text\">
+<input value=\"Apply\" onclick=\"setThreshold();\" type=\"submit\">
+<input value=\"Expand All\" onclick=\"expandAll(event);\" type=\"submit\">
+<input value=\"Collapse All\" onclick=\"collapseAll(event);\" type=\"submit\">
+<input value=\"Show Help\" onclick=\"toggleHelp(this);\" type=\"submit\">
+</div>
+end_commands
+    end
+
+    def print_help
+      @output.puts <<-'end_help'
+<div style="display: none;" id="help">
+• Enter a decimal value <i>d</i> into the threshold field and click "Apply"
+        to hide all nodes marked with time values lower than <i>d</i>.<br>
+• Click on "Expand All" for full tree expansion.<br>
+• Click on "Collapse All" to show only top level nodes.<br>
+• Use a, s, d, w as in Quake or Urban Terror to navigate the tree.<br>
+• Use f and b to navigate the tree in preorder forward and backwards.<br>
+• Use x to toggle visibility of a subtree.<br>
+• Use * to expand/collapse a whole subtree.<br>
+• Use h to navigate to thread root.<br>
+• Use n and p to navigate between threads.<br>
+• Click on background to move focus to a subtree.<br>
+</div>
+end_help
+    end
+  end
+end
+
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/call_tree_printer.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/call_tree_printer.rb
new file mode 100755
index 0000000..bd38af0
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/call_tree_printer.rb
@@ -0,0 +1,92 @@
+# encoding: utf-8
+
+module RubyProf
+  # Generate profiling information in calltree format
+  # for use by kcachegrind and similar tools.
+
+  class CallTreePrinter  < AbstractPrinter
+    # Specify print options.
+    #
+    # options - Hash table
+    #   :min_percent - Number 0 to 100 that specifes the minimum
+    #                  %self (the methods self time divided by the
+    #                  overall total time) that a method must take
+    #                  for it to be printed out in the report.
+    #                  Default value is 0.
+    #
+    #   :print_file  - True or false. Specifies if a method's source
+    #                  file should be printed.  Default value if false.
+    #
+    def print(output = STDOUT, options = {})
+      @output = output
+      setup_options(options)
+
+      # add a header - this information is somewhat arbitrary
+      @output << "events: "
+      case RubyProf.measure_mode
+        when RubyProf::PROCESS_TIME
+          @value_scale = RubyProf::CLOCKS_PER_SEC;
+          @output << 'process_time'
+        when RubyProf::WALL_TIME
+          @value_scale = 1_000_000
+          @output << 'wall_time'
+        when RubyProf.const_defined?(:CPU_TIME) && RubyProf::CPU_TIME
+          @value_scale = RubyProf.cpu_frequency
+          @output << 'cpu_time'
+        when RubyProf.const_defined?(:ALLOCATIONS) && RubyProf::ALLOCATIONS
+          @value_scale = 1
+          @output << 'allocations'
+        when RubyProf.const_defined?(:MEMORY) && RubyProf::MEMORY
+          @value_scale = 1
+          @output << 'memory'
+        when RubyProf.const_defined?(:GC_RUNS) && RubyProf::GC_RUNS
+          @value_scale = 1
+          @output << 'gc_runs'
+        when RubyProf.const_defined?(:GC_TIME) && RubyProf::GC_TIME
+          @value_scale = 1000000
+          @output << 'gc_time'
+        else
+          raise "Unknown measure mode: #{RubyProf.measure_mode}"
+      end
+      @output << "\n\n"
+
+      print_threads
+    end
+
+    def print_threads
+      @result.threads.each do |thread|
+        print_thread(thread)
+      end
+    end
+
+    def convert(value)
+      (value * @value_scale).round
+    end
+
+    def file(method)
+      File.expand_path(method.source_file)
+    end
+
+    def print_thread(thread)
+      thread.methods.reverse_each do |method|
+        # Print out the file and method name
+        @output << "fl=#{file(method)}\n"
+        @output << "fn=#{method_name(method)}\n"
+
+        # Now print out the function line number and its self time
+        @output << "#{method.line} #{convert(method.self_time)}\n"
+
+        # Now print out all the children methods
+        method.children.each do |callee|
+          @output << "cfl=#{file(callee.target)}\n"
+          @output << "cfn=#{method_name(callee.target)}\n"
+          @output << "calls=#{callee.called} #{callee.line}\n"
+
+          # Print out total times here!
+          @output << "#{callee.line} #{convert(callee.total_time)}\n"
+        end
+      @output << "\n"
+      end
+    end #end print_methods
+  end # end class
+end # end packages
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/dot_printer.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/dot_printer.rb
new file mode 100755
index 0000000..8b627a8
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/dot_printer.rb
@@ -0,0 +1,132 @@
+# encoding: utf-8
+
+require 'set'
+
+module RubyProf
+  # Generates a graphviz graph in dot format.
+  # To use the dot printer:
+  #
+  #   result = RubyProf.profile do
+  #     [code to profile]
+  #   end
+  #
+  #   printer = RubyProf::DotPrinter.new(result)
+  #   printer.print(STDOUT)
+  #
+  # You can use either dot viewer such as GraphViz, or the dot command line tool
+  # to reformat the output into a wide variety of outputs:
+  #
+  #   dot -Tpng graph.dot > graph.png
+  #
+  class DotPrinter < RubyProf::AbstractPrinter
+    CLASS_COLOR = '"#666666"'
+    EDGE_COLOR  = '"#666666"'
+
+    # Creates the DotPrinter using a RubyProf::Result.
+    def initialize(result)
+      super(result)
+      @seen_methods = Set.new
+    end
+
+    # Print a graph report to the provided output.
+    #
+    # output - Any IO object, including STDOUT or a file. The default value is
+    # STDOUT.
+    #
+    # options - Hash of print options.  See #setup_options
+    # for more information.
+    #
+    # When profiling results that cover a large number of method calls it
+    # helps to use the :min_percent option, for example:
+    #
+    #   DotPrinter.new(result).print(STDOUT, :min_percent=>5)
+    #
+    def print(output = STDOUT, options = {})
+      @output = output
+      setup_options(options)
+
+      puts 'digraph "Profile" {'
+      #puts "label=\"#{mode_name} >=#{min_percent}%\\nTotal: #{total_time}\";"
+      puts "labelloc=t;"
+      puts "labeljust=l;"
+      print_threads
+      puts '}'
+    end
+
+    private
+
+    # Something of a hack, figure out which constant went with the
+    # RubyProf.measure_mode so that we can display it.  Otherwise it's easy to
+    # forget what measurement was made.
+    def mode_name
+      RubyProf.constants.find{|c| RubyProf.const_get(c) == RubyProf.measure_mode}
+    end
+
+    def print_threads
+      @result.threads.each do |thread|
+        puts "subgraph \"Thread #{thread.id}\" {"
+
+        print_thread(thread)
+        puts "}"
+
+        print_classes(thread)
+      end
+    end
+
+    # Determines an ID to use to represent the subject in the Dot file.
+    def dot_id(subject)
+      subject.object_id
+    end
+
+    def print_thread(thread)
+      total_time = thread.total_time
+      thread.methods.sort_by(&sort_method).reverse_each do |method|
+        total_percentage = (method.total_time/total_time) * 100
+
+        next if total_percentage < min_percent
+        name = method_name(method).split("#").last
+        puts "#{dot_id(method)} [label=\"#{name}\\n(#{total_percentage.round}%)\"];"
+        @seen_methods << method
+        print_edges(total_time, method)
+      end
+    end
+
+    def print_classes(thread)
+      grouped = {}
+      thread.methods.each{|m| grouped[m.klass_name] ||= []; grouped[m.klass_name] << m}
+      grouped.each do |cls, methods2|
+        # Filter down to just seen methods
+        big_methods = methods2.select{|m| @seen_methods.include? m}
+
+        if !big_methods.empty?
+          puts "subgraph cluster_#{cls.object_id} {"
+          puts "label = \"#{cls}\";"
+          puts "fontcolor = #{CLASS_COLOR};"
+          puts "fontsize = 16;"
+          puts "color = #{CLASS_COLOR};"
+          big_methods.each do |m|
+            puts "#{m.object_id};"
+          end
+          puts "}"
+        end
+      end
+    end
+
+    def print_edges(total_time, method)
+      method.aggregate_children.sort_by(&:total_time).reverse.each do |child|
+
+        target_percentage = (child.target.total_time / total_time) * 100.0
+        next if target_percentage < min_percent
+
+        # Get children method
+        puts "#{dot_id(method)} -> #{dot_id(child.target)} [label=\"#{child.called}/#{child.target.called}\" fontsize=10 fontcolor=#{EDGE_COLOR}];"
+      end
+    end
+
+    # Silly little helper for printing to the @output
+    def puts(str)
+      @output.puts(str)
+    end
+
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/flat_printer.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/flat_printer.rb
new file mode 100755
index 0000000..4caa532
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/flat_printer.rb
@@ -0,0 +1,70 @@
+# encoding: utf-8
+
+module RubyProf
+  # Generates flat[link:files/examples/flat_txt.html] profile reports as text.
+  # To use the flat printer:
+  #
+  #   result = RubyProf.profile do
+  #     [code to profile]
+  #   end
+  #
+  #   printer = RubyProf::FlatPrinter.new(result)
+  #   printer.print(STDOUT, {})
+  #
+  class FlatPrinter < AbstractPrinter
+    # Override for this printer to sort by self time by default
+    def sort_method
+      @options[:sort_method] || :self_time
+    end
+
+    private
+
+    #def print_threads
+    #  @result.threads.each do |thread|
+    #    print_thread(thread)
+    #    @output << "\n" * 2
+    #  end
+    #end
+
+    def print_header(thread)
+      @output << "Measure Mode: %s\n" % RubyProf.measure_mode_string
+      @output << "Thread ID: %d\n" % thread.id
+      @output << "Fiber ID: %d\n" % thread.fiber_id unless thread.id == thread.fiber_id
+      @output << "Total: %0.6f\n" % thread.total_time
+      @output << "Sort by: #{sort_method}\n"
+      @output << "\n"
+      @output << " %self      total      self      wait     child     calls  name\n"
+    end
+
+    def print_methods(thread)
+      total_time = thread.total_time
+      methods = thread.methods.sort_by(&sort_method).reverse
+
+      sum = 0
+      methods.each do |method|
+        self_percent = (method.self_time / total_time) * 100
+        next if self_percent < min_percent
+
+        sum += method.self_time
+        #self_time_called = method.called > 0 ? method.self_time/method.called : 0
+        #total_time_called = method.called > 0? method.total_time/method.called : 0
+
+        @output << "%6.2f  %9.3f %9.3f %9.3f %9.3f %8d  %s%s\n" % [
+                      method.self_time / total_time * 100, # %self
+                      method.total_time,                   # total
+                      method.self_time,                    # self
+                      method.wait_time,                    # wait
+                      method.children_time,                # children
+                      method.called,                       # calls
+                      method.recursive? ? "*" : " ",       # cycle
+                      method_name(method)                  # name
+                  ]
+      end
+    end
+
+    def print_footer(thread)
+      @output << "\n"
+      @output << "* indicates recursively called methods\n"
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb
new file mode 100755
index 0000000..d31fbc6
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb
@@ -0,0 +1,64 @@
+# encoding: utf-8
+
+module RubyProf
+  # Generates flat[link:files/examples/flat_txt.html] profile reports as text.
+  # To use the flat printer with line numbers:
+  #
+  #   result = RubyProf.profile do
+  #     [code to profile]
+  #   end
+  #
+  #   printer = RubyProf::FlatPrinterWithLineNumbers.new(result)
+  #   printer.print(STDOUT, {})
+  #
+  class FlatPrinterWithLineNumbers < FlatPrinter
+    def print_methods(thread)
+      total_time = thread.total_time
+
+      methods = thread.methods.sort_by(&sort_method).reverse
+      sum = 0
+      methods.each do |method|
+        self_percent = (method.self_time / total_time) * 100
+        next if self_percent < min_percent
+
+        sum += method.self_time
+        #self_time_called = method.called > 0 ? method.self_time/method.called : 0
+        #total_time_called = method.called > 0? method.total_time/method.called : 0
+
+        @output << "%6.2f  %9.3f %9.3f %9.3f %9.3f %8d  %s%s" % [
+            method.self_time / total_time * 100, # %self
+            method.total_time,                   # total
+            method.self_time,                    # self
+            method.wait_time,                    # wait
+            method.children_time,                # children
+            method.called,                       # calls
+            method.recursive? ? "*" : " ",       # cycle
+            method_name(method)                  # name
+        ]
+         if method.source_file == 'ruby_runtime'
+           @output << "\n"
+         else
+           @output << "\n      defined at:\n"
+           @output << "          %s:%s\n" % [File.expand_path(method.source_file), method.line]
+         end
+
+         callers = []
+         method.call_infos.each do |ci|
+           if ci.parent && ci.parent.target.source_file != 'ruby_runtime'
+             callers << [method_name(ci.parent.target), File.expand_path(ci.parent.target.source_file), ci.parent.target.line]
+           end
+         end
+         # make sure callers are unique
+         callers.uniq!
+
+         unless callers.empty?
+           @output << "      called from:\n"
+           callers.each do |args|
+             @output << "          %s (%s:%s)\n" % args
+           end
+         end
+         @output << "\n"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/graph_html_printer.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/graph_html_printer.rb
new file mode 100755
index 0000000..7827b52
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/graph_html_printer.rb
@@ -0,0 +1,246 @@
+# encoding: utf-8
+
+require 'erb'
+
+module RubyProf
+  # Generates graph[link:files/examples/graph_html.html] profile reports as html.
+  # To use the graph html printer:
+  #
+  #   result = RubyProf.profile do
+  #     [code to profile]
+  #   end
+  #
+  #   printer = RubyProf::GraphHtmlPrinter.new(result)
+  #   printer.print(STDOUT, :min_percent=>0)
+  #
+  # The Graph printer takes the following options in its print methods:
+  #   :filename    - specify a file to use that contains the ERB
+  #                  template to use, instead of the built-in self.template
+  #
+  #   :template    - specify an ERB template to use, instead of the
+  #                  built-in self.template
+  #
+
+  class GraphHtmlPrinter < AbstractPrinter
+    include ERB::Util
+
+    def setup_options(options)
+      super(options)
+
+      filename = options[:filename]
+      template = filename ? File.read(filename).untaint : (options[:template] || self.template)
+      @erb = ERB.new(template)
+      @erb.filename = filename
+    end
+
+    def print(output = STDOUT, options = {})
+      @output = output
+      setup_options(options)
+      @output << @erb.result(binding).split("\n").map(&:rstrip).join("\n") << "\n"
+    end
+
+    # Creates a link to a method.  Note that we do not create
+    # links to methods which are under the min_perecent
+    # specified by the user, since they will not be
+    # printed out.
+    def create_link(thread, overall_time, method)
+      total_percent = (method.total_time/overall_time) * 100
+      if total_percent < min_percent
+        # Just return name
+        h method.full_name
+      else
+        href = '#' + method_href(thread, method)
+        "<a href=\"#{href}\">#{h method.full_name}</a>"
+      end
+    end
+
+    def method_href(thread, method)
+      h(method.full_name.gsub(/[><#\.\?=:]/,"_") + "_" + thread.fiber_id.to_s)
+    end
+
+    def file_link(path, linenum)
+      srcfile = File.expand_path(path)
+      if srcfile =~ /\/ruby_runtime$/
+        ""
+      else
+        if RUBY_PLATFORM =~ /darwin/
+          "<a href=\"txmt://open?url=file://#{h srcfile}&line=#{linenum}\" title=\"#{h srcfile}:#{linenum}\">#{linenum}</a>"
+        else
+          "<a href=\"file://#{h srcfile}##{linenum}\" title=\"#{h srcfile}:#{linenum}\">#{linenum}</a>"
+        end
+      end
+    end
+
+    def template
+'
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <style media="all" type="text/css">
+    table {
+      border-collapse: collapse;
+      border: 1px solid #CCC;
+      font-family: Verdana, Arial, Helvetica, sans-serif;
+      font-size: 9pt;
+      line-height: normal;
+      width: 100%;
+    }
+
+    th {
+      text-align: center;
+      border-top: 1px solid #FB7A31;
+      border-bottom: 1px solid #FB7A31;
+      background: #FFC;
+      padding: 0.3em;
+      border-left: 1px solid silver;
+    }
+
+    tr.break td {
+      border: 0;
+      border-top: 1px solid #FB7A31;
+      padding: 0;
+      margin: 0;
+    }
+
+    tr.method td {
+      font-weight: bold;
+    }
+
+    td {
+      padding: 0.3em;
+    }
+
+    td:first-child {
+      width: 190px;
+      }
+
+    td {
+      border-left: 1px solid #CCC;
+      text-align: center;
+    }
+
+    .method_name {
+      text-align: left;
+    }
+
+    tfoot td {
+      text-align: left;
+    }
+  </style>
+  </head>
+  <body>
+    <h1>Profile Report: <%= RubyProf.measure_mode_string %></h1>
+    <!-- Threads Table -->
+    <table>
+      <tr>
+        <th>Thread ID</th>
+        <th>Fiber ID</th>
+        <th>Total Time</th>
+      </tr>
+      <% for thread in @result.threads %>
+      <tr>
+        <td><%= thread.id %></td>
+        <td><a href="#<%= thread.fiber_id %>"><%= thread.fiber_id %></a></td>
+        <td><%= thread.total_time %></td>
+      </tr>
+      <% end %>
+    </table>
+    <!-- Methods Tables -->
+    <%
+       for thread in @result.threads
+         methods = thread.methods
+         total_time = thread.total_time
+    %>
+      <h2><a name="<%= thread.fiber_id %>">Thread <%= thread.id %>, Fiber: <%= thread.fiber_id %></a></h2>
+      <table>
+        <thead>
+          <tr>
+            <th>%Total</th>
+            <th>%Self</th>
+            <th>Total</th>
+            <th>Self</th>
+            <th>Wait</th>
+            <th>Child</th>
+            <th>Calls</th>
+            <th class="method_name">Name</th>
+            <th>Line</th>
+          </tr>
+        </thead>
+        <tbody>
+          <%
+             min_time = @options[:min_time] || (@options[:nonzero] ? 0.005 : nil)
+             methods.sort_by(&sort_method).reverse_each do |method|
+               total_percentage = (method.total_time/total_time) * 100
+               next if total_percentage < min_percent
+               next if min_time && method.total_time < min_time
+               self_percentage = (method.self_time/total_time) * 100
+          %>
+               <!-- Parents -->
+               <%
+                  for caller in method.aggregate_parents.sort_by(&:total_time)
+                    next unless caller.parent
+                    next if min_time && caller.total_time < min_time
+               %>
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td><%= sprintf("%.2f", caller.total_time) %></td>
+                   <td><%= sprintf("%.2f", caller.self_time) %></td>
+                   <td><%= sprintf("%.2f", caller.wait_time) %></td>
+                   <td><%= sprintf("%.2f", caller.children_time) %></td>
+                   <td><%= "#{caller.called}/#{method.called}" %></td>
+                   <td class="method_name"><%= create_link(thread, total_time, caller.parent.target) %></td>
+                   <td><%= file_link(caller.parent.target.source_file, caller.line) %></td>
+                 </tr>
+               <% end %>
+               <tr class="method">
+                 <td><%= sprintf("%.2f\%", total_percentage) %></td>
+                 <td><%= sprintf("%.2f\%", self_percentage) %></td>
+                 <td><%= sprintf("%.2f", method.total_time) %></td>
+                 <td><%= sprintf("%.2f", method.self_time) %></td>
+                 <td><%= sprintf("%.2f", method.wait_time) %></td>
+                 <td><%= sprintf("%.2f", method.children_time) %></td>
+                 <td><%= sprintf("%i", method.called) %></td>
+                 <td class="method_name">
+                   <a name="<%= method_href(thread, method) %>">
+                     <%= method.recursive? ? "*" : " "%><%= h method.full_name %>
+                   </a>
+                 </td>
+                 <td><%= file_link(method.source_file, method.line) %></td>
+               </tr>
+               <!-- Children -->
+               <%
+                  method.recalc_recursion unless method.non_recursive?
+                  for callee in method.aggregate_children.sort_by(&:total_time).reverse
+                    next if min_time && callee.total_time < min_time
+               %>
+                 <tr>
+                   <td> </td>
+                   <td> </td>
+                   <td><%= sprintf("%.2f", callee.total_time) %></td>
+                   <td><%= sprintf("%.2f", callee.self_time) %></td>
+                   <td><%= sprintf("%.2f", callee.wait_time) %></td>
+                   <td><%= sprintf("%.2f", callee.children_time) %></td>
+                   <td><%= "#{callee.called}/#{callee.target.called}" %></td>
+                   <td class="method_name"><%= create_link(thread, total_time, callee.target) %></td>
+                   <td><%= file_link(method.source_file, callee.line) %></td>
+                 </tr>
+               <% end %>
+               <!-- Create divider row -->
+               <tr class="break"><td colspan="9"></td></tr>
+            <% thread.recalc_recursion unless method.non_recursive? %>
+          <% end %>
+        </tbody>
+        <tfoot>
+          <tr>
+            <td colspan="9">* indicates recursively called methods</td>
+          </tr>
+        </tfoot>
+      </table>
+    <% end %>
+  </body>
+</html>'
+    end
+  end
+end
+
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/graph_printer.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/graph_printer.rb
new file mode 100755
index 0000000..be83956
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/graph_printer.rb
@@ -0,0 +1,118 @@
+# encoding: utf-8
+
+module RubyProf
+  # Generates graph[link:files/examples/graph_txt.html] profile reports as text.
+  # To use the graph printer:
+  #
+  #   result = RubyProf.profile do
+  #     [code to profile]
+  #   end
+  #
+  #   printer = RubyProf::GraphPrinter.new(result)
+  #   printer.print(STDOUT, {})
+  #
+  # The constructor takes two arguments. See the README
+
+  class GraphPrinter < AbstractPrinter
+    PERCENTAGE_WIDTH = 8
+    TIME_WIDTH = 11
+    CALL_WIDTH = 17
+
+    private
+
+    def print_header(thread)
+      @output << "Measure Mode: %s\n" % RubyProf.measure_mode_string
+      @output << "Thread ID: #{thread.id}\n"
+      @output << "Fiber ID: #{thread.fiber_id}\n" unless thread.id == thread.fiber_id
+      @output << "Total Time: #{thread.total_time}\n"
+      @output << "Sort by: #{sort_method}\n"
+      @output << "\n"
+
+      # 1 is for % sign
+      @output << sprintf("%#{PERCENTAGE_WIDTH}s", "%total")
+      @output << sprintf("%#{PERCENTAGE_WIDTH}s", "%self")
+      @output << sprintf("%#{TIME_WIDTH}s", "total")
+      @output << sprintf("%#{TIME_WIDTH}s", "self")
+      @output << sprintf("%#{TIME_WIDTH}s", "wait")
+      @output << sprintf("%#{TIME_WIDTH}s", "child")
+      @output << sprintf("%#{CALL_WIDTH}s", "calls")
+      @output << "    Name"
+      @output << "\n"
+    end
+
+    def print_methods(thread)
+      total_time = thread.total_time
+      # Sort methods from longest to shortest total time
+      methods = thread.methods.sort_by(&sort_method)
+
+      # Print each method in total time order
+      methods.reverse_each do |method|
+        total_percentage = (method.total_time/total_time) * 100
+        next if total_percentage < min_percent
+
+        self_percentage = (method.self_time/total_time) * 100
+
+        @output << "-" * 80 << "\n"
+        print_parents(thread, method)
+
+        # 1 is for % sign
+        @output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", total_percentage)
+        @output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", self_percentage)
+        @output << sprintf("%#{TIME_WIDTH}.3f", method.total_time)
+        @output << sprintf("%#{TIME_WIDTH}.3f", method.self_time)
+        @output << sprintf("%#{TIME_WIDTH}.3f", method.wait_time)
+        @output << sprintf("%#{TIME_WIDTH}.3f", method.children_time)
+        @output << sprintf("%#{CALL_WIDTH}i", method.called)
+        @output << sprintf("     %s",  method.recursive? ? "*" : " ")
+        @output << sprintf("%s", method_name(method))
+        if print_file
+          @output << sprintf("  %s:%s", method.source_file, method.line)
+        end
+        @output << "\n"
+
+        method.recalc_recursion unless method.non_recursive?
+        print_children(method)
+        thread.recalc_recursion unless method.non_recursive?
+      end
+    end
+
+    def print_parents(thread, method)
+      method.aggregate_parents.sort_by(&:total_time).each do |caller|
+        next unless caller.parent
+        @output << " " * 2 * PERCENTAGE_WIDTH
+        @output << sprintf("%#{TIME_WIDTH}.3f", caller.total_time)
+        @output << sprintf("%#{TIME_WIDTH}.3f", caller.self_time)
+        @output << sprintf("%#{TIME_WIDTH}.3f", caller.wait_time)
+        @output << sprintf("%#{TIME_WIDTH}.3f", caller.children_time)
+
+        call_called = "#{caller.called}/#{method.called}"
+        @output << sprintf("%#{CALL_WIDTH}s", call_called)
+        @output << sprintf("      %s", caller.parent.target.full_name)
+        @output << "\n"
+      end
+    end
+
+    def print_children(method)
+      method.aggregate_children.sort_by(&:total_time).reverse.each do |child|
+        # Get children method
+
+        @output << " " * 2 * PERCENTAGE_WIDTH
+
+        @output << sprintf("%#{TIME_WIDTH}.3f", child.total_time)
+        @output << sprintf("%#{TIME_WIDTH}.3f", child.self_time)
+        @output << sprintf("%#{TIME_WIDTH}.3f", child.wait_time)
+        @output << sprintf("%#{TIME_WIDTH}.3f", child.children_time)
+
+        call_called = "#{child.called}/#{child.target.called}"
+        @output << sprintf("%#{CALL_WIDTH}s", call_called)
+        @output << sprintf("      %s", child.target.full_name)
+        @output << "\n"
+      end
+    end
+
+    def print_footer(thread)
+      @output << "\n"
+      @output << "* indicates recursively called methods\n"
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/multi_printer.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/multi_printer.rb
new file mode 100755
index 0000000..beb5d0c
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/printers/multi_printer.rb
@@ -0,0 +1,56 @@
+# encoding: utf-8
+
+module RubyProf
+  # Helper class to simplify printing profiles of several types from
+  # one profiling run. Currently prints a flat profile, a callgrind
+  # profile, a call stack profile and a graph profile.
+  class MultiPrinter
+    def initialize(result)
+      @stack_printer = CallStackPrinter.new(result)
+      @graph_printer = GraphHtmlPrinter.new(result)
+      @tree_printer = CallTreePrinter.new(result)
+      @flat_printer = FlatPrinter.new(result)
+    end
+
+    # create profile files under options[:path] or the current
+    # directory. options[:profile] is used as the base name for the
+    # pofile file, defaults to "profile".
+    def print(options)
+      @profile = options.delete(:profile) || "profile"
+      @directory = options.delete(:path) || File.expand_path(".")
+      File.open(stack_profile, "w") do |f|
+        @stack_printer.print(f, options.merge(:graph => "#{@profile}.graph.html"))
+      end
+      File.open(graph_profile, "w") do |f|
+        @graph_printer.print(f, options)
+      end
+      File.open(tree_profile, "w") do |f|
+        @tree_printer.print(f, options)
+      end
+      File.open(flat_profile, "w") do |f|
+        @flat_printer.print(f, options)
+      end
+    end
+
+    # the name of the call stack profile file
+    def stack_profile
+      "#{@directory}/#{@profile}.stack.html"
+    end
+
+    # the name of the graph profile file
+    def graph_profile
+      "#{@directory}/#{@profile}.graph.html"
+    end
+
+    # the name of the callgrind profile file
+    def tree_profile
+      "#{@directory}/#{@profile}.grind.dat"
+    end
+
+    # the name of the flat profile file
+    def flat_profile
+      "#{@directory}/#{@profile}.flat.txt"
+    end
+
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/profile.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/profile.rb
new file mode 100755
index 0000000..e35f51c
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/profile.rb
@@ -0,0 +1,56 @@
+# encoding: utf-8
+
+require 'set'
+module RubyProf
+  class Profile
+    # This method gets called once profiling has been completed
+    # but before results are returned to the user.  Thus it provides
+    # a hook to do any necessary post-processing on the call graph.
+    def post_process
+      self.threads.each do |thread|
+        thread.detect_recursion
+      end
+    end
+
+    # eliminate some calls from the graph by merging the information into callers.
+    # matchers can be a list of strings or regular expressions or the name of a file containing regexps.
+    def eliminate_methods!(matchers)
+      matchers = read_regexps_from_file(matchers) if matchers.is_a?(String)
+      eliminated = []
+      threads.each do |thread|
+        matchers.each{ |matcher| eliminated.concat(eliminate_methods(thread.methods, matcher)) }
+      end
+      eliminated
+    end
+
+    private
+
+    # read regexps from file
+    def read_regexps_from_file(file_name)
+      matchers = []
+      File.open(file_name).each_line do |l|
+        next if (l =~ /^(#.*|\s*)$/) # emtpy lines and lines starting with #
+        matchers << Regexp.new(l.strip)
+      end
+    end
+
+    # eliminate methods matching matcher
+    def eliminate_methods(methods, matcher)
+      eliminated = []
+      i = 0
+      while i < methods.size
+        method_info = methods[i]
+        method_name = method_info.full_name
+        if matcher === method_name
+          raise "can't eliminate root method" if method_info.root?
+          eliminated << methods.delete_at(i)
+          method_info.eliminate!
+        else
+          i += 1
+        end
+      end
+      eliminated
+    end
+
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/rack.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/rack.rb
new file mode 100755
index 0000000..ea1baf2
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/rack.rb
@@ -0,0 +1,51 @@
+# encoding: utf-8
+require 'tmpdir'
+
+module Rack
+  class RubyProf
+    def initialize(app, options = {})
+      @app = app
+      @options = options
+      @options[:min_percent] ||= 1
+
+      @tmpdir = options[:path] || Dir.tmpdir
+      FileUtils.mkdir_p(@tmpdir)
+
+      @printer_klasses = @options[:printers]  || {::RubyProf::FlatPrinter => 'flat.txt',
+                                                  ::RubyProf::GraphPrinter => 'graph.txt',
+                                                  ::RubyProf::GraphHtmlPrinter => 'graph.html',
+                                                  ::RubyProf::CallStackPrinter => 'call_stack.html'}
+
+      @skip_paths = options[:skip_paths] || [%r{^/assets}, %r{\.css$}, %r{\.js$}, %r{\.png$}, %r{\.jpeg$}, %r{\.jpg$}, %r{\.gif$}]
+    end
+
+    def call(env)
+      request = Rack::Request.new(env)
+
+      if @skip_paths.any? {|skip_path| skip_path =~ request.path}
+        @app.call(env)
+      else
+        result = nil
+        data = ::RubyProf::Profile.profile do
+          result = @app.call(env)
+        end
+
+        path = request.path.gsub('/', '-')
+        path.slice!(0)
+
+        print(data, path)
+        result
+      end
+    end
+
+    def print(data, path)
+      @printer_klasses.each do |printer_klass, base_name|
+        printer = printer_klass.new(data)
+        file_name = ::File.join(@tmpdir, "#{path}-#{base_name}")
+        ::File.open(file_name, 'wb') do |file|
+          printer.print(file, @options)
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/task.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/task.rb
new file mode 100755
index 0000000..65b83ca
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/task.rb
@@ -0,0 +1,147 @@
+#!/usr/bin/env ruby
+# encoding: utf-8
+
+require 'rake'
+require 'rake/testtask'
+require 'fileutils'
+
+module RubyProf
+
+  # Define a task library for profiling unit tests with ruby-prof.
+  #
+  # All of the options provided by
+  # the Rake:TestTask are supported except the loader
+  # which is set to ruby-prof.  For detailed information
+  # please refer to the Rake:TestTask documentation.
+  #
+  # ruby-prof specific options include:
+  #
+  #   output_dir - For each file specified an output
+  #                file with profile information will be
+  #                written to the output directory.
+  #                By default, the output directory is
+  #                called "profile" and is created underneath
+  #                the current working directory.
+  #
+  #   printer - Specifies the output printer.  Valid values include
+  #             :flat, :graph, :graph_html and :call_tree.
+  #
+  #   min_percent - Methods that take less than the specified percent
+  #                 will not be written out.
+  #
+  # Example:
+  #
+  #   require 'ruby-prof/task'
+  #
+  #   RubyProf::ProfileTask.new do |t|
+  #     t.test_files = FileList['test/test*.rb']
+  #     t.output_dir = "c:/temp"
+  #     t.printer = :graph
+  #     t.min_percent = 10
+  #   end
+  #
+  # If rake is invoked with a "TEST=filename" command line option,
+  # then the list of test files will be overridden to include only the
+  # filename specified on the command line.  This provides an easy way
+  # to run just one test.
+  #
+  # If rake is invoked with a "TESTOPTS=options" command line option,
+  # then the given options are passed to the test process after a
+  # '--'.  This allows Test::Unit options to be passed to the test
+  # suite.
+  #
+  # Examples:
+  #
+  #   rake profile                           # run tests normally
+  #   rake profile TEST=just_one_file.rb     # run just one test file.
+  #   rake profile TESTOPTS="-v"             # run in verbose mode
+  #   rake profile TESTOPTS="--runner=fox"   # use the fox test runner
+
+  class ProfileTask < Rake::TestTask
+    attr_accessor :output_dir
+    attr_accessor :min_percent
+    attr_accessor :printer
+
+    def initialize(name = :profile)
+      super(name)
+    end
+
+    # Create the tasks defined by this task lib.
+    def define
+      lib_path = @libs.join(File::PATH_SEPARATOR)
+      desc "Profile" + (@name==:profile ? "" : " for #{@name}")
+
+      task @name do
+        create_output_directory
+
+        @ruby_opts.unshift( "-I#{lib_path}" )
+        @ruby_opts.unshift( "-w" ) if @warning
+        @ruby_opts.push("-S ruby-prof")
+        @ruby_opts.push("--printer #{@printer}")
+        @ruby_opts.push("--min_percent #{@min_percent}")
+
+        file_list.each do |file_path|
+          run_script(file_path)
+        end
+      end
+      self
+    end
+
+    # Run script
+    def run_script(script_path)
+      run_code = ''
+      RakeFileUtils.verbose(@verbose) do
+        file_name = File.basename(script_path, File.extname(script_path))
+        case @printer
+          when :flat, :graph, :call_tree
+            file_name += ".txt"
+          when :graph_html
+            file_name += ".html"
+          else
+            file_name += ".txt"
+        end
+
+        output_file_path = File.join(output_directory, file_name)
+
+        command_line = @ruby_opts.join(" ") +
+                      " --file=" + output_file_path +
+                      " " + script_path
+
+        puts "ruby " + command_line
+        # We have to catch the exeption to continue on.  However,
+        # the error message will have been output to STDERR
+        # already by the time we get here so we don't have to
+        # do that again
+        begin
+          ruby command_line
+        rescue => e
+          STDOUT << e << "\n"
+          STDOUT.flush
+        end
+        puts ""
+        puts ""
+      end
+    end
+
+    def output_directory
+      File.expand_path(@output_dir)
+    end
+
+    def create_output_directory
+      if not File.exist?(output_directory)
+        Dir.mkdir(output_directory)
+      end
+    end
+
+    def clean_output_directory
+      if File.exist?(output_directory)
+        files = Dir.glob(output_directory + '/*')
+        FileUtils.rm(files)
+      end
+    end
+
+    def option_list # :nodoc:
+      ENV['OPTIONS'] || @options.join(" ") || ""
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/thread.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/thread.rb
new file mode 100755
index 0000000..04e549b
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/thread.rb
@@ -0,0 +1,34 @@
+module RubyProf
+  class Thread
+    def top_methods
+      self.methods.select do |method_info|
+        method_info.call_infos.detect(&:root?)
+      end
+    end
+
+    def top_call_infos
+      top_methods.map(&:call_infos).flatten.select(&:root?)
+    end
+
+    # This method detect recursive calls in the call tree of a given thread
+    # It should be called only once for each thread
+    def detect_recursion
+      top_call_infos.each(&:detect_recursion)
+    end
+
+    def recalc_recursion
+      top_call_infos.each(&:recalc_recursion)
+    end
+
+    def total_time
+      self.top_methods.inject(0) do |sum, method_info|
+        method_info.call_infos.each do |call_info|
+          if call_info.parent.nil?
+            sum += call_info.total_time
+          end
+        end
+        sum
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/version.rb b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/version.rb
new file mode 100755
index 0000000..1c19e6b
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/ruby-prof/version.rb
@@ -0,0 +1,3 @@
+module RubyProf
+  VERSION = "0.15.8"
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/lib/unprof.rb b/app/server/vendor/ruby-prof-0.15.8/lib/unprof.rb
new file mode 100755
index 0000000..c0683e3
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/lib/unprof.rb
@@ -0,0 +1,10 @@
+# encoding: utf-8
+
+require "ruby-prof"
+
+at_exit {
+  result = RubyProf.stop
+  printer = RubyProf::FlatPrinter.new(result)
+  printer.print(STDOUT)
+}
+RubyProf.start
diff --git a/app/server/vendor/ruby-prof-0.15.8/ruby-prof.gemspec b/app/server/vendor/ruby-prof-0.15.8/ruby-prof.gemspec
new file mode 100755
index 0000000..63d2772
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/ruby-prof.gemspec
@@ -0,0 +1,57 @@
+# -*- encoding: utf-8 -*-
+
+$:.push File.expand_path("../lib", __FILE__)
+require "ruby-prof/version"
+
+Gem::Specification.new do |spec|
+  spec.name = "ruby-prof"
+
+  spec.homepage = "https://github.com/ruby-prof/ruby-prof/"
+  spec.summary = "Fast Ruby profiler"
+  spec.description = <<-EOF
+ruby-prof is a fast code profiler for Ruby. It is a C extension and
+therefore is many times faster than the standard Ruby profiler. It
+supports both flat and graph profiles.  For each method, graph profiles
+show how long the method ran, which methods called it and which
+methods it called. RubyProf generate both text and html and can output
+it to standard out or to a file.
+EOF
+  spec.license = 'BSD-2-Clause'
+  spec.version = RubyProf::VERSION
+
+  spec.author = "Shugo Maeda, Charlie Savage, Roger Pack, Stefan Kaes"
+  spec.email = "shugo at ruby-lang.org, cfis at savagexi.com, rogerdpack at gmail.com, skaes at railsexpress.de"
+  spec.platform = Gem::Platform::RUBY
+  spec.require_path = "lib"
+  spec.bindir = "bin"
+  spec.executables = ["ruby-prof", "ruby-prof-check-trace"]
+  spec.extensions = ["ext/ruby_prof/extconf.rb"]
+  spec.files = Dir['CHANGES',
+                   'LICENSE',
+                   'Rakefile',
+                   'README.rdoc',
+                   'ruby-prof.gemspec',
+                   'bin/ruby-prof',
+                   'bin/ruby-prof-check-trace',
+                   'doc/**/*',
+                   'examples/*',
+                   'ext/ruby_prof/extconf.rb',
+                   'ext/ruby_prof/*.c',
+                   'ext/ruby_prof/*.h',
+                   'ext/ruby_prof/vc/*.sln',
+                   'ext/ruby_prof/vc/*.vcxproj',
+                   'lib/ruby-prof.rb',
+                   'lib/unprof.rb',
+                   'lib/ruby-prof/*.rb',
+                   'lib/ruby-prof/assets/*.{html,png}',
+                   'lib/ruby-prof/printers/*.rb',
+                   'test/*.rb']
+
+  spec.test_files = Dir["test/test_*.rb"]
+  spec.required_ruby_version = '>= 1.9.3'
+  spec.date = Time.now.strftime('%Y-%m-%d')
+  spec.homepage = 'https://github.com/ruby-prof/ruby-prof'
+  spec.add_development_dependency('minitest', '~> 5.5.0')
+  spec.add_development_dependency('rake-compiler')
+  spec.add_development_dependency('rdoc')
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/aggregate_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/aggregate_test.rb
new file mode 100755
index 0000000..279ef44
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/aggregate_test.rb
@@ -0,0 +1,136 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+# Test data
+#   A   B   C
+#   |   |   |
+#   Z   A   A
+#       |   |
+#       Z   Z
+
+class AggClass
+  def z
+    sleep 1
+  end
+
+  def a
+    z
+  end
+
+  def b
+    a
+  end
+
+  def c
+    a
+  end
+end
+
+class AggregateTest < TestCase
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+  end
+
+  def test_all_call_infos_are_not_recursive
+    c1 = AggClass.new
+    result = RubyProf.profile do
+      c1.a
+      c1.b
+      c1.c
+    end
+    methods = result.threads.first.methods.sort.reverse
+    methods.each do |m|
+      m.call_infos.each do |ci|
+        assert(!ci.recursive)
+      end
+    end
+  end
+
+  def test_call_infos
+    c1 = AggClass.new
+    result = RubyProf.profile do
+      c1.a
+      c1.b
+      c1.c
+    end
+
+    methods = result.threads.first.methods.sort.reverse
+    method = methods.find {|meth| meth.full_name == 'AggClass#z'}
+
+    # Check AggClass#z
+    assert_equal('AggClass#z', method.full_name)
+    assert_equal(3, method.called)
+    assert_in_delta(3, method.total_time, 0.05)
+    assert_in_delta(0, method.wait_time, 0.05)
+    assert_in_delta(0, method.self_time, 0.05)
+    assert_in_delta(3, method.children_time, 0.05)
+    assert_equal(3, method.call_infos.length)
+
+    call_info = method.call_infos[0]
+    assert_equal('AggregateTest#test_call_infos->AggClass#a->AggClass#z', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+
+    call_info = method.call_infos[1]
+    assert_equal('AggregateTest#test_call_infos->AggClass#b->AggClass#a->AggClass#z', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+
+    call_info = method.call_infos[2]
+    assert_equal('AggregateTest#test_call_infos->AggClass#c->AggClass#a->AggClass#z', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+  end
+
+  def test_aggregates_parents
+    c1 = AggClass.new
+    result = RubyProf.profile do
+      c1.a
+      c1.b
+      c1.c
+    end
+
+    methods = result.threads.first.methods.sort.reverse
+    method = methods.find {|meth| meth.full_name == 'AggClass#z'}
+
+    # Check AggClass#z
+    assert_equal('AggClass#z', method.full_name)
+
+    call_infos = method.aggregate_parents
+    assert_equal(1, call_infos.length)
+
+    call_info = call_infos.first
+    assert_equal('AggClass#a', call_info.parent.target.full_name)
+    assert_in_delta(3, call_info.total_time, 0.05)
+    assert_in_delta(0, call_info.wait_time, 0.05)
+    assert_in_delta(0, call_info.self_time, 0.05)
+    assert_in_delta(3, call_info.children_time, 0.05)
+    assert_equal(3, call_info.called)
+  end
+
+  def test_aggregates_children
+    c1 = AggClass.new
+    result = RubyProf.profile do
+      c1.a
+      c1.b
+      c1.c
+    end
+
+    methods = result.threads.first.methods.sort.reverse
+    method = methods.find {|meth| meth.full_name == 'AggClass#a'}
+
+    # Check AggClass#a
+    assert_equal('AggClass#a', method.full_name)
+
+    call_infos = method.aggregate_children
+    assert_equal(1, call_infos.length)
+
+    call_info = call_infos.first
+    assert_equal('AggClass#z', call_info.target.full_name)
+    assert_in_delta(3, call_info.total_time, 0.05)
+    assert_in_delta(0, call_info.wait_time, 0.05)
+    assert_in_delta(0, call_info.self_time, 0.05)
+    assert_in_delta(3, call_info.children_time, 0.05)
+    assert_equal(3, call_info.called)
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/basic_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/basic_test.rb
new file mode 100755
index 0000000..f967bc8
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/basic_test.rb
@@ -0,0 +1,128 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class BasicTest < TestCase
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+  end
+
+  def start
+    RubyProf.start
+    RubyProf::C1.hello
+  end
+
+  def test_running
+    assert(!RubyProf.running?)
+    RubyProf.start
+    assert(RubyProf.running?)
+    RubyProf.stop
+    assert(!RubyProf.running?)
+  end
+
+  def test_double_profile
+    RubyProf.start
+    assert_raises(RuntimeError) do
+      RubyProf.start
+    end
+    RubyProf.stop
+  end
+
+  def test_no_block
+    assert_raises(ArgumentError) do
+      RubyProf.profile
+    end
+  end
+
+  def test_traceback
+    RubyProf.start
+    assert_raises(NoMethodError) do
+      RubyProf.xxx
+    end
+
+    RubyProf.stop
+  end
+
+  def test_leave_method
+    start
+    sleep 0.15
+    profile = RubyProf.stop
+
+    assert_equal(1, profile.threads.count)
+
+    thread = profile.threads.first
+    assert_in_delta(0.25, thread.total_time, 0.01)
+
+    top_methods = thread.top_methods.sort
+    assert_equal(2, top_methods.count)
+    assert_equal("BasicTest#start", top_methods[0].full_name)
+    assert_equal("BasicTest#test_leave_method", top_methods[1].full_name)
+
+    assert_equal(4, thread.methods.length)
+    methods = profile.threads.first.methods.sort
+
+    # Check times
+    assert_equal("<Class::RubyProf::C1>#hello", methods[0].full_name)
+    assert_in_delta(0.1, methods[0].total_time, 0.01)
+    assert_in_delta(0.0,  methods[0].wait_time, 0.01)
+    assert_in_delta(0.0,  methods[0].self_time, 0.01)
+
+    assert_equal("BasicTest#start", methods[1].full_name)
+    assert_in_delta(0.1, methods[1].total_time, 0.01)
+    assert_in_delta(0.0, methods[1].wait_time, 0.01)
+    assert_in_delta(0.0, methods[1].self_time, 0.01)
+
+    assert_equal("BasicTest#test_leave_method", methods[2].full_name)
+    assert_in_delta(0.15, methods[2].total_time, 0.01)
+    assert_in_delta(0.0, methods[2].wait_time, 0.01)
+    assert_in_delta(0.0, methods[2].self_time, 0.01)
+
+    assert_equal("Kernel#sleep", methods[3].full_name)
+    assert_in_delta(0.25, methods[3].total_time, 0.01)
+    assert_in_delta(0.0, methods[3].wait_time, 0.01)
+    assert_in_delta(0.25, methods[3].self_time, 0.01)
+  end
+
+  def test_leave_method_2
+    start
+    RubyProf::C1.hello
+    RubyProf::C1.hello
+    profile = RubyProf.stop
+
+    assert_equal(1, profile.threads.count)
+
+    thread = profile.threads.first
+    assert_in_delta(0.3, thread.total_time, 0.01)
+
+    top_methods = thread.top_methods.sort
+    assert_equal(2, top_methods.count)
+    assert_equal("BasicTest#start", top_methods[0].full_name)
+    assert_equal("BasicTest#test_leave_method_2", top_methods[1].full_name)
+
+    assert_equal(4, thread.methods.length)
+    methods = profile.threads.first.methods.sort
+
+    # Check times
+    assert_equal("BasicTest#start", methods[0].full_name)
+    assert_in_delta(0.1, methods[0].total_time, 0.01)
+    assert_in_delta(0.0, methods[0].wait_time, 0.01)
+    assert_in_delta(0.0, methods[0].self_time, 0.01)
+
+    assert_equal("BasicTest#test_leave_method_2", methods[1].full_name)
+    assert_in_delta(0.2, methods[1].total_time, 0.01)
+    assert_in_delta(0.0, methods[1].wait_time, 0.01)
+    assert_in_delta(0.0, methods[1].self_time, 0.01)
+
+    assert_equal("Kernel#sleep", methods[2].full_name)
+    assert_in_delta(0.3, methods[2].total_time, 0.01)
+    assert_in_delta(0.0, methods[2].wait_time, 0.01)
+    assert_in_delta(0.3, methods[2].self_time, 0.01)
+
+    assert_equal("<Class::RubyProf::C1>#hello", methods[3].full_name)
+    assert_in_delta(0.3, methods[3].total_time, 0.01)
+    assert_in_delta(0.0, methods[3].wait_time, 0.01)
+    assert_in_delta(0.0, methods[3].self_time, 0.01)
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/block_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/block_test.rb
new file mode 100755
index 0000000..86e2712
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/block_test.rb
@@ -0,0 +1,74 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path("../test_helper", __FILE__)
+
+class BlockMethodTest < TestCase
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+  end
+
+  def test_block
+    result = RubyProf.profile do
+      1.times { RubyProf::C1.new.hello }
+    end
+
+    # Methods called
+    #  Kernel#sleep
+    #  <Class::BasicObject>#allocate
+    #  #{RubyProf.parent_object}#inizialize
+    #  RubyProf::C1#hello
+    #  Class#new
+    #  Integer#times
+    #  BlockMethodTest#test_block
+
+    methods = result.threads.first.methods.sort.reverse
+    assert_equal(RubyProf.ruby_2? ? 6 : 7, methods.length)
+
+    # Check times
+    assert_equal("BlockMethodTest#test_block", methods[0].full_name)
+    assert_in_delta(0.2, methods[0].total_time, 0.02)
+    assert_in_delta(0.0, methods[0].wait_time, 0.02)
+    assert_in_delta(0.0, methods[0].self_time, 0.02)
+
+    assert_equal("Integer#times", methods[1].full_name)
+    assert_in_delta(0.2, methods[1].total_time, 0.02)
+    assert_in_delta(0.0, methods[1].wait_time, 0.02)
+    assert_in_delta(0.0, methods[1].self_time, 0.02)
+
+    assert_equal("RubyProf::C1#hello", methods[2].full_name)
+    assert_in_delta(0.2, methods[2].total_time, 0.02)
+    assert_in_delta(0.0, methods[2].wait_time, 0.02)
+    assert_in_delta(0.0, methods[2].self_time, 0.02)
+
+    assert_equal("Kernel#sleep", methods[3].full_name)
+    assert_in_delta(0.2, methods[3].total_time, 0.01)
+    assert_in_delta(0.0, methods[3].wait_time, 0.01)
+    assert_in_delta(0.2, methods[3].self_time, 0.01)
+
+    assert_equal("Class#new", methods[4].full_name)
+    assert_in_delta(0.0, methods[4].total_time, 0.01)
+    assert_in_delta(0.0, methods[4].wait_time, 0.01)
+    assert_in_delta(0.0, methods[4].self_time, 0.01)
+
+    # the timing difference between #initialize and #allocate is so small
+    # that we cannot rely on #initialize appearing first.
+    # so switch them, if necessary
+    if methods[5].full_name =~ /#allocate/
+      methods[5], methods[6] = methods[6], methods[5]
+    end
+
+    assert_equal("#{RubyProf.parent_object}#initialize", methods[5].full_name)
+    assert_in_delta(0.0, methods[5].total_time, 0.01)
+    assert_in_delta(0.0, methods[5].wait_time, 0.01)
+    assert_in_delta(0.0, methods[5].self_time, 0.01)
+
+    unless RubyProf.ruby_2?
+      assert_equal("<Class::#{RubyProf.parent_object}>#allocate", methods[6].full_name)
+      assert_in_delta(0.0, methods[6].total_time, 0.01)
+      assert_in_delta(0.0, methods[6].wait_time, 0.01)
+      assert_in_delta(0.0, methods[6].self_time, 0.01)
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/call_info_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/call_info_test.rb
new file mode 100755
index 0000000..52703aa
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/call_info_test.rb
@@ -0,0 +1,78 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class CallInfoTest < TestCase
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+  end
+
+#  def test_clone
+#    result = RubyProf.profile do
+#      RubyProf::C1.hello
+#    end
+#
+#    method = result.threads.first.top_methods.first
+#    call_info = method.call_infos.first
+#    call_info_clone = call_info.clone
+#
+##    assert_equal(call_info.target, call_info_clone.target)
+#    assert_equal(call_info.total_time, call_info_clone.total_time)
+#  end
+
+  def test_merge
+    result1 = RubyProf.profile do
+      RubyProf::C1.hello
+    end
+
+    methods = result1.threads.first.methods.sort.reverse
+    assert_equal(3, methods.length)
+
+    assert_equal('CallInfoTest#test_merge', methods[0].full_name)
+    assert_in_delta(0.1, methods[0].total_time, 0.01)
+    assert_in_delta(0, methods[0].wait_time, 0.01)
+    assert_in_delta(0, methods[0].self_time, 0.01)
+    assert_equal(1, methods[0].called)
+
+    assert_equal('<Class::RubyProf::C1>#hello', methods[1].full_name)
+    assert_in_delta(0.1, methods[1].total_time, 0.01)
+    assert_in_delta(0, methods[1].wait_time, 0.01)
+    assert_in_delta(0, methods[1].self_time, 0.01)
+    assert_equal(1, methods[1].called)
+
+    assert_equal('Kernel#sleep', methods[2].full_name)
+    assert_in_delta(0.1, methods[2].total_time, 0.01)
+    assert_in_delta(0, methods[2].wait_time, 0.01)
+    assert_in_delta(0.1, methods[2].self_time, 0.01)
+    assert_equal(1, methods[2].called)
+
+    RubyProf.profile do
+      RubyProf::C1.hello
+    end
+
+    # Merge the trees
+    methods = result1.threads.first.methods.sort.reverse
+    assert_equal(3, methods.length)
+
+    assert_equal('CallInfoTest#test_merge', methods[0].full_name)
+    assert_in_delta(0.1, methods[0].total_time, 0.01)
+    assert_in_delta(0, methods[0].wait_time, 0.01)
+    assert_in_delta(0, methods[0].self_time, 0.01)
+    assert_equal(1, methods[0].called)
+
+    assert_equal('<Class::RubyProf::C1>#hello', methods[1].full_name)
+    assert_in_delta(0.1, methods[1].total_time, 0.01)
+    assert_in_delta(0, methods[1].wait_time, 0.01)
+    assert_in_delta(0, methods[1].self_time, 0.01)
+    assert_equal(1, methods[1].called)
+
+    assert_equal('Kernel#sleep', methods[2].full_name)
+    assert_in_delta(0.1, methods[2].total_time, 0.01)
+    assert_in_delta(0, methods[2].wait_time, 0.01)
+    assert_in_delta(0.1, methods[2].self_time, 0.01)
+    assert_equal(1, methods[2].called)
+  end
+end
+
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/call_info_visitor_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/call_info_visitor_test.rb
new file mode 100755
index 0000000..2eb94c8
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/call_info_visitor_test.rb
@@ -0,0 +1,31 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class CallInfoVisitorTest < TestCase
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+  end
+
+  def test_visit
+    result = RubyProf.profile do
+      RubyProf::C1.hello
+    end
+
+    visitor = RubyProf::CallInfoVisitor.new(result.threads.first.top_call_infos)
+
+    method_names = Array.new
+
+    visitor.visit do |call_info, event|
+      method_names << call_info.target.full_name if event == :enter
+    end
+
+    assert_equal(3, method_names.length)
+    assert_equal("CallInfoVisitorTest#test_visit", method_names[0])
+    assert_equal("<Class::RubyProf::C1>#hello", method_names[1])
+    assert_equal("Kernel#sleep", method_names[2])
+  end
+end
+
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/duplicate_names_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/duplicate_names_test.rb
new file mode 100755
index 0000000..dc9f58c
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/duplicate_names_test.rb
@@ -0,0 +1,32 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class DuplicateNames < TestCase
+  def test_names
+    result = RubyProf::profile do
+      str = %{module Foo; class Bar; def foo; end end end}
+
+      eval str
+      Foo::Bar.new.foo
+      DuplicateNames.class_eval {remove_const :Foo}
+
+      eval str
+      Foo::Bar.new.foo
+      DuplicateNames.class_eval {remove_const :Foo}
+
+      eval str
+      Foo::Bar.new.foo
+    end
+
+    # There should be 3 foo methods
+    methods = result.threads.first.methods.sort.reverse
+
+    methods = methods.select do |method|
+      method.full_name == 'DuplicateNames::Foo::Bar#foo'
+    end
+
+    assert_equal(3, methods.length)
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/dynamic_method_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/dynamic_method_test.rb
new file mode 100755
index 0000000..6a3d431
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/dynamic_method_test.rb
@@ -0,0 +1,55 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path("../test_helper", __FILE__)
+
+class DynamicMethodTest < TestCase
+
+  class FruitMedley
+    define_method(:apple) do
+      sleep(0.1)
+      "I'm a peach"
+    end
+
+    define_method(:orange) do
+      sleep(0.2)
+      "I'm an orange"
+    end
+
+    [:banana, :peach].each_with_index do |fruit,i|
+      define_method(fruit) do
+        sleep(i == 0 ? 0.3 : 0.4)
+        "I'm a #{fruit}"
+      end
+    end
+  end
+
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+  end
+
+  def test_dynamic_method
+    medley = FruitMedley.new
+    result = RubyProf.profile do
+      medley.apple
+      medley.orange
+      medley.banana
+      medley.peach
+    end
+
+    # RubyProf::FlatPrinter.new(result).print(STDOUT)
+
+    methods = result.threads.first.methods.sort.reverse
+    expected_method_names = %w(
+      DynamicMethodTest#test_dynamic_method
+      Kernel#sleep
+      DynamicMethodTest::FruitMedley#peach
+      DynamicMethodTest::FruitMedley#banana
+      DynamicMethodTest::FruitMedley#orange
+      DynamicMethodTest::FruitMedley#apple
+      Symbol#to_s
+    )
+    assert_equal expected_method_names.join("\n"), methods.map(&:full_name).join("\n")
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/enumerable_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/enumerable_test.rb
new file mode 100755
index 0000000..a21fa1e
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/enumerable_test.rb
@@ -0,0 +1,21 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+# --  Test for bug
+# http://github.com/rdp/ruby-prof/issues#issue/12
+
+class EnumerableTest < TestCase
+  def test_enumerable
+    result = RubyProf.profile do
+      3.times {  [1,2,3].any? {|n| n} }
+    end
+    methods = if RUBY_VERSION >= "2.2.0"
+      %w(EnumerableTest#test_enumerable Integer#times Array#any?)
+    else
+      %w(EnumerableTest#test_enumerable Integer#times Enumerable#any? Array#each)
+    end
+    assert_equal(methods, result.threads.first.methods.map(&:full_name))
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/exceptions_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/exceptions_test.rb
new file mode 100755
index 0000000..4be00b5
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/exceptions_test.rb
@@ -0,0 +1,16 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class ExceptionsTest < TestCase
+  def test_profile
+    result = begin
+      RubyProf.profile do
+        raise(RuntimeError, 'Test error')
+      end
+    rescue
+    end
+    refute_nil(result)
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/exclude_threads_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/exclude_threads_test.rb
new file mode 100755
index 0000000..a3ce906
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/exclude_threads_test.rb
@@ -0,0 +1,54 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+
+# --  Tests ----
+class ExcludeThreadsTest < TestCase
+  def test_exclude_threads
+
+    def thread1_proc
+      sleep(0.5)
+      sleep(2)
+    end
+
+    def thread2_proc
+      sleep(0.5)
+      sleep(2)
+    end
+
+    thread1 = Thread.new do
+      thread1_proc
+    end
+
+    thread2 = Thread.new do
+      thread2_proc
+    end
+
+    RubyProf::exclude_threads = [ thread2 ]
+
+    RubyProf.start
+
+    thread1.join
+    thread2.join
+
+    result = RubyProf.stop
+
+    RubyProf::exclude_threads = nil
+
+    assert_equal(2, result.threads.length)
+
+    output = Array.new
+    result.threads.each do |thread|
+      thread.methods.each do | m |
+        if m.full_name.index("ExcludeThreadsTest#thread") == 0
+          output.push(m.full_name)
+        end
+      end
+    end
+
+    assert_equal(1, output.length)
+    assert_equal("ExcludeThreadsTest#thread1_proc", output[0])
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/fiber_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/fiber_test.rb
new file mode 100755
index 0000000..0be5fe0
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/fiber_test.rb
@@ -0,0 +1,65 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+require 'timeout'
+require 'set'
+begin
+  require 'fiber'
+rescue LoadError
+end
+
+# --  Tests ----
+class FiberTest < TestCase
+
+  def fiber_test
+    @fiber_ids << Fiber.current.object_id
+    enum = Enumerator.new do |yielder|
+        [1,2].each do |x|
+          @fiber_ids << Fiber.current.object_id
+          sleep 0.1
+          yielder.yield x
+        end
+      end
+    while true
+      begin
+        enum.next
+      rescue StopIteration
+        break
+      end
+    end
+    sleep 0.1
+  end
+
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+    @fiber_ids  = Set.new
+    @root_fiber = Fiber.current.object_id
+    @thread_id  = Thread.current.object_id
+    @result     = RubyProf.profile { fiber_test }
+  end
+
+  def test_fibers
+    profiled_fiber_ids = @result.threads.map(&:fiber_id)
+    assert_equal(2, @result.threads.length)
+    assert_equal([@thread_id], @result.threads.map(&:id).uniq)
+    assert_equal(@fiber_ids, Set.new(profiled_fiber_ids))
+
+    assert profiled_fiber_ids.include?(@root_fiber)
+    assert(root_fiber_profile = @result.threads.detect{|t| t.fiber_id == @root_fiber})
+    assert(enum_fiber_profile = @result.threads.detect{|t| t.fiber_id != @root_fiber})
+
+    assert_in_delta(0.3, root_fiber_profile.total_time, 0.05)
+    assert_in_delta(0.2, enum_fiber_profile.total_time, 0.05)
+
+    assert(method_next = root_fiber_profile.methods.detect{|m| m.full_name == "Enumerator#next"})
+    assert(method_each = enum_fiber_profile.methods.detect{|m| m.full_name == "Enumerator#each"})
+
+    assert_in_delta(0.2, method_next.total_time, 0.05)
+    assert_in_delta(0.2, method_each.total_time, 0.05)
+
+    # RubyProf::CallInfoPrinter.new(@result).print
+  end
+
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/line_number_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/line_number_test.rb
new file mode 100755
index 0000000..f74fbd7
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/line_number_test.rb
@@ -0,0 +1,71 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class LineNumbers
+  def method1
+  end
+
+  def method2
+    method1
+  end
+
+  def method3
+    sleep(1)
+  end
+end
+
+# --  Tests ----
+class LineNumbersTest < TestCase
+  def test_function_line_no
+    numbers = LineNumbers.new
+
+    result = RubyProf.profile do
+      numbers.method2
+    end
+
+    methods = result.threads.first.methods.sort.reverse
+    assert_equal(3, methods.length)
+
+    method = methods[0]
+    assert_equal('LineNumbersTest#test_function_line_no', method.full_name)
+    assert_equal(25, method.line)
+
+    method = methods[1]
+    assert_equal('LineNumbers#method2', method.full_name)
+    assert_equal(10, method.line)
+
+    method = methods[2]
+    assert_equal('LineNumbers#method1', method.full_name)
+    assert_equal(7, method.line)
+  end
+
+  def test_c_function
+    numbers = LineNumbers.new
+
+    result = RubyProf.profile do
+      numbers.method3
+    end
+
+    methods = result.threads.first.methods.sort_by {|method| method.full_name}
+    assert_equal(3, methods.length)
+
+    # Methods:
+    #   LineNumbers#method3
+    #   LineNumbersTest#test_c_function
+    #   Kernel#sleep
+
+    method = methods[0]
+    assert_equal('Kernel#sleep', method.full_name)
+    assert_equal(0, method.line)
+
+    method = methods[1]
+    assert_equal('LineNumbers#method3', method.full_name)
+    assert_equal(14, method.line)
+
+    method = methods[2]
+    assert_equal('LineNumbersTest#test_c_function', method.full_name)
+    assert_equal(48, method.line)
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/measure_allocations_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/measure_allocations_test.rb
new file mode 100755
index 0000000..c015209
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/measure_allocations_test.rb
@@ -0,0 +1,25 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class MeasureAllocationsTest < TestCase
+  def test_allocations_mode
+    RubyProf::measure_mode = RubyProf::ALLOCATIONS
+    assert_equal(RubyProf::ALLOCATIONS, RubyProf::measure_mode)
+  end
+
+  def test_allocations_enabled_defined
+    assert(defined?(RubyProf::ALLOCATIONS_ENABLED))
+  end
+
+  if RubyProf::ALLOCATIONS_ENABLED
+    def test_allocations
+      t = RubyProf.measure_allocations
+      assert_kind_of Integer, t
+
+      u = RubyProf.measure_allocations
+      assert u > t, [t, u].inspect
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/measure_cpu_time_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/measure_cpu_time_test.rb
new file mode 100755
index 0000000..027b9a5
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/measure_cpu_time_test.rb
@@ -0,0 +1,153 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class MeasureCpuTimeTest < TestCase
+  def setup
+    RubyProf::measure_mode = RubyProf::CPU_TIME
+  end
+
+  def test_mode
+    RubyProf::measure_mode = RubyProf::CPU_TIME
+    assert_equal(RubyProf::CPU_TIME, RubyProf::measure_mode)
+  end
+
+  def test_cpu_time_enabled_defined
+    assert(defined?(RubyProf::CPU_TIME_ENABLED))
+  end
+
+  def test_class_methods
+    result = RubyProf.profile do
+      RubyProf::C7.hello
+    end
+
+    # Length should be greater 2:
+    #   MeasureCpuTimeTest#test_class_methods
+    #   <Class::RubyProf::C1>#hello
+    #   ....
+
+    methods = result.threads.first.methods.sort.reverse[0..1]
+    assert_equal(2, methods.length)
+
+    # Check the names
+    assert_equal('MeasureCpuTimeTest#test_class_methods', methods[0].full_name)
+    assert_equal('<Class::RubyProf::C7>#hello', methods[1].full_name)
+
+    # Check times
+    assert_in_delta(0.1, methods[0].total_time, 0.02)
+    assert_in_delta(0, methods[0].wait_time, 0.02)
+    assert_in_delta(0, methods[0].self_time, 0.02)
+
+    assert_in_delta(0.1, methods[1].total_time, 0.02)
+    assert_in_delta(0, methods[1].wait_time, 0.02)
+    assert_in_delta(0, methods[1].self_time, 0.02)
+  end
+
+  def test_instance_methods
+    result = RubyProf.profile do
+      RubyProf::C7.new.hello
+    end
+
+    methods = result.threads.first.methods.sort.reverse[0..1]
+    assert_equal(2, methods.length)
+
+    # Methods at this point:
+    #   MeasureCpuTimeTest#test_instance_methods
+    #   C7#hello
+    #   ...
+
+    names = methods.map(&:full_name)
+    assert_equal('MeasureCpuTimeTest#test_instance_methods', names[0])
+    assert_equal('RubyProf::C7#hello', names[1])
+
+
+    # Check times
+    assert_in_delta(0.2, methods[0].total_time, 0.03)
+    assert_in_delta(0, methods[0].wait_time, 0.03)
+    assert_in_delta(0, methods[0].self_time, 0.03)
+
+    assert_in_delta(0.2, methods[1].total_time, 0.03)
+    assert_in_delta(0, methods[1].wait_time, 0.03)
+    assert_in_delta(0, methods[1].self_time, 0.1)
+  end
+
+  def test_module_methods
+    result = RubyProf.profile do
+      RubyProf::C8.hello
+    end
+
+    # Methods:
+    #   MeasureCpuTimeTest#test_module_methods
+    #   M1#hello
+    #   ...
+
+    methods = result.threads.first.methods.sort.reverse[0..1]
+    assert_equal(2, methods.length)
+
+    assert_equal('MeasureCpuTimeTest#test_module_methods', methods[0].full_name)
+    assert_equal('RubyProf::M7#hello', methods[1].full_name)
+
+    # Check times
+    assert_in_delta(0.3, methods[0].total_time, 0.1)
+    assert_in_delta(0, methods[0].wait_time, 0.02)
+    assert_in_delta(0, methods[0].self_time, 0.02)
+
+    assert_in_delta(0.3, methods[1].total_time, 0.1)
+    assert_in_delta(0, methods[1].wait_time, 0.02)
+    assert_in_delta(0, methods[1].self_time, 0.1)
+  end
+
+  def test_module_instance_methods
+    result = RubyProf.profile do
+      RubyProf::C8.new.hello
+    end
+
+    # Methods:
+    #   MeasureCpuTimeTest#test_module_instance_methods
+    #   M7#hello
+    #   ...
+
+    methods = result.threads.first.methods.sort.reverse[0..1]
+    assert_equal(2, methods.length)
+    names = methods.map(&:full_name)
+    assert_equal('MeasureCpuTimeTest#test_module_instance_methods', names[0])
+    assert_equal('RubyProf::M7#hello', names[1])
+
+    # Check times
+    assert_in_delta(0.3, methods[0].total_time, 0.1)
+    assert_in_delta(0, methods[0].wait_time, 0.1)
+    assert_in_delta(0, methods[0].self_time, 0.1)
+
+    assert_in_delta(0.3, methods[1].total_time, 0.02)
+    assert_in_delta(0, methods[1].wait_time, 0.01)
+    assert_in_delta(0, methods[1].self_time, 0.1)
+  end
+
+  def test_singleton
+    c3 = RubyProf::C3.new
+
+    class << c3
+      def hello
+      end
+    end
+
+    result = RubyProf.profile do
+      c3.hello
+    end
+
+    methods = result.threads.first.methods.sort.reverse
+    assert_equal(2, methods.length)
+
+    assert_equal('MeasureCpuTimeTest#test_singleton', methods[0].full_name)
+    assert_equal('<Object::RubyProf::C3>#hello', methods[1].full_name)
+
+    assert_in_delta(0, methods[0].total_time, 0.01)
+    assert_in_delta(0, methods[0].wait_time, 0.01)
+    assert_in_delta(0, methods[0].self_time, 0.01)
+
+    assert_in_delta(0, methods[1].total_time, 0.01)
+    assert_in_delta(0, methods[1].wait_time, 0.01)
+    assert_in_delta(0, methods[1].self_time, 0.01)
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/measure_gc_runs_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/measure_gc_runs_test.rb
new file mode 100755
index 0000000..be33416
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/measure_gc_runs_test.rb
@@ -0,0 +1,32 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class MeasureGCRunsTest < TestCase
+  include MemoryTestHelper
+
+  def test_gc_runs_mode
+    RubyProf::measure_mode = RubyProf::GC_RUNS
+    assert_equal(RubyProf::GC_RUNS, RubyProf::measure_mode)
+  end
+
+  def test_gc_runs_enabled_defined
+    assert(defined?(RubyProf::GC_RUNS_ENABLED))
+  end
+
+  if RubyProf::GC_RUNS_ENABLED
+    def test_gc_runs
+      t = RubyProf.measure_gc_runs
+      assert_kind_of Integer, t
+
+      GC.enable_stats if GC.respond_to?(:enable_stats)
+      GC.start
+
+      u = RubyProf.measure_gc_runs
+      assert u > t, [t, u].inspect
+      RubyProf::measure_mode = RubyProf::GC_RUNS
+      memory_test_helper
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/measure_gc_time_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/measure_gc_time_test.rb
new file mode 100755
index 0000000..c913f7e
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/measure_gc_time_test.rb
@@ -0,0 +1,36 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class MeasureGCTimeTest < TestCase
+  include MemoryTestHelper
+
+  def test_gc_time_mode
+    RubyProf::measure_mode = RubyProf::GC_TIME
+    assert_equal(RubyProf::GC_TIME, RubyProf::measure_mode)
+  end
+
+  def test_gc_time_enabled_defined
+    assert(defined?(RubyProf::GC_TIME_ENABLED))
+  end
+
+  if RubyProf::GC_TIME_ENABLED
+    def test_gc_time
+      RubyProf::measure_mode = RubyProf::GC_TIME
+      RubyProf.enable_gc_stats_if_needed
+
+      t = RubyProf.measure_gc_time
+      assert_kind_of Float, t
+
+      GC.start
+
+      u = RubyProf.measure_gc_time
+      assert u > t, [t, u].inspect
+
+      memory_test_helper
+    ensure
+      RubyProf.disable_gc_stats_if_needed
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/measure_memory_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/measure_memory_test.rb
new file mode 100755
index 0000000..8e05972
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/measure_memory_test.rb
@@ -0,0 +1,33 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class MeasureMemoryTest < TestCase
+  include MemoryTestHelper
+
+  def test_memory_mode
+    RubyProf::measure_mode = RubyProf::MEMORY
+    assert_equal(RubyProf::MEMORY, RubyProf::measure_mode)
+  end
+
+  def test_memory_enabled_defined
+    assert(defined?(RubyProf::MEMORY_ENABLED))
+  end
+
+  if RubyProf::MEMORY_ENABLED
+    def test_memory
+      RubyProf::measure_mode = RubyProf::MEMORY
+      RubyProf.enable_gc_stats_if_needed
+      t = RubyProf.measure_memory
+      assert_kind_of Float, t
+      u = RubyProf.measure_memory
+      assert_operator u, :>, t
+      total = memory_test_helper
+      assert(total > 0, 'Should measure more than zero kilobytes of memory usage')
+      refute_equal(0, total % 1, 'Should not truncate fractional kilobyte measurements')
+    ensure
+      RubyProf.disable_gc_stats_if_needed
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/measure_process_time_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/measure_process_time_test.rb
new file mode 100755
index 0000000..2f87f79
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/measure_process_time_test.rb
@@ -0,0 +1,63 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class MeasureProcessTimeTest < TestCase
+  def setup
+    # Need to fix this for linux (windows works since PROCESS_TIME is WALL_TIME anyway)
+    RubyProf::measure_mode = RubyProf::PROCESS_TIME
+  end
+
+  def test_mode
+    assert_equal(RubyProf::PROCESS_TIME, RubyProf::measure_mode)
+  end
+
+  def test_process_time_enabled_defined
+    assert(defined?(RubyProf::PROCESS_TIME_ENABLED))
+  end
+
+  def test_primes
+    start = Process.times
+    result = RubyProf.profile do
+      run_primes(10000)
+    end
+    finish = Process.times
+
+    total_time = (finish.utime - start.utime) + (finish.stime - start.stime)
+
+    thread = result.threads.first
+    assert_in_delta(total_time, thread.total_time, 0.03)
+
+    methods = result.threads.first.methods.sort.reverse
+
+    # WTF?
+    if RUBY_VERSION =~ /^1\.9\.3/
+      assert_equal 16, methods.length
+    elsif RUBY_VERSION =~ /^2\.0/
+      assert_equal 15, methods.length
+    else # if RUBY_VERSION =~ /^2\.1/
+      assert_equal 14, methods.length
+    end
+    # puts methods.map(&:full_name).inspect
+
+    # Check times
+    assert_equal("MeasureProcessTimeTest#test_primes", methods[0].full_name)
+    assert_in_delta(total_time, methods[0].total_time, 0.02)
+    assert_in_delta(0.0, methods[0].wait_time, 0.01)
+    assert_in_delta(0.0, methods[0].self_time, 0.01)
+
+    assert_equal("Object#run_primes", methods[1].full_name)
+    assert_in_delta(total_time, methods[1].total_time, 0.02)
+    assert_in_delta(0.0, methods[1].wait_time, 0.01)
+    assert_in_delta(0.0, methods[1].self_time, 0.01)
+
+    assert_equal("Object#find_primes", methods[2].full_name)
+    assert_equal("Array#select", methods[3].full_name)
+    assert_equal("Object#is_prime", methods[4].full_name)
+    assert_equal("Integer#upto", methods[5].full_name)
+    assert_equal("Object#make_random_array", methods[6].full_name)
+    assert_equal("Array#each_index", methods[7].full_name)
+    assert_equal("Kernel#rand", methods[8].full_name)
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/measure_wall_time_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/measure_wall_time_test.rb
new file mode 100755
index 0000000..09d7e60
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/measure_wall_time_test.rb
@@ -0,0 +1,255 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class MeasureWallTimeTest < TestCase
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+  end
+
+  def test_mode
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+    assert_equal(RubyProf::WALL_TIME, RubyProf::measure_mode)
+  end
+
+  def test_wall_time_enabled_defined
+    assert(defined?(RubyProf::WALL_TIME_ENABLED))
+  end
+
+  def test_class_methods
+    result = RubyProf.profile do
+      RubyProf::C1.hello
+    end
+
+    thread = result.threads.first
+    assert_in_delta(0.1, thread.total_time, 0.01)
+
+    top_methods = thread.top_methods
+    assert_equal(1, top_methods.count)
+    assert_equal("MeasureWallTimeTest#test_class_methods", top_methods[0].full_name)
+
+    # Length should be 3:
+    #   MeasureWallTimeTest#test_class_methods
+    #   <Class::RubyProf::C1>#hello
+    #   Kernel#sleep
+
+    methods = result.threads.first.methods.sort.reverse
+    assert_equal(3, methods.length)
+
+    # Check the names
+    assert_equal('MeasureWallTimeTest#test_class_methods', methods[0].full_name)
+    assert_equal('<Class::RubyProf::C1>#hello', methods[1].full_name)
+    assert_equal('Kernel#sleep', methods[2].full_name)
+
+    # Check times
+    assert_in_delta(0.1, methods[0].total_time, 0.01)
+    assert_in_delta(0, methods[0].wait_time, 0.01)
+    assert_in_delta(0, methods[0].self_time, 0.01)
+
+    assert_in_delta(0.1, methods[1].total_time, 0.01)
+    assert_in_delta(0, methods[1].wait_time, 0.01)
+    assert_in_delta(0, methods[1].self_time, 0.01)
+
+    assert_in_delta(0.1, methods[2].total_time, 0.01)
+    assert_in_delta(0, methods[2].wait_time, 0.01)
+    assert_in_delta(0.1, methods[2].self_time, 0.01)
+  end
+
+  def test_instance_methods
+    result = RubyProf.profile do
+      RubyProf::C1.new.hello
+    end
+
+    thread = result.threads.first
+    assert_in_delta(0.2, thread.total_time, 0.01)
+
+    top_methods = thread.top_methods
+    assert_equal(1, top_methods.count)
+    assert_equal("MeasureWallTimeTest#test_instance_methods", top_methods[0].full_name)
+
+    # Methods called
+    #   MeasureWallTimeTest#test_instance_methods
+    #   Class.new
+    #   Class:Object#allocate
+    #   for Object#initialize
+    #   C1#hello
+    #   Kernel#sleep
+
+    methods = result.threads.first.methods.sort.reverse
+    assert_equal(RubyProf.ruby_2? ? 5 : 6, methods.length)
+    names = methods.map(&:full_name)
+    assert_equal('MeasureWallTimeTest#test_instance_methods', names[0])
+    assert_equal('RubyProf::C1#hello', names[1])
+    assert_equal('Kernel#sleep', names[2])
+    assert_equal('Class#new', names[3])
+
+    # order can differ
+    assert(names.include?("#{RubyProf.parent_object}#initialize"))
+    unless RubyProf.ruby_2?
+      assert(names.include?("<Class::#{RubyProf.parent_object}>#allocate"))
+    end
+
+    # Check times
+    assert_in_delta(0.2, methods[0].total_time, 0.02)
+    assert_in_delta(0, methods[0].wait_time, 0.02)
+    assert_in_delta(0, methods[0].self_time, 0.02)
+
+    assert_in_delta(0.2, methods[1].total_time, 0.02)
+    assert_in_delta(0, methods[1].wait_time, 0.02)
+    assert_in_delta(0, methods[1].self_time, 0.02)
+
+    assert_in_delta(0.2, methods[2].total_time, 0.02)
+    assert_in_delta(0, methods[2].wait_time, 0.02)
+    assert_in_delta(0.2, methods[2].self_time, 0.02)
+
+    assert_in_delta(0, methods[3].total_time, 0.01)
+    assert_in_delta(0, methods[3].wait_time, 0.01)
+    assert_in_delta(0, methods[3].self_time, 0.01)
+
+    assert_in_delta(0, methods[4].total_time, 0.01)
+    assert_in_delta(0, methods[4].wait_time, 0.01)
+    assert_in_delta(0, methods[4].self_time, 0.01)
+
+    unless RubyProf.ruby_2?
+      assert_in_delta(0, methods[5].total_time, 0.01)
+      assert_in_delta(0, methods[5].wait_time, 0.01)
+      assert_in_delta(0, methods[5].self_time, 0.01)
+    end
+  end
+
+  def test_module_methods
+    result = RubyProf.profile do
+      RubyProf::C2.hello
+    end
+
+    thread = result.threads.first
+    assert_in_delta(0.3, thread.total_time, 0.01)
+
+    top_methods = thread.top_methods
+    assert_equal(1, top_methods.count)
+    assert_equal("MeasureWallTimeTest#test_module_methods", top_methods[0].full_name)
+
+    # Methods:
+    #   MeasureWallTimeTest#test_module_methods
+    #   M1#hello
+    #   Kernel#sleep
+
+    methods = result.threads.first.methods.sort.reverse
+    assert_equal(3, methods.length)
+
+    assert_equal('MeasureWallTimeTest#test_module_methods', methods[0].full_name)
+    assert_equal('RubyProf::M1#hello', methods[1].full_name)
+    assert_equal('Kernel#sleep', methods[2].full_name)
+
+    # Check times
+    assert_in_delta(0.3, methods[0].total_time, 0.1)
+    assert_in_delta(0, methods[0].wait_time, 0.02)
+    assert_in_delta(0, methods[0].self_time, 0.02)
+
+    assert_in_delta(0.3, methods[1].total_time, 0.1)
+    assert_in_delta(0, methods[1].wait_time, 0.02)
+    assert_in_delta(0, methods[1].self_time, 0.02)
+
+    assert_in_delta(0.3, methods[2].total_time, 0.1)
+    assert_in_delta(0, methods[2].wait_time, 0.02)
+    assert_in_delta(0.3, methods[2].self_time, 0.1)
+  end
+
+  def test_module_instance_methods
+    result = RubyProf.profile do
+      RubyProf::C2.new.hello
+    end
+
+    thread = result.threads.first
+    assert_in_delta(0.3, thread.total_time, 0.01)
+
+    top_methods = thread.top_methods
+    assert_equal(1, top_methods.count)
+    assert_equal("MeasureWallTimeTest#test_module_instance_methods", top_methods[0].full_name)
+
+    # Methods:
+    #   MeasureWallTimeTest#test_module_instance_methods
+    #   Class#new
+    #   <Class::Object>#allocate
+    #   Object#initialize
+    #   M1#hello
+    #   Kernel#sleep
+
+    methods = result.threads.first.methods.sort.reverse
+    assert_equal(RubyProf.ruby_2? ? 5 : 6, methods.length)
+    names = methods.map(&:full_name)
+    assert_equal('MeasureWallTimeTest#test_module_instance_methods', names[0])
+    assert_equal('RubyProf::M1#hello', names[1])
+    assert_equal('Kernel#sleep', names[2])
+    assert_equal('Class#new', names[3])
+
+    # order can differ
+    assert(names.include?("#{RubyProf.parent_object}#initialize"))
+    unless RubyProf.ruby_2?
+      assert(names.include?("<Class::#{RubyProf.parent_object}>#allocate"))
+    end
+
+    # Check times
+    assert_in_delta(0.3, methods[0].total_time, 0.1)
+    assert_in_delta(0, methods[0].wait_time, 0.1)
+    assert_in_delta(0, methods[0].self_time, 0.1)
+
+    assert_in_delta(0.3, methods[1].total_time, 0.02)
+    assert_in_delta(0, methods[1].wait_time, 0.01)
+    assert_in_delta(0, methods[1].self_time, 0.01)
+
+    assert_in_delta(0.3, methods[2].total_time, 0.02)
+    assert_in_delta(0, methods[2].wait_time, 0.01)
+    assert_in_delta(0.3, methods[2].self_time, 0.02)
+
+    assert_in_delta(0, methods[3].total_time, 0.01)
+    assert_in_delta(0, methods[3].wait_time, 0.01)
+    assert_in_delta(0, methods[3].self_time, 0.01)
+
+    assert_in_delta(0, methods[4].total_time, 0.01)
+    assert_in_delta(0, methods[4].wait_time, 0.01)
+    assert_in_delta(0, methods[4].self_time, 0.01)
+
+    unless RubyProf.ruby_2?
+      assert_in_delta(0, methods[5].total_time, 0.01)
+      assert_in_delta(0, methods[5].wait_time, 0.01)
+      assert_in_delta(0, methods[5].self_time, 0.01)
+    end
+  end
+
+  def test_singleton
+    c3 = RubyProf::C3.new
+
+    class << c3
+      def hello
+      end
+    end
+
+    result = RubyProf.profile do
+      c3.hello
+    end
+
+    thread = result.threads.first
+    assert_in_delta(0.0, thread.total_time, 0.01)
+
+    top_methods = thread.top_methods
+    assert_equal(1, top_methods.count)
+    assert_equal("MeasureWallTimeTest#test_singleton", top_methods[0].full_name)
+
+    methods = result.threads.first.methods.sort.reverse
+    assert_equal(2, methods.length)
+
+    assert_equal('MeasureWallTimeTest#test_singleton', methods[0].full_name)
+    assert_equal('<Object::RubyProf::C3>#hello', methods[1].full_name)
+
+    assert_in_delta(0, methods[0].total_time, 0.01)
+    assert_in_delta(0, methods[0].wait_time, 0.01)
+    assert_in_delta(0, methods[0].self_time, 0.01)
+
+    assert_in_delta(0, methods[1].total_time, 0.01)
+    assert_in_delta(0, methods[1].wait_time, 0.01)
+    assert_in_delta(0, methods[1].self_time, 0.01)
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/method_elimination_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/method_elimination_test.rb
new file mode 100755
index 0000000..c312bf4
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/method_elimination_test.rb
@@ -0,0 +1,84 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+# Test data
+#     A
+#    / \
+#   B   C
+#        \
+#         B
+
+module MethodElimination
+  def self.a
+    1.times {|i| c}
+  end
+
+  def self.b
+    sleep 0.1
+  end
+
+  def self.c
+    1.times {|i| b}
+  end
+end
+
+class MethodEliminationTest < TestCase
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+  end
+
+  def test_setting_parent
+    result = RubyProf.profile do
+      1000.times { 1+1 }
+    end
+    method_infos = result.threads.first.methods.sort.reverse
+    assert(m1 = method_infos[0])
+    assert(c1 = m1.call_infos.first)
+    assert_nil(c1.parent)
+  end
+
+  def test_methods_can_be_eliminated
+    RubyProf.start
+    5.times {MethodElimination.a}
+    result = RubyProf.stop
+
+    methods = result.threads.first.methods.sort.reverse
+
+    assert_equal(6, methods.count)
+    assert_equal('MethodEliminationTest#test_methods_can_be_eliminated', methods[0].full_name)
+    assert_equal('Integer#times', methods[1].full_name)
+    assert_equal('<Module::MethodElimination>#a', methods[2].full_name)
+    assert_equal('<Module::MethodElimination>#c', methods[3].full_name)
+    assert_equal('<Module::MethodElimination>#b', methods[4].full_name)
+    assert_equal('Kernel#sleep', methods[5].full_name)
+
+    result.eliminate_methods!([/Integer#times/])
+
+    methods = result.threads.first.methods.sort.reverse
+    assert_equal(5, methods.count)
+    assert_equal('MethodEliminationTest#test_methods_can_be_eliminated', methods[0].full_name)
+    assert_equal('<Module::MethodElimination>#a', methods[1].full_name)
+    assert_equal('<Module::MethodElimination>#c', methods[2].full_name)
+    assert_equal('<Module::MethodElimination>#b', methods[3].full_name)
+    assert_equal('Kernel#sleep', methods[4].full_name)
+  end
+
+  private
+
+  def assert_method_has_been_eliminated(result, eliminated_method)
+    result.threads.each do |thread|
+      thread.methods.each do |method|
+        method.call_infos.each do |ci|
+          assert(ci.target != eliminated_method, "broken self")
+          assert(ci.parent.target != eliminated_method, "broken parent") if ci.parent
+          ci.children.each do |callee|
+            assert(callee.target != eliminated_method, "broken kid")
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/module_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/module_test.rb
new file mode 100755
index 0000000..8639b94
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/module_test.rb
@@ -0,0 +1,45 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+# Need to use wall time for this test due to the sleep calls
+RubyProf::measure_mode = RubyProf::WALL_TIME
+
+module Foo
+  def Foo::hello
+    sleep(0.5)
+  end
+end
+
+module Bar
+  def Bar::hello
+    sleep(0.5)
+    Foo::hello
+  end
+
+  def hello
+    sleep(0.5)
+    Bar::hello
+  end
+end
+
+include Bar
+
+class ModuleTest < TestCase
+  def test_nested_modules
+    result = RubyProf.profile do
+      hello
+    end
+
+    methods = result.threads.first.methods
+
+    # Length should be 5
+    assert_equal(5, methods.length)
+
+    # these methods should be in there... (hard to tell order though).
+    for name in ['ModuleTest#test_nested_modules','Bar#hello','Kernel#sleep','<Module::Bar>#hello','<Module::Foo>#hello']
+      assert methods.map(&:full_name).include?( name )
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/multi_printer_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/multi_printer_test.rb
new file mode 100755
index 0000000..d26f357
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/multi_printer_test.rb
@@ -0,0 +1,82 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+# Test data
+#     A
+#    / \
+#   B   C
+#        \
+#         B
+
+class MSTPT
+  def a
+    100.times{b}
+    300.times{c}
+    c;c;c
+  end
+
+  def b
+    sleep 0
+  end
+
+  def c
+    5.times{b}
+  end
+end
+
+class MultiPrinterTest < TestCase
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+  end
+
+  def test_all_profiles_can_be_created
+    start_time = Time.now
+    RubyProf.start
+    5.times{MSTPT.new.a}
+    result = RubyProf.stop
+    end_time = Time.now
+    expected_time = end_time - start_time
+    stack = graph = nil
+    assert_nothing_raised { stack, graph = print(result) }
+    re = Regexp.new('
+\s*<table>
+\s*<tr>
+\s*<th>Thread ID</th>
+\s*(<th>Fiber ID</th>)?
+\s*<th>Total Time</th>
+\s*</tr>
+\s*
+\s*<tr>
+\s*(<td>([\.0-9]+)</td>)?
+\s*<td><a href="#-?\d+">-?\d+</a></td>
+\s*<td>([\.0-9e]+)</td>
+\s*</tr>
+\s*
+\s*</table>')
+    assert_match(re, graph)
+    graph =~ re
+    display_time = $4.to_f
+    assert_in_delta expected_time, display_time, 0.001
+  end
+
+  private
+  def print(result)
+    test = caller.first =~ /in `(.*)'/ ? $1 : "test"
+    path = RubyProf.tmpdir
+    profile = "ruby_prof_#{test}"
+    printer = RubyProf::MultiPrinter.new(result)
+    printer.print(:path => path, :profile => profile,
+                  :threshold => 0, :min_percent => 0, :title => "ruby_prof #{test}")
+    if RUBY_PLATFORM =~ /darwin/ && ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT']=="1"
+      system("open '#{printer.stack_profile}'")
+    end
+    if GC.respond_to?(:dump_file_and_line_info)
+      GC.start
+      GC.dump_file_and_line_info("heap.dump")
+    end
+    [File.read(printer.stack_profile), File.read(printer.graph_profile)]
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/no_method_class_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/no_method_class_test.rb
new file mode 100755
index 0000000..49c4d48
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/no_method_class_test.rb
@@ -0,0 +1,15 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+# Make sure this works with no class or method
+result = RubyProf.profile do
+  sleep 1
+end
+
+methods = result.threads.first.methods
+global_method = methods.sort_by {|method| method.full_name}.first
+if global_method.full_name != 'Global#[No method]'
+  raise(RuntimeError, "Wrong method name.  Expected: Global#[No method].  Actual: #{global_method.full_name}")
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/pause_resume_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/pause_resume_test.rb
new file mode 100755
index 0000000..a546311
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/pause_resume_test.rb
@@ -0,0 +1,166 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class PauseResumeTest < TestCase
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+  end
+
+  def test_pause_resume
+    # Measured
+    RubyProf.start
+    RubyProf::C1.hello
+
+    # Not measured
+    RubyProf.pause
+    sleep 1
+    RubyProf::C1.hello
+
+    # Measured
+    RubyProf.resume
+    RubyProf::C1.hello
+
+    result = RubyProf.stop
+
+    # Length should be 3:
+    #   PauseResumeTest#test_pause_resume
+    #   <Class::RubyProf::C1>#hello
+    #   Kernel#sleep
+
+    methods = result.threads.first.methods.sort_by {|method_info| method_info.full_name}
+    # remove methods called by pause/resume
+    called_methods = ['Array#include?', 'Fixnum#==', 'Kernel#respond_to?', 'Kernel#respond_to_missing?']
+    methods.reject!{|m| called_methods.include?(m.full_name) }
+    # TODO: fix pause/resume to not include those methods in the first place
+    assert_equal(3, methods.length)
+
+    # Check the names
+    assert_equal('<Class::RubyProf::C1>#hello', methods[0].full_name)
+    assert_equal('Kernel#sleep', methods[1].full_name)
+    assert_equal('PauseResumeTest#test_pause_resume', methods[2].full_name)
+
+    # Check times
+    assert_in_delta(0.2, methods[0].total_time, 0.01)
+    assert_in_delta(0, methods[0].wait_time, 0.01)
+    assert_in_delta(0, methods[0].self_time, 0.01)
+
+    assert_in_delta(0.2, methods[1].total_time, 0.01)
+    assert_in_delta(0, methods[1].wait_time, 0.01)
+    assert_in_delta(0.2, methods[1].self_time, 0.01)
+
+    assert_in_delta(0.2, methods[2].total_time, 0.01)
+    assert_in_delta(0, methods[2].wait_time, 0.01)
+    assert_in_delta(0, methods[2].self_time, 0.01)
+  end
+
+  # pause/resume in the same frame
+  def test_pause_resume_1
+    profile = RubyProf::Profile.new(RubyProf::WALL_TIME,[])
+
+    profile.start
+    method_1a
+
+    profile.pause
+    method_1b
+
+    profile.resume
+    method_1c
+
+    result = profile.stop
+    assert_in_delta(0.6, result.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_1$/}[0].total_time, 0.05)
+  end
+  def method_1a; sleep 0.2 end
+  def method_1b; sleep 1   end
+  def method_1c; sleep 0.4 end
+
+  # pause in parent frame, resume in child
+  def test_pause_resume_2
+    profile = RubyProf::Profile.new(RubyProf::WALL_TIME,[])
+
+    profile.start
+    method_2a
+
+    profile.pause
+    sleep 0.5
+    method_2b(profile)
+
+    result = profile.stop
+    assert_in_delta(0.6, result.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_2$/}[0].total_time, 0.05)
+  end
+  def method_2a; sleep 0.2 end
+  def method_2b(profile); sleep 0.5; profile.resume; sleep 0.4 end
+
+  # pause in child frame, resume in parent
+  def test_pause_resume_3
+    profile = RubyProf::Profile.new(RubyProf::WALL_TIME,[])
+
+    profile.start
+    method_3a(profile)
+
+    sleep 0.5
+    profile.resume
+    method_3b
+
+    result = profile.stop
+    assert_in_delta(0.6, result.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_3$/}[0].total_time, 0.05)
+  end
+  def method_3a(profile); sleep 0.2; profile.pause; sleep 0.5 end
+  def method_3b; sleep 0.4 end
+
+  def test_pause_seq
+    profile = RubyProf::Profile.new(RubyProf::WALL_TIME,[])
+    profile.start ; assert !profile.paused?
+    profile.pause ; assert profile.paused?
+    profile.resume; assert !profile.paused?
+    profile.pause ; assert profile.paused?
+    profile.pause ; assert profile.paused?
+    profile.resume; assert !profile.paused?
+    profile.resume; assert !profile.paused?
+    profile.stop  ; assert !profile.paused?
+  end
+
+  def test_pause_block
+    profile = RubyProf::Profile.new(RubyProf::WALL_TIME,[])
+    profile.start
+    profile.pause
+    assert profile.paused?
+
+    times_block_invoked = 0
+    retval= profile.resume{
+      times_block_invoked += 1
+      120 + times_block_invoked
+    }
+    assert_equal 1, times_block_invoked
+    assert profile.paused?
+
+    assert_equal 121, retval, "resume() should return the result of the given block."
+
+    profile.stop
+  end
+
+  def test_pause_block_with_error
+    profile = RubyProf::Profile.new(RubyProf::WALL_TIME,[])
+    profile.start
+    profile.pause
+    assert profile.paused?
+
+    begin
+      profile.resume{ raise }
+      flunk 'Exception expected.'
+    rescue
+      assert profile.paused?
+    end
+
+    profile.stop
+  end
+
+  def test_resume_when_not_paused
+    profile = RubyProf::Profile.new(RubyProf::WALL_TIME,[])
+    profile.start ; assert !profile.paused?
+    profile.resume; assert !profile.paused?
+    profile.stop  ; assert !profile.paused?
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/prime.rb b/app/server/vendor/ruby-prof-0.15.8/test/prime.rb
new file mode 100755
index 0000000..0049a48
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/prime.rb
@@ -0,0 +1,54 @@
+# A silly little test program that finds prime numbers.  It
+# is intentionally badly designed to show off the use
+# of ruby-prof.
+#
+# Source from http://people.cs.uchicago.edu/~bomb154/154/maclabs/profilers-lab/
+
+def make_random_array(length, maxnum)
+  result = Array.new(length)
+  result.each_index do |i|
+    result[i] = rand(maxnum)
+  end
+
+  result
+end
+
+def is_prime(x)
+  y = 2
+  y.upto(x-1) do |i|
+    return false if (x % i) == 0
+  end
+  true
+end
+
+def find_primes(arr)
+  result = arr.select do |value|
+    is_prime(value)
+  end
+  result
+end
+
+def find_largest(primes)
+  largest = primes.first
+
+  # Intentionally use upto for example purposes
+  # (upto is also called from is_prime)
+  0.upto(primes.length-1) do |i|
+    prime = primes[i]
+    if prime > largest
+      largest = prime
+    end
+  end
+  largest
+end
+
+def run_primes(length=10, maxnum=1000)
+  # Create random numbers
+  random_array = make_random_array(length, maxnum)
+
+  # Find the primes
+  primes = find_primes(random_array)
+
+  # Find the largest primes
+  find_largest(primes)
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/printers_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/printers_test.rb
new file mode 100755
index 0000000..9cbd0ba
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/printers_test.rb
@@ -0,0 +1,253 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+require 'stringio'
+require 'fileutils'
+
+# --  Tests ----
+class PrintersTest < TestCase
+  def setup
+    # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+    @result = RubyProf.profile do
+      run_primes(200)
+    end
+  end
+
+  def test_printers
+    assert_nothing_raised do
+      output = ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1" ? STDOUT : StringIO.new('')
+
+      printer = RubyProf::CallInfoPrinter.new(@result)
+      printer.print(output)
+
+      printer = RubyProf::CallTreePrinter.new(@result)
+      printer.print(output)
+
+      printer = RubyProf::FlatPrinter.new(@result)
+      printer.print(output)
+
+      printer = RubyProf::FlatPrinterWithLineNumbers.new(@result)
+      printer.print(output)
+
+      printer = RubyProf::GraphHtmlPrinter.new(@result)
+      printer.print(output)
+
+      printer = RubyProf::GraphPrinter.new(@result)
+      printer.print(output)
+    end
+  end
+
+  def test_print_to_files
+    assert_nothing_raised do
+      output_dir = 'examples2'
+
+      if ENV['SAVE_NEW_PRINTER_EXAMPLES']
+        output_dir = 'examples'
+      end
+      FileUtils.mkdir_p output_dir
+
+      printer = RubyProf::DotPrinter.new(@result)
+      File.open("#{output_dir}/graph.dot", "w") {|f| printer.print(f)}
+
+      printer = RubyProf::CallStackPrinter.new(@result)
+      File.open("#{output_dir}/stack.html", "w") {|f| printer.print(f, :application => "primes")}
+
+      printer = RubyProf::MultiPrinter.new(@result)
+      printer.print(:path => "#{output_dir}", :profile => "multi", :application => "primes")
+      for file in ['graph.dot', 'multi.flat.txt', 'multi.graph.html', 'multi.grind.dat', 'multi.stack.html', 'stack.html']
+        existant_file = output_dir + '/' + file
+        assert File.size(existant_file) > 0
+      end
+    end
+  end
+
+  def test_flat_string
+    output = helper_test_flat_string(RubyProf::FlatPrinter)
+    refute_match(/prime.rb/, output)
+  end
+
+  def helper_test_flat_string(klass)
+    output = ''
+
+    printer = klass.new(@result)
+    printer.print(output)
+
+    assert_match(/Thread ID: -?\d+/i, output)
+    assert_match(/Fiber ID: -?\d+/i, output)
+    assert_match(/Total: \d+\.\d+/i, output)
+    assert_match(/Object#run_primes/i, output)
+    output
+  end
+
+  def test_flat_string_with_numbers
+    output = helper_test_flat_string RubyProf::FlatPrinterWithLineNumbers
+    assert_match(/prime.rb/, output)
+    refute_match(/ruby_runtime:0/, output)
+    assert_match(/called from/, output)
+
+    # should combine common parents
+    # 1.9 inlines it's  Fixnum#- so we don't see as many
+    assert_equal(2, output.scan(/Object#is_prime/).length)
+    refute_match(/\.\/test\/prime.rb/, output) # don't use relative paths
+  end
+
+  def test_graph_html_string
+    output = ''
+    printer = RubyProf::GraphHtmlPrinter.new(@result)
+    printer.print(output)
+
+    assert_match(/DTD HTML 4\.01/i, output)
+    assert_match( %r{<th>Total Time</th>}i, output)
+    assert_match(/Object#run_primes/i, output)
+  end
+
+  def test_graph_string
+    output = ''
+    printer = RubyProf::GraphPrinter.new(@result)
+    printer.print(output)
+
+    assert_match(/Thread ID: -?\d+/i, output)
+    assert_match(/Fiber ID: -?\d+/i, output)
+    assert_match(/Total Time: \d+\.\d+/i, output)
+    assert_match(/Object#run_primes/i, output)
+  end
+
+  def test_call_tree_string
+    output = ''
+    printer = RubyProf::CallTreePrinter.new(@result)
+    printer.print(output)
+    assert_match(/fn=Object#find_primes/i, output)
+    assert_match(/events: wall_time/i, output)
+    refute_match(/d\d\d\d\d\d/, output) # old bug looked [in error] like Object::run_primes(d5833116)
+  end
+
+  def do_nothing
+    start = Time.now
+    while(Time.now == start)
+    end
+  end
+
+  def test_all_with_small_percentiles
+    result = RubyProf.profile do
+      sleep 2
+      do_nothing
+    end
+
+    # RubyProf::CallTreePrinter doesn't "do" a min_percent
+    # RubyProf::FlatPrinter only outputs if self time > percent...
+    # RubyProf::FlatPrinterWithLineNumbers same
+    for klass in [ RubyProf::GraphPrinter, RubyProf::GraphHtmlPrinter]
+      printer = klass.new(result)
+      out = ''
+      printer.print(out, :min_percent => 0.00000001)
+      assert_match(/do_nothing/, out)
+    end
+
+  end
+
+  def test_flat_result_sorting_by_self_time_is_default
+    printer = RubyProf::FlatPrinter.new(@result)
+
+    printer.print(output = '')
+    self_times = flat_output_nth_column_values(output, 3)
+
+    assert_sorted self_times
+  end
+
+  def test_flat_result_sorting
+    printer = RubyProf::FlatPrinter.new(@result)
+
+    sort_method_with_column_number = {:total_time => 2, :self_time => 3, :wait_time => 4, :children_time => 5}
+
+    sort_method_with_column_number.each_pair do |sort_method, n|
+      printer.print(output = '', :sort_method => sort_method)
+      times = flat_output_nth_column_values(output, n)
+      assert_sorted times
+    end
+  end
+
+  def test_flat_result_with_line_numbers_sorting_by_self_time_is_default
+    printer = RubyProf::FlatPrinterWithLineNumbers.new(@result)
+
+    printer.print(output = '')
+    self_times = flat_output_nth_column_values(output, 3)
+
+    assert_sorted self_times
+  end
+
+  def test_flat_with_line_numbers_result_sorting
+    printer = RubyProf::FlatPrinterWithLineNumbers.new(@result)
+
+    sort_method_with_column_number = {:total_time => 2, :self_time => 3, :wait_time => 4, :children_time => 5}
+
+    sort_method_with_column_number.each_pair do |sort_method, n|
+      printer.print(output = '', :sort_method => sort_method)
+      times = flat_output_nth_column_values(output, n)
+      assert_sorted times
+    end
+  end
+
+  def test_graph_result_sorting_by_total_time_is_default
+    printer = RubyProf::GraphPrinter.new(@result)
+    printer.print(output = '')
+    total_times = graph_output_nth_column_values(output, 3)
+
+    assert_sorted total_times
+  end
+
+  def test_graph_results_sorting
+    printer = RubyProf::GraphPrinter.new(@result)
+
+    sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
+
+    sort_method_with_column_number.each_pair do |sort_method, n|
+      printer.print(output = '', :sort_method => sort_method)
+      times = graph_output_nth_column_values(output, n)
+      assert_sorted times
+    end
+  end
+
+  def test_graph_html_result_sorting_by_total_time_is_default
+    printer = RubyProf::GraphHtmlPrinter.new(@result)
+    printer.print(output = '')
+    total_times = graph_html_output_nth_column_values(output, 3)
+
+    assert_sorted total_times
+  end
+
+  def test_graph_html_result_sorting
+    printer = RubyProf::GraphHtmlPrinter.new(@result)
+
+    sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
+
+    sort_method_with_column_number.each_pair do |sort_method, n|
+      printer.print(output = '', :sort_method => sort_method)
+      times = graph_html_output_nth_column_values(output, n)
+      assert_sorted times
+    end
+  end
+
+  private
+  def flat_output_nth_column_values(output, n)
+    only_method_calls = output.split("\n").select { |line| line =~ /^ +\d+/ }
+    only_method_calls.collect { |line| line.split(/ +/)[n] }
+  end
+
+  def graph_output_nth_column_values(output, n)
+    only_root_calls = output.split("\n").select { |line| line =~ /^ +[\d\.]+%/ }
+    only_root_calls.collect { |line| line.split(/ +/)[n] }
+  end
+
+  def graph_html_output_nth_column_values(output, n)
+    only_root_calls = output.split('<tr class="method">')
+    only_root_calls.delete_at(0)
+    only_root_calls.collect {|line| line.scan(/[\d\.]+/)[n - 1] }
+  end
+
+  def assert_sorted array
+    array = array.map{|n| n.to_f} # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
+    assert_equal array, array.sort.reverse, "Array #{array.inspect} is not sorted"
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/rack_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/rack_test.rb
new file mode 100755
index 0000000..5819100
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/rack_test.rb
@@ -0,0 +1,20 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class FakeRackApp
+  def call(env)
+  end
+end
+
+class RackTest < TestCase
+  def test_create_print_path
+    path = Dir.mktmpdir
+    Dir.delete(path)
+
+    Rack::RubyProf.new(FakeRackApp.new, :path => path)
+
+    assert_equal(true, Dir.exist?(path))
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/recursive_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/recursive_test.rb
new file mode 100755
index 0000000..dc31737
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/recursive_test.rb
@@ -0,0 +1,211 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+# Simple recursive test
+def simple(n)
+  sleep(1)
+  n -= 1
+  return if n == 0
+  simple(n)
+end
+
+
+# More complicated recursive test
+def render_partial(i)
+  sleep(1)
+  case i
+  when 0
+    render_partial(10)
+  when 1
+    2.times do |j|
+      render_partial(j + 10)
+    end
+  end
+end
+
+def render
+  2.times do |i|
+    render_partial(i)
+  end
+end
+
+# --  Tests ----
+class RecursiveTest < TestCase
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+  end
+
+  def test_simple
+    result = RubyProf.profile do
+      simple(2)
+    end
+
+    # Remove Fixnum+, Fixnum== for less than Ruby 1.9
+    result.eliminate_methods!(%w(Fixnum#== Fixnum#-))
+
+    methods = result.threads.first.methods.sort.reverse
+    assert_equal(3, methods.length)
+
+    # Method 0: RecursiveTest#test_simple
+    method = methods[0]
+    assert_equal('RecursiveTest#test_simple', method.full_name)
+    assert_equal(1, method.called)
+    assert_in_delta(2, method.total_time, 0.1)
+    assert_in_delta(0, method.self_time, 0.01)
+    assert_in_delta(0, method.wait_time, 0.01)
+    assert_in_delta(2, method.children_time, 0.1)
+
+    assert_equal(1, method.call_infos.length)
+    call_info = method.call_infos[0]
+    assert(!call_info.recursive)
+    assert_equal('RecursiveTest#test_simple', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+
+    # Method 1: Object#simple
+    method = methods[1]
+    assert_equal('Object#simple', method.full_name)
+    assert_equal(2, method.called)
+    assert_in_delta(2, method.total_time, 0.1)
+    assert_in_delta(0, method.self_time, 0.1)
+    assert_in_delta(0, method.wait_time, 0.1)
+    assert_in_delta(2, method.children_time, 0.1)
+
+    assert_equal(2, method.call_infos.length)
+
+    call_info = method.call_infos.first
+    assert_equal(2, call_info.children.length)
+    assert_equal('RecursiveTest#test_simple->Object#simple', call_info.call_sequence)
+    assert(!call_info.recursive)
+
+    call_info = method.call_infos.last
+    assert_equal(1, call_info.children.length)
+    assert_equal('RecursiveTest#test_simple->Object#simple->Object#simple', call_info.call_sequence)
+    assert(call_info.recursive)
+
+    method = methods[2]
+    assert_equal('Kernel#sleep', method.full_name)
+    assert_equal(2, method.called)
+    assert_in_delta(2, method.total_time, 0.1)
+    assert_in_delta(2, method.self_time, 0.1)
+    assert_in_delta(0, method.wait_time, 0.1)
+    assert_in_delta(0, method.children_time, 0.1)
+
+    assert_equal(2, method.call_infos.length)
+    call_info = method.call_infos[0]
+    assert_equal('RecursiveTest#test_simple->Object#simple->Kernel#sleep', call_info.call_sequence)
+    assert_equal(0, call_info.children.length)
+    assert(!call_info.recursive)
+
+    call_info = method.call_infos[1]
+    assert_equal('RecursiveTest#test_simple->Object#simple->Object#simple->Kernel#sleep', call_info.call_sequence)
+    assert_equal(0, call_info.children.length)
+    assert(!call_info.recursive)
+  end
+
+  def test_cycle
+    result = RubyProf.profile do
+      render
+    end
+
+    methods = result.threads.first.methods.sort.reverse
+    assert_equal(5, methods.length)
+
+    method = methods[0]
+    assert_equal('RecursiveTest#test_cycle', method.full_name)
+    assert_equal(1, method.called)
+    assert_in_delta(5, method.total_time, 0.1)
+    assert_in_delta(0, method.self_time, 0.01)
+    assert_in_delta(0, method.wait_time, 0.01)
+    assert_in_delta(5, method.children_time, 0.1)
+
+    assert_equal(1, method.call_infos.length)
+    call_info = method.call_infos[0]
+    assert_equal('RecursiveTest#test_cycle', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+    assert(!call_info.recursive)
+
+    method = methods[1]
+    assert_equal('Object#render', method.full_name)
+    assert_equal(1, method.called)
+    assert_in_delta(5, method.total_time, 0.1)
+    assert_in_delta(0, method.self_time, 0.01)
+    assert_in_delta(0, method.wait_time, 0.01)
+    assert_in_delta(5, method.children_time, 0.1)
+
+    assert_equal(1, method.call_infos.length)
+    call_info = method.call_infos[0]
+    assert_equal('RecursiveTest#test_cycle->Object#render', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+    assert(!call_info.recursive)
+
+    method = methods[2]
+    assert_equal('Integer#times', method.full_name)
+    assert_equal(2, method.called)
+    assert_in_delta(5, method.total_time, 0.1)
+    assert_in_delta(0, method.self_time, 0.1)
+    assert_in_delta(0, method.wait_time, 0.1)
+    assert_in_delta(5, method.children_time, 0.1)
+
+    assert_equal(2, method.call_infos.length)
+    call_info = method.call_infos[0]
+    assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+    assert(!call_info.recursive)
+
+    call_info = method.call_infos[1]
+    assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial->Integer#times', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+    assert(call_info.recursive)
+
+    method = methods[3]
+    assert_equal('Object#render_partial', method.full_name)
+    assert_equal(5, method.called)
+    assert_in_delta(5, method.total_time, 0.1)
+    assert_in_delta(0, method.self_time, 0.1)
+    assert_in_delta(0, method.wait_time, 0.01)
+    assert_in_delta(5, method.children_time, 0.05)
+
+    assert_equal(3, method.call_infos.length)
+    call_info = method.call_infos[0]
+    assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial', call_info.call_sequence)
+    assert_equal(3, call_info.children.length)
+    assert(!call_info.recursive)
+
+    call_info = method.call_infos[1]
+    assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial->Object#render_partial', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+    assert(call_info.recursive)
+
+    call_info = method.call_infos[2]
+    assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial->Integer#times->Object#render_partial', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+    assert(call_info.recursive)
+
+    method = methods[4]
+    assert_equal('Kernel#sleep', method.full_name)
+    assert_equal(5, method.called)
+    assert_in_delta(5, method.total_time, 0.1)
+    assert_in_delta(5, method.self_time, 0.1)
+    assert_in_delta(0, method.wait_time, 0.01)
+    assert_in_delta(0, method.children_time, 0.01)
+
+    assert_equal(3, method.call_infos.length)
+    call_info = method.call_infos[0]
+    assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial->Kernel#sleep', call_info.call_sequence)
+    assert_equal(0, call_info.children.length)
+    assert(!call_info.recursive)
+
+    call_info = method.call_infos[1]
+    assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial->Object#render_partial->Kernel#sleep', call_info.call_sequence)
+    assert_equal(0, call_info.children.length)
+    assert(!call_info.recursive)
+
+    call_info = method.call_infos[2]
+    assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial->Integer#times->Object#render_partial->Kernel#sleep', call_info.call_sequence)
+    assert_equal(0, call_info.children.length)
+    assert(!call_info.recursive)
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/singleton_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/singleton_test.rb
new file mode 100755
index 0000000..c27f890
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/singleton_test.rb
@@ -0,0 +1,38 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+require 'timeout'
+
+# --  Test for bug [#5657]
+# http://rubyforge.org/tracker/index.php?func=detail&aid=5657&group_id=1814&atid=7060
+
+
+class A
+  attr_accessor :as
+  def initialize
+    @as = []
+    class << @as
+      def <<(an_a)
+        super
+      end
+    end
+  end
+
+  def <<(an_a)
+    @as << an_a
+  end
+end
+
+class SingletonTest < TestCase
+  def test_singleton
+    result = RubyProf.profile do
+      a = A.new
+      a << :first_thing
+      assert_equal(1, a.as.size)
+    end
+    printer = RubyProf::FlatPrinter.new(result)
+    output = ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1" ? STDOUT : ''
+    printer.print(output)
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/stack_printer_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/stack_printer_test.rb
new file mode 100755
index 0000000..11e6b57
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/stack_printer_test.rb
@@ -0,0 +1,78 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+# Test data
+#     A
+#    / \
+#   B   C
+#        \
+#         B
+
+class STPT
+  def a
+    100.times{b}
+    300.times{c}
+    c;c;c
+  end
+
+  def b
+    sleep 0
+  end
+
+  def c
+    5.times{b}
+  end
+end
+
+class StackPrinterTest < TestCase
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+  end
+
+  def test_stack_can_be_printed
+    start_time = Time.now
+    RubyProf.start
+    5.times{STPT.new.a}
+    result = RubyProf.stop
+    end_time = Time.now
+    expected_time = end_time - start_time
+
+    file_contents = nil
+    assert_nothing_raised { file_contents = print(result) }
+    # TODO: why are thread ids negative on travis-ci.org (32 bit build maybe?)
+    re = /Thread: (-?\d+)(, Fiber: (-?\d+))? \(100\.00% ~ ([\.0-9]+)\)/
+    assert_match(re, file_contents)
+    file_contents =~ re
+    actual_time = $4.to_f
+    assert_in_delta(expected_time, actual_time, 0.1)
+  end
+
+  def test_method_elimination
+    RubyProf.start
+    5.times{STPT.new.a}
+    result = RubyProf.stop
+    assert_nothing_raised {
+      # result.dump
+      result.eliminate_methods!([/Integer#times/])
+      # $stderr.puts "================================"
+      # result.dump
+      print(result)
+    }
+  end
+
+  private
+  def print(result)
+    test = caller.first =~ /in `(.*)'/ ? $1 : "test"
+    testfile_name = "#{RubyProf.tmpdir}/ruby_prof_#{test}.html"
+    # puts "printing to #{testfile_name}"
+    printer = RubyProf::CallStackPrinter.new(result)
+    File.open(testfile_name, "w") {|f| printer.print(f, :threshold => 0, :min_percent => 0, :title => "ruby_prof #{test}")}
+    system("open '#{testfile_name}'") if RUBY_PLATFORM =~ /darwin/ && ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT']=="1"
+    assert File.exist?(testfile_name), "#{testfile_name} does not exist"
+    assert File.readable?(testfile_name), "#{testfile_name} is no readable"
+    File.read(testfile_name)
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/stack_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/stack_test.rb
new file mode 100755
index 0000000..38bef2f
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/stack_test.rb
@@ -0,0 +1,138 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+# Test data
+#     A
+#    / \
+#   B   C
+#        \
+#         B
+
+class StackClass
+  def a
+    sleep 1
+    b
+    c
+  end
+
+  def b
+    sleep 2
+  end
+
+  def c
+    sleep 3
+    b
+  end
+end
+
+class StackTest < TestCase
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+  end
+
+  def test_call_sequence
+    c = StackClass.new
+    result = RubyProf.profile do
+      c.a
+    end
+
+    # Length should be 5:
+    #   StackTest#test_call_sequence
+    #   StackClass#a
+    #   Kernel#sleep
+    #   StackClass#c
+    #   StackClass#b
+
+    methods = result.threads.first.methods.sort.reverse
+    assert_equal(5, methods.length)
+
+    # Check StackTest#test_call_sequence
+    method = methods[0]
+    assert_equal('StackTest#test_call_sequence', method.full_name)
+    assert_equal(1, method.called)
+    assert_in_delta(8, method.total_time, 0.25)
+    assert_in_delta(0, method.wait_time, 0.01)
+    assert_in_delta(0, method.self_time, 0.01)
+    assert_in_delta(8, method.children_time, 0.25)
+    assert_equal(1, method.call_infos.length)
+
+    call_info = method.call_infos[0]
+    assert_equal('StackTest#test_call_sequence', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+
+    # Check StackClass#a
+    method = methods[1]
+    assert_equal('StackClass#a', method.full_name)
+    assert_equal(1, method.called)
+    assert_in_delta(8, method.total_time, 0.15)
+    assert_in_delta(0, method.wait_time, 0.01)
+    assert_in_delta(0, method.self_time, 0.01)
+    assert_in_delta(8, method.children_time, 0.05)
+    assert_equal(1, method.call_infos.length)
+
+    call_info = method.call_infos[0]
+    assert_equal('StackTest#test_call_sequence->StackClass#a', call_info.call_sequence)
+    assert_equal(3, call_info.children.length)
+
+    # Check Kernel#sleep
+    method = methods[2]
+    assert_equal('Kernel#sleep', method.full_name)
+    assert_equal(4, method.called)
+    assert_in_delta(8, method.total_time, 0.05)
+    assert_in_delta(0, method.wait_time, 0.01)
+    assert_in_delta(8, method.self_time, 0.05)
+    assert_in_delta(0, method.children_time, 0.05)
+    assert_equal(4, method.call_infos.length)
+
+    call_info = method.call_infos[0]
+    assert_equal('StackTest#test_call_sequence->StackClass#a->Kernel#sleep', call_info.call_sequence)
+    assert_equal(0, call_info.children.length)
+
+    call_info = method.call_infos[1]
+    assert_equal('StackTest#test_call_sequence->StackClass#a->StackClass#b->Kernel#sleep', call_info.call_sequence)
+    assert_equal(0, call_info.children.length)
+
+    call_info = method.call_infos[2]
+    assert_equal('StackTest#test_call_sequence->StackClass#a->StackClass#c->Kernel#sleep', call_info.call_sequence)
+    assert_equal(0, call_info.children.length)
+
+    call_info = method.call_infos[3]
+    assert_equal('StackTest#test_call_sequence->StackClass#a->StackClass#c->StackClass#b->Kernel#sleep', call_info.call_sequence)
+    assert_equal(0, call_info.children.length)
+
+    # Check StackClass#c
+    method = methods[3]
+    assert_equal('StackClass#c', method.full_name)
+    assert_equal(1, method.called)
+    assert_in_delta(5, method.total_time, 0.05)
+    assert_in_delta(0, method.wait_time, 0.01)
+    assert_in_delta(0, method.self_time, 0.01)
+    assert_in_delta(5, method.children_time, 0.05)
+    assert_equal(1, method.call_infos.length)
+
+    call_info = method.call_infos[0]
+    assert_equal('StackTest#test_call_sequence->StackClass#a->StackClass#c', call_info.call_sequence)
+    assert_equal(2, call_info.children.length)
+
+    # Check StackClass#b
+    method = methods[4]
+    assert_equal('StackClass#b', method.full_name)
+    assert_equal(2, method.called)
+    assert_in_delta(4, method.total_time, 0.05)
+    assert_in_delta(0, method.wait_time, 0.01)
+    assert_in_delta(0, method.self_time, 0.01)
+    assert_in_delta(4, method.children_time, 0.05)
+    assert_equal(2, method.call_infos.length)
+
+    call_info = method.call_infos[0]
+    assert_equal('StackTest#test_call_sequence->StackClass#a->StackClass#b', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+
+    call_info = method.call_infos[1]
+    assert_equal('StackTest#test_call_sequence->StackClass#a->StackClass#c->StackClass#b', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/start_stop_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/start_stop_test.rb
new file mode 100755
index 0000000..a777650
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/start_stop_test.rb
@@ -0,0 +1,112 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class StartStopTest < TestCase
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+  end
+
+  def method1
+     RubyProf.start
+     method2
+  end
+
+  def method2
+     method3
+  end
+
+  def method3
+    sleep(2)
+    @result = RubyProf.stop
+  end
+  
+  def test_extra_stop_should_raise
+    RubyProf.start
+    assert_raises(RuntimeError) do
+      RubyProf.start
+    end
+    
+    assert_raises(RuntimeError) do
+      RubyProf.profile {}
+    end
+    
+    RubyProf.stop # ok
+    assert_raises(RuntimeError) do
+      RubyProf.stop
+    end
+  end
+    
+
+  def test_different_methods
+    method1
+
+    # Ruby prof should be stopped
+    assert_equal(false, RubyProf.running?)
+
+
+    # Length should be 4:
+    #   StartStopTest#method1
+    #   StartStopTest#method2
+    #   StartStopTest#method3
+    #   Kernel#sleep
+
+    methods = @result.threads.first.methods.sort.reverse
+    assert_equal(4, methods.length)
+
+    # Check StackTest#test_call_sequence
+    method = methods[0]
+    assert_equal('StartStopTest#method1', method.full_name)
+    assert_equal(1, method.called)
+    assert_in_delta(2, method.total_time, 0.05)
+    assert_in_delta(0, method.wait_time, 0.02)
+    assert_in_delta(0, method.self_time, 0.02)
+    assert_in_delta(2, method.children_time, 0.05)
+    assert_equal(1, method.call_infos.length)
+
+    call_info = method.call_infos[0]
+    assert_equal('StartStopTest#method1', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+
+    method = methods[1]
+    assert_equal('StartStopTest#method2', method.full_name)
+    assert_equal(1, method.called)
+    assert_in_delta(2, method.total_time, 0.05)
+    assert_in_delta(0, method.wait_time, 0.02)
+    assert_in_delta(0, method.self_time, 0.02)
+    assert_in_delta(2, method.children_time, 0.05)
+    assert_equal(1, method.call_infos.length)
+
+    call_info = method.call_infos[0]
+    assert_equal('StartStopTest#method1->StartStopTest#method2', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+
+    method = methods[2]
+    assert_equal('StartStopTest#method3', method.full_name)
+    assert_equal(1, method.called)
+    assert_in_delta(2, method.total_time, 0.02)
+    assert_in_delta(0, method.wait_time, 0.02)
+    assert_in_delta(0, method.self_time, 0.02)
+    assert_in_delta(2, method.children_time, 0.02)
+    assert_equal(1, method.call_infos.length)
+
+    call_info = method.call_infos[0]
+    assert_equal('StartStopTest#method1->StartStopTest#method2->StartStopTest#method3', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+
+    method = methods[3]
+    assert_equal('Kernel#sleep', method.full_name)
+    assert_equal(1, method.called)
+    assert_in_delta(2, method.total_time, 0.02)
+    assert_in_delta(0, method.wait_time, 0.02)
+    assert_in_delta(2, method.self_time, 0.02)
+    assert_in_delta(0, method.children_time, 0.02)
+    assert_equal(1, method.call_infos.length)
+
+    call_info = method.call_infos[0]
+    assert_equal('StartStopTest#method1->StartStopTest#method2->StartStopTest#method3->Kernel#sleep', call_info.call_sequence)
+    assert_equal(0, call_info.children.length)
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/test_helper.rb b/app/server/vendor/ruby-prof-0.15.8/test/test_helper.rb
new file mode 100755
index 0000000..70eda34
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/test_helper.rb
@@ -0,0 +1,146 @@
+# encoding: UTF-8
+
+# Make RubyMine happy
+require "rubygems"
+gem "minitest"
+
+if ENV["RM_INFO"] || ENV["TEAMCITY_VERSION"]
+  if RUBY_PLATFORM =~ /(win32|mingw)/
+    gem "win32console"
+  end
+  gem "minitest-reporters"
+  require 'minitest/reporters'
+  MiniTest::Reporters.use!
+end
+
+require "minitest/pride" if RUBY_VERSION == "1.9.3"
+
+# To make testing/debugging easier, test within this source tree versus an installed gem
+dir = File.dirname(__FILE__)
+root = File.expand_path(File.join(dir, '..'))
+lib = File.expand_path(File.join(root, 'lib'))
+ext = File.expand_path(File.join(root, 'ext', 'ruby_prof'))
+
+$LOAD_PATH << lib
+$LOAD_PATH << ext
+
+require 'ruby-prof'
+require 'minitest/autorun'
+
+class TestCase < Minitest::Test
+  def assert_nothing_raised(*)
+    yield
+  end
+end
+
+require File.expand_path('../prime', __FILE__)
+
+# Some classes used in measurement tests
+module RubyProf
+  class C1
+    def C1.hello
+      sleep(0.1)
+    end
+
+    def hello
+      sleep(0.2)
+    end
+  end
+
+  module M1
+    def hello
+      sleep(0.3)
+    end
+  end
+
+  class C2
+    include M1
+    extend M1
+  end
+
+  class C3
+    def hello
+      sleep(0.4)
+    end
+  end
+
+  module M4
+    def hello
+      sleep(0.5)
+    end
+  end
+
+  module M5
+    include M4
+    def goodbye
+      hello
+    end
+  end
+
+  class C6
+    include M5
+    def test
+      goodbye
+    end
+  end
+
+  class C7
+    def self.hello
+      t = Time.now.to_f
+      while Time.now.to_f - t < 0.1; end
+    end
+
+    def hello
+      t = Time.now.to_f
+      while Time.now.to_f - t < 0.2; end
+    end
+  end
+
+  module M7
+    def hello
+      t = Time.now.to_f
+      while Time.now.to_f - t < 0.3; end
+    end
+  end
+
+  class C8
+    include M7
+    extend M7
+  end
+
+  def self.ruby_major_version
+    match = RUBY_VERSION.match(/(\d)\.(\d)/)
+    return Integer(match[1])
+  end
+
+  def self.ruby_minor_version
+    match = RUBY_VERSION.match(/(\d)\.(\d)/)
+    return Integer(match[2])
+  end
+
+  def self.parent_object
+    if ruby_major_version == 1 && ruby_minor_version == 8
+      Object
+    else
+      BasicObject
+    end
+  end
+
+  def self.ruby_2?
+    ruby_major_version == 2
+  end
+
+  # store printer output in this directory
+  def self.tmpdir
+    File.expand_path('../../tmp', __FILE__)
+  end
+end
+
+module MemoryTestHelper
+  def memory_test_helper
+    result = RubyProf.profile {Array.new}
+    total = result.threads.first.methods.inject(0) { |sum, m| sum + m.total_time }
+    assert(total < 1_000_000, 'Total should not have subtract overflow error')
+    total
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/thread_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/thread_test.rb
new file mode 100755
index 0000000..b4a79b8
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/thread_test.rb
@@ -0,0 +1,186 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+require 'timeout'
+require 'benchmark'
+
+# --  Tests ----
+class ThreadTest < TestCase
+  def setup
+    # Need to use wall time for this test due to the sleep calls
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+  end
+
+  def test_thread_count
+    RubyProf.start
+
+    thread = Thread.new do
+      sleep(1)
+    end
+
+    thread.join
+    result = RubyProf.stop
+    assert_equal(2, result.threads.length)
+  end
+
+  def test_thread_identity
+    RubyProf.start
+    sleep_thread = Thread.new do
+      sleep(1)
+    end
+    sleep_thread.join
+    result = RubyProf.stop
+
+    thread_ids = result.threads.map {|thread| thread.id}.sort
+    threads = [Thread.current, sleep_thread]
+    assert_equal(2, result.threads.length)
+
+    assert(thread_ids.include?(threads[0].object_id))
+    assert(thread_ids.include?(threads[1].object_id))
+
+    assert_instance_of(Thread, ObjectSpace._id2ref(thread_ids[0]))
+    assert(threads.include?(ObjectSpace._id2ref(thread_ids[0])))
+
+    assert_instance_of(Thread, ObjectSpace._id2ref(thread_ids[1]))
+    assert(threads.include?(ObjectSpace._id2ref(thread_ids[1])))
+  end
+
+  def test_thread_timings
+    RubyProf.start
+    thread = Thread.new do
+      sleep 0
+      # force it to hit thread.join, below, first
+      # thus forcing sleep(1), below, to be counted as (wall) self_time
+      # since we currently count time "in some other thread" as self.wait_time
+      # for whatever reason
+      sleep(1)
+    end
+    thread.join
+    result = RubyProf.stop
+
+    # Check background thread
+    assert_equal(2, result.threads.length)
+
+    rp_thread = result.threads.detect {|t| t.id == thread.object_id}
+    methods = rp_thread.methods.sort.reverse
+    # fails on travis. why?
+    # expected_methods = ["ThreadTest#test_thread_timings", "Kernel#sleep"]
+    # assert_equal(expected_methods, methods.map(&:full_name))
+
+    method = methods[0]
+    assert_equal('ThreadTest#test_thread_timings', method.full_name)
+    assert_equal(1, method.called)
+    assert_in_delta(1, method.total_time, 0.05)
+    assert_in_delta(0, method.self_time, 0.05)
+    assert_in_delta(0, method.wait_time, 0.05)
+    assert_in_delta(1, method.children_time, 0.05)
+    assert_equal(1, method.call_infos.length)
+    call_info = method.call_infos[0]
+    assert_equal('ThreadTest#test_thread_timings', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+
+    method = methods[1]
+    assert_equal('Kernel#sleep', method.full_name)
+    assert_equal(2, method.called)
+    assert_in_delta(1, method.total_time, 0.05)
+    assert_in_delta(1.0, method.self_time, 0.05)
+    assert_in_delta(0, method.wait_time, 0.05)
+    assert_in_delta(0, method.children_time, 0.05)
+
+    assert_equal(1, method.call_infos.length)
+    call_info = method.call_infos[0]
+    assert_equal('ThreadTest#test_thread_timings->Kernel#sleep', call_info.call_sequence)
+    assert_equal(0, call_info.children.length)
+
+    # Check foreground thread
+    rp_thread = result.threads.detect {|athread| athread.id == Thread.current.object_id}
+    methods = rp_thread.methods.sort.reverse
+    assert_equal(4, methods.length)
+    methods = methods.sort.reverse
+
+    method = methods[0]
+    assert_equal('ThreadTest#test_thread_timings', method.full_name)
+    # the sub calls to Object#new, when popped,
+    # cause the parent frame to be created for method #test_thread_timings, which means a +1 when it's popped in the end
+    # xxxx a test that shows it the other way, too (never creates parent frame--if that's even possible)
+    assert_equal(1, method.called)
+    assert_in_delta(1, method.total_time, 0.05)
+    assert_in_delta(0, method.self_time, 0.05)
+    assert_in_delta(0, method.wait_time, 0.05)
+    assert_in_delta(1, method.children_time, 0.05)
+
+    assert_equal(1, method.call_infos.length)
+    call_info = method.call_infos[0]
+    assert_equal('ThreadTest#test_thread_timings', call_info.call_sequence)
+    assert_equal(2, call_info.children.length)
+
+    method = methods[1]
+    assert_equal('Thread#join', method.full_name)
+    assert_equal(1, method.called)
+    assert_in_delta(1, method.total_time, 0.05)
+    assert_in_delta(0, method.self_time, 0.05)
+    assert_in_delta(1.0, method.wait_time, 0.05)
+    assert_in_delta(0, method.children_time, 0.05)
+
+    assert_equal(1, method.call_infos.length)
+    call_info = method.call_infos[0]
+    assert_equal('ThreadTest#test_thread_timings->Thread#join', call_info.call_sequence)
+    assert_equal(0, call_info.children.length)
+
+    method = methods[2]
+    assert_equal('<Class::Thread>#new', method.full_name)
+    assert_equal(1, method.called)
+    assert_in_delta(0, method.total_time, 0.05)
+    assert_in_delta(0, method.self_time, 0.05)
+    assert_in_delta(0, method.wait_time, 0.05)
+    assert_in_delta(0, method.children_time, 0.05)
+
+    assert_equal(1, method.call_infos.length)
+    call_info = method.call_infos[0]
+    assert_equal('ThreadTest#test_thread_timings-><Class::Thread>#new', call_info.call_sequence)
+    assert_equal(1, call_info.children.length)
+
+    method = methods[3]
+    assert_equal('Thread#initialize', method.full_name)
+    assert_equal(1, method.called)
+    assert_in_delta(0, method.total_time, 0.05)
+    assert_in_delta(0, method.self_time, 0.05)
+    assert_in_delta(0, method.wait_time, 0.05)
+    assert_in_delta(0, method.children_time, 0.05)
+
+    assert_equal(1, method.call_infos.length)
+    call_info = method.call_infos[0]
+    assert_equal('ThreadTest#test_thread_timings-><Class::Thread>#new->Thread#initialize', call_info.call_sequence)
+    assert_equal(0, call_info.children.length)
+  end
+
+  # useless test: what does it test?
+  def test_thread_back_and_forth
+    result = nil
+    seconds = Benchmark.realtime do
+      result = RubyProf.profile do
+        a = Thread.new { 100_000.times { sleep 0 }}
+        b = Thread.new { 100_000.times { sleep 0 }}
+        a.join
+        b.join
+      end
+    end
+    methods = result.threads.map {|thread| thread.methods}
+    timings = methods.flatten.sort
+    assert(timings[-1].total_time < seconds)
+  end
+
+  def test_thread
+    RubyProf.profile do
+      begin
+        Timeout::timeout(2) do
+          while true
+            next
+          end
+        end
+      rescue Timeout::Error
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/unique_call_path_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/unique_call_path_test.rb
new file mode 100755
index 0000000..a59ddb6
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/unique_call_path_test.rb
@@ -0,0 +1,202 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+class UniqueCallPath
+  def method_a(i)
+    if i==1
+      method_b
+    else
+      method_c
+    end
+  end
+
+  def method_b
+    method_c
+  end
+
+  def method_c
+  end
+
+  def method_k(i)
+    method_a(i)
+  end
+end
+
+
+# --  Tests ----
+class UniqueCallPathTest < TestCase
+  def test_root_method
+    unique_call_path = UniqueCallPath.new
+
+    result = RubyProf.profile do
+      unique_call_path.method_a(1)
+    end
+
+    root_methods = Array.new
+    result.threads.each do |thread|
+      thread.methods.each do | m |
+        if m.root?
+          root_methods.push(m)
+        end
+      end
+    end
+
+    assert_equal(1, root_methods.length)
+    assert_equal("UniqueCallPathTest#test_root_method", root_methods[0].full_name)
+  end
+
+  def test_root_children
+    unique_call_path = UniqueCallPath.new
+
+    result = RubyProf.profile do
+      unique_call_path.method_a(1)
+      unique_call_path.method_k(2)
+    end
+
+    root_methods = Array.new
+    result.threads.each do |thread|
+      thread.methods.each do | m |
+        if m.root?
+          root_methods.push(m)
+        end
+      end
+    end
+
+    assert_equal(1, root_methods.length)
+
+    root_children = Array.new
+    root_methods[0].children.each do | c |
+      if c.parent.target.eql?(root_methods[0])
+        root_children.push(c)
+      end
+    end
+
+    children = root_children.sort do |c1, c2|
+      c1.target.full_name <=> c2.target.full_name
+    end
+
+    assert_equal(2, children.length)
+    assert_equal("UniqueCallPath#method_a", children[0].target.full_name)
+    assert_equal("UniqueCallPath#method_k", children[1].target.full_name)
+  end
+
+  def test_children_of
+    unique_call_path = UniqueCallPath.new
+
+    result = RubyProf.profile do
+      unique_call_path.method_a(1)
+      unique_call_path.method_k(2)
+    end
+
+    root_methods = Array.new
+    result.threads.each do |thread|
+      thread.methods.each do | m |
+        if m.root?
+          root_methods.push(m)
+        end
+      end
+    end
+
+    assert_equal(1, root_methods.length)
+    method = root_methods[0]
+    assert_equal('UniqueCallPathTest#test_children_of', method.full_name)
+
+    call_info_a = nil
+    root_methods[0].children.each do | c |
+      if c.target.full_name == "UniqueCallPath#method_a"
+        call_info_a = c
+        break
+      end
+    end
+
+    assert !call_info_a.nil?
+
+    children_of_a = Array.new
+
+    call_info_a.children.each do | c |
+      if c.parent.eql?(call_info_a)
+        children_of_a.push(c)
+      end
+    end
+
+    assert_equal(2, call_info_a.target.children.length)
+
+    children_of_a = children_of_a.sort do |c1, c2|
+      c1.target.full_name <=> c2.target.full_name
+    end
+
+    assert_equal(1, children_of_a.length)
+    assert_equal("UniqueCallPath#method_b", children_of_a[0].target.full_name)
+  end
+
+  def test_id2ref
+    unique_call_path = UniqueCallPath.new
+
+    result = RubyProf.profile do
+      unique_call_path.method_a(1)
+    end
+
+    root_methods = Array.new
+    result.threads.each do |thread|
+      thread.methods.each do | m |
+        if m.root?
+          root_methods.push(m)
+        end
+      end
+    end
+
+    child = root_methods[0].children[0]
+
+    refute_equal(0, child.object_id)
+    #assert_equal(RubyProf::CallInfo.id2ref(child.id).target.full_name, child.target.full_name)
+  end
+
+  def test_unique_path
+    unique_call_path = UniqueCallPath.new
+
+    result = RubyProf.profile do
+      unique_call_path.method_a(1)
+      unique_call_path.method_k(1)
+    end
+
+    root_methods = Array.new
+    result.threads.each do |thread|
+      thread.methods.each do | m |
+        if m.root?
+          root_methods.push(m)
+        end
+      end
+    end
+
+    assert_equal(1, root_methods.length)
+
+    call_info_a = nil
+    root_methods[0].children.each do | c |
+      if c.target.full_name == "UniqueCallPath#method_a"
+        call_info_a = c
+        break
+      end
+    end
+
+    assert !call_info_a.nil?
+
+    children_of_a = Array.new
+    call_info_a.children.each do |c|
+      if c.parent.eql?(call_info_a)
+        children_of_a.push(c)
+      end
+    end
+
+    assert_equal(2, call_info_a.target.children.length)
+
+    children_of_a = children_of_a.sort do |c1, c2|
+      c1.target.full_name <=> c2.target.full_name
+    end
+
+    assert_equal(1, children_of_a.length)
+    assert_equal(1, children_of_a[0].called)
+    assert_equal("UniqueCallPath#method_b", children_of_a[0].target.full_name)
+  end
+end
diff --git a/app/server/vendor/ruby-prof-0.15.8/test/yarv_test.rb b/app/server/vendor/ruby-prof-0.15.8/test/yarv_test.rb
new file mode 100755
index 0000000..8028a62
--- /dev/null
+++ b/app/server/vendor/ruby-prof-0.15.8/test/yarv_test.rb
@@ -0,0 +1,55 @@
+#!/usr/bin/env ruby
+# encoding: UTF-8
+
+require File.expand_path('../test_helper', __FILE__)
+
+# tests for bugs reported by users
+class BugsTest < TestCase
+  def setup
+    RubyProf::measure_mode = RubyProf::WALL_TIME
+    define_methods
+  end
+
+  def test_array_push_unoptimized
+    a = nil
+    result = RubyProf.profile do
+      a = self.array_push_unoptimized
+    end
+    assert_equal 2, a.length
+    assert_equal ["BugsTest#test_array_push_unoptimized", "BugsTest#array_push_unoptimized", 'Array#<<', "Array#push"], result.threads.first.methods.map(&:full_name)
+  end
+
+  def test_array_push_optimized
+    a = nil
+    result = RubyProf.profile do
+      a = self.array_push_optimized
+    end
+    assert_equal 2, a.length
+    assert_equal ["BugsTest#test_array_push_optimized", "BugsTest#array_push_optimized", "Array#push"], result.threads.first.methods.map(&:full_name)
+  end
+
+  private
+  def define_methods
+    return if respond_to?(:array_push_optimized)
+    old_compile_option = RubyVM::InstructionSequence.compile_option
+    RubyVM::InstructionSequence.compile_option = {
+      :trace_instruction => true,
+      :specialized_instruction => false
+    }
+    self.class.class_eval <<-"EOM"
+      def array_push_unoptimized
+        a = []
+        a << 1
+        a.push 2
+      end
+    EOM
+    RubyVM::InstructionSequence.compile_option = old_compile_option
+    self.class.class_eval <<-"EOM"
+      def array_push_optimized
+        a = []
+        a << 1
+        a.push 2
+      end
+    EOM
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/.gitattributes b/app/server/vendor/rugged-0.23.3/.gitattributes
new file mode 100755
index 0000000..bcbb8a9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/.gitattributes
@@ -0,0 +1,4 @@
+test/fixtures/*.git/packed-refs text eol=lf
+test/fixtures/*.git/logs/**/* text eol=lf
+
+script/* text eol=lf
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/.gitignore b/app/server/vendor/rugged-0.23.3/.gitignore
new file mode 100755
index 0000000..429849f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/.gitignore
@@ -0,0 +1,14 @@
+*.bundle
+*.swp
+Gemfile.lock
+tmp/
+test/fixtures/testrepo.git
+ext/rugged/vendor/libgit2-dist/
+ext/rugged/vendor/mkmf.log
+ext/rugged/libgit2_embed.a
+lib/rugged/**/rugged.so
+.yardoc
+vendor/gems
+bin/
+pkg/
+rdoc/
diff --git a/app/server/vendor/rugged-0.23.3/.gitmodules b/app/server/vendor/rugged-0.23.3/.gitmodules
new file mode 100755
index 0000000..44fa6fd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "vendor/libgit2"]
+	path = vendor/libgit2
+	url = https://github.com/libgit2/libgit2.git
diff --git a/app/server/vendor/rugged-0.23.3/.travis.yml b/app/server/vendor/rugged-0.23.3/.travis.yml
new file mode 100755
index 0000000..934e0fb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/.travis.yml
@@ -0,0 +1,35 @@
+language: ruby
+cache: bundler
+
+os:
+  - linux
+  - osx
+
+rvm:
+  - 1.9.3
+  - 2.0.0
+  - 2.1.5
+  - 2.2.2
+  - ruby-head
+  - rbx-2
+
+addons:
+  apt:
+    packages:
+    - cmake
+    - libssh2-1-dev
+    - openssh-client
+    - openssh-server
+
+sudo: false
+
+matrix:
+  fast_finish: true
+  allow_failures:
+    - rvm: rbx-2
+    - rvm: ruby-head
+
+before_install:
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then ./vendor/libgit2/script/install-deps-osx.sh; fi
+
+script: script/travisbuild
diff --git a/app/server/vendor/rugged-0.23.3/CHANGELOG.md b/app/server/vendor/rugged-0.23.3/CHANGELOG.md
new file mode 100755
index 0000000..c7394c2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/CHANGELOG.md
@@ -0,0 +1,285 @@
+
+## Rugged 0.23.3 (October 6, 2015) ##
+
+*   Update bundled libgit2 to 0.23.3.
+
+    See https://github.com/libgit2/libgit2/releases/tag/v0.23.3
+    for a list of fixed issues and new features.
+
+    *Arthur Schreiber*
+
+## Rugged 0.23.2 (August 13, 2015) ##
+
+*   Update bundled libgit2 to 98f7bd289dfb172473b7d7353d4b0f0b09c67937.
+
+    *Vicent Martí*
+
+## Rugged 0.23.1 (August 11, 2015) ##
+
+*   Update bundled libgit2 to 98f7bd289dfb172473b7d7353d4b0f0b09c67937.
+
+    *Vicent Martí*
+
+## Rugged 0.23.0 (July 6, 2015) ##
+
+*   Update bundled libgit2 to 0.23.0.
+
+    See https://github.com/libgit2/libgit2/releases/tag/v0.23.0
+    for a list of fixed issues and new features.
+
+    *Arthur Schreiber*
+
+*   Add `Rugged::Repository#checkout_index`.
+
+    This allows to perform checkout from a given index.
+    It might be handy in case of manual merge conflicts resolution with user intervention.
+
+    *Dmytro Milinevskyy*
+
+*   Remove `Rugged::Submodule#reset_update_rule`, `Rugged::Submodule#reset_ignore_rule`
+    and `Rugged::Submodule#save`.
+
+    These methods were removed due to changes in the underlying libgit2 API.
+
+    *Arthur Schreiber*
+
+*   Add `Rugged::Blob#loc`.
+
+    Returns the number of lines in a blob, assuming it is plaintext.
+
+    *Vicent Martí*
+
+*   Add `Rugged::Walker.walk`.
+
+    This API allows creating a walker, performing a walk, and cleaning it up
+    immediately after the walk was performed.
+
+    *Vicent Martí*
+
+*   Add accessors for the Repository ident.
+
+    Added `Repository#ident` and `Repository#ident=` to read and set the
+    identity that is used when writing reflog entries.
+
+    *Arthur Schreiber*
+
+*   `Rugged::Remote` instances are now immutable.
+
+    * `Remote#clear_refspecs` and `Remote#save` were removed without
+      replacement.
+
+    * `Remote#url=` and `Remote#push_url=` were removed and replaced by
+      `RemoteCollection#set_url` and `RemoteCollection#set_push_url`.
+
+    * `Remote#add_push` and `Remote#add_fetch` were removed and replaced by
+      `RemoteCollection#add_push_refspec` and
+      `RemoteCollection#add_fetch_refspec`.
+
+    *Arthur Schreiber*
+
+*   Update bundled libgit2 to 9042693e283f65d9afb4906ed693a862a250664b.
+
+    *Arthur Schreiber*
+
+*   Updated the API of reflog modifying methods.
+
+    This removes both the optional `:message` as well as `:signature` options from
+    the following methods:
+
+    * `BranchCollection#create`, `BranchCollection#move`, `BranchCollection#rename`
+    * `ReferenceCollection#create`, `ReferenceCollection#rename`
+    * `Remote#push`
+    * `Repository#reset`
+
+    Additionally, the `:signature` option from `Remote#fetch` was removed as well.
+
+    The reflog message is now automatically generated and committed with the
+    the identity that is set in the Repository's configuration.
+
+    *Arthur Schreiber*
+
+*   The `:safe_create` flag was removed from `Repository#checkout_tree`.
+
+    You can use `:create` in combination with `:recreate_missing` instead.
+
+    *Arthur Schreiber*
+
+
+## Rugged 0.22.2 (May 17, 2015) ##
+
+*   Update bundled libgit2 to 0.22.2.
+
+    See https://github.com/libgit2/libgit2/releases/tag/v0.22.0,
+    https://github.com/libgit2/libgit2/releases/tag/v0.22.1 and
+    https://github.com/libgit2/libgit2/releases/tag/v0.22.2 for a list
+    of fixed issues and new features.
+
+    *Arthur Schreiber*
+
+*   Add `Rugged::Tree#count_recursive`.
+
+    This counts all blobs in a tree, recursively, with an optional limit
+    to bail early. This allows asking things like: "Are there more
+    than 1 million files in this repo?" in a very performant way.
+
+    Fixes #464.
+
+    *Andy Delcambre*
+
+*   Add missing handling of libgit2 errors in `Rugged::BranchCollection#each`
+    and `Rugged::BranchCollection#each_name`.
+
+    Fixes #457.
+
+    *aiionx*
+
+*   The `Rugged::Tree::Builder` API was changed to account for libgit2 changes.
+
+    When creating a new `Rugged::Tree::Builder` instance through
+    `Rugged::Tree::Builder.new` you have to pass a repository instance,
+    while `Rugged::Tree::Builder#write` does not take any arguments anymore.
+
+    *Vicent Martí*
+
+*   Add alternative backend support (experimental).
+
+    Bare repositories can now be stored using an alternative backend.
+
+    Fixes #410.
+
+    *Viktor Charypar*
+
+*   Replace `Remote#rename!` with `RemoteCollection#rename`.
+
+    This brings the `RemoteCollection` more in line with the API of
+    `ReferenceCollection` and `BranchCollection`.
+
+    *Arthur Schreiber*
+
+*   Remove URL validation from `Remote#url=`, `Remote#push_url=`,
+    `RemoteCollection#create_anonymous` and `RemoteCollection#create`,
+    as the underlying function `git_remote_supported_url()` was removed
+    from libgit2.
+
+    *Arthur Schreiber*
+
+*   Add `Repository#merge_bases`.
+
+    This returns an array containing all merge bases between one or
+    multiple commits.
+
+    *Arthur Schreiber*
+
+*   Add submodule support.
+
+    Expose git submodules functionality through `Rugged::Submodule` and
+    `Rugged::SubmoduleCollection`.
+
+    *Nikolai Vladimirov*
+
+*   Add `Rugged::Walker#push_range`.
+
+    *Evgeniy Sokovikov*
+
+*   Implement `Rugged::Blob::HashSignature` and `Rugged::Blob#hashsig`.
+
+    Allows similarity detection of `Rugged::Blob` instances against other blobs or
+    arbitrary strings.
+
+    *Vicent Martí*
+
+*   Add `Rugged::Repository#attributes`.
+
+    This method allows accessing the attributes for different path names as
+    specified by `.gitattributes` files.
+
+    *Vicent Martí*
+
+*   Add `Rugged::TagCollection#create_annotation`.
+
+    This method allows the creation of a tag object, but without creating
+    a tag reference.
+
+    *Charlie Somerville*
+
+*   Add `Rugged::Repository#cherrypick`.
+
+    *Arthur Schreiber*
+
+*   Add `Rugged::Repository#descendant_of?`
+
+    *Jake Douglas*
+
+*   `Rugged::Index#read_tree` now actually checks that the given object is a
+    `Rugged::Tree` instance.
+
+    Fixes #401.
+
+    *Andy Delcambre*
+
+*   Add `Rugged::Repository#expand_oids`.
+
+    This allows expanding a list of shortened SHA1 strings, optionally restricting
+    the expansion to a specific object type.
+
+    *Vicent Martí*
+
+*   Add `Rugged::Remote#check_connection`.
+
+    This is useful if one needs to check if it is possible to fetch/push
+    from/to the remote.
+
+    Basically, it is analogue to `git fetch --dry-run` and `git push --dry-run`.
+
+    *Dmitry Medvinsky*
+
+*   Remove defunct `Rugged::Diff::Line#hunk` and `Rugged::Diff::Line#owner`.
+
+    Fixes #390.
+
+    *Arthur Schreiber*
+
+*   Remove `Rugged::Diff#tree` and change `Rugged::Diff#owner` to return the
+    repository that the `Rugged::Diff` object belongs to.
+
+    We need to keep a reference from the `Rugged::Diff` to the repository to
+    ensure that the underlying libgit2 data does not get freed accidentally.
+
+    Fixes #389.
+
+    *Arthur Schreiber*
+
+*   Add `#additions` and `#deletions` to `Rugged::Patch`.
+
+    *Mindaugas Mozūras*
+
+
+## Rugged 0.21.4 (January 18, 2015) ##
+
+*   Update bundled libgit2 to 0.21.4.
+
+    See https://github.com/libgit2/libgit2/releases/tag/v0.21.4 for a list
+    of fixed issues.
+
+    *Arthur Schreiber*
+
+
+## Rugged 0.21.3 (December 18, 2014) ##
+
+*   Update bundled libgit2 to 0.21.3.
+
+    See https://github.com/libgit2/libgit2/releases/tag/v0.21.3 for a list
+    of fixed issues.
+
+    *Arthur Schreiber*
+
+
+## Rugged 0.21.2 (November 16, 2014) ##
+
+*   Update bundled libgit2 to 0.21.2 (from 0.21.0).
+
+    See https://github.com/libgit2/libgit2/releases/tag/v0.21.1 and
+    https://github.com/libgit2/libgit2/releases/tag/v0.21.2 for a list
+    of fixed issues.
+
+    *Arthur Schreiber*
diff --git a/app/server/vendor/rugged-0.23.3/Gemfile b/app/server/vendor/rugged-0.23.3/Gemfile
new file mode 100755
index 0000000..7463cca
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/Gemfile
@@ -0,0 +1,7 @@
+source "http://rubygems.org"
+
+platforms :rbx do
+  gem 'rubysl', '~> 2.0'
+end
+
+gemspec
diff --git a/app/server/vendor/rugged-0.23.3/LICENSE b/app/server/vendor/rugged-0.23.3/LICENSE
new file mode 100755
index 0000000..42fc3db
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/LICENSE
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2014 GitHub, Inc
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/app/server/vendor/rugged-0.23.3/README.md b/app/server/vendor/rugged-0.23.3/README.md
new file mode 100755
index 0000000..f811d0f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/README.md
@@ -0,0 +1,619 @@
+# Rugged
+**libgit2 bindings in Ruby**
+
+Rugged is a library for accessing [libgit2](https://github.com/libgit2/libgit2) in Ruby. It gives you the speed and
+portability of libgit2 with the beauty of the Ruby language.
+
+### libgit2
+
+libgit2 is a pure C implementation of the Git core methods. It's designed to be
+fast and portable. For more information about libgit2,
+[check out libgit2's website](http://libgit2.github.com) or browse the
+[libgit2 organization](https://github.com/libgit2) on GitHub.
+
+## Install
+
+Rugged is a self-contained gem. You can install it by running:
+
+    $ gem install rugged
+
+You need to have CMake and `pkg-config` installed on your system to be able to build the included version of `libgit2`. On OS X, after installing [Homebrew](http://brew.sh/), you can get CMake with:
+```bash
+$ brew install cmake
+```
+
+If you want to build Rugged with HTTPS and SSH support, check out the list of optional [libgit2 dependencies](https://github.com/libgit2/libgit2#optional-dependencies).
+
+If you're using bundler and want to bundle `libgit2` with Rugged, you can use the `:submodules` option:
+
+```ruby
+gem 'rugged', git: 'git://github.com/libgit2/rugged.git', submodules: true
+```
+
+To load Rugged, you'll usually want to add something like this:
+
+```ruby
+require 'rugged'
+```
+
+### Use the system provided libgit2
+
+By default, Rugged builds and uses a bundled version of libgit2. If you
+want to use the system library instead, you can install rugged as follows:
+
+```
+gem install rugged -- --use-system-libraries
+```
+
+Or if you are using bundler:
+
+```
+bundle config build.rugged --use-system-libraries
+bundle install
+```
+
+However, note that Rugged does only support specific versions of libgit2.
+
+## Usage
+
+Rugged gives you access to the many parts of a Git repository. You can read and
+write objects, walk a tree, access the staging area, and lots more. Let's look
+at each area individually.
+
+### Repositories
+
+#### Instantiation
+
+The repository is naturally central to Git. Rugged has a `Repository` class that
+you can instantiate with a path to open an existing repository :
+
+```ruby
+repo = Rugged::Repository.new('path/to/my/repository')
+# => #<Rugged::Repository:2228536260 {path: "path/to/my/repository/.git/"}>
+```
+
+You can create a new repository with `init_at`. Add a second parameter `:bare` to make a bare repository:
+
+```ruby
+Rugged::Repository.init_at('.', :bare)
+```
+
+You can also let Rugged discover the path to the .git directory if you give it a
+subdirectory.
+
+```ruby
+Rugged::Repository.discover("/Users/me/projects/repo/lib/subdir/")
+# => "/Users/me/projects/repo/.git/"
+```
+
+Once your Repository instantiated (in the following examples, as `repo`), you
+can access or modify it.
+
+#### Accessing a Repository
+
+```ruby
+# Does the given SHA1 exist in this repository?
+repo.exists?('07b44cbda23b726e5d54e2ef383495922c024202')
+# => true
+
+# Boolean repository state values:
+repo.bare?
+# => false
+repo.empty?
+# => true
+repo.head_unborn?
+# => false
+repo.head_detached?
+# => false
+
+# Path accessors
+repo.path
+# => "path/to/my/repository/.git/"
+repo.workdir
+# => "path/to/my/repository/"
+
+# The HEAD of the repository.
+ref = repo.head
+# => #<Rugged::Reference:2228467240 {name: "refs/heads/master", target:  #<Rugged::Commit:2228467250 {message: "helpful message", tree: #<Rugged::Tree:2228467260 {oid: 5d6f29220a0783b8085134df14ec4d960b6c3bf2}>}>
+
+# From the returned ref, you can also access the `name`, `target`, and target SHA:
+ref.name
+# => "refs/heads/master"
+ref.target
+# => #<Rugged::Commit:2228467250 {message: "helpful message", tree: #<Rugged::Tree:2228467260 {oid: 5d6f29220a0783b8085134df14ec4d960b6c3bf2}>}>
+ref.target_id
+# => "2bc6a70483369f33f641ca44873497f13a15cde5"
+
+# Reading an object
+object = repo.read('a0ae5566e3c8a3bddffab21022056f0b5e03ef07')
+# => #<Rugged::OdbObject:0x109a64780>
+object.len
+# => 237
+object.data
+# => "tree 76f23f186076fc291742816721ea8c3e95567241\nparent 8e3c5c52b8f29da0adc7e8be8a037cbeaea6de6b\nauthor Vicent Mart\303\255 <tanoku at gmail.com> 1333859005 +0200\ncommitter Vicent Mart\303\255 <tanoku at gmail.com> 1333859005 +0200\n\nAdd `Repository#blob_at`\n"
+object.type
+# => :commit
+```
+
+#### Writing to a Repository
+
+There's a few ways to write to a repository. To write directly from your
+instantiated repository object:
+
+```ruby
+sha = repo.write(content, type)
+```
+
+You can also use the `Commit` object directly to craft a commit; this is a bit
+more high-level, so it may be preferable:
+
+```ruby
+oid = repo.write("This is a blob.", :blob)
+index = repo.index
+index.read_tree(repo.head.target.tree)
+index.add(:path => "README.md", :oid => oid, :mode => 0100644)
+
+options = {}
+options[:tree] = index.write_tree(repo)
+
+options[:author] = { :email => "testuser at github.com", :name => 'Test Author', :time => Time.now }
+options[:committer] = { :email => "testuser at github.com", :name => 'Test Author', :time => Time.now }
+options[:message] ||= "Making a commit via Rugged!"
+options[:parents] = repo.empty? ? [] : [ repo.head.target ].compact
+options[:update_ref] = 'HEAD'
+
+Rugged::Commit.create(repo, options)
+```
+
+---
+
+### Objects
+
+`Object` is the main object class - it shouldn't be created directly, but all of
+these methods should be useful in their derived classes.
+
+```ruby
+obj = repo.lookup(sha)
+obj.oid  # object sha
+obj.type # One of :commit, :tree, :blob or :tag
+
+robj = obj.read_raw
+str  = robj.data
+int  = robj.len
+```
+
+There are four base object types in Git: **blobs**, **commits**, **tags**, and
+**trees**. Each of these object types have a corresponding class within Rugged.
+
+### Commit Objects
+
+```ruby
+commit = repo.lookup('a0ae5566e3c8a3bddffab21022056f0b5e03ef07')
+# => #<Rugged::Commit:2245304380>
+
+commit.message
+# => "Add `Repository#blob_at`\n"
+
+commit.time
+# => Sat Apr 07 21:23:25 -0700 2012
+
+commit.author
+# => {:email=>"tanoku at gmail.com", :name=>"Vicent Mart\303\255", :time=>Sun Apr 08 04:23:25 UTC 2012}
+
+commit.tree
+# => #<Rugged::Tree:2245269740>
+
+commit.parents
+# => [#<Rugged::Commit:2245264600 {message: "Merge pull request #47 from isaac/remotes\n\nAdd Rugged::Repository#remotes", tree: #<Rugged::Tree:2245264240 {oid: 6a2aee58a41fa007d07aa55565e2231f9b39b4a9}>]
+```
+
+You can also write new objects to the database this way:
+
+```ruby
+author = {:email=>"tanoku at gmail.com", :time=>Time.now, :name=>"Vicent Mart\303\255"}
+
+Rugged::Commit.create(r,
+	:author => author,
+	:message => "Hello world\n\n",
+	:committer => author,
+	:parents => ["2cb831a8aea28b2c1b9c63385585b864e4d3bad1"],
+	:tree => some_tree,
+	:update_ref => "HEAD") #=> "f148106ca58764adc93ad4e2d6b1d168422b9796"
+```
+
+### Tag Objects
+
+```ruby
+tag  = repo.lookup(tag_sha)
+
+object = tag.target
+sha    = tag.target.oid
+str    = tag.target_type # :commit, :tag, :blob
+str    = tag.name        # "v1.0"
+str    = tag.message
+person = tag.tagger
+```
+
+### Tree Objects
+
+```ruby
+tree = repo.lookup('779fbb1e17e666832773a9825875300ea736c2da')
+# => #<Rugged::Tree:2245194360>
+
+# number of tree entries
+tree.count
+
+tree[0]           # or...
+tree.first        # or...
+tree.get_entry(0)
+# => {:type=>:blob, :oid=>"99e7edb53db9355f10c6f2dfaa5a183f205d93bf", :filemode=>33188, :name=>".gitignore"}
+```
+
+The tree object is an Enumerable, so you can also do stuff like this:
+
+```ruby
+tree.each { |e| puts e[:oid] }
+tree.sort { |a, b| a[:oid] <=> b[:oid] }.map { |e| e[:name] }.join(':')
+```
+
+And there are some Rugged-specific methods, too:
+
+```ruby
+tree.each_tree { |entry| puts entry[:name] }  # list subdirs
+tree.each_blob { |entry| puts entry[:name] }  # list only files
+```
+
+You can also write trees with the `TreeBuilder`:
+
+```ruby
+oid = repo.write("This is a blob.", :blob)
+builder = Rugged::Tree::Builder.new(repo)
+builder << { :type => :blob, :name => "README.md", :oid => oid, :filemode => 0100644 }
+
+options = {}
+options[:tree] = builder.write
+
+options[:author] = { :email => "testuser at github.com", :name => 'Test Author', :time => Time.now }
+options[:committer] = { :email => "testuser at github.com", :name => 'Test Author', :time => Time.now }
+options[:message] ||= "Making a commit via Rugged!"
+options[:parents] = repo.empty? ? [] : [ repo.head.target ].compact
+options[:update_ref] = 'HEAD'
+
+Rugged::Commit.create(repo, options)
+```
+
+### Blob Objects
+
+Blob objects represent the data in the files of a Tree Object.
+
+```ruby
+blob = repo.lookup('e1253910439ea902cf49be8a9f02f3c08d89ac73')
+blob.content # => Gives you the content of the blob.
+```
+
+#### Streaming Blob Objects
+
+There is currently no way to stream data from a blob, because `libgit2` itself does not (yet) support
+streaming blobs out of the git object database. While there are hooks and interfaces for supporting it,
+the default file system backend always loads the entire blob contents into memory. 
+
+If you need to access a Blob object through an IO-like API, you can wrap it with the `StringIO` class.
+Note that the only advantage here is a stream-compatible interface, the complete blob object will still
+be loaded into memory. Below is an example for streaming a Blob using the Sinatra framework:
+
+```ruby
+# Sinatra endpoint
+get "/blobs/:sha" do
+  repo = Rugged::Repository.new(my_repo_path)
+  blob = repo.lookup params[:sha]
+
+  headers({
+    "Vary" => "Accept",
+    "Connection" => "keep-alive",
+    "Transfer-Encoding" => "chunked",
+    "Content-Type" => "application/octet-stream",
+  })
+
+  stream do |out|
+    StringIO.new(blob.content).each(8000) do |chunk|
+      out << chunk
+    end
+  end
+end
+```
+
+---
+
+### Commit Walker
+
+`Rugged::Walker` is a class designed to help you traverse a set of commits over
+a repository.
+
+You first push head SHAs onto the walker, and then call next to get a list of
+the reachable commit objects one at a time. You can also `hide()` commits if you
+are not interested in anything beneath them (useful in situations like when
+you're running something like `git log master ^origin/master`).
+
+```ruby
+walker = Rugged::Walker.new(repo)
+walker.sorting(Rugged::SORT_TOPO | Rugged::SORT_REVERSE) # optional
+walker.push(hex_sha_interesting)
+walker.hide(hex_sha_uninteresting)
+walker.each { |c| puts c.inspect }
+walker.reset
+```
+
+---
+
+### Index ("staging") area
+
+We can inspect and manipulate the Git Index as well. To work with the index
+inside an existing repository, instantiate it by using the `Repository.index`
+method instead of manually opening the Index by its path.
+
+```ruby
+index = Rugged::Index.new(path)
+
+# Re-read the index file from disk.
+index.reload
+
+# Count up index entries.
+count = index.count
+
+# The collection of index entries.
+index.entries
+
+# Iterating over index entries.
+index.each { |i| puts i.inspect }
+
+# Get a particular entry in the index.
+index[path]
+
+# Unstage.
+index.remove(path)
+
+# Stage. Also updates existing entry if there is one.
+index.add(ientry)
+
+# Stage. Create ientry from file in path, updates the index.
+index.add(path)
+```
+
+---
+
+### Refs
+
+You can access references through the `Rugged::ReferenceCollection` object returned by `Repository#references`.
+
+```ruby
+ref = repo.references["refs/heads/master"]
+
+sha = ref.target_id
+str = ref.type   # :direct
+str = ref.name   # "refs/heads/master"
+```
+
+You can also easily iterate over all references:
+
+```ruby
+repo.references.each do |ref|
+  puts ref.name
+end
+```
+
+Or only over references that match the given pattern (glob):
+
+```ruby
+repo.references.each("refs/tags/*") do |ref|
+  puts ref.name
+end
+```
+
+It is also easy to create, update, rename or delete a reference:
+
+```ruby
+ref = repo.references.create("refs/heads/unit_test", some_commit_sha)
+
+repo.references.update(ref, new_sha) # or...
+repo.references.update("refs/heads/unit_test", new_sha)
+
+repo.references.rename(ref, "refs/heads/blead") # or...
+repo.references.rename("refs/heads/unit_test", "refs/heads/blead")
+
+repo.references.delete(ref) # or...
+repo.references.delete("refs/heads/unit_test") # or...
+```
+
+Finally, you can access the reflog for any branch:
+
+```ruby
+ref = repo.references["refs/heads/master"]
+entry = ref.log.first
+sha   = entry[:id_old]
+sha   = entry[:id_new]
+str   = entry[:message]
+prsn  = entry[:committer]
+```
+
+---
+
+### Branches
+
+The `Rugged::BranchCollection` object returned by `Repository#branches` will help
+you with all of your branch-related needs.
+
+Iterate over all branches:
+
+```ruby
+repo.branches.each_name().sort
+# => ["master", "origin/HEAD", "origin/master", "origin/packed"]
+
+repo.branches.each_name(:local).sort
+# => ["master"]
+
+repo.branches.each_name(:remote).sort
+# => ["origin/HEAD", "origin/master", "origin/packed"]
+```
+
+Look up branches and get attributes:
+
+```ruby
+branch = repo.branches["master"]
+branch.name # => 'master'
+branch.canonical_name # => 'refs/heads/master'
+```
+
+Look up the id for the target of a branch:
+
+```ruby
+repo.branches["master"].target_id
+# => "36060c58702ed4c2a40832c51758d5344201d89a"
+```
+
+Creation and deletion:
+
+```ruby
+branch = repo.branches.create("test_branch", "HEAD")
+
+repo.branches.rename("test_branch", "new_branch") # or...
+repo.branches.rename("refs/heads/test_branch", "new_branch") # or...
+repo.branches.rename(ref, "new_branch") # or...
+
+repo.branches.delete("test_branch") # or...
+repo.branches.delete("refs/heads/test_branch") # or...
+repo.branches.delete(ref) # or...
+```
+
+---
+
+### Diffs
+
+There are various ways to get hands on diffs:
+
+```ruby
+# Diff between two subsequent commits
+diff_commits = commit_object.parents[0].diff(commit_object)
+
+# Diff between two tree objects
+diff_trees = tree_object_a.diff(tree_object_b)
+
+# Diff between index/staging and current working directory
+diff_index = repository.index.diff
+
+# Diff between index/staging and another diffable (commit/tree/index)
+diff_index_diffable = repository.index.diff(some_diffable)
+```
+
+When you already have a diff object, you can examine it:
+
+```ruby
+# Get patch
+diff.patch
+=> "diff --git a/foo1 b/foo1\nnew file mode 100644\nindex 0000000..81b68f0\n--- /dev/null\n+++ b/foo1\n@@ -0,0 +1,2 @@\n+abc\n+add line1\ndiff --git a/txt1 b/txt1\ndeleted file mode 100644\nindex 81b68f0..0000000\n--- a/txt1\n+++ /dev/null\n@@ -1,2 +0,0 @@\n-abc\n-add line1\ndiff --git a/txt2 b/txt2\nindex a7bb42f..a357de7 100644\n--- a/txt2\n+++ b/txt2\n@@ -1,2 +1,3 @@\n abc2\n add line2-1\n+add line2-2\n"
+
+# Get delta (faster, if you only need information on what files changed)
+diff.each_delta{ |d| puts d.inspect }
+#<Rugged::Diff::Delta:70144372137380 {old_file: {:oid=>"0000000000000000000000000000000000000000", :path=>"foo1", :size=>0, :flags=>6, :mode=>0}, new_file: {:oid=>"81b68f040b120c9627518213f7fc317d1ed18e1c", :path=>"foo1", :size=>14, :flags=>6, :mode=>33188}, similarity: 0, status: :added>
+#<Rugged::Diff::Delta:70144372136540 {old_file: {:oid=>"81b68f040b120c9627518213f7fc317d1ed18e1c", :path=>"txt1", :size=>14, :flags=>6, :mode=>33188}, new_file: {:oid=>"0000000000000000000000000000000000000000", :path=>"txt1", :size=>0, :flags=>6, :mode=>0}, similarity: 0, status: :deleted>
+#<Rugged::Diff::Delta:70144372135780 {old_file: {:oid=>"a7bb42f71183c162efea5e4c80597437d716c62b", :path=>"txt2", :size=>17, :flags=>6, :mode=>33188}, new_file: {:oid=>"a357de7d870823acc3953f1b2471f9c18d0d56ea", :path=>"txt2", :size=>29, :flags=>6, :mode=>33188}, similarity: 0, status: :modified>
+
+# Detect renamed files
+# Note that the status field changed from :added/:deleted to :renamed
+diff.find_similar!
+diff.each_delta{ |d| puts d.inspect }
+#<Rugged::Diff::Delta:70144372230920 {old_file: {:oid=>"81b68f040b120c9627518213f7fc317d1ed18e1c", :path=>"txt1", :size=>14, :flags=>6, :mode=>33188}, new_file: {:oid=>"81b68f040b120c9627518213f7fc317d1ed18e1c", :path=>"foo1", :size=>14, :flags=>6, :mode=>33188}, similarity: 100, status: :renamed>
+#<Rugged::Diff::Delta:70144372230140 {old_file: {:oid=>"a7bb42f71183c162efea5e4c80597437d716c62b", :path=>"txt2", :size=>17, :flags=>6, :mode=>33188}, new_file: {:oid=>"a357de7d870823acc3953f1b2471f9c18d0d56ea", :path=>"txt2", :size=>29, :flags=>6, :mode=>33188}, similarity: 0, status: :modified>
+
+# Merge one diff into another (mutating the first one)
+diff1.merge!(diff2)
+
+# Write a patch into a file (or any other object responding to write)
+# Note that the patch as in diff.patch will be written, it won't be applied
+file = File.open('/some/file', 'w')
+diff.write_patch(file)
+file.close
+```
+
+---
+
+### Config files
+
+It's also easy to read and manipulate the Git config file data with Rugged.
+
+```ruby
+# Read values
+repo.config['core.bare']
+
+# Set values
+repo.config['user.name'] = true
+
+# Delete values
+repo.config.delete('user.name')
+```
+
+---
+
+### General methods
+
+Rugged also includes a general library for handling basic Git operations. One of
+these is converting a raw sha (20 bytes) into a readable hex sha (40
+characters).
+
+```ruby
+Rugged.hex_to_raw('bfde59cdd0dfac1d892814f66a95641abd8a1faf')
+# => "\277\336Y\315\320\337\254\035\211(\024\366j\225d\032\275\212\037\257"
+
+Rugged.raw_to_hex("\277\336Y\315\320\337\254\035\211(\024\366j\225d\032\275\212\037\257")
+=> "bfde59cdd0dfac1d892814f66a95641abd8a1faf"
+```
+
+---
+
+### Alternative backends
+
+You can store bare repositories in alternative backends instead of storing on disk. (see
+`redbadger/rugged-redis` for an example of how a rugged backend works).
+
+```ruby
+a_backend = Rugged::InMemory::Backend.new(opt1: 'setting', opt2: 'setting')
+
+repo = Rugged::Repository.init_at('repo_name', :bare, backend: a_backend)
+
+# or
+
+repo = Rugged::Repository.bare('repo_name', backend: a_backend)
+```
+---
+
+## Contributing
+
+Fork libgit2/rugged on GitHub, make it awesomer (preferably in a branch named
+for the topic), send a pull request.
+
+
+## Development
+
+Simply clone and install:
+
+    $ git clone https://github.com/libgit2/rugged.git
+    $ cd rugged
+    $ bundle install
+    $ rake compile
+    $ rake test
+
+## Support
+
+We encourage you to use StackOverflow for any questions or concerns regarding Rugged. Please tag your questions with the [rugged](http://stackoverflow.com/questions/tagged/rugged) keyword.
+
+For bug reports, please open a ticket on the GitHub [issue tracker](https://github.com/libgit2/rugged/issues).
+
+## Authors
+
+* Vicent Marti <tanoku at gmail.com>
+* Scott Chacon <schacon at gmail.com>
+* Arthur Schreiber <schreiber.arthur at gmail.com>
+
+
+## License
+
+MIT. See LICENSE file.
diff --git a/app/server/vendor/rugged-0.23.3/Rakefile b/app/server/vendor/rugged-0.23.3/Rakefile
new file mode 100755
index 0000000..9fdd909
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/Rakefile
@@ -0,0 +1,67 @@
+require 'rake/testtask'
+
+begin
+  require 'rake/extensiontask'
+rescue LoadError
+  abort <<-error
+  rake-compile is missing; Rugged depends on rake-compiler to build the C wrapping code.
+
+  Install it by running `gem i rake-compiler`
+error
+end
+
+gemspec = Gem::Specification::load(File.expand_path('../rugged.gemspec', __FILE__))
+
+Gem::PackageTask.new(gemspec) do |pkg|
+end
+
+Rake::ExtensionTask.new('rugged', gemspec) do |r|
+  r.lib_dir = 'lib/rugged'
+end
+
+desc "checkout libgit2 source"
+task :checkout do
+  if !ENV['CI_BUILD']
+    sh "git submodule update --init"
+  end
+end
+Rake::Task[:compile].prerequisites.insert(0, :checkout)
+
+namespace :clean do
+  task :libgit2 do
+    FileUtils.rm_rf("vendor/libgit2/build")
+  end
+end
+Rake::Task[:clean].prerequisites << "clean:libgit2"
+
+desc "Open an irb session preloaded with Rugged"
+task :console do
+  exec "script/console"
+end
+
+#
+# Tests
+#
+task :default => [:compile, :test]
+
+task :cover do
+  ruby 'test/coverage/cover.rb'
+end
+
+Rake::TestTask.new do |t|
+  t.libs << 'lib' << 'test'
+  t.pattern = 'test/**/*_test.rb'
+  t.verbose = false
+  t.warning = true
+end
+
+begin
+  require 'rdoc/task'
+  Rake::RDocTask.new do |rdoc|
+    rdoc.rdoc_dir = 'rdoc'
+    rdoc.rdoc_files.include('ext/**/*.c')
+    rdoc.rdoc_files.include('lib/**/*.rb')
+  end
+rescue LoadError
+end
+
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/extconf.rb b/app/server/vendor/rugged-0.23.3/ext/rugged/extconf.rb
new file mode 100755
index 0000000..764b33f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/extconf.rb
@@ -0,0 +1,93 @@
+require 'mkmf'
+
+RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
+
+$CFLAGS << " #{ENV["CFLAGS"]}"
+$CFLAGS << " -g"
+$CFLAGS << " -O3" unless $CFLAGS[/-O\d/]
+$CFLAGS << " -Wall -Wno-comment"
+
+def sys(cmd)
+  puts " -- #{cmd}"
+  unless ret = xsystem(cmd)
+    raise "ERROR: '#{cmd}' failed"
+  end
+  ret
+end
+
+if !(MAKE = find_executable('gmake') || find_executable('make'))
+  abort "ERROR: GNU make is required to build Rugged."
+end
+
+CWD = File.expand_path(File.dirname(__FILE__))
+LIBGIT2_DIR = File.join(CWD, '..', '..', 'vendor', 'libgit2')
+
+if arg_config("--use-system-libraries", !!ENV['RUGGED_USE_SYSTEM_LIBRARIES'])
+  puts "Building Rugged using system libraries.\n"
+
+  dir_config('git2').any? or pkg_config('libgit2')
+
+  major = minor = nil
+
+  File.readlines(File.join(LIBGIT2_DIR, "include", "git2", "version.h")).each do |line|
+    if !major && (matches = line.match(/^#define LIBGIT2_VER_MAJOR ([0-9]+)$/))
+      major = matches[1]
+      next
+    end
+
+    if !minor && (matches = line.match(/^#define LIBGIT2_VER_MINOR ([0-9]+)$/))
+      minor = matches[1]
+      next
+    end
+
+    break if major && minor
+  end
+
+  try_compile(<<-SRC) or abort "libgit2 version is not compatible, expected ~> #{major}.#{minor}.0"
+#include <git2/version.h>
+
+#if LIBGIT2_VER_MAJOR != #{major} || LIBGIT2_VER_MINOR != #{minor}
+#error libgit2 version is not compatible
+#endif
+  SRC
+else
+  if !find_executable('cmake')
+    abort "ERROR: CMake is required to build Rugged."
+  end
+
+  if !find_executable('pkg-config')
+    abort "ERROR: pkg-config is required to build Rugged."
+  end
+
+  Dir.chdir(LIBGIT2_DIR) do
+    Dir.mkdir("build") if !Dir.exists?("build")
+
+    Dir.chdir("build") do
+      sys("cmake .. -DBUILD_CLAR=OFF -DTHREADSAFE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS=-fPIC -DCMAKE_BUILD_TYPE=RelWithDebInfo -G \"Unix Makefiles\"")
+      sys(MAKE)
+
+      pcfile = File.join(LIBGIT2_DIR, "build", "libgit2.pc")
+      $LDFLAGS << " " + `pkg-config --libs --static #{pcfile}`.strip
+    end
+  end
+
+  # Prepend the vendored libgit2 build dir to the $DEFLIBPATH.
+  #
+  # By default, $DEFLIBPATH includes $(libpath), which usually points
+  # to something like /usr/lib for system ruby versions (not those
+  # installed through rbenv or rvm).
+  #
+  # This was causing system-wide libgit2 installations to be preferred
+  # over of our vendored libgit2 version when building rugged.
+  #
+  # By putting the path to the vendored libgit2 library at the front of
+  # $DEFLIBPATH, we can ensure that our bundled version is always used.
+  $DEFLIBPATH.unshift("#{LIBGIT2_DIR}/build")
+  dir_config('git2', "#{LIBGIT2_DIR}/include", "#{LIBGIT2_DIR}/build")
+end
+
+unless have_library 'git2' and have_header 'git2.h'
+  abort "ERROR: Failed to build libgit2"
+end
+
+create_makefile("rugged/rugged")
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged.c
new file mode 100755
index 0000000..a0c3976
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged.c
@@ -0,0 +1,497 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+const char *RUGGED_ERROR_NAMES[] = {
+	"None",            /* GITERR_NONE */
+	"NoMemError",      /* GITERR_NOMEMORY, */
+	"OSError",         /* GITERR_OS, */
+	"InvalidError",    /* GITERR_INVALID, */
+	"ReferenceError",  /* GITERR_REFERENCE, */
+	"ZlibError",       /* GITERR_ZLIB, */
+	"RepositoryError", /* GITERR_REPOSITORY, */
+	"ConfigError",     /* GITERR_CONFIG, */
+	"RegexError",      /* GITERR_REGEX, */
+	"OdbError",        /* GITERR_ODB, */
+	"IndexError",      /* GITERR_INDEX, */
+	"ObjectError",     /* GITERR_OBJECT, */
+	"NetworkError",    /* GITERR_NET, */
+	"TagError",        /* GITERR_TAG, */
+	"TreeError",       /* GITERR_TREE, */
+	"IndexerError",    /* GITERR_INDEXER, */
+	"SslError",        /* GITERR_SSL, */
+	"SubmoduleError",  /* GITERR_SUBMODULE, */
+	"ThreadError",     /* GITERR_THREAD, */
+	"StashError",      /* GITERR_STASH, */
+	"CheckoutError",   /* GITERR_CHECKOUT, */
+	"FetchheadError",  /* GITERR_FETCHHEAD, */
+	"MergeError",      /* GITERR_MERGE, */
+	"SshError",        /* GITERR_SSH, */
+	"FilterError"      /* GITERR_FILTER, */
+};
+
+#define RUGGED_ERROR_COUNT (int)((sizeof(RUGGED_ERROR_NAMES)/sizeof(RUGGED_ERROR_NAMES[0])))
+
+VALUE rb_mRugged;
+VALUE rb_eRuggedError;
+VALUE rb_eRuggedErrors[RUGGED_ERROR_COUNT];
+
+static VALUE rb_mShutdownHook;
+
+/*
+ *  call-seq:
+ *     Rugged.libgit2_version -> version
+ *
+ *  Returns an array representing the current libgit2 version in use. Using
+ *  the array makes it easier for the end-user to take conditional actions
+ *  based on each respective version attribute: major, minor, rev.
+ *
+ *    Rugged.libgit2_version #=> [0, 17, 0]
+ */
+static VALUE rb_git_libgit2_version(VALUE self)
+{
+	int major;
+	int minor;
+	int rev;
+
+	git_libgit2_version(&major, &minor, &rev);
+
+	// We return an array of three elements to represent the version components
+	return rb_ary_new3(3, INT2NUM(major), INT2NUM(minor), INT2NUM(rev));
+}
+
+/*
+ *  call-seq:
+ *     Rugged.features -> [feature, ...]
+ *
+ *  Returns an array representing the features that libgit2 was compiled
+ *  with — this includes `:threads` (thread support), `:https` and `:ssh`.
+ *
+ *    Rugged.features #=> [:threads, :https]
+ */
+static VALUE rb_git_features(VALUE self)
+{
+	VALUE ret_arr = rb_ary_new();
+
+	int caps = git_libgit2_features();
+
+	if (caps & GIT_FEATURE_THREADS)
+		rb_ary_push(ret_arr, CSTR2SYM("threads"));
+
+	if (caps & GIT_FEATURE_HTTPS)
+		rb_ary_push(ret_arr, CSTR2SYM("https"));
+
+	if (caps & GIT_FEATURE_SSH)
+		rb_ary_push(ret_arr, CSTR2SYM("ssh"));
+
+	return ret_arr;
+}
+
+/*
+ *  call-seq:
+ *    Rugged.hex_to_raw(oid) -> raw_buffer
+ *
+ *  Turn a string of 40 hexadecimal characters into the buffer of
+ *  20 bytes it represents.
+ *
+ *    Rugged.hex_to_raw('d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f')
+ *    #=> "\330xk\374\227H^\215{\031\262\037\270\214\216\361\361\231\374?"
+ */
+static VALUE rb_git_hex_to_raw(VALUE self, VALUE hex)
+{
+	git_oid oid;
+
+	Check_Type(hex, T_STRING);
+	rugged_exception_check(git_oid_fromstr(&oid, StringValueCStr(hex)));
+
+	return rb_str_new((const char *)oid.id, 20);
+}
+
+/*
+ *  call-seq:
+ *    Rugged.raw_to_hex(buffer) -> hex_oid
+ *
+ *  Turn a buffer of 20 bytes (representing a SHA1 OID) into its
+ *  readable hexadecimal representation.
+ *
+ *    Rugged.raw_to_hex("\330xk\374\227H^\215{\031\262\037\270\214\216\361\361\231\374?")
+ *    #=> "d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f"
+ */
+static VALUE rb_git_raw_to_hex(VALUE self, VALUE raw)
+{
+	git_oid oid;
+	char out[40];
+
+	Check_Type(raw, T_STRING);
+
+	if (RSTRING_LEN(raw) != GIT_OID_RAWSZ)
+		rb_raise(rb_eTypeError, "Invalid buffer size for an OID");
+
+	git_oid_fromraw(&oid, (const unsigned char *)RSTRING_PTR(raw));
+	git_oid_fmt(out, &oid);
+
+	return rb_str_new(out, 40);
+}
+
+/*
+ *  call-seq:
+ *    Rugged.prettify_message(message, strip_comments = '#') -> clean_message
+ *
+ *  Process a commit or tag message into standard form, by stripping trailing spaces and
+ *  comments, and making sure that the message has a proper header line.
+ */
+static VALUE rb_git_prettify_message(int argc, VALUE *argv, VALUE self)
+{
+	char comment_char = '#';
+	int strip_comments = 1;
+
+	git_buf message = { NULL };
+	VALUE rb_message, rb_strip;
+	int error;
+	VALUE result = Qnil;
+
+	rb_scan_args(argc, argv, "11", &rb_message, &rb_strip);
+
+	Check_Type(rb_message, T_STRING);
+
+	switch (TYPE(rb_strip)) {
+	case T_FALSE:
+		strip_comments = 0;
+		break;
+
+	case T_STRING:
+		if (RSTRING_LEN(rb_strip) > 0)
+			comment_char = RSTRING_PTR(rb_strip)[0];
+		break;
+
+	case T_TRUE:
+	case T_NIL:
+	default:
+		break;
+	}
+
+	error = git_message_prettify(&message,
+				StringValueCStr(rb_message), strip_comments, comment_char);
+
+	if (!error)
+		result = rb_enc_str_new(message.ptr, message.size, rb_utf8_encoding());
+
+	git_buf_free(&message);
+	rugged_exception_check(error);
+
+	return result;
+}
+
+static VALUE minimize_cb(VALUE rb_oid, git_oid_shorten *shortener)
+{
+	Check_Type(rb_oid, T_STRING);
+	git_oid_shorten_add(shortener, RSTRING_PTR(rb_oid));
+	return Qnil;
+}
+
+static VALUE minimize_yield(VALUE rb_oid, VALUE *data)
+{
+	rb_funcall(data[0], rb_intern("call"), 1,
+		rb_str_substr(rb_oid, 0, FIX2INT(data[1])));
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    Rugged.minimize_oid(oid_iterator, min_length = 7) { |short_oid| block }
+ *    Rugged.minimize_oid(oid_iterator, min_length = 7) -> min_length
+ *
+ *  Iterate through +oid_iterator+, which should yield any number of SHA1 OIDs
+ *  (represented as 40-character hexadecimal strings), and tries to minify them.
+ *
+ *  Minifying a set of a SHA1 strings means finding the shortest root substring
+ *  for each string that uniquely identifies it.
+ *
+ *  If no +block+ is given, the function will return the minimal length as an
+ *  integer value:
+ *
+ *    oids = [
+ *      'd8786bfc974aaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
+ *      'd8786bfc974bbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
+ *      'd8786bfc974ccccccccccccccccccccccccccccc',
+ *      '68d041ee999cb07c6496fbdd4f384095de6ca9e1',
+ *    ]
+ *
+ *    Rugged.minimize_oids(oids) #=> 12
+ *
+ *  If a +block+ is given, it will be called with each OID from +iterator+
+ *  in its minified form:
+ *
+ *    Rugged.minimize_oid(oids) { |oid| puts oid }
+ *
+ *  produces:
+ *
+ *    d8786bfc974a
+ *    d8786bfc974b
+ *    d8786bfc974c
+ *    68d041ee999c
+ *
+ *  The optional +min_length+ argument allows you to specify a lower bound for
+ *  the minified strings; returned strings won't be shorter than the given value,
+ *  even if they would still be uniquely represented.
+ *
+ *    Rugged.minimize_oid(oids, 18) #=> 18
+ */
+static VALUE rb_git_minimize_oid(int argc, VALUE *argv, VALUE self)
+{
+	git_oid_shorten *shrt;
+	int length, minlen = 7;
+	VALUE rb_enum, rb_minlen, rb_block;
+
+	rb_scan_args(argc, argv, "11&", &rb_enum, &rb_minlen, &rb_block);
+
+	if (!NIL_P(rb_minlen)) {
+		Check_Type(rb_minlen, T_FIXNUM);
+		minlen = FIX2INT(rb_minlen);
+	}
+
+	if (!rb_respond_to(rb_enum, rb_intern("each")))
+		rb_raise(rb_eTypeError, "Expecting an Enumerable instance");
+
+	shrt = git_oid_shorten_new(minlen);
+
+	rb_iterate(rb_each, rb_enum, &minimize_cb, (VALUE)shrt);
+	length = git_oid_shorten_add(shrt, NULL);
+
+	git_oid_shorten_free(shrt);
+	rugged_exception_check(length);
+
+	if (!NIL_P(rb_block)) {
+		VALUE yield_data[2];
+
+		yield_data[0] = rb_block;
+		yield_data[1] = INT2FIX(length);
+
+		rb_iterate(rb_each, rb_enum, &minimize_yield, (VALUE)yield_data);
+		return Qnil;
+	}
+
+	return INT2FIX(length);
+}
+
+static void cleanup_cb(void *unused)
+{
+	(void)unused;
+	git_libgit2_shutdown();
+}
+
+void rugged_exception_raise(void)
+{
+	VALUE err_klass, err_obj;
+	const git_error *error;
+	const char *err_message;
+
+	error = giterr_last();
+
+	if (error && error->klass > 0 && error->klass < RUGGED_ERROR_COUNT) {
+		err_klass = rb_eRuggedErrors[error->klass];
+		err_message = error->message;
+	} else {
+		err_klass = rb_eRuntimeError;
+		err_message = "Rugged operation failed";
+	}
+
+	err_obj = rb_exc_new2(err_klass, err_message);
+	giterr_clear();
+	rb_exc_raise(err_obj);
+}
+
+VALUE rugged__block_yield_splat(VALUE args) {
+	VALUE block = rb_ary_shift(args);
+	int n = RARRAY_LENINT(args);
+
+	if (n == 0) {
+		return rb_funcall(block, rb_intern("call"), 0);
+	} else {
+		int i;
+		VALUE *argv;
+		argv = ALLOCA_N(VALUE, n);
+
+		for (i=0; i < n; i++) {
+			argv[i] = rb_ary_entry(args, i);
+		}
+
+		return rb_funcall2(block, rb_intern("call"), n, argv);
+	}
+}
+
+/*
+ *  call-seq:
+ *    Rugged.__cache_usage__ -> [current, max]
+ *
+ *  Returns an array representing the current bytes in the internal
+ *  libgit2 cache and the maximum size of the cache.
+ */
+static VALUE rb_git_cache_usage(VALUE self)
+{
+	int64_t used, max;
+	git_libgit2_opts(GIT_OPT_GET_CACHED_MEMORY, &used, &max);
+	return rb_ary_new3(2, LL2NUM(used), LL2NUM(max));
+}
+
+VALUE rugged_strarray_to_rb_ary(git_strarray *str_array)
+{
+	VALUE rb_array = rb_ary_new2(str_array->count);
+	size_t i;
+
+	for (i = 0; i < str_array->count; ++i) {
+		rb_ary_push(rb_array, rb_str_new_utf8(str_array->strings[i]));
+	}
+
+	return rb_array;
+}
+
+void rugged_rb_ary_to_strarray(VALUE rb_array, git_strarray *str_array)
+{
+	int i;
+
+	str_array->strings = NULL;
+	str_array->count = 0;
+
+	if (NIL_P(rb_array))
+		return;
+
+	if (TYPE(rb_array) == T_STRING) {
+		str_array->count = 1;
+		str_array->strings = xmalloc(sizeof(char *));
+		str_array->strings[0] = StringValueCStr(rb_array);
+		return;
+	}
+
+	Check_Type(rb_array, T_ARRAY);
+
+	for (i = 0; i < RARRAY_LEN(rb_array); ++i)
+		Check_Type(rb_ary_entry(rb_array, i), T_STRING);
+
+	str_array->count = RARRAY_LEN(rb_array);
+	str_array->strings = xmalloc(str_array->count * sizeof(char *));
+
+	for (i = 0; i < RARRAY_LEN(rb_array); ++i) {
+		VALUE rb_string = rb_ary_entry(rb_array, i);
+		str_array->strings[i] = StringValueCStr(rb_string);
+	}
+}
+
+void Init_rugged(void)
+{
+	rb_mRugged = rb_define_module("Rugged");
+
+	/* Initialize the Error classes */
+	{
+		int i;
+
+		rb_eRuggedError = rb_define_class_under(rb_mRugged, "Error", rb_eStandardError);
+
+		rb_eRuggedErrors[0] = Qnil; /* 0 return value -- no exception */
+		rb_eRuggedErrors[1] = rb_define_class_under(rb_mRugged, RUGGED_ERROR_NAMES[1], rb_eNoMemError);
+		rb_eRuggedErrors[2] = rb_define_class_under(rb_mRugged, RUGGED_ERROR_NAMES[2], rb_eIOError);
+		rb_eRuggedErrors[3] = rb_define_class_under(rb_mRugged, RUGGED_ERROR_NAMES[3], rb_eArgError);
+
+		for (i = 4; i < RUGGED_ERROR_COUNT; ++i) {
+			rb_eRuggedErrors[i] = rb_define_class_under(rb_mRugged, RUGGED_ERROR_NAMES[i], rb_eRuggedError);
+		}
+	}
+
+	rb_define_module_function(rb_mRugged, "libgit2_version", rb_git_libgit2_version, 0);
+	rb_define_module_function(rb_mRugged, "features", rb_git_features, 0);
+	rb_define_module_function(rb_mRugged, "hex_to_raw", rb_git_hex_to_raw, 1);
+	rb_define_module_function(rb_mRugged, "raw_to_hex", rb_git_raw_to_hex, 1);
+	rb_define_module_function(rb_mRugged, "minimize_oid", rb_git_minimize_oid, -1);
+	rb_define_module_function(rb_mRugged, "prettify_message", rb_git_prettify_message, -1);
+	rb_define_module_function(rb_mRugged, "__cache_usage__", rb_git_cache_usage, 0);
+
+	Init_rugged_reference();
+	Init_rugged_reference_collection();
+
+	Init_rugged_object();
+	Init_rugged_commit();
+	Init_rugged_tree();
+	Init_rugged_tag();
+	Init_rugged_tag_collection();
+	Init_rugged_blob();
+
+	Init_rugged_index();
+	Init_rugged_repo();
+	Init_rugged_revwalk();
+	Init_rugged_branch();
+	Init_rugged_branch_collection();
+	Init_rugged_config();
+	Init_rugged_remote();
+	Init_rugged_remote_collection();
+	Init_rugged_notes();
+	Init_rugged_settings();
+	Init_rugged_submodule();
+	Init_rugged_submodule_collection();
+	Init_rugged_diff();
+	Init_rugged_patch();
+	Init_rugged_diff_delta();
+	Init_rugged_diff_hunk();
+	Init_rugged_diff_line();
+	Init_rugged_blame();
+	Init_rugged_cred();
+	Init_rugged_backend();
+
+	/*
+	 * Sort the repository contents in no particular ordering;
+	 * this sorting is arbitrary, implementation-specific
+	 * and subject to change at any time.
+	 * This is the default sorting for new walkers.
+	 */
+	rb_define_const(rb_mRugged, "SORT_NONE", INT2FIX(GIT_SORT_NONE));
+
+	/*
+	 * Sort the repository contents in topological order
+	 * (parents before children); this sorting mode
+	 * can be combined with time sorting.
+	 */
+	rb_define_const(rb_mRugged, "SORT_TOPO", INT2FIX(GIT_SORT_TOPOLOGICAL));
+
+	/*
+	 * Sort the repository contents by commit time;
+	 * this sorting mode can be combined with
+	 * topological sorting.
+	 */
+	rb_define_const(rb_mRugged, "SORT_DATE", INT2FIX(GIT_SORT_TIME));
+
+	/*
+	 * Iterate through the repository contents in reverse
+	 * order; this sorting mode can be combined with
+	 * any of the above.
+	 */
+	rb_define_const(rb_mRugged, "SORT_REVERSE", INT2FIX(GIT_SORT_REVERSE));
+
+	/* Initialize libgit2 */
+	git_libgit2_init();
+
+	/* Hook a global object to cleanup the library
+	 * on shutdown */
+	rb_mShutdownHook = Data_Wrap_Struct(rb_cObject, NULL, &cleanup_cb, NULL);
+	rb_global_variable(&rb_mShutdownHook);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged.h b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged.h
new file mode 100755
index 0000000..98d575a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged.h
@@ -0,0 +1,185 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef __H_RUGGED_BINDINGS__
+#define __H_RUGGED_BINDINGS__
+
+// tell rbx not to use it's caching compat layer
+// by doing this we're making a promize to RBX that
+// we'll never modify the pointers we get back from RSTRING_PTR
+#define RSTRING_NOT_MODIFIED
+
+#include <ruby.h>
+#ifndef HAVE_RUBY_ENCODING_H
+#error "Rugged requires Ruby 1.9+ to build"
+#else
+#include <ruby/encoding.h>
+#endif
+
+#include <assert.h>
+#include <git2.h>
+#include <git2/odb_backend.h>
+
+#define rb_str_new_utf8(str) rb_enc_str_new(str, strlen(str), rb_utf8_encoding())
+#define CSTR2SYM(s) (ID2SYM(rb_intern((s))))
+
+/*
+ * Initialization functions
+ */
+void Init_rugged_object(void);
+void Init_rugged_branch(void);
+void Init_rugged_branch_collection(void);
+void Init_rugged_commit(void);
+void Init_rugged_tree(void);
+void Init_rugged_tag(void);
+void Init_rugged_tag_collection(void);
+void Init_rugged_blob(void);
+void Init_rugged_index(void);
+void Init_rugged_repo(void);
+void Init_rugged_revwalk(void);
+void Init_rugged_reference(void);
+void Init_rugged_reference_collection(void);
+void Init_rugged_config(void);
+void Init_rugged_remote(void);
+void Init_rugged_remote_collection(void);
+void Init_rugged_notes(void);
+void Init_rugged_settings(void);
+void Init_rugged_submodule(void);
+void Init_rugged_submodule_collection(void);
+void Init_rugged_diff(void);
+void Init_rugged_patch(void);
+void Init_rugged_diff_delta(void);
+void Init_rugged_diff_hunk(void);
+void Init_rugged_diff_line(void);
+void Init_rugged_blame(void);
+void Init_rugged_cred(void);
+void Init_rugged_backend(void);
+
+VALUE rb_git_object_init(git_otype type, int argc, VALUE *argv, VALUE self);
+
+VALUE rugged_raw_read(git_repository *repo, const git_oid *oid);
+
+VALUE rugged_signature_new(const git_signature *sig, const char *encoding_name);
+
+VALUE rugged_repo_new(VALUE klass, git_repository *repo);
+VALUE rugged_index_new(VALUE klass, VALUE owner, git_index *index);
+VALUE rugged_config_new(VALUE klass, VALUE owner, git_config *cfg);
+VALUE rugged_object_new(VALUE owner, git_object *object);
+VALUE rugged_object_rev_parse(VALUE rb_repo, VALUE rb_spec, int as_obj);
+VALUE rugged_ref_new(VALUE klass, VALUE owner, git_reference *ref);
+VALUE rugged_diff_new(VALUE klass, VALUE owner, git_diff *diff);
+VALUE rugged_patch_new(VALUE owner, git_patch *patch);
+VALUE rugged_diff_delta_new(VALUE owner, const git_diff_delta *delta);
+VALUE rugged_diff_hunk_new(VALUE owner, size_t hunk_idx, const git_diff_hunk *hunk, size_t lines_in_hunk);
+VALUE rugged_diff_line_new(const git_diff_line *line);
+VALUE rugged_remote_new(VALUE owner, git_remote *remote);
+VALUE rb_git_delta_file_fromC(const git_diff_file *file);
+
+void rugged_parse_diff_options(git_diff_options *opts, VALUE rb_options);
+void rugged_parse_merge_options(git_merge_options *opts, VALUE rb_options);
+
+void rugged_cred_extract(git_cred **cred, int allowed_types, VALUE rb_credential);
+
+VALUE rugged_otype_new(git_otype t);
+git_otype rugged_otype_get(VALUE rb_type);
+
+git_signature *rugged_signature_get(VALUE rb_person, git_repository *repo);
+git_object *rugged_object_get(git_repository *repo, VALUE object_value, git_otype type);
+int rugged_oid_get(git_oid *oid, git_repository *repo, VALUE p);
+
+void rugged_rb_ary_to_strarray(VALUE rb_array, git_strarray *str_array);
+VALUE rugged_strarray_to_rb_ary(git_strarray *str_array);
+
+static inline void rugged_set_owner(VALUE object, VALUE owner)
+{
+	rb_iv_set(object, "@owner", owner);
+}
+
+static inline VALUE rugged_owner(VALUE object)
+{
+	return rb_iv_get(object, "@owner");
+}
+
+extern void rugged_exception_raise(void);
+
+static inline void rugged_exception_check(int errorcode)
+{
+	if (errorcode < 0)
+		rugged_exception_raise();
+}
+
+static inline int rugged_parse_bool(VALUE boolean)
+{
+	if (TYPE(boolean) != T_TRUE && TYPE(boolean) != T_FALSE)
+		rb_raise(rb_eTypeError, "Expected boolean value");
+
+	return boolean ? 1 : 0;
+}
+
+extern VALUE rb_cRuggedRepo;
+
+VALUE rugged__block_yield_splat(VALUE args);
+
+struct rugged_cb_payload
+{
+    VALUE rb_data;
+    int exception;
+};
+
+struct rugged_remote_cb_payload
+{
+	VALUE progress;
+	VALUE completion;
+	VALUE transfer_progress;
+	VALUE update_tips;
+	VALUE credentials;
+	VALUE result;
+	int exception;
+};
+
+void rugged_remote_init_callbacks_and_payload_from_options(
+	VALUE rb_options,
+	git_remote_callbacks *callbacks,
+	struct rugged_remote_cb_payload *payload);
+
+static inline void rugged_check_repo(VALUE rb_repo)
+{
+	if (!rb_obj_is_kind_of(rb_repo, rb_cRuggedRepo))
+		rb_raise(rb_eTypeError, "Expecting a Rugged Repository");
+}
+
+static inline VALUE rugged_create_oid(const git_oid *oid)
+{
+	char out[40];
+	git_oid_fmt(out, oid);
+	return rb_str_new(out, 40);
+}
+
+
+typedef struct _rugged_backend {
+  int (* odb_backend)(git_odb_backend **backend_out, struct _rugged_backend *backend, const char* path);
+  int (* refdb_backend)(git_refdb_backend **backend_out, struct _rugged_backend *backend, const char* path);
+} rugged_backend;
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_backend.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_backend.c
new file mode 100755
index 0000000..b4bb391
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_backend.c
@@ -0,0 +1,34 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+
+VALUE rb_cRuggedBackend;
+
+void Init_rugged_backend(void)
+{
+	rb_cRuggedBackend = rb_define_class_under(rb_mRugged, "Backend", rb_cObject);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_blame.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_blame.c
new file mode 100755
index 0000000..ba0a8c9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_blame.c
@@ -0,0 +1,292 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+VALUE rb_cRuggedBlame;
+
+static VALUE rb_git_blame_hunk_fromC(const git_blame_hunk *hunk)
+{
+	VALUE rb_hunk;
+	if (!hunk)  {
+		return Qnil;
+	}
+
+	rb_hunk = rb_hash_new();
+	rb_hash_aset(rb_hunk, CSTR2SYM("lines_in_hunk"), UINT2NUM(hunk->lines_in_hunk));
+
+	rb_hash_aset(rb_hunk, CSTR2SYM("final_commit_id"), rugged_create_oid(&(hunk->final_commit_id)));
+	rb_hash_aset(rb_hunk, CSTR2SYM("final_start_line_number"), UINT2NUM(hunk->final_start_line_number));
+	rb_hash_aset(rb_hunk, CSTR2SYM("final_signature"), hunk->final_signature ? rugged_signature_new(hunk->final_signature, NULL) : Qnil);
+
+	rb_hash_aset(rb_hunk, CSTR2SYM("orig_commit_id"), rugged_create_oid(&(hunk->orig_commit_id)));
+	rb_hash_aset(rb_hunk, CSTR2SYM("orig_path"), hunk->orig_path ? rb_str_new2(hunk->orig_path) : Qnil);
+	rb_hash_aset(rb_hunk, CSTR2SYM("orig_start_line_number"), UINT2NUM(hunk->orig_start_line_number));
+	rb_hash_aset(rb_hunk, CSTR2SYM("orig_signature"), hunk->orig_signature ? rugged_signature_new(hunk->orig_signature, NULL) : Qnil);
+
+	rb_hash_aset(rb_hunk, CSTR2SYM("boundary"), hunk->boundary ? Qtrue : Qfalse);
+
+	return rb_hunk;
+}
+
+static void rugged_parse_blame_options(git_blame_options *opts, git_repository *repo, VALUE rb_options)
+{
+	if (!NIL_P(rb_options)) {
+		VALUE rb_value;
+		Check_Type(rb_options, T_HASH);
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("min_line"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts->min_line = FIX2UINT(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("max_line"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts->max_line = FIX2UINT(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("newest_commit"));
+		if (!NIL_P(rb_value)) {
+			int error = rugged_oid_get(&opts->newest_commit, repo, rb_value);
+			rugged_exception_check(error);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("oldest_commit"));
+		if (!NIL_P(rb_value)) {
+			int error = rugged_oid_get(&opts->oldest_commit, repo, rb_value);
+			rugged_exception_check(error);
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("track_copies_same_file")))) {
+			opts->flags |= GIT_BLAME_TRACK_COPIES_SAME_FILE;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("track_copies_same_commit_moves")))) {
+			opts->flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("track_copies_same_commit_copies")))) {
+			opts->flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("track_copies_any_commit_copies")))) {
+			opts->flags |= GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES;
+		}
+	}
+}
+
+/*
+ *  call-seq:
+ *    Blame.new(repo, path, options = {}) -> blame
+ *
+ *  Get blame data for the file at +path+ in +repo+.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :newest_commit ::
+ *    The ID of the newest commit to consider in the blame. Defaults to +HEAD+.
+ *    This can either be a Rugged::Object instance, or a full or abbreviated
+ *    SHA1 id.
+ *
+ *  :oldest_commit ::
+ *    The id of the oldest commit to consider. Defaults to the first commit
+ *    encountered with a NULL parent. This can either be a Rugged::Object
+ *    instance, or a full or abbreviated SHA1 id.
+ *
+ *  :min_line ::
+ *    The first line in the file to blame. Line numbers start with 1.
+ *    Defaults to +1+.
+ *
+ *  :max_line ::
+ *    The last line in the file to blame. Defaults to the last line in
+ *    the file.
+ *
+ *  :track_copies_same_file
+ *    If this value is +true+, lines that have moved within a file will be
+ *    tracked (like `git blame -M`).
+ *
+ *  :track_copies_same_commit_moves
+ *    If this value is +true+, lines that have moved across files in the same
+ *    commit will be tracked (like `git blame -C`).
+ *
+ *  :track_copies_same_commit_copies
+ *    If this value is +true+, lines that have been copied from another file
+ *    that exists in the same commit will be tracked (like `git blame -CC`).
+ *
+ *  :track_copies_any_commit_copies
+ *    If this value is +true+, lines that have been copied from another file
+ *    that exists in *any* commit will be tracked (like `git blame -CCC`).
+ *
+ */
+static VALUE rb_git_blame_new(int argc, VALUE *argv, VALUE klass)
+{
+	VALUE rb_repo, rb_path, rb_options;
+	git_repository *repo;
+	git_blame *blame;
+	git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+
+	rb_scan_args(argc, argv, "20:", &rb_repo, &rb_path, &rb_options);
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Check_Type(rb_path, T_STRING);
+
+	rugged_parse_blame_options(&opts, repo, rb_options);
+
+	rugged_exception_check(git_blame_file(
+		&blame, repo, StringValueCStr(rb_path), &opts
+	));
+
+	return Data_Wrap_Struct(klass, NULL, &git_blame_free, blame);
+}
+
+/*
+ *  call-seq:
+ *    blame.for_line(line_no) -> hunk
+ *
+ *  Returns the blame hunk data for the given +line_no+ in +blame+.
+ *  Line number counting starts with +1+.
+ */
+static VALUE rb_git_blame_for_line(VALUE self, VALUE rb_line_no)
+{
+	git_blame *blame;
+	int line_no;
+
+	Data_Get_Struct(self, git_blame, blame);
+	Check_Type(rb_line_no, T_FIXNUM);
+
+	line_no = NUM2INT(rb_line_no);
+
+	if (line_no < 0) {
+		rb_raise(rb_eArgError, "line number can't be negative");
+	}
+
+	return rb_git_blame_hunk_fromC(
+		git_blame_get_hunk_byline(blame, (uint32_t)line_no)
+	);
+}
+
+/*
+ *  call-seq:
+ *    blame.count -> count
+ *    blame.size -> count
+ *
+ *  Returns the total +count+ of blame hunks in +blame+.
+ */
+static VALUE rb_git_blame_count(VALUE self)
+{
+	git_blame *blame;
+	Data_Get_Struct(self, git_blame, blame);
+	return UINT2NUM(git_blame_get_hunk_count(blame));
+}
+
+/*
+ *  call-seq:
+ *    blame[index] -> hunk
+ *
+ *  Returns the blame hunk data at the given +index+ in +blame+.
+ *
+ *  Negative indices count backward from the end of the blame hunks (-1 is the last
+ *  element).
+ *
+ *  Returns +nil+ if no blame hunk exists at the given +index+.
+ */
+static VALUE rb_git_blame_get_by_index(VALUE self, VALUE rb_index)
+{
+	git_blame *blame;
+	int index;
+	uint32_t blame_count;
+
+	Data_Get_Struct(self, git_blame, blame);
+	Check_Type(rb_index, T_FIXNUM);
+
+	index = NUM2INT(rb_index);
+	blame_count = git_blame_get_hunk_count(blame);
+
+	if (index < 0) {
+		if ((uint32_t)(-index) > blame_count) {
+			return Qnil;
+		}
+
+		return rb_git_blame_hunk_fromC(
+			git_blame_get_hunk_byindex(blame, (uint32_t)(blame_count + index))
+		);
+	}
+
+	if ((uint32_t)index > blame_count)
+		return Qnil;
+
+	return rb_git_blame_hunk_fromC(
+		git_blame_get_hunk_byindex(blame, (uint32_t)index)
+	);
+}
+
+/*
+ *  call-seq:
+ *    blame.each { |hunk| ... } -> blame
+ *    blame.each -> enumerator
+ *
+ *  If given a block, yields each +hunk+ that is part of +blame+.
+ *  If no block is given, an enumerator will be returned.
+ */
+static VALUE rb_git_blame_each(VALUE self)
+{
+	git_blame *blame;
+	uint32_t i, blame_count;
+
+	if (!rb_block_given_p()) {
+		return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("each"), self);
+	}
+
+	Data_Get_Struct(self, git_blame, blame);
+
+	blame_count = git_blame_get_hunk_count(blame);
+	for (i = 0; i < blame_count; ++i) {
+		rb_yield(rb_git_blame_hunk_fromC(
+			git_blame_get_hunk_byindex(blame, i)
+		));
+	}
+
+	return self;
+}
+
+void Init_rugged_blame(void)
+{
+	rb_cRuggedBlame = rb_define_class_under(rb_mRugged, "Blame", rb_cObject);
+	rb_include_module(rb_cRuggedBlame, rb_mEnumerable);
+
+	rb_define_singleton_method(rb_cRuggedBlame, "new", rb_git_blame_new, -1);
+
+	rb_define_method(rb_cRuggedBlame, "[]", rb_git_blame_get_by_index, 1);
+	rb_define_method(rb_cRuggedBlame, "for_line", rb_git_blame_for_line, 1);
+
+	rb_define_method(rb_cRuggedBlame, "count", rb_git_blame_count, 0);
+	rb_define_method(rb_cRuggedBlame, "size", rb_git_blame_count, 0);
+
+	rb_define_method(rb_cRuggedBlame, "each", rb_git_blame_each, 0);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_blob.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_blob.c
new file mode 100755
index 0000000..31cd095
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_blob.c
@@ -0,0 +1,638 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+#include <ctype.h>
+#include <git2/sys/hashsig.h>
+
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedObject;
+extern VALUE rb_cRuggedRepo;
+static ID id_read;
+
+VALUE rb_cRuggedBlob;
+VALUE rb_cRuggedBlobSig;
+
+/*
+ *  call-seq:
+ *    blob.text(max_lines = -1, encoding = Encoding.default_external) -> string
+ *
+ *  Return up to +max_lines+ of text from a blob as a +String+.
+ *  If +max_lines+ is less than 0, the full string is returned.
+ *
+ *  The string is created with the given +encoding+, defaulting to
+ *  Encoding.default_external.
+ *
+ *  When limiting the size of the text with +max_lines+, the string is
+ *  expected to have an ASCII-compatible encoding, and is checked
+ *  for the newline +\n+ character.
+ */
+static VALUE rb_git_blob_text_GET(int argc, VALUE *argv, VALUE self)
+{
+	git_blob *blob;
+	size_t size;
+	const char *content;
+	VALUE rb_max_lines, rb_encoding;
+
+	Data_Get_Struct(self, git_blob, blob);
+	rb_scan_args(argc, argv, "02", &rb_max_lines, &rb_encoding);
+
+	content = git_blob_rawcontent(blob);
+	size = git_blob_rawsize(blob);
+
+	if (!NIL_P(rb_max_lines)) {
+		size_t i = 0;
+		int lines = 0, maxlines;
+
+		Check_Type(rb_max_lines, T_FIXNUM);
+		maxlines = FIX2INT(rb_max_lines);
+
+		if (maxlines >= 0) {
+			while (i < size && lines < maxlines) {
+				if (content[i++] == '\n')
+					lines++;
+			}
+			size = (size_t)i;
+		}
+
+	}
+
+	if (!NIL_P(rb_encoding)) {
+		return rb_enc_str_new(content, size, rb_to_encoding(rb_encoding));
+	}
+
+	return rb_external_str_new(content, size);
+}
+
+/*
+ *  call-seq:
+ *    blob.content(max_bytes=-1) -> string
+ *
+ *  Return up to +max_bytes+ from the contents of a blob as bytes +String+.
+ *  If +max_bytes+ is less than 0, the full string is returned.
+ *
+ *  This string is tagged with the ASCII-8BIT encoding: the bytes are
+ *  returned as-is, since Git is encoding agnostic.
+ */
+static VALUE rb_git_blob_content_GET(int argc, VALUE *argv, VALUE self)
+{
+	git_blob *blob;
+	size_t size;
+	const char *content;
+	VALUE rb_max_bytes;
+
+	Data_Get_Struct(self, git_blob, blob);
+	rb_scan_args(argc, argv, "01", &rb_max_bytes);
+
+	content = git_blob_rawcontent(blob);
+	size = git_blob_rawsize(blob);
+
+	if (!NIL_P(rb_max_bytes)) {
+		int maxbytes;
+
+		Check_Type(rb_max_bytes, T_FIXNUM);
+		maxbytes = FIX2INT(rb_max_bytes);
+
+		if (maxbytes >= 0 && (size_t)maxbytes < size)
+			size = (size_t)maxbytes;
+	}
+
+	/*
+	 * since we don't really ever know the encoding of a blob
+	 * lets default to the binary encoding (ascii-8bit)
+	 */
+	return rb_str_new(content, size);
+}
+
+/*
+ *  call-seq:
+ *    blob.rawsize -> int
+ *
+ *  Return the size in bytes of the blob. This is the real,
+ *  uncompressed size and the length of +blob.content+, not
+ *  the compressed size.
+ */
+static VALUE rb_git_blob_rawsize(VALUE self)
+{
+	git_blob *blob;
+	Data_Get_Struct(self, git_blob, blob);
+
+	return INT2FIX(git_blob_rawsize(blob));
+}
+
+/*
+ *  call-seq:
+ *    Blob.from_buffer(repository, buffer) -> oid
+ *
+ *  Write a blob to +repository+ with the contents specified
+ *  in +buffer+, where +buffer+ is a +String+.
+ *  The encoding of +buffer+ is ignored and bytes are copied as-is.
+ */
+static VALUE rb_git_blob_from_buffer(VALUE self, VALUE rb_repo, VALUE rb_buffer)
+{
+	int error;
+	git_oid oid;
+	git_repository *repo;
+
+	Check_Type(rb_buffer, T_STRING);
+	rugged_check_repo(rb_repo);
+
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_blob_create_frombuffer(&oid, repo, RSTRING_PTR(rb_buffer), RSTRING_LEN(rb_buffer));
+	rugged_exception_check(error);
+
+	return rugged_create_oid(&oid);
+}
+
+/*
+ *  call-seq:
+ *    Blob.from_workdir(repository, file_path) -> oid
+ *
+ *  Write the file specified in +file_path+ to a blob in +repository+.
+ *  +file_path+ must be relative to the repository's working folder.
+ *  The repository cannot be bare.
+ *
+ *    Blob.from_workdir(repo, 'src/blob.h') #=> '9d09060c850defbc7711d08b57def0d14e742f4e'
+ */
+static VALUE rb_git_blob_from_workdir(VALUE self, VALUE rb_repo, VALUE rb_path)
+{
+	int error;
+	git_oid oid;
+	git_repository *repo;
+
+	Check_Type(rb_path, T_STRING);
+	rugged_check_repo(rb_repo);
+
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_blob_create_fromworkdir(&oid, repo, StringValueCStr(rb_path));
+	rugged_exception_check(error);
+
+	return rugged_create_oid(&oid);
+}
+
+/*
+ *  call-seq:
+ *    Blob.from_disk(repository, file_path) -> oid
+ *
+ *  Write the file specified in +file_path+ to a blob in +repository+.
+ *  The repository can be bare or not.
+ *
+ *  Example:
+ *
+ *    Blob.from_disk(repo, '/var/repos/blob.h') #=> '5b5b025afb0b4c913b4c338a42934a3863bf3643'
+ */
+static VALUE rb_git_blob_from_disk(VALUE self, VALUE rb_repo, VALUE rb_path)
+{
+	int error;
+	git_oid oid;
+	git_repository *repo;
+
+	Check_Type(rb_path, T_STRING);
+	rugged_check_repo(rb_repo);
+
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_blob_create_fromdisk(&oid, repo, StringValueCStr(rb_path));
+	rugged_exception_check(error);
+
+	return rugged_create_oid(&oid);
+}
+
+static VALUE rb_read_check(VALUE pointer) {
+	VALUE *args = (VALUE *)pointer;
+	VALUE rb_buffer = rb_funcall(args[0], id_read, 1, args[1]);
+
+	if (!NIL_P(rb_buffer))
+		Check_Type(rb_buffer, T_STRING);
+
+	return rb_buffer;
+}
+
+static int cb_blob__get__chunk(char *content, size_t max_length, void *data)
+{
+	VALUE rb_buffer, rb_args[2];
+	size_t str_len, safe_len;
+	struct rugged_cb_payload *payload = data;
+
+	rb_args[0] = payload->rb_data;
+	rb_args[1] = INT2FIX(max_length);
+
+	rb_buffer = rb_protect(rb_read_check, (VALUE)rb_args, &payload->exception);
+
+	if (payload->exception)
+		return GIT_ERROR;
+
+	if (NIL_P(rb_buffer))
+		return 0;
+
+	str_len = (size_t)RSTRING_LEN(rb_buffer);
+	safe_len = str_len > max_length ? max_length : str_len;
+	memcpy(content, StringValuePtr(rb_buffer), safe_len);
+
+	return (int)safe_len;
+}
+
+/*
+ *  call-seq:
+ *    Blob.from_io(repository, io [, hint_path]) -> oid
+ *
+ *  Write a loose blob to the +repository+ from an +IO+ provider
+ *  of data.
+ *
+ *  The repository can be bare or not.
+ *
+ *  The data provider +io+ should respond to a <code>read(size)</code>
+ *  method. Generally any instance of a class based on Ruby's +IO+ class
+ *  should work(ex. +File+). On each +read+ call it should
+ *  return a +String+ with maximum size of +size+.
+ *
+ *  *NOTE:* If an exception is raised in the +io+ object's
+ *  +read+ method, no blob will be created.
+ *
+ *  Provided the +hint_path+ parameter is given, its value
+ *  will help to determine what git filters should be applied
+ *  to the object before it can be placed to the object database.
+ *
+ *    File.open('/path/to/file') do |file|
+ *      Blob.from_io(repo, file, 'hint/blob.h') #=> '42cab3c0cde61e2b5a2392e1eadbeffa20ffa171'
+ *    end
+ */
+static VALUE rb_git_blob_from_io(int argc, VALUE *argv, VALUE klass)
+{
+	VALUE rb_repo, rb_io, rb_hint_path;
+	struct rugged_cb_payload payload;
+	const char * hint_path = NULL;
+
+	int error;
+	git_oid oid;
+	git_repository *repo;
+
+	rb_scan_args(argc, argv, "21", &rb_repo, &rb_io, &rb_hint_path);
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	if (!NIL_P(rb_hint_path)) {
+		Check_Type(rb_hint_path, T_STRING);
+		hint_path = StringValueCStr(rb_hint_path);
+	}
+
+	payload.exception = 0;
+	payload.rb_data = rb_io;
+
+	error = git_blob_create_fromchunks(
+			&oid,
+			repo,
+			hint_path,
+			cb_blob__get__chunk,
+			(void *)&payload);
+
+	if (payload.exception)
+		rb_jump_tag(payload.exception);
+	rugged_exception_check(error);
+
+	return rugged_create_oid(&oid);
+}
+
+/*
+ *  call-seq:
+ *    blob.loc -> int
+ *
+ *  Return the number of lines for this blob,
+ *  assuming the blob is plaintext (i.e. not binary)
+ */
+static VALUE rb_git_blob_loc(VALUE self)
+{
+	git_blob *blob;
+	const char *data, *data_end;
+	size_t loc = 0;
+
+	Data_Get_Struct(self, git_blob, blob);
+
+	data = git_blob_rawcontent(blob);
+	data_end = data + git_blob_rawsize(blob);
+
+	if (data == data_end)
+		return INT2FIX(0);
+
+	for (; data < data_end; ++data) {
+		if (data[0] == '\n') {
+			loc++;
+		}
+		else if (data[0] == '\r') {
+			if (data + 1 < data_end && data[1] == '\n')
+				data++;
+			loc++;
+		}
+	}
+
+	if (data[-1] != '\n' && data[-1] != '\r')
+		loc++;
+
+	return INT2FIX(loc);
+}
+
+
+/*
+ *  call-seq:
+ *    blob.sloc -> int
+ *
+ *  Return the number of non-empty code lines for the blob,
+ *  assuming the blob is plaintext (i.e. not binary)
+ */
+static VALUE rb_git_blob_sloc(VALUE self)
+{
+	git_blob *blob;
+	const char *data, *data_end;
+	size_t sloc = 0;
+
+	Data_Get_Struct(self, git_blob, blob);
+
+	data = git_blob_rawcontent(blob);
+	data_end = data + git_blob_rawsize(blob);
+
+	if (data == data_end)
+		return INT2FIX(0);
+
+	/* go through the whole blob, counting lines
+	 * that are not empty */
+	while (data < data_end) {
+		if (*data++ == '\n') {
+			while (data < data_end && isspace(*data))
+				data++;
+
+			sloc++;
+		}
+	}
+
+	/* last line without trailing '\n'? */
+	if (data[-1] != '\n')
+		sloc++;
+
+	return INT2FIX(sloc);
+}
+
+/*
+ *  call-seq:
+ *    blob.binary? -> true or false
+ *
+ *  Determine if the blob content is most certainly binary or not.
+ *
+ *  The heuristic used to guess if a file is binary is taken from core git:
+ *  Searching for NUL bytes and looking for a reasonable ratio of printable
+ *  to non-printable characters among the first 4000 bytes.
+ *
+ */
+static VALUE rb_git_blob_is_binary(VALUE self)
+{
+	git_blob *blob;
+	Data_Get_Struct(self, git_blob, blob);
+	return git_blob_is_binary(blob) ? Qtrue : Qfalse;
+}
+
+/*
+ *  call-seq:
+ *    blob.diff(other, options = {}) -> patch
+ *
+ *  Directly generate a Rugged::Patch from the difference between +blob+ and +other+.
+ *
+ *  +other+ can either be another Rugged::Blob instance, a string,
+ *  or nil (treated as an empty blob).
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :max_size ::
+ *    An integer specifying the maximum byte size of a blob before a it will
+ *    be treated as binary. The default value is 512MB.
+ *
+ *  :context_lines ::
+ *    The number of unchanged lines that define the boundary of a hunk (and
+ *    to display before and after the actual changes). The default is 3.
+ *
+ *  :interhunk_lines ::
+ *    The maximum number of unchanged lines between hunk boundaries before the hunks
+ *    will be merged into a one. The default is 0.
+ *
+ *  :reverse ::
+ *    If true, the sides of the diff will be reversed.
+ *
+ *  :force_text ::
+ *    If true, all files will be treated as text, disabling binary attributes & detection.
+ *
+ *  :ignore_whitespace ::
+ *    If true, all whitespace will be ignored.
+ *
+ *  :ignore_whitespace_change ::
+ *    If true, changes in amount of whitespace will be ignored.
+ *
+ *  :ignore_whitespace_eol ::
+ *    If true, whitespace at end of line will be ignored.
+ *
+ *  :patience ::
+ *    If true, the "patience diff" algorithm will be used (currently unimplemented).
+ *
+ *  :skip_binary_check ::
+ *    If true, diff deltas will be generated without spending time on binary
+ *    detection. This is useful to improve performance in cases where the actual
+ *    file content difference is not needed.
+ *
+ *  :old_path ::
+ *    An optional string to treat +blob+ as if it had this filename.
+ *
+ *  :new_path ::
+ *    An optional string to treat +other+ as if it had this filename.
+ */
+static VALUE rb_git_blob_diff(int argc, VALUE *argv, VALUE self)
+{
+	git_blob *blob;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_patch *patch;
+	const char *old_path = NULL, *new_path = NULL;
+	VALUE rb_other, rb_options;
+	int error;
+
+	rb_scan_args(argc, argv, "10:", &rb_other, &rb_options);
+	if (!NIL_P(rb_options)) {
+		VALUE rb_value;
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("old_path"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_STRING);
+			old_path = StringValueCStr(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("new_path"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_STRING);
+			new_path = StringValueCStr(rb_value);
+		}
+
+		rugged_parse_diff_options(&opts, rb_options);
+	}
+
+	Data_Get_Struct(self, git_blob, blob);
+
+	if (NIL_P(rb_other)) {
+		error = git_patch_from_blobs(&patch, blob, old_path, NULL, new_path, &opts);
+	} else if (rb_obj_is_kind_of(rb_other, rb_cRuggedBlob)) {
+		git_blob *other_blob;
+
+		Data_Get_Struct(rb_other, git_blob, other_blob);
+
+		error = git_patch_from_blobs(&patch, blob, old_path, other_blob, new_path, &opts);
+	} else if (TYPE(rb_other) == T_STRING) {
+		const char * buffer = StringValueCStr(rb_other);
+
+		error = git_patch_from_blob_and_buffer(&patch, blob, old_path, buffer, RSTRING_LEN(rb_other), new_path, &opts);
+	} else {
+		rb_raise(rb_eTypeError, "wrong argument type %s (expected Rugged::Blob, String, or nil)",
+			rb_obj_classname(rb_other));
+	}
+
+	rugged_exception_check(error);
+
+	return rugged_patch_new(self, patch);
+}
+
+static VALUE rb_git_blob_to_buffer(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_repo, rb_sha1, rb_max_bytes;
+	VALUE rb_ret;
+
+	git_repository *repo = NULL;
+	git_blob *blob = NULL;
+
+	size_t size;
+	const char *content;
+
+	rb_scan_args(argc, argv, "21", &rb_repo, &rb_sha1, &rb_max_bytes);
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	blob = (git_blob *)rugged_object_get(repo, rb_sha1, GIT_OBJ_BLOB);
+
+	content = git_blob_rawcontent(blob);
+	size = git_blob_rawsize(blob);
+
+	if (!NIL_P(rb_max_bytes)) {
+		int maxbytes;
+
+		Check_Type(rb_max_bytes, T_FIXNUM);
+		maxbytes = FIX2INT(rb_max_bytes);
+
+		if (maxbytes >= 0 && (size_t)maxbytes < size)
+			size = (size_t)maxbytes;
+	}
+
+	rb_ret = rb_ary_new();
+
+	rb_ary_push(rb_ret, rb_str_new(content, size));
+	rb_ary_push(rb_ret, INT2FIX(git_blob_rawsize(blob)));
+
+	git_object_free((git_object*)blob);
+
+	/* TODO: LOC */
+
+	return rb_ret;
+}
+
+static VALUE rb_git_blob_sig_new(int argc, VALUE *argv, VALUE klass)
+{
+	int error, opts = 0;
+	git_hashsig *sig;
+	VALUE rb_blob, rb_options;
+
+	if (rb_scan_args(argc, argv, "11", &rb_blob, &rb_options) == 2) {
+		Check_Type(rb_options, T_FIXNUM);
+		opts = FIX2INT(rb_options);
+	}
+
+	if (rb_obj_is_kind_of(rb_blob, rb_cRuggedBlob)) {
+		git_blob *blob;
+		Data_Get_Struct(rb_blob, git_blob, blob);
+
+		error = git_hashsig_create(&sig,
+				git_blob_rawcontent(blob),
+				git_blob_rawsize(blob),
+				opts);
+	} else {
+		Check_Type(rb_blob, T_STRING);
+		error = git_hashsig_create(&sig, RSTRING_PTR(rb_blob), RSTRING_LEN(rb_blob), opts);
+	}
+
+	rugged_exception_check(error);
+
+	return Data_Wrap_Struct(klass, NULL, &git_hashsig_free, sig);
+}
+
+static VALUE rb_git_blob_sig_compare(VALUE self, VALUE rb_sig_a, VALUE rb_sig_b)
+{
+	git_hashsig *sig_a;
+	git_hashsig *sig_b;
+	int result;
+
+	if (!rb_obj_is_kind_of(rb_sig_a, rb_cRuggedBlobSig) ||
+		!rb_obj_is_kind_of(rb_sig_b, rb_cRuggedBlobSig)) {
+		rb_raise(rb_eTypeError, "Expected Rugged::Blob::HashSignature");
+	}
+
+	Data_Get_Struct(rb_sig_a, git_hashsig, sig_a);
+	Data_Get_Struct(rb_sig_b, git_hashsig, sig_b);
+
+	result = git_hashsig_compare(sig_a, sig_b);
+
+	if (result < 0)
+		rugged_exception_check(result);
+
+	return INT2FIX(result);
+}
+
+void Init_rugged_blob(void)
+{
+	id_read = rb_intern("read");
+
+	rb_cRuggedBlob = rb_define_class_under(rb_mRugged, "Blob", rb_cRuggedObject);
+
+	rb_define_method(rb_cRuggedBlob, "size", rb_git_blob_rawsize, 0);
+	rb_define_method(rb_cRuggedBlob, "content", rb_git_blob_content_GET, -1);
+	rb_define_method(rb_cRuggedBlob, "text", rb_git_blob_text_GET, -1);
+	rb_define_method(rb_cRuggedBlob, "sloc", rb_git_blob_sloc, 0);
+	rb_define_method(rb_cRuggedBlob, "loc", rb_git_blob_loc, 0);
+	rb_define_method(rb_cRuggedBlob, "binary?", rb_git_blob_is_binary, 0);
+	rb_define_method(rb_cRuggedBlob, "diff", rb_git_blob_diff, -1);
+
+	rb_define_singleton_method(rb_cRuggedBlob, "from_buffer", rb_git_blob_from_buffer, 2);
+	rb_define_singleton_method(rb_cRuggedBlob, "from_workdir", rb_git_blob_from_workdir, 2);
+	rb_define_singleton_method(rb_cRuggedBlob, "from_disk", rb_git_blob_from_disk, 2);
+	rb_define_singleton_method(rb_cRuggedBlob, "from_io", rb_git_blob_from_io, -1);
+
+	rb_define_singleton_method(rb_cRuggedBlob, "to_buffer", rb_git_blob_to_buffer, -1);
+
+	rb_cRuggedBlobSig = rb_define_class_under(rb_cRuggedBlob, "HashSignature", rb_cObject);
+	rb_define_singleton_method(rb_cRuggedBlobSig, "new", rb_git_blob_sig_new, -1);
+	rb_define_singleton_method(rb_cRuggedBlobSig, "compare", rb_git_blob_sig_compare, 2);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_branch.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_branch.c
new file mode 100755
index 0000000..5172fc1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_branch.c
@@ -0,0 +1,195 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedRepo;
+extern VALUE rb_cRuggedObject;
+extern VALUE rb_cRuggedReference;
+VALUE rb_cRuggedBranch;
+
+static inline VALUE rugged_branch_new(VALUE owner, git_reference *ref)
+{
+	return rugged_ref_new(rb_cRuggedBranch, owner, ref);
+}
+
+/*
+ *  call-seq:
+ *    branch.head? -> true or false
+ *
+ *  Returns +true+ if the branch is pointed at by +HEAD+, +false+ otherwise.
+ */
+static VALUE rb_git_branch_head_p(VALUE self)
+{
+	git_reference *branch;
+	Data_Get_Struct(self, git_reference, branch);
+	return git_branch_is_head(branch) ? Qtrue : Qfalse;
+}
+
+/*
+ *  call-seq:
+ *    branch.name -> string
+ *
+ *  Returns the name of +branch+.
+ *
+ *  See Rugged::Reference#canonical_name if you need the fully qualified
+ *  name of the underlying reference.
+ */
+static VALUE rb_git_branch_name(VALUE self)
+{
+	git_reference *branch;
+	const char *branch_name;
+	Data_Get_Struct(self, git_reference, branch);
+
+	rugged_exception_check(git_branch_name(&branch_name, branch));
+
+	return rb_str_new_utf8(branch_name);
+}
+
+static VALUE rb_git_branch__remote_name(VALUE rb_repo, const char *canonical_name)
+{
+	git_repository *repo;
+	git_buf remote_name = { NULL };
+	int error;
+	VALUE result = Qnil;
+
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	if ((error = git_branch_remote_name(&remote_name, repo, canonical_name)) == GIT_OK)
+		result = rb_enc_str_new(remote_name.ptr, remote_name.size, rb_utf8_encoding());
+
+	git_buf_free(&remote_name);
+	rugged_exception_check(error);
+
+	return result;
+}
+
+/*
+ *  call-seq:
+ *    branch.remote_name -> string
+ *
+ *  Get the name of the remote the branch belongs to.
+ *
+ *  If +branch+ is a remote branch, the name of the remote it belongs to is
+ *  returned. If +branch+ is a tracking branch, the name of the remote
+ *  of the tracked branch is returned.
+ *
+ *  Otherwise, +nil+ is returned.
+ */
+static VALUE rb_git_branch_remote_name(VALUE self)
+{
+	git_reference *branch, *remote_ref;
+	int error = 0;
+
+	Data_Get_Struct(self, git_reference, branch);
+
+	if (git_reference_is_remote(branch)) {
+		remote_ref = branch;
+	} else {
+		error = git_branch_upstream(&remote_ref, branch);
+
+		if (error == GIT_ENOTFOUND)
+			return Qnil;
+
+		rugged_exception_check(error);
+	}
+
+	return rb_git_branch__remote_name(
+			rugged_owner(self),
+			git_reference_name(remote_ref));
+}
+
+/*
+ *  call-seq:
+ *    branch.upstream -> branch
+ *
+ *  Returns the remote tracking branch, or +nil+ if the branch is
+ *  remote or has no tracking branch.
+ */
+static VALUE rb_git_branch_upstream(VALUE self)
+{
+	git_reference *branch, *upstream_branch;
+	int error;
+
+	Data_Get_Struct(self, git_reference, branch);
+
+	if (git_reference_is_remote(branch))
+		return Qnil;
+
+	error = git_branch_upstream(&upstream_branch, branch);
+
+	if (error == GIT_ENOTFOUND)
+		return Qnil;
+
+	rugged_exception_check(error);
+
+	return rugged_branch_new(rugged_owner(self), upstream_branch);
+}
+
+/*
+ *  call-seq:
+ *    branch.upstream = branch
+ *
+ *  Set the upstream configuration for a given local branch.
+ *
+ *  Takes a local or remote Rugged::Branch instance or a Rugged::Reference
+ *  pointing to a branch.
+ */
+static VALUE rb_git_branch_set_upstream(VALUE self, VALUE rb_branch)
+{
+	git_reference *branch, *target_branch;
+	const char *target_branch_name;
+
+	Data_Get_Struct(self, git_reference, branch);
+	if (!NIL_P(rb_branch)) {
+		if (!rb_obj_is_kind_of(rb_branch, rb_cRuggedReference))
+			rb_raise(rb_eTypeError, "Expecting a Rugged::Reference instance");
+
+		Data_Get_Struct(rb_branch, git_reference, target_branch);
+
+		rugged_exception_check(
+			git_branch_name(&target_branch_name, target_branch)
+		);
+	} else {
+		target_branch_name = NULL;
+	}
+
+	rugged_exception_check(
+		git_branch_set_upstream(branch, target_branch_name)
+	);
+
+	return rb_branch;
+}
+
+void Init_rugged_branch(void)
+{
+	rb_cRuggedBranch = rb_define_class_under(rb_mRugged, "Branch", rb_cRuggedReference);
+
+	rb_define_method(rb_cRuggedBranch, "head?", rb_git_branch_head_p, 0);
+	rb_define_method(rb_cRuggedBranch, "name", rb_git_branch_name, 0);
+	rb_define_method(rb_cRuggedBranch, "remote_name", rb_git_branch_remote_name, 0);
+	rb_define_method(rb_cRuggedBranch, "upstream", rb_git_branch_upstream, 0);
+	rb_define_method(rb_cRuggedBranch, "upstream=", rb_git_branch_set_upstream, 1);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_branch_collection.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_branch_collection.c
new file mode 100755
index 0000000..db9fd6f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_branch_collection.c
@@ -0,0 +1,408 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedRepo;
+extern VALUE rb_cRuggedBranch;
+
+VALUE rb_cRuggedBranchCollection;
+
+static inline VALUE rugged_branch_new(VALUE owner, git_reference *ref)
+{
+	return rugged_ref_new(rb_cRuggedBranch, owner, ref);
+}
+
+// Helper method to normalize branch lookups.
+static inline int rugged_branch_lookup(git_reference **branch, git_repository *repo, VALUE rb_name_or_branch)
+{
+	if (rb_obj_is_kind_of(rb_name_or_branch, rb_cRuggedBranch)) {
+		rb_name_or_branch = rb_funcall(rb_name_or_branch, rb_intern("canonical_name"), 0);
+
+		if (TYPE(rb_name_or_branch) != T_STRING)
+			rb_raise(rb_eTypeError, "Expected #canonical_name to return a String");
+
+		return git_reference_lookup(branch, repo, StringValueCStr(rb_name_or_branch));
+	} else if (TYPE(rb_name_or_branch) == T_STRING) {
+		char *branch_name = StringValueCStr(rb_name_or_branch), *ref_name;
+		int error;
+
+		if (strncmp(branch_name, "refs/heads/", strlen("refs/heads/")) == 0 ||
+		    strncmp(branch_name, "refs/remotes/", strlen("refs/remotes/")) == 0)
+			return git_reference_lookup(branch, repo, branch_name);
+
+		if ((error = git_branch_lookup(branch, repo, branch_name, GIT_BRANCH_LOCAL)) == GIT_OK ||
+		    error != GIT_ENOTFOUND)
+			return error;
+
+		if ((error = git_branch_lookup(branch, repo, branch_name, GIT_BRANCH_REMOTE)) == GIT_OK ||
+		    error != GIT_ENOTFOUND)
+			return error;
+
+		ref_name = xmalloc((strlen(branch_name) + strlen("refs/") + 1)  * sizeof(char));
+		strcpy(ref_name, "refs/");
+		strcat(ref_name, branch_name);
+
+		error = git_reference_lookup(branch, repo, ref_name);
+		xfree(ref_name);
+
+		return error;
+	} else {
+		rb_raise(rb_eTypeError, "Expecting a String or Rugged::Branch instance");
+	}
+}
+
+/*
+ *  call-seq:
+ *    BranchCollection.new(repo) -> refs
+ *
+ *  Creates and returns a new collection of branches for the given +repo+.
+ */
+static VALUE rb_git_branch_collection_initialize(VALUE self, VALUE repo)
+{
+	rugged_set_owner(self, repo);
+	return self;
+}
+
+static git_branch_t parse_branch_type(VALUE rb_filter)
+{
+	ID id_filter;
+
+	Check_Type(rb_filter, T_SYMBOL);
+	id_filter = SYM2ID(rb_filter);
+
+	if (id_filter == rb_intern("local")) {
+		return GIT_BRANCH_LOCAL;
+	} else if (id_filter == rb_intern("remote")) {
+		return GIT_BRANCH_REMOTE;
+	} else {
+		rb_raise(rb_eTypeError,
+			"Invalid branch filter. Expected `:remote`, `:local` or `nil`");
+	}
+}
+
+/*
+ *  call-seq:
+ *    branches.create(name, target, options = {}) -> branch
+ *
+ *  Create a new branch with the given +name+, pointing to the +target+.
+ *
+ *  +name+ needs to be a branch name, not an absolute reference path
+ *  (e.g. +development+ instead of +refs/heads/development+).
+ *
+ *  +target+ needs to be an existing commit in the given repository.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :force ::
+ *    Overwrites the branch with the given +name+, if it already exists,
+ *    instead of raising an exception.
+ *
+ *  If a branch with the given +name+ already exists and +:force+ is not +true+,
+ *  an exception will be raised.
+ *
+ *  Returns a Rugged::Branch for the newly created branch.
+ */
+static VALUE rb_git_branch_collection_create(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_repo = rugged_owner(self), rb_name, rb_target, rb_options;
+	git_repository *repo;
+	git_reference *branch;
+	git_commit *target;
+	int error, force = 0;
+
+	rb_scan_args(argc, argv, "20:", &rb_name, &rb_target, &rb_options);
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Check_Type(rb_name, T_STRING);
+	Check_Type(rb_target, T_STRING);
+
+	if (!NIL_P(rb_options)) {
+		force = RTEST(rb_hash_aref(rb_options, CSTR2SYM("force")));
+	}
+
+	target = (git_commit *)rugged_object_get(repo, rb_target, GIT_OBJ_COMMIT);
+
+	error = git_branch_create(&branch, repo, StringValueCStr(rb_name), target, force);
+
+	git_commit_free(target);
+
+	rugged_exception_check(error);
+
+	return rugged_branch_new(rb_repo, branch);
+}
+
+/*
+ *  call-seq:
+ *    branches[name] -> branch
+ *
+ *  Return the branch with the given +name+.
+ *
+ *  Branches can be looked up by their relative (+development+) or absolute
+ *  (+refs/heads/development+) branch name.
+ *
+ *  If a local branch and a remote branch both share the same short name
+ *  (e.g. +refs/heads/origin/master+ and +refs/remotes/origin/master+),
+ *  passing +origin/master+ as the +name+ will return the local branch.
+ *  You can explicitly request the local branch by passing
+ *  +heads/origin/master+, or the remote branch through +remotes/origin/master+.
+ *
+ *  Returns the looked up branch, or +nil+ if the branch doesn't exist.
+ */
+static VALUE rb_git_branch_collection_aref(VALUE self, VALUE rb_name) {
+	git_reference *branch;
+	git_repository *repo;
+
+	VALUE rb_repo = rugged_owner(self);
+	int error;
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Check_Type(rb_name, T_STRING);
+
+	error = rugged_branch_lookup(&branch, repo, rb_name);
+	if (error == GIT_ENOTFOUND)
+		return Qnil;
+
+	rugged_exception_check(error);
+	return rugged_branch_new(rb_repo, branch);
+}
+
+static VALUE each_branch(int argc, VALUE *argv, VALUE self, int branch_names_only)
+{
+	VALUE rb_repo = rugged_owner(self), rb_filter;
+	git_repository *repo;
+	git_branch_iterator *iter;
+	int error, exception = 0;
+	git_branch_t filter = (GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE), branch_type;
+
+	rb_scan_args(argc, argv, "01", &rb_filter);
+
+	if (!rb_block_given_p()) {
+		VALUE symbol = branch_names_only ? CSTR2SYM("each_name") : CSTR2SYM("each");
+		return rb_funcall(self, rb_intern("to_enum"), 2, symbol, rb_filter);
+	}
+
+	rugged_check_repo(rb_repo);
+
+	if (!NIL_P(rb_filter))
+		filter = parse_branch_type(rb_filter);
+
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_branch_iterator_new(&iter, repo, filter);
+	rugged_exception_check(error);
+
+	if (branch_names_only) {
+		git_reference *branch;
+		while (!exception && (error = git_branch_next(&branch, &branch_type, iter)) == GIT_OK) {
+			rb_protect(rb_yield, rb_str_new_utf8(git_reference_shorthand(branch)), &exception);
+		}
+	} else {
+		git_reference *branch;
+		while (!exception && (error = git_branch_next(&branch, &branch_type, iter)) == GIT_OK) {
+			rb_protect(rb_yield, rugged_branch_new(rb_repo, branch), &exception);
+		}
+	}
+
+	git_branch_iterator_free(iter);
+
+	if (exception)
+		rb_jump_tag(exception);
+
+	if (error != GIT_ITEROVER)
+		rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    branches.each([filter]) { |branch| block }
+ *    branches.each([filter]) -> enumerator
+ *
+ *  Iterate through the branches in the collection. Iteration can be
+ *  optionally filtered to yield only +:local+ or +:remote+ branches.
+ *
+ *  The given block will be called once with a +Rugged::Branch+ object
+ *  for each branch in the repository. If no block is given, an enumerator
+ *  will be returned.
+ */
+static VALUE rb_git_branch_collection_each(int argc, VALUE *argv, VALUE self)
+{
+	return each_branch(argc, argv, self, 0);
+}
+
+/*
+ *  call-seq:
+ *    branches.each_name([filter]) { |branch_name| block }
+ *    branches.each_name([filter]) -> enumerator
+ *
+ *  Iterate through the names of the branches in the collection. Iteration can be
+ *  optionally filtered to yield only +:local+ or +:remote+ branches.
+ *
+ *  The given block will be called once with the name of each branch as a +String+.
+ *  If no block is given, an enumerator will be returned.
+ */
+static VALUE rb_git_branch_collection_each_name(int argc, VALUE *argv, VALUE self)
+{
+	return each_branch(argc, argv, self, 1);
+}
+
+/*
+ *  call-seq:
+ *    branches.delete(branch) -> nil
+ *    branches.delete(name) -> nil
+ *
+ *  Delete the specified branch.
+ *
+ *  If a Rugged::Branch object was passed, the object will become
+ *  invalidated and won't be able to be used for any other operations.
+ */
+static VALUE rb_git_branch_collection_delete(VALUE self, VALUE rb_name_or_branch)
+{
+	git_reference *branch;
+	git_repository *repo;
+
+	VALUE rb_repo = rugged_owner(self);
+	int error;
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = rugged_branch_lookup(&branch, repo, rb_name_or_branch);
+	rugged_exception_check(error);
+
+	error = git_branch_delete(branch);
+	git_reference_free(branch);
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    branch.move(old_name, new_name, options = {}) -> new_branch
+ *    branch.move(branch, new_name, options = {}) -> new_branch
+ *    branch.rename(old_name, new_name, options = {}) -> new_branch
+ *    branch.rename(branch, new_name, options = {}) -> new_branch
+ *
+ *  Rename a branch to +new_name+.
+ *
+ *  +new_name+ needs to be a branch name, not an absolute reference path
+ *  (e.g. +development+ instead of +refs/heads/development+).
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :force ::
+ *    Overwrites the branch with the given +name+, if it already exists,
+ *    instead of raising an exception.
+ *
+ *  If a branch with the given +new_name+ already exists and +:force+ is not +true+,
+ *  an exception will be raised.
+ *
+ *  A new Rugged::Branch object for the renamed branch will be returned.
+ *
+ */
+static VALUE rb_git_branch_collection_move(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_repo = rugged_owner(self), rb_name_or_branch, rb_new_branch_name, rb_options;
+	git_reference *old_branch = NULL, *new_branch = NULL;
+	git_repository *repo;
+	int error, force = 0;
+
+	rb_scan_args(argc, argv, "20:", &rb_name_or_branch, &rb_new_branch_name, &rb_options);
+	Check_Type(rb_new_branch_name, T_STRING);
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = rugged_branch_lookup(&old_branch, repo, rb_name_or_branch);
+	rugged_exception_check(error);
+
+	if (!NIL_P(rb_options)) {
+		force = RTEST(rb_hash_aref(rb_options, CSTR2SYM("force")));
+	}
+
+	error = git_branch_move(&new_branch, old_branch, StringValueCStr(rb_new_branch_name), force);
+
+	git_reference_free(old_branch);
+
+	rugged_exception_check(error);
+
+	return rugged_branch_new(rugged_owner(self), new_branch);
+}
+
+/*
+ *  call-seq:
+ *    branches.exist?(name) -> true or false
+ *    branches.exists?(name) -> true or false
+ *
+ *  Check if a branch exists with the given +name+.
+ */
+static VALUE rb_git_branch_collection_exist_p(VALUE self, VALUE rb_name)
+{
+	VALUE rb_repo = rugged_owner(self);
+	git_repository *repo;
+	git_reference *branch;
+	int error;
+
+	Check_Type(rb_name, T_STRING);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = rugged_branch_lookup(&branch, repo, rb_name);
+	git_reference_free(branch);
+
+	if (error == GIT_ENOTFOUND)
+		return Qfalse;
+	else
+		rugged_exception_check(error);
+
+	return Qtrue;
+}
+
+void Init_rugged_branch_collection(void)
+{
+	rb_cRuggedBranchCollection = rb_define_class_under(rb_mRugged, "BranchCollection", rb_cObject);
+	rb_include_module(rb_cRuggedBranchCollection, rb_mEnumerable);
+
+	rb_define_method(rb_cRuggedBranchCollection, "initialize", rb_git_branch_collection_initialize, 1);
+
+	rb_define_method(rb_cRuggedBranchCollection, "[]",         rb_git_branch_collection_aref, 1);
+	rb_define_method(rb_cRuggedBranchCollection, "create",     rb_git_branch_collection_create, -1);
+
+	rb_define_method(rb_cRuggedBranchCollection, "each",       rb_git_branch_collection_each, -1);
+	rb_define_method(rb_cRuggedBranchCollection, "each_name",  rb_git_branch_collection_each_name, -1);
+
+	rb_define_method(rb_cRuggedBranchCollection, "exist?",     rb_git_branch_collection_exist_p, 1);
+	rb_define_method(rb_cRuggedBranchCollection, "exists?",    rb_git_branch_collection_exist_p, 1);
+
+	rb_define_method(rb_cRuggedBranchCollection, "move",       rb_git_branch_collection_move, -1);
+	rb_define_method(rb_cRuggedBranchCollection, "rename",     rb_git_branch_collection_move, -1);
+	rb_define_method(rb_cRuggedBranchCollection, "delete",     rb_git_branch_collection_delete, 1);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_commit.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_commit.c
new file mode 100755
index 0000000..663e9ca
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_commit.c
@@ -0,0 +1,582 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedObject;
+extern VALUE rb_cRuggedRepo;
+extern VALUE rb_cRuggedSignature;
+VALUE rb_cRuggedCommit;
+
+/*
+ *  call-seq:
+ *    commit.message -> msg
+ *
+ *  Return the message of this commit. This includes the full body of the
+ *  message, with the short description, detailed descritpion, and any
+ *  optional footers or signatures after it.
+ *
+ *  In Ruby 1.9+, the returned string will be encoded with the encoding
+ *  specified in the +Encoding+ header of the commit, if available.
+ *
+ *    commit.message #=> "add a lot of RDoc docs\n\nthis includes docs for commit and blob"
+ */
+static VALUE rb_git_commit_message_GET(VALUE self)
+{
+	git_commit *commit;
+	rb_encoding *encoding = rb_utf8_encoding();
+	const char *encoding_name;
+	const char *message;
+
+	Data_Get_Struct(self, git_commit, commit);
+
+	message = git_commit_message(commit);
+	encoding_name = git_commit_message_encoding(commit);
+	if (encoding_name != NULL)
+		encoding = rb_enc_find(encoding_name);
+
+	return rb_enc_str_new(message, strlen(message), encoding);
+}
+
+/*
+ *  call-seq:
+ *    commit.committer -> signature
+ *
+ *  Return the signature for the committer of this +commit+. The signature
+ *  is returned as a +Hash+ containing +:name+, +:email+ of the author
+ *  and +:time+ of the change.
+ *
+ *  The committer of a commit is the person who actually applied the changes
+ *  of the commit; in most cases it's the same as the author.
+ *
+ *  In Ruby 1.9+, the returned string will be encoded with the encoding
+ *  specified in the +Encoding+ header of the commit, if available.
+ *
+ *    commit.committer #=> {:email=>"tanoku at gmail.com", :time=>Tue Jan 24 05:42:45 UTC 2012, :name=>"Vicent Mart\303\255"}
+ */
+static VALUE rb_git_commit_committer_GET(VALUE self)
+{
+	git_commit *commit;
+	Data_Get_Struct(self, git_commit, commit);
+
+	return rugged_signature_new(
+		git_commit_committer(commit),
+		git_commit_message_encoding(commit));
+}
+
+/*
+ *  call-seq:
+ *    commit.author -> signature
+ *
+ *  Return the signature for the author of this +commit+. The signature
+ *  is returned as a +Hash+ containing +:name+, +:email+ of the author
+ *  and +:time+ of the change.
+ *
+ *  The author of the commit is the person who intially created the changes.
+ *
+ *  In Ruby 1.9+, the returned string will be encoded with the encoding
+ *  specified in the +Encoding+ header of the commit, if available.
+ *
+ *    commit.author #=> {:email=>"tanoku at gmail.com", :time=>Tue Jan 24 05:42:45 UTC 2012, :name=>"Vicent Mart\303\255"}
+ */
+static VALUE rb_git_commit_author_GET(VALUE self)
+{
+	git_commit *commit;
+	Data_Get_Struct(self, git_commit, commit);
+
+	return rugged_signature_new(
+		git_commit_author(commit),
+		git_commit_message_encoding(commit));
+}
+
+/*
+ *  call-seq:
+ *    commit.epoch_time -> int
+ *
+ *  Return the time when this commit was made effective. This is the same value
+ *  as the +:time+ attribute for +commit.committer+, but represented as an +Integer+
+ *  value in seconds since the Epoch.
+ *
+ *    commit.time #=> 1327383765
+ */
+static VALUE rb_git_commit_epoch_time_GET(VALUE self)
+{
+	git_commit *commit;
+	Data_Get_Struct(self, git_commit, commit);
+
+	return ULONG2NUM(git_commit_time(commit));
+}
+
+/*
+ *  call-seq:
+ *    commit.tree -> tree
+ *
+ *  Return the tree pointed at by this +commit+. The tree is
+ *  returned as a +Rugged::Tree+ object.
+ *
+ *    commit.tree #=> #<Rugged::Tree:0x10882c680>
+ */
+static VALUE rb_git_commit_tree_GET(VALUE self)
+{
+	git_commit *commit;
+	git_tree *tree;
+	VALUE owner;
+	int error;
+
+	Data_Get_Struct(self, git_commit, commit);
+	owner = rugged_owner(self);
+
+	error = git_commit_tree(&tree, commit);
+	rugged_exception_check(error);
+
+	return rugged_object_new(owner, (git_object *)tree);
+}
+
+/*
+ *  call-seq:
+ *    commit.tree_id -> oid
+ *
+ *  Return the tree oid pointed at by this +commit+. The tree is
+ *  returned as a String object.
+ *
+ *    commit.tree_id #=> "f148106ca58764adc93ad4e2d6b1d168422b9796"
+ */
+static VALUE rb_git_commit_tree_id_GET(VALUE self)
+{
+	git_commit *commit;
+	const git_oid *tree_id;
+
+	Data_Get_Struct(self, git_commit, commit);
+
+	tree_id = git_commit_tree_id(commit);
+
+	return rugged_create_oid(tree_id);
+}
+
+/*
+ *  call-seq:
+ *    commit.parents -> [commit, ...]
+ *
+ *  Return the parent(s) of this commit as an array of +Rugged::Commit+
+ *  objects. An array is always returned even when the commit has only
+ *  one or zero parents.
+ *
+ *    commit.parents #=> => [#<Rugged::Commit:0x108828918>]
+ *    root.parents #=> []
+ */
+static VALUE rb_git_commit_parents_GET(VALUE self)
+{
+	git_commit *commit;
+	git_commit *parent;
+	unsigned int n, parent_count;
+	VALUE ret_arr, owner;
+	int error;
+
+	Data_Get_Struct(self, git_commit, commit);
+	owner = rugged_owner(self);
+
+	parent_count = git_commit_parentcount(commit);
+	ret_arr = rb_ary_new2((long)parent_count);
+
+	for (n = 0; n < parent_count; n++) {
+		error = git_commit_parent(&parent, commit, n);
+		rugged_exception_check(error);
+		rb_ary_push(ret_arr, rugged_object_new(owner, (git_object *)parent));
+	}
+
+	return ret_arr;
+}
+
+/*
+ *  call-seq:
+ *    commit.parent_ids -> [oid, ...]
+ *
+ *  Return the parent oid(s) of this commit as an array of oid String
+ *  objects. An array is always returned even when the commit has only
+ *  one or zero parents.
+ *
+ *    commit.parent_ids #=> => ["2cb831a8aea28b2c1b9c63385585b864e4d3bad1", ...]
+ *    root.parent_ids #=> []
+ */
+static VALUE rb_git_commit_parent_ids_GET(VALUE self)
+{
+	git_commit *commit;
+	const git_oid *parent_id;
+	unsigned int n, parent_count;
+	VALUE ret_arr;
+
+	Data_Get_Struct(self, git_commit, commit);
+
+	parent_count = git_commit_parentcount(commit);
+	ret_arr = rb_ary_new2((long)parent_count);
+
+	for (n = 0; n < parent_count; n++) {
+		parent_id = git_commit_parent_id(commit, n);
+		if (parent_id) {
+			rb_ary_push(ret_arr, rugged_create_oid(parent_id));
+		}
+	}
+
+	return ret_arr;
+}
+
+/*
+ *  call-seq:
+ *    commit.amend(data = {}) -> oid
+ *
+ *  Amend a commit object, with the given +data+
+ *  arguments, passed as a +Hash+:
+ *
+ *  - +:message+: a string with the full text for the commit's message
+ *  - +:committer+ (optional): a hash with the signature for the committer,
+ *    defaults to the signature from the configuration
+ *  - +:author+ (optional): a hash with the signature for the author,
+ *    defaults to the signature from the configuration
+ *  - +:tree+: the tree for this amended commit, represented as a <tt>Rugged::Tree</tt>
+ *    instance or an OID +String+.
+ *  - +:update_ref+ (optional): a +String+ with the name of a reference in the
+ *  repository which should be updated to point to this amended commit (e.g. "HEAD")
+ *
+ *  When the amended commit is successfully written to disk, its +oid+ will be
+ *  returned as a hex +String+.
+ *
+ *    author = {:email=>"tanoku at gmail.com", :time=>Time.now, :name=>"Vicent Mart\303\255"}
+ *
+ *    commit.amend(
+ *      :author => author,
+ *      :message => "Updated Hello world\n\n",
+ *      :committer => author,
+ *      :tree => some_tree) #=> "f148106ca58764adc93ad4e2d6b1d168422b9796"
+ */
+static VALUE rb_git_commit_amend(VALUE self, VALUE rb_data)
+{
+	VALUE rb_message, rb_tree, rb_ref, owner;
+	int error = 0;
+	git_commit *commit_to_amend;
+	char *message = NULL;
+	git_tree *tree = NULL;
+	git_signature *author = NULL, *committer = NULL;
+	git_oid commit_oid;
+	git_repository *repo;
+	const char *update_ref = NULL;
+
+	Check_Type(rb_data, T_HASH);
+
+	Data_Get_Struct(self, git_commit, commit_to_amend);
+
+	owner = rugged_owner(self);
+	Data_Get_Struct(owner, git_repository, repo);
+
+	rb_ref = rb_hash_aref(rb_data, CSTR2SYM("update_ref"));
+	if (!NIL_P(rb_ref)) {
+		Check_Type(rb_ref, T_STRING);
+		update_ref = StringValueCStr(rb_ref);
+	}
+
+	rb_message = rb_hash_aref(rb_data, CSTR2SYM("message"));
+	if (!NIL_P(rb_message)) {
+		Check_Type(rb_message, T_STRING);
+		message = StringValueCStr(rb_message);
+	}
+
+	rb_tree = rb_hash_aref(rb_data, CSTR2SYM("tree"));
+	if (!NIL_P(rb_tree))
+		tree = (git_tree *)rugged_object_get(repo, rb_tree, GIT_OBJ_TREE);
+
+	if (!NIL_P(rb_hash_aref(rb_data, CSTR2SYM("committer")))) {
+		committer = rugged_signature_get(
+			rb_hash_aref(rb_data, CSTR2SYM("committer")), repo
+		);
+	}
+
+	if (!NIL_P(rb_hash_aref(rb_data, CSTR2SYM("author")))) {
+		author = rugged_signature_get(
+			rb_hash_aref(rb_data, CSTR2SYM("author")), repo
+		);
+	}
+
+	error = git_commit_amend(
+		&commit_oid,
+		commit_to_amend,
+		update_ref,
+		author,
+		committer,
+		NULL,
+		message,
+		tree);
+
+	git_signature_free(author);
+	git_signature_free(committer);
+
+	git_object_free((git_object *)tree);
+
+	rugged_exception_check(error);
+
+	return rugged_create_oid(&commit_oid);
+}
+
+/*
+ *  call-seq:
+ *    Commit.create(repository, data = {}) -> oid
+ *
+ *  Write a new +Commit+ object to +repository+, with the given +data+
+ *  arguments, passed as a +Hash+:
+ *
+ *  - +:message+: a string with the full text for the commit's message
+ *  - +:committer+ (optional): a hash with the signature for the committer,
+ *    defaults to the signature from the configuration
+ *  - +:author+ (optional): a hash with the signature for the author,
+ *    defaults to the signature from the configuration
+ *  - +:parents+: an +Array+ with zero or more parents for this commit,
+ *    represented as <tt>Rugged::Commit</tt> instances, or OID +String+.
+ *  - +:tree+: the tree for this commit, represented as a <tt>Rugged::Tree</tt>
+ *    instance or an OID +String+.
+ *  - +:update_ref+ (optional): a +String+ with the name of a reference in the
+ *    repository which should be updated to point to this commit (e.g. "HEAD")
+ *
+ *  When the commit is successfully written to disk, its +oid+ will be
+ *  returned as a hex +String+.
+ *
+ *    author = {:email=>"tanoku at gmail.com", :time=>Time.now, :name=>"Vicent Mart\303\255"}
+ *
+ *    Rugged::Commit.create(r,
+ *      :author => author,
+ *      :message => "Hello world\n\n",
+ *      :committer => author,
+ *      :parents => ["2cb831a8aea28b2c1b9c63385585b864e4d3bad1"],
+ *      :tree => some_tree) #=> "f148106ca58764adc93ad4e2d6b1d168422b9796"
+ */
+static VALUE rb_git_commit_create(VALUE self, VALUE rb_repo, VALUE rb_data)
+{
+	VALUE rb_message, rb_tree, rb_parents, rb_ref;
+	VALUE rb_err_obj = Qnil;
+	int parent_count, i, error = 0;
+	const git_commit **parents = NULL;
+	git_commit **free_list = NULL;
+	git_tree *tree;
+	git_signature *author, *committer;
+	git_oid commit_oid;
+	git_repository *repo;
+	const char *update_ref = NULL;
+
+	Check_Type(rb_data, T_HASH);
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	rb_ref = rb_hash_aref(rb_data, CSTR2SYM("update_ref"));
+	if (!NIL_P(rb_ref)) {
+		Check_Type(rb_ref, T_STRING);
+		update_ref = StringValueCStr(rb_ref);
+	}
+
+	rb_message = rb_hash_aref(rb_data, CSTR2SYM("message"));
+	Check_Type(rb_message, T_STRING);
+
+	committer = rugged_signature_get(
+		rb_hash_aref(rb_data, CSTR2SYM("committer")), repo
+	);
+
+	author = rugged_signature_get(
+		rb_hash_aref(rb_data, CSTR2SYM("author")), repo
+	);
+
+	rb_parents = rb_hash_aref(rb_data, CSTR2SYM("parents"));
+	Check_Type(rb_parents, T_ARRAY);
+
+	rb_tree = rb_hash_aref(rb_data, CSTR2SYM("tree"));
+	tree = (git_tree *)rugged_object_get(repo, rb_tree, GIT_OBJ_TREE);
+
+	parents = alloca(RARRAY_LEN(rb_parents) * sizeof(void *));
+	free_list = alloca(RARRAY_LEN(rb_parents) * sizeof(void *));
+	parent_count = 0;
+
+	for (i = 0; i < (int)RARRAY_LEN(rb_parents); ++i) {
+		VALUE p = rb_ary_entry(rb_parents, i);
+		git_commit *parent = NULL;
+		git_commit *free_ptr = NULL;
+
+		if (NIL_P(p))
+			continue;
+
+		if (TYPE(p) == T_STRING) {
+			git_oid oid;
+
+			error = git_oid_fromstr(&oid, StringValueCStr(p));
+			if (error < GIT_OK)
+				goto cleanup;
+
+			error = git_commit_lookup(&parent, repo, &oid);
+			if (error < GIT_OK)
+				goto cleanup;
+
+			free_ptr = parent;
+
+		} else if (rb_obj_is_kind_of(p, rb_cRuggedCommit)) {
+			Data_Get_Struct(p, git_commit, parent);
+		} else {
+			rb_err_obj = rb_exc_new2(rb_eTypeError, "Invalid type for parent object");
+			goto cleanup;
+		}
+
+		parents[parent_count] = parent;
+		free_list[parent_count] = free_ptr;
+		parent_count++;
+	}
+
+	error = git_commit_create(
+		&commit_oid,
+		repo,
+		update_ref,
+		author,
+		committer,
+		NULL,
+		StringValueCStr(rb_message),
+		tree,
+		parent_count,
+		parents);
+
+cleanup:
+	git_signature_free(author);
+	git_signature_free(committer);
+
+	git_object_free((git_object *)tree);
+
+	for (i = 0; i < parent_count; ++i)
+		git_object_free((git_object *)free_list[i]);
+
+	if (!NIL_P(rb_err_obj))
+		rb_exc_raise(rb_err_obj);
+
+	rugged_exception_check(error);
+
+	return rugged_create_oid(&commit_oid);
+}
+
+/*
+ *  call-seq:
+ *    commit.to_mbox(options = {}) -> str
+ *
+ *  Returns +commit+'s contents formatted to resemble UNIX mailbox format.
+ *
+ *  Does not (yet) support merge commits.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :patch_no ::
+ *    Number for this patch in the series. Defaults to +1+.
+ *
+ *  :total_patches ::
+ *    Total number of patches in the series. Defaults to +1+.
+ *
+ *  :exclude_subject_patch_marker ::
+ *    If set to true, no "[PATCH]" marker will be
+ *    added to the beginning of the subject line.
+ *
+ *  Additionally, you can also pass the same options as for Rugged::Tree#diff.
+ */
+static VALUE rb_git_commit_to_mbox(int argc, VALUE *argv, VALUE self)
+{
+	git_buf email_patch = { NULL };
+	git_repository *repo;
+	git_commit *commit;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_format_email_flags_t flags = GIT_DIFF_FORMAT_EMAIL_NONE;
+
+	VALUE rb_repo = rugged_owner(self), rb_email_patch = Qnil, rb_val, rb_options;
+
+	int error;
+	size_t patch_no = 1, total_patches = 1;
+
+	rb_scan_args(argc, argv, ":", &rb_options);
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Data_Get_Struct(self, git_commit, commit);
+
+	if (!NIL_P(rb_options)) {
+		Check_Type(rb_options, T_HASH);
+
+		rb_val = rb_hash_aref(rb_options, CSTR2SYM("patch_no"));
+		if (!NIL_P(rb_val))
+			patch_no = NUM2INT(rb_val);
+
+		rb_val = rb_hash_aref(rb_options, CSTR2SYM("total_patches"));
+		if (!NIL_P(rb_val))
+			total_patches = NUM2INT(rb_val);
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("exclude_subject_patch_marker"))))
+			flags |= GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER;
+
+		rugged_parse_diff_options(&opts, rb_options);
+	}
+
+	error = git_diff_commit_as_email(
+		&email_patch,
+		repo,
+		commit,
+		patch_no,
+		total_patches,
+		flags,
+		&opts);
+
+	if (error) goto cleanup;
+
+	rb_email_patch = rb_enc_str_new(email_patch.ptr, email_patch.size, rb_utf8_encoding());
+
+	cleanup:
+
+	xfree(opts.pathspec.strings);
+	git_buf_free(&email_patch);
+	rugged_exception_check(error);
+
+	return rb_email_patch;
+}
+
+
+void Init_rugged_commit(void)
+{
+	rb_cRuggedCommit = rb_define_class_under(rb_mRugged, "Commit", rb_cRuggedObject);
+
+	rb_define_singleton_method(rb_cRuggedCommit, "create", rb_git_commit_create, 2);
+
+	rb_define_method(rb_cRuggedCommit, "message", rb_git_commit_message_GET, 0);
+	rb_define_method(rb_cRuggedCommit, "epoch_time", rb_git_commit_epoch_time_GET, 0);
+	rb_define_method(rb_cRuggedCommit, "committer", rb_git_commit_committer_GET, 0);
+	rb_define_method(rb_cRuggedCommit, "author", rb_git_commit_author_GET, 0);
+	rb_define_method(rb_cRuggedCommit, "tree", rb_git_commit_tree_GET, 0);
+
+	rb_define_method(rb_cRuggedCommit, "tree_id", rb_git_commit_tree_id_GET, 0);
+	rb_define_method(rb_cRuggedCommit, "tree_oid", rb_git_commit_tree_id_GET, 0);
+
+	rb_define_method(rb_cRuggedCommit, "parents", rb_git_commit_parents_GET, 0);
+	rb_define_method(rb_cRuggedCommit, "parent_ids", rb_git_commit_parent_ids_GET, 0);
+	rb_define_method(rb_cRuggedCommit, "parent_oids", rb_git_commit_parent_ids_GET, 0);
+
+	rb_define_method(rb_cRuggedCommit, "amend", rb_git_commit_amend, 1);
+
+	rb_define_method(rb_cRuggedCommit, "to_mbox", rb_git_commit_to_mbox, -1);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_config.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_config.c
new file mode 100755
index 0000000..1c97a16
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_config.c
@@ -0,0 +1,333 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+VALUE rb_cRuggedConfig;
+
+void rb_git_config__free(git_config *config)
+{
+	git_config_free(config);
+}
+
+VALUE rugged_config_new(VALUE klass, VALUE owner, git_config *cfg)
+{
+	VALUE rb_config = Data_Wrap_Struct(klass, NULL, &rb_git_config__free, cfg);
+	rugged_set_owner(rb_config, owner);
+	return rb_config;
+}
+
+/*
+ *  call-seq:
+ *    Config.new(path) -> new_config
+ *
+ *  Open the file specified in +path+ as a +Rugged::Config+ file.
+ *  If +path+ cannot be found, or the file is an invalid Git config,
+ *  an exception will be raised.
+ */
+static VALUE rb_git_config_new(VALUE klass, VALUE rb_path)
+{
+	git_config *config = NULL;
+	int error, i;
+
+	if (TYPE(rb_path) == T_ARRAY) {
+		error = git_config_new(&config);
+		rugged_exception_check(error);
+
+		for (i = 0; i < RARRAY_LEN(rb_path); ++i) {
+			VALUE f = rb_ary_entry(rb_path, i);
+			Check_Type(f, T_STRING);
+			error = git_config_add_file_ondisk(config, StringValueCStr(f), i + 1, 1);
+			rugged_exception_check(error);
+		}
+	} else if (TYPE(rb_path) == T_STRING) {
+		error = git_config_open_ondisk(&config, StringValueCStr(rb_path));
+		rugged_exception_check(error);
+	} else {
+		rb_raise(rb_eTypeError, "Expecting a filename or an array of filenames");
+	}
+
+	return rugged_config_new(klass, Qnil, config);
+}
+
+/*
+ *  call-seq:
+ *    cfg.get(key) -> value
+ *    cfg[key] -> value
+ *
+ *  Get the value for the given config +key+. Values are always
+ *  returned as +String+, or +nil+ if the given key doesn't exist
+ *  in the Config file.
+ *
+ *    cfg['apply.whitespace'] #=> 'fix'
+ *    cfg['diff.renames'] #=> 'true'
+ */
+static VALUE rb_git_config_get(VALUE self, VALUE rb_key)
+{
+	git_config *config;
+	git_buf buf = { NULL };
+	int error;
+	VALUE rb_result;
+
+	Data_Get_Struct(self, git_config, config);
+	Check_Type(rb_key, T_STRING);
+
+	error = git_config_get_string_buf(&buf, config, StringValueCStr(rb_key));
+	if (error == GIT_ENOTFOUND)
+		return Qnil;
+
+	rugged_exception_check(error);
+	rb_result = rb_str_new_utf8(buf.ptr);
+	git_buf_free(&buf);
+
+	return rb_result;
+}
+
+/*
+ *  call-seq:
+ *    cfg.store(key, value)
+ *    cfg[key] = value
+ *
+ *  Store the given +value+ in the Config file, under the section
+ *  and name specified by +key+. Value can be any of the following
+ *  Ruby types: +String+, +true+, +false+ and +Fixnum+.
+ *
+ *  The config file will be automatically stored to disk.
+ *
+ *    cfg['apply.whitespace'] = 'fix'
+ *    cfg['diff.renames'] = true
+ *    cfg['gc.reflogexpre'] = 90
+ */
+static VALUE rb_git_config_store(VALUE self, VALUE rb_key, VALUE rb_val)
+{
+	git_config *config;
+	const char *key;
+	int error;
+
+	Data_Get_Struct(self, git_config, config);
+	Check_Type(rb_key, T_STRING);
+
+	key = StringValueCStr(rb_key);
+
+	switch (TYPE(rb_val)) {
+	case T_STRING:
+		error = git_config_set_string(config, key, StringValueCStr(rb_val));
+		break;
+
+	case T_TRUE:
+	case T_FALSE:
+		error = git_config_set_bool(config, key, (rb_val == Qtrue));
+		break;
+
+	case T_FIXNUM:
+		error = git_config_set_int32(config, key, FIX2INT(rb_val));
+		break;
+
+	default:
+		rb_raise(rb_eTypeError,
+			"Invalid value; config files can only store string, bool or int keys");
+	}
+
+	rugged_exception_check(error);
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    cfg.delete(key) -> true or false
+ *
+ *  Delete the given +key+ from the config file. Return +true+ if
+ *  the deletion was successful, or +false+ if the key was not
+ *  found in the Config file.
+ *
+ *  The config file is immediately updated on disk.
+ */
+static VALUE rb_git_config_delete(VALUE self, VALUE rb_key)
+{
+	git_config *config;
+	int error;
+
+	Data_Get_Struct(self, git_config, config);
+	Check_Type(rb_key, T_STRING);
+
+	error = git_config_delete_entry(config, StringValueCStr(rb_key));
+	if (error == GIT_ENOTFOUND)
+		return Qfalse;
+
+	rugged_exception_check(error);
+	return Qtrue;
+}
+
+static int cb_config__each_key(const git_config_entry *entry, void *opaque)
+{
+	rb_funcall((VALUE)opaque, rb_intern("call"), 1, rb_str_new_utf8(entry->name));
+	return GIT_OK;
+}
+
+static int cb_config__each_pair(const git_config_entry *entry, void *opaque)
+{
+	rb_funcall((VALUE)opaque, rb_intern("call"), 2,
+		rb_str_new_utf8(entry->name),
+		rb_str_new_utf8(entry->value)
+	);
+
+	return GIT_OK;
+}
+
+static int cb_config__to_hash(const git_config_entry *entry, void *opaque)
+{
+	rb_hash_aset((VALUE)opaque,
+		rb_str_new_utf8(entry->name),
+		rb_str_new_utf8(entry->value)
+	);
+
+	return GIT_OK;
+}
+
+/*
+ *  call-seq:
+ *    cfg.each_key { |key| block }
+ *    cfg.each_key -> enumarator
+ *
+ *  Call the given block once for each key in the config file. If no block
+ *  is given, an enumerator is returned.
+ *
+ *    cfg.each_key do |key|
+ *      puts key
+ *    end
+ */
+static VALUE rb_git_config_each_key(VALUE self)
+{
+	git_config *config;
+	int error;
+
+	Data_Get_Struct(self, git_config, config);
+
+	if (!rb_block_given_p())
+		return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("each_key"));
+
+	error = git_config_foreach(config, &cb_config__each_key, (void *)rb_block_proc());
+	rugged_exception_check(error);
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    cfg.each_pair { |key, value| block }
+ *    cfg.each_pair -> enumerator
+ *    cfg.each { |key, value| block }
+ *    cfg.each -> enumerator
+ *
+ *  Call the given block once for each key/value pair in the config file.
+ *  If no block is given, an enumerator is returned.
+ *
+ *    cfg.each do |key, value|
+ *      puts "#{key} => #{value}"
+ *    end
+ */
+static VALUE rb_git_config_each_pair(VALUE self)
+{
+	git_config *config;
+	int error;
+
+	Data_Get_Struct(self, git_config, config);
+
+	if (!rb_block_given_p())
+		return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("each_pair"));
+
+	error = git_config_foreach(config, &cb_config__each_pair, (void *)rb_block_proc());
+	rugged_exception_check(error);
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    cfg.to_hash -> hash
+ *
+ *  Returns the config file represented as a Ruby hash, where
+ *  each configuration entry appears as a key with its
+ *  corresponding value.
+ *
+ *    cfg.to_hash #=> {"core.autolf" => "true", "core.bare" => "true"}
+ */
+static VALUE rb_git_config_to_hash(VALUE self)
+{
+	git_config *config;
+	int error;
+	VALUE hash;
+
+	Data_Get_Struct(self, git_config, config);
+	hash = rb_hash_new();
+
+	error = git_config_foreach(config, &cb_config__to_hash, (void *)hash);
+	rugged_exception_check(error);
+	return hash;
+}
+
+/*
+ *  call-seq:
+ *    Config.global() -> new_config
+ *    Config.open_global() -> new_config
+ *
+ *  Open the default global config file as a new +Rugged::Config+ object.
+ *  An exception will be raised if the global config file doesn't
+ *  exist.
+ */
+static VALUE rb_git_config_open_default(VALUE klass)
+{
+	git_config *cfg;
+	int error;
+
+	error = git_config_open_default(&cfg);
+	rugged_exception_check(error);
+
+	return rugged_config_new(klass, Qnil, cfg);
+}
+
+void Init_rugged_config(void)
+{
+	/*
+	 * Config
+	 */
+	rb_cRuggedConfig = rb_define_class_under(rb_mRugged, "Config", rb_cObject);
+	rb_define_singleton_method(rb_cRuggedConfig, "new", rb_git_config_new, 1);
+
+	rb_define_singleton_method(rb_cRuggedConfig, "global", rb_git_config_open_default, 0);
+	rb_define_singleton_method(rb_cRuggedConfig, "open_global", rb_git_config_open_default, 0);
+
+	rb_define_method(rb_cRuggedConfig, "delete", rb_git_config_delete, 1);
+
+	rb_define_method(rb_cRuggedConfig, "store", rb_git_config_store, 2);
+	rb_define_method(rb_cRuggedConfig, "[]=", rb_git_config_store, 2);
+
+	rb_define_method(rb_cRuggedConfig, "get", rb_git_config_get, 1);
+	rb_define_method(rb_cRuggedConfig, "[]", rb_git_config_get, 1);
+
+	rb_define_method(rb_cRuggedConfig, "each_key", rb_git_config_each_key, 0);
+	rb_define_method(rb_cRuggedConfig, "each_pair", rb_git_config_each_pair, 0);
+	rb_define_method(rb_cRuggedConfig, "each", rb_git_config_each_pair, 0);
+	rb_define_method(rb_cRuggedConfig, "to_hash", rb_git_config_to_hash, 0);
+
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_cred.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_cred.c
new file mode 100755
index 0000000..eeebf06
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_cred.c
@@ -0,0 +1,148 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+VALUE rb_mRuggedCred;
+VALUE rb_cRuggedCredUserPassword;
+VALUE rb_cRuggedCredSshKey;
+VALUE rb_cRuggedCredSshKeyFromAgent;
+VALUE rb_cRuggedCredDefault;
+
+static void rugged_cred_extract_userpass(git_cred **cred, VALUE rb_credential)
+{
+	VALUE rb_username = rb_iv_get(rb_credential, "@username");
+	VALUE rb_password = rb_iv_get(rb_credential, "@password");
+
+	Check_Type(rb_username, T_STRING);
+	Check_Type(rb_password, T_STRING);
+
+	rugged_exception_check(
+		git_cred_userpass_plaintext_new(cred,
+			StringValueCStr(rb_username),
+			StringValueCStr(rb_password)
+		)
+	);
+}
+
+static void rugged_cred_extract_ssh_key(git_cred **cred, VALUE rb_credential)
+{
+	VALUE rb_username   = rb_iv_get(rb_credential, "@username");
+	VALUE rb_publickey  = rb_iv_get(rb_credential, "@publickey");
+	VALUE rb_privatekey = rb_iv_get(rb_credential, "@privatekey");
+	VALUE rb_passphrase = rb_iv_get(rb_credential, "@passphrase");
+
+	Check_Type(rb_username, T_STRING);
+	Check_Type(rb_privatekey, T_STRING);
+
+	if (!NIL_P(rb_publickey))
+		Check_Type(rb_publickey, T_STRING);
+	if (!NIL_P(rb_passphrase))
+		Check_Type(rb_passphrase, T_STRING);
+
+	rugged_exception_check(
+		git_cred_ssh_key_new(cred,
+			StringValueCStr(rb_username),
+			NIL_P(rb_publickey) ? NULL : StringValueCStr(rb_publickey),
+			StringValueCStr(rb_privatekey),
+			NIL_P(rb_passphrase) ? NULL : StringValueCStr(rb_passphrase)
+		)
+	);
+}
+
+static void rugged_credential_extract_ssh_key_from_agent(git_cred **cred, VALUE rb_credential)
+{
+	VALUE rb_username = rb_iv_get(rb_credential, "@username");
+
+	Check_Type(rb_username, T_STRING);
+
+	rugged_exception_check(
+		git_cred_ssh_key_from_agent(cred, StringValueCStr(rb_username))
+	);
+}
+
+static void rugged_cred_extract_default(git_cred **cred, VALUE rb_credential)
+{
+	rugged_exception_check(git_cred_default_new(cred));
+}
+
+static void rugged_cred_extract_username(git_cred **cred, VALUE rb_credential)
+{
+	VALUE rb_username = rb_iv_get(rb_credential, "@username");
+	Check_Type(rb_username, T_STRING);
+
+	rugged_exception_check(git_cred_username_new(cred, StringValueCStr(rb_username)));
+}
+
+void rugged_cred_extract(git_cred **cred, int allowed_types, VALUE rb_credential)
+{
+	if (rb_obj_is_kind_of(rb_credential, rb_cRuggedCredUserPassword)) {
+		if (allowed_types & GIT_CREDTYPE_USERNAME) {
+			rugged_cred_extract_username(cred, rb_credential);
+			return;
+		}
+
+		if (!(allowed_types & GIT_CREDTYPE_USERPASS_PLAINTEXT))
+			rb_raise(rb_eArgError, "Invalid credential type");
+
+		rugged_cred_extract_userpass(cred, rb_credential);
+	} else if (rb_obj_is_kind_of(rb_credential, rb_cRuggedCredSshKey)) {
+		if (allowed_types & GIT_CREDTYPE_USERNAME) {
+			rugged_cred_extract_username(cred, rb_credential);
+			return;
+		}
+
+		if (!(allowed_types & GIT_CREDTYPE_SSH_KEY))
+			rb_raise(rb_eArgError, "Invalid credential type");
+
+		rugged_cred_extract_ssh_key(cred, rb_credential);
+	} else if (rb_obj_is_kind_of(rb_credential, rb_cRuggedCredSshKeyFromAgent)) {
+		if (allowed_types & GIT_CREDTYPE_USERNAME) {
+			rugged_cred_extract_username(cred, rb_credential);
+			return;
+		}
+
+		if (!(allowed_types & GIT_CREDTYPE_SSH_KEY))
+			rb_raise(rb_eArgError, "Invalid credential type");
+
+		rugged_credential_extract_ssh_key_from_agent(cred, rb_credential);
+	} else if (rb_obj_is_kind_of(rb_credential, rb_cRuggedCredDefault)) {
+		if (!(allowed_types & GIT_CREDTYPE_DEFAULT))
+			rb_raise(rb_eArgError, "Invalid credential type");
+
+		rugged_cred_extract_default(cred, rb_credential);
+	}
+}
+
+
+void Init_rugged_cred(void)
+{
+	rb_mRuggedCred                = rb_define_module_under(rb_mRugged, "Credentials");
+
+	rb_cRuggedCredUserPassword    = rb_define_class_under(rb_mRuggedCred, "UserPassword", rb_cObject);
+	rb_cRuggedCredSshKey          = rb_define_class_under(rb_mRuggedCred, "SshKey", rb_cObject);
+	rb_cRuggedCredSshKeyFromAgent = rb_define_class_under(rb_mRuggedCred, "SshKeyFromAgent", rb_cObject);
+	rb_cRuggedCredDefault         = rb_define_class_under(rb_mRuggedCred, "Default", rb_cObject);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_diff.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_diff.c
new file mode 100755
index 0000000..3f5ff37
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_diff.c
@@ -0,0 +1,686 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+VALUE rb_cRuggedDiff;
+
+VALUE rugged_diff_new(VALUE klass, VALUE owner, git_diff *diff)
+{
+	VALUE rb_diff = Data_Wrap_Struct(klass, NULL, git_diff_free, diff);
+	rugged_set_owner(rb_diff, owner);
+	return rb_diff;
+}
+
+/**
+ * The caller has to free the returned git_diff_options pathspec strings array.
+ */
+void rugged_parse_diff_options(git_diff_options *opts, VALUE rb_options)
+{
+	if (!NIL_P(rb_options)) {
+		VALUE rb_value;
+		Check_Type(rb_options, T_HASH);
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("reverse")))) {
+			opts->flags |= GIT_DIFF_REVERSE;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("include_ignored")))) {
+			opts->flags |= GIT_DIFF_INCLUDE_IGNORED;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("recurse_ignored_dirs")))) {
+			opts->flags |= GIT_DIFF_RECURSE_IGNORED_DIRS;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("include_untracked")))) {
+			opts->flags |= GIT_DIFF_INCLUDE_UNTRACKED;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("recurse_untracked_dirs")))) {
+			opts->flags |= GIT_DIFF_RECURSE_UNTRACKED_DIRS;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("include_unmodified")))) {
+			opts->flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("include_typechange")))) {
+			opts->flags |= GIT_DIFF_INCLUDE_TYPECHANGE;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("include_typechange_trees")))) {
+			opts->flags |= GIT_DIFF_INCLUDE_TYPECHANGE_TREES;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("ignore_filemode")))) {
+			opts->flags |= GIT_DIFF_IGNORE_FILEMODE;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("ignore_submodules")))) {
+			opts->flags |= GIT_DIFF_IGNORE_SUBMODULES;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("ignore_case")))) {
+			opts->flags |= GIT_DIFF_IGNORE_CASE;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("disable_pathspec_match")))) {
+			opts->flags |= GIT_DIFF_DISABLE_PATHSPEC_MATCH;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("skip_binary_check")))) {
+			opts->flags |= GIT_DIFF_SKIP_BINARY_CHECK;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("fast_untracked_dirs")))) {
+			opts->flags |= GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("force_text")))) {
+			opts->flags |= GIT_DIFF_FORCE_TEXT;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("force_binary")))) {
+			opts->flags |= GIT_DIFF_FORCE_BINARY;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("ignore_whitespace")))) {
+			opts->flags |= GIT_DIFF_IGNORE_WHITESPACE;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("ignore_whitespace_change")))) {
+			opts->flags |= GIT_DIFF_IGNORE_WHITESPACE_CHANGE;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("ignore_whitespace_eol")))) {
+			opts->flags |= GIT_DIFF_IGNORE_WHITESPACE_EOL;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("show_untracked_content")))) {
+			opts->flags |= GIT_DIFF_SHOW_UNTRACKED_CONTENT;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("show_unmodified")))) {
+			opts->flags |= GIT_DIFF_SHOW_UNMODIFIED;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("show_binary")))) {
+			opts->flags |= GIT_DIFF_SHOW_BINARY;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("patience")))) {
+			opts->flags |= GIT_DIFF_PATIENCE;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("minimal")))) {
+			opts->flags |= GIT_DIFF_MINIMAL;
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("paths"));
+		if (!NIL_P(rb_value)) {
+			int i;
+			Check_Type(rb_value, T_ARRAY);
+
+			for (i = 0; i < RARRAY_LEN(rb_value); ++i)
+				Check_Type(rb_ary_entry(rb_value, i), T_STRING);
+
+			opts->pathspec.count = RARRAY_LEN(rb_value);
+			opts->pathspec.strings = xmalloc(opts->pathspec.count * sizeof(char *));
+
+			for (i = 0; i < RARRAY_LEN(rb_value); ++i) {
+				VALUE rb_path = rb_ary_entry(rb_value, i);
+				opts->pathspec.strings[i] = StringValueCStr(rb_path);
+			}
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("context_lines"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts->context_lines = FIX2INT(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("interhunk_lines"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts->interhunk_lines = FIX2INT(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("id_abbrev"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts->id_abbrev = FIX2INT(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("max_size"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts->max_size = FIX2INT(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("old_prefix"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_STRING);
+			opts->old_prefix = StringValueCStr(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("new_prefix"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_STRING);
+			opts->new_prefix = StringValueCStr(rb_value);
+		}
+	}
+}
+
+static int diff_print_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *payload)
+{
+	VALUE rb_str = (VALUE)payload;
+
+	switch (line->origin) {
+		case GIT_DIFF_LINE_CONTEXT:
+		case GIT_DIFF_LINE_ADDITION:
+		case GIT_DIFF_LINE_DELETION:
+			rb_str_cat(rb_str, &line->origin, 1);
+	}
+
+	rb_str_cat(rb_str, line->content, line->content_len);
+
+	return GIT_OK;
+}
+
+/*
+ *  call-seq:
+ *    diff.patch -> patch
+ *    diff.patch(:compact => true) -> compact_patch
+ *
+ *  Return a string containing the diff in patch form.
+ */
+static VALUE rb_git_diff_patch(int argc, VALUE *argv, VALUE self)
+{
+	git_diff *diff;
+	VALUE rb_str = rb_str_new(NULL, 0);
+	VALUE rb_opts;
+
+	rb_scan_args(argc, argv, "00:", &rb_opts);
+
+	Data_Get_Struct(self, git_diff, diff);
+
+	if (!NIL_P(rb_opts)) {
+		if (rb_hash_aref(rb_opts, CSTR2SYM("compact")) == Qtrue)
+			git_diff_print(diff, GIT_DIFF_FORMAT_NAME_STATUS, diff_print_cb, (void*)rb_str);
+		else
+			git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, diff_print_cb, (void*)rb_str);
+	} else {
+		git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, diff_print_cb, (void*)rb_str);
+	}
+
+	return rb_str;
+}
+
+static int diff_write_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *payload)
+{
+	VALUE rb_io = (VALUE)payload, str = rb_str_new(line->content, line->content_len);
+
+	rb_io_write(rb_io, str);
+
+	return GIT_OK;
+}
+
+/*
+ *  call-seq:
+ *    diff.write_patch(io) -> nil
+ *    diff.write_patch(io, :compact => true) -> nil
+ *
+ *  Write a patch directly to an object which responds to "write".
+ */
+static VALUE rb_git_diff_write_patch(int argc, VALUE *argv, VALUE self)
+{
+	git_diff *diff;
+	VALUE rb_io, rb_opts;
+
+	rb_scan_args(argc, argv, "10:", &rb_io, &rb_opts);
+
+	if (!rb_respond_to(rb_io, rb_intern("write")))
+		rb_raise(rb_eArgError, "Expected io to respond to \"write\"");
+
+	Data_Get_Struct(self, git_diff, diff);
+
+	if (!NIL_P(rb_opts)) {
+		if (rb_hash_aref(rb_opts, CSTR2SYM("compact")) == Qtrue)
+			git_diff_print(diff, GIT_DIFF_FORMAT_NAME_STATUS, diff_write_cb, (void*)rb_io);
+		else
+			git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, diff_write_cb, (void*)rb_io);
+	} else {
+		git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, diff_write_cb, (void*)rb_io);
+	}
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    diff.merge!(other_diff) -> self
+ *
+ *  Merges all diff information from +other_diff+.
+ */
+static VALUE rb_git_diff_merge(VALUE self, VALUE rb_other)
+{
+	git_diff *diff;
+	git_diff *other;
+	int error;
+
+	if (!rb_obj_is_kind_of(rb_other, rb_cRuggedDiff))
+		rb_raise(rb_eTypeError, "A Rugged::Diff instance is required");
+
+	Data_Get_Struct(self, git_diff, diff);
+	Data_Get_Struct(rb_other, git_diff, other);
+
+	error = git_diff_merge(diff, other);
+	rugged_exception_check(error);
+
+	return self;
+}
+
+/*
+ *  call-seq:
+ *    diff.find_similar!([options]) -> self
+ *
+ *  Detects entries in the diff that look like renames or copies (based on the
+ *  given options) and replaces them with actual rename or copy entries.
+ *
+ *  Additionally, modified files can be broken into add/delete pairs if the
+ *  amount of changes are above a specific threshold (see +:break_rewrite_threshold+).
+ *
+ *  By default, similarity will be measured without leading whitespace. You
+ *  you can use the +:dont_ignore_whitespace+ to disable this.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :rename_threshold ::
+ *    An integer specifying the similarity to consider a file renamed (default 50).
+ *
+ *  :rename_from_rewrite_threshold ::
+ *    An integer specifying the similarity of modified to be eligible
+ *    rename source (default 50).
+ *
+ *  :copy_threshold ::
+ *    An integer specifying the similarity to consider a file a copy (default 50).
+ *
+ *  :break_rewrite_threshold ::
+ *    An integer specifying the similarity to split modify into delete/add pair (default 60).
+ *
+ *  :rename_limit ::
+ *    An integer specifying the maximum amount of similarity sources to examine
+ *    (a la diff's +-l+ option or the +diff.renameLimit+ config) (default 200).
+ *
+ *  :renames ::
+ *    If true, looking for renames will be enabled (+--find-renames+).
+ *
+ *  :renames_from_rewrites ::
+ *    If true, the "old side" of modified files will be considered for renames (+--break-rewrites=N+).
+ *
+ *  :copies ::
+ *    If true, looking for copies will be enabled (+--find-copies+).
+ *
+ *  :copies_from_unmodified ::
+ *    If true, unmodified files will be considered as copy sources (+--find-copies-harder+).
+ *
+ *  :break_rewrites ::
+ *    If true, larger rewrites will be split into delete/add pairs (+--break-rewrites=/M+).
+ *
+ *  :all ::
+ *    If true, enables all finding features.
+ *
+ *  :ignore_whitespace ::
+ *    If true, similarity will be measured with all whitespace ignored.
+ *
+ *  :dont_ignore_whitespace ::
+ *    If true, similarity will be measured without ignoring any whitespace.
+ *
+ */
+static VALUE rb_git_diff_find_similar(int argc, VALUE *argv, VALUE self)
+{
+	git_diff *diff;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	VALUE rb_options;
+	int error;
+
+	Data_Get_Struct(self, git_diff, diff);
+
+	rb_scan_args(argc, argv, "00:", &rb_options);
+
+	if (!NIL_P(rb_options)) {
+		VALUE rb_value = rb_hash_aref(rb_options, CSTR2SYM("rename_threshold"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts.rename_threshold = FIX2INT(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("rename_from_rewrite_threshold"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts.rename_from_rewrite_threshold = FIX2INT(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("copy_threshold"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts.copy_threshold = FIX2INT(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("break_rewrite_threshold"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts.break_rewrite_threshold = FIX2INT(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("rename_limit"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts.rename_limit = FIX2INT(rb_value);
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("renames")))) {
+			opts.flags |= GIT_DIFF_FIND_RENAMES;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("renames_from_rewrites")))) {
+			opts.flags |= GIT_DIFF_FIND_RENAMES_FROM_REWRITES;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("copies")))) {
+			opts.flags |= GIT_DIFF_FIND_COPIES;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("copies_from_unmodified")))) {
+			opts.flags |= GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("break_rewrites")))) {
+			opts.flags |= GIT_DIFF_FIND_AND_BREAK_REWRITES;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("all")))) {
+			opts.flags |= GIT_DIFF_FIND_ALL;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("ignore_whitespace")))) {
+			opts.flags |= GIT_DIFF_FIND_IGNORE_WHITESPACE;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("dont_ignore_whitespace")))) {
+			opts.flags |= GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE;
+		}
+	}
+
+	error = git_diff_find_similar(diff, &opts);
+	rugged_exception_check(error);
+
+	return self;
+}
+
+/*
+ *  call-seq:
+ *    diff.each_patch { |patch| } -> self
+ *    diff.each_patch -> enumerator
+ *
+ *  If given a block, yields each patch that is part of the diff.
+ *  If no block is given, an enumerator will be returned.
+ */
+static VALUE rb_git_diff_each_patch(VALUE self)
+{
+	git_diff *diff;
+	git_patch *patch;
+	int error = 0;
+	size_t d, delta_count;
+
+	if (!rb_block_given_p()) {
+		return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("each_patch"), self);
+	}
+
+	Data_Get_Struct(self, git_diff, diff);
+
+	delta_count = git_diff_num_deltas(diff);
+	for (d = 0; d < delta_count; ++d) {
+		error = git_patch_from_diff(&patch, diff, d);
+		if (error) break;
+
+		rb_yield(rugged_patch_new(self, patch));
+	}
+
+	rugged_exception_check(error);
+
+	return self;
+}
+
+/*
+ *  call-seq:
+ *    diff.each_delta { |delta| } -> self
+ *    diff.each_delta -> enumerator
+ *
+ *  If given a block, yields each delta that is part of the diff.
+ *  If no block is given, an enumerator will be returned.
+ *
+ *  This method should be preferred over #each_patch if you're not interested
+ *  in the actual line-by-line changes of the diff.
+ */
+static VALUE rb_git_diff_each_delta(VALUE self)
+{
+	git_diff *diff;
+	const git_diff_delta *delta;
+	int error = 0;
+	size_t d, delta_count;
+
+	if (!rb_block_given_p()) {
+		return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("each_delta"), self);
+	}
+
+	Data_Get_Struct(self, git_diff, diff);
+
+	delta_count = git_diff_num_deltas(diff);
+	for (d = 0; d < delta_count; ++d) {
+		delta = git_diff_get_delta(diff, d);
+		rb_yield(rugged_diff_delta_new(self, delta));
+	}
+
+	rugged_exception_check(error);
+
+	return self;
+}
+
+static int each_line_cb(
+    const git_diff_delta *delta,
+    const git_diff_hunk *hunk,
+    const git_diff_line *line,
+    void *payload)
+{
+	int *exception = (int *)payload;
+	rb_protect(rb_yield, rugged_diff_line_new(line), exception);
+	return *exception ? GIT_ERROR : GIT_OK;
+}
+
+/*
+ *  call-seq:
+ *    diff.each_line([format = :patch]) { |line| } -> self
+ *    diff.each_line([format = :patch]) -> enumerator
+ */
+static VALUE rb_git_diff_each_line(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_format;
+	git_diff *diff;
+	git_diff_format_t format;
+	int exception = 0, error;
+
+	Data_Get_Struct(self, git_diff, diff);
+
+	if (rb_scan_args(argc, argv, "01", &rb_format) == 1) {
+		Check_Type(rb_format, T_SYMBOL);
+	} else {
+		rb_format = CSTR2SYM("patch");
+	}
+
+	if (!rb_block_given_p())
+		return rb_funcall(self, rb_intern("to_enum"), 2, CSTR2SYM("each_line"), rb_format);
+
+	if (SYM2ID(rb_format) == rb_intern("patch")) {
+		format = GIT_DIFF_FORMAT_PATCH;
+	} else if (SYM2ID(rb_format) == rb_intern("patch_header")) {
+		format = GIT_DIFF_FORMAT_PATCH_HEADER;
+	} else if (SYM2ID(rb_format) == rb_intern("raw")) {
+		format = GIT_DIFF_FORMAT_RAW;
+	} else if (SYM2ID(rb_format) == rb_intern("name_only")) {
+		format = GIT_DIFF_FORMAT_NAME_ONLY;
+	} else if (SYM2ID(rb_format) == rb_intern("name_status")) {
+		format = GIT_DIFF_FORMAT_NAME_STATUS;
+	} else {
+		rb_raise(rb_eArgError, "unknown :format");
+	}
+
+	error = git_diff_print(diff, format, each_line_cb, &exception);
+
+	if (exception)
+		rb_jump_tag(exception);
+	rugged_exception_check(error);
+
+	return self;
+}
+
+
+/*
+ *  call-seq: diff.size -> int
+ *
+ *  Returns the number of deltas/patches in this diff.
+ */
+static VALUE rb_git_diff_size(VALUE self)
+{
+	git_diff *diff;
+
+	Data_Get_Struct(self, git_diff, diff);
+
+	return INT2FIX(git_diff_num_deltas(diff));
+}
+
+struct diff_stats {
+	size_t files, adds, dels;
+};
+
+static int diff_file_stats_cb(
+	const git_diff_delta *delta,
+	float progress,
+	void *payload)
+{
+	struct diff_stats *stats = payload;
+
+	switch (delta->status) {
+	case GIT_DELTA_ADDED:
+	case GIT_DELTA_DELETED:
+	case GIT_DELTA_MODIFIED:
+	case GIT_DELTA_RENAMED:
+	case GIT_DELTA_COPIED:
+	case GIT_DELTA_TYPECHANGE:
+		stats->files++;
+		break;
+	default:
+		/* unmodified, ignored, and untracked files don't count */
+		break;
+	}
+	return GIT_OK;
+}
+
+static int diff_line_stats_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *payload)
+{
+	struct diff_stats *stats = payload;
+
+	switch (line->origin) {
+	case GIT_DIFF_LINE_ADDITION: stats->adds++; break;
+	case GIT_DIFF_LINE_DELETION: stats->dels++; break;
+	default: break;
+	}
+
+	return GIT_OK;
+}
+
+/*
+ *  call-seq: diff.stat -> int, int, int
+ *
+ *  Returns the number of files/additions/deletions in this diff.
+ */
+static VALUE rb_git_diff_stat(VALUE self)
+{
+	git_diff *diff;
+	struct diff_stats stats = { 0, 0, 0 };
+
+	Data_Get_Struct(self, git_diff, diff);
+
+	git_diff_foreach(
+		diff, diff_file_stats_cb, NULL, NULL, diff_line_stats_cb, &stats);
+
+	return rb_ary_new3(
+		3, INT2FIX(stats.files), INT2FIX(stats.adds), INT2FIX(stats.dels));
+}
+
+/*
+ *  call-seq: diff.sorted_icase?
+ *
+ *  Returns true when deltas are sorted case insensitively.
+ */
+static VALUE rb_git_diff_sorted_icase_p(VALUE self)
+{
+	git_diff *diff;
+	Data_Get_Struct(self, git_diff, diff);
+	return git_diff_is_sorted_icase(diff) ? Qtrue : Qfalse;
+}
+
+void Init_rugged_diff(void)
+{
+	rb_cRuggedDiff = rb_define_class_under(rb_mRugged, "Diff", rb_cObject);
+
+	rb_define_method(rb_cRuggedDiff, "patch", rb_git_diff_patch, -1);
+	rb_define_method(rb_cRuggedDiff, "write_patch", rb_git_diff_write_patch, -1);
+
+	rb_define_method(rb_cRuggedDiff, "find_similar!", rb_git_diff_find_similar, -1);
+	rb_define_method(rb_cRuggedDiff, "merge!", rb_git_diff_merge, 1);
+
+	rb_define_method(rb_cRuggedDiff, "size", rb_git_diff_size, 0);
+	rb_define_method(rb_cRuggedDiff, "stat", rb_git_diff_stat, 0);
+
+	rb_define_method(rb_cRuggedDiff, "sorted_icase?", rb_git_diff_sorted_icase_p, 0);
+
+	rb_define_method(rb_cRuggedDiff, "each_patch", rb_git_diff_each_patch, 0);
+	rb_define_method(rb_cRuggedDiff, "each_delta", rb_git_diff_each_delta, 0);
+	rb_define_method(rb_cRuggedDiff, "each_line", rb_git_diff_each_line, -1);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_diff_delta.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_diff_delta.c
new file mode 100755
index 0000000..21f66b6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_diff_delta.c
@@ -0,0 +1,105 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_cRuggedDiff;
+VALUE rb_cRuggedDiffDelta;
+
+VALUE rb_git_delta_file_fromC(const git_diff_file *file)
+{
+	VALUE rb_file;
+
+	if (!file)
+		return Qnil;
+
+	rb_file = rb_hash_new();
+
+	rb_hash_aset(rb_file, CSTR2SYM("oid"), rugged_create_oid(&file->id));
+	rb_hash_aset(rb_file, CSTR2SYM("path"), file->path ? rb_str_new2(file->path) : Qnil);
+	rb_hash_aset(rb_file, CSTR2SYM("size"), INT2FIX(file->size));
+	rb_hash_aset(rb_file, CSTR2SYM("flags"), UINT2NUM(file->flags));
+	rb_hash_aset(rb_file, CSTR2SYM("mode"), UINT2NUM(file->mode));
+
+	return rb_file;
+}
+
+static VALUE rb_git_delta_status_fromC(git_delta_t status)
+{
+	switch(status) {
+		case GIT_DELTA_UNMODIFIED:
+			return CSTR2SYM("unmodified");
+		case GIT_DELTA_ADDED:
+			return CSTR2SYM("added");
+		case GIT_DELTA_DELETED:
+			return CSTR2SYM("deleted");
+		case GIT_DELTA_MODIFIED:
+			return CSTR2SYM("modified");
+		case GIT_DELTA_RENAMED:
+			return CSTR2SYM("renamed");
+		case GIT_DELTA_COPIED:
+			return CSTR2SYM("copied");
+		case GIT_DELTA_IGNORED:
+			return CSTR2SYM("ignored");
+		case GIT_DELTA_UNTRACKED:
+			return CSTR2SYM("untracked");
+		case GIT_DELTA_TYPECHANGE:
+			return CSTR2SYM("typechange");
+		default:
+			return CSTR2SYM("unknown");
+	}
+}
+
+static VALUE rb_git_delta_status_char_fromC(git_delta_t status)
+{
+	char status_char[2];
+
+	status_char[0] = git_diff_status_char(status);
+	status_char[1] = '\0';
+
+	return CSTR2SYM(status_char);
+}
+
+VALUE rugged_diff_delta_new(VALUE owner, const git_diff_delta *delta)
+{
+	VALUE rb_delta = rb_class_new_instance(0, NULL, rb_cRuggedDiffDelta);
+
+	rugged_set_owner(rb_delta, owner);
+	rb_iv_set(rb_delta, "@old_file", rb_git_delta_file_fromC(&delta->old_file));
+	rb_iv_set(rb_delta, "@new_file", rb_git_delta_file_fromC(&delta->new_file));
+	rb_iv_set(rb_delta, "@similarity", INT2FIX(delta->similarity));
+	rb_iv_set(rb_delta, "@status", rb_git_delta_status_fromC(delta->status));
+	rb_iv_set(rb_delta, "@status_char", rb_git_delta_status_char_fromC(delta->status));
+	rb_iv_set(rb_delta, "@binary",
+		(!(delta->flags & GIT_DIFF_FLAG_NOT_BINARY) &&
+		 (delta->flags & GIT_DIFF_FLAG_BINARY)) ? Qtrue : Qfalse
+	);
+
+	return rb_delta;
+}
+
+void Init_rugged_diff_delta(void)
+{
+	rb_cRuggedDiffDelta = rb_define_class_under(rb_cRuggedDiff, "Delta", rb_cObject);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_diff_hunk.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_diff_hunk.c
new file mode 100755
index 0000000..ed662f8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_diff_hunk.c
@@ -0,0 +1,103 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_cRuggedDiff;
+VALUE rb_cRuggedDiffHunk;
+
+
+VALUE rugged_diff_hunk_new(VALUE owner, size_t hunk_idx, const git_diff_hunk *hunk, size_t lines_in_hunk)
+{
+	VALUE rb_hunk = rb_class_new_instance(0, NULL, rb_cRuggedDiffHunk);
+	rugged_set_owner(rb_hunk, owner);
+
+	rb_iv_set(rb_hunk, "@header", rb_str_new(hunk->header, hunk->header_len));
+	rb_iv_set(rb_hunk, "@line_count", INT2FIX(lines_in_hunk));
+	rb_iv_set(rb_hunk, "@hunk_index", INT2FIX(hunk_idx));
+
+	rb_iv_set(rb_hunk, "@old_start", INT2FIX(hunk->old_start));
+	rb_iv_set(rb_hunk, "@old_lines", INT2FIX(hunk->old_lines));
+	rb_iv_set(rb_hunk, "@new_start", INT2FIX(hunk->new_start));
+	rb_iv_set(rb_hunk, "@new_lines", INT2FIX(hunk->new_lines));
+
+	return rb_hunk;
+}
+
+/*
+ *  call-seq:
+ *    hunk.each_line { |line| } -> self
+ *    hunk.each_line -> Enumerator
+ *
+ *  If given a block, yields each line that is part of the current hunk.
+ *
+ *  If no block is given, an enumerator is returned instead.
+ */
+static VALUE rb_git_diff_hunk_each_line(VALUE self)
+{
+	git_patch *patch;
+	int error = 0, l, lines_count, hunk_idx;
+
+	if (!rb_block_given_p()) {
+		return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("each_line"), self);
+	}
+
+	Data_Get_Struct(rugged_owner(self), git_patch, patch);
+
+	lines_count = FIX2INT(rb_iv_get(self, "@line_count"));
+	hunk_idx = FIX2INT(rb_iv_get(self, "@hunk_index"));
+
+	for (l = 0; l < lines_count; ++l) {
+		const git_diff_line *line;
+		error = git_patch_get_line_in_hunk(&line, patch, hunk_idx, l);
+		if (error) break;
+
+		rb_yield(rugged_diff_line_new(line));
+	}
+	rugged_exception_check(error);
+
+	return self;
+}
+
+void Init_rugged_diff_hunk(void)
+{
+	rb_cRuggedDiffHunk = rb_define_class_under(rb_cRuggedDiff, "Hunk", rb_cObject);
+
+	rb_include_module(rb_cRuggedDiffHunk, rb_mEnumerable);
+
+	rb_define_method(rb_cRuggedDiffHunk, "each", rb_git_diff_hunk_each_line, 0);
+	rb_define_method(rb_cRuggedDiffHunk, "each_line", rb_git_diff_hunk_each_line, 0);
+
+	rb_define_attr(rb_cRuggedDiffHunk, "header", 1, 0);
+	rb_define_attr(rb_cRuggedDiffHunk, "line_count", 1, 0);
+	rb_define_attr(rb_cRuggedDiffHunk, "hunk_index", 1, 0);
+
+	rb_define_attr(rb_cRuggedDiffHunk, "old_start", 1, 0);
+	rb_define_attr(rb_cRuggedDiffHunk, "old_lines", 1, 0);
+	rb_define_attr(rb_cRuggedDiffHunk, "new_start", 1, 0);
+	rb_define_attr(rb_cRuggedDiffHunk, "new_lines", 1, 0);
+
+	rb_define_alias(rb_cRuggedDiffHunk, "count", "line_count");
+	rb_define_alias(rb_cRuggedDiffHunk, "size", "line_count");
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_diff_line.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_diff_line.c
new file mode 100755
index 0000000..63bf8fb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_diff_line.c
@@ -0,0 +1,83 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_cRuggedDiff;
+VALUE rb_cRuggedDiffLine;
+
+VALUE rugged_diff_line_new(const git_diff_line *line)
+{
+	VALUE rb_line = rb_class_new_instance(0, NULL, rb_cRuggedDiffLine), rb_line_origin;
+
+	switch(line->origin) {
+		case GIT_DIFF_LINE_CONTEXT:
+			rb_line_origin = CSTR2SYM("context");
+			break;
+		case GIT_DIFF_LINE_ADDITION:
+			rb_line_origin = CSTR2SYM("addition");
+			break;
+		case GIT_DIFF_LINE_DELETION:
+			rb_line_origin = CSTR2SYM("deletion");
+			break;
+		case GIT_DIFF_LINE_CONTEXT_EOFNL: /* neither file has newline at the end */
+			rb_line_origin = CSTR2SYM("eof_no_newline");
+			break;
+		case GIT_DIFF_LINE_ADD_EOFNL: /* added at end of old file */
+			rb_line_origin = CSTR2SYM("eof_newline_added");
+			break;
+		case GIT_DIFF_LINE_DEL_EOFNL: /* removed at end of old file */
+			rb_line_origin = CSTR2SYM("eof_newline_removed");
+			break;
+		case GIT_DIFF_LINE_FILE_HDR:
+			rb_line_origin = CSTR2SYM("file_header");
+			break;
+		case GIT_DIFF_LINE_HUNK_HDR:
+			rb_line_origin = CSTR2SYM("hunk_header");
+			break;
+		case GIT_DIFF_LINE_BINARY:
+			rb_line_origin = CSTR2SYM("binary");
+			break;
+		default:
+			/* FIXME: raise here instead? */
+			rb_line_origin = CSTR2SYM("unknown");
+	}
+
+	rb_iv_set(rb_line, "@line_origin", rb_line_origin);
+	rb_iv_set(rb_line, "@content", rb_str_new(line->content, line->content_len));
+	rb_iv_set(rb_line, "@old_lineno", INT2FIX(line->old_lineno));
+	rb_iv_set(rb_line, "@new_lineno", INT2FIX(line->new_lineno));
+
+	if (line->content_offset == -1)
+		rb_iv_set(rb_line, "@content_offset", Qnil);
+	else
+		rb_iv_set(rb_line, "@content_offset", INT2FIX(line->content_offset));
+
+	return rb_line;
+}
+
+void Init_rugged_diff_line(void)
+{
+	rb_cRuggedDiffLine = rb_define_class_under(rb_cRuggedDiff, "Line", rb_cObject);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_index.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_index.c
new file mode 100755
index 0000000..05dc6c4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_index.c
@@ -0,0 +1,1255 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+VALUE rb_cRuggedIndex;
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedCommit;
+extern VALUE rb_cRuggedDiff;
+extern VALUE rb_cRuggedTree;
+
+static void rb_git_indexentry_toC(git_index_entry *entry, VALUE rb_entry);
+static VALUE rb_git_indexentry_fromC(const git_index_entry *entry);
+
+/*
+ * Index
+ */
+
+static void rb_git_index__free(git_index *index)
+{
+	git_index_free(index);
+}
+
+VALUE rugged_index_new(VALUE klass, VALUE owner, git_index *index)
+{
+	VALUE rb_index = Data_Wrap_Struct(klass, NULL, &rb_git_index__free, index);
+	rugged_set_owner(rb_index, owner);
+	return rb_index;
+}
+
+/*
+ *  call-seq:
+ *    Index.new([path])
+ *
+ *  Create a bare index object based on the index file at +path+.
+ *
+ *  Any index methods that rely on the ODB or a working directory (e.g. #add)
+ *  will raise a Rugged::IndexError.
+ */
+static VALUE rb_git_index_new(int argc, VALUE *argv, VALUE klass)
+{
+	git_index *index;
+	int error;
+
+	VALUE rb_path;
+	const char *path = NULL;
+
+	if (rb_scan_args(argc, argv, "01", &rb_path) == 1) {
+		Check_Type(rb_path, T_STRING);
+		path = StringValueCStr(rb_path);
+	}
+
+	error = git_index_open(&index, path);
+	rugged_exception_check(error);
+
+	return rugged_index_new(klass, Qnil, index);
+}
+
+/*
+ *  call-seq:
+ *    index.clear -> nil
+ *
+ *  Clear the contents (remove all entries) of the index object. Changes are in-memory only
+ *  and can be saved by calling #write.
+ */
+static VALUE rb_git_index_clear(VALUE self)
+{
+	git_index *index;
+	Data_Get_Struct(self, git_index, index);
+	git_index_clear(index);
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    index.reload -> nil
+ *
+ *  Reloads the index contents from the disk, discarding any changes that
+ *  have not been saved through #write.
+ */
+static VALUE rb_git_index_read(VALUE self)
+{
+	git_index *index;
+	int error;
+
+	Data_Get_Struct(self, git_index, index);
+
+	error = git_index_read(index, 0);
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    index.write -> nil
+ *
+ *  Writes the index object from memory back to the disk, persisting all changes.
+ */
+static VALUE rb_git_index_write(VALUE self)
+{
+	git_index *index;
+	int error;
+
+	Data_Get_Struct(self, git_index, index);
+
+	error = git_index_write(index);
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    index.count -> int
+ *
+ *  Returns the number of entries currently in the index.
+ */
+static VALUE rb_git_index_count(VALUE self)
+{
+	git_index *index;
+	Data_Get_Struct(self, git_index, index);
+	return INT2FIX(git_index_entrycount(index));
+}
+
+/*
+ *  call-seq:
+ *    index[path[, stage = 0]]     -> entry or nil
+ *    index[position]              -> entry or nil
+ *    index.get(path[, stage = 0]) -> entry or nil
+ *    index.get(position)          -> entry or nil
+ *
+ *  Return a specific entry in the index.
+ *
+ *  The first two forms returns entries based on their +path+ in the index and an optional +stage+,
+ *  while the last two forms return entries based on their position in the index.
+ */
+static VALUE rb_git_index_get(int argc, VALUE *argv, VALUE self)
+{
+	git_index *index;
+	const git_index_entry *entry = NULL;
+
+	VALUE rb_entry, rb_stage;
+
+	Data_Get_Struct(self, git_index, index);
+
+	rb_scan_args(argc, argv, "11", &rb_entry, &rb_stage);
+
+	if (TYPE(rb_entry) == T_STRING) {
+		int stage = 0;
+
+		if (!NIL_P(rb_stage)) {
+			Check_Type(rb_stage, T_FIXNUM);
+			stage = FIX2INT(rb_stage);
+		}
+
+		entry = git_index_get_bypath(index, StringValueCStr(rb_entry), stage);
+	}
+
+	else if (TYPE(rb_entry) == T_FIXNUM) {
+		if (argc > 1) {
+			rb_raise(rb_eArgError,
+				"Too many arguments when trying to lookup entry by index");
+		}
+
+		entry = git_index_get_byindex(index, FIX2INT(rb_entry));
+	} else {
+		rb_raise(rb_eArgError,
+			"Invalid type for `entry`: expected String or Fixnum");
+	}
+
+	return entry ? rb_git_indexentry_fromC(entry) : Qnil;
+}
+
+/*
+ *  call-seq:
+ *    index.each { |entry| } -> nil
+ *    index.each -> Enumerator
+ *
+ *  Passes each entry of the index to the given block.
+ *
+ *  If no block is given, an enumerator is returned instead.
+ */
+static VALUE rb_git_index_each(VALUE self)
+{
+	git_index *index;
+	unsigned int i, count;
+
+	Data_Get_Struct(self, git_index, index);
+
+	if (!rb_block_given_p())
+		return rb_funcall(self, rb_intern("to_enum"), 0);
+
+	count = (unsigned int)git_index_entrycount(index);
+	for (i = 0; i < count; ++i) {
+		const git_index_entry *entry = git_index_get_byindex(index, i);
+		if (entry)
+			rb_yield(rb_git_indexentry_fromC(entry));
+	}
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    index.remove(path[, stage = 0]) -> nil
+ *
+ *  Removes the entry at the given +path+ with the given +stage+
+ *  from the index.
+ */
+static VALUE rb_git_index_remove(int argc, VALUE *argv, VALUE self)
+{
+	git_index *index;
+	int error, stage = 0;
+
+	VALUE rb_entry, rb_stage;
+
+	Data_Get_Struct(self, git_index, index);
+
+	if (rb_scan_args(argc, argv, "11", &rb_entry, &rb_stage) > 1) {
+		Check_Type(rb_stage, T_FIXNUM);
+		stage = FIX2INT(rb_stage);
+	}
+
+	Check_Type(rb_entry, T_STRING);
+
+	error = git_index_remove(index, StringValueCStr(rb_entry), stage);
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    index.remove_dir(dir[, stage = 0]) -> nil
+ *
+ *  Removes all entries under the given +dir+ with the given +stage+
+ *  from the index.
+ */
+static VALUE rb_git_index_remove_directory(int argc, VALUE *argv, VALUE self)
+{
+	git_index *index;
+	int error, stage = 0;
+
+	VALUE rb_dir, rb_stage;
+
+	Data_Get_Struct(self, git_index, index);
+
+	if (rb_scan_args(argc, argv, "11", &rb_dir, &rb_stage) > 1) {
+		Check_Type(rb_stage, T_FIXNUM);
+		stage = FIX2INT(rb_stage);
+	}
+
+	Check_Type(rb_dir, T_STRING);
+
+	error = git_index_remove_directory(index, StringValueCStr(rb_dir), stage);
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    index << entry -> nil
+ *    index << path -> nil
+ *    index.add(entry) -> nil
+ *    index.add(path) -> nil
+ *    index.update(entry) -> nil
+ *    index.update(path) -> nil
+ *
+ *  Add a new entry to the index or update an existing entry in the index.
+ *
+ *  If passed a +path+ to an existing, readable file relative to the workdir,
+ *  creates a new index entry based on this file.
+ *
+ *  Alternatively, a new index entry can be created by passing a Hash containing
+ *  all key/value pairs of an index entry.
+ *
+ *  Any gitignore rules that might match +path+ (or the +:path+ value of the
+ *  entry hash) are ignored.
+ *
+ *  If the index entry at +path+ (or +:path+) currently contains a merge conflict,
+ *  it will no longer be marked as conflicting and the data about the conflict
+ *  will be moved into the "resolve undo" (REUC) section of the index.
+ */
+static VALUE rb_git_index_add(VALUE self, VALUE rb_entry)
+{
+	git_index *index;
+	int error = 0;
+
+	Data_Get_Struct(self, git_index, index);
+
+	if (TYPE(rb_entry) == T_HASH) {
+		git_index_entry entry;
+
+		rb_git_indexentry_toC(&entry, rb_entry);
+		error = git_index_add(index, &entry);
+	}
+
+	else if (TYPE(rb_entry) == T_STRING) {
+		error = git_index_add_bypath(index, StringValueCStr(rb_entry));
+	}
+
+	else {
+		rb_raise(rb_eTypeError,
+			"Expecting a hash defining an Index Entry or a path to a file in the repository");
+	}
+
+	rugged_exception_check(error);
+	return Qnil;
+}
+
+int rugged__index_matched_path_cb(const char *path, const char *matched_pathspec, void *payload)
+{
+	int *exception = (int *)payload;
+
+	VALUE rb_result, rb_args = rb_ary_new2(2);
+	rb_ary_push(rb_args, rb_str_new2(path));
+	rb_ary_push(rb_args, matched_pathspec == NULL ? Qnil : rb_str_new2(matched_pathspec));
+
+	rb_result = rb_protect(rb_yield_splat, rb_args, exception);
+
+	if (*exception)
+		return GIT_ERROR;
+
+	return RTEST(rb_result) ? 0 : 1;
+}
+
+/*
+ *  call-seq:
+ *    index.add_all(pathspec = [][, options])                            -> nil
+ *    index.add_all(pathspec = [][, options]) { |path, pathspec| block } -> nil
+ *
+ *  Add or update index entries matching files in the working directory.
+ *
+ *  Searches the working directory for files that +pathspec+ and adds them
+ *  to +index+ (by updating an existing entry or adding a new entry).
+ *
+ *  +pathspec+ can either be a String, or an Array of Strings.
+ *  If +pathspec+ is empty, all entries in the index will be matched.
+ *
+ *  Files that are ignored due to +.gitignore+ rules will be skipped,
+ *  unless they're already have an entry in +index+.
+ *
+ *  Files that are marked as the result of a merge request, will have this
+ *  marking removed and the merge conflict information will be moved into the
+ *  "resolve undo" (REUC) section of +index+.
+ *
+ *  If a block is given, each matched +path+ and the +pathspec+ that matched
+ *  it will be passed to the block. If the return value of +block+ is
+ *  falsy, the matching item will not be added to the index.
+ *
+ *  This method will fail in bare index instances.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :force ::
+ *    If +true+, any +.gitignore+ rules will be ignored.
+ *
+ *  :disable_pathspec_match ::
+ *    If +true+, glob expansion will be disabled and exact matching will be forced.
+ *
+ *  :check_pathspec ::
+ *    If +true+, and the +:force+ options is +false+ or not given, exact matches
+ *    of ignored files or files that are not already in +index+ will raise a
+ *    Rugged::InvalidError. This emulates <code>git add -A</code>.
+ */
+static VALUE rb_git_index_add_all(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_pathspecs, rb_options;
+
+	git_index *index;
+	git_strarray pathspecs;
+	int error, exception = 0;
+	unsigned int flags = GIT_INDEX_ADD_DEFAULT;
+
+	Data_Get_Struct(self, git_index, index);
+
+	if (rb_scan_args(argc, argv, "02", &rb_pathspecs, &rb_options) > 1) {
+		Check_Type(rb_options, T_HASH);
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("force"))))
+			flags |= GIT_INDEX_ADD_FORCE;
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("disable_pathspec_match"))))
+			flags |= GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH;
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("check_pathspec"))))
+			flags |= GIT_INDEX_ADD_CHECK_PATHSPEC;
+	}
+
+	rugged_rb_ary_to_strarray(rb_pathspecs, &pathspecs);
+
+	error = git_index_add_all(index, &pathspecs, flags,
+		rb_block_given_p() ? rugged__index_matched_path_cb : NULL, &exception);
+
+	xfree(pathspecs.strings);
+
+	if (exception)
+		rb_jump_tag(exception);
+
+	rugged_exception_check(error);
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    index.update_all(pathspec = [])                            -> nil
+ *    index.update_all(pathspec = []) { |path, pathspec| block } -> nil
+ *
+ *  Update all index entries to match the working directory.
+ *
+ *  Searches +index+ for entries that match +pathspec+ and synchronizes
+ *  them with the content of the working directory.
+ *
+ *  +pathspec+ can either be a String, or an Array of Strings.
+ *  If +pathspec+ is empty, all entries in the index will be matched.
+ *
+ *  Entries where the corresponding working directory file no longer exists
+ *  get deleted, all other matched entries will get updated to reflect their
+ *  working directory state (the latest version of the a file's content will
+ *  automatically be added to the ODB).
+ *
+ *  If a block is given, each matched +path+ and the +pathspec+ that matched
+ *  it will be passed to the block. If the return value of +block+ is
+ *  falsy, the matching item will not be updated in the index.
+ *
+ *  This method will fail in bare index instances.
+ */
+static VALUE rb_git_index_update_all(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_pathspecs = rb_ary_new();
+
+	git_index *index;
+	git_strarray pathspecs;
+	int error, exception = 0;
+
+	Data_Get_Struct(self, git_index, index);
+
+	rb_scan_args(argc, argv, "01", &rb_pathspecs);
+
+	rugged_rb_ary_to_strarray(rb_pathspecs, &pathspecs);
+
+	error = git_index_update_all(index, &pathspecs,
+		rb_block_given_p() ? rugged__index_matched_path_cb : NULL, &exception);
+
+	xfree(pathspecs.strings);
+
+	if (exception)
+		rb_jump_tag(exception);
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    index.remove_all(pathspec = []) -> nil
+ *    index.remove_all(pathspec = []) { |path, pathspec| block } -> nil
+ *
+ *  Remove all matching index entries.
+ *
+ *  Searches +index+ for entries that match +pathspec+ and removes them
+ *  from the index.
+ *
+ *  +pathspec+ can either be a String, or an Array of Strings.
+ *  If +pathspec+ is empty, all entries in the index will be matched.
+ *
+ *  If a block is given, each matched +path+ and the +pathspec+ that matched
+ *  it will be passed to the block. If the return value of +block+ is
+ *  falsy, the matching item will not be removed from the index.
+ */
+static VALUE rb_git_index_remove_all(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_pathspecs = rb_ary_new();
+
+	git_index *index;
+	git_strarray pathspecs;
+	int error, exception = 0;
+
+	Data_Get_Struct(self, git_index, index);
+
+	rb_scan_args(argc, argv, "01", &rb_pathspecs);
+
+	if (NIL_P(rb_pathspecs))
+		rb_pathspecs = rb_ary_new();
+
+	rugged_rb_ary_to_strarray(rb_ary_to_ary(rb_pathspecs), &pathspecs);
+
+	error = git_index_remove_all(index, &pathspecs,
+		rb_block_given_p() ? rugged__index_matched_path_cb : NULL, &exception);
+
+	xfree(pathspecs.strings);
+
+	if (exception)
+		rb_jump_tag(exception);
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+static VALUE rb_git_indexentry_fromC(const git_index_entry *entry)
+{
+	VALUE rb_entry, rb_mtime, rb_ctime;
+	unsigned int valid, stage;
+
+	if (!entry)
+		return Qnil;
+
+	rb_entry = rb_hash_new();
+
+	rb_hash_aset(rb_entry, CSTR2SYM("path"), rb_str_new_utf8(entry->path));
+	rb_hash_aset(rb_entry, CSTR2SYM("oid"), rugged_create_oid(&entry->id));
+
+	rb_hash_aset(rb_entry, CSTR2SYM("dev"), INT2FIX(entry->dev));
+	rb_hash_aset(rb_entry, CSTR2SYM("ino"), INT2FIX(entry->ino));
+	rb_hash_aset(rb_entry, CSTR2SYM("mode"), INT2FIX(entry->mode));
+	rb_hash_aset(rb_entry, CSTR2SYM("gid"), INT2FIX(entry->gid));
+	rb_hash_aset(rb_entry, CSTR2SYM("uid"), INT2FIX(entry->uid));
+	rb_hash_aset(rb_entry, CSTR2SYM("file_size"), INT2FIX(entry->file_size));
+
+	valid = (entry->flags & GIT_IDXENTRY_VALID);
+	rb_hash_aset(rb_entry, CSTR2SYM("valid"), valid ? Qtrue : Qfalse);
+
+	stage = (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT;
+	rb_hash_aset(rb_entry, CSTR2SYM("stage"), INT2FIX(stage));
+
+	rb_mtime = rb_time_new(entry->mtime.seconds, entry->mtime.nanoseconds / 1000);
+	rb_ctime = rb_time_new(entry->ctime.seconds, entry->ctime.nanoseconds / 1000);
+
+	rb_hash_aset(rb_entry, CSTR2SYM("ctime"), rb_ctime);
+	rb_hash_aset(rb_entry, CSTR2SYM("mtime"), rb_mtime);
+
+	return rb_entry;
+}
+
+static inline uint32_t
+default_entry_value(VALUE rb_entry, const char *key)
+{
+	VALUE val = rb_hash_aref(rb_entry, CSTR2SYM(key));
+	if (NIL_P(val))
+		return 0;
+
+	Check_Type(val, T_FIXNUM);
+	return FIX2INT(val);
+}
+
+static void rb_git_indexentry_toC(git_index_entry *entry, VALUE rb_entry)
+{
+	VALUE val;
+
+	Check_Type(rb_entry, T_HASH);
+
+	val = rb_hash_aref(rb_entry, CSTR2SYM("path"));
+	Check_Type(val, T_STRING);
+	entry->path = StringValueCStr(val);
+
+	val = rb_hash_aref(rb_entry, CSTR2SYM("oid"));
+	Check_Type(val, T_STRING);
+	rugged_exception_check(
+		git_oid_fromstr(&entry->id, StringValueCStr(val))
+	);
+
+	entry->dev = default_entry_value(rb_entry, "dev");
+	entry->ino = default_entry_value(rb_entry, "ino");
+	entry->mode = default_entry_value(rb_entry, "mode");
+	entry->gid = default_entry_value(rb_entry, "gid");
+	entry->uid = default_entry_value(rb_entry, "uid");
+	entry->file_size = default_entry_value(rb_entry, "file_size");
+
+	if ((val = rb_hash_aref(rb_entry, CSTR2SYM("mtime"))) != Qnil) {
+		if (!rb_obj_is_kind_of(val, rb_cTime))
+			rb_raise(rb_eTypeError, ":mtime must be a Time instance");
+
+		entry->mtime.seconds = NUM2INT(rb_funcall(val, rb_intern("to_i"), 0));
+		entry->mtime.nanoseconds = NUM2INT(rb_funcall(val, rb_intern("usec"), 0)) * 1000;
+	} else {
+		entry->mtime.seconds = entry->mtime.nanoseconds = 0;
+	}
+
+	if ((val = rb_hash_aref(rb_entry, CSTR2SYM("ctime"))) != Qnil) {
+		if (!rb_obj_is_kind_of(val, rb_cTime))
+			rb_raise(rb_eTypeError, ":ctime must be a Time instance");
+
+		entry->ctime.seconds = NUM2INT(rb_funcall(val, rb_intern("to_i"), 0));
+		entry->ctime.nanoseconds = NUM2INT(rb_funcall(val, rb_intern("usec"), 0)) * 1000;
+	} else {
+		entry->ctime.seconds = entry->ctime.nanoseconds = 0;
+	}
+
+	entry->flags = 0x0;
+	entry->flags_extended = 0x0;
+
+	val = rb_hash_aref(rb_entry, CSTR2SYM("stage"));
+	if (!NIL_P(val)) {
+		unsigned int stage = NUM2INT(val);
+		entry->flags &= ~GIT_IDXENTRY_STAGEMASK;
+		entry->flags |= (stage << GIT_IDXENTRY_STAGESHIFT) & GIT_IDXENTRY_STAGEMASK;
+	}
+
+	val = rb_hash_aref(rb_entry, CSTR2SYM("valid"));
+	if (!NIL_P(val)) {
+		entry->flags &= ~GIT_IDXENTRY_VALID;
+		if (rugged_parse_bool(val))
+			entry->flags |= GIT_IDXENTRY_VALID;
+	} else {
+		entry->flags |= GIT_IDXENTRY_VALID;
+	}
+}
+
+/*
+ *  call-seq:
+ *    index.write_tree([repo]) -> oid
+ *
+ *  Write the index to a tree, either in the index's repository, or in
+ *  the given +repo+.
+ *
+ *  If the index contains any files in conflict, writing the tree will fail.
+ *
+ *  Returns the OID string of the written tree object.
+ */
+static VALUE rb_git_index_writetree(int argc, VALUE *argv, VALUE self)
+{
+	git_index *index;
+	git_oid tree_oid;
+	int error;
+	VALUE rb_repo;
+
+	Data_Get_Struct(self, git_index, index);
+
+	if (rb_scan_args(argc, argv, "01", &rb_repo) == 1) {
+		git_repository *repo = NULL;
+		rugged_check_repo(rb_repo);
+		Data_Get_Struct(rb_repo, git_repository, repo);
+		error = git_index_write_tree_to(&tree_oid, index, repo);
+	}
+	else {
+		error = git_index_write_tree(&tree_oid, index);
+	}
+
+	rugged_exception_check(error);
+	return rugged_create_oid(&tree_oid);
+}
+
+/*
+ *  call-seq:
+ *    index.read_tree(tree)
+ *
+ *  Clear the current index and start the index again on top of +tree+
+ *
+ *  Further index operations (+add+, +update+, +remove+, etc) will
+ *  be considered changes on top of +tree+.
+ */
+static VALUE rb_git_index_readtree(VALUE self, VALUE rb_tree)
+{
+	git_index *index;
+	git_tree *tree;
+	int error;
+
+	Data_Get_Struct(self, git_index, index);
+	Data_Get_Struct(rb_tree, git_tree, tree);
+
+	if (!rb_obj_is_kind_of(rb_tree, rb_cRuggedTree)) {
+		rb_raise(rb_eTypeError, "A Rugged::Tree instance is required");
+	}
+
+	error = git_index_read_tree(index, tree);
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    index.diff([options]) -> diff
+ *    index.diff(diffable[, options]) -> diff
+ *
+ *  The first form returns a diff between the index and the current working
+ *  directory.
+ *
+ *  The second form returns a diff between the index and the given diffable object.
+ *  +diffable+ can either be a +Rugged::Commit+ or a +Rugged::Tree+.
+ *
+ *  The index will be used as the "old file" side of the diff, while the working
+ *  directory or the +diffable+ will be used for the "new file" side.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :paths ::
+ *    An array of paths / fnmatch patterns to constrain the diff to a specific
+ *    set of files. Also see +:disable_pathspec_match+.
+ *
+ *  :max_size ::
+ *    An integer specifying the maximum byte size of a file before a it will
+ *    be treated as binary. The default value is 512MB.
+ *
+ *  :context_lines ::
+ *    The number of unchanged lines that define the boundary of a hunk (and
+ *    to display before and after the actual changes). The default is 3.
+ *
+ *  :interhunk_lines ::
+ *    The maximum number of unchanged lines between hunk boundaries before the hunks
+ *    will be merged into a one. The default is 0.
+ *
+ *  :reverse ::
+ *    If true, the sides of the diff will be reversed.
+ *
+ *  :force_text ::
+ *    If true, all files will be treated as text, disabling binary attributes & detection.
+ *
+ *  :ignore_whitespace ::
+ *    If true, all whitespace will be ignored.
+ *
+ *  :ignore_whitespace_change ::
+ *    If true, changes in amount of whitespace will be ignored.
+ *
+ *  :ignore_whitespace_eol ::
+ *    If true, whitespace at end of line will be ignored.
+ *
+ *  :ignore_submodules ::
+ *    if true, submodules will be excluded from the diff completely.
+ *
+ *  :patience ::
+ *    If true, the "patience diff" algorithm will be used (currenlty unimplemented).
+ *
+ *  :include_ignored ::
+ *    If true, ignored files will be included in the diff.
+ *
+ *  :include_untracked ::
+ *   If true, untracked files will be included in the diff.
+ *
+ *  :include_unmodified ::
+ *    If true, unmodified files will be included in the diff.
+ *
+ *  :recurse_untracked_dirs ::
+ *    Even if +:include_untracked+ is true, untracked directories will only be
+ *    marked with a single entry in the diff. If this flag is set to true,
+ *    all files under ignored directories will be included in the diff, too.
+ *
+ *  :disable_pathspec_match ::
+ *    If true, the given +:paths+ will be applied as exact matches, instead of
+ *    as fnmatch patterns.
+ *
+ *  :deltas_are_icase ::
+ *    If true, filename comparisons will be made with case-insensitivity.
+ *
+ *  :include_untracked_content ::
+ *    if true, untracked content will be contained in the the diff patch text.
+ *
+ *  :skip_binary_check ::
+ *    If true, diff deltas will be generated without spending time on binary
+ *    detection. This is useful to improve performance in cases where the actual
+ *    file content difference is not needed.
+ *
+ *  :include_typechange ::
+ *    If true, type changes for files will not be interpreted as deletion of
+ *    the "old file" and addition of the "new file", but will generate
+ *    typechange records.
+ *
+ *  :include_typechange_trees ::
+ *    Even if +:include_typechange+ is true, blob -> tree changes will still
+ *    usually be handled as a deletion of the blob. If this flag is set to true,
+ *    blob -> tree changes will be marked as typechanges.
+ *
+ *  :ignore_filemode ::
+ *    If true, file mode changes will be ignored.
+ *
+ *  :recurse_ignored_dirs ::
+ *    Even if +:include_ignored+ is true, ignored directories will only be
+ *    marked with a single entry in the diff. If this flag is set to true,
+ *    all files under ignored directories will be included in the diff, too.
+ */
+static VALUE rb_git_index_diff(int argc, VALUE *argv, VALUE self)
+{
+	git_index *index;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_repository *repo;
+	git_diff *diff = NULL;
+	VALUE owner, rb_other, rb_options;
+	int error;
+
+	rb_scan_args(argc, argv, "01:", &rb_other, &rb_options);
+	rugged_parse_diff_options(&opts, rb_options);
+
+	Data_Get_Struct(self, git_index, index);
+	owner = rugged_owner(self);
+	Data_Get_Struct(owner, git_repository, repo);
+
+	if (NIL_P(rb_other)) {
+		error = git_diff_index_to_workdir(&diff, repo, index, &opts);
+	} else {
+		// Need to flip the reverse option, so that the index is by default
+		// the "old file" side of the diff.
+		opts.flags ^= GIT_DIFF_REVERSE;
+
+		if (rb_obj_is_kind_of(rb_other, rb_cRuggedCommit)) {
+			git_tree *other_tree;
+			git_commit *commit;
+			Data_Get_Struct(rb_other, git_commit, commit);
+			error = git_commit_tree(&other_tree, commit);
+
+			if (!error)
+				error = git_diff_tree_to_index(&diff, repo, other_tree, index, &opts);
+		} else if (rb_obj_is_kind_of(rb_other, rb_cRuggedTree)) {
+			git_tree *other_tree;
+			Data_Get_Struct(rb_other, git_tree, other_tree);
+			error = git_diff_tree_to_index(&diff, repo, other_tree, index, &opts);
+		} else {
+			xfree(opts.pathspec.strings);
+			rb_raise(rb_eTypeError, "A Rugged::Commit or Rugged::Tree instance is required");
+		}
+	}
+
+	xfree(opts.pathspec.strings);
+	rugged_exception_check(error);
+
+	return rugged_diff_new(rb_cRuggedDiff, owner, diff);
+}
+
+/*
+ *  call-seq:
+ *    index.conflicts? -> true or false
+ *
+ *  Determines if the index contains entries representing conflicts.
+ */
+static VALUE rb_git_index_conflicts_p(VALUE self)
+{
+	git_index *index;
+	Data_Get_Struct(self, git_index, index);
+	return git_index_has_conflicts(index) ? Qtrue : Qfalse;
+}
+
+/*
+ *  call-seq:
+ *    index.conflict_add(conflict) -> nil
+ *
+ *  Add or update index entries that represent a conflict.
+ *
+ *  +conflict+ has to be a hash containing +:ancestor+, +:ours+ and
+ *  +:theirs+ key/value pairs. Any of those paris can be +nil+ (or left out)
+ *  to indicate that the file was not present in the respective tree during
+ *  the merge.
+ */
+static VALUE rb_git_conflict_add(VALUE self, VALUE rb_conflict)
+{
+	VALUE rb_ancestor, rb_ours, rb_theirs;
+	git_index *index;
+	git_index_entry ancestor, ours, theirs;
+	int error;
+
+	Check_Type(rb_conflict, T_HASH);
+
+	rb_ancestor = rb_hash_aref(rb_conflict, CSTR2SYM("ancestor"));
+	rb_ours     = rb_hash_aref(rb_conflict, CSTR2SYM("ours"));
+	rb_theirs   = rb_hash_aref(rb_conflict, CSTR2SYM("theirs"));
+
+	if (!NIL_P(rb_ancestor))
+		rb_git_indexentry_toC(&ancestor, rb_ancestor);
+
+	if (!NIL_P(rb_ours))
+		rb_git_indexentry_toC(&ours, rb_ours);
+
+	if (!NIL_P(rb_theirs))
+		rb_git_indexentry_toC(&theirs, rb_theirs);
+
+	Data_Get_Struct(self, git_index, index);
+
+	error = git_index_conflict_add(index,
+		NIL_P(rb_ancestor) ? NULL : &ancestor,
+		NIL_P(rb_theirs) ? NULL : &ours,
+		NIL_P(rb_ours) ? NULL : &theirs);
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    index.conflict_remove(path) -> nil
+ *
+ *  Removes the index entries that represent the conflict at +path+.
+ */
+static VALUE rb_git_conflict_remove(VALUE self, VALUE rb_path)
+{
+	git_index *index;
+	int error;
+
+	Check_Type(rb_path, T_STRING);
+
+	Data_Get_Struct(self, git_index, index);
+
+	error = git_index_conflict_remove(index, StringValueCStr(rb_path));
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    index.conflict_get(path) -> conflict or nil
+ *
+ *  Return index entries from the ancestor, our side and their side of
+ *  the conflict at +path+.
+ *
+ *  If +:ancestor+, +:ours+ or +:theirs+ is +nil+, that indicates that +path+
+ *  did not exist in the respective tree.
+ *
+ *  Returns nil if no conflict is present at +path+.
+ */
+static VALUE rb_git_conflict_get(VALUE self, VALUE rb_path)
+{
+	VALUE rb_result = rb_hash_new();
+	git_index *index;
+	const git_index_entry *ancestor, *ours, *theirs;
+	int error;
+
+	Check_Type(rb_path, T_STRING);
+
+	Data_Get_Struct(self, git_index, index);
+
+	error = git_index_conflict_get(&ancestor, &ours, &theirs, index, StringValueCStr(rb_path));
+	if (error == GIT_ENOTFOUND)
+		return Qnil;
+	else
+		rugged_exception_check(error);
+
+	rb_hash_aset(rb_result, CSTR2SYM("ancestor"), rb_git_indexentry_fromC(ancestor));
+	rb_hash_aset(rb_result, CSTR2SYM("ours"),     rb_git_indexentry_fromC(ours));
+	rb_hash_aset(rb_result, CSTR2SYM("theirs"),   rb_git_indexentry_fromC(theirs));
+
+	return rb_result;
+}
+
+void rugged_parse_merge_file_options(git_merge_file_options *opts, VALUE rb_options)
+{
+	if (!NIL_P(rb_options)) {
+		VALUE rb_value;
+		Check_Type(rb_options, T_HASH);
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("ancestor_label"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts->ancestor_label = StringValueCStr(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("our_label"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts->our_label = StringValueCStr(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("their_label"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts->their_label = StringValueCStr(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("favor"));
+		if (!NIL_P(rb_value)) {
+			ID id_favor;
+
+			Check_Type(rb_value, T_SYMBOL);
+			id_favor = SYM2ID(rb_value);
+
+			if (id_favor == rb_intern("normal")) {
+				opts->favor = GIT_MERGE_FILE_FAVOR_NORMAL;
+			} else if (id_favor == rb_intern("ours")) {
+				opts->favor = GIT_MERGE_FILE_FAVOR_OURS;
+			} else if (id_favor == rb_intern("theirs")) {
+				opts->favor = GIT_MERGE_FILE_FAVOR_THEIRS;
+			} else if (id_favor == rb_intern("union")) {
+				opts->favor = GIT_MERGE_FILE_FAVOR_UNION;
+			} else {
+				rb_raise(rb_eTypeError,
+					"Invalid favor mode. Expected `:normal`, `:ours`, `:theirs` or `:union`");
+			}
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("style"));
+		if (!NIL_P(rb_value)) {
+			ID id_style;
+
+			Check_Type(rb_value, T_SYMBOL);
+			id_style = SYM2ID(rb_value);
+
+			if (id_style == rb_intern("standard")) {
+				opts->flags |= GIT_MERGE_FILE_STYLE_MERGE;
+			} else if (id_style == rb_intern("diff3")) {
+				opts->flags |= GIT_MERGE_FILE_STYLE_DIFF3;
+			} else {
+				rb_raise(rb_eTypeError,
+					"Invalid style mode. Expected `:standard`, or `:diff3`");
+			}
+		} else {
+			opts->flags |= GIT_MERGE_FILE_STYLE_MERGE;
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("simplify")))) {
+			opts->flags |= GIT_MERGE_FILE_SIMPLIFY_ALNUM;
+		}
+	}
+}
+
+/*
+ *  call-seq:
+ *    index.merge_file(path[, options]) -> merge_file or nil
+ *    index.merge_file(path) -> merge_file or nil
+ *
+ *  Return merge_file (in memory) from the ancestor, our side and their side of
+ *  the conflict at +path+.
+ *
+ *  If +:ancestor+, +:ours+ or +:theirs+ is +nil+, that indicates that +path+
+ *  did not exist in the respective tree.
+ *
+ *  Returns nil if no conflict is present at +path+.
+
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :ancestor_label ::
+ *    The name of the ancestor branch used to decorate conflict markers.
+ *
+ *  :our_label ::
+ *    The name of our branch used to decorate conflict markers.
+ *
+ *  :their_label ::
+ *    The name of their branch used to decorate conflict markers.
+ *
+ *  :favor ::
+ *    Specifies how and if conflicts are auto-resolved by favoring a specific
+ *    file output. Can be one of `:normal`, `:ours`, `:theirs` or `:union`.
+ *    Defaults to `:normal`.
+ *
+ *  :style ::
+ *    Specifies the type of merge file to produce. Can be one of `:standard`, `:diff3`. Defaults to `:standard`
+ *
+ *  :simplify ::
+ *    If true, the merge file is simplified by condensing non-alphanumeric regions.
+ *
+ */
+
+static VALUE rb_git_merge_file(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_path, rb_options;
+	VALUE rb_result = rb_hash_new();
+	VALUE rb_repo = rugged_owner(self);
+
+	git_repository *repo;
+	git_index *index;
+	const git_index_entry *ancestor, *ours, *theirs;
+	git_merge_file_result merge_file_result = {0};
+	git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
+	int error;
+
+	rb_scan_args(argc, argv, "1:", &rb_path, &rb_options);
+
+	if (!NIL_P(rb_options)) {
+		Check_Type(rb_options, T_HASH);
+		rugged_parse_merge_file_options(&opts, rb_options);
+	}
+
+	Check_Type(rb_path, T_STRING);
+
+	Data_Get_Struct(self, git_index, index);
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_index_conflict_get(&ancestor, &ours, &theirs, index, StringValueCStr(rb_path));
+	if (error == GIT_ENOTFOUND)
+		return Qnil;
+	else
+		rugged_exception_check(error);
+
+	error = git_merge_file_from_index(&merge_file_result, repo, ancestor, ours, theirs, &opts);
+	rugged_exception_check(error);
+
+	rb_hash_aset(rb_result, CSTR2SYM("automergeable"), merge_file_result.automergeable ? Qtrue : Qfalse);
+	rb_hash_aset(rb_result, CSTR2SYM("path"),         rb_path);
+	rb_hash_aset(rb_result, CSTR2SYM("filemode"),     INT2FIX(merge_file_result.mode));
+	rb_hash_aset(rb_result, CSTR2SYM("data"),         rb_str_new(merge_file_result.ptr, merge_file_result.len));
+
+	git_merge_file_result_free(&merge_file_result);
+
+	return rb_result;
+}
+
+/*
+ *  call-seq:
+ *    index.conflict_cleanup -> nil
+ *
+ *  Remove all conflicting entries (entries with a stage greater than 0)
+ *  from the index.
+ */
+static VALUE rb_git_conflict_cleanup(VALUE self)
+{
+	git_index *index;
+
+	Data_Get_Struct(self, git_index, index);
+	git_index_conflict_cleanup(index);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    index.conflicts -> conflicts
+ *
+ *  Return all conflicts in +index+.
+ *
+ *  Each conflict is represented as a Hash with +:ancestor+, +:ours+ or
+ *  +:theirs+ key-value pairs, each containing index entry data.
+ *
+ *  If the value of the +:ancestor+, +:ours+ or +:theirs+ key is +nil+,
+ *  that indicates that file in conflict did not exists in the respective tree.
+ */
+static VALUE rb_git_index_conflicts(VALUE self)
+{
+	VALUE rb_conflicts = rb_ary_new();
+	git_index *index;
+	git_index_conflict_iterator *iter;
+	const git_index_entry *ancestor, *ours, *theirs;
+	int error;
+
+	Data_Get_Struct(self, git_index, index);
+
+	error = git_index_conflict_iterator_new(&iter, index);
+	rugged_exception_check(error);
+
+	while ((error = git_index_conflict_next(&ancestor, &ours, &theirs, iter)) == GIT_OK) {
+		VALUE rb_conflict = rb_hash_new();
+
+		rb_hash_aset(rb_conflict, CSTR2SYM("ancestor"), rb_git_indexentry_fromC(ancestor));
+		rb_hash_aset(rb_conflict, CSTR2SYM("ours"),     rb_git_indexentry_fromC(ours));
+		rb_hash_aset(rb_conflict, CSTR2SYM("theirs"),   rb_git_indexentry_fromC(theirs));
+
+		rb_ary_push(rb_conflicts, rb_conflict);
+	}
+
+	git_index_conflict_iterator_free(iter);
+
+	if (error != GIT_ITEROVER)
+		rugged_exception_check(error);
+
+	return rb_conflicts;
+}
+
+/*
+ *  Document-class: Rugged::Index
+ *
+ *  == Index Entries
+ *
+ *  Index entries are represented as Hash instances with the following key/value pairs:
+ *
+ *  path: ::
+ *    The entry's path in the index.
+ *
+ *  oid: ::
+ *    The oid of the entry's git object (blob / tree).
+ *
+ *  dev: ::
+ *    The device for the index entry.
+ *
+ *  ino: ::
+ *    The inode for the index entry.
+ *
+ *  mode: ::
+ *    The current permissions of the index entry.
+ *
+ *  gid: ::
+ *    Group ID of the index entry's owner.
+ *
+ *  uid: ::
+ *    User ID of the index entry's owner.
+ *
+ *  file_size: ::
+ *    The index entry's size, in bytes.
+ *
+ *  valid: ::
+ *    +true+ if the index entry is valid, +false+ otherwise.
+ *
+ *  stage: ::
+ *    The current stage of the index entry.
+ *
+ *  mtime: ::
+ *    A Time instance representing the index entry's time of last modification.
+ *
+ *  mtime: ::
+ *    A Time instance representing the index entry's time of last status change
+ *    (ie. change of owner, group, mode, etc.).
+ */
+void Init_rugged_index(void)
+{
+	/*
+	 * Index
+	 */
+	rb_cRuggedIndex = rb_define_class_under(rb_mRugged, "Index", rb_cObject);
+	rb_define_singleton_method(rb_cRuggedIndex, "new", rb_git_index_new, -1);
+
+	rb_define_method(rb_cRuggedIndex, "count", rb_git_index_count, 0);
+	rb_define_method(rb_cRuggedIndex, "reload", rb_git_index_read, 0);
+	rb_define_method(rb_cRuggedIndex, "clear", rb_git_index_clear, 0);
+	rb_define_method(rb_cRuggedIndex, "write", rb_git_index_write, 0);
+	rb_define_method(rb_cRuggedIndex, "get", rb_git_index_get, -1);
+	rb_define_method(rb_cRuggedIndex, "[]", rb_git_index_get, -1);
+	rb_define_method(rb_cRuggedIndex, "each", rb_git_index_each, 0);
+	rb_define_method(rb_cRuggedIndex, "diff", rb_git_index_diff, -1);
+
+	rb_define_method(rb_cRuggedIndex, "conflicts?", rb_git_index_conflicts_p, 0);
+	rb_define_method(rb_cRuggedIndex, "conflicts", rb_git_index_conflicts, 0);
+	rb_define_method(rb_cRuggedIndex, "conflict_get", rb_git_conflict_get, 1);
+	rb_define_method(rb_cRuggedIndex, "conflict_add", rb_git_conflict_add, 1);
+	rb_define_method(rb_cRuggedIndex, "conflict_remove", rb_git_conflict_remove, 1);
+	rb_define_method(rb_cRuggedIndex, "conflict_cleanup", rb_git_conflict_cleanup, 0);
+
+	rb_define_method(rb_cRuggedIndex, "merge_file", rb_git_merge_file, -1);
+
+	rb_define_method(rb_cRuggedIndex, "add", rb_git_index_add, 1);
+	rb_define_method(rb_cRuggedIndex, "update", rb_git_index_add, 1);
+	rb_define_method(rb_cRuggedIndex, "<<", rb_git_index_add, 1);
+
+	rb_define_method(rb_cRuggedIndex, "remove", rb_git_index_remove, -1);
+	rb_define_method(rb_cRuggedIndex, "remove_dir", rb_git_index_remove_directory, -1);
+
+	rb_define_method(rb_cRuggedIndex, "add_all", rb_git_index_add_all, -1);
+	rb_define_method(rb_cRuggedIndex, "update_all", rb_git_index_update_all, -1);
+	rb_define_method(rb_cRuggedIndex, "remove_all", rb_git_index_remove_all, -1);
+
+	rb_define_method(rb_cRuggedIndex, "write_tree", rb_git_index_writetree, -1);
+	rb_define_method(rb_cRuggedIndex, "read_tree", rb_git_index_readtree, 1);
+
+	rb_const_set(rb_cRuggedIndex, rb_intern("ENTRY_FLAGS_STAGE"), INT2FIX(GIT_IDXENTRY_STAGEMASK));
+	rb_const_set(rb_cRuggedIndex, rb_intern("ENTRY_FLAGS_STAGE_SHIFT"), INT2FIX(GIT_IDXENTRY_STAGESHIFT));
+	rb_const_set(rb_cRuggedIndex, rb_intern("ENTRY_FLAGS_VALID"), INT2FIX(GIT_IDXENTRY_VALID));
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_note.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_note.c
new file mode 100755
index 0000000..0828874
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_note.c
@@ -0,0 +1,376 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_cRuggedRepo;
+extern VALUE rb_cRuggedObject;
+
+static VALUE rugged_git_note_message(const git_note *note)
+{
+	const char *message;
+	message = git_note_message(note);
+
+	/*
+	 * assume the note message is utf8 compatible, because that's
+	 * the sensible thing to do.
+	 */
+	return rb_str_new_utf8(message);
+}
+
+static VALUE rugged_git_note_oid(const git_note* note)
+{
+	const git_oid *oid;
+	oid = git_note_id(note);
+
+	return rugged_create_oid(oid);
+}
+
+/*
+ *  call-seq:
+ *    obj.notes(notes_ref = 'refs/notes/commits') -> hash
+ *
+ *  Lookup a note for +obj+ from +notes_ref+:
+ *  - +notes_ref+: (optional): canonical name of the reference to use, defaults to "refs/notes/commits"
+ *
+ *  Returns a new Hash object.
+ *
+ *    obj.notes #=> {:message=>"note text\n", :oid=>"94eca2de348d5f672faf56b0decafa5937e3235e"}
+ */
+static VALUE rb_git_note_lookup(int argc, VALUE *argv, VALUE self)
+{
+	git_repository *repo;
+	const char *notes_ref = NULL;
+	VALUE rb_notes_ref;
+	VALUE rb_note_hash;
+	VALUE owner;
+	git_note *note;
+	git_object *object;
+	int error;
+
+	rb_scan_args(argc, argv, "01", &rb_notes_ref);
+
+	if (!NIL_P(rb_notes_ref)) {
+		Check_Type(rb_notes_ref, T_STRING);
+		notes_ref = StringValueCStr(rb_notes_ref);
+	}
+
+	Data_Get_Struct(self, git_object, object);
+
+	owner = rugged_owner(self);
+	Data_Get_Struct(owner, git_repository, repo);
+
+	error = git_note_read(&note, repo, notes_ref, git_object_id(object));
+
+	if (error == GIT_ENOTFOUND)
+		return Qnil;
+
+	rugged_exception_check(error);
+
+	rb_note_hash = rb_hash_new();
+	rb_hash_aset(rb_note_hash, CSTR2SYM("message"), rugged_git_note_message(note));
+	rb_hash_aset(rb_note_hash, CSTR2SYM("oid"), rugged_git_note_oid(note));
+
+	git_note_free(note);
+
+	return rb_note_hash;
+}
+
+/*
+ *  call-seq:
+ *    obj.create_note(data = {}) -> oid
+ *
+ *  Write a new +note+ to +object+, with the given +data+
+ *  arguments, passed as a +Hash+:
+ *
+ *  - +:message+: the content of the note to add to the object
+ *  - +:committer+: (optional) a hash with the signature for the committer
+ *    defaults to the signature from the configuration
+ *  - +:author+: (optional) a hash with the signature for the author
+ *    defaults to the signature from the configuration
+ *  - +:ref+: (optional): canonical name of the reference to use, defaults to "refs/notes/commits"
+ *  - +:force+: (optional): overwrite existing note (disabled by default)
+ *
+ *  When the note is successfully written to disk, its +oid+ will be
+ *  returned as a hex +String+.
+ *
+ *    author = {:email=>"tanoku at gmail.com", :time=>Time.now, :name=>"Vicent Mart\303\255"}
+ *
+ *    obj.create_note(
+ *      :author    => author,
+ *      :committer => author,
+ *      :message   => "Hello world\n\n",
+ *      :ref       => 'refs/notes/builds'
+ *    )
+ */
+static VALUE rb_git_note_create(VALUE self, VALUE rb_data)
+{
+	VALUE rb_ref, rb_message, rb_force;
+	git_repository *repo = NULL;
+	const char *notes_ref = NULL;
+
+	VALUE owner;
+
+	git_signature *author, *committer;
+	git_oid note_oid;
+
+	git_object *target = NULL;
+	int error = 0;
+	int force = 0;
+
+	Check_Type(rb_data, T_HASH);
+
+	Data_Get_Struct(self, git_object, target);
+
+	owner = rugged_owner(self);
+	Data_Get_Struct(owner, git_repository, repo);
+
+	rb_ref = rb_hash_aref(rb_data, CSTR2SYM("ref"));
+
+	rb_force = rb_hash_aref(rb_data, CSTR2SYM("force"));
+	if (!NIL_P(rb_force))
+		force = rugged_parse_bool(rb_force);
+
+	if (!NIL_P(rb_ref)) {
+		Check_Type(rb_ref, T_STRING);
+		notes_ref = StringValueCStr(rb_ref);
+	}
+
+	rb_message = rb_hash_aref(rb_data, CSTR2SYM("message"));
+	Check_Type(rb_message, T_STRING);
+
+	committer = rugged_signature_get(
+		rb_hash_aref(rb_data, CSTR2SYM("committer")), repo
+	);
+
+	author = rugged_signature_get(
+		rb_hash_aref(rb_data, CSTR2SYM("author")), repo
+	);
+
+	error = git_note_create(
+			&note_oid,
+			repo,
+			notes_ref,
+			author,
+			committer,
+			git_object_id(target),
+			StringValueCStr(rb_message),
+			force);
+
+
+	git_signature_free(author);
+	git_signature_free(committer);
+
+	rugged_exception_check(error);
+
+	return rugged_create_oid(&note_oid);
+}
+
+/*
+ *  call-seq:
+ *    obj.remove_note(data = {}) -> boolean
+ *
+ *  Removes a +note+ from +object+, with the given +data+
+ *  arguments, passed as a +Hash+:
+ *
+ *  - +:committer+ (optional): a hash with the signature for the committer,
+ *    defaults to the signature from the configuration
+ *  - +:author+ (optional): a hash with the signature for the author,
+ *    defaults to the signature from the configuration
+ *  - +:ref+: (optional): canonical name of the reference to use, defaults to "refs/notes/commits"
+ *
+ *  When the note is successfully removed +true+ will be
+ *  returned as a +Boolean+.
+ *
+ *    author = {:email=>"tanoku at gmail.com", :time=>Time.now, :name=>"Vicent Mart\303\255"}
+ *
+ *    obj.remove_note(
+ *      :author    => author,
+ *      :committer => author,
+ *      :ref       => 'refs/notes/builds'
+ *    )
+ */
+static VALUE rb_git_note_remove(int argc, VALUE *argv, VALUE self)
+{
+	int error = 0;
+	const char *notes_ref = NULL;
+	git_repository *repo = NULL;
+	git_signature *author, *committer;
+	git_object *target = NULL;
+	VALUE rb_data;
+	VALUE rb_ref = Qnil;
+	VALUE rb_author = Qnil;
+	VALUE rb_committer = Qnil;
+	VALUE owner;
+
+	Data_Get_Struct(self, git_object, target);
+
+	owner = rugged_owner(self);
+	Data_Get_Struct(owner, git_repository, repo);
+
+	rb_scan_args(argc, argv, "01", &rb_data);
+
+	if (!NIL_P(rb_data)) {
+		Check_Type(rb_data, T_HASH);
+
+		rb_ref = rb_hash_aref(rb_data, CSTR2SYM("ref"));
+		if (!NIL_P(rb_ref)) {
+			Check_Type(rb_ref, T_STRING);
+			notes_ref = StringValueCStr(rb_ref);
+		}
+
+		rb_committer = rb_hash_aref(rb_data, CSTR2SYM("committer"));
+		rb_author = rb_hash_aref(rb_data, CSTR2SYM("author"));
+	}
+
+	committer = rugged_signature_get(rb_committer, repo);
+	author = rugged_signature_get(rb_author, repo);
+
+	error = git_note_remove(
+			repo,
+			notes_ref,
+			author,
+			committer,
+			git_object_id(target));
+
+	git_signature_free(author);
+	git_signature_free(committer);
+
+	if (error == GIT_ENOTFOUND)
+		return Qfalse;
+
+	rugged_exception_check(error);
+
+	return Qtrue;
+}
+
+static int cb_note__each(const git_oid *blob_id, const git_oid *annotated_object_id, void *data)
+{
+	VALUE rb_args = rb_ary_new2(2);
+	struct rugged_cb_payload *payload = data;
+	git_object *annotated_object;
+	git_object *note_blob;
+
+	git_repository *repo;
+
+	Data_Get_Struct(payload->rb_data, git_repository, repo);
+
+	rugged_exception_check(
+		git_object_lookup(&annotated_object, repo, annotated_object_id, GIT_OBJ_ANY)
+	);
+
+	rugged_exception_check(
+		git_object_lookup(&note_blob, repo, blob_id, GIT_OBJ_BLOB)
+	);
+
+	rb_ary_push(rb_args, rugged_object_new(payload->rb_data, note_blob));
+	rb_ary_push(rb_args, rugged_object_new(payload->rb_data, annotated_object));
+
+	rb_protect(rb_yield_splat, rb_args, &payload->exception);
+
+	return payload->exception ? GIT_ERROR : GIT_OK;
+}
+
+/*
+ *  call-seq:
+ *    repo.each_note(notes_ref = "refs/notes/commits") { |note_blob, annotated_object| block }
+ *    repo.each_note(notes_ref = "refs/notes/commits") -> an_enumerator
+ *
+ *  Call the given block once for each note_blob/annotated_object pair in +repository+
+ *  - +notes_ref+: (optional): canonical name of the reference to use defaults to "refs/notes/commits"
+ *
+ *  If no block is given, an +Enumerator+ is returned.
+ *
+ *    @repo.each_note do |note_blob, annotated_object|
+ *      puts "#{note_blob.oid} => #{annotated_object.oid}"
+ *    end
+ */
+static VALUE rb_git_note_each(int argc, VALUE *argv, VALUE self)
+{
+	git_repository *repo;
+	const char *notes_ref = NULL;
+	int error;
+	struct rugged_cb_payload payload = { self, 0 };
+	VALUE rb_notes_ref;
+
+	rb_scan_args(argc, argv, "01", &rb_notes_ref);
+
+	if (!rb_block_given_p()) {
+		return rb_funcall(self, rb_intern("to_enum"), 3, CSTR2SYM("each_note"), self, rb_notes_ref);
+	}
+
+	if (!NIL_P(rb_notes_ref)) {
+		Check_Type(rb_notes_ref, T_STRING);
+		notes_ref = StringValueCStr(rb_notes_ref);
+	}
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	error = git_note_foreach(repo, notes_ref, &cb_note__each, &payload);
+
+	if (payload.exception)
+		rb_jump_tag(payload.exception);
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    repo.notes_default_ref() -> string
+ *
+ *  Get the default notes reference for a +repository+:
+ *
+ *  Returns a new String object.
+ *
+ *    repo.default_notes_ref #=> "refs/notes/commits"
+ */
+static VALUE rb_git_note_default_ref_GET(VALUE self)
+{
+	git_repository *repo = NULL;
+	git_buf ref_name = { 0 };
+	VALUE rb_result;
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	rugged_exception_check(
+		git_note_default_ref(&ref_name, repo)
+	);
+
+	rb_result = rb_enc_str_new(ref_name.ptr, ref_name.size, rb_utf8_encoding());
+
+	git_buf_free(&ref_name);
+
+	return rb_result;
+}
+
+void Init_rugged_notes(void)
+{
+	rb_define_method(rb_cRuggedObject, "notes", rb_git_note_lookup, -1);
+	rb_define_method(rb_cRuggedObject, "create_note", rb_git_note_create, 1);
+	rb_define_method(rb_cRuggedObject, "remove_note", rb_git_note_remove, -1);
+
+	rb_define_method(rb_cRuggedRepo, "each_note", rb_git_note_each, -1);
+	rb_define_method(rb_cRuggedRepo, "default_notes_ref", rb_git_note_default_ref_GET, 0);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_object.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_object.c
new file mode 100755
index 0000000..7a4de3c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_object.c
@@ -0,0 +1,383 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedTagAnnotation;
+extern VALUE rb_cRuggedTree;
+extern VALUE rb_cRuggedCommit;
+extern VALUE rb_cRuggedBlob;
+extern VALUE rb_cRuggedRepo;
+
+VALUE rb_cRuggedObject;
+
+git_otype rugged_otype_get(VALUE self)
+{
+	git_otype type = GIT_OBJ_BAD;
+
+	if (NIL_P(self))
+		return GIT_OBJ_ANY;
+
+	switch (TYPE(self)) {
+	case T_STRING:
+		type = git_object_string2type(StringValueCStr(self));
+		break;
+
+	case T_FIXNUM:
+		type = FIX2INT(self);
+		break;
+
+	case T_SYMBOL: {
+		ID t = SYM2ID(self);
+
+		if (t == rb_intern("commit"))
+			type = GIT_OBJ_COMMIT;
+		else if (t == rb_intern("tree"))
+			type = GIT_OBJ_TREE;
+		else if (t == rb_intern("tag"))
+			type = GIT_OBJ_TAG;
+		else if (t == rb_intern("blob"))
+			type = GIT_OBJ_BLOB;
+	   }
+	}
+
+	if (!git_object_typeisloose(type))
+		rb_raise(rb_eTypeError, "Invalid Git object type specifier");
+
+	return type;
+}
+
+VALUE rugged_otype_new(git_otype t)
+{
+	switch (t) {
+		case GIT_OBJ_COMMIT:
+			return CSTR2SYM("commit");
+		case GIT_OBJ_TAG:
+			return CSTR2SYM("tag");
+		case GIT_OBJ_TREE:
+			return CSTR2SYM("tree");
+		case GIT_OBJ_BLOB:
+			return CSTR2SYM("blob");
+		default:
+			return Qnil;
+	}
+}
+
+int rugged_oid_get(git_oid *oid, git_repository *repo, VALUE p)
+{
+	git_object *object;
+	int error;
+
+	if (rb_obj_is_kind_of(p, rb_cRuggedObject)) {
+		Data_Get_Struct(p, git_object, object);
+		git_oid_cpy(oid, git_object_id(object));
+	} else {
+		Check_Type(p, T_STRING);
+
+		/* Fast path: see if the 40-char string is an OID */
+		if (RSTRING_LEN(p) == 40 &&
+			git_oid_fromstr(oid, RSTRING_PTR(p)) == 0)
+			return GIT_OK;
+
+		if ((error = git_revparse_single(&object, repo, StringValueCStr(p))))
+			return error;
+
+		git_oid_cpy(oid, git_object_id(object));
+		git_object_free(object);
+	}
+
+	return GIT_OK;
+}
+
+git_object *rugged_object_get(git_repository *repo, VALUE object_value, git_otype type)
+{
+	git_object *object = NULL;
+
+	if (rb_obj_is_kind_of(object_value, rb_cRuggedObject)) {
+		git_object *owned_obj = NULL;
+		Data_Get_Struct(object_value, git_object, owned_obj);
+		git_object_dup(&object, owned_obj);
+	} else {
+		int error;
+
+		Check_Type(object_value, T_STRING);
+
+		/* Fast path: if we have a 40-char string, just perform the lookup directly */
+		if (RSTRING_LEN(object_value) == 40) {
+			git_oid oid;
+
+			/* If it's not an OID, we can still try the revparse */
+			if (git_oid_fromstr(&oid, RSTRING_PTR(object_value)) == 0) {
+				error = git_object_lookup(&object, repo, &oid, type);
+				rugged_exception_check(error);
+				return object;
+			}
+		}
+
+		/* Otherwise, assume the string is a revlist and try to parse it */
+		error = git_revparse_single(&object, repo, StringValueCStr(object_value));
+		rugged_exception_check(error);
+	}
+
+	assert(object);
+
+	if (type != GIT_OBJ_ANY && git_object_type(object) != type)
+		rb_raise(rb_eArgError, "Object is not of the required type");
+
+	return object;
+}
+
+static void rb_git_object__free(git_object *object)
+{
+	git_object_free(object);
+}
+
+VALUE rugged_object_new(VALUE owner, git_object *object)
+{
+	VALUE klass, rb_object;
+
+	switch (git_object_type(object))
+	{
+		case GIT_OBJ_COMMIT:
+			klass = rb_cRuggedCommit;
+			break;
+
+		case GIT_OBJ_TAG:
+			klass = rb_cRuggedTagAnnotation;
+			break;
+
+		case GIT_OBJ_TREE:
+			klass = rb_cRuggedTree;
+			break;
+
+		case GIT_OBJ_BLOB:
+			klass = rb_cRuggedBlob;
+			break;
+
+		default:
+			rb_raise(rb_eTypeError, "Invalid type for Rugged::Object");
+			return Qnil; /* never reached */
+	}
+
+	rb_object = Data_Wrap_Struct(klass, NULL, &rb_git_object__free, object);
+	rugged_set_owner(rb_object, owner);
+	return rb_object;
+}
+
+
+static git_otype class2otype(VALUE klass)
+{
+	if (RTEST(rb_class_inherited_p(klass, rb_cRuggedCommit)))
+        return GIT_OBJ_COMMIT;
+
+	if (RTEST(rb_class_inherited_p(klass, rb_cRuggedTagAnnotation)))
+		return GIT_OBJ_TAG;
+
+	if (RTEST(rb_class_inherited_p(klass, rb_cRuggedBlob)))
+		return GIT_OBJ_BLOB;
+
+	if (RTEST(rb_class_inherited_p(klass, rb_cRuggedTree)))
+		return GIT_OBJ_TREE;
+
+	return GIT_OBJ_BAD;
+}
+
+/*
+ *  call-seq:
+ *    Object.new(repo, oid) -> object
+ *    Object.lookup(repo, oid) -> object
+ *
+ *  Find and return the git object inside +repo+ with the given +oid+.
+ *
+ *  +oid+ can either have be the complete, 40 character string or any
+ *  unique prefix.
+ */
+VALUE rb_git_object_lookup(VALUE klass, VALUE rb_repo, VALUE rb_hex)
+{
+	git_object *object;
+	git_otype type;
+	git_oid oid;
+	int error;
+	int oid_length;
+
+	git_repository *repo;
+
+	type = class2otype(klass);
+
+	if (type == GIT_OBJ_BAD)
+		type = GIT_OBJ_ANY;
+
+	Check_Type(rb_hex, T_STRING);
+	oid_length = (int)RSTRING_LEN(rb_hex);
+
+	rugged_check_repo(rb_repo);
+
+	if (oid_length > GIT_OID_HEXSZ)
+		rb_raise(rb_eTypeError, "The given OID is too long");
+
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_oid_fromstrn(&oid, RSTRING_PTR(rb_hex), oid_length);
+	rugged_exception_check(error);
+
+	if (oid_length < GIT_OID_HEXSZ)
+		error = git_object_lookup_prefix(&object, repo, &oid, oid_length, type);
+	else
+		error = git_object_lookup(&object, repo, &oid, type);
+
+	rugged_exception_check(error);
+
+	return rugged_object_new(rb_repo, object);
+}
+
+VALUE rugged_object_rev_parse(VALUE rb_repo, VALUE rb_spec, int as_obj)
+{
+	git_object *object;
+	const char *spec;
+	int error;
+	git_repository *repo;
+	VALUE ret;
+
+	Check_Type(rb_spec, T_STRING);
+	spec = RSTRING_PTR(rb_spec);
+
+	rugged_check_repo(rb_repo);
+
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_revparse_single(&object, repo, spec);
+	rugged_exception_check(error);
+
+	if (as_obj) {
+		return rugged_object_new(rb_repo, object);
+	}
+
+	ret = rugged_create_oid(git_object_id(object));
+	git_object_free(object);
+	return ret;
+}
+
+/*
+ *  call-seq: Object.rev_parse(repo, str) -> object
+ *
+ *  Find and return a single object inside +repo+ as specified by the
+ *  git revision string +str+.
+ *
+ *  See http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions or
+ *  <code>man gitrevisions</code> for information on the accepted syntax.
+ *
+ *  Raises a Rugged::InvalidError if +str+ does not contain a valid revision string.
+ */
+VALUE rb_git_object_rev_parse(VALUE klass, VALUE rb_repo, VALUE rb_spec)
+{
+	return rugged_object_rev_parse(rb_repo, rb_spec, 1);
+}
+
+/*
+ *  call-seq: Object.rev_parse_oid(repo, str) -> oid
+ *
+ *  Find and return the id of the object inside +repo+ as specified by the
+ *  git revision string +str+.
+ *
+ *  See http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions or
+ *  <code>man gitrevisions</code> for information on the accepted syntax.
+ *
+ *  Raises a Rugged::InvalidError if +str+ does not contain a valid revision string.
+ */
+VALUE rb_git_object_rev_parse_oid(VALUE klass, VALUE rb_repo, VALUE rb_spec)
+{
+	return rugged_object_rev_parse(rb_repo, rb_spec, 0);
+}
+
+/*
+ *  call-seq: object == other
+ *
+ *  Returns true only if +object+ and other are both instances or subclasses of
+ *  Rugged::Object and have the same object id, false otherwise.
+ */
+static VALUE rb_git_object_equal(VALUE self, VALUE other)
+{
+	git_object *a, *b;
+
+	if (!rb_obj_is_kind_of(other, rb_cRuggedObject))
+		return Qfalse;
+
+	Data_Get_Struct(self, git_object, a);
+	Data_Get_Struct(other, git_object, b);
+
+	return git_oid_cmp(git_object_id(a), git_object_id(b)) == 0 ? Qtrue : Qfalse;
+}
+
+/*
+ *  call-seq: object.oid -> oid
+ *
+ *  Return the Object ID (a 40 character SHA1 hash) for +object+.
+ */
+static VALUE rb_git_object_oid_GET(VALUE self)
+{
+	git_object *object;
+	Data_Get_Struct(self, git_object, object);
+	return rugged_create_oid(git_object_id(object));
+}
+
+/*
+ *  call-seq: object.type -> type
+ *
+ *  Returns the object's type. Can be one of +:commit+, +:tag+, +:tree+ or +:blob+.
+ */
+static VALUE rb_git_object_type_GET(VALUE self)
+{
+	git_object *object;
+	Data_Get_Struct(self, git_object, object);
+
+	return rugged_otype_new(git_object_type(object));
+}
+
+/*
+ *  call-seq: object.read_raw -> raw_object
+ *
+ *  Returns the git object as a Rugged::OdbObject instance.
+ */
+static VALUE rb_git_object_read_raw(VALUE self)
+{
+	git_object *object;
+	Data_Get_Struct(self, git_object, object);
+
+	return rugged_raw_read(git_object_owner(object), git_object_id(object));
+}
+
+void Init_rugged_object(void)
+{
+	rb_cRuggedObject = rb_define_class_under(rb_mRugged, "Object", rb_cObject);
+	rb_define_singleton_method(rb_cRuggedObject, "lookup", rb_git_object_lookup, 2);
+	rb_define_singleton_method(rb_cRuggedObject, "rev_parse", rb_git_object_rev_parse, 2);
+	rb_define_singleton_method(rb_cRuggedObject, "rev_parse_oid", rb_git_object_rev_parse_oid, 2);
+	rb_define_singleton_method(rb_cRuggedObject, "new", rb_git_object_lookup, 2);
+
+	rb_define_method(rb_cRuggedObject, "read_raw", rb_git_object_read_raw, 0);
+	rb_define_method(rb_cRuggedObject, "==", rb_git_object_equal, 1);
+	rb_define_method(rb_cRuggedObject, "oid", rb_git_object_oid_GET, 0);
+	rb_define_method(rb_cRuggedObject, "type", rb_git_object_type_GET, 0);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_patch.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_patch.c
new file mode 100755
index 0000000..2c90f47
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_patch.c
@@ -0,0 +1,245 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedDiffDelta;
+VALUE rb_cRuggedPatch;
+
+/*
+ *  call-seq:
+ *    Patch.from_strings(old_content = nil, new_content = nil, options = {}) -> patch
+ *
+ *  Directly generate a Rugged::Patch from the difference between the content of
+ *  the two strings `old_content` and `new_content`.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :old_path ::
+ *    An optional string to treat +blob+ as if it had this filename.
+ *
+ *  :new_path ::
+ *    An optional string to treat +other+ as if it had this filename.
+ *
+ *  Additionally, `options` can also contain all other valid diff options
+ *  (see Rugged::Tree#diff for a complete list).
+ */
+VALUE rb_git_patch_from_strings(int argc, VALUE *argv, VALUE self)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_patch *patch;
+	char * old_path = NULL, * new_path = NULL;
+	VALUE rb_old_buffer, rb_new_buffer, rb_options;
+
+	rb_scan_args(argc, argv, "02:", &rb_old_buffer, &rb_new_buffer, &rb_options);
+
+	if (!NIL_P(rb_options)) {
+		VALUE rb_value;
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("old_path"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_STRING);
+			old_path = StringValueCStr(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("new_path"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_STRING);
+			new_path = StringValueCStr(rb_value);
+		}
+
+		rugged_parse_diff_options(&opts, rb_options);
+	}
+
+	rugged_exception_check(git_patch_from_buffers(&patch,
+		NIL_P(rb_old_buffer) ? NULL : StringValuePtr(rb_old_buffer),
+		NIL_P(rb_old_buffer) ? 0 : RSTRING_LEN(rb_old_buffer),
+		old_path,
+		NIL_P(rb_new_buffer) ? NULL : StringValuePtr(rb_new_buffer),
+		NIL_P(rb_new_buffer) ? 0 : RSTRING_LEN(rb_new_buffer),
+		new_path,
+		&opts
+	));
+
+	return rugged_patch_new(self, patch);
+}
+
+VALUE rugged_patch_new(VALUE owner, git_patch *patch)
+{
+	VALUE rb_patch = Data_Wrap_Struct(rb_cRuggedPatch, NULL, &git_patch_free, patch);
+	rugged_set_owner(rb_patch, owner);
+	return rb_patch;
+}
+
+/*
+ *  call-seq:
+ *    patch.each_hunk { |hunk| } -> self
+ *    patch.each_hunk -> enumerator
+ *
+ *  If given a block, yields each hunk that is part of the patch.
+ *
+ *  If no block is given, an enumerator is returned instead.
+ */
+static VALUE rb_git_diff_patch_each_hunk(VALUE self)
+{
+	git_patch *patch;
+	const git_diff_hunk *hunk;
+	size_t lines_in_hunk;
+	int error = 0;
+	size_t hunks_count, h;
+
+	if (!rb_block_given_p()) {
+		return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("each_hunk"), self);
+	}
+
+	Data_Get_Struct(self, git_patch, patch);
+
+	hunks_count = git_patch_num_hunks(patch);
+	for (h = 0; h < hunks_count; ++h) {
+		error = git_patch_get_hunk(&hunk, &lines_in_hunk, patch, h);
+		if (error) break;
+
+		rb_yield(rugged_diff_hunk_new(self, h, hunk, lines_in_hunk));
+	}
+	rugged_exception_check(error);
+
+	return self;
+}
+
+/*
+ *  call-seq:
+ *    patch.hunk_count -> int
+ *
+ *  Returns the number of hunks in the patch.
+ */
+static VALUE rb_git_diff_patch_hunk_count(VALUE self)
+{
+	git_patch *patch;
+	Data_Get_Struct(self, git_patch, patch);
+
+	return INT2FIX(git_patch_num_hunks(patch));
+}
+
+/*
+ *  call-seq:
+ *    patch.delta -> delta
+ *
+ *  Returns the delta object associated with the patch.
+ */
+static VALUE rb_git_diff_patch_delta(VALUE self)
+{
+	git_patch *patch;
+	Data_Get_Struct(self, git_patch, patch);
+
+	return rugged_diff_delta_new(rugged_owner(self), git_patch_get_delta(patch));
+}
+
+/*
+ *  call-seq:
+ *    patch.stat -> int, int
+ *
+ *  Returns the number of additions and deletions in the patch.
+ */
+static VALUE rb_git_diff_patch_stat(VALUE self)
+{
+	git_patch *patch;
+	size_t additions, deletions;
+	Data_Get_Struct(self, git_patch, patch);
+
+	git_patch_line_stats(NULL, &additions, &deletions, patch);
+
+	return rb_ary_new3(2, INT2FIX(additions), INT2FIX(deletions));
+}
+
+/*
+ *  call-seq:
+ *    patch.lines -> int
+ *
+ *  Returns the total number of lines in the patch.
+ */
+static VALUE rb_git_diff_patch_lines(VALUE self)
+{
+	git_patch *patch;
+	size_t context, adds, dels;
+	Data_Get_Struct(self, git_patch, patch);
+
+	git_patch_line_stats(&context, &adds, &dels, patch);
+
+	return INT2FIX(context + adds + dels);
+}
+
+static int patch_print_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *payload)
+{
+	VALUE rb_str = (VALUE)payload;
+
+	switch (line->origin) {
+		case GIT_DIFF_LINE_CONTEXT:
+		case GIT_DIFF_LINE_ADDITION:
+		case GIT_DIFF_LINE_DELETION:
+			rb_str_cat(rb_str, &line->origin, 1);
+	}
+
+	rb_str_cat(rb_str, line->content, line->content_len);
+
+	return GIT_OK;
+}
+
+/*
+ *  call-seq:
+ *    patch.to_s -> str
+ *
+ *  Returns the contents of the patch as a single diff string.
+ */
+static VALUE rb_git_diff_patch_to_s(VALUE self)
+{
+	git_patch *patch;
+	VALUE rb_str = rb_str_new(NULL, 0);
+	Data_Get_Struct(self, git_patch, patch);
+
+	rugged_exception_check(git_patch_print(patch, patch_print_cb, (void*)rb_str));
+
+	return rb_str;
+}
+
+void Init_rugged_patch(void)
+{
+	rb_cRuggedPatch = rb_define_class_under(rb_mRugged, "Patch", rb_cObject);
+
+	rb_define_singleton_method(rb_cRuggedPatch, "from_strings", rb_git_patch_from_strings, -1);
+
+	rb_define_method(rb_cRuggedPatch, "stat", rb_git_diff_patch_stat, 0);
+	rb_define_method(rb_cRuggedPatch, "lines", rb_git_diff_patch_lines, 0);
+
+	rb_define_method(rb_cRuggedPatch, "delta", rb_git_diff_patch_delta, 0);
+
+	rb_define_method(rb_cRuggedPatch, "to_s", rb_git_diff_patch_to_s, 0);
+
+	rb_define_method(rb_cRuggedPatch, "each_hunk", rb_git_diff_patch_each_hunk, 0);
+	rb_define_method(rb_cRuggedPatch, "hunk_count", rb_git_diff_patch_hunk_count, 0);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_reference.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_reference.c
new file mode 100755
index 0000000..7dcf53b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_reference.c
@@ -0,0 +1,396 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedRepo;
+
+VALUE rb_cRuggedReference;
+
+void rb_git_ref__free(git_reference *ref)
+{
+	git_reference_free(ref);
+}
+
+VALUE rugged_ref_new(VALUE klass, VALUE owner, git_reference *ref)
+{
+	VALUE rb_ref = Data_Wrap_Struct(klass, NULL, &rb_git_ref__free, ref);
+	rugged_set_owner(rb_ref, owner);
+	return rb_ref;
+}
+
+/*
+ *  call-seq:
+ *    Reference.valid_name?(ref_name) -> true or false
+ *
+ *  Check if a reference name is well-formed.
+ *
+ *  Valid reference names must follow one of two patterns:
+ *
+ *  1. Top-level names must contain only capital letters and underscores,
+ *     and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
+ *  2. Names prefixed with "refs/" can be almost anything.  You must avoid
+ *     the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ *     sequences ".." and "@{" which have special meaning to revparse.
+ *
+ *  Returns true if the reference name is valid, false if not.
+ */
+static VALUE rb_git_ref_valid_name(VALUE klass, VALUE rb_name)
+{
+	Check_Type(rb_name, T_STRING);
+	return git_reference_is_valid_name(StringValueCStr(rb_name)) == 1 ? Qtrue : Qfalse;
+}
+
+/*
+ *  call-seq:
+ *    ref.peel -> oid
+ *
+ *  Peels tag objects to the sha that they point at. Replicates
+ *  +git show-ref --dereference+.
+ */
+static VALUE rb_git_ref_peel(VALUE self)
+{
+	/* Leave room for \0 */
+	git_reference *ref;
+	git_object *object;
+	char oid[GIT_OID_HEXSZ + 1];
+	int error;
+
+	Data_Get_Struct(self, git_reference, ref);
+
+	error = git_reference_peel(&object, ref, GIT_OBJ_ANY);
+	if (error == GIT_ENOTFOUND)
+		return Qnil;
+	else
+		rugged_exception_check(error);
+
+	if (git_reference_type(ref) == GIT_REF_OID &&
+			!git_oid_cmp(git_object_id(object), git_reference_target(ref))) {
+		git_object_free(object);
+		return Qnil;
+	} else {
+		git_oid_tostr(oid, sizeof(oid), git_object_id(object));
+		git_object_free(object);
+		return rb_str_new_utf8(oid);
+	}
+}
+
+/*
+ *  call-seq:
+ *    reference.target_id -> id
+ *    reference.target_id -> ref_name
+ *
+ *  Return the target of +reference+.
+ *
+ *  If +reference+ is a symbolic reference, it returns the target
+ *  reference object.
+ *
+ *  If +reference+ is a direct reference, it returns the target object.
+ *
+ *    ref1.type #=> :symbolic
+ *    ref1.target #=> #<Rugged::Reference ...>
+ *
+ *    ref2.type #=> :direct
+ *    ref2.target #=> #<Rugged::Commit ...>
+ */
+static VALUE rb_git_ref_target(VALUE self)
+{
+	git_reference *ref;
+
+	Data_Get_Struct(self, git_reference, ref);
+
+	if (git_reference_type(ref) == GIT_REF_OID) {
+		git_object *target;
+
+		rugged_exception_check(
+			git_object_lookup(&target, git_reference_owner(ref), git_reference_target(ref), GIT_OBJ_ANY)
+		);
+		return rugged_object_new(rugged_owner(self), target);
+	} else {
+		git_reference *target;
+
+		rugged_exception_check(
+			git_reference_lookup(&target, git_reference_owner(ref), git_reference_symbolic_target(ref))
+		);
+
+		return rugged_ref_new(rb_cRuggedReference, rugged_owner(self), target);
+	}
+}
+
+/*
+ *  call-seq:
+ *    reference.target_id -> id
+ *    reference.target_id -> ref_name
+ *
+ *  Return the target identifier of +reference+.
+ *
+ *  If +reference+ is a symbolic reference, it returns the canonical
+ *  name of the target reference.
+ *
+ *  If +reference+ is a direct reference, it returns the sha id of the target.
+ *
+ *    ref1.type #=> :symbolic
+ *    ref1.target_id #=> "refs/heads/master"
+ *
+ *    ref2.type #=> :direct
+ *    ref2.target_id #=> "de5ba987198bcf2518885f0fc1350e5172cded78"
+ */
+static VALUE rb_git_ref_target_id(VALUE self)
+{
+	git_reference *ref;
+	Data_Get_Struct(self, git_reference, ref);
+
+	if (git_reference_type(ref) == GIT_REF_OID) {
+		return rugged_create_oid(git_reference_target(ref));
+	} else {
+		return rb_str_new_utf8(git_reference_symbolic_target(ref));
+	}
+}
+
+/*
+ *  call-seq:
+ *    reference.type -> :symbolic or :direct
+ *
+ *  Return whether the reference is +:symbolic+ or +:direct+
+ */
+static VALUE rb_git_ref_type(VALUE self)
+{
+	git_reference *ref;
+	Data_Get_Struct(self, git_reference, ref);
+
+	switch (git_reference_type(ref)) {
+		case GIT_REF_OID:
+			return CSTR2SYM("direct");
+		case GIT_REF_SYMBOLIC:
+			return CSTR2SYM("symbolic");
+		default:
+			return Qnil;
+	}
+}
+
+/*
+ *  call-seq:
+ *    reference.name -> name
+ *    reference.canonical_name -> name
+ *
+ *  Returns the fully qualified name of the reference.
+ *
+ *  +name+ gets overwritten in subclasess like Rugged::Branch or Rugged::Tag
+ *  to return "nicer" names for presentational purposes, while +canonical_name+
+ *  is always supposed to return the fully qualified reference path.
+ *
+ *    reference.name #=> 'HEAD'
+ */
+static VALUE rb_git_ref_name(VALUE self)
+{
+	git_reference *ref;
+	Data_Get_Struct(self, git_reference, ref);
+	return rb_str_new_utf8(git_reference_name(ref));
+}
+
+/*
+ *  call-seq:
+ *    reference.resolve -> peeled_ref
+ *
+ *  Peel a symbolic reference to its target reference.
+ *
+ *    r1.type #=> :symbolic
+ *    r1.name #=> 'HEAD'
+ *    r1.target #=> 'refs/heads/master'
+ *
+ *    r2 = r1.resolve #=> #<Rugged::Reference:0x401b3948>
+ *    r2.target #=> '9d09060c850defbc7711d08b57def0d14e742f4e'
+ */
+static VALUE rb_git_ref_resolve(VALUE self)
+{
+	git_reference *ref;
+	git_reference *resolved;
+	int error;
+
+	Data_Get_Struct(self, git_reference, ref);
+
+	error = git_reference_resolve(&resolved, ref);
+	rugged_exception_check(error);
+
+	return rugged_ref_new(rb_cRuggedReference, rugged_owner(self), resolved);
+}
+
+static VALUE reflog_entry_new(const git_reflog_entry *entry)
+{
+	VALUE rb_entry = rb_hash_new();
+	const char *message;
+
+	rb_hash_aset(rb_entry,
+		CSTR2SYM("id_old"),
+		rugged_create_oid(git_reflog_entry_id_old(entry))
+	);
+
+	rb_hash_aset(rb_entry,
+		CSTR2SYM("id_new"),
+		rugged_create_oid(git_reflog_entry_id_new(entry))
+	);
+
+	rb_hash_aset(rb_entry,
+		CSTR2SYM("committer"),
+		rugged_signature_new(git_reflog_entry_committer(entry), NULL)
+	);
+
+	if ((message = git_reflog_entry_message(entry)) != NULL) {
+		rb_hash_aset(rb_entry, CSTR2SYM("message"), rb_str_new_utf8(message));
+	}
+
+	return rb_entry;
+}
+
+/*
+ *  call-seq:
+ *    reference.log -> [reflog_entry, ...]
+ *
+ *  Return an array with the log of all modifications to this reference
+ *
+ *  Each +reflog_entry+ is a hash with the following keys:
+ *
+ *  - +:id_old+: previous OID before the change
+ *  - +:id_new+: OID after the change
+ *  - +:committer+: author of the change
+ *  - +:message+: message for the change
+ *
+ *  Example:
+ *
+ *    reference.log #=> [
+ *    # {
+ *    #  :id_old => nil,
+ *    #  :id_new => '9d09060c850defbc7711d08b57def0d14e742f4e',
+ *    #  :committer => {:name => 'Vicent Marti', :email => {'vicent at github.com'}},
+ *    #  :message => 'created reference'
+ *    # }, ... ]
+ */
+static VALUE rb_git_reflog(VALUE self)
+{
+	git_reflog *reflog;
+	git_reference *ref;
+	int error;
+	VALUE rb_log;
+	size_t i, ref_count;
+
+	Data_Get_Struct(self, git_reference, ref);
+
+	error = git_reflog_read(&reflog, git_reference_owner(ref), git_reference_name(ref));
+	rugged_exception_check(error);
+
+	ref_count = git_reflog_entrycount(reflog);
+	rb_log = rb_ary_new2(ref_count);
+
+	for (i = 0; i < ref_count; ++i) {
+		const git_reflog_entry *entry =
+			git_reflog_entry_byindex(reflog, ref_count - i - 1);
+
+		rb_ary_push(rb_log, reflog_entry_new(entry));
+	}
+
+	git_reflog_free(reflog);
+	return rb_log;
+}
+
+/*
+ *  call-seq:
+ *    reference.log? -> true or false
+ *
+ *  Return +true+ if the reference has a reflog, +false+ otherwise.
+ */
+static VALUE rb_git_has_reflog(VALUE self)
+{
+	git_reference *ref;
+	git_repository *repo;
+
+	Data_Get_Struct(self, git_reference, ref);
+	repo = git_reference_owner(ref);
+
+	return git_reference_has_log(repo, git_reference_name(ref)) ? Qtrue : Qfalse;
+}
+
+/*
+ *  call-seq:
+ *    reference.branch? -> true or false
+ *
+ *  Returns +true+ if +reference+ is a local branch, false otherwise.
+ */
+static VALUE rb_git_ref_is_branch(VALUE self)
+{
+	git_reference *ref;
+	Data_Get_Struct(self, git_reference, ref);
+	return git_reference_is_branch(ref) ? Qtrue : Qfalse;
+}
+
+/*
+ *  call-seq:
+ *    reference.remote? -> true or false
+ *
+ *  Returns +true+ if +reference+ is a remote branch, false otherwise.
+ */
+static VALUE rb_git_ref_is_remote(VALUE self)
+{
+	git_reference *ref;
+	Data_Get_Struct(self, git_reference, ref);
+	return git_reference_is_remote(ref) ? Qtrue : Qfalse;
+}
+
+/*
+ *  call-seq:
+ *    reference.tag? -> true or false
+ *
+ *  Returns +true+ if +reference+ is a tag, false otherwise.
+ */
+static VALUE rb_git_ref_is_tag(VALUE self)
+{
+	git_reference *ref;
+	Data_Get_Struct(self, git_reference, ref);
+	return git_reference_is_tag(ref) ? Qtrue : Qfalse;
+}
+
+void Init_rugged_reference(void)
+{
+	rb_cRuggedReference = rb_define_class_under(rb_mRugged, "Reference", rb_cObject);
+
+	rb_define_singleton_method(rb_cRuggedReference, "valid_name?", rb_git_ref_valid_name, 1);
+
+	rb_define_method(rb_cRuggedReference, "target", rb_git_ref_target, 0);
+	rb_define_method(rb_cRuggedReference, "target_id", rb_git_ref_target_id, 0);
+	rb_define_method(rb_cRuggedReference, "peel", rb_git_ref_peel, 0);
+
+	rb_define_method(rb_cRuggedReference, "type", rb_git_ref_type, 0);
+
+	rb_define_method(rb_cRuggedReference, "name", rb_git_ref_name, 0);
+	rb_define_method(rb_cRuggedReference, "canonical_name", rb_git_ref_name, 0);
+
+	rb_define_method(rb_cRuggedReference, "resolve", rb_git_ref_resolve, 0);
+
+	rb_define_method(rb_cRuggedReference, "branch?", rb_git_ref_is_branch, 0);
+	rb_define_method(rb_cRuggedReference, "remote?", rb_git_ref_is_remote, 0);
+	rb_define_method(rb_cRuggedReference, "tag?", rb_git_ref_is_tag, 0);
+
+	rb_define_method(rb_cRuggedReference, "log", rb_git_reflog, 0);
+	rb_define_method(rb_cRuggedReference, "log?", rb_git_has_reflog, 0);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_reference_collection.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_reference_collection.c
new file mode 100755
index 0000000..f31e919
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_reference_collection.c
@@ -0,0 +1,446 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedRepo;
+extern VALUE rb_cRuggedReference;
+
+VALUE rb_cRuggedReferenceCollection;
+
+/*
+ *  call-seq:
+ *    ReferenceCollection.new(repo) -> refs
+ *
+ *  Creates and returns a new collection of references for the given +repo+.
+ */
+static VALUE rb_git_reference_collection_initialize(VALUE self, VALUE repo)
+{
+	rugged_set_owner(self, repo);
+	return self;
+}
+
+/*
+ *  call-seq:
+ *    references.create(name, oid, options = {}) -> new_ref
+ *    references.create(name, target, options = {}) -> new_ref
+ *
+ *  Create a symbolic or direct reference on the collection's +repository+ with the given +name+.
+ *
+ *  If the second argument is a valid OID, the reference will be created as direct.
+ *  Otherwise, it will be assumed the target is the name of another reference.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :force ::
+ *    Overwrites the reference with the given +name+, if it already exists,
+ *    instead of raising an exception.
+ *
+ *  If a reference with the given +name+ already exists and +:force+ is not +true+,
+ *  an exception will be raised.
+ */
+static VALUE rb_git_reference_collection_create(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_repo = rugged_owner(self), rb_name, rb_target, rb_options;
+	git_repository *repo;
+	git_reference *ref;
+	git_oid oid;
+	char *log_message = NULL;
+	int error, force = 0;
+
+	rb_scan_args(argc, argv, "20:", &rb_name, &rb_target, &rb_options);
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+	Check_Type(rb_name, T_STRING);
+	Check_Type(rb_target, T_STRING);
+
+	if (!NIL_P(rb_options)) {
+		VALUE rb_val = rb_hash_aref(rb_options, CSTR2SYM("message"));
+		if (!NIL_P(rb_val))
+			log_message = StringValueCStr(rb_val);
+
+		force = RTEST(rb_hash_aref(rb_options, CSTR2SYM("force")));
+	}
+
+	if (git_oid_fromstr(&oid, StringValueCStr(rb_target)) == GIT_OK) {
+		error = git_reference_create(
+			&ref, repo, StringValueCStr(rb_name), &oid, force, log_message);
+	} else {
+		error = git_reference_symbolic_create(
+			&ref, repo, StringValueCStr(rb_name), StringValueCStr(rb_target), force, log_message);
+	}
+
+	rugged_exception_check(error);
+
+	return rugged_ref_new(rb_cRuggedReference, rb_repo, ref);
+}
+
+/*
+ *  call-seq:
+ *    references[name] -> new_ref
+ *
+ *  Lookup a reference in the collection with the given +name+.
+ *
+ *  Returns a new Rugged::Reference object.
+ */
+static VALUE rb_git_reference_collection_aref(VALUE self, VALUE rb_name) {
+	VALUE rb_repo = rugged_owner(self);
+	git_repository *repo;
+	git_reference *ref;
+	int error;
+
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_reference_lookup(&ref, repo, StringValueCStr(rb_name));
+
+	if (error == GIT_ENOTFOUND)
+		return Qnil;
+
+	rugged_exception_check(error);
+
+	return rugged_ref_new(rb_cRuggedReference, rb_repo, ref);
+}
+
+static VALUE rb_git_reference_collection__each(int argc, VALUE *argv, VALUE self, int only_names)
+{
+	VALUE rb_glob, rb_repo = rugged_owner(self);
+	git_repository *repo;
+	git_reference_iterator *iter;
+	int error, exception = 0;
+
+	rb_scan_args(argc, argv, "01", &rb_glob);
+
+	if (!rb_block_given_p()) {
+		return rb_funcall(self,
+			rb_intern("to_enum"), 2,
+			only_names ? CSTR2SYM("each_name") : CSTR2SYM("each"),
+			rb_glob);
+	}
+
+	rugged_check_repo(rb_repo);
+
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	if (!NIL_P(rb_glob)) {
+		Check_Type(rb_glob, T_STRING);
+		error = git_reference_iterator_glob_new(&iter, repo, StringValueCStr(rb_glob));
+	} else {
+		error = git_reference_iterator_new(&iter, repo);
+	}
+
+	rugged_exception_check(error);
+
+	if (only_names) {
+		const char *ref_name;
+		while (!exception && (error = git_reference_next_name(&ref_name, iter)) == GIT_OK) {
+			rb_protect(rb_yield, rb_str_new_utf8(ref_name), &exception);
+		}
+	} else {
+		git_reference *ref;
+		while (!exception && (error = git_reference_next(&ref, iter)) == GIT_OK) {
+			rb_protect(rb_yield, rugged_ref_new(rb_cRuggedReference, rb_repo, ref), &exception);
+		}
+	}
+
+	git_reference_iterator_free(iter);
+
+	if (exception)
+		rb_jump_tag(exception);
+
+	if (error != GIT_ITEROVER)
+		rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    references.each(glob = nil) { |ref| block } -> nil
+ *    references.each(glob = nil) -> enumerator
+ *
+ *  Iterate through all the references in the collection's +repository+. Iteration
+ *  can be optionally filtered to the ones matching the given
+ *  +glob+, a standard Unix filename glob.
+ *
+ *  The given block will be called once with a Rugged::Reference
+ *  instance for each reference.
+ *
+ *  If no block is given, an enumerator will be returned.
+ */
+static VALUE rb_git_reference_collection_each(int argc, VALUE *argv, VALUE self)
+{
+	return rb_git_reference_collection__each(argc, argv, self, 0);
+}
+
+/*
+ *  call-seq:
+ *    references.each_name(glob = nil) { |ref_name| block } -> nil
+ *    references.each_name(glob = nil) -> enumerator
+ *
+ *  Iterate through all the reference names in the collection's +repository+. Iteration
+ *  can be optionally filtered to the ones matching the given
+ *  +glob+, a standard Unix filename glob.
+ *
+ *  The given block will be called once with the name of each reference.
+ *
+ *  If no block is given, an enumerator will be returned.
+ */
+static VALUE rb_git_reference_collection_each_name(int argc, VALUE *argv, VALUE self)
+{
+	return rb_git_reference_collection__each(argc, argv, self, 1);
+}
+
+/*
+ *  call-seq:
+ *    references.exist?(name) -> true or false
+ *    references.exists?(name) -> true or false
+ *
+ *  Check if a given reference exists with the given +name+.
+ */
+static VALUE rb_git_reference_collection_exist_p(VALUE self, VALUE rb_name_or_ref)
+{
+	VALUE rb_repo = rugged_owner(self);
+	git_repository *repo;
+	git_reference *ref;
+	int error;
+
+	if (rb_obj_is_kind_of(rb_name_or_ref, rb_cRuggedReference))
+		rb_name_or_ref = rb_funcall(rb_name_or_ref, rb_intern("canonical_name"), 0);
+
+	if (TYPE(rb_name_or_ref) != T_STRING)
+		rb_raise(rb_eTypeError, "Expecting a String or Rugged::Reference instance");
+
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_reference_lookup(&ref, repo, StringValueCStr(rb_name_or_ref));
+	git_reference_free(ref);
+
+	if (error == GIT_ENOTFOUND)
+		return Qfalse;
+	else
+		rugged_exception_check(error);
+
+	return Qtrue;
+}
+
+/*
+ *  call-seq:
+ *    references.rename(old_name, new_name, options = {}) -> new_ref
+ *    references.rename(ref, new_name, options = {}) -> new_ref
+ *
+ *  Change the name of a reference. If +force+ is +true+, any previously
+ *  existing references will be overwritten when renaming.
+ *
+ *  Return a new reference object with the new object
+ *
+ *    reference.name #=> 'refs/heads/master'
+ *    new_ref = references.rename(ref, 'refs/heads/development') #=> <Reference>
+ *    new_ref.name #=> 'refs/heads/development'
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :force ::
+ *    Overwrites the reference with the given +name+, if it already exists,
+ *    instead of raising an exception.
+ *
+ *  If a reference with the given +new_name+ already exists and +:force+ is not +true+,
+ *  an exception will be raised.
+ */
+static VALUE rb_git_reference_collection_rename(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_new_name, rb_name_or_ref, rb_options;
+	VALUE rb_repo = rugged_owner(self);
+	git_reference *ref, *out = NULL;
+	git_repository *repo;
+	char *log_message = NULL;
+	int error, force = 0;
+
+	rb_scan_args(argc, argv, "20:", &rb_name_or_ref, &rb_new_name, &rb_options);
+	Check_Type(rb_new_name, T_STRING);
+
+	if (rb_obj_is_kind_of(rb_name_or_ref, rb_cRuggedReference))
+		rb_name_or_ref = rb_funcall(rb_name_or_ref, rb_intern("canonical_name"), 0);
+
+	if (TYPE(rb_name_or_ref) != T_STRING)
+		rb_raise(rb_eTypeError, "Expecting a String or Rugged::Reference instance");
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	if (!NIL_P(rb_options)) {
+		VALUE rb_val = rb_hash_aref(rb_options, CSTR2SYM("message"));
+		if (!NIL_P(rb_val))
+			log_message = StringValueCStr(rb_val);
+
+		force = RTEST(rb_hash_aref(rb_options, CSTR2SYM("force")));
+	}
+
+	if ((error = git_reference_lookup(&ref, repo, StringValueCStr(rb_name_or_ref))) == GIT_OK)
+		error = git_reference_rename(&out, ref, StringValueCStr(rb_new_name), force, log_message);
+
+	git_reference_free(ref);
+
+	rugged_exception_check(error);
+
+	return rugged_ref_new(rb_cRuggedReference, rugged_owner(self), out);
+}
+
+/*
+ *  call-seq:
+ *    references.update(ref, oid)             -> new_ref
+ *    references.update(name, oid)            -> new_ref
+ *    references.update(ref, other_ref)       -> new_ref
+ *    references.update(name, other_ref_name) -> new_ref
+ *
+ *  Set the target of a reference. If +ref+ is a direct reference,
+ *  the new target must be a +String+ representing a SHA1 OID.
+ *
+ *  If +reference+ is symbolic, the new target must be a +String+ with
+ *  the name of another reference.
+ *
+ *  The original reference is unaltered; a new reference object is
+ *  returned with the new target, and the changes are persisted to
+ *  disk.
+ *
+ *    r1.type #=> :symbolic
+ *    references.update(r1, "refs/heads/master") #=> <Reference>
+ *
+ *    r2.type #=> :direct
+ *    references.update(r2, "de5ba987198bcf2518885f0fc1350e5172cded78") #=> <Reference>
+ */
+static VALUE rb_git_reference_collection_update(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_repo = rugged_owner(self), rb_name_or_ref, rb_target, rb_options;
+	git_repository *repo = NULL;
+	git_reference *ref = NULL, *out = NULL;
+	char *log_message = NULL;
+	int error;
+
+	rb_scan_args(argc, argv, "20:", &rb_name_or_ref, &rb_target, &rb_options);
+
+	if (rb_obj_is_kind_of(rb_name_or_ref, rb_cRuggedReference))
+		rb_name_or_ref = rb_funcall(rb_name_or_ref, rb_intern("canonical_name"), 0);
+
+	if (TYPE(rb_name_or_ref) != T_STRING)
+		rb_raise(rb_eTypeError, "Expecting a String or Rugged::Reference instance");
+
+	if (rb_obj_is_kind_of(rb_target, rb_cRuggedReference))
+		rb_target = rb_funcall(rb_target, rb_intern("canonical_name"), 0);
+
+	if (TYPE(rb_target) != T_STRING)
+		rb_raise(rb_eTypeError, "Expecting a String or Rugged::Reference instance");
+
+	if (!NIL_P(rb_options)) {
+		VALUE rb_val = rb_hash_aref(rb_options, CSTR2SYM("message"));
+		if (!NIL_P(rb_val))
+			log_message = StringValueCStr(rb_val);
+	}
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_reference_lookup(&ref, repo, StringValueCStr(rb_name_or_ref));
+	rugged_exception_check(error);
+
+	if (git_reference_type(ref) == GIT_REF_OID) {
+		git_oid target;
+
+		error = git_oid_fromstr(&target, StringValueCStr(rb_target));
+		if (error) goto cleanup;
+
+		error = git_reference_set_target(&out, ref, &target, log_message);
+	} else {
+		error = git_reference_symbolic_set_target(&out, ref, StringValueCStr(rb_target), log_message);
+	}
+
+cleanup:
+
+	git_reference_free(ref);
+	rugged_exception_check(error);
+
+	return rugged_ref_new(rb_cRuggedReference, rb_repo, out);
+}
+
+/*
+ *  call-seq:
+ *    references.delete(ref) -> nil
+ *    references.delete(name) -> nil
+ *
+ *  Delete specified reference.
+ *
+ *  If a Rugged::Reference object was passed, the object will become
+ *  invalidated and won't be able to be used for any other operations.
+ *
+ *    repo.references.delete("HEAD")
+ *    # Reference no longer exists on disk
+ */
+static VALUE rb_git_reference_collection_delete(VALUE self, VALUE rb_name_or_ref)
+{
+	VALUE rb_repo = rugged_owner(self);
+	git_reference *ref;
+	git_repository *repo;
+	int error;
+
+	if (rb_obj_is_kind_of(rb_name_or_ref, rb_cRuggedReference))
+		rb_name_or_ref = rb_funcall(rb_name_or_ref, rb_intern("canonical_name"), 0);
+
+	if (TYPE(rb_name_or_ref) != T_STRING)
+		rb_raise(rb_eTypeError, "Expecting a String or Rugged::Reference instance");
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_reference_lookup(&ref, repo, StringValueCStr(rb_name_or_ref));
+	rugged_exception_check(error);
+
+	error = git_reference_delete(ref);
+	git_reference_free(ref);
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+void Init_rugged_reference_collection(void)
+{
+	rb_cRuggedReferenceCollection = rb_define_class_under(rb_mRugged, "ReferenceCollection", rb_cObject);
+	rb_include_module(rb_cRuggedReferenceCollection, rb_mEnumerable);
+
+	rb_define_method(rb_cRuggedReferenceCollection, "initialize", rb_git_reference_collection_initialize, 1);
+
+	rb_define_method(rb_cRuggedReferenceCollection, "create",     rb_git_reference_collection_create, -1);
+	rb_define_method(rb_cRuggedReferenceCollection, "[]",         rb_git_reference_collection_aref, 1);
+
+	rb_define_method(rb_cRuggedReferenceCollection, "each",       rb_git_reference_collection_each, -1);
+	rb_define_method(rb_cRuggedReferenceCollection, "each_name",  rb_git_reference_collection_each_name, -1);
+
+	rb_define_method(rb_cRuggedReferenceCollection, "exist?",     rb_git_reference_collection_exist_p, 1);
+	rb_define_method(rb_cRuggedReferenceCollection, "exists?",    rb_git_reference_collection_exist_p, 1);
+
+	rb_define_method(rb_cRuggedReferenceCollection, "move",       rb_git_reference_collection_rename, -1);
+	rb_define_method(rb_cRuggedReferenceCollection, "rename",     rb_git_reference_collection_rename, -1);
+	rb_define_method(rb_cRuggedReferenceCollection, "update",     rb_git_reference_collection_update, -1);
+	rb_define_method(rb_cRuggedReferenceCollection, "delete",      rb_git_reference_collection_delete, 1);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_remote.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_remote.c
new file mode 100755
index 0000000..1ee79f4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_remote.c
@@ -0,0 +1,637 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedRepo;
+extern VALUE rb_eRuggedError;
+VALUE rb_cRuggedRemote;
+
+#define RUGGED_REMOTE_CALLBACKS_INIT {1, progress_cb, NULL, credentials_cb, NULL, transfer_progress_cb, update_tips_cb, NULL, NULL, push_update_reference_cb, NULL}
+
+static int progress_cb(const char *str, int len, void *data)
+{
+	struct rugged_remote_cb_payload *payload = data;
+	VALUE args = rb_ary_new2(2);
+
+	if (NIL_P(payload->progress))
+		return 0;
+
+	rb_ary_push(args, payload->progress);
+	rb_ary_push(args, rb_str_new(str, len));
+
+	rb_protect(rugged__block_yield_splat, args, &payload->exception);
+
+	return payload->exception ? GIT_ERROR : GIT_OK;
+}
+
+static int transfer_progress_cb(const git_transfer_progress *stats, void *data)
+{
+	struct rugged_remote_cb_payload *payload = data;
+	VALUE args = rb_ary_new2(5);
+
+	if (NIL_P(payload->transfer_progress))
+		return 0;
+
+	rb_ary_push(args, payload->transfer_progress);
+	rb_ary_push(args, UINT2NUM(stats->total_objects));
+	rb_ary_push(args, UINT2NUM(stats->indexed_objects));
+	rb_ary_push(args, UINT2NUM(stats->received_objects));
+	rb_ary_push(args, UINT2NUM(stats->local_objects));
+	rb_ary_push(args, UINT2NUM(stats->total_deltas));
+	rb_ary_push(args, UINT2NUM(stats->indexed_deltas));
+	rb_ary_push(args, INT2FIX(stats->received_bytes));
+
+	rb_protect(rugged__block_yield_splat, args, &payload->exception);
+
+	return payload->exception ? GIT_ERROR : GIT_OK;
+}
+
+static int push_update_reference_cb(const char *refname, const char *status, void *data) {
+	struct rugged_remote_cb_payload *payload = data;
+
+	if (status != NULL)
+		rb_hash_aset(payload->result, rb_str_new_utf8(refname), rb_str_new_utf8(status));
+
+	return GIT_OK;
+}
+
+static int update_tips_cb(const char *refname, const git_oid *src, const git_oid *dest, void *data)
+{
+	struct rugged_remote_cb_payload *payload = data;
+	VALUE args = rb_ary_new2(4);
+
+	if (NIL_P(payload->update_tips))
+		return 0;
+
+	rb_ary_push(args, payload->update_tips);
+	rb_ary_push(args, rb_str_new_utf8(refname));
+	rb_ary_push(args, git_oid_iszero(src) ? Qnil : rugged_create_oid(src));
+	rb_ary_push(args, git_oid_iszero(dest) ? Qnil : rugged_create_oid(dest));
+
+	rb_protect(rugged__block_yield_splat, args, &payload->exception);
+
+	return payload->exception ? GIT_ERROR : GIT_OK;
+}
+
+struct extract_cred_args
+{
+	VALUE rb_callback;
+	git_cred **cred;
+	const char *url;
+	const char *username_from_url;
+	unsigned int allowed_types;
+};
+
+static VALUE allowed_types_to_rb_ary(int allowed_types) {
+	VALUE rb_allowed_types = rb_ary_new();
+
+	if (allowed_types & GIT_CREDTYPE_USERPASS_PLAINTEXT)
+		rb_ary_push(rb_allowed_types, CSTR2SYM("plaintext"));
+
+	if (allowed_types & GIT_CREDTYPE_SSH_KEY)
+		rb_ary_push(rb_allowed_types, CSTR2SYM("ssh_key"));
+
+	if (allowed_types & GIT_CREDTYPE_DEFAULT)
+		rb_ary_push(rb_allowed_types, CSTR2SYM("default"));
+
+	return rb_allowed_types;
+}
+
+static VALUE extract_cred(VALUE data) {
+	struct extract_cred_args *args = (struct extract_cred_args*)data;
+	VALUE rb_url, rb_username_from_url, rb_cred;
+
+	rb_url = args->url ? rb_str_new2(args->url) : Qnil;
+	rb_username_from_url = args->username_from_url ? rb_str_new2(args->username_from_url) : Qnil;
+
+	rb_cred = rb_funcall(args->rb_callback, rb_intern("call"), 3,
+		rb_url, rb_username_from_url, allowed_types_to_rb_ary(args->allowed_types));
+
+	rugged_cred_extract(args->cred, args->allowed_types, rb_cred);
+
+	return Qnil;
+}
+
+static int credentials_cb(
+	git_cred **cred,
+	const char *url,
+	const char *username_from_url,
+	unsigned int allowed_types,
+	void *data)
+{
+	struct rugged_remote_cb_payload *payload = data;
+	struct extract_cred_args args = {
+		payload->credentials, cred, url, username_from_url, allowed_types
+	};
+
+	if (NIL_P(payload->credentials))
+		return GIT_PASSTHROUGH;
+
+	rb_protect(extract_cred, (VALUE)&args, &payload->exception);
+
+	return payload->exception ? GIT_ERROR : GIT_OK;
+}
+
+#define CALLABLE_OR_RAISE(ret, rb_options, name) \
+	do {							\
+		ret = rb_hash_aref(rb_options, CSTR2SYM(name)); \
+								\
+		if (!NIL_P(ret) && !rb_respond_to(ret, rb_intern("call"))) \
+			rb_raise(rb_eArgError, "Expected a Proc or an object that responds to #call (:" name " )."); \
+	} while (0);
+
+void rugged_remote_init_callbacks_and_payload_from_options(
+	VALUE rb_options,
+	git_remote_callbacks *callbacks,
+	struct rugged_remote_cb_payload *payload)
+{
+	git_remote_callbacks prefilled = RUGGED_REMOTE_CALLBACKS_INIT;
+
+	prefilled.payload = payload;
+	memcpy(callbacks, &prefilled, sizeof(git_remote_callbacks));
+
+	if (!NIL_P(rb_options)) {
+		CALLABLE_OR_RAISE(payload->update_tips, rb_options, "update_tips");
+		CALLABLE_OR_RAISE(payload->progress, rb_options, "progress");
+		CALLABLE_OR_RAISE(payload->transfer_progress, rb_options, "transfer_progress");
+		CALLABLE_OR_RAISE(payload->credentials, rb_options, "credentials");
+	}
+}
+
+static void rb_git_remote__free(git_remote *remote)
+{
+	git_remote_free(remote);
+}
+
+VALUE rugged_remote_new(VALUE owner, git_remote *remote)
+{
+	VALUE rb_remote;
+
+	rb_remote = Data_Wrap_Struct(rb_cRuggedRemote, NULL, &rb_git_remote__free, remote);
+	rugged_set_owner(rb_remote, owner);
+	return rb_remote;
+}
+
+static VALUE rugged_rhead_new(const git_remote_head *head)
+{
+	VALUE rb_head = rb_hash_new();
+
+	rb_hash_aset(rb_head, CSTR2SYM("local?"), head->local ? Qtrue : Qfalse);
+	rb_hash_aset(rb_head, CSTR2SYM("oid"), rugged_create_oid(&head->oid));
+	rb_hash_aset(rb_head, CSTR2SYM("loid"),
+			git_oid_iszero(&head->loid) ? Qnil : rugged_create_oid(&head->loid));
+	rb_hash_aset(rb_head, CSTR2SYM("name"), rb_str_new_utf8(head->name));
+
+	return rb_head;
+}
+
+/*
+ *  call-seq:
+ *    remote.ls(options = {}) -> an_enumerator
+ *    remote.ls(options = {}) { |remote_head_hash| block }
+ *
+ *  Connects +remote+ to list all references available along with their
+ *  associated commit ids.
+ *
+ *  The given block is called once for each remote head with a Hash containing the
+ *  following keys:
+ *
+ *  :local? ::
+ *    +true+ if the remote head is available locally, +false+ otherwise.
+ *
+ *  :oid ::
+ *    The id of the object the remote head is currently pointing to.
+ *
+ *  :loid ::
+ *    The id of the object the local copy of the remote head is currently
+ *    pointing to. Set to +nil+ if there is no local copy of the remote head.
+ *
+ *  :name ::
+ *    The fully qualified reference name of the remote head.
+ *
+ *  If no block is given, an enumerator will be returned.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :credentials ::
+ *    The credentials to use for the ls operation. Can be either an instance of one
+ *    of the Rugged::Credentials types, or a proc returning one of the former.
+ *    The proc will be called with the +url+, the +username+ from the url (if applicable) and
+ *    a list of applicable credential types.
+ */
+static VALUE rb_git_remote_ls(int argc, VALUE *argv, VALUE self)
+{
+	git_remote *remote;
+	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
+	const git_remote_head **heads;
+
+	struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
+
+	VALUE rb_options;
+
+	int error;
+	size_t heads_len, i;
+
+	Data_Get_Struct(self, git_remote, remote);
+
+	rb_scan_args(argc, argv, ":", &rb_options);
+
+	if (!rb_block_given_p())
+		return rb_funcall(self, rb_intern("to_enum"), 2, CSTR2SYM("ls"), rb_options);
+
+	rugged_remote_init_callbacks_and_payload_from_options(rb_options, &callbacks, &payload);
+
+	if ((error = git_remote_connect(remote, GIT_DIRECTION_FETCH, &callbacks)) ||
+	    (error = git_remote_ls(&heads, &heads_len, remote)))
+		goto cleanup;
+
+	for (i = 0; i < heads_len && !payload.exception; i++)
+		rb_protect(rb_yield, rugged_rhead_new(heads[i]), &payload.exception);
+
+	cleanup:
+
+	git_remote_disconnect(remote);
+
+	if (payload.exception)
+		rb_jump_tag(payload.exception);
+
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    remote.name() -> string
+ *
+ *	Returns the remote's name.
+ *
+ *	  remote.name #=> "origin"
+ */
+static VALUE rb_git_remote_name(VALUE self)
+{
+	git_remote *remote;
+	const char * name;
+	Data_Get_Struct(self, git_remote, remote);
+
+	name = git_remote_name(remote);
+
+	return name ? rb_str_new_utf8(name) : Qnil;
+}
+
+/*
+ *  call-seq:
+ *    remote.url() -> string
+ *
+ *  Returns the remote's url
+ *
+ *    remote.url #=> "git://github.com/libgit2/rugged.git"
+ */
+static VALUE rb_git_remote_url(VALUE self)
+{
+	git_remote *remote;
+	Data_Get_Struct(self, git_remote, remote);
+
+	return rb_str_new_utf8(git_remote_url(remote));
+}
+
+/*
+ *  call-seq:
+ *    remote.push_url() -> string or nil
+ *
+ *  Returns the remote's url for pushing or nil if no special url for
+ *  pushing is set.
+ *
+ *    remote.push_url #=> "git://github.com/libgit2/rugged.git"
+ */
+static VALUE rb_git_remote_push_url(VALUE self)
+{
+	git_remote *remote;
+	const char * push_url;
+
+	Data_Get_Struct(self, git_remote, remote);
+
+	push_url = git_remote_pushurl(remote);
+	return push_url ? rb_str_new_utf8(push_url) : Qnil;
+}
+
+/*
+ *  call-seq:
+ *    remote.push_url = url -> url
+ *
+ *  Sets the remote's url for pushing without persisting it in the config.
+ *  Existing connections will not be updated.
+ *
+ *    remote.push_url = 'git at github.com/libgit2/rugged.git' #=> "git at github.com/libgit2/rugged.git"
+ */
+static VALUE rb_git_remote_set_push_url(VALUE self, VALUE rb_url)
+{
+	VALUE rb_repo = rugged_owner(self);
+	git_remote *remote;
+	git_repository *repo;
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Check_Type(rb_url, T_STRING);
+	Data_Get_Struct(self, git_remote, remote);
+
+	rugged_exception_check(
+		git_remote_set_pushurl(repo, git_remote_name(remote), StringValueCStr(rb_url))
+	);
+
+	return rb_url;
+}
+
+static VALUE rb_git_remote_refspecs(VALUE self, git_direction direction)
+{
+	git_remote *remote;
+	int error = 0;
+	git_strarray refspecs;
+	VALUE rb_refspec_array;
+
+	Data_Get_Struct(self, git_remote, remote);
+
+	if (direction == GIT_DIRECTION_FETCH)
+		error = git_remote_get_fetch_refspecs(&refspecs, remote);
+	else
+		error = git_remote_get_push_refspecs(&refspecs, remote);
+
+	rugged_exception_check(error);
+
+	rb_refspec_array = rugged_strarray_to_rb_ary(&refspecs);
+	git_strarray_free(&refspecs);
+	return rb_refspec_array;
+}
+
+/*
+ *  call-seq:
+ *  remote.fetch_refspecs -> array
+ *
+ *  Get the remote's list of fetch refspecs as +array+.
+ */
+static VALUE rb_git_remote_fetch_refspecs(VALUE self)
+{
+	return rb_git_remote_refspecs(self, GIT_DIRECTION_FETCH);
+}
+
+/*
+ *  call-seq:
+ *  remote.push_refspecs -> array
+ *
+ *  Get the remote's list of push refspecs as +array+.
+ */
+static VALUE rb_git_remote_push_refspecs(VALUE self)
+{
+	return rb_git_remote_refspecs(self, GIT_DIRECTION_PUSH);
+}
+
+/*
+ *  call-seq:
+ *    remote.check_connection(direction, options = {}) -> boolean
+ *
+ *  Try to connect to the +remote+. Useful to simulate
+ *  <tt>git fetch --dry-run</tt> and <tt>git push --dry-run</tt>.
+ *
+ *  Returns +true+ if connection is successful, +false+ otherwise.
+ *
+ *  +direction+ must be either +:fetch+ or +:push+.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  +credentials+ ::
+ *    The credentials to use for the connection. Can be either an instance of
+ *    one of the Rugged::Credentials types, or a proc returning one of the
+ *    former.
+ *    The proc will be called with the +url+, the +username+ from the url (if
+ *    applicable) and a list of applicable credential types.
+ *
+ *  Example:
+ *
+ *    remote = repo.remotes["origin"]
+ *    success = remote.check_connection(:fetch)
+ *    raise Error("Unable to pull without credentials") unless success
+ */
+static VALUE rb_git_remote_check_connection(int argc, VALUE *argv, VALUE self)
+{
+	git_remote *remote;
+	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
+	struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
+	VALUE rb_direction, rb_options;
+	ID id_direction;
+	int error, direction;
+
+	Data_Get_Struct(self, git_remote, remote);
+	rb_scan_args(argc, argv, "01:", &rb_direction, &rb_options);
+
+	Check_Type(rb_direction, T_SYMBOL);
+	id_direction = SYM2ID(rb_direction);
+	if (id_direction == rb_intern("fetch"))
+		direction = GIT_DIRECTION_FETCH;
+	else if (id_direction == rb_intern("push"))
+		direction = GIT_DIRECTION_PUSH;
+	else
+		rb_raise(rb_eTypeError, "Invalid direction. Expected :fetch or :push");
+
+	rugged_remote_init_callbacks_and_payload_from_options(rb_options, &callbacks, &payload);
+
+	error = git_remote_connect(remote, direction, &callbacks);
+	git_remote_disconnect(remote);
+
+	if (payload.exception)
+		rb_jump_tag(payload.exception);
+
+	return error ? Qfalse : Qtrue;
+}
+
+/*
+ *  call-seq:
+ *    remote.fetch(refspecs = nil, options = {}) -> hash
+ *
+ *  Downloads new data from the remote for the given +refspecs+ and updates tips.
+ *
+ *  You can optionally pass in a single or multiple alternative +refspecs+ to use instead of the fetch
+ *  refspecs already configured for +remote+.
+ *
+ *  Returns a hash containing statistics for the fetch operation.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :credentials ::
+ *    The credentials to use for the fetch operation. Can be either an instance of one
+ *    of the Rugged::Credentials types, or a proc returning one of the former.
+ *    The proc will be called with the +url+, the +username+ from the url (if applicable) and
+ *    a list of applicable credential types.
+ *
+ *  :progress ::
+ *    A callback that will be executed with the textual progress received from the remote.
+ *    This is the text send over the progress side-band (ie. the "counting objects" output).
+ *
+ *  :transfer_progress ::
+ *    A callback that will be executed to report clone progress information. It will be passed
+ *    the amount of +total_objects+, +indexed_objects+, +received_objects+, +local_objects+,
+ *    +total_deltas+, +indexed_deltas+ and +received_bytes+.
+ *
+ *  :update_tips ::
+ *    A callback that will be executed each time a reference is updated locally. It will be
+ *    passed the +refname+, +old_oid+ and +new_oid+.
+ *
+ *  :message ::
+ *    The message to insert into the reflogs. Defaults to "fetch".
+ *
+ *  Example:
+ *
+ *    remote = Rugged::Remote.lookup(@repo, 'origin')
+ *    remote.fetch({
+ *      transfer_progress: lambda { |total_objects, indexed_objects, received_objects, local_objects, total_deltas, indexed_deltas, received_bytes|
+ *        # ...
+ *      }
+ *    })
+ */
+static VALUE rb_git_remote_fetch(int argc, VALUE *argv, VALUE self)
+{
+	git_remote *remote;
+	git_strarray refspecs;
+	git_fetch_options opts = GIT_FETCH_OPTIONS_INIT;
+	const git_transfer_progress *stats;
+	struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
+
+	char *log_message = NULL;
+	int error;
+
+	VALUE rb_options, rb_refspecs, rb_result = Qnil;
+
+	rb_scan_args(argc, argv, "01:", &rb_refspecs, &rb_options);
+
+	rugged_rb_ary_to_strarray(rb_refspecs, &refspecs);
+
+	Data_Get_Struct(self, git_remote, remote);
+
+	rugged_remote_init_callbacks_and_payload_from_options(rb_options, &opts.callbacks, &payload);
+
+	if (!NIL_P(rb_options)) {
+		VALUE rb_val = rb_hash_aref(rb_options, CSTR2SYM("message"));
+		if (!NIL_P(rb_val))
+			log_message = StringValueCStr(rb_val);
+	}
+
+	error = git_remote_fetch(remote, &refspecs, &opts, log_message);
+
+	xfree(refspecs.strings);
+
+	if (payload.exception)
+		rb_jump_tag(payload.exception);
+
+	rugged_exception_check(error);
+
+	stats = git_remote_stats(remote);
+
+	rb_result = rb_hash_new();
+	rb_hash_aset(rb_result, CSTR2SYM("total_objects"),    UINT2NUM(stats->total_objects));
+	rb_hash_aset(rb_result, CSTR2SYM("indexed_objects"),  UINT2NUM(stats->indexed_objects));
+	rb_hash_aset(rb_result, CSTR2SYM("received_objects"), UINT2NUM(stats->received_objects));
+	rb_hash_aset(rb_result, CSTR2SYM("local_objects"),    UINT2NUM(stats->local_objects));
+	rb_hash_aset(rb_result, CSTR2SYM("total_deltas"),     UINT2NUM(stats->total_deltas));
+	rb_hash_aset(rb_result, CSTR2SYM("indexed_deltas"),   UINT2NUM(stats->indexed_deltas));
+	rb_hash_aset(rb_result, CSTR2SYM("received_bytes"),   INT2FIX(stats->received_bytes));
+
+	return rb_result;
+}
+
+/*
+ *  call-seq:
+ *    remote.push(refspecs = nil, options = {}) -> hash
+ *
+ *  Pushes the given +refspecs+ to the given +remote+. Returns a hash that contains
+ *  key-value pairs that reflect pushed refs and error messages, if applicable.
+ *
+ *  You can optionally pass in an alternative list of +refspecs+ to use instead of the push
+ *  refspecs already configured for +remote+.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :credentials ::
+ *    The credentials to use for the push operation. Can be either an instance of one
+ *    of the Rugged::Credentials types, or a proc returning one of the former.
+ *    The proc will be called with the +url+, the +username+ from the url (if applicable) and
+ *    a list of applicable credential types.
+ *
+ *  :update_tips ::
+ *    A callback that will be executed each time a reference is updated remotely. It will be
+ *    passed the +refname+, +old_oid+ and +new_oid+.
+ *
+ *  Example:
+ *
+ *    remote = Rugged::Remote.lookup(@repo, 'origin')
+ *    remote.push(["refs/heads/master", ":refs/heads/to_be_deleted"])
+ */
+static VALUE rb_git_remote_push(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_refspecs, rb_options;
+
+	git_remote *remote;
+	git_strarray refspecs;
+	git_push_options opts = GIT_PUSH_OPTIONS_INIT;
+
+	int error = 0;
+
+	struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, rb_hash_new(), 0 };
+
+	rb_scan_args(argc, argv, "01:", &rb_refspecs, &rb_options);
+
+	rugged_rb_ary_to_strarray(rb_refspecs, &refspecs);
+
+	Data_Get_Struct(self, git_remote, remote);
+
+	rugged_remote_init_callbacks_and_payload_from_options(rb_options, &opts.callbacks, &payload);
+
+	error = git_remote_push(remote, &refspecs, &opts);
+
+	xfree(refspecs.strings);
+
+	if (payload.exception)
+		rb_jump_tag(payload.exception);
+
+	rugged_exception_check(error);
+
+	return payload.result;
+}
+
+void Init_rugged_remote(void)
+{
+	rb_cRuggedRemote = rb_define_class_under(rb_mRugged, "Remote", rb_cObject);
+
+	rb_define_method(rb_cRuggedRemote, "name", rb_git_remote_name, 0);
+	rb_define_method(rb_cRuggedRemote, "url", rb_git_remote_url, 0);
+	rb_define_method(rb_cRuggedRemote, "push_url", rb_git_remote_push_url, 0);
+	rb_define_method(rb_cRuggedRemote, "push_url=", rb_git_remote_set_push_url, 1);
+	rb_define_method(rb_cRuggedRemote, "fetch_refspecs", rb_git_remote_fetch_refspecs, 0);
+	rb_define_method(rb_cRuggedRemote, "push_refspecs", rb_git_remote_push_refspecs, 0);
+	rb_define_method(rb_cRuggedRemote, "ls", rb_git_remote_ls, -1);
+	rb_define_method(rb_cRuggedRemote, "check_connection", rb_git_remote_check_connection, -1);
+	rb_define_method(rb_cRuggedRemote, "fetch", rb_git_remote_fetch, -1);
+	rb_define_method(rb_cRuggedRemote, "push", rb_git_remote_push, -1);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_remote_collection.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_remote_collection.c
new file mode 100755
index 0000000..00e19dd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_remote_collection.c
@@ -0,0 +1,457 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedRepo;
+extern VALUE rb_eRuggedError;
+extern VALUE rb_cRuggedRemote;
+VALUE rb_cRuggedRemoteCollection;
+
+/*
+ *  call-seq:
+ *    RemoteCollection.new(repo) -> remotes
+ *
+ *  Creates and returns a new collection of remotes for the given +repo+.
+ */
+static VALUE rb_git_remote_collection_initialize(VALUE self, VALUE repo)
+{
+	rugged_set_owner(self, repo);
+	return self;
+}
+
+/*
+ *  call-seq:
+ *    remotes.create_anonymous(url) -> remote
+ *
+ *  Return a new remote with +url+ in +repository+ , the remote is not persisted:
+ *  - +url+: a valid remote url
+ *
+ *  Returns a new Rugged::Remote object.
+ *
+ *    @repo.remotes.create_anonymous('git://github.com/libgit2/libgit2.git') #=> #<Rugged::Remote:0x00000001fbfa80>
+ */
+static VALUE rb_git_remote_collection_create_anonymous(VALUE self, VALUE rb_url)
+{
+	git_remote *remote;
+	git_repository *repo;
+	int error;
+
+	VALUE rb_repo = rugged_owner(self);
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Check_Type(rb_url, T_STRING);
+
+	error = git_remote_create_anonymous(
+			&remote,
+			repo,
+			StringValueCStr(rb_url));
+
+	rugged_exception_check(error);
+
+	return rugged_remote_new(rb_repo, remote);
+}
+
+/*
+ *  call-seq:
+ *     remotes.create(name, url) -> remote
+ *
+ *  Add a new remote with +name+ and +url+ to +repository+
+ *  - +url+: a valid remote url
+ *  - +name+: a valid remote name
+ *
+ *  Returns a new Rugged::Remote object.
+ *
+ *    @repo.remotes.create('origin', 'git://github.com/libgit2/rugged.git') #=> #<Rugged::Remote:0x00000001fbfa80>
+ */
+static VALUE rb_git_remote_collection_create(VALUE self, VALUE rb_name, VALUE rb_url)
+{
+	git_remote *remote;
+	git_repository *repo;
+	int error;
+
+	VALUE rb_repo = rugged_owner(self);
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Check_Type(rb_name, T_STRING);
+	Check_Type(rb_url, T_STRING);
+
+	error = git_remote_create(
+			&remote,
+			repo,
+			StringValueCStr(rb_name),
+			StringValueCStr(rb_url));
+
+	rugged_exception_check(error);
+
+	return rugged_remote_new(rb_repo, remote);
+}
+
+/*
+ *  call-seq:
+ *    remotes[name] -> remote or nil
+ *
+ *  Lookup a remote in the collection with the given +name+.
+ *
+ *  Returns a new Rugged::Remote object or +nil+ if the
+ *  remote doesn't exist.
+ *
+ *    @repo.remotes["origin"] #=> #<Rugged::Remote:0x00000001fbfa80>
+ */
+static VALUE rb_git_remote_collection_aref(VALUE self, VALUE rb_name)
+{
+	git_remote *remote;
+	git_repository *repo;
+	int error;
+
+	VALUE rb_repo = rugged_owner(self);
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Check_Type(rb_name, T_STRING);
+
+	error = git_remote_lookup(&remote, repo, StringValueCStr(rb_name));
+
+	if (error == GIT_ENOTFOUND)
+		return Qnil;
+
+	rugged_exception_check(error);
+
+	return rugged_remote_new(rb_repo, remote);
+}
+
+static VALUE rb_git_remote_collection__each(VALUE self, int only_names)
+{
+	git_repository *repo;
+	git_strarray remotes;
+	size_t i;
+	int error = 0;
+	int exception = 0;
+
+	VALUE rb_repo;
+
+	if (!rb_block_given_p()) {
+		if (only_names)
+			return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("each_name"));
+		else
+			return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("each"));
+	}
+
+	rb_repo = rugged_owner(self);
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_remote_list(&remotes, repo);
+	rugged_exception_check(error);
+
+	if (only_names) {
+		for (i = 0; !exception && i < remotes.count; ++i) {
+			rb_protect(rb_yield, rb_str_new_utf8(remotes.strings[i]), &exception);
+		}
+	} else {
+		for (i = 0; !exception && !error && i < remotes.count; ++i) {
+			git_remote *remote;
+
+			if (!(error = git_remote_lookup(&remote, repo, remotes.strings[i])))
+				rb_protect(rb_yield, rugged_remote_new(rb_repo, remote), &exception);
+		}
+	}
+
+	git_strarray_free(&remotes);
+
+	if (exception)
+		rb_jump_tag(exception);
+
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+
+/*
+ *  call-seq:
+ *    remotes.each { |remote| } -> nil
+ *    remotes.each -> enumerator
+ *
+ *  Iterate through all the remotes in the collection's +repository+.
+ *
+ *  The given block will be called once with a Rugged::Remote
+ *  instance for each remote.
+ *
+ *  If no block is given, an enumerator will be returned.
+ */
+static VALUE rb_git_remote_collection_each(VALUE self)
+{
+	return rb_git_remote_collection__each(self, 0);
+}
+
+/*
+ *  call-seq:
+ *    remotes.each_name { |str| } -> nil
+ *    remotes.each_name -> enumerator
+ *
+ *  Iterate through all the remote names in the collection's +repository+.
+ *
+ *  The given block will be called once with the name of each remote.
+ *
+ *  If no block is given, an enumerator will be returned.
+ */
+static VALUE rb_git_remote_collection_each_name(VALUE self)
+{
+	return rb_git_remote_collection__each(self, 1);
+}
+
+/*
+ *  call-seq:
+ *    remotes.rename(remote, new_name) { |str| }  -> remote
+ *    remotes.rename(name, new_name) { |str| } -> remote
+ *
+ *  Renames a remote.
+ *
+ *  All remote-tracking branches and configuration settings
+ *  for the remote are updated.
+ *
+ *  Non-default refspecs cannot be renamed automatically and will be
+ *  yielded to the given block.
+ *
+ *  Anonymous, in-memory remotes created through
+ *  +ReferenceCollection#create_anonymous+ can not be given a name through
+ *  this method.
+ *
+ *  Returns a new Rugged::Remote object with the new name.
+ */
+static VALUE rb_git_remote_collection_rename(VALUE self, VALUE rb_name_or_remote, VALUE rb_new_name)
+{
+	VALUE rb_repo = rugged_owner(self);
+	git_repository *repo;
+	size_t i;
+	int error, exception;
+	git_strarray problems;
+
+	if (!rb_block_given_p())
+		rb_raise(rb_eArgError, "Rugged::RemoteCollection#rename must be called with a block");
+
+	Check_Type(rb_new_name, T_STRING);
+
+	if (rb_obj_is_kind_of(rb_name_or_remote, rb_cRuggedRemote))
+		rb_name_or_remote = rb_funcall(rb_name_or_remote, rb_intern("name"), 0);
+
+	if (TYPE(rb_name_or_remote) != T_STRING)
+		rb_raise(rb_eTypeError, "Expecting a String or Rugged::Remote instance");
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_remote_rename(&problems, repo, StringValueCStr(rb_name_or_remote), StringValueCStr(rb_new_name));
+	rugged_exception_check(error);
+
+	for (i = exception = 0; !exception && i < problems.count; ++i) {
+		rb_protect(rb_yield, rb_str_new_utf8(problems.strings[i]), &exception);
+	}
+
+	git_strarray_free(&problems);
+
+	if (exception)
+		rb_jump_tag(exception);
+
+	return rb_git_remote_collection_aref(self, rb_new_name);
+}
+
+/*
+ *  call-seq:
+ *    remotes.delete(remote) -> nil
+ *    remotes.delete(name) -> nil
+ *
+ *  Delete the specified remote.
+ *
+ *    repo.remotes.delete("origin")
+ *    # Remote no longer exists in the configuration.
+ */
+static VALUE rb_git_remote_collection_delete(VALUE self, VALUE rb_name_or_remote)
+{
+	VALUE rb_repo = rugged_owner(self);
+	git_repository *repo;
+
+	if (rb_obj_is_kind_of(rb_name_or_remote, rb_cRuggedRemote))
+		rb_name_or_remote = rb_funcall(rb_name_or_remote, rb_intern("name"), 0);
+
+	if (TYPE(rb_name_or_remote) != T_STRING)
+		rb_raise(rb_eTypeError, "Expecting a String or Rugged::Remote instance");
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	rugged_exception_check(
+		git_remote_delete(repo, StringValueCStr(rb_name_or_remote))
+	);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    remotes.set_url(remote, url) -> nil
+ *    remotes.set_url(name, url) -> nil
+ *
+ *  Sets the remote's url in the configuration.
+ *  Rugged::Remote objects already in memory will not be affected.
+ *
+ *    repo.remotes.set_url("origin", 'git://github.com/libgit2/rugged.git')
+ */
+static VALUE rb_git_remote_collection_set_url(VALUE self, VALUE rb_name_or_remote, VALUE rb_url)
+{
+	VALUE rb_repo = rugged_owner(self);
+	git_repository *repo;
+
+	if (rb_obj_is_kind_of(rb_name_or_remote, rb_cRuggedRemote))
+		rb_name_or_remote = rb_funcall(rb_name_or_remote, rb_intern("name"), 0);
+
+	if (TYPE(rb_name_or_remote) != T_STRING)
+		rb_raise(rb_eTypeError, "Expecting a String or Rugged::Remote instance");
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Check_Type(rb_url, T_STRING);
+
+	rugged_exception_check(
+		git_remote_set_url(repo, StringValueCStr(rb_name_or_remote), StringValueCStr(rb_url))
+	);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    remotes.set_push_url(remote, url) -> nil
+ *    remotes.set_push_url(name, url) -> nil
+ *
+ *  Sets the remote's url for pushing in the configuration.
+ *  Rugged::Remote objects already in memory will not be affected.
+ *
+ *    repo.remotes.set_push_url("origin", 'git://github.com/libgit2/rugged.git')
+ */
+static VALUE rb_git_remote_collection_set_push_url(VALUE self, VALUE rb_name_or_remote, VALUE rb_url)
+{
+	VALUE rb_repo = rugged_owner(self);
+	git_repository *repo;
+
+	if (rb_obj_is_kind_of(rb_name_or_remote, rb_cRuggedRemote))
+		rb_name_or_remote = rb_funcall(rb_name_or_remote, rb_intern("name"), 0);
+
+	if (TYPE(rb_name_or_remote) != T_STRING)
+		rb_raise(rb_eTypeError, "Expecting a String or Rugged::Remote instance");
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Check_Type(rb_url, T_STRING);
+
+	rugged_exception_check(
+		git_remote_set_pushurl(repo, StringValueCStr(rb_name_or_remote), StringValueCStr(rb_url))
+	);
+
+	return Qnil;
+}
+
+static VALUE rb_git_remote_collection_add_refspec(VALUE self, VALUE rb_name_or_remote, VALUE rb_refspec, git_direction direction)
+{
+	VALUE rb_repo = rugged_owner(self);
+	git_repository *repo;
+	int error = 0;
+
+	if (rb_obj_is_kind_of(rb_name_or_remote, rb_cRuggedRemote))
+		rb_name_or_remote = rb_funcall(rb_name_or_remote, rb_intern("name"), 0);
+
+	if (TYPE(rb_name_or_remote) != T_STRING)
+		rb_raise(rb_eTypeError, "Expecting a String or Rugged::Remote instance");
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Check_Type(rb_refspec, T_STRING);
+
+	if (direction == GIT_DIRECTION_FETCH)
+		error = git_remote_add_fetch(repo, StringValueCStr(rb_name_or_remote), StringValueCStr(rb_refspec));
+	else
+		error = git_remote_add_push(repo, StringValueCStr(rb_name_or_remote), StringValueCStr(rb_refspec));
+
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    remotes.add_fetch_refspec(remote, refspec) -> nil
+ *    remotes.add_fetch_refspec(name, refspec) -> nil
+ *
+ *  Add a fetch refspec to the remote.
+ */
+static VALUE rb_git_remote_collection_add_fetch_refspec(VALUE self, VALUE rb_name_or_remote, VALUE rb_refspec)
+{
+	return rb_git_remote_collection_add_refspec(self, rb_name_or_remote, rb_refspec, GIT_DIRECTION_FETCH);
+}
+
+/*
+ *  call-seq:
+ *    remotes.add_push_refspec(remote, refspec) -> nil
+ *    remotes.add_push_refspec(name, refspec) -> nil
+ *
+ *  Add a push refspec to the remote.
+ */
+static VALUE rb_git_remote_collection_add_push_refspec(VALUE self, VALUE rb_name_or_remote, VALUE rb_refspec)
+{
+	return rb_git_remote_collection_add_refspec(self, rb_name_or_remote, rb_refspec, GIT_DIRECTION_PUSH);
+}
+
+void Init_rugged_remote_collection(void)
+{
+	rb_cRuggedRemoteCollection = rb_define_class_under(rb_mRugged, "RemoteCollection", rb_cObject);
+	rb_include_module(rb_cRuggedRemoteCollection, rb_mEnumerable);
+
+	rb_define_method(rb_cRuggedRemoteCollection, "initialize",        rb_git_remote_collection_initialize, 1);
+
+	rb_define_method(rb_cRuggedRemoteCollection, "[]",                rb_git_remote_collection_aref, 1);
+
+	rb_define_method(rb_cRuggedRemoteCollection, "create",            rb_git_remote_collection_create, 2);
+	rb_define_method(rb_cRuggedRemoteCollection, "create_anonymous",  rb_git_remote_collection_create_anonymous, 1);
+
+	rb_define_method(rb_cRuggedRemoteCollection, "each",              rb_git_remote_collection_each, 0);
+	rb_define_method(rb_cRuggedRemoteCollection, "each_name",         rb_git_remote_collection_each_name, 0);
+
+	rb_define_method(rb_cRuggedRemoteCollection, "set_url",           rb_git_remote_collection_set_url, 2);
+	rb_define_method(rb_cRuggedRemoteCollection, "set_push_url",      rb_git_remote_collection_set_push_url, 2);
+
+	rb_define_method(rb_cRuggedRemoteCollection, "add_push_refspec",  rb_git_remote_collection_add_push_refspec, 2);
+	rb_define_method(rb_cRuggedRemoteCollection, "add_fetch_refspec", rb_git_remote_collection_add_fetch_refspec, 2);
+
+	rb_define_method(rb_cRuggedRemoteCollection, "rename",            rb_git_remote_collection_rename, 2);
+	rb_define_method(rb_cRuggedRemoteCollection, "delete",            rb_git_remote_collection_delete, 1);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_repo.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_repo.c
new file mode 100755
index 0000000..15a086c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_repo.c
@@ -0,0 +1,2545 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+#include <git2/sys/repository.h>
+#include <git2/sys/odb_backend.h>
+#include <git2/sys/refdb_backend.h>
+#include <git2/refs.h>
+
+extern VALUE rb_mRugged;
+extern VALUE rb_eRuggedError;
+extern VALUE rb_cRuggedIndex;
+extern VALUE rb_cRuggedConfig;
+extern VALUE rb_cRuggedBackend;
+extern VALUE rb_cRuggedRemote;
+extern VALUE rb_cRuggedCommit;
+extern VALUE rb_cRuggedTag;
+extern VALUE rb_cRuggedTree;
+extern VALUE rb_cRuggedReference;
+extern VALUE rb_cRuggedBackend;
+
+extern VALUE rb_cRuggedCredPlaintext;
+extern VALUE rb_cRuggedCredSshKey;
+extern VALUE rb_cRuggedCredDefault;
+
+VALUE rb_cRuggedRepo;
+VALUE rb_cRuggedOdbObject;
+
+static ID id_call;
+
+/*
+ *  call-seq:
+ *    odb_obj.oid -> hex_oid
+ *
+ *  Return the Object ID (a 40 character SHA1 hash) for this raw
+ *  object.
+ *
+ *    odb_obj.oid #=> "d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f"
+ */
+static VALUE rb_git_odbobj_oid(VALUE self)
+{
+	git_odb_object *obj;
+	Data_Get_Struct(self, git_odb_object, obj);
+	return rugged_create_oid(git_odb_object_id(obj));
+}
+
+/*
+ *  call-seq:
+ *    odb_obj.data -> buffer
+ *
+ *  Return an ASCII buffer with the raw bytes that form the Git object.
+ *
+ *    odb_obj.data #=> "tree 87ebee8367f9cc5ac04858b3bd5610ca74f04df9\n"
+ *                 #=> "parent 68d041ee999cb07c6496fbdd4f384095de6ca9e1\n"
+ *                 #=> "author Vicent Martí <tanoku at gmail.com> 1326863045 -0800\n"
+ *                 #=> ...
+ */
+static VALUE rb_git_odbobj_data(VALUE self)
+{
+	git_odb_object *obj;
+	Data_Get_Struct(self, git_odb_object, obj);
+	return rb_str_new(git_odb_object_data(obj), git_odb_object_size(obj));
+}
+
+/*
+ *  call-seq:
+ *    odb_obj.size -> size
+ *
+ *  Return the size in bytes of the Git object after decompression. This is
+ *  also the size of the +obj.data+ buffer.
+ *
+ *    odb_obj.size #=> 231
+ */
+static VALUE rb_git_odbobj_size(VALUE self)
+{
+	git_odb_object *obj;
+	Data_Get_Struct(self, git_odb_object, obj);
+	return INT2FIX(git_odb_object_size(obj));
+}
+
+/*
+ *  call-seq:
+ *    odb_obj.type -> Symbol
+ *
+ *  Return a Ruby symbol representing the basic Git type of this object.
+ *  Possible values are +:tree+, +:blob+, +:commit+ and +:tag+.
+ *
+ *    odb_obj.type #=> :tag
+ */
+static VALUE rb_git_odbobj_type(VALUE self)
+{
+	git_odb_object *obj;
+	Data_Get_Struct(self, git_odb_object, obj);
+	return rugged_otype_new(git_odb_object_type(obj));
+}
+
+void rb_git__odbobj_free(void *obj)
+{
+	git_odb_object_free((git_odb_object *)obj);
+}
+
+VALUE rugged_raw_read(git_repository *repo, const git_oid *oid)
+{
+	git_odb *odb;
+	git_odb_object *obj;
+
+	int error;
+
+	error = git_repository_odb(&odb, repo);
+	rugged_exception_check(error);
+
+	error = git_odb_read(&obj, odb, oid);
+	git_odb_free(odb);
+	rugged_exception_check(error);
+
+	return Data_Wrap_Struct(rb_cRuggedOdbObject, NULL, rb_git__odbobj_free, obj);
+}
+
+void rb_git_repo__free(git_repository *repo)
+{
+	git_repository_free(repo);
+}
+
+VALUE rugged_repo_new(VALUE klass, git_repository *repo)
+{
+	VALUE rb_repo = Data_Wrap_Struct(klass, NULL, &rb_git_repo__free, repo);
+
+#ifdef HAVE_RUBY_ENCODING_H
+	/* TODO: set this properly */
+	rb_iv_set(rb_repo, "@encoding",
+		rb_enc_from_encoding(rb_filesystem_encoding()));
+#endif
+
+	rb_iv_set(rb_repo, "@config", Qnil);
+	rb_iv_set(rb_repo, "@index", Qnil);
+
+	return rb_repo;
+}
+
+static void load_alternates(git_repository *repo, VALUE rb_alternates)
+{
+	git_odb *odb = NULL;
+	int i, error;
+
+	if (NIL_P(rb_alternates))
+		return;
+
+	Check_Type(rb_alternates, T_ARRAY);
+
+	if (RARRAY_LEN(rb_alternates) == 0)
+		return;
+
+	for (i = 0; i < RARRAY_LEN(rb_alternates); ++i)
+		Check_Type(rb_ary_entry(rb_alternates, i), T_STRING);
+
+	error = git_repository_odb(&odb, repo);
+	rugged_exception_check(error);
+
+	for (i = 0; !error && i < RARRAY_LEN(rb_alternates); ++i) {
+		VALUE alt = rb_ary_entry(rb_alternates, i);
+		error = git_odb_add_disk_alternate(odb, StringValueCStr(alt));
+	}
+
+	git_odb_free(odb);
+	rugged_exception_check(error);
+}
+
+static void rugged_repo_new_with_backend(git_repository **repo, VALUE rb_path, VALUE rb_backend)
+{
+	char *path;
+
+	git_odb *odb = NULL;
+	git_odb_backend *odb_backend = NULL;
+	git_refdb *refdb = NULL;
+	git_refdb_backend *refdb_backend = NULL;
+	git_reference *head = NULL;
+	rugged_backend *backend;
+
+	int error = 0;
+
+	Check_Type(rb_path, T_STRING);
+	path = StringValueCStr(rb_path);
+
+	if (rb_obj_is_kind_of(rb_backend, rb_cRuggedBackend) == Qfalse) {
+		rb_raise(rb_eRuggedError, "Backend must be an instance of Rugged::Backend");
+	}
+
+	Data_Get_Struct(rb_backend, rugged_backend, backend);
+
+	error = git_odb_new(&odb);
+	if (error) goto cleanup;
+
+	error = backend->odb_backend(&odb_backend, backend, path);
+	if (error) goto cleanup;
+
+	error = git_odb_add_backend(odb, odb_backend, 1);
+	if (error) goto cleanup;
+
+	error = git_repository_wrap_odb(repo, odb);
+	if (error) goto cleanup;
+
+	error = git_refdb_new(&refdb, *repo);
+	if (error) goto cleanup;
+
+	error = backend->refdb_backend(&refdb_backend, backend, path);
+	if (error) goto cleanup;
+
+	error = git_refdb_set_backend(refdb, refdb_backend);
+	if (error) goto cleanup;
+
+	git_repository_set_refdb(*repo, refdb);
+
+	error = git_reference_lookup(&head, *repo, "HEAD");
+
+	if (error == GIT_ENOTFOUND) {
+		giterr_clear();
+		error = git_reference_symbolic_create(&head, *repo, "HEAD", "refs/heads/master", 0, NULL);
+	}
+
+	if (!error) {
+		git_reference_free(head);
+		return;
+	}
+
+cleanup:
+	git_repository_free(*repo);
+	git_odb_free(odb);
+	git_refdb_free(refdb);
+
+	if (odb_backend != NULL) odb_backend->free(odb_backend);
+	if (refdb_backend != NULL) refdb_backend->free(refdb_backend);
+
+	rugged_exception_check(error);
+}
+
+/*
+ *  call-seq:
+ *    Repository.bare(path[, alternates]) -> repository OR
+ *    Repository.bare(path[, options]) -> repository
+ *
+ *  Open a bare Git repository at +path+ and return a +Repository+
+ *  object representing it.
+ *
+ *  This is faster than Rugged::Repository.new, as it won't attempt to perform
+ *  any +.git+ directory discovery, won't try to load the config options to
+ *  determine whether the repository is bare and won't try to load the workdir.
+ *
+ *  Optionally, you can pass a list of alternate object folders or an options Hash.
+ *
+ *    Rugged::Repository.bare(path, ['./other/repo/.git/objects'])
+ *    Rugged::Repository.bare(path, opts)
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :backend ::
+ *    A Rugged::Backend instance
+ *  :alternates ::
+ *    A list of alternate object folders.
+ *    Rugged::Repository.bare(path, :alternates => ['./other/repo/.git/objects'])
+ */
+static VALUE rb_git_repo_open_bare(int argc, VALUE *argv, VALUE klass)
+{
+	git_repository *repo = NULL;
+	int error = 0;
+	VALUE rb_path, rb_options, rb_alternates = 0;
+
+	rb_scan_args(argc, argv, "11", &rb_path, &rb_options);
+
+	if (!NIL_P(rb_options) && TYPE(rb_options) == T_ARRAY)
+		rb_alternates = rb_options;
+
+	if (!NIL_P(rb_options) && TYPE(rb_options) == T_HASH) {
+		/* Check for `:backend` */
+		VALUE rb_backend = rb_hash_aref(rb_options, CSTR2SYM("backend"));
+
+		if (!NIL_P(rb_backend)) {
+			rugged_repo_new_with_backend(&repo, rb_path, rb_backend);
+		}
+
+		/* Check for `:alternates` */
+		rb_alternates = rb_hash_aref(rb_options, CSTR2SYM("alternates"));
+	}
+
+	if (!repo) {
+		Check_Type(rb_path, T_STRING);
+
+		error = git_repository_open_bare(&repo, StringValueCStr(rb_path));
+		rugged_exception_check(error);
+	}
+
+	if (rb_alternates) {
+		load_alternates(repo, rb_alternates);
+	}
+
+	return rugged_repo_new(klass, repo);
+}
+
+/*
+ *  call-seq:
+ *    Repository.new(path, options = {}) -> repository
+ *
+ *  Open a Git repository in the given +path+ and return a +Repository+ object
+ *  representing it. An exception will be thrown if +path+ doesn't point to a
+ *  valid repository. If you need to create a repository from scratch, use
+ *  Rugged::Repository.init_at instead.
+ *
+ *  The +path+ must point to either the actual folder (+.git+) of a Git repository,
+ *  or to the directorly that contains the +.git+ folder.
+ *
+ *  See also Rugged::Repository.discover and Rugged::Repository.bare.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :alternates ::
+ *    A list of alternate object folders.
+ *
+ *  Examples:
+ *
+ *    Rugged::Repository.new('test/.git') #=> #<Rugged::Repository:0x108849488>
+ *    Rugged::Repository.new(path, :alternates => ['./other/repo/.git/objects'])
+ */
+static VALUE rb_git_repo_new(int argc, VALUE *argv, VALUE klass)
+{
+	git_repository *repo;
+	int error = 0;
+	VALUE rb_path, rb_options;
+
+	rb_scan_args(argc, argv, "10:", &rb_path, &rb_options);
+	Check_Type(rb_path, T_STRING);
+
+	error = git_repository_open(&repo, StringValueCStr(rb_path));
+	rugged_exception_check(error);
+
+	if (!NIL_P(rb_options)) {
+		/* Check for `:alternates` */
+		load_alternates(repo, rb_hash_aref(rb_options, CSTR2SYM("alternates")));
+	}
+
+	return rugged_repo_new(klass, repo);
+}
+
+/*
+ *  call-seq:
+ *    Repository.init_at(path, is_bare = false, opts = {}) -> repository
+ *
+ *  Initialize a Git repository in +path+. This implies creating all the
+ *  necessary files on the FS, or re-initializing an already existing
+ *  repository if the files have already been created.
+ *
+ *  The +is_bare+ (optional, defaults to false) attribute specifies whether
+ *  the Repository should be created on disk as bare or not.
+ *  Bare repositories have no working directory and are created in the root
+ *  of +path+. Non-bare repositories are created in a +.git+ folder and
+ *  use +path+ as working directory.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :backend ::
+ *    A Rugged::Backend instance
+ *
+ *
+ *    Rugged::Repository.init_at('repository', :bare) #=> #<Rugged::Repository:0x108849488>
+ */
+static VALUE rb_git_repo_init_at(int argc, VALUE *argv, VALUE klass)
+{
+	git_repository *repo = NULL;
+	VALUE rb_path, rb_is_bare, rb_options;
+	int error;
+
+	rb_scan_args(argc, argv, "11:", &rb_path, &rb_is_bare, &rb_options);
+	Check_Type(rb_path, T_STRING);
+
+	if (!NIL_P(rb_options)) {
+		/* Check for `:backend` */
+		VALUE rb_backend = rb_hash_aref(rb_options, CSTR2SYM("backend"));
+
+		if (rb_backend && !NIL_P(rb_backend)) {
+			rugged_repo_new_with_backend(&repo, rb_path, rb_backend);
+		}
+	}
+
+	if(!repo) {
+		error =	git_repository_init(&repo, StringValueCStr(rb_path), RTEST(rb_is_bare));
+		rugged_exception_check(error);
+	}
+
+	return rugged_repo_new(klass, repo);
+}
+
+static void parse_clone_options(git_clone_options *ret, VALUE rb_options, struct rugged_remote_cb_payload *remote_payload)
+{
+	VALUE val;
+
+	if (NIL_P(rb_options))
+		return;
+
+	val = rb_hash_aref(rb_options, CSTR2SYM("bare"));
+	if (RTEST(val))
+		ret->bare = 1;
+
+	val = rb_hash_aref(rb_options, CSTR2SYM("checkout_branch"));
+	if (!NIL_P(val)) {
+		Check_Type(val, T_STRING);
+		ret->checkout_branch = StringValueCStr(val);
+	}
+
+	rugged_remote_init_callbacks_and_payload_from_options(rb_options, &ret->fetch_opts.callbacks, remote_payload);
+}
+
+/*
+ *  call-seq:
+ *    Repository.clone_at(url, local_path[, options]) -> repository
+ *
+ *  Clone a repository from +url+ to +local_path+.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :bare ::
+ *    If +true+, the clone will be created as a bare repository.
+ *    Defaults to +false+.
+ *
+ *  :checkout_branch ::
+ *    The name of a branch to checkout. Defaults to the remote's +HEAD+.
+ *
+ *  :remote ::
+ *    The name to give to the "origin" remote. Defaults to <tt>"origin"</tt>.
+ *
+ *  :ignore_cert_errors ::
+ *    If set to +true+, errors while validating the remote's host certificate will be ignored.
+ *
+ *  :credentials ::
+ *    The credentials to use for the clone operation. Can be either an instance of one
+ *    of the Rugged::Credentials types, or a proc returning one of the former.
+ *    The proc will be called with the +url+, the +username+ from the url (if applicable) and
+ *    a list of applicable credential types.
+ *
+ *  :progress ::
+ *    A callback that will be executed with the textual progress received from the remote.
+ *    This is the text send over the progress side-band (ie. the "counting objects" output).
+ *
+ *  :transfer_progress ::
+ *    A callback that will be executed to report clone progress information. It will be passed
+ *    the amount of +total_objects+, +indexed_objects+, +received_objects+, +local_objects+,
+ *    +total_deltas+, +indexed_deltas+, and +received_bytes+.
+ *
+ *  :update_tips ::
+ *    A callback that will be executed each time a reference was updated locally. It will be
+ *    passed the +refname+, +old_oid+ and +new_oid+.
+ *
+ *  Example:
+ *
+ *    Repository.clone_at("https://github.com/libgit2/rugged.git", "./some/dir", {
+ *      transfer_progress: lambda { |total_objects, indexed_objects, received_objects, local_objects, total_deltas, indexed_deltas, received_bytes|
+ *        # ...
+ *      }
+ *    })
+ */
+static VALUE rb_git_repo_clone_at(int argc, VALUE *argv, VALUE klass)
+{
+	VALUE url, local_path, rb_options_hash;
+	git_clone_options options = GIT_CLONE_OPTIONS_INIT;
+	struct rugged_remote_cb_payload remote_payload = { Qnil, Qnil, Qnil, Qnil, 0 };
+	git_repository *repo;
+	int error;
+
+	rb_scan_args(argc, argv, "21", &url, &local_path, &rb_options_hash);
+	Check_Type(url, T_STRING);
+	Check_Type(local_path, T_STRING);
+
+	parse_clone_options(&options, rb_options_hash, &remote_payload);
+
+	error = git_clone(&repo, StringValueCStr(url), StringValueCStr(local_path), &options);
+
+	if (RTEST(remote_payload.exception))
+		rb_jump_tag(remote_payload.exception);
+	rugged_exception_check(error);
+
+	return rugged_repo_new(klass, repo);
+}
+
+#define RB_GIT_REPO_OWNED_GET(_klass, _object) \
+	VALUE rb_data = rb_iv_get(self, "@" #_object); \
+	if (NIL_P(rb_data)) { \
+		git_repository *repo; \
+		git_##_object *data; \
+		int error; \
+		Data_Get_Struct(self, git_repository, repo); \
+		error = git_repository_##_object(&data, repo); \
+		rugged_exception_check(error); \
+		rb_data = rugged_##_object##_new(_klass, self, data); \
+		rb_iv_set(self, "@" #_object, rb_data); \
+	} \
+	return rb_data; \
+
+#define RB_GIT_REPO_OWNED_SET(_klass, _object) \
+	VALUE rb_old_data; \
+	git_repository *repo; \
+	git_##_object *data; \
+	if (!rb_obj_is_kind_of(rb_data, _klass))\
+		rb_raise(rb_eTypeError, \
+			"The given object is not a Rugged::" #_object); \
+	if (!NIL_P(rugged_owner(rb_data))) \
+		rb_raise(rb_eRuntimeError, \
+			"The given object is already owned by another repository"); \
+	Data_Get_Struct(self, git_repository, repo); \
+	Data_Get_Struct(rb_data, git_##_object, data); \
+	git_repository_set_##_object(repo, data); \
+	rb_old_data = rb_iv_get(self, "@" #_object); \
+	if (!NIL_P(rb_old_data)) rugged_set_owner(rb_old_data, Qnil); \
+	rugged_set_owner(rb_data, self); \
+	rb_iv_set(self, "@" #_object, rb_data); \
+	return Qnil; \
+
+
+/*
+ *  call-seq:
+ *    repo.index = idx
+ *
+ *  Set the index for this +Repository+. +idx+ must be a instance of
+ *  Rugged::Index. This index will be used internally by all
+ *  operations that use the Git index on +repo+.
+ *
+ *  Note that it's not necessary to set the +index+ for any repository;
+ *  by default repositories are loaded with the index file that can be
+ *  located on the +.git+ folder in the filesystem.
+ */
+static VALUE rb_git_repo_set_index(VALUE self, VALUE rb_data)
+{
+	RB_GIT_REPO_OWNED_SET(rb_cRuggedIndex, index);
+}
+
+/*
+ *  call-seq:
+ *    repo.index -> idx
+ *
+ *  Return the default index for this repository.
+ */
+static VALUE rb_git_repo_get_index(VALUE self)
+{
+	RB_GIT_REPO_OWNED_GET(rb_cRuggedIndex, index);
+}
+
+/*
+ *  call-seq:
+ *    repo.config = cfg
+ *
+ *  Set the configuration file for this +Repository+. +cfg+ must be a instance of
+ *  Rugged::Config. This config file will be used internally by all
+ *  operations that need to lookup configuration settings on +repo+.
+ *
+ *  Note that it's not necessary to set the +config+ for any repository;
+ *  by default repositories are loaded with their relevant config files
+ *  on the filesystem, and the corresponding global and system files if
+ *  they can be found.
+ */
+static VALUE rb_git_repo_set_config(VALUE self, VALUE rb_data)
+{
+	RB_GIT_REPO_OWNED_SET(rb_cRuggedConfig, config);
+}
+
+/*
+ *  call-seq:
+ *    repo.config -> cfg
+ *
+ *  Return a Rugged::Config object representing this repository's config.
+ */
+static VALUE rb_git_repo_get_config(VALUE self)
+{
+	RB_GIT_REPO_OWNED_GET(rb_cRuggedConfig, config);
+}
+
+/*
+ *  call-seq:
+ *    repo.ident = ident
+ *
+ *  Set the identity to be used for writing reflogs.
+ *
+ *  +ident+ can be either +nil+ or a Hash containing +name+ and/or +email+ entries.
+ */
+static VALUE rb_git_repo_set_ident(VALUE self, VALUE rb_ident) {
+	VALUE rb_val;
+
+	git_repository *repo;
+	const char *name = NULL, *email = NULL;
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	if (!NIL_P(rb_ident)) {
+		Check_Type(rb_ident, T_HASH);
+
+		if (!NIL_P(rb_val = rb_hash_aref(rb_ident, CSTR2SYM("name")))) {
+			Check_Type(rb_val, T_STRING);
+			name = StringValueCStr(rb_val);
+		}
+
+		if (!NIL_P(rb_val = rb_hash_aref(rb_ident, CSTR2SYM("email")))) {
+			Check_Type(rb_val, T_STRING);
+			email = StringValueCStr(rb_val);
+		}
+	}
+
+	rugged_exception_check(
+		git_repository_set_ident(repo, name, email)
+	);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    repo.ident -> ident
+ *
+ *  Return a Hash containing the identity that is used to write reflogs.
+ *
+ *  +ident+ is a Hash containing +name+ and/or +email+ entries, or `nil`.
+ */
+static VALUE rb_git_repo_get_ident(VALUE self)
+{
+	VALUE rb_ident = rb_hash_new();
+
+	git_repository *repo;
+	const char *name = NULL, *email = NULL;
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	rugged_exception_check(
+		git_repository_ident(&name, &email, repo)
+	);
+
+	if (name) {
+		rb_hash_aset(rb_ident, CSTR2SYM("name"), rb_str_new_utf8(name));
+	}
+
+	if (email) {
+		rb_hash_aset(rb_ident, CSTR2SYM("email"), rb_str_new_utf8(email));
+	}
+
+	return rb_ident;
+}
+
+/*
+ *  call-seq:
+ *    repo.merge_base(oid1, oid2, ...)
+ *    repo.merge_base(ref1, ref2, ...)
+ *    repo.merge_base(commit1, commit2, ...)
+ *
+ *  Find a merge base, given two or more commits or oids.
+ *  Returns nil if a merge base is not found.
+ */
+static VALUE rb_git_repo_merge_base(VALUE self, VALUE rb_args)
+{
+	int error = GIT_OK, i;
+	git_repository *repo;
+	git_oid base, *input_array = xmalloc(sizeof(git_oid) * RARRAY_LEN(rb_args));
+	int len = (int)RARRAY_LEN(rb_args);
+
+	if (len < 2)
+		rb_raise(rb_eArgError, "wrong number of arguments (%d for 2+)", len);
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	for (i = 0; !error && i < len; ++i) {
+		error = rugged_oid_get(&input_array[i], repo, rb_ary_entry(rb_args, i));
+	}
+
+	if (error) {
+		xfree(input_array);
+		rugged_exception_check(error);
+	}
+
+	error = git_merge_base_many(&base, repo, len, input_array);
+	xfree(input_array);
+
+	if (error == GIT_ENOTFOUND)
+		return Qnil;
+
+	rugged_exception_check(error);
+
+	return rugged_create_oid(&base);
+}
+
+/*
+ *  call-seq:
+ *    repo.merge_bases(oid1, oid2, ...) -> Array
+ *    repo.merge_bases(ref1, ref2, ...) -> Array
+ *    repo.merge_bases(commit1, commit2, ...) -> Array
+ *
+ *  Find all merge bases, given two or more commits or oids.
+ *  Returns an empty array if no merge bases are found.
+ */
+static VALUE rb_git_repo_merge_bases(VALUE self, VALUE rb_args)
+{
+	int error = GIT_OK;
+	size_t i, len = (size_t)RARRAY_LEN(rb_args);
+	git_repository *repo;
+	git_oidarray bases = {NULL, 0};
+	git_oid *input_array;
+
+	VALUE rb_bases;
+
+	if (len < 2)
+		rb_raise(rb_eArgError, "wrong number of arguments (%ld for 2+)", RARRAY_LEN(rb_args));
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	input_array = xmalloc(sizeof(git_oid) * len);
+
+	for (i = 0; !error && i < len; ++i) {
+		error = rugged_oid_get(&input_array[i], repo, rb_ary_entry(rb_args, i));
+	}
+
+	if (error) {
+		xfree(input_array);
+		rugged_exception_check(error);
+	}
+
+	error = git_merge_bases_many(&bases, repo, len, input_array);
+	xfree(input_array);
+
+	if (error != GIT_ENOTFOUND)
+		rugged_exception_check(error);
+
+	rb_bases = rb_ary_new2(bases.count);
+
+	for (i = 0; i < bases.count; ++i) {
+		rb_ary_push(rb_bases, rugged_create_oid(&bases.ids[i]));
+	}
+
+	git_oidarray_free(&bases);
+
+	return rb_bases;
+}
+
+/*
+ *  call-seq:
+ *    repo.merge_analysis(their_commit) -> Array
+ *
+ *  Analyzes the given commit and determines the opportunities for merging
+ *  it into the repository's HEAD. Returns an Array containing a combination
+ *  of the following symbols:
+ *
+ *  :normal ::
+ *    A "normal" merge is possible, both HEAD and the given commit have
+ *    diverged from their common ancestor. The divergent commits must be
+ *    merged.
+ *
+ *  :up_to_date ::
+ *    The given commit is reachable from HEAD, meaning HEAD is up-to-date
+ *    and no merge needs to be performed.
+ *
+ *  :fastforward ::
+ *    The given commit is a fast-forward from HEAD and no merge needs to be
+ *    performed. HEAD can simply be set to the given commit.
+ *
+ *  :unborn ::
+ *    The HEAD of the current repository is "unborn" and does not point to
+ *    a valid commit. No merge can be performed, but the caller may wish
+ *    to simply set HEAD to the given commit.
+ */
+static VALUE rb_git_repo_merge_analysis(int argc, VALUE *argv, VALUE self)
+{
+	int error;
+	git_repository *repo;
+	git_commit *their_commit;
+	git_annotated_commit *annotated_commit;
+	git_merge_analysis_t analysis;
+	git_merge_preference_t preference;
+	VALUE rb_their_commit, result;
+
+	rb_scan_args(argc, argv, "10", &rb_their_commit);
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	if (TYPE(rb_their_commit) == T_STRING) {
+		rb_their_commit = rugged_object_rev_parse(self, rb_their_commit, 1);
+	}
+
+	if (!rb_obj_is_kind_of(rb_their_commit, rb_cRuggedCommit)) {
+		rb_raise(rb_eArgError, "Expected a Rugged::Commit.");
+	}
+
+	Data_Get_Struct(rb_their_commit, git_commit, their_commit);
+
+	error = git_annotated_commit_lookup(&annotated_commit, repo, git_commit_id(their_commit));
+	rugged_exception_check(error);
+
+	error = git_merge_analysis(&analysis, &preference, repo,
+				   /* hack as we currently only do one commit */
+				   (const git_annotated_commit **) &annotated_commit, 1);
+	git_annotated_commit_free(annotated_commit);
+	rugged_exception_check(error);
+
+	result = rb_ary_new();
+	if (analysis & GIT_MERGE_ANALYSIS_NORMAL)
+		rb_ary_push(result, CSTR2SYM("normal"));
+	if (analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE)
+		rb_ary_push(result, CSTR2SYM("up_to_date"));
+	if (analysis & GIT_MERGE_ANALYSIS_FASTFORWARD)
+		rb_ary_push(result, CSTR2SYM("fastforward"));
+	if (analysis & GIT_MERGE_ANALYSIS_UNBORN)
+		rb_ary_push(result, CSTR2SYM("unborn"));
+
+	return result;
+}
+
+/*
+ *  call-seq:
+ *    repo.merge_commits(our_commit, their_commit, options = {}) -> index
+ *
+ *  Merges the two given commits, returning a Rugged::Index that reflects
+ *  the result of the merge.
+ *
+ *  +our_commit+ and +their_commit+ can either be Rugged::Commit objects,
+ *  or OIDs resolving to the former.
+ */
+static VALUE rb_git_repo_merge_commits(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_our_commit, rb_their_commit, rb_options;
+	git_commit *our_commit, *their_commit;
+	git_index *index;
+	git_repository *repo;
+	git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+
+	rb_scan_args(argc, argv, "20:", &rb_our_commit, &rb_their_commit, &rb_options);
+
+	if (TYPE(rb_our_commit) == T_STRING) {
+		rb_our_commit = rugged_object_rev_parse(self, rb_our_commit, 1);
+	}
+
+	if (!rb_obj_is_kind_of(rb_our_commit, rb_cRuggedCommit)) {
+		rb_raise(rb_eArgError, "Expected a Rugged::Commit.");
+	}
+
+	if (TYPE(rb_their_commit) == T_STRING) {
+		rb_their_commit = rugged_object_rev_parse(self, rb_their_commit, 1);
+	}
+
+	if (!rb_obj_is_kind_of(rb_their_commit, rb_cRuggedCommit)) {
+		rb_raise(rb_eArgError, "Expected a Rugged::Commit.");
+	}
+
+	if (!NIL_P(rb_options)) {
+		Check_Type(rb_options, T_HASH);
+		rugged_parse_merge_options(&opts, rb_options);
+	}
+
+	Data_Get_Struct(self, git_repository, repo);
+	Data_Get_Struct(rb_our_commit, git_commit, our_commit);
+	Data_Get_Struct(rb_their_commit, git_commit, their_commit);
+
+	rugged_exception_check(git_merge_commits(&index, repo, our_commit, their_commit, &opts));
+
+	return rugged_index_new(rb_cRuggedIndex, self, index);
+}
+
+/*
+ *  call-seq:
+ *    repo.include?(oid) -> true or false
+ *    repo.exists?(oid) -> true or false
+ *
+ *  Return whether an object with the given SHA1 OID (represented as
+ *  a hex string of at least 7 characters) exists in the repository.
+ *
+ *    repo.include?("d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f") #=> true
+ *    repo.include?("d8786bfc") #=> true
+ */
+static VALUE rb_git_repo_exists(VALUE self, VALUE hex)
+{
+	git_repository *repo;
+	git_odb *odb;
+	git_oid oid;
+	int error;
+
+	Data_Get_Struct(self, git_repository, repo);
+	Check_Type(hex, T_STRING);
+
+	error = git_oid_fromstrn(&oid, RSTRING_PTR(hex), RSTRING_LEN(hex));
+	rugged_exception_check(error);
+
+	error = git_repository_odb(&odb, repo);
+	rugged_exception_check(error);
+
+	error = git_odb_exists_prefix(NULL, odb, &oid, RSTRING_LEN(hex));
+	git_odb_free(odb);
+
+	if (error == 0 || error == GIT_EAMBIGUOUS)
+		return Qtrue;
+
+	return Qfalse;
+}
+
+/*
+ *  call-seq:
+ *    repo.read(oid) -> str
+ *
+ *  Read and return the raw data of the object identified by the given +oid+.
+ */
+static VALUE rb_git_repo_read(VALUE self, VALUE hex)
+{
+	git_repository *repo;
+	git_oid oid;
+	int error;
+
+	Data_Get_Struct(self, git_repository, repo);
+	Check_Type(hex, T_STRING);
+
+	error = git_oid_fromstr(&oid, StringValueCStr(hex));
+	rugged_exception_check(error);
+
+	return rugged_raw_read(repo, &oid);
+}
+
+/*
+ *  call-seq:
+ *    repo.read_header(oid) -> hash
+ *
+ *  Read and return the header information in +repo+'s ODB
+ *  for the object identified by the given +oid+.
+ *
+ *  Returns a Hash object with the following key/value pairs:
+ *
+ *  :type ::
+ *    A Symbol denoting the object's type. Possible values are:
+ *    +:tree+, +:blob+, +:commit+ or +:tag+.
+ *  :len ::
+ *    A Number representing the object's length, in bytes.
+ */
+static VALUE rb_git_repo_read_header(VALUE self, VALUE hex)
+{
+	git_repository *repo;
+	git_oid oid;
+	git_odb *odb;
+	git_otype type;
+	size_t len;
+	VALUE rb_hash;
+	int error;
+
+	Data_Get_Struct(self, git_repository, repo);
+	Check_Type(hex, T_STRING);
+
+	error = git_oid_fromstr(&oid, StringValueCStr(hex));
+	rugged_exception_check(error);
+
+	error = git_repository_odb(&odb, repo);
+	rugged_exception_check(error);
+
+	error = git_odb_read_header(&len, &type, odb, &oid);
+	git_odb_free(odb);
+	rugged_exception_check(error);
+
+	rb_hash = rb_hash_new();
+	rb_hash_aset(rb_hash, CSTR2SYM("type"), CSTR2SYM(git_object_type2string(type)));
+	rb_hash_aset(rb_hash, CSTR2SYM("len"), INT2FIX(len));
+
+	return rb_hash;
+}
+
+/**
+ *  call-seq:
+ *    repo.expand_oids([oid..], object_type = :any) -> hash
+ *
+ *  Expand a list of short oids to their full value, assuming they exist
+ *  in the repository. If `object_type` is passed, OIDs are expected to be
+ *  of the given type.
+ *
+ *  Returns a hash of `{ short_oid => full_oid }` for the short OIDs which
+ *  exist in the repository and match the expected object type. Missing OIDs
+ *  will not appear in the resulting hash.
+ */
+static VALUE rb_git_repo_expand_oids(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_result, rb_oids, rb_expected_type;
+
+	git_otype expected_type = GIT_OBJ_ANY;
+
+	git_repository *repo;
+	git_oid oid;
+	git_odb *odb;
+	int i, error;
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	rb_scan_args(argc, argv, "11", &rb_oids, &rb_expected_type);
+
+	Check_Type(rb_oids, T_ARRAY);
+	expected_type = rugged_otype_get(rb_expected_type);
+
+	error = git_repository_odb(&odb, repo);
+	rugged_exception_check(error);
+
+	rb_result = rb_hash_new();
+
+	for (i = 0; i < RARRAY_LEN(rb_oids); ++i) {
+		VALUE hex_oid = rb_ary_entry(rb_oids, i);
+		git_oid found_oid;
+
+		if (TYPE(hex_oid) != T_STRING) {
+			git_odb_free(odb);
+			rb_raise(rb_eTypeError, "Expected a SHA1 OID");
+		}
+
+		error = git_oid_fromstrn(&oid, RSTRING_PTR(hex_oid), RSTRING_LEN(hex_oid));
+		if (error < 0) {
+			git_odb_free(odb);
+			rugged_exception_check(error);
+		}
+
+		error = git_odb_exists_prefix(&found_oid, odb, &oid, RSTRING_LEN(hex_oid));
+
+		if (!error) {
+			if (expected_type != GIT_OBJ_ANY) {
+				size_t found_size;
+				git_otype found_type;
+
+				if (git_odb_read_header(&found_size, &found_type, odb, &found_oid) < 0)
+					continue;
+
+				if (found_type != expected_type)
+					continue;
+			}
+
+			rb_hash_aset(rb_result, hex_oid, rugged_create_oid(&found_oid));
+		}
+	}
+
+	git_odb_free(odb);
+	return rb_result;
+}
+
+/*
+ *  call-seq:
+ *    repo.descendant_of?(commit, ancestor) -> true or false
+ *
+ *  +commit+ and +ancestor+ must be String commit OIDs or instances of Rugged::Commit.
+ *
+ *  Returns true if +commit+ is a descendant of +ancestor+, or false if not.
+ */
+static VALUE rb_git_repo_descendant_of(VALUE self, VALUE rb_commit, VALUE rb_ancestor)
+{
+	int result;
+	int error;
+	git_repository *repo;
+	git_oid commit, ancestor;
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	error = rugged_oid_get(&commit, repo, rb_commit);
+	rugged_exception_check(error);
+
+	error = rugged_oid_get(&ancestor, repo, rb_ancestor);
+	rugged_exception_check(error);
+
+	result = git_graph_descendant_of(repo, &commit, &ancestor);
+	rugged_exception_check(result);
+
+	return result ? Qtrue : Qfalse;
+}
+
+/*
+ *  call-seq:
+ *    Repository.hash_data(str, type) -> oid
+ *
+ *  Hash the contents of +str+ as raw bytes (ignoring any encoding
+ *  information) and adding the relevant header corresponding to +type+,
+ *  and return a hex string representing the result from the hash.
+ *
+ *    Repository.hash_data('hello world', :commit) #=> "de5ba987198bcf2518885f0fc1350e5172cded78"
+ *
+ *    Repository.hash_data('hello_world', :tag) #=> "9d09060c850defbc7711d08b57def0d14e742f4e"
+ */
+static VALUE rb_git_repo_hash(VALUE self, VALUE rb_buffer, VALUE rb_type)
+{
+	int error;
+	git_oid oid;
+
+	Check_Type(rb_buffer, T_STRING);
+
+	error = git_odb_hash(&oid,
+		RSTRING_PTR(rb_buffer),
+		RSTRING_LEN(rb_buffer),
+		rugged_otype_get(rb_type)
+	);
+	rugged_exception_check(error);
+
+	return rugged_create_oid(&oid);
+}
+
+/*
+ *  call-seq:
+ *    Repository.hash_file(path, type) -> oid
+ *
+ *  Hash the contents of the file pointed at by +path+, assuming
+ *  that it'd be stored in the ODB with the given +type+, and return
+ *  a hex string representing the SHA1 OID resulting from the hash.
+ *
+ *    Repository.hash_file('foo.txt', :commit) #=> "de5ba987198bcf2518885f0fc1350e5172cded78"
+ *
+ *    Repository.hash_file('foo.txt', :tag) #=> "9d09060c850defbc7711d08b57def0d14e742f4e"
+ */
+static VALUE rb_git_repo_hashfile(VALUE self, VALUE rb_path, VALUE rb_type)
+{
+	int error;
+	git_oid oid;
+
+	Check_Type(rb_path, T_STRING);
+
+	error = git_odb_hashfile(&oid,
+		StringValueCStr(rb_path),
+		rugged_otype_get(rb_type)
+	);
+	rugged_exception_check(error);
+
+	return rugged_create_oid(&oid);
+}
+
+/*
+ *  call-seq:
+ *    repo.write(buffer, type) -> oid
+ *
+ *  Write the data contained in the +buffer+ string as a raw object of the
+ *  given +type+ into the repository's object database.
+ *
+ *  +type+ can be either +:tag+, +:commit+, +:tree+ or +:blob+.
+ *
+ *  Returns the newly created object's oid.
+ */
+static VALUE rb_git_repo_write(VALUE self, VALUE rb_buffer, VALUE rub_type)
+{
+	git_repository *repo;
+	git_odb_stream *stream;
+
+	git_odb *odb;
+	git_oid oid;
+	int error;
+
+	git_otype type;
+
+	Data_Get_Struct(self, git_repository, repo);
+	Check_Type(rb_buffer, T_STRING);
+
+	error = git_repository_odb(&odb, repo);
+	rugged_exception_check(error);
+
+	type = rugged_otype_get(rub_type);
+
+	error = git_odb_open_wstream(&stream, odb, RSTRING_LEN(rb_buffer), type);
+	git_odb_free(odb);
+	rugged_exception_check(error);
+
+	error = git_odb_stream_write(stream, RSTRING_PTR(rb_buffer), RSTRING_LEN(rb_buffer));
+	if (!error)
+		error = git_odb_stream_finalize_write(&oid, stream);
+
+	git_odb_stream_free(stream);
+	rugged_exception_check(error);
+
+	return rugged_create_oid(&oid);
+}
+
+#define RB_GIT_REPO_GETTER(method) \
+	git_repository *repo; \
+	int error; \
+	Data_Get_Struct(self, git_repository, repo); \
+	error = git_repository_##method(repo); \
+	rugged_exception_check(error); \
+	return error ? Qtrue : Qfalse; \
+
+/*
+ *  call-seq:
+ *    repo.bare? -> true or false
+ *
+ *  Return whether a repository is bare or not. A bare repository has no
+ *  working directory.
+ */
+static VALUE rb_git_repo_is_bare(VALUE self)
+{
+	RB_GIT_REPO_GETTER(is_bare);
+}
+
+/*
+ *  call-seq:
+ *    repo.shallow? -> true or false
+ *
+ *  Return whether a repository is a shallow clone or not. A shallow clone has
+ *  a truncated history and can not be cloned or fetched from, nor can be
+ *  pushed from nor into it.
+ */
+static VALUE rb_git_repo_is_shallow(VALUE self)
+{
+	RB_GIT_REPO_GETTER(is_shallow);
+}
+
+/*
+ *  call-seq:
+ *    repo.empty? -> true or false
+ *
+ *  Return whether a repository is empty or not. An empty repository has just
+ *  been initialized and has no commits yet.
+ */
+static VALUE rb_git_repo_is_empty(VALUE self)
+{
+	RB_GIT_REPO_GETTER(is_empty);
+}
+
+/*
+ *  call-seq:
+ *    repo.head_detached? -> true or false
+ *
+ *  Return whether the +HEAD+ of a repository is detached or not.
+ */
+static VALUE rb_git_repo_head_detached(VALUE self)
+{
+	RB_GIT_REPO_GETTER(head_detached);
+}
+
+/*
+ *  call-seq:
+ *    repo.head_unborn? -> true or false
+ *
+ *  Return whether the current branch is unborn (+HEAD+ points to a
+ *  non-existent branch).
+ */
+static VALUE rb_git_repo_head_unborn(VALUE self)
+{
+	RB_GIT_REPO_GETTER(head_unborn);
+}
+
+/*
+ *  call-seq:
+ *    repo.head = str
+ *
+ *  Make the repository's +HEAD+ point to the specified reference.
+ */
+static VALUE rb_git_repo_set_head(VALUE self, VALUE rb_head)
+{
+	git_repository *repo;
+	int error;
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	Check_Type(rb_head, T_STRING);
+	error = git_repository_set_head(repo, StringValueCStr(rb_head));
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    repo.head -> ref
+ *
+ *  Retrieve and resolve the reference pointed at by the repository's +HEAD+.
+ *
+ *  Returns +nil+ if +HEAD+ is missing.
+ */
+static VALUE rb_git_repo_get_head(VALUE self)
+{
+	git_repository *repo;
+	git_reference *head;
+	int error;
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	error = git_repository_head(&head, repo);
+	if (error == GIT_ENOTFOUND)
+		return Qnil;
+	else
+		rugged_exception_check(error);
+
+	return rugged_ref_new(rb_cRuggedReference, self, head);
+}
+
+/*
+ *  call-seq:
+ *    repo.path -> path
+ *
+ *  Return the full, normalized path to this repository. For non-bare repositories,
+ *  this is the path of the actual +.git+ folder, not the working directory.
+ *
+ *    repo.path #=> "/home/foo/workthing/.git"
+ */
+static VALUE rb_git_repo_path(VALUE self)
+{
+	git_repository *repo;
+	const char *path;
+
+	Data_Get_Struct(self, git_repository, repo);
+	path = git_repository_path(repo);
+
+	return path ? rb_str_new_utf8(path) : Qnil;
+}
+
+/*
+ *  call-seq:
+ *    repo.workdir -> path or nil
+ *
+ *  Return the working directory for this repository, or +nil+ if
+ *  the repository is bare.
+ *
+ *    repo1.bare? #=> false
+ *    repo1.workdir #=> "/home/foo/workthing/"
+ *
+ *    repo2.bare? #=> true
+ *    repo2.workdir #=> nil
+ */
+static VALUE rb_git_repo_workdir(VALUE self)
+{
+	git_repository *repo;
+	const char *workdir;
+
+	Data_Get_Struct(self, git_repository, repo);
+	workdir = git_repository_workdir(repo);
+
+	return workdir ? rb_str_new_utf8(workdir) : Qnil;
+}
+
+/*
+ *  call-seq:
+ *    repo.workdir = path
+ *
+ *  Sets the working directory of +repo+ to +path+. All internal
+ *  operations on +repo+ that affect the working directory will
+ *  instead use +path+.
+ *
+ *  The +workdir+ can be set on bare repositories to temporarily
+ *  turn them into normal repositories.
+ *
+ *    repo.bare? #=> true
+ *    repo.workdir = "/tmp/workdir"
+ *    repo.bare? #=> false
+ *    repo.checkout
+ */
+static VALUE rb_git_repo_set_workdir(VALUE self, VALUE rb_workdir)
+{
+	git_repository *repo;
+
+	Data_Get_Struct(self, git_repository, repo);
+	Check_Type(rb_workdir, T_STRING);
+
+	rugged_exception_check(
+		git_repository_set_workdir(repo, StringValueCStr(rb_workdir), 0)
+	);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    Repository.discover(path = nil, across_fs = true) -> repository
+ *
+ *  Traverse +path+ upwards until a Git working directory with a +.git+
+ *  folder has been found, open it and return it as a +Repository+
+ *  object.
+ *
+ *  If +path+ is +nil+, the current working directory will be used as
+ *  a starting point.
+ *
+ *  If +across_fs+ is +true+, the traversal won't stop when reaching
+ *  a different device than the one that contained +path+ (only applies
+ *  to UNIX-based OSses).
+ */
+static VALUE rb_git_repo_discover(int argc, VALUE *argv, VALUE klass)
+{
+	git_repository *repo;
+	VALUE rb_path, rb_across_fs;
+	git_buf repository_path = { NULL };
+	int error, across_fs = 0;
+
+	rb_scan_args(argc, argv, "02", &rb_path, &rb_across_fs);
+
+	if (NIL_P(rb_path)) {
+		VALUE rb_dir = rb_const_get(rb_cObject, rb_intern("Dir"));
+		rb_path = rb_funcall(rb_dir, rb_intern("pwd"), 0);
+	}
+
+	if (!NIL_P(rb_across_fs)) {
+		across_fs = rugged_parse_bool(rb_across_fs);
+	}
+
+	Check_Type(rb_path, T_STRING);
+
+	error = git_repository_discover(
+		&repository_path,
+		StringValueCStr(rb_path),
+		across_fs,
+		NULL
+	);
+
+	rugged_exception_check(error);
+
+	error = git_repository_open(&repo, repository_path.ptr);
+	git_buf_free(&repository_path);
+
+	rugged_exception_check(error);
+
+	return rugged_repo_new(klass, repo);
+}
+
+static VALUE flags_to_rb(unsigned int flags)
+{
+	VALUE rb_flags = rb_ary_new();
+
+	if (flags & GIT_STATUS_INDEX_NEW)
+		rb_ary_push(rb_flags, CSTR2SYM("index_new"));
+
+	if (flags & GIT_STATUS_INDEX_MODIFIED)
+		rb_ary_push(rb_flags, CSTR2SYM("index_modified"));
+
+	if (flags & GIT_STATUS_INDEX_DELETED)
+		rb_ary_push(rb_flags, CSTR2SYM("index_deleted"));
+
+	if (flags & GIT_STATUS_WT_NEW)
+		rb_ary_push(rb_flags, CSTR2SYM("worktree_new"));
+
+	if (flags & GIT_STATUS_WT_MODIFIED)
+		rb_ary_push(rb_flags, CSTR2SYM("worktree_modified"));
+
+	if (flags & GIT_STATUS_WT_DELETED)
+		rb_ary_push(rb_flags, CSTR2SYM("worktree_deleted"));
+
+	if (flags & GIT_STATUS_IGNORED)
+		rb_ary_push(rb_flags, CSTR2SYM("ignored"));
+
+	return rb_flags;
+}
+
+static int rugged__status_cb(const char *path, unsigned int flags, void *payload)
+{
+	rb_funcall((VALUE)payload, rb_intern("call"), 2,
+		rb_str_new_utf8(path), flags_to_rb(flags)
+	);
+
+	return GIT_OK;
+}
+
+/*
+ *  call-seq:
+ *    repo.status { |file, status_data| block }
+ *    repo.status(path) -> status_data
+ *
+ *  Returns the status for one or more files in the working directory
+ *  of the repository. This is equivalent to the +git status+ command.
+ *
+ *  The returned +status_data+ is always an array containing one or more
+ *  status flags as Ruby symbols. Possible flags are:
+ *
+ *  - +:index_new+: the file is new in the index
+ *  - +:index_modified+: the file has been modified in the index
+ *  - +:index_deleted+: the file has been deleted from the index
+ *  - +:worktree_new+: the file is new in the working directory
+ *  - +:worktree_modified+: the file has been modified in the working directory
+ *  - +:worktree_deleted+: the file has been deleted from the working directory
+ *
+ *  If a +block+ is given, status information will be gathered for every
+ *  single file on the working dir. The +block+ will be called with the
+ *  status data for each file.
+ *
+ *    repo.status { |file, status_data| puts "#{file} has status: #{status_data.inspect}" }
+ *
+ *  results in, for example:
+ *
+ *    src/diff.c has status: [:index_new, :worktree_new]
+ *    README has status: [:worktree_modified]
+ *
+ *  If a +path+ is given instead, the function will return the +status_data+ for
+ *  the file pointed to by path, or raise an exception if the path doesn't exist.
+ *
+ *  +path+ must be relative to the repository's working directory.
+ *
+ *    repo.status('src/diff.c') #=> [:index_new, :worktree_new]
+ */
+static VALUE rb_git_repo_status(int argc, VALUE *argv, VALUE self)
+{
+	int error;
+	VALUE rb_path;
+	git_repository *repo;
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	if (rb_scan_args(argc, argv, "01", &rb_path) == 1) {
+		unsigned int flags;
+		Check_Type(rb_path, T_STRING);
+		error = git_status_file(&flags, repo, StringValueCStr(rb_path));
+		rugged_exception_check(error);
+
+		return flags_to_rb(flags);
+	}
+
+	if (!rb_block_given_p())
+		rb_raise(rb_eRuntimeError,
+			"A block was expected for iterating through "
+			"the repository contents.");
+
+	error = git_status_foreach(
+		repo,
+		&rugged__status_cb,
+		(void *)rb_block_proc()
+	);
+
+	rugged_exception_check(error);
+	return Qnil;
+}
+
+static int rugged__each_id_cb(const git_oid *id, void *payload)
+{
+	int *exception = (int *)payload;
+	rb_protect(rb_yield, rugged_create_oid(id), exception);
+	return *exception ? GIT_ERROR : GIT_OK;
+}
+
+/*
+ *  call-seq:
+ *    repo.each_id { |id| block }
+ *    repo.each_id -> Iterator
+ *
+ *  Call the given +block+ once with every object ID found in +repo+
+ *  and all its alternates. Object IDs are passed as 40-character
+ *  strings.
+ */
+static VALUE rb_git_repo_each_id(VALUE self)
+{
+	git_repository *repo;
+	git_odb *odb;
+	int error, exception = 0;
+
+	if (!rb_block_given_p())
+		return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("each_id"));
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	error = git_repository_odb(&odb, repo);
+	rugged_exception_check(error);
+
+	error = git_odb_foreach(odb, &rugged__each_id_cb, &exception);
+	git_odb_free(odb);
+
+	if (exception)
+		rb_jump_tag(exception);
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+static int parse_reset_type(VALUE rb_reset_type)
+{
+	ID id_reset_type;
+
+	Check_Type(rb_reset_type, T_SYMBOL);
+	id_reset_type = SYM2ID(rb_reset_type);
+
+	if (id_reset_type == rb_intern("soft")) {
+		return GIT_RESET_SOFT;
+	} else if (id_reset_type == rb_intern("mixed")) {
+		return GIT_RESET_MIXED;
+	} else if (id_reset_type == rb_intern("hard")) {
+		return GIT_RESET_HARD;
+	} else {
+		rb_raise(rb_eArgError,
+			"Invalid reset type. Expected `:soft`, `:mixed` or `:hard`");
+	}
+}
+
+/*
+ *  call-seq:
+ *    repo.reset(target, reset_type) -> nil
+ *
+ *  Sets the current head to the specified commit oid and optionally
+ *  resets the index and working tree to match.
+ *  - +target+: Rugged::Commit, Rugged::Tag or rev that resolves to a commit or tag object
+ *  - +reset_type+: +:soft+, +:mixed+ or +:hard+
+ *
+ *  [:soft]
+ *    the head will be moved to the commit.
+ *  [:mixed]
+ *    will trigger a +:soft+ reset, plus the index will be replaced
+ *    with the content of the commit tree.
+ *  [:hard]
+ *    will trigger a +:mixed+ reset and the working directory will be
+ *    replaced with the content of the index. (Untracked and ignored files
+ *    will be left alone)
+ *
+ *  Examples:
+ *
+ *    repo.reset('origin/master', :hard) #=> nil
+ */
+static VALUE rb_git_repo_reset(VALUE self, VALUE rb_target, VALUE rb_reset_type)
+{
+	git_repository *repo;
+	int reset_type;
+	git_object *target = NULL;
+	int error;
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	reset_type = parse_reset_type(rb_reset_type);
+	target = rugged_object_get(repo, rb_target, GIT_OBJ_ANY);
+
+	error = git_reset(repo, target, reset_type, NULL);
+
+	git_object_free(target);
+
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    repo.reset_path(pathspecs, target=nil) -> nil
+ *
+ *  Updates entries in the index from the +target+ commit tree, matching
+ *  the given +pathspecs+.
+ *
+ *  Passing a nil +target+ will result in removing
+ *  entries in the index matching the provided pathspecs.
+ *
+ *  - +pathspecs+: list of pathspecs to operate on (+String+ or +Array+ of +String+ objects)
+ *  - +target+(optional): Rugged::Commit, Rugged::Tag or rev that resolves to a commit or tag object.
+ *
+ *  Examples:
+ *    reset_path(File.join('subdir','file.txt'), '441034f860c1d5d90e4188d11ae0d325176869a8') #=> nil
+ */
+static VALUE rb_git_repo_reset_path(int argc, VALUE *argv, VALUE self)
+{
+	git_repository *repo;
+	git_object *target = NULL;
+	git_strarray pathspecs;
+	VALUE rb_target, rb_paths;
+	int error = 0;
+
+	pathspecs.strings = NULL;
+	pathspecs.count = 0;
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	rb_scan_args(argc, argv, "11", &rb_paths, &rb_target);
+
+	rugged_rb_ary_to_strarray(rb_paths, &pathspecs);
+
+	if (!NIL_P(rb_target))
+		target = rugged_object_get(repo, rb_target, GIT_OBJ_ANY);
+
+	error = git_reset_default(repo, target, &pathspecs);
+
+	xfree(pathspecs.strings);
+	git_object_free(target);
+
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    repo.close -> nil
+ *
+ *  Frees all the resources used by this repository immediately. The repository can
+ *  still be used after this call. Resources will be opened as necessary.
+ *
+ *  It is not required to call this method explicitly. Repositories are closed
+ *  automatically before garbage collection
+ */
+static VALUE rb_git_repo_close(VALUE self)
+{
+	git_repository *repo;
+	Data_Get_Struct(self, git_repository, repo);
+
+	git_repository__cleanup(repo);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    repo.namespace = new_namespace
+ *
+ *  Sets the active namespace for the repository.
+ *  If set to nil, no namespace will be active.
+ */
+static VALUE rb_git_repo_set_namespace(VALUE self, VALUE rb_namespace)
+{
+	git_repository *repo;
+	int error;
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	if (!NIL_P(rb_namespace)) {
+		Check_Type(rb_namespace, T_STRING);
+		error = git_repository_set_namespace(repo, StringValueCStr(rb_namespace));
+	} else {
+		error = git_repository_set_namespace(repo, NULL);
+	}
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    repo.namespace -> str
+ *
+ *  Returns the active namespace for the repository.
+ */
+static VALUE rb_git_repo_get_namespace(VALUE self)
+{
+	git_repository *repo;
+	const char *namespace;
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	namespace = git_repository_get_namespace(repo);
+	return namespace ? rb_str_new_utf8(namespace) : Qnil;
+}
+
+/*
+ *  call-seq:
+ *    repo.ahead_behind(local, upstream) -> Array
+ *
+ *  Returns a 2 element Array containing the number of commits
+ *  that the upstream object is ahead and behind the local object.
+ *
+ *  +local+ and +upstream+ can either be strings containing SHA1 OIDs or
+ *  Rugged::Object instances.
+ */
+static VALUE rb_git_repo_ahead_behind(VALUE self, VALUE rb_local, VALUE rb_upstream) {
+	git_repository *repo;
+	int error;
+	git_oid local, upstream;
+	size_t ahead, behind;
+	VALUE rb_result;
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	error = rugged_oid_get(&local, repo, rb_local);
+	rugged_exception_check(error);
+
+	error = rugged_oid_get(&upstream, repo, rb_upstream);
+	rugged_exception_check(error);
+
+	error = git_graph_ahead_behind(&ahead, &behind, repo, &local, &upstream);
+	rugged_exception_check(error);
+
+	rb_result = rb_ary_new2(2);
+	rb_ary_push(rb_result, INT2FIX((int) ahead));
+	rb_ary_push(rb_result, INT2FIX((int) behind));
+	return rb_result;
+}
+
+/*
+ *  call-seq:
+ *    repo.default_signature -> signature or nil
+ *
+ *  Returns a +Hash+ with the default user +signature+ or +nil+.
+ *
+ *  Looks up the +user.name+ and +user.email+ from the configuration and
+ *  uses the current time as the timestamp, and creates a new signature
+ *  based on that information.  It will return +nil+ if either the
+ *  +user.name+ or +user.email+ are not set.
+ *
+ *  Returns a +Hash+:
+ *  - +:name+: the +user.name+ config value
+ *  - +:email+: the +user.email+ config value
+ *  - +:time+: the current time as a +Time+ instance
+ */
+static VALUE rb_git_repo_default_signature(VALUE self) {
+	int error;
+	git_repository *repo;
+	git_signature *signature;
+	VALUE rb_signature;
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	error = git_signature_default(&signature, repo);
+
+	if (error == GIT_ENOTFOUND)
+		return Qnil;
+
+	rugged_exception_check(error);
+
+	rb_signature = rugged_signature_new(signature, NULL);
+	git_signature_free(signature);
+	return rb_signature;
+}
+
+void rugged__checkout_progress_cb(
+	const char *path,
+	size_t completed_steps,
+	size_t total_steps,
+	void *data
+) {
+	struct rugged_cb_payload *payload = data;
+	VALUE args = rb_ary_new2(4);
+	rb_ary_push(args, payload->rb_data);
+	rb_ary_push(args, path == NULL ? Qnil : rb_str_new2(path));
+	rb_ary_push(args, INT2FIX(completed_steps));
+	rb_ary_push(args, INT2FIX(total_steps));
+
+	rb_protect(rugged__block_yield_splat, args, &payload->exception);
+}
+
+static int rugged__checkout_notify_cb(
+	git_checkout_notify_t why,
+	const char *path,
+	const git_diff_file *baseline,
+	const git_diff_file *target,
+	const git_diff_file *workdir,
+	void *data
+) {
+	struct rugged_cb_payload *payload = data;
+	VALUE args = rb_ary_new2(5);
+	rb_ary_push(args, payload->rb_data);
+
+	switch (why) {
+		case GIT_CHECKOUT_NOTIFY_CONFLICT:
+			rb_ary_push(args, CSTR2SYM("conflict"));
+		break;
+
+		case GIT_CHECKOUT_NOTIFY_DIRTY:
+			rb_ary_push(args, CSTR2SYM("dirty"));
+		break;
+
+		case GIT_CHECKOUT_NOTIFY_UPDATED:
+			rb_ary_push(args, CSTR2SYM("updated"));
+		break;
+
+		case GIT_CHECKOUT_NOTIFY_UNTRACKED:
+			rb_ary_push(args, CSTR2SYM("untracked"));
+		break;
+
+		case GIT_CHECKOUT_NOTIFY_IGNORED:
+			rb_ary_push(args, CSTR2SYM("ignored"));
+		break;
+
+		default:
+			rb_ary_push(args, CSTR2SYM("unknown"));
+	}
+
+	rb_ary_push(args, rb_git_delta_file_fromC(baseline));
+	rb_ary_push(args, rb_git_delta_file_fromC(target));
+	rb_ary_push(args, rb_git_delta_file_fromC(workdir));
+
+	rb_protect(rugged__block_yield_splat, args, &payload->exception);
+
+	return payload->exception ? GIT_ERROR : GIT_OK;
+}
+
+/**
+ * The caller has to free the returned git_checkout_options paths strings array.
+ */
+static void rugged_parse_checkout_options(git_checkout_options *opts, VALUE rb_options)
+{
+	VALUE rb_value;
+
+	if (NIL_P(rb_options))
+		return;
+
+	Check_Type(rb_options, T_HASH);
+
+	rb_value = rb_hash_aref(rb_options, CSTR2SYM("progress"));
+	if (!NIL_P(rb_value)) {
+		struct rugged_cb_payload *payload = malloc(sizeof(struct rugged_cb_payload));
+		payload->rb_data = rb_value;
+		payload->exception = 0;
+
+		opts->progress_payload = payload;
+		opts->progress_cb = &rugged__checkout_progress_cb;
+	}
+
+	rb_value = rb_hash_aref(rb_options, CSTR2SYM("notify"));
+	if (!NIL_P(rb_value)) {
+		struct rugged_cb_payload *payload = malloc(sizeof(struct rugged_cb_payload));
+		payload->rb_data = rb_value;
+		payload->exception = 0;
+
+		opts->notify_payload = payload;
+		opts->notify_cb = &rugged__checkout_notify_cb;
+	}
+
+	if (!NIL_P(rb_value = rb_hash_aref(rb_options, CSTR2SYM("strategy")))) {
+		int i;
+
+		rb_value = rb_ary_to_ary(rb_value);
+		for (i = 0; i < RARRAY_LEN(rb_value); ++i) {
+			VALUE rb_strategy = rb_ary_entry(rb_value, i);
+
+			if (rb_strategy == CSTR2SYM("safe")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_SAFE;
+			} else if (rb_strategy == CSTR2SYM("force")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_FORCE;
+			} else if (rb_strategy == CSTR2SYM("recreate_missing")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_RECREATE_MISSING;
+			} else if (rb_strategy == CSTR2SYM("allow_conflicts")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_ALLOW_CONFLICTS;
+			} else if (rb_strategy == CSTR2SYM("remove_untracked")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_REMOVE_UNTRACKED;
+			} else if (rb_strategy == CSTR2SYM("remove_ignored")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_REMOVE_IGNORED;
+			} else if (rb_strategy == CSTR2SYM("update_only")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_UPDATE_ONLY;
+			} else if (rb_strategy == CSTR2SYM("dont_update_index")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_DONT_UPDATE_INDEX;
+			} else if (rb_strategy == CSTR2SYM("no_refresh")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_NO_REFRESH;
+			} else if (rb_strategy == CSTR2SYM("disable_pathspec_match")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH;
+			} else if (rb_strategy == CSTR2SYM("skip_locked_directories")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES;
+			} else if (rb_strategy == CSTR2SYM("skip_unmerged")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_SKIP_UNMERGED;
+			} else if (rb_strategy == CSTR2SYM("use_ours")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_USE_OURS;
+			} else if (rb_strategy == CSTR2SYM("use_theirs")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_USE_THEIRS;
+			} else if (rb_strategy == CSTR2SYM("update_submodules")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_UPDATE_SUBMODULES;
+			} else if (rb_strategy == CSTR2SYM("update_submodules_if_changed")) {
+				opts->checkout_strategy |= GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED;
+			} else if (rb_strategy != CSTR2SYM("none")) {
+				rb_raise(rb_eArgError, "Unknown checkout strategy");
+			}
+		}
+	}
+
+	if (!NIL_P(rb_value = rb_hash_aref(rb_options, CSTR2SYM("notify_flags")))) {
+		int i;
+
+		rb_value = rb_ary_to_ary(rb_value);
+		for (i = 0; i < RARRAY_LEN(rb_value); ++i) {
+			VALUE rb_notify_flag = rb_ary_entry(rb_value, i);
+
+			if (rb_notify_flag == CSTR2SYM("conflict")) {
+				opts->notify_flags |= GIT_CHECKOUT_NOTIFY_CONFLICT;
+			} else if (rb_notify_flag == CSTR2SYM("dirty")) {
+				opts->notify_flags |= GIT_CHECKOUT_NOTIFY_DIRTY;
+			} else if (rb_notify_flag == CSTR2SYM("updated")) {
+				opts->notify_flags |= GIT_CHECKOUT_NOTIFY_UPDATED;
+			} else if (rb_notify_flag == CSTR2SYM("untracked")) {
+				opts->notify_flags |= GIT_CHECKOUT_NOTIFY_UNTRACKED;
+			} else if (rb_notify_flag == CSTR2SYM("ignored")) {
+				opts->notify_flags |= GIT_CHECKOUT_NOTIFY_IGNORED;
+			} else if (rb_notify_flag == CSTR2SYM("all")) {
+				opts->notify_flags |= GIT_CHECKOUT_NOTIFY_ALL;
+			} else if (rb_notify_flag != CSTR2SYM("none")) {
+				rb_raise(rb_eArgError, "Unknown checkout notify flag");
+			}
+		}
+	}
+
+	opts->disable_filters = RTEST(rb_hash_aref(rb_options, CSTR2SYM("disable_filters")));
+
+	rb_value = rb_hash_aref(rb_options, CSTR2SYM("dir_mode"));
+	if (!NIL_P(rb_value)) {
+		opts->dir_mode = FIX2UINT(rb_value);
+	}
+
+	rb_value = rb_hash_aref(rb_options, CSTR2SYM("file_mode"));
+	if (!NIL_P(rb_value)) {
+		opts->file_mode = FIX2UINT(rb_value);
+	}
+
+	rb_value = rb_hash_aref(rb_options, CSTR2SYM("file_open_flags"));
+	if (!NIL_P(rb_value)) {
+		opts->file_mode = FIX2INT(rb_value);
+	}
+
+	rb_value = rb_hash_aref(rb_options, CSTR2SYM("target_directory"));
+	if (!NIL_P(rb_value)) {
+		opts->target_directory = StringValueCStr(rb_value);
+	}
+
+	rb_value = rb_hash_aref(rb_options, CSTR2SYM("baseline"));
+	if (!NIL_P(rb_value)) {
+		if (rb_obj_is_kind_of(rb_value, rb_cRuggedTree)) {
+			Data_Get_Struct(rb_value, git_tree, opts->baseline);
+		} else {
+			rb_raise(rb_eTypeError, "Expected a Rugged::Tree.");
+		}
+	}
+
+	rb_value = rb_hash_aref(rb_options, CSTR2SYM("paths"));
+	rugged_rb_ary_to_strarray(rb_value, &opts->paths);
+}
+
+/**
+ *  call-seq:
+ *    repo.checkout_tree(treeish[, options])
+ *
+ *  Updates files in the index and working tree to match the content of the
+ *  tree pointed at by the +treeish+.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :progress ::
+ *    A callback that will be executed for checkout progress notifications.
+ *    Up to 3 parameters are passed on each execution:
+ *
+ *    - The path to the last updated file (or +nil+ on the very first invocation).
+ *    - The number of completed checkout steps.
+ *    - The number of total checkout steps to be performed.
+ *
+ *  :notify ::
+ *    A callback that will be executed for each checkout notification types specified
+ *    with +:notify_flags+. Up to 5 parameters are passed on each execution:
+ *
+ *    - An array containing the +:notify_flags+ that caused the callback execution.
+ *    - The path of the current file.
+ *    - A hash describing the baseline blob (or +nil+ if it does not exist).
+ *    - A hash describing the target blob (or +nil+ if it does not exist).
+ *    - A hash describing the workdir blob (or +nil+ if it does not exist).
+ *
+ *  :strategy ::
+ *    A single symbol or an array of symbols representing the strategies to use when
+ *    performing the checkout. Possible values are:
+ *
+ *    :none ::
+ *      Perform a dry run (default).
+ *
+ *    :safe ::
+ *      Allow safe updates that cannot overwrite uncommitted data.
+ *
+ *    :recreate_missing ::
+ *      Allow checkout to recreate missing files.
+ *
+ *    :force ::
+ *      Allow all updates to force working directory to look like index.
+ *
+ *    :allow_conflicts ::
+ *      Allow checkout to make safe updates even if conflicts are found.
+ *
+ *    :remove_untracked ::
+ *      Remove untracked files not in index (that are not ignored).
+ *
+ *    :remove_ignored ::
+ *      Remove ignored files not in index.
+ *
+ *    :update_only ::
+ *      Only update existing files, don't create new ones.
+ *
+ *    :dont_update_index ::
+ *      Normally checkout updates index entries as it goes; this stops that.
+ *
+ *    :no_refresh ::
+ *      Don't refresh index/config/etc before doing checkout.
+ *
+ *    :disable_pathspec_match ::
+ *      Treat pathspec as simple list of exact match file paths.
+ *
+ *    :skip_locked_directories ::
+ *      Ignore directories in use, they will be left empty.
+ *
+ *    :skip_unmerged ::
+ *      Allow checkout to skip unmerged files (NOT IMPLEMENTED).
+ *
+ *    :use_ours ::
+ *      For unmerged files, checkout stage 2 from index (NOT IMPLEMENTED).
+ *
+ *    :use_theirs ::
+ *      For unmerged files, checkout stage 3 from index (NOT IMPLEMENTED).
+ *
+ *    :update_submodules ::
+ *      Recursively checkout submodules with same options (NOT IMPLEMENTED).
+ *
+ *    :update_submodules_if_changed ::
+ *      Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED).
+ *
+ *  :disable_filters ::
+ *    If +true+, filters like CRLF line conversion will be disabled.
+ *
+ *  :dir_mode ::
+ *    Mode for newly created directories. Default: +0755+.
+ *
+ *  :file_mode ::
+ *    Mode for newly created files. Default: +0755+ or +0644+.
+ *
+ *  :file_open_flags ::
+ *    Mode for opening files. Default: <code>IO::CREAT | IO::TRUNC | IO::WRONLY</code>.
+ *
+ *  :notify_flags ::
+ *    A single symbol or an array of symbols representing the cases in which the +:notify+
+ *    callback should be invoked. Possible values are:
+ *
+ *    :none ::
+ *      Do not invoke the +:notify+ callback (default).
+ *
+ *    :conflict ::
+ *      Invoke the callback for conflicting paths.
+ *
+ *    :dirty ::
+ *      Invoke the callback for "dirty" files, i.e. those that do not need an update but
+ *      no longer match the baseline.
+ *
+ *    :updated ::
+ *      Invoke the callback for any file that was changed.
+ *
+ *    :untracked ::
+ *      Invoke the callback for untracked files.
+ *
+ *    :ignored ::
+ *      Invoke the callback for ignored files.
+ *
+ *    :all ::
+ *      Invoke the callback for all these cases.
+ *
+ *  :paths ::
+ *    A glob string or an array of glob strings specifying which paths should be taken
+ *    into account for the checkout operation. +nil+ will match all files.
+ *    Default: +nil+.
+ *
+ *  :baseline ::
+ *    A Rugged::Tree that represents the current, expected contents of the workdir.
+ *    Default: +HEAD+.
+ *
+ *  :target_directory ::
+ *    A path to an alternative workdir directory in which the checkout should be performed.
+ */
+static VALUE rb_git_checkout_tree(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_treeish, rb_options;
+	git_repository *repo;
+	git_object *treeish;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	struct rugged_cb_payload *payload;
+	int error, exception = 0;
+
+	rb_scan_args(argc, argv, "10:", &rb_treeish, &rb_options);
+
+	if (TYPE(rb_treeish) == T_STRING) {
+		rb_treeish = rugged_object_rev_parse(self, rb_treeish, 1);
+	}
+
+	if (!rb_obj_is_kind_of(rb_treeish, rb_cRuggedCommit) &&
+			!rb_obj_is_kind_of(rb_treeish, rb_cRuggedTag) &&
+			!rb_obj_is_kind_of(rb_treeish, rb_cRuggedTree)) {
+		rb_raise(rb_eTypeError, "Expected Rugged::Commit, Rugged::Tag or Rugged::Tree");
+	}
+
+	Data_Get_Struct(self, git_repository, repo);
+	Data_Get_Struct(rb_treeish, git_object, treeish);
+
+	rugged_parse_checkout_options(&opts, rb_options);
+
+	error = git_checkout_tree(repo, treeish, &opts);
+	xfree(opts.paths.strings);
+
+	if ((payload = opts.notify_payload) != NULL) {
+		exception = payload->exception;
+		xfree(opts.notify_payload);
+	}
+
+	if ((payload = opts.progress_payload) != NULL) {
+		exception = payload->exception;
+		xfree(opts.progress_payload);
+	}
+
+	if (exception)
+		rb_jump_tag(exception);
+
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/**
+ *  call-seq: repo.checkout_index(index[,options]) -> nil
+ *
+ *  Updates files in the index and the working tree to match the content of the
+ *  commit pointed at by +index+.
+ *
+ *  See Repository#checkout_tree for a list of supported +options+.
+ */
+static VALUE rb_git_checkout_index(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_index, rb_options;
+	git_repository *repo;
+	git_index *index;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	struct rugged_cb_payload *payload;
+	int error, exception = 0;
+
+	rb_scan_args(argc, argv, "10:", &rb_index, &rb_options);
+
+	if (!rb_obj_is_kind_of(rb_index, rb_cRuggedIndex))
+		rb_raise(rb_eTypeError, "Expected Rugged::Index");
+
+	Data_Get_Struct(self, git_repository, repo);
+	Data_Get_Struct(rb_index, git_index, index);
+
+	rugged_parse_checkout_options(&opts, rb_options);
+
+	error = git_checkout_index(repo, index, &opts);
+	xfree(opts.paths.strings);
+
+	if ((payload = opts.notify_payload) != NULL) {
+		exception = payload->exception;
+		xfree(opts.notify_payload);
+	}
+
+	if ((payload = opts.progress_payload) != NULL) {
+		exception = payload->exception;
+		xfree(opts.progress_payload);
+	}
+
+	if (exception)
+		rb_jump_tag(exception);
+
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/**
+ *  call-seq: repo.checkout_head([options]) -> nil
+ *
+ *  Updates files in the index and the working tree to match the content of the
+ *  commit pointed at by +HEAD+.
+ *
+ *  See Repository#checkout_tree for a list of supported +options+.
+ */
+static VALUE rb_git_checkout_head(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_options;
+	git_repository *repo;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	struct rugged_cb_payload *payload;
+	int error, exception = 0;
+
+	rb_scan_args(argc, argv, "00:", &rb_options);
+
+	Data_Get_Struct(self, git_repository, repo);
+
+	rugged_parse_checkout_options(&opts, rb_options);
+
+	error = git_checkout_head(repo, &opts);
+	xfree(opts.paths.strings);
+
+	if ((payload = opts.notify_payload) != NULL) {
+		exception = payload->exception;
+		xfree(opts.notify_payload);
+	}
+
+	if ((payload = opts.progress_payload) != NULL) {
+		exception = payload->exception;
+		xfree(opts.progress_payload);
+	}
+
+	if (exception)
+		rb_jump_tag(exception);
+
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    repo.path_ignored?(path) -> true or false
+ *
+ *  Return whether a path is ignored or not.
+ */
+static VALUE rb_git_repo_is_path_ignored(VALUE self, VALUE rb_path) {
+	git_repository *repo;
+	const char *path;
+	int error;
+	int ignored;
+
+	Data_Get_Struct(self, git_repository, repo);
+	path = StringValueCStr(rb_path);
+	error = git_ignore_path_is_ignored(&ignored, repo, path);
+	rugged_exception_check(error);
+	return ignored ? Qtrue : Qfalse;
+}
+
+static void rugged_parse_cherrypick_options(git_cherrypick_options *opts, VALUE rb_options)
+{
+	VALUE rb_value;
+
+	if (NIL_P(rb_options))
+		return;
+
+	Check_Type(rb_options, T_HASH);
+
+	rb_value = rb_hash_aref(rb_options, CSTR2SYM("mainline"));
+	if (!NIL_P(rb_value)) {
+		opts->mainline = FIX2UINT(rb_value);
+	}
+}
+
+static VALUE rugged_create_attr(const char *attr)
+{
+	switch (git_attr_value(attr)) {
+	case GIT_ATTR_TRUE_T:
+		return Qtrue;
+
+	case GIT_ATTR_FALSE_T:
+		return Qfalse;
+
+	case GIT_ATTR_VALUE_T:
+		return rb_str_new2(attr);
+
+	case GIT_ATTR_UNSPECIFIED_T:
+	default:
+		return Qnil;
+	}
+}
+
+static int foreach_attr_hash(const char *name, const char *value, void *payload)
+{
+	VALUE rb_hash = (VALUE)payload;
+	rb_hash_aset(rb_hash, rb_str_new2(name), rugged_create_attr(value));
+	return 0;
+}
+
+static VALUE rb_git_repo_attributes(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_path, rb_names, rb_options;
+
+	git_repository *repo;
+	int error, options = 0;
+
+	rb_scan_args(argc, argv, "12", &rb_path, &rb_names, &rb_options);
+
+	Data_Get_Struct(self, git_repository, repo);
+	Check_Type(rb_path, T_STRING);
+
+	if (!NIL_P(rb_options)) {
+		Check_Type(rb_options, T_FIXNUM);
+		options = FIX2INT(rb_options);
+	}
+
+	switch (TYPE(rb_names)) {
+	case T_ARRAY:
+	{
+		VALUE rb_result;
+		const char **values;
+		const char **names;
+		long i, num_attr = RARRAY_LEN(rb_names);
+
+		if (num_attr > 32)
+			rb_raise(rb_eRuntimeError, "Too many attributes requested");
+
+		values = alloca(num_attr * sizeof(const char *));
+		names = alloca(num_attr * sizeof(const char *));
+
+		for (i = 0; i < num_attr; ++i) {
+			VALUE attr = rb_ary_entry(rb_names, i);
+			Check_Type(attr, T_STRING);
+			names[i] = StringValueCStr(attr);
+		}
+
+		error = git_attr_get_many(
+			values, repo, options,
+			StringValueCStr(rb_path),
+			(size_t)num_attr, names);
+
+		rugged_exception_check(error);
+
+		rb_result = rb_hash_new();
+		for (i = 0; i < num_attr; ++i) {
+			VALUE attr = rb_ary_entry(rb_names, i);
+			rb_hash_aset(rb_result, attr, rugged_create_attr(values[i]));
+		}
+		return rb_result;
+	}
+
+	case T_STRING:
+	{
+		const char *value;
+
+		error = git_attr_get(
+			&value, repo, options,
+			StringValueCStr(rb_path),
+			StringValueCStr(rb_names));
+
+		rugged_exception_check(error);
+
+		return rugged_create_attr(value);
+	}
+
+	case T_NIL:
+	{
+		VALUE rb_result = rb_hash_new();
+
+		error = git_attr_foreach(
+			repo, options,
+			StringValueCStr(rb_path),
+			&foreach_attr_hash,
+			(void *)rb_result);
+
+		rugged_exception_check(error);
+		return rb_result;
+	}
+
+	default:
+		rb_raise(rb_eTypeError,
+			"Invalid attribute name (expected String or Array)");
+	}
+}
+
+/*
+ *  call-seq:
+ *    repo.cherrypick(commit[, options]) -> nil
+ *
+ *  Cherry-pick the given commit and update the index and working
+ *  directory accordingly.
+ *
+ *  `commit` can be either a string containing a commit id or a
+ *  `Rugged::Commit` object.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :mainline ::
+ *    When cherry-picking a merge, you need to specify the parent number
+ *    (starting from 1) which should be considered the mainline.
+ */
+static VALUE rb_git_repo_cherrypick(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_options, rb_commit;
+
+	git_repository *repo;
+	git_commit *commit;
+	git_cherrypick_options opts = GIT_CHERRYPICK_OPTIONS_INIT;
+
+	int error;
+
+	rb_scan_args(argc, argv, "10:", &rb_commit, &rb_options);
+
+	if (TYPE(rb_commit) == T_STRING) {
+		rb_commit = rugged_object_rev_parse(self, rb_commit, 1);
+	}
+
+	if (!rb_obj_is_kind_of(rb_commit, rb_cRuggedCommit)) {
+		rb_raise(rb_eArgError, "Expected a Rugged::Commit.");
+	}
+
+	Data_Get_Struct(self, git_repository, repo);
+	Data_Get_Struct(rb_commit, git_commit, commit);
+
+	rugged_parse_cherrypick_options(&opts, rb_options);
+
+	error = git_cherrypick(repo, commit, &opts);
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+void Init_rugged_repo(void)
+{
+	id_call = rb_intern("call");
+
+	rb_cRuggedRepo = rb_define_class_under(rb_mRugged, "Repository", rb_cObject);
+
+	rb_define_singleton_method(rb_cRuggedRepo, "new", rb_git_repo_new, -1);
+	rb_define_singleton_method(rb_cRuggedRepo, "bare", rb_git_repo_open_bare, -1);
+	rb_define_singleton_method(rb_cRuggedRepo, "hash_data", rb_git_repo_hash,  2);
+	rb_define_singleton_method(rb_cRuggedRepo, "hash_file", rb_git_repo_hashfile,  2);
+	rb_define_singleton_method(rb_cRuggedRepo, "init_at", rb_git_repo_init_at, -1);
+	rb_define_singleton_method(rb_cRuggedRepo, "discover", rb_git_repo_discover, -1);
+	rb_define_singleton_method(rb_cRuggedRepo, "clone_at", rb_git_repo_clone_at, -1);
+
+	rb_define_method(rb_cRuggedRepo, "close", rb_git_repo_close, 0);
+
+	rb_define_method(rb_cRuggedRepo, "exists?", rb_git_repo_exists, 1);
+	rb_define_method(rb_cRuggedRepo, "include?", rb_git_repo_exists, 1);
+	rb_define_method(rb_cRuggedRepo, "expand_oids", rb_git_repo_expand_oids, -1);
+	rb_define_method(rb_cRuggedRepo, "descendant_of?", rb_git_repo_descendant_of, 2);
+
+	rb_define_method(rb_cRuggedRepo, "read",   rb_git_repo_read,   1);
+	rb_define_method(rb_cRuggedRepo, "read_header",   rb_git_repo_read_header,   1);
+	rb_define_method(rb_cRuggedRepo, "write",  rb_git_repo_write,  2);
+	rb_define_method(rb_cRuggedRepo, "each_id",  rb_git_repo_each_id,  0);
+
+	rb_define_method(rb_cRuggedRepo, "path",  rb_git_repo_path, 0);
+	rb_define_method(rb_cRuggedRepo, "workdir",  rb_git_repo_workdir, 0);
+	rb_define_method(rb_cRuggedRepo, "workdir=",  rb_git_repo_set_workdir, 1);
+	rb_define_method(rb_cRuggedRepo, "status",  rb_git_repo_status,  -1);
+
+	rb_define_method(rb_cRuggedRepo, "index",  rb_git_repo_get_index,  0);
+	rb_define_method(rb_cRuggedRepo, "index=",  rb_git_repo_set_index,  1);
+	rb_define_method(rb_cRuggedRepo, "config",  rb_git_repo_get_config,  0);
+	rb_define_method(rb_cRuggedRepo, "config=",  rb_git_repo_set_config,  1);
+
+	rb_define_method(rb_cRuggedRepo, "ident", rb_git_repo_get_ident, 0);
+	rb_define_method(rb_cRuggedRepo, "ident=", rb_git_repo_set_ident, 1);
+
+	rb_define_method(rb_cRuggedRepo, "bare?",  rb_git_repo_is_bare,  0);
+	rb_define_method(rb_cRuggedRepo, "shallow?",  rb_git_repo_is_shallow,  0);
+	rb_define_method(rb_cRuggedRepo, "empty?",  rb_git_repo_is_empty,  0);
+
+	rb_define_method(rb_cRuggedRepo, "head_detached?",  rb_git_repo_head_detached,  0);
+	rb_define_method(rb_cRuggedRepo, "head_unborn?",  rb_git_repo_head_unborn,  0);
+	rb_define_method(rb_cRuggedRepo, "head=", rb_git_repo_set_head, 1);
+	rb_define_method(rb_cRuggedRepo, "head", rb_git_repo_get_head, 0);
+
+	rb_define_method(rb_cRuggedRepo, "merge_base", rb_git_repo_merge_base, -2);
+	rb_define_method(rb_cRuggedRepo, "merge_bases", rb_git_repo_merge_bases, -2);
+
+	rb_define_method(rb_cRuggedRepo, "merge_analysis", rb_git_repo_merge_analysis, -1);
+	rb_define_method(rb_cRuggedRepo, "merge_commits", rb_git_repo_merge_commits, -1);
+
+	rb_define_method(rb_cRuggedRepo, "path_ignored?", rb_git_repo_is_path_ignored, 1);
+
+	rb_define_method(rb_cRuggedRepo, "reset", rb_git_repo_reset, 2);
+	rb_define_method(rb_cRuggedRepo, "reset_path", rb_git_repo_reset_path, -1);
+
+	rb_define_method(rb_cRuggedRepo, "namespace=", rb_git_repo_set_namespace, 1);
+	rb_define_method(rb_cRuggedRepo, "namespace", rb_git_repo_get_namespace, 0);
+
+	rb_define_method(rb_cRuggedRepo, "ahead_behind", rb_git_repo_ahead_behind, 2);
+
+	rb_define_method(rb_cRuggedRepo, "default_signature", rb_git_repo_default_signature, 0);
+
+	rb_define_method(rb_cRuggedRepo, "checkout_tree", rb_git_checkout_tree, -1);
+	rb_define_method(rb_cRuggedRepo, "checkout_index", rb_git_checkout_index, -1);
+	rb_define_method(rb_cRuggedRepo, "checkout_head", rb_git_checkout_head, -1);
+
+	rb_define_method(rb_cRuggedRepo, "cherrypick", rb_git_repo_cherrypick, -1);
+	rb_define_method(rb_cRuggedRepo, "fetch_attributes", rb_git_repo_attributes, -1);
+
+	rb_cRuggedOdbObject = rb_define_class_under(rb_mRugged, "OdbObject", rb_cObject);
+	rb_define_method(rb_cRuggedOdbObject, "data",  rb_git_odbobj_data,  0);
+	rb_define_method(rb_cRuggedOdbObject, "len",  rb_git_odbobj_size,  0);
+	rb_define_method(rb_cRuggedOdbObject, "type",  rb_git_odbobj_type,  0);
+	rb_define_method(rb_cRuggedOdbObject, "oid",  rb_git_odbobj_oid,  0);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_revwalk.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_revwalk.c
new file mode 100755
index 0000000..3c1ef50
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_revwalk.c
@@ -0,0 +1,495 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedObject;
+VALUE rb_cRuggedWalker;
+
+static void rb_git_walk__free(git_revwalk *walk)
+{
+	git_revwalk_free(walk);
+}
+
+VALUE rugged_walker_new(VALUE klass, VALUE owner, git_revwalk *walk)
+{
+	VALUE rb_walk = Data_Wrap_Struct(klass, NULL, &rb_git_walk__free, walk);
+	rugged_set_owner(rb_walk, owner);
+	return rb_walk;
+}
+
+static void push_commit_oid(git_revwalk *walk, const git_oid *oid, int hide)
+{
+	int error;
+	if (hide) error = git_revwalk_hide(walk, oid);
+	else error = git_revwalk_push(walk, oid);
+	rugged_exception_check(error);
+}
+
+static void push_commit_ref(git_revwalk *walk, const char *ref, int hide)
+{
+	int error;
+	if (hide) error = git_revwalk_hide_ref(walk, ref);
+	else error = git_revwalk_push_ref(walk, ref);
+	rugged_exception_check(error);
+}
+
+static void push_commit_1(git_revwalk *walk, VALUE rb_commit, int hide)
+{
+	if (rb_obj_is_kind_of(rb_commit, rb_cRuggedObject)) {
+		git_object *object;
+		Data_Get_Struct(rb_commit, git_object, object);
+
+		push_commit_oid(walk, git_object_id(object), hide);
+		return;
+	}
+
+	Check_Type(rb_commit, T_STRING);
+
+	if (RSTRING_LEN(rb_commit) == 40) {
+		git_oid commit_oid;
+		if (git_oid_fromstr(&commit_oid, RSTRING_PTR(rb_commit)) == 0) {
+			push_commit_oid(walk, &commit_oid, hide);
+			return;
+		}
+	}
+
+	push_commit_ref(walk, StringValueCStr(rb_commit), hide);
+}
+
+static void push_commit(git_revwalk *walk, VALUE rb_commit, int hide)
+{
+	if (rb_type(rb_commit) == T_ARRAY) {
+		long i;
+		for (i = 0; i < RARRAY_LEN(rb_commit); ++i)
+			push_commit_1(walk, rb_ary_entry(rb_commit, i), hide);
+
+		return;
+	}
+
+	push_commit_1(walk, rb_commit, hide);
+}
+
+/*
+ *  call-seq:
+ *    Walker.new(repository) -> walker
+ *
+ *  Create a new +Walker+ instance able to walk commits found
+ *  in +repository+, which is a <tt>Rugged::Repository</tt> instance.
+ */
+static VALUE rb_git_walker_new(VALUE klass, VALUE rb_repo)
+{
+	git_repository *repo;
+	git_revwalk *walk;
+	int error;
+
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_revwalk_new(&walk, repo);
+	rugged_exception_check(error);
+
+	return rugged_walker_new(klass, rb_repo, walk);;
+}
+
+/*
+ *  call-seq:
+ *    walker.push(commit) -> nil
+ *
+ *  Push one new +commit+ to start the walk from. +commit+ must be a
+ *  +String+ with the OID of a commit in the repository, or a <tt>Rugged::Commit</tt>
+ *  instance.
+ *
+ *  More than one commit may be pushed to the walker (to walk several
+ *  branches simulataneously).
+ *
+ *  Duplicate pushed commits will be ignored; at least one commit must have been
+ *  pushed as a starting point before the walk can begin.
+ *
+ *    walker.push("92b22bbcb37caf4f6f53d30292169e84f5e4283b")
+ */
+static VALUE rb_git_walker_push(VALUE self, VALUE rb_commit)
+{
+	git_revwalk *walk;
+	Data_Get_Struct(self, git_revwalk, walk);
+	push_commit(walk, rb_commit, 0);
+	return Qnil;
+}
+
+static VALUE rb_git_walker_push_range(VALUE self, VALUE range)
+{
+	git_revwalk *walk;
+	Data_Get_Struct(self, git_revwalk, walk);
+	rugged_exception_check(git_revwalk_push_range(walk, StringValueCStr(range)));
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    walker.hide(commit) -> nil
+ *
+ *  Hide the given +commit+ (and all its parents) from the
+ *  output in the revision walk.
+ */
+static VALUE rb_git_walker_hide(VALUE self, VALUE rb_commit)
+{
+	git_revwalk *walk;
+	Data_Get_Struct(self, git_revwalk, walk);
+	push_commit(walk, rb_commit, 1);
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    walker.sorting(sort_mode) -> nil
+ *
+ *  Change the sorting mode for the revision walk.
+ *
+ *  This will cause +walker+ to be reset.
+ */
+static VALUE rb_git_walker_sorting(VALUE self, VALUE ruby_sort_mode)
+{
+	git_revwalk *walk;
+	Data_Get_Struct(self, git_revwalk, walk);
+	git_revwalk_sorting(walk, FIX2INT(ruby_sort_mode));
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    walker.simplify_first_parent() -> nil
+ *
+ *  Simplify the walk to the first parent of each commit.
+ */
+static VALUE rb_git_walker_simplify_first_parent(VALUE self)
+{
+	git_revwalk *walk;
+	Data_Get_Struct(self, git_revwalk, walk);
+	git_revwalk_simplify_first_parent(walk);
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    walker.reset -> nil
+ *
+ *  Remove all pushed and hidden commits and reset the +walker+
+ *  back into a blank state.
+ */
+static VALUE rb_git_walker_reset(VALUE self)
+{
+	git_revwalk *walk;
+	Data_Get_Struct(self, git_revwalk, walk);
+	git_revwalk_reset(walk);
+	return Qnil;
+}
+
+struct walk_options {
+	VALUE rb_owner;
+	VALUE rb_options;
+
+	git_repository *repo;
+	git_revwalk *walk;
+	int oid_only;
+	uint64_t offset, limit;
+};
+
+static void load_walk_limits(struct walk_options *w, VALUE rb_options)
+{
+	VALUE rb_value = rb_hash_lookup(rb_options, CSTR2SYM("offset"));
+	if (!NIL_P(rb_value)) {
+		Check_Type(rb_value, T_FIXNUM);
+		w->offset = FIX2ULONG(rb_value);
+	}
+
+	rb_value = rb_hash_lookup(rb_options, CSTR2SYM("limit"));
+	if (!NIL_P(rb_value)) {
+		Check_Type(rb_value, T_FIXNUM);
+		w->limit = FIX2ULONG(rb_value);
+	}
+}
+
+static VALUE load_all_options(VALUE _payload)
+{
+	struct walk_options *w = (struct walk_options *)_payload;
+	VALUE rb_options = w->rb_options;
+	VALUE rb_show, rb_hide, rb_sort, rb_simp, rb_oid_only;
+
+	load_walk_limits(w, rb_options);
+
+	rb_sort = rb_hash_lookup(rb_options, CSTR2SYM("sort"));
+	if (!NIL_P(rb_sort)) {
+		Check_Type(rb_sort, T_FIXNUM);
+		git_revwalk_sorting(w->walk, FIX2INT(rb_sort));
+	}
+
+	rb_show = rb_hash_lookup(rb_options, CSTR2SYM("show"));
+	if (!NIL_P(rb_show)) {
+		push_commit(w->walk, rb_show, 0);
+	}
+
+	rb_hide = rb_hash_lookup(rb_options, CSTR2SYM("hide"));
+	if (!NIL_P(rb_hide)) {
+		push_commit(w->walk, rb_hide, 1);
+	}
+
+	rb_simp = rb_hash_lookup(rb_options, CSTR2SYM("simplify"));
+	if (RTEST(rb_simp)) {
+		git_revwalk_simplify_first_parent(w->walk);
+	}
+
+	rb_oid_only = rb_hash_lookup(rb_options, CSTR2SYM("oid_only"));
+	if (RTEST(rb_oid_only)) {
+		w->oid_only = 1;
+	}
+
+	return Qnil;
+}
+
+static VALUE do_walk(VALUE _payload)
+{
+	struct walk_options *w = (struct walk_options *)_payload;
+	int error;
+	git_oid commit_oid;
+
+	while ((error = git_revwalk_next(&commit_oid, w->walk)) == 0) {
+		if (w->offset > 0) {
+			w->offset--;
+			continue;
+		}
+
+		if (w->oid_only) {
+			rb_yield(rugged_create_oid(&commit_oid));
+		} else {
+			git_commit *commit;
+
+			error = git_commit_lookup(&commit, w->repo, &commit_oid);
+			rugged_exception_check(error);
+
+			rb_yield(
+				rugged_object_new(w->rb_owner, (git_object *)commit)
+			);
+		}
+
+		if (--w->limit == 0)
+			break;
+	}
+
+	if (error != GIT_ITEROVER)
+		rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    Rugged::Walker.walk(repo, options={}) { |commit| block }
+ *
+ *	Create a Walker object, initialize it with the given options
+ *	and perform a walk on the repository; the lifetime of the
+ *	walker is bound to the call and it is immediately cleaned
+ *	up after the walk is over.
+ *
+ *	The following options are available:
+ *
+ *	- +sort+: Sorting mode for the walk (or an OR combination
+ *	of several sorting modes).
+ *
+ *	- +show+: Tips of the repository that will be walked;
+ *	this is necessary for the walk to yield any results.
+ *	A tip can be a 40-char object ID, an existing +Rugged::Commit+
+ *	object, a reference, or an +Array+ of several of these
+ *	(if you'd like to walk several tips in parallel).
+ *
+ *	- +hide+: Same as +show+, but hides the given tips instead
+ *	so they don't appear on the walk.
+ *
+ *	- +oid_only+: if +true+, the walker will yield 40-char OIDs
+ *	for each commit, instead of real +Rugged::Commit+ objects.
+ *	Defaults to +false+.
+ *
+ *	- +simplify+: if +true+, the walk will be simplified
+ *	to the first parent of each commit.
+ *
+ *	Example:
+ *
+ *    Rugged::Walker.walk(repo,
+ *		show: "92b22bbcb37caf4f6f53d30292169e84f5e4283b",
+ *		sort: Rugged::SORT_DATE|Rugged::SORT_TOPO,
+ *		oid_only: true) do |commit_oid|
+ *			puts commit_oid
+ *		end
+ *
+ *  generates:
+ *
+ *    92b22bbcb37caf4f6f53d30292169e84f5e4283b
+ *    6b750d5800439b502de669465b385e5f469c78b6
+ *    ef9207141549f4ffcd3c4597e270d32e10d0a6bc
+ *    cb75e05f0f8ac3407fb3bd0ebd5ff07573b16c9f
+ *    ...
+ */
+static VALUE rb_git_walk(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_repo, rb_options;
+	struct walk_options w;
+	int exception = 0;
+
+	rb_scan_args(argc, argv, "10:", &rb_repo, &rb_options);
+
+	if (!rb_block_given_p()) {
+		ID iter_method = ID2SYM(rb_intern("walk"));
+		return rb_funcall(self, rb_intern("to_enum"), 3,
+			iter_method, rb_repo, rb_options);
+	}
+
+	Data_Get_Struct(rb_repo, git_repository, w.repo);
+	rugged_exception_check(git_revwalk_new(&w.walk, w.repo));
+
+	w.rb_owner = rb_repo;
+	w.rb_options = rb_options;
+
+	w.oid_only = 0;
+	w.offset = 0;
+	w.limit = UINT64_MAX;
+
+	if (!NIL_P(w.rb_options))
+		rb_protect(load_all_options, (VALUE)&w, &exception);
+
+	if (!exception)
+		rb_protect(do_walk, (VALUE)&w, &exception);
+
+	git_revwalk_free(w.walk);
+
+	if (exception)
+		rb_jump_tag(exception);
+
+	return Qnil;
+}
+
+static VALUE rb_git_walk_with_opts(int argc, VALUE *argv, VALUE self, int oid_only)
+{
+	VALUE rb_options;
+	struct walk_options w;
+
+	rb_scan_args(argc, argv, "01", &rb_options);
+
+	if (!rb_block_given_p()) {
+		ID iter_method = ID2SYM(rb_intern(oid_only ? "each_oid" : "each"));
+		return rb_funcall(self, rb_intern("to_enum"), 2, iter_method, rb_options);
+	}
+
+	Data_Get_Struct(self, git_revwalk, w.walk);
+	w.repo = git_revwalk_repository(w.walk);
+
+	w.rb_owner = rugged_owner(self);
+	w.rb_options = Qnil;
+
+	w.oid_only = oid_only;
+	w.offset = 0;
+	w.limit = UINT64_MAX;
+
+	if (!NIL_P(rb_options))
+		load_walk_limits(&w, rb_options);
+
+	return do_walk((VALUE)&w);
+}
+
+/*
+ *  call-seq:
+ *    walker.each { |commit| block }
+ *    walker.each -> Iterator
+ *
+ *  Perform the walk through the repository, yielding each
+ *  one of the commits found as a <tt>Rugged::Commit</tt> instance
+ *  to +block+.
+ *
+ *  If no +block+ is given, an +Iterator+ will be returned.
+ *
+ *  The walker must have been previously set-up before a walk can be performed
+ *  (i.e. at least one commit must have been pushed).
+ *
+ *    walker.push("92b22bbcb37caf4f6f53d30292169e84f5e4283b")
+ *    walker.each { |commit| puts commit.oid }
+ *
+ *  generates:
+ *
+ *    92b22bbcb37caf4f6f53d30292169e84f5e4283b
+ *    6b750d5800439b502de669465b385e5f469c78b6
+ *    ef9207141549f4ffcd3c4597e270d32e10d0a6bc
+ *    cb75e05f0f8ac3407fb3bd0ebd5ff07573b16c9f
+ *    ...
+ */
+static VALUE rb_git_walker_each(int argc, VALUE *argv, VALUE self)
+{
+	return rb_git_walk_with_opts(argc, argv, self, 0);
+}
+
+/*
+ *  call-seq:
+ *    walker.each_oid { |commit| block }
+ *    walker.each_oid -> Iterator
+ *
+ *  Perform the walk through the repository, yielding each
+ *  one of the commit oids found as a <tt>String</tt>
+ *  to +block+.
+ *
+ *  If no +block+ is given, an +Iterator+ will be returned.
+ *
+ *  The walker must have been previously set-up before a walk can be performed
+ *  (i.e. at least one commit must have been pushed).
+ *
+ *    walker.push("92b22bbcb37caf4f6f53d30292169e84f5e4283b")
+ *    walker.each { |commit_oid| puts commit_oid }
+ *
+ *  generates:
+ *
+ *    92b22bbcb37caf4f6f53d30292169e84f5e4283b
+ *    6b750d5800439b502de669465b385e5f469c78b6
+ *    ef9207141549f4ffcd3c4597e270d32e10d0a6bc
+ *    cb75e05f0f8ac3407fb3bd0ebd5ff07573b16c9f
+ *    ...
+ */
+static VALUE rb_git_walker_each_oid(int argc, VALUE *argv, VALUE self)
+{
+	return rb_git_walk_with_opts(argc, argv, self, 1);
+}
+
+
+
+void Init_rugged_revwalk(void)
+{
+	rb_cRuggedWalker = rb_define_class_under(rb_mRugged, "Walker", rb_cObject);
+	rb_define_singleton_method(rb_cRuggedWalker, "new", rb_git_walker_new, 1);
+	rb_define_singleton_method(rb_cRuggedWalker, "walk", rb_git_walk, -1);
+
+	rb_define_method(rb_cRuggedWalker, "push", rb_git_walker_push, 1);
+	rb_define_method(rb_cRuggedWalker, "push_range", rb_git_walker_push_range, 1);
+	rb_define_method(rb_cRuggedWalker, "each", rb_git_walker_each, -1);
+	rb_define_method(rb_cRuggedWalker, "each_oid", rb_git_walker_each_oid, -1);
+	rb_define_method(rb_cRuggedWalker, "walk", rb_git_walker_each, -1);
+	rb_define_method(rb_cRuggedWalker, "hide", rb_git_walker_hide, 1);
+	rb_define_method(rb_cRuggedWalker, "reset", rb_git_walker_reset, 0);
+	rb_define_method(rb_cRuggedWalker, "sorting", rb_git_walker_sorting, 1);
+	rb_define_method(rb_cRuggedWalker, "simplify_first_parent", rb_git_walker_simplify_first_parent, 0);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_settings.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_settings.c
new file mode 100755
index 0000000..4eb6eae
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_settings.c
@@ -0,0 +1,155 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+#if !defined(NUM2SIZET)
+#  if SIZEOF_SIZE_T == SIZEOF_LONG
+#    define NUM2SIZET(n) ((size_t)NUM2ULONG(n))
+#    define SIZET2NUM(n) ((size_t)ULONG2NUM(n))
+#  else
+#    define NUM2SIZET(n) ((size_t)NUM2ULL(n))
+#    define SIZET2NUM(n) ((size_t)ULL2NUM(n))
+#  endif
+#endif /* ! defined(NUM2SIZET) */
+
+extern VALUE rb_mRugged;
+
+static void set_search_path(int level, VALUE value)
+{
+	const char *path;
+
+	Check_Type(value, T_STRING);
+	path = StringValueCStr(value);
+
+	rugged_exception_check(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, level, path));
+}
+
+static VALUE get_search_path(int level)
+{
+	git_buf buf = {NULL};
+	VALUE ret;
+
+	rugged_exception_check(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, level, &buf));
+
+	ret = rb_str_new_utf8(buf.ptr);
+	git_buf_free(&buf);
+
+	return ret;
+}
+
+/*
+ *  call-seq:
+ *    Settings[option] = value
+ *
+ *  Sets a libgit2 library option.
+ */
+static VALUE rb_git_set_option(VALUE self, VALUE option, VALUE value)
+{
+	const char *opt;
+
+	Check_Type(option, T_STRING);
+	opt = StringValueCStr(option);
+
+	if (strcmp(opt, "mwindow_size") == 0) {
+		size_t val;
+		Check_Type(value, T_FIXNUM);
+		val = NUM2SIZET(value);
+		git_libgit2_opts(GIT_OPT_SET_MWINDOW_SIZE, val);
+	}
+
+	else if (strcmp(opt, "mwindow_mapped_limit") == 0) {
+		size_t val;
+		Check_Type(value, T_FIXNUM);
+		val = NUM2SIZET(value);
+		git_libgit2_opts(GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, val);
+	}
+
+	else if (strcmp(opt, "search_path_global") == 0) {
+		set_search_path(GIT_CONFIG_LEVEL_GLOBAL, value);
+	}
+
+	else if (strcmp(opt, "search_path_xdg") == 0) {
+		set_search_path(GIT_CONFIG_LEVEL_XDG, value);
+	}
+
+	else if (strcmp(opt, "search_path_system") == 0) {
+		set_search_path(GIT_CONFIG_LEVEL_SYSTEM, value);
+	}
+
+	else {
+		rb_raise(rb_eArgError, "Unknown option specified");
+	}
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    Settings[option] -> value
+ *
+ *  Gets the value of a libgit2 library option.
+ */
+static VALUE rb_git_get_option(VALUE self, VALUE option)
+{
+	const char *opt;
+
+	Check_Type(option, T_STRING);
+	opt = StringValueCStr(option);
+
+	if (strcmp(opt, "mwindow_size") == 0) {
+		size_t val;
+		git_libgit2_opts(GIT_OPT_GET_MWINDOW_SIZE, &val);
+		return SIZET2NUM(val);
+	}
+
+	else if (strcmp(opt, "mwindow_mapped_limit") == 0) {
+		size_t val;
+		git_libgit2_opts(GIT_OPT_GET_MWINDOW_MAPPED_LIMIT, &val);
+		return SIZET2NUM(val);
+	}
+
+	else if (strcmp(opt, "search_path_global") == 0) {
+		return get_search_path(GIT_CONFIG_LEVEL_GLOBAL);
+	}
+
+	else if (strcmp(opt, "search_path_xdg") == 0) {
+		return get_search_path(GIT_CONFIG_LEVEL_XDG);
+	}
+
+	else if (strcmp(opt, "search_path_system") == 0) {
+		return get_search_path(GIT_CONFIG_LEVEL_SYSTEM);
+	}
+
+	else {
+		rb_raise(rb_eArgError, "Unknown option specified");
+	}
+}
+
+void Init_rugged_settings(void)
+{
+	VALUE rb_cRuggedSettings = rb_define_class_under(rb_mRugged, "Settings", rb_cObject);
+	rb_define_module_function(rb_cRuggedSettings, "[]=", rb_git_set_option, 2);
+	rb_define_module_function(rb_cRuggedSettings, "[]", rb_git_get_option, 1);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_signature.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_signature.c
new file mode 100755
index 0000000..3b4daec
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_signature.c
@@ -0,0 +1,106 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+VALUE rugged_signature_new(const git_signature *sig, const char *encoding_name)
+{
+	VALUE rb_sig, rb_time;
+	rb_encoding *encoding = rb_utf8_encoding();
+
+	if (encoding_name != NULL)
+		encoding = rb_enc_find(encoding_name);
+
+	rb_sig = rb_hash_new();
+
+	/* Allocate the time with a the given timezone */
+	rb_time = rb_funcall(
+		rb_time_new(sig->when.time, 0),
+		rb_intern("getlocal"), 1,
+		INT2FIX(sig->when.offset * 60)
+	);
+
+	rb_hash_aset(rb_sig, CSTR2SYM("name"),
+		rb_enc_str_new(sig->name, strlen(sig->name), encoding));
+
+	rb_hash_aset(rb_sig, CSTR2SYM("email"),
+		rb_enc_str_new(sig->email, strlen(sig->email), encoding));
+
+	rb_hash_aset(rb_sig, CSTR2SYM("time"), rb_time);
+
+	return rb_sig;
+}
+
+git_signature *rugged_signature_get(VALUE rb_sig, git_repository *repo)
+{
+	int error;
+	VALUE rb_time, rb_unix_t, rb_offset, rb_name, rb_email, rb_time_offset;
+	git_signature *sig;
+
+	if (NIL_P(rb_sig)) {
+		rugged_exception_check(
+			git_signature_default(&sig, repo)
+		);
+		return sig;
+	}
+
+	Check_Type(rb_sig, T_HASH);
+
+	rb_name = rb_hash_aref(rb_sig, CSTR2SYM("name"));
+	rb_email = rb_hash_aref(rb_sig, CSTR2SYM("email"));
+	rb_time = rb_hash_aref(rb_sig, CSTR2SYM("time"));
+	rb_time_offset = rb_hash_aref(rb_sig, CSTR2SYM("time_offset"));
+
+	Check_Type(rb_name, T_STRING);
+	Check_Type(rb_email, T_STRING);
+
+
+	if (NIL_P(rb_time)) {
+		error = git_signature_now(&sig,
+				StringValueCStr(rb_name),
+				StringValueCStr(rb_email));
+	} else {
+		if (!rb_obj_is_kind_of(rb_time, rb_cTime))
+			rb_raise(rb_eTypeError, "expected Time object");
+
+		rb_unix_t = rb_funcall(rb_time, rb_intern("tv_sec"), 0);
+
+		if (NIL_P(rb_time_offset)) {
+			rb_offset = rb_funcall(rb_time, rb_intern("utc_offset"), 0);
+		} else {
+			Check_Type(rb_time_offset, T_FIXNUM);
+			rb_offset = rb_time_offset;
+		}
+
+		error = git_signature_new(&sig,
+				StringValueCStr(rb_name),
+				StringValueCStr(rb_email),
+				NUM2LONG(rb_unix_t),
+				FIX2INT(rb_offset) / 60);
+	}
+
+	rugged_exception_check(error);
+
+	return sig;
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_submodule.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_submodule.c
new file mode 100755
index 0000000..2c9b0c1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_submodule.c
@@ -0,0 +1,852 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+extern VALUE rb_mRugged;
+VALUE rb_cRuggedSubmodule;
+
+static VALUE id_in_head, id_in_index, id_in_config, id_in_workdir;
+static VALUE id_index_added, id_index_deleted, id_index_modified;
+static VALUE id_wd_uninitialized, id_wd_added, id_wd_deleted, id_wd_modified;
+static VALUE id_wd_index_modified, id_wd_wd_modified, id_wd_untracked;
+
+static ID id_ignore_none, id_ignore_untracked, id_ignore_dirty, id_ignore_all;
+
+static ID id_update_checkout, id_update_rebase, id_update_merge, id_update_none;
+
+void init_status_list(void)
+{
+	id_in_head            = CSTR2SYM("in_head");
+	id_in_index           = CSTR2SYM("in_index");
+	id_in_config          = CSTR2SYM("in_config");
+	id_in_workdir         = CSTR2SYM("in_workdir");
+	id_index_added        = CSTR2SYM("added_to_index");
+	id_index_deleted      = CSTR2SYM("deleted_from_index");
+	id_index_modified     = CSTR2SYM("modified_in_index");
+	id_wd_uninitialized   = CSTR2SYM("uninitialized");
+	id_wd_added           = CSTR2SYM("added_to_workdir");
+	id_wd_deleted         = CSTR2SYM("deleted_from_workdir");
+	id_wd_modified        = CSTR2SYM("modified_in_workdir");
+	id_wd_index_modified  = CSTR2SYM("dirty_workdir_index");
+	id_wd_wd_modified     = CSTR2SYM("modified_files_in_workdir");
+	id_wd_untracked       = CSTR2SYM("untracked_files_in_workdir");
+
+	return;
+}
+
+static VALUE submodule_status_flags_to_rb(unsigned int flags)
+{
+	VALUE rb_flags = rb_ary_new();
+
+	if (flags & GIT_SUBMODULE_STATUS_IN_HEAD)
+		rb_ary_push(rb_flags, id_in_head);
+
+	if (flags & GIT_SUBMODULE_STATUS_IN_INDEX)
+		rb_ary_push(rb_flags, id_in_index);
+
+	if (flags & GIT_SUBMODULE_STATUS_IN_CONFIG)
+		rb_ary_push(rb_flags, id_in_config);
+
+	if (flags & GIT_SUBMODULE_STATUS_IN_WD)
+		rb_ary_push(rb_flags, id_in_workdir);
+
+	if (flags & GIT_SUBMODULE_STATUS_INDEX_ADDED)
+		rb_ary_push(rb_flags, id_index_added);
+
+	if (flags & GIT_SUBMODULE_STATUS_INDEX_DELETED)
+		rb_ary_push(rb_flags, id_index_deleted);
+
+	if (flags & GIT_SUBMODULE_STATUS_INDEX_MODIFIED)
+		rb_ary_push(rb_flags, id_index_modified);
+
+	if (flags & GIT_SUBMODULE_STATUS_WD_UNINITIALIZED)
+		rb_ary_push(rb_flags, id_wd_uninitialized);
+
+	if (flags & GIT_SUBMODULE_STATUS_WD_ADDED)
+		rb_ary_push(rb_flags, id_wd_added);
+
+	if (flags & GIT_SUBMODULE_STATUS_WD_DELETED)
+		rb_ary_push(rb_flags, id_wd_deleted);
+
+	if (flags & GIT_SUBMODULE_STATUS_WD_MODIFIED)
+		rb_ary_push(rb_flags, id_wd_modified);
+
+	if (flags & GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED)
+		rb_ary_push(rb_flags, id_wd_index_modified);
+
+	if (flags & GIT_SUBMODULE_STATUS_WD_WD_MODIFIED)
+		rb_ary_push(rb_flags, id_wd_wd_modified);
+
+	if (flags & GIT_SUBMODULE_STATUS_WD_UNTRACKED)
+		rb_ary_push(rb_flags, id_wd_untracked);
+
+	return rb_flags;
+}
+
+/*
+ *  call-seq:
+ *    submodule.status -> array
+ *
+ *  Returns an +array+ with the status flags for a submodule.
+ *
+ *  Depending on the #ignore_rule property of the submodule, some of
+ *  the flags may never be returned because they indicate changes that are
+ *  supposed to be ignored.
+ *
+ *  Submodule info is contained in 4 places: the +HEAD+ tree, the index,
+ *  config files (both +.git/config+ and +.gitmodules+), and the working
+ *  directory. Any or all of those places might be missing information about
+ *  the submodule depending on what state the repository is in. We consider
+ *  all four places to build the combination of status flags.
+ *
+ *  There are four values that are not really status, but give basic info
+ *  about what sources of submodule data are available. These will be
+ *  returned even if ignore is set to +:all+.
+ *
+ *  :in_head ::
+ *    superproject +HEAD+ contains submodule
+ *  :in_index ::
+ *    superproject index contains submodule
+ *  :in_config ::
+ *    superproject +.gitmodules+ has submodule
+ *  :in_workdir ::
+ *    superproject workdir has submodule
+ *
+ *  The following values will be returned as long as ignore is not +:all+.
+ *
+ *  :added_to_index ::
+ *    submodule is in index, not in +HEAD+
+ *  :deleted_from_index ::
+ *    submodule is in +HEAD+, not in index
+ *  :modified_in_index ::
+ *    submodule in index and +HEAD+ don't match
+ *  :uninitialized ::
+ *    submodule in workdir is not initialized
+ *  :added_to_workdir ::
+ *    submodule is in workdir, not index
+ *  :deleted_from_workdir ::
+ *    submodule is in index, not workdir
+ *  :modified_in_workdir ::
+ *    submodule in index and workdir +HEAD+ don't match
+ *
+ *  The following can only be returned if ignore is +:none+ or +:untracked+.
+ *
+ *  :dirty_workdir_index ::
+ *    submodule workdir index is dirty
+ *  :modified_files_in_workdir ::
+ *    submodule workdir has modified files
+ *
+ *  Lastly, the following will only be returned for ignore +:none+.
+ *
+ *  :untracked_files_in_workdir ::
+ *    submodule workdir contains untracked files
+ */
+static VALUE rb_git_submodule_status(VALUE self)
+{
+	VALUE rb_repo = rugged_owner(self);
+	git_submodule *submodule;
+	git_repository *repo;
+	unsigned int flags;
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+	Data_Get_Struct(self, git_submodule, submodule);
+
+	rugged_exception_check(
+		git_submodule_status(&flags, repo, git_submodule_name(submodule),
+			GIT_SUBMODULE_IGNORE_UNSPECIFIED)
+	);
+
+	return submodule_status_flags_to_rb(flags);
+
+}
+
+#define RB_GIT_SUBMODULE_LOCATION_FLAG_CHECK(flag) \
+	git_submodule *submodule; \
+	unsigned int flags; \
+	Data_Get_Struct(self, git_submodule, submodule); \
+	rugged_exception_check( \
+		git_submodule_location(&flags, submodule) \
+	); \
+	return (flags & flag) ? Qtrue : Qfalse; \
+
+/*
+ *  call-seq:
+ *    submodule.in_head? -> true or false
+ *
+ *  Returns +true+ if superproject +HEAD+ contains submodule.
+ */
+static VALUE rb_git_submodule_status_in_head(VALUE self)
+{
+	RB_GIT_SUBMODULE_LOCATION_FLAG_CHECK(GIT_SUBMODULE_STATUS_IN_HEAD)
+}
+
+/*
+ *  call-seq:
+ *    submodule.in_index? -> true or false
+ *
+ *  Returns +true+ if superproject index contains submodule.
+ */
+static VALUE rb_git_submodule_status_in_index(VALUE self)
+{
+	RB_GIT_SUBMODULE_LOCATION_FLAG_CHECK(GIT_SUBMODULE_STATUS_IN_INDEX)
+}
+
+/*
+ *  call-seq:
+ *    submodule.in_config? -> true or false
+ *
+ *  Returns +true+ if superproject +.gitmodules+ has submodule.
+ */
+static VALUE rb_git_submodule_status_in_config(VALUE self)
+{
+	RB_GIT_SUBMODULE_LOCATION_FLAG_CHECK(GIT_SUBMODULE_STATUS_IN_CONFIG)
+}
+
+/*
+ *  call-seq:
+ *    submodule.in_workdir? -> true or false
+ *
+ *  Returns +true+ if superproject workdir has submodule.
+ */
+static VALUE rb_git_submodule_status_in_workdir(VALUE self)
+{
+	RB_GIT_SUBMODULE_LOCATION_FLAG_CHECK(GIT_SUBMODULE_STATUS_IN_WD)
+}
+
+#define RB_GIT_SUBMODULE_STATUS_FLAG_CHECK(flag) \
+	VALUE rb_repo = rugged_owner(self); \
+	git_repository *repo; \
+	git_submodule *submodule; \
+	unsigned int flags; \
+	rugged_check_repo(rb_repo); \
+	Data_Get_Struct(rb_repo, git_repository, repo); \
+	Data_Get_Struct(self, git_submodule, submodule); \
+	rugged_exception_check( \
+		git_submodule_status(&flags, repo, git_submodule_name(submodule), \
+			GIT_SUBMODULE_IGNORE_UNSPECIFIED) \
+	); \
+	return (flags & flag) ? Qtrue : Qfalse; \
+
+/*
+ *  call-seq:
+ *    submodule.added_to_index? -> true or false
+ *
+ *  Returns +true+ if submodule is in index, not in +HEAD+.
+ */
+static VALUE rb_git_submodule_status_added_to_index(VALUE self)
+{
+	RB_GIT_SUBMODULE_STATUS_FLAG_CHECK(GIT_SUBMODULE_STATUS_INDEX_ADDED)
+}
+
+/*
+ *  call-seq:
+ *    submodule.deleted_from_index? -> true or false
+ *
+ *  Returns +true+ if submodule is in +HEAD+, not in index
+ */
+static VALUE rb_git_submodule_status_deleted_from_index(VALUE self)
+{
+	RB_GIT_SUBMODULE_STATUS_FLAG_CHECK(GIT_SUBMODULE_STATUS_INDEX_DELETED)
+}
+
+/*
+ *  call-seq:
+ *    submodule.modified_in_index? -> true or false
+ *
+ *  Returns +true+ if submodule in index and +HEAD+ don't match.
+ */
+static VALUE rb_git_submodule_status_modified_in_index(VALUE self)
+{
+	RB_GIT_SUBMODULE_STATUS_FLAG_CHECK(GIT_SUBMODULE_STATUS_INDEX_MODIFIED)
+}
+
+/*
+ *  call-seq:
+ *    submodule.uninitialized? -> true or false
+ *
+ *  Returns +true+ if submodule in workdir is not initialized.
+ */
+static VALUE rb_git_submodule_status_uninitialized(VALUE self)
+{
+	RB_GIT_SUBMODULE_STATUS_FLAG_CHECK(GIT_SUBMODULE_STATUS_WD_UNINITIALIZED)
+}
+
+/*
+ *  call-seq:
+ *    submodule.added_to_workdir? -> true or false
+ *
+ *  Returns +true+ if submodule is in workdir, not index.
+ */
+static VALUE rb_git_submodule_status_added_to_workdir(VALUE self)
+{
+	RB_GIT_SUBMODULE_STATUS_FLAG_CHECK(GIT_SUBMODULE_STATUS_WD_ADDED)
+}
+
+/*
+ *  call-seq:
+ *    submodule.deleted_from_workdir? -> true or false
+ *
+ *  Returns +true+ if submodule is in index, not workdir.
+ */
+static VALUE rb_git_submodule_status_deleted_from_workdir(VALUE self)
+{
+	RB_GIT_SUBMODULE_STATUS_FLAG_CHECK(GIT_SUBMODULE_STATUS_WD_DELETED)
+}
+
+/*
+ *  call-seq:
+ *    submodule.modified_in_workdir? -> true or false
+ *
+ *  Returns +true+ if submodule in index and workdir +HEAD+ don't match.
+ */
+static VALUE rb_git_submodule_status_modified_in_workdir(VALUE self)
+{
+	RB_GIT_SUBMODULE_STATUS_FLAG_CHECK(GIT_SUBMODULE_STATUS_WD_MODIFIED)
+}
+
+/*
+ *  call-seq:
+ *    submodule.dirty_workdir_index? -> true or false
+ *
+ *  Returns +true+ if submodule workdir index is dirty.
+ */
+static VALUE rb_git_submodule_status_dirty_workdir_index(VALUE self)
+{
+	RB_GIT_SUBMODULE_STATUS_FLAG_CHECK(GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED)
+}
+
+/*
+ *  call-seq:
+ *    submodule.modified_files_in_workdir? -> true or false
+ *
+ *  Returns +true+ if submodule workdir has modified files.
+ */
+static VALUE rb_git_submodule_status_modified_files_in_workdir(VALUE self)
+{
+	RB_GIT_SUBMODULE_STATUS_FLAG_CHECK(GIT_SUBMODULE_STATUS_WD_WD_MODIFIED)
+}
+
+/*
+ *  call-seq:
+ *    submodule.untracked_files_in_workdir? -> true or false
+ *
+ *  Returns +true+ if submodule workdir contains untracked files.
+ */
+static VALUE rb_git_submodule_status_untracked_files_in_workdir(VALUE self)
+{
+	RB_GIT_SUBMODULE_STATUS_FLAG_CHECK(GIT_SUBMODULE_STATUS_WD_UNTRACKED)
+}
+
+#define RB_GIT_SUBMODULE_STATUS_CHECK(check) \
+	VALUE rb_repo = rugged_owner(self); \
+	git_repository *repo; \
+	git_submodule *submodule; \
+	unsigned int flags; \
+	rugged_check_repo(rb_repo); \
+	Data_Get_Struct(rb_repo, git_repository, repo); \
+	Data_Get_Struct(self, git_submodule, submodule); \
+	rugged_exception_check( \
+		git_submodule_status(&flags, repo, git_submodule_name(submodule), \
+			GIT_SUBMODULE_IGNORE_UNSPECIFIED) \
+	); \
+	return check(flags) ? Qtrue : Qfalse; \
+
+/*
+ *  call-seq:
+ *    submodule.unmodified? -> true or false
+ *
+ *  Returns +true+ if the submodule is unmodified.
+ */
+static VALUE rb_git_submodule_status_unmodified(VALUE self)
+{
+	RB_GIT_SUBMODULE_STATUS_CHECK(GIT_SUBMODULE_STATUS_IS_UNMODIFIED)
+}
+
+/*
+ *  call-seq:
+ *    submodule.dirty_workdir? -> true or false
+ *
+ *  Returns +true+ if the submodule workdir is dirty.
+ *
+ *  The workdir is considered dirty if the workdir index is modified, there
+ *  are modified files in the workdir or if there are untracked files in the
+ *  workdir.
+ */
+static VALUE rb_git_submodule_status_dirty_workdir(VALUE self)
+{
+	RB_GIT_SUBMODULE_STATUS_CHECK(GIT_SUBMODULE_STATUS_IS_WD_DIRTY)
+}
+
+/*
+ *  call-seq:
+ *    submodule.add_to_index([options]) -> submodule
+ *
+ *  Add current submodule +HEAD+ commit to the index of superproject.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :write_index ::
+ *    (default +true+) If this should immediately write the index file.
+ *    If passed as +false+, Rugged::Repository#index can be used to explicitly
+ *    call Rugged::Index#write to save the change.
+ */
+static VALUE rb_git_submodule_add_to_index(int argc, VALUE *argv, VALUE self)
+{
+	git_submodule *submodule;
+	VALUE rb_options;
+	int write_index = 1;
+
+	Data_Get_Struct(self, git_submodule, submodule);
+
+	rb_scan_args(argc, argv, ":", &rb_options);
+
+	if (!NIL_P(rb_options)) {
+		VALUE rb_val;
+
+		rb_val = rb_hash_aref(rb_options, CSTR2SYM("write_index"));
+		write_index = (rb_val != Qfalse);
+	}
+
+	rugged_exception_check(
+		git_submodule_add_to_index(submodule, write_index)
+	);
+
+	return self;
+}
+
+/*
+ *  call-seq:
+ *    submodule.reload -> submodule
+ *
+ *  Reread submodule info from config, index, and +HEAD+.
+ *
+ *  Call this to reread cached submodule information for this submodule if
+ *  there is reason to believe that it has changed.
+ */
+static VALUE rb_git_submodule_reload(VALUE self)
+{
+	git_submodule *submodule;
+	Data_Get_Struct(self, git_submodule, submodule);
+
+	rugged_exception_check(
+		git_submodule_reload(submodule, 1)
+	);
+
+	return self;
+}
+
+/*
+ *  call-seq:
+ *    submodule.sync -> submodule
+ *
+ *  Copy submodule remote info into submodule repository.
+ *
+ *  This copies the information about the submodules URL into the checked out
+ *  submodule config, acting like <tt>"git submodule sync"</tt>. This is useful
+ *  if the URL for the submodule was altered (by a manual change, or a fetch of
+ *  upstream changes) and the local repository needs to be updated.
+ */
+static VALUE rb_git_submodule_sync(VALUE self)
+{
+	git_submodule *submodule;
+	Data_Get_Struct(self, git_submodule, submodule);
+
+	rugged_exception_check(
+		git_submodule_sync(submodule)
+	);
+
+	return self;
+}
+
+/*
+ *  call-seq:
+ *    submodule.init([options]) -> submodule
+ *
+ *  Copy submodule info into +.git/config+ file.
+ *
+ *  Just like <tt>"git submodule init"</tt>, this copies information about the
+ *  submodule into +.git/config+.
+ *
+ * The following options can be passed in the +options+ Hash:
+ *
+ *  :overwrite ::
+ *    (defaults to +false+) - By default, existing entries
+ *    will not be overwritten, but setting this to +true+ forces them to be
+ *    updated.
+ */
+static VALUE rb_git_submodule_init(int argc, VALUE *argv, VALUE self)
+{
+	git_submodule *submodule;
+	VALUE rb_options;
+	int overwrite = 0;
+
+	Data_Get_Struct(self, git_submodule, submodule);
+
+	rb_scan_args(argc, argv, ":", &rb_options);
+
+	if (!NIL_P(rb_options)) {
+		VALUE rb_val;
+
+		rb_val = rb_hash_aref(rb_options, CSTR2SYM("overwrite"));
+		overwrite = RTEST(rb_val);
+	}
+
+	rugged_exception_check(
+		git_submodule_init(submodule, overwrite)
+	);
+
+	return self;
+}
+
+/*
+ *  call-seq:
+ *    submodule.name -> string
+ *
+ *  Returns the name of the submodule.
+ */
+static VALUE rb_git_submodule_name(VALUE self)
+{
+	git_submodule *submodule;
+	const char *name;
+
+	Data_Get_Struct(self, git_submodule, submodule);
+
+	name = git_submodule_name(submodule);
+
+	return rb_str_new_utf8(name);
+}
+
+/*
+ *  call-seq:
+ *    submodule.url -> string or nil
+ *
+ *  Returns the URL of the submodule.
+ */
+static VALUE rb_git_submodule_url(VALUE self)
+{
+
+	git_submodule *submodule;
+	const char *url;
+
+	Data_Get_Struct(self, git_submodule, submodule);
+
+	url = git_submodule_url(submodule);
+
+	return url ? rb_str_new_utf8(url) : Qnil;
+}
+
+/*
+ *  call-seq:
+ *    submodule.path -> string
+ *
+ *  Returns the path of the submodule.
+ *
+ *  The +path+ is almost always the same as the #name,
+ *  but the two are actually not required to match.
+ */
+static VALUE rb_git_submodule_path(VALUE self)
+{
+	git_submodule *submodule;
+	const char *path;
+
+	Data_Get_Struct(self, git_submodule, submodule);
+
+	path = git_submodule_path(submodule);
+
+	return rb_str_new_utf8(path);
+}
+
+#define RB_GIT_OID_GETTER(_klass, _attribute) \
+	git_##_klass *object; \
+	const git_oid * oid; \
+	Data_Get_Struct(self, git_##_klass, object); \
+	oid = git_##_klass##_##_attribute(object); \
+	return oid ? rugged_create_oid(oid) : Qnil; \
+
+/*
+ *  call-seq:
+ *    submodule.head_oid -> string or nil
+ *
+ *  Returns the OID for the submodule in the current +HEAD+ tree or +nil+
+ *  if the submodule is not in the +HEAD+.
+ */
+static VALUE rb_git_submodule_head_id(VALUE self)
+{
+	RB_GIT_OID_GETTER(submodule, head_id);
+}
+
+/*
+ *  call-seq:
+ *    submodule.index_oid -> string or nil
+ *
+ *  Returns the OID for the submodule in the index or +nil+ if the submodule
+ *  is not in the index.
+ */
+static VALUE rb_git_submodule_index_id(VALUE self)
+{
+	RB_GIT_OID_GETTER(submodule, index_id);
+}
+
+/*
+ *  call-seq:
+ *    submodule.workdir_oid -> string or nil
+ *
+ *  Returns the OID for the submodule in the current working directory or
+ *  +nil+ of the submodule is not checked out.
+ *
+ *  This returns the OID that corresponds to looking up +HEAD+ in the checked
+ *  out submodule.  If there are pending changes in the index or anything
+ *  else, this won't notice that. #status can be called for a more complete
+ *  picture about the state of the working directory.
+ */
+static VALUE rb_git_submodule_wd_id(VALUE self)
+{
+	RB_GIT_OID_GETTER(submodule, wd_id);
+}
+
+/*
+ *  call-seq:
+ *    submodule.fetch_recurse_submodules? -> true or false
+ *
+ *  Returns the +fetchRecurseSubmodules+ rule for a submodule.
+ *
+ *  This accesses the <tt>submodule.<name>.fetchRecurseSubmodules</tt> value
+ *  for the submodule that controls fetching behavior for the submodule.
+ *
+ *  Note that at this time, +Rugged+ does not honor this setting and the fetch
+ *  functionality currently ignores submodules.
+ *
+ */
+static VALUE rb_git_submodule_fetch_recurse_submodules(VALUE self)
+{
+	git_submodule *submodule;
+	Data_Get_Struct(self, git_submodule, submodule);
+
+	return git_submodule_fetch_recurse_submodules(submodule) ? Qtrue : Qfalse;
+}
+
+static VALUE rb_git_subm_ignore_rule_fromC(git_submodule_ignore_t rule)
+{
+	switch(rule) {
+	case GIT_SUBMODULE_IGNORE_NONE:
+		return ID2SYM(id_ignore_none);
+	case GIT_SUBMODULE_IGNORE_UNTRACKED:
+		return ID2SYM(id_ignore_untracked);
+	case GIT_SUBMODULE_IGNORE_DIRTY:
+		return ID2SYM(id_ignore_dirty);
+	case GIT_SUBMODULE_IGNORE_ALL:
+		return ID2SYM(id_ignore_all);
+	default:
+		return CSTR2SYM("unknown");
+	}
+}
+
+/*
+ *  call-seq:
+ *    submodule.ignore_rule -> symbol
+ *
+ *  Returns the ignore rule for a submodule.
+ *
+ *  There are four ignore values:
+ *
+ *  :none (default)::
+ *    will consider any change to the contents of the submodule from
+ *    a clean checkout to be dirty, including the addition of untracked files.
+ *  :untracked ::
+ *    examines the contents of the working tree but untracked files will not
+ *    count as making the submodule dirty.
+ *  :dirty ::
+ *    means to only check if the +HEAD+ of the submodule has moved for status.
+ *    This is fast since it does not need to scan the working tree
+ *    of the submodule at all.
+ *  :all ::
+ *    means not to open the submodule repository. The working directory will be
+ *    considered clean so long as there is a checked out version present.
+ *
+ *  See #status on how ignore rules reflect the returned status info
+ *  for a submodule.
+ */
+static VALUE rb_git_submodule_ignore_rule(VALUE self)
+{
+	git_submodule *submodule;
+	git_submodule_ignore_t ignore;
+
+	Data_Get_Struct(self, git_submodule, submodule);
+	ignore = git_submodule_ignore(submodule);
+
+	return rb_git_subm_ignore_rule_fromC(ignore);
+}
+
+static VALUE rb_git_subm_update_rule_fromC(git_submodule_update_t rule)
+{
+	switch(rule) {
+	case GIT_SUBMODULE_UPDATE_CHECKOUT:
+		return ID2SYM(id_update_checkout);
+	case GIT_SUBMODULE_UPDATE_REBASE:
+		return ID2SYM(id_update_rebase);
+	case GIT_SUBMODULE_UPDATE_MERGE:
+		return ID2SYM(id_update_merge);
+	case GIT_SUBMODULE_UPDATE_NONE:
+		return ID2SYM(id_update_none);
+	default:
+		return CSTR2SYM("unknown");
+	}
+}
+
+/*
+ *  call-seq:
+ *    submodule.update_rule -> symbol
+ *
+ *  Returns the update rule for a submodule.
+ *
+ *  There are four update_rule values:
+ *
+ *  :checkout (default)::
+ *    the new commit specified in the superproject will be checked out in the
+ *    submodule on a detached +HEAD+.
+ *  :rebase ::
+ *    the current branch of the submodule will be rebased onto the commit
+ *    specified in the superproject.
+ *  :merge ::
+ *    the commit specified in the superproject will be merged into the current
+ *    branch of the submodule.
+ *  :none ::
+ *    the submodule will not be updated
+ */
+static VALUE rb_git_submodule_update_rule(VALUE self)
+{
+	git_submodule *submodule;
+	git_submodule_update_t update;
+
+	Data_Get_Struct(self, git_submodule, submodule);
+	update = git_submodule_update_strategy(submodule);
+
+	return rb_git_subm_update_rule_fromC(update);
+}
+
+/*
+ *  call-seq:
+ *    submodule.repository -> repository
+ *
+ *  Returns the +repository+ for the submodule.
+ *
+ *  The returned +repository+ is a newly opened Rugged::Repository object.
+ *  This will only work if the submodule is checked out into the working
+ *  directory.
+ */
+static VALUE rb_git_submodule_repository(VALUE self)
+{
+	git_submodule *submodule;
+	git_repository *repo;
+
+	Data_Get_Struct(self, git_submodule, submodule);
+
+	rugged_exception_check(
+		git_submodule_open(&repo, submodule)
+	);
+
+	return rugged_repo_new(rb_cRuggedRepo, repo);
+}
+
+/*
+ *  call-seq:
+ *    submodule.finalize_add -> submodule
+ *
+ *  Resolve the setup of a new submodule.
+ *
+ *  This should be called on a submodule once
+ *  Rugged::SubmoduleCollection#setup_add is finished and the sumodule repo is
+ *  cloned.
+ *
+ *  This adds the +.gitmodules+ file and the newly cloned submodule to the index
+ *  to be ready to be committed (but doesn't actually do the commit).
+ */
+static VALUE rb_git_submodule_finalize_add(VALUE self)
+{
+	git_submodule *submodule;
+	Data_Get_Struct(self, git_submodule, submodule);
+
+	rugged_exception_check(
+		git_submodule_add_finalize(submodule)
+	);
+
+	return self;
+}
+
+void Init_rugged_submodule(void)
+{
+	init_status_list();
+	id_ignore_none = rb_intern("none");
+	id_ignore_dirty = rb_intern("dirty");
+	id_ignore_untracked = rb_intern("untracked");
+	id_ignore_all = rb_intern("all");
+
+	id_update_checkout = rb_intern("checkout");
+	id_update_rebase = rb_intern("rebase");
+	id_update_merge = rb_intern("merge");
+	id_update_none  = rb_intern("none");
+
+	rb_cRuggedSubmodule = rb_define_class_under(rb_mRugged, "Submodule", rb_cObject);
+
+	rb_define_method(rb_cRuggedSubmodule, "finalize_add", rb_git_submodule_finalize_add, 0);
+
+	rb_define_method(rb_cRuggedSubmodule, "name", rb_git_submodule_name, 0);
+	rb_define_method(rb_cRuggedSubmodule, "url", rb_git_submodule_url, 0);
+	rb_define_method(rb_cRuggedSubmodule, "path", rb_git_submodule_path, 0);
+	rb_define_method(rb_cRuggedSubmodule, "fetch_recurse_submodules?", rb_git_submodule_fetch_recurse_submodules, 0);
+
+	rb_define_method(rb_cRuggedSubmodule, "ignore_rule", rb_git_submodule_ignore_rule, 0);
+	rb_define_method(rb_cRuggedSubmodule, "update_rule", rb_git_submodule_update_rule, 0);
+
+	rb_define_method(rb_cRuggedSubmodule, "head_oid", rb_git_submodule_head_id, 0);
+	rb_define_method(rb_cRuggedSubmodule, "index_oid", rb_git_submodule_index_id, 0);
+	rb_define_method(rb_cRuggedSubmodule, "workdir_oid", rb_git_submodule_wd_id, 0);
+
+	rb_define_method(rb_cRuggedSubmodule, "status", rb_git_submodule_status, 0);
+	rb_define_method(rb_cRuggedSubmodule, "in_head?", rb_git_submodule_status_in_head, 0);
+	rb_define_method(rb_cRuggedSubmodule, "in_index?", rb_git_submodule_status_in_index, 0);
+	rb_define_method(rb_cRuggedSubmodule, "in_config?", rb_git_submodule_status_in_config, 0);
+	rb_define_method(rb_cRuggedSubmodule, "in_workdir?", rb_git_submodule_status_in_workdir, 0);
+	rb_define_method(rb_cRuggedSubmodule, "added_to_index?", rb_git_submodule_status_added_to_index, 0);
+	rb_define_method(rb_cRuggedSubmodule, "deleted_from_index?", rb_git_submodule_status_deleted_from_index, 0);
+	rb_define_method(rb_cRuggedSubmodule, "modified_in_index?", rb_git_submodule_status_modified_in_index, 0);
+	rb_define_method(rb_cRuggedSubmodule, "uninitialized?", rb_git_submodule_status_uninitialized, 0);
+	rb_define_method(rb_cRuggedSubmodule, "added_to_workdir?", rb_git_submodule_status_added_to_workdir, 0);
+	rb_define_method(rb_cRuggedSubmodule, "deleted_from_workdir?", rb_git_submodule_status_deleted_from_workdir, 0);
+	rb_define_method(rb_cRuggedSubmodule, "modified_in_workdir?", rb_git_submodule_status_modified_in_workdir, 0);
+	rb_define_method(rb_cRuggedSubmodule, "dirty_workdir_index?", rb_git_submodule_status_dirty_workdir_index, 0);
+	rb_define_method(rb_cRuggedSubmodule, "modified_files_in_workdir?", rb_git_submodule_status_modified_files_in_workdir, 0);
+	rb_define_method(rb_cRuggedSubmodule, "untracked_files_in_workdir?", rb_git_submodule_status_untracked_files_in_workdir, 0);
+
+	rb_define_method(rb_cRuggedSubmodule, "unmodified?", rb_git_submodule_status_unmodified, 0);
+	rb_define_method(rb_cRuggedSubmodule, "dirty_workdir?", rb_git_submodule_status_dirty_workdir, 0);
+
+	rb_define_method(rb_cRuggedSubmodule, "repository", rb_git_submodule_repository, 0);
+
+	rb_define_method(rb_cRuggedSubmodule, "add_to_index", rb_git_submodule_add_to_index, -1);
+	rb_define_method(rb_cRuggedSubmodule, "reload", rb_git_submodule_reload, 0);
+	rb_define_method(rb_cRuggedSubmodule, "sync", rb_git_submodule_sync, 0);
+	rb_define_method(rb_cRuggedSubmodule, "init", rb_git_submodule_init, -1);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_submodule_collection.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_submodule_collection.c
new file mode 100755
index 0000000..d8abf68
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_submodule_collection.c
@@ -0,0 +1,384 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedSubmodule;
+VALUE rb_cRuggedSubmoduleCollection;
+
+/*
+ *  call-seq:
+ *    SubmoduleCollection.new(repo) -> submodules
+ *
+ *  Creates and returns a new collection of submodules for the given +repo+.
+ */
+static VALUE rb_git_submodule_collection_initialize(VALUE self, VALUE rb_repo)
+{
+	rugged_check_repo(rb_repo);
+	rugged_set_owner(self, rb_repo);
+	return self;
+}
+
+static void rb_git_submodule__free(git_submodule *submodule)
+{
+	git_submodule_free(submodule);
+}
+
+VALUE rugged_submodule_new(VALUE owner, git_submodule *submodule)
+{
+	VALUE rb_submodule;
+
+	rb_submodule = Data_Wrap_Struct(
+			rb_cRuggedSubmodule,
+			NULL,
+			&rb_git_submodule__free,
+			submodule);
+	rugged_set_owner(rb_submodule, owner);
+
+	return rb_submodule;
+}
+
+/*
+ *  call-seq:
+ *    submodules[name] -> submodule or nil
+ *
+ *  Lookup +submodule+ by +name+ or +path+ (they are usually the same) in
+ *  +repository+.
+ *
+ *  Returns +nil+ if submodule does not exist.
+ *
+ *  Raises <tt>Rugged::SubmoduleError</tt> if submodule exists only in working
+ *  directory (i.e. there is a subdirectory that is a valid self-contained git
+ *  repository) and is not mentioned in the +HEAD+, the index and the config.
+ */
+static VALUE rb_git_submodule_collection_aref(VALUE self, VALUE rb_name)
+{
+	git_repository *repo;
+	git_submodule *submodule;
+	int error;
+
+	VALUE rb_repo = rugged_owner(self);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Check_Type(rb_name, T_STRING);
+
+	error = git_submodule_lookup(
+			&submodule,
+			repo,
+			StringValueCStr(rb_name)
+		);
+
+	if (error == GIT_ENOTFOUND)
+		return Qnil;
+
+	rugged_exception_check(error);
+
+	return rugged_submodule_new(rb_repo, submodule);
+}
+
+static int cb_submodule__each(git_submodule *submodule, const char *name, void *data)
+{
+	struct rugged_cb_payload *payload = data;
+	git_repository *repo;
+	git_submodule *dummy_sm;
+	VALUE rb_repo;
+
+	rb_repo = payload->rb_data;
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	/* The submodule passed here has it's refcount decreased just after
+	 * the foreach finishes. The only way to increase that refcount is
+	 * to lookup the submodule.
+	 *
+	 * This should not return an error as the submodule name here is valid
+	 * and exists, as it was just passed to this callback.
+	 */
+	git_submodule_lookup(&dummy_sm, repo, git_submodule_name(submodule));
+
+	rb_protect(
+		rb_yield,
+		rugged_submodule_new(rb_repo, dummy_sm),
+		&payload->exception
+	);
+	return (payload->exception) ? GIT_ERROR : GIT_OK;
+}
+
+/*
+ *  call-seq:
+ *    submodules.each { |submodule| block }
+ *    submodules.each -> enumerator
+ *
+ *  Iterate through all the tracked submodules in the collection's +repository+.
+ *
+ *  The given +block+ will be called once with each +submodule+
+ *  as a Rugged::Submodule instance.
+ *  If no block is given, an enumerator will be returned.
+ */
+static VALUE rb_git_submodule_collection_each(VALUE self)
+{
+	git_repository *repo;
+	int error;
+	struct rugged_cb_payload payload;
+
+	VALUE rb_repo = rugged_owner(self);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	if (!rb_block_given_p())
+		return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("each"));
+
+	payload.exception = 0;
+	payload.rb_data = rb_repo;
+
+	error = git_submodule_foreach(repo, &cb_submodule__each, &payload);
+
+	if (payload.exception)
+		rb_jump_tag(payload.exception);
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    submodules.setup_add(url, path[, options]) -> submodule
+ *
+ *  Setup a new +submodule+ for checkout in +repository+.
+ *
+ *  This does <tt>"git submodule add"</tt> up to the fetch and checkout of the
+ *  submodule contents.  It prepares a new submodule, creates an entry in
+ *  +.gitmodules+ and creates an empty initialized repository either at the
+ *  given +path+ in the working directory or in +.git/modules+ with a gitlink
+ *  from the working directory to the new repository.
+ *
+ *  To fully emulate <tt>"git submodule add"</tt> call this function, then open
+ *  the submodule repository and perform the clone step as needed.
+ *  Lastly, call Submodule#finalize_add to wrap up adding the new submodule and
+ *  +.gitmodules+ to the index to be ready to commit.
+ *
+ *  - +url+: URL for the submodule's remote
+ *  - +path+: path at which the submodule should be created
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *  :gitlink ::
+ *    (defaults to +true+) should workdir contain a
+ *    gitlink to the repository in +.git/modules+ vs. repository
+ *    directly in workdir.
+ *
+ *  Returns the newly created +submodule+
+ */
+static VALUE rb_git_submodule_setup_add(int argc, VALUE *argv, VALUE self)
+{
+	git_submodule *submodule;
+	git_repository *repo;
+	int error;
+	int use_gitlink = 1;
+	VALUE rb_repo, rb_url, rb_path, rb_options;
+
+	rb_scan_args(argc, argv, "20:", &rb_url, &rb_path, &rb_options);
+
+	Check_Type(rb_url, T_STRING);
+	Check_Type(rb_path, T_STRING);
+
+	rb_repo = rugged_owner(self);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	if (!NIL_P(rb_options)) {
+		VALUE rb_val;
+
+		rb_val = rb_hash_aref(rb_options, CSTR2SYM("gitlink"));
+		use_gitlink = (rb_val != Qfalse);
+	}
+
+	error = git_submodule_add_setup(
+			&submodule,
+			repo,
+			StringValueCStr(rb_url),
+			StringValueCStr(rb_path),
+			use_gitlink
+		);
+
+	rugged_exception_check(error);
+
+	return rugged_submodule_new(rb_repo, submodule);
+}
+
+static git_submodule_ignore_t rb_git_subm_ignore_rule_toC(VALUE rb_ignore_rule)
+{
+	ID id_ignore_rule;
+
+	Check_Type(rb_ignore_rule, T_SYMBOL);
+	id_ignore_rule = SYM2ID(rb_ignore_rule);
+
+	if (id_ignore_rule == rb_intern("none")) {
+		return GIT_SUBMODULE_IGNORE_NONE;
+	} else if (id_ignore_rule == rb_intern("untracked")) {
+		return GIT_SUBMODULE_IGNORE_UNTRACKED;
+	} else if (id_ignore_rule == rb_intern("dirty")) {
+		return GIT_SUBMODULE_IGNORE_DIRTY;
+	} else if (id_ignore_rule == rb_intern("all")) {
+		return GIT_SUBMODULE_IGNORE_ALL;
+	} else {
+		rb_raise(rb_eArgError, "Invalid submodule ignore rule type.");
+	}
+}
+
+static git_submodule_update_t rb_git_subm_update_rule_toC(VALUE rb_update_rule)
+{
+	ID id_update_rule;
+
+	Check_Type(rb_update_rule, T_SYMBOL);
+	id_update_rule = SYM2ID(rb_update_rule);
+
+	if (id_update_rule == rb_intern("checkout")) {
+		return GIT_SUBMODULE_UPDATE_CHECKOUT;
+	} else if (id_update_rule == rb_intern("rebase")) {
+		return GIT_SUBMODULE_UPDATE_REBASE;
+	} else if (id_update_rule == rb_intern("merge")) {
+		return GIT_SUBMODULE_UPDATE_MERGE;
+	} else if (id_update_rule == rb_intern("none")) {
+		return GIT_SUBMODULE_UPDATE_NONE;
+	} else {
+		rb_raise(rb_eArgError, "Invalid submodule update rule type.");
+	}
+}
+
+/*
+ *  call-seq:
+ *    submodules.update(submodule, settings) -> nil
+ *    submodules.update(name, settings) -> nil
+ *
+ *  Update settings for the given submodule in the submodule config.
+ *
+ *  Existing `Rugged::Submodule` instances are not updated, but can be
+ *  reloaded by calling `#reload`.
+ *
+ *  The following options can be passed in the +settings+ Hash:
+ *
+ *  :url ::
+ *    Updates the URL for the submodule.
+ *
+ *  :ignore_rule ::
+ *    See `Rugged::Submodule#ignore_rule` for a list of accepted rules.
+ *
+ *  :update_rule ::
+ *    See `Rugged::Submodule#update_rule` for a list of accepted rules.
+ *
+ *  :fetch_recurse_submodules ::
+ *    Updates the +fetchRecurseSubmodules+ rule.
+ */
+static VALUE rb_git_submodule_update(VALUE self, VALUE rb_name_or_submodule, VALUE rb_settings)
+{
+	git_repository *repo;
+	git_submodule_ignore_t ignore_rule = GIT_SUBMODULE_IGNORE_UNSPECIFIED;
+	git_submodule_update_t update_rule = GIT_SUBMODULE_UPDATE_DEFAULT;
+	const char *submodule_name;
+	int fetch_recurse_submodules = 0;
+	VALUE rb_repo = rugged_owner(self);
+	VALUE rb_url, rb_fetch_recurse_submodules, rb_ignore_rule, rb_update_rule;
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	if (rb_obj_is_kind_of(rb_name_or_submodule, rb_cRuggedSubmodule))
+		rb_name_or_submodule = rb_funcall(rb_name_or_submodule, rb_intern("name"), 0);
+
+	if (TYPE(rb_name_or_submodule) != T_STRING)
+		rb_raise(rb_eTypeError, "Expecting a String or Rugged::Submodule instance");
+
+	rb_url = rb_hash_aref(rb_settings, CSTR2SYM("url"));
+	rb_fetch_recurse_submodules = rb_hash_aref(rb_settings, CSTR2SYM("fetch_recurse_submodules"));
+	rb_ignore_rule = rb_hash_aref(rb_settings, CSTR2SYM("ignore_rule"));
+	rb_update_rule = rb_hash_aref(rb_settings, CSTR2SYM("update_rule"));
+
+	if (!NIL_P(rb_url)) {
+		Check_Type(rb_url, T_STRING);
+	}
+
+	if (!NIL_P(rb_fetch_recurse_submodules)) {
+		fetch_recurse_submodules = rugged_parse_bool(rb_fetch_recurse_submodules);
+	}
+
+	if (!NIL_P(rb_ignore_rule)) {
+		ignore_rule = rb_git_subm_ignore_rule_toC(rb_ignore_rule);
+	}
+
+	if (!NIL_P(rb_update_rule)) {
+		update_rule = rb_git_subm_update_rule_toC(rb_update_rule);
+	}
+
+	submodule_name = StringValueCStr(rb_name_or_submodule);
+
+	if (!NIL_P(rb_url)) {
+		rugged_exception_check(
+			git_submodule_set_url(repo,
+				submodule_name,
+				StringValueCStr(rb_url)
+			)
+		);
+	}
+
+	if (!NIL_P(rb_fetch_recurse_submodules)) {
+		rugged_exception_check(
+			git_submodule_set_fetch_recurse_submodules(repo,
+				submodule_name,
+				fetch_recurse_submodules
+			)
+		);
+	}
+
+	if (!NIL_P(rb_ignore_rule)) {
+		rugged_exception_check(
+			git_submodule_set_ignore(repo,
+				submodule_name,
+				ignore_rule
+			)
+		);
+	}
+
+	if (!NIL_P(rb_update_rule)) {
+		rugged_exception_check(
+			git_submodule_set_update(repo,
+				submodule_name,
+				update_rule
+			)
+		);
+	}
+
+	return Qnil;
+}
+
+void Init_rugged_submodule_collection(void)
+{
+	rb_cRuggedSubmoduleCollection = rb_define_class_under(rb_mRugged, "SubmoduleCollection", rb_cObject);
+	rb_include_module(rb_cRuggedSubmoduleCollection, rb_mEnumerable);
+
+	rb_define_method(rb_cRuggedSubmoduleCollection, "initialize", rb_git_submodule_collection_initialize, 1);
+	rb_define_method(rb_cRuggedSubmoduleCollection, "[]",         rb_git_submodule_collection_aref, 1);
+	rb_define_method(rb_cRuggedSubmoduleCollection, "each",       rb_git_submodule_collection_each, 0);
+
+	rb_define_method(rb_cRuggedSubmoduleCollection, "update",     rb_git_submodule_update, 2);
+
+	rb_define_method(rb_cRuggedSubmoduleCollection, "setup_add",  rb_git_submodule_setup_add, -1);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_tag.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_tag.c
new file mode 100755
index 0000000..ed58776
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_tag.c
@@ -0,0 +1,251 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedObject;
+extern VALUE rb_cRuggedRepo;
+extern VALUE rb_cRuggedReference;
+
+VALUE rb_cRuggedTag;
+VALUE rb_cRuggedTagAnnotation;
+
+/*
+ *  call-seq:
+ *    annotation.target -> object
+ *
+ *  Return the +object+ pointed at by this tag annotation, as a <tt>Rugged::Object</tt>
+ *  instance.
+ *
+ *    annotation.target #=> #<Rugged::Commit:0x108828918>
+ */
+static VALUE rb_git_tag_annotation_target(VALUE self)
+{
+	git_tag *tag;
+	git_object *target;
+	int error;
+	VALUE owner;
+
+	Data_Get_Struct(self, git_tag, tag);
+	owner = rugged_owner(self);
+
+	error = git_tag_target(&target, tag);
+	rugged_exception_check(error);
+
+	return rugged_object_new(owner, target);
+}
+
+/*
+ *  call-seq:
+ *    annotation.target_oid -> oid
+ *    annotation.target_id -> oid
+ *
+ *  Return the oid pointed at by this tag annotation, as a <tt>String</tt>
+ *  instance.
+ *
+ *    annotation.target_id #=> "2cb831a8aea28b2c1b9c63385585b864e4d3bad1"
+ */
+static VALUE rb_git_tag_annotation_target_id(VALUE self)
+{
+	git_tag *tag;
+	const git_oid *target_oid;
+
+	Data_Get_Struct(self, git_tag, tag);
+
+	target_oid = git_tag_target_id(tag);
+
+	return rugged_create_oid(target_oid);
+}
+
+/*
+ *  call-seq:
+ *    annotation.type -> t
+ *
+ *  Return a symbol representing the type of the objeced pointed at by
+ *  this +annotation+. Possible values are +:blob+, +:commit+, +:tree+ and +:tag+.
+ *
+ *  This is always the same as the +type+ of the returned <tt>annotation.target</tt>
+ *
+ *    annotation.type #=> :commit
+ *    annotation.target.type == annotation.type #=> true
+ */
+static VALUE rb_git_tag_annotation_target_type(VALUE self)
+{
+	git_tag *tag;
+	Data_Get_Struct(self, git_tag, tag);
+
+	return rugged_otype_new(git_tag_target_type(tag));
+}
+
+/*
+ *  call-seq:
+ *    annotation.name -> name
+ *
+ *  Return a string with the name of this tag +annotation+.
+ *
+ *    annotation.name #=> "v0.16.0"
+ */
+static VALUE rb_git_tag_annotation_name(VALUE self)
+{
+	git_tag *tag;
+	Data_Get_Struct(self, git_tag, tag);
+
+	return rb_str_new_utf8(git_tag_name(tag));
+}
+
+/*
+ *  call-seq:
+ *    annotation.tagger -> signature
+ *
+ *  Return the signature for the author of this tag +annotation+. The signature
+ *  is returned as a +Hash+ containing +:name+, +:email+ of the author
+ *  and +:time+ of the tagging.
+ *
+ *    annotation.tagger #=> {:email=>"tanoku at gmail.com", :time=>Tue Jan 24 05:42:45 UTC 2012, :name=>"Vicent Mart\303\255"}
+ */
+static VALUE rb_git_tag_annotation_tagger(VALUE self)
+{
+	git_tag *tag;
+	const git_signature *tagger;
+
+	Data_Get_Struct(self, git_tag, tag);
+	tagger = git_tag_tagger(tag);
+
+	if (!tagger)
+		return Qnil;
+
+	return rugged_signature_new(tagger, NULL);
+}
+
+/*
+ *  call-seq:
+ *    annotation.message -> msg
+ *
+ *  Return the message of this tag +annotation+. This includes the full body of the
+ *  message and any optional footers or signatures after it.
+ *
+ *    annotation.message #=> "Release v0.16.0, codename 'broken stuff'"
+ */
+static VALUE rb_git_tag_annotation_message(VALUE self)
+{
+	git_tag *tag;
+	const char *message;
+
+	Data_Get_Struct(self, git_tag, tag);
+	message = git_tag_message(tag);
+
+	if (!message)
+		return Qnil;
+
+	return rb_str_new_utf8(message);
+}
+
+/*
+ *  call-seq:
+ *    tag.annotation -> annotation or nil
+ */
+static VALUE rb_git_tag_annotation(VALUE self)
+{
+	git_reference *ref, *resolved_ref;
+	git_repository *repo;
+	git_object *target;
+	int error;
+	VALUE rb_repo = rugged_owner(self);
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(self, git_reference, ref);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_reference_resolve(&resolved_ref, ref);
+	rugged_exception_check(error);
+
+	error = git_object_lookup(&target, repo, git_reference_target(resolved_ref), GIT_OBJ_TAG);
+	git_reference_free(resolved_ref);
+
+	if (error == GIT_ENOTFOUND)
+		return Qnil;
+
+	return rugged_object_new(rb_repo, target);
+}
+
+/*
+ *  call-seq:
+ *    tag.target -> git_object
+ */
+static VALUE rb_git_tag_target(VALUE self)
+{
+	git_reference *ref, *resolved_ref;
+	git_repository *repo;
+	git_object *target;
+	int error;
+	VALUE rb_repo = rugged_owner(self);
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(self, git_reference, ref);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_reference_resolve(&resolved_ref, ref);
+	rugged_exception_check(error);
+
+	error = git_object_lookup(&target, repo, git_reference_target(resolved_ref), GIT_OBJ_ANY);
+	git_reference_free(resolved_ref);
+	rugged_exception_check(error);
+
+	if (git_object_type(target) == GIT_OBJ_TAG) {
+		git_object *annotation_target;
+
+		error = git_tag_target(&annotation_target, (git_tag *)target);
+		git_object_free(target);
+		rugged_exception_check(error);
+
+		return rugged_object_new(rb_repo, annotation_target);
+	} else {
+		return rugged_object_new(rb_repo, target);
+	}
+}
+
+static VALUE rb_git_tag_annotated_p(VALUE self)
+{
+	return RTEST(rb_git_tag_annotation(self)) ? Qtrue : Qfalse;
+}
+
+void Init_rugged_tag(void)
+{
+	rb_cRuggedTag = rb_define_class_under(rb_mRugged, "Tag", rb_cRuggedReference);
+
+	rb_define_method(rb_cRuggedTag, "annotation", rb_git_tag_annotation, 0);
+	rb_define_method(rb_cRuggedTag, "annotated?", rb_git_tag_annotated_p, 0);
+	rb_define_method(rb_cRuggedTag, "target", rb_git_tag_target, 0);
+
+	rb_cRuggedTagAnnotation = rb_define_class_under(rb_cRuggedTag, "Annotation", rb_cRuggedObject);
+
+	rb_define_method(rb_cRuggedTagAnnotation, "message", rb_git_tag_annotation_message, 0);
+	rb_define_method(rb_cRuggedTagAnnotation, "name", rb_git_tag_annotation_name, 0);
+	rb_define_method(rb_cRuggedTagAnnotation, "target", rb_git_tag_annotation_target, 0);
+	rb_define_method(rb_cRuggedTagAnnotation, "target_oid", rb_git_tag_annotation_target_id, 0);
+	rb_define_method(rb_cRuggedTagAnnotation, "target_id", rb_git_tag_annotation_target_id, 0);
+	rb_define_method(rb_cRuggedTagAnnotation, "target_type", rb_git_tag_annotation_target_type, 0);
+	rb_define_method(rb_cRuggedTagAnnotation, "tagger", rb_git_tag_annotation_tagger, 0);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_tag_collection.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_tag_collection.c
new file mode 100755
index 0000000..590d707
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_tag_collection.c
@@ -0,0 +1,347 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedRepo;
+extern VALUE rb_cRuggedTag;
+
+VALUE rb_cRuggedTagCollection;
+
+/*
+ *  call-seq:
+ *    TagCollection.new(repo) -> refs
+ */
+static VALUE rb_git_tag_collection_initialize(VALUE self, VALUE repo)
+{
+	rugged_set_owner(self, repo);
+	return self;
+}
+
+/*
+ *  call-seq:
+ *    tags[name] -> tag
+ *
+ *  Lookup a tag in +repo+, with the given +name+.
+ *
+ *  +name+ can be a short or canonical tag name
+ *  (e.g. +v0.1.0+ or +refs/tags/v0.1.0+).
+ *
+ *  Returns the looked up tag, or +nil+ if the tag doesn't exist.
+ */
+static VALUE rb_git_tag_collection_aref(VALUE self, VALUE rb_name)
+{
+	git_reference *tag;
+	git_repository *repo;
+	int error;
+	VALUE rb_repo = rugged_owner(self);
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Check_Type(rb_name, T_STRING);
+
+	error = git_reference_lookup(&tag, repo, StringValueCStr(rb_name));
+	if (error == GIT_ENOTFOUND || error == GIT_EINVALIDSPEC) {
+		char *canonical_ref = xmalloc((RSTRING_LEN(rb_name) + strlen("refs/tags/") + 1) * sizeof(char));
+		strcpy(canonical_ref, "refs/tags/");
+		strcat(canonical_ref, StringValueCStr(rb_name));
+
+		error = git_reference_lookup(&tag, repo, canonical_ref);
+		xfree(canonical_ref);
+		if (error == GIT_ENOTFOUND)
+			return Qnil;
+	}
+
+	rugged_exception_check(error);
+
+	return rugged_ref_new(rb_cRuggedTag, rb_repo, tag);
+}
+
+/*
+ *  call-seq:
+ *    tags.delete(name) -> nil
+ *
+ *  Delete the tag reference identified by +name+.
+ */
+static VALUE rb_git_tag_collection_delete(VALUE self, VALUE rb_name)
+{
+	VALUE rb_repo = rugged_owner(self);
+	git_repository *repo;
+	int error;
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Check_Type(rb_name, T_STRING);
+
+	error = git_tag_delete(repo, StringValueCStr(rb_name));
+	rugged_exception_check(error);
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    tags.create(name, target[, force = false][, annotation = nil]) -> oid
+ *
+ *  Create a new tag with the specified +name+ on +target+ in +repo+.
+ *
+ *  If +annotation+ is not +nil+, it will cause the creation of an annotated tag object.
+ *  +annotation+ has to contain the following key value pairs:
+ *
+ *  :tagger ::
+ *    An optional Hash containing a git signature. Defaults to the signature
+ *    from the configuration if only `:message` is given. Will cause the
+ *    creation of an annotated tag object if present.
+ *
+ *  :message ::
+ *    An optional string containing the message for the new tag.
+ *
+ *  Returns the OID of the newly created tag.
+ */
+static VALUE rb_git_tag_collection_create(int argc, VALUE *argv, VALUE self)
+{
+	git_oid tag_oid;
+	git_repository *repo = NULL;
+	git_object *target = NULL;
+	int error, force = 0;
+
+	VALUE rb_repo = rugged_owner(self), rb_name, rb_target, rb_force, rb_annotation;
+
+	rb_scan_args(argc, argv, "21:", &rb_name, &rb_target, &rb_force, &rb_annotation);
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Check_Type(rb_name, T_STRING);
+
+	if (!NIL_P(rb_force))
+		force = rugged_parse_bool(rb_force);
+
+	target = rugged_object_get(repo, rb_target, GIT_OBJ_ANY);
+
+	if (NIL_P(rb_annotation)) {
+		error = git_tag_create_lightweight(
+			&tag_oid,
+			repo,
+			StringValueCStr(rb_name),
+			target,
+			force
+		);
+	} else {
+		git_signature *tagger = rugged_signature_get(
+			rb_hash_aref(rb_annotation, CSTR2SYM("tagger")), repo
+		);
+		VALUE rb_message = rb_hash_aref(rb_annotation, CSTR2SYM("message"));
+
+		Check_Type(rb_message, T_STRING);
+
+		error = git_tag_create(
+			&tag_oid,
+			repo,
+			StringValueCStr(rb_name),
+			target,
+			tagger,
+			StringValueCStr(rb_message),
+			force
+		);
+
+		git_signature_free(tagger);
+	}
+
+	git_object_free(target);
+	rugged_exception_check(error);
+
+	return rb_git_tag_collection_aref(self, rb_name);
+}
+
+/*
+ *  call-seq:
+ *    tags.create_annotation(name, target, annotation) -> annotation
+ *
+ *  Create a new annotated tag object with the specified +name+ on +target+ in
+ *  +repo+.
+ *
+ *  Unlike the +create+ method, +create_annotation+ simply creates a tag
+ *  object. It does not write a tag ref.
+ *
+ *  +annotation+ must have the following keys:
+ *
+ *  :tagger ::
+ *    An optional Hash containing a git signature. Defaults to the signature
+ *    from the configuration if only `:message` is given. Will cause the
+ *    creation of an annotated tag object if present.
+ *
+ *  :message ::
+ *    An optional string containing the message for the new tag.
+ *
+ *  Returns an instance of Rugged::Tag::Annotation representing the newly
+ *  created annotation.
+ */
+static VALUE rb_git_tag_collection_create_annotation(VALUE self, VALUE rb_name, VALUE rb_target, VALUE rb_annotation)
+{
+	git_oid tag_oid;
+	git_repository *repo = NULL;
+	git_object *target = NULL, *tag = NULL;
+	git_signature *tagger = NULL;
+	VALUE rb_message;
+	int error;
+
+	VALUE rb_repo = rugged_owner(self);
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	Check_Type(rb_name, T_STRING);
+
+	target = rugged_object_get(repo, rb_target, GIT_OBJ_ANY);
+
+	rb_message = rb_hash_aref(rb_annotation, CSTR2SYM("message"));
+	Check_Type(rb_message, T_STRING);
+
+	tagger = rugged_signature_get(
+		rb_hash_aref(rb_annotation, CSTR2SYM("tagger")), repo
+	);
+
+	error = git_tag_annotation_create(
+		&tag_oid,
+		repo,
+		StringValueCStr(rb_name),
+		target,
+		tagger,
+		StringValueCStr(rb_message)
+	);
+
+	git_object_free(target);
+	git_signature_free(tagger);
+
+	rugged_exception_check(error);
+
+	error = git_object_lookup(&tag, repo, &tag_oid, GIT_OBJ_TAG);
+	rugged_exception_check(error);
+
+	return rugged_object_new(rb_repo, tag);
+}
+
+static VALUE each_tag(int argc, VALUE *argv, VALUE self, int tag_names_only)
+{
+	git_repository *repo;
+	git_strarray tags;
+	size_t i;
+	int error, exception = 0;
+	VALUE rb_repo = rugged_owner(self), rb_pattern;
+	const char *pattern = NULL;
+
+	rb_scan_args(argc, argv, "01", &rb_pattern);
+
+	if (!rb_block_given_p()) {
+		VALUE symbol = tag_names_only ? CSTR2SYM("each_name") : CSTR2SYM("each");
+		return rb_funcall(self, rb_intern("to_enum"), 2, symbol, rb_pattern);
+	}
+
+	if (!NIL_P(rb_pattern)) {
+		Check_Type(rb_pattern, T_STRING);
+		pattern = StringValueCStr(rb_pattern);
+	}
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_tag_list_match(&tags, pattern ? pattern : "", repo);
+	rugged_exception_check(error);
+
+	if (tag_names_only) {
+		for (i = 0; !exception && i < tags.count; ++i)
+			rb_protect(rb_yield, rb_str_new_utf8(tags.strings[i]), &exception);
+	} else {
+		for (i = 0; !exception && i < tags.count; ++i) {
+			rb_protect(rb_yield, rb_git_tag_collection_aref(self,
+				rb_str_new_utf8(tags.strings[i])), &exception);
+		}
+	}
+
+	git_strarray_free(&tags);
+
+	if (exception)
+		rb_jump_tag(exception);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    tags.each_name([pattern]) { |name| block } -> nil
+ *    tags.each_name([pattern])                  -> enumerator
+ *
+ *  Iterate through all the tag names in +repo+. Iteration
+ *  can be optionally filtered to the ones matching the given
+ *  +pattern+, a standard Unix filename glob.
+ *
+ *  If +pattern+ is empty or not given, all tag names will be returned.
+ *
+ *  The given block will be called once with the name for each tag.
+ *
+ *  If no block is given, an enumerator will be returned.
+ */
+static VALUE rb_git_tag_collection_each_name(int argc, VALUE *argv, VALUE self)
+{
+	return each_tag(argc, argv, self, 1);
+}
+
+/*
+ *  call-seq:
+ *    tags.each([pattern]) { |name| block } -> nil
+ *    tags.each([pattern])                  -> enumerator
+ *
+ *  Iterate through all the tags in +repo+. Iteration
+ *  can be optionally filtered to the ones matching the given
+ *  +pattern+, a standard Unix filename glob.
+ *
+ *  If +pattern+ is empty or not given, all tag names will be returned.
+ *
+ *  The given block will be called once with the name for each tag.
+ *
+ *  If no block is given, an enumerator will be returned.
+ */
+static VALUE rb_git_tag_collection_each(int argc, VALUE *argv, VALUE self)
+{
+	return each_tag(argc, argv, self, 0);
+}
+
+void Init_rugged_tag_collection(void)
+{
+	rb_cRuggedTagCollection = rb_define_class_under(rb_mRugged, "TagCollection", rb_cObject);
+	rb_include_module(rb_cRuggedTagCollection, rb_mEnumerable);
+
+	rb_define_method(rb_cRuggedTagCollection, "initialize", rb_git_tag_collection_initialize, 1);
+
+	rb_define_method(rb_cRuggedTagCollection, "create",            rb_git_tag_collection_create, -1);
+	rb_define_method(rb_cRuggedTagCollection, "create_annotation", rb_git_tag_collection_create_annotation, 3);
+	rb_define_method(rb_cRuggedTagCollection, "[]",                rb_git_tag_collection_aref, 1);
+
+	rb_define_method(rb_cRuggedTagCollection, "each",       rb_git_tag_collection_each, -1);
+	rb_define_method(rb_cRuggedTagCollection, "each_name",  rb_git_tag_collection_each_name, -1);
+
+	rb_define_method(rb_cRuggedTagCollection, "delete",     rb_git_tag_collection_delete, 1);
+}
diff --git a/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_tree.c b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_tree.c
new file mode 100755
index 0000000..ac666f4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/ext/rugged/rugged_tree.c
@@ -0,0 +1,901 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2014 GitHub, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "rugged.h"
+
+extern VALUE rb_mRugged;
+extern VALUE rb_cRuggedObject;
+extern VALUE rb_cRuggedRepo;
+extern VALUE rb_cRuggedDiff;
+extern VALUE rb_cRuggedIndex;
+extern VALUE rb_cRuggedCommit;
+
+VALUE rb_cRuggedTree;
+VALUE rb_cRuggedTreeBuilder;
+
+static VALUE rb_git_treeentry_fromC(const git_tree_entry *entry)
+{
+	VALUE rb_entry;
+	VALUE type;
+
+	if (!entry)
+		return Qnil;
+
+	rb_entry = rb_hash_new();
+
+	rb_hash_aset(rb_entry, CSTR2SYM("name"), rb_str_new_utf8(git_tree_entry_name(entry)));
+	rb_hash_aset(rb_entry, CSTR2SYM("oid"), rugged_create_oid(git_tree_entry_id(entry)));
+
+	rb_hash_aset(rb_entry, CSTR2SYM("filemode"), INT2FIX(git_tree_entry_filemode(entry)));
+
+	switch(git_tree_entry_type(entry)) {
+		case GIT_OBJ_TREE:
+			type = CSTR2SYM("tree");
+			break;
+
+		case GIT_OBJ_BLOB:
+			type = CSTR2SYM("blob");
+			break;
+
+		case GIT_OBJ_COMMIT:
+			type = CSTR2SYM("commit");
+			break;
+
+		default:
+			type = Qnil;
+			break;
+	}
+	rb_hash_aset(rb_entry, CSTR2SYM("type"), type);
+
+	return rb_entry;
+}
+
+/*
+ * Rugged Tree
+ */
+
+/*
+ *  call-seq:
+ *    tree.count -> count
+ *    tree.length -> count
+ *
+ *  Return the number of entries contained in the tree.
+ *
+ *  Note that this only applies to entries in the root of the tree,
+ *  not any other entries contained in sub-folders.
+ */
+static VALUE rb_git_tree_entrycount(VALUE self)
+{
+	git_tree *tree;
+	Data_Get_Struct(self, git_tree, tree);
+
+	return INT2FIX(git_tree_entrycount(tree));
+}
+
+struct rugged_treecount_cb_payload
+{
+	int count;
+	int limit;
+};
+
+static int rugged__treecount_cb(const char *root, const git_tree_entry *entry, void *data)
+{
+	struct rugged_treecount_cb_payload *payload = data;
+
+	if (payload->limit >= 0 && payload->count >= payload->limit) {
+		return -1;
+	} else if(git_tree_entry_type(entry) == GIT_OBJ_TREE) {
+		return 0;
+	} else {
+		++(payload->count);
+		return 1;
+	}
+}
+
+/*
+ *  call-seq:
+ *    tree.count_recursive(limit=nil) -> count
+ *
+ *  `limit` - The maximum number of blobs to the count in the repository.
+ *  Rugged will stop walking the tree after `limit` items to avoid long
+ *  execution times.
+ *
+ *  Return the number of blobs (up to the limit) contained in the tree and
+ *  all subtrees.
+ */
+static VALUE rb_git_tree_entrycount_recursive(int argc, VALUE* argv, VALUE self)
+{
+	git_tree *tree;
+	int error;
+	struct rugged_treecount_cb_payload payload;
+	VALUE rb_limit;
+
+	Data_Get_Struct(self, git_tree, tree);
+
+	rb_scan_args(argc, argv, "01", &rb_limit);
+
+	payload.limit = -1;
+	payload.count = 0;
+
+	if (!NIL_P(rb_limit)) {
+		Check_Type(rb_limit, T_FIXNUM);
+		payload.limit = FIX2INT(rb_limit);
+	}
+
+
+	error = git_tree_walk(tree, GIT_TREEWALK_PRE, &rugged__treecount_cb, (void *)&payload);
+
+	if (error && giterr_last()->klass == GITERR_CALLBACK) {
+		giterr_clear();
+		error = 0;
+	}
+
+	rugged_exception_check(error);
+
+	return INT2FIX(payload.count);
+}
+
+/*
+ *  call-seq:
+ *    tree[e] -> entry
+ *    tree.get_entry(e) -> entry
+ *
+ *  Return one of the entries from a tree as a +Hash+. If +e+ is a number, the +e+nth entry
+ *  from the tree will be returned. If +e+ is a string, the entry with that name
+ *  will be returned.
+ *
+ *  If the entry doesn't exist, +nil+ will be returned.
+ *
+ *    tree[3] #=> {:name => "foo.txt", :type => :blob, :oid => "d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f", :filemode => 0}
+ *    tree['bar.txt'] #=> {:name => "bar.txt", :type => :blob, :oid => "de5ba987198bcf2518885f0fc1350e5172cded78", :filemode => 0}
+ *    tree['baz.txt'] #=> nil
+ */
+static VALUE rb_git_tree_get_entry(VALUE self, VALUE entry_id)
+{
+	git_tree *tree;
+	Data_Get_Struct(self, git_tree, tree);
+
+	if (TYPE(entry_id) == T_FIXNUM)
+		return rb_git_treeentry_fromC(git_tree_entry_byindex(tree, FIX2INT(entry_id)));
+
+	else if (TYPE(entry_id) == T_STRING)
+		return rb_git_treeentry_fromC(git_tree_entry_byname(tree, StringValueCStr(entry_id)));
+
+	else
+		rb_raise(rb_eTypeError, "entry_id must be either an index or a filename");
+}
+
+/*
+ *  call-seq:
+ *    tree.get_entry_by_oid(rb_oid) -> entry
+ *
+ *  Return one of the entries from a tree as a +Hash+, based off the oid SHA.
+ *
+ *  If the entry doesn't exist, +nil+ will be returned.
+ *
+ *  This does a full traversal of the every element in the tree, so this method
+ *  is not especially fast.
+ *
+ *    tree.get_entry_by_oid("d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f")
+ *    #=> {:name => "foo.txt", :type => :blob, :oid => "d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f", :filemode => 0}
+ *
+ */
+static VALUE rb_git_tree_get_entry_by_oid(VALUE self, VALUE rb_oid)
+{
+	git_tree *tree;
+	git_oid oid;
+	Data_Get_Struct(self, git_tree, tree);
+
+	Check_Type(rb_oid, T_STRING);
+	rugged_exception_check(git_oid_fromstr(&oid, StringValueCStr(rb_oid)));
+
+	return rb_git_treeentry_fromC(git_tree_entry_byid(tree, &oid));
+}
+
+/*
+ *  call-seq:
+ *    tree.each { |entry| block }
+ *    tree.each -> enumerator
+ *
+ *  Call +block+ with each of the entries of the subtree as a +Hash+. If no +block+
+ *  is given, an +enumerator+ is returned instead.
+ *
+ *  Note that only the entries in the root of the tree are yielded; if you need to
+ *  list also entries in subfolders, use +tree.walk+ instead.
+ *
+ *    tree.each { |entry| puts entry.inspect }
+ *
+ *  generates:
+ *
+ *    {:name => "foo.txt", :type => :blob, :oid => "d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f", :filemode => 0}
+ *    {:name => "bar.txt", :type => :blob, :oid => "de5ba987198bcf2518885f0fc1350e5172cded78", :filemode => 0}
+ *    ...
+ */
+static VALUE rb_git_tree_each(VALUE self)
+{
+	git_tree *tree;
+	size_t i, count;
+	Data_Get_Struct(self, git_tree, tree);
+
+	if (!rb_block_given_p())
+		return rb_funcall(self, rb_intern("to_enum"), 0);
+
+	count = git_tree_entrycount(tree);
+
+	for (i = 0; i < count; ++i) {
+		const git_tree_entry *entry = git_tree_entry_byindex(tree, i);
+		rb_yield(rb_git_treeentry_fromC(entry));
+	}
+
+	return Qnil;
+}
+
+static int rugged__treewalk_cb(const char *root, const git_tree_entry *entry, void *payload)
+{
+	int *exception = (int *)payload;
+
+	VALUE rb_result, rb_args = rb_ary_new2(2);
+
+	rb_ary_push(rb_args, rb_str_new_utf8(root));
+	rb_ary_push(rb_args, rb_git_treeentry_fromC(entry));
+
+	rb_result = rb_protect(rb_yield_splat, rb_args, exception);
+
+	if (*exception)
+		return -1;
+
+	/* skip entry when 'false' is returned */
+	if (TYPE(rb_result) == T_FALSE)
+		return 1;
+
+	/* otherwise continue normal iteration */
+	return 0;
+}
+
+/*
+ *  call-seq:
+ *    tree.walk(mode) { |root, entry| block }
+ *    tree.walk(mode) -> Iterator
+ *
+ *  Walk +tree+ with the given mode (either +:preorder+ or +:postorder+) and yield
+ *  to +block+ every entry in +tree+ and all its subtrees, as a +Hash+. The +block+
+ *  also takes a +root+, the relative path in the traversal, starting from the root
+ *  of the original tree.
+ *
+ *  If the +block+ returns a falsy value, that entry and its sub-entries (in the case
+ *  of a folder) will be skipped for the iteration.
+ *
+ *  If no +block+ is given, an +Iterator+ is returned instead.
+ *
+ *    tree.walk(:postorder) { |root, entry| puts "#{root}#{entry[:name]} [#{entry[:oid]}]" }
+ *
+ *  generates:
+ *
+ *    USAGE.rb [02bae86c91f96b5fdb6b1cf06f5aa3612139e318]
+ *    ext [23f135b3c576b6ac4785821888991d7089f35db1]
+ *    ext/rugged [25c88faa9302e34e16664eb9c990deb2bcf77849]
+ *    ext/rugged/extconf.rb [40c1aa8a8cec8ca444ed5758e3f00ecff093070a]
+ *    ...
+ */
+static VALUE rb_git_tree_walk(VALUE self, VALUE rb_mode)
+{
+	git_tree *tree;
+	int error, mode = 0, exception = 0;
+	ID id_mode;
+
+	Data_Get_Struct(self, git_tree, tree);
+
+	if (!rb_block_given_p())
+		return rb_funcall(self, rb_intern("to_enum"), 2, CSTR2SYM("walk"), rb_mode);
+
+	Check_Type(rb_mode, T_SYMBOL);
+	id_mode = SYM2ID(rb_mode);
+
+	if (id_mode == rb_intern("preorder"))
+		mode = GIT_TREEWALK_PRE;
+	else if (id_mode == rb_intern("postorder"))
+		mode = GIT_TREEWALK_POST;
+	else
+		rb_raise(rb_eTypeError,
+				"Invalid iteration mode. Expected `:preorder` or `:postorder`");
+
+	error = git_tree_walk(tree, mode, &rugged__treewalk_cb, (void *)&exception);
+
+	if (exception)
+		rb_jump_tag(exception);
+
+	rugged_exception_check(error);
+
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    tree.path(path) -> entry
+ *
+ *  Retrieve and return a tree entry by its relative path.
+ */
+static VALUE rb_git_tree_path(VALUE self, VALUE rb_path)
+{
+	int error;
+	git_tree *tree;
+	git_tree_entry *entry;
+	VALUE rb_entry;
+	Data_Get_Struct(self, git_tree, tree);
+	Check_Type(rb_path, T_STRING);
+
+	error = git_tree_entry_bypath(&entry, tree, StringValueCStr(rb_path));
+	rugged_exception_check(error);
+
+	rb_entry = rb_git_treeentry_fromC(entry);
+	git_tree_entry_free(entry);
+
+	return rb_entry;
+}
+
+/*
+ *  call-seq:
+ *    Tree.diff(repo, tree, diffable[, options]) -> diff
+ *
+ *  Returns a diff between the `tree` and the diffable object that was given.
+ *  +diffable+ can either be a +Rugged::Commit+, a +Rugged::Tree+, a +Rugged::Index+,
+ *  or +nil+.
+ *
+ *  The +tree+ object will be used as the "old file" side of the diff, while the
+ *  parent tree or the +diffable+ object will be used for the "new file" side.
+ *
+ *  If +tree+ or +diffable+ are nil, they will be treated as an empty tree. Passing
+ *  both as `nil` will raise an exception.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :paths ::
+ *    An array of paths / fnmatch patterns to constrain the diff to a specific
+ *    set of files. Also see +:disable_pathspec_match+.
+ *
+ *  :max_size ::
+ *    An integer specifying the maximum byte size of a file before a it will
+ *    be treated as binary. The default value is 512MB.
+ *
+ *  :context_lines ::
+ *    The number of unchanged lines that define the boundary of a hunk (and
+ *    to display before and after the actual changes). The default is 3.
+ *
+ *  :interhunk_lines ::
+ *    The maximum number of unchanged lines between hunk boundaries before the hunks
+ *    will be merged into a one. The default is 0.
+ *
+ *  :old_prefix ::
+ *    The virtual "directory" to prefix to old filenames in hunk headers.
+ *    The default is "a".
+ *
+ *  :new_prefix ::
+ *    The virtual "directory" to prefix to new filenames in hunk headers.
+ *    The default is "b".
+ *
+ *  :reverse ::
+ *    If true, the sides of the diff will be reversed.
+ *
+ *  :force_text ::
+ *    If true, all files will be treated as text, disabling binary attributes & detection.
+ *
+ *  :ignore_whitespace ::
+ *    If true, all whitespace will be ignored.
+ *
+ *  :ignore_whitespace_change ::
+ *    If true, changes in amount of whitespace will be ignored.
+ *
+ *  :ignore_whitespace_eol ::
+ *    If true, whitespace at end of line will be ignored.
+ *
+ *  :ignore_submodules ::
+ *    if true, submodules will be excluded from the diff completely.
+ *
+ *  :patience ::
+ *    If true, the "patience diff" algorithm will be used (currenlty unimplemented).
+ *
+ *  :include_ignored ::
+ *    If true, ignored files will be included in the diff.
+ *
+ *  :include_untracked ::
+ *   If true, untracked files will be included in the diff.
+ *
+ *  :include_unmodified ::
+ *    If true, unmodified files will be included in the diff.
+ *
+ *  :recurse_untracked_dirs ::
+ *    Even if +:include_untracked+ is true, untracked directories will only be
+ *    marked with a single entry in the diff. If this flag is set to true,
+ *    all files under ignored directories will be included in the diff, too.
+ *
+ *  :disable_pathspec_match ::
+ *    If true, the given +:paths+ will be applied as exact matches, instead of
+ *    as fnmatch patterns.
+ *
+ *  :deltas_are_icase ::
+ *    If true, filename comparisons will be made with case-insensitivity.
+ *
+ *  :include_untracked_content ::
+ *    if true, untracked content will be contained in the the diff patch text.
+ *
+ *  :skip_binary_check ::
+ *    If true, diff deltas will be generated without spending time on binary
+ *    detection. This is useful to improve performance in cases where the actual
+ *    file content difference is not needed.
+ *
+ *  :include_typechange ::
+ *    If true, type changes for files will not be interpreted as deletion of
+ *    the "old file" and addition of the "new file", but will generate
+ *    typechange records.
+ *
+ *  :include_typechange_trees ::
+ *    Even if +:include_typechange+ is true, blob -> tree changes will still
+ *    usually be handled as a deletion of the blob. If this flag is set to true,
+ *    blob -> tree changes will be marked as typechanges.
+ *
+ *  :ignore_filemode ::
+ *    If true, file mode changes will be ignored.
+ *
+ *  :recurse_ignored_dirs ::
+ *    Even if +:include_ignored+ is true, ignored directories will only be
+ *    marked with a single entry in the diff. If this flag is set to true,
+ *    all files under ignored directories will be included in the diff, too.
+ *
+ *  Examples:
+ *
+ *    # Emulating `git diff <treeish>`
+ *    tree = Rugged::Tree.lookup(repo, "d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+ *    diff = tree.diff(repo.index)
+ *    diff.merge!(tree.diff)
+ *
+ *    # Tree-to-Tree Diff
+ *    tree = Rugged::Tree.lookup(repo, "d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+ *    other_tree = Rugged::Tree.lookup(repo, "7a9e0b02e63179929fed24f0a3e0f19168114d10")
+ *    diff = tree.diff(other_tree)
+ */
+static VALUE rb_git_tree_diff_(int argc, VALUE *argv, VALUE self)
+{
+	git_tree *tree = NULL;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_repository *repo = NULL;
+	git_diff *diff = NULL;
+	VALUE rb_self, rb_repo, rb_other, rb_options;
+	int error;
+
+	rb_scan_args(argc, argv, "22", &rb_repo, &rb_self, &rb_other, &rb_options);
+	rugged_parse_diff_options(&opts, rb_options);
+
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	if (!NIL_P(rb_self)) {
+		if (!rb_obj_is_kind_of(rb_self, rb_cRuggedTree))
+			rb_raise(rb_eTypeError,
+				"At least a Rugged::Tree object is required for diffing");
+
+		Data_Get_Struct(rb_self, git_tree, tree);
+	}
+
+	if (NIL_P(rb_other)) {
+		if (tree == NULL) {
+			xfree(opts.pathspec.strings);
+			rb_raise(rb_eTypeError, "Need 'old' or 'new' for diffing");
+		}
+
+		error = git_diff_tree_to_tree(&diff, repo, tree, NULL, &opts);
+	} else {
+		if (TYPE(rb_other) == T_STRING)
+			rb_other = rugged_object_rev_parse(rb_repo, rb_other, 1);
+
+		if (rb_obj_is_kind_of(rb_other, rb_cRuggedCommit)) {
+			git_tree *other_tree;
+			git_commit *commit;
+
+			Data_Get_Struct(rb_other, git_commit, commit);
+			error = git_commit_tree(&other_tree, commit);
+
+			if (!error) {
+				error = git_diff_tree_to_tree(&diff, repo, tree, other_tree, &opts);
+				git_tree_free(other_tree);
+			}
+		} else if (rb_obj_is_kind_of(rb_other, rb_cRuggedTree)) {
+			git_tree *other_tree;
+
+			Data_Get_Struct(rb_other, git_tree, other_tree);
+			error = git_diff_tree_to_tree(&diff, repo, tree, other_tree, &opts);
+		} else if (rb_obj_is_kind_of(rb_other, rb_cRuggedIndex)) {
+			git_index *index;
+			Data_Get_Struct(rb_other, git_index, index);
+			error = git_diff_tree_to_index(&diff, repo, tree, index, &opts);
+		} else {
+			xfree(opts.pathspec.strings);
+			rb_raise(rb_eTypeError, "A Rugged::Commit, Rugged::Tree or Rugged::Index instance is required");
+		}
+	}
+
+	xfree(opts.pathspec.strings);
+	rugged_exception_check(error);
+
+	return rugged_diff_new(rb_cRuggedDiff, rb_repo, diff);
+}
+
+/*
+ *  call-seq:
+ *    tree.diff_workdir([options]) -> diff
+ *
+ *  Returns a diff between a tree and the current workdir.
+ *
+ *  The +tree+ object will be used as the "old file" side of the diff, while the
+ *  content of the current workdir will be used for the "new file" side.
+ *
+ *  See Rugged::Tree#diff for a list of options that can be passed.
+ */
+static VALUE rb_git_tree_diff_workdir(int argc, VALUE *argv, VALUE self)
+{
+	git_tree *tree;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_repository *repo;
+	git_diff *diff;
+	VALUE owner, rb_options;
+	int error;
+
+	rb_scan_args(argc, argv, "00:", &rb_options);
+	rugged_parse_diff_options(&opts, rb_options);
+
+	Data_Get_Struct(self, git_tree, tree);
+	owner = rugged_owner(self);
+	Data_Get_Struct(owner, git_repository, repo);
+
+	error = git_diff_tree_to_workdir(&diff, repo, tree, &opts);
+
+	xfree(opts.pathspec.strings);
+	rugged_exception_check(error);
+
+	return rugged_diff_new(rb_cRuggedDiff, owner, diff);
+}
+
+void rugged_parse_merge_options(git_merge_options *opts, VALUE rb_options)
+{
+	if (!NIL_P(rb_options)) {
+		VALUE rb_value;
+		Check_Type(rb_options, T_HASH);
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("rename_threshold"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts->rename_threshold = FIX2UINT(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("target_limit"));
+		if (!NIL_P(rb_value)) {
+			Check_Type(rb_value, T_FIXNUM);
+			opts->target_limit = FIX2UINT(rb_value);
+		}
+
+		rb_value = rb_hash_aref(rb_options, CSTR2SYM("favor"));
+		if (!NIL_P(rb_value)) {
+			ID id_favor;
+
+			Check_Type(rb_value, T_SYMBOL);
+			id_favor = SYM2ID(rb_value);
+
+			if (id_favor == rb_intern("normal")) {
+				opts->file_favor = GIT_MERGE_FILE_FAVOR_NORMAL;
+			} else if (id_favor == rb_intern("ours")) {
+				opts->file_favor = GIT_MERGE_FILE_FAVOR_OURS;
+			} else if (id_favor == rb_intern("theirs")) {
+				opts->file_favor = GIT_MERGE_FILE_FAVOR_THEIRS;
+			} else if (id_favor == rb_intern("union")) {
+				opts->file_favor = GIT_MERGE_FILE_FAVOR_UNION;
+			} else {
+				rb_raise(rb_eTypeError,
+					"Invalid favor mode. Expected `:normal`, `:ours`, `:theirs` or `:union`");
+			}
+		}
+
+		if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("renames")))) {
+			opts->tree_flags |= GIT_MERGE_TREE_FIND_RENAMES;
+		}
+	}
+}
+
+/*
+ *  tree.merge(other_tree[, ancestor_tree[, options]]) -> Rugged::Index
+ *  tree.merge(other_tree[, options]) -> Rugged::Index
+ *
+ *  Merges two trees and returns the a Rugged::Index object that reflects
+ *  the result of the merge.
+ *
+ *  The following options can be passed in the +options+ Hash:
+ *
+ *  :renames ::
+ *    If true, looking for renames will be enabled (`--find-renames`).
+ *
+ *  :rename_threshold ::
+ *    An integer specifying the minimum similarity of a file to be
+ *    seen as an eligible rename source (default 50).
+ *
+ *  :target_limit ::
+ *    An integer specifying the maximum byte size of a file before a it will
+ *    be treated as binary. The default value is 512MB.
+ *
+ *  :favor ::
+ *    Specifies how and if conflicts are auto-resolved by favoring a specific
+ *    file output. Can be one of `:normal`, `:ours`, `:theirs` or `:union`.
+ *
+ */
+static VALUE rb_git_tree_merge(int argc, VALUE *argv, VALUE self)
+{
+	VALUE rb_other_tree, rb_ancestor_tree, rb_options;
+	VALUE rb_repo = rugged_owner(self);
+
+	git_tree *tree, *other_tree, *ancestor_tree;
+	git_repository *repo;
+	git_index *index;
+	git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+	int error;
+
+	if (rb_scan_args(argc, argv, "12", &rb_other_tree, &rb_ancestor_tree, &rb_options) == 2) {
+		if (TYPE(rb_ancestor_tree) == T_HASH) {
+			rb_options = rb_ancestor_tree;
+			rb_ancestor_tree = Qnil;
+		}
+	}
+
+	if (!NIL_P(rb_options)) {
+		Check_Type(rb_options, T_HASH);
+		rugged_parse_merge_options(&opts, rb_options);
+	}
+
+	if (!rb_obj_is_kind_of(rb_other_tree, rb_cRuggedTree))
+		rb_raise(rb_eTypeError, "Expecting a Rugged::Tree instance");
+	else if (!NIL_P(rb_ancestor_tree) && !rb_obj_is_kind_of(rb_ancestor_tree, rb_cRuggedTree))
+		rb_raise(rb_eTypeError, "Expecting a Rugged::Tree instance");
+
+	Data_Get_Struct(self, git_tree, tree);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+	Data_Get_Struct(rb_other_tree, git_tree, other_tree);
+
+	if (!NIL_P(rb_ancestor_tree))
+		Data_Get_Struct(rb_ancestor_tree, git_tree, ancestor_tree);
+	else
+		ancestor_tree = NULL;
+
+	error = git_merge_trees(&index, repo, ancestor_tree, tree, other_tree, &opts);
+	rugged_exception_check(error);
+
+	return rugged_index_new(rb_cRuggedIndex, rb_repo, index);
+}
+
+static void rb_git_treebuilder_free(git_treebuilder *bld)
+{
+	git_treebuilder_free(bld);
+}
+
+/*
+ *  call-seq:
+ *    Tree::Builder.new(repository, [tree])
+ *
+ *  Create a new Rugged::Tree::Builder instance to write a tree to
+ *  the given +repository+.
+ *
+ *  If an optional +tree+ is given, the returned Tree::Builder will be
+ *  initialized with the entry of +tree+. Otherwise, the Tree::Builder
+ *  will be empty and has to be filled manually.
+ */
+static VALUE rb_git_treebuilder_new(int argc, VALUE *argv, VALUE klass)
+{
+	git_treebuilder *builder;
+	git_repository *repo;
+	git_tree *tree = NULL;
+	VALUE rb_object, rb_builder, rb_repo;
+	int error;
+
+	if (rb_scan_args(argc, argv, "11", &rb_repo, &rb_object) == 2) {
+		if (!rb_obj_is_kind_of(rb_object, rb_cRuggedTree))
+			rb_raise(rb_eTypeError, "A Rugged::Tree instance is required");
+
+		Data_Get_Struct(rb_object, git_tree, tree);
+	}
+
+	rugged_check_repo(rb_repo);
+	Data_Get_Struct(rb_repo, git_repository, repo);
+
+	error = git_treebuilder_new(&builder, repo, tree);
+	rugged_exception_check(error);
+
+	rb_builder = Data_Wrap_Struct(klass, NULL, &rb_git_treebuilder_free, builder);
+	rugged_set_owner(rb_builder, rb_repo);
+
+	return rb_builder;
+}
+
+/*
+ *  call-seq:
+ *    builder.clear -> nil
+ *
+ *  Clear all entries in +builder+.
+ */
+static VALUE rb_git_treebuilder_clear(VALUE self)
+{
+	git_treebuilder *builder;
+	Data_Get_Struct(self, git_treebuilder, builder);
+	git_treebuilder_clear(builder);
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    builder[path] -> entry
+ *
+ *  Return an entry from +builder+ based on its relative path.
+ */
+static VALUE rb_git_treebuilder_get(VALUE self, VALUE path)
+{
+	git_treebuilder *builder;
+	Data_Get_Struct(self, git_treebuilder, builder);
+
+	Check_Type(path, T_STRING);
+
+	return rb_git_treeentry_fromC(git_treebuilder_get(builder, StringValueCStr(path)));
+}
+
+/*
+ *  call-seq:
+ *    builder << entry      -> nil
+ *    builder.insert(entry) -> nil
+ *
+ *  Inser a new entry into +builder+.
+ */
+static VALUE rb_git_treebuilder_insert(VALUE self, VALUE rb_entry)
+{
+	git_treebuilder *builder;
+	VALUE rb_path, rb_oid, rb_attr;
+	git_oid oid;
+	int error;
+
+	Data_Get_Struct(self, git_treebuilder, builder);
+	Check_Type(rb_entry, T_HASH);
+
+	rb_path = rb_hash_aref(rb_entry, CSTR2SYM("name"));
+	Check_Type(rb_path, T_STRING);
+
+	rb_oid = rb_hash_aref(rb_entry, CSTR2SYM("oid"));
+	Check_Type(rb_oid, T_STRING);
+	rugged_exception_check(git_oid_fromstr(&oid, StringValueCStr(rb_oid)));
+
+	rb_attr = rb_hash_aref(rb_entry, CSTR2SYM("filemode"));
+	Check_Type(rb_attr, T_FIXNUM);
+
+	error = git_treebuilder_insert(NULL,
+		builder,
+		StringValueCStr(rb_path),
+		&oid,
+		FIX2INT(rb_attr));
+
+	rugged_exception_check(error);
+	return Qnil;
+}
+
+/*
+ *  call-seq:
+ *    builder.remove(path) -> true or false
+ *
+ *  Remove an entry from +builder+ by its relative +path+.
+ *
+ *  Returns +true+ if the entry was successfully removed,
+ *  or +false+ if the entry was not found.
+ */
+static VALUE rb_git_treebuilder_remove(VALUE self, VALUE path)
+{
+	git_treebuilder *builder;
+	int error;
+
+	Data_Get_Struct(self, git_treebuilder, builder);
+	Check_Type(path, T_STRING);
+
+	error = git_treebuilder_remove(builder, StringValueCStr(path));
+	if (error == GIT_ENOTFOUND)
+		return Qfalse;
+
+	rugged_exception_check(error);
+	return Qtrue;
+}
+
+/*
+ *  call-seq:
+ *    builder.write -> oid
+ *
+ *  Write +builder+'s content as a tree to the repository
+ *  that owns the builder and return the +oid+ for the
+ *  newly created tree.
+ */
+static VALUE rb_git_treebuilder_write(VALUE self)
+{
+	git_treebuilder *builder;
+	git_oid written_id;
+	int error;
+
+	Data_Get_Struct(self, git_treebuilder, builder);
+
+	error = git_treebuilder_write(&written_id, builder);
+	rugged_exception_check(error);
+
+	return rugged_create_oid(&written_id);
+}
+
+static int treebuilder_cb(const git_tree_entry *entry, void *opaque)
+{
+	VALUE proc = (VALUE)opaque;
+	VALUE ret = rb_funcall(proc, rb_intern("call"), 1, rb_git_treeentry_fromC(entry));
+	return rugged_parse_bool(ret);
+}
+
+/*
+ *  call-seq:
+ *    builder.reject! { |entry| block } -> nil
+ *
+ *  Deletes every tree +entry+ from +builder+ for which
+ *  the given +block+ evaluates to true.
+ */
+static VALUE rb_git_treebuilder_filter(VALUE self)
+{
+	git_treebuilder *builder;
+
+	rb_need_block();
+	Data_Get_Struct(self, git_treebuilder, builder);
+
+	git_treebuilder_filter(builder, &treebuilder_cb, (void *)rb_block_proc());
+	return Qnil;
+}
+
+void Init_rugged_tree(void)
+{
+	/*
+	 * Tree
+	 */
+	rb_cRuggedTree = rb_define_class_under(rb_mRugged, "Tree", rb_cRuggedObject);
+	rb_define_method(rb_cRuggedTree, "count", rb_git_tree_entrycount, 0);
+	rb_define_method(rb_cRuggedTree, "count_recursive", rb_git_tree_entrycount_recursive, -1);
+	rb_define_method(rb_cRuggedTree, "length", rb_git_tree_entrycount, 0);
+	rb_define_method(rb_cRuggedTree, "get_entry", rb_git_tree_get_entry, 1);
+	rb_define_method(rb_cRuggedTree, "get_entry_by_oid", rb_git_tree_get_entry_by_oid, 1);
+	rb_define_method(rb_cRuggedTree, "path", rb_git_tree_path, 1);
+	rb_define_method(rb_cRuggedTree, "diff_workdir", rb_git_tree_diff_workdir, -1);
+	rb_define_method(rb_cRuggedTree, "[]", rb_git_tree_get_entry, 1);
+	rb_define_method(rb_cRuggedTree, "each", rb_git_tree_each, 0);
+	rb_define_method(rb_cRuggedTree, "walk", rb_git_tree_walk, 1);
+	rb_define_method(rb_cRuggedTree, "merge", rb_git_tree_merge, -1);
+
+	rb_define_singleton_method(rb_cRuggedTree, "diff", rb_git_tree_diff_, -1);
+
+	rb_cRuggedTreeBuilder = rb_define_class_under(rb_cRuggedTree, "Builder", rb_cObject);
+	rb_define_singleton_method(rb_cRuggedTreeBuilder, "new", rb_git_treebuilder_new, -1);
+	rb_define_method(rb_cRuggedTreeBuilder, "clear", rb_git_treebuilder_clear, 0);
+	rb_define_method(rb_cRuggedTreeBuilder, "[]", rb_git_treebuilder_get, 1);
+	rb_define_method(rb_cRuggedTreeBuilder, "insert", rb_git_treebuilder_insert, 1);
+	rb_define_method(rb_cRuggedTreeBuilder, "<<", rb_git_treebuilder_insert, 1);
+	rb_define_method(rb_cRuggedTreeBuilder, "remove", rb_git_treebuilder_remove, 1);
+	rb_define_method(rb_cRuggedTreeBuilder, "write", rb_git_treebuilder_write, 0);
+	rb_define_method(rb_cRuggedTreeBuilder, "reject!", rb_git_treebuilder_filter, 0);
+}
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged.rb b/app/server/vendor/rugged-0.23.3/lib/rugged.rb
new file mode 100755
index 0000000..1c9c211
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged.rb
@@ -0,0 +1,44 @@
+# Start modifications
+#
+# Original code:
+begin
+  RUBY_VERSION =~ /(\d+.\d+)/
+  require "rugged/#{$1}/rugged"
+rescue LoadError
+
+  # Modifications made for Sonic Pi multi-platform compatibility:
+  require 'rbconfig'
+  ruby_api = RbConfig::CONFIG['ruby_version']
+  os = case RUBY_PLATFORM
+       when /.*arm.*-linux.*/
+         :raspberry
+       when /.*linux.*/
+         :linux
+       when /.*darwin.*/
+         :osx
+       when /.*mingw.*/
+         :windows
+       else
+         RUBY_PLATFORM
+       end
+  require_relative "../../../rb-native/#{os}/#{ruby_api}/rugged"
+end
+# End modifications
+
+require 'rugged/index'
+require 'rugged/object'
+require 'rugged/commit'
+require 'rugged/version'
+require 'rugged/repository'
+require 'rugged/reference'
+require 'rugged/walker'
+require 'rugged/tree'
+require 'rugged/tag'
+require 'rugged/branch'
+require 'rugged/diff'
+require 'rugged/patch'
+require 'rugged/remote'
+require 'rugged/credentials'
+require 'rugged/attributes'
+require 'rugged/blob'
+require 'rugged/submodule_collection'
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/attributes.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/attributes.rb
new file mode 100755
index 0000000..d9ebae8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/attributes.rb
@@ -0,0 +1,41 @@
+module Rugged
+  class Repository
+    def attributes(path, options = {})
+      Attributes.new(self, path, options)
+    end
+
+    class Attributes
+      include Enumerable
+
+      LOAD_PRIORITIES = {
+        [:file, :index] => 0,
+        [:index, :file] => 1,
+        [:index] => 2,
+      }
+
+      def self.parse_opts(opt)
+        flags = LOAD_PRIORITIES[opt[:priority]] || 0
+        flags |= 4 if opt[:skip_system]
+        flags
+      end
+
+      def initialize(repository, path, options = {})
+        @repository = repository
+        @path = path
+        @load_flags = Attributes.parse_opts(options)
+      end
+
+      def [](attribute)
+        @repository.fetch_attributes(@path, attribute, @load_flags)
+      end
+
+      def to_h
+        @hash ||= @repository.fetch_attributes(@path, nil, @load_flags)
+      end
+
+      def each(&block)
+        to_h.each(&block)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/blob.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/blob.rb
new file mode 100755
index 0000000..96293d9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/blob.rb
@@ -0,0 +1,28 @@
+module Rugged
+  class Blob
+    class HashSignature
+      WHITESPACE_DEFAULT  = 0
+      WHITESPACE_IGNORE   = 1
+      WHITESPACE_SMART    = 2
+    end
+
+    def hashsig(options = 0)
+      @hashsig ||= HashSignature.new(self, options)
+    end
+
+    def similarity(other)
+      other_sig = case other
+      when HashSignature
+        other
+      when String
+        HashSignature.new(other)
+      when Blob
+        other.hashsig
+      else
+        raise TypeError, "Expected a Rugged::Blob, String or Rugged::Blob::HashSignature"
+      end
+
+      HashSignature.compare(self.hashsig, other_sig)
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/branch.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/branch.rb
new file mode 100755
index 0000000..9ac77b2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/branch.rb
@@ -0,0 +1,19 @@
+module Rugged
+  class Branch < Rugged::Reference
+    def ==(other)
+      other.instance_of?(Rugged::Branch) &&
+        other.canonical_name == self.canonical_name
+    end
+    
+    # Get the remote the branch belongs to.
+    #
+    # If the branch is remote returns the remote it belongs to.
+    # In case of local branch, it returns the remote of the branch
+    # it tracks or nil if there is no tracking branch.
+    #
+    def remote
+      remote_name = self.remote_name
+      @owner.remotes[remote_name] if remote_name
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/commit.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/commit.rb
new file mode 100755
index 0000000..f7adea2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/commit.rb
@@ -0,0 +1,50 @@
+module Rugged
+  class Commit
+
+    def self.prettify_message(msg, strip_comments = true)
+      Rugged::prettify_message(msg, strip_comments)
+    end
+
+    def inspect
+      "#<Rugged::Commit:#{object_id} {message: #{message.inspect}, tree: #{tree.inspect}, parents: #{parent_oids}}>"
+    end
+
+    # Return a diff between this commit and its first parent or another commit or tree.
+    #
+    # See Rugged::Tree#diff for more details.
+    def diff(*args)
+      args.unshift(parents.first) if args.size == 1 && args.first.is_a?(Hash)
+      self.tree.diff(*args)
+    end
+
+    # Return a diff between this commit and the workdir.
+    #
+    # See Rugged::Tree#diff_workdir for more details.
+    def diff_workdir(options = {})
+      self.tree.diff_workdir(options)
+    end
+
+    # The time when this commit was made effective. This is the same value
+    # as the +:time+ attribute for +commit.committer+.
+    #
+    # Returns a Time object
+    def time
+      @time ||= Time.at(self.epoch_time)
+    end
+
+    def to_hash
+      {
+        :message => message,
+        :committer => committer,
+        :author => author,
+        :tree => tree,
+        :parents => parents,
+      }
+    end
+
+    def modify(new_args, update_ref=nil)
+      args = self.to_hash.merge(new_args)
+      Commit.create(args, update_ref)
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/console.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/console.rb
new file mode 100755
index 0000000..3f9650c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/console.rb
@@ -0,0 +1,9 @@
+# Loaded by script/console. Land helpers here.
+
+def repo
+  Rugged::Repository.new(File.expand_path('../../../', __FILE__))
+end
+
+Pry.config.prompt = lambda do |context, nesting, pry|
+  "[rugged] #{context}> "
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/credentials.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/credentials.rb
new file mode 100755
index 0000000..a68f868
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/credentials.rb
@@ -0,0 +1,43 @@
+module Rugged
+  module Credentials
+    # A plain-text username and password credential object.
+    class UserPassword
+      def initialize(options)
+        @username, @password = options[:username], options[:password]
+      end
+
+      def call(url, username_from_url, allowed_types)
+        self
+      end
+    end
+
+    # A ssh key credential object that can optionally be passphrase-protected
+    class SshKey
+      def initialize(options)
+        @username, @publickey, @privatekey, @passphrase = options[:username], options[:publickey], options[:privatekey], options[:passphrase]
+      end
+
+      def call(url, username_from_url, allowed_types)
+        self
+      end
+    end
+
+    class SshKeyFromAgent
+      def initialize(options)
+        @username = options[:username]
+      end
+
+      def call(url, username_from_url, allowed_types)
+        self
+      end
+    end
+
+    # A "default" credential usable for Negotiate mechanisms like NTLM or
+    # Kerberos authentication
+    class Default
+      def call(url, username_from_url, allowed_types)
+        self
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/diff.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/diff.rb
new file mode 100755
index 0000000..b37cb99
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/diff.rb
@@ -0,0 +1,20 @@
+require 'rugged/diff/hunk'
+require 'rugged/diff/line'
+require 'rugged/diff/delta'
+
+module Rugged
+  class Diff
+    include Enumerable
+    alias each each_patch
+
+    attr_reader :owner
+
+    def patches
+      each_patch.to_a
+    end
+
+    def deltas
+      each_delta.to_a
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/diff/delta.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/diff/delta.rb
new file mode 100755
index 0000000..132b5ad
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/diff/delta.rb
@@ -0,0 +1,53 @@
+module Rugged
+  class Diff
+    class Delta
+      attr_reader :owner
+      alias diff owner
+
+      attr_reader :old_file
+      attr_reader :new_file
+      attr_reader :similarity
+      attr_reader :status
+      attr_reader :status_char
+      attr_reader :binary
+
+      alias binary? binary
+
+      def added?
+        status == :added
+      end
+
+      def deleted?
+        status == :deleted
+      end
+
+      def modified?
+        status == :modified
+      end
+
+      def renamed?
+        status == :renamed
+      end
+
+      def copied?
+        status == :copied
+      end
+
+      def ignored?
+        status == :ignored
+      end
+
+      def untracked?
+        status == :untracked
+      end
+
+      def typechange?
+        status == :typechange
+      end
+
+      def inspect
+        "#<#{self.class.name}:#{object_id} {old_file: #{old_file.inspect}, new_file: #{new_file.inspect}, similarity: #{similarity.inspect}, status: #{status.inspect}>"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/diff/hunk.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/diff/hunk.rb
new file mode 100755
index 0000000..3182adf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/diff/hunk.rb
@@ -0,0 +1,18 @@
+module Rugged
+  class Diff
+    class Hunk
+      def delta
+        @owner
+      end
+
+      def inspect
+        "#<#{self.class.name}:#{object_id} {header: #{header.inspect}, count: #{count.inspect}}>"
+      end
+
+      # Returns an Array containing all lines of the hunk.
+      def lines
+        each_line.to_a
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/diff/line.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/diff/line.rb
new file mode 100755
index 0000000..83c87be
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/diff/line.rb
@@ -0,0 +1,47 @@
+module Rugged
+  class Diff
+    class Line
+      attr_reader :line_origin, :content, :old_lineno, :new_lineno, :content_offset
+
+      def context?
+        @line_origin == :context
+      end
+
+      def addition?
+        @line_origin == :addition
+      end
+
+      def deletion?
+        @line_origin == :deletion
+      end
+
+      def eof_no_newline?
+        @line_origin == :eof_no_newline
+      end
+
+      def eof_newline_added?
+        @line_origin == :eof_newline_added
+      end
+
+      def eof_newline_removed?
+        @line_origin == :eof_newline_removed
+      end
+
+      def file_header?
+        @line_origin == :file_header
+      end
+
+      def hunk_header?
+        @line_origin == :hunk_header
+      end
+
+      def binary?
+        @line_origin == :binary
+      end
+
+      def inspect
+        "#<#{self.class.name}:#{object_id} {line_origin: #{line_origin.inspect}, content: #{content.inspect}>"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/index.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/index.rb
new file mode 100755
index 0000000..6abc778
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/index.rb
@@ -0,0 +1,13 @@
+module Rugged
+  class Index
+    include Enumerable
+
+    def to_s
+      s = "#<Rugged::Index\n"
+      self.each do |entry|
+        s << "  [#{entry[:stage]}] '#{entry[:path]}'\n"
+      end
+      s + '>'
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/object.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/object.rb
new file mode 100755
index 0000000..a74ec70
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/object.rb
@@ -0,0 +1,7 @@
+module Rugged
+  class Object
+    def <=>(other)
+      self.oid <=> other.oid
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/patch.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/patch.rb
new file mode 100755
index 0000000..b93ac58
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/patch.rb
@@ -0,0 +1,36 @@
+module Rugged
+  class Patch
+    include Enumerable
+    alias each each_hunk
+
+    alias size hunk_count
+    alias count hunk_count
+
+    attr_accessor :owner
+    alias diff owner
+
+    def inspect
+      "#<#{self.class.name}:#{object_id}>"
+    end
+
+    # Returns the number of additions in the patch.
+    def additions
+      stat[0]
+    end
+
+    # Returns the number of deletions in the patch.
+    def deletions
+      stat[1]
+    end
+
+    # Returns the number of total changes in the patch.
+    def changes
+      additions + deletions
+    end
+
+    # Returns an Array containing all hunks of the patch.
+    def hunks
+      each_hunk.to_a
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/reference.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/reference.rb
new file mode 100755
index 0000000..471dd57
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/reference.rb
@@ -0,0 +1,7 @@
+module Rugged
+  class Reference
+    def inspect
+      "#<#{self.class}:#{object_id} {name: #{name.inspect}, target: #{target.inspect}}>"
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/remote.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/remote.rb
new file mode 100755
index 0000000..2c64442
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/remote.rb
@@ -0,0 +1,4 @@
+module Rugged
+  class Remote
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/repository.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/repository.rb
new file mode 100755
index 0000000..cbffb3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/repository.rb
@@ -0,0 +1,227 @@
+module Rugged
+  # Repository is an interface into a Git repository on-disk. It's the primary
+  # interface between your app and the main Git objects Rugged makes available
+  # to you.
+  class Repository
+    # Pretty formatting of a Repository.
+    #
+    # Returns a very pretty String.
+    def inspect
+      "#<Rugged::Repository:#{object_id} {path: #{path.inspect}}>"
+    end
+
+    # Get the most recent commit from this repo.
+    #
+    # Returns a Rugged::Commit object.
+    def last_commit
+      self.head.target
+    end
+
+    # Checkout the specified branch, reference or commit.
+    #
+    # target - A revparse spec for the branch, reference or commit to check out.
+    # options - Options passed to #checkout_tree.
+    def checkout(target, options = {})
+      options[:strategy] ||= :safe
+      options.delete(:paths)
+
+      return checkout_head(options) if target == "HEAD"
+
+      if target.kind_of?(Rugged::Branch)
+        branch = target
+      else
+        branch = branches[target]
+      end
+
+      if branch
+        self.checkout_tree(branch.target, options)
+
+        if branch.remote?
+          references.create("HEAD", branch.target_id, force: true)
+        else
+          references.create("HEAD", branch.canonical_name, force: true)
+        end
+      else
+        commit = Commit.lookup(self, self.rev_parse_oid(target))
+        references.create("HEAD", commit.oid, force: true)
+        self.checkout_tree(commit, options)
+      end
+    end
+
+    def diff(left, right, opts = {})
+      left = rev_parse(left) if left.kind_of?(String)
+      right = rev_parse(right) if right.kind_of?(String)
+
+      if !left.is_a?(Rugged::Tree) && !left.is_a?(Rugged::Commit) && !left.nil?
+        raise TypeError, "Expected a Rugged::Tree or Rugged::Commit instance"
+      end
+
+      if !right.is_a?(Rugged::Tree) && !right.is_a?(Rugged::Commit) && !right.nil?
+        raise TypeError, "Expected a Rugged::Tree or Rugged::Commit instance"
+      end
+
+      if left
+        left.diff(right, opts)
+      elsif right
+        right.diff(left, opts.merge(:reverse => !opts[:reverse]))
+      end
+    end
+
+    def diff_workdir(left, opts = {})
+      left = rev_parse(left) if left.kind_of?(String)
+
+      if !left.is_a?(Rugged::Tree) && !left.is_a?(Rugged::Commit)
+        raise TypeError, "Expected a Rugged::Tree or Rugged::Commit instance"
+      end
+
+      left.diff_workdir(opts)
+    end
+
+    # Walks over a set of commits using Rugged::Walker.
+    #
+    # from    - The String SHA1 to push onto Walker to begin our walk.
+    # sorting - The sorting order of the commits, as defined in the README.
+    # block   - A block that we pass into walker#each.
+    #
+    # Returns nothing if called with a block, otherwise returns an instance of
+    # Enumerable::Enumerator containing Rugged::Commit objects.
+    def walk(from, sorting=Rugged::SORT_DATE, &block)
+      walker = Rugged::Walker.new(self)
+      walker.sorting(sorting)
+      walker.push(from)
+      walker.each(&block)
+    end
+
+    # Look up a SHA1.
+    #
+    # Returns one of the four classes that inherit from Rugged::Object.
+    def lookup(oid)
+      Rugged::Object.lookup(self, oid)
+    end
+
+    # Look up an object by a revision string.
+    #
+    # Returns one of the four classes that inherit from Rugged::Object.
+    def rev_parse(spec)
+      Rugged::Object.rev_parse(self, spec)
+    end
+
+    # Look up an object by a revision string.
+    #
+    # Returns the oid of the matched object as a String
+    def rev_parse_oid(spec)
+      Rugged::Object.rev_parse_oid(self, spec)
+    end
+
+    # Look up a single reference by name.
+    #
+    # Example:
+    #
+    #   repo.ref 'refs/heads/master'
+    #   # => #<Rugged::Reference:2199125780 {name: "refs/heads/master",
+    #          target: "25b5d3b40c4eadda8098172b26c68cf151109799"}>
+    #
+    # Returns a Rugged::Reference.
+    def ref(ref_name)
+      references[ref_name]
+    end
+
+    def refs(glob = nil)
+      references.each(glob)
+    end
+
+    def references
+      @references ||= ReferenceCollection.new(self)
+    end
+
+    def ref_names(glob = nil)
+      references.each_name(glob)
+    end
+
+    # All the tags in the repository.
+    #
+    # Returns an TagCollection containing all the tags.
+    def tags
+      @tags ||= TagCollection.new(self)
+    end
+
+    # All the remotes in the repository.
+    #
+    # Returns a Rugged::RemoteCollection containing all the Rugged::Remote objects
+    # in the repository.
+    def remotes
+      @remotes ||= RemoteCollection.new(self)
+    end
+
+    # All the branches in the repository
+    #
+    # Returns an BranchCollection containing Rugged::Branch objects
+    def branches
+      @branches ||= BranchCollection.new(self)
+    end
+
+    # All the submodules in the repository
+    #
+    # Returns an SubmoduleCollection containing Rugged::Submodule objects
+    def submodules
+      @submodules ||= SubmoduleCollection.new(self)
+    end
+
+    # Create a new branch in the repository
+    #
+    # name - The name of the branch (without a full reference path)
+    # sha_or_ref - The target of the branch; either a String representing
+    # an OID or a reference name, or a Rugged::Object instance.
+    #
+    # Returns a Rugged::Branch object
+    def create_branch(name, sha_or_ref = "HEAD")
+      case sha_or_ref
+      when Rugged::Object
+        target = sha_or_ref.oid
+      else
+        target = rev_parse_oid(sha_or_ref)
+      end
+
+      branches.create(name, target)
+    end
+
+    # Get the blob at a path for a specific revision.
+    #
+    # revision - The String SHA1.
+    # path     - The String file path.
+    #
+    # Returns a String.
+    def blob_at(revision, path)
+      tree = Rugged::Commit.lookup(self, revision).tree
+      begin
+        blob_data = tree.path(path)
+      rescue Rugged::TreeError
+        return nil
+      end
+      blob = Rugged::Blob.lookup(self, blob_data[:oid])
+      (blob.type == :blob) ? blob : nil
+    end
+
+    def fetch(remote_or_url, *args)
+      unless remote_or_url.kind_of? Remote
+        remote_or_url = remotes[remote_or_url] || remotes.create_anonymous(remote_or_url)
+      end
+
+      remote_or_url.fetch(*args)
+    end
+
+    # Push a list of refspecs to the given remote.
+    #
+    # refspecs - A list of refspecs that should be pushed to the remote.
+    #
+    # Returns a hash containing the pushed refspecs as keys and
+    # any error messages or +nil+ as values.
+    def push(remote_or_url, *args)
+      unless remote_or_url.kind_of? Remote
+        remote_or_url = remotes[remote_or_url] || remotes.create_anonymous(remote_or_url)
+      end
+
+      remote_or_url.push(*args)
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/submodule_collection.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/submodule_collection.rb
new file mode 100755
index 0000000..d795e8b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/submodule_collection.rb
@@ -0,0 +1,48 @@
+module Rugged
+  class SubmoduleCollection
+
+    # call-seq:
+    #   submodules.setup_add(url, path[, options]) -> submodule
+    #
+    # Add a new +submodule+.
+    #
+    # This does <tt>"git submodule add"</tt> incuding fetch and checkout of the
+    # submodule contents.
+    #
+    # - +url+: URL for the submodule's remote
+    # - +path+: path at which the submodule should be created
+    #
+    # The +options+ hash accepts all options supported by Rugged::Remote#fetch
+    # and the following:
+    # :gitlink ::
+    #   (defaults to +true+) should workdir contain a
+    #   gitlink to the repository in +.git/modules+ vs. repository
+    #   directly in workdir.
+    #
+    # Returns the newly created +submodule+
+    def add(url, path, options = {})
+      submodule = setup_add(url, path, options)
+      clone_submodule(submodule.repository, options)
+      submodule.finalize_add
+    end
+
+    private
+    # currently libgit2's `git_submodule_add_setup` initializes a repo
+    # with a workdir for the submodule. libgit2's `git_clone` however
+    # requires the target for the clone to be an empty dir.
+    #
+    # This provides a ghetto clone implementation that:
+    # 1. fetches the remote
+    # 2. sets up a master branch to be tracking origin/master
+    # 3. checkouts the submodule
+    def clone_submodule(repo, fetch_options)
+      # the remote was just added by setup_add, no need to check presence
+      repo.remotes['origin'].fetch(fetch_options)
+
+      repo.branches.create('master','origin/master')
+      repo.branches['master'].upstream = repo.branches['origin/master']
+
+      repo.checkout_head(strategy: :force)
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/tag.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/tag.rb
new file mode 100755
index 0000000..96fd468
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/tag.rb
@@ -0,0 +1,31 @@
+module Rugged
+  class Tag < Rugged::Reference
+    def name
+      canonical_name.sub(%r{^refs/tags/}, "")
+    end
+
+    class Annotation
+      def self.prettify_message(msg, strip_comments = true)
+        Rugged::prettify_message(msg, strip_comments)
+      end
+
+      def inspect
+        "#<Rugged::Tag::Annotation:#{object_id} {name: #{name.inspect}, message: #{message.inspect}, target: #{target.inspect}>"
+      end
+
+      def to_hash
+        {
+          :message => message,
+          :name => name,
+          :target => target,
+          :tagger => tagger,
+        }
+      end
+
+      def modify(new_args, force=True)
+        args = self.to_hash.merge(new_args)
+        Tag.create(args, force)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/tree.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/tree.rb
new file mode 100755
index 0000000..f1c6a44
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/tree.rb
@@ -0,0 +1,38 @@
+module Rugged
+  class Tree
+    include Enumerable
+
+    attr_reader :owner
+    alias repo owner
+
+    def diff(other = nil, options = nil)
+      Tree.diff(repo, self, other, options)
+    end
+
+    def inspect
+      data = "#<Rugged::Tree:#{object_id} {oid: #{oid}}>\n"
+      self.each { |e| data << "  <\"#{e[:name]}\" #{e[:oid]}>\n" }
+      data
+    end
+
+    # Walks the tree but only yields blobs
+    def walk_blobs(mode=:postorder)
+      self.walk(mode) { |root, e| yield root, e if e[:type] == :blob }
+    end
+
+    # Walks the tree but only yields subtrees
+    def walk_trees(mode=:postorder)
+      self.walk(mode) { |root, e| yield root, e if e[:type] == :tree }
+    end
+
+    # Iterate over the blobs in this tree
+    def each_blob
+      self.each { |e| yield e if e[:type] == :blob }
+    end
+
+    # Iterat over the subtrees in this tree
+    def each_tree
+      self.each { |e| yield e if e[:type] == :tree }
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/version.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/version.rb
new file mode 100755
index 0000000..551abab
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/version.rb
@@ -0,0 +1,3 @@
+module Rugged
+  Version = VERSION = '0.23.3'
+end
diff --git a/app/server/vendor/rugged-0.23.3/lib/rugged/walker.rb b/app/server/vendor/rugged-0.23.3/lib/rugged/walker.rb
new file mode 100755
index 0000000..3161f40
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/lib/rugged/walker.rb
@@ -0,0 +1,5 @@
+module Rugged
+  class Walker
+    include Enumerable
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/rugged.gemspec b/app/server/vendor/rugged-0.23.3/rugged.gemspec
new file mode 100755
index 0000000..1ce05a9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/rugged.gemspec
@@ -0,0 +1,34 @@
+$:.push File.expand_path("../lib", __FILE__)
+
+if ENV['DEVELOPMENT']
+  VERSION = `git describe --tags`.strip.gsub('-', '.')[1..-1]
+else
+  require 'rugged/version'
+  VERSION = Rugged::Version
+end
+
+Gem::Specification.new do |s|
+  s.name                  = "rugged"
+  s.version               = VERSION
+  s.date                  = Time.now.strftime('%Y-%m-%d')
+  s.summary               = "Rugged is a Ruby binding to the libgit2 linkable library"
+  s.homepage              = "https://github.com/libgit2/rugged"
+  s.email                 = "schacon at gmail.com"
+  s.authors               = [ "Scott Chacon", "Vicent Marti" ]
+  s.license               = "MIT"
+  s.files                 = %w( README.md LICENSE )
+  s.files                 += Dir.glob("lib/**/*.rb")
+  s.files                 += Dir.glob("ext/**/*.[ch]")
+  s.files                 += Dir.glob("vendor/libgit2/cmake/**/*")
+  s.files                 += Dir.glob("vendor/libgit2/{include,src,deps}/**/*")
+  s.files                 += Dir.glob("vendor/libgit2/{CMakeLists.txt,Makefile.embed,AUTHORS,COPYING,libgit2.pc.in}")
+  s.extensions            = ['ext/rugged/extconf.rb']
+  s.required_ruby_version = '>= 1.9.3'
+  s.description           = <<desc
+Rugged is a Ruby bindings to the libgit2 linkable C Git library. This is
+for testing and using the libgit2 library in a language that is awesome.
+desc
+  s.add_development_dependency "rake-compiler", ">= 0.9.0"
+  s.add_development_dependency "pry"
+  s.add_development_dependency "minitest", "~> 3.0"
+end
diff --git a/app/server/vendor/rugged-0.23.3/script/bootstrap b/app/server/vendor/rugged-0.23.3/script/bootstrap
new file mode 100755
index 0000000..6fa6b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/script/bootstrap
@@ -0,0 +1,9 @@
+#!/bin/sh
+set -e
+
+cd "$(dirname "$0")/.."
+if bundle check 1>/dev/null 2>&1; then
+    echo "Gem environment up-to-date"
+else
+    exec bundle install --binstubs --path vendor/gems "$@"
+fi
diff --git a/app/server/vendor/rugged-0.23.3/script/bump-libgit2 b/app/server/vendor/rugged-0.23.3/script/bump-libgit2
new file mode 100755
index 0000000..9fdf9db
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/script/bump-libgit2
@@ -0,0 +1,14 @@
+#!/bin/sh
+set -e
+
+cd "$(dirname "$0")/../vendor/libgit2"
+
+git fetch origin
+git checkout origin/master
+
+LIBGIT2_SHA1=$(git rev-parse --verify HEAD)
+
+cd "../../"
+
+git add vendor/libgit2
+git commit -m "Bump libgit2 to $LIBGIT2_SHA1"
diff --git a/app/server/vendor/rugged-0.23.3/script/cibuild b/app/server/vendor/rugged-0.23.3/script/cibuild
new file mode 100755
index 0000000..1d68ec2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/script/cibuild
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+set -ex
+
+# change into root dir and setup path
+cd $(dirname "$0")/..
+PATH="$(pwd)/bin:$(pwd)/script:/usr/share/rbenv/shims:$PATH"
+
+export RBENV_VERSION="2.1.2-github"
+export CI_BUILD=1
+
+# Write commit we're building at
+git log -n 1 || true
+echo
+
+git submodule update --init
+
+(
+    cd vendor/libgit2
+    git fetch origin
+    git reset -q --hard origin/master
+)
+
+bundle install --path vendor/gems --binstubs
+bundle exec rake clean
+bundle exec rake compile
+bundle exec rake test
diff --git a/app/server/vendor/rugged-0.23.3/script/console b/app/server/vendor/rugged-0.23.3/script/console
new file mode 100755
index 0000000..3661576
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/script/console
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Run a Ruby REPL.
+
+set -e
+
+cd $(dirname "$0")/..
+exec ruby -S bin/pry -Ilib -r rugged -r rugged/console
diff --git a/app/server/vendor/rugged-0.23.3/script/travisbuild b/app/server/vendor/rugged-0.23.3/script/travisbuild
new file mode 100755
index 0000000..f19a703
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/script/travisbuild
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# Create a test repo which we can use for the online tests
+mkdir $HOME/_temp
+git init --bare $HOME/_temp/test.git
+git daemon --listen=localhost --export-all --enable=receive-pack --base-path=$HOME/_temp $HOME/_temp 2>/dev/null &
+
+ssh-keygen -t rsa -f ~/.ssh/rugged_test_rsa -N "" -q
+cat ~/.ssh/rugged_test_rsa.pub >>~/.ssh/authorized_keys
+ssh-keyscan -t rsa localhost >>~/.ssh/known_hosts
+
+export GITTEST_REMOTE_GIT_URL="git://localhost/test.git"
+export GITTEST_REMOTE_SSH_URL="ssh://localhost/$HOME/_temp/test.git"
+export GITTEST_REMOTE_SSH_USER=$USER
+export GITTEST_REMOTE_SSH_KEY="$HOME/.ssh/rugged_test_rsa"
+export GITTEST_REMOTE_SSH_PUBKEY="$HOME/.ssh/rugged_test_rsa.pub"
+export GITTEST_REMOTE_SSH_PASSPHRASE=""
+export GITTEST_REMOTE_REPO_PATH="$HOME/_temp/test.git"
+
+echo 'PasswordAuthentication yes' | sudo tee -a /etc/sshd_config
+eval $(ssh-agent)
+ssh-add $GITTEST_REMOTE_SSH_KEY
+
+# We need the config so the tests don't fail
+git config --global user.name 'The rugged tests are fragile'
+bundle exec rake || exit $?
diff --git a/app/server/vendor/rugged-0.23.3/test/blame_test.rb b/app/server/vendor/rugged-0.23.3/test/blame_test.rb
new file mode 100755
index 0000000..e35809c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/blame_test.rb
@@ -0,0 +1,169 @@
+require "test_helper"
+require "time"
+
+class BlameTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("testrepo")
+    @blame = Rugged::Blame.new(@repo, "branch_file.txt")
+  end
+
+  def test_blame_index
+    assert_equal 2, @blame.count
+
+    assert_equal({
+      :lines_in_hunk => 1,
+      :final_commit_id => "c47800c7266a2be04c571c04d5a6614691ea99bd",
+      :final_start_line_number => 1,
+      :final_signature => {
+        :name => "Scott Chacon",
+        :email => "schacon at gmail.com",
+        :time => Time.parse("2010-05-25 11:58:14 -0700")
+      },
+      :orig_commit_id => "c47800c7266a2be04c571c04d5a6614691ea99bd",
+      :orig_path => "branch_file.txt",
+      :orig_start_line_number => 1,
+      :orig_signature => {
+        :name => "Scott Chacon",
+        :email => "schacon at gmail.com",
+        :time => Time.parse("2010-05-25 11:58:14 -0700")
+      },
+      :boundary => false
+    }, @blame[0])
+
+    assert_equal({
+      :lines_in_hunk => 1,
+      :final_commit_id => "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+      :final_start_line_number => 2,
+      :final_signature => {
+        :name => "Scott Chacon",
+        :email => "schacon at gmail.com",
+        :time => Time.parse("2011-08-09 19:33:46 -0700")
+      },
+      :orig_commit_id => "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+      :orig_path => "branch_file.txt",
+      :orig_start_line_number => 2,
+      :orig_signature => {
+        :name => "Scott Chacon",
+        :email => "schacon at gmail.com",
+        :time => Time.parse("2011-08-09 19:33:46 -0700")
+      },
+      :boundary => false
+    }, @blame[1])
+
+    assert_equal @blame[1], @blame[-1]
+    assert_equal @blame[0], @blame[-2]
+
+    assert_nil @blame[-3]
+  end
+
+  def test_blame_options
+    blame = Rugged::Blame.new(@repo, "branch_file.txt", max_line: 1)
+    assert_equal 1, blame.count
+
+    assert_equal({
+      :lines_in_hunk => 1,
+      :final_commit_id => "c47800c7266a2be04c571c04d5a6614691ea99bd",
+      :final_start_line_number => 1,
+      :final_signature => {
+        :name => "Scott Chacon",
+        :email => "schacon at gmail.com",
+        :time => Time.parse("2010-05-25 11:58:14 -0700")
+      },
+      :orig_commit_id => "c47800c7266a2be04c571c04d5a6614691ea99bd",
+      :orig_path => "branch_file.txt",
+      :orig_start_line_number => 1,
+      :orig_signature => {
+        :name => "Scott Chacon",
+        :email => "schacon at gmail.com",
+        :time => Time.parse("2010-05-25 11:58:14 -0700")
+      },
+      :boundary => false
+    }, blame[0])
+
+
+    blame = Rugged::Blame.new(@repo, "branch_file.txt", min_line: 2)
+    assert_equal 1, blame.count
+
+    assert_equal({
+      :lines_in_hunk => 1,
+      :final_commit_id => "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+      :final_start_line_number => 2,
+      :final_signature => {
+        :name => "Scott Chacon",
+        :email => "schacon at gmail.com",
+        :time => Time.parse("2011-08-09 19:33:46 -0700")
+      },
+      :orig_commit_id => "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+      :orig_path => "branch_file.txt",
+      :orig_start_line_number => 2,
+      :orig_signature => {
+        :name => "Scott Chacon",
+        :email => "schacon at gmail.com",
+        :time => Time.parse("2011-08-09 19:33:46 -0700")
+      },
+      :boundary => false
+    }, blame[0])
+  end
+
+  def test_blame_for_line
+    assert_equal({
+      :lines_in_hunk => 1,
+      :final_commit_id => "c47800c7266a2be04c571c04d5a6614691ea99bd",
+      :final_start_line_number => 1,
+      :final_signature => {
+        :name => "Scott Chacon",
+        :email => "schacon at gmail.com",
+        :time => Time.parse("2010-05-25 11:58:14 -0700")
+      },
+      :orig_commit_id => "c47800c7266a2be04c571c04d5a6614691ea99bd",
+      :orig_path => "branch_file.txt",
+      :orig_start_line_number => 1,
+      :orig_signature => {
+        :name => "Scott Chacon",
+        :email => "schacon at gmail.com",
+        :time => Time.parse("2010-05-25 11:58:14 -0700")
+      },
+      :boundary => false
+    }, @blame.for_line(1))
+
+    assert_equal({
+      :lines_in_hunk => 1,
+      :final_commit_id => "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+      :final_start_line_number => 2,
+      :final_signature => {
+        :name => "Scott Chacon",
+        :email => "schacon at gmail.com",
+        :time => Time.parse("2011-08-09 19:33:46 -0700")
+      },
+      :orig_commit_id => "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+      :orig_path => "branch_file.txt",
+      :orig_start_line_number => 2,
+      :orig_signature => {
+        :name => "Scott Chacon",
+        :email => "schacon at gmail.com",
+        :time => Time.parse("2011-08-09 19:33:46 -0700")
+      },
+      :boundary => false
+    }, @blame.for_line(2))
+  end
+
+  def test_blame_with_invalid_line
+    assert_nil @blame.for_line(0)
+    assert_nil @blame.for_line(1000000)
+
+    assert_raises ArgumentError do
+      @blame.for_line(-1)
+    end
+  end
+
+  def test_each
+    hunks = []
+    @blame.each do |hunk|
+      hunks << hunk
+    end
+
+    assert_equal 2, hunks.count
+    assert_equal @blame[0], hunks[0]
+    assert_equal @blame[1], hunks[1]
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/blob_test.rb b/app/server/vendor/rugged-0.23.3/test/blob_test.rb
new file mode 100755
index 0000000..ded4104
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/blob_test.rb
@@ -0,0 +1,452 @@
+require "test_helper"
+
+class BlobTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_rugged("testrepo.git")
+  end
+
+  def test_lookup_raises_error_if_object_type_does_not_match
+    assert_raises Rugged::InvalidError do
+      # commit
+      Rugged::Blob.lookup(@repo, "8496071c1b46c854b31185ea97743be6a8774479")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # tag
+      Rugged::Blob.lookup(@repo, "0c37a5391bbff43c37f0d0371823a5509eed5b1d")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # tree
+      Rugged::Blob.lookup(@repo, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")
+    end
+
+    subclass = Class.new(Rugged::Blob)
+
+    assert_raises Rugged::InvalidError do
+      # commit
+      subclass.lookup(@repo, "8496071c1b46c854b31185ea97743be6a8774479")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # tag
+      subclass.lookup(@repo, "0c37a5391bbff43c37f0d0371823a5509eed5b1d")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # tree
+      subclass.lookup(@repo, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")
+    end
+  end
+
+  def test_read_blob_data
+    oid = "fa49b077972391ad58037050f2a75f74e3671e92"
+    blob = @repo.lookup(oid)
+    assert_equal 9, blob.size
+    assert_equal "new file\n", blob.content
+    assert_equal :blob, blob.type
+    assert_equal oid, blob.oid
+    assert_equal "new file\n", blob.text
+  end
+
+  def test_blob_sloc
+    oid = "7771329dfa3002caf8c61a0ceb62a31d09023f37"
+    blob = @repo.lookup(oid)
+    assert_equal 328, blob.sloc
+  end
+
+  def test_blob_content_with_size
+    oid = "7771329dfa3002caf8c61a0ceb62a31d09023f37"
+    blob = @repo.lookup(oid)
+    content =  blob.content(10)
+    assert_equal "# Rugged\n*", content
+    assert_equal 10, content.size
+  end
+
+  def test_blob_content_with_size_gt_file_size
+    oid = "7771329dfa3002caf8c61a0ceb62a31d09023f37"
+    blob = @repo.lookup(oid)
+    content =  blob.content(1000000)
+    assert_equal blob.size, content.size
+  end
+
+  def test_blob_content_with_zero_size
+    oid = "7771329dfa3002caf8c61a0ceb62a31d09023f37"
+    blob = @repo.lookup(oid)
+    content =  blob.content(0)
+    assert_equal '', content
+  end
+
+  def test_blob_content_with_negative_size
+    oid = "7771329dfa3002caf8c61a0ceb62a31d09023f37"
+    blob = @repo.lookup(oid)
+    content =  blob.content(-100)
+    assert_equal blob.size, content.size
+  end
+
+  def test_blob_text_with_max_lines
+    oid = "7771329dfa3002caf8c61a0ceb62a31d09023f37"
+    blob = @repo.lookup(oid)
+    assert_equal "# Rugged\n", blob.text(1)
+  end
+
+  def test_blob_text_with_lines_gt_file_lines
+    oid = "7771329dfa3002caf8c61a0ceb62a31d09023f37"
+    blob = @repo.lookup(oid)
+    text = blob.text(1000000)
+    assert_equal 464, text.lines.count
+  end
+
+  def test_blob_text_with_zero_lines
+    oid = "7771329dfa3002caf8c61a0ceb62a31d09023f37"
+    blob = @repo.lookup(oid)
+    text = blob.text(0)
+    assert_equal '', text
+  end
+
+  def test_blob_text_with_negative_lines
+    oid = "7771329dfa3002caf8c61a0ceb62a31d09023f37"
+    blob = @repo.lookup(oid)
+    text = blob.text(-100)
+    assert_equal 464, text.lines.count
+  end
+
+  def test_blob_text_default_encoding
+    oid = "7771329dfa3002caf8c61a0ceb62a31d09023f37"
+    blob = @repo.lookup(oid)
+    assert_equal Encoding.default_external, blob.text.encoding
+  end
+
+  def test_blob_text_set_encoding
+    oid = "7771329dfa3002caf8c61a0ceb62a31d09023f37"
+    blob = @repo.lookup(oid)
+    assert_equal Encoding::ASCII_8BIT, blob.text(0, Encoding::ASCII_8BIT).encoding
+  end
+end
+
+class BlobWriteTest < Rugged::TestCase
+  def setup
+    @source_repo = FixtureRepo.from_rugged("testrepo.git")
+    @repo = FixtureRepo.clone(@source_repo)
+  end
+
+  def test_fetch_blob_content_with_nulls
+    content = "100644 example_helper.rb\x00\xD3\xD5\xED\x9DA4_"+
+               "\xE3\xC3\nK\xCD<!\xEA-_\x9E\xDC=40000 examples\x00"+
+               "\xAE\xCB\xE9d!|\xB9\xA6\x96\x024],U\xEE\x99\xA2\xEE\xD4\x92"
+
+    content.force_encoding('binary') if content.respond_to?(:force_encoding)
+
+    oid = @repo.write(content, 'tree')
+    blob = @repo.lookup(oid)
+    assert_equal content, blob.read_raw.data
+  end
+
+  def test_write_blob_data
+    assert_equal '1d83f106355e4309a293e42ad2a2c4b8bdbe77ae',
+      Rugged::Blob.from_buffer(@repo, "a new blob content")
+  end
+
+  def test_write_blob_from_workdir
+    assert_equal '1385f264afb75a56a5bec74243be9b367ba4ca08',
+      Rugged::Blob.from_workdir(@repo, "README")
+  end
+
+  def test_write_blob_from_disk
+    file_path = File.join(TEST_DIR, (File.join('fixtures', 'archive.tar.gz')))
+    File.open(file_path, 'rb') do |file|
+      oid = Rugged::Blob.from_disk(@repo, file.path)
+      assert oid
+
+      blob = @repo.lookup(oid)
+      file.rewind
+      assert_equal file.read, blob.content
+    end
+  end
+
+  def test_blob_is_binary
+    binary_file_path = File.join(TEST_DIR, (File.join('fixtures', 'archive.tar.gz')))
+    binary_blob = @repo.lookup(Rugged::Blob.from_disk(@repo, binary_file_path))
+    assert binary_blob.binary?
+
+    text_file_path = File.join(TEST_DIR, (File.join('fixtures', 'text_file.md')))
+    text_blob = @repo.lookup(Rugged::Blob.from_disk(@repo, text_file_path))
+    refute text_blob.binary?
+  end
+end
+
+class BlobLOCTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_rugged("testrepo.git")
+  end
+
+  def write_blob(data)
+    sha = Rugged::Blob.from_buffer(@repo, data)
+    Rugged::Blob.lookup(@repo, sha)
+  end
+
+  def test_loc_end_nl
+    blob = write_blob("hello\nworld\nwhat\n")
+    assert_equal 3, blob.loc
+  end
+
+  def test_loc_no_end_nl
+    blob = write_blob("hello\nworld\nwhat")
+    assert_equal 3, blob.loc
+  end
+
+  def test_loc_carriages
+    blob = write_blob("hello\r\nworld\r\nwhat\r\n")
+    assert_equal 3, blob.loc
+  end
+
+  def test_loc_carriages_no_end_nl
+    blob = write_blob("hello\r\nworld\r\nwhat")
+    assert_equal 3, blob.loc
+  end
+
+  def test_loc_mixed
+    blob = write_blob("hello\nworld\rwhat\r")
+    assert_equal 3, blob.loc
+  end
+
+  def test_loc_mixed_no_end_nl
+    blob = write_blob("hello\nworld\rwhat")
+    assert_equal 3, blob.loc
+  end
+end
+
+class BlobDiffTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("diff")
+  end
+
+  def test_diff_blob
+    a = @repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = @repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    blob  = @repo.lookup(a.tree["readme.txt"][:oid])
+    other = @repo.lookup(b.tree["readme.txt"][:oid])
+
+    patch = blob.diff(other)
+
+    assert_equal :modified, patch.delta.status
+
+    hunks = []
+    patch.each_hunk do |hunk|
+      assert_instance_of Rugged::Diff::Hunk, hunk
+      hunks << hunk
+    end
+    assert_equal 3, hunks.size
+
+    assert hunks[0].header.start_with? "@@ -1,4 +1,4 @@"
+    assert hunks[1].header.start_with? "@@ -7,10 +7,6 @@"
+    assert hunks[2].header.start_with? "@@ -24,12 +20,9 @@"
+
+    lines = []
+    hunks[0].each_line do |line|
+      lines << line
+    end
+    assert_equal 5, lines.size
+
+    assert_equal :deletion, lines[0].line_origin
+    assert_equal "The Git feature that really makes it stand apart from nearly every other SCM\n", lines[0].content
+
+    assert_equal :addition, lines[1].line_origin
+    assert_equal "The Git feature that r3ally mak3s it stand apart from n3arly 3v3ry other SCM\n", lines[1].content
+
+    assert_equal :context, lines[2].line_origin
+    assert_equal "out there is its branching model.\n", lines[2].content
+
+    assert_equal :context, lines[3].line_origin
+    assert_equal "\n", lines[3].content
+
+    assert_equal :context, lines[4].line_origin
+    assert_equal "Git allows and encourages you to have multiple local branches that can be\n", lines[4].content
+  end
+
+  def test_diff_string
+    a = @repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = @repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    blob  = @repo.lookup(a.tree["readme.txt"][:oid])
+    other = @repo.lookup(b.tree["readme.txt"][:oid]).content
+
+    patch = blob.diff(other)
+
+    assert_equal :modified, patch.delta.status
+
+    hunks = []
+    patch.each_hunk do |hunk|
+      assert_instance_of Rugged::Diff::Hunk, hunk
+      hunks << hunk
+    end
+    assert_equal 3, hunks.size
+
+    assert hunks[0].header.start_with? "@@ -1,4 +1,4 @@"
+    assert hunks[1].header.start_with? "@@ -7,10 +7,6 @@"
+    assert hunks[2].header.start_with? "@@ -24,12 +20,9 @@"
+
+    lines = []
+    hunks[0].each_line do |line|
+      lines << line
+    end
+    assert_equal 5, lines.size
+
+    assert_equal :deletion, lines[0].line_origin
+    assert_equal "The Git feature that really makes it stand apart from nearly every other SCM\n", lines[0].content
+
+    assert_equal :addition, lines[1].line_origin
+    assert_equal "The Git feature that r3ally mak3s it stand apart from n3arly 3v3ry other SCM\n", lines[1].content
+
+    assert_equal :context, lines[2].line_origin
+    assert_equal "out there is its branching model.\n", lines[2].content
+
+    assert_equal :context, lines[3].line_origin
+    assert_equal "\n", lines[3].content
+
+    assert_equal :context, lines[4].line_origin
+    assert_equal "Git allows and encourages you to have multiple local branches that can be\n", lines[4].content
+  end
+
+  def test_diff_nil
+    a = @repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+
+    blob  = @repo.lookup(a.tree["readme.txt"][:oid])
+
+    patch = blob.diff(nil)
+
+    assert_equal :deleted, patch.delta.status
+
+    hunks = []
+    patch.each_hunk do |hunk|
+      assert_instance_of Rugged::Diff::Hunk, hunk
+      hunks << hunk
+    end
+    assert_equal 1, hunks.size
+
+    assert hunks[0].header.start_with? "@@ -1,35 +0,0 @@"
+
+    lines = []
+    hunks[0].each_line do |line|
+      lines << line
+    end
+    assert_equal 35, lines.size
+
+    lines.each do |line|
+      assert_equal :deletion, line.line_origin
+    end
+  end
+
+  def test_diff_with_paths
+    a = @repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = @repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    blob  = @repo.lookup(a.tree["readme.txt"][:oid])
+    other = @repo.lookup(b.tree["readme.txt"][:oid])
+
+    patch = blob.diff(other, :old_path => "old_readme.txt", :new_path => "new_readme.txt")
+    assert_equal "old_readme.txt", patch.delta.old_file[:path]
+    assert_equal "new_readme.txt", patch.delta.new_file[:path]
+  end
+end
+
+class BlobCreateFromIOTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_rugged("testrepo.git")
+  end
+
+  def test_write_blob_from_io_with_hintpath
+    file_path= File.join(TEST_DIR, (File.join('fixtures', 'archive.tar.gz')))
+    File.open(file_path, 'rb') do |io|
+      oid = Rugged::Blob.from_io(@repo, io, 'archive.tar.gz2')
+      io.rewind
+      blob = @repo.lookup(oid)
+      assert_equal io.read, blob.content
+    end
+  end
+
+  def test_write_blob_from_io_without_hintpath
+    file_path= File.join(TEST_DIR, (File.join('fixtures', 'archive.tar.gz')))
+    File.open(file_path, 'rb') do |io|
+      oid = Rugged::Blob.from_io(@repo, io)
+      io.rewind
+      blob = @repo.lookup(oid)
+      assert_equal io.read, blob.content
+    end
+  end
+
+  class BrokenIO
+    def read(length)
+      raise IOError
+    end
+  end
+
+  def test_write_blob_from_io_broken_io_raises_error
+    assert_raises IOError do
+      Rugged::Blob.from_io(@repo, BrokenIO.new)
+    end
+  end
+
+  class OverflowIO
+    def initialize()
+      @called = false
+    end
+
+    def read(size)
+      res = @called ? nil : 'a' * size * 4
+      @called = true
+      res
+    end
+  end
+
+  def test_write_blob_from_io_overflow_io
+    assert Rugged::Blob.from_io(@repo, OverflowIO.new)
+  end
+
+  class BadIO
+    def read(length)
+      :invalid_data
+    end
+  end
+
+  def test_write_blob_from_io_bad_io
+    assert_raises TypeError do
+      Rugged::Blob.from_io(@repo, BadIO.new)
+    end
+  end
+end
+
+class BlobHashSignatureTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_rugged("testrepo.git")
+  end
+
+  LOREM = <<-LOREM
+Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+Sed quis volutpat nunc. Vivamus consectetur pretium lacus, hendrerit dapibus justo rutrum at.
+Fusce imperdiet volutpat ex, vel volutpat velit posuere ac.
+Aenean ante neque, eleifend eu ligula sed, porttitor sagittis eros.
+Vestibulum tincidunt pulvinar ante sit amet tristique.
+Phasellus eu lacus in nunc pulvinar fringilla eu at felis.
+Vestibulum lobortis ipsum eleifend tellus eleifend ultricies. Sed maximus ornare nunc vel consequat.
+Praesent pharetra urna orci, nec pellentesque nulla viverra condimentum.
+Donec ipsum sapien, eleifend gravida lectus vel, congue pulvinar enim.
+Vestibulum pretium gravida velit sit amet consequat.
+Sed sit amet est eu sapien lacinia porttitor eu eu lacus.
+Fusce tempus est a nisi dignissim pulvinar.
+Quisque maximus eleifend massa, non elementum massa convallis a.
+LOREM
+
+  def test_signature_from_blob
+    blob = @repo.lookup("7771329dfa3002caf8c61a0ceb62a31d09023f37")
+
+    sig1 = Rugged::Blob::HashSignature.new(blob)
+    assert blob.similarity(sig1) == 100
+    assert blob.similarity(LOREM) < 20
+
+    sig1 = Rugged::Blob::HashSignature.new(LOREM)
+    sig2 = Rugged::Blob::HashSignature.new(LOREM.gsub('ipsum', 'epsen'))
+    assert Rugged::Blob::HashSignature.compare(sig1, sig2) > 75
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/branch_test.rb b/app/server/vendor/rugged-0.23.3/test/branch_test.rb
new file mode 100755
index 0000000..a576148
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/branch_test.rb
@@ -0,0 +1,321 @@
+# encoding: UTF-8
+require "test_helper"
+
+class BranchTest < Rugged::TestCase
+  def setup
+    @source_repo = FixtureRepo.from_rugged("testrepo.git")
+    @repo = FixtureRepo.clone(@source_repo)
+  end
+
+  def test_list_all_names
+    assert_equal [
+      "master",
+      "origin/HEAD",
+      "origin/master",
+      "origin/packed",
+    ], @repo.branches.each_name.sort
+  end
+
+  def test_lookup_with_ambiguous_names
+    @repo.branches.create("origin/master", "41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9")
+
+    assert_equal "41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9", @repo.branches["origin/master"].target_id
+
+    assert_equal "41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9", @repo.branches["heads/origin/master"].target_id
+    assert_equal "36060c58702ed4c2a40832c51758d5344201d89a", @repo.branches["remotes/origin/master"].target_id
+
+    assert_equal "41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9", @repo.branches["refs/heads/origin/master"].target_id
+    assert_equal "36060c58702ed4c2a40832c51758d5344201d89a", @repo.branches["refs/remotes/origin/master"].target_id
+  end
+
+  def test_list_only_local_branches
+    assert_equal ["master"], @repo.branches.each_name(:local).sort
+  end
+
+  def test_list_only_remote_branches
+    assert_equal [
+      "origin/HEAD",
+      "origin/master",
+      "origin/packed",
+    ], @repo.branches.each_name(:remote).sort
+  end
+
+  def test_get_latest_commit_in_branch
+    target = @repo.branches["master"].target
+
+    assert_kind_of Rugged::Commit, target
+    assert_equal "36060c58702ed4c2a40832c51758d5344201d89a", target.oid
+  end
+
+  def test_lookup_local_branch
+    branch = @repo.branches["master"]
+    refute_nil branch
+
+    assert_equal "master", branch.name
+    assert_equal "refs/heads/master", branch.canonical_name
+    assert_equal "36060c58702ed4c2a40832c51758d5344201d89a", branch.target.oid
+  end
+
+  def test_lookup_remote_branches
+    branch = @repo.branches["origin/packed"]
+    refute_nil branch
+
+    assert_equal "origin/packed", branch.name
+    assert_equal "refs/remotes/origin/packed", branch.canonical_name
+    assert_equal "41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9", branch.target.oid
+  end
+
+  def test_lookup_unicode_branch_name
+    new_branch = @repo.create_branch("Ångström", "5b5b025afb0b4c913b4c338a42934a3863bf3644")
+    refute_nil new_branch
+
+    retrieved_branch = @repo.branches["Ångström"]
+    refute_nil retrieved_branch
+
+    assert_equal new_branch, retrieved_branch
+  end
+
+  def test_delete_branch
+    branch = @repo.create_branch("test_branch")
+    @repo.branches.delete(branch)
+    assert_nil @repo.branches["test_branch"]
+  end
+
+  def test_is_head
+    assert @repo.branches["master"].head?
+    refute @repo.branches["origin/master"].head?
+    refute @repo.branches["origin/packed"].head?
+    refute @repo.create_branch("test_branch").head?
+  end
+
+  def test_rename_branch
+    branch = @repo.create_branch("test_branch")
+
+    @repo.branches.move(branch, 'other_branch')
+
+    assert_nil @repo.branches["test_branch"]
+    refute_nil @repo.branches["other_branch"]
+  end
+
+  def test_create_new_branch
+    new_branch = @repo.create_branch("test_branch", "5b5b025afb0b4c913b4c338a42934a3863bf3644")
+
+    refute_nil new_branch
+    assert_equal "test_branch", new_branch.name
+    assert_equal "refs/heads/test_branch", new_branch.canonical_name
+
+    refute_nil new_branch.target
+    assert_equal "5b5b025afb0b4c913b4c338a42934a3863bf3644", new_branch.target.oid
+
+    refute_nil @repo.branches.find { |p| p.name == "test_branch" }
+  end
+
+  def test_create_unicode_branch_nfc
+    branch_name = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D"
+
+    new_branch = @repo.create_branch(branch_name, "5b5b025afb0b4c913b4c338a42934a3863bf3644")
+    refute_nil new_branch
+
+    assert_equal branch_name, new_branch.name
+    assert_equal "refs/heads/#{branch_name}", new_branch.canonical_name
+
+    refute_nil @repo.branches[branch_name]
+  end
+
+  def test_create_unicode_branch_nfd
+    branch_name = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D"
+
+    new_branch = @repo.create_branch(branch_name, "5b5b025afb0b4c913b4c338a42934a3863bf3644")
+    refute_nil new_branch
+
+    if @repo.config["core.precomposeunicode"] == "true"
+      expected_name = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D"
+    else
+      expected_name = branch_name
+    end
+
+    assert_equal expected_name, new_branch.name
+    assert_equal "refs/heads/#{expected_name}", new_branch.canonical_name
+
+    refute_nil @repo.branches[branch_name]
+    refute_nil @repo.branches[expected_name]
+  end
+
+  def test_create_branch_short_sha
+    new_branch = @repo.create_branch("test_branch", "5b5b025")
+
+    refute_nil new_branch
+    assert_equal "test_branch", new_branch.name
+    assert_equal "refs/heads/test_branch", new_branch.canonical_name
+
+    refute_nil new_branch.target
+    assert_equal "5b5b025afb0b4c913b4c338a42934a3863bf3644", new_branch.target.oid
+  end
+
+  def test_create_branch_from_tag
+    new_branch = @repo.create_branch("test_branch", "refs/tags/v0.9")
+
+    refute_nil new_branch
+    assert_equal "test_branch", new_branch.name
+    assert_equal "refs/heads/test_branch", new_branch.canonical_name
+
+    refute_nil new_branch.target
+    assert_equal "5b5b025afb0b4c913b4c338a42934a3863bf3644", new_branch.target.oid
+  end
+
+  def test_create_branch_from_head
+    new_branch = @repo.create_branch("test_branch")
+
+    refute_nil new_branch
+    assert_equal "test_branch", new_branch.name
+    assert_equal "refs/heads/test_branch", new_branch.canonical_name
+
+    refute_nil new_branch.target
+    assert_equal "36060c58702ed4c2a40832c51758d5344201d89a", new_branch.target.oid
+  end
+
+  def test_create_branch_explicit_head
+    new_branch = @repo.create_branch("test_branch", "HEAD")
+
+    refute_nil new_branch
+    assert_equal "test_branch", new_branch.name
+    assert_equal "refs/heads/test_branch", new_branch.canonical_name
+
+    refute_nil new_branch.target
+    assert_equal "36060c58702ed4c2a40832c51758d5344201d89a", new_branch.target.oid
+  end
+
+  def test_create_branch_from_commit
+    new_branch = @repo.create_branch("test_branch",
+      Rugged::Commit.lookup(@repo, "5b5b025afb0b4c913b4c338a42934a3863bf3644"))
+
+    refute_nil new_branch
+    assert_equal "test_branch", new_branch.name
+    assert_equal "refs/heads/test_branch", new_branch.canonical_name
+
+    refute_nil new_branch.target
+    assert_equal "5b5b025afb0b4c913b4c338a42934a3863bf3644", new_branch.target.oid
+  end
+
+  def test_create_branch_from_tree_fails
+    assert_raises ArgumentError, Rugged::InvalidError do
+      @repo.create_branch("test_branch",
+        Rugged::Tree.lookup(@repo, "f60079018b664e4e79329a7ef9559c8d9e0378d1"))
+    end
+  end
+
+  def test_create_branch_from_blob_fails
+    assert_raises ArgumentError, Rugged::InvalidError do
+      @repo.create_branch("test_branch",
+        Rugged::Blob.lookup(@repo, "1385f264afb75a56a5bec74243be9b367ba4ca08"))
+    end
+  end
+
+  def test_create_branch_from_unknown_ref_fails
+    assert_raises Rugged::ReferenceError do
+      @repo.create_branch("test_branch", "i_do_not_exist")
+    end
+  end
+
+  def test_create_branch_from_unknown_commit_fails
+    assert_raises Rugged::ReferenceError do
+      @repo.create_branch("test_branch", "dd15de908706711b51b7acb24faab726d2b3cb16")
+    end
+  end
+
+  def test_create_branch_from_non_canonical_fails
+    assert_raises Rugged::ReferenceError do
+      @repo.create_branch("test_branch", "packed")
+    end
+  end
+
+  def test_branch_remote_remote_branch
+    assert_equal 'origin',
+      @repo.branches["origin/master"].remote.name
+  end
+
+  def test_branch_remote_local_tracking_remote_branch
+    assert_equal 'origin',
+      @repo.branches["master"].remote.name
+  end
+
+  def test_branch_remote_local_non_tracking_branch
+    branch = @repo.create_branch('test_branch',
+                                 '5b5b025afb0b4c913b4c338a42934a3863bf3644')
+    assert_nil branch.remote
+  end
+
+  def test_branch_upstream
+    upstream_branch = @repo.branches["master"].upstream
+    assert_equal 'origin/master', upstream_branch.name
+  end
+
+  def test_branch_upstream_remote_branch
+    assert_nil @repo.branches["origin/master"].upstream
+  end
+
+  def test_branch_upstream_no_tracking_branch
+    branch = @repo.create_branch('test_branch',
+      '5b5b025afb0b4c913b4c338a42934a3863bf3644')
+
+    assert_nil branch.upstream
+  end
+
+  def test_branch_set_upstream_invalid
+    branch = @repo.create_branch('test_branch',
+      '5b5b025afb0b4c913b4c338a42934a3863bf3644')
+
+    assert_raises TypeError do
+      branch.upstream = :invalid_branch
+    end
+  end
+
+  def test_branch_set_upstream_with_reference
+    branch = @repo.create_branch('test_branch',
+      '5b5b025afb0b4c913b4c338a42934a3863bf3644')
+
+    branch.upstream = @repo.references["refs/heads/master"]
+    assert_equal 'master',  branch.upstream.name
+  end
+
+  def test_branch_set_upstream_with_tag_reference
+    branch = @repo.create_branch('test_branch',
+      '5b5b025afb0b4c913b4c338a42934a3863bf3644')
+
+    assert_raises Rugged::InvalidError do
+      branch.upstream = @repo.references["refs/tags/v1.0"]
+    end
+  end
+
+  def test_branch_set_upstream_local
+    branch = @repo.create_branch('test_branch',
+      '5b5b025afb0b4c913b4c338a42934a3863bf3644')
+
+    branch.upstream =  @repo.branches["master"]
+    assert_equal 'master',  branch.upstream.name
+  end
+
+  def test_branch_set_upstream_remote
+    branch = @repo.create_branch('test_branch',
+      '5b5b025afb0b4c913b4c338a42934a3863bf3644')
+
+    branch.upstream =  @repo.branches["origin/master"]
+    assert_equal 'origin/master',  branch.upstream.name
+  end
+
+  def test_branch_unset_upstream
+    branch = @repo.branches["master"]
+    assert branch.upstream
+    branch.upstream = nil
+    assert_nil branch.upstream
+  end
+
+  def test_branch_set_upstream_on_remote_branch
+    branch = @repo.branches["origin/master"]
+
+    assert_raises Rugged::InvalidError do
+      branch.upstream = @repo.create_branch('test_branch',
+                                            '5b5b025afb0b4c913b4c338a42934a3863bf3644')
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/cherrypick_test.rb b/app/server/vendor/rugged-0.23.3/test/cherrypick_test.rb
new file mode 100755
index 0000000..3bc0b59
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/cherrypick_test.rb
@@ -0,0 +1,78 @@
+require "test_helper"
+
+class WorkdirCherrypickTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("cherrypick")
+  end
+
+  def test_automerge
+    signature = {
+      name: "Picker",
+      email: "picker at example.org"
+    }
+
+    @repo.reset("d3d77487660ee3c0194ee01dc5eaf478782b1c7e", :hard)
+
+    @repo.cherrypick("cfc4f0999a8367568e049af4f72e452d40828a15")
+    Rugged::Commit.create(@repo, {
+      tree: @repo.index.write_tree,
+      update_ref: "HEAD",
+      parents: [ @repo.last_commit ],
+      author: signature,
+      committer: signature,
+      message: "Cherry picked!"
+    })
+
+    assert_equal "38c05a857e831a7e759d83778bfc85d003e21c45", @repo.index["file1.txt"][:oid]
+    assert_equal "a661b5dec1004e2c62654ded3762370c27cf266b", @repo.index["file2.txt"][:oid]
+    assert_equal "df6b290e0bd6a89b01d69f66687e8abf385283ca", @repo.index["file3.txt"][:oid]
+
+    @repo.cherrypick("964ea3da044d9083181a88ba6701de9e35778bf4")
+    Rugged::Commit.create(@repo, {
+      tree: @repo.index.write_tree,
+      update_ref: "HEAD",
+      parents: [ @repo.last_commit ],
+      author: signature,
+      committer: signature,
+      message: "Cherry picked!"
+    })
+
+    assert_equal "38c05a857e831a7e759d83778bfc85d003e21c45", @repo.index["file1.txt"][:oid]
+    assert_equal "bd8fc3c59fb52d3c8b5907ace7defa5803f82419", @repo.index["file2.txt"][:oid]
+    assert_equal "df6b290e0bd6a89b01d69f66687e8abf385283ca", @repo.index["file3.txt"][:oid]
+
+    @repo.cherrypick("a43a050c588d4e92f11a6b139680923e9728477d")
+    Rugged::Commit.create(@repo, {
+      tree: @repo.index.write_tree,
+      update_ref: "HEAD",
+      parents: [ @repo.last_commit ],
+      author: signature,
+      committer: signature,
+      message: "Cherry picked!"
+    })
+
+    assert_equal "f06427bee380364bc7e0cb26a9245158e4726ce0", @repo.index["file1.txt"][:oid]
+    assert_equal "bd8fc3c59fb52d3c8b5907ace7defa5803f82419", @repo.index["file2.txt"][:oid]
+    assert_equal "df6b290e0bd6a89b01d69f66687e8abf385283ca", @repo.index["file3.txt"][:oid]
+  end
+
+  def test_merge_first_parent
+    @repo.reset("cfc4f0999a8367568e049af4f72e452d40828a15", :hard)
+
+    @repo.cherrypick("abe4603bc7cd5b8167a267e0e2418fd2348f8cff", mainline: 1)
+
+    assert_equal "f90f9dcbdac2cce5cc166346160e19cb693ef4e8", @repo.index["file1.txt"][:oid]
+    assert_equal "563f6473a3858f99b80e5f93c660512ed38e1e6f", @repo.index["file2.txt"][:oid]
+    assert_equal "e233b9ed408a95e9d4b65fec7fc34943a556deb2", @repo.index["file3.txt"][:oid]
+  end
+
+  def test_merge_second_parent
+    @repo.reset("cfc4f0999a8367568e049af4f72e452d40828a15", :hard)
+
+    @repo.cherrypick("abe4603bc7cd5b8167a267e0e2418fd2348f8cff", mainline: 2)
+
+    assert_equal "487434cace79238a7091e2220611d4f20a765690", @repo.index["file1.txt"][:oid]
+    assert_equal "e5183bfd18e3a0a691fadde2f0d5610b73282d31", @repo.index["file2.txt"][:oid]
+    assert_equal "409a1bec58bf35348e8b62b72bb9c1f45cf5a587", @repo.index["file3.txt"][:oid]
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/commit_test.rb b/app/server/vendor/rugged-0.23.3/test/commit_test.rb
new file mode 100755
index 0000000..4121c7a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/commit_test.rb
@@ -0,0 +1,481 @@
+require "test_helper"
+
+class TestCommit < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_rugged("testrepo.git")
+    @repo.config['core.abbrev'] = 7
+  end
+
+  def test_lookup_raises_error_if_object_type_does_not_match
+    assert_raises Rugged::InvalidError do
+      # blob
+      Rugged::Commit.lookup(@repo, "fa49b077972391ad58037050f2a75f74e3671e92")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # tag
+      Rugged::Commit.lookup(@repo, "0c37a5391bbff43c37f0d0371823a5509eed5b1d")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # tree
+      Rugged::Commit.lookup(@repo, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")
+    end
+
+    subclass = Class.new(Rugged::Commit)
+
+    assert_raises Rugged::InvalidError do
+      # blob
+      subclass.lookup(@repo, "fa49b077972391ad58037050f2a75f74e3671e92")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # tag
+      subclass.lookup(@repo, "0c37a5391bbff43c37f0d0371823a5509eed5b1d")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # tree
+      subclass.lookup(@repo, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")
+    end
+  end
+
+  def test_read_commit_data
+    oid = "8496071c1b46c854b31185ea97743be6a8774479"
+    obj = @repo.lookup(oid)
+
+    assert_equal obj.oid, oid
+    assert_equal obj.type, :commit
+    assert_equal obj.message, "testing\n"
+    assert_equal obj.time.to_i, 1273360386
+    assert_equal obj.epoch_time, 1273360386
+
+    c = obj.committer
+    assert_equal c[:name], "Scott Chacon"
+    assert_equal c[:time].to_i, 1273360386
+    assert_equal c[:email], "schacon at gmail.com"
+
+    c = obj.author
+    assert_equal c[:name], "Scott Chacon"
+    assert_equal c[:time].to_i, 1273360386
+    assert_equal c[:email], "schacon at gmail.com"
+
+    assert_equal obj.tree.oid, "181037049a54a1eb5fab404658a3a250b44335d7"
+    assert_equal [], obj.parents
+  end
+
+  def test_commit_with_multiple_parents
+    oid = "a4a7dce85cf63874e984719f4fdd239f5145052f"
+    obj = @repo.lookup(oid)
+    parents = obj.parents.map {|c| c.oid }
+    assert parents.include?("9fd738e8f7967c078dceed8190330fc8648ee56a")
+    assert parents.include?("c47800c7266a2be04c571c04d5a6614691ea99bd")
+  end
+
+  def test_get_parent_oids
+    oid = "a4a7dce85cf63874e984719f4fdd239f5145052f"
+    obj = @repo.lookup(oid)
+    parents = obj.parent_oids
+    assert parents.include?("9fd738e8f7967c078dceed8190330fc8648ee56a")
+    assert parents.include?("c47800c7266a2be04c571c04d5a6614691ea99bd")
+  end
+
+  def test_get_tree_oid
+    oid = "8496071c1b46c854b31185ea97743be6a8774479"
+    obj = @repo.lookup(oid)
+
+    assert_equal obj.tree_oid, "181037049a54a1eb5fab404658a3a250b44335d7"
+  end
+
+  def test_amend_commit
+    oid = "8496071c1b46c854b31185ea97743be6a8774479"
+    obj = @repo.lookup(oid)
+
+    entry = {:type => :blob,
+             :name => "README.txt",
+             :oid  => "1385f264afb75a56a5bec74243be9b367ba4ca08",
+             :filemode => 33188}
+
+    builder = Rugged::Tree::Builder.new(@repo)
+    builder << entry
+    tree_oid = builder.write
+
+    person = {:name => 'Scott', :email => 'schacon at gmail.com', :time => Time.now }
+
+    commit_params = {
+      :message => "This is the amended commit message\n\nThis commit is created from Rugged",
+      :committer => person,
+      :author => person,
+      :tree => tree_oid
+    }
+
+    new_commit_oid = obj.amend(commit_params)
+
+    amended_commit = @repo.lookup(new_commit_oid)
+    assert_equal commit_params[:message], amended_commit.message
+    assert_equal tree_oid, amended_commit.tree.oid
+  end
+
+  def test_amend_commit_blank_tree
+    oid = "8496071c1b46c854b31185ea97743be6a8774479"
+    obj = @repo.lookup(oid)
+
+    person = {:name => 'Scott', :email => 'schacon at gmail.com', :time => Time.now }
+
+    commit_params = {
+      :message => "This is the amended commit message\n\nThis commit is created from Rugged",
+      :committer => person,
+      :author => person
+    }
+
+    new_commit_oid = obj.amend(commit_params)
+
+    amended_commit = @repo.lookup(new_commit_oid)
+    assert_equal commit_params[:message], amended_commit.message
+  end
+
+  def test_amend_commit_blank_author_and_committer
+    oid = "8496071c1b46c854b31185ea97743be6a8774479"
+    obj = @repo.lookup(oid)
+
+    commit_params = {
+      :message => "This is the amended commit message\n\nThis commit is created from Rugged"
+    }
+
+    new_commit_oid = obj.amend(commit_params)
+
+    amended_commit = @repo.lookup(new_commit_oid)
+    assert_equal commit_params[:message], amended_commit.message
+  end
+
+  def test_amend_commit_blank_message
+    oid = "8496071c1b46c854b31185ea97743be6a8774479"
+    obj = @repo.lookup(oid)
+
+    entry = {:type => :blob,
+             :name => "README.txt",
+             :oid  => "1385f264afb75a56a5bec74243be9b367ba4ca08",
+             :filemode => 33188}
+
+    builder = Rugged::Tree::Builder.new(@repo)
+    builder << entry
+    tree_oid = builder.write
+
+    person = {:name => 'Scott', :email => 'schacon at gmail.com', :time => Time.now }
+
+    commit_params = {
+      :committer => person,
+      :author => person,
+      :tree => tree_oid
+    }
+
+    new_commit_oid = obj.amend(commit_params)
+
+    amended_commit = @repo.lookup(new_commit_oid)
+    assert_equal tree_oid, amended_commit.tree.oid
+  end
+end
+
+class CommitWriteTest < Rugged::TestCase
+  def setup
+    @source_repo = FixtureRepo.from_rugged("testrepo.git")
+    @repo = FixtureRepo.clone(@source_repo)
+    @repo.config['core.abbrev'] = 7
+  end
+
+  def test_write_commit_with_time
+    person = {:name => 'Scott', :email => 'schacon at gmail.com', :time => Time.now }
+
+    Rugged::Commit.create(@repo,
+      :message => "This is the commit message\n\nThis commit is created from Rugged",
+      :committer => person,
+      :author => person,
+      :parents => [@repo.head.target],
+      :tree => "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")
+  end
+
+  def test_write_commit_with_time_offset
+    person = {:name => 'Jake', :email => 'jake at github.com', :time => Time.now, :time_offset => 3600}
+
+    oid = Rugged::Commit.create(@repo,
+      :message => "This is the commit message\n\nThis commit is created from Rugged",
+      :committer => person,
+      :author => person,
+      :parents => [@repo.head.target],
+      :tree => "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")
+
+    commit = @repo.lookup(oid)
+    assert_equal 3600, commit.committer[:time].utc_offset
+  end
+
+  def test_write_commit_without_time
+    person = {:name => 'Jake', :email => 'jake at github.com'}
+
+    oid = Rugged::Commit.create(@repo,
+      :message => "This is the commit message\n\nThis commit is created from Rugged",
+      :committer => person,
+      :author => person,
+      :parents => [@repo.head.target],
+      :tree => "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")
+
+    commit = @repo.lookup(oid)
+    assert_kind_of Time, commit.committer[:time]
+  end
+
+  def test_write_commit_without_signature
+    name = 'Rugged User'
+    email = 'rugged at example.com'
+    @repo.config['user.name'] = name
+    @repo.config['user.email'] = email
+
+    oid = Rugged::Commit.create(@repo,
+      :message => "This is the commit message\n\nThis commit is created from Rugged",
+      :parents => [@repo.head.target],
+      :tree => "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")
+
+    commit = @repo.lookup(oid)
+    assert_equal name, commit.committer[:name]
+    assert_equal email, commit.committer[:email]
+    assert_equal name, commit.author[:name]
+    assert_equal email, commit.author[:email]
+  end
+
+  def test_write_invalid_parents
+    person = {:name => 'Scott', :email => 'schacon at gmail.com', :time => Time.now }
+    assert_raises TypeError do
+      Rugged::Commit.create(@repo,
+        :message => "This is the commit message\n\nThis commit is created from Rugged",
+        :parents => [:invalid_parent],
+        :committer => person,
+        :author => person,
+        :tree => "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")
+    end
+  end
+
+  def test_write_empty_email_fails
+    person = {:name => 'Jake', :email => '', :time => Time.now}
+    assert_raises Rugged::InvalidError do
+      Rugged::Commit.create(@repo,
+      :message => "This is the commit message\n\nThis commit is created from Rugged",
+      :committer => person,
+      :author => person,
+      :parents => [@repo.head.target],
+      :tree => "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")
+    end
+  end
+end
+
+class CommitToMboxTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2 "diff_format_email"
+    @repo.config['core.abbrev'] = 7
+  end
+
+  def test_format_to_mbox
+    assert_equal <<-EOS, @repo.lookup("9264b96c6d104d0e07ae33d3007b6a48246c6f92").to_mbox
+From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001
+From: Jacques Germishuys <jacquesg at striata.com>
+Date: Wed, 9 Apr 2014 20:57:01 +0200
+Subject: [PATCH] Modify some content
+
+---
+ file1.txt | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/file1.txt b/file1.txt
+index 94aaae8..af8f41d 100644
+--- a/file1.txt
++++ b/file1.txt
+@@ -1,15 +1,17 @@
+ file1.txt
+ file1.txt
++_file1.txt_
+ file1.txt
+ file1.txt
+ file1.txt
+ file1.txt
++
++
+ file1.txt
+ file1.txt
+ file1.txt
+ file1.txt
+ file1.txt
+-file1.txt
+-file1.txt
+-file1.txt
++_file1.txt_
++_file1.txt_
+ file1.txt
+--
+libgit2 #{Rugged.libgit2_version.join('.')}
+
+EOS
+  end
+
+  def test_format_to_mbox_multiple
+    commit = @repo.lookup("10808fe9c9be5a190c0ba68d1a002233fb363508")
+    assert_equal <<-EOS, commit.to_mbox(patch_no: 1, total_patches: 2)
+From 10808fe9c9be5a190c0ba68d1a002233fb363508 Mon Sep 17 00:00:00 2001
+From: Jacques Germishuys <jacquesg at striata.com>
+Date: Thu, 10 Apr 2014 19:37:05 +0200
+Subject: [PATCH 1/2] Added file2.txt file3.txt
+
+---
+ file2.txt | 5 +++++
+ file3.txt | 5 +++++
+ 2 files changed, 10 insertions(+), 0 deletions(-)
+ create mode 100644 file2.txt
+ create mode 100644 file3.txt
+
+diff --git a/file2.txt b/file2.txt
+new file mode 100644
+index 0000000..e909123
+--- /dev/null
++++ b/file2.txt
+@@ -0,0 +1,5 @@
++file2
++file2
++file2
++file2
++file2
+diff --git a/file3.txt b/file3.txt
+new file mode 100644
+index 0000000..9435022
+--- /dev/null
++++ b/file3.txt
+@@ -0,0 +1,5 @@
++file3
++file3
++file3
++file3
++file3
+--
+libgit2 #{Rugged.libgit2_version.join('.')}
+
+EOS
+
+    commit = @repo.lookup("873806f6f27e631eb0b23e4b56bea2bfac14a373")
+    assert_equal <<-EOS, commit.to_mbox(patch_no: 2, total_patches: 2)
+From 873806f6f27e631eb0b23e4b56bea2bfac14a373 Mon Sep 17 00:00:00 2001
+From: Jacques Germishuys <jacquesg at striata.com>
+Date: Thu, 10 Apr 2014 19:37:36 +0200
+Subject: [PATCH 2/2] Modified file2.txt, file3.txt
+
+---
+ file2.txt | 2 +-
+ file3.txt | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/file2.txt b/file2.txt
+index e909123..7aff11d 100644
+--- a/file2.txt
++++ b/file2.txt
+@@ -1,5 +1,5 @@
+ file2
+ file2
+ file2
+-file2
++file2!
+ file2
+diff --git a/file3.txt b/file3.txt
+index 9435022..9a2d780 100644
+--- a/file3.txt
++++ b/file3.txt
+@@ -1,5 +1,5 @@
+ file3
+-file3
++file3!
+ file3
+ file3
+ file3
+--
+libgit2 #{Rugged.libgit2_version.join('.')}
+
+EOS
+
+  end
+
+  def test_format_to_mbox_exclude_marker
+    commit = @repo.lookup("9264b96c6d104d0e07ae33d3007b6a48246c6f92")
+    assert_equal <<-EOS, commit.to_mbox(exclude_subject_patch_marker: true)
+From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001
+From: Jacques Germishuys <jacquesg at striata.com>
+Date: Wed, 9 Apr 2014 20:57:01 +0200
+Subject: Modify some content
+
+---
+ file1.txt | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/file1.txt b/file1.txt
+index 94aaae8..af8f41d 100644
+--- a/file1.txt
++++ b/file1.txt
+@@ -1,15 +1,17 @@
+ file1.txt
+ file1.txt
++_file1.txt_
+ file1.txt
+ file1.txt
+ file1.txt
+ file1.txt
++
++
+ file1.txt
+ file1.txt
+ file1.txt
+ file1.txt
+ file1.txt
+-file1.txt
+-file1.txt
+-file1.txt
++_file1.txt_
++_file1.txt_
+ file1.txt
+--
+libgit2 #{Rugged.libgit2_version.join('.')}
+
+EOS
+  end
+
+  def test_format_to_mbox_diff_options
+    commit = @repo.lookup("9264b96c6d104d0e07ae33d3007b6a48246c6f92")
+    assert_equal <<-EOS, commit.to_mbox(context_lines: 1, interhunk_lines: 1)
+From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001
+From: Jacques Germishuys <jacquesg at striata.com>
+Date: Wed, 9 Apr 2014 20:57:01 +0200
+Subject: [PATCH] Modify some content
+
+---
+ file1.txt | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/file1.txt b/file1.txt
+index 94aaae8..af8f41d 100644
+--- a/file1.txt
++++ b/file1.txt
+@@ -2,2 +2,3 @@ file1.txt
+ file1.txt
++_file1.txt_
+ file1.txt
+@@ -6,2 +7,4 @@ file1.txt
+ file1.txt
++
++
+ file1.txt
+@@ -11,5 +14,4 @@ file1.txt
+ file1.txt
+-file1.txt
+-file1.txt
+-file1.txt
++_file1.txt_
++_file1.txt_
+ file1.txt
+--
+libgit2 #{Rugged.libgit2_version.join('.')}
+
+EOS
+  end
+
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/config_test.rb b/app/server/vendor/rugged-0.23.3/test/config_test.rb
new file mode 100755
index 0000000..2cccec4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/config_test.rb
@@ -0,0 +1,51 @@
+require "test_helper"
+
+class ConfigTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_rugged("testrepo.git")
+  end
+
+  def test_read_config_file
+    config = @repo.config
+    assert_equal 'false', config['core.bare']
+    assert_nil config['not.exist']
+  end
+
+  def test_read_config_from_path
+    config = Rugged::Config.new(File.join(@repo.path, 'config'))
+    assert_equal 'false', config['core.bare']
+  end
+
+  def test_read_global_config_file
+    config = Rugged::Config.global
+    assert config['user.name'] != nil
+    assert_nil config['core.bare']
+  end
+end
+
+class ConfigWriteTest < Rugged::TestCase
+  def setup
+    @source_repo = FixtureRepo.from_rugged("testrepo.git")
+    @repo = FixtureRepo.clone(@source_repo)
+    @path = @repo.workdir
+  end
+
+  def test_write_config_values
+    config = @repo.config
+    config['custom.value'] = 'my value'
+
+    config2 = @repo.config
+    assert_equal 'my value', config2['custom.value']
+
+    content = File.read(File.join(@repo.path, 'config'))
+    assert_match(/value = my value/, content)
+  end
+
+  def test_delete_config_values
+    config = @repo.config
+    config.delete('core.bare')
+
+    config2 = @repo.config
+    assert_nil config2.get('core.bare')
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/coverage/cover.rb b/app/server/vendor/rugged-0.23.3/test/coverage/cover.rb
new file mode 100755
index 0000000..b81ef3c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/coverage/cover.rb
@@ -0,0 +1,133 @@
+require 'open-uri'
+require 'json'
+require 'set'
+
+CWD = File.expand_path(File.dirname(__FILE__))
+
+IGNORED_METHODS = %w(
+  git_blob_free
+  git_blob_lookup
+  git_blob_lookup_prefix
+  git_blob_id
+  git_blob_owner
+  git_commit_create_v
+  git_commit_free
+  git_commit_id
+  git_commit_lookup_prefix
+  git_commit_parent_oid
+  git_commit_time_offset
+  git_commit_tree_oid
+  git_config_file__ondisk
+  git_config_find_global
+  git_config_find_system
+  git_diff_list_free
+  git_diff_patch_free
+  git_index_entry_stage
+  git_indexer_stream_free
+  git_note_free
+  git_object__size
+  git_odb_add_alternate
+  git_odb_add_backend
+  git_odb_backend_loose
+  git_odb_backend_pack
+  git_odb_new
+  git_odb_open_rstream
+  git_odb_read_header
+  git_odb_read_prefix
+  git_odb_write
+  git_oid_allocfmt
+  git_oid_cpy
+  git_oid_ncmp
+  git_oid_pathfmt
+  git_oid_streq
+  git_oid_tostr
+  git_packbuilder_free
+  git_reference_owner
+  git_reference_listall
+  git_reflog_delete
+  git_reflog_rename
+  git_repository_odb
+  git_repository_set_odb
+  git_signature_dup
+  git_signature_now
+  git_tag_free
+  git_tag_id
+  git_tag_lookup
+  git_tag_lookup_prefix
+  git_tag_target_oid
+  git_tree_free
+  git_tree_id
+  git_tree_lookup
+  git_tree_lookup_prefix
+  git_strarray_copy
+  git_trace_set
+  imaxdiv
+)
+
+method_list = nil
+
+# The list of methods in libgit2 that we want coverage for
+open('http://libgit2.github.com/libgit2/HEAD.json') do |f|
+  json_data = JSON.parse(f.read())
+  method_list = json_data['groups']
+end
+
+# Don't look for the methods in IGNORED_METHODS.
+look_for = []
+method_list.each do |_, methods|
+  methods.reject! { |m| IGNORED_METHODS.include? m }
+  look_for += methods
+end
+
+# Look at the .c and .h files in the rugged directory
+source_files = Dir.glob("#{CWD}/../../ext/rugged/*.{c,h}")
+
+# If any of the files contain the string representation
+# of a libgit2 method, add it to our set of found methods
+found = Set.new
+source_files.each do |file|
+  File.open(file) do |f|
+    contents = f.read()
+    look_for.each do |method|
+      if contents.index(method) != nil
+        found.add(method)
+      end
+    end
+  end
+end
+
+# Keep a count of missing and total
+total_missing = 0
+total_methods = 0
+
+# Print the results for each group
+method_list.each do |group, group_methods|
+
+  # Skip the group if all methods are ignored
+  next if group_methods.size == 0
+
+  # What are for we missing for this group?
+  group_miss = group_methods.reject {|m| found.include? m}
+  print "\n#{group} [#{group_methods.size - group_miss.size}/#{group_methods.size}]: "
+
+  # Add the numbers to our grand total running count
+  total_missing += group_miss.size
+  total_methods += group_methods.size
+
+  # Unit test style printout. A dot is a match, an 'M' is a miss.
+  group_methods.each do |m|
+    print found.include?(m) ? "." : "M"
+  end
+
+  print "\n"
+
+  # Print out what is missing
+  if not group_miss.empty?
+    puts "  > missing: " + "#{group_miss.join(", ")}"
+  end
+end
+
+# The grand tally
+percent = (100.0 * (total_methods - total_missing) / total_methods).round
+puts "\n" + "=" * 60
+puts "\nTOTAL: [#{total_methods - total_missing}/#{total_methods}] wrapped. (#{percent}% coverage)"
diff --git a/app/server/vendor/rugged-0.23.3/test/diff_test.rb b/app/server/vendor/rugged-0.23.3/test/diff_test.rb
new file mode 100755
index 0000000..20162ce
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/diff_test.rb
@@ -0,0 +1,1152 @@
+require "test_helper"
+
+class PatchFromStringsTest < Rugged::TestCase
+  def test_from_strings_no_args
+    patch = Rugged::Patch.from_strings()
+    assert_equal 0, patch.size
+    assert_equal "", patch.to_s
+  end
+
+  def test_from_strings_create_file
+    patch = Rugged::Patch.from_strings(nil, "added\n")
+    assert_equal 1, patch.size
+    assert_equal <<-EOS, patch.to_s
+diff --git a/file b/file
+new file mode 100644
+index 0000000..d5f7fc3
+--- /dev/null
++++ b/file
+@@ -0,0 +1 @@
++added
+EOS
+  end
+
+  def test_from_strings_delete_file
+    patch = Rugged::Patch.from_strings("deleted\n", nil)
+    assert_equal 1, patch.size
+    assert_equal <<-EOS, patch.to_s
+diff --git a/file b/file
+deleted file mode 100644
+index 71779d2..0000000
+--- a/file
++++ /dev/null
+@@ -1 +0,0 @@
+-deleted
+EOS
+  end
+
+  def test_from_strings_without_paths
+    patch = Rugged::Patch.from_strings("deleted\n", "added\n")
+    assert_equal 1, patch.size
+    assert_equal <<-EOS, patch.to_s
+diff --git a/file b/file
+index 71779d2..d5f7fc3 100644
+--- a/file
++++ b/file
+@@ -1 +1 @@
+-deleted
++added
+EOS
+  end
+
+  def test_from_strings_with_custom_paths
+    patch = Rugged::Patch.from_strings("deleted\n", "added\n", old_path: "old", new_path: "new")
+    assert_equal 1, patch.size
+    assert_equal <<-EOS, patch.to_s
+diff --git a/old b/new
+index 71779d2..d5f7fc3 100644
+--- a/old
++++ b/new
+@@ -1 +1 @@
+-deleted
++added
+EOS
+  end
+end
+
+class RepoDiffTest < Rugged::TestCase
+  def test_with_oid_string
+    repo = FixtureRepo.from_libgit2("attr")
+    diff = repo.diff("605812a", "370fe9ec22", :context_lines => 1, :interhunk_lines => 1)
+
+    deltas = diff.deltas
+    patches = diff.patches
+    hunks = patches.map(&:hunks).flatten
+    lines = hunks.map(&:lines).flatten
+
+    assert_equal 5, diff.size
+    assert_equal 5, deltas.size
+    assert_equal 5, patches.size
+
+    assert_equal 2, deltas.select(&:added?).size
+    assert_equal 1, deltas.select(&:deleted?).size
+    assert_equal 2, deltas.select(&:modified?).size
+
+    assert_equal 5, hunks.size
+
+    assert_equal((7 + 24 + 1 + 6 + 6), lines.size)
+    assert_equal((1), lines.select(&:context?).size)
+    assert_equal((24 + 1 + 5 + 5), lines.select(&:addition?).size)
+    assert_equal((7 + 1), lines.select(&:deletion?).size)
+  end
+
+  def test_delta_status_char
+    repo = FixtureRepo.from_libgit2("attr")
+    diff = repo.diff("605812a", "370fe9ec22", :context_lines => 1, :interhunk_lines => 1)
+
+    deltas = diff.deltas
+
+    assert_equal :D, deltas[0].status_char
+    assert_equal :A, deltas[1].status_char
+    assert_equal :A, deltas[2].status_char
+    assert_equal :M, deltas[3].status_char
+    assert_equal :M, deltas[4].status_char
+  end
+
+  def test_with_nil_on_left_side
+    repo = FixtureRepo.from_libgit2("attr")
+    diff = repo.diff("605812a", nil, :context_lines => 1, :interhunk_lines => 1)
+
+    deltas = diff.deltas
+    patches = diff.patches
+    hunks = patches.map(&:hunks).flatten
+    lines = hunks.map(&:lines).flatten
+
+    assert_equal 16, diff.size
+    assert_equal 16, deltas.size
+    assert_equal 16, patches.size
+
+    assert_equal 0, deltas.select(&:added?).size
+    assert_equal 16, deltas.select(&:deleted?).size
+    assert_equal 0, deltas.select(&:modified?).size
+
+    assert_equal 15, hunks.size
+
+    assert_equal 115, lines.size
+    assert_equal 0, lines.select(&:context?).size
+    assert_equal 0, lines.select(&:addition?).size
+    assert_equal 113, lines.select(&:deletion?).size
+  end
+
+  def test_with_nil_on_right_side
+    repo = FixtureRepo.from_libgit2("attr")
+    diff = repo.diff(nil, "605812a", :context_lines => 1, :interhunk_lines => 1)
+
+    deltas = diff.deltas
+    patches = diff.patches
+    hunks = patches.map(&:hunks).flatten
+    lines = hunks.map(&:lines).flatten
+
+    assert_equal 16, diff.size
+    assert_equal 16, deltas.size
+    assert_equal 16, patches.size
+
+    assert_equal 16, deltas.select(&:added?).size
+    assert_equal 0, deltas.select(&:deleted?).size
+    assert_equal 0, deltas.select(&:modified?).size
+
+    assert_equal 15, hunks.size
+
+    assert_equal 115, lines.size
+    assert_equal 0, lines.select(&:context?).size
+    assert_equal 113, lines.select(&:addition?).size
+    assert_equal 0, lines.select(&:deletion?).size
+  end
+end
+
+class RepoWorkdirDiffTest < Rugged::TestCase
+  def test_basic_diff
+    repo = FixtureRepo.from_libgit2("status")
+    diff = repo.diff_workdir("26a125ee1bf",
+      :context_lines => 3,
+      :interhunk_lines => 1,
+      :include_ignored => true,
+      :include_untracked => true
+    )
+
+    deltas = diff.deltas
+    patches = diff.patches
+    hunks = patches.map(&:hunks).flatten
+    lines = hunks.map(&:lines).flatten
+
+    assert_equal 14, deltas.size
+    assert_equal 14, patches.size
+
+    assert_equal 0, deltas.select(&:added?).size
+    assert_equal 4, deltas.select(&:deleted?).size
+    assert_equal 4, deltas.select(&:modified?).size
+    assert_equal 1, deltas.select(&:ignored?).size
+    assert_equal 5, deltas.select(&:untracked?).size
+
+    assert_equal 8, hunks.size
+
+    assert_equal 13, lines.size
+    assert_equal 4, lines.select(&:context?).size
+    assert_equal 5, lines.select(&:addition?).size
+    assert_equal 4, lines.select(&:deletion?).size
+  end
+end
+
+class CommitDiffTest < Rugged::TestCase
+  def test_diff_with_parent
+    repo = FixtureRepo.from_libgit2("attr")
+    commit = Rugged::Commit.lookup(repo, "605812a")
+
+    diff = commit.diff(:context_lines => 1, :interhunk_lines => 1)
+
+    deltas = diff.deltas
+    patches = diff.patches
+    hunks = patches.map(&:hunks).flatten
+    lines = hunks.map(&:lines).flatten
+
+    assert_equal 5, diff.size
+    assert_equal 5, deltas.size
+    assert_equal 5, patches.size
+
+    assert_equal 0, deltas.select(&:added?).size
+    assert_equal 3, deltas.select(&:deleted?).size
+    assert_equal 2, deltas.select(&:modified?).size
+
+    assert_equal 4, hunks.size
+
+    assert_equal(51, lines.size)
+    assert_equal(2, lines.select(&:context?).size)
+    assert_equal(3, lines.select(&:addition?).size)
+    assert_equal(46, lines.select(&:deletion?).size)
+  end
+
+  def test_diff_with_parent_for_initial_commit
+    repo = FixtureRepo.from_libgit2("attr")
+    commit = Rugged::Commit.lookup(repo, "6bab5c79cd5140d0f800917f550eb2a3dc32b0da")
+
+    diff = commit.diff(:context_lines => 1, :interhunk_lines => 1, :reverse => true)
+
+    deltas = diff.deltas
+    patches = diff.patches
+    hunks = patches.map(&:hunks).flatten
+    lines = hunks.map(&:lines).flatten
+
+    assert_equal 13, diff.size
+    assert_equal 13, deltas.size
+    assert_equal 13, patches.size
+
+    assert_equal 13, deltas.select(&:added?).size
+    assert_equal 0, deltas.select(&:deleted?).size
+    assert_equal 0, deltas.select(&:modified?).size
+
+    assert_equal 13, hunks.size
+
+    assert_equal(72, lines.size)
+    assert_equal(0, lines.select(&:context?).size)
+    assert_equal(70, lines.select(&:addition?).size)
+    assert_equal(0, lines.select(&:deletion?).size)
+  end
+end
+
+class CommitToWorkdirDiffTest < Rugged::TestCase
+  def test_basic_diff
+    repo = FixtureRepo.from_libgit2("status")
+    a = Rugged::Commit.lookup(repo, "26a125ee1bf")
+
+    diff = a.diff_workdir(
+      :context_lines => 3,
+      :interhunk_lines => 1,
+      :include_ignored => true,
+      :include_untracked => true
+    )
+
+    deltas = diff.deltas
+    patches = diff.patches
+    hunks = patches.map(&:hunks).flatten
+    lines = hunks.map(&:lines).flatten
+
+    assert_equal 14, deltas.size
+    assert_equal 14, patches.size
+
+    assert_equal 0, deltas.select(&:added?).size
+    assert_equal 4, deltas.select(&:deleted?).size
+    assert_equal 4, deltas.select(&:modified?).size
+    assert_equal 1, deltas.select(&:ignored?).size
+    assert_equal 5, deltas.select(&:untracked?).size
+
+    assert_equal 8, hunks.size
+
+    assert_equal 13, lines.size
+    assert_equal 4, lines.select(&:context?).size
+    assert_equal 5, lines.select(&:addition?).size
+    assert_equal 4, lines.select(&:deletion?).size
+  end
+end
+
+class TreeToWorkdirDiffTest < Rugged::TestCase
+  def test_basic_diff
+    repo = FixtureRepo.from_libgit2("status")
+    a = Rugged::Commit.lookup(repo, "26a125ee1bf").tree
+
+    diff = a.diff_workdir(
+      :context_lines => 3,
+      :interhunk_lines => 1,
+      :include_ignored => true,
+      :include_untracked => true
+    )
+
+    deltas = diff.deltas
+    patches = diff.patches
+    hunks = patches.map(&:hunks).flatten
+    lines = hunks.map(&:lines).flatten
+
+    assert_equal 14, deltas.size
+    assert_equal 14, patches.size
+
+    assert_equal 0, deltas.select(&:added?).size
+    assert_equal 4, deltas.select(&:deleted?).size
+    assert_equal 4, deltas.select(&:modified?).size
+    assert_equal 1, deltas.select(&:ignored?).size
+    assert_equal 5, deltas.select(&:untracked?).size
+
+    assert_equal 8, hunks.size
+
+    assert_equal 13, lines.size
+    assert_equal 4, lines.select(&:context?).size
+    assert_equal 5, lines.select(&:addition?).size
+    assert_equal 4, lines.select(&:deletion?).size
+  end
+
+  def test_diff_merge
+    repo = FixtureRepo.from_libgit2("status")
+    index = repo.index
+
+    a = Rugged::Commit.lookup(repo, "26a125ee1bf").tree
+
+    # merge diffs to simulate "git diff 26a125ee1bf"
+
+    diff  = a.diff(index, :include_ignored => true, :include_untracked => true)
+    diff2 = index.diff(:include_ignored => true, :include_untracked => true)
+    diff.merge!(diff2)
+
+    deltas = diff.deltas
+    patches = diff.patches
+    hunks = patches.map(&:hunks).flatten
+    lines = hunks.map(&:lines).flatten
+
+    # expected values differ from "git diff --porcelain 26a125ee1bf"
+    # because that includes the file "staged_delete_modified_file" twice,
+    # once in the deleted list and again the untracked list and libgit2
+    # does not do that with a merged diff (though it would with status)
+
+    assert_equal 15, deltas.size
+    assert_equal 15, patches.size
+
+    assert_equal 2, deltas.select(&:added?).size
+    assert_equal 5, deltas.select(&:deleted?).size
+    assert_equal 4, deltas.select(&:modified?).size
+    assert_equal 1, deltas.select(&:ignored?).size
+    assert_equal 3, deltas.select(&:untracked?).size
+
+    assert_equal 11, hunks.size
+
+    assert_equal 17, lines.size
+    assert_equal 4, lines.select(&:context?).size
+    assert_equal 8, lines.select(&:addition?).size
+    assert_equal 5, lines.select(&:deletion?).size
+  end
+
+  def test_stats
+    repo = FixtureRepo.from_libgit2("status")
+    index = repo.index
+
+    a = Rugged::Commit.lookup(repo, "26a125ee1bf").tree
+
+    # merge diffs to simulate "git diff 26a125ee1bf"
+
+    diff  = a.diff(index, :include_ignored => true, :include_untracked => true)
+    diff2 = index.diff(:include_ignored => true, :include_untracked => true)
+    diff.merge!(diff2)
+
+    # expected values from: git diff --stat 26a125ee1bf
+    files, adds, dels = diff.stat
+    assert_equal 11, files
+    assert_equal 8, adds
+    assert_equal 5, dels
+
+    # expected per-file values from the diff --stat output plus total lines
+    expected_patch_stat = [
+      [ 0, 1, 1 ], [ 1, 0, 2 ], [ 1, 0, 2 ], [ 0, 1, 1 ], [ 2, 0, 3 ],
+      [ 0, 1, 1 ], [ 0, 1, 1 ], [ 1, 0, 1 ], [ 2, 0, 2 ], [ 0, 1, 1 ],
+      [ 1, 0, 2 ]
+    ]
+
+    diff.each_patch do |patch|
+      next if [:unmodified, :ignored, :untracked].include? patch.delta.status
+
+      expected_adds, expected_dels, expected_lines = expected_patch_stat.shift
+
+      actual_adds, actual_dels = patch.stat
+
+      assert_equal expected_adds, actual_adds
+      assert_equal expected_dels, actual_dels
+      assert_equal expected_adds + expected_dels, patch.changes
+
+      assert_equal expected_lines, patch.lines
+    end
+  end
+end
+
+class TreeToTreeDiffTest < Rugged::TestCase
+  def test_basic_diff
+    repo = FixtureRepo.from_libgit2("attr")
+    a = Rugged::Commit.lookup(repo, "605812a").tree
+    b = Rugged::Commit.lookup(repo, "370fe9ec22").tree
+    c = Rugged::Commit.lookup(repo, "f5b0af1fb4f5c").tree
+
+    diff = a.diff(b, :context_lines => 1, :interhunk_lines => 1)
+
+    deltas = diff.deltas
+    patches = diff.patches
+    hunks = patches.map(&:hunks).flatten
+    lines = hunks.map(&:lines).flatten
+
+    assert_equal 5, diff.size
+    assert_equal 5, deltas.size
+    assert_equal 5, patches.size
+
+    assert_equal 2, deltas.select(&:added?).size
+    assert_equal 1, deltas.select(&:deleted?).size
+    assert_equal 2, deltas.select(&:modified?).size
+
+    assert_equal 5, hunks.size
+
+    assert_equal((7 + 24 + 1 + 6 + 6), lines.size)
+    assert_equal((1), lines.select(&:context?).size)
+    assert_equal((24 + 1 + 5 + 5), lines.select(&:addition?).size)
+    assert_equal((7 + 1), lines.select(&:deletion?).size)
+
+
+    diff = c.diff(b, :context_lines => 1, :interhunk_lines => 1)
+    deltas = diff.deltas
+    patches = diff.patches
+    hunks = patches.map(&:hunks).flatten
+    lines = hunks.map(&:lines).flatten
+
+    assert_equal 2, deltas.size
+    assert_equal 2, patches.size
+
+    assert_equal 0, deltas.select(&:added?).size
+    assert_equal 0, deltas.select(&:deleted?).size
+    assert_equal 2, deltas.select(&:modified?).size
+
+    assert_equal 2, hunks.size
+
+    assert_equal((8 + 15), lines.size)
+    assert_equal((1), lines.select(&:context?).size)
+    assert_equal((1), lines.select(&:addition?).size)
+    assert_equal((7 + 14), lines.select(&:deletion?).size)
+  end
+
+  def test_diff_with_empty_tree
+    repo = FixtureRepo.from_libgit2("attr")
+    a = Rugged::Commit.lookup(repo, "605812a").tree
+
+    diff = a.diff(nil, :context_lines => 1, :interhunk_lines => 1)
+
+    deltas = diff.deltas
+    patches = diff.patches
+    hunks = patches.map(&:hunks).flatten
+    lines = hunks.map(&:lines).flatten
+
+    assert_equal 16, diff.size
+    assert_equal 16, deltas.size
+    assert_equal 16, patches.size
+
+    assert_equal 0, deltas.select(&:added?).size
+    assert_equal 16, deltas.select(&:deleted?).size
+    assert_equal 0, deltas.select(&:modified?).size
+
+    assert_equal 15, hunks.size
+
+    assert_equal 115, lines.size
+    assert_equal 0, lines.select(&:context?).size
+    assert_equal 0, lines.select(&:addition?).size
+    assert_equal 113, lines.select(&:deletion?).size
+  end
+
+  def test_diff_with_rev_string
+    repo = FixtureRepo.from_libgit2("attr")
+    a = Rugged::Commit.lookup(repo, "605812a").tree
+
+    diff = a.diff("370fe9ec22", :context_lines => 1, :interhunk_lines => 1)
+
+    deltas = diff.deltas
+    patches = diff.patches
+    hunks = patches.map(&:hunks).flatten
+    lines = hunks.map(&:lines).flatten
+
+    assert_equal 5, diff.size
+    assert_equal 5, deltas.size
+    assert_equal 5, patches.size
+
+    assert_equal 2, deltas.select(&:added?).size
+    assert_equal 1, deltas.select(&:deleted?).size
+    assert_equal 2, deltas.select(&:modified?).size
+
+    assert_equal 5, hunks.size
+
+    assert_equal((7 + 24 + 1 + 6 + 6), lines.size)
+    assert_equal((1), lines.select(&:context?).size)
+    assert_equal((24 + 1 + 5 + 5), lines.select(&:addition?).size)
+    assert_equal((7 + 1), lines.select(&:deletion?).size)
+  end
+
+  def test_diff_merge
+    repo = FixtureRepo.from_libgit2("attr")
+    a = Rugged::Commit.lookup(repo, "605812a").tree
+    b = Rugged::Commit.lookup(repo, "370fe9ec22").tree
+    c = Rugged::Commit.lookup(repo, "f5b0af1fb4f5c").tree
+
+    diff = a.diff(b).merge!(c.diff(b))
+
+    deltas = diff.deltas
+    patches = diff.patches
+    hunks = patches.map(&:hunks).flatten
+    lines = hunks.map(&:lines).flatten
+
+    assert_equal 6, diff.size
+    assert_equal 6, patches.size
+    assert_equal 6, deltas.size
+
+    assert_equal 2, deltas.select(&:added?).size
+    assert_equal 1, deltas.select(&:deleted?).size
+    assert_equal 3, deltas.select(&:modified?).size
+
+    assert_equal 6, hunks.size
+
+    assert_equal 59, lines.size
+    assert_equal 1, lines.select(&:context?).size
+    assert_equal 36, lines.select(&:addition?).size
+    assert_equal 22, lines.select(&:deletion?).size
+  end
+
+  def test_symlink_blob_mode_changed_to_regular_file
+    repo = FixtureRepo.from_libgit2("unsymlinked.git")
+
+    a = Rugged::Commit.lookup(repo, "7fccd7").tree
+    b = Rugged::Commit.lookup(repo, "806999").tree
+
+    diff = a.diff(b)
+
+    deltas = diff.deltas
+    patches = diff.patches
+
+    assert_equal 3, diff.size
+    assert_equal 3, patches.size
+    assert_equal 3, deltas.size
+
+    assert_equal 1, deltas.select(&:added?).size
+    assert_equal 2, deltas.select(&:deleted?).size
+    assert_equal 0, deltas.select(&:modified?).size
+    assert_equal 0, deltas.select(&:typechange?).size
+  end
+
+  def test_symlink_blob_mode_changed_to_regular_file_as_typechange
+    repo = FixtureRepo.from_libgit2("unsymlinked.git")
+
+    a = Rugged::Commit.lookup(repo, "7fccd7").tree
+    b = Rugged::Commit.lookup(repo, "806999").tree
+
+    diff = a.diff(b, :include_typechange => true)
+
+    deltas = diff.deltas
+    patches = diff.patches
+
+    assert_equal 2, diff.size
+    assert_equal 2, patches.size
+    assert_equal 2, deltas.size
+
+    assert_equal 0, deltas.select(&:added?).size
+    assert_equal 1, deltas.select(&:deleted?).size
+    assert_equal 0, deltas.select(&:modified?).size
+    assert_equal 1, deltas.select(&:typechange?).size
+  end
+
+  def test_regular_blob_mode_changed_to_executable_file
+    repo = FixtureRepo.from_libgit2("unsymlinked.git")
+
+    a = Rugged::Commit.lookup(repo, "806999").tree
+    b = Rugged::Commit.lookup(repo, "a8595c").tree
+
+    diff = a.diff(b)
+
+    deltas = diff.deltas
+    patches = diff.patches
+
+    assert_equal 1, diff.size
+    assert_equal 1, patches.size
+    assert_equal 1, deltas.size
+
+    assert_equal 0, deltas.select(&:added?).size
+    assert_equal 0, deltas.select(&:deleted?).size
+    assert_equal 1, deltas.select(&:modified?).size
+    assert_equal 0, deltas.select(&:typechange?).size
+  end
+
+  def test_size
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree)
+    assert_equal 2, diff.size
+  end
+
+  def test_each_delta
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree)
+
+    deltas = []
+    diff.each_delta do |delta|
+      assert_instance_of Rugged::Diff::Delta, delta
+      deltas << delta
+    end
+
+    assert_equal 2, deltas.size
+
+    assert_equal "another.txt", deltas[0].old_file[:path]
+    assert_equal "another.txt", deltas[0].new_file[:path]
+
+    refute deltas[0].binary?
+
+    assert_equal "readme.txt", deltas[1].old_file[:path]
+    assert_equal "readme.txt", deltas[1].new_file[:path]
+
+    refute deltas[1].binary?
+  end
+
+  def test_diff_treats_files_bigger_as_max_size_as_binary
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree, :max_size => 10)
+    assert_equal 2, diff.patches.size
+    assert_equal <<-EOS, diff.patch
+diff --git a/another.txt b/another.txt
+index 3e5bcba..546c735 100644
+Binary files a/another.txt and b/another.txt differ
+diff --git a/readme.txt b/readme.txt
+index 7b808f7..29ab705 100644
+Binary files a/readme.txt and b/readme.txt differ
+EOS
+  end
+
+  def test_contraining_paths
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree, :paths => ["readme.txt"])
+    assert_equal "M\treadme.txt\n", diff.patch(:compact => true)
+
+    diff = a.tree.diff(b.tree, :paths => ["r*.txt"])
+    assert_equal "M\treadme.txt\n", diff.patch(:compact => true)
+
+    diff = a.tree.diff(b.tree, :paths => ["*.txt"])
+    assert_equal "M\tanother.txt\nM\treadme.txt\n", diff.patch(:compact => true)
+
+    diff = a.tree.diff(b.tree, :paths => ["*.txt"], :disable_pathspec_match => true)
+    assert_equal "", diff.patch(:compact => true)
+
+    diff = a.tree.diff(b.tree, :paths => ["readme.txt"], :disable_pathspec_match => true)
+    assert_equal "M\treadme.txt\n", diff.patch(:compact => true)
+  end
+
+  def test_options
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree, :context_lines => 0)
+
+    assert_equal <<-EOS, diff.patch
+diff --git a/another.txt b/another.txt
+index 3e5bcba..546c735 100644
+--- a/another.txt
++++ b/another.txt
+@@ -2 +2 @@ Git is fast. With Git, nearly all operations are performed locally, giving
+-it a huge speed advantage on centralized systems that constantly have to
++it an huge speed advantage on centralized systems that constantly have to
+@@ -11,4 +10,0 @@ from the start.
+-Let's see how common operations stack up against Subversion, a common
+-centralized version control system that is similar to CVS or
+-Perforce. Smaller is faster.
+-
+@@ -34,0 +31,4 @@ SVN.
++Let's see how common operations stack up against Subversion, a common
++centralized version control system that is similar to CVS or
++Perforce. Smaller is faster.
++
+diff --git a/readme.txt b/readme.txt
+index 7b808f7..29ab705 100644
+--- a/readme.txt
++++ b/readme.txt
+@@ -1 +1 @@
+-The Git feature that really makes it stand apart from nearly every other SCM
++The Git feature that r3ally mak3s it stand apart from n3arly 3v3ry other SCM
+@@ -10,4 +9,0 @@ This means that you can do things like:
+-Frictionless Context Switching. Create a branch to try out an idea, commit a
+-few times, switch back to where you branched from, apply a patch, switch
+-back to where you are experimenting, and merge it in.
+-
+@@ -27,3 +22,0 @@ Notably, when you push to a remote repository, you do not have to push all
+-of your branches. You can choose to share just one of your branches, a few
+-of them, or all of them. This tends to free people to try new ideas without
+-worrying about having to plan how and when they are going to merge it in or
+@@ -35 +28 @@ incredibly easy and it changes the way most developers work when they learn
+-it.
++it.!
+\\ No newline at end of file
+EOS
+  end
+
+  def test_iteration
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree)
+
+    patches = []
+
+    diff.each_patch do |patch|
+      assert_instance_of Rugged::Patch, patch
+      patches << patch
+    end
+
+    assert_equal 2, patches.size
+
+    assert_equal "another.txt", patches[0].delta.old_file[:path]
+    assert_equal "another.txt", patches[0].delta.new_file[:path]
+
+    refute patches[0].delta.binary?
+
+    hunks = []
+    patches[0].each_hunk do |hunk|
+      assert_instance_of Rugged::Diff::Hunk, hunk
+      hunks << hunk
+    end
+    assert_equal 3, hunks.size
+
+    assert hunks[0].header.start_with? "@@ -1,5 +1,5 @@"
+    assert_equal 6, hunks[0].line_count
+    assert_equal 1, hunks[0].old_start
+    assert_equal 5, hunks[0].old_lines
+    assert_equal 1, hunks[0].new_start
+    assert_equal 5, hunks[0].new_lines
+
+    assert hunks[1].header.start_with? "@@ -8,10 +8,6 @@"
+    assert_equal 10, hunks[1].line_count
+    assert_equal 8, hunks[1].old_start
+    assert_equal 10, hunks[1].old_lines
+    assert_equal 8, hunks[1].new_start
+    assert_equal 6, hunks[1].new_lines
+
+    assert hunks[2].header.start_with? "@@ -32,6 +28,10 @@"
+    assert_equal 10, hunks[2].line_count
+    assert_equal 32, hunks[2].old_start
+    assert_equal 6, hunks[2].old_lines
+    assert_equal 28, hunks[2].new_start
+    assert_equal 10, hunks[2].new_lines
+
+    assert_equal "readme.txt", patches[1].delta.old_file[:path]
+    assert_equal "readme.txt", patches[1].delta.new_file[:path]
+
+    refute patches[1].delta.binary?
+
+    hunks = []
+    patches[1].each_hunk do |hunk|
+      assert_instance_of Rugged::Diff::Hunk, hunk
+      hunks << hunk
+    end
+    assert_equal 3, hunks.size
+
+    assert hunks[0].header.start_with? "@@ -1,4 +1,4 @@"
+    assert hunks[1].header.start_with? "@@ -7,10 +7,6 @@"
+    assert hunks[2].header.start_with? "@@ -24,12 +20,9 @@"
+
+    lines = []
+    hunks[0].each_line do |line|
+      lines << line
+    end
+    assert_equal 5, lines.size
+
+    assert_equal :deletion, lines[0].line_origin
+    assert_equal "The Git feature that really makes it stand apart from nearly every other SCM\n", lines[0].content
+    assert_equal 0, lines[0].content_offset
+
+    assert_equal :addition, lines[1].line_origin
+    assert_equal "The Git feature that r3ally mak3s it stand apart from n3arly 3v3ry other SCM\n", lines[1].content
+    assert_equal 0, lines[1].content_offset
+
+    assert_equal :context, lines[2].line_origin
+    assert_equal "out there is its branching model.\n", lines[2].content
+    assert_nil lines[2].content_offset
+
+    assert_equal :context, lines[3].line_origin
+    assert_equal "\n", lines[3].content
+
+    assert_equal :context, lines[4].line_origin
+    assert_equal "Git allows and encourages you to have multiple local branches that can be\n", lines[4].content
+
+    lines = hunks[2].each_line.to_a
+
+    assert_equal 14, lines.size
+
+    assert_equal :deletion, lines[3].line_origin
+    assert_equal "of your branches. You can choose to share just one of your branches, a few\n", lines[3].content
+    assert_equal 1248, lines[3].content_offset
+
+    assert_equal :deletion, lines[4].line_origin
+    assert_equal "of them, or all of them. This tends to free people to try new ideas without\n", lines[4].content
+    assert_equal 1323, lines[4].content_offset
+
+    assert_equal :deletion, lines[11].line_origin
+    assert_equal "it.\n", lines[11].content
+    assert_equal 1721, lines[11].content_offset
+
+    assert_equal :addition, lines[12].line_origin
+    assert_equal "it.!", lines[12].content
+    assert_equal 1289, lines[12].content_offset
+  end
+
+  def test_each_line_patch
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree)
+
+    lines = diff.each_line.to_a
+    assert_equal 63, lines.size
+
+    assert_equal(:file_header, lines[0].line_origin)
+    assert_equal("diff --git a/another.txt b/another.txt\nindex 3e5bcba..546c735 100644\n--- a/another.txt\n+++ b/another.txt\n", lines[0].content)
+    assert_equal(0, lines[0].content_offset)
+    assert_equal(-1, lines[0].old_lineno)
+    assert_equal(-1, lines[0].new_lineno)
+
+    assert_equal(:hunk_header, lines[1].line_origin)
+    assert_equal("@@ -1,5 +1,5 @@\n", lines[1].content)
+    assert_equal(0, lines[1].content_offset)
+    assert_equal(-1, lines[1].old_lineno)
+    assert_equal(-1, lines[1].new_lineno)
+
+    assert_equal(:context, lines[2].line_origin)
+    assert_equal("Git is fast. With Git, nearly all operations are performed locally, giving\n", lines[2].content)
+    assert_equal(nil, lines[2].content_offset)
+    assert_equal(1, lines[2].old_lineno)
+    assert_equal(1, lines[2].new_lineno)
+
+    assert_equal(:deletion, lines[3].line_origin)
+    assert_equal("it a huge speed advantage on centralized systems that constantly have to\n", lines[3].content)
+    assert_equal(75, lines[3].content_offset)
+    assert_equal(2, lines[3].old_lineno)
+    assert_equal(-1, lines[3].new_lineno)
+
+    assert_equal(:addition, lines[4].line_origin)
+    assert_equal("it an huge speed advantage on centralized systems that constantly have to\n", lines[4].content)
+    assert_equal(75, lines[4].content_offset)
+    assert_equal(-1, lines[4].old_lineno)
+    assert_equal(2, lines[4].new_lineno)
+  end
+
+  def test_each_line_patch_header
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree)
+
+    lines = diff.each_line(:patch_header).to_a
+    assert_equal 2, lines.size
+
+    assert_equal(:file_header, lines[0].line_origin)
+    assert_equal("diff --git a/another.txt b/another.txt\nindex 3e5bcba..546c735 100644\n--- a/another.txt\n+++ b/another.txt\n", lines[0].content)
+    assert_equal(0, lines[0].content_offset)
+    assert_equal(-1, lines[0].old_lineno)
+    assert_equal(-1, lines[0].new_lineno)
+
+    assert_equal(:file_header, lines[1].line_origin)
+    assert_equal("diff --git a/readme.txt b/readme.txt\nindex 7b808f7..29ab705 100644\n--- a/readme.txt\n+++ b/readme.txt\n", lines[1].content)
+    assert_equal(0, lines[1].content_offset)
+    assert_equal(-1, lines[1].old_lineno)
+    assert_equal(-1, lines[1].new_lineno)
+  end
+
+  def test_each_line_raw
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree)
+
+    lines = diff.each_line(:raw).to_a
+    assert_equal 2, lines.size
+
+    assert_equal(:file_header, lines[0].line_origin)
+    assert_equal(":100644 100644 3e5bcba... 546c735... M\tanother.txt\n", lines[0].content)
+    assert_equal(0, lines[0].content_offset)
+    assert_equal(-1, lines[0].old_lineno)
+    assert_equal(-1, lines[0].new_lineno)
+
+    assert_equal(:file_header, lines[1].line_origin)
+    assert_equal(":100644 100644 7b808f7... 29ab705... M\treadme.txt\n", lines[1].content)
+    assert_equal(0, lines[1].content_offset)
+    assert_equal(-1, lines[1].old_lineno)
+    assert_equal(-1, lines[1].new_lineno)
+  end
+
+  def test_each_line_name_only
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree)
+
+    lines = diff.each_line(:name_only).to_a
+    assert_equal 2, lines.size
+
+    assert_equal(:file_header, lines[0].line_origin)
+    assert_equal("another.txt\n", lines[0].content)
+    assert_equal(0, lines[0].content_offset)
+    assert_equal(-1, lines[0].old_lineno)
+    assert_equal(-1, lines[0].new_lineno)
+
+    assert_equal(:file_header, lines[1].line_origin)
+    assert_equal("readme.txt\n", lines[1].content)
+    assert_equal(0, lines[1].content_offset)
+    assert_equal(-1, lines[1].old_lineno)
+    assert_equal(-1, lines[1].new_lineno)
+  end
+
+  def test_each_line_name_status
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree)
+
+    lines = diff.each_line(:name_status).to_a
+    assert_equal 2, lines.size
+
+    assert_equal(:file_header, lines[0].line_origin)
+    assert_equal("M\tanother.txt\n", lines[0].content)
+    assert_equal(0, lines[0].content_offset)
+    assert_equal(-1, lines[0].old_lineno)
+    assert_equal(-1, lines[0].new_lineno)
+
+    assert_equal(:file_header, lines[1].line_origin)
+    assert_equal("M\treadme.txt\n", lines[1].content)
+    assert_equal(0, lines[1].content_offset)
+    assert_equal(-1, lines[1].old_lineno)
+    assert_equal(-1, lines[1].new_lineno)
+  end
+
+  def test_each_line_unknown_format_raises_error
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree)
+
+    assert_raises ArgumentError do
+      diff.each_line(:foobar).to_a
+    end
+  end
+
+  def test_each_patch_returns_enumerator
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree)
+
+    assert_instance_of Enumerator, diff.each_patch
+
+    patches = []
+    diff.each_patch.each do |patch|
+      assert_instance_of Rugged::Patch, patch
+      patches << patch
+    end
+    assert_equal 2, patches.size
+  end
+
+  def test_each_hunk_returns_enumerator
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree)
+
+    diff.each_patch do |patch|
+      assert_instance_of Enumerator, patch.each_hunk
+    end
+  end
+
+  def test_each_line_returns_enumerator
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree)
+
+    diff.each_patch do |patch|
+      patch.each_hunk do |hunk|
+        assert_instance_of Enumerator, hunk.each_line
+      end
+    end
+  end
+
+  def test_patch
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree)
+
+    expected = <<-EOS
+diff --git a/another.txt b/another.txt
+index 3e5bcba..546c735 100644
+--- a/another.txt
++++ b/another.txt
+@@ -1,5 +1,5 @@
+ Git is fast. With Git, nearly all operations are performed locally, giving
+-it a huge speed advantage on centralized systems that constantly have to
++it an huge speed advantage on centralized systems that constantly have to
+ communicate with a server somewhere.
+ 
+ Git was built to work on the Linux kernel, meaning that it has had to
+@@ -8,10 +8,6 @@ reducing the overhead of runtimes associated with higher-level
+ languages. Speed and performance has been a primary design goal of the Git
+ from the start.
+ 
+-Let's see how common operations stack up against Subversion, a common
+-centralized version control system that is similar to CVS or
+-Perforce. Smaller is faster.
+-
+ For testing, large AWS instances were set up in the same availability
+ zone. Git and SVN were installed on both machines, the Ruby repository was
+ copied to both Git and SVN servers, and common operations were performed on
+@@ -32,6 +28,10 @@ Clearly, in many of these common version control operations, Git is one or
+ two orders of magnitude faster than SVN, even under ideal conditions for
+ SVN.
+ 
++Let's see how common operations stack up against Subversion, a common
++centralized version control system that is similar to CVS or
++Perforce. Smaller is faster.
++
+ One place where Git is slower is in the initial clone operation. Here, Git
+ is downloading the entire history rather than only the latest version. As
+ seen in the above charts, it's not considerably slower for an operation that
+diff --git a/readme.txt b/readme.txt
+index 7b808f7..29ab705 100644
+--- a/readme.txt
++++ b/readme.txt
+@@ -1,4 +1,4 @@
+-The Git feature that really makes it stand apart from nearly every other SCM
++The Git feature that r3ally mak3s it stand apart from n3arly 3v3ry other SCM
+ out there is its branching model.
+ 
+ Git allows and encourages you to have multiple local branches that can be
+@@ -7,10 +7,6 @@ those lines of development takes seconds.
+ 
+ This means that you can do things like:
+ 
+-Frictionless Context Switching. Create a branch to try out an idea, commit a
+-few times, switch back to where you branched from, apply a patch, switch
+-back to where you are experimenting, and merge it in.
+-
+ Role-Based Codelines. Have a branch that always contains only what goes to
+ production, another that you merge work into for testing, and several
+ smaller ones for day to day work.
+@@ -24,12 +20,9 @@ not going to work, and just delete it - abandoning the work\xE2\x80\x94with nobody else
+ ever seeing it (even if you've pushed other branches in the meantime).
+ 
+ Notably, when you push to a remote repository, you do not have to push all
+-of your branches. You can choose to share just one of your branches, a few
+-of them, or all of them. This tends to free people to try new ideas without
+-worrying about having to plan how and when they are going to merge it in or
+ share it with others.
+ 
+ There are ways to accomplish some of this with other systems, but the work
+ involved is much more difficult and error-prone. Git makes this process
+ incredibly easy and it changes the way most developers work when they learn
+-it.
++it.!
+\\ No newline at end of file
+EOS
+
+    expected.force_encoding('binary') if expected.respond_to?(:force_encoding)
+
+    assert_equal expected, diff.patch
+  end
+
+  def test_patch_compact
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree)
+
+    assert_equal <<-EOS, diff.patch(:compact => true)
+M\tanother.txt
+M\treadme.txt
+EOS
+  end
+
+  def test_stats
+    repo = FixtureRepo.from_libgit2("diff")
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree)
+
+    files, adds, dels = diff.stat
+    assert_equal 2, files
+    assert_equal 7, adds
+    assert_equal 14, dels
+
+    expected_patch_stat = [ [ 5, 5, 26 ], [ 2, 9, 28 ] ]
+
+    diff.each_patch do |patch|
+      expected_adds, expected_dels, expected_lines = expected_patch_stat.shift
+
+      actual_adds, actual_dels = patch.stat
+
+      assert_equal expected_adds, actual_adds
+      assert_equal expected_dels, actual_dels
+      assert_equal expected_adds + expected_dels, patch.changes
+
+      assert_equal expected_lines, patch.lines
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/errors_test.rb b/app/server/vendor/rugged-0.23.3/test/errors_test.rb
new file mode 100755
index 0000000..b56803a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/errors_test.rb
@@ -0,0 +1,34 @@
+require "test_helper"
+
+class ErrorsTest < Rugged::TestCase
+
+  def test_rugged_error_classes_exist
+    error_classes = [
+      Rugged::NoMemError,
+      Rugged::OSError,
+      Rugged::InvalidError,
+      Rugged::Error,
+      Rugged::ReferenceError,
+      Rugged::ZlibError,
+      Rugged::RepositoryError,
+      Rugged::ConfigError,
+      Rugged::RegexError,
+      Rugged::OdbError,
+      Rugged::IndexError,
+      Rugged::ObjectError,
+      Rugged::NetworkError,
+      Rugged::TagError,
+      Rugged::TreeError,
+      Rugged::IndexerError
+    ]
+
+    # All should descend from StandardError (correctly), except
+    # Rugged::NoMemError which descends from Ruby's built-in NoMemoryError,
+    # which descends from Exception
+    error_classes.each do |klass|
+      err = klass.new
+      assert err.is_a?(Exception)
+    end
+  end
+end
+
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/alternate/objects/14/6ae76773c91e3b1d00cf7a338ec55ae58297e2 b/app/server/vendor/rugged-0.23.3/test/fixtures/alternate/objects/14/6ae76773c91e3b1d00cf7a338ec55ae58297e2
new file mode 100755
index 0000000..a9ea0ba
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/alternate/objects/14/6ae76773c91e3b1d00cf7a338ec55ae58297e2 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/alternate/objects/14/9c32d47e99d0a3572ff1e70a2e0051bbf347a9 b/app/server/vendor/rugged-0.23.3/test/fixtures/alternate/objects/14/9c32d47e99d0a3572ff1e70a2e0051bbf347a9
new file mode 100755
index 0000000..ee08c7f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/alternate/objects/14/9c32d47e99d0a3572ff1e70a2e0051bbf347a9 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/alternate/objects/14/fb3108588f9421bf764041e5e3ac305eb6277f b/app/server/vendor/rugged-0.23.3/test/fixtures/alternate/objects/14/fb3108588f9421bf764041e5e3ac305eb6277f
new file mode 100755
index 0000000..18adabe
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/alternate/objects/14/fb3108588f9421bf764041e5e3ac305eb6277f differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/archive.tar.gz b/app/server/vendor/rugged-0.23.3/test/fixtures/archive.tar.gz
new file mode 100755
index 0000000..42cab3c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/archive.tar.gz differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/HEAD_TRACKER b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/HEAD_TRACKER
new file mode 100755
index 0000000..40d876b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/HEAD_TRACKER
@@ -0,0 +1 @@
+ref: HEAD
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/config b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/config
new file mode 100755
index 0000000..d011401
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/config
@@ -0,0 +1,8 @@
+[core]
+        repositoryformatversion = 0
+        filemode = true
+        bare = false
+        logallrefupdates = true
+[remote "test"]
+	url = git://github.com/libgit2/libgit2
+	fetch = +refs/heads/*:refs/remotes/test/*
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/index b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/index
new file mode 100755
index 0000000..a27fb9c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/09/9fabac3a9ea935598528c27f866e34089c2eff b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/09/9fabac3a9ea935598528c27f866e34089c2eff
new file mode 100755
index 0000000..c60c78f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/09/9fabac3a9ea935598528c27f866e34089c2eff
@@ -0,0 +1 @@
+xÎQ P¿9Å^@³ÂB!1F½‚'€î¢ÒJ?¼½Õ#ø7™ÉK¦ŸJhM›VE€,³·.3û¼§Þ¦ˆ‚ÔuVsHè-;õŠUÆÑÙ,œMˆ’…P³Iɉ&ÎĔ׍ìסŠK»O.2µո$8¤ùN·¡Ý—´ë§r„½!½l±CTk»lòUgfˆ0¿ËsêÓG(
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08
new file mode 100755
index 0000000..cedb2a2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/14/4344043ba4d4a405da03de3844aa829ae8be0e b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/14/4344043ba4d4a405da03de3844aa829ae8be0e
new file mode 100755
index 0000000..b7d944f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/14/4344043ba4d4a405da03de3844aa829ae8be0e differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/16/8e4ebd1c667499548ae12403b19b22a5c5e925 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/16/8e4ebd1c667499548ae12403b19b22a5c5e925
new file mode 100755
index 0000000..d37b93e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/16/8e4ebd1c667499548ae12403b19b22a5c5e925 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7
new file mode 100755
index 0000000..93a16f1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd
new file mode 100755
index 0000000..ba0bfb3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b
new file mode 100755
index 0000000..225c457
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d
new file mode 100755
index 0000000..df40d99
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54
new file mode 100755
index 0000000..321eaa8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc
new file mode 100755
index 0000000..9bb5b62
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057
new file mode 100755
index 0000000..7ca4cee
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/45/dd856fdd4d89b884c340ba0e047752d9b085d6 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/45/dd856fdd4d89b884c340ba0e047752d9b085d6
new file mode 100755
index 0000000..a83ed97
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/45/dd856fdd4d89b884c340ba0e047752d9b085d6 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
new file mode 100755
index 0000000..8953b6c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
@@ -0,0 +1,2 @@
+xŽQ
+Â0DýÎ)öÊ6›Í¦ "xO°‰‰-ØFb¼¿EoàÏ0¼Ç¤º,ske×[ÎPn8R,EpD?±gŸ}Ê^3²âÙ<µåµGŽhYKÄèÒ8ЖDAÉ)¿ÉÈ;gôݧÚàšjïp™4ÕŽ¯ô-çû¢óãêr‚ÁŠ;°s°GA4Ûº=ìùÖ(ôin7øIÌKÍFE
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/4e/0883eeeeebc1fb1735161cea82f7cb5fab7e63 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/4e/0883eeeeebc1fb1735161cea82f7cb5fab7e63
new file mode 100755
index 0000000..e915021
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/4e/0883eeeeebc1fb1735161cea82f7cb5fab7e63 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
new file mode 100755
index 0000000..c1f22c5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
@@ -0,0 +1,2 @@
+xŽÛ	1EýNi@™Ék2 "X‚$ÙYW0YcÿíÀ¿Ã…s¸¥ÕzïÚÚõMDÏ€0æœ8!¶†ÉÌÞs‰XŠªgÚdí::@X0»P¢wÙ"F/‰‰œÍRàˆUz÷¥múZZïú²¤ÒV}|•/œo5݇ÒêI£!¬1z Æ:vùÇUim}ê/¢>
+öF-
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/62/eb56dabb4b9929bc15dd9263c2c733b13d2dcc b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/62/eb56dabb4b9929bc15dd9263c2c733b13d2dcc
new file mode 100755
index 0000000..b669961
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/62/eb56dabb4b9929bc15dd9263c2c733b13d2dcc differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/66/3adb09143767984f7be83a91effa47e128c735 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/66/3adb09143767984f7be83a91effa47e128c735
new file mode 100755
index 0000000..9ff5eb2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/66/3adb09143767984f7be83a91effa47e128c735 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a
new file mode 100755
index 0000000..2ef4faa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af
new file mode 100755
index 0000000..716b0c6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af
@@ -0,0 +1 @@
+xŽAj!³ö?0¨£ßÂ09Êo}HÚ6¨}ÿôjUPP©ÕZ&Yÿø˜ AÔ›±€pŒÁFdë¼÷pz[fŽYŒ½PÒqLJ.,Z§`™Å®Ð.ù`’vÙ³q
$Æ5+9çOëtœû>Û/úDE/龡W¯ï*e¿§VŸdf1>ð覭Öê²×äÄ›¹úÊ™F« ­ìTŽÙhœk.i¶^0Ô?P¼R,
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/7b/4384978d2493e851f9cca7858815fac9b10980 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/7b/4384978d2493e851f9cca7858815fac9b10980
new file mode 100755
index 0000000..23c462f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/7b/4384978d2493e851f9cca7858815fac9b10980 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d
new file mode 100755
index 0000000..2f9b6b6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479
new file mode 100755
index 0000000..5df58dd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/87/380ae84009e9c503506c2f6143a4fc6c60bf80 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/87/380ae84009e9c503506c2f6143a4fc6c60bf80
new file mode 100755
index 0000000..3042f57
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/87/380ae84009e9c503506c2f6143a4fc6c60bf80 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162
new file mode 100755
index 0000000..4cc3f4d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162
@@ -0,0 +1 @@
+x+)JMU044b040031QrutñueX¡l¨ðmmA‹m›Ì£íJ}Gß;U‘T”˜—œŸ–™“ªWRQÂ`6ýš÷KÇ¥¶^/¾-*|òøWØ¥3P¥y©å`%ËEÛÞ±\&gŽÐ|Ÿ0§ÿ†{Ӎ1X
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4
new file mode 100755
index 0000000..bf7b2bb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
new file mode 100755
index 0000000..a796124
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
@@ -0,0 +1,3 @@
+xŽ[
+Â0EýÎ*fÊäÕ¤ "¸W0“‡-ØFâtÿ݁—çpS[–YÀ˜x^
+Díb	CLhutɉ}¥8X*4Zí¬sY½¨—UÀ‘AÃÖ
ÌX3‡R«Mµ¶) s6è¼¢M¦ÖážšÜ&Jm…ó;}Çõ±Ðü<¥¶\@›à‚ÑޏpÄ€¨vº?”ò«jÛºLð«¨Ø?Hå
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
new file mode 100755
index 0000000..f858869
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
@@ -0,0 +1,2 @@
+x;j1DëmdÓú·À˜ÇŽ|M«µ3`ŒV{>€³âQ¯ ¸·vL0I?Í!š4–Z=Ê! ×¦8²F¢Ã’!rÖsQßyÈ9]$DŽ&„l6AÇ>jFWüÒµIKNiûë§Z¢%¡SˆŒ‘
+‹Ò	­ÅʉøU~̽øä>'¼ï™û	¯wþ
×[ËÇ×÷öÚDGÚ¡±ðŒQ-ºMù«>dܶ‘OÞáÒò}í\à8g_ШÂoYr
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750
new file mode 100755
index 0000000..29c8e82
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750
@@ -0,0 +1,3 @@
+xŽQ
+!@ûösBQ"‚ŽÐ	ÆÙ±
rÍîßÒú{<xð¤·öàîƪ
+™HlJSer!ZPTe*Žj°UÝÑEo^¼ê2 (†ˆ¬XSÅ€ED‘ƒO<Y¦šj$2üs_á&}¸Î,}Ó[~p¹7~<ÒÛ:Ÿ	£°·ÉZ³Ùípè?­1_ûåC0
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd
new file mode 100755
index 0000000..d0d7e73
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6
new file mode 100755
index 0000000..18a7f61
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/ae/90f12eea699729ed24555e40b9fd669da12a12 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/ae/90f12eea699729ed24555e40b9fd669da12a12
new file mode 100755
index 0000000..d952546
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/ae/90f12eea699729ed24555e40b9fd669da12a12 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/b2/5fa35b38051e4ae45d4222e795f9df2e43f1d1 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/b2/5fa35b38051e4ae45d4222e795f9df2e43f1d1
new file mode 100755
index 0000000..f460f25
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/b2/5fa35b38051e4ae45d4222e795f9df2e43f1d1
@@ -0,0 +1,2 @@
+xÌA
+Â0…a×9ÅìIÒ	™€ˆp'î§1Ñ¶‘v\x{cáýðVŸpƒvWûgŠ¾ÇŽ0xº[]"g†#{rDÆ
Cot ­äûN œU$­ò?9-p+1Í^¤ÀQx®¯Ï9O\ÆC¬Ó	Œm'D
{mµVêú(+´ñælè¶,Þ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593
new file mode 100755
index 0000000..f613670
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644
new file mode 100755
index 0000000..0817229
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644
@@ -0,0 +1,3 @@
+xKj1D³Ö)zçUBëÛ-0ÁuV9¦Õò<#£È÷ÏȲ+ŠW<Jú¶Ý&8Ê/s¨‚e‹µµÈ•KJ­«½S
+ØRvÌÁ{©æQ†îr«äY¹QN$H\Eµ²Íè=6áX5¦òÇK Fr)·(‰dC‡Î†”­–œ—jÊs®}À—ô9ác-Òw8Ëo¸\·r»¿IßÞÁ:
+l}F‚W$Ds´Ç£©ÿÙšOW…e”]V8-ÝÌÈ"U
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/c0/528fd6cc988c0a40ce0be11bc192fc8dc5346e b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/c0/528fd6cc988c0a40ce0be11bc192fc8dc5346e
new file mode 100755
index 0000000..0401ab4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/c0/528fd6cc988c0a40ce0be11bc192fc8dc5346e differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
new file mode 100755
index 0000000..75f541f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
@@ -0,0 +1,3 @@
+xŽQ
+Â0DýÎ)öʦ»I<‚'ØlR+˜Fj¼¿EoàÏ0<xÃh«õÞa Üõµ]È™­åXUlÞPF)Åz‘4yó”µ,\r	'SÂÄ-mI4
+‘Xhô”&òÌFÞ}n+\µõ—Y´-p|é·œoU¶z;-‘aÑlt{ØË?®I«,:ÃoÚR̳cHK
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/cf/80f8de9f1185bf3a05f993f6121880dd0cfbc9 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/cf/80f8de9f1185bf3a05f993f6121880dd0cfbc9
new file mode 100755
index 0000000..7620c51
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/cf/80f8de9f1185bf3a05f993f6121880dd0cfbc9 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/d5/2a8fe84ceedf260afe4f0287bbfca04a117e83 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/d5/2a8fe84ceedf260afe4f0287bbfca04a117e83
new file mode 100755
index 0000000..00940f0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/d5/2a8fe84ceedf260afe4f0287bbfca04a117e83 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f
new file mode 100755
index 0000000..a67d6e6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100755
index 0000000..7112238
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0
new file mode 100755
index 0000000..b135ecc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3
new file mode 100755
index 0000000..82e2790
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1
new file mode 100755
index 0000000..697c94c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92
new file mode 100755
index 0000000..112998d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765
new file mode 100755
index 0000000..12bf5f3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765 differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx
new file mode 100755
index 0000000..5068f28
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack
new file mode 100755
index 0000000..a6a1f30
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx
new file mode 100755
index 0000000..94c3c71
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack
new file mode 100755
index 0000000..74c7fe4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx
new file mode 100755
index 0000000..555cfa9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.pack b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.pack
new file mode 100755
index 0000000..4d539ed
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/packed-refs b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/packed-refs
new file mode 100755
index 0000000..6018a19
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/packed-refs
@@ -0,0 +1,4 @@
+# pack-refs with: peeled 
+41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9 refs/heads/packed
+5b5b025afb0b4c913b4c338a42934a3863bf3644 refs/heads/packed-test
+b25fa35b38051e4ae45d4222e795f9df2e43f1d1 refs/tags/packed-tag
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/br2 b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/br2
new file mode 100755
index 0000000..aab87e5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/br2
@@ -0,0 +1 @@
+a4a7dce85cf63874e984719f4fdd239f5145052f
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/dir b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/dir
new file mode 100755
index 0000000..4567d37
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/dir
@@ -0,0 +1 @@
+144344043ba4d4a405da03de3844aa829ae8be0e
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/master
new file mode 100755
index 0000000..f31fe78
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/master
@@ -0,0 +1 @@
+099fabac3a9ea935598528c27f866e34089c2eff
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/packed-test b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/packed-test
new file mode 100755
index 0000000..f2c14ad
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/packed-test
@@ -0,0 +1 @@
+4a202b346bb0fb0db7eff3cffeb3c70babbd2045
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/subtrees b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/subtrees
new file mode 100755
index 0000000..ad27e0b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/subtrees
@@ -0,0 +1 @@
+763d71aadf09a7951596c9746c024e7eece7c7af
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/test b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/test
new file mode 100755
index 0000000..399c4c7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/heads/test
@@ -0,0 +1 @@
+e90810b8df3e80c413d903f631643c716887138d
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/tags/e90810b b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/tags/e90810b
new file mode 100755
index 0000000..584495d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/tags/e90810b
@@ -0,0 +1 @@
+7b4384978d2493e851f9cca7858815fac9b10980
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/tags/foo/bar b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/tags/foo/bar
new file mode 100755
index 0000000..6ee952a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/tags/foo/bar
@@ -0,0 +1 @@
+b25fa35b38051e4ae45d4222e795f9df2e43f1d1
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/tags/foo/foo/bar b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/tags/foo/foo/bar
new file mode 100755
index 0000000..6ee952a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/tags/foo/foo/bar
@@ -0,0 +1 @@
+b25fa35b38051e4ae45d4222e795f9df2e43f1d1
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/tags/point_to_blob b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/tags/point_to_blob
new file mode 100755
index 0000000..f874a3f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/tags/point_to_blob
@@ -0,0 +1 @@
+1385f264afb75a56a5bec74243be9b367ba4ca08
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/tags/test b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/tags/test
new file mode 100755
index 0000000..6ee952a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/testrepo/.gitted/refs/tags/test
@@ -0,0 +1 @@
+b25fa35b38051e4ae45d4222e795f9df2e43f1d1
diff --git a/app/server/vendor/rugged-0.23.3/test/fixtures/text_file.md b/app/server/vendor/rugged-0.23.3/test/fixtures/text_file.md
new file mode 100755
index 0000000..7771329
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/fixtures/text_file.md
@@ -0,0 +1,464 @@
+# Rugged
+**libgit2 bindings in Ruby**
+
+Rugged is a library for accessing [libgit2](https://github.com/libgit2/libgit2) in Ruby. It gives you the speed and
+portability of libgit2 with the beauty of the Ruby language.
+
+### libgit2
+
+libgit2 is a pure C implementation of the Git core methods. It's designed to be
+fast and portable. For more information about libgit2,
+[check out libgit2's website](http://libgit2.github.com) or browse the
+[libgit2 organization](https://github.com/libgit2) on GitHub.
+
+## Install
+
+Rugged is a self-contained gem. You can install it by running:
+
+    $ gem install rugged
+
+To load Rugged, you'll usually want to add something like this:
+
+```ruby
+require 'rugged'
+```
+
+## Usage
+
+Rugged gives you access to the many parts of a Git repository. You can read and
+write objects, walk a tree, access the staging area, and lots more. Let's look
+at each area individually.
+
+### Repositories
+
+#### Instantiation
+
+The repository is naturally central to Git. Rugged has a `Repository` class that
+you can instantiate with a path to open an existing repository :
+
+```ruby
+repo = Rugged::Repository.new('path/to/my/repository')
+# => #<Rugged::Repository:2228536260 {path: "path/to/my/repository/.git/"}>
+```
+
+You can create a new repository with `init_at`. Add a second parameter `:bare` to make a bare repository:
+
+```ruby
+Rugged::Repository.init_at('.', :bare)
+```
+
+You can also let Rugged discover the path to the .git directory if you give it a
+subdirectory.
+
+```ruby
+Rugged::Repository.discover("/Users/me/projects/repo/lib/subdir/")
+# => "/Users/me/projects/repo/.git/"
+```
+
+Once your Repository instantiated (in the following examples, as `repo`), you
+can access or modify it.
+
+#### Accessing a Repository
+
+```ruby
+# Does the given SHA1 exist in this repository?
+repo.exists?('07b44cbda23b726e5d54e2ef383495922c024202')
+# => true
+
+# Boolean repository state values:
+repo.bare?
+# => false
+repo.empty?
+# => true
+repo.head_orphan?
+# => false
+repo.head_detached?
+# => false
+
+# Path accessors
+repo.path
+# => "path/to/my/repository/.git/"
+repo.workdir
+# => "path/to/my/repository/"
+
+# The HEAD of the repository.
+ref = repo.head
+# => #<Rugged::Reference:2228467240 {name: "refs/heads/master", target: "07b44cbda23b726e5d54e2ef383495922c024202"}>
+
+# From the returned ref, you can also access the `name` and `target`:
+ref.name
+# => "refs/heads/master"
+ref.target
+# => "07b44cbda23b726e5d54e2ef383495922c024202"
+
+# Reading an object
+object = repo.read('a0ae5566e3c8a3bddffab21022056f0b5e03ef07')
+# => #<Rugged::OdbObject:0x109a64780>
+object.len
+# => 237
+object.data
+# => "tree 76f23f186076fc291742816721ea8c3e95567241\nparent 8e3c5c52b8f29da0adc7e8be8a037cbeaea6de6b\nauthor Vicent Mart\303\255 <tanoku at gmail.com> 1333859005 +0200\ncommitter Vicent Mart\303\255 <tanoku at gmail.com> 1333859005 +0200\n\nAdd `Repository#blob_at`\n"
+object.type
+# => :commit
+```
+
+#### Writing to a Repository
+
+There's a few ways to write to a repository. To write directly from your
+instantiated repository object:
+
+```ruby
+sha = repo.write(content, type)
+```
+
+You can also use the `Commit` object directly to craft a commit; this is a bit
+more high-level, so it may be preferable:
+
+```ruby
+oid = repo.write("This is a blob.", :blob)
+index = Rugged::Index.new
+index.add(:path => "README.md", :oid => oid, :mode => 0100644)
+
+options = {}
+options[:tree] = index.write_tree(repo)
+
+options[:author] = { :email => "testuser at github.com", :name => 'Test Author', :time => Time.now }
+options[:committer] = { :email => "testuser at github.com", :name => 'Test Author', :time => Time.now }
+options[:message] ||= "Making a commit via Rugged!"
+options[:parents] = repo.empty? ? [] : [ repo.head.target ].compact
+options[:update_ref] = 'HEAD'
+
+Rugged::Commit.create(repo, options)
+```
+
+---
+
+### Objects
+
+`Object` is the main object class - it shouldn't be created directly, but all of
+these methods should be useful in their derived classes.
+
+```ruby
+obj = repo.lookup(sha)
+obj.oid  # object sha
+obj.type # One of :commit, :tree, :blob or :tag
+
+robj = obj.read_raw
+str  = robj.data
+int  = robj.len
+```
+
+There are four base object types in Git: **blobs**, **commits**, **tags**, and
+**trees**. Each of these object types have a corresponding class within Rugged.
+
+### Commit Objects
+
+```ruby
+commit = repo.lookup('a0ae5566e3c8a3bddffab21022056f0b5e03ef07')
+# => #<Rugged::Commit:2245304380>
+
+commit.message
+# => "Add `Repository#blob_at`\n"
+
+commit.time
+# => Sat Apr 07 21:23:25 -0700 2012
+
+commit.author
+# => {:email=>"tanoku at gmail.com", :name=>"Vicent Mart\303\255", :time=>Sun Apr 08 04:23:25 UTC 2012}
+
+commit.tree
+# => #<Rugged::Tree:2245269740>
+
+commit.parents
+=> [#<Rugged::Commit:2245264600 {message: "Merge pull request #47 from isaac/remotes\n\nAdd Rugged::Repository#remotes", tree: #<Rugged::Tree:2245264240 {oid: 6a2aee58a41fa007d07aa55565e2231f9b39b4a9}>
+```
+
+You can also write new objects to the database this way:
+
+```ruby
+author = {:email=>"tanoku at gmail.com", :time=>Time.now, :name=>"Vicent Mart\303\255"}
+
+Rugged::Commit.create(r,
+	:author => author,
+	:message => "Hello world\n\n",
+	:committer => author,
+	:parents => ["2cb831a8aea28b2c1b9c63385585b864e4d3bad1"],
+	:tree => some_tree,
+	:update_ref => "HEAD") #=> "f148106ca58764adc93ad4e2d6b1d168422b9796"
+```
+
+### Tag Objects
+
+```ruby
+tag  = repo.lookup(tag_sha)
+
+object = tag.target
+sha    = tag.target.oid
+str    = tag.target_type # :commit, :tag, :blob
+str    = tag.name        # "v1.0"
+str    = tag.message
+person = tag.tagger
+```
+
+### Tree Objects
+
+```ruby
+tree = repo.lookup('779fbb1e17e666832773a9825875300ea736c2da')
+# => #<Rugged::Tree:2245194360>
+
+# number of tree entries
+tree.count
+
+tree[0]           # or...
+tree.first        # or...
+tree.get_entry(0)
+# => {:type=>:blob, :oid=>"99e7edb53db9355f10c6f2dfaa5a183f205d93bf", :filemode=>33188, :name=>".gitignore"}
+```
+
+The tree object is an Enumerable, so you can also do stuff like this:
+
+```ruby
+tree.each { |e| puts e[:oid] }
+tree.sort { |a, b| a[:oid] <=> b[:oid] }.map { |e| e[:name] }.join(':')
+```
+
+And there are some Rugged-specific methods, too:
+
+```ruby
+tree.each_tree { |entry| puts entry[:name] }  # list subdirs
+tree.each_blob { |entry| puts entry[:name] }  # list only files
+```
+
+You can also write trees with the `TreeBuilder`:
+
+```ruby
+oid = repo.write("This is a blob.", :blob)
+builder = Rugged::Tree::Builder.new
+builder << { :type => :blob, :name => "README.md", :oid => oid, :filemode => 0100644 }
+
+options = {}
+options[:tree] = builder.write(repo)
+
+options[:author] = { :email => "testuser at github.com", :name => 'Test Author', :time => Time.now }
+options[:committer] = { :email => "testuser at github.com", :name => 'Test Author', :time => Time.now }
+options[:message] ||= "Making a commit via Rugged!"
+options[:parents] = repo.empty? ? [] : [ repo.head.target ].compact
+options[:update_ref] = 'HEAD'
+
+Rugged::Commit.create(repo, options)
+```
+
+---
+
+### Commit Walker
+
+`Rugged::Walker` is a class designed to help you traverse a set of commits over
+a repository.
+
+You first push head SHAs onto the walker, and then call next to get a list of
+the reachable commit objects one at a time. You can also `hide()` commits if you
+are not interested in anything beneath them (useful in situations like when
+you're running something like `git log master ^origin/master`).
+
+```ruby
+walker = Rugged::Walker.new(repo)
+walker.sorting(Rugged::SORT_TOPO | Rugged::SORT_REVERSE) # optional
+walker.push(hex_sha_interesting)
+walker.hide(hex_sha_uninteresting)
+walker.each { |c| puts c.inspect }
+walker.reset
+```
+
+---
+
+### Index ("staging") area
+
+We can inspect and manipulate the Git Index as well. To work with the index
+inside an existing repository, instantiate it by using the `Repository.index`
+method instead of manually opening the Index by its path.
+
+```ruby
+index = Rugged::Index.new(path)
+
+# Re-read the index file from disk.
+index.reload
+
+# Count up index entries.
+count = index.count
+
+# The collection of index entries.
+index.entries
+
+# Iterating over index entries.
+index.each { |i| puts i.inspect }
+
+# Get a particular entry in the index.
+index[path]
+
+# Unstage.
+index.remove(path)
+
+# Stage. Also updates existing entry if there is one.
+index.add(ientry)
+
+# Stage. Create ientry from file in path, updates the index.
+index.add(path)
+```
+
+---
+
+### Refs
+
+The `Rugged::Reference` class allows you to list, create and delete packed and loose refs.
+
+```ruby
+ref = repo.head # or...
+ref = Rugged::Reference.lookup(repo, "refs/heads/master")
+
+sha = ref.target
+str = ref.type   # :direct
+str = ref.name   # "refs/heads/master"
+```
+
+You can also easily get an array of references:
+
+```ruby
+repo.refs.each do |ref|
+  puts ref.name
+end
+```
+
+Or use a pattern (regex):
+
+```ruby
+repo.refs(/tags/).each do |ref|
+  puts ref.name
+end
+```
+
+It is also easy to create, update, rename or delete a reference:
+
+```ruby
+ref = Rugged::Reference.create(repo, "refs/heads/unit_test", some_commit_sha)
+
+ref.set_target(new_sha)
+
+ref.rename("refs/heads/blead")
+
+ref.delete!
+```
+
+Finally, you can access the reflog for any branch:
+
+```ruby
+ref = Rugged::Reference.lookup(repo, "refs/heads/master")
+entry = ref.log.first
+sha   = entry[:id_old]
+sha   = entry[:id_new]
+str   = entry[:message]
+prsn  = entry[:committer]
+```
+
+---
+
+### Branches
+
+`Rugged::Branch` will help you with all of your branch-related needs.
+
+Iterate over all branches:
+
+```ruby
+Rugged::Branch.each_name(repo).sort
+# => ["master", "origin/HEAD", "origin/master", "origin/packed"]
+
+Rugged::Branch.each_name(repo, :local).sort
+# => ["master"]
+
+Rugged::Branch.each_name(repo, :remote).sort
+# => ["origin/HEAD", "origin/master", "origin/packed"]
+```
+
+Look up branches and get attributes:
+
+```ruby
+branch = Rugged::Branch.lookup(repo, "master")
+branch.name # => 'master'
+branch.canonical_name # => 'refs/heads/master'
+```
+
+Look up the oid for the tip of a branch:
+
+```ruby
+Rugged::Branch.lookup(repo, "master").tip.oid
+# => "36060c58702ed4c2a40832c51758d5344201d89a"
+```
+
+Creation and deletion:
+
+```ruby
+branch = repo.create_branch("test_branch")
+branch.move("new_branch")
+branch.delete!
+```
+
+---
+
+### Config files
+
+It's also easy to read and manipulate the Git config file data with Rugged.
+
+```ruby
+# Read values
+repo.config['core.bare']
+
+# Set values
+repo.config['user.name'] = true
+
+# Delete values
+repo.config.delete('user.name')
+```
+
+---
+
+### General methods
+
+Rugged also includes a general library for handling basic Git operations. One of
+these is converting a raw sha (20 bytes) into a readable hex sha (40
+characters).
+
+```ruby
+Rugged.hex_to_raw('bfde59cdd0dfac1d892814f66a95641abd8a1faf')
+# => "\277\336Y\315\320\337\254\035\211(\024\366j\225d\032\275\212\037\257"
+
+Rugged.raw_to_hex("\277\336Y\315\320\337\254\035\211(\024\366j\225d\032\275\212\037\257")
+=> "bfde59cdd0dfac1d892814f66a95641abd8a1faf"
+```
+
+---
+
+## Contributing
+
+Fork libgit2/rugged on GitHub, make it awesomer (preferably in a branch named
+for the topic), send a pull request.
+
+
+## Development
+
+Simply clone and install:
+
+    $ git clone https://github.com/libgit2/rugged.git
+    $ cd rugged
+    $ bundle install
+    $ rake compile
+    $ rake test
+
+
+## Authors
+
+* Vicent Marti <tanoku at gmail.com>
+* Scott Chacon <schacon at gmail.com>
+
+
+## License
+
+MIT. See LICENSE file.
diff --git a/app/server/vendor/rugged-0.23.3/test/index_test.rb b/app/server/vendor/rugged-0.23.3/test/index_test.rb
new file mode 100755
index 0000000..7a23efd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/index_test.rb
@@ -0,0 +1,422 @@
+require "test_helper"
+require 'base64'
+require 'tempfile'
+require 'fileutils'
+
+class IndexTest < Rugged::TestCase
+  def self.new_index_entry
+      now = Time.now
+      {
+        :path => "new_path",
+        :oid => "d385f264afb75a56a5bec74243be9b367ba4ca08",
+        :mtime => now,
+        :ctime => now,
+        :file_size => 1000,
+        :dev => 234881027,
+        :ino => 88888,
+        :mode => 33188,
+        :uid => 502,
+        :gid => 502,
+        :stage => 3,
+      }
+  end
+
+  def setup
+    path = File.dirname(__FILE__) + '/fixtures/testrepo.git/index'
+    @index = Rugged::Index.new(path)
+  end
+
+  def test_iteration
+    enum = @index.each
+    assert enum.kind_of? Enumerable
+
+    i = 0
+    @index.each { |e| i += 1 }
+    assert_equal @index.count, i
+  end
+
+  def test_index_size
+    assert_equal 2, @index.count
+  end
+
+  def test_empty_index
+    @index.clear
+    assert_equal 0, @index.count
+  end
+
+  def test_remove_entries
+    @index.remove 'new.txt'
+    assert_equal 1, @index.count
+  end
+
+  def test_remove_dir
+    @index.remove_dir 'does-not-exist'
+    assert_equal 2, @index.count
+
+    @index.remove_dir '', 2
+    assert_equal 2, @index.count
+
+    @index.remove_dir ''
+    assert_equal 0, @index.count
+  end
+
+  def test_get_entry_data
+    e = @index[0]
+    assert_equal 'README', e[:path]
+    assert_equal '1385f264afb75a56a5bec74243be9b367ba4ca08', e[:oid]
+    assert_equal 1273360380, e[:mtime].to_i
+    assert_equal 1273360380, e[:ctime].to_i
+    assert_equal 4, e[:file_size]
+    assert_equal 234881026, e[:dev]
+    assert_equal 6674088, e[:ino]
+    assert_equal 33188, e[:mode]
+    assert_equal 501, e[:uid]
+    assert_equal 0, e[:gid]
+    assert_equal false, e[:valid]
+    assert_equal 0, e[:stage]
+
+    e = @index[1]
+    assert_equal 'new.txt', e[:path]
+    assert_equal 'fa49b077972391ad58037050f2a75f74e3671e92', e[:oid]
+  end
+
+  def test_iterate_entries
+    itr_test = @index.sort { |a, b| a[:oid] <=> b[:oid] }.map { |e| e[:path] }.join(':')
+    assert_equal "README:new.txt", itr_test
+  end
+
+  def test_update_entries
+    now = Time.at Time.now.to_i
+    e = @index[0]
+
+    e[:oid] = "12ea3153a78002a988bb92f4123e7e831fd1138a"
+    e[:mtime] = now
+    e[:ctime] = now
+    e[:file_size] = 1000
+    e[:dev] = 234881027
+    e[:ino] = 88888
+    e[:mode] = 33188
+    e[:uid] = 502
+    e[:gid] = 502
+    e[:stage] = 3
+
+    @index.add(e)
+    new_e = @index.get e[:path], 3
+
+    assert_equal e, new_e
+  end
+
+  def test_add_new_entries
+    e = IndexTest.new_index_entry
+    @index << e
+    assert_equal 3, @index.count
+    itr_test = @index.sort { |a, b| a[:oid] <=> b[:oid] }.map { |x| x[:path] }.join(':')
+    assert_equal "README:new_path:new.txt", itr_test
+  end
+end
+
+class IndexWriteTest < Rugged::TestCase
+  def setup
+    path = File.dirname(__FILE__) + '/fixtures/testrepo.git/index'
+
+    @tmpfile = Tempfile.new('index', Dir.tmpdir, encoding: "binary")
+    @tmpfile.write(File.binread(path))
+    @tmpfile.close
+
+    @index = Rugged::Index.new(@tmpfile.path)
+  end
+
+  def teardown
+    @tmpfile.unlink
+  end
+
+  def test_raises_when_writing_invalid_entries
+    assert_raises TypeError do
+      @index.add(21)
+    end
+  end
+
+  def test_can_write_index
+    e = IndexTest.new_index_entry
+    @index << e
+
+    e[:path] = "else.txt"
+    @index << e
+
+    @index.write
+
+    index2 = Rugged::Index.new(@tmpfile.path)
+
+    itr_test = index2.sort { |a, b| a[:oid] <=> b[:oid] }.map { |x| x[:path] }.join(':')
+    assert_equal "README:else.txt:new_path:new.txt", itr_test
+    assert_equal 4, index2.count
+  end
+end
+
+class IndexWorkdirTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.empty
+    @index = @repo.index
+  end
+
+  def test_adding_a_path
+    File.open(File.join(@repo.workdir, 'test.txt'), 'w') do |f|
+      f.puts "test content"
+    end
+    @index.add('test.txt')
+    @index.write
+
+    index2 = Rugged::Index.new(File.join(@repo.workdir, '.git', 'index'))
+    assert_equal index2[0][:path], 'test.txt'
+  end
+
+  def test_reloading_index
+    File.open(File.join(@repo.workdir, 'test.txt'), 'w') do |f|
+      f.puts "test content"
+    end
+    @index.add('test.txt')
+    @index.write
+
+    rindex = Rugged::Index.new(File.join(@repo.workdir, '.git', 'index'))
+    e = rindex['test.txt']
+    assert_equal 0, e[:stage]
+
+    rindex << IndexTest.new_index_entry
+    rindex.write
+
+    assert_equal 1, @index.count
+    @index.reload
+    assert_equal 2, @index.count
+
+    e = @index.get 'new_path', 3
+    assert_equal e[:mode], 33188
+  end
+end
+
+class IndexConflictsTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("mergedrepo")
+  end
+
+  def test_conflicts?
+    assert @repo.index.conflicts?
+  end
+
+  def test_conflicts
+    conflicts = @repo.index.conflicts
+
+    assert_equal 2, conflicts.size
+
+    assert_equal "conflicts-one.txt", conflicts[0][:ancestor][:path]
+    assert_equal "conflicts-one.txt", conflicts[0][:ours][:path]
+    assert_equal "conflicts-one.txt", conflicts[0][:theirs][:path]
+    assert_equal 1, conflicts[0][:ancestor][:stage]
+    assert_equal 2, conflicts[0][:ours][:stage]
+    assert_equal 3, conflicts[0][:theirs][:stage]
+
+    assert_equal "conflicts-two.txt", conflicts[1][:ancestor][:path]
+    assert_equal "conflicts-two.txt", conflicts[1][:ours][:path]
+    assert_equal "conflicts-two.txt", conflicts[1][:theirs][:path]
+    assert_equal 1, conflicts[1][:ancestor][:stage]
+    assert_equal 2, conflicts[1][:ours][:stage]
+    assert_equal 3, conflicts[1][:theirs][:stage]
+  end
+
+  def test_conflict_get
+    conflict = @repo.index.conflict_get("conflicts-one.txt")
+
+    assert_equal "conflicts-one.txt", conflict[:ancestor][:path]
+    assert_equal "conflicts-one.txt", conflict[:ours][:path]
+    assert_equal "conflicts-one.txt", conflict[:theirs][:path]
+    assert_equal 1, conflict[:ancestor][:stage]
+    assert_equal 2, conflict[:ours][:stage]
+    assert_equal 3, conflict[:theirs][:stage]
+
+    refute @repo.index.conflict_get("conflict-does-not-exists.txt")
+  end
+
+  def test_conflict_remove
+    @repo.index.conflict_remove("conflicts-one.txt")
+    assert_equal @repo.index.conflicts.size, 1
+
+    @repo.index.conflict_remove("conflicts-two.txt")
+    assert_equal @repo.index.conflicts.size, 0
+
+    refute @repo.index.conflicts?
+  end
+
+  def test_conflict_add
+    conflict = @repo.index.conflict_get("conflicts-one.txt")
+
+    conflict[:ancestor][:path] = conflict[:ours][:path] = conflict[:theirs][:path] = "new-conflict.txt"
+    @repo.index.conflict_add(conflict)
+
+    assert_equal @repo.index.conflicts.size, 3
+
+    conflict[:ancestor] = nil
+    conflict[:ours][:path] = conflict[:theirs][:path] = "another-new-conflict.txt"
+
+    @repo.index.conflict_add(conflict)
+
+    assert_equal @repo.index.conflicts.size, 4
+  end
+
+  def test_conflict_cleanup
+    @repo.index.conflict_cleanup
+
+    assert_equal @repo.index.conflicts.size, 0
+    refute @repo.index.conflicts?
+  end
+end
+
+class IndexMergeFileTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("mergedrepo")
+  end
+
+  def test_merge_file
+    merge_file_result = @repo.index.merge_file("conflicts-one.txt")
+
+    assert !merge_file_result[:automergeable]
+    assert_equal merge_file_result[:path], "conflicts-one.txt"
+    assert_equal merge_file_result[:data], "<<<<<<< conflicts-one.txt\nThis is most certainly a conflict!\n=======\nThis is a conflict!!!\n>>>>>>> conflicts-one.txt\n"
+  end
+
+end
+
+class IndexRepositoryTest < Rugged::TestCase
+  def setup
+    @source_repo = FixtureRepo.from_rugged("testrepo.git")
+    @repo = FixtureRepo.clone(@source_repo)
+    @path = @repo.workdir
+  end
+
+  def test_idempotent_read_write
+    head_sha = @repo.references['HEAD'].resolve.target_id
+    tree = @repo.lookup(head_sha).tree
+    index = @repo.index
+    index.read_tree(tree)
+
+    index_tree_sha = index.write_tree
+    index_tree = @repo.lookup(index_tree_sha)
+    assert_equal tree.oid, index_tree.oid
+  end
+
+  def test_build_tree_from_index
+    head_sha = @repo.references['refs/remotes/origin/packed'].resolve.target_id
+    tree = @repo.lookup(head_sha).tree
+
+    index = @repo.index
+    index.read_tree(tree)
+    index.remove('second.txt')
+
+    new_tree_sha = index.write_tree
+    assert head_sha != new_tree_sha
+    assert_nil @repo.lookup(new_tree_sha)['second.txt']
+  end
+
+  def test_read_tree_with_not_a_tree
+    head_sha = @repo.references['refs/remotes/origin/packed'].resolve.target_id
+    commit = @repo.lookup(head_sha)
+
+    index = @repo.index
+    assert_raises TypeError do
+      index.read_tree(commit)
+    end
+  end
+end
+
+class IndexAddAllTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.empty
+
+    Dir.chdir(@repo.workdir) do
+      File.open("file.foo", "w") { |f| f.write "a file" }
+      File.open("file.bar", "w") { |f| f.write "another file" }
+      File.open("file.zzz", "w") { |f| f.write "yet another one" }
+      File.open("other.zzz", "w") { |f| f.write "yet another one" }
+      File.open("more.zzz", "w") { |f| f.write "yet another one" }
+      File.open(".gitignore", "w") { |f| f.write "*.foo\n" }
+    end
+  end
+
+  def test_add_all_lifecycle
+    Dir.chdir(@repo.workdir) do
+      @repo.index.add_all("file.*")
+
+      assert @repo.index["file.bar"]
+      assert @repo.index["file.zzz"]
+      refute @repo.index["file.foo"]
+      refute @repo.index["other.zzz"]
+      refute @repo.index["more.zzz"]
+
+      @repo.index.add_all("*.zzz")
+
+      assert @repo.index["file.bar"]
+      assert @repo.index["file.zzz"]
+      assert @repo.index["other.zzz"]
+      assert @repo.index["more.zzz"]
+      refute @repo.index["file.foo"]
+    end
+  end
+
+  def test_add_all_dry_run
+    Dir.chdir(@repo.workdir) do
+      yielded = []
+      @repo.index.add_all do |path, pathspec|
+        yielded << path
+        false
+      end
+
+      assert_equal [".gitignore", "file.bar", "file.zzz", "more.zzz", "other.zzz"], yielded
+
+      yielded.each do |path|
+        refute @repo.index[path]
+      end
+
+      yielded = []
+      @repo.index.add_all(["file.*", "*.zzz"]) do |path, pathspec|
+        yielded << [path, pathspec]
+        false
+      end
+
+      assert_equal [
+        ["file.bar", "file.*"],
+        ["file.zzz", "file.*"],
+        ["more.zzz", "*.zzz"],
+        ["other.zzz", "*.zzz"]
+      ], yielded
+    end
+  end
+
+  def test_update_all
+    Dir.chdir(@repo.workdir) do
+      @repo.index.add_all("file.*")
+
+      File.open("file.bar", "w") { |f| f.write "new content for file" }
+      @repo.index.update_all("file.*")
+
+      assert @repo.index["file.bar"]
+      assert_equal "new content for file", @repo.lookup(@repo.index["file.bar"][:oid]).content
+
+      refute @repo.index["other.zzz"], "#update_all should only update files in the index"
+      refute @repo.index["more.zzz"], "#update_all should only update files in the index"
+
+      File.unlink("file.bar")
+      @repo.index.update_all
+
+      refute @repo.index["file.bar"], "#update_all should remove index entries that are removed from the workdir"
+    end
+  end
+
+  def test_remove_all
+    Dir.chdir(@repo.workdir) do
+      @repo.index.add_all("file.*")
+      @repo.index.remove_all("*.zzz")
+
+      assert @repo.index["file.bar"]
+      refute @repo.index["file.zzz"]
+    end
+  end
+
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/lib_test.rb b/app/server/vendor/rugged-0.23.3/test/lib_test.rb
new file mode 100755
index 0000000..f028d08
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/lib_test.rb
@@ -0,0 +1,138 @@
+require "test_helper"
+require 'base64'
+
+class RuggedTest < Rugged::TestCase
+
+  @@oids = [
+    'd8786bfc974aaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
+    'd8786bfc974bbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
+    'd8786bfc974ccccccccccccccccccccccccccccc',
+    '68d041ee999cb07c6496fbdd4f384095de6ca9e1'
+  ]
+
+  def test_libgit2_version
+    version = Rugged::libgit2_version
+    assert_equal version.length, 3
+    version.each do |i|
+      assert i.is_a? Fixnum
+    end
+  end
+
+  def test_options
+    Rugged::Settings['mwindow_size'] = 8 * 1024 * 1024
+    Rugged::Settings['mwindow_mapped_limit'] = 8 * 1024 * 1024
+
+    assert_equal 8 * 1024 * 1024, Rugged::Settings['mwindow_size']
+
+    assert_raises(TypeError) { Rugged::Settings['mwindow_mapped_limit'] = 'asdf' }
+    assert_raises(TypeError) { Rugged::Settings['mwindow_size'] = nil }
+  end
+
+  def test_search_path
+    paths = [['search_path_global', '/tmp/global'],
+             ['search_path_xdg', '/tmp/xdg'],
+             ['search_path_system', '/tmp/system']]
+
+    paths.each do |opt, path|
+      Rugged::Settings[opt] = path
+      assert_equal(path, Rugged::Settings[opt])
+    end
+  end
+
+  def test_features
+    features = Rugged.features
+    assert features.is_a? Array
+  end
+
+  def test_hex_to_raw_oid
+    raw = Rugged::hex_to_raw("ce08fe4884650f067bd5703b6a59a8b3b3c99a09")
+    b64raw = Base64.encode64(raw).strip
+    assert_equal "zgj+SIRlDwZ71XA7almos7PJmgk=", b64raw
+
+    hex = "ce08fe4884650f067bd5703b6a59a8b3b3c99a09"
+    raw1 = Rugged::hex_to_raw(hex)
+    raw2 = [hex].pack("H*")
+    assert_equal raw1, raw2
+  end
+
+  def test_raw_to_hex
+    raw = Base64.decode64("FqASNFZ4mrze9Ld1ITwjqL109eA=")
+    hex = Rugged::raw_to_hex(raw)
+    assert_equal "16a0123456789abcdef4b775213c23a8bd74f5e0", hex
+
+    raw = Rugged::hex_to_raw("ce08fe4884650f067bd5703b6a59a8b3b3c99a09")
+    hex1 = Rugged::raw_to_hex(raw)
+    hex2 = raw.unpack("H*")[0]
+    assert_equal hex1, hex2
+  end
+
+  def test_raw_to_hex_with_nulls
+    raw = Rugged::hex_to_raw("702f00394564b24052511cb69961164828bf5494")
+    hex1 = Rugged::raw_to_hex(raw)
+    hex2 = raw.unpack("H*")[0]
+    assert_equal hex1, hex2
+  end
+
+  def test_hex_to_raw_with_invalid_character_raises_invalid_error
+    assert_raises Rugged::InvalidError do
+      Rugged::hex_to_raw("\x16\xA0\x124VWATx\x9A\xBC\xDE\xF4") # invalid bytes
+    end
+  end
+
+  def test_raw_to_hex_with_invalid_size_raises_type_error
+    assert_raises TypeError do
+      Rugged::raw_to_hex("702f00394564b24052511cb69961164828bf5") # invalid OID size
+    end
+  end
+
+  def test_minimize_oid_with_no_block
+    assert_equal 12, Rugged::minimize_oid(@@oids)
+  end
+
+  def test_minimize_oid_with_min_length
+    assert_equal 20, Rugged::minimize_oid(@@oids, 20)
+  end
+
+  def test_minimize_oid_with_block
+    minimized_oids = []
+    Rugged::minimize_oid(@@oids) { |oid| minimized_oids << oid }
+    expected_oids = [
+      "d8786bfc974a",
+      "d8786bfc974b",
+      "d8786bfc974c",
+      "68d041ee999c"
+    ]
+
+    assert_equal expected_oids, minimized_oids
+  end
+
+  def test_rugged_lib_constants
+    assert_equal 0, Rugged::SORT_NONE
+    assert_equal 1, Rugged::SORT_TOPO
+    assert_equal 2, Rugged::SORT_DATE
+    assert_equal 4, Rugged::SORT_REVERSE
+  end
+
+  def test_prettify_commit_messages
+    message = <<-MESSAGE
+Testing this whole prettify business
+
+with newlines and stuff
+# take out this line haha
+# and this one
+
+not this one
+MESSAGE
+
+    clean_message = <<-MESSAGE
+Testing this whole prettify business
+
+with newlines and stuff
+
+not this one
+MESSAGE
+
+    assert_equal clean_message, Rugged::prettify_message(message, true)
+  end
+end
+
diff --git a/app/server/vendor/rugged-0.23.3/test/merge_test.rb b/app/server/vendor/rugged-0.23.3/test/merge_test.rb
new file mode 100755
index 0000000..141ce62
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/merge_test.rb
@@ -0,0 +1,52 @@
+require "test_helper"
+
+class TrivialMergeTest < Rugged::TestCase
+  def test_2alt
+    repo = FixtureRepo.from_libgit2("merge-resolve")
+
+    ours = repo.rev_parse("trivial-2alt")
+    theirs = repo.rev_parse("trivial-2alt-branch")
+
+    analysis = repo.merge_analysis(theirs)
+    assert_equal [:normal], analysis
+
+    base = repo.rev_parse(repo.merge_base(ours, theirs))
+
+    index = ours.tree.merge(theirs.tree, base.tree)
+
+    refute index.conflicts?
+  end
+
+  def test_4
+    repo = FixtureRepo.from_libgit2("merge-resolve")
+
+    ours = repo.rev_parse("trivial-4")
+    theirs = repo.rev_parse("trivial-4-branch")
+    base = repo.rev_parse(repo.merge_base(ours, theirs))
+
+    index = ours.tree.merge(theirs.tree, base.tree)
+
+    assert index.conflicts?
+    assert 2, index.count { |entry| entry[:stage] > 0 }
+    assert index["new-and-different.txt", 2]
+    assert index["new-and-different.txt", 3]
+  end
+
+  def test_analysis
+    repo = FixtureRepo.from_libgit2("merge-resolve")
+
+    analysis = repo.merge_analysis("HEAD")
+    assert_equal [:up_to_date], analysis
+
+    analysis = repo.merge_analysis(repo.rev_parse("HEAD~"))
+    assert_equal [:up_to_date], analysis
+
+    analysis = repo.merge_analysis("ff_branch")
+    assert_equal [:normal, :fastforward], analysis
+
+    analysis = repo.merge_analysis("branch")
+    assert_equal [:normal], analysis
+
+  end
+
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/note_test.rb b/app/server/vendor/rugged-0.23.3/test/note_test.rb
new file mode 100755
index 0000000..e4a245c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/note_test.rb
@@ -0,0 +1,211 @@
+require 'test_helper'
+
+class NoteTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_rugged("testrepo.git")
+  end
+
+  def test_read_note_for_object
+    oid = "36060c58702ed4c2a40832c51758d5344201d89a"
+    obj = @repo.lookup(oid)
+    notes = obj.notes
+    assert_equal "note text\n", notes[:message]
+    assert_equal "94eca2de348d5f672faf56b0decafa5937e3235e", notes[:oid]
+  end
+
+  def test_read_note_for_object_from_ref
+    oid = "36060c58702ed4c2a40832c51758d5344201d89a"
+    obj = @repo.lookup(oid)
+    notes = obj.notes('refs/notes/commits')
+    assert_equal "note text\n", notes[:message]
+    assert_equal "94eca2de348d5f672faf56b0decafa5937e3235e", notes[:oid]
+  end
+
+  def test_object_without_note
+    oid = "8496071c1b46c854b31185ea97743be6a8774479"
+    obj = @repo.lookup(oid)
+    assert_nil obj.notes
+  end
+
+  def test_nil_ref_lookup
+    oid = "36060c58702ed4c2a40832c51758d5344201d89a"
+    obj = @repo.lookup(oid)
+    assert_nil obj.notes('refs/notes/missing')
+  end
+
+  def test_iterate_over_notes
+    @repo.each_note('refs/notes/commits') do |note_blob, annotated_object|
+      assert_equal "note text\n", note_blob.content
+      assert_equal "36060c58702ed4c2a40832c51758d5344201d89a", annotated_object.oid
+    end
+  end
+
+  def test_each_note_enumerable
+    enum = @repo.each_note('refs/notes/commits')
+    assert enum.kind_of? Enumerable
+  end
+
+  def test_default_ref
+    assert_equal 'refs/notes/commits', @repo.default_notes_ref
+  end
+end
+
+class NoteWriteTest < Rugged::TestCase
+  def setup
+    @source_repo = FixtureRepo.from_rugged("testrepo.git")
+    @repo = FixtureRepo.clone(@source_repo)
+  end
+
+  def test_create_note
+    person = {:name => 'Scott', :email => 'schacon at gmail.com', :time => Time.now }
+
+    oid = "8496071c1b46c854b31185ea97743be6a8774479"
+    message ="This is the note message\n\nThis note is created from Rugged"
+    obj = @repo.lookup(oid)
+
+    note_oid = obj.create_note(
+      :message => message,
+      :committer => person,
+      :author => person,
+      :ref => 'refs/notes/test'
+    )
+
+    assert_equal '38c3a690c474d8dcdb13088205a464a60312eec4', note_oid
+    # note is actually a blob
+    blob = @repo.lookup(note_oid)
+    assert_equal blob.oid, note_oid
+    assert_equal blob.content, message
+    assert_equal blob.type, :blob
+
+    note = obj.notes('refs/notes/test')
+    assert_equal note[:oid], note_oid
+    assert_equal note[:message], message
+  end
+
+  def test_create_note_without_signature
+    name = 'Rugged User'
+    email = 'rugged at example.com'
+    @repo.config['user.name'] = name
+    @repo.config['user.email'] = email
+
+    oid = "8496071c1b46c854b31185ea97743be6a8774479"
+    message ="This is the note message\n\nThis note is created from Rugged"
+    obj = @repo.lookup(oid)
+
+    note_oid = obj.create_note(
+      :message => message,
+      :ref => 'refs/notes/test'
+    )
+    assert_equal '38c3a690c474d8dcdb13088205a464a60312eec4', note_oid
+    note_commit = @repo.references['refs/notes/test'].target
+    assert_equal name, note_commit.committer[:name]
+    assert_equal email, note_commit.committer[:email]
+    assert_equal name, note_commit.author[:name]
+    assert_equal email, note_commit.author[:email]
+  end
+
+  def test_create_note_on_object_with_notes_raises
+    person = {:name => 'Scott', :email => 'schacon at gmail.com', :time => Time.now }
+    oid = "8496071c1b46c854b31185ea97743be6a8774479"
+    message ="This is the note message\n\nThis note is created from Rugged"
+    obj = @repo.lookup(oid)
+    obj.create_note(
+      :message => message,
+      :committer => person,
+      :author => person,
+      :ref => 'refs/notes/test'
+    )
+
+    assert_raises Rugged::RepositoryError do
+      obj.create_note(
+        :message => message,
+        :committer => person,
+        :author => person,
+        :ref => 'refs/notes/test'
+      )
+    end
+  end
+
+  def test_overwrite_object_note
+    person = {:name => 'Scott', :email => 'schacon at gmail.com', :time => Time.now }
+    oid = "8496071c1b46c854b31185ea97743be6a8774479"
+    message ="This is the note message\n\nThis note is created from Rugged"
+    obj = @repo.lookup(oid)
+    obj.create_note(
+      :message => message,
+      :committer => person,
+      :author => person,
+      :ref => 'refs/notes/test'
+    )
+
+    obj.create_note(
+      :message => 'new message',
+      :committer => person,
+      :author => person,
+      :ref => 'refs/notes/test',
+      :force => true
+    )
+
+    note = obj.notes('refs/notes/test')
+    assert_equal note[:message], 'new message'
+  end
+
+  def test_remove_note
+    oid = "36060c58702ed4c2a40832c51758d5344201d89a"
+    person = {:name => 'Scott', :email => 'schacon at gmail.com', :time => Time.now }
+    message ="This is the note message\n\nThis note is created from Rugged"
+    obj = @repo.lookup(oid)
+
+    obj.create_note(
+      :message => message,
+      :committer => person,
+      :author => person,
+      :ref => 'refs/notes/test'
+    )
+
+    assert obj.remove_note(
+      :committer => person,
+      :author => person,
+      :ref => 'refs/notes/test'
+    )
+
+    assert_nil obj.notes('refs/notes/test')
+  end
+
+  def test_remote_without_signature
+    name = 'Rugged User'
+    email = 'rugged at example.com'
+    @repo.config['user.name'] = name
+    @repo.config['user.email'] = email
+    oid = "36060c58702ed4c2a40832c51758d5344201d89a"
+
+    message ="This is the note message\n\nThis note is created from Rugged"
+    obj = @repo.lookup(oid)
+
+    obj.create_note(
+      :message => message,
+      :ref => 'refs/notes/test'
+    )
+
+    obj.create_note(
+      :message => message,
+    )
+
+    assert obj.remove_note(:ref => 'refs/notes/test')
+    assert obj.remove_note
+
+    assert_nil obj.notes('refs/notes/test')
+    assert_nil obj.notes
+  end
+
+  def test_remove_missing_note
+    person = {:name => 'Scott', :email => 'schacon at gmail.com', :time => Time.now }
+    oid = "36060c58702ed4c2a40832c51758d5344201d89a"
+    obj = @repo.lookup(oid)
+    refute obj.remove_note(
+      :committer => person,
+      :author => person,
+      :ref => 'refs/notes/test'
+    )
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/object_test.rb b/app/server/vendor/rugged-0.23.3/test/object_test.rb
new file mode 100755
index 0000000..a424d54
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/object_test.rb
@@ -0,0 +1,73 @@
+require "test_helper"
+require 'base64'
+
+class ObjectTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_rugged("testrepo.git")
+  end
+
+  def test_lookup_can_lookup_any_object_type
+    blob = Rugged::Object.lookup(@repo, "fa49b077972391ad58037050f2a75f74e3671e92")
+    assert_instance_of Rugged::Blob, blob
+
+    commit = Rugged::Object.lookup(@repo, "8496071c1b46c854b31185ea97743be6a8774479")
+    assert_instance_of Rugged::Commit, commit
+
+    tag = Rugged::Object.lookup(@repo, "0c37a5391bbff43c37f0d0371823a5509eed5b1d")
+    assert_instance_of Rugged::Tag::Annotation, tag
+
+    tree = Rugged::Object.lookup(@repo, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")
+    assert_instance_of Rugged::Tree, tree
+
+    subclass = Class.new(Rugged::Object)
+
+    blob = subclass.lookup(@repo, "fa49b077972391ad58037050f2a75f74e3671e92")
+    assert_instance_of Rugged::Blob, blob
+
+    commit = subclass.lookup(@repo, "8496071c1b46c854b31185ea97743be6a8774479")
+    assert_instance_of Rugged::Commit, commit
+
+    tag = subclass.lookup(@repo, "0c37a5391bbff43c37f0d0371823a5509eed5b1d")
+    assert_instance_of Rugged::Tag::Annotation, tag
+
+    tree = subclass.lookup(@repo, "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b")
+    assert_instance_of Rugged::Tree, tree
+  end
+
+  def test_fail_to_lookup_inexistant_object
+    assert_raises Rugged::OdbError do
+      @repo.lookup("a496071c1b46c854b31185ea97743be6a8774479")
+    end
+  end
+
+  def test_lookup_object
+    obj = @repo.lookup("8496071c1b46c854b31185ea97743be6a8774479")
+    assert_equal :commit, obj.type
+    assert_equal '8496071c1b46c854b31185ea97743be6a8774479', obj.oid
+  end
+
+  def test_objects_are_the_same
+    obj = @repo.lookup("8496071c1b46c854b31185ea97743be6a8774479")
+    obj2 = @repo.lookup("8496071c1b46c854b31185ea97743be6a8774479")
+    assert_equal obj, obj2
+  end
+
+  def test_read_raw_data
+    obj = @repo.lookup("8496071c1b46c854b31185ea97743be6a8774479")
+    assert obj.read_raw
+  end
+
+  def test_lookup_by_rev
+    obj = @repo.rev_parse("v1.0")
+    assert "0c37a5391bbff43c37f0d0371823a5509eed5b1d", obj.oid
+    obj = @repo.rev_parse("v1.0^1")
+    assert "8496071c1b46c854b31185ea97743be6a8774479", obj.oid
+  end
+
+  def test_lookup_oid_by_rev
+    oid = @repo.rev_parse_oid("v1.0")
+    assert "0c37a5391bbff43c37f0d0371823a5509eed5b1d", oid
+    @repo.rev_parse_oid("v1.0^1")
+    assert "8496071c1b46c854b31185ea97743be6a8774479", oid
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/online/clone_test.rb b/app/server/vendor/rugged-0.23.3/test/online/clone_test.rb
new file mode 100755
index 0000000..51d8768
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/online/clone_test.rb
@@ -0,0 +1,66 @@
+require 'test_helper'
+
+class OnlineCloneTest < Rugged::OnlineTestCase
+  if git_creds?
+    def test_clone_over_git
+      Dir.mktmpdir do |dir|
+        repo = Rugged::Repository.clone_at(ENV['GITTEST_REMOTE_GIT_URL'], dir)
+
+        assert_instance_of Rugged::Repository, repo
+      end
+    end
+  end
+
+  if Rugged.features.include?(:ssh) && ssh_creds?
+    def test_clone_over_ssh_with_credentials
+      Dir.mktmpdir do |dir|
+        repo = Rugged::Repository.clone_at(ENV['GITTEST_REMOTE_SSH_URL'], dir, {
+          credentials: ssh_key_credential
+        })
+
+        assert_instance_of Rugged::Repository, repo
+      end
+    end
+
+    def test_clone_over_ssh_with_credentials_from_agent
+      Dir.mktmpdir do |dir|
+        repo = Rugged::Repository.clone_at(ENV['GITTEST_REMOTE_SSH_URL'], dir, {
+          credentials: ssh_key_credential_from_agent
+        })
+
+        assert_instance_of Rugged::Repository, repo
+      end
+    end
+
+    def test_clone_over_ssh_with_credentials_callback
+      Dir.mktmpdir do |dir|
+        repo = Rugged::Repository.clone_at(ENV['GITTEST_REMOTE_SSH_URL'], dir, {
+          credentials: lambda { |url, username, allowed_types|
+            return ssh_key_credential
+          }
+        })
+
+        assert_instance_of Rugged::Repository, repo
+      end
+    end
+
+    def test_clone_callback_args_with_username
+      Dir.mktmpdir do |dir|
+        url, username, allowed_types = nil, nil, nil
+
+        assert_raises Rugged::SshError do
+          Rugged::Repository.clone_at("git at github.com:libgit2/TestGitRepository", dir, {
+            credentials: lambda { |*args|
+              url, username, allowed_types = *args
+              return nil
+            }
+          })
+        end
+
+        assert_equal "git at github.com:libgit2/TestGitRepository", url
+        assert_equal "git", username
+        assert_equal [:ssh_key].sort, allowed_types.sort
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/online/fetch_test.rb b/app/server/vendor/rugged-0.23.3/test/online/fetch_test.rb
new file mode 100755
index 0000000..f6796bb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/online/fetch_test.rb
@@ -0,0 +1,60 @@
+require 'test_helper'
+
+class OnlineFetchTest < Rugged::OnlineTestCase
+  def setup
+    @repo = FixtureRepo.empty
+  end
+
+  if git_creds?
+    def test_fetch_over_git
+      @repo.remotes.create("origin", ENV['GITTEST_REMOTE_GIT_URL'])
+
+      @repo.fetch("origin")
+    end
+  end
+
+  if Rugged.features.include?(:https)
+    def test_fetch_over_https
+      @repo.remotes.create("origin", "https://github.com/libgit2/TestGitRepository.git")
+
+      @repo.fetch("origin")
+
+      assert_equal [
+        "refs/remotes/origin/first-merge",
+        "refs/remotes/origin/master",
+        "refs/remotes/origin/no-parent",
+        "refs/tags/annotated_tag",
+        "refs/tags/blob",
+        "refs/tags/commit_tree"
+      ], @repo.refs.map(&:name).sort
+    end
+  end
+
+  if Rugged.features.include?(:ssh) && ssh_creds?
+    def test_fetch_over_ssh_with_credentials
+      @repo.remotes.create("origin", ENV['GITTEST_REMOTE_SSH_URL'])
+
+      @repo.fetch("origin", {
+        credentials: ssh_key_credential
+      })
+    end
+
+    def test_fetch_over_ssh_with_credentials_from_agent
+      @repo.remotes.create("origin", ENV['GITTEST_REMOTE_SSH_URL'])
+
+      @repo.fetch("origin", {
+        credentials: ssh_key_credential_from_agent
+      })
+    end
+
+    def test_fetch_over_ssh_with_credentials_callback
+      @repo.remotes.create("origin", ENV['GITTEST_REMOTE_SSH_URL'])
+
+      @repo.fetch("origin", {
+        credentials: lambda { |url, username, allowed_types|
+          return ssh_key_credential
+        }
+      })
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/online/ls_test.rb b/app/server/vendor/rugged-0.23.3/test/online/ls_test.rb
new file mode 100755
index 0000000..dffd4cf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/online/ls_test.rb
@@ -0,0 +1,47 @@
+require 'test_helper'
+
+class OnlineLsTest < Rugged::OnlineTestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("push_src")
+  end
+
+  if Rugged.features.include?(:https)
+    def test_ls_over_https
+      remote = @repo.remotes.create("origin", "https://github.com/libgit2/TestGitRepository.git")
+
+      assert_equal [
+        { :local? => false, :oid => "49322bb17d3acc9146f98c97d078513228bbf3c0", :loid => nil, :name => "HEAD" },
+        { :local? => false, :oid => "0966a434eb1a025db6b71485ab63a3bfbea520b6", :loid => nil, :name => "refs/heads/first-merge" },
+        { :local? => false, :oid => "49322bb17d3acc9146f98c97d078513228bbf3c0", :loid => nil, :name => "refs/heads/master" },
+        { :local? => false, :oid => "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1", :loid => nil, :name => "refs/heads/no-parent" },
+        { :local? => false, :oid => "d96c4e80345534eccee5ac7b07fc7603b56124cb", :loid => nil, :name => "refs/tags/annotated_tag" },
+        { :local? => false, :oid => "c070ad8c08840c8116da865b2d65593a6bb9cd2a", :loid => nil, :name => "refs/tags/annotated_tag^{}" },
+        { :local? => false, :oid => "55a1a760df4b86a02094a904dfa511deb5655905", :loid => nil, :name => "refs/tags/blob" },
+        { :local? => false, :oid => "8f50ba15d49353813cc6e20298002c0d17b0a9ee", :loid => nil, :name => "refs/tags/commit_tree" },
+        { :local? => false, :oid => "6e0c7bdb9b4ed93212491ee778ca1c65047cab4e", :loid => nil, :name => "refs/tags/nearly-dangling"}
+      ], remote.ls.to_a
+    end
+  end
+
+  if git_creds?
+    def test_ls_over_git
+      remote = @repo.remotes.create("origin", ENV['GITTEST_REMOTE_GIT_URL'])
+      remote.push(["refs/heads/b1:refs/heads/b1"])
+
+      assert_equal [
+        { :local? => false, :oid => "a78705c3b2725f931d3ee05348d83cc26700f247", :loid => nil, :name => "refs/heads/b1" }
+      ], remote.ls.to_a
+    end
+  end
+
+  if Rugged.features.include?(:ssh) && ssh_creds?
+    def test_ls_over_ssh_with_credentials
+      remote = @repo.remotes.create("origin", ENV['GITTEST_REMOTE_SSH_URL'])
+      remote.push(["refs/heads/b1:refs/heads/b1"], credentials: ssh_key_credential)
+
+      assert_equal [
+        { :local? => false, :oid => "a78705c3b2725f931d3ee05348d83cc26700f247", :loid => nil, :name => "refs/heads/b1" }
+      ], remote.ls(credentials: ssh_key_credential).to_a
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/online/push_test.rb b/app/server/vendor/rugged-0.23.3/test/online/push_test.rb
new file mode 100755
index 0000000..541beaa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/online/push_test.rb
@@ -0,0 +1,57 @@
+require 'test_helper'
+
+class OnlineGitPushTest < Rugged::OnlineTestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("push_src")
+    @remote = @repo.remotes.create("test", ENV['GITTEST_REMOTE_GIT_URL'])
+    @target_repo = Rugged::Repository.new(ENV['GITTEST_REMOTE_REPO_PATH'])
+  end
+
+  if git_creds?
+    def test_push_branches
+      @remote.push([
+        "refs/heads/b1:refs/heads/b1",
+        "refs/heads/b2:refs/heads/b2",
+        "refs/heads/b3:refs/heads/b3",
+        "refs/heads/b4:refs/heads/b4",
+        "refs/heads/b5:refs/heads/b5"
+      ])
+
+      assert_equal @repo.references["refs/heads/b1"].target_id, @target_repo.references["refs/heads/b1"].target_id
+      assert_equal @repo.references["refs/heads/b2"].target_id, @target_repo.references["refs/heads/b2"].target_id
+      assert_equal @repo.references["refs/heads/b3"].target_id, @target_repo.references["refs/heads/b3"].target_id
+      assert_equal @repo.references["refs/heads/b4"].target_id, @target_repo.references["refs/heads/b4"].target_id
+      assert_equal @repo.references["refs/heads/b5"].target_id, @target_repo.references["refs/heads/b5"].target_id
+    end
+  end
+end
+
+if Rugged.features.include?(:ssh)
+  class OnlineSshPushTest < Rugged::OnlineTestCase
+    def setup
+      @repo = FixtureRepo.from_libgit2("push_src")
+      @remote = @repo.remotes.create("test", ENV['GITTEST_REMOTE_SSH_URL'])
+      @target_repo = Rugged::Repository.new(ENV['GITTEST_REMOTE_REPO_PATH'])
+    end
+
+    if ssh_creds?
+      def test_push_branches
+        @remote.push([
+          "refs/heads/b1:refs/heads/b1",
+          "refs/heads/b2:refs/heads/b2",
+          "refs/heads/b3:refs/heads/b3",
+          "refs/heads/b4:refs/heads/b4",
+          "refs/heads/b5:refs/heads/b5"
+        ], {
+          credentials: ssh_key_credential
+        })
+
+        assert_equal @repo.references["refs/heads/b1"].target_id, @target_repo.references["refs/heads/b1"].target_id
+        assert_equal @repo.references["refs/heads/b2"].target_id, @target_repo.references["refs/heads/b2"].target_id
+        assert_equal @repo.references["refs/heads/b3"].target_id, @target_repo.references["refs/heads/b3"].target_id
+        assert_equal @repo.references["refs/heads/b4"].target_id, @target_repo.references["refs/heads/b4"].target_id
+        assert_equal @repo.references["refs/heads/b5"].target_id, @target_repo.references["refs/heads/b5"].target_id
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/patch_test.rb b/app/server/vendor/rugged-0.23.3/test/patch_test.rb
new file mode 100755
index 0000000..a2c161b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/patch_test.rb
@@ -0,0 +1,56 @@
+require "test_helper"
+
+class PatchTest < Rugged::TestCase
+  def test_to_s
+    repo = FixtureRepo.from_libgit2("diff")
+    repo.config['core.abbrev'] = 7
+
+    a = repo.lookup("d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
+    b = repo.lookup("7a9e0b02e63179929fed24f0a3e0f19168114d10")
+
+    diff = a.tree.diff(b.tree, :context_lines => 0)
+
+    assert_equal <<-EOS, diff.patches[0].to_s
+diff --git a/another.txt b/another.txt
+index 3e5bcba..546c735 100644
+--- a/another.txt
++++ b/another.txt
+@@ -2 +2 @@ Git is fast. With Git, nearly all operations are performed locally, giving
+-it a huge speed advantage on centralized systems that constantly have to
++it an huge speed advantage on centralized systems that constantly have to
+@@ -11,4 +10,0 @@ from the start.
+-Let's see how common operations stack up against Subversion, a common
+-centralized version control system that is similar to CVS or
+-Perforce. Smaller is faster.
+-
+@@ -34,0 +31,4 @@ SVN.
++Let's see how common operations stack up against Subversion, a common
++centralized version control system that is similar to CVS or
++Perforce. Smaller is faster.
++
+EOS
+
+    assert_equal <<-EOS, diff.patches[1].to_s
+diff --git a/readme.txt b/readme.txt
+index 7b808f7..29ab705 100644
+--- a/readme.txt
++++ b/readme.txt
+@@ -1 +1 @@
+-The Git feature that really makes it stand apart from nearly every other SCM
++The Git feature that r3ally mak3s it stand apart from n3arly 3v3ry other SCM
+@@ -10,4 +9,0 @@ This means that you can do things like:
+-Frictionless Context Switching. Create a branch to try out an idea, commit a
+-few times, switch back to where you branched from, apply a patch, switch
+-back to where you are experimenting, and merge it in.
+-
+@@ -27,3 +22,0 @@ Notably, when you push to a remote repository, you do not have to push all
+-of your branches. You can choose to share just one of your branches, a few
+-of them, or all of them. This tends to free people to try new ideas without
+-worrying about having to plan how and when they are going to merge it in or
+@@ -35 +28 @@ incredibly easy and it changes the way most developers work when they learn
+-it.
++it.!
+\\ No newline at end of file
+EOS
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/reference_test.rb b/app/server/vendor/rugged-0.23.3/test/reference_test.rb
new file mode 100755
index 0000000..8d50068
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/reference_test.rb
@@ -0,0 +1,415 @@
+# encoding: UTF-8
+require "test_helper"
+
+class ReferenceTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("testrepo")
+  end
+
+  def test_reference_validity
+    valid = "refs/foobar"
+    invalid = "refs/~nope^*"
+
+    assert Rugged::Reference.valid_name?(valid)
+    assert !Rugged::Reference.valid_name?(invalid)
+  end
+
+  def test_each_can_handle_exceptions
+    assert_raises Exception do
+      @repo.references.each do
+        raise Exception.new("fail")
+      end
+    end
+  end
+
+  def test_list_references
+    assert_equal [
+      "refs/heads/br2",
+      "refs/heads/dir",
+      "refs/heads/ident",
+      "refs/heads/long-file-name",
+      "refs/heads/master",
+      "refs/heads/packed",
+      "refs/heads/packed-test",
+      "refs/heads/subtrees",
+      "refs/heads/test",
+      "refs/tags/e90810b",
+      "refs/tags/foo/bar",
+      "refs/tags/foo/foo/bar",
+      "refs/tags/packed-tag",
+      "refs/tags/point_to_blob",
+      "refs/tags/test"
+    ], @repo.refs.map(&:name).sort
+  end
+
+  def test_can_filter_refs_with_glob
+    assert_equal [
+      "refs/tags/e90810b",
+      "refs/tags/foo/bar",
+      "refs/tags/foo/foo/bar",
+      "refs/tags/packed-tag",
+      "refs/tags/point_to_blob",
+      "refs/tags/test"
+    ], @repo.refs('refs/tags/*').map(&:name).sort
+  end
+
+  def test_can_open_reference
+    ref = @repo.references["refs/heads/master"]
+    assert_equal "099fabac3a9ea935598528c27f866e34089c2eff", ref.target_id
+    assert_equal :direct, ref.type
+    assert_equal "refs/heads/master", ref.name
+    assert_equal "refs/heads/master", ref.canonical_name
+    assert_nil ref.peel
+  end
+
+  def test_can_open_a_symbolic_reference
+    ref = @repo.references["HEAD"]
+    assert_equal "refs/heads/master", ref.target_id
+    assert_equal :symbolic, ref.type
+
+    resolved = ref.resolve
+    assert_equal :direct, resolved.type
+    assert_equal "099fabac3a9ea935598528c27f866e34089c2eff", resolved.target_id
+    assert_equal resolved.target_id, ref.peel
+  end
+
+  def test_looking_up_missing_ref_returns_nil
+    ref = @repo.references["lol/wut"]
+    assert_equal nil, ref
+  end
+
+  def test_reference_exists
+    exists = @repo.references.exists?("refs/heads/master")
+    assert exists
+
+    exists = @repo.references.exists?("lol/wut")
+    assert !exists
+  end
+
+  def test_load_packed_ref
+    ref = @repo.references["refs/heads/packed"]
+    assert_equal "41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9", ref.target_id
+    assert_equal :direct, ref.type
+    assert_equal "refs/heads/packed", ref.name
+  end
+
+  def test_resolve_head
+    ref = @repo.references["HEAD"]
+    assert_equal "refs/heads/master", ref.target_id
+    assert_equal :symbolic, ref.type
+
+    head = ref.resolve
+    assert_equal "099fabac3a9ea935598528c27f866e34089c2eff", head.target_id
+    assert_equal :direct, head.type
+  end
+
+  def test_reference_to_tag
+    ref = @repo.references["refs/tags/test"]
+
+    assert_equal "b25fa35b38051e4ae45d4222e795f9df2e43f1d1", ref.target_id
+    assert_equal "e90810b8df3e80c413d903f631643c716887138d", ref.peel
+  end
+
+  def test_collection_delete_with_tag
+    tag = @repo.tags["test"]
+
+    @repo.references.delete(tag)
+    refute @repo.references.exists?("refs/tags/test")
+  end
+
+  def test_collection_delete_with_branch
+    branch = @repo.branches["master"]
+
+    @repo.references.delete(branch)
+    refute @repo.references.exists?("refs/heads/master")
+  end
+
+  def test_reference_is_branch
+    repo = FixtureRepo.from_libgit2("testrepo.git")
+
+    assert repo.references["refs/heads/master"].branch?
+
+    refute repo.references["refs/remotes/test/master"].branch?
+    refute repo.references["refs/tags/test"].branch?
+  end
+
+  def test_reference_is_remote
+    repo = FixtureRepo.from_libgit2("testrepo.git")
+
+    assert repo.references["refs/remotes/test/master"].remote?
+
+    refute repo.references["refs/heads/master"].remote?
+    refute repo.references["refs/tags/test"].remote?
+  end
+
+  def test_reference_is_tag
+    repo = FixtureRepo.from_libgit2("testrepo.git")
+
+    assert repo.references["refs/tags/test"].tag?
+
+    refute repo.references["refs/heads/master"].tag?
+    refute repo.references["refs/remotes/test/master"].tag?
+  end
+end
+
+class ReferenceWriteTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_rugged("testrepo.git")
+  end
+
+  def test_create_force
+    @repo.references.create("refs/heads/unit_test", "refs/heads/master")
+
+    @repo.references.create("refs/heads/unit_test",
+      "refs/heads/master", force: true)
+
+    @repo.references.create("refs/heads/unit_test",
+      "refs/heads/master", force: :force)
+  end
+
+  def test_create_unicode_reference_nfc
+    ref_name = "refs/heads/\xC3\x85\x73\x74\x72\xC3\xB6\x6D"
+
+    new_ref = @repo.references.create(ref_name, "5b5b025afb0b4c913b4c338a42934a3863bf3644")
+    refute_nil new_ref
+
+    assert_equal ref_name, new_ref.name
+    assert_equal ref_name, new_ref.canonical_name
+
+    refute_nil @repo.references[ref_name]
+  end
+
+  def test_create_unicode_reference_nfd
+    ref_name = "refs/heads/\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D"
+
+    new_ref = @repo.references.create(ref_name, "5b5b025afb0b4c913b4c338a42934a3863bf3644")
+    refute_nil new_ref
+
+    if @repo.config["core.precomposeunicode"] == "true"
+      expected_name = "refs/heads/\xC3\x85\x73\x74\x72\xC3\xB6\x6D"
+    else
+      expected_name = ref_name
+    end
+
+    assert_equal expected_name, new_ref.name
+    assert_equal expected_name, new_ref.canonical_name
+
+    refute_nil @repo.references[ref_name]
+    refute_nil @repo.references[expected_name]
+  end
+
+  def test_rename_unicode_reference_nfd
+    ref_name = "refs/heads/\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D"
+
+    @repo.references.create("refs/heads/unit_test", "36060c58702ed4c2a40832c51758d5344201d89a")
+    new_ref = @repo.references.rename("refs/heads/unit_test", ref_name)
+    refute_nil new_ref
+
+    if @repo.config["core.precomposeunicode"] == "true"
+      expected_name = "refs/heads/\xC3\x85\x73\x74\x72\xC3\xB6\x6D"
+    else
+      expected_name = ref_name
+    end
+
+    assert_equal expected_name, new_ref.name
+    assert_equal expected_name, new_ref.canonical_name
+
+    refute_nil @repo.references[ref_name]
+    refute_nil @repo.references[expected_name]
+  end
+
+  def test_create_symbolic_ref
+    ref = @repo.references.create("refs/heads/unit_test", "refs/heads/master")
+    assert_equal "refs/heads/master", ref.target_id
+    assert_equal :symbolic, ref.type
+    assert_equal "refs/heads/unit_test", ref.name
+    @repo.references.delete(ref)
+  end
+
+  def test_create_ref_from_oid
+    ref = @repo.references.create(
+      "refs/heads/unit_test",
+      "36060c58702ed4c2a40832c51758d5344201d89a")
+
+    assert_equal "36060c58702ed4c2a40832c51758d5344201d89a", ref.target_id
+    assert_equal :direct, ref.type
+    assert_equal "refs/heads/unit_test", ref.name
+    @repo.references.delete(ref)
+  end
+
+  def test_rename_ref
+    ref = @repo.references.create("refs/heads/unit_test",
+      "36060c58702ed4c2a40832c51758d5344201d89a")
+
+    assert_equal "36060c58702ed4c2a40832c51758d5344201d89a", ref.target_id
+    assert_equal :direct, ref.type
+    assert_equal "refs/heads/unit_test", ref.name
+
+    new_ref = @repo.references.rename(ref, "refs/heads/rug_new_name")
+    assert_equal "refs/heads/rug_new_name", new_ref.name
+    @repo.references.delete(new_ref)
+  end
+
+  def test_set_ref_target
+    ref = @repo.references.create("refs/heads/unit_test",
+      "36060c58702ed4c2a40832c51758d5344201d89a")
+
+    assert_equal "36060c58702ed4c2a40832c51758d5344201d89a", ref.target_id
+    assert_equal :direct, ref.type
+    assert_equal "refs/heads/unit_test", ref.name
+
+    new_ref = @repo.references.update(ref, "5b5b025afb0b4c913b4c338a42934a3863bf3644")
+    assert_equal "5b5b025afb0b4c913b4c338a42934a3863bf3644", new_ref.target_id
+    @repo.references.delete(new_ref)
+  end
+
+  def test_write_and_read_unicode_refs
+    ref1 = @repo.references.create("refs/heads/Ångström", "refs/heads/master")
+    ref2 = @repo.references.create("refs/heads/foobar", "refs/heads/Ångström")
+
+    assert_equal "refs/heads/Ångström", ref1.name
+    assert_equal "refs/heads/Ångström", ref2.target_id
+  end
+end
+
+class ReflogTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("testrepo")
+
+    @ident = {
+      name: 'Rugged User',
+      email: 'rugged at example.com'
+    }
+
+    @repo.config['user.name'] = @ident[:name]
+    @repo.config['user.email'] = @ident[:email]
+
+    @ref = @repo.references.create("refs/heads/test-reflog",
+      "a65fedf39aefe402d3bb6e24df4d4f5fe4547750")
+  end
+
+  def test_create_default_log
+    ref = @repo.references.create("refs/heads/test-reflog-default",
+      "a65fedf39aefe402d3bb6e24df4d4f5fe4547750")
+    reflog = ref.log
+
+    assert_equal reflog.size, 1
+
+    assert_equal '0000000000000000000000000000000000000000', reflog[0][:id_old]
+    assert_equal 'a65fedf39aefe402d3bb6e24df4d4f5fe4547750', reflog[0][:id_new]
+    assert_equal nil, reflog[0][:message]
+    assert_equal @ident[:name], reflog[0][:committer][:name]
+    assert_equal @ident[:email], reflog[0][:committer][:email]
+    assert_kind_of Time, reflog[0][:committer][:time]
+  end
+
+  def test_create_default_log_custom_ident
+    @repo.ident = {
+      name: 'Other User',
+      email: 'other at example.com'
+    }
+
+    ref = @repo.references.create("refs/heads/test-reflog-default",
+      "a65fedf39aefe402d3bb6e24df4d4f5fe4547750")
+    reflog = ref.log
+
+    assert_equal reflog.size, 1
+
+    assert_equal '0000000000000000000000000000000000000000', reflog[0][:id_old]
+    assert_equal 'a65fedf39aefe402d3bb6e24df4d4f5fe4547750', reflog[0][:id_new]
+    assert_equal nil, reflog[0][:message]
+    assert_equal 'Other User', reflog[0][:committer][:name]
+    assert_equal 'other at example.com', reflog[0][:committer][:email]
+    assert_kind_of Time, reflog[0][:committer][:time]
+  end
+
+  def test_create_default_log_custom_log_message
+    ref = @repo.references.create(
+      "refs/heads/test-reflog-default",
+      "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", {
+        message: "reference created"
+      })
+    reflog = ref.log
+
+    assert_equal reflog.size, 1
+
+    assert_equal '0000000000000000000000000000000000000000', reflog[0][:id_old]
+    assert_equal 'a65fedf39aefe402d3bb6e24df4d4f5fe4547750', reflog[0][:id_new]
+    assert_equal "reference created", reflog[0][:message]
+    assert_equal @ident[:name], reflog[0][:committer][:name]
+    assert_equal @ident[:email], reflog[0][:committer][:email]
+    assert_kind_of Time, reflog[0][:committer][:time]
+  end
+
+  def test_create_default_log_custom_ident_and_log_message
+    @repo.ident = {
+      name: 'Other User',
+      email: 'other at example.com'
+    }
+
+    ref = @repo.references.create(
+      "refs/heads/test-reflog-default",
+      "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", {
+        message: "reference created"
+      })
+    reflog = ref.log
+
+    assert_equal reflog.size, 1
+
+    assert_equal '0000000000000000000000000000000000000000', reflog[0][:id_old]
+    assert_equal 'a65fedf39aefe402d3bb6e24df4d4f5fe4547750', reflog[0][:id_new]
+    assert_equal "reference created", reflog[0][:message]
+    assert_equal 'Other User', reflog[0][:committer][:name]
+    assert_equal 'other at example.com', reflog[0][:committer][:email]
+    assert_kind_of Time, reflog[0][:committer][:time]
+  end
+
+  def test_set_target_default_log
+    @repo.references.update(@ref, "5b5b025afb0b4c913b4c338a42934a3863bf3644")
+
+    reflog = @ref.log
+    assert_equal reflog.size, 2
+
+    assert_equal 'a65fedf39aefe402d3bb6e24df4d4f5fe4547750', reflog[1][:id_old]
+    assert_equal '5b5b025afb0b4c913b4c338a42934a3863bf3644', reflog[1][:id_new]
+    assert_equal nil, reflog[1][:message]
+    assert_equal @ident[:name], reflog[1][:committer][:name]
+    assert_equal @ident[:email], reflog[1][:committer][:email]
+    assert_kind_of Time, reflog[1][:committer][:time]
+  end
+
+  def test_set_target_default_log_custom_signature
+    @repo.ident = {
+      name: "Other User",
+      email: "other at exmaple.com"
+    }
+
+    @repo.references.update(@ref, "5b5b025afb0b4c913b4c338a42934a3863bf3644")
+
+    reflog = @ref.log
+    assert_equal reflog.size, 2
+
+    assert_equal 'a65fedf39aefe402d3bb6e24df4d4f5fe4547750', reflog[1][:id_old]
+    assert_equal '5b5b025afb0b4c913b4c338a42934a3863bf3644', reflog[1][:id_new]
+    assert_equal nil, reflog[1][:message]
+    assert_equal "Other User", reflog[1][:committer][:name]
+    assert_equal "other at exmaple.com", reflog[1][:committer][:email]
+    assert_kind_of Time, reflog[1][:committer][:time]
+  end
+
+  def test_set_target_default_log_custom_log_message
+    @repo.references.update(@ref, "5b5b025afb0b4c913b4c338a42934a3863bf3644", {
+      message: "reference updated"
+    })
+
+    reflog = @ref.log
+    assert_equal reflog.size, 2
+
+    assert_equal 'a65fedf39aefe402d3bb6e24df4d4f5fe4547750', reflog[1][:id_old]
+    assert_equal '5b5b025afb0b4c913b4c338a42934a3863bf3644', reflog[1][:id_new]
+    assert_equal "reference updated", reflog[1][:message]
+    assert_equal @ident[:name], reflog[1][:committer][:name]
+    assert_equal @ident[:email], reflog[1][:committer][:email]
+    assert_kind_of Time, reflog[1][:committer][:time]
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/remote_test.rb b/app/server/vendor/rugged-0.23.3/test/remote_test.rb
new file mode 100755
index 0000000..925b889
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/remote_test.rb
@@ -0,0 +1,352 @@
+require "test_helper"
+require 'net/http'
+
+class RemoteNetworkTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_rugged("testrepo.git")
+  end
+
+  def skip_if_unreachable
+    begin
+      Net::HTTP.new('github.com').head('/')
+    rescue SocketError => msg
+      skip "github is not reachable: #{msg}"
+    end
+  end
+
+  def test_remote_network_connect
+    skip_if_unreachable
+    remote = @repo.remotes.create_anonymous('git://github.com/libgit2/libgit2.git')
+    assert remote.ls.any?
+  end
+
+  def test_remote_check_connection_fetch
+    skip_if_unreachable
+    remote = @repo.remotes.create_anonymous('git://github.com/libgit2/libgit2.git')
+    assert remote.check_connection(:fetch)
+  end
+
+  def test_remote_check_connection_push
+    skip_if_unreachable
+    remote = @repo.remotes.create_anonymous('git://github.com/libgit2/libgit2.git')
+    assert !remote.check_connection(:push)
+  end
+
+  def test_remote_check_connection_push_credentials
+    skip_if_unreachable
+    remote = @repo.remotes.create_anonymous('https://github.com/libgit2-push-test/libgit2-push-test.git')
+    credentials = Rugged::Credentials::UserPassword.new(username: "libgit2-push-test", password: "123qwe123")
+    assert remote.check_connection(:push, credentials: credentials)
+  end
+
+  def test_remote_check_connection_invalid
+    skip_if_unreachable
+    remote = @repo.remotes.create_anonymous('git://github.com/libgit2/libgit2.git')
+    assert_raises(TypeError) { remote.check_connection(:pull) }
+  end
+end
+
+class RemoteTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("testrepo.git")
+  end
+
+  class TestException < StandardError
+  end
+
+  def test_list_remote_names
+    assert_equal ["empty-remote-pushurl", "empty-remote-url", "joshaber", "test", "test_with_pushurl"], @repo.remotes.each_name.sort
+  end
+
+  def test_list_remotes
+    assert @repo.remotes.kind_of? Enumerable
+    assert_equal ["empty-remote-pushurl", "empty-remote-url", "joshaber", "test", "test_with_pushurl"], @repo.remotes.map(&:name).sort
+  end
+
+  def test_remotes_each_protect
+    assert_raises TestException do
+      @repo.remotes.each do |remote|
+        raise TestException
+      end
+    end
+  end
+
+  def test_remote_new_name
+    remote = @repo.remotes.create_anonymous('git://github.com/libgit2/libgit2.git')
+    assert_nil remote.name
+    assert_equal 'git://github.com/libgit2/libgit2.git', remote.url
+  end
+
+  def test_remote_new_invalid_url
+    @repo.remotes.create_anonymous('libgit2')
+  end
+
+  def test_remote_delete
+    @repo.remotes.delete("test")
+    assert_nil @repo.remotes["test"]
+  end
+
+  def test_push_url
+    assert_equal 'git://github.com/libgit2/pushlibgit2',
+      @repo.remotes['test_with_pushurl'].push_url
+
+    assert_nil @repo.remotes['joshaber'].push_url
+  end
+
+  def test_fetch_refspecs
+    remote = @repo.remotes['test']
+    assert_equal ['+refs/heads/*:refs/remotes/test/*'], remote.fetch_refspecs
+
+    assert_empty @repo.remotes['joshaber'].fetch_refspecs
+  end
+
+  def test_push_refspecs
+    remote = @repo.remotes['test']
+    assert_empty remote.push_refspecs
+  end
+
+  def test_remote_lookup
+    remote = @repo.remotes['test']
+    assert_equal 'git://github.com/libgit2/libgit2', remote.url
+    assert_equal 'test', remote.name
+  end
+
+  def test_remote_lookup_missing
+    assert_nil @repo.remotes['missing_remote']
+  end
+
+  def test_remote_lookup_invalid
+    assert_raises Rugged::ConfigError do
+      @repo.remotes["*\?"]
+    end
+  end
+end
+
+class RemotePushTest < Rugged::TestCase
+  def setup
+    @remote_repo = FixtureRepo.from_libgit2("testrepo.git")
+    # We can only push to bare repos
+    @remote_repo.config['core.bare'] = 'true'
+
+    @repo = FixtureRepo.clone(@remote_repo)
+    @repo.references.create("refs/heads/unit_test",
+      "8496071c1b46c854b31185ea97743be6a8774479")
+
+    @remote = @repo.remotes['origin']
+  end
+
+  def test_push_single_ref
+    result = @remote.push(["refs/heads/master", "refs/heads/master:refs/heads/foobar", "refs/heads/unit_test"])
+    assert_equal({}, result)
+
+    assert_equal "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", @remote_repo.ref("refs/heads/foobar").target_id
+    assert_equal "8496071c1b46c854b31185ea97743be6a8774479", @remote_repo.ref("refs/heads/unit_test").target_id
+  end
+
+  def test_push_to_non_bare_raise_error
+    @remote_repo.config['core.bare'] = 'false'
+
+    exception = assert_raises Rugged::InvalidError do
+      @remote.push(["refs/heads/master"])
+    end
+
+    assert_equal "Local push doesn't (yet) support pushing to non-bare repos.", exception.message
+  end
+
+  def test_push_non_forward_raise_error
+    exception = assert_raises Rugged::ReferenceError do
+      @remote.push(["refs/heads/unit_test:refs/heads/master"])
+    end
+
+    assert_equal "Cannot push non-fastforwardable reference", exception.message
+    assert_equal "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", @remote_repo.ref("refs/heads/master").target_id
+  end
+
+  def test_push_non_forward_forced_raise_no_error
+    result = @remote.push(["+refs/heads/unit_test:refs/heads/master"])
+    assert_equal({}, result)
+
+    assert_equal "8496071c1b46c854b31185ea97743be6a8774479", @remote_repo.ref("refs/heads/master").target_id
+  end
+end
+
+class RemoteWriteTest < Rugged::TestCase
+  def setup
+    @source_repo = FixtureRepo.from_rugged("testrepo.git")
+    @repo = FixtureRepo.clone(@source_repo)
+  end
+
+  def test_remote_add
+    @repo.remotes.create('upstream', 'git://github.com/libgit2/libgit2.git')
+    remote = @repo.remotes['upstream']
+    assert_equal 'upstream', remote.name
+    assert_equal 'git://github.com/libgit2/libgit2.git', remote.url
+  end
+
+  def test_remote_add_with_invalid_url
+    @repo.remotes.create('upstream', 'libgit2')
+  end
+
+  def test_remote_set_url
+    remote = @repo.remotes['origin']
+
+    old_url = remote.url
+    new_url = 'git://github.com/l?#!@#$ibgit2/TestGitRepository.git'
+
+    @repo.remotes.set_url(remote, new_url)
+
+    assert_equal old_url, remote.url
+    assert_equal new_url, @repo.remotes['origin'].url
+  end
+
+  def test_remote_set_push_url
+    remote = @repo.remotes['origin']
+
+    old_url = remote.push_url
+    new_url = 'git://github.com/l?#!@#$ibgit2/TestGitRepository.git'
+
+    @repo.remotes.set_push_url(remote, new_url)
+
+    assert_equal old_url, remote.push_url
+    assert_equal new_url, @repo.remotes['origin'].push_url
+  end
+
+  def test_remote_add_fetch_refspech
+    remote = @repo.remotes['origin']
+    assert_nil @repo.remotes.add_fetch_refspec('origin', '+refs/pull/*/head:refs/remotes/origin/pr/*')
+
+    assert_equal ['+refs/heads/*:refs/remotes/origin/*'], remote.fetch_refspecs
+    assert_equal [
+      '+refs/heads/*:refs/remotes/origin/*', '+refs/pull/*/head:refs/remotes/origin/pr/*'
+    ], @repo.remotes['origin'].fetch_refspecs
+  end
+
+  def test_remote_add_push_refspec
+    remote = @repo.remotes['origin']
+    assert_nil @repo.remotes.add_push_refspec('origin', 'refs/heads/*:refs/heads/test/*')
+
+    assert_equal [], remote.push_refspecs
+    assert_equal [
+      'refs/heads/*:refs/heads/test/*'
+    ], @repo.remotes['origin'].push_refspecs
+  end
+
+  def test_rename
+    new_remote = @repo.remotes.rename('origin', 'new_remote_name') { }
+    assert_equal new_remote.name, 'new_remote_name'
+  end
+
+  def test_rename_with_remote
+    old_remote = @repo.remotes['origin']
+    new_remote = @repo.remotes.rename(old_remote, 'new_remote_name') { }
+
+    assert_equal new_remote.name, 'new_remote_name'
+    assert_equal old_remote.name, 'origin'
+  end
+
+  def test_rename_invalid_name
+    assert_raises Rugged::ConfigError do
+      @repo.remotes.rename('origin', '/?') { }
+    end
+  end
+
+  def test_rename_to_existing
+    assert_raises Rugged::ConfigError do
+      @repo.remotes.rename('origin', 'origin') { }
+    end
+  end
+
+  def test_rename_error_callback
+    @repo.config['remote.origin.fetch'] = '+refs/*:refs/*'
+
+    problems = []
+    @repo.remotes.rename('origin', 'test_remote') { |problem| problems << problem }
+    assert_equal ["+refs/*:refs/*"], problems
+  end
+end
+
+class RemoteTransportTest < Rugged::TestCase
+  class TestException < StandardError
+  end
+
+  def setup
+    @repo = FixtureRepo.empty
+    repo_dir = File.join(TEST_DIR, (File.join('fixtures', 'testrepo.git', '.')))
+    @remote = @repo.remotes.create('origin', repo_dir)
+  end
+
+  def test_remote_ls
+    assert @remote.ls.kind_of? Enumerable
+    rheads = @remote.ls.to_a
+
+    assert_equal 7, rheads.count
+
+    rhead = rheads.first
+    assert_equal false, rhead[:local?]
+    assert rhead[:oid]
+    assert_nil rhead[:loid]
+  end
+
+  def test_remote_fetch
+    assert_equal({
+      total_objects: 19,
+      indexed_objects: 19,
+      received_objects: 19,
+      local_objects: 0,
+      total_deltas: 2,
+      indexed_deltas: 2,
+      received_bytes: 1563
+    }, @remote.fetch)
+
+    assert_equal '36060c58702ed4c2a40832c51758d5344201d89a', @repo.branches['origin/master'].target_id
+    assert_equal '41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9', @repo.branches["origin/packed"].target_id
+    assert_equal '5b5b025afb0b4c913b4c338a42934a3863bf3644', @repo.tags["v0.9"].target_id
+    assert_equal '0c37a5391bbff43c37f0d0371823a5509eed5b1d', @repo.tags["v1.0"].target_id
+  end
+
+  def test_update_tips_callback
+    @remote.fetch update_tips: lambda { |ref, source, destination|
+      assert @repo.references[ref]
+      assert_nil source
+      assert destination
+    }
+
+    assert_equal '36060c58702ed4c2a40832c51758d5344201d89a', @repo.branches['origin/master'].target_id
+    assert_equal '41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9', @repo.branches["origin/packed"].target_id
+    assert_equal '5b5b025afb0b4c913b4c338a42934a3863bf3644', @repo.tags["v0.9"].target_id
+    assert_equal '0c37a5391bbff43c37f0d0371823a5509eed5b1d', @repo.tags["v1.0"].target_id
+  end
+
+  def test_update_tips_callback_error
+    assert_raises TestException do
+      @remote.fetch update_tips: lambda { |*args|
+        raise TestException
+      }
+    end
+
+    # In case of an error inside the callback, all further tip updates get cancelled
+    assert_equal '36060c58702ed4c2a40832c51758d5344201d89a', @repo.branches["origin/master"].target_id
+    refute @repo.branches["origin/packed"]
+    refute @repo.tags["v0.9"]
+    refute @repo.tags["v1.0"]
+  end
+
+  def test_transfer_progress_callback
+    total_objects = indexed_objects = received_objects = local_objects = total_deltas = indexed_deltas = received_bytes = nil
+    callsback = 0
+
+    @remote.fetch transfer_progress: lambda { |*args|
+      total_objects, indexed_objects, received_objects, local_objects, total_deltas, indexed_deltas, received_bytes = args
+      callsback += 1
+    }
+
+    assert_equal 22, callsback
+    assert_equal 19, total_objects
+    assert_equal 19, indexed_objects
+    assert_equal 19, received_objects
+    assert_equal 0, local_objects
+    assert_equal 2, total_deltas
+    assert_equal 2, indexed_deltas
+    assert_equal 1563, received_bytes
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/repo_ignore_test.rb b/app/server/vendor/rugged-0.23.3/test/repo_ignore_test.rb
new file mode 100755
index 0000000..f45fe26
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/repo_ignore_test.rb
@@ -0,0 +1,18 @@
+require "test_helper"
+
+class RepositoryIgnoreTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2 "attr"
+  end
+
+  def test_path_ignored
+    assert @repo.path_ignored?("ign")
+    refute @repo.path_ignored?("ignore_not")
+    assert @repo.path_ignored?("dir")
+    assert @repo.path_ignored?("dir/foo")
+    assert @repo.path_ignored?("dir/foo/bar")
+    refute @repo.path_ignored?("foo/dir")
+    assert @repo.path_ignored?("foo/dir/bar")
+    refute @repo.path_ignored?("direction")
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/repo_pack_test.rb b/app/server/vendor/rugged-0.23.3/test/repo_pack_test.rb
new file mode 100755
index 0000000..e3bc4df
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/repo_pack_test.rb
@@ -0,0 +1,26 @@
+require "test_helper"
+require 'base64'
+
+class PackfileTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_rugged("testrepo.git")
+  end
+
+  def test_packfile_object_exists
+    assert @repo.exists?("41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9")
+    assert @repo.exists?("f82a8eb4cb20e88d1030fd10d89286215a715396")
+  end
+
+  def test_read_packed_object
+    rawobj = @repo.read("41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9")
+    assert_match 'tree f82a8eb4cb20e88d1030fd10d89286215a715396', rawobj.data
+    assert_equal 230, rawobj.len
+    assert_equal :commit, rawobj.type
+  end
+
+  def test_read_packed_header
+    hash = @repo.read_header("41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9")
+    assert_equal 230, hash[:len]
+    assert_equal :commit, hash[:type]
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/repo_reset_test.rb b/app/server/vendor/rugged-0.23.3/test/repo_reset_test.rb
new file mode 100755
index 0000000..be1b887
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/repo_reset_test.rb
@@ -0,0 +1,85 @@
+require "test_helper"
+
+class RepositoryResetTest < Rugged::TestCase
+  def setup
+    @source_repo = FixtureRepo.from_rugged("testrepo.git")
+    @repo = FixtureRepo.clone(@source_repo)
+  end
+
+  def repo_file_path; File.join('subdir', 'README') end
+  def file_path;      File.join(@repo.workdir, 'subdir', 'README') end
+
+  def test_reset_with_rugged_tag
+    tag = @repo.lookup('0c37a5391bbff43c37f0d0371823a5509eed5b1d')
+    @repo.reset(tag, :soft)
+    assert_equal tag.target_id , @repo.head.target_id
+  end
+
+  def test_reset_with_invalid_mode
+    assert_raises ArgumentError do
+      @repo.reset('441034f860c1d5d90e4188d11ae0d325176869a8', :tender)
+    end
+  end
+
+  def test_reset_soft
+    original_content = File.open(file_path) { |f| f.read }
+
+    @repo.reset('441034f860c1d5d90e4188d11ae0d325176869a8', :soft)
+    assert_equal '441034f860c1d5d90e4188d11ae0d325176869a8', @repo.head.target_id
+    assert_equal [:index_modified], @repo.status(repo_file_path)
+
+    new_content = File.open(file_path) { |f| f.read }
+
+    assert_equal original_content, new_content
+  end
+
+  def test_reset_mixed
+    original_content = File.open(file_path) { |f| f.read }
+
+    @repo.reset('441034f860c1d5d90e4188d11ae0d325176869a8', :mixed)
+    assert_equal [:worktree_modified], @repo.status(repo_file_path)
+
+    new_content = File.open(file_path) { |f| f.read }
+
+    assert_equal original_content, new_content
+  end
+
+  def test_reset_hard
+    original_content = File.open(file_path) { |f| f.read }
+
+    @repo.reset('441034f860c1d5d90e4188d11ae0d325176869a8', :hard)
+    assert_empty @repo.status(repo_file_path)
+
+    new_content = File.open(file_path) { |f| f.read }
+
+    refute_equal original_content, new_content
+  end
+
+  def test_reset_path
+    File.open(file_path, 'w') do |f|
+      f.puts "test content"
+    end
+    @repo.index.add(repo_file_path)
+    @repo.index.write
+
+    @repo.reset_path(repo_file_path, '441034f860c1d5d90e4188d11ae0d325176869a8')
+    assert_equal [:index_modified, :worktree_modified], @repo.status(repo_file_path)
+  end
+
+  def test_reset_path_no_target
+    File.open(file_path, 'w') do |f|
+      f.puts "test content"
+    end
+    @repo.index.add(repo_file_path)
+    @repo.index.write
+
+    @repo.reset_path(repo_file_path)
+    assert_equal [:index_deleted, :worktree_new], @repo.status(repo_file_path)
+  end
+
+  def test_reset_path_invalid_pathspec
+    assert_raises TypeError do
+      @repo.reset_path([:invalid_reset_path], '441034f860c1d5d90e4188d11ae0d325176869a8')
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/repo_test.rb b/app/server/vendor/rugged-0.23.3/test/repo_test.rb
new file mode 100755
index 0000000..655d863
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/repo_test.rb
@@ -0,0 +1,887 @@
+require 'test_helper'
+require 'base64'
+
+class RepositoryTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2 "testrepo.git"
+  end
+
+  def test_last_commit
+    assert @repo.respond_to? :last_commit
+    assert "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", @repo.last_commit.oid
+  end
+
+  def test_fails_to_open_unexisting_repos
+    assert_raises IOError, Rugged::OSError do
+      Rugged::Repository.new("fakepath/123/")
+    end
+
+    assert_raises Rugged::RepositoryError do
+      Rugged::Repository.new("test")
+    end
+  end
+
+  def test_can_check_if_objects_exist
+    assert @repo.exists?("8496071c1b46c854b31185ea97743be6a8774479")
+    assert @repo.exists?("1385f264afb75a56a5bec74243be9b367ba4ca08")
+    assert !@repo.exists?("ce08fe4884650f067bd5703b6a59a8b3b3c99a09")
+    assert !@repo.exists?("8496071c1c46c854b31185ea97743be6a8774479")
+  end
+
+  def test_can_read_a_raw_object
+    rawobj = @repo.read("8496071c1b46c854b31185ea97743be6a8774479")
+    assert_match 'tree 181037049a54a1eb5fab404658a3a250b44335d7', rawobj.data
+    assert_equal 172, rawobj.len
+    assert_equal :commit, rawobj.type
+  end
+
+  def test_can_read_object_headers
+    hash = @repo.read_header("8496071c1b46c854b31185ea97743be6a8774479")
+    assert_equal 172, hash[:len]
+    assert_equal :commit, hash[:type]
+  end
+
+  def test_check_reads_fail_on_missing_objects
+    assert_raises Rugged::OdbError do
+      @repo.read("a496071c1b46c854b31185ea97743be6a8774471")
+    end
+  end
+
+  def test_check_read_headers_fail_on_missing_objects
+    assert_raises Rugged::OdbError do
+      @repo.read_header("a496071c1b46c854b31185ea97743be6a8774471")
+    end
+  end
+
+  def test_walking_with_block
+    oid = "a4a7dce85cf63874e984719f4fdd239f5145052f"
+    list = []
+    @repo.walk(oid) { |c| list << c }
+    assert list.map {|c| c.oid[0,5] }.join('.'), "a4a7d.c4780.9fd73.4a202.5b5b0.84960"
+  end
+
+  def test_walking_without_block
+    commits = @repo.walk('a4a7dce85cf63874e984719f4fdd239f5145052f')
+
+    assert commits.kind_of?(Enumerable)
+    assert commits.count > 0
+  end
+
+  def test_lookup_object
+    object = @repo.lookup("8496071c1b46c854b31185ea97743be6a8774479")
+    assert object.kind_of?(Rugged::Commit)
+  end
+
+  def test_find_reference
+    ref = @repo.ref('refs/heads/master')
+
+    assert ref.kind_of?(Rugged::Reference)
+    assert_equal 'refs/heads/master', ref.name
+  end
+
+  def test_match_all_refs
+    refs = @repo.refs 'refs/heads/*'
+    assert_equal 12, refs.count
+  end
+
+  def test_return_all_ref_names
+    refs = @repo.ref_names
+    refs.each {|name| assert name.kind_of?(String)}
+    assert_equal 21, refs.count
+  end
+
+  def test_return_all_tags
+    tags = @repo.tags
+    assert_equal 7, tags.count
+  end
+
+  def test_return_matching_tags
+    assert_equal 1, @repo.tags.each('e90810b').count
+    assert_equal 4, @repo.tags.each('*tag*').count
+  end
+
+  def test_return_all_remotes
+    remotes = @repo.remotes
+    assert_equal 5, remotes.count
+  end
+
+  def test_lookup_head
+    head = @repo.head
+    assert_equal "refs/heads/master", head.name
+    assert_equal "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", head.target_id
+    assert_equal :direct, head.type
+  end
+
+  def test_set_head_ref
+    @repo.head = "refs/heads/packed"
+    assert_equal "refs/heads/packed", @repo.head.name
+  end
+
+  def test_set_head_invalid
+    assert_raises Rugged::ReferenceError do
+      @repo.head = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"
+    end
+  end
+
+  def test_access_a_file
+    sha = 'a65fedf39aefe402d3bb6e24df4d4f5fe4547750'
+    blob = @repo.blob_at(sha, 'new.txt')
+    assert_equal "my new file\n", blob.content
+  end
+
+  def test_access_a_missing_file
+    sha = 'a65fedf39aefe402d3bb6e24df4d4f5fe4547750'
+    blob = @repo.blob_at(sha, 'file-not-found.txt')
+    assert_nil blob
+  end
+
+  def test_garbage_collection
+    Rugged::Repository.new(@repo.path)
+    ObjectSpace.garbage_collect
+  end
+
+  def test_enumerate_all_objects
+    assert_equal 1687, @repo.each_id.count
+  end
+
+  def test_loading_alternates
+    alt_path = File.dirname(__FILE__) + '/fixtures/alternate/objects'
+    repo = Rugged::Repository.new(@repo.path, :alternates => [alt_path])
+
+    assert_equal 1690, repo.each_id.count
+    assert repo.read('146ae76773c91e3b1d00cf7a338ec55ae58297e2')
+  end
+
+  def test_alternates_with_invalid_path_type
+    assert_raises TypeError do
+      Rugged::Repository.new(@repo.path, :alternates => [:invalid_input])
+    end
+  end
+
+  def test_find_merge_base_between_oids
+    commit1 = 'a4a7dce85cf63874e984719f4fdd239f5145052f'
+    commit2 = 'a65fedf39aefe402d3bb6e24df4d4f5fe4547750'
+    base    = 'c47800c7266a2be04c571c04d5a6614691ea99bd'
+    assert_equal base, @repo.merge_base(commit1, commit2)
+  end
+
+  def test_find_merge_base_between_commits
+    commit1 = @repo.lookup('a4a7dce85cf63874e984719f4fdd239f5145052f')
+    commit2 = @repo.lookup('a65fedf39aefe402d3bb6e24df4d4f5fe4547750')
+    base    = 'c47800c7266a2be04c571c04d5a6614691ea99bd'
+    assert_equal base, @repo.merge_base(commit1, commit2)
+  end
+
+  def test_find_merge_base_between_ref_and_oid
+    commit1 = 'a4a7dce85cf63874e984719f4fdd239f5145052f'
+    commit2 = "refs/heads/master"
+    base    = 'c47800c7266a2be04c571c04d5a6614691ea99bd'
+    assert_equal base, @repo.merge_base(commit1, commit2)
+  end
+
+  def test_find_merge_base_between_many
+    commit1 = 'a4a7dce85cf63874e984719f4fdd239f5145052f'
+    commit2 = "refs/heads/packed"
+    commit3 = @repo.lookup('a65fedf39aefe402d3bb6e24df4d4f5fe4547750')
+
+    base    = 'c47800c7266a2be04c571c04d5a6614691ea99bd'
+    assert_equal base, @repo.merge_base(commit1, commit2, commit3)
+  end
+
+  def test_find_merge_bases_between_oids
+    commit1 = 'a4a7dce85cf63874e984719f4fdd239f5145052f'
+    commit2 = 'a65fedf39aefe402d3bb6e24df4d4f5fe4547750'
+
+    assert_equal [
+      "c47800c7266a2be04c571c04d5a6614691ea99bd", "9fd738e8f7967c078dceed8190330fc8648ee56a"
+    ], @repo.merge_bases(commit1, commit2)
+  end
+
+  def test_find_merge_bases_between_commits
+    commit1 = @repo.lookup('a4a7dce85cf63874e984719f4fdd239f5145052f')
+    commit2 = @repo.lookup('a65fedf39aefe402d3bb6e24df4d4f5fe4547750')
+
+    assert_equal [
+      "c47800c7266a2be04c571c04d5a6614691ea99bd", "9fd738e8f7967c078dceed8190330fc8648ee56a"
+    ], @repo.merge_bases(commit1, commit2)
+  end
+
+  def test_find_merge_bases_between_ref_and_oid
+    commit1 = 'a4a7dce85cf63874e984719f4fdd239f5145052f'
+    commit2 = "refs/heads/master"
+
+    assert_equal [
+      "c47800c7266a2be04c571c04d5a6614691ea99bd", "9fd738e8f7967c078dceed8190330fc8648ee56a"
+    ], @repo.merge_bases(commit1, commit2)
+  end
+
+  def test_find_merge_bases_between_many
+    commit1 = 'a4a7dce85cf63874e984719f4fdd239f5145052f'
+    commit2 = "refs/heads/packed"
+    commit3 = @repo.lookup('a65fedf39aefe402d3bb6e24df4d4f5fe4547750')
+
+    assert_equal [
+      "c47800c7266a2be04c571c04d5a6614691ea99bd", "9fd738e8f7967c078dceed8190330fc8648ee56a"
+    ], @repo.merge_bases(commit1, commit2, commit3)
+  end
+
+  def test_ahead_behind_with_oids
+    ahead, behind = @repo.ahead_behind(
+      'a4a7dce85cf63874e984719f4fdd239f5145052f',
+      'a65fedf39aefe402d3bb6e24df4d4f5fe4547750'
+    )
+    assert_equal 1, ahead
+    assert_equal 2, behind
+  end
+
+  def test_ahead_behind_with_commits
+    ahead, behind = @repo.ahead_behind(
+      @repo.lookup('a4a7dce85cf63874e984719f4fdd239f5145052f'),
+      @repo.lookup('a65fedf39aefe402d3bb6e24df4d4f5fe4547750')
+    )
+    assert_equal 1, ahead
+    assert_equal 2, behind
+  end
+
+  def test_expand_objects
+    expected = {
+      'a4a7dce8' => 'a4a7dce85cf63874e984719f4fdd239f5145052f',
+      'a65fedf3' => 'a65fedf39aefe402d3bb6e24df4d4f5fe4547750',
+      'c47800c7' => 'c47800c7266a2be04c571c04d5a6614691ea99bd'
+    }
+
+    assert_equal expected, @repo.expand_oids(['a4a7dce8', 'a65fedf3', 'c47800c7', 'deadbeef'])
+  end
+
+  def test_expand_and_filter_objects
+    assert_equal 2, @repo.expand_oids(['a4a7dce8', '1385f264af']).size
+    assert_equal 1, @repo.expand_oids(['a4a7dce8', '1385f264af'], :commit).size
+  end
+
+  def test_descendant_of
+    # String commit OIDs
+    assert @repo.descendant_of?("a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")
+    refute @repo.descendant_of?("be3563ae3f795b2b4353bcce3a527ad0a4f7f644", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750")
+
+    # Rugged::Commit instances
+    commit = @repo.lookup("a65fedf39aefe402d3bb6e24df4d4f5fe4547750")
+    ancestor = @repo.lookup("be3563ae3f795b2b4353bcce3a527ad0a4f7f644")
+
+    assert @repo.descendant_of?(commit, ancestor)
+    refute @repo.descendant_of?(ancestor, commit)
+  end
+
+  def test_descendant_of_bogus_args
+    # non-existent commit
+    assert_raises(Rugged::OdbError) do
+      @repo.descendant_of?("deadbeef" * 5, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750")
+    end
+
+    # non-existent ancestor
+    assert_raises(Rugged::OdbError) do
+      @repo.descendant_of?("a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "deadbeef" * 5)
+    end
+
+    # tree OID as the commit
+    assert_raises(Rugged::InvalidError) do
+      @repo.descendant_of?("181037049a54a1eb5fab404658a3a250b44335d7", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")
+    end
+
+    # tree OID as the ancestor
+    assert_raises(Rugged::InvalidError) do
+      @repo.descendant_of?("be3563ae3f795b2b4353bcce3a527ad0a4f7f644", "181037049a54a1eb5fab404658a3a250b44335d7")
+    end
+  end
+end
+
+class MergeCommitsRepositoryTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("merge-resolve")
+  end
+
+  def test_merge_commits
+    our_commit = @repo.branches["master"].target_id
+    their_commit = @repo.branches["branch"].target_id
+
+    index = @repo.merge_commits(our_commit, their_commit)
+
+    assert_equal 8, index.count
+
+    assert_equal "233c0919c998ed110a4b6ff36f353aec8b713487", index["added-in-master.txt", 0][:oid]
+    assert_equal "f2e1550a0c9e53d5811175864a29536642ae3821", index["automergeable.txt", 0][:oid]
+    assert_equal "4eb04c9e79e88f6640d01ff5b25ca2a60764f216", index["changed-in-branch.txt", 0][:oid]
+    assert_equal "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", index["changed-in-master.txt", 0][:oid]
+
+    assert_equal "d427e0b2e138501a3d15cc376077a3631e15bd46", index["conflicting.txt", 1][:oid]
+    assert_equal "4e886e602529caa9ab11d71f86634bd1b6e0de10", index["conflicting.txt", 2][:oid]
+    assert_equal "2bd0a343aeef7a2cf0d158478966a6e587ff3863", index["conflicting.txt", 3][:oid]
+
+    assert_equal "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", index["unchanged.txt", 0][:oid]
+
+    assert index.conflicts?
+  end
+end
+
+class ShallowRepositoryTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("testrepo.git")
+    @shallow_repo = FixtureRepo.from_libgit2("shallow.git")
+  end
+
+  def test_is_shallow
+    refute @repo.shallow?
+    assert @shallow_repo.shallow?
+  end
+end
+
+class RepositoryWriteTest < Rugged::TestCase
+  def setup
+    @source_repo = FixtureRepo.from_rugged("testrepo.git")
+    @repo = FixtureRepo.clone(@source_repo)
+  end
+
+  TEST_CONTENT = "my test data\n"
+  TEST_CONTENT_TYPE = 'blob'
+
+  def test_can_hash_data
+    oid = Rugged::Repository.hash_data(TEST_CONTENT, TEST_CONTENT_TYPE)
+    assert_equal "76b1b55ab653581d6f2c7230d34098e837197674", oid
+  end
+
+  def test_write_to_odb
+    oid = @repo.write(TEST_CONTENT, TEST_CONTENT_TYPE)
+    assert_equal "76b1b55ab653581d6f2c7230d34098e837197674", oid
+    assert @repo.exists?("76b1b55ab653581d6f2c7230d34098e837197674")
+  end
+
+  def test_no_merge_base_between_unrelated_branches
+    info = @repo.rev_parse('HEAD').to_hash
+    baseless = Rugged::Commit.create(@repo, info.merge(:parents => []))
+    assert_nil @repo.merge_base('HEAD', baseless)
+  end
+
+  def test_no_merge_bases_between_unrelated_branches
+    info = @repo.rev_parse('HEAD').to_hash
+    baseless = Rugged::Commit.create(@repo, info.merge(:parents => []))
+    assert_equal [], @repo.merge_bases('HEAD', baseless)
+  end
+
+  def test_default_signature
+    name = 'Rugged User'
+    email = 'rugged at example.com'
+    @repo.config['user.name'] = name
+    @repo.config['user.email'] = email
+    assert_equal name, @repo.default_signature[:name]
+    assert_equal email, @repo.default_signature[:email]
+  end
+
+  def test_ident
+    assert_equal(nil, @repo.ident[:name])
+    assert_equal(nil, @repo.ident[:email])
+
+    @repo.ident = { name: "Other User" }
+    assert_equal("Other User", @repo.ident[:name])
+    assert_equal(nil, @repo.ident[:email])
+
+    @repo.ident = { email: "other at example.com" }
+    assert_equal(nil, @repo.ident[:name])
+    assert_equal("other at example.com", @repo.ident[:email])
+
+    @repo.ident = { name: "Other User", email: "other at example.com" }
+    assert_equal("Other User", @repo.ident[:name])
+    assert_equal("other at example.com", @repo.ident[:email])
+
+    @repo.ident = {}
+    assert_equal(nil, @repo.ident[:name])
+    assert_equal(nil, @repo.ident[:email])
+
+    @repo.ident = { name: "Other User", email: "other at example.com" }
+    @repo.ident = nil
+    assert_equal(nil, @repo.ident[:name])
+    assert_equal(nil, @repo.ident[:email])
+  end
+end
+
+class RepositoryDiscoverTest < Rugged::TestCase
+  def setup
+    @tmpdir = Dir.mktmpdir
+    Dir.mkdir(File.join(@tmpdir, 'foo'))
+  end
+
+  def teardown
+    FileUtils.remove_entry_secure(@tmpdir)
+  end
+
+  def test_discover_false
+    assert_raises Rugged::RepositoryError do
+      Rugged::Repository.discover(@tmpdir)
+    end
+  end
+
+  def test_discover_nested_false
+    assert_raises Rugged::RepositoryError do
+      Rugged::Repository.discover(File.join(@tmpdir, 'foo'))
+    end
+  end
+
+  def test_discover_true
+    repo = Rugged::Repository.init_at(@tmpdir, true)
+    root = Rugged::Repository.discover(@tmpdir)
+    begin
+      assert root.bare?
+      assert_equal repo.path, root.path
+    ensure
+      repo.close
+      root.close
+    end
+  end
+
+  def test_discover_nested_true
+    repo = Rugged::Repository.init_at(@tmpdir, true)
+    root = Rugged::Repository.discover(File.join(@tmpdir, 'foo'))
+    begin
+      assert root.bare?
+      assert_equal repo.path, root.path
+    ensure
+      repo.close
+      root.close
+    end
+  end
+end
+
+class RepositoryInitTest < Rugged::TestCase
+  def setup
+    @tmppath = Dir.mktmpdir
+  end
+
+  def teardown
+    FileUtils.remove_entry_secure(@tmppath)
+  end
+
+  def test_init_bare_false
+    repo = Rugged::Repository.init_at(@tmppath, false)
+    begin
+      refute repo.bare?
+    ensure
+      repo.close
+    end
+  end
+
+  def test_init_bare_true
+    repo = Rugged::Repository.init_at(@tmppath, true)
+    begin
+      assert repo.bare?
+    ensure
+      repo.close
+    end
+  end
+
+  def test_init_bare_truthy
+    repo = Rugged::Repository.init_at(@tmppath, :bare)
+    begin
+      assert repo.bare?
+    ensure
+      repo.close
+    end
+  end
+
+  def test_init_non_bare_default
+    repo = Rugged::Repository.init_at(@tmppath)
+    begin
+      refute repo.bare?
+    ensure
+      repo.close
+    end
+  end
+end
+
+class RepositoryCloneTest < Rugged::TestCase
+  def setup
+    @tmppath = Dir.mktmpdir
+    @source_path = "file://" + File.join(Rugged::TestCase::TEST_DIR, 'fixtures', 'testrepo.git')
+  end
+
+  def teardown
+    FileUtils.remove_entry_secure(@tmppath)
+  end
+
+  def test_clone
+    repo = Rugged::Repository.clone_at(@source_path, @tmppath)
+    begin
+      assert_equal "hey", File.read(File.join(@tmppath, "README")).chomp
+      assert_equal "36060c58702ed4c2a40832c51758d5344201d89a", repo.head.target_id
+      assert_equal "36060c58702ed4c2a40832c51758d5344201d89a", repo.ref("refs/heads/master").target_id
+      assert_equal "36060c58702ed4c2a40832c51758d5344201d89a", repo.ref("refs/remotes/origin/master").target_id
+      assert_equal "41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9", repo.ref("refs/remotes/origin/packed").target_id
+    ensure
+      repo.close
+    end
+  end
+
+  def test_clone_bare
+    repo = Rugged::Repository.clone_at(@source_path, @tmppath, :bare => true)
+    begin
+      assert repo.bare?
+    ensure
+      repo.close
+    end
+  end
+
+  def test_clone_with_transfer_progress_callback
+    total_objects = indexed_objects = received_objects = local_objects = total_deltas = indexed_deltas = received_bytes = nil
+    callsback = 0
+    repo = Rugged::Repository.clone_at(@source_path, @tmppath, {
+      transfer_progress: lambda { |*args|
+        total_objects, indexed_objects, received_objects, local_objects, total_deltas, indexed_deltas, received_bytes = args
+        callsback += 1
+      }
+    })
+    repo.close
+    assert_equal 22,   callsback
+    assert_equal 19,   total_objects
+    assert_equal 19,   indexed_objects
+    assert_equal 19,   received_objects
+    assert_equal 0,    local_objects
+    assert_equal 2,    total_deltas
+    assert_equal 2,    indexed_deltas
+    assert_equal 1563, received_bytes
+  end
+
+
+  def test_clone_with_update_tips_callback
+    calls = 0
+    updated_tips = {}
+
+    repo = Rugged::Repository.clone_at(@source_path, @tmppath, {
+      update_tips: lambda { |refname, a, b|
+        calls += 1
+        updated_tips[refname] = [a, b]
+      }
+    })
+    repo.close
+
+    assert_equal 4, calls
+    assert_equal({
+      "refs/remotes/origin/master" => [nil, "36060c58702ed4c2a40832c51758d5344201d89a"],
+      "refs/remotes/origin/packed" => [nil, "41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9"],
+      "refs/tags/v0.9"             => [nil, "5b5b025afb0b4c913b4c338a42934a3863bf3644"],
+      "refs/tags/v1.0"             => [nil, "0c37a5391bbff43c37f0d0371823a5509eed5b1d"],
+    }, updated_tips)
+  end
+
+  def test_clone_with_branch
+    repo = Rugged::Repository.clone_at(@source_path, @tmppath, {checkout_branch: "packed"})
+    begin
+      assert_equal "what file?\n", File.read(File.join(@tmppath, "second.txt"))
+      assert_equal repo.head.target_id, repo.ref("refs/heads/packed").target_id
+      assert_equal "refs/heads/packed", repo.references["HEAD"].target_id
+    ensure
+      repo.close
+    end
+  end
+
+  def test_clone_quits_on_error
+    begin
+      Rugged::Repository.clone_at(@source_path, @tmppath, {
+        transfer_progress: lambda { |*_| raise 'boom' }
+      })
+    rescue => e
+      assert_equal 'boom', e.message
+    end
+    assert_no_dotgit_dir(@tmppath)
+  end
+
+  def test_clone_with_bad_progress_callback
+    assert_raises ArgumentError do
+      Rugged::Repository.clone_at(@source_path, @tmppath, {
+        transfer_progress: Object.new
+      })
+    end
+    assert_no_dotgit_dir(@tmppath)
+  end
+
+  def assert_no_dotgit_dir(path)
+    assert_equal [], Dir[File.join(path, ".git/**")], "new repository's .git dir should not exist"
+  end
+end
+
+class RepositoryNamespaceTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("testrepo.git")
+  end
+
+  def test_no_namespace
+    assert_nil @repo.namespace
+  end
+
+  def test_changing_namespace
+    @repo.namespace = "foo"
+    assert_equal "foo", @repo.namespace
+
+    @repo.namespace = "bar"
+    assert_equal "bar", @repo.namespace
+
+    @repo.namespace = "foo/bar"
+    assert_equal "foo/bar", @repo.namespace
+
+    @repo.namespace = nil
+    assert_equal nil, @repo.namespace
+  end
+
+  def test_refs_in_namespaces
+    @repo.namespace = "foo"
+    assert_equal [], @repo.refs.to_a
+  end
+end
+
+class RepositoryPushTest < Rugged::TestCase
+  def setup
+    @remote_repo = FixtureRepo.from_libgit2("testrepo.git")
+    # We can only push to bare repos
+    @remote_repo.config['core.bare'] = 'true'
+
+    @repo = FixtureRepo.clone(@remote_repo)
+    @repo.references.create("refs/heads/unit_test",
+      "8496071c1b46c854b31185ea97743be6a8774479")
+  end
+
+  def test_push_single_ref
+    result = @repo.push("origin", ["refs/heads/master", "refs/heads/master:refs/heads/foobar", "refs/heads/unit_test"])
+    assert_equal({}, result)
+
+    assert_equal "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", @remote_repo.ref("refs/heads/foobar").target_id
+    assert_equal "8496071c1b46c854b31185ea97743be6a8774479", @remote_repo.ref("refs/heads/unit_test").target_id
+  end
+
+  def test_push_to_remote_instance
+    result = @repo.push(@repo.remotes["origin"], ["refs/heads/master"])
+    assert_equal({}, result)
+  end
+
+  def test_push_to_non_bare_raise_error
+    @remote_repo.config['core.bare'] = 'false'
+
+    exception = assert_raises Rugged::InvalidError do
+      @repo.push("origin", ["refs/heads/master"])
+    end
+
+    assert_equal "Local push doesn't (yet) support pushing to non-bare repos.", exception.message
+  end
+
+  def test_push_non_forward_raise_error
+    exception = assert_raises Rugged::ReferenceError do
+      @repo.push("origin", ["refs/heads/unit_test:refs/heads/master"])
+    end
+
+    assert_equal "Cannot push non-fastforwardable reference", exception.message
+    assert_equal "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", @remote_repo.ref("refs/heads/master").target_id
+  end
+
+  def test_push_non_forward_forced_raise_no_error
+    result = @repo.push("origin", ["+refs/heads/unit_test:refs/heads/master"])
+    assert_equal({}, result)
+
+    assert_equal "8496071c1b46c854b31185ea97743be6a8774479", @remote_repo.ref("refs/heads/master").target_id
+  end
+end
+
+class RepositoryAttributesTest < Rugged::TestCase
+
+  ATTRIBUTES = <<-ATTR
+*.txt linguist-lang=text
+new.txt other-attr=this
+README is_readme
+ATTR
+
+  def setup
+    @repo = FixtureRepo.from_libgit2("testrepo")
+    @repo.checkout_tree(@repo.rev_parse("refs/heads/dir"), :strategy => :force)
+    IO.write(File.join(@repo.workdir, ".gitattributes"), ATTRIBUTES)
+  end
+
+  def test_read_attributes_internal
+    assert_equal 'text', @repo.fetch_attributes('branch_file.txt', 'linguist-lang')
+    assert_equal 'text', @repo.fetch_attributes('new.txt', 'linguist-lang')
+    assert_equal 'this', @repo.fetch_attributes('new.txt', 'other-attr')
+    assert_equal true, @repo.fetch_attributes('README', 'is_readme')
+    assert_equal nil, @repo.fetch_attributes('README', 'linguist-lang')
+  end
+
+  def test_read_attributes_internal_multi
+    attr_new = { 'linguist-lang' => 'text', 'other-attr' => 'this' }
+    assert_equal attr_new, @repo.fetch_attributes('new.txt', ['linguist-lang', 'other-attr'])
+
+    attr_readme = { 'is_readme' => true, 'other-attr' => nil}
+    assert_equal attr_readme, @repo.fetch_attributes('README', ['is_readme', 'other-attr'])
+  end
+
+  def test_read_attributes_internal_hash
+    attr_new = { 'linguist-lang' => 'text', 'other-attr' => 'this' }
+    assert_equal attr_new, @repo.fetch_attributes('new.txt')
+
+    attr_new = { 'linguist-lang' => 'text' }
+    assert_equal attr_new, @repo.fetch_attributes('branch_file.txt')
+  end
+
+  def test_attributes
+    atr = @repo.attributes('new.txt')
+    assert atr.instance_of? Rugged::Repository::Attributes
+    assert atr.to_h.instance_of? Hash
+
+    assert_equal 'text', atr['linguist-lang']
+    assert_equal 'this', atr['other-attr']
+
+    atr = @repo.attributes('branch_file.txt')
+    assert_equal 'text', atr['linguist-lang']
+    assert_equal nil, atr['other-attr']
+
+    atr.each do |key, value|
+      assert key.instance_of? String
+      assert [String, TrueClass, FalseClass].include? value.class
+    end
+
+    atr = @repo.attributes('new.txt', :priority => [:index])
+    assert_equal nil, atr['linguist-lang']
+    assert_equal nil, atr['linguist-lang']
+  end
+end
+
+class RepositoryCheckoutTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("testrepo")
+    @clone = FixtureRepo.clone(@repo)
+
+    _bare = FixtureRepo.from_libgit2("testrepo.git")
+    @bare = Rugged::Repository.bare(_bare.path)
+    _bare.close
+  end
+
+  def verify_dir
+    assert File.exist?(File.join(@repo.workdir, "README"))
+    assert File.exist?(File.join(@repo.workdir, "branch_file.txt"))
+    assert File.exist?(File.join(@repo.workdir, "new.txt"))
+    assert File.exist?(File.join(@repo.workdir, "a/b.txt"))
+
+    refute File.exist?(File.join(@repo.workdir, "ab"))
+  end
+
+  def verify_subtrees
+    assert File.exist?(File.join(@repo.workdir, "README"))
+    assert File.exist?(File.join(@repo.workdir, "branch_file.txt"))
+    assert File.exist?(File.join(@repo.workdir, "new.txt"))
+    assert File.exist?(File.join(@repo.workdir, "ab/4.txt"))
+    assert File.exist?(File.join(@repo.workdir, "ab/c/3.txt"))
+    assert File.exist?(File.join(@repo.workdir, "ab/de/2.txt"))
+    assert File.exist?(File.join(@repo.workdir, "ab/de/fgh/1.txt"))
+
+    refute File.exist?(File.join(@repo.workdir, "a"))
+  end
+
+  def test_checkout_tree_with_commit
+    @repo.checkout_tree(@repo.rev_parse("refs/heads/dir"), :strategy => :force)
+    @repo.head = "refs/heads/dir"
+    verify_dir
+
+    @repo.checkout_tree(@repo.rev_parse("refs/heads/subtrees"), :strategy => :safe)
+    @repo.head = "refs/heads/subtrees"
+    verify_subtrees
+  end
+
+  def test_checkout_with_revspec_string
+    @repo.checkout_tree("refs/heads/dir", :strategy => :force)
+    @repo.head = "refs/heads/dir"
+    verify_dir
+  end
+
+  def test_checkout_tree_with_index
+    index = @repo.index
+    head = @repo.references["refs/heads/dir"]
+    index.read_tree head.target.tree
+    @repo.checkout_index(index, :strategy => :force)
+    @repo.head = "refs/heads/dir"
+    verify_dir
+  end
+
+  def test_checkout_tree_raises_errors_in_notify_cb
+    exception = assert_raises RuntimeError do
+      @repo.checkout_tree(@repo.rev_parse("refs/heads/dir"), :strategy => :force,
+        :notify_flags => :all,
+        :notify => lambda { |*args| raise "fail" })
+    end
+
+    assert_equal exception.message, "fail"
+  end
+
+  def test_checkout_tree_raises_errors_in_progress_cb
+    exception = assert_raises RuntimeError do
+      @repo.checkout_tree(@repo.rev_parse("refs/heads/dir"), :strategy => :force,
+        :progress => lambda { |*args| raise "fail" })
+    end
+
+    assert_equal exception.message, "fail"
+  end
+
+  def test_checkout_tree_subdirectory
+    refute File.exist?(File.join(@repo.workdir, "ab"))
+
+    @repo.checkout_tree(@repo.rev_parse("refs/heads/subtrees"), :strategy => :safe, :paths => "ab/de/")
+
+    assert File.exist?(File.join(@repo.workdir, "ab"))
+    assert File.exist?(File.join(@repo.workdir, "ab/de/2.txt"))
+    assert File.exist?(File.join(@repo.workdir, "ab/de/fgh/1.txt"))
+  end
+
+  def test_checkout_tree_subtree_directory
+    refute File.exist?(File.join(@repo.workdir, "de"))
+
+    @repo.checkout_tree(@repo.rev_parse("refs/heads/subtrees:ab"), :strategy => :safe, :paths => "de/")
+
+    assert File.exist?(File.join(@repo.workdir, "de"))
+    assert File.exist?(File.join(@repo.workdir, "de/2.txt"))
+    assert File.exist?(File.join(@repo.workdir, "de/fgh/1.txt"))
+  end
+
+  def test_checkout_tree_raises_with_bare_repo
+    assert_raises Rugged::RepositoryError do
+      @bare.checkout_tree("HEAD", :strategy => :safe)
+    end
+  end
+
+  def test_checkout_tree_works_with_bare_repo_and_target_directory
+    Dir.mktmpdir("alternative") do |dir|
+      @bare.checkout_tree("HEAD", :strategy => [:safe, :recreate_missing], :target_directory => dir)
+
+      assert File.exist?(File.join(dir, "README"))
+      assert File.exist?(File.join(dir, "new.txt"))
+    end
+  end
+
+  def test_checkout_with_branch_updates_HEAD
+    @repo.checkout("dir", :strategy => :force)
+    assert_equal "refs/heads/dir", @repo.head.name
+  end
+
+  def test_checkout_with_HEAD
+    @repo.checkout("dir", :strategy => :force)
+    File.unlink(File.join(@repo.workdir, "README"))
+
+    @repo.checkout("HEAD", :strategy => :force)
+
+    assert File.exist?(File.join(@repo.workdir, "README"))
+    assert_equal "refs/heads/dir", @repo.head.name
+  end
+
+  def test_checkout_with_commit_detaches_HEAD
+    @repo.checkout(@repo.rev_parse_oid("refs/heads/dir"), :strategy => :force)
+
+    assert @repo.head_detached?
+    assert_equal @repo.rev_parse_oid("refs/heads/dir"), @repo.head.target_id
+  end
+
+  def test_checkout_with_remote_branch_detaches_HEAD
+    @clone.checkout("origin/dir", :strategy => :force)
+
+    assert @clone.head_detached?
+    assert_equal @clone.rev_parse_oid("refs/remotes/origin/dir"), @clone.head.target_id
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/status_test.rb b/app/server/vendor/rugged-0.23.3/test/status_test.rb
new file mode 100755
index 0000000..057335b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/status_test.rb
@@ -0,0 +1,52 @@
+# encoding: UTF-8
+require "test_helper"
+
+class LibgitRepositoryStatusTest < Rugged::TestCase
+  STATUSES = {
+    "staged_changes" => [:index_modified],
+    "staged_changes_file_deleted" => [:index_modified, :worktree_deleted],
+    "staged_changes_modified_file" => [:index_modified, :worktree_modified],
+    "staged_delete_file_deleted" => [:index_deleted],
+    "staged_delete_modified_file" => [:index_deleted, :worktree_new],
+    "staged_new_file" => [:index_new],
+    "staged_new_file_deleted_file" => [:index_new, :worktree_deleted],
+    "staged_new_file_modified_file" => [:index_new, :worktree_modified],
+    "file_deleted" => [:worktree_deleted],
+    "modified_file" => [:worktree_modified],
+    "new_file" => [:worktree_new],
+    "ignored_file" => [:ignored],
+    "subdir/deleted_file" => [:worktree_deleted],
+    "subdir/modified_file" => [:worktree_modified],
+    "subdir/new_file" => [:worktree_new],
+    "\xe8\xbf\x99" => [:worktree_new]
+  }
+
+  STATUSES.each do |file,expected_statuses|
+    name = "test_" + file.gsub("/", "__")
+    define_method name do
+      actual_status = @repo.status file
+      assert_equal expected_statuses, actual_status
+    end
+  end
+
+  def setup
+    @repo = FixtureRepo.from_libgit2 "status"
+  end
+
+  def test_status_with_callback
+    actual_statuses = {}
+    @repo.status do |file, status|
+      assert_nil actual_statuses[file]
+      actual_statuses[file] = status
+      assert_equal STATUSES[file], actual_statuses[file]
+    end
+    assert_equal STATUSES, actual_statuses
+  end
+
+  def test_status_with_invalid_file_path
+    invalid_file = "something_that_doesnt_exist"
+    assert_raises Rugged::InvalidError do
+      @repo.status(invalid_file)
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/submodule_test.rb b/app/server/vendor/rugged-0.23.3/test/submodule_test.rb
new file mode 100755
index 0000000..fd99799
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/submodule_test.rb
@@ -0,0 +1,319 @@
+require 'test_helper'
+
+class SubmoduleTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2('submod2').tap do |repo|
+      Dir.chdir(repo.workdir) do
+        File.rename(
+          File.join('not-submodule', '.gitted'),
+          File.join('not-submodule', '.git')
+        )
+
+        File.rename(
+          File.join('not', '.gitted'),
+          File.join('not', '.git')
+        )
+      end
+    end
+  end
+
+  class TestException < StandardError
+  end
+
+  def test_submodule_simple_lookup
+    # lookup pending change in .gitmodules that is not in HEAD
+    assert @repo.submodules['sm_added_and_uncommited']
+
+    # lookup pending change in .gitmodules that is neither in HEAD nor index
+    assert @repo.submodules['sm_gitmodules_only']
+
+    # lookup git repo subdir that is not added as submodule */
+    assert_raises Rugged::SubmoduleError do
+      assert @repo.submodules['not-submodule']
+    end
+
+    # lookup existing directory that is not a submodule
+    assert_nil @repo.submodules['just_a_dir']
+
+    # lookup existing file that is not a submodule
+    assert_nil @repo.submodules['just_a_file']
+
+    # lookup non-existent item
+    assert_nil @repo.submodules['no_such_file']
+  end
+
+  def test_submodule_attribute_getters
+    # unchanged
+    submodule = @repo.submodules['sm_unchanged']
+    oid = "480095882d281ed676fe5b863569520e54a7d5c0"
+
+    submodule_repo = submodule.repository
+    assert_instance_of Rugged::Repository, submodule_repo
+
+    assert :none, submodule.ignore_rule
+    assert submodule.path.end_with?('sm_unchanged')
+    #assert submodule.url.end_with?('submod2_target')
+    assert_equal 'sm_unchanged', submodule.name
+
+    assert_equal oid, submodule.head_oid
+    assert_equal oid, submodule.index_oid
+    assert_equal oid, submodule.workdir_oid
+
+    # changed head
+    submodule = @repo.submodules['sm_changed_head']
+
+    assert_equal 'sm_changed_head', submodule.name
+    assert_equal oid, submodule.head_oid
+    assert_equal oid, submodule.index_oid
+    assert_equal '3d9386c507f6b093471a3e324085657a3c2b4247', submodule.workdir_oid
+
+    # added and uncommited
+    submodule = @repo.submodules['sm_added_and_uncommited']
+
+    assert_equal 'sm_added_and_uncommited', submodule.name
+    assert_nil submodule.head_oid
+    assert_equal oid, submodule.index_oid
+    assert_equal oid, submodule.workdir_oid
+
+    # missing commits
+    submodule = @repo.submodules['sm_missing_commits']
+    assert_equal 'sm_missing_commits', submodule.name
+    assert_equal oid, submodule.head_oid
+    assert_equal oid, submodule.index_oid
+    assert_equal '5e4963595a9774b90524d35a807169049de8ccad', submodule.workdir_oid
+
+    # status checks
+    submodule = @repo.submodules['sm_unchanged']
+
+    expected = [:in_head, :in_index, :in_config, :in_workdir]
+    assert_equal expected, submodule.status
+    assert submodule.in_head?
+    assert submodule.in_index?
+    assert submodule.in_config?
+    assert submodule.in_workdir?
+    assert submodule.unmodified?
+    refute submodule.dirty_workdir?
+  end
+
+  def test_submodule_each
+    assert @repo.submodules.kind_of? Enumerable
+    assert_instance_of Enumerator, @repo.submodules.each
+
+    @repo.submodules.each do |submodule|
+      assert_equal :none, submodule.ignore_rule
+      assert submodule.name
+      assert submodule.url
+      assert submodule.path
+    end
+
+    # test error handling in callback
+    assert_raises TestException do
+      @repo.submodules.each do |submodule|
+        raise TestException
+      end
+    end
+  end
+
+  def test_submodule_status_ignore_none
+    submodule = @repo.submodules['sm_changed_index']
+    assert_includes submodule.status, :dirty_workdir_index
+    assert submodule.dirty_workdir_index?
+
+    submodule = @repo.submodules['sm_changed_head']
+    assert_includes submodule.status, :modified_in_workdir
+    assert submodule.modified_in_workdir?
+
+    submodule = @repo.submodules['sm_changed_file']
+    assert_includes submodule.status, :modified_files_in_workdir
+    assert submodule.modified_files_in_workdir?
+    assert submodule.dirty_workdir?
+    refute submodule.unmodified?
+
+    submodule = @repo.submodules['sm_changed_untracked_file']
+    assert_includes submodule.status, :untracked_files_in_workdir
+    assert submodule.untracked_files_in_workdir?
+
+    submodule = @repo.submodules['sm_missing_commits']
+    assert_includes submodule.status, :modified_in_workdir
+    assert submodule.modified_in_workdir?
+
+    submodule = @repo.submodules['sm_added_and_uncommited']
+    assert_includes submodule.status, :added_to_index
+    assert submodule.added_to_index?
+
+    sm_unchanged_path = File.join(@repo.workdir, 'sm_unchanged')
+
+    # removed sm_unchanged for deleted workdir
+    FileUtils.remove_entry_secure(sm_unchanged_path)
+    submodule = @repo.submodules['sm_unchanged']
+    assert_includes submodule.status, :deleted_from_workdir
+    assert submodule.deleted_from_workdir?
+
+    # now mkdir sm_unchanged to test uninitialized
+    FileUtils.mkdir(sm_unchanged_path, :mode => 0755)
+    submodule = @repo.submodules['sm_unchanged']
+    assert_includes submodule.status, :uninitialized
+    assert submodule.uninitialized?
+
+    # update sm_changed_head in index
+    submodule = @repo.submodules['sm_changed_head']
+    submodule.add_to_index(write_index: true)
+    assert_includes submodule.status, :modified_in_index
+    assert submodule.modified_in_index?
+
+    # remove sm_changed_head from index
+    index = @repo.index
+    index.remove('sm_changed_head')
+    index.write
+
+    submodule = @repo.submodules['sm_changed_head']
+    assert_includes submodule.status, :deleted_from_index
+    assert submodule.deleted_from_index?
+  end
+
+  def test_submodule_update_ignore_rule
+    sm_unchanged_path = File.join(@repo.workdir, 'sm_unchanged')
+    # removed sm_unchanged for deleted workdir
+    FileUtils.remove_entry_secure(sm_unchanged_path)
+
+    # untracked
+    @repo.submodules.update('sm_changed_untracked_file', ignore_rule: :untracked)
+    submodule = @repo.submodules['sm_changed_untracked_file']
+
+    assert submodule.unmodified?
+    refute submodule.untracked_files_in_workdir?
+
+    #dirty
+    @repo.submodules.update('sm_changed_file', ignore_rule: :dirty)
+    submodule = @repo.submodules['sm_changed_file']
+
+    refute submodule.modified_files_in_workdir?
+
+    #all
+    @repo.submodules.update('sm_added_and_uncommited', ignore_rule: :all)
+    submodule = @repo.submodules['sm_added_and_uncommited']
+
+    assert submodule.unmodified?
+    refute submodule.added_to_index?
+  end
+
+  def test_submodule_update
+    url = 'https://github.com/libgit2/libgit2.git'
+    submodule = @repo.submodules['sm_changed_head']
+
+    refute submodule.fetch_recurse_submodules?
+
+    @repo.submodules.update(submodule, {
+      url: url,
+      ignore_rule: :untracked,
+      fetch_recurse_submodules: true
+    })
+
+    submodule.reload
+
+    assert_equal :untracked, submodule.ignore_rule
+    assert_equal url, submodule.url
+    assert submodule.fetch_recurse_submodules?
+  end
+
+  def test_submodule_update_update_rule
+    submodule = @repo.submodules['sm_unchanged']
+    assert_equal :checkout, submodule.update_rule
+
+    @repo.submodules.update('sm_unchanged', update_rule: :rebase)
+    submodule.reload
+    assert_equal :rebase, submodule.update_rule
+
+    @repo.submodules.update('sm_unchanged', update_rule: :merge)
+    submodule.reload
+    assert_equal :merge, submodule.update_rule
+
+    @repo.submodules.update('sm_unchanged', update_rule: :none)
+    submodule.reload
+    assert_equal :none, submodule.update_rule
+  end
+
+  def test_submodule_sync
+    submodule = @repo.submodules['sm_unchanged']
+
+    # At this point, the .git/config URLs for the submodules have
+    # not be rewritten with the absolute paths (although the
+    # .gitmodules have.  Let's confirm that they DO NOT match
+    # yet, then we can do a sync to make them match...
+    refute_equal submodule.url, @repo.config['submodule.sm_unchanged.url']
+
+    submodule.sync
+
+    assert_equal submodule.url, @repo.config['submodule.sm_unchanged.url']
+  end
+
+  def test_submodule_init
+    submodule = @repo.submodules['sm_unchanged']
+
+    #erase submodule data from .git/config
+    @repo.config.delete('submodule.sm_unchanged.url')
+
+    # confirm no submodule data in config
+    assert_nil @repo.config['submodule.sm_unchanged.url']
+
+    # call init and see that settings are copied. Call it twice, just to check
+    # if it accepts the overwrite flag and that it's optional
+    submodule.init(overwrite: true)
+    submodule.init
+
+    submodule.reload
+
+    # confirm submodule data in config
+    assert_equal submodule.url, @repo.config['submodule.sm_unchanged.url']
+  end
+
+  def test_submodule_setup_add
+    url = 'https://github.com/libgit2/libgit2.git'
+    submod_path = 'sm_libgit2'
+    second_submod_path = 'sm2_libgit2'
+
+    # re-add existing submodule
+    assert_raises Rugged::SubmoduleError do
+      @repo.submodules.setup_add('whatever', 'sm_unchanged')
+    end
+
+    # add a submodule using gitlink by default
+    submodule = @repo.submodules.setup_add(url, submod_path)
+
+    assert File.file?(File.join(@repo.workdir, submod_path, '.git'))
+    assert File.directory?(File.join(@repo.path, 'modules'))
+    assert File.directory?(File.join(@repo.path, 'modules', submod_path))
+    assert File.file?(File.join(@repo.path, 'modules', submod_path, 'HEAD'))
+
+    assert_equal url, @repo.config["submodule.#{submod_path}.url"]
+
+    submodule = @repo.submodules.setup_add(url, second_submod_path, gitlink: false)
+
+    assert File.directory?(File.join(@repo.workdir, second_submod_path, '.git'))
+    refute File.exist?(File.join(@repo.path, 'modules', second_submod_path))
+    assert_equal url, @repo.config["submodule.#{submod_path}.url"]
+  end
+
+  def test_submodule_add
+    url = File.join(Rugged::TestCase::TEST_DIR, 'fixtures', 'testrepo.git')
+    submod_path = 'sm_test_repo'
+
+    callback_called = false
+    update_tips_cb =  proc { callback_called = true }
+
+    submodule = @repo.submodules.add(url, submod_path, update_tips: update_tips_cb)
+
+    # options are passed to remote fetch
+    assert callback_called
+
+    # submodule repo is initialized
+    assert File.file?(File.join(@repo.workdir, submod_path, '.git'))
+
+    # submodule repo is checked out
+    assert File.file?(File.join(@repo.workdir, submod_path, 'README'))
+
+    # sets up master as a remote tracking branch
+    assert submodule.repository.branches['master']
+    assert_equal 'origin/master', submodule.repository.branches['master'].upstream.name
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/tag_test.rb b/app/server/vendor/rugged-0.23.3/test/tag_test.rb
new file mode 100755
index 0000000..16c5008
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/tag_test.rb
@@ -0,0 +1,230 @@
+require "test_helper"
+
+class TagTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("testrepo.git")
+  end
+
+  def test_lookup_raises_error_if_object_type_does_not_match
+    assert_raises Rugged::InvalidError do
+      # blob
+      Rugged::Tag::Annotation.lookup(@repo, "fa49b077972391ad58037050f2a75f74e3671e92")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # commit
+      Rugged::Tag::Annotation.lookup(@repo, "8496071c1b46c854b31185ea97743be6a8774479")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # tree
+      Rugged::Tag::Annotation.lookup(@repo, "181037049a54a1eb5fab404658a3a250b44335d7")
+    end
+
+    subclass = Class.new(Rugged::Tag::Annotation)
+
+    assert_raises Rugged::InvalidError do
+      # blob
+      subclass.lookup(@repo, "fa49b077972391ad58037050f2a75f74e3671e92")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # commit
+      subclass.lookup(@repo, "8496071c1b46c854b31185ea97743be6a8774479")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # tree
+      subclass.lookup(@repo, "181037049a54a1eb5fab404658a3a250b44335d7")
+    end
+  end
+
+  def test_reading_a_tag
+    oid = "7b4384978d2493e851f9cca7858815fac9b10980"
+    obj = @repo.lookup(oid)
+
+    assert_equal oid, obj.oid
+    assert_equal :tag, obj.type
+    assert_equal "This is a very simple tag.\n", obj.message
+    assert_equal "e90810b", obj.name
+    assert_equal "e90810b8df3e80c413d903f631643c716887138d", obj.target.oid
+    assert_equal :commit, obj.target_type
+    c = obj.tagger
+    assert_equal "Vicent Marti", c[:name]
+    assert_equal 1281578357, c[:time].to_i
+    assert_equal "tanoku at gmail.com", c[:email]
+  end
+
+  def test_reading_the_oid_of_a_tag
+    oid = "7b4384978d2493e851f9cca7858815fac9b10980"
+    obj = @repo.lookup(oid)
+
+    assert_equal "e90810b8df3e80c413d903f631643c716887138d", obj.target_oid
+  end
+
+  def test_lookup
+    tag = @repo.tags["e90810b"]
+
+    assert_equal tag.name, "e90810b"
+    assert_equal tag.canonical_name, "refs/tags/e90810b"
+  end
+
+  def test_lookup_git_compliance
+    @repo.tags.create("refs/tags/v2.0", "e90810b8df3e80c413d903f631643c716887138d")
+
+    assert_nil @repo.tags["v2.0"]
+    assert_equal "refs/tags/refs/tags/v2.0", @repo.tags["refs/tags/v2.0"].canonical_name
+    assert_equal "refs/tags/refs/tags/v2.0", @repo.tags["refs/tags/refs/tags/v2.0"].canonical_name
+
+    @repo.tags.create("v2.0", "e90810b8df3e80c413d903f631643c716887138d")
+
+    assert_equal "refs/tags/v2.0", @repo.tags["v2.0"].canonical_name
+    assert_equal "refs/tags/v2.0", @repo.tags["refs/tags/v2.0"].canonical_name
+    assert_equal "refs/tags/refs/tags/v2.0", @repo.tags["refs/tags/refs/tags/v2.0"].canonical_name
+  end
+
+  def test_each
+    tags = @repo.tags.each.sort_by(&:name)
+
+    assert_equal tags.count, 7
+    assert_equal tags[0].name, "annotated_tag_to_blob"
+    assert_equal tags[1].name, "e90810b"
+  end
+
+  def test_each_name
+    tag_names = @repo.tags.each_name.sort
+
+    assert_equal tag_names.count, 7
+    assert_equal tag_names[0], "annotated_tag_to_blob"
+    assert_equal tag_names[1], "e90810b"
+  end
+end
+
+class AnnotatedTagTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("testrepo.git")
+    @tag = @repo.tags.create('annotated_tag', "5b5b025afb0b4c913b4c338a42934a3863bf3644", {
+      :message => "test tag message\n",
+      :tagger  => { :name => 'Scott', :email => 'schacon at gmail.com', :time => Time.now }
+    })
+  end
+
+  def test_is_annotated
+    assert_equal true, @tag.annotated?
+  end
+
+  def test_annotation
+    annotation = @tag.annotation
+
+    assert_kind_of Rugged::Tag::Annotation, annotation
+    assert_equal "test tag message\n", annotation.message
+    assert_equal 'Scott', annotation.tagger[:name]
+    assert_equal 'schacon at gmail.com', annotation.tagger[:email]
+    assert_kind_of Time, annotation.tagger[:time]
+  end
+
+  def test_target
+    target = @tag.target
+
+    assert_kind_of Rugged::Commit, target
+    assert_equal "5b5b025afb0b4c913b4c338a42934a3863bf3644", target.oid
+  end
+end
+
+class AnnotatedTagObjectTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("testrepo.git")
+    @annotation = @repo.tags.create_annotation("my-tag", "5b5b025afb0b4c913b4c338a42934a3863bf3644", {
+      :message => "test tag message\n",
+      :tagger  => { :name => "Scott", :email => "schacon at gmail.com", :time => Time.now },
+    })
+  end
+
+  def test_annotation
+    assert_kind_of Rugged::Tag::Annotation, @annotation
+    assert_equal "test tag message\n", @annotation.message
+    assert_equal 'Scott', @annotation.tagger[:name]
+    assert_equal 'schacon at gmail.com', @annotation.tagger[:email]
+    assert_kind_of Time, @annotation.tagger[:time]
+  end
+
+  def test_does_not_create_ref
+    assert_nil @repo.tags["my-tag"]
+  end
+
+  def test_target
+    assert_kind_of Rugged::Commit, @annotation.target
+    assert_equal "5b5b025afb0b4c913b4c338a42934a3863bf3644", @annotation.target.oid
+  end
+end
+
+class LightweightTagTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_libgit2("testrepo.git")
+    @tag = @repo.tags.create('lightweight_tag', "5b5b025afb0b4c913b4c338a42934a3863bf3644")
+  end
+
+  def test_is_not_annotated
+    assert_equal false, @tag.annotated?
+  end
+
+  def test_has_no_annotation
+    assert_nil @tag.annotation
+  end
+
+  def test_target
+    target = @tag.target
+
+    assert_kind_of Rugged::Commit, target
+    assert_equal "5b5b025afb0b4c913b4c338a42934a3863bf3644", target.oid
+  end
+end
+
+class TagWriteTest < Rugged::TestCase
+  def setup
+    @source_repo = FixtureRepo.from_rugged("testrepo.git")
+    @repo = FixtureRepo.clone(@source_repo)
+  end
+
+  def test_writing_a_tag
+    tag = @repo.tags.create('tag', "5b5b025afb0b4c913b4c338a42934a3863bf3644", {
+      :message => "test tag message\n",
+      :tagger  => { :name => 'Scott', :email => 'schacon at gmail.com', :time => Time.now }
+    })
+
+    annotation = tag.annotation
+    assert_equal :tag, annotation.type
+    assert_equal "5b5b025afb0b4c913b4c338a42934a3863bf3644", annotation.target.oid
+    assert_equal "test tag message\n", annotation.message
+    assert_equal "Scott", annotation.tagger[:name]
+    assert_equal "schacon at gmail.com", annotation.tagger[:email]
+  end
+
+  def test_writing_a_tag_without_signature
+    name = 'Rugged User'
+    email = 'rugged at example.com'
+    @repo.config['user.name'] = name
+    @repo.config['user.email'] = email
+
+    tag = @repo.tags.create('tag', "5b5b025afb0b4c913b4c338a42934a3863bf3644", {
+      :message => "test tag message\n"
+    })
+
+    assert_equal name, tag.annotation.tagger[:name]
+    assert_equal email, tag.annotation.tagger[:email]
+  end
+
+  def test_tag_invalid_message_type
+    assert_raises TypeError do
+      @repo.tags.create('tag', "5b5b025afb0b4c913b4c338a42934a3863bf3644", {
+        :message => :invalid_message,
+        :tagger  => {:name => 'Scott', :email => 'schacon at gmail.com', :time => Time.now }
+      })
+    end
+  end
+
+  def test_writing_light_tags
+    tag = @repo.tags.create('tag', "5b5b025afb0b4c913b4c338a42934a3863bf3644")
+    assert_equal @repo.lookup("5b5b025afb0b4c913b4c338a42934a3863bf3644"), tag.target
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/test_helper.rb b/app/server/vendor/rugged-0.23.3/test/test_helper.rb
new file mode 100755
index 0000000..5c92049
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/test_helper.rb
@@ -0,0 +1,171 @@
+require 'tempfile'
+require 'tmpdir'
+require 'minitest/autorun'
+require 'rugged'
+require 'pp'
+
+module Rugged
+  class TestCase < MiniTest::Unit::TestCase
+    # Automatically clean up created fixture repos after each test run
+    def after_teardown
+      Rugged::TestCase::FixtureRepo.teardown
+      super
+    end
+
+    module FixtureRepo
+      # Create a new, empty repository.
+      def self.empty(*args)
+        path = Dir.mktmpdir("rugged-empty")
+        ensure_cleanup(path)
+        Rugged::Repository.init_at(path, *args)
+      end
+
+      # Create a repository based on a rugged fixture repo.
+      def self.from_rugged(name, *args)
+        path = Dir.mktmpdir("rugged-#{name}")
+        ensure_cleanup(path)
+
+        FileUtils.cp_r(File.join(TestCase::TEST_DIR, "fixtures", name, "."), path)
+
+        prepare(path)
+
+        Rugged::Repository.new(path, *args).tap do |repo|
+          rewrite_gitmodules(repo) unless repo.bare?
+        end
+      end
+
+      # Create a repository based on a libgit2 fixture repo.
+      def self.from_libgit2(name, *args)
+        path = Dir.mktmpdir("rugged-libgit2-#{name}")
+        ensure_cleanup(path)
+
+        FileUtils.cp_r(File.join(TestCase::LIBGIT2_FIXTURE_DIR, name, "."), path)
+
+        prepare(path)
+
+        Rugged::Repository.new(path, *args).tap do |repo|
+          rewrite_gitmodules(repo) unless repo.bare?
+        end
+      end
+
+      # Create a repository cloned from another Rugged::Repository instance.
+      def self.clone(repository)
+        path = Dir.mktmpdir("rugged")
+        ensure_cleanup(path)
+
+        `git clone --quiet -- #{repository.path} #{path}`
+
+        Rugged::Repository.new(path)
+      end
+
+      def self.prepare(path)
+        Dir.chdir(path) do
+          File.rename(".gitted", ".git") if File.exist?(".gitted")
+          File.rename("gitattributes", ".gitattributes") if File.exist?("gitattributes")
+          File.rename("gitignore", ".gitignore") if File.exist?("gitignore")
+        end
+      end
+
+      # Rugged reuses libgit2 fixtures and needs the same setup code.
+      #
+      # This should be the same as the libgit2 fixture
+      # setup in vendor/libgit2/tests/submodule/submodule_helpers.c
+      def self.rewrite_gitmodules(repo)
+        workdir = repo.workdir
+
+        return unless File.exist?(File.join(workdir, 'gitmodules'))
+
+        input_path = File.join(workdir, 'gitmodules')
+        output_path = File.join(workdir, '.gitmodules')
+        submodules = []
+
+        File.open(input_path, 'r') do |input|
+          File.open(output_path, 'w') do |output|
+            input.each_line do |line|
+              if %r{path = (?<submodule>.+$)} =~ line
+                submodules << submodule.strip
+              elsif %r{url = \.\.\/(?<url>.+$)} =~ line
+                # Copy repositories pointed to by relative urls
+                # and replace the relative url by the absolute path to the
+                # copied repo.
+                url.strip!
+                path = Dir.mktmpdir(url)
+                ensure_cleanup(path)
+                FileUtils.cp_r(File.join(TestCase::LIBGIT2_FIXTURE_DIR, url, "."), path)
+
+                line = "url = #{path}\n"
+              end
+              output.write(line)
+            end
+          end
+        end
+
+        FileUtils.remove_entry_secure(input_path)
+
+        # rename .gitted -> .git in submodule dirs
+        submodules.each do |submodule|
+          submodule_path = File.join(workdir, submodule)
+          if File.exist?(File.join(submodule_path, '.gitted'))
+            Dir.chdir(submodule_path) do
+              File.rename('.gitted', '.git')
+            end
+          end
+        end
+      end
+
+      # Delete temp directories that got created
+      def self.teardown
+        self.directories.each { |path| FileUtils.remove_entry_secure(path) }
+        self.directories.clear
+      end
+
+      def self.directories
+        @directories ||= []
+      end
+
+      # Registers the given +path+ to be deleted when #teardown is called.
+      def self.ensure_cleanup(path)
+        self.directories << path
+      end
+    end
+
+    TEST_DIR = File.dirname(File.expand_path(__FILE__))
+    LIBGIT2_FIXTURE_DIR = File.expand_path("../../vendor/libgit2/tests/resources", __FILE__)
+  end
+
+  class OnlineTestCase < TestCase
+    if ENV['GITTEST_REMOTE_REPO_PATH']
+      def before_setup
+        remote_repo = Rugged::Repository.new(ENV['GITTEST_REMOTE_REPO_PATH'])
+        remote_repo.references.each do |ref|
+          remote_repo.references.delete(ref)
+        end
+
+        super
+      end
+    end
+
+    def self.ssh_creds?
+      %w{URL USER KEY PUBKEY PASSPHRASE}.all? { |key| ENV["GITTEST_REMOTE_SSH_#{key}"] }
+    end
+
+    def self.git_creds?
+      ENV['GITTEST_REMOTE_GIT_URL']
+    end
+
+    def ssh_key_credential
+      Rugged::Credentials::SshKey.new({
+        username:   ENV["GITTEST_REMOTE_SSH_USER"],
+        publickey:  ENV["GITTEST_REMOTE_SSH_PUBKEY"],
+        privatekey: ENV["GITTEST_REMOTE_SSH_KEY"],
+        passphrase: ENV["GITTEST_REMOTE_SSH_PASSPHASE"],
+      })
+    end
+
+    def ssh_key_credential_from_agent
+      Rugged::Credentials::SshKeyFromAgent.new({
+        username: ENV["GITTEST_REMOTE_SSH_USER"]
+      })
+    end
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/tree_test.rb b/app/server/vendor/rugged-0.23.3/test/tree_test.rb
new file mode 100755
index 0000000..c5681db
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/tree_test.rb
@@ -0,0 +1,132 @@
+require "test_helper"
+
+class TreeTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_rugged("testrepo.git")
+    @oid = "c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b"
+    @tree = @repo.lookup(@oid)
+  end
+
+  def test_lookup_raises_error_if_object_type_does_not_match
+    assert_raises Rugged::InvalidError do
+      # blob
+      Rugged::Tree.lookup(@repo, "fa49b077972391ad58037050f2a75f74e3671e92")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # commit
+      Rugged::Tree.lookup(@repo, "8496071c1b46c854b31185ea97743be6a8774479")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # tag
+      Rugged::Tree.lookup(@repo, "0c37a5391bbff43c37f0d0371823a5509eed5b1d")
+    end
+
+    subclass = Class.new(Rugged::Tree)
+
+    assert_raises Rugged::InvalidError do
+      # blob
+      subclass.lookup(@repo, "fa49b077972391ad58037050f2a75f74e3671e92")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # commit
+      subclass.lookup(@repo, "8496071c1b46c854b31185ea97743be6a8774479")
+    end
+
+    assert_raises Rugged::InvalidError do
+      # tag
+      subclass.lookup(@repo, "0c37a5391bbff43c37f0d0371823a5509eed5b1d")
+    end
+  end
+
+  def test_read_tree_data
+    assert_equal @oid, @tree.oid
+    assert_equal :tree, @tree.type
+    assert_equal 3, @tree.count
+    assert_equal 6, @tree.count_recursive
+    assert_equal 5, @tree.count_recursive(5)
+    assert_equal 6, @tree.count_recursive(10)
+    assert_raises(TypeError) do
+      @tree.count_recursive("NaN")
+    end
+    assert_equal "1385f264afb75a56a5bec74243be9b367ba4ca08", @tree[0][:oid]
+    assert_equal "fa49b077972391ad58037050f2a75f74e3671e92", @tree[1][:oid]
+  end
+
+  def test_read_tree_entry_data
+    bent = @tree[0]
+    tent = @tree[2]
+
+    assert_equal "README", bent[:name]
+    assert_equal :blob, bent[:type]
+    # assert_equal 33188, bent.attributes
+
+    assert_equal "subdir", tent[:name]
+    assert_equal :tree, tent[:type]
+    assert_equal "619f9935957e010c419cb9d15621916ddfcc0b96", tent[:oid]
+    assert_equal :tree, @repo.lookup(tent[:oid]).type
+  end
+
+  def test_get_entry_by_oid
+    bent = @tree.get_entry_by_oid("1385f264afb75a56a5bec74243be9b367ba4ca08")
+    assert_equal "README", bent[:name]
+    assert_equal :blob, bent[:type]
+  end
+
+  def test_get_entry_by_oid_returns_nil_if_no_oid
+    nada = @tree.get_entry_by_oid("1385f264afb75a56a5bec74243be9b367ba4ca07")
+    assert_equal nil, nada
+  end
+
+  def test_get_entry_by_oid_throws_error_if_wrong_type
+    assert_raises TypeError do
+      @tree.get_entry_by_oid(:not_a_string)
+    end
+  end
+
+  def test_tree_iteration
+    enum_test = @tree.sort { |a, b| a[:oid] <=> b[:oid] }.map { |e| e[:name] }.join(':')
+    assert_equal "README:subdir:new.txt", enum_test
+
+    enum = @tree.each
+    assert enum.kind_of? Enumerable
+  end
+
+  def test_tree_walk_only_trees
+    @tree.walk_trees {|root, entry| assert_equal :tree, entry[:type]}
+  end
+
+  def test_tree_walk_only_blobs
+    @tree.walk_blobs {|root, entry| assert_equal :blob, entry[:type]}
+  end
+
+  def test_iterate_subtrees
+    @tree.each_tree {|tree| assert_equal :tree, tree[:type]}
+  end
+
+  def test_iterate_subtree_blobs
+    @tree.each_blob {|tree| assert_equal :blob, tree[:type]}
+  end
+end
+
+class TreeWriteTest < Rugged::TestCase
+  def setup
+    @source_repo = FixtureRepo.from_rugged("testrepo.git")
+    @repo = FixtureRepo.clone(@source_repo)
+  end
+
+  def test_write_tree_data
+    entry = {:type => :blob,
+             :name => "README.txt",
+             :oid  => "1385f264afb75a56a5bec74243be9b367ba4ca08",
+             :filemode => 33188}
+
+    builder = Rugged::Tree::Builder.new(@repo)
+    builder << entry
+    sha = builder.write
+    obj = @repo.lookup(sha)
+    assert_equal 38, obj.read_raw.len
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/test/walker_test.rb b/app/server/vendor/rugged-0.23.3/test/walker_test.rb
new file mode 100755
index 0000000..17a0682
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/test/walker_test.rb
@@ -0,0 +1,159 @@
+require "test_helper"
+require 'base64'
+
+class WalkerTest < Rugged::TestCase
+  def setup
+    @repo = FixtureRepo.from_rugged("testrepo.git")
+    @walker = Rugged::Walker.new(@repo)
+  end
+
+  def test_walk_revlist
+    @walker.push("9fd738e8f7967c078dceed8190330fc8648ee56a")
+    data = @walker.each.to_a
+    oids = data.sort { |a, b| a.oid <=> b.oid }.map {|a| a.oid[0,5]}.join('.')
+    assert_equal "4a202.5b5b0.84960.9fd73", oids
+  end
+
+  def test_walk_revlist_with_limit
+    @walker.push("9fd738e8f7967c078dceed8190330fc8648ee56a")
+    data = @walker.each(:limit => 2).to_a
+    oids = data.map{|c| c.oid}
+    assert_equal ["9fd738e8f7967c078dceed8190330fc8648ee56a", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045"], oids
+  end
+
+  def test_walk_revlist_with_offset
+    @walker.push("9fd738e8f7967c078dceed8190330fc8648ee56a")
+    data = @walker.each(:offset => 2).to_a
+    oids = data.map{|c| c.oid}
+    assert_equal ["5b5b025afb0b4c913b4c338a42934a3863bf3644", "8496071c1b46c854b31185ea97743be6a8774479"], oids
+  end
+
+  def test_walk_revlist_with_limit_and_offset
+    @walker.push("9fd738e8f7967c078dceed8190330fc8648ee56a")
+    data = @walker.each(:offset => 2, :limit => 1).to_a
+    oids = data.map{|c| c.oid}
+    assert_equal ["5b5b025afb0b4c913b4c338a42934a3863bf3644"], oids
+  end
+
+  def test_walk_revlist_as_oids
+    @walker.push("9fd738e8f7967c078dceed8190330fc8648ee56a")
+    oids = @walker.each_oid.to_a
+    oids = oids.sort { |a, b| a <=> b }.map {|a| a[0,5]}.join('.')
+    assert_equal "4a202.5b5b0.84960.9fd73", oids
+  end
+
+  def test_walk_revlist_with_limit_as_oids
+    @walker.push("9fd738e8f7967c078dceed8190330fc8648ee56a")
+    oids = @walker.each_oid(:limit => 2).to_a
+    assert_equal ["9fd738e8f7967c078dceed8190330fc8648ee56a", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045"], oids
+  end
+
+  def test_walk_revlist_with_offset_as_oids
+    @walker.push("9fd738e8f7967c078dceed8190330fc8648ee56a")
+    oids = @walker.each_oid(:offset => 2).to_a
+    assert_equal ["5b5b025afb0b4c913b4c338a42934a3863bf3644", "8496071c1b46c854b31185ea97743be6a8774479"], oids
+  end
+
+  def test_walk_revlist_with_limit_and_offset_as_oids
+    @walker.push("9fd738e8f7967c078dceed8190330fc8648ee56a")
+    oids = @walker.each_oid(:offset => 2, :limit => 1).to_a
+    assert_equal ["5b5b025afb0b4c913b4c338a42934a3863bf3644"], oids
+  end
+
+  def test_walk_push_range
+    @walker.push_range("HEAD~2..HEAD")
+    data = @walker.each.to_a
+    oids = data.sort { |a, b| a.oid <=> b.oid }.map {|a| a.oid[0,5]}.join('.')
+    assert_equal "36060.5b5b0", oids
+  end
+
+  def test_walk_partial_revlist
+    oid = "8496071c1b46c854b31185ea97743be6a8774479"
+    @walker.push(oid)
+    walk = @walker.each.to_a
+    assert_equal oid, walk[0].oid
+    assert_equal 1, walk.count
+  end
+
+  def test_hide_part_of_list
+    @walker.push("9fd738e8f7967c078dceed8190330fc8648ee56a")
+    @walker.hide("5b5b025afb0b4c913b4c338a42934a3863bf3644")
+    assert_equal 2, @walker.each.count
+  end
+
+  # resetting a walker emtpies the walking queue
+  def test_resetting_walker
+    oid = "8496071c1b46c854b31185ea97743be6a8774479"
+    @walker.push(oid)
+    walk = @walker.each.to_a
+    assert_equal oid, walk[0].oid
+    assert_equal 1, walk.count
+    @walker.reset
+    walk = @walker.each.to_a
+    assert_equal 0, walk.count
+  end
+
+  def test_walk_is_enumberable
+    @walker.push("9fd738e8f7967c078dceed8190330fc8648ee56a")
+    enum = @walker.sort { |a, b| a.oid <=> b.oid }.map { |a| a.oid[0, 4] }.join('.')
+    assert_equal "4a20.5b5b.8496.9fd7", enum
+  end
+
+  def do_sort(sorting)
+    oid = "a4a7dce85cf63874e984719f4fdd239f5145052f"
+    @walker.sorting(sorting)
+    @walker.push(oid)
+    @walker.each.to_a
+  end
+
+  def revlist_with_sorting(sorting)
+    data = do_sort sorting
+    data.map {|a| a.oid[0,5] if a }.join('.')
+  end
+
+  def is_toposorted(list)
+    list.all? do |commit|
+      commit.parents.all? { |parent| list.index(commit) < list.index(parent) }
+    end
+  end
+
+  def test_sort_by_date
+    time = revlist_with_sorting(Rugged::SORT_DATE)
+    assert_equal "a4a7d.c4780.9fd73.4a202.5b5b0.84960", time
+  end
+
+  def test_sort_by_topo
+    sort_list = do_sort(Rugged::SORT_TOPO)
+    assert_equal is_toposorted(sort_list), true
+  end
+
+  def test_sort_by_date_reversed
+    time = revlist_with_sorting(Rugged::SORT_DATE | Rugged::SORT_REVERSE)
+    assert_equal "84960.5b5b0.4a202.9fd73.c4780.a4a7d", time
+  end
+
+  def test_sort_by_topo_reverse
+    sort_list = do_sort(Rugged::SORT_TOPO | Rugged::SORT_REVERSE).reverse
+    assert_equal is_toposorted(sort_list), true
+  end
+
+  def test_walk_api
+    sha = "9fd738e8f7967c078dceed8190330fc8648ee56a"
+    data = Rugged::Walker.walk(@repo, show: sha).to_a
+    oids = data.sort { |a, b| a.oid <=> b.oid }.map {|a| a.oid[0,5]}.join('.')
+    assert_equal "4a202.5b5b0.84960.9fd73", oids
+  end
+end
+
+# testrepo (the non-bare repo) is the one with non-linear history,
+# which we need in order to make sure that we are activating the
+# first-parent simplification
+class WalkerTest2 < Rugged::TestCase
+  def test_simplify_first_parent
+    repo = FixtureRepo.from_libgit2("testrepo")
+    walker = Rugged::Walker.new(repo)
+    walker.push("099fabac3a9ea935598528c27f866e34089c2eff")
+    walker.simplify_first_parent
+    assert_equal 7, walker.each.to_a.length
+  end
+end
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/AUTHORS b/app/server/vendor/rugged-0.23.3/vendor/libgit2/AUTHORS
new file mode 100755
index 0000000..61e2113
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/AUTHORS
@@ -0,0 +1,76 @@
+The following people contribute or have contributed
+to the libgit2 project (sorted alphabetically):
+
+Alex Budovski
+Alexei Sholik
+Andreas Ericsson
+Anton "antong" Gyllenberg
+Ankur Sethi
+Arthur Schreiber
+Ben Noordhuis
+Ben Straub
+Benjamin C Meyer
+Brian Downing
+Brian Lopez
+Carlos Martín Nieto
+Colin Timmermans
+Daniel Huckstep
+Dave Borowitz
+David Boyce
+David Glesser
+Dmitry Kakurin
+Dmitry Kovega
+Emeric Fermas
+Emmanuel Rodriguez
+Florian Forster
+Holger Weiss
+Ingmar Vanhassel
+J. David Ibáñez
+Jacques Germishuys
+Jakob Pfender
+Jason Penny
+Jason R. McNeil
+Jerome Lambourg
+Johan 't Hart
+John Wiegley
+Jonathan "Duke" Leto
+Julien Miotte
+Julio Espinoza-Sokal
+Justin Love
+Kelly "kelly.leahy" Leahy
+Kirill A. Shutemov
+Lambert CLARA
+Luc Bertrand
+Marc Pegon
+Marcel Groothuis
+Marco Villegas
+Michael "schu" Schubert
+Microsoft Corporation
+Olivier Ramonat
+Peter Drahoš
+Pierre Habouzit
+Pierre-Olivier Latour
+Przemyslaw Pawelczyk
+Ramsay Jones
+Robert G. Jakabosky
+Romain Geissler
+Romain Muller
+Russell Belfer
+Sakari Jokinen
+Samuel Charles "Sam" Day
+Sarath Lakshman
+Sascha Cunz
+Sascha Peilicke
+Scott Chacon
+Sebastian Schuberth
+Sergey Nikishin
+Shawn O. Pearce
+Shuhei Tanuma
+Steve Frécinaux
+Sven Strickroth
+Tim Branyen
+Tim Clem
+Tim Harder
+Torsten Bögershausen
+Trent Mick
+Vicent Marti
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/CHANGELOG.md b/app/server/vendor/rugged-0.23.3/vendor/libgit2/CHANGELOG.md
new file mode 100755
index 0000000..b824a66
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/CHANGELOG.md
@@ -0,0 +1,537 @@
+v0.23 + 1
+-------
+
+### Changes or improvements
+
+### API additions
+
+### API removals
+
+v0.23
+------
+
+### Changes or improvements
+
+* Patience and minimal diff drivers can now be used for merges.
+
+* Merges can now ignore whitespace changes.
+
+* Updated binary identification in CRLF filtering to avoid false positives in
+  UTF-8 files.
+
+* Rename and copy detection is enabled for small files.
+
+* Checkout can now handle an initial checkout of a repository, making
+  `GIT_CHECKOUT_SAFE_CREATE` unnecessary for users of clone.
+
+* The signature parameter in the ref-modifying functions has been
+  removed. Use `git_repository_set_ident()` and
+  `git_repository_ident()` to override the signature to be used.
+
+* The local transport now auto-scales the number of threads to use
+  when creating the packfile instead of sticking to one.
+
+* Reference renaming now uses the right id for the old value.
+
+* The annotated version of branch creation, HEAD detaching and reset
+  allow for specifying the expression from the user to be put into the
+  reflog.
+
+* `git_rebase_commit` now returns `GIT_EUNMERGED` when you attempt to
+  commit with unstaged changes.
+
+* On Mac OS X, we now use SecureTransport to provide the cryptographic
+  support for HTTPS connections insead of OpenSSL.
+
+* Checkout can now accept an index for the baseline computations via the
+  `baseline_index` member.
+
+* The configuration for fetching is no longer stored inside the
+  `git_remote` struct but has been moved to a `git_fetch_options`. The
+  remote functions now take these options or the callbacks instead of
+  setting them beforehand.
+
+* `git_submodule` instances are no longer cached or shared across
+  lookup. Each submodule represents the configuration at the time of
+  loading.
+
+* The index now uses diffs for `add_all()` and `update_all()` which
+  gives it a speed boost and closer semantics to git.
+
+* The ssh transport now reports the stderr output from the server as
+  the error message, which allows you to get the "repository not
+  found" messages.
+
+* `git_index_conflict_add()` will remove staged entries that exist for
+  conflicted paths.
+
+* The flags for a `git_diff_file` will now have the `GIT_DIFF_FLAG_EXISTS`
+  bit set when a file exists on that side of the diff.  This is useful
+  for understanding whether a side of the diff exists in the presence of
+  a conflict.
+
+* The constructor for a write-stream into the odb now takes
+  `git_off_t` instead of `size_t` for the size of the blob, which
+  allows putting large files into the odb on 32-bit systems.
+
+* The remote's push and pull URLs now honor the url.$URL.insteadOf
+  configuration. This allows modifying URL prefixes to a custom
+  value via gitconfig.
+
+* `git_diff_foreach`, `git_diff_blobs`, `git_diff_blob_to_buffer`,
+  and `git_diff_buffers` now accept a new binary callback of type
+  `git_diff_binary_cb` that includes the binary diff information.
+
+* The race condition mitigations described in `racy-git.txt` have been
+  implemented.
+
+* If libcurl is installed, we will use it to connect to HTTP(S)
+  servers.
+
+### API additions
+
+* The `git_merge_options` gained a `file_flags` member.
+
+* Parsing and retrieving a configuration value as a path is exposed
+  via `git_config_parse_path()` and `git_config_get_path()`
+  respectively.
+
+* `git_repository_set_ident()` and `git_repository_ident()` serve to
+  set and query which identity will be used when writing to the
+  reflog.
+
+* `git_config_entry_free()` frees a config entry.
+
+* `git_config_get_string_buf()` provides a way to safely retrieve a
+  string from a non-snapshot configuration.
+
+* `git_annotated_commit_from_revspec()` allows to get an annotated
+  commit from an extended sha synatx string.
+
+* `git_repository_set_head_detached_from_annotated()`,
+  `git_branch_create_from_annotated()` and
+  `git_reset_from_annotated()` allow for the caller to provide an
+  annotated commit through which they can control what expression is
+  put into the reflog as the source/target.
+
+* `git_index_add_frombuffer()` can now create a blob from memory
+  buffer and add it to the index which is attached to a repository.
+
+* The structure `git_fetch_options` has been added to determine the
+  runtime configuration for fetching, such as callbacks, pruning and
+  autotag behaviour. It has the runtime initializer
+  `git_fetch_init_options()`.
+
+* The enum `git_fetch_prune_t` has been added, letting you specify the
+  pruning behaviour for a fetch.
+
+* A push operation will notify the caller of what updates it indends
+  to perform on the remote, which provides similar information to
+  git's pre-push hook.
+
+* `git_stash_apply()` can now apply a stashed state from the stash list,
+  placing the data into the working directory and index.
+
+* `git_stash_pop()` will apply a stashed state (like `git_stash_apply()`)
+  but will remove the stashed state after a successful application.
+
+* A new error code `GIT_EEOF` indicates an early EOF from the
+  server. This typically indicates an error with the URL or
+  configuration of the server, and tools can use this to show messages
+  about failing to communicate with the server.
+
+* A new error code `GIT_EINVALID` indicates that an argument to a
+  function is invalid, or an invalid operation was requested.
+
+* `git_diff_index_to_workdir()` and `git_diff_tree_to_index()` will now
+  produce deltas of type `GIT_DELTA_CONFLICTED` to indicate that the index
+  side of the delta is a conflict.
+
+* The `git_status` family of functions will now produce status of type
+  `GIT_STATUS_CONFLICTED` to indicate that a conflict exists for that file
+  in the index.
+
+* `git_index_entry_is_conflict()` is a utility function to determine if
+  a given index entry has a non-zero stage entry, indicating that it is
+  one side of a conflict.
+
+* It is now possible to pass a keypair via a buffer instead of a
+  path. For this, `GIT_CREDTYPE_SSH_MEMORY` and
+  `git_cred_ssh_key_memory_new()` have been added.
+
+* `git_filter_list_contains` will indicate whether a particular
+  filter will be run in the given filter list.
+
+* `git_commit_header_field()` has been added, which allows retrieving
+  the contents of an arbitrary header field.
+
+* `git_submodule_set_branch()` allows to set the configured branch for
+  a submodule.
+
+### API removals
+
+* `git_remote_save()` and `git_remote_clear_refspecs()` have been
+  removed. Remote's configuration is changed via the configuration
+  directly or through a convenience function which performs changes to
+  the configuration directly.
+
+* `git_remote_set_callbacks()`, `git_remote_get_callbacks()` and
+  `git_remote_set_transport()` have been removed and the remote no
+  longer stores this configuration.
+
+* `git_remote_set_fetch_refpecs()` and
+  `git_remote_set_push_refspecs()` have been removed. There is no
+  longer a way to set the base refspecs at run-time.
+
+* `git_submodule_save()` has been removed. The submodules are no
+  longer configured via the objects.
+
+* `git_submodule_reload_all()` has been removed as we no longer cache
+  submodules.
+
+### Breaking API changes
+
+* `git_smart_subtransport_cb` now has a `param` parameter.
+
+* The `git_merge_options` structure member `flags` has been renamed
+  to `tree_flags`.
+
+* The `git_merge_file_options` structure member `flags` is now
+  an unsigned int. It was previously a `git_merge_file_flags_t`.
+
+* `GIT_CHECKOUT_SAFE_CREATE` has been removed.  Most users will generally
+  be able to switch to `GIT_CHECKOUT_SAFE`, but if you require missing
+  file handling during checkout, you may now use `GIT_CHECKOUT_SAFE |
+  GIT_CHECKOUT_RECREATE_MISSING`.
+
+* The `git_clone_options` and `git_submodule_update_options`
+  structures no longer have a `signature` field.
+
+* The following functions have removed the signature and/or log message
+  parameters in favour of git-emulating ones.
+
+    * `git_branch_create()`, `git_branch_move()`
+    * `git_rebase_init()`, `git_rebase_abort()`
+    * `git_reference_symbolic_create_matching()`,
+      `git_reference_symbolic_create()`, `git_reference_create()`,
+      `git_reference_create_matching()`,
+      `git_reference_symbolic_set_target()`,
+      `git_reference_set_target()`, `git_reference_rename()`
+    * `git_remote_update_tips()`, `git_remote_fetch()`, `git_remote_push()`
+    * `git_repository_set_head()`,
+      `git_repository_set_head_detached()`,
+      `git_repository_detach_head()`
+    * `git_reset()`
+
+* `git_config_get_entry()` now gives back a ref-counted
+  `git_config_entry`. You must free it when you no longer need it.
+
+* `git_config_get_string()` will return an error if used on a
+  non-snapshot configuration, as there can be no guarantee that the
+  returned pointer is valid.
+
+* `git_note_default_ref()` now uses a `git_buf` to return the string,
+  as the string is otherwise not guaranteed to stay allocated.
+
+* `git_rebase_operation_current()` will return `GIT_REBASE_NO_OPERATION`
+  if it is called immediately after creating a rebase session but before
+  you have applied the first patch.
+
+* `git_rebase_options` now contains a `git_checkout_options` struct
+  that will be used for functions that modify the working directory,
+  namely `git_checkout_init`, `git_checkout_next` and
+  `git_checkout_abort`.  As a result, `git_rebase_open` now also takes
+  a `git_rebase_options` and only the `git_rebase_init` and
+  `git_rebase_open` functions take a `git_rebase_options`, where they
+  will persist the options to subsequent `git_rebase` calls.
+
+* The `git_clone_options` struct now has fetch options in a
+  `fetch_opts` field instead of remote callbacks in
+  `remote_callbacks`.
+
+* The remote callbacks has gained a new member `push_negotiation`
+  which gets called before sending the update commands to the server.
+
+* The following functions no longer act on a remote instance but
+  change the repository's configuration. Their signatures have changed
+  accordingly:
+
+    * `git_remote_set_url()`, `git_remote_seturl()`
+    * `git_remote_add_fetch()`, `git_remote_add_push()` and
+    * `git_remote_set_autotag()`
+
+* `git_remote_connect()` and `git_remote_prune()` now take a pointer
+  to the callbacks.
+
+* `git_remote_fetch()` and `git_remote_download()` now take a pointer
+  to fetch options which determine the runtime configuration.
+
+* The `git_remote_autotag_option_t` values have been changed. It has
+  gained a `_UNSPECIFIED` default value to specify no override for the
+  configured setting.
+
+* `git_remote_update_tips()` now takes a pointer to the callbacks as
+  well as a boolean whether to write `FETCH_HEAD` and the autotag
+  setting.
+
+* `git_remote_create_anonymous()` no longer takes a fetch refspec as
+  url-only remotes cannot have configured refspecs.
+
+* The `git_submodule_update_options` struct now has fetch options in
+  the `fetch_opts` field instead of callbacks in the
+  `remote_callbacks` field.
+
+* The following functions no longer act on a submodule instance but
+  change the repository's configuration. Their signatures have changed
+  accordingly:
+
+    * `git_submodule_set_url()`, `git_submodule_set_ignore()`,
+      `git_submodule_set_update()`,
+      `git_submodule_set_fetch_recurse_submodules()`.
+
+* `git_submodule_status()` no longer takes a submodule instance but a
+  repsitory, a submodule name and an ignore setting.
+
+* The `push` function in the `git_transport` interface now takes a
+  pointer to the remote callbacks.
+
+* The `git_index_entry` struct's fields' types have been changed to
+  more accurately reflect what is in fact stored in the
+  index. Specifically, time and file size are 32 bits intead of 64, as
+  these values are truncated.
+
+* `GIT_EMERGECONFLICT` is now `GIT_ECONFLICT`, which more accurately
+  describes the nature of the error.
+
+* It is no longer allowed to call `git_buf_grow()` on buffers
+  borrowing the memory they point to.
+
+v0.22
+------
+
+### Changes or improvements
+
+* `git_signature_new()` now requires a non-empty email address.
+
+* Use CommonCrypto libraries for SHA-1 calculation on Mac OS X.
+
+* Disable SSL compression and SSLv2 and SSLv3 ciphers in favor of TLSv1
+  in OpenSSL.
+
+* The fetch behavior of remotes with autotag set to `GIT_REMOTE_DOWNLOAD_TAGS_ALL`
+  has been changed to match git 1.9.0 and later. In this mode, libgit2 now
+  fetches all tags in addition to whatever else needs to be fetched.
+
+* `git_checkout()` now handles case-changing renames correctly on
+  case-insensitive filesystems; for example renaming "readme" to "README".
+
+* The search for libssh2 is now done via pkg-config instead of a
+  custom search of a few directories.
+
+* Add support for core.protectHFS and core.protectNTFS. Add more
+  validation for filenames which we write such as references.
+
+* The local transport now generates textual progress output like
+  git-upload-pack does ("counting objects").
+
+* `git_checkout_index()` can now check out an in-memory index that is not
+  necessarily the repository's index, so you may check out an index
+  that was produced by git_merge and friends while retaining the cached
+  information.
+
+* Remove the default timeout for receiving / sending data over HTTP using
+  the WinHTTP transport layer.
+
+* Add SPNEGO (Kerberos) authentication using GSSAPI on Unix systems.
+
+* Provide built-in objects for the empty blob (e69de29) and empty
+  tree (4b825dc) objects.
+
+* The index' tree cache is now filled upon read-tree and write-tree
+  and the cache is written to disk.
+
+* LF -> CRLF filter refuses to handle mixed-EOL files
+
+* LF -> CRLF filter now runs when * text = auto (with Git for Windows 1.9.4)
+
+* File unlocks are atomic again via rename. Read-only files on Windows are
+  made read-write if necessary.
+
+* Share open packfiles across repositories to share descriptors and mmaps.
+
+* Use a map for the treebuilder, making insertion O(1)
+
+* The build system now accepts an option EMBED_SSH_PATH which when set
+  tells it to include a copy of libssh2 at the given location. This is
+  enabled for MSVC.
+
+* Add support for refspecs with the asterisk in the middle of a
+  pattern.
+
+* Fetching now performs opportunistic updates. To achieve this, we
+  introduce a difference between active and passive refspecs, which
+  make `git_remote_download()` and `git_remote_fetch()` to take a list of
+  resfpecs to be the active list, similarly to how git fetch accepts a
+  list on the command-line.
+
+* The THREADSAFE option to build libgit2 with threading support has
+  been flipped to be on by default.
+
+* The remote object has learnt to prune remote-tracking branches. If
+  the remote is configured to do so, this will happen via
+  `git_remote_fetch()`. You can also call `git_remote_prune()` after
+  connecting or fetching to perform the prune.
+
+
+### API additions
+
+* Introduce `git_buf_text_is_binary()` and `git_buf_text_contains_nul()` for
+  consumers to perform binary detection on a git_buf.
+
+* `git_branch_upstream_remote()` has been introduced to provide the
+  branch.<name>.remote configuration value.
+
+* Introduce `git_describe_commit()` and `git_describe_workdir()` to provide
+  a description of the current commit (and working tree, respectively)
+  based on the nearest tag or reference
+
+* Introduce `git_merge_bases()` and the `git_oidarray` type to expose all
+  merge bases between two commits.
+
+* Introduce `git_merge_bases_many()` to expose all merge bases between
+  multiple commits.
+
+* Introduce rebase functionality (using the merge algorithm only).
+  Introduce `git_rebase_init()` to begin a new rebase session,
+  `git_rebase_open()` to open an in-progress rebase session,
+  `git_rebase_commit()` to commit the current rebase operation,
+  `git_rebase_next()` to apply the next rebase operation,
+  `git_rebase_abort()` to abort an in-progress rebase and `git_rebase_finish()`
+  to complete a rebase operation.
+
+* Introduce `git_note_author()` and `git_note_committer()` to get the author
+  and committer information on a `git_note`, respectively.
+
+* A factory function for ssh has been added which allows to change the
+  path of the programs to execute for receive-pack and upload-pack on
+  the server, `git_transport_ssh_with_paths()`.
+
+* The ssh transport supports asking the remote host for accepted
+  credential types as well as multiple challeges using a single
+  connection. This requires to know which username you want to connect
+  as, so this introduces the USERNAME credential type which the ssh
+  transport will use to ask for the username.
+
+* The `GIT_EPEEL` error code has been introduced when we cannot peel a tag
+  to the requested object type; if the given object otherwise cannot be
+  peeled, `GIT_EINVALIDSPEC` is returned.
+
+* Introduce `GIT_REPOSITORY_INIT_RELATIVE_GITLINK` to use relative paths
+  when writing gitlinks, as is used by git core for submodules.
+
+* `git_remote_prune()` has been added. See above for description.
+
+
+* Introduce reference transactions, which allow multiple references to
+  be locked at the same time and updates be queued. This also allows
+  us to safely update a reflog with arbitrary contents, as we need to
+  do for stash.
+
+### API removals
+
+* `git_remote_supported_url()` and `git_remote_is_valid_url()` have been
+  removed as they have become essentially useless with rsync-style ssh paths.
+
+* `git_clone_into()` and `git_clone_local_into()` have been removed from the
+  public API in favour of `git_clone callbacks`.
+
+* The option to ignore certificate errors via `git_remote_cert_check()`
+  is no longer present. Instead, `git_remote_callbacks` has gained a new
+  entry which lets the user perform their own certificate checks.
+
+### Breaking API changes
+
+* `git_cherry_pick()` is now `git_cherrypick()`.
+
+* The `git_submodule_update()` function was renamed to
+  `git_submodule_update_strategy()`. `git_submodule_update()` is now used to
+  provide functionalty similar to "git submodule update".
+
+* `git_treebuilder_create()` was renamed to `git_treebuilder_new()` to better
+  reflect it being a constructor rather than something which writes to
+  disk.
+
+* `git_treebuilder_new()` (was `git_treebuilder_create()`) now takes a
+  repository so that it can query repository configuration.
+  Subsequently, `git_treebuilder_write()` no longer takes a repository.
+
+* `git_threads_init()` and `git_threads_shutdown()` have been renamed to
+  `git_libgit2_init()` and `git_libgit2_shutdown()` to better explain what
+  their purpose is, as it's grown to be more than just about threads.
+
+* `git_libgit2_init()` and `git_libgit2_shutdown()` now return the number of
+  initializations of the library, so consumers may schedule work on the
+  first initialization.
+
+* The `git_transport_register()` function no longer takes a priority and takes
+  a URL scheme name (eg "http") instead of a prefix like "http://"
+
+* `git_index_name_entrycount()` and `git_index_reuc_entrycount()` now
+  return size_t instead of unsigned int.
+
+* The `context_lines` and `interhunk_lines` fields in `git_diff`_options are
+  now `uint32_t` instead of `uint16_t`. This allows to set them to `UINT_MAX`,
+  in effect asking for "infinite" context e.g. to iterate over all the
+  unmodified lines of a diff.
+
+* `git_status_file()` now takes an exact path. Use `git_status_list_new()` if
+  pathspec searching is needed.
+
+* `git_note_create()` has changed the position of the notes reference
+  name to match `git_note_remove()`.
+
+* Rename `git_remote_load()` to `git_remote_lookup()` to bring it in line
+  with the rest of the lookup functions.
+
+* `git_remote_rename()` now takes the repository and the remote's
+  current name. Accepting a remote indicates we want to change it,
+  which we only did partially. It is much clearer if we accept a name
+  and no loaded objects are changed.
+
+* `git_remote_delete()` now accepts the repository and the remote's name
+  instead of a loaded remote.
+
+* `git_merge_head` is now `git_annotated_commit`, to better reflect its usage
+  for multiple functions (including rebase)
+
+* The `git_clone_options` struct no longer provides the `ignore_cert_errors` or
+  `remote_name` members for remote customization.
+
+  Instead, the `git_clone_options` struct has two new members, `remote_cb` and
+  `remote_cb_payload`, which allow the caller to completely override the remote
+  creation process. If needed, the caller can use this callback to give their
+  remote a name other than the default (origin) or disable cert checking.
+
+  The `remote_callbacks` member has been preserved for convenience, although it
+  is not used when a remote creation callback is supplied.
+
+* The `git_clone`_options struct now provides `repository_cb` and
+  `repository_cb_payload` to allow the user to create a repository with
+  custom options.
+
+* The `git_push` struct to perform a push has been replaced with
+  `git_remote_upload()`. The refspecs and options are passed as a
+  function argument. `git_push_update_tips()` is now also
+  `git_remote_update_tips()` and the callbacks are in the same struct as
+  the rest.
+
+* The `git_remote_set_transport()` function now sets a transport factory function,
+  rather than a pre-existing transport instance.
+
+* The `git_transport` structure definition has moved into the sys/transport.h
+  file.
+
+* libgit2 no longer automatically sets the OpenSSL locking
+  functions. This is not something which we can know to do. A
+  last-resort convenience function is provided in sys/openssl.h,
+  `git_openssl_set_locking()` which can be used to set the locking.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/CMakeLists.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/CMakeLists.txt
new file mode 100755
index 0000000..73c9630
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/CMakeLists.txt
@@ -0,0 +1,618 @@
+# CMake build script for the libgit2 project
+#
+# Building (out of source build):
+# > mkdir build && cd build
+# > cmake .. [-DSETTINGS=VALUE]
+# > cmake --build .
+#
+# Testing:
+# > ctest -V
+#
+# Install:
+# > cmake --build . --target install
+
+PROJECT(libgit2 C)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+CMAKE_POLICY(SET CMP0015 NEW)
+
+# Add find modules to the path
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
+
+INCLUDE(CheckLibraryExists)
+INCLUDE(AddCFlagIfSupported)
+INCLUDE(FindPkgConfig)
+
+# Build options
+#
+OPTION( SONAME				"Set the (SO)VERSION of the target"		ON  )
+OPTION( BUILD_SHARED_LIBS	"Build Shared Library (OFF for Static)"	ON  )
+OPTION( THREADSAFE			"Build libgit2 as threadsafe"			ON )
+OPTION( BUILD_CLAR			"Build Tests using the Clar suite"		ON  )
+OPTION( BUILD_EXAMPLES		"Build library usage example apps"		OFF )
+OPTION( TAGS				"Generate tags"							OFF )
+OPTION( PROFILE				"Generate profiling information"		OFF )
+OPTION( ENABLE_TRACE		"Enables tracing support"				OFF )
+OPTION( LIBGIT2_FILENAME	"Name of the produced binary"			OFF )
+
+OPTION( USE_ICONV			"Link with and use iconv library" 		OFF )
+OPTION( USE_SSH				"Link with libssh to enable SSH support" ON )
+OPTION( USE_GSSAPI			"Link with libgssapi for SPNEGO auth"   OFF )
+OPTION( VALGRIND			"Configure build for valgrind"			OFF )
+OPTION( CURL			"User curl for HTTP if available" ON)
+
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+	SET( USE_ICONV ON )
+	FIND_PACKAGE(Security)
+	FIND_PACKAGE(CoreFoundation REQUIRED)
+ENDIF()
+
+IF(MSVC)
+	# This option is only available when building with MSVC. By default, libgit2
+	# is build using the cdecl calling convention, which is useful if you're
+	# writing C. However, the CLR and Win32 API both expect stdcall.
+	#
+	# If you are writing a CLR program and want to link to libgit2, you'll want
+	# to turn this on by invoking CMake with the "-DSTDCALL=ON" argument.
+	OPTION( STDCALL			"Build libgit2 with the __stdcall convention"	OFF  )
+
+	# This option must match the settings used in your program, in particular if you
+	# are linking statically
+	OPTION( STATIC_CRT		"Link the static CRT libraries"	ON  )
+
+	ADD_DEFINITIONS(-D_SCL_SECURE_NO_WARNINGS)
+	ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
+	ADD_DEFINITIONS(-D_CRT_NONSTDC_NO_DEPRECATE)
+ENDIF()
+
+
+IF(WIN32)
+	# By default, libgit2 is built with WinHTTP.  To use the built-in
+	# HTTP transport, invoke CMake with the "-DWINHTTP=OFF" argument.
+	OPTION(	WINHTTP			"Use Win32 WinHTTP routines"	ON	)
+ENDIF()
+
+IF(MSVC)
+	# Enable MSVC CRTDBG memory leak reporting when in debug mode.
+	OPTION(MSVC_CRTDBG "Enable CRTDBG memory leak reporting" OFF)
+ENDIF()
+
+IF (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+	OPTION( USE_OPENSSL                     "Link with and use openssl library"             ON )
+ENDIF()
+
+# This variable will contain the libraries we need to put into
+# libgit2.pc's Requires.private. That is, what we're linking to or
+# what someone who's statically linking us needs to link to.
+SET(LIBGIT2_PC_REQUIRES "")
+# This will be set later if we use the system's http-parser library or
+# use iconv (OSX) and will be written to the Libs.private field in the
+# pc file.
+SET(LIBGIT2_PC_LIBS "")
+
+# Installation paths
+#
+SET(BIN_INSTALL_DIR bin CACHE PATH "Where to install binaries to.")
+SET(LIB_INSTALL_DIR lib CACHE PATH "Where to install libraries to.")
+SET(INCLUDE_INSTALL_DIR include CACHE PATH "Where to install headers to.")
+
+FUNCTION(TARGET_OS_LIBRARIES target)
+	IF(WIN32)
+		TARGET_LINK_LIBRARIES(${target} ws2_32)
+	ELSEIF(CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
+		TARGET_LINK_LIBRARIES(${target} socket nsl)
+		LIST(APPEND LIBGIT2_PC_LIBS "-lsocket" "-lnsl")
+		SET(LIBGIT2_PC_LIBS ${LIBGIT2_PC_LIBS} PARENT_SCOPE)
+	ENDIF()
+	CHECK_LIBRARY_EXISTS(rt clock_gettime "time.h" NEED_LIBRT)
+	IF(NEED_LIBRT)
+		TARGET_LINK_LIBRARIES(${target} rt)
+		LIST(APPEND LIBGIT2_PC_LIBS "-lrt")
+		SET(LIBGIT2_PC_LIBS ${LIBGIT2_PC_LIBS} PARENT_SCOPE)
+	ENDIF()
+
+	IF(THREADSAFE)
+		TARGET_LINK_LIBRARIES(${target} ${CMAKE_THREAD_LIBS_INIT})
+	ENDIF()
+ENDFUNCTION()
+
+# For the MSVC IDE, this function splits up the source files like windows
+# explorer does. This is esp. useful with the libgit2_clar project, were
+# usually 2 or more files share the same name.  Sadly, this file grouping
+# is a per-directory option in cmake and not per-target, resulting in
+# empty virtual folders "tests" for the git2.dll
+FUNCTION(MSVC_SPLIT_SOURCES target)
+	IF(MSVC_IDE)
+		GET_TARGET_PROPERTY(sources ${target} SOURCES)
+		FOREACH(source ${sources})
+			IF(source MATCHES ".*/")
+				STRING(REPLACE ${CMAKE_CURRENT_SOURCE_DIR}/ "" rel ${source})
+				IF(rel)
+					STRING(REGEX REPLACE "/([^/]*)$" "" rel ${rel})
+					IF(rel)
+						STRING(REPLACE "/" "\\\\" rel ${rel})
+						SOURCE_GROUP(${rel} FILES ${source})
+					ENDIF()
+				ENDIF()
+			ENDIF()
+		ENDFOREACH()
+	ENDIF()
+ENDFUNCTION()
+
+FILE(STRINGS "include/git2/version.h" GIT2_HEADER REGEX "^#define LIBGIT2_VERSION \"[^\"]*\"$")
+
+STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"([0-9]+).*$" "\\1" LIBGIT2_VERSION_MAJOR "${GIT2_HEADER}")
+STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" LIBGIT2_VERSION_MINOR  "${GIT2_HEADER}")
+STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" LIBGIT2_VERSION_REV "${GIT2_HEADER}")
+SET(LIBGIT2_VERSION_STRING "${LIBGIT2_VERSION_MAJOR}.${LIBGIT2_VERSION_MINOR}.${LIBGIT2_VERSION_REV}")
+
+FILE(STRINGS "include/git2/version.h" GIT2_HEADER_SOVERSION REGEX "^#define LIBGIT2_SOVERSION [0-9]+$")
+STRING(REGEX REPLACE "^.*LIBGIT2_SOVERSION ([0-9]+)$" "\\1" LIBGIT2_SOVERSION "${GIT2_HEADER_SOVERSION}")
+
+# Find required dependencies
+INCLUDE_DIRECTORIES(src include)
+
+IF (SECURITY_FOUND)
+  # OS X 10.7 and older do not have some functions we use, fall back to OpenSSL there
+  CHECK_LIBRARY_EXISTS("${SECURITY_DIRS}" SSLCreateContext "Security/SecureTransport.h" HAVE_NEWER_SECURITY)
+  IF (HAVE_NEWER_SECURITY)
+    MESSAGE("-- Found Security ${SECURITY_DIRS}")
+    LIST(APPEND LIBGIT2_PC_LIBS "-framework Security")
+  ELSE()
+    MESSAGE("-- Security framework is too old, falling back to OpenSSL")
+    SET(SECURITY_FOUND "NO")
+    SET(SECURITY_DIRS "")
+    SET(SECURITY_DIR "")
+    SET(USE_OPENSSL "ON")
+  ENDIF()
+ENDIF()
+
+IF (COREFOUNDATION_FOUND)
+  MESSAGE("-- Found CoreFoundation ${COREFOUNDATION_DIRS}")
+  LIST(APPEND LIBGIT2_PC_LIBS "-framework CoreFoundation")
+ENDIF()
+
+
+IF (WIN32 AND WINHTTP)
+	ADD_DEFINITIONS(-DGIT_WINHTTP)
+	INCLUDE_DIRECTORIES(deps/http-parser)
+	FILE(GLOB SRC_HTTP deps/http-parser/*.c deps/http-parser/*.h)
+
+	# Since MinGW does not come with headers or an import library for winhttp,
+	# we have to include a private header and generate our own import library
+	IF (MINGW)
+		FIND_PROGRAM(DLLTOOL dlltool CMAKE_FIND_ROOT_PATH_BOTH)
+		IF (NOT DLLTOOL)
+			MESSAGE(FATAL_ERROR "Could not find dlltool command")
+		ENDIF ()
+
+		SET(LIBWINHTTP_PATH "${CMAKE_CURRENT_BINARY_DIR}/deps/winhttp")
+		FILE(MAKE_DIRECTORY ${LIBWINHTTP_PATH})
+
+		IF ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+			set(WINHTTP_DEF "${CMAKE_CURRENT_SOURCE_DIR}/deps/winhttp/winhttp64.def")
+		ELSE()
+			set(WINHTTP_DEF "${CMAKE_CURRENT_SOURCE_DIR}/deps/winhttp/winhttp.def")
+		ENDIF()
+
+		ADD_CUSTOM_COMMAND(
+			OUTPUT ${LIBWINHTTP_PATH}/libwinhttp.a
+			COMMAND ${DLLTOOL} -d ${WINHTTP_DEF} -k -D winhttp.dll -l libwinhttp.a
+			DEPENDS ${WINHTTP_DEF}
+			WORKING_DIRECTORY ${LIBWINHTTP_PATH}
+		)
+
+		SET_SOURCE_FILES_PROPERTIES(
+			${CMAKE_CURRENT_SOURCE_DIR}/src/transports/winhttp.c
+			PROPERTIES OBJECT_DEPENDS ${LIBWINHTTP_PATH}/libwinhttp.a
+		)
+
+		INCLUDE_DIRECTORIES(deps/winhttp)
+		LINK_DIRECTORIES(${LIBWINHTTP_PATH})
+	ENDIF ()
+
+	LINK_LIBRARIES(winhttp rpcrt4 crypt32)
+ELSE ()
+	IF (CURL)
+		PKG_CHECK_MODULES(CURL libcurl)
+	ENDIF ()
+
+	IF (NOT AMIGA AND USE_OPENSSL)
+		FIND_PACKAGE(OpenSSL)
+	ENDIF ()
+
+	IF (CURL_FOUND)
+		ADD_DEFINITIONS(-DGIT_CURL)
+		INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIRS})
+		LINK_LIBRARIES(${CURL_LIBRARIES})
+		LIST(APPEND LIBGIT2_PC_LIBS ${CURL_LDFLAGS})
+	ENDIF()
+
+	FIND_PACKAGE(HTTP_Parser)
+	IF (HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2)
+		INCLUDE_DIRECTORIES(${HTTP_PARSER_INCLUDE_DIRS})
+		LINK_LIBRARIES(${HTTP_PARSER_LIBRARIES})
+		LIST(APPEND LIBGIT2_PC_LIBS "-lhttp_parser")
+	ELSE()
+		MESSAGE(STATUS "http-parser was not found or is too old; using bundled 3rd-party sources.")
+		INCLUDE_DIRECTORIES(deps/http-parser)
+		FILE(GLOB SRC_HTTP deps/http-parser/*.c deps/http-parser/*.h)
+	ENDIF()
+ENDIF()
+
+# Specify sha1 implementation
+IF (WIN32 AND NOT MINGW AND NOT SHA1_TYPE STREQUAL "builtin")
+	ADD_DEFINITIONS(-DWIN32_SHA1)
+	FILE(GLOB SRC_SHA1 src/hash/hash_win32.c)
+ELSEIF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+	ADD_DEFINITIONS(-DGIT_COMMON_CRYPTO)
+ELSEIF (OPENSSL_FOUND AND NOT SHA1_TYPE STREQUAL "builtin")
+	ADD_DEFINITIONS(-DOPENSSL_SHA1)
+	IF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+		LIST(APPEND LIBGIT2_PC_LIBS "-lssl")
+	ELSE()
+		SET(LIBGIT2_PC_REQUIRES "${LIBGIT2_PC_REQUIRES} openssl")
+	ENDIF ()
+ELSE()
+	FILE(GLOB SRC_SHA1 src/hash/hash_generic.c)
+ENDIF()
+
+# Enable tracing
+IF (ENABLE_TRACE STREQUAL "ON")
+	ADD_DEFINITIONS(-DGIT_TRACE)
+ENDIF()
+
+# Include POSIX regex when it is required
+IF(WIN32 OR AMIGA OR CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
+	INCLUDE_DIRECTORIES(deps/regex)
+	SET(SRC_REGEX deps/regex/regex.c)
+ENDIF()
+
+# Optional external dependency: zlib
+FIND_PACKAGE(ZLIB)
+IF (ZLIB_FOUND)
+	INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIRS})
+	LINK_LIBRARIES(${ZLIB_LIBRARIES})
+	IF(APPLE OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+		LIST(APPEND LIBGIT2_PC_LIBS "-lz")
+	ELSE()
+		SET(LIBGIT2_PC_REQUIRES "${LIBGIT2_PC_REQUIRES} zlib")
+	ENDIF()
+ELSE()
+	MESSAGE(STATUS "zlib was not found; using bundled 3rd-party sources." )
+	INCLUDE_DIRECTORIES(deps/zlib)
+	ADD_DEFINITIONS(-DNO_VIZ -DSTDC -DNO_GZIP)
+	FILE(GLOB SRC_ZLIB deps/zlib/*.c deps/zlib/*.h)
+ENDIF()
+
+# Optional external dependency: libssh2
+IF (USE_SSH)
+	PKG_CHECK_MODULES(LIBSSH2 libssh2)
+ENDIF()
+IF (LIBSSH2_FOUND)
+	ADD_DEFINITIONS(-DGIT_SSH)
+	INCLUDE_DIRECTORIES(${LIBSSH2_INCLUDE_DIRS})
+	LINK_DIRECTORIES(${LIBSSH2_LIBRARY_DIRS})
+	LIST(APPEND LIBGIT2_PC_LIBS ${LIBSSH2_LDFLAGS})
+	#SET(LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS} ${LIBSSH2_LDFLAGS}")
+	SET(SSH_LIBRARIES ${LIBSSH2_LIBRARIES})
+
+	CHECK_LIBRARY_EXISTS("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS)
+	IF (HAVE_LIBSSH2_MEMORY_CREDENTIALS)
+		ADD_DEFINITIONS(-DGIT_SSH_MEMORY_CREDENTIALS)
+	ENDIF()
+ELSE()
+	MESSAGE(STATUS "LIBSSH2 not found. Set CMAKE_PREFIX_PATH if it is installed outside of the default search path.")
+ENDIF()
+
+# Optional external dependency: libgssapi
+IF (USE_GSSAPI)
+	FIND_PACKAGE(GSSAPI)
+ENDIF()
+IF (GSSAPI_FOUND)
+	ADD_DEFINITIONS(-DGIT_GSSAPI)
+ENDIF()
+
+# Optional external dependency: iconv
+IF (USE_ICONV)
+	FIND_PACKAGE(Iconv)
+ENDIF()
+IF (ICONV_FOUND)
+	ADD_DEFINITIONS(-DGIT_USE_ICONV)
+	INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR})
+	LIST(APPEND LIBGIT2_PC_LIBS ${ICONV_LIBRARIES})
+ENDIF()
+
+# Platform specific compilation flags
+IF (MSVC)
+
+	STRING(REPLACE "/Zm1000" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+
+	# /GF - String pooling
+	# /MP - Parallel build
+	SET(CMAKE_C_FLAGS "/GF /MP /nologo ${CMAKE_C_FLAGS}")
+
+	IF (STDCALL)
+		# /Gz - stdcall calling convention
+		SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gz")
+	ENDIF ()
+
+	IF (STATIC_CRT)
+		SET(CRT_FLAG_DEBUG "/MTd")
+		SET(CRT_FLAG_RELEASE "/MT")
+	ELSE()
+		SET(CRT_FLAG_DEBUG "/MDd")
+		SET(CRT_FLAG_RELEASE "/MD")
+	ENDIF()
+
+	IF (MSVC_CRTDBG)
+		SET(CRT_FLAG_DEBUG "${CRT_FLAG_DEBUG} /DGIT_MSVC_CRTDBG")
+	ENDIF()
+
+	# /Zi - Create debugging information
+	# /Od - Disable optimization
+	# /D_DEBUG - #define _DEBUG
+	# /MTd - Statically link the multithreaded debug version of the CRT
+	# /MDd - Dynamically link the multithreaded debug version of the CRT
+	# /RTC1 - Run time checks
+	SET(CMAKE_C_FLAGS_DEBUG "/Zi /Od /D_DEBUG /RTC1 ${CRT_FLAG_DEBUG}")
+
+	# /DNDEBUG - Disables asserts
+	# /MT - Statically link the multithreaded release version of the CRT
+	# /MD - Dynamically link the multithreaded release version of the CRT
+	# /O2 - Optimize for speed
+	# /Oy - Enable frame pointer omission (FPO) (otherwise CMake will automatically turn it off)
+	# /GL - Link time code generation (whole program optimization)
+	# /Gy - Function-level linking
+	SET(CMAKE_C_FLAGS_RELEASE "/DNDEBUG /O2 /Oy /GL /Gy ${CRT_FLAG_RELEASE}")
+
+	# /Oy- - Disable frame pointer omission (FPO)
+	SET(CMAKE_C_FLAGS_RELWITHDEBINFO "/DNDEBUG /Zi /O2 /Oy- /GL /Gy ${CRT_FLAG_RELEASE}")
+
+	# /O1 - Optimize for size
+	SET(CMAKE_C_FLAGS_MINSIZEREL "/DNDEBUG /O1 /Oy /GL /Gy ${CRT_FLAG_RELEASE}")
+
+	# /DYNAMICBASE - Address space load randomization (ASLR)
+	# /NXCOMPAT - Data execution prevention (DEP)
+	# /LARGEADDRESSAWARE - >2GB user address space on x86
+	# /VERSION - Embed version information in PE header
+	SET(CMAKE_EXE_LINKER_FLAGS "/DYNAMICBASE /NXCOMPAT /LARGEADDRESSAWARE /VERSION:${LIBGIT2_VERSION_MAJOR}.${LIBGIT2_VERSION_MINOR}")
+
+	# /DEBUG - Create a PDB
+	# /LTCG - Link time code generation (whole program optimization)
+	# /OPT:REF /OPT:ICF - Fold out duplicate code at link step
+	# /INCREMENTAL:NO - Required to use /LTCG
+	# /DEBUGTYPE:cv,fixup - Additional data embedded in the PDB (requires /INCREMENTAL:NO, so not on for Debug)
+	SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG")
+	SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "/RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO")
+	SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/DEBUG /RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO /DEBUGTYPE:cv,fixup")
+	SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "/RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO")
+
+	# Same linker settings for DLL as EXE
+	SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
+	SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
+	SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
+	SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
+	SET(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL}")
+
+	SET(WIN_RC "src/win32/git2.rc")
+
+   # Precompiled headers
+
+ELSE ()
+	SET(CMAKE_C_FLAGS "-D_GNU_SOURCE -Wall -Wextra ${CMAKE_C_FLAGS}")
+
+	IF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
+		SET(CMAKE_C_FLAGS "-std=c99 -D_POSIX_C_SOURCE=200112L -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS ${CMAKE_C_FLAGS}")
+	ENDIF()
+
+	IF (WIN32 AND NOT CYGWIN)
+		SET(CMAKE_C_FLAGS_DEBUG "-D_DEBUG")
+	ENDIF ()
+
+	IF (MINGW) # MinGW always does PIC and complains if we tell it to
+		STRING(REGEX REPLACE "-fPIC" "" CMAKE_SHARED_LIBRARY_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}")
+		# MinGW >= 3.14 uses the C99-style stdio functions
+		# automatically, but forks like mingw-w64 still want
+		# us to define this in order to use them
+		ADD_DEFINITIONS(-D__USE_MINGW_ANSI_STDIO=1)
+
+	ELSEIF (BUILD_SHARED_LIBS)
+		ADD_C_FLAG_IF_SUPPORTED(-fvisibility=hidden)
+
+		SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
+	ENDIF ()
+
+	ADD_C_FLAG_IF_SUPPORTED(-Wdocumentation)
+	ADD_C_FLAG_IF_SUPPORTED(-Wno-missing-field-initializers)
+	ADD_C_FLAG_IF_SUPPORTED(-Wstrict-aliasing=2)
+	ADD_C_FLAG_IF_SUPPORTED(-Wstrict-prototypes)
+	ADD_C_FLAG_IF_SUPPORTED(-Wdeclaration-after-statement)
+	ADD_C_FLAG_IF_SUPPORTED(-Wno-unused-const-variable)
+	ADD_C_FLAG_IF_SUPPORTED(-Wno-unused-function)
+
+	IF (APPLE) # Apple deprecated OpenSSL
+		ADD_C_FLAG_IF_SUPPORTED(-Wno-deprecated-declarations)
+	ENDIF()
+
+	IF (PROFILE)
+		SET(CMAKE_C_FLAGS "-pg ${CMAKE_C_FLAGS}")
+		SET(CMAKE_EXE_LINKER_FLAGS "-pg ${CMAKE_EXE_LINKER_FLAGS}")
+	ENDIF ()
+ENDIF()
+
+IF( NOT CMAKE_CONFIGURATION_TYPES )
+	# Build Debug by default
+	IF (NOT CMAKE_BUILD_TYPE)
+		SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
+	ENDIF ()
+ELSE()
+	# Using a multi-configuration generator eg MSVC or Xcode
+	# that uses CMAKE_CONFIGURATION_TYPES and not CMAKE_BUILD_TYPE
+ENDIF()
+
+IF (SECURITY_FOUND)
+  ADD_DEFINITIONS(-DGIT_SECURE_TRANSPORT)
+  INCLUDE_DIRECTORIES(${SECURITY_INCLUDE_DIR})
+ENDIF ()
+
+IF (OPENSSL_FOUND)
+  ADD_DEFINITIONS(-DGIT_OPENSSL)
+  INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
+  SET(SSL_LIBRARIES ${OPENSSL_LIBRARIES})
+ENDIF()
+
+
+
+IF (THREADSAFE)
+	IF (NOT WIN32)
+		FIND_PACKAGE(Threads REQUIRED)
+	ENDIF()
+
+	ADD_DEFINITIONS(-DGIT_THREADS)
+ENDIF()
+
+ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
+
+# Collect sourcefiles
+FILE(GLOB SRC_H include/git2.h include/git2/*.h include/git2/sys/*.h)
+
+# On Windows use specific platform sources
+IF (WIN32 AND NOT CYGWIN)
+	ADD_DEFINITIONS(-DWIN32 -D_WIN32_WINNT=0x0501)
+	FILE(GLOB SRC_OS src/win32/*.c src/win32/*.h)
+ELSEIF (AMIGA)
+	ADD_DEFINITIONS(-DNO_ADDRINFO -DNO_READDIR_R -DNO_MMAP)
+ELSE()
+	IF (VALGRIND)
+		ADD_DEFINITIONS(-DNO_MMAP)
+	ENDIF()
+	FILE(GLOB SRC_OS src/unix/*.c src/unix/*.h)
+ENDIF()
+FILE(GLOB SRC_GIT2 src/*.c src/*.h src/transports/*.c src/transports/*.h src/xdiff/*.c src/xdiff/*.h)
+
+# Determine architecture of the machine
+IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
+	ADD_DEFINITIONS(-DGIT_ARCH_64)
+ELSEIF (CMAKE_SIZEOF_VOID_P EQUAL 4)
+	ADD_DEFINITIONS(-DGIT_ARCH_32)
+ELSE()
+	MESSAGE(FATAL_ERROR "Unsupported architecture")
+ENDIF()
+
+# Compile and link libgit2
+ADD_LIBRARY(git2 ${SRC_H} ${SRC_GIT2} ${SRC_OS} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SHA1} ${WIN_RC})
+TARGET_LINK_LIBRARIES(git2 ${SECURITY_DIRS})
+TARGET_LINK_LIBRARIES(git2 ${COREFOUNDATION_DIRS})
+TARGET_LINK_LIBRARIES(git2 ${SSL_LIBRARIES})
+TARGET_LINK_LIBRARIES(git2 ${SSH_LIBRARIES})
+TARGET_LINK_LIBRARIES(git2 ${GSSAPI_LIBRARIES})
+TARGET_LINK_LIBRARIES(git2 ${ICONV_LIBRARIES})
+TARGET_OS_LIBRARIES(git2)
+
+# Workaround for Cmake bug #0011240 (see http://public.kitware.com/Bug/view.php?id=11240)
+# Win64+MSVC+static libs = linker error
+IF(MSVC AND GIT_ARCH_64 AND NOT BUILD_SHARED_LIBS)
+  SET_TARGET_PROPERTIES(git2 PROPERTIES STATIC_LIBRARY_FLAGS "/MACHINE:x64")
+ENDIF()
+
+MSVC_SPLIT_SOURCES(git2)
+
+IF (SONAME)
+	SET_TARGET_PROPERTIES(git2 PROPERTIES VERSION ${LIBGIT2_VERSION_STRING})
+	SET_TARGET_PROPERTIES(git2 PROPERTIES SOVERSION ${LIBGIT2_SOVERSION})
+	IF (LIBGIT2_FILENAME)
+		ADD_DEFINITIONS(-DLIBGIT2_FILENAME=\"${LIBGIT2_FILENAME}\")
+		SET_TARGET_PROPERTIES(git2 PROPERTIES OUTPUT_NAME ${LIBGIT2_FILENAME})
+	ENDIF()
+ENDIF()
+STRING(REPLACE ";" " " LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS}")
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libgit2.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libgit2.pc @ONLY)
+
+IF (MSVC_IDE)
+   # Precompiled headers
+   SET_TARGET_PROPERTIES(git2 PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h")
+   SET_SOURCE_FILES_PROPERTIES(src/win32/precompiled.c COMPILE_FLAGS "/Ycprecompiled.h")
+ENDIF ()
+
+# Install
+INSTALL(TARGETS git2
+	RUNTIME DESTINATION ${BIN_INSTALL_DIR}
+	LIBRARY DESTINATION ${LIB_INSTALL_DIR}
+	ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgit2.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig )
+INSTALL(DIRECTORY include/git2 DESTINATION ${INCLUDE_INSTALL_DIR} )
+INSTALL(FILES include/git2.h DESTINATION ${INCLUDE_INSTALL_DIR} )
+
+# Tests
+IF (BUILD_CLAR)
+	FIND_PACKAGE(PythonInterp REQUIRED)
+
+	SET(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/tests/resources/")
+	SET(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tests")
+	SET(CLAR_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/tests/resources" CACHE PATH "Path to test resources.")
+	ADD_DEFINITIONS(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\")
+	ADD_DEFINITIONS(-DCLAR_RESOURCES=\"${TEST_RESOURCES}\")
+	ADD_DEFINITIONS(-DCLAR_TMPDIR=\"libgit2_tests\")
+
+	INCLUDE_DIRECTORIES(${CLAR_PATH})
+	FILE(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/*/*.h)
+	SET(SRC_CLAR "${CLAR_PATH}/main.c" "${CLAR_PATH}/clar_libgit2.c" "${CLAR_PATH}/clar_libgit2_trace.c" "${CLAR_PATH}/clar_libgit2_timer.c" "${CLAR_PATH}/clar.c")
+
+	ADD_CUSTOM_COMMAND(
+		OUTPUT ${CLAR_PATH}/clar.suite
+		COMMAND ${PYTHON_EXECUTABLE} generate.py -f -xonline -xstress .
+		DEPENDS ${SRC_TEST}
+		WORKING_DIRECTORY ${CLAR_PATH}
+	)
+
+	SET_SOURCE_FILES_PROPERTIES(
+		${CLAR_PATH}/clar.c
+		PROPERTIES OBJECT_DEPENDS ${CLAR_PATH}/clar.suite)
+
+	ADD_EXECUTABLE(libgit2_clar ${SRC_H} ${SRC_GIT2} ${SRC_OS} ${SRC_CLAR} ${SRC_TEST} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SHA1})
+
+	TARGET_LINK_LIBRARIES(libgit2_clar ${COREFOUNDATION_DIRS})
+	TARGET_LINK_LIBRARIES(libgit2_clar ${SECURITY_DIRS})
+	TARGET_LINK_LIBRARIES(libgit2_clar ${SSL_LIBRARIES})
+	TARGET_LINK_LIBRARIES(libgit2_clar ${SSH_LIBRARIES})
+	TARGET_LINK_LIBRARIES(libgit2_clar ${GSSAPI_LIBRARIES})
+	TARGET_LINK_LIBRARIES(libgit2_clar ${ICONV_LIBRARIES})
+	TARGET_OS_LIBRARIES(libgit2_clar)
+	MSVC_SPLIT_SOURCES(libgit2_clar)
+
+	IF (MSVC_IDE)
+		# Precompiled headers
+		SET_TARGET_PROPERTIES(libgit2_clar PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h")
+	ENDIF ()
+
+	ENABLE_TESTING()
+	IF (WINHTTP OR OPENSSL_FOUND OR SECURITY_FOUND)
+		ADD_TEST(libgit2_clar libgit2_clar -ionline)
+	ELSE ()
+		ADD_TEST(libgit2_clar libgit2_clar -v)
+	ENDIF ()
+ENDIF ()
+
+IF (TAGS)
+	FIND_PROGRAM(CTAGS ctags)
+	IF (NOT CTAGS)
+		MESSAGE(FATAL_ERROR "Could not find ctags command")
+	ENDIF ()
+
+	FILE(GLOB_RECURSE SRC_ALL *.[ch])
+
+	ADD_CUSTOM_COMMAND(
+		OUTPUT tags
+		COMMAND ${CTAGS} -a ${SRC_ALL}
+		DEPENDS ${SRC_ALL}
+	)
+	ADD_CUSTOM_TARGET(
+		do_tags ALL
+		DEPENDS tags
+	)
+ENDIF ()
+
+IF (BUILD_EXAMPLES)
+	ADD_SUBDIRECTORY(examples)
+ENDIF ()
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/CONTRIBUTING.md b/app/server/vendor/rugged-0.23.3/vendor/libgit2/CONTRIBUTING.md
new file mode 100755
index 0000000..71fad63
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/CONTRIBUTING.md
@@ -0,0 +1,146 @@
+# Welcome to libgit2!
+
+We're making it easy to do interesting things with git, and we'd love to have
+your help.
+
+## Licensing
+
+By contributing to libgit2, you agree to release your contribution under
+the terms of the license.  Except for the `examples` directory, all code
+is released under the [GPL v2 with linking exception](COPYING).
+
+The `examples` code is governed by the
+[CC0 Public Domain Dedication](examples/COPYING), so that you may copy
+from them into your own application.
+
+## Discussion & Chat
+
+We hang out in the
+[`#libgit2`](http://webchat.freenode.net/?channels=#libgit2)) channel on
+irc.freenode.net.
+
+Also, feel free to open an
+[Issue](https://github.com/libgit2/libgit2/issues/new) to start a discussion
+about any concerns you have.  We like to use Issues for that so there is an
+easily accessible permanent record of the conversation.
+
+## Libgit2 Versions
+
+The `master` branch is the main branch where development happens.
+Releases are tagged
+(e.g. [v0.21.0](https://github.com/libgit2/libgit2/releases/tag/v0.21.0) )
+and when a critical bug fix needs to be backported, it will be done on a
+`<tag>-maint` maintenance branch.
+
+## Reporting Bugs
+
+First, know which version of libgit2 your problem is in and include it in
+your bug report.  This can either be a tag (e.g.
+[v0.17.0](https://github.com/libgit2/libgit2/releases/tag/v0.17.0)) or a
+commit SHA
+(e.g. [01be7863](https://github.com/libgit2/libgit2/commit/01be7863)).
+Using [`git describe`](http://git-scm.com/docs/git-describe) is a
+great way to tell us what version you're working with.
+
+If you're not running against the latest `master` branch version,
+please compile and test against that to avoid re-reporting an issue that's
+already been fixed.
+
+It's *incredibly* helpful to be able to reproduce the problem.  Please
+include a list of steps, a bit of code, and/or a zipped repository (if
+possible).  Note that some of the libgit2 developers are employees of
+GitHub, so if your repository is private, find us on IRC and we'll figure
+out a way to help you.
+
+## Pull Requests
+
+Our work flow is a [typical GitHub
+flow](https://guides.github.com/introduction/flow/index.html), where
+contributors fork the [libgit2 repository](https://github.com/libgit2/libgit2),
+make their changes on branch, and submit a
+[Pull Request](https://help.github.com/articles/using-pull-requests)
+(a.k.a. "PR").  Pull requests should usually be targeted at the `master`
+branch.
+
+Life will be a lot easier for you (and us) if you follow this pattern
+(i.e. fork, named branch, submit PR).  If you use your fork's `master`
+branch directly, things can get messy.
+
+Please include a nice description of your changes when you submit your PR;
+if we have to read the whole diff to figure out why you're contributing
+in the first place, you're less likely to get feedback and have your change
+merged in.
+
+If you are starting to work on a particular area, feel free to submit a PR
+that highlights your work in progress (and note in the PR title that it's
+not ready to merge). These early PRs are welcome and will help in getting
+visibility for your fix, allow others to comment early on the changes and
+also let others know that you are currently working on something.
+
+Before wrapping up a PR, you should be sure to:
+
+* Write tests to cover any functional changes
+* Update documentation for any changed public APIs
+* Add to the [`CHANGELOG.md`](CHANGELOG.md) file describing any major changes
+
+## Unit Tests
+
+We believe that our unit tests allow us to keep the quality of libgit2
+high: any new changes must not cause unit test failures, and new changes
+should include unit tests that cover the bug fixes or new features.
+For bug fixes, we prefer unit tests that illustrate the failure before
+the change, but pass with your changes.
+
+In addition to new tests, please ensure that your changes do not cause
+any other test failures.  Running the entire test suite is helpful
+before you submit a pull request.  When you build libgit2, the test
+suite will also be built.  You can run all tests by simply running
+the resultant `libgit2_clar` binary.  If you want to run a specific
+unit test, you can name it with the `-s` option.  For example:
+
+    libgit2_clar -sstatus::worktree::long_filenames
+
+Or you can run an entire class of tests.  For example, to run all the
+worktree status tests:
+
+    libgit2_clar -sstatus::worktree
+
+## Porting Code From Other Open-Source Projects
+
+`libgit2` is licensed under the terms of the GPL v2 with a linking
+exception.  Any code brought in must be compatible with those terms.
+
+The most common case is porting code from core Git.  Git is a pure GPL
+project, which means that in order to port code to this project, we need the
+explicit permission of the author.  Check the
+[`git.git-authors`](https://github.com/libgit2/libgit2/blob/development/git.git-authors)
+file for authors who have already consented.
+
+Other licenses have other requirements; check the license of the library
+you're porting code *from* to see what you need to do.  As a general rule,
+MIT and BSD (3-clause) licenses are typically no problem.  Apache 2.0
+license typically doesn't work due to GPL incompatibility.
+
+If your pull request uses code from core Git, another project, or code
+from a forum / Stack Overflow, then *please* flag this in your PR and make
+sure you've given proper credit to the original author in the code
+snippet.
+
+## Style Guide
+
+The public API of `libgit2` is [ANSI C](http://en.wikipedia.org/wiki/ANSI_C)
+(a.k.a. C89) compatible.  Internally, `libgit2` is written using a portable
+subset of C99 - in order to compile with GCC, Clang, MSVC, etc., we keep
+local variable declarations at the tops of blocks only and avoid `//` style
+comments.  Additionally, `libgit2` follows some extra conventions for
+function and type naming, code formatting, and testing.
+
+We like to keep the source code consistent and easy to read.  Maintaining
+this takes some discipline, but it's been more than worth it.  Take a look
+at the [conventions
+file](https://github.com/libgit2/libgit2/blob/development/CONVENTIONS.md).
+
+## Starter Projects
+
+See our [projects
+list](https://github.com/libgit2/libgit2/blob/development/PROJECTS.md).
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/CONVENTIONS.md b/app/server/vendor/rugged-0.23.3/vendor/libgit2/CONVENTIONS.md
new file mode 100755
index 0000000..5b8238a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/CONVENTIONS.md
@@ -0,0 +1,234 @@
+# Libgit2 Conventions
+
+We like to keep the source consistent and readable.  Herein are some
+guidelines that should help with that.
+
+## Compatibility
+
+`libgit2` runs on many different platforms with many different compilers.
+
+The public API of `libgit2` is [ANSI C](http://en.wikipedia.org/wiki/ANSI_C)
+(a.k.a. C89) compatible.
+
+Internally, `libgit2` is written using a portable subset of C99 - in order
+to maximize compatibility (e.g. with MSVC) we avoid certain C99
+extensions.  Specifically, we keep local variable declarations at the tops
+of blocks only and we avoid `//` style comments.
+
+Also, to the greatest extent possible, we try to avoid lots of `#ifdef`s
+inside the core code base.  This is somewhat unavoidable, but since it can
+really hamper maintainability, we keep it to a minimum.
+
+## Match Surrounding Code
+
+If there is one rule to take away from this document, it is *new code should
+match the surrounding code in a way that makes it impossible to distinguish
+the new from the old.* Consistency is more important to us than anyone's
+personal opinion about where braces should be placed or spaces vs. tabs.
+
+If a section of code is being completely rewritten, it is okay to bring it
+in line with the standards that are laid out here, but we will not accept
+submissions that contain a large number of changes that are merely
+reformatting.
+
+## Naming Things
+
+All external types and functions start with `git_` and all `#define` macros
+start with `GIT_`.  The `libgit2` API is mostly broken into related
+functional modules each with a corresponding header.  All functions in a
+module should be named like `git_modulename_functioname()`
+(e.g. `git_repository_open()`).
+
+Functions with a single output parameter should name that parameter `out`.
+Multiple outputs should be named `foo_out`, `bar_out`, etc.
+
+Parameters of type `git_oid` should be named `id`, or `foo_id`.  Calls that
+return an OID should be named `git_foo_id`.
+
+Where a callback function is used, the function should also include a
+user-supplied extra input that is a `void *` named "payload" that will be
+passed through to the callback at each invocation.
+
+## Typedefs
+
+Wherever possible, use `typedef`.  In some cases, if a structure is just a
+collection of function pointers, the pointer types don't need to be
+separately typedef'd, but loose function pointer types should be.
+
+## Exports
+
+All exported functions must be declared as:
+
+```c
+GIT_EXTERN(result_type) git_modulename_functionname(arg_list);
+```
+
+## Internals
+
+Functions whose *modulename* is followed by two underscores,
+for example `git_odb__read_packed`, are semi-private functions.
+They are primarily intended for use within the library itself,
+and may disappear or change their signature in a future release.
+
+## Parameters
+
+Out parameters come first.
+
+Whenever possible, pass argument pointers as `const`.  Some structures (such
+as `git_repository` and `git_index`) have mutable internal structure that
+prevents this.
+
+Callbacks should always take a `void *` payload as their last parameter.
+Callback pointers are grouped with their payloads, and typically come last
+when passed as arguments:
+
+```c
+int git_foo(git_repository *repo, git_foo_cb callback, void *payload);
+```
+
+## Memory Ownership
+
+Some APIs allocate memory which the caller is responsible for freeing; others
+return a pointer into a buffer that's owned by some other object.  Make this
+explicit in the documentation.
+
+## Return codes
+
+Most public APIs should return an `int` error code.  As is typical with most
+C library functions, a zero value indicates success and a negative value
+indicates failure.
+
+Some bindings will transform these returned error codes into exception
+types, so returning a semantically appropriate error code is important.
+Check
+[`include/git2/errors.h`](https://github.com/libgit2/libgit2/blob/development/include/git2/errors.h)
+for the return codes already defined.
+
+In your implementation, use `giterr_set()` to provide extended error
+information to callers.
+
+If a `libgit2` function internally invokes another function that reports an
+error, but the error is not propagated up, use `giterr_clear()` to prevent
+callers from getting the wrong error message later on.
+
+
+## Structs
+
+Most public types should be opaque, e.g.:
+
+```C
+typedef struct git_odb git_odb;
+```
+
+...with allocation functions returning an "instance" created within
+the library, and not within the application.  This allows the type
+to grow (or shrink) in size without rebuilding client code.
+
+To preserve ABI compatibility, include an `int version` field in all opaque
+structures, and initialize to the latest version in the construction call.
+Increment the "latest" version whenever the structure changes, and try to only
+append to the end of the structure.
+
+## Option Structures
+
+If a function's parameter count is too high, it may be desirable to package
+up the options in a structure.  Make them transparent, include a version
+field, and provide an initializer constant or constructor.  Using these
+structures should be this easy:
+
+```C
+git_foo_options opts = GIT_FOO_OPTIONS_INIT;
+opts.baz = BAZ_OPTION_ONE;
+git_foo(&opts);
+```
+
+## Enumerations
+
+Typedef all enumerated types.  If each option stands alone, use the enum
+type for passing them as parameters; if they are flags to be OR'ed together,
+pass them as `unsigned int` or `uint32_t` or some appropriate type.
+
+## Code Layout
+
+Try to keep lines less than 80 characters long.  This is a loose
+requirement, but going significantly over 80 columns is not nice.
+
+Use common sense to wrap most code lines; public function declarations
+can use a couple of different styles:
+
+```c
+/** All on one line is okay if it fits */
+GIT_EXTERN(int) git_foo_simple(git_oid *id);
+
+/** Otherwise one argument per line is a good next step */
+GIT_EXTERN(int) git_foo_id(
+	git_oid **out,
+	int a,
+	int b);
+```
+
+Indent with tabs; set your editor's tab width to 4 for best effect.
+
+Avoid trailing whitespace and only commit Unix-style newlines (i.e. no CRLF
+in the repository - just set `core.autocrlf` to true if you are writing code
+on a Windows machine).
+
+## Documentation
+
+All comments should conform to Doxygen "javadoc" style conventions for
+formatting the public API documentation.  Try to document every parameter,
+and keep the comments up to date if you change the parameter list.
+
+## Public Header Template
+
+Use this template when creating a new public header.
+
+```C
+#ifndef INCLUDE_git_${filename}_h__
+#define INCLUDE_git_${filename}_h__
+
+#include "git/common.h"
+
+/**
+ * @file git/${filename}.h
+ * @brief Git some description
+ * @defgroup git_${filename} some description routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/* ... definitions ... */
+
+/** @} */
+GIT_END_DECL
+#endif
+```
+
+## Inlined functions
+
+All inlined functions must be declared as:
+
+```C
+GIT_INLINE(result_type) git_modulename_functionname(arg_list);
+```
+
+`GIT_INLINE` (or `inline`) should not be used in public headers in order
+to preserve ANSI C compatibility.
+
+## Tests
+
+`libgit2` uses the [clar](https://github.com/vmg/clar) testing framework.
+
+All PRs should have corresponding tests.
+
+* If the PR fixes an existing issue, the test should fail prior to applying
+  the PR and succeed after applying it.
+* If the PR is for new functionality, then the tests should exercise that
+  new functionality to a certain extent.  We don't require 100% coverage
+  right now (although we are getting stricter over time).
+
+When adding new tests, we prefer if you attempt to reuse existing test data
+(in `tests-clar/resources/`) if possible.  If you are going to add new test
+repositories, please try to strip them of unnecessary files (e.g. sample
+hooks, etc).
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/COPYING b/app/server/vendor/rugged-0.23.3/vendor/libgit2/COPYING
new file mode 100755
index 0000000..1b88b9b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/COPYING
@@ -0,0 +1,960 @@
+ libgit2 is Copyright (C) the libgit2 contributors,
+ unless otherwise stated. See the AUTHORS file for details.
+
+ Note that the only valid version of the GPL as far as this project
+ is concerned is _this_ particular version of the license (ie v2, not
+ v2.2 or v3.x or whatever), unless explicitly otherwise stated.
+
+----------------------------------------------------------------------
+
+			LINKING EXCEPTION
+
+ In addition to the permissions in the GNU General Public License,
+ the authors give you unlimited permission to link the compiled
+ version of this library into combinations with other programs,
+ and to distribute those combinations without any restriction
+ coming from the use of this file.  (The General Public License
+ restrictions do apply in other respects; for example, they cover
+ modification of the file, and distribution when not linked into
+ a combined executable.)
+
+----------------------------------------------------------------------
+
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+----------------------------------------------------------------------
+
+The bundled ZLib code is licensed under the ZLib license:
+
+Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup at gzip.org          madler at alumni.caltech.edu
+
+----------------------------------------------------------------------
+
+The Clar framework is licensed under the ISC license:
+
+Copyright (c) 2011-2015 Vicent Marti
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+----------------------------------------------------------------------
+
+The regex library (deps/regex/) is licensed under the GNU LGPL
+(available at the end of this file).
+
+Definitions for data structures and routines for the regular
+expression library.
+
+Copyright (C) 1985,1989-93,1995-98,2000,2001,2002,2003,2005,2006,2008
+Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+ 
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with the GNU C Library; if not, write to the Free
+Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+----------------------------------------------------------------------
+
+The bundled winhttp definition files (deps/winhttp/) are licensed under
+the GNU LGPL (available at the end of this file).
+
+Copyright (C) 2007 Francois Gouget
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+----------------------------------------------------------------------
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+----------------------------------------------------------------------
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/Makefile.embed b/app/server/vendor/rugged-0.23.3/vendor/libgit2/Makefile.embed
new file mode 100755
index 0000000..eb8a78e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/Makefile.embed
@@ -0,0 +1,60 @@
+PLATFORM=$(shell uname -s)
+
+ifneq (,$(CROSS_COMPILE))
+	PREFIX=$(CROSS_COMPILE)-
+else
+	PREFIX=
+endif
+
+MINGW=0
+ifneq (,$(findstring MINGW32,$(PLATFORM)))
+	MINGW=1
+endif
+ifneq (,$(findstring mingw,$(CROSS_COMPILE)))
+	MINGW=1
+endif
+
+rm=rm -f
+AR=$(PREFIX)ar cq
+RANLIB=$(PREFIX)ranlib
+
+LIBNAME=libgit2.a
+
+ifeq ($(MINGW),1)
+	CC=gcc
+else
+	CC=cc
+endif
+
+CC:=$(PREFIX)$(CC)
+
+INCLUDES= -I. -Isrc -Iinclude -Ideps/http-parser -Ideps/zlib
+
+DEFINES= $(INCLUDES) -DNO_VIZ -DSTDC -DNO_GZIP -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $(EXTRA_DEFINES)
+CFLAGS= -g $(DEFINES) -Wall -Wextra -Wno-missing-field-initializers -O2 $(EXTRA_CFLAGS)
+
+SRCS = $(wildcard src/*.c) $(wildcard src/transports/*.c) $(wildcard src/xdiff/*.c) $(wildcard deps/http-parser/*.c) $(wildcard deps/zlib/*.c) src/hash/hash_generic.c
+
+ifeq ($(MINGW),1)
+	SRCS += $(wildcard src/win32/*.c) $(wildcard src/compat/*.c) deps/regex/regex.c
+	INCLUDES += -Ideps/regex
+	DEFINES += -DWIN32 -D_WIN32_WINNT=0x0501 -D__USE_MINGW_ANSI_STDIO=1
+else
+	SRCS += $(wildcard src/unix/*.c) 
+	CFLAGS += -fPIC
+endif
+
+OBJS = $(patsubst %.c,%.o,$(SRCS))
+
+%.c.o:
+	$(CC) $(CFLAGS) -c $*.c
+
+all: $(LIBNAME)
+
+$(LIBNAME): $(OBJS)
+	$(rm) $@
+	$(AR) $@ $(OBJS)
+	$(RANLIB) $@
+
+clean:
+	$(rm) $(OBJS) $(LIBNAME)
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/PROJECTS.md b/app/server/vendor/rugged-0.23.3/vendor/libgit2/PROJECTS.md
new file mode 100755
index 0000000..4f200b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/PROJECTS.md
@@ -0,0 +1,101 @@
+Projects For LibGit2
+====================
+
+So, you want to start helping out with `libgit2`? That's fantastic! We
+welcome contributions and we promise we'll try to be nice.
+
+This is a list of libgit2 related projects that new contributors can take
+on.  It includes a number of good starter projects and well as some larger
+ideas that no one is actively working on.
+
+## Before You Start
+
+Please start by reading the [README.md](README.md),
+[CONTRIBUTING.md](CONTRIBUTING.md), and [CONVENTIONS.md](CONVENTIONS.md)
+files before diving into one of these projects.  Those explain our work
+flow and coding conventions to help ensure that your work will be easily
+integrated into libgit2.
+
+Next, work through the build instructions and make sure you can clone the
+repository, compile it, and run the tests successfully.  That will make
+sure that your development environment is set up correctly and you are
+ready to start on libgit2 development.
+
+## Starter Projects
+
+These are good small projects to get started with libgit2.
+
+* Look at the `examples/` programs, find an existing one that mirrors a
+  core Git command and add a missing command-line option.  There are many
+  gaps right now and this helps demonstrate how to use the library.  Here
+  are some specific ideas (though there are many more):
+    * Fix the `examples/diff.c` implementation of the `-B`
+      (a.k.a. `--break-rewrites`) command line option to actually look for
+      the optional `[<n>][/<m>]` configuration values. There is an
+      existing comment that reads `/* TODO: parse thresholds */`. The
+      trick to this one will be doing it in a manner that is clean and
+      simple, but still handles the various cases correctly (e.g. `-B/70%`
+      is apparently a legal setting).
+    * Implement the `--log-size` option for `examples/log.c`. I think all
+      the data is available, you would just need to add the code into the
+      `print_commit()` routine (along with a way of passing the option
+      into that function).
+    * As an extension to the matching idea for `examples/log.c`, add the
+      `-i` option to use `strcasestr()` for matches.
+    * For `examples/log.c`, implement the `--first-parent` option now that
+      libgit2 supports it in the revwalk API.
+* Pick a Git command that is not already emulated in `examples/` and write
+  a new example that mirrors the behavior.  Examples don't have to be
+  perfect emulations, but should demonstrate how to use the libgit2 APIs
+  to get results that are similar to Git commands.  This lets you (and us)
+  easily exercise a particular facet of the API and measure compatability
+  and feature parity with core git.
+* Submit a PR to clarify documentation! While we do try to document all of
+  the APIs, your fresh eyes on the documentation will find areas that are
+  confusing much more easily.
+
+If none of these appeal to you, take a look at our issues list to see if
+there are any unresolved issues you'd like to jump in on.
+
+## Larger Projects
+
+These are ideas for larger projects mostly taken from our backlog of
+[Issues](https://github.com/libgit2/libgit2/issues).  Please don't dive
+into one of these as a first project for libgit2 - we'd rather get to
+know you first by successfully shipping your work on one of the smaller
+projects above.
+
+Some of these projects are broken down into subprojects and/or have
+some incremental steps listed towards the larger goal.  Those steps
+might make good smaller projects by themselves.
+
+* Port part of the Git test suite to run against the command line emulation
+  in examples/
+    * Pick a Git command that is emulated in our examples/ area
+    * Extract the Git tests that exercise that command
+    * Convert the tests to call our emulation
+    * These tests could go in examples/tests/...
+* Fix symlink support for files in the .git directory (i.e. don't overwrite
+  the symlinks when writing the file contents back out)
+* Add hooks API to enumerate and manage hooks (not run them at this point)
+    * Enumeration of available hooks
+    * Lookup API to see which hooks have a script and get the script
+    * Read/write API to load a hook script and write a hook script
+    * Eventually, callback API to invoke a hook callback when libgit2
+      executes the action in question
+* Isolate logic of ignore evaluation into a standalone API
+* Upgrade internal libxdiff code to latest from core Git
+* Improve index internals with hashtable lookup for files instead of
+  using binary search every time
+* Tree builder improvements:
+    * Extend to allow building a tree hierarchy
+* Apply-patch API
+* Add a patch editing API to enable "git add -p" type operations
+* Textconv API to filter binary data before generating diffs (something
+  like the current Filter API, probably).
+* Performance profiling and improvement
+* Support "git replace" ref replacements
+* Include conflicts in diff results and in status
+    * GIT_DELTA_CONFLICT for items in conflict (with multiple files)
+    * Appropriate flags for status
+* Support sparse checkout (i.e. "core.sparsecheckout" and ".git/info/sparse-checkout")
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/README.md b/app/server/vendor/rugged-0.23.3/vendor/libgit2/README.md
new file mode 100755
index 0000000..3191aee
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/README.md
@@ -0,0 +1,244 @@
+libgit2 - the Git linkable library
+==================================
+
+[![Travis Build Status](https://secure.travis-ci.org/libgit2/libgit2.svg?branch=master)](http://travis-ci.org/libgit2/libgit2)
+[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/xvof5b4t5480a2q3/branch/master?svg=true)](https://ci.appveyor.com/project/libgit2/libgit2/branch/master)
+[![Coverity Scan Build Status](https://scan.coverity.com/projects/639/badge.svg)](https://scan.coverity.com/projects/639)
+
+`libgit2` is a portable, pure C implementation of the Git core methods
+provided as a re-entrant linkable library with a solid API, allowing you to
+write native speed custom Git applications in any language with bindings.
+
+`libgit2` is licensed under a **very permissive license** (GPLv2 with a special
+Linking Exception).  This basically means that you can link it (unmodified)
+with any kind of software without having to release its source code.
+Additionally, the example code has been released to the public domain (see the
+[separate license](examples/COPYING) for more information).
+
+* Website: [libgit2.github.com](http://libgit2.github.com)
+* StackOverflow Tag: [libgit2](http://stackoverflow.com/questions/tagged/libgit2)
+* Issues: [GitHub Issues](https://github.com/libgit2/libgit2/issues) (Right here!)
+* API documentation: <http://libgit2.github.com/libgit2>
+* IRC: [#libgit2](irc://irc.freenode.net/libgit2) on irc.freenode.net.
+* Mailing list: The libgit2 mailing list was
+    traditionally hosted in Librelist but has been deprecated. We encourage you to
+    [use StackOverflow](http://stackoverflow.com/questions/tagged/libgit2) instead for any questions regarding
+    the library, or [open an issue](https://github.com/libgit2/libgit2/issues)
+    on GitHub for bug reports.  The mailing list archives are still available at
+    <http://librelist.com/browser/libgit2/>.
+
+
+What It Can Do
+==============
+
+`libgit2` is already very usable and is being used in production for many
+applications including the GitHub.com site, in Plastic SCM and also powering
+Microsoft's Visual Studio tools for Git.  The library provides:
+
+* SHA conversions, formatting and shortening
+* abstracted ODB backend system
+* commit, tag, tree and blob parsing, editing, and write-back
+* tree traversal
+* revision walking
+* index file (staging area) manipulation
+* reference management (including packed references)
+* config file management
+* high level repository management
+* thread safety and reentrancy
+* descriptive and detailed error messages
+* ...and more (over 175 different API calls)
+
+Optional dependencies
+=====================
+
+While the library provides git functionality without the need for
+dependencies, it can make use of a few libraries to add to it:
+
+- pthreads (non-Windows) to enable threadsafe access as well as multi-threaded pack generation
+- OpenSSL (non-Windows) to talk over HTTPS and provide the SHA-1 functions
+- LibSSH2 to enable the SSH transport
+- iconv (OSX) to handle the HFS+ path encoding peculiarities
+
+Initialization
+===============
+
+The library needs to keep track of some global state. Call
+
+    git_libgit2_init();
+
+before calling any other libgit2 functions. You can call this function many times. A matching number of calls to
+
+    git_libgit2_shutdown();
+
+will free the resources.  Note that if you have worker threads, you should
+call `git_libgit2_shutdown` *after* those threads have exited.  If you
+require assistance coordinating this, simply have the worker threads call
+`git_libgit2_init` at startup and `git_libgit2_shutdown` at shutdown.
+
+Threading
+=========
+
+See [THREADING](THREADING.md) for information
+
+Building libgit2 - Using CMake
+==============================
+
+`libgit2` builds cleanly on most platforms without any external dependencies.
+Under Unix-like systems, like Linux, \*BSD and Mac OS X, libgit2 expects `pthreads` to be available;
+they should be installed by default on all systems. Under Windows, libgit2 uses the native Windows API
+for threading.
+
+The `libgit2` library is built using [CMake](<http://www.cmake.org>) (version 2.8 or newer) on all platforms.
+
+On most systems you can build the library using the following commands
+
+	$ mkdir build && cd build
+	$ cmake ..
+	$ cmake --build .
+
+Alternatively you can point the CMake GUI tool to the CMakeLists.txt file and generate platform specific build project or IDE workspace.
+
+To install the library you can specify the install prefix by setting:
+
+	$ cmake .. -DCMAKE_INSTALL_PREFIX=/install/prefix
+	$ cmake --build . --target install
+
+For more advanced use or questions about CMake please read <http://www.cmake.org/Wiki/CMake_FAQ>.
+
+The following CMake variables are declared:
+
+- `BIN_INSTALL_DIR`: Where to install binaries to.
+- `LIB_INSTALL_DIR`: Where to install libraries to.
+- `INCLUDE_INSTALL_DIR`: Where to install headers to.
+- `BUILD_SHARED_LIBS`: Build libgit2 as a Shared Library (defaults to ON)
+- `BUILD_CLAR`: Build [Clar](https://github.com/vmg/clar)-based test suite (defaults to ON)
+- `THREADSAFE`: Build libgit2 with threading support (defaults to ON)
+- `STDCALL`: Build libgit2 as `stdcall`. Turn off for `cdecl` (Windows; defaults to ON)
+
+Compiler and linker options
+---------------------------
+
+CMake lets you specify a few variables to control the behavior of the
+compiler and linker. These flags are rarely used but can be useful for
+64-bit to 32-bit cross-compilation.
+
+- `CMAKE_C_FLAGS`: Set your own compiler flags
+- `CMAKE_FIND_ROOT_PATH`: Override the search path for libraries
+- `ZLIB_LIBRARY`, `OPENSSL_SSL_LIBRARY` AND `OPENSSL_CRYPTO_LIBRARY`:
+Tell CMake where to find those specific libraries
+
+MacOS X
+-------
+
+If you want to build a universal binary for Mac OS X, CMake sets it
+all up for you if you use `-DCMAKE_OSX_ARCHITECTURES="i386;x86_64"`
+when configuring.
+
+Windows
+-------
+
+You need to run the CMake commands from the Visual Studio command
+prompt, not the regular or Windows SDK one. Select the right generator
+for your version with the `-G "Visual Studio X" option.
+
+See [the website](https://libgit2.github.com/docs/guides/build-and-link)
+for more detailed instructions.
+
+Android
+-------
+
+Extract toolchain from NDK using, `make-standalone-toolchain.sh` script.
+Optionally, crosscompile and install OpenSSL inside of it. Then create CMake
+toolchain file that configures paths to your crosscompiler (substitute `{PATH}`
+with full path to the toolchain):
+
+	SET(CMAKE_SYSTEM_NAME Linux)
+	SET(CMAKE_SYSTEM_VERSION Android)
+
+	SET(CMAKE_C_COMPILER   {PATH}/bin/arm-linux-androideabi-gcc)
+	SET(CMAKE_CXX_COMPILER {PATH}/bin/arm-linux-androideabi-g++)
+	SET(CMAKE_FIND_ROOT_PATH {PATH}/sysroot/)
+
+	SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+	SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+	SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+Add `-DCMAKE_TOOLCHAIN_FILE={pathToToolchainFile}` to cmake command
+when configuring.
+
+Language Bindings
+==================================
+
+Here are the bindings to libgit2 that are currently available:
+
+* C++
+    * libqgit2, Qt bindings <https://projects.kde.org/projects/playground/libs/libqgit2/>
+* Chicken Scheme
+    * chicken-git <https://wiki.call-cc.org/egg/git>
+* D
+    * dlibgit <https://github.com/s-ludwig/dlibgit>
+* Delphi
+    * GitForDelphi <https://github.com/libgit2/GitForDelphi>
+* Erlang
+    * Geef <https://github.com/carlosmn/geef>
+* Go
+    * git2go <https://github.com/libgit2/git2go>
+* GObject
+    * libgit2-glib <https://live.gnome.org/Libgit2-glib>
+* Haskell
+    * hgit2 <https://github.com/fpco/gitlib>
+* Java
+    * Jagged <https://github.com/ethomson/jagged>
+* Julia
+    * LibGit2.jl <https://github.com/jakebolewski/LibGit2.jl>
+* Lua
+    * luagit2 <https://github.com/libgit2/luagit2>
+* .NET
+    * libgit2sharp <https://github.com/libgit2/libgit2sharp>
+* Node.js
+    * node-gitteh <https://github.com/libgit2/node-gitteh>
+    * nodegit <https://github.com/tbranyen/nodegit>
+* Objective-C
+    * objective-git <https://github.com/libgit2/objective-git>
+* OCaml
+    * ocaml-libgit2 <https://github.com/fxfactorial/ocaml-libgit2>
+* Parrot Virtual Machine
+    * parrot-libgit2 <https://github.com/letolabs/parrot-libgit2>
+* Perl
+    * Git-Raw <https://github.com/jacquesg/p5-Git-Raw>
+* PHP
+    * php-git <https://github.com/libgit2/php-git>
+* PowerShell
+    * GitPowerShell <https://github.com/ethomson/gitpowershell>
+* Python
+    * pygit2 <https://github.com/libgit2/pygit2>
+* R
+    * git2r <https://github.com/ropensci/git2r>
+* Ruby
+    * Rugged <https://github.com/libgit2/rugged>
+* Rust
+    * git2-rs <https://github.com/alexcrichton/git2-rs>
+* Swift
+    * Gift <https://github.com/modocache/Gift>
+* Vala
+    * libgit2.vapi <https://github.com/apmasell/vapis/blob/master/libgit2.vapi>
+
+If you start another language binding to libgit2, please let us know so
+we can add it to the list.
+
+How Can I Contribute?
+==================================
+
+Check the [contribution guidelines](CONTRIBUTING.md) to understand our
+workflow, the libgit2 [coding conventions](CONVENTIONS.md), and out list of
+[good starting projects](PROJECTS.md).
+
+License
+==================================
+
+`libgit2` is under GPL2 **with linking exception**. This means you can link to
+and use the library from any program, proprietary or open source; paid or
+gratis.  However, you cannot modify libgit2 and distribute it without
+supplying the source.
+
+See the [COPYING file](COPYING) for the full license text.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/THREADING.md b/app/server/vendor/rugged-0.23.3/vendor/libgit2/THREADING.md
new file mode 100755
index 0000000..3717d6c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/THREADING.md
@@ -0,0 +1,107 @@
+Threads in libgit2
+==================
+
+You may safely use any libgit2 object from any thread, though there
+may be issues depending on the cryptographic libraries libgit2 or its
+dependencies link to (more on this later). For libgit2 itself,
+provided you take the following into consideration you won't run into
+issues:
+
+Sharing objects
+---------------
+
+Use an object from a single thread at a time. Most data structures do
+not guard against concurrent access themselves. This is because they
+are rarely used in isolation and it makes more sense to synchronize
+access via a larger lock or similar mechanism.
+
+There are some objects which are read-only/immutable and are thus safe
+to share across threads, such as references and configuration
+snapshots.
+
+Error messages
+--------------
+
+The error message is thread-local. The `giterr_last()` call must
+happen on the same thread as the error in order to get the
+message. Often this will be the case regardless, but if you use
+something like the [GCD](http://en.wikipedia.org/wiki/Grand_Central_Dispatch)
+on Mac OS X (where code is executed on an arbitrary thread), the code
+must make sure to retrieve the error code on the thread where the error
+happened.
+
+Threads and cryptographic libraries
+=======================================
+
+On Windows
+----------
+
+When built as a native Windows DLL, libgit2 uses WinCNG and WinHTTP,
+both of which are thread-safe. You do not need to do anything special.
+
+When using libssh2 which itself uses WinCNG, there are no special
+steps necessary. If you are using a MinGW or similar environment where
+libssh2 uses OpenSSL or libgcrypt, then the general case affects
+you.
+
+On Mac OS X
+-----------
+
+By default we use libcurl to perform the encryption. The
+system-provided libcurl uses SecureTransport, so no special steps are
+necessary. If you link against another libcurl (e.g. from homebrew)
+refer to the general case.
+
+If the option to use libcurl was deactivated, the library makes use of
+CommonCrypto and SecureTransport for cryptographic support. These are
+thread-safe and you do not need to do anything special.
+
+Note that libssh2 may still use OpenSSL itself. In that case, the
+general case still affects you if you use ssh.
+
+General Case
+------------
+
+By default we use libcurl, which has its own ![recommendations for
+thread safety](http://curl.haxx.se/libcurl/c/libcurl-tutorial.html#Multi-threading).
+
+If libcurl was not found or was disabled, libgit2 uses OpenSSL to be
+able to use HTTPS as a transport. This library is made to be
+thread-implementation agnostic, and the users of the library must set
+which locking function it should use. This means that libgit2 cannot
+know what to set as the user of libgit2 may use OpenSSL independently
+and the locking settings must survive libgit2 shutting down.
+
+libgit2 does provide a last-resort convenience function
+`git_openssl_set_locking()` (available in `sys/openssl.h`) to use the
+platform-native mutex mechanisms to perform the locking, which you may
+rely on if you do not want to use OpenSSL outside of libgit2, or you
+know that libgit2 will outlive the rest of the operations. It is not
+safe to use OpenSSL multi-threaded after libgit2's shutdown function
+has been called.
+
+If your programming language offers a package/bindings for OpenSSL,
+you should very strongly prefer to use that in order to set up
+locking, as they provide a level of coördination which is impossible
+when using this function.
+
+See the
+[OpenSSL documentation](https://www.openssl.org/docs/crypto/threads.html)
+on threading for more details.
+
+Be also aware that libgit2 does not always link against OpenSSL
+if there are alternatives provided by the system.
+
+libssh2 may be linked against OpenSSL or libgcrypt. If it uses
+OpenSSL, you only need to set up threading for OpenSSL once and the
+above paragraphs are enough. If it uses libgcrypt, then you need to
+set up its locking before using it multi-threaded. libgit2 has no
+direct connection to libgcrypt and thus has not convenience functions for
+it (but libgcrypt has macros). Read libgcrypt's
+[threading documentation for more information](http://www.gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html)
+
+It is your responsibility as an application author or packager to know
+what your dependencies are linked against and to take the appropriate
+steps to ensure the cryptographic libraries are thread-safe. We agree
+that this situation is far from ideal but at this time it is something
+the application authors need to deal with.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/api.docurium b/app/server/vendor/rugged-0.23.3/vendor/libgit2/api.docurium
new file mode 100755
index 0000000..9e17817
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/api.docurium
@@ -0,0 +1,13 @@
+{
+ "name":   "libgit2",
+ "github": "libgit2/libgit2",
+ "input":  "include/git2",
+ "prefix": "git_",
+ "output": "docs",
+ "branch": "gh-pages",
+ "examples": "examples",
+ "legacy":  {
+    "input": {"src/git": ["v0.1.0"],
+              "src/git2": ["v0.2.0", "v0.3.0"]}
+  }
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/appveyor.yml b/app/server/vendor/rugged-0.23.3/vendor/libgit2/appveyor.yml
new file mode 100755
index 0000000..166fa56
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/appveyor.yml
@@ -0,0 +1,39 @@
+version: '{build}'
+branches:
+  only:
+  - master
+  - /^maint.*/
+environment:
+  GITTEST_INVASIVE_FS_STRUCTURE: 1
+  GITTEST_INVASIVE_FS_SIZE: 1
+
+  matrix:
+  - GENERATOR: "Visual Studio 11"
+    ARCH: 32
+  - GENERATOR: "Visual Studio 11 Win64"
+    ARCH: 64
+  - GENERATOR: "MSYS Makefiles"
+    ARCH: 32
+  - GENERATOR: "MSYS Makefiles"
+    ARCH: i686 # this is for 32-bit MinGW-w64
+  - GENERATOR: "MSYS Makefiles"
+    ARCH: 64
+matrix:
+  allow_failures:
+    - GENERATOR: "MSYS Makefiles"
+      ARCH: 32
+cache:
+- i686-4.9.2-release-win32-sjlj-rt_v3-rev1.7z
+- x86_64-4.9.2-release-win32-seh-rt_v3-rev1.7z
+build_script:
+- ps: |
+    mkdir build
+    cd build
+    if ($env:GENERATOR -ne "MSYS Makefiles") {
+      cmake -D ENABLE_TRACE=ON -D BUILD_CLAR=ON -D MSVC_CRTDBG=ON .. -G"$env:GENERATOR"
+      cmake --build . --config Debug
+    }
+- cmd: |
+    if "%GENERATOR%"=="MSYS Makefiles" (C:\MinGW\msys\1.0\bin\sh --login /c/projects/libgit2/script/appveyor-mingw.sh)
+test_script:
+- ps: ctest -V .
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/AddCFlagIfSupported.cmake b/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/AddCFlagIfSupported.cmake
new file mode 100755
index 0000000..67fc895
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/AddCFlagIfSupported.cmake
@@ -0,0 +1,16 @@
+# - Append compiler flag to CMAKE_C_FLAGS if compiler supports it
+# ADD_C_FLAG_IF_SUPPORTED(<flag>)
+#  <flag> - the compiler flag to test
+# This internally calls the CHECK_C_COMPILER_FLAG macro.
+
+INCLUDE(CheckCCompilerFlag)
+
+MACRO(ADD_C_FLAG_IF_SUPPORTED _FLAG)
+	STRING(TOUPPER ${_FLAG} UPCASE)
+	STRING(REGEX REPLACE "^-" "" UPCASE_PRETTY ${UPCASE}) 
+	CHECK_C_COMPILER_FLAG(${_FLAG} IS_${UPCASE_PRETTY}_SUPPORTED)
+
+	IF(IS_${UPCASE_PRETTY}_SUPPORTED)
+		SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_FLAG}")
+	ENDIF()
+ENDMACRO()
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake b/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake
new file mode 100755
index 0000000..ebd619a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake
@@ -0,0 +1,9 @@
+IF (COREFOUNDATION_INCLUDE_DIR AND COREFOUNDATION_DIRS)
+  SET(COREFOUNDATION_FOUND TRUE)
+ELSE ()
+  FIND_PATH(COREFOUNDATION_INCLUDE_DIR NAMES CoreFoundation.h)
+  FIND_LIBRARY(COREFOUNDATION_DIRS NAMES CoreFoundation)
+  IF (COREFOUNDATION_INCLUDE_DIR AND COREFOUNDATION_DIRS)
+    SET(COREFOUNDATION_FOUND TRUE)
+  ENDIF ()
+ENDIF ()
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake b/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake
new file mode 100755
index 0000000..8520d35
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake
@@ -0,0 +1,324 @@
+# - Try to find GSSAPI
+# Once done this will define
+#
+#  KRB5_CONFIG - Path to krb5-config
+#  GSSAPI_ROOT_DIR - Set this variable to the root installation of GSSAPI
+#
+# Read-Only variables:
+#  GSSAPI_FLAVOR_MIT - set to TURE if MIT Kerberos has been found
+#  GSSAPI_FLAVOR_HEIMDAL - set to TRUE if Heimdal Keberos has been found
+#  GSSAPI_FOUND - system has GSSAPI
+#  GSSAPI_INCLUDE_DIR - the GSSAPI include directory
+#  GSSAPI_LIBRARIES - Link these to use GSSAPI
+#  GSSAPI_DEFINITIONS - Compiler switches required for using GSSAPI
+#
+#=============================================================================
+#  Copyright (c) 2013 Andreas Schneider <asn at cryptomilk.org>
+#
+#  Distributed under the OSI-approved BSD License (the "License");
+#  see accompanying file Copyright.txt for details.
+#
+#  This software is distributed WITHOUT ANY WARRANTY; without even the
+#  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#  See the License for more information.
+#=============================================================================
+#
+
+find_path(GSSAPI_ROOT_DIR
+    NAMES
+        include/gssapi.h
+        include/gssapi/gssapi.h
+    HINTS
+        ${_GSSAPI_ROOT_HINTS}
+    PATHS
+        ${_GSSAPI_ROOT_PATHS}
+)
+mark_as_advanced(GSSAPI_ROOT_DIR)
+
+if (UNIX)
+    find_program(KRB5_CONFIG
+        NAMES
+            krb5-config
+        PATHS
+            ${GSSAPI_ROOT_DIR}/bin
+            /opt/local/bin)
+    mark_as_advanced(KRB5_CONFIG)
+
+    if (KRB5_CONFIG)
+        # Check if we have MIT KRB5
+        execute_process(
+            COMMAND
+                ${KRB5_CONFIG} --vendor
+            RESULT_VARIABLE
+                _GSSAPI_VENDOR_RESULT
+            OUTPUT_VARIABLE
+                _GSSAPI_VENDOR_STRING)
+
+        if (_GSSAPI_VENDOR_STRING MATCHES ".*Massachusetts.*")
+            set(GSSAPI_FLAVOR_MIT TRUE)
+        else()
+            execute_process(
+                COMMAND
+                    ${KRB5_CONFIG} --libs gssapi
+                RESULT_VARIABLE
+                    _GSSAPI_LIBS_RESULT
+                OUTPUT_VARIABLE
+                    _GSSAPI_LIBS_STRING)
+
+            if (_GSSAPI_LIBS_STRING MATCHES ".*roken.*")
+                set(GSSAPI_FLAVOR_HEIMDAL TRUE)
+            endif()
+        endif()
+
+        # Get the include dir
+        execute_process(
+            COMMAND
+                ${KRB5_CONFIG} --cflags gssapi
+            RESULT_VARIABLE
+                _GSSAPI_INCLUDE_RESULT
+            OUTPUT_VARIABLE
+                _GSSAPI_INCLUDE_STRING)
+        string(REGEX REPLACE "(\r?\n)+$" "" _GSSAPI_INCLUDE_STRING "${_GSSAPI_INCLUDE_STRING}")
+        string(REGEX REPLACE " *-I" "" _GSSAPI_INCLUDEDIR "${_GSSAPI_INCLUDE_STRING}")
+    endif()
+
+    if (NOT GSSAPI_FLAVOR_MIT AND NOT GSSAPI_FLAVOR_HEIMDAL)
+        # Check for HEIMDAL
+        find_package(PkgConfig)
+        if (PKG_CONFIG_FOUND)
+            pkg_check_modules(_GSSAPI heimdal-gssapi)
+        endif (PKG_CONFIG_FOUND)
+
+        if (_GSSAPI_FOUND)
+            set(GSSAPI_FLAVOR_HEIMDAL TRUE)
+        else()
+            find_path(_GSSAPI_ROKEN
+                NAMES
+                    roken.h
+                PATHS
+                    ${GSSAPI_ROOT_DIR}/include
+                    ${_GSSAPI_INCLUDEDIR})
+            if (_GSSAPI_ROKEN)
+                set(GSSAPI_FLAVOR_HEIMDAL TRUE)
+            endif()
+        endif ()
+    endif()
+endif (UNIX)
+
+find_path(GSSAPI_INCLUDE_DIR
+    NAMES
+        gssapi.h
+        gssapi/gssapi.h
+    PATHS
+        ${GSSAPI_ROOT_DIR}/include
+        ${_GSSAPI_INCLUDEDIR}
+)
+
+if (GSSAPI_FLAVOR_MIT)
+    find_library(GSSAPI_LIBRARY
+        NAMES
+            gssapi_krb5
+        PATHS
+            ${GSSAPI_ROOT_DIR}/lib
+            ${_GSSAPI_LIBDIR}
+    )
+
+    find_library(KRB5_LIBRARY
+        NAMES
+            krb5
+        PATHS
+            ${GSSAPI_ROOT_DIR}/lib
+            ${_GSSAPI_LIBDIR}
+    )
+
+    find_library(K5CRYPTO_LIBRARY
+        NAMES
+            k5crypto
+        PATHS
+            ${GSSAPI_ROOT_DIR}/lib
+            ${_GSSAPI_LIBDIR}
+    )
+
+    find_library(COM_ERR_LIBRARY
+        NAMES
+            com_err
+        PATHS
+            ${GSSAPI_ROOT_DIR}/lib
+            ${_GSSAPI_LIBDIR}
+    )
+
+    if (GSSAPI_LIBRARY)
+        set(GSSAPI_LIBRARIES
+            ${GSSAPI_LIBRARIES}
+            ${GSSAPI_LIBRARY}
+        )
+    endif (GSSAPI_LIBRARY)
+
+    if (KRB5_LIBRARY)
+        set(GSSAPI_LIBRARIES
+            ${GSSAPI_LIBRARIES}
+            ${KRB5_LIBRARY}
+        )
+    endif (KRB5_LIBRARY)
+
+    if (K5CRYPTO_LIBRARY)
+        set(GSSAPI_LIBRARIES
+            ${GSSAPI_LIBRARIES}
+            ${K5CRYPTO_LIBRARY}
+        )
+    endif (K5CRYPTO_LIBRARY)
+
+    if (COM_ERR_LIBRARY)
+        set(GSSAPI_LIBRARIES
+            ${GSSAPI_LIBRARIES}
+            ${COM_ERR_LIBRARY}
+        )
+    endif (COM_ERR_LIBRARY)
+endif (GSSAPI_FLAVOR_MIT)
+
+if (GSSAPI_FLAVOR_HEIMDAL)
+    find_library(GSSAPI_LIBRARY
+        NAMES
+            gssapi
+        PATHS
+            ${GSSAPI_ROOT_DIR}/lib
+            ${_GSSAPI_LIBDIR}
+    )
+
+    find_library(KRB5_LIBRARY
+        NAMES
+            krb5
+        PATHS
+            ${GSSAPI_ROOT_DIR}/lib
+            ${_GSSAPI_LIBDIR}
+    )
+
+    find_library(HCRYPTO_LIBRARY
+        NAMES
+            hcrypto
+        PATHS
+            ${GSSAPI_ROOT_DIR}/lib
+            ${_GSSAPI_LIBDIR}
+    )
+
+    find_library(COM_ERR_LIBRARY
+        NAMES
+            com_err
+        PATHS
+            ${GSSAPI_ROOT_DIR}/lib
+            ${_GSSAPI_LIBDIR}
+    )
+
+    find_library(HEIMNTLM_LIBRARY
+        NAMES
+            heimntlm
+        PATHS
+            ${GSSAPI_ROOT_DIR}/lib
+            ${_GSSAPI_LIBDIR}
+    )
+
+    find_library(HX509_LIBRARY
+        NAMES
+            hx509
+        PATHS
+            ${GSSAPI_ROOT_DIR}/lib
+            ${_GSSAPI_LIBDIR}
+    )
+
+    find_library(ASN1_LIBRARY
+        NAMES
+            asn1
+        PATHS
+            ${GSSAPI_ROOT_DIR}/lib
+            ${_GSSAPI_LIBDIR}
+    )
+
+    find_library(WIND_LIBRARY
+        NAMES
+            wind
+        PATHS
+            ${GSSAPI_ROOT_DIR}/lib
+            ${_GSSAPI_LIBDIR}
+    )
+
+    find_library(ROKEN_LIBRARY
+        NAMES
+            roken
+        PATHS
+            ${GSSAPI_ROOT_DIR}/lib
+            ${_GSSAPI_LIBDIR}
+    )
+
+    if (GSSAPI_LIBRARY)
+        set(GSSAPI_LIBRARIES
+            ${GSSAPI_LIBRARIES}
+            ${GSSAPI_LIBRARY}
+        )
+    endif (GSSAPI_LIBRARY)
+
+    if (KRB5_LIBRARY)
+        set(GSSAPI_LIBRARIES
+            ${GSSAPI_LIBRARIES}
+            ${KRB5_LIBRARY}
+        )
+    endif (KRB5_LIBRARY)
+
+    if (HCRYPTO_LIBRARY)
+        set(GSSAPI_LIBRARIES
+            ${GSSAPI_LIBRARIES}
+            ${HCRYPTO_LIBRARY}
+        )
+    endif (HCRYPTO_LIBRARY)
+
+    if (COM_ERR_LIBRARY)
+        set(GSSAPI_LIBRARIES
+            ${GSSAPI_LIBRARIES}
+            ${COM_ERR_LIBRARY}
+        )
+    endif (COM_ERR_LIBRARY)
+
+    if (HEIMNTLM_LIBRARY)
+        set(GSSAPI_LIBRARIES
+            ${GSSAPI_LIBRARIES}
+            ${HEIMNTLM_LIBRARY}
+        )
+    endif (HEIMNTLM_LIBRARY)
+
+    if (HX509_LIBRARY)
+        set(GSSAPI_LIBRARIES
+            ${GSSAPI_LIBRARIES}
+            ${HX509_LIBRARY}
+        )
+    endif (HX509_LIBRARY)
+
+    if (ASN1_LIBRARY)
+        set(GSSAPI_LIBRARIES
+            ${GSSAPI_LIBRARIES}
+            ${ASN1_LIBRARY}
+        )
+    endif (ASN1_LIBRARY)
+
+    if (WIND_LIBRARY)
+        set(GSSAPI_LIBRARIES
+            ${GSSAPI_LIBRARIES}
+            ${WIND_LIBRARY}
+        )
+    endif (WIND_LIBRARY)
+
+    if (ROKEN_LIBRARY)
+        set(GSSAPI_LIBRARIES
+            ${GSSAPI_LIBRARIES}
+            ${WIND_LIBRARY}
+        )
+    endif (ROKEN_LIBRARY)
+endif (GSSAPI_FLAVOR_HEIMDAL)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(GSSAPI DEFAULT_MSG GSSAPI_LIBRARIES GSSAPI_INCLUDE_DIR)
+
+if (GSSAPI_INCLUDE_DIRS AND GSSAPI_LIBRARIES)
+    set(GSSAPI_FOUND TRUE)
+endif (GSSAPI_INCLUDE_DIRS AND GSSAPI_LIBRARIES)
+
+# show the GSSAPI_INCLUDE_DIRS and GSSAPI_LIBRARIES variables only in the advanced view
+mark_as_advanced(GSSAPI_INCLUDE_DIRS GSSAPI_LIBRARIES)
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/FindHTTP_Parser.cmake b/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/FindHTTP_Parser.cmake
new file mode 100755
index 0000000..d92bf75
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/FindHTTP_Parser.cmake
@@ -0,0 +1,39 @@
+# - Try to find http-parser
+#
+# Defines the following variables:
+#
+# HTTP_PARSER_FOUND - system has http-parser
+# HTTP_PARSER_INCLUDE_DIR - the http-parser include directory
+# HTTP_PARSER_LIBRARIES - Link these to use http-parser
+# HTTP_PARSER_VERSION_MAJOR - major version
+# HTTP_PARSER_VERSION_MINOR - minor version
+# HTTP_PARSER_VERSION_STRING - the version of http-parser found
+
+# Find the header and library
+FIND_PATH(HTTP_PARSER_INCLUDE_DIR NAMES http_parser.h)
+FIND_LIBRARY(HTTP_PARSER_LIBRARY NAMES http_parser libhttp_parser)
+
+# Found the header, read version
+if (HTTP_PARSER_INCLUDE_DIR AND EXISTS "${HTTP_PARSER_INCLUDE_DIR}/http_parser.h")
+	FILE(READ "${HTTP_PARSER_INCLUDE_DIR}/http_parser.h" HTTP_PARSER_H)
+	IF (HTTP_PARSER_H)
+		STRING(REGEX REPLACE ".*#define[\t ]+HTTP_PARSER_VERSION_MAJOR[\t ]+([0-9]+).*" "\\1" HTTP_PARSER_VERSION_MAJOR "${HTTP_PARSER_H}")
+		STRING(REGEX REPLACE ".*#define[\t ]+HTTP_PARSER_VERSION_MINOR[\t ]+([0-9]+).*" "\\1" HTTP_PARSER_VERSION_MINOR "${HTTP_PARSER_H}")
+		SET(HTTP_PARSER_VERSION_STRING "${HTTP_PARSER_VERSION_MAJOR}.${HTTP_PARSER_VERSION_MINOR}")
+	ENDIF()
+	UNSET(HTTP_PARSER_H)
+ENDIF()
+
+# Handle the QUIETLY and REQUIRED arguments and set HTTP_PARSER_FOUND
+# to TRUE if all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(HTTP_Parser REQUIRED_VARS HTTP_PARSER_INCLUDE_DIR HTTP_PARSER_LIBRARY)
+
+# Hide advanced variables
+MARK_AS_ADVANCED(HTTP_PARSER_INCLUDE_DIR HTTP_PARSER_LIBRARY)
+
+# Set standard variables
+IF (HTTP_PARSER_FOUND)
+	SET(HTTP_PARSER_LIBRARIES ${HTTP_PARSER_LIBRARY})
+	set(HTTP_PARSER_INCLUDE_DIRS ${HTTP_PARSER_INCLUDE_DIR})
+ENDIF()
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/FindIconv.cmake b/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/FindIconv.cmake
new file mode 100755
index 0000000..95414bd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/FindIconv.cmake
@@ -0,0 +1,40 @@
+# - Try to find Iconv
+# Once done this will define
+#
+# ICONV_FOUND - system has Iconv
+# ICONV_INCLUDE_DIR - the Iconv include directory
+# ICONV_LIBRARIES - Link these to use Iconv
+#
+
+IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
+	# Already in cache, be silent
+	SET(ICONV_FIND_QUIETLY TRUE)
+ENDIF()
+
+FIND_PATH(ICONV_INCLUDE_DIR iconv.h)
+FIND_LIBRARY(iconv_lib NAMES iconv libiconv libiconv-2 c)
+
+IF(ICONV_INCLUDE_DIR AND iconv_lib)
+	 SET(ICONV_FOUND TRUE)
+ENDIF()
+
+IF(ICONV_FOUND)
+	# split iconv into -L and -l linker options, so we can set them for pkg-config
+	GET_FILENAME_COMPONENT(iconv_path ${iconv_lib} PATH)
+	GET_FILENAME_COMPONENT(iconv_name ${iconv_lib} NAME_WE)
+	STRING(REGEX REPLACE "^lib" "" iconv_name ${iconv_name})
+	SET(ICONV_LIBRARIES "-L${iconv_path} -l${iconv_name}")
+
+	IF(NOT ICONV_FIND_QUIETLY)
+		MESSAGE(STATUS "Found Iconv: ${ICONV_LIBRARIES}")
+	ENDIF(NOT ICONV_FIND_QUIETLY)
+ELSE()
+	IF(Iconv_FIND_REQUIRED)
+		MESSAGE(FATAL_ERROR "Could not find Iconv")
+	ENDIF(Iconv_FIND_REQUIRED)
+ENDIF()
+
+MARK_AS_ADVANCED(
+	ICONV_INCLUDE_DIR
+	ICONV_LIBRARIES
+)
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/FindSecurity.cmake b/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/FindSecurity.cmake
new file mode 100755
index 0000000..0decdde
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/cmake/Modules/FindSecurity.cmake
@@ -0,0 +1,9 @@
+IF (SECURITY_INCLUDE_DIR AND SECURITY_DIRS)
+  SET(SECURITY_FOUND TRUE)
+ELSE ()
+  FIND_PATH(SECURITY_INCLUDE_DIR NAMES Security/Security.h)
+  FIND_LIBRARY(SECURITY_DIRS NAMES Security)
+  IF (SECURITY_INCLUDE_DIR AND SECURITY_DIRS)
+    SET(SECURITY_FOUND TRUE)
+  ENDIF ()
+ENDIF ()
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/http-parser/LICENSE-MIT b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/http-parser/LICENSE-MIT
new file mode 100755
index 0000000..58010b3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/http-parser/LICENSE-MIT
@@ -0,0 +1,23 @@
+http_parser.c is based on src/http/ngx_http_parse.c from NGINX copyright
+Igor Sysoev.
+
+Additional changes are licensed under the same terms as NGINX and
+copyright Joyent, Inc. and other Node contributors. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE. 
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/http-parser/http_parser.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/http-parser/http_parser.c
new file mode 100755
index 0000000..2035302
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/http-parser/http_parser.c
@@ -0,0 +1,2174 @@
+/* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev
+ *
+ * Additional changes are licensed under the same terms as NGINX and
+ * copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+#include "http_parser.h"
+#include <assert.h>
+#include <stddef.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#ifndef ULLONG_MAX
+# define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */
+#endif
+
+#ifndef MIN
+# define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef ARRAY_SIZE
+# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#endif
+
+#ifndef BIT_AT
+# define BIT_AT(a, i)                                                \
+  (!!((unsigned int) (a)[(unsigned int) (i) >> 3] &                  \
+   (1 << ((unsigned int) (i) & 7))))
+#endif
+
+#ifndef ELEM_AT
+# define ELEM_AT(a, i, v) ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v))
+#endif
+
+#define SET_ERRNO(e)                                                 \
+do {                                                                 \
+  parser->http_errno = (e);                                          \
+} while(0)
+
+
+/* Run the notify callback FOR, returning ER if it fails */
+#define CALLBACK_NOTIFY_(FOR, ER)                                    \
+do {                                                                 \
+  assert(HTTP_PARSER_ERRNO(parser) == HPE_OK);                       \
+                                                                     \
+  if (settings->on_##FOR) {                                          \
+    if (0 != settings->on_##FOR(parser)) {                           \
+      SET_ERRNO(HPE_CB_##FOR);                                       \
+    }                                                                \
+                                                                     \
+    /* We either errored above or got paused; get out */             \
+    if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {                       \
+      return (ER);                                                   \
+    }                                                                \
+  }                                                                  \
+} while (0)
+
+/* Run the notify callback FOR and consume the current byte */
+#define CALLBACK_NOTIFY(FOR)            CALLBACK_NOTIFY_(FOR, p - data + 1)
+
+/* Run the notify callback FOR and don't consume the current byte */
+#define CALLBACK_NOTIFY_NOADVANCE(FOR)  CALLBACK_NOTIFY_(FOR, p - data)
+
+/* Run data callback FOR with LEN bytes, returning ER if it fails */
+#define CALLBACK_DATA_(FOR, LEN, ER)                                 \
+do {                                                                 \
+  assert(HTTP_PARSER_ERRNO(parser) == HPE_OK);                       \
+                                                                     \
+  if (FOR##_mark) {                                                  \
+    if (settings->on_##FOR) {                                        \
+      if (0 != settings->on_##FOR(parser, FOR##_mark, (LEN))) {      \
+        SET_ERRNO(HPE_CB_##FOR);                                     \
+      }                                                              \
+                                                                     \
+      /* We either errored above or got paused; get out */           \
+      if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {                     \
+        return (ER);                                                 \
+      }                                                              \
+    }                                                                \
+    FOR##_mark = NULL;                                               \
+  }                                                                  \
+} while (0)
+  
+/* Run the data callback FOR and consume the current byte */
+#define CALLBACK_DATA(FOR)                                           \
+    CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1)
+
+/* Run the data callback FOR and don't consume the current byte */
+#define CALLBACK_DATA_NOADVANCE(FOR)                                 \
+    CALLBACK_DATA_(FOR, p - FOR##_mark, p - data)
+
+/* Set the mark FOR; non-destructive if mark is already set */
+#define MARK(FOR)                                                    \
+do {                                                                 \
+  if (!FOR##_mark) {                                                 \
+    FOR##_mark = p;                                                  \
+  }                                                                  \
+} while (0)
+
+
+#define PROXY_CONNECTION "proxy-connection"
+#define CONNECTION "connection"
+#define CONTENT_LENGTH "content-length"
+#define TRANSFER_ENCODING "transfer-encoding"
+#define UPGRADE "upgrade"
+#define CHUNKED "chunked"
+#define KEEP_ALIVE "keep-alive"
+#define CLOSE "close"
+
+
+static const char *method_strings[] =
+  {
+#define XX(num, name, string) #string,
+  HTTP_METHOD_MAP(XX)
+#undef XX
+  };
+
+
+/* Tokens as defined by rfc 2616. Also lowercases them.
+ *        token       = 1*<any CHAR except CTLs or separators>
+ *     separators     = "(" | ")" | "<" | ">" | "@"
+ *                    | "," | ";" | ":" | "\" | <">
+ *                    | "/" | "[" | "]" | "?" | "="
+ *                    | "{" | "}" | SP | HT
+ */
+static const char tokens[256] = {
+/*   0 nul    1 soh    2 stx    3 etx    4 eot    5 enq    6 ack    7 bel  */
+        0,       0,       0,       0,       0,       0,       0,       0,
+/*   8 bs     9 ht    10 nl    11 vt    12 np    13 cr    14 so    15 si   */
+        0,       0,       0,       0,       0,       0,       0,       0,
+/*  16 dle   17 dc1   18 dc2   19 dc3   20 dc4   21 nak   22 syn   23 etb */
+        0,       0,       0,       0,       0,       0,       0,       0,
+/*  24 can   25 em    26 sub   27 esc   28 fs    29 gs    30 rs    31 us  */
+        0,       0,       0,       0,       0,       0,       0,       0,
+/*  32 sp    33  !    34  "    35  #    36  $    37  %    38  &    39  '  */
+        0,      '!',      0,      '#',     '$',     '%',     '&',    '\'',
+/*  40  (    41  )    42  *    43  +    44  ,    45  -    46  .    47  /  */
+        0,       0,      '*',     '+',      0,      '-',     '.',      0,
+/*  48  0    49  1    50  2    51  3    52  4    53  5    54  6    55  7  */
+       '0',     '1',     '2',     '3',     '4',     '5',     '6',     '7',
+/*  56  8    57  9    58  :    59  ;    60  <    61  =    62  >    63  ?  */
+       '8',     '9',      0,       0,       0,       0,       0,       0,
+/*  64  @    65  A    66  B    67  C    68  D    69  E    70  F    71  G  */
+        0,      'a',     'b',     'c',     'd',     'e',     'f',     'g',
+/*  72  H    73  I    74  J    75  K    76  L    77  M    78  N    79  O  */
+       'h',     'i',     'j',     'k',     'l',     'm',     'n',     'o',
+/*  80  P    81  Q    82  R    83  S    84  T    85  U    86  V    87  W  */
+       'p',     'q',     'r',     's',     't',     'u',     'v',     'w',
+/*  88  X    89  Y    90  Z    91  [    92  \    93  ]    94  ^    95  _  */
+       'x',     'y',     'z',      0,       0,       0,      '^',     '_',
+/*  96  `    97  a    98  b    99  c   100  d   101  e   102  f   103  g  */
+       '`',     'a',     'b',     'c',     'd',     'e',     'f',     'g',
+/* 104  h   105  i   106  j   107  k   108  l   109  m   110  n   111  o  */
+       'h',     'i',     'j',     'k',     'l',     'm',     'n',     'o',
+/* 112  p   113  q   114  r   115  s   116  t   117  u   118  v   119  w  */
+       'p',     'q',     'r',     's',     't',     'u',     'v',     'w',
+/* 120  x   121  y   122  z   123  {   124  |   125  }   126  ~   127 del */
+       'x',     'y',     'z',      0,      '|',      0,      '~',       0 };
+
+
+static const int8_t unhex[256] =
+  {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+  ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+  ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+  , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1
+  ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
+  ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+  ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
+  ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+  };
+
+
+#if HTTP_PARSER_STRICT
+# define T(v) 0
+#else
+# define T(v) v
+#endif
+
+
+static const uint8_t normal_url_char[32] = {
+/*   0 nul    1 soh    2 stx    3 etx    4 eot    5 enq    6 ack    7 bel  */
+        0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,
+/*   8 bs     9 ht    10 nl    11 vt    12 np    13 cr    14 so    15 si   */
+        0    | T(2)   |   0    |   0    | T(16)  |   0    |   0    |   0,
+/*  16 dle   17 dc1   18 dc2   19 dc3   20 dc4   21 nak   22 syn   23 etb */
+        0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,
+/*  24 can   25 em    26 sub   27 esc   28 fs    29 gs    30 rs    31 us  */
+        0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,
+/*  32 sp    33  !    34  "    35  #    36  $    37  %    38  &    39  '  */
+        0    |   2    |   4    |   0    |   16   |   32   |   64   |  128,
+/*  40  (    41  )    42  *    43  +    44  ,    45  -    46  .    47  /  */
+        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+/*  48  0    49  1    50  2    51  3    52  4    53  5    54  6    55  7  */
+        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+/*  56  8    57  9    58  :    59  ;    60  <    61  =    62  >    63  ?  */
+        1    |   2    |   4    |   8    |   16   |   32   |   64   |   0,
+/*  64  @    65  A    66  B    67  C    68  D    69  E    70  F    71  G  */
+        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+/*  72  H    73  I    74  J    75  K    76  L    77  M    78  N    79  O  */
+        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+/*  80  P    81  Q    82  R    83  S    84  T    85  U    86  V    87  W  */
+        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+/*  88  X    89  Y    90  Z    91  [    92  \    93  ]    94  ^    95  _  */
+        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+/*  96  `    97  a    98  b    99  c   100  d   101  e   102  f   103  g  */
+        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+/* 104  h   105  i   106  j   107  k   108  l   109  m   110  n   111  o  */
+        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+/* 112  p   113  q   114  r   115  s   116  t   117  u   118  v   119  w  */
+        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+/* 120  x   121  y   122  z   123  {   124  |   125  }   126  ~   127 del */
+        1    |   2    |   4    |   8    |   16   |   32   |   64   |   0, };
+
+#undef T
+
+enum state
+  { s_dead = 1 /* important that this is > 0 */
+
+  , s_start_req_or_res
+  , s_res_or_resp_H
+  , s_start_res
+  , s_res_H
+  , s_res_HT
+  , s_res_HTT
+  , s_res_HTTP
+  , s_res_first_http_major
+  , s_res_http_major
+  , s_res_first_http_minor
+  , s_res_http_minor
+  , s_res_first_status_code
+  , s_res_status_code
+  , s_res_status
+  , s_res_line_almost_done
+
+  , s_start_req
+
+  , s_req_method
+  , s_req_spaces_before_url
+  , s_req_schema
+  , s_req_schema_slash
+  , s_req_schema_slash_slash
+  , s_req_server_start
+  , s_req_server
+  , s_req_server_with_at
+  , s_req_path
+  , s_req_query_string_start
+  , s_req_query_string
+  , s_req_fragment_start
+  , s_req_fragment
+  , s_req_http_start
+  , s_req_http_H
+  , s_req_http_HT
+  , s_req_http_HTT
+  , s_req_http_HTTP
+  , s_req_first_http_major
+  , s_req_http_major
+  , s_req_first_http_minor
+  , s_req_http_minor
+  , s_req_line_almost_done
+
+  , s_header_field_start
+  , s_header_field
+  , s_header_value_start
+  , s_header_value
+  , s_header_value_lws
+
+  , s_header_almost_done
+
+  , s_chunk_size_start
+  , s_chunk_size
+  , s_chunk_parameters
+  , s_chunk_size_almost_done
+
+  , s_headers_almost_done
+  , s_headers_done
+
+  /* Important: 's_headers_done' must be the last 'header' state. All
+   * states beyond this must be 'body' states. It is used for overflow
+   * checking. See the PARSING_HEADER() macro.
+   */
+
+  , s_chunk_data
+  , s_chunk_data_almost_done
+  , s_chunk_data_done
+
+  , s_body_identity
+  , s_body_identity_eof
+
+  , s_message_done
+  };
+
+
+#define PARSING_HEADER(state) (state <= s_headers_done)
+
+
+enum header_states
+  { h_general = 0
+  , h_C
+  , h_CO
+  , h_CON
+
+  , h_matching_connection
+  , h_matching_proxy_connection
+  , h_matching_content_length
+  , h_matching_transfer_encoding
+  , h_matching_upgrade
+
+  , h_connection
+  , h_content_length
+  , h_transfer_encoding
+  , h_upgrade
+
+  , h_matching_transfer_encoding_chunked
+  , h_matching_connection_keep_alive
+  , h_matching_connection_close
+
+  , h_transfer_encoding_chunked
+  , h_connection_keep_alive
+  , h_connection_close
+  };
+
+enum http_host_state
+  {
+    s_http_host_dead = 1
+  , s_http_userinfo_start
+  , s_http_userinfo
+  , s_http_host_start
+  , s_http_host_v6_start
+  , s_http_host
+  , s_http_host_v6
+  , s_http_host_v6_end
+  , s_http_host_port_start
+  , s_http_host_port
+};
+
+/* Macros for character classes; depends on strict-mode  */
+#define CR                  '\r'
+#define LF                  '\n'
+#define LOWER(c)            (unsigned char)(c | 0x20)
+#define IS_ALPHA(c)         (LOWER(c) >= 'a' && LOWER(c) <= 'z')
+#define IS_NUM(c)           ((c) >= '0' && (c) <= '9')
+#define IS_ALPHANUM(c)      (IS_ALPHA(c) || IS_NUM(c))
+#define IS_HEX(c)           (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f'))
+#define IS_MARK(c)          ((c) == '-' || (c) == '_' || (c) == '.' || \
+  (c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \
+  (c) == ')')
+#define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \
+  (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \
+  (c) == '$' || (c) == ',')
+
+#if HTTP_PARSER_STRICT
+#define TOKEN(c)            (tokens[(unsigned char)c])
+#define IS_URL_CHAR(c)      (BIT_AT(normal_url_char, (unsigned char)c))
+#define IS_HOST_CHAR(c)     (IS_ALPHANUM(c) || (c) == '.' || (c) == '-')
+#else
+#define TOKEN(c)            ((c == ' ') ? ' ' : tokens[(unsigned char)c])
+#define IS_URL_CHAR(c)                                                         \
+  (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80))
+#define IS_HOST_CHAR(c)                                                        \
+  (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_')
+#endif
+
+
+#define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res)
+
+
+#if HTTP_PARSER_STRICT
+# define STRICT_CHECK(cond)                                          \
+do {                                                                 \
+  if (cond) {                                                        \
+    SET_ERRNO(HPE_STRICT);                                           \
+    goto error;                                                      \
+  }                                                                  \
+} while (0)
+# define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead)
+#else
+# define STRICT_CHECK(cond)
+# define NEW_MESSAGE() start_state
+#endif
+
+
+/* Map errno values to strings for human-readable output */
+#define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s },
+static struct {
+  const char *name;
+  const char *description;
+} http_strerror_tab[] = {
+  HTTP_ERRNO_MAP(HTTP_STRERROR_GEN)
+};
+#undef HTTP_STRERROR_GEN
+
+int http_message_needs_eof(const http_parser *parser);
+
+/* Our URL parser.
+ *
+ * This is designed to be shared by http_parser_execute() for URL validation,
+ * hence it has a state transition + byte-for-byte interface. In addition, it
+ * is meant to be embedded in http_parser_parse_url(), which does the dirty
+ * work of turning state transitions URL components for its API.
+ *
+ * This function should only be invoked with non-space characters. It is
+ * assumed that the caller cares about (and can detect) the transition between
+ * URL and non-URL states by looking for these.
+ */
+static enum state
+parse_url_char(enum state s, const char ch)
+{
+  if (ch == ' ' || ch == '\r' || ch == '\n') {
+    return s_dead;
+  }
+
+#if HTTP_PARSER_STRICT
+  if (ch == '\t' || ch == '\f') {
+    return s_dead;
+  }
+#endif
+
+  switch (s) {
+    case s_req_spaces_before_url:
+      /* Proxied requests are followed by scheme of an absolute URI (alpha).
+       * All methods except CONNECT are followed by '/' or '*'.
+       */
+
+      if (ch == '/' || ch == '*') {
+        return s_req_path;
+      }
+
+      if (IS_ALPHA(ch)) {
+        return s_req_schema;
+      }
+
+      break;
+
+    case s_req_schema:
+      if (IS_ALPHA(ch)) {
+        return s;
+      }
+
+      if (ch == ':') {
+        return s_req_schema_slash;
+      }
+
+      break;
+
+    case s_req_schema_slash:
+      if (ch == '/') {
+        return s_req_schema_slash_slash;
+      }
+
+      break;
+
+    case s_req_schema_slash_slash:
+      if (ch == '/') {
+        return s_req_server_start;
+      }
+
+      break;
+
+    case s_req_server_with_at:
+      if (ch == '@') {
+        return s_dead;
+      }
+
+    /* FALLTHROUGH */
+    case s_req_server_start:
+    case s_req_server:
+      if (ch == '/') {
+        return s_req_path;
+      }
+
+      if (ch == '?') {
+        return s_req_query_string_start;
+      }
+
+      if (ch == '@') {
+        return s_req_server_with_at;
+      }
+
+      if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') {
+        return s_req_server;
+      }
+
+      break;
+
+    case s_req_path:
+      if (IS_URL_CHAR(ch)) {
+        return s;
+      }
+
+      switch (ch) {
+        case '?':
+          return s_req_query_string_start;
+
+        case '#':
+          return s_req_fragment_start;
+      }
+
+      break;
+
+    case s_req_query_string_start:
+    case s_req_query_string:
+      if (IS_URL_CHAR(ch)) {
+        return s_req_query_string;
+      }
+
+      switch (ch) {
+        case '?':
+          /* allow extra '?' in query string */
+          return s_req_query_string;
+
+        case '#':
+          return s_req_fragment_start;
+      }
+
+      break;
+
+    case s_req_fragment_start:
+      if (IS_URL_CHAR(ch)) {
+        return s_req_fragment;
+      }
+
+      switch (ch) {
+        case '?':
+          return s_req_fragment;
+
+        case '#':
+          return s;
+      }
+
+      break;
+
+    case s_req_fragment:
+      if (IS_URL_CHAR(ch)) {
+        return s;
+      }
+
+      switch (ch) {
+        case '?':
+        case '#':
+          return s;
+      }
+
+      break;
+
+    default:
+      break;
+  }
+
+  /* We should never fall out of the switch above unless there's an error */
+  return s_dead;
+}
+
+size_t http_parser_execute (http_parser *parser,
+                            const http_parser_settings *settings,
+                            const char *data,
+                            size_t len)
+{
+  char c, ch;
+  int8_t unhex_val;
+  const char *p = data;
+  const char *header_field_mark = 0;
+  const char *header_value_mark = 0;
+  const char *url_mark = 0;
+  const char *body_mark = 0;
+
+  /* We're in an error state. Don't bother doing anything. */
+  if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {
+    return 0;
+  }
+
+  if (len == 0) {
+    switch (parser->state) {
+      case s_body_identity_eof:
+        /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if
+         * we got paused.
+         */
+        CALLBACK_NOTIFY_NOADVANCE(message_complete);
+        return 0;
+
+      case s_dead:
+      case s_start_req_or_res:
+      case s_start_res:
+      case s_start_req:
+        return 0;
+
+      default:
+        SET_ERRNO(HPE_INVALID_EOF_STATE);
+        return 1;
+    }
+  }
+
+
+  if (parser->state == s_header_field)
+    header_field_mark = data;
+  if (parser->state == s_header_value)
+    header_value_mark = data;
+  switch (parser->state) {
+  case s_req_path:
+  case s_req_schema:
+  case s_req_schema_slash:
+  case s_req_schema_slash_slash:
+  case s_req_server_start:
+  case s_req_server:
+  case s_req_server_with_at:
+  case s_req_query_string_start:
+  case s_req_query_string:
+  case s_req_fragment_start:
+  case s_req_fragment:
+    url_mark = data;
+    break;
+  }
+
+  for (p=data; p != data + len; p++) {
+    ch = *p;
+
+    if (PARSING_HEADER(parser->state)) {
+      ++parser->nread;
+      /* Buffer overflow attack */
+      if (parser->nread > HTTP_MAX_HEADER_SIZE) {
+        SET_ERRNO(HPE_HEADER_OVERFLOW);
+        goto error;
+      }
+    }
+
+    reexecute_byte:
+    switch (parser->state) {
+
+      case s_dead:
+        /* this state is used after a 'Connection: close' message
+         * the parser will error out if it reads another message
+         */
+        if (ch == CR || ch == LF)
+          break;
+
+        SET_ERRNO(HPE_CLOSED_CONNECTION);
+        goto error;
+
+      case s_start_req_or_res:
+      {
+        if (ch == CR || ch == LF)
+          break;
+        parser->flags = 0;
+        parser->content_length = ULLONG_MAX;
+
+        if (ch == 'H') {
+          parser->state = s_res_or_resp_H;
+
+          CALLBACK_NOTIFY(message_begin);
+        } else {
+          parser->type = HTTP_REQUEST;
+          parser->state = s_start_req;
+          goto reexecute_byte;
+        }
+
+        break;
+      }
+
+      case s_res_or_resp_H:
+        if (ch == 'T') {
+          parser->type = HTTP_RESPONSE;
+          parser->state = s_res_HT;
+        } else {
+          if (ch != 'E') {
+            SET_ERRNO(HPE_INVALID_CONSTANT);
+            goto error;
+          }
+
+          parser->type = HTTP_REQUEST;
+          parser->method = HTTP_HEAD;
+          parser->index = 2;
+          parser->state = s_req_method;
+        }
+        break;
+
+      case s_start_res:
+      {
+        parser->flags = 0;
+        parser->content_length = ULLONG_MAX;
+
+        switch (ch) {
+          case 'H':
+            parser->state = s_res_H;
+            break;
+
+          case CR:
+          case LF:
+            break;
+
+          default:
+            SET_ERRNO(HPE_INVALID_CONSTANT);
+            goto error;
+        }
+
+        CALLBACK_NOTIFY(message_begin);
+        break;
+      }
+
+      case s_res_H:
+        STRICT_CHECK(ch != 'T');
+        parser->state = s_res_HT;
+        break;
+
+      case s_res_HT:
+        STRICT_CHECK(ch != 'T');
+        parser->state = s_res_HTT;
+        break;
+
+      case s_res_HTT:
+        STRICT_CHECK(ch != 'P');
+        parser->state = s_res_HTTP;
+        break;
+
+      case s_res_HTTP:
+        STRICT_CHECK(ch != '/');
+        parser->state = s_res_first_http_major;
+        break;
+
+      case s_res_first_http_major:
+        if (ch < '0' || ch > '9') {
+          SET_ERRNO(HPE_INVALID_VERSION);
+          goto error;
+        }
+
+        parser->http_major = ch - '0';
+        parser->state = s_res_http_major;
+        break;
+
+      /* major HTTP version or dot */
+      case s_res_http_major:
+      {
+        if (ch == '.') {
+          parser->state = s_res_first_http_minor;
+          break;
+        }
+
+        if (!IS_NUM(ch)) {
+          SET_ERRNO(HPE_INVALID_VERSION);
+          goto error;
+        }
+
+        parser->http_major *= 10;
+        parser->http_major += ch - '0';
+
+        if (parser->http_major > 999) {
+          SET_ERRNO(HPE_INVALID_VERSION);
+          goto error;
+        }
+
+        break;
+      }
+
+      /* first digit of minor HTTP version */
+      case s_res_first_http_minor:
+        if (!IS_NUM(ch)) {
+          SET_ERRNO(HPE_INVALID_VERSION);
+          goto error;
+        }
+
+        parser->http_minor = ch - '0';
+        parser->state = s_res_http_minor;
+        break;
+
+      /* minor HTTP version or end of request line */
+      case s_res_http_minor:
+      {
+        if (ch == ' ') {
+          parser->state = s_res_first_status_code;
+          break;
+        }
+
+        if (!IS_NUM(ch)) {
+          SET_ERRNO(HPE_INVALID_VERSION);
+          goto error;
+        }
+
+        parser->http_minor *= 10;
+        parser->http_minor += ch - '0';
+
+        if (parser->http_minor > 999) {
+          SET_ERRNO(HPE_INVALID_VERSION);
+          goto error;
+        }
+
+        break;
+      }
+
+      case s_res_first_status_code:
+      {
+        if (!IS_NUM(ch)) {
+          if (ch == ' ') {
+            break;
+          }
+
+          SET_ERRNO(HPE_INVALID_STATUS);
+          goto error;
+        }
+        parser->status_code = ch - '0';
+        parser->state = s_res_status_code;
+        break;
+      }
+
+      case s_res_status_code:
+      {
+        if (!IS_NUM(ch)) {
+          switch (ch) {
+            case ' ':
+              parser->state = s_res_status;
+              break;
+            case CR:
+              parser->state = s_res_line_almost_done;
+              break;
+            case LF:
+              parser->state = s_header_field_start;
+              break;
+            default:
+              SET_ERRNO(HPE_INVALID_STATUS);
+              goto error;
+          }
+          break;
+        }
+
+        parser->status_code *= 10;
+        parser->status_code += ch - '0';
+
+        if (parser->status_code > 999) {
+          SET_ERRNO(HPE_INVALID_STATUS);
+          goto error;
+        }
+
+        break;
+      }
+
+      case s_res_status:
+        /* the human readable status. e.g. "NOT FOUND"
+         * we are not humans so just ignore this */
+        if (ch == CR) {
+          parser->state = s_res_line_almost_done;
+          break;
+        }
+
+        if (ch == LF) {
+          parser->state = s_header_field_start;
+          break;
+        }
+        break;
+
+      case s_res_line_almost_done:
+        STRICT_CHECK(ch != LF);
+        parser->state = s_header_field_start;
+        break;
+
+      case s_start_req:
+      {
+        if (ch == CR || ch == LF)
+          break;
+        parser->flags = 0;
+        parser->content_length = ULLONG_MAX;
+
+        if (!IS_ALPHA(ch)) {
+          SET_ERRNO(HPE_INVALID_METHOD);
+          goto error;
+        }
+
+        parser->method = (enum http_method) 0;
+        parser->index = 1;
+        switch (ch) {
+          case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break;
+          case 'D': parser->method = HTTP_DELETE; break;
+          case 'G': parser->method = HTTP_GET; break;
+          case 'H': parser->method = HTTP_HEAD; break;
+          case 'L': parser->method = HTTP_LOCK; break;
+          case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH */ break;
+          case 'N': parser->method = HTTP_NOTIFY; break;
+          case 'O': parser->method = HTTP_OPTIONS; break;
+          case 'P': parser->method = HTTP_POST;
+            /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */
+            break;
+          case 'R': parser->method = HTTP_REPORT; break;
+          case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break;
+          case 'T': parser->method = HTTP_TRACE; break;
+          case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE */ break;
+          default:
+            SET_ERRNO(HPE_INVALID_METHOD);
+            goto error;
+        }
+        parser->state = s_req_method;
+
+        CALLBACK_NOTIFY(message_begin);
+
+        break;
+      }
+
+      case s_req_method:
+      {
+        const char *matcher;
+        if (ch == '\0') {
+          SET_ERRNO(HPE_INVALID_METHOD);
+          goto error;
+        }
+
+        matcher = method_strings[parser->method];
+        if (ch == ' ' && matcher[parser->index] == '\0') {
+          parser->state = s_req_spaces_before_url;
+        } else if (ch == matcher[parser->index]) {
+          ; /* nada */
+        } else if (parser->method == HTTP_CONNECT) {
+          if (parser->index == 1 && ch == 'H') {
+            parser->method = HTTP_CHECKOUT;
+          } else if (parser->index == 2  && ch == 'P') {
+            parser->method = HTTP_COPY;
+          } else {
+            goto error;
+          }
+        } else if (parser->method == HTTP_MKCOL) {
+          if (parser->index == 1 && ch == 'O') {
+            parser->method = HTTP_MOVE;
+          } else if (parser->index == 1 && ch == 'E') {
+            parser->method = HTTP_MERGE;
+          } else if (parser->index == 1 && ch == '-') {
+            parser->method = HTTP_MSEARCH;
+          } else if (parser->index == 2 && ch == 'A') {
+            parser->method = HTTP_MKACTIVITY;
+          } else {
+            goto error;
+          }
+        } else if (parser->method == HTTP_SUBSCRIBE) {
+          if (parser->index == 1 && ch == 'E') {
+            parser->method = HTTP_SEARCH;
+          } else {
+            goto error;
+          }
+        } else if (parser->index == 1 && parser->method == HTTP_POST) {
+          if (ch == 'R') {
+            parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */
+          } else if (ch == 'U') {
+            parser->method = HTTP_PUT; /* or HTTP_PURGE */
+          } else if (ch == 'A') {
+            parser->method = HTTP_PATCH;
+          } else {
+            goto error;
+          }
+        } else if (parser->index == 2) {
+          if (parser->method == HTTP_PUT) {
+            if (ch == 'R') parser->method = HTTP_PURGE;
+          } else if (parser->method == HTTP_UNLOCK) {
+            if (ch == 'S') parser->method = HTTP_UNSUBSCRIBE;
+          }
+        } else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') {
+          parser->method = HTTP_PROPPATCH;
+        } else {
+          SET_ERRNO(HPE_INVALID_METHOD);
+          goto error;
+        }
+
+        ++parser->index;
+        break;
+      }
+
+      case s_req_spaces_before_url:
+      {
+        if (ch == ' ') break;
+
+        MARK(url);
+        if (parser->method == HTTP_CONNECT) {
+          parser->state = s_req_server_start;
+        }
+
+        parser->state = parse_url_char((enum state)parser->state, ch);
+        if (parser->state == s_dead) {
+          SET_ERRNO(HPE_INVALID_URL);
+          goto error;
+        }
+
+        break;
+      }
+
+      case s_req_schema:
+      case s_req_schema_slash:
+      case s_req_schema_slash_slash:
+      case s_req_server_start:
+      {
+        switch (ch) {
+          /* No whitespace allowed here */
+          case ' ':
+          case CR:
+          case LF:
+            SET_ERRNO(HPE_INVALID_URL);
+            goto error;
+          default:
+            parser->state = parse_url_char((enum state)parser->state, ch);
+            if (parser->state == s_dead) {
+              SET_ERRNO(HPE_INVALID_URL);
+              goto error;
+            }
+        }
+
+        break;
+      }
+
+      case s_req_server:
+      case s_req_server_with_at:
+      case s_req_path:
+      case s_req_query_string_start:
+      case s_req_query_string:
+      case s_req_fragment_start:
+      case s_req_fragment:
+      {
+        switch (ch) {
+          case ' ':
+            parser->state = s_req_http_start;
+            CALLBACK_DATA(url);
+            break;
+          case CR:
+          case LF:
+            parser->http_major = 0;
+            parser->http_minor = 9;
+            parser->state = (ch == CR) ?
+              s_req_line_almost_done :
+              s_header_field_start;
+            CALLBACK_DATA(url);
+            break;
+          default:
+            parser->state = parse_url_char((enum state)parser->state, ch);
+            if (parser->state == s_dead) {
+              SET_ERRNO(HPE_INVALID_URL);
+              goto error;
+            }
+        }
+        break;
+      }
+
+      case s_req_http_start:
+        switch (ch) {
+          case 'H':
+            parser->state = s_req_http_H;
+            break;
+          case ' ':
+            break;
+          default:
+            SET_ERRNO(HPE_INVALID_CONSTANT);
+            goto error;
+        }
+        break;
+
+      case s_req_http_H:
+        STRICT_CHECK(ch != 'T');
+        parser->state = s_req_http_HT;
+        break;
+
+      case s_req_http_HT:
+        STRICT_CHECK(ch != 'T');
+        parser->state = s_req_http_HTT;
+        break;
+
+      case s_req_http_HTT:
+        STRICT_CHECK(ch != 'P');
+        parser->state = s_req_http_HTTP;
+        break;
+
+      case s_req_http_HTTP:
+        STRICT_CHECK(ch != '/');
+        parser->state = s_req_first_http_major;
+        break;
+
+      /* first digit of major HTTP version */
+      case s_req_first_http_major:
+        if (ch < '1' || ch > '9') {
+          SET_ERRNO(HPE_INVALID_VERSION);
+          goto error;
+        }
+
+        parser->http_major = ch - '0';
+        parser->state = s_req_http_major;
+        break;
+
+      /* major HTTP version or dot */
+      case s_req_http_major:
+      {
+        if (ch == '.') {
+          parser->state = s_req_first_http_minor;
+          break;
+        }
+
+        if (!IS_NUM(ch)) {
+          SET_ERRNO(HPE_INVALID_VERSION);
+          goto error;
+        }
+
+        parser->http_major *= 10;
+        parser->http_major += ch - '0';
+
+        if (parser->http_major > 999) {
+          SET_ERRNO(HPE_INVALID_VERSION);
+          goto error;
+        }
+
+        break;
+      }
+
+      /* first digit of minor HTTP version */
+      case s_req_first_http_minor:
+        if (!IS_NUM(ch)) {
+          SET_ERRNO(HPE_INVALID_VERSION);
+          goto error;
+        }
+
+        parser->http_minor = ch - '0';
+        parser->state = s_req_http_minor;
+        break;
+
+      /* minor HTTP version or end of request line */
+      case s_req_http_minor:
+      {
+        if (ch == CR) {
+          parser->state = s_req_line_almost_done;
+          break;
+        }
+
+        if (ch == LF) {
+          parser->state = s_header_field_start;
+          break;
+        }
+
+        /* XXX allow spaces after digit? */
+
+        if (!IS_NUM(ch)) {
+          SET_ERRNO(HPE_INVALID_VERSION);
+          goto error;
+        }
+
+        parser->http_minor *= 10;
+        parser->http_minor += ch - '0';
+
+        if (parser->http_minor > 999) {
+          SET_ERRNO(HPE_INVALID_VERSION);
+          goto error;
+        }
+
+        break;
+      }
+
+      /* end of request line */
+      case s_req_line_almost_done:
+      {
+        if (ch != LF) {
+          SET_ERRNO(HPE_LF_EXPECTED);
+          goto error;
+        }
+
+        parser->state = s_header_field_start;
+        break;
+      }
+
+      case s_header_field_start:
+      {
+        if (ch == CR) {
+          parser->state = s_headers_almost_done;
+          break;
+        }
+
+        if (ch == LF) {
+          /* they might be just sending \n instead of \r\n so this would be
+           * the second \n to denote the end of headers*/
+          parser->state = s_headers_almost_done;
+          goto reexecute_byte;
+        }
+
+        c = TOKEN(ch);
+
+        if (!c) {
+          SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
+          goto error;
+        }
+
+        MARK(header_field);
+
+        parser->index = 0;
+        parser->state = s_header_field;
+
+        switch (c) {
+          case 'c':
+            parser->header_state = h_C;
+            break;
+
+          case 'p':
+            parser->header_state = h_matching_proxy_connection;
+            break;
+
+          case 't':
+            parser->header_state = h_matching_transfer_encoding;
+            break;
+
+          case 'u':
+            parser->header_state = h_matching_upgrade;
+            break;
+
+          default:
+            parser->header_state = h_general;
+            break;
+        }
+        break;
+      }
+
+      case s_header_field:
+      {
+        c = TOKEN(ch);
+
+        if (c) {
+          switch (parser->header_state) {
+            case h_general:
+              break;
+
+            case h_C:
+              parser->index++;
+              parser->header_state = (c == 'o' ? h_CO : h_general);
+              break;
+
+            case h_CO:
+              parser->index++;
+              parser->header_state = (c == 'n' ? h_CON : h_general);
+              break;
+
+            case h_CON:
+              parser->index++;
+              switch (c) {
+                case 'n':
+                  parser->header_state = h_matching_connection;
+                  break;
+                case 't':
+                  parser->header_state = h_matching_content_length;
+                  break;
+                default:
+                  parser->header_state = h_general;
+                  break;
+              }
+              break;
+
+            /* connection */
+
+            case h_matching_connection:
+              parser->index++;
+              if (parser->index > sizeof(CONNECTION)-1
+                  || c != CONNECTION[parser->index]) {
+                parser->header_state = h_general;
+              } else if (parser->index == sizeof(CONNECTION)-2) {
+                parser->header_state = h_connection;
+              }
+              break;
+
+            /* proxy-connection */
+
+            case h_matching_proxy_connection:
+              parser->index++;
+              if (parser->index > sizeof(PROXY_CONNECTION)-1
+                  || c != PROXY_CONNECTION[parser->index]) {
+                parser->header_state = h_general;
+              } else if (parser->index == sizeof(PROXY_CONNECTION)-2) {
+                parser->header_state = h_connection;
+              }
+              break;
+
+            /* content-length */
+
+            case h_matching_content_length:
+              parser->index++;
+              if (parser->index > sizeof(CONTENT_LENGTH)-1
+                  || c != CONTENT_LENGTH[parser->index]) {
+                parser->header_state = h_general;
+              } else if (parser->index == sizeof(CONTENT_LENGTH)-2) {
+                parser->header_state = h_content_length;
+              }
+              break;
+
+            /* transfer-encoding */
+
+            case h_matching_transfer_encoding:
+              parser->index++;
+              if (parser->index > sizeof(TRANSFER_ENCODING)-1
+                  || c != TRANSFER_ENCODING[parser->index]) {
+                parser->header_state = h_general;
+              } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) {
+                parser->header_state = h_transfer_encoding;
+              }
+              break;
+
+            /* upgrade */
+
+            case h_matching_upgrade:
+              parser->index++;
+              if (parser->index > sizeof(UPGRADE)-1
+                  || c != UPGRADE[parser->index]) {
+                parser->header_state = h_general;
+              } else if (parser->index == sizeof(UPGRADE)-2) {
+                parser->header_state = h_upgrade;
+              }
+              break;
+
+            case h_connection:
+            case h_content_length:
+            case h_transfer_encoding:
+            case h_upgrade:
+              if (ch != ' ') parser->header_state = h_general;
+              break;
+
+            default:
+              assert(0 && "Unknown header_state");
+              break;
+          }
+          break;
+        }
+
+        if (ch == ':') {
+          parser->state = s_header_value_start;
+          CALLBACK_DATA(header_field);
+          break;
+        }
+
+        if (ch == CR) {
+          parser->state = s_header_almost_done;
+          CALLBACK_DATA(header_field);
+          break;
+        }
+
+        if (ch == LF) {
+          parser->state = s_header_field_start;
+          CALLBACK_DATA(header_field);
+          break;
+        }
+
+        SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
+        goto error;
+      }
+
+      case s_header_value_start:
+      {
+        if (ch == ' ' || ch == '\t') break;
+
+        MARK(header_value);
+
+        parser->state = s_header_value;
+        parser->index = 0;
+
+        if (ch == CR) {
+          parser->header_state = h_general;
+          parser->state = s_header_almost_done;
+          CALLBACK_DATA(header_value);
+          break;
+        }
+
+        if (ch == LF) {
+          parser->state = s_header_field_start;
+          CALLBACK_DATA(header_value);
+          break;
+        }
+
+        c = LOWER(ch);
+
+        switch (parser->header_state) {
+          case h_upgrade:
+            parser->flags |= F_UPGRADE;
+            parser->header_state = h_general;
+            break;
+
+          case h_transfer_encoding:
+            /* looking for 'Transfer-Encoding: chunked' */
+            if ('c' == c) {
+              parser->header_state = h_matching_transfer_encoding_chunked;
+            } else {
+              parser->header_state = h_general;
+            }
+            break;
+
+          case h_content_length:
+            if (!IS_NUM(ch)) {
+              SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+              goto error;
+            }
+
+            parser->content_length = ch - '0';
+            break;
+
+          case h_connection:
+            /* looking for 'Connection: keep-alive' */
+            if (c == 'k') {
+              parser->header_state = h_matching_connection_keep_alive;
+            /* looking for 'Connection: close' */
+            } else if (c == 'c') {
+              parser->header_state = h_matching_connection_close;
+            } else {
+              parser->header_state = h_general;
+            }
+            break;
+
+          default:
+            parser->header_state = h_general;
+            break;
+        }
+        break;
+      }
+
+      case s_header_value:
+      {
+
+        if (ch == CR) {
+          parser->state = s_header_almost_done;
+          CALLBACK_DATA(header_value);
+          break;
+        }
+
+        if (ch == LF) {
+          parser->state = s_header_almost_done;
+          CALLBACK_DATA_NOADVANCE(header_value);
+          goto reexecute_byte;
+        }
+
+        c = LOWER(ch);
+
+        switch (parser->header_state) {
+          case h_general:
+            break;
+
+          case h_connection:
+          case h_transfer_encoding:
+            assert(0 && "Shouldn't get here.");
+            break;
+
+          case h_content_length:
+          {
+            uint64_t t;
+
+            if (ch == ' ') break;
+
+            if (!IS_NUM(ch)) {
+              SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+              goto error;
+            }
+
+            t = parser->content_length;
+            t *= 10;
+            t += ch - '0';
+
+            /* Overflow? */
+            if (t < parser->content_length || t == ULLONG_MAX) {
+              SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+              goto error;
+            }
+
+            parser->content_length = t;
+            break;
+          }
+
+          /* Transfer-Encoding: chunked */
+          case h_matching_transfer_encoding_chunked:
+            parser->index++;
+            if (parser->index > sizeof(CHUNKED)-1
+                || c != CHUNKED[parser->index]) {
+              parser->header_state = h_general;
+            } else if (parser->index == sizeof(CHUNKED)-2) {
+              parser->header_state = h_transfer_encoding_chunked;
+            }
+            break;
+
+          /* looking for 'Connection: keep-alive' */
+          case h_matching_connection_keep_alive:
+            parser->index++;
+            if (parser->index > sizeof(KEEP_ALIVE)-1
+                || c != KEEP_ALIVE[parser->index]) {
+              parser->header_state = h_general;
+            } else if (parser->index == sizeof(KEEP_ALIVE)-2) {
+              parser->header_state = h_connection_keep_alive;
+            }
+            break;
+
+          /* looking for 'Connection: close' */
+          case h_matching_connection_close:
+            parser->index++;
+            if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) {
+              parser->header_state = h_general;
+            } else if (parser->index == sizeof(CLOSE)-2) {
+              parser->header_state = h_connection_close;
+            }
+            break;
+
+          case h_transfer_encoding_chunked:
+          case h_connection_keep_alive:
+          case h_connection_close:
+            if (ch != ' ') parser->header_state = h_general;
+            break;
+
+          default:
+            parser->state = s_header_value;
+            parser->header_state = h_general;
+            break;
+        }
+        break;
+      }
+
+      case s_header_almost_done:
+      {
+        STRICT_CHECK(ch != LF);
+
+        parser->state = s_header_value_lws;
+
+        switch (parser->header_state) {
+          case h_connection_keep_alive:
+            parser->flags |= F_CONNECTION_KEEP_ALIVE;
+            break;
+          case h_connection_close:
+            parser->flags |= F_CONNECTION_CLOSE;
+            break;
+          case h_transfer_encoding_chunked:
+            parser->flags |= F_CHUNKED;
+            break;
+          default:
+            break;
+        }
+
+        break;
+      }
+
+      case s_header_value_lws:
+      {
+        if (ch == ' ' || ch == '\t')
+          parser->state = s_header_value_start;
+        else
+        {
+          parser->state = s_header_field_start;
+          goto reexecute_byte;
+        }
+        break;
+      }
+
+      case s_headers_almost_done:
+      {
+        STRICT_CHECK(ch != LF);
+
+        if (parser->flags & F_TRAILING) {
+          /* End of a chunked request */
+          parser->state = NEW_MESSAGE();
+          CALLBACK_NOTIFY(message_complete);
+          break;
+        }
+
+        parser->state = s_headers_done;
+
+        /* Set this here so that on_headers_complete() callbacks can see it */
+        parser->upgrade =
+          (parser->flags & F_UPGRADE || parser->method == HTTP_CONNECT);
+
+        /* Here we call the headers_complete callback. This is somewhat
+         * different than other callbacks because if the user returns 1, we
+         * will interpret that as saying that this message has no body. This
+         * is needed for the annoying case of recieving a response to a HEAD
+         * request.
+         *
+         * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so
+         * we have to simulate it by handling a change in errno below.
+         */
+        if (settings->on_headers_complete) {
+          switch (settings->on_headers_complete(parser)) {
+            case 0:
+              break;
+
+            case 1:
+              parser->flags |= F_SKIPBODY;
+              break;
+
+            default:
+              SET_ERRNO(HPE_CB_headers_complete);
+              return p - data; /* Error */
+          }
+        }
+
+        if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {
+          return p - data;
+        }
+
+        goto reexecute_byte;
+      }
+
+      case s_headers_done:
+      {
+        STRICT_CHECK(ch != LF);
+
+        parser->nread = 0;
+
+        /* Exit, the rest of the connect is in a different protocol. */
+        if (parser->upgrade) {
+          parser->state = NEW_MESSAGE();
+          CALLBACK_NOTIFY(message_complete);
+          return (p - data) + 1;
+        }
+
+        if (parser->flags & F_SKIPBODY) {
+          parser->state = NEW_MESSAGE();
+          CALLBACK_NOTIFY(message_complete);
+        } else if (parser->flags & F_CHUNKED) {
+          /* chunked encoding - ignore Content-Length header */
+          parser->state = s_chunk_size_start;
+        } else {
+          if (parser->content_length == 0) {
+            /* Content-Length header given but zero: Content-Length: 0\r\n */
+            parser->state = NEW_MESSAGE();
+            CALLBACK_NOTIFY(message_complete);
+          } else if (parser->content_length != ULLONG_MAX) {
+            /* Content-Length header given and non-zero */
+            parser->state = s_body_identity;
+          } else {
+            if (parser->type == HTTP_REQUEST ||
+                !http_message_needs_eof(parser)) {
+              /* Assume content-length 0 - read the next */
+              parser->state = NEW_MESSAGE();
+              CALLBACK_NOTIFY(message_complete);
+            } else {
+              /* Read body until EOF */
+              parser->state = s_body_identity_eof;
+            }
+          }
+        }
+
+        break;
+      }
+
+      case s_body_identity:
+      {
+        uint64_t to_read = MIN(parser->content_length,
+                               (uint64_t) ((data + len) - p));
+
+        assert(parser->content_length != 0
+            && parser->content_length != ULLONG_MAX);
+
+        /* The difference between advancing content_length and p is because
+         * the latter will automaticaly advance on the next loop iteration.
+         * Further, if content_length ends up at 0, we want to see the last
+         * byte again for our message complete callback.
+         */
+        MARK(body);
+        parser->content_length -= to_read;
+        p += to_read - 1;
+
+        if (parser->content_length == 0) {
+          parser->state = s_message_done;
+
+          /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte.
+           *
+           * The alternative to doing this is to wait for the next byte to
+           * trigger the data callback, just as in every other case. The
+           * problem with this is that this makes it difficult for the test
+           * harness to distinguish between complete-on-EOF and
+           * complete-on-length. It's not clear that this distinction is
+           * important for applications, but let's keep it for now.
+           */
+          CALLBACK_DATA_(body, p - body_mark + 1, p - data);
+          goto reexecute_byte;
+        }
+
+        break;
+      }
+
+      /* read until EOF */
+      case s_body_identity_eof:
+        MARK(body);
+        p = data + len - 1;
+
+        break;
+
+      case s_message_done:
+        parser->state = NEW_MESSAGE();
+        CALLBACK_NOTIFY(message_complete);
+        break;
+
+      case s_chunk_size_start:
+      {
+        assert(parser->nread == 1);
+        assert(parser->flags & F_CHUNKED);
+
+        unhex_val = unhex[(unsigned char)ch];
+        if (unhex_val == -1) {
+          SET_ERRNO(HPE_INVALID_CHUNK_SIZE);
+          goto error;
+        }
+
+        parser->content_length = unhex_val;
+        parser->state = s_chunk_size;
+        break;
+      }
+
+      case s_chunk_size:
+      {
+        uint64_t t;
+
+        assert(parser->flags & F_CHUNKED);
+
+        if (ch == CR) {
+          parser->state = s_chunk_size_almost_done;
+          break;
+        }
+
+        unhex_val = unhex[(unsigned char)ch];
+
+        if (unhex_val == -1) {
+          if (ch == ';' || ch == ' ') {
+            parser->state = s_chunk_parameters;
+            break;
+          }
+
+          SET_ERRNO(HPE_INVALID_CHUNK_SIZE);
+          goto error;
+        }
+
+        t = parser->content_length;
+        t *= 16;
+        t += unhex_val;
+
+        /* Overflow? */
+        if (t < parser->content_length || t == ULLONG_MAX) {
+          SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+          goto error;
+        }
+
+        parser->content_length = t;
+        break;
+      }
+
+      case s_chunk_parameters:
+      {
+        assert(parser->flags & F_CHUNKED);
+        /* just ignore this. TODO check for overflow */
+        if (ch == CR) {
+          parser->state = s_chunk_size_almost_done;
+          break;
+        }
+        break;
+      }
+
+      case s_chunk_size_almost_done:
+      {
+        assert(parser->flags & F_CHUNKED);
+        STRICT_CHECK(ch != LF);
+
+        parser->nread = 0;
+
+        if (parser->content_length == 0) {
+          parser->flags |= F_TRAILING;
+          parser->state = s_header_field_start;
+        } else {
+          parser->state = s_chunk_data;
+        }
+        break;
+      }
+
+      case s_chunk_data:
+      {
+        uint64_t to_read = MIN(parser->content_length,
+                               (uint64_t) ((data + len) - p));
+
+        assert(parser->flags & F_CHUNKED);
+        assert(parser->content_length != 0
+            && parser->content_length != ULLONG_MAX);
+
+        /* See the explanation in s_body_identity for why the content
+         * length and data pointers are managed this way.
+         */
+        MARK(body);
+        parser->content_length -= to_read;
+        p += to_read - 1;
+
+        if (parser->content_length == 0) {
+          parser->state = s_chunk_data_almost_done;
+        }
+
+        break;
+      }
+
+      case s_chunk_data_almost_done:
+        assert(parser->flags & F_CHUNKED);
+        assert(parser->content_length == 0);
+        STRICT_CHECK(ch != CR);
+        parser->state = s_chunk_data_done;
+        CALLBACK_DATA(body);
+        break;
+
+      case s_chunk_data_done:
+        assert(parser->flags & F_CHUNKED);
+        STRICT_CHECK(ch != LF);
+        parser->nread = 0;
+        parser->state = s_chunk_size_start;
+        break;
+
+      default:
+        assert(0 && "unhandled state");
+        SET_ERRNO(HPE_INVALID_INTERNAL_STATE);
+        goto error;
+    }
+  }
+
+  /* Run callbacks for any marks that we have leftover after we ran our of
+   * bytes. There should be at most one of these set, so it's OK to invoke
+   * them in series (unset marks will not result in callbacks).
+   *
+   * We use the NOADVANCE() variety of callbacks here because 'p' has already
+   * overflowed 'data' and this allows us to correct for the off-by-one that
+   * we'd otherwise have (since CALLBACK_DATA() is meant to be run with a 'p'
+   * value that's in-bounds).
+   */
+
+  assert(((header_field_mark ? 1 : 0) +
+          (header_value_mark ? 1 : 0) +
+          (url_mark ? 1 : 0)  +
+          (body_mark ? 1 : 0)) <= 1);
+
+  CALLBACK_DATA_NOADVANCE(header_field);
+  CALLBACK_DATA_NOADVANCE(header_value);
+  CALLBACK_DATA_NOADVANCE(url);
+  CALLBACK_DATA_NOADVANCE(body);
+
+  return len;
+
+error:
+  if (HTTP_PARSER_ERRNO(parser) == HPE_OK) {
+    SET_ERRNO(HPE_UNKNOWN);
+  }
+
+  return (p - data);
+}
+
+
+/* Does the parser need to see an EOF to find the end of the message? */
+int
+http_message_needs_eof (const http_parser *parser)
+{
+  if (parser->type == HTTP_REQUEST) {
+    return 0;
+  }
+
+  /* See RFC 2616 section 4.4 */
+  if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */
+      parser->status_code == 204 ||     /* No Content */
+      parser->status_code == 304 ||     /* Not Modified */
+      parser->flags & F_SKIPBODY) {     /* response to a HEAD request */
+    return 0;
+  }
+
+  if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) {
+    return 0;
+  }
+
+  return 1;
+}
+
+
+int
+http_should_keep_alive (const http_parser *parser)
+{
+  if (parser->http_major > 0 && parser->http_minor > 0) {
+    /* HTTP/1.1 */
+    if (parser->flags & F_CONNECTION_CLOSE) {
+      return 0;
+    }
+  } else {
+    /* HTTP/1.0 or earlier */
+    if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) {
+      return 0;
+    }
+  }
+
+  return !http_message_needs_eof(parser);
+}
+
+
+const char *
+http_method_str (enum http_method m)
+{
+  return ELEM_AT(method_strings, m, "<unknown>");
+}
+
+
+void
+http_parser_init (http_parser *parser, enum http_parser_type t)
+{
+  void *data = parser->data; /* preserve application data */
+  memset(parser, 0, sizeof(*parser));
+  parser->data = data;
+  parser->type = t;
+  parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res));
+  parser->http_errno = HPE_OK;
+}
+
+const char *
+http_errno_name(enum http_errno err) {
+  assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0])));
+  return http_strerror_tab[err].name;
+}
+
+const char *
+http_errno_description(enum http_errno err) {
+  assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0])));
+  return http_strerror_tab[err].description;
+}
+
+static enum http_host_state
+http_parse_host_char(enum http_host_state s, const char ch) {
+  switch(s) {
+    case s_http_userinfo:
+    case s_http_userinfo_start:
+      if (ch == '@') {
+        return s_http_host_start;
+      }
+
+      if (IS_USERINFO_CHAR(ch)) {
+        return s_http_userinfo;
+      }
+      break;
+
+    case s_http_host_start:
+      if (ch == '[') {
+        return s_http_host_v6_start;
+      }
+
+      if (IS_HOST_CHAR(ch)) {
+        return s_http_host;
+      }
+
+      break;
+
+    case s_http_host:
+      if (IS_HOST_CHAR(ch)) {
+        return s_http_host;
+      }
+
+    /* FALLTHROUGH */
+    case s_http_host_v6_end:
+      if (ch == ':') {
+        return s_http_host_port_start;
+      }
+
+      break;
+
+    case s_http_host_v6:
+      if (ch == ']') {
+        return s_http_host_v6_end;
+      }
+
+    /* FALLTHROUGH */
+    case s_http_host_v6_start:
+      if (IS_HEX(ch) || ch == ':') {
+        return s_http_host_v6;
+      }
+
+      break;
+
+    case s_http_host_port:
+    case s_http_host_port_start:
+      if (IS_NUM(ch)) {
+        return s_http_host_port;
+      }
+
+      break;
+
+    default:
+      break;
+  }
+  return s_http_host_dead;
+}
+
+static int
+http_parse_host(const char * buf, struct http_parser_url *u, int found_at) {
+  enum http_host_state s;
+
+  const char *p;
+  size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len;
+
+  u->field_data[UF_HOST].len = 0;
+
+  s = found_at ? s_http_userinfo_start : s_http_host_start;
+
+  for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) {
+    enum http_host_state new_s = http_parse_host_char(s, *p);
+
+    if (new_s == s_http_host_dead) {
+      return 1;
+    }
+
+    switch(new_s) {
+      case s_http_host:
+        if (s != s_http_host) {
+          u->field_data[UF_HOST].off = p - buf;
+        }
+        u->field_data[UF_HOST].len++;
+        break;
+
+      case s_http_host_v6:
+        if (s != s_http_host_v6) {
+          u->field_data[UF_HOST].off = p - buf;
+        }
+        u->field_data[UF_HOST].len++;
+        break;
+
+      case s_http_host_port:
+        if (s != s_http_host_port) {
+          u->field_data[UF_PORT].off = p - buf;
+          u->field_data[UF_PORT].len = 0;
+          u->field_set |= (1 << UF_PORT);
+        }
+        u->field_data[UF_PORT].len++;
+        break;
+
+      case s_http_userinfo:
+        if (s != s_http_userinfo) {
+          u->field_data[UF_USERINFO].off = p - buf ;
+          u->field_data[UF_USERINFO].len = 0;
+          u->field_set |= (1 << UF_USERINFO);
+        }
+        u->field_data[UF_USERINFO].len++;
+        break;
+
+      default:
+        break;
+    }
+    s = new_s;
+  }
+
+  /* Make sure we don't end somewhere unexpected */
+  switch (s) {
+    case s_http_host_start:
+    case s_http_host_v6_start:
+    case s_http_host_v6:
+    case s_http_host_port_start:
+    case s_http_userinfo:
+    case s_http_userinfo_start:
+      return 1;
+    default:
+      break;
+  }
+
+  return 0;
+}
+
+int
+http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
+                      struct http_parser_url *u)
+{
+  enum state s;
+  const char *p;
+  enum http_parser_url_fields uf, old_uf;
+  int found_at = 0;
+
+  u->port = u->field_set = 0;
+  s = is_connect ? s_req_server_start : s_req_spaces_before_url;
+  uf = old_uf = UF_MAX;
+
+  for (p = buf; p < buf + buflen; p++) {
+    s = parse_url_char(s, *p);
+
+    /* Figure out the next field that we're operating on */
+    switch (s) {
+      case s_dead:
+        return 1;
+
+      /* Skip delimeters */
+      case s_req_schema_slash:
+      case s_req_schema_slash_slash:
+      case s_req_server_start:
+      case s_req_query_string_start:
+      case s_req_fragment_start:
+        continue;
+
+      case s_req_schema:
+        uf = UF_SCHEMA;
+        break;
+
+      case s_req_server_with_at:
+        found_at = 1;
+
+      /* FALLTROUGH */
+      case s_req_server:
+        uf = UF_HOST;
+        break;
+
+      case s_req_path:
+        uf = UF_PATH;
+        break;
+
+      case s_req_query_string:
+        uf = UF_QUERY;
+        break;
+
+      case s_req_fragment:
+        uf = UF_FRAGMENT;
+        break;
+
+      default:
+        assert(!"Unexpected state");
+        return 1;
+    }
+
+    /* Nothing's changed; soldier on */
+    if (uf == old_uf) {
+      u->field_data[uf].len++;
+      continue;
+    }
+
+    u->field_data[uf].off = p - buf;
+    u->field_data[uf].len = 1;
+
+    u->field_set |= (1 << uf);
+    old_uf = uf;
+  }
+
+  /* host must be present if there is a schema */
+  /* parsing http:///toto will fail */
+  if ((u->field_set & ((1 << UF_SCHEMA) | (1 << UF_HOST))) != 0) {
+    if (http_parse_host(buf, u, found_at) != 0) {
+      return 1;
+    }
+  }
+
+  /* CONNECT requests can only contain "hostname:port" */
+  if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) {
+    return 1;
+  }
+
+  if (u->field_set & (1 << UF_PORT)) {
+    /* Don't bother with endp; we've already validated the string */
+    unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10);
+
+    /* Ports have a max value of 2^16 */
+    if (v > 0xffff) {
+      return 1;
+    }
+
+    u->port = (uint16_t) v;
+  }
+
+  return 0;
+}
+
+void
+http_parser_pause(http_parser *parser, int paused) {
+  /* Users should only be pausing/unpausing a parser that is not in an error
+   * state. In non-debug builds, there's not much that we can do about this
+   * other than ignore it.
+   */
+  if (HTTP_PARSER_ERRNO(parser) == HPE_OK ||
+      HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) {
+    SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK);
+  } else {
+    assert(0 && "Attempting to pause parser in error state");
+  }
+}
+
+int
+http_body_is_final(const struct http_parser *parser) {
+    return parser->state == s_message_done;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/http-parser/http_parser.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/http-parser/http_parser.h
new file mode 100755
index 0000000..67e1d95
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/http-parser/http_parser.h
@@ -0,0 +1,305 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+#ifndef http_parser_h
+#define http_parser_h
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HTTP_PARSER_VERSION_MAJOR 2
+#define HTTP_PARSER_VERSION_MINOR 0
+
+#include <sys/types.h>
+#if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600)
+#include <BaseTsd.h>
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+typedef SIZE_T size_t;
+typedef SSIZE_T ssize_t;
+#elif defined(__sun) || defined(__sun__)
+#include <sys/inttypes.h>
+#else
+#include <stdint.h>
+#endif
+
+/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
+ * faster
+ */
+#ifndef HTTP_PARSER_STRICT
+# define HTTP_PARSER_STRICT 1
+#endif
+
+/* Maximium header size allowed */
+#define HTTP_MAX_HEADER_SIZE (80*1024)
+
+
+typedef struct http_parser http_parser;
+typedef struct http_parser_settings http_parser_settings;
+
+
+/* Callbacks should return non-zero to indicate an error. The parser will
+ * then halt execution.
+ *
+ * The one exception is on_headers_complete. In a HTTP_RESPONSE parser
+ * returning '1' from on_headers_complete will tell the parser that it
+ * should not expect a body. This is used when receiving a response to a
+ * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
+ * chunked' headers that indicate the presence of a body.
+ *
+ * http_data_cb does not return data chunks. It will be call arbitrarally
+ * many times for each string. E.G. you might get 10 callbacks for "on_url"
+ * each providing just a few characters more data.
+ */
+typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
+typedef int (*http_cb) (http_parser*);
+
+
+/* Request Methods */
+#define HTTP_METHOD_MAP(XX)         \
+  XX(0,  DELETE,      DELETE)       \
+  XX(1,  GET,         GET)          \
+  XX(2,  HEAD,        HEAD)         \
+  XX(3,  POST,        POST)         \
+  XX(4,  PUT,         PUT)          \
+  /* pathological */                \
+  XX(5,  CONNECT,     CONNECT)      \
+  XX(6,  OPTIONS,     OPTIONS)      \
+  XX(7,  TRACE,       TRACE)        \
+  /* webdav */                      \
+  XX(8,  COPY,        COPY)         \
+  XX(9,  LOCK,        LOCK)         \
+  XX(10, MKCOL,       MKCOL)        \
+  XX(11, MOVE,        MOVE)         \
+  XX(12, PROPFIND,    PROPFIND)     \
+  XX(13, PROPPATCH,   PROPPATCH)    \
+  XX(14, SEARCH,      SEARCH)       \
+  XX(15, UNLOCK,      UNLOCK)       \
+  /* subversion */                  \
+  XX(16, REPORT,      REPORT)       \
+  XX(17, MKACTIVITY,  MKACTIVITY)   \
+  XX(18, CHECKOUT,    CHECKOUT)     \
+  XX(19, MERGE,       MERGE)        \
+  /* upnp */                        \
+  XX(20, MSEARCH,     M-SEARCH)     \
+  XX(21, NOTIFY,      NOTIFY)       \
+  XX(22, SUBSCRIBE,   SUBSCRIBE)    \
+  XX(23, UNSUBSCRIBE, UNSUBSCRIBE)  \
+  /* RFC-5789 */                    \
+  XX(24, PATCH,       PATCH)        \
+  XX(25, PURGE,       PURGE)        \
+
+enum http_method
+  {
+#define XX(num, name, string) HTTP_##name = num,
+  HTTP_METHOD_MAP(XX)
+#undef XX
+  };
+
+
+enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
+
+
+/* Flag values for http_parser.flags field */
+enum flags
+  { F_CHUNKED               = 1 << 0
+  , F_CONNECTION_KEEP_ALIVE = 1 << 1
+  , F_CONNECTION_CLOSE      = 1 << 2
+  , F_TRAILING              = 1 << 3
+  , F_UPGRADE               = 1 << 4
+  , F_SKIPBODY              = 1 << 5
+  };
+
+
+/* Map for errno-related constants
+ * 
+ * The provided argument should be a macro that takes 2 arguments.
+ */
+#define HTTP_ERRNO_MAP(XX)                                           \
+  /* No error */                                                     \
+  XX(OK, "success")                                                  \
+                                                                     \
+  /* Callback-related errors */                                      \
+  XX(CB_message_begin, "the on_message_begin callback failed")       \
+  XX(CB_url, "the on_url callback failed")                           \
+  XX(CB_header_field, "the on_header_field callback failed")         \
+  XX(CB_header_value, "the on_header_value callback failed")         \
+  XX(CB_headers_complete, "the on_headers_complete callback failed") \
+  XX(CB_body, "the on_body callback failed")                         \
+  XX(CB_message_complete, "the on_message_complete callback failed") \
+                                                                     \
+  /* Parsing-related errors */                                       \
+  XX(INVALID_EOF_STATE, "stream ended at an unexpected time")        \
+  XX(HEADER_OVERFLOW,                                                \
+     "too many header bytes seen; overflow detected")                \
+  XX(CLOSED_CONNECTION,                                              \
+     "data received after completed connection: close message")      \
+  XX(INVALID_VERSION, "invalid HTTP version")                        \
+  XX(INVALID_STATUS, "invalid HTTP status code")                     \
+  XX(INVALID_METHOD, "invalid HTTP method")                          \
+  XX(INVALID_URL, "invalid URL")                                     \
+  XX(INVALID_HOST, "invalid host")                                   \
+  XX(INVALID_PORT, "invalid port")                                   \
+  XX(INVALID_PATH, "invalid path")                                   \
+  XX(INVALID_QUERY_STRING, "invalid query string")                   \
+  XX(INVALID_FRAGMENT, "invalid fragment")                           \
+  XX(LF_EXPECTED, "LF character expected")                           \
+  XX(INVALID_HEADER_TOKEN, "invalid character in header")            \
+  XX(INVALID_CONTENT_LENGTH,                                         \
+     "invalid character in content-length header")                   \
+  XX(INVALID_CHUNK_SIZE,                                             \
+     "invalid character in chunk size header")                       \
+  XX(INVALID_CONSTANT, "invalid constant string")                    \
+  XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
+  XX(STRICT, "strict mode assertion failed")                         \
+  XX(PAUSED, "parser is paused")                                     \
+  XX(UNKNOWN, "an unknown error occurred")
+
+
+/* Define HPE_* values for each errno value above */
+#define HTTP_ERRNO_GEN(n, s) HPE_##n,
+enum http_errno {
+  HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
+};
+#undef HTTP_ERRNO_GEN
+
+
+/* Get an http_errno value from an http_parser */
+#define HTTP_PARSER_ERRNO(p)            ((enum http_errno) (p)->http_errno)
+
+
+struct http_parser {
+  /** PRIVATE **/
+  unsigned char type : 2;     /* enum http_parser_type */
+  unsigned char flags : 6;    /* F_* values from 'flags' enum; semi-public */
+  unsigned char state;        /* enum state from http_parser.c */
+  unsigned char header_state; /* enum header_state from http_parser.c */
+  unsigned char index;        /* index into current matcher */
+
+  uint32_t nread;          /* # bytes read in various scenarios */
+  uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
+
+  /** READ-ONLY **/
+  unsigned short http_major;
+  unsigned short http_minor;
+  unsigned short status_code; /* responses only */
+  unsigned char method;       /* requests only */
+  unsigned char http_errno : 7;
+
+  /* 1 = Upgrade header was present and the parser has exited because of that.
+   * 0 = No upgrade header present.
+   * Should be checked when http_parser_execute() returns in addition to
+   * error checking.
+   */
+  unsigned char upgrade : 1;
+
+  /** PUBLIC **/
+  void *data; /* A pointer to get hook to the "connection" or "socket" object */
+};
+
+
+struct http_parser_settings {
+  http_cb      on_message_begin;
+  http_data_cb on_url;
+  http_data_cb on_header_field;
+  http_data_cb on_header_value;
+  http_cb      on_headers_complete;
+  http_data_cb on_body;
+  http_cb      on_message_complete;
+};
+
+
+enum http_parser_url_fields
+  { UF_SCHEMA           = 0
+  , UF_HOST             = 1
+  , UF_PORT             = 2
+  , UF_PATH             = 3
+  , UF_QUERY            = 4
+  , UF_FRAGMENT         = 5
+  , UF_USERINFO         = 6
+  , UF_MAX              = 7
+  };
+
+
+/* Result structure for http_parser_parse_url().
+ *
+ * Callers should index into field_data[] with UF_* values iff field_set
+ * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
+ * because we probably have padding left over), we convert any port to
+ * a uint16_t.
+ */
+struct http_parser_url {
+  uint16_t field_set;           /* Bitmask of (1 << UF_*) values */
+  uint16_t port;                /* Converted UF_PORT string */
+
+  struct {
+    uint16_t off;               /* Offset into buffer in which field starts */
+    uint16_t len;               /* Length of run in buffer */
+  } field_data[UF_MAX];
+};
+
+
+void http_parser_init(http_parser *parser, enum http_parser_type type);
+
+
+size_t http_parser_execute(http_parser *parser,
+                           const http_parser_settings *settings,
+                           const char *data,
+                           size_t len);
+
+
+/* If http_should_keep_alive() in the on_headers_complete or
+ * on_message_complete callback returns 0, then this should be
+ * the last message on the connection.
+ * If you are the server, respond with the "Connection: close" header.
+ * If you are the client, close the connection.
+ */
+int http_should_keep_alive(const http_parser *parser);
+
+/* Returns a string version of the HTTP method. */
+const char *http_method_str(enum http_method m);
+
+/* Return a string name of the given error */
+const char *http_errno_name(enum http_errno err);
+
+/* Return a string description of the given error */
+const char *http_errno_description(enum http_errno err);
+
+/* Parse a URL; return nonzero on failure */
+int http_parser_parse_url(const char *buf, size_t buflen,
+                          int is_connect,
+                          struct http_parser_url *u);
+
+/* Pause or un-pause the parser; a nonzero value pauses */
+void http_parser_pause(http_parser *parser, int paused);
+
+/* Checks if this is the final chunk of the body. */
+int http_body_is_final(const http_parser *parser);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/config.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/config.h
new file mode 100755
index 0000000..9537069
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/config.h
@@ -0,0 +1,7 @@
+#ifndef _REGEX_CONFIG_H_
+#define _REGEX_CONFIG_H_
+
+# define GAWK
+# define NO_MBSUPPORT
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regcomp.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regcomp.c
new file mode 100755
index 0000000..43bffbc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regcomp.c
@@ -0,0 +1,3857 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002-2007,2009,2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu at yamato.ibm.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301 USA.  */
+
+static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
+					  size_t length, reg_syntax_t syntax);
+static void re_compile_fastmap_iter (regex_t *bufp,
+				     const re_dfastate_t *init_state,
+				     char *fastmap);
+static reg_errcode_t init_dfa (re_dfa_t *dfa, size_t pat_len);
+#ifdef RE_ENABLE_I18N
+static void free_charset (re_charset_t *cset);
+#endif /* RE_ENABLE_I18N */
+static void free_workarea_compile (regex_t *preg);
+static reg_errcode_t create_initial_state (re_dfa_t *dfa);
+#ifdef RE_ENABLE_I18N
+static void optimize_utf8 (re_dfa_t *dfa);
+#endif
+static reg_errcode_t analyze (regex_t *preg);
+static reg_errcode_t preorder (bin_tree_t *root,
+			       reg_errcode_t (fn (void *, bin_tree_t *)),
+			       void *extra);
+static reg_errcode_t postorder (bin_tree_t *root,
+				reg_errcode_t (fn (void *, bin_tree_t *)),
+				void *extra);
+static reg_errcode_t optimize_subexps (void *extra, bin_tree_t *node);
+static reg_errcode_t lower_subexps (void *extra, bin_tree_t *node);
+static bin_tree_t *lower_subexp (reg_errcode_t *err, regex_t *preg,
+				 bin_tree_t *node);
+static reg_errcode_t calc_first (void *extra, bin_tree_t *node);
+static reg_errcode_t calc_next (void *extra, bin_tree_t *node);
+static reg_errcode_t link_nfa_nodes (void *extra, bin_tree_t *node);
+static int duplicate_node (re_dfa_t *dfa, int org_idx, unsigned int constraint);
+static int search_duplicated_node (const re_dfa_t *dfa, int org_node,
+				   unsigned int constraint);
+static reg_errcode_t calc_eclosure (re_dfa_t *dfa);
+static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa,
+					 int node, int root);
+static reg_errcode_t calc_inveclosure (re_dfa_t *dfa);
+static int fetch_number (re_string_t *input, re_token_t *token,
+			 reg_syntax_t syntax);
+static int peek_token (re_token_t *token, re_string_t *input,
+			reg_syntax_t syntax) internal_function;
+static bin_tree_t *parse (re_string_t *regexp, regex_t *preg,
+			  reg_syntax_t syntax, reg_errcode_t *err);
+static bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg,
+				  re_token_t *token, reg_syntax_t syntax,
+				  int nest, reg_errcode_t *err);
+static bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg,
+				 re_token_t *token, reg_syntax_t syntax,
+				 int nest, reg_errcode_t *err);
+static bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg,
+				     re_token_t *token, reg_syntax_t syntax,
+				     int nest, reg_errcode_t *err);
+static bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg,
+				  re_token_t *token, reg_syntax_t syntax,
+				  int nest, reg_errcode_t *err);
+static bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp,
+				 re_dfa_t *dfa, re_token_t *token,
+				 reg_syntax_t syntax, reg_errcode_t *err);
+static bin_tree_t *parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa,
+				      re_token_t *token, reg_syntax_t syntax,
+				      reg_errcode_t *err);
+static reg_errcode_t parse_bracket_element (bracket_elem_t *elem,
+					    re_string_t *regexp,
+					    re_token_t *token, int token_len,
+					    re_dfa_t *dfa,
+					    reg_syntax_t syntax,
+					    int accept_hyphen);
+static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem,
+					  re_string_t *regexp,
+					  re_token_t *token);
+#ifdef RE_ENABLE_I18N
+static reg_errcode_t build_equiv_class (bitset_t sbcset,
+					re_charset_t *mbcset,
+					int *equiv_class_alloc,
+					const unsigned char *name);
+static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,
+				      bitset_t sbcset,
+				      re_charset_t *mbcset,
+				      int *char_class_alloc,
+				      const char *class_name,
+				      reg_syntax_t syntax);
+#else  /* not RE_ENABLE_I18N */
+static reg_errcode_t build_equiv_class (bitset_t sbcset,
+					const unsigned char *name);
+static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,
+				      bitset_t sbcset,
+				      const char *class_name,
+				      reg_syntax_t syntax);
+#endif /* not RE_ENABLE_I18N */
+static bin_tree_t *build_charclass_op (re_dfa_t *dfa,
+				       RE_TRANSLATE_TYPE trans,
+				       const char *class_name,
+				       const char *extra,
+				       int non_match, reg_errcode_t *err);
+static bin_tree_t *create_tree (re_dfa_t *dfa,
+				bin_tree_t *left, bin_tree_t *right,
+				re_token_type_t type);
+static bin_tree_t *create_token_tree (re_dfa_t *dfa,
+				      bin_tree_t *left, bin_tree_t *right,
+				      const re_token_t *token);
+static bin_tree_t *duplicate_tree (const bin_tree_t *src, re_dfa_t *dfa);
+static void free_token (re_token_t *node);
+static reg_errcode_t free_tree (void *extra, bin_tree_t *node);
+static reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node);
+
+/* This table gives an error message for each of the error codes listed
+   in regex.h.  Obviously the order here has to be same as there.
+   POSIX doesn't require that we do anything for REG_NOERROR,
+   but why not be nice?  */
+
+const char __re_error_msgid[] attribute_hidden =
+  {
+#define REG_NOERROR_IDX	0
+    gettext_noop ("Success")	/* REG_NOERROR */
+    "\0"
+#define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof "Success")
+    gettext_noop ("No match")	/* REG_NOMATCH */
+    "\0"
+#define REG_BADPAT_IDX	(REG_NOMATCH_IDX + sizeof "No match")
+    gettext_noop ("Invalid regular expression") /* REG_BADPAT */
+    "\0"
+#define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof "Invalid regular expression")
+    gettext_noop ("Invalid collation character") /* REG_ECOLLATE */
+    "\0"
+#define REG_ECTYPE_IDX	(REG_ECOLLATE_IDX + sizeof "Invalid collation character")
+    gettext_noop ("Invalid character class name") /* REG_ECTYPE */
+    "\0"
+#define REG_EESCAPE_IDX	(REG_ECTYPE_IDX + sizeof "Invalid character class name")
+    gettext_noop ("Trailing backslash") /* REG_EESCAPE */
+    "\0"
+#define REG_ESUBREG_IDX	(REG_EESCAPE_IDX + sizeof "Trailing backslash")
+    gettext_noop ("Invalid back reference") /* REG_ESUBREG */
+    "\0"
+#define REG_EBRACK_IDX	(REG_ESUBREG_IDX + sizeof "Invalid back reference")
+    gettext_noop ("Unmatched [ or [^")	/* REG_EBRACK */
+    "\0"
+#define REG_EPAREN_IDX	(REG_EBRACK_IDX + sizeof "Unmatched [ or [^")
+    gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */
+    "\0"
+#define REG_EBRACE_IDX	(REG_EPAREN_IDX + sizeof "Unmatched ( or \\(")
+    gettext_noop ("Unmatched \\{") /* REG_EBRACE */
+    "\0"
+#define REG_BADBR_IDX	(REG_EBRACE_IDX + sizeof "Unmatched \\{")
+    gettext_noop ("Invalid content of \\{\\}") /* REG_BADBR */
+    "\0"
+#define REG_ERANGE_IDX	(REG_BADBR_IDX + sizeof "Invalid content of \\{\\}")
+    gettext_noop ("Invalid range end")	/* REG_ERANGE */
+    "\0"
+#define REG_ESPACE_IDX	(REG_ERANGE_IDX + sizeof "Invalid range end")
+    gettext_noop ("Memory exhausted") /* REG_ESPACE */
+    "\0"
+#define REG_BADRPT_IDX	(REG_ESPACE_IDX + sizeof "Memory exhausted")
+    gettext_noop ("Invalid preceding regular expression") /* REG_BADRPT */
+    "\0"
+#define REG_EEND_IDX	(REG_BADRPT_IDX + sizeof "Invalid preceding regular expression")
+    gettext_noop ("Premature end of regular expression") /* REG_EEND */
+    "\0"
+#define REG_ESIZE_IDX	(REG_EEND_IDX + sizeof "Premature end of regular expression")
+    gettext_noop ("Regular expression too big") /* REG_ESIZE */
+    "\0"
+#define REG_ERPAREN_IDX	(REG_ESIZE_IDX + sizeof "Regular expression too big")
+    gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
+  };
+
+const size_t __re_error_msgid_idx[] attribute_hidden =
+  {
+    REG_NOERROR_IDX,
+    REG_NOMATCH_IDX,
+    REG_BADPAT_IDX,
+    REG_ECOLLATE_IDX,
+    REG_ECTYPE_IDX,
+    REG_EESCAPE_IDX,
+    REG_ESUBREG_IDX,
+    REG_EBRACK_IDX,
+    REG_EPAREN_IDX,
+    REG_EBRACE_IDX,
+    REG_BADBR_IDX,
+    REG_ERANGE_IDX,
+    REG_ESPACE_IDX,
+    REG_BADRPT_IDX,
+    REG_EEND_IDX,
+    REG_ESIZE_IDX,
+    REG_ERPAREN_IDX
+  };
+
+/* Entry points for GNU code.  */
+
+
+#ifdef ZOS_USS
+
+/* For ZOS USS we must define btowc */
+
+wchar_t 
+btowc (int c)
+{
+   wchar_t wtmp[2];
+   char tmp[2];
+
+   tmp[0] = c;
+   tmp[1] = 0;
+
+   mbtowc (wtmp, tmp, 1);
+   return wtmp[0];
+}
+#endif
+
+/* re_compile_pattern is the GNU regular expression compiler: it
+   compiles PATTERN (of length LENGTH) and puts the result in BUFP.
+   Returns 0 if the pattern was valid, otherwise an error string.
+
+   Assumes the `allocated' (and perhaps `buffer') and `translate' fields
+   are set in BUFP on entry.  */
+
+const char *
+re_compile_pattern (const char *pattern,
+		    size_t length,
+		    struct re_pattern_buffer *bufp)
+{
+  reg_errcode_t ret;
+
+  /* And GNU code determines whether or not to get register information
+     by passing null for the REGS argument to re_match, etc., not by
+     setting no_sub, unless RE_NO_SUB is set.  */
+  bufp->no_sub = !!(re_syntax_options & RE_NO_SUB);
+
+  /* Match anchors at newline.  */
+  bufp->newline_anchor = 1;
+
+  ret = re_compile_internal (bufp, pattern, length, re_syntax_options);
+
+  if (!ret)
+    return NULL;
+  return gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]);
+}
+#ifdef _LIBC
+weak_alias (__re_compile_pattern, re_compile_pattern)
+#endif
+
+/* Set by `re_set_syntax' to the current regexp syntax to recognize.  Can
+   also be assigned to arbitrarily: each pattern buffer stores its own
+   syntax, so it can be changed between regex compilations.  */
+/* This has no initializer because initialized variables in Emacs
+   become read-only after dumping.  */
+reg_syntax_t re_syntax_options;
+
+
+/* Specify the precise syntax of regexps for compilation.  This provides
+   for compatibility for various utilities which historically have
+   different, incompatible syntaxes.
+
+   The argument SYNTAX is a bit mask comprised of the various bits
+   defined in regex.h.  We return the old syntax.  */
+
+reg_syntax_t
+re_set_syntax (reg_syntax_t syntax)
+{
+  reg_syntax_t ret = re_syntax_options;
+
+  re_syntax_options = syntax;
+  return ret;
+}
+#ifdef _LIBC
+weak_alias (__re_set_syntax, re_set_syntax)
+#endif
+
+int
+re_compile_fastmap (struct re_pattern_buffer *bufp)
+{
+  re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
+  char *fastmap = bufp->fastmap;
+
+  memset (fastmap, '\0', sizeof (char) * SBC_MAX);
+  re_compile_fastmap_iter (bufp, dfa->init_state, fastmap);
+  if (dfa->init_state != dfa->init_state_word)
+    re_compile_fastmap_iter (bufp, dfa->init_state_word, fastmap);
+  if (dfa->init_state != dfa->init_state_nl)
+    re_compile_fastmap_iter (bufp, dfa->init_state_nl, fastmap);
+  if (dfa->init_state != dfa->init_state_begbuf)
+    re_compile_fastmap_iter (bufp, dfa->init_state_begbuf, fastmap);
+  bufp->fastmap_accurate = 1;
+  return 0;
+}
+#ifdef _LIBC
+weak_alias (__re_compile_fastmap, re_compile_fastmap)
+#endif
+
+static inline void
+__attribute ((always_inline))
+re_set_fastmap (char *fastmap, int icase, int ch)
+{
+  fastmap[ch] = 1;
+  if (icase)
+    fastmap[tolower (ch)] = 1;
+}
+
+/* Helper function for re_compile_fastmap.
+   Compile fastmap for the initial_state INIT_STATE.  */
+
+static void
+re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
+			 char *fastmap)
+{
+  volatile re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
+  int node_cnt;
+  int icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));
+  for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
+    {
+      int node = init_state->nodes.elems[node_cnt];
+      re_token_type_t type = dfa->nodes[node].type;
+
+      if (type == CHARACTER)
+	{
+	  re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
+#ifdef RE_ENABLE_I18N
+	  if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
+	    {
+	      unsigned char *buf = re_malloc (unsigned char, dfa->mb_cur_max), *p;
+	      wchar_t wc;
+	      mbstate_t state;
+
+	      p = buf;
+	      *p++ = dfa->nodes[node].opr.c;
+	      while (++node < dfa->nodes_len
+		     &&	dfa->nodes[node].type == CHARACTER
+		     && dfa->nodes[node].mb_partial)
+		*p++ = dfa->nodes[node].opr.c;
+	      memset (&state, '\0', sizeof (state));
+	      if (__mbrtowc (&wc, (const char *) buf, p - buf,
+			     &state) == p - buf
+		  && (__wcrtomb ((char *) buf, towlower (wc), &state)
+		      != (size_t) -1))
+		re_set_fastmap (fastmap, 0, buf[0]);
+	      re_free (buf);
+	    }
+#endif
+	}
+      else if (type == SIMPLE_BRACKET)
+	{
+	  int i, ch;
+	  for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
+	    {
+	      int j;
+	      bitset_word_t w = dfa->nodes[node].opr.sbcset[i];
+	      for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
+		if (w & ((bitset_word_t) 1 << j))
+		  re_set_fastmap (fastmap, icase, ch);
+	    }
+	}
+#ifdef RE_ENABLE_I18N
+      else if (type == COMPLEX_BRACKET)
+	{
+	  re_charset_t *cset = dfa->nodes[node].opr.mbcset;
+	  int i;
+
+# ifdef _LIBC
+	  /* See if we have to try all bytes which start multiple collation
+	     elements.
+	     e.g. In da_DK, we want to catch 'a' since "aa" is a valid
+		  collation element, and don't catch 'b' since 'b' is
+		  the only collation element which starts from 'b' (and
+		  it is caught by SIMPLE_BRACKET).  */
+	      if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0
+		  && (cset->ncoll_syms || cset->nranges))
+		{
+		  const int32_t *table = (const int32_t *)
+		    _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+		  for (i = 0; i < SBC_MAX; ++i)
+		    if (table[i] < 0)
+		      re_set_fastmap (fastmap, icase, i);
+		}
+# endif /* _LIBC */
+
+	  /* See if we have to start the match at all multibyte characters,
+	     i.e. where we would not find an invalid sequence.  This only
+	     applies to multibyte character sets; for single byte character
+	     sets, the SIMPLE_BRACKET again suffices.  */
+	  if (dfa->mb_cur_max > 1
+	      && (cset->nchar_classes || cset->non_match || cset->nranges
+# ifdef _LIBC
+		  || cset->nequiv_classes
+# endif /* _LIBC */
+		 ))
+	    {
+	      unsigned char c = 0;
+	      do
+		{
+		  mbstate_t mbs;
+		  memset (&mbs, 0, sizeof (mbs));
+		  if (__mbrtowc (NULL, (char *) &c, 1, &mbs) == (size_t) -2)
+		    re_set_fastmap (fastmap, false, (int) c);
+		}
+	      while (++c != 0);
+	    }
+
+	  else
+	    {
+	      /* ... Else catch all bytes which can start the mbchars.  */
+	      for (i = 0; i < cset->nmbchars; ++i)
+		{
+		  char buf[256];
+		  mbstate_t state;
+		  memset (&state, '\0', sizeof (state));
+		  if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
+		    re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
+		  if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
+		    {
+		      if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)
+			  != (size_t) -1)
+			re_set_fastmap (fastmap, false, *(unsigned char *) buf);
+		    }
+		}
+	    }
+	}
+#endif /* RE_ENABLE_I18N */
+      else if (type == OP_PERIOD
+#ifdef RE_ENABLE_I18N
+	       || type == OP_UTF8_PERIOD
+#endif /* RE_ENABLE_I18N */
+	       || type == END_OF_RE)
+	{
+	  memset (fastmap, '\1', sizeof (char) * SBC_MAX);
+	  if (type == END_OF_RE)
+	    bufp->can_be_null = 1;
+	  return;
+	}
+    }
+}
+
+/* Entry point for POSIX code.  */
+/* regcomp takes a regular expression as a string and compiles it.
+
+   PREG is a regex_t *.  We do not expect any fields to be initialized,
+   since POSIX says we shouldn't.  Thus, we set
+
+     `buffer' to the compiled pattern;
+     `used' to the length of the compiled pattern;
+     `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
+       REG_EXTENDED bit in CFLAGS is set; otherwise, to
+       RE_SYNTAX_POSIX_BASIC;
+     `newline_anchor' to REG_NEWLINE being set in CFLAGS;
+     `fastmap' to an allocated space for the fastmap;
+     `fastmap_accurate' to zero;
+     `re_nsub' to the number of subexpressions in PATTERN.
+
+   PATTERN is the address of the pattern string.
+
+   CFLAGS is a series of bits which affect compilation.
+
+     If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
+     use POSIX basic syntax.
+
+     If REG_NEWLINE is set, then . and [^...] don't match newline.
+     Also, regexec will try a match beginning after every newline.
+
+     If REG_ICASE is set, then we considers upper- and lowercase
+     versions of letters to be equivalent when matching.
+
+     If REG_NOSUB is set, then when PREG is passed to regexec, that
+     routine will report only success or failure, and nothing about the
+     registers.
+
+   It returns 0 if it succeeds, nonzero if it doesn't.  (See regex.h for
+   the return codes and their meanings.)  */
+
+int
+regcomp (regex_t *__restrict preg,
+	 const char *__restrict pattern,
+	 int cflags)
+{
+  reg_errcode_t ret;
+  reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED
+			 : RE_SYNTAX_POSIX_BASIC);
+
+  preg->buffer = NULL;
+  preg->allocated = 0;
+  preg->used = 0;
+
+  /* Try to allocate space for the fastmap.  */
+  preg->fastmap = re_malloc (char, SBC_MAX);
+  if (BE (preg->fastmap == NULL, 0))
+    return REG_ESPACE;
+
+  syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0;
+
+  /* If REG_NEWLINE is set, newlines are treated differently.  */
+  if (cflags & REG_NEWLINE)
+    { /* REG_NEWLINE implies neither . nor [^...] match newline.  */
+      syntax &= ~RE_DOT_NEWLINE;
+      syntax |= RE_HAT_LISTS_NOT_NEWLINE;
+      /* It also changes the matching behavior.  */
+      preg->newline_anchor = 1;
+    }
+  else
+    preg->newline_anchor = 0;
+  preg->no_sub = !!(cflags & REG_NOSUB);
+  preg->translate = NULL;
+
+  ret = re_compile_internal (preg, pattern, strlen (pattern), syntax);
+
+  /* POSIX doesn't distinguish between an unmatched open-group and an
+     unmatched close-group: both are REG_EPAREN.  */
+  if (ret == REG_ERPAREN)
+    ret = REG_EPAREN;
+
+  /* We have already checked preg->fastmap != NULL.  */
+  if (BE (ret == REG_NOERROR, 1))
+    /* Compute the fastmap now, since regexec cannot modify the pattern
+       buffer.  This function never fails in this implementation.  */
+    (void) re_compile_fastmap (preg);
+  else
+    {
+      /* Some error occurred while compiling the expression.  */
+      re_free (preg->fastmap);
+      preg->fastmap = NULL;
+    }
+
+  return (int) ret;
+}
+#ifdef _LIBC
+weak_alias (__regcomp, regcomp)
+#endif
+
+/* Returns a message corresponding to an error code, ERRCODE, returned
+   from either regcomp or regexec.   We don't use PREG here.  */
+
+size_t
+regerror(int errcode, UNUSED const regex_t *__restrict preg,
+	 char *__restrict errbuf, size_t errbuf_size)
+{
+  const char *msg;
+  size_t msg_size;
+
+  if (BE (errcode < 0
+	  || errcode >= (int) (sizeof (__re_error_msgid_idx)
+			       / sizeof (__re_error_msgid_idx[0])), 0))
+    /* Only error codes returned by the rest of the code should be passed
+       to this routine.  If we are given anything else, or if other regex
+       code generates an invalid error code, then the program has a bug.
+       Dump core so we can fix it.  */
+    abort ();
+
+  msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]);
+
+  msg_size = strlen (msg) + 1; /* Includes the null.  */
+
+  if (BE (errbuf_size != 0, 1))
+    {
+      if (BE (msg_size > errbuf_size, 0))
+	{
+	  memcpy (errbuf, msg, errbuf_size - 1);
+	  errbuf[errbuf_size - 1] = 0;
+	}
+      else
+	memcpy (errbuf, msg, msg_size);
+    }
+
+  return msg_size;
+}
+#ifdef _LIBC
+weak_alias (__regerror, regerror)
+#endif
+
+
+#ifdef RE_ENABLE_I18N
+/* This static array is used for the map to single-byte characters when
+   UTF-8 is used.  Otherwise we would allocate memory just to initialize
+   it the same all the time.  UTF-8 is the preferred encoding so this is
+   a worthwhile optimization.  */
+#if __GNUC__ >= 3
+static const bitset_t utf8_sb_map = {
+  /* Set the first 128 bits.  */
+  [0 ... 0x80 / BITSET_WORD_BITS - 1] = BITSET_WORD_MAX
+};
+#else /* ! (__GNUC__ >= 3) */
+static bitset_t utf8_sb_map;
+#endif /* __GNUC__ >= 3 */
+#endif /* RE_ENABLE_I18N */
+
+
+static void
+free_dfa_content (re_dfa_t *dfa)
+{
+  unsigned int i;
+  int j;
+
+  if (dfa->nodes)
+    for (i = 0; i < dfa->nodes_len; ++i)
+      free_token (dfa->nodes + i);
+  re_free (dfa->nexts);
+  for (i = 0; i < dfa->nodes_len; ++i)
+    {
+      if (dfa->eclosures != NULL)
+	re_node_set_free (dfa->eclosures + i);
+      if (dfa->inveclosures != NULL)
+	re_node_set_free (dfa->inveclosures + i);
+      if (dfa->edests != NULL)
+	re_node_set_free (dfa->edests + i);
+    }
+  re_free (dfa->edests);
+  re_free (dfa->eclosures);
+  re_free (dfa->inveclosures);
+  re_free (dfa->nodes);
+
+  if (dfa->state_table)
+    for (i = 0; i <= dfa->state_hash_mask; ++i)
+      {
+	struct re_state_table_entry *entry = dfa->state_table + i;
+	for (j = 0; j < entry->num; ++j)
+	  {
+	    re_dfastate_t *state = entry->array[j];
+	    free_state (state);
+	  }
+	re_free (entry->array);
+      }
+  re_free (dfa->state_table);
+#ifdef RE_ENABLE_I18N
+  if (dfa->sb_char != utf8_sb_map)
+    re_free (dfa->sb_char);
+#endif
+  re_free (dfa->subexp_map);
+#ifdef DEBUG
+  re_free (dfa->re_str);
+#endif
+
+  re_free (dfa);
+}
+
+
+/* Free dynamically allocated space used by PREG.  */
+
+void
+regfree (regex_t *preg)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  if (BE (dfa != NULL, 1))
+    free_dfa_content (dfa);
+  preg->buffer = NULL;
+  preg->allocated = 0;
+
+  re_free (preg->fastmap);
+  preg->fastmap = NULL;
+
+  re_free (preg->translate);
+  preg->translate = NULL;
+}
+#ifdef _LIBC
+weak_alias (__regfree, regfree)
+#endif
+
+/* Entry points compatible with 4.2 BSD regex library.  We don't define
+   them unless specifically requested.  */
+
+#if defined _REGEX_RE_COMP || defined _LIBC
+
+/* BSD has one and only one pattern buffer.  */
+static struct re_pattern_buffer re_comp_buf;
+
+char *
+# ifdef _LIBC
+/* Make these definitions weak in libc, so POSIX programs can redefine
+   these names if they don't use our functions, and still use
+   regcomp/regexec above without link errors.  */
+weak_function
+# endif
+re_comp (s)
+     const char *s;
+{
+  reg_errcode_t ret;
+  char *fastmap;
+
+  if (!s)
+    {
+      if (!re_comp_buf.buffer)
+	return gettext ("No previous regular expression");
+      return 0;
+    }
+
+  if (re_comp_buf.buffer)
+    {
+      fastmap = re_comp_buf.fastmap;
+      re_comp_buf.fastmap = NULL;
+      __regfree (&re_comp_buf);
+      memset (&re_comp_buf, '\0', sizeof (re_comp_buf));
+      re_comp_buf.fastmap = fastmap;
+    }
+
+  if (re_comp_buf.fastmap == NULL)
+    {
+      re_comp_buf.fastmap = (char *) malloc (SBC_MAX);
+      if (re_comp_buf.fastmap == NULL)
+	return (char *) gettext (__re_error_msgid
+				 + __re_error_msgid_idx[(int) REG_ESPACE]);
+    }
+
+  /* Since `re_exec' always passes NULL for the `regs' argument, we
+     don't need to initialize the pattern buffer fields which affect it.  */
+
+  /* Match anchors at newlines.  */
+  re_comp_buf.newline_anchor = 1;
+
+  ret = re_compile_internal (&re_comp_buf, s, strlen (s), re_syntax_options);
+
+  if (!ret)
+    return NULL;
+
+  /* Yes, we're discarding `const' here if !HAVE_LIBINTL.  */
+  return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]);
+}
+
+#ifdef _LIBC
+libc_freeres_fn (free_mem)
+{
+  __regfree (&re_comp_buf);
+}
+#endif
+
+#endif /* _REGEX_RE_COMP */
+
+/* Internal entry point.
+   Compile the regular expression PATTERN, whose length is LENGTH.
+   SYNTAX indicate regular expression's syntax.  */
+
+static reg_errcode_t
+re_compile_internal (regex_t *preg, const char * pattern, size_t length,
+		     reg_syntax_t syntax)
+{
+  reg_errcode_t err = REG_NOERROR;
+  re_dfa_t *dfa;
+  re_string_t regexp;
+
+  /* Initialize the pattern buffer.  */
+  preg->fastmap_accurate = 0;
+  preg->syntax = syntax;
+  preg->not_bol = preg->not_eol = 0;
+  preg->used = 0;
+  preg->re_nsub = 0;
+  preg->can_be_null = 0;
+  preg->regs_allocated = REGS_UNALLOCATED;
+
+  /* Initialize the dfa.  */
+  dfa = (re_dfa_t *) preg->buffer;
+  if (BE (preg->allocated < sizeof (re_dfa_t), 0))
+    {
+      /* If zero allocated, but buffer is non-null, try to realloc
+	 enough space.  This loses if buffer's address is bogus, but
+	 that is the user's responsibility.  If ->buffer is NULL this
+	 is a simple allocation.  */
+      dfa = re_realloc (preg->buffer, re_dfa_t, 1);
+      if (dfa == NULL)
+	return REG_ESPACE;
+      preg->allocated = sizeof (re_dfa_t);
+      preg->buffer = (unsigned char *) dfa;
+    }
+  preg->used = sizeof (re_dfa_t);
+
+  err = init_dfa (dfa, length);
+  if (BE (err != REG_NOERROR, 0))
+    {
+      free_dfa_content (dfa);
+      preg->buffer = NULL;
+      preg->allocated = 0;
+      return err;
+    }
+#ifdef DEBUG
+  /* Note: length+1 will not overflow since it is checked in init_dfa.  */
+  dfa->re_str = re_malloc (char, length + 1);
+  strncpy (dfa->re_str, pattern, length + 1);
+#endif
+
+  __libc_lock_init (dfa->lock);
+
+  err = re_string_construct (&regexp, pattern, length, preg->translate,
+			     syntax & RE_ICASE, dfa);
+  if (BE (err != REG_NOERROR, 0))
+    {
+    re_compile_internal_free_return:
+      free_workarea_compile (preg);
+      re_string_destruct (&regexp);
+      free_dfa_content (dfa);
+      preg->buffer = NULL;
+      preg->allocated = 0;
+      return err;
+    }
+
+  /* Parse the regular expression, and build a structure tree.  */
+  preg->re_nsub = 0;
+  dfa->str_tree = parse (&regexp, preg, syntax, &err);
+  if (BE (dfa->str_tree == NULL, 0))
+    goto re_compile_internal_free_return;
+
+  /* Analyze the tree and create the nfa.  */
+  err = analyze (preg);
+  if (BE (err != REG_NOERROR, 0))
+    goto re_compile_internal_free_return;
+
+#ifdef RE_ENABLE_I18N
+  /* If possible, do searching in single byte encoding to speed things up.  */
+  if (dfa->is_utf8 && !(syntax & RE_ICASE) && preg->translate == NULL)
+    optimize_utf8 (dfa);
+#endif
+
+  /* Then create the initial state of the dfa.  */
+  err = create_initial_state (dfa);
+
+  /* Release work areas.  */
+  free_workarea_compile (preg);
+  re_string_destruct (&regexp);
+
+  if (BE (err != REG_NOERROR, 0))
+    {
+      free_dfa_content (dfa);
+      preg->buffer = NULL;
+      preg->allocated = 0;
+    }
+
+  return err;
+}
+
+/* Initialize DFA.  We use the length of the regular expression PAT_LEN
+   as the initial length of some arrays.  */
+
+static reg_errcode_t
+init_dfa (re_dfa_t *dfa, size_t pat_len)
+{
+  unsigned int table_size;
+
+  memset (dfa, '\0', sizeof (re_dfa_t));
+
+  /* Force allocation of str_tree_storage the first time.  */
+  dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;
+
+  /* Avoid overflows.  */
+  if (pat_len == SIZE_MAX)
+    return REG_ESPACE;
+
+  dfa->nodes_alloc = pat_len + 1;
+  dfa->nodes = re_malloc (re_token_t, dfa->nodes_alloc);
+
+  /*  table_size = 2 ^ ceil(log pat_len) */
+  for (table_size = 1; ; table_size <<= 1)
+    if (table_size > pat_len)
+      break;
+
+  dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size);
+  dfa->state_hash_mask = table_size - 1;
+
+  dfa->mb_cur_max = MB_CUR_MAX;
+#ifdef _LIBC
+  if (dfa->mb_cur_max == 6
+      && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0)
+    dfa->is_utf8 = 1;
+  dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII)
+		       != 0);
+#else
+  dfa->is_utf8 = 1;
+  /* We check exhaustively in the loop below if this charset is a
+     superset of ASCII.  */
+  dfa->map_notascii = 0;
+#endif
+
+#ifdef RE_ENABLE_I18N
+  if (dfa->mb_cur_max > 1)
+    {
+      if (dfa->is_utf8)
+        {
+#if !defined(__GNUC__) || __GNUC__ < 3
+	  static short utf8_sb_map_inited = 0;
+
+	  if (! utf8_sb_map_inited)
+	    {
+		int i;
+
+	  	utf8_sb_map_inited = 0;
+		for (i = 0; i <= 0x80 / BITSET_WORD_BITS - 1; i++)
+		  utf8_sb_map[i] = BITSET_WORD_MAX;
+	    }
+#endif
+	  dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map;
+	}
+      else
+	{
+	  int i, j, ch;
+
+	  dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
+	  if (BE (dfa->sb_char == NULL, 0))
+	    return REG_ESPACE;
+
+	  /* Set the bits corresponding to single byte chars.  */
+	  for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
+	    for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
+	      {
+		wint_t wch = __btowc (ch);
+		if (wch != WEOF)
+		  dfa->sb_char[i] |= (bitset_word_t) 1 << j;
+# ifndef _LIBC
+		if (isascii (ch) && wch != ch)
+		  dfa->map_notascii = 1;
+# endif
+	      }
+	}
+    }
+#endif
+
+  if (BE (dfa->nodes == NULL || dfa->state_table == NULL, 0))
+    return REG_ESPACE;
+  return REG_NOERROR;
+}
+
+/* Initialize WORD_CHAR table, which indicate which character is
+   "word".  In this case "word" means that it is the word construction
+   character used by some operators like "\<", "\>", etc.  */
+
+static void
+internal_function
+init_word_char (re_dfa_t *dfa)
+{
+  int i, j, ch;
+  dfa->word_ops_used = 1;
+  for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
+    for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
+      if (isalnum (ch) || ch == '_')
+	dfa->word_char[i] |= (bitset_word_t) 1 << j;
+}
+
+/* Free the work area which are only used while compiling.  */
+
+static void
+free_workarea_compile (regex_t *preg)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_storage_t *storage, *next;
+  for (storage = dfa->str_tree_storage; storage; storage = next)
+    {
+      next = storage->next;
+      re_free (storage);
+    }
+  dfa->str_tree_storage = NULL;
+  dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;
+  dfa->str_tree = NULL;
+  re_free (dfa->org_indices);
+  dfa->org_indices = NULL;
+}
+
+/* Create initial states for all contexts.  */
+
+static reg_errcode_t
+create_initial_state (re_dfa_t *dfa)
+{
+  int first, i;
+  reg_errcode_t err;
+  re_node_set init_nodes;
+
+  /* Initial states have the epsilon closure of the node which is
+     the first node of the regular expression.  */
+  first = dfa->str_tree->first->node_idx;
+  dfa->init_node = first;
+  err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+
+  /* The back-references which are in initial states can epsilon transit,
+     since in this case all of the subexpressions can be null.
+     Then we add epsilon closures of the nodes which are the next nodes of
+     the back-references.  */
+  if (dfa->nbackref > 0)
+    for (i = 0; i < init_nodes.nelem; ++i)
+      {
+	int node_idx = init_nodes.elems[i];
+	re_token_type_t type = dfa->nodes[node_idx].type;
+
+	int clexp_idx;
+	if (type != OP_BACK_REF)
+	  continue;
+	for (clexp_idx = 0; clexp_idx < init_nodes.nelem; ++clexp_idx)
+	  {
+	    re_token_t *clexp_node;
+	    clexp_node = dfa->nodes + init_nodes.elems[clexp_idx];
+	    if (clexp_node->type == OP_CLOSE_SUBEXP
+		&& clexp_node->opr.idx == dfa->nodes[node_idx].opr.idx)
+	      break;
+	  }
+	if (clexp_idx == init_nodes.nelem)
+	  continue;
+
+	if (type == OP_BACK_REF)
+	  {
+	    int dest_idx = dfa->edests[node_idx].elems[0];
+	    if (!re_node_set_contains (&init_nodes, dest_idx))
+	      {
+		reg_errcode_t err = re_node_set_merge (&init_nodes,
+						       dfa->eclosures
+						       + dest_idx);
+		if (err != REG_NOERROR)
+		  return err;
+		i = 0;
+	      }
+	  }
+      }
+
+  /* It must be the first time to invoke acquire_state.  */
+  dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0);
+  /* We don't check ERR here, since the initial state must not be NULL.  */
+  if (BE (dfa->init_state == NULL, 0))
+    return err;
+  if (dfa->init_state->has_constraint)
+    {
+      dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes,
+						       CONTEXT_WORD);
+      dfa->init_state_nl = re_acquire_state_context (&err, dfa, &init_nodes,
+						     CONTEXT_NEWLINE);
+      dfa->init_state_begbuf = re_acquire_state_context (&err, dfa,
+							 &init_nodes,
+							 CONTEXT_NEWLINE
+							 | CONTEXT_BEGBUF);
+      if (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL
+	      || dfa->init_state_begbuf == NULL, 0))
+	return err;
+    }
+  else
+    dfa->init_state_word = dfa->init_state_nl
+      = dfa->init_state_begbuf = dfa->init_state;
+
+  re_node_set_free (&init_nodes);
+  return REG_NOERROR;
+}
+
+#ifdef RE_ENABLE_I18N
+/* If it is possible to do searching in single byte encoding instead of UTF-8
+   to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change
+   DFA nodes where needed.  */
+
+static void
+optimize_utf8 (re_dfa_t *dfa)
+{
+  int node, i, mb_chars = 0, has_period = 0;
+
+  for (node = 0; node < dfa->nodes_len; ++node)
+    switch (dfa->nodes[node].type)
+      {
+      case CHARACTER:
+	if (dfa->nodes[node].opr.c >= 0x80)
+	  mb_chars = 1;
+	break;
+      case ANCHOR:
+	switch (dfa->nodes[node].opr.ctx_type)
+	  {
+	  case LINE_FIRST:
+	  case LINE_LAST:
+	  case BUF_FIRST:
+	  case BUF_LAST:
+	    break;
+	  default:
+	    /* Word anchors etc. cannot be handled.  It's okay to test
+	       opr.ctx_type since constraints (for all DFA nodes) are
+	       created by ORing one or more opr.ctx_type values.  */
+	    return;
+	  }
+	break;
+      case OP_PERIOD:
+	has_period = 1;
+	break;
+      case OP_BACK_REF:
+      case OP_ALT:
+      case END_OF_RE:
+      case OP_DUP_ASTERISK:
+      case OP_OPEN_SUBEXP:
+      case OP_CLOSE_SUBEXP:
+	break;
+      case COMPLEX_BRACKET:
+	return;
+      case SIMPLE_BRACKET:
+	/* Just double check.  The non-ASCII range starts at 0x80.  */
+	assert (0x80 % BITSET_WORD_BITS == 0);
+	for (i = 0x80 / BITSET_WORD_BITS; i < BITSET_WORDS; ++i)
+	  if (dfa->nodes[node].opr.sbcset[i])
+	    return;
+	break;
+      default:
+	abort ();
+      }
+
+  if (mb_chars || has_period)
+    for (node = 0; node < dfa->nodes_len; ++node)
+      {
+	if (dfa->nodes[node].type == CHARACTER
+	    && dfa->nodes[node].opr.c >= 0x80)
+	  dfa->nodes[node].mb_partial = 0;
+	else if (dfa->nodes[node].type == OP_PERIOD)
+	  dfa->nodes[node].type = OP_UTF8_PERIOD;
+      }
+
+  /* The search can be in single byte locale.  */
+  dfa->mb_cur_max = 1;
+  dfa->is_utf8 = 0;
+  dfa->has_mb_node = dfa->nbackref > 0 || has_period;
+}
+#endif
+
+/* Analyze the structure tree, and calculate "first", "next", "edest",
+   "eclosure", and "inveclosure".  */
+
+static reg_errcode_t
+analyze (regex_t *preg)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  reg_errcode_t ret;
+
+  /* Allocate arrays.  */
+  dfa->nexts = re_malloc (int, dfa->nodes_alloc);
+  dfa->org_indices = re_malloc (int, dfa->nodes_alloc);
+  dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc);
+  dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc);
+  if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL
+	  || dfa->eclosures == NULL, 0))
+    return REG_ESPACE;
+
+  dfa->subexp_map = re_malloc (int, preg->re_nsub);
+  if (dfa->subexp_map != NULL)
+    {
+      unsigned int i;
+      for (i = 0; i < preg->re_nsub; i++)
+	dfa->subexp_map[i] = i;
+      preorder (dfa->str_tree, optimize_subexps, dfa);
+      for (i = 0; i < preg->re_nsub; i++)
+	if (dfa->subexp_map[i] != (int)i)
+	  break;
+      if (i == preg->re_nsub)
+	{
+	  free (dfa->subexp_map);
+	  dfa->subexp_map = NULL;
+	}
+    }
+
+  ret = postorder (dfa->str_tree, lower_subexps, preg);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+  ret = postorder (dfa->str_tree, calc_first, dfa);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+  preorder (dfa->str_tree, calc_next, dfa);
+  ret = preorder (dfa->str_tree, link_nfa_nodes, dfa);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+  ret = calc_eclosure (dfa);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+
+  /* We only need this during the prune_impossible_nodes pass in regexec.c;
+     skip it if p_i_n will not run, as calc_inveclosure can be quadratic.  */
+  if ((!preg->no_sub && preg->re_nsub > 0 && dfa->has_plural_match)
+      || dfa->nbackref)
+    {
+      dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len);
+      if (BE (dfa->inveclosures == NULL, 0))
+	return REG_ESPACE;
+      ret = calc_inveclosure (dfa);
+    }
+
+  return ret;
+}
+
+/* Our parse trees are very unbalanced, so we cannot use a stack to
+   implement parse tree visits.  Instead, we use parent pointers and
+   some hairy code in these two functions.  */
+static reg_errcode_t
+postorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)),
+	   void *extra)
+{
+  bin_tree_t *node, *prev;
+
+  for (node = root; ; )
+    {
+      /* Descend down the tree, preferably to the left (or to the right
+	 if that's the only child).  */
+      while (node->left || node->right)
+	if (node->left)
+	  node = node->left;
+	else
+	  node = node->right;
+
+      do
+	{
+	  reg_errcode_t err = fn (extra, node);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	  if (node->parent == NULL)
+	    return REG_NOERROR;
+	  prev = node;
+	  node = node->parent;
+	}
+      /* Go up while we have a node that is reached from the right.  */
+      while (node->right == prev || node->right == NULL);
+      node = node->right;
+    }
+}
+
+static reg_errcode_t
+preorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)),
+	  void *extra)
+{
+  bin_tree_t *node;
+
+  for (node = root; ; )
+    {
+      reg_errcode_t err = fn (extra, node);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+
+      /* Go to the left node, or up and to the right.  */
+      if (node->left)
+	node = node->left;
+      else
+	{
+	  bin_tree_t *prev = NULL;
+	  while (node->right == prev || node->right == NULL)
+	    {
+	      prev = node;
+	      node = node->parent;
+	      if (!node)
+		return REG_NOERROR;
+	    }
+	  node = node->right;
+	}
+    }
+}
+
+/* Optimization pass: if a SUBEXP is entirely contained, strip it and tell
+   re_search_internal to map the inner one's opr.idx to this one's.  Adjust
+   backreferences as well.  Requires a preorder visit.  */
+static reg_errcode_t
+optimize_subexps (void *extra, bin_tree_t *node)
+{
+  re_dfa_t *dfa = (re_dfa_t *) extra;
+
+  if (node->token.type == OP_BACK_REF && dfa->subexp_map)
+    {
+      int idx = node->token.opr.idx;
+      node->token.opr.idx = dfa->subexp_map[idx];
+      dfa->used_bkref_map |= 1 << node->token.opr.idx;
+    }
+
+  else if (node->token.type == SUBEXP
+	   && node->left && node->left->token.type == SUBEXP)
+    {
+      int other_idx = node->left->token.opr.idx;
+
+      node->left = node->left->left;
+      if (node->left)
+	node->left->parent = node;
+
+      dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx];
+      if (other_idx < BITSET_WORD_BITS)
+	  dfa->used_bkref_map &= ~((bitset_word_t) 1 << other_idx);
+    }
+
+  return REG_NOERROR;
+}
+
+/* Lowering pass: Turn each SUBEXP node into the appropriate concatenation
+   of OP_OPEN_SUBEXP, the body of the SUBEXP (if any) and OP_CLOSE_SUBEXP.  */
+static reg_errcode_t
+lower_subexps (void *extra, bin_tree_t *node)
+{
+  regex_t *preg = (regex_t *) extra;
+  reg_errcode_t err = REG_NOERROR;
+
+  if (node->left && node->left->token.type == SUBEXP)
+    {
+      node->left = lower_subexp (&err, preg, node->left);
+      if (node->left)
+	node->left->parent = node;
+    }
+  if (node->right && node->right->token.type == SUBEXP)
+    {
+      node->right = lower_subexp (&err, preg, node->right);
+      if (node->right)
+	node->right->parent = node;
+    }
+
+  return err;
+}
+
+static bin_tree_t *
+lower_subexp (reg_errcode_t *err, regex_t *preg, bin_tree_t *node)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_t *body = node->left;
+  bin_tree_t *op, *cls, *tree1, *tree;
+
+  if (preg->no_sub
+      /* We do not optimize empty subexpressions, because otherwise we may
+	 have bad CONCAT nodes with NULL children.  This is obviously not
+	 very common, so we do not lose much.  An example that triggers
+	 this case is the sed "script" /\(\)/x.  */
+      && node->left != NULL
+      && (node->token.opr.idx >= BITSET_WORD_BITS
+	  || !(dfa->used_bkref_map
+	       & ((bitset_word_t) 1 << node->token.opr.idx))))
+    return node->left;
+
+  /* Convert the SUBEXP node to the concatenation of an
+     OP_OPEN_SUBEXP, the contents, and an OP_CLOSE_SUBEXP.  */
+  op = create_tree (dfa, NULL, NULL, OP_OPEN_SUBEXP);
+  cls = create_tree (dfa, NULL, NULL, OP_CLOSE_SUBEXP);
+  tree1 = body ? create_tree (dfa, body, cls, CONCAT) : cls;
+  tree = create_tree (dfa, op, tree1, CONCAT);
+  if (BE (tree == NULL || tree1 == NULL || op == NULL || cls == NULL, 0))
+    {
+      *err = REG_ESPACE;
+      return NULL;
+    }
+
+  op->token.opr.idx = cls->token.opr.idx = node->token.opr.idx;
+  op->token.opt_subexp = cls->token.opt_subexp = node->token.opt_subexp;
+  return tree;
+}
+
+/* Pass 1 in building the NFA: compute FIRST and create unlinked automaton
+   nodes.  Requires a postorder visit.  */
+static reg_errcode_t
+calc_first (void *extra, bin_tree_t *node)
+{
+  re_dfa_t *dfa = (re_dfa_t *) extra;
+  if (node->token.type == CONCAT)
+    {
+      node->first = node->left->first;
+      node->node_idx = node->left->node_idx;
+    }
+  else
+    {
+      node->first = node;
+      node->node_idx = re_dfa_add_node (dfa, node->token);
+      if (BE (node->node_idx == -1, 0))
+	return REG_ESPACE;
+      if (node->token.type == ANCHOR)
+	dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type;
+    }
+  return REG_NOERROR;
+}
+
+/* Pass 2: compute NEXT on the tree.  Preorder visit.  */
+static reg_errcode_t
+calc_next (UNUSED void *extra, bin_tree_t *node)
+{
+  switch (node->token.type)
+    {
+    case OP_DUP_ASTERISK:
+      node->left->next = node;
+      break;
+    case CONCAT:
+      node->left->next = node->right->first;
+      node->right->next = node->next;
+      break;
+    default:
+      if (node->left)
+	node->left->next = node->next;
+      if (node->right)
+	node->right->next = node->next;
+      break;
+    }
+  return REG_NOERROR;
+}
+
+/* Pass 3: link all DFA nodes to their NEXT node (any order will do).  */
+static reg_errcode_t
+link_nfa_nodes (void *extra, bin_tree_t *node)
+{
+  re_dfa_t *dfa = (re_dfa_t *) extra;
+  int idx = node->node_idx;
+  reg_errcode_t err = REG_NOERROR;
+
+  switch (node->token.type)
+    {
+    case CONCAT:
+      break;
+
+    case END_OF_RE:
+      assert (node->next == NULL);
+      break;
+
+    case OP_DUP_ASTERISK:
+    case OP_ALT:
+      {
+	int left, right;
+	dfa->has_plural_match = 1;
+	if (node->left != NULL)
+	  left = node->left->first->node_idx;
+	else
+	  left = node->next->node_idx;
+	if (node->right != NULL)
+	  right = node->right->first->node_idx;
+	else
+	  right = node->next->node_idx;
+	assert (left > -1);
+	assert (right > -1);
+	err = re_node_set_init_2 (dfa->edests + idx, left, right);
+      }
+      break;
+
+    case ANCHOR:
+    case OP_OPEN_SUBEXP:
+    case OP_CLOSE_SUBEXP:
+      err = re_node_set_init_1 (dfa->edests + idx, node->next->node_idx);
+      break;
+
+    case OP_BACK_REF:
+      dfa->nexts[idx] = node->next->node_idx;
+      if (node->token.type == OP_BACK_REF)
+	err = re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]);
+      break;
+
+    default:
+      assert (!IS_EPSILON_NODE (node->token.type));
+      dfa->nexts[idx] = node->next->node_idx;
+      break;
+    }
+
+  return err;
+}
+
+/* Duplicate the epsilon closure of the node ROOT_NODE.
+   Note that duplicated nodes have constraint INIT_CONSTRAINT in addition
+   to their own constraint.  */
+
+static reg_errcode_t
+internal_function
+duplicate_node_closure (re_dfa_t *dfa, int top_org_node, int top_clone_node,
+			int root_node, unsigned int init_constraint)
+{
+  int org_node, clone_node, ret;
+  unsigned int constraint = init_constraint;
+  for (org_node = top_org_node, clone_node = top_clone_node;;)
+    {
+      int org_dest, clone_dest;
+      if (dfa->nodes[org_node].type == OP_BACK_REF)
+	{
+	  /* If the back reference epsilon-transit, its destination must
+	     also have the constraint.  Then duplicate the epsilon closure
+	     of the destination of the back reference, and store it in
+	     edests of the back reference.  */
+	  org_dest = dfa->nexts[org_node];
+	  re_node_set_empty (dfa->edests + clone_node);
+	  clone_dest = duplicate_node (dfa, org_dest, constraint);
+	  if (BE (clone_dest == -1, 0))
+	    return REG_ESPACE;
+	  dfa->nexts[clone_node] = dfa->nexts[org_node];
+	  ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+	  if (BE (ret < 0, 0))
+	    return REG_ESPACE;
+	}
+      else if (dfa->edests[org_node].nelem == 0)
+	{
+	  /* In case of the node can't epsilon-transit, don't duplicate the
+	     destination and store the original destination as the
+	     destination of the node.  */
+	  dfa->nexts[clone_node] = dfa->nexts[org_node];
+	  break;
+	}
+      else if (dfa->edests[org_node].nelem == 1)
+	{
+	  /* In case of the node can epsilon-transit, and it has only one
+	     destination.  */
+	  org_dest = dfa->edests[org_node].elems[0];
+	  re_node_set_empty (dfa->edests + clone_node);
+	  /* If the node is root_node itself, it means the epsilon clsoure
+	     has a loop.   Then tie it to the destination of the root_node.  */
+	  if (org_node == root_node && clone_node != org_node)
+	    {
+	      ret = re_node_set_insert (dfa->edests + clone_node, org_dest);
+	      if (BE (ret < 0, 0))
+		return REG_ESPACE;
+	      break;
+	    }
+	  /* In case of the node has another constraint, add it.  */
+	  constraint |= dfa->nodes[org_node].constraint;
+	  clone_dest = duplicate_node (dfa, org_dest, constraint);
+	  if (BE (clone_dest == -1, 0))
+	    return REG_ESPACE;
+	  ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+	  if (BE (ret < 0, 0))
+	    return REG_ESPACE;
+	}
+      else /* dfa->edests[org_node].nelem == 2 */
+	{
+	  /* In case of the node can epsilon-transit, and it has two
+	     destinations. In the bin_tree_t and DFA, that's '|' and '*'.   */
+	  org_dest = dfa->edests[org_node].elems[0];
+	  re_node_set_empty (dfa->edests + clone_node);
+	  /* Search for a duplicated node which satisfies the constraint.  */
+	  clone_dest = search_duplicated_node (dfa, org_dest, constraint);
+	  if (clone_dest == -1)
+	    {
+	      /* There is no such duplicated node, create a new one.  */
+	      reg_errcode_t err;
+	      clone_dest = duplicate_node (dfa, org_dest, constraint);
+	      if (BE (clone_dest == -1, 0))
+		return REG_ESPACE;
+	      ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+	      if (BE (ret < 0, 0))
+		return REG_ESPACE;
+	      err = duplicate_node_closure (dfa, org_dest, clone_dest,
+					    root_node, constraint);
+	      if (BE (err != REG_NOERROR, 0))
+		return err;
+	    }
+	  else
+	    {
+	      /* There is a duplicated node which satisfies the constraint,
+		 use it to avoid infinite loop.  */
+	      ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+	      if (BE (ret < 0, 0))
+		return REG_ESPACE;
+	    }
+
+	  org_dest = dfa->edests[org_node].elems[1];
+	  clone_dest = duplicate_node (dfa, org_dest, constraint);
+	  if (BE (clone_dest == -1, 0))
+	    return REG_ESPACE;
+	  ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+	  if (BE (ret < 0, 0))
+	    return REG_ESPACE;
+	}
+      org_node = org_dest;
+      clone_node = clone_dest;
+    }
+  return REG_NOERROR;
+}
+
+/* Search for a node which is duplicated from the node ORG_NODE, and
+   satisfies the constraint CONSTRAINT.  */
+
+static int
+search_duplicated_node (const re_dfa_t *dfa, int org_node,
+			unsigned int constraint)
+{
+  int idx;
+  for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx)
+    {
+      if (org_node == dfa->org_indices[idx]
+	  && constraint == dfa->nodes[idx].constraint)
+	return idx; /* Found.  */
+    }
+  return -1; /* Not found.  */
+}
+
+/* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT.
+   Return the index of the new node, or -1 if insufficient storage is
+   available.  */
+
+static int
+duplicate_node (re_dfa_t *dfa, int org_idx, unsigned int constraint)
+{
+  int dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]);
+  if (BE (dup_idx != -1, 1))
+    {
+      dfa->nodes[dup_idx].constraint = constraint;
+      dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].constraint;
+      dfa->nodes[dup_idx].duplicated = 1;
+
+      /* Store the index of the original node.  */
+      dfa->org_indices[dup_idx] = org_idx;
+    }
+  return dup_idx;
+}
+
+static reg_errcode_t
+calc_inveclosure (re_dfa_t *dfa)
+{
+  int ret;
+  unsigned int src, idx;
+  for (idx = 0; idx < dfa->nodes_len; ++idx)
+    re_node_set_init_empty (dfa->inveclosures + idx);
+
+  for (src = 0; src < dfa->nodes_len; ++src)
+    {
+      int *elems = dfa->eclosures[src].elems;
+      int idx;
+      for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx)
+	{
+	  ret = re_node_set_insert_last (dfa->inveclosures + elems[idx], src);
+	  if (BE (ret == -1, 0))
+	    return REG_ESPACE;
+	}
+    }
+
+  return REG_NOERROR;
+}
+
+/* Calculate "eclosure" for all the node in DFA.  */
+
+static reg_errcode_t
+calc_eclosure (re_dfa_t *dfa)
+{
+  size_t node_idx;
+  int incomplete;
+#ifdef DEBUG
+  assert (dfa->nodes_len > 0);
+#endif
+  incomplete = 0;
+  /* For each nodes, calculate epsilon closure.  */
+  for (node_idx = 0; ; ++node_idx)
+    {
+      reg_errcode_t err;
+      re_node_set eclosure_elem;
+      if (node_idx == dfa->nodes_len)
+	{
+	  if (!incomplete)
+	    break;
+	  incomplete = 0;
+	  node_idx = 0;
+	}
+
+#ifdef DEBUG
+      assert (dfa->eclosures[node_idx].nelem != -1);
+#endif
+
+      /* If we have already calculated, skip it.  */
+      if (dfa->eclosures[node_idx].nelem != 0)
+	continue;
+      /* Calculate epsilon closure of `node_idx'.  */
+      err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, 1);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+
+      if (dfa->eclosures[node_idx].nelem == 0)
+	{
+	  incomplete = 1;
+	  re_node_set_free (&eclosure_elem);
+	}
+    }
+  return REG_NOERROR;
+}
+
+/* Calculate epsilon closure of NODE.  */
+
+static reg_errcode_t
+calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, int node, int root)
+{
+  reg_errcode_t err;
+  int i;
+  re_node_set eclosure;
+  int ret;
+  int incomplete = 0;
+  err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+
+  /* This indicates that we are calculating this node now.
+     We reference this value to avoid infinite loop.  */
+  dfa->eclosures[node].nelem = -1;
+
+  /* If the current node has constraints, duplicate all nodes
+     since they must inherit the constraints.  */
+  if (dfa->nodes[node].constraint
+      && dfa->edests[node].nelem
+      && !dfa->nodes[dfa->edests[node].elems[0]].duplicated)
+    {
+      err = duplicate_node_closure (dfa, node, node, node,
+				    dfa->nodes[node].constraint);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+    }
+
+  /* Expand each epsilon destination nodes.  */
+  if (IS_EPSILON_NODE(dfa->nodes[node].type))
+    for (i = 0; i < dfa->edests[node].nelem; ++i)
+      {
+	re_node_set eclosure_elem;
+	int edest = dfa->edests[node].elems[i];
+	/* If calculating the epsilon closure of `edest' is in progress,
+	   return intermediate result.  */
+	if (dfa->eclosures[edest].nelem == -1)
+	  {
+	    incomplete = 1;
+	    continue;
+	  }
+	/* If we haven't calculated the epsilon closure of `edest' yet,
+	   calculate now. Otherwise use calculated epsilon closure.  */
+	if (dfa->eclosures[edest].nelem == 0)
+	  {
+	    err = calc_eclosure_iter (&eclosure_elem, dfa, edest, 0);
+	    if (BE (err != REG_NOERROR, 0))
+	      return err;
+	  }
+	else
+	  eclosure_elem = dfa->eclosures[edest];
+	/* Merge the epsilon closure of `edest'.  */
+	err = re_node_set_merge (&eclosure, &eclosure_elem);
+	if (BE (err != REG_NOERROR, 0))
+	  return err;
+	/* If the epsilon closure of `edest' is incomplete,
+	   the epsilon closure of this node is also incomplete.  */
+	if (dfa->eclosures[edest].nelem == 0)
+	  {
+	    incomplete = 1;
+	    re_node_set_free (&eclosure_elem);
+	  }
+      }
+
+  /* An epsilon closure includes itself.  */
+  ret = re_node_set_insert (&eclosure, node);
+  if (BE (ret < 0, 0))
+    return REG_ESPACE;
+  if (incomplete && !root)
+    dfa->eclosures[node].nelem = 0;
+  else
+    dfa->eclosures[node] = eclosure;
+  *new_set = eclosure;
+  return REG_NOERROR;
+}
+
+/* Functions for token which are used in the parser.  */
+
+/* Fetch a token from INPUT.
+   We must not use this function inside bracket expressions.  */
+
+static void
+internal_function
+fetch_token (re_token_t *result, re_string_t *input, reg_syntax_t syntax)
+{
+  re_string_skip_bytes (input, peek_token (result, input, syntax));
+}
+
+/* Peek a token from INPUT, and return the length of the token.
+   We must not use this function inside bracket expressions.  */
+
+static int
+internal_function
+peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
+{
+  unsigned char c;
+
+  if (re_string_eoi (input))
+    {
+      token->type = END_OF_RE;
+      return 0;
+    }
+
+  c = re_string_peek_byte (input, 0);
+  token->opr.c = c;
+
+  token->word_char = 0;
+#ifdef RE_ENABLE_I18N
+  token->mb_partial = 0;
+  if (input->mb_cur_max > 1 &&
+      !re_string_first_byte (input, re_string_cur_idx (input)))
+    {
+      token->type = CHARACTER;
+      token->mb_partial = 1;
+      return 1;
+    }
+#endif
+  if (c == '\\')
+    {
+      unsigned char c2;
+      if (re_string_cur_idx (input) + 1 >= re_string_length (input))
+	{
+	  token->type = BACK_SLASH;
+	  return 1;
+	}
+
+      c2 = re_string_peek_byte_case (input, 1);
+      token->opr.c = c2;
+      token->type = CHARACTER;
+#ifdef RE_ENABLE_I18N
+      if (input->mb_cur_max > 1)
+	{
+	  wint_t wc = re_string_wchar_at (input,
+					  re_string_cur_idx (input) + 1);
+	  token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
+	}
+      else
+#endif
+	token->word_char = IS_WORD_CHAR (c2) != 0;
+
+      switch (c2)
+	{
+	case '|':
+	  if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_NO_BK_VBAR))
+	    token->type = OP_ALT;
+	  break;
+	case '1': case '2': case '3': case '4': case '5':
+	case '6': case '7': case '8': case '9':
+	  if (!(syntax & RE_NO_BK_REFS))
+	    {
+	      token->type = OP_BACK_REF;
+	      token->opr.idx = c2 - '1';
+	    }
+	  break;
+	case '<':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    {
+	      token->type = ANCHOR;
+	      token->opr.ctx_type = WORD_FIRST;
+	    }
+	  break;
+	case '>':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    {
+	      token->type = ANCHOR;
+	      token->opr.ctx_type = WORD_LAST;
+	    }
+	  break;
+	case 'b':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    {
+	      token->type = ANCHOR;
+	      token->opr.ctx_type = WORD_DELIM;
+	    }
+	  break;
+	case 'B':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    {
+	      token->type = ANCHOR;
+	      token->opr.ctx_type = NOT_WORD_DELIM;
+	    }
+	  break;
+	case 'w':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    token->type = OP_WORD;
+	  break;
+	case 'W':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    token->type = OP_NOTWORD;
+	  break;
+	case 's':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    token->type = OP_SPACE;
+	  break;
+	case 'S':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    token->type = OP_NOTSPACE;
+	  break;
+	case '`':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    {
+	      token->type = ANCHOR;
+	      token->opr.ctx_type = BUF_FIRST;
+	    }
+	  break;
+	case '\'':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    {
+	      token->type = ANCHOR;
+	      token->opr.ctx_type = BUF_LAST;
+	    }
+	  break;
+	case '(':
+	  if (!(syntax & RE_NO_BK_PARENS))
+	    token->type = OP_OPEN_SUBEXP;
+	  break;
+	case ')':
+	  if (!(syntax & RE_NO_BK_PARENS))
+	    token->type = OP_CLOSE_SUBEXP;
+	  break;
+	case '+':
+	  if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))
+	    token->type = OP_DUP_PLUS;
+	  break;
+	case '?':
+	  if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))
+	    token->type = OP_DUP_QUESTION;
+	  break;
+	case '{':
+	  if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))
+	    token->type = OP_OPEN_DUP_NUM;
+	  break;
+	case '}':
+	  if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))
+	    token->type = OP_CLOSE_DUP_NUM;
+	  break;
+	default:
+	  break;
+	}
+      return 2;
+    }
+
+  token->type = CHARACTER;
+#ifdef RE_ENABLE_I18N
+  if (input->mb_cur_max > 1)
+    {
+      wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input));
+      token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
+    }
+  else
+#endif
+    token->word_char = IS_WORD_CHAR (token->opr.c);
+
+  switch (c)
+    {
+    case '\n':
+      if (syntax & RE_NEWLINE_ALT)
+	token->type = OP_ALT;
+      break;
+    case '|':
+      if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_NO_BK_VBAR))
+	token->type = OP_ALT;
+      break;
+    case '*':
+      token->type = OP_DUP_ASTERISK;
+      break;
+    case '+':
+      if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))
+	token->type = OP_DUP_PLUS;
+      break;
+    case '?':
+      if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))
+	token->type = OP_DUP_QUESTION;
+      break;
+    case '{':
+      if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+	token->type = OP_OPEN_DUP_NUM;
+      break;
+    case '}':
+      if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+	token->type = OP_CLOSE_DUP_NUM;
+      break;
+    case '(':
+      if (syntax & RE_NO_BK_PARENS)
+	token->type = OP_OPEN_SUBEXP;
+      break;
+    case ')':
+      if (syntax & RE_NO_BK_PARENS)
+	token->type = OP_CLOSE_SUBEXP;
+      break;
+    case '[':
+      token->type = OP_OPEN_BRACKET;
+      break;
+    case '.':
+      token->type = OP_PERIOD;
+      break;
+    case '^':
+      if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE)) &&
+	  re_string_cur_idx (input) != 0)
+	{
+	  char prev = re_string_peek_byte (input, -1);
+	  if (!(syntax & RE_NEWLINE_ALT) || prev != '\n')
+	    break;
+	}
+      token->type = ANCHOR;
+      token->opr.ctx_type = LINE_FIRST;
+      break;
+    case '$':
+      if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) &&
+	  re_string_cur_idx (input) + 1 != re_string_length (input))
+	{
+	  re_token_t next;
+	  re_string_skip_bytes (input, 1);
+	  peek_token (&next, input, syntax);
+	  re_string_skip_bytes (input, -1);
+	  if (next.type != OP_ALT && next.type != OP_CLOSE_SUBEXP)
+	    break;
+	}
+      token->type = ANCHOR;
+      token->opr.ctx_type = LINE_LAST;
+      break;
+    default:
+      break;
+    }
+  return 1;
+}
+
+/* Peek a token from INPUT, and return the length of the token.
+   We must not use this function out of bracket expressions.  */
+
+static int
+internal_function
+peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
+{
+  unsigned char c;
+  if (re_string_eoi (input))
+    {
+      token->type = END_OF_RE;
+      return 0;
+    }
+  c = re_string_peek_byte (input, 0);
+  token->opr.c = c;
+
+#ifdef RE_ENABLE_I18N
+  if (input->mb_cur_max > 1 &&
+      !re_string_first_byte (input, re_string_cur_idx (input)))
+    {
+      token->type = CHARACTER;
+      return 1;
+    }
+#endif /* RE_ENABLE_I18N */
+
+  if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS)
+      && re_string_cur_idx (input) + 1 < re_string_length (input))
+    {
+      /* In this case, '\' escape a character.  */
+      unsigned char c2;
+      re_string_skip_bytes (input, 1);
+      c2 = re_string_peek_byte (input, 0);
+      token->opr.c = c2;
+      token->type = CHARACTER;
+      return 1;
+    }
+  if (c == '[') /* '[' is a special char in a bracket exps.  */
+    {
+      unsigned char c2;
+      int token_len;
+      if (re_string_cur_idx (input) + 1 < re_string_length (input))
+	c2 = re_string_peek_byte (input, 1);
+      else
+	c2 = 0;
+      token->opr.c = c2;
+      token_len = 2;
+      switch (c2)
+	{
+	case '.':
+	  token->type = OP_OPEN_COLL_ELEM;
+	  break;
+	case '=':
+	  token->type = OP_OPEN_EQUIV_CLASS;
+	  break;
+	case ':':
+	  if (syntax & RE_CHAR_CLASSES)
+	    {
+	      token->type = OP_OPEN_CHAR_CLASS;
+	      break;
+	    }
+	  /* else fall through.  */
+	default:
+	  token->type = CHARACTER;
+	  token->opr.c = c;
+	  token_len = 1;
+	  break;
+	}
+      return token_len;
+    }
+  switch (c)
+    {
+    case '-':
+      token->type = OP_CHARSET_RANGE;
+      break;
+    case ']':
+      token->type = OP_CLOSE_BRACKET;
+      break;
+    case '^':
+      token->type = OP_NON_MATCH_LIST;
+      break;
+    default:
+      token->type = CHARACTER;
+    }
+  return 1;
+}
+
+/* Functions for parser.  */
+
+/* Entry point of the parser.
+   Parse the regular expression REGEXP and return the structure tree.
+   If an error is occured, ERR is set by error code, and return NULL.
+   This function build the following tree, from regular expression <reg_exp>:
+	   CAT
+	   / \
+	  /   \
+   <reg_exp>  EOR
+
+   CAT means concatenation.
+   EOR means end of regular expression.  */
+
+static bin_tree_t *
+parse (re_string_t *regexp, regex_t *preg, reg_syntax_t syntax,
+       reg_errcode_t *err)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_t *tree, *eor, *root;
+  re_token_t current_token;
+  dfa->syntax = syntax;
+  fetch_token (&current_token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+  tree = parse_reg_exp (regexp, preg, &current_token, syntax, 0, err);
+  if (BE (*err != REG_NOERROR && tree == NULL, 0))
+    return NULL;
+  eor = create_tree (dfa, NULL, NULL, END_OF_RE);
+  if (tree != NULL)
+    root = create_tree (dfa, tree, eor, CONCAT);
+  else
+    root = eor;
+  if (BE (eor == NULL || root == NULL, 0))
+    {
+      *err = REG_ESPACE;
+      return NULL;
+    }
+  return root;
+}
+
+/* This function build the following tree, from regular expression
+   <branch1>|<branch2>:
+	   ALT
+	   / \
+	  /   \
+   <branch1> <branch2>
+
+   ALT means alternative, which represents the operator `|'.  */
+
+static bin_tree_t *
+parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
+	       reg_syntax_t syntax, int nest, reg_errcode_t *err)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_t *tree, *branch = NULL;
+  tree = parse_branch (regexp, preg, token, syntax, nest, err);
+  if (BE (*err != REG_NOERROR && tree == NULL, 0))
+    return NULL;
+
+  while (token->type == OP_ALT)
+    {
+      fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+      if (token->type != OP_ALT && token->type != END_OF_RE
+	  && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
+	{
+	  branch = parse_branch (regexp, preg, token, syntax, nest, err);
+	  if (BE (*err != REG_NOERROR && branch == NULL, 0))
+	    return NULL;
+	}
+      else
+	branch = NULL;
+      tree = create_tree (dfa, tree, branch, OP_ALT);
+      if (BE (tree == NULL, 0))
+	{
+	  *err = REG_ESPACE;
+	  return NULL;
+	}
+    }
+  return tree;
+}
+
+/* This function build the following tree, from regular expression
+   <exp1><exp2>:
+	CAT
+	/ \
+       /   \
+   <exp1> <exp2>
+
+   CAT means concatenation.  */
+
+static bin_tree_t *
+parse_branch (re_string_t *regexp, regex_t *preg, re_token_t *token,
+	      reg_syntax_t syntax, int nest, reg_errcode_t *err)
+{
+  bin_tree_t *tree, *exp;
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  tree = parse_expression (regexp, preg, token, syntax, nest, err);
+  if (BE (*err != REG_NOERROR && tree == NULL, 0))
+    return NULL;
+
+  while (token->type != OP_ALT && token->type != END_OF_RE
+	 && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
+    {
+      exp = parse_expression (regexp, preg, token, syntax, nest, err);
+      if (BE (*err != REG_NOERROR && exp == NULL, 0))
+	{
+	  return NULL;
+	}
+      if (tree != NULL && exp != NULL)
+	{
+	  tree = create_tree (dfa, tree, exp, CONCAT);
+	  if (tree == NULL)
+	    {
+	      *err = REG_ESPACE;
+	      return NULL;
+	    }
+	}
+      else if (tree == NULL)
+	tree = exp;
+      /* Otherwise exp == NULL, we don't need to create new tree.  */
+    }
+  return tree;
+}
+
+/* This function build the following tree, from regular expression a*:
+	 *
+	 |
+	 a
+*/
+
+static bin_tree_t *
+parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
+		  reg_syntax_t syntax, int nest, reg_errcode_t *err)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_t *tree;
+  switch (token->type)
+    {
+    case CHARACTER:
+      tree = create_token_tree (dfa, NULL, NULL, token);
+      if (BE (tree == NULL, 0))
+	{
+	  *err = REG_ESPACE;
+	  return NULL;
+	}
+#ifdef RE_ENABLE_I18N
+      if (dfa->mb_cur_max > 1)
+	{
+	  while (!re_string_eoi (regexp)
+		 && !re_string_first_byte (regexp, re_string_cur_idx (regexp)))
+	    {
+	      bin_tree_t *mbc_remain;
+	      fetch_token (token, regexp, syntax);
+	      mbc_remain = create_token_tree (dfa, NULL, NULL, token);
+	      tree = create_tree (dfa, tree, mbc_remain, CONCAT);
+	      if (BE (mbc_remain == NULL || tree == NULL, 0))
+		{
+		  *err = REG_ESPACE;
+		  return NULL;
+		}
+	    }
+	}
+#endif
+      break;
+    case OP_OPEN_SUBEXP:
+      tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err);
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+	return NULL;
+      break;
+    case OP_OPEN_BRACKET:
+      tree = parse_bracket_exp (regexp, dfa, token, syntax, err);
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+	return NULL;
+      break;
+    case OP_BACK_REF:
+      if (!BE (dfa->completed_bkref_map & (1 << token->opr.idx), 1))
+	{
+	  *err = REG_ESUBREG;
+	  return NULL;
+	}
+      dfa->used_bkref_map |= 1 << token->opr.idx;
+      tree = create_token_tree (dfa, NULL, NULL, token);
+      if (BE (tree == NULL, 0))
+	{
+	  *err = REG_ESPACE;
+	  return NULL;
+	}
+      ++dfa->nbackref;
+      dfa->has_mb_node = 1;
+      break;
+    case OP_OPEN_DUP_NUM:
+      if (syntax & RE_CONTEXT_INVALID_DUP)
+	{
+	  *err = REG_BADRPT;
+	  return NULL;
+	}
+      /* FALLTHROUGH */
+    case OP_DUP_ASTERISK:
+    case OP_DUP_PLUS:
+    case OP_DUP_QUESTION:
+      if (syntax & RE_CONTEXT_INVALID_OPS)
+	{
+	  *err = REG_BADRPT;
+	  return NULL;
+	}
+      else if (syntax & RE_CONTEXT_INDEP_OPS)
+	{
+	  fetch_token (token, regexp, syntax);
+	  return parse_expression (regexp, preg, token, syntax, nest, err);
+	}
+      /* else fall through  */
+    case OP_CLOSE_SUBEXP:
+      if ((token->type == OP_CLOSE_SUBEXP) &&
+	  !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD))
+	{
+	  *err = REG_ERPAREN;
+	  return NULL;
+	}
+      /* else fall through  */
+    case OP_CLOSE_DUP_NUM:
+      /* We treat it as a normal character.  */
+
+      /* Then we can these characters as normal characters.  */
+      token->type = CHARACTER;
+      /* mb_partial and word_char bits should be initialized already
+	 by peek_token.  */
+      tree = create_token_tree (dfa, NULL, NULL, token);
+      if (BE (tree == NULL, 0))
+	{
+	  *err = REG_ESPACE;
+	  return NULL;
+	}
+      break;
+    case ANCHOR:
+      if ((token->opr.ctx_type
+	   & (WORD_DELIM | NOT_WORD_DELIM | WORD_FIRST | WORD_LAST))
+	  && dfa->word_ops_used == 0)
+	init_word_char (dfa);
+      if (token->opr.ctx_type == WORD_DELIM
+	  || token->opr.ctx_type == NOT_WORD_DELIM)
+	{
+	  bin_tree_t *tree_first, *tree_last;
+	  if (token->opr.ctx_type == WORD_DELIM)
+	    {
+	      token->opr.ctx_type = WORD_FIRST;
+	      tree_first = create_token_tree (dfa, NULL, NULL, token);
+	      token->opr.ctx_type = WORD_LAST;
+	    }
+	  else
+	    {
+	      token->opr.ctx_type = INSIDE_WORD;
+	      tree_first = create_token_tree (dfa, NULL, NULL, token);
+	      token->opr.ctx_type = INSIDE_NOTWORD;
+	    }
+	  tree_last = create_token_tree (dfa, NULL, NULL, token);
+	  tree = create_tree (dfa, tree_first, tree_last, OP_ALT);
+	  if (BE (tree_first == NULL || tree_last == NULL || tree == NULL, 0))
+	    {
+	      *err = REG_ESPACE;
+	      return NULL;
+	    }
+	}
+      else
+	{
+	  tree = create_token_tree (dfa, NULL, NULL, token);
+	  if (BE (tree == NULL, 0))
+	    {
+	      *err = REG_ESPACE;
+	      return NULL;
+	    }
+	}
+      /* We must return here, since ANCHORs can't be followed
+	 by repetition operators.
+	 eg. RE"^*" is invalid or "<ANCHOR(^)><CHAR(*)>",
+	     it must not be "<ANCHOR(^)><REPEAT(*)>".  */
+      fetch_token (token, regexp, syntax);
+      return tree;
+    case OP_PERIOD:
+      tree = create_token_tree (dfa, NULL, NULL, token);
+      if (BE (tree == NULL, 0))
+	{
+	  *err = REG_ESPACE;
+	  return NULL;
+	}
+      if (dfa->mb_cur_max > 1)
+	dfa->has_mb_node = 1;
+      break;
+    case OP_WORD:
+    case OP_NOTWORD:
+      tree = build_charclass_op (dfa, regexp->trans,
+				 "alnum",
+				 "_",
+				 token->type == OP_NOTWORD, err);
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+	return NULL;
+      break;
+    case OP_SPACE:
+    case OP_NOTSPACE:
+      tree = build_charclass_op (dfa, regexp->trans,
+				 "space",
+				 "",
+				 token->type == OP_NOTSPACE, err);
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+	return NULL;
+      break;
+    case OP_ALT:
+    case END_OF_RE:
+      return NULL;
+    case BACK_SLASH:
+      *err = REG_EESCAPE;
+      return NULL;
+    default:
+      /* Must not happen?  */
+#ifdef DEBUG
+      assert (0);
+#endif
+      return NULL;
+    }
+  fetch_token (token, regexp, syntax);
+
+  while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS
+	 || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)
+    {
+      tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+	return NULL;
+      /* In BRE consecutive duplications are not allowed.  */
+      if ((syntax & RE_CONTEXT_INVALID_DUP)
+	  && (token->type == OP_DUP_ASTERISK
+	      || token->type == OP_OPEN_DUP_NUM))
+	{
+	  *err = REG_BADRPT;
+	  return NULL;
+	}
+    }
+
+  return tree;
+}
+
+/* This function build the following tree, from regular expression
+   (<reg_exp>):
+	 SUBEXP
+	    |
+	<reg_exp>
+*/
+
+static bin_tree_t *
+parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
+	       reg_syntax_t syntax, int nest, reg_errcode_t *err)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_t *tree;
+  size_t cur_nsub;
+  cur_nsub = preg->re_nsub++;
+
+  fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+
+  /* The subexpression may be a null string.  */
+  if (token->type == OP_CLOSE_SUBEXP)
+    tree = NULL;
+  else
+    {
+      tree = parse_reg_exp (regexp, preg, token, syntax, nest, err);
+      if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0))
+	*err = REG_EPAREN;
+      if (BE (*err != REG_NOERROR, 0))
+	return NULL;
+    }
+
+  if (cur_nsub <= '9' - '1')
+    dfa->completed_bkref_map |= 1 << cur_nsub;
+
+  tree = create_tree (dfa, tree, NULL, SUBEXP);
+  if (BE (tree == NULL, 0))
+    {
+      *err = REG_ESPACE;
+      return NULL;
+    }
+  tree->token.opr.idx = cur_nsub;
+  return tree;
+}
+
+/* This function parse repetition operators like "*", "+", "{1,3}" etc.  */
+
+static bin_tree_t *
+parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
+	      re_token_t *token, reg_syntax_t syntax, reg_errcode_t *err)
+{
+  bin_tree_t *tree = NULL, *old_tree = NULL;
+  int i, start, end, start_idx = re_string_cur_idx (regexp);
+#ifndef RE_TOKEN_INIT_BUG
+  re_token_t start_token = *token;
+#else
+  re_token_t start_token;
+
+  memcpy ((void *) &start_token, (void *) token, sizeof start_token);
+#endif
+
+  if (token->type == OP_OPEN_DUP_NUM)
+    {
+      end = 0;
+      start = fetch_number (regexp, token, syntax);
+      if (start == -1)
+	{
+	  if (token->type == CHARACTER && token->opr.c == ',')
+	    start = 0; /* We treat "{,m}" as "{0,m}".  */
+	  else
+	    {
+	      *err = REG_BADBR; /* <re>{} is invalid.  */
+	      return NULL;
+	    }
+	}
+      if (BE (start != -2, 1))
+	{
+	  /* We treat "{n}" as "{n,n}".  */
+	  end = ((token->type == OP_CLOSE_DUP_NUM) ? start
+		 : ((token->type == CHARACTER && token->opr.c == ',')
+		    ? fetch_number (regexp, token, syntax) : -2));
+	}
+      if (BE (start == -2 || end == -2, 0))
+	{
+	  /* Invalid sequence.  */
+	  if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0))
+	    {
+	      if (token->type == END_OF_RE)
+		*err = REG_EBRACE;
+	      else
+		*err = REG_BADBR;
+
+	      return NULL;
+	    }
+
+	  /* If the syntax bit is set, rollback.  */
+	  re_string_set_index (regexp, start_idx);
+	  *token = start_token;
+	  token->type = CHARACTER;
+	  /* mb_partial and word_char bits should be already initialized by
+	     peek_token.  */
+	  return elem;
+	}
+
+      if (BE ((end != -1 && start > end) || token->type != OP_CLOSE_DUP_NUM, 0))
+	{
+	  /* First number greater than second.  */
+	  *err = REG_BADBR;
+	  return NULL;
+	}
+    }
+  else
+    {
+      start = (token->type == OP_DUP_PLUS) ? 1 : 0;
+      end = (token->type == OP_DUP_QUESTION) ? 1 : -1;
+    }
+
+  fetch_token (token, regexp, syntax);
+
+  if (BE (elem == NULL, 0))
+    return NULL;
+  if (BE (start == 0 && end == 0, 0))
+    {
+      postorder (elem, free_tree, NULL);
+      return NULL;
+    }
+
+  /* Extract "<re>{n,m}" to "<re><re>...<re><re>{0,<m-n>}".  */
+  if (BE (start > 0, 0))
+    {
+      tree = elem;
+      for (i = 2; i <= start; ++i)
+	{
+	  elem = duplicate_tree (elem, dfa);
+	  tree = create_tree (dfa, tree, elem, CONCAT);
+	  if (BE (elem == NULL || tree == NULL, 0))
+	    goto parse_dup_op_espace;
+	}
+
+      if (start == end)
+	return tree;
+
+      /* Duplicate ELEM before it is marked optional.  */
+      elem = duplicate_tree (elem, dfa);
+      old_tree = tree;
+    }
+  else
+    old_tree = NULL;
+
+  if (elem->token.type == SUBEXP)
+    postorder (elem, mark_opt_subexp, (void *) (long) elem->token.opr.idx);
+
+  tree = create_tree (dfa, elem, NULL, (end == -1 ? OP_DUP_ASTERISK : OP_ALT));
+  if (BE (tree == NULL, 0))
+    goto parse_dup_op_espace;
+
+  /* This loop is actually executed only when end != -1,
+     to rewrite <re>{0,n} as (<re>(<re>...<re>?)?)?...  We have
+     already created the start+1-th copy.  */
+  for (i = start + 2; i <= end; ++i)
+    {
+      elem = duplicate_tree (elem, dfa);
+      tree = create_tree (dfa, tree, elem, CONCAT);
+      if (BE (elem == NULL || tree == NULL, 0))
+	goto parse_dup_op_espace;
+
+      tree = create_tree (dfa, tree, NULL, OP_ALT);
+      if (BE (tree == NULL, 0))
+	goto parse_dup_op_espace;
+    }
+
+  if (old_tree)
+    tree = create_tree (dfa, old_tree, tree, CONCAT);
+
+  return tree;
+
+ parse_dup_op_espace:
+  *err = REG_ESPACE;
+  return NULL;
+}
+
+/* Size of the names for collating symbol/equivalence_class/character_class.
+   I'm not sure, but maybe enough.  */
+#define BRACKET_NAME_BUF_SIZE 32
+
+#ifndef _LIBC
+  /* Local function for parse_bracket_exp only used in case of NOT _LIBC.
+     Build the range expression which starts from START_ELEM, and ends
+     at END_ELEM.  The result are written to MBCSET and SBCSET.
+     RANGE_ALLOC is the allocated size of mbcset->range_starts, and
+     mbcset->range_ends, is a pointer argument sinse we may
+     update it.  */
+
+static reg_errcode_t
+internal_function
+# ifdef RE_ENABLE_I18N
+build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc,
+		 bracket_elem_t *start_elem, bracket_elem_t *end_elem)
+# else /* not RE_ENABLE_I18N */
+build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem,
+		 bracket_elem_t *end_elem)
+# endif /* not RE_ENABLE_I18N */
+{
+  unsigned int start_ch, end_ch;
+  /* Equivalence Classes and Character Classes can't be a range start/end.  */
+  if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
+	  || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
+	  0))
+    return REG_ERANGE;
+
+  /* We can handle no multi character collating elements without libc
+     support.  */
+  if (BE ((start_elem->type == COLL_SYM
+	   && strlen ((char *) start_elem->opr.name) > 1)
+	  || (end_elem->type == COLL_SYM
+	      && strlen ((char *) end_elem->opr.name) > 1), 0))
+    return REG_ECOLLATE;
+
+# ifdef RE_ENABLE_I18N
+  {
+    wchar_t wc;
+    wint_t start_wc;
+    wint_t end_wc;
+    wchar_t cmp_buf[6] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'};
+
+    start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch
+		: ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
+		   : 0));
+    end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch
+	      : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
+		 : 0));
+#ifdef GAWK
+    /*
+     * Fedora Core 2, maybe others, have broken `btowc' that returns -1
+     * for any value > 127. Sigh. Note that `start_ch' and `end_ch' are
+     * unsigned, so we don't have sign extension problems.
+     */
+    start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM)
+		? start_ch : start_elem->opr.wch);
+    end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM)
+	      ? end_ch : end_elem->opr.wch);
+#else
+    start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM)
+		? __btowc (start_ch) : start_elem->opr.wch);
+    end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM)
+	      ? __btowc (end_ch) : end_elem->opr.wch);
+#endif
+    if (start_wc == WEOF || end_wc == WEOF)
+      return REG_ECOLLATE;
+    cmp_buf[0] = start_wc;
+    cmp_buf[4] = end_wc;
+    if (wcscoll (cmp_buf, cmp_buf + 4) > 0)
+      return REG_ERANGE;
+
+    /* Got valid collation sequence values, add them as a new entry.
+       However, for !_LIBC we have no collation elements: if the
+       character set is single byte, the single byte character set
+       that we build below suffices.  parse_bracket_exp passes
+       no MBCSET if dfa->mb_cur_max == 1.  */
+    if (mbcset)
+      {
+	/* Check the space of the arrays.  */
+	if (BE (*range_alloc == mbcset->nranges, 0))
+	  {
+	    /* There is not enough space, need realloc.  */
+	    wchar_t *new_array_start, *new_array_end;
+	    int new_nranges;
+
+	    /* +1 in case of mbcset->nranges is 0.  */
+	    new_nranges = 2 * mbcset->nranges + 1;
+	    /* Use realloc since mbcset->range_starts and mbcset->range_ends
+	       are NULL if *range_alloc == 0.  */
+	    new_array_start = re_realloc (mbcset->range_starts, wchar_t,
+					  new_nranges);
+	    new_array_end = re_realloc (mbcset->range_ends, wchar_t,
+					new_nranges);
+
+	    if (BE (new_array_start == NULL || new_array_end == NULL, 0))
+	      return REG_ESPACE;
+
+	    mbcset->range_starts = new_array_start;
+	    mbcset->range_ends = new_array_end;
+	    *range_alloc = new_nranges;
+	  }
+
+	mbcset->range_starts[mbcset->nranges] = start_wc;
+	mbcset->range_ends[mbcset->nranges++] = end_wc;
+      }
+
+    /* Build the table for single byte characters.  */
+    for (wc = 0; wc < SBC_MAX; ++wc)
+      {
+	cmp_buf[2] = wc;
+	if (wcscoll (cmp_buf, cmp_buf + 2) <= 0
+	    && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0)
+	  bitset_set (sbcset, wc);
+      }
+  }
+# else /* not RE_ENABLE_I18N */
+  {
+    unsigned int ch;
+    start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch
+		: ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
+		   : 0));
+    end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch
+	      : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
+		 : 0));
+    if (start_ch > end_ch)
+      return REG_ERANGE;
+    /* Build the table for single byte characters.  */
+    for (ch = 0; ch < SBC_MAX; ++ch)
+      if (start_ch <= ch  && ch <= end_ch)
+	bitset_set (sbcset, ch);
+  }
+# endif /* not RE_ENABLE_I18N */
+  return REG_NOERROR;
+}
+#endif /* not _LIBC */
+
+#ifndef _LIBC
+/* Helper function for parse_bracket_exp only used in case of NOT _LIBC..
+   Build the collating element which is represented by NAME.
+   The result are written to MBCSET and SBCSET.
+   COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
+   pointer argument since we may update it.  */
+
+static reg_errcode_t
+internal_function
+# ifdef RE_ENABLE_I18N
+build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset,
+			int *coll_sym_alloc, const unsigned char *name)
+# else /* not RE_ENABLE_I18N */
+build_collating_symbol (bitset_t sbcset, const unsigned char *name)
+# endif /* not RE_ENABLE_I18N */
+{
+  size_t name_len = strlen ((const char *) name);
+  if (BE (name_len != 1, 0))
+    return REG_ECOLLATE;
+  else
+    {
+      bitset_set (sbcset, name[0]);
+      return REG_NOERROR;
+    }
+}
+#endif /* not _LIBC */
+
+/* This function parse bracket expression like "[abc]", "[a-c]",
+   "[[.a-a.]]" etc.  */
+
+static bin_tree_t *
+parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+		   reg_syntax_t syntax, reg_errcode_t *err)
+{
+#ifdef _LIBC
+  const unsigned char *collseqmb;
+  const char *collseqwc;
+  uint32_t nrules;
+  int32_t table_size;
+  const int32_t *symb_table;
+  const unsigned char *extra;
+
+  /* Local function for parse_bracket_exp used in _LIBC environement.
+     Seek the collating symbol entry correspondings to NAME.
+     Return the index of the symbol in the SYMB_TABLE.  */
+
+  auto inline int32_t
+  __attribute ((always_inline))
+  seek_collating_symbol_entry (name, name_len)
+	 const unsigned char *name;
+	 size_t name_len;
+    {
+      int32_t hash = elem_hash ((const char *) name, name_len);
+      int32_t elem = hash % table_size;
+      if (symb_table[2 * elem] != 0)
+	{
+	  int32_t second = hash % (table_size - 2) + 1;
+
+	  do
+	    {
+	      /* First compare the hashing value.  */
+	      if (symb_table[2 * elem] == hash
+		  /* Compare the length of the name.  */
+		  && name_len == extra[symb_table[2 * elem + 1]]
+		  /* Compare the name.  */
+		  && memcmp (name, &extra[symb_table[2 * elem + 1] + 1],
+			     name_len) == 0)
+		{
+		  /* Yep, this is the entry.  */
+		  break;
+		}
+
+	      /* Next entry.  */
+	      elem += second;
+	    }
+	  while (symb_table[2 * elem] != 0);
+	}
+      return elem;
+    }
+
+  /* Local function for parse_bracket_exp used in _LIBC environment.
+     Look up the collation sequence value of BR_ELEM.
+     Return the value if succeeded, UINT_MAX otherwise.  */
+
+  auto inline unsigned int
+  __attribute ((always_inline))
+  lookup_collation_sequence_value (br_elem)
+	 bracket_elem_t *br_elem;
+    {
+      if (br_elem->type == SB_CHAR)
+	{
+	  /*
+	  if (MB_CUR_MAX == 1)
+	  */
+	  if (nrules == 0)
+	    return collseqmb[br_elem->opr.ch];
+	  else
+	    {
+	      wint_t wc = __btowc (br_elem->opr.ch);
+	      return __collseq_table_lookup (collseqwc, wc);
+	    }
+	}
+      else if (br_elem->type == MB_CHAR)
+	{
+	  if (nrules != 0)
+	    return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
+	}
+      else if (br_elem->type == COLL_SYM)
+	{
+	  size_t sym_name_len = strlen ((char *) br_elem->opr.name);
+	  if (nrules != 0)
+	    {
+	      int32_t elem, idx;
+	      elem = seek_collating_symbol_entry (br_elem->opr.name,
+						  sym_name_len);
+	      if (symb_table[2 * elem] != 0)
+		{
+		  /* We found the entry.  */
+		  idx = symb_table[2 * elem + 1];
+		  /* Skip the name of collating element name.  */
+		  idx += 1 + extra[idx];
+		  /* Skip the byte sequence of the collating element.  */
+		  idx += 1 + extra[idx];
+		  /* Adjust for the alignment.  */
+		  idx = (idx + 3) & ~3;
+		  /* Skip the multibyte collation sequence value.  */
+		  idx += sizeof (unsigned int);
+		  /* Skip the wide char sequence of the collating element.  */
+		  idx += sizeof (unsigned int) *
+		    (1 + *(unsigned int *) (extra + idx));
+		  /* Return the collation sequence value.  */
+		  return *(unsigned int *) (extra + idx);
+		}
+	      else if (symb_table[2 * elem] == 0 && sym_name_len == 1)
+		{
+		  /* No valid character.  Match it as a single byte
+		     character.  */
+		  return collseqmb[br_elem->opr.name[0]];
+		}
+	    }
+	  else if (sym_name_len == 1)
+	    return collseqmb[br_elem->opr.name[0]];
+	}
+      return UINT_MAX;
+    }
+
+  /* Local function for parse_bracket_exp used in _LIBC environement.
+     Build the range expression which starts from START_ELEM, and ends
+     at END_ELEM.  The result are written to MBCSET and SBCSET.
+     RANGE_ALLOC is the allocated size of mbcset->range_starts, and
+     mbcset->range_ends, is a pointer argument sinse we may
+     update it.  */
+
+  auto inline reg_errcode_t
+  __attribute ((always_inline))
+  build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem)
+	 re_charset_t *mbcset;
+	 int *range_alloc;
+	 bitset_t sbcset;
+	 bracket_elem_t *start_elem, *end_elem;
+    {
+      unsigned int ch;
+      uint32_t start_collseq;
+      uint32_t end_collseq;
+
+      /* Equivalence Classes and Character Classes can't be a range
+	 start/end.  */
+      if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
+	      || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
+	      0))
+	return REG_ERANGE;
+
+      start_collseq = lookup_collation_sequence_value (start_elem);
+      end_collseq = lookup_collation_sequence_value (end_elem);
+      /* Check start/end collation sequence values.  */
+      if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0))
+	return REG_ECOLLATE;
+      if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0))
+	return REG_ERANGE;
+
+      /* Got valid collation sequence values, add them as a new entry.
+	 However, if we have no collation elements, and the character set
+	 is single byte, the single byte character set that we
+	 build below suffices. */
+      if (nrules > 0 || dfa->mb_cur_max > 1)
+	{
+	  /* Check the space of the arrays.  */
+	  if (BE (*range_alloc == mbcset->nranges, 0))
+	    {
+	      /* There is not enough space, need realloc.  */
+	      uint32_t *new_array_start;
+	      uint32_t *new_array_end;
+	      int new_nranges;
+
+	      /* +1 in case of mbcset->nranges is 0.  */
+	      new_nranges = 2 * mbcset->nranges + 1;
+	      new_array_start = re_realloc (mbcset->range_starts, uint32_t,
+					    new_nranges);
+	      new_array_end = re_realloc (mbcset->range_ends, uint32_t,
+					  new_nranges);
+
+	      if (BE (new_array_start == NULL || new_array_end == NULL, 0))
+		return REG_ESPACE;
+
+	      mbcset->range_starts = new_array_start;
+	      mbcset->range_ends = new_array_end;
+	      *range_alloc = new_nranges;
+	    }
+
+	  mbcset->range_starts[mbcset->nranges] = start_collseq;
+	  mbcset->range_ends[mbcset->nranges++] = end_collseq;
+	}
+
+      /* Build the table for single byte characters.  */
+      for (ch = 0; ch < SBC_MAX; ch++)
+	{
+	  uint32_t ch_collseq;
+	  /*
+	  if (MB_CUR_MAX == 1)
+	  */
+	  if (nrules == 0)
+	    ch_collseq = collseqmb[ch];
+	  else
+	    ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch));
+	  if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)
+	    bitset_set (sbcset, ch);
+	}
+      return REG_NOERROR;
+    }
+
+  /* Local function for parse_bracket_exp used in _LIBC environement.
+     Build the collating element which is represented by NAME.
+     The result are written to MBCSET and SBCSET.
+     COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
+     pointer argument sinse we may update it.  */
+
+  auto inline reg_errcode_t
+  __attribute ((always_inline))
+  build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name)
+	 re_charset_t *mbcset;
+	 int *coll_sym_alloc;
+	 bitset_t sbcset;
+	 const unsigned char *name;
+    {
+      int32_t elem, idx;
+      size_t name_len = strlen ((const char *) name);
+      if (nrules != 0)
+	{
+	  elem = seek_collating_symbol_entry (name, name_len);
+	  if (symb_table[2 * elem] != 0)
+	    {
+	      /* We found the entry.  */
+	      idx = symb_table[2 * elem + 1];
+	      /* Skip the name of collating element name.  */
+	      idx += 1 + extra[idx];
+	    }
+	  else if (symb_table[2 * elem] == 0 && name_len == 1)
+	    {
+	      /* No valid character, treat it as a normal
+		 character.  */
+	      bitset_set (sbcset, name[0]);
+	      return REG_NOERROR;
+	    }
+	  else
+	    return REG_ECOLLATE;
+
+	  /* Got valid collation sequence, add it as a new entry.  */
+	  /* Check the space of the arrays.  */
+	  if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0))
+	    {
+	      /* Not enough, realloc it.  */
+	      /* +1 in case of mbcset->ncoll_syms is 0.  */
+	      int new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1;
+	      /* Use realloc since mbcset->coll_syms is NULL
+		 if *alloc == 0.  */
+	      int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t,
+						   new_coll_sym_alloc);
+	      if (BE (new_coll_syms == NULL, 0))
+		return REG_ESPACE;
+	      mbcset->coll_syms = new_coll_syms;
+	      *coll_sym_alloc = new_coll_sym_alloc;
+	    }
+	  mbcset->coll_syms[mbcset->ncoll_syms++] = idx;
+	  return REG_NOERROR;
+	}
+      else
+	{
+	  if (BE (name_len != 1, 0))
+	    return REG_ECOLLATE;
+	  else
+	    {
+	      bitset_set (sbcset, name[0]);
+	      return REG_NOERROR;
+	    }
+	}
+    }
+#endif
+
+  re_token_t br_token;
+  re_bitset_ptr_t sbcset;
+#ifdef RE_ENABLE_I18N
+  re_charset_t *mbcset;
+  int coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;
+  int equiv_class_alloc = 0, char_class_alloc = 0;
+#endif /* not RE_ENABLE_I18N */
+  int non_match = 0;
+  bin_tree_t *work_tree;
+  int token_len;
+  int first_round = 1;
+#ifdef _LIBC
+  collseqmb = (const unsigned char *)
+    _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
+  nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+  if (nrules)
+    {
+      /*
+      if (MB_CUR_MAX > 1)
+      */
+      collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);
+      table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB);
+      symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE,
+						  _NL_COLLATE_SYMB_TABLEMB);
+      extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
+						   _NL_COLLATE_SYMB_EXTRAMB);
+    }
+#endif
+  sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
+#ifdef RE_ENABLE_I18N
+  mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
+#endif /* RE_ENABLE_I18N */
+#ifdef RE_ENABLE_I18N
+  if (BE (sbcset == NULL || mbcset == NULL, 0))
+#else
+  if (BE (sbcset == NULL, 0))
+#endif /* RE_ENABLE_I18N */
+    {
+      *err = REG_ESPACE;
+      return NULL;
+    }
+
+  token_len = peek_token_bracket (token, regexp, syntax);
+  if (BE (token->type == END_OF_RE, 0))
+    {
+      *err = REG_BADPAT;
+      goto parse_bracket_exp_free_return;
+    }
+  if (token->type == OP_NON_MATCH_LIST)
+    {
+#ifdef RE_ENABLE_I18N
+      mbcset->non_match = 1;
+#endif /* not RE_ENABLE_I18N */
+      non_match = 1;
+      if (syntax & RE_HAT_LISTS_NOT_NEWLINE)
+	bitset_set (sbcset, '\n');
+      re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
+      token_len = peek_token_bracket (token, regexp, syntax);
+      if (BE (token->type == END_OF_RE, 0))
+	{
+	  *err = REG_BADPAT;
+	  goto parse_bracket_exp_free_return;
+	}
+    }
+
+  /* We treat the first ']' as a normal character.  */
+  if (token->type == OP_CLOSE_BRACKET)
+    token->type = CHARACTER;
+
+  while (1)
+    {
+      bracket_elem_t start_elem, end_elem;
+      unsigned char start_name_buf[BRACKET_NAME_BUF_SIZE];
+      unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE];
+      reg_errcode_t ret;
+      int token_len2 = 0, is_range_exp = 0;
+      re_token_t token2;
+
+      start_elem.opr.name = start_name_buf;
+      ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa,
+				   syntax, first_round);
+      if (BE (ret != REG_NOERROR, 0))
+	{
+	  *err = ret;
+	  goto parse_bracket_exp_free_return;
+	}
+      first_round = 0;
+
+      /* Get information about the next token.  We need it in any case.  */
+      token_len = peek_token_bracket (token, regexp, syntax);
+
+      /* Do not check for ranges if we know they are not allowed.  */
+      if (start_elem.type != CHAR_CLASS && start_elem.type != EQUIV_CLASS)
+	{
+	  if (BE (token->type == END_OF_RE, 0))
+	    {
+	      *err = REG_EBRACK;
+	      goto parse_bracket_exp_free_return;
+	    }
+	  if (token->type == OP_CHARSET_RANGE)
+	    {
+	      re_string_skip_bytes (regexp, token_len); /* Skip '-'.  */
+	      token_len2 = peek_token_bracket (&token2, regexp, syntax);
+	      if (BE (token2.type == END_OF_RE, 0))
+		{
+		  *err = REG_EBRACK;
+		  goto parse_bracket_exp_free_return;
+		}
+	      if (token2.type == OP_CLOSE_BRACKET)
+		{
+		  /* We treat the last '-' as a normal character.  */
+		  re_string_skip_bytes (regexp, -token_len);
+		  token->type = CHARACTER;
+		}
+	      else
+		is_range_exp = 1;
+	    }
+	}
+
+      if (is_range_exp == 1)
+	{
+	  end_elem.opr.name = end_name_buf;
+	  ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2,
+				       dfa, syntax, 1);
+	  if (BE (ret != REG_NOERROR, 0))
+	    {
+	      *err = ret;
+	      goto parse_bracket_exp_free_return;
+	    }
+
+	  token_len = peek_token_bracket (token, regexp, syntax);
+
+#ifdef _LIBC
+	  *err = build_range_exp (sbcset, mbcset, &range_alloc,
+				  &start_elem, &end_elem);
+#else
+# ifdef RE_ENABLE_I18N
+	  *err = build_range_exp (sbcset,
+				  dfa->mb_cur_max > 1 ? mbcset : NULL,
+				  &range_alloc, &start_elem, &end_elem);
+# else
+	  *err = build_range_exp (sbcset, &start_elem, &end_elem);
+# endif
+#endif /* RE_ENABLE_I18N */
+	  if (BE (*err != REG_NOERROR, 0))
+	    goto parse_bracket_exp_free_return;
+	}
+      else
+	{
+	  switch (start_elem.type)
+	    {
+	    case SB_CHAR:
+	      bitset_set (sbcset, start_elem.opr.ch);
+	      break;
+#ifdef RE_ENABLE_I18N
+	    case MB_CHAR:
+	      /* Check whether the array has enough space.  */
+	      if (BE (mbchar_alloc == mbcset->nmbchars, 0))
+		{
+		  wchar_t *new_mbchars;
+		  /* Not enough, realloc it.  */
+		  /* +1 in case of mbcset->nmbchars is 0.  */
+		  mbchar_alloc = 2 * mbcset->nmbchars + 1;
+		  /* Use realloc since array is NULL if *alloc == 0.  */
+		  new_mbchars = re_realloc (mbcset->mbchars, wchar_t,
+					    mbchar_alloc);
+		  if (BE (new_mbchars == NULL, 0))
+		    goto parse_bracket_exp_espace;
+		  mbcset->mbchars = new_mbchars;
+		}
+	      mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;
+	      break;
+#endif /* RE_ENABLE_I18N */
+	    case EQUIV_CLASS:
+	      *err = build_equiv_class (sbcset,
+#ifdef RE_ENABLE_I18N
+					mbcset, &equiv_class_alloc,
+#endif /* RE_ENABLE_I18N */
+					start_elem.opr.name);
+	      if (BE (*err != REG_NOERROR, 0))
+		goto parse_bracket_exp_free_return;
+	      break;
+	    case COLL_SYM:
+	      *err = build_collating_symbol (sbcset,
+#ifdef RE_ENABLE_I18N
+					     mbcset, &coll_sym_alloc,
+#endif /* RE_ENABLE_I18N */
+					     start_elem.opr.name);
+	      if (BE (*err != REG_NOERROR, 0))
+		goto parse_bracket_exp_free_return;
+	      break;
+	    case CHAR_CLASS:
+	      *err = build_charclass (regexp->trans, sbcset,
+#ifdef RE_ENABLE_I18N
+				      mbcset, &char_class_alloc,
+#endif /* RE_ENABLE_I18N */
+				      (const char *) start_elem.opr.name, syntax);
+	      if (BE (*err != REG_NOERROR, 0))
+	       goto parse_bracket_exp_free_return;
+	      break;
+	    default:
+	      assert (0);
+	      break;
+	    }
+	}
+      if (BE (token->type == END_OF_RE, 0))
+	{
+	  *err = REG_EBRACK;
+	  goto parse_bracket_exp_free_return;
+	}
+      if (token->type == OP_CLOSE_BRACKET)
+	break;
+    }
+
+  re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
+
+  /* If it is non-matching list.  */
+  if (non_match)
+    bitset_not (sbcset);
+
+#ifdef RE_ENABLE_I18N
+  /* Ensure only single byte characters are set.  */
+  if (dfa->mb_cur_max > 1)
+    bitset_mask (sbcset, dfa->sb_char);
+
+  if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes
+      || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes
+						     || mbcset->non_match)))
+    {
+      bin_tree_t *mbc_tree;
+      int sbc_idx;
+      /* Build a tree for complex bracket.  */
+      dfa->has_mb_node = 1;
+      br_token.type = COMPLEX_BRACKET;
+      br_token.opr.mbcset = mbcset;
+      mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+      if (BE (mbc_tree == NULL, 0))
+	goto parse_bracket_exp_espace;
+      for (sbc_idx = 0; sbc_idx < BITSET_WORDS; ++sbc_idx)
+	if (sbcset[sbc_idx])
+	  break;
+      /* If there are no bits set in sbcset, there is no point
+	 of having both SIMPLE_BRACKET and COMPLEX_BRACKET.  */
+      if (sbc_idx < BITSET_WORDS)
+	{
+	  /* Build a tree for simple bracket.  */
+	  br_token.type = SIMPLE_BRACKET;
+	  br_token.opr.sbcset = sbcset;
+	  work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+	  if (BE (work_tree == NULL, 0))
+	    goto parse_bracket_exp_espace;
+
+	  /* Then join them by ALT node.  */
+	  work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT);
+	  if (BE (work_tree == NULL, 0))
+	    goto parse_bracket_exp_espace;
+	}
+      else
+	{
+	  re_free (sbcset);
+	  work_tree = mbc_tree;
+	}
+    }
+  else
+#endif /* not RE_ENABLE_I18N */
+    {
+#ifdef RE_ENABLE_I18N
+      free_charset (mbcset);
+#endif
+      /* Build a tree for simple bracket.  */
+      br_token.type = SIMPLE_BRACKET;
+      br_token.opr.sbcset = sbcset;
+      work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+      if (BE (work_tree == NULL, 0))
+	goto parse_bracket_exp_espace;
+    }
+  return work_tree;
+
+ parse_bracket_exp_espace:
+  *err = REG_ESPACE;
+ parse_bracket_exp_free_return:
+  re_free (sbcset);
+#ifdef RE_ENABLE_I18N
+  free_charset (mbcset);
+#endif /* RE_ENABLE_I18N */
+  return NULL;
+}
+
+/* Parse an element in the bracket expression.  */
+
+static reg_errcode_t
+parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,
+		       re_token_t *token, int token_len, UNUSED re_dfa_t *dfa,
+		       reg_syntax_t syntax, int accept_hyphen)
+{
+#ifdef RE_ENABLE_I18N
+  int cur_char_size;
+  cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp));
+  if (cur_char_size > 1)
+    {
+      elem->type = MB_CHAR;
+      elem->opr.wch = re_string_wchar_at (regexp, re_string_cur_idx (regexp));
+      re_string_skip_bytes (regexp, cur_char_size);
+      return REG_NOERROR;
+    }
+#endif /* RE_ENABLE_I18N */
+  re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
+  if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS
+      || token->type == OP_OPEN_EQUIV_CLASS)
+    return parse_bracket_symbol (elem, regexp, token);
+  if (BE (token->type == OP_CHARSET_RANGE, 0) && !accept_hyphen)
+    {
+      /* A '-' must only appear as anything but a range indicator before
+	 the closing bracket.  Everything else is an error.  */
+      re_token_t token2;
+      (void) peek_token_bracket (&token2, regexp, syntax);
+      if (token2.type != OP_CLOSE_BRACKET)
+	/* The actual error value is not standardized since this whole
+	   case is undefined.  But ERANGE makes good sense.  */
+	return REG_ERANGE;
+    }
+  elem->type = SB_CHAR;
+  elem->opr.ch = token->opr.c;
+  return REG_NOERROR;
+}
+
+/* Parse a bracket symbol in the bracket expression.  Bracket symbols are
+   such as [:<character_class>:], [.<collating_element>.], and
+   [=<equivalent_class>=].  */
+
+static reg_errcode_t
+parse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp,
+		      re_token_t *token)
+{
+  unsigned char ch, delim = token->opr.c;
+  int i = 0;
+  if (re_string_eoi(regexp))
+    return REG_EBRACK;
+  for (;; ++i)
+    {
+      if (i >= BRACKET_NAME_BUF_SIZE)
+	return REG_EBRACK;
+      if (token->type == OP_OPEN_CHAR_CLASS)
+	ch = re_string_fetch_byte_case (regexp);
+      else
+	ch = re_string_fetch_byte (regexp);
+      if (re_string_eoi(regexp))
+	return REG_EBRACK;
+      if (ch == delim && re_string_peek_byte (regexp, 0) == ']')
+	break;
+      elem->opr.name[i] = ch;
+    }
+  re_string_skip_bytes (regexp, 1);
+  elem->opr.name[i] = '\0';
+  switch (token->type)
+    {
+    case OP_OPEN_COLL_ELEM:
+      elem->type = COLL_SYM;
+      break;
+    case OP_OPEN_EQUIV_CLASS:
+      elem->type = EQUIV_CLASS;
+      break;
+    case OP_OPEN_CHAR_CLASS:
+      elem->type = CHAR_CLASS;
+      break;
+    default:
+      break;
+    }
+  return REG_NOERROR;
+}
+
+  /* Helper function for parse_bracket_exp.
+     Build the equivalence class which is represented by NAME.
+     The result are written to MBCSET and SBCSET.
+     EQUIV_CLASS_ALLOC is the allocated size of mbcset->equiv_classes,
+     is a pointer argument sinse we may update it.  */
+
+static reg_errcode_t
+#ifdef RE_ENABLE_I18N
+build_equiv_class (bitset_t sbcset, re_charset_t *mbcset,
+		   int *equiv_class_alloc, const unsigned char *name)
+#else /* not RE_ENABLE_I18N */
+build_equiv_class (bitset_t sbcset, const unsigned char *name)
+#endif /* not RE_ENABLE_I18N */
+{
+#ifdef _LIBC
+  uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+  if (nrules != 0)
+    {
+      const int32_t *table, *indirect;
+      const unsigned char *weights, *extra, *cp;
+      unsigned char char_buf[2];
+      int32_t idx1, idx2;
+      unsigned int ch;
+      size_t len;
+      /* This #include defines a local function!  */
+# include <locale/weight.h>
+      /* Calculate the index for equivalence class.  */
+      cp = name;
+      table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+      weights = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
+					       _NL_COLLATE_WEIGHTMB);
+      extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
+						   _NL_COLLATE_EXTRAMB);
+      indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
+						_NL_COLLATE_INDIRECTMB);
+      idx1 = findidx (&cp);
+      if (BE (idx1 == 0 || cp < name + strlen ((const char *) name), 0))
+	/* This isn't a valid character.  */
+	return REG_ECOLLATE;
+
+      /* Build single byte matcing table for this equivalence class.  */
+      char_buf[1] = (unsigned char) '\0';
+      len = weights[idx1 & 0xffffff];
+      for (ch = 0; ch < SBC_MAX; ++ch)
+	{
+	  char_buf[0] = ch;
+	  cp = char_buf;
+	  idx2 = findidx (&cp);
+/*
+	  idx2 = table[ch];
+*/
+	  if (idx2 == 0)
+	    /* This isn't a valid character.  */
+	    continue;
+	  /* Compare only if the length matches and the collation rule
+	     index is the same.  */
+	  if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24))
+	    {
+	      int cnt = 0;
+
+	      while (cnt <= len &&
+		     weights[(idx1 & 0xffffff) + 1 + cnt]
+		     == weights[(idx2 & 0xffffff) + 1 + cnt])
+		++cnt;
+
+	      if (cnt > len)
+		bitset_set (sbcset, ch);
+	    }
+	}
+      /* Check whether the array has enough space.  */
+      if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0))
+	{
+	  /* Not enough, realloc it.  */
+	  /* +1 in case of mbcset->nequiv_classes is 0.  */
+	  int new_equiv_class_alloc = 2 * mbcset->nequiv_classes + 1;
+	  /* Use realloc since the array is NULL if *alloc == 0.  */
+	  int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes,
+						   int32_t,
+						   new_equiv_class_alloc);
+	  if (BE (new_equiv_classes == NULL, 0))
+	    return REG_ESPACE;
+	  mbcset->equiv_classes = new_equiv_classes;
+	  *equiv_class_alloc = new_equiv_class_alloc;
+	}
+      mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;
+    }
+  else
+#endif /* _LIBC */
+    {
+      if (BE (strlen ((const char *) name) != 1, 0))
+	return REG_ECOLLATE;
+      bitset_set (sbcset, *name);
+    }
+  return REG_NOERROR;
+}
+
+  /* Helper function for parse_bracket_exp.
+     Build the character class which is represented by NAME.
+     The result are written to MBCSET and SBCSET.
+     CHAR_CLASS_ALLOC is the allocated size of mbcset->char_classes,
+     is a pointer argument sinse we may update it.  */
+
+static reg_errcode_t
+#ifdef RE_ENABLE_I18N
+build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
+		 re_charset_t *mbcset, int *char_class_alloc,
+		 const char *class_name, reg_syntax_t syntax)
+#else /* not RE_ENABLE_I18N */
+build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
+		 const char *class_name, reg_syntax_t syntax)
+#endif /* not RE_ENABLE_I18N */
+{
+  int i;
+
+  /* In case of REG_ICASE "upper" and "lower" match the both of
+     upper and lower cases.  */
+  if ((syntax & RE_ICASE)
+      && (strcmp (class_name, "upper") == 0 || strcmp (class_name, "lower") == 0))
+    class_name = "alpha";
+
+#ifdef RE_ENABLE_I18N
+  /* Check the space of the arrays.  */
+  if (BE (*char_class_alloc == mbcset->nchar_classes, 0))
+    {
+      /* Not enough, realloc it.  */
+      /* +1 in case of mbcset->nchar_classes is 0.  */
+      int new_char_class_alloc = 2 * mbcset->nchar_classes + 1;
+      /* Use realloc since array is NULL if *alloc == 0.  */
+      wctype_t *new_char_classes = re_realloc (mbcset->char_classes, wctype_t,
+					       new_char_class_alloc);
+      if (BE (new_char_classes == NULL, 0))
+	return REG_ESPACE;
+      mbcset->char_classes = new_char_classes;
+      *char_class_alloc = new_char_class_alloc;
+    }
+  mbcset->char_classes[mbcset->nchar_classes++] = __wctype (class_name);
+#endif /* RE_ENABLE_I18N */
+
+#define BUILD_CHARCLASS_LOOP(ctype_func)	\
+  do {						\
+    if (BE (trans != NULL, 0))			\
+      {						\
+	for (i = 0; i < SBC_MAX; ++i)		\
+  	  if (ctype_func (i))			\
+	    bitset_set (sbcset, trans[i]);	\
+      }						\
+    else					\
+      {						\
+	for (i = 0; i < SBC_MAX; ++i)		\
+  	  if (ctype_func (i))			\
+	    bitset_set (sbcset, i);		\
+      }						\
+  } while (0)
+
+  if (strcmp (class_name, "alnum") == 0)
+    BUILD_CHARCLASS_LOOP (isalnum);
+  else if (strcmp (class_name, "cntrl") == 0)
+    BUILD_CHARCLASS_LOOP (iscntrl);
+  else if (strcmp (class_name, "lower") == 0)
+    BUILD_CHARCLASS_LOOP (islower);
+  else if (strcmp (class_name, "space") == 0)
+    BUILD_CHARCLASS_LOOP (isspace);
+  else if (strcmp (class_name, "alpha") == 0)
+    BUILD_CHARCLASS_LOOP (isalpha);
+  else if (strcmp (class_name, "digit") == 0)
+    BUILD_CHARCLASS_LOOP (isdigit);
+  else if (strcmp (class_name, "print") == 0)
+    BUILD_CHARCLASS_LOOP (isprint);
+  else if (strcmp (class_name, "upper") == 0)
+    BUILD_CHARCLASS_LOOP (isupper);
+  else if (strcmp (class_name, "blank") == 0)
+#ifndef GAWK
+    BUILD_CHARCLASS_LOOP (isblank);
+#else
+    /* see comments above */
+    BUILD_CHARCLASS_LOOP (is_blank);
+#endif
+  else if (strcmp (class_name, "graph") == 0)
+    BUILD_CHARCLASS_LOOP (isgraph);
+  else if (strcmp (class_name, "punct") == 0)
+    BUILD_CHARCLASS_LOOP (ispunct);
+  else if (strcmp (class_name, "xdigit") == 0)
+    BUILD_CHARCLASS_LOOP (isxdigit);
+  else
+    return REG_ECTYPE;
+
+  return REG_NOERROR;
+}
+
+static bin_tree_t *
+build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
+		    const char *class_name,
+		    const char *extra, int non_match,
+		    reg_errcode_t *err)
+{
+  re_bitset_ptr_t sbcset;
+#ifdef RE_ENABLE_I18N
+  re_charset_t *mbcset;
+  int alloc = 0;
+#endif /* not RE_ENABLE_I18N */
+  reg_errcode_t ret;
+  re_token_t br_token;
+  bin_tree_t *tree;
+
+  sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
+#ifdef RE_ENABLE_I18N
+  mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
+#endif /* RE_ENABLE_I18N */
+
+#ifdef RE_ENABLE_I18N
+  if (BE (sbcset == NULL || mbcset == NULL, 0))
+#else /* not RE_ENABLE_I18N */
+  if (BE (sbcset == NULL, 0))
+#endif /* not RE_ENABLE_I18N */
+    {
+      *err = REG_ESPACE;
+      return NULL;
+    }
+
+  if (non_match)
+    {
+#ifdef RE_ENABLE_I18N
+      mbcset->non_match = 1;
+#endif /* not RE_ENABLE_I18N */
+    }
+
+  /* We don't care the syntax in this case.  */
+  ret = build_charclass (trans, sbcset,
+#ifdef RE_ENABLE_I18N
+			 mbcset, &alloc,
+#endif /* RE_ENABLE_I18N */
+			 class_name, 0);
+
+  if (BE (ret != REG_NOERROR, 0))
+    {
+      re_free (sbcset);
+#ifdef RE_ENABLE_I18N
+      free_charset (mbcset);
+#endif /* RE_ENABLE_I18N */
+      *err = ret;
+      return NULL;
+    }
+  /* \w match '_' also.  */
+  for (; *extra; extra++)
+    bitset_set (sbcset, *extra);
+
+  /* If it is non-matching list.  */
+  if (non_match)
+    bitset_not (sbcset);
+
+#ifdef RE_ENABLE_I18N
+  /* Ensure only single byte characters are set.  */
+  if (dfa->mb_cur_max > 1)
+    bitset_mask (sbcset, dfa->sb_char);
+#endif
+
+  /* Build a tree for simple bracket.  */
+  br_token.type = SIMPLE_BRACKET;
+  br_token.opr.sbcset = sbcset;
+  tree = create_token_tree (dfa, NULL, NULL, &br_token);
+  if (BE (tree == NULL, 0))
+    goto build_word_op_espace;
+
+#ifdef RE_ENABLE_I18N
+  if (dfa->mb_cur_max > 1)
+    {
+      bin_tree_t *mbc_tree;
+      /* Build a tree for complex bracket.  */
+      br_token.type = COMPLEX_BRACKET;
+      br_token.opr.mbcset = mbcset;
+      dfa->has_mb_node = 1;
+      mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+      if (BE (mbc_tree == NULL, 0))
+	goto build_word_op_espace;
+      /* Then join them by ALT node.  */
+      tree = create_tree (dfa, tree, mbc_tree, OP_ALT);
+      if (BE (mbc_tree != NULL, 1))
+	return tree;
+    }
+  else
+    {
+      free_charset (mbcset);
+      return tree;
+    }
+#else /* not RE_ENABLE_I18N */
+  return tree;
+#endif /* not RE_ENABLE_I18N */
+
+ build_word_op_espace:
+  re_free (sbcset);
+#ifdef RE_ENABLE_I18N
+  free_charset (mbcset);
+#endif /* RE_ENABLE_I18N */
+  *err = REG_ESPACE;
+  return NULL;
+}
+
+/* This is intended for the expressions like "a{1,3}".
+   Fetch a number from `input', and return the number.
+   Return -1, if the number field is empty like "{,1}".
+   Return -2, If an error is occured.  */
+
+static int
+fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax)
+{
+  int num = -1;
+  unsigned char c;
+  while (1)
+    {
+      fetch_token (token, input, syntax);
+      c = token->opr.c;
+      if (BE (token->type == END_OF_RE, 0))
+	return -2;
+      if (token->type == OP_CLOSE_DUP_NUM || c == ',')
+	break;
+      num = ((token->type != CHARACTER || c < '0' || '9' < c || num == -2)
+	     ? -2 : ((num == -1) ? c - '0' : num * 10 + c - '0'));
+      num = (num > RE_DUP_MAX) ? -2 : num;
+    }
+  return num;
+}
+
+#ifdef RE_ENABLE_I18N
+static void
+free_charset (re_charset_t *cset)
+{
+  re_free (cset->mbchars);
+# ifdef _LIBC
+  re_free (cset->coll_syms);
+  re_free (cset->equiv_classes);
+  re_free (cset->range_starts);
+  re_free (cset->range_ends);
+# endif
+  re_free (cset->char_classes);
+  re_free (cset);
+}
+#endif /* RE_ENABLE_I18N */
+
+/* Functions for binary tree operation.  */
+
+/* Create a tree node.  */
+
+static bin_tree_t *
+create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,
+	     re_token_type_t type)
+{
+  re_token_t t;
+  t.type = type;
+  return create_token_tree (dfa, left, right, &t);
+}
+
+static bin_tree_t *
+create_token_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,
+		   const re_token_t *token)
+{
+  bin_tree_t *tree;
+  if (BE (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE, 0))
+    {
+      bin_tree_storage_t *storage = re_malloc (bin_tree_storage_t, 1);
+
+      if (storage == NULL)
+	return NULL;
+      storage->next = dfa->str_tree_storage;
+      dfa->str_tree_storage = storage;
+      dfa->str_tree_storage_idx = 0;
+    }
+  tree = &dfa->str_tree_storage->data[dfa->str_tree_storage_idx++];
+
+  tree->parent = NULL;
+  tree->left = left;
+  tree->right = right;
+  tree->token = *token;
+  tree->token.duplicated = 0;
+  tree->token.opt_subexp = 0;
+  tree->first = NULL;
+  tree->next = NULL;
+  tree->node_idx = -1;
+
+  if (left != NULL)
+    left->parent = tree;
+  if (right != NULL)
+    right->parent = tree;
+  return tree;
+}
+
+/* Mark the tree SRC as an optional subexpression.
+   To be called from preorder or postorder.  */
+
+static reg_errcode_t
+mark_opt_subexp (void *extra, bin_tree_t *node)
+{
+  int idx = (int) (long) extra;
+  if (node->token.type == SUBEXP && node->token.opr.idx == idx)
+    node->token.opt_subexp = 1;
+
+  return REG_NOERROR;
+}
+
+/* Free the allocated memory inside NODE. */
+
+static void
+free_token (re_token_t *node)
+{
+#ifdef RE_ENABLE_I18N
+  if (node->type == COMPLEX_BRACKET && node->duplicated == 0)
+    free_charset (node->opr.mbcset);
+  else
+#endif /* RE_ENABLE_I18N */
+    if (node->type == SIMPLE_BRACKET && node->duplicated == 0)
+      re_free (node->opr.sbcset);
+}
+
+/* Worker function for tree walking.  Free the allocated memory inside NODE
+   and its children. */
+
+static reg_errcode_t
+free_tree (UNUSED void *extra, bin_tree_t *node)
+{
+  free_token (&node->token);
+  return REG_NOERROR;
+}
+
+
+/* Duplicate the node SRC, and return new node.  This is a preorder
+   visit similar to the one implemented by the generic visitor, but
+   we need more infrastructure to maintain two parallel trees --- so,
+   it's easier to duplicate.  */
+
+static bin_tree_t *
+duplicate_tree (const bin_tree_t *root, re_dfa_t *dfa)
+{
+  const bin_tree_t *node;
+  bin_tree_t *dup_root;
+  bin_tree_t **p_new = &dup_root, *dup_node = root->parent;
+
+  for (node = root; ; )
+    {
+      /* Create a new tree and link it back to the current parent.  */
+      *p_new = create_token_tree (dfa, NULL, NULL, &node->token);
+      if (*p_new == NULL)
+	return NULL;
+      (*p_new)->parent = dup_node;
+      (*p_new)->token.duplicated = 1;
+      dup_node = *p_new;
+
+      /* Go to the left node, or up and to the right.  */
+      if (node->left)
+	{
+	  node = node->left;
+	  p_new = &dup_node->left;
+	}
+      else
+	{
+	  const bin_tree_t *prev = NULL;
+	  while (node->right == prev || node->right == NULL)
+	    {
+	      prev = node;
+	      node = node->parent;
+	      dup_node = dup_node->parent;
+	      if (!node)
+		return dup_root;
+	    }
+	  node = node->right;
+	  p_new = &dup_node->right;
+	}
+    }
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regex.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regex.c
new file mode 100755
index 0000000..225a001
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regex.c
@@ -0,0 +1,92 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu at yamato.ibm.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301 USA.  */
+
+#include "config.h"
+
+/* Make sure noone compiles this code with a C++ compiler.  */
+#ifdef __cplusplus
+# error "This is C code, use a C compiler"
+#endif
+
+#ifdef _LIBC
+/* We have to keep the namespace clean.  */
+# define regfree(preg) __regfree (preg)
+# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
+# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
+# define regerror(errcode, preg, errbuf, errbuf_size) \
+	__regerror(errcode, preg, errbuf, errbuf_size)
+# define re_set_registers(bu, re, nu, st, en) \
+	__re_set_registers (bu, re, nu, st, en)
+# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
+	__re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
+# define re_match(bufp, string, size, pos, regs) \
+	__re_match (bufp, string, size, pos, regs)
+# define re_search(bufp, string, size, startpos, range, regs) \
+	__re_search (bufp, string, size, startpos, range, regs)
+# define re_compile_pattern(pattern, length, bufp) \
+	__re_compile_pattern (pattern, length, bufp)
+# define re_set_syntax(syntax) __re_set_syntax (syntax)
+# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
+	__re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
+# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
+
+# include "../locale/localeinfo.h"
+#endif
+
+#if defined (_MSC_VER)
+#include <stdio.h> /* for size_t */
+#endif
+
+/* On some systems, limits.h sets RE_DUP_MAX to a lower value than
+   GNU regex allows.  Include it before <regex.h>, which correctly
+   #undefs RE_DUP_MAX and sets it to the right value.  */
+#include <limits.h>
+
+#ifdef GAWK
+#undef alloca
+#define alloca alloca_is_bad_you_should_never_use_it
+#endif
+#include <regex.h>
+#include "regex_internal.h"
+
+#include "regex_internal.c"
+
+#ifdef GAWK
+# define bool int
+
+# ifndef true
+#  define true (1)
+# endif
+
+# ifndef false
+#  define false (0)
+# endif
+#endif
+#include "regcomp.c"
+#include "regexec.c"
+
+/* Binary backward compatibility.  */
+#if _LIBC
+# include <shlib-compat.h>
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)
+link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.")
+int re_max_failures = 2000;
+# endif
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regex.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regex.h
new file mode 100755
index 0000000..61c9683
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regex.h
@@ -0,0 +1,582 @@
+#include <stdio.h>
+#include <stddef.h>
+
+/* Definitions for data structures and routines for the regular
+   expression library.
+   Copyright (C) 1985,1989-93,1995-98,2000,2001,2002,2003,2005,2006,2008
+   Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301 USA.  */
+
+#ifndef _REGEX_H
+#define _REGEX_H 1
+
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifndef _LIBC
+#define __USE_GNU	1
+#endif
+
+/* Allow the use in C++ code.  */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The following two types have to be signed and unsigned integer type
+   wide enough to hold a value of a pointer.  For most ANSI compilers
+   ptrdiff_t and size_t should be likely OK.  Still size of these two
+   types is 2 for Microsoft C.  Ugh... */
+typedef long int s_reg_t;
+typedef unsigned long int active_reg_t;
+
+/* The following bits are used to determine the regexp syntax we
+   recognize.  The set/not-set meanings are chosen so that Emacs syntax
+   remains the value 0.  The bits are given in alphabetical order, and
+   the definitions shifted by one from the previous bit; thus, when we
+   add or remove a bit, only one other definition need change.  */
+typedef unsigned long int reg_syntax_t;
+
+#ifdef __USE_GNU
+/* If this bit is not set, then \ inside a bracket expression is literal.
+   If set, then such a \ quotes the following character.  */
+# define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+     literals.
+   If set, then \+ and \? are operators and + and ? are literals.  */
+# define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* If this bit is set, then character classes are supported.  They are:
+     [:alpha:], [:upper:], [:lower:],  [:digit:], [:alnum:], [:xdigit:],
+     [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+   If not set, then character classes are not supported.  */
+# define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+     expressions, of course).
+   If this bit is not set, then it depends:
+        ^  is an anchor if it is at the beginning of a regular
+           expression or after an open-group or an alternation operator;
+        $  is an anchor if it is at the end of a regular expression, or
+           before a close-group or an alternation operator.
+
+   This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+   POSIX draft 11.2 says that * etc. in leading positions is undefined.
+   We already implemented a previous draft which made those constructs
+   invalid, though, so we haven't changed the code back.  */
+# define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+     regardless of where they are in the pattern.
+   If this bit is not set, then special characters are special only in
+     some contexts; otherwise they are ordinary.  Specifically,
+     * + ? and intervals are only special when not after the beginning,
+     open-group, or alternation operator.  */
+# define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+     immediately after an alternation or begin-group operator.  */
+# define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+   If not set, then it doesn't.  */
+# define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+   If not set, then it does.  */
+# define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+   If not set, they do.  */
+# define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+     interval, depending on RE_NO_BK_BRACES.
+   If not set, \{, \}, {, and } are literals.  */
+# define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+   If not set, they are.  */
+# define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+   If not set, newline is literal.  */
+# define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then `{...}' defines an interval, and \{ and \}
+     are literals.
+  If not set, then `\{...\}' defines an interval.  */
+# define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+   If not set, \(...\) defines a group, and ( and ) are literals.  */
+# define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+   If not set, then \<digit> is a back-reference.  */
+# define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal.
+   If not set, then \| is an alternation operator, and | is literal.  */
+# define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+     than the starting range point, as in [z-a], is invalid.
+   If not set, then when ending range point collates higher than the
+     starting range point, the range is ignored.  */
+# define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+   If not set, then an unmatched ) is invalid.  */
+# define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* If this bit is set, succeed as soon as we match the whole pattern,
+   without further backtracking.  */
+# define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
+
+/* If this bit is set, do not process the GNU regex operators.
+   If not set, then the GNU regex operators are recognized. */
+# define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)
+
+/* If this bit is set, a syntactically invalid interval is treated as
+   a string of ordinary characters.  For example, the ERE 'a{1' is
+   treated as 'a\{1'.  */
+# define RE_INVALID_INTERVAL_ORD (RE_NO_GNU_OPS << 1)
+
+/* If this bit is set, then ignore case when matching.
+   If not set, then case is significant.  */
+# define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
+
+/* This bit is used internally like RE_CONTEXT_INDEP_ANCHORS but only
+   for ^, because it is difficult to scan the regex backwards to find
+   whether ^ should be special.  */
+# define RE_CARET_ANCHORS_HERE (RE_ICASE << 1)
+
+/* If this bit is set, then \{ cannot be first in an bre or
+   immediately after an alternation or begin-group operator.  */
+# define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1)
+
+/* If this bit is set, then no_sub will be set to 1 during
+   re_compile_pattern.  */
+#define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1)
+#endif
+
+/* This global variable defines the particular regexp syntax to use (for
+   some interfaces).  When a regexp is compiled, the syntax used is
+   stored in the pattern buffer, so changing this does not affect
+   already-compiled regexps.  */
+extern reg_syntax_t re_syntax_options;
+
+#ifdef __USE_GNU
+/* Define combinations of the above bits for the standard possibilities.
+   (The [[[ comments delimit what gets put into the Texinfo file, so
+   don't delete them!)  */
+/* [[[begin syntaxes]]] */
+#define RE_SYNTAX_EMACS 0
+
+#define RE_SYNTAX_AWK							\
+  (RE_BACKSLASH_ESCAPE_IN_LISTS   | RE_DOT_NOT_NULL			\
+   | RE_NO_BK_PARENS              | RE_NO_BK_REFS			\
+   | RE_NO_BK_VBAR                | RE_NO_EMPTY_RANGES			\
+   | RE_DOT_NEWLINE		  | RE_CONTEXT_INDEP_ANCHORS		\
+   | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
+
+#define RE_SYNTAX_GNU_AWK						\
+  ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS		\
+   | RE_INVALID_INTERVAL_ORD)						\
+   & ~(RE_DOT_NOT_NULL | RE_CONTEXT_INDEP_OPS				\
+       | RE_CONTEXT_INVALID_OPS ))
+
+#define RE_SYNTAX_POSIX_AWK						\
+  (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS		\
+   | RE_INTERVALS	    | RE_NO_GNU_OPS				\
+   | RE_INVALID_INTERVAL_ORD)
+
+#define RE_SYNTAX_GREP							\
+  (RE_BK_PLUS_QM              | RE_CHAR_CLASSES				\
+   | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS				\
+   | RE_NEWLINE_ALT)
+
+#define RE_SYNTAX_EGREP							\
+  (RE_CHAR_CLASSES        | RE_CONTEXT_INDEP_ANCHORS			\
+   | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE			\
+   | RE_NEWLINE_ALT       | RE_NO_BK_PARENS				\
+   | RE_NO_BK_VBAR)
+
+#define RE_SYNTAX_POSIX_EGREP						\
+  (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES			\
+   | RE_INVALID_INTERVAL_ORD)
+
+/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff.  */
+#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
+
+#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax.  */
+#define _RE_SYNTAX_POSIX_COMMON						\
+  (RE_CHAR_CLASSES | RE_DOT_NEWLINE      | RE_DOT_NOT_NULL		\
+   | RE_INTERVALS  | RE_NO_EMPTY_RANGES)
+
+#define RE_SYNTAX_POSIX_BASIC						\
+  (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+   RE_LIMITED_OPS, i.e., \? \+ \| are not recognized.  Actually, this
+   isn't minimal, since other operators, such as \`, aren't disabled.  */
+#define RE_SYNTAX_POSIX_MINIMAL_BASIC					\
+  (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+#define RE_SYNTAX_POSIX_EXTENDED					\
+  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS			\
+   | RE_CONTEXT_INDEP_OPS   | RE_NO_BK_BRACES				\
+   | RE_NO_BK_PARENS        | RE_NO_BK_VBAR				\
+   | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is
+   removed and RE_NO_BK_REFS is added.  */
+#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED				\
+  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS			\
+   | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES				\
+   | RE_NO_BK_PARENS        | RE_NO_BK_REFS				\
+   | RE_NO_BK_VBAR	    | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+
+/* Maximum number of duplicates an interval can allow.  Some systems
+   (erroneously) define this in other header files, but we want our
+   value, so remove any previous define.  */
+# ifdef RE_DUP_MAX
+#  undef RE_DUP_MAX
+# endif
+/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows.  */
+# define RE_DUP_MAX (0x7fff)
+#endif
+
+
+/* POSIX `cflags' bits (i.e., information for `regcomp').  */
+
+/* If this bit is set, then use extended regular expression syntax.
+   If not set, then use basic regular expression syntax.  */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+   If not set, then case is significant.  */
+#define REG_ICASE (REG_EXTENDED << 1)
+
+/* If this bit is set, then anchors do not match at newline
+     characters in the string.
+   If not set, then anchors do match at newlines.  */
+#define REG_NEWLINE (REG_ICASE << 1)
+
+/* If this bit is set, then report only success or fail in regexec.
+   If not set, then returns differ between not matching and errors.  */
+#define REG_NOSUB (REG_NEWLINE << 1)
+
+
+/* POSIX `eflags' bits (i.e., information for regexec).  */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+     the beginning of the string (presumably because it's not the
+     beginning of a line).
+   If not set, then the beginning-of-line operator does match the
+     beginning of the string.  */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line.  */
+#define REG_NOTEOL (1 << 1)
+
+/* Use PMATCH[0] to delimit the start and end of the search in the
+   buffer.  */
+#define REG_STARTEND (1 << 2)
+
+
+/* If any error codes are removed, changed, or added, update the
+   `re_error_msg' table in regex.c.  */
+typedef enum
+{
+#if defined _XOPEN_SOURCE || defined __USE_XOPEN2K
+  REG_ENOSYS = -1,	/* This will never happen for this implementation.  */
+#endif
+
+  REG_NOERROR = 0,	/* Success.  */
+  REG_NOMATCH,		/* Didn't find a match (for regexec).  */
+
+  /* POSIX regcomp return error codes.  (In the order listed in the
+     standard.)  */
+  REG_BADPAT,		/* Invalid pattern.  */
+  REG_ECOLLATE,		/* Inalid collating element.  */
+  REG_ECTYPE,		/* Invalid character class name.  */
+  REG_EESCAPE,		/* Trailing backslash.  */
+  REG_ESUBREG,		/* Invalid back reference.  */
+  REG_EBRACK,		/* Unmatched left bracket.  */
+  REG_EPAREN,		/* Parenthesis imbalance.  */
+  REG_EBRACE,		/* Unmatched \{.  */
+  REG_BADBR,		/* Invalid contents of \{\}.  */
+  REG_ERANGE,		/* Invalid range end.  */
+  REG_ESPACE,		/* Ran out of memory.  */
+  REG_BADRPT,		/* No preceding re for repetition op.  */
+
+  /* Error codes we've added.  */
+  REG_EEND,		/* Premature end.  */
+  REG_ESIZE,		/* Compiled pattern bigger than 2^16 bytes.  */
+  REG_ERPAREN		/* Unmatched ) or \); not returned from regcomp.  */
+} reg_errcode_t;
+
+/* This data structure represents a compiled pattern.  Before calling
+   the pattern compiler, the fields `buffer', `allocated', `fastmap',
+   `translate', and `no_sub' can be set.  After the pattern has been
+   compiled, the `re_nsub' field is available.  All other fields are
+   private to the regex routines.  */
+
+#ifndef RE_TRANSLATE_TYPE
+# define __RE_TRANSLATE_TYPE unsigned char *
+# ifdef __USE_GNU
+#  define RE_TRANSLATE_TYPE __RE_TRANSLATE_TYPE
+# endif
+#endif
+
+#ifdef __USE_GNU
+# define __REPB_PREFIX(name) name
+#else
+# define __REPB_PREFIX(name) __##name
+#endif
+
+struct re_pattern_buffer
+{
+  /* Space that holds the compiled pattern.  It is declared as
+     `unsigned char *' because its elements are sometimes used as
+     array indexes.  */
+  unsigned char *__REPB_PREFIX(buffer);
+
+  /* Number of bytes to which `buffer' points.  */
+  unsigned long int __REPB_PREFIX(allocated);
+
+  /* Number of bytes actually used in `buffer'.  */
+  unsigned long int __REPB_PREFIX(used);
+
+  /* Syntax setting with which the pattern was compiled.  */
+  reg_syntax_t __REPB_PREFIX(syntax);
+
+  /* Pointer to a fastmap, if any, otherwise zero.  re_search uses the
+     fastmap, if there is one, to skip over impossible starting points
+     for matches.  */
+  char *__REPB_PREFIX(fastmap);
+
+  /* Either a translate table to apply to all characters before
+     comparing them, or zero for no translation.  The translation is
+     applied to a pattern when it is compiled and to a string when it
+     is matched.  */
+  __RE_TRANSLATE_TYPE __REPB_PREFIX(translate);
+
+  /* Number of subexpressions found by the compiler.  */
+  size_t re_nsub;
+
+  /* Zero if this pattern cannot match the empty string, one else.
+     Well, in truth it's used only in `re_search_2', to see whether or
+     not we should use the fastmap, so we don't set this absolutely
+     perfectly; see `re_compile_fastmap' (the `duplicate' case).  */
+  unsigned __REPB_PREFIX(can_be_null) : 1;
+
+  /* If REGS_UNALLOCATED, allocate space in the `regs' structure
+     for `max (RE_NREGS, re_nsub + 1)' groups.
+     If REGS_REALLOCATE, reallocate space if necessary.
+     If REGS_FIXED, use what's there.  */
+#ifdef __USE_GNU
+# define REGS_UNALLOCATED 0
+# define REGS_REALLOCATE 1
+# define REGS_FIXED 2
+#endif
+  unsigned __REPB_PREFIX(regs_allocated) : 2;
+
+  /* Set to zero when `regex_compile' compiles a pattern; set to one
+     by `re_compile_fastmap' if it updates the fastmap.  */
+  unsigned __REPB_PREFIX(fastmap_accurate) : 1;
+
+  /* If set, `re_match_2' does not return information about
+     subexpressions.  */
+  unsigned __REPB_PREFIX(no_sub) : 1;
+
+  /* If set, a beginning-of-line anchor doesn't match at the beginning
+     of the string.  */
+  unsigned __REPB_PREFIX(not_bol) : 1;
+
+  /* Similarly for an end-of-line anchor.  */
+  unsigned __REPB_PREFIX(not_eol) : 1;
+
+  /* If true, an anchor at a newline matches.  */
+  unsigned __REPB_PREFIX(newline_anchor) : 1;
+};
+
+typedef struct re_pattern_buffer regex_t;
+
+/* Type for byte offsets within the string.  POSIX mandates this.  */
+typedef int regoff_t;
+
+
+#ifdef __USE_GNU
+/* This is the structure we store register match data in.  See
+   regex.texinfo for a full description of what registers match.  */
+struct re_registers
+{
+  unsigned num_regs;
+  regoff_t *start;
+  regoff_t *end;
+};
+
+
+/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+   `re_match_2' returns information about at least this many registers
+   the first time a `regs' structure is passed.  */
+# ifndef RE_NREGS
+#  define RE_NREGS 30
+# endif
+#endif
+
+
+/* POSIX specification for registers.  Aside from the different names than
+   `re_registers', POSIX uses an array of structures, instead of a
+   structure of arrays.  */
+typedef struct
+{
+  regoff_t rm_so;  /* Byte offset from string's start to substring's start.  */
+  regoff_t rm_eo;  /* Byte offset from string's start to substring's end.  */
+} regmatch_t;
+
+/* Declarations for routines.  */
+
+#ifdef __USE_GNU
+/* Sets the current default syntax to SYNTAX, and return the old syntax.
+   You can also simply assign to the `re_syntax_options' variable.  */
+extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax);
+
+/* Compile the regular expression PATTERN, with length LENGTH
+   and syntax given by the global `re_syntax_options', into the buffer
+   BUFFER.  Return NULL if successful, and an error string if not.  */
+extern const char *re_compile_pattern (const char *__pattern, size_t __length,
+				       struct re_pattern_buffer *__buffer);
+
+
+/* Compile a fastmap for the compiled pattern in BUFFER; used to
+   accelerate searches.  Return 0 if successful and -2 if was an
+   internal error.  */
+extern int re_compile_fastmap (struct re_pattern_buffer *__buffer);
+
+
+/* Search in the string STRING (with length LENGTH) for the pattern
+   compiled into BUFFER.  Start searching at position START, for RANGE
+   characters.  Return the starting position of the match, -1 for no
+   match, or -2 for an internal error.  Also return register
+   information in REGS (if REGS and BUFFER->no_sub are nonzero).  */
+extern int re_search (struct re_pattern_buffer *__buffer, const char *__cstring,
+		      int __length, int __start, int __range,
+		      struct re_registers *__regs);
+
+
+/* Like `re_search', but search in the concatenation of STRING1 and
+   STRING2.  Also, stop searching at index START + STOP.  */
+extern int re_search_2 (struct re_pattern_buffer *__buffer,
+			const char *__string1, int __length1,
+			const char *__string2, int __length2, int __start,
+			int __range, struct re_registers *__regs, int __stop);
+
+
+/* Like `re_search', but return how many characters in STRING the regexp
+   in BUFFER matched, starting at position START.  */
+extern int re_match (struct re_pattern_buffer *__buffer, const char *__cstring,
+		     int __length, int __start, struct re_registers *__regs);
+
+
+/* Relates to `re_match' as `re_search_2' relates to `re_search'.  */
+extern int re_match_2 (struct re_pattern_buffer *__buffer,
+		       const char *__string1, int __length1,
+		       const char *__string2, int __length2, int __start,
+		       struct re_registers *__regs, int __stop);
+
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+   ENDS.  Subsequent matches using BUFFER and REGS will use this memory
+   for recording register information.  STARTS and ENDS must be
+   allocated with malloc, and must each be at least `NUM_REGS * sizeof
+   (regoff_t)' bytes long.
+
+   If NUM_REGS == 0, then subsequent matches should allocate their own
+   register data.
+
+   Unless this function is called, the first search or match using
+   PATTERN_BUFFER will allocate its own register data, without
+   freeing the old data.  */
+extern void re_set_registers (struct re_pattern_buffer *__buffer,
+			      struct re_registers *__regs,
+			      unsigned int __num_regs,
+			      regoff_t *__starts, regoff_t *__ends);
+#endif	/* Use GNU */
+
+#if defined _REGEX_RE_COMP || (defined _LIBC && defined __USE_BSD)
+# ifndef _CRAY
+/* 4.2 bsd compatibility.  */
+extern char *re_comp (const char *);
+extern int re_exec (const char *);
+# endif
+#endif
+
+/* GCC 2.95 and later have "__restrict"; C99 compilers have
+   "restrict", and "configure" may have defined "restrict".  */
+#ifndef __restrict
+# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
+#  if defined restrict || 199901L <= __STDC_VERSION__
+#   define __restrict restrict
+#  else
+#   define __restrict
+#  endif
+# endif
+#endif
+/* gcc 3.1 and up support the [restrict] syntax.  */
+#ifndef __restrict_arr
+# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) \
+     && !defined __GNUG__
+#  define __restrict_arr __restrict
+# else
+#  define __restrict_arr
+# endif
+#endif
+
+/* POSIX compatibility.  */
+extern int regcomp (regex_t *__restrict __preg,
+		    const char *__restrict __pattern,
+		    int __cflags);
+
+extern int regexec (const regex_t *__restrict __preg,
+		    const char *__restrict __cstring, size_t __nmatch,
+		    regmatch_t __pmatch[__restrict_arr],
+		    int __eflags);
+
+extern size_t regerror (int __errcode, const regex_t *__restrict __preg,
+			char *__restrict __errbuf, size_t __errbuf_size);
+
+extern void regfree (regex_t *__preg);
+
+
+#ifdef __cplusplus
+}
+#endif	/* C++ */
+
+#endif /* regex.h */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regex_internal.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regex_internal.c
new file mode 100755
index 0000000..ad57c20
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regex_internal.c
@@ -0,0 +1,1744 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002-2006, 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu at yamato.ibm.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301 USA.  */
+
+static void re_string_construct_common (const char *str, int len,
+					re_string_t *pstr,
+					RE_TRANSLATE_TYPE trans, int icase,
+					const re_dfa_t *dfa) internal_function;
+static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa,
+					  const re_node_set *nodes,
+					  unsigned int hash) internal_function;
+static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
+					  const re_node_set *nodes,
+					  unsigned int context,
+					  unsigned int hash) internal_function;
+
+#ifdef GAWK
+#undef MAX	/* safety */
+static size_t
+MAX(size_t a, size_t b)
+{
+	return (a > b ? a : b);
+}
+#endif
+
+/* Functions for string operation.  */
+
+/* This function allocate the buffers.  It is necessary to call
+   re_string_reconstruct before using the object.  */
+
+static reg_errcode_t
+internal_function
+re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len,
+		    RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
+{
+  reg_errcode_t ret;
+  int init_buf_len;
+
+  /* Ensure at least one character fits into the buffers.  */
+  if (init_len < dfa->mb_cur_max)
+    init_len = dfa->mb_cur_max;
+  init_buf_len = (len + 1 < init_len) ? len + 1: init_len;
+  re_string_construct_common (str, len, pstr, trans, icase, dfa);
+
+  ret = re_string_realloc_buffers (pstr, init_buf_len);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+
+  pstr->word_char = dfa->word_char;
+  pstr->word_ops_used = dfa->word_ops_used;
+  pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
+  pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len;
+  pstr->valid_raw_len = pstr->valid_len;
+  return REG_NOERROR;
+}
+
+/* This function allocate the buffers, and initialize them.  */
+
+static reg_errcode_t
+internal_function
+re_string_construct (re_string_t *pstr, const char *str, int len,
+		     RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
+{
+  reg_errcode_t ret;
+  memset (pstr, '\0', sizeof (re_string_t));
+  re_string_construct_common (str, len, pstr, trans, icase, dfa);
+
+  if (len > 0)
+    {
+      ret = re_string_realloc_buffers (pstr, len + 1);
+      if (BE (ret != REG_NOERROR, 0))
+	return ret;
+    }
+  pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
+
+  if (icase)
+    {
+#ifdef RE_ENABLE_I18N
+      if (dfa->mb_cur_max > 1)
+	{
+	  while (1)
+	    {
+	      ret = build_wcs_upper_buffer (pstr);
+	      if (BE (ret != REG_NOERROR, 0))
+		return ret;
+	      if (pstr->valid_raw_len >= len)
+		break;
+	      if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
+		break;
+	      ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
+	      if (BE (ret != REG_NOERROR, 0))
+		return ret;
+	    }
+	}
+      else
+#endif /* RE_ENABLE_I18N  */
+	build_upper_buffer (pstr);
+    }
+  else
+    {
+#ifdef RE_ENABLE_I18N
+      if (dfa->mb_cur_max > 1)
+	build_wcs_buffer (pstr);
+      else
+#endif /* RE_ENABLE_I18N  */
+	{
+	  if (trans != NULL)
+	    re_string_translate_buffer (pstr);
+	  else
+	    {
+	      pstr->valid_len = pstr->bufs_len;
+	      pstr->valid_raw_len = pstr->bufs_len;
+	    }
+	}
+    }
+
+  return REG_NOERROR;
+}
+
+/* Helper functions for re_string_allocate, and re_string_construct.  */
+
+static reg_errcode_t
+internal_function
+re_string_realloc_buffers (re_string_t *pstr, int new_buf_len)
+{
+#ifdef RE_ENABLE_I18N
+  if (pstr->mb_cur_max > 1)
+    {
+      wint_t *new_wcs;
+
+      /* Avoid overflow in realloc.  */
+      const size_t max_object_size = MAX (sizeof (wint_t), sizeof (int));
+      if (BE (SIZE_MAX / max_object_size < new_buf_len, 0))
+	return REG_ESPACE;
+
+      new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
+      if (BE (new_wcs == NULL, 0))
+	return REG_ESPACE;
+      pstr->wcs = new_wcs;
+      if (pstr->offsets != NULL)
+	{
+	  int *new_offsets = re_realloc (pstr->offsets, int, new_buf_len);
+	  if (BE (new_offsets == NULL, 0))
+	    return REG_ESPACE;
+	  pstr->offsets = new_offsets;
+	}
+    }
+#endif /* RE_ENABLE_I18N  */
+  if (pstr->mbs_allocated)
+    {
+      unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char,
+					   new_buf_len);
+      if (BE (new_mbs == NULL, 0))
+	return REG_ESPACE;
+      pstr->mbs = new_mbs;
+    }
+  pstr->bufs_len = new_buf_len;
+  return REG_NOERROR;
+}
+
+
+static void
+internal_function
+re_string_construct_common (const char *str, int len, re_string_t *pstr,
+			    RE_TRANSLATE_TYPE trans, int icase,
+			    const re_dfa_t *dfa)
+{
+  pstr->raw_mbs = (const unsigned char *) str;
+  pstr->len = len;
+  pstr->raw_len = len;
+  pstr->trans = trans;
+  pstr->icase = icase ? 1 : 0;
+  pstr->mbs_allocated = (trans != NULL || icase);
+  pstr->mb_cur_max = dfa->mb_cur_max;
+  pstr->is_utf8 = dfa->is_utf8;
+  pstr->map_notascii = dfa->map_notascii;
+  pstr->stop = pstr->len;
+  pstr->raw_stop = pstr->stop;
+}
+
+#ifdef RE_ENABLE_I18N
+
+/* Build wide character buffer PSTR->WCS.
+   If the byte sequence of the string are:
+     <mb1>(0), <mb1>(1), <mb2>(0), <mb2>(1), <sb3>
+   Then wide character buffer will be:
+     <wc1>   , WEOF    , <wc2>   , WEOF    , <wc3>
+   We use WEOF for padding, they indicate that the position isn't
+   a first byte of a multibyte character.
+
+   Note that this function assumes PSTR->VALID_LEN elements are already
+   built and starts from PSTR->VALID_LEN.  */
+
+static void
+internal_function
+build_wcs_buffer (re_string_t *pstr)
+{
+#ifdef _LIBC
+  unsigned char buf[MB_LEN_MAX];
+  assert (MB_LEN_MAX >= pstr->mb_cur_max);
+#else
+  unsigned char buf[64];
+#endif
+  mbstate_t prev_st;
+  int byte_idx, end_idx, remain_len;
+  size_t mbclen;
+
+  /* Build the buffers from pstr->valid_len to either pstr->len or
+     pstr->bufs_len.  */
+  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+  for (byte_idx = pstr->valid_len; byte_idx < end_idx;)
+    {
+      wchar_t wc;
+      const char *p;
+
+      remain_len = end_idx - byte_idx;
+      prev_st = pstr->cur_state;
+      /* Apply the translation if we need.  */
+      if (BE (pstr->trans != NULL, 0))
+	{
+	  int i, ch;
+
+	  for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
+	    {
+	      ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i];
+	      buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch];
+	    }
+	  p = (const char *) buf;
+	}
+      else
+	p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx;
+      mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
+      if (BE (mbclen == (size_t) -2, 0))
+	{
+	  /* The buffer doesn't have enough space, finish to build.  */
+	  pstr->cur_state = prev_st;
+	  break;
+	}
+      else if (BE (mbclen == (size_t) -1 || mbclen == 0, 0))
+	{
+	  /* We treat these cases as a singlebyte character.  */
+	  mbclen = 1;
+	  wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
+	  if (BE (pstr->trans != NULL, 0))
+	    wc = pstr->trans[wc];
+	  pstr->cur_state = prev_st;
+	}
+
+      /* Write wide character and padding.  */
+      pstr->wcs[byte_idx++] = wc;
+      /* Write paddings.  */
+      for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
+	pstr->wcs[byte_idx++] = WEOF;
+    }
+  pstr->valid_len = byte_idx;
+  pstr->valid_raw_len = byte_idx;
+}
+
+/* Build wide character buffer PSTR->WCS like build_wcs_buffer,
+   but for REG_ICASE.  */
+
+static reg_errcode_t
+internal_function
+build_wcs_upper_buffer (re_string_t *pstr)
+{
+  mbstate_t prev_st;
+  int src_idx, byte_idx, end_idx, remain_len;
+  size_t mbclen;
+#ifdef _LIBC
+  char buf[MB_LEN_MAX];
+  assert (MB_LEN_MAX >= pstr->mb_cur_max);
+#else
+  char buf[64];
+#endif
+
+  byte_idx = pstr->valid_len;
+  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+
+  /* The following optimization assumes that ASCII characters can be
+     mapped to wide characters with a simple cast.  */
+  if (! pstr->map_notascii && pstr->trans == NULL && !pstr->offsets_needed)
+    {
+      while (byte_idx < end_idx)
+	{
+	  wchar_t wc;
+
+	  if (isascii (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx])
+	      && mbsinit (&pstr->cur_state))
+	    {
+	      /* In case of a singlebyte character.  */
+	      pstr->mbs[byte_idx]
+		= toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]);
+	      /* The next step uses the assumption that wchar_t is encoded
+		 ASCII-safe: all ASCII values can be converted like this.  */
+	      pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx];
+	      ++byte_idx;
+	      continue;
+	    }
+
+	  remain_len = end_idx - byte_idx;
+	  prev_st = pstr->cur_state;
+	  mbclen = __mbrtowc (&wc,
+			      ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
+			       + byte_idx), remain_len, &pstr->cur_state);
+	  if (BE (mbclen + 2 > 2, 1))
+	    {
+	      wchar_t wcu = wc;
+	      if (iswlower (wc))
+		{
+		  size_t mbcdlen;
+
+		  wcu = towupper (wc);
+		  mbcdlen = wcrtomb (buf, wcu, &prev_st);
+		  if (BE (mbclen == mbcdlen, 1))
+		    memcpy (pstr->mbs + byte_idx, buf, mbclen);
+		  else
+		    {
+		      src_idx = byte_idx;
+		      goto offsets_needed;
+		    }
+		}
+	      else
+		memcpy (pstr->mbs + byte_idx,
+			pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen);
+	      pstr->wcs[byte_idx++] = wcu;
+	      /* Write paddings.  */
+	      for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
+		pstr->wcs[byte_idx++] = WEOF;
+	    }
+	  else if (mbclen == (size_t) -1 || mbclen == 0)
+	    {
+	      /* It is an invalid character or '\0'.  Just use the byte.  */
+	      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
+	      pstr->mbs[byte_idx] = ch;
+	      /* And also cast it to wide char.  */
+	      pstr->wcs[byte_idx++] = (wchar_t) ch;
+	      if (BE (mbclen == (size_t) -1, 0))
+		pstr->cur_state = prev_st;
+	    }
+	  else
+	    {
+	      /* The buffer doesn't have enough space, finish to build.  */
+	      pstr->cur_state = prev_st;
+	      break;
+	    }
+	}
+      pstr->valid_len = byte_idx;
+      pstr->valid_raw_len = byte_idx;
+      return REG_NOERROR;
+    }
+  else
+    for (src_idx = pstr->valid_raw_len; byte_idx < end_idx;)
+      {
+	wchar_t wc;
+	const char *p;
+      offsets_needed:
+	remain_len = end_idx - byte_idx;
+	prev_st = pstr->cur_state;
+	if (BE (pstr->trans != NULL, 0))
+	  {
+	    int i, ch;
+
+	    for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
+	      {
+		ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i];
+		buf[i] = pstr->trans[ch];
+	      }
+	    p = (const char *) buf;
+	  }
+	else
+	  p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;
+	mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
+	if (BE (mbclen + 2 > 2, 1))
+	  {
+	    wchar_t wcu = wc;
+	    if (iswlower (wc))
+	      {
+		size_t mbcdlen;
+
+		wcu = towupper (wc);
+		mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st);
+		if (BE (mbclen == mbcdlen, 1))
+		  memcpy (pstr->mbs + byte_idx, buf, mbclen);
+		else if (mbcdlen != (size_t) -1)
+		  {
+		    size_t i;
+
+		    if (byte_idx + mbcdlen > pstr->bufs_len)
+		      {
+			pstr->cur_state = prev_st;
+			break;
+		      }
+
+		    if (pstr->offsets == NULL)
+		      {
+			pstr->offsets = re_malloc (int, pstr->bufs_len);
+
+			if (pstr->offsets == NULL)
+			  return REG_ESPACE;
+		      }
+		    if (!pstr->offsets_needed)
+		      {
+			for (i = 0; i < (size_t) byte_idx; ++i)
+			  pstr->offsets[i] = i;
+			pstr->offsets_needed = 1;
+		      }
+
+		    memcpy (pstr->mbs + byte_idx, buf, mbcdlen);
+		    pstr->wcs[byte_idx] = wcu;
+		    pstr->offsets[byte_idx] = src_idx;
+		    for (i = 1; i < mbcdlen; ++i)
+		      {
+			pstr->offsets[byte_idx + i]
+			  = src_idx + (i < mbclen ? i : mbclen - 1);
+			pstr->wcs[byte_idx + i] = WEOF;
+		      }
+		    pstr->len += mbcdlen - mbclen;
+		    if (pstr->raw_stop > src_idx)
+		      pstr->stop += mbcdlen - mbclen;
+		    end_idx = (pstr->bufs_len > pstr->len)
+			      ? pstr->len : pstr->bufs_len;
+		    byte_idx += mbcdlen;
+		    src_idx += mbclen;
+		    continue;
+		  }
+		else
+		  memcpy (pstr->mbs + byte_idx, p, mbclen);
+	      }
+	    else
+	      memcpy (pstr->mbs + byte_idx, p, mbclen);
+
+	    if (BE (pstr->offsets_needed != 0, 0))
+	      {
+		size_t i;
+		for (i = 0; i < mbclen; ++i)
+		  pstr->offsets[byte_idx + i] = src_idx + i;
+	      }
+	    src_idx += mbclen;
+
+	    pstr->wcs[byte_idx++] = wcu;
+	    /* Write paddings.  */
+	    for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
+	      pstr->wcs[byte_idx++] = WEOF;
+	  }
+	else if (mbclen == (size_t) -1 || mbclen == 0)
+	  {
+	    /* It is an invalid character or '\0'.  Just use the byte.  */
+	    int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx];
+
+	    if (BE (pstr->trans != NULL, 0))
+	      ch = pstr->trans [ch];
+	    pstr->mbs[byte_idx] = ch;
+
+	    if (BE (pstr->offsets_needed != 0, 0))
+	      pstr->offsets[byte_idx] = src_idx;
+	    ++src_idx;
+
+	    /* And also cast it to wide char.  */
+	    pstr->wcs[byte_idx++] = (wchar_t) ch;
+	    if (BE (mbclen == (size_t) -1, 0))
+	      pstr->cur_state = prev_st;
+	  }
+	else
+	  {
+	    /* The buffer doesn't have enough space, finish to build.  */
+	    pstr->cur_state = prev_st;
+	    break;
+	  }
+      }
+  pstr->valid_len = byte_idx;
+  pstr->valid_raw_len = src_idx;
+  return REG_NOERROR;
+}
+
+/* Skip characters until the index becomes greater than NEW_RAW_IDX.
+   Return the index.  */
+
+static int
+internal_function
+re_string_skip_chars (re_string_t *pstr, int new_raw_idx, wint_t *last_wc)
+{
+  mbstate_t prev_st;
+  int rawbuf_idx;
+  size_t mbclen;
+  wint_t wc = WEOF;
+
+  /* Skip the characters which are not necessary to check.  */
+  for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len;
+       rawbuf_idx < new_raw_idx;)
+    {
+      wchar_t wc2;
+      int remain_len = pstr->len - rawbuf_idx;
+      prev_st = pstr->cur_state;
+      mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx,
+			  remain_len, &pstr->cur_state);
+      if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
+	{
+	  /* We treat these cases as a single byte character.  */
+	  if (mbclen == 0 || remain_len == 0)
+	    wc = L'\0';
+	  else
+	    wc = *(unsigned char *) (pstr->raw_mbs + rawbuf_idx);
+	  mbclen = 1;
+	  pstr->cur_state = prev_st;
+	}
+      else
+	wc = (wint_t) wc2;
+      /* Then proceed the next character.  */
+      rawbuf_idx += mbclen;
+    }
+  *last_wc = (wint_t) wc;
+  return rawbuf_idx;
+}
+#endif /* RE_ENABLE_I18N  */
+
+/* Build the buffer PSTR->MBS, and apply the translation if we need.
+   This function is used in case of REG_ICASE.  */
+
+static void
+internal_function
+build_upper_buffer (re_string_t *pstr)
+{
+  int char_idx, end_idx;
+  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+
+  for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx)
+    {
+      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx];
+      if (BE (pstr->trans != NULL, 0))
+	ch = pstr->trans[ch];
+      if (islower (ch))
+	pstr->mbs[char_idx] = toupper (ch);
+      else
+	pstr->mbs[char_idx] = ch;
+    }
+  pstr->valid_len = char_idx;
+  pstr->valid_raw_len = char_idx;
+}
+
+/* Apply TRANS to the buffer in PSTR.  */
+
+static void
+internal_function
+re_string_translate_buffer (re_string_t *pstr)
+{
+  int buf_idx, end_idx;
+  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+
+  for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx)
+    {
+      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + buf_idx];
+      pstr->mbs[buf_idx] = pstr->trans[ch];
+    }
+
+  pstr->valid_len = buf_idx;
+  pstr->valid_raw_len = buf_idx;
+}
+
+/* This function re-construct the buffers.
+   Concretely, convert to wide character in case of pstr->mb_cur_max > 1,
+   convert to upper case in case of REG_ICASE, apply translation.  */
+
+static reg_errcode_t
+internal_function
+re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
+{
+  int offset = idx - pstr->raw_mbs_idx;
+  if (BE (offset < 0, 0))
+    {
+      /* Reset buffer.  */
+#ifdef RE_ENABLE_I18N
+      if (pstr->mb_cur_max > 1)
+	memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
+#endif /* RE_ENABLE_I18N */
+      pstr->len = pstr->raw_len;
+      pstr->stop = pstr->raw_stop;
+      pstr->valid_len = 0;
+      pstr->raw_mbs_idx = 0;
+      pstr->valid_raw_len = 0;
+      pstr->offsets_needed = 0;
+      pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
+			   : CONTEXT_NEWLINE | CONTEXT_BEGBUF);
+      if (!pstr->mbs_allocated)
+	pstr->mbs = (unsigned char *) pstr->raw_mbs;
+      offset = idx;
+    }
+
+  if (BE (offset != 0, 1))
+    {
+      /* Should the already checked characters be kept?  */
+      if (BE (offset < pstr->valid_raw_len, 1))
+	{
+	  /* Yes, move them to the front of the buffer.  */
+#ifdef RE_ENABLE_I18N
+	  if (BE (pstr->offsets_needed, 0))
+	    {
+	      int low = 0, high = pstr->valid_len, mid;
+	      do
+		{
+		  mid = (high + low) / 2;
+		  if (pstr->offsets[mid] > offset)
+		    high = mid;
+		  else if (pstr->offsets[mid] < offset)
+		    low = mid + 1;
+		  else
+		    break;
+		}
+	      while (low < high);
+	      if (pstr->offsets[mid] < offset)
+		++mid;
+	      pstr->tip_context = re_string_context_at (pstr, mid - 1,
+							eflags);
+	      /* This can be quite complicated, so handle specially
+		 only the common and easy case where the character with
+		 different length representation of lower and upper
+		 case is present at or after offset.  */
+	      if (pstr->valid_len > offset
+		  && mid == offset && pstr->offsets[mid] == offset)
+		{
+		  memmove (pstr->wcs, pstr->wcs + offset,
+			   (pstr->valid_len - offset) * sizeof (wint_t));
+		  memmove (pstr->mbs, pstr->mbs + offset, pstr->valid_len - offset);
+		  pstr->valid_len -= offset;
+		  pstr->valid_raw_len -= offset;
+		  for (low = 0; low < pstr->valid_len; low++)
+		    pstr->offsets[low] = pstr->offsets[low + offset] - offset;
+		}
+	      else
+		{
+		  /* Otherwise, just find out how long the partial multibyte
+		     character at offset is and fill it with WEOF/255.  */
+		  pstr->len = pstr->raw_len - idx + offset;
+		  pstr->stop = pstr->raw_stop - idx + offset;
+		  pstr->offsets_needed = 0;
+		  while (mid > 0 && pstr->offsets[mid - 1] == offset)
+		    --mid;
+		  while (mid < pstr->valid_len)
+		    if (pstr->wcs[mid] != WEOF)
+		      break;
+		    else
+		      ++mid;
+		  if (mid == pstr->valid_len)
+		    pstr->valid_len = 0;
+		  else
+		    {
+		      pstr->valid_len = pstr->offsets[mid] - offset;
+		      if (pstr->valid_len)
+			{
+			  for (low = 0; low < pstr->valid_len; ++low)
+			    pstr->wcs[low] = WEOF;
+			  memset (pstr->mbs, 255, pstr->valid_len);
+			}
+		    }
+		  pstr->valid_raw_len = pstr->valid_len;
+		}
+	    }
+	  else
+#endif
+	    {
+	      pstr->tip_context = re_string_context_at (pstr, offset - 1,
+							eflags);
+#ifdef RE_ENABLE_I18N
+	      if (pstr->mb_cur_max > 1)
+		memmove (pstr->wcs, pstr->wcs + offset,
+			 (pstr->valid_len - offset) * sizeof (wint_t));
+#endif /* RE_ENABLE_I18N */
+	      if (BE (pstr->mbs_allocated, 0))
+		memmove (pstr->mbs, pstr->mbs + offset,
+			 pstr->valid_len - offset);
+	      pstr->valid_len -= offset;
+	      pstr->valid_raw_len -= offset;
+#if DEBUG
+	      assert (pstr->valid_len > 0);
+#endif
+	    }
+	}
+      else
+	{
+#ifdef RE_ENABLE_I18N
+	  /* No, skip all characters until IDX.  */
+	  int prev_valid_len = pstr->valid_len;
+
+	  if (BE (pstr->offsets_needed, 0))
+	    {
+	      pstr->len = pstr->raw_len - idx + offset;
+	      pstr->stop = pstr->raw_stop - idx + offset;
+	      pstr->offsets_needed = 0;
+	    }
+#endif
+	  pstr->valid_len = 0;
+#ifdef RE_ENABLE_I18N
+	  if (pstr->mb_cur_max > 1)
+	    {
+	      int wcs_idx;
+	      wint_t wc = WEOF;
+
+	      if (pstr->is_utf8)
+		{
+		  const unsigned char *raw, *p, *end;
+
+		  /* Special case UTF-8.  Multi-byte chars start with any
+		     byte other than 0x80 - 0xbf.  */
+		  raw = pstr->raw_mbs + pstr->raw_mbs_idx;
+		  end = raw + (offset - pstr->mb_cur_max);
+		  if (end < pstr->raw_mbs)
+		    end = pstr->raw_mbs;
+		  p = raw + offset - 1;
+#ifdef _LIBC
+		  /* We know the wchar_t encoding is UCS4, so for the simple
+		     case, ASCII characters, skip the conversion step.  */
+		  if (isascii (*p) && BE (pstr->trans == NULL, 1))
+		    {
+		      memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
+		      /* pstr->valid_len = 0; */
+		      wc = (wchar_t) *p;
+		    }
+		  else
+#endif
+		    for (; p >= end; --p)
+		      if ((*p & 0xc0) != 0x80)
+			{
+			  mbstate_t cur_state;
+			  wchar_t wc2;
+			  int mlen = raw + pstr->len - p;
+			  unsigned char buf[6];
+			  size_t mbclen;
+
+			  if (BE (pstr->trans != NULL, 0))
+			    {
+			      int i = mlen < 6 ? mlen : 6;
+			      while (--i >= 0)
+				buf[i] = pstr->trans[p[i]];
+			    }
+			  /* XXX Don't use mbrtowc, we know which conversion
+			     to use (UTF-8 -> UCS4).  */
+			  memset (&cur_state, 0, sizeof (cur_state));
+			  mbclen = __mbrtowc (&wc2, (const char *) p, mlen,
+					      &cur_state);
+			  if (raw + offset - p <= mbclen
+			      && mbclen < (size_t) -2)
+			    {
+			      memset (&pstr->cur_state, '\0',
+				      sizeof (mbstate_t));
+			      pstr->valid_len = mbclen - (raw + offset - p);
+			      wc = wc2;
+			    }
+			  break;
+			}
+		}
+
+	      if (wc == WEOF)
+		pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx;
+	      if (wc == WEOF)
+		pstr->tip_context
+		  = re_string_context_at (pstr, prev_valid_len - 1, eflags);
+	      else
+		pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0)
+				      && IS_WIDE_WORD_CHAR (wc))
+				     ? CONTEXT_WORD
+				     : ((IS_WIDE_NEWLINE (wc)
+					 && pstr->newline_anchor)
+					? CONTEXT_NEWLINE : 0));
+	      if (BE (pstr->valid_len, 0))
+		{
+		  for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
+		    pstr->wcs[wcs_idx] = WEOF;
+		  if (pstr->mbs_allocated)
+		    memset (pstr->mbs, 255, pstr->valid_len);
+		}
+	      pstr->valid_raw_len = pstr->valid_len;
+	    }
+	  else
+#endif /* RE_ENABLE_I18N */
+	    {
+	      int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1];
+	      pstr->valid_raw_len = 0;
+	      if (pstr->trans)
+		c = pstr->trans[c];
+	      pstr->tip_context = (bitset_contain (pstr->word_char, c)
+				   ? CONTEXT_WORD
+				   : ((IS_NEWLINE (c) && pstr->newline_anchor)
+				      ? CONTEXT_NEWLINE : 0));
+	    }
+	}
+      if (!BE (pstr->mbs_allocated, 0))
+	pstr->mbs += offset;
+    }
+  pstr->raw_mbs_idx = idx;
+  pstr->len -= offset;
+  pstr->stop -= offset;
+
+  /* Then build the buffers.  */
+#ifdef RE_ENABLE_I18N
+  if (pstr->mb_cur_max > 1)
+    {
+      if (pstr->icase)
+	{
+	  reg_errcode_t ret = build_wcs_upper_buffer (pstr);
+	  if (BE (ret != REG_NOERROR, 0))
+	    return ret;
+	}
+      else
+	build_wcs_buffer (pstr);
+    }
+  else
+#endif /* RE_ENABLE_I18N */
+    if (BE (pstr->mbs_allocated, 0))
+      {
+	if (pstr->icase)
+	  build_upper_buffer (pstr);
+	else if (pstr->trans != NULL)
+	  re_string_translate_buffer (pstr);
+      }
+    else
+      pstr->valid_len = pstr->len;
+
+  pstr->cur_idx = 0;
+  return REG_NOERROR;
+}
+
+static unsigned char
+internal_function __attribute ((pure))
+re_string_peek_byte_case (const re_string_t *pstr, int idx)
+{
+  int ch, off;
+
+  /* Handle the common (easiest) cases first.  */
+  if (BE (!pstr->mbs_allocated, 1))
+    return re_string_peek_byte (pstr, idx);
+
+#ifdef RE_ENABLE_I18N
+  if (pstr->mb_cur_max > 1
+      && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
+    return re_string_peek_byte (pstr, idx);
+#endif
+
+  off = pstr->cur_idx + idx;
+#ifdef RE_ENABLE_I18N
+  if (pstr->offsets_needed)
+    off = pstr->offsets[off];
+#endif
+
+  ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
+
+#ifdef RE_ENABLE_I18N
+  /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I
+     this function returns CAPITAL LETTER I instead of first byte of
+     DOTLESS SMALL LETTER I.  The latter would confuse the parser,
+     since peek_byte_case doesn't advance cur_idx in any way.  */
+  if (pstr->offsets_needed && !isascii (ch))
+    return re_string_peek_byte (pstr, idx);
+#endif
+
+  return ch;
+}
+
+static unsigned char
+internal_function __attribute ((pure))
+re_string_fetch_byte_case (re_string_t *pstr)
+{
+  if (BE (!pstr->mbs_allocated, 1))
+    return re_string_fetch_byte (pstr);
+
+#ifdef RE_ENABLE_I18N
+  if (pstr->offsets_needed)
+    {
+      int off, ch;
+
+      /* For tr_TR.UTF-8 [[:islower:]] there is
+	 [[: CAPITAL LETTER I WITH DOT lower:]] in mbs.  Skip
+	 in that case the whole multi-byte character and return
+	 the original letter.  On the other side, with
+	 [[: DOTLESS SMALL LETTER I return [[:I, as doing
+	 anything else would complicate things too much.  */
+
+      if (!re_string_first_byte (pstr, pstr->cur_idx))
+	return re_string_fetch_byte (pstr);
+
+      off = pstr->offsets[pstr->cur_idx];
+      ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
+
+      if (! isascii (ch))
+	return re_string_fetch_byte (pstr);
+
+      re_string_skip_bytes (pstr,
+			    re_string_char_size_at (pstr, pstr->cur_idx));
+      return ch;
+    }
+#endif
+
+  return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++];
+}
+
+static void
+internal_function
+re_string_destruct (re_string_t *pstr)
+{
+#ifdef RE_ENABLE_I18N
+  re_free (pstr->wcs);
+  re_free (pstr->offsets);
+#endif /* RE_ENABLE_I18N  */
+  if (pstr->mbs_allocated)
+    re_free (pstr->mbs);
+}
+
+/* Return the context at IDX in INPUT.  */
+
+static unsigned int
+internal_function
+re_string_context_at (const re_string_t *input, int idx, int eflags)
+{
+  int c;
+  if (BE (idx < 0, 0))
+    /* In this case, we use the value stored in input->tip_context,
+       since we can't know the character in input->mbs[-1] here.  */
+    return input->tip_context;
+  if (BE (idx == input->len, 0))
+    return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
+	    : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
+#ifdef RE_ENABLE_I18N
+  if (input->mb_cur_max > 1)
+    {
+      wint_t wc;
+      int wc_idx = idx;
+      while(input->wcs[wc_idx] == WEOF)
+	{
+#ifdef DEBUG
+	  /* It must not happen.  */
+	  assert (wc_idx >= 0);
+#endif
+	  --wc_idx;
+	  if (wc_idx < 0)
+	    return input->tip_context;
+	}
+      wc = input->wcs[wc_idx];
+      if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc))
+	return CONTEXT_WORD;
+      return (IS_WIDE_NEWLINE (wc) && input->newline_anchor
+	      ? CONTEXT_NEWLINE : 0);
+    }
+  else
+#endif
+    {
+      c = re_string_byte_at (input, idx);
+      if (bitset_contain (input->word_char, c))
+	return CONTEXT_WORD;
+      return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0;
+    }
+}
+
+/* Functions for set operation.  */
+
+static reg_errcode_t
+internal_function
+re_node_set_alloc (re_node_set *set, int size)
+{
+  /*
+   * ADR: valgrind says size can be 0, which then doesn't
+   * free the block of size 0.  Harumph. This seems
+   * to work ok, though.
+   */
+  if (size == 0)
+    {
+       memset(set, 0, sizeof(*set));
+       return REG_NOERROR;
+    }
+  set->alloc = size;
+  set->nelem = 0;
+  set->elems = re_malloc (int, size);
+  if (BE (set->elems == NULL, 0))
+    return REG_ESPACE;
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function
+re_node_set_init_1 (re_node_set *set, int elem)
+{
+  set->alloc = 1;
+  set->nelem = 1;
+  set->elems = re_malloc (int, 1);
+  if (BE (set->elems == NULL, 0))
+    {
+      set->alloc = set->nelem = 0;
+      return REG_ESPACE;
+    }
+  set->elems[0] = elem;
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function
+re_node_set_init_2 (re_node_set *set, int elem1, int elem2)
+{
+  set->alloc = 2;
+  set->elems = re_malloc (int, 2);
+  if (BE (set->elems == NULL, 0))
+    return REG_ESPACE;
+  if (elem1 == elem2)
+    {
+      set->nelem = 1;
+      set->elems[0] = elem1;
+    }
+  else
+    {
+      set->nelem = 2;
+      if (elem1 < elem2)
+	{
+	  set->elems[0] = elem1;
+	  set->elems[1] = elem2;
+	}
+      else
+	{
+	  set->elems[0] = elem2;
+	  set->elems[1] = elem1;
+	}
+    }
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function
+re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
+{
+  dest->nelem = src->nelem;
+  if (src->nelem > 0)
+    {
+      dest->alloc = dest->nelem;
+      dest->elems = re_malloc (int, dest->alloc);
+      if (BE (dest->elems == NULL, 0))
+	{
+	  dest->alloc = dest->nelem = 0;
+	  return REG_ESPACE;
+	}
+      memcpy (dest->elems, src->elems, src->nelem * sizeof (int));
+    }
+  else
+    re_node_set_init_empty (dest);
+  return REG_NOERROR;
+}
+
+/* Calculate the intersection of the sets SRC1 and SRC2. And merge it to
+   DEST. Return value indicate the error code or REG_NOERROR if succeeded.
+   Note: We assume dest->elems is NULL, when dest->alloc is 0.  */
+
+static reg_errcode_t
+internal_function
+re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
+			   const re_node_set *src2)
+{
+  int i1, i2, is, id, delta, sbase;
+  if (src1->nelem == 0 || src2->nelem == 0)
+    return REG_NOERROR;
+
+  /* We need dest->nelem + 2 * elems_in_intersection; this is a
+     conservative estimate.  */
+  if (src1->nelem + src2->nelem + dest->nelem > dest->alloc)
+    {
+      int new_alloc = src1->nelem + src2->nelem + dest->alloc;
+      int *new_elems = re_realloc (dest->elems, int, new_alloc);
+      if (BE (new_elems == NULL, 0))
+	return REG_ESPACE;
+      dest->elems = new_elems;
+      dest->alloc = new_alloc;
+    }
+
+  /* Find the items in the intersection of SRC1 and SRC2, and copy
+     into the top of DEST those that are not already in DEST itself.  */
+  sbase = dest->nelem + src1->nelem + src2->nelem;
+  i1 = src1->nelem - 1;
+  i2 = src2->nelem - 1;
+  id = dest->nelem - 1;
+  for (;;)
+    {
+      if (src1->elems[i1] == src2->elems[i2])
+	{
+	  /* Try to find the item in DEST.  Maybe we could binary search?  */
+	  while (id >= 0 && dest->elems[id] > src1->elems[i1])
+	    --id;
+
+	  if (id < 0 || dest->elems[id] != src1->elems[i1])
+	    dest->elems[--sbase] = src1->elems[i1];
+
+	  if (--i1 < 0 || --i2 < 0)
+	    break;
+	}
+
+      /* Lower the highest of the two items.  */
+      else if (src1->elems[i1] < src2->elems[i2])
+	{
+	  if (--i2 < 0)
+	    break;
+	}
+      else
+	{
+	  if (--i1 < 0)
+	    break;
+	}
+    }
+
+  id = dest->nelem - 1;
+  is = dest->nelem + src1->nelem + src2->nelem - 1;
+  delta = is - sbase + 1;
+
+  /* Now copy.  When DELTA becomes zero, the remaining
+     DEST elements are already in place; this is more or
+     less the same loop that is in re_node_set_merge.  */
+  dest->nelem += delta;
+  if (delta > 0 && id >= 0)
+    for (;;)
+      {
+	if (dest->elems[is] > dest->elems[id])
+	  {
+	    /* Copy from the top.  */
+	    dest->elems[id + delta--] = dest->elems[is--];
+	    if (delta == 0)
+	      break;
+	  }
+	else
+	  {
+	    /* Slide from the bottom.  */
+	    dest->elems[id + delta] = dest->elems[id];
+	    if (--id < 0)
+	      break;
+	  }
+      }
+
+  /* Copy remaining SRC elements.  */
+  memcpy (dest->elems, dest->elems + sbase, delta * sizeof (int));
+
+  return REG_NOERROR;
+}
+
+/* Calculate the union set of the sets SRC1 and SRC2. And store it to
+   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
+
+static reg_errcode_t
+internal_function
+re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
+			const re_node_set *src2)
+{
+  int i1, i2, id;
+  if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0)
+    {
+      dest->alloc = src1->nelem + src2->nelem;
+      dest->elems = re_malloc (int, dest->alloc);
+      if (BE (dest->elems == NULL, 0))
+	return REG_ESPACE;
+    }
+  else
+    {
+      if (src1 != NULL && src1->nelem > 0)
+	return re_node_set_init_copy (dest, src1);
+      else if (src2 != NULL && src2->nelem > 0)
+	return re_node_set_init_copy (dest, src2);
+      else
+	re_node_set_init_empty (dest);
+      return REG_NOERROR;
+    }
+  for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;)
+    {
+      if (src1->elems[i1] > src2->elems[i2])
+	{
+	  dest->elems[id++] = src2->elems[i2++];
+	  continue;
+	}
+      if (src1->elems[i1] == src2->elems[i2])
+	++i2;
+      dest->elems[id++] = src1->elems[i1++];
+    }
+  if (i1 < src1->nelem)
+    {
+      memcpy (dest->elems + id, src1->elems + i1,
+	     (src1->nelem - i1) * sizeof (int));
+      id += src1->nelem - i1;
+    }
+  else if (i2 < src2->nelem)
+    {
+      memcpy (dest->elems + id, src2->elems + i2,
+	     (src2->nelem - i2) * sizeof (int));
+      id += src2->nelem - i2;
+    }
+  dest->nelem = id;
+  return REG_NOERROR;
+}
+
+/* Calculate the union set of the sets DEST and SRC. And store it to
+   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
+
+static reg_errcode_t
+internal_function
+re_node_set_merge (re_node_set *dest, const re_node_set *src)
+{
+  int is, id, sbase, delta;
+  if (src == NULL || src->nelem == 0)
+    return REG_NOERROR;
+  if (dest->alloc < 2 * src->nelem + dest->nelem)
+    {
+      int new_alloc = 2 * (src->nelem + dest->alloc);
+      int *new_buffer = re_realloc (dest->elems, int, new_alloc);
+      if (BE (new_buffer == NULL, 0))
+	return REG_ESPACE;
+      dest->elems = new_buffer;
+      dest->alloc = new_alloc;
+    }
+
+  if (BE (dest->nelem == 0, 0))
+    {
+      dest->nelem = src->nelem;
+      memcpy (dest->elems, src->elems, src->nelem * sizeof (int));
+      return REG_NOERROR;
+    }
+
+  /* Copy into the top of DEST the items of SRC that are not
+     found in DEST.  Maybe we could binary search in DEST?  */
+  for (sbase = dest->nelem + 2 * src->nelem,
+       is = src->nelem - 1, id = dest->nelem - 1; is >= 0 && id >= 0; )
+    {
+      if (dest->elems[id] == src->elems[is])
+	is--, id--;
+      else if (dest->elems[id] < src->elems[is])
+	dest->elems[--sbase] = src->elems[is--];
+      else /* if (dest->elems[id] > src->elems[is]) */
+	--id;
+    }
+
+  if (is >= 0)
+    {
+      /* If DEST is exhausted, the remaining items of SRC must be unique.  */
+      sbase -= is + 1;
+      memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (int));
+    }
+
+  id = dest->nelem - 1;
+  is = dest->nelem + 2 * src->nelem - 1;
+  delta = is - sbase + 1;
+  if (delta == 0)
+    return REG_NOERROR;
+
+  /* Now copy.  When DELTA becomes zero, the remaining
+     DEST elements are already in place.  */
+  dest->nelem += delta;
+  for (;;)
+    {
+      if (dest->elems[is] > dest->elems[id])
+	{
+	  /* Copy from the top.  */
+	  dest->elems[id + delta--] = dest->elems[is--];
+	  if (delta == 0)
+	    break;
+	}
+      else
+	{
+	  /* Slide from the bottom.  */
+	  dest->elems[id + delta] = dest->elems[id];
+	  if (--id < 0)
+	    {
+	      /* Copy remaining SRC elements.  */
+	      memcpy (dest->elems, dest->elems + sbase,
+		      delta * sizeof (int));
+	      break;
+	    }
+	}
+    }
+
+  return REG_NOERROR;
+}
+
+/* Insert the new element ELEM to the re_node_set* SET.
+   SET should not already have ELEM.
+   return -1 if an error is occured, return 1 otherwise.  */
+
+static int
+internal_function
+re_node_set_insert (re_node_set *set, int elem)
+{
+  int idx;
+  /* In case the set is empty.  */
+  if (set->alloc == 0)
+    {
+      if (BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1))
+	return 1;
+      else
+	return -1;
+    }
+
+  if (BE (set->nelem, 0) == 0)
+    {
+      /* We already guaranteed above that set->alloc != 0.  */
+      set->elems[0] = elem;
+      ++set->nelem;
+      return 1;
+    }
+
+  /* Realloc if we need.  */
+  if (set->alloc == set->nelem)
+    {
+      int *new_elems;
+      set->alloc = set->alloc * 2;
+      new_elems = re_realloc (set->elems, int, set->alloc);
+      if (BE (new_elems == NULL, 0))
+	return -1;
+      set->elems = new_elems;
+    }
+
+  /* Move the elements which follows the new element.  Test the
+     first element separately to skip a check in the inner loop.  */
+  if (elem < set->elems[0])
+    {
+      idx = 0;
+      for (idx = set->nelem; idx > 0; idx--)
+	set->elems[idx] = set->elems[idx - 1];
+    }
+  else
+    {
+      for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
+	set->elems[idx] = set->elems[idx - 1];
+    }
+
+  /* Insert the new element.  */
+  set->elems[idx] = elem;
+  ++set->nelem;
+  return 1;
+}
+
+/* Insert the new element ELEM to the re_node_set* SET.
+   SET should not already have any element greater than or equal to ELEM.
+   Return -1 if an error is occured, return 1 otherwise.  */
+
+static int
+internal_function
+re_node_set_insert_last (re_node_set *set, int elem)
+{
+  /* Realloc if we need.  */
+  if (set->alloc == set->nelem)
+    {
+      int *new_elems;
+      set->alloc = (set->alloc + 1) * 2;
+      new_elems = re_realloc (set->elems, int, set->alloc);
+      if (BE (new_elems == NULL, 0))
+	return -1;
+      set->elems = new_elems;
+    }
+
+  /* Insert the new element.  */
+  set->elems[set->nelem++] = elem;
+  return 1;
+}
+
+/* Compare two node sets SET1 and SET2.
+   return 1 if SET1 and SET2 are equivalent, return 0 otherwise.  */
+
+static int
+internal_function __attribute ((pure))
+re_node_set_compare (const re_node_set *set1, const re_node_set *set2)
+{
+  int i;
+  if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem)
+    return 0;
+  for (i = set1->nelem ; --i >= 0 ; )
+    if (set1->elems[i] != set2->elems[i])
+      return 0;
+  return 1;
+}
+
+/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise.  */
+
+static int
+internal_function __attribute ((pure))
+re_node_set_contains (const re_node_set *set, int elem)
+{
+  unsigned int idx, right, mid;
+  if (set->nelem <= 0)
+    return 0;
+
+  /* Binary search the element.  */
+  idx = 0;
+  right = set->nelem - 1;
+  while (idx < right)
+    {
+      mid = (idx + right) / 2;
+      if (set->elems[mid] < elem)
+	idx = mid + 1;
+      else
+	right = mid;
+    }
+  return set->elems[idx] == elem ? idx + 1 : 0;
+}
+
+static void
+internal_function
+re_node_set_remove_at (re_node_set *set, int idx)
+{
+  if (idx < 0 || idx >= set->nelem)
+    return;
+  --set->nelem;
+  for (; idx < set->nelem; idx++)
+    set->elems[idx] = set->elems[idx + 1];
+}
+
+
+/* Add the token TOKEN to dfa->nodes, and return the index of the token.
+   Or return -1, if an error will be occured.  */
+
+static int
+internal_function
+re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
+{
+  if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0))
+    {
+      size_t new_nodes_alloc = dfa->nodes_alloc * 2;
+      int *new_nexts, *new_indices;
+      re_node_set *new_edests, *new_eclosures;
+      re_token_t *new_nodes;
+
+      /* Avoid overflows in realloc.  */
+      const size_t max_object_size = MAX (sizeof (re_token_t),
+					  MAX (sizeof (re_node_set),
+					       sizeof (int)));
+      if (BE (SIZE_MAX / max_object_size < new_nodes_alloc, 0))
+	return -1;
+
+      new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc);
+      if (BE (new_nodes == NULL, 0))
+	return -1;
+      dfa->nodes = new_nodes;
+      new_nexts = re_realloc (dfa->nexts, int, new_nodes_alloc);
+      new_indices = re_realloc (dfa->org_indices, int, new_nodes_alloc);
+      new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc);
+      new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc);
+      if (BE (new_nexts == NULL || new_indices == NULL
+	      || new_edests == NULL || new_eclosures == NULL, 0))
+	return -1;
+      dfa->nexts = new_nexts;
+      dfa->org_indices = new_indices;
+      dfa->edests = new_edests;
+      dfa->eclosures = new_eclosures;
+      dfa->nodes_alloc = new_nodes_alloc;
+    }
+  dfa->nodes[dfa->nodes_len] = token;
+  dfa->nodes[dfa->nodes_len].constraint = 0;
+#ifdef RE_ENABLE_I18N
+  dfa->nodes[dfa->nodes_len].accept_mb =
+    (token.type == OP_PERIOD && dfa->mb_cur_max > 1) || token.type == COMPLEX_BRACKET;
+#endif
+  dfa->nexts[dfa->nodes_len] = -1;
+  re_node_set_init_empty (dfa->edests + dfa->nodes_len);
+  re_node_set_init_empty (dfa->eclosures + dfa->nodes_len);
+  return dfa->nodes_len++;
+}
+
+static inline unsigned int
+internal_function
+calc_state_hash (const re_node_set *nodes, unsigned int context)
+{
+  unsigned int hash = nodes->nelem + context;
+  int i;
+  for (i = 0 ; i < nodes->nelem ; i++)
+    hash += nodes->elems[i];
+  return hash;
+}
+
+/* Search for the state whose node_set is equivalent to NODES.
+   Return the pointer to the state, if we found it in the DFA.
+   Otherwise create the new one and return it.  In case of an error
+   return NULL and set the error code in ERR.
+   Note: - We assume NULL as the invalid state, then it is possible that
+	   return value is NULL and ERR is REG_NOERROR.
+	 - We never return non-NULL value in case of any errors, it is for
+	   optimization.  */
+
+static re_dfastate_t *
+internal_function
+re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
+		  const re_node_set *nodes)
+{
+  unsigned int hash;
+  re_dfastate_t *new_state;
+  struct re_state_table_entry *spot;
+  int i;
+  if (BE (nodes->nelem == 0, 0))
+    {
+      *err = REG_NOERROR;
+      return NULL;
+    }
+  hash = calc_state_hash (nodes, 0);
+  spot = dfa->state_table + (hash & dfa->state_hash_mask);
+
+  for (i = 0 ; i < spot->num ; i++)
+    {
+      re_dfastate_t *state = spot->array[i];
+      if (hash != state->hash)
+	continue;
+      if (re_node_set_compare (&state->nodes, nodes))
+	return state;
+    }
+
+  /* There are no appropriate state in the dfa, create the new one.  */
+  new_state = create_ci_newstate (dfa, nodes, hash);
+  if (BE (new_state == NULL, 0))
+    *err = REG_ESPACE;
+
+  return new_state;
+}
+
+/* Search for the state whose node_set is equivalent to NODES and
+   whose context is equivalent to CONTEXT.
+   Return the pointer to the state, if we found it in the DFA.
+   Otherwise create the new one and return it.  In case of an error
+   return NULL and set the error code in ERR.
+   Note: - We assume NULL as the invalid state, then it is possible that
+	   return value is NULL and ERR is REG_NOERROR.
+	 - We never return non-NULL value in case of any errors, it is for
+	   optimization.  */
+
+static re_dfastate_t *
+internal_function
+re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
+			  const re_node_set *nodes, unsigned int context)
+{
+  unsigned int hash;
+  re_dfastate_t *new_state;
+  struct re_state_table_entry *spot;
+  int i;
+  if (nodes->nelem == 0)
+    {
+      *err = REG_NOERROR;
+      return NULL;
+    }
+  hash = calc_state_hash (nodes, context);
+  spot = dfa->state_table + (hash & dfa->state_hash_mask);
+
+  for (i = 0 ; i < spot->num ; i++)
+    {
+      re_dfastate_t *state = spot->array[i];
+      if (state->hash == hash
+	  && state->context == context
+	  && re_node_set_compare (state->entrance_nodes, nodes))
+	return state;
+    }
+  /* There are no appropriate state in `dfa', create the new one.  */
+  new_state = create_cd_newstate (dfa, nodes, context, hash);
+  if (BE (new_state == NULL, 0))
+    *err = REG_ESPACE;
+
+  return new_state;
+}
+
+/* Finish initialization of the new state NEWSTATE, and using its hash value
+   HASH put in the appropriate bucket of DFA's state table.  Return value
+   indicates the error code if failed.  */
+
+static reg_errcode_t
+register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
+		unsigned int hash)
+{
+  struct re_state_table_entry *spot;
+  reg_errcode_t err;
+  int i;
+
+  newstate->hash = hash;
+  err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem);
+  if (BE (err != REG_NOERROR, 0))
+    return REG_ESPACE;
+  for (i = 0; i < newstate->nodes.nelem; i++)
+    {
+      int elem = newstate->nodes.elems[i];
+      if (!IS_EPSILON_NODE (dfa->nodes[elem].type))
+	if (re_node_set_insert_last (&newstate->non_eps_nodes, elem) < 0)
+	  return REG_ESPACE;
+    }
+
+  spot = dfa->state_table + (hash & dfa->state_hash_mask);
+  if (BE (spot->alloc <= spot->num, 0))
+    {
+      int new_alloc = 2 * spot->num + 2;
+      re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *,
+					      new_alloc);
+      if (BE (new_array == NULL, 0))
+	return REG_ESPACE;
+      spot->array = new_array;
+      spot->alloc = new_alloc;
+    }
+  spot->array[spot->num++] = newstate;
+  return REG_NOERROR;
+}
+
+static void
+free_state (re_dfastate_t *state)
+{
+  re_node_set_free (&state->non_eps_nodes);
+  re_node_set_free (&state->inveclosure);
+  if (state->entrance_nodes != &state->nodes)
+    {
+      re_node_set_free (state->entrance_nodes);
+      re_free (state->entrance_nodes);
+    }
+  re_node_set_free (&state->nodes);
+  re_free (state->word_trtable);
+  re_free (state->trtable);
+  re_free (state);
+}
+
+/* Create the new state which is independ of contexts.
+   Return the new state if succeeded, otherwise return NULL.  */
+
+static re_dfastate_t *
+internal_function
+create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
+		    unsigned int hash)
+{
+  int i;
+  reg_errcode_t err;
+  re_dfastate_t *newstate;
+
+  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
+  if (BE (newstate == NULL, 0))
+    return NULL;
+  err = re_node_set_init_copy (&newstate->nodes, nodes);
+  if (BE (err != REG_NOERROR, 0))
+    {
+      re_free (newstate);
+      return NULL;
+    }
+
+  newstate->entrance_nodes = &newstate->nodes;
+  for (i = 0 ; i < nodes->nelem ; i++)
+    {
+      re_token_t *node = dfa->nodes + nodes->elems[i];
+      re_token_type_t type = node->type;
+      if (type == CHARACTER && !node->constraint)
+	continue;
+#ifdef RE_ENABLE_I18N
+      newstate->accept_mb |= node->accept_mb;
+#endif /* RE_ENABLE_I18N */
+
+      /* If the state has the halt node, the state is a halt state.  */
+      if (type == END_OF_RE)
+	newstate->halt = 1;
+      else if (type == OP_BACK_REF)
+	newstate->has_backref = 1;
+      else if (type == ANCHOR || node->constraint)
+	newstate->has_constraint = 1;
+    }
+  err = register_state (dfa, newstate, hash);
+  if (BE (err != REG_NOERROR, 0))
+    {
+      free_state (newstate);
+      newstate = NULL;
+    }
+  return newstate;
+}
+
+/* Create the new state which is depend on the context CONTEXT.
+   Return the new state if succeeded, otherwise return NULL.  */
+
+static re_dfastate_t *
+internal_function
+create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
+		    unsigned int context, unsigned int hash)
+{
+  int i, nctx_nodes = 0;
+  reg_errcode_t err;
+  re_dfastate_t *newstate;
+
+  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
+  if (BE (newstate == NULL, 0))
+    return NULL;
+  err = re_node_set_init_copy (&newstate->nodes, nodes);
+  if (BE (err != REG_NOERROR, 0))
+    {
+      re_free (newstate);
+      return NULL;
+    }
+
+  newstate->context = context;
+  newstate->entrance_nodes = &newstate->nodes;
+
+  for (i = 0 ; i < nodes->nelem ; i++)
+    {
+      re_token_t *node = dfa->nodes + nodes->elems[i];
+      re_token_type_t type = node->type;
+      unsigned int constraint = node->constraint;
+
+      if (type == CHARACTER && !constraint)
+	continue;
+#ifdef RE_ENABLE_I18N
+      newstate->accept_mb |= node->accept_mb;
+#endif /* RE_ENABLE_I18N */
+
+      /* If the state has the halt node, the state is a halt state.  */
+      if (type == END_OF_RE)
+	newstate->halt = 1;
+      else if (type == OP_BACK_REF)
+	newstate->has_backref = 1;
+
+      if (constraint)
+	{
+	  if (newstate->entrance_nodes == &newstate->nodes)
+	    {
+	      newstate->entrance_nodes = re_malloc (re_node_set, 1);
+	      if (BE (newstate->entrance_nodes == NULL, 0))
+		{
+		  free_state (newstate);
+		  return NULL;
+		}
+	      if (re_node_set_init_copy (newstate->entrance_nodes, nodes)
+		  != REG_NOERROR)
+		return NULL;
+	      nctx_nodes = 0;
+	      newstate->has_constraint = 1;
+	    }
+
+	  if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context))
+	    {
+	      re_node_set_remove_at (&newstate->nodes, i - nctx_nodes);
+	      ++nctx_nodes;
+	    }
+	}
+    }
+  err = register_state (dfa, newstate, hash);
+  if (BE (err != REG_NOERROR, 0))
+    {
+      free_state (newstate);
+      newstate = NULL;
+    }
+  return  newstate;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regex_internal.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regex_internal.h
new file mode 100755
index 0000000..53ccebe
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regex_internal.h
@@ -0,0 +1,819 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002-2005, 2007, 2008, 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu at yamato.ibm.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _REGEX_INTERNAL_H
+#define _REGEX_INTERNAL_H 1
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef UNUSED
+#	ifdef __GNUC__
+#		define UNUSED __attribute__((unused))
+#	else
+#		define UNUSED
+#	endif
+#endif
+
+#if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET || defined _LIBC
+# include <langinfo.h>
+#endif
+#if defined HAVE_LOCALE_H || defined _LIBC
+# include <locale.h>
+#endif
+#if defined HAVE_WCHAR_H || defined _LIBC
+# include <wchar.h>
+#endif /* HAVE_WCHAR_H || _LIBC */
+#if defined HAVE_WCTYPE_H || defined _LIBC
+# include <wctype.h>
+#endif /* HAVE_WCTYPE_H || _LIBC */
+#if defined HAVE_STDBOOL_H || defined _LIBC
+# include <stdbool.h>
+#endif /* HAVE_STDBOOL_H || _LIBC */
+#if !defined(ZOS_USS)
+#if defined HAVE_STDINT_H || defined _LIBC
+# include <stdint.h>
+#endif /* HAVE_STDINT_H || _LIBC */
+#endif /* !ZOS_USS */
+#if defined _LIBC
+# include <bits/libc-lock.h>
+#else
+# define __libc_lock_define(CLASS,NAME)
+# define __libc_lock_init(NAME) do { } while (0)
+# define __libc_lock_lock(NAME) do { } while (0)
+# define __libc_lock_unlock(NAME) do { } while (0)
+#endif
+
+#ifndef GAWK
+/* In case that the system doesn't have isblank().  */
+#if !defined _LIBC && !defined HAVE_ISBLANK && !defined isblank
+# define isblank(ch) ((ch) == ' ' || (ch) == '\t')
+#endif
+#else /* GAWK */
+/*
+ * This is a mess. On glibc systems you have to define
+ * a magic constant to get isblank() out of <ctype.h>, since it's
+ * a C99 function.  To heck with all that and borrow a page from
+ * dfa.c's book.
+ */
+
+static int
+is_blank (int c)
+{
+   return (c == ' ' || c == '\t');
+}
+#endif /* GAWK */
+
+#ifdef _LIBC
+# ifndef _RE_DEFINE_LOCALE_FUNCTIONS
+#  define _RE_DEFINE_LOCALE_FUNCTIONS 1
+#   include <locale/localeinfo.h>
+#   include <locale/elem-hash.h>
+#   include <locale/coll-lookup.h>
+# endif
+#endif
+
+/* This is for other GNU distributions with internationalized messages.  */
+#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
+# include <libintl.h>
+# ifdef _LIBC
+#  undef gettext
+#  define gettext(msgid) \
+  INTUSE(__dcgettext) (_libc_intl_domainname, msgid, LC_MESSAGES)
+# endif
+#else
+# define gettext(msgid) (msgid)
+#endif
+
+#ifndef gettext_noop
+/* This define is so xgettext can find the internationalizable
+   strings.  */
+# define gettext_noop(String) String
+#endif
+
+/* For loser systems without the definition.  */
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+
+#ifndef NO_MBSUPPORT
+#include "mbsupport.h" /* gawk */
+#endif
+#ifndef MB_CUR_MAX
+#define MB_CUR_MAX 1
+#endif
+
+#if (defined MBS_SUPPORT) || _LIBC
+# define RE_ENABLE_I18N
+#endif
+
+#if __GNUC__ >= 3
+# define BE(expr, val) __builtin_expect (expr, val)
+#else
+# define BE(expr, val) (expr)
+# ifdef inline
+# undef inline
+# endif
+# define inline
+#endif
+
+/* Number of single byte character.  */
+#define SBC_MAX 256
+
+#define COLL_ELEM_LEN_MAX 8
+
+/* The character which represents newline.  */
+#define NEWLINE_CHAR '\n'
+#define WIDE_NEWLINE_CHAR L'\n'
+
+/* Rename to standard API for using out of glibc.  */
+#ifndef _LIBC
+# ifdef __wctype
+# undef __wctype
+# endif
+# define __wctype wctype
+# ifdef __iswctype
+# undef __iswctype
+# endif
+# define __iswctype iswctype
+# define __btowc btowc
+# define __mbrtowc mbrtowc
+#undef __mempcpy	/* GAWK */
+# define __mempcpy mempcpy
+# define __wcrtomb wcrtomb
+# define __regfree regfree
+# define attribute_hidden
+#endif /* not _LIBC */
+
+#ifdef __GNUC__
+# define __attribute(arg) __attribute__ (arg)
+#else
+# define __attribute(arg)
+#endif
+
+extern const char __re_error_msgid[] attribute_hidden;
+extern const size_t __re_error_msgid_idx[] attribute_hidden;
+
+/* An integer used to represent a set of bits.  It must be unsigned,
+   and must be at least as wide as unsigned int.  */
+typedef unsigned long int bitset_word_t;
+/* All bits set in a bitset_word_t.  */
+#define BITSET_WORD_MAX ULONG_MAX
+/* Number of bits in a bitset_word_t. Cast to int as most code use it
+ * like that for counting */
+#define BITSET_WORD_BITS ((int)(sizeof (bitset_word_t) * CHAR_BIT))
+/* Number of bitset_word_t in a bit_set.  */
+#define BITSET_WORDS (SBC_MAX / BITSET_WORD_BITS)
+typedef bitset_word_t bitset_t[BITSET_WORDS];
+typedef bitset_word_t *re_bitset_ptr_t;
+typedef const bitset_word_t *re_const_bitset_ptr_t;
+
+#define bitset_set(set,i) \
+  (set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS)
+#define bitset_clear(set,i) \
+  (set[i / BITSET_WORD_BITS] &= ~((bitset_word_t) 1 << i % BITSET_WORD_BITS))
+#define bitset_contain(set,i) \
+  (set[i / BITSET_WORD_BITS] & ((bitset_word_t) 1 << i % BITSET_WORD_BITS))
+#define bitset_empty(set) memset (set, '\0', sizeof (bitset_t))
+#define bitset_set_all(set) memset (set, '\xff', sizeof (bitset_t))
+#define bitset_copy(dest,src) memcpy (dest, src, sizeof (bitset_t))
+
+#define PREV_WORD_CONSTRAINT 0x0001
+#define PREV_NOTWORD_CONSTRAINT 0x0002
+#define NEXT_WORD_CONSTRAINT 0x0004
+#define NEXT_NOTWORD_CONSTRAINT 0x0008
+#define PREV_NEWLINE_CONSTRAINT 0x0010
+#define NEXT_NEWLINE_CONSTRAINT 0x0020
+#define PREV_BEGBUF_CONSTRAINT 0x0040
+#define NEXT_ENDBUF_CONSTRAINT 0x0080
+#define WORD_DELIM_CONSTRAINT 0x0100
+#define NOT_WORD_DELIM_CONSTRAINT 0x0200
+
+typedef enum
+{
+  INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
+  WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
+  WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
+  INSIDE_NOTWORD = PREV_NOTWORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
+  LINE_FIRST = PREV_NEWLINE_CONSTRAINT,
+  LINE_LAST = NEXT_NEWLINE_CONSTRAINT,
+  BUF_FIRST = PREV_BEGBUF_CONSTRAINT,
+  BUF_LAST = NEXT_ENDBUF_CONSTRAINT,
+  WORD_DELIM = WORD_DELIM_CONSTRAINT,
+  NOT_WORD_DELIM = NOT_WORD_DELIM_CONSTRAINT
+} re_context_type;
+
+typedef struct
+{
+  int alloc;
+  int nelem;
+  int *elems;
+} re_node_set;
+
+typedef enum
+{
+  NON_TYPE = 0,
+
+  /* Node type, These are used by token, node, tree.  */
+  CHARACTER = 1,
+  END_OF_RE = 2,
+  SIMPLE_BRACKET = 3,
+  OP_BACK_REF = 4,
+  OP_PERIOD = 5,
+#ifdef RE_ENABLE_I18N
+  COMPLEX_BRACKET = 6,
+  OP_UTF8_PERIOD = 7,
+#endif /* RE_ENABLE_I18N */
+
+  /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used
+     when the debugger shows values of this enum type.  */
+#define EPSILON_BIT 8
+  OP_OPEN_SUBEXP = EPSILON_BIT | 0,
+  OP_CLOSE_SUBEXP = EPSILON_BIT | 1,
+  OP_ALT = EPSILON_BIT | 2,
+  OP_DUP_ASTERISK = EPSILON_BIT | 3,
+  ANCHOR = EPSILON_BIT | 4,
+
+  /* Tree type, these are used only by tree. */
+  CONCAT = 16,
+  SUBEXP = 17,
+
+  /* Token type, these are used only by token.  */
+  OP_DUP_PLUS = 18,
+  OP_DUP_QUESTION,
+  OP_OPEN_BRACKET,
+  OP_CLOSE_BRACKET,
+  OP_CHARSET_RANGE,
+  OP_OPEN_DUP_NUM,
+  OP_CLOSE_DUP_NUM,
+  OP_NON_MATCH_LIST,
+  OP_OPEN_COLL_ELEM,
+  OP_CLOSE_COLL_ELEM,
+  OP_OPEN_EQUIV_CLASS,
+  OP_CLOSE_EQUIV_CLASS,
+  OP_OPEN_CHAR_CLASS,
+  OP_CLOSE_CHAR_CLASS,
+  OP_WORD,
+  OP_NOTWORD,
+  OP_SPACE,
+  OP_NOTSPACE,
+  BACK_SLASH
+
+} re_token_type_t;
+
+#ifdef RE_ENABLE_I18N
+typedef struct
+{
+  /* Multibyte characters.  */
+  wchar_t *mbchars;
+
+  /* Collating symbols.  */
+# ifdef _LIBC
+  int32_t *coll_syms;
+# endif
+
+  /* Equivalence classes. */
+# ifdef _LIBC
+  int32_t *equiv_classes;
+# endif
+
+  /* Range expressions. */
+# ifdef _LIBC
+  uint32_t *range_starts;
+  uint32_t *range_ends;
+# else /* not _LIBC */
+  wchar_t *range_starts;
+  wchar_t *range_ends;
+# endif /* not _LIBC */
+
+  /* Character classes. */
+  wctype_t *char_classes;
+
+  /* If this character set is the non-matching list.  */
+  unsigned int non_match : 1;
+
+  /* # of multibyte characters.  */
+  int nmbchars;
+
+  /* # of collating symbols.  */
+  int ncoll_syms;
+
+  /* # of equivalence classes. */
+  int nequiv_classes;
+
+  /* # of range expressions. */
+  int nranges;
+
+  /* # of character classes. */
+  int nchar_classes;
+} re_charset_t;
+#endif /* RE_ENABLE_I18N */
+
+typedef struct
+{
+  union
+  {
+    unsigned char c;		/* for CHARACTER */
+    re_bitset_ptr_t sbcset;	/* for SIMPLE_BRACKET */
+#ifdef RE_ENABLE_I18N
+    re_charset_t *mbcset;	/* for COMPLEX_BRACKET */
+#endif /* RE_ENABLE_I18N */
+    int idx;			/* for BACK_REF */
+    re_context_type ctx_type;	/* for ANCHOR */
+  } opr;
+#if __GNUC__ >= 2
+  re_token_type_t type : 8;
+#else
+  re_token_type_t type;
+#endif
+  unsigned int constraint : 10;	/* context constraint */
+  unsigned int duplicated : 1;
+  unsigned int opt_subexp : 1;
+#ifdef RE_ENABLE_I18N
+  unsigned int accept_mb : 1;
+  /* These 2 bits can be moved into the union if needed (e.g. if running out
+     of bits; move opr.c to opr.c.c and move the flags to opr.c.flags).  */
+  unsigned int mb_partial : 1;
+#endif
+  unsigned int word_char : 1;
+} re_token_t;
+
+#define IS_EPSILON_NODE(type) ((type) & EPSILON_BIT)
+
+struct re_string_t
+{
+  /* Indicate the raw buffer which is the original string passed as an
+     argument of regexec(), re_search(), etc..  */
+  const unsigned char *raw_mbs;
+  /* Store the multibyte string.  In case of "case insensitive mode" like
+     REG_ICASE, upper cases of the string are stored, otherwise MBS points
+     the same address that RAW_MBS points.  */
+  unsigned char *mbs;
+#ifdef RE_ENABLE_I18N
+  /* Store the wide character string which is corresponding to MBS.  */
+  wint_t *wcs;
+  int *offsets;
+  mbstate_t cur_state;
+#endif
+  /* Index in RAW_MBS.  Each character mbs[i] corresponds to
+     raw_mbs[raw_mbs_idx + i].  */
+  int raw_mbs_idx;
+  /* The length of the valid characters in the buffers.  */
+  int valid_len;
+  /* The corresponding number of bytes in raw_mbs array.  */
+  int valid_raw_len;
+  /* The length of the buffers MBS and WCS.  */
+  int bufs_len;
+  /* The index in MBS, which is updated by re_string_fetch_byte.  */
+  int cur_idx;
+  /* length of RAW_MBS array.  */
+  int raw_len;
+  /* This is RAW_LEN - RAW_MBS_IDX + VALID_LEN - VALID_RAW_LEN.  */
+  int len;
+  /* End of the buffer may be shorter than its length in the cases such
+     as re_match_2, re_search_2.  Then, we use STOP for end of the buffer
+     instead of LEN.  */
+  int raw_stop;
+  /* This is RAW_STOP - RAW_MBS_IDX adjusted through OFFSETS.  */
+  int stop;
+
+  /* The context of mbs[0].  We store the context independently, since
+     the context of mbs[0] may be different from raw_mbs[0], which is
+     the beginning of the input string.  */
+  unsigned int tip_context;
+  /* The translation passed as a part of an argument of re_compile_pattern.  */
+  RE_TRANSLATE_TYPE trans;
+  /* Copy of re_dfa_t's word_char.  */
+  re_const_bitset_ptr_t word_char;
+  /* 1 if REG_ICASE.  */
+  unsigned char icase;
+  unsigned char is_utf8;
+  unsigned char map_notascii;
+  unsigned char mbs_allocated;
+  unsigned char offsets_needed;
+  unsigned char newline_anchor;
+  unsigned char word_ops_used;
+  int mb_cur_max;
+};
+typedef struct re_string_t re_string_t;
+
+
+struct re_dfa_t;
+typedef struct re_dfa_t re_dfa_t;
+
+#ifndef _LIBC
+# ifdef __i386__
+#  define internal_function   __attribute ((regparm (3), stdcall))
+# else
+#  define internal_function
+# endif
+#endif
+
+#ifndef NOT_IN_libc
+static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr,
+						int new_buf_len)
+     internal_function;
+# ifdef RE_ENABLE_I18N
+static void build_wcs_buffer (re_string_t *pstr) internal_function;
+static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr)
+  internal_function;
+# endif /* RE_ENABLE_I18N */
+static void build_upper_buffer (re_string_t *pstr) internal_function;
+static void re_string_translate_buffer (re_string_t *pstr) internal_function;
+static unsigned int re_string_context_at (const re_string_t *input, int idx,
+					  int eflags)
+     internal_function __attribute ((pure));
+#endif
+#define re_string_peek_byte(pstr, offset) \
+  ((pstr)->mbs[(pstr)->cur_idx + offset])
+#define re_string_fetch_byte(pstr) \
+  ((pstr)->mbs[(pstr)->cur_idx++])
+#define re_string_first_byte(pstr, idx) \
+  ((idx) == (pstr)->valid_len || (pstr)->wcs[idx] != WEOF)
+#define re_string_is_single_byte_char(pstr, idx) \
+  ((pstr)->wcs[idx] != WEOF && ((pstr)->valid_len == (idx) + 1 \
+				|| (pstr)->wcs[(idx) + 1] != WEOF))
+#define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx)
+#define re_string_cur_idx(pstr) ((pstr)->cur_idx)
+#define re_string_get_buffer(pstr) ((pstr)->mbs)
+#define re_string_length(pstr) ((pstr)->len)
+#define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx])
+#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx))
+#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx))
+
+#ifndef _LIBC
+# if HAVE_ALLOCA
+#  if (_MSC_VER)
+#   include <malloc.h>
+#   define __libc_use_alloca(n) 0
+#  else
+#   include <alloca.h>
+/* The OS usually guarantees only one guard page at the bottom of the stack,
+   and a page size can be as small as 4096 bytes.  So we cannot safely
+   allocate anything larger than 4096 bytes.  Also care for the possibility
+   of a few compiler-allocated temporary stack slots.  */
+#  define __libc_use_alloca(n) ((n) < 4032)
+#  endif
+# else
+/* alloca is implemented with malloc, so just use malloc.  */
+#  define __libc_use_alloca(n) 0
+# endif
+#endif
+
+#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t)))
+/* SunOS 4.1.x realloc doesn't accept null pointers: pre-Standard C. Sigh. */
+#define re_realloc(p,t,n) ((p != NULL) ? (t *) realloc (p,(n)*sizeof(t)) : (t *) calloc(n,sizeof(t)))
+#define re_free(p) free (p)
+
+struct bin_tree_t
+{
+  struct bin_tree_t *parent;
+  struct bin_tree_t *left;
+  struct bin_tree_t *right;
+  struct bin_tree_t *first;
+  struct bin_tree_t *next;
+
+  re_token_t token;
+
+  /* `node_idx' is the index in dfa->nodes, if `type' == 0.
+     Otherwise `type' indicate the type of this node.  */
+  int node_idx;
+};
+typedef struct bin_tree_t bin_tree_t;
+
+#define BIN_TREE_STORAGE_SIZE \
+  ((1024 - sizeof (void *)) / sizeof (bin_tree_t))
+
+struct bin_tree_storage_t
+{
+  struct bin_tree_storage_t *next;
+  bin_tree_t data[BIN_TREE_STORAGE_SIZE];
+};
+typedef struct bin_tree_storage_t bin_tree_storage_t;
+
+#define CONTEXT_WORD 1
+#define CONTEXT_NEWLINE (CONTEXT_WORD << 1)
+#define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1)
+#define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1)
+
+#define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD)
+#define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE)
+#define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF)
+#define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF)
+#define IS_ORDINARY_CONTEXT(c) ((c) == 0)
+
+#define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_')
+#define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR)
+#define IS_WIDE_WORD_CHAR(ch) (iswalnum (ch) || (ch) == L'_')
+#define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR)
+
+#define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \
+ ((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
+  || ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
+  || ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\
+  || ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context)))
+
+#define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \
+ ((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
+  || (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
+  || (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \
+  || (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context)))
+
+struct re_dfastate_t
+{
+  unsigned int hash;
+  re_node_set nodes;
+  re_node_set non_eps_nodes;
+  re_node_set inveclosure;
+  re_node_set *entrance_nodes;
+  struct re_dfastate_t **trtable, **word_trtable;
+  unsigned int context : 4;
+  unsigned int halt : 1;
+  /* If this state can accept `multi byte'.
+     Note that we refer to multibyte characters, and multi character
+     collating elements as `multi byte'.  */
+  unsigned int accept_mb : 1;
+  /* If this state has backreference node(s).  */
+  unsigned int has_backref : 1;
+  unsigned int has_constraint : 1;
+};
+typedef struct re_dfastate_t re_dfastate_t;
+
+struct re_state_table_entry
+{
+  int num;
+  int alloc;
+  re_dfastate_t **array;
+};
+
+/* Array type used in re_sub_match_last_t and re_sub_match_top_t.  */
+
+typedef struct
+{
+  int next_idx;
+  int alloc;
+  re_dfastate_t **array;
+} state_array_t;
+
+/* Store information about the node NODE whose type is OP_CLOSE_SUBEXP.  */
+
+typedef struct
+{
+  int node;
+  int str_idx; /* The position NODE match at.  */
+  state_array_t path;
+} re_sub_match_last_t;
+
+/* Store information about the node NODE whose type is OP_OPEN_SUBEXP.
+   And information about the node, whose type is OP_CLOSE_SUBEXP,
+   corresponding to NODE is stored in LASTS.  */
+
+typedef struct
+{
+  int str_idx;
+  int node;
+  state_array_t *path;
+  int alasts; /* Allocation size of LASTS.  */
+  int nlasts; /* The number of LASTS.  */
+  re_sub_match_last_t **lasts;
+} re_sub_match_top_t;
+
+struct re_backref_cache_entry
+{
+  int node;
+  int str_idx;
+  int subexp_from;
+  int subexp_to;
+  char more;
+  char unused;
+  unsigned short int eps_reachable_subexps_map;
+};
+
+typedef struct
+{
+  /* The string object corresponding to the input string.  */
+  re_string_t input;
+#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
+  const re_dfa_t *const dfa;
+#else
+  const re_dfa_t *dfa;
+#endif
+  /* EFLAGS of the argument of regexec.  */
+  int eflags;
+  /* Where the matching ends.  */
+  int match_last;
+  int last_node;
+  /* The state log used by the matcher.  */
+  re_dfastate_t **state_log;
+  int state_log_top;
+  /* Back reference cache.  */
+  int nbkref_ents;
+  int abkref_ents;
+  struct re_backref_cache_entry *bkref_ents;
+  int max_mb_elem_len;
+  int nsub_tops;
+  int asub_tops;
+  re_sub_match_top_t **sub_tops;
+} re_match_context_t;
+
+typedef struct
+{
+  re_dfastate_t **sifted_states;
+  re_dfastate_t **limited_states;
+  int last_node;
+  int last_str_idx;
+  re_node_set limits;
+} re_sift_context_t;
+
+struct re_fail_stack_ent_t
+{
+  int idx;
+  int node;
+  regmatch_t *regs;
+  re_node_set eps_via_nodes;
+};
+
+struct re_fail_stack_t
+{
+  int num;
+  int alloc;
+  struct re_fail_stack_ent_t *stack;
+};
+
+struct re_dfa_t
+{
+  re_token_t *nodes;
+  size_t nodes_alloc;
+  size_t nodes_len;
+  int *nexts;
+  int *org_indices;
+  re_node_set *edests;
+  re_node_set *eclosures;
+  re_node_set *inveclosures;
+  struct re_state_table_entry *state_table;
+  re_dfastate_t *init_state;
+  re_dfastate_t *init_state_word;
+  re_dfastate_t *init_state_nl;
+  re_dfastate_t *init_state_begbuf;
+  bin_tree_t *str_tree;
+  bin_tree_storage_t *str_tree_storage;
+  re_bitset_ptr_t sb_char;
+  int str_tree_storage_idx;
+
+  /* number of subexpressions `re_nsub' is in regex_t.  */
+  unsigned int state_hash_mask;
+  int init_node;
+  int nbackref; /* The number of backreference in this dfa.  */
+
+  /* Bitmap expressing which backreference is used.  */
+  bitset_word_t used_bkref_map;
+  bitset_word_t completed_bkref_map;
+
+  unsigned int has_plural_match : 1;
+  /* If this dfa has "multibyte node", which is a backreference or
+     a node which can accept multibyte character or multi character
+     collating element.  */
+  unsigned int has_mb_node : 1;
+  unsigned int is_utf8 : 1;
+  unsigned int map_notascii : 1;
+  unsigned int word_ops_used : 1;
+  int mb_cur_max;
+  bitset_t word_char;
+  reg_syntax_t syntax;
+  int *subexp_map;
+#ifdef DEBUG
+  char* re_str;
+#endif
+#if defined _LIBC
+  __libc_lock_define (, lock)
+#endif
+};
+
+#define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
+#define re_node_set_remove(set,id) \
+  (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
+#define re_node_set_empty(p) ((p)->nelem = 0)
+#define re_node_set_free(set) re_free ((set)->elems)
+
+
+typedef enum
+{
+  SB_CHAR,
+  MB_CHAR,
+  EQUIV_CLASS,
+  COLL_SYM,
+  CHAR_CLASS
+} bracket_elem_type;
+
+typedef struct
+{
+  bracket_elem_type type;
+  union
+  {
+    unsigned char ch;
+    unsigned char *name;
+    wchar_t wch;
+  } opr;
+} bracket_elem_t;
+
+
+/* Inline functions for bitset operation.  */
+static inline void
+bitset_not (bitset_t set)
+{
+  int bitset_i;
+  for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)
+    set[bitset_i] = ~set[bitset_i];
+}
+
+static inline void
+bitset_merge (bitset_t dest, const bitset_t src)
+{
+  int bitset_i;
+  for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)
+    dest[bitset_i] |= src[bitset_i];
+}
+
+static inline void
+bitset_mask (bitset_t dest, const bitset_t src)
+{
+  int bitset_i;
+  for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)
+    dest[bitset_i] &= src[bitset_i];
+}
+
+#ifdef RE_ENABLE_I18N
+/* Inline functions for re_string.  */
+static inline int
+internal_function __attribute ((pure))
+re_string_char_size_at (const re_string_t *pstr, int idx)
+{
+  int byte_idx;
+  if (pstr->mb_cur_max == 1)
+    return 1;
+  for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx)
+    if (pstr->wcs[idx + byte_idx] != WEOF)
+      break;
+  return byte_idx;
+}
+
+static inline wint_t
+internal_function __attribute ((pure))
+re_string_wchar_at (const re_string_t *pstr, int idx)
+{
+  if (pstr->mb_cur_max == 1)
+    return (wint_t) pstr->mbs[idx];
+  return (wint_t) pstr->wcs[idx];
+}
+
+# ifndef NOT_IN_libc
+static int
+internal_function __attribute ((pure))
+re_string_elem_size_at (const re_string_t *pstr, int idx)
+{
+#  ifdef _LIBC
+  const unsigned char *p, *extra;
+  const int32_t *table, *indirect;
+  int32_t tmp;
+#   include <locale/weight.h>
+  uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+
+  if (nrules != 0)
+    {
+      table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+      extra = (const unsigned char *)
+	_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
+      indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
+						_NL_COLLATE_INDIRECTMB);
+      p = pstr->mbs + idx;
+      tmp = findidx (&p);
+      return p - pstr->mbs - idx;
+    }
+  else
+#  endif /* _LIBC */
+    return 1;
+}
+# endif
+#endif /* RE_ENABLE_I18N */
+
+#endif /*  _REGEX_INTERNAL_H */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regexec.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regexec.c
new file mode 100755
index 0000000..0a1602e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/regex/regexec.c
@@ -0,0 +1,4369 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002-2005, 2007, 2009, 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu at yamato.ibm.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301 USA.  */
+
+static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
+				     int n) internal_function;
+static void match_ctx_clean (re_match_context_t *mctx) internal_function;
+static void match_ctx_free (re_match_context_t *cache) internal_function;
+static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, int node,
+					  int str_idx, int from, int to)
+     internal_function;
+static int search_cur_bkref_entry (const re_match_context_t *mctx, int str_idx)
+     internal_function;
+static reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, int node,
+					   int str_idx) internal_function;
+static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop,
+						   int node, int str_idx)
+     internal_function;
+static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
+			   re_dfastate_t **limited_sts, int last_node,
+			   int last_str_idx)
+     internal_function;
+static reg_errcode_t re_search_internal (const regex_t *preg,
+					 const char *string, int length,
+					 int start, int range, int stop,
+					 size_t nmatch, regmatch_t pmatch[],
+					 int eflags);
+static int re_search_2_stub (struct re_pattern_buffer *bufp,
+			     const char *string1, int length1,
+			     const char *string2, int length2,
+			     int start, int range, struct re_registers *regs,
+			     int stop, int ret_len);
+static int re_search_stub (struct re_pattern_buffer *bufp,
+			   const char *string, int length, int start,
+			   int range, int stop, struct re_registers *regs,
+			   int ret_len);
+static unsigned re_copy_regs (struct re_registers *regs, regmatch_t *pmatch,
+			      unsigned int nregs, int regs_allocated);
+static reg_errcode_t prune_impossible_nodes (re_match_context_t *mctx);
+static int check_matching (re_match_context_t *mctx, int fl_longest_match,
+			   int *p_match_first) internal_function;
+static int check_halt_state_context (const re_match_context_t *mctx,
+				     const re_dfastate_t *state, int idx)
+     internal_function;
+static void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,
+			 regmatch_t *prev_idx_match, int cur_node,
+			 int cur_idx, int nmatch) internal_function;
+static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs,
+				      int str_idx, int dest_node, int nregs,
+				      regmatch_t *regs,
+				      re_node_set *eps_via_nodes)
+     internal_function;
+static reg_errcode_t set_regs (const regex_t *preg,
+			       const re_match_context_t *mctx,
+			       size_t nmatch, regmatch_t *pmatch,
+			       int fl_backtrack) internal_function;
+static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs)
+     internal_function;
+
+#ifdef RE_ENABLE_I18N
+static int sift_states_iter_mb (const re_match_context_t *mctx,
+				re_sift_context_t *sctx,
+				int node_idx, int str_idx, int max_str_idx)
+     internal_function;
+#endif /* RE_ENABLE_I18N */
+static reg_errcode_t sift_states_backward (const re_match_context_t *mctx,
+					   re_sift_context_t *sctx)
+     internal_function;
+static reg_errcode_t build_sifted_states (const re_match_context_t *mctx,
+					  re_sift_context_t *sctx, int str_idx,
+					  re_node_set *cur_dest)
+     internal_function;
+static reg_errcode_t update_cur_sifted_state (const re_match_context_t *mctx,
+					      re_sift_context_t *sctx,
+					      int str_idx,
+					      re_node_set *dest_nodes)
+     internal_function;
+static reg_errcode_t add_epsilon_src_nodes (const re_dfa_t *dfa,
+					    re_node_set *dest_nodes,
+					    const re_node_set *candidates)
+     internal_function;
+static int check_dst_limits (const re_match_context_t *mctx,
+			     re_node_set *limits,
+			     int dst_node, int dst_idx, int src_node,
+			     int src_idx) internal_function;
+static int check_dst_limits_calc_pos_1 (const re_match_context_t *mctx,
+					int boundaries, int subexp_idx,
+					int from_node, int bkref_idx)
+     internal_function;
+static int check_dst_limits_calc_pos (const re_match_context_t *mctx,
+				      int limit, int subexp_idx,
+				      int node, int str_idx,
+				      int bkref_idx) internal_function;
+static reg_errcode_t check_subexp_limits (const re_dfa_t *dfa,
+					  re_node_set *dest_nodes,
+					  const re_node_set *candidates,
+					  re_node_set *limits,
+					  struct re_backref_cache_entry *bkref_ents,
+					  int str_idx) internal_function;
+static reg_errcode_t sift_states_bkref (const re_match_context_t *mctx,
+					re_sift_context_t *sctx,
+					int str_idx, const re_node_set *candidates)
+     internal_function;
+static reg_errcode_t merge_state_array (const re_dfa_t *dfa,
+					re_dfastate_t **dst,
+					re_dfastate_t **src, int num)
+     internal_function;
+static re_dfastate_t *find_recover_state (reg_errcode_t *err,
+					 re_match_context_t *mctx) internal_function;
+static re_dfastate_t *transit_state (reg_errcode_t *err,
+				     re_match_context_t *mctx,
+				     re_dfastate_t *state) internal_function;
+static re_dfastate_t *merge_state_with_log (reg_errcode_t *err,
+					    re_match_context_t *mctx,
+					    re_dfastate_t *next_state)
+     internal_function;
+static reg_errcode_t check_subexp_matching_top (re_match_context_t *mctx,
+						re_node_set *cur_nodes,
+						int str_idx) internal_function;
+#if 0
+static re_dfastate_t *transit_state_sb (reg_errcode_t *err,
+					re_match_context_t *mctx,
+					re_dfastate_t *pstate)
+     internal_function;
+#endif
+#ifdef RE_ENABLE_I18N
+static reg_errcode_t transit_state_mb (re_match_context_t *mctx,
+				       re_dfastate_t *pstate)
+     internal_function;
+#endif /* RE_ENABLE_I18N */
+static reg_errcode_t transit_state_bkref (re_match_context_t *mctx,
+					  const re_node_set *nodes)
+     internal_function;
+static reg_errcode_t get_subexp (re_match_context_t *mctx,
+				 int bkref_node, int bkref_str_idx)
+     internal_function;
+static reg_errcode_t get_subexp_sub (re_match_context_t *mctx,
+				     const re_sub_match_top_t *sub_top,
+				     re_sub_match_last_t *sub_last,
+				     int bkref_node, int bkref_str)
+     internal_function;
+static int find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
+			     int subexp_idx, int type) internal_function;
+static reg_errcode_t check_arrival (re_match_context_t *mctx,
+				    state_array_t *path, int top_node,
+				    int top_str, int last_node, int last_str,
+				    int type) internal_function;
+static reg_errcode_t check_arrival_add_next_nodes (re_match_context_t *mctx,
+						   int str_idx,
+						   re_node_set *cur_nodes,
+						   re_node_set *next_nodes)
+     internal_function;
+static reg_errcode_t check_arrival_expand_ecl (const re_dfa_t *dfa,
+					       re_node_set *cur_nodes,
+					       int ex_subexp, int type)
+     internal_function;
+static reg_errcode_t check_arrival_expand_ecl_sub (const re_dfa_t *dfa,
+						   re_node_set *dst_nodes,
+						   int target, int ex_subexp,
+						   int type) internal_function;
+static reg_errcode_t expand_bkref_cache (re_match_context_t *mctx,
+					 re_node_set *cur_nodes, int cur_str,
+					 int subexp_num, int type)
+     internal_function;
+static int build_trtable (const re_dfa_t *dfa,
+			  re_dfastate_t *state) internal_function;
+#ifdef RE_ENABLE_I18N
+static int check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
+				    const re_string_t *input, int idx)
+     internal_function;
+# ifdef _LIBC
+static unsigned int find_collation_sequence_value (const unsigned char *mbs,
+						   size_t name_len)
+     internal_function;
+# endif /* _LIBC */
+#endif /* RE_ENABLE_I18N */
+static int group_nodes_into_DFAstates (const re_dfa_t *dfa,
+				       const re_dfastate_t *state,
+				       re_node_set *states_node,
+				       bitset_t *states_ch) internal_function;
+static int check_node_accept (const re_match_context_t *mctx,
+			      const re_token_t *node, int idx)
+     internal_function;
+static reg_errcode_t extend_buffers (re_match_context_t *mctx)
+     internal_function;
+
+/* Entry point for POSIX code.  */
+
+/* regexec searches for a given pattern, specified by PREG, in the
+   string STRING.
+
+   If NMATCH is zero or REG_NOSUB was set in the cflags argument to
+   `regcomp', we ignore PMATCH.  Otherwise, we assume PMATCH has at
+   least NMATCH elements, and we set them to the offsets of the
+   corresponding matched substrings.
+
+   EFLAGS specifies `execution flags' which affect matching: if
+   REG_NOTBOL is set, then ^ does not match at the beginning of the
+   string; if REG_NOTEOL is set, then $ does not match at the end.
+
+   We return 0 if we find a match and REG_NOMATCH if not.  */
+
+int
+regexec (
+	const regex_t *__restrict preg,
+	const char *__restrict string,
+	size_t nmatch,
+	regmatch_t pmatch[],
+	int eflags)
+{
+  reg_errcode_t err;
+  int start, length;
+
+  if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND))
+    return REG_BADPAT;
+
+  if (eflags & REG_STARTEND)
+    {
+      start = pmatch[0].rm_so;
+      length = pmatch[0].rm_eo;
+    }
+  else
+    {
+      start = 0;
+      length = strlen (string);
+    }
+
+  __libc_lock_lock (dfa->lock);
+  if (preg->no_sub)
+    err = re_search_internal (preg, string, length, start, length - start,
+			      length, 0, NULL, eflags);
+  else
+    err = re_search_internal (preg, string, length, start, length - start,
+			      length, nmatch, pmatch, eflags);
+  __libc_lock_unlock (dfa->lock);
+  return err != REG_NOERROR;
+}
+
+#ifdef _LIBC
+# include <shlib-compat.h>
+versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
+
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+__typeof__ (__regexec) __compat_regexec;
+
+int
+attribute_compat_text_section
+__compat_regexec (const regex_t *__restrict preg,
+		  const char *__restrict string, size_t nmatch,
+		  regmatch_t pmatch[], int eflags)
+{
+  return regexec (preg, string, nmatch, pmatch,
+		  eflags & (REG_NOTBOL | REG_NOTEOL));
+}
+compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
+# endif
+#endif
+
+/* Entry points for GNU code.  */
+
+/* re_match, re_search, re_match_2, re_search_2
+
+   The former two functions operate on STRING with length LENGTH,
+   while the later two operate on concatenation of STRING1 and STRING2
+   with lengths LENGTH1 and LENGTH2, respectively.
+
+   re_match() matches the compiled pattern in BUFP against the string,
+   starting at index START.
+
+   re_search() first tries matching at index START, then it tries to match
+   starting from index START + 1, and so on.  The last start position tried
+   is START + RANGE.  (Thus RANGE = 0 forces re_search to operate the same
+   way as re_match().)
+
+   The parameter STOP of re_{match,search}_2 specifies that no match exceeding
+   the first STOP characters of the concatenation of the strings should be
+   concerned.
+
+   If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match
+   and all groups is stroed in REGS.  (For the "_2" variants, the offsets are
+   computed relative to the concatenation, not relative to the individual
+   strings.)
+
+   On success, re_match* functions return the length of the match, re_search*
+   return the position of the start of the match.  Return value -1 means no
+   match was found and -2 indicates an internal error.  */
+
+int
+re_match (struct re_pattern_buffer *bufp,
+	  const char *string,
+	  int length,
+	  int start,
+	  struct re_registers *regs)
+{
+  return re_search_stub (bufp, string, length, start, 0, length, regs, 1);
+}
+#ifdef _LIBC
+weak_alias (__re_match, re_match)
+#endif
+
+int
+re_search (struct re_pattern_buffer *bufp,
+	   const char *string,
+	   int length, int start, int range,
+	   struct re_registers *regs)
+{
+  return re_search_stub (bufp, string, length, start, range, length, regs, 0);
+}
+#ifdef _LIBC
+weak_alias (__re_search, re_search)
+#endif
+
+int
+re_match_2 (struct re_pattern_buffer *bufp,
+	    const char *string1, int length1,
+	    const char *string2, int length2, int start,
+	    struct re_registers *regs, int stop)
+{
+  return re_search_2_stub (bufp, string1, length1, string2, length2,
+			   start, 0, regs, stop, 1);
+}
+#ifdef _LIBC
+weak_alias (__re_match_2, re_match_2)
+#endif
+
+int
+re_search_2 (struct re_pattern_buffer *bufp,
+	     const char *string1, int length1,
+	     const char *string2, int length2, int start,
+	     int range, struct re_registers *regs,  int stop)
+{
+  return re_search_2_stub (bufp, string1, length1, string2, length2,
+			   start, range, regs, stop, 0);
+}
+#ifdef _LIBC
+weak_alias (__re_search_2, re_search_2)
+#endif
+
+static int
+re_search_2_stub (struct re_pattern_buffer *bufp,
+		  const char *string1, int length1,
+		  const char *string2, int length2, int start,
+		  int range, struct re_registers *regs,
+		  int stop, int ret_len)
+{
+  const char *str;
+  int rval;
+  int len = length1 + length2;
+  int free_str = 0;
+
+  if (BE (length1 < 0 || length2 < 0 || stop < 0, 0))
+    return -2;
+
+  /* Concatenate the strings.  */
+  if (length2 > 0)
+    if (length1 > 0)
+      {
+	char *s = re_malloc (char, len);
+
+	if (BE (s == NULL, 0))
+	  return -2;
+	memcpy (s, string1, length1);
+	memcpy (s + length1, string2, length2);
+	str = s;
+	free_str = 1;
+      }
+    else
+      str = string2;
+  else
+    str = string1;
+
+  rval = re_search_stub (bufp, str, len, start, range, stop, regs, ret_len);
+  if (free_str)
+    re_free ((char *) str);
+  return rval;
+}
+
+/* The parameters have the same meaning as those of re_search.
+   Additional parameters:
+   If RET_LEN is nonzero the length of the match is returned (re_match style);
+   otherwise the position of the match is returned.  */
+
+static int
+re_search_stub (struct re_pattern_buffer *bufp,
+		const char *string, int length, int start,
+		int range, int stop,
+		struct re_registers *regs, int ret_len)
+{
+  reg_errcode_t result;
+  regmatch_t *pmatch;
+  int nregs, rval;
+  int eflags = 0;
+
+  /* Check for out-of-range.  */
+  if (BE (start < 0 || start > length, 0))
+    return -1;
+  if (BE (start + range > length, 0))
+    range = length - start;
+  else if (BE (start + range < 0, 0))
+    range = -start;
+
+  __libc_lock_lock (dfa->lock);
+
+  eflags |= (bufp->not_bol) ? REG_NOTBOL : 0;
+  eflags |= (bufp->not_eol) ? REG_NOTEOL : 0;
+
+  /* Compile fastmap if we haven't yet.  */
+  if (range > 0 && bufp->fastmap != NULL && !bufp->fastmap_accurate)
+    re_compile_fastmap (bufp);
+
+  if (BE (bufp->no_sub, 0))
+    regs = NULL;
+
+  /* We need at least 1 register.  */
+  if (regs == NULL)
+    nregs = 1;
+  else if (BE (bufp->regs_allocated == REGS_FIXED &&
+	       regs->num_regs < bufp->re_nsub + 1, 0))
+    {
+      nregs = regs->num_regs;
+      if (BE (nregs < 1, 0))
+	{
+	  /* Nothing can be copied to regs.  */
+	  regs = NULL;
+	  nregs = 1;
+	}
+    }
+  else
+    nregs = bufp->re_nsub + 1;
+  pmatch = re_malloc (regmatch_t, nregs);
+  if (BE (pmatch == NULL, 0))
+    {
+      rval = -2;
+      goto out;
+    }
+
+  result = re_search_internal (bufp, string, length, start, range, stop,
+			       nregs, pmatch, eflags);
+
+  rval = 0;
+
+  /* I hope we needn't fill ther regs with -1's when no match was found.  */
+  if (result != REG_NOERROR)
+    rval = -1;
+  else if (regs != NULL)
+    {
+      /* If caller wants register contents data back, copy them.  */
+      bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs,
+					   bufp->regs_allocated);
+      if (BE (bufp->regs_allocated == REGS_UNALLOCATED, 0))
+	rval = -2;
+    }
+
+  if (BE (rval == 0, 1))
+    {
+      if (ret_len)
+	{
+	  assert (pmatch[0].rm_so == start);
+	  rval = pmatch[0].rm_eo - start;
+	}
+      else
+	rval = pmatch[0].rm_so;
+    }
+  re_free (pmatch);
+ out:
+  __libc_lock_unlock (dfa->lock);
+  return rval;
+}
+
+static unsigned
+re_copy_regs (struct re_registers *regs,
+	      regmatch_t *pmatch,
+	      unsigned int nregs, int regs_allocated)
+{
+  int rval = REGS_REALLOCATE;
+  unsigned int i;
+  unsigned int need_regs = nregs + 1;
+  /* We need one extra element beyond `num_regs' for the `-1' marker GNU code
+     uses.  */
+
+  /* Have the register data arrays been allocated?  */
+  if (regs_allocated == REGS_UNALLOCATED)
+    { /* No.  So allocate them with malloc.  */
+      regs->start = re_malloc (regoff_t, need_regs);
+      if (BE (regs->start == NULL, 0))
+	return REGS_UNALLOCATED;
+      regs->end = re_malloc (regoff_t, need_regs);
+      if (BE (regs->end == NULL, 0))
+	{
+	  re_free (regs->start);
+	  return REGS_UNALLOCATED;
+	}
+      regs->num_regs = need_regs;
+    }
+  else if (regs_allocated == REGS_REALLOCATE)
+    { /* Yes.  If we need more elements than were already
+	 allocated, reallocate them.  If we need fewer, just
+	 leave it alone.  */
+      if (BE (need_regs > regs->num_regs, 0))
+	{
+	  regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs);
+	  regoff_t *new_end;
+	  if (BE (new_start == NULL, 0))
+	    return REGS_UNALLOCATED;
+	  new_end = re_realloc (regs->end, regoff_t, need_regs);
+	  if (BE (new_end == NULL, 0))
+	    {
+	      re_free (new_start);
+	      return REGS_UNALLOCATED;
+	    }
+	  regs->start = new_start;
+	  regs->end = new_end;
+	  regs->num_regs = need_regs;
+	}
+    }
+  else
+    {
+      assert (regs_allocated == REGS_FIXED);
+      /* This function may not be called with REGS_FIXED and nregs too big.  */
+      assert (regs->num_regs >= nregs);
+      rval = REGS_FIXED;
+    }
+
+  /* Copy the regs.  */
+  for (i = 0; i < nregs; ++i)
+    {
+      regs->start[i] = pmatch[i].rm_so;
+      regs->end[i] = pmatch[i].rm_eo;
+    }
+  for ( ; i < regs->num_regs; ++i)
+    regs->start[i] = regs->end[i] = -1;
+
+  return rval;
+}
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+   ENDS.  Subsequent matches using PATTERN_BUFFER and REGS will use
+   this memory for recording register information.  STARTS and ENDS
+   must be allocated using the malloc library routine, and must each
+   be at least NUM_REGS * sizeof (regoff_t) bytes long.
+
+   If NUM_REGS == 0, then subsequent matches should allocate their own
+   register data.
+
+   Unless this function is called, the first search or match using
+   PATTERN_BUFFER will allocate its own register data, without
+   freeing the old data.  */
+
+void
+re_set_registers (struct re_pattern_buffer *bufp,
+		  struct re_registers *regs,
+		  unsigned num_regs,
+		  regoff_t *starts,
+		  regoff_t *ends)
+{
+  if (num_regs)
+    {
+      bufp->regs_allocated = REGS_REALLOCATE;
+      regs->num_regs = num_regs;
+      regs->start = starts;
+      regs->end = ends;
+    }
+  else
+    {
+      bufp->regs_allocated = REGS_UNALLOCATED;
+      regs->num_regs = 0;
+      regs->start = regs->end = (regoff_t *) 0;
+    }
+}
+#ifdef _LIBC
+weak_alias (__re_set_registers, re_set_registers)
+#endif
+
+/* Entry points compatible with 4.2 BSD regex library.  We don't define
+   them unless specifically requested.  */
+
+#if defined _REGEX_RE_COMP || defined _LIBC
+int
+# ifdef _LIBC
+weak_function
+# endif
+re_exec (s)
+     const char *s;
+{
+  return 0 == regexec (&re_comp_buf, s, 0, NULL, 0);
+}
+#endif /* _REGEX_RE_COMP */
+
+/* Internal entry point.  */
+
+/* Searches for a compiled pattern PREG in the string STRING, whose
+   length is LENGTH.  NMATCH, PMATCH, and EFLAGS have the same
+   mingings with regexec.  START, and RANGE have the same meanings
+   with re_search.
+   Return REG_NOERROR if we find a match, and REG_NOMATCH if not,
+   otherwise return the error code.
+   Note: We assume front end functions already check ranges.
+   (START + RANGE >= 0 && START + RANGE <= LENGTH)  */
+
+static reg_errcode_t
+re_search_internal (const regex_t *preg,
+		    const char *string,
+		    int length, int start, int range, int stop,
+		    size_t nmatch, regmatch_t pmatch[],
+		    int eflags)
+{
+  reg_errcode_t err;
+  const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer;
+  int left_lim, right_lim, incr;
+  int fl_longest_match, match_first, match_kind, match_last = -1;
+  unsigned int extra_nmatch;
+  int sb, ch;
+#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
+  re_match_context_t mctx = { .dfa = dfa };
+#else
+  re_match_context_t mctx;
+#endif
+  char *fastmap = (preg->fastmap != NULL && preg->fastmap_accurate
+		   && range && !preg->can_be_null) ? preg->fastmap : NULL;
+  RE_TRANSLATE_TYPE t = preg->translate;
+
+#if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
+  memset (&mctx, '\0', sizeof (re_match_context_t));
+  mctx.dfa = dfa;
+#endif
+
+  extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0;
+  nmatch -= extra_nmatch;
+
+  /* Check if the DFA haven't been compiled.  */
+  if (BE (preg->used == 0 || dfa->init_state == NULL
+	  || dfa->init_state_word == NULL || dfa->init_state_nl == NULL
+	  || dfa->init_state_begbuf == NULL, 0))
+    return REG_NOMATCH;
+
+#ifdef DEBUG
+  /* We assume front-end functions already check them.  */
+  assert (start + range >= 0 && start + range <= length);
+#endif
+
+  /* If initial states with non-begbuf contexts have no elements,
+     the regex must be anchored.  If preg->newline_anchor is set,
+     we'll never use init_state_nl, so do not check it.  */
+  if (dfa->init_state->nodes.nelem == 0
+      && dfa->init_state_word->nodes.nelem == 0
+      && (dfa->init_state_nl->nodes.nelem == 0
+	  || !preg->newline_anchor))
+    {
+      if (start != 0 && start + range != 0)
+	return REG_NOMATCH;
+      start = range = 0;
+    }
+
+  /* We must check the longest matching, if nmatch > 0.  */
+  fl_longest_match = (nmatch != 0 || dfa->nbackref);
+
+  err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1,
+			    preg->translate, preg->syntax & RE_ICASE, dfa);
+  if (BE (err != REG_NOERROR, 0))
+    goto free_return;
+  mctx.input.stop = stop;
+  mctx.input.raw_stop = stop;
+  mctx.input.newline_anchor = preg->newline_anchor;
+
+  err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2);
+  if (BE (err != REG_NOERROR, 0))
+    goto free_return;
+
+  /* We will log all the DFA states through which the dfa pass,
+     if nmatch > 1, or this dfa has "multibyte node", which is a
+     back-reference or a node which can accept multibyte character or
+     multi character collating element.  */
+  if (nmatch > 1 || dfa->has_mb_node)
+    {
+      /* Avoid overflow.  */
+      if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= (size_t)mctx.input.bufs_len, 0))
+	{
+	  err = REG_ESPACE;
+	  goto free_return;
+	}
+
+      mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1);
+      if (BE (mctx.state_log == NULL, 0))
+	{
+	  err = REG_ESPACE;
+	  goto free_return;
+	}
+    }
+  else
+    mctx.state_log = NULL;
+
+  match_first = start;
+  mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
+			   : CONTEXT_NEWLINE | CONTEXT_BEGBUF;
+
+  /* Check incrementally whether of not the input string match.  */
+  incr = (range < 0) ? -1 : 1;
+  left_lim = (range < 0) ? start + range : start;
+  right_lim = (range < 0) ? start : start + range;
+  sb = dfa->mb_cur_max == 1;
+  match_kind =
+    (fastmap
+     ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)
+	| (range >= 0 ? 2 : 0)
+	| (t != NULL ? 1 : 0))
+     : 8);
+
+  for (;; match_first += incr)
+    {
+      err = REG_NOMATCH;
+      if (match_first < left_lim || right_lim < match_first)
+	goto free_return;
+
+      /* Advance as rapidly as possible through the string, until we
+	 find a plausible place to start matching.  This may be done
+	 with varying efficiency, so there are various possibilities:
+	 only the most common of them are specialized, in order to
+	 save on code size.  We use a switch statement for speed.  */
+      switch (match_kind)
+	{
+	case 8:
+	  /* No fastmap.  */
+	  break;
+
+	case 7:
+	  /* Fastmap with single-byte translation, match forward.  */
+	  while (BE (match_first < right_lim, 1)
+		 && !fastmap[t[(unsigned char) string[match_first]]])
+	    ++match_first;
+	  goto forward_match_found_start_or_reached_end;
+
+	case 6:
+	  /* Fastmap without translation, match forward.  */
+	  while (BE (match_first < right_lim, 1)
+		 && !fastmap[(unsigned char) string[match_first]])
+	    ++match_first;
+
+	forward_match_found_start_or_reached_end:
+	  if (BE (match_first == right_lim, 0))
+	    {
+	      ch = match_first >= length
+		       ? 0 : (unsigned char) string[match_first];
+	      if (!fastmap[t ? t[ch] : ch])
+		goto free_return;
+	    }
+	  break;
+
+	case 4:
+	case 5:
+	  /* Fastmap without multi-byte translation, match backwards.  */
+	  while (match_first >= left_lim)
+	    {
+	      ch = match_first >= length
+		       ? 0 : (unsigned char) string[match_first];
+	      if (fastmap[t ? t[ch] : ch])
+		break;
+	      --match_first;
+	    }
+	  if (match_first < left_lim)
+	    goto free_return;
+	  break;
+
+	default:
+	  /* In this case, we can't determine easily the current byte,
+	     since it might be a component byte of a multibyte
+	     character.  Then we use the constructed buffer instead.  */
+	  for (;;)
+	    {
+	      /* If MATCH_FIRST is out of the valid range, reconstruct the
+		 buffers.  */
+	      unsigned int offset = match_first - mctx.input.raw_mbs_idx;
+	      if (BE (offset >= (unsigned int) mctx.input.valid_raw_len, 0))
+		{
+		  err = re_string_reconstruct (&mctx.input, match_first,
+					       eflags);
+		  if (BE (err != REG_NOERROR, 0))
+		    goto free_return;
+
+		  offset = match_first - mctx.input.raw_mbs_idx;
+		}
+	      /* If MATCH_FIRST is out of the buffer, leave it as '\0'.
+		 Note that MATCH_FIRST must not be smaller than 0.  */
+	      ch = (match_first >= length
+		    ? 0 : re_string_byte_at (&mctx.input, offset));
+	      if (fastmap[ch])
+		break;
+	      match_first += incr;
+	      if (match_first < left_lim || match_first > right_lim)
+		{
+		  err = REG_NOMATCH;
+		  goto free_return;
+		}
+	    }
+	  break;
+	}
+
+      /* Reconstruct the buffers so that the matcher can assume that
+	 the matching starts from the beginning of the buffer.  */
+      err = re_string_reconstruct (&mctx.input, match_first, eflags);
+      if (BE (err != REG_NOERROR, 0))
+	goto free_return;
+
+#ifdef RE_ENABLE_I18N
+     /* Don't consider this char as a possible match start if it part,
+	yet isn't the head, of a multibyte character.  */
+      if (!sb && !re_string_first_byte (&mctx.input, 0))
+	continue;
+#endif
+
+      /* It seems to be appropriate one, then use the matcher.  */
+      /* We assume that the matching starts from 0.  */
+      mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;
+      match_last = check_matching (&mctx, fl_longest_match,
+				   range >= 0 ? &match_first : NULL);
+      if (match_last != -1)
+	{
+	  if (BE (match_last == -2, 0))
+	    {
+	      err = REG_ESPACE;
+	      goto free_return;
+	    }
+	  else
+	    {
+	      mctx.match_last = match_last;
+	      if ((!preg->no_sub && nmatch > 1) || dfa->nbackref)
+		{
+		  re_dfastate_t *pstate = mctx.state_log[match_last];
+		  mctx.last_node = check_halt_state_context (&mctx, pstate,
+							     match_last);
+		}
+	      if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match)
+		  || dfa->nbackref)
+		{
+		  err = prune_impossible_nodes (&mctx);
+		  if (err == REG_NOERROR)
+		    break;
+		  if (BE (err != REG_NOMATCH, 0))
+		    goto free_return;
+		  match_last = -1;
+		}
+	      else
+		break; /* We found a match.  */
+	    }
+	}
+
+      match_ctx_clean (&mctx);
+    }
+
+#ifdef DEBUG
+  assert (match_last != -1);
+  assert (err == REG_NOERROR);
+#endif
+
+  /* Set pmatch[] if we need.  */
+  if (nmatch > 0)
+    {
+      unsigned int reg_idx;
+
+      /* Initialize registers.  */
+      for (reg_idx = 1; reg_idx < nmatch; ++reg_idx)
+	pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1;
+
+      /* Set the points where matching start/end.  */
+      pmatch[0].rm_so = 0;
+      pmatch[0].rm_eo = mctx.match_last;
+
+      if (!preg->no_sub && nmatch > 1)
+	{
+	  err = set_regs (preg, &mctx, nmatch, pmatch,
+			  dfa->has_plural_match && dfa->nbackref > 0);
+	  if (BE (err != REG_NOERROR, 0))
+	    goto free_return;
+	}
+
+      /* At last, add the offset to the each registers, since we slided
+	 the buffers so that we could assume that the matching starts
+	 from 0.  */
+      for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
+	if (pmatch[reg_idx].rm_so != -1)
+	  {
+#ifdef RE_ENABLE_I18N
+	    if (BE (mctx.input.offsets_needed != 0, 0))
+	      {
+		pmatch[reg_idx].rm_so =
+		  (pmatch[reg_idx].rm_so == mctx.input.valid_len
+		   ? mctx.input.valid_raw_len
+		   : mctx.input.offsets[pmatch[reg_idx].rm_so]);
+		pmatch[reg_idx].rm_eo =
+		  (pmatch[reg_idx].rm_eo == mctx.input.valid_len
+		   ? mctx.input.valid_raw_len
+		   : mctx.input.offsets[pmatch[reg_idx].rm_eo]);
+	      }
+#else
+	    assert (mctx.input.offsets_needed == 0);
+#endif
+	    pmatch[reg_idx].rm_so += match_first;
+	    pmatch[reg_idx].rm_eo += match_first;
+	  }
+      for (reg_idx = 0; reg_idx < extra_nmatch; ++reg_idx)
+	{
+	  pmatch[nmatch + reg_idx].rm_so = -1;
+	  pmatch[nmatch + reg_idx].rm_eo = -1;
+	}
+
+      if (dfa->subexp_map)
+	for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++)
+	  if (dfa->subexp_map[reg_idx] != (int)reg_idx)
+	    {
+	      pmatch[reg_idx + 1].rm_so
+		= pmatch[dfa->subexp_map[reg_idx] + 1].rm_so;
+	      pmatch[reg_idx + 1].rm_eo
+		= pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo;
+	    }
+    }
+
+ free_return:
+  re_free (mctx.state_log);
+  if (dfa->nbackref)
+    match_ctx_free (&mctx);
+  re_string_destruct (&mctx.input);
+  return err;
+}
+
+static reg_errcode_t
+prune_impossible_nodes (re_match_context_t *mctx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  int halt_node, match_last;
+  reg_errcode_t ret;
+  re_dfastate_t **sifted_states;
+  re_dfastate_t **lim_states = NULL;
+  re_sift_context_t sctx;
+#ifdef DEBUG
+  assert (mctx->state_log != NULL);
+#endif
+  match_last = mctx->match_last;
+  halt_node = mctx->last_node;
+
+  /* Avoid overflow.  */
+  if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= (size_t)match_last, 0))
+    return REG_ESPACE;
+
+  sifted_states = re_malloc (re_dfastate_t *, match_last + 1);
+  if (BE (sifted_states == NULL, 0))
+    {
+      ret = REG_ESPACE;
+      goto free_return;
+    }
+  if (dfa->nbackref)
+    {
+      lim_states = re_malloc (re_dfastate_t *, match_last + 1);
+      if (BE (lim_states == NULL, 0))
+	{
+	  ret = REG_ESPACE;
+	  goto free_return;
+	}
+      while (1)
+	{
+	  memset (lim_states, '\0',
+		  sizeof (re_dfastate_t *) * (match_last + 1));
+	  sift_ctx_init (&sctx, sifted_states, lim_states, halt_node,
+			 match_last);
+	  ret = sift_states_backward (mctx, &sctx);
+	  re_node_set_free (&sctx.limits);
+	  if (BE (ret != REG_NOERROR, 0))
+	      goto free_return;
+	  if (sifted_states[0] != NULL || lim_states[0] != NULL)
+	    break;
+	  do
+	    {
+	      --match_last;
+	      if (match_last < 0)
+		{
+		  ret = REG_NOMATCH;
+		  goto free_return;
+		}
+	    } while (mctx->state_log[match_last] == NULL
+		     || !mctx->state_log[match_last]->halt);
+	  halt_node = check_halt_state_context (mctx,
+						mctx->state_log[match_last],
+						match_last);
+	}
+      ret = merge_state_array (dfa, sifted_states, lim_states,
+			       match_last + 1);
+      re_free (lim_states);
+      lim_states = NULL;
+      if (BE (ret != REG_NOERROR, 0))
+	goto free_return;
+    }
+  else
+    {
+      sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, match_last);
+      ret = sift_states_backward (mctx, &sctx);
+      re_node_set_free (&sctx.limits);
+      if (BE (ret != REG_NOERROR, 0))
+	goto free_return;
+      if (sifted_states[0] == NULL)
+	{
+	  ret = REG_NOMATCH;
+	  goto free_return;
+	}
+    }
+  re_free (mctx->state_log);
+  mctx->state_log = sifted_states;
+  sifted_states = NULL;
+  mctx->last_node = halt_node;
+  mctx->match_last = match_last;
+  ret = REG_NOERROR;
+ free_return:
+  re_free (sifted_states);
+  re_free (lim_states);
+  return ret;
+}
+
+/* Acquire an initial state and return it.
+   We must select appropriate initial state depending on the context,
+   since initial states may have constraints like "\<", "^", etc..  */
+
+static inline re_dfastate_t *
+__attribute ((always_inline)) internal_function
+acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx,
+			    int idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  if (dfa->init_state->has_constraint)
+    {
+      unsigned int context;
+      context = re_string_context_at (&mctx->input, idx - 1, mctx->eflags);
+      if (IS_WORD_CONTEXT (context))
+	return dfa->init_state_word;
+      else if (IS_ORDINARY_CONTEXT (context))
+	return dfa->init_state;
+      else if (IS_BEGBUF_CONTEXT (context) && IS_NEWLINE_CONTEXT (context))
+	return dfa->init_state_begbuf;
+      else if (IS_NEWLINE_CONTEXT (context))
+	return dfa->init_state_nl;
+      else if (IS_BEGBUF_CONTEXT (context))
+	{
+	  /* It is relatively rare case, then calculate on demand.  */
+	  return re_acquire_state_context (err, dfa,
+					   dfa->init_state->entrance_nodes,
+					   context);
+	}
+      else
+	/* Must not happen?  */
+	return dfa->init_state;
+    }
+  else
+    return dfa->init_state;
+}
+
+/* Check whether the regular expression match input string INPUT or not,
+   and return the index where the matching end, return -1 if not match,
+   or return -2 in case of an error.
+   FL_LONGEST_MATCH means we want the POSIX longest matching.
+   If P_MATCH_FIRST is not NULL, and the match fails, it is set to the
+   next place where we may want to try matching.
+   Note that the matcher assume that the maching starts from the current
+   index of the buffer.  */
+
+static int
+internal_function
+check_matching (re_match_context_t *mctx, int fl_longest_match,
+		int *p_match_first)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err;
+  int match = 0;
+  int match_last = -1;
+  int cur_str_idx = re_string_cur_idx (&mctx->input);
+  re_dfastate_t *cur_state;
+  int at_init_state = p_match_first != NULL;
+  int next_start_idx = cur_str_idx;
+
+  err = REG_NOERROR;
+  cur_state = acquire_init_state_context (&err, mctx, cur_str_idx);
+  /* An initial state must not be NULL (invalid).  */
+  if (BE (cur_state == NULL, 0))
+    {
+      assert (err == REG_ESPACE);
+      return -2;
+    }
+
+  if (mctx->state_log != NULL)
+    {
+      mctx->state_log[cur_str_idx] = cur_state;
+
+      /* Check OP_OPEN_SUBEXP in the initial state in case that we use them
+	 later.  E.g. Processing back references.  */
+      if (BE (dfa->nbackref, 0))
+	{
+	  at_init_state = 0;
+	  err = check_subexp_matching_top (mctx, &cur_state->nodes, 0);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+
+	  if (cur_state->has_backref)
+	    {
+	      err = transit_state_bkref (mctx, &cur_state->nodes);
+	      if (BE (err != REG_NOERROR, 0))
+		return err;
+	    }
+	}
+    }
+
+  /* If the RE accepts NULL string.  */
+  if (BE (cur_state->halt, 0))
+    {
+      if (!cur_state->has_constraint
+	  || check_halt_state_context (mctx, cur_state, cur_str_idx))
+	{
+	  if (!fl_longest_match)
+	    return cur_str_idx;
+	  else
+	    {
+	      match_last = cur_str_idx;
+	      match = 1;
+	    }
+	}
+    }
+
+  while (!re_string_eoi (&mctx->input))
+    {
+      re_dfastate_t *old_state = cur_state;
+      int next_char_idx = re_string_cur_idx (&mctx->input) + 1;
+
+      if (BE (next_char_idx >= mctx->input.bufs_len, 0)
+	  || (BE (next_char_idx >= mctx->input.valid_len, 0)
+	      && mctx->input.valid_len < mctx->input.len))
+	{
+	  err = extend_buffers (mctx);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      assert (err == REG_ESPACE);
+	      return -2;
+	    }
+	}
+
+      cur_state = transit_state (&err, mctx, cur_state);
+      if (mctx->state_log != NULL)
+	cur_state = merge_state_with_log (&err, mctx, cur_state);
+
+      if (cur_state == NULL)
+	{
+	  /* Reached the invalid state or an error.  Try to recover a valid
+	     state using the state log, if available and if we have not
+	     already found a valid (even if not the longest) match.  */
+	  if (BE (err != REG_NOERROR, 0))
+	    return -2;
+
+	  if (mctx->state_log == NULL
+	      || (match && !fl_longest_match)
+	      || (cur_state = find_recover_state (&err, mctx)) == NULL)
+	    break;
+	}
+
+      if (BE (at_init_state, 0))
+	{
+	  if (old_state == cur_state)
+	    next_start_idx = next_char_idx;
+	  else
+	    at_init_state = 0;
+	}
+
+      if (cur_state->halt)
+	{
+	  /* Reached a halt state.
+	     Check the halt state can satisfy the current context.  */
+	  if (!cur_state->has_constraint
+	      || check_halt_state_context (mctx, cur_state,
+					   re_string_cur_idx (&mctx->input)))
+	    {
+	      /* We found an appropriate halt state.  */
+	      match_last = re_string_cur_idx (&mctx->input);
+	      match = 1;
+
+	      /* We found a match, do not modify match_first below.  */
+	      p_match_first = NULL;
+	      if (!fl_longest_match)
+		break;
+	    }
+	}
+    }
+
+  if (p_match_first)
+    *p_match_first += next_start_idx;
+
+  return match_last;
+}
+
+/* Check NODE match the current context.  */
+
+static int
+internal_function
+check_halt_node_context (const re_dfa_t *dfa, int node, unsigned int context)
+{
+  re_token_type_t type = dfa->nodes[node].type;
+  unsigned int constraint = dfa->nodes[node].constraint;
+  if (type != END_OF_RE)
+    return 0;
+  if (!constraint)
+    return 1;
+  if (NOT_SATISFY_NEXT_CONSTRAINT (constraint, context))
+    return 0;
+  return 1;
+}
+
+/* Check the halt state STATE match the current context.
+   Return 0 if not match, if the node, STATE has, is a halt node and
+   match the context, return the node.  */
+
+static int
+internal_function
+check_halt_state_context (const re_match_context_t *mctx,
+			  const re_dfastate_t *state, int idx)
+{
+  int i;
+  unsigned int context;
+#ifdef DEBUG
+  assert (state->halt);
+#endif
+  context = re_string_context_at (&mctx->input, idx, mctx->eflags);
+  for (i = 0; i < state->nodes.nelem; ++i)
+    if (check_halt_node_context (mctx->dfa, state->nodes.elems[i], context))
+      return state->nodes.elems[i];
+  return 0;
+}
+
+/* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA
+   corresponding to the DFA).
+   Return the destination node, and update EPS_VIA_NODES, return -1 in case
+   of errors.  */
+
+static int
+internal_function
+proceed_next_node (const re_match_context_t *mctx, int nregs, regmatch_t *regs,
+		   int *pidx, int node, re_node_set *eps_via_nodes,
+		   struct re_fail_stack_t *fs)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  int i, err;
+  if (IS_EPSILON_NODE (dfa->nodes[node].type))
+    {
+      re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes;
+      re_node_set *edests = &dfa->edests[node];
+      int dest_node;
+      err = re_node_set_insert (eps_via_nodes, node);
+      if (BE (err < 0, 0))
+	return -2;
+      /* Pick up a valid destination, or return -1 if none is found.  */
+      for (dest_node = -1, i = 0; i < edests->nelem; ++i)
+	{
+	  int candidate = edests->elems[i];
+	  if (!re_node_set_contains (cur_nodes, candidate))
+	    continue;
+	  if (dest_node == -1)
+	    dest_node = candidate;
+
+	  else
+	    {
+	      /* In order to avoid infinite loop like "(a*)*", return the second
+		 epsilon-transition if the first was already considered.  */
+	      if (re_node_set_contains (eps_via_nodes, dest_node))
+		return candidate;
+
+	      /* Otherwise, push the second epsilon-transition on the fail stack.  */
+	      else if (fs != NULL
+		       && push_fail_stack (fs, *pidx, candidate, nregs, regs,
+					   eps_via_nodes))
+		return -2;
+
+	      /* We know we are going to exit.  */
+	      break;
+	    }
+	}
+      return dest_node;
+    }
+  else
+    {
+      int naccepted = 0;
+      re_token_type_t type = dfa->nodes[node].type;
+
+#ifdef RE_ENABLE_I18N
+      if (dfa->nodes[node].accept_mb)
+	naccepted = check_node_accept_bytes (dfa, node, &mctx->input, *pidx);
+      else
+#endif /* RE_ENABLE_I18N */
+      if (type == OP_BACK_REF)
+	{
+	  int subexp_idx = dfa->nodes[node].opr.idx + 1;
+	  naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so;
+	  if (fs != NULL)
+	    {
+	      if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1)
+		return -1;
+	      else if (naccepted)
+		{
+		  char *buf = (char *) re_string_get_buffer (&mctx->input);
+		  if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx,
+			      naccepted) != 0)
+		    return -1;
+		}
+	    }
+
+	  if (naccepted == 0)
+	    {
+	      int dest_node;
+	      err = re_node_set_insert (eps_via_nodes, node);
+	      if (BE (err < 0, 0))
+		return -2;
+	      dest_node = dfa->edests[node].elems[0];
+	      if (re_node_set_contains (&mctx->state_log[*pidx]->nodes,
+					dest_node))
+		return dest_node;
+	    }
+	}
+
+      if (naccepted != 0
+	  || check_node_accept (mctx, dfa->nodes + node, *pidx))
+	{
+	  int dest_node = dfa->nexts[node];
+	  *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted;
+	  if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL
+		     || !re_node_set_contains (&mctx->state_log[*pidx]->nodes,
+					       dest_node)))
+	    return -1;
+	  re_node_set_empty (eps_via_nodes);
+	  return dest_node;
+	}
+    }
+  return -1;
+}
+
+static reg_errcode_t
+internal_function
+push_fail_stack (struct re_fail_stack_t *fs, int str_idx, int dest_node,
+		 int nregs, regmatch_t *regs, re_node_set *eps_via_nodes)
+{
+  reg_errcode_t err;
+  int num = fs->num++;
+  if (fs->num == fs->alloc)
+    {
+      struct re_fail_stack_ent_t *new_array;
+      new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t)
+				       * fs->alloc * 2));
+      if (new_array == NULL)
+	return REG_ESPACE;
+      fs->alloc *= 2;
+      fs->stack = new_array;
+    }
+  fs->stack[num].idx = str_idx;
+  fs->stack[num].node = dest_node;
+  fs->stack[num].regs = re_malloc (regmatch_t, nregs);
+  if (fs->stack[num].regs == NULL)
+    return REG_ESPACE;
+  memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);
+  err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes);
+  return err;
+}
+
+static int
+internal_function
+pop_fail_stack (struct re_fail_stack_t *fs, int *pidx, int nregs,
+		regmatch_t *regs, re_node_set *eps_via_nodes)
+{
+  int num = --fs->num;
+  assert (num >= 0);
+  *pidx = fs->stack[num].idx;
+  memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);
+  re_node_set_free (eps_via_nodes);
+  re_free (fs->stack[num].regs);
+  *eps_via_nodes = fs->stack[num].eps_via_nodes;
+  return fs->stack[num].node;
+}
+
+/* Set the positions where the subexpressions are starts/ends to registers
+   PMATCH.
+   Note: We assume that pmatch[0] is already set, and
+   pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch.  */
+
+static reg_errcode_t
+internal_function
+set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
+	  regmatch_t *pmatch, int fl_backtrack)
+{
+  const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer;
+  int idx, cur_node;
+  re_node_set eps_via_nodes;
+  struct re_fail_stack_t *fs;
+  struct re_fail_stack_t fs_body = { 0, 2, NULL };
+  regmatch_t *prev_idx_match;
+  int prev_idx_match_malloced = 0;
+
+#ifdef DEBUG
+  assert (nmatch > 1);
+  assert (mctx->state_log != NULL);
+#endif
+  if (fl_backtrack)
+    {
+      fs = &fs_body;
+      fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc);
+      if (fs->stack == NULL)
+	return REG_ESPACE;
+    }
+  else
+    fs = NULL;
+
+  cur_node = dfa->init_node;
+  re_node_set_init_empty (&eps_via_nodes);
+
+#ifdef HAVE_ALLOCA
+  if (__libc_use_alloca (nmatch * sizeof (regmatch_t)))
+    prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t));
+  else
+#endif
+    {
+      prev_idx_match = re_malloc (regmatch_t, nmatch);
+      if (prev_idx_match == NULL)
+	{
+	  free_fail_stack_return (fs);
+	  return REG_ESPACE;
+	}
+      prev_idx_match_malloced = 1;
+    }
+  memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
+
+  for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;)
+    {
+      update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch);
+
+      if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
+	{
+	  unsigned int reg_idx;
+	  if (fs)
+	    {
+	      for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
+		if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1)
+		  break;
+	      if (reg_idx == nmatch)
+		{
+		  re_node_set_free (&eps_via_nodes);
+		  if (prev_idx_match_malloced)
+		    re_free (prev_idx_match);
+		  return free_fail_stack_return (fs);
+		}
+	      cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
+					 &eps_via_nodes);
+	    }
+	  else
+	    {
+	      re_node_set_free (&eps_via_nodes);
+	      if (prev_idx_match_malloced)
+		re_free (prev_idx_match);
+	      return REG_NOERROR;
+	    }
+	}
+
+      /* Proceed to next node.  */
+      cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node,
+				    &eps_via_nodes, fs);
+
+      if (BE (cur_node < 0, 0))
+	{
+	  if (BE (cur_node == -2, 0))
+	    {
+	      re_node_set_free (&eps_via_nodes);
+	      if (prev_idx_match_malloced)
+		re_free (prev_idx_match);
+	      free_fail_stack_return (fs);
+	      return REG_ESPACE;
+	    }
+	  if (fs)
+	    cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
+				       &eps_via_nodes);
+	  else
+	    {
+	      re_node_set_free (&eps_via_nodes);
+	      if (prev_idx_match_malloced)
+		re_free (prev_idx_match);
+	      return REG_NOMATCH;
+	    }
+	}
+    }
+  re_node_set_free (&eps_via_nodes);
+  if (prev_idx_match_malloced)
+    re_free (prev_idx_match);
+  return free_fail_stack_return (fs);
+}
+
+static reg_errcode_t
+internal_function
+free_fail_stack_return (struct re_fail_stack_t *fs)
+{
+  if (fs)
+    {
+      int fs_idx;
+      for (fs_idx = 0; fs_idx < fs->num; ++fs_idx)
+	{
+	  re_node_set_free (&fs->stack[fs_idx].eps_via_nodes);
+	  re_free (fs->stack[fs_idx].regs);
+	}
+      re_free (fs->stack);
+    }
+  return REG_NOERROR;
+}
+
+static void
+internal_function
+update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,
+	     regmatch_t *prev_idx_match, int cur_node, int cur_idx, int nmatch)
+{
+  int type = dfa->nodes[cur_node].type;
+  if (type == OP_OPEN_SUBEXP)
+    {
+      int reg_num = dfa->nodes[cur_node].opr.idx + 1;
+
+      /* We are at the first node of this sub expression.  */
+      if (reg_num < nmatch)
+	{
+	  pmatch[reg_num].rm_so = cur_idx;
+	  pmatch[reg_num].rm_eo = -1;
+	}
+    }
+  else if (type == OP_CLOSE_SUBEXP)
+    {
+      int reg_num = dfa->nodes[cur_node].opr.idx + 1;
+      if (reg_num < nmatch)
+	{
+	  /* We are at the last node of this sub expression.  */
+	  if (pmatch[reg_num].rm_so < cur_idx)
+	    {
+	      pmatch[reg_num].rm_eo = cur_idx;
+	      /* This is a non-empty match or we are not inside an optional
+		 subexpression.  Accept this right away.  */
+	      memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
+	    }
+	  else
+	    {
+	      if (dfa->nodes[cur_node].opt_subexp
+		  && prev_idx_match[reg_num].rm_so != -1)
+		/* We transited through an empty match for an optional
+		   subexpression, like (a?)*, and this is not the subexp's
+		   first match.  Copy back the old content of the registers
+		   so that matches of an inner subexpression are undone as
+		   well, like in ((a?))*.  */
+		memcpy (pmatch, prev_idx_match, sizeof (regmatch_t) * nmatch);
+	      else
+		/* We completed a subexpression, but it may be part of
+		   an optional one, so do not update PREV_IDX_MATCH.  */
+		pmatch[reg_num].rm_eo = cur_idx;
+	    }
+	}
+    }
+}
+
+/* This function checks the STATE_LOG from the SCTX->last_str_idx to 0
+   and sift the nodes in each states according to the following rules.
+   Updated state_log will be wrote to STATE_LOG.
+
+   Rules: We throw away the Node `a' in the STATE_LOG[STR_IDX] if...
+     1. When STR_IDX == MATCH_LAST(the last index in the state_log):
+	If `a' isn't the LAST_NODE and `a' can't epsilon transit to
+	the LAST_NODE, we throw away the node `a'.
+     2. When 0 <= STR_IDX < MATCH_LAST and `a' accepts
+	string `s' and transit to `b':
+	i. If 'b' isn't in the STATE_LOG[STR_IDX+strlen('s')], we throw
+	   away the node `a'.
+	ii. If 'b' is in the STATE_LOG[STR_IDX+strlen('s')] but 'b' is
+	    thrown away, we throw away the node `a'.
+     3. When 0 <= STR_IDX < MATCH_LAST and 'a' epsilon transit to 'b':
+	i. If 'b' isn't in the STATE_LOG[STR_IDX], we throw away the
+	   node `a'.
+	ii. If 'b' is in the STATE_LOG[STR_IDX] but 'b' is thrown away,
+	    we throw away the node `a'.  */
+
+#define STATE_NODE_CONTAINS(state,node) \
+  ((state) != NULL && re_node_set_contains (&(state)->nodes, node))
+
+static reg_errcode_t
+internal_function
+sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx)
+{
+  reg_errcode_t err;
+  int null_cnt = 0;
+  int str_idx = sctx->last_str_idx;
+  re_node_set cur_dest;
+
+#ifdef DEBUG
+  assert (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL);
+#endif
+
+  /* Build sifted state_log[str_idx].  It has the nodes which can epsilon
+     transit to the last_node and the last_node itself.  */
+  err = re_node_set_init_1 (&cur_dest, sctx->last_node);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+  err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
+  if (BE (err != REG_NOERROR, 0))
+    goto free_return;
+
+  /* Then check each states in the state_log.  */
+  while (str_idx > 0)
+    {
+      /* Update counters.  */
+      null_cnt = (sctx->sifted_states[str_idx] == NULL) ? null_cnt + 1 : 0;
+      if (null_cnt > mctx->max_mb_elem_len)
+	{
+	  memset (sctx->sifted_states, '\0',
+		  sizeof (re_dfastate_t *) * str_idx);
+	  re_node_set_free (&cur_dest);
+	  return REG_NOERROR;
+	}
+      re_node_set_empty (&cur_dest);
+      --str_idx;
+
+      if (mctx->state_log[str_idx])
+	{
+	  err = build_sifted_states (mctx, sctx, str_idx, &cur_dest);
+	  if (BE (err != REG_NOERROR, 0))
+	    goto free_return;
+	}
+
+      /* Add all the nodes which satisfy the following conditions:
+	 - It can epsilon transit to a node in CUR_DEST.
+	 - It is in CUR_SRC.
+	 And update state_log.  */
+      err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
+      if (BE (err != REG_NOERROR, 0))
+	goto free_return;
+    }
+  err = REG_NOERROR;
+ free_return:
+  re_node_set_free (&cur_dest);
+  return err;
+}
+
+static reg_errcode_t
+internal_function
+build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx,
+		     int str_idx, re_node_set *cur_dest)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  const re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes;
+  int i;
+
+  /* Then build the next sifted state.
+     We build the next sifted state on `cur_dest', and update
+     `sifted_states[str_idx]' with `cur_dest'.
+     Note:
+     `cur_dest' is the sifted state from `state_log[str_idx + 1]'.
+     `cur_src' points the node_set of the old `state_log[str_idx]'
+     (with the epsilon nodes pre-filtered out).  */
+  for (i = 0; i < cur_src->nelem; i++)
+    {
+      int prev_node = cur_src->elems[i];
+      int naccepted = 0;
+      int ret;
+
+#ifdef DEBUG
+      re_token_type_t type = dfa->nodes[prev_node].type;
+      assert (!IS_EPSILON_NODE (type));
+#endif
+#ifdef RE_ENABLE_I18N
+      /* If the node may accept `multi byte'.  */
+      if (dfa->nodes[prev_node].accept_mb)
+	naccepted = sift_states_iter_mb (mctx, sctx, prev_node,
+					 str_idx, sctx->last_str_idx);
+#endif /* RE_ENABLE_I18N */
+
+      /* We don't check backreferences here.
+	 See update_cur_sifted_state().  */
+      if (!naccepted
+	  && check_node_accept (mctx, dfa->nodes + prev_node, str_idx)
+	  && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1],
+				  dfa->nexts[prev_node]))
+	naccepted = 1;
+
+      if (naccepted == 0)
+	continue;
+
+      if (sctx->limits.nelem)
+	{
+	  int to_idx = str_idx + naccepted;
+	  if (check_dst_limits (mctx, &sctx->limits,
+				dfa->nexts[prev_node], to_idx,
+				prev_node, str_idx))
+	    continue;
+	}
+      ret = re_node_set_insert (cur_dest, prev_node);
+      if (BE (ret == -1, 0))
+	return REG_ESPACE;
+    }
+
+  return REG_NOERROR;
+}
+
+/* Helper functions.  */
+
+static reg_errcode_t
+internal_function
+clean_state_log_if_needed (re_match_context_t *mctx, int next_state_log_idx)
+{
+  int top = mctx->state_log_top;
+
+  if (next_state_log_idx >= mctx->input.bufs_len
+      || (next_state_log_idx >= mctx->input.valid_len
+	  && mctx->input.valid_len < mctx->input.len))
+    {
+      reg_errcode_t err;
+      err = extend_buffers (mctx);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+    }
+
+  if (top < next_state_log_idx)
+    {
+      memset (mctx->state_log + top + 1, '\0',
+	      sizeof (re_dfastate_t *) * (next_state_log_idx - top));
+      mctx->state_log_top = next_state_log_idx;
+    }
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function
+merge_state_array (const re_dfa_t *dfa, re_dfastate_t **dst,
+		   re_dfastate_t **src, int num)
+{
+  int st_idx;
+  reg_errcode_t err;
+  for (st_idx = 0; st_idx < num; ++st_idx)
+    {
+      if (dst[st_idx] == NULL)
+	dst[st_idx] = src[st_idx];
+      else if (src[st_idx] != NULL)
+	{
+	  re_node_set merged_set;
+	  err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes,
+					&src[st_idx]->nodes);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	  dst[st_idx] = re_acquire_state (&err, dfa, &merged_set);
+	  re_node_set_free (&merged_set);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	}
+    }
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function
+update_cur_sifted_state (const re_match_context_t *mctx,
+			 re_sift_context_t *sctx, int str_idx,
+			 re_node_set *dest_nodes)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err = REG_NOERROR;
+  const re_node_set *candidates;
+  candidates = ((mctx->state_log[str_idx] == NULL) ? NULL
+		: &mctx->state_log[str_idx]->nodes);
+
+  if (dest_nodes->nelem == 0)
+    sctx->sifted_states[str_idx] = NULL;
+  else
+    {
+      if (candidates)
+	{
+	  /* At first, add the nodes which can epsilon transit to a node in
+	     DEST_NODE.  */
+	  err = add_epsilon_src_nodes (dfa, dest_nodes, candidates);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+
+	  /* Then, check the limitations in the current sift_context.  */
+	  if (sctx->limits.nelem)
+	    {
+	      err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits,
+					 mctx->bkref_ents, str_idx);
+	      if (BE (err != REG_NOERROR, 0))
+		return err;
+	    }
+	}
+
+      sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+    }
+
+  if (candidates && mctx->state_log[str_idx]->has_backref)
+    {
+      err = sift_states_bkref (mctx, sctx, str_idx, candidates);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+    }
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function
+add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes,
+		       const re_node_set *candidates)
+{
+  reg_errcode_t err = REG_NOERROR;
+  int i;
+
+  re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+
+  if (!state->inveclosure.alloc)
+    {
+      err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem);
+      if (BE (err != REG_NOERROR, 0))
+	return REG_ESPACE;
+      for (i = 0; i < dest_nodes->nelem; i++)
+	{
+	  err = re_node_set_merge (&state->inveclosure,
+				   dfa->inveclosures + dest_nodes->elems[i]);
+	  if (BE (err != REG_NOERROR, 0))
+	    return REG_ESPACE;
+	}
+    }
+  return re_node_set_add_intersect (dest_nodes, candidates,
+				    &state->inveclosure);
+}
+
+static reg_errcode_t
+internal_function
+sub_epsilon_src_nodes (const re_dfa_t *dfa, int node, re_node_set *dest_nodes,
+		       const re_node_set *candidates)
+{
+    int ecl_idx;
+    reg_errcode_t err;
+    re_node_set *inv_eclosure = dfa->inveclosures + node;
+    re_node_set except_nodes;
+    re_node_set_init_empty (&except_nodes);
+    for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
+      {
+	int cur_node = inv_eclosure->elems[ecl_idx];
+	if (cur_node == node)
+	  continue;
+	if (IS_EPSILON_NODE (dfa->nodes[cur_node].type))
+	  {
+	    int edst1 = dfa->edests[cur_node].elems[0];
+	    int edst2 = ((dfa->edests[cur_node].nelem > 1)
+			 ? dfa->edests[cur_node].elems[1] : -1);
+	    if ((!re_node_set_contains (inv_eclosure, edst1)
+		 && re_node_set_contains (dest_nodes, edst1))
+		|| (edst2 > 0
+		    && !re_node_set_contains (inv_eclosure, edst2)
+		    && re_node_set_contains (dest_nodes, edst2)))
+	      {
+		err = re_node_set_add_intersect (&except_nodes, candidates,
+						 dfa->inveclosures + cur_node);
+		if (BE (err != REG_NOERROR, 0))
+		  {
+		    re_node_set_free (&except_nodes);
+		    return err;
+		  }
+	      }
+	  }
+      }
+    for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
+      {
+	int cur_node = inv_eclosure->elems[ecl_idx];
+	if (!re_node_set_contains (&except_nodes, cur_node))
+	  {
+	    int idx = re_node_set_contains (dest_nodes, cur_node) - 1;
+	    re_node_set_remove_at (dest_nodes, idx);
+	  }
+      }
+    re_node_set_free (&except_nodes);
+    return REG_NOERROR;
+}
+
+static int
+internal_function
+check_dst_limits (const re_match_context_t *mctx, re_node_set *limits,
+		  int dst_node, int dst_idx, int src_node, int src_idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  int lim_idx, src_pos, dst_pos;
+
+  int dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx);
+  int src_bkref_idx = search_cur_bkref_entry (mctx, src_idx);
+  for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
+    {
+      int subexp_idx;
+      struct re_backref_cache_entry *ent;
+      ent = mctx->bkref_ents + limits->elems[lim_idx];
+      subexp_idx = dfa->nodes[ent->node].opr.idx;
+
+      dst_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
+					   subexp_idx, dst_node, dst_idx,
+					   dst_bkref_idx);
+      src_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
+					   subexp_idx, src_node, src_idx,
+					   src_bkref_idx);
+
+      /* In case of:
+	 <src> <dst> ( <subexp> )
+	 ( <subexp> ) <src> <dst>
+	 ( <subexp1> <src> <subexp2> <dst> <subexp3> )  */
+      if (src_pos == dst_pos)
+	continue; /* This is unrelated limitation.  */
+      else
+	return 1;
+    }
+  return 0;
+}
+
+static int
+internal_function
+check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries,
+			     int subexp_idx, int from_node, int bkref_idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  const re_node_set *eclosures = dfa->eclosures + from_node;
+  int node_idx;
+
+  /* Else, we are on the boundary: examine the nodes on the epsilon
+     closure.  */
+  for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx)
+    {
+      int node = eclosures->elems[node_idx];
+      switch (dfa->nodes[node].type)
+	{
+	case OP_BACK_REF:
+	  if (bkref_idx != -1)
+	    {
+	      struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx;
+	      do
+		{
+		  int dst, cpos;
+
+		  if (ent->node != node)
+		    continue;
+
+		  if (subexp_idx < BITSET_WORD_BITS
+		      && !(ent->eps_reachable_subexps_map
+			   & ((bitset_word_t) 1 << subexp_idx)))
+		    continue;
+
+		  /* Recurse trying to reach the OP_OPEN_SUBEXP and
+		     OP_CLOSE_SUBEXP cases below.  But, if the
+		     destination node is the same node as the source
+		     node, don't recurse because it would cause an
+		     infinite loop: a regex that exhibits this behavior
+		     is ()\1*\1*  */
+		  dst = dfa->edests[node].elems[0];
+		  if (dst == from_node)
+		    {
+		      if (boundaries & 1)
+			return -1;
+		      else /* if (boundaries & 2) */
+			return 0;
+		    }
+
+		  cpos =
+		    check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,
+						 dst, bkref_idx);
+		  if (cpos == -1 /* && (boundaries & 1) */)
+		    return -1;
+		  if (cpos == 0 && (boundaries & 2))
+		    return 0;
+
+		  if (subexp_idx < BITSET_WORD_BITS)
+		    ent->eps_reachable_subexps_map
+		      &= ~((bitset_word_t) 1 << subexp_idx);
+		}
+	      while (ent++->more);
+	    }
+	  break;
+
+	case OP_OPEN_SUBEXP:
+	  if ((boundaries & 1) && subexp_idx == dfa->nodes[node].opr.idx)
+	    return -1;
+	  break;
+
+	case OP_CLOSE_SUBEXP:
+	  if ((boundaries & 2) && subexp_idx == dfa->nodes[node].opr.idx)
+	    return 0;
+	  break;
+
+	default:
+	    break;
+	}
+    }
+
+  return (boundaries & 2) ? 1 : 0;
+}
+
+static int
+internal_function
+check_dst_limits_calc_pos (const re_match_context_t *mctx, int limit,
+			   int subexp_idx, int from_node, int str_idx,
+			   int bkref_idx)
+{
+  struct re_backref_cache_entry *lim = mctx->bkref_ents + limit;
+  int boundaries;
+
+  /* If we are outside the range of the subexpression, return -1 or 1.  */
+  if (str_idx < lim->subexp_from)
+    return -1;
+
+  if (lim->subexp_to < str_idx)
+    return 1;
+
+  /* If we are within the subexpression, return 0.  */
+  boundaries = (str_idx == lim->subexp_from);
+  boundaries |= (str_idx == lim->subexp_to) << 1;
+  if (boundaries == 0)
+    return 0;
+
+  /* Else, examine epsilon closure.  */
+  return check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,
+				      from_node, bkref_idx);
+}
+
+/* Check the limitations of sub expressions LIMITS, and remove the nodes
+   which are against limitations from DEST_NODES. */
+
+static reg_errcode_t
+internal_function
+check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes,
+		     const re_node_set *candidates, re_node_set *limits,
+		     struct re_backref_cache_entry *bkref_ents, int str_idx)
+{
+  reg_errcode_t err;
+  int node_idx, lim_idx;
+
+  for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
+    {
+      int subexp_idx;
+      struct re_backref_cache_entry *ent;
+      ent = bkref_ents + limits->elems[lim_idx];
+
+      if (str_idx <= ent->subexp_from || ent->str_idx < str_idx)
+	continue; /* This is unrelated limitation.  */
+
+      subexp_idx = dfa->nodes[ent->node].opr.idx;
+      if (ent->subexp_to == str_idx)
+	{
+	  int ops_node = -1;
+	  int cls_node = -1;
+	  for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
+	    {
+	      int node = dest_nodes->elems[node_idx];
+	      re_token_type_t type = dfa->nodes[node].type;
+	      if (type == OP_OPEN_SUBEXP
+		  && subexp_idx == dfa->nodes[node].opr.idx)
+		ops_node = node;
+	      else if (type == OP_CLOSE_SUBEXP
+		       && subexp_idx == dfa->nodes[node].opr.idx)
+		cls_node = node;
+	    }
+
+	  /* Check the limitation of the open subexpression.  */
+	  /* Note that (ent->subexp_to = str_idx != ent->subexp_from).  */
+	  if (ops_node >= 0)
+	    {
+	      err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes,
+					   candidates);
+	      if (BE (err != REG_NOERROR, 0))
+		return err;
+	    }
+
+	  /* Check the limitation of the close subexpression.  */
+	  if (cls_node >= 0)
+	    for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
+	      {
+		int node = dest_nodes->elems[node_idx];
+		if (!re_node_set_contains (dfa->inveclosures + node,
+					   cls_node)
+		    && !re_node_set_contains (dfa->eclosures + node,
+					      cls_node))
+		  {
+		    /* It is against this limitation.
+		       Remove it form the current sifted state.  */
+		    err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
+						 candidates);
+		    if (BE (err != REG_NOERROR, 0))
+		      return err;
+		    --node_idx;
+		  }
+	      }
+	}
+      else /* (ent->subexp_to != str_idx)  */
+	{
+	  for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
+	    {
+	      int node = dest_nodes->elems[node_idx];
+	      re_token_type_t type = dfa->nodes[node].type;
+	      if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP)
+		{
+		  if (subexp_idx != dfa->nodes[node].opr.idx)
+		    continue;
+		  /* It is against this limitation.
+		     Remove it form the current sifted state.  */
+		  err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
+					       candidates);
+		  if (BE (err != REG_NOERROR, 0))
+		    return err;
+		}
+	    }
+	}
+    }
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function
+sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx,
+		   int str_idx, const re_node_set *candidates)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err;
+  int node_idx, node;
+  re_sift_context_t local_sctx;
+  int first_idx = search_cur_bkref_entry (mctx, str_idx);
+
+  if (first_idx == -1)
+    return REG_NOERROR;
+
+  local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized.  */
+
+  for (node_idx = 0; node_idx < candidates->nelem; ++node_idx)
+    {
+      int enabled_idx;
+      re_token_type_t type;
+      struct re_backref_cache_entry *entry;
+      node = candidates->elems[node_idx];
+      type = dfa->nodes[node].type;
+      /* Avoid infinite loop for the REs like "()\1+".  */
+      if (node == sctx->last_node && str_idx == sctx->last_str_idx)
+	continue;
+      if (type != OP_BACK_REF)
+	continue;
+
+      entry = mctx->bkref_ents + first_idx;
+      enabled_idx = first_idx;
+      do
+	{
+	  int subexp_len;
+	  int to_idx;
+	  int dst_node;
+	  int ret;
+	  re_dfastate_t *cur_state;
+
+	  if (entry->node != node)
+	    continue;
+	  subexp_len = entry->subexp_to - entry->subexp_from;
+	  to_idx = str_idx + subexp_len;
+	  dst_node = (subexp_len ? dfa->nexts[node]
+		      : dfa->edests[node].elems[0]);
+
+	  if (to_idx > sctx->last_str_idx
+	      || sctx->sifted_states[to_idx] == NULL
+	      || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx], dst_node)
+	      || check_dst_limits (mctx, &sctx->limits, node,
+				   str_idx, dst_node, to_idx))
+	    continue;
+
+	  if (local_sctx.sifted_states == NULL)
+	    {
+	      local_sctx = *sctx;
+	      err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits);
+	      if (BE (err != REG_NOERROR, 0))
+		goto free_return;
+	    }
+	  local_sctx.last_node = node;
+	  local_sctx.last_str_idx = str_idx;
+	  ret = re_node_set_insert (&local_sctx.limits, enabled_idx);
+	  if (BE (ret < 0, 0))
+	    {
+	      err = REG_ESPACE;
+	      goto free_return;
+	    }
+	  cur_state = local_sctx.sifted_states[str_idx];
+	  err = sift_states_backward (mctx, &local_sctx);
+	  if (BE (err != REG_NOERROR, 0))
+	    goto free_return;
+	  if (sctx->limited_states != NULL)
+	    {
+	      err = merge_state_array (dfa, sctx->limited_states,
+				       local_sctx.sifted_states,
+				       str_idx + 1);
+	      if (BE (err != REG_NOERROR, 0))
+		goto free_return;
+	    }
+	  local_sctx.sifted_states[str_idx] = cur_state;
+	  re_node_set_remove (&local_sctx.limits, enabled_idx);
+
+	  /* mctx->bkref_ents may have changed, reload the pointer.  */
+	  entry = mctx->bkref_ents + enabled_idx;
+	}
+      while (enabled_idx++, entry++->more);
+    }
+  err = REG_NOERROR;
+ free_return:
+  if (local_sctx.sifted_states != NULL)
+    {
+      re_node_set_free (&local_sctx.limits);
+    }
+
+  return err;
+}
+
+
+#ifdef RE_ENABLE_I18N
+static int
+internal_function
+sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx,
+		     int node_idx, int str_idx, int max_str_idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  int naccepted;
+  /* Check the node can accept `multi byte'.  */
+  naccepted = check_node_accept_bytes (dfa, node_idx, &mctx->input, str_idx);
+  if (naccepted > 0 && str_idx + naccepted <= max_str_idx &&
+      !STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + naccepted],
+			    dfa->nexts[node_idx]))
+    /* The node can't accept the `multi byte', or the
+       destination was already thrown away, then the node
+       could't accept the current input `multi byte'.   */
+    naccepted = 0;
+  /* Otherwise, it is sure that the node could accept
+     `naccepted' bytes input.  */
+  return naccepted;
+}
+#endif /* RE_ENABLE_I18N */
+
+
+/* Functions for state transition.  */
+
+/* Return the next state to which the current state STATE will transit by
+   accepting the current input byte, and update STATE_LOG if necessary.
+   If STATE can accept a multibyte char/collating element/back reference
+   update the destination of STATE_LOG.  */
+
+static re_dfastate_t *
+internal_function
+transit_state (reg_errcode_t *err, re_match_context_t *mctx,
+	       re_dfastate_t *state)
+{
+  re_dfastate_t **trtable;
+  unsigned char ch;
+
+#ifdef RE_ENABLE_I18N
+  /* If the current state can accept multibyte.  */
+  if (BE (state->accept_mb, 0))
+    {
+      *err = transit_state_mb (mctx, state);
+      if (BE (*err != REG_NOERROR, 0))
+	return NULL;
+    }
+#endif /* RE_ENABLE_I18N */
+
+  /* Then decide the next state with the single byte.  */
+#if 0
+  if (0)
+    /* don't use transition table  */
+    return transit_state_sb (err, mctx, state);
+#endif
+
+  /* Use transition table  */
+  ch = re_string_fetch_byte (&mctx->input);
+  for (;;)
+    {
+      trtable = state->trtable;
+      if (BE (trtable != NULL, 1))
+	return trtable[ch];
+
+      trtable = state->word_trtable;
+      if (BE (trtable != NULL, 1))
+	{
+	  unsigned int context;
+	  context
+	    = re_string_context_at (&mctx->input,
+				    re_string_cur_idx (&mctx->input) - 1,
+				    mctx->eflags);
+	  if (IS_WORD_CONTEXT (context))
+	    return trtable[ch + SBC_MAX];
+	  else
+	    return trtable[ch];
+	}
+
+      if (!build_trtable (mctx->dfa, state))
+	{
+	  *err = REG_ESPACE;
+	  return NULL;
+	}
+
+      /* Retry, we now have a transition table.  */
+    }
+}
+
+/* Update the state_log if we need */
+re_dfastate_t *
+internal_function
+merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx,
+		      re_dfastate_t *next_state)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  int cur_idx = re_string_cur_idx (&mctx->input);
+
+  if (cur_idx > mctx->state_log_top)
+    {
+      mctx->state_log[cur_idx] = next_state;
+      mctx->state_log_top = cur_idx;
+    }
+  else if (mctx->state_log[cur_idx] == 0)
+    {
+      mctx->state_log[cur_idx] = next_state;
+    }
+  else
+    {
+      re_dfastate_t *pstate;
+      unsigned int context;
+      re_node_set next_nodes, *log_nodes, *table_nodes = NULL;
+      /* If (state_log[cur_idx] != 0), it implies that cur_idx is
+	 the destination of a multibyte char/collating element/
+	 back reference.  Then the next state is the union set of
+	 these destinations and the results of the transition table.  */
+      pstate = mctx->state_log[cur_idx];
+      log_nodes = pstate->entrance_nodes;
+      if (next_state != NULL)
+	{
+	  table_nodes = next_state->entrance_nodes;
+	  *err = re_node_set_init_union (&next_nodes, table_nodes,
+					     log_nodes);
+	  if (BE (*err != REG_NOERROR, 0))
+	    return NULL;
+	}
+      else
+	next_nodes = *log_nodes;
+      /* Note: We already add the nodes of the initial state,
+	 then we don't need to add them here.  */
+
+      context = re_string_context_at (&mctx->input,
+				      re_string_cur_idx (&mctx->input) - 1,
+				      mctx->eflags);
+      next_state = mctx->state_log[cur_idx]
+	= re_acquire_state_context (err, dfa, &next_nodes, context);
+      /* We don't need to check errors here, since the return value of
+	 this function is next_state and ERR is already set.  */
+
+      if (table_nodes != NULL)
+	re_node_set_free (&next_nodes);
+    }
+
+  if (BE (dfa->nbackref, 0) && next_state != NULL)
+    {
+      /* Check OP_OPEN_SUBEXP in the current state in case that we use them
+	 later.  We must check them here, since the back references in the
+	 next state might use them.  */
+      *err = check_subexp_matching_top (mctx, &next_state->nodes,
+					cur_idx);
+      if (BE (*err != REG_NOERROR, 0))
+	return NULL;
+
+      /* If the next state has back references.  */
+      if (next_state->has_backref)
+	{
+	  *err = transit_state_bkref (mctx, &next_state->nodes);
+	  if (BE (*err != REG_NOERROR, 0))
+	    return NULL;
+	  next_state = mctx->state_log[cur_idx];
+	}
+    }
+
+  return next_state;
+}
+
+/* Skip bytes in the input that correspond to part of a
+   multi-byte match, then look in the log for a state
+   from which to restart matching.  */
+re_dfastate_t *
+internal_function
+find_recover_state (reg_errcode_t *err, re_match_context_t *mctx)
+{
+  re_dfastate_t *cur_state;
+  do
+    {
+      int max = mctx->state_log_top;
+      int cur_str_idx = re_string_cur_idx (&mctx->input);
+
+      do
+	{
+	  if (++cur_str_idx > max)
+	    return NULL;
+	  re_string_skip_bytes (&mctx->input, 1);
+	}
+      while (mctx->state_log[cur_str_idx] == NULL);
+
+      cur_state = merge_state_with_log (err, mctx, NULL);
+    }
+  while (*err == REG_NOERROR && cur_state == NULL);
+  return cur_state;
+}
+
+/* Helper functions for transit_state.  */
+
+/* From the node set CUR_NODES, pick up the nodes whose types are
+   OP_OPEN_SUBEXP and which have corresponding back references in the regular
+   expression. And register them to use them later for evaluating the
+   correspoding back references.  */
+
+static reg_errcode_t
+internal_function
+check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes,
+			   int str_idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  int node_idx;
+  reg_errcode_t err;
+
+  /* TODO: This isn't efficient.
+	   Because there might be more than one nodes whose types are
+	   OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
+	   nodes.
+	   E.g. RE: (a){2}  */
+  for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx)
+    {
+      int node = cur_nodes->elems[node_idx];
+      if (dfa->nodes[node].type == OP_OPEN_SUBEXP
+	  && dfa->nodes[node].opr.idx < BITSET_WORD_BITS
+	  && (dfa->used_bkref_map
+	      & ((bitset_word_t) 1 << dfa->nodes[node].opr.idx)))
+	{
+	  err = match_ctx_add_subtop (mctx, node, str_idx);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	}
+    }
+  return REG_NOERROR;
+}
+
+#if 0
+/* Return the next state to which the current state STATE will transit by
+   accepting the current input byte.  */
+
+static re_dfastate_t *
+transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx,
+		  re_dfastate_t *state)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  re_node_set next_nodes;
+  re_dfastate_t *next_state;
+  int node_cnt, cur_str_idx = re_string_cur_idx (&mctx->input);
+  unsigned int context;
+
+  *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1);
+  if (BE (*err != REG_NOERROR, 0))
+    return NULL;
+  for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt)
+    {
+      int cur_node = state->nodes.elems[node_cnt];
+      if (check_node_accept (mctx, dfa->nodes + cur_node, cur_str_idx))
+	{
+	  *err = re_node_set_merge (&next_nodes,
+				    dfa->eclosures + dfa->nexts[cur_node]);
+	  if (BE (*err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&next_nodes);
+	      return NULL;
+	    }
+	}
+    }
+  context = re_string_context_at (&mctx->input, cur_str_idx, mctx->eflags);
+  next_state = re_acquire_state_context (err, dfa, &next_nodes, context);
+  /* We don't need to check errors here, since the return value of
+     this function is next_state and ERR is already set.  */
+
+  re_node_set_free (&next_nodes);
+  re_string_skip_bytes (&mctx->input, 1);
+  return next_state;
+}
+#endif
+
+#ifdef RE_ENABLE_I18N
+static reg_errcode_t
+internal_function
+transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err;
+  int i;
+
+  for (i = 0; i < pstate->nodes.nelem; ++i)
+    {
+      re_node_set dest_nodes, *new_nodes;
+      int cur_node_idx = pstate->nodes.elems[i];
+      int naccepted, dest_idx;
+      unsigned int context;
+      re_dfastate_t *dest_state;
+
+      if (!dfa->nodes[cur_node_idx].accept_mb)
+	continue;
+
+      if (dfa->nodes[cur_node_idx].constraint)
+	{
+	  context = re_string_context_at (&mctx->input,
+					  re_string_cur_idx (&mctx->input),
+					  mctx->eflags);
+	  if (NOT_SATISFY_NEXT_CONSTRAINT (dfa->nodes[cur_node_idx].constraint,
+					   context))
+	    continue;
+	}
+
+      /* How many bytes the node can accept?  */
+      naccepted = check_node_accept_bytes (dfa, cur_node_idx, &mctx->input,
+					   re_string_cur_idx (&mctx->input));
+      if (naccepted == 0)
+	continue;
+
+      /* The node can accepts `naccepted' bytes.  */
+      dest_idx = re_string_cur_idx (&mctx->input) + naccepted;
+      mctx->max_mb_elem_len = ((mctx->max_mb_elem_len < naccepted) ? naccepted
+			       : mctx->max_mb_elem_len);
+      err = clean_state_log_if_needed (mctx, dest_idx);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+#ifdef DEBUG
+      assert (dfa->nexts[cur_node_idx] != -1);
+#endif
+      new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx];
+
+      dest_state = mctx->state_log[dest_idx];
+      if (dest_state == NULL)
+	dest_nodes = *new_nodes;
+      else
+	{
+	  err = re_node_set_init_union (&dest_nodes,
+					dest_state->entrance_nodes, new_nodes);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	}
+      context = re_string_context_at (&mctx->input, dest_idx - 1,
+				      mctx->eflags);
+      mctx->state_log[dest_idx]
+	= re_acquire_state_context (&err, dfa, &dest_nodes, context);
+      if (dest_state != NULL)
+	re_node_set_free (&dest_nodes);
+      if (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0))
+	return err;
+    }
+  return REG_NOERROR;
+}
+#endif /* RE_ENABLE_I18N */
+
+static reg_errcode_t
+internal_function
+transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err;
+  int i;
+  int cur_str_idx = re_string_cur_idx (&mctx->input);
+
+  for (i = 0; i < nodes->nelem; ++i)
+    {
+      int dest_str_idx, prev_nelem, bkc_idx;
+      int node_idx = nodes->elems[i];
+      unsigned int context;
+      const re_token_t *node = dfa->nodes + node_idx;
+      re_node_set *new_dest_nodes;
+
+      /* Check whether `node' is a backreference or not.  */
+      if (node->type != OP_BACK_REF)
+	continue;
+
+      if (node->constraint)
+	{
+	  context = re_string_context_at (&mctx->input, cur_str_idx,
+					  mctx->eflags);
+	  if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))
+	    continue;
+	}
+
+      /* `node' is a backreference.
+	 Check the substring which the substring matched.  */
+      bkc_idx = mctx->nbkref_ents;
+      err = get_subexp (mctx, node_idx, cur_str_idx);
+      if (BE (err != REG_NOERROR, 0))
+	goto free_return;
+
+      /* And add the epsilon closures (which is `new_dest_nodes') of
+	 the backreference to appropriate state_log.  */
+#ifdef DEBUG
+      assert (dfa->nexts[node_idx] != -1);
+#endif
+      for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx)
+	{
+	  int subexp_len;
+	  re_dfastate_t *dest_state;
+	  struct re_backref_cache_entry *bkref_ent;
+	  bkref_ent = mctx->bkref_ents + bkc_idx;
+	  if (bkref_ent->node != node_idx || bkref_ent->str_idx != cur_str_idx)
+	    continue;
+	  subexp_len = bkref_ent->subexp_to - bkref_ent->subexp_from;
+	  new_dest_nodes = (subexp_len == 0
+			    ? dfa->eclosures + dfa->edests[node_idx].elems[0]
+			    : dfa->eclosures + dfa->nexts[node_idx]);
+	  dest_str_idx = (cur_str_idx + bkref_ent->subexp_to
+			  - bkref_ent->subexp_from);
+	  context = re_string_context_at (&mctx->input, dest_str_idx - 1,
+					  mctx->eflags);
+	  dest_state = mctx->state_log[dest_str_idx];
+	  prev_nelem = ((mctx->state_log[cur_str_idx] == NULL) ? 0
+			: mctx->state_log[cur_str_idx]->nodes.nelem);
+	  /* Add `new_dest_node' to state_log.  */
+	  if (dest_state == NULL)
+	    {
+	      mctx->state_log[dest_str_idx]
+		= re_acquire_state_context (&err, dfa, new_dest_nodes,
+					    context);
+	      if (BE (mctx->state_log[dest_str_idx] == NULL
+		      && err != REG_NOERROR, 0))
+		goto free_return;
+	    }
+	  else
+	    {
+	      re_node_set dest_nodes;
+	      err = re_node_set_init_union (&dest_nodes,
+					    dest_state->entrance_nodes,
+					    new_dest_nodes);
+	      if (BE (err != REG_NOERROR, 0))
+		{
+		  re_node_set_free (&dest_nodes);
+		  goto free_return;
+		}
+	      mctx->state_log[dest_str_idx]
+		= re_acquire_state_context (&err, dfa, &dest_nodes, context);
+	      re_node_set_free (&dest_nodes);
+	      if (BE (mctx->state_log[dest_str_idx] == NULL
+		      && err != REG_NOERROR, 0))
+		goto free_return;
+	    }
+	  /* We need to check recursively if the backreference can epsilon
+	     transit.  */
+	  if (subexp_len == 0
+	      && mctx->state_log[cur_str_idx]->nodes.nelem > prev_nelem)
+	    {
+	      err = check_subexp_matching_top (mctx, new_dest_nodes,
+					       cur_str_idx);
+	      if (BE (err != REG_NOERROR, 0))
+		goto free_return;
+	      err = transit_state_bkref (mctx, new_dest_nodes);
+	      if (BE (err != REG_NOERROR, 0))
+		goto free_return;
+	    }
+	}
+    }
+  err = REG_NOERROR;
+ free_return:
+  return err;
+}
+
+/* Enumerate all the candidates which the backreference BKREF_NODE can match
+   at BKREF_STR_IDX, and register them by match_ctx_add_entry().
+   Note that we might collect inappropriate candidates here.
+   However, the cost of checking them strictly here is too high, then we
+   delay these checking for prune_impossible_nodes().  */
+
+static reg_errcode_t
+internal_function
+get_subexp (re_match_context_t *mctx, int bkref_node, int bkref_str_idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  int subexp_num, sub_top_idx;
+  const char *buf = (const char *) re_string_get_buffer (&mctx->input);
+  /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX.  */
+  int cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx);
+  if (cache_idx != -1)
+    {
+      const struct re_backref_cache_entry *entry
+	= mctx->bkref_ents + cache_idx;
+      do
+	if (entry->node == bkref_node)
+	  return REG_NOERROR; /* We already checked it.  */
+      while (entry++->more);
+    }
+
+  subexp_num = dfa->nodes[bkref_node].opr.idx;
+
+  /* For each sub expression  */
+  for (sub_top_idx = 0; sub_top_idx < mctx->nsub_tops; ++sub_top_idx)
+    {
+      reg_errcode_t err;
+      re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx];
+      re_sub_match_last_t *sub_last;
+      int sub_last_idx, sl_str, bkref_str_off;
+
+      if (dfa->nodes[sub_top->node].opr.idx != subexp_num)
+	continue; /* It isn't related.  */
+
+      sl_str = sub_top->str_idx;
+      bkref_str_off = bkref_str_idx;
+      /* At first, check the last node of sub expressions we already
+	 evaluated.  */
+      for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx)
+	{
+	  int sl_str_diff;
+	  sub_last = sub_top->lasts[sub_last_idx];
+	  sl_str_diff = sub_last->str_idx - sl_str;
+	  /* The matched string by the sub expression match with the substring
+	     at the back reference?  */
+	  if (sl_str_diff > 0)
+	    {
+	      if (BE (bkref_str_off + sl_str_diff > mctx->input.valid_len, 0))
+		{
+		  /* Not enough chars for a successful match.  */
+		  if (bkref_str_off + sl_str_diff > mctx->input.len)
+		    break;
+
+		  err = clean_state_log_if_needed (mctx,
+						   bkref_str_off
+						   + sl_str_diff);
+		  if (BE (err != REG_NOERROR, 0))
+		    return err;
+		  buf = (const char *) re_string_get_buffer (&mctx->input);
+		}
+	      if (memcmp (buf + bkref_str_off, buf + sl_str, sl_str_diff) != 0)
+		/* We don't need to search this sub expression any more.  */
+		break;
+	    }
+	  bkref_str_off += sl_str_diff;
+	  sl_str += sl_str_diff;
+	  err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,
+				bkref_str_idx);
+
+	  /* Reload buf, since the preceding call might have reallocated
+	     the buffer.  */
+	  buf = (const char *) re_string_get_buffer (&mctx->input);
+
+	  if (err == REG_NOMATCH)
+	    continue;
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	}
+
+      if (sub_last_idx < sub_top->nlasts)
+	continue;
+      if (sub_last_idx > 0)
+	++sl_str;
+      /* Then, search for the other last nodes of the sub expression.  */
+      for (; sl_str <= bkref_str_idx; ++sl_str)
+	{
+	  int cls_node, sl_str_off;
+	  const re_node_set *nodes;
+	  sl_str_off = sl_str - sub_top->str_idx;
+	  /* The matched string by the sub expression match with the substring
+	     at the back reference?  */
+	  if (sl_str_off > 0)
+	    {
+	      if (BE (bkref_str_off >= mctx->input.valid_len, 0))
+		{
+		  /* If we are at the end of the input, we cannot match.  */
+		  if (bkref_str_off >= mctx->input.len)
+		    break;
+
+		  err = extend_buffers (mctx);
+		  if (BE (err != REG_NOERROR, 0))
+		    return err;
+
+		  buf = (const char *) re_string_get_buffer (&mctx->input);
+		}
+	      if (buf [bkref_str_off++] != buf[sl_str - 1])
+		break; /* We don't need to search this sub expression
+			  any more.  */
+	    }
+	  if (mctx->state_log[sl_str] == NULL)
+	    continue;
+	  /* Does this state have a ')' of the sub expression?  */
+	  nodes = &mctx->state_log[sl_str]->nodes;
+	  cls_node = find_subexp_node (dfa, nodes, subexp_num,
+				       OP_CLOSE_SUBEXP);
+	  if (cls_node == -1)
+	    continue; /* No.  */
+	  if (sub_top->path == NULL)
+	    {
+	      sub_top->path = calloc (sizeof (state_array_t),
+				      sl_str - sub_top->str_idx + 1);
+	      if (sub_top->path == NULL)
+		return REG_ESPACE;
+	    }
+	  /* Can the OP_OPEN_SUBEXP node arrive the OP_CLOSE_SUBEXP node
+	     in the current context?  */
+	  err = check_arrival (mctx, sub_top->path, sub_top->node,
+			       sub_top->str_idx, cls_node, sl_str,
+			       OP_CLOSE_SUBEXP);
+	  if (err == REG_NOMATCH)
+	      continue;
+	  if (BE (err != REG_NOERROR, 0))
+	      return err;
+	  sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str);
+	  if (BE (sub_last == NULL, 0))
+	    return REG_ESPACE;
+	  err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,
+				bkref_str_idx);
+	  if (err == REG_NOMATCH)
+	    continue;
+	}
+    }
+  return REG_NOERROR;
+}
+
+/* Helper functions for get_subexp().  */
+
+/* Check SUB_LAST can arrive to the back reference BKREF_NODE at BKREF_STR.
+   If it can arrive, register the sub expression expressed with SUB_TOP
+   and SUB_LAST.  */
+
+static reg_errcode_t
+internal_function
+get_subexp_sub (re_match_context_t *mctx, const re_sub_match_top_t *sub_top,
+		re_sub_match_last_t *sub_last, int bkref_node, int bkref_str)
+{
+  reg_errcode_t err;
+  int to_idx;
+  /* Can the subexpression arrive the back reference?  */
+  err = check_arrival (mctx, &sub_last->path, sub_last->node,
+		       sub_last->str_idx, bkref_node, bkref_str,
+		       OP_OPEN_SUBEXP);
+  if (err != REG_NOERROR)
+    return err;
+  err = match_ctx_add_entry (mctx, bkref_node, bkref_str, sub_top->str_idx,
+			     sub_last->str_idx);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+  to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx;
+  return clean_state_log_if_needed (mctx, to_idx);
+}
+
+/* Find the first node which is '(' or ')' and whose index is SUBEXP_IDX.
+   Search '(' if FL_OPEN, or search ')' otherwise.
+   TODO: This function isn't efficient...
+	 Because there might be more than one nodes whose types are
+	 OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
+	 nodes.
+	 E.g. RE: (a){2}  */
+
+static int
+internal_function
+find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
+		  int subexp_idx, int type)
+{
+  int cls_idx;
+  for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx)
+    {
+      int cls_node = nodes->elems[cls_idx];
+      const re_token_t *node = dfa->nodes + cls_node;
+      if (node->type == type
+	  && node->opr.idx == subexp_idx)
+	return cls_node;
+    }
+  return -1;
+}
+
+/* Check whether the node TOP_NODE at TOP_STR can arrive to the node
+   LAST_NODE at LAST_STR.  We record the path onto PATH since it will be
+   heavily reused.
+   Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise.  */
+
+static reg_errcode_t
+internal_function
+check_arrival (re_match_context_t *mctx, state_array_t *path, int top_node,
+	       int top_str, int last_node, int last_str, int type)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err = REG_NOERROR;
+  int subexp_num, backup_cur_idx, str_idx, null_cnt;
+  re_dfastate_t *cur_state = NULL;
+  re_node_set *cur_nodes, next_nodes;
+  re_dfastate_t **backup_state_log;
+  unsigned int context;
+
+  subexp_num = dfa->nodes[top_node].opr.idx;
+  /* Extend the buffer if we need.  */
+  if (BE (path->alloc < last_str + mctx->max_mb_elem_len + 1, 0))
+    {
+      re_dfastate_t **new_array;
+      int old_alloc = path->alloc;
+      path->alloc += last_str + mctx->max_mb_elem_len + 1;
+      new_array = re_realloc (path->array, re_dfastate_t *, path->alloc);
+      if (BE (new_array == NULL, 0))
+	{
+	  path->alloc = old_alloc;
+	  return REG_ESPACE;
+	}
+      path->array = new_array;
+      memset (new_array + old_alloc, '\0',
+	      sizeof (re_dfastate_t *) * (path->alloc - old_alloc));
+    }
+
+  str_idx = path->next_idx ? path->next_idx : top_str;
+
+  /* Temporary modify MCTX.  */
+  backup_state_log = mctx->state_log;
+  backup_cur_idx = mctx->input.cur_idx;
+  mctx->state_log = path->array;
+  mctx->input.cur_idx = str_idx;
+
+  /* Setup initial node set.  */
+  context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags);
+  if (str_idx == top_str)
+    {
+      err = re_node_set_init_1 (&next_nodes, top_node);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+      err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);
+      if (BE (err != REG_NOERROR, 0))
+	{
+	  re_node_set_free (&next_nodes);
+	  return err;
+	}
+    }
+  else
+    {
+      cur_state = mctx->state_log[str_idx];
+      if (cur_state && cur_state->has_backref)
+	{
+	  err = re_node_set_init_copy (&next_nodes, &cur_state->nodes);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	}
+      else
+	re_node_set_init_empty (&next_nodes);
+    }
+  if (str_idx == top_str || (cur_state && cur_state->has_backref))
+    {
+      if (next_nodes.nelem)
+	{
+	  err = expand_bkref_cache (mctx, &next_nodes, str_idx,
+				    subexp_num, type);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&next_nodes);
+	      return err;
+	    }
+	}
+      cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
+      if (BE (cur_state == NULL && err != REG_NOERROR, 0))
+	{
+	  re_node_set_free (&next_nodes);
+	  return err;
+	}
+      mctx->state_log[str_idx] = cur_state;
+    }
+
+  for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;)
+    {
+      re_node_set_empty (&next_nodes);
+      if (mctx->state_log[str_idx + 1])
+	{
+	  err = re_node_set_merge (&next_nodes,
+				   &mctx->state_log[str_idx + 1]->nodes);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&next_nodes);
+	      return err;
+	    }
+	}
+      if (cur_state)
+	{
+	  err = check_arrival_add_next_nodes (mctx, str_idx,
+					      &cur_state->non_eps_nodes,
+					      &next_nodes);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&next_nodes);
+	      return err;
+	    }
+	}
+      ++str_idx;
+      if (next_nodes.nelem)
+	{
+	  err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&next_nodes);
+	      return err;
+	    }
+	  err = expand_bkref_cache (mctx, &next_nodes, str_idx,
+				    subexp_num, type);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&next_nodes);
+	      return err;
+	    }
+	}
+      context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags);
+      cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
+      if (BE (cur_state == NULL && err != REG_NOERROR, 0))
+	{
+	  re_node_set_free (&next_nodes);
+	  return err;
+	}
+      mctx->state_log[str_idx] = cur_state;
+      null_cnt = cur_state == NULL ? null_cnt + 1 : 0;
+    }
+  re_node_set_free (&next_nodes);
+  cur_nodes = (mctx->state_log[last_str] == NULL ? NULL
+	       : &mctx->state_log[last_str]->nodes);
+  path->next_idx = str_idx;
+
+  /* Fix MCTX.  */
+  mctx->state_log = backup_state_log;
+  mctx->input.cur_idx = backup_cur_idx;
+
+  /* Then check the current node set has the node LAST_NODE.  */
+  if (cur_nodes != NULL && re_node_set_contains (cur_nodes, last_node))
+    return REG_NOERROR;
+
+  return REG_NOMATCH;
+}
+
+/* Helper functions for check_arrival.  */
+
+/* Calculate the destination nodes of CUR_NODES at STR_IDX, and append them
+   to NEXT_NODES.
+   TODO: This function is similar to the functions transit_state*(),
+	 however this function has many additional works.
+	 Can't we unify them?  */
+
+static reg_errcode_t
+internal_function
+check_arrival_add_next_nodes (re_match_context_t *mctx, int str_idx,
+			      re_node_set *cur_nodes, re_node_set *next_nodes)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  int result;
+  int cur_idx;
+#ifdef RE_ENABLE_I18N
+  reg_errcode_t err = REG_NOERROR;
+#endif
+  re_node_set union_set;
+  re_node_set_init_empty (&union_set);
+  for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx)
+    {
+      int naccepted = 0;
+      int cur_node = cur_nodes->elems[cur_idx];
+#ifdef DEBUG
+      re_token_type_t type = dfa->nodes[cur_node].type;
+      assert (!IS_EPSILON_NODE (type));
+#endif
+#ifdef RE_ENABLE_I18N
+      /* If the node may accept `multi byte'.  */
+      if (dfa->nodes[cur_node].accept_mb)
+	{
+	  naccepted = check_node_accept_bytes (dfa, cur_node, &mctx->input,
+					       str_idx);
+	  if (naccepted > 1)
+	    {
+	      re_dfastate_t *dest_state;
+	      int next_node = dfa->nexts[cur_node];
+	      int next_idx = str_idx + naccepted;
+	      dest_state = mctx->state_log[next_idx];
+	      re_node_set_empty (&union_set);
+	      if (dest_state)
+		{
+		  err = re_node_set_merge (&union_set, &dest_state->nodes);
+		  if (BE (err != REG_NOERROR, 0))
+		    {
+		      re_node_set_free (&union_set);
+		      return err;
+		    }
+		}
+	      result = re_node_set_insert (&union_set, next_node);
+	      if (BE (result < 0, 0))
+		{
+		  re_node_set_free (&union_set);
+		  return REG_ESPACE;
+		}
+	      mctx->state_log[next_idx] = re_acquire_state (&err, dfa,
+							    &union_set);
+	      if (BE (mctx->state_log[next_idx] == NULL
+		      && err != REG_NOERROR, 0))
+		{
+		  re_node_set_free (&union_set);
+		  return err;
+		}
+	    }
+	}
+#endif /* RE_ENABLE_I18N */
+      if (naccepted
+	  || check_node_accept (mctx, dfa->nodes + cur_node, str_idx))
+	{
+	  result = re_node_set_insert (next_nodes, dfa->nexts[cur_node]);
+	  if (BE (result < 0, 0))
+	    {
+	      re_node_set_free (&union_set);
+	      return REG_ESPACE;
+	    }
+	}
+    }
+  re_node_set_free (&union_set);
+  return REG_NOERROR;
+}
+
+/* For all the nodes in CUR_NODES, add the epsilon closures of them to
+   CUR_NODES, however exclude the nodes which are:
+    - inside the sub expression whose number is EX_SUBEXP, if FL_OPEN.
+    - out of the sub expression whose number is EX_SUBEXP, if !FL_OPEN.
+*/
+
+static reg_errcode_t
+internal_function
+check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes,
+			  int ex_subexp, int type)
+{
+  reg_errcode_t err;
+  int idx, outside_node;
+  re_node_set new_nodes;
+#ifdef DEBUG
+  assert (cur_nodes->nelem);
+#endif
+  err = re_node_set_alloc (&new_nodes, cur_nodes->nelem);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+  /* Create a new node set NEW_NODES with the nodes which are epsilon
+     closures of the node in CUR_NODES.  */
+
+  for (idx = 0; idx < cur_nodes->nelem; ++idx)
+    {
+      int cur_node = cur_nodes->elems[idx];
+      const re_node_set *eclosure = dfa->eclosures + cur_node;
+      outside_node = find_subexp_node (dfa, eclosure, ex_subexp, type);
+      if (outside_node == -1)
+	{
+	  /* There are no problematic nodes, just merge them.  */
+	  err = re_node_set_merge (&new_nodes, eclosure);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&new_nodes);
+	      return err;
+	    }
+	}
+      else
+	{
+	  /* There are problematic nodes, re-calculate incrementally.  */
+	  err = check_arrival_expand_ecl_sub (dfa, &new_nodes, cur_node,
+					      ex_subexp, type);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&new_nodes);
+	      return err;
+	    }
+	}
+    }
+  re_node_set_free (cur_nodes);
+  *cur_nodes = new_nodes;
+  return REG_NOERROR;
+}
+
+/* Helper function for check_arrival_expand_ecl.
+   Check incrementally the epsilon closure of TARGET, and if it isn't
+   problematic append it to DST_NODES.  */
+
+static reg_errcode_t
+internal_function
+check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes,
+			      int target, int ex_subexp, int type)
+{
+  int cur_node;
+  for (cur_node = target; !re_node_set_contains (dst_nodes, cur_node);)
+    {
+      int err;
+
+      if (dfa->nodes[cur_node].type == type
+	  && dfa->nodes[cur_node].opr.idx == ex_subexp)
+	{
+	  if (type == OP_CLOSE_SUBEXP)
+	    {
+	      err = re_node_set_insert (dst_nodes, cur_node);
+	      if (BE (err == -1, 0))
+		return REG_ESPACE;
+	    }
+	  break;
+	}
+      err = re_node_set_insert (dst_nodes, cur_node);
+      if (BE (err == -1, 0))
+	return REG_ESPACE;
+      if (dfa->edests[cur_node].nelem == 0)
+	break;
+      if (dfa->edests[cur_node].nelem == 2)
+	{
+	  err = check_arrival_expand_ecl_sub (dfa, dst_nodes,
+					      dfa->edests[cur_node].elems[1],
+					      ex_subexp, type);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	}
+      cur_node = dfa->edests[cur_node].elems[0];
+    }
+  return REG_NOERROR;
+}
+
+
+/* For all the back references in the current state, calculate the
+   destination of the back references by the appropriate entry
+   in MCTX->BKREF_ENTS.  */
+
+static reg_errcode_t
+internal_function
+expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes,
+		    int cur_str, int subexp_num, int type)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err;
+  int cache_idx_start = search_cur_bkref_entry (mctx, cur_str);
+  struct re_backref_cache_entry *ent;
+
+  if (cache_idx_start == -1)
+    return REG_NOERROR;
+
+ restart:
+  ent = mctx->bkref_ents + cache_idx_start;
+  do
+    {
+      int to_idx, next_node;
+
+      /* Is this entry ENT is appropriate?  */
+      if (!re_node_set_contains (cur_nodes, ent->node))
+	continue; /* No.  */
+
+      to_idx = cur_str + ent->subexp_to - ent->subexp_from;
+      /* Calculate the destination of the back reference, and append it
+	 to MCTX->STATE_LOG.  */
+      if (to_idx == cur_str)
+	{
+	  /* The backreference did epsilon transit, we must re-check all the
+	     node in the current state.  */
+	  re_node_set new_dests;
+	  reg_errcode_t err2, err3;
+	  next_node = dfa->edests[ent->node].elems[0];
+	  if (re_node_set_contains (cur_nodes, next_node))
+	    continue;
+	  err = re_node_set_init_1 (&new_dests, next_node);
+	  err2 = check_arrival_expand_ecl (dfa, &new_dests, subexp_num, type);
+	  err3 = re_node_set_merge (cur_nodes, &new_dests);
+	  re_node_set_free (&new_dests);
+	  if (BE (err != REG_NOERROR || err2 != REG_NOERROR
+		  || err3 != REG_NOERROR, 0))
+	    {
+	      err = (err != REG_NOERROR ? err
+		     : (err2 != REG_NOERROR ? err2 : err3));
+	      return err;
+	    }
+	  /* TODO: It is still inefficient...  */
+	  goto restart;
+	}
+      else
+	{
+	  re_node_set union_set;
+	  next_node = dfa->nexts[ent->node];
+	  if (mctx->state_log[to_idx])
+	    {
+	      int ret;
+	      if (re_node_set_contains (&mctx->state_log[to_idx]->nodes,
+					next_node))
+		continue;
+	      err = re_node_set_init_copy (&union_set,
+					   &mctx->state_log[to_idx]->nodes);
+	      ret = re_node_set_insert (&union_set, next_node);
+	      if (BE (err != REG_NOERROR || ret < 0, 0))
+		{
+		  re_node_set_free (&union_set);
+		  err = err != REG_NOERROR ? err : REG_ESPACE;
+		  return err;
+		}
+	    }
+	  else
+	    {
+	      err = re_node_set_init_1 (&union_set, next_node);
+	      if (BE (err != REG_NOERROR, 0))
+		return err;
+	    }
+	  mctx->state_log[to_idx] = re_acquire_state (&err, dfa, &union_set);
+	  re_node_set_free (&union_set);
+	  if (BE (mctx->state_log[to_idx] == NULL
+		  && err != REG_NOERROR, 0))
+	    return err;
+	}
+    }
+  while (ent++->more);
+  return REG_NOERROR;
+}
+
+/* Build transition table for the state.
+   Return 1 if succeeded, otherwise return NULL.  */
+
+static int
+internal_function
+build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
+{
+  reg_errcode_t err;
+  int i, j, ch, need_word_trtable = 0;
+  bitset_word_t elem, mask;
+  bool dests_node_malloced = false;
+  bool dest_states_malloced = false;
+  int ndests; /* Number of the destination states from `state'.  */
+  re_dfastate_t **trtable;
+  re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl;
+  re_node_set follows, *dests_node;
+  bitset_t *dests_ch;
+  bitset_t acceptable;
+
+  struct dests_alloc
+  {
+    re_node_set dests_node[SBC_MAX];
+    bitset_t dests_ch[SBC_MAX];
+  } *dests_alloc;
+
+  /* We build DFA states which corresponds to the destination nodes
+     from `state'.  `dests_node[i]' represents the nodes which i-th
+     destination state contains, and `dests_ch[i]' represents the
+     characters which i-th destination state accepts.  */
+#ifdef HAVE_ALLOCA
+  if (__libc_use_alloca (sizeof (struct dests_alloc)))
+    dests_alloc = (struct dests_alloc *) alloca (sizeof (struct dests_alloc));
+  else
+#endif
+    {
+      dests_alloc = re_malloc (struct dests_alloc, 1);
+      if (BE (dests_alloc == NULL, 0))
+	return 0;
+      dests_node_malloced = true;
+    }
+  dests_node = dests_alloc->dests_node;
+  dests_ch = dests_alloc->dests_ch;
+
+  /* Initialize transiton table.  */
+  state->word_trtable = state->trtable = NULL;
+
+  /* At first, group all nodes belonging to `state' into several
+     destinations.  */
+  ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch);
+  if (BE (ndests <= 0, 0))
+    {
+      if (dests_node_malloced)
+	free (dests_alloc);
+      /* Return 0 in case of an error, 1 otherwise.  */
+      if (ndests == 0)
+	{
+	  state->trtable = (re_dfastate_t **)
+	    calloc (sizeof (re_dfastate_t *), SBC_MAX);
+	  return 1;
+	}
+      return 0;
+    }
+
+  err = re_node_set_alloc (&follows, ndests + 1);
+  if (BE (err != REG_NOERROR, 0))
+    goto out_free;
+
+  /* Avoid arithmetic overflow in size calculation.  */
+  if (BE ((((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX)
+	    / (3 * sizeof (re_dfastate_t *)))
+	   < (size_t)ndests),
+	  0))
+    goto out_free;
+
+#ifdef HAVE_ALLOCA
+  if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX
+			 + ndests * 3 * sizeof (re_dfastate_t *)))
+    dest_states = (re_dfastate_t **)
+      alloca (ndests * 3 * sizeof (re_dfastate_t *));
+  else
+#endif
+    {
+      dest_states = (re_dfastate_t **)
+	malloc (ndests * 3 * sizeof (re_dfastate_t *));
+      if (BE (dest_states == NULL, 0))
+	{
+out_free:
+	  if (dest_states_malloced)
+	    free (dest_states);
+	  re_node_set_free (&follows);
+	  for (i = 0; i < ndests; ++i)
+	    re_node_set_free (dests_node + i);
+	  if (dests_node_malloced)
+	    free (dests_alloc);
+	  return 0;
+	}
+      dest_states_malloced = true;
+    }
+  dest_states_word = dest_states + ndests;
+  dest_states_nl = dest_states_word + ndests;
+  bitset_empty (acceptable);
+
+  /* Then build the states for all destinations.  */
+  for (i = 0; i < ndests; ++i)
+    {
+      int next_node;
+      re_node_set_empty (&follows);
+      /* Merge the follows of this destination states.  */
+      for (j = 0; j < dests_node[i].nelem; ++j)
+	{
+	  next_node = dfa->nexts[dests_node[i].elems[j]];
+	  if (next_node != -1)
+	    {
+	      err = re_node_set_merge (&follows, dfa->eclosures + next_node);
+	      if (BE (err != REG_NOERROR, 0))
+		goto out_free;
+	    }
+	}
+      dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0);
+      if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0))
+	goto out_free;
+      /* If the new state has context constraint,
+	 build appropriate states for these contexts.  */
+      if (dest_states[i]->has_constraint)
+	{
+	  dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows,
+							  CONTEXT_WORD);
+	  if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
+	    goto out_free;
+
+	  if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)
+	    need_word_trtable = 1;
+
+	  dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
+							CONTEXT_NEWLINE);
+	  if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0))
+	    goto out_free;
+ 	}
+      else
+	{
+	  dest_states_word[i] = dest_states[i];
+	  dest_states_nl[i] = dest_states[i];
+	}
+      bitset_merge (acceptable, dests_ch[i]);
+    }
+
+  if (!BE (need_word_trtable, 0))
+    {
+      /* We don't care about whether the following character is a word
+	 character, or we are in a single-byte character set so we can
+	 discern by looking at the character code: allocate a
+	 256-entry transition table.  */
+      trtable = state->trtable =
+	(re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);
+      if (BE (trtable == NULL, 0))
+	goto out_free;
+
+      /* For all characters ch...:  */
+      for (i = 0; i < BITSET_WORDS; ++i)
+	for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;
+	     elem;
+	     mask <<= 1, elem >>= 1, ++ch)
+	  if (BE (elem & 1, 0))
+	    {
+	      /* There must be exactly one destination which accepts
+		 character ch.  See group_nodes_into_DFAstates.  */
+	      for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)
+		;
+
+	      /* j-th destination accepts the word character ch.  */
+	      if (dfa->word_char[i] & mask)
+		trtable[ch] = dest_states_word[j];
+	      else
+		trtable[ch] = dest_states[j];
+	    }
+    }
+  else
+    {
+      /* We care about whether the following character is a word
+	 character, and we are in a multi-byte character set: discern
+	 by looking at the character code: build two 256-entry
+	 transition tables, one starting at trtable[0] and one
+	 starting at trtable[SBC_MAX].  */
+      trtable = state->word_trtable =
+	(re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX);
+      if (BE (trtable == NULL, 0))
+	goto out_free;
+
+      /* For all characters ch...:  */
+      for (i = 0; i < BITSET_WORDS; ++i)
+	for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;
+	     elem;
+	     mask <<= 1, elem >>= 1, ++ch)
+	  if (BE (elem & 1, 0))
+	    {
+	      /* There must be exactly one destination which accepts
+		 character ch.  See group_nodes_into_DFAstates.  */
+	      for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)
+		;
+
+	      /* j-th destination accepts the word character ch.  */
+	      trtable[ch] = dest_states[j];
+	      trtable[ch + SBC_MAX] = dest_states_word[j];
+	    }
+    }
+
+  /* new line */
+  if (bitset_contain (acceptable, NEWLINE_CHAR))
+    {
+      /* The current state accepts newline character.  */
+      for (j = 0; j < ndests; ++j)
+	if (bitset_contain (dests_ch[j], NEWLINE_CHAR))
+	  {
+	    /* k-th destination accepts newline character.  */
+	    trtable[NEWLINE_CHAR] = dest_states_nl[j];
+	    if (need_word_trtable)
+	      trtable[NEWLINE_CHAR + SBC_MAX] = dest_states_nl[j];
+	    /* There must be only one destination which accepts
+	       newline.  See group_nodes_into_DFAstates.  */
+	    break;
+	  }
+    }
+
+  if (dest_states_malloced)
+    free (dest_states);
+
+  re_node_set_free (&follows);
+  for (i = 0; i < ndests; ++i)
+    re_node_set_free (dests_node + i);
+
+  if (dests_node_malloced)
+    free (dests_alloc);
+
+  return 1;
+}
+
+/* Group all nodes belonging to STATE into several destinations.
+   Then for all destinations, set the nodes belonging to the destination
+   to DESTS_NODE[i] and set the characters accepted by the destination
+   to DEST_CH[i].  This function return the number of destinations.  */
+
+static int
+internal_function
+group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
+			    re_node_set *dests_node, bitset_t *dests_ch)
+{
+  reg_errcode_t err;
+  int result;
+  int i, j, k;
+  int ndests; /* Number of the destinations from `state'.  */
+  bitset_t accepts; /* Characters a node can accept.  */
+  const re_node_set *cur_nodes = &state->nodes;
+  bitset_empty (accepts);
+  ndests = 0;
+
+  /* For all the nodes belonging to `state',  */
+  for (i = 0; i < cur_nodes->nelem; ++i)
+    {
+      re_token_t *node = &dfa->nodes[cur_nodes->elems[i]];
+      re_token_type_t type = node->type;
+      unsigned int constraint = node->constraint;
+
+      /* Enumerate all single byte character this node can accept.  */
+      if (type == CHARACTER)
+	bitset_set (accepts, node->opr.c);
+      else if (type == SIMPLE_BRACKET)
+	{
+	  bitset_merge (accepts, node->opr.sbcset);
+	}
+      else if (type == OP_PERIOD)
+	{
+#ifdef RE_ENABLE_I18N
+	  if (dfa->mb_cur_max > 1)
+	    bitset_merge (accepts, dfa->sb_char);
+	  else
+#endif
+	    bitset_set_all (accepts);
+	  if (!(dfa->syntax & RE_DOT_NEWLINE))
+	    bitset_clear (accepts, '\n');
+	  if (dfa->syntax & RE_DOT_NOT_NULL)
+	    bitset_clear (accepts, '\0');
+	}
+#ifdef RE_ENABLE_I18N
+      else if (type == OP_UTF8_PERIOD)
+	{
+	  memset (accepts, '\xff', sizeof (bitset_t) / 2);
+	  if (!(dfa->syntax & RE_DOT_NEWLINE))
+	    bitset_clear (accepts, '\n');
+	  if (dfa->syntax & RE_DOT_NOT_NULL)
+	    bitset_clear (accepts, '\0');
+	}
+#endif
+      else
+	continue;
+
+      /* Check the `accepts' and sift the characters which are not
+	 match it the context.  */
+      if (constraint)
+	{
+	  if (constraint & NEXT_NEWLINE_CONSTRAINT)
+	    {
+	      bool accepts_newline = bitset_contain (accepts, NEWLINE_CHAR);
+	      bitset_empty (accepts);
+	      if (accepts_newline)
+		bitset_set (accepts, NEWLINE_CHAR);
+	      else
+		continue;
+	    }
+	  if (constraint & NEXT_ENDBUF_CONSTRAINT)
+	    {
+	      bitset_empty (accepts);
+	      continue;
+	    }
+
+	  if (constraint & NEXT_WORD_CONSTRAINT)
+	    {
+	      bitset_word_t any_set = 0;
+	      if (type == CHARACTER && !node->word_char)
+		{
+		  bitset_empty (accepts);
+		  continue;
+		}
+#ifdef RE_ENABLE_I18N
+	      if (dfa->mb_cur_max > 1)
+		for (j = 0; j < BITSET_WORDS; ++j)
+		  any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j]));
+	      else
+#endif
+		for (j = 0; j < BITSET_WORDS; ++j)
+		  any_set |= (accepts[j] &= dfa->word_char[j]);
+	      if (!any_set)
+		continue;
+	    }
+	  if (constraint & NEXT_NOTWORD_CONSTRAINT)
+	    {
+	      bitset_word_t any_set = 0;
+	      if (type == CHARACTER && node->word_char)
+		{
+		  bitset_empty (accepts);
+		  continue;
+		}
+#ifdef RE_ENABLE_I18N
+	      if (dfa->mb_cur_max > 1)
+		for (j = 0; j < BITSET_WORDS; ++j)
+		  any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j]));
+	      else
+#endif
+		for (j = 0; j < BITSET_WORDS; ++j)
+		  any_set |= (accepts[j] &= ~dfa->word_char[j]);
+	      if (!any_set)
+		continue;
+	    }
+	}
+
+      /* Then divide `accepts' into DFA states, or create a new
+	 state.  Above, we make sure that accepts is not empty.  */
+      for (j = 0; j < ndests; ++j)
+	{
+	  bitset_t intersec; /* Intersection sets, see below.  */
+	  bitset_t remains;
+	  /* Flags, see below.  */
+	  bitset_word_t has_intersec, not_subset, not_consumed;
+
+	  /* Optimization, skip if this state doesn't accept the character.  */
+	  if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c))
+	    continue;
+
+	  /* Enumerate the intersection set of this state and `accepts'.  */
+	  has_intersec = 0;
+	  for (k = 0; k < BITSET_WORDS; ++k)
+	    has_intersec |= intersec[k] = accepts[k] & dests_ch[j][k];
+	  /* And skip if the intersection set is empty.  */
+	  if (!has_intersec)
+	    continue;
+
+	  /* Then check if this state is a subset of `accepts'.  */
+	  not_subset = not_consumed = 0;
+	  for (k = 0; k < BITSET_WORDS; ++k)
+	    {
+	      not_subset |= remains[k] = ~accepts[k] & dests_ch[j][k];
+	      not_consumed |= accepts[k] = accepts[k] & ~dests_ch[j][k];
+	    }
+
+	  /* If this state isn't a subset of `accepts', create a
+	     new group state, which has the `remains'. */
+	  if (not_subset)
+	    {
+	      bitset_copy (dests_ch[ndests], remains);
+	      bitset_copy (dests_ch[j], intersec);
+	      err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]);
+	      if (BE (err != REG_NOERROR, 0))
+		goto error_return;
+	      ++ndests;
+	    }
+
+	  /* Put the position in the current group. */
+	  result = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);
+	  if (BE (result < 0, 0))
+	    goto error_return;
+
+	  /* If all characters are consumed, go to next node. */
+	  if (!not_consumed)
+	    break;
+	}
+      /* Some characters remain, create a new group. */
+      if (j == ndests)
+	{
+	  bitset_copy (dests_ch[ndests], accepts);
+	  err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]);
+	  if (BE (err != REG_NOERROR, 0))
+	    goto error_return;
+	  ++ndests;
+	  bitset_empty (accepts);
+	}
+    }
+  return ndests;
+ error_return:
+  for (j = 0; j < ndests; ++j)
+    re_node_set_free (dests_node + j);
+  return -1;
+}
+
+#ifdef RE_ENABLE_I18N
+/* Check how many bytes the node `dfa->nodes[node_idx]' accepts.
+   Return the number of the bytes the node accepts.
+   STR_IDX is the current index of the input string.
+
+   This function handles the nodes which can accept one character, or
+   one collating element like '.', '[a-z]', opposite to the other nodes
+   can only accept one byte.  */
+
+static int
+internal_function
+check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
+			 const re_string_t *input, int str_idx)
+{
+  const re_token_t *node = dfa->nodes + node_idx;
+  int char_len, elem_len;
+  int i;
+  wint_t wc;
+
+  if (BE (node->type == OP_UTF8_PERIOD, 0))
+    {
+      unsigned char c = re_string_byte_at (input, str_idx), d;
+      if (BE (c < 0xc2, 1))
+	return 0;
+
+      if (str_idx + 2 > input->len)
+	return 0;
+
+      d = re_string_byte_at (input, str_idx + 1);
+      if (c < 0xe0)
+	return (d < 0x80 || d > 0xbf) ? 0 : 2;
+      else if (c < 0xf0)
+	{
+	  char_len = 3;
+	  if (c == 0xe0 && d < 0xa0)
+	    return 0;
+	}
+      else if (c < 0xf8)
+	{
+	  char_len = 4;
+	  if (c == 0xf0 && d < 0x90)
+	    return 0;
+	}
+      else if (c < 0xfc)
+	{
+	  char_len = 5;
+	  if (c == 0xf8 && d < 0x88)
+	    return 0;
+	}
+      else if (c < 0xfe)
+	{
+	  char_len = 6;
+	  if (c == 0xfc && d < 0x84)
+	    return 0;
+	}
+      else
+	return 0;
+
+      if (str_idx + char_len > input->len)
+	return 0;
+
+      for (i = 1; i < char_len; ++i)
+	{
+	  d = re_string_byte_at (input, str_idx + i);
+	  if (d < 0x80 || d > 0xbf)
+	    return 0;
+	}
+      return char_len;
+    }
+
+  char_len = re_string_char_size_at (input, str_idx);
+  if (node->type == OP_PERIOD)
+    {
+      if (char_len <= 1)
+	return 0;
+      /* FIXME: I don't think this if is needed, as both '\n'
+	 and '\0' are char_len == 1.  */
+      /* '.' accepts any one character except the following two cases.  */
+      if ((!(dfa->syntax & RE_DOT_NEWLINE) &&
+	   re_string_byte_at (input, str_idx) == '\n') ||
+	  ((dfa->syntax & RE_DOT_NOT_NULL) &&
+	   re_string_byte_at (input, str_idx) == '\0'))
+	return 0;
+      return char_len;
+    }
+
+  elem_len = re_string_elem_size_at (input, str_idx);
+  wc = __btowc(*(input->mbs+str_idx));
+  if (((elem_len <= 1 && char_len <= 1) || char_len == 0) && (wc != WEOF && wc < SBC_MAX))
+    return 0;
+
+  if (node->type == COMPLEX_BRACKET)
+    {
+      const re_charset_t *cset = node->opr.mbcset;
+# ifdef _LIBC
+      const unsigned char *pin
+	= ((const unsigned char *) re_string_get_buffer (input) + str_idx);
+      int j;
+      uint32_t nrules;
+# endif /* _LIBC */
+      int match_len = 0;
+      wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)
+		    ? re_string_wchar_at (input, str_idx) : 0);
+
+      /* match with multibyte character?  */
+      for (i = 0; i < cset->nmbchars; ++i)
+	if (wc == cset->mbchars[i])
+	  {
+	    match_len = char_len;
+	    goto check_node_accept_bytes_match;
+	  }
+      /* match with character_class?  */
+      for (i = 0; i < cset->nchar_classes; ++i)
+	{
+	  wctype_t wt = cset->char_classes[i];
+	  if (__iswctype (wc, wt))
+	    {
+	      match_len = char_len;
+	      goto check_node_accept_bytes_match;
+	    }
+	}
+
+# ifdef _LIBC
+      nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+      if (nrules != 0)
+	{
+	  unsigned int in_collseq = 0;
+	  const int32_t *table, *indirect;
+	  const unsigned char *weights, *extra;
+	  const char *collseqwc;
+	  /* This #include defines a local function!  */
+#  include <locale/weight.h>
+
+	  /* match with collating_symbol?  */
+	  if (cset->ncoll_syms)
+	    extra = (const unsigned char *)
+	      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
+	  for (i = 0; i < cset->ncoll_syms; ++i)
+	    {
+	      const unsigned char *coll_sym = extra + cset->coll_syms[i];
+	      /* Compare the length of input collating element and
+		 the length of current collating element.  */
+	      if (*coll_sym != elem_len)
+		continue;
+	      /* Compare each bytes.  */
+	      for (j = 0; j < *coll_sym; j++)
+		if (pin[j] != coll_sym[1 + j])
+		  break;
+	      if (j == *coll_sym)
+		{
+		  /* Match if every bytes is equal.  */
+		  match_len = j;
+		  goto check_node_accept_bytes_match;
+		}
+	    }
+
+	  if (cset->nranges)
+	    {
+	      if (elem_len <= char_len)
+		{
+		  collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);
+		  in_collseq = __collseq_table_lookup (collseqwc, wc);
+		}
+	      else
+		in_collseq = find_collation_sequence_value (pin, elem_len);
+	    }
+	  /* match with range expression?  */
+	  for (i = 0; i < cset->nranges; ++i)
+	    if (cset->range_starts[i] <= in_collseq
+		&& in_collseq <= cset->range_ends[i])
+	      {
+		match_len = elem_len;
+		goto check_node_accept_bytes_match;
+	      }
+
+	  /* match with equivalence_class?  */
+	  if (cset->nequiv_classes)
+	    {
+	      const unsigned char *cp = pin;
+	      table = (const int32_t *)
+		_NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+	      weights = (const unsigned char *)
+		_NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
+	      extra = (const unsigned char *)
+		_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
+	      indirect = (const int32_t *)
+		_NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
+	      int32_t idx = findidx (&cp);
+	      if (idx > 0)
+		for (i = 0; i < cset->nequiv_classes; ++i)
+		  {
+		    int32_t equiv_class_idx = cset->equiv_classes[i];
+		    size_t weight_len = weights[idx & 0xffffff];
+		    if (weight_len == weights[equiv_class_idx & 0xffffff]
+			&& (idx >> 24) == (equiv_class_idx >> 24))
+		      {
+			int cnt = 0;
+
+			idx &= 0xffffff;
+			equiv_class_idx &= 0xffffff;
+
+			while (cnt <= weight_len
+			       && (weights[equiv_class_idx + 1 + cnt]
+				   == weights[idx + 1 + cnt]))
+			  ++cnt;
+			if (cnt > weight_len)
+			  {
+			    match_len = elem_len;
+			    goto check_node_accept_bytes_match;
+			  }
+		      }
+		  }
+	    }
+	}
+      else
+# endif /* _LIBC */
+	{
+	  /* match with range expression?  */
+#if __GNUC__ >= 2
+	  wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'};
+#else
+	  wchar_t cmp_buf[] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'};
+	  cmp_buf[2] = wc;
+#endif
+	  for (i = 0; i < cset->nranges; ++i)
+	    {
+	      cmp_buf[0] = cset->range_starts[i];
+	      cmp_buf[4] = cset->range_ends[i];
+	      if (wcscoll (cmp_buf, cmp_buf + 2) <= 0
+		  && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0)
+		{
+		  match_len = char_len;
+		  goto check_node_accept_bytes_match;
+		}
+	    }
+	}
+    check_node_accept_bytes_match:
+      if (!cset->non_match)
+	return match_len;
+      else
+	{
+	  if (match_len > 0)
+	    return 0;
+	  else
+	    return (elem_len > char_len) ? elem_len : char_len;
+	}
+    }
+  return 0;
+}
+
+# ifdef _LIBC
+static unsigned int
+internal_function
+find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
+{
+  uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+  if (nrules == 0)
+    {
+      if (mbs_len == 1)
+	{
+	  /* No valid character.  Match it as a single byte character.  */
+	  const unsigned char *collseq = (const unsigned char *)
+	    _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
+	  return collseq[mbs[0]];
+	}
+      return UINT_MAX;
+    }
+  else
+    {
+      int32_t idx;
+      const unsigned char *extra = (const unsigned char *)
+	_NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
+      int32_t extrasize = (const unsigned char *)
+	_NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB + 1) - extra;
+
+      for (idx = 0; idx < extrasize;)
+	{
+	  int mbs_cnt, found = 0;
+	  int32_t elem_mbs_len;
+	  /* Skip the name of collating element name.  */
+	  idx = idx + extra[idx] + 1;
+	  elem_mbs_len = extra[idx++];
+	  if (mbs_len == elem_mbs_len)
+	    {
+	      for (mbs_cnt = 0; mbs_cnt < elem_mbs_len; ++mbs_cnt)
+		if (extra[idx + mbs_cnt] != mbs[mbs_cnt])
+		  break;
+	      if (mbs_cnt == elem_mbs_len)
+		/* Found the entry.  */
+		found = 1;
+	    }
+	  /* Skip the byte sequence of the collating element.  */
+	  idx += elem_mbs_len;
+	  /* Adjust for the alignment.  */
+	  idx = (idx + 3) & ~3;
+	  /* Skip the collation sequence value.  */
+	  idx += sizeof (uint32_t);
+	  /* Skip the wide char sequence of the collating element.  */
+	  idx = idx + sizeof (uint32_t) * (extra[idx] + 1);
+	  /* If we found the entry, return the sequence value.  */
+	  if (found)
+	    return *(uint32_t *) (extra + idx);
+	  /* Skip the collation sequence value.  */
+	  idx += sizeof (uint32_t);
+	}
+      return UINT_MAX;
+    }
+}
+# endif /* _LIBC */
+#endif /* RE_ENABLE_I18N */
+
+/* Check whether the node accepts the byte which is IDX-th
+   byte of the INPUT.  */
+
+static int
+internal_function
+check_node_accept (const re_match_context_t *mctx, const re_token_t *node,
+		   int idx)
+{
+  unsigned char ch;
+  ch = re_string_byte_at (&mctx->input, idx);
+  switch (node->type)
+    {
+    case CHARACTER:
+      if (node->opr.c != ch)
+	return 0;
+      break;
+
+    case SIMPLE_BRACKET:
+      if (!bitset_contain (node->opr.sbcset, ch))
+	return 0;
+      break;
+
+#ifdef RE_ENABLE_I18N
+    case OP_UTF8_PERIOD:
+      if (ch >= 0x80)
+	return 0;
+      /* FALLTHROUGH */
+#endif
+    case OP_PERIOD:
+      if ((ch == '\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE))
+	  || (ch == '\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL)))
+	return 0;
+      break;
+
+    default:
+      return 0;
+    }
+
+  if (node->constraint)
+    {
+      /* The node has constraints.  Check whether the current context
+	 satisfies the constraints.  */
+      unsigned int context = re_string_context_at (&mctx->input, idx,
+						   mctx->eflags);
+      if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))
+	return 0;
+    }
+
+  return 1;
+}
+
+/* Extend the buffers, if the buffers have run out.  */
+
+static reg_errcode_t
+internal_function
+extend_buffers (re_match_context_t *mctx)
+{
+  reg_errcode_t ret;
+  re_string_t *pstr = &mctx->input;
+
+  /* Avoid overflow.  */
+  if (BE (INT_MAX / 2 / sizeof (re_dfastate_t *) <= (size_t)pstr->bufs_len, 0))
+    return REG_ESPACE;
+
+  /* Double the lengthes of the buffers.  */
+  ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+
+  if (mctx->state_log != NULL)
+    {
+      /* And double the length of state_log.  */
+      /* XXX We have no indication of the size of this buffer.  If this
+	 allocation fail we have no indication that the state_log array
+	 does not have the right size.  */
+      re_dfastate_t **new_array = re_realloc (mctx->state_log, re_dfastate_t *,
+					      pstr->bufs_len + 1);
+      if (BE (new_array == NULL, 0))
+	return REG_ESPACE;
+      mctx->state_log = new_array;
+    }
+
+  /* Then reconstruct the buffers.  */
+  if (pstr->icase)
+    {
+#ifdef RE_ENABLE_I18N
+      if (pstr->mb_cur_max > 1)
+	{
+	  ret = build_wcs_upper_buffer (pstr);
+	  if (BE (ret != REG_NOERROR, 0))
+	    return ret;
+	}
+      else
+#endif /* RE_ENABLE_I18N  */
+	build_upper_buffer (pstr);
+    }
+  else
+    {
+#ifdef RE_ENABLE_I18N
+      if (pstr->mb_cur_max > 1)
+	build_wcs_buffer (pstr);
+      else
+#endif /* RE_ENABLE_I18N  */
+	{
+	  if (pstr->trans != NULL)
+	    re_string_translate_buffer (pstr);
+	}
+    }
+  return REG_NOERROR;
+}
+
+
+/* Functions for matching context.  */
+
+/* Initialize MCTX.  */
+
+static reg_errcode_t
+internal_function
+match_ctx_init (re_match_context_t *mctx, int eflags, int n)
+{
+  mctx->eflags = eflags;
+  mctx->match_last = -1;
+  if (n > 0)
+    {
+      mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n);
+      mctx->sub_tops = re_malloc (re_sub_match_top_t *, n);
+      if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0))
+	return REG_ESPACE;
+    }
+  /* Already zero-ed by the caller.
+     else
+       mctx->bkref_ents = NULL;
+     mctx->nbkref_ents = 0;
+     mctx->nsub_tops = 0;  */
+  mctx->abkref_ents = n;
+  mctx->max_mb_elem_len = 1;
+  mctx->asub_tops = n;
+  return REG_NOERROR;
+}
+
+/* Clean the entries which depend on the current input in MCTX.
+   This function must be invoked when the matcher changes the start index
+   of the input, or changes the input string.  */
+
+static void
+internal_function
+match_ctx_clean (re_match_context_t *mctx)
+{
+  int st_idx;
+  for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx)
+    {
+      int sl_idx;
+      re_sub_match_top_t *top = mctx->sub_tops[st_idx];
+      for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx)
+	{
+	  re_sub_match_last_t *last = top->lasts[sl_idx];
+	  re_free (last->path.array);
+	  re_free (last);
+	}
+      re_free (top->lasts);
+      if (top->path)
+	{
+	  re_free (top->path->array);
+	  re_free (top->path);
+	}
+      free (top);
+    }
+
+  mctx->nsub_tops = 0;
+  mctx->nbkref_ents = 0;
+}
+
+/* Free all the memory associated with MCTX.  */
+
+static void
+internal_function
+match_ctx_free (re_match_context_t *mctx)
+{
+  /* First, free all the memory associated with MCTX->SUB_TOPS.  */
+  match_ctx_clean (mctx);
+  re_free (mctx->sub_tops);
+  re_free (mctx->bkref_ents);
+}
+
+/* Add a new backreference entry to MCTX.
+   Note that we assume that caller never call this function with duplicate
+   entry, and call with STR_IDX which isn't smaller than any existing entry.
+*/
+
+static reg_errcode_t
+internal_function
+match_ctx_add_entry (re_match_context_t *mctx, int node, int str_idx, int from,
+		     int to)
+{
+  if (mctx->nbkref_ents >= mctx->abkref_ents)
+    {
+      struct re_backref_cache_entry* new_entry;
+      new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry,
+			      mctx->abkref_ents * 2);
+      if (BE (new_entry == NULL, 0))
+	{
+	  re_free (mctx->bkref_ents);
+	  return REG_ESPACE;
+	}
+      mctx->bkref_ents = new_entry;
+      memset (mctx->bkref_ents + mctx->nbkref_ents, '\0',
+	      sizeof (struct re_backref_cache_entry) * mctx->abkref_ents);
+      mctx->abkref_ents *= 2;
+    }
+  if (mctx->nbkref_ents > 0
+      && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx)
+    mctx->bkref_ents[mctx->nbkref_ents - 1].more = 1;
+
+  mctx->bkref_ents[mctx->nbkref_ents].node = node;
+  mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx;
+  mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from;
+  mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to;
+
+  /* This is a cache that saves negative results of check_dst_limits_calc_pos.
+     If bit N is clear, means that this entry won't epsilon-transition to
+     an OP_OPEN_SUBEXP or OP_CLOSE_SUBEXP for the N+1-th subexpression.  If
+     it is set, check_dst_limits_calc_pos_1 will recurse and try to find one
+     such node.
+
+     A backreference does not epsilon-transition unless it is empty, so set
+     to all zeros if FROM != TO.  */
+  mctx->bkref_ents[mctx->nbkref_ents].eps_reachable_subexps_map
+    = (from == to ? ~0 : 0);
+
+  mctx->bkref_ents[mctx->nbkref_ents++].more = 0;
+  if (mctx->max_mb_elem_len < to - from)
+    mctx->max_mb_elem_len = to - from;
+  return REG_NOERROR;
+}
+
+/* Search for the first entry which has the same str_idx, or -1 if none is
+   found.  Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX.  */
+
+static int
+internal_function
+search_cur_bkref_entry (const re_match_context_t *mctx, int str_idx)
+{
+  int left, right, mid, last;
+  last = right = mctx->nbkref_ents;
+  for (left = 0; left < right;)
+    {
+      mid = (left + right) / 2;
+      if (mctx->bkref_ents[mid].str_idx < str_idx)
+	left = mid + 1;
+      else
+	right = mid;
+    }
+  if (left < last && mctx->bkref_ents[left].str_idx == str_idx)
+    return left;
+  else
+    return -1;
+}
+
+/* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches
+   at STR_IDX.  */
+
+static reg_errcode_t
+internal_function
+match_ctx_add_subtop (re_match_context_t *mctx, int node, int str_idx)
+{
+#ifdef DEBUG
+  assert (mctx->sub_tops != NULL);
+  assert (mctx->asub_tops > 0);
+#endif
+  if (BE (mctx->nsub_tops == mctx->asub_tops, 0))
+    {
+      int new_asub_tops = mctx->asub_tops * 2;
+      re_sub_match_top_t **new_array = re_realloc (mctx->sub_tops,
+						   re_sub_match_top_t *,
+						   new_asub_tops);
+      if (BE (new_array == NULL, 0))
+	return REG_ESPACE;
+      mctx->sub_tops = new_array;
+      mctx->asub_tops = new_asub_tops;
+    }
+  mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t));
+  if (BE (mctx->sub_tops[mctx->nsub_tops] == NULL, 0))
+    return REG_ESPACE;
+  mctx->sub_tops[mctx->nsub_tops]->node = node;
+  mctx->sub_tops[mctx->nsub_tops++]->str_idx = str_idx;
+  return REG_NOERROR;
+}
+
+/* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches
+   at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP.  */
+
+static re_sub_match_last_t *
+internal_function
+match_ctx_add_sublast (re_sub_match_top_t *subtop, int node, int str_idx)
+{
+  re_sub_match_last_t *new_entry;
+  if (BE (subtop->nlasts == subtop->alasts, 0))
+    {
+      int new_alasts = 2 * subtop->alasts + 1;
+      re_sub_match_last_t **new_array = re_realloc (subtop->lasts,
+						    re_sub_match_last_t *,
+						    new_alasts);
+      if (BE (new_array == NULL, 0))
+	return NULL;
+      subtop->lasts = new_array;
+      subtop->alasts = new_alasts;
+    }
+  new_entry = calloc (1, sizeof (re_sub_match_last_t));
+  if (BE (new_entry != NULL, 1))
+    {
+      subtop->lasts[subtop->nlasts] = new_entry;
+      new_entry->node = node;
+      new_entry->str_idx = str_idx;
+      ++subtop->nlasts;
+    }
+  return new_entry;
+}
+
+static void
+internal_function
+sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
+	       re_dfastate_t **limited_sts, int last_node, int last_str_idx)
+{
+  sctx->sifted_states = sifted_sts;
+  sctx->limited_states = limited_sts;
+  sctx->last_node = last_node;
+  sctx->last_str_idx = last_str_idx;
+  re_node_set_init_empty (&sctx->limits);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/winhttp/urlmon.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/winhttp/urlmon.h
new file mode 100755
index 0000000..4143d50
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/winhttp/urlmon.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#if defined(__MINGW_VERSION) || defined(__MINGW32_VERSION)
+
+#ifndef __CUSTOM_URLMON_H
+#define __CUSTOM_URLMON_H
+
+typedef struct IInternetSecurityManager IInternetSecurityManager;
+
+typedef struct IInternetSecurityManagerVtbl
+{
+	HRESULT(STDMETHODCALLTYPE *QueryInterface)(IInternetSecurityManager *, REFIID, void **);
+	ULONG(STDMETHODCALLTYPE *AddRef)(IInternetSecurityManager *);
+	ULONG(STDMETHODCALLTYPE *Release)(IInternetSecurityManager *);
+	LPVOID SetSecuritySite;
+	LPVOID GetSecuritySite;
+	HRESULT(STDMETHODCALLTYPE *MapUrlToZone)(IInternetSecurityManager *, LPCWSTR, DWORD *, DWORD);
+	LPVOID GetSecurityId;
+	LPVOID ProcessUrlAction;
+	LPVOID QueryCustomPolicy;
+	LPVOID SetZoneMapping;
+	LPVOID GetZoneMappings;
+} IInternetSecurityManagerVtbl;
+
+struct IInternetSecurityManager
+{
+	CONST_VTBL struct IInternetSecurityManagerVtbl *lpVtbl;
+};
+
+#define URLZONE_LOCAL_MACHINE 0
+#define URLZONE_INTRANET      1
+#define URLZONE_TRUSTED       2
+
+#endif /* __CUSTOM_URLMON_H */
+
+#else
+
+#include_next <urlmon.h>
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/winhttp/winhttp.def b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/winhttp/winhttp.def
new file mode 100755
index 0000000..eecce59
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/winhttp/winhttp.def
@@ -0,0 +1,29 @@
+LIBRARY		WINHTTP
+EXPORTS
+WinHttpAddRequestHeaders at 16
+WinHttpCheckPlatform at 0
+WinHttpCloseHandle at 4
+WinHttpConnect at 16
+WinHttpCrackUrl at 16
+WinHttpCreateUrl at 16
+WinHttpDetectAutoProxyConfigUrl at 8
+WinHttpGetDefaultProxyConfiguration at 4
+WinHttpGetIEProxyConfigForCurrentUser at 4
+WinHttpGetProxyForUrl at 16
+WinHttpOpen at 20
+WinHttpOpenRequest at 28
+WinHttpQueryAuthSchemes at 16
+WinHttpQueryDataAvailable at 8
+WinHttpQueryHeaders at 24
+WinHttpQueryOption at 16
+WinHttpReadData at 16
+WinHttpReceiveResponse at 8
+WinHttpSendRequest at 28
+WinHttpSetCredentials at 24
+WinHttpSetDefaultProxyConfiguration at 4
+WinHttpSetOption at 16
+WinHttpSetStatusCallback at 16
+WinHttpSetTimeouts at 20
+WinHttpTimeFromSystemTime at 8
+WinHttpTimeToSystemTime at 8
+WinHttpWriteData at 16
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/winhttp/winhttp.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/winhttp/winhttp.h
new file mode 100755
index 0000000..dd1986a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/winhttp/winhttp.h
@@ -0,0 +1,592 @@
+/*
+ * Copyright (C) 2007 Francois Gouget
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#if defined(__MINGW_VERSION) || defined(__MINGW32_VERSION)
+
+#ifndef __WINE_WINHTTP_H
+#define __WINE_WINHTTP_H
+
+#ifdef _WIN64
+#include <pshpack8.h>
+#else
+#include <pshpack4.h>
+#endif
+
+#define WINHTTPAPI
+#define BOOLAPI WINHTTPAPI BOOL WINAPI
+
+
+typedef LPVOID HINTERNET;
+typedef HINTERNET *LPHINTERNET;
+
+#define INTERNET_DEFAULT_PORT           0
+#define INTERNET_DEFAULT_HTTP_PORT      80
+#define INTERNET_DEFAULT_HTTPS_PORT     443
+typedef WORD INTERNET_PORT;
+typedef INTERNET_PORT *LPINTERNET_PORT;
+
+#define INTERNET_SCHEME_HTTP            1
+#define INTERNET_SCHEME_HTTPS           2
+typedef int INTERNET_SCHEME, *LPINTERNET_SCHEME;
+
+#define ICU_ESCAPE  0x80000000
+
+/* flags for WinHttpOpen */
+#define WINHTTP_FLAG_ASYNC                  0x10000000
+
+/* flags for WinHttpOpenRequest */
+#define WINHTTP_FLAG_ESCAPE_PERCENT         0x00000004
+#define WINHTTP_FLAG_NULL_CODEPAGE          0x00000008
+#define WINHTTP_FLAG_ESCAPE_DISABLE         0x00000040
+#define WINHTTP_FLAG_ESCAPE_DISABLE_QUERY   0x00000080
+#define WINHTTP_FLAG_BYPASS_PROXY_CACHE     0x00000100
+#define WINHTTP_FLAG_REFRESH                WINHTTP_FLAG_BYPASS_PROXY_CACHE
+#define WINHTTP_FLAG_SECURE                 0x00800000
+
+#define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY   0
+#define WINHTTP_ACCESS_TYPE_NO_PROXY        1
+#define WINHTTP_ACCESS_TYPE_NAMED_PROXY     3
+
+#define WINHTTP_NO_PROXY_NAME               NULL
+#define WINHTTP_NO_PROXY_BYPASS             NULL
+
+#define WINHTTP_NO_REFERER                  NULL
+#define WINHTTP_DEFAULT_ACCEPT_TYPES        NULL
+
+#define WINHTTP_NO_ADDITIONAL_HEADERS       NULL
+#define WINHTTP_NO_REQUEST_DATA             NULL
+
+#define WINHTTP_HEADER_NAME_BY_INDEX        NULL
+#define WINHTTP_NO_OUTPUT_BUFFER            NULL
+#define WINHTTP_NO_HEADER_INDEX             NULL
+
+#define WINHTTP_ADDREQ_INDEX_MASK                    0x0000FFFF
+#define WINHTTP_ADDREQ_FLAGS_MASK                    0xFFFF0000
+#define WINHTTP_ADDREQ_FLAG_ADD_IF_NEW               0x10000000
+#define WINHTTP_ADDREQ_FLAG_ADD                      0x20000000
+#define WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA      0x40000000
+#define WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON  0x01000000
+#define WINHTTP_ADDREQ_FLAG_COALESCE                 WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
+#define WINHTTP_ADDREQ_FLAG_REPLACE                  0x80000000
+
+#define WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH 0
+
+/* flags for WinHttp{Set/Query}Options */
+#define WINHTTP_FIRST_OPTION                         WINHTTP_OPTION_CALLBACK
+#define WINHTTP_OPTION_CALLBACK                       1
+#define WINHTTP_OPTION_RESOLVE_TIMEOUT                2
+#define WINHTTP_OPTION_CONNECT_TIMEOUT                3
+#define WINHTTP_OPTION_CONNECT_RETRIES                4
+#define WINHTTP_OPTION_SEND_TIMEOUT                   5
+#define WINHTTP_OPTION_RECEIVE_TIMEOUT                6
+#define WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT       7
+#define WINHTTP_OPTION_HANDLE_TYPE                    9
+#define WINHTTP_OPTION_READ_BUFFER_SIZE              12
+#define WINHTTP_OPTION_WRITE_BUFFER_SIZE             13
+#define WINHTTP_OPTION_PARENT_HANDLE                 21
+#define WINHTTP_OPTION_EXTENDED_ERROR                24
+#define WINHTTP_OPTION_SECURITY_FLAGS                31
+#define WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT   32
+#define WINHTTP_OPTION_URL                           34
+#define WINHTTP_OPTION_SECURITY_KEY_BITNESS          36
+#define WINHTTP_OPTION_PROXY                         38
+#define WINHTTP_OPTION_USER_AGENT                    41
+#define WINHTTP_OPTION_CONTEXT_VALUE                 45
+#define WINHTTP_OPTION_CLIENT_CERT_CONTEXT           47
+#define WINHTTP_OPTION_REQUEST_PRIORITY              58
+#define WINHTTP_OPTION_HTTP_VERSION                  59
+#define WINHTTP_OPTION_DISABLE_FEATURE               63
+#define WINHTTP_OPTION_CODEPAGE                      68
+#define WINHTTP_OPTION_MAX_CONNS_PER_SERVER          73
+#define WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER      74
+#define WINHTTP_OPTION_AUTOLOGON_POLICY              77
+#define WINHTTP_OPTION_SERVER_CERT_CONTEXT           78
+#define WINHTTP_OPTION_ENABLE_FEATURE                79
+#define WINHTTP_OPTION_WORKER_THREAD_COUNT           80
+#define WINHTTP_OPTION_PASSPORT_COBRANDING_TEXT      81
+#define WINHTTP_OPTION_PASSPORT_COBRANDING_URL       82
+#define WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH       83
+#define WINHTTP_OPTION_SECURE_PROTOCOLS              84
+#define WINHTTP_OPTION_ENABLETRACING                 85
+#define WINHTTP_OPTION_PASSPORT_SIGN_OUT             86
+#define WINHTTP_OPTION_PASSPORT_RETURN_URL           87
+#define WINHTTP_OPTION_REDIRECT_POLICY               88
+#define WINHTTP_OPTION_MAX_HTTP_AUTOMATIC_REDIRECTS  89
+#define WINHTTP_OPTION_MAX_HTTP_STATUS_CONTINUE      90
+#define WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE      91
+#define WINHTTP_OPTION_MAX_RESPONSE_DRAIN_SIZE       92
+#define WINHTTP_OPTION_CONNECTION_INFO               93
+#define WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST       94
+#define WINHTTP_OPTION_SPN                           96
+#define WINHTTP_OPTION_GLOBAL_PROXY_CREDS            97
+#define WINHTTP_OPTION_GLOBAL_SERVER_CREDS           98
+#define WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT           99
+#define WINHTTP_OPTION_REJECT_USERPWD_IN_URL         100
+#define WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS 101
+#define WINHTTP_LAST_OPTION                          WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS
+#define WINHTTP_OPTION_USERNAME                      0x1000
+#define WINHTTP_OPTION_PASSWORD                      0x1001
+#define WINHTTP_OPTION_PROXY_USERNAME                0x1002
+#define WINHTTP_OPTION_PROXY_PASSWORD                0x1003
+
+#define WINHTTP_CONNS_PER_SERVER_UNLIMITED 0xFFFFFFFF
+
+#define WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM   0
+#define WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW      1
+#define WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH     2
+#define WINHTTP_AUTOLOGON_SECURITY_LEVEL_DEFAULT  WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM
+
+#define WINHTTP_OPTION_REDIRECT_POLICY_NEVER                        0
+#define WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP       1
+#define WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS                       2
+#define WINHTTP_OPTION_REDIRECT_POLICY_LAST            WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
+#define WINHTTP_OPTION_REDIRECT_POLICY_DEFAULT         WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP
+
+#define WINHTTP_DISABLE_PASSPORT_AUTH    0x00000000
+#define WINHTTP_ENABLE_PASSPORT_AUTH     0x10000000
+#define WINHTTP_DISABLE_PASSPORT_KEYRING 0x20000000
+#define WINHTTP_ENABLE_PASSPORT_KEYRING  0x40000000
+
+#define WINHTTP_DISABLE_COOKIES                   0x00000001
+#define WINHTTP_DISABLE_REDIRECTS                 0x00000002
+#define WINHTTP_DISABLE_AUTHENTICATION            0x00000004
+#define WINHTTP_DISABLE_KEEP_ALIVE                0x00000008
+#define WINHTTP_ENABLE_SSL_REVOCATION             0x00000001
+#define WINHTTP_ENABLE_SSL_REVERT_IMPERSONATION   0x00000002
+#define WINHTTP_DISABLE_SPN_SERVER_PORT           0x00000000
+#define WINHTTP_ENABLE_SPN_SERVER_PORT            0x00000001
+#define WINHTTP_OPTION_SPN_MASK                   WINHTTP_ENABLE_SPN_SERVER_PORT
+
+/* Options for WinHttpOpenRequest */
+#define WINHTTP_NO_REFERER             NULL
+#define WINHTTP_DEFAULT_ACCEPT_TYPES   NULL
+
+/* Options for WinHttpSendRequest */
+#define WINHTTP_NO_ADDITIONAL_HEADERS   NULL
+#define WINHTTP_NO_REQUEST_DATA         NULL
+
+/* WinHTTP error codes */
+#define WINHTTP_ERROR_BASE                                  12000
+#define ERROR_WINHTTP_OUT_OF_HANDLES                        (WINHTTP_ERROR_BASE + 1)
+#define ERROR_WINHTTP_TIMEOUT                               (WINHTTP_ERROR_BASE + 2)
+#define ERROR_WINHTTP_INTERNAL_ERROR                        (WINHTTP_ERROR_BASE + 4)
+#define ERROR_WINHTTP_INVALID_URL                           (WINHTTP_ERROR_BASE + 5)
+#define ERROR_WINHTTP_UNRECOGNIZED_SCHEME                   (WINHTTP_ERROR_BASE + 6)
+#define ERROR_WINHTTP_NAME_NOT_RESOLVED                     (WINHTTP_ERROR_BASE + 7)
+#define ERROR_WINHTTP_INVALID_OPTION                        (WINHTTP_ERROR_BASE + 9)
+#define ERROR_WINHTTP_OPTION_NOT_SETTABLE                   (WINHTTP_ERROR_BASE + 11)
+#define ERROR_WINHTTP_SHUTDOWN                              (WINHTTP_ERROR_BASE + 12)
+#define ERROR_WINHTTP_LOGIN_FAILURE                         (WINHTTP_ERROR_BASE + 15)
+#define ERROR_WINHTTP_OPERATION_CANCELLED                   (WINHTTP_ERROR_BASE + 17)
+#define ERROR_WINHTTP_INCORRECT_HANDLE_TYPE                 (WINHTTP_ERROR_BASE + 18)
+#define ERROR_WINHTTP_INCORRECT_HANDLE_STATE                (WINHTTP_ERROR_BASE + 19)
+#define ERROR_WINHTTP_CANNOT_CONNECT                        (WINHTTP_ERROR_BASE + 29)
+#define ERROR_WINHTTP_CONNECTION_ERROR                      (WINHTTP_ERROR_BASE + 30)
+#define ERROR_WINHTTP_RESEND_REQUEST                        (WINHTTP_ERROR_BASE + 32)
+#define ERROR_WINHTTP_SECURE_CERT_DATE_INVALID              (WINHTTP_ERROR_BASE + 37)
+#define ERROR_WINHTTP_SECURE_CERT_CN_INVALID                (WINHTTP_ERROR_BASE + 38)
+#define ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED               (WINHTTP_ERROR_BASE + 44)
+#define ERROR_WINHTTP_SECURE_INVALID_CA                     (WINHTTP_ERROR_BASE + 45)
+#define ERROR_WINHTTP_SECURE_CERT_REV_FAILED                (WINHTTP_ERROR_BASE + 57)
+#define ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN               (WINHTTP_ERROR_BASE + 100)
+#define ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND               (WINHTTP_ERROR_BASE + 101)
+#define ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND                (WINHTTP_ERROR_BASE + 102)
+#define ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN                (WINHTTP_ERROR_BASE + 103)
+#define ERROR_WINHTTP_HEADER_NOT_FOUND                      (WINHTTP_ERROR_BASE + 150)
+#define ERROR_WINHTTP_INVALID_SERVER_RESPONSE               (WINHTTP_ERROR_BASE + 152)
+#define ERROR_WINHTTP_INVALID_HEADER                        (WINHTTP_ERROR_BASE + 153)
+#define ERROR_WINHTTP_INVALID_QUERY_REQUEST                 (WINHTTP_ERROR_BASE + 154)
+#define ERROR_WINHTTP_HEADER_ALREADY_EXISTS                 (WINHTTP_ERROR_BASE + 155)
+#define ERROR_WINHTTP_REDIRECT_FAILED                       (WINHTTP_ERROR_BASE + 156)
+#define ERROR_WINHTTP_SECURE_CHANNEL_ERROR                  (WINHTTP_ERROR_BASE + 157)
+#define ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT                 (WINHTTP_ERROR_BASE + 166)
+#define ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT             (WINHTTP_ERROR_BASE + 167)
+#define ERROR_WINHTTP_SECURE_INVALID_CERT                   (WINHTTP_ERROR_BASE + 169)
+#define ERROR_WINHTTP_SECURE_CERT_REVOKED                   (WINHTTP_ERROR_BASE + 170)
+#define ERROR_WINHTTP_NOT_INITIALIZED                       (WINHTTP_ERROR_BASE + 172)
+#define ERROR_WINHTTP_SECURE_FAILURE                        (WINHTTP_ERROR_BASE + 175)
+#define ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR              (WINHTTP_ERROR_BASE + 178)
+#define ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE               (WINHTTP_ERROR_BASE + 179)
+#define ERROR_WINHTTP_AUTODETECTION_FAILED                  (WINHTTP_ERROR_BASE + 180)
+#define ERROR_WINHTTP_HEADER_COUNT_EXCEEDED                 (WINHTTP_ERROR_BASE + 181)
+#define ERROR_WINHTTP_HEADER_SIZE_OVERFLOW                  (WINHTTP_ERROR_BASE + 182)
+#define ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW (WINHTTP_ERROR_BASE + 183)
+#define ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW               (WINHTTP_ERROR_BASE + 184)
+#define ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY            (WINHTTP_ERROR_BASE + 185)
+#define ERROR_WINHTTP_CLIENT_CERT_NO_ACCESS_PRIVATE_KEY     (WINHTTP_ERROR_BASE + 186)
+#define WINHTTP_ERROR_LAST                                  (WINHTTP_ERROR_BASE + 186)
+
+/* WinHttp status codes */
+#define HTTP_STATUS_CONTINUE            100
+#define HTTP_STATUS_SWITCH_PROTOCOLS    101
+#define HTTP_STATUS_OK                  200
+#define HTTP_STATUS_CREATED             201
+#define HTTP_STATUS_ACCEPTED            202
+#define HTTP_STATUS_PARTIAL             203
+#define HTTP_STATUS_NO_CONTENT          204
+#define HTTP_STATUS_RESET_CONTENT       205
+#define HTTP_STATUS_PARTIAL_CONTENT     206
+#define HTTP_STATUS_WEBDAV_MULTI_STATUS 207
+#define HTTP_STATUS_AMBIGUOUS           300
+#define HTTP_STATUS_MOVED               301
+#define HTTP_STATUS_REDIRECT            302
+#define HTTP_STATUS_REDIRECT_METHOD     303
+#define HTTP_STATUS_NOT_MODIFIED        304
+#define HTTP_STATUS_USE_PROXY           305
+#define HTTP_STATUS_REDIRECT_KEEP_VERB  307
+#define HTTP_STATUS_BAD_REQUEST         400
+#define HTTP_STATUS_DENIED              401
+#define HTTP_STATUS_PAYMENT_REQ         402
+#define HTTP_STATUS_FORBIDDEN           403
+#define HTTP_STATUS_NOT_FOUND           404
+#define HTTP_STATUS_BAD_METHOD          405
+#define HTTP_STATUS_NONE_ACCEPTABLE     406
+#define HTTP_STATUS_PROXY_AUTH_REQ      407
+#define HTTP_STATUS_REQUEST_TIMEOUT     408
+#define HTTP_STATUS_CONFLICT            409
+#define HTTP_STATUS_GONE                410
+#define HTTP_STATUS_LENGTH_REQUIRED     411
+#define HTTP_STATUS_PRECOND_FAILED      412
+#define HTTP_STATUS_REQUEST_TOO_LARGE   413
+#define HTTP_STATUS_URI_TOO_LONG        414
+#define HTTP_STATUS_UNSUPPORTED_MEDIA   415
+#define HTTP_STATUS_RETRY_WITH          449
+#define HTTP_STATUS_SERVER_ERROR        500
+#define HTTP_STATUS_NOT_SUPPORTED       501
+#define HTTP_STATUS_BAD_GATEWAY         502
+#define HTTP_STATUS_SERVICE_UNAVAIL     503
+#define HTTP_STATUS_GATEWAY_TIMEOUT     504
+#define HTTP_STATUS_VERSION_NOT_SUP     505
+#define HTTP_STATUS_FIRST               HTTP_STATUS_CONTINUE
+#define HTTP_STATUS_LAST                HTTP_STATUS_VERSION_NOT_SUP
+
+#define SECURITY_FLAG_IGNORE_UNKNOWN_CA         0x00000100
+#define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID  0x00002000
+#define SECURITY_FLAG_IGNORE_CERT_CN_INVALID    0x00001000
+#define SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE   0x00000200
+#define SECURITY_FLAG_SECURE                    0x00000001
+#define SECURITY_FLAG_STRENGTH_WEAK             0x10000000
+#define SECURITY_FLAG_STRENGTH_MEDIUM           0x40000000
+#define SECURITY_FLAG_STRENGTH_STRONG           0x20000000
+
+#define ICU_NO_ENCODE          0x20000000
+#define ICU_DECODE             0x10000000
+#define ICU_NO_META            0x08000000
+#define ICU_ENCODE_SPACES_ONLY 0x04000000
+#define ICU_BROWSER_MODE       0x02000000
+#define ICU_ENCODE_PERCENT     0x00001000
+
+/* Query flags */
+#define WINHTTP_QUERY_MIME_VERSION                 0
+#define WINHTTP_QUERY_CONTENT_TYPE                 1
+#define WINHTTP_QUERY_CONTENT_TRANSFER_ENCODING    2
+#define WINHTTP_QUERY_CONTENT_ID                   3
+#define WINHTTP_QUERY_CONTENT_DESCRIPTION          4
+#define WINHTTP_QUERY_CONTENT_LENGTH               5
+#define WINHTTP_QUERY_CONTENT_LANGUAGE             6
+#define WINHTTP_QUERY_ALLOW                        7
+#define WINHTTP_QUERY_PUBLIC                       8
+#define WINHTTP_QUERY_DATE                         9
+#define WINHTTP_QUERY_EXPIRES                      10
+#define WINHTTP_QUERY_LAST_MODIFIED                11
+#define WINHTTP_QUERY_MESSAGE_ID                   12
+#define WINHTTP_QUERY_URI                          13
+#define WINHTTP_QUERY_DERIVED_FROM                 14
+#define WINHTTP_QUERY_COST                         15
+#define WINHTTP_QUERY_LINK                         16
+#define WINHTTP_QUERY_PRAGMA                       17
+#define WINHTTP_QUERY_VERSION                      18
+#define WINHTTP_QUERY_STATUS_CODE                  19
+#define WINHTTP_QUERY_STATUS_TEXT                  20
+#define WINHTTP_QUERY_RAW_HEADERS                  21
+#define WINHTTP_QUERY_RAW_HEADERS_CRLF             22
+#define WINHTTP_QUERY_CONNECTION                   23
+#define WINHTTP_QUERY_ACCEPT                       24
+#define WINHTTP_QUERY_ACCEPT_CHARSET               25
+#define WINHTTP_QUERY_ACCEPT_ENCODING              26
+#define WINHTTP_QUERY_ACCEPT_LANGUAGE              27
+#define WINHTTP_QUERY_AUTHORIZATION                28
+#define WINHTTP_QUERY_CONTENT_ENCODING             29
+#define WINHTTP_QUERY_FORWARDED                    30
+#define WINHTTP_QUERY_FROM                         31
+#define WINHTTP_QUERY_IF_MODIFIED_SINCE            32
+#define WINHTTP_QUERY_LOCATION                     33
+#define WINHTTP_QUERY_ORIG_URI                     34
+#define WINHTTP_QUERY_REFERER                      35
+#define WINHTTP_QUERY_RETRY_AFTER                  36
+#define WINHTTP_QUERY_SERVER                       37
+#define WINHTTP_QUERY_TITLE                        38
+#define WINHTTP_QUERY_USER_AGENT                   39
+#define WINHTTP_QUERY_WWW_AUTHENTICATE             40
+#define WINHTTP_QUERY_PROXY_AUTHENTICATE           41
+#define WINHTTP_QUERY_ACCEPT_RANGES                42
+#define WINHTTP_QUERY_SET_COOKIE                   43
+#define WINHTTP_QUERY_COOKIE                       44
+#define WINHTTP_QUERY_REQUEST_METHOD               45
+#define WINHTTP_QUERY_REFRESH                      46
+#define WINHTTP_QUERY_CONTENT_DISPOSITION          47
+#define WINHTTP_QUERY_AGE                          48
+#define WINHTTP_QUERY_CACHE_CONTROL                49
+#define WINHTTP_QUERY_CONTENT_BASE                 50
+#define WINHTTP_QUERY_CONTENT_LOCATION             51
+#define WINHTTP_QUERY_CONTENT_MD5                  52
+#define WINHTTP_QUERY_CONTENT_RANGE                53
+#define WINHTTP_QUERY_ETAG                         54
+#define WINHTTP_QUERY_HOST                         55
+#define WINHTTP_QUERY_IF_MATCH                     56
+#define WINHTTP_QUERY_IF_NONE_MATCH                57
+#define WINHTTP_QUERY_IF_RANGE                     58
+#define WINHTTP_QUERY_IF_UNMODIFIED_SINCE          59
+#define WINHTTP_QUERY_MAX_FORWARDS                 60
+#define WINHTTP_QUERY_PROXY_AUTHORIZATION          61
+#define WINHTTP_QUERY_RANGE                        62
+#define WINHTTP_QUERY_TRANSFER_ENCODING            63
+#define WINHTTP_QUERY_UPGRADE                      64
+#define WINHTTP_QUERY_VARY                         65
+#define WINHTTP_QUERY_VIA                          66
+#define WINHTTP_QUERY_WARNING                      67
+#define WINHTTP_QUERY_EXPECT                       68
+#define WINHTTP_QUERY_PROXY_CONNECTION             69
+#define WINHTTP_QUERY_UNLESS_MODIFIED_SINCE        70
+#define WINHTTP_QUERY_PROXY_SUPPORT                75
+#define WINHTTP_QUERY_AUTHENTICATION_INFO          76
+#define WINHTTP_QUERY_PASSPORT_URLS                77
+#define WINHTTP_QUERY_PASSPORT_CONFIG              78
+#define WINHTTP_QUERY_MAX                          78
+#define WINHTTP_QUERY_CUSTOM                       65535
+#define WINHTTP_QUERY_FLAG_REQUEST_HEADERS         0x80000000
+#define WINHTTP_QUERY_FLAG_SYSTEMTIME              0x40000000
+#define WINHTTP_QUERY_FLAG_NUMBER                  0x20000000
+
+/* Callback options */
+#define WINHTTP_CALLBACK_STATUS_RESOLVING_NAME          0x00000001
+#define WINHTTP_CALLBACK_STATUS_NAME_RESOLVED           0x00000002
+#define WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER    0x00000004
+#define WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER     0x00000008
+#define WINHTTP_CALLBACK_STATUS_SENDING_REQUEST         0x00000010
+#define WINHTTP_CALLBACK_STATUS_REQUEST_SENT            0x00000020
+#define WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE      0x00000040
+#define WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED       0x00000080
+#define WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION      0x00000100
+#define WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED       0x00000200
+#define WINHTTP_CALLBACK_STATUS_HANDLE_CREATED          0x00000400
+#define WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING          0x00000800
+#define WINHTTP_CALLBACK_STATUS_DETECTING_PROXY         0x00001000
+#define WINHTTP_CALLBACK_STATUS_REDIRECT                0x00004000
+#define WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE   0x00008000
+#define WINHTTP_CALLBACK_STATUS_SECURE_FAILURE          0x00010000
+#define WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE       0x00020000
+#define WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE          0x00040000
+#define WINHTTP_CALLBACK_STATUS_READ_COMPLETE           0x00080000
+#define WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE          0x00100000
+#define WINHTTP_CALLBACK_STATUS_REQUEST_ERROR           0x00200000
+#define WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE    0x00400000
+#define WINHTTP_CALLBACK_FLAG_RESOLVE_NAME              (WINHTTP_CALLBACK_STATUS_RESOLVING_NAME | WINHTTP_CALLBACK_STATUS_NAME_RESOLVED)
+#define WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER         (WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER | WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER)
+#define WINHTTP_CALLBACK_FLAG_SEND_REQUEST              (WINHTTP_CALLBACK_STATUS_SENDING_REQUEST | WINHTTP_CALLBACK_STATUS_REQUEST_SENT)
+#define WINHTTP_CALLBACK_FLAG_RECEIVE_RESPONSE          (WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE | WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED)
+#define WINHTTP_CALLBACK_FLAG_CLOSE_CONNECTION          (WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION | WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED)
+#define WINHTTP_CALLBACK_FLAG_HANDLES                   (WINHTTP_CALLBACK_STATUS_HANDLE_CREATED | WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING)
+#define WINHTTP_CALLBACK_FLAG_DETECTING_PROXY           WINHTTP_CALLBACK_STATUS_DETECTING_PROXY
+#define WINHTTP_CALLBACK_FLAG_REDIRECT                  WINHTTP_CALLBACK_STATUS_REDIRECT
+#define WINHTTP_CALLBACK_FLAG_INTERMEDIATE_RESPONSE     WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE
+#define WINHTTP_CALLBACK_FLAG_SECURE_FAILURE            WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
+#define WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE      WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE
+#define WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE         WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE
+#define WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE            WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE
+#define WINHTTP_CALLBACK_FLAG_READ_COMPLETE             WINHTTP_CALLBACK_STATUS_READ_COMPLETE
+#define WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE            WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE
+#define WINHTTP_CALLBACK_FLAG_REQUEST_ERROR             WINHTTP_CALLBACK_STATUS_REQUEST_ERROR
+#define WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS           (WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE | WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE \
+                                                        | WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE | WINHTTP_CALLBACK_STATUS_READ_COMPLETE          \
+                                                        | WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE | WINHTTP_CALLBACK_STATUS_REQUEST_ERROR)
+#define WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS         0xffffffff
+#define WINHTTP_INVALID_STATUS_CALLBACK                 ((WINHTTP_STATUS_CALLBACK)(-1))
+
+#define API_RECEIVE_RESPONSE          (1)
+#define API_QUERY_DATA_AVAILABLE      (2)
+#define API_READ_DATA                 (3)
+#define API_WRITE_DATA                (4)
+#define API_SEND_REQUEST              (5)
+
+#define WINHTTP_HANDLE_TYPE_SESSION                  1
+#define WINHTTP_HANDLE_TYPE_CONNECT                  2
+#define WINHTTP_HANDLE_TYPE_REQUEST                  3
+
+#define WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED         0x00000001
+#define WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT            0x00000002
+#define WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED            0x00000004
+#define WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA              0x00000008
+#define WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID         0x00000010
+#define WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID       0x00000020
+#define WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE        0x00000040
+#define WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR  0x80000000
+
+#define WINHTTP_FLAG_SECURE_PROTOCOL_SSL2  0x00000008
+#define WINHTTP_FLAG_SECURE_PROTOCOL_SSL3  0x00000020
+#define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1  0x00000080
+#define WINHTTP_FLAG_SECURE_PROTOCOL_ALL   (WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 | WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1)
+
+#define WINHTTP_AUTH_SCHEME_BASIC      0x00000001
+#define WINHTTP_AUTH_SCHEME_NTLM       0x00000002
+#define WINHTTP_AUTH_SCHEME_PASSPORT   0x00000004
+#define WINHTTP_AUTH_SCHEME_DIGEST     0x00000008
+#define WINHTTP_AUTH_SCHEME_NEGOTIATE  0x00000010
+
+#define WINHTTP_AUTH_TARGET_SERVER     0x00000000
+#define WINHTTP_AUTH_TARGET_PROXY      0x00000001
+
+#define WINHTTP_TIME_FORMAT_BUFSIZE    62
+
+typedef struct
+{
+    DWORD   dwStructSize;
+    LPWSTR  lpszScheme;
+    DWORD   dwSchemeLength;
+    INTERNET_SCHEME nScheme;
+    LPWSTR  lpszHostName;
+    DWORD   dwHostNameLength;
+    INTERNET_PORT nPort;
+    LPWSTR  lpszUserName;
+    DWORD   dwUserNameLength;
+    LPWSTR  lpszPassword;
+    DWORD   dwPasswordLength;
+    LPWSTR  lpszUrlPath;
+    DWORD   dwUrlPathLength;
+    LPWSTR  lpszExtraInfo;
+    DWORD   dwExtraInfoLength;
+} URL_COMPONENTS, *LPURL_COMPONENTS;
+typedef URL_COMPONENTS URL_COMPONENTSW;
+typedef LPURL_COMPONENTS LPURL_COMPONENTSW;
+
+typedef struct
+{
+    DWORD_PTR dwResult;
+    DWORD dwError;
+} WINHTTP_ASYNC_RESULT, *LPWINHTTP_ASYNC_RESULT;
+
+typedef struct
+{
+    FILETIME ftExpiry;
+    FILETIME ftStart;
+    LPWSTR lpszSubjectInfo;
+    LPWSTR lpszIssuerInfo;
+    LPWSTR lpszProtocolName;
+    LPWSTR lpszSignatureAlgName;
+    LPWSTR lpszEncryptionAlgName;
+    DWORD dwKeySize;
+} WINHTTP_CERTIFICATE_INFO;
+
+typedef struct
+{
+    DWORD dwAccessType;
+    LPWSTR lpszProxy;
+    LPWSTR lpszProxyBypass;
+} WINHTTP_PROXY_INFO, *LPWINHTTP_PROXY_INFO;
+typedef WINHTTP_PROXY_INFO WINHTTP_PROXY_INFOW;
+typedef LPWINHTTP_PROXY_INFO LPWINHTTP_PROXY_INFOW;
+
+typedef struct
+{
+    BOOL   fAutoDetect;
+    LPWSTR lpszAutoConfigUrl;
+    LPWSTR lpszProxy;
+    LPWSTR lpszProxyBypass;
+} WINHTTP_CURRENT_USER_IE_PROXY_CONFIG;
+
+typedef VOID (CALLBACK *WINHTTP_STATUS_CALLBACK)(HINTERNET,DWORD_PTR,DWORD,LPVOID,DWORD);
+
+#define WINHTTP_AUTO_DETECT_TYPE_DHCP   0x00000001
+#define WINHTTP_AUTO_DETECT_TYPE_DNS_A  0x00000002
+
+#define WINHTTP_AUTOPROXY_AUTO_DETECT           0x00000001
+#define WINHTTP_AUTOPROXY_CONFIG_URL            0x00000002
+#define WINHTTP_AUTOPROXY_RUN_INPROCESS         0x00010000
+#define WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY   0x00020000
+
+typedef struct
+{
+    DWORD dwFlags;
+    DWORD dwAutoDetectFlags;
+    LPCWSTR lpszAutoConfigUrl;
+    LPVOID lpvReserved;
+    DWORD dwReserved;
+    BOOL fAutoLogonIfChallenged;
+} WINHTTP_AUTOPROXY_OPTIONS;
+
+typedef struct
+{
+    DWORD dwMajorVersion;
+    DWORD dwMinorVersion;
+} HTTP_VERSION_INFO, *LPHTTP_VERSION_INFO;
+
+#ifdef _WS2DEF_
+typedef struct
+{
+    DWORD cbSize;
+    SOCKADDR_STORAGE LocalAddress;
+    SOCKADDR_STORAGE RemoteAddress;
+} WINHTTP_CONNECTION_INFO;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+BOOL        WINAPI WinHttpAddRequestHeaders(HINTERNET,LPCWSTR,DWORD,DWORD);
+BOOL        WINAPI WinHttpDetectAutoProxyConfigUrl(DWORD,LPWSTR*);
+BOOL        WINAPI WinHttpCheckPlatform(void);
+BOOL        WINAPI WinHttpCloseHandle(HINTERNET);
+HINTERNET   WINAPI WinHttpConnect(HINTERNET,LPCWSTR,INTERNET_PORT,DWORD);
+BOOL        WINAPI WinHttpCrackUrl(LPCWSTR,DWORD,DWORD,LPURL_COMPONENTS);
+BOOL        WINAPI WinHttpCreateUrl(LPURL_COMPONENTS,DWORD,LPWSTR,LPDWORD);
+BOOL        WINAPI WinHttpGetDefaultProxyConfiguration(WINHTTP_PROXY_INFO*);
+BOOL        WINAPI WinHttpGetIEProxyConfigForCurrentUser(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG*);
+BOOL        WINAPI WinHttpGetProxyForUrl(HINTERNET,LPCWSTR,WINHTTP_AUTOPROXY_OPTIONS*,WINHTTP_PROXY_INFO*);
+HINTERNET   WINAPI WinHttpOpen(LPCWSTR,DWORD,LPCWSTR,LPCWSTR,DWORD);
+HINTERNET   WINAPI WinHttpOpenRequest(HINTERNET,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR*,DWORD);
+BOOL        WINAPI WinHttpQueryAuthParams(HINTERNET,DWORD,LPVOID*);
+BOOL        WINAPI WinHttpQueryAuthSchemes(HINTERNET,LPDWORD,LPDWORD,LPDWORD);
+BOOL        WINAPI WinHttpQueryDataAvailable(HINTERNET,LPDWORD);
+BOOL        WINAPI WinHttpQueryHeaders(HINTERNET,DWORD,LPCWSTR,LPVOID,LPDWORD,LPDWORD);
+BOOL        WINAPI WinHttpQueryOption(HINTERNET,DWORD,LPVOID,LPDWORD);
+BOOL        WINAPI WinHttpReadData(HINTERNET,LPVOID,DWORD,LPDWORD);
+BOOL        WINAPI WinHttpReceiveResponse(HINTERNET,LPVOID);
+BOOL        WINAPI WinHttpSendRequest(HINTERNET,LPCWSTR,DWORD,LPVOID,DWORD,DWORD,DWORD_PTR);
+BOOL        WINAPI WinHttpSetDefaultProxyConfiguration(WINHTTP_PROXY_INFO*);
+BOOL        WINAPI WinHttpSetCredentials(HINTERNET,DWORD,DWORD,LPCWSTR,LPCWSTR,LPVOID);
+BOOL        WINAPI WinHttpSetOption(HINTERNET,DWORD,LPVOID,DWORD);
+WINHTTP_STATUS_CALLBACK WINAPI WinHttpSetStatusCallback(HINTERNET,WINHTTP_STATUS_CALLBACK,DWORD,DWORD_PTR);
+BOOL        WINAPI WinHttpSetTimeouts(HINTERNET,int,int,int,int);
+BOOL        WINAPI WinHttpTimeFromSystemTime(const SYSTEMTIME *,LPWSTR);
+BOOL        WINAPI WinHttpTimeToSystemTime(LPCWSTR,SYSTEMTIME*);
+BOOL        WINAPI WinHttpWriteData(HINTERNET,LPCVOID,DWORD,LPDWORD);
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <poppack.h>
+
+#endif  /* __WINE_WINHTTP_H */
+
+#else
+
+#include_next <winhttp.h>
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/winhttp/winhttp64.def b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/winhttp/winhttp64.def
new file mode 100755
index 0000000..bfad3a0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/winhttp/winhttp64.def
@@ -0,0 +1,29 @@
+LIBRARY		WINHTTP
+EXPORTS
+WinHttpAddRequestHeaders
+WinHttpCheckPlatform
+WinHttpCloseHandle
+WinHttpConnect
+WinHttpCrackUrl
+WinHttpCreateUrl
+WinHttpDetectAutoProxyConfigUrl
+WinHttpGetDefaultProxyConfiguration
+WinHttpGetIEProxyConfigForCurrentUser
+WinHttpGetProxyForUrl
+WinHttpOpen
+WinHttpOpenRequest
+WinHttpQueryAuthSchemes
+WinHttpQueryDataAvailable
+WinHttpQueryHeaders
+WinHttpQueryOption
+WinHttpReadData
+WinHttpReceiveResponse
+WinHttpSendRequest
+WinHttpSetCredentials
+WinHttpSetDefaultProxyConfiguration
+WinHttpSetOption
+WinHttpSetStatusCallback
+WinHttpSetTimeouts
+WinHttpTimeFromSystemTime
+WinHttpTimeToSystemTime
+WinHttpWriteData
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/adler32.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/adler32.c
new file mode 100755
index 0000000..a868f07
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/adler32.c
@@ -0,0 +1,179 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2011 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#define local static
+
+local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
+
+#define BASE 65521      /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+
+/* use NO_DIVIDE if your processor does not do division in hardware --
+   try it both ways to see which is faster */
+#ifdef NO_DIVIDE
+/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
+   (thank you to John Reiser for pointing this out) */
+#  define CHOP(a) \
+    do { \
+        unsigned long tmp = a >> 16; \
+        a &= 0xffffUL; \
+        a += (tmp << 4) - tmp; \
+    } while (0)
+#  define MOD28(a) \
+    do { \
+        CHOP(a); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#  define MOD(a) \
+    do { \
+        CHOP(a); \
+        MOD28(a); \
+    } while (0)
+#  define MOD63(a) \
+    do { /* this assumes a is not negative */ \
+        z_off64_t tmp = a >> 32; \
+        a &= 0xffffffffL; \
+        a += (tmp << 8) - (tmp << 5) + tmp; \
+        tmp = a >> 16; \
+        a &= 0xffffL; \
+        a += (tmp << 4) - tmp; \
+        tmp = a >> 16; \
+        a &= 0xffffL; \
+        a += (tmp << 4) - tmp; \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#else
+#  define MOD(a) a %= BASE
+#  define MOD28(a) a %= BASE
+#  define MOD63(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+    uLong adler;
+    const Bytef *buf;
+    uInt len;
+{
+    unsigned long sum2;
+    unsigned n;
+
+    /* split Adler-32 into component sums */
+    sum2 = (adler >> 16) & 0xffff;
+    adler &= 0xffff;
+
+    /* in case user likes doing a byte at a time, keep it fast */
+    if (len == 1) {
+        adler += buf[0];
+        if (adler >= BASE)
+            adler -= BASE;
+        sum2 += adler;
+        if (sum2 >= BASE)
+            sum2 -= BASE;
+        return adler | (sum2 << 16);
+    }
+
+    /* initial Adler-32 value (deferred check for len == 1 speed) */
+    if (buf == Z_NULL)
+        return 1L;
+
+    /* in case short lengths are provided, keep it somewhat fast */
+    if (len < 16) {
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        if (adler >= BASE)
+            adler -= BASE;
+        MOD28(sum2);            /* only added so many BASE's */
+        return adler | (sum2 << 16);
+    }
+
+    /* do length NMAX blocks -- requires just one modulo operation */
+    while (len >= NMAX) {
+        len -= NMAX;
+        n = NMAX / 16;          /* NMAX is divisible by 16 */
+        do {
+            DO16(buf);          /* 16 sums unrolled */
+            buf += 16;
+        } while (--n);
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* do remaining bytes (less than NMAX, still just one modulo) */
+    if (len) {                  /* avoid modulos if none remaining */
+        while (len >= 16) {
+            len -= 16;
+            DO16(buf);
+            buf += 16;
+        }
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* return recombined sums */
+    return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+local uLong adler32_combine_(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off64_t len2;
+{
+    unsigned long sum1;
+    unsigned long sum2;
+    unsigned rem;
+
+    /* for negative len, return invalid adler32 as a clue for debugging */
+    if (len2 < 0)
+        return 0xffffffffUL;
+
+    /* the derivation of this formula is left as an exercise for the reader */
+    MOD63(len2);                /* assumes len2 >= 0 */
+    rem = (unsigned)len2;
+    sum1 = adler1 & 0xffff;
+    sum2 = rem * sum1;
+    MOD(sum2);
+    sum1 += (adler2 & 0xffff) + BASE - 1;
+    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+    if (sum1 >= BASE) sum1 -= BASE;
+    if (sum1 >= BASE) sum1 -= BASE;
+    if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
+    if (sum2 >= BASE) sum2 -= BASE;
+    return sum1 | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off_t len2;
+{
+    return adler32_combine_(adler1, adler2, len2);
+}
+
+uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off64_t len2;
+{
+    return adler32_combine_(adler1, adler2, len2);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/crc32.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/crc32.c
new file mode 100755
index 0000000..979a719
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/crc32.c
@@ -0,0 +1,425 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64 at csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors.  This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+/*
+  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+  protection on the static variables used to control the first-use generation
+  of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+  first call get_crc_table() to initialize the tables before allowing more than
+  one thread to use crc32().
+
+  DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
+ */
+
+#ifdef MAKECRCH
+#  include <stdio.h>
+#  ifndef DYNAMIC_CRC_TABLE
+#    define DYNAMIC_CRC_TABLE
+#  endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h"      /* for STDC and FAR definitions */
+
+#define local static
+
+/* Definitions for doing the crc four data bytes at a time. */
+#if !defined(NOBYFOUR) && defined(Z_U4)
+#  define BYFOUR
+#endif
+#ifdef BYFOUR
+   local unsigned long crc32_little OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+   local unsigned long crc32_big OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+#  define TBLS 8
+#else
+#  define TBLS 1
+#endif /* BYFOUR */
+
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+                                         unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
+
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local z_crc_t FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+   local void write_table OF((FILE *, const z_crc_t FAR *));
+#endif /* MAKECRCH */
+/*
+  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit.  Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one.  If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder.  The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+  x (which is shifting right by one and adding x^32 mod p if the bit shifted
+  out is a one).  We start with the highest power (least significant bit) of
+  q and repeat for all eight bits of q.
+
+  The first table is simply the CRC of all possible eight bit values.  This is
+  all the information needed to generate CRCs on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.  The remaining tables
+  allow for word-at-a-time CRC calculation for both big-endian and little-
+  endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+    z_crc_t c;
+    int n, k;
+    z_crc_t poly;                       /* polynomial exclusive-or pattern */
+    /* terms of polynomial defining this crc (except x^32): */
+    static volatile int first = 1;      /* flag to limit concurrent making */
+    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+    /* See if another task is already doing this (not thread-safe, but better
+       than nothing -- significantly reduces duration of vulnerability in
+       case the advice about DYNAMIC_CRC_TABLE is ignored) */
+    if (first) {
+        first = 0;
+
+        /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+        poly = 0;
+        for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
+            poly |= (z_crc_t)1 << (31 - p[n]);
+
+        /* generate a crc for every 8-bit value */
+        for (n = 0; n < 256; n++) {
+            c = (z_crc_t)n;
+            for (k = 0; k < 8; k++)
+                c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+            crc_table[0][n] = c;
+        }
+
+#ifdef BYFOUR
+        /* generate crc for each value followed by one, two, and three zeros,
+           and then the byte reversal of those as well as the first table */
+        for (n = 0; n < 256; n++) {
+            c = crc_table[0][n];
+            crc_table[4][n] = ZSWAP32(c);
+            for (k = 1; k < 4; k++) {
+                c = crc_table[0][c & 0xff] ^ (c >> 8);
+                crc_table[k][n] = c;
+                crc_table[k + 4][n] = ZSWAP32(c);
+            }
+        }
+#endif /* BYFOUR */
+
+        crc_table_empty = 0;
+    }
+    else {      /* not first */
+        /* wait for the other guy to finish (not efficient, but rare) */
+        while (crc_table_empty)
+            ;
+    }
+
+#ifdef MAKECRCH
+    /* write out CRC tables to crc32.h */
+    {
+        FILE *out;
+
+        out = fopen("crc32.h", "w");
+        if (out == NULL) return;
+        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+        fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+        fprintf(out, "local const z_crc_t FAR ");
+        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
+        write_table(out, crc_table[0]);
+#  ifdef BYFOUR
+        fprintf(out, "#ifdef BYFOUR\n");
+        for (k = 1; k < 8; k++) {
+            fprintf(out, "  },\n  {\n");
+            write_table(out, crc_table[k]);
+        }
+        fprintf(out, "#endif\n");
+#  endif /* BYFOUR */
+        fprintf(out, "  }\n};\n");
+        fclose(out);
+    }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+    FILE *out;
+    const z_crc_t FAR *table;
+{
+    int n;
+
+    for (n = 0; n < 256; n++)
+        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ",
+                (unsigned long)(table[n]),
+                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const z_crc_t FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+    return (const z_crc_t FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    uInt len;
+{
+    if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+    if (sizeof(void *) == sizeof(ptrdiff_t)) {
+        z_crc_t endian;
+
+        endian = 1;
+        if (*((unsigned char *)(&endian)))
+            return crc32_little(crc, buf, len);
+        else
+            return crc32_big(crc, buf, len);
+    }
+#endif /* BYFOUR */
+    crc = crc ^ 0xffffffffUL;
+    while (len >= 8) {
+        DO8;
+        len -= 8;
+    }
+    if (len) do {
+        DO1;
+    } while (--len);
+    return crc ^ 0xffffffffUL;
+}
+
+#ifdef BYFOUR
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register z_crc_t c;
+    register const z_crc_t FAR *buf4;
+
+    c = (z_crc_t)crc;
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+        len--;
+    }
+
+    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+    while (len >= 32) {
+        DOLIT32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOLIT4;
+        len -= 4;
+    }
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *++buf4; \
+        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register z_crc_t c;
+    register const z_crc_t FAR *buf4;
+
+    c = ZSWAP32((z_crc_t)crc);
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+        len--;
+    }
+
+    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+    buf4--;
+    while (len >= 32) {
+        DOBIG32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOBIG4;
+        len -= 4;
+    }
+    buf4++;
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)(ZSWAP32(c));
+}
+
+#endif /* BYFOUR */
+
+#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+    unsigned long *mat;
+    unsigned long vec;
+{
+    unsigned long sum;
+
+    sum = 0;
+    while (vec) {
+        if (vec & 1)
+            sum ^= *mat;
+        vec >>= 1;
+        mat++;
+    }
+    return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+    unsigned long *square;
+    unsigned long *mat;
+{
+    int n;
+
+    for (n = 0; n < GF2_DIM; n++)
+        square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+local uLong crc32_combine_(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off64_t len2;
+{
+    int n;
+    unsigned long row;
+    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */
+    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */
+
+    /* degenerate case (also disallow negative lengths) */
+    if (len2 <= 0)
+        return crc1;
+
+    /* put operator for one zero bit in odd */
+    odd[0] = 0xedb88320UL;          /* CRC-32 polynomial */
+    row = 1;
+    for (n = 1; n < GF2_DIM; n++) {
+        odd[n] = row;
+        row <<= 1;
+    }
+
+    /* put operator for two zero bits in even */
+    gf2_matrix_square(even, odd);
+
+    /* put operator for four zero bits in odd */
+    gf2_matrix_square(odd, even);
+
+    /* apply len2 zeros to crc1 (first square will put the operator for one
+       zero byte, eight zero bits, in even) */
+    do {
+        /* apply zeros operator for this bit of len2 */
+        gf2_matrix_square(even, odd);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(even, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+        if (len2 == 0)
+            break;
+
+        /* another iteration of the loop with odd and even swapped */
+        gf2_matrix_square(odd, even);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(odd, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+    } while (len2 != 0);
+
+    /* return combined crc */
+    crc1 ^= crc2;
+    return crc1;
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off_t len2;
+{
+    return crc32_combine_(crc1, crc2, len2);
+}
+
+uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off64_t len2;
+{
+    return crc32_combine_(crc1, crc2, len2);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/crc32.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/crc32.h
new file mode 100755
index 0000000..9e0c778
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/crc32.h
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const z_crc_t FAR crc_table[TBLS][256] =
+{
+  {
+    0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+    0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+    0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+    0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+    0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+    0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+    0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+    0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+    0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+    0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+    0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+    0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+    0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+    0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+    0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+    0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+    0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+    0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+    0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+    0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+    0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+    0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+    0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+    0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+    0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+    0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+    0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+    0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+    0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+    0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+    0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+    0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+    0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+    0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+    0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+    0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+    0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+    0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+    0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+    0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+    0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+    0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+    0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+    0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+    0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+    0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+    0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+    0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+    0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+    0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+    0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+    0x2d02ef8dUL
+#ifdef BYFOUR
+  },
+  {
+    0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+    0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+    0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+    0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+    0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+    0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+    0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+    0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+    0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+    0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+    0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+    0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+    0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+    0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+    0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+    0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+    0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+    0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+    0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+    0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+    0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+    0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+    0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+    0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+    0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+    0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+    0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+    0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+    0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+    0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+    0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+    0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+    0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+    0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+    0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+    0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+    0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+    0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+    0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+    0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+    0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+    0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+    0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+    0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+    0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+    0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+    0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+    0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+    0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+    0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+    0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+    0x9324fd72UL
+  },
+  {
+    0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+    0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+    0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+    0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+    0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+    0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+    0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+    0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+    0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+    0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+    0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+    0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+    0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+    0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+    0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+    0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+    0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+    0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+    0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+    0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+    0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+    0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+    0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+    0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+    0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+    0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+    0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+    0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+    0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+    0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+    0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+    0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+    0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+    0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+    0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+    0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+    0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+    0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+    0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+    0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+    0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+    0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+    0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+    0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+    0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+    0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+    0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+    0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+    0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+    0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+    0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+    0xbe9834edUL
+  },
+  {
+    0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+    0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+    0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+    0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+    0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+    0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+    0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+    0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+    0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+    0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+    0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+    0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+    0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+    0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+    0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+    0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+    0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+    0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+    0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+    0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+    0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+    0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+    0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+    0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+    0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+    0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+    0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+    0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+    0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+    0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+    0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+    0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+    0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+    0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+    0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+    0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+    0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+    0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+    0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+    0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+    0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+    0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+    0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+    0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+    0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+    0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+    0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+    0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+    0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+    0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+    0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+    0xde0506f1UL
+  },
+  {
+    0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+    0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+    0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+    0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+    0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+    0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+    0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+    0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+    0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+    0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+    0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+    0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+    0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+    0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+    0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+    0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+    0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+    0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+    0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+    0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+    0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+    0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+    0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+    0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+    0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+    0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+    0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+    0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+    0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+    0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+    0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+    0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+    0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+    0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+    0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+    0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+    0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+    0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+    0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+    0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+    0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+    0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+    0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+    0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+    0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+    0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+    0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+    0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+    0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+    0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+    0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+    0x8def022dUL
+  },
+  {
+    0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+    0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+    0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+    0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+    0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+    0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+    0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+    0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+    0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+    0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+    0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+    0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+    0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+    0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+    0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+    0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+    0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+    0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+    0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+    0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+    0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+    0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+    0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+    0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+    0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+    0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+    0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+    0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+    0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+    0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+    0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+    0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+    0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+    0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+    0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+    0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+    0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+    0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+    0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+    0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+    0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+    0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+    0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+    0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+    0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+    0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+    0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+    0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+    0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+    0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+    0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+    0x72fd2493UL
+  },
+  {
+    0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+    0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+    0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+    0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+    0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+    0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+    0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+    0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+    0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+    0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+    0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+    0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+    0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+    0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+    0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+    0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+    0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+    0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+    0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+    0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+    0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+    0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+    0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+    0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+    0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+    0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+    0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+    0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+    0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+    0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+    0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+    0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+    0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+    0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+    0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+    0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+    0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+    0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+    0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+    0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+    0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+    0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+    0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+    0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+    0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+    0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+    0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+    0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+    0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+    0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+    0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+    0xed3498beUL
+  },
+  {
+    0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+    0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+    0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+    0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+    0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+    0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+    0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+    0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+    0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+    0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+    0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+    0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+    0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+    0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+    0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+    0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+    0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+    0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+    0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+    0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+    0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+    0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+    0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+    0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+    0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+    0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+    0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+    0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+    0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+    0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+    0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+    0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+    0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+    0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+    0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+    0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+    0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+    0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+    0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+    0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+    0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+    0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+    0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+    0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+    0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+    0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+    0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+    0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+    0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+    0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+    0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+    0xf10605deUL
+#endif
+  }
+};
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/deflate.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/deflate.c
new file mode 100755
index 0000000..6969577
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/deflate.c
@@ -0,0 +1,1967 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process depends on being able to identify portions
+ *      of the input text which are identical to earlier input (within a
+ *      sliding window trailing behind the input currently being processed).
+ *
+ *      The most straightforward technique turns out to be the fastest for
+ *      most input files: try all possible matches and select the longest.
+ *      The key feature of this algorithm is that insertions into the string
+ *      dictionary are very simple and thus fast, and deletions are avoided
+ *      completely. Insertions are performed at each input character, whereas
+ *      string matches are performed only when the previous match ends. So it
+ *      is preferable to spend more time in matches to allow very fast string
+ *      insertions and avoid deletions. The matching algorithm for small
+ *      strings is inspired from that of Rabin & Karp. A brute force approach
+ *      is used to find longer strings when a small match has been found.
+ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ *      (by Leonid Broukhis).
+ *         A previous version of this file used a more sophisticated algorithm
+ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
+ *      time, but has a larger average cost, uses more memory and is patented.
+ *      However the F&G algorithm may be faster for some highly redundant
+ *      files if the parameter max_chain_length (described below) is too large.
+ *
+ *  ACKNOWLEDGEMENTS
+ *
+ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ *      I found it in 'freeze' written by Leonid Broukhis.
+ *      Thanks to many people for bug reports and testing.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ *      Available in http://tools.ietf.org/html/rfc1951
+ *
+ *      A description of the Rabin and Karp algorithm is given in the book
+ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ *      Fiala,E.R., and Greene,D.H.
+ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+   " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ *  Function prototypes.
+ */
+typedef enum {
+    need_more,      /* block not completed, need more input or more output */
+    block_done,     /* block flush performed */
+    finish_started, /* finish started, need only more output at next deflate */
+    finish_done     /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window    OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast   OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow   OF((deflate_state *s, int flush));
+#endif
+local block_state deflate_rle    OF((deflate_state *s, int flush));
+local block_state deflate_huff   OF((deflate_state *s, int flush));
+local void lm_init        OF((deflate_state *s));
+local void putShortMSB    OF((deflate_state *s, uInt b));
+local void flush_pending  OF((z_streamp strm));
+local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifdef ASMV
+      void match_init OF((void)); /* asm code initialization */
+      uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef DEBUG
+local  void check_match OF((deflate_state *s, IPos start, IPos match,
+                            int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+#  define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+   ush good_length; /* reduce lazy search above this match length */
+   ush max_lazy;    /* do not perform lazy search above this match length */
+   ush nice_length; /* quit search above this match length */
+   ush max_chain;
+   compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4,    5, 16,    8, deflate_fast},
+/* 3 */ {4,    6, 32,   32, deflate_fast},
+
+/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
+/* 5 */ {8,   16, 32,   32, deflate_slow},
+/* 6 */ {8,   16, 128, 128, deflate_slow},
+/* 7 */ {8,   32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+#ifndef NO_DUMMY_DECL
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+#endif
+
+/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
+#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0))
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
+ *    input characters, so that a running hash key can be computed from the
+ *    previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
+ *    input characters and the first MIN_MATCH bytes of str are valid
+ *    (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+    s->head[s->hash_size-1] = NIL; \
+    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+    z_streamp strm;
+    int level;
+    const char *version;
+    int stream_size;
+{
+    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+                         Z_DEFAULT_STRATEGY, version, stream_size);
+    /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+                  version, stream_size)
+    z_streamp strm;
+    int  level;
+    int  method;
+    int  windowBits;
+    int  memLevel;
+    int  strategy;
+    const char *version;
+    int stream_size;
+{
+    deflate_state *s;
+    int wrap = 1;
+    static const char my_version[] = ZLIB_VERSION;
+
+    ushf *overlay;
+    /* We overlay pending_buf and d_buf+l_buf. This works since the average
+     * output size for (length,distance) codes is <= 24 bits.
+     */
+
+    if (version == Z_NULL || version[0] != my_version[0] ||
+        stream_size != sizeof(z_stream)) {
+        return Z_VERSION_ERROR;
+    }
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->msg = Z_NULL;
+    if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+#endif
+    }
+    if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zfree = zcfree;
+#endif
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+    if (windowBits < 0) { /* suppress zlib wrapper */
+        wrap = 0;
+        windowBits = -windowBits;
+    }
+#ifdef GZIP
+    else if (windowBits > 15) {
+        wrap = 2;       /* write gzip wrapper instead */
+        windowBits -= 16;
+    }
+#endif
+    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+        strategy < 0 || strategy > Z_FIXED) {
+        return Z_STREAM_ERROR;
+    }
+    if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */
+    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+    if (s == Z_NULL) return Z_MEM_ERROR;
+    strm->state = (struct internal_state FAR *)s;
+    s->strm = strm;
+
+    s->wrap = wrap;
+    s->gzhead = Z_NULL;
+    s->w_bits = windowBits;
+    s->w_size = 1 << s->w_bits;
+    s->w_mask = s->w_size - 1;
+
+    s->hash_bits = memLevel + 7;
+    s->hash_size = 1 << s->hash_bits;
+    s->hash_mask = s->hash_size - 1;
+    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
+    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+    s->high_water = 0;      /* nothing written to s->window yet */
+
+    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+    s->pending_buf = (uchf *) overlay;
+    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+        s->pending_buf == Z_NULL) {
+        s->status = FINISH_STATE;
+        strm->msg = ERR_MSG(Z_MEM_ERROR);
+        deflateEnd (strm);
+        return Z_MEM_ERROR;
+    }
+    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+    s->level = level;
+    s->strategy = strategy;
+    s->method = (Byte)method;
+
+    return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+    z_streamp strm;
+    const Bytef *dictionary;
+    uInt  dictLength;
+{
+    deflate_state *s;
+    uInt str, n;
+    int wrap;
+    unsigned avail;
+    z_const unsigned char *next;
+
+    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)
+        return Z_STREAM_ERROR;
+    s = strm->state;
+    wrap = s->wrap;
+    if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
+        return Z_STREAM_ERROR;
+
+    /* when using zlib wrappers, compute Adler-32 for provided dictionary */
+    if (wrap == 1)
+        strm->adler = adler32(strm->adler, dictionary, dictLength);
+    s->wrap = 0;                    /* avoid computing Adler-32 in read_buf */
+
+    /* if dictionary would fill window, just replace the history */
+    if (dictLength >= s->w_size) {
+        if (wrap == 0) {            /* already empty otherwise */
+            CLEAR_HASH(s);
+            s->strstart = 0;
+            s->block_start = 0L;
+            s->insert = 0;
+        }
+        dictionary += dictLength - s->w_size;  /* use the tail */
+        dictLength = s->w_size;
+    }
+
+    /* insert dictionary into window and hash */
+    avail = strm->avail_in;
+    next = strm->next_in;
+    strm->avail_in = dictLength;
+    strm->next_in = (z_const Bytef *)dictionary;
+    fill_window(s);
+    while (s->lookahead >= MIN_MATCH) {
+        str = s->strstart;
+        n = s->lookahead - (MIN_MATCH-1);
+        do {
+            UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+            s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+            s->head[s->ins_h] = (Pos)str;
+            str++;
+        } while (--n);
+        s->strstart = str;
+        s->lookahead = MIN_MATCH-1;
+        fill_window(s);
+    }
+    s->strstart += s->lookahead;
+    s->block_start = (long)s->strstart;
+    s->insert = s->lookahead;
+    s->lookahead = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    strm->next_in = next;
+    strm->avail_in = avail;
+    s->wrap = wrap;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateResetKeep (strm)
+    z_streamp strm;
+{
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
+        return Z_STREAM_ERROR;
+    }
+
+    strm->total_in = strm->total_out = 0;
+    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+    strm->data_type = Z_UNKNOWN;
+
+    s = (deflate_state *)strm->state;
+    s->pending = 0;
+    s->pending_out = s->pending_buf;
+
+    if (s->wrap < 0) {
+        s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+    }
+    s->status = s->wrap ? INIT_STATE : BUSY_STATE;
+    strm->adler =
+#ifdef GZIP
+        s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+        adler32(0L, Z_NULL, 0);
+    s->last_flush = Z_NO_FLUSH;
+
+    _tr_init(s);
+
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+    z_streamp strm;
+{
+    int ret;
+
+    ret = deflateResetKeep(strm);
+    if (ret == Z_OK)
+        lm_init(strm->state);
+    return ret;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetHeader (strm, head)
+    z_streamp strm;
+    gz_headerp head;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    if (strm->state->wrap != 2) return Z_STREAM_ERROR;
+    strm->state->gzhead = head;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePending (strm, pending, bits)
+    unsigned *pending;
+    int *bits;
+    z_streamp strm;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    if (pending != Z_NULL)
+        *pending = strm->state->pending;
+    if (bits != Z_NULL)
+        *bits = strm->state->bi_valid;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (strm, bits, value)
+    z_streamp strm;
+    int bits;
+    int value;
+{
+    deflate_state *s;
+    int put;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+    if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
+        return Z_BUF_ERROR;
+    do {
+        put = Buf_size - s->bi_valid;
+        if (put > bits)
+            put = bits;
+        s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
+        s->bi_valid += put;
+        _tr_flush_bits(s);
+        value >>= put;
+        bits -= put;
+    } while (bits);
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+    z_streamp strm;
+    int level;
+    int strategy;
+{
+    deflate_state *s;
+    compress_func func;
+    int err = Z_OK;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
+        return Z_STREAM_ERROR;
+    }
+    func = configuration_table[s->level].func;
+
+    if ((strategy != s->strategy || func != configuration_table[level].func) &&
+        strm->total_in != 0) {
+        /* Flush the last buffer: */
+        err = deflate(strm, Z_BLOCK);
+        if (err == Z_BUF_ERROR && s->pending == 0)
+            err = Z_OK;
+    }
+    if (s->level != level) {
+        s->level = level;
+        s->max_lazy_match   = configuration_table[level].max_lazy;
+        s->good_match       = configuration_table[level].good_length;
+        s->nice_match       = configuration_table[level].nice_length;
+        s->max_chain_length = configuration_table[level].max_chain;
+    }
+    s->strategy = strategy;
+    return err;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
+    z_streamp strm;
+    int good_length;
+    int max_lazy;
+    int nice_length;
+    int max_chain;
+{
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+    s->good_match = good_length;
+    s->max_lazy_match = max_lazy;
+    s->nice_match = nice_length;
+    s->max_chain_length = max_chain;
+    return Z_OK;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well.  The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds for
+ * every combination of windowBits and memLevel.  But even the conservative
+ * upper bound of about 14% expansion does not seem onerous for output buffer
+ * allocation.
+ */
+uLong ZEXPORT deflateBound(strm, sourceLen)
+    z_streamp strm;
+    uLong sourceLen;
+{
+    deflate_state *s;
+    uLong complen, wraplen;
+    Bytef *str;
+
+    /* conservative upper bound for compressed data */
+    complen = sourceLen +
+              ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
+
+    /* if can't get parameters, return conservative bound plus zlib wrapper */
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return complen + 6;
+
+    /* compute wrapper length */
+    s = strm->state;
+    switch (s->wrap) {
+    case 0:                                 /* raw deflate */
+        wraplen = 0;
+        break;
+    case 1:                                 /* zlib wrapper */
+        wraplen = 6 + (s->strstart ? 4 : 0);
+        break;
+    case 2:                                 /* gzip wrapper */
+        wraplen = 18;
+        if (s->gzhead != Z_NULL) {          /* user-supplied gzip header */
+            if (s->gzhead->extra != Z_NULL)
+                wraplen += 2 + s->gzhead->extra_len;
+            str = s->gzhead->name;
+            if (str != Z_NULL)
+                do {
+                    wraplen++;
+                } while (*str++);
+            str = s->gzhead->comment;
+            if (str != Z_NULL)
+                do {
+                    wraplen++;
+                } while (*str++);
+            if (s->gzhead->hcrc)
+                wraplen += 2;
+        }
+        break;
+    default:                                /* for compiler happiness */
+        wraplen = 6;
+    }
+
+    /* if not default parameters, return conservative bound */
+    if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+        return complen + wraplen;
+
+    /* default settings: return tight bound for that case */
+    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+           (sourceLen >> 25) + 13 - 6 + wraplen;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+    deflate_state *s;
+    uInt b;
+{
+    put_byte(s, (Byte)(b >> 8));
+    put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+    z_streamp strm;
+{
+    unsigned len;
+    deflate_state *s = strm->state;
+
+    _tr_flush_bits(s);
+    len = s->pending;
+    if (len > strm->avail_out) len = strm->avail_out;
+    if (len == 0) return;
+
+    zmemcpy(strm->next_out, s->pending_out, len);
+    strm->next_out  += len;
+    s->pending_out  += len;
+    strm->total_out += len;
+    strm->avail_out  -= len;
+    s->pending -= len;
+    if (s->pending == 0) {
+        s->pending_out = s->pending_buf;
+    }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+    z_streamp strm;
+    int flush;
+{
+    int old_flush; /* value of flush param for previous deflate call */
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        flush > Z_BLOCK || flush < 0) {
+        return Z_STREAM_ERROR;
+    }
+    s = strm->state;
+
+    if (strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+        (s->status == FINISH_STATE && flush != Z_FINISH)) {
+        ERR_RETURN(strm, Z_STREAM_ERROR);
+    }
+    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+    s->strm = strm; /* just in case */
+    old_flush = s->last_flush;
+    s->last_flush = flush;
+
+    /* Write the header */
+    if (s->status == INIT_STATE) {
+#ifdef GZIP
+        if (s->wrap == 2) {
+            strm->adler = crc32(0L, Z_NULL, 0);
+            put_byte(s, 31);
+            put_byte(s, 139);
+            put_byte(s, 8);
+            if (s->gzhead == Z_NULL) {
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, s->level == 9 ? 2 :
+                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                             4 : 0));
+                put_byte(s, OS_CODE);
+                s->status = BUSY_STATE;
+            }
+            else {
+                put_byte(s, (s->gzhead->text ? 1 : 0) +
+                            (s->gzhead->hcrc ? 2 : 0) +
+                            (s->gzhead->extra == Z_NULL ? 0 : 4) +
+                            (s->gzhead->name == Z_NULL ? 0 : 8) +
+                            (s->gzhead->comment == Z_NULL ? 0 : 16)
+                        );
+                put_byte(s, (Byte)(s->gzhead->time & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+                put_byte(s, s->level == 9 ? 2 :
+                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                             4 : 0));
+                put_byte(s, s->gzhead->os & 0xff);
+                if (s->gzhead->extra != Z_NULL) {
+                    put_byte(s, s->gzhead->extra_len & 0xff);
+                    put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
+                }
+                if (s->gzhead->hcrc)
+                    strm->adler = crc32(strm->adler, s->pending_buf,
+                                        s->pending);
+                s->gzindex = 0;
+                s->status = EXTRA_STATE;
+            }
+        }
+        else
+#endif
+        {
+            uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+            uInt level_flags;
+
+            if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+                level_flags = 0;
+            else if (s->level < 6)
+                level_flags = 1;
+            else if (s->level == 6)
+                level_flags = 2;
+            else
+                level_flags = 3;
+            header |= (level_flags << 6);
+            if (s->strstart != 0) header |= PRESET_DICT;
+            header += 31 - (header % 31);
+
+            s->status = BUSY_STATE;
+            putShortMSB(s, header);
+
+            /* Save the adler32 of the preset dictionary: */
+            if (s->strstart != 0) {
+                putShortMSB(s, (uInt)(strm->adler >> 16));
+                putShortMSB(s, (uInt)(strm->adler & 0xffff));
+            }
+            strm->adler = adler32(0L, Z_NULL, 0);
+        }
+    }
+#ifdef GZIP
+    if (s->status == EXTRA_STATE) {
+        if (s->gzhead->extra != Z_NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+
+            while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size)
+                        break;
+                }
+                put_byte(s, s->gzhead->extra[s->gzindex]);
+                s->gzindex++;
+            }
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (s->gzindex == s->gzhead->extra_len) {
+                s->gzindex = 0;
+                s->status = NAME_STATE;
+            }
+        }
+        else
+            s->status = NAME_STATE;
+    }
+    if (s->status == NAME_STATE) {
+        if (s->gzhead->name != Z_NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+            int val;
+
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size) {
+                        val = 1;
+                        break;
+                    }
+                }
+                val = s->gzhead->name[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (val == 0) {
+                s->gzindex = 0;
+                s->status = COMMENT_STATE;
+            }
+        }
+        else
+            s->status = COMMENT_STATE;
+    }
+    if (s->status == COMMENT_STATE) {
+        if (s->gzhead->comment != Z_NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+            int val;
+
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size) {
+                        val = 1;
+                        break;
+                    }
+                }
+                val = s->gzhead->comment[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (val == 0)
+                s->status = HCRC_STATE;
+        }
+        else
+            s->status = HCRC_STATE;
+    }
+    if (s->status == HCRC_STATE) {
+        if (s->gzhead->hcrc) {
+            if (s->pending + 2 > s->pending_buf_size)
+                flush_pending(strm);
+            if (s->pending + 2 <= s->pending_buf_size) {
+                put_byte(s, (Byte)(strm->adler & 0xff));
+                put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+                strm->adler = crc32(0L, Z_NULL, 0);
+                s->status = BUSY_STATE;
+            }
+        }
+        else
+            s->status = BUSY_STATE;
+    }
+#endif
+
+    /* Flush as much pending output as possible */
+    if (s->pending != 0) {
+        flush_pending(strm);
+        if (strm->avail_out == 0) {
+            /* Since avail_out is 0, deflate will be called again with
+             * more output space, but possibly with both pending and
+             * avail_in equal to zero. There won't be anything to do,
+             * but this is not an error situation so make sure we
+             * return OK instead of BUF_ERROR at next call of deflate:
+             */
+            s->last_flush = -1;
+            return Z_OK;
+        }
+
+    /* Make sure there is something to do and avoid duplicate consecutive
+     * flushes. For repeated and useless calls with Z_FINISH, we keep
+     * returning Z_STREAM_END instead of Z_BUF_ERROR.
+     */
+    } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
+               flush != Z_FINISH) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* User must not provide more input after the first FINISH: */
+    if (s->status == FINISH_STATE && strm->avail_in != 0) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* Start a new block or continue the current one.
+     */
+    if (strm->avail_in != 0 || s->lookahead != 0 ||
+        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+        block_state bstate;
+
+        bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
+                    (s->strategy == Z_RLE ? deflate_rle(s, flush) :
+                        (*(configuration_table[s->level].func))(s, flush));
+
+        if (bstate == finish_started || bstate == finish_done) {
+            s->status = FINISH_STATE;
+        }
+        if (bstate == need_more || bstate == finish_started) {
+            if (strm->avail_out == 0) {
+                s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+            }
+            return Z_OK;
+            /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+             * of deflate should use the same flush parameter to make sure
+             * that the flush is complete. So we don't have to output an
+             * empty block here, this will be done at next call. This also
+             * ensures that for a very small output buffer, we emit at most
+             * one empty block.
+             */
+        }
+        if (bstate == block_done) {
+            if (flush == Z_PARTIAL_FLUSH) {
+                _tr_align(s);
+            } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
+                _tr_stored_block(s, (char*)0, 0L, 0);
+                /* For a full flush, this empty block will be recognized
+                 * as a special marker by inflate_sync().
+                 */
+                if (flush == Z_FULL_FLUSH) {
+                    CLEAR_HASH(s);             /* forget history */
+                    if (s->lookahead == 0) {
+                        s->strstart = 0;
+                        s->block_start = 0L;
+                        s->insert = 0;
+                    }
+                }
+            }
+            flush_pending(strm);
+            if (strm->avail_out == 0) {
+              s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+              return Z_OK;
+            }
+        }
+    }
+    Assert(strm->avail_out > 0, "bug2");
+
+    if (flush != Z_FINISH) return Z_OK;
+    if (s->wrap <= 0) return Z_STREAM_END;
+
+    /* Write the trailer */
+#ifdef GZIP
+    if (s->wrap == 2) {
+        put_byte(s, (Byte)(strm->adler & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+        put_byte(s, (Byte)(strm->total_in & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+    }
+    else
+#endif
+    {
+        putShortMSB(s, (uInt)(strm->adler >> 16));
+        putShortMSB(s, (uInt)(strm->adler & 0xffff));
+    }
+    flush_pending(strm);
+    /* If avail_out is zero, the application will call deflate again
+     * to flush the rest.
+     */
+    if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+    return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+    z_streamp strm;
+{
+    int status;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+    status = strm->state->status;
+    if (status != INIT_STATE &&
+        status != EXTRA_STATE &&
+        status != NAME_STATE &&
+        status != COMMENT_STATE &&
+        status != HCRC_STATE &&
+        status != BUSY_STATE &&
+        status != FINISH_STATE) {
+      return Z_STREAM_ERROR;
+    }
+
+    /* Deallocate in reverse order of allocations: */
+    TRY_FREE(strm, strm->state->pending_buf);
+    TRY_FREE(strm, strm->state->head);
+    TRY_FREE(strm, strm->state->prev);
+    TRY_FREE(strm, strm->state->window);
+
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+
+    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+    z_streamp dest;
+    z_streamp source;
+{
+#ifdef MAXSEG_64K
+    return Z_STREAM_ERROR;
+#else
+    deflate_state *ds;
+    deflate_state *ss;
+    ushf *overlay;
+
+
+    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+        return Z_STREAM_ERROR;
+    }
+
+    ss = source->state;
+
+    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+
+    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+    if (ds == Z_NULL) return Z_MEM_ERROR;
+    dest->state = (struct internal_state FAR *) ds;
+    zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
+    ds->strm = dest;
+
+    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
+    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
+    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+    ds->pending_buf = (uchf *) overlay;
+
+    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+        ds->pending_buf == Z_NULL) {
+        deflateEnd (dest);
+        return Z_MEM_ERROR;
+    }
+    /* following zmemcpy do not work for 16-bit MSDOS */
+    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+    zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
+    zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
+    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+    ds->l_desc.dyn_tree = ds->dyn_ltree;
+    ds->d_desc.dyn_tree = ds->dyn_dtree;
+    ds->bl_desc.dyn_tree = ds->bl_tree;
+
+    return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.  All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+    z_streamp strm;
+    Bytef *buf;
+    unsigned size;
+{
+    unsigned len = strm->avail_in;
+
+    if (len > size) len = size;
+    if (len == 0) return 0;
+
+    strm->avail_in  -= len;
+
+    zmemcpy(buf, strm->next_in, len);
+    if (strm->state->wrap == 1) {
+        strm->adler = adler32(strm->adler, buf, len);
+    }
+#ifdef GZIP
+    else if (strm->state->wrap == 2) {
+        strm->adler = crc32(strm->adler, buf, len);
+    }
+#endif
+    strm->next_in  += len;
+    strm->total_in += len;
+
+    return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+    deflate_state *s;
+{
+    s->window_size = (ulg)2L*s->w_size;
+
+    CLEAR_HASH(s);
+
+    /* Set the default configuration parameters:
+     */
+    s->max_lazy_match   = configuration_table[s->level].max_lazy;
+    s->good_match       = configuration_table[s->level].good_length;
+    s->nice_match       = configuration_table[s->level].nice_length;
+    s->max_chain_length = configuration_table[s->level].max_chain;
+
+    s->strstart = 0;
+    s->block_start = 0L;
+    s->lookahead = 0;
+    s->insert = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    s->ins_h = 0;
+#ifndef FASTEST
+#ifdef ASMV
+    match_init(); /* initialize the asm code */
+#endif
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    unsigned chain_length = s->max_chain_length;/* max hash chain length */
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    int best_len = s->prev_length;              /* best match length so far */
+    int nice_match = s->nice_match;             /* stop if match long enough */
+    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+        s->strstart - (IPos)MAX_DIST(s) : NIL;
+    /* Stop when cur_match becomes <= limit. To simplify the code,
+     * we prevent matches with the string of window index 0.
+     */
+    Posf *prev = s->prev;
+    uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+    /* Compare two bytes at a time. Note: this is not always beneficial.
+     * Try with and without -DUNALIGNED_OK to check.
+     */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+    register ush scan_start = *(ushf*)scan;
+    register ush scan_end   = *(ushf*)(scan+best_len-1);
+#else
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+    register Byte scan_end1  = scan[best_len-1];
+    register Byte scan_end   = scan[best_len];
+#endif
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    /* Do not waste too much time if we already have a good match: */
+    if (s->prev_length >= s->good_match) {
+        chain_length >>= 2;
+    }
+    /* Do not look for matches beyond the end of the input. This is necessary
+     * to make deflate deterministic.
+     */
+    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    do {
+        Assert(cur_match < s->strstart, "no future");
+        match = s->window + cur_match;
+
+        /* Skip to next match if the match length cannot increase
+         * or if the match length is less than 2.  Note that the checks below
+         * for insufficient lookahead only occur occasionally for performance
+         * reasons.  Therefore uninitialized memory will be accessed, and
+         * conditional jumps will be made that depend on those values.
+         * However the length of the match is limited to the lookahead, so
+         * the output of deflate is not affected by the uninitialized values.
+         */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+        /* This code assumes sizeof(unsigned short) == 2. Do not use
+         * UNALIGNED_OK if your compiler uses a different size.
+         */
+        if (*(ushf*)(match+best_len-1) != scan_end ||
+            *(ushf*)match != scan_start) continue;
+
+        /* It is not necessary to compare scan[2] and match[2] since they are
+         * always equal when the other bytes match, given that the hash keys
+         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+         * strstart+3, +5, ... up to strstart+257. We check for insufficient
+         * lookahead only every 4th comparison; the 128th check will be made
+         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+         * necessary to put more guard bytes at the end of the window, or
+         * to check more often for insufficient lookahead.
+         */
+        Assert(scan[2] == match[2], "scan[2]?");
+        scan++, match++;
+        do {
+        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 scan < strend);
+        /* The funny "do {}" generates better code on most compilers */
+
+        /* Here, scan <= window+strstart+257 */
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+        if (*scan == *match) scan++;
+
+        len = (MAX_MATCH - 1) - (int)(strend-scan);
+        scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+        if (match[best_len]   != scan_end  ||
+            match[best_len-1] != scan_end1 ||
+            *match            != *scan     ||
+            *++match          != scan[1])      continue;
+
+        /* The check at best_len-1 can be removed because it will be made
+         * again later. (This heuristic is not always a win.)
+         * It is not necessary to compare scan[2] and match[2] since they
+         * are always equal when the other bytes match, given that
+         * the hash keys are equal and that HASH_BITS >= 8.
+         */
+        scan += 2, match++;
+        Assert(*scan == *match, "match[2]?");
+
+        /* We check for insufficient lookahead only every 8th comparison;
+         * the 256th check will be made at strstart+258.
+         */
+        do {
+        } while (*++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 scan < strend);
+
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+        len = MAX_MATCH - (int)(strend - scan);
+        scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+        if (len > best_len) {
+            s->match_start = cur_match;
+            best_len = len;
+            if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+            scan_end = *(ushf*)(scan+best_len-1);
+#else
+            scan_end1  = scan[best_len-1];
+            scan_end   = scan[best_len];
+#endif
+        }
+    } while ((cur_match = prev[cur_match & wmask]) > limit
+             && --chain_length != 0);
+
+    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+    return s->lookahead;
+}
+#endif /* ASMV */
+
+#else /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for FASTEST only
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    Assert(cur_match < s->strstart, "no future");
+
+    match = s->window + cur_match;
+
+    /* Return failure if the match length is less than 2:
+     */
+    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+    /* The check at best_len-1 can be removed because it will be made
+     * again later. (This heuristic is not always a win.)
+     * It is not necessary to compare scan[2] and match[2] since they
+     * are always equal when the other bytes match, given that
+     * the hash keys are equal and that HASH_BITS >= 8.
+     */
+    scan += 2, match += 2;
+    Assert(*scan == *match, "match[2]?");
+
+    /* We check for insufficient lookahead only every 8th comparison;
+     * the 256th check will be made at strstart+258.
+     */
+    do {
+    } while (*++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             scan < strend);
+
+    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+    len = MAX_MATCH - (int)(strend - scan);
+
+    if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+    s->match_start = cur_match;
+    return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#endif /* FASTEST */
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+    deflate_state *s;
+    IPos start, match;
+    int length;
+{
+    /* check that the match is indeed a match */
+    if (zmemcmp(s->window + match,
+                s->window + start, length) != EQUAL) {
+        fprintf(stderr, " start %u, match %u, length %d\n",
+                start, match, length);
+        do {
+            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+        } while (--length != 0);
+        z_error("invalid match");
+    }
+    if (z_verbose > 1) {
+        fprintf(stderr,"\\[%d,%d]", start-match, length);
+        do { putc(s->window[start++], stderr); } while (--length != 0);
+    }
+}
+#else
+#  define check_match(s, start, match, length)
+#endif /* DEBUG */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+local void fill_window(s)
+    deflate_state *s;
+{
+    register unsigned n, m;
+    register Posf *p;
+    unsigned more;    /* Amount of free space at the end of the window. */
+    uInt wsize = s->w_size;
+
+    Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
+
+    do {
+        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+        /* Deal with !@#$% 64K limit: */
+        if (sizeof(int) <= 2) {
+            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+                more = wsize;
+
+            } else if (more == (unsigned)(-1)) {
+                /* Very unlikely, but possible on 16 bit machine if
+                 * strstart == 0 && lookahead == 1 (input done a byte at time)
+                 */
+                more--;
+            }
+        }
+
+        /* If the window is almost full and there is insufficient lookahead,
+         * move the upper half to the lower one to make room in the upper half.
+         */
+        if (s->strstart >= wsize+MAX_DIST(s)) {
+
+            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+            s->match_start -= wsize;
+            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
+            s->block_start -= (long) wsize;
+
+            /* Slide the hash table (could be avoided with 32 bit values
+               at the expense of memory usage). We slide even when level == 0
+               to keep the hash table consistent if we switch back to level > 0
+               later. (Using level 0 permanently is not an optimal usage of
+               zlib, so we don't care about this pathological case.)
+             */
+            n = s->hash_size;
+            p = &s->head[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+            } while (--n);
+
+            n = wsize;
+#ifndef FASTEST
+            p = &s->prev[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+                /* If n is not on any hash chain, prev[n] is garbage but
+                 * its value will never be used.
+                 */
+            } while (--n);
+#endif
+            more += wsize;
+        }
+        if (s->strm->avail_in == 0) break;
+
+        /* If there was no sliding:
+         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+         *    more == window_size - lookahead - strstart
+         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+         * => more >= window_size - 2*WSIZE + 2
+         * In the BIG_MEM or MMAP case (not yet supported),
+         *   window_size == input_size + MIN_LOOKAHEAD  &&
+         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+         * Otherwise, window_size == 2*WSIZE so more >= 2.
+         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+         */
+        Assert(more >= 2, "more < 2");
+
+        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+        s->lookahead += n;
+
+        /* Initialize the hash value now that we have some input: */
+        if (s->lookahead + s->insert >= MIN_MATCH) {
+            uInt str = s->strstart - s->insert;
+            s->ins_h = s->window[str];
+            UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
+#if MIN_MATCH != 3
+            Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+            while (s->insert) {
+                UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+                s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+                s->head[s->ins_h] = (Pos)str;
+                str++;
+                s->insert--;
+                if (s->lookahead + s->insert < MIN_MATCH)
+                    break;
+            }
+        }
+        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+         * but this is not important since only literal bytes will be emitted.
+         */
+
+    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+
+    /* If the WIN_INIT bytes after the end of the current data have never been
+     * written, then zero those bytes in order to avoid memory check reports of
+     * the use of uninitialized (or uninitialised as Julian writes) bytes by
+     * the longest match routines.  Update the high water mark for the next
+     * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
+     * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
+     */
+    if (s->high_water < s->window_size) {
+        ulg curr = s->strstart + (ulg)(s->lookahead);
+        ulg init;
+
+        if (s->high_water < curr) {
+            /* Previous high water mark below current data -- zero WIN_INIT
+             * bytes or up to end of window, whichever is less.
+             */
+            init = s->window_size - curr;
+            if (init > WIN_INIT)
+                init = WIN_INIT;
+            zmemzero(s->window + curr, (unsigned)init);
+            s->high_water = curr + init;
+        }
+        else if (s->high_water < (ulg)curr + WIN_INIT) {
+            /* High water mark at or above current data, but below current data
+             * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
+             * to end of window, whichever is less.
+             */
+            init = (ulg)curr + WIN_INIT - s->high_water;
+            if (init > s->window_size - s->high_water)
+                init = s->window_size - s->high_water;
+            zmemzero(s->window + s->high_water, (unsigned)init);
+            s->high_water += init;
+        }
+    }
+
+    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
+           "not enough room for search");
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, last) { \
+   _tr_flush_block(s, (s->block_start >= 0L ? \
+                   (charf *)&s->window[(unsigned)s->block_start] : \
+                   (charf *)Z_NULL), \
+                (ulg)((long)s->strstart - s->block_start), \
+                (last)); \
+   s->block_start = s->strstart; \
+   flush_pending(s->strm); \
+   Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, last) { \
+   FLUSH_BLOCK_ONLY(s, last); \
+   if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+     * to pending_buf_size, and each stored block has a 5 byte header:
+     */
+    ulg max_block_size = 0xffff;
+    ulg max_start;
+
+    if (max_block_size > s->pending_buf_size - 5) {
+        max_block_size = s->pending_buf_size - 5;
+    }
+
+    /* Copy as much as possible from input to output: */
+    for (;;) {
+        /* Fill the window as much as possible: */
+        if (s->lookahead <= 1) {
+
+            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+                   s->block_start >= (long)s->w_size, "slide too late");
+
+            fill_window(s);
+            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+        Assert(s->block_start >= 0L, "block gone");
+
+        s->strstart += s->lookahead;
+        s->lookahead = 0;
+
+        /* Emit a stored block if pending_buf will be full: */
+        max_start = s->block_start + max_block_size;
+        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+            /* strstart == 0 is possible when wraparound on 16-bit machine */
+            s->lookahead = (uInt)(s->strstart - max_start);
+            s->strstart = (uInt)max_start;
+            FLUSH_BLOCK(s, 0);
+        }
+        /* Flush if we may have to slide, otherwise block_start may become
+         * negative and the data will be gone:
+         */
+        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+            FLUSH_BLOCK(s, 0);
+        }
+    }
+    s->insert = 0;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if ((long)s->strstart > s->block_start)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head;       /* head of the hash chain */
+    int bflush;           /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        hash_head = NIL;
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         * At this point we have always match_length < MIN_MATCH
+         */
+        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            s->match_length = longest_match (s, hash_head);
+            /* longest_match() sets match_start */
+        }
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->match_start, s->match_length);
+
+            _tr_tally_dist(s, s->strstart - s->match_start,
+                           s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+
+            /* Insert new strings in the hash table only if the match length
+             * is not too large. This saves time but degrades compression.
+             */
+#ifndef FASTEST
+            if (s->match_length <= s->max_insert_length &&
+                s->lookahead >= MIN_MATCH) {
+                s->match_length--; /* string at strstart already in table */
+                do {
+                    s->strstart++;
+                    INSERT_STRING(s, s->strstart, hash_head);
+                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                     * always MIN_MATCH bytes ahead.
+                     */
+                } while (--s->match_length != 0);
+                s->strstart++;
+            } else
+#endif
+            {
+                s->strstart += s->match_length;
+                s->match_length = 0;
+                s->ins_h = s->window[s->strstart];
+                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+                Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+                 * matter since it will be recomputed at next deflate call.
+                 */
+            }
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head;          /* head of hash chain */
+    int bflush;              /* set if current block must be flushed */
+
+    /* Process the input block. */
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        hash_head = NIL;
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         */
+        s->prev_length = s->match_length, s->prev_match = s->match_start;
+        s->match_length = MIN_MATCH-1;
+
+        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+            s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            s->match_length = longest_match (s, hash_head);
+            /* longest_match() sets match_start */
+
+            if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+                || (s->match_length == MIN_MATCH &&
+                    s->strstart - s->match_start > TOO_FAR)
+#endif
+                )) {
+
+                /* If prev_match is also MIN_MATCH, match_start is garbage
+                 * but we will ignore the current match anyway.
+                 */
+                s->match_length = MIN_MATCH-1;
+            }
+        }
+        /* If there was a match at the previous step and the current
+         * match is not better, output the previous match:
+         */
+        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+            /* Do not insert strings in hash table beyond this. */
+
+            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+                           s->prev_length - MIN_MATCH, bflush);
+
+            /* Insert in hash table all strings up to the end of the match.
+             * strstart-1 and strstart are already inserted. If there is not
+             * enough lookahead, the last two strings are not inserted in
+             * the hash table.
+             */
+            s->lookahead -= s->prev_length-1;
+            s->prev_length -= 2;
+            do {
+                if (++s->strstart <= max_insert) {
+                    INSERT_STRING(s, s->strstart, hash_head);
+                }
+            } while (--s->prev_length != 0);
+            s->match_available = 0;
+            s->match_length = MIN_MATCH-1;
+            s->strstart++;
+
+            if (bflush) FLUSH_BLOCK(s, 0);
+
+        } else if (s->match_available) {
+            /* If there was no match at the previous position, output a
+             * single literal. If there was a match but the current match
+             * is longer, truncate the previous match to a single literal.
+             */
+            Tracevv((stderr,"%c", s->window[s->strstart-1]));
+            _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+            if (bflush) {
+                FLUSH_BLOCK_ONLY(s, 0);
+            }
+            s->strstart++;
+            s->lookahead--;
+            if (s->strm->avail_out == 0) return need_more;
+        } else {
+            /* There is no previous match to compare with, wait for
+             * the next step to decide.
+             */
+            s->match_available = 1;
+            s->strstart++;
+            s->lookahead--;
+        }
+    }
+    Assert (flush != Z_NO_FLUSH, "no flush?");
+    if (s->match_available) {
+        Tracevv((stderr,"%c", s->window[s->strstart-1]));
+        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+        s->match_available = 0;
+    }
+    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
+#endif /* FASTEST */
+
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one.  Do not maintain a hash table.  (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+local block_state deflate_rle(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    int bflush;             /* set if current block must be flushed */
+    uInt prev;              /* byte at distance one to match */
+    Bytef *scan, *strend;   /* scan goes up to strend for length of run */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the longest run, plus one for the unrolled loop.
+         */
+        if (s->lookahead <= MAX_MATCH) {
+            fill_window(s);
+            if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* See how many times the previous byte repeats */
+        s->match_length = 0;
+        if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
+            scan = s->window + s->strstart - 1;
+            prev = *scan;
+            if (prev == *++scan && prev == *++scan && prev == *++scan) {
+                strend = s->window + s->strstart + MAX_MATCH;
+                do {
+                } while (prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         scan < strend);
+                s->match_length = MAX_MATCH - (int)(strend - scan);
+                if (s->match_length > s->lookahead)
+                    s->match_length = s->lookahead;
+            }
+            Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
+        }
+
+        /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->strstart - 1, s->match_length);
+
+            _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+            s->strstart += s->match_length;
+            s->match_length = 0;
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    s->insert = 0;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
+
+/* ===========================================================================
+ * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
+ * (It will be regenerated if this run of deflate switches away from Huffman.)
+ */
+local block_state deflate_huff(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    int bflush;             /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we have a literal to write. */
+        if (s->lookahead == 0) {
+            fill_window(s);
+            if (s->lookahead == 0) {
+                if (flush == Z_NO_FLUSH)
+                    return need_more;
+                break;      /* flush the current block */
+            }
+        }
+
+        /* Output a literal byte */
+        s->match_length = 0;
+        Tracevv((stderr,"%c", s->window[s->strstart]));
+        _tr_tally_lit (s, s->window[s->strstart], bflush);
+        s->lookahead--;
+        s->strstart++;
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    s->insert = 0;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/deflate.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/deflate.h
new file mode 100755
index 0000000..a17c836
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/deflate.h
@@ -0,0 +1,346 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2012 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer creation by deflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip encoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS  256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES   30
+/* number of distance codes */
+
+#define BL_CODES  19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define Buf_size 16
+/* size of bit buffer in bi_buf */
+
+#define INIT_STATE    42
+#define EXTRA_STATE   69
+#define NAME_STATE    73
+#define COMMENT_STATE 91
+#define HCRC_STATE   103
+#define BUSY_STATE   113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+    union {
+        ush  freq;       /* frequency count */
+        ush  code;       /* bit string */
+    } fc;
+    union {
+        ush  dad;        /* father node in Huffman tree */
+        ush  len;        /* length of bit string */
+    } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad  dl.dad
+#define Len  dl.len
+
+typedef struct static_tree_desc_s  static_tree_desc;
+
+typedef struct tree_desc_s {
+    ct_data *dyn_tree;           /* the dynamic tree */
+    int     max_code;            /* largest code with non zero frequency */
+    static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+    z_streamp strm;      /* pointer back to this zlib stream */
+    int   status;        /* as the name implies */
+    Bytef *pending_buf;  /* output still pending */
+    ulg   pending_buf_size; /* size of pending_buf */
+    Bytef *pending_out;  /* next pending byte to output to the stream */
+    uInt   pending;      /* nb of bytes in the pending buffer */
+    int   wrap;          /* bit 0 true for zlib, bit 1 true for gzip */
+    gz_headerp  gzhead;  /* gzip header information to write */
+    uInt   gzindex;      /* where in extra, name, or comment */
+    Byte  method;        /* can only be DEFLATED */
+    int   last_flush;    /* value of flush param for previous deflate call */
+
+                /* used by deflate.c: */
+
+    uInt  w_size;        /* LZ77 window size (32K by default) */
+    uInt  w_bits;        /* log2(w_size)  (8..16) */
+    uInt  w_mask;        /* w_size - 1 */
+
+    Bytef *window;
+    /* Sliding window. Input bytes are read into the second half of the window,
+     * and move to the first half later to keep a dictionary of at least wSize
+     * bytes. With this organization, matches are limited to a distance of
+     * wSize-MAX_MATCH bytes, but this ensures that IO is always
+     * performed with a length multiple of the block size. Also, it limits
+     * the window size to 64K, which is quite useful on MSDOS.
+     * To do: use the user input buffer as sliding window.
+     */
+
+    ulg window_size;
+    /* Actual size of window: 2*wSize, except when the user input buffer
+     * is directly used as sliding window.
+     */
+
+    Posf *prev;
+    /* Link to older string with same hash index. To limit the size of this
+     * array to 64K, this link is maintained only for the last 32K strings.
+     * An index in this array is thus a window index modulo 32K.
+     */
+
+    Posf *head; /* Heads of the hash chains or NIL. */
+
+    uInt  ins_h;          /* hash index of string to be inserted */
+    uInt  hash_size;      /* number of elements in hash table */
+    uInt  hash_bits;      /* log2(hash_size) */
+    uInt  hash_mask;      /* hash_size-1 */
+
+    uInt  hash_shift;
+    /* Number of bits by which ins_h must be shifted at each input
+     * step. It must be such that after MIN_MATCH steps, the oldest
+     * byte no longer takes part in the hash key, that is:
+     *   hash_shift * MIN_MATCH >= hash_bits
+     */
+
+    long block_start;
+    /* Window position at the beginning of the current output block. Gets
+     * negative when the window is moved backwards.
+     */
+
+    uInt match_length;           /* length of best match */
+    IPos prev_match;             /* previous match */
+    int match_available;         /* set if previous match exists */
+    uInt strstart;               /* start of string to insert */
+    uInt match_start;            /* start of matching string */
+    uInt lookahead;              /* number of valid bytes ahead in window */
+
+    uInt prev_length;
+    /* Length of the best match at previous step. Matches not greater than this
+     * are discarded. This is used in the lazy match evaluation.
+     */
+
+    uInt max_chain_length;
+    /* To speed up deflation, hash chains are never searched beyond this
+     * length.  A higher limit improves compression ratio but degrades the
+     * speed.
+     */
+
+    uInt max_lazy_match;
+    /* Attempt to find a better match only when the current match is strictly
+     * smaller than this value. This mechanism is used only for compression
+     * levels >= 4.
+     */
+#   define max_insert_length  max_lazy_match
+    /* Insert new strings in the hash table only if the match length is not
+     * greater than this length. This saves time but degrades compression.
+     * max_insert_length is used only for compression levels <= 3.
+     */
+
+    int level;    /* compression level (1..9) */
+    int strategy; /* favor or force Huffman coding*/
+
+    uInt good_match;
+    /* Use a faster search when the previous match is longer than this */
+
+    int nice_match; /* Stop searching when current match exceeds this */
+
+                /* used by trees.c: */
+    /* Didn't use ct_data typedef below to suppress compiler warning */
+    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
+    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
+
+    struct tree_desc_s l_desc;               /* desc. for literal tree */
+    struct tree_desc_s d_desc;               /* desc. for distance tree */
+    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
+
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
+    int heap_len;               /* number of elements in the heap */
+    int heap_max;               /* element of largest frequency */
+    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+     * The same heap array is used to build all trees.
+     */
+
+    uch depth[2*L_CODES+1];
+    /* Depth of each subtree used as tie breaker for trees of equal frequency
+     */
+
+    uchf *l_buf;          /* buffer for literals or lengths */
+
+    uInt  lit_bufsize;
+    /* Size of match buffer for literals/lengths.  There are 4 reasons for
+     * limiting lit_bufsize to 64K:
+     *   - frequencies can be kept in 16 bit counters
+     *   - if compression is not successful for the first block, all input
+     *     data is still in the window so we can still emit a stored block even
+     *     when input comes from standard input.  (This can also be done for
+     *     all blocks if lit_bufsize is not greater than 32K.)
+     *   - if compression is not successful for a file smaller than 64K, we can
+     *     even emit a stored file instead of a stored block (saving 5 bytes).
+     *     This is applicable only for zip (not gzip or zlib).
+     *   - creating new Huffman trees less frequently may not provide fast
+     *     adaptation to changes in the input data statistics. (Take for
+     *     example a binary file with poorly compressible code followed by
+     *     a highly compressible string table.) Smaller buffer sizes give
+     *     fast adaptation but have of course the overhead of transmitting
+     *     trees more frequently.
+     *   - I can't count above 4
+     */
+
+    uInt last_lit;      /* running index in l_buf */
+
+    ushf *d_buf;
+    /* Buffer for distances. To simplify the code, d_buf and l_buf have
+     * the same number of elements. To use different lengths, an extra flag
+     * array would be necessary.
+     */
+
+    ulg opt_len;        /* bit length of current block with optimal trees */
+    ulg static_len;     /* bit length of current block with static trees */
+    uInt matches;       /* number of string matches in current block */
+    uInt insert;        /* bytes at end of window left to insert */
+
+#ifdef DEBUG
+    ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */
+#endif
+
+    ush bi_buf;
+    /* Output buffer. bits are inserted starting at the bottom (least
+     * significant bits).
+     */
+    int bi_valid;
+    /* Number of valid bits in bi_buf.  All bits above the last valid bit
+     * are always zero.
+     */
+
+    ulg high_water;
+    /* High water mark offset in window for initialized bytes -- bytes above
+     * this are set to zero in order to avoid memory check warnings when
+     * longest match routines access bytes past the input.  This is then
+     * updated to the new high water mark.
+     */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+#define WIN_INIT MAX_MATCH
+/* Number of bytes after end of data in window to initialize in order to avoid
+   memory checker errors from longest match routines */
+
+        /* in trees.c */
+void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
+int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
+                        ulg stored_len, int last));
+void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
+                        ulg stored_len, int last));
+
+#define d_code(dist) \
+   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+  extern uch ZLIB_INTERNAL _length_code[];
+  extern uch ZLIB_INTERNAL _dist_code[];
+#else
+  extern const uch ZLIB_INTERNAL _length_code[];
+  extern const uch ZLIB_INTERNAL _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+  { uch cc = (uch)(c); \
+    s->d_buf[s->last_lit] = 0; \
+    s->l_buf[s->last_lit++] = cc; \
+    s->dyn_ltree[cc].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+   }
+# define _tr_tally_dist(s, distance, length, flush) \
+  { uch len = (uch)(length); \
+    ush dist = (ush)(distance); \
+    s->d_buf[s->last_lit] = dist; \
+    s->l_buf[s->last_lit++] = len; \
+    dist--; \
+    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+    s->dyn_dtree[d_code(dist)].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+  }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+              flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/infback.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/infback.c
new file mode 100755
index 0000000..f3833c2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/infback.c
@@ -0,0 +1,640 @@
+/* infback.c -- inflate using a call-back interface
+ * Copyright (C) 1995-2011 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+   This code is largely copied from inflate.c.  Normally either infback.o or
+   inflate.o would be linked into an application--not both.  The interface
+   with inffast.c is retained so that optimized assembler-coded versions of
+   inflate_fast() can be used with either inflate.c or infback.c.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+
+/*
+   strm provides memory allocation functions in zalloc and zfree, or
+   Z_NULL to use the library memory allocation functions.
+
+   windowBits is in the range 8..15, and window is a user-supplied
+   window and output buffer that is 2**windowBits bytes.
+ */
+int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
+z_streamp strm;
+int windowBits;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+{
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL || window == Z_NULL ||
+        windowBits < 8 || windowBits > 15)
+        return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+#endif
+    }
+    if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+    strm->zfree = zcfree;
+#endif
+    state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+                                               sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (struct internal_state FAR *)state;
+    state->dmax = 32768U;
+    state->wbits = windowBits;
+    state->wsize = 1U << windowBits;
+    state->window = window;
+    state->wnext = 0;
+    state->whave = 0;
+    return Z_OK;
+}
+
+/*
+   Return state with length and distance decoding tables and index sizes set to
+   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
+   If BUILDFIXED is defined, then instead this routine builds the tables the
+   first time it's called, and returns those tables the first time and
+   thereafter.  This reduces the size of the code by about 2K bytes, in
+   exchange for a little execution time.  However, BUILDFIXED should not be
+   used for threaded applications, since the rewriting of the tables and virgin
+   may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+    static int virgin = 1;
+    static code *lenfix, *distfix;
+    static code fixed[544];
+
+    /* build fixed huffman tables if first call (may not be thread safe) */
+    if (virgin) {
+        unsigned sym, bits;
+        static code *next;
+
+        /* literal/length table */
+        sym = 0;
+        while (sym < 144) state->lens[sym++] = 8;
+        while (sym < 256) state->lens[sym++] = 9;
+        while (sym < 280) state->lens[sym++] = 7;
+        while (sym < 288) state->lens[sym++] = 8;
+        next = fixed;
+        lenfix = next;
+        bits = 9;
+        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+        /* distance table */
+        sym = 0;
+        while (sym < 32) state->lens[sym++] = 5;
+        distfix = next;
+        bits = 5;
+        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+        /* do this just once */
+        virgin = 0;
+    }
+#else /* !BUILDFIXED */
+#   include "inffixed.h"
+#endif /* BUILDFIXED */
+    state->lencode = lenfix;
+    state->lenbits = 9;
+    state->distcode = distfix;
+    state->distbits = 5;
+}
+
+/* Macros for inflateBack(): */
+
+/* Load returned state from inflate_fast() */
+#define LOAD() \
+    do { \
+        put = strm->next_out; \
+        left = strm->avail_out; \
+        next = strm->next_in; \
+        have = strm->avail_in; \
+        hold = state->hold; \
+        bits = state->bits; \
+    } while (0)
+
+/* Set state from registers for inflate_fast() */
+#define RESTORE() \
+    do { \
+        strm->next_out = put; \
+        strm->avail_out = left; \
+        strm->next_in = next; \
+        strm->avail_in = have; \
+        state->hold = hold; \
+        state->bits = bits; \
+    } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Assure that some input is available.  If input is requested, but denied,
+   then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+    do { \
+        if (have == 0) { \
+            have = in(in_desc, &next); \
+            if (have == 0) { \
+                next = Z_NULL; \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+   with an error if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        PULL(); \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflateBack() with
+   an error. */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/* Assure that some output space is available, by writing out the window
+   if it's full.  If the write fails, return from inflateBack() with a
+   Z_BUF_ERROR. */
+#define ROOM() \
+    do { \
+        if (left == 0) { \
+            put = state->window; \
+            left = state->wsize; \
+            state->whave = left; \
+            if (out(out_desc, put, left)) { \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/*
+   strm provides the memory allocation functions and window buffer on input,
+   and provides information on the unused input on return.  For Z_DATA_ERROR
+   returns, strm will also provide an error message.
+
+   in() and out() are the call-back input and output functions.  When
+   inflateBack() needs more input, it calls in().  When inflateBack() has
+   filled the window with output, or when it completes with data in the
+   window, it calls out() to write out the data.  The application must not
+   change the provided input until in() is called again or inflateBack()
+   returns.  The application must not change the window/output buffer until
+   inflateBack() returns.
+
+   in() and out() are called with a descriptor parameter provided in the
+   inflateBack() call.  This parameter can be a structure that provides the
+   information required to do the read or write, as well as accumulated
+   information on the input and output such as totals and check values.
+
+   in() should return zero on failure.  out() should return non-zero on
+   failure.  If either in() or out() fails, than inflateBack() returns a
+   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
+   was in() or out() that caused in the error.  Otherwise,  inflateBack()
+   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+   error, or Z_MEM_ERROR if it could not allocate memory for the state.
+   inflateBack() can also return Z_STREAM_ERROR if the input parameters
+   are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
+z_streamp strm;
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+{
+    struct inflate_state FAR *state;
+    z_const unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have, left;        /* available input and output */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned copy;              /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code here;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    /* Check that the strm exists and that the state was initialized */
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* Reset the state */
+    strm->msg = Z_NULL;
+    state->mode = TYPE;
+    state->last = 0;
+    state->whave = 0;
+    next = strm->next_in;
+    have = next != Z_NULL ? strm->avail_in : 0;
+    hold = 0;
+    bits = 0;
+    put = state->window;
+    left = state->wsize;
+
+    /* Inflate until end of block marked as last */
+    for (;;)
+        switch (state->mode) {
+        case TYPE:
+            /* determine and dispatch block type */
+            if (state->last) {
+                BYTEBITS();
+                state->mode = DONE;
+                break;
+            }
+            NEEDBITS(3);
+            state->last = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                fixedtables(state);
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = LEN;              /* decode codes */
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                state->mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+
+        case STORED:
+            /* get and verify stored block length */
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                state->mode = BAD;
+                break;
+            }
+            state->length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %u\n",
+                    state->length));
+            INITBITS();
+
+            /* copy stored block from input to output */
+            while (state->length != 0) {
+                copy = state->length;
+                PULL();
+                ROOM();
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                state->length -= copy;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            state->mode = TYPE;
+            break;
+
+        case TABLE:
+            /* get dynamic table entries descriptor */
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+            if (state->nlen > 286 || state->ndist > 30) {
+                strm->msg = (char *)"too many length or distance symbols";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+
+            /* get code length code lengths (not a typo) */
+            state->have = 0;
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 7;
+            ret = inflate_table(CODES, state->lens, 19, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+
+            /* get length and distance code code lengths */
+            state->have = 0;
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    here = state->lencode[BITS(state->lenbits)];
+                    if ((unsigned)(here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (here.val < 16) {
+                    DROPBITS(here.bits);
+                    state->lens[state->have++] = here.val;
+                }
+                else {
+                    if (here.val == 16) {
+                        NEEDBITS(here.bits + 2);
+                        DROPBITS(here.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            state->mode = BAD;
+                            break;
+                        }
+                        len = (unsigned)(state->lens[state->have - 1]);
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (here.val == 17) {
+                        NEEDBITS(here.bits + 3);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(here.bits + 7);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        state->mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* handle error breaks in while */
+            if (state->mode == BAD) break;
+
+            /* check for end-of-block code (better have one) */
+            if (state->lens[256] == 0) {
+                strm->msg = (char *)"invalid code -- missing end-of-block";
+                state->mode = BAD;
+                break;
+            }
+
+            /* build code tables -- note: do not change the lenbits or distbits
+               values here (9 and 6) without reading the comments in inftrees.h
+               concerning the ENOUGH constants, which depend on those values */
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 9;
+            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                state->mode = BAD;
+                break;
+            }
+            state->distcode = (code const FAR *)(state->next);
+            state->distbits = 6;
+            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+                            &(state->next), &(state->distbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            state->mode = LEN;
+
+        case LEN:
+            /* use inflate_fast() if we have enough input and output */
+            if (have >= 6 && left >= 258) {
+                RESTORE();
+                if (state->whave < state->wsize)
+                    state->whave = state->wsize - left;
+                inflate_fast(strm, state->wsize);
+                LOAD();
+                break;
+            }
+
+            /* get a literal, length, or end-of-block code */
+            for (;;) {
+                here = state->lencode[BITS(state->lenbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (here.op && (here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(here.bits);
+            state->length = (unsigned)here.val;
+
+            /* process literal */
+            if (here.op == 0) {
+                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", here.val));
+                ROOM();
+                *put++ = (unsigned char)(state->length);
+                left--;
+                state->mode = LEN;
+                break;
+            }
+
+            /* process end of block */
+            if (here.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                state->mode = TYPE;
+                break;
+            }
+
+            /* invalid code */
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                state->mode = BAD;
+                break;
+            }
+
+            /* length code -- get extra bits, if any */
+            state->extra = (unsigned)(here.op) & 15;
+            if (state->extra != 0) {
+                NEEDBITS(state->extra);
+                state->length += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            Tracevv((stderr, "inflate:         length %u\n", state->length));
+
+            /* get distance code */
+            for (;;) {
+                here = state->distcode[BITS(state->distbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(here.bits);
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+            state->offset = (unsigned)here.val;
+
+            /* get distance extra bits, if any */
+            state->extra = (unsigned)(here.op) & 15;
+            if (state->extra != 0) {
+                NEEDBITS(state->extra);
+                state->offset += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            if (state->offset > state->wsize - (state->whave < state->wsize ?
+                                                left : 0)) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
+
+            /* copy match from window to output */
+            do {
+                ROOM();
+                copy = state->wsize - state->offset;
+                if (copy < left) {
+                    from = put + copy;
+                    copy = left - copy;
+                }
+                else {
+                    from = put - state->offset;
+                    copy = left;
+                }
+                if (copy > state->length) copy = state->length;
+                state->length -= copy;
+                left -= copy;
+                do {
+                    *put++ = *from++;
+                } while (--copy);
+            } while (state->length != 0);
+            break;
+
+        case DONE:
+            /* inflate stream terminated properly -- write leftover output */
+            ret = Z_STREAM_END;
+            if (left < state->wsize) {
+                if (out(out_desc, state->window, state->wsize - left))
+                    ret = Z_BUF_ERROR;
+            }
+            goto inf_leave;
+
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+
+        default:                /* can't happen, but makes compilers happy */
+            ret = Z_STREAM_ERROR;
+            goto inf_leave;
+        }
+
+    /* Return unused input */
+  inf_leave:
+    strm->next_in = next;
+    strm->avail_in = have;
+    return ret;
+}
+
+int ZEXPORT inflateBackEnd(strm)
+z_streamp strm;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inffast.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inffast.c
new file mode 100755
index 0000000..bda59ce
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inffast.c
@@ -0,0 +1,340 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2008, 2010, 2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifndef ASMINF
+
+/* Allow machine dependent optimization for post-increment or pre-increment.
+   Based on testing to date,
+   Pre-increment preferred for:
+   - PowerPC G3 (Adler)
+   - MIPS R5000 (Randers-Pehrson)
+   Post-increment preferred for:
+   - none
+   No measurable difference:
+   - Pentium III (Anderson)
+   - M68060 (Nikl)
+ */
+#ifdef POSTINC
+#  define OFF 0
+#  define PUP(a) *(a)++
+#else
+#  define OFF 1
+#  define PUP(a) *++(a)
+#endif
+
+/*
+   Decode literal, length, and distance codes and write out the resulting
+   literal and match bytes until either not enough input or output is
+   available, an end-of-block is encountered, or a data error is encountered.
+   When large enough input and output buffers are supplied to inflate(), for
+   example, a 16K input buffer and a 64K output buffer, more than 95% of the
+   inflate execution time is spent in this routine.
+
+   Entry assumptions:
+
+        state->mode == LEN
+        strm->avail_in >= 6
+        strm->avail_out >= 258
+        start >= strm->avail_out
+        state->bits < 8
+
+   On return, state->mode is one of:
+
+        LEN -- ran out of enough output space or enough available input
+        TYPE -- reached end of block code, inflate() to interpret next block
+        BAD -- error in block data
+
+   Notes:
+
+    - The maximum input bits used by a length/distance pair is 15 bits for the
+      length code, 5 bits for the length extra, 15 bits for the distance code,
+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
+      Therefore if strm->avail_in >= 6, then there is enough input to avoid
+      checking for available input while decoding.
+
+    - The maximum bytes that a single length/distance pair can output is 258
+      bytes, which is the maximum length that can be coded.  inflate_fast()
+      requires strm->avail_out >= 258 for each loop to avoid checking for
+      output space.
+ */
+void ZLIB_INTERNAL inflate_fast(strm, start)
+z_streamp strm;
+unsigned start;         /* inflate()'s starting value for strm->avail_out */
+{
+    struct inflate_state FAR *state;
+    z_const unsigned char FAR *in;      /* local strm->next_in */
+    z_const unsigned char FAR *last;    /* have enough input while in < last */
+    unsigned char FAR *out;     /* local strm->next_out */
+    unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */
+    unsigned char FAR *end;     /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+    unsigned dmax;              /* maximum distance from zlib header */
+#endif
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned wnext;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */
+    unsigned long hold;         /* local strm->hold */
+    unsigned bits;              /* local strm->bits */
+    code const FAR *lcode;      /* local strm->lencode */
+    code const FAR *dcode;      /* local strm->distcode */
+    unsigned lmask;             /* mask for first level of length codes */
+    unsigned dmask;             /* mask for first level of distance codes */
+    code here;                  /* retrieved table entry */
+    unsigned op;                /* code bits, operation, extra bits, or */
+                                /*  window position, window bytes to copy */
+    unsigned len;               /* match length, unused bytes */
+    unsigned dist;              /* match distance */
+    unsigned char FAR *from;    /* where to copy match from */
+
+    /* copy state to local variables */
+    state = (struct inflate_state FAR *)strm->state;
+    in = strm->next_in - OFF;
+    last = in + (strm->avail_in - 5);
+    out = strm->next_out - OFF;
+    beg = out - (start - strm->avail_out);
+    end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+    dmax = state->dmax;
+#endif
+    wsize = state->wsize;
+    whave = state->whave;
+    wnext = state->wnext;
+    window = state->window;
+    hold = state->hold;
+    bits = state->bits;
+    lcode = state->lencode;
+    dcode = state->distcode;
+    lmask = (1U << state->lenbits) - 1;
+    dmask = (1U << state->distbits) - 1;
+
+    /* decode literals and length/distances until end-of-block or not enough
+       input data or output space */
+    do {
+        if (bits < 15) {
+            hold += (unsigned long)(PUP(in)) << bits;
+            bits += 8;
+            hold += (unsigned long)(PUP(in)) << bits;
+            bits += 8;
+        }
+        here = lcode[hold & lmask];
+      dolen:
+        op = (unsigned)(here.bits);
+        hold >>= op;
+        bits -= op;
+        op = (unsigned)(here.op);
+        if (op == 0) {                          /* literal */
+            Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                    "inflate:         literal '%c'\n" :
+                    "inflate:         literal 0x%02x\n", here.val));
+            PUP(out) = (unsigned char)(here.val);
+        }
+        else if (op & 16) {                     /* length base */
+            len = (unsigned)(here.val);
+            op &= 15;                           /* number of extra bits */
+            if (op) {
+                if (bits < op) {
+                    hold += (unsigned long)(PUP(in)) << bits;
+                    bits += 8;
+                }
+                len += (unsigned)hold & ((1U << op) - 1);
+                hold >>= op;
+                bits -= op;
+            }
+            Tracevv((stderr, "inflate:         length %u\n", len));
+            if (bits < 15) {
+                hold += (unsigned long)(PUP(in)) << bits;
+                bits += 8;
+                hold += (unsigned long)(PUP(in)) << bits;
+                bits += 8;
+            }
+            here = dcode[hold & dmask];
+          dodist:
+            op = (unsigned)(here.bits);
+            hold >>= op;
+            bits -= op;
+            op = (unsigned)(here.op);
+            if (op & 16) {                      /* distance base */
+                dist = (unsigned)(here.val);
+                op &= 15;                       /* number of extra bits */
+                if (bits < op) {
+                    hold += (unsigned long)(PUP(in)) << bits;
+                    bits += 8;
+                    if (bits < op) {
+                        hold += (unsigned long)(PUP(in)) << bits;
+                        bits += 8;
+                    }
+                }
+                dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+                if (dist > dmax) {
+                    strm->msg = (char *)"invalid distance too far back";
+                    state->mode = BAD;
+                    break;
+                }
+#endif
+                hold >>= op;
+                bits -= op;
+                Tracevv((stderr, "inflate:         distance %u\n", dist));
+                op = (unsigned)(out - beg);     /* max distance in output */
+                if (dist > op) {                /* see if copy from window */
+                    op = dist - op;             /* distance back in window */
+                    if (op > whave) {
+                        if (state->sane) {
+                            strm->msg =
+                                (char *)"invalid distance too far back";
+                            state->mode = BAD;
+                            break;
+                        }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+                        if (len <= op - whave) {
+                            do {
+                                PUP(out) = 0;
+                            } while (--len);
+                            continue;
+                        }
+                        len -= op - whave;
+                        do {
+                            PUP(out) = 0;
+                        } while (--op > whave);
+                        if (op == 0) {
+                            from = out - dist;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--len);
+                            continue;
+                        }
+#endif
+                    }
+                    from = window - OFF;
+                    if (wnext == 0) {           /* very common case */
+                        from += wsize - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    else if (wnext < op) {      /* wrap around window */
+                        from += wsize + wnext - op;
+                        op -= wnext;
+                        if (op < len) {         /* some from end of window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = window - OFF;
+                            if (wnext < len) {  /* some from start of window */
+                                op = wnext;
+                                len -= op;
+                                do {
+                                    PUP(out) = PUP(from);
+                                } while (--op);
+                                from = out - dist;      /* rest from output */
+                            }
+                        }
+                    }
+                    else {                      /* contiguous in window */
+                        from += wnext - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    while (len > 2) {
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        len -= 3;
+                    }
+                    if (len) {
+                        PUP(out) = PUP(from);
+                        if (len > 1)
+                            PUP(out) = PUP(from);
+                    }
+                }
+                else {
+                    from = out - dist;          /* copy direct from output */
+                    do {                        /* minimum length is three */
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        len -= 3;
+                    } while (len > 2);
+                    if (len) {
+                        PUP(out) = PUP(from);
+                        if (len > 1)
+                            PUP(out) = PUP(from);
+                    }
+                }
+            }
+            else if ((op & 64) == 0) {          /* 2nd level distance code */
+                here = dcode[here.val + (hold & ((1U << op) - 1))];
+                goto dodist;
+            }
+            else {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+        }
+        else if ((op & 64) == 0) {              /* 2nd level length code */
+            here = lcode[here.val + (hold & ((1U << op) - 1))];
+            goto dolen;
+        }
+        else if (op & 32) {                     /* end-of-block */
+            Tracevv((stderr, "inflate:         end of block\n"));
+            state->mode = TYPE;
+            break;
+        }
+        else {
+            strm->msg = (char *)"invalid literal/length code";
+            state->mode = BAD;
+            break;
+        }
+    } while (in < last && out < end);
+
+    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+    len = bits >> 3;
+    in -= len;
+    bits -= len << 3;
+    hold &= (1U << bits) - 1;
+
+    /* update state and return */
+    strm->next_in = in + OFF;
+    strm->next_out = out + OFF;
+    strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+    strm->avail_out = (unsigned)(out < end ?
+                                 257 + (end - out) : 257 - (out - end));
+    state->hold = hold;
+    state->bits = bits;
+    return;
+}
+
+/*
+   inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+   - Using bit fields for code structure
+   - Different op definition to avoid & for extra bits (do & for table bits)
+   - Three separate decoding do-loops for direct, window, and wnext == 0
+   - Special case for distance > 1 copies to do overlapped load and store copy
+   - Explicit branch predictions (based on measured branch probabilities)
+   - Deferring match copy and interspersed it with decoding subsequent codes
+   - Swapping literal/length else
+   - Swapping window/direct else
+   - Larger unrolled copy loops (three is about right)
+   - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inffast.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inffast.h
new file mode 100755
index 0000000..e5c1aa4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inffast.h
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inffixed.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inffixed.h
new file mode 100755
index 0000000..d628327
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inffixed.h
@@ -0,0 +1,94 @@
+    /* inffixed.h -- table for decoding fixed codes
+     * Generated automatically by makefixed().
+     */
+
+    /* WARNING: this file should *not* be used by applications.
+       It is part of the implementation of this library and is
+       subject to change. Applications should only use zlib.h.
+     */
+
+    static const code lenfix[512] = {
+        {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+        {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+        {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+        {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+        {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+        {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+        {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+        {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+        {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+        {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+        {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+        {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+        {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+        {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+        {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+        {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+        {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+        {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+        {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+        {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+        {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+        {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+        {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+        {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+        {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+        {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+        {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+        {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+        {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+        {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+        {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+        {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+        {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+        {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+        {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+        {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+        {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+        {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+        {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+        {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+        {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+        {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+        {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+        {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+        {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+        {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+        {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+        {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+        {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+        {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+        {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+        {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+        {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+        {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+        {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+        {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+        {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+        {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+        {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+        {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+        {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+        {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+        {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+        {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+        {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+        {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+        {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+        {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+        {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+        {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+        {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+        {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+        {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+        {0,9,255}
+    };
+
+    static const code distfix[32] = {
+        {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+        {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+        {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+        {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+        {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+        {22,5,193},{64,5,0}
+    };
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inflate.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inflate.c
new file mode 100755
index 0000000..870f89b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inflate.c
@@ -0,0 +1,1512 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2012 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0    24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ *   creation of window when not needed, minimize use of window when it is
+ *   needed, make inffast.c even faster, implement gzip decoding, and to
+ *   improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1    25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2    4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ *   to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3    22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ *   buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4    1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common wnext == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ *   source file infback.c to provide a call-back interface to inflate for
+ *   programs like gzip and unzip -- uses window as output buffer to avoid
+ *   window copying
+ *
+ * 1.2.beta5    1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ *   input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6    4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ *   make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7    27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0        9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ *   for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ *   and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+#  ifndef BUILDFIXED
+#    define BUILDFIXED
+#  endif
+#endif
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
+                           unsigned copy));
+#ifdef BUILDFIXED
+   void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
+                              unsigned len));
+
+int ZEXPORT inflateResetKeep(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    strm->total_in = strm->total_out = state->total = 0;
+    strm->msg = Z_NULL;
+    if (state->wrap)        /* to support ill-conceived Java test suite */
+        strm->adler = state->wrap & 1;
+    state->mode = HEAD;
+    state->last = 0;
+    state->havedict = 0;
+    state->dmax = 32768U;
+    state->head = Z_NULL;
+    state->hold = 0;
+    state->bits = 0;
+    state->lencode = state->distcode = state->next = state->codes;
+    state->sane = 1;
+    state->back = -1;
+    Tracev((stderr, "inflate: reset\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    state->wsize = 0;
+    state->whave = 0;
+    state->wnext = 0;
+    return inflateResetKeep(strm);
+}
+
+int ZEXPORT inflateReset2(strm, windowBits)
+z_streamp strm;
+int windowBits;
+{
+    int wrap;
+    struct inflate_state FAR *state;
+
+    /* get the state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* extract wrap request from windowBits parameter */
+    if (windowBits < 0) {
+        wrap = 0;
+        windowBits = -windowBits;
+    }
+    else {
+        wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+        if (windowBits < 48)
+            windowBits &= 15;
+#endif
+    }
+
+    /* set number of window bits, free window if different */
+    if (windowBits && (windowBits < 8 || windowBits > 15))
+        return Z_STREAM_ERROR;
+    if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
+        ZFREE(strm, state->window);
+        state->window = Z_NULL;
+    }
+
+    /* update state and reset the rest of it */
+    state->wrap = wrap;
+    state->wbits = (unsigned)windowBits;
+    return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+    int ret;
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+#endif
+    }
+    if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zfree = zcfree;
+#endif
+    state = (struct inflate_state FAR *)
+            ZALLOC(strm, 1, sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (struct internal_state FAR *)state;
+    state->window = Z_NULL;
+    ret = inflateReset2(strm, windowBits);
+    if (ret != Z_OK) {
+        ZFREE(strm, state);
+        strm->state = Z_NULL;
+    }
+    return ret;
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (bits < 0) {
+        state->hold = 0;
+        state->bits = 0;
+        return Z_OK;
+    }
+    if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
+    value &= (1L << bits) - 1;
+    state->hold += value << state->bits;
+    state->bits += bits;
+    return Z_OK;
+}
+
+/*
+   Return state with length and distance decoding tables and index sizes set to
+   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
+   If BUILDFIXED is defined, then instead this routine builds the tables the
+   first time it's called, and returns those tables the first time and
+   thereafter.  This reduces the size of the code by about 2K bytes, in
+   exchange for a little execution time.  However, BUILDFIXED should not be
+   used for threaded applications, since the rewriting of the tables and virgin
+   may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+    static int virgin = 1;
+    static code *lenfix, *distfix;
+    static code fixed[544];
+
+    /* build fixed huffman tables if first call (may not be thread safe) */
+    if (virgin) {
+        unsigned sym, bits;
+        static code *next;
+
+        /* literal/length table */
+        sym = 0;
+        while (sym < 144) state->lens[sym++] = 8;
+        while (sym < 256) state->lens[sym++] = 9;
+        while (sym < 280) state->lens[sym++] = 7;
+        while (sym < 288) state->lens[sym++] = 8;
+        next = fixed;
+        lenfix = next;
+        bits = 9;
+        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+        /* distance table */
+        sym = 0;
+        while (sym < 32) state->lens[sym++] = 5;
+        distfix = next;
+        bits = 5;
+        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+        /* do this just once */
+        virgin = 0;
+    }
+#else /* !BUILDFIXED */
+#   include "inffixed.h"
+#endif /* BUILDFIXED */
+    state->lencode = lenfix;
+    state->lenbits = 9;
+    state->distcode = distfix;
+    state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+   Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
+   defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
+   those tables to stdout, which would be piped to inffixed.h.  A small program
+   can simply call makefixed to do this:
+
+    void makefixed(void);
+
+    int main(void)
+    {
+        makefixed();
+        return 0;
+    }
+
+   Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+    a.out > inffixed.h
+ */
+void makefixed()
+{
+    unsigned low, size;
+    struct inflate_state state;
+
+    fixedtables(&state);
+    puts("    /* inffixed.h -- table for decoding fixed codes");
+    puts("     * Generated automatically by makefixed().");
+    puts("     */");
+    puts("");
+    puts("    /* WARNING: this file should *not* be used by applications.");
+    puts("       It is part of the implementation of this library and is");
+    puts("       subject to change. Applications should only use zlib.h.");
+    puts("     */");
+    puts("");
+    size = 1U << 9;
+    printf("    static const code lenfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 7) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
+               state.lencode[low].bits, state.lencode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+    size = 1U << 5;
+    printf("\n    static const code distfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 6) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+               state.distcode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+}
+#endif /* MAKEFIXED */
+
+/*
+   Update the window with the last wsize (normally 32K) bytes written before
+   returning.  If window does not exist yet, create it.  This is only called
+   when a window is already in use, or when output has been written during this
+   inflate call, but the end of the deflate stream has not been reached yet.
+   It is also called to create a window for dictionary data when a dictionary
+   is loaded.
+
+   Providing output buffers larger than 32K to inflate() should provide a speed
+   advantage, since only the last 32K of output is copied to the sliding window
+   upon return from inflate(), and since all distances after the first 32K of
+   output will fall in the output data, making match copies simpler and faster.
+   The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, end, copy)
+z_streamp strm;
+const Bytef *end;
+unsigned copy;
+{
+    struct inflate_state FAR *state;
+    unsigned dist;
+
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* if it hasn't been done already, allocate space for the window */
+    if (state->window == Z_NULL) {
+        state->window = (unsigned char FAR *)
+                        ZALLOC(strm, 1U << state->wbits,
+                               sizeof(unsigned char));
+        if (state->window == Z_NULL) return 1;
+    }
+
+    /* if window not in use yet, initialize */
+    if (state->wsize == 0) {
+        state->wsize = 1U << state->wbits;
+        state->wnext = 0;
+        state->whave = 0;
+    }
+
+    /* copy state->wsize or less output bytes into the circular window */
+    if (copy >= state->wsize) {
+        zmemcpy(state->window, end - state->wsize, state->wsize);
+        state->wnext = 0;
+        state->whave = state->wsize;
+    }
+    else {
+        dist = state->wsize - state->wnext;
+        if (dist > copy) dist = copy;
+        zmemcpy(state->window + state->wnext, end - copy, dist);
+        copy -= dist;
+        if (copy) {
+            zmemcpy(state->window, end - copy, copy);
+            state->wnext = copy;
+            state->whave = state->wsize;
+        }
+        else {
+            state->wnext += dist;
+            if (state->wnext == state->wsize) state->wnext = 0;
+            if (state->whave < state->wsize) state->whave += dist;
+        }
+    }
+    return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+#  define UPDATE(check, buf, len) \
+    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+#  define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+#  define CRC2(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        check = crc32(check, hbuf, 2); \
+    } while (0)
+
+#  define CRC4(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        hbuf[2] = (unsigned char)((word) >> 16); \
+        hbuf[3] = (unsigned char)((word) >> 24); \
+        check = crc32(check, hbuf, 4); \
+    } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+    do { \
+        put = strm->next_out; \
+        left = strm->avail_out; \
+        next = strm->next_in; \
+        have = strm->avail_in; \
+        hold = state->hold; \
+        bits = state->bits; \
+    } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+    do { \
+        strm->next_out = put; \
+        strm->avail_out = left; \
+        strm->next_in = next; \
+        strm->avail_in = have; \
+        state->hold = hold; \
+        state->bits = bits; \
+    } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+   if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        if (have == 0) goto inf_leave; \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/*
+   inflate() uses a state machine to process as much input data and generate as
+   much output data as possible before returning.  The state machine is
+   structured roughly as follows:
+
+    for (;;) switch (state) {
+    ...
+    case STATEn:
+        if (not enough input data or output space to make progress)
+            return;
+        ... make progress ...
+        state = STATEm;
+        break;
+    ...
+    }
+
+   so when inflate() is called again, the same case is attempted again, and
+   if the appropriate resources are provided, the machine proceeds to the
+   next state.  The NEEDBITS() macro is usually the way the state evaluates
+   whether it can proceed or should return.  NEEDBITS() does the return if
+   the requested bits are not available.  The typical use of the BITS macros
+   is:
+
+        NEEDBITS(n);
+        ... do something with BITS(n) ...
+        DROPBITS(n);
+
+   where NEEDBITS(n) either returns from inflate() if there isn't enough
+   input left to load n bits into the accumulator, or it continues.  BITS(n)
+   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
+   the low n bits off the accumulator.  INITBITS() clears the accumulator
+   and sets the number of available bits to zero.  BYTEBITS() discards just
+   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
+   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+   if there is no input available.  The decoding of variable length codes uses
+   PULLBYTE() directly in order to pull just enough bytes to decode the next
+   code, and no more.
+
+   Some states loop until they get enough input, making sure that enough
+   state information is maintained to continue the loop where it left off
+   if NEEDBITS() returns in the loop.  For example, want, need, and keep
+   would all have to actually be part of the saved state in case NEEDBITS()
+   returns:
+
+    case STATEw:
+        while (want < need) {
+            NEEDBITS(n);
+            keep[want++] = BITS(n);
+            DROPBITS(n);
+        }
+        state = STATEx;
+    case STATEx:
+
+   As shown above, if the next state is also the next case, then the break
+   is omitted.
+
+   A state may also return if there is not enough output space available to
+   complete that state.  Those states are copying stored data, writing a
+   literal byte, and copying a matching string.
+
+   When returning, a "goto inf_leave" is used to update the total counters,
+   update the check value, and determine whether any progress has been made
+   during that inflate() call in order to return the proper return code.
+   Progress is defined as a change in either strm->avail_in or strm->avail_out.
+   When there is a window, goto inf_leave will update the window with the last
+   output written.  If a goto inf_leave occurs in the middle of decompression
+   and there is no window currently, goto inf_leave will create one and copy
+   output to the window for the next call of inflate().
+
+   In this implementation, the flush parameter of inflate() only affects the
+   return code (per zlib.h).  inflate() always writes as much as possible to
+   strm->next_out, given the space available and the provided input--the effect
+   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
+   the allocation of and copying into a sliding window until necessary, which
+   provides the effect documented in zlib.h for Z_FINISH when the entire input
+   stream available.  So the only thing the flush parameter actually does is:
+   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
+   will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+    struct inflate_state FAR *state;
+    z_const unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have, left;        /* available input and output */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned in, out;           /* save starting available input and output */
+    unsigned copy;              /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code here;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+#ifdef GUNZIP
+    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
+#endif
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0))
+        return Z_STREAM_ERROR;
+
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
+    LOAD();
+    in = have;
+    out = left;
+    ret = Z_OK;
+    for (;;)
+        switch (state->mode) {
+        case HEAD:
+            if (state->wrap == 0) {
+                state->mode = TYPEDO;
+                break;
+            }
+            NEEDBITS(16);
+#ifdef GUNZIP
+            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
+                state->check = crc32(0L, Z_NULL, 0);
+                CRC2(state->check, hold);
+                INITBITS();
+                state->mode = FLAGS;
+                break;
+            }
+            state->flags = 0;           /* expect zlib header */
+            if (state->head != Z_NULL)
+                state->head->done = -1;
+            if (!(state->wrap & 1) ||   /* check if zlib header allowed */
+#else
+            if (
+#endif
+                ((BITS(8) << 8) + (hold >> 8)) % 31) {
+                strm->msg = (char *)"incorrect header check";
+                state->mode = BAD;
+                break;
+            }
+            if (BITS(4) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            DROPBITS(4);
+            len = BITS(4) + 8;
+            if (state->wbits == 0)
+                state->wbits = len;
+            else if (len > state->wbits) {
+                strm->msg = (char *)"invalid window size";
+                state->mode = BAD;
+                break;
+            }
+            state->dmax = 1U << len;
+            Tracev((stderr, "inflate:   zlib header ok\n"));
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = hold & 0x200 ? DICTID : TYPE;
+            INITBITS();
+            break;
+#ifdef GUNZIP
+        case FLAGS:
+            NEEDBITS(16);
+            state->flags = (int)(hold);
+            if ((state->flags & 0xff) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            if (state->flags & 0xe000) {
+                strm->msg = (char *)"unknown header flags set";
+                state->mode = BAD;
+                break;
+            }
+            if (state->head != Z_NULL)
+                state->head->text = (int)((hold >> 8) & 1);
+            if (state->flags & 0x0200) CRC2(state->check, hold);
+            INITBITS();
+            state->mode = TIME;
+        case TIME:
+            NEEDBITS(32);
+            if (state->head != Z_NULL)
+                state->head->time = hold;
+            if (state->flags & 0x0200) CRC4(state->check, hold);
+            INITBITS();
+            state->mode = OS;
+        case OS:
+            NEEDBITS(16);
+            if (state->head != Z_NULL) {
+                state->head->xflags = (int)(hold & 0xff);
+                state->head->os = (int)(hold >> 8);
+            }
+            if (state->flags & 0x0200) CRC2(state->check, hold);
+            INITBITS();
+            state->mode = EXLEN;
+        case EXLEN:
+            if (state->flags & 0x0400) {
+                NEEDBITS(16);
+                state->length = (unsigned)(hold);
+                if (state->head != Z_NULL)
+                    state->head->extra_len = (unsigned)hold;
+                if (state->flags & 0x0200) CRC2(state->check, hold);
+                INITBITS();
+            }
+            else if (state->head != Z_NULL)
+                state->head->extra = Z_NULL;
+            state->mode = EXTRA;
+        case EXTRA:
+            if (state->flags & 0x0400) {
+                copy = state->length;
+                if (copy > have) copy = have;
+                if (copy) {
+                    if (state->head != Z_NULL &&
+                        state->head->extra != Z_NULL) {
+                        len = state->head->extra_len - state->length;
+                        zmemcpy(state->head->extra + len, next,
+                                len + copy > state->head->extra_max ?
+                                state->head->extra_max - len : copy);
+                    }
+                    if (state->flags & 0x0200)
+                        state->check = crc32(state->check, next, copy);
+                    have -= copy;
+                    next += copy;
+                    state->length -= copy;
+                }
+                if (state->length) goto inf_leave;
+            }
+            state->length = 0;
+            state->mode = NAME;
+        case NAME:
+            if (state->flags & 0x0800) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->name != Z_NULL &&
+                            state->length < state->head->name_max)
+                        state->head->name[state->length++] = len;
+                } while (len && copy < have);
+                if (state->flags & 0x0200)
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->name = Z_NULL;
+            state->length = 0;
+            state->mode = COMMENT;
+        case COMMENT:
+            if (state->flags & 0x1000) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->comment != Z_NULL &&
+                            state->length < state->head->comm_max)
+                        state->head->comment[state->length++] = len;
+                } while (len && copy < have);
+                if (state->flags & 0x0200)
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->comment = Z_NULL;
+            state->mode = HCRC;
+        case HCRC:
+            if (state->flags & 0x0200) {
+                NEEDBITS(16);
+                if (hold != (state->check & 0xffff)) {
+                    strm->msg = (char *)"header crc mismatch";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+            }
+            if (state->head != Z_NULL) {
+                state->head->hcrc = (int)((state->flags >> 9) & 1);
+                state->head->done = 1;
+            }
+            strm->adler = state->check = crc32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+            break;
+#endif
+        case DICTID:
+            NEEDBITS(32);
+            strm->adler = state->check = ZSWAP32(hold);
+            INITBITS();
+            state->mode = DICT;
+        case DICT:
+            if (state->havedict == 0) {
+                RESTORE();
+                return Z_NEED_DICT;
+            }
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+        case TYPE:
+            if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
+        case TYPEDO:
+            if (state->last) {
+                BYTEBITS();
+                state->mode = CHECK;
+                break;
+            }
+            NEEDBITS(3);
+            state->last = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                fixedtables(state);
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = LEN_;             /* decode codes */
+                if (flush == Z_TREES) {
+                    DROPBITS(2);
+                    goto inf_leave;
+                }
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                state->mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+        case STORED:
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                state->mode = BAD;
+                break;
+            }
+            state->length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %u\n",
+                    state->length));
+            INITBITS();
+            state->mode = COPY_;
+            if (flush == Z_TREES) goto inf_leave;
+        case COPY_:
+            state->mode = COPY;
+        case COPY:
+            copy = state->length;
+            if (copy) {
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                if (copy == 0) goto inf_leave;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                state->length -= copy;
+                break;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            state->mode = TYPE;
+            break;
+        case TABLE:
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+            if (state->nlen > 286 || state->ndist > 30) {
+                strm->msg = (char *)"too many length or distance symbols";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+            state->have = 0;
+            state->mode = LENLENS;
+        case LENLENS:
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            state->lencode = (const code FAR *)(state->next);
+            state->lenbits = 7;
+            ret = inflate_table(CODES, state->lens, 19, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+            state->have = 0;
+            state->mode = CODELENS;
+        case CODELENS:
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    here = state->lencode[BITS(state->lenbits)];
+                    if ((unsigned)(here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (here.val < 16) {
+                    DROPBITS(here.bits);
+                    state->lens[state->have++] = here.val;
+                }
+                else {
+                    if (here.val == 16) {
+                        NEEDBITS(here.bits + 2);
+                        DROPBITS(here.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            state->mode = BAD;
+                            break;
+                        }
+                        len = state->lens[state->have - 1];
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (here.val == 17) {
+                        NEEDBITS(here.bits + 3);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(here.bits + 7);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        state->mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* handle error breaks in while */
+            if (state->mode == BAD) break;
+
+            /* check for end-of-block code (better have one) */
+            if (state->lens[256] == 0) {
+                strm->msg = (char *)"invalid code -- missing end-of-block";
+                state->mode = BAD;
+                break;
+            }
+
+            /* build code tables -- note: do not change the lenbits or distbits
+               values here (9 and 6) without reading the comments in inftrees.h
+               concerning the ENOUGH constants, which depend on those values */
+            state->next = state->codes;
+            state->lencode = (const code FAR *)(state->next);
+            state->lenbits = 9;
+            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                state->mode = BAD;
+                break;
+            }
+            state->distcode = (const code FAR *)(state->next);
+            state->distbits = 6;
+            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+                            &(state->next), &(state->distbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            state->mode = LEN_;
+            if (flush == Z_TREES) goto inf_leave;
+        case LEN_:
+            state->mode = LEN;
+        case LEN:
+            if (have >= 6 && left >= 258) {
+                RESTORE();
+                inflate_fast(strm, out);
+                LOAD();
+                if (state->mode == TYPE)
+                    state->back = -1;
+                break;
+            }
+            state->back = 0;
+            for (;;) {
+                here = state->lencode[BITS(state->lenbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (here.op && (here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+                state->back += last.bits;
+            }
+            DROPBITS(here.bits);
+            state->back += here.bits;
+            state->length = (unsigned)here.val;
+            if ((int)(here.op) == 0) {
+                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", here.val));
+                state->mode = LIT;
+                break;
+            }
+            if (here.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                state->back = -1;
+                state->mode = TYPE;
+                break;
+            }
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                state->mode = BAD;
+                break;
+            }
+            state->extra = (unsigned)(here.op) & 15;
+            state->mode = LENEXT;
+        case LENEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->length += BITS(state->extra);
+                DROPBITS(state->extra);
+                state->back += state->extra;
+            }
+            Tracevv((stderr, "inflate:         length %u\n", state->length));
+            state->was = state->length;
+            state->mode = DIST;
+        case DIST:
+            for (;;) {
+                here = state->distcode[BITS(state->distbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+                state->back += last.bits;
+            }
+            DROPBITS(here.bits);
+            state->back += here.bits;
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+            state->offset = (unsigned)here.val;
+            state->extra = (unsigned)(here.op) & 15;
+            state->mode = DISTEXT;
+        case DISTEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->offset += BITS(state->extra);
+                DROPBITS(state->extra);
+                state->back += state->extra;
+            }
+#ifdef INFLATE_STRICT
+            if (state->offset > state->dmax) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
+            state->mode = MATCH;
+        case MATCH:
+            if (left == 0) goto inf_leave;
+            copy = out - left;
+            if (state->offset > copy) {         /* copy from window */
+                copy = state->offset - copy;
+                if (copy > state->whave) {
+                    if (state->sane) {
+                        strm->msg = (char *)"invalid distance too far back";
+                        state->mode = BAD;
+                        break;
+                    }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+                    Trace((stderr, "inflate.c too far\n"));
+                    copy -= state->whave;
+                    if (copy > state->length) copy = state->length;
+                    if (copy > left) copy = left;
+                    left -= copy;
+                    state->length -= copy;
+                    do {
+                        *put++ = 0;
+                    } while (--copy);
+                    if (state->length == 0) state->mode = LEN;
+                    break;
+#endif
+                }
+                if (copy > state->wnext) {
+                    copy -= state->wnext;
+                    from = state->window + (state->wsize - copy);
+                }
+                else
+                    from = state->window + (state->wnext - copy);
+                if (copy > state->length) copy = state->length;
+            }
+            else {                              /* copy from output */
+                from = put - state->offset;
+                copy = state->length;
+            }
+            if (copy > left) copy = left;
+            left -= copy;
+            state->length -= copy;
+            do {
+                *put++ = *from++;
+            } while (--copy);
+            if (state->length == 0) state->mode = LEN;
+            break;
+        case LIT:
+            if (left == 0) goto inf_leave;
+            *put++ = (unsigned char)(state->length);
+            left--;
+            state->mode = LEN;
+            break;
+        case CHECK:
+            if (state->wrap) {
+                NEEDBITS(32);
+                out -= left;
+                strm->total_out += out;
+                state->total += out;
+                if (out)
+                    strm->adler = state->check =
+                        UPDATE(state->check, put - out, out);
+                out = left;
+                if ((
+#ifdef GUNZIP
+                     state->flags ? hold :
+#endif
+                     ZSWAP32(hold)) != state->check) {
+                    strm->msg = (char *)"incorrect data check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   check matches trailer\n"));
+            }
+#ifdef GUNZIP
+            state->mode = LENGTH;
+        case LENGTH:
+            if (state->wrap && state->flags) {
+                NEEDBITS(32);
+                if (hold != (state->total & 0xffffffffUL)) {
+                    strm->msg = (char *)"incorrect length check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   length matches trailer\n"));
+            }
+#endif
+            state->mode = DONE;
+        case DONE:
+            ret = Z_STREAM_END;
+            goto inf_leave;
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+        case MEM:
+            return Z_MEM_ERROR;
+        case SYNC:
+        default:
+            return Z_STREAM_ERROR;
+        }
+
+    /*
+       Return from inflate(), updating the total counts and the check value.
+       If there was no progress during the inflate() call, return a buffer
+       error.  Call updatewindow() to create and/or update the window state.
+       Note: a memory error from inflate() is non-recoverable.
+     */
+  inf_leave:
+    RESTORE();
+    if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
+            (state->mode < CHECK || flush != Z_FINISH)))
+        if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
+            state->mode = MEM;
+            return Z_MEM_ERROR;
+        }
+    in -= strm->avail_in;
+    out -= strm->avail_out;
+    strm->total_in += in;
+    strm->total_out += out;
+    state->total += out;
+    if (state->wrap && out)
+        strm->adler = state->check =
+            UPDATE(state->check, strm->next_out - out, out);
+    strm->data_type = state->bits + (state->last ? 64 : 0) +
+                      (state->mode == TYPE ? 128 : 0) +
+                      (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
+    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+        ret = Z_BUF_ERROR;
+    return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->window != Z_NULL) ZFREE(strm, state->window);
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+Bytef *dictionary;
+uInt *dictLength;
+{
+    struct inflate_state FAR *state;
+
+    /* check state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* copy dictionary */
+    if (state->whave && dictionary != Z_NULL) {
+        zmemcpy(dictionary, state->window + state->wnext,
+                state->whave - state->wnext);
+        zmemcpy(dictionary + state->whave - state->wnext,
+                state->window, state->wnext);
+    }
+    if (dictLength != Z_NULL)
+        *dictLength = state->whave;
+    return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+const Bytef *dictionary;
+uInt dictLength;
+{
+    struct inflate_state FAR *state;
+    unsigned long dictid;
+    int ret;
+
+    /* check state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->wrap != 0 && state->mode != DICT)
+        return Z_STREAM_ERROR;
+
+    /* check for correct dictionary identifier */
+    if (state->mode == DICT) {
+        dictid = adler32(0L, Z_NULL, 0);
+        dictid = adler32(dictid, dictionary, dictLength);
+        if (dictid != state->check)
+            return Z_DATA_ERROR;
+    }
+
+    /* copy dictionary to window using updatewindow(), which will amend the
+       existing dictionary if appropriate */
+    ret = updatewindow(strm, dictionary + dictLength, dictLength);
+    if (ret) {
+        state->mode = MEM;
+        return Z_MEM_ERROR;
+    }
+    state->havedict = 1;
+    Tracev((stderr, "inflate:   dictionary set\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateGetHeader(strm, head)
+z_streamp strm;
+gz_headerp head;
+{
+    struct inflate_state FAR *state;
+
+    /* check state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+    /* save header structure */
+    state->head = head;
+    head->done = 0;
+    return Z_OK;
+}
+
+/*
+   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
+   or when out of input.  When called, *have is the number of pattern bytes
+   found in order so far, in 0..3.  On return *have is updated to the new
+   state.  If on return *have equals four, then the pattern was found and the
+   return value is how many bytes were read including the last byte of the
+   pattern.  If *have is less than four, then the pattern has not been found
+   yet and the return value is len.  In the latter case, syncsearch() can be
+   called again with more data and the *have state.  *have is initialized to
+   zero for the first call.
+ */
+local unsigned syncsearch(have, buf, len)
+unsigned FAR *have;
+const unsigned char FAR *buf;
+unsigned len;
+{
+    unsigned got;
+    unsigned next;
+
+    got = *have;
+    next = 0;
+    while (next < len && got < 4) {
+        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+            got++;
+        else if (buf[next])
+            got = 0;
+        else
+            got = 4 - got;
+        next++;
+    }
+    *have = got;
+    return next;
+}
+
+int ZEXPORT inflateSync(strm)
+z_streamp strm;
+{
+    unsigned len;               /* number of bytes to look at or looked at */
+    unsigned long in, out;      /* temporary to save total_in and total_out */
+    unsigned char buf[4];       /* to restore bit buffer to byte string */
+    struct inflate_state FAR *state;
+
+    /* check parameters */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+    /* if first time, start search in bit buffer */
+    if (state->mode != SYNC) {
+        state->mode = SYNC;
+        state->hold <<= state->bits & 7;
+        state->bits -= state->bits & 7;
+        len = 0;
+        while (state->bits >= 8) {
+            buf[len++] = (unsigned char)(state->hold);
+            state->hold >>= 8;
+            state->bits -= 8;
+        }
+        state->have = 0;
+        syncsearch(&(state->have), buf, len);
+    }
+
+    /* search available input */
+    len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+    strm->avail_in -= len;
+    strm->next_in += len;
+    strm->total_in += len;
+
+    /* return no joy or set up to restart inflate() on a new block */
+    if (state->have != 4) return Z_DATA_ERROR;
+    in = strm->total_in;  out = strm->total_out;
+    inflateReset(strm);
+    strm->total_in = in;  strm->total_out = out;
+    state->mode = TYPE;
+    return Z_OK;
+}
+
+/*
+   Returns true if inflate is currently at the end of a block generated by
+   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+   implementation to provide an additional safety check. PPP uses
+   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+   block. When decompressing, PPP checks that at the end of input packet,
+   inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(dest, source)
+z_streamp dest;
+z_streamp source;
+{
+    struct inflate_state FAR *state;
+    struct inflate_state FAR *copy;
+    unsigned char FAR *window;
+    unsigned wsize;
+
+    /* check input */
+    if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
+        source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)source->state;
+
+    /* allocate space */
+    copy = (struct inflate_state FAR *)
+           ZALLOC(source, 1, sizeof(struct inflate_state));
+    if (copy == Z_NULL) return Z_MEM_ERROR;
+    window = Z_NULL;
+    if (state->window != Z_NULL) {
+        window = (unsigned char FAR *)
+                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+        if (window == Z_NULL) {
+            ZFREE(source, copy);
+            return Z_MEM_ERROR;
+        }
+    }
+
+    /* copy state */
+    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+    zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
+    if (state->lencode >= state->codes &&
+        state->lencode <= state->codes + ENOUGH - 1) {
+        copy->lencode = copy->codes + (state->lencode - state->codes);
+        copy->distcode = copy->codes + (state->distcode - state->codes);
+    }
+    copy->next = copy->codes + (state->next - state->codes);
+    if (window != Z_NULL) {
+        wsize = 1U << state->wbits;
+        zmemcpy(window, state->window, wsize);
+    }
+    copy->window = window;
+    dest->state = (struct internal_state FAR *)copy;
+    return Z_OK;
+}
+
+int ZEXPORT inflateUndermine(strm, subvert)
+z_streamp strm;
+int subvert;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    state->sane = !subvert;
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+    return Z_OK;
+#else
+    state->sane = 1;
+    return Z_DATA_ERROR;
+#endif
+}
+
+long ZEXPORT inflateMark(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
+    state = (struct inflate_state FAR *)strm->state;
+    return ((long)(state->back) << 16) +
+        (state->mode == COPY ? state->length :
+            (state->mode == MATCH ? state->was - state->length : 0));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inflate.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inflate.h
new file mode 100755
index 0000000..95f4986
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inflate.h
@@ -0,0 +1,122 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2009 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer decoding by inflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip decoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+    HEAD,       /* i: waiting for magic header */
+    FLAGS,      /* i: waiting for method and flags (gzip) */
+    TIME,       /* i: waiting for modification time (gzip) */
+    OS,         /* i: waiting for extra flags and operating system (gzip) */
+    EXLEN,      /* i: waiting for extra length (gzip) */
+    EXTRA,      /* i: waiting for extra bytes (gzip) */
+    NAME,       /* i: waiting for end of file name (gzip) */
+    COMMENT,    /* i: waiting for end of comment (gzip) */
+    HCRC,       /* i: waiting for header crc (gzip) */
+    DICTID,     /* i: waiting for dictionary check value */
+    DICT,       /* waiting for inflateSetDictionary() call */
+        TYPE,       /* i: waiting for type bits, including last-flag bit */
+        TYPEDO,     /* i: same, but skip check to exit inflate on new block */
+        STORED,     /* i: waiting for stored size (length and complement) */
+        COPY_,      /* i/o: same as COPY below, but only first time in */
+        COPY,       /* i/o: waiting for input or output to copy stored block */
+        TABLE,      /* i: waiting for dynamic block table lengths */
+        LENLENS,    /* i: waiting for code length code lengths */
+        CODELENS,   /* i: waiting for length/lit and distance code lengths */
+            LEN_,       /* i: same as LEN below, but only first time in */
+            LEN,        /* i: waiting for length/lit/eob code */
+            LENEXT,     /* i: waiting for length extra bits */
+            DIST,       /* i: waiting for distance code */
+            DISTEXT,    /* i: waiting for distance extra bits */
+            MATCH,      /* o: waiting for output space to copy string */
+            LIT,        /* o: waiting for output space to write literal */
+    CHECK,      /* i: waiting for 32-bit check value */
+    LENGTH,     /* i: waiting for 32-bit length (gzip) */
+    DONE,       /* finished check, done -- remain here until reset */
+    BAD,        /* got a data error -- remain here until reset */
+    MEM,        /* got an inflate() memory error -- remain here until reset */
+    SYNC        /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+    State transitions between above modes -
+
+    (most modes can go to BAD or MEM on error -- not shown for clarity)
+
+    Process header:
+        HEAD -> (gzip) or (zlib) or (raw)
+        (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
+                  HCRC -> TYPE
+        (zlib) -> DICTID or TYPE
+        DICTID -> DICT -> TYPE
+        (raw) -> TYPEDO
+    Read deflate blocks:
+            TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
+            STORED -> COPY_ -> COPY -> TYPE
+            TABLE -> LENLENS -> CODELENS -> LEN_
+            LEN_ -> LEN
+    Read deflate codes in fixed or dynamic block:
+                LEN -> LENEXT or LIT or TYPE
+                LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+                LIT -> LEN
+    Process trailer:
+        CHECK -> LENGTH -> DONE
+ */
+
+/* state maintained between inflate() calls.  Approximately 10K bytes. */
+struct inflate_state {
+    inflate_mode mode;          /* current inflate mode */
+    int last;                   /* true if processing last block */
+    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip */
+    int havedict;               /* true if dictionary provided */
+    int flags;                  /* gzip header method and flags (0 if zlib) */
+    unsigned dmax;              /* zlib header max distance (INFLATE_STRICT) */
+    unsigned long check;        /* protected copy of check value */
+    unsigned long total;        /* protected copy of output count */
+    gz_headerp head;            /* where to save gzip header information */
+        /* sliding window */
+    unsigned wbits;             /* log base 2 of requested window size */
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned wnext;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if needed */
+        /* bit accumulator */
+    unsigned long hold;         /* input bit accumulator */
+    unsigned bits;              /* number of bits in "in" */
+        /* for string and stored block copying */
+    unsigned length;            /* literal or length of data to copy */
+    unsigned offset;            /* distance back to copy string from */
+        /* for table and code decoding */
+    unsigned extra;             /* extra bits needed */
+        /* fixed and dynamic code tables */
+    code const FAR *lencode;    /* starting table for length/literal codes */
+    code const FAR *distcode;   /* starting table for distance codes */
+    unsigned lenbits;           /* index bits for lencode */
+    unsigned distbits;          /* index bits for distcode */
+        /* dynamic table building */
+    unsigned ncode;             /* number of code length code lengths */
+    unsigned nlen;              /* number of length code lengths */
+    unsigned ndist;             /* number of distance code lengths */
+    unsigned have;              /* number of code lengths in lens[] */
+    code FAR *next;             /* next available space in codes[] */
+    unsigned short lens[320];   /* temporary storage for code lengths */
+    unsigned short work[288];   /* work area for code table building */
+    code codes[ENOUGH];         /* space for code tables */
+    int sane;                   /* if false, allow invalid distance too far */
+    int back;                   /* bits back of last unprocessed length/lit */
+    unsigned was;               /* initial length of match */
+};
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inftrees.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inftrees.c
new file mode 100755
index 0000000..44d89cf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inftrees.c
@@ -0,0 +1,306 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+   " inflate 1.2.8 Copyright 1995-2013 Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/*
+   Build a set of tables to decode the provided canonical Huffman code.
+   The code lengths are lens[0..codes-1].  The result starts at *table,
+   whose indices are 0..2^bits-1.  work is a writable array of at least
+   lens shorts, which is used as a work area.  type is the type of code
+   to be generated, CODES, LENS, or DISTS.  On return, zero is success,
+   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table
+   on return points to the next available entry's address.  bits is the
+   requested root table index bits, and on return it is the actual root
+   table index bits.  It will differ if the request is greater than the
+   longest code or if it is less than the shortest code.
+ */
+int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+    unsigned len;               /* a code's length in bits */
+    unsigned sym;               /* index of code symbols */
+    unsigned min, max;          /* minimum and maximum code lengths */
+    unsigned root;              /* number of index bits for root table */
+    unsigned curr;              /* number of index bits for current table */
+    unsigned drop;              /* code bits to drop for sub-table */
+    int left;                   /* number of prefix codes available */
+    unsigned used;              /* code entries in table used */
+    unsigned huff;              /* Huffman code */
+    unsigned incr;              /* for incrementing code, index */
+    unsigned fill;              /* index for replicating entries */
+    unsigned low;               /* low bits for current root entry */
+    unsigned mask;              /* mask for low root bits */
+    code here;                  /* table entry for duplication */
+    code FAR *next;             /* next available space in table */
+    const unsigned short FAR *base;     /* base value table to use */
+    const unsigned short FAR *extra;    /* extra bits table to use */
+    int end;                    /* use base and extra for symbol > end */
+    unsigned short count[MAXBITS+1];    /* number of codes of each length */
+    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */
+    static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+    static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+        16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78};
+    static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577, 0, 0};
+    static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+        16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+        23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+        28, 28, 29, 29, 64, 64};
+
+    /*
+       Process a set of code lengths to create a canonical Huffman code.  The
+       code lengths are lens[0..codes-1].  Each length corresponds to the
+       symbols 0..codes-1.  The Huffman code is generated by first sorting the
+       symbols by length from short to long, and retaining the symbol order
+       for codes with equal lengths.  Then the code starts with all zero bits
+       for the first code of the shortest length, and the codes are integer
+       increments for the same length, and zeros are appended as the length
+       increases.  For the deflate format, these bits are stored backwards
+       from their more natural integer increment ordering, and so when the
+       decoding tables are built in the large loop below, the integer codes
+       are incremented backwards.
+
+       This routine assumes, but does not check, that all of the entries in
+       lens[] are in the range 0..MAXBITS.  The caller must assure this.
+       1..MAXBITS is interpreted as that code length.  zero means that that
+       symbol does not occur in this code.
+
+       The codes are sorted by computing a count of codes for each length,
+       creating from that a table of starting indices for each length in the
+       sorted table, and then entering the symbols in order in the sorted
+       table.  The sorted table is work[], with that space being provided by
+       the caller.
+
+       The length counts are used for other purposes as well, i.e. finding
+       the minimum and maximum length codes, determining if there are any
+       codes at all, checking for a valid set of lengths, and looking ahead
+       at length counts to determine sub-table sizes when building the
+       decoding tables.
+     */
+
+    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+    for (len = 0; len <= MAXBITS; len++)
+        count[len] = 0;
+    for (sym = 0; sym < codes; sym++)
+        count[lens[sym]]++;
+
+    /* bound code lengths, force root to be within code lengths */
+    root = *bits;
+    for (max = MAXBITS; max >= 1; max--)
+        if (count[max] != 0) break;
+    if (root > max) root = max;
+    if (max == 0) {                     /* no symbols to code at all */
+        here.op = (unsigned char)64;    /* invalid code marker */
+        here.bits = (unsigned char)1;
+        here.val = (unsigned short)0;
+        *(*table)++ = here;             /* make a table to force an error */
+        *(*table)++ = here;
+        *bits = 1;
+        return 0;     /* no symbols, but wait for decoding to report error */
+    }
+    for (min = 1; min < max; min++)
+        if (count[min] != 0) break;
+    if (root < min) root = min;
+
+    /* check for an over-subscribed or incomplete set of lengths */
+    left = 1;
+    for (len = 1; len <= MAXBITS; len++) {
+        left <<= 1;
+        left -= count[len];
+        if (left < 0) return -1;        /* over-subscribed */
+    }
+    if (left > 0 && (type == CODES || max != 1))
+        return -1;                      /* incomplete set */
+
+    /* generate offsets into symbol table for each length for sorting */
+    offs[1] = 0;
+    for (len = 1; len < MAXBITS; len++)
+        offs[len + 1] = offs[len] + count[len];
+
+    /* sort symbols by length, by symbol order within each length */
+    for (sym = 0; sym < codes; sym++)
+        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+    /*
+       Create and fill in decoding tables.  In this loop, the table being
+       filled is at next and has curr index bits.  The code being used is huff
+       with length len.  That code is converted to an index by dropping drop
+       bits off of the bottom.  For codes where len is less than drop + curr,
+       those top drop + curr - len bits are incremented through all values to
+       fill the table with replicated entries.
+
+       root is the number of index bits for the root table.  When len exceeds
+       root, sub-tables are created pointed to by the root entry with an index
+       of the low root bits of huff.  This is saved in low to check for when a
+       new sub-table should be started.  drop is zero when the root table is
+       being filled, and drop is root when sub-tables are being filled.
+
+       When a new sub-table is needed, it is necessary to look ahead in the
+       code lengths to determine what size sub-table is needed.  The length
+       counts are used for this, and so count[] is decremented as codes are
+       entered in the tables.
+
+       used keeps track of how many table entries have been allocated from the
+       provided *table space.  It is checked for LENS and DIST tables against
+       the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+       the initial root table size constants.  See the comments in inftrees.h
+       for more information.
+
+       sym increments through all symbols, and the loop terminates when
+       all codes of length max, i.e. all codes, have been processed.  This
+       routine permits incomplete codes, so another loop after this one fills
+       in the rest of the decoding tables with invalid code markers.
+     */
+
+    /* set up for code type */
+    switch (type) {
+    case CODES:
+        base = extra = work;    /* dummy value--not used */
+        end = 19;
+        break;
+    case LENS:
+        base = lbase;
+        base -= 257;
+        extra = lext;
+        extra -= 257;
+        end = 256;
+        break;
+    default:            /* DISTS */
+        base = dbase;
+        extra = dext;
+        end = -1;
+    }
+
+    /* initialize state for loop */
+    huff = 0;                   /* starting code */
+    sym = 0;                    /* starting code symbol */
+    len = min;                  /* starting code length */
+    next = *table;              /* current table to fill in */
+    curr = root;                /* current table index bits */
+    drop = 0;                   /* current bits to drop from code for index */
+    low = (unsigned)(-1);       /* trigger new sub-table when len > root */
+    used = 1U << root;          /* use root table entries */
+    mask = used - 1;            /* mask for comparing low */
+
+    /* check available table space */
+    if ((type == LENS && used > ENOUGH_LENS) ||
+        (type == DISTS && used > ENOUGH_DISTS))
+        return 1;
+
+    /* process all codes and make table entries */
+    for (;;) {
+        /* create table entry */
+        here.bits = (unsigned char)(len - drop);
+        if ((int)(work[sym]) < end) {
+            here.op = (unsigned char)0;
+            here.val = work[sym];
+        }
+        else if ((int)(work[sym]) > end) {
+            here.op = (unsigned char)(extra[work[sym]]);
+            here.val = base[work[sym]];
+        }
+        else {
+            here.op = (unsigned char)(32 + 64);         /* end of block */
+            here.val = 0;
+        }
+
+        /* replicate for those indices with low len bits equal to huff */
+        incr = 1U << (len - drop);
+        fill = 1U << curr;
+        min = fill;                 /* save offset to next table */
+        do {
+            fill -= incr;
+            next[(huff >> drop) + fill] = here;
+        } while (fill != 0);
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+
+        /* go to next symbol, update count, len */
+        sym++;
+        if (--(count[len]) == 0) {
+            if (len == max) break;
+            len = lens[work[sym]];
+        }
+
+        /* create new sub-table if needed */
+        if (len > root && (huff & mask) != low) {
+            /* if first time, transition to sub-tables */
+            if (drop == 0)
+                drop = root;
+
+            /* increment past last table */
+            next += min;            /* here min is 1 << curr */
+
+            /* determine length of next table */
+            curr = len - drop;
+            left = (int)(1 << curr);
+            while (curr + drop < max) {
+                left -= count[curr + drop];
+                if (left <= 0) break;
+                curr++;
+                left <<= 1;
+            }
+
+            /* check for enough space */
+            used += 1U << curr;
+            if ((type == LENS && used > ENOUGH_LENS) ||
+                (type == DISTS && used > ENOUGH_DISTS))
+                return 1;
+
+            /* point entry in root table to sub-table */
+            low = huff & mask;
+            (*table)[low].op = (unsigned char)curr;
+            (*table)[low].bits = (unsigned char)root;
+            (*table)[low].val = (unsigned short)(next - *table);
+        }
+    }
+
+    /* fill in remaining table entry if code is incomplete (guaranteed to have
+       at most one remaining entry, since if the code is incomplete, the
+       maximum code length that was allowed to get this far is one bit) */
+    if (huff != 0) {
+        here.op = (unsigned char)64;            /* invalid code marker */
+        here.bits = (unsigned char)(len - drop);
+        here.val = (unsigned short)0;
+        next[huff] = here;
+    }
+
+    /* set return parameters */
+    *table += used;
+    *bits = root;
+    return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inftrees.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inftrees.h
new file mode 100755
index 0000000..baa53a0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/inftrees.h
@@ -0,0 +1,62 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables.  Each entry provides either the
+   information needed to do the operation requested by the code that
+   indexed that table entry, or it provides a pointer to another
+   table that indexes more bits of the code.  op indicates whether
+   the entry is a pointer to another table, a literal, a length or
+   distance, an end-of-block, or an invalid code.  For a table
+   pointer, the low four bits of op is the number of index bits of
+   that table.  For a length or distance, the low four bits of op
+   is the number of extra bits to get after the code.  bits is
+   the number of bits in this code or part of the code to drop off
+   of the bit buffer.  val is the actual byte to output in the case
+   of a literal, the base length or distance, or the offset from
+   the current table to the next table.  Each entry is four bytes. */
+typedef struct {
+    unsigned char op;           /* operation, extra bits, table bits */
+    unsigned char bits;         /* bits in this part of the code */
+    unsigned short val;         /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+    00000000 - literal
+    0000tttt - table link, tttt != 0 is the number of table index bits
+    0001eeee - length or distance, eeee is the number of extra bits
+    01100000 - end of block
+    01000000 - invalid code
+ */
+
+/* Maximum size of the dynamic table.  The maximum number of code structures is
+   1444, which is the sum of 852 for literal/length codes and 592 for distance
+   codes.  These values were found by exhaustive searches using the program
+   examples/enough.c found in the zlib distribtution.  The arguments to that
+   program are the number of symbols, the initial root table size, and the
+   maximum bit length of a code.  "enough 286 9 15" for literal/length codes
+   returns returns 852, and "enough 30 6 15" for distance codes returns 592.
+   The initial root table size (9 or 6) is found in the fifth argument of the
+   inflate_table() calls in inflate.c and infback.c.  If the root table size is
+   changed, then these maximum sizes would be need to be recalculated and
+   updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 592
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
+
+/* Type of code to build for inflate_table() */
+typedef enum {
+    CODES,
+    LENS,
+    DISTS
+} codetype;
+
+int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
+                             unsigned codes, code FAR * FAR *table,
+                             unsigned FAR *bits, unsigned short FAR *work));
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/trees.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/trees.c
new file mode 100755
index 0000000..bb866f0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/trees.c
@@ -0,0 +1,1226 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2012 Jean-loup Gailly
+ * detect_data_type() function provided freely by Cosmin Truta, 2006
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process uses several Huffman trees. The more
+ *      common source values are represented by shorter bit sequences.
+ *
+ *      Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values).  The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ *      Storer, James A.
+ *          Data Compression:  Methods and Theory, pp. 49-50.
+ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
+ *
+ *      Sedgewick, R.
+ *          Algorithms, p290.
+ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+#  include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6      16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10    17
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+
+#define REPZ_11_138  18
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN  512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+#  include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+    const ct_data *static_tree;  /* static tree or NULL */
+    const intf *extra_bits;      /* extra bits for each code or NULL */
+    int     extra_base;          /* base index for extra_bits */
+    int     elems;               /* max number of elements in the tree */
+    int     max_length;          /* max bit length for the codes */
+};
+
+local static_tree_desc  static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc  static_d_desc =
+{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
+
+local static_tree_desc  static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block     OF((deflate_state *s));
+local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
+local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree     OF((deflate_state *s, tree_desc *desc));
+local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local int  build_bl_tree  OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+                              int blcodes));
+local void compress_block OF((deflate_state *s, const ct_data *ltree,
+                              const ct_data *dtree));
+local int  detect_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup      OF((deflate_state *s));
+local void bi_flush       OF((deflate_state *s));
+local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
+                              int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+   /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+#  define send_code(s, c, tree) \
+     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+       send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+    put_byte(s, (uch)((w) & 0xff)); \
+    put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits      OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+    deflate_state *s;
+    int value;  /* value to send */
+    int length; /* number of bits */
+{
+    Tracevv((stderr," l %2d v %4x ", length, value));
+    Assert(length > 0 && length <= 15, "invalid length");
+    s->bits_sent += (ulg)length;
+
+    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+     * unused bits in value.
+     */
+    if (s->bi_valid > (int)Buf_size - length) {
+        s->bi_buf |= (ush)value << s->bi_valid;
+        put_short(s, s->bi_buf);
+        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+        s->bi_valid += length - Buf_size;
+    } else {
+        s->bi_buf |= (ush)value << s->bi_valid;
+        s->bi_valid += length;
+    }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+  if (s->bi_valid > (int)Buf_size - len) {\
+    int val = value;\
+    s->bi_buf |= (ush)val << s->bi_valid;\
+    put_short(s, s->bi_buf);\
+    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+    s->bi_valid += len - Buf_size;\
+  } else {\
+    s->bi_buf |= (ush)(value) << s->bi_valid;\
+    s->bi_valid += len;\
+  }\
+}
+#endif /* DEBUG */
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+    static int static_init_done = 0;
+    int n;        /* iterates over tree elements */
+    int bits;     /* bit counter */
+    int length;   /* length value */
+    int code;     /* code value */
+    int dist;     /* distance index */
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    if (static_init_done) return;
+
+    /* For some embedded targets, global variables are not initialized: */
+#ifdef NO_INIT_GLOBAL_POINTERS
+    static_l_desc.static_tree = static_ltree;
+    static_l_desc.extra_bits = extra_lbits;
+    static_d_desc.static_tree = static_dtree;
+    static_d_desc.extra_bits = extra_dbits;
+    static_bl_desc.extra_bits = extra_blbits;
+#endif
+
+    /* Initialize the mapping length (0..255) -> length code (0..28) */
+    length = 0;
+    for (code = 0; code < LENGTH_CODES-1; code++) {
+        base_length[code] = length;
+        for (n = 0; n < (1<<extra_lbits[code]); n++) {
+            _length_code[length++] = (uch)code;
+        }
+    }
+    Assert (length == 256, "tr_static_init: length != 256");
+    /* Note that the length 255 (match length 258) can be represented
+     * in two different ways: code 284 + 5 bits or code 285, so we
+     * overwrite length_code[255] to use the best encoding:
+     */
+    _length_code[length-1] = (uch)code;
+
+    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+    dist = 0;
+    for (code = 0 ; code < 16; code++) {
+        base_dist[code] = dist;
+        for (n = 0; n < (1<<extra_dbits[code]); n++) {
+            _dist_code[dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: dist != 256");
+    dist >>= 7; /* from now on, all distances are divided by 128 */
+    for ( ; code < D_CODES; code++) {
+        base_dist[code] = dist << 7;
+        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+            _dist_code[256 + dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+    /* Construct the codes of the static literal tree */
+    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+    n = 0;
+    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+    /* Codes 286 and 287 do not exist, but we must include them in the
+     * tree construction to get a canonical Huffman tree (longest code
+     * all ones)
+     */
+    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+    /* The static distance tree is trivial: */
+    for (n = 0; n < D_CODES; n++) {
+        static_dtree[n].Len = 5;
+        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+    }
+    static_init_done = 1;
+
+#  ifdef GEN_TREES_H
+    gen_trees_header();
+#  endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+#  ifndef DEBUG
+#    include <stdio.h>
+#  endif
+
+#  define SEPARATOR(i, last, width) \
+      ((i) == (last)? "\n};\n\n" :    \
+       ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+    FILE *header = fopen("trees.h", "w");
+    int i;
+
+    Assert (header != NULL, "Can't open trees.h");
+    fprintf(header,
+            "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+    for (i = 0; i < L_CODES+2; i++) {
+        fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+                static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+    }
+
+    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+                static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+    }
+
+    fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
+    for (i = 0; i < DIST_CODE_LEN; i++) {
+        fprintf(header, "%2u%s", _dist_code[i],
+                SEPARATOR(i, DIST_CODE_LEN-1, 20));
+    }
+
+    fprintf(header,
+        "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+        fprintf(header, "%2u%s", _length_code[i],
+                SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+    }
+
+    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+    for (i = 0; i < LENGTH_CODES; i++) {
+        fprintf(header, "%1u%s", base_length[i],
+                SEPARATOR(i, LENGTH_CODES-1, 20));
+    }
+
+    fprintf(header, "local const int base_dist[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "%5u%s", base_dist[i],
+                SEPARATOR(i, D_CODES-1, 10));
+    }
+
+    fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void ZLIB_INTERNAL _tr_init(s)
+    deflate_state *s;
+{
+    tr_static_init();
+
+    s->l_desc.dyn_tree = s->dyn_ltree;
+    s->l_desc.stat_desc = &static_l_desc;
+
+    s->d_desc.dyn_tree = s->dyn_dtree;
+    s->d_desc.stat_desc = &static_d_desc;
+
+    s->bl_desc.dyn_tree = s->bl_tree;
+    s->bl_desc.stat_desc = &static_bl_desc;
+
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG
+    s->compressed_len = 0L;
+    s->bits_sent = 0L;
+#endif
+
+    /* Initialize the first block of the first file: */
+    init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+    deflate_state *s;
+{
+    int n; /* iterates over tree elements */
+
+    /* Initialize the trees. */
+    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+    s->dyn_ltree[END_BLOCK].Freq = 1;
+    s->opt_len = s->static_len = 0L;
+    s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+    top = s->heap[SMALLEST]; \
+    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+    pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+   (tree[n].Freq < tree[m].Freq || \
+   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+    deflate_state *s;
+    ct_data *tree;  /* the tree to restore */
+    int k;               /* node to move down */
+{
+    int v = s->heap[k];
+    int j = k << 1;  /* left son of k */
+    while (j <= s->heap_len) {
+        /* Set j to the smallest of the two sons: */
+        if (j < s->heap_len &&
+            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+            j++;
+        }
+        /* Exit if v is smaller than both sons */
+        if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+        /* Exchange v with the smallest son */
+        s->heap[k] = s->heap[j];  k = j;
+
+        /* And continue down the tree, setting j to the left son of k */
+        j <<= 1;
+    }
+    s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+local void gen_bitlen(s, desc)
+    deflate_state *s;
+    tree_desc *desc;    /* the tree descriptor */
+{
+    ct_data *tree        = desc->dyn_tree;
+    int max_code         = desc->max_code;
+    const ct_data *stree = desc->stat_desc->static_tree;
+    const intf *extra    = desc->stat_desc->extra_bits;
+    int base             = desc->stat_desc->extra_base;
+    int max_length       = desc->stat_desc->max_length;
+    int h;              /* heap index */
+    int n, m;           /* iterate over the tree elements */
+    int bits;           /* bit length */
+    int xbits;          /* extra bits */
+    ush f;              /* frequency */
+    int overflow = 0;   /* number of elements with bit length too large */
+
+    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+    /* In a first pass, compute the optimal bit lengths (which may
+     * overflow in the case of the bit length tree).
+     */
+    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+        n = s->heap[h];
+        bits = tree[tree[n].Dad].Len + 1;
+        if (bits > max_length) bits = max_length, overflow++;
+        tree[n].Len = (ush)bits;
+        /* We overwrite tree[n].Dad which is no longer needed */
+
+        if (n > max_code) continue; /* not a leaf node */
+
+        s->bl_count[bits]++;
+        xbits = 0;
+        if (n >= base) xbits = extra[n-base];
+        f = tree[n].Freq;
+        s->opt_len += (ulg)f * (bits + xbits);
+        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+    }
+    if (overflow == 0) return;
+
+    Trace((stderr,"\nbit length overflow\n"));
+    /* This happens for example on obj2 and pic of the Calgary corpus */
+
+    /* Find the first bit length which could increase: */
+    do {
+        bits = max_length-1;
+        while (s->bl_count[bits] == 0) bits--;
+        s->bl_count[bits]--;      /* move one leaf down the tree */
+        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+        s->bl_count[max_length]--;
+        /* The brother of the overflow item also moves one step up,
+         * but this does not affect bl_count[max_length]
+         */
+        overflow -= 2;
+    } while (overflow > 0);
+
+    /* Now recompute all bit lengths, scanning in increasing frequency.
+     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+     * lengths instead of fixing only the wrong ones. This idea is taken
+     * from 'ar' written by Haruhiko Okumura.)
+     */
+    for (bits = max_length; bits != 0; bits--) {
+        n = s->bl_count[bits];
+        while (n != 0) {
+            m = s->heap[--h];
+            if (m > max_code) continue;
+            if ((unsigned) tree[m].Len != (unsigned) bits) {
+                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+                s->opt_len += ((long)bits - (long)tree[m].Len)
+                              *(long)tree[m].Freq;
+                tree[m].Len = (ush)bits;
+            }
+            n--;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+    ct_data *tree;             /* the tree to decorate */
+    int max_code;              /* largest code with non zero frequency */
+    ushf *bl_count;            /* number of codes at each bit length */
+{
+    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+    ush code = 0;              /* running code value */
+    int bits;                  /* bit index */
+    int n;                     /* code index */
+
+    /* The distribution counts are first used to generate the code values
+     * without bit reversal.
+     */
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+    }
+    /* Check that the bit counts in bl_count are consistent. The last code
+     * must be all ones.
+     */
+    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+            "inconsistent bit counts");
+    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+    for (n = 0;  n <= max_code; n++) {
+        int len = tree[n].Len;
+        if (len == 0) continue;
+        /* Now reverse the bits */
+        tree[n].Code = (ush)bi_reverse(next_code[len]++, len);
+
+        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+    }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+    deflate_state *s;
+    tree_desc *desc; /* the tree descriptor */
+{
+    ct_data *tree         = desc->dyn_tree;
+    const ct_data *stree  = desc->stat_desc->static_tree;
+    int elems             = desc->stat_desc->elems;
+    int n, m;          /* iterate over heap elements */
+    int max_code = -1; /* largest code with non zero frequency */
+    int node;          /* new node being created */
+
+    /* Construct the initial heap, with least frequent element in
+     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+     * heap[0] is not used.
+     */
+    s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+    for (n = 0; n < elems; n++) {
+        if (tree[n].Freq != 0) {
+            s->heap[++(s->heap_len)] = max_code = n;
+            s->depth[n] = 0;
+        } else {
+            tree[n].Len = 0;
+        }
+    }
+
+    /* The pkzip format requires that at least one distance code exists,
+     * and that at least one bit should be sent even if there is only one
+     * possible code. So to avoid special checks later on we force at least
+     * two codes of non zero frequency.
+     */
+    while (s->heap_len < 2) {
+        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+        tree[node].Freq = 1;
+        s->depth[node] = 0;
+        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+        /* node is 0 or 1 so it does not have extra bits */
+    }
+    desc->max_code = max_code;
+
+    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+     * establish sub-heaps of increasing lengths:
+     */
+    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+    /* Construct the Huffman tree by repeatedly combining the least two
+     * frequent nodes.
+     */
+    node = elems;              /* next internal node of the tree */
+    do {
+        pqremove(s, tree, n);  /* n = node of least frequency */
+        m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+        s->heap[--(s->heap_max)] = m;
+
+        /* Create a new node father of n and m */
+        tree[node].Freq = tree[n].Freq + tree[m].Freq;
+        s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+                                s->depth[n] : s->depth[m]) + 1);
+        tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+        if (tree == s->bl_tree) {
+            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+        }
+#endif
+        /* and insert the new node in the heap */
+        s->heap[SMALLEST] = node++;
+        pqdownheap(s, tree, SMALLEST);
+
+    } while (s->heap_len >= 2);
+
+    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+    /* At this point, the fields freq and dad are set. We can now
+     * generate the bit lengths.
+     */
+    gen_bitlen(s, (tree_desc *)desc);
+
+    /* The field len is now set, we can generate the bit codes */
+    gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree;   /* the tree to be scanned */
+    int max_code;    /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    if (nextlen == 0) max_count = 138, min_count = 3;
+    tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            s->bl_tree[curlen].Freq += (ush)count;
+        } else if (curlen != 0) {
+            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+            s->bl_tree[REP_3_6].Freq++;
+        } else if (count <= 10) {
+            s->bl_tree[REPZ_3_10].Freq++;
+        } else {
+            s->bl_tree[REPZ_11_138].Freq++;
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree; /* the tree to be scanned */
+    int max_code;       /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    /* tree[max_code+1].Len = -1; */  /* guard already set */
+    if (nextlen == 0) max_count = 138, min_count = 3;
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+        } else if (curlen != 0) {
+            if (curlen != prevlen) {
+                send_code(s, curlen, s->bl_tree); count--;
+            }
+            Assert(count >= 3 && count <= 6, " 3_6?");
+            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+        } else if (count <= 10) {
+            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+        } else {
+            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+    deflate_state *s;
+{
+    int max_blindex;  /* index of last bit length code of non zero freq */
+
+    /* Determine the bit length frequencies for literal and distance trees */
+    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+    /* Build the bit length tree: */
+    build_tree(s, (tree_desc *)(&(s->bl_desc)));
+    /* opt_len now includes the length of the tree representations, except
+     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+     */
+
+    /* Determine the number of bit length codes to send. The pkzip format
+     * requires that at least 4 bit length codes be sent. (appnote.txt says
+     * 3 but the actual value used is 4.)
+     */
+    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+    }
+    /* Update opt_len to include the bit length tree and counts */
+    s->opt_len += 3*(max_blindex+1) + 5+5+4;
+    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+            s->opt_len, s->static_len));
+
+    return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+    deflate_state *s;
+    int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+    int rank;                    /* index in bl_order */
+
+    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+            "too many codes");
+    Tracev((stderr, "\nbl counts: "));
+    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+    send_bits(s, dcodes-1,   5);
+    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
+    for (rank = 0; rank < blcodes; rank++) {
+        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+    }
+    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
+    deflate_state *s;
+    charf *buf;       /* input block */
+    ulg stored_len;   /* length of input block */
+    int last;         /* one if this is the last block for a file */
+{
+    send_bits(s, (STORED_BLOCK<<1)+last, 3);    /* send block type */
+#ifdef DEBUG
+    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+    s->compressed_len += (stored_len + 4) << 3;
+#endif
+    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
+ */
+void ZLIB_INTERNAL _tr_flush_bits(s)
+    deflate_state *s;
+{
+    bi_flush(s);
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ */
+void ZLIB_INTERNAL _tr_align(s)
+    deflate_state *s;
+{
+    send_bits(s, STATIC_TREES<<1, 3);
+    send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+    bi_flush(s);
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
+    deflate_state *s;
+    charf *buf;       /* input block, or NULL if too old */
+    ulg stored_len;   /* length of input block */
+    int last;         /* one if this is the last block for a file */
+{
+    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+    int max_blindex = 0;  /* index of last bit length code of non zero freq */
+
+    /* Build the Huffman trees unless a stored block is forced */
+    if (s->level > 0) {
+
+        /* Check if the file is binary or text */
+        if (s->strm->data_type == Z_UNKNOWN)
+            s->strm->data_type = detect_data_type(s);
+
+        /* Construct the literal and distance trees */
+        build_tree(s, (tree_desc *)(&(s->l_desc)));
+        Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+
+        build_tree(s, (tree_desc *)(&(s->d_desc)));
+        Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+        /* At this point, opt_len and static_len are the total bit lengths of
+         * the compressed block data, excluding the tree representations.
+         */
+
+        /* Build the bit length tree for the above two trees, and get the index
+         * in bl_order of the last bit length code to send.
+         */
+        max_blindex = build_bl_tree(s);
+
+        /* Determine the best encoding. Compute the block lengths in bytes. */
+        opt_lenb = (s->opt_len+3+7)>>3;
+        static_lenb = (s->static_len+3+7)>>3;
+
+        Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+                opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+                s->last_lit));
+
+        if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+    } else {
+        Assert(buf != (char*)0, "lost buf");
+        opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+    }
+
+#ifdef FORCE_STORED
+    if (buf != (char*)0) { /* force stored block */
+#else
+    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+                       /* 4: two words for the lengths */
+#endif
+        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+         * Otherwise we can't have processed more than WSIZE input bytes since
+         * the last block flush, because compression would have been
+         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+         * transform a block into a stored block.
+         */
+        _tr_stored_block(s, buf, stored_len, last);
+
+#ifdef FORCE_STATIC
+    } else if (static_lenb >= 0) { /* force static trees */
+#else
+    } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
+#endif
+        send_bits(s, (STATIC_TREES<<1)+last, 3);
+        compress_block(s, (const ct_data *)static_ltree,
+                       (const ct_data *)static_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->static_len;
+#endif
+    } else {
+        send_bits(s, (DYN_TREES<<1)+last, 3);
+        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+                       max_blindex+1);
+        compress_block(s, (const ct_data *)s->dyn_ltree,
+                       (const ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->opt_len;
+#endif
+    }
+    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+    /* The above check is made mod 2^32, for files larger than 512 MB
+     * and uLong implemented on 32 bits.
+     */
+    init_block(s);
+
+    if (last) {
+        bi_windup(s);
+#ifdef DEBUG
+        s->compressed_len += 7;  /* align on byte boundary */
+#endif
+    }
+    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+           s->compressed_len-7*last));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int ZLIB_INTERNAL _tr_tally (s, dist, lc)
+    deflate_state *s;
+    unsigned dist;  /* distance of matched string */
+    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+    s->d_buf[s->last_lit] = (ush)dist;
+    s->l_buf[s->last_lit++] = (uch)lc;
+    if (dist == 0) {
+        /* lc is the unmatched char */
+        s->dyn_ltree[lc].Freq++;
+    } else {
+        s->matches++;
+        /* Here, lc is the match length - MIN_MATCH */
+        dist--;             /* dist = match distance - 1 */
+        Assert((ush)dist < (ush)MAX_DIST(s) &&
+               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
+
+        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+        s->dyn_dtree[d_code(dist)].Freq++;
+    }
+
+#ifdef TRUNCATE_BLOCK
+    /* Try to guess if it is profitable to stop the current block here */
+    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+        /* Compute an upper bound for the compressed length */
+        ulg out_length = (ulg)s->last_lit*8L;
+        ulg in_length = (ulg)((long)s->strstart - s->block_start);
+        int dcode;
+        for (dcode = 0; dcode < D_CODES; dcode++) {
+            out_length += (ulg)s->dyn_dtree[dcode].Freq *
+                (5L+extra_dbits[dcode]);
+        }
+        out_length >>= 3;
+        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+               s->last_lit, in_length, out_length,
+               100L - out_length*100L/in_length));
+        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+    }
+#endif
+    return (s->last_lit == s->lit_bufsize-1);
+    /* We avoid equality with lit_bufsize because of wraparound at 64K
+     * on 16 bit machines and because stored blocks are restricted to
+     * 64K-1 bytes.
+     */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+    deflate_state *s;
+    const ct_data *ltree; /* literal tree */
+    const ct_data *dtree; /* distance tree */
+{
+    unsigned dist;      /* distance of matched string */
+    int lc;             /* match length or unmatched char (if dist == 0) */
+    unsigned lx = 0;    /* running index in l_buf */
+    unsigned code;      /* the code to send */
+    int extra;          /* number of extra bits to send */
+
+    if (s->last_lit != 0) do {
+        dist = s->d_buf[lx];
+        lc = s->l_buf[lx++];
+        if (dist == 0) {
+            send_code(s, lc, ltree); /* send a literal byte */
+            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+        } else {
+            /* Here, lc is the match length - MIN_MATCH */
+            code = _length_code[lc];
+            send_code(s, code+LITERALS+1, ltree); /* send the length code */
+            extra = extra_lbits[code];
+            if (extra != 0) {
+                lc -= base_length[code];
+                send_bits(s, lc, extra);       /* send the extra length bits */
+            }
+            dist--; /* dist is now the match distance - 1 */
+            code = d_code(dist);
+            Assert (code < D_CODES, "bad d_code");
+
+            send_code(s, code, dtree);       /* send the distance code */
+            extra = extra_dbits[code];
+            if (extra != 0) {
+                dist -= base_dist[code];
+                send_bits(s, dist, extra);   /* send the extra distance bits */
+            }
+        } /* literal or match pair ? */
+
+        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+        Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+               "pendingBuf overflow");
+
+    } while (lx < s->last_lit);
+
+    send_code(s, END_BLOCK, ltree);
+}
+
+/* ===========================================================================
+ * Check if the data type is TEXT or BINARY, using the following algorithm:
+ * - TEXT if the two conditions below are satisfied:
+ *    a) There are no non-portable control characters belonging to the
+ *       "black list" (0..6, 14..25, 28..31).
+ *    b) There is at least one printable character belonging to the
+ *       "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+ * - BINARY otherwise.
+ * - The following partially-portable control characters form a
+ *   "gray list" that is ignored in this detection algorithm:
+ *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+local int detect_data_type(s)
+    deflate_state *s;
+{
+    /* black_mask is the bit mask of black-listed bytes
+     * set bits 0..6, 14..25, and 28..31
+     * 0xf3ffc07f = binary 11110011111111111100000001111111
+     */
+    unsigned long black_mask = 0xf3ffc07fUL;
+    int n;
+
+    /* Check for non-textual ("black-listed") bytes. */
+    for (n = 0; n <= 31; n++, black_mask >>= 1)
+        if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
+            return Z_BINARY;
+
+    /* Check for textual ("white-listed") bytes. */
+    if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
+            || s->dyn_ltree[13].Freq != 0)
+        return Z_TEXT;
+    for (n = 32; n < LITERALS; n++)
+        if (s->dyn_ltree[n].Freq != 0)
+            return Z_TEXT;
+
+    /* There are no "black-listed" or "white-listed" bytes:
+     * this stream either is empty or has tolerated ("gray-listed") bytes only.
+     */
+    return Z_BINARY;
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+    unsigned code; /* the value to invert */
+    int len;       /* its bit length */
+{
+    register unsigned res = 0;
+    do {
+        res |= code & 1;
+        code >>= 1, res <<= 1;
+    } while (--len > 0);
+    return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+    deflate_state *s;
+{
+    if (s->bi_valid == 16) {
+        put_short(s, s->bi_buf);
+        s->bi_buf = 0;
+        s->bi_valid = 0;
+    } else if (s->bi_valid >= 8) {
+        put_byte(s, (Byte)s->bi_buf);
+        s->bi_buf >>= 8;
+        s->bi_valid -= 8;
+    }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+    deflate_state *s;
+{
+    if (s->bi_valid > 8) {
+        put_short(s, s->bi_buf);
+    } else if (s->bi_valid > 0) {
+        put_byte(s, (Byte)s->bi_buf);
+    }
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG
+    s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+    deflate_state *s;
+    charf    *buf;    /* the input data */
+    unsigned len;     /* its length */
+    int      header;  /* true if block header must be written */
+{
+    bi_windup(s);        /* align on byte boundary */
+
+    if (header) {
+        put_short(s, (ush)len);
+        put_short(s, (ush)~len);
+#ifdef DEBUG
+        s->bits_sent += 2*16;
+#endif
+    }
+#ifdef DEBUG
+    s->bits_sent += (ulg)len<<3;
+#endif
+    while (len--) {
+        put_byte(s, *buf++);
+    }
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/trees.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/trees.h
new file mode 100755
index 0000000..d35639d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/trees.h
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},
+{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},
+{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},
+{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},
+{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},
+{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},
+{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},
+{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},
+{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},
+{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},
+{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},
+{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},
+{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},
+{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},
+{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},
+{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},
+{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},
+{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},
+{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},
+{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},
+{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},
+{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},
+{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},
+{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},
+{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},
+{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},
+{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},
+{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},
+{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},
+{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},
+{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},
+{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},
+{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},
+{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},
+{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},
+{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},
+{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},
+{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},
+{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},
+{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},
+{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},
+{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},
+{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},
+{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},
+{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},
+{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},
+{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},
+{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},
+{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},
+{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},
+{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},
+{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},
+{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},
+{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},
+{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},
+{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},
+{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},
+{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {
+ 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,
+ 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,
+   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,
+ 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576
+};
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/zconf.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/zconf.h
new file mode 100755
index 0000000..229c400
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/zconf.h
@@ -0,0 +1,58 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+#include "../../src/common.h"
+
+/* Jeez, don't complain about non-prototype
+ * forms, we didn't write zlib */
+#if defined(_MSC_VER)
+#	pragma warning( disable : 4131 )
+#	pragma warning( disable : 4142 ) /* benign redefinition of type */
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#define MAX_MEM_LEVEL 9
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#define MAX_WBITS   15 /* 32K LZ77 window */
+
+#define ZEXTERN extern
+#define ZEXPORT
+#define ZEXPORTVA
+#ifndef FAR
+#	define FAR
+#endif
+#define OF(args)  args
+#define Z_ARG(args) args
+
+typedef unsigned char  Byte;  /* 8 bits */
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+typedef unsigned long z_crc_t;
+
+typedef Byte  FAR Bytef;
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+typedef void const *voidpc;
+typedef void FAR   *voidpf;
+typedef void       *voidp;
+
+#define z_off_t git_off_t
+#define z_off64_t z_off_t
+#define z_const const
+
+#endif /* ZCONF_H */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/zlib.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/zlib.h
new file mode 100755
index 0000000..3e0c767
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/zlib.h
@@ -0,0 +1,1768 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 1.2.8, April 28th, 2013
+
+  Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup at gzip.org          madler at alumni.caltech.edu
+
+
+  The data format used by the zlib library is described by RFCs (Request for
+  Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+  (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.8"
+#define ZLIB_VERNUM 0x1280
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 8
+#define ZLIB_VER_SUBREVISION 0
+
+/*
+    The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed data.
+  This version of the library supports only one compression method (deflation)
+  but other algorithms will be added later and will have the same stream
+  interface.
+
+    Compression can be done in a single step if the buffers are large enough,
+  or can be done by repeated calls of the compression function.  In the latter
+  case, the application must provide more input and/or consume the output
+  (providing more output space) before each call.
+
+    The compressed data format used by default by the in-memory functions is
+  the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+  around a deflate stream, which is itself documented in RFC 1951.
+
+    The library also supports reading and writing files in gzip (.gz) format
+  with an interface similar to that of stdio using the functions that start
+  with "gz".  The gzip format is different from the zlib format.  gzip is a
+  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+    This library can optionally read and write gzip streams in memory as well.
+
+    The zlib format was designed to be compact and fast for use in memory
+  and on communications channels.  The gzip format was designed for single-
+  file compression on file systems, has a larger header than zlib to maintain
+  directory information, and uses a different, slower check method than zlib.
+
+    The library does not install any signal handler.  The decoder checks
+  the consistency of the compressed data, so the library should never crash
+  even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    z_const Bytef *next_in;     /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total number of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total number of bytes output so far */
+
+    z_const char *msg;  /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: binary or text */
+    uLong   adler;      /* adler32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+     gzip header information passed to and from zlib routines.  See RFC 1952
+  for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+    int     text;       /* true if compressed data believed to be text */
+    uLong   time;       /* modification time */
+    int     xflags;     /* extra flags (not used when writing a gzip file) */
+    int     os;         /* operating system */
+    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */
+    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */
+    uInt    extra_max;  /* space at extra (only when reading header) */
+    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */
+    uInt    name_max;   /* space at name (only when reading header) */
+    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */
+    uInt    comm_max;   /* space at comment (only when reading header) */
+    int     hcrc;       /* true if there was or will be a header crc */
+    int     done;       /* true when done reading gzip header (not used
+                           when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+     The application must update next_in and avail_in when avail_in has dropped
+   to zero.  It must update next_out and avail_out when avail_out has dropped
+   to zero.  The application must initialize zalloc, zfree and opaque before
+   calling the init function.  All other fields are set by the compression
+   library and must not be updated by the application.
+
+     The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree.  This can be useful for custom
+   memory management.  The compression library attaches no meaning to the
+   opaque value.
+
+     zalloc must return Z_NULL if there is not enough memory for the object.
+   If zlib is used in a multi-threaded application, zalloc and zfree must be
+   thread safe.
+
+     On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this if
+   the symbol MAXSEG_64K is defined (see zconf.h).  WARNING: On MSDOS, pointers
+   returned by zalloc for objects of exactly 65536 bytes *must* have their
+   offset normalized to zero.  The default allocation function provided by this
+   library ensures this (see zutil.c).  To reduce memory requirements and avoid
+   any allocation of 64K objects, at the expense of compression ratio, compile
+   the library with -DMAX_WBITS=14 (see zconf.h).
+
+     The fields total_in and total_out can be used for statistics or progress
+   reports.  After compression, total_in holds the total size of the
+   uncompressed data and may be saved for use in the decompressor (particularly
+   if the decompressor wants to decompress everything in a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1
+#define Z_SYNC_FLUSH    2
+#define Z_FULL_FLUSH    3
+#define Z_FINISH        4
+#define Z_BLOCK         5
+#define Z_TREES         6
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_RLE                 3
+#define Z_FIXED               4
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_TEXT     1
+#define Z_ASCII    Z_TEXT   /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+
+                        /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is not
+   compatible with the zlib.h header file used by the application.  This check
+   is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+     Initializes the internal stream state for compression.  The fields
+   zalloc, zfree and opaque must be initialized before by the caller.  If
+   zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+   allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+   1 gives best speed, 9 gives best compression, 0 gives no compression at all
+   (the input data is simply copied a block at a time).  Z_DEFAULT_COMPRESSION
+   requests a default compromise between speed and compression (currently
+   equivalent to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if level is not a valid compression level, or
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).  msg is set to null
+   if there is no error message.  deflateInit does not perform any compression:
+   this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+    deflate compresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full.  It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+    The detailed semantics are as follows.  deflate performs one or both of the
+  following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly.  If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary (in interactive applications).  Some
+    output may be provided even if flush is not set.
+
+    Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming more
+  output, and updating avail_in or avail_out accordingly; avail_out should
+  never be zero before the call.  The application can consume the compressed
+  output when it wants, for example when the output buffer is full (avail_out
+  == 0), or after each call of deflate().  If deflate returns Z_OK and with
+  zero avail_out, it must be called again after making room in the output
+  buffer because there might be more output pending.
+
+    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+  decide how much data to accumulate before producing output, in order to
+  maximize compression.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+  flushed to the output buffer and the output is aligned on a byte boundary, so
+  that the decompressor can get all input data available so far.  (In
+  particular avail_in is zero after the call if enough output space has been
+  provided before the call.) Flushing may degrade compression for some
+  compression algorithms and so it should be used only when necessary.  This
+  completes the current deflate block and follows it with an empty stored block
+  that is three bits plus filler bits to the next byte, followed by four bytes
+  (00 00 ff ff).
+
+    If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+  output buffer, but the output is not aligned to a byte boundary.  All of the
+  input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+  This completes the current deflate block and follows it with an empty fixed
+  codes block that is 10 bits long.  This assures that enough bytes are output
+  in order for the decompressor to finish the block before the empty fixed code
+  block.
+
+    If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+  for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+  seven bits of the current block are held to be written as the next byte after
+  the next deflate block is completed.  In this case, the decompressor may not
+  be provided enough bits at this point in order to complete decompression of
+  the data provided so far to the compressor.  It may need to wait for the next
+  block to be emitted.  This is for advanced applications that need to control
+  the emission of deflate blocks.
+
+    If flush is set to Z_FULL_FLUSH, all output is flushed as with
+  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+  restart from this point if previous compressed data has been damaged or if
+  random access is desired.  Using Z_FULL_FLUSH too often can seriously degrade
+  compression.
+
+    If deflate returns with avail_out == 0, this function must be called again
+  with the same value of the flush parameter and more output space (updated
+  avail_out), until the flush is complete (deflate returns with non-zero
+  avail_out).  In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+  avail_out is greater than six to avoid repeated flush markers due to
+  avail_out == 0 on return.
+
+    If the parameter flush is set to Z_FINISH, pending input is processed,
+  pending output is flushed and deflate returns with Z_STREAM_END if there was
+  enough output space; if deflate returns with Z_OK, this function must be
+  called again with Z_FINISH and more output space (updated avail_out) but no
+  more input data, until it returns with Z_STREAM_END or an error.  After
+  deflate has returned Z_STREAM_END, the only possible operations on the stream
+  are deflateReset or deflateEnd.
+
+    Z_FINISH can be used immediately after deflateInit if all the compression
+  is to be done in a single step.  In this case, avail_out must be at least the
+  value returned by deflateBound (see below).  Then deflate is guaranteed to
+  return Z_STREAM_END.  If not enough output space is provided, deflate will
+  not return Z_STREAM_END, and it must be called again as described above.
+
+    deflate() sets strm->adler to the adler32 checksum of all input read
+  so far (that is, total_in bytes).
+
+    deflate() may update strm->data_type if it can make a good guess about
+  the input data type (Z_BINARY or Z_TEXT).  In doubt, the data is considered
+  binary.  This field is only for information purposes and does not affect the
+  compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible
+  (for example avail_in or avail_out was zero).  Note that Z_BUF_ERROR is not
+  fatal, and deflate() can be called again with more input and more output
+  space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any pending
+   output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded).  In the error case, msg
+   may be set but then points to a static string (which must not be
+   deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+     Initializes the internal stream state for decompression.  The fields
+   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+   the caller.  If next_in is not Z_NULL and avail_in is large enough (the
+   exact value depends on the compression method), inflateInit determines the
+   compression method from the zlib header and allocates all data structures
+   accordingly; otherwise the allocation will be deferred to the first call of
+   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+   use default allocation functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+   invalid, such as a null pointer to the structure.  msg is set to null if
+   there is no error message.  inflateInit does not perform any decompression
+   apart from possibly reading the zlib header if present: actual decompression
+   will be done by inflate().  (So next_in and avail_in may be modified, but
+   next_out and avail_out are unused and unchanged.) The current implementation
+   of inflateInit() does not process any header information -- that is deferred
+   until inflate() is called.
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+    inflate decompresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full.  It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+  The detailed semantics are as follows.  inflate performs one or both of the
+  following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly.  If not all input can be processed (because there is not
+    enough room in the output buffer), next_in is updated and processing will
+    resume at this point for the next call of inflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there is
+    no more input data or no more space in the output buffer (see below about
+    the flush parameter).
+
+    Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming more
+  output, and updating the next_* and avail_* values accordingly.  The
+  application can consume the uncompressed output when it wants, for example
+  when the output buffer is full (avail_out == 0), or after each call of
+  inflate().  If inflate returns Z_OK and with zero avail_out, it must be
+  called again after making room in the output buffer because there might be
+  more output pending.
+
+    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+  Z_BLOCK, or Z_TREES.  Z_SYNC_FLUSH requests that inflate() flush as much
+  output as possible to the output buffer.  Z_BLOCK requests that inflate()
+  stop if and when it gets to the next deflate block boundary.  When decoding
+  the zlib or gzip format, this will cause inflate() to return immediately
+  after the header and before the first block.  When doing a raw inflate,
+  inflate() will go ahead and process the first block, and will return when it
+  gets to the end of that block, or when it runs out of data.
+
+    The Z_BLOCK option assists in appending to or combining deflate streams.
+  Also to assist in this, on return inflate() will set strm->data_type to the
+  number of unused bits in the last byte taken from strm->next_in, plus 64 if
+  inflate() is currently decoding the last block in the deflate stream, plus
+  128 if inflate() returned immediately after decoding an end-of-block code or
+  decoding the complete header up to just before the first byte of the deflate
+  stream.  The end-of-block will not be indicated until all of the uncompressed
+  data from that block has been written to strm->next_out.  The number of
+  unused bits may in general be greater than seven, except when bit 7 of
+  data_type is set, in which case the number of unused bits will be less than
+  eight.  data_type is set as noted here every time inflate() returns for all
+  flush options, and so can be used to determine the amount of currently
+  consumed input in bits.
+
+    The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+  end of each deflate block header is reached, before any actual data in that
+  block is decoded.  This allows the caller to determine the length of the
+  deflate block header for later use in random access within a deflate block.
+  256 is added to the value of strm->data_type when inflate() returns
+  immediately after reaching the end of the deflate block header.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error.  However if all decompression is to be performed in a single step (a
+  single call of inflate), the parameter flush should be set to Z_FINISH.  In
+  this case all pending input is processed and all pending output is flushed;
+  avail_out must be large enough to hold all of the uncompressed data for the
+  operation to complete.  (The size of the uncompressed data may have been
+  saved by the compressor for this purpose.) The use of Z_FINISH is not
+  required to perform an inflation in one step.  However it may be used to
+  inform inflate that a faster approach can be used for the single inflate()
+  call.  Z_FINISH also informs inflate to not maintain a sliding window if the
+  stream completes, which reduces inflate's memory footprint.  If the stream
+  does not complete, either because not all of the stream is provided or not
+  enough output space is provided, then a sliding window will be allocated and
+  inflate() can be called again to continue the operation as if Z_NO_FLUSH had
+  been used.
+
+     In this implementation, inflate() always flushes as much output as
+  possible to the output buffer, and always uses the faster approach on the
+  first call.  So the effects of the flush parameter in this implementation are
+  on the return value of inflate() as noted below, when inflate() returns early
+  when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+  memory for a sliding window when Z_FINISH is used.
+
+     If a preset dictionary is needed after this call (see inflateSetDictionary
+  below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
+  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+  strm->adler to the Adler-32 checksum of all output produced so far (that is,
+  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+  below.  At the end of the stream, inflate() checks that its computed adler32
+  checksum is equal to that saved by the compressor and returns Z_STREAM_END
+  only if the checksum is correct.
+
+    inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+  deflate data.  The header type is detected automatically, if requested when
+  initializing with inflateInit2().  Any information contained in the gzip
+  header is not retained, so applications that need that information should
+  instead use raw inflate, see inflateInit2() below, or inflateBack() and
+  perform their own processing of the gzip header and trailer.  When processing
+  gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+  producted so far.  The CRC-32 is checked against the gzip trailer.
+
+    inflate() returns Z_OK if some progress has been made (more input processed
+  or more output produced), Z_STREAM_END if the end of the compressed data has
+  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+  corrupted (input stream not conforming to the zlib format or incorrect check
+  value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+  next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory,
+  Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+  output buffer when Z_FINISH is used.  Note that Z_BUF_ERROR is not fatal, and
+  inflate() can be called again with more input and more output space to
+  continue decompressing.  If Z_DATA_ERROR is returned, the application may
+  then call inflateSync() to look for a good compression block if a partial
+  recovery of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any pending
+   output.
+
+     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+   was inconsistent.  In the error case, msg may be set but then points to a
+   static string (which must not be deallocated).
+*/
+
+
+                        /* Advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+                                     int  level,
+                                     int  method,
+                                     int  windowBits,
+                                     int  memLevel,
+                                     int  strategy));
+
+     This is another version of deflateInit with more compression options.  The
+   fields next_in, zalloc, zfree and opaque must be initialized before by the
+   caller.
+
+     The method parameter is the compression method.  It must be Z_DEFLATED in
+   this version of the library.
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer).  It should be in the range 8..15 for this
+   version of the library.  Larger values of this parameter result in better
+   compression at the expense of memory usage.  The default value is 15 if
+   deflateInit is used instead.
+
+     windowBits can also be -8..-15 for raw deflate.  In this case, -windowBits
+   determines the window size.  deflate() will then generate raw deflate data
+   with no zlib header or trailer, and will not compute an adler32 check value.
+
+     windowBits can also be greater than 15 for optional gzip encoding.  Add
+   16 to windowBits to write a simple gzip header and trailer around the
+   compressed data instead of a zlib wrapper.  The gzip header will have no
+   file name, no extra data, no comment, no modification time (set to zero), no
+   header crc, and the operating system will be set to 255 (unknown).  If a
+   gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+     The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state.  memLevel=1 uses minimum memory but is
+   slow and reduces compression ratio; memLevel=9 uses maximum memory for
+   optimal speed.  The default value is 8.  See zconf.h for total memory usage
+   as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm.  Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match), or Z_RLE to limit match distances to one (run-length
+   encoding).  Filtered data consists mostly of small values with a somewhat
+   random distribution.  In this case, the compression algorithm is tuned to
+   compress them better.  The effect of Z_FILTERED is to force more Huffman
+   coding and less string matching; it is somewhat intermediate between
+   Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY.  Z_RLE is designed to be almost as
+   fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data.  The
+   strategy parameter only affects the compression ratio but not the
+   correctness of the compressed output even if it is not set appropriately.
+   Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+   decoder for special applications.
+
+     deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+   method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+   incompatible with the version assumed by the caller (ZLIB_VERSION).  msg is
+   set to null if there is no error message.  deflateInit2 does not perform any
+   compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the compression dictionary from the given byte sequence
+   without producing any compressed output.  When using the zlib format, this
+   function must be called immediately after deflateInit, deflateInit2 or
+   deflateReset, and before any call of deflate.  When doing raw deflate, this
+   function must be called either before any call of deflate, or immediately
+   after the completion of a deflate block, i.e. after all input has been
+   consumed and all output has been delivered when using any of the flush
+   options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH.  The
+   compressor and decompressor must use exactly the same dictionary (see
+   inflateSetDictionary).
+
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary.  Using a
+   dictionary is most useful when the data to be compressed is short and can be
+   predicted with good accuracy; the data can then be compressed better than
+   with the default empty dictionary.
+
+     Depending on the size of the compression data structures selected by
+   deflateInit or deflateInit2, a part of the dictionary may in effect be
+   discarded, for example if the dictionary is larger than the window size
+   provided in deflateInit or deflateInit2.  Thus the strings most likely to be
+   useful should be put at the end of the dictionary, not at the front.  In
+   addition, the current implementation of deflate will use at most the window
+   size minus 262 bytes of the provided dictionary.
+
+     Upon return of this function, strm->adler is set to the adler32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor.  (The adler32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.) If a raw deflate was requested, then the
+   adler32 value is not computed and strm->adler is not set.
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
+   inconsistent (for example if deflate has already been called for this stream
+   or if not at a block boundary for raw deflate).  deflateSetDictionary does
+   not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter.  The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and can
+   consume lots of memory.
+
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being Z_NULL).  msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit,
+   but does not free and reallocate all the internal compression state.  The
+   stream will keep the same compression level and any other attributes that
+   may have been set by deflateInit2.
+
+     deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+                                      int level,
+                                      int strategy));
+/*
+     Dynamically update the compression level and compression strategy.  The
+   interpretation of level and strategy is as in deflateInit2.  This can be
+   used to switch between compression and straight copy of the input data, or
+   to switch to a different kind of input data requiring a different strategy.
+   If the compression level is changed, the input available so far is
+   compressed with the old level (and may be flushed); the new level will take
+   effect only at the next call of deflate().
+
+     Before the call of deflateParams, the stream state must be set as for
+   a call of deflate(), since the currently available input may have to be
+   compressed and flushed.  In particular, strm->avail_out must be non-zero.
+
+     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if
+   strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+                                    int good_length,
+                                    int max_lazy,
+                                    int nice_length,
+                                    int max_chain));
+/*
+     Fine tune deflate's internal compression parameters.  This should only be
+   used by someone who understands the algorithm used by zlib's deflate for
+   searching for the best matching string, and even then only by the most
+   fanatic optimizer trying to squeeze out the last compressed bit for their
+   specific input data.  Read the deflate.c source code for the meaning of the
+   max_lazy, good_length, nice_length, and max_chain parameters.
+
+     deflateTune() can be called after deflateInit() or deflateInit2(), and
+   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+                                       uLong sourceLen));
+/*
+     deflateBound() returns an upper bound on the compressed size after
+   deflation of sourceLen bytes.  It must be called after deflateInit() or
+   deflateInit2(), and after deflateSetHeader(), if used.  This would be used
+   to allocate an output buffer for deflation in a single pass, and so would be
+   called before deflate().  If that first deflate() call is provided the
+   sourceLen input bytes, an output buffer allocated to the size returned by
+   deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+   to return Z_STREAM_END.  Note that it is possible for the compressed size to
+   be larger than the value returned by deflateBound() if flush options other
+   than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+                                       unsigned *pending,
+                                       int *bits));
+/*
+     deflatePending() returns the number of bytes and bits of output that have
+   been generated, but not yet provided in the available output.  The bytes not
+   provided would be due to the available output space having being consumed.
+   The number of bits of output not provided are between 0 and 7, where they
+   await more bits to join them in order to fill out a full byte.  If pending
+   or bits are Z_NULL, then those values are not set.
+
+     deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+ */
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     deflatePrime() inserts bits in the deflate output stream.  The intent
+   is that this function is used to start off the deflate output with the bits
+   leftover from a previous deflate stream when appending to it.  As such, this
+   function can only be used for raw deflate, and must be used before the first
+   deflate() call after a deflateInit2() or deflateReset().  bits must be less
+   than or equal to 16, and that many of the least significant bits of value
+   will be inserted in the output.
+
+     deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+   room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+   source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+     deflateSetHeader() provides gzip header information for when a gzip
+   stream is requested by deflateInit2().  deflateSetHeader() may be called
+   after deflateInit2() or deflateReset() and before the first call of
+   deflate().  The text, time, os, extra field, name, and comment information
+   in the provided gz_header structure are written to the gzip header (xflag is
+   ignored -- the extra flags are set according to the compression level).  The
+   caller must assure that, if not Z_NULL, name and comment are terminated with
+   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+   available there.  If hcrc is true, a gzip header crc is included.  Note that
+   the current versions of the command-line version of gzip (up through version
+   1.3.x) do not support header crc's, and will report that it is a "multi-part
+   gzip file" and give up.
+
+     If deflateSetHeader is not used, the default gzip header has text false,
+   the time set to zero, and os set to 255, with no extra, name, or comment
+   fields.  The gzip header is returned to the default state by deflateReset().
+
+     deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+                                     int  windowBits));
+
+     This is another version of inflateInit with an extra parameter.  The
+   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+   before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library.  The default value is 15 if inflateInit is used
+   instead.  windowBits must be greater than or equal to the windowBits value
+   provided to deflateInit2() while compressing, or it must be equal to 15 if
+   deflateInit2() was not used.  If a compressed stream with a larger window
+   size is given as input, inflate() will return with the error code
+   Z_DATA_ERROR instead of trying to allocate a larger window.
+
+     windowBits can also be zero to request that inflate use the window size in
+   the zlib header of the compressed stream.
+
+     windowBits can also be -8..-15 for raw inflate.  In this case, -windowBits
+   determines the window size.  inflate() will then process raw deflate data,
+   not looking for a zlib or gzip header, not generating a check value, and not
+   looking for any check values for comparison at the end of the stream.  This
+   is for use with other formats that use the deflate compressed data format
+   such as zip.  Those formats provide their own check values.  If a custom
+   format is developed using the raw deflate format for compressed data, it is
+   recommended that a check value such as an adler32 or a crc32 be applied to
+   the uncompressed data as is done in the zlib, gzip, and zip formats.  For
+   most applications, the zlib format should be used as is.  Note that comments
+   above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+     windowBits can also be greater than 15 for optional gzip decoding.  Add
+   32 to windowBits to enable zlib and gzip decoding with automatic header
+   detection, or add 16 to decode only the gzip format (the zlib format will
+   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is a
+   crc32 instead of an adler32.
+
+     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+   invalid, such as a null pointer to the structure.  msg is set to null if
+   there is no error message.  inflateInit2 does not perform any decompression
+   apart from possibly reading the zlib header if present: actual decompression
+   will be done by inflate().  (So next_in and avail_in may be modified, but
+   next_out and avail_out are unused and unchanged.) The current implementation
+   of inflateInit2() does not process any header information -- that is
+   deferred until inflate() is called.
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the decompression dictionary from the given uncompressed byte
+   sequence.  This function must be called immediately after a call of inflate,
+   if that call returned Z_NEED_DICT.  The dictionary chosen by the compressor
+   can be determined from the adler32 value returned by that call of inflate.
+   The compressor and decompressor must use exactly the same dictionary (see
+   deflateSetDictionary).  For raw inflate, this function can be called at any
+   time to set the dictionary.  If the provided dictionary is smaller than the
+   window and there is already data in the window, then the provided dictionary
+   will amend what's there.  The application must insure that the dictionary
+   that was used for compression is provided.
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect adler32 value).  inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
+                                             Bytef *dictionary,
+                                             uInt  *dictLength));
+/*
+     Returns the sliding dictionary being maintained by inflate.  dictLength is
+   set to the number of bytes in the dictionary, and that many bytes are copied
+   to dictionary.  dictionary must have enough space, where 32768 bytes is
+   always enough.  If inflateGetDictionary() is called with dictionary equal to
+   Z_NULL, then only the dictionary length is returned, and nothing is copied.
+   Similary, if dictLength is Z_NULL, then it is not set.
+
+     inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+   stream state is inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+     Skips invalid compressed data until a possible full flush point (see above
+   for the description of deflate with Z_FULL_FLUSH) can be found, or until all
+   available input is skipped.  No output is provided.
+
+     inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+   All full flush points have this pattern, but not all occurrences of this
+   pattern are full flush points.
+
+     inflateSync returns Z_OK if a possible full flush point has been found,
+   Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+   has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+   In the success case, the application may save the current current value of
+   total_in which indicates where valid compressed data was found.  In the
+   error case, the application may repeatedly call inflateSync, providing more
+   input each time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when randomly accessing a large stream.  The
+   first pass through the stream can periodically record the inflate state,
+   allowing restarting inflate at those points when randomly accessing the
+   stream.
+
+     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being Z_NULL).  msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate all the internal decompression state.  The
+   stream will keep attributes that may have been set by inflateInit2.
+
+     inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+                                      int windowBits));
+/*
+     This function is the same as inflateReset, but it also permits changing
+   the wrap and window size requests.  The windowBits parameter is interpreted
+   the same as it is for inflateInit2.
+
+     inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+   the windowBits parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     This function inserts bits in the inflate input stream.  The intent is
+   that this function is used to start inflating at a bit position in the
+   middle of a byte.  The provided bits will be used before any bytes are used
+   from next_in.  This function should only be used with raw inflate, and
+   should be used before the first inflate() call after inflateInit2() or
+   inflateReset().  bits must be less than or equal to 16, and that many of the
+   least significant bits of value will be inserted in the input.
+
+     If bits is negative, then the input stream bit buffer is emptied.  Then
+   inflatePrime() can be called again to put bits in the buffer.  This is used
+   to clear out bits leftover after feeding inflate a block description prior
+   to feeding inflate codes.
+
+     inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+     This function returns two values, one in the lower 16 bits of the return
+   value, and the other in the remaining upper bits, obtained by shifting the
+   return value down 16 bits.  If the upper value is -1 and the lower value is
+   zero, then inflate() is currently decoding information outside of a block.
+   If the upper value is -1 and the lower value is non-zero, then inflate is in
+   the middle of a stored block, with the lower value equaling the number of
+   bytes from the input remaining to copy.  If the upper value is not -1, then
+   it is the number of bits back from the current bit position in the input of
+   the code (literal or length/distance pair) currently being processed.  In
+   that case the lower value is the number of bytes already emitted for that
+   code.
+
+     A code is being processed if inflate is waiting for more input to complete
+   decoding of the code, or if it has completed decoding but is waiting for
+   more output space to write the literal or match data.
+
+     inflateMark() is used to mark locations in the input data for random
+   access, which may be at bit positions, and to note those cases where the
+   output of a code may span boundaries of random access blocks.  The current
+   location in the input stream can be determined from avail_in and data_type
+   as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+     inflateMark returns the value noted above or -1 << 16 if the provided
+   source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+     inflateGetHeader() requests that gzip header information be stored in the
+   provided gz_header structure.  inflateGetHeader() may be called after
+   inflateInit2() or inflateReset(), and before the first call of inflate().
+   As inflate() processes the gzip stream, head->done is zero until the header
+   is completed, at which time head->done is set to one.  If a zlib stream is
+   being decoded, then head->done is set to -1 to indicate that there will be
+   no gzip header information forthcoming.  Note that Z_BLOCK or Z_TREES can be
+   used to force inflate() to return immediately after header processing is
+   complete and before any actual data is decompressed.
+
+     The text, time, xflags, and os fields are filled in with the gzip header
+   contents.  hcrc is set to true if there is a header CRC.  (The header CRC
+   was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+   contains the maximum number of bytes to write to extra.  Once done is true,
+   extra_len contains the actual extra field length, and extra contains the
+   extra field, or that field truncated if extra_max is less than extra_len.
+   If name is not Z_NULL, then up to name_max characters are written there,
+   terminated with a zero unless the length is greater than name_max.  If
+   comment is not Z_NULL, then up to comm_max characters are written there,
+   terminated with a zero unless the length is greater than comm_max.  When any
+   of extra, name, or comment are not Z_NULL and the respective field is not
+   present in the header, then that field is set to Z_NULL to signal its
+   absence.  This allows the use of deflateSetHeader() with the returned
+   structure to duplicate the header.  However if those fields are set to
+   allocated memory, then the application will need to save those pointers
+   elsewhere so that they can be eventually freed.
+
+     If inflateGetHeader is not used, then the header information is simply
+   discarded.  The header is always checked for validity, including the header
+   CRC if present.  inflateReset() will reset the process to discard the header
+   information.  The application would need to call inflateGetHeader() again to
+   retrieve the header from the next gzip stream.
+
+     inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+                                        unsigned char FAR *window));
+
+     Initialize the internal stream state for decompression using inflateBack()
+   calls.  The fields zalloc, zfree and opaque in strm must be initialized
+   before the call.  If zalloc and zfree are Z_NULL, then the default library-
+   derived memory allocation routines are used.  windowBits is the base two
+   logarithm of the window size, in the range 8..15.  window is a caller
+   supplied buffer of that size.  Except for special applications where it is
+   assured that deflate was used with small window sizes, windowBits must be 15
+   and a 32K byte window must be supplied to be able to decompress general
+   deflate streams.
+
+     See inflateBack() for the usage of these routines.
+
+     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+   the parameters are invalid, Z_MEM_ERROR if the internal state could not be
+   allocated, or Z_VERSION_ERROR if the version of the library does not match
+   the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *,
+                                z_const unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+                                    in_func in, void FAR *in_desc,
+                                    out_func out, void FAR *out_desc));
+/*
+     inflateBack() does a raw inflate with a single call using a call-back
+   interface for input and output.  This is potentially more efficient than
+   inflate() for file i/o applications, in that it avoids copying between the
+   output and the sliding window by simply making the window itself the output
+   buffer.  inflate() can be faster on modern CPUs when used with large
+   buffers.  inflateBack() trusts the application to not change the output
+   buffer passed by the output function, at least until inflateBack() returns.
+
+     inflateBackInit() must be called first to allocate the internal state
+   and to initialize the state with the user-provided window buffer.
+   inflateBack() may then be used multiple times to inflate a complete, raw
+   deflate stream with each call.  inflateBackEnd() is then called to free the
+   allocated state.
+
+     A raw deflate stream is one with no zlib or gzip header or trailer.
+   This routine would normally be used in a utility that reads zip or gzip
+   files and writes out uncompressed files.  The utility would decode the
+   header and process the trailer on its own, hence this routine expects only
+   the raw deflate stream to decompress.  This is different from the normal
+   behavior of inflate(), which expects either a zlib or gzip header and
+   trailer around the deflate stream.
+
+     inflateBack() uses two subroutines supplied by the caller that are then
+   called by inflateBack() for input and output.  inflateBack() calls those
+   routines until it reads a complete deflate stream and writes out all of the
+   uncompressed data, or until it encounters an error.  The function's
+   parameters and return types are defined above in the in_func and out_func
+   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the
+   number of bytes of provided input, and a pointer to that input in buf.  If
+   there is no input available, in() must return zero--buf is ignored in that
+   case--and inflateBack() will return a buffer error.  inflateBack() will call
+   out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].  out()
+   should return zero on success, or non-zero on failure.  If out() returns
+   non-zero, inflateBack() will return with an error.  Neither in() nor out()
+   are permitted to change the contents of the window provided to
+   inflateBackInit(), which is also the buffer that out() uses to write from.
+   The length written by out() will be at most the window size.  Any non-zero
+   amount of input may be provided by in().
+
+     For convenience, inflateBack() can be provided input on the first call by
+   setting strm->next_in and strm->avail_in.  If that input is exhausted, then
+   in() will be called.  Therefore strm->next_in must be initialized before
+   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called
+   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in
+   must also be initialized, and then if strm->avail_in is not zero, input will
+   initially be taken from strm->next_in[0 ..  strm->avail_in - 1].
+
+     The in_desc and out_desc parameters of inflateBack() is passed as the
+   first parameter of in() and out() respectively when they are called.  These
+   descriptors can be optionally used to pass any information that the caller-
+   supplied in() and out() functions need to do their job.
+
+     On return, inflateBack() will set strm->next_in and strm->avail_in to
+   pass back any unused input that was provided by the last in() call.  The
+   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+   if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+   in the deflate stream (in which case strm->msg is set to indicate the nature
+   of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+   In the case of Z_BUF_ERROR, an input or output error can be distinguished
+   using strm->next_in which will be Z_NULL only if in() returned an error.  If
+   strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+   non-zero.  (in() will always be called before out(), so strm->next_in is
+   assured to be defined if out() returns non-zero.) Note that inflateBack()
+   cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+     All memory allocated by inflateBackInit() is freed.
+
+     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+   state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+     1.0: size of uInt
+     3.2: size of uLong
+     5.4: size of voidpf (pointer)
+     7.6: size of z_off_t
+
+    Compiler, assembler, and debug options:
+     8: DEBUG
+     9: ASMV or ASMINF -- use ASM code
+     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+     11: 0 (reserved)
+
+    One-time table building (smaller code, but not thread-safe if true):
+     12: BUILDFIXED -- build static block decoding tables when needed
+     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+     14,15: 0 (reserved)
+
+    Library content (indicates missing functionality):
+     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+                          deflate code when not needed)
+     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+                    and decode gzip streams (to avoid linking crc code)
+     18-19: 0 (reserved)
+
+    Operation variations (changes in library functionality):
+     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+     21: FASTEST -- deflate algorithm with only one, lowest compression level
+     22,23: 0 (reserved)
+
+    The sprintf variant used by gzprintf (zero is best):
+     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+     26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+    Remainder:
+     27-31: 0 (reserved)
+ */
+
+#ifndef Z_SOLO
+
+                        /* utility functions */
+
+/*
+     The following utility functions are implemented on top of the basic
+   stream-oriented functions.  To simplify the interface, some default options
+   are assumed (compression level and memory usage, standard memory allocation
+   functions).  The source code of these utility functions can be modified if
+   you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
+                                 const Bytef *source, uLong sourceLen));
+/*
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer.  Upon entry, destLen is the total size
+   of the destination buffer, which must be at least the value returned by
+   compressBound(sourceLen).  Upon exit, destLen is the actual size of the
+   compressed buffer.
+
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
+                                  const Bytef *source, uLong sourceLen,
+                                  int level));
+/*
+     Compresses the source buffer into the destination buffer.  The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer.  Upon entry, destLen is the total size of the
+   destination buffer, which must be at least the value returned by
+   compressBound(sourceLen).  Upon exit, destLen is the actual size of the
+   compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+     compressBound() returns an upper bound on the compressed size after
+   compress() or compress2() on sourceLen bytes.  It would be used before a
+   compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
+                                   const Bytef *source, uLong sourceLen));
+/*
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer.  Upon entry, destLen is the total size
+   of the destination buffer, which must be large enough to hold the entire
+   uncompressed data.  (The size of the uncompressed data must have been saved
+   previously by the compressor and transmitted to the decompressor by some
+   mechanism outside the scope of this compression library.) Upon exit, destLen
+   is the actual size of the uncompressed buffer.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.  In
+   the case where there is not enough room, uncompress() will fill the output
+   buffer with the uncompressed data up to that point.
+*/
+
+                        /* gzip file access functions */
+
+/*
+     This library supports reading and writing files in gzip (.gz) format with
+   an interface similar to that of stdio, using the functions that start with
+   "gz".  The gzip format is different from the zlib format.  gzip is a gzip
+   wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef struct gzFile_s *gzFile;    /* semi-opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+     Opens a gzip (.gz) file for reading or writing.  The mode parameter is as
+   in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+   a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+   compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+   for fixed code compression as in "wb9F".  (See the description of
+   deflateInit2 for more information about the strategy parameter.)  'T' will
+   request transparent writing or appending with no compression and not using
+   the gzip format.
+
+     "a" can be used instead of "w" to request that the gzip stream that will
+   be written be appended to the file.  "+" will result in an error, since
+   reading and writing to the same gzip file is not supported.  The addition of
+   "x" when writing will create the file exclusively, which fails if the file
+   already exists.  On systems that support it, the addition of "e" when
+   reading or writing will set the flag to close the file on an execve() call.
+
+     These functions, as well as gzip, will read and decode a sequence of gzip
+   streams in a file.  The append function of gzopen() can be used to create
+   such a file.  (Also see gzflush() for another way to do this.)  When
+   appending, gzopen does not test whether the file begins with a gzip stream,
+   nor does it look for the end of the gzip streams to begin appending.  gzopen
+   will simply append a gzip stream to the existing file.
+
+     gzopen can be used to read a file which is not in gzip format; in this
+   case gzread will directly read from the file without decompression.  When
+   reading, this will be detected automatically by looking for the magic two-
+   byte gzip header.
+
+     gzopen returns NULL if the file could not be opened, if there was
+   insufficient memory to allocate the gzFile state, or if an invalid mode was
+   specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+   errno can be checked to determine if the reason gzopen failed was that the
+   file could not be opened.
+*/
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+     gzdopen associates a gzFile with the file descriptor fd.  File descriptors
+   are obtained from calls like open, dup, creat, pipe or fileno (if the file
+   has been previously opened with fopen).  The mode parameter is as in gzopen.
+
+     The next call of gzclose on the returned gzFile will also close the file
+   descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+   fd.  If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+   mode);.  The duplicated descriptor should be saved to avoid a leak, since
+   gzdopen does not close fd if it fails.  If you are using fileno() to get the
+   file descriptor from a FILE *, then you will have to use dup() to avoid
+   double-close()ing the file descriptor.  Both gzclose() and fclose() will
+   close the associated file descriptor, so they need to have different file
+   descriptors.
+
+     gzdopen returns NULL if there was insufficient memory to allocate the
+   gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+   provided, or '+' was provided), or if fd is -1.  The file descriptor is not
+   used until the next gz* read, write, seek, or close operation, so gzdopen
+   will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+     Set the internal buffer size used by this library's functions.  The
+   default buffer size is 8192 bytes.  This function must be called after
+   gzopen() or gzdopen(), and before any other calls that read or write the
+   file.  The buffer memory allocation is always deferred to the first read or
+   write.  Two buffers are allocated, either both of the specified size when
+   writing, or one of the specified size and the other twice that size when
+   reading.  A larger buffer size of, for example, 64K or 128K bytes will
+   noticeably increase the speed of decompression (reading).
+
+     The new buffer size also affects the maximum length for gzprintf().
+
+     gzbuffer() returns 0 on success, or -1 on failure, such as being called
+   too late.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+     Dynamically update the compression level or strategy.  See the description
+   of deflateInit2 for the meaning of these parameters.
+
+     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+   opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+     Reads the given number of uncompressed bytes from the compressed file.  If
+   the input file is not in gzip format, gzread copies the given number of
+   bytes into the buffer directly from the file.
+
+     After reaching the end of a gzip stream in the input, gzread will continue
+   to read, looking for another gzip stream.  Any number of gzip streams may be
+   concatenated in the input file, and will all be decompressed by gzread().
+   If something other than a gzip stream is encountered after a gzip stream,
+   that remaining trailing garbage is ignored (and no error is returned).
+
+     gzread can be used to read a gzip file that is being concurrently written.
+   Upon reaching the end of the input, gzread will return with the available
+   data.  If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+   gzclearerr can be used to clear the end of file indicator in order to permit
+   gzread to be tried again.  Z_OK indicates that a gzip stream was completed
+   on the last gzread.  Z_BUF_ERROR indicates that the input file ended in the
+   middle of a gzip stream.  Note that gzread does not return -1 in the event
+   of an incomplete gzip stream.  This error is deferred until gzclose(), which
+   will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+   stream.  Alternatively, gzerror can be used before gzclose to detect this
+   case.
+
+     gzread returns the number of uncompressed bytes actually read, less than
+   len for end of file, or -1 for error.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+                                voidpc buf, unsigned len));
+/*
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of uncompressed bytes written or 0 in case of
+   error.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
+/*
+     Converts, formats, and writes the arguments to the compressed file under
+   control of the format string, as in fprintf.  gzprintf returns the number of
+   uncompressed bytes actually written, or 0 in case of error.  The number of
+   uncompressed bytes written is limited to 8191, or one less than the buffer
+   size given to gzbuffer().  The caller should assure that this limit is not
+   exceeded.  If it is exceeded, then gzprintf() will return an error (0) with
+   nothing written.  In this case, there may also be a buffer overflow with
+   unpredictable consequences, which is possible only if zlib was compiled with
+   the insecure functions sprintf() or vsprintf() because the secure snprintf()
+   or vsnprintf() functions were not available.  This can be determined using
+   zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+     Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+
+     gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+     Reads bytes from the compressed file until len-1 characters are read, or a
+   newline character is read and transferred to buf, or an end-of-file
+   condition is encountered.  If any characters are read or if len == 1, the
+   string is terminated with a null character.  If no characters are read due
+   to an end-of-file or len < 1, then the buffer is left untouched.
+
+     gzgets returns buf which is a null-terminated string, or it returns NULL
+   for end-of-file or in case of error.  If there was an error, the contents at
+   buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+     Writes c, converted to an unsigned char, into the compressed file.  gzputc
+   returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+     Reads one byte from the compressed file.  gzgetc returns this byte or -1
+   in case of end of file or error.  This is implemented as a macro for speed.
+   As such, it does not do all of the checking the other functions do.  I.e.
+   it does not check to see if file is NULL, nor whether the structure file
+   points to has been clobbered or not.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+     Push one character back onto the stream to be read as the first character
+   on the next read.  At least one character of push-back is allowed.
+   gzungetc() returns the character pushed, or -1 on failure.  gzungetc() will
+   fail if c is -1, and may fail if a character has been pushed but not read
+   yet.  If gzungetc is used immediately after gzopen or gzdopen, at least the
+   output buffer size of pushed characters is allowed.  (See gzbuffer above.)
+   The pushed character will be discarded if the stream is repositioned with
+   gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+     Flushes all pending output into the compressed file.  The parameter flush
+   is as in the deflate() function.  The return value is the zlib error number
+   (see function gzerror below).  gzflush is only permitted when writing.
+
+     If the flush parameter is Z_FINISH, the remaining data is written and the
+   gzip stream is completed in the output.  If gzwrite() is called again, a new
+   gzip stream will be started in the output.  gzread() is able to read such
+   concatented gzip streams.
+
+     gzflush should be called only when strictly necessary because it will
+   degrade compression if called too often.
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+                                   z_off_t offset, int whence));
+
+     Sets the starting position for the next gzread or gzwrite on the given
+   compressed file.  The offset represents a number of bytes in the
+   uncompressed data stream.  The whence parameter is defined as in lseek(2);
+   the value SEEK_END is not supported.
+
+     If the file is opened for reading, this function is emulated but can be
+   extremely slow.  If the file is opened for writing, only forward seeks are
+   supported; gzseek then compresses a sequence of zeroes up to the new
+   starting position.
+
+     gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error, in
+   particular if the file is opened for writing and the new starting position
+   would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
+/*
+     Rewinds the given file. This function is supported only for reading.
+
+     gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
+
+     Returns the starting position for the next gzread or gzwrite on the given
+   compressed file.  This position represents a number of bytes in the
+   uncompressed data stream, and is zero when starting, even if appending or
+   reading a gzip stream from the middle of a file using gzdopen().
+
+     gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+     Returns the current offset in the file being read or written.  This offset
+   includes the count of bytes that precede the gzip stream, for example when
+   appending or when using gzdopen() for reading.  When reading, the offset
+   does not include as yet unused buffered input.  This information can be used
+   for a progress indicator.  On error, gzoffset() returns -1.
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+     Returns true (1) if the end-of-file indicator has been set while reading,
+   false (0) otherwise.  Note that the end-of-file indicator is set only if the
+   read tried to go past the end of the input, but came up short.  Therefore,
+   just like feof(), gzeof() may return false even if there is no more data to
+   read, in the event that the last read request was for the exact number of
+   bytes remaining in the input file.  This will happen if the input file size
+   is an exact multiple of the buffer size.
+
+     If gzeof() returns true, then the read functions will return no more data,
+   unless the end-of-file indicator is reset by gzclearerr() and the input file
+   has grown since the previous end of file was detected.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+     Returns true (1) if file is being copied directly while reading, or false
+   (0) if file is a gzip stream being decompressed.
+
+     If the input file is empty, gzdirect() will return true, since the input
+   does not contain a gzip stream.
+
+     If gzdirect() is used immediately after gzopen() or gzdopen() it will
+   cause buffers to be allocated to allow reading the file to determine if it
+   is a gzip file.  Therefore if gzbuffer() is used, it should be called before
+   gzdirect().
+
+     When writing, gzdirect() returns true (1) if transparent writing was
+   requested ("wT" for the gzopen() mode), or false (0) otherwise.  (Note:
+   gzdirect() is not needed when writing.  Transparent writing must be
+   explicitly requested, so the application already knows the answer.  When
+   linking statically, using gzdirect() will include all of the zlib code for
+   gzip file reading and decompression, which may not be desired.)
+*/
+
+ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
+/*
+     Flushes all pending output if necessary, closes the compressed file and
+   deallocates the (de)compression state.  Note that once file is closed, you
+   cannot call gzerror with file, since its structures have been deallocated.
+   gzclose must not be called more than once on the same file, just as free
+   must not be called more than once on the same allocation.
+
+     gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+   file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+   last read ended in the middle of a gzip stream, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+     Same as gzclose(), but gzclose_r() is only for use when reading, and
+   gzclose_w() is only for use when writing or appending.  The advantage to
+   using these instead of gzclose() is that they avoid linking in zlib
+   compression or decompression code that is not used when only reading or only
+   writing respectively.  If gzclose() is used, then both compression and
+   decompression code will be included the application when linking to a static
+   zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+     Returns the error message for the last error which occurred on the given
+   compressed file.  errnum is set to zlib error number.  If an error occurred
+   in the file system and not in the compression library, errnum is set to
+   Z_ERRNO and the application may consult errno to get the exact error code.
+
+     The application must not modify the returned string.  Future calls to
+   this function may invalidate the previously returned string.  If file is
+   closed, then the string previously returned by gzerror will no longer be
+   available.
+
+     gzerror() should be used to distinguish errors from end-of-file for those
+   functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+     Clears the error and end-of-file flags for file.  This is analogous to the
+   clearerr() function in stdio.  This is useful for continuing to read a gzip
+   file that is being written concurrently.
+*/
+
+#endif /* !Z_SOLO */
+
+                        /* checksum functions */
+
+/*
+     These functions are not related to compression but are exported
+   anyway because they might be useful in applications using the compression
+   library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum.  If buf is Z_NULL, this function returns the
+   required initial value for the checksum.
+
+     An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+   much faster.
+
+   Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+                                          z_off_t len2));
+
+     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
+   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of
+   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.  Note
+   that the z_off_t type (like off_t) is a signed integer.  If len2 is
+   negative, the result has no meaning or utility.
+*/
+
+ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
+/*
+     Update a running CRC-32 with the bytes buf[0..len-1] and return the
+   updated CRC-32.  If buf is Z_NULL, this function returns the required
+   initial value for the crc.  Pre- and post-conditioning (one's complement) is
+   performed within this function so it shouldn't be done by the application.
+
+   Usage example:
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+     Combine two CRC-32 check values into one.  For two sequences of bytes,
+   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32
+   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+   len2.
+*/
+
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
+                                      int windowBits, int memLevel,
+                                      int strategy, const char *version,
+                                      int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
+                                      const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+                                         unsigned char FAR *window,
+                                         const char *version,
+                                         int stream_size));
+#define deflateInit(strm, level) \
+        deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit(strm) \
+        inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                      (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+                      (int)sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+        inflateBackInit_((strm), (windowBits), (window), \
+                      ZLIB_VERSION, (int)sizeof(z_stream))
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure.  Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro.  The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously.  They can
+ * only be used by the gzgetc() macro.  You have been warned.
+ */
+struct gzFile_s {
+    unsigned have;
+    unsigned char *next;
+    z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));  /* backward compatibility */
+#ifdef Z_PREFIX_SET
+#  undef z_gzgetc
+#  define z_gzgetc(g) \
+          ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#else
+#  define gzgetc(g) \
+          ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#endif
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#ifdef Z_LARGE64
+   ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+   ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+   ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+   ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+   ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+   ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
+#  ifdef Z_PREFIX_SET
+#    define z_gzopen z_gzopen64
+#    define z_gzseek z_gzseek64
+#    define z_gztell z_gztell64
+#    define z_gzoffset z_gzoffset64
+#    define z_adler32_combine z_adler32_combine64
+#    define z_crc32_combine z_crc32_combine64
+#  else
+#    define gzopen gzopen64
+#    define gzseek gzseek64
+#    define gztell gztell64
+#    define gzoffset gzoffset64
+#    define adler32_combine adler32_combine64
+#    define crc32_combine crc32_combine64
+#  endif
+#  ifndef Z_LARGE64
+     ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+     ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+     ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+     ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+     ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+     ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#  endif
+#else
+   ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+   ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+   ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+   ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+
+#else /* Z_SOLO */
+
+   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
+/* hack for buggy compilers */
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+    struct internal_state {int dummy;};
+#endif
+
+/* undocumented functions */
+ZEXTERN const char   * ZEXPORT zError           OF((int));
+ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table    OF((void));
+ZEXTERN int            ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int            ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int            ZEXPORT deflateResetKeep OF((z_streamp));
+#if defined(_WIN32) && !defined(Z_SOLO)
+ZEXTERN gzFile         ZEXPORT gzopen_w OF((const wchar_t *path,
+                                            const char *mode));
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+ZEXTERN int            ZEXPORTVA gzvprintf Z_ARG((gzFile file,
+                                                  const char *format,
+                                                  va_list va));
+#  endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/zutil.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/zutil.c
new file mode 100755
index 0000000..2fe2a71
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/zutil.c
@@ -0,0 +1,321 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#ifndef NO_DUMMY_DECL
+struct internal_state      {int dummy;}; /* for buggy compilers */
+#endif
+
+z_const char * const z_errmsg[10] = {
+"need dictionary",     /* Z_NEED_DICT       2  */
+"stream end",          /* Z_STREAM_END      1  */
+"",                    /* Z_OK              0  */
+"file error",          /* Z_ERRNO         (-1) */
+"stream error",        /* Z_STREAM_ERROR  (-2) */
+"data error",          /* Z_DATA_ERROR    (-3) */
+"insufficient memory", /* Z_MEM_ERROR     (-4) */
+"buffer error",        /* Z_BUF_ERROR     (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+    return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+    uLong flags;
+
+    flags = 0;
+    switch ((int)(sizeof(uInt))) {
+    case 2:     break;
+    case 4:     flags += 1;     break;
+    case 8:     flags += 2;     break;
+    default:    flags += 3;
+    }
+    switch ((int)(sizeof(uLong))) {
+    case 2:     break;
+    case 4:     flags += 1 << 2;        break;
+    case 8:     flags += 2 << 2;        break;
+    default:    flags += 3 << 2;
+    }
+    switch ((int)(sizeof(voidpf))) {
+    case 2:     break;
+    case 4:     flags += 1 << 4;        break;
+    case 8:     flags += 2 << 4;        break;
+    default:    flags += 3 << 4;
+    }
+    switch ((int)(sizeof(z_off_t))) {
+    case 2:     break;
+    case 4:     flags += 1 << 6;        break;
+    case 8:     flags += 2 << 6;        break;
+    default:    flags += 3 << 6;
+    }
+#ifdef DEBUG
+    flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+    flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+    flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+    flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+    flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+    flags += 1L << 16;
+#endif
+#ifdef NO_GZIP
+    flags += 1L << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+    flags += 1L << 20;
+#endif
+#ifdef FASTEST
+    flags += 1L << 21;
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifdef NO_vsnprintf
+    flags += 1L << 25;
+#    ifdef HAS_vsprintf_void
+    flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_vsnprintf_void
+    flags += 1L << 26;
+#    endif
+#  endif
+#else
+    flags += 1L << 24;
+#  ifdef NO_snprintf
+    flags += 1L << 25;
+#    ifdef HAS_sprintf_void
+    flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_snprintf_void
+    flags += 1L << 26;
+#    endif
+#  endif
+#endif
+    return flags;
+}
+
+#ifdef DEBUG
+
+#  ifndef verbose
+#    define verbose 0
+#  endif
+int ZLIB_INTERNAL z_verbose = verbose;
+
+void ZLIB_INTERNAL z_error (m)
+    char *m;
+{
+    fprintf(stderr, "%s\n", m);
+    exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+    int err;
+{
+    return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+    /* The Microsoft C Run-Time Library for Windows CE doesn't have
+     * errno.  We define it as a global variable to simplify porting.
+     * Its value is always 0 and should not be used.
+     */
+    int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void ZLIB_INTERNAL zmemcpy(dest, source, len)
+    Bytef* dest;
+    const Bytef* source;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = *source++; /* ??? to be unrolled */
+    } while (--len != 0);
+}
+
+int ZLIB_INTERNAL zmemcmp(s1, s2, len)
+    const Bytef* s1;
+    const Bytef* s2;
+    uInt  len;
+{
+    uInt j;
+
+    for (j = 0; j < len; j++) {
+        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+    }
+    return 0;
+}
+
+void ZLIB_INTERNAL zmemzero(dest, len)
+    Bytef* dest;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = 0;  /* ??? to be unrolled */
+    } while (--len != 0);
+}
+#endif
+
+#ifndef Z_SOLO
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+    voidpf org_ptr;
+    voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    voidpf buf = opaque; /* just to make some compilers happy */
+    ulg bsize = (ulg)items*size;
+
+    /* If we allocate less than 65520 bytes, we assume that farmalloc
+     * will return a usable pointer which doesn't have to be normalized.
+     */
+    if (bsize < 65520L) {
+        buf = farmalloc(bsize);
+        if (*(ush*)&buf != 0) return buf;
+    } else {
+        buf = farmalloc(bsize + 16L);
+    }
+    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+    table[next_ptr].org_ptr = buf;
+
+    /* Normalize the pointer to seg:0 */
+    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+    *(ush*)&buf = 0;
+    table[next_ptr++].new_ptr = buf;
+    return buf;
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+    int n;
+    if (*(ush*)&ptr != 0) { /* object < 64K */
+        farfree(ptr);
+        return;
+    }
+    /* Find the original pointer */
+    for (n = 0; n < next_ptr; n++) {
+        if (ptr != table[n].new_ptr) continue;
+
+        farfree(table[n].org_ptr);
+        while (++n < next_ptr) {
+            table[n-1] = table[n];
+        }
+        next_ptr--;
+        return;
+    }
+    ptr = opaque; /* just to make some compilers happy */
+    Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+#  define _halloc  halloc
+#  define _hfree   hfree
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    return _halloc((long)items, size);
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp  malloc OF((uInt size));
+extern voidp  calloc OF((uInt items, uInt size));
+extern void   free   OF((voidpf ptr));
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
+    voidpf opaque;
+    unsigned items;
+    unsigned size;
+{
+    if (opaque) items += size - size; /* make compiler happy */
+    return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+                              (voidpf)calloc(items, size);
+}
+
+void ZLIB_INTERNAL zcfree (opaque, ptr)
+    voidpf opaque;
+    voidpf ptr;
+{
+    free(ptr);
+    if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
+
+#endif /* !Z_SOLO */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/zutil.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/zutil.h
new file mode 100755
index 0000000..24ab06b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/deps/zlib/zutil.h
@@ -0,0 +1,253 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#ifdef HAVE_HIDDEN
+#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+#  define ZLIB_INTERNAL
+#endif
+
+#include "zlib.h"
+
+#if defined(STDC) && !defined(Z_SOLO)
+#  if !(defined(_WIN32_WCE) && defined(_MSC_VER))
+#    include <stddef.h>
+#  endif
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+
+#ifdef Z_SOLO
+   typedef long ptrdiff_t;  /* guess -- will be caught if guess is wrong */
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char  uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long  ulg;
+
+extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+  return (strm->msg = ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+        /* common constants */
+
+#ifndef DEF_WBITS
+#  define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+        /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+#  define OS_CODE  0x00
+#  ifndef Z_SOLO
+#    if defined(__TURBOC__) || defined(__BORLANDC__)
+#      if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+         /* Allow compilation with ANSI keywords only enabled */
+         void _Cdecl farfree( void *block );
+         void *_Cdecl farmalloc( unsigned long nbytes );
+#      else
+#        include <alloc.h>
+#      endif
+#    else /* MSC or DJGPP */
+#      include <malloc.h>
+#    endif
+#  endif
+#endif
+
+#ifdef AMIGA
+#  define OS_CODE  0x01
+#endif
+
+#if defined(VAXC) || defined(VMS)
+#  define OS_CODE  0x02
+#  define F_OPEN(name, mode) \
+     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#if defined(ATARI) || defined(atarist)
+#  define OS_CODE  0x05
+#endif
+
+#ifdef OS2
+#  define OS_CODE  0x06
+#  if defined(M_I86) && !defined(Z_SOLO)
+#    include <malloc.h>
+#  endif
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+#  define OS_CODE  0x07
+#  ifndef Z_SOLO
+#    if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#      include <unix.h> /* for fdopen */
+#    else
+#      ifndef fdopen
+#        define fdopen(fd,mode) NULL /* No fdopen() */
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef TOPS20
+#  define OS_CODE  0x0a
+#endif
+
+#ifdef WIN32
+#  ifndef __CYGWIN__  /* Cygwin is Unix, not Win32 */
+#    define OS_CODE  0x0b
+#  endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+#  define OS_CODE  0x0f
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+#  define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
+#  if defined(_WIN32_WCE)
+#    define fdopen(fd,mode) NULL /* No fdopen() */
+#    ifndef _PTRDIFF_T_DEFINED
+       typedef int ptrdiff_t;
+#      define _PTRDIFF_T_DEFINED
+#    endif
+#  else
+#    define fdopen(fd,type)  _fdopen(fd,type)
+#  endif
+#endif
+
+#if defined(__BORLANDC__) && !defined(MSDOS)
+  #pragma warn -8004
+  #pragma warn -8008
+  #pragma warn -8066
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_WIN32) && \
+    (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
+    ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+    ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#endif
+
+        /* common defaults */
+
+#ifndef OS_CODE
+#  define OS_CODE  0x03  /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+#  define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+         /* functions */
+
+#if defined(pyr) || defined(Z_SOLO)
+#  define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+  * You may have to use the same strategy for Borland C (untested).
+  * The __SC__ check is for Symantec.
+  */
+#  define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+#  define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+#    define zmemcpy _fmemcpy
+#    define zmemcmp _fmemcmp
+#    define zmemzero(dest, len) _fmemset(dest, 0, len)
+#  else
+#    define zmemcpy memcpy
+#    define zmemcmp memcmp
+#    define zmemzero(dest, len) memset(dest, 0, len)
+#  endif
+#else
+   void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+   int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+   void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  include <stdio.h>
+   extern int ZLIB_INTERNAL z_verbose;
+   extern void ZLIB_INTERNAL z_error OF((char *m));
+#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
+#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
+#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+#ifndef Z_SOLO
+   voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+                                    unsigned size));
+   void ZLIB_INTERNAL zcfree  OF((voidpf opaque, voidpf ptr));
+#endif
+
+#define ZALLOC(strm, items, size) \
+           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+/* Reverse the bytes in a 32-bit value */
+#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+                    (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+#endif /* ZUTIL_H */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/docs/checkout-internals.md b/app/server/vendor/rugged-0.23.3/vendor/libgit2/docs/checkout-internals.md
new file mode 100755
index 0000000..6147ffd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/docs/checkout-internals.md
@@ -0,0 +1,204 @@
+Checkout Internals
+==================
+
+Checkout has to handle a lot of different cases.  It examines the
+differences between the target tree, the baseline tree and the working
+directory, plus the contents of the index, and groups files into five
+categories:
+
+1. UNMODIFIED - Files that match in all places.
+2. SAFE - Files where the working directory and the baseline content
+   match that can be safely updated to the target.
+3. DIRTY/MISSING - Files where the working directory differs from the
+   baseline but there is no conflicting change with the target.  One
+   example is a file that doesn't exist in the working directory - no
+   data would be lost as a result of writing this file.  Which action
+   will be taken with these files depends on the options you use.
+4. CONFLICTS - Files where changes in the working directory conflict
+   with changes to be applied by the target.  If conflicts are found,
+   they prevent any other modifications from being made (although there
+   are options to override that and force the update, of course).
+5. UNTRACKED/IGNORED - Files in the working directory that are untracked
+   or ignored (i.e. only in the working directory, not the other places).
+
+Right now, this classification is done via 3 iterators (for the three
+trees), with a final lookup in the index.  At some point, this may move to
+a 4 iterator version to incorporate the index better.
+
+The actual checkout is done in five phases (at least right now).
+
+1. The diff between the baseline and the target tree is used as a base
+   list of possible updates to be applied.
+2. Iterate through the diff and the working directory, building a list of
+   actions to be taken (and sending notifications about conflicts and
+   dirty files).
+3. Remove any files / directories as needed (because alphabetical
+   iteration means that an untracked directory will end up sorted *after*
+   a blob that should be checked out with the same name).
+4. Update all blobs.
+5. Update all submodules (after 4 in case a new .gitmodules blob was
+   checked out)
+
+Checkout could be driven either off a target-to-workdir diff or a
+baseline-to-target diff.  There are pros and cons of each.
+
+Target-to-workdir means the diff includes every file that could be
+modified, which simplifies bookkeeping, but the code to constantly refer
+back to the baseline gets complicated.
+
+Baseline-to-target has simpler code because the diff defines the action to
+take, but needs special handling for untracked and ignored files, if they
+need to be removed.
+
+The current checkout implementation is based on a baseline-to-target diff.
+
+
+Picking Actions
+===============
+
+The most interesting aspect of this is phase 2, picking the actions that
+should be taken.  There are a lot of corner cases, so it may be easier to
+start by looking at the rules for a simple 2-iterator diff:
+
+Key
+---
+- B1,B2,B3 - blobs with different SHAs,
+- Bi       - ignored blob (WD only)
+- T1,T2,T3 - trees with different SHAs,
+- Ti       - ignored tree (WD only)
+- x        - nothing
+
+Diff with 2 non-workdir iterators
+---------------------------------
+
+|    | Old | New |                                                            |
+|----|-----|-----|------------------------------------------------------------|
+|  0 |   x |   x | nothing                                                    |
+|  1 |   x |  B1 | added blob                                                 |
+|  2 |   x |  T1 | added tree                                                 |
+|  3 |  B1 |   x | removed blob                                               |
+|  4 |  B1 |  B1 | unmodified blob                                            |
+|  5 |  B1 |  B2 | modified blob                                              |
+|  6 |  B1 |  T1 | typechange blob -> tree                                    |
+|  7 |  T1 |   x | removed tree                                               |
+|  8 |  T1 |  B1 | typechange tree -> blob                                    |
+|  9 |  T1 |  T1 | unmodified tree                                            |
+| 10 |  T1 |  T2 | modified tree (implies modified/added/removed blob inside) |
+
+
+Now, let's make the "New" iterator into a working directory iterator, so
+we replace "added" items with either untracked or ignored, like this:
+
+Diff with non-work & workdir iterators
+--------------------------------------
+
+|    | Old | New |                                                            |
+|----|-----|-----|------------------------------------------------------------|
+|  0 |  x  | x   | nothing                                                    |
+|  1 |  x  | B1  | untracked blob                                             |
+|  2 |  x  | Bi  | ignored file                                               |
+|  3 |  x  | T1  | untracked tree                                             |
+|  4 |  x  | Ti  | ignored tree                                               |
+|  5 | B1  | x   | removed blob                                               |
+|  6 | B1  | B1  | unmodified blob                                            |
+|  7 | B1  | B2  | modified blob                                              |
+|  8 | B1  | T1  | typechange blob -> tree                                    |
+|  9 | B1  | Ti  | removed blob AND ignored tree as separate items            |
+| 10 | T1  | x   | removed tree                                               |
+| 11 | T1  | B1  | typechange tree -> blob                                    |
+| 12 | T1  | Bi  | removed tree AND ignored blob as separate items            |
+| 13 | T1  | T1  | unmodified tree                                            |
+| 14 | T1  | T2  | modified tree (implies modified/added/removed blob inside) |
+
+Note: if there is a corresponding entry in the old tree, then a working
+directory item won't be ignored (i.e. no Bi or Ti for tracked items).
+
+
+Now, expand this to three iterators: a baseline tree, a target tree, and
+an actual working directory tree:
+
+Checkout From 3 Iterators (2 not workdir, 1 workdir)
+----------------------------------------------------
+
+(base == old HEAD; target == what to checkout; actual == working dir)
+
+|     |base | target | actual/workdir |                                                                    |
+|-----|-----|------- |----------------|--------------------------------------------------------------------|
+|  0  |   x |      x |      x         | nothing                                                            |
+|  1  |   x |      x | B1/Bi/T1/Ti    | untracked/ignored blob/tree (SAFE)                                 |
+|  2+ |   x |     B1 |      x         | add blob (SAFE)                                                    |
+|  3  |   x |     B1 |     B1         | independently added blob (FORCEABLE-2)                             |
+|  4* |   x |     B1 | B2/Bi/T1/Ti    | add blob with content conflict (FORCEABLE-2)                       |
+|  5+ |   x |     T1 |      x         | add tree (SAFE)                                                    |
+|  6* |   x |     T1 |  B1/Bi         | add tree with blob conflict (FORCEABLE-2)                          |
+|  7  |   x |     T1 |   T1/i         | independently added tree (SAFE+MISSING)                            |
+|  8  |  B1 |      x |      x         | independently deleted blob (SAFE+MISSING)                          |
+|  9- |  B1 |      x |     B1         | delete blob (SAFE)                                                 |
+| 10- |  B1 |      x |     B2         | delete of modified blob (FORCEABLE-1)                              |
+| 11  |  B1 |      x |  T1/Ti         | independently deleted blob AND untrack/ign tree (SAFE+MISSING !!!) |
+| 12  |  B1 |     B1 |      x         | locally deleted blob (DIRTY || SAFE+CREATE)                        |
+| 13+ |  B1 |     B2 |      x         | update to deleted blob (SAFE+MISSING)                              |
+| 14  |  B1 |     B1 |     B1         | unmodified file (SAFE)                                             |
+| 15  |  B1 |     B1 |     B2         | locally modified file (DIRTY)                                      |
+| 16+ |  B1 |     B2 |     B1         | update unmodified blob (SAFE)                                      |
+| 17  |  B1 |     B2 |     B2         | independently updated blob (FORCEABLE-1)                           |
+| 18+ |  B1 |     B2 |     B3         | update to modified blob (FORCEABLE-1)                              |
+| 19  |  B1 |     B1 |  T1/Ti         | locally deleted blob AND untrack/ign tree (DIRTY)                  |
+| 20* |  B1 |     B2 |  T1/Ti         | update to deleted blob AND untrack/ign tree (F-1)                  |
+| 21+ |  B1 |     T1 |      x         | add tree with locally deleted blob (SAFE+MISSING)                  |
+| 22* |  B1 |     T1 |     B1         | add tree AND deleted blob (SAFE)                                   |
+| 23* |  B1 |     T1 |     B2         | add tree with delete of modified blob (F-1)                        |
+| 24  |  B1 |     T1 |     T1         | add tree with deleted blob (F-1)                                   |
+| 25  |  T1 |      x |      x         | independently deleted tree (SAFE+MISSING)                          |
+| 26  |  T1 |      x |  B1/Bi         | independently deleted tree AND untrack/ign blob (F-1)              |
+| 27- |  T1 |      x |     T1         | deleted tree (MAYBE SAFE)                                          |
+| 28+ |  T1 |     B1 |      x         | deleted tree AND added blob (SAFE+MISSING)                         |
+| 29  |  T1 |     B1 |     B1         | independently typechanged tree -> blob (F-1)                       |
+| 30+ |  T1 |     B1 |     B2         | typechange tree->blob with conflicting blob (F-1)                  |
+| 31* |  T1 |     B1 |  T1/T2         | typechange tree->blob (MAYBE SAFE)                                 |
+| 32+ |  T1 |     T1 |      x         | restore locally deleted tree (SAFE+MISSING)                        |
+| 33  |  T1 |     T1 |  B1/Bi         | locally typechange tree->untrack/ign blob (DIRTY)                  |
+| 34  |  T1 |     T1 |  T1/T2         | unmodified tree (MAYBE SAFE)                                       |
+| 35+ |  T1 |     T2 |      x         | update locally deleted tree (SAFE+MISSING)                         |
+| 36* |  T1 |     T2 |  B1/Bi         | update to tree with typechanged tree->blob conflict (F-1)          |
+| 37  |  T1 |     T2 | T1/T2/T3       | update to existing tree (MAYBE SAFE)                               |
+
+
+The number is followed by ' ' if no change is needed or '+' if the case
+needs to write to disk or '-' if something must be deleted and '*' if
+there should be a delete followed by an write.
+
+There are four tiers of safe cases:
+
+* SAFE         == completely safe to update
+* SAFE+MISSING == safe except the workdir is missing the expect content
+* MAYBE SAFE   == safe if workdir tree matches (or is missing) baseline
+                  content, which is unknown at this point
+* FORCEABLE == conflict unless FORCE is given
+* DIRTY     == no conflict but change is not applied unless FORCE
+
+Some slightly unusual circumstances:
+
+* 8 - parent dir is only deleted when file is, so parent will be left if
+    empty even though it would be deleted if the file were present
+* 11 - core git does not consider this a conflict but attempts to delete T1
+    and gives "unable to unlink file" error yet does not skip the rest
+    of the operation
+* 12 - without FORCE file is left deleted (i.e. not restored) so new wd is
+    dirty (and warning message "D file" is printed), with FORCE, file is
+    restored.
+* 24 - This should be considered MAYBE SAFE since effectively it is 7 and 8
+    combined, but core git considers this a conflict unless forced.
+* 26 - This combines two cases (1 & 25) (and also implied 8 for tree content)
+    which are ok on their own, but core git treat this as a conflict.
+    If not forced, this is a conflict.  If forced, this actually doesn't
+    have to write anything and leaves the new blob as an untracked file.
+* 32 - This is the only case where the baseline and target values match
+    and yet we will still write to the working directory.  In all other
+    cases, if baseline == target, we don't touch the workdir (it is
+    either already right or is "dirty").  However, since this case also
+    implies that a ?/B1/x case will exist as well, it can be skipped.
+
+Cases 3, 17, 24, 26, and 29 are all considered conflicts even though
+none of them will require making any updates to the working directory.
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/docs/diff-internals.md b/app/server/vendor/rugged-0.23.3/vendor/libgit2/docs/diff-internals.md
new file mode 100755
index 0000000..da4c5a1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/docs/diff-internals.md
@@ -0,0 +1,92 @@
+Diff is broken into four phases:
+
+1. Building a list of things that have changed.  These changes are called
+   deltas (git_diff_delta objects) and are grouped into a git_diff_list.
+2. Applying file similarity measurement for rename and copy detection (and
+   to potentially split files that have changed radically).  This step is
+   optional.
+3. Computing the textual diff for each delta.  Not all deltas have a
+   meaningful textual diff.  For those that do, the textual diff can
+   either be generated on the fly and passed to output callbacks or can be
+   turned into a git_diff_patch object.
+4. Formatting the diff and/or patch into standard text formats (such as
+   patches, raw lists, etc).
+
+In the source code, step 1 is implemented in `src/diff.c`, step 2 in
+`src/diff_tform.c`, step 3 in `src/diff_patch.c`, and step 4 in
+`src/diff_print.c`.  Additionally, when it comes to accessing file
+content, everything goes through diff drivers that are implemented in
+`src/diff_driver.c`.
+
+External Objects
+----------------
+
+* `git_diff_options` represents user choices about how a diff should be
+  performed and is passed to most diff generating functions.
+* `git_diff_file` represents an item on one side of a possible delta
+* `git_diff_delta` represents a pair of items that have changed in some
+  way - it contains two `git_diff_file` plus a status and other stuff.
+* `git_diff_list` is a list of deltas along with information about how
+  those particular deltas were found.
+* `git_diff_patch` represents the actual diff between a pair of items.  In
+  some cases, a delta may not have a corresponding patch, if the objects
+  are binary, for example.  The content of a patch will be a set of hunks
+  and lines.
+* A `hunk` is range of lines described by a `git_diff_range` (i.e.  "lines
+  10-20 in the old file became lines 12-23 in the new").  It will have a
+  header that compactly represents that information, and it will have a
+  number of lines of context surrounding added and deleted lines.
+* A `line` is simple a line of data along with a `git_diff_line_t` value
+  that tells how the data should be interpreted (e.g. context or added).
+
+Internal Objects
+----------------
+
+* `git_diff_file_content` is an internal structure that represents the
+  data on one side of an item to be diffed; it is an augmented
+  `git_diff_file` with more flags and the actual file data.
+
+    * it is created from a repository plus a) a git_diff_file, b) a git_blob,
+   or c) raw data and size
+    * there are three main operations on git_diff_file_content:
+    
+        * _initialization_ sets up the data structure and does what it can up to,
+          but not including loading and looking at the actual data
+        * _loading_ loads the data, preprocesses it (i.e. applies filters) and
+          potentially analyzes it (to decide if binary)
+        * _free_ releases loaded data and frees any allocated memory
+
+* The internal structure of a `git_diff_patch` stores the actual diff
+  between a pair of `git_diff_file_content` items
+
+    * it may be "unset" if the items are not diffable
+    * "empty" if the items are the same
+    * otherwise it will consist of a set of hunks each of which covers some
+      number of lines of context, additions and deletions
+    * a patch is created from two git_diff_file_content items
+    * a patch is fully instantiated in three phases:
+    
+        * initial creation and initialization
+        * loading of data and preliminary data examination
+        * diffing of data and optional storage of diffs
+    * (TBD) if a patch is asked to store the diffs and the size of the diff
+      is significantly smaller than the raw data of the two sides, then the
+      patch may be flattened using a pool of string data
+
+* `git_diff_output` is an internal structure that represents an output
+  target for a `git_diff_patch`
+    * It consists of file, hunk, and line callbacks, plus a payload
+    * There is a standard flattened output that can be used for plain text output
+    * Typically we use a `git_xdiff_output` which drives the callbacks via the
+      xdiff code taken from core Git.
+
+* `git_diff_driver` is an internal structure that encapsulates the logic
+  for a given type of file
+    * a driver is looked up based on the name and mode of a file.
+    * the driver can then be used to:
+        * determine if a file is binary (by attributes, by git_diff_options
+          settings, or by examining the content)
+        * give you a function pointer that is used to evaluate function context
+          for hunk headers
+    * At some point, the logic for getting a filtered version of file content
+      or calculating the OID of a file may be moved into the driver.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/docs/error-handling.md b/app/server/vendor/rugged-0.23.3/vendor/libgit2/docs/error-handling.md
new file mode 100755
index 0000000..2dbe64a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/docs/error-handling.md
@@ -0,0 +1,270 @@
+Error reporting in libgit2
+==========================
+
+Libgit2 tries to follow the POSIX style: functions return an `int` value
+with 0 (zero) indicating success and negative values indicating an error.
+There are specific negative error codes for each "expected failure"
+(e.g. `GIT_ENOTFOUND` for files that take a path which might be missing)
+and a generic error code (-1) for all critical or non-specific failures
+(e.g. running out of memory or system corruption).
+
+When a negative value is returned, an error message is also set.  The
+message can be accessed via the `giterr_last` function which will return a
+pointer to a `git_error` structure containing the error message text and
+the class of error (i.e. what part of the library generated the error).
+
+For instance: An object lookup by SHA prefix (`git_object_lookup_prefix`)
+has two expected failure cases: the SHA is not found at all which returns
+`GIT_ENOTFOUND` or the SHA prefix is ambiguous (i.e. two or more objects
+share the prefix) which returns `GIT_EAMBIGUOUS`.  There are any number of
+critical failures (such as a packfile being corrupted, a loose object
+having the wrong access permissions, etc.) all of which will return -1.
+When the object lookup is successful, it will return 0.
+
+If libgit2 was compiled with threads enabled (`-DTHREADSAFE=ON` when using
+CMake), then the error message will be kept in thread-local storage, so it
+will not be modified by other threads.  If threads are not enabled, then
+the error message is in global data.
+
+All of the error return codes, the `git_error` type, the error access
+functions, and the error classes are defined in `include/git2/errors.h`.
+See the documentation there for details on the APIs for accessing,
+clearing, and even setting error codes.
+
+When writing libgit2 code, please be smart and conservative when returning
+error codes.  Functions usually have a maximum of two or three "expected
+errors" and in most cases only one.  If you feel there are more possible
+expected error scenarios, then the API you are writing may be at too high
+a level for core libgit2.
+
+Example usage
+-------------
+
+When using libgit2, you will typically capture the return value from
+functions using an `int` variable and check to see if it is negative.
+When that happens, you can, if you wish, look at the specific value or
+look at the error message that was generated.
+
+~~~c
+{
+	git_repository *repo;
+	int error = git_repository_open(&repo, "path/to/repo");
+
+	if (error < 0) {
+		fprintf(stderr, "Could not open repository: %s\n", giterr_last()->message);
+		exit(1);
+	}
+
+	... use `repo` here ...
+
+	git_repository_free(repo); /* void function - no error return code */
+}
+~~~
+
+Some of the error return values do have meaning.  Optionally, you can look
+at the specific error values to decide what to do.
+
+~~~c
+{
+	git_repository *repo;
+	const char *path = "path/to/repo";
+	int error = git_repository_open(&repo, path);
+
+	if (error < 0) {
+		if (error == GIT_ENOTFOUND)
+			fprintf(stderr, "Could not find repository at path '%s'\n", path);
+		else
+			fprintf(stderr, "Unable to open repository: %s\n",
+				giterr_last()->message);
+		exit(1);
+	}
+
+	... happy ...
+}
+~~~
+
+Some of the higher-level language bindings may use a range of information
+from libgit2 to convert error return codes into exceptions, including the
+specific error return codes and even the class of error and the error
+message returned by `giterr_last`, but the full range of that logic is
+beyond the scope of this document.
+
+Example internal implementation
+-------------------------------
+
+Internally, libgit2 detects error scenarios, records error messages, and
+returns error values.  Errors from low-level functions are generally
+passed upwards (unless the higher level can either handle the error or
+wants to translate the error into something more meaningful).
+
+~~~c
+int git_repository_open(git_repository **repository, const char *path)
+{
+	/* perform some logic to open the repository */
+	if (p_exists(path) < 0) {
+		giterr_set(GITERR_REPOSITORY, "The path '%s' doesn't exist", path);
+		return GIT_ENOTFOUND;
+	}
+
+	...
+}
+~~~
+
+The public error API
+--------------------
+
+- `const git_error *giterr_last(void)`: The main function used to look up
+  the last error.  This may return NULL if no error has occurred.
+  Otherwise this should return a `git_error` object indicating the class
+  of error and the error message that was generated by the library.
+
+  The last error is stored in thread-local storage when libgit2 is
+  compiled with thread support, so you do not have to worry about another
+  thread overwriting the value.  When thread support is off, the last
+  error is a global value.
+
+  _Note_ There are some known bugs in the library where this may return
+  NULL even when an error code was generated.  Please report these as
+  bugs, but in the meantime, please code defensively and check for NULL
+  when calling this function.
+
+- `void geterr_clear(void)`: This function clears the last error.  The
+  library will call this when an error is generated by low level function
+  and the higher level function handles the error.
+
+  _Note_ There are some known bugs in the library where a low level
+  function's error message is not cleared by higher level code that
+  handles the error and returns zero.  Please report these as bugs, but in
+  the meantime, a zero return value from a libgit2 API does not guarantee
+  that `giterr_last()` will return NULL.
+
+- `void giterr_set_str(int error_class, const char *message)`: This
+  function can be used when writing a custom backend module to set the
+  libgit2 error message.  See the documentation on this function for its
+  use.  Normal usage of libgit2 will probably never need to call this API.
+
+- `void giterr_set_oom(void)`: This is a standard function for reporting
+  an out-of-memory error.  It is written in a manner that it doesn't have
+  to allocate any extra memory in order to record the error, so this is
+  the best way to report that scenario.
+
+Deviations from the standard
+----------------------------
+
+There are some public functions that do not return `int` values.  There
+are two primary cases:
+
+* `void` return values: If a function has a `void` return, then it will
+  never fail.  This primary will be used for object destructors.
+
+* `git_xyz *` return values: These are simple accessor functions where the
+  only meaningful error would typically be looking something up by index
+  and having the index be out of bounds.  In those cases, the function
+  will typically return NULL.
+
+* Boolean return values: There are some cases where a function cannot fail
+  and wants to return a boolean value.  In those cases, we try to return 1
+  for true and 0 for false.  These cases are rare and the return value for
+  the function should probably be an `unsigned int` to denote these cases.
+  If you find an exception, please open an issue and let's fix it.
+
+There are a few other exceptions to these rules here and there in the
+library, but those are extremely rare and should probably be converted
+over to other to more standard patterns for usage.  Feel free to open
+issues pointing these out.
+
+There are some known bugs in the library where some functions may return a
+negative value but not set an error message and some other functions may
+return zero (no error) and yet leave an error message set.  Please report
+these cases as issues and they will be fixed.  In the meanwhile, please
+code defensively, checking that the return value of `giterr_last` is not
+NULL before using it, and not relying on `giterr_last` to return NULL when
+a function returns 0 for success.
+
+The internal error API
+----------------------
+
+- `void giterr_set(int error_class, const char *fmt, ...)`: This is the
+  main internal function for setting an error.  It works like `printf` to
+  format the error message.  See the notes of `giterr_set_str` for a
+  general description of how error messages are stored (and also about
+  special handling for `error_class` of `GITERR_OS`).
+
+Writing error messages
+----------------------
+
+Here are some guidelines when writing error messages:
+
+- Use proper English, and an impersonal or past tenses: *The given path
+  does not exist*, *Failed to lookup object in ODB*
+
+- Use short, direct and objective messages. **One line, max**. libgit2 is
+  a low level library: think that all the messages reported will be thrown
+  as Ruby or Python exceptions. Think how long are common exception
+  messages in those languages.
+
+- **Do not add redundant information to the error message**, specially
+  information that can be inferred from the context.
+
+	E.g. in `git_repository_open`, do not report a message like "Failed to
+	open repository: path not found". Somebody is calling that
+	function. If it fails, they already know that the repository failed to
+	open!
+
+General guidelines for error reporting
+--------------------------------------
+
+- Libgit2 does not handle programming errors with these
+  functions. Programming errors are `assert`ed, and when their source is
+  internal, fixed as soon as possible. This is C, people.
+
+	Example of programming errors that would **not** be handled: passing
+    NULL to a function that expects a valid pointer; passing a `git_tree`
+    to a function that expects a `git_commit`. All these cases need to be
+    identified with `assert` and fixed asap.
+
+	Example of a runtime error: failing to parse a `git_tree` because it
+    contains invalid data. Failing to open a file because it doesn't exist
+    on disk. These errors are handled, a meaningful error message is set,
+    and an error code is returned.
+
+- In general, *do not* try to overwrite errors internally and *do*
+  propagate error codes from lower level functions to the higher level.
+  There are some cases where propagating an error code will be more
+  confusing rather than less, so there are some exceptions to this rule,
+  but the default behavior should be to simply clean up and pass the error
+  on up to the caller.
+
+    **WRONG**
+
+	~~~c
+	int git_commit_parent(...)
+	{
+		...
+
+		if (git_commit_lookup(parent, repo, parent_id) < 0) {
+			giterr_set(GITERR_COMMIT, "Overwrite lookup error message");
+			return -1; /* mask error code */
+		}
+
+		...
+	}
+	~~~
+
+	**RIGHT**
+
+	~~~c
+	int git_commit_parent(...)
+	{
+		...
+
+		error = git_commit_lookup(parent, repo, parent_id);
+		if (error < 0) {
+			/* cleanup intermediate objects if necessary */
+			/* leave error message and propagate error code */
+			return error;
+		}
+
+		...
+	}
+	~~~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/docs/merge-df_conflicts.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/docs/merge-df_conflicts.txt
new file mode 100755
index 0000000..09780ee
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/docs/merge-df_conflicts.txt
@@ -0,0 +1,41 @@
+Anc / Our / Thr represent the ancestor / ours / theirs side of a merge
+from branch "branch" into HEAD.  Workdir represents the expected files in
+the working directory.  Index represents the expected files in the index,
+with stage markers.
+
+    Anc  Our  Thr    Workdir             Index
+1   D    D
+               D/F   D/F                 D/F [0]
+
+2   D    D+          D~HEAD (mod/del)    D/F [0]
+               D/F   D/F                 D [1]
+                                         D [2]
+
+3   D          D     D/F                 D/F [0]
+         D/F
+
+4   D          D+    D~branch (mod/del)  D/F [0]
+         D/F         D/F                 D [1]
+                                         D [3]
+
+5   D                D/F (add/add)       D/F [2]
+         D/F                             D/F [3]
+               D/F
+
+6   D/F  D/F         D                   D [0]
+               D
+
+7   D/F  D/F+        D/F (mod/del)       D/F [1]
+               D     D~branch (fil/dir)  D/F [2]
+                                         D [3]
+
+8   D/F        D/F   D                   D [0]
+         D
+
+9   D/F        D/F+  D/F (mod/del)       D/F [1]
+         D           D~HEAD (fil/dir)    D [2]
+                                         D/F [3]
+
+10  D/F              D/F (fil/dir)       D/F [0]
+         D           D~HEAD              D [2]
+               D
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/.gitignore b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/.gitignore
new file mode 100755
index 0000000..0e49159
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/.gitignore
@@ -0,0 +1,15 @@
+general
+showindex
+diff
+rev-list
+blame
+cat-file
+init
+log
+rev-parse
+remote
+status
+tag
+for-each-ref
+describe
+*.dSYM
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/CMakeLists.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/CMakeLists.txt
new file mode 100755
index 0000000..596be45
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/CMakeLists.txt
@@ -0,0 +1,16 @@
+FILE(GLOB_RECURSE SRC_EXAMPLE_GIT2 network/*.c network/*.h)
+ADD_EXECUTABLE(cgit2 ${SRC_EXAMPLE_GIT2})
+IF(WIN32 OR ANDROID)
+	TARGET_LINK_LIBRARIES(cgit2 git2)
+ELSE()
+	TARGET_LINK_LIBRARIES(cgit2 git2 pthread)
+ENDIF()
+
+FILE(GLOB SRC_EXAMPLE_APPS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c)
+FOREACH(src_app ${SRC_EXAMPLE_APPS})
+	STRING(REPLACE ".c" "" app_name ${src_app})
+	IF(NOT ${app_name} STREQUAL "common")
+		ADD_EXECUTABLE(${app_name} ${src_app} "common.c")
+		TARGET_LINK_LIBRARIES(${app_name} git2)
+	ENDIF()
+ENDFOREACH()
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/COPYING b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/COPYING
new file mode 100755
index 0000000..0e259d4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/COPYING
@@ -0,0 +1,121 @@
+Creative Commons Legal Code
+
+CC0 1.0 Universal
+
+    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+    HEREUNDER.
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator
+and subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for
+the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without fear
+of later claims of infringement build upon, modify, incorporate in other
+works, reuse and redistribute as freely as possible in any form whatsoever
+and for any purposes, including without limitation commercial purposes.
+These owners may contribute to the Commons to promote the ideal of a free
+culture and the further production of creative, cultural and scientific
+works, or to gain reputation or greater distribution for their Work in
+part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or she
+is an owner of Copyright and Related Rights in the Work, voluntarily
+elects to apply CC0 to the Work and publicly distribute the Work under its
+terms, with knowledge of his or her Copyright and Related Rights in the
+Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not
+limited to, the following:
+
+  i. the right to reproduce, adapt, distribute, perform, display,
+     communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or performer(s);
+iii. publicity and privacy rights pertaining to a person's image or
+     likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a Work,
+     subject to the limitations in paragraph 4(a), below;
+  v. rights protecting the extraction, dissemination, use and reuse of data
+     in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+     European Parliament and of the Council of 11 March 1996 on the legal
+     protection of databases, and under any national implementation
+     thereof, including any amended or successor version of such
+     directive); and
+vii. other similar, equivalent or corresponding rights throughout the
+     world based on applicable law or treaty, and any national
+     implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention
+of, applicable law, Affirmer hereby overtly, fully, permanently,
+irrevocably and unconditionally waives, abandons, and surrenders all of
+Affirmer's Copyright and Related Rights and associated claims and causes
+of action, whether now known or unknown (including existing as well as
+future claims and causes of action), in the Work (i) in all territories
+worldwide, (ii) for the maximum duration provided by applicable law or
+treaty (including future time extensions), (iii) in any current or future
+medium and for any number of copies, and (iv) for any purpose whatsoever,
+including without limitation commercial, advertising or promotional
+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
+member of the public at large and to the detriment of Affirmer's heirs and
+successors, fully intending that such Waiver shall not be subject to
+revocation, rescission, cancellation, termination, or any other legal or
+equitable action to disrupt the quiet enjoyment of the Work by the public
+as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason
+be judged legally invalid or ineffective under applicable law, then the
+Waiver shall be preserved to the maximum extent permitted taking into
+account Affirmer's express Statement of Purpose. In addition, to the
+extent the Waiver is so judged Affirmer hereby grants to each affected
+person a royalty-free, non transferable, non sublicensable, non exclusive,
+irrevocable and unconditional license to exercise Affirmer's Copyright and
+Related Rights in the Work (i) in all territories worldwide, (ii) for the
+maximum duration provided by applicable law or treaty (including future
+time extensions), (iii) in any current or future medium and for any number
+of copies, and (iv) for any purpose whatsoever, including without
+limitation commercial, advertising or promotional purposes (the
+"License"). The License shall be deemed effective as of the date CC0 was
+applied by Affirmer to the Work. Should any part of the License for any
+reason be judged legally invalid or ineffective under applicable law, such
+partial invalidity or ineffectiveness shall not invalidate the remainder
+of the License, and in such case Affirmer hereby affirms that he or she
+will not (i) exercise any of his or her remaining Copyright and Related
+Rights in the Work or (ii) assert any associated claims and causes of
+action with respect to the Work, in either case contrary to Affirmer's
+express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+    surrendered, licensed or otherwise affected by this document.
+ b. Affirmer offers the Work as-is and makes no representations or
+    warranties of any kind concerning the Work, express, implied,
+    statutory or otherwise, including without limitation warranties of
+    title, merchantability, fitness for a particular purpose, non
+    infringement, or the absence of latent or other defects, accuracy, or
+    the present or absence of errors, whether or not discoverable, all to
+    the greatest extent permissible under applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+    that may apply to the Work or any use thereof, including without
+    limitation any person's Copyright and Related Rights in the Work.
+    Further, Affirmer disclaims responsibility for obtaining any necessary
+    consents, permissions or other rights required for any use of the
+    Work.
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+    party to this document and has no duty or obligation with respect to
+    this CC0 or use of the Work.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/Makefile b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/Makefile
new file mode 100755
index 0000000..bd7e92d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/Makefile
@@ -0,0 +1,17 @@
+.PHONY: all
+
+CC = gcc
+CFLAGS = -g -I../include -I../src -Wall -Wextra -Wmissing-prototypes -Wno-missing-field-initializers
+LFLAGS = -L../build -lgit2 -lz
+APPS = general showindex diff rev-list cat-file status log rev-parse init blame tag remote
+APPS += for-each-ref
+APPS += describe
+
+all: $(APPS)
+
+% : %.c
+	$(CC) -o $@ common.c $(CFLAGS) $< $(LFLAGS)
+
+clean:
+	$(RM) $(APPS)
+	$(RM) -r *.dSYM
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/README.md b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/README.md
new file mode 100755
index 0000000..769c4b2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/README.md
@@ -0,0 +1,22 @@
+libgit2 examples
+================
+
+These examples are a mixture of basic emulation of core Git command line
+functions and simple snippets demonstrating libgit2 API usage (for use
+with Docurium).  As a whole, they are not vetted carefully for bugs, error
+handling, and cross-platform compatibility in the same manner as the rest
+of the code in libgit2, so copy with caution.
+
+That being said, you are welcome to copy code from these examples as
+desired when using libgit2. They have been [released to the public domain][cc0],
+so there are no restrictions on their use.
+
+[cc0]: COPYING
+
+For annotated HTML versions, see the "Examples" section of:
+
+    http://libgit2.github.com/libgit2
+
+such as:
+
+    http://libgit2.github.com/libgit2/ex/HEAD/general.html
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/add.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/add.c
new file mode 100755
index 0000000..0101ab9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/add.c
@@ -0,0 +1,159 @@
+/*
+ * libgit2 "add" example - shows how to modify the index
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "common.h"
+#include <assert.h>
+
+enum print_options {
+	SKIP = 1,
+	VERBOSE = 2,
+	UPDATE = 4,
+};
+
+struct print_payload {
+	enum print_options options;
+	git_repository *repo;
+};
+
+/* Forward declarations for helpers */
+static void parse_opts(int *options, int *count, int argc, char *argv[]);
+void init_array(git_strarray *array, int argc, char **argv);
+int print_matched_cb(const char *path, const char *matched_pathspec, void *payload);
+
+int main (int argc, char** argv)
+{
+	git_index_matched_path_cb matched_cb = NULL;
+	git_repository *repo = NULL;
+	git_index *index;
+	git_strarray array = {0};
+	int options = 0, count = 0;
+	struct print_payload payload = {0};
+
+	git_libgit2_init();
+
+	parse_opts(&options, &count, argc, argv);
+
+	init_array(&array, argc-count, argv+count);
+
+	check_lg2(git_repository_open(&repo, "."), "No git repository", NULL);
+	check_lg2(git_repository_index(&index, repo), "Could not open repository index", NULL);
+
+	if (options&VERBOSE || options&SKIP) {
+		matched_cb = &print_matched_cb;
+	}
+
+	payload.options = options;
+	payload.repo = repo;
+
+	if (options&UPDATE) {
+		git_index_update_all(index, &array, matched_cb, &payload);
+	} else {
+		git_index_add_all(index, &array, 0, matched_cb, &payload);
+	}
+
+	git_index_write(index);
+	git_index_free(index);
+	git_repository_free(repo);
+
+	git_libgit2_shutdown();
+
+	return 0;
+}
+
+int print_matched_cb(const char *path, const char *matched_pathspec, void *payload)
+{
+	struct print_payload p = *(struct print_payload*)(payload);
+	int ret;
+	git_status_t status;
+	(void)matched_pathspec;
+
+	if (git_status_file((unsigned int*)(&status), p.repo, path)) {
+		return -1; //abort
+	}
+
+	if (status & GIT_STATUS_WT_MODIFIED ||
+	         status & GIT_STATUS_WT_NEW) {
+		printf("add '%s'\n", path);
+		ret = 0;
+	} else {
+		ret = 1;
+	}
+
+	if(p.options & SKIP) {
+		ret = 1;
+	}
+
+	return ret;
+}
+
+void init_array(git_strarray *array, int argc, char **argv)
+{
+	unsigned int i;
+
+	array->count = argc;
+	array->strings = malloc(sizeof(char*) * array->count);
+	assert(array->strings!=NULL);
+
+	for(i=0; i<array->count; i++) {
+		array->strings[i]=argv[i];
+	}
+
+	return;
+}
+
+void print_usage(void)
+{
+	fprintf(stderr, "usage: add [options] [--] file-spec [file-spec] [...]\n\n");
+	fprintf(stderr, "\t-n, --dry-run    dry run\n");
+	fprintf(stderr, "\t-v, --verbose    be verbose\n");
+	fprintf(stderr, "\t-u, --update     update tracked files\n");
+	exit(1);
+}
+
+static void parse_opts(int *options, int *count, int argc, char *argv[])
+{
+	int i;
+
+	for (i = 1; i < argc; ++i) {
+		if (argv[i][0] != '-') {
+			break;
+		}
+		else if(!strcmp(argv[i], "--verbose") || !strcmp(argv[i], "-v")) {
+			*options |= VERBOSE;
+		}
+		else if(!strcmp(argv[i], "--dry-run") || !strcmp(argv[i], "-n")) {
+			*options |= SKIP;
+		}
+		else if(!strcmp(argv[i], "--update") || !strcmp(argv[i], "-u")) {
+			*options |= UPDATE;
+		}
+		else if(!strcmp(argv[i], "-h")) {
+			print_usage();
+			break;
+		}
+		else if(!strcmp(argv[i], "--")) {
+			i++;
+			break;
+		}
+		else {
+			fprintf(stderr, "Unsupported option %s.\n", argv[i]);
+			print_usage();
+		}
+	}
+
+	if (argc<=i)
+		print_usage();
+
+	*count = i;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/blame.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/blame.c
new file mode 100755
index 0000000..9288352
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/blame.c
@@ -0,0 +1,212 @@
+/*
+ * libgit2 "blame" example - shows how to use the blame API
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "common.h"
+
+#ifdef _MSC_VER
+#define snprintf sprintf_s
+#define strcasecmp strcmpi
+#endif
+
+/**
+ * This example demonstrates how to invoke the libgit2 blame API to roughly
+ * simulate the output of `git blame` and a few of its command line arguments.
+ */
+
+struct opts {
+	char *path;
+	char *commitspec;
+	int C;
+	int M;
+	int start_line;
+	int end_line;
+	int F;
+};
+static void parse_opts(struct opts *o, int argc, char *argv[]);
+
+int main(int argc, char *argv[])
+{
+	int line, break_on_null_hunk;
+	size_t i, rawsize;
+	char spec[1024] = {0};
+	struct opts o = {0};
+	const char *rawdata;
+	git_repository *repo = NULL;
+	git_revspec revspec = {0};
+	git_blame_options blameopts = GIT_BLAME_OPTIONS_INIT;
+	git_blame *blame = NULL;
+	git_blob *blob;
+	git_object *obj;
+
+	git_libgit2_init();
+
+	parse_opts(&o, argc, argv);
+	if (o.M) blameopts.flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES;
+	if (o.C) blameopts.flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES;
+	if (o.F) blameopts.flags |= GIT_BLAME_FIRST_PARENT;
+
+	/** Open the repository. */
+	check_lg2(git_repository_open_ext(&repo, ".", 0, NULL), "Couldn't open repository", NULL);
+
+	/**
+	 * The commit range comes in "commitish" form. Use the rev-parse API to
+	 * nail down the end points.
+	 */
+	if (o.commitspec) {
+		check_lg2(git_revparse(&revspec, repo, o.commitspec), "Couldn't parse commit spec", NULL);
+		if (revspec.flags & GIT_REVPARSE_SINGLE) {
+			git_oid_cpy(&blameopts.newest_commit, git_object_id(revspec.from));
+			git_object_free(revspec.from);
+		} else {
+			git_oid_cpy(&blameopts.oldest_commit, git_object_id(revspec.from));
+			git_oid_cpy(&blameopts.newest_commit, git_object_id(revspec.to));
+			git_object_free(revspec.from);
+			git_object_free(revspec.to);
+		}
+	}
+
+	/** Run the blame. */
+	check_lg2(git_blame_file(&blame, repo, o.path, &blameopts), "Blame error", NULL);
+
+	/**
+	 * Get the raw data inside the blob for output. We use the
+	 * `commitish:path/to/file.txt` format to find it.
+	 */
+	if (git_oid_iszero(&blameopts.newest_commit))
+		strcpy(spec, "HEAD");
+	else
+		git_oid_tostr(spec, sizeof(spec), &blameopts.newest_commit);
+	strcat(spec, ":");
+	strcat(spec, o.path);
+
+	check_lg2(git_revparse_single(&obj, repo, spec), "Object lookup error", NULL);
+	check_lg2(git_blob_lookup(&blob, repo, git_object_id(obj)), "Blob lookup error", NULL);
+	git_object_free(obj);
+
+	rawdata = git_blob_rawcontent(blob);
+	rawsize = git_blob_rawsize(blob);
+
+	/** Produce the output. */
+	line = 1;
+	i = 0;
+	break_on_null_hunk = 0;
+	while (i < rawsize) {
+		const char *eol = memchr(rawdata + i, '\n', rawsize - i);
+		char oid[10] = {0};
+		const git_blame_hunk *hunk = git_blame_get_hunk_byline(blame, line);
+
+		if (break_on_null_hunk && !hunk)
+			break;
+
+		if (hunk) {
+			char sig[128] = {0};
+			break_on_null_hunk = 1;
+			
+			git_oid_tostr(oid, 10, &hunk->final_commit_id);
+			snprintf(sig, 30, "%s <%s>", hunk->final_signature->name, hunk->final_signature->email);
+
+			printf("%s ( %-30s %3d) %.*s\n",
+					oid,
+					sig,
+					line,
+					(int)(eol - rawdata - i),
+					rawdata + i);
+		}
+
+		i = (int)(eol - rawdata + 1);
+		line++;
+	}
+
+	/** Cleanup. */
+	git_blob_free(blob);
+	git_blame_free(blame);
+	git_repository_free(repo);
+
+	git_libgit2_shutdown();
+
+	return 0;
+}
+
+/** Tell the user how to make this thing work. */
+static void usage(const char *msg, const char *arg)
+{
+	if (msg && arg)
+		fprintf(stderr, "%s: %s\n", msg, arg);
+	else if (msg)
+		fprintf(stderr, "%s\n", msg);
+	fprintf(stderr, "usage: blame [options] [<commit range>] <path>\n");
+	fprintf(stderr, "\n");
+	fprintf(stderr, "   <commit range>      example: `HEAD~10..HEAD`, or `1234abcd`\n");
+	fprintf(stderr, "   -L <n,m>            process only line range n-m, counting from 1\n");
+	fprintf(stderr, "   -M                  find line moves within and across files\n");
+	fprintf(stderr, "   -C                  find line copies within and across files\n");
+	fprintf(stderr, "   -F                  follow only the first parent commits\n");
+	fprintf(stderr, "\n");
+	exit(1);
+}
+
+/** Parse the arguments. */
+static void parse_opts(struct opts *o, int argc, char *argv[])
+{
+	int i;
+	char *bare_args[3] = {0};
+
+	if (argc < 2) usage(NULL, NULL);
+
+	for (i=1; i<argc; i++) {
+		char *a = argv[i];
+
+		if (a[0] != '-') {
+			int i=0;
+			while (bare_args[i] && i < 3) ++i;
+			if (i >= 3)
+				usage("Invalid argument set", NULL);
+			bare_args[i] = a;
+		}
+		else if (!strcmp(a, "--"))
+			continue;
+		else if (!strcasecmp(a, "-M"))
+			o->M = 1;
+		else if (!strcasecmp(a, "-C"))
+			o->C = 1;
+		else if (!strcasecmp(a, "-F"))
+			o->F = 1;
+		else if (!strcasecmp(a, "-L")) {
+			i++; a = argv[i];
+			if (i >= argc) fatal("Not enough arguments to -L", NULL);
+			check_lg2(sscanf(a, "%d,%d", &o->start_line, &o->end_line)-2, "-L format error", NULL);
+		}
+		else {
+			/* commit range */
+			if (o->commitspec) fatal("Only one commit spec allowed", NULL);
+			o->commitspec = a;
+		}
+	}
+
+	/* Handle the bare arguments */
+	if (!bare_args[0]) usage("Please specify a path", NULL);
+	o->path = bare_args[0];
+	if (bare_args[1]) {
+		/* <commitspec> <path> */
+		o->path = bare_args[1];
+		o->commitspec = bare_args[0];
+	}
+	if (bare_args[2]) {
+		/* <oldcommit> <newcommit> <path> */
+		char spec[128] = {0};
+		o->path = bare_args[2];
+		sprintf(spec, "%s..%s", bare_args[0], bare_args[1]);
+		o->commitspec = spec;
+	}
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/cat-file.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/cat-file.c
new file mode 100755
index 0000000..f948740
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/cat-file.c
@@ -0,0 +1,246 @@
+/*
+ * libgit2 "cat-file" example - shows how to print data from the ODB
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "common.h"
+
+static void print_signature(const char *header, const git_signature *sig)
+{
+	char sign;
+	int offset, hours, minutes;
+
+	if (!sig)
+		return;
+
+	offset = sig->when.offset;
+	if (offset < 0) {
+		sign = '-';
+		offset = -offset;
+	} else {
+		sign = '+';
+	}
+
+	hours   = offset / 60;
+	minutes = offset % 60;
+
+	printf("%s %s <%s> %ld %c%02d%02d\n",
+		   header, sig->name, sig->email, (long)sig->when.time,
+		   sign, hours, minutes);
+}
+
+/** Printing out a blob is simple, get the contents and print */
+static void show_blob(const git_blob *blob)
+{
+	/* ? Does this need crlf filtering? */
+	fwrite(git_blob_rawcontent(blob), (size_t)git_blob_rawsize(blob), 1, stdout);
+}
+
+/** Show each entry with its type, id and attributes */
+static void show_tree(const git_tree *tree)
+{
+	size_t i, max_i = (int)git_tree_entrycount(tree);
+	char oidstr[GIT_OID_HEXSZ + 1];
+	const git_tree_entry *te;
+
+	for (i = 0; i < max_i; ++i) {
+		te = git_tree_entry_byindex(tree, i);
+
+		git_oid_tostr(oidstr, sizeof(oidstr), git_tree_entry_id(te));
+
+		printf("%06o %s %s\t%s\n",
+			git_tree_entry_filemode(te),
+			git_object_type2string(git_tree_entry_type(te)),
+			oidstr, git_tree_entry_name(te));
+	}
+}
+
+/**
+ * Commits and tags have a few interesting fields in their header.
+ */
+static void show_commit(const git_commit *commit)
+{
+	unsigned int i, max_i;
+	char oidstr[GIT_OID_HEXSZ + 1];
+
+	git_oid_tostr(oidstr, sizeof(oidstr), git_commit_tree_id(commit));
+	printf("tree %s\n", oidstr);
+
+	max_i = (unsigned int)git_commit_parentcount(commit);
+	for (i = 0; i < max_i; ++i) {
+		git_oid_tostr(oidstr, sizeof(oidstr), git_commit_parent_id(commit, i));
+		printf("parent %s\n", oidstr);
+	}
+
+	print_signature("author", git_commit_author(commit));
+	print_signature("committer", git_commit_committer(commit));
+
+	if (git_commit_message(commit))
+		printf("\n%s\n", git_commit_message(commit));
+}
+
+static void show_tag(const git_tag *tag)
+{
+	char oidstr[GIT_OID_HEXSZ + 1];
+
+	git_oid_tostr(oidstr, sizeof(oidstr), git_tag_target_id(tag));;
+	printf("object %s\n", oidstr);
+	printf("type %s\n", git_object_type2string(git_tag_target_type(tag)));
+	printf("tag %s\n", git_tag_name(tag));
+	print_signature("tagger", git_tag_tagger(tag));
+
+	if (git_tag_message(tag))
+		printf("\n%s\n", git_tag_message(tag));
+}
+
+enum {
+	SHOW_TYPE = 1,
+	SHOW_SIZE = 2,
+	SHOW_NONE = 3,
+	SHOW_PRETTY = 4
+};
+
+/* Forward declarations for option-parsing helper */
+struct opts {
+	const char *dir;
+	const char *rev;
+	int action;
+	int verbose;
+};
+static void parse_opts(struct opts *o, int argc, char *argv[]);
+
+
+/** Entry point for this command */
+int main(int argc, char *argv[])
+{
+	git_repository *repo;
+	struct opts o = { ".", NULL, 0, 0 };
+	git_object *obj = NULL;
+	char oidstr[GIT_OID_HEXSZ + 1];
+
+	git_libgit2_init();
+
+	parse_opts(&o, argc, argv);
+
+	check_lg2(git_repository_open_ext(&repo, o.dir, 0, NULL),
+			"Could not open repository", NULL);
+	check_lg2(git_revparse_single(&obj, repo, o.rev),
+			"Could not resolve", o.rev);
+
+	if (o.verbose) {
+		char oidstr[GIT_OID_HEXSZ + 1];
+		git_oid_tostr(oidstr, sizeof(oidstr), git_object_id(obj));
+
+		printf("%s %s\n--\n",
+			git_object_type2string(git_object_type(obj)), oidstr);
+	}
+
+	switch (o.action) {
+	case SHOW_TYPE:
+		printf("%s\n", git_object_type2string(git_object_type(obj)));
+		break;
+	case SHOW_SIZE: {
+		git_odb *odb;
+		git_odb_object *odbobj;
+
+		check_lg2(git_repository_odb(&odb, repo), "Could not open ODB", NULL);
+		check_lg2(git_odb_read(&odbobj, odb, git_object_id(obj)),
+			"Could not find obj", NULL);
+
+		printf("%ld\n", (long)git_odb_object_size(odbobj));
+
+		git_odb_object_free(odbobj);
+		git_odb_free(odb);
+		}
+		break;
+	case SHOW_NONE:
+		/* just want return result */
+		break;
+	case SHOW_PRETTY:
+
+		switch (git_object_type(obj)) {
+		case GIT_OBJ_BLOB:
+			show_blob((const git_blob *)obj);
+			break;
+		case GIT_OBJ_COMMIT:
+			show_commit((const git_commit *)obj);
+			break;
+		case GIT_OBJ_TREE:
+			show_tree((const git_tree *)obj);
+			break;
+		case GIT_OBJ_TAG:
+			show_tag((const git_tag *)obj);
+			break;
+		default:
+			printf("unknown %s\n", oidstr);
+			break;
+		}
+		break;
+	}
+
+	git_object_free(obj);
+	git_repository_free(repo);
+
+	git_libgit2_shutdown();
+
+	return 0;
+}
+
+/** Print out usage information */
+static void usage(const char *message, const char *arg)
+{
+	if (message && arg)
+		fprintf(stderr, "%s: %s\n", message, arg);
+	else if (message)
+		fprintf(stderr, "%s\n", message);
+	fprintf(stderr,
+			"usage: cat-file (-t | -s | -e | -p) [-v] [-q] "
+			"[-h|--help] [--git-dir=<dir>] <object>\n");
+	exit(1);
+}
+
+/** Parse the command-line options taken from git */
+static void parse_opts(struct opts *o, int argc, char *argv[])
+{
+	struct args_info args = ARGS_INFO_INIT;
+
+	for (args.pos = 1; args.pos < argc; ++args.pos) {
+		char *a = argv[args.pos];
+
+		if (a[0] != '-') {
+			if (o->rev != NULL)
+				usage("Only one rev should be provided", NULL);
+			else
+				o->rev = a;
+		}
+		else if (!strcmp(a, "-t"))
+			o->action = SHOW_TYPE;
+		else if (!strcmp(a, "-s"))
+			o->action = SHOW_SIZE;
+		else if (!strcmp(a, "-e"))
+			o->action = SHOW_NONE;
+		else if (!strcmp(a, "-p"))
+			o->action = SHOW_PRETTY;
+		else if (!strcmp(a, "-q"))
+			o->verbose = 0;
+		else if (!strcmp(a, "-v"))
+			o->verbose = 1;
+		else if (!strcmp(a, "--help") || !strcmp(a, "-h"))
+			usage(NULL, NULL);
+		else if (!match_str_arg(&o->dir, &args, "--git-dir"))
+			usage("Unknown option", a);
+	}
+
+	if (!o->action || !o->rev)
+		usage(NULL, NULL);
+
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/common.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/common.c
new file mode 100755
index 0000000..0f25f37
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/common.c
@@ -0,0 +1,218 @@
+/*
+ * Utilities library for libgit2 examples
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "common.h"
+
+void check_lg2(int error, const char *message, const char *extra)
+{
+	const git_error *lg2err;
+	const char *lg2msg = "", *lg2spacer = "";
+
+	if (!error)
+		return;
+
+	if ((lg2err = giterr_last()) != NULL && lg2err->message != NULL) {
+		lg2msg = lg2err->message;
+		lg2spacer = " - ";
+	}
+
+	if (extra)
+		fprintf(stderr, "%s '%s' [%d]%s%s\n",
+			message, extra, error, lg2spacer, lg2msg);
+	else
+		fprintf(stderr, "%s [%d]%s%s\n",
+			message, error, lg2spacer, lg2msg);
+
+	exit(1);
+}
+
+void fatal(const char *message, const char *extra)
+{
+	if (extra)
+		fprintf(stderr, "%s %s\n", message, extra);
+	else
+		fprintf(stderr, "%s\n", message);
+
+	exit(1);
+}
+
+size_t is_prefixed(const char *str, const char *pfx)
+{
+	size_t len = strlen(pfx);
+	return strncmp(str, pfx, len) ? 0 : len;
+}
+
+int optional_str_arg(
+	const char **out, struct args_info *args, const char *opt, const char *def)
+{
+	const char *found = args->argv[args->pos];
+	size_t len = is_prefixed(found, opt);
+
+	if (!len)
+		return 0;
+
+	if (!found[len]) {
+		if (args->pos + 1 == args->argc) {
+			*out = def;
+			return 1;
+		}
+		args->pos += 1;
+		*out = args->argv[args->pos];
+		return 1;
+	}
+
+	if (found[len] == '=') {
+		*out = found + len + 1;
+		return 1;
+	}
+
+	return 0;
+}
+
+int match_str_arg(
+	const char **out, struct args_info *args, const char *opt)
+{
+	const char *found = args->argv[args->pos];
+	size_t len = is_prefixed(found, opt);
+
+	if (!len)
+		return 0;
+
+	if (!found[len]) {
+		if (args->pos + 1 == args->argc)
+			fatal("expected value following argument", opt);
+		args->pos += 1;
+		*out = args->argv[args->pos];
+		return 1;
+	}
+
+	if (found[len] == '=') {
+		*out = found + len + 1;
+		return 1;
+	}
+
+	return 0;
+}
+
+static const char *match_numeric_arg(struct args_info *args, const char *opt)
+{
+	const char *found = args->argv[args->pos];
+	size_t len = is_prefixed(found, opt);
+
+	if (!len)
+		return NULL;
+
+	if (!found[len]) {
+		if (args->pos + 1 == args->argc)
+			fatal("expected numeric value following argument", opt);
+		args->pos += 1;
+		found = args->argv[args->pos];
+	} else {
+		found = found + len;
+		if (*found == '=')
+			found++;
+	}
+
+	return found;
+}
+
+int match_uint16_arg(
+	uint16_t *out, struct args_info *args, const char *opt)
+{
+	const char *found = match_numeric_arg(args, opt);
+	uint16_t val;
+	char *endptr = NULL;
+
+	if (!found)
+		return 0;
+
+	val = (uint16_t)strtoul(found, &endptr, 0);
+	if (!endptr || *endptr != '\0')
+		fatal("expected number after argument", opt);
+
+	if (out)
+		*out = val;
+	return 1;
+}
+
+static int match_int_internal(
+	int *out, const char *str, int allow_negative, const char *opt)
+{
+	char *endptr = NULL;
+	int	  val = (int)strtol(str, &endptr, 10);
+
+	if (!endptr || *endptr != '\0')
+		fatal("expected number", opt);
+	else if (val < 0 && !allow_negative)
+		fatal("negative values are not allowed", opt);
+
+	if (out)
+		*out = val;
+
+	return 1;
+}
+
+int is_integer(int *out, const char *str, int allow_negative)
+{
+	return match_int_internal(out, str, allow_negative, NULL);
+}
+
+int match_int_arg(
+	int *out, struct args_info *args, const char *opt, int allow_negative)
+{
+	const char *found = match_numeric_arg(args, opt);
+	if (!found)
+		return 0;
+	return match_int_internal(out, found, allow_negative, opt);
+}
+
+int diff_output(
+	const git_diff_delta *d,
+	const git_diff_hunk *h,
+	const git_diff_line *l,
+	void *p)
+{
+	FILE *fp = (FILE*)p;
+
+	(void)d; (void)h;
+
+	if (!fp)
+		fp = stdout;
+
+	if (l->origin == GIT_DIFF_LINE_CONTEXT ||
+		l->origin == GIT_DIFF_LINE_ADDITION ||
+		l->origin == GIT_DIFF_LINE_DELETION)
+		fputc(l->origin, fp);
+
+	fwrite(l->content, 1, l->content_len, fp);
+
+	return 0;
+}
+
+void treeish_to_tree(
+	git_tree **out, git_repository *repo, const char *treeish)
+{
+	git_object *obj = NULL;
+
+	check_lg2(
+		git_revparse_single(&obj, repo, treeish),
+		"looking up object", treeish);
+
+	check_lg2(
+		git_object_peel((git_object **)out, obj, GIT_OBJ_TREE),
+		"resolving object to tree", treeish);
+
+	git_object_free(obj);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/common.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/common.h
new file mode 100755
index 0000000..b9fa37c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/common.h
@@ -0,0 +1,96 @@
+/*
+ * Utilities library for libgit2 examples
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <git2.h>
+
+/**
+ * Check libgit2 error code, printing error to stderr on failure and
+ * exiting the program.
+ */
+extern void check_lg2(int error, const char *message, const char *extra);
+
+/**
+ * Exit the program, printing error to stderr
+ */
+extern void fatal(const char *message, const char *extra);
+
+/**
+ * Check if a string has the given prefix.  Returns 0 if not prefixed
+ * or the length of the prefix if it is.
+ */
+extern size_t is_prefixed(const char *str, const char *pfx);
+
+/**
+ * Match an integer string, returning 1 if matched, 0 if not.
+ */
+extern int is_integer(int *out, const char *str, int allow_negative);
+
+struct args_info {
+	int    argc;
+	char **argv;
+	int    pos;
+};
+#define ARGS_INFO_INIT { argc, argv, 0 }
+
+/**
+ * Check current `args` entry against `opt` string.  If it matches
+ * exactly, take the next arg as a string; if it matches as a prefix with
+ * an equal sign, take the remainder as a string; if value not supplied, 
+ * default value `def` will be given. otherwise return 0.
+ */
+extern int optional_str_arg(
+	const char **out, struct args_info *args, const char *opt, const char *def);
+
+/**
+ * Check current `args` entry against `opt` string.  If it matches
+ * exactly, take the next arg as a string; if it matches as a prefix with
+ * an equal sign, take the remainder as a string; otherwise return 0.
+ */
+extern int match_str_arg(
+	const char **out, struct args_info *args, const char *opt);
+
+/**
+ * Check current `args` entry against `opt` string parsing as uint16.  If
+ * `opt` matches exactly, take the next arg as a uint16_t value; if `opt`
+ * is a prefix (equal sign optional), take the remainder of the arg as a
+ * uint16_t value; otherwise return 0.
+ */
+extern int match_uint16_arg(
+	uint16_t *out, struct args_info *args, const char *opt);
+
+/**
+ * Check current `args` entry against `opt` string parsing as int.  If
+ * `opt` matches exactly, take the next arg as an int value; if it matches
+ * as a prefix (equal sign optional), take the remainder of the arg as a
+ * int value; otherwise return 0.
+ */
+extern int match_int_arg(
+	int *out, struct args_info *args, const char *opt, int allow_negative);
+
+/**
+ * Basic output function for plain text diff output
+ * Pass `FILE*` such as `stdout` or `stderr` as payload (or NULL == `stdout`)
+ */
+extern int diff_output(
+	const git_diff_delta*, const git_diff_hunk*, const git_diff_line*, void*);
+
+/**
+ * Convert a treeish argument to an actual tree; this will call check_lg2
+ * and exit the program if `treeish` cannot be resolved to a tree
+ */
+extern void treeish_to_tree(
+	git_tree **out, git_repository *repo, const char *treeish);
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/describe.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/describe.c
new file mode 100755
index 0000000..4cdf61f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/describe.c
@@ -0,0 +1,184 @@
+/*
+ * libgit2 "describe" example - shows how to describe commits
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "common.h"
+#include <assert.h>
+
+/**
+ * The following example partially reimplements the `git describe` command
+ * and some of its options.
+ *
+ * These commands should work:
+
+ * - Describe HEAD with default options (`describe`)
+ * - Describe specified revision (`describe master~2`)
+ * - Describe specified revisions (`describe master~2 HEAD~3`)
+ * - Describe HEAD with dirty state suffix (`describe --dirty=*`)
+ * - Describe consider all refs (`describe --all master`)
+ * - Describe consider lightweight tags (`describe --tags temp-tag`)
+ * - Describe show non-default abbreviated size (`describe --abbrev=10`)
+ * - Describe always output the long format if matches a tag (`describe --long v1.0`)
+ * - Describe consider only tags of specified pattern (`describe --match v*-release`)
+ * - Describe show the fallback result (`describe --always`)
+ * - Describe follow only the first parent commit (`describe --first-parent`)
+ *
+ * The command line parsing logic is simplified and doesn't handle
+ * all of the use cases.
+ */
+
+/** describe_options represents the parsed command line options */
+typedef struct {
+	const char **commits;
+	size_t commit_count;
+	git_describe_options describe_options;
+	git_describe_format_options format_options;
+} describe_options;
+
+typedef struct args_info args_info;
+
+static void *xrealloc(void *oldp, size_t newsz)
+{
+	void *p = realloc(oldp, newsz);
+	if (p == NULL) {
+		fprintf(stderr, "Cannot allocate memory, exiting.\n");
+		exit(1);
+	}
+	return p;
+}
+
+static void opts_add_commit(describe_options *opts, const char *commit)
+{
+	size_t sz;
+
+	assert(opts != NULL);
+
+	sz = ++opts->commit_count * sizeof(opts->commits[0]);
+	opts->commits = xrealloc(opts->commits, sz);
+	opts->commits[opts->commit_count - 1] = commit;
+}
+
+static void do_describe_single(git_repository *repo, describe_options *opts, const char *rev)
+{
+	git_object *commit;
+	git_describe_result *describe_result;
+	git_buf buf = { 0 };
+	
+	if (rev) {
+		check_lg2(git_revparse_single(&commit, repo, rev),
+			"Failed to lookup rev", rev);
+
+		check_lg2(git_describe_commit(&describe_result, commit, &opts->describe_options),
+			"Failed to describe rev", rev);
+	}
+	else
+		check_lg2(git_describe_workdir(&describe_result, repo, &opts->describe_options),
+			"Failed to describe workdir", NULL);
+
+	check_lg2(git_describe_format(&buf, describe_result, &opts->format_options),
+			"Failed to format describe rev", rev);
+
+	printf("%s\n", buf.ptr);
+}
+
+static void do_describe(git_repository *repo, describe_options *opts)
+{
+	if (opts->commit_count == 0)
+		do_describe_single(repo, opts, NULL);
+	else
+	{
+		size_t i;
+		for (i = 0; i < opts->commit_count; i++)
+			do_describe_single(repo, opts, opts->commits[i]);
+	}
+}
+
+static void print_usage(void)
+{
+	fprintf(stderr, "usage: see `git help describe`\n");
+	exit(1);
+}
+
+/** Parse command line arguments */
+static void parse_options(describe_options *opts, int argc, char **argv)
+{
+	args_info args = ARGS_INFO_INIT;
+
+	for (args.pos = 1; args.pos < argc; ++args.pos) {
+		const char *curr = argv[args.pos];
+
+		if (curr[0] != '-') {
+			opts_add_commit(opts, curr);
+		} else if (!strcmp(curr, "--all")) {
+			opts->describe_options.describe_strategy = GIT_DESCRIBE_ALL;
+		} else if (!strcmp(curr, "--tags")) {
+			opts->describe_options.describe_strategy = GIT_DESCRIBE_TAGS;
+		} else if (!strcmp(curr, "--exact-match")) {
+			opts->describe_options.max_candidates_tags = 0;
+		} else if (!strcmp(curr, "--long")) {
+			opts->format_options.always_use_long_format = 1;
+		} else if (!strcmp(curr, "--always")) {
+			opts->describe_options.show_commit_oid_as_fallback = 1;
+		} else if (!strcmp(curr, "--first-parent")) {
+			opts->describe_options.only_follow_first_parent = 1;
+		} else if (optional_str_arg(&opts->format_options.dirty_suffix, &args, "--dirty", "-dirty")) {
+		} else if (match_int_arg((int *)&opts->format_options.abbreviated_size, &args, "--abbrev", 0)) {
+		} else if (match_int_arg((int *)&opts->describe_options.max_candidates_tags, &args, "--candidates", 0)) {
+		} else if (match_str_arg(&opts->describe_options.pattern, &args, "--match")) {
+		} else {
+			print_usage();
+		}
+	}
+
+	if (opts->commit_count > 0) {
+		if (opts->format_options.dirty_suffix)
+			fatal("--dirty is incompatible with commit-ishes", NULL);
+	}
+	else {
+		if (!opts->format_options.dirty_suffix || !opts->format_options.dirty_suffix[0]) {
+			opts_add_commit(opts, "HEAD");
+		}
+	}
+}
+
+/** Initialize describe_options struct */
+static void describe_options_init(describe_options *opts)
+{
+	memset(opts, 0, sizeof(*opts));
+
+	opts->commits = NULL;
+	opts->commit_count = 0;
+	git_describe_init_options(&opts->describe_options, GIT_DESCRIBE_OPTIONS_VERSION);
+	git_describe_init_format_options(&opts->format_options, GIT_DESCRIBE_FORMAT_OPTIONS_VERSION);
+}
+
+int main(int argc, char **argv)
+{
+	git_repository *repo;
+	describe_options opts;
+
+	git_libgit2_init();
+
+	check_lg2(git_repository_open_ext(&repo, ".", 0, NULL),
+			"Could not open repository", NULL);
+
+	describe_options_init(&opts);
+	parse_options(&opts, argc, argv);
+
+	do_describe(repo, &opts);
+
+	git_repository_free(repo);
+	git_libgit2_shutdown();
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/diff.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/diff.c
new file mode 100755
index 0000000..b69cb22
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/diff.c
@@ -0,0 +1,337 @@
+/*
+ * libgit2 "diff" example - shows how to use the diff API
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "common.h"
+
+/**
+ * This example demonstrates the use of the libgit2 diff APIs to
+ * create `git_diff` objects and display them, emulating a number of
+ * core Git `diff` command line options.
+ *
+ * This covers on a portion of the core Git diff options and doesn't
+ * have particularly good error handling, but it should show most of
+ * the core libgit2 diff APIs, including various types of diffs and
+ * how to do renaming detection and patch formatting.
+ */
+
+static const char *colors[] = {
+	"\033[m", /* reset */
+	"\033[1m", /* bold */
+	"\033[31m", /* red */
+	"\033[32m", /* green */
+	"\033[36m" /* cyan */
+};
+
+enum {
+	OUTPUT_DIFF = (1 << 0),
+	OUTPUT_STAT = (1 << 1),
+	OUTPUT_SHORTSTAT = (1 << 2),
+	OUTPUT_NUMSTAT = (1 << 3),
+	OUTPUT_SUMMARY = (1 << 4)
+};
+
+enum {
+	CACHE_NORMAL = 0,
+	CACHE_ONLY = 1,
+	CACHE_NONE = 2
+};
+
+/** The 'opts' struct captures all the various parsed command line options. */
+struct opts {
+	git_diff_options diffopts;
+	git_diff_find_options findopts;
+	int color;
+	int cache;
+	int output;
+	git_diff_format_t format;
+	const char *treeish1;
+	const char *treeish2;
+	const char *dir;
+};
+
+/** These functions are implemented at the end */
+static void usage(const char *message, const char *arg);
+static void parse_opts(struct opts *o, int argc, char *argv[]);
+static int color_printer(
+	const git_diff_delta*, const git_diff_hunk*, const git_diff_line*, void*);
+static void diff_print_stats(git_diff *diff, struct opts *o);
+
+int main(int argc, char *argv[])
+{
+	git_repository *repo = NULL;
+	git_tree *t1 = NULL, *t2 = NULL;
+	git_diff *diff;
+	struct opts o = {
+		GIT_DIFF_OPTIONS_INIT, GIT_DIFF_FIND_OPTIONS_INIT,
+		-1, 0, 0, GIT_DIFF_FORMAT_PATCH, NULL, NULL, "."
+	};
+
+	git_libgit2_init();
+
+	parse_opts(&o, argc, argv);
+
+	check_lg2(git_repository_open_ext(&repo, o.dir, 0, NULL),
+		"Could not open repository", o.dir);
+
+	/**
+	 * Possible argument patterns:
+	 *
+	 *  * <sha1> <sha2>
+	 *  * <sha1> --cached
+	 *  * <sha1>
+	 *  * --cached
+	 *  * --nocache (don't use index data in diff at all)
+	 *  * nothing
+	 *
+	 * Currently ranged arguments like <sha1>..<sha2> and <sha1>...<sha2>
+	 * are not supported in this example
+	 */
+
+	if (o.treeish1)
+		treeish_to_tree(&t1, repo, o.treeish1);
+	if (o.treeish2)
+		treeish_to_tree(&t2, repo, o.treeish2);
+
+	if (t1 && t2)
+		check_lg2(
+			git_diff_tree_to_tree(&diff, repo, t1, t2, &o.diffopts),
+			"diff trees", NULL);
+	else if (o.cache != CACHE_NORMAL) {
+		if (!t1)
+			treeish_to_tree(&t1, repo, "HEAD");
+
+		if (o.cache == CACHE_NONE)
+			check_lg2(
+				git_diff_tree_to_workdir(&diff, repo, t1, &o.diffopts),
+				"diff tree to working directory", NULL);
+		else
+			check_lg2(
+				git_diff_tree_to_index(&diff, repo, t1, NULL, &o.diffopts),
+				"diff tree to index", NULL);
+	}
+	else if (t1)
+		check_lg2(
+			git_diff_tree_to_workdir_with_index(&diff, repo, t1, &o.diffopts),
+			"diff tree to working directory", NULL);
+	else
+		check_lg2(
+			git_diff_index_to_workdir(&diff, repo, NULL, &o.diffopts),
+			"diff index to working directory", NULL);
+
+	/** Apply rename and copy detection if requested. */
+
+	if ((o.findopts.flags & GIT_DIFF_FIND_ALL) != 0)
+		check_lg2(
+			git_diff_find_similar(diff, &o.findopts),
+			"finding renames and copies", NULL);
+
+	/** Generate simple output using libgit2 display helper. */
+
+	if (!o.output)
+		o.output = OUTPUT_DIFF;
+
+	if (o.output != OUTPUT_DIFF)
+		diff_print_stats(diff, &o);
+
+	if ((o.output & OUTPUT_DIFF) != 0) {
+		if (o.color >= 0)
+			fputs(colors[0], stdout);
+
+		check_lg2(
+			git_diff_print(diff, o.format, color_printer, &o.color),
+			"displaying diff", NULL);
+
+		if (o.color >= 0)
+			fputs(colors[0], stdout);
+	}
+
+	/** Cleanup before exiting. */
+
+	git_diff_free(diff);
+	git_tree_free(t1);
+	git_tree_free(t2);
+	git_repository_free(repo);
+
+	git_libgit2_shutdown();
+
+	return 0;
+}
+
+static void usage(const char *message, const char *arg)
+{
+	if (message && arg)
+		fprintf(stderr, "%s: %s\n", message, arg);
+	else if (message)
+		fprintf(stderr, "%s\n", message);
+	fprintf(stderr, "usage: diff [<tree-oid> [<tree-oid>]]\n");
+	exit(1);
+}
+
+/** This implements very rudimentary colorized output. */
+static int color_printer(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *data)
+{
+	int *last_color = data, color = 0;
+
+	(void)delta; (void)hunk;
+
+	if (*last_color >= 0) {
+		switch (line->origin) {
+		case GIT_DIFF_LINE_ADDITION:  color = 3; break;
+		case GIT_DIFF_LINE_DELETION:  color = 2; break;
+		case GIT_DIFF_LINE_ADD_EOFNL: color = 3; break;
+		case GIT_DIFF_LINE_DEL_EOFNL: color = 2; break;
+		case GIT_DIFF_LINE_FILE_HDR:  color = 1; break;
+		case GIT_DIFF_LINE_HUNK_HDR:  color = 4; break;
+		default: break;
+		}
+
+		if (color != *last_color) {
+			if (*last_color == 1 || color == 1)
+				fputs(colors[0], stdout);
+			fputs(colors[color], stdout);
+			*last_color = color;
+		}
+	}
+
+	return diff_output(delta, hunk, line, stdout);
+}
+
+/** Parse arguments as copied from git-diff. */
+static void parse_opts(struct opts *o, int argc, char *argv[])
+{
+	struct args_info args = ARGS_INFO_INIT;
+
+
+	for (args.pos = 1; args.pos < argc; ++args.pos) {
+		const char *a = argv[args.pos];
+
+		if (a[0] != '-') {
+			if (o->treeish1 == NULL)
+				o->treeish1 = a;
+			else if (o->treeish2 == NULL)
+				o->treeish2 = a;
+			else
+				usage("Only one or two tree identifiers can be provided", NULL);
+		}
+		else if (!strcmp(a, "-p") || !strcmp(a, "-u") ||
+				 !strcmp(a, "--patch")) {
+			o->output |= OUTPUT_DIFF;
+			o->format = GIT_DIFF_FORMAT_PATCH;
+		}
+		else if (!strcmp(a, "--cached"))
+			o->cache = CACHE_ONLY;
+		else if (!strcmp(a, "--nocache"))
+			o->cache = CACHE_NONE;
+		else if (!strcmp(a, "--name-only") || !strcmp(a, "--format=name"))
+			o->format = GIT_DIFF_FORMAT_NAME_ONLY;
+		else if (!strcmp(a, "--name-status") ||
+				!strcmp(a, "--format=name-status"))
+			o->format = GIT_DIFF_FORMAT_NAME_STATUS;
+		else if (!strcmp(a, "--raw") || !strcmp(a, "--format=raw"))
+			o->format = GIT_DIFF_FORMAT_RAW;
+		else if (!strcmp(a, "--format=diff-index")) {
+			o->format = GIT_DIFF_FORMAT_RAW;
+			o->diffopts.id_abbrev = 40;
+		}
+		else if (!strcmp(a, "--color"))
+			o->color = 0;
+		else if (!strcmp(a, "--no-color"))
+			o->color = -1;
+		else if (!strcmp(a, "-R"))
+			o->diffopts.flags |= GIT_DIFF_REVERSE;
+		else if (!strcmp(a, "-a") || !strcmp(a, "--text"))
+			o->diffopts.flags |= GIT_DIFF_FORCE_TEXT;
+		else if (!strcmp(a, "--ignore-space-at-eol"))
+			o->diffopts.flags |= GIT_DIFF_IGNORE_WHITESPACE_EOL;
+		else if (!strcmp(a, "-b") || !strcmp(a, "--ignore-space-change"))
+			o->diffopts.flags |= GIT_DIFF_IGNORE_WHITESPACE_CHANGE;
+		else if (!strcmp(a, "-w") || !strcmp(a, "--ignore-all-space"))
+			o->diffopts.flags |= GIT_DIFF_IGNORE_WHITESPACE;
+		else if (!strcmp(a, "--ignored"))
+			o->diffopts.flags |= GIT_DIFF_INCLUDE_IGNORED;
+		else if (!strcmp(a, "--untracked"))
+			o->diffopts.flags |= GIT_DIFF_INCLUDE_UNTRACKED;
+		else if (!strcmp(a, "--patience"))
+			o->diffopts.flags |= GIT_DIFF_PATIENCE;
+		else if (!strcmp(a, "--minimal"))
+			o->diffopts.flags |= GIT_DIFF_MINIMAL;
+		else if (!strcmp(a, "--stat"))
+			o->output |= OUTPUT_STAT;
+		else if (!strcmp(a, "--numstat"))
+			o->output |= OUTPUT_NUMSTAT;
+		else if (!strcmp(a, "--shortstat"))
+			o->output |= OUTPUT_SHORTSTAT;
+		else if (!strcmp(a, "--summary"))
+			o->output |= OUTPUT_SUMMARY;
+		else if (match_uint16_arg(
+				&o->findopts.rename_threshold, &args, "-M") ||
+			match_uint16_arg(
+				&o->findopts.rename_threshold, &args, "--find-renames"))
+			o->findopts.flags |= GIT_DIFF_FIND_RENAMES;
+		else if (match_uint16_arg(
+				&o->findopts.copy_threshold, &args, "-C") ||
+			match_uint16_arg(
+				&o->findopts.copy_threshold, &args, "--find-copies"))
+			o->findopts.flags |= GIT_DIFF_FIND_COPIES;
+		else if (!strcmp(a, "--find-copies-harder"))
+			o->findopts.flags |= GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED;
+		else if (is_prefixed(a, "-B") || is_prefixed(a, "--break-rewrites"))
+			/* TODO: parse thresholds */
+			o->findopts.flags |= GIT_DIFF_FIND_REWRITES;
+		else if (!match_uint16_arg(
+				&o->diffopts.context_lines, &args, "-U") &&
+			!match_uint16_arg(
+				&o->diffopts.context_lines, &args, "--unified") &&
+			!match_uint16_arg(
+				&o->diffopts.interhunk_lines, &args, "--inter-hunk-context") &&
+			!match_uint16_arg(
+				&o->diffopts.id_abbrev, &args, "--abbrev") &&
+			!match_str_arg(&o->diffopts.old_prefix, &args, "--src-prefix") &&
+			!match_str_arg(&o->diffopts.new_prefix, &args, "--dst-prefix") &&
+			!match_str_arg(&o->dir, &args, "--git-dir"))
+			usage("Unknown command line argument", a);
+	}
+}
+
+/** Display diff output with "--stat", "--numstat", or "--shortstat" */
+static void diff_print_stats(git_diff *diff, struct opts *o)
+{
+	git_diff_stats *stats;
+	git_buf b = GIT_BUF_INIT_CONST(NULL, 0);
+	git_diff_stats_format_t format = 0;
+
+	check_lg2(
+		git_diff_get_stats(&stats, diff), "generating stats for diff", NULL);
+
+	if (o->output & OUTPUT_STAT)
+		format |= GIT_DIFF_STATS_FULL;
+	if (o->output & OUTPUT_SHORTSTAT)
+		format |= GIT_DIFF_STATS_SHORT;
+	if (o->output & OUTPUT_NUMSTAT)
+		format |= GIT_DIFF_STATS_NUMBER;
+	if (o->output & OUTPUT_SUMMARY)
+		format |= GIT_DIFF_STATS_INCLUDE_SUMMARY;
+
+	check_lg2(
+		git_diff_stats_to_buf(&b, stats, format, 80), "formatting stats", NULL);
+
+	fputs(b.ptr, stdout);
+
+	git_buf_free(&b);
+	git_diff_stats_free(stats);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/for-each-ref.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/for-each-ref.c
new file mode 100755
index 0000000..a8ceaaf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/for-each-ref.c
@@ -0,0 +1,49 @@
+#include <git2.h>
+#include <stdio.h>
+#include "common.h"
+
+static int show_ref(git_reference *ref, void *data)
+{
+        git_repository *repo = data;
+        git_reference *resolved = NULL;
+        char hex[GIT_OID_HEXSZ+1];
+        const git_oid *oid;
+        git_object *obj;
+
+        if (git_reference_type(ref) == GIT_REF_SYMBOLIC)
+                check_lg2(git_reference_resolve(&resolved, ref),
+                          "Unable to resolve symbolic reference",
+                          git_reference_name(ref));
+
+        oid = git_reference_target(resolved ? resolved : ref);
+        git_oid_fmt(hex, oid);
+        hex[GIT_OID_HEXSZ] = 0;
+        check_lg2(git_object_lookup(&obj, repo, oid, GIT_OBJ_ANY),
+                  "Unable to lookup object", hex);
+
+        printf("%s %-6s\t%s\n",
+               hex,
+               git_object_type2string(git_object_type(obj)),
+               git_reference_name(ref));
+
+        if (resolved)
+                git_reference_free(resolved);
+        return 0;
+}
+
+int main(int argc, char **argv)
+{
+        git_repository *repo;
+        git_libgit2_init();
+
+        if (argc != 1 || argv[1] /* silence -Wunused-parameter */)
+                fatal("Sorry, no for-each-ref options supported yet", NULL);
+
+        check_lg2(git_repository_open(&repo, "."),
+                  "Could not open repository", NULL);
+        check_lg2(git_reference_foreach(repo, show_ref, repo),
+                  "Could not iterate over references", NULL);
+
+        git_libgit2_shutdown();
+        return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/general.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/general.c
new file mode 100755
index 0000000..706650b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/general.c
@@ -0,0 +1,531 @@
+/*
+ * libgit2 "general" example - shows basic libgit2 concepts
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+// [**libgit2**][lg] is a portable, pure C implementation of the Git core
+// methods provided as a re-entrant linkable library with a solid API,
+// allowing you to write native speed custom Git applications in any
+// language which supports C bindings.
+//
+// This file is an example of using that API in a real, compilable C file.
+// As the API is updated, this file will be updated to demonstrate the new
+// functionality.
+//
+// If you're trying to write something in C using [libgit2][lg], you should
+// also check out the generated [API documentation][ap]. We try to link to
+// the relevant sections of the API docs in each section in this file.
+//
+// **libgit2** (for the most part) only implements the core plumbing
+// functions, not really the higher level porcelain stuff. For a primer on
+// Git Internals that you will need to know to work with Git at this level,
+// check out [Chapter 9][pg] of the Pro Git book.
+//
+// [lg]: http://libgit2.github.com
+// [ap]: http://libgit2.github.com/libgit2
+// [pg]: http://progit.org/book/ch9-0.html
+
+// ### Includes
+
+// Including the `git2.h` header will include all the other libgit2 headers
+// that you need.  It should be the only thing you need to include in order
+// to compile properly and get all the libgit2 API.
+#include <git2.h>
+#include <stdio.h>
+
+// Almost all libgit2 functions return 0 on success or negative on error.
+// This is not production quality error checking, but should be sufficient
+// as an example.
+static void check_error(int error_code, const char *action)
+{
+	const git_error *error = giterr_last();
+	if (!error_code)
+		return;
+
+	printf("Error %d %s - %s\n", error_code, action,
+		   (error && error->message) ? error->message : "???");
+
+	exit(1);
+}
+
+int main (int argc, char** argv)
+{
+  // Initialize the library, this will set up any global state which libgit2 needs
+  // including threading and crypto
+  git_libgit2_init();
+
+  // ### Opening the Repository
+
+  // There are a couple of methods for opening a repository, this being the
+  // simplest.  There are also [methods][me] for specifying the index file
+  // and work tree locations, here we assume they are in the normal places.
+	//
+	// (Try running this program against tests/resources/testrepo.git.)
+  //
+  // [me]: http://libgit2.github.com/libgit2/#HEAD/group/repository
+  int error;
+  const char *repo_path = (argc > 1) ? argv[1] : "/opt/libgit2-test/.git";
+  git_repository *repo;
+
+  error = git_repository_open(&repo, repo_path);
+  check_error(error, "opening repository");
+
+  // ### SHA-1 Value Conversions
+
+  // For our first example, we will convert a 40 character hex value to the
+  // 20 byte raw SHA1 value.
+  printf("*Hex to Raw*\n");
+  char hex[] = "4a202b346bb0fb0db7eff3cffeb3c70babbd2045";
+
+  // The `git_oid` is the structure that keeps the SHA value. We will use
+  // this throughout the example for storing the value of the current SHA
+  // key we're working with.
+  git_oid oid;
+  git_oid_fromstr(&oid, hex);
+
+  // Once we've converted the string into the oid value, we can get the raw
+  // value of the SHA by accessing `oid.id`
+
+  // Next we will convert the 20 byte raw SHA1 value to a human readable 40
+  // char hex value.
+  printf("\n*Raw to Hex*\n");
+  char out[GIT_OID_HEXSZ+1];
+  out[GIT_OID_HEXSZ] = '\0';
+
+  // If you have a oid, you can easily get the hex value of the SHA as well.
+  git_oid_fmt(out, &oid);
+  printf("SHA hex string: %s\n", out);
+
+  // ### Working with the Object Database
+
+  // **libgit2** provides [direct access][odb] to the object database.  The
+  // object database is where the actual objects are stored in Git. For
+  // working with raw objects, we'll need to get this structure from the
+  // repository.
+  //
+  // [odb]: http://libgit2.github.com/libgit2/#HEAD/group/odb
+  git_odb *odb;
+  git_repository_odb(&odb, repo);
+
+  // #### Raw Object Reading
+
+  printf("\n*Raw Object Read*\n");
+  git_odb_object *obj;
+  git_otype otype;
+  const unsigned char *data;
+  const char *str_type;
+
+  // We can read raw objects directly from the object database if we have
+  // the oid (SHA) of the object.  This allows us to access objects without
+  // knowing their type and inspect the raw bytes unparsed.
+  error = git_odb_read(&obj, odb, &oid);
+  check_error(error, "finding object in repository");
+
+  // A raw object only has three properties - the type (commit, blob, tree
+  // or tag), the size of the raw data and the raw, unparsed data itself.
+  // For a commit or tag, that raw data is human readable plain ASCII
+  // text. For a blob it is just file contents, so it could be text or
+  // binary data. For a tree it is a special binary format, so it's unlikely
+  // to be hugely helpful as a raw object.
+  data = (const unsigned char *)git_odb_object_data(obj);
+  otype = git_odb_object_type(obj);
+
+  // We provide methods to convert from the object type which is an enum, to
+  // a string representation of that value (and vice-versa).
+  str_type = git_object_type2string(otype);
+  printf("object length and type: %d, %s\n",
+      (int)git_odb_object_size(obj),
+      str_type);
+
+  // For proper memory management, close the object when you are done with
+  // it or it will leak memory.
+  git_odb_object_free(obj);
+
+  // #### Raw Object Writing
+
+  printf("\n*Raw Object Write*\n");
+
+  // You can also write raw object data to Git. This is pretty cool because
+  // it gives you direct access to the key/value properties of Git.  Here
+  // we'll write a new blob object that just contains a simple string.
+  // Notice that we have to specify the object type as the `git_otype` enum.
+  git_odb_write(&oid, odb, "test data", sizeof("test data") - 1, GIT_OBJ_BLOB);
+
+  // Now that we've written the object, we can check out what SHA1 was
+  // generated when the object was written to our database.
+  git_oid_fmt(out, &oid);
+  printf("Written Object: %s\n", out);
+
+  // ### Object Parsing
+
+  // libgit2 has methods to parse every object type in Git so you don't have
+  // to work directly with the raw data. This is much faster and simpler
+  // than trying to deal with the raw data yourself.
+
+  // #### Commit Parsing
+
+  // [Parsing commit objects][pco] is simple and gives you access to all the
+  // data in the commit - the author (name, email, datetime), committer
+  // (same), tree, message, encoding and parent(s).
+  //
+  // [pco]: http://libgit2.github.com/libgit2/#HEAD/group/commit
+
+  printf("\n*Commit Parsing*\n");
+
+  git_commit *commit;
+  git_oid_fromstr(&oid, "8496071c1b46c854b31185ea97743be6a8774479");
+
+  error = git_commit_lookup(&commit, repo, &oid);
+  check_error(error, "looking up commit");
+
+  const git_signature *author, *cmtter;
+  const char *message;
+  time_t ctime;
+  unsigned int parents, p;
+
+  // Each of the properties of the commit object are accessible via methods,
+  // including commonly needed variations, such as `git_commit_time` which
+  // returns the author time and `git_commit_message` which gives you the
+  // commit message (as a NUL-terminated string).
+  message  = git_commit_message(commit);
+  author   = git_commit_author(commit);
+  cmtter   = git_commit_committer(commit);
+  ctime    = git_commit_time(commit);
+
+  // The author and committer methods return [git_signature] structures,
+  // which give you name, email and `when`, which is a `git_time` structure,
+  // giving you a timestamp and timezone offset.
+  printf("Author: %s (%s)\n", author->name, author->email);
+
+  // Commits can have zero or more parents. The first (root) commit will
+  // have no parents, most commits will have one (i.e. the commit it was
+  // based on) and merge commits will have two or more.  Commits can
+  // technically have any number, though it's rare to have more than two.
+  parents  = git_commit_parentcount(commit);
+  for (p = 0;p < parents;p++) {
+    git_commit *parent;
+    git_commit_parent(&parent, commit, p);
+    git_oid_fmt(out, git_commit_id(parent));
+    printf("Parent: %s\n", out);
+    git_commit_free(parent);
+  }
+
+  // Don't forget to close the object to prevent memory leaks. You will have
+  // to do this for all the objects you open and parse.
+  git_commit_free(commit);
+
+  // #### Writing Commits
+
+  // libgit2 provides a couple of methods to create commit objects easily as
+  // well. There are four different create signatures, we'll just show one
+  // of them here.  You can read about the other ones in the [commit API
+  // docs][cd].
+  //
+  // [cd]: http://libgit2.github.com/libgit2/#HEAD/group/commit
+
+  printf("\n*Commit Writing*\n");
+  git_oid tree_id, parent_id, commit_id;
+  git_tree *tree;
+  git_commit *parent;
+
+  // Creating signatures for an authoring identity and time is simple.  You
+  // will need to do this to specify who created a commit and when.  Default
+  // values for the name and email should be found in the `user.name` and
+  // `user.email` configuration options.  See the `config` section of this
+  // example file to see how to access config values.
+  git_signature_new((git_signature **)&author,
+      "Scott Chacon", "schacon at gmail.com", 123456789, 60);
+  git_signature_new((git_signature **)&cmtter,
+      "Scott A Chacon", "scott at github.com", 987654321, 90);
+
+  // Commit objects need a tree to point to and optionally one or more
+  // parents.  Here we're creating oid objects to create the commit with,
+  // but you can also use
+  git_oid_fromstr(&tree_id, "f60079018b664e4e79329a7ef9559c8d9e0378d1");
+  git_tree_lookup(&tree, repo, &tree_id);
+  git_oid_fromstr(&parent_id, "5b5b025afb0b4c913b4c338a42934a3863bf3644");
+  git_commit_lookup(&parent, repo, &parent_id);
+
+  // Here we actually create the commit object with a single call with all
+  // the values we need to create the commit.  The SHA key is written to the
+  // `commit_id` variable here.
+  git_commit_create_v(
+    &commit_id, /* out id */
+    repo,
+    NULL, /* do not update the HEAD */
+    author,
+    cmtter,
+    NULL, /* use default message encoding */
+    "example commit",
+    tree,
+    1, parent);
+
+  // Now we can take a look at the commit SHA we've generated.
+  git_oid_fmt(out, &commit_id);
+  printf("New Commit: %s\n", out);
+
+  // #### Tag Parsing
+
+  // You can parse and create tags with the [tag management API][tm], which
+  // functions very similarly to the commit lookup, parsing and creation
+  // methods, since the objects themselves are very similar.
+  //
+  // [tm]: http://libgit2.github.com/libgit2/#HEAD/group/tag
+  printf("\n*Tag Parsing*\n");
+  git_tag *tag;
+  const char *tmessage, *tname;
+  git_otype ttype;
+
+  // We create an oid for the tag object if we know the SHA and look it up
+  // the same way that we would a commit (or any other object).
+  git_oid_fromstr(&oid, "b25fa35b38051e4ae45d4222e795f9df2e43f1d1");
+
+  error = git_tag_lookup(&tag, repo, &oid);
+  check_error(error, "looking up tag");
+
+  // Now that we have the tag object, we can extract the information it
+  // generally contains: the target (usually a commit object), the type of
+  // the target object (usually 'commit'), the name ('v1.0'), the tagger (a
+  // git_signature - name, email, timestamp), and the tag message.
+  git_tag_target((git_object **)&commit, tag);
+  tname = git_tag_name(tag);		// "test"
+  ttype = git_tag_target_type(tag);	// GIT_OBJ_COMMIT (otype enum)
+  tmessage = git_tag_message(tag);	// "tag message\n"
+  printf("Tag Message: %s\n", tmessage);
+
+  git_commit_free(commit);
+
+  // #### Tree Parsing
+
+  // [Tree parsing][tp] is a bit different than the other objects, in that
+  // we have a subtype which is the tree entry.  This is not an actual
+  // object type in Git, but a useful structure for parsing and traversing
+  // tree entries.
+  //
+  // [tp]: http://libgit2.github.com/libgit2/#HEAD/group/tree
+  printf("\n*Tree Parsing*\n");
+
+  const git_tree_entry *entry;
+  git_object *objt;
+
+  // Create the oid and lookup the tree object just like the other objects.
+  git_oid_fromstr(&oid, "2a741c18ac5ff082a7caaec6e74db3075a1906b5");
+  git_tree_lookup(&tree, repo, &oid);
+
+  // Getting the count of entries in the tree so you can iterate over them
+  // if you want to.
+  size_t cnt = git_tree_entrycount(tree); // 3
+  printf("tree entries: %d\n", (int)cnt);
+
+  entry = git_tree_entry_byindex(tree, 0);
+  printf("Entry name: %s\n", git_tree_entry_name(entry)); // "hello.c"
+
+  // You can also access tree entries by name if you know the name of the
+  // entry you're looking for.
+  entry = git_tree_entry_byname(tree, "README");
+  git_tree_entry_name(entry); // "hello.c"
+
+  // Once you have the entry object, you can access the content or subtree
+  // (or commit, in the case of submodules) that it points to.  You can also
+  // get the mode if you want.
+  git_tree_entry_to_object(&objt, repo, entry); // blob
+
+  // Remember to close the looked-up object once you are done using it
+  git_object_free(objt);
+
+  // #### Blob Parsing
+
+  // The last object type is the simplest and requires the least parsing
+  // help. Blobs are just file contents and can contain anything, there is
+  // no structure to it. The main advantage to using the [simple blob
+  // api][ba] is that when you're creating blobs you don't have to calculate
+  // the size of the content.  There is also a helper for reading a file
+  // from disk and writing it to the db and getting the oid back so you
+  // don't have to do all those steps yourself.
+  //
+  // [ba]: http://libgit2.github.com/libgit2/#HEAD/group/blob
+
+  printf("\n*Blob Parsing*\n");
+  git_blob *blob;
+
+  git_oid_fromstr(&oid, "1385f264afb75a56a5bec74243be9b367ba4ca08");
+  git_blob_lookup(&blob, repo, &oid);
+
+  // You can access a buffer with the raw contents of the blob directly.
+  // Note that this buffer may not be contain ASCII data for certain blobs
+  // (e.g. binary files): do not consider the buffer a NULL-terminated
+  // string, and use the `git_blob_rawsize` attribute to find out its exact
+  // size in bytes
+  printf("Blob Size: %ld\n", (long)git_blob_rawsize(blob)); // 8
+  git_blob_rawcontent(blob); // "content"
+
+  // ### Revwalking
+
+  // The libgit2 [revision walking api][rw] provides methods to traverse the
+  // directed graph created by the parent pointers of the commit objects.
+  // Since all commits point back to the commit that came directly before
+  // them, you can walk this parentage as a graph and find all the commits
+  // that were ancestors of (reachable from) a given starting point.  This
+  // can allow you to create `git log` type functionality.
+  //
+  // [rw]: http://libgit2.github.com/libgit2/#HEAD/group/revwalk
+
+  printf("\n*Revwalking*\n");
+  git_revwalk *walk;
+  git_commit *wcommit;
+
+  git_oid_fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644");
+
+  // To use the revwalker, create a new walker, tell it how you want to sort
+  // the output and then push one or more starting points onto the walker.
+  // If you want to emulate the output of `git log` you would push the SHA
+  // of the commit that HEAD points to into the walker and then start
+  // traversing them.  You can also 'hide' commits that you want to stop at
+  // or not see any of their ancestors.  So if you want to emulate `git log
+  // branch1..branch2`, you would push the oid of `branch2` and hide the oid
+  // of `branch1`.
+  git_revwalk_new(&walk, repo);
+  git_revwalk_sorting(walk, GIT_SORT_TOPOLOGICAL | GIT_SORT_REVERSE);
+  git_revwalk_push(walk, &oid);
+
+  const git_signature *cauth;
+  const char *cmsg;
+
+  // Now that we have the starting point pushed onto the walker, we start
+  // asking for ancestors. It will return them in the sorting order we asked
+  // for as commit oids.  We can then lookup and parse the committed pointed
+  // at by the returned OID; note that this operation is specially fast
+  // since the raw contents of the commit object will be cached in memory
+  while ((git_revwalk_next(&oid, walk)) == 0) {
+    error = git_commit_lookup(&wcommit, repo, &oid);
+	check_error(error, "looking up commit during revwalk");
+
+    cmsg  = git_commit_message(wcommit);
+    cauth = git_commit_author(wcommit);
+    printf("%s (%s)\n", cmsg, cauth->email);
+
+    git_commit_free(wcommit);
+  }
+
+  // Like the other objects, be sure to free the revwalker when you're done
+  // to prevent memory leaks.  Also, make sure that the repository being
+  // walked it not deallocated while the walk is in progress, or it will
+  // result in undefined behavior
+  git_revwalk_free(walk);
+
+  // ### Index File Manipulation
+
+  // The [index file API][gi] allows you to read, traverse, update and write
+  // the Git index file (sometimes thought of as the staging area).
+  //
+  // [gi]: http://libgit2.github.com/libgit2/#HEAD/group/index
+
+  printf("\n*Index Walking*\n");
+
+  git_index *index;
+  unsigned int i, ecount;
+
+  // You can either open the index from the standard location in an open
+  // repository, as we're doing here, or you can open and manipulate any
+  // index file with `git_index_open_bare()`. The index for the repository
+  // will be located and loaded from disk.
+  git_repository_index(&index, repo);
+
+  // For each entry in the index, you can get a bunch of information
+  // including the SHA (oid), path and mode which map to the tree objects
+  // that are written out.  It also has filesystem properties to help
+  // determine what to inspect for changes (ctime, mtime, dev, ino, uid,
+  // gid, file_size and flags) All these properties are exported publicly in
+  // the `git_index_entry` struct
+  ecount = git_index_entrycount(index);
+  for (i = 0; i < ecount; ++i) {
+    const git_index_entry *e = git_index_get_byindex(index, i);
+
+    printf("path: %s\n", e->path);
+    printf("mtime: %d\n", (int)e->mtime.seconds);
+    printf("fs: %d\n", (int)e->file_size);
+  }
+
+  git_index_free(index);
+
+  // ### References
+
+  // The [reference API][ref] allows you to list, resolve, create and update
+  // references such as branches, tags and remote references (everything in
+  // the .git/refs directory).
+  //
+  // [ref]: http://libgit2.github.com/libgit2/#HEAD/group/reference
+
+  printf("\n*Reference Listing*\n");
+
+  // Here we will implement something like `git for-each-ref` simply listing
+  // out all available references and the object SHA they resolve to.
+  git_strarray ref_list;
+  git_reference_list(&ref_list, repo);
+
+  const char *refname;
+  git_reference *ref;
+
+  // Now that we have the list of reference names, we can lookup each ref
+  // one at a time and resolve them to the SHA, then print both values out.
+  for (i = 0; i < ref_list.count; ++i) {
+    refname = ref_list.strings[i];
+    git_reference_lookup(&ref, repo, refname);
+
+    switch (git_reference_type(ref)) {
+    case GIT_REF_OID:
+      git_oid_fmt(out, git_reference_target(ref));
+      printf("%s [%s]\n", refname, out);
+      break;
+
+    case GIT_REF_SYMBOLIC:
+      printf("%s => %s\n", refname, git_reference_symbolic_target(ref));
+      break;
+    default:
+      fprintf(stderr, "Unexpected reference type\n");
+      exit(1);
+    }
+  }
+
+  git_strarray_free(&ref_list);
+
+  // ### Config Files
+
+  // The [config API][config] allows you to list and updatee config values
+  // in any of the accessible config file locations (system, global, local).
+  //
+  // [config]: http://libgit2.github.com/libgit2/#HEAD/group/config
+
+  printf("\n*Config Listing*\n");
+
+  const char *email;
+  int32_t j;
+
+  git_config *cfg;
+
+  // Open a config object so we can read global values from it.
+  char config_path[256];
+  sprintf(config_path, "%s/config", repo_path);
+  check_error(git_config_open_ondisk(&cfg, config_path), "opening config");
+
+  git_config_get_int32(&j, cfg, "help.autocorrect");
+  printf("Autocorrect: %d\n", j);
+
+  git_config_get_string(&email, cfg, "user.email");
+  printf("Email: %s\n", email);
+
+  // Finally, when you're done with the repository, you can free it as well.
+  git_repository_free(repo);
+
+  return 0;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/init.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/init.c
new file mode 100755
index 0000000..fe7a672
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/init.c
@@ -0,0 +1,253 @@
+/*
+ * libgit2 "init" example - shows how to initialize a new repo
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "common.h"
+
+/**
+ * This is a sample program that is similar to "git init".  See the
+ * documentation for that (try "git help init") to understand what this
+ * program is emulating.
+ *
+ * This demonstrates using the libgit2 APIs to initialize a new repository.
+ *
+ * This also contains a special additional option that regular "git init"
+ * does not support which is "--initial-commit" to make a first empty commit.
+ * That is demonstrated in the "create_initial_commit" helper function.
+ */
+
+/** Forward declarations of helpers */
+struct opts {
+	int no_options;
+	int quiet;
+	int bare;
+	int initial_commit;
+	uint32_t shared;
+	const char *template;
+	const char *gitdir;
+	const char *dir;
+};
+static void create_initial_commit(git_repository *repo);
+static void parse_opts(struct opts *o, int argc, char *argv[]);
+
+
+int main(int argc, char *argv[])
+{
+	git_repository *repo = NULL;
+	struct opts o = { 1, 0, 0, 0, GIT_REPOSITORY_INIT_SHARED_UMASK, 0, 0, 0 };
+
+	git_libgit2_init();
+
+	parse_opts(&o, argc, argv);
+
+	/* Initialize repository. */
+
+	if (o.no_options) {
+		/**
+		 * No options were specified, so let's demonstrate the default
+		 * simple case of git_repository_init() API usage...
+		 */
+		check_lg2(git_repository_init(&repo, o.dir, 0),
+			"Could not initialize repository", NULL);
+	}
+	else {
+		/**
+		 * Some command line options were specified, so we'll use the
+		 * extended init API to handle them
+		 */
+		git_repository_init_options initopts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
+		initopts.flags = GIT_REPOSITORY_INIT_MKPATH;
+
+		if (o.bare)
+			initopts.flags |= GIT_REPOSITORY_INIT_BARE;
+
+		if (o.template) {
+			initopts.flags |= GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE;
+			initopts.template_path = o.template;
+		}
+
+		if (o.gitdir) {
+			/**
+			 * If you specified a separate git directory, then initialize
+			 * the repository at that path and use the second path as the
+			 * working directory of the repository (with a git-link file)
+			 */
+			initopts.workdir_path = o.dir;
+			o.dir = o.gitdir;
+		}
+
+		if (o.shared != 0)
+			initopts.mode = o.shared;
+
+		check_lg2(git_repository_init_ext(&repo, o.dir, &initopts),
+				"Could not initialize repository", NULL);
+	}
+
+	/** Print a message to stdout like "git init" does. */
+
+	if (!o.quiet) {
+		if (o.bare || o.gitdir)
+			o.dir = git_repository_path(repo);
+		else
+			o.dir = git_repository_workdir(repo);
+
+		printf("Initialized empty Git repository in %s\n", o.dir);
+	}
+
+	/**
+	 * As an extension to the basic "git init" command, this example
+	 * gives the option to create an empty initial commit.  This is
+	 * mostly to demonstrate what it takes to do that, but also some
+	 * people like to have that empty base commit in their repo.
+	 */
+	if (o.initial_commit) {
+		create_initial_commit(repo);
+		printf("Created empty initial commit\n");
+	}
+
+	git_repository_free(repo);
+	git_libgit2_shutdown();
+
+	return 0;
+}
+
+/**
+ * Unlike regular "git init", this example shows how to create an initial
+ * empty commit in the repository.  This is the helper function that does
+ * that.
+ */
+static void create_initial_commit(git_repository *repo)
+{
+	git_signature *sig;
+	git_index *index;
+	git_oid tree_id, commit_id;
+	git_tree *tree;
+
+	/** First use the config to initialize a commit signature for the user. */
+
+	if (git_signature_default(&sig, repo) < 0)
+		fatal("Unable to create a commit signature.",
+		      "Perhaps 'user.name' and 'user.email' are not set");
+
+	/* Now let's create an empty tree for this commit */
+
+	if (git_repository_index(&index, repo) < 0)
+		fatal("Could not open repository index", NULL);
+
+	/**
+	 * Outside of this example, you could call git_index_add_bypath()
+	 * here to put actual files into the index.  For our purposes, we'll
+	 * leave it empty for now.
+	 */
+
+	if (git_index_write_tree(&tree_id, index) < 0)
+		fatal("Unable to write initial tree from index", NULL);
+
+	git_index_free(index);
+
+	if (git_tree_lookup(&tree, repo, &tree_id) < 0)
+		fatal("Could not look up initial tree", NULL);
+
+	/**
+	 * Ready to create the initial commit.
+	 *
+	 * Normally creating a commit would involve looking up the current
+	 * HEAD commit and making that be the parent of the initial commit,
+	 * but here this is the first commit so there will be no parent.
+	 */
+
+	if (git_commit_create_v(
+			&commit_id, repo, "HEAD", sig, sig,
+			NULL, "Initial commit", tree, 0) < 0)
+		fatal("Could not create the initial commit", NULL);
+
+	/** Clean up so we don't leak memory. */
+
+	git_tree_free(tree);
+	git_signature_free(sig);
+}
+
+static void usage(const char *error, const char *arg)
+{
+	fprintf(stderr, "error: %s '%s'\n", error, arg);
+	fprintf(stderr,
+			"usage: init [-q | --quiet] [--bare] [--template=<dir>]\n"
+			"            [--shared[=perms]] [--initial-commit]\n"
+			"            [--separate-git-dir] <directory>\n");
+	exit(1);
+}
+
+/** Parse the tail of the --shared= argument. */
+static uint32_t parse_shared(const char *shared)
+{
+	if (!strcmp(shared, "false") || !strcmp(shared, "umask"))
+		return GIT_REPOSITORY_INIT_SHARED_UMASK;
+
+	else if (!strcmp(shared, "true") || !strcmp(shared, "group"))
+		return GIT_REPOSITORY_INIT_SHARED_GROUP;
+
+	else if (!strcmp(shared, "all") || !strcmp(shared, "world") ||
+			 !strcmp(shared, "everybody"))
+		return GIT_REPOSITORY_INIT_SHARED_ALL;
+
+	else if (shared[0] == '0') {
+		long val;
+		char *end = NULL;
+		val = strtol(shared + 1, &end, 8);
+		if (end == shared + 1 || *end != 0)
+			usage("invalid octal value for --shared", shared);
+		return (uint32_t)val;
+	}
+
+	else
+		usage("unknown value for --shared", shared);
+
+	return 0;
+}
+
+static void parse_opts(struct opts *o, int argc, char *argv[])
+{
+	struct args_info args = ARGS_INFO_INIT;
+	const char *sharedarg;
+
+	/** Process arguments. */
+
+	for (args.pos = 1; args.pos < argc; ++args.pos) {
+		char *a = argv[args.pos];
+
+		if (a[0] == '-')
+			o->no_options = 0;
+
+		if (a[0] != '-') {
+			if (o->dir != NULL)
+				usage("extra argument", a);
+			o->dir = a;
+		}
+		else if (!strcmp(a, "-q") || !strcmp(a, "--quiet"))
+			o->quiet = 1;
+		else if (!strcmp(a, "--bare"))
+			o->bare = 1;
+		else if (!strcmp(a, "--shared"))
+			o->shared = GIT_REPOSITORY_INIT_SHARED_GROUP;
+		else if (!strcmp(a, "--initial-commit"))
+			o->initial_commit = 1;
+		else if (match_str_arg(&sharedarg, &args, "--shared"))
+			o->shared = parse_shared(sharedarg);
+		else if (!match_str_arg(&o->template, &args, "--template") ||
+		         !match_str_arg(&o->gitdir, &args, "--separate-git-dir"))
+			usage("unknown option", a);
+	}
+
+	if (!o->dir)
+		usage("must specify directory to init", NULL);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/log.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/log.c
new file mode 100755
index 0000000..e54eed3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/log.c
@@ -0,0 +1,479 @@
+/*
+ * libgit2 "log" example - shows how to walk history and get commit info
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "common.h"
+
+/**
+ * This example demonstrates the libgit2 rev walker APIs to roughly
+ * simulate the output of `git log` and a few of command line arguments.
+ * `git log` has many many options and this only shows a few of them.
+ *
+ * This does not have:
+ *
+ * - Robust error handling
+ * - Colorized or paginated output formatting
+ * - Most of the `git log` options
+ *
+ * This does have:
+ *
+ * - Examples of translating command line arguments to equivalent libgit2
+ *   revwalker configuration calls
+ * - Simplified options to apply pathspec limits and to show basic diffs
+ */
+
+/** log_state represents walker being configured while handling options */
+struct log_state {
+	git_repository *repo;
+	const char *repodir;
+	git_revwalk *walker;
+	int hide;
+	int sorting;
+	int revisions;
+};
+
+/** utility functions that are called to configure the walker */
+static void set_sorting(struct log_state *s, unsigned int sort_mode);
+static void push_rev(struct log_state *s, git_object *obj, int hide);
+static int add_revision(struct log_state *s, const char *revstr);
+
+/** log_options holds other command line options that affect log output */
+struct log_options {
+	int show_diff;
+	int skip, limit;
+	int min_parents, max_parents;
+	git_time_t before;
+	git_time_t after;
+	const char *author;
+	const char *committer;
+	const char *grep;
+};
+
+/** utility functions that parse options and help with log output */
+static int parse_options(
+	struct log_state *s, struct log_options *opt, int argc, char **argv);
+static void print_time(const git_time *intime, const char *prefix);
+static void print_commit(git_commit *commit);
+static int match_with_parent(git_commit *commit, int i, git_diff_options *);
+
+/** utility functions for filtering */
+static int signature_matches(const git_signature *sig, const char *filter);
+static int log_message_matches(const git_commit *commit, const char *filter);
+
+int main(int argc, char *argv[])
+{
+	int i, count = 0, printed = 0, parents, last_arg;
+	struct log_state s;
+	struct log_options opt;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_oid oid;
+	git_commit *commit = NULL;
+	git_pathspec *ps = NULL;
+
+	git_libgit2_init();
+
+	/** Parse arguments and set up revwalker. */
+
+	last_arg = parse_options(&s, &opt, argc, argv);
+
+	diffopts.pathspec.strings = &argv[last_arg];
+	diffopts.pathspec.count	  = argc - last_arg;
+	if (diffopts.pathspec.count > 0)
+		check_lg2(git_pathspec_new(&ps, &diffopts.pathspec),
+			"Building pathspec", NULL);
+
+	if (!s.revisions)
+		add_revision(&s, NULL);
+
+	/** Use the revwalker to traverse the history. */
+
+	printed = count = 0;
+
+	for (; !git_revwalk_next(&oid, s.walker); git_commit_free(commit)) {
+		check_lg2(git_commit_lookup(&commit, s.repo, &oid),
+			"Failed to look up commit", NULL);
+
+		parents = (int)git_commit_parentcount(commit);
+		if (parents < opt.min_parents)
+			continue;
+		if (opt.max_parents > 0 && parents > opt.max_parents)
+			continue;
+
+		if (diffopts.pathspec.count > 0) {
+			int unmatched = parents;
+
+			if (parents == 0) {
+				git_tree *tree;
+				check_lg2(git_commit_tree(&tree, commit), "Get tree", NULL);
+				if (git_pathspec_match_tree(
+						NULL, tree, GIT_PATHSPEC_NO_MATCH_ERROR, ps) != 0)
+					unmatched = 1;
+				git_tree_free(tree);
+			} else if (parents == 1) {
+				unmatched = match_with_parent(commit, 0, &diffopts) ? 0 : 1;
+			} else {
+				for (i = 0; i < parents; ++i) {
+					if (match_with_parent(commit, i, &diffopts))
+						unmatched--;
+				}
+			}
+
+			if (unmatched > 0)
+				continue;
+		}
+
+		if (!signature_matches(git_commit_author(commit), opt.author))
+			continue;
+
+		if (!signature_matches(git_commit_committer(commit), opt.committer))
+			continue;
+
+		if (!log_message_matches(commit, opt.grep))
+			continue;
+
+		if (count++ < opt.skip)
+			continue;
+		if (opt.limit != -1 && printed++ >= opt.limit) {
+			git_commit_free(commit);
+			break;
+		}
+
+		print_commit(commit);
+
+		if (opt.show_diff) {
+			git_tree *a = NULL, *b = NULL;
+			git_diff *diff = NULL;
+
+			if (parents > 1)
+				continue;
+			check_lg2(git_commit_tree(&b, commit), "Get tree", NULL);
+			if (parents == 1) {
+				git_commit *parent;
+				check_lg2(git_commit_parent(&parent, commit, 0), "Get parent", NULL);
+				check_lg2(git_commit_tree(&a, parent), "Tree for parent", NULL);
+				git_commit_free(parent);
+			}
+
+			check_lg2(git_diff_tree_to_tree(
+				&diff, git_commit_owner(commit), a, b, &diffopts),
+				"Diff commit with parent", NULL);
+			check_lg2(
+                git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, diff_output, NULL),
+				"Displaying diff", NULL);
+
+			git_diff_free(diff);
+			git_tree_free(a);
+			git_tree_free(b);
+		}
+	}
+
+	git_pathspec_free(ps);
+	git_revwalk_free(s.walker);
+	git_repository_free(s.repo);
+	git_libgit2_shutdown();
+
+	return 0;
+}
+
+/** Determine if the given git_signature does not contain the filter text. */
+static int signature_matches(const git_signature *sig, const char *filter) {
+	if (filter == NULL)
+		return 1;
+
+	if (sig != NULL &&
+		(strstr(sig->name, filter) != NULL ||
+		strstr(sig->email, filter) != NULL))
+		return 1;
+
+	return 0;
+}
+
+static int log_message_matches(const git_commit *commit, const char *filter) {
+	const char *message = NULL;
+
+	if (filter == NULL)
+		return 1;
+
+	if ((message = git_commit_message(commit)) != NULL &&
+		strstr(message, filter) != NULL)
+		return 1;
+
+	return 0;
+}
+
+/** Push object (for hide or show) onto revwalker. */
+static void push_rev(struct log_state *s, git_object *obj, int hide)
+{
+	hide = s->hide ^ hide;
+
+	/** Create revwalker on demand if it doesn't already exist. */
+	if (!s->walker) {
+		check_lg2(git_revwalk_new(&s->walker, s->repo),
+			"Could not create revision walker", NULL);
+		git_revwalk_sorting(s->walker, s->sorting);
+	}
+
+	if (!obj)
+		check_lg2(git_revwalk_push_head(s->walker),
+			"Could not find repository HEAD", NULL);
+	else if (hide)
+		check_lg2(git_revwalk_hide(s->walker, git_object_id(obj)),
+			"Reference does not refer to a commit", NULL);
+	else
+		check_lg2(git_revwalk_push(s->walker, git_object_id(obj)),
+			"Reference does not refer to a commit", NULL);
+
+	git_object_free(obj);
+}
+
+/** Parse revision string and add revs to walker. */
+static int add_revision(struct log_state *s, const char *revstr)
+{
+	git_revspec revs;
+	int hide = 0;
+
+	/** Open repo on demand if it isn't already open. */
+	if (!s->repo) {
+		if (!s->repodir) s->repodir = ".";
+		check_lg2(git_repository_open_ext(&s->repo, s->repodir, 0, NULL),
+			"Could not open repository", s->repodir);
+	}
+
+	if (!revstr) {
+		push_rev(s, NULL, hide);
+		return 0;
+	}
+
+	if (*revstr == '^') {
+		revs.flags = GIT_REVPARSE_SINGLE;
+		hide = !hide;
+
+		if (git_revparse_single(&revs.from, s->repo, revstr + 1) < 0)
+			return -1;
+	} else if (git_revparse(&revs, s->repo, revstr) < 0)
+		return -1;
+
+	if ((revs.flags & GIT_REVPARSE_SINGLE) != 0)
+		push_rev(s, revs.from, hide);
+	else {
+		push_rev(s, revs.to, hide);
+
+		if ((revs.flags & GIT_REVPARSE_MERGE_BASE) != 0) {
+			git_oid base;
+			check_lg2(git_merge_base(&base, s->repo,
+				git_object_id(revs.from), git_object_id(revs.to)),
+				"Could not find merge base", revstr);
+			check_lg2(
+				git_object_lookup(&revs.to, s->repo, &base, GIT_OBJ_COMMIT),
+				"Could not find merge base commit", NULL);
+
+			push_rev(s, revs.to, hide);
+		}
+
+		push_rev(s, revs.from, !hide);
+	}
+
+	return 0;
+}
+
+/** Update revwalker with sorting mode. */
+static void set_sorting(struct log_state *s, unsigned int sort_mode)
+{
+	/** Open repo on demand if it isn't already open. */
+	if (!s->repo) {
+		if (!s->repodir) s->repodir = ".";
+		check_lg2(git_repository_open_ext(&s->repo, s->repodir, 0, NULL),
+			"Could not open repository", s->repodir);
+	}
+
+	/** Create revwalker on demand if it doesn't already exist. */
+	if (!s->walker)
+		check_lg2(git_revwalk_new(&s->walker, s->repo),
+			"Could not create revision walker", NULL);
+
+	if (sort_mode == GIT_SORT_REVERSE)
+		s->sorting = s->sorting ^ GIT_SORT_REVERSE;
+	else
+		s->sorting = sort_mode | (s->sorting & GIT_SORT_REVERSE);
+
+	git_revwalk_sorting(s->walker, s->sorting);
+}
+
+/** Helper to format a git_time value like Git. */
+static void print_time(const git_time *intime, const char *prefix)
+{
+	char sign, out[32];
+	struct tm *intm;
+	int offset, hours, minutes;
+	time_t t;
+
+	offset = intime->offset;
+	if (offset < 0) {
+		sign = '-';
+		offset = -offset;
+	} else {
+		sign = '+';
+	}
+
+	hours   = offset / 60;
+	minutes = offset % 60;
+
+	t = (time_t)intime->time + (intime->offset * 60);
+
+	intm = gmtime(&t);
+	strftime(out, sizeof(out), "%a %b %e %T %Y", intm);
+
+	printf("%s%s %c%02d%02d\n", prefix, out, sign, hours, minutes);
+}
+
+/** Helper to print a commit object. */
+static void print_commit(git_commit *commit)
+{
+	char buf[GIT_OID_HEXSZ + 1];
+	int i, count;
+	const git_signature *sig;
+	const char *scan, *eol;
+
+	git_oid_tostr(buf, sizeof(buf), git_commit_id(commit));
+	printf("commit %s\n", buf);
+
+	if ((count = (int)git_commit_parentcount(commit)) > 1) {
+		printf("Merge:");
+		for (i = 0; i < count; ++i) {
+			git_oid_tostr(buf, 8, git_commit_parent_id(commit, i));
+			printf(" %s", buf);
+		}
+		printf("\n");
+	}
+
+	if ((sig = git_commit_author(commit)) != NULL) {
+		printf("Author: %s <%s>\n", sig->name, sig->email);
+		print_time(&sig->when, "Date:   ");
+	}
+	printf("\n");
+
+	for (scan = git_commit_message(commit); scan && *scan; ) {
+		for (eol = scan; *eol && *eol != '\n'; ++eol) /* find eol */;
+
+		printf("    %.*s\n", (int)(eol - scan), scan);
+		scan = *eol ? eol + 1 : NULL;
+	}
+	printf("\n");
+}
+
+/** Helper to find how many files in a commit changed from its nth parent. */
+static int match_with_parent(git_commit *commit, int i, git_diff_options *opts)
+{
+	git_commit *parent;
+	git_tree *a, *b;
+	git_diff *diff;
+	int ndeltas;
+
+	check_lg2(
+		git_commit_parent(&parent, commit, (size_t)i), "Get parent", NULL);
+	check_lg2(git_commit_tree(&a, parent), "Tree for parent", NULL);
+	check_lg2(git_commit_tree(&b, commit), "Tree for commit", NULL);
+	check_lg2(
+		git_diff_tree_to_tree(&diff, git_commit_owner(commit), a, b, opts),
+		"Checking diff between parent and commit", NULL);
+
+	ndeltas = (int)git_diff_num_deltas(diff);
+
+	git_diff_free(diff);
+	git_tree_free(a);
+	git_tree_free(b);
+	git_commit_free(parent);
+
+	return ndeltas > 0;
+}
+
+/** Print a usage message for the program. */
+static void usage(const char *message, const char *arg)
+{
+	if (message && arg)
+		fprintf(stderr, "%s: %s\n", message, arg);
+	else if (message)
+		fprintf(stderr, "%s\n", message);
+	fprintf(stderr, "usage: log [<options>]\n");
+	exit(1);
+}
+
+/** Parse some log command line options. */
+static int parse_options(
+	struct log_state *s, struct log_options *opt, int argc, char **argv)
+{
+	struct args_info args = ARGS_INFO_INIT;
+
+	memset(s, 0, sizeof(*s));
+	s->sorting = GIT_SORT_TIME;
+
+	memset(opt, 0, sizeof(*opt));
+	opt->max_parents = -1;
+	opt->limit = -1;
+
+	for (args.pos = 1; args.pos < argc; ++args.pos) {
+		const char *a = argv[args.pos];
+
+		if (a[0] != '-') {
+			if (!add_revision(s, a))
+				s->revisions++;
+			else
+				/** Try failed revision parse as filename. */
+				break;
+		} else if (!strcmp(a, "--")) {
+			++args.pos;
+			break;
+		}
+		else if (!strcmp(a, "--date-order"))
+			set_sorting(s, GIT_SORT_TIME);
+		else if (!strcmp(a, "--topo-order"))
+			set_sorting(s, GIT_SORT_TOPOLOGICAL);
+		else if (!strcmp(a, "--reverse"))
+			set_sorting(s, GIT_SORT_REVERSE);
+		else if (match_str_arg(&opt->author, &args, "--author"))
+			/** Found valid --author */;
+		else if (match_str_arg(&opt->committer, &args, "--committer"))
+			/** Found valid --committer */;
+		else if (match_str_arg(&opt->grep, &args, "--grep"))
+			/** Found valid --grep */;
+		else if (match_str_arg(&s->repodir, &args, "--git-dir"))
+			/** Found git-dir. */;
+		else if (match_int_arg(&opt->skip, &args, "--skip", 0))
+			/** Found valid --skip. */;
+		else if (match_int_arg(&opt->limit, &args, "--max-count", 0))
+			/** Found valid --max-count. */;
+		else if (a[1] >= '0' && a[1] <= '9')
+			is_integer(&opt->limit, a + 1, 0);
+		else if (match_int_arg(&opt->limit, &args, "-n", 0))
+			/** Found valid -n. */;
+		else if (!strcmp(a, "--merges"))
+			opt->min_parents = 2;
+		else if (!strcmp(a, "--no-merges"))
+			opt->max_parents = 1;
+		else if (!strcmp(a, "--no-min-parents"))
+			opt->min_parents = 0;
+		else if (!strcmp(a, "--no-max-parents"))
+			opt->max_parents = -1;
+		else if (match_int_arg(&opt->max_parents, &args, "--max-parents=", 1))
+			/** Found valid --max-parents. */;
+		else if (match_int_arg(&opt->min_parents, &args, "--min-parents=", 0))
+			/** Found valid --min_parents. */;
+		else if (!strcmp(a, "-p") || !strcmp(a, "-u") || !strcmp(a, "--patch"))
+			opt->show_diff = 1;
+		else
+			usage("Unsupported argument", a);
+	}
+
+	return args.pos;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/.gitignore b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/.gitignore
new file mode 100755
index 0000000..1b48e66
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/.gitignore
@@ -0,0 +1 @@
+/git2
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/Makefile b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/Makefile
new file mode 100755
index 0000000..f65c6cb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/Makefile
@@ -0,0 +1,22 @@
+default: all
+
+CC = gcc
+CFLAGS += -g
+CFLAGS += -I../../include
+LDFLAGS += -L../../build -L../..
+LIBRARIES += -lgit2 -lpthread
+
+OBJECTS = \
+  git2.o \
+  ls-remote.o \
+  fetch.o \
+  clone.o \
+  index-pack.o \
+  common.o
+
+all: $(OBJECTS)
+	$(CC) $(CFLAGS) $(LDFLAGS) -o git2 $(OBJECTS) $(LIBRARIES)
+
+clean:
+	$(RM) $(OBJECTS)
+	$(RM) git2
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/clone.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/clone.c
new file mode 100755
index 0000000..caf41cc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/clone.c
@@ -0,0 +1,113 @@
+#include "common.h"
+#include <git2.h>
+#include <git2/clone.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef _WIN32
+# include <pthread.h>
+# include <unistd.h>
+#endif
+
+typedef struct progress_data {
+	git_transfer_progress fetch_progress;
+	size_t completed_steps;
+	size_t total_steps;
+	const char *path;
+} progress_data;
+
+static void print_progress(const progress_data *pd)
+{
+	int network_percent = pd->fetch_progress.total_objects > 0 ?
+		(100*pd->fetch_progress.received_objects) / pd->fetch_progress.total_objects :
+		0;
+	int index_percent = pd->fetch_progress.total_objects > 0 ?
+		(100*pd->fetch_progress.indexed_objects) / pd->fetch_progress.total_objects :
+		0;
+
+	int checkout_percent = pd->total_steps > 0
+		? (100 * pd->completed_steps) / pd->total_steps
+		: 0;
+	int kbytes = pd->fetch_progress.received_bytes / 1024;
+
+	if (pd->fetch_progress.total_objects &&
+		pd->fetch_progress.received_objects == pd->fetch_progress.total_objects) {
+		printf("Resolving deltas %d/%d\r",
+		       pd->fetch_progress.indexed_deltas,
+		       pd->fetch_progress.total_deltas);
+	} else {
+		printf("net %3d%% (%4d kb, %5d/%5d)  /  idx %3d%% (%5d/%5d)  /  chk %3d%% (%4" PRIuZ "/%4" PRIuZ ") %s\n",
+		   network_percent, kbytes,
+		   pd->fetch_progress.received_objects, pd->fetch_progress.total_objects,
+		   index_percent, pd->fetch_progress.indexed_objects, pd->fetch_progress.total_objects,
+		   checkout_percent,
+		   pd->completed_steps, pd->total_steps,
+		   pd->path);
+	}
+}
+
+static int sideband_progress(const char *str, int len, void *payload)
+{
+	(void)payload; // unused
+
+	printf("remote: %*s", len, str);
+	fflush(stdout);
+	return 0;
+}
+
+static int fetch_progress(const git_transfer_progress *stats, void *payload)
+{
+	progress_data *pd = (progress_data*)payload;
+	pd->fetch_progress = *stats;
+	print_progress(pd);
+	return 0;
+}
+static void checkout_progress(const char *path, size_t cur, size_t tot, void *payload)
+{
+	progress_data *pd = (progress_data*)payload;
+	pd->completed_steps = cur;
+	pd->total_steps = tot;
+	pd->path = path;
+	print_progress(pd);
+}
+
+
+int do_clone(git_repository *repo, int argc, char **argv)
+{
+	progress_data pd = {{0}};
+	git_repository *cloned_repo = NULL;
+	git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
+	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
+	const char *url = argv[1];
+	const char *path = argv[2];
+	int error;
+
+	(void)repo; // unused
+
+	// Validate args
+	if (argc < 3) {
+		printf ("USAGE: %s <url> <path>\n", argv[0]);
+		return -1;
+	}
+
+	// Set up options
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+	checkout_opts.progress_cb = checkout_progress;
+	checkout_opts.progress_payload = &pd;
+	clone_opts.checkout_opts = checkout_opts;
+	clone_opts.fetch_opts.callbacks.sideband_progress = sideband_progress;
+	clone_opts.fetch_opts.callbacks.transfer_progress = &fetch_progress;
+	clone_opts.fetch_opts.callbacks.credentials = cred_acquire_cb;
+	clone_opts.fetch_opts.callbacks.payload = &pd;
+
+	// Do the clone
+	error = git_clone(&cloned_repo, url, path, &clone_opts);
+	printf("\n");
+	if (error != 0) {
+		const git_error *err = giterr_last();
+		if (err) printf("ERROR %d: %s\n", err->klass, err->message);
+		else printf("ERROR %d: no detailed info\n", error);
+	}
+	else if (cloned_repo) git_repository_free(cloned_repo);
+	return error;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/common.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/common.c
new file mode 100755
index 0000000..d123eed
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/common.c
@@ -0,0 +1,34 @@
+#include "common.h"
+#include <stdio.h>
+
+/* Shamelessly borrowed from http://stackoverflow.com/questions/3417837/
+ * with permission of the original author, Martin Pool.
+ * http://sourcefrog.net/weblog/software/languages/C/unused.html
+ */
+#ifdef UNUSED
+#elif defined(__GNUC__)
+# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
+#elif defined(__LCLINT__)
+# define UNUSED(x) /*@unused@*/ x
+#else
+# define UNUSED(x) x
+#endif
+
+int cred_acquire_cb(git_cred **out,
+		const char * UNUSED(url),
+		const char * UNUSED(username_from_url),
+		unsigned int UNUSED(allowed_types),
+		void * UNUSED(payload))
+{
+	char username[128] = {0};
+	char password[128] = {0};
+
+	printf("Username: ");
+	scanf("%s", username);
+
+	/* Yup. Right there on your terminal. Careful where you copy/paste output. */
+	printf("Password: ");
+	scanf("%s", password);
+
+	return git_cred_userpass_plaintext_new(out, username, password);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/common.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/common.h
new file mode 100755
index 0000000..1b09caa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/common.h
@@ -0,0 +1,30 @@
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#include <git2.h>
+
+typedef int (*git_cb)(git_repository *, int , char **);
+
+int ls_remote(git_repository *repo, int argc, char **argv);
+int parse_pkt_line(git_repository *repo, int argc, char **argv);
+int show_remote(git_repository *repo, int argc, char **argv);
+int fetch(git_repository *repo, int argc, char **argv);
+int index_pack(git_repository *repo, int argc, char **argv);
+int do_clone(git_repository *repo, int argc, char **argv);
+
+int cred_acquire_cb(git_cred **out,
+		const char * url,
+		const char * username_from_url,
+		unsigned int allowed_types,
+		void *payload);
+
+#ifndef PRIuZ
+/* Define the printf format specifer to use for size_t output */
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#	define PRIuZ "Iu"
+#else
+#	define PRIuZ "zu"
+#endif
+#endif
+
+#endif /* __COMMON_H__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/fetch.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/fetch.c
new file mode 100755
index 0000000..6be1240
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/fetch.c
@@ -0,0 +1,170 @@
+#include "common.h"
+#include <git2.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef _WIN32
+# include <pthread.h>
+# include <unistd.h>
+#endif
+
+struct dl_data {
+	git_remote *remote;
+	git_fetch_options *fetch_opts;
+	int ret;
+	int finished;
+};
+
+static int progress_cb(const char *str, int len, void *data)
+{
+	(void)data;
+	printf("remote: %.*s", len, str);
+	fflush(stdout); /* We don't have the \n to force the flush */
+	return 0;
+}
+
+static void *download(void *ptr)
+{
+	struct dl_data *data = (struct dl_data *)ptr;
+
+	// Connect to the remote end specifying that we want to fetch
+	// information from it.
+	if (git_remote_connect(data->remote, GIT_DIRECTION_FETCH, &data->fetch_opts->callbacks) < 0) {
+		data->ret = -1;
+		goto exit;
+	}
+
+	// Download the packfile and index it. This function updates the
+	// amount of received data and the indexer stats which lets you
+	// inform the user about progress.
+	if (git_remote_download(data->remote, NULL, data->fetch_opts) < 0) {
+		data->ret = -1;
+		goto exit;
+	}
+
+	data->ret = 0;
+
+exit:
+	data->finished = 1;
+	return &data->ret;
+}
+
+/**
+ * This function gets called for each remote-tracking branch that gets
+ * updated. The message we output depends on whether it's a new one or
+ * an update.
+ */
+static int update_cb(const char *refname, const git_oid *a, const git_oid *b, void *data)
+{
+	char a_str[GIT_OID_HEXSZ+1], b_str[GIT_OID_HEXSZ+1];
+	(void)data;
+
+	git_oid_fmt(b_str, b);
+	b_str[GIT_OID_HEXSZ] = '\0';
+
+	if (git_oid_iszero(a)) {
+		printf("[new]     %.20s %s\n", b_str, refname);
+	} else {
+		git_oid_fmt(a_str, a);
+		a_str[GIT_OID_HEXSZ] = '\0';
+		printf("[updated] %.10s..%.10s %s\n", a_str, b_str, refname);
+	}
+
+	return 0;
+}
+
+/** Entry point for this command */
+int fetch(git_repository *repo, int argc, char **argv)
+{
+	git_remote *remote = NULL;
+	const git_transfer_progress *stats;
+	struct dl_data data;
+	git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
+#ifndef _WIN32
+	pthread_t worker;
+#endif
+
+	if (argc < 2) {
+		fprintf(stderr, "usage: %s fetch <repo>\n", argv[-1]);
+		return EXIT_FAILURE;
+	}
+
+	// Figure out whether it's a named remote or a URL
+	printf("Fetching %s for repo %p\n", argv[1], repo);
+	if (git_remote_lookup(&remote, repo, argv[1]) < 0) {
+		if (git_remote_create_anonymous(&remote, repo, argv[1]) < 0)
+			return -1;
+	}
+
+	// Set up the callbacks (only update_tips for now)
+	fetch_opts.callbacks.update_tips = &update_cb;
+	fetch_opts.callbacks.sideband_progress = &progress_cb;
+	fetch_opts.callbacks.credentials = cred_acquire_cb;
+
+	// Set up the information for the background worker thread
+	data.remote = remote;
+	data.fetch_opts = &fetch_opts;
+	data.ret = 0;
+	data.finished = 0;
+
+	stats = git_remote_stats(remote);
+
+#ifdef _WIN32
+	download(&data);
+#else
+	pthread_create(&worker, NULL, download, &data);
+
+	// Loop while the worker thread is still running. Here we show processed
+	// and total objects in the pack and the amount of received
+	// data. Most frontends will probably want to show a percentage and
+	// the download rate.
+	do {
+		usleep(10000);
+
+		if (stats->received_objects == stats->total_objects) {
+			printf("Resolving deltas %d/%d\r",
+			       stats->indexed_deltas, stats->total_deltas);
+		} else if (stats->total_objects > 0) {
+			printf("Received %d/%d objects (%d) in %" PRIuZ " bytes\r",
+			       stats->received_objects, stats->total_objects,
+				   stats->indexed_objects, stats->received_bytes);
+		}
+	} while (!data.finished);
+
+	if (data.ret < 0)
+		goto on_error;
+
+	pthread_join(worker, NULL);
+#endif
+
+	/**
+	 * If there are local objects (we got a thin pack), then tell
+	 * the user how many objects we saved from having to cross the
+	 * network.
+	 */
+	if (stats->local_objects > 0) {
+		printf("\rReceived %d/%d objects in %" PRIuZ " bytes (used %d local objects)\n",
+		       stats->indexed_objects, stats->total_objects, stats->received_bytes, stats->local_objects);
+	} else{
+		printf("\rReceived %d/%d objects in %" PRIuZ "bytes\n",
+			stats->indexed_objects, stats->total_objects, stats->received_bytes);
+	}
+
+	// Disconnect the underlying connection to prevent from idling.
+	git_remote_disconnect(remote);
+
+	// Update the references in the remote's namespace to point to the
+	// right commits. This may be needed even if there was no packfile
+	// to download, which can happen e.g. when the branches have been
+	// changed but all the needed objects are available locally.
+	if (git_remote_update_tips(remote, &fetch_opts.callbacks, 1, fetch_opts.download_tags, NULL) < 0)
+		return -1;
+
+	git_remote_free(remote);
+
+	return 0;
+
+ on_error:
+	git_remote_free(remote);
+	return -1;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/git2.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/git2.c
new file mode 100755
index 0000000..448103c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/git2.c
@@ -0,0 +1,73 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "common.h"
+
+// This part is not strictly libgit2-dependent, but you can use this
+// as a starting point for a git-like tool
+
+struct {
+	char *name;
+	git_cb fn;
+} commands[] = {
+	{"ls-remote", ls_remote},
+	{"fetch", fetch},
+	{"clone", do_clone},
+	{"index-pack", index_pack},
+	{ NULL, NULL}
+};
+
+static int run_command(git_cb fn, int argc, char **argv)
+{
+	int error;
+	git_repository *repo;
+
+	// Before running the actual command, create an instance of the local
+	// repository and pass it to the function.
+
+	error = git_repository_open(&repo, ".git");
+	if (error < 0)
+		repo = NULL;
+
+	// Run the command. If something goes wrong, print the error message to stderr
+	error = fn(repo, argc, argv);
+	if (error < 0) {
+		if (giterr_last() == NULL)
+			fprintf(stderr, "Error without message");
+		else
+			fprintf(stderr, "Bad news:\n %s\n", giterr_last()->message);
+	}
+
+	if(repo)
+		git_repository_free(repo);
+
+	return !!error;
+}
+
+int main(int argc, char **argv)
+{
+	int i;
+	int return_code = 1;
+
+	if (argc < 2) {
+		fprintf(stderr, "usage: %s <cmd> [repo]\n", argv[0]);
+		exit(EXIT_FAILURE);
+	}
+
+	git_libgit2_init();
+
+	for (i = 0; commands[i].name != NULL; ++i) {
+		if (!strcmp(argv[1], commands[i].name)) {
+			return_code = run_command(commands[i].fn, --argc, ++argv);
+			goto shutdown;
+		}
+	}
+
+	fprintf(stderr, "Command not found: %s\n", argv[1]);
+
+shutdown:
+	git_libgit2_shutdown();
+
+	return return_code;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/index-pack.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/index-pack.c
new file mode 100755
index 0000000..314f211
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/index-pack.c
@@ -0,0 +1,88 @@
+#include <git2.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef _WIN32
+# include <io.h>
+# include <Windows.h>
+
+# define open _open
+# define read _read
+# define close _close
+
+#define ssize_t unsigned int
+#else
+# include <unistd.h>
+#endif
+#include "common.h"
+
+// This could be run in the main loop whilst the application waits for
+// the indexing to finish in a worker thread
+static int index_cb(const git_transfer_progress *stats, void *data)
+{
+	(void)data;
+	printf("\rProcessing %d of %d", stats->indexed_objects, stats->total_objects);
+
+	return 0;
+}
+
+int index_pack(git_repository *repo, int argc, char **argv)
+{
+	git_indexer *idx;
+	git_transfer_progress stats = {0, 0};
+	int error;
+	char hash[GIT_OID_HEXSZ + 1] = {0};
+	int fd;
+	ssize_t read_bytes;
+	char buf[512];
+
+	(void)repo;
+
+	if (argc < 2) {
+		fprintf(stderr, "usage: %s index-pack <packfile>\n", argv[-1]);
+		return EXIT_FAILURE;
+	}
+
+	if (git_indexer_new(&idx, ".", 0, NULL, NULL, NULL) < 0) {
+		puts("bad idx");
+		return -1;
+	}
+
+	if ((fd = open(argv[1], 0)) < 0) {
+		perror("open");
+		return -1;
+	}
+
+	do {
+		read_bytes = read(fd, buf, sizeof(buf));
+		if (read_bytes < 0)
+			break;
+
+		if ((error = git_indexer_append(idx, buf, read_bytes, &stats)) < 0)
+			goto cleanup;
+
+		index_cb(&stats, NULL);
+	} while (read_bytes > 0);
+
+	if (read_bytes < 0) {
+		error = -1;
+		perror("failed reading");
+		goto cleanup;
+	}
+
+	if ((error = git_indexer_commit(idx, &stats)) < 0)
+		goto cleanup;
+
+	printf("\rIndexing %d of %d\n", stats.indexed_objects, stats.total_objects);
+
+	git_oid_fmt(hash, git_indexer_hash(idx));
+	puts(hash);
+
+ cleanup:
+	close(fd);
+	git_indexer_free(idx);
+	return error;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/ls-remote.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/ls-remote.c
new file mode 100755
index 0000000..2102656
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/network/ls-remote.c
@@ -0,0 +1,64 @@
+#include <git2.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "common.h"
+
+static int use_remote(git_repository *repo, char *name)
+{
+	git_remote *remote = NULL;
+	int error;
+	const git_remote_head **refs;
+	size_t refs_len, i;
+	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
+
+	// Find the remote by name
+	error = git_remote_lookup(&remote, repo, name);
+	if (error < 0) {
+		error = git_remote_create_anonymous(&remote, repo, name);
+		if (error < 0)
+			goto cleanup;
+	}
+
+	/**
+	 * Connect to the remote and call the printing function for
+	 * each of the remote references.
+	 */
+	callbacks.credentials = cred_acquire_cb;
+
+	error = git_remote_connect(remote, GIT_DIRECTION_FETCH, &callbacks);
+	if (error < 0)
+		goto cleanup;
+
+	/**
+	 * Get the list of references on the remote and print out
+	 * their name next to what they point to.
+	 */
+	if (git_remote_ls(&refs, &refs_len, remote) < 0)
+		goto cleanup;
+
+	for (i = 0; i < refs_len; i++) {
+		char oid[GIT_OID_HEXSZ + 1] = {0};
+		git_oid_fmt(oid, &refs[i]->oid);
+		printf("%s\t%s\n", oid, refs[i]->name);
+	}
+
+cleanup:
+	git_remote_free(remote);
+	return error;
+}
+
+/** Entry point for this command */
+int ls_remote(git_repository *repo, int argc, char **argv)
+{
+	int error;
+
+	if (argc < 2) {
+		fprintf(stderr, "usage: %s ls-remote <remote>\n", argv[-1]);
+		return EXIT_FAILURE;
+	}
+
+	error = use_remote(repo, argv[1]);
+
+	return error;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/remote.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/remote.c
new file mode 100755
index 0000000..e0d5a14
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/remote.c
@@ -0,0 +1,269 @@
+/*
+ * libgit2 "remote" example - shows how to modify remotes for a repo
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "common.h"
+
+/**
+ * This is a sample program that is similar to "git remote".  See the
+ * documentation for that (try "git help remote") to understand what this
+ * program is emulating.
+ *
+ * This demonstrates using the libgit2 APIs to modify remotes of a repository.
+ */
+
+enum subcmd {
+	subcmd_add,
+	subcmd_remove,
+	subcmd_rename,
+	subcmd_seturl,
+	subcmd_show,
+};
+
+struct opts {
+	enum subcmd cmd;
+
+	/* for command-specific args */
+	int argc;
+	char **argv;
+};
+
+static int cmd_add(git_repository *repo, struct opts *o);
+static int cmd_remove(git_repository *repo, struct opts *o);
+static int cmd_rename(git_repository *repo, struct opts *o);
+static int cmd_seturl(git_repository *repo, struct opts *o);
+static int cmd_show(git_repository *repo, struct opts *o);
+
+static void parse_subcmd(
+	struct opts *opt, int argc, char **argv);
+static void usage(const char *msg, const char *arg);
+
+int main(int argc, char *argv[])
+{
+	int retval = 0;
+	struct opts opt = {0};
+	git_buf buf = GIT_BUF_INIT_CONST(NULL, 0);
+	git_repository *repo = NULL;
+
+	parse_subcmd(&opt, argc, argv);
+
+	git_libgit2_init();
+
+	check_lg2(git_repository_discover(&buf, ".", 0, NULL),
+		"Could not find repository", NULL);
+
+	check_lg2(git_repository_open(&repo, buf.ptr),
+		"Could not open repository", NULL);
+	git_buf_free(&buf);
+
+	switch (opt.cmd)
+	{
+	case subcmd_add:
+		retval = cmd_add(repo, &opt);
+		break;
+	case subcmd_remove:
+		retval = cmd_remove(repo, &opt);
+		break;
+	case subcmd_rename:
+		retval = cmd_rename(repo, &opt);
+		break;
+	case subcmd_seturl:
+		retval = cmd_seturl(repo, &opt);
+		break;
+	case subcmd_show:
+		retval = cmd_show(repo, &opt);
+		break;
+	}
+
+	git_libgit2_shutdown();
+
+	return retval;
+}
+
+static int cmd_add(git_repository *repo, struct opts *o)
+{
+	char *name, *url;
+	git_remote *remote = {0};
+
+	if (o->argc != 2)
+		usage("you need to specify a name and URL", NULL);
+
+	name = o->argv[0];
+	url = o->argv[1];
+
+	check_lg2(git_remote_create(&remote, repo, name, url),
+			"could not create remote", NULL);
+
+	return 0;
+}
+
+static int cmd_remove(git_repository *repo, struct opts *o)
+{
+	char *name;
+
+	if (o->argc != 1)
+		usage("you need to specify a name", NULL);
+
+	name = o->argv[0];
+
+	check_lg2(git_remote_delete(repo, name),
+			"could not delete remote", name);
+
+	return 0;
+}
+
+static int cmd_rename(git_repository *repo, struct opts *o)
+{
+	int i, retval;
+	char *old, *new;
+	git_strarray problems = {0};
+
+	if (o->argc != 2)
+		usage("you need to specify old and new remote name", NULL);
+
+	old = o->argv[0];
+	new = o->argv[1];
+
+	retval = git_remote_rename(&problems, repo, old, new);
+	if (!retval)
+		return 0;
+
+	for (i = 0; i < (int) problems.count; i++) {
+		puts(problems.strings[0]);
+	}
+
+	git_strarray_free(&problems);
+
+	return retval;
+}
+
+static int cmd_seturl(git_repository *repo, struct opts *o)
+{
+	int i, retval, push = 0;
+	char *name = NULL, *url = NULL;
+
+	for (i = 0; i < o->argc; i++) {
+		char *arg = o->argv[i];
+
+		if (!strcmp(arg, "--push")) {
+			push = 1;
+		} else if (arg[0] != '-' && name == NULL) {
+			name = arg;
+		} else if (arg[0] != '-' && url == NULL) {
+			url = arg;
+		} else {
+			usage("invalid argument to set-url", arg);
+		}
+	}
+
+	if (name == NULL || url == NULL)
+		usage("you need to specify remote and the new URL", NULL);
+
+	if (push)
+		retval = git_remote_set_pushurl(repo, name, url);
+	else
+		retval = git_remote_set_url(repo, name, url);
+
+	check_lg2(retval, "could not set URL", url);
+
+	return 0;
+}
+
+static int cmd_show(git_repository *repo, struct opts *o)
+{
+	int i;
+	const char *arg, *name, *fetch, *push;
+	int verbose = 0;
+	git_strarray remotes = {0};
+	git_remote *remote = {0};
+
+	for (i = 0; i < o->argc; i++) {
+		arg = o->argv[i];
+
+		if (!strcmp(arg, "-v") || !strcmp(arg, "--verbose")) {
+			verbose = 1;
+		}
+	}
+
+	check_lg2(git_remote_list(&remotes, repo),
+		"could not retrieve remotes", NULL);
+
+	for (i = 0; i < (int) remotes.count; i++) {
+		name = remotes.strings[i];
+		if (!verbose) {
+			puts(name);
+			continue;
+		}
+
+		check_lg2(git_remote_lookup(&remote, repo, name),
+			"could not look up remote", name);
+
+		fetch = git_remote_url(remote);
+		if (fetch)
+			printf("%s\t%s (fetch)\n", name, fetch);
+		push = git_remote_pushurl(remote);
+		/* use fetch URL if no distinct push URL has been set */
+		push = push ? push : fetch;
+		if (push)
+			printf("%s\t%s (push)\n", name, push);
+
+		git_remote_free(remote);
+	}
+
+	git_strarray_free(&remotes);
+
+	return 0;
+}
+
+static void parse_subcmd(
+	struct opts *opt, int argc, char **argv)
+{
+	char *arg = argv[1];
+	enum subcmd cmd = 0;
+
+	if (argc < 2)
+		usage("no command specified", NULL);
+
+	if (!strcmp(arg, "add")) {
+		cmd = subcmd_add;
+	} else if (!strcmp(arg, "remove")) {
+		cmd = subcmd_remove;
+	} else if (!strcmp(arg, "rename")) {
+		cmd = subcmd_rename;
+	} else if (!strcmp(arg, "set-url")) {
+		cmd = subcmd_seturl;
+	} else if (!strcmp(arg, "show")) {
+		cmd = subcmd_show;
+	} else {
+		usage("command is not valid", arg);
+	}
+	opt->cmd = cmd;
+
+	opt->argc = argc - 2; /* executable and subcommand are removed */
+	opt->argv = argv + 2;
+}
+
+static void usage(const char *msg, const char *arg)
+{
+	fputs("usage: remote add <name> <url>\n", stderr);
+	fputs("       remote remove <name>\n", stderr);
+	fputs("       remote rename <old> <new>\n", stderr);
+	fputs("       remote set-url [--push] <name> <newurl>\n", stderr);
+	fputs("       remote show [-v|--verbose]\n", stderr);
+
+	if (msg && !arg)
+		fprintf(stderr, "\n%s\n", msg);
+	else if (msg && arg)
+		fprintf(stderr, "\n%s: %s\n", msg, arg);
+	exit(1);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/rev-list.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/rev-list.c
new file mode 100755
index 0000000..ee9afc4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/rev-list.c
@@ -0,0 +1,121 @@
+/*
+ * libgit2 "rev-list" example - shows how to transform a rev-spec into a list
+ * of commit ids
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "common.h"
+
+static int revwalk_parseopts(git_repository *repo, git_revwalk *walk, int nopts, char **opts);
+
+int main (int argc, char **argv)
+{
+	git_repository *repo;
+	git_revwalk *walk;
+	git_oid oid;
+	char buf[GIT_OID_HEXSZ+1];
+
+	git_libgit2_init();
+
+	check_lg2(git_repository_open_ext(&repo, ".", 0, NULL), "opening repository", NULL);
+	check_lg2(git_revwalk_new(&walk, repo), "allocating revwalk", NULL);
+	check_lg2(revwalk_parseopts(repo, walk, argc-1, argv+1), "parsing options", NULL);
+
+	while (!git_revwalk_next(&oid, walk)) {
+		git_oid_fmt(buf, &oid);
+		buf[GIT_OID_HEXSZ] = '\0';
+		printf("%s\n", buf);
+	}
+
+	git_libgit2_shutdown();
+	return 0;
+}
+
+static int push_commit(git_revwalk *walk, const git_oid *oid, int hide)
+{
+	if (hide)
+		return git_revwalk_hide(walk, oid);
+	else
+		return git_revwalk_push(walk, oid);
+}
+
+static int push_spec(git_repository *repo, git_revwalk *walk, const char *spec, int hide)
+{
+	int error;
+	git_object *obj;
+
+	if ((error = git_revparse_single(&obj, repo, spec)) < 0)
+		return error;
+
+	error = push_commit(walk, git_object_id(obj), hide);
+	git_object_free(obj);
+	return error;
+}
+
+static int push_range(git_repository *repo, git_revwalk *walk, const char *range, int hide)
+{
+	git_revspec revspec;
+	int error = 0;
+
+	if ((error = git_revparse(&revspec, repo, range)))
+		return error;
+
+	if (revspec.flags & GIT_REVPARSE_MERGE_BASE) {
+		/* TODO: support "<commit>...<commit>" */
+		return GIT_EINVALIDSPEC;
+	}
+
+	if ((error = push_commit(walk, git_object_id(revspec.from), !hide)))
+		goto out;
+
+	error = push_commit(walk, git_object_id(revspec.to), hide);
+
+out:
+	git_object_free(revspec.from);
+	git_object_free(revspec.to);
+	return error;
+}
+
+static int revwalk_parseopts(git_repository *repo, git_revwalk *walk, int nopts, char **opts)
+{
+	int hide, i, error;
+	unsigned int sorting = GIT_SORT_NONE;
+
+	hide = 0;
+	for (i = 0; i < nopts; i++) {
+		if (!strcmp(opts[i], "--topo-order")) {
+			sorting = GIT_SORT_TOPOLOGICAL | (sorting & GIT_SORT_REVERSE);
+			git_revwalk_sorting(walk, sorting);
+		} else if (!strcmp(opts[i], "--date-order")) {
+			sorting = GIT_SORT_TIME | (sorting & GIT_SORT_REVERSE);
+			git_revwalk_sorting(walk, sorting);
+		} else if (!strcmp(opts[i], "--reverse")) {
+			sorting = (sorting & ~GIT_SORT_REVERSE)
+			    | ((sorting & GIT_SORT_REVERSE) ? 0 : GIT_SORT_REVERSE);
+			git_revwalk_sorting(walk, sorting);
+		} else if (!strcmp(opts[i], "--not")) {
+			hide = !hide;
+		} else if (opts[i][0] == '^') {
+			if ((error = push_spec(repo, walk, opts[i] + 1, !hide)))
+				return error;
+		} else if (strstr(opts[i], "..")) {
+			if ((error = push_range(repo, walk, opts[i], hide)))
+				return error;
+		} else {
+			if ((error = push_spec(repo, walk, opts[i], hide)))
+				return error;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/rev-parse.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/rev-parse.c
new file mode 100755
index 0000000..483d6e0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/rev-parse.c
@@ -0,0 +1,115 @@
+/*
+ * libgit2 "rev-parse" example - shows how to parse revspecs
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "common.h"
+
+/** Forward declarations for helpers. */
+struct parse_state {
+	git_repository *repo;
+	const char *repodir;
+	const char *spec;
+	int not;
+};
+static void parse_opts(struct parse_state *ps, int argc, char *argv[]);
+static int parse_revision(struct parse_state *ps);
+
+
+int main(int argc, char *argv[])
+{
+	struct parse_state ps = {0};
+
+	git_libgit2_init();
+	parse_opts(&ps, argc, argv);
+
+	check_lg2(parse_revision(&ps), "Parsing", NULL);
+
+	git_repository_free(ps.repo);
+	git_libgit2_shutdown();
+
+	return 0;
+}
+
+static void usage(const char *message, const char *arg)
+{
+	if (message && arg)
+		fprintf(stderr, "%s: %s\n", message, arg);
+	else if (message)
+		fprintf(stderr, "%s\n", message);
+	fprintf(stderr, "usage: rev-parse [ --option ] <args>...\n");
+	exit(1);
+}
+
+static void parse_opts(struct parse_state *ps, int argc, char *argv[])
+{
+	struct args_info args = ARGS_INFO_INIT;
+
+	for (args.pos=1; args.pos < argc; ++args.pos) {
+		const char *a = argv[args.pos];
+
+		if (a[0] != '-') {
+			if (ps->spec)
+				usage("Too many specs", a);
+			ps->spec = a;
+		} else if (!strcmp(a, "--not"))
+			ps->not = !ps->not;
+		else if (!match_str_arg(&ps->repodir, &args, "--git-dir"))
+			usage("Cannot handle argument", a);
+	}
+}
+
+static int parse_revision(struct parse_state *ps)
+{
+	git_revspec rs;
+	char str[GIT_OID_HEXSZ + 1];
+
+	if (!ps->repo) {
+		if (!ps->repodir)
+			ps->repodir = ".";
+		check_lg2(git_repository_open_ext(&ps->repo, ps->repodir, 0, NULL),
+			"Could not open repository from", ps->repodir);
+	}
+
+	check_lg2(git_revparse(&rs, ps->repo, ps->spec), "Could not parse", ps->spec);
+
+	if ((rs.flags & GIT_REVPARSE_SINGLE) != 0) {
+		git_oid_tostr(str, sizeof(str), git_object_id(rs.from));
+		printf("%s\n", str);
+		git_object_free(rs.from);
+	}
+	else if ((rs.flags & GIT_REVPARSE_RANGE) != 0) {
+		git_oid_tostr(str, sizeof(str), git_object_id(rs.to));
+		printf("%s\n", str);
+		git_object_free(rs.to);
+
+		if ((rs.flags & GIT_REVPARSE_MERGE_BASE) != 0) {
+			git_oid base;
+			check_lg2(git_merge_base(&base, ps->repo,
+						git_object_id(rs.from), git_object_id(rs.to)),
+					"Could not find merge base", ps->spec);
+
+			git_oid_tostr(str, sizeof(str), &base);
+			printf("%s\n", str);
+		}
+
+		git_oid_tostr(str, sizeof(str), git_object_id(rs.from));
+		printf("^%s\n", str);
+		git_object_free(rs.from);
+	}
+	else {
+		fatal("Invalid results from git_revparse", ps->spec);
+	}
+
+	return 0;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/showindex.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/showindex.c
new file mode 100755
index 0000000..43be5e2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/showindex.c
@@ -0,0 +1,70 @@
+/*
+ * libgit2 "showindex" example - shows how to extract data from the index
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "common.h"
+
+int main (int argc, char** argv)
+{
+	git_index *index;
+	unsigned int i, ecount;
+	char *dir = ".";
+	size_t dirlen;
+	char out[GIT_OID_HEXSZ+1];
+	out[GIT_OID_HEXSZ] = '\0';
+
+	git_libgit2_init();
+
+	if (argc > 2)
+		fatal("usage: showindex [<repo-dir>]", NULL);
+	if (argc > 1)
+		dir = argv[1];
+
+	dirlen = strlen(dir);
+	if (dirlen > 5 && strcmp(dir + dirlen - 5, "index") == 0) {
+		check_lg2(git_index_open(&index, dir), "could not open index", dir);
+	} else {
+		git_repository *repo;
+		check_lg2(git_repository_open_ext(&repo, dir, 0, NULL), "could not open repository", dir);
+		check_lg2(git_repository_index(&index, repo), "could not open repository index", NULL);
+		git_repository_free(repo);
+	}
+
+	git_index_read(index, 0);
+
+	ecount = git_index_entrycount(index);
+	if (!ecount)
+		printf("Empty index\n");
+
+	for (i = 0; i < ecount; ++i) {
+		const git_index_entry *e = git_index_get_byindex(index, i);
+
+		git_oid_fmt(out, &e->id);
+
+		printf("File Path: %s\n", e->path);
+		printf("    Stage: %d\n", git_index_entry_stage(e));
+		printf(" Blob SHA: %s\n", out);
+		printf("File Mode: %07o\n", e->mode);
+		printf("File Size: %d bytes\n", (int)e->file_size);
+		printf("Dev/Inode: %d/%d\n", (int)e->dev, (int)e->ino);
+		printf("  UID/GID: %d/%d\n", (int)e->uid, (int)e->gid);
+		printf("    ctime: %d\n", (int)e->ctime.seconds);
+		printf("    mtime: %d\n", (int)e->mtime.seconds);
+		printf("\n");
+	}
+
+	git_index_free(index);
+	git_libgit2_shutdown();
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/status.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/status.c
new file mode 100755
index 0000000..49f006d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/status.c
@@ -0,0 +1,517 @@
+/*
+ * libgit2 "status" example - shows how to use the status APIs
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "common.h"
+#ifdef _WIN32
+# include <Windows.h>
+# define sleep(a) Sleep(a * 1000)
+#else
+# include <unistd.h>
+#endif
+
+/**
+ * This example demonstrates the use of the libgit2 status APIs,
+ * particularly the `git_status_list` object, to roughly simulate the
+ * output of running `git status`.  It serves as a simple example of
+ * using those APIs to get basic status information.
+ *
+ * This does not have:
+ *
+ * - Robust error handling
+ * - Colorized or paginated output formatting
+ *
+ * This does have:
+ *
+ * - Examples of translating command line arguments to the status
+ *   options settings to mimic `git status` results.
+ * - A sample status formatter that matches the default "long" format
+ *   from `git status`
+ * - A sample status formatter that matches the "short" format
+ */
+
+enum {
+	FORMAT_DEFAULT   = 0,
+	FORMAT_LONG      = 1,
+	FORMAT_SHORT     = 2,
+	FORMAT_PORCELAIN = 3,
+};
+
+#define MAX_PATHSPEC 8
+
+struct opts {
+	git_status_options statusopt;
+	char *repodir;
+	char *pathspec[MAX_PATHSPEC];
+	int npaths;
+	int format;
+	int zterm;
+	int showbranch;
+	int showsubmod;
+	int repeat;
+};
+
+static void parse_opts(struct opts *o, int argc, char *argv[]);
+static void show_branch(git_repository *repo, int format);
+static void print_long(git_status_list *status);
+static void print_short(git_repository *repo, git_status_list *status);
+static int print_submod(git_submodule *sm, const char *name, void *payload);
+
+int main(int argc, char *argv[])
+{
+	git_repository *repo = NULL;
+	git_status_list *status;
+	struct opts o = { GIT_STATUS_OPTIONS_INIT, "." };
+
+	git_libgit2_init();
+
+	o.statusopt.show  = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
+	o.statusopt.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX |
+		GIT_STATUS_OPT_SORT_CASE_SENSITIVELY;
+
+	parse_opts(&o, argc, argv);
+
+	/**
+	 * Try to open the repository at the given path (or at the current
+	 * directory if none was given).
+	 */
+	check_lg2(git_repository_open_ext(&repo, o.repodir, 0, NULL),
+		  "Could not open repository", o.repodir);
+
+	if (git_repository_is_bare(repo))
+		fatal("Cannot report status on bare repository",
+			git_repository_path(repo));
+
+show_status:
+	if (o.repeat)
+		printf("\033[H\033[2J");
+
+	/**
+	 * Run status on the repository
+	 *
+	 * We use `git_status_list_new()` to generate a list of status
+	 * information which lets us iterate over it at our
+	 * convenience and extract the data we want to show out of
+	 * each entry.
+	 *
+	 * You can use `git_status_foreach()` or
+	 * `git_status_foreach_ext()` if you'd prefer to execute a
+	 * callback for each entry. The latter gives you more control
+	 * about what results are presented.
+	 */
+	check_lg2(git_status_list_new(&status, repo, &o.statusopt),
+		"Could not get status", NULL);
+
+	if (o.showbranch)
+		show_branch(repo, o.format);
+
+	if (o.showsubmod) {
+		int submod_count = 0;
+		check_lg2(git_submodule_foreach(repo, print_submod, &submod_count),
+			"Cannot iterate submodules", o.repodir);
+	}
+
+	if (o.format == FORMAT_LONG)
+		print_long(status);
+	else
+		print_short(repo, status);
+
+	git_status_list_free(status);
+
+	if (o.repeat) {
+		sleep(o.repeat);
+		goto show_status;
+	}
+
+	git_repository_free(repo);
+	git_libgit2_shutdown();
+
+	return 0;
+}
+
+/**
+ * If the user asked for the branch, let's show the short name of the
+ * branch.
+ */
+static void show_branch(git_repository *repo, int format)
+{
+	int error = 0;
+	const char *branch = NULL;
+	git_reference *head = NULL;
+
+	error = git_repository_head(&head, repo);
+
+	if (error == GIT_EUNBORNBRANCH || error == GIT_ENOTFOUND)
+		branch = NULL;
+	else if (!error) {
+		branch = git_reference_shorthand(head);
+	} else
+		check_lg2(error, "failed to get current branch", NULL);
+
+	if (format == FORMAT_LONG)
+		printf("# On branch %s\n",
+			branch ? branch : "Not currently on any branch.");
+	else
+		printf("## %s\n", branch ? branch : "HEAD (no branch)");
+
+	git_reference_free(head);
+}
+
+/**
+ * This function print out an output similar to git's status command
+ * in long form, including the command-line hints.
+ */
+static void print_long(git_status_list *status)
+{
+	size_t i, maxi = git_status_list_entrycount(status);
+	const git_status_entry *s;
+	int header = 0, changes_in_index = 0;
+	int changed_in_workdir = 0, rm_in_workdir = 0;
+	const char *old_path, *new_path;
+
+	/** Print index changes. */
+
+	for (i = 0; i < maxi; ++i) {
+		char *istatus = NULL;
+
+		s = git_status_byindex(status, i);
+
+		if (s->status == GIT_STATUS_CURRENT)
+			continue;
+
+		if (s->status & GIT_STATUS_WT_DELETED)
+			rm_in_workdir = 1;
+
+		if (s->status & GIT_STATUS_INDEX_NEW)
+			istatus = "new file: ";
+		if (s->status & GIT_STATUS_INDEX_MODIFIED)
+			istatus = "modified: ";
+		if (s->status & GIT_STATUS_INDEX_DELETED)
+			istatus = "deleted:  ";
+		if (s->status & GIT_STATUS_INDEX_RENAMED)
+			istatus = "renamed:  ";
+		if (s->status & GIT_STATUS_INDEX_TYPECHANGE)
+			istatus = "typechange:";
+
+		if (istatus == NULL)
+			continue;
+
+		if (!header) {
+			printf("# Changes to be committed:\n");
+			printf("#   (use \"git reset HEAD <file>...\" to unstage)\n");
+			printf("#\n");
+			header = 1;
+		}
+
+		old_path = s->head_to_index->old_file.path;
+		new_path = s->head_to_index->new_file.path;
+
+		if (old_path && new_path && strcmp(old_path, new_path))
+			printf("#\t%s  %s -> %s\n", istatus, old_path, new_path);
+		else
+			printf("#\t%s  %s\n", istatus, old_path ? old_path : new_path);
+	}
+
+	if (header) {
+		changes_in_index = 1;
+		printf("#\n");
+	}
+	header = 0;
+
+	/** Print workdir changes to tracked files. */
+
+	for (i = 0; i < maxi; ++i) {
+		char *wstatus = NULL;
+
+		s = git_status_byindex(status, i);
+
+		/**
+		 * With `GIT_STATUS_OPT_INCLUDE_UNMODIFIED` (not used in this example)
+		 * `index_to_workdir` may not be `NULL` even if there are
+		 * no differences, in which case it will be a `GIT_DELTA_UNMODIFIED`.
+		 */
+		if (s->status == GIT_STATUS_CURRENT || s->index_to_workdir == NULL)
+			continue;
+
+		/** Print out the output since we know the file has some changes */
+		if (s->status & GIT_STATUS_WT_MODIFIED)
+			wstatus = "modified: ";
+		if (s->status & GIT_STATUS_WT_DELETED)
+			wstatus = "deleted:  ";
+		if (s->status & GIT_STATUS_WT_RENAMED)
+			wstatus = "renamed:  ";
+		if (s->status & GIT_STATUS_WT_TYPECHANGE)
+			wstatus = "typechange:";
+
+		if (wstatus == NULL)
+			continue;
+
+		if (!header) {
+			printf("# Changes not staged for commit:\n");
+			printf("#   (use \"git add%s <file>...\" to update what will be committed)\n", rm_in_workdir ? "/rm" : "");
+			printf("#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n");
+			printf("#\n");
+			header = 1;
+		}
+
+		old_path = s->index_to_workdir->old_file.path;
+		new_path = s->index_to_workdir->new_file.path;
+
+		if (old_path && new_path && strcmp(old_path, new_path))
+			printf("#\t%s  %s -> %s\n", wstatus, old_path, new_path);
+		else
+			printf("#\t%s  %s\n", wstatus, old_path ? old_path : new_path);
+	}
+
+	if (header) {
+		changed_in_workdir = 1;
+		printf("#\n");
+	}
+
+	/** Print untracked files. */
+
+	header = 0;
+
+	for (i = 0; i < maxi; ++i) {
+		s = git_status_byindex(status, i);
+
+		if (s->status == GIT_STATUS_WT_NEW) {
+
+			if (!header) {
+				printf("# Untracked files:\n");
+				printf("#   (use \"git add <file>...\" to include in what will be committed)\n");
+				printf("#\n");
+				header = 1;
+			}
+
+			printf("#\t%s\n", s->index_to_workdir->old_file.path);
+		}
+	}
+
+	header = 0;
+
+	/** Print ignored files. */
+
+	for (i = 0; i < maxi; ++i) {
+		s = git_status_byindex(status, i);
+
+		if (s->status == GIT_STATUS_IGNORED) {
+
+			if (!header) {
+				printf("# Ignored files:\n");
+				printf("#   (use \"git add -f <file>...\" to include in what will be committed)\n");
+				printf("#\n");
+				header = 1;
+			}
+
+			printf("#\t%s\n", s->index_to_workdir->old_file.path);
+		}
+	}
+
+	if (!changes_in_index && changed_in_workdir)
+		printf("no changes added to commit (use \"git add\" and/or \"git commit -a\")\n");
+}
+
+/**
+ * This version of the output prefixes each path with two status
+ * columns and shows submodule status information.
+ */
+static void print_short(git_repository *repo, git_status_list *status)
+{
+	size_t i, maxi = git_status_list_entrycount(status);
+	const git_status_entry *s;
+	char istatus, wstatus;
+	const char *extra, *a, *b, *c;
+
+	for (i = 0; i < maxi; ++i) {
+		s = git_status_byindex(status, i);
+
+		if (s->status == GIT_STATUS_CURRENT)
+			continue;
+
+		a = b = c = NULL;
+		istatus = wstatus = ' ';
+		extra = "";
+
+		if (s->status & GIT_STATUS_INDEX_NEW)
+			istatus = 'A';
+		if (s->status & GIT_STATUS_INDEX_MODIFIED)
+			istatus = 'M';
+		if (s->status & GIT_STATUS_INDEX_DELETED)
+			istatus = 'D';
+		if (s->status & GIT_STATUS_INDEX_RENAMED)
+			istatus = 'R';
+		if (s->status & GIT_STATUS_INDEX_TYPECHANGE)
+			istatus = 'T';
+
+		if (s->status & GIT_STATUS_WT_NEW) {
+			if (istatus == ' ')
+				istatus = '?';
+			wstatus = '?';
+		}
+		if (s->status & GIT_STATUS_WT_MODIFIED)
+			wstatus = 'M';
+		if (s->status & GIT_STATUS_WT_DELETED)
+			wstatus = 'D';
+		if (s->status & GIT_STATUS_WT_RENAMED)
+			wstatus = 'R';
+		if (s->status & GIT_STATUS_WT_TYPECHANGE)
+			wstatus = 'T';
+
+		if (s->status & GIT_STATUS_IGNORED) {
+			istatus = '!';
+			wstatus = '!';
+		}
+
+		if (istatus == '?' && wstatus == '?')
+			continue;
+
+		/**
+		 * A commit in a tree is how submodules are stored, so
+		 * let's go take a look at its status.
+		 */
+		if (s->index_to_workdir &&
+			s->index_to_workdir->new_file.mode == GIT_FILEMODE_COMMIT)
+		{
+			unsigned int smstatus = 0;
+
+			if (!git_submodule_status(&smstatus, repo, s->index_to_workdir->new_file.path,
+						  GIT_SUBMODULE_IGNORE_UNSPECIFIED)) {
+				if (smstatus & GIT_SUBMODULE_STATUS_WD_MODIFIED)
+					extra = " (new commits)";
+				else if (smstatus & GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED)
+					extra = " (modified content)";
+				else if (smstatus & GIT_SUBMODULE_STATUS_WD_WD_MODIFIED)
+					extra = " (modified content)";
+				else if (smstatus & GIT_SUBMODULE_STATUS_WD_UNTRACKED)
+					extra = " (untracked content)";
+			}
+		}
+
+		/**
+		 * Now that we have all the information, format the output.
+		 */
+
+		if (s->head_to_index) {
+			a = s->head_to_index->old_file.path;
+			b = s->head_to_index->new_file.path;
+		}
+		if (s->index_to_workdir) {
+			if (!a)
+				a = s->index_to_workdir->old_file.path;
+			if (!b)
+				b = s->index_to_workdir->old_file.path;
+			c = s->index_to_workdir->new_file.path;
+		}
+
+		if (istatus == 'R') {
+			if (wstatus == 'R')
+				printf("%c%c %s %s %s%s\n", istatus, wstatus, a, b, c, extra);
+			else
+				printf("%c%c %s %s%s\n", istatus, wstatus, a, b, extra);
+		} else {
+			if (wstatus == 'R')
+				printf("%c%c %s %s%s\n", istatus, wstatus, a, c, extra);
+			else
+				printf("%c%c %s%s\n", istatus, wstatus, a, extra);
+		}
+	}
+
+	for (i = 0; i < maxi; ++i) {
+		s = git_status_byindex(status, i);
+
+		if (s->status == GIT_STATUS_WT_NEW)
+			printf("?? %s\n", s->index_to_workdir->old_file.path);
+	}
+}
+
+static int print_submod(git_submodule *sm, const char *name, void *payload)
+{
+	int *count = payload;
+	(void)name;
+
+	if (*count == 0)
+		printf("# Submodules\n");
+	(*count)++;
+
+	printf("# - submodule '%s' at %s\n",
+		git_submodule_name(sm), git_submodule_path(sm));
+
+	return 0;
+}
+
+/**
+ * Parse options that git's status command supports.
+ */
+static void parse_opts(struct opts *o, int argc, char *argv[])
+{
+	struct args_info args = ARGS_INFO_INIT;
+
+	for (args.pos = 1; args.pos < argc; ++args.pos) {
+		char *a = argv[args.pos];
+
+		if (a[0] != '-') {
+			if (o->npaths < MAX_PATHSPEC)
+				o->pathspec[o->npaths++] = a;
+			else
+				fatal("Example only supports a limited pathspec", NULL);
+		}
+		else if (!strcmp(a, "-s") || !strcmp(a, "--short"))
+			o->format = FORMAT_SHORT;
+		else if (!strcmp(a, "--long"))
+			o->format = FORMAT_LONG;
+		else if (!strcmp(a, "--porcelain"))
+			o->format = FORMAT_PORCELAIN;
+		else if (!strcmp(a, "-b") || !strcmp(a, "--branch"))
+			o->showbranch = 1;
+		else if (!strcmp(a, "-z")) {
+			o->zterm = 1;
+			if (o->format == FORMAT_DEFAULT)
+				o->format = FORMAT_PORCELAIN;
+		}
+		else if (!strcmp(a, "--ignored"))
+			o->statusopt.flags |= GIT_STATUS_OPT_INCLUDE_IGNORED;
+		else if (!strcmp(a, "-uno") ||
+				 !strcmp(a, "--untracked-files=no"))
+			o->statusopt.flags &= ~GIT_STATUS_OPT_INCLUDE_UNTRACKED;
+		else if (!strcmp(a, "-unormal") ||
+				 !strcmp(a, "--untracked-files=normal"))
+			o->statusopt.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED;
+		else if (!strcmp(a, "-uall") ||
+				 !strcmp(a, "--untracked-files=all"))
+			o->statusopt.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+				GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
+		else if (!strcmp(a, "--ignore-submodules=all"))
+			o->statusopt.flags |= GIT_STATUS_OPT_EXCLUDE_SUBMODULES;
+		else if (!strncmp(a, "--git-dir=", strlen("--git-dir=")))
+			o->repodir = a + strlen("--git-dir=");
+		else if (!strcmp(a, "--repeat"))
+			o->repeat = 10;
+		else if (match_int_arg(&o->repeat, &args, "--repeat", 0))
+			/* okay */;
+		else if (!strcmp(a, "--list-submodules"))
+			o->showsubmod = 1;
+		else
+			check_lg2(-1, "Unsupported option", a);
+	}
+
+	if (o->format == FORMAT_DEFAULT)
+		o->format = FORMAT_LONG;
+	if (o->format == FORMAT_LONG)
+		o->showbranch = 1;
+	if (o->npaths > 0) {
+		o->statusopt.pathspec.strings = o->pathspec;
+		o->statusopt.pathspec.count   = o->npaths;
+	}
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/tag.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/tag.c
new file mode 100755
index 0000000..c6a70d9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/tag.c
@@ -0,0 +1,319 @@
+/*
+ * libgit2 "tag" example - shows how to list, create and delete tags
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "common.h"
+
+/**
+ * The following example partially reimplements the `git tag` command
+ * and some of its options.
+ *
+ * These commands should work:
+
+ * - Tag name listing (`tag`)
+ * - Filtered tag listing with messages (`tag -n3 -l "v0.1*"`)
+ * - Lightweight tag creation (`tag test v0.18.0`)
+ * - Tag creation (`tag -a -m "Test message" test v0.18.0`)
+ * - Tag deletion (`tag -d test`)
+ *
+ * The command line parsing logic is simplified and doesn't handle
+ * all of the use cases.
+ */
+
+/** tag_options represents the parsed command line options */
+typedef struct {
+	const char *message;
+	const char *pattern;
+	const char *tag_name;
+	const char *target;
+	int num_lines;
+	int force;
+} tag_options;
+
+/** tag_state represents the current program state for dragging around */
+typedef struct {
+	git_repository *repo;
+	tag_options *opts;
+} tag_state;
+
+/** An action to execute based on the command line arguments */
+typedef void (*tag_action)(tag_state *state);
+typedef struct args_info args_info;
+
+static void check(int result, const char *message)
+{
+	if (result) fatal(message, NULL);
+}
+
+/** Tag listing: Print individual message lines */
+static void print_list_lines(const char *message, const tag_state *state)
+{
+	const char *msg = message;
+	int num = state->opts->num_lines - 1;
+
+	if (!msg) return;
+
+	/** first line - headline */
+	while(*msg && *msg != '\n') printf("%c", *msg++);
+
+	/** skip over new lines */
+	while(*msg && *msg == '\n') msg++;
+
+	printf("\n");
+
+	/** print just headline? */
+	if (num == 0) return;
+	if (*msg && msg[1]) printf("\n");
+
+	/** print individual commit/tag lines */
+	while (*msg && num-- >= 2) {
+		printf("    ");
+
+		while (*msg && *msg != '\n') printf("%c", *msg++);
+
+		/** handle consecutive new lines */
+		if (*msg && *msg == '\n' && msg[1] == '\n') {
+			num--;
+			printf("\n");
+		}
+		while(*msg && *msg == '\n') msg++;
+
+		printf("\n");
+	}
+}
+
+/** Tag listing: Print an actual tag object */
+static void print_tag(git_tag *tag, const tag_state *state)
+{
+	printf("%-16s", git_tag_name(tag));
+
+	if (state->opts->num_lines) {
+		const char *msg = git_tag_message(tag);
+		print_list_lines(msg, state);
+	} else {
+		printf("\n");
+	}
+}
+
+/** Tag listing: Print a commit (target of a lightweight tag) */
+static void print_commit(git_commit *commit, const char *name,
+		const tag_state *state)
+{
+	printf("%-16s", name);
+
+	if (state->opts->num_lines) {
+		const char *msg = git_commit_message(commit);
+		print_list_lines(msg, state);
+	} else {
+		printf("\n");
+	}
+}
+
+/** Tag listing: Fallback, should not happen */
+static void print_name(const char *name)
+{
+	printf("%s\n", name);
+}
+
+/** Tag listing: Lookup tags based on ref name and dispatch to print */
+static int each_tag(const char *name, tag_state *state)
+{
+	git_repository *repo = state->repo;
+	git_object *obj;
+
+	check_lg2(git_revparse_single(&obj, repo, name),
+			"Failed to lookup rev", name);
+
+	switch (git_object_type(obj)) {
+		case GIT_OBJ_TAG:
+			print_tag((git_tag *) obj, state);
+			break;
+		case GIT_OBJ_COMMIT:
+			print_commit((git_commit *) obj, name, state);
+			break;
+		default:
+			print_name(name);
+	}
+
+	git_object_free(obj);
+	return 0;
+}
+
+static void action_list_tags(tag_state *state)
+{
+	const char *pattern = state->opts->pattern;
+	git_strarray tag_names = {0};
+	size_t i;
+
+	check_lg2(git_tag_list_match(&tag_names, pattern ? pattern : "*", state->repo),
+			"Unable to get list of tags", NULL);
+
+	for(i = 0; i < tag_names.count; i++) {
+		each_tag(tag_names.strings[i], state);
+	}
+
+	git_strarray_free(&tag_names);
+}
+
+static void action_delete_tag(tag_state *state)
+{
+	tag_options *opts = state->opts;
+	git_object *obj;
+	git_buf abbrev_oid = {0};
+
+	check(!opts->tag_name, "Name required");
+
+	check_lg2(git_revparse_single(&obj, state->repo, opts->tag_name),
+			"Failed to lookup rev", opts->tag_name);
+
+	check_lg2(git_object_short_id(&abbrev_oid, obj),
+			"Unable to get abbreviated OID", opts->tag_name);
+
+	check_lg2(git_tag_delete(state->repo, opts->tag_name),
+			"Unable to delete tag", opts->tag_name);
+
+	printf("Deleted tag '%s' (was %s)\n", opts->tag_name, abbrev_oid.ptr);
+
+	git_buf_free(&abbrev_oid);
+	git_object_free(obj);
+}
+
+static void action_create_lighweight_tag(tag_state *state)
+{
+	git_repository *repo = state->repo;
+	tag_options *opts = state->opts;
+	git_oid oid;
+	git_object *target;
+
+	check(!opts->tag_name, "Name required");
+
+	if (!opts->target) opts->target = "HEAD";
+
+	check(!opts->target, "Target required");
+
+	check_lg2(git_revparse_single(&target, repo, opts->target),
+			"Unable to resolve spec", opts->target);
+
+	check_lg2(git_tag_create_lightweight(&oid, repo, opts->tag_name,
+				target, opts->force), "Unable to create tag", NULL);
+
+	git_object_free(target);
+}
+
+static void action_create_tag(tag_state *state)
+{
+	git_repository *repo = state->repo;
+	tag_options *opts = state->opts;
+	git_signature *tagger;
+	git_oid oid;
+	git_object *target;
+
+	check(!opts->tag_name, "Name required");
+	check(!opts->message, "Message required");
+
+	if (!opts->target) opts->target = "HEAD";
+
+	check_lg2(git_revparse_single(&target, repo, opts->target),
+			"Unable to resolve spec", opts->target);
+
+	check_lg2(git_signature_default(&tagger, repo),
+			"Unable to create signature", NULL);
+
+	check_lg2(git_tag_create(&oid, repo, opts->tag_name,
+				target, tagger, opts->message, opts->force), "Unable to create tag", NULL);
+
+	git_object_free(target);
+	git_signature_free(tagger);
+}
+
+static void print_usage(void)
+{
+	fprintf(stderr, "usage: see `git help tag`\n");
+	exit(1);
+}
+
+/** Parse command line arguments and choose action to run when done */
+static void parse_options(tag_action *action, tag_options *opts, int argc, char **argv)
+{
+	args_info args = ARGS_INFO_INIT;
+	*action = &action_list_tags;
+
+	for (args.pos = 1; args.pos < argc; ++args.pos) {
+		const char *curr = argv[args.pos];
+
+		if (curr[0] != '-') {
+			if (!opts->tag_name)
+				opts->tag_name = curr;
+			else if (!opts->target)
+				opts->target = curr;
+			else
+				print_usage();
+
+			if (*action != &action_create_tag)
+				*action = &action_create_lighweight_tag;
+		} else if (!strcmp(curr, "-n")) {
+			opts->num_lines = 1;
+			*action = &action_list_tags;
+		} else if (!strcmp(curr, "-a")) {
+			*action = &action_create_tag;
+		} else if (!strcmp(curr, "-f")) {
+			opts->force = 1;
+		} else if (match_int_arg(&opts->num_lines, &args, "-n", 0)) {
+			*action = &action_list_tags;
+		} else if (match_str_arg(&opts->pattern, &args, "-l")) {
+			*action = &action_list_tags;
+		} else if (match_str_arg(&opts->tag_name, &args, "-d")) {
+			*action = &action_delete_tag;
+		} else if (match_str_arg(&opts->message, &args, "-m")) {
+			*action = &action_create_tag;
+		}
+	}
+}
+
+/** Initialize tag_options struct */
+static void tag_options_init(tag_options *opts)
+{
+	memset(opts, 0, sizeof(*opts));
+
+	opts->message   = NULL;
+	opts->pattern   = NULL;
+	opts->tag_name  = NULL;
+	opts->target    = NULL;
+	opts->num_lines = 0;
+	opts->force     = 0;
+}
+
+int main(int argc, char **argv)
+{
+	git_repository *repo;
+	tag_options opts;
+	tag_action action;
+	tag_state state;
+
+	git_libgit2_init();
+
+	check_lg2(git_repository_open_ext(&repo, ".", 0, NULL),
+			"Could not open repository", NULL);
+
+	tag_options_init(&opts);
+	parse_options(&action, &opts, argc, argv);
+
+	state.repo = repo;
+	state.opts = &opts;
+	action(&state);
+
+	git_repository_free(repo);
+	git_libgit2_shutdown();
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/test/test-rev-list.sh b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/test/test-rev-list.sh
new file mode 100755
index 0000000..aa645be
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/examples/test/test-rev-list.sh
@@ -0,0 +1,95 @@
+#!/bin/bash
+
+THIS_FILE="$(readlink -f "$0")"
+ROOT="$(dirname "$(dirname "$(dirname "$THIS_FILE")")")"
+PROGRAM="$ROOT"/examples/rev-list
+LIBDIR="$ROOT"/build
+REPO="$ROOT"/tests/resources/testrepo.git
+
+cd "$REPO"
+
+run () {
+    LD_LIBRARY_PATH="$LIBDIR" "$PROGRAM" "$@"
+}
+
+diff -u - <(run --date-order a4a7dce) <<EOF
+a4a7dce85cf63874e984719f4fdd239f5145052f
+c47800c7266a2be04c571c04d5a6614691ea99bd
+9fd738e8f7967c078dceed8190330fc8648ee56a
+4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+5b5b025afb0b4c913b4c338a42934a3863bf3644
+8496071c1b46c854b31185ea97743be6a8774479
+EOF
+
+out="$(run --topo-order a4a7dce)"
+diff -q - <(echo -n "$out") <<EOF >/dev/null ||
+a4a7dce85cf63874e984719f4fdd239f5145052f
+c47800c7266a2be04c571c04d5a6614691ea99bd
+9fd738e8f7967c078dceed8190330fc8648ee56a
+4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+5b5b025afb0b4c913b4c338a42934a3863bf3644
+8496071c1b46c854b31185ea97743be6a8774479
+EOF
+diff -u - <(echo "$out") <<EOF
+a4a7dce85cf63874e984719f4fdd239f5145052f
+9fd738e8f7967c078dceed8190330fc8648ee56a
+4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+c47800c7266a2be04c571c04d5a6614691ea99bd
+5b5b025afb0b4c913b4c338a42934a3863bf3644
+8496071c1b46c854b31185ea97743be6a8774479
+EOF
+
+diff -u - <(run --date-order --reverse a4a7dce) <<EOF
+8496071c1b46c854b31185ea97743be6a8774479
+5b5b025afb0b4c913b4c338a42934a3863bf3644
+4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+9fd738e8f7967c078dceed8190330fc8648ee56a
+c47800c7266a2be04c571c04d5a6614691ea99bd
+a4a7dce85cf63874e984719f4fdd239f5145052f
+EOF
+
+out=$(run --topo-order --reverse a4a7dce)
+diff -q - <(echo -n "$out") <<EOF >/dev/null ||
+8496071c1b46c854b31185ea97743be6a8774479
+5b5b025afb0b4c913b4c338a42934a3863bf3644
+4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+9fd738e8f7967c078dceed8190330fc8648ee56a
+c47800c7266a2be04c571c04d5a6614691ea99bd
+a4a7dce85cf63874e984719f4fdd239f5145052f
+EOF
+diff -u - <(echo "$out") <<EOF
+8496071c1b46c854b31185ea97743be6a8774479
+5b5b025afb0b4c913b4c338a42934a3863bf3644
+c47800c7266a2be04c571c04d5a6614691ea99bd
+4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+9fd738e8f7967c078dceed8190330fc8648ee56a
+a4a7dce85cf63874e984719f4fdd239f5145052f
+EOF
+
+out="$(run --date-order --topo-order --reverse --reverse a4a7dce)"
+diff -q - <(echo -n "$out") <<EOF >/dev/null ||
+a4a7dce85cf63874e984719f4fdd239f5145052f
+c47800c7266a2be04c571c04d5a6614691ea99bd
+9fd738e8f7967c078dceed8190330fc8648ee56a
+4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+5b5b025afb0b4c913b4c338a42934a3863bf3644
+8496071c1b46c854b31185ea97743be6a8774479
+EOF
+diff -u - <(echo "$out") <<EOF
+a4a7dce85cf63874e984719f4fdd239f5145052f
+9fd738e8f7967c078dceed8190330fc8648ee56a
+4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+c47800c7266a2be04c571c04d5a6614691ea99bd
+5b5b025afb0b4c913b4c338a42934a3863bf3644
+8496071c1b46c854b31185ea97743be6a8774479
+EOF
+
+diff -u - <(run ^9fd738e~2 9fd738e) <<EOF
+9fd738e8f7967c078dceed8190330fc8648ee56a
+4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+EOF
+
+diff -u - <(run --not 9fd738e..9fd738e~2) <<EOF
+9fd738e8f7967c078dceed8190330fc8648ee56a
+4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+EOF
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/git.git-authors b/app/server/vendor/rugged-0.23.3/vendor/libgit2/git.git-authors
new file mode 100755
index 0000000..9131a1f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/git.git-authors
@@ -0,0 +1,74 @@
+# This document lists the authors that have given voice to
+# their decision regarding relicensing the GPL'd code from
+# git.git to the GPL + gcc-exception license used by libgit2.
+#
+# Note that the permission is given for libgit2 use only. For
+# other uses, you must ask each of the contributors yourself.
+#
+# To show the owners of a file in git.git, one can run the
+# following command:
+#
+#  git blame -C -C -M -- file | \
+#    sed -e 's/[^(]*(\([^0-9]*\).*/\1/' -e 's/[\t ]*$//' | \
+#      sort | uniq -c | sort -nr
+#
+# If everyone on the list that produces are on the list in
+# the recently added file "git.git-authors", it *should* be
+# safe to include that code in libgit2, but make sure to
+# read the file to ensure the code doesn't originate from
+# somewhere else.
+#
+# The format of this list is
+# "ok/no/ask/???"<tab>"Author"<space>"<email>"
+#
+# "ok" means the author consents to relicensing all their
+#   contributed code (possibly with some exceptions)
+# "no" means the author does not consent
+# "ask" means that the contributor wants to give/withhold
+#   his/her consent on a patch-by-patch basis.
+# "???" means the person is a prominent contributor who has
+#   not yet made his/her standpoint clear.
+#
+# Please try to keep the list alphabetically ordered. It will
+# help in case we get all 600-ish git.git authors on it.
+#
+# (Paul Kocher is the author of the mozilla-sha1 implementation
+#  but has otherwise not contributed to git.)
+#
+ok	Adam Simpkins <adam at adamsimpkins.net> (http transport)
+ok	Adrian Johnson <ajohnson at redneon.com>
+ok	Alexey Shumkin <alex.crezoff at gmail.com>
+ok	Andreas Ericsson <ae at op5.se>
+ok	Boyd Lynn Gerber <gerberb at zenez.com>
+ok	Brandon Casey <drafnel at gmail.com>
+ok	Brian Downing <bdowning at lavos.net>
+ok	Brian Gernhardt <benji at silverinsanity.com>
+ok	Christian Couder <chriscool at tuxfamily.org>
+ok	Daniel Barkalow <barkalow at iabervon.org>
+ok	Florian Forster <octo at verplant.org>
+ok	Gustaf Hendeby <hendeby at isy.liu.se>
+ok	Holger Weiss <holger at zedat.fu-berlin.de>
+ok	Jeff King <peff at peff.net>
+ok	Johannes Schindelin <Johannes.Schindelin at gmx.de>
+ok	Johannes Sixt <j6t at kdbg.org>
+ask	Jonathan Nieder <jrnieder at gmail.com>
+ok	Junio C Hamano <gitster at pobox.com>
+ok	Kristian Høgsberg <krh at redhat.com>
+ok	Linus Torvalds <torvalds at linux-foundation.org>
+ok	Lukas Sandström <lukass at etek.chalmers.se>
+ok	Matthieu Moy <Matthieu.Moy at imag.fr>
+ok	Michael Haggerty <mhagger at alum.mit.edu>
+ok	Nicolas Pitre <nico at fluxnic.net> <nico at cam.org>
+ok	Paolo Bonzini <bonzini at gnu.org>
+ok	Paul Kocher <paul at cryptography.com>
+ok	Peter Hagervall <hager at cs.umu.se>
+ok	Petr Onderka <gsvick at gmail.com>
+ok	Pierre Habouzit <madcoder at debian.org>
+ok	Pieter de Bie <pdebie at ai.rug.nl>
+ok	René Scharfe <rene.scharfe at lsrfire.ath.cx>
+ok	Sebastian Schuberth <sschuberth at gmail.com>
+ok	Shawn O. Pearce <spearce at spearce.org>
+ok	Steffen Prohaska <prohaska at zib.de>
+ok	Sven Verdoolaege <skimo at kotnet.org>
+ask	Thomas Rast <tr at thomasrast.ch> (ok before 6-Oct-2013)
+ok	Torsten Bögershausen <tboegi at web.de>
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2.h
new file mode 100755
index 0000000..ac4a631
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_git_git_h__
+#define INCLUDE_git_git_h__
+
+#include "git2/annotated_commit.h"
+#include "git2/attr.h"
+#include "git2/blob.h"
+#include "git2/blame.h"
+#include "git2/branch.h"
+#include "git2/buffer.h"
+#include "git2/checkout.h"
+#include "git2/cherrypick.h"
+#include "git2/clone.h"
+#include "git2/commit.h"
+#include "git2/common.h"
+#include "git2/config.h"
+#include "git2/describe.h"
+#include "git2/diff.h"
+#include "git2/errors.h"
+#include "git2/filter.h"
+#include "git2/global.h"
+#include "git2/graph.h"
+#include "git2/ignore.h"
+#include "git2/index.h"
+#include "git2/indexer.h"
+#include "git2/merge.h"
+#include "git2/message.h"
+#include "git2/net.h"
+#include "git2/notes.h"
+#include "git2/object.h"
+#include "git2/odb.h"
+#include "git2/odb_backend.h"
+#include "git2/oid.h"
+#include "git2/pack.h"
+#include "git2/patch.h"
+#include "git2/pathspec.h"
+#include "git2/rebase.h"
+#include "git2/refdb.h"
+#include "git2/reflog.h"
+#include "git2/refs.h"
+#include "git2/refspec.h"
+#include "git2/remote.h"
+#include "git2/repository.h"
+#include "git2/reset.h"
+#include "git2/revert.h"
+#include "git2/revparse.h"
+#include "git2/revwalk.h"
+#include "git2/signature.h"
+#include "git2/stash.h"
+#include "git2/status.h"
+#include "git2/submodule.h"
+#include "git2/tag.h"
+#include "git2/transport.h"
+#include "git2/transaction.h"
+#include "git2/tree.h"
+#include "git2/types.h"
+#include "git2/version.h"
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/annotated_commit.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/annotated_commit.h
new file mode 100755
index 0000000..7fb896a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/annotated_commit.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_annotated_commit_h__
+#define INCLUDE_git_annotated_commit_h__
+
+#include "common.h"
+#include "repository.h"
+#include "types.h"
+
+/**
+ * @file git2/annotated_commit.h
+ * @brief Git annotated commit routines
+ * @defgroup git_annotated_commit Git annotated commit routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Creates a `git_annotated_commit` from the given reference.
+ * The resulting git_annotated_commit must be freed with
+ * `git_annotated_commit_free`.
+ *
+ * @param out pointer to store the git_annotated_commit result in
+ * @param repo repository that contains the given reference
+ * @param ref reference to use to lookup the git_annotated_commit
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_annotated_commit_from_ref(
+	git_annotated_commit **out,
+	git_repository *repo,
+	const git_reference *ref);
+
+/**
+ * Creates a `git_annotated_commit` from the given fetch head data.
+ * The resulting git_annotated_commit must be freed with
+ * `git_annotated_commit_free`.
+ *
+ * @param out pointer to store the git_annotated_commit result in
+ * @param repo repository that contains the given commit
+ * @param branch_name name of the (remote) branch
+ * @param remote_url url of the remote
+ * @param id the commit object id of the remote branch
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_annotated_commit_from_fetchhead(
+	git_annotated_commit **out,
+	git_repository *repo,
+	const char *branch_name,
+	const char *remote_url,
+	const git_oid *id);
+
+/**
+ * Creates a `git_annotated_commit` from the given commit id.
+ * The resulting git_annotated_commit must be freed with
+ * `git_annotated_commit_free`.
+ *
+ * An annotated commit contains information about how it was
+ * looked up, which may be useful for functions like merge or
+ * rebase to provide context to the operation.  For example,
+ * conflict files will include the name of the source or target
+ * branches being merged.  It is therefore preferable to use the
+ * most specific function (eg `git_annotated_commit_from_ref`)
+ * instead of this one when that data is known.
+ *
+ * @param out pointer to store the git_annotated_commit result in
+ * @param repo repository that contains the given commit
+ * @param id the commit object id to lookup
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_annotated_commit_lookup(
+	git_annotated_commit **out,
+	git_repository *repo,
+	const git_oid *id);
+
+/**
+ * Creates a `git_annotated_comit` from a revision string.
+ *
+ * See `man gitrevisions`, or
+ * http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for
+ * information on the syntax accepted.
+ *
+ * @param out pointer to store the git_annotated_commit result in
+ * @param repo repository that contains the given commit
+ * @param revspec the extended sha syntax string to use to lookup the commit
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_annotated_commit_from_revspec(
+	git_annotated_commit **out,
+	git_repository *repo,
+	const char *revspec);
+
+/**
+ * Gets the commit ID that the given `git_annotated_commit` refers to.
+ *
+ * @param commit the given annotated commit
+ * @return commit id
+ */
+GIT_EXTERN(const git_oid *) git_annotated_commit_id(
+	const git_annotated_commit *commit);
+
+/**
+ * Frees a `git_annotated_commit`.
+ *
+ * @param commit annotated commit to free
+ */
+GIT_EXTERN(void) git_annotated_commit_free(
+	git_annotated_commit *commit);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/attr.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/attr.h
new file mode 100755
index 0000000..0238f3d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/attr.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_attr_h__
+#define INCLUDE_git_attr_h__
+
+#include "common.h"
+#include "types.h"
+
+/**
+ * @file git2/attr.h
+ * @brief Git attribute management routines
+ * @defgroup git_attr Git attribute management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * GIT_ATTR_TRUE checks if an attribute is set on.  In core git
+ * parlance, this the value for "Set" attributes.
+ *
+ * For example, if the attribute file contains:
+ *
+ *    *.c foo
+ *
+ * Then for file `xyz.c` looking up attribute "foo" gives a value for
+ * which `GIT_ATTR_TRUE(value)` is true.
+ */
+#define GIT_ATTR_TRUE(attr)	(git_attr_value(attr) == GIT_ATTR_TRUE_T)
+
+/**
+ * GIT_ATTR_FALSE checks if an attribute is set off.  In core git
+ * parlance, this is the value for attributes that are "Unset" (not to
+ * be confused with values that a "Unspecified").
+ *
+ * For example, if the attribute file contains:
+ *
+ *    *.h -foo
+ *
+ * Then for file `zyx.h` looking up attribute "foo" gives a value for
+ * which `GIT_ATTR_FALSE(value)` is true.
+ */
+#define GIT_ATTR_FALSE(attr) (git_attr_value(attr) == GIT_ATTR_FALSE_T)
+
+/**
+ * GIT_ATTR_UNSPECIFIED checks if an attribute is unspecified.  This
+ * may be due to the attribute not being mentioned at all or because
+ * the attribute was explicitly set unspecified via the `!` operator.
+ *
+ * For example, if the attribute file contains:
+ *
+ *    *.c foo
+ *    *.h -foo
+ *    onefile.c !foo
+ *
+ * Then for `onefile.c` looking up attribute "foo" yields a value with
+ * `GIT_ATTR_UNSPECIFIED(value)` of true.  Also, looking up "foo" on
+ * file `onefile.rb` or looking up "bar" on any file will all give
+ * `GIT_ATTR_UNSPECIFIED(value)` of true.
+ */
+#define GIT_ATTR_UNSPECIFIED(attr) (git_attr_value(attr) == GIT_ATTR_UNSPECIFIED_T)
+
+/**
+ * GIT_ATTR_HAS_VALUE checks if an attribute is set to a value (as
+ * opposed to TRUE, FALSE or UNSPECIFIED).  This would be the case if
+ * for a file with something like:
+ *
+ *    *.txt eol=lf
+ *
+ * Given this, looking up "eol" for `onefile.txt` will give back the
+ * string "lf" and `GIT_ATTR_SET_TO_VALUE(attr)` will return true.
+ */
+#define GIT_ATTR_HAS_VALUE(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_T)
+
+/**
+ * Possible states for an attribute
+ */
+typedef enum {
+	GIT_ATTR_UNSPECIFIED_T = 0, /**< The attribute has been left unspecified */
+	GIT_ATTR_TRUE_T,  /**< The attribute has been set */
+	GIT_ATTR_FALSE_T, /**< The attribute has been unset */
+	GIT_ATTR_VALUE_T, /**< This attribute has a value */
+} git_attr_t;
+
+/**
+ * Return the value type for a given attribute.
+ *
+ * This can be either `TRUE`, `FALSE`, `UNSPECIFIED` (if the attribute
+ * was not set at all), or `VALUE`, if the attribute was set to an
+ * actual string.
+ *
+ * If the attribute has a `VALUE` string, it can be accessed normally
+ * as a NULL-terminated C string.
+ *
+ * @param attr The attribute
+ * @return the value type for the attribute
+ */
+GIT_EXTERN(git_attr_t) git_attr_value(const char *attr);
+
+/**
+ * Check attribute flags: Reading values from index and working directory.
+ *
+ * When checking attributes, it is possible to check attribute files
+ * in both the working directory (if there is one) and the index (if
+ * there is one).  You can explicitly choose where to check and in
+ * which order using the following flags.
+ *
+ * Core git usually checks the working directory then the index,
+ * except during a checkout when it checks the index first.  It will
+ * use index only for creating archives or for a bare repo (if an
+ * index has been specified for the bare repo).
+ */
+#define GIT_ATTR_CHECK_FILE_THEN_INDEX	0
+#define GIT_ATTR_CHECK_INDEX_THEN_FILE	1
+#define GIT_ATTR_CHECK_INDEX_ONLY		2
+
+/**
+ * Check attribute flags: Using the system attributes file.
+ *
+ * Normally, attribute checks include looking in the /etc (or system
+ * equivalent) directory for a `gitattributes` file.  Passing this
+ * flag will cause attribute checks to ignore that file.
+ */
+#define GIT_ATTR_CHECK_NO_SYSTEM		(1 << 2)
+
+/**
+ * Look up the value of one git attribute for path.
+ *
+ * @param value_out Output of the value of the attribute.  Use the GIT_ATTR_...
+ *             macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just
+ *             use the string value for attributes set to a value.  You
+ *             should NOT modify or free this value.
+ * @param repo The repository containing the path.
+ * @param flags A combination of GIT_ATTR_CHECK... flags.
+ * @param path The path to check for attributes.  Relative paths are
+ *             interpreted relative to the repo root.  The file does
+ *             not have to exist, but if it does not, then it will be
+ *             treated as a plain file (not a directory).
+ * @param name The name of the attribute to look up.
+ */
+GIT_EXTERN(int) git_attr_get(
+	const char **value_out,
+	git_repository *repo,
+	uint32_t flags,
+	const char *path,
+	const char *name);
+
+/**
+ * Look up a list of git attributes for path.
+ *
+ * Use this if you have a known list of attributes that you want to
+ * look up in a single call.  This is somewhat more efficient than
+ * calling `git_attr_get()` multiple times.
+ *
+ * For example, you might write:
+ *
+ *     const char *attrs[] = { "crlf", "diff", "foo" };
+ *     const char **values[3];
+ *     git_attr_get_many(values, repo, 0, "my/fun/file.c", 3, attrs);
+ *
+ * Then you could loop through the 3 values to get the settings for
+ * the three attributes you asked about.
+ *
+ * @param values_out An array of num_attr entries that will have string
+ *             pointers written into it for the values of the attributes.
+ *             You should not modify or free the values that are written
+ *             into this array (although of course, you should free the
+ *             array itself if you allocated it).
+ * @param repo The repository containing the path.
+ * @param flags A combination of GIT_ATTR_CHECK... flags.
+ * @param path The path inside the repo to check attributes.  This
+ *             does not have to exist, but if it does not, then
+ *             it will be treated as a plain file (i.e. not a directory).
+ * @param num_attr The number of attributes being looked up
+ * @param names An array of num_attr strings containing attribute names.
+ */
+GIT_EXTERN(int) git_attr_get_many(
+	const char **values_out,
+	git_repository *repo,
+	uint32_t flags,
+	const char *path,
+	size_t num_attr,
+	const char **names);
+
+typedef int (*git_attr_foreach_cb)(const char *name, const char *value, void *payload);
+
+/**
+ * Loop over all the git attributes for a path.
+ *
+ * @param repo The repository containing the path.
+ * @param flags A combination of GIT_ATTR_CHECK... flags.
+ * @param path Path inside the repo to check attributes.  This does not have
+ *             to exist, but if it does not, then it will be treated as a
+ *             plain file (i.e. not a directory).
+ * @param callback Function to invoke on each attribute name and value.  The
+ *             value may be NULL is the attribute is explicitly set to
+ *             UNSPECIFIED using the '!' sign.  Callback will be invoked
+ *             only once per attribute name, even if there are multiple
+ *             rules for a given file.  The highest priority rule will be
+ *             used.  Return a non-zero value from this to stop looping.
+ *             The value will be returned from `git_attr_foreach`.
+ * @param payload Passed on as extra parameter to callback function.
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_attr_foreach(
+	git_repository *repo,
+	uint32_t flags,
+	const char *path,
+	git_attr_foreach_cb callback,
+	void *payload);
+
+/**
+ * Flush the gitattributes cache.
+ *
+ * Call this if you have reason to believe that the attributes files on
+ * disk no longer match the cached contents of memory.  This will cause
+ * the attributes files to be reloaded the next time that an attribute
+ * access function is called.
+ */
+GIT_EXTERN(void) git_attr_cache_flush(
+	git_repository *repo);
+
+/**
+ * Add a macro definition.
+ *
+ * Macros will automatically be loaded from the top level `.gitattributes`
+ * file of the repository (plus the build-in "binary" macro).  This
+ * function allows you to add others.  For example, to add the default
+ * macro, you would call:
+ *
+ *     git_attr_add_macro(repo, "binary", "-diff -crlf");
+ */
+GIT_EXTERN(int) git_attr_add_macro(
+	git_repository *repo,
+	const char *name,
+	const char *values);
+
+/** @} */
+GIT_END_DECL
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/blame.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/blame.h
new file mode 100755
index 0000000..173e999
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/blame.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_git_blame_h__
+#define INCLUDE_git_blame_h__
+
+#include "common.h"
+#include "oid.h"
+
+/**
+ * @file git2/blame.h
+ * @brief Git blame routines
+ * @defgroup git_blame Git blame routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Flags for indicating option behavior for git_blame APIs.
+ */
+typedef enum {
+	/** Normal blame, the default */
+	GIT_BLAME_NORMAL = 0,
+	/** Track lines that have moved within a file (like `git blame -M`).
+	 * NOT IMPLEMENTED. */
+	GIT_BLAME_TRACK_COPIES_SAME_FILE = (1<<0),
+	/** Track lines that have moved across files in the same commit (like `git blame -C`).
+	 * NOT IMPLEMENTED. */
+	GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES = (1<<1),
+	/** Track lines that have been copied from another file that exists in the
+	 * same commit (like `git blame -CC`). Implies SAME_FILE.
+	 * NOT IMPLEMENTED. */
+	GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES = (1<<2),
+	/** Track lines that have been copied from another file that exists in *any*
+	 * commit (like `git blame -CCC`). Implies SAME_COMMIT_COPIES.
+	 * NOT IMPLEMENTED. */
+	GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES = (1<<3),
+	/** Restrict the search of commits to those reachable following only the
+	 * first parents. */
+	GIT_BLAME_FIRST_PARENT = (1<<4),
+} git_blame_flag_t;
+
+/**
+ * Blame options structure
+ *
+ * Use zeros to indicate default settings.  It's easiest to use the
+ * `GIT_BLAME_OPTIONS_INIT` macro:
+ *     git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+ *
+ * - `flags` is a combination of the `git_blame_flag_t` values above.
+ * - `min_match_characters` is the lower bound on the number of alphanumeric
+ *   characters that must be detected as moving/copying within a file for it to
+ *   associate those lines with the parent commit. The default value is 20.
+ *   This value only takes effect if any of the `GIT_BLAME_TRACK_COPIES_*`
+ *   flags are specified.
+ * - `newest_commit` is the id of the newest commit to consider.  The default
+ *                   is HEAD.
+ * - `oldest_commit` is the id of the oldest commit to consider.  The default
+ *                   is the first commit encountered with a NULL parent.
+ *	- `min_line` is the first line in the file to blame.  The default is 1 (line
+ *	             numbers start with 1).
+ *	- `max_line` is the last line in the file to blame.  The default is the last
+ *	             line of the file.
+ */
+typedef struct git_blame_options {
+	unsigned int version;
+
+	uint32_t flags;
+	uint16_t min_match_characters;
+	git_oid newest_commit;
+	git_oid oldest_commit;
+	uint32_t min_line;
+	uint32_t max_line;
+} git_blame_options;
+
+#define GIT_BLAME_OPTIONS_VERSION 1
+#define GIT_BLAME_OPTIONS_INIT {GIT_BLAME_OPTIONS_VERSION}
+
+/**
+ * Initializes a `git_blame_options` with default values. Equivalent to
+ * creating an instance with GIT_BLAME_OPTIONS_INIT.
+ *
+ * @param opts The `git_blame_options` struct to initialize
+ * @param version Version of struct; pass `GIT_BLAME_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_blame_init_options(
+	git_blame_options *opts,
+	unsigned int version);
+
+/**
+ * Structure that represents a blame hunk.
+ *
+ * - `lines_in_hunk` is the number of lines in this hunk
+ * - `final_commit_id` is the OID of the commit where this line was last
+ *   changed.
+ * - `final_start_line_number` is the 1-based line number where this hunk
+ *   begins, in the final version of the file
+ * - `orig_commit_id` is the OID of the commit where this hunk was found.  This
+ *   will usually be the same as `final_commit_id`, except when
+ *   `GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES` has been specified.
+ * - `orig_path` is the path to the file where this hunk originated, as of the
+ *   commit specified by `orig_commit_id`.
+ * - `orig_start_line_number` is the 1-based line number where this hunk begins
+ *   in the file named by `orig_path` in the commit specified by
+ *   `orig_commit_id`.
+ * - `boundary` is 1 iff the hunk has been tracked to a boundary commit (the
+ *   root, or the commit specified in git_blame_options.oldest_commit)
+ */
+typedef struct git_blame_hunk {
+	uint16_t lines_in_hunk;
+
+	git_oid final_commit_id;
+	uint16_t final_start_line_number;
+	git_signature *final_signature;
+
+	git_oid orig_commit_id;
+	const char *orig_path;
+	uint16_t orig_start_line_number;
+	git_signature *orig_signature;
+
+	char boundary;
+} git_blame_hunk;
+
+
+/* Opaque structure to hold blame results */
+typedef struct git_blame git_blame;
+
+/**
+ * Gets the number of hunks that exist in the blame structure.
+ */
+GIT_EXTERN(uint32_t) git_blame_get_hunk_count(git_blame *blame);
+
+/**
+ * Gets the blame hunk at the given index.
+ *
+ * @param blame the blame structure to query
+ * @param index index of the hunk to retrieve
+ * @return the hunk at the given index, or NULL on error
+ */
+GIT_EXTERN(const git_blame_hunk*) git_blame_get_hunk_byindex(
+		git_blame *blame,
+		uint32_t index);
+
+/**
+ * Gets the hunk that relates to the given line number in the newest commit.
+ *
+ * @param blame the blame structure to query
+ * @param lineno the (1-based) line number to find a hunk for
+ * @return the hunk that contains the given line, or NULL on error
+ */
+GIT_EXTERN(const git_blame_hunk*) git_blame_get_hunk_byline(
+		git_blame *blame,
+		uint32_t lineno);
+
+/**
+ * Get the blame for a single file.
+ *
+ * @param out pointer that will receive the blame object
+ * @param repo repository whose history is to be walked
+ * @param path path to file to consider
+ * @param options options for the blame operation.  If NULL, this is treated as
+ *                though GIT_BLAME_OPTIONS_INIT were passed.
+ * @return 0 on success, or an error code. (use giterr_last for information
+ *         about the error.)
+ */
+GIT_EXTERN(int) git_blame_file(
+		git_blame **out,
+		git_repository *repo,
+		const char *path,
+		git_blame_options *options);
+
+
+/**
+ * Get blame data for a file that has been modified in memory. The `reference`
+ * parameter is a pre-calculated blame for the in-odb history of the file. This
+ * means that once a file blame is completed (which can be expensive), updating
+ * the buffer blame is very fast.
+ *
+ * Lines that differ between the buffer and the committed version are marked as
+ * having a zero OID for their final_commit_id.
+ *
+ * @param out pointer that will receive the resulting blame data
+ * @param reference cached blame from the history of the file (usually the output
+ *                  from git_blame_file)
+ * @param buffer the (possibly) modified contents of the file
+ * @param buffer_len number of valid bytes in the buffer
+ * @return 0 on success, or an error code. (use giterr_last for information
+ *         about the error)
+ */
+GIT_EXTERN(int) git_blame_buffer(
+		git_blame **out,
+		git_blame *reference,
+		const char *buffer,
+		size_t buffer_len);
+
+/**
+ * Free memory allocated by git_blame_file or git_blame_buffer.
+ *
+ * @param blame the blame structure to free
+ */
+GIT_EXTERN(void) git_blame_free(git_blame *blame);
+
+/** @} */
+GIT_END_DECL
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/blob.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/blob.h
new file mode 100755
index 0000000..4a6d8e5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/blob.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_blob_h__
+#define INCLUDE_git_blob_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "object.h"
+#include "buffer.h"
+
+/**
+ * @file git2/blob.h
+ * @brief Git blob load and write routines
+ * @defgroup git_blob Git blob load and write routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Lookup a blob object from a repository.
+ *
+ * @param blob pointer to the looked up blob
+ * @param repo the repo to use when locating the blob.
+ * @param id identity of the blob to locate.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_blob_lookup(git_blob **blob, git_repository *repo, const git_oid *id);
+
+/**
+ * Lookup a blob object from a repository,
+ * given a prefix of its identifier (short id).
+ *
+ * @see git_object_lookup_prefix
+ *
+ * @param blob pointer to the looked up blob
+ * @param repo the repo to use when locating the blob.
+ * @param id identity of the blob to locate.
+ * @param len the length of the short identifier
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_blob_lookup_prefix(git_blob **blob, git_repository *repo, const git_oid *id, size_t len);
+
+/**
+ * Close an open blob
+ *
+ * This is a wrapper around git_object_free()
+ *
+ * IMPORTANT:
+ * It *is* necessary to call this method when you stop
+ * using a blob. Failure to do so will cause a memory leak.
+ *
+ * @param blob the blob to close
+ */
+GIT_EXTERN(void) git_blob_free(git_blob *blob);
+
+/**
+ * Get the id of a blob.
+ *
+ * @param blob a previously loaded blob.
+ * @return SHA1 hash for this blob.
+ */
+GIT_EXTERN(const git_oid *) git_blob_id(const git_blob *blob);
+
+/**
+ * Get the repository that contains the blob.
+ *
+ * @param blob A previously loaded blob.
+ * @return Repository that contains this blob.
+ */
+GIT_EXTERN(git_repository *) git_blob_owner(const git_blob *blob);
+
+/**
+ * Get a read-only buffer with the raw content of a blob.
+ *
+ * A pointer to the raw content of a blob is returned;
+ * this pointer is owned internally by the object and shall
+ * not be free'd. The pointer may be invalidated at a later
+ * time.
+ *
+ * @param blob pointer to the blob
+ * @return the pointer
+ */
+GIT_EXTERN(const void *) git_blob_rawcontent(const git_blob *blob);
+
+/**
+ * Get the size in bytes of the contents of a blob
+ *
+ * @param blob pointer to the blob
+ * @return size on bytes
+ */
+GIT_EXTERN(git_off_t) git_blob_rawsize(const git_blob *blob);
+
+/**
+ * Get a buffer with the filtered content of a blob.
+ *
+ * This applies filters as if the blob was being checked out to the
+ * working directory under the specified filename.  This may apply
+ * CRLF filtering or other types of changes depending on the file
+ * attributes set for the blob and the content detected in it.
+ *
+ * The output is written into a `git_buf` which the caller must free
+ * when done (via `git_buf_free`).
+ *
+ * If no filters need to be applied, then the `out` buffer will just
+ * be populated with a pointer to the raw content of the blob.  In
+ * that case, be careful to *not* free the blob until done with the
+ * buffer or copy it into memory you own.
+ *
+ * @param out The git_buf to be filled in
+ * @param blob Pointer to the blob
+ * @param as_path Path used for file attribute lookups, etc.
+ * @param check_for_binary_data Should this test if blob content contains
+ *        NUL bytes / looks like binary data before applying filters?
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_blob_filtered_content(
+	git_buf *out,
+	git_blob *blob,
+	const char *as_path,
+	int check_for_binary_data);
+
+/**
+ * Read a file from the working folder of a repository
+ * and write it to the Object Database as a loose blob
+ *
+ * @param id return the id of the written blob
+ * @param repo repository where the blob will be written.
+ *	this repository cannot be bare
+ * @param relative_path file from which the blob will be created,
+ *	relative to the repository's working dir
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_blob_create_fromworkdir(git_oid *id, git_repository *repo, const char *relative_path);
+
+/**
+ * Read a file from the filesystem and write its content
+ * to the Object Database as a loose blob
+ *
+ * @param id return the id of the written blob
+ * @param repo repository where the blob will be written.
+ *	this repository can be bare or not
+ * @param path file from which the blob will be created
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *id, git_repository *repo, const char *path);
+
+
+typedef int (*git_blob_chunk_cb)(char *content, size_t max_length, void *payload);
+
+/**
+ * Write a loose blob to the Object Database from a
+ * provider of chunks of data.
+ *
+ * If the `hintpath` parameter is filled, it will be used to determine
+ * what git filters should be applied to the object before it is written
+ * to the object database.
+ *
+ * The implementation of the callback MUST respect the following rules:
+ *
+ *  - `content` must be filled by the callback. The maximum number of
+ *    bytes that the buffer can accept per call is defined by the
+ *    `max_length` parameter. Allocation and freeing of the buffer will
+ *    be taken care of by libgit2.
+ *
+ *  - The `callback` must return the number of bytes that have been
+ *    written to the `content` buffer.
+ *
+ *  - When there is no more data to stream, `callback` should return
+ *    0. This will prevent it from being invoked anymore.
+ *
+ *  - If an error occurs, the callback should return a negative value.
+ *    This value will be returned to the caller.
+ *
+ * @param id Return the id of the written blob
+ * @param repo Repository where the blob will be written.
+ *        This repository can be bare or not.
+ * @param hintpath If not NULL, will be used to select data filters
+ *        to apply onto the content of the blob to be created.
+ * @return 0 or error code (from either libgit2 or callback function)
+ */
+GIT_EXTERN(int) git_blob_create_fromchunks(
+	git_oid *id,
+	git_repository *repo,
+	const char *hintpath,
+	git_blob_chunk_cb callback,
+	void *payload);
+
+/**
+ * Write an in-memory buffer to the ODB as a blob
+ *
+ * @param id return the id of the written blob
+ * @param repo repository where to blob will be written
+ * @param buffer data to be written into the blob
+ * @param len length of the data
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_blob_create_frombuffer(
+	git_oid *id, git_repository *repo, const void *buffer, size_t len);
+
+/**
+ * Determine if the blob content is most certainly binary or not.
+ *
+ * The heuristic used to guess if a file is binary is taken from core git:
+ * Searching for NUL bytes and looking for a reasonable ratio of printable
+ * to non-printable characters among the first 8000 bytes.
+ *
+ * @param blob The blob which content should be analyzed
+ * @return 1 if the content of the blob is detected
+ * as binary; 0 otherwise.
+ */
+GIT_EXTERN(int) git_blob_is_binary(const git_blob *blob);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/branch.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/branch.h
new file mode 100755
index 0000000..34354f4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/branch.h
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_branch_h__
+#define INCLUDE_git_branch_h__
+
+#include "common.h"
+#include "oid.h"
+#include "types.h"
+
+/**
+ * @file git2/branch.h
+ * @brief Git branch parsing routines
+ * @defgroup git_branch Git branch management
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create a new branch pointing at a target commit
+ *
+ * A new direct reference will be created pointing to
+ * this target commit. If `force` is true and a reference
+ * already exists with the given name, it'll be replaced.
+ *
+ * The returned reference must be freed by the user.
+ *
+ * The branch name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
+ *
+ * @param out Pointer where to store the underlying reference.
+ *
+ * @param branch_name Name for the branch; this name is
+ * validated for consistency. It should also not conflict with
+ * an already existing branch name.
+ *
+ * @param target Commit to which this branch should point. This object
+ * must belong to the given `repo`.
+ *
+ * @param force Overwrite existing branch.
+ *
+ * @return 0, GIT_EINVALIDSPEC or an error code.
+ * A proper reference is written in the refs/heads namespace
+ * pointing to the provided target commit.
+ */
+GIT_EXTERN(int) git_branch_create(
+	git_reference **out,
+	git_repository *repo,
+	const char *branch_name,
+	const git_commit *target,
+	int force);
+
+/**
+ * Create a new branch pointing at a target commit
+ *
+ * This behaves like `git_branch_create()` but takes an annotated
+ * commit, which lets you specify which extended sha syntax string was
+ * specified by a user, allowing for more exact reflog messages.
+ *
+ * See the documentation for `git_branch_create()`.
+ *
+ * @see git_branch_create
+ */
+GIT_EXTERN(int) git_branch_create_from_annotated(
+	git_reference **ref_out,
+	git_repository *repository,
+	const char *branch_name,
+	const git_annotated_commit *commit,
+	int force);
+
+/**
+ * Delete an existing branch reference.
+ *
+ * If the branch is successfully deleted, the passed reference
+ * object will be invalidated. The reference must be freed manually
+ * by the user.
+ *
+ * @param branch A valid reference representing a branch
+ * @return 0 on success, or an error code.
+ */
+GIT_EXTERN(int) git_branch_delete(git_reference *branch);
+
+/** Iterator type for branches */
+typedef struct git_branch_iterator git_branch_iterator;
+
+/**
+ * Create an iterator which loops over the requested branches.
+ *
+ * @param out the iterator
+ * @param repo Repository where to find the branches.
+ * @param list_flags Filtering flags for the branch
+ * listing. Valid values are GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE
+ * or GIT_BRANCH_ALL.
+ *
+ * @return 0 on success  or an error code
+ */
+GIT_EXTERN(int) git_branch_iterator_new(
+	git_branch_iterator **out,
+	git_repository *repo,
+	git_branch_t list_flags);
+
+/**
+ * Retrieve the next branch from the iterator
+ *
+ * @param out the reference
+ * @param out_type the type of branch (local or remote-tracking)
+ * @param iter the branch iterator
+ * @return 0 on success, GIT_ITEROVER if there are no more branches or an error code.
+ */
+GIT_EXTERN(int) git_branch_next(git_reference **out, git_branch_t *out_type, git_branch_iterator *iter);
+
+/**
+ * Free a branch iterator
+ *
+ * @param iter the iterator to free
+ */
+GIT_EXTERN(void) git_branch_iterator_free(git_branch_iterator *iter);
+
+/**
+ * Move/rename an existing local branch reference.
+ *
+ * The new branch name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
+ *
+ * @param branch Current underlying reference of the branch.
+ *
+ * @param new_branch_name Target name of the branch once the move
+ * is performed; this name is validated for consistency.
+ *
+ * @param force Overwrite existing branch.
+ *
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code.
+ */
+GIT_EXTERN(int) git_branch_move(
+	git_reference **out,
+	git_reference *branch,
+	const char *new_branch_name,
+	int force);
+
+/**
+ * Lookup a branch by its name in a repository.
+ *
+ * The generated reference must be freed by the user.
+ *
+ * The branch name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
+ *
+ * @param out pointer to the looked-up branch reference
+ *
+ * @param repo the repository to look up the branch
+ *
+ * @param branch_name Name of the branch to be looked-up;
+ * this name is validated for consistency.
+ *
+ * @param branch_type Type of the considered branch. This should
+ * be valued with either GIT_BRANCH_LOCAL or GIT_BRANCH_REMOTE.
+ *
+ * @return 0 on success; GIT_ENOTFOUND when no matching branch
+ * exists, GIT_EINVALIDSPEC, otherwise an error code.
+ */
+GIT_EXTERN(int) git_branch_lookup(
+	git_reference **out,
+	git_repository *repo,
+	const char *branch_name,
+	git_branch_t branch_type);
+
+/**
+ * Return the name of the given local or remote branch.
+ *
+ * The name of the branch matches the definition of the name
+ * for git_branch_lookup. That is, if the returned name is given
+ * to git_branch_lookup() then the reference is returned that
+ * was given to this function.
+ *
+ * @param out where the pointer of branch name is stored;
+ * this is valid as long as the ref is not freed.
+ * @param ref the reference ideally pointing to a branch
+ *
+ * @return 0 on success; otherwise an error code (e.g., if the
+ *  ref is no local or remote branch).
+ */
+GIT_EXTERN(int) git_branch_name(
+		const char **out,
+		const git_reference *ref);
+
+/**
+ * Return the reference supporting the remote tracking branch,
+ * given a local branch reference.
+ *
+ * @param out Pointer where to store the retrieved
+ * reference.
+ *
+ * @param branch Current underlying reference of the branch.
+ *
+ * @return 0 on success; GIT_ENOTFOUND when no remote tracking
+ * reference exists, otherwise an error code.
+ */
+GIT_EXTERN(int) git_branch_upstream(
+	git_reference **out,
+	const git_reference *branch);
+
+/**
+ * Set the upstream configuration for a given local branch
+ *
+ * @param branch the branch to configure
+ *
+ * @param upstream_name remote-tracking or local branch to set as
+ * upstream. Pass NULL to unset.
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_branch_set_upstream(git_reference *branch, const char *upstream_name);
+
+/**
+ * Return the name of the reference supporting the remote tracking branch,
+ * given the name of a local branch reference.
+ *
+ * @param out Pointer to the user-allocated git_buf which will be
+ * filled with the name of the reference.
+ *
+ * @param repo the repository where the branches live
+ *
+ * @param refname reference name of the local branch.
+ *
+ * @return 0, GIT_ENOTFOUND when no remote tracking reference exists,
+ *     otherwise an error code.
+ */
+GIT_EXTERN(int) git_branch_upstream_name(
+	git_buf *out,
+	git_repository *repo,
+	const char *refname);
+
+/**
+ * Determine if the current local branch is pointed at by HEAD.
+ *
+ * @param branch Current underlying reference of the branch.
+ *
+ * @return 1 if HEAD points at the branch, 0 if it isn't,
+ * error code otherwise.
+ */
+GIT_EXTERN(int) git_branch_is_head(
+	const git_reference *branch);
+
+/**
+ * Return the name of remote that the remote tracking branch belongs to.
+ *
+ * @param out Pointer to the user-allocated git_buf which will be filled with the name of the remote.
+ *
+ * @param repo The repository where the branch lives.
+ *
+ * @param canonical_branch_name name of the remote tracking branch.
+ *
+ * @return 0, GIT_ENOTFOUND
+ *     when no remote matching remote was found,
+ *     GIT_EAMBIGUOUS when the branch maps to several remotes,
+ *     otherwise an error code.
+ */
+GIT_EXTERN(int) git_branch_remote_name(
+	git_buf *out,
+	git_repository *repo,
+	const char *canonical_branch_name);
+
+
+/**
+ * Retrieve the name fo the upstream remote of a local branch
+ *
+ * @param buf the buffer into which to write the name
+ * @param repo the repository in which to look
+ * @param refname the full name of the branch
+ * @return 0 or an error code
+ */
+ GIT_EXTERN(int) git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/buffer.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/buffer.h
new file mode 100755
index 0000000..9fc6a58
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/buffer.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_buf_h__
+#define INCLUDE_git_buf_h__
+
+#include "common.h"
+
+/**
+ * @file git2/buffer.h
+ * @brief Buffer export structure
+ *
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * A data buffer for exporting data from libgit2
+ *
+ * Sometimes libgit2 wants to return an allocated data buffer to the
+ * caller and have the caller take responsibility for freeing that memory.
+ * This can be awkward if the caller does not have easy access to the same
+ * allocation functions that libgit2 is using.  In those cases, libgit2
+ * will fill in a `git_buf` and the caller can use `git_buf_free()` to
+ * release it when they are done.
+ *
+ * A `git_buf` may also be used for the caller to pass in a reference to
+ * a block of memory they hold.  In this case, libgit2 will not resize or
+ * free the memory, but will read from it as needed.
+ *
+ * A `git_buf` is a public structure with three fields:
+ *
+ * - `ptr` points to the start of the allocated memory.  If it is NULL,
+ *   then the `git_buf` is considered empty and libgit2 will feel free
+ *   to overwrite it with new data.
+ *
+ * - `size` holds the size (in bytes) of the data that is actually used.
+ *
+ * - `asize` holds the known total amount of allocated memory if the `ptr`
+ *    was allocated by libgit2.  It may be larger than `size`.  If `ptr`
+ *    was not allocated by libgit2 and should not be resized and/or freed,
+ *    then `asize` will be set to zero.
+ *
+ * Some APIs may occasionally do something slightly unusual with a buffer,
+ * such as setting `ptr` to a value that was passed in by the user.  In
+ * those cases, the behavior will be clearly documented by the API.
+ */
+typedef struct {
+	char   *ptr;
+	size_t asize, size;
+} git_buf;
+
+/**
+ * Static initializer for git_buf from static buffer
+ */
+#define GIT_BUF_INIT_CONST(STR,LEN) { (char *)(STR), 0, (size_t)(LEN) }
+
+/**
+ * Free the memory referred to by the git_buf.
+ *
+ * Note that this does not free the `git_buf` itself, just the memory
+ * pointed to by `buffer->ptr`.  This will not free the memory if it looks
+ * like it was not allocated internally, but it will clear the buffer back
+ * to the empty state.
+ *
+ * @param buffer The buffer to deallocate
+ */
+GIT_EXTERN(void) git_buf_free(git_buf *buffer);
+
+/**
+ * Resize the buffer allocation to make more space.
+ *
+ * This will attempt to grow the buffer to accommodate the target size.
+ *
+ * If the buffer refers to memory that was not allocated by libgit2 (i.e.
+ * the `asize` field is zero), then `ptr` will be replaced with a newly
+ * allocated block of data.  Be careful so that memory allocated by the
+ * caller is not lost.  As a special variant, if you pass `target_size` as
+ * 0 and the memory is not allocated by libgit2, this will allocate a new
+ * buffer of size `size` and copy the external data into it.
+ *
+ * Currently, this will never shrink a buffer, only expand it.
+ *
+ * If the allocation fails, this will return an error and the buffer will be
+ * marked as invalid for future operations, invaliding the contents.
+ *
+ * @param buffer The buffer to be resized; may or may not be allocated yet
+ * @param target_size The desired available size
+ * @return 0 on success, -1 on allocation failure
+ */
+GIT_EXTERN(int) git_buf_grow(git_buf *buffer, size_t target_size);
+
+/**
+ * Set buffer to a copy of some raw data.
+ *
+ * @param buffer The buffer to set
+ * @param data The data to copy into the buffer
+ * @param datalen The length of the data to copy into the buffer
+ * @return 0 on success, -1 on allocation failure
+ */
+GIT_EXTERN(int) git_buf_set(
+	git_buf *buffer, const void *data, size_t datalen);
+
+/**
+* Check quickly if buffer looks like it contains binary data
+*
+* @param buf Buffer to check
+* @return 1 if buffer looks like non-text data
+*/
+GIT_EXTERN(int) git_buf_is_binary(const git_buf *buf);
+
+/**
+* Check quickly if buffer contains a NUL byte
+*
+* @param buf Buffer to check
+* @return 1 if buffer contains a NUL byte
+*/
+GIT_EXTERN(int) git_buf_contains_nul(const git_buf *buf);
+
+GIT_END_DECL
+
+/** @} */
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/checkout.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/checkout.h
new file mode 100755
index 0000000..6cf9ed8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/checkout.h
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_checkout_h__
+#define INCLUDE_git_checkout_h__
+
+#include "common.h"
+#include "types.h"
+#include "diff.h"
+
+/**
+ * @file git2/checkout.h
+ * @brief Git checkout routines
+ * @defgroup git_checkout Git checkout routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Checkout behavior flags
+ *
+ * In libgit2, checkout is used to update the working directory and index
+ * to match a target tree.  Unlike git checkout, it does not move the HEAD
+ * commit for you - use `git_repository_set_head` or the like to do that.
+ *
+ * Checkout looks at (up to) four things: the "target" tree you want to
+ * check out, the "baseline" tree of what was checked out previously, the
+ * working directory for actual files, and the index for staged changes.
+ *
+ * You give checkout one of three strategies for update:
+ *
+ * - `GIT_CHECKOUT_NONE` is a dry-run strategy that checks for conflicts,
+ *   etc., but doesn't make any actual changes.
+ *
+ * - `GIT_CHECKOUT_FORCE` is at the opposite extreme, taking any action to
+ *   make the working directory match the target (including potentially
+ *   discarding modified files).
+ *
+ * - `GIT_CHECKOUT_SAFE` is between these two options, it will only make
+ *   modifications that will not lose changes.
+ *
+ *                         |  target == baseline   |  target != baseline  |
+ *    ---------------------|-----------------------|----------------------|
+ *     workdir == baseline |       no action       |  create, update, or  |
+ *                         |                       |     delete file      |
+ *    ---------------------|-----------------------|----------------------|
+ *     workdir exists and  |       no action       |   conflict (notify   |
+ *       is != baseline    | notify dirty MODIFIED | and cancel checkout) |
+ *    ---------------------|-----------------------|----------------------|
+ *      workdir missing,   | notify dirty DELETED  |     create file      |
+ *      baseline present   |                       |                      |
+ *    ---------------------|-----------------------|----------------------|
+ *
+ * To emulate `git checkout`, use `GIT_CHECKOUT_SAFE` with a checkout
+ * notification callback (see below) that displays information about dirty
+ * files.  The default behavior will cancel checkout on conflicts.
+ *
+ * To emulate `git checkout-index`, use `GIT_CHECKOUT_SAFE` with a
+ * notification callback that cancels the operation if a dirty-but-existing
+ * file is found in the working directory.  This core git command isn't
+ * quite "force" but is sensitive about some types of changes.
+ *
+ * To emulate `git checkout -f`, use `GIT_CHECKOUT_FORCE`.
+ *
+ *
+ * There are some additional flags to modified the behavior of checkout:
+ *
+ * - GIT_CHECKOUT_ALLOW_CONFLICTS makes SAFE mode apply safe file updates
+ *   even if there are conflicts (instead of cancelling the checkout).
+ *
+ * - GIT_CHECKOUT_REMOVE_UNTRACKED means remove untracked files (i.e. not
+ *   in target, baseline, or index, and not ignored) from the working dir.
+ *
+ * - GIT_CHECKOUT_REMOVE_IGNORED means remove ignored files (that are also
+ *   untracked) from the working directory as well.
+ *
+ * - GIT_CHECKOUT_UPDATE_ONLY means to only update the content of files that
+ *   already exist.  Files will not be created nor deleted.  This just skips
+ *   applying adds, deletes, and typechanges.
+ *
+ * - GIT_CHECKOUT_DONT_UPDATE_INDEX prevents checkout from writing the
+ *   updated files' information to the index.
+ *
+ * - Normally, checkout will reload the index and git attributes from disk
+ *   before any operations.  GIT_CHECKOUT_NO_REFRESH prevents this reload.
+ *
+ * - Unmerged index entries are conflicts.  GIT_CHECKOUT_SKIP_UNMERGED skips
+ *   files with unmerged index entries instead.  GIT_CHECKOUT_USE_OURS and
+ *   GIT_CHECKOUT_USE_THEIRS to proceed with the checkout using either the
+ *   stage 2 ("ours") or stage 3 ("theirs") version of files in the index.
+ *
+ * - GIT_CHECKOUT_DONT_OVERWRITE_IGNORED prevents ignored files from being
+ *   overwritten.  Normally, files that are ignored in the working directory
+ *   are not considered "precious" and may be overwritten if the checkout
+ *   target contains that file.
+ *
+ * - GIT_CHECKOUT_DONT_REMOVE_EXISTING prevents checkout from removing
+ *   files or folders that fold to the same name on case insensitive
+ *   filesystems.  This can cause files to retain their existing names
+ *   and write through existing symbolic links.
+ */
+typedef enum {
+	GIT_CHECKOUT_NONE = 0, /**< default is a dry run, no actual updates */
+
+	/** Allow safe updates that cannot overwrite uncommitted data */
+	GIT_CHECKOUT_SAFE = (1u << 0),
+
+	/** Allow all updates to force working directory to look like index */
+	GIT_CHECKOUT_FORCE = (1u << 1),
+
+
+	/** Allow checkout to recreate missing files */
+	GIT_CHECKOUT_RECREATE_MISSING = (1u << 2),
+
+	/** Allow checkout to make safe updates even if conflicts are found */
+	GIT_CHECKOUT_ALLOW_CONFLICTS = (1u << 4),
+
+	/** Remove untracked files not in index (that are not ignored) */
+	GIT_CHECKOUT_REMOVE_UNTRACKED = (1u << 5),
+
+	/** Remove ignored files not in index */
+	GIT_CHECKOUT_REMOVE_IGNORED = (1u << 6),
+
+	/** Only update existing files, don't create new ones */
+	GIT_CHECKOUT_UPDATE_ONLY = (1u << 7),
+
+	/**
+	 * Normally checkout updates index entries as it goes; this stops that.
+	 * Implies `GIT_CHECKOUT_DONT_WRITE_INDEX`.
+	 */
+	GIT_CHECKOUT_DONT_UPDATE_INDEX = (1u << 8),
+
+	/** Don't refresh index/config/etc before doing checkout */
+	GIT_CHECKOUT_NO_REFRESH = (1u << 9),
+
+	/** Allow checkout to skip unmerged files */
+	GIT_CHECKOUT_SKIP_UNMERGED = (1u << 10),
+	/** For unmerged files, checkout stage 2 from index */
+	GIT_CHECKOUT_USE_OURS = (1u << 11),
+	/** For unmerged files, checkout stage 3 from index */
+	GIT_CHECKOUT_USE_THEIRS = (1u << 12),
+
+	/** Treat pathspec as simple list of exact match file paths */
+	GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH = (1u << 13),
+
+	/** Ignore directories in use, they will be left empty */
+	GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES = (1u << 18),
+
+	/** Don't overwrite ignored files that exist in the checkout target */
+	GIT_CHECKOUT_DONT_OVERWRITE_IGNORED = (1u << 19),
+
+	/** Write normal merge files for conflicts */
+	GIT_CHECKOUT_CONFLICT_STYLE_MERGE = (1u << 20),
+
+	/** Include common ancestor data in diff3 format files for conflicts */
+	GIT_CHECKOUT_CONFLICT_STYLE_DIFF3 = (1u << 21),
+
+	/** Don't overwrite existing files or folders */
+	GIT_CHECKOUT_DONT_REMOVE_EXISTING = (1u << 22),
+
+	/** Normally checkout writes the index upon completion; this prevents that. */
+	GIT_CHECKOUT_DONT_WRITE_INDEX = (1u << 23),
+
+	/**
+	 * THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED
+	 */
+
+	/** Recursively checkout submodules with same options (NOT IMPLEMENTED) */
+	GIT_CHECKOUT_UPDATE_SUBMODULES = (1u << 16),
+	/** Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED) */
+	GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = (1u << 17),
+
+} git_checkout_strategy_t;
+
+/**
+ * Checkout notification flags
+ *
+ * Checkout will invoke an options notification callback (`notify_cb`) for
+ * certain cases - you pick which ones via `notify_flags`:
+ *
+ * - GIT_CHECKOUT_NOTIFY_CONFLICT invokes checkout on conflicting paths.
+ *
+ * - GIT_CHECKOUT_NOTIFY_DIRTY notifies about "dirty" files, i.e. those that
+ *   do not need an update but no longer match the baseline.  Core git
+ *   displays these files when checkout runs, but won't stop the checkout.
+ *
+ * - GIT_CHECKOUT_NOTIFY_UPDATED sends notification for any file changed.
+ *
+ * - GIT_CHECKOUT_NOTIFY_UNTRACKED notifies about untracked files.
+ *
+ * - GIT_CHECKOUT_NOTIFY_IGNORED notifies about ignored files.
+ *
+ * Returning a non-zero value from this callback will cancel the checkout.
+ * The non-zero return value will be propagated back and returned by the
+ * git_checkout_... call.
+ *
+ * Notification callbacks are made prior to modifying any files on disk,
+ * so canceling on any notification will still happen prior to any files
+ * being modified.
+ */
+typedef enum {
+	GIT_CHECKOUT_NOTIFY_NONE      = 0,
+	GIT_CHECKOUT_NOTIFY_CONFLICT  = (1u << 0),
+	GIT_CHECKOUT_NOTIFY_DIRTY     = (1u << 1),
+	GIT_CHECKOUT_NOTIFY_UPDATED   = (1u << 2),
+	GIT_CHECKOUT_NOTIFY_UNTRACKED = (1u << 3),
+	GIT_CHECKOUT_NOTIFY_IGNORED   = (1u << 4),
+
+	GIT_CHECKOUT_NOTIFY_ALL       = 0x0FFFFu
+} git_checkout_notify_t;
+
+typedef struct {
+	size_t mkdir_calls;
+	size_t stat_calls;
+	size_t chmod_calls;
+} git_checkout_perfdata;
+
+/** Checkout notification callback function */
+typedef int (*git_checkout_notify_cb)(
+	git_checkout_notify_t why,
+	const char *path,
+	const git_diff_file *baseline,
+	const git_diff_file *target,
+	const git_diff_file *workdir,
+	void *payload);
+
+/** Checkout progress notification function */
+typedef void (*git_checkout_progress_cb)(
+	const char *path,
+	size_t completed_steps,
+	size_t total_steps,
+	void *payload);
+
+/** Checkout perfdata notification function */
+typedef void (*git_checkout_perfdata_cb)(
+	const git_checkout_perfdata *perfdata,
+	void *payload);
+
+/**
+ * Checkout options structure
+ *
+ * Zero out for defaults.  Initialize with `GIT_CHECKOUT_OPTIONS_INIT` macro to
+ * correctly set the `version` field.  E.g.
+ *
+ *		git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+ */
+typedef struct git_checkout_options {
+	unsigned int version;
+
+	unsigned int checkout_strategy; /**< default will be a dry run */
+
+	int disable_filters;    /**< don't apply filters like CRLF conversion */
+	unsigned int dir_mode;  /**< default is 0755 */
+	unsigned int file_mode; /**< default is 0644 or 0755 as dictated by blob */
+	int file_open_flags;    /**< default is O_CREAT | O_TRUNC | O_WRONLY */
+
+	unsigned int notify_flags; /**< see `git_checkout_notify_t` above */
+	git_checkout_notify_cb notify_cb;
+	void *notify_payload;
+
+	/** Optional callback to notify the consumer of checkout progress. */
+	git_checkout_progress_cb progress_cb;
+	void *progress_payload;
+
+	/** When not zeroed out, array of fnmatch patterns specifying which
+	 *  paths should be taken into account, otherwise all files.  Use
+	 *  GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH to treat as simple list.
+	 */
+	git_strarray paths;
+
+	/** The expected content of the working directory; defaults to HEAD.
+	 *  If the working directory does not match this baseline information,
+	 *  that will produce a checkout conflict.
+	 */
+	git_tree *baseline;
+
+	/** Like `baseline` above, though expressed as an index.  This
+	 *  option overrides `baseline`.
+	 */
+	git_index *baseline_index; /**< expected content of workdir, expressed as an index. */
+
+	const char *target_directory; /**< alternative checkout path to workdir */
+
+	const char *ancestor_label; /**< the name of the common ancestor side of conflicts */
+	const char *our_label; /**< the name of the "our" side of conflicts */
+	const char *their_label; /**< the name of the "their" side of conflicts */
+
+	/** Optional callback to notify the consumer of performance data. */
+	git_checkout_perfdata_cb perfdata_cb;
+	void *perfdata_payload;
+} git_checkout_options;
+
+#define GIT_CHECKOUT_OPTIONS_VERSION 1
+#define GIT_CHECKOUT_OPTIONS_INIT {GIT_CHECKOUT_OPTIONS_VERSION}
+
+/**
+* Initializes a `git_checkout_options` with default values. Equivalent to
+* creating an instance with GIT_CHECKOUT_OPTIONS_INIT.
+*
+* @param opts the `git_checkout_options` struct to initialize.
+* @param version Version of struct; pass `GIT_CHECKOUT_OPTIONS_VERSION`
+* @return Zero on success; -1 on failure.
+*/
+GIT_EXTERN(int) git_checkout_init_options(
+	git_checkout_options *opts,
+	unsigned int version);
+
+/**
+ * Updates files in the index and the working tree to match the content of
+ * the commit pointed at by HEAD.
+ *
+ * @param repo repository to check out (must be non-bare)
+ * @param opts specifies checkout options (may be NULL)
+ * @return 0 on success, GIT_EUNBORNBRANCH if HEAD points to a non
+ *         existing branch, non-zero value returned by `notify_cb`, or
+ *         other error code < 0 (use giterr_last for error details)
+ */
+GIT_EXTERN(int) git_checkout_head(
+	git_repository *repo,
+	const git_checkout_options *opts);
+
+/**
+ * Updates files in the working tree to match the content of the index.
+ *
+ * @param repo repository into which to check out (must be non-bare)
+ * @param index index to be checked out (or NULL to use repository index)
+ * @param opts specifies checkout options (may be NULL)
+ * @return 0 on success, non-zero return value from `notify_cb`, or error
+ *         code < 0 (use giterr_last for error details)
+ */
+GIT_EXTERN(int) git_checkout_index(
+	git_repository *repo,
+	git_index *index,
+	const git_checkout_options *opts);
+
+/**
+ * Updates files in the index and working tree to match the content of the
+ * tree pointed at by the treeish.
+ *
+ * @param repo repository to check out (must be non-bare)
+ * @param treeish a commit, tag or tree which content will be used to update
+ * the working directory (or NULL to use HEAD)
+ * @param opts specifies checkout options (may be NULL)
+ * @return 0 on success, non-zero return value from `notify_cb`, or error
+ *         code < 0 (use giterr_last for error details)
+ */
+GIT_EXTERN(int) git_checkout_tree(
+	git_repository *repo,
+	const git_object *treeish,
+	const git_checkout_options *opts);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/cherrypick.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/cherrypick.h
new file mode 100755
index 0000000..edec96a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/cherrypick.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_cherrypick_h__
+#define INCLUDE_git_cherrypick_h__
+
+#include "common.h"
+#include "types.h"
+#include "merge.h"
+
+/**
+ * @file git2/cherrypick.h
+ * @brief Git cherry-pick routines
+ * @defgroup git_cherrypick Git cherry-pick routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Cherry-pick options
+ */
+typedef struct {
+	unsigned int version;
+
+	/** For merge commits, the "mainline" is treated as the parent. */
+	unsigned int mainline;
+
+	git_merge_options merge_opts; /**< Options for the merging */
+	git_checkout_options checkout_opts; /**< Options for the checkout */
+} git_cherrypick_options;
+
+#define GIT_CHERRYPICK_OPTIONS_VERSION 1
+#define GIT_CHERRYPICK_OPTIONS_INIT {GIT_CHERRYPICK_OPTIONS_VERSION, 0, GIT_MERGE_OPTIONS_INIT, GIT_CHECKOUT_OPTIONS_INIT}
+
+/**
+ * Initializes a `git_cherrypick_options` with default values. Equivalent to
+ * creating an instance with GIT_CHERRYPICK_OPTIONS_INIT.
+ *
+ * @param opts the `git_cherrypick_options` struct to initialize
+ * @param version Version of struct; pass `GIT_CHERRYPICK_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_cherrypick_init_options(
+	git_cherrypick_options *opts,
+	unsigned int version);
+
+/**
+ * Cherry-picks the given commit against the given "our" commit, producing an
+ * index that reflects the result of the cherry-pick.
+ *
+ * The returned index must be freed explicitly with `git_index_free`.
+ *
+ * @param out pointer to store the index result in
+ * @param repo the repository that contains the given commits
+ * @param cherrypick_commit the commit to cherry-pick
+ * @param our_commit the commit to revert against (eg, HEAD)
+ * @param mainline the parent of the revert commit, if it is a merge
+ * @param merge_options the merge options (or null for defaults)
+ * @return zero on success, -1 on failure.
+ */
+GIT_EXTERN(int) git_cherrypick_commit(
+	git_index **out,
+	git_repository *repo,
+	git_commit *cherrypick_commit,
+	git_commit *our_commit,
+	unsigned int mainline,
+	const git_merge_options *merge_options);
+
+/**
+ * Cherry-pick the given commit, producing changes in the index and working directory.
+ *
+ * @param repo the repository to cherry-pick
+ * @param commit the commit to cherry-pick
+ * @param cherrypick_options the cherry-pick options (or null for defaults)
+ * @return zero on success, -1 on failure.
+ */
+GIT_EXTERN(int) git_cherrypick(
+	git_repository *repo,
+	git_commit *commit,
+	const git_cherrypick_options *cherrypick_options);
+
+/** @} */
+GIT_END_DECL
+
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/clone.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/clone.h
new file mode 100755
index 0000000..9e23aac
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/clone.h
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_clone_h__
+#define INCLUDE_git_clone_h__
+
+#include "common.h"
+#include "types.h"
+#include "indexer.h"
+#include "checkout.h"
+#include "remote.h"
+#include "transport.h"
+
+
+/**
+ * @file git2/clone.h
+ * @brief Git cloning routines
+ * @defgroup git_clone Git cloning routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Options for bypassing the git-aware transport on clone. Bypassing
+ * it means that instead of a fetch, libgit2 will copy the object
+ * database directory instead of figuring out what it needs, which is
+ * faster. If possible, it will hardlink the files to save space.
+ */
+typedef enum {
+	/**
+	 * Auto-detect (default), libgit2 will bypass the git-aware
+	 * transport for local paths, but use a normal fetch for
+	 * `file://` urls.
+	 */
+	GIT_CLONE_LOCAL_AUTO,
+	/**
+	 * Bypass the git-aware transport even for a `file://` url.
+	 */
+	GIT_CLONE_LOCAL,
+	/**
+	 * Do no bypass the git-aware transport
+	 */
+	GIT_CLONE_NO_LOCAL,
+	/**
+	 * Bypass the git-aware transport, but do not try to use
+	 * hardlinks.
+	 */
+	GIT_CLONE_LOCAL_NO_LINKS,
+} git_clone_local_t;
+
+/**
+ * The signature of a function matching git_remote_create, with an additional
+ * void* as a callback payload.
+ *
+ * Callers of git_clone may provide a function matching this signature to override
+ * the remote creation and customization process during a clone operation.
+ *
+ * @param out the resulting remote
+ * @param repo the repository in which to create the remote
+ * @param name the remote's name
+ * @param url the remote's url
+ * @param payload an opaque payload
+ * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
+ */
+typedef int (*git_remote_create_cb)(
+	git_remote **out,
+	git_repository *repo,
+	const char *name,
+	const char *url,
+	void *payload);
+
+/**
+ * The signature of a function matchin git_repository_init, with an
+ * aditional void * as callback payload.
+ *
+ * Callers of git_clone my provide a function matching this signature
+ * to override the repository creation and customization process
+ * during a clone operation.
+ *
+ * @param out the resulting repository
+ * @param path path in which to create the repository
+ * @param bare whether the repository is bare. This is the value from the clone options
+ * @param payload payload specified by the options
+ * @return 0, or a negative value to indicate error
+ */
+typedef int (*git_repository_create_cb)(
+	git_repository **out,
+	const char *path,
+	int bare,
+	void *payload);
+
+/**
+ * Clone options structure
+ *
+ * Use the GIT_CLONE_OPTIONS_INIT to get the default settings, like this:
+ *
+ *		git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
+ */
+typedef struct git_clone_options {
+	unsigned int version;
+
+	/**
+	 * These options are passed to the checkout step. To disable
+	 * checkout, set the `checkout_strategy` to
+	 * `GIT_CHECKOUT_NONE`.
+	 */
+	git_checkout_options checkout_opts;
+
+	/**
+	 * Options which control the fetch, including callbacks.
+	 *
+	 * The callbacks are used for reporting fetch progress, and for acquiring
+	 * credentials in the event they are needed.
+	 */
+	git_fetch_options fetch_opts;
+
+	/**
+	 * Set to zero (false) to create a standard repo, or non-zero
+	 * for a bare repo
+	 */
+	int bare;
+
+	/**
+	 * Whether to use a fetch or copy the object database.
+	 */
+	git_clone_local_t local;
+
+	/**
+	 * The name of the branch to checkout. NULL means use the
+	 * remote's default branch.
+	 */
+	const char* checkout_branch;
+
+	/**
+	 * A callback used to create the new repository into which to
+	 * clone. If NULL, the 'bare' field will be used to determine
+	 * whether to create a bare repository.
+	 */
+	git_repository_create_cb repository_cb;
+
+	/**
+	 * An opaque payload to pass to the git_repository creation callback.
+	 * This parameter is ignored unless repository_cb is non-NULL.
+	 */
+	void *repository_cb_payload;
+
+	/**
+	 * A callback used to create the git_remote, prior to its being
+	 * used to perform the clone operation. See the documentation for
+	 * git_remote_create_cb for details. This parameter may be NULL,
+	 * indicating that git_clone should provide default behavior.
+	 */
+	git_remote_create_cb remote_cb;
+
+	/**
+	 * An opaque payload to pass to the git_remote creation callback.
+	 * This parameter is ignored unless remote_cb is non-NULL.
+	 */
+	void *remote_cb_payload;
+} git_clone_options;
+
+#define GIT_CLONE_OPTIONS_VERSION 1
+#define GIT_CLONE_OPTIONS_INIT { GIT_CLONE_OPTIONS_VERSION, \
+	{ GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE }, \
+	GIT_FETCH_OPTIONS_INIT }
+
+/**
+ * Initializes a `git_clone_options` with default values. Equivalent to
+ * creating an instance with GIT_CLONE_OPTIONS_INIT.
+ *
+ * @param opts The `git_clone_options` struct to initialize
+ * @param version Version of struct; pass `GIT_CLONE_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_clone_init_options(
+	git_clone_options *opts,
+	unsigned int version);
+
+/**
+ * Clone a remote repository.
+ *
+ * By default this creates its repository and initial remote to match
+ * git's defaults. You can use the options in the callback to
+ * customize how these are created.
+ *
+ * @param out pointer that will receive the resulting repository object
+ * @param url the remote repository to clone
+ * @param local_path local directory to clone to
+ * @param options configuration options for the clone.  If NULL, the
+ *        function works as though GIT_OPTIONS_INIT were passed.
+ * @return 0 on success, any non-zero return value from a callback
+ *         function, or a negative value to indicate an error (use
+ *         `giterr_last` for a detailed error message)
+ */
+GIT_EXTERN(int) git_clone(
+	git_repository **out,
+	const char *url,
+	const char *local_path,
+	const git_clone_options *options);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/commit.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/commit.h
new file mode 100755
index 0000000..04711c1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/commit.h
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_commit_h__
+#define INCLUDE_git_commit_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "object.h"
+
+/**
+ * @file git2/commit.h
+ * @brief Git commit parsing, formatting routines
+ * @defgroup git_commit Git commit parsing, formatting routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Lookup a commit object from a repository.
+ *
+ * The returned object should be released with `git_commit_free` when no
+ * longer needed.
+ *
+ * @param commit pointer to the looked up commit
+ * @param repo the repo to use when locating the commit.
+ * @param id identity of the commit to locate. If the object is
+ *		an annotated tag it will be peeled back to the commit.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_lookup(
+	git_commit **commit, git_repository *repo, const git_oid *id);
+
+/**
+ * Lookup a commit object from a repository, given a prefix of its
+ * identifier (short id).
+ *
+ * The returned object should be released with `git_commit_free` when no
+ * longer needed.
+ *
+ * @see git_object_lookup_prefix
+ *
+ * @param commit pointer to the looked up commit
+ * @param repo the repo to use when locating the commit.
+ * @param id identity of the commit to locate. If the object is
+ *		an annotated tag it will be peeled back to the commit.
+ * @param len the length of the short identifier
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_lookup_prefix(
+	git_commit **commit, git_repository *repo, const git_oid *id, size_t len);
+
+/**
+ * Close an open commit
+ *
+ * This is a wrapper around git_object_free()
+ *
+ * IMPORTANT:
+ * It *is* necessary to call this method when you stop
+ * using a commit. Failure to do so will cause a memory leak.
+ *
+ * @param commit the commit to close
+ */
+
+GIT_EXTERN(void) git_commit_free(git_commit *commit);
+
+/**
+ * Get the id of a commit.
+ *
+ * @param commit a previously loaded commit.
+ * @return object identity for the commit.
+ */
+GIT_EXTERN(const git_oid *) git_commit_id(const git_commit *commit);
+
+/**
+ * Get the repository that contains the commit.
+ *
+ * @param commit A previously loaded commit.
+ * @return Repository that contains this commit.
+ */
+GIT_EXTERN(git_repository *) git_commit_owner(const git_commit *commit);
+
+/**
+ * Get the encoding for the message of a commit,
+ * as a string representing a standard encoding name.
+ *
+ * The encoding may be NULL if the `encoding` header
+ * in the commit is missing; in that case UTF-8 is assumed.
+ *
+ * @param commit a previously loaded commit.
+ * @return NULL, or the encoding
+ */
+GIT_EXTERN(const char *) git_commit_message_encoding(const git_commit *commit);
+
+/**
+ * Get the full message of a commit.
+ *
+ * The returned message will be slightly prettified by removing any
+ * potential leading newlines.
+ *
+ * @param commit a previously loaded commit.
+ * @return the message of a commit
+ */
+GIT_EXTERN(const char *) git_commit_message(const git_commit *commit);
+
+/**
+ * Get the full raw message of a commit.
+ *
+ * @param commit a previously loaded commit.
+ * @return the raw message of a commit
+ */
+GIT_EXTERN(const char *) git_commit_message_raw(const git_commit *commit);
+
+/**
+ * Get the short "summary" of the git commit message.
+ *
+ * The returned message is the summary of the commit, comprising the
+ * first paragraph of the message with whitespace trimmed and squashed.
+ *
+ * @param commit a previously loaded commit.
+ * @return the summary of a commit or NULL on error
+ */
+GIT_EXTERN(const char *) git_commit_summary(git_commit *commit);
+
+/**
+ * Get the commit time (i.e. committer time) of a commit.
+ *
+ * @param commit a previously loaded commit.
+ * @return the time of a commit
+ */
+GIT_EXTERN(git_time_t) git_commit_time(const git_commit *commit);
+
+/**
+ * Get the commit timezone offset (i.e. committer's preferred timezone) of a commit.
+ *
+ * @param commit a previously loaded commit.
+ * @return positive or negative timezone offset, in minutes from UTC
+ */
+GIT_EXTERN(int) git_commit_time_offset(const git_commit *commit);
+
+/**
+ * Get the committer of a commit.
+ *
+ * @param commit a previously loaded commit.
+ * @return the committer of a commit
+ */
+GIT_EXTERN(const git_signature *) git_commit_committer(const git_commit *commit);
+
+/**
+ * Get the author of a commit.
+ *
+ * @param commit a previously loaded commit.
+ * @return the author of a commit
+ */
+GIT_EXTERN(const git_signature *) git_commit_author(const git_commit *commit);
+
+/**
+ * Get the full raw text of the commit header.
+ *
+ * @param commit a previously loaded commit
+ * @return the header text of the commit
+ */
+GIT_EXTERN(const char *) git_commit_raw_header(const git_commit *commit);
+
+/**
+ * Get the tree pointed to by a commit.
+ *
+ * @param tree_out pointer where to store the tree object
+ * @param commit a previously loaded commit.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_tree(git_tree **tree_out, const git_commit *commit);
+
+/**
+ * Get the id of the tree pointed to by a commit. This differs from
+ * `git_commit_tree` in that no attempts are made to fetch an object
+ * from the ODB.
+ *
+ * @param commit a previously loaded commit.
+ * @return the id of tree pointed to by commit.
+ */
+GIT_EXTERN(const git_oid *) git_commit_tree_id(const git_commit *commit);
+
+/**
+ * Get the number of parents of this commit
+ *
+ * @param commit a previously loaded commit.
+ * @return integer of count of parents
+ */
+GIT_EXTERN(unsigned int) git_commit_parentcount(const git_commit *commit);
+
+/**
+ * Get the specified parent of the commit.
+ *
+ * @param out Pointer where to store the parent commit
+ * @param commit a previously loaded commit.
+ * @param n the position of the parent (from 0 to `parentcount`)
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_commit_parent(
+	git_commit **out,
+	const git_commit *commit,
+	unsigned int n);
+
+/**
+ * Get the oid of a specified parent for a commit. This is different from
+ * `git_commit_parent`, which will attempt to load the parent commit from
+ * the ODB.
+ *
+ * @param commit a previously loaded commit.
+ * @param n the position of the parent (from 0 to `parentcount`)
+ * @return the id of the parent, NULL on error.
+ */
+GIT_EXTERN(const git_oid *) git_commit_parent_id(
+	const git_commit *commit,
+	unsigned int n);
+
+/**
+ * Get the commit object that is the <n>th generation ancestor
+ * of the named commit object, following only the first parents.
+ * The returned commit has to be freed by the caller.
+ *
+ * Passing `0` as the generation number returns another instance of the
+ * base commit itself.
+ *
+ * @param ancestor Pointer where to store the ancestor commit
+ * @param commit a previously loaded commit.
+ * @param n the requested generation
+ * @return 0 on success; GIT_ENOTFOUND if no matching ancestor exists
+ * or an error code
+ */
+GIT_EXTERN(int) git_commit_nth_gen_ancestor(
+	git_commit **ancestor,
+	const git_commit *commit,
+	unsigned int n);
+
+/**
+ * Get an arbitrary header field
+ *
+ * @param out the buffer to fill
+ * @param commit the commit to look in
+ * @param field the header field to return
+ * @return 0 on succeess, GIT_ENOTFOUND if the field does not exist,
+ * or an error code
+ */
+GIT_EXTERN(int) git_commit_header_field(git_buf *out, const git_commit *commit, const char *field);
+
+/**
+ * Create new commit in the repository from a list of `git_object` pointers
+ *
+ * The message will **not** be cleaned up automatically. You can do that
+ * with the `git_message_prettify()` function.
+ *
+ * @param id Pointer in which to store the OID of the newly created commit
+ *
+ * @param repo Repository where to store the commit
+ *
+ * @param update_ref If not NULL, name of the reference that
+ *	will be updated to point to this commit. If the reference
+ *	is not direct, it will be resolved to a direct reference.
+ *	Use "HEAD" to update the HEAD of the current branch and
+ *	make it point to this commit. If the reference doesn't
+ *	exist yet, it will be created. If it does exist, the first
+ *	parent must be the tip of this branch.
+ *
+ * @param author Signature with author and author time of commit
+ *
+ * @param committer Signature with committer and * commit time of commit
+ *
+ * @param message_encoding The encoding for the message in the
+ *  commit, represented with a standard encoding name.
+ *  E.g. "UTF-8". If NULL, no encoding header is written and
+ *  UTF-8 is assumed.
+ *
+ * @param message Full message for this commit
+ *
+ * @param tree An instance of a `git_tree` object that will
+ *  be used as the tree for the commit. This tree object must
+ *  also be owned by the given `repo`.
+ *
+ * @param parent_count Number of parents for this commit
+ *
+ * @param parents Array of `parent_count` pointers to `git_commit`
+ *  objects that will be used as the parents for this commit. This
+ *  array may be NULL if `parent_count` is 0 (root commit). All the
+ *  given commits must be owned by the `repo`.
+ *
+ * @return 0 or an error code
+ *	The created commit will be written to the Object Database and
+ *	the given reference will be updated to point to it
+ */
+GIT_EXTERN(int) git_commit_create(
+	git_oid *id,
+	git_repository *repo,
+	const char *update_ref,
+	const git_signature *author,
+	const git_signature *committer,
+	const char *message_encoding,
+	const char *message,
+	const git_tree *tree,
+	size_t parent_count,
+	const git_commit *parents[]);
+
+/**
+ * Create new commit in the repository using a variable argument list.
+ *
+ * The message will **not** be cleaned up automatically. You can do that
+ * with the `git_message_prettify()` function.
+ *
+ * The parents for the commit are specified as a variable list of pointers
+ * to `const git_commit *`. Note that this is a convenience method which may
+ * not be safe to export for certain languages or compilers
+ *
+ * All other parameters remain the same as `git_commit_create()`.
+ *
+ * @see git_commit_create
+ */
+GIT_EXTERN(int) git_commit_create_v(
+	git_oid *id,
+	git_repository *repo,
+	const char *update_ref,
+	const git_signature *author,
+	const git_signature *committer,
+	const char *message_encoding,
+	const char *message,
+	const git_tree *tree,
+	size_t parent_count,
+	...);
+
+/**
+ * Amend an existing commit by replacing only non-NULL values.
+ *
+ * This creates a new commit that is exactly the same as the old commit,
+ * except that any non-NULL values will be updated.  The new commit has
+ * the same parents as the old commit.
+ *
+ * The `update_ref` value works as in the regular `git_commit_create()`,
+ * updating the ref to point to the newly rewritten commit.  If you want
+ * to amend a commit that is not currently the tip of the branch and then
+ * rewrite the following commits to reach a ref, pass this as NULL and
+ * update the rest of the commit chain and ref separately.
+ *
+ * Unlike `git_commit_create()`, the `author`, `committer`, `message`,
+ * `message_encoding`, and `tree` parameters can be NULL in which case this
+ * will use the values from the original `commit_to_amend`.
+ *
+ * All parameters have the same meanings as in `git_commit_create()`.
+ *
+ * @see git_commit_create
+ */
+GIT_EXTERN(int) git_commit_amend(
+	git_oid *id,
+	const git_commit *commit_to_amend,
+	const char *update_ref,
+	const git_signature *author,
+	const git_signature *committer,
+	const char *message_encoding,
+	const char *message,
+	const git_tree *tree);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/common.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/common.h
new file mode 100755
index 0000000..d84a765
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/common.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_common_h__
+#define INCLUDE_git_common_h__
+
+#include <time.h>
+#include <stdlib.h>
+
+#ifdef _MSC_VER
+#	include "inttypes.h"
+#else
+#	include <inttypes.h>
+#endif
+
+#ifdef __cplusplus
+# define GIT_BEGIN_DECL extern "C" {
+# define GIT_END_DECL	}
+#else
+ /** Start declarations in C mode */
+# define GIT_BEGIN_DECL /* empty */
+ /** End declarations in C mode */
+# define GIT_END_DECL	/* empty */
+#endif
+
+/** Declare a public function exported for application use. */
+#if __GNUC__ >= 4
+# define GIT_EXTERN(type) extern \
+			 __attribute__((visibility("default"))) \
+			 type
+#elif defined(_MSC_VER)
+# define GIT_EXTERN(type) __declspec(dllexport) type
+#else
+# define GIT_EXTERN(type) extern type
+#endif
+
+/** Declare a function's takes printf style arguments. */
+#ifdef __GNUC__
+# define GIT_FORMAT_PRINTF(a,b) __attribute__((format (printf, a, b)))
+#else
+# define GIT_FORMAT_PRINTF(a,b) /* empty */
+#endif
+
+#if (defined(_WIN32)) && !defined(__CYGWIN__)
+#define GIT_WIN32 1
+#endif
+
+#ifdef __amigaos4__
+#include <netinet/in.h>
+#endif
+
+/**
+ * @file git2/common.h
+ * @brief Git common platform definitions
+ * @defgroup git_common Git common platform definitions
+ * @ingroup Git
+ * @{
+ */
+
+GIT_BEGIN_DECL
+
+/**
+ * The separator used in path list strings (ie like in the PATH
+ * environment variable). A semi-colon ";" is used on Windows, and
+ * a colon ":" for all other systems.
+ */
+#ifdef GIT_WIN32
+#define GIT_PATH_LIST_SEPARATOR ';'
+#else
+#define GIT_PATH_LIST_SEPARATOR ':'
+#endif
+
+/**
+ * The maximum length of a valid git path.
+ */
+#define GIT_PATH_MAX 4096
+
+/**
+ * The string representation of the null object ID.
+ */
+#define GIT_OID_HEX_ZERO "0000000000000000000000000000000000000000"
+
+/**
+ * Return the version of the libgit2 library
+ * being currently used.
+ *
+ * @param major Store the major version number
+ * @param minor Store the minor version number
+ * @param rev Store the revision (patch) number
+ */
+GIT_EXTERN(void) git_libgit2_version(int *major, int *minor, int *rev);
+
+/**
+ * Combinations of these values describe the features with which libgit2
+ * was compiled
+ */
+typedef enum {
+	GIT_FEATURE_THREADS	= (1 << 0),
+	GIT_FEATURE_HTTPS = (1 << 1),
+	GIT_FEATURE_SSH = (1 << 2),
+} git_feature_t;
+
+/**
+ * Query compile time options for libgit2.
+ *
+ * @return A combination of GIT_FEATURE_* values.
+ *
+ * - GIT_FEATURE_THREADS
+ *   Libgit2 was compiled with thread support. Note that thread support is
+ *   still to be seen as a 'work in progress' - basic object lookups are
+ *   believed to be threadsafe, but other operations may not be.
+ *
+ * - GIT_FEATURE_HTTPS
+ *   Libgit2 supports the https:// protocol. This requires the openssl
+ *   library to be found when compiling libgit2.
+ *
+ * - GIT_FEATURE_SSH
+ *   Libgit2 supports the SSH protocol for network operations. This requires
+ *   the libssh2 library to be found when compiling libgit2
+ */
+GIT_EXTERN(int) git_libgit2_features(void);
+
+/**
+ * Global library options
+ *
+ * These are used to select which global option to set or get and are
+ * used in `git_libgit2_opts()`.
+ */
+typedef enum {
+	GIT_OPT_GET_MWINDOW_SIZE,
+	GIT_OPT_SET_MWINDOW_SIZE,
+	GIT_OPT_GET_MWINDOW_MAPPED_LIMIT,
+	GIT_OPT_SET_MWINDOW_MAPPED_LIMIT,
+	GIT_OPT_GET_SEARCH_PATH,
+	GIT_OPT_SET_SEARCH_PATH,
+	GIT_OPT_SET_CACHE_OBJECT_LIMIT,
+	GIT_OPT_SET_CACHE_MAX_SIZE,
+	GIT_OPT_ENABLE_CACHING,
+	GIT_OPT_GET_CACHED_MEMORY,
+	GIT_OPT_GET_TEMPLATE_PATH,
+	GIT_OPT_SET_TEMPLATE_PATH,
+	GIT_OPT_SET_SSL_CERT_LOCATIONS,
+} git_libgit2_opt_t;
+
+/**
+ * Set or query a library global option
+ *
+ * Available options:
+ *
+ *	* opts(GIT_OPT_GET_MWINDOW_SIZE, size_t *):
+ *
+ *		> Get the maximum mmap window size
+ *
+ *	* opts(GIT_OPT_SET_MWINDOW_SIZE, size_t):
+ *
+ *		> Set the maximum mmap window size
+ *
+ *	* opts(GIT_OPT_GET_MWINDOW_MAPPED_LIMIT, size_t *):
+ *
+ *		> Get the maximum memory that will be mapped in total by the library
+ *
+ *	* opts(GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, size_t):
+ *
+ *		>Set the maximum amount of memory that can be mapped at any time
+ *		by the library
+ *
+ *	* opts(GIT_OPT_GET_SEARCH_PATH, int level, git_buf *buf)
+ *
+ *		> Get the search path for a given level of config data.  "level" must
+ *		> be one of `GIT_CONFIG_LEVEL_SYSTEM`, `GIT_CONFIG_LEVEL_GLOBAL`, or
+ *		> `GIT_CONFIG_LEVEL_XDG`.  The search path is written to the `out`
+ *		> buffer.
+ *
+ *	* opts(GIT_OPT_SET_SEARCH_PATH, int level, const char *path)
+ *
+ *		> Set the search path for a level of config data.  The search path
+ *		> applied to shared attributes and ignore files, too.
+ *		>
+ *		> - `path` lists directories delimited by GIT_PATH_LIST_SEPARATOR.
+ *		>   Pass NULL to reset to the default (generally based on environment
+ *		>   variables).  Use magic path `$PATH` to include the old value
+ *		>   of the path (if you want to prepend or append, for instance).
+ *		>
+ *		> - `level` must be GIT_CONFIG_LEVEL_SYSTEM, GIT_CONFIG_LEVEL_GLOBAL,
+ *		>   or GIT_CONFIG_LEVEL_XDG.
+ *
+ *	* opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, git_otype type, size_t size)
+ *
+ *		> Set the maximum data size for the given type of object to be
+ *		> considered eligible for caching in memory.  Setting to value to
+ *		> zero means that that type of object will not be cached.
+ *		> Defaults to 0 for GIT_OBJ_BLOB (i.e. won't cache blobs) and 4k
+ *		> for GIT_OBJ_COMMIT, GIT_OBJ_TREE, and GIT_OBJ_TAG.
+ *
+ *	* opts(GIT_OPT_SET_CACHE_MAX_SIZE, ssize_t max_storage_bytes)
+ *
+ *		> Set the maximum total data size that will be cached in memory
+ *		> across all repositories before libgit2 starts evicting objects
+ *		> from the cache.  This is a soft limit, in that the library might
+ *		> briefly exceed it, but will start aggressively evicting objects
+ *		> from cache when that happens.  The default cache size is 256MB.
+ *
+ *	* opts(GIT_OPT_ENABLE_CACHING, int enabled)
+ *
+ *		> Enable or disable caching completely.
+ *		>
+ *		> Because caches are repository-specific, disabling the cache
+ *		> cannot immediately clear all cached objects, but each cache will
+ *		> be cleared on the next attempt to update anything in it.
+ *
+ *	* opts(GIT_OPT_GET_CACHED_MEMORY, ssize_t *current, ssize_t *allowed)
+ *
+ *		> Get the current bytes in cache and the maximum that would be
+ *		> allowed in the cache.
+ *
+ *	* opts(GIT_OPT_GET_TEMPLATE_PATH, git_buf *out)
+ *
+ *		> Get the default template path.
+ *		> The path is written to the `out` buffer.
+ *
+ *	* opts(GIT_OPT_SET_TEMPLATE_PATH, const char *path)
+ *
+ *		> Set the default template path.
+ *		>
+ *		> - `path` directory of template.
+ *
+ *	* opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, const char *file, const char *path)
+ *
+ *		> Set the SSL certificate-authority locations.
+ *		>
+ *		> - `file` is the location of a file containing several
+ *		>   certificates concatenated together.
+ *		> - `path` is the location of a directory holding several
+ *		>   certificates, one per file.
+ *		>
+ * 		> Either parameter may be `NULL`, but not both.
+ *
+ * @param option Option key
+ * @param ... value to set the option
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_libgit2_opts(int option, ...);
+
+/** @} */
+GIT_END_DECL
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/config.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/config.h
new file mode 100755
index 0000000..537663e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/config.h
@@ -0,0 +1,696 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_config_h__
+#define INCLUDE_git_config_h__
+
+#include "common.h"
+#include "types.h"
+#include "buffer.h"
+
+/**
+ * @file git2/config.h
+ * @brief Git config management routines
+ * @defgroup git_config Git config management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Priority level of a config file.
+ * These priority levels correspond to the natural escalation logic
+ * (from higher to lower) when searching for config entries in git.git.
+ *
+ * git_config_open_default() and git_repository_config() honor those
+ * priority levels as well.
+ */
+typedef enum {
+	/** System-wide configuration file; /etc/gitconfig on Linux systems */
+	GIT_CONFIG_LEVEL_SYSTEM = 1,
+
+	/** XDG compatible configuration file; typically ~/.config/git/config */
+	GIT_CONFIG_LEVEL_XDG = 2,
+
+	/** User-specific configuration file (also called Global configuration
+	 * file); typically ~/.gitconfig
+	 */
+	GIT_CONFIG_LEVEL_GLOBAL = 3,
+
+	/** Repository specific configuration file; $WORK_DIR/.git/config on
+	 * non-bare repos
+	 */
+	GIT_CONFIG_LEVEL_LOCAL = 4,
+
+	/** Application specific configuration file; freely defined by applications
+	 */
+	GIT_CONFIG_LEVEL_APP = 5,
+
+	/** Represents the highest level available config file (i.e. the most
+	 * specific config file available that actually is loaded)
+	 */
+	GIT_CONFIG_HIGHEST_LEVEL = -1,
+} git_config_level_t;
+
+/**
+ * An entry in a configuration file
+ */
+typedef struct git_config_entry {
+	const char *name; /**< Name of the entry (normalised) */
+	const char *value; /**< String value of the entry */
+	git_config_level_t level; /**< Which config file this was found in */
+	void (*free)(struct git_config_entry *entry); /**< Free function for this entry */
+	void *payload; /**< Opaque value for the free function. Do not read or write */
+} git_config_entry;
+
+/**
+ * Free a config entry
+ */
+GIT_EXTERN(void) git_config_entry_free(git_config_entry *);
+
+typedef int  (*git_config_foreach_cb)(const git_config_entry *, void *);
+typedef struct git_config_iterator git_config_iterator;
+
+/**
+ * Config var type
+ */
+typedef enum {
+	GIT_CVAR_FALSE = 0,
+	GIT_CVAR_TRUE = 1,
+	GIT_CVAR_INT32,
+	GIT_CVAR_STRING
+} git_cvar_t;
+
+/**
+ * Mapping from config variables to values.
+ */
+typedef struct {
+	git_cvar_t cvar_type;
+	const char *str_match;
+	int map_value;
+} git_cvar_map;
+
+/**
+ * Locate the path to the global configuration file
+ *
+ * The user or global configuration file is usually
+ * located in `$HOME/.gitconfig`.
+ *
+ * This method will try to guess the full path to that
+ * file, if the file exists. The returned path
+ * may be used on any `git_config` call to load the
+ * global configuration file.
+ *
+ * This method will not guess the path to the xdg compatible
+ * config file (.config/git/config).
+ *
+ * @param out Pointer to a user-allocated git_buf in which to store the path
+ * @return 0 if a global configuration file has been found. Its path will be stored in `out`.
+ */
+GIT_EXTERN(int) git_config_find_global(git_buf *out);
+
+/**
+ * Locate the path to the global xdg compatible configuration file
+ *
+ * The xdg compatible configuration file is usually
+ * located in `$HOME/.config/git/config`.
+ *
+ * This method will try to guess the full path to that
+ * file, if the file exists. The returned path
+ * may be used on any `git_config` call to load the
+ * xdg compatible configuration file.
+ *
+ * @param out Pointer to a user-allocated git_buf in which to store the path
+ * @return 0 if a xdg compatible configuration file has been
+ *	found. Its path will be stored in `out`.
+ */
+GIT_EXTERN(int) git_config_find_xdg(git_buf *out);
+
+/**
+ * Locate the path to the system configuration file
+ *
+ * If /etc/gitconfig doesn't exist, it will look for
+ * %PROGRAMFILES%\Git\etc\gitconfig.
+ *
+ * @param out Pointer to a user-allocated git_buf in which to store the path
+ * @return 0 if a system configuration file has been
+ *	found. Its path will be stored in `out`.
+ */
+GIT_EXTERN(int) git_config_find_system(git_buf *out);
+
+/**
+ * Open the global, XDG and system configuration files
+ *
+ * Utility wrapper that finds the global, XDG and system configuration files
+ * and opens them into a single prioritized config object that can be
+ * used when accessing default config data outside a repository.
+ *
+ * @param out Pointer to store the config instance
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_open_default(git_config **out);
+
+/**
+ * Allocate a new configuration object
+ *
+ * This object is empty, so you have to add a file to it before you
+ * can do anything with it.
+ *
+ * @param out pointer to the new configuration
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_new(git_config **out);
+
+/**
+ * Add an on-disk config file instance to an existing config
+ *
+ * The on-disk file pointed at by `path` will be opened and
+ * parsed; it's expected to be a native Git config file following
+ * the default Git config syntax (see man git-config).
+ *
+ * If the file does not exist, the file will still be added and it
+ * will be created the first time we write to it.
+ *
+ * Note that the configuration object will free the file
+ * automatically.
+ *
+ * Further queries on this config object will access each
+ * of the config file instances in order (instances with
+ * a higher priority level will be accessed first).
+ *
+ * @param cfg the configuration to add the file to
+ * @param path path to the configuration file to add
+ * @param level the priority level of the backend
+ * @param force replace config file at the given priority level
+ * @return 0 on success, GIT_EEXISTS when adding more than one file
+ *  for a given priority level (and force_replace set to 0),
+ *  GIT_ENOTFOUND when the file doesn't exist or error code
+ */
+GIT_EXTERN(int) git_config_add_file_ondisk(
+	git_config *cfg,
+	const char *path,
+	git_config_level_t level,
+	int force);
+
+/**
+ * Create a new config instance containing a single on-disk file
+ *
+ * This method is a simple utility wrapper for the following sequence
+ * of calls:
+ *	- git_config_new
+ *	- git_config_add_file_ondisk
+ *
+ * @param out The configuration instance to create
+ * @param path Path to the on-disk file to open
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_config_open_ondisk(git_config **out, const char *path);
+
+/**
+ * Build a single-level focused config object from a multi-level one.
+ *
+ * The returned config object can be used to perform get/set/delete operations
+ * on a single specific level.
+ *
+ * Getting several times the same level from the same parent multi-level config
+ * will return different config instances, but containing the same config_file
+ * instance.
+ *
+ * @param out The configuration instance to create
+ * @param parent Multi-level config to search for the given level
+ * @param level Configuration level to search for
+ * @return 0, GIT_ENOTFOUND if the passed level cannot be found in the
+ * multi-level parent config, or an error code
+ */
+GIT_EXTERN(int) git_config_open_level(
+	git_config **out,
+	const git_config *parent,
+	git_config_level_t level);
+
+/**
+ * Open the global/XDG configuration file according to git's rules
+ *
+ * Git allows you to store your global configuration at
+ * `$HOME/.config` or `$XDG_CONFIG_HOME/git/config`. For backwards
+ * compatability, the XDG file shouldn't be used unless the use has
+ * created it explicitly. With this function you'll open the correct
+ * one to write to.
+ *
+ * @param out pointer in which to store the config object
+ * @param config the config object in which to look
+ */
+GIT_EXTERN(int) git_config_open_global(git_config **out, git_config *config);
+
+/**
+ * Create a snapshot of the configuration
+ *
+ * Create a snapshot of the current state of a configuration, which
+ * allows you to look into a consistent view of the configuration for
+ * looking up complex values (e.g. a remote, submodule).
+ *
+ * The string returned when querying such a config object is valid
+ * until it is freed.
+ *
+ * @param out pointer in which to store the snapshot config object
+ * @param config configuration to snapshot
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_snapshot(git_config **out, git_config *config);
+
+/**
+ * Free the configuration and its associated memory and files
+ *
+ * @param cfg the configuration to free
+ */
+GIT_EXTERN(void) git_config_free(git_config *cfg);
+
+/**
+ * Get the git_config_entry of a config variable.
+ *
+ * Free the git_config_entry after use with `git_config_entry_free()`.
+ *
+ * @param out pointer to the variable git_config_entry
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_get_entry(
+	git_config_entry **out,
+	const git_config *cfg,
+	const char *name);
+
+/**
+ * Get the value of an integer config variable.
+ *
+ * All config files will be looked into, in the order of their
+ * defined level. A higher level means a higher priority. The
+ * first occurrence of the variable will be returned here.
+ *
+ * @param out pointer to the variable where the value should be stored
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_get_int32(int32_t *out, const git_config *cfg, const char *name);
+
+/**
+ * Get the value of a long integer config variable.
+ *
+ * All config files will be looked into, in the order of their
+ * defined level. A higher level means a higher priority. The
+ * first occurrence of the variable will be returned here.
+ *
+ * @param out pointer to the variable where the value should be stored
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_get_int64(int64_t *out, const git_config *cfg, const char *name);
+
+/**
+ * Get the value of a boolean config variable.
+ *
+ * This function uses the usual C convention of 0 being false and
+ * anything else true.
+ *
+ * All config files will be looked into, in the order of their
+ * defined level. A higher level means a higher priority. The
+ * first occurrence of the variable will be returned here.
+ *
+ * @param out pointer to the variable where the value should be stored
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_get_bool(int *out, const git_config *cfg, const char *name);
+
+/**
+ * Get the value of a path config variable.
+ *
+ * A leading '~' will be expanded to the global search path (which
+ * defaults to the user's home directory but can be overridden via
+ * `git_libgit2_opts()`.
+ *
+ * All config files will be looked into, in the order of their
+ * defined level. A higher level means a higher priority. The
+ * first occurrence of the variable will be returned here.
+ *
+ * @param out the buffer in which to store the result
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_get_path(git_buf *out, const git_config *cfg, const char *name);
+
+/**
+ * Get the value of a string config variable.
+ *
+ * This function can only be used on snapshot config objects. The
+ * string is owned by the config and should not be freed by the
+ * user. The pointer will be valid until the config is freed.
+ *
+ * All config files will be looked into, in the order of their
+ * defined level. A higher level means a higher priority. The
+ * first occurrence of the variable will be returned here.
+ *
+ * @param out pointer to the string
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_get_string(const char **out, const git_config *cfg, const char *name);
+
+/**
+ * Get the value of a string config variable.
+ *
+ * The value of the config will be copied into the buffer.
+ *
+ * All config files will be looked into, in the order of their
+ * defined level. A higher level means a higher priority. The
+ * first occurrence of the variable will be returned here.
+ *
+ * @param out buffer in which to store the string
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_get_string_buf(git_buf *out, const git_config *cfg, const char *name);
+
+/**
+ * Get each value of a multivar in a foreach callback
+ *
+ * The callback will be called on each variable found
+ *
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @param regexp regular expression to filter which variables we're
+ * interested in. Use NULL to indicate all
+ * @param callback the function to be called on each value of the variable
+ * @param payload opaque pointer to pass to the callback
+ */
+GIT_EXTERN(int) git_config_get_multivar_foreach(const git_config *cfg, const char *name, const char *regexp, git_config_foreach_cb callback, void *payload);
+
+/**
+ * Get each value of a multivar
+ *
+ * @param out pointer to store the iterator
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @param regexp regular expression to filter which variables we're
+ * interested in. Use NULL to indicate all
+ */
+GIT_EXTERN(int) git_config_multivar_iterator_new(git_config_iterator **out, const git_config *cfg, const char *name, const char *regexp);
+
+/**
+ * Return the current entry and advance the iterator
+ *
+ * The pointers returned by this function are valid until the iterator
+ * is freed.
+ *
+ * @param entry pointer to store the entry
+ * @param iter the iterator
+ * @return 0 or an error code. GIT_ITEROVER if the iteration has completed
+ */
+GIT_EXTERN(int) git_config_next(git_config_entry **entry, git_config_iterator *iter);
+
+/**
+ * Free a config iterator
+ *
+ * @param iter the iterator to free
+ */
+GIT_EXTERN(void) git_config_iterator_free(git_config_iterator *iter);
+
+/**
+ * Set the value of an integer config variable in the config file
+ * with the highest level (usually the local one).
+ *
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @param value Integer value for the variable
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_set_int32(git_config *cfg, const char *name, int32_t value);
+
+/**
+ * Set the value of a long integer config variable in the config file
+ * with the highest level (usually the local one).
+ *
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @param value Long integer value for the variable
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_set_int64(git_config *cfg, const char *name, int64_t value);
+
+/**
+ * Set the value of a boolean config variable in the config file
+ * with the highest level (usually the local one).
+ *
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @param value the value to store
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_set_bool(git_config *cfg, const char *name, int value);
+
+/**
+ * Set the value of a string config variable in the config file
+ * with the highest level (usually the local one).
+ *
+ * A copy of the string is made and the user is free to use it
+ * afterwards.
+ *
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @param value the string to store.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_set_string(git_config *cfg, const char *name, const char *value);
+
+/**
+ * Set a multivar in the local config file.
+ *
+ * @param cfg where to look for the variable
+ * @param name the variable's name
+ * @param regexp a regular expression to indicate which values to replace
+ * @param value the new value.
+ */
+GIT_EXTERN(int) git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value);
+
+/**
+ * Delete a config variable from the config file
+ * with the highest level (usually the local one).
+ *
+ * @param cfg the configuration
+ * @param name the variable to delete
+ */
+GIT_EXTERN(int) git_config_delete_entry(git_config *cfg, const char *name);
+
+/**
+ * Deletes one or several entries from a multivar in the local config file.
+ *
+ * @param cfg where to look for the variables
+ * @param name the variable's name
+ * @param regexp a regular expression to indicate which values to delete
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_config_delete_multivar(git_config *cfg, const char *name, const char *regexp);
+
+/**
+ * Perform an operation on each config variable.
+ *
+ * The callback receives the normalized name and value of each variable
+ * in the config backend, and the data pointer passed to this function.
+ * If the callback returns a non-zero value, the function stops iterating
+ * and returns that value to the caller.
+ *
+ * The pointers passed to the callback are only valid as long as the
+ * iteration is ongoing.
+ *
+ * @param cfg where to get the variables from
+ * @param callback the function to call on each variable
+ * @param payload the data to pass to the callback
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_config_foreach(
+	const git_config *cfg,
+	git_config_foreach_cb callback,
+	void *payload);
+
+/**
+ * Iterate over all the config variables
+ *
+ * Use `git_config_next` to advance the iteration and
+ * `git_config_iterator_free` when done.
+ *
+ * @param out pointer to store the iterator
+ * @param cfg where to ge the variables from
+ */
+GIT_EXTERN(int) git_config_iterator_new(git_config_iterator **out, const git_config *cfg);
+
+/**
+ * Iterate over all the config variables whose name matches a pattern
+ *
+ * Use `git_config_next` to advance the iteration and
+ * `git_config_iterator_free` when done.
+ *
+ * @param out pointer to store the iterator
+ * @param cfg where to ge the variables from
+ * @param regexp regular expression to match the names
+ */
+GIT_EXTERN(int) git_config_iterator_glob_new(git_config_iterator **out, const git_config *cfg, const char *regexp);
+
+/**
+ * Perform an operation on each config variable matching a regular expression.
+ *
+ * This behaviors like `git_config_foreach` with an additional filter of a
+ * regular expression that filters which config keys are passed to the
+ * callback.
+ *
+ * The pointers passed to the callback are only valid as long as the
+ * iteration is ongoing.
+ *
+ * @param cfg where to get the variables from
+ * @param regexp regular expression to match against config names
+ * @param callback the function to call on each variable
+ * @param payload the data to pass to the callback
+ * @return 0 or the return value of the callback which didn't return 0
+ */
+GIT_EXTERN(int) git_config_foreach_match(
+	const git_config *cfg,
+	const char *regexp,
+	git_config_foreach_cb callback,
+	void *payload);
+
+/**
+ * Query the value of a config variable and return it mapped to
+ * an integer constant.
+ *
+ * This is a helper method to easily map different possible values
+ * to a variable to integer constants that easily identify them.
+ *
+ * A mapping array looks as follows:
+ *
+ *	git_cvar_map autocrlf_mapping[] = {
+ *		{GIT_CVAR_FALSE, NULL, GIT_AUTO_CRLF_FALSE},
+ *		{GIT_CVAR_TRUE, NULL, GIT_AUTO_CRLF_TRUE},
+ *		{GIT_CVAR_STRING, "input", GIT_AUTO_CRLF_INPUT},
+ *		{GIT_CVAR_STRING, "default", GIT_AUTO_CRLF_DEFAULT}};
+ *
+ * On any "false" value for the variable (e.g. "false", "FALSE", "no"), the
+ * mapping will store `GIT_AUTO_CRLF_FALSE` in the `out` parameter.
+ *
+ * The same thing applies for any "true" value such as "true", "yes" or "1", storing
+ * the `GIT_AUTO_CRLF_TRUE` variable.
+ *
+ * Otherwise, if the value matches the string "input" (with case insensitive comparison),
+ * the given constant will be stored in `out`, and likewise for "default".
+ *
+ * If not a single match can be made to store in `out`, an error code will be
+ * returned.
+ *
+ * @param out place to store the result of the mapping
+ * @param cfg config file to get the variables from
+ * @param name name of the config variable to lookup
+ * @param maps array of `git_cvar_map` objects specifying the possible mappings
+ * @param map_n number of mapping objects in `maps`
+ * @return 0 on success, error code otherwise
+ */
+GIT_EXTERN(int) git_config_get_mapped(
+	int *out,
+	const git_config *cfg,
+	const char *name,
+	const git_cvar_map *maps,
+	size_t map_n);
+
+/**
+ * Maps a string value to an integer constant
+ *
+ * @param out place to store the result of the parsing
+ * @param maps array of `git_cvar_map` objects specifying the possible mappings
+ * @param map_n number of mapping objects in `maps`
+ * @param value value to parse
+ */
+GIT_EXTERN(int) git_config_lookup_map_value(
+	int *out,
+	const git_cvar_map *maps,
+	size_t map_n,
+	const char *value);
+
+/**
+ * Parse a string value as a bool.
+ *
+ * Valid values for true are: 'true', 'yes', 'on', 1 or any
+ *  number different from 0
+ * Valid values for false are: 'false', 'no', 'off', 0
+ *
+ * @param out place to store the result of the parsing
+ * @param value value to parse
+ */
+GIT_EXTERN(int) git_config_parse_bool(int *out, const char *value);
+
+/**
+ * Parse a string value as an int32.
+ *
+ * An optional value suffix of 'k', 'm', or 'g' will
+ * cause the value to be multiplied by 1024, 1048576,
+ * or 1073741824 prior to output.
+ *
+ * @param out place to store the result of the parsing
+ * @param value value to parse
+ */
+GIT_EXTERN(int) git_config_parse_int32(int32_t *out, const char *value);
+
+/**
+ * Parse a string value as an int64.
+ *
+ * An optional value suffix of 'k', 'm', or 'g' will
+ * cause the value to be multiplied by 1024, 1048576,
+ * or 1073741824 prior to output.
+ *
+ * @param out place to store the result of the parsing
+ * @param value value to parse
+ */
+GIT_EXTERN(int) git_config_parse_int64(int64_t *out, const char *value);
+
+/**
+ * Parse a string value as a path.
+ *
+ * A leading '~' will be expanded to the global search path (which
+ * defaults to the user's home directory but can be overridden via
+ * `git_libgit2_opts()`.
+ *
+ * If the value does not begin with a tilde, the input will be
+ * returned.
+ *
+ * @param out placae to store the result of parsing
+ * @param value the path to evaluate
+ */
+GIT_EXTERN(int) git_config_parse_path(git_buf *out, const char *value);
+
+/**
+ * Perform an operation on each config variable in given config backend
+ * matching a regular expression.
+ *
+ * This behaviors like `git_config_foreach_match` except instead of all config
+ * entries it just enumerates through the given backend entry.
+ *
+ * @param backend where to get the variables from
+ * @param regexp regular expression to match against config names (can be NULL)
+ * @param callback the function to call on each variable
+ * @param payload the data to pass to the callback
+ */
+GIT_EXTERN(int) git_config_backend_foreach_match(
+	git_config_backend *backend,
+	const char *regexp,
+	git_config_foreach_cb callback,
+	void *payload);
+
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/cred_helpers.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/cred_helpers.h
new file mode 100755
index 0000000..1416d56
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/cred_helpers.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_cred_helpers_h__
+#define INCLUDE_git_cred_helpers_h__
+
+#include "transport.h"
+
+/**
+ * @file git2/cred_helpers.h
+ * @brief Utility functions for credential management
+ * @defgroup git_cred_helpers credential management helpers
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Payload for git_cred_stock_userpass_plaintext.
+ */
+typedef struct git_cred_userpass_payload {
+	const char *username;
+	const char *password;
+} git_cred_userpass_payload;
+
+
+/**
+ * Stock callback usable as a git_cred_acquire_cb.  This calls
+ * git_cred_userpass_plaintext_new unless the protocol has not specified
+ * `GIT_CREDTYPE_USERPASS_PLAINTEXT` as an allowed type.
+ *
+ * @param cred The newly created credential object.
+ * @param url The resource for which we are demanding a credential.
+ * @param user_from_url The username that was embedded in a "user\@host"
+ *                          remote url, or NULL if not included.
+ * @param allowed_types A bitmask stating which cred types are OK to return.
+ * @param payload The payload provided when specifying this callback.  (This is
+ *        interpreted as a `git_cred_userpass_payload*`.)
+ */
+GIT_EXTERN(int) git_cred_userpass(
+		git_cred **cred,
+		const char *url,
+		const char *user_from_url,
+		unsigned int allowed_types,
+		void *payload);
+
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/describe.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/describe.h
new file mode 100755
index 0000000..3044d91
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/describe.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_describe_h__
+#define INCLUDE_git_describe_h__
+
+#include "common.h"
+#include "types.h"
+#include "buffer.h"
+
+/**
+ * @file git2/describe.h
+ * @brief Git describing routines
+ * @defgroup git_describe Git describing routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Reference lookup strategy
+ *
+ * These behave like the --tags and --all optios to git-describe,
+ * namely they say to look for any reference in either refs/tags/ or
+ * refs/ respectively.
+ */
+typedef enum {
+	GIT_DESCRIBE_DEFAULT,
+	GIT_DESCRIBE_TAGS,
+	GIT_DESCRIBE_ALL,
+} git_describe_strategy_t;
+
+/**
+ * Describe options structure
+ *
+ * Initialize with `GIT_DESCRIBE_OPTIONS_INIT` macro to correctly set
+ * the `version` field.  E.g.
+ *
+ *		git_describe_options opts = GIT_DESCRIBE_OPTIONS_INIT;
+ */
+typedef struct git_describe_options {
+	unsigned int version;
+
+	unsigned int max_candidates_tags; /** default: 10 */
+	unsigned int describe_strategy; /** default: GIT_DESCRIBE_DEFAULT */
+	const char *pattern;
+	/**
+	 * When calculating the distance from the matching tag or
+	 * reference, only walk down the first-parent ancestry.
+	 */
+	int only_follow_first_parent;
+	/**
+	 * If no matching tag or reference is found, the describe
+	 * operation would normally fail. If this option is set, it
+	 * will instead fall back to showing the full id of the
+	 * commit.
+	 */
+	int show_commit_oid_as_fallback;
+} git_describe_options;
+
+#define GIT_DESCRIBE_DEFAULT_MAX_CANDIDATES_TAGS 10
+#define GIT_DESCRIBE_DEFAULT_ABBREVIATED_SIZE 7
+
+#define GIT_DESCRIBE_OPTIONS_VERSION 1
+#define GIT_DESCRIBE_OPTIONS_INIT { \
+	GIT_DESCRIBE_OPTIONS_VERSION, \
+	GIT_DESCRIBE_DEFAULT_MAX_CANDIDATES_TAGS, \
+}
+
+GIT_EXTERN(int) git_describe_init_options(git_describe_options *opts, unsigned int version);
+
+/**
+ * Options for formatting the describe string
+ */
+typedef struct {
+	unsigned int version;
+
+	/**
+	 * Size of the abbreviated commit id to use. This value is the
+	 * lower bound for the length of the abbreviated string. The
+	 * default is 7.
+	 */
+	unsigned int abbreviated_size;
+
+	/**
+	 * Set to use the long format even when a shorter name could be used.
+	 */
+	int always_use_long_format;
+
+	/**
+	 * If the workdir is dirty and this is set, this string will
+	 * be appended to the description string.
+	 */
+	const char *dirty_suffix;
+} git_describe_format_options;
+
+#define GIT_DESCRIBE_FORMAT_OPTIONS_VERSION 1
+#define GIT_DESCRIBE_FORMAT_OPTIONS_INIT { \
+		GIT_DESCRIBE_FORMAT_OPTIONS_VERSION,   \
+		GIT_DESCRIBE_DEFAULT_ABBREVIATED_SIZE, \
+ }
+
+GIT_EXTERN(int) git_describe_init_format_options(git_describe_format_options *opts, unsigned int version);
+
+typedef struct git_describe_result git_describe_result;
+
+/**
+ * Describe a commit
+ *
+ * Perform the describe operation on the given committish object.
+ *
+ * @param result pointer to store the result. You must free this once
+ * you're done with it.
+ * @param committish a committish to describe
+ * @param opts the lookup options
+ */
+GIT_EXTERN(int) git_describe_commit(
+	git_describe_result **result,
+	git_object *committish,
+	git_describe_options *opts);
+
+/**
+ * Describe a commit
+ *
+ * Perform the describe operation on the current commit and the
+ * worktree. After peforming describe on HEAD, a status is run and the
+ * description is considered to be dirty if there are.
+ *
+ * @param out pointer to store the result. You must free this once
+ * you're done with it.
+ * @param repo the repository in which to perform the describe
+ * @param opts the lookup options
+ */
+GIT_EXTERN(int) git_describe_workdir(
+	git_describe_result **out,
+	git_repository *repo,
+	git_describe_options *opts);
+
+/**
+ * Print the describe result to a buffer
+ *
+ * @param out The buffer to store the result
+ * @param result the result from `git_describe_commit()` or
+ * `git_describe_workdir()`.
+ * @param opts the formatting options
+ */
+GIT_EXTERN(int) git_describe_format(
+	git_buf *out,
+	const git_describe_result *result,
+	const git_describe_format_options *opts);
+
+/**
+ * Free the describe result.
+ */
+GIT_EXTERN(void) git_describe_result_free(git_describe_result *result);
+
+/** @} */
+GIT_END_DECL
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/diff.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/diff.h
new file mode 100755
index 0000000..b3ab539
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/diff.h
@@ -0,0 +1,1307 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_diff_h__
+#define INCLUDE_git_diff_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "tree.h"
+#include "refs.h"
+
+/**
+ * @file git2/diff.h
+ * @brief Git tree and file differencing routines.
+ *
+ * Overview
+ * --------
+ *
+ * Calculating diffs is generally done in two phases: building a list of
+ * diffs then traversing it.  This makes is easier to share logic across
+ * the various types of diffs (tree vs tree, workdir vs index, etc.), and
+ * also allows you to insert optional diff post-processing phases,
+ * such as rename detection, in between the steps.  When you are done with
+ * a diff object, it must be freed.
+ *
+ * Terminology
+ * -----------
+ *
+ * To understand the diff APIs, you should know the following terms:
+ *
+ * - A `diff` represents the cumulative list of differences between two
+ *   snapshots of a repository (possibly filtered by a set of file name
+ *   patterns).  This is the `git_diff` object.
+ *
+ * - A `delta` is a file pair with an old and new revision.  The old version
+ *   may be absent if the file was just created and the new version may be
+ *   absent if the file was deleted.  A diff is mostly just a list of deltas.
+ *
+ * - A `binary` file / delta is a file (or pair) for which no text diffs
+ *   should be generated.  A diff can contain delta entries that are
+ *   binary, but no diff content will be output for those files.  There is
+ *   a base heuristic for binary detection and you can further tune the
+ *   behavior with git attributes or diff flags and option settings.
+ *
+ * - A `hunk` is a span of modified lines in a delta along with some stable
+ *   surrounding context.  You can configure the amount of context and other
+ *   properties of how hunks are generated.  Each hunk also comes with a
+ *   header that described where it starts and ends in both the old and new
+ *   versions in the delta.
+ *
+ * - A `line` is a range of characters inside a hunk.  It could be a context
+ *   line (i.e. in both old and new versions), an added line (i.e. only in
+ *   the new version), or a removed line (i.e. only in the old version).
+ *   Unfortunately, we don't know anything about the encoding of data in the
+ *   file being diffed, so we cannot tell you much about the line content.
+ *   Line data will not be NUL-byte terminated, however, because it will be
+ *   just a span of bytes inside the larger file.
+ *
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Flags for diff options.  A combination of these flags can be passed
+ * in via the `flags` value in the `git_diff_options`.
+ */
+typedef enum {
+	/** Normal diff, the default */
+	GIT_DIFF_NORMAL = 0,
+
+	/*
+	 * Options controlling which files will be in the diff
+	 */
+
+	/** Reverse the sides of the diff */
+	GIT_DIFF_REVERSE = (1u << 0),
+
+	/** Include ignored files in the diff */
+	GIT_DIFF_INCLUDE_IGNORED = (1u << 1),
+
+	/** Even with GIT_DIFF_INCLUDE_IGNORED, an entire ignored directory
+	 *  will be marked with only a single entry in the diff; this flag
+	 *  adds all files under the directory as IGNORED entries, too.
+	 */
+	GIT_DIFF_RECURSE_IGNORED_DIRS = (1u << 2),
+
+	/** Include untracked files in the diff */
+	GIT_DIFF_INCLUDE_UNTRACKED = (1u << 3),
+
+	/** Even with GIT_DIFF_INCLUDE_UNTRACKED, an entire untracked
+	 *  directory will be marked with only a single entry in the diff
+	 *  (a la what core Git does in `git status`); this flag adds *all*
+	 *  files under untracked directories as UNTRACKED entries, too.
+	 */
+	GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1u << 4),
+
+	/** Include unmodified files in the diff */
+	GIT_DIFF_INCLUDE_UNMODIFIED = (1u << 5),
+
+	/** Normally, a type change between files will be converted into a
+	 *  DELETED record for the old and an ADDED record for the new; this
+	 *  options enabled the generation of TYPECHANGE delta records.
+	 */
+	GIT_DIFF_INCLUDE_TYPECHANGE = (1u << 6),
+
+	/** Even with GIT_DIFF_INCLUDE_TYPECHANGE, blob->tree changes still
+	 *  generally show as a DELETED blob.  This flag tries to correctly
+	 *  label blob->tree transitions as TYPECHANGE records with new_file's
+	 *  mode set to tree.  Note: the tree SHA will not be available.
+	 */
+	GIT_DIFF_INCLUDE_TYPECHANGE_TREES = (1u << 7),
+
+	/** Ignore file mode changes */
+	GIT_DIFF_IGNORE_FILEMODE = (1u << 8),
+
+	/** Treat all submodules as unmodified */
+	GIT_DIFF_IGNORE_SUBMODULES = (1u << 9),
+
+	/** Use case insensitive filename comparisons */
+	GIT_DIFF_IGNORE_CASE = (1u << 10),
+
+	/** May be combined with `GIT_DIFF_IGNORE_CASE` to specify that a file
+	 *  that has changed case will be returned as an add/delete pair.
+	 */
+	GIT_DIFF_INCLUDE_CASECHANGE = (1u << 11),
+
+	/** If the pathspec is set in the diff options, this flags means to
+	 *  apply it as an exact match instead of as an fnmatch pattern.
+	 */
+	GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1u << 12),
+
+	/** Disable updating of the `binary` flag in delta records.  This is
+	 *  useful when iterating over a diff if you don't need hunk and data
+	 *  callbacks and want to avoid having to load file completely.
+	 */
+	GIT_DIFF_SKIP_BINARY_CHECK = (1u << 13),
+
+	/** When diff finds an untracked directory, to match the behavior of
+	 *  core Git, it scans the contents for IGNORED and UNTRACKED files.
+	 *  If *all* contents are IGNORED, then the directory is IGNORED; if
+	 *  any contents are not IGNORED, then the directory is UNTRACKED.
+	 *  This is extra work that may not matter in many cases.  This flag
+	 *  turns off that scan and immediately labels an untracked directory
+	 *  as UNTRACKED (changing the behavior to not match core Git).
+	 */
+	GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS = (1u << 14),
+
+	/** When diff finds a file in the working directory with stat
+	 * information different from the index, but the OID ends up being the
+	 * same, write the correct stat information into the index.  Note:
+	 * without this flag, diff will always leave the index untouched.
+	 */
+	GIT_DIFF_UPDATE_INDEX = (1u << 15),
+
+	/** Include unreadable files in the diff */
+	GIT_DIFF_INCLUDE_UNREADABLE = (1u << 16),
+	
+	/** Include unreadable files in the diff */
+	GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED = (1u << 17),
+
+	/*
+	 * Options controlling how output will be generated
+	 */
+
+	/** Treat all files as text, disabling binary attributes & detection */
+	GIT_DIFF_FORCE_TEXT = (1u << 20),
+	/** Treat all files as binary, disabling text diffs */
+	GIT_DIFF_FORCE_BINARY = (1u << 21),
+
+	/** Ignore all whitespace */
+	GIT_DIFF_IGNORE_WHITESPACE = (1u << 22),
+	/** Ignore changes in amount of whitespace */
+	GIT_DIFF_IGNORE_WHITESPACE_CHANGE = (1u << 23),
+	/** Ignore whitespace at end of line */
+	GIT_DIFF_IGNORE_WHITESPACE_EOL = (1u << 24),
+
+	/** When generating patch text, include the content of untracked
+	 *  files.  This automatically turns on GIT_DIFF_INCLUDE_UNTRACKED but
+	 *  it does not turn on GIT_DIFF_RECURSE_UNTRACKED_DIRS.  Add that
+	 *  flag if you want the content of every single UNTRACKED file.
+	 */
+	GIT_DIFF_SHOW_UNTRACKED_CONTENT = (1u << 25),
+
+	/** When generating output, include the names of unmodified files if
+	 *  they are included in the git_diff.  Normally these are skipped in
+	 *  the formats that list files (e.g. name-only, name-status, raw).
+	 *  Even with this, these will not be included in patch format.
+	 */
+	GIT_DIFF_SHOW_UNMODIFIED = (1u << 26),
+
+	/** Use the "patience diff" algorithm */
+	GIT_DIFF_PATIENCE = (1u << 28),
+	/** Take extra time to find minimal diff */
+	GIT_DIFF_MINIMAL = (1 << 29),
+
+	/** Include the necessary deflate / delta information so that `git-apply`
+	 *  can apply given diff information to binary files.
+	 */
+	GIT_DIFF_SHOW_BINARY = (1 << 30),
+} git_diff_option_t;
+
+/**
+ * The diff object that contains all individual file deltas.
+ *
+ * This is an opaque structure which will be allocated by one of the diff
+ * generator functions below (such as `git_diff_tree_to_tree`).  You are
+ * responsible for releasing the object memory when done, using the
+ * `git_diff_free()` function.
+ */
+typedef struct git_diff git_diff;
+
+/**
+ * Flags for the delta object and the file objects on each side.
+ *
+ * These flags are used for both the `flags` value of the `git_diff_delta`
+ * and the flags for the `git_diff_file` objects representing the old and
+ * new sides of the delta.  Values outside of this public range should be
+ * considered reserved for internal or future use.
+ */
+typedef enum {
+	GIT_DIFF_FLAG_BINARY     = (1u << 0), /**< file(s) treated as binary data */
+	GIT_DIFF_FLAG_NOT_BINARY = (1u << 1), /**< file(s) treated as text data */
+	GIT_DIFF_FLAG_VALID_ID   = (1u << 2), /**< `id` value is known correct */
+	GIT_DIFF_FLAG_EXISTS     = (1u << 3), /**< file exists at this side of the delta */
+} git_diff_flag_t;
+
+/**
+ * What type of change is described by a git_diff_delta?
+ *
+ * `GIT_DELTA_RENAMED` and `GIT_DELTA_COPIED` will only show up if you run
+ * `git_diff_find_similar()` on the diff object.
+ *
+ * `GIT_DELTA_TYPECHANGE` only shows up given `GIT_DIFF_INCLUDE_TYPECHANGE`
+ * in the option flags (otherwise type changes will be split into ADDED /
+ * DELETED pairs).
+ */
+typedef enum {
+	GIT_DELTA_UNMODIFIED = 0,  /**< no changes */
+	GIT_DELTA_ADDED = 1,	   /**< entry does not exist in old version */
+	GIT_DELTA_DELETED = 2,	   /**< entry does not exist in new version */
+	GIT_DELTA_MODIFIED = 3,    /**< entry content changed between old and new */
+	GIT_DELTA_RENAMED = 4,     /**< entry was renamed between old and new */
+	GIT_DELTA_COPIED = 5,      /**< entry was copied from another old entry */
+	GIT_DELTA_IGNORED = 6,     /**< entry is ignored item in workdir */
+	GIT_DELTA_UNTRACKED = 7,   /**< entry is untracked item in workdir */
+	GIT_DELTA_TYPECHANGE = 8,  /**< type of entry changed between old and new */
+	GIT_DELTA_UNREADABLE = 9,  /**< entry is unreadable */
+	GIT_DELTA_CONFLICTED = 10, /**< entry in the index is conflicted */
+} git_delta_t;
+
+/**
+ * Description of one side of a delta.
+ *
+ * Although this is called a "file", it could represent a file, a symbolic
+ * link, a submodule commit id, or even a tree (although that only if you
+ * are tracking type changes or ignored/untracked directories).
+ *
+ * The `oid` is the `git_oid` of the item.  If the entry represents an
+ * absent side of a diff (e.g. the `old_file` of a `GIT_DELTA_ADDED` delta),
+ * then the oid will be zeroes.
+ *
+ * `path` is the NUL-terminated path to the entry relative to the working
+ * directory of the repository.
+ *
+ * `size` is the size of the entry in bytes.
+ *
+ * `flags` is a combination of the `git_diff_flag_t` types
+ *
+ * `mode` is, roughly, the stat() `st_mode` value for the item.  This will
+ * be restricted to one of the `git_filemode_t` values.
+ */
+typedef struct {
+	git_oid     id;
+	const char *path;
+	git_off_t   size;
+	uint32_t    flags;
+	uint16_t    mode;
+} git_diff_file;
+
+/**
+ * Description of changes to one entry.
+ *
+ * When iterating over a diff, this will be passed to most callbacks and
+ * you can use the contents to understand exactly what has changed.
+ *
+ * The `old_file` represents the "from" side of the diff and the `new_file`
+ * represents to "to" side of the diff.  What those means depend on the
+ * function that was used to generate the diff and will be documented below.
+ * You can also use the `GIT_DIFF_REVERSE` flag to flip it around.
+ *
+ * Although the two sides of the delta are named "old_file" and "new_file",
+ * they actually may correspond to entries that represent a file, a symbolic
+ * link, a submodule commit id, or even a tree (if you are tracking type
+ * changes or ignored/untracked directories).
+ *
+ * Under some circumstances, in the name of efficiency, not all fields will
+ * be filled in, but we generally try to fill in as much as possible.  One
+ * example is that the "flags" field may not have either the `BINARY` or the
+ * `NOT_BINARY` flag set to avoid examining file contents if you do not pass
+ * in hunk and/or line callbacks to the diff foreach iteration function.  It
+ * will just use the git attributes for those files.
+ *
+ * The similarity score is zero unless you call `git_diff_find_similar()`
+ * which does a similarity analysis of files in the diff.  Use that
+ * function to do rename and copy detection, and to split heavily modified
+ * files in add/delete pairs.  After that call, deltas with a status of
+ * GIT_DELTA_RENAMED or GIT_DELTA_COPIED will have a similarity score
+ * between 0 and 100 indicating how similar the old and new sides are.
+ *
+ * If you ask `git_diff_find_similar` to find heavily modified files to
+ * break, but to not *actually* break the records, then GIT_DELTA_MODIFIED
+ * records may have a non-zero similarity score if the self-similarity is
+ * below the split threshold.  To display this value like core Git, invert
+ * the score (a la `printf("M%03d", 100 - delta->similarity)`).
+ */
+typedef struct {
+	git_delta_t   status;
+	uint32_t      flags;	   /**< git_diff_flag_t values */
+	uint16_t      similarity;  /**< for RENAMED and COPIED, value 0-100 */
+	uint16_t      nfiles;	   /**< number of files in this delta */
+	git_diff_file old_file;
+	git_diff_file new_file;
+} git_diff_delta;
+
+/**
+ * Diff notification callback function.
+ *
+ * The callback will be called for each file, just before the `git_delta_t`
+ * gets inserted into the diff.
+ *
+ * When the callback:
+ * - returns < 0, the diff process will be aborted.
+ * - returns > 0, the delta will not be inserted into the diff, but the
+ *		diff process continues.
+ * - returns 0, the delta is inserted into the diff, and the diff process
+ *		continues.
+ */
+typedef int (*git_diff_notify_cb)(
+	const git_diff *diff_so_far,
+	const git_diff_delta *delta_to_add,
+	const char *matched_pathspec,
+	void *payload);
+
+/**
+ * Structure describing options about how the diff should be executed.
+ *
+ * Setting all values of the structure to zero will yield the default
+ * values.  Similarly, passing NULL for the options structure will
+ * give the defaults.  The default values are marked below.
+ *
+ * - `flags` is a combination of the `git_diff_option_t` values above
+ * - `context_lines` is the number of unchanged lines that define the
+ *    boundary of a hunk (and to display before and after)
+ * - `interhunk_lines` is the maximum number of unchanged lines between
+ *    hunk boundaries before the hunks will be merged into a one.
+ * - `old_prefix` is the virtual "directory" to prefix to old file names
+ *   in hunk headers (default "a")
+ * - `new_prefix` is the virtual "directory" to prefix to new file names
+ *   in hunk headers (default "b")
+ * - `pathspec` is an array of paths / fnmatch patterns to constrain diff
+ * - `max_size` is a file size (in bytes) above which a blob will be marked
+ *   as binary automatically; pass a negative value to disable.
+ * - `notify_cb` is an optional callback function, notifying the consumer of
+ *   which files are being examined as the diff is generated
+ * - `notify_payload` is the payload data to pass to the `notify_cb` function
+ * - `ignore_submodules` overrides the submodule ignore setting for all
+ *   submodules in the diff.
+ */
+typedef struct {
+	unsigned int version;      /**< version for the struct */
+	uint32_t flags;            /**< defaults to GIT_DIFF_NORMAL */
+
+	/* options controlling which files are in the diff */
+
+	git_submodule_ignore_t ignore_submodules; /**< submodule ignore rule */
+	git_strarray       pathspec;     /**< defaults to include all paths */
+	git_diff_notify_cb notify_cb;
+	void              *notify_payload;
+
+	/* options controlling how to diff text is generated */
+
+	uint32_t    context_lines;    /**< defaults to 3 */
+	uint32_t    interhunk_lines;  /**< defaults to 0 */
+	uint16_t    id_abbrev;       /**< default 'core.abbrev' or 7 if unset */
+	git_off_t   max_size;         /**< defaults to 512MB */
+	const char *old_prefix;       /**< defaults to "a" */
+	const char *new_prefix;       /**< defaults to "b" */
+} git_diff_options;
+
+/* The current version of the diff options structure */
+#define GIT_DIFF_OPTIONS_VERSION 1
+
+/* Stack initializer for diff options.  Alternatively use
+ * `git_diff_options_init` programmatic initialization.
+ */
+#define GIT_DIFF_OPTIONS_INIT \
+	{GIT_DIFF_OPTIONS_VERSION, 0, GIT_SUBMODULE_IGNORE_UNSPECIFIED, {NULL,0}, NULL, NULL, 3}
+
+/**
+ * Initializes a `git_diff_options` with default values. Equivalent to
+ * creating an instance with GIT_DIFF_OPTIONS_INIT.
+ *
+ * @param opts The `git_diff_options` struct to initialize
+ * @param version Version of struct; pass `GIT_DIFF_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_diff_init_options(
+	git_diff_options *opts,
+	unsigned int version);
+
+/**
+ * When iterating over a diff, callback that will be made per file.
+ *
+ * @param delta A pointer to the delta data for the file
+ * @param progress Goes from 0 to 1 over the diff
+ * @param payload User-specified pointer from foreach function
+ */
+typedef int (*git_diff_file_cb)(
+	const git_diff_delta *delta,
+	float progress,
+	void *payload);
+
+/**
+ * When producing a binary diff, the binary data returned will be
+ * either the deflated full ("literal") contents of the file, or
+ * the deflated binary delta between the two sides (whichever is
+ * smaller).
+ */
+typedef enum {
+	/** There is no binary delta. */
+	GIT_DIFF_BINARY_NONE,
+
+	/** The binary data is the literal contents of the file. */
+	GIT_DIFF_BINARY_LITERAL,
+
+	/** The binary data is the delta from one side to the other. */
+	GIT_DIFF_BINARY_DELTA,
+} git_diff_binary_t;
+
+/** The contents of one of the files in a binary diff. */
+typedef struct {
+	/** The type of binary data for this file. */
+	git_diff_binary_t type;
+
+	/** The binary data, deflated. */
+	const char *data;
+
+	/** The length of the binary data. */
+	size_t datalen;
+
+	/** The length of the binary data after inflation. */
+	size_t inflatedlen;
+} git_diff_binary_file;
+
+/** Structure describing the binary contents of a diff. */
+typedef struct {
+	git_diff_binary_file old_file; /**< The contents of the old file. */
+	git_diff_binary_file new_file; /**< The contents of the new file. */
+} git_diff_binary;
+
+/**
+* When iterating over a diff, callback that will be made for
+* binary content within the diff.
+*/
+typedef int(*git_diff_binary_cb)(
+	const git_diff_delta *delta,
+	const git_diff_binary *binary,
+	void *payload);
+
+/**
+ * Structure describing a hunk of a diff.
+ */
+typedef struct {
+	int    old_start;     /**< Starting line number in old_file */
+	int    old_lines;     /**< Number of lines in old_file */
+	int    new_start;     /**< Starting line number in new_file */
+	int    new_lines;     /**< Number of lines in new_file */
+	size_t header_len;    /**< Number of bytes in header text */
+	char   header[128];   /**< Header text, NUL-byte terminated */
+} git_diff_hunk;
+
+/**
+ * When iterating over a diff, callback that will be made per hunk.
+ */
+typedef int (*git_diff_hunk_cb)(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	void *payload);
+
+/**
+ * Line origin constants.
+ *
+ * These values describe where a line came from and will be passed to
+ * the git_diff_line_cb when iterating over a diff.  There are some
+ * special origin constants at the end that are used for the text
+ * output callbacks to demarcate lines that are actually part of
+ * the file or hunk headers.
+ */
+typedef enum {
+	/* These values will be sent to `git_diff_line_cb` along with the line */
+	GIT_DIFF_LINE_CONTEXT   = ' ',
+	GIT_DIFF_LINE_ADDITION  = '+',
+	GIT_DIFF_LINE_DELETION  = '-',
+
+	GIT_DIFF_LINE_CONTEXT_EOFNL = '=', /**< Both files have no LF at end */
+	GIT_DIFF_LINE_ADD_EOFNL = '>',     /**< Old has no LF at end, new does */
+	GIT_DIFF_LINE_DEL_EOFNL = '<',     /**< Old has LF at end, new does not */
+
+	/* The following values will only be sent to a `git_diff_line_cb` when
+	 * the content of a diff is being formatted through `git_diff_print`.
+	 */
+	GIT_DIFF_LINE_FILE_HDR  = 'F',
+	GIT_DIFF_LINE_HUNK_HDR  = 'H',
+	GIT_DIFF_LINE_BINARY    = 'B' /**< For "Binary files x and y differ" */
+} git_diff_line_t;
+
+/**
+ * Structure describing a line (or data span) of a diff.
+ */
+typedef struct {
+	char   origin;       /**< A git_diff_line_t value */
+	int    old_lineno;   /**< Line number in old file or -1 for added line */
+	int    new_lineno;   /**< Line number in new file or -1 for deleted line */
+	int    num_lines;    /**< Number of newline characters in content */
+	size_t content_len;  /**< Number of bytes of data */
+	git_off_t content_offset; /**< Offset in the original file to the content */
+	const char *content; /**< Pointer to diff text, not NUL-byte terminated */
+} git_diff_line;
+
+/**
+ * When iterating over a diff, callback that will be made per text diff
+ * line. In this context, the provided range will be NULL.
+ *
+ * When printing a diff, callback that will be made to output each line
+ * of text.  This uses some extra GIT_DIFF_LINE_... constants for output
+ * of lines of file and hunk headers.
+ */
+typedef int (*git_diff_line_cb)(
+	const git_diff_delta *delta, /**< delta that contains this data */
+	const git_diff_hunk *hunk,   /**< hunk containing this data */
+	const git_diff_line *line,   /**< line data */
+	void *payload);              /**< user reference data */
+
+/**
+ * Flags to control the behavior of diff rename/copy detection.
+ */
+typedef enum {
+	/** Obey `diff.renames`. Overridden by any other GIT_DIFF_FIND_... flag. */
+	GIT_DIFF_FIND_BY_CONFIG = 0,
+
+	/** Look for renames? (`--find-renames`) */
+	GIT_DIFF_FIND_RENAMES = (1u << 0),
+
+	/** Consider old side of MODIFIED for renames? (`--break-rewrites=N`) */
+	GIT_DIFF_FIND_RENAMES_FROM_REWRITES = (1u << 1),
+
+	/** Look for copies? (a la `--find-copies`). */
+	GIT_DIFF_FIND_COPIES = (1u << 2),
+
+	/** Consider UNMODIFIED as copy sources? (`--find-copies-harder`).
+	 *
+	 * For this to work correctly, use GIT_DIFF_INCLUDE_UNMODIFIED when
+	 * the initial `git_diff` is being generated.
+	 */
+	GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED = (1u << 3),
+
+	/** Mark significant rewrites for split (`--break-rewrites=/M`) */
+	GIT_DIFF_FIND_REWRITES = (1u << 4),
+	/** Actually split large rewrites into delete/add pairs */
+	GIT_DIFF_BREAK_REWRITES = (1u << 5),
+	/** Mark rewrites for split and break into delete/add pairs */
+	GIT_DIFF_FIND_AND_BREAK_REWRITES =
+		(GIT_DIFF_FIND_REWRITES | GIT_DIFF_BREAK_REWRITES),
+
+	/** Find renames/copies for UNTRACKED items in working directory.
+	 *
+	 * For this to work correctly, use GIT_DIFF_INCLUDE_UNTRACKED when the
+	 * initial `git_diff` is being generated (and obviously the diff must
+	 * be against the working directory for this to make sense).
+	 */
+	GIT_DIFF_FIND_FOR_UNTRACKED = (1u << 6),
+
+	/** Turn on all finding features. */
+	GIT_DIFF_FIND_ALL = (0x0ff),
+
+	/** Measure similarity ignoring leading whitespace (default) */
+	GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE = 0,
+	/** Measure similarity ignoring all whitespace */
+	GIT_DIFF_FIND_IGNORE_WHITESPACE = (1u << 12),
+	/** Measure similarity including all data */
+	GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = (1u << 13),
+	/** Measure similarity only by comparing SHAs (fast and cheap) */
+	GIT_DIFF_FIND_EXACT_MATCH_ONLY = (1u << 14),
+
+	/** Do not break rewrites unless they contribute to a rename.
+	 *
+	 * Normally, GIT_DIFF_FIND_AND_BREAK_REWRITES will measure the self-
+	 * similarity of modified files and split the ones that have changed a
+	 * lot into a DELETE / ADD pair.  Then the sides of that pair will be
+	 * considered candidates for rename and copy detection.
+	 *
+	 * If you add this flag in and the split pair is *not* used for an
+	 * actual rename or copy, then the modified record will be restored to
+	 * a regular MODIFIED record instead of being split.
+	 */
+	GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY  = (1u << 15),
+
+	/** Remove any UNMODIFIED deltas after find_similar is done.
+	 *
+	 * Using GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED to emulate the
+	 * --find-copies-harder behavior requires building a diff with the
+	 * GIT_DIFF_INCLUDE_UNMODIFIED flag.  If you do not want UNMODIFIED
+	 * records in the final result, pass this flag to have them removed.
+	 */
+	GIT_DIFF_FIND_REMOVE_UNMODIFIED = (1u << 16),
+} git_diff_find_t;
+
+/**
+ * Pluggable similarity metric
+ */
+typedef struct {
+	int (*file_signature)(
+		void **out, const git_diff_file *file,
+		const char *fullpath, void *payload);
+	int (*buffer_signature)(
+		void **out, const git_diff_file *file,
+		const char *buf, size_t buflen, void *payload);
+	void (*free_signature)(void *sig, void *payload);
+	int (*similarity)(int *score, void *siga, void *sigb, void *payload);
+	void *payload;
+} git_diff_similarity_metric;
+
+/**
+ * Control behavior of rename and copy detection
+ *
+ * These options mostly mimic parameters that can be passed to git-diff.
+ *
+ * - `rename_threshold` is the same as the -M option with a value
+ * - `copy_threshold` is the same as the -C option with a value
+ * - `rename_from_rewrite_threshold` matches the top of the -B option
+ * - `break_rewrite_threshold` matches the bottom of the -B option
+ * - `rename_limit` is the maximum number of matches to consider for
+ *   a particular file.  This is a little different from the `-l` option
+ *   to regular Git because we will still process up to this many matches
+ *   before abandoning the search.
+ *
+ * The `metric` option allows you to plug in a custom similarity metric.
+ * Set it to NULL for the default internal metric which is based on sampling
+ * hashes of ranges of data in the file.  The default metric is a pretty
+ * good similarity approximation that should work fairly well for both text
+ * and binary data, and is pretty fast with fixed memory overhead.
+ */
+typedef struct {
+	unsigned int version;
+
+	/**
+	 * Combination of git_diff_find_t values (default GIT_DIFF_FIND_BY_CONFIG).
+	 * NOTE: if you don't explicitly set this, `diff.renames` could be set
+	 * to false, resulting in `git_diff_find_similar` doing nothing.
+	 */
+	uint32_t flags;
+
+	/** Similarity to consider a file renamed (default 50) */
+	uint16_t rename_threshold;
+	/** Similarity of modified to be eligible rename source (default 50) */
+	uint16_t rename_from_rewrite_threshold;
+	/** Similarity to consider a file a copy (default 50) */
+	uint16_t copy_threshold;
+	/** Similarity to split modify into delete/add pair (default 60) */
+	uint16_t break_rewrite_threshold;
+
+	/** Maximum similarity sources to examine for a file (somewhat like
+	 *  git-diff's `-l` option or `diff.renameLimit` config) (default 200)
+	 */
+	size_t rename_limit;
+
+	/** Pluggable similarity metric; pass NULL to use internal metric */
+	git_diff_similarity_metric *metric;
+} git_diff_find_options;
+
+#define GIT_DIFF_FIND_OPTIONS_VERSION 1
+#define GIT_DIFF_FIND_OPTIONS_INIT {GIT_DIFF_FIND_OPTIONS_VERSION}
+
+/**
+ * Initializes a `git_diff_find_options` with default values. Equivalent to
+ * creating an instance with GIT_DIFF_FIND_OPTIONS_INIT.
+ *
+ * @param opts The `git_diff_find_options` struct to initialize
+ * @param version Version of struct; pass `GIT_DIFF_FIND_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_diff_find_init_options(
+	git_diff_find_options *opts,
+	unsigned int version);
+
+/** @name Diff Generator Functions
+ *
+ * These are the functions you would use to create (or destroy) a
+ * git_diff from various objects in a repository.
+ */
+/**@{*/
+
+/**
+ * Deallocate a diff.
+ *
+ * @param diff The previously created diff; cannot be used after free.
+ */
+GIT_EXTERN(void) git_diff_free(git_diff *diff);
+
+/**
+ * Create a diff with the difference between two tree objects.
+ *
+ * This is equivalent to `git diff <old-tree> <new-tree>`
+ *
+ * The first tree will be used for the "old_file" side of the delta and the
+ * second tree will be used for the "new_file" side of the delta.  You can
+ * pass NULL to indicate an empty tree, although it is an error to pass
+ * NULL for both the `old_tree` and `new_tree`.
+ *
+ * @param diff Output pointer to a git_diff pointer to be allocated.
+ * @param repo The repository containing the trees.
+ * @param old_tree A git_tree object to diff from, or NULL for empty tree.
+ * @param new_tree A git_tree object to diff to, or NULL for empty tree.
+ * @param opts Structure with options to influence diff or NULL for defaults.
+ */
+GIT_EXTERN(int) git_diff_tree_to_tree(
+	git_diff **diff,
+	git_repository *repo,
+	git_tree *old_tree,
+	git_tree *new_tree,
+	const git_diff_options *opts); /**< can be NULL for defaults */
+
+/**
+ * Create a diff between a tree and repository index.
+ *
+ * This is equivalent to `git diff --cached <treeish>` or if you pass
+ * the HEAD tree, then like `git diff --cached`.
+ *
+ * The tree you pass will be used for the "old_file" side of the delta, and
+ * the index will be used for the "new_file" side of the delta.
+ *
+ * If you pass NULL for the index, then the existing index of the `repo`
+ * will be used.  In this case, the index will be refreshed from disk
+ * (if it has changed) before the diff is generated.
+ *
+ * @param diff Output pointer to a git_diff pointer to be allocated.
+ * @param repo The repository containing the tree and index.
+ * @param old_tree A git_tree object to diff from, or NULL for empty tree.
+ * @param index The index to diff with; repo index used if NULL.
+ * @param opts Structure with options to influence diff or NULL for defaults.
+ */
+GIT_EXTERN(int) git_diff_tree_to_index(
+	git_diff **diff,
+	git_repository *repo,
+	git_tree *old_tree,
+	git_index *index,
+	const git_diff_options *opts); /**< can be NULL for defaults */
+
+/**
+ * Create a diff between the repository index and the workdir directory.
+ *
+ * This matches the `git diff` command.  See the note below on
+ * `git_diff_tree_to_workdir` for a discussion of the difference between
+ * `git diff` and `git diff HEAD` and how to emulate a `git diff <treeish>`
+ * using libgit2.
+ *
+ * The index will be used for the "old_file" side of the delta, and the
+ * working directory will be used for the "new_file" side of the delta.
+ *
+ * If you pass NULL for the index, then the existing index of the `repo`
+ * will be used.  In this case, the index will be refreshed from disk
+ * (if it has changed) before the diff is generated.
+ *
+ * @param diff Output pointer to a git_diff pointer to be allocated.
+ * @param repo The repository.
+ * @param index The index to diff from; repo index used if NULL.
+ * @param opts Structure with options to influence diff or NULL for defaults.
+ */
+GIT_EXTERN(int) git_diff_index_to_workdir(
+	git_diff **diff,
+	git_repository *repo,
+	git_index *index,
+	const git_diff_options *opts); /**< can be NULL for defaults */
+
+/**
+ * Create a diff between a tree and the working directory.
+ *
+ * The tree you provide will be used for the "old_file" side of the delta,
+ * and the working directory will be used for the "new_file" side.
+ *
+ * This is not the same as `git diff <treeish>` or `git diff-index
+ * <treeish>`.  Those commands use information from the index, whereas this
+ * function strictly returns the differences between the tree and the files
+ * in the working directory, regardless of the state of the index.  Use
+ * `git_diff_tree_to_workdir_with_index` to emulate those commands.
+ *
+ * To see difference between this and `git_diff_tree_to_workdir_with_index`,
+ * consider the example of a staged file deletion where the file has then
+ * been put back into the working dir and further modified.  The
+ * tree-to-workdir diff for that file is 'modified', but `git diff` would
+ * show status 'deleted' since there is a staged delete.
+ *
+ * @param diff A pointer to a git_diff pointer that will be allocated.
+ * @param repo The repository containing the tree.
+ * @param old_tree A git_tree object to diff from, or NULL for empty tree.
+ * @param opts Structure with options to influence diff or NULL for defaults.
+ */
+GIT_EXTERN(int) git_diff_tree_to_workdir(
+	git_diff **diff,
+	git_repository *repo,
+	git_tree *old_tree,
+	const git_diff_options *opts); /**< can be NULL for defaults */
+
+/**
+ * Create a diff between a tree and the working directory using index data
+ * to account for staged deletes, tracked files, etc.
+ *
+ * This emulates `git diff <tree>` by diffing the tree to the index and
+ * the index to the working directory and blending the results into a
+ * single diff that includes staged deleted, etc.
+ *
+ * @param diff A pointer to a git_diff pointer that will be allocated.
+ * @param repo The repository containing the tree.
+ * @param old_tree A git_tree object to diff from, or NULL for empty tree.
+ * @param opts Structure with options to influence diff or NULL for defaults.
+ */
+GIT_EXTERN(int) git_diff_tree_to_workdir_with_index(
+	git_diff **diff,
+	git_repository *repo,
+	git_tree *old_tree,
+	const git_diff_options *opts); /**< can be NULL for defaults */
+
+/**
+ * Merge one diff into another.
+ *
+ * This merges items from the "from" list into the "onto" list.  The
+ * resulting diff will have all items that appear in either list.
+ * If an item appears in both lists, then it will be "merged" to appear
+ * as if the old version was from the "onto" list and the new version
+ * is from the "from" list (with the exception that if the item has a
+ * pending DELETE in the middle, then it will show as deleted).
+ *
+ * @param onto Diff to merge into.
+ * @param from Diff to merge.
+ */
+GIT_EXTERN(int) git_diff_merge(
+	git_diff *onto,
+	const git_diff *from);
+
+/**
+ * Transform a diff marking file renames, copies, etc.
+ *
+ * This modifies a diff in place, replacing old entries that look
+ * like renames or copies with new entries reflecting those changes.
+ * This also will, if requested, break modified files into add/remove
+ * pairs if the amount of change is above a threshold.
+ *
+ * @param diff diff to run detection algorithms on
+ * @param options Control how detection should be run, NULL for defaults
+ * @return 0 on success, -1 on failure
+ */
+GIT_EXTERN(int) git_diff_find_similar(
+	git_diff *diff,
+	const git_diff_find_options *options);
+
+/**@}*/
+
+
+/** @name Diff Processor Functions
+ *
+ * These are the functions you apply to a diff to process it
+ * or read it in some way.
+ */
+/**@{*/
+
+/**
+ * Query how many diff records are there in a diff.
+ *
+ * @param diff A git_diff generated by one of the above functions
+ * @return Count of number of deltas in the list
+ */
+GIT_EXTERN(size_t) git_diff_num_deltas(const git_diff *diff);
+
+/**
+ * Query how many diff deltas are there in a diff filtered by type.
+ *
+ * This works just like `git_diff_entrycount()` with an extra parameter
+ * that is a `git_delta_t` and returns just the count of how many deltas
+ * match that particular type.
+ *
+ * @param diff A git_diff generated by one of the above functions
+ * @param type A git_delta_t value to filter the count
+ * @return Count of number of deltas matching delta_t type
+ */
+GIT_EXTERN(size_t) git_diff_num_deltas_of_type(
+	const git_diff *diff, git_delta_t type);
+
+/**
+ * Return the diff delta for an entry in the diff list.
+ *
+ * The `git_diff_delta` pointer points to internal data and you do not
+ * have to release it when you are done with it.  It will go away when
+ * the * `git_diff` (or any associated `git_patch`) goes away.
+ *
+ * Note that the flags on the delta related to whether it has binary
+ * content or not may not be set if there are no attributes set for the
+ * file and there has been no reason to load the file data at this point.
+ * For now, if you need those flags to be up to date, your only option is
+ * to either use `git_diff_foreach` or create a `git_patch`.
+ *
+ * @param diff Diff list object
+ * @param idx Index into diff list
+ * @return Pointer to git_diff_delta (or NULL if `idx` out of range)
+ */
+GIT_EXTERN(const git_diff_delta *) git_diff_get_delta(
+	const git_diff *diff, size_t idx);
+
+/**
+ * Check if deltas are sorted case sensitively or insensitively.
+ *
+ * @param diff diff to check
+ * @return 0 if case sensitive, 1 if case is ignored
+ */
+GIT_EXTERN(int) git_diff_is_sorted_icase(const git_diff *diff);
+
+/**
+ * Loop over all deltas in a diff issuing callbacks.
+ *
+ * This will iterate through all of the files described in a diff.  You
+ * should provide a file callback to learn about each file.
+ *
+ * The "hunk" and "line" callbacks are optional, and the text diff of the
+ * files will only be calculated if they are not NULL.  Of course, these
+ * callbacks will not be invoked for binary files on the diff or for
+ * files whose only changed is a file mode change.
+ *
+ * Returning a non-zero value from any of the callbacks will terminate
+ * the iteration and return the value to the user.
+ *
+ * @param diff A git_diff generated by one of the above functions.
+ * @param file_cb Callback function to make per file in the diff.
+ * @param binary_cb Optional callback to make for binary files.
+ * @param hunk_cb Optional callback to make per hunk of text diff.  This
+ *                callback is called to describe a range of lines in the
+ *                diff.  It will not be issued for binary files.
+ * @param line_cb Optional callback to make per line of diff text.  This
+ *                same callback will be made for context lines, added, and
+ *                removed lines, and even for a deleted trailing newline.
+ * @param payload Reference pointer that will be passed to your callbacks.
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_diff_foreach(
+	git_diff *diff,
+	git_diff_file_cb file_cb,
+	git_diff_binary_cb binary_cb,
+	git_diff_hunk_cb hunk_cb,
+	git_diff_line_cb line_cb,
+	void *payload);
+
+/**
+ * Look up the single character abbreviation for a delta status code.
+ *
+ * When you run `git diff --name-status` it uses single letter codes in
+ * the output such as 'A' for added, 'D' for deleted, 'M' for modified,
+ * etc.  This function converts a git_delta_t value into these letters for
+ * your own purposes.  GIT_DELTA_UNTRACKED will return a space (i.e. ' ').
+ *
+ * @param status The git_delta_t value to look up
+ * @return The single character label for that code
+ */
+GIT_EXTERN(char) git_diff_status_char(git_delta_t status);
+
+/**
+ * Possible output formats for diff data
+ */
+typedef enum {
+	GIT_DIFF_FORMAT_PATCH        = 1u, /**< full git diff */
+	GIT_DIFF_FORMAT_PATCH_HEADER = 2u, /**< just the file headers of patch */
+	GIT_DIFF_FORMAT_RAW          = 3u, /**< like git diff --raw */
+	GIT_DIFF_FORMAT_NAME_ONLY    = 4u, /**< like git diff --name-only */
+	GIT_DIFF_FORMAT_NAME_STATUS  = 5u, /**< like git diff --name-status */
+} git_diff_format_t;
+
+/**
+ * Iterate over a diff generating formatted text output.
+ *
+ * Returning a non-zero value from the callbacks will terminate the
+ * iteration and return the non-zero value to the caller.
+ *
+ * @param diff A git_diff generated by one of the above functions.
+ * @param format A git_diff_format_t value to pick the text format.
+ * @param print_cb Callback to make per line of diff text.
+ * @param payload Reference pointer that will be passed to your callback.
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_diff_print(
+	git_diff *diff,
+	git_diff_format_t format,
+	git_diff_line_cb print_cb,
+	void *payload);
+
+/**@}*/
+
+
+/*
+ * Misc
+ */
+
+/**
+ * Directly run a diff on two blobs.
+ *
+ * Compared to a file, a blob lacks some contextual information. As such,
+ * the `git_diff_file` given to the callback will have some fake data; i.e.
+ * `mode` will be 0 and `path` will be NULL.
+ *
+ * NULL is allowed for either `old_blob` or `new_blob` and will be treated
+ * as an empty blob, with the `oid` set to NULL in the `git_diff_file` data.
+ * Passing NULL for both blobs is a noop; no callbacks will be made at all.
+ *
+ * We do run a binary content check on the blob content and if either blob
+ * looks like binary data, the `git_diff_delta` binary attribute will be set
+ * to 1 and no call to the hunk_cb nor line_cb will be made (unless you pass
+ * `GIT_DIFF_FORCE_TEXT` of course).
+ *
+ * @param old_blob Blob for old side of diff, or NULL for empty blob
+ * @param old_as_path Treat old blob as if it had this filename; can be NULL
+ * @param new_blob Blob for new side of diff, or NULL for empty blob
+ * @param new_as_path Treat new blob as if it had this filename; can be NULL
+ * @param options Options for diff, or NULL for default options
+ * @param file_cb Callback for "file"; made once if there is a diff; can be NULL
+ * @param binary_cb Callback for binary files; can be NULL
+ * @param hunk_cb Callback for each hunk in diff; can be NULL
+ * @param line_cb Callback for each line in diff; can be NULL
+ * @param payload Payload passed to each callback function
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_diff_blobs(
+	const git_blob *old_blob,
+	const char *old_as_path,
+	const git_blob *new_blob,
+	const char *new_as_path,
+	const git_diff_options *options,
+	git_diff_file_cb file_cb,
+	git_diff_binary_cb binary_cb,
+	git_diff_hunk_cb hunk_cb,
+	git_diff_line_cb line_cb,
+	void *payload);
+
+/**
+ * Directly run a diff between a blob and a buffer.
+ *
+ * As with `git_diff_blobs`, comparing a blob and buffer lacks some context,
+ * so the `git_diff_file` parameters to the callbacks will be faked a la the
+ * rules for `git_diff_blobs()`.
+ *
+ * Passing NULL for `old_blob` will be treated as an empty blob (i.e. the
+ * `file_cb` will be invoked with GIT_DELTA_ADDED and the diff will be the
+ * entire content of the buffer added).  Passing NULL to the buffer will do
+ * the reverse, with GIT_DELTA_REMOVED and blob content removed.
+ *
+ * @param old_blob Blob for old side of diff, or NULL for empty blob
+ * @param old_as_path Treat old blob as if it had this filename; can be NULL
+ * @param buffer Raw data for new side of diff, or NULL for empty
+ * @param buffer_len Length of raw data for new side of diff
+ * @param buffer_as_path Treat buffer as if it had this filename; can be NULL
+ * @param options Options for diff, or NULL for default options
+ * @param file_cb Callback for "file"; made once if there is a diff; can be NULL
+ * @param binary_cb Callback for binary files; can be NULL
+ * @param hunk_cb Callback for each hunk in diff; can be NULL
+ * @param line_cb Callback for each line in diff; can be NULL
+ * @param payload Payload passed to each callback function
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_diff_blob_to_buffer(
+	const git_blob *old_blob,
+	const char *old_as_path,
+	const char *buffer,
+	size_t buffer_len,
+	const char *buffer_as_path,
+	const git_diff_options *options,
+	git_diff_file_cb file_cb,
+	git_diff_binary_cb binary_cb,
+	git_diff_hunk_cb hunk_cb,
+	git_diff_line_cb line_cb,
+	void *payload);
+
+/**
+ * Directly run a diff between two buffers.
+ *
+ * Even more than with `git_diff_blobs`, comparing two buffer lacks
+ * context, so the `git_diff_file` parameters to the callbacks will be
+ * faked a la the rules for `git_diff_blobs()`.
+ *
+ * @param old_buffer Raw data for old side of diff, or NULL for empty
+ * @param old_len Length of the raw data for old side of the diff
+ * @param old_as_path Treat old buffer as if it had this filename; can be NULL
+ * @param new_buffer Raw data for new side of diff, or NULL for empty
+ * @param new_len Length of raw data for new side of diff
+ * @param new_as_path Treat buffer as if it had this filename; can be NULL
+ * @param options Options for diff, or NULL for default options
+ * @param file_cb Callback for "file"; made once if there is a diff; can be NULL
+ * @param binary_cb Callback for binary files; can be NULL
+ * @param hunk_cb Callback for each hunk in diff; can be NULL
+ * @param line_cb Callback for each line in diff; can be NULL
+ * @param payload Payload passed to each callback function
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_diff_buffers(
+	const void *old_buffer,
+	size_t old_len,
+	const char *old_as_path,
+	const void *new_buffer,
+	size_t new_len,
+	const char *new_as_path,
+	const git_diff_options *options,
+	git_diff_file_cb file_cb,
+	git_diff_binary_cb binary_cb,
+	git_diff_hunk_cb hunk_cb,
+	git_diff_line_cb line_cb,
+	void *payload);
+
+/**
+ * This is an opaque structure which is allocated by `git_diff_get_stats`.
+ * You are responsible for releasing the object memory when done, using the
+ * `git_diff_stats_free()` function.
+ */
+typedef struct git_diff_stats git_diff_stats;
+
+/**
+ * Formatting options for diff stats
+ */
+typedef enum {
+	/** No stats*/
+	GIT_DIFF_STATS_NONE = 0,
+
+	/** Full statistics, equivalent of `--stat` */
+	GIT_DIFF_STATS_FULL = (1u << 0),
+
+	/** Short statistics, equivalent of `--shortstat` */
+	GIT_DIFF_STATS_SHORT = (1u << 1),
+
+	/** Number statistics, equivalent of `--numstat` */
+	GIT_DIFF_STATS_NUMBER = (1u << 2),
+
+	/** Extended header information such as creations, renames and mode changes, equivalent of `--summary` */
+	GIT_DIFF_STATS_INCLUDE_SUMMARY = (1u << 3),
+} git_diff_stats_format_t;
+
+/**
+ * Accumlate diff statistics for all patches.
+ *
+ * @param out Structure containg the diff statistics.
+ * @param diff A git_diff generated by one of the above functions.
+ * @return 0 on success; non-zero on error
+ */
+GIT_EXTERN(int) git_diff_get_stats(
+	git_diff_stats **out,
+	git_diff *diff);
+
+/**
+ * Get the total number of files changed in a diff
+ *
+ * @param stats A `git_diff_stats` generated by one of the above functions.
+ * @return total number of files changed in the diff
+ */
+GIT_EXTERN(size_t) git_diff_stats_files_changed(
+	const git_diff_stats *stats);
+
+/**
+ * Get the total number of insertions in a diff
+ *
+ * @param stats A `git_diff_stats` generated by one of the above functions.
+ * @return total number of insertions in the diff
+ */
+GIT_EXTERN(size_t) git_diff_stats_insertions(
+	const git_diff_stats *stats);
+
+/**
+ * Get the total number of deletions in a diff
+ *
+ * @param stats A `git_diff_stats` generated by one of the above functions.
+ * @return total number of deletions in the diff
+ */
+GIT_EXTERN(size_t) git_diff_stats_deletions(
+	const git_diff_stats *stats);
+
+/**
+ * Print diff statistics to a `git_buf`.
+ *
+ * @param out buffer to store the formatted diff statistics in.
+ * @param stats A `git_diff_stats` generated by one of the above functions.
+ * @param format Formatting option.
+ * @param width Target width for output (only affects GIT_DIFF_STATS_FULL)
+ * @return 0 on success; non-zero on error
+ */
+GIT_EXTERN(int) git_diff_stats_to_buf(
+	git_buf *out,
+	const git_diff_stats *stats,
+	git_diff_stats_format_t format,
+	size_t width);
+
+/**
+ * Deallocate a `git_diff_stats`.
+ *
+ * @param stats The previously created statistics object;
+ * cannot be used after free.
+ */
+GIT_EXTERN(void) git_diff_stats_free(git_diff_stats *stats);
+
+/**
+ * Formatting options for diff e-mail generation
+ */
+typedef enum {
+	/** Normal patch, the default */
+	GIT_DIFF_FORMAT_EMAIL_NONE = 0,
+
+	/** Don't insert "[PATCH]" in the subject header*/
+	GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER = (1 << 0),
+
+} git_diff_format_email_flags_t;
+
+/**
+ * Options for controlling the formatting of the generated e-mail.
+ */
+typedef struct {
+	unsigned int version;
+
+	git_diff_format_email_flags_t flags;
+
+	/** This patch number */
+	size_t patch_no;
+
+	/** Total number of patches in this series */
+	size_t total_patches;
+
+	/** id to use for the commit */
+	const git_oid *id;
+
+	/** Summary of the change */
+	const char *summary;
+
+	/** Author of the change */
+	const git_signature *author;
+} git_diff_format_email_options;
+
+#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION 1
+#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT {GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION, 0, 1, 1, NULL, NULL, NULL}
+
+/**
+ * Create an e-mail ready patch from a diff.
+ *
+ * @param out buffer to store the e-mail patch in
+ * @param diff containing the commit
+ * @param opts structure with options to influence content and formatting.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_diff_format_email(
+	git_buf *out,
+	git_diff *diff,
+	const git_diff_format_email_options *opts);
+
+/**
+ * Create an e-mail ready patch for a commit.
+ *
+ * Does not support creating patches for merge commits (yet).
+ *
+ * @param out buffer to store the e-mail patch in
+ * @param repo containing the commit
+ * @param commit pointer to up commit
+ * @param patch_no patch number of the commit
+ * @param total_patches total number of patches in the patch set
+ * @param flags determines the formatting of the e-mail
+ * @param diff_opts structure with options to influence diff or NULL for defaults.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_diff_commit_as_email(
+	git_buf *out,
+	git_repository *repo,
+	git_commit *commit,
+	size_t patch_no,
+	size_t total_patches,
+	git_diff_format_email_flags_t flags,
+	const git_diff_options *diff_opts);
+
+/**
+ * Initializes a `git_diff_format_email_options` with default values.
+ *
+ * Equivalent to creating an instance with GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT.
+ *
+ * @param opts The `git_diff_format_email_options` struct to initialize
+ * @param version Version of struct; pass `GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_diff_format_email_init_options(
+	git_diff_format_email_options *opts,
+	unsigned int version);
+
+GIT_END_DECL
+
+/** @} */
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/errors.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/errors.h
new file mode 100755
index 0000000..e189e55
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/errors.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_errors_h__
+#define INCLUDE_git_errors_h__
+
+#include "common.h"
+
+/**
+ * @file git2/errors.h
+ * @brief Git error handling routines and variables
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/** Generic return codes */
+typedef enum {
+	GIT_OK         =  0,		/**< No error */
+
+	GIT_ERROR      = -1,		/**< Generic error */
+	GIT_ENOTFOUND  = -3,		/**< Requested object could not be found */
+	GIT_EEXISTS    = -4,		/**< Object exists preventing operation */
+	GIT_EAMBIGUOUS = -5,		/**< More than one object matches */
+	GIT_EBUFS      = -6,		/**< Output buffer too short to hold data */
+
+	/* GIT_EUSER is a special error that is never generated by libgit2
+	 * code.  You can return it from a callback (e.g to stop an iteration)
+	 * to know that it was generated by the callback and not by libgit2.
+	 */
+	GIT_EUSER      = -7,
+
+	GIT_EBAREREPO       =  -8,	/**< Operation not allowed on bare repository */
+	GIT_EUNBORNBRANCH   =  -9,	/**< HEAD refers to branch with no commits */
+	GIT_EUNMERGED       = -10,	/**< Merge in progress prevented operation */
+	GIT_ENONFASTFORWARD = -11,	/**< Reference was not fast-forwardable */
+	GIT_EINVALIDSPEC    = -12,	/**< Name/ref spec was not in a valid format */
+	GIT_ECONFLICT       = -13,	/**< Checkout conflicts prevented operation */
+	GIT_ELOCKED         = -14,	/**< Lock file prevented operation */
+	GIT_EMODIFIED       = -15,	/**< Reference value does not match expected */
+	GIT_EAUTH           = -16,      /**< Authentication error */
+	GIT_ECERTIFICATE    = -17,      /**< Server certificate is invalid */
+	GIT_EAPPLIED        = -18,	/**< Patch/merge has already been applied */
+	GIT_EPEEL           = -19,      /**< The requested peel operation is not possible */
+	GIT_EEOF            = -20,      /**< Unexpected EOF */
+	GIT_EINVALID        = -21,      /**< Invalid operation or input */
+	GIT_EUNCOMMITTED    = -22,	/**< Uncommitted changes in index prevented operation */
+	GIT_EDIRECTORY      = -23,      /**< The operation is not valid for a directory */
+
+	GIT_PASSTHROUGH     = -30,	/**< Internal only */
+	GIT_ITEROVER        = -31,	/**< Signals end of iteration with iterator */
+} git_error_code;
+
+/**
+ * Structure to store extra details of the last error that occurred.
+ *
+ * This is kept on a per-thread basis if GIT_THREADS was defined when the
+ * library was build, otherwise one is kept globally for the library
+ */
+typedef struct {
+	char *message;
+	int klass;
+} git_error;
+
+/** Error classes */
+typedef enum {
+	GITERR_NONE = 0,
+	GITERR_NOMEMORY,
+	GITERR_OS,
+	GITERR_INVALID,
+	GITERR_REFERENCE,
+	GITERR_ZLIB,
+	GITERR_REPOSITORY,
+	GITERR_CONFIG,
+	GITERR_REGEX,
+	GITERR_ODB,
+	GITERR_INDEX,
+	GITERR_OBJECT,
+	GITERR_NET,
+	GITERR_TAG,
+	GITERR_TREE,
+	GITERR_INDEXER,
+	GITERR_SSL,
+	GITERR_SUBMODULE,
+	GITERR_THREAD,
+	GITERR_STASH,
+	GITERR_CHECKOUT,
+	GITERR_FETCHHEAD,
+	GITERR_MERGE,
+	GITERR_SSH,
+	GITERR_FILTER,
+	GITERR_REVERT,
+	GITERR_CALLBACK,
+	GITERR_CHERRYPICK,
+	GITERR_DESCRIBE,
+	GITERR_REBASE,
+	GITERR_FILESYSTEM
+} git_error_t;
+
+/**
+ * Return the last `git_error` object that was generated for the
+ * current thread or NULL if no error has occurred.
+ *
+ * @return A git_error object.
+ */
+GIT_EXTERN(const git_error *) giterr_last(void);
+
+/**
+ * Clear the last library error that occurred for this thread.
+ */
+GIT_EXTERN(void) giterr_clear(void);
+
+/**
+ * Get the last error data and clear it.
+ *
+ * This copies the last error into the given `git_error` struct
+ * and returns 0 if the copy was successful, leaving the error
+ * cleared as if `giterr_clear` had been called.
+ *
+ * If there was no existing error in the library, -1 will be returned
+ * and the contents of `cpy` will be left unmodified.
+ */
+GIT_EXTERN(int) giterr_detach(git_error *cpy);
+
+/**
+ * Set the error message string for this thread.
+ *
+ * This function is public so that custom ODB backends and the like can
+ * relay an error message through libgit2.  Most regular users of libgit2
+ * will never need to call this function -- actually, calling it in most
+ * circumstances (for example, calling from within a callback function)
+ * will just end up having the value overwritten by libgit2 internals.
+ *
+ * This error message is stored in thread-local storage and only applies
+ * to the particular thread that this libgit2 call is made from.
+ *
+ * NOTE: Passing the `error_class` as GITERR_OS has a special behavior: we
+ * attempt to append the system default error message for the last OS error
+ * that occurred and then clear the last error.  The specific implementation
+ * of looking up and clearing this last OS error will vary by platform.
+ *
+ * @param error_class One of the `git_error_t` enum above describing the
+ *                    general subsystem that is responsible for the error.
+ * @param string The formatted error message to keep
+ */
+GIT_EXTERN(void) giterr_set_str(int error_class, const char *string);
+
+/**
+ * Set the error message to a special value for memory allocation failure.
+ *
+ * The normal `giterr_set_str()` function attempts to `strdup()` the string
+ * that is passed in.  This is not a good idea when the error in question
+ * is a memory allocation failure.  That circumstance has a special setter
+ * function that sets the error string to a known and statically allocated
+ * internal value.
+ */
+GIT_EXTERN(void) giterr_set_oom(void);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/filter.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/filter.h
new file mode 100755
index 0000000..436a0f3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/filter.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_filter_h__
+#define INCLUDE_git_filter_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "buffer.h"
+
+/**
+ * @file git2/filter.h
+ * @brief Git filter APIs
+ *
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Filters are applied in one of two directions: smudging - which is
+ * exporting a file from the Git object database to the working directory,
+ * and cleaning - which is importing a file from the working directory to
+ * the Git object database.  These values control which direction of
+ * change is being applied.
+ */
+typedef enum {
+	GIT_FILTER_TO_WORKTREE = 0,
+	GIT_FILTER_SMUDGE = GIT_FILTER_TO_WORKTREE,
+	GIT_FILTER_TO_ODB = 1,
+	GIT_FILTER_CLEAN = GIT_FILTER_TO_ODB,
+} git_filter_mode_t;
+
+/**
+ * Filter option flags.
+ */
+typedef enum {
+	GIT_FILTER_DEFAULT = 0u,
+	GIT_FILTER_ALLOW_UNSAFE = (1u << 0),
+} git_filter_flag_t;
+
+/**
+ * A filter that can transform file data
+ *
+ * This represents a filter that can be used to transform or even replace
+ * file data.  Libgit2 includes one built in filter and it is possible to
+ * write your own (see git2/sys/filter.h for information on that).
+ *
+ * The two builtin filters are:
+ *
+ * * "crlf" which uses the complex rules with the "text", "eol", and
+ *   "crlf" file attributes to decide how to convert between LF and CRLF
+ *   line endings
+ * * "ident" which replaces "$Id$" in a blob with "$Id: <blob OID>$" upon
+ *   checkout and replaced "$Id: <anything>$" with "$Id$" on checkin.
+ */
+typedef struct git_filter git_filter;
+
+/**
+ * List of filters to be applied
+ *
+ * This represents a list of filters to be applied to a file / blob.  You
+ * can build the list with one call, apply it with another, and dispose it
+ * with a third.  In typical usage, there are not many occasions where a
+ * git_filter_list is needed directly since the library will generally
+ * handle conversions for you, but it can be convenient to be able to
+ * build and apply the list sometimes.
+ */
+typedef struct git_filter_list git_filter_list;
+
+/**
+ * Load the filter list for a given path.
+ *
+ * This will return 0 (success) but set the output git_filter_list to NULL
+ * if no filters are requested for the given file.
+ *
+ * @param filters Output newly created git_filter_list (or NULL)
+ * @param repo Repository object that contains `path`
+ * @param blob The blob to which the filter will be applied (if known)
+ * @param path Relative path of the file to be filtered
+ * @param mode Filtering direction (WT->ODB or ODB->WT)
+ * @param flags Combination of `git_filter_flag_t` flags
+ * @return 0 on success (which could still return NULL if no filters are
+ *         needed for the requested file), <0 on error
+ */
+GIT_EXTERN(int) git_filter_list_load(
+	git_filter_list **filters,
+	git_repository *repo,
+	git_blob *blob, /* can be NULL */
+	const char *path,
+	git_filter_mode_t mode,
+	uint32_t flags);
+
+/**
+ * Query the filter list to see if a given filter (by name) will run.
+ * The built-in filters "crlf" and "ident" can be queried, otherwise this
+ * is the name of the filter specified by the filter attribute.
+ *
+ * This will return 0 if the given filter is not in the list, or 1 if
+ * the filter will be applied.
+ *
+ * @param filters A loaded git_filter_list (or NULL)
+ * @param name The name of the filter to query
+ * @return 1 if the filter is in the list, 0 otherwise
+ */
+GIT_EXTERN(int) git_filter_list_contains(
+	git_filter_list *filters,
+	const char *name);
+
+/**
+ * Apply filter list to a data buffer.
+ *
+ * See `git2/buffer.h` for background on `git_buf` objects.
+ *
+ * If the `in` buffer holds data allocated by libgit2 (i.e. `in->asize` is
+ * not zero), then it will be overwritten when applying the filters.  If
+ * not, then it will be left untouched.
+ *
+ * If there are no filters to apply (or `filters` is NULL), then the `out`
+ * buffer will reference the `in` buffer data (with `asize` set to zero)
+ * instead of allocating data.  This keeps allocations to a minimum, but
+ * it means you have to be careful about freeing the `in` data since `out`
+ * may be pointing to it!
+ *
+ * @param out Buffer to store the result of the filtering
+ * @param filters A loaded git_filter_list (or NULL)
+ * @param in Buffer containing the data to filter
+ * @return 0 on success, an error code otherwise
+ */
+GIT_EXTERN(int) git_filter_list_apply_to_data(
+	git_buf *out,
+	git_filter_list *filters,
+	git_buf *in);
+
+/**
+ * Apply a filter list to the contents of a file on disk
+ *
+ * @param out buffer into which to store the filtered file
+ * @param filters the list of filters to apply
+ * @param repo the repository in which to perform the filtering
+ * @param path the path of the file to filter, a relative path will be
+ * taken as relative to the workdir
+ */
+GIT_EXTERN(int) git_filter_list_apply_to_file(
+	git_buf *out,
+	git_filter_list *filters,
+	git_repository *repo,
+	const char *path);
+
+/**
+ * Apply a filter list to the contents of a blob
+ *
+ * @param out buffer into which to store the filtered file
+ * @param filters the list of filters to apply
+ * @param blob the blob to filter
+ */
+GIT_EXTERN(int) git_filter_list_apply_to_blob(
+	git_buf *out,
+	git_filter_list *filters,
+	git_blob *blob);
+
+/**
+ * Apply a filter list to an arbitrary buffer as a stream
+ *
+ * @param filters the list of filters to apply
+ * @param data the buffer to filter
+ * @param target the stream into which the data will be written
+ */
+GIT_EXTERN(int) git_filter_list_stream_data(
+	git_filter_list *filters,
+	git_buf *data,
+	git_writestream *target);
+
+/**
+ * Apply a filter list to a file as a stream
+ *
+ * @param filters the list of filters to apply
+ * @param repo the repository in which to perform the filtering
+ * @param path the path of the file to filter, a relative path will be
+ * taken as relative to the workdir
+ * @param target the stream into which the data will be written
+ */
+GIT_EXTERN(int) git_filter_list_stream_file(
+	git_filter_list *filters,
+	git_repository *repo,
+	const char *path,
+	git_writestream *target);
+
+/**
+ * Apply a filter list to a blob as a stream
+ *
+ * @param filters the list of filters to apply
+ * @param blob the blob to filter
+ * @param target the stream into which the data will be written
+ */
+GIT_EXTERN(int) git_filter_list_stream_blob(
+	git_filter_list *filters,
+	git_blob *blob,
+	git_writestream *target);
+
+/**
+ * Free a git_filter_list
+ *
+ * @param filters A git_filter_list created by `git_filter_list_load`
+ */
+GIT_EXTERN(void) git_filter_list_free(git_filter_list *filters);
+
+
+GIT_END_DECL
+
+/** @} */
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/global.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/global.h
new file mode 100755
index 0000000..ce5bdf4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/global.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_global_h__
+#define INCLUDE_git_global_h__
+
+#include "common.h"
+
+GIT_BEGIN_DECL
+
+/**
+ * Init the global state
+ *
+ * This function must the called before any other libgit2 function in
+ * order to set up global state and threading.
+ *
+ * This function may be called multiple times - it will return the number
+ * of times the initialization has been called (including this one) that have
+ * not subsequently been shutdown.
+ *
+ * @return the number of initializations of the library, or an error code.
+ */
+GIT_EXTERN(int) git_libgit2_init(void);
+
+/**
+ * Shutdown the global state
+ *
+ * Clean up the global state and threading context after calling it as
+ * many times as `git_libgit2_init()` was called - it will return the
+ * number of remainining initializations that have not been shutdown
+ * (after this one).
+ * 
+ * @return the number of remaining initializations of the library, or an
+ * error code.
+ */
+GIT_EXTERN(int) git_libgit2_shutdown(void);
+
+/** @} */
+GIT_END_DECL
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/graph.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/graph.h
new file mode 100755
index 0000000..c997d8c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/graph.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_graph_h__
+#define INCLUDE_git_graph_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+
+/**
+ * @file git2/graph.h
+ * @brief Git graph traversal routines
+ * @defgroup git_revwalk Git graph traversal routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Count the number of unique commits between two commit objects
+ *
+ * There is no need for branches containing the commits to have any
+ * upstream relationship, but it helps to think of one as a branch and
+ * the other as its upstream, the `ahead` and `behind` values will be
+ * what git would report for the branches.
+ *
+ * @param ahead number of unique from commits in `upstream`
+ * @param behind number of unique from commits in `local`
+ * @param repo the repository where the commits exist
+ * @param local the commit for local
+ * @param upstream the commit for upstream
+ */
+GIT_EXTERN(int) git_graph_ahead_behind(size_t *ahead, size_t *behind, git_repository *repo, const git_oid *local, const git_oid *upstream);
+
+
+/**
+ * Determine if a commit is the descendant of another commit.
+ *
+ * @param commit a previously loaded commit.
+ * @param ancestor a potential ancestor commit.
+ * @return 1 if the given commit is a descendant of the potential ancestor,
+ * 0 if not, error code otherwise.
+ */
+GIT_EXTERN(int) git_graph_descendant_of(
+	git_repository *repo,
+	const git_oid *commit,
+	const git_oid *ancestor);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/ignore.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/ignore.h
new file mode 100755
index 0000000..d0c1877
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/ignore.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_ignore_h__
+#define INCLUDE_git_ignore_h__
+
+#include "common.h"
+#include "types.h"
+
+GIT_BEGIN_DECL
+
+/**
+ * Add ignore rules for a repository.
+ *
+ * Excludesfile rules (i.e. .gitignore rules) are generally read from
+ * .gitignore files in the repository tree or from a shared system file
+ * only if a "core.excludesfile" config value is set.  The library also
+ * keeps a set of per-repository internal ignores that can be configured
+ * in-memory and will not persist.  This function allows you to add to
+ * that internal rules list.
+ *
+ * Example usage:
+ *
+ *     error = git_ignore_add_rule(myrepo, "*.c\ndir/\nFile with space\n");
+ *
+ * This would add three rules to the ignores.
+ *
+ * @param repo The repository to add ignore rules to.
+ * @param rules Text of rules, a la the contents of a .gitignore file.
+ *              It is okay to have multiple rules in the text; if so,
+ *              each rule should be terminated with a newline.
+ * @return 0 on success
+ */
+GIT_EXTERN(int) git_ignore_add_rule(
+	git_repository *repo,
+	const char *rules);
+
+/**
+ * Clear ignore rules that were explicitly added.
+ *
+ * Resets to the default internal ignore rules.  This will not turn off
+ * rules in .gitignore files that actually exist in the filesystem.
+ *
+ * The default internal ignores ignore ".", ".." and ".git" entries.
+ *
+ * @param repo The repository to remove ignore rules from.
+ * @return 0 on success
+ */
+GIT_EXTERN(int) git_ignore_clear_internal_rules(
+	git_repository *repo);
+
+/**
+ * Test if the ignore rules apply to a given path.
+ *
+ * This function checks the ignore rules to see if they would apply to the
+ * given file.  This indicates if the file would be ignored regardless of
+ * whether the file is already in the index or committed to the repository.
+ *
+ * One way to think of this is if you were to do "git add ." on the
+ * directory containing the file, would it be added or not?
+ *
+ * @param ignored boolean returning 0 if the file is not ignored, 1 if it is
+ * @param repo a repository object
+ * @param path the file to check ignores for, relative to the repo's workdir.
+ * @return 0 if ignore rules could be processed for the file (regardless
+ *         of whether it exists or not), or an error < 0 if they could not.
+ */
+GIT_EXTERN(int) git_ignore_path_is_ignored(
+	int *ignored,
+	git_repository *repo,
+	const char *path);
+
+GIT_END_DECL
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/index.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/index.h
new file mode 100755
index 0000000..7caf3ed
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/index.h
@@ -0,0 +1,761 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_index_h__
+#define INCLUDE_git_index_h__
+
+#include "common.h"
+#include "indexer.h"
+#include "types.h"
+#include "oid.h"
+#include "strarray.h"
+
+/**
+ * @file git2/index.h
+ * @brief Git index parsing and manipulation routines
+ * @defgroup git_index Git index parsing and manipulation routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/** Time structure used in a git index entry */
+typedef struct {
+	int32_t seconds;
+	/* nsec should not be stored as time_t compatible */
+	uint32_t nanoseconds;
+} git_index_time;
+
+/**
+ * In-memory representation of a file entry in the index.
+ *
+ * This is a public structure that represents a file entry in the index.
+ * The meaning of the fields corresponds to core Git's documentation (in
+ * "Documentation/technical/index-format.txt").
+ *
+ * The `flags` field consists of a number of bit fields which can be
+ * accessed via the first set of `GIT_IDXENTRY_...` bitmasks below.  These
+ * flags are all read from and persisted to disk.
+ *
+ * The `flags_extended` field also has a number of bit fields which can be
+ * accessed via the later `GIT_IDXENTRY_...` bitmasks below.  Some of
+ * these flags are read from and written to disk, but some are set aside
+ * for in-memory only reference.
+ *
+ * Note that the time and size fields are truncated to 32 bits. This
+ * is enough to detect changes, which is enough for the index to
+ * function as a cache, but it should not be taken as an authoritative
+ * source for that data.
+ */
+typedef struct git_index_entry {
+	git_index_time ctime;
+	git_index_time mtime;
+
+	uint32_t dev;
+	uint32_t ino;
+	uint32_t mode;
+	uint32_t uid;
+	uint32_t gid;
+	uint32_t file_size;
+
+	git_oid id;
+
+	uint16_t flags;
+	uint16_t flags_extended;
+
+	const char *path;
+} git_index_entry;
+
+/**
+ * Bitmasks for on-disk fields of `git_index_entry`'s `flags`
+ *
+ * These bitmasks match the four fields in the `git_index_entry` `flags`
+ * value both in memory and on disk.  You can use them to interpret the
+ * data in the `flags`.
+ */
+#define GIT_IDXENTRY_NAMEMASK  (0x0fff)
+#define GIT_IDXENTRY_STAGEMASK (0x3000)
+#define GIT_IDXENTRY_STAGESHIFT 12
+
+/**
+ * Flags for index entries
+ */
+typedef enum {
+	GIT_IDXENTRY_EXTENDED  = (0x4000),
+	GIT_IDXENTRY_VALID     = (0x8000),
+} git_indxentry_flag_t;
+
+#define GIT_IDXENTRY_STAGE(E) \
+	(((E)->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT)
+
+#define GIT_IDXENTRY_STAGE_SET(E,S) do { \
+	(E)->flags = ((E)->flags & ~GIT_IDXENTRY_STAGEMASK) | \
+		(((S) & 0x03) << GIT_IDXENTRY_STAGESHIFT); } while (0)
+
+/**
+ * Bitmasks for on-disk fields of `git_index_entry`'s `flags_extended`
+ *
+ * In memory, the `flags_extended` fields are divided into two parts: the
+ * fields that are read from and written to disk, and other fields that
+ * in-memory only and used by libgit2.  Only the flags in
+ * `GIT_IDXENTRY_EXTENDED_FLAGS` will get saved on-disk.
+ *
+ * Thee first three bitmasks match the three fields in the
+ * `git_index_entry` `flags_extended` value that belong on disk.  You
+ * can use them to interpret the data in the `flags_extended`.
+ *
+ * The rest of the bitmasks match the other fields in the `git_index_entry`
+ * `flags_extended` value that are only used in-memory by libgit2.
+ * You can use them to interpret the data in the `flags_extended`.
+ *
+ */
+typedef enum {
+
+	GIT_IDXENTRY_INTENT_TO_ADD  =  (1 << 13),
+	GIT_IDXENTRY_SKIP_WORKTREE  =  (1 << 14),
+	/** Reserved for future extension */
+	GIT_IDXENTRY_EXTENDED2      =  (1 << 15),
+
+	GIT_IDXENTRY_EXTENDED_FLAGS = (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE),
+	GIT_IDXENTRY_UPDATE            =  (1 << 0),
+	GIT_IDXENTRY_REMOVE            =  (1 << 1),
+	GIT_IDXENTRY_UPTODATE          =  (1 << 2),
+	GIT_IDXENTRY_ADDED             =  (1 << 3),
+
+	GIT_IDXENTRY_HASHED            =  (1 << 4),
+	GIT_IDXENTRY_UNHASHED          =  (1 << 5),
+	GIT_IDXENTRY_WT_REMOVE         =  (1 << 6), /**< remove in work directory */
+	GIT_IDXENTRY_CONFLICTED        =  (1 << 7),
+
+	GIT_IDXENTRY_UNPACKED          =  (1 << 8),
+	GIT_IDXENTRY_NEW_SKIP_WORKTREE =  (1 << 9),
+} git_idxentry_extended_flag_t;
+
+/** Capabilities of system that affect index actions. */
+typedef enum {
+	GIT_INDEXCAP_IGNORE_CASE = 1,
+	GIT_INDEXCAP_NO_FILEMODE = 2,
+	GIT_INDEXCAP_NO_SYMLINKS = 4,
+	GIT_INDEXCAP_FROM_OWNER  = -1,
+} git_indexcap_t;
+
+/** Callback for APIs that add/remove/update files matching pathspec */
+typedef int (*git_index_matched_path_cb)(
+	const char *path, const char *matched_pathspec, void *payload);
+
+/** Flags for APIs that add files matching pathspec */
+typedef enum {
+	GIT_INDEX_ADD_DEFAULT = 0,
+	GIT_INDEX_ADD_FORCE = (1u << 0),
+	GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH = (1u << 1),
+	GIT_INDEX_ADD_CHECK_PATHSPEC = (1u << 2),
+} git_index_add_option_t;
+
+/**
+ * Match any index stage.
+ *
+ * Some index APIs take a stage to match; pass this value to match
+ * any entry matching the path regardless of stage.
+ */
+#define GIT_INDEX_STAGE_ANY -1
+
+/** @name Index File Functions
+ *
+ * These functions work on the index file itself.
+ */
+/**@{*/
+
+/**
+ * Create a new bare Git index object as a memory representation
+ * of the Git index file in 'index_path', without a repository
+ * to back it.
+ *
+ * Since there is no ODB or working directory behind this index,
+ * any Index methods which rely on these (e.g. index_add_bypath)
+ * will fail with the GIT_ERROR error code.
+ *
+ * If you need to access the index of an actual repository,
+ * use the `git_repository_index` wrapper.
+ *
+ * The index must be freed once it's no longer in use.
+ *
+ * @param out the pointer for the new index
+ * @param index_path the path to the index file in disk
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_open(git_index **out, const char *index_path);
+
+/**
+ * Create an in-memory index object.
+ *
+ * This index object cannot be read/written to the filesystem,
+ * but may be used to perform in-memory index operations.
+ *
+ * The index must be freed once it's no longer in use.
+ *
+ * @param out the pointer for the new index
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_new(git_index **out);
+
+/**
+ * Free an existing index object.
+ *
+ * @param index an existing index object
+ */
+GIT_EXTERN(void) git_index_free(git_index *index);
+
+/**
+ * Get the repository this index relates to
+ *
+ * @param index The index
+ * @return A pointer to the repository
+ */
+GIT_EXTERN(git_repository *) git_index_owner(const git_index *index);
+
+/**
+ * Read index capabilities flags.
+ *
+ * @param index An existing index object
+ * @return A combination of GIT_INDEXCAP values
+ */
+GIT_EXTERN(int) git_index_caps(const git_index *index);
+
+/**
+ * Set index capabilities flags.
+ *
+ * If you pass `GIT_INDEXCAP_FROM_OWNER` for the caps, then the
+ * capabilities will be read from the config of the owner object,
+ * looking at `core.ignorecase`, `core.filemode`, `core.symlinks`.
+ *
+ * @param index An existing index object
+ * @param caps A combination of GIT_INDEXCAP values
+ * @return 0 on success, -1 on failure
+ */
+GIT_EXTERN(int) git_index_set_caps(git_index *index, int caps);
+
+/**
+ * Update the contents of an existing index object in memory by reading
+ * from the hard disk.
+ *
+ * If `force` is true, this performs a "hard" read that discards in-memory
+ * changes and always reloads the on-disk index data.  If there is no
+ * on-disk version, the index will be cleared.
+ *
+ * If `force` is false, this does a "soft" read that reloads the index
+ * data from disk only if it has changed since the last time it was
+ * loaded.  Purely in-memory index data will be untouched.  Be aware: if
+ * there are changes on disk, unwritten in-memory changes are discarded.
+ *
+ * @param index an existing index object
+ * @param force if true, always reload, vs. only read if file has changed
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_read(git_index *index, int force);
+
+/**
+ * Write an existing index object from memory back to disk
+ * using an atomic file lock.
+ *
+ * @param index an existing index object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_write(git_index *index);
+
+/**
+ * Get the full path to the index file on disk.
+ *
+ * @param index an existing index object
+ * @return path to index file or NULL for in-memory index
+ */
+GIT_EXTERN(const char *) git_index_path(const git_index *index);
+
+/**
+ * Get the checksum of the index
+ *
+ * This checksum is the SHA-1 hash over the index file (except the
+ * last 20 bytes which are the checksum itself). In cases where the
+ * index does not exist on-disk, it will be zeroed out.
+ *
+ * @param index an existing index object
+ * @return a pointer to the checksum of the index
+ */
+GIT_EXTERN(const git_oid *) git_index_checksum(git_index *index);
+
+/**
+ * Read a tree into the index file with stats
+ *
+ * The current index contents will be replaced by the specified tree.
+ *
+ * @param index an existing index object
+ * @param tree tree to read
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_read_tree(git_index *index, const git_tree *tree);
+
+/**
+ * Write the index as a tree
+ *
+ * This method will scan the index and write a representation
+ * of its current state back to disk; it recursively creates
+ * tree objects for each of the subtrees stored in the index,
+ * but only returns the OID of the root tree. This is the OID
+ * that can be used e.g. to create a commit.
+ *
+ * The index instance cannot be bare, and needs to be associated
+ * to an existing repository.
+ *
+ * The index must not contain any file in conflict.
+ *
+ * @param out Pointer where to store the OID of the written tree
+ * @param index Index to write
+ * @return 0 on success, GIT_EUNMERGED when the index is not clean
+ * or an error code
+ */
+GIT_EXTERN(int) git_index_write_tree(git_oid *out, git_index *index);
+
+/**
+ * Write the index as a tree to the given repository
+ *
+ * This method will do the same as `git_index_write_tree`, but
+ * letting the user choose the repository where the tree will
+ * be written.
+ *
+ * The index must not contain any file in conflict.
+ *
+ * @param out Pointer where to store OID of the the written tree
+ * @param index Index to write
+ * @param repo Repository where to write the tree
+ * @return 0 on success, GIT_EUNMERGED when the index is not clean
+ * or an error code
+ */
+GIT_EXTERN(int) git_index_write_tree_to(git_oid *out, git_index *index, git_repository *repo);
+
+/**@}*/
+
+/** @name Raw Index Entry Functions
+ *
+ * These functions work on index entries, and allow for raw manipulation
+ * of the entries.
+ */
+/**@{*/
+
+/* Index entry manipulation */
+
+/**
+ * Get the count of entries currently in the index
+ *
+ * @param index an existing index object
+ * @return integer of count of current entries
+ */
+GIT_EXTERN(size_t) git_index_entrycount(const git_index *index);
+
+/**
+ * Clear the contents (all the entries) of an index object.
+ *
+ * This clears the index object in memory; changes must be explicitly
+ * written to disk for them to take effect persistently.
+ *
+ * @param index an existing index object
+ * @return 0 on success, error code < 0 on failure
+ */
+GIT_EXTERN(int) git_index_clear(git_index *index);
+
+/**
+ * Get a pointer to one of the entries in the index
+ *
+ * The entry is not modifiable and should not be freed.  Because the
+ * `git_index_entry` struct is a publicly defined struct, you should
+ * be able to make your own permanent copy of the data if necessary.
+ *
+ * @param index an existing index object
+ * @param n the position of the entry
+ * @return a pointer to the entry; NULL if out of bounds
+ */
+GIT_EXTERN(const git_index_entry *) git_index_get_byindex(
+	git_index *index, size_t n);
+
+/**
+ * Get a pointer to one of the entries in the index
+ *
+ * The entry is not modifiable and should not be freed.  Because the
+ * `git_index_entry` struct is a publicly defined struct, you should
+ * be able to make your own permanent copy of the data if necessary.
+ *
+ * @param index an existing index object
+ * @param path path to search
+ * @param stage stage to search
+ * @return a pointer to the entry; NULL if it was not found
+ */
+GIT_EXTERN(const git_index_entry *) git_index_get_bypath(
+	git_index *index, const char *path, int stage);
+
+/**
+ * Remove an entry from the index
+ *
+ * @param index an existing index object
+ * @param path path to search
+ * @param stage stage to search
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_remove(git_index *index, const char *path, int stage);
+
+/**
+ * Remove all entries from the index under a given directory
+ *
+ * @param index an existing index object
+ * @param dir container directory path
+ * @param stage stage to search
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_remove_directory(
+	git_index *index, const char *dir, int stage);
+
+/**
+ * Add or update an index entry from an in-memory struct
+ *
+ * If a previous index entry exists that has the same path and stage
+ * as the given 'source_entry', it will be replaced.  Otherwise, the
+ * 'source_entry' will be added.
+ *
+ * A full copy (including the 'path' string) of the given
+ * 'source_entry' will be inserted on the index.
+ *
+ * @param index an existing index object
+ * @param source_entry new entry object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_add(git_index *index, const git_index_entry *source_entry);
+
+/**
+ * Return the stage number from a git index entry
+ *
+ * This entry is calculated from the entry's flag attribute like this:
+ *
+ *    (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT
+ *
+ * @param entry The entry
+ * @return the stage number
+ */
+GIT_EXTERN(int) git_index_entry_stage(const git_index_entry *entry);
+
+/**
+ * Return whether the given index entry is a conflict (has a high stage
+ * entry).  This is simply shorthand for `git_index_entry_stage > 0`.
+ *
+ * @param entry The entry
+ * @return 1 if the entry is a conflict entry, 0 otherwise
+ */
+GIT_EXTERN(int) git_index_entry_is_conflict(const git_index_entry *entry);
+
+/**@}*/
+
+/** @name Workdir Index Entry Functions
+ *
+ * These functions work on index entries specifically in the working
+ * directory (ie, stage 0).
+ */
+/**@{*/
+
+/**
+ * Add or update an index entry from a file on disk
+ *
+ * The file `path` must be relative to the repository's
+ * working folder and must be readable.
+ *
+ * This method will fail in bare index instances.
+ *
+ * This forces the file to be added to the index, not looking
+ * at gitignore rules.  Those rules can be evaluated through
+ * the git_status APIs (in status.h) before calling this.
+ *
+ * If this file currently is the result of a merge conflict, this
+ * file will no longer be marked as conflicting.  The data about
+ * the conflict will be moved to the "resolve undo" (REUC) section.
+ *
+ * @param index an existing index object
+ * @param path filename to add
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_add_bypath(git_index *index, const char *path);
+
+/**
+ * Add or update an index entry from a buffer in memory
+ *
+ * This method will create a blob in the repository that owns the
+ * index and then add the index entry to the index.  The `path` of the
+ * entry represents the position of the blob relative to the
+ * repository's root folder.
+ *
+ * If a previous index entry exists that has the same path as the
+ * given 'entry', it will be replaced.  Otherwise, the 'entry' will be
+ * added. The `id` and the `file_size` of the 'entry' are updated with the
+ * real value of the blob.
+ *
+ * This forces the file to be added to the index, not looking
+ * at gitignore rules.  Those rules can be evaluated through
+ * the git_status APIs (in status.h) before calling this.
+ *
+ * If this file currently is the result of a merge conflict, this
+ * file will no longer be marked as conflicting.  The data about
+ * the conflict will be moved to the "resolve undo" (REUC) section.
+ *
+ * @param index an existing index object
+ * @param entry filename to add
+ * @param buffer data to be written into the blob
+ * @param len length of the data
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_add_frombuffer(
+	git_index *index,
+	const git_index_entry *entry,
+	const void *buffer, size_t len);
+
+/**
+ * Remove an index entry corresponding to a file on disk
+ *
+ * The file `path` must be relative to the repository's
+ * working folder.  It may exist.
+ *
+ * If this file currently is the result of a merge conflict, this
+ * file will no longer be marked as conflicting.  The data about
+ * the conflict will be moved to the "resolve undo" (REUC) section.
+ *
+ * @param index an existing index object
+ * @param path filename to remove
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_remove_bypath(git_index *index, const char *path);
+
+/**
+ * Add or update index entries matching files in the working directory.
+ *
+ * This method will fail in bare index instances.
+ *
+ * The `pathspec` is a list of file names or shell glob patterns that will
+ * matched against files in the repository's working directory.  Each file
+ * that matches will be added to the index (either updating an existing
+ * entry or adding a new entry).  You can disable glob expansion and force
+ * exact matching with the `GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH` flag.
+ *
+ * Files that are ignored will be skipped (unlike `git_index_add_bypath`).
+ * If a file is already tracked in the index, then it *will* be updated
+ * even if it is ignored.  Pass the `GIT_INDEX_ADD_FORCE` flag to
+ * skip the checking of ignore rules.
+ *
+ * To emulate `git add -A` and generate an error if the pathspec contains
+ * the exact path of an ignored file (when not using FORCE), add the
+ * `GIT_INDEX_ADD_CHECK_PATHSPEC` flag.  This checks that each entry
+ * in the `pathspec` that is an exact match to a filename on disk is
+ * either not ignored or already in the index.  If this check fails, the
+ * function will return GIT_EINVALIDSPEC.
+ *
+ * To emulate `git add -A` with the "dry-run" option, just use a callback
+ * function that always returns a positive value.  See below for details.
+ *
+ * If any files are currently the result of a merge conflict, those files
+ * will no longer be marked as conflicting.  The data about the conflicts
+ * will be moved to the "resolve undo" (REUC) section.
+ *
+ * If you provide a callback function, it will be invoked on each matching
+ * item in the working directory immediately *before* it is added to /
+ * updated in the index.  Returning zero will add the item to the index,
+ * greater than zero will skip the item, and less than zero will abort the
+ * scan and return that value to the caller.
+ *
+ * @param index an existing index object
+ * @param pathspec array of path patterns
+ * @param flags combination of git_index_add_option_t flags
+ * @param callback notification callback for each added/updated path (also
+ *                 gets index of matching pathspec entry); can be NULL;
+ *                 return 0 to add, >0 to skip, <0 to abort scan.
+ * @param payload payload passed through to callback function
+ * @return 0 on success, negative callback return value, or error code
+ */
+GIT_EXTERN(int) git_index_add_all(
+	git_index *index,
+	const git_strarray *pathspec,
+	unsigned int flags,
+	git_index_matched_path_cb callback,
+	void *payload);
+
+/**
+ * Remove all matching index entries.
+ *
+ * If you provide a callback function, it will be invoked on each matching
+ * item in the index immediately *before* it is removed.  Return 0 to
+ * remove the item, > 0 to skip the item, and < 0 to abort the scan.
+ *
+ * @param index An existing index object
+ * @param pathspec array of path patterns
+ * @param callback notification callback for each removed path (also
+ *                 gets index of matching pathspec entry); can be NULL;
+ *                 return 0 to add, >0 to skip, <0 to abort scan.
+ * @param payload payload passed through to callback function
+ * @return 0 on success, negative callback return value, or error code
+ */
+GIT_EXTERN(int) git_index_remove_all(
+	git_index *index,
+	const git_strarray *pathspec,
+	git_index_matched_path_cb callback,
+	void *payload);
+
+/**
+ * Update all index entries to match the working directory
+ *
+ * This method will fail in bare index instances.
+ *
+ * This scans the existing index entries and synchronizes them with the
+ * working directory, deleting them if the corresponding working directory
+ * file no longer exists otherwise updating the information (including
+ * adding the latest version of file to the ODB if needed).
+ *
+ * If you provide a callback function, it will be invoked on each matching
+ * item in the index immediately *before* it is updated (either refreshed
+ * or removed depending on working directory state).  Return 0 to proceed
+ * with updating the item, > 0 to skip the item, and < 0 to abort the scan.
+ *
+ * @param index An existing index object
+ * @param pathspec array of path patterns
+ * @param callback notification callback for each updated path (also
+ *                 gets index of matching pathspec entry); can be NULL;
+ *                 return 0 to add, >0 to skip, <0 to abort scan.
+ * @param payload payload passed through to callback function
+ * @return 0 on success, negative callback return value, or error code
+ */
+GIT_EXTERN(int) git_index_update_all(
+	git_index *index,
+	const git_strarray *pathspec,
+	git_index_matched_path_cb callback,
+	void *payload);
+
+/**
+ * Find the first position of any entries which point to given
+ * path in the Git index.
+ *
+ * @param at_pos the address to which the position of the index entry is written (optional)
+ * @param index an existing index object
+ * @param path path to search
+ * @return a zero-based position in the index if found; GIT_ENOTFOUND otherwise
+ */
+GIT_EXTERN(int) git_index_find(size_t *at_pos, git_index *index, const char *path);
+
+/**@}*/
+
+/** @name Conflict Index Entry Functions
+ *
+ * These functions work on conflict index entries specifically (ie, stages 1-3)
+ */
+/**@{*/
+
+/**
+ * Add or update index entries to represent a conflict.  Any staged
+ * entries that exist at the given paths will be removed.
+ *
+ * The entries are the entries from the tree included in the merge.  Any
+ * entry may be null to indicate that that file was not present in the
+ * trees during the merge.  For example, ancestor_entry may be NULL to
+ * indicate that a file was added in both branches and must be resolved.
+ *
+ * @param index an existing index object
+ * @param ancestor_entry the entry data for the ancestor of the conflict
+ * @param our_entry the entry data for our side of the merge conflict
+ * @param their_entry the entry data for their side of the merge conflict
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_conflict_add(
+	git_index *index,
+	const git_index_entry *ancestor_entry,
+	const git_index_entry *our_entry,
+	const git_index_entry *their_entry);
+
+/**
+ * Get the index entries that represent a conflict of a single file.
+ *
+ * The entries are not modifiable and should not be freed.  Because the
+ * `git_index_entry` struct is a publicly defined struct, you should
+ * be able to make your own permanent copy of the data if necessary.
+ *
+ * @param ancestor_out Pointer to store the ancestor entry
+ * @param our_out Pointer to store the our entry
+ * @param their_out Pointer to store the their entry
+ * @param index an existing index object
+ * @param path path to search
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_conflict_get(
+	const git_index_entry **ancestor_out,
+	const git_index_entry **our_out,
+	const git_index_entry **their_out,
+	git_index *index,
+	const char *path);
+
+/**
+ * Removes the index entries that represent a conflict of a single file.
+ *
+ * @param index an existing index object
+ * @param path path to remove conflicts for
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_conflict_remove(git_index *index, const char *path);
+
+/**
+ * Remove all conflicts in the index (entries with a stage greater than 0).
+ *
+ * @param index an existing index object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_conflict_cleanup(git_index *index);
+
+/**
+ * Determine if the index contains entries representing file conflicts.
+ *
+ * @return 1 if at least one conflict is found, 0 otherwise.
+ */
+GIT_EXTERN(int) git_index_has_conflicts(const git_index *index);
+
+/**
+ * Create an iterator for the conflicts in the index.
+ *
+ * The index must not be modified while iterating; the results are undefined.
+ *
+ * @param iterator_out The newly created conflict iterator
+ * @param index The index to scan
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_conflict_iterator_new(
+	git_index_conflict_iterator **iterator_out,
+	git_index *index);
+
+/**
+ * Returns the current conflict (ancestor, ours and theirs entry) and
+ * advance the iterator internally to the next value.
+ *
+ * @param ancestor_out Pointer to store the ancestor side of the conflict
+ * @param our_out Pointer to store our side of the conflict
+ * @param their_out Pointer to store their side of the conflict
+ * @return 0 (no error), GIT_ITEROVER (iteration is done) or an error code
+ *         (negative value)
+ */
+GIT_EXTERN(int) git_index_conflict_next(
+	const git_index_entry **ancestor_out,
+	const git_index_entry **our_out,
+	const git_index_entry **their_out,
+	git_index_conflict_iterator *iterator);
+
+/**
+ * Frees a `git_index_conflict_iterator`.
+ *
+ * @param iterator pointer to the iterator
+ */
+GIT_EXTERN(void) git_index_conflict_iterator_free(
+	git_index_conflict_iterator *iterator);
+
+/**@}*/
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/indexer.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/indexer.h
new file mode 100755
index 0000000..d2d315e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/indexer.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef _INCLUDE_git_indexer_h__
+#define _INCLUDE_git_indexer_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+
+GIT_BEGIN_DECL
+
+typedef struct git_indexer git_indexer;
+
+/**
+ * Create a new indexer instance
+ *
+ * @param out where to store the indexer instance
+ * @param path to the directory where the packfile should be stored
+ * @param mode permissions to use creating packfile or 0 for defaults
+ * @param odb object database from which to read base objects when
+ * fixing thin packs. Pass NULL if no thin pack is expected (an error
+ * will be returned if there are bases missing)
+ * @param progress_cb function to call with progress information
+ * @param progress_cb_payload payload for the progress callback
+ */
+GIT_EXTERN(int) git_indexer_new(
+		git_indexer **out,
+		const char *path,
+		unsigned int mode,
+		git_odb *odb,
+		git_transfer_progress_cb progress_cb,
+		void *progress_cb_payload);
+
+/**
+ * Add data to the indexer
+ *
+ * @param idx the indexer
+ * @param data the data to add
+ * @param size the size of the data in bytes
+ * @param stats stat storage
+ */
+GIT_EXTERN(int) git_indexer_append(git_indexer *idx, const void *data, size_t size, git_transfer_progress *stats);
+
+/**
+ * Finalize the pack and index
+ *
+ * Resolve any pending deltas and write out the index file
+ *
+ * @param idx the indexer
+ */
+GIT_EXTERN(int) git_indexer_commit(git_indexer *idx, git_transfer_progress *stats);
+
+/**
+ * Get the packfile's hash
+ *
+ * A packfile's name is derived from the sorted hashing of all object
+ * names. This is only correct after the index has been finalized.
+ *
+ * @param idx the indexer instance
+ */
+GIT_EXTERN(const git_oid *) git_indexer_hash(const git_indexer *idx);
+
+/**
+ * Free the indexer and its resources
+ *
+ * @param idx the indexer to free
+ */
+GIT_EXTERN(void) git_indexer_free(git_indexer *idx);
+
+GIT_END_DECL
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/inttypes.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/inttypes.h
new file mode 100755
index 0000000..17364c7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/inttypes.h
@@ -0,0 +1,309 @@
+// ISO C9x  compliant inttypes.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+//  Copyright (c) 2006 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+//
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+//
+//   3. The name of the author may be used to endorse or promote products
+//      derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_INTTYPES_H_ // [
+#define _MSC_INTTYPES_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#if _MSC_VER >= 1600
+#include <stdint.h>
+#else
+#include "stdint.h"
+#endif
+
+// 7.8 Format conversion of integer types
+
+typedef struct {
+   intmax_t quot;
+   intmax_t rem;
+} imaxdiv_t;
+
+// 7.8.1 Macros for format specifiers
+
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [   See footnote 185 at page 198
+
+// The fprintf macros for signed integers are:
+#define PRId8       "d"
+#define PRIi8       "i"
+#define PRIdLEAST8  "d"
+#define PRIiLEAST8  "i"
+#define PRIdFAST8   "d"
+#define PRIiFAST8   "i"
+
+#define PRId16       "hd"
+#define PRIi16       "hi"
+#define PRIdLEAST16  "hd"
+#define PRIiLEAST16  "hi"
+#define PRIdFAST16   "hd"
+#define PRIiFAST16   "hi"
+
+#define PRId32       "I32d"
+#define PRIi32       "I32i"
+#define PRIdLEAST32  "I32d"
+#define PRIiLEAST32  "I32i"
+#define PRIdFAST32   "I32d"
+#define PRIiFAST32   "I32i"
+
+#define PRId64       "I64d"
+#define PRIi64       "I64i"
+#define PRIdLEAST64  "I64d"
+#define PRIiLEAST64  "I64i"
+#define PRIdFAST64   "I64d"
+#define PRIiFAST64   "I64i"
+
+#define PRIdMAX     "I64d"
+#define PRIiMAX     "I64i"
+
+#define PRIdPTR     "Id"
+#define PRIiPTR     "Ii"
+
+// The fprintf macros for unsigned integers are:
+#define PRIo8       "o"
+#define PRIu8       "u"
+#define PRIx8       "x"
+#define PRIX8       "X"
+#define PRIoLEAST8  "o"
+#define PRIuLEAST8  "u"
+#define PRIxLEAST8  "x"
+#define PRIXLEAST8  "X"
+#define PRIoFAST8   "o"
+#define PRIuFAST8   "u"
+#define PRIxFAST8   "x"
+#define PRIXFAST8   "X"
+
+#define PRIo16       "ho"
+#define PRIu16       "hu"
+#define PRIx16       "hx"
+#define PRIX16       "hX"
+#define PRIoLEAST16  "ho"
+#define PRIuLEAST16  "hu"
+#define PRIxLEAST16  "hx"
+#define PRIXLEAST16  "hX"
+#define PRIoFAST16   "ho"
+#define PRIuFAST16   "hu"
+#define PRIxFAST16   "hx"
+#define PRIXFAST16   "hX"
+
+#define PRIo32       "I32o"
+#define PRIu32       "I32u"
+#define PRIx32       "I32x"
+#define PRIX32       "I32X"
+#define PRIoLEAST32  "I32o"
+#define PRIuLEAST32  "I32u"
+#define PRIxLEAST32  "I32x"
+#define PRIXLEAST32  "I32X"
+#define PRIoFAST32   "I32o"
+#define PRIuFAST32   "I32u"
+#define PRIxFAST32   "I32x"
+#define PRIXFAST32   "I32X"
+
+#define PRIo64       "I64o"
+#define PRIu64       "I64u"
+#define PRIx64       "I64x"
+#define PRIX64       "I64X"
+#define PRIoLEAST64  "I64o"
+#define PRIuLEAST64  "I64u"
+#define PRIxLEAST64  "I64x"
+#define PRIXLEAST64  "I64X"
+#define PRIoFAST64   "I64o"
+#define PRIuFAST64   "I64u"
+#define PRIxFAST64   "I64x"
+#define PRIXFAST64   "I64X"
+
+#define PRIoMAX     "I64o"
+#define PRIuMAX     "I64u"
+#define PRIxMAX     "I64x"
+#define PRIXMAX     "I64X"
+
+#define PRIoPTR     "Io"
+#define PRIuPTR     "Iu"
+#define PRIxPTR     "Ix"
+#define PRIXPTR     "IX"
+
+// The fscanf macros for signed integers are:
+#define SCNd8       "d"
+#define SCNi8       "i"
+#define SCNdLEAST8  "d"
+#define SCNiLEAST8  "i"
+#define SCNdFAST8   "d"
+#define SCNiFAST8   "i"
+
+#define SCNd16       "hd"
+#define SCNi16       "hi"
+#define SCNdLEAST16  "hd"
+#define SCNiLEAST16  "hi"
+#define SCNdFAST16   "hd"
+#define SCNiFAST16   "hi"
+
+#define SCNd32       "ld"
+#define SCNi32       "li"
+#define SCNdLEAST32  "ld"
+#define SCNiLEAST32  "li"
+#define SCNdFAST32   "ld"
+#define SCNiFAST32   "li"
+
+#define SCNd64       "I64d"
+#define SCNi64       "I64i"
+#define SCNdLEAST64  "I64d"
+#define SCNiLEAST64  "I64i"
+#define SCNdFAST64   "I64d"
+#define SCNiFAST64   "I64i"
+
+#define SCNdMAX     "I64d"
+#define SCNiMAX     "I64i"
+
+#ifdef _WIN64 // [
+#  define SCNdPTR     "I64d"
+#  define SCNiPTR     "I64i"
+#else  // _WIN64 ][
+#  define SCNdPTR     "ld"
+#  define SCNiPTR     "li"
+#endif  // _WIN64 ]
+
+// The fscanf macros for unsigned integers are:
+#define SCNo8       "o"
+#define SCNu8       "u"
+#define SCNx8       "x"
+#define SCNX8       "X"
+#define SCNoLEAST8  "o"
+#define SCNuLEAST8  "u"
+#define SCNxLEAST8  "x"
+#define SCNXLEAST8  "X"
+#define SCNoFAST8   "o"
+#define SCNuFAST8   "u"
+#define SCNxFAST8   "x"
+#define SCNXFAST8   "X"
+
+#define SCNo16       "ho"
+#define SCNu16       "hu"
+#define SCNx16       "hx"
+#define SCNX16       "hX"
+#define SCNoLEAST16  "ho"
+#define SCNuLEAST16  "hu"
+#define SCNxLEAST16  "hx"
+#define SCNXLEAST16  "hX"
+#define SCNoFAST16   "ho"
+#define SCNuFAST16   "hu"
+#define SCNxFAST16   "hx"
+#define SCNXFAST16   "hX"
+
+#define SCNo32       "lo"
+#define SCNu32       "lu"
+#define SCNx32       "lx"
+#define SCNX32       "lX"
+#define SCNoLEAST32  "lo"
+#define SCNuLEAST32  "lu"
+#define SCNxLEAST32  "lx"
+#define SCNXLEAST32  "lX"
+#define SCNoFAST32   "lo"
+#define SCNuFAST32   "lu"
+#define SCNxFAST32   "lx"
+#define SCNXFAST32   "lX"
+
+#define SCNo64       "I64o"
+#define SCNu64       "I64u"
+#define SCNx64       "I64x"
+#define SCNX64       "I64X"
+#define SCNoLEAST64  "I64o"
+#define SCNuLEAST64  "I64u"
+#define SCNxLEAST64  "I64x"
+#define SCNXLEAST64  "I64X"
+#define SCNoFAST64   "I64o"
+#define SCNuFAST64   "I64u"
+#define SCNxFAST64   "I64x"
+#define SCNXFAST64   "I64X"
+
+#define SCNoMAX     "I64o"
+#define SCNuMAX     "I64u"
+#define SCNxMAX     "I64x"
+#define SCNXMAX     "I64X"
+
+#ifdef _WIN64 // [
+#  define SCNoPTR     "I64o"
+#  define SCNuPTR     "I64u"
+#  define SCNxPTR     "I64x"
+#  define SCNXPTR     "I64X"
+#else  // _WIN64 ][
+#  define SCNoPTR     "lo"
+#  define SCNuPTR     "lu"
+#  define SCNxPTR     "lx"
+#  define SCNXPTR     "lX"
+#endif  // _WIN64 ]
+
+#endif // __STDC_FORMAT_MACROS ]
+
+// 7.8.2 Functions for greatest-width integer types
+
+// 7.8.2.1 The imaxabs function
+#define imaxabs _abs64
+
+// 7.8.2.2 The imaxdiv function
+
+// This is modified version of div() function from Microsoft's div.c found
+// in %MSVC.NET%\crt\src\div.c
+#ifdef STATIC_IMAXDIV // [
+static
+#else // STATIC_IMAXDIV ][
+_inline
+#endif // STATIC_IMAXDIV ]
+imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
+{
+	imaxdiv_t result;
+
+	result.quot = numer / denom;
+	result.rem = numer % denom;
+
+	if (numer < 0 && result.rem > 0) {
+		// did division wrong; must fix up
+		++result.quot;
+		result.rem -= denom;
+	}
+
+	return result;
+}
+
+// 7.8.2.3 The strtoimax and strtoumax functions
+#define strtoimax _strtoi64
+#define strtoumax _strtoui64
+
+// 7.8.2.4 The wcstoimax and wcstoumax functions
+#define wcstoimax _wcstoi64
+#define wcstoumax _wcstoui64
+
+
+#endif // _MSC_INTTYPES_H_ ]
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/merge.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/merge.h
new file mode 100755
index 0000000..5fef452
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/merge.h
@@ -0,0 +1,551 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_merge_h__
+#define INCLUDE_git_merge_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "oidarray.h"
+#include "checkout.h"
+#include "index.h"
+#include "annotated_commit.h"
+
+/**
+ * @file git2/merge.h
+ * @brief Git merge routines
+ * @defgroup git_merge Git merge routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * The file inputs to `git_merge_file`.  Callers should populate the
+ * `git_merge_file_input` structure with descriptions of the files in
+ * each side of the conflict for use in producing the merge file.
+ */
+typedef struct {
+	unsigned int version;
+
+	/** Pointer to the contents of the file. */
+	const char *ptr;
+
+	/** Size of the contents pointed to in `ptr`. */
+	size_t size;
+
+	/** File name of the conflicted file, or `NULL` to not merge the path. */
+	const char *path;
+
+	/** File mode of the conflicted file, or `0` to not merge the mode. */
+	unsigned int mode;
+} git_merge_file_input;
+
+#define GIT_MERGE_FILE_INPUT_VERSION 1
+#define GIT_MERGE_FILE_INPUT_INIT {GIT_MERGE_FILE_INPUT_VERSION}
+
+/**
+ * Initializes a `git_merge_file_input` with default values. Equivalent to
+ * creating an instance with GIT_MERGE_FILE_INPUT_INIT.
+ *
+ * @param opts the `git_merge_file_input` instance to initialize.
+ * @param version the version of the struct; you should pass
+ *        `GIT_MERGE_FILE_INPUT_VERSION` here.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_file_init_input(
+	git_merge_file_input *opts,
+	unsigned int version);
+
+/**
+ * Flags for `git_merge_tree` options.  A combination of these flags can be
+ * passed in via the `tree_flags` value in the `git_merge_options`.
+ */
+typedef enum {
+	/**
+	 * Detect renames that occur between the common ancestor and the "ours"
+	 * side or the common ancestor and the "theirs" side.  This will enable
+	 * the ability to merge between a modified and renamed file.
+	 */
+	GIT_MERGE_TREE_FIND_RENAMES = (1 << 0),
+} git_merge_tree_flag_t;
+
+/**
+ * Merge file favor options for `git_merge_options` instruct the file-level
+ * merging functionality how to deal with conflicting regions of the files.
+ */
+typedef enum {
+	/**
+	 * When a region of a file is changed in both branches, a conflict
+	 * will be recorded in the index so that `git_checkout` can produce
+	 * a merge file with conflict markers in the working directory.
+	 * This is the default.
+	 */
+	GIT_MERGE_FILE_FAVOR_NORMAL = 0,
+
+	/**
+	 * When a region of a file is changed in both branches, the file
+	 * created in the index will contain the "ours" side of any conflicting
+	 * region.  The index will not record a conflict.
+	 */
+	GIT_MERGE_FILE_FAVOR_OURS = 1,
+
+	/**
+	 * When a region of a file is changed in both branches, the file
+	 * created in the index will contain the "theirs" side of any conflicting
+	 * region.  The index will not record a conflict.
+	 */
+	GIT_MERGE_FILE_FAVOR_THEIRS = 2,
+
+	/**
+	 * When a region of a file is changed in both branches, the file
+	 * created in the index will contain each unique line from each side,
+	 * which has the result of combining both files.  The index will not
+	 * record a conflict.
+	 */
+	GIT_MERGE_FILE_FAVOR_UNION = 3,
+} git_merge_file_favor_t;
+
+/**
+ * File merging flags
+ */
+typedef enum {
+	/** Defaults */
+	GIT_MERGE_FILE_DEFAULT = 0,
+
+	/** Create standard conflicted merge files */
+	GIT_MERGE_FILE_STYLE_MERGE = (1 << 0),
+
+	/** Create diff3-style files */
+	GIT_MERGE_FILE_STYLE_DIFF3 = (1 << 1),
+
+	/** Condense non-alphanumeric regions for simplified diff file */
+	GIT_MERGE_FILE_SIMPLIFY_ALNUM = (1 << 2),
+
+	/** Ignore all whitespace */
+	GIT_MERGE_FILE_IGNORE_WHITESPACE = (1 << 3),
+
+	/** Ignore changes in amount of whitespace */
+	GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE = (1 << 4),
+
+	/** Ignore whitespace at end of line */
+	GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL = (1 << 5),
+
+	/** Use the "patience diff" algorithm */
+	GIT_MERGE_FILE_DIFF_PATIENCE = (1 << 6),
+
+	/** Take extra time to find minimal diff */
+	GIT_MERGE_FILE_DIFF_MINIMAL = (1 << 7),
+} git_merge_file_flags_t;
+
+/**
+ * Options for merging a file
+ */
+typedef struct {
+	unsigned int version;
+
+	/**
+	 * Label for the ancestor file side of the conflict which will be prepended
+	 * to labels in diff3-format merge files.
+	 */
+	const char *ancestor_label;
+
+	/**
+	 * Label for our file side of the conflict which will be prepended
+	 * to labels in merge files.
+	 */
+	const char *our_label;
+
+	/**
+	 * Label for their file side of the conflict which will be prepended
+	 * to labels in merge files.
+	 */
+	const char *their_label;
+
+	/** The file to favor in region conflicts. */
+	git_merge_file_favor_t favor;
+
+	/** see `git_merge_file_flags_t` above */
+	unsigned int flags;
+} git_merge_file_options;
+
+#define GIT_MERGE_FILE_OPTIONS_VERSION 1
+#define GIT_MERGE_FILE_OPTIONS_INIT {GIT_MERGE_FILE_OPTIONS_VERSION}
+
+/**
+ * Initializes a `git_merge_file_options` with default values. Equivalent to
+ * creating an instance with GIT_MERGE_FILE_OPTIONS_INIT.
+ *
+ * @param opts the `git_merge_file_options` instance to initialize.
+ * @param version the version of the struct; you should pass
+ *        `GIT_MERGE_FILE_OPTIONS_VERSION` here.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_file_init_options(
+	git_merge_file_options *opts,
+	unsigned int version);
+
+/**
+ * Information about file-level merging
+ */
+typedef struct {
+	/**
+	 * True if the output was automerged, false if the output contains
+	 * conflict markers.
+	 */
+	unsigned int automergeable;
+
+	/**
+	 * The path that the resultant merge file should use, or NULL if a
+	 * filename conflict would occur.
+	 */
+	const char *path;
+
+	/** The mode that the resultant merge file should use.  */
+	unsigned int mode;
+
+	/** The contents of the merge. */
+	const char *ptr;
+
+	/** The length of the merge contents. */
+	size_t len;
+} git_merge_file_result;
+
+/**
+ * Merging options
+ */
+typedef struct {
+	unsigned int version;
+	git_merge_tree_flag_t tree_flags;
+
+	/**
+	 * Similarity to consider a file renamed (default 50).  If
+	 * `GIT_MERGE_TREE_FIND_RENAMES` is enabled, added files will be compared
+	 * with deleted files to determine their similarity.  Files that are
+	 * more similar than the rename threshold (percentage-wise) will be
+	 * treated as a rename.
+	 */
+	unsigned int rename_threshold;
+
+	/**
+	 * Maximum similarity sources to examine for renames (default 200).
+	 * If the number of rename candidates (add / delete pairs) is greater
+	 * than this value, inexact rename detection is aborted.
+	 *
+	 * This setting overrides the `merge.renameLimit` configuration value.
+	 */
+	unsigned int target_limit;
+
+	/** Pluggable similarity metric; pass NULL to use internal metric */
+	git_diff_similarity_metric *metric;
+
+	/** Flags for handling conflicting content. */
+	git_merge_file_favor_t file_favor;
+
+	/** see `git_merge_file_flags_t` above */
+	unsigned int file_flags;
+} git_merge_options;
+
+#define GIT_MERGE_OPTIONS_VERSION 1
+#define GIT_MERGE_OPTIONS_INIT {GIT_MERGE_OPTIONS_VERSION}
+
+/**
+ * Initializes a `git_merge_options` with default values. Equivalent to
+ * creating an instance with GIT_MERGE_OPTIONS_INIT.
+ *
+ * @param opts the `git_merge_options` instance to initialize.
+ * @param version the version of the struct; you should pass
+ *        `GIT_MERGE_OPTIONS_VERSION` here.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_init_options(
+	git_merge_options *opts,
+	unsigned int version);
+
+/**
+ * The results of `git_merge_analysis` indicate the merge opportunities.
+ */
+typedef enum {
+	/** No merge is possible.  (Unused.) */
+	GIT_MERGE_ANALYSIS_NONE = 0,
+
+	/**
+	 * A "normal" merge; both HEAD and the given merge input have diverged
+	 * from their common ancestor.  The divergent commits must be merged.
+	 */
+	GIT_MERGE_ANALYSIS_NORMAL = (1 << 0),
+
+	/**
+	 * All given merge inputs are reachable from HEAD, meaning the
+	 * repository is up-to-date and no merge needs to be performed.
+	 */
+	GIT_MERGE_ANALYSIS_UP_TO_DATE = (1 << 1),
+
+	/**
+	 * The given merge input is a fast-forward from HEAD and no merge
+	 * needs to be performed.  Instead, the client can check out the
+	 * given merge input.
+	 */
+	GIT_MERGE_ANALYSIS_FASTFORWARD = (1 << 2),
+
+	/**
+	 * The HEAD of the current repository is "unborn" and does not point to
+	 * a valid commit.  No merge can be performed, but the caller may wish
+	 * to simply set HEAD to the target commit(s).
+	 */
+	GIT_MERGE_ANALYSIS_UNBORN = (1 << 3),
+} git_merge_analysis_t;
+
+/**
+ * The user's stated preference for merges.
+ */
+typedef enum {
+	/**
+	 * No configuration was found that suggests a preferred behavior for
+	 * merge.
+	 */
+	GIT_MERGE_PREFERENCE_NONE = 0,
+
+	/**
+	 * There is a `merge.ff=false` configuration setting, suggesting that
+	 * the user does not want to allow a fast-forward merge.
+	 */
+	GIT_MERGE_PREFERENCE_NO_FASTFORWARD = (1 << 0),
+
+	/**
+	 * There is a `merge.ff=only` configuration setting, suggesting that
+	 * the user only wants fast-forward merges.
+	 */
+	GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY = (1 << 1),
+} git_merge_preference_t;
+
+/**
+ * Analyzes the given branch(es) and determines the opportunities for
+ * merging them into the HEAD of the repository.
+ *
+ * @param analysis_out analysis enumeration that the result is written into
+ * @param repo the repository to merge
+ * @param their_heads the heads to merge into
+ * @param their_heads_len the number of heads to merge
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge_analysis(
+	git_merge_analysis_t *analysis_out,
+	git_merge_preference_t *preference_out,
+	git_repository *repo,
+	const git_annotated_commit **their_heads,
+	size_t their_heads_len);
+
+/**
+ * Find a merge base between two commits
+ *
+ * @param out the OID of a merge base between 'one' and 'two'
+ * @param repo the repository where the commits exist
+ * @param one one of the commits
+ * @param two the other commit
+ * @return 0 on success, GIT_ENOTFOUND if not found or error code
+ */
+GIT_EXTERN(int) git_merge_base(
+	git_oid *out,
+	git_repository *repo,
+	const git_oid *one,
+	const git_oid *two);
+
+/**
+ * Find merge bases between two commits
+ *
+ * @param out array in which to store the resulting ids
+ * @param repo the repository where the commits exist
+ * @param one one of the commits
+ * @param two the other commit
+ * @return 0 on success, GIT_ENOTFOUND if not found or error code
+ */
+GIT_EXTERN(int) git_merge_bases(
+	git_oidarray *out,
+	git_repository *repo,
+	const git_oid *one,
+	const git_oid *two);
+
+/**
+ * Find a merge base given a list of commits
+ *
+ * @param out the OID of a merge base considering all the commits
+ * @param repo the repository where the commits exist
+ * @param length The number of commits in the provided `input_array`
+ * @param input_array oids of the commits
+ * @return Zero on success; GIT_ENOTFOUND or -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_base_many(
+	git_oid *out,
+	git_repository *repo,
+	size_t length,
+	const git_oid input_array[]);
+
+/**
+ * Find all merge bases given a list of commits
+ *
+ * @param out array in which to store the resulting ids
+ * @param repo the repository where the commits exist
+ * @param length The number of commits in the provided `input_array`
+ * @param input_array oids of the commits
+ * @return Zero on success; GIT_ENOTFOUND or -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_bases_many(
+	git_oidarray *out,
+	git_repository *repo,
+	size_t length,
+	const git_oid input_array[]);
+
+/**
+ * Find a merge base in preparation for an octopus merge
+ *
+ * @param out the OID of a merge base considering all the commits
+ * @param repo the repository where the commits exist
+ * @param length The number of commits in the provided `input_array`
+ * @param input_array oids of the commits
+ * @return Zero on success; GIT_ENOTFOUND or -1 on failure.
+ */
+GIT_EXTERN(int) git_merge_base_octopus(
+	git_oid *out,
+	git_repository *repo,
+	size_t length,
+	const git_oid input_array[]);
+
+/**
+ * Merge two files as they exist in the in-memory data structures, using
+ * the given common ancestor as the baseline, producing a
+ * `git_merge_file_result` that reflects the merge result.  The
+ * `git_merge_file_result` must be freed with `git_merge_file_result_free`.
+ *
+ * Note that this function does not reference a repository and any
+ * configuration must be passed as `git_merge_file_options`.
+ *
+ * @param out The git_merge_file_result to be filled in
+ * @param ancestor The contents of the ancestor file
+ * @param ours The contents of the file in "our" side
+ * @param theirs The contents of the file in "their" side
+ * @param opts The merge file options or `NULL` for defaults
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge_file(
+	git_merge_file_result *out,
+	const git_merge_file_input *ancestor,
+	const git_merge_file_input *ours,
+	const git_merge_file_input *theirs,
+	const git_merge_file_options *opts);
+
+/**
+ * Merge two files as they exist in the index, using the given common
+ * ancestor as the baseline, producing a `git_merge_file_result` that
+ * reflects the merge result.  The `git_merge_file_result` must be freed with
+ * `git_merge_file_result_free`.
+ *
+ * @param out The git_merge_file_result to be filled in
+ * @param repo The repository
+ * @param ancestor The index entry for the ancestor file (stage level 1)
+ * @param ours The index entry for our file (stage level 2)
+ * @param theirs The index entry for their file (stage level 3)
+ * @param opts The merge file options or NULL
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge_file_from_index(
+	git_merge_file_result *out,
+	git_repository *repo,
+	const git_index_entry *ancestor,
+	const git_index_entry *ours,
+	const git_index_entry *theirs,
+	const git_merge_file_options *opts);
+
+/**
+ * Frees a `git_merge_file_result`.
+ *
+ * @param result The result to free or `NULL`
+ */
+GIT_EXTERN(void) git_merge_file_result_free(git_merge_file_result *result);
+
+/**
+ * Merge two trees, producing a `git_index` that reflects the result of
+ * the merge.  The index may be written as-is to the working directory
+ * or checked out.  If the index is to be converted to a tree, the caller
+ * should resolve any conflicts that arose as part of the merge.
+ *
+ * The returned index must be freed explicitly with `git_index_free`.
+ *
+ * @param out pointer to store the index result in
+ * @param repo repository that contains the given trees
+ * @param ancestor_tree the common ancestor between the trees (or null if none)
+ * @param our_tree the tree that reflects the destination tree
+ * @param their_tree the tree to merge in to `our_tree`
+ * @param opts the merge tree options (or null for defaults)
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge_trees(
+	git_index **out,
+	git_repository *repo,
+	const git_tree *ancestor_tree,
+	const git_tree *our_tree,
+	const git_tree *their_tree,
+	const git_merge_options *opts);
+
+/**
+ * Merge two commits, producing a `git_index` that reflects the result of
+ * the merge.  The index may be written as-is to the working directory
+ * or checked out.  If the index is to be converted to a tree, the caller
+ * should resolve any conflicts that arose as part of the merge.
+ *
+ * The merge performed uses the first common ancestor, unlike the
+ * `git-merge-recursive` strategy, which may produce an artificial common
+ * ancestor tree when there are multiple ancestors.
+ *
+ * The returned index must be freed explicitly with `git_index_free`.
+ *
+ * @param out pointer to store the index result in
+ * @param repo repository that contains the given trees
+ * @param our_commit the commit that reflects the destination tree
+ * @param their_commit the commit to merge in to `our_commit`
+ * @param opts the merge tree options (or null for defaults)
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge_commits(
+	git_index **out,
+	git_repository *repo,
+	const git_commit *our_commit,
+	const git_commit *their_commit,
+	const git_merge_options *opts);
+
+/**
+ * Merges the given commit(s) into HEAD, writing the results into the working
+ * directory.  Any changes are staged for commit and any conflicts are written
+ * to the index.  Callers should inspect the repository's index after this
+ * completes, resolve any conflicts and prepare a commit.
+ *
+ * The merge performed uses the first common ancestor, unlike the
+ * `git-merge-recursive` strategy, which may produce an artificial common
+ * ancestor tree when there are multiple ancestors.
+ *
+ * For compatibility with git, the repository is put into a merging
+ * state. Once the commit is done (or if the uses wishes to abort),
+ * you should clear this state by calling
+ * `git_repository_state_cleanup()`.
+ *
+ * @param repo the repository to merge
+ * @param their_heads the heads to merge into
+ * @param their_heads_len the number of heads to merge
+ * @param merge_opts merge options
+ * @param checkout_opts checkout options
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_merge(
+	git_repository *repo,
+	const git_annotated_commit **their_heads,
+	size_t their_heads_len,
+	const git_merge_options *merge_opts,
+	const git_checkout_options *checkout_opts);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/message.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/message.h
new file mode 100755
index 0000000..d78b1dc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/message.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_message_h__
+#define INCLUDE_git_message_h__
+
+#include "common.h"
+#include "buffer.h"
+
+/**
+ * @file git2/message.h
+ * @brief Git message management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Clean up message from excess whitespace and make sure that the last line
+ * ends with a '\n'.
+ *
+ * Optionally, can remove lines starting with a "#".
+ *
+ * @param out The user-allocated git_buf which will be filled with the
+ *     cleaned up message.
+ *
+ * @param message The message to be prettified.
+ *
+ * @param strip_comments Non-zero to remove comment lines, 0 to leave them in.
+ *
+ * @param comment_char Comment character. Lines starting with this character
+ * are considered to be comments and removed if `strip_comments` is non-zero.
+ *
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_message_prettify(git_buf *out, const char *message, int strip_comments, char comment_char);
+
+/** @} */
+GIT_END_DECL
+
+#endif /* INCLUDE_git_message_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/net.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/net.h
new file mode 100755
index 0000000..04dff34
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/net.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_net_h__
+#define INCLUDE_git_net_h__
+
+#include "common.h"
+#include "oid.h"
+#include "types.h"
+
+/**
+ * @file git2/net.h
+ * @brief Git networking declarations
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+#define GIT_DEFAULT_PORT "9418"
+
+/**
+ * Direction of the connection.
+ *
+ * We need this because we need to know whether we should call
+ * git-upload-pack or git-receive-pack on the remote end when get_refs
+ * gets called.
+ */
+typedef enum {
+	GIT_DIRECTION_FETCH = 0,
+	GIT_DIRECTION_PUSH  = 1
+} git_direction;
+
+/**
+ * Description of a reference advertised by a remote server, given out
+ * on `ls` calls.
+ */
+struct git_remote_head {
+	int local; /* available locally */
+	git_oid oid;
+	git_oid loid;
+	char *name;
+	/**
+	 * If the server send a symref mapping for this ref, this will
+	 * point to the target.
+	 */
+	char *symref_target;
+};
+
+/**
+ * Callback for listing the remote heads
+ */
+typedef int (*git_headlist_cb)(git_remote_head *rhead, void *payload);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/notes.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/notes.h
new file mode 100755
index 0000000..3a626ca
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/notes.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_note_h__
+#define INCLUDE_git_note_h__
+
+#include "oid.h"
+
+/**
+ * @file git2/notes.h
+ * @brief Git notes management routines
+ * @defgroup git_note Git notes management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Callback for git_note_foreach.
+ *
+ * Receives:
+ * - blob_id: Oid of the blob containing the message
+ * - annotated_object_id: Oid of the git object being annotated
+ * - payload: Payload data passed to `git_note_foreach`
+ */
+typedef int (*git_note_foreach_cb)(
+	const git_oid *blob_id, const git_oid *annotated_object_id, void *payload);
+
+/**
+ * note iterator
+ */
+typedef struct git_iterator git_note_iterator;
+
+/**
+ * Creates a new iterator for notes
+ *
+ * The iterator must be freed manually by the user.
+ *
+ * @param out pointer to the iterator
+ * @param repo repository where to look up the note
+ * @param notes_ref canonical name of the reference to use (optional); defaults to
+ *                  "refs/notes/commits"
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_note_iterator_new(
+	git_note_iterator **out,
+	git_repository *repo,
+	const char *notes_ref);
+
+/**
+ * Frees an git_note_iterator
+ *
+ * @param it pointer to the iterator
+ */
+GIT_EXTERN(void) git_note_iterator_free(git_note_iterator *it);
+
+/**
+ * Return the current item (note_id and annotated_id) and advance the iterator
+ * internally to the next value
+ *
+ * @param note_id id of blob containing the message
+ * @param annotated_id id of the git object being annotated
+ * @param it pointer to the iterator
+ *
+ * @return 0 (no error), GIT_ITEROVER (iteration is done) or an error code
+ *         (negative value)
+ */
+GIT_EXTERN(int) git_note_next(
+	git_oid* note_id,
+	git_oid* annotated_id,
+	git_note_iterator *it);
+
+
+/**
+ * Read the note for an object
+ *
+ * The note must be freed manually by the user.
+ *
+ * @param out pointer to the read note; NULL in case of error
+ * @param repo repository where to look up the note
+ * @param notes_ref canonical name of the reference to use (optional); defaults to
+ *                  "refs/notes/commits"
+ * @param oid OID of the git object to read the note from
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_note_read(
+	git_note **out,
+	git_repository *repo,
+	const char *notes_ref,
+	const git_oid *oid);
+
+/**
+ * Get the note author
+ *
+ * @param note the note
+ * @return the author
+ */
+GIT_EXTERN(const git_signature *) git_note_author(const git_note *note);
+
+/**
+ * Get the note committer
+ *
+ * @param note the note
+ * @return the committer
+ */
+GIT_EXTERN(const git_signature *) git_note_committer(const git_note *note);
+
+
+/**
+ * Get the note message
+ *
+ * @param note the note
+ * @return the note message
+ */
+GIT_EXTERN(const char *) git_note_message(const git_note *note);
+
+
+/**
+ * Get the note object's id
+ *
+ * @param note the note
+ * @return the note object's id
+ */
+GIT_EXTERN(const git_oid *) git_note_id(const git_note *note);
+
+/**
+ * Add a note for an object
+ *
+ * @param out pointer to store the OID (optional); NULL in case of error
+ * @param repo repository where to store the note
+ * @param notes_ref canonical name of the reference to use (optional);
+ *					defaults to "refs/notes/commits"
+ * @param author signature of the notes commit author
+ * @param committer signature of the notes commit committer
+ * @param oid OID of the git object to decorate
+ * @param note Content of the note to add for object oid
+ * @param force Overwrite existing note
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_note_create(
+	git_oid *out,
+	git_repository *repo,
+	const char *notes_ref,
+	const git_signature *author,
+	const git_signature *committer,
+	const git_oid *oid,
+	const char *note,
+	int force);
+
+
+/**
+ * Remove the note for an object
+ *
+ * @param repo repository where the note lives
+ * @param notes_ref canonical name of the reference to use (optional);
+ *					defaults to "refs/notes/commits"
+ * @param author signature of the notes commit author
+ * @param committer signature of the notes commit committer
+ * @param oid OID of the git object to remove the note from
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_note_remove(
+	git_repository *repo,
+	const char *notes_ref,
+	const git_signature *author,
+	const git_signature *committer,
+	const git_oid *oid);
+
+/**
+ * Free a git_note object
+ *
+ * @param note git_note object
+ */
+GIT_EXTERN(void) git_note_free(git_note *note);
+
+/**
+ * Get the default notes reference for a repository
+ *
+ * @param out buffer in which to store the name of the default notes reference
+ * @param repo The Git repository
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_note_default_ref(git_buf *out, git_repository *repo);
+
+/**
+ * Loop over all the notes within a specified namespace
+ * and issue a callback for each one.
+ *
+ * @param repo Repository where to find the notes.
+ *
+ * @param notes_ref Reference to read from (optional); defaults to
+ *        "refs/notes/commits".
+ *
+ * @param note_cb Callback to invoke per found annotation.  Return non-zero
+ *        to stop looping.
+ *
+ * @param payload Extra parameter to callback function.
+ *
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_note_foreach(
+	git_repository *repo,
+	const char *notes_ref,
+	git_note_foreach_cb note_cb,
+	void *payload);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/object.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/object.h
new file mode 100755
index 0000000..a798c9d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/object.h
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_object_h__
+#define INCLUDE_git_object_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "buffer.h"
+
+/**
+ * @file git2/object.h
+ * @brief Git revision object management routines
+ * @defgroup git_object Git revision object management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Lookup a reference to one of the objects in a repository.
+ *
+ * The generated reference is owned by the repository and
+ * should be closed with the `git_object_free` method
+ * instead of free'd manually.
+ *
+ * The 'type' parameter must match the type of the object
+ * in the odb; the method will fail otherwise.
+ * The special value 'GIT_OBJ_ANY' may be passed to let
+ * the method guess the object's type.
+ *
+ * @param object pointer to the looked-up object
+ * @param repo the repository to look up the object
+ * @param id the unique identifier for the object
+ * @param type the type of the object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_object_lookup(
+		git_object **object,
+		git_repository *repo,
+		const git_oid *id,
+		git_otype type);
+
+/**
+ * Lookup a reference to one of the objects in a repository,
+ * given a prefix of its identifier (short id).
+ *
+ * The object obtained will be so that its identifier
+ * matches the first 'len' hexadecimal characters
+ * (packets of 4 bits) of the given 'id'.
+ * 'len' must be at least GIT_OID_MINPREFIXLEN, and
+ * long enough to identify a unique object matching
+ * the prefix; otherwise the method will fail.
+ *
+ * The generated reference is owned by the repository and
+ * should be closed with the `git_object_free` method
+ * instead of free'd manually.
+ *
+ * The 'type' parameter must match the type of the object
+ * in the odb; the method will fail otherwise.
+ * The special value 'GIT_OBJ_ANY' may be passed to let
+ * the method guess the object's type.
+ *
+ * @param object_out pointer where to store the looked-up object
+ * @param repo the repository to look up the object
+ * @param id a short identifier for the object
+ * @param len the length of the short identifier
+ * @param type the type of the object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_object_lookup_prefix(
+		git_object **object_out,
+		git_repository *repo,
+		const git_oid *id,
+		size_t len,
+		git_otype type);
+
+
+/**
+ * Lookup an object that represents a tree entry.
+ *
+ * @param out buffer that receives a pointer to the object (which must be freed
+ *            by the caller)
+ * @param treeish root object that can be peeled to a tree
+ * @param path relative path from the root object to the desired object
+ * @param type type of object desired
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_object_lookup_bypath(
+		git_object **out,
+		const git_object *treeish,
+		const char *path,
+		git_otype type);
+
+/**
+ * Get the id (SHA1) of a repository object
+ *
+ * @param obj the repository object
+ * @return the SHA1 id
+ */
+GIT_EXTERN(const git_oid *) git_object_id(const git_object *obj);
+
+/**
+ * Get a short abbreviated OID string for the object
+ *
+ * This starts at the "core.abbrev" length (default 7 characters) and
+ * iteratively extends to a longer string if that length is ambiguous.
+ * The result will be unambiguous (at least until new objects are added to
+ * the repository).
+ *
+ * @param out Buffer to write string into
+ * @param obj The object to get an ID for
+ * @return 0 on success, <0 for error
+ */
+GIT_EXTERN(int) git_object_short_id(git_buf *out, const git_object *obj);
+
+/**
+ * Get the object type of an object
+ *
+ * @param obj the repository object
+ * @return the object's type
+ */
+GIT_EXTERN(git_otype) git_object_type(const git_object *obj);
+
+/**
+ * Get the repository that owns this object
+ *
+ * Freeing or calling `git_repository_close` on the
+ * returned pointer will invalidate the actual object.
+ *
+ * Any other operation may be run on the repository without
+ * affecting the object.
+ *
+ * @param obj the object
+ * @return the repository who owns this object
+ */
+GIT_EXTERN(git_repository *) git_object_owner(const git_object *obj);
+
+/**
+ * Close an open object
+ *
+ * This method instructs the library to close an existing
+ * object; note that git_objects are owned and cached by the repository
+ * so the object may or may not be freed after this library call,
+ * depending on how aggressive is the caching mechanism used
+ * by the repository.
+ *
+ * IMPORTANT:
+ * It *is* necessary to call this method when you stop using
+ * an object. Failure to do so will cause a memory leak.
+ *
+ * @param object the object to close
+ */
+GIT_EXTERN(void) git_object_free(git_object *object);
+
+/**
+ * Convert an object type to its string representation.
+ *
+ * The result is a pointer to a string in static memory and
+ * should not be free()'ed.
+ *
+ * @param type object type to convert.
+ * @return the corresponding string representation.
+ */
+GIT_EXTERN(const char *) git_object_type2string(git_otype type);
+
+/**
+ * Convert a string object type representation to it's git_otype.
+ *
+ * @param str the string to convert.
+ * @return the corresponding git_otype.
+ */
+GIT_EXTERN(git_otype) git_object_string2type(const char *str);
+
+/**
+ * Determine if the given git_otype is a valid loose object type.
+ *
+ * @param type object type to test.
+ * @return true if the type represents a valid loose object type,
+ * false otherwise.
+ */
+GIT_EXTERN(int) git_object_typeisloose(git_otype type);
+
+/**
+ * Get the size in bytes for the structure which
+ * acts as an in-memory representation of any given
+ * object type.
+ *
+ * For all the core types, this would the equivalent
+ * of calling `sizeof(git_commit)` if the core types
+ * were not opaque on the external API.
+ *
+ * @param type object type to get its size
+ * @return size in bytes of the object
+ */
+GIT_EXTERN(size_t) git_object__size(git_otype type);
+
+/**
+ * Recursively peel an object until an object of the specified type is met.
+ *
+ * If the query cannot be satisfied due to the object model,
+ * GIT_EINVALIDSPEC will be returned (e.g. trying to peel a blob to a
+ * tree).
+ *
+ * If you pass `GIT_OBJ_ANY` as the target type, then the object will
+ * be peeled until the type changes. A tag will be peeled until the
+ * referenced object is no longer a tag, and a commit will be peeled
+ * to a tree. Any other object type will return GIT_EINVALIDSPEC.
+ *
+ * If peeling a tag we discover an object which cannot be peeled to
+ * the target type due to the object model, GIT_EPEEL will be
+ * returned.
+ *
+ * You must free the returned object.
+ *
+ * @param peeled Pointer to the peeled git_object
+ * @param object The object to be processed
+ * @param target_type The type of the requested object (a GIT_OBJ_ value)
+ * @return 0 on success, GIT_EINVALIDSPEC, GIT_EPEEL, or an error code
+ */
+GIT_EXTERN(int) git_object_peel(
+	git_object **peeled,
+	const git_object *object,
+	git_otype target_type);
+
+/**
+ * Create an in-memory copy of a Git object. The copy must be
+ * explicitly free'd or it will leak.
+ *
+ * @param dest Pointer to store the copy of the object
+ * @param source Original object to copy
+ */
+GIT_EXTERN(int) git_object_dup(git_object **dest, git_object *source);
+
+/** @} */
+GIT_END_DECL
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/odb.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/odb.h
new file mode 100755
index 0000000..4f1e18b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/odb.h
@@ -0,0 +1,495 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_odb_h__
+#define INCLUDE_git_odb_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+
+/**
+ * @file git2/odb.h
+ * @brief Git object database routines
+ * @defgroup git_odb Git object database routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Function type for callbacks from git_odb_foreach.
+ */
+typedef int (*git_odb_foreach_cb)(const git_oid *id, void *payload);
+
+/**
+ * Create a new object database with no backends.
+ *
+ * Before the ODB can be used for read/writing, a custom database
+ * backend must be manually added using `git_odb_add_backend()`
+ *
+ * @param out location to store the database pointer, if opened.
+ *			Set to NULL if the open failed.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_odb_new(git_odb **out);
+
+/**
+ * Create a new object database and automatically add
+ * the two default backends:
+ *
+ *	- git_odb_backend_loose: read and write loose object files
+ *		from disk, assuming `objects_dir` as the Objects folder
+ *
+ *	- git_odb_backend_pack: read objects from packfiles,
+ *		assuming `objects_dir` as the Objects folder which
+ *		contains a 'pack/' folder with the corresponding data
+ *
+ * @param out location to store the database pointer, if opened.
+ *			Set to NULL if the open failed.
+ * @param objects_dir path of the backends' "objects" directory.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_odb_open(git_odb **out, const char *objects_dir);
+
+/**
+ * Add an on-disk alternate to an existing Object DB.
+ *
+ * Note that the added path must point to an `objects`, not
+ * to a full repository, to use it as an alternate store.
+ *
+ * Alternate backends are always checked for objects *after*
+ * all the main backends have been exhausted.
+ *
+ * Writing is disabled on alternate backends.
+ *
+ * @param odb database to add the backend to
+ * @param path path to the objects folder for the alternate
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_odb_add_disk_alternate(git_odb *odb, const char *path);
+
+/**
+ * Close an open object database.
+ *
+ * @param db database pointer to close. If NULL no action is taken.
+ */
+GIT_EXTERN(void) git_odb_free(git_odb *db);
+
+/**
+ * Read an object from the database.
+ *
+ * This method queries all available ODB backends
+ * trying to read the given OID.
+ *
+ * The returned object is reference counted and
+ * internally cached, so it should be closed
+ * by the user once it's no longer in use.
+ *
+ * @param out pointer where to store the read object
+ * @param db database to search for the object in.
+ * @param id identity of the object to read.
+ * @return
+ * - 0 if the object was read;
+ * - GIT_ENOTFOUND if the object is not in the database.
+ */
+GIT_EXTERN(int) git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id);
+
+/**
+ * Read an object from the database, given a prefix
+ * of its identifier.
+ *
+ * This method queries all available ODB backends
+ * trying to match the 'len' first hexadecimal
+ * characters of the 'short_id'.
+ * The remaining (GIT_OID_HEXSZ-len)*4 bits of
+ * 'short_id' must be 0s.
+ * 'len' must be at least GIT_OID_MINPREFIXLEN,
+ * and the prefix must be long enough to identify
+ * a unique object in all the backends; the
+ * method will fail otherwise.
+ *
+ * The returned object is reference counted and
+ * internally cached, so it should be closed
+ * by the user once it's no longer in use.
+ *
+ * @param out pointer where to store the read object
+ * @param db database to search for the object in.
+ * @param short_id a prefix of the id of the object to read.
+ * @param len the length of the prefix
+ * @return
+ * - 0 if the object was read;
+ * - GIT_ENOTFOUND if the object is not in the database.
+ * - GIT_EAMBIGUOUS if the prefix is ambiguous (several objects match the prefix)
+ */
+GIT_EXTERN(int) git_odb_read_prefix(git_odb_object **out, git_odb *db, const git_oid *short_id, size_t len);
+
+/**
+ * Read the header of an object from the database, without
+ * reading its full contents.
+ *
+ * The header includes the length and the type of an object.
+ *
+ * Note that most backends do not support reading only the header
+ * of an object, so the whole object will be read and then the
+ * header will be returned.
+ *
+ * @param len_out pointer where to store the length
+ * @param type_out pointer where to store the type
+ * @param db database to search for the object in.
+ * @param id identity of the object to read.
+ * @return
+ * - 0 if the object was read;
+ * - GIT_ENOTFOUND if the object is not in the database.
+ */
+GIT_EXTERN(int) git_odb_read_header(size_t *len_out, git_otype *type_out, git_odb *db, const git_oid *id);
+
+/**
+ * Determine if the given object can be found in the object database.
+ *
+ * @param db database to be searched for the given object.
+ * @param id the object to search for.
+ * @return
+ * - 1, if the object was found
+ * - 0, otherwise
+ */
+GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id);
+
+/**
+ * Determine if objects can be found in the object database from a short OID.
+ *
+ * @param out The full OID of the found object if just one is found.
+ * @param db The database to be searched for the given object.
+ * @param short_id A prefix of the id of the object to read.
+ * @param len The length of the prefix.
+ * @return 0 if found, GIT_ENOTFOUND if not found, GIT_EAMBIGUOUS if multiple
+ *         matches were found, other value < 0 if there was a read error.
+ */
+GIT_EXTERN(int) git_odb_exists_prefix(
+	git_oid *out, git_odb *db, const git_oid *short_id, size_t len);
+
+/**
+ * Refresh the object database to load newly added files.
+ *
+ * If the object databases have changed on disk while the library
+ * is running, this function will force a reload of the underlying
+ * indexes.
+ *
+ * Use this function when you're confident that an external
+ * application has tampered with the ODB.
+ *
+ * NOTE that it is not necessary to call this function at all. The
+ * library will automatically attempt to refresh the ODB
+ * when a lookup fails, to see if the looked up object exists
+ * on disk but hasn't been loaded yet.
+ *
+ * @param db database to refresh
+ * @return 0 on success, error code otherwise
+ */
+GIT_EXTERN(int) git_odb_refresh(struct git_odb *db);
+
+/**
+ * List all objects available in the database
+ *
+ * The callback will be called for each object available in the
+ * database. Note that the objects are likely to be returned in the index
+ * order, which would make accessing the objects in that order inefficient.
+ * Return a non-zero value from the callback to stop looping.
+ *
+ * @param db database to use
+ * @param cb the callback to call for each object
+ * @param payload data to pass to the callback
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_odb_foreach(git_odb *db, git_odb_foreach_cb cb, void *payload);
+
+/**
+ * Write an object directly into the ODB
+ *
+ * This method writes a full object straight into the ODB.
+ * For most cases, it is preferred to write objects through a write
+ * stream, which is both faster and less memory intensive, specially
+ * for big objects.
+ *
+ * This method is provided for compatibility with custom backends
+ * which are not able to support streaming writes
+ *
+ * @param out pointer to store the OID result of the write
+ * @param odb object database where to store the object
+ * @param data buffer with the data to store
+ * @param len size of the buffer
+ * @param type type of the data to store
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_odb_write(git_oid *out, git_odb *odb, const void *data, size_t len, git_otype type);
+
+/**
+ * Open a stream to write an object into the ODB
+ *
+ * The type and final length of the object must be specified
+ * when opening the stream.
+ *
+ * The returned stream will be of type `GIT_STREAM_WRONLY`, and it
+ * won't be effective until `git_odb_stream_finalize_write` is called
+ * and returns without an error
+ *
+ * The stream must always be freed when done with `git_odb_stream_free` or
+ * will leak memory.
+ *
+ * @see git_odb_stream
+ *
+ * @param out pointer where to store the stream
+ * @param db object database where the stream will write
+ * @param size final size of the object that will be written
+ * @param type type of the object that will be written
+ * @return 0 if the stream was created; error code otherwise
+ */
+GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **out, git_odb *db, git_off_t size, git_otype type);
+
+/**
+ * Write to an odb stream
+ *
+ * This method will fail if the total number of received bytes exceeds the
+ * size declared with `git_odb_open_wstream()`
+ *
+ * @param stream the stream
+ * @param buffer the data to write
+ * @param len the buffer's length
+ * @return 0 if the write succeeded; error code otherwise
+ */
+GIT_EXTERN(int) git_odb_stream_write(git_odb_stream *stream, const char *buffer, size_t len);
+
+/**
+ * Finish writing to an odb stream
+ *
+ * The object will take its final name and will be available to the
+ * odb.
+ *
+ * This method will fail if the total number of received bytes
+ * differs from the size declared with `git_odb_open_wstream()`
+ *
+ * @param out pointer to store the resulting object's id
+ * @param stream the stream
+ * @return 0 on success; an error code otherwise
+ */
+GIT_EXTERN(int) git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stream);
+
+/**
+ * Read from an odb stream
+ *
+ * Most backends don't implement streaming reads
+ */
+GIT_EXTERN(int) git_odb_stream_read(git_odb_stream *stream, char *buffer, size_t len);
+
+/**
+ * Free an odb stream
+ *
+ * @param stream the stream to free
+ */
+GIT_EXTERN(void) git_odb_stream_free(git_odb_stream *stream);
+
+/**
+ * Open a stream to read an object from the ODB
+ *
+ * Note that most backends do *not* support streaming reads
+ * because they store their objects as compressed/delta'ed blobs.
+ *
+ * It's recommended to use `git_odb_read` instead, which is
+ * assured to work on all backends.
+ *
+ * The returned stream will be of type `GIT_STREAM_RDONLY` and
+ * will have the following methods:
+ *
+ *		- stream->read: read `n` bytes from the stream
+ *		- stream->free: free the stream
+ *
+ * The stream must always be free'd or will leak memory.
+ *
+ * @see git_odb_stream
+ *
+ * @param out pointer where to store the stream
+ * @param db object database where the stream will read from
+ * @param oid oid of the object the stream will read from
+ * @return 0 if the stream was created; error code otherwise
+ */
+GIT_EXTERN(int) git_odb_open_rstream(git_odb_stream **out, git_odb *db, const git_oid *oid);
+
+/**
+ * Open a stream for writing a pack file to the ODB.
+ *
+ * If the ODB layer understands pack files, then the given
+ * packfile will likely be streamed directly to disk (and a
+ * corresponding index created).  If the ODB layer does not
+ * understand pack files, the objects will be stored in whatever
+ * format the ODB layer uses.
+ *
+ * @see git_odb_writepack
+ *
+ * @param out pointer to the writepack functions
+ * @param db object database where the stream will read from
+ * @param progress_cb function to call with progress information.
+ * Be aware that this is called inline with network and indexing operations,
+ * so performance may be affected.
+ * @param progress_payload payload for the progress callback
+ */
+GIT_EXTERN(int) git_odb_write_pack(
+	git_odb_writepack **out,
+	git_odb *db,
+	git_transfer_progress_cb progress_cb,
+	void *progress_payload);
+
+/**
+ * Determine the object-ID (sha1 hash) of a data buffer
+ *
+ * The resulting SHA-1 OID will be the identifier for the data
+ * buffer as if the data buffer it were to written to the ODB.
+ *
+ * @param out the resulting object-ID.
+ * @param data data to hash
+ * @param len size of the data
+ * @param type of the data to hash
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_odb_hash(git_oid *out, const void *data, size_t len, git_otype type);
+
+/**
+ * Read a file from disk and fill a git_oid with the object id
+ * that the file would have if it were written to the Object
+ * Database as an object of the given type (w/o applying filters).
+ * Similar functionality to git.git's `git hash-object` without
+ * the `-w` flag, however, with the --no-filters flag.
+ * If you need filters, see git_repository_hashfile.
+ *
+ * @param out oid structure the result is written into.
+ * @param path file to read and determine object id for
+ * @param type the type of the object that will be hashed
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_odb_hashfile(git_oid *out, const char *path, git_otype type);
+
+/**
+ * Create a copy of an odb_object
+ *
+ * The returned copy must be manually freed with `git_odb_object_free`.
+ * Note that because of an implementation detail, the returned copy will be
+ * the same pointer as `source`: the object is internally refcounted, so the
+ * copy still needs to be freed twice.
+ *
+ * @param dest pointer where to store the copy
+ * @param source object to copy
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_odb_object_dup(git_odb_object **dest, git_odb_object *source);
+
+/**
+ * Close an ODB object
+ *
+ * This method must always be called once a `git_odb_object` is no
+ * longer needed, otherwise memory will leak.
+ *
+ * @param object object to close
+ */
+GIT_EXTERN(void) git_odb_object_free(git_odb_object *object);
+
+/**
+ * Return the OID of an ODB object
+ *
+ * This is the OID from which the object was read from
+ *
+ * @param object the object
+ * @return a pointer to the OID
+ */
+GIT_EXTERN(const git_oid *) git_odb_object_id(git_odb_object *object);
+
+/**
+ * Return the data of an ODB object
+ *
+ * This is the uncompressed, raw data as read from the ODB,
+ * without the leading header.
+ *
+ * This pointer is owned by the object and shall not be free'd.
+ *
+ * @param object the object
+ * @return a pointer to the data
+ */
+GIT_EXTERN(const void *) git_odb_object_data(git_odb_object *object);
+
+/**
+ * Return the size of an ODB object
+ *
+ * This is the real size of the `data` buffer, not the
+ * actual size of the object.
+ *
+ * @param object the object
+ * @return the size
+ */
+GIT_EXTERN(size_t) git_odb_object_size(git_odb_object *object);
+
+/**
+ * Return the type of an ODB object
+ *
+ * @param object the object
+ * @return the type
+ */
+GIT_EXTERN(git_otype) git_odb_object_type(git_odb_object *object);
+
+/**
+ * Add a custom backend to an existing Object DB
+ *
+ * The backends are checked in relative ordering, based on the
+ * value of the `priority` parameter.
+ *
+ * Read <odb_backends.h> for more information.
+ *
+ * @param odb database to add the backend to
+ * @param backend pointer to a git_odb_backend instance
+ * @param priority Value for ordering the backends queue
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority);
+
+/**
+ * Add a custom backend to an existing Object DB; this
+ * backend will work as an alternate.
+ *
+ * Alternate backends are always checked for objects *after*
+ * all the main backends have been exhausted.
+ *
+ * The backends are checked in relative ordering, based on the
+ * value of the `priority` parameter.
+ *
+ * Writing is disabled on alternate backends.
+ *
+ * Read <odb_backends.h> for more information.
+ *
+ * @param odb database to add the backend to
+ * @param backend pointer to a git_odb_backend instance
+ * @param priority Value for ordering the backends queue
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority);
+
+/**
+ * Get the number of ODB backend objects
+ *
+ * @param odb object database
+ * @return number of backends in the ODB
+ */
+GIT_EXTERN(size_t) git_odb_num_backends(git_odb *odb);
+
+/**
+ * Lookup an ODB backend object by index
+ *
+ * @param out output pointer to ODB backend at pos
+ * @param odb object database
+ * @param pos index into object database backend list
+ * @return 0 on success; GIT_ENOTFOUND if pos is invalid; other errors < 0
+ */
+GIT_EXTERN(int) git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/odb_backend.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/odb_backend.h
new file mode 100755
index 0000000..b17cfd8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/odb_backend.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_odb_backend_h__
+#define INCLUDE_git_odb_backend_h__
+
+#include "common.h"
+#include "types.h"
+
+/**
+ * @file git2/backend.h
+ * @brief Git custom backend functions
+ * @defgroup git_odb Git object database routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/*
+ * Constructors for in-box ODB backends.
+ */
+
+/**
+ * Create a backend for the packfiles.
+ *
+ * @param out location to store the odb backend pointer
+ * @param objects_dir the Git repository's objects directory
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **out, const char *objects_dir);
+
+/**
+ * Create a backend for loose objects
+ *
+ * @param out location to store the odb backend pointer
+ * @param objects_dir the Git repository's objects directory
+ * @param compression_level zlib compression level to use
+ * @param do_fsync whether to do an fsync() after writing (currently ignored)
+ * @param dir_mode permissions to use creating a directory or 0 for defaults
+ * @param file_mode permissions to use creating a file or 0 for defaults
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_odb_backend_loose(
+	git_odb_backend **out,
+	const char *objects_dir,
+	int compression_level,
+	int do_fsync,
+	unsigned int dir_mode,
+	unsigned int file_mode);
+
+/**
+ * Create a backend out of a single packfile
+ *
+ * This can be useful for inspecting the contents of a single
+ * packfile.
+ *
+ * @param out location to store the odb backend pointer
+ * @param index_file path to the packfile's .idx file
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **out, const char *index_file);
+
+/** Streaming mode */
+typedef enum {
+	GIT_STREAM_RDONLY = (1 << 1),
+	GIT_STREAM_WRONLY = (1 << 2),
+	GIT_STREAM_RW = (GIT_STREAM_RDONLY | GIT_STREAM_WRONLY),
+} git_odb_stream_t;
+
+/**
+ * A stream to read/write from a backend.
+ *
+ * This represents a stream of data being written to or read from a
+ * backend. When writing, the frontend functions take care of
+ * calculating the object's id and all `finalize_write` needs to do is
+ * store the object with the id it is passed.
+ */
+struct git_odb_stream {
+	git_odb_backend *backend;
+	unsigned int mode;
+	void *hash_ctx;
+
+	git_off_t declared_size;
+	git_off_t received_bytes;
+
+	/**
+	 * Write at most `len` bytes into `buffer` and advance the stream.
+	 */
+	int (*read)(git_odb_stream *stream, char *buffer, size_t len);
+
+	/**
+	 * Write `len` bytes from `buffer` into the stream.
+	 */
+	int (*write)(git_odb_stream *stream, const char *buffer, size_t len);
+
+	/**
+	 * Store the contents of the stream as an object with the id
+	 * specified in `oid`.
+	 *
+	 * This method might not be invoked if:
+	 * - an error occurs earlier with the `write` callback,
+	 * - the object referred to by `oid` already exists in any backend, or
+	 * - the final number of received bytes differs from the size declared
+	 *   with `git_odb_open_wstream()`
+	 */
+	int (*finalize_write)(git_odb_stream *stream, const git_oid *oid);
+
+	/**
+	 * Free the stream's memory.
+	 *
+	 * This method might be called without a call to `finalize_write` if
+	 * an error occurs or if the object is already present in the ODB.
+	 */
+	void (*free)(git_odb_stream *stream);
+};
+
+/** A stream to write a pack file to the ODB */
+struct git_odb_writepack {
+	git_odb_backend *backend;
+
+	int (*append)(git_odb_writepack *writepack, const void *data, size_t size, git_transfer_progress *stats);
+	int (*commit)(git_odb_writepack *writepack, git_transfer_progress *stats);
+	void (*free)(git_odb_writepack *writepack);
+};
+
+GIT_END_DECL
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/oid.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/oid.h
new file mode 100755
index 0000000..8ad51c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/oid.h
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_oid_h__
+#define INCLUDE_git_oid_h__
+
+#include "common.h"
+#include "types.h"
+
+/**
+ * @file git2/oid.h
+ * @brief Git object id routines
+ * @defgroup git_oid Git object id routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/** Size (in bytes) of a raw/binary oid */
+#define GIT_OID_RAWSZ 20
+
+/** Size (in bytes) of a hex formatted oid */
+#define GIT_OID_HEXSZ (GIT_OID_RAWSZ * 2)
+
+/** Minimum length (in number of hex characters,
+ * i.e. packets of 4 bits) of an oid prefix */
+#define GIT_OID_MINPREFIXLEN 4
+
+/** Unique identity of any object (commit, tree, blob, tag). */
+typedef struct git_oid {
+	/** raw binary formatted id */
+	unsigned char id[GIT_OID_RAWSZ];
+} git_oid;
+
+/**
+ * Parse a hex formatted object id into a git_oid.
+ *
+ * @param out oid structure the result is written into.
+ * @param str input hex string; must be pointing at the start of
+ *		the hex sequence and have at least the number of bytes
+ *		needed for an oid encoded in hex (40 bytes).
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_oid_fromstr(git_oid *out, const char *str);
+
+/**
+ * Parse a hex formatted null-terminated string into a git_oid.
+ *
+ * @param out oid structure the result is written into.
+ * @param str input hex string; must be at least 4 characters
+ *      long and null-terminated.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_oid_fromstrp(git_oid *out, const char *str);
+
+/**
+ * Parse N characters of a hex formatted object id into a git_oid
+ *
+ * If N is odd, N-1 characters will be parsed instead.
+ * The remaining space in the git_oid will be set to zero.
+ *
+ * @param out oid structure the result is written into.
+ * @param str input hex string of at least size `length`
+ * @param length length of the input string
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_oid_fromstrn(git_oid *out, const char *str, size_t length);
+
+/**
+ * Copy an already raw oid into a git_oid structure.
+ *
+ * @param out oid structure the result is written into.
+ * @param raw the raw input bytes to be copied.
+ */
+GIT_EXTERN(void) git_oid_fromraw(git_oid *out, const unsigned char *raw);
+
+/**
+ * Format a git_oid into a hex string.
+ *
+ * @param out output hex string; must be pointing at the start of
+ *		the hex sequence and have at least the number of bytes
+ *		needed for an oid encoded in hex (40 bytes). Only the
+ *		oid digits are written; a '\\0' terminator must be added
+ *		by the caller if it is required.
+ * @param id oid structure to format.
+ */
+GIT_EXTERN(void) git_oid_fmt(char *out, const git_oid *id);
+
+/**
+ * Format a git_oid into a partial hex string.
+ *
+ * @param out output hex string; you say how many bytes to write.
+ *		If the number of bytes is > GIT_OID_HEXSZ, extra bytes
+ *		will be zeroed; if not, a '\0' terminator is NOT added.
+ * @param n number of characters to write into out string
+ * @param id oid structure to format.
+ */
+GIT_EXTERN(void) git_oid_nfmt(char *out, size_t n, const git_oid *id);
+
+/**
+ * Format a git_oid into a loose-object path string.
+ *
+ * The resulting string is "aa/...", where "aa" is the first two
+ * hex digits of the oid and "..." is the remaining 38 digits.
+ *
+ * @param out output hex string; must be pointing at the start of
+ *		the hex sequence and have at least the number of bytes
+ *		needed for an oid encoded in hex (41 bytes). Only the
+ *		oid digits are written; a '\\0' terminator must be added
+ *		by the caller if it is required.
+ * @param id oid structure to format.
+ */
+GIT_EXTERN(void) git_oid_pathfmt(char *out, const git_oid *id);
+
+/**
+ * Format a git_oid into a statically allocated c-string.
+ *
+ * The c-string is owned by the library and should not be freed
+ * by the user. If libgit2 is built with thread support, the string
+ * will be stored in TLS (i.e. one buffer per thread) to allow for
+ * concurrent calls of the function.
+ *
+ * @param oid The oid structure to format
+ * @return the c-string
+ */
+GIT_EXTERN(char *) git_oid_tostr_s(const git_oid *oid);
+
+/**
+ * Format a git_oid into a buffer as a hex format c-string.
+ *
+ * If the buffer is smaller than GIT_OID_HEXSZ+1, then the resulting
+ * oid c-string will be truncated to n-1 characters (but will still be
+ * NUL-byte terminated).
+ *
+ * If there are any input parameter errors (out == NULL, n == 0, oid ==
+ * NULL), then a pointer to an empty string is returned, so that the
+ * return value can always be printed.
+ *
+ * @param out the buffer into which the oid string is output.
+ * @param n the size of the out buffer.
+ * @param id the oid structure to format.
+ * @return the out buffer pointer, assuming no input parameter
+ *			errors, otherwise a pointer to an empty string.
+ */
+GIT_EXTERN(char *) git_oid_tostr(char *out, size_t n, const git_oid *id);
+
+/**
+ * Copy an oid from one structure to another.
+ *
+ * @param out oid structure the result is written into.
+ * @param src oid structure to copy from.
+ */
+GIT_EXTERN(void) git_oid_cpy(git_oid *out, const git_oid *src);
+
+/**
+ * Compare two oid structures.
+ *
+ * @param a first oid structure.
+ * @param b second oid structure.
+ * @return <0, 0, >0 if a < b, a == b, a > b.
+ */
+GIT_EXTERN(int) git_oid_cmp(const git_oid *a, const git_oid *b);
+
+/**
+ * Compare two oid structures for equality
+ *
+ * @param a first oid structure.
+ * @param b second oid structure.
+ * @return true if equal, false otherwise
+ */
+GIT_EXTERN(int) git_oid_equal(const git_oid *a, const git_oid *b);
+
+/**
+ * Compare the first 'len' hexadecimal characters (packets of 4 bits)
+ * of two oid structures.
+ *
+ * @param a first oid structure.
+ * @param b second oid structure.
+ * @param len the number of hex chars to compare
+ * @return 0 in case of a match
+ */
+GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, size_t len);
+
+/**
+ * Check if an oid equals an hex formatted object id.
+ *
+ * @param id oid structure.
+ * @param str input hex string of an object id.
+ * @return 0 in case of a match, -1 otherwise.
+ */
+GIT_EXTERN(int) git_oid_streq(const git_oid *id, const char *str);
+
+/**
+ * Compare an oid to an hex formatted object id.
+ *
+ * @param id oid structure.
+ * @param str input hex string of an object id.
+ * @return -1 if str is not valid, <0 if id sorts before str,
+ *         0 if id matches str, >0 if id sorts after str.
+ */
+GIT_EXTERN(int) git_oid_strcmp(const git_oid *id, const char *str);
+
+/**
+ * Check is an oid is all zeros.
+ *
+ * @return 1 if all zeros, 0 otherwise.
+ */
+GIT_EXTERN(int) git_oid_iszero(const git_oid *id);
+
+/**
+ * OID Shortener object
+ */
+typedef struct git_oid_shorten git_oid_shorten;
+
+/**
+ * Create a new OID shortener.
+ *
+ * The OID shortener is used to process a list of OIDs
+ * in text form and return the shortest length that would
+ * uniquely identify all of them.
+ *
+ * E.g. look at the result of `git log --abbrev`.
+ *
+ * @param min_length The minimal length for all identifiers,
+ *		which will be used even if shorter OIDs would still
+ *		be unique.
+ *	@return a `git_oid_shorten` instance, NULL if OOM
+ */
+GIT_EXTERN(git_oid_shorten *) git_oid_shorten_new(size_t min_length);
+
+/**
+ * Add a new OID to set of shortened OIDs and calculate
+ * the minimal length to uniquely identify all the OIDs in
+ * the set.
+ *
+ * The OID is expected to be a 40-char hexadecimal string.
+ * The OID is owned by the user and will not be modified
+ * or freed.
+ *
+ * For performance reasons, there is a hard-limit of how many
+ * OIDs can be added to a single set (around ~32000, assuming
+ * a mostly randomized distribution), which should be enough
+ * for any kind of program, and keeps the algorithm fast and
+ * memory-efficient.
+ *
+ * Attempting to add more than those OIDs will result in a
+ * GITERR_INVALID error
+ *
+ * @param os a `git_oid_shorten` instance
+ * @param text_id an OID in text form
+ * @return the minimal length to uniquely identify all OIDs
+ *		added so far to the set; or an error code (<0) if an
+ *		error occurs.
+ */
+GIT_EXTERN(int) git_oid_shorten_add(git_oid_shorten *os, const char *text_id);
+
+/**
+ * Free an OID shortener instance
+ *
+ * @param os a `git_oid_shorten` instance
+ */
+GIT_EXTERN(void) git_oid_shorten_free(git_oid_shorten *os);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/oidarray.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/oidarray.h
new file mode 100755
index 0000000..0b32045
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/oidarray.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_oidarray_h__
+#define INCLUDE_git_oidarray_h__
+
+#include "common.h"
+#include "oid.h"
+
+GIT_BEGIN_DECL
+
+/** Array of object ids */
+typedef struct git_oidarray {
+	git_oid *ids;
+	size_t count;
+} git_oidarray;
+
+/**
+ * Free the OID array
+ *
+ * This method must (and must only) be called on `git_oidarray`
+ * objects where the array is allocated by the library. Not doing so,
+ * will result in a memory leak.
+ *
+ * This does not free the `git_oidarray` itself, since the library will
+ * never allocate that object directly itself (it is more commonly embedded
+ * inside another struct or created on the stack).
+ *
+ * @param array git_oidarray from which to free oid data
+ */
+GIT_EXTERN(void) git_oidarray_free(git_oidarray *array);
+
+/** @} */
+GIT_END_DECL
+
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/pack.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/pack.h
new file mode 100755
index 0000000..4941998
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/pack.h
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_pack_h__
+#define INCLUDE_git_pack_h__
+
+#include "common.h"
+#include "oid.h"
+
+/**
+ * @file git2/pack.h
+ * @brief Git pack management routines
+ *
+ * Packing objects
+ * ---------------
+ *
+ * Creation of packfiles requires two steps:
+ *
+ * - First, insert all the objects you want to put into the packfile
+ *   using `git_packbuilder_insert` and `git_packbuilder_insert_tree`.
+ *   It's important to add the objects in recency order ("in the order
+ *   that they are 'reachable' from head").
+ *
+ *   "ANY order will give you a working pack, ... [but it is] the thing
+ *   that gives packs good locality. It keeps the objects close to the
+ *   head (whether they are old or new, but they are _reachable_ from the
+ *   head) at the head of the pack. So packs actually have absolutely
+ *   _wonderful_ IO patterns." - Linus Torvalds
+ *   git.git/Documentation/technical/pack-heuristics.txt
+ *
+ * - Second, use `git_packbuilder_write` or `git_packbuilder_foreach` to
+ *   write the resulting packfile.
+ *
+ *   libgit2 will take care of the delta ordering and generation.
+ *   `git_packbuilder_set_threads` can be used to adjust the number of
+ *   threads used for the process.
+ *
+ * See tests/pack/packbuilder.c for an example.
+ *
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Stages that are reported by the packbuilder progress callback.
+ */
+typedef enum {
+	GIT_PACKBUILDER_ADDING_OBJECTS = 0,
+	GIT_PACKBUILDER_DELTAFICATION = 1,
+} git_packbuilder_stage_t;
+
+/**
+ * Initialize a new packbuilder
+ *
+ * @param out The new packbuilder object
+ * @param repo The repository
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_new(git_packbuilder **out, git_repository *repo);
+
+/**
+ * Set number of threads to spawn
+ *
+ * By default, libgit2 won't spawn any threads at all;
+ * when set to 0, libgit2 will autodetect the number of
+ * CPUs.
+ *
+ * @param pb The packbuilder
+ * @param n Number of threads to spawn
+ * @return number of actual threads to be used
+ */
+GIT_EXTERN(unsigned int) git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n);
+
+/**
+ * Insert a single object
+ *
+ * For an optimal pack it's mandatory to insert objects in recency order,
+ * commits followed by trees and blobs.
+ *
+ * @param pb The packbuilder
+ * @param id The oid of the commit
+ * @param name The name; might be NULL
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_insert(git_packbuilder *pb, const git_oid *id, const char *name);
+
+/**
+ * Insert a root tree object
+ *
+ * This will add the tree as well as all referenced trees and blobs.
+ *
+ * @param pb The packbuilder
+ * @param id The oid of the root tree
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid *id);
+
+/**
+ * Insert a commit object
+ *
+ * This will add a commit as well as the completed referenced tree.
+ *
+ * @param pb The packbuilder
+ * @param id The oid of the commit
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid *id);
+
+/**
+ * Insert objects as given by the walk
+ *
+ * Those commits and all objects they reference will be inserted into
+ * the packbuilder.
+ *
+ * @param pb the packbuilder
+ * @param walk the revwalk to use to fill the packbuilder
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_insert_walk(git_packbuilder *pb, git_revwalk *walk);
+
+/**
+ * Recursively insert an object and its referenced objects
+ *
+ * Insert the object as well as any object it references.
+ *
+ * @param pb the packbuilder
+ * @param id the id of the root object to insert
+ * @param name optional name for the object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_insert_recur(git_packbuilder *pb, const git_oid *id, const char *name);
+
+/**
+ * Write the contents of the packfile to an in-memory buffer
+ *
+ * The contents of the buffer will become a valid packfile, even though there
+ * will be no attached index
+ *
+ * @param buf Buffer where to write the packfile
+ * @param pb The packbuilder
+ */
+GIT_EXTERN(int) git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb);
+
+/**
+ * Write the new pack and corresponding index file to path.
+ *
+ * @param pb The packbuilder
+ * @param path to the directory where the packfile and index should be stored
+ * @param mode permissions to use creating a packfile or 0 for defaults
+ * @param progress_cb function to call with progress information from the indexer (optional)
+ * @param progress_cb_payload payload for the progress callback (optional)
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_write(
+	git_packbuilder *pb,
+	const char *path,
+	unsigned int mode,
+	git_transfer_progress_cb progress_cb,
+	void *progress_cb_payload);
+
+/**
+* Get the packfile's hash
+*
+* A packfile's name is derived from the sorted hashing of all object
+* names. This is only correct after the packfile has been written.
+*
+* @param pb The packbuilder object
+*/
+GIT_EXTERN(const git_oid *) git_packbuilder_hash(git_packbuilder *pb);
+
+typedef int (*git_packbuilder_foreach_cb)(void *buf, size_t size, void *payload);
+
+/**
+ * Create the new pack and pass each object to the callback
+ *
+ * @param pb the packbuilder
+ * @param cb the callback to call with each packed object's buffer
+ * @param payload the callback's data
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_foreach(git_packbuilder *pb, git_packbuilder_foreach_cb cb, void *payload);
+
+/**
+ * Get the total number of objects the packbuilder will write out
+ *
+ * @param pb the packbuilder
+ * @return the number of objects in the packfile
+ */
+GIT_EXTERN(uint32_t) git_packbuilder_object_count(git_packbuilder *pb);
+
+/**
+ * Get the number of objects the packbuilder has already written out
+ *
+ * @param pb the packbuilder
+ * @return the number of objects which have already been written
+ */
+GIT_EXTERN(uint32_t) git_packbuilder_written(git_packbuilder *pb);
+
+/** Packbuilder progress notification function */
+typedef int (*git_packbuilder_progress)(
+	int stage,
+	unsigned int current,
+	unsigned int total,
+	void *payload);
+
+/**
+ * Set the callbacks for a packbuilder
+ *
+ * @param pb The packbuilder object
+ * @param progress_cb Function to call with progress information during
+ * pack building. Be aware that this is called inline with pack building
+ * operations, so performance may be affected.
+ * @param progress_cb_payload Payload for progress callback.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_packbuilder_set_callbacks(
+	git_packbuilder *pb,
+	git_packbuilder_progress progress_cb,
+	void *progress_cb_payload);
+
+/**
+ * Free the packbuilder and all associated data
+ *
+ * @param pb The packbuilder
+ */
+GIT_EXTERN(void) git_packbuilder_free(git_packbuilder *pb);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/patch.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/patch.h
new file mode 100755
index 0000000..790cb74
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/patch.h
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_patch_h__
+#define INCLUDE_git_patch_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "diff.h"
+
+/**
+ * @file git2/patch.h
+ * @brief Patch handling routines.
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * The diff patch is used to store all the text diffs for a delta.
+ *
+ * You can easily loop over the content of patches and get information about
+ * them.
+ */
+typedef struct git_patch git_patch;
+
+/**
+ * Return a patch for an entry in the diff list.
+ *
+ * The `git_patch` is a newly created object contains the text diffs
+ * for the delta.  You have to call `git_patch_free()` when you are
+ * done with it.  You can use the patch object to loop over all the hunks
+ * and lines in the diff of the one delta.
+ *
+ * For an unchanged file or a binary file, no `git_patch` will be
+ * created, the output will be set to NULL, and the `binary` flag will be
+ * set true in the `git_diff_delta` structure.
+ *
+ * It is okay to pass NULL for either of the output parameters; if you pass
+ * NULL for the `git_patch`, then the text diff will not be calculated.
+ *
+ * @param out Output parameter for the delta patch object
+ * @param diff Diff list object
+ * @param idx Index into diff list
+ * @return 0 on success, other value < 0 on error
+ */
+GIT_EXTERN(int) git_patch_from_diff(
+	git_patch **out, git_diff *diff, size_t idx);
+
+/**
+ * Directly generate a patch from the difference between two blobs.
+ *
+ * This is just like `git_diff_blobs()` except it generates a patch object
+ * for the difference instead of directly making callbacks.  You can use the
+ * standard `git_patch` accessor functions to read the patch data, and
+ * you must call `git_patch_free()` on the patch when done.
+ *
+ * @param out The generated patch; NULL on error
+ * @param old_blob Blob for old side of diff, or NULL for empty blob
+ * @param old_as_path Treat old blob as if it had this filename; can be NULL
+ * @param new_blob Blob for new side of diff, or NULL for empty blob
+ * @param new_as_path Treat new blob as if it had this filename; can be NULL
+ * @param opts Options for diff, or NULL for default options
+ * @return 0 on success or error code < 0
+ */
+GIT_EXTERN(int) git_patch_from_blobs(
+	git_patch **out,
+	const git_blob *old_blob,
+	const char *old_as_path,
+	const git_blob *new_blob,
+	const char *new_as_path,
+	const git_diff_options *opts);
+
+/**
+ * Directly generate a patch from the difference between a blob and a buffer.
+ *
+ * This is just like `git_diff_blob_to_buffer()` except it generates a patch
+ * object for the difference instead of directly making callbacks.  You can
+ * use the standard `git_patch` accessor functions to read the patch
+ * data, and you must call `git_patch_free()` on the patch when done.
+ *
+ * @param out The generated patch; NULL on error
+ * @param old_blob Blob for old side of diff, or NULL for empty blob
+ * @param old_as_path Treat old blob as if it had this filename; can be NULL
+ * @param buffer Raw data for new side of diff, or NULL for empty
+ * @param buffer_len Length of raw data for new side of diff
+ * @param buffer_as_path Treat buffer as if it had this filename; can be NULL
+ * @param opts Options for diff, or NULL for default options
+ * @return 0 on success or error code < 0
+ */
+GIT_EXTERN(int) git_patch_from_blob_and_buffer(
+	git_patch **out,
+	const git_blob *old_blob,
+	const char *old_as_path,
+	const char *buffer,
+	size_t buffer_len,
+	const char *buffer_as_path,
+	const git_diff_options *opts);
+
+/**
+ * Directly generate a patch from the difference between two buffers.
+ *
+ * This is just like `git_diff_buffers()` except it generates a patch
+ * object for the difference instead of directly making callbacks.  You can
+ * use the standard `git_patch` accessor functions to read the patch
+ * data, and you must call `git_patch_free()` on the patch when done.
+ *
+ * @param out The generated patch; NULL on error
+ * @param old_buffer Raw data for old side of diff, or NULL for empty
+ * @param old_len Length of the raw data for old side of the diff
+ * @param old_as_path Treat old buffer as if it had this filename; can be NULL
+ * @param new_buffer Raw data for new side of diff, or NULL for empty
+ * @param new_len Length of raw data for new side of diff
+ * @param new_as_path Treat buffer as if it had this filename; can be NULL
+ * @param opts Options for diff, or NULL for default options
+ * @return 0 on success or error code < 0
+ */
+GIT_EXTERN(int) git_patch_from_buffers(
+	git_patch **out,
+	const void *old_buffer,
+	size_t old_len,
+	const char *old_as_path,
+	const char *new_buffer,
+	size_t new_len,
+	const char *new_as_path,
+	const git_diff_options *opts);
+
+/**
+ * Free a git_patch object.
+ */
+GIT_EXTERN(void) git_patch_free(git_patch *patch);
+
+/**
+ * Get the delta associated with a patch.  This delta points to internal
+ * data and you do not have to release it when you are done with it.
+ */
+GIT_EXTERN(const git_diff_delta *) git_patch_get_delta(const git_patch *patch);
+
+/**
+ * Get the number of hunks in a patch
+ */
+GIT_EXTERN(size_t) git_patch_num_hunks(const git_patch *patch);
+
+/**
+ * Get line counts of each type in a patch.
+ *
+ * This helps imitate a diff --numstat type of output.  For that purpose,
+ * you only need the `total_additions` and `total_deletions` values, but we
+ * include the `total_context` line count in case you want the total number
+ * of lines of diff output that will be generated.
+ *
+ * All outputs are optional. Pass NULL if you don't need a particular count.
+ *
+ * @param total_context Count of context lines in output, can be NULL.
+ * @param total_additions Count of addition lines in output, can be NULL.
+ * @param total_deletions Count of deletion lines in output, can be NULL.
+ * @param patch The git_patch object
+ * @return 0 on success, <0 on error
+ */
+GIT_EXTERN(int) git_patch_line_stats(
+	size_t *total_context,
+	size_t *total_additions,
+	size_t *total_deletions,
+	const git_patch *patch);
+
+/**
+ * Get the information about a hunk in a patch
+ *
+ * Given a patch and a hunk index into the patch, this returns detailed
+ * information about that hunk.  Any of the output pointers can be passed
+ * as NULL if you don't care about that particular piece of information.
+ *
+ * @param out Output pointer to git_diff_hunk of hunk
+ * @param lines_in_hunk Output count of total lines in this hunk
+ * @param patch Input pointer to patch object
+ * @param hunk_idx Input index of hunk to get information about
+ * @return 0 on success, GIT_ENOTFOUND if hunk_idx out of range, <0 on error
+ */
+GIT_EXTERN(int) git_patch_get_hunk(
+	const git_diff_hunk **out,
+	size_t *lines_in_hunk,
+	git_patch *patch,
+	size_t hunk_idx);
+
+/**
+ * Get the number of lines in a hunk.
+ *
+ * @param patch The git_patch object
+ * @param hunk_idx Index of the hunk
+ * @return Number of lines in hunk or -1 if invalid hunk index
+ */
+GIT_EXTERN(int) git_patch_num_lines_in_hunk(
+	const git_patch *patch,
+	size_t hunk_idx);
+
+/**
+ * Get data about a line in a hunk of a patch.
+ *
+ * Given a patch, a hunk index, and a line index in the hunk, this
+ * will return a lot of details about that line.  If you pass a hunk
+ * index larger than the number of hunks or a line index larger than
+ * the number of lines in the hunk, this will return -1.
+ *
+ * @param out The git_diff_line data for this line
+ * @param patch The patch to look in
+ * @param hunk_idx The index of the hunk
+ * @param line_of_hunk The index of the line in the hunk
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_patch_get_line_in_hunk(
+	const git_diff_line **out,
+	git_patch *patch,
+	size_t hunk_idx,
+	size_t line_of_hunk);
+
+/**
+ * Look up size of patch diff data in bytes
+ *
+ * This returns the raw size of the patch data.  This only includes the
+ * actual data from the lines of the diff, not the file or hunk headers.
+ *
+ * If you pass `include_context` as true (non-zero), this will be the size
+ * of all of the diff output; if you pass it as false (zero), this will
+ * only include the actual changed lines (as if `context_lines` was 0).
+ *
+ * @param patch A git_patch representing changes to one file
+ * @param include_context Include context lines in size if non-zero
+ * @param include_hunk_headers Include hunk header lines if non-zero
+ * @param include_file_headers Include file header lines if non-zero
+ * @return The number of bytes of data
+ */
+GIT_EXTERN(size_t) git_patch_size(
+	git_patch *patch,
+	int include_context,
+	int include_hunk_headers,
+	int include_file_headers);
+
+/**
+ * Serialize the patch to text via callback.
+ *
+ * Returning a non-zero value from the callback will terminate the iteration
+ * and return that value to the caller.
+ *
+ * @param patch A git_patch representing changes to one file
+ * @param print_cb Callback function to output lines of the patch.  Will be
+ *                 called for file headers, hunk headers, and diff lines.
+ * @param payload Reference pointer that will be passed to your callbacks.
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_patch_print(
+	git_patch *patch,
+	git_diff_line_cb print_cb,
+	void *payload);
+
+/**
+ * Get the content of a patch as a single diff text.
+ *
+ * @param out The git_buf to be filled in
+ * @param patch A git_patch representing changes to one file
+ * @return 0 on success, <0 on failure.
+ */
+GIT_EXTERN(int) git_patch_to_buf(
+	git_buf *out,
+	git_patch *patch);
+
+GIT_END_DECL
+
+/**@}*/
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/pathspec.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/pathspec.h
new file mode 100755
index 0000000..de6f027
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/pathspec.h
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_pathspec_h__
+#define INCLUDE_git_pathspec_h__
+
+#include "common.h"
+#include "types.h"
+#include "strarray.h"
+#include "diff.h"
+
+GIT_BEGIN_DECL
+
+/**
+ * Compiled pathspec
+ */
+typedef struct git_pathspec git_pathspec;
+
+/**
+ * List of filenames matching a pathspec
+ */
+typedef struct git_pathspec_match_list git_pathspec_match_list;
+
+/**
+ * Options controlling how pathspec match should be executed
+ *
+ * - GIT_PATHSPEC_IGNORE_CASE forces match to ignore case; otherwise
+ *   match will use native case sensitivity of platform filesystem
+ * - GIT_PATHSPEC_USE_CASE forces case sensitive match; otherwise
+ *   match will use native case sensitivity of platform filesystem
+ * - GIT_PATHSPEC_NO_GLOB disables glob patterns and just uses simple
+ *   string comparison for matching
+ * - GIT_PATHSPEC_NO_MATCH_ERROR means the match functions return error
+ *   code GIT_ENOTFOUND if no matches are found; otherwise no matches is
+ *   still success (return 0) but `git_pathspec_match_list_entrycount`
+ *   will indicate 0 matches.
+ * - GIT_PATHSPEC_FIND_FAILURES means that the `git_pathspec_match_list`
+ *   should track which patterns matched which files so that at the end of
+ *   the match we can identify patterns that did not match any files.
+ * - GIT_PATHSPEC_FAILURES_ONLY means that the `git_pathspec_match_list`
+ *   does not need to keep the actual matching filenames.  Use this to
+ *   just test if there were any matches at all or in combination with
+ *   GIT_PATHSPEC_FIND_FAILURES to validate a pathspec.
+ */
+typedef enum {
+	GIT_PATHSPEC_DEFAULT        = 0,
+	GIT_PATHSPEC_IGNORE_CASE    = (1u << 0),
+	GIT_PATHSPEC_USE_CASE       = (1u << 1),
+	GIT_PATHSPEC_NO_GLOB        = (1u << 2),
+	GIT_PATHSPEC_NO_MATCH_ERROR = (1u << 3),
+	GIT_PATHSPEC_FIND_FAILURES  = (1u << 4),
+	GIT_PATHSPEC_FAILURES_ONLY  = (1u << 5),
+} git_pathspec_flag_t;
+
+/**
+ * Compile a pathspec
+ *
+ * @param out Output of the compiled pathspec
+ * @param pathspec A git_strarray of the paths to match
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_pathspec_new(
+	git_pathspec **out, const git_strarray *pathspec);
+
+/**
+ * Free a pathspec
+ *
+ * @param ps The compiled pathspec
+ */
+GIT_EXTERN(void) git_pathspec_free(git_pathspec *ps);
+
+/**
+ * Try to match a path against a pathspec
+ *
+ * Unlike most of the other pathspec matching functions, this will not
+ * fall back on the native case-sensitivity for your platform.  You must
+ * explicitly pass flags to control case sensitivity or else this will
+ * fall back on being case sensitive.
+ *
+ * @param ps The compiled pathspec
+ * @param flags Combination of git_pathspec_flag_t options to control match
+ * @param path The pathname to attempt to match
+ * @return 1 is path matches spec, 0 if it does not
+ */
+GIT_EXTERN(int) git_pathspec_matches_path(
+	const git_pathspec *ps, uint32_t flags, const char *path);
+
+/**
+ * Match a pathspec against the working directory of a repository.
+ *
+ * This matches the pathspec against the current files in the working
+ * directory of the repository.  It is an error to invoke this on a bare
+ * repo.  This handles git ignores (i.e. ignored files will not be
+ * considered to match the `pathspec` unless the file is tracked in the
+ * index).
+ *
+ * If `out` is not NULL, this returns a `git_patchspec_match_list`.  That
+ * contains the list of all matched filenames (unless you pass the
+ * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
+ * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
+ * flag).  You must call `git_pathspec_match_list_free()` on this object.
+ *
+ * @param out Output list of matches; pass NULL to just get return value
+ * @param repo The repository in which to match; bare repo is an error
+ * @param flags Combination of git_pathspec_flag_t options to control match
+ * @param ps Pathspec to be matched
+ * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
+ *         the GIT_PATHSPEC_NO_MATCH_ERROR flag was given
+ */
+GIT_EXTERN(int) git_pathspec_match_workdir(
+	git_pathspec_match_list **out,
+	git_repository *repo,
+	uint32_t flags,
+	git_pathspec *ps);
+
+/**
+ * Match a pathspec against entries in an index.
+ *
+ * This matches the pathspec against the files in the repository index.
+ *
+ * NOTE: At the moment, the case sensitivity of this match is controlled
+ * by the current case-sensitivity of the index object itself and the
+ * USE_CASE and IGNORE_CASE flags will have no effect.  This behavior will
+ * be corrected in a future release.
+ *
+ * If `out` is not NULL, this returns a `git_patchspec_match_list`.  That
+ * contains the list of all matched filenames (unless you pass the
+ * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
+ * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
+ * flag).  You must call `git_pathspec_match_list_free()` on this object.
+ *
+ * @param out Output list of matches; pass NULL to just get return value
+ * @param index The index to match against
+ * @param flags Combination of git_pathspec_flag_t options to control match
+ * @param ps Pathspec to be matched
+ * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
+ *         the GIT_PATHSPEC_NO_MATCH_ERROR flag is used
+ */
+GIT_EXTERN(int) git_pathspec_match_index(
+	git_pathspec_match_list **out,
+	git_index *index,
+	uint32_t flags,
+	git_pathspec *ps);
+
+/**
+ * Match a pathspec against files in a tree.
+ *
+ * This matches the pathspec against the files in the given tree.
+ *
+ * If `out` is not NULL, this returns a `git_patchspec_match_list`.  That
+ * contains the list of all matched filenames (unless you pass the
+ * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
+ * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
+ * flag).  You must call `git_pathspec_match_list_free()` on this object.
+ *
+ * @param out Output list of matches; pass NULL to just get return value
+ * @param tree The root-level tree to match against
+ * @param flags Combination of git_pathspec_flag_t options to control match
+ * @param ps Pathspec to be matched
+ * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
+ *         the GIT_PATHSPEC_NO_MATCH_ERROR flag is used
+ */
+GIT_EXTERN(int) git_pathspec_match_tree(
+	git_pathspec_match_list **out,
+	git_tree *tree,
+	uint32_t flags,
+	git_pathspec *ps);
+
+/**
+ * Match a pathspec against files in a diff list.
+ *
+ * This matches the pathspec against the files in the given diff list.
+ *
+ * If `out` is not NULL, this returns a `git_patchspec_match_list`.  That
+ * contains the list of all matched filenames (unless you pass the
+ * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
+ * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
+ * flag).  You must call `git_pathspec_match_list_free()` on this object.
+ *
+ * @param out Output list of matches; pass NULL to just get return value
+ * @param diff A generated diff list
+ * @param flags Combination of git_pathspec_flag_t options to control match
+ * @param ps Pathspec to be matched
+ * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
+ *         the GIT_PATHSPEC_NO_MATCH_ERROR flag is used
+ */
+GIT_EXTERN(int) git_pathspec_match_diff(
+	git_pathspec_match_list **out,
+	git_diff *diff,
+	uint32_t flags,
+	git_pathspec *ps);
+
+/**
+ * Free memory associates with a git_pathspec_match_list
+ *
+ * @param m The git_pathspec_match_list to be freed
+ */
+GIT_EXTERN(void) git_pathspec_match_list_free(git_pathspec_match_list *m);
+
+/**
+ * Get the number of items in a match list.
+ *
+ * @param m The git_pathspec_match_list object
+ * @return Number of items in match list
+ */
+GIT_EXTERN(size_t) git_pathspec_match_list_entrycount(
+	const git_pathspec_match_list *m);
+
+/**
+ * Get a matching filename by position.
+ *
+ * This routine cannot be used if the match list was generated by
+ * `git_pathspec_match_diff`.  If so, it will always return NULL.
+ *
+ * @param m The git_pathspec_match_list object
+ * @param pos The index into the list
+ * @return The filename of the match
+ */
+GIT_EXTERN(const char *) git_pathspec_match_list_entry(
+	const git_pathspec_match_list *m, size_t pos);
+
+/**
+ * Get a matching diff delta by position.
+ *
+ * This routine can only be used if the match list was generated by
+ * `git_pathspec_match_diff`.  Otherwise it will always return NULL.
+ *
+ * @param m The git_pathspec_match_list object
+ * @param pos The index into the list
+ * @return The filename of the match
+ */
+GIT_EXTERN(const git_diff_delta *) git_pathspec_match_list_diff_entry(
+	const git_pathspec_match_list *m, size_t pos);
+
+/**
+ * Get the number of pathspec items that did not match.
+ *
+ * This will be zero unless you passed GIT_PATHSPEC_FIND_FAILURES when
+ * generating the git_pathspec_match_list.
+ *
+ * @param m The git_pathspec_match_list object
+ * @return Number of items in original pathspec that had no matches
+ */
+GIT_EXTERN(size_t) git_pathspec_match_list_failed_entrycount(
+	const git_pathspec_match_list *m);
+
+/**
+ * Get an original pathspec string that had no matches.
+ *
+ * This will be return NULL for positions out of range.
+ *
+ * @param m The git_pathspec_match_list object
+ * @param pos The index into the failed items
+ * @return The pathspec pattern that didn't match anything
+ */
+GIT_EXTERN(const char *) git_pathspec_match_list_failed_entry(
+	const git_pathspec_match_list *m, size_t pos);
+
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/rebase.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/rebase.h
new file mode 100755
index 0000000..d9aa175
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/rebase.h
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_rebase_h__
+#define INCLUDE_git_rebase_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "annotated_commit.h"
+
+/**
+ * @file git2/rebase.h
+ * @brief Git rebase routines
+ * @defgroup git_rebase Git merge routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Rebase options
+ *
+ * Use to tell the rebase machinery how to operate.
+ */
+typedef struct {
+	unsigned int version;
+
+	/**
+	 * Used by `git_rebase_init`, this will instruct other clients working
+	 * on this rebase that you want a quiet rebase experience, which they
+	 * may choose to provide in an application-specific manner.  This has no
+	 * effect upon libgit2 directly, but is provided for interoperability
+	 * between Git tools.
+	 */
+	int quiet;
+
+	/**
+	 * Used by `git_rebase_finish`, this is the name of the notes reference
+	 * used to rewrite notes for rebased commits when finishing the rebase;
+	 * if NULL, the contents of the coniguration option `notes.rewriteRef`
+	 * is examined, unless the configuration option `notes.rewrite.rebase`
+	 * is set to false.  If `notes.rewriteRef` is also NULL, notes will
+	 * not be rewritten.
+	 */
+	const char *rewrite_notes_ref;
+
+	/**
+	 * Options to control how files are written during `git_rebase_init`,
+	 * `git_checkout_next` and `git_checkout_abort`.  Note that a minimum
+	 * strategy of `GIT_CHECKOUT_SAFE` is defaulted in `init` and `next`,
+	 * and a minimum strategy of `GIT_CHECKOUT_FORCE` is defaulted in
+	 * `abort` to match git semantics.
+	 */
+	git_checkout_options checkout_options;
+} git_rebase_options;
+
+/**
+ * Type of rebase operation in-progress after calling `git_rebase_next`.
+ */
+typedef enum {
+	/**
+	 * The given commit is to be cherry-picked.  The client should commit
+	 * the changes and continue if there are no conflicts.
+	 */
+	GIT_REBASE_OPERATION_PICK = 0,
+
+	/**
+	 * The given commit is to be cherry-picked, but the client should prompt
+	 * the user to provide an updated commit message.
+	 */
+	GIT_REBASE_OPERATION_REWORD,
+
+	/**
+	 * The given commit is to be cherry-picked, but the client should stop
+	 * to allow the user to edit the changes before committing them.
+	 */
+	GIT_REBASE_OPERATION_EDIT,
+
+	/**
+	 * The given commit is to be squashed into the previous commit.  The
+	 * commit message will be merged with the previous message.
+	 */
+	GIT_REBASE_OPERATION_SQUASH,
+
+	/**
+	 * The given commit is to be squashed into the previous commit.  The
+	 * commit message from this commit will be discarded.
+	 */
+	GIT_REBASE_OPERATION_FIXUP,
+
+	/**
+	 * No commit will be cherry-picked.  The client should run the given
+	 * command and (if successful) continue.
+	 */
+	GIT_REBASE_OPERATION_EXEC,
+} git_rebase_operation_t;
+
+#define GIT_REBASE_OPTIONS_VERSION 1
+#define GIT_REBASE_OPTIONS_INIT \
+	{GIT_REBASE_OPTIONS_VERSION, 0, NULL, GIT_CHECKOUT_OPTIONS_INIT}
+
+/** Indicates that a rebase operation is not (yet) in progress. */
+#define GIT_REBASE_NO_OPERATION SIZE_MAX
+
+/**
+ * A rebase operation
+ *
+ * Describes a single instruction/operation to be performed during the
+ * rebase.
+ */
+typedef struct {
+	/** The type of rebase operation. */
+	git_rebase_operation_t type;
+
+	/**
+	 * The commit ID being cherry-picked.  This will be populated for
+	 * all operations except those of type `GIT_REBASE_OPERATION_EXEC`.
+	 */
+	const git_oid id;
+
+	/**
+	 * The executable the user has requested be run.  This will only
+	 * be populated for operations of type `GIT_REBASE_OPERATION_EXEC`.
+	 */
+	const char *exec;
+} git_rebase_operation;
+
+/**
+ * Initializes a `git_rebase_options` with default values. Equivalent to
+ * creating an instance with GIT_REBASE_OPTIONS_INIT.
+ *
+ * @param opts the `git_rebase_options` instance to initialize.
+ * @param version the version of the struct; you should pass
+ *        `GIT_REBASE_OPTIONS_VERSION` here.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_rebase_init_options(
+	git_rebase_options *opts,
+	unsigned int version);
+
+/**
+ * Initializes a rebase operation to rebase the changes in `branch`
+ * relative to `upstream` onto another branch.  To begin the rebase
+ * process, call `git_rebase_next`.  When you have finished with this
+ * object, call `git_rebase_free`.
+ *
+ * @param out Pointer to store the rebase object
+ * @param repo The repository to perform the rebase
+ * @param branch The terminal commit to rebase, or NULL to rebase the
+ *               current branch
+ * @param upstream The commit to begin rebasing from, or NULL to rebase all
+ *                 reachable commits
+ * @param onto The branch to rebase onto, or NULL to rebase onto the given
+ *             upstream
+ * @param opts Options to specify how rebase is performed, or NULL
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_rebase_init(
+	git_rebase **out,
+	git_repository *repo,
+	const git_annotated_commit *branch,
+	const git_annotated_commit *upstream,
+	const git_annotated_commit *onto,
+	const git_rebase_options *opts);
+
+/**
+ * Opens an existing rebase that was previously started by either an
+ * invocation of `git_rebase_init` or by another client.
+ *
+ * @param out Pointer to store the rebase object
+ * @param repo The repository that has a rebase in-progress
+ * @param opts Options to specify how rebase is performed
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_rebase_open(
+	git_rebase **out,
+	git_repository *repo,
+	const git_rebase_options *opts);
+
+/**
+ * Gets the count of rebase operations that are to be applied.
+ *
+ * @param rebase The in-progress rebase
+ * @return The number of rebase operations in total
+ */
+GIT_EXTERN(size_t) git_rebase_operation_entrycount(git_rebase *rebase);
+
+/**
+ * Gets the index of the rebase operation that is currently being applied.
+ * If the first operation has not yet been applied (because you have
+ * called `init` but not yet `next`) then this returns
+ * `GIT_REBASE_NO_OPERATION`.
+ *
+ * @param rebase The in-progress rebase
+ * @return The index of the rebase operation currently being applied.
+ */
+GIT_EXTERN(size_t) git_rebase_operation_current(git_rebase *rebase);
+
+/**
+ * Gets the rebase operation specified by the given index.
+ *
+ * @param rebase The in-progress rebase
+ * @param idx The index of the rebase operation to retrieve
+ * @return The rebase operation or NULL if `idx` was out of bounds
+ */
+GIT_EXTERN(git_rebase_operation *) git_rebase_operation_byindex(
+	git_rebase *rebase,
+	size_t idx);
+
+/**
+ * Performs the next rebase operation and returns the information about it.
+ * If the operation is one that applies a patch (which is any operation except
+ * GIT_REBASE_OPERATION_EXEC) then the patch will be applied and the index and
+ * working directory will be updated with the changes.  If there are conflicts,
+ * you will need to address those before committing the changes.
+ *
+ * @param operation Pointer to store the rebase operation that is to be performed next
+ * @param rebase The rebase in progress
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_rebase_next(
+	git_rebase_operation **operation,
+	git_rebase *rebase);
+
+/**
+ * Commits the current patch.  You must have resolved any conflicts that
+ * were introduced during the patch application from the `git_rebase_next`
+ * invocation.
+ *
+ * @param id Pointer in which to store the OID of the newly created commit
+ * @param rebase The rebase that is in-progress
+ * @param author The author of the updated commit, or NULL to keep the
+ *        author from the original commit
+ * @param committer The committer of the rebase
+ * @param message_encoding The encoding for the message in the commit,
+ *        represented with a standard encoding name.  If message is NULL,
+ *        this should also be NULL, and the encoding from the original
+ *        commit will be maintained.  If message is specified, this may be
+ *        NULL to indicate that "UTF-8" is to be used.
+ * @param message The message for this commit, or NULL to use the message
+ *        from the original commit.
+ * @return Zero on success, GIT_EUNMERGED if there are unmerged changes in
+ *        the index, GIT_EAPPLIED if the current commit has already
+ *        been applied to the upstream and there is nothing to commit,
+ *        -1 on failure.
+ */
+GIT_EXTERN(int) git_rebase_commit(
+	git_oid *id,
+	git_rebase *rebase,
+	const git_signature *author,
+	const git_signature *committer,
+	const char *message_encoding,
+	const char *message);
+
+/**
+ * Aborts a rebase that is currently in progress, resetting the repository
+ * and working directory to their state before rebase began.
+ *
+ * @param rebase The rebase that is in-progress
+ * @return Zero on success; GIT_ENOTFOUND if a rebase is not in progress,
+ *         -1 on other errors.
+ */
+GIT_EXTERN(int) git_rebase_abort(git_rebase *rebase);
+
+/**
+ * Finishes a rebase that is currently in progress once all patches have
+ * been applied.
+ *
+ * @param rebase The rebase that is in-progress
+ * @param signature The identity that is finishing the rebase (optional)
+ * @return Zero on success; -1 on error
+ */
+GIT_EXTERN(int) git_rebase_finish(
+	git_rebase *rebase,
+	const git_signature *signature);
+
+/**
+ * Frees the `git_rebase` object.
+ *
+ * @param rebase The rebase object
+ */
+GIT_EXTERN(void) git_rebase_free(git_rebase *rebase);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/refdb.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/refdb.h
new file mode 100755
index 0000000..a315876
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/refdb.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_refdb_h__
+#define INCLUDE_git_refdb_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "refs.h"
+
+/**
+ * @file git2/refdb.h
+ * @brief Git custom refs backend functions
+ * @defgroup git_refdb Git custom refs backend API
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create a new reference database with no backends.
+ *
+ * Before the Ref DB can be used for read/writing, a custom database
+ * backend must be manually set using `git_refdb_set_backend()`
+ *
+ * @param out location to store the database pointer, if opened.
+ *			Set to NULL if the open failed.
+ * @param repo the repository
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_refdb_new(git_refdb **out, git_repository *repo);
+
+/**
+ * Create a new reference database and automatically add
+ * the default backends:
+ *
+ *  - git_refdb_dir: read and write loose and packed refs
+ *      from disk, assuming the repository dir as the folder
+ *
+ * @param out location to store the database pointer, if opened.
+ *			Set to NULL if the open failed.
+ * @param repo the repository
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_refdb_open(git_refdb **out, git_repository *repo);
+
+/**
+ * Suggests that the given refdb compress or optimize its references.
+ * This mechanism is implementation specific.  For on-disk reference
+ * databases, for example, this may pack all loose references.
+ */
+GIT_EXTERN(int) git_refdb_compress(git_refdb *refdb);
+
+/**
+ * Close an open reference database.
+ *
+ * @param refdb reference database pointer or NULL
+ */
+GIT_EXTERN(void) git_refdb_free(git_refdb *refdb);
+
+/** @} */
+GIT_END_DECL
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/reflog.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/reflog.h
new file mode 100755
index 0000000..c949a28
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/reflog.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_reflog_h__
+#define INCLUDE_git_reflog_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+
+/**
+ * @file git2/reflog.h
+ * @brief Git reflog management routines
+ * @defgroup git_reflog Git reflog management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Read the reflog for the given reference
+ *
+ * If there is no reflog file for the given
+ * reference yet, an empty reflog object will
+ * be returned.
+ *
+ * The reflog must be freed manually by using
+ * git_reflog_free().
+ *
+ * @param out pointer to reflog
+ * @param repo the repostiory
+ * @param name reference to look up
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reflog_read(git_reflog **out, git_repository *repo,  const char *name);
+
+/**
+ * Write an existing in-memory reflog object back to disk
+ * using an atomic file lock.
+ *
+ * @param reflog an existing reflog object
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reflog_write(git_reflog *reflog);
+
+/**
+ * Add a new entry to the in-memory reflog.
+ *
+ * `msg` is optional and can be NULL.
+ *
+ * @param reflog an existing reflog object
+ * @param id the OID the reference is now pointing to
+ * @param committer the signature of the committer
+ * @param msg the reflog message
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reflog_append(git_reflog *reflog, const git_oid *id, const git_signature *committer, const char *msg);
+
+/**
+ * Rename a reflog
+ *
+ * The reflog to be renamed is expected to already exist
+ *
+ * The new name will be checked for validity.
+ * See `git_reference_create_symbolic()` for rules about valid names.
+ *
+ * @param repo the repository
+ * @param old_name the old name of the reference
+ * @param name the new name of the reference
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_reflog_rename(git_repository *repo, const char *old_name, const char *name);
+
+/**
+ * Delete the reflog for the given reference
+ *
+ * @param repo the repository
+ * @param name the reflog to delete
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reflog_delete(git_repository *repo, const char *name);
+
+/**
+ * Get the number of log entries in a reflog
+ *
+ * @param reflog the previously loaded reflog
+ * @return the number of log entries
+ */
+GIT_EXTERN(size_t) git_reflog_entrycount(git_reflog *reflog);
+
+/**
+ * Lookup an entry by its index
+ *
+ * Requesting the reflog entry with an index of 0 (zero) will
+ * return the most recently created entry.
+ *
+ * @param reflog a previously loaded reflog
+ * @param idx the position of the entry to lookup. Should be greater than or
+ * equal to 0 (zero) and less than `git_reflog_entrycount()`.
+ * @return the entry; NULL if not found
+ */
+GIT_EXTERN(const git_reflog_entry *) git_reflog_entry_byindex(const git_reflog *reflog, size_t idx);
+
+/**
+ * Remove an entry from the reflog by its index
+ *
+ * To ensure there's no gap in the log history, set `rewrite_previous_entry`
+ * param value to 1. When deleting entry `n`, member old_oid of entry `n-1`
+ * (if any) will be updated with the value of member new_oid of entry `n+1`.
+ *
+ * @param reflog a previously loaded reflog.
+ *
+ * @param idx the position of the entry to remove. Should be greater than or
+ * equal to 0 (zero) and less than `git_reflog_entrycount()`.
+ *
+ * @param rewrite_previous_entry 1 to rewrite the history; 0 otherwise.
+ *
+ * @return 0 on success, GIT_ENOTFOUND if the entry doesn't exist
+ * or an error code.
+ */
+GIT_EXTERN(int) git_reflog_drop(
+	git_reflog *reflog,
+	size_t idx,
+	int rewrite_previous_entry);
+
+/**
+ * Get the old oid
+ *
+ * @param entry a reflog entry
+ * @return the old oid
+ */
+GIT_EXTERN(const git_oid *) git_reflog_entry_id_old(const git_reflog_entry *entry);
+
+/**
+ * Get the new oid
+ *
+ * @param entry a reflog entry
+ * @return the new oid at this time
+ */
+GIT_EXTERN(const git_oid *) git_reflog_entry_id_new(const git_reflog_entry *entry);
+
+/**
+ * Get the committer of this entry
+ *
+ * @param entry a reflog entry
+ * @return the committer
+ */
+GIT_EXTERN(const git_signature *) git_reflog_entry_committer(const git_reflog_entry *entry);
+
+/**
+ * Get the log message
+ *
+ * @param entry a reflog entry
+ * @return the log msg
+ */
+GIT_EXTERN(const char *) git_reflog_entry_message(const git_reflog_entry *entry);
+
+/**
+ * Free the reflog
+ *
+ * @param reflog reflog to free
+ */
+GIT_EXTERN(void) git_reflog_free(git_reflog *reflog);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/refs.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/refs.h
new file mode 100755
index 0000000..db84ed0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/refs.h
@@ -0,0 +1,735 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_refs_h__
+#define INCLUDE_git_refs_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "strarray.h"
+
+/**
+ * @file git2/refs.h
+ * @brief Git reference management routines
+ * @defgroup git_reference Git reference management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Lookup a reference by name in a repository.
+ *
+ * The returned reference must be freed by the user.
+ *
+ * The name will be checked for validity.
+ * See `git_reference_symbolic_create()` for rules about valid names.
+ *
+ * @param out pointer to the looked-up reference
+ * @param repo the repository to look up the reference
+ * @param name the long name for the reference (e.g. HEAD, refs/heads/master, refs/tags/v0.1.0, ...)
+ * @return 0 on success, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code.
+ */
+GIT_EXTERN(int) git_reference_lookup(git_reference **out, git_repository *repo, const char *name);
+
+/**
+ * Lookup a reference by name and resolve immediately to OID.
+ *
+ * This function provides a quick way to resolve a reference name straight
+ * through to the object id that it refers to.  This avoids having to
+ * allocate or free any `git_reference` objects for simple situations.
+ *
+ * The name will be checked for validity.
+ * See `git_reference_symbolic_create()` for rules about valid names.
+ *
+ * @param out Pointer to oid to be filled in
+ * @param repo The repository in which to look up the reference
+ * @param name The long name for the reference (e.g. HEAD, refs/heads/master, refs/tags/v0.1.0, ...)
+ * @return 0 on success, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code.
+ */
+GIT_EXTERN(int) git_reference_name_to_id(
+	git_oid *out, git_repository *repo, const char *name);
+
+/**
+ * Lookup a reference by DWIMing its short name
+ *
+ * Apply the git precendence rules to the given shorthand to determine
+ * which reference the user is referring to.
+ *
+ * @param out pointer in which to store the reference
+ * @param repo the repository in which to look
+ * @param shorthand the short name for the reference
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_dwim(git_reference **out, git_repository *repo, const char *shorthand);
+
+/**
+ * Conditionally create a new symbolic reference.
+ *
+ * A symbolic reference is a reference name that refers to another
+ * reference name.  If the other name moves, the symbolic name will move,
+ * too.  As a simple example, the "HEAD" reference might refer to
+ * "refs/heads/master" while on the "master" branch of a repository.
+ *
+ * The symbolic reference will be created in the repository and written to
+ * the disk.  The generated reference object must be freed by the user.
+ *
+ * Valid reference names must follow one of two patterns:
+ *
+ * 1. Top-level names must contain only capital letters and underscores,
+ *    and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
+ * 2. Names prefixed with "refs/" can be almost anything.  You must avoid
+ *    the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ *    sequences ".." and "@{" which have special meaning to revparse.
+ *
+ * This function will return an error if a reference already exists with the
+ * given name unless `force` is true, in which case it will be overwritten.
+ *
+ * The message for the reflog will be ignored if the reference does
+ * not belong in the standard set (HEAD, branches and remote-tracking
+ * branches) and it does not have a reflog.
+ *
+ * It will return GIT_EMODIFIED if the reference's value at the time
+ * of updating does not match the one passed through `current_value`
+ * (i.e. if the ref has changed since the user read it).
+ *
+ * @param out Pointer to the newly created reference
+ * @param repo Repository where that reference will live
+ * @param name The name of the reference
+ * @param target The target of the reference
+ * @param force Overwrite existing references
+ * @param current_value The expected value of the reference when updating
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC, GIT_EMODIFIED or an error code
+ */
+GIT_EXTERN(int) git_reference_symbolic_create_matching(git_reference **out, git_repository *repo, const char *name, const char *target, int force, const char *current_value, const char *log_message);
+
+/**
+ * Create a new symbolic reference.
+ *
+ * A symbolic reference is a reference name that refers to another
+ * reference name.  If the other name moves, the symbolic name will move,
+ * too.  As a simple example, the "HEAD" reference might refer to
+ * "refs/heads/master" while on the "master" branch of a repository.
+ *
+ * The symbolic reference will be created in the repository and written to
+ * the disk.  The generated reference object must be freed by the user.
+ *
+ * Valid reference names must follow one of two patterns:
+ *
+ * 1. Top-level names must contain only capital letters and underscores,
+ *    and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
+ * 2. Names prefixed with "refs/" can be almost anything.  You must avoid
+ *    the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ *    sequences ".." and "@{" which have special meaning to revparse.
+ *
+ * This function will return an error if a reference already exists with the
+ * given name unless `force` is true, in which case it will be overwritten.
+ *
+ * The message for the reflog will be ignored if the reference does
+ * not belong in the standard set (HEAD, branches and remote-tracking
+ * branches) and it does not have a reflog.
+ *
+ * @param out Pointer to the newly created reference
+ * @param repo Repository where that reference will live
+ * @param name The name of the reference
+ * @param target The target of the reference
+ * @param force Overwrite existing references
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_reference_symbolic_create(git_reference **out, git_repository *repo, const char *name, const char *target, int force, const char *log_message);
+
+/**
+ * Create a new direct reference.
+ *
+ * A direct reference (also called an object id reference) refers directly
+ * to a specific object id (a.k.a. OID or SHA) in the repository.  The id
+ * permanently refers to the object (although the reference itself can be
+ * moved).  For example, in libgit2 the direct ref "refs/tags/v0.17.0"
+ * refers to OID 5b9fac39d8a76b9139667c26a63e6b3f204b3977.
+ *
+ * The direct reference will be created in the repository and written to
+ * the disk.  The generated reference object must be freed by the user.
+ *
+ * Valid reference names must follow one of two patterns:
+ *
+ * 1. Top-level names must contain only capital letters and underscores,
+ *    and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
+ * 2. Names prefixed with "refs/" can be almost anything.  You must avoid
+ *    the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ *    sequences ".." and "@{" which have special meaning to revparse.
+ *
+ * This function will return an error if a reference already exists with the
+ * given name unless `force` is true, in which case it will be overwritten.
+ *
+ * The message for the reflog will be ignored if the reference does
+ * not belong in the standard set (HEAD, branches and remote-tracking
+ * branches) and and it does not have a reflog.
+ *
+ * @param out Pointer to the newly created reference
+ * @param repo Repository where that reference will live
+ * @param name The name of the reference
+ * @param id The object id pointed to by the reference.
+ * @param force Overwrite existing references
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force, const char *log_message);
+
+/**
+ * Conditionally create new direct reference
+ *
+ * A direct reference (also called an object id reference) refers directly
+ * to a specific object id (a.k.a. OID or SHA) in the repository.  The id
+ * permanently refers to the object (although the reference itself can be
+ * moved).  For example, in libgit2 the direct ref "refs/tags/v0.17.0"
+ * refers to OID 5b9fac39d8a76b9139667c26a63e6b3f204b3977.
+ *
+ * The direct reference will be created in the repository and written to
+ * the disk.  The generated reference object must be freed by the user.
+ *
+ * Valid reference names must follow one of two patterns:
+ *
+ * 1. Top-level names must contain only capital letters and underscores,
+ *    and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
+ * 2. Names prefixed with "refs/" can be almost anything.  You must avoid
+ *    the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ *    sequences ".." and "@{" which have special meaning to revparse.
+ *
+ * This function will return an error if a reference already exists with the
+ * given name unless `force` is true, in which case it will be overwritten.
+ *
+ * The message for the reflog will be ignored if the reference does
+ * not belong in the standard set (HEAD, branches and remote-tracking
+ * branches) and and it does not have a reflog.
+ *
+ * It will return GIT_EMODIFIED if the reference's value at the time
+ * of updating does not match the one passed through `current_id`
+ * (i.e. if the ref has changed since the user read it).
+ *
+ * @param out Pointer to the newly created reference
+ * @param repo Repository where that reference will live
+ * @param name The name of the reference
+ * @param id The object id pointed to by the reference.
+ * @param force Overwrite existing references
+ * @param current_id The expected value of the reference at the time of update
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EMODIFIED if the value of the reference
+ * has changed, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_reference_create_matching(git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force, const git_oid *current_id, const char *log_message);
+
+/**
+ * Get the OID pointed to by a direct reference.
+ *
+ * Only available if the reference is direct (i.e. an object id reference,
+ * not a symbolic one).
+ *
+ * To find the OID of a symbolic ref, call `git_reference_resolve()` and
+ * then this function (or maybe use `git_reference_name_to_id()` to
+ * directly resolve a reference name all the way through to an OID).
+ *
+ * @param ref The reference
+ * @return a pointer to the oid if available, NULL otherwise
+ */
+GIT_EXTERN(const git_oid *) git_reference_target(const git_reference *ref);
+
+/**
+ * Return the peeled OID target of this reference.
+ *
+ * This peeled OID only applies to direct references that point to
+ * a hard Tag object: it is the result of peeling such Tag.
+ *
+ * @param ref The reference
+ * @return a pointer to the oid if available, NULL otherwise
+ */
+GIT_EXTERN(const git_oid *) git_reference_target_peel(const git_reference *ref);
+
+/**
+ * Get full name to the reference pointed to by a symbolic reference.
+ *
+ * Only available if the reference is symbolic.
+ *
+ * @param ref The reference
+ * @return a pointer to the name if available, NULL otherwise
+ */
+GIT_EXTERN(const char *) git_reference_symbolic_target(const git_reference *ref);
+
+/**
+ * Get the type of a reference.
+ *
+ * Either direct (GIT_REF_OID) or symbolic (GIT_REF_SYMBOLIC)
+ *
+ * @param ref The reference
+ * @return the type
+ */
+GIT_EXTERN(git_ref_t) git_reference_type(const git_reference *ref);
+
+/**
+ * Get the full name of a reference.
+ *
+ * See `git_reference_symbolic_create()` for rules about valid names.
+ *
+ * @param ref The reference
+ * @return the full name for the ref
+ */
+GIT_EXTERN(const char *) git_reference_name(const git_reference *ref);
+
+/**
+ * Resolve a symbolic reference to a direct reference.
+ *
+ * This method iteratively peels a symbolic reference until it resolves to
+ * a direct reference to an OID.
+ *
+ * The peeled reference is returned in the `resolved_ref` argument, and
+ * must be freed manually once it's no longer needed.
+ *
+ * If a direct reference is passed as an argument, a copy of that
+ * reference is returned. This copy must be manually freed too.
+ *
+ * @param out Pointer to the peeled reference
+ * @param ref The reference
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_resolve(git_reference **out, const git_reference *ref);
+
+/**
+ * Get the repository where a reference resides.
+ *
+ * @param ref The reference
+ * @return a pointer to the repo
+ */
+GIT_EXTERN(git_repository *) git_reference_owner(const git_reference *ref);
+
+/**
+ * Create a new reference with the same name as the given reference but a
+ * different symbolic target. The reference must be a symbolic reference,
+ * otherwise this will fail.
+ *
+ * The new reference will be written to disk, overwriting the given reference.
+ *
+ * The target name will be checked for validity.
+ * See `git_reference_symbolic_create()` for rules about valid names.
+ *
+ * The message for the reflog will be ignored if the reference does
+ * not belong in the standard set (HEAD, branches and remote-tracking
+ * branches) and and it does not have a reflog.
+ *
+ * @param out Pointer to the newly created reference
+ * @param ref The reference
+ * @param target The new target for the reference
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_reference_symbolic_set_target(
+	git_reference **out,
+	git_reference *ref,
+	const char *target,
+	const char *log_message);
+
+/**
+ * Conditionally create a new reference with the same name as the given reference but a
+ * different OID target. The reference must be a direct reference, otherwise
+ * this will fail.
+ *
+ * The new reference will be written to disk, overwriting the given reference.
+ *
+ * @param out Pointer to the newly created reference
+ * @param ref The reference
+ * @param id The new target OID for the reference
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EMODIFIED if the value of the reference
+ * has changed since it was read, or an error code
+ */
+GIT_EXTERN(int) git_reference_set_target(
+	git_reference **out,
+	git_reference *ref,
+	const git_oid *id,
+	const char *log_message);
+
+/**
+ * Rename an existing reference.
+ *
+ * This method works for both direct and symbolic references.
+ *
+ * The new name will be checked for validity.
+ * See `git_reference_symbolic_create()` for rules about valid names.
+ *
+ * If the `force` flag is not enabled, and there's already
+ * a reference with the given name, the renaming will fail.
+ *
+ * IMPORTANT:
+ * The user needs to write a proper reflog entry if the
+ * reflog is enabled for the repository. We only rename
+ * the reflog if it exists.
+ *
+ * @param ref The reference to rename
+ * @param new_name The new name for the reference
+ * @param force Overwrite an existing reference
+ * @param log_message The one line long message to be appended to the reflog
+ * @return 0 on success, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
+ *
+ */
+GIT_EXTERN(int) git_reference_rename(
+	git_reference **new_ref,
+	git_reference *ref,
+	const char *new_name,
+	int force,
+	const char *log_message);
+
+/**
+ * Delete an existing reference.
+ *
+ * This method works for both direct and symbolic references.  The reference
+ * will be immediately removed on disk but the memory will not be freed.
+ * Callers must call `git_reference_free`.
+ *
+ * This function will return an error if the reference has changed
+ * from the time it was looked up.
+ *
+ * @param ref The reference to remove
+ * @return 0, GIT_EMODIFIED or an error code
+ */
+GIT_EXTERN(int) git_reference_delete(git_reference *ref);
+
+/**
+ * Delete an existing reference by name
+ *
+ * This method removes the named reference from the repository without
+ * looking at its old value.
+ *
+ * @param name The reference to remove
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_remove(git_repository *repo, const char *name);
+
+/**
+ * Fill a list with all the references that can be found in a repository.
+ *
+ * The string array will be filled with the names of all references; these
+ * values are owned by the user and should be free'd manually when no
+ * longer needed, using `git_strarray_free()`.
+ *
+ * @param array Pointer to a git_strarray structure where
+ *		the reference names will be stored
+ * @param repo Repository where to find the refs
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo);
+
+typedef int (*git_reference_foreach_cb)(git_reference *reference, void *payload);
+typedef int (*git_reference_foreach_name_cb)(const char *name, void *payload);
+
+/**
+ * Perform a callback on each reference in the repository.
+ *
+ * The `callback` function will be called for each reference in the
+ * repository, receiving the reference object and the `payload` value
+ * passed to this method.  Returning a non-zero value from the callback
+ * will terminate the iteration.
+ *
+ * @param repo Repository where to find the refs
+ * @param callback Function which will be called for every listed ref
+ * @param payload Additional data to pass to the callback
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_reference_foreach(
+	git_repository *repo,
+	git_reference_foreach_cb callback,
+	void *payload);
+
+/**
+ * Perform a callback on the fully-qualified name of each reference.
+ *
+ * The `callback` function will be called for each reference in the
+ * repository, receiving the name of the reference and the `payload` value
+ * passed to this method.  Returning a non-zero value from the callback
+ * will terminate the iteration.
+ *
+ * @param repo Repository where to find the refs
+ * @param callback Function which will be called for every listed ref name
+ * @param payload Additional data to pass to the callback
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_reference_foreach_name(
+	git_repository *repo,
+	git_reference_foreach_name_cb callback,
+	void *payload);
+
+/**
+ * Free the given reference.
+ *
+ * @param ref git_reference
+ */
+GIT_EXTERN(void) git_reference_free(git_reference *ref);
+
+/**
+ * Compare two references.
+ *
+ * @param ref1 The first git_reference
+ * @param ref2 The second git_reference
+ * @return 0 if the same, else a stable but meaningless ordering.
+ */
+GIT_EXTERN(int) git_reference_cmp(
+	const git_reference *ref1,
+	const git_reference *ref2);
+
+/**
+ * Create an iterator for the repo's references
+ *
+ * @param out pointer in which to store the iterator
+ * @param repo the repository
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_iterator_new(
+	git_reference_iterator **out,
+	git_repository *repo);
+
+/**
+ * Create an iterator for the repo's references that match the
+ * specified glob
+ *
+ * @param out pointer in which to store the iterator
+ * @param repo the repository
+ * @param glob the glob to match against the reference names
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_iterator_glob_new(
+	git_reference_iterator **out,
+	git_repository *repo,
+	const char *glob);
+
+/**
+ * Get the next reference
+ *
+ * @param out pointer in which to store the reference
+ * @param iter the iterator
+ * @return 0, GIT_ITEROVER if there are no more; or an error code
+ */
+GIT_EXTERN(int) git_reference_next(git_reference **out, git_reference_iterator *iter);
+
+/**
+ * Get the next reference's name
+ *
+ * This function is provided for convenience in case only the names
+ * are interesting as it avoids the allocation of the `git_reference`
+ * object which `git_reference_next()` needs.
+ *
+ * @param out pointer in which to store the string
+ * @param iter the iterator
+ * @return 0, GIT_ITEROVER if there are no more; or an error code
+ */
+GIT_EXTERN(int) git_reference_next_name(const char **out, git_reference_iterator *iter);
+
+/**
+ * Free the iterator and its associated resources
+ *
+ * @param iter the iterator to free
+ */
+GIT_EXTERN(void) git_reference_iterator_free(git_reference_iterator *iter);
+
+/**
+ * Perform a callback on each reference in the repository whose name
+ * matches the given pattern.
+ *
+ * This function acts like `git_reference_foreach()` with an additional
+ * pattern match being applied to the reference name before issuing the
+ * callback function.  See that function for more information.
+ *
+ * The pattern is matched using fnmatch or "glob" style where a '*' matches
+ * any sequence of letters, a '?' matches any letter, and square brackets
+ * can be used to define character ranges (such as "[0-9]" for digits).
+ *
+ * @param repo Repository where to find the refs
+ * @param glob Pattern to match (fnmatch-style) against reference name.
+ * @param callback Function which will be called for every listed ref
+ * @param payload Additional data to pass to the callback
+ * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ */
+GIT_EXTERN(int) git_reference_foreach_glob(
+	git_repository *repo,
+	const char *glob,
+	git_reference_foreach_name_cb callback,
+	void *payload);
+
+/**
+ * Check if a reflog exists for the specified reference.
+ *
+ * @param repo the repository
+ * @param refname the reference's name
+ * @return 0 when no reflog can be found, 1 when it exists;
+ * otherwise an error code.
+ */
+GIT_EXTERN(int) git_reference_has_log(git_repository *repo, const char *refname);
+
+/**
+ * Ensure there is a reflog for a particular reference.
+ *
+ * Make sure that successive updates to the reference will append to
+ * its log.
+ *
+ * @param repo the repository
+ * @param refname the reference's name
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_reference_ensure_log(git_repository *repo, const char *refname);
+
+/**
+ * Check if a reference is a local branch.
+ *
+ * @param ref A git reference
+ *
+ * @return 1 when the reference lives in the refs/heads
+ * namespace; 0 otherwise.
+ */
+GIT_EXTERN(int) git_reference_is_branch(const git_reference *ref);
+
+/**
+ * Check if a reference is a remote tracking branch
+ *
+ * @param ref A git reference
+ *
+ * @return 1 when the reference lives in the refs/remotes
+ * namespace; 0 otherwise.
+ */
+GIT_EXTERN(int) git_reference_is_remote(const git_reference *ref);
+
+/**
+ * Check if a reference is a tag
+ *
+ * @param ref A git reference
+ *
+ * @return 1 when the reference lives in the refs/tags
+ * namespace; 0 otherwise.
+ */
+GIT_EXTERN(int) git_reference_is_tag(const git_reference *ref);
+
+/**
+ * Check if a reference is a note
+ *
+ * @param ref A git reference
+ *
+ * @return 1 when the reference lives in the refs/notes
+ * namespace; 0 otherwise.
+ */
+GIT_EXTERN(int) git_reference_is_note(const git_reference *ref);
+
+/**
+ * Normalization options for reference lookup
+ */
+typedef enum {
+	/**
+	 * No particular normalization.
+	 */
+	GIT_REF_FORMAT_NORMAL = 0u,
+
+	/**
+	 * Control whether one-level refnames are accepted
+	 * (i.e., refnames that do not contain multiple /-separated
+	 * components). Those are expected to be written only using
+	 * uppercase letters and underscore (FETCH_HEAD, ...)
+	 */
+	GIT_REF_FORMAT_ALLOW_ONELEVEL = (1u << 0),
+
+	/**
+	 * Interpret the provided name as a reference pattern for a
+	 * refspec (as used with remote repositories). If this option
+	 * is enabled, the name is allowed to contain a single * (<star>)
+	 * in place of a one full pathname component
+	 * (e.g., foo/<star>/bar but not foo/bar<star>).
+	 */
+	GIT_REF_FORMAT_REFSPEC_PATTERN = (1u << 1),
+
+	/**
+	 * Interpret the name as part of a refspec in shorthand form
+	 * so the `ONELEVEL` naming rules aren't enforced and 'master'
+	 * becomes a valid name.
+	 */
+	GIT_REF_FORMAT_REFSPEC_SHORTHAND = (1u << 2),
+} git_reference_normalize_t;
+
+/**
+ * Normalize reference name and check validity.
+ *
+ * This will normalize the reference name by removing any leading slash
+ * '/' characters and collapsing runs of adjacent slashes between name
+ * components into a single slash.
+ *
+ * Once normalized, if the reference name is valid, it will be returned in
+ * the user allocated buffer.
+ *
+ * See `git_reference_symbolic_create()` for rules about valid names.
+ *
+ * @param buffer_out User allocated buffer to store normalized name
+ * @param buffer_size Size of buffer_out
+ * @param name Reference name to be checked.
+ * @param flags Flags to constrain name validation rules - see the
+ *              GIT_REF_FORMAT constants above.
+ * @return 0 on success, GIT_EBUFS if buffer is too small, GIT_EINVALIDSPEC
+ * or an error code.
+ */
+GIT_EXTERN(int) git_reference_normalize_name(
+	char *buffer_out,
+	size_t buffer_size,
+	const char *name,
+	unsigned int flags);
+
+/**
+ * Recursively peel reference until object of the specified type is found.
+ *
+ * The retrieved `peeled` object is owned by the repository
+ * and should be closed with the `git_object_free` method.
+ *
+ * If you pass `GIT_OBJ_ANY` as the target type, then the object
+ * will be peeled until a non-tag object is met.
+ *
+ * @param out Pointer to the peeled git_object
+ * @param ref The reference to be processed
+ * @param type The type of the requested object (GIT_OBJ_COMMIT,
+ * GIT_OBJ_TAG, GIT_OBJ_TREE, GIT_OBJ_BLOB or GIT_OBJ_ANY).
+ * @return 0 on success, GIT_EAMBIGUOUS, GIT_ENOTFOUND or an error code
+ */
+GIT_EXTERN(int) git_reference_peel(
+	git_object **out,
+	git_reference *ref,
+	git_otype type);
+
+/**
+ * Ensure the reference name is well-formed.
+ *
+ * Valid reference names must follow one of two patterns:
+ *
+ * 1. Top-level names must contain only capital letters and underscores,
+ *    and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
+ * 2. Names prefixed with "refs/" can be almost anything.  You must avoid
+ *    the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ *    sequences ".." and "@{" which have special meaning to revparse.
+ *
+ * @param refname name to be checked.
+ * @return 1 if the reference name is acceptable; 0 if it isn't
+ */
+GIT_EXTERN(int) git_reference_is_valid_name(const char *refname);
+
+/**
+ * Get the reference's short name
+ *
+ * This will transform the reference name into a name "human-readable"
+ * version. If no shortname is appropriate, it will return the full
+ * name.
+ *
+ * The memory is owned by the reference and must not be freed.
+ *
+ * @param ref a reference
+ * @return the human-readable version of the name
+ */
+GIT_EXTERN(const char *) git_reference_shorthand(const git_reference *ref);
+
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/refspec.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/refspec.h
new file mode 100755
index 0000000..9acdc72
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/refspec.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_refspec_h__
+#define INCLUDE_git_refspec_h__
+
+#include "common.h"
+#include "types.h"
+#include "net.h"
+#include "buffer.h"
+
+/**
+ * @file git2/refspec.h
+ * @brief Git refspec attributes
+ * @defgroup git_refspec Git refspec attributes
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Get the source specifier
+ *
+ * @param refspec the refspec
+ * @return the refspec's source specifier
+ */
+GIT_EXTERN(const char *) git_refspec_src(const git_refspec *refspec);
+
+/**
+ * Get the destination specifier
+ *
+ * @param refspec the refspec
+ * @return the refspec's destination specifier
+ */
+GIT_EXTERN(const char *) git_refspec_dst(const git_refspec *refspec);
+
+/**
+ * Get the refspec's string
+ *
+ * @param refspec the refspec
+ * @returns the refspec's original string
+ */
+GIT_EXTERN(const char *) git_refspec_string(const git_refspec *refspec);
+
+/**
+ * Get the force update setting
+ *
+ * @param refspec the refspec
+ * @return 1 if force update has been set, 0 otherwise
+ */
+GIT_EXTERN(int) git_refspec_force(const git_refspec *refspec);
+
+/**
+ * Get the refspec's direction.
+ *
+ * @param spec refspec
+ * @return GIT_DIRECTION_FETCH or GIT_DIRECTION_PUSH
+ */
+GIT_EXTERN(git_direction) git_refspec_direction(const git_refspec *spec);
+
+/**
+ * Check if a refspec's source descriptor matches a reference 
+ *
+ * @param refspec the refspec
+ * @param refname the name of the reference to check
+ * @return 1 if the refspec matches, 0 otherwise
+ */
+GIT_EXTERN(int) git_refspec_src_matches(const git_refspec *refspec, const char *refname);
+
+/**
+ * Check if a refspec's destination descriptor matches a reference
+ *
+ * @param refspec the refspec
+ * @param refname the name of the reference to check
+ * @return 1 if the refspec matches, 0 otherwise
+ */
+GIT_EXTERN(int) git_refspec_dst_matches(const git_refspec *refspec, const char *refname);
+
+/**
+ * Transform a reference to its target following the refspec's rules
+ *
+ * @param out where to store the target name
+ * @param spec the refspec
+ * @param name the name of the reference to transform
+ * @return 0, GIT_EBUFS or another error
+ */
+GIT_EXTERN(int) git_refspec_transform(git_buf *out, const git_refspec *spec, const char *name);
+
+/**
+ * Transform a target reference to its source reference following the refspec's rules
+ *
+ * @param out where to store the source reference name
+ * @param spec the refspec
+ * @param name the name of the reference to transform
+ * @return 0, GIT_EBUFS or another error
+ */
+GIT_EXTERN(int) git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name);
+
+GIT_END_DECL
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/remote.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/remote.h
new file mode 100755
index 0000000..444fe52
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/remote.h
@@ -0,0 +1,800 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_remote_h__
+#define INCLUDE_git_remote_h__
+
+#include "common.h"
+#include "repository.h"
+#include "refspec.h"
+#include "net.h"
+#include "indexer.h"
+#include "strarray.h"
+#include "transport.h"
+#include "pack.h"
+
+/**
+ * @file git2/remote.h
+ * @brief Git remote management functions
+ * @defgroup git_remote remote management functions
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+typedef int (*git_remote_rename_problem_cb)(const char *problematic_refspec, void *payload);
+
+/**
+ * Add a remote with the default fetch refspec to the repository's configuration.
+ *
+ * @param out the resulting remote
+ * @param repo the repository in which to create the remote
+ * @param name the remote's name
+ * @param url the remote's url
+ * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
+ */
+GIT_EXTERN(int) git_remote_create(
+		git_remote **out,
+		git_repository *repo,
+		const char *name,
+		const char *url);
+
+/**
+ * Add a remote with the provided fetch refspec (or default if NULL) to the repository's
+ * configuration.
+ *
+ * @param out the resulting remote
+ * @param repo the repository in which to create the remote
+ * @param name the remote's name
+ * @param url the remote's url
+ * @param fetch the remote fetch value
+ * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
+ */
+GIT_EXTERN(int) git_remote_create_with_fetchspec(
+		git_remote **out,
+		git_repository *repo,
+		const char *name,
+		const char *url,
+		const char *fetch);
+
+/**
+ * Create an anonymous remote
+ *
+ * Create a remote with the given url in-memory. You can use this when
+ * you have a URL instead of a remote's name.
+ *
+ * @param out pointer to the new remote objects
+ * @param repo the associated repository
+ * @param url the remote repository's URL
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_create_anonymous(
+		git_remote **out,
+		git_repository *repo,
+		const char *url);
+
+/**
+ * Get the information for a particular remote
+ *
+ * The name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
+ *
+ * @param out pointer to the new remote object
+ * @param repo the associated repository
+ * @param name the remote's name
+ * @return 0, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_remote_lookup(git_remote **out, git_repository *repo, const char *name);
+
+/**
+ * Create a copy of an existing remote.  All internal strings are also
+ * duplicated. Callbacks are not duplicated.
+ *
+ * Call `git_remote_free` to free the data.
+ *
+ * @param dest pointer where to store the copy
+ * @param source object to copy
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_dup(git_remote **dest, git_remote *source);
+
+/**
+ * Get the remote's repository
+ *
+ * @param remote the remote
+ * @return a pointer to the repository
+ */
+GIT_EXTERN(git_repository *) git_remote_owner(const git_remote *remote);
+
+/**
+ * Get the remote's name
+ *
+ * @param remote the remote
+ * @return a pointer to the name or NULL for in-memory remotes
+ */
+GIT_EXTERN(const char *) git_remote_name(const git_remote *remote);
+
+/**
+ * Get the remote's url
+ *
+ * If url.*.insteadOf has been configured for this URL, it will
+ * return the modified URL.
+ *
+ * @param remote the remote
+ * @return a pointer to the url
+ */
+GIT_EXTERN(const char *) git_remote_url(const git_remote *remote);
+
+/**
+ * Get the remote's url for pushing
+ *
+ * If url.*.pushInsteadOf has been configured for this URL, it
+ * will return the modified URL.
+ *
+ * @param remote the remote
+ * @return a pointer to the url or NULL if no special url for pushing is set
+ */
+GIT_EXTERN(const char *) git_remote_pushurl(const git_remote *remote);
+
+/**
+ * Set the remote's url in the configuration
+ *
+ * Remote objects already in memory will not be affected. This assumes
+ * the common case of a single-url remote and will otherwise return an error.
+ *
+ * @param repo the repository in which to perform the change
+ * @param remote the remote's name
+ * @param url the url to set
+ * @return 0 or an error value
+ */
+GIT_EXTERN(int) git_remote_set_url(git_repository *repo, const char *remote, const char* url);
+
+/**
+ * Set the remote's url for pushing in the configuration.
+ *
+ * Remote objects already in memory will not be affected. This assumes
+ * the common case of a single-url remote and will otherwise return an error.
+ *
+ *
+ * @param repo the repository in which to perform the change
+ * @param remote the remote's name
+ * @param url the url to set
+ */
+GIT_EXTERN(int) git_remote_set_pushurl(git_repository *repo, const char *remote, const char* url);
+
+/**
+ * Add a fetch refspec to the remote's configuration
+ *
+ * Add the given refspec to the fetch list in the configuration. No
+ * loaded remote instances will be affected.
+ *
+ * @param repo the repository in which to change the configuration
+ * @param remote the name of the remote to change
+ * @param refspec the new fetch refspec
+ * @return 0, GIT_EINVALIDSPEC if refspec is invalid or an error value
+ */
+GIT_EXTERN(int) git_remote_add_fetch(git_repository *repo, const char *remote, const char *refspec);
+
+/**
+ * Get the remote's list of fetch refspecs
+ *
+ * The memory is owned by the user and should be freed with
+ * `git_strarray_free`.
+ *
+ * @param array pointer to the array in which to store the strings
+ * @param remote the remote to query
+ */
+GIT_EXTERN(int) git_remote_get_fetch_refspecs(git_strarray *array, const git_remote *remote);
+
+/**
+ * Add a push refspec to the remote's configuration
+ *
+ * Add the given refspec to the push list in the configuration. No
+ * loaded remote instances will be affected.
+ *
+ * @param repo the repository in which to change the configuration
+ * @param remote the name of the remote to change
+ * @param refspec the new push refspec
+ * @return 0, GIT_EINVALIDSPEC if refspec is invalid or an error value
+ */
+GIT_EXTERN(int) git_remote_add_push(git_repository *repo, const char *remote, const char *refspec);
+
+/**
+ * Get the remote's list of push refspecs
+ *
+ * The memory is owned by the user and should be freed with
+ * `git_strarray_free`.
+ *
+ * @param array pointer to the array in which to store the strings
+ * @param remote the remote to query
+ */
+GIT_EXTERN(int) git_remote_get_push_refspecs(git_strarray *array, const git_remote *remote);
+
+/**
+ * Get the number of refspecs for a remote
+ *
+ * @param remote the remote
+ * @return the amount of refspecs configured in this remote
+ */
+GIT_EXTERN(size_t) git_remote_refspec_count(const git_remote *remote);
+
+/**
+ * Get a refspec from the remote
+ *
+ * @param remote the remote to query
+ * @param n the refspec to get
+ * @return the nth refspec
+ */
+GIT_EXTERN(const git_refspec *)git_remote_get_refspec(const git_remote *remote, size_t n);
+
+/**
+ * Open a connection to a remote
+ *
+ * The transport is selected based on the URL. The direction argument
+ * is due to a limitation of the git protocol (over TCP or SSH) which
+ * starts up a specific binary which can only do the one or the other.
+ *
+ * @param remote the remote to connect to
+ * @param direction GIT_DIRECTION_FETCH if you want to fetch or
+ * GIT_DIRECTION_PUSH if you want to push
+ * @param callbacks the callbacks to use for this connection
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks);
+
+/**
+ * Get the remote repository's reference advertisement list
+ *
+ * Get the list of references with which the server responds to a new
+ * connection.
+ *
+ * The remote (or more exactly its transport) must have connected to
+ * the remote repository. This list is available as soon as the
+ * connection to the remote is initiated and it remains available
+ * after disconnecting.
+ *
+ * The memory belongs to the remote. The pointer will be valid as long
+ * as a new connection is not initiated, but it is recommended that
+ * you make a copy in order to make use of the data.
+ *
+ * @param out pointer to the array
+ * @param size the number of remote heads
+ * @param remote the remote
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_remote_ls(const git_remote_head ***out,  size_t *size, git_remote *remote);
+
+/**
+ * Check whether the remote is connected
+ *
+ * Check whether the remote's underlying transport is connected to the
+ * remote host.
+ *
+ * @param remote the remote
+ * @return 1 if it's connected, 0 otherwise.
+ */
+GIT_EXTERN(int) git_remote_connected(const git_remote *remote);
+
+/**
+ * Cancel the operation
+ *
+ * At certain points in its operation, the network code checks whether
+ * the operation has been cancelled and if so stops the operation.
+ *
+ * @param remote the remote
+ */
+GIT_EXTERN(void) git_remote_stop(git_remote *remote);
+
+/**
+ * Disconnect from the remote
+ *
+ * Close the connection to the remote.
+ *
+ * @param remote the remote to disconnect from
+ */
+GIT_EXTERN(void) git_remote_disconnect(git_remote *remote);
+
+/**
+ * Free the memory associated with a remote
+ *
+ * This also disconnects from the remote, if the connection
+ * has not been closed yet (using git_remote_disconnect).
+ *
+ * @param remote the remote to free
+ */
+GIT_EXTERN(void) git_remote_free(git_remote *remote);
+
+/**
+ * Get a list of the configured remotes for a repo
+ *
+ * The string array must be freed by the user.
+ *
+ * @param out a string array which receives the names of the remotes
+ * @param repo the repository to query
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_list(git_strarray *out, git_repository *repo);
+
+/**
+ * Argument to the completion callback which tells it which operation
+ * finished.
+ */
+typedef enum git_remote_completion_type {
+	GIT_REMOTE_COMPLETION_DOWNLOAD,
+	GIT_REMOTE_COMPLETION_INDEXING,
+	GIT_REMOTE_COMPLETION_ERROR,
+} git_remote_completion_type;
+
+/** Push network progress notification function */
+typedef int (*git_push_transfer_progress)(
+	unsigned int current,
+	unsigned int total,
+	size_t bytes,
+	void* payload);
+/**
+ * Represents an update which will be performed on the remote during push
+ */
+typedef struct {
+	/**
+	 * The source name of the reference
+	 */
+	char *src_refname;
+	/**
+	 * The name of the reference to update on the server
+	 */
+	char *dst_refname;
+	/**
+	 * The current target of the reference
+	 */
+	git_oid src;
+	/**
+	 * The new target for the reference
+	 */
+	git_oid dst;
+} git_push_update;
+
+/**
+ * @param updates an array containing the updates which will be sent
+ * as commands to the destination.
+ * @param len number of elements in `updates`
+ * @param payload Payload provided by the caller
+ */
+typedef int (*git_push_negotiation)(const git_push_update **updates, size_t len, void *payload);
+
+/**
+ * The callback settings structure
+ *
+ * Set the callbacks to be called by the remote when informing the user
+ * about the progress of the network operations.
+ */
+struct git_remote_callbacks {
+	unsigned int version;
+	/**
+	 * Textual progress from the remote. Text send over the
+	 * progress side-band will be passed to this function (this is
+	 * the 'counting objects' output.
+	 */
+	git_transport_message_cb sideband_progress;
+
+	/**
+	 * Completion is called when different parts of the download
+	 * process are done (currently unused).
+	 */
+	int (*completion)(git_remote_completion_type type, void *data);
+
+	/**
+	 * This will be called if the remote host requires
+	 * authentication in order to connect to it.
+	 *
+	 * Returning GIT_PASSTHROUGH will make libgit2 behave as
+	 * though this field isn't set.
+	 */
+	git_cred_acquire_cb credentials;
+
+	/**
+	 * If cert verification fails, this will be called to let the
+	 * user make the final decision of whether to allow the
+	 * connection to proceed. Returns 1 to allow the connection, 0
+	 * to disallow it or a negative value to indicate an error.
+	 */
+        git_transport_certificate_check_cb certificate_check;
+
+	/**
+	 * During the download of new data, this will be regularly
+	 * called with the current count of progress done by the
+	 * indexer.
+	 */
+	git_transfer_progress_cb transfer_progress;
+
+	/**
+	 * Each time a reference is updated locally, this function
+	 * will be called with information about it.
+	 */
+	int (*update_tips)(const char *refname, const git_oid *a, const git_oid *b, void *data);
+
+	/**
+	 * Function to call with progress information during pack
+	 * building. Be aware that this is called inline with pack
+	 * building operations, so performance may be affected.
+	 */
+	git_packbuilder_progress pack_progress;
+
+	/**
+	 * Function to call with progress information during the
+	 * upload portion of a push. Be aware that this is called
+	 * inline with pack building operations, so performance may be
+	 * affected.
+	 */
+	git_push_transfer_progress push_transfer_progress;
+
+	/**
+	 * Called for each updated reference on push. If `status` is
+	 * not `NULL`, the update was rejected by the remote server
+	 * and `status` contains the reason given.
+	 */
+	int (*push_update_reference)(const char *refname, const char *status, void *data);
+
+	/**
+	 * Called once between the negotiation step and the upload. It
+	 * provides information about what updates will be performed.
+	 */
+	git_push_negotiation push_negotiation;
+
+	/**
+	 * Create the transport to use for this operation. Leave NULL
+	 * to auto-detect.
+	 */
+	git_transport_cb transport;
+
+	/**
+	 * This will be passed to each of the callbacks in this struct
+	 * as the last parameter.
+	 */
+	void *payload;
+};
+
+#define GIT_REMOTE_CALLBACKS_VERSION 1
+#define GIT_REMOTE_CALLBACKS_INIT {GIT_REMOTE_CALLBACKS_VERSION}
+
+/**
+ * Initializes a `git_remote_callbacks` with default values. Equivalent to
+ * creating an instance with GIT_REMOTE_CALLBACKS_INIT.
+ *
+ * @param opts the `git_remote_callbacks` struct to initialize
+ * @param version Version of struct; pass `GIT_REMOTE_CALLBACKS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_remote_init_callbacks(
+	git_remote_callbacks *opts,
+	unsigned int version);
+
+typedef enum {
+	/**
+	 * Use the setting from the configuration
+	 */
+	GIT_FETCH_PRUNE_UNSPECIFIED,
+	/**
+	 * Force pruning on
+	 */
+	GIT_FETCH_PRUNE,
+	/**
+	 * Force pruning off
+	 */
+	GIT_FETCH_NO_PRUNE,
+} git_fetch_prune_t;
+
+/**
+ * Automatic tag following option
+ *
+ * Lets us select the --tags option to use.
+ */
+typedef enum {
+	/**
+	 * Use the setting from the configuration.
+	 */
+	GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED = 0,
+	/**
+	 * Ask the server for tags pointing to objects we're already
+	 * downloading.
+	 */
+	GIT_REMOTE_DOWNLOAD_TAGS_AUTO,
+	/**
+	 * Don't ask for any tags beyond the refspecs.
+	 */
+	GIT_REMOTE_DOWNLOAD_TAGS_NONE,
+	/**
+	 * Ask for the all the tags.
+	 */
+	GIT_REMOTE_DOWNLOAD_TAGS_ALL,
+} git_remote_autotag_option_t;
+
+/**
+ * Fetch options structure.
+ *
+ * Zero out for defaults.  Initialize with `GIT_FETCH_OPTIONS_INIT` macro to
+ * correctly set the `version` field.  E.g.
+ *
+ *		git_fetch_options opts = GIT_FETCH_OPTIONS_INIT;
+ */
+typedef struct {
+	int version;
+
+	/**
+	 * Callbacks to use for this fetch operation
+	 */
+	git_remote_callbacks callbacks;
+
+	/**
+	 * Whether to perform a prune after the fetch
+	 */
+	git_fetch_prune_t prune;
+
+	/**
+	 * Whether to write the results to FETCH_HEAD. Defaults to
+	 * on. Leave this default in order to behave like git.
+	 */
+	int update_fetchhead;
+
+	/**
+	 * Determines how to behave regarding tags on the remote, such
+	 * as auto-downloading tags for objects we're downloading or
+	 * downloading all of them.
+	 *
+	 * The default is to auto-follow tags.
+	 */
+	git_remote_autotag_option_t download_tags;
+} git_fetch_options;
+
+#define GIT_FETCH_OPTIONS_VERSION 1
+#define GIT_FETCH_OPTIONS_INIT { GIT_FETCH_OPTIONS_VERSION, GIT_REMOTE_CALLBACKS_INIT, GIT_FETCH_PRUNE_UNSPECIFIED, 1 }
+
+/**
+ * Initializes a `git_fetch_options` with default values. Equivalent to
+ * creating an instance with GIT_FETCH_OPTIONS_INIT.
+ *
+ * @param opts the `git_push_options` instance to initialize.
+ * @param version the version of the struct; you should pass
+ *        `GIT_FETCH_OPTIONS_VERSION` here.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_fetch_init_options(
+	git_fetch_options *opts,
+	unsigned int version);
+
+
+/**
+ * Controls the behavior of a git_push object.
+ */
+typedef struct {
+	unsigned int version;
+
+	/**
+	 * If the transport being used to push to the remote requires the creation
+	 * of a pack file, this controls the number of worker threads used by
+	 * the packbuilder when creating that pack file to be sent to the remote.
+	 *
+	 * If set to 0, the packbuilder will auto-detect the number of threads
+	 * to create. The default value is 1.
+	 */
+	unsigned int pb_parallelism;
+
+	/**
+	 * Callbacks to use for this push operation
+	 */
+	git_remote_callbacks callbacks;
+} git_push_options;
+
+#define GIT_PUSH_OPTIONS_VERSION 1
+#define GIT_PUSH_OPTIONS_INIT { GIT_PUSH_OPTIONS_VERSION, 0, GIT_REMOTE_CALLBACKS_INIT }
+
+/**
+ * Initializes a `git_push_options` with default values. Equivalent to
+ * creating an instance with GIT_PUSH_OPTIONS_INIT.
+ *
+ * @param opts the `git_push_options` instance to initialize.
+ * @param version the version of the struct; you should pass
+ *        `GIT_PUSH_OPTIONS_VERSION` here.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_push_init_options(
+	git_push_options *opts,
+	unsigned int version);
+
+/**
+ * Download and index the packfile
+ *
+ * Connect to the remote if it hasn't been done yet, negotiate with
+ * the remote git which objects are missing, download and index the
+ * packfile.
+ *
+ * The .idx file will be created and both it and the packfile with be
+ * renamed to their final name.
+ *
+ * @param remote the remote
+ * @param refspecs the refspecs to use for this negotiation and
+ * download. Use NULL or an empty array to use the base refspecs
+ * @param opts the options to use for this fetch
+ * @return 0 or an error code
+ */
+ GIT_EXTERN(int) git_remote_download(git_remote *remote, const git_strarray *refspecs, const git_fetch_options *opts);
+
+/**
+ * Create a packfile and send it to the server
+ *
+ * Connect to the remote if it hasn't been done yet, negotiate with
+ * the remote git which objects are missing, create a packfile with the missing objects and send it.
+ *
+ * @param remote the remote
+ * @param refspecs the refspecs to use for this negotiation and
+ * upload. Use NULL or an empty array to use the base refspecs
+ * @param opts the options to use for this push
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_upload(git_remote *remote, const git_strarray *refspecs, const git_push_options *opts);
+
+/**
+ * Update the tips to the new state
+ *
+ * @param remote the remote to update
+ * @param reflog_message The message to insert into the reflogs. If
+ * NULL and fetching, the default is "fetch <name>", where <name> is
+ * the name of the remote (or its url, for in-memory remotes). This
+ * parameter is ignored when pushing.
+ * @param callbacks  pointer to the callback structure to use
+ * @param update_fetchhead whether to write to FETCH_HEAD. Pass 1 to behave like git.
+ * @param download_tags what the behaviour for downloading tags is for this fetch. This is
+ * ignored for push. This must be the same value passed to `git_remote_download()`.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_update_tips(
+		git_remote *remote,
+		const git_remote_callbacks *callbacks,
+		int update_fetchhead,
+		git_remote_autotag_option_t download_tags,
+		const char *reflog_message);
+
+/**
+ * Download new data and update tips
+ *
+ * Convenience function to connect to a remote, download the data,
+ * disconnect and update the remote-tracking branches.
+ *
+ * @param remote the remote to fetch from
+ * @param refspecs the refspecs to use for this fetch. Pass NULL or an
+ *                 empty array to use the base refspecs.
+ * @param opts options to use for this fetch
+ * @param reflog_message The message to insert into the reflogs. If NULL, the
+ *								 default is "fetch"
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_fetch(
+		git_remote *remote,
+		const git_strarray *refspecs,
+		const git_fetch_options *opts,
+		const char *reflog_message);
+
+/**
+ * Prune tracking refs that are no longer present on remote
+ *
+ * @param remote the remote to prune
+ * @param callbacks callbacks to use for this prune
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_remote_prune(git_remote *remote, const git_remote_callbacks *callbacks);
+
+/**
+ * Perform a push
+ *
+ * Peform all the steps from a push.
+ *
+ * @param remote the remote to push to
+ * @param refspecs the refspecs to use for pushing. If none are
+ * passed, the configured refspecs will be used
+ * @param opts options to use for this push
+ */
+GIT_EXTERN(int) git_remote_push(git_remote *remote,
+				const git_strarray *refspecs,
+				const git_push_options *opts);
+
+/**
+ * Get the statistics structure that is filled in by the fetch operation.
+ */
+GIT_EXTERN(const git_transfer_progress *) git_remote_stats(git_remote *remote);
+
+/**
+ * Retrieve the tag auto-follow setting
+ *
+ * @param remote the remote to query
+ * @return the auto-follow setting
+ */
+GIT_EXTERN(git_remote_autotag_option_t) git_remote_autotag(const git_remote *remote);
+
+/**
+ * Set the remote's tag following setting.
+ *
+ * The change will be made in the configuration. No loaded remotes
+ * will be affected.
+ *
+ * @param repo the repository in which to make the change
+ * @param remote the name of the remote
+ * @param value the new value to take.
+ */
+GIT_EXTERN(int) git_remote_set_autotag(git_repository *repo, const char *remote, git_remote_autotag_option_t value);
+/**
+ * Retrieve the ref-prune setting
+ *
+ * @param remote the remote to query
+ * @return the ref-prune setting
+ */
+GIT_EXTERN(int) git_remote_prune_refs(const git_remote *remote);
+
+/**
+ * Give the remote a new name
+ *
+ * All remote-tracking branches and configuration settings
+ * for the remote are updated.
+ *
+ * The new name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
+ *
+ * No loaded instances of a the remote with the old name will change
+ * their name or their list of refspecs.
+ *
+ * @param problems non-default refspecs cannot be renamed and will be
+ * stored here for further processing by the caller. Always free this
+ * strarray on successful return.
+ * @param repo the repository in which to rename
+ * @param name the current name of the remote
+ * @param new_name the new name the remote should bear
+ * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
+ */
+GIT_EXTERN(int) git_remote_rename(
+	git_strarray *problems,
+	git_repository *repo,
+	const char *name,
+	const char *new_name);
+
+/**
+ * Ensure the remote name is well-formed.
+ *
+ * @param remote_name name to be checked.
+ * @return 1 if the reference name is acceptable; 0 if it isn't
+ */
+GIT_EXTERN(int) git_remote_is_valid_name(const char *remote_name);
+
+/**
+* Delete an existing persisted remote.
+*
+* All remote-tracking branches and configuration settings
+* for the remote will be removed.
+*
+* @param repo the repository in which to act
+* @param name the name of the remove to delete
+* @return 0 on success, or an error code.
+*/
+GIT_EXTERN(int) git_remote_delete(git_repository *repo, const char *name);
+
+/**
+ * Retrieve the name of the remote's default branch
+ *
+ * The default branch of a repository is the branch which HEAD points
+ * to. If the remote does not support reporting this information
+ * directly, it performs the guess as git does; that is, if there are
+ * multiple branches which point to the same commit, the first one is
+ * chosen. If the master branch is a candidate, it wins.
+ *
+ * This function must only be called after connecting.
+ *
+ * @param out the buffern in which to store the reference name
+ * @param remote the remote
+ * @return 0, GIT_ENOTFOUND if the remote does not have any references
+ * or none of them point to HEAD's commit, or an error message.
+ */
+GIT_EXTERN(int) git_remote_default_branch(git_buf *out, git_remote *remote);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/repository.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/repository.h
new file mode 100755
index 0000000..cf268ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/repository.h
@@ -0,0 +1,754 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_repository_h__
+#define INCLUDE_git_repository_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "buffer.h"
+
+/**
+ * @file git2/repository.h
+ * @brief Git repository management routines
+ * @defgroup git_repository Git repository management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Open a git repository.
+ *
+ * The 'path' argument must point to either a git repository
+ * folder, or an existing work dir.
+ *
+ * The method will automatically detect if 'path' is a normal
+ * or bare repository or fail is 'path' is neither.
+ *
+ * @param out pointer to the repo which will be opened
+ * @param path the path to the repository
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_repository_open(git_repository **out, const char *path);
+
+/**
+ * Create a "fake" repository to wrap an object database
+ *
+ * Create a repository object to wrap an object database to be used
+ * with the API when all you have is an object database. This doesn't
+ * have any paths associated with it, so use with care.
+ *
+ * @param out pointer to the repo
+ * @param odb the object database to wrap
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_repository_wrap_odb(git_repository **out, git_odb *odb);
+
+/**
+ * Look for a git repository and copy its path in the given buffer.
+ * The lookup start from base_path and walk across parent directories
+ * if nothing has been found. The lookup ends when the first repository
+ * is found, or when reaching a directory referenced in ceiling_dirs
+ * or when the filesystem changes (in case across_fs is true).
+ *
+ * The method will automatically detect if the repository is bare
+ * (if there is a repository).
+ *
+ * @param out A pointer to a user-allocated git_buf which will contain
+ * the found path.
+ *
+ * @param start_path The base path where the lookup starts.
+ *
+ * @param across_fs If true, then the lookup will not stop when a
+ * filesystem device change is detected while exploring parent directories.
+ *
+ * @param ceiling_dirs A GIT_PATH_LIST_SEPARATOR separated list of
+ * absolute symbolic link free paths. The lookup will stop when any
+ * of this paths is reached. Note that the lookup always performs on
+ * start_path no matter start_path appears in ceiling_dirs ceiling_dirs
+ * might be NULL (which is equivalent to an empty string)
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_repository_discover(
+		git_buf *out,
+		const char *start_path,
+		int across_fs,
+		const char *ceiling_dirs);
+
+/**
+ * Option flags for `git_repository_open_ext`.
+ *
+ * * GIT_REPOSITORY_OPEN_NO_SEARCH - Only open the repository if it can be
+ *   immediately found in the start_path.  Do not walk up from the
+ *   start_path looking at parent directories.
+ * * GIT_REPOSITORY_OPEN_CROSS_FS - Unless this flag is set, open will not
+ *   continue searching across filesystem boundaries (i.e. when `st_dev`
+ *   changes from the `stat` system call).  (E.g. Searching in a user's home
+ *   directory "/home/user/source/" will not return "/.git/" as the found
+ *   repo if "/" is a different filesystem than "/home".)
+ * * GIT_REPOSITORY_OPEN_BARE - Open repository as a bare repo regardless
+ *   of core.bare config, and defer loading config file for faster setup.
+ *   Unlike `git_repository_open_bare`, this can follow gitlinks.
+ */
+typedef enum {
+	GIT_REPOSITORY_OPEN_NO_SEARCH = (1 << 0),
+	GIT_REPOSITORY_OPEN_CROSS_FS  = (1 << 1),
+	GIT_REPOSITORY_OPEN_BARE      = (1 << 2),
+} git_repository_open_flag_t;
+
+/**
+ * Find and open a repository with extended controls.
+ *
+ * @param out Pointer to the repo which will be opened.  This can
+ *        actually be NULL if you only want to use the error code to
+ *        see if a repo at this path could be opened.
+ * @param path Path to open as git repository.  If the flags
+ *        permit "searching", then this can be a path to a subdirectory
+ *        inside the working directory of the repository.
+ * @param flags A combination of the GIT_REPOSITORY_OPEN flags above.
+ * @param ceiling_dirs A GIT_PATH_LIST_SEPARATOR delimited list of path
+ *        prefixes at which the search for a containing repository should
+ *        terminate.
+ * @return 0 on success, GIT_ENOTFOUND if no repository could be found,
+ *        or -1 if there was a repository but open failed for some reason
+ *        (such as repo corruption or system errors).
+ */
+GIT_EXTERN(int) git_repository_open_ext(
+	git_repository **out,
+	const char *path,
+	unsigned int flags,
+	const char *ceiling_dirs);
+
+/**
+ * Open a bare repository on the serverside.
+ *
+ * This is a fast open for bare repositories that will come in handy
+ * if you're e.g. hosting git repositories and need to access them
+ * efficiently
+ *
+ * @param out Pointer to the repo which will be opened.
+ * @param bare_path Direct path to the bare repository
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository_open_bare(git_repository **out, const char *bare_path);
+
+/**
+ * Free a previously allocated repository
+ *
+ * Note that after a repository is free'd, all the objects it has spawned
+ * will still exist until they are manually closed by the user
+ * with `git_object_free`, but accessing any of the attributes of
+ * an object without a backing repository will result in undefined
+ * behavior
+ *
+ * @param repo repository handle to close. If NULL nothing occurs.
+ */
+GIT_EXTERN(void) git_repository_free(git_repository *repo);
+
+/**
+ * Creates a new Git repository in the given folder.
+ *
+ * TODO:
+ *	- Reinit the repository
+ *
+ * @param out pointer to the repo which will be created or reinitialized
+ * @param path the path to the repository
+ * @param is_bare if true, a Git repository without a working directory is
+ *		created at the pointed path. If false, provided path will be
+ *		considered as the working directory into which the .git directory
+ *		will be created.
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_repository_init(
+	git_repository **out,
+	const char *path,
+	unsigned is_bare);
+
+/**
+ * Option flags for `git_repository_init_ext`.
+ *
+ * These flags configure extra behaviors to `git_repository_init_ext`.
+ * In every case, the default behavior is the zero value (i.e. flag is
+ * not set).  Just OR the flag values together for the `flags` parameter
+ * when initializing a new repo.  Details of individual values are:
+ *
+ * * BARE   - Create a bare repository with no working directory.
+ * * NO_REINIT - Return an GIT_EEXISTS error if the repo_path appears to
+ *        already be an git repository.
+ * * NO_DOTGIT_DIR - Normally a "/.git/" will be appended to the repo
+ *        path for non-bare repos (if it is not already there), but
+ *        passing this flag prevents that behavior.
+ * * MKDIR  - Make the repo_path (and workdir_path) as needed.  Init is
+ *        always willing to create the ".git" directory even without this
+ *        flag.  This flag tells init to create the trailing component of
+ *        the repo and workdir paths as needed.
+ * * MKPATH - Recursively make all components of the repo and workdir
+ *        paths as necessary.
+ * * EXTERNAL_TEMPLATE - libgit2 normally uses internal templates to
+ *        initialize a new repo.  This flags enables external templates,
+ *        looking the "template_path" from the options if set, or the
+ *        `init.templatedir` global config if not, or falling back on
+ *        "/usr/share/git-core/templates" if it exists.
+ * * GIT_REPOSITORY_INIT_RELATIVE_GITLINK - If an alternate workdir is
+ *        specified, use relative paths for the gitdir and core.worktree.
+ */
+typedef enum {
+	GIT_REPOSITORY_INIT_BARE              = (1u << 0),
+	GIT_REPOSITORY_INIT_NO_REINIT         = (1u << 1),
+	GIT_REPOSITORY_INIT_NO_DOTGIT_DIR     = (1u << 2),
+	GIT_REPOSITORY_INIT_MKDIR             = (1u << 3),
+	GIT_REPOSITORY_INIT_MKPATH            = (1u << 4),
+	GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE = (1u << 5),
+	GIT_REPOSITORY_INIT_RELATIVE_GITLINK  = (1u << 6),
+} git_repository_init_flag_t;
+
+/**
+ * Mode options for `git_repository_init_ext`.
+ *
+ * Set the mode field of the `git_repository_init_options` structure
+ * either to the custom mode that you would like, or to one of the
+ * following modes:
+ *
+ * * SHARED_UMASK - Use permissions configured by umask - the default.
+ * * SHARED_GROUP - Use "--shared=group" behavior, chmod'ing the new repo
+ *        to be group writable and "g+sx" for sticky group assignment.
+ * * SHARED_ALL - Use "--shared=all" behavior, adding world readability.
+ * * Anything else - Set to custom value.
+ */
+typedef enum {
+	GIT_REPOSITORY_INIT_SHARED_UMASK = 0,
+	GIT_REPOSITORY_INIT_SHARED_GROUP = 0002775,
+	GIT_REPOSITORY_INIT_SHARED_ALL   = 0002777,
+} git_repository_init_mode_t;
+
+/**
+ * Extended options structure for `git_repository_init_ext`.
+ *
+ * This contains extra options for `git_repository_init_ext` that enable
+ * additional initialization features.  The fields are:
+ *
+ * * flags - Combination of GIT_REPOSITORY_INIT flags above.
+ * * mode  - Set to one of the standard GIT_REPOSITORY_INIT_SHARED_...
+ *        constants above, or to a custom value that you would like.
+ * * workdir_path - The path to the working dir or NULL for default (i.e.
+ *        repo_path parent on non-bare repos).  IF THIS IS RELATIVE PATH,
+ *        IT WILL BE EVALUATED RELATIVE TO THE REPO_PATH.  If this is not
+ *        the "natural" working directory, a .git gitlink file will be
+ *        created here linking to the repo_path.
+ * * description - If set, this will be used to initialize the "description"
+ *        file in the repository, instead of using the template content.
+ * * template_path - When GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE is set,
+ *        this contains the path to use for the template directory.  If
+ *        this is NULL, the config or default directory options will be
+ *        used instead.
+ * * initial_head - The name of the head to point HEAD at.  If NULL, then
+ *        this will be treated as "master" and the HEAD ref will be set
+ *        to "refs/heads/master".  If this begins with "refs/" it will be
+ *        used verbatim; otherwise "refs/heads/" will be prefixed.
+ * * origin_url - If this is non-NULL, then after the rest of the
+ *        repository initialization is completed, an "origin" remote
+ *        will be added pointing to this URL.
+ */
+typedef struct {
+	unsigned int version;
+	uint32_t    flags;
+	uint32_t    mode;
+	const char *workdir_path;
+	const char *description;
+	const char *template_path;
+	const char *initial_head;
+	const char *origin_url;
+} git_repository_init_options;
+
+#define GIT_REPOSITORY_INIT_OPTIONS_VERSION 1
+#define GIT_REPOSITORY_INIT_OPTIONS_INIT {GIT_REPOSITORY_INIT_OPTIONS_VERSION}
+
+/**
+ * Initializes a `git_repository_init_options` with default values. Equivalent
+ * to creating an instance with GIT_REPOSITORY_INIT_OPTIONS_INIT.
+ *
+ * @param opts the `git_repository_init_options` struct to initialize
+ * @param version Version of struct; pass `GIT_REPOSITORY_INIT_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_repository_init_init_options(
+	git_repository_init_options *opts,
+	unsigned int version);
+
+/**
+ * Create a new Git repository in the given folder with extended controls.
+ *
+ * This will initialize a new git repository (creating the repo_path
+ * if requested by flags) and working directory as needed.  It will
+ * auto-detect the case sensitivity of the file system and if the
+ * file system supports file mode bits correctly.
+ *
+ * @param out Pointer to the repo which will be created or reinitialized.
+ * @param repo_path The path to the repository.
+ * @param opts Pointer to git_repository_init_options struct.
+ * @return 0 or an error code on failure.
+ */
+GIT_EXTERN(int) git_repository_init_ext(
+	git_repository **out,
+	const char *repo_path,
+	git_repository_init_options *opts);
+
+/**
+ * Retrieve and resolve the reference pointed at by HEAD.
+ *
+ * The returned `git_reference` will be owned by caller and
+ * `git_reference_free()` must be called when done with it to release the
+ * allocated memory and prevent a leak.
+ *
+ * @param out pointer to the reference which will be retrieved
+ * @param repo a repository object
+ *
+ * @return 0 on success, GIT_EUNBORNBRANCH when HEAD points to a non existing
+ * branch, GIT_ENOTFOUND when HEAD is missing; an error code otherwise
+ */
+GIT_EXTERN(int) git_repository_head(git_reference **out, git_repository *repo);
+
+/**
+ * Check if a repository's HEAD is detached
+ *
+ * A repository's HEAD is detached when it points directly to a commit
+ * instead of a branch.
+ *
+ * @param repo Repo to test
+ * @return 1 if HEAD is detached, 0 if it's not; error code if there
+ * was an error.
+ */
+GIT_EXTERN(int) git_repository_head_detached(git_repository *repo);
+
+/**
+ * Check if the current branch is unborn
+ *
+ * An unborn branch is one named from HEAD but which doesn't exist in
+ * the refs namespace, because it doesn't have any commit to point to.
+ *
+ * @param repo Repo to test
+ * @return 1 if the current branch is unborn, 0 if it's not; error
+ * code if there was an error
+ */
+GIT_EXTERN(int) git_repository_head_unborn(git_repository *repo);
+
+/**
+ * Check if a repository is empty
+ *
+ * An empty repository has just been initialized and contains no references
+ * apart from HEAD, which must be pointing to the unborn master branch.
+ *
+ * @param repo Repo to test
+ * @return 1 if the repository is empty, 0 if it isn't, error code
+ * if the repository is corrupted
+ */
+GIT_EXTERN(int) git_repository_is_empty(git_repository *repo);
+
+/**
+ * Get the path of this repository
+ *
+ * This is the path of the `.git` folder for normal repositories,
+ * or of the repository itself for bare repositories.
+ *
+ * @param repo A repository object
+ * @return the path to the repository
+ */
+GIT_EXTERN(const char *) git_repository_path(git_repository *repo);
+
+/**
+ * Get the path of the working directory for this repository
+ *
+ * If the repository is bare, this function will always return
+ * NULL.
+ *
+ * @param repo A repository object
+ * @return the path to the working dir, if it exists
+ */
+GIT_EXTERN(const char *) git_repository_workdir(git_repository *repo);
+
+/**
+ * Set the path to the working directory for this repository
+ *
+ * The working directory doesn't need to be the same one
+ * that contains the `.git` folder for this repository.
+ *
+ * If this repository is bare, setting its working directory
+ * will turn it into a normal repository, capable of performing
+ * all the common workdir operations (checkout, status, index
+ * manipulation, etc).
+ *
+ * @param repo A repository object
+ * @param workdir The path to a working directory
+ * @param update_gitlink Create/update gitlink in workdir and set config
+ *        "core.worktree" (if workdir is not the parent of the .git directory)
+ * @return 0, or an error code
+ */
+GIT_EXTERN(int) git_repository_set_workdir(
+	git_repository *repo, const char *workdir, int update_gitlink);
+
+/**
+ * Check if a repository is bare
+ *
+ * @param repo Repo to test
+ * @return 1 if the repository is bare, 0 otherwise.
+ */
+GIT_EXTERN(int) git_repository_is_bare(git_repository *repo);
+
+/**
+ * Get the configuration file for this repository.
+ *
+ * If a configuration file has not been set, the default
+ * config set for the repository will be returned, including
+ * global and system configurations (if they are available).
+ *
+ * The configuration file must be freed once it's no longer
+ * being used by the user.
+ *
+ * @param out Pointer to store the loaded configuration
+ * @param repo A repository object
+ * @return 0, or an error code
+ */
+GIT_EXTERN(int) git_repository_config(git_config **out, git_repository *repo);
+
+/**
+ * Get a snapshot of the repository's configuration
+ *
+ * Convenience function to take a snapshot from the repository's
+ * configuration.  The contents of this snapshot will not change,
+ * even if the underlying config files are modified.
+ *
+ * The configuration file must be freed once it's no longer
+ * being used by the user.
+ *
+ * @param out Pointer to store the loaded configuration
+ * @param repo the repository
+ * @return 0, or an error code
+ */
+GIT_EXTERN(int) git_repository_config_snapshot(git_config **out, git_repository *repo);
+
+/**
+ * Get the Object Database for this repository.
+ *
+ * If a custom ODB has not been set, the default
+ * database for the repository will be returned (the one
+ * located in `.git/objects`).
+ *
+ * The ODB must be freed once it's no longer being used by
+ * the user.
+ *
+ * @param out Pointer to store the loaded ODB
+ * @param repo A repository object
+ * @return 0, or an error code
+ */
+GIT_EXTERN(int) git_repository_odb(git_odb **out, git_repository *repo);
+
+/**
+ * Get the Reference Database Backend for this repository.
+ *
+ * If a custom refsdb has not been set, the default database for
+ * the repository will be returned (the one that manipulates loose
+ * and packed references in the `.git` directory).
+ *
+ * The refdb must be freed once it's no longer being used by
+ * the user.
+ *
+ * @param out Pointer to store the loaded refdb
+ * @param repo A repository object
+ * @return 0, or an error code
+ */
+GIT_EXTERN(int) git_repository_refdb(git_refdb **out, git_repository *repo);
+
+/**
+ * Get the Index file for this repository.
+ *
+ * If a custom index has not been set, the default
+ * index for the repository will be returned (the one
+ * located in `.git/index`).
+ *
+ * The index must be freed once it's no longer being used by
+ * the user.
+ *
+ * @param out Pointer to store the loaded index
+ * @param repo A repository object
+ * @return 0, or an error code
+ */
+GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo);
+
+/**
+ * Retrieve git's prepared message
+ *
+ * Operations such as git revert/cherry-pick/merge with the -n option
+ * stop just short of creating a commit with the changes and save
+ * their prepared message in .git/MERGE_MSG so the next git-commit
+ * execution can present it to the user for them to amend if they
+ * wish.
+ *
+ * Use this function to get the contents of this file. Don't forget to
+ * remove the file after you create the commit.
+ *
+ * @param out git_buf to write data into
+ * @param repo Repository to read prepared message from
+ * @return 0, GIT_ENOTFOUND if no message exists or an error code
+ */
+GIT_EXTERN(int) git_repository_message(git_buf *out, git_repository *repo);
+
+/**
+ * Remove git's prepared message.
+ *
+ * Remove the message that `git_repository_message` retrieves.
+ */
+GIT_EXTERN(int) git_repository_message_remove(git_repository *repo);
+
+/**
+ * Remove all the metadata associated with an ongoing command like merge,
+ * revert, cherry-pick, etc.  For example: MERGE_HEAD, MERGE_MSG, etc.
+ *
+ * @param repo A repository object
+ * @return 0 on success, or error
+ */
+GIT_EXTERN(int) git_repository_state_cleanup(git_repository *repo);
+
+typedef int (*git_repository_fetchhead_foreach_cb)(const char *ref_name,
+	const char *remote_url,
+	const git_oid *oid,
+	unsigned int is_merge,
+	void *payload);
+
+/**
+ * Invoke 'callback' for each entry in the given FETCH_HEAD file.
+ *
+ * Return a non-zero value from the callback to stop the loop.
+ *
+ * @param repo A repository object
+ * @param callback Callback function
+ * @param payload Pointer to callback data (optional)
+ * @return 0 on success, non-zero callback return value, GIT_ENOTFOUND if
+ *         there is no FETCH_HEAD file, or other error code.
+ */
+GIT_EXTERN(int) git_repository_fetchhead_foreach(
+	git_repository *repo,
+	git_repository_fetchhead_foreach_cb callback,
+	void *payload);
+
+typedef int (*git_repository_mergehead_foreach_cb)(const git_oid *oid,
+	void *payload);
+
+/**
+ * If a merge is in progress, invoke 'callback' for each commit ID in the
+ * MERGE_HEAD file.
+ *
+ * Return a non-zero value from the callback to stop the loop.
+ *
+ * @param repo A repository object
+ * @param callback Callback function
+ * @param payload Pointer to callback data (optional)
+ * @return 0 on success, non-zero callback return value, GIT_ENOTFOUND if
+ *         there is no MERGE_HEAD file, or other error code.
+ */
+GIT_EXTERN(int) git_repository_mergehead_foreach(
+	git_repository *repo,
+	git_repository_mergehead_foreach_cb callback,
+	void *payload);
+
+/**
+ * Calculate hash of file using repository filtering rules.
+ *
+ * If you simply want to calculate the hash of a file on disk with no filters,
+ * you can just use the `git_odb_hashfile()` API.  However, if you want to
+ * hash a file in the repository and you want to apply filtering rules (e.g.
+ * crlf filters) before generating the SHA, then use this function.
+ *
+ * Note: if the repository has `core.safecrlf` set to fail and the
+ * filtering triggers that failure, then this function will return an
+ * error and not calculate the hash of the file.
+ *
+ * @param out Output value of calculated SHA
+ * @param repo Repository pointer
+ * @param path Path to file on disk whose contents should be hashed. If the
+ *             repository is not NULL, this can be a relative path.
+ * @param type The object type to hash as (e.g. GIT_OBJ_BLOB)
+ * @param as_path The path to use to look up filtering rules. If this is
+ *             NULL, then the `path` parameter will be used instead. If
+ *             this is passed as the empty string, then no filters will be
+ *             applied when calculating the hash.
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository_hashfile(
+	git_oid *out,
+	git_repository *repo,
+	const char *path,
+	git_otype type,
+	const char *as_path);
+
+/**
+ * Make the repository HEAD point to the specified reference.
+ *
+ * If the provided reference points to a Tree or a Blob, the HEAD is
+ * unaltered and -1 is returned.
+ *
+ * If the provided reference points to a branch, the HEAD will point
+ * to that branch, staying attached, or become attached if it isn't yet.
+ * If the branch doesn't exist yet, no error will be return. The HEAD
+ * will then be attached to an unborn branch.
+ *
+ * Otherwise, the HEAD will be detached and will directly point to
+ * the Commit.
+ *
+ * @param repo Repository pointer
+ * @param refname Canonical name of the reference the HEAD should point at
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository_set_head(
+	git_repository* repo,
+	const char* refname);
+
+/**
+ * Make the repository HEAD directly point to the Commit.
+ *
+ * If the provided committish cannot be found in the repository, the HEAD
+ * is unaltered and GIT_ENOTFOUND is returned.
+ *
+ * If the provided commitish cannot be peeled into a commit, the HEAD
+ * is unaltered and -1 is returned.
+ *
+ * Otherwise, the HEAD will eventually be detached and will directly point to
+ * the peeled Commit.
+ *
+ * @param repo Repository pointer
+ * @param commitish Object id of the Commit the HEAD should point to
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository_set_head_detached(
+	git_repository* repo,
+	const git_oid* commitish);
+
+/**
+ * Make the repository HEAD directly point to the Commit.
+ *
+ * This behaves like `git_repository_set_head_detached()` but takes an
+ * annotated commit, which lets you specify which extended sha syntax
+ * string was specified by a user, allowing for more exact reflog
+ * messages.
+ *
+ * See the documentation for `git_repository_set_head_detached()`.
+ *
+ * @see git_repository_set_head_detached
+ */
+GIT_EXTERN(int) git_repository_set_head_detached_from_annotated(
+	git_repository *repo,
+	const git_annotated_commit *commitish);
+
+/**
+ * Detach the HEAD.
+ *
+ * If the HEAD is already detached and points to a Commit, 0 is returned.
+ *
+ * If the HEAD is already detached and points to a Tag, the HEAD is
+ * updated into making it point to the peeled Commit, and 0 is returned.
+ *
+ * If the HEAD is already detached and points to a non commitish, the HEAD is
+ * unaltered, and -1 is returned.
+ *
+ * Otherwise, the HEAD will be detached and point to the peeled Commit.
+ *
+ * @param repo Repository pointer
+ * @return 0 on success, GIT_EUNBORNBRANCH when HEAD points to a non existing
+ * branch or an error code
+ */
+GIT_EXTERN(int) git_repository_detach_head(
+	git_repository* repo);
+
+/**
+ * Repository state
+ *
+ * These values represent possible states for the repository to be in,
+ * based on the current operation which is ongoing.
+ */
+typedef enum {
+	GIT_REPOSITORY_STATE_NONE,
+	GIT_REPOSITORY_STATE_MERGE,
+	GIT_REPOSITORY_STATE_REVERT,
+	GIT_REPOSITORY_STATE_CHERRYPICK,
+	GIT_REPOSITORY_STATE_BISECT,
+	GIT_REPOSITORY_STATE_REBASE,
+	GIT_REPOSITORY_STATE_REBASE_INTERACTIVE,
+	GIT_REPOSITORY_STATE_REBASE_MERGE,
+	GIT_REPOSITORY_STATE_APPLY_MAILBOX,
+	GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE,
+} git_repository_state_t;
+
+/**
+ * Determines the status of a git repository - ie, whether an operation
+ * (merge, cherry-pick, etc) is in progress.
+ *
+ * @param repo Repository pointer
+ * @return The state of the repository
+ */
+GIT_EXTERN(int) git_repository_state(git_repository *repo);
+
+/**
+ * Sets the active namespace for this Git Repository
+ *
+ * This namespace affects all reference operations for the repo.
+ * See `man gitnamespaces`
+ *
+ * @param repo The repo
+ * @param nmspace The namespace. This should not include the refs
+ *	folder, e.g. to namespace all references under `refs/namespaces/foo/`,
+ *	use `foo` as the namespace.
+ *	@return 0 on success, -1 on error
+ */
+GIT_EXTERN(int) git_repository_set_namespace(git_repository *repo, const char *nmspace);
+
+/**
+ * Get the currently active namespace for this repository
+ *
+ * @param repo The repo
+ * @return the active namespace, or NULL if there isn't one
+ */
+GIT_EXTERN(const char *) git_repository_get_namespace(git_repository *repo);
+
+
+/**
+ * Determine if the repository was a shallow clone
+ *
+ * @param repo The repository
+ * @return 1 if shallow, zero if not
+ */
+GIT_EXTERN(int) git_repository_is_shallow(git_repository *repo);
+
+/**
+ * Retrieve the configured identity to use for reflogs
+ *
+ * The memory is owned by the repository and must not be freed by the
+ * user.
+ *
+ * @param name where to store the pointer to the name
+ * @param email where to store the pointer to the email
+ * @param repo the repository
+ */
+GIT_EXTERN(int) git_repository_ident(const char **name, const char **email, const git_repository *repo);
+
+/**
+ * Set the identity to be used for writing reflogs
+ *
+ * If both are set, this name and email will be used to write to the
+ * reflog. Pass NULL to unset. When unset, the identity will be taken
+ * from the repository's configuration.
+ *
+ * @param repo the repository to configure
+ * @param name the name to use for the reflog entries
+ * @param email the email to use for the reflog entries
+ */
+GIT_EXTERN(int) git_repository_set_ident(git_repository *repo, const char *name, const char *email);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/reset.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/reset.h
new file mode 100755
index 0000000..7907529
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/reset.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_reset_h__
+#define INCLUDE_git_reset_h__
+
+#include "common.h"
+#include "types.h"
+#include "strarray.h"
+#include "checkout.h"
+
+/**
+ * @file git2/reset.h
+ * @brief Git reset management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Kinds of reset operation
+ */
+typedef enum {
+	GIT_RESET_SOFT  = 1, /**< Move the head to the given commit */
+	GIT_RESET_MIXED = 2, /**< SOFT plus reset index to the commit */
+	GIT_RESET_HARD  = 3, /**< MIXED plus changes in working tree discarded */
+} git_reset_t;
+
+/**
+ * Sets the current head to the specified commit oid and optionally
+ * resets the index and working tree to match.
+ *
+ * SOFT reset means the Head will be moved to the commit.
+ *
+ * MIXED reset will trigger a SOFT reset, plus the index will be replaced
+ * with the content of the commit tree.
+ *
+ * HARD reset will trigger a MIXED reset and the working directory will be
+ * replaced with the content of the index.  (Untracked and ignored files
+ * will be left alone, however.)
+ *
+ * TODO: Implement remaining kinds of resets.
+ *
+ * @param repo Repository where to perform the reset operation.
+ *
+ * @param target Committish to which the Head should be moved to. This object
+ * must belong to the given `repo` and can either be a git_commit or a
+ * git_tag. When a git_tag is being passed, it should be dereferencable
+ * to a git_commit which oid will be used as the target of the branch.
+ *
+ * @param reset_type Kind of reset operation to perform.
+ *
+ * @param checkout_opts Checkout options to be used for a HARD reset.
+ * The checkout_strategy field will be overridden (based on reset_type).
+ * This parameter can be used to propagate notify and progress callbacks.
+ *
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_reset(
+	git_repository *repo,
+	git_object *target,
+	git_reset_t reset_type,
+	const git_checkout_options *checkout_opts);
+
+/**
+ * Sets the current head to the specified commit oid and optionally
+ * resets the index and working tree to match.
+ *
+ * This behaves like `git_reset()` but takes an annotated commit,
+ * which lets you specify which extended sha syntax string was
+ * specified by a user, allowing for more exact reflog messages.
+ *
+ * See the documentation for `git_reset()`.
+ *
+ * @see git_reset
+ */
+GIT_EXTERN(int) git_reset_from_annotated(
+	git_repository *repo,
+	git_annotated_commit *commit,
+	git_reset_t reset_type,
+	const git_checkout_options *checkout_opts);
+
+/**
+ * Updates some entries in the index from the target commit tree.
+ *
+ * The scope of the updated entries is determined by the paths
+ * being passed in the `pathspec` parameters.
+ *
+ * Passing a NULL `target` will result in removing
+ * entries in the index matching the provided pathspecs.
+ *
+ * @param repo Repository where to perform the reset operation.
+ *
+ * @param target The committish which content will be used to reset the content
+ * of the index.
+ *
+ * @param pathspecs List of pathspecs to operate on.
+ *
+ * @return 0 on success or an error code < 0
+ */
+GIT_EXTERN(int) git_reset_default(
+	git_repository *repo,
+	git_object *target,
+	git_strarray* pathspecs);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/revert.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/revert.h
new file mode 100755
index 0000000..2de1942
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/revert.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_revert_h__
+#define INCLUDE_git_revert_h__
+
+#include "common.h"
+#include "types.h"
+#include "merge.h"
+
+/**
+ * @file git2/revert.h
+ * @brief Git revert routines
+ * @defgroup git_revert Git revert routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Options for revert
+ */
+typedef struct {
+	unsigned int version;
+
+	/** For merge commits, the "mainline" is treated as the parent. */
+	unsigned int mainline;
+
+	git_merge_options merge_opts; /**< Options for the merging */
+	git_checkout_options checkout_opts; /**< Options for the checkout */
+} git_revert_options;
+
+#define GIT_REVERT_OPTIONS_VERSION 1
+#define GIT_REVERT_OPTIONS_INIT {GIT_REVERT_OPTIONS_VERSION, 0, GIT_MERGE_OPTIONS_INIT, GIT_CHECKOUT_OPTIONS_INIT}
+
+/**
+ * Initializes a `git_revert_options` with default values. Equivalent to
+ * creating an instance with GIT_REVERT_OPTIONS_INIT.
+ *
+ * @param opts the `git_revert_options` struct to initialize
+ * @param version Version of struct; pass `GIT_REVERT_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_revert_init_options(
+	git_revert_options *opts,
+	unsigned int version);
+
+/**
+ * Reverts the given commit against the given "our" commit, producing an
+ * index that reflects the result of the revert.
+ *
+ * The returned index must be freed explicitly with `git_index_free`.
+ *
+ * @param out pointer to store the index result in
+ * @param repo the repository that contains the given commits
+ * @param revert_commit the commit to revert
+ * @param our_commit the commit to revert against (eg, HEAD)
+ * @param mainline the parent of the revert commit, if it is a merge
+ * @param merge_options the merge options (or null for defaults)
+ * @return zero on success, -1 on failure.
+ */
+GIT_EXTERN(int) git_revert_commit(
+	git_index **out,
+	git_repository *repo,
+	git_commit *revert_commit,
+	git_commit *our_commit,
+	unsigned int mainline,
+	const git_merge_options *merge_options);
+
+/**
+ * Reverts the given commit, producing changes in the index and working directory.
+ *
+ * @param repo the repository to revert
+ * @param commit the commit to revert
+ * @param given_opts merge flags
+ * @return zero on success, -1 on failure.
+ */
+GIT_EXTERN(int) git_revert(
+	git_repository *repo,
+	git_commit *commit,
+	const git_revert_options *given_opts);
+
+/** @} */
+GIT_END_DECL
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/revparse.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/revparse.h
new file mode 100755
index 0000000..d170e16
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/revparse.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_revparse_h__
+#define INCLUDE_git_revparse_h__
+
+#include "common.h"
+#include "types.h"
+
+/**
+ * @file git2/revparse.h
+ * @brief Git revision parsing routines
+ * @defgroup git_revparse Git revision parsing routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Find a single object, as specified by a revision string.
+ *
+ * See `man gitrevisions`, or
+ * http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for
+ * information on the syntax accepted.
+ *
+ * The returned object should be released with `git_object_free` when no
+ * longer needed.
+ *
+ * @param out pointer to output object
+ * @param repo the repository to search in
+ * @param spec the textual specification for an object
+ * @return 0 on success, GIT_ENOTFOUND, GIT_EAMBIGUOUS, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_revparse_single(
+	git_object **out, git_repository *repo, const char *spec);
+
+/**
+ * Find a single object and intermediate reference by a revision string.
+ *
+ * See `man gitrevisions`, or
+ * http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for
+ * information on the syntax accepted.
+ *
+ * In some cases (`@{<-n>}` or `<branchname>@{upstream}`), the expression may
+ * point to an intermediate reference. When such expressions are being passed
+ * in, `reference_out` will be valued as well.
+ *
+ * The returned object should be released with `git_object_free` and the
+ * returned reference with `git_reference_free` when no longer needed.
+ *
+ * @param object_out pointer to output object
+ * @param reference_out pointer to output reference or NULL
+ * @param repo the repository to search in
+ * @param spec the textual specification for an object
+ * @return 0 on success, GIT_ENOTFOUND, GIT_EAMBIGUOUS, GIT_EINVALIDSPEC
+ * or an error code
+ */
+GIT_EXTERN(int) git_revparse_ext(
+	git_object **object_out,
+	git_reference **reference_out,
+	git_repository *repo,
+	const char *spec);
+
+/**
+ * Revparse flags.  These indicate the intended behavior of the spec passed to
+ * git_revparse.
+ */
+typedef enum {
+	/** The spec targeted a single object. */
+	GIT_REVPARSE_SINGLE         = 1 << 0,
+	/** The spec targeted a range of commits. */
+	GIT_REVPARSE_RANGE          = 1 << 1,
+	/** The spec used the '...' operator, which invokes special semantics. */
+	GIT_REVPARSE_MERGE_BASE     = 1 << 2,
+} git_revparse_mode_t;
+
+/**
+ * Git Revision Spec: output of a `git_revparse` operation
+ */
+typedef struct {
+	/** The left element of the revspec; must be freed by the user */
+	git_object *from;
+	/** The right element of the revspec; must be freed by the user */
+	git_object *to;
+	/** The intent of the revspec (i.e. `git_revparse_mode_t` flags) */
+	unsigned int flags;
+} git_revspec;
+
+/**
+ * Parse a revision string for `from`, `to`, and intent.
+ *
+ * See `man gitrevisions` or
+ * http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for
+ * information on the syntax accepted.
+ *
+ * @param revspec Pointer to an user-allocated git_revspec struct where
+ *	              the result of the rev-parse will be stored
+ * @param repo the repository to search in
+ * @param spec the rev-parse spec to parse
+ * @return 0 on success, GIT_INVALIDSPEC, GIT_ENOTFOUND, GIT_EAMBIGUOUS or an error code
+ */
+GIT_EXTERN(int) git_revparse(
+	git_revspec *revspec,
+	git_repository *repo,
+	const char *spec);
+
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/revwalk.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/revwalk.h
new file mode 100755
index 0000000..2cc0053
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/revwalk.h
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_revwalk_h__
+#define INCLUDE_git_revwalk_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+
+/**
+ * @file git2/revwalk.h
+ * @brief Git revision traversal routines
+ * @defgroup git_revwalk Git revision traversal routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Flags to specify the sorting which a revwalk should perform.
+ */
+typedef enum {
+	/**
+	 * Sort the repository contents in no particular ordering;
+	 * this sorting is arbitrary, implementation-specific
+	 * and subject to change at any time.
+	 * This is the default sorting for new walkers.
+	 */
+	GIT_SORT_NONE = 0,
+
+	/**
+	 * Sort the repository contents in topological order
+	 * (parents before children); this sorting mode
+	 * can be combined with time sorting.
+	 */
+	GIT_SORT_TOPOLOGICAL = 1 << 0,
+
+	/**
+	 * Sort the repository contents by commit time;
+	 * this sorting mode can be combined with
+	 * topological sorting.
+	 */
+	GIT_SORT_TIME = 1 << 1,
+
+	/**
+	 * Iterate through the repository contents in reverse
+	 * order; this sorting mode can be combined with
+	 * any of the above.
+	 */
+	GIT_SORT_REVERSE = 1 << 2,
+} git_sort_t;
+
+/**
+ * Allocate a new revision walker to iterate through a repo.
+ *
+ * This revision walker uses a custom memory pool and an internal
+ * commit cache, so it is relatively expensive to allocate.
+ *
+ * For maximum performance, this revision walker should be
+ * reused for different walks.
+ *
+ * This revision walker is *not* thread safe: it may only be
+ * used to walk a repository on a single thread; however,
+ * it is possible to have several revision walkers in
+ * several different threads walking the same repository.
+ *
+ * @param out pointer to the new revision walker
+ * @param repo the repo to walk through
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_new(git_revwalk **out, git_repository *repo);
+
+/**
+ * Reset the revision walker for reuse.
+ *
+ * This will clear all the pushed and hidden commits, and
+ * leave the walker in a blank state (just like at
+ * creation) ready to receive new commit pushes and
+ * start a new walk.
+ *
+ * The revision walk is automatically reset when a walk
+ * is over.
+ *
+ * @param walker handle to reset.
+ */
+GIT_EXTERN(void) git_revwalk_reset(git_revwalk *walker);
+
+/**
+ * Add a new root for the traversal
+ *
+ * The pushed commit will be marked as one of the roots from which to
+ * start the walk. This commit may not be walked if it or a child is
+ * hidden.
+ *
+ * At least one commit must be pushed onto the walker before a walk
+ * can be started.
+ *
+ * The given id must belong to a committish on the walked
+ * repository.
+ *
+ * @param walk the walker being used for the traversal.
+ * @param id the oid of the commit to start from.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *id);
+
+/**
+ * Push matching references
+ *
+ * The OIDs pointed to by the references that match the given glob
+ * pattern will be pushed to the revision walker.
+ *
+ * A leading 'refs/' is implied if not present as well as a trailing
+ * '/\*' if the glob lacks '?', '\*' or '['.
+ *
+ * Any references matching this glob which do not point to a
+ * committish will be ignored.
+ *
+ * @param walk the walker being used for the traversal
+ * @param glob the glob pattern references should match
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_push_glob(git_revwalk *walk, const char *glob);
+
+/**
+ * Push the repository's HEAD
+ *
+ * @param walk the walker being used for the traversal
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_push_head(git_revwalk *walk);
+
+/**
+ * Mark a commit (and its ancestors) uninteresting for the output.
+ *
+ * The given id must belong to a committish on the walked
+ * repository.
+ *
+ * The resolved commit and all its parents will be hidden from the
+ * output on the revision walk.
+ *
+ * @param walk the walker being used for the traversal.
+ * @param commit_id the oid of commit that will be ignored during the traversal
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *commit_id);
+
+/**
+ * Hide matching references.
+ *
+ * The OIDs pointed to by the references that match the given glob
+ * pattern and their ancestors will be hidden from the output on the
+ * revision walk.
+ *
+ * A leading 'refs/' is implied if not present as well as a trailing
+ * '/\*' if the glob lacks '?', '\*' or '['.
+ *
+ * Any references matching this glob which do not point to a
+ * committish will be ignored.
+ *
+ * @param walk the walker being used for the traversal
+ * @param glob the glob pattern references should match
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_hide_glob(git_revwalk *walk, const char *glob);
+
+/**
+ * Hide the repository's HEAD
+ *
+ * @param walk the walker being used for the traversal
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_hide_head(git_revwalk *walk);
+
+/**
+ * Push the OID pointed to by a reference
+ *
+ * The reference must point to a committish.
+ *
+ * @param walk the walker being used for the traversal
+ * @param refname the reference to push
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_push_ref(git_revwalk *walk, const char *refname);
+
+/**
+ * Hide the OID pointed to by a reference
+ *
+ * The reference must point to a committish.
+ *
+ * @param walk the walker being used for the traversal
+ * @param refname the reference to hide
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_revwalk_hide_ref(git_revwalk *walk, const char *refname);
+
+/**
+ * Get the next commit from the revision walk.
+ *
+ * The initial call to this method is *not* blocking when
+ * iterating through a repo with a time-sorting mode.
+ *
+ * Iterating with Topological or inverted modes makes the initial
+ * call blocking to preprocess the commit list, but this block should be
+ * mostly unnoticeable on most repositories (topological preprocessing
+ * times at 0.3s on the git.git repo).
+ *
+ * The revision walker is reset when the walk is over.
+ *
+ * @param out Pointer where to store the oid of the next commit
+ * @param walk the walker to pop the commit from.
+ * @return 0 if the next commit was found;
+ *	GIT_ITEROVER if there are no commits left to iterate
+ */
+GIT_EXTERN(int) git_revwalk_next(git_oid *out, git_revwalk *walk);
+
+/**
+ * Change the sorting mode when iterating through the
+ * repository's contents.
+ *
+ * Changing the sorting mode resets the walker.
+ *
+ * @param walk the walker being used for the traversal.
+ * @param sort_mode combination of GIT_SORT_XXX flags
+ */
+GIT_EXTERN(void) git_revwalk_sorting(git_revwalk *walk, unsigned int sort_mode);
+
+/**
+ * Push and hide the respective endpoints of the given range.
+ *
+ * The range should be of the form
+ *   <commit>..<commit>
+ * where each <commit> is in the form accepted by 'git_revparse_single'.
+ * The left-hand commit will be hidden and the right-hand commit pushed.
+ *
+ * @param walk the walker being used for the traversal
+ * @param range the range
+ * @return 0 or an error code
+ *
+ */
+GIT_EXTERN(int) git_revwalk_push_range(git_revwalk *walk, const char *range);
+
+/**
+ * Simplify the history by first-parent
+ *
+ * No parents other than the first for each commit will be enqueued.
+ */
+GIT_EXTERN(void) git_revwalk_simplify_first_parent(git_revwalk *walk);
+
+
+/**
+ * Free a revision walker previously allocated.
+ *
+ * @param walk traversal handle to close. If NULL nothing occurs.
+ */
+GIT_EXTERN(void) git_revwalk_free(git_revwalk *walk);
+
+/**
+ * Return the repository on which this walker
+ * is operating.
+ *
+ * @param walk the revision walker
+ * @return the repository being walked
+ */
+GIT_EXTERN(git_repository *) git_revwalk_repository(git_revwalk *walk);
+
+/**
+ * This is a callback function that user can provide to hide a
+ * commit and its parents. If the callback function returns non-zero value,
+ * then this commit and its parents will be hidden.
+ *
+ * @param commit_id oid of Commit
+ * @param payload User-specified pointer to data to be passed as data payload
+ */
+typedef int(*git_revwalk_hide_cb)(
+	const git_oid *commit_id,
+	void *payload);
+
+/**
+ * Adds a callback function to hide a commit and its parents
+ *
+ * @param walk the revision walker
+ * @param hide_cb  callback function to hide a commit and its parents
+ * @param payload  data payload to be passed to callback function
+ */
+GIT_EXTERN(int) git_revwalk_add_hide_cb(
+	git_revwalk *walk,
+	git_revwalk_hide_cb hide_cb,
+	void *payload);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/signature.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/signature.h
new file mode 100755
index 0000000..feb1b40
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/signature.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_signature_h__
+#define INCLUDE_git_signature_h__
+
+#include "common.h"
+#include "types.h"
+
+/**
+ * @file git2/signature.h
+ * @brief Git signature creation
+ * @defgroup git_signature Git signature creation
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create a new action signature.
+ *
+ * Call `git_signature_free()` to free the data.
+ *
+ * Note: angle brackets ('<' and '>') characters are not allowed
+ * to be used in either the `name` or the `email` parameter.
+ *
+ * @param out new signature, in case of error NULL
+ * @param name name of the person
+ * @param email email of the person
+ * @param time time when the action happened
+ * @param offset timezone offset in minutes for the time
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_signature_new(git_signature **out, const char *name, const char *email, git_time_t time, int offset);
+
+/**
+ * Create a new action signature with a timestamp of 'now'.
+ *
+ * Call `git_signature_free()` to free the data.
+ *
+ * @param out new signature, in case of error NULL
+ * @param name name of the person
+ * @param email email of the person
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_signature_now(git_signature **out, const char *name, const char *email);
+
+/**
+ * Create a new action signature with default user and now timestamp.
+ *
+ * This looks up the user.name and user.email from the configuration and
+ * uses the current time as the timestamp, and creates a new signature
+ * based on that information.  It will return GIT_ENOTFOUND if either the
+ * user.name or user.email are not set.
+ *
+ * @param out new signature
+ * @param repo repository pointer
+ * @return 0 on success, GIT_ENOTFOUND if config is missing, or error code
+ */
+GIT_EXTERN(int) git_signature_default(git_signature **out, git_repository *repo);
+
+/**
+ * Create a copy of an existing signature.  All internal strings are also
+ * duplicated.
+ *
+ * Call `git_signature_free()` to free the data.
+ *
+ * @param dest pointer where to store the copy
+ * @param sig signature to duplicate
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_signature_dup(git_signature **dest, const git_signature *sig);
+
+/**
+ * Free an existing signature.
+ *
+ * Because the signature is not an opaque structure, it is legal to free it
+ * manually, but be sure to free the "name" and "email" strings in addition
+ * to the structure itself.
+ *
+ * @param sig signature to free
+ */
+GIT_EXTERN(void) git_signature_free(git_signature *sig);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/stash.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/stash.h
new file mode 100755
index 0000000..526db0b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/stash.h
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_stash_h__
+#define INCLUDE_git_stash_h__
+
+#include "common.h"
+#include "types.h"
+
+/**
+ * @file git2/stash.h
+ * @brief Git stash management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Stash flags
+ */
+typedef enum {
+	/**
+	 * No option, default
+	 */
+	GIT_STASH_DEFAULT = 0,
+
+	/**
+	 * All changes already added to the index are left intact in
+	 * the working directory
+	 */
+	GIT_STASH_KEEP_INDEX = (1 << 0),
+
+	/**
+	 * All untracked files are also stashed and then cleaned up
+	 * from the working directory
+	 */
+	GIT_STASH_INCLUDE_UNTRACKED = (1 << 1),
+
+	/**
+	 * All ignored files are also stashed and then cleaned up from
+	 * the working directory
+	 */
+	GIT_STASH_INCLUDE_IGNORED = (1 << 2),
+} git_stash_flags;
+
+/**
+ * Save the local modifications to a new stash.
+ *
+ * @param out Object id of the commit containing the stashed state.
+ * This commit is also the target of the direct reference refs/stash.
+ *
+ * @param repo The owning repository.
+ *
+ * @param stasher The identity of the person performing the stashing.
+ *
+ * @param message Optional description along with the stashed state.
+ *
+ * @param flags Flags to control the stashing process. (see GIT_STASH_* above)
+ *
+ * @return 0 on success, GIT_ENOTFOUND where there's nothing to stash,
+ * or error code.
+ */
+GIT_EXTERN(int) git_stash_save(
+	git_oid *out,
+	git_repository *repo,
+	const git_signature *stasher,
+	const char *message,
+	unsigned int flags);
+
+/** Stash application flags. */
+typedef enum {
+	GIT_STASH_APPLY_DEFAULT = 0,
+
+	/* Try to reinstate not only the working tree's changes,
+	 * but also the index's changes.
+	 */
+	GIT_STASH_APPLY_REINSTATE_INDEX = (1 << 0),
+} git_stash_apply_flags;
+
+typedef enum {
+	GIT_STASH_APPLY_PROGRESS_NONE = 0,
+
+	/** Loading the stashed data from the object database. */
+	GIT_STASH_APPLY_PROGRESS_LOADING_STASH,
+
+	/** The stored index is being analyzed. */
+	GIT_STASH_APPLY_PROGRESS_ANALYZE_INDEX,
+
+	/** The modified files are being analyzed. */
+	GIT_STASH_APPLY_PROGRESS_ANALYZE_MODIFIED,
+
+	/** The untracked and ignored files are being analyzed. */
+	GIT_STASH_APPLY_PROGRESS_ANALYZE_UNTRACKED,
+
+	/** The untracked files are being written to disk. */
+	GIT_STASH_APPLY_PROGRESS_CHECKOUT_UNTRACKED,
+
+	/** The modified files are being written to disk. */
+	GIT_STASH_APPLY_PROGRESS_CHECKOUT_MODIFIED,
+
+	/** The stash was applied successfully. */
+	GIT_STASH_APPLY_PROGRESS_DONE,
+} git_stash_apply_progress_t;
+
+/**
+ * Stash application progress notification function.
+ * Return 0 to continue processing, or a negative value to
+ * abort the stash application.
+ */
+typedef int (*git_stash_apply_progress_cb)(
+	git_stash_apply_progress_t progress,
+	void *payload);
+
+/** Stash application options structure.
+ *
+ * Initialize with the `GIT_STASH_APPLY_OPTIONS_INIT` macro to set
+ * sensible defaults; for example:
+ *
+ *		git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
+ */
+typedef struct git_stash_apply_options {
+	unsigned int version;
+
+	/** See `git_stash_apply_flags_t`, above. */
+	git_stash_apply_flags flags;
+
+	/** Options to use when writing files to the working directory. */
+	git_checkout_options checkout_options;
+
+	/** Optional callback to notify the consumer of application progress. */
+	git_stash_apply_progress_cb progress_cb;
+	void *progress_payload;
+} git_stash_apply_options;
+
+#define GIT_STASH_APPLY_OPTIONS_VERSION 1
+#define GIT_STASH_APPLY_OPTIONS_INIT { \
+	GIT_STASH_APPLY_OPTIONS_VERSION, \
+	GIT_STASH_APPLY_DEFAULT, \
+	GIT_CHECKOUT_OPTIONS_INIT }
+
+/**
+ * Initializes a `git_stash_apply_options` with default values. Equivalent to
+ * creating an instance with GIT_STASH_APPLY_OPTIONS_INIT.
+ *
+ * @param opts the `git_stash_apply_options` instance to initialize.
+ * @param version the version of the struct; you should pass
+ *        `GIT_STASH_APPLY_OPTIONS_INIT` here.
+ * @return Zero on success; -1 on failure.
+ */
+int git_stash_apply_init_options(
+	git_stash_apply_options *opts, unsigned int version);
+
+/**
+ * Apply a single stashed state from the stash list.
+ *
+ * If local changes in the working directory conflict with changes in the
+ * stash then GIT_EMERGECONFLICT will be returned.  In this case, the index
+ * will always remain unmodified and all files in the working directory will
+ * remain unmodified.  However, if you are restoring untracked files or
+ * ignored files and there is a conflict when applying the modified files,
+ * then those files will remain in the working directory.
+ *
+ * If passing the GIT_STASH_APPLY_REINSTATE_INDEX flag and there would be
+ * conflicts when reinstating the index, the function will return
+ * GIT_EMERGECONFLICT and both the working directory and index will be left
+ * unmodified.
+ *
+ * Note that a minimum checkout strategy of `GIT_CHECKOUT_SAFE` is implied.
+ *
+ * @param repo The owning repository.
+ * @param index The position within the stash list. 0 points to the
+ *              most recent stashed state.
+ * @param options Options to control how stashes are applied.
+ *
+ * @return 0 on success, GIT_ENOTFOUND if there's no stashed state for the
+ *         given index, GIT_EMERGECONFLICT if changes exist in the working
+ *         directory, or an error code
+ */
+GIT_EXTERN(int) git_stash_apply(
+	git_repository *repo,
+	size_t index,
+	const git_stash_apply_options *options);
+
+/**
+ * This is a callback function you can provide to iterate over all the
+ * stashed states that will be invoked per entry.
+ *
+ * @param index The position within the stash list. 0 points to the
+ *              most recent stashed state.
+ * @param message The stash message.
+ * @param stash_id The commit oid of the stashed state.
+ * @param payload Extra parameter to callback function.
+ * @return 0 to continue iterating or non-zero to stop.
+ */
+typedef int (*git_stash_cb)(
+	size_t index,
+	const char* message,
+	const git_oid *stash_id,
+	void *payload);
+
+/**
+ * Loop over all the stashed states and issue a callback for each one.
+ *
+ * If the callback returns a non-zero value, this will stop looping.
+ *
+ * @param repo Repository where to find the stash.
+ *
+ * @param callback Callback to invoke per found stashed state. The most
+ *                 recent stash state will be enumerated first.
+ *
+ * @param payload Extra parameter to callback function.
+ *
+ * @return 0 on success, non-zero callback return value, or error code.
+ */
+GIT_EXTERN(int) git_stash_foreach(
+	git_repository *repo,
+	git_stash_cb callback,
+	void *payload);
+
+/**
+ * Remove a single stashed state from the stash list.
+ *
+ * @param repo The owning repository.
+ *
+ * @param index The position within the stash list. 0 points to the
+ * most recent stashed state.
+ *
+ * @return 0 on success, GIT_ENOTFOUND if there's no stashed state for the given
+ * index, or error code.
+ */
+GIT_EXTERN(int) git_stash_drop(
+	git_repository *repo,
+	size_t index);
+
+/**
+ * Apply a single stashed state from the stash list and remove it from the list
+ * if successful.
+ *
+ * @param repo The owning repository.
+ * @param index The position within the stash list. 0 points to the
+ *              most recent stashed state.
+ * @param options Options to control how stashes are applied.
+ *
+ * @return 0 on success, GIT_ENOTFOUND if there's no stashed state for the given
+ * index, or error code. (see git_stash_apply() above for details)
+*/
+GIT_EXTERN(int) git_stash_pop(
+	git_repository *repo,
+	size_t index,
+	const git_stash_apply_options *options);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/status.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/status.h
new file mode 100755
index 0000000..6711139
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/status.h
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_status_h__
+#define INCLUDE_git_status_h__
+
+#include "common.h"
+#include "types.h"
+
+/**
+ * @file git2/status.h
+ * @brief Git file status routines
+ * @defgroup git_status Git file status routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Status flags for a single file.
+ *
+ * A combination of these values will be returned to indicate the status of
+ * a file.  Status compares the working directory, the index, and the
+ * current HEAD of the repository.  The `GIT_STATUS_INDEX` set of flags
+ * represents the status of file in the index relative to the HEAD, and the
+ * `GIT_STATUS_WT` set of flags represent the status of the file in the
+ * working directory relative to the index.
+ */
+typedef enum {
+	GIT_STATUS_CURRENT = 0,
+
+	GIT_STATUS_INDEX_NEW        = (1u << 0),
+	GIT_STATUS_INDEX_MODIFIED   = (1u << 1),
+	GIT_STATUS_INDEX_DELETED    = (1u << 2),
+	GIT_STATUS_INDEX_RENAMED    = (1u << 3),
+	GIT_STATUS_INDEX_TYPECHANGE = (1u << 4),
+
+	GIT_STATUS_WT_NEW           = (1u << 7),
+	GIT_STATUS_WT_MODIFIED      = (1u << 8),
+	GIT_STATUS_WT_DELETED       = (1u << 9),
+	GIT_STATUS_WT_TYPECHANGE    = (1u << 10),
+	GIT_STATUS_WT_RENAMED       = (1u << 11),
+	GIT_STATUS_WT_UNREADABLE    = (1u << 12),
+
+	GIT_STATUS_IGNORED          = (1u << 14),
+	GIT_STATUS_CONFLICTED       = (1u << 15),
+} git_status_t;
+
+/**
+ * Function pointer to receive status on individual files
+ *
+ * `path` is the relative path to the file from the root of the repository.
+ *
+ * `status_flags` is a combination of `git_status_t` values that apply.
+ *
+ * `payload` is the value you passed to the foreach function as payload.
+ */
+typedef int (*git_status_cb)(
+	const char *path, unsigned int status_flags, void *payload);
+
+/**
+ * Select the files on which to report status.
+ *
+ * With `git_status_foreach_ext`, this will control which changes get
+ * callbacks.  With `git_status_list_new`, these will control which
+ * changes are included in the list.
+ *
+ * - GIT_STATUS_SHOW_INDEX_AND_WORKDIR is the default.  This roughly
+ *   matches `git status --porcelain` regarding which files are
+ *   included and in what order.
+ * - GIT_STATUS_SHOW_INDEX_ONLY only gives status based on HEAD to index
+ *   comparison, not looking at working directory changes.
+ * - GIT_STATUS_SHOW_WORKDIR_ONLY only gives status based on index to
+ *   working directory comparison, not comparing the index to the HEAD.
+ */
+typedef enum {
+	GIT_STATUS_SHOW_INDEX_AND_WORKDIR = 0,
+	GIT_STATUS_SHOW_INDEX_ONLY = 1,
+	GIT_STATUS_SHOW_WORKDIR_ONLY = 2,
+} git_status_show_t;
+
+/**
+ * Flags to control status callbacks
+ *
+ * - GIT_STATUS_OPT_INCLUDE_UNTRACKED says that callbacks should be made
+ *   on untracked files.  These will only be made if the workdir files are
+ *   included in the status "show" option.
+ * - GIT_STATUS_OPT_INCLUDE_IGNORED says that ignored files get callbacks.
+ *   Again, these callbacks will only be made if the workdir files are
+ *   included in the status "show" option.
+ * - GIT_STATUS_OPT_INCLUDE_UNMODIFIED indicates that callback should be
+ *   made even on unmodified files.
+ * - GIT_STATUS_OPT_EXCLUDE_SUBMODULES indicates that submodules should be
+ *   skipped.  This only applies if there are no pending typechanges to
+ *   the submodule (either from or to another type).
+ * - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that all files in
+ *   untracked directories should be included.  Normally if an entire
+ *   directory is new, then just the top-level directory is included (with
+ *   a trailing slash on the entry name).  This flag says to include all
+ *   of the individual files in the directory instead.
+ * - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH indicates that the given path
+ *   should be treated as a literal path, and not as a pathspec pattern.
+ * - GIT_STATUS_OPT_RECURSE_IGNORED_DIRS indicates that the contents of
+ *   ignored directories should be included in the status.  This is like
+ *   doing `git ls-files -o -i --exclude-standard` with core git.
+ * - GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX indicates that rename detection
+ *   should be processed between the head and the index and enables
+ *   the GIT_STATUS_INDEX_RENAMED as a possible status flag.
+ * - GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR indicates that rename
+ *   detection should be run between the index and the working directory
+ *   and enabled GIT_STATUS_WT_RENAMED as a possible status flag.
+ * - GIT_STATUS_OPT_SORT_CASE_SENSITIVELY overrides the native case
+ *   sensitivity for the file system and forces the output to be in
+ *   case-sensitive order
+ * - GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY overrides the native case
+ *   sensitivity for the file system and forces the output to be in
+ *   case-insensitive order
+ * - GIT_STATUS_OPT_RENAMES_FROM_REWRITES indicates that rename detection
+ *   should include rewritten files
+ * - GIT_STATUS_OPT_NO_REFRESH bypasses the default status behavior of
+ *   doing a "soft" index reload (i.e. reloading the index data if the
+ *   file on disk has been modified outside libgit2).
+ * - GIT_STATUS_OPT_UPDATE_INDEX tells libgit2 to refresh the stat cache
+ *   in the index for files that are unchanged but have out of date stat
+ *   information in the index.  It will result in less work being done on
+ *   subsequent calls to get status.  This is mutually exclusive with the
+ *   NO_REFRESH option.
+ *
+ * Calling `git_status_foreach()` is like calling the extended version
+ * with: GIT_STATUS_OPT_INCLUDE_IGNORED, GIT_STATUS_OPT_INCLUDE_UNTRACKED,
+ * and GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS.  Those options are bundled
+ * together as `GIT_STATUS_OPT_DEFAULTS` if you want them as a baseline.
+ */
+typedef enum {
+	GIT_STATUS_OPT_INCLUDE_UNTRACKED                = (1u << 0),
+	GIT_STATUS_OPT_INCLUDE_IGNORED                  = (1u << 1),
+	GIT_STATUS_OPT_INCLUDE_UNMODIFIED               = (1u << 2),
+	GIT_STATUS_OPT_EXCLUDE_SUBMODULES               = (1u << 3),
+	GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS           = (1u << 4),
+	GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH           = (1u << 5),
+	GIT_STATUS_OPT_RECURSE_IGNORED_DIRS             = (1u << 6),
+	GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX            = (1u << 7),
+	GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR         = (1u << 8),
+	GIT_STATUS_OPT_SORT_CASE_SENSITIVELY            = (1u << 9),
+	GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY          = (1u << 10),
+	GIT_STATUS_OPT_RENAMES_FROM_REWRITES            = (1u << 11),
+	GIT_STATUS_OPT_NO_REFRESH                       = (1u << 12),
+	GIT_STATUS_OPT_UPDATE_INDEX                     = (1u << 13),
+	GIT_STATUS_OPT_INCLUDE_UNREADABLE               = (1u << 14),
+	GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED  = (1u << 15),
+} git_status_opt_t;
+
+#define GIT_STATUS_OPT_DEFAULTS \
+	(GIT_STATUS_OPT_INCLUDE_IGNORED | \
+	GIT_STATUS_OPT_INCLUDE_UNTRACKED | \
+	GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS)
+
+/**
+ * Options to control how `git_status_foreach_ext()` will issue callbacks.
+ *
+ * This structure is set so that zeroing it out will give you relatively
+ * sane defaults.
+ *
+ * The `show` value is one of the `git_status_show_t` constants that
+ * control which files to scan and in what order.
+ *
+ * The `flags` value is an OR'ed combination of the `git_status_opt_t`
+ * values above.
+ *
+ * The `pathspec` is an array of path patterns to match (using
+ * fnmatch-style matching), or just an array of paths to match exactly if
+ * `GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH` is specified in the flags.
+ */
+typedef struct {
+	unsigned int      version;
+	git_status_show_t show;
+	unsigned int      flags;
+	git_strarray      pathspec;
+} git_status_options;
+
+#define GIT_STATUS_OPTIONS_VERSION 1
+#define GIT_STATUS_OPTIONS_INIT {GIT_STATUS_OPTIONS_VERSION}
+
+/**
+ * Initializes a `git_status_options` with default values. Equivalent to
+ * creating an instance with GIT_STATUS_OPTIONS_INIT.
+ *
+ * @param opts The `git_status_options` instance to initialize.
+ * @param version Version of struct; pass `GIT_STATUS_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_status_init_options(
+	git_status_options *opts,
+	unsigned int version);
+
+/**
+ * A status entry, providing the differences between the file as it exists
+ * in HEAD and the index, and providing the differences between the index
+ * and the working directory.
+ *
+ * The `status` value provides the status flags for this file.
+ *
+ * The `head_to_index` value provides detailed information about the
+ * differences between the file in HEAD and the file in the index.
+ *
+ * The `index_to_workdir` value provides detailed information about the
+ * differences between the file in the index and the file in the
+ * working directory.
+ */
+typedef struct {
+	git_status_t status;
+	git_diff_delta *head_to_index;
+	git_diff_delta *index_to_workdir;
+} git_status_entry;
+
+
+/**
+ * Gather file statuses and run a callback for each one.
+ *
+ * The callback is passed the path of the file, the status (a combination of
+ * the `git_status_t` values above) and the `payload` data pointer passed
+ * into this function.
+ *
+ * If the callback returns a non-zero value, this function will stop looping
+ * and return that value to caller.
+ *
+ * @param repo A repository object
+ * @param callback The function to call on each file
+ * @param payload Pointer to pass through to callback function
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_status_foreach(
+	git_repository *repo,
+	git_status_cb callback,
+	void *payload);
+
+/**
+ * Gather file status information and run callbacks as requested.
+ *
+ * This is an extended version of the `git_status_foreach()` API that
+ * allows for more granular control over which paths will be processed and
+ * in what order.  See the `git_status_options` structure for details
+ * about the additional controls that this makes available.
+ *
+ * Note that if a `pathspec` is given in the `git_status_options` to filter
+ * the status, then the results from rename detection (if you enable it) may
+ * not be accurate.  To do rename detection properly, this must be called
+ * with no `pathspec` so that all files can be considered.
+ *
+ * @param repo Repository object
+ * @param opts Status options structure
+ * @param callback The function to call on each file
+ * @param payload Pointer to pass through to callback function
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+GIT_EXTERN(int) git_status_foreach_ext(
+	git_repository *repo,
+	const git_status_options *opts,
+	git_status_cb callback,
+	void *payload);
+
+/**
+ * Get file status for a single file.
+ *
+ * This tries to get status for the filename that you give.  If no files
+ * match that name (in either the HEAD, index, or working directory), this
+ * returns GIT_ENOTFOUND.
+ *
+ * If the name matches multiple files (for example, if the `path` names a
+ * directory or if running on a case- insensitive filesystem and yet the
+ * HEAD has two entries that both match the path), then this returns
+ * GIT_EAMBIGUOUS because it cannot give correct results.
+ *
+ * This does not do any sort of rename detection.  Renames require a set of
+ * targets and because of the path filtering, there is not enough
+ * information to check renames correctly.  To check file status with rename
+ * detection, there is no choice but to do a full `git_status_list_new` and
+ * scan through looking for the path that you are interested in.
+ *
+ * @param status_flags Output combination of git_status_t values for file
+ * @param repo A repository object
+ * @param path The exact path to retrieve status for relative to the
+ * repository working directory
+ * @return 0 on success, GIT_ENOTFOUND if the file is not found in the HEAD,
+ *      index, and work tree, GIT_EAMBIGUOUS if `path` matches multiple files
+ *      or if it refers to a folder, and -1 on other errors.
+ */
+GIT_EXTERN(int) git_status_file(
+	unsigned int *status_flags,
+	git_repository *repo,
+	const char *path);
+
+/**
+ * Gather file status information and populate the `git_status_list`.
+ *
+ * Note that if a `pathspec` is given in the `git_status_options` to filter
+ * the status, then the results from rename detection (if you enable it) may
+ * not be accurate.  To do rename detection properly, this must be called
+ * with no `pathspec` so that all files can be considered.
+ *
+ * @param out Pointer to store the status results in
+ * @param repo Repository object
+ * @param opts Status options structure
+ * @return 0 on success or error code
+ */
+GIT_EXTERN(int) git_status_list_new(
+	git_status_list **out,
+	git_repository *repo,
+	const git_status_options *opts);
+
+/**
+ * Gets the count of status entries in this list.
+ *
+ * If there are no changes in status (at least according the options given
+ * when the status list was created), this can return 0.
+ *
+ * @param statuslist Existing status list object
+ * @return the number of status entries
+ */
+GIT_EXTERN(size_t) git_status_list_entrycount(
+	git_status_list *statuslist);
+
+/**
+ * Get a pointer to one of the entries in the status list.
+ *
+ * The entry is not modifiable and should not be freed.
+ *
+ * @param statuslist Existing status list object
+ * @param idx Position of the entry
+ * @return Pointer to the entry; NULL if out of bounds
+ */
+GIT_EXTERN(const git_status_entry *) git_status_byindex(
+	git_status_list *statuslist,
+	size_t idx);
+
+/**
+ * Free an existing status list
+ *
+ * @param statuslist Existing status list object
+ */
+GIT_EXTERN(void) git_status_list_free(
+	git_status_list *statuslist);
+
+/**
+ * Test if the ignore rules apply to a given file.
+ *
+ * This function checks the ignore rules to see if they would apply to the
+ * given file.  This indicates if the file would be ignored regardless of
+ * whether the file is already in the index or committed to the repository.
+ *
+ * One way to think of this is if you were to do "git add ." on the
+ * directory containing the file, would it be added or not?
+ *
+ * @param ignored Boolean returning 0 if the file is not ignored, 1 if it is
+ * @param repo A repository object
+ * @param path The file to check ignores for, rooted at the repo's workdir.
+ * @return 0 if ignore rules could be processed for the file (regardless
+ *         of whether it exists or not), or an error < 0 if they could not.
+ */
+GIT_EXTERN(int) git_status_should_ignore(
+	int *ignored,
+	git_repository *repo,
+	const char *path);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/stdint.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/stdint.h
new file mode 100755
index 0000000..c66fbb8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/stdint.h
@@ -0,0 +1,247 @@
+// ISO C9x  compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+//  Copyright (c) 2006-2008 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+//
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+//
+//   3. The name of the author may be used to endorse or promote products
+//      derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+#  include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+#     define _W64 __w64
+#  else
+#     define _W64
+#  endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+   typedef signed char       int8_t;
+   typedef signed short      int16_t;
+   typedef signed int        int32_t;
+   typedef unsigned char     uint8_t;
+   typedef unsigned short    uint16_t;
+   typedef unsigned int      uint32_t;
+#else
+   typedef signed __int8     int8_t;
+   typedef signed __int16    int16_t;
+   typedef signed __int32    int32_t;
+   typedef unsigned __int8   uint8_t;
+   typedef unsigned __int16  uint16_t;
+   typedef unsigned __int32  uint32_t;
+#endif
+typedef signed __int64       int64_t;
+typedef unsigned __int64     uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t    int_least8_t;
+typedef int16_t   int_least16_t;
+typedef int32_t   int_least32_t;
+typedef int64_t   int_least64_t;
+typedef uint8_t   uint_least8_t;
+typedef uint16_t  uint_least16_t;
+typedef uint32_t  uint_least32_t;
+typedef uint64_t  uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t    int_fast8_t;
+typedef int16_t   int_fast16_t;
+typedef int32_t   int_fast32_t;
+typedef int64_t   int_fast64_t;
+typedef uint8_t   uint_fast8_t;
+typedef uint16_t  uint_fast16_t;
+typedef uint32_t  uint_fast32_t;
+typedef uint64_t  uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+   typedef signed __int64    intptr_t;
+   typedef unsigned __int64  uintptr_t;
+#else // _WIN64 ][
+   typedef _W64 signed int   intptr_t;
+   typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t   intmax_t;
+typedef uint64_t  uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN     ((int8_t)_I8_MIN)
+#define INT8_MAX     _I8_MAX
+#define INT16_MIN    ((int16_t)_I16_MIN)
+#define INT16_MAX    _I16_MAX
+#define INT32_MIN    ((int32_t)_I32_MIN)
+#define INT32_MAX    _I32_MAX
+#define INT64_MIN    ((int64_t)_I64_MIN)
+#define INT64_MAX    _I64_MAX
+#define UINT8_MAX    _UI8_MAX
+#define UINT16_MAX   _UI16_MAX
+#define UINT32_MAX   _UI32_MAX
+#define UINT64_MAX   _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN    INT8_MIN
+#define INT_LEAST8_MAX    INT8_MAX
+#define INT_LEAST16_MIN   INT16_MIN
+#define INT_LEAST16_MAX   INT16_MAX
+#define INT_LEAST32_MIN   INT32_MIN
+#define INT_LEAST32_MAX   INT32_MAX
+#define INT_LEAST64_MIN   INT64_MIN
+#define INT_LEAST64_MAX   INT64_MAX
+#define UINT_LEAST8_MAX   UINT8_MAX
+#define UINT_LEAST16_MAX  UINT16_MAX
+#define UINT_LEAST32_MAX  UINT32_MAX
+#define UINT_LEAST64_MAX  UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN    INT8_MIN
+#define INT_FAST8_MAX    INT8_MAX
+#define INT_FAST16_MIN   INT16_MIN
+#define INT_FAST16_MAX   INT16_MAX
+#define INT_FAST32_MIN   INT32_MIN
+#define INT_FAST32_MAX   INT32_MAX
+#define INT_FAST64_MIN   INT64_MIN
+#define INT_FAST64_MAX   INT64_MAX
+#define UINT_FAST8_MAX   UINT8_MAX
+#define UINT_FAST16_MAX  UINT16_MAX
+#define UINT_FAST32_MAX  UINT32_MAX
+#define UINT_FAST64_MAX  UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+#  define INTPTR_MIN   INT64_MIN
+#  define INTPTR_MAX   INT64_MAX
+#  define UINTPTR_MAX  UINT64_MAX
+#else // _WIN64 ][
+#  define INTPTR_MIN   INT32_MIN
+#  define INTPTR_MAX   INT32_MAX
+#  define UINTPTR_MAX  UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN   INT64_MIN
+#define INTMAX_MAX   INT64_MAX
+#define UINTMAX_MAX  UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+#  define PTRDIFF_MIN  _I64_MIN
+#  define PTRDIFF_MAX  _I64_MAX
+#else  // _WIN64 ][
+#  define PTRDIFF_MIN  _I32_MIN
+#  define PTRDIFF_MAX  _I32_MAX
+#endif  // _WIN64 ]
+
+#define SIG_ATOMIC_MIN  INT_MIN
+#define SIG_ATOMIC_MAX  INT_MAX
+
+#ifndef SIZE_MAX // [
+#  ifdef _WIN64 // [
+#     define SIZE_MAX  _UI64_MAX
+#  else // _WIN64 ][
+#     define SIZE_MAX  _UI32_MAX
+#  endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+#  define WCHAR_MIN  0
+#endif  // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+#  define WCHAR_MAX  _UI16_MAX
+#endif  // WCHAR_MAX ]
+
+#define WINT_MIN  0
+#define WINT_MAX  _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val)  val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val)  val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C   INT64_C
+#define UINTMAX_C  UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/strarray.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/strarray.h
new file mode 100755
index 0000000..86fa25f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/strarray.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_strarray_h__
+#define INCLUDE_git_strarray_h__
+
+#include "common.h"
+
+/**
+ * @file git2/strarray.h
+ * @brief Git string array routines
+ * @defgroup git_strarray Git string array routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/** Array of strings */
+typedef struct git_strarray {
+	char **strings;
+	size_t count;
+} git_strarray;
+
+/**
+ * Close a string array object
+ *
+ * This method should be called on `git_strarray` objects where the strings
+ * array is allocated and contains allocated strings, such as what you
+ * would get from `git_strarray_copy()`.  Not doing so, will result in a
+ * memory leak.
+ *
+ * This does not free the `git_strarray` itself, since the library will
+ * never allocate that object directly itself (it is more commonly embedded
+ * inside another struct or created on the stack).
+ *
+ * @param array git_strarray from which to free string data
+ */
+GIT_EXTERN(void) git_strarray_free(git_strarray *array);
+
+/**
+ * Copy a string array object from source to target.
+ *
+ * Note: target is overwritten and hence should be empty, otherwise its
+ * contents are leaked.  Call git_strarray_free() if necessary.
+ *
+ * @param tgt target
+ * @param src source
+ * @return 0 on success, < 0 on allocation failure
+ */
+GIT_EXTERN(int) git_strarray_copy(git_strarray *tgt, const git_strarray *src);
+
+
+/** @} */
+GIT_END_DECL
+
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/submodule.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/submodule.h
new file mode 100755
index 0000000..689fe4b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/submodule.h
@@ -0,0 +1,626 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_submodule_h__
+#define INCLUDE_git_submodule_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "remote.h"
+#include "checkout.h"
+
+/**
+ * @file git2/submodule.h
+ * @brief Git submodule management utilities
+ *
+ * Submodule support in libgit2 builds a list of known submodules and keeps
+ * it in the repository.  The list is built from the .gitmodules file, the
+ * .git/config file, the index, and the HEAD tree.  Items in the working
+ * directory that look like submodules (i.e. a git repo) but are not
+ * mentioned in those places won't be tracked.
+ *
+ * @defgroup git_submodule Git submodule management routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Return codes for submodule status.
+ *
+ * A combination of these flags will be returned to describe the status of a
+ * submodule.  Depending on the "ignore" property of the submodule, some of
+ * the flags may never be returned because they indicate changes that are
+ * supposed to be ignored.
+ *
+ * Submodule info is contained in 4 places: the HEAD tree, the index, config
+ * files (both .git/config and .gitmodules), and the working directory.  Any
+ * or all of those places might be missing information about the submodule
+ * depending on what state the repo is in.  We consider all four places to
+ * build the combination of status flags.
+ *
+ * There are four values that are not really status, but give basic info
+ * about what sources of submodule data are available.  These will be
+ * returned even if ignore is set to "ALL".
+ *
+ * * IN_HEAD   - superproject head contains submodule
+ * * IN_INDEX  - superproject index contains submodule
+ * * IN_CONFIG - superproject gitmodules has submodule
+ * * IN_WD     - superproject workdir has submodule
+ *
+ * The following values will be returned so long as ignore is not "ALL".
+ *
+ * * INDEX_ADDED       - in index, not in head
+ * * INDEX_DELETED     - in head, not in index
+ * * INDEX_MODIFIED    - index and head don't match
+ * * WD_UNINITIALIZED  - workdir contains empty directory
+ * * WD_ADDED          - in workdir, not index
+ * * WD_DELETED        - in index, not workdir
+ * * WD_MODIFIED       - index and workdir head don't match
+ *
+ * The following can only be returned if ignore is "NONE" or "UNTRACKED".
+ *
+ * * WD_INDEX_MODIFIED - submodule workdir index is dirty
+ * * WD_WD_MODIFIED    - submodule workdir has modified files
+ *
+ * Lastly, the following will only be returned for ignore "NONE".
+ *
+ * * WD_UNTRACKED      - wd contains untracked files
+ */
+typedef enum {
+	GIT_SUBMODULE_STATUS_IN_HEAD           = (1u << 0),
+	GIT_SUBMODULE_STATUS_IN_INDEX          = (1u << 1),
+	GIT_SUBMODULE_STATUS_IN_CONFIG         = (1u << 2),
+	GIT_SUBMODULE_STATUS_IN_WD             = (1u << 3),
+	GIT_SUBMODULE_STATUS_INDEX_ADDED       = (1u << 4),
+	GIT_SUBMODULE_STATUS_INDEX_DELETED     = (1u << 5),
+	GIT_SUBMODULE_STATUS_INDEX_MODIFIED    = (1u << 6),
+	GIT_SUBMODULE_STATUS_WD_UNINITIALIZED  = (1u << 7),
+	GIT_SUBMODULE_STATUS_WD_ADDED          = (1u << 8),
+	GIT_SUBMODULE_STATUS_WD_DELETED        = (1u << 9),
+	GIT_SUBMODULE_STATUS_WD_MODIFIED       = (1u << 10),
+	GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED = (1u << 11),
+	GIT_SUBMODULE_STATUS_WD_WD_MODIFIED    = (1u << 12),
+	GIT_SUBMODULE_STATUS_WD_UNTRACKED      = (1u << 13),
+} git_submodule_status_t;
+
+#define GIT_SUBMODULE_STATUS__IN_FLAGS		0x000Fu
+#define GIT_SUBMODULE_STATUS__INDEX_FLAGS	0x0070u
+#define GIT_SUBMODULE_STATUS__WD_FLAGS		0x3F80u
+
+#define GIT_SUBMODULE_STATUS_IS_UNMODIFIED(S) \
+	(((S) & ~GIT_SUBMODULE_STATUS__IN_FLAGS) == 0)
+
+#define GIT_SUBMODULE_STATUS_IS_INDEX_UNMODIFIED(S) \
+	(((S) & GIT_SUBMODULE_STATUS__INDEX_FLAGS) == 0)
+
+#define GIT_SUBMODULE_STATUS_IS_WD_UNMODIFIED(S) \
+	(((S) & (GIT_SUBMODULE_STATUS__WD_FLAGS & \
+	~GIT_SUBMODULE_STATUS_WD_UNINITIALIZED)) == 0)
+
+#define GIT_SUBMODULE_STATUS_IS_WD_DIRTY(S) \
+	(((S) & (GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED | \
+	GIT_SUBMODULE_STATUS_WD_WD_MODIFIED | \
+	GIT_SUBMODULE_STATUS_WD_UNTRACKED)) != 0)
+
+/**
+ * Submodule update options structure
+ *
+ * Use the GIT_SUBMODULE_UPDATE_OPTIONS_INIT to get the default settings,
+ * like this:
+ *
+ * git_submodule_update_options opts = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
+ */
+typedef struct git_submodule_update_options {
+	unsigned int version;
+
+	/**
+	 * These options are passed to the checkout step. To disable
+	 * checkout, set the `checkout_strategy` to
+	 * `GIT_CHECKOUT_NONE`. Generally you will want the use
+	 * GIT_CHECKOUT_SAFE to update files in the working
+	 * directory. Use the `clone_checkout_strategy` field
+	 * to set the checkout strategy that will be used in
+	 * the case where update needs to clone the repository.
+	 */
+	git_checkout_options checkout_opts;
+
+	/**
+	 * Options which control the fetch, including callbacks.
+	 *
+	 * The callbacks to use for reporting fetch progress, and for acquiring
+	 * credentials in the event they are needed.
+	 */
+	git_fetch_options fetch_opts;
+
+	/**
+	 * The checkout strategy to use when the sub repository needs to
+	 * be cloned. Use GIT_CHECKOUT_SAFE to create all files
+	 * in the working directory for the newly cloned repository.
+	 */
+	unsigned int clone_checkout_strategy;
+} git_submodule_update_options;
+
+#define GIT_SUBMODULE_UPDATE_OPTIONS_VERSION 1
+#define GIT_SUBMODULE_UPDATE_OPTIONS_INIT \
+	{ GIT_CHECKOUT_OPTIONS_VERSION, \
+		{ GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE }, \
+	GIT_FETCH_OPTIONS_INIT, GIT_CHECKOUT_SAFE }
+
+/**
+ * Initializes a `git_submodule_update_options` with default values.
+ * Equivalent to creating an instance with GIT_SUBMODULE_UPDATE_OPTIONS_INIT.
+ *
+ * @param opts The `git_submodule_update_options` instance to initialize.
+ * @param version Version of struct; pass `GIT_SUBMODULE_UPDATE_OPTIONS_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_submodule_update_init_options(
+	git_submodule_update_options *opts, unsigned int version);
+
+/**
+ * Update a submodule. This will clone a missing submodule and
+ * checkout the subrepository to the commit specified in the index of
+ * containing repository.
+ *
+ * @param submodule Submodule object
+ * @param init If the submodule is not initialized, setting this flag to true
+ *        will initialize the submodule before updating. Otherwise, this will
+ *        return an error if attempting to update an uninitialzed repository.
+ *        but setting this to true forces them to be updated.
+ * @param options configuration options for the update.  If NULL, the
+ *        function works as though GIT_SUBMODULE_UPDATE_OPTIONS_INIT was passed.
+ * @return 0 on success, any non-zero return value from a callback
+ *         function, or a negative value to indicate an error (use
+ *         `giterr_last` for a detailed error message).
+ */
+GIT_EXTERN(int) git_submodule_update(git_submodule *submodule, int init, git_submodule_update_options *options);
+
+/**
+ * Lookup submodule information by name or path.
+ *
+ * Given either the submodule name or path (they are usually the same), this
+ * returns a structure describing the submodule.
+ *
+ * There are two expected error scenarios:
+ *
+ * - The submodule is not mentioned in the HEAD, the index, and the config,
+ *   but does "exist" in the working directory (i.e. there is a subdirectory
+ *   that appears to be a Git repository).  In this case, this function
+ *   returns GIT_EEXISTS to indicate a sub-repository exists but not in a
+ *   state where a git_submodule can be instantiated.
+ * - The submodule is not mentioned in the HEAD, index, or config and the
+ *   working directory doesn't contain a value git repo at that path.
+ *   There may or may not be anything else at that path, but nothing that
+ *   looks like a submodule.  In this case, this returns GIT_ENOTFOUND.
+ *
+ * You must call `git_submodule_free` when done with the submodule.
+ *
+ * @param out Output ptr to submodule; pass NULL to just get return code
+ * @param repo The parent repository
+ * @param name The name of or path to the submodule; trailing slashes okay
+ * @return 0 on success, GIT_ENOTFOUND if submodule does not exist,
+ *         GIT_EEXISTS if a repository is found in working directory only,
+ *         -1 on other errors.
+ */
+GIT_EXTERN(int) git_submodule_lookup(
+	git_submodule **out,
+	git_repository *repo,
+	const char *name);
+
+/**
+ * Release a submodule
+ *
+ * @param submodule Submodule object
+ */
+GIT_EXTERN(void) git_submodule_free(git_submodule *submodule);
+
+/**
+ * Iterate over all tracked submodules of a repository.
+ *
+ * See the note on `git_submodule` above.  This iterates over the tracked
+ * submodules as described therein.
+ *
+ * If you are concerned about items in the working directory that look like
+ * submodules but are not tracked, the diff API will generate a diff record
+ * for workdir items that look like submodules but are not tracked, showing
+ * them as added in the workdir.  Also, the status API will treat the entire
+ * subdirectory of a contained git repo as a single GIT_STATUS_WT_NEW item.
+ *
+ * @param repo The repository
+ * @param callback Function to be called with the name of each submodule.
+ *        Return a non-zero value to terminate the iteration.
+ * @param payload Extra data to pass to callback
+ * @return 0 on success, -1 on error, or non-zero return value of callback
+ */
+GIT_EXTERN(int) git_submodule_foreach(
+	git_repository *repo,
+	int (*callback)(git_submodule *sm, const char *name, void *payload),
+	void *payload);
+
+/**
+ * Set up a new git submodule for checkout.
+ *
+ * This does "git submodule add" up to the fetch and checkout of the
+ * submodule contents.  It preps a new submodule, creates an entry in
+ * .gitmodules and creates an empty initialized repository either at the
+ * given path in the working directory or in .git/modules with a gitlink
+ * from the working directory to the new repo.
+ *
+ * To fully emulate "git submodule add" call this function, then open the
+ * submodule repo and perform the clone step as needed.  Lastly, call
+ * `git_submodule_add_finalize()` to wrap up adding the new submodule and
+ * .gitmodules to the index to be ready to commit.
+ *
+ * You must call `git_submodule_free` on the submodule object when done.
+ *
+ * @param out The newly created submodule ready to open for clone
+ * @param repo The repository in which you want to create the submodule
+ * @param url URL for the submodule's remote
+ * @param path Path at which the submodule should be created
+ * @param use_gitlink Should workdir contain a gitlink to the repo in
+ *        .git/modules vs. repo directly in workdir.
+ * @return 0 on success, GIT_EEXISTS if submodule already exists,
+ *         -1 on other errors.
+ */
+GIT_EXTERN(int) git_submodule_add_setup(
+	git_submodule **out,
+	git_repository *repo,
+	const char *url,
+	const char *path,
+	int use_gitlink);
+
+/**
+ * Resolve the setup of a new git submodule.
+ *
+ * This should be called on a submodule once you have called add setup
+ * and done the clone of the submodule.  This adds the .gitmodules file
+ * and the newly cloned submodule to the index to be ready to be committed
+ * (but doesn't actually do the commit).
+ *
+ * @param submodule The submodule to finish adding.
+ */
+GIT_EXTERN(int) git_submodule_add_finalize(git_submodule *submodule);
+
+/**
+ * Add current submodule HEAD commit to index of superproject.
+ *
+ * @param submodule The submodule to add to the index
+ * @param write_index Boolean if this should immediately write the index
+ *            file.  If you pass this as false, you will have to get the
+ *            git_index and explicitly call `git_index_write()` on it to
+ *            save the change.
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_submodule_add_to_index(
+	git_submodule *submodule,
+	int write_index);
+
+/**
+ * Get the containing repository for a submodule.
+ *
+ * This returns a pointer to the repository that contains the submodule.
+ * This is a just a reference to the repository that was passed to the
+ * original `git_submodule_lookup()` call, so if that repository has been
+ * freed, then this may be a dangling reference.
+ *
+ * @param submodule Pointer to submodule object
+ * @return Pointer to `git_repository`
+ */
+GIT_EXTERN(git_repository *) git_submodule_owner(git_submodule *submodule);
+
+/**
+ * Get the name of submodule.
+ *
+ * @param submodule Pointer to submodule object
+ * @return Pointer to the submodule name
+ */
+GIT_EXTERN(const char *) git_submodule_name(git_submodule *submodule);
+
+/**
+ * Get the path to the submodule.
+ *
+ * The path is almost always the same as the submodule name, but the
+ * two are actually not required to match.
+ *
+ * @param submodule Pointer to submodule object
+ * @return Pointer to the submodule path
+ */
+GIT_EXTERN(const char *) git_submodule_path(git_submodule *submodule);
+
+/**
+ * Get the URL for the submodule.
+ *
+ * @param submodule Pointer to submodule object
+ * @return Pointer to the submodule url
+ */
+GIT_EXTERN(const char *) git_submodule_url(git_submodule *submodule);
+
+/**
+ * Resolve a submodule url relative to the given repository.
+ *
+ * @param out buffer to store the absolute submodule url in
+ * @param repo Pointer to repository object
+ * @param url Relative url
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_submodule_resolve_url(git_buf *out, git_repository *repo, const char *url);
+
+/**
+* Get the branch for the submodule.
+*
+* @param submodule Pointer to submodule object
+* @return Pointer to the submodule branch
+*/
+GIT_EXTERN(const char *) git_submodule_branch(git_submodule *submodule);
+
+/**
+ * Set the branch for the submodule in the configuration
+ *
+ * After calling this, you may wish to call `git_submodule_sync()` to
+ * write the changes to the checked out submodule repository.
+ *
+ * @param repo the repository to affect
+ * @param name the name of the submodule to configure
+ * @param branch Branch that should be used for the submodule
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_submodule_set_branch(git_repository *repo, const char *name, const char *branch);
+
+/**
+ * Set the URL for the submodule in the configuration
+ *
+ *
+ * After calling this, you may wish to call `git_submodule_sync()` to
+ * write the changes to the checked out submodule repository.
+ *
+ * @param repo the repository to affect
+ * @param name the name of the submodule to configure
+ * @param url URL that should be used for the submodule
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_submodule_set_url(git_repository *repo, const char *name, const char *url);
+
+/**
+ * Get the OID for the submodule in the index.
+ *
+ * @param submodule Pointer to submodule object
+ * @return Pointer to git_oid or NULL if submodule is not in index.
+ */
+GIT_EXTERN(const git_oid *) git_submodule_index_id(git_submodule *submodule);
+
+/**
+ * Get the OID for the submodule in the current HEAD tree.
+ *
+ * @param submodule Pointer to submodule object
+ * @return Pointer to git_oid or NULL if submodule is not in the HEAD.
+ */
+GIT_EXTERN(const git_oid *) git_submodule_head_id(git_submodule *submodule);
+
+/**
+ * Get the OID for the submodule in the current working directory.
+ *
+ * This returns the OID that corresponds to looking up 'HEAD' in the checked
+ * out submodule.  If there are pending changes in the index or anything
+ * else, this won't notice that.  You should call `git_submodule_status()`
+ * for a more complete picture about the state of the working directory.
+ *
+ * @param submodule Pointer to submodule object
+ * @return Pointer to git_oid or NULL if submodule is not checked out.
+ */
+GIT_EXTERN(const git_oid *) git_submodule_wd_id(git_submodule *submodule);
+
+/**
+ * Get the ignore rule that will be used for the submodule.
+ *
+ * These values control the behavior of `git_submodule_status()` for this
+ * submodule.  There are four ignore values:
+ *
+ *  - **GIT_SUBMODULE_IGNORE_NONE** will consider any change to the contents
+ *    of the submodule from a clean checkout to be dirty, including the
+ *    addition of untracked files.  This is the default if unspecified.
+ *  - **GIT_SUBMODULE_IGNORE_UNTRACKED** examines the contents of the
+ *    working tree (i.e. call `git_status_foreach()` on the submodule) but
+ *    UNTRACKED files will not count as making the submodule dirty.
+ *  - **GIT_SUBMODULE_IGNORE_DIRTY** means to only check if the HEAD of the
+ *    submodule has moved for status.  This is fast since it does not need to
+ *    scan the working tree of the submodule at all.
+ *  - **GIT_SUBMODULE_IGNORE_ALL** means not to open the submodule repo.
+ *    The working directory will be consider clean so long as there is a
+ *    checked out version present.
+ *
+ * @param submodule The submodule to check
+ * @return The current git_submodule_ignore_t valyue what will be used for
+ *         this submodule.
+ */
+GIT_EXTERN(git_submodule_ignore_t) git_submodule_ignore(
+	git_submodule *submodule);
+
+/**
+ * Set the ignore rule for the submodule in the configuration
+ *
+ * This does not affect any currently-loaded instances.
+ *
+ * @param repo the repository to affect
+ * @param name the name of the submdule
+ * @param ignore The new value for the ignore rule
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_submodule_set_ignore(
+	git_repository *repo,
+	const char *name,
+	git_submodule_ignore_t ignore);
+
+/**
+ * Get the update rule that will be used for the submodule.
+ *
+ * This value controls the behavior of the `git submodule update` command.
+ * There are four useful values documented with `git_submodule_update_t`.
+ *
+ * @param submodule The submodule to check
+ * @return The current git_submodule_update_t value that will be used
+ *         for this submodule.
+ */
+GIT_EXTERN(git_submodule_update_t) git_submodule_update_strategy(
+	git_submodule *submodule);
+
+/**
+ * Set the update rule for the submodule in the configuration
+ *
+ * This setting won't affect any existing instances.
+ *
+ * @param repo the repository to affect
+ * @param name the name of the submodule to configure
+ * @param update The new value to use
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_submodule_set_update(
+	git_repository *repo,
+	const char *name,
+	git_submodule_update_t update);
+
+/**
+ * Read the fetchRecurseSubmodules rule for a submodule.
+ *
+ * This accesses the submodule.<name>.fetchRecurseSubmodules value for
+ * the submodule that controls fetching behavior for the submodule.
+ *
+ * Note that at this time, libgit2 does not honor this setting and the
+ * fetch functionality current ignores submodules.
+ *
+ * @return 0 if fetchRecurseSubmodules is false, 1 if true
+ */
+GIT_EXTERN(git_submodule_recurse_t) git_submodule_fetch_recurse_submodules(
+	git_submodule *submodule);
+
+/**
+ * Set the fetchRecurseSubmodules rule for a submodule in the configuration
+ *
+ * This setting won't affect any existing instances.
+ *
+ * @param repo the repository to affect
+ * @param name the submodule to configure
+ * @param fetch_recurse_submodules Boolean value
+ * @return old value for fetchRecurseSubmodules
+ */
+GIT_EXTERN(int) git_submodule_set_fetch_recurse_submodules(
+	git_repository *repo,
+	const char *name,
+	git_submodule_recurse_t fetch_recurse_submodules);
+
+/**
+ * Copy submodule info into ".git/config" file.
+ *
+ * Just like "git submodule init", this copies information about the
+ * submodule into ".git/config".  You can use the accessor functions
+ * above to alter the in-memory git_submodule object and control what
+ * is written to the config, overriding what is in .gitmodules.
+ *
+ * @param submodule The submodule to write into the superproject config
+ * @param overwrite By default, existing entries will not be overwritten,
+ *                  but setting this to true forces them to be updated.
+ * @return 0 on success, <0 on failure.
+ */
+GIT_EXTERN(int) git_submodule_init(git_submodule *submodule, int overwrite);
+
+/**
+ * Set up the subrepository for a submodule in preparation for clone.
+ *
+ * This function can be called to init and set up a submodule
+ * repository from a submodule in preparation to clone it from
+ * its remote.
+ *
+ * @param out Output pointer to the created git repository.
+ * @param sm The submodule to create a new subrepository from.
+ * @param use_gitlink Should the workdir contain a gitlink to
+ *        the repo in .git/modules vs. repo directly in workdir.
+ * @return 0 on success, <0 on failure.
+ */
+GIT_EXTERN(int) git_submodule_repo_init(
+	git_repository **out,
+	const git_submodule *sm,
+	int use_gitlink);
+
+/**
+ * Copy submodule remote info into submodule repo.
+ *
+ * This copies the information about the submodules URL into the checked out
+ * submodule config, acting like "git submodule sync".  This is useful if
+ * you have altered the URL for the submodule (or it has been altered by a
+ * fetch of upstream changes) and you need to update your local repo.
+ */
+GIT_EXTERN(int) git_submodule_sync(git_submodule *submodule);
+
+/**
+ * Open the repository for a submodule.
+ *
+ * This is a newly opened repository object.  The caller is responsible for
+ * calling `git_repository_free()` on it when done.  Multiple calls to this
+ * function will return distinct `git_repository` objects.  This will only
+ * work if the submodule is checked out into the working directory.
+ *
+ * @param repo Pointer to the submodule repo which was opened
+ * @param submodule Submodule to be opened
+ * @return 0 on success, <0 if submodule repo could not be opened.
+ */
+GIT_EXTERN(int) git_submodule_open(
+	git_repository **repo,
+	git_submodule *submodule);
+
+/**
+ * Reread submodule info from config, index, and HEAD.
+ *
+ * Call this to reread cached submodule information for this submodule if
+ * you have reason to believe that it has changed.
+ *
+ * @param submodule The submodule to reload
+ * @param force Force reload even if the data doesn't seem out of date
+ * @return 0 on success, <0 on error
+ */
+GIT_EXTERN(int) git_submodule_reload(git_submodule *submodule, int force);
+
+/**
+ * Get the status for a submodule.
+ *
+ * This looks at a submodule and tries to determine the status.  It
+ * will return a combination of the `GIT_SUBMODULE_STATUS` values above.
+ * How deeply it examines the working directory to do this will depend
+ * on the `git_submodule_ignore_t` value for the submodule.
+ *
+ * @param status Combination of `GIT_SUBMODULE_STATUS` flags
+ * @param repo the repository in which to look
+ * @param name name of the submodule
+ * @param ignore the ignore rules to follow
+ * @return 0 on success, <0 on error
+ */
+GIT_EXTERN(int) git_submodule_status(
+	unsigned int *status,
+	git_repository *repo,
+	const char *name,
+	git_submodule_ignore_t ignore);
+
+/**
+ * Get the locations of submodule information.
+ *
+ * This is a bit like a very lightweight version of `git_submodule_status`.
+ * It just returns a made of the first four submodule status values (i.e.
+ * the ones like GIT_SUBMODULE_STATUS_IN_HEAD, etc) that tell you where the
+ * submodule data comes from (i.e. the HEAD commit, gitmodules file, etc.).
+ * This can be useful if you want to know if the submodule is present in the
+ * working directory at this point in time, etc.
+ *
+ * @param location_status Combination of first four `GIT_SUBMODULE_STATUS` flags
+ * @param submodule Submodule for which to get status
+ * @return 0 on success, <0 on error
+ */
+GIT_EXTERN(int) git_submodule_location(
+	unsigned int *location_status,
+	git_submodule *submodule);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/commit.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/commit.h
new file mode 100755
index 0000000..627d3ae
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/commit.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_commit_h__
+#define INCLUDE_sys_git_commit_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+
+/**
+ * @file git2/sys/commit.h
+ * @brief Low-level Git commit creation
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create new commit in the repository from a list of `git_oid` values.
+ *
+ * See documentation for `git_commit_create()` for information about the
+ * parameters, as the meaning is identical excepting that `tree` and
+ * `parents` now take `git_oid`.  This is a dangerous API in that nor
+ * the `tree`, neither the `parents` list of `git_oid`s are checked for
+ * validity.
+ *
+ * @see git_commit_create
+ */
+GIT_EXTERN(int) git_commit_create_from_ids(
+	git_oid *id,
+	git_repository *repo,
+	const char *update_ref,
+	const git_signature *author,
+	const git_signature *committer,
+	const char *message_encoding,
+	const char *message,
+	const git_oid *tree,
+	size_t parent_count,
+	const git_oid *parents[]);
+
+/**
+ * Callback function to return parents for commit.
+ *
+ * This is invoked with the count of the number of parents processed so far
+ * along with the user supplied payload.  This should return a git_oid of
+ * the next parent or NULL if all parents have been provided.
+ */
+typedef const git_oid *(*git_commit_parent_callback)(size_t idx, void *payload);
+
+/**
+ * Create a new commit in the repository with an callback to supply parents.
+ *
+ * See documentation for `git_commit_create()` for information about the
+ * parameters, as the meaning is identical excepting that `tree` takes a
+ * `git_oid` and doesn't check for validity, and `parent_cb` is invoked
+ * with `parent_payload` and should return `git_oid` values or NULL to
+ * indicate that all parents are accounted for.
+ *
+ * @see git_commit_create
+ */
+GIT_EXTERN(int) git_commit_create_from_callback(
+	git_oid *id,
+	git_repository *repo,
+	const char *update_ref,
+	const git_signature *author,
+	const git_signature *committer,
+	const char *message_encoding,
+	const char *message,
+	const git_oid *tree,
+	git_commit_parent_callback parent_cb,
+	void *parent_payload);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/config.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/config.h
new file mode 100755
index 0000000..044e344
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/config.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_config_backend_h__
+#define INCLUDE_sys_git_config_backend_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/config.h"
+
+/**
+ * @file git2/sys/config.h
+ * @brief Git config backend routines
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Every iterator must have this struct as its first element, so the
+ * API can talk to it. You'd define your iterator as
+ *
+ *     struct my_iterator {
+ *             git_config_iterator parent;
+ *             ...
+ *     }
+ *
+ * and assign `iter->parent.backend` to your `git_config_backend`.
+ */
+struct git_config_iterator {
+	git_config_backend *backend;
+	unsigned int flags;
+
+	/**
+	 * Return the current entry and advance the iterator. The
+	 * memory belongs to the library.
+	 */
+	int (*next)(git_config_entry **entry, git_config_iterator *iter);
+
+	/**
+	 * Free the iterator
+	 */
+	void (*free)(git_config_iterator *iter);
+};
+
+/**
+ * Generic backend that implements the interface to
+ * access a configuration file
+ */
+struct git_config_backend {
+	unsigned int version;
+	/** True if this backend is for a snapshot */
+	int readonly;
+	struct git_config *cfg;
+
+	/* Open means open the file/database and parse if necessary */
+	int (*open)(struct git_config_backend *, git_config_level_t level);
+	int (*get)(struct git_config_backend *, const char *key, git_config_entry **entry);
+	int (*set)(struct git_config_backend *, const char *key, const char *value);
+	int (*set_multivar)(git_config_backend *cfg, const char *name, const char *regexp, const char *value);
+	int (*del)(struct git_config_backend *, const char *key);
+	int (*del_multivar)(struct git_config_backend *, const char *key, const char *regexp);
+	int (*iterator)(git_config_iterator **, struct git_config_backend *);
+	/** Produce a read-only version of this backend */
+	int (*snapshot)(struct git_config_backend **, struct git_config_backend *);
+	void (*free)(struct git_config_backend *);
+};
+#define GIT_CONFIG_BACKEND_VERSION 1
+#define GIT_CONFIG_BACKEND_INIT {GIT_CONFIG_BACKEND_VERSION}
+
+/**
+ * Initializes a `git_config_backend` with default values. Equivalent to
+ * creating an instance with GIT_CONFIG_BACKEND_INIT.
+ *
+ * @param backend the `git_config_backend` struct to initialize.
+ * @param version Version of struct; pass `GIT_CONFIG_BACKEND_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_config_init_backend(
+	git_config_backend *backend,
+	unsigned int version);
+
+/**
+ * Add a generic config file instance to an existing config
+ *
+ * Note that the configuration object will free the file
+ * automatically.
+ *
+ * Further queries on this config object will access each
+ * of the config file instances in order (instances with
+ * a higher priority level will be accessed first).
+ *
+ * @param cfg the configuration to add the file to
+ * @param file the configuration file (backend) to add
+ * @param level the priority level of the backend
+ * @param force if a config file already exists for the given
+ *  priority level, replace it
+ * @return 0 on success, GIT_EEXISTS when adding more than one file
+ *  for a given priority level (and force_replace set to 0), or error code
+ */
+GIT_EXTERN(int) git_config_add_backend(
+	git_config *cfg,
+	git_config_backend *file,
+	git_config_level_t level,
+	int force);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/diff.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/diff.h
new file mode 100755
index 0000000..aefd7b9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/diff.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_diff_h__
+#define INCLUDE_sys_git_diff_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+#include "git2/diff.h"
+#include "git2/status.h"
+
+/**
+ * @file git2/sys/diff.h
+ * @brief Low-level Git diff utilities
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Diff print callback that writes to a git_buf.
+ *
+ * This function is provided not for you to call it directly, but instead
+ * so you can use it as a function pointer to the `git_diff_print` or
+ * `git_patch_print` APIs.  When using those APIs, you specify a callback
+ * to actually handle the diff and/or patch data.
+ *
+ * Use this callback to easily write that data to a `git_buf` buffer.  You
+ * must pass a `git_buf *` value as the payload to the `git_diff_print`
+ * and/or `git_patch_print` function.  The data will be appended to the
+ * buffer (after any existing content).
+ */
+GIT_EXTERN(int) git_diff_print_callback__to_buf(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *payload); /**< payload must be a `git_buf *` */
+
+/**
+ * Diff print callback that writes to stdio FILE handle.
+ *
+ * This function is provided not for you to call it directly, but instead
+ * so you can use it as a function pointer to the `git_diff_print` or
+ * `git_patch_print` APIs.  When using those APIs, you specify a callback
+ * to actually handle the diff and/or patch data.
+ *
+ * Use this callback to easily write that data to a stdio FILE handle.  You
+ * must pass a `FILE *` value (such as `stdout` or `stderr` or the return
+ * value from `fopen()`) as the payload to the `git_diff_print`
+ * and/or `git_patch_print` function.  If you pass NULL, this will write
+ * data to `stdout`.
+ */
+GIT_EXTERN(int) git_diff_print_callback__to_file_handle(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *payload); /**< payload must be a `FILE *` */
+
+
+/**
+ * Performance data from diffing
+ */
+typedef struct {
+	unsigned int version;
+	size_t stat_calls; /**< Number of stat() calls performed */
+	size_t oid_calculations; /**< Number of ID calculations */
+} git_diff_perfdata;
+
+#define GIT_DIFF_PERFDATA_VERSION 1
+#define GIT_DIFF_PERFDATA_INIT {GIT_DIFF_PERFDATA_VERSION,0,0}
+
+/**
+ * Get performance data for a diff object.
+ *
+ * @param out Structure to be filled with diff performance data
+ * @param diff Diff to read performance data from
+ * @return 0 for success, <0 for error
+ */
+GIT_EXTERN(int) git_diff_get_perfdata(
+	git_diff_perfdata *out, const git_diff *diff);
+
+/**
+ * Get performance data for diffs from a git_status_list
+ */
+GIT_EXTERN(int) git_status_list_get_perfdata(
+	git_diff_perfdata *out, const git_status_list *status);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/filter.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/filter.h
new file mode 100755
index 0000000..5fd8d55
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/filter.h
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_filter_h__
+#define INCLUDE_sys_git_filter_h__
+
+#include "git2/filter.h"
+
+/**
+ * @file git2/sys/filter.h
+ * @brief Git filter backend and plugin routines
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Look up a filter by name
+ *
+ * @param name The name of the filter
+ * @return Pointer to the filter object or NULL if not found
+ */
+GIT_EXTERN(git_filter *) git_filter_lookup(const char *name);
+
+#define GIT_FILTER_CRLF  "crlf"
+#define GIT_FILTER_IDENT "ident"
+
+/**
+ * This is priority that the internal CRLF filter will be registered with
+ */
+#define GIT_FILTER_CRLF_PRIORITY 0
+
+/**
+ * This is priority that the internal ident filter will be registered with
+ */
+#define GIT_FILTER_IDENT_PRIORITY 100
+
+/**
+ * This is priority to use with a custom filter to imitate a core Git
+ * filter driver, so that it will be run last on checkout and first on
+ * checkin.  You do not have to use this, but it helps compatibility.
+ */
+#define GIT_FILTER_DRIVER_PRIORITY 200
+
+/**
+ * Create a new empty filter list
+ *
+ * Normally you won't use this because `git_filter_list_load` will create
+ * the filter list for you, but you can use this in combination with the
+ * `git_filter_lookup` and `git_filter_list_push` functions to assemble
+ * your own chains of filters.
+ */
+GIT_EXTERN(int) git_filter_list_new(
+	git_filter_list **out,
+	git_repository *repo,
+	git_filter_mode_t mode,
+	uint32_t options);
+
+/**
+ * Add a filter to a filter list with the given payload.
+ *
+ * Normally you won't have to do this because the filter list is created
+ * by calling the "check" function on registered filters when the filter
+ * attributes are set, but this does allow more direct manipulation of
+ * filter lists when desired.
+ *
+ * Note that normally the "check" function can set up a payload for the
+ * filter.  Using this function, you can either pass in a payload if you
+ * know the expected payload format, or you can pass NULL.  Some filters
+ * may fail with a NULL payload.  Good luck!
+ */
+GIT_EXTERN(int) git_filter_list_push(
+	git_filter_list *fl, git_filter *filter, void *payload);
+
+/**
+ * Look up how many filters are in the list
+ *
+ * We will attempt to apply all of these filters to any data passed in,
+ * but note that the filter apply action still has the option of skipping
+ * data that is passed in (for example, the CRLF filter will skip data
+ * that appears to be binary).
+ *
+ * @param fl A filter list
+ * @return The number of filters in the list
+ */
+GIT_EXTERN(size_t) git_filter_list_length(const git_filter_list *fl);
+
+/**
+ * A filter source represents a file/blob to be processed
+ */
+typedef struct git_filter_source git_filter_source;
+
+/**
+ * Get the repository that the source data is coming from.
+ */
+GIT_EXTERN(git_repository *) git_filter_source_repo(const git_filter_source *src);
+
+/**
+ * Get the path that the source data is coming from.
+ */
+GIT_EXTERN(const char *) git_filter_source_path(const git_filter_source *src);
+
+/**
+ * Get the file mode of the source file
+ * If the mode is unknown, this will return 0
+ */
+GIT_EXTERN(uint16_t) git_filter_source_filemode(const git_filter_source *src);
+
+/**
+ * Get the OID of the source
+ * If the OID is unknown (often the case with GIT_FILTER_CLEAN) then
+ * this will return NULL.
+ */
+GIT_EXTERN(const git_oid *) git_filter_source_id(const git_filter_source *src);
+
+/**
+ * Get the git_filter_mode_t to be used
+ */
+GIT_EXTERN(git_filter_mode_t) git_filter_source_mode(const git_filter_source *src);
+
+/**
+ * Get the combination git_filter_flag_t options to be applied
+ */
+GIT_EXTERN(uint32_t) git_filter_source_flags(const git_filter_source *src);
+
+/*
+ * struct git_filter
+ *
+ * The filter lifecycle:
+ * - initialize - first use of filter
+ * - shutdown   - filter removed/unregistered from system
+ * - check      - considering filter for file
+ * - apply      - apply filter to file contents
+ * - cleanup    - done with file
+ */
+
+/**
+ * Initialize callback on filter
+ *
+ * Specified as `filter.initialize`, this is an optional callback invoked
+ * before a filter is first used.  It will be called once at most.
+ *
+ * If non-NULL, the filter's `initialize` callback will be invoked right
+ * before the first use of the filter, so you can defer expensive
+ * initialization operations (in case libgit2 is being used in a way that
+ * doesn't need the filter).
+ */
+typedef int (*git_filter_init_fn)(git_filter *self);
+
+/**
+ * Shutdown callback on filter
+ *
+ * Specified as `filter.shutdown`, this is an optional callback invoked
+ * when the filter is unregistered or when libgit2 is shutting down.  It
+ * will be called once at most and should release resources as needed.
+ * This may be called even if the `initialize` callback was not made.
+ *
+ * Typically this function will free the `git_filter` object itself.
+ */
+typedef void (*git_filter_shutdown_fn)(git_filter *self);
+
+/**
+ * Callback to decide if a given source needs this filter
+ *
+ * Specified as `filter.check`, this is an optional callback that checks
+ * if filtering is needed for a given source.
+ *
+ * It should return 0 if the filter should be applied (i.e. success),
+ * GIT_PASSTHROUGH if the filter should not be applied, or an error code
+ * to fail out of the filter processing pipeline and return to the caller.
+ *
+ * The `attr_values` will be set to the values of any attributes given in
+ * the filter definition.  See `git_filter` below for more detail.
+ *
+ * The `payload` will be a pointer to a reference payload for the filter.
+ * This will start as NULL, but `check` can assign to this pointer for
+ * later use by the `apply` callback.  Note that the value should be heap
+ * allocated (not stack), so that it doesn't go away before the `apply`
+ * callback can use it.  If a filter allocates and assigns a value to the
+ * `payload`, it will need a `cleanup` callback to free the payload.
+ */
+typedef int (*git_filter_check_fn)(
+	git_filter  *self,
+	void       **payload, /* points to NULL ptr on entry, may be set */
+	const git_filter_source *src,
+	const char **attr_values);
+
+/**
+ * Callback to actually perform the data filtering
+ *
+ * Specified as `filter.apply`, this is the callback that actually filters
+ * data.  If it successfully writes the output, it should return 0.  Like
+ * `check`, it can return GIT_PASSTHROUGH to indicate that the filter
+ * doesn't want to run.  Other error codes will stop filter processing and
+ * return to the caller.
+ *
+ * The `payload` value will refer to any payload that was set by the
+ * `check` callback.  It may be read from or written to as needed.
+ */
+typedef int (*git_filter_apply_fn)(
+	git_filter    *self,
+	void         **payload, /* may be read and/or set */
+	git_buf       *to,
+	const git_buf *from,
+	const git_filter_source *src);
+
+typedef int (*git_filter_stream_fn)(
+	git_writestream **out,
+	git_filter *self,
+	void **payload,
+	const git_filter_source *src,
+	git_writestream *next);
+
+/**
+ * Callback to clean up after filtering has been applied
+ *
+ * Specified as `filter.cleanup`, this is an optional callback invoked
+ * after the filter has been applied.  If the `check` or `apply` callbacks
+ * allocated a `payload` to keep per-source filter state, use this
+ * callback to free that payload and release resources as required.
+ */
+typedef void (*git_filter_cleanup_fn)(
+	git_filter *self,
+	void       *payload);
+
+/**
+ * Filter structure used to register custom filters.
+ *
+ * To associate extra data with a filter, allocate extra data and put the
+ * `git_filter` struct at the start of your data buffer, then cast the
+ * `self` pointer to your larger structure when your callback is invoked.
+ *
+ * `version` should be set to GIT_FILTER_VERSION
+ *
+ * `attributes` is a whitespace-separated list of attribute names to check
+ * for this filter (e.g. "eol crlf text").  If the attribute name is bare,
+ * it will be simply loaded and passed to the `check` callback.  If it has
+ * a value (i.e. "name=value"), the attribute must match that value for
+ * the filter to be applied.
+ *
+ * The `initialize`, `shutdown`, `check`, `apply`, and `cleanup` callbacks
+ * are all documented above with the respective function pointer typedefs.
+ */
+struct git_filter {
+	unsigned int           version;
+
+	const char            *attributes;
+
+	git_filter_init_fn     initialize;
+	git_filter_shutdown_fn shutdown;
+	git_filter_check_fn    check;
+	git_filter_apply_fn    apply;
+	git_filter_stream_fn   stream;
+	git_filter_cleanup_fn  cleanup;
+};
+
+#define GIT_FILTER_VERSION 1
+
+/**
+ * Register a filter under a given name with a given priority.
+ *
+ * As mentioned elsewhere, the initialize callback will not be invoked
+ * immediately.  It is deferred until the filter is used in some way.
+ *
+ * A filter's attribute checks and `check` and `apply` callbacks will be
+ * issued in order of `priority` on smudge (to workdir), and in reverse
+ * order of `priority` on clean (to odb).
+ *
+ * Two filters are preregistered with libgit2:
+ * - GIT_FILTER_CRLF with priority 0
+ * - GIT_FILTER_IDENT with priority 100
+ *
+ * Currently the filter registry is not thread safe, so any registering or
+ * deregistering of filters must be done outside of any possible usage of
+ * the filters (i.e. during application setup or shutdown).
+ *
+ * @param name A name by which the filter can be referenced.  Attempting
+ * 			to register with an in-use name will return GIT_EEXISTS.
+ * @param filter The filter definition.  This pointer will be stored as is
+ * 			by libgit2 so it must be a durable allocation (either static
+ * 			or on the heap).
+ * @param priority The priority for filter application
+ * @return 0 on successful registry, error code <0 on failure
+ */
+GIT_EXTERN(int) git_filter_register(
+	const char *name, git_filter *filter, int priority);
+
+/**
+ * Remove the filter with the given name
+ *
+ * Attempting to remove the builtin libgit2 filters is not permitted and
+ * will return an error.
+ *
+ * Currently the filter registry is not thread safe, so any registering or
+ * deregistering of filters must be done outside of any possible usage of
+ * the filters (i.e. during application setup or shutdown).
+ *
+ * @param name The name under which the filter was registered
+ * @return 0 on success, error code <0 on failure
+ */
+GIT_EXTERN(int) git_filter_unregister(const char *name);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/hashsig.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/hashsig.h
new file mode 100755
index 0000000..09c19ae
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/hashsig.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_hashsig_h__
+#define INCLUDE_sys_hashsig_h__
+
+#include "git2/common.h"
+
+GIT_BEGIN_DECL
+
+/**
+ * Similarity signature of arbitrary text content based on line hashes
+ */
+typedef struct git_hashsig git_hashsig;
+
+/**
+ * Options for hashsig computation
+ *
+ * The options GIT_HASHSIG_NORMAL, GIT_HASHSIG_IGNORE_WHITESPACE,
+ * GIT_HASHSIG_SMART_WHITESPACE are exclusive and should not be combined.
+ */
+typedef enum {
+	/**
+	 * Use all data
+	 */
+	GIT_HASHSIG_NORMAL = 0,
+
+	/**
+	 * Ignore whitespace
+	 */
+	GIT_HASHSIG_IGNORE_WHITESPACE = (1 << 0),
+
+	/**
+	 * Ignore \r and all space after \n
+	 */
+	GIT_HASHSIG_SMART_WHITESPACE = (1 << 1),
+
+	/**
+	 * Allow hashing of small files
+	 */
+	GIT_HASHSIG_ALLOW_SMALL_FILES = (1 << 2)
+} git_hashsig_option_t;
+
+/**
+ * Compute a similarity signature for a text buffer
+ *
+ * If you have passed the option GIT_HASHSIG_IGNORE_WHITESPACE, then the
+ * whitespace will be removed from the buffer while it is being processed,
+ * modifying the buffer in place. Sorry about that!
+ *
+ * @param out The computed similarity signature.
+ * @param buf The input buffer.
+ * @param buflen The input buffer size.
+ * @param opts The signature computation options (see above).
+ * @return 0 on success, GIT_EBUFS if the buffer doesn't contain enough data to
+ * compute a valid signature (unless GIT_HASHSIG_ALLOW_SMALL_FILES is set), or
+ * error code.
+ */
+GIT_EXTERN(int) git_hashsig_create(
+	git_hashsig **out,
+	const char *buf,
+	size_t buflen,
+	git_hashsig_option_t opts);
+
+/**
+ * Compute a similarity signature for a text file
+ *
+ * This walks through the file, only loading a maximum of 4K of file data at
+ * a time. Otherwise, it acts just like `git_hashsig_create`.
+ *
+ * @param out The computed similarity signature.
+ * @param path The path to the input file.
+ * @param opts The signature computation options (see above).
+ * @return 0 on success, GIT_EBUFS if the buffer doesn't contain enough data to
+ * compute a valid signature (unless GIT_HASHSIG_ALLOW_SMALL_FILES is set), or
+ * error code.
+ */
+GIT_EXTERN(int) git_hashsig_create_fromfile(
+	git_hashsig **out,
+	const char *path,
+	git_hashsig_option_t opts);
+
+/**
+ * Release memory for a content similarity signature
+ *
+ * @param sig The similarity signature to free.
+ */
+GIT_EXTERN(void) git_hashsig_free(git_hashsig *sig);
+
+/**
+ * Measure similarity score between two similarity signatures
+ *
+ * @param a The first similarity signature to compare.
+ * @param b The second similarity signature to compare.
+ * @return [0 to 100] on success as the similarity score, or error code.
+ */
+GIT_EXTERN(int) git_hashsig_compare(
+	const git_hashsig *a,
+	const git_hashsig *b);
+
+GIT_END_DECL
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/index.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/index.h
new file mode 100755
index 0000000..29a99f7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/index.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_index_h__
+#define INCLUDE_sys_git_index_h__
+
+/**
+ * @file git2/sys/index.h
+ * @brief Low-level Git index manipulation routines
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/** Representation of a rename conflict entry in the index. */
+typedef struct git_index_name_entry {
+	char *ancestor;
+	char *ours;
+	char *theirs;
+} git_index_name_entry;
+
+/** Representation of a resolve undo entry in the index. */
+typedef struct git_index_reuc_entry {
+	unsigned int mode[3];
+	git_oid oid[3];
+	char *path;
+} git_index_reuc_entry;
+
+/** @name Conflict Name entry functions
+ *
+ * These functions work on rename conflict entries.
+ */
+/**@{*/
+
+/**
+ * Get the count of filename conflict entries currently in the index.
+ *
+ * @param index an existing index object
+ * @return integer of count of current filename conflict entries
+ */
+GIT_EXTERN(size_t) git_index_name_entrycount(git_index *index);
+
+/**
+ * Get a filename conflict entry from the index.
+ *
+ * The returned entry is read-only and should not be modified
+ * or freed by the caller.
+ *
+ * @param index an existing index object
+ * @param n the position of the entry
+ * @return a pointer to the filename conflict entry; NULL if out of bounds
+ */
+GIT_EXTERN(const git_index_name_entry *) git_index_name_get_byindex(
+	git_index *index, size_t n);
+
+/**
+ * Record the filenames involved in a rename conflict.
+ *
+ * @param index an existing index object
+ * @param ancestor the path of the file as it existed in the ancestor
+ * @param ours the path of the file as it existed in our tree
+ * @param theirs the path of the file as it existed in their tree
+ */
+GIT_EXTERN(int) git_index_name_add(git_index *index,
+	const char *ancestor, const char *ours, const char *theirs);
+
+/**
+ * Remove all filename conflict entries.
+ *
+ * @param index an existing index object
+ */
+GIT_EXTERN(void) git_index_name_clear(git_index *index);
+
+/**@}*/
+
+/** @name Resolve Undo (REUC) index entry manipulation.
+ *
+ * These functions work on the Resolve Undo index extension and contains
+ * data about the original files that led to a merge conflict.
+ */
+/**@{*/
+
+/**
+ * Get the count of resolve undo entries currently in the index.
+ *
+ * @param index an existing index object
+ * @return integer of count of current resolve undo entries
+ */
+GIT_EXTERN(size_t) git_index_reuc_entrycount(git_index *index);
+
+/**
+ * Finds the resolve undo entry that points to the given path in the Git
+ * index.
+ *
+ * @param at_pos the address to which the position of the reuc entry is written (optional)
+ * @param index an existing index object
+ * @param path path to search
+ * @return 0 if found, < 0 otherwise (GIT_ENOTFOUND)
+ */
+GIT_EXTERN(int) git_index_reuc_find(size_t *at_pos, git_index *index, const char *path);
+
+/**
+ * Get a resolve undo entry from the index.
+ *
+ * The returned entry is read-only and should not be modified
+ * or freed by the caller.
+ *
+ * @param index an existing index object
+ * @param path path to search
+ * @return the resolve undo entry; NULL if not found
+ */
+GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_bypath(git_index *index, const char *path);
+
+/**
+ * Get a resolve undo entry from the index.
+ *
+ * The returned entry is read-only and should not be modified
+ * or freed by the caller.
+ *
+ * @param index an existing index object
+ * @param n the position of the entry
+ * @return a pointer to the resolve undo entry; NULL if out of bounds
+ */
+GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_byindex(git_index *index, size_t n);
+
+/**
+ * Adds a resolve undo entry for a file based on the given parameters.
+ *
+ * The resolve undo entry contains the OIDs of files that were involved
+ * in a merge conflict after the conflict has been resolved.  This allows
+ * conflicts to be re-resolved later.
+ *
+ * If there exists a resolve undo entry for the given path in the index,
+ * it will be removed.
+ *
+ * This method will fail in bare index instances.
+ *
+ * @param index an existing index object
+ * @param path filename to add
+ * @param ancestor_mode mode of the ancestor file
+ * @param ancestor_id oid of the ancestor file
+ * @param our_mode mode of our file
+ * @param our_id oid of our file
+ * @param their_mode mode of their file
+ * @param their_id oid of their file
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_reuc_add(git_index *index, const char *path,
+	int ancestor_mode, const git_oid *ancestor_id,
+	int our_mode, const git_oid *our_id,
+	int their_mode, const git_oid *their_id);
+
+/**
+ * Remove an resolve undo entry from the index
+ *
+ * @param index an existing index object
+ * @param n position of the resolve undo entry to remove
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_reuc_remove(git_index *index, size_t n);
+
+/**
+ * Remove all resolve undo entries from the index
+ *
+ * @param index an existing index object
+ */
+GIT_EXTERN(void) git_index_reuc_clear(git_index *index);
+
+/**@}*/
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/mempack.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/mempack.h
new file mode 100755
index 0000000..96074fb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/mempack.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_odb_mempack_h__
+#define INCLUDE_sys_git_odb_mempack_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+#include "git2/odb.h"
+
+/**
+ * @file git2/sys/mempack.h
+ * @brief Custom ODB backend that permits packing objects in-memory
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ *	Instantiate a new mempack backend.
+ *
+ *	The backend must be added to an existing ODB with the highest
+ *	priority.
+ *
+ *		git_mempack_new(&mempacker);
+ *		git_repository_odb(&odb, repository);
+ *		git_odb_add_backend(odb, mempacker, 999);
+ *
+ *	Once the backend has been loaded, all writes to the ODB will
+ *	instead be queued in memory, and can be finalized with
+ *	`git_mempack_dump`.
+ *
+ *	Subsequent reads will also be served from the in-memory store
+ *	to ensure consistency, until the memory store is dumped.
+ *
+ *	@param out Poiter where to store the ODB backend
+ *	@return 0 on success; error code otherwise
+ */
+int git_mempack_new(git_odb_backend **out);
+
+/**
+ *	Dump all the queued in-memory writes to a packfile.
+ *
+ *	The contents of the packfile will be stored in the given buffer.
+ *	It is the caller's responsibility to ensure that the generated
+ *	packfile is available to the repository (e.g. by writing it
+ *	to disk, or doing something crazy like distributing it across
+ *	several copies of the repository over a network).
+ *
+ *	Once the generated packfile is available to the repository,
+ *	call `git_mempack_reset` to cleanup the memory store.
+ *
+ *	Calling `git_mempack_reset` before the packfile has been
+ *	written to disk will result in an inconsistent repository
+ *	(the objects in the memory store won't be accessible).
+ *
+ *	@param pack Buffer where to store the raw packfile
+ *	@param repo The active repository where the backend is loaded
+ *	@param backend The mempack backend
+ *	@return 0 on success; error code otherwise
+ */
+int git_mempack_dump(git_buf *pack, git_repository *repo, git_odb_backend *backend);
+
+/**
+ *	Reset the memory packer by clearing all the queued objects.
+ *
+ *	This assumes that `git_mempack_dump` has been called before to
+ *	store all the queued objects into a single packfile.
+ *
+ *	Alternatively, call `reset` without a previous dump to "undo"
+ *	all the recently written objects, giving transaction-like
+ *	semantics to the Git repository.
+ *
+ *	@param backend The mempack backend
+ */
+void git_mempack_reset(git_odb_backend *backend);
+
+GIT_END_DECL
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/odb_backend.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/odb_backend.h
new file mode 100755
index 0000000..fe102ff
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/odb_backend.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_odb_backend_h__
+#define INCLUDE_sys_git_odb_backend_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+#include "git2/odb.h"
+
+/**
+ * @file git2/sys/backend.h
+ * @brief Git custom backend implementors functions
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * An instance for a custom backend
+ */
+struct git_odb_backend {
+	unsigned int version;
+	git_odb *odb;
+
+	/* read and read_prefix each return to libgit2 a buffer which
+	 * will be freed later. The buffer should be allocated using
+	 * the function git_odb_backend_malloc to ensure that it can
+	 * be safely freed later. */
+	int (* read)(
+		void **, size_t *, git_otype *, git_odb_backend *, const git_oid *);
+
+	/* To find a unique object given a prefix of its oid.  The oid given
+	 * must be so that the remaining (GIT_OID_HEXSZ - len)*4 bits are 0s.
+	 */
+	int (* read_prefix)(
+		git_oid *, void **, size_t *, git_otype *,
+		git_odb_backend *, const git_oid *, size_t);
+
+	int (* read_header)(
+		size_t *, git_otype *, git_odb_backend *, const git_oid *);
+
+	/**
+	 * Write an object into the backend. The id of the object has
+	 * already been calculated and is passed in.
+	 */
+	int (* write)(
+		git_odb_backend *, const git_oid *, const void *, size_t, git_otype);
+
+	int (* writestream)(
+		git_odb_stream **, git_odb_backend *, git_off_t, git_otype);
+
+	int (* readstream)(
+		git_odb_stream **, git_odb_backend *, const git_oid *);
+
+	int (* exists)(
+		git_odb_backend *, const git_oid *);
+
+	int (* exists_prefix)(
+		git_oid *, git_odb_backend *, const git_oid *, size_t);
+
+	/**
+	 * If the backend implements a refreshing mechanism, it should be exposed
+	 * through this endpoint. Each call to `git_odb_refresh()` will invoke it.
+	 *
+	 * However, the backend implementation should try to stay up-to-date as much
+	 * as possible by itself as libgit2 will not automatically invoke
+	 * `git_odb_refresh()`. For instance, a potential strategy for the backend
+	 * implementation to achieve this could be to internally invoke this
+	 * endpoint on failed lookups (ie. `exists()`, `read()`, `read_header()`).
+	 */
+	int (* refresh)(git_odb_backend *);
+
+	int (* foreach)(
+		git_odb_backend *, git_odb_foreach_cb cb, void *payload);
+
+	int (* writepack)(
+		git_odb_writepack **, git_odb_backend *, git_odb *odb,
+		git_transfer_progress_cb progress_cb, void *progress_payload);
+
+	void (* free)(git_odb_backend *);
+};
+
+#define GIT_ODB_BACKEND_VERSION 1
+#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION}
+
+/**
+ * Initializes a `git_odb_backend` with default values. Equivalent to
+ * creating an instance with GIT_ODB_BACKEND_INIT.
+ *
+ * @param backend the `git_odb_backend` struct to initialize.
+ * @param version Version the struct; pass `GIT_ODB_BACKEND_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_odb_init_backend(
+	git_odb_backend *backend,
+	unsigned int version);
+
+GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len);
+
+GIT_END_DECL
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/openssl.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/openssl.h
new file mode 100755
index 0000000..b41c55c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/openssl.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_openssl_h__
+#define INCLUDE_git_openssl_h__
+
+#include "git2/common.h"
+
+GIT_BEGIN_DECL
+
+/**
+ * Initialize the OpenSSL locks
+ *
+ * OpenSSL requires the application to determine how it performs
+ * locking.
+ *
+ * This is a last-resort convenience function which libgit2 provides for
+ * allocating and initializing the locks as well as setting the
+ * locking function to use the system's native locking functions.
+ *
+ * The locking function will be cleared and the memory will be freed
+ * when you call git_threads_sutdown().
+ *
+ * If your programming language has an OpenSSL package/bindings, it
+ * likely sets up locking. You should very strongly prefer that over
+ * this function.
+ *
+ * @return 0 on success, -1 if there are errors or if libgit2 was not
+ * built with OpenSSL and threading support.
+ */
+GIT_EXTERN(int) git_openssl_set_locking(void);
+
+GIT_END_DECL
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/refdb_backend.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/refdb_backend.h
new file mode 100755
index 0000000..8b004a7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/refdb_backend.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_refdb_backend_h__
+#define INCLUDE_sys_git_refdb_backend_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+
+/**
+ * @file git2/refdb_backend.h
+ * @brief Git custom refs backend functions
+ * @defgroup git_refdb_backend Git custom refs backend API
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+
+/**
+ * Every backend's iterator must have a pointer to itself as the first
+ * element, so the API can talk to it. You'd define your iterator as
+ *
+ *     struct my_iterator {
+ *             git_reference_iterator parent;
+ *             ...
+ *     }
+ *
+ * and assign `iter->parent.backend` to your `git_refdb_backend`.
+ */
+struct git_reference_iterator {
+	git_refdb *db;
+
+	/**
+	 * Return the current reference and advance the iterator.
+	 */
+	int (*next)(
+		git_reference **ref,
+		git_reference_iterator *iter);
+
+	/**
+	 * Return the name of the current reference and advance the iterator
+	 */
+	int (*next_name)(
+		const char **ref_name,
+		git_reference_iterator *iter);
+
+	/**
+	 * Free the iterator
+	 */
+	void (*free)(
+		git_reference_iterator *iter);
+};
+
+/** An instance for a custom backend */
+struct git_refdb_backend {
+	unsigned int version;
+
+	/**
+	 * Queries the refdb backend to determine if the given ref_name
+	 * exists.  A refdb implementation must provide this function.
+	 */
+	int (*exists)(
+		int *exists,
+		git_refdb_backend *backend,
+		const char *ref_name);
+
+	/**
+	 * Queries the refdb backend for a given reference.  A refdb
+	 * implementation must provide this function.
+	 */
+	int (*lookup)(
+		git_reference **out,
+		git_refdb_backend *backend,
+		const char *ref_name);
+
+	/**
+	 * Allocate an iterator object for the backend.
+	 *
+	 * A refdb implementation must provide this function.
+	 */
+	int (*iterator)(
+		git_reference_iterator **iter,
+		struct git_refdb_backend *backend,
+		const char *glob);
+
+	/*
+	 * Writes the given reference to the refdb.  A refdb implementation
+	 * must provide this function.
+	 */
+	int (*write)(git_refdb_backend *backend,
+		     const git_reference *ref, int force,
+		     const git_signature *who, const char *message,
+		     const git_oid *old, const char *old_target);
+
+	int (*rename)(
+		git_reference **out, git_refdb_backend *backend,
+		const char *old_name, const char *new_name, int force,
+		const git_signature *who, const char *message);
+
+	/**
+	 * Deletes the given reference from the refdb.  A refdb implementation
+	 * must provide this function.
+	 */
+	int (*del)(git_refdb_backend *backend, const char *ref_name, const git_oid *old_id, const char *old_target);
+
+	/**
+	 * Suggests that the given refdb compress or optimize its references.
+	 * This mechanism is implementation specific.  (For on-disk reference
+	 * databases, this may pack all loose references.)    A refdb
+	 * implementation may provide this function; if it is not provided,
+	 * nothing will be done.
+	 */
+	int (*compress)(git_refdb_backend *backend);
+
+	/**
+	 * Query whether a particular reference has a log (may be empty)
+	 */
+	int (*has_log)(git_refdb_backend *backend, const char *refname);
+
+	/**
+	 * Make sure a particular reference will have a reflog which
+	 * will be appended to on writes.
+	 */
+	int (*ensure_log)(git_refdb_backend *backend, const char *refname);
+
+	/**
+	 * Frees any resources held by the refdb.  A refdb implementation may
+	 * provide this function; if it is not provided, nothing will be done.
+	 */
+	void (*free)(git_refdb_backend *backend);
+
+	/**
+	 * Read the reflog for the given reference name.
+	 */
+	int (*reflog_read)(git_reflog **out, git_refdb_backend *backend, const char *name);
+
+	/**
+	 * Write a reflog to disk.
+	 */
+	int (*reflog_write)(git_refdb_backend *backend, git_reflog *reflog);
+
+	/**
+	 * Rename a reflog
+	 */
+	int (*reflog_rename)(git_refdb_backend *_backend, const char *old_name, const char *new_name);
+
+	/**
+	 * Remove a reflog.
+	 */
+	int (*reflog_delete)(git_refdb_backend *backend, const char *name);
+
+	/**
+	 * Lock a reference. The opaque parameter will be passed to the unlock function
+	 */
+	int (*lock)(void **payload_out, git_refdb_backend *backend, const char *refname);
+
+	/**
+	 * Unlock a reference. Only one of target or symbolic_target
+	 * will be set. success indicates whether to update the
+	 * reference or discard the lock (if it's false)
+	 */
+	int (*unlock)(git_refdb_backend *backend, void *payload, int success, int update_reflog,
+		      const git_reference *ref, const git_signature *sig, const char *message);
+};
+
+#define GIT_REFDB_BACKEND_VERSION 1
+#define GIT_REFDB_BACKEND_INIT {GIT_REFDB_BACKEND_VERSION}
+
+/**
+ * Initializes a `git_refdb_backend` with default values. Equivalent to
+ * creating an instance with GIT_REFDB_BACKEND_INIT.
+ *
+ * @param backend the `git_refdb_backend` struct to initialize
+ * @param version Version of struct; pass `GIT_REFDB_BACKEND_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_refdb_init_backend(
+	git_refdb_backend *backend,
+	unsigned int version);
+
+/**
+ * Constructors for default filesystem-based refdb backend
+ *
+ * Under normal usage, this is called for you when the repository is
+ * opened / created, but you can use this to explicitly construct a
+ * filesystem refdb backend for a repository.
+ *
+ * @param backend_out Output pointer to the git_refdb_backend object
+ * @param repo Git repository to access
+ * @return 0 on success, <0 error code on failure
+ */
+GIT_EXTERN(int) git_refdb_backend_fs(
+	git_refdb_backend **backend_out,
+	git_repository *repo);
+
+/**
+ * Sets the custom backend to an existing reference DB
+ *
+ * The `git_refdb` will take ownership of the `git_refdb_backend` so you
+ * should NOT free it after calling this function.
+ *
+ * @param refdb database to add the backend to
+ * @param backend pointer to a git_refdb_backend instance
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_refdb_set_backend(
+	git_refdb *refdb,
+	git_refdb_backend *backend);
+
+GIT_END_DECL
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/reflog.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/reflog.h
new file mode 100755
index 0000000..c9d0041
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/reflog.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_reflog_h__
+#define INCLUDE_sys_git_reflog_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+
+GIT_BEGIN_DECL
+
+GIT_EXTERN(git_reflog_entry *) git_reflog_entry__alloc(void);
+GIT_EXTERN(void) git_reflog_entry__free(git_reflog_entry *entry);
+
+GIT_END_DECL
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/refs.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/refs.h
new file mode 100755
index 0000000..d2ce2e0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/refs.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_refdb_h__
+#define INCLUDE_sys_git_refdb_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+
+/**
+ * @file git2/sys/refs.h
+ * @brief Low-level Git ref creation
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create a new direct reference from an OID.
+ *
+ * @param name the reference name
+ * @param oid the object id for a direct reference
+ * @param peel the first non-tag object's OID, or NULL
+ * @return the created git_reference or NULL on error
+ */
+GIT_EXTERN(git_reference *) git_reference__alloc(
+	const char *name,
+	const git_oid *oid,
+	const git_oid *peel);
+
+/**
+ * Create a new symbolic reference.
+ *
+ * @param name the reference name
+ * @param target the target for a symbolic reference
+ * @return the created git_reference or NULL on error
+ */
+GIT_EXTERN(git_reference *) git_reference__alloc_symbolic(
+	const char *name,
+	const char *target);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/repository.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/repository.h
new file mode 100755
index 0000000..800396c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/repository.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_repository_h__
+#define INCLUDE_sys_git_repository_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+
+/**
+ * @file git2/sys/repository.h
+ * @brief Git repository custom implementation routines
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create a new repository with neither backends nor config object
+ *
+ * Note that this is only useful if you wish to associate the repository
+ * with a non-filesystem-backed object database and config store.
+ *
+ * @param out The blank repository
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository_new(git_repository **out);
+
+/**
+ * Reset all the internal state in a repository.
+ *
+ * This will free all the mapped memory and internal objects
+ * of the repository and leave it in a "blank" state.
+ *
+ * There's no need to call this function directly unless you're
+ * trying to aggressively cleanup the repo before its
+ * deallocation. `git_repository_free` already performs this operation
+ * before deallocation the repo.
+ */
+GIT_EXTERN(void) git_repository__cleanup(git_repository *repo);
+
+/**
+ * Update the filesystem config settings for an open repository
+ *
+ * When a repository is initialized, config values are set based on the
+ * properties of the filesystem that the repository is on, such as
+ * "core.ignorecase", "core.filemode", "core.symlinks", etc.  If the
+ * repository is moved to a new filesystem, these properties may no
+ * longer be correct and API calls may not behave as expected.  This
+ * call reruns the phase of repository initialization that sets those
+ * properties to compensate for the current filesystem of the repo.
+ *
+ * @param repo A repository object
+ * @param recurse_submodules Should submodules be updated recursively
+ * @return 0 on success, < 0 on error
+ */
+GIT_EXTERN(int) git_repository_reinit_filesystem(
+	git_repository *repo,
+	int recurse_submodules);
+
+/**
+ * Set the configuration file for this repository
+ *
+ * This configuration file will be used for all configuration
+ * queries involving this repository.
+ *
+ * The repository will keep a reference to the config file;
+ * the user must still free the config after setting it
+ * to the repository, or it will leak.
+ *
+ * @param repo A repository object
+ * @param config A Config object
+ */
+GIT_EXTERN(void) git_repository_set_config(git_repository *repo, git_config *config);
+
+/**
+ * Set the Object Database for this repository
+ *
+ * The ODB will be used for all object-related operations
+ * involving this repository.
+ *
+ * The repository will keep a reference to the ODB; the user
+ * must still free the ODB object after setting it to the
+ * repository, or it will leak.
+ *
+ * @param repo A repository object
+ * @param odb An ODB object
+ */
+GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb);
+
+/**
+ * Set the Reference Database Backend for this repository
+ *
+ * The refdb will be used for all reference related operations
+ * involving this repository.
+ *
+ * The repository will keep a reference to the refdb; the user
+ * must still free the refdb object after setting it to the
+ * repository, or it will leak.
+ *
+ * @param repo A repository object
+ * @param refdb An refdb object
+ */
+GIT_EXTERN(void) git_repository_set_refdb(git_repository *repo, git_refdb *refdb);
+
+/**
+ * Set the index file for this repository
+ *
+ * This index will be used for all index-related operations
+ * involving this repository.
+ *
+ * The repository will keep a reference to the index file;
+ * the user must still free the index after setting it
+ * to the repository, or it will leak.
+ *
+ * @param repo A repository object
+ * @param index An index object
+ */
+GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index);
+
+/**
+ * Set a repository to be bare.
+ *
+ * Clear the working directory and set core.bare to true.  You may also
+ * want to call `git_repository_set_index(repo, NULL)` since a bare repo
+ * typically does not have an index, but this function will not do that
+ * for you.
+ *
+ * @param repo Repo to make bare
+ * @return 0 on success, <0 on failure
+ */
+GIT_EXTERN(int) git_repository_set_bare(git_repository *repo);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/stream.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/stream.h
new file mode 100755
index 0000000..55a714b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/stream.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_stream_h__
+#define INCLUDE_sys_git_stream_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+
+GIT_BEGIN_DECL
+
+#define GIT_STREAM_VERSION 1
+
+/**
+ * Every stream must have this struct as its first element, so the
+ * API can talk to it. You'd define your stream as
+ *
+ *     struct my_stream {
+ *             git_stream parent;
+ *             ...
+ *     }
+ *
+ * and fill the functions
+ */
+typedef struct git_stream {
+	int version;
+
+	int encrypted;
+	int proxy_support;
+	int (*connect)(struct git_stream *);
+	int (*certificate)(git_cert **, struct git_stream *);
+	int (*set_proxy)(struct git_stream *, const char *proxy_url);
+	ssize_t (*read)(struct git_stream *, void *, size_t);
+	ssize_t (*write)(struct git_stream *, const char *, size_t, int);
+	int (*close)(struct git_stream *);
+	void (*free)(struct git_stream *);
+} git_stream;
+
+GIT_END_DECL
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/transport.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/transport.h
new file mode 100755
index 0000000..867fbcb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/sys/transport.h
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_sys_git_transport_h
+#define INCLUDE_sys_git_transport_h
+
+#include "git2/net.h"
+#include "git2/types.h"
+
+/**
+ * @file git2/sys/transport.h
+ * @brief Git custom transport registration interfaces and functions
+ * @defgroup git_transport Git custom transport registration
+ * @ingroup Git
+ * @{
+ */
+
+GIT_BEGIN_DECL
+
+/**
+ * Flags to pass to transport
+ *
+ * Currently unused.
+ */
+typedef enum {
+	GIT_TRANSPORTFLAGS_NONE = 0,
+} git_transport_flags_t;
+
+struct git_transport {
+	unsigned int version;
+	/* Set progress and error callbacks */
+	int (*set_callbacks)(
+		git_transport *transport,
+		git_transport_message_cb progress_cb,
+		git_transport_message_cb error_cb,
+		git_transport_certificate_check_cb certificate_check_cb,
+		void *payload);
+
+	/* Connect the transport to the remote repository, using the given
+	 * direction. */
+	int (*connect)(
+		git_transport *transport,
+		const char *url,
+		git_cred_acquire_cb cred_acquire_cb,
+		void *cred_acquire_payload,
+		int direction,
+		int flags);
+
+	/* This function may be called after a successful call to
+	 * connect(). The array returned is owned by the transport and
+	 * is guaranteed until the next call of a transport function. */
+	int (*ls)(
+		const git_remote_head ***out,
+		size_t *size,
+		git_transport *transport);
+
+	/* Executes the push whose context is in the git_push object. */
+	int (*push)(git_transport *transport, git_push *push, const git_remote_callbacks *callbacks);
+
+	/* This function may be called after a successful call to connect(), when
+	 * the direction is FETCH. The function performs a negotiation to calculate
+	 * the wants list for the fetch. */
+	int (*negotiate_fetch)(
+		git_transport *transport,
+		git_repository *repo,
+		const git_remote_head * const *refs,
+		size_t count);
+
+	/* This function may be called after a successful call to negotiate_fetch(),
+	 * when the direction is FETCH. This function retrieves the pack file for
+	 * the fetch from the remote end. */
+	int (*download_pack)(
+		git_transport *transport,
+		git_repository *repo,
+		git_transfer_progress *stats,
+		git_transfer_progress_cb progress_cb,
+		void *progress_payload);
+
+	/* Checks to see if the transport is connected */
+	int (*is_connected)(git_transport *transport);
+
+	/* Reads the flags value previously passed into connect() */
+	int (*read_flags)(git_transport *transport, int *flags);
+
+	/* Cancels any outstanding transport operation */
+	void (*cancel)(git_transport *transport);
+
+	/* This function is the reverse of connect() -- it terminates the
+	 * connection to the remote end. */
+	int (*close)(git_transport *transport);
+
+	/* Frees/destructs the git_transport object. */
+	void (*free)(git_transport *transport);
+};
+
+#define GIT_TRANSPORT_VERSION 1
+#define GIT_TRANSPORT_INIT {GIT_TRANSPORT_VERSION}
+
+/**
+ * Initializes a `git_transport` with default values. Equivalent to
+ * creating an instance with GIT_TRANSPORT_INIT.
+ *
+ * @param opts the `git_transport` struct to initialize
+ * @param version Version of struct; pass `GIT_TRANSPORT_VERSION`
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_transport_init(
+	git_transport *opts,
+	unsigned int version);
+
+/**
+ * Function to use to create a transport from a URL. The transport database
+ * is scanned to find a transport that implements the scheme of the URI (i.e.
+ * git:// or http://) and a transport object is returned to the caller.
+ *
+ * @param out The newly created transport (out)
+ * @param owner The git_remote which will own this transport
+ * @param url The URL to connect to
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_new(git_transport **out, git_remote *owner, const char *url);
+
+/**
+ * Create an ssh transport with custom git command paths
+ *
+ * This is a factory function suitable for setting as the transport
+ * callback in a remote (or for a clone in the options).
+ *
+ * The payload argument must be a strarray pointer with the paths for
+ * the `git-upload-pack` and `git-receive-pack` at index 0 and 1.
+ *
+ * @param out the resulting transport
+ * @param owner the owning remote
+ * @param payload a strarray with the paths
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_ssh_with_paths(git_transport **out, git_remote *owner, void *payload);
+
+/**
+ * Add a custom transport definition, to be used in addition to the built-in
+ * set of transports that come with libgit2.
+ *
+ * The caller is responsible for synchronizing calls to git_transport_register
+ * and git_transport_unregister with other calls to the library that
+ * instantiate transports.
+ *
+ * @param prefix The scheme (ending in "://") to match, i.e. "git://"
+ * @param cb The callback used to create an instance of the transport
+ * @param param A fixed parameter to pass to cb at creation time
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_register(
+	const char *prefix,
+	git_transport_cb cb,
+	void *param);
+
+/**
+ *
+ * Unregister a custom transport definition which was previously registered
+ * with git_transport_register.
+ *
+ * @param prefix From the previous call to git_transport_register
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_unregister(
+	const char *prefix);
+
+/* Transports which come with libgit2 (match git_transport_cb). The expected
+ * value for "param" is listed in-line below. */
+
+/**
+ * Create an instance of the dummy transport.
+ *
+ * @param out The newly created transport (out)
+ * @param owner The git_remote which will own this transport
+ * @param payload You must pass NULL for this parameter.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_dummy(
+	git_transport **out,
+	git_remote *owner,
+	/* NULL */ void *payload);
+
+/**
+ * Create an instance of the local transport.
+ *
+ * @param out The newly created transport (out)
+ * @param owner The git_remote which will own this transport
+ * @param payload You must pass NULL for this parameter.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_local(
+	git_transport **out,
+	git_remote *owner,
+	/* NULL */ void *payload);
+
+/**
+ * Create an instance of the smart transport.
+ *
+ * @param out The newly created transport (out)
+ * @param owner The git_remote which will own this transport
+ * @param payload A pointer to a git_smart_subtransport_definition
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transport_smart(
+	git_transport **out,
+	git_remote *owner,
+	/* (git_smart_subtransport_definition *) */ void *payload);
+
+/*
+ *** End of base transport interface ***
+ *** Begin interface for subtransports for the smart transport ***
+ */
+
+/* The smart transport knows how to speak the git protocol, but it has no
+ * knowledge of how to establish a connection between it and another endpoint,
+ * or how to move data back and forth. For this, a subtransport interface is
+ * declared, and the smart transport delegates this work to the subtransports.
+ * Three subtransports are implemented: git, http, and winhttp. (The http and
+ * winhttp transports each implement both http and https.) */
+
+/* Subtransports can either be RPC = 0 (persistent connection) or RPC = 1
+ * (request/response). The smart transport handles the differences in its own
+ * logic. The git subtransport is RPC = 0, while http and winhttp are both
+ * RPC = 1. */
+
+/* Actions that the smart transport can ask
+ * a subtransport to perform */
+typedef enum {
+	GIT_SERVICE_UPLOADPACK_LS = 1,
+	GIT_SERVICE_UPLOADPACK = 2,
+	GIT_SERVICE_RECEIVEPACK_LS = 3,
+	GIT_SERVICE_RECEIVEPACK = 4,
+} git_smart_service_t;
+
+typedef struct git_smart_subtransport git_smart_subtransport;
+typedef struct git_smart_subtransport_stream git_smart_subtransport_stream;
+
+/* A stream used by the smart transport to read and write data
+ * from a subtransport */
+struct git_smart_subtransport_stream {
+	/* The owning subtransport */
+	git_smart_subtransport *subtransport;
+
+	int (*read)(
+		git_smart_subtransport_stream *stream,
+		char *buffer,
+		size_t buf_size,
+		size_t *bytes_read);
+
+	int (*write)(
+		git_smart_subtransport_stream *stream,
+		const char *buffer,
+		size_t len);
+
+	void (*free)(
+		git_smart_subtransport_stream *stream);
+};
+
+/* An implementation of a subtransport which carries data for the
+ * smart transport */
+struct git_smart_subtransport {
+	int (* action)(
+			git_smart_subtransport_stream **out,
+			git_smart_subtransport *transport,
+			const char *url,
+			git_smart_service_t action);
+
+	/* Subtransports are guaranteed a call to close() between
+	 * calls to action(), except for the following two "natural" progressions
+	 * of actions against a constant URL.
+	 *
+	 * 1. UPLOADPACK_LS -> UPLOADPACK
+	 * 2. RECEIVEPACK_LS -> RECEIVEPACK */
+	int (*close)(git_smart_subtransport *transport);
+
+	void (*free)(git_smart_subtransport *transport);
+};
+
+/* A function which creates a new subtransport for the smart transport */
+typedef int (*git_smart_subtransport_cb)(
+	git_smart_subtransport **out,
+	git_transport* owner,
+	void* param);
+
+/**
+ * Definition for a "subtransport"
+ *
+ * This is used to let the smart protocol code know about the protocol
+ * which you are implementing.
+ */
+typedef struct git_smart_subtransport_definition {
+	/** The function to use to create the git_smart_subtransport */
+	git_smart_subtransport_cb callback;
+
+	/**
+	 * True if the protocol is stateless; false otherwise. For example,
+	 * http:// is stateless, but git:// is not.
+	 */
+	unsigned rpc;
+
+	/** Param of the callback
+	 */
+	void* param;
+} git_smart_subtransport_definition;
+
+/* Smart transport subtransports that come with libgit2 */
+
+/**
+ * Create an instance of the http subtransport. This subtransport
+ * also supports https. On Win32, this subtransport may be implemented
+ * using the WinHTTP library.
+ *
+ * @param out The newly created subtransport
+ * @param owner The smart transport to own this subtransport
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_smart_subtransport_http(
+	git_smart_subtransport **out,
+	git_transport* owner,
+	void *param);
+
+/**
+ * Create an instance of the git subtransport.
+ *
+ * @param out The newly created subtransport
+ * @param owner The smart transport to own this subtransport
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_smart_subtransport_git(
+	git_smart_subtransport **out,
+	git_transport* owner,
+	void *param);
+
+/**
+ * Create an instance of the ssh subtransport.
+ *
+ * @param out The newly created subtransport
+ * @param owner The smart transport to own this subtransport
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_smart_subtransport_ssh(
+	git_smart_subtransport **out,
+	git_transport* owner,
+	void *param);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/tag.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/tag.h
new file mode 100755
index 0000000..c822cee
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/tag.h
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_tag_h__
+#define INCLUDE_git_tag_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "object.h"
+#include "strarray.h"
+
+/**
+ * @file git2/tag.h
+ * @brief Git tag parsing routines
+ * @defgroup git_tag Git tag management
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Lookup a tag object from the repository.
+ *
+ * @param out pointer to the looked up tag
+ * @param repo the repo to use when locating the tag.
+ * @param id identity of the tag to locate.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tag_lookup(
+	git_tag **out, git_repository *repo, const git_oid *id);
+
+/**
+ * Lookup a tag object from the repository,
+ * given a prefix of its identifier (short id).
+ *
+ * @see git_object_lookup_prefix
+ *
+ * @param out pointer to the looked up tag
+ * @param repo the repo to use when locating the tag.
+ * @param id identity of the tag to locate.
+ * @param len the length of the short identifier
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tag_lookup_prefix(
+	git_tag **out, git_repository *repo, const git_oid *id, size_t len);
+
+/**
+ * Close an open tag
+ *
+ * You can no longer use the git_tag pointer after this call.
+ *
+ * IMPORTANT: You MUST call this method when you are through with a tag to
+ * release memory. Failure to do so will cause a memory leak.
+ *
+ * @param tag the tag to close
+ */
+GIT_EXTERN(void) git_tag_free(git_tag *tag);
+
+/**
+ * Get the id of a tag.
+ *
+ * @param tag a previously loaded tag.
+ * @return object identity for the tag.
+ */
+GIT_EXTERN(const git_oid *) git_tag_id(const git_tag *tag);
+
+/**
+ * Get the repository that contains the tag.
+ *
+ * @param tag A previously loaded tag.
+ * @return Repository that contains this tag.
+ */
+GIT_EXTERN(git_repository *) git_tag_owner(const git_tag *tag);
+
+/**
+ * Get the tagged object of a tag
+ *
+ * This method performs a repository lookup for the
+ * given object and returns it
+ *
+ * @param target_out pointer where to store the target
+ * @param tag a previously loaded tag.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tag_target(git_object **target_out, const git_tag *tag);
+
+/**
+ * Get the OID of the tagged object of a tag
+ *
+ * @param tag a previously loaded tag.
+ * @return pointer to the OID
+ */
+GIT_EXTERN(const git_oid *) git_tag_target_id(const git_tag *tag);
+
+/**
+ * Get the type of a tag's tagged object
+ *
+ * @param tag a previously loaded tag.
+ * @return type of the tagged object
+ */
+GIT_EXTERN(git_otype) git_tag_target_type(const git_tag *tag);
+
+/**
+ * Get the name of a tag
+ *
+ * @param tag a previously loaded tag.
+ * @return name of the tag
+ */
+GIT_EXTERN(const char *) git_tag_name(const git_tag *tag);
+
+/**
+ * Get the tagger (author) of a tag
+ *
+ * @param tag a previously loaded tag.
+ * @return reference to the tag's author or NULL when unspecified
+ */
+GIT_EXTERN(const git_signature *) git_tag_tagger(const git_tag *tag);
+
+/**
+ * Get the message of a tag
+ *
+ * @param tag a previously loaded tag.
+ * @return message of the tag or NULL when unspecified
+ */
+GIT_EXTERN(const char *) git_tag_message(const git_tag *tag);
+
+
+/**
+ * Create a new tag in the repository from an object
+ *
+ * A new reference will also be created pointing to
+ * this tag object. If `force` is true and a reference
+ * already exists with the given name, it'll be replaced.
+ *
+ * The message will not be cleaned up. This can be achieved
+ * through `git_message_prettify()`.
+ *
+ * The tag name will be checked for validity. You must avoid
+ * the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ * sequences ".." and "@{" which have special meaning to revparse.
+ *
+ * @param oid Pointer where to store the OID of the
+ * newly created tag. If the tag already exists, this parameter
+ * will be the oid of the existing tag, and the function will
+ * return a GIT_EEXISTS error code.
+ *
+ * @param repo Repository where to store the tag
+ *
+ * @param tag_name Name for the tag; this name is validated
+ * for consistency. It should also not conflict with an
+ * already existing tag name
+ *
+ * @param target Object to which this tag points. This object
+ * must belong to the given `repo`.
+ *
+ * @param tagger Signature of the tagger for this tag, and
+ * of the tagging time
+ *
+ * @param message Full message for this tag
+ *
+ * @param force Overwrite existing references
+ *
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
+ *	A tag object is written to the ODB, and a proper reference
+ *	is written in the /refs/tags folder, pointing to it
+ */
+GIT_EXTERN(int) git_tag_create(
+	git_oid *oid,
+	git_repository *repo,
+	const char *tag_name,
+	const git_object *target,
+	const git_signature *tagger,
+	const char *message,
+	int force);
+
+/**
+ * Create a new tag in the object database pointing to a git_object
+ *
+ * The message will not be cleaned up. This can be achieved
+ * through `git_message_prettify()`.
+ *
+ * @param oid Pointer where to store the OID of the
+ * newly created tag
+ *
+ * @param repo Repository where to store the tag
+ *
+ * @param tag_name Name for the tag
+ *
+ * @param target Object to which this tag points. This object
+ * must belong to the given `repo`.
+ *
+ * @param tagger Signature of the tagger for this tag, and
+ * of the tagging time
+ *
+ * @param message Full message for this tag
+ *
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_tag_annotation_create(
+	git_oid *oid,
+	git_repository *repo,
+	const char *tag_name,
+	const git_object *target,
+	const git_signature *tagger,
+	const char *message);
+
+/**
+ * Create a new tag in the repository from a buffer
+ *
+ * @param oid Pointer where to store the OID of the newly created tag
+ * @param repo Repository where to store the tag
+ * @param buffer Raw tag data
+ * @param force Overwrite existing tags
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_tag_create_frombuffer(
+	git_oid *oid,
+	git_repository *repo,
+	const char *buffer,
+	int force);
+
+/**
+ * Create a new lightweight tag pointing at a target object
+ *
+ * A new direct reference will be created pointing to
+ * this target object. If `force` is true and a reference
+ * already exists with the given name, it'll be replaced.
+ *
+ * The tag name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
+ *
+ * @param oid Pointer where to store the OID of the provided
+ * target object. If the tag already exists, this parameter
+ * will be filled with the oid of the existing pointed object
+ * and the function will return a GIT_EEXISTS error code.
+ *
+ * @param repo Repository where to store the lightweight tag
+ *
+ * @param tag_name Name for the tag; this name is validated
+ * for consistency. It should also not conflict with an
+ * already existing tag name
+ *
+ * @param target Object to which this tag points. This object
+ * must belong to the given `repo`.
+ *
+ * @param force Overwrite existing references
+ *
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
+ *	A proper reference is written in the /refs/tags folder,
+ * pointing to the provided target object
+ */
+GIT_EXTERN(int) git_tag_create_lightweight(
+	git_oid *oid,
+	git_repository *repo,
+	const char *tag_name,
+	const git_object *target,
+	int force);
+
+/**
+ * Delete an existing tag reference.
+ *
+ * The tag name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
+ *
+ * @param repo Repository where lives the tag
+ *
+ * @param tag_name Name of the tag to be deleted;
+ * this name is validated for consistency.
+ *
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
+ */
+GIT_EXTERN(int) git_tag_delete(
+	git_repository *repo,
+	const char *tag_name);
+
+/**
+ * Fill a list with all the tags in the Repository
+ *
+ * The string array will be filled with the names of the
+ * matching tags; these values are owned by the user and
+ * should be free'd manually when no longer needed, using
+ * `git_strarray_free`.
+ *
+ * @param tag_names Pointer to a git_strarray structure where
+ *		the tag names will be stored
+ * @param repo Repository where to find the tags
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tag_list(
+	git_strarray *tag_names,
+	git_repository *repo);
+
+/**
+ * Fill a list with all the tags in the Repository
+ * which name match a defined pattern
+ *
+ * If an empty pattern is provided, all the tags
+ * will be returned.
+ *
+ * The string array will be filled with the names of the
+ * matching tags; these values are owned by the user and
+ * should be free'd manually when no longer needed, using
+ * `git_strarray_free`.
+ *
+ * @param tag_names Pointer to a git_strarray structure where
+ *		the tag names will be stored
+ * @param pattern Standard fnmatch pattern
+ * @param repo Repository where to find the tags
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tag_list_match(
+	git_strarray *tag_names,
+	const char *pattern,
+	git_repository *repo);
+
+
+typedef int (*git_tag_foreach_cb)(const char *name, git_oid *oid, void *payload);
+
+/**
+ * Call callback `cb' for each tag in the repository
+ *
+ * @param repo Repository
+ * @param callback Callback function
+ * @param payload Pointer to callback data (optional)
+ */
+GIT_EXTERN(int) git_tag_foreach(
+	git_repository *repo,
+	git_tag_foreach_cb callback,
+	void *payload);
+
+
+/**
+ * Recursively peel a tag until a non tag git_object is found
+ *
+ * The retrieved `tag_target` object is owned by the repository
+ * and should be closed with the `git_object_free` method.
+ *
+ * @param tag_target_out Pointer to the peeled git_object
+ * @param tag The tag to be processed
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tag_peel(
+	git_object **tag_target_out,
+	const git_tag *tag);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/trace.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/trace.h
new file mode 100755
index 0000000..f9b4d6f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/trace.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_trace_h__
+#define INCLUDE_git_trace_h__
+
+#include "common.h"
+#include "types.h"
+
+/**
+ * @file git2/trace.h
+ * @brief Git tracing configuration routines
+ * @defgroup git_trace Git tracing configuration routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Available tracing levels.  When tracing is set to a particular level,
+ * callers will be provided tracing at the given level and all lower levels.
+ */
+typedef enum {
+	/** No tracing will be performed. */
+	GIT_TRACE_NONE = 0,
+
+	/** Severe errors that may impact the program's execution */
+	GIT_TRACE_FATAL = 1,
+
+	/** Errors that do not impact the program's execution */
+	GIT_TRACE_ERROR = 2,
+
+	/** Warnings that suggest abnormal data */
+	GIT_TRACE_WARN = 3,
+
+	/** Informational messages about program execution */
+	GIT_TRACE_INFO = 4,
+
+	/** Detailed data that allows for debugging */
+	GIT_TRACE_DEBUG = 5,
+
+	/** Exceptionally detailed debugging data */
+	GIT_TRACE_TRACE = 6
+} git_trace_level_t;
+
+/**
+ * An instance for a tracing function
+ */
+typedef void (*git_trace_callback)(git_trace_level_t level, const char *msg);
+
+/**
+ * Sets the system tracing configuration to the specified level with the
+ * specified callback.  When system events occur at a level equal to, or
+ * lower than, the given level they will be reported to the given callback.
+ *
+ * @param level Level to set tracing to
+ * @param cb Function to call with trace data
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_trace_set(git_trace_level_t level, git_trace_callback cb);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/transaction.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/transaction.h
new file mode 100755
index 0000000..64abb0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/transaction.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_transaction_h__
+#define INCLUDE_git_transaction_h__
+
+#include "common.h"
+GIT_BEGIN_DECL
+
+/**
+ * Create a new transaction object
+ *
+ * This does not lock anything, but sets up the transaction object to
+ * know from which repository to lock.
+ *
+ * @param out the resulting transaction
+ * @param repo the repository in which to lock
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transaction_new(git_transaction **out, git_repository *repo);
+
+/**
+ * Lock a reference
+ *
+ * Lock the specified reference. This is the first step to updating a
+ * reference.
+ *
+ * @param tx the transaction
+ * @param refname the reference to lock
+ * @return 0 or an error message
+ */
+GIT_EXTERN(int) git_transaction_lock_ref(git_transaction *tx, const char *refname);
+
+/**
+ * Set the target of a reference
+ *
+ * Set the target of the specified reference. This reference must be
+ * locked.
+ *
+ * @param tx the transaction
+ * @param refname reference to update
+ * @param target target to set the reference to
+ * @param sig signature to use in the reflog; pass NULL to read the identity from the config
+ * @param msg message to use in the reflog
+ * @return 0, GIT_ENOTFOUND if the reference is not among the locked ones, or an error code
+ */
+GIT_EXTERN(int) git_transaction_set_target(git_transaction *tx, const char *refname, const git_oid *target, const git_signature *sig, const char *msg);
+
+/**
+ * Set the target of a reference
+ *
+ * Set the target of the specified reference. This reference must be
+ * locked.
+ *
+ * @param tx the transaction
+ * @param refname reference to update
+ * @param target target to set the reference to
+ * @param sig signature to use in the reflog; pass NULL to read the identity from the config
+ * @param msg message to use in the reflog
+ * @return 0, GIT_ENOTFOUND if the reference is not among the locked ones, or an error code
+ */
+GIT_EXTERN(int) git_transaction_set_symbolic_target(git_transaction *tx, const char *refname, const char *target, const git_signature *sig, const char *msg);
+
+/**
+ * Set the reflog of a reference
+ *
+ * Set the specified reference's reflog. If this is combined with
+ * setting the target, that update won't be written to the reflog.
+ *
+ * @param tx the transaction
+ * @param refname the reference whose reflog to set
+ * @param reflog the reflog as it should be written out
+ * @return 0, GIT_ENOTFOUND if the reference is not among the locked ones, or an error code
+ */
+GIT_EXTERN(int) git_transaction_set_reflog(git_transaction *tx, const char *refname, const git_reflog *reflog);
+
+/**
+ * Remove a reference
+ *
+ * @param tx the transaction
+ * @param refname the reference to remove
+ * @return 0, GIT_ENOTFOUND if the reference is not among the locked ones, or an error code
+ */
+GIT_EXTERN(int) git_transaction_remove(git_transaction *tx, const char *refname);
+
+/**
+ * Commit the changes from the transaction
+ *
+ * Perform the changes that have been queued. The updates will be made
+ * one by one, and the first failure will stop the processing.
+ *
+ * @param tx the transaction
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_transaction_commit(git_transaction *tx);
+
+/**
+ * Free the resources allocated by this transaction
+ *
+ * If any references remain locked, they will be unlocked without any
+ * changes made to them.
+ *
+ * @param tx the transaction
+ */
+GIT_EXTERN(void) git_transaction_free(git_transaction *tx);
+
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/transport.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/transport.h
new file mode 100755
index 0000000..2eeebd5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/transport.h
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_transport_h__
+#define INCLUDE_git_transport_h__
+
+#include "indexer.h"
+#include "net.h"
+#include "types.h"
+
+/**
+ * @file git2/transport.h
+ * @brief Git transport interfaces and functions
+ * @defgroup git_transport interfaces and functions
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/** Signature of a function which creates a transport */
+typedef int (*git_transport_cb)(git_transport **out, git_remote *owner, void *param);
+
+/**
+ * Type of SSH host fingerprint
+ */
+typedef enum {
+	/** MD5 is available */
+	GIT_CERT_SSH_MD5 = (1 << 0),
+	/** SHA-1 is available */
+	GIT_CERT_SSH_SHA1 = (1 << 1),
+} git_cert_ssh_t;
+
+/**
+ * Hostkey information taken from libssh2
+ */
+typedef struct {
+	/**
+	 * Type of certificate. Here to share the header with
+	 * `git_cert`.
+	 */
+	git_cert_t cert_type;
+        /**
+         * A hostkey type from libssh2, either
+         * `GIT_CERT_SSH_MD5` or `GIT_CERT_SSH_SHA1`
+         */
+	git_cert_ssh_t type;
+
+        /**
+         * Hostkey hash. If type has `GIT_CERT_SSH_MD5` set, this will
+         * have the MD5 hash of the hostkey.
+         */
+	unsigned char hash_md5[16];
+
+        /**
+         * Hostkey hash. If type has `GIT_CERT_SSH_SHA1` set, this will
+         * have the SHA-1 hash of the hostkey.
+         */
+        unsigned char hash_sha1[20];
+} git_cert_hostkey;
+
+/**
+ * X.509 certificate information
+ */
+typedef struct {
+	/**
+	 * Type of certificate. Here to share the header with
+	 * `git_cert`.
+	 */
+	git_cert_t cert_type;
+	/**
+	 * Pointer to the X.509 certificate data
+	 */
+	void *data;
+	/**
+	 * Length of the memory block pointed to by `data`.
+	 */
+	size_t len;
+} git_cert_x509;
+
+/*
+ *** Begin interface for credentials acquisition ***
+ */
+
+/** Authentication type requested */
+typedef enum {
+	/* git_cred_userpass_plaintext */
+	GIT_CREDTYPE_USERPASS_PLAINTEXT = (1u << 0),
+
+	/* git_cred_ssh_key */
+	GIT_CREDTYPE_SSH_KEY = (1u << 1),
+
+	/* git_cred_ssh_custom */
+	GIT_CREDTYPE_SSH_CUSTOM = (1u << 2),
+
+	/* git_cred_default */
+	GIT_CREDTYPE_DEFAULT = (1u << 3),
+
+	/* git_cred_ssh_interactive */
+	GIT_CREDTYPE_SSH_INTERACTIVE = (1u << 4),
+
+	/**
+	 * Username-only information
+	 *
+	 * If the SSH transport does not know which username to use,
+	 * it will ask via this credential type.
+	 */
+	GIT_CREDTYPE_USERNAME = (1u << 5),
+
+	/**
+	 * Credentials read from memory.
+	 *
+	 * Only available for libssh2+OpenSSL for now.
+	 */
+	GIT_CREDTYPE_SSH_MEMORY = (1u << 6),
+} git_credtype_t;
+
+/* The base structure for all credential types */
+typedef struct git_cred git_cred;
+
+struct git_cred {
+	git_credtype_t credtype;
+	void (*free)(git_cred *cred);
+};
+
+/** A plaintext username and password */
+typedef struct {
+	git_cred parent;
+	char *username;
+	char *password;
+} git_cred_userpass_plaintext;
+
+
+/*
+ * If the user hasn't included libssh2.h before git2.h, we need to
+ * define a few types for the callback signatures.
+ */
+#ifndef LIBSSH2_VERSION
+typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION;
+typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT LIBSSH2_USERAUTH_KBDINT_PROMPT;
+typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE LIBSSH2_USERAUTH_KBDINT_RESPONSE;
+#endif
+
+typedef int (*git_cred_sign_callback)(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract);
+typedef void (*git_cred_ssh_interactive_callback)(const char* name, int name_len, const char* instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract);
+
+/**
+ * A ssh key from disk
+ */
+typedef struct git_cred_ssh_key {
+	git_cred parent;
+	char *username;
+	char *publickey;
+	char *privatekey;
+	char *passphrase;
+} git_cred_ssh_key;
+
+/**
+ * Keyboard-interactive based ssh authentication
+ */
+typedef struct git_cred_ssh_interactive {
+	git_cred parent;
+	char *username;
+	git_cred_ssh_interactive_callback prompt_callback;
+	void *payload;
+} git_cred_ssh_interactive;
+
+/**
+ * A key with a custom signature function
+ */
+typedef struct git_cred_ssh_custom {
+	git_cred parent;
+	char *username;
+	char *publickey;
+	size_t publickey_len;
+	git_cred_sign_callback sign_callback;
+	void *payload;
+} git_cred_ssh_custom;
+
+/** A key for NTLM/Kerberos "default" credentials */
+typedef struct git_cred git_cred_default;
+
+/** Username-only credential information */
+typedef struct git_cred_username {
+	git_cred parent;
+	char username[1];
+} git_cred_username;
+
+/**
+ * Check whether a credential object contains username information.
+ *
+ * @param cred object to check
+ * @return 1 if the credential object has non-NULL username, 0 otherwise
+ */
+GIT_EXTERN(int) git_cred_has_username(git_cred *cred);
+
+/**
+ * Create a new plain-text username and password credential object.
+ * The supplied credential parameter will be internally duplicated.
+ *
+ * @param out The newly created credential object.
+ * @param username The username of the credential.
+ * @param password The password of the credential.
+ * @return 0 for success or an error code for failure
+ */
+GIT_EXTERN(int) git_cred_userpass_plaintext_new(
+	git_cred **out,
+	const char *username,
+	const char *password);
+
+/**
+ * Create a new passphrase-protected ssh key credential object.
+ * The supplied credential parameter will be internally duplicated.
+ *
+ * @param out The newly created credential object.
+ * @param username username to use to authenticate
+ * @param publickey The path to the public key of the credential.
+ * @param privatekey The path to the private key of the credential.
+ * @param passphrase The passphrase of the credential.
+ * @return 0 for success or an error code for failure
+ */
+GIT_EXTERN(int) git_cred_ssh_key_new(
+	git_cred **out,
+	const char *username,
+	const char *publickey,
+	const char *privatekey,
+	const char *passphrase);
+
+/**
+ * Create a new ssh keyboard-interactive based credential object.
+ * The supplied credential parameter will be internally duplicated.
+ *
+ * @param username Username to use to authenticate.
+ * @param prompt_callback The callback method used for prompts.
+ * @param payload Additional data to pass to the callback.
+ * @return 0 for success or an error code for failure.
+ */
+GIT_EXTERN(int) git_cred_ssh_interactive_new(
+	git_cred **out,
+	const char *username,
+	git_cred_ssh_interactive_callback prompt_callback,
+	void *payload);
+
+/**
+ * Create a new ssh key credential object used for querying an ssh-agent.
+ * The supplied credential parameter will be internally duplicated.
+ *
+ * @param out The newly created credential object.
+ * @param username username to use to authenticate
+ * @return 0 for success or an error code for failure
+ */
+GIT_EXTERN(int) git_cred_ssh_key_from_agent(
+	git_cred **out,
+	const char *username);
+
+/**
+ * Create an ssh key credential with a custom signing function.
+ *
+ * This lets you use your own function to sign the challenge.
+ *
+ * This function and its credential type is provided for completeness
+ * and wraps `libssh2_userauth_publickey()`, which is undocumented.
+ *
+ * The supplied credential parameter will be internally duplicated.
+ *
+ * @param out The newly created credential object.
+ * @param username username to use to authenticate
+ * @param publickey The bytes of the public key.
+ * @param publickey_len The length of the public key in bytes.
+ * @param sign_callback The callback method to sign the data during the challenge.
+ * @param payload Additional data to pass to the callback.
+ * @return 0 for success or an error code for failure
+ */
+GIT_EXTERN(int) git_cred_ssh_custom_new(
+	git_cred **out,
+	const char *username,
+	const char *publickey,
+	size_t publickey_len,
+	git_cred_sign_callback sign_callback,
+	void *payload);
+
+/**
+ * Create a "default" credential usable for Negotiate mechanisms like NTLM
+ * or Kerberos authentication.
+ *
+ * @return 0 for success or an error code for failure
+ */
+GIT_EXTERN(int) git_cred_default_new(git_cred **out);
+
+/**
+ * Create a credential to specify a username.
+ *
+ * This is used with ssh authentication to query for the username if
+ * none is specified in the url.
+ */
+GIT_EXTERN(int) git_cred_username_new(git_cred **cred, const char *username);
+
+/**
+ * Create a new ssh key credential object reading the keys from memory.
+ *
+ * @param out The newly created credential object.
+ * @param username username to use to authenticate.
+ * @param publickey The public key of the credential.
+ * @param privatekey The private key of the credential.
+ * @param passphrase The passphrase of the credential.
+ * @return 0 for success or an error code for failure
+ */
+GIT_EXTERN(int) git_cred_ssh_key_memory_new(
+	git_cred **out,
+	const char *username,
+	const char *publickey,
+	const char *privatekey,
+	const char *passphrase);
+
+/**
+ * Signature of a function which acquires a credential object.
+ *
+ * - cred: The newly created credential object.
+ * - url: The resource for which we are demanding a credential.
+ * - username_from_url: The username that was embedded in a "user\@host"
+ *                          remote url, or NULL if not included.
+ * - allowed_types: A bitmask stating which cred types are OK to return.
+ * - payload: The payload provided when specifying this callback.
+ * - returns 0 for success, < 0 to indicate an error, > 0 to indicate
+ *       no credential was acquired
+ */
+typedef int (*git_cred_acquire_cb)(
+	git_cred **cred,
+	const char *url,
+	const char *username_from_url,
+	unsigned int allowed_types,
+	void *payload);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/tree.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/tree.h
new file mode 100755
index 0000000..550a448
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/tree.h
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_tree_h__
+#define INCLUDE_git_tree_h__
+
+#include "common.h"
+#include "types.h"
+#include "oid.h"
+#include "object.h"
+
+/**
+ * @file git2/tree.h
+ * @brief Git tree parsing, loading routines
+ * @defgroup git_tree Git tree parsing, loading routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Lookup a tree object from the repository.
+ *
+ * @param out Pointer to the looked up tree
+ * @param repo The repo to use when locating the tree.
+ * @param id Identity of the tree to locate.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tree_lookup(
+	git_tree **out, git_repository *repo, const git_oid *id);
+
+/**
+ * Lookup a tree object from the repository,
+ * given a prefix of its identifier (short id).
+ *
+ * @see git_object_lookup_prefix
+ *
+ * @param out pointer to the looked up tree
+ * @param repo the repo to use when locating the tree.
+ * @param id identity of the tree to locate.
+ * @param len the length of the short identifier
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tree_lookup_prefix(
+	git_tree **out,
+	git_repository *repo,
+	const git_oid *id,
+	size_t len);
+
+/**
+ * Close an open tree
+ *
+ * You can no longer use the git_tree pointer after this call.
+ *
+ * IMPORTANT: You MUST call this method when you stop using a tree to
+ * release memory. Failure to do so will cause a memory leak.
+ *
+ * @param tree The tree to close
+ */
+GIT_EXTERN(void) git_tree_free(git_tree *tree);
+
+/**
+ * Get the id of a tree.
+ *
+ * @param tree a previously loaded tree.
+ * @return object identity for the tree.
+ */
+GIT_EXTERN(const git_oid *) git_tree_id(const git_tree *tree);
+
+/**
+ * Get the repository that contains the tree.
+ *
+ * @param tree A previously loaded tree.
+ * @return Repository that contains this tree.
+ */
+GIT_EXTERN(git_repository *) git_tree_owner(const git_tree *tree);
+
+/**
+ * Get the number of entries listed in a tree
+ *
+ * @param tree a previously loaded tree.
+ * @return the number of entries in the tree
+ */
+GIT_EXTERN(size_t) git_tree_entrycount(const git_tree *tree);
+
+/**
+ * Lookup a tree entry by its filename
+ *
+ * This returns a git_tree_entry that is owned by the git_tree.  You don't
+ * have to free it, but you must not use it after the git_tree is released.
+ *
+ * @param tree a previously loaded tree.
+ * @param filename the filename of the desired entry
+ * @return the tree entry; NULL if not found
+ */
+GIT_EXTERN(const git_tree_entry *) git_tree_entry_byname(
+	const git_tree *tree, const char *filename);
+
+/**
+ * Lookup a tree entry by its position in the tree
+ *
+ * This returns a git_tree_entry that is owned by the git_tree.  You don't
+ * have to free it, but you must not use it after the git_tree is released.
+ *
+ * @param tree a previously loaded tree.
+ * @param idx the position in the entry list
+ * @return the tree entry; NULL if not found
+ */
+GIT_EXTERN(const git_tree_entry *) git_tree_entry_byindex(
+	const git_tree *tree, size_t idx);
+
+/**
+ * Lookup a tree entry by SHA value.
+ *
+ * This returns a git_tree_entry that is owned by the git_tree.  You don't
+ * have to free it, but you must not use it after the git_tree is released.
+ *
+ * Warning: this must examine every entry in the tree, so it is not fast.
+ *
+ * @param tree a previously loaded tree.
+ * @param id the sha being looked for
+ * @return the tree entry; NULL if not found
+ */
+GIT_EXTERN(const git_tree_entry *) git_tree_entry_byid(
+	const git_tree *tree, const git_oid *id);
+
+/**
+ * Retrieve a tree entry contained in a tree or in any of its subtrees,
+ * given its relative path.
+ *
+ * Unlike the other lookup functions, the returned tree entry is owned by
+ * the user and must be freed explicitly with `git_tree_entry_free()`.
+ *
+ * @param out Pointer where to store the tree entry
+ * @param root Previously loaded tree which is the root of the relative path
+ * @param path Path to the contained entry
+ * @return 0 on success; GIT_ENOTFOUND if the path does not exist
+ */
+GIT_EXTERN(int) git_tree_entry_bypath(
+	git_tree_entry **out,
+	const git_tree *root,
+	const char *path);
+
+/**
+ * Duplicate a tree entry
+ *
+ * Create a copy of a tree entry. The returned copy is owned by the user,
+ * and must be freed explicitly with `git_tree_entry_free()`.
+ *
+ * @param dest pointer where to store the copy
+ * @param source tree entry to duplicate
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tree_entry_dup(git_tree_entry **dest, const git_tree_entry *source);
+
+/**
+ * Free a user-owned tree entry
+ *
+ * IMPORTANT: This function is only needed for tree entries owned by the
+ * user, such as the ones returned by `git_tree_entry_dup()` or
+ * `git_tree_entry_bypath()`.
+ *
+ * @param entry The entry to free
+ */
+GIT_EXTERN(void) git_tree_entry_free(git_tree_entry *entry);
+
+/**
+ * Get the filename of a tree entry
+ *
+ * @param entry a tree entry
+ * @return the name of the file
+ */
+GIT_EXTERN(const char *) git_tree_entry_name(const git_tree_entry *entry);
+
+/**
+ * Get the id of the object pointed by the entry
+ *
+ * @param entry a tree entry
+ * @return the oid of the object
+ */
+GIT_EXTERN(const git_oid *) git_tree_entry_id(const git_tree_entry *entry);
+
+/**
+ * Get the type of the object pointed by the entry
+ *
+ * @param entry a tree entry
+ * @return the type of the pointed object
+ */
+GIT_EXTERN(git_otype) git_tree_entry_type(const git_tree_entry *entry);
+
+/**
+ * Get the UNIX file attributes of a tree entry
+ *
+ * @param entry a tree entry
+ * @return filemode as an integer
+ */
+GIT_EXTERN(git_filemode_t) git_tree_entry_filemode(const git_tree_entry *entry);
+
+/**
+ * Get the raw UNIX file attributes of a tree entry
+ *
+ * This function does not perform any normalization and is only useful
+ * if you need to be able to recreate the original tree object.
+ *
+ * @param entry a tree entry
+ * @return filemode as an integer
+ */
+
+GIT_EXTERN(git_filemode_t) git_tree_entry_filemode_raw(const git_tree_entry *entry);
+/**
+ * Compare two tree entries
+ *
+ * @param e1 first tree entry
+ * @param e2 second tree entry
+ * @return <0 if e1 is before e2, 0 if e1 == e2, >0 if e1 is after e2
+ */
+GIT_EXTERN(int) git_tree_entry_cmp(const git_tree_entry *e1, const git_tree_entry *e2);
+
+/**
+ * Convert a tree entry to the git_object it points to.
+ *
+ * You must call `git_object_free()` on the object when you are done with it.
+ *
+ * @param object_out pointer to the converted object
+ * @param repo repository where to lookup the pointed object
+ * @param entry a tree entry
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tree_entry_to_object(
+	git_object **object_out,
+	git_repository *repo,
+	const git_tree_entry *entry);
+
+/**
+ * Create a new tree builder.
+ *
+ * The tree builder can be used to create or modify trees in memory and
+ * write them as tree objects to the database.
+ *
+ * If the `source` parameter is not NULL, the tree builder will be
+ * initialized with the entries of the given tree.
+ *
+ * If the `source` parameter is NULL, the tree builder will start with no
+ * entries and will have to be filled manually.
+ *
+ * @param out Pointer where to store the tree builder
+ * @param repo Repository in which to store the object
+ * @param source Source tree to initialize the builder (optional)
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_treebuilder_new(
+	git_treebuilder **out, git_repository *repo, const git_tree *source);
+
+/**
+ * Clear all the entires in the builder
+ *
+ * @param bld Builder to clear
+ */
+GIT_EXTERN(void) git_treebuilder_clear(git_treebuilder *bld);
+
+/**
+ * Get the number of entries listed in a treebuilder
+ *
+ * @param bld a previously loaded treebuilder.
+ * @return the number of entries in the treebuilder
+ */
+GIT_EXTERN(unsigned int) git_treebuilder_entrycount(git_treebuilder *bld);
+
+/**
+ * Free a tree builder
+ *
+ * This will clear all the entries and free to builder.
+ * Failing to free the builder after you're done using it
+ * will result in a memory leak
+ *
+ * @param bld Builder to free
+ */
+GIT_EXTERN(void) git_treebuilder_free(git_treebuilder *bld);
+
+/**
+ * Get an entry from the builder from its filename
+ *
+ * The returned entry is owned by the builder and should
+ * not be freed manually.
+ *
+ * @param bld Tree builder
+ * @param filename Name of the entry
+ * @return pointer to the entry; NULL if not found
+ */
+GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(
+	git_treebuilder *bld, const char *filename);
+
+/**
+ * Add or update an entry to the builder
+ *
+ * Insert a new entry for `filename` in the builder with the
+ * given attributes.
+ *
+ * If an entry named `filename` already exists, its attributes
+ * will be updated with the given ones.
+ *
+ * The optional pointer `out` can be used to retrieve a pointer to the
+ * newly created/updated entry.  Pass NULL if you do not need it. The
+ * pointer may not be valid past the next operation in this
+ * builder. Duplicate the entry if you want to keep it.
+ *
+ * No attempt is being made to ensure that the provided oid points
+ * to an existing git object in the object database, nor that the
+ * attributes make sense regarding the type of the pointed at object.
+ *
+ * @param out Pointer to store the entry (optional)
+ * @param bld Tree builder
+ * @param filename Filename of the entry
+ * @param id SHA1 oid of the entry
+ * @param filemode Folder attributes of the entry. This parameter must
+ *			be valued with one of the following entries: 0040000, 0100644,
+ *			0100755, 0120000 or 0160000.
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_treebuilder_insert(
+	const git_tree_entry **out,
+	git_treebuilder *bld,
+	const char *filename,
+	const git_oid *id,
+	git_filemode_t filemode);
+
+/**
+ * Remove an entry from the builder by its filename
+ *
+ * @param bld Tree builder
+ * @param filename Filename of the entry to remove
+ */
+GIT_EXTERN(int) git_treebuilder_remove(
+	git_treebuilder *bld, const char *filename);
+
+/**
+ * Callback for git_treebuilder_filter
+ *
+ * The return value is treated as a boolean, with zero indicating that the
+ * entry should be left alone and any non-zero value meaning that the
+ * entry should be removed from the treebuilder list (i.e. filtered out).
+ */
+typedef int (*git_treebuilder_filter_cb)(
+	const git_tree_entry *entry, void *payload);
+
+/**
+ * Selectively remove entries in the tree
+ *
+ * The `filter` callback will be called for each entry in the tree with a
+ * pointer to the entry and the provided `payload`; if the callback returns
+ * non-zero, the entry will be filtered (removed from the builder).
+ *
+ * @param bld Tree builder
+ * @param filter Callback to filter entries
+ * @param payload Extra data to pass to filter callback
+ */
+GIT_EXTERN(void) git_treebuilder_filter(
+	git_treebuilder *bld,
+	git_treebuilder_filter_cb filter,
+	void *payload);
+
+/**
+ * Write the contents of the tree builder as a tree object
+ *
+ * The tree builder will be written to the given `repo`, and its
+ * identifying SHA1 hash will be stored in the `id` pointer.
+ *
+ * @param id Pointer to store the OID of the newly written tree
+ * @param bld Tree builder to write
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_treebuilder_write(
+	git_oid *id, git_treebuilder *bld);
+
+
+/** Callback for the tree traversal method */
+typedef int (*git_treewalk_cb)(
+	const char *root, const git_tree_entry *entry, void *payload);
+
+/** Tree traversal modes */
+typedef enum {
+	GIT_TREEWALK_PRE = 0, /* Pre-order */
+	GIT_TREEWALK_POST = 1, /* Post-order */
+} git_treewalk_mode;
+
+/**
+ * Traverse the entries in a tree and its subtrees in post or pre order.
+ *
+ * The entries will be traversed in the specified order, children subtrees
+ * will be automatically loaded as required, and the `callback` will be
+ * called once per entry with the current (relative) root for the entry and
+ * the entry data itself.
+ *
+ * If the callback returns a positive value, the passed entry will be
+ * skipped on the traversal (in pre mode). A negative value stops the walk.
+ *
+ * @param tree The tree to walk
+ * @param mode Traversal mode (pre or post-order)
+ * @param callback Function to call on each tree entry
+ * @param payload Opaque pointer to be passed on each callback
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_tree_walk(
+	const git_tree *tree,
+	git_treewalk_mode mode,
+	git_treewalk_cb callback,
+	void *payload);
+
+/** @} */
+
+GIT_END_DECL
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/types.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/types.h
new file mode 100755
index 0000000..6f41014
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/types.h
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_types_h__
+#define INCLUDE_git_types_h__
+
+#include "common.h"
+
+/**
+ * @file git2/types.h
+ * @brief libgit2 base & compatibility types
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Cross-platform compatibility types for off_t / time_t
+ *
+ * NOTE: This needs to be in a public header so that both the library
+ * implementation and client applications both agree on the same types.
+ * Otherwise we get undefined behavior.
+ *
+ * Use the "best" types that each platform provides. Currently we truncate
+ * these intermediate representations for compatibility with the git ABI, but
+ * if and when it changes to support 64 bit types, our code will naturally
+ * adapt.
+ * NOTE: These types should match those that are returned by our internal
+ * stat() functions, for all platforms.
+ */
+#include <sys/types.h>
+#ifdef __amigaos4__
+#include <stdint.h>
+#endif
+
+#if defined(_MSC_VER)
+
+typedef __int64 git_off_t;
+typedef __time64_t git_time_t;
+
+#elif defined(__MINGW32__)
+
+typedef off64_t git_off_t;
+typedef __time64_t git_time_t;
+
+#elif defined(__HAIKU__)
+
+typedef __haiku_std_int64 git_off_t;
+typedef __haiku_std_int64 git_time_t;
+
+#else /* POSIX */
+
+/*
+ * Note: Can't use off_t since if a client program includes <sys/types.h>
+ * before us (directly or indirectly), they'll get 32 bit off_t in their client
+ * app, even though /we/ define _FILE_OFFSET_BITS=64.
+ */
+typedef int64_t git_off_t;
+typedef int64_t git_time_t;
+
+#endif
+
+/** Basic type (loose or packed) of any Git object. */
+typedef enum {
+	GIT_OBJ_ANY = -2,		/**< Object can be any of the following */
+	GIT_OBJ_BAD = -1,		/**< Object is invalid. */
+	GIT_OBJ__EXT1 = 0,		/**< Reserved for future use. */
+	GIT_OBJ_COMMIT = 1,		/**< A commit object. */
+	GIT_OBJ_TREE = 2,		/**< A tree (directory listing) object. */
+	GIT_OBJ_BLOB = 3,		/**< A file revision object. */
+	GIT_OBJ_TAG = 4,		/**< An annotated tag object. */
+	GIT_OBJ__EXT2 = 5,		/**< Reserved for future use. */
+	GIT_OBJ_OFS_DELTA = 6, /**< A delta, base is given by an offset. */
+	GIT_OBJ_REF_DELTA = 7, /**< A delta, base is given by object id. */
+} git_otype;
+
+/** An open object database handle. */
+typedef struct git_odb git_odb;
+
+/** A custom backend in an ODB */
+typedef struct git_odb_backend git_odb_backend;
+
+/** An object read from the ODB */
+typedef struct git_odb_object git_odb_object;
+
+/** A stream to read/write from the ODB */
+typedef struct git_odb_stream git_odb_stream;
+
+/** A stream to write a packfile to the ODB */
+typedef struct git_odb_writepack git_odb_writepack;
+
+/** An open refs database handle. */
+typedef struct git_refdb git_refdb;
+
+/** A custom backend for refs */
+typedef struct git_refdb_backend git_refdb_backend;
+
+/**
+ * Representation of an existing git repository,
+ * including all its object contents
+ */
+typedef struct git_repository git_repository;
+
+/** Representation of a generic object in a repository */
+typedef struct git_object git_object;
+
+/** Representation of an in-progress walk through the commits in a repo */
+typedef struct git_revwalk git_revwalk;
+
+/** Parsed representation of a tag object. */
+typedef struct git_tag git_tag;
+
+/** In-memory representation of a blob object. */
+typedef struct git_blob git_blob;
+
+/** Parsed representation of a commit object. */
+typedef struct git_commit git_commit;
+
+/** Representation of each one of the entries in a tree object. */
+typedef struct git_tree_entry git_tree_entry;
+
+/** Representation of a tree object. */
+typedef struct git_tree git_tree;
+
+/** Constructor for in-memory trees */
+typedef struct git_treebuilder git_treebuilder;
+
+/** Memory representation of an index file. */
+typedef struct git_index git_index;
+
+/** An iterator for conflicts in the index. */
+typedef struct git_index_conflict_iterator git_index_conflict_iterator;
+
+/** Memory representation of a set of config files */
+typedef struct git_config git_config;
+
+/** Interface to access a configuration file */
+typedef struct git_config_backend git_config_backend;
+
+/** Representation of a reference log entry */
+typedef struct git_reflog_entry git_reflog_entry;
+
+/** Representation of a reference log */
+typedef struct git_reflog git_reflog;
+
+/** Representation of a git note */
+typedef struct git_note git_note;
+
+/** Representation of a git packbuilder */
+typedef struct git_packbuilder git_packbuilder;
+
+/** Time in a signature */
+typedef struct git_time {
+	git_time_t time; /**< time in seconds from epoch */
+	int offset; /**< timezone offset, in minutes */
+} git_time;
+
+/** An action signature (e.g. for committers, taggers, etc) */
+typedef struct git_signature {
+	char *name; /**< full name of the author */
+	char *email; /**< email of the author */
+	git_time when; /**< time when the action happened */
+} git_signature;
+
+/** In-memory representation of a reference. */
+typedef struct git_reference git_reference;
+
+/** Iterator for references */
+typedef struct git_reference_iterator  git_reference_iterator;
+
+/** Transactional interface to references */
+typedef struct git_transaction git_transaction;
+
+/** Annotated commits, the input to merge and rebase. */
+typedef struct git_annotated_commit git_annotated_commit;
+
+/** Merge result */
+typedef struct git_merge_result git_merge_result;
+
+/** Representation of a status collection */
+typedef struct git_status_list git_status_list;
+
+/** Representation of a rebase */
+typedef struct git_rebase git_rebase;
+
+/** Basic type of any Git reference. */
+typedef enum {
+	GIT_REF_INVALID = 0, /**< Invalid reference */
+	GIT_REF_OID = 1, /**< A reference which points at an object id */
+	GIT_REF_SYMBOLIC = 2, /**< A reference which points at another reference */
+	GIT_REF_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC,
+} git_ref_t;
+
+/** Basic type of any Git branch. */
+typedef enum {
+	GIT_BRANCH_LOCAL = 1,
+	GIT_BRANCH_REMOTE = 2,
+	GIT_BRANCH_ALL = GIT_BRANCH_LOCAL|GIT_BRANCH_REMOTE,
+} git_branch_t;
+
+/** Valid modes for index and tree entries. */
+typedef enum {
+	GIT_FILEMODE_UNREADABLE          = 0000000,
+	GIT_FILEMODE_TREE                = 0040000,
+	GIT_FILEMODE_BLOB                = 0100644,
+	GIT_FILEMODE_BLOB_EXECUTABLE     = 0100755,
+	GIT_FILEMODE_LINK                = 0120000,
+	GIT_FILEMODE_COMMIT              = 0160000,
+} git_filemode_t;
+
+/*
+ * A refspec specifies the mapping between remote and local reference
+ * names when fetch or pushing.
+ */
+typedef struct git_refspec git_refspec;
+
+/**
+ * Git's idea of a remote repository. A remote can be anonymous (in
+ * which case it does not have backing configuration entires).
+ */
+typedef struct git_remote git_remote;
+
+/**
+ * Interface which represents a transport to communicate with a
+ * remote.
+ */
+typedef struct git_transport git_transport;
+
+/**
+ * Preparation for a push operation. Can be used to configure what to
+ * push and the level of parallelism of the packfile builder.
+ */
+typedef struct git_push git_push;
+
+/* documentation in the definition */
+typedef struct git_remote_head git_remote_head;
+typedef struct git_remote_callbacks git_remote_callbacks;
+
+/**
+ * This is passed as the first argument to the callback to allow the
+ * user to see the progress.
+ *
+ * - total_objects: number of objects in the packfile being downloaded
+ * - indexed_objects: received objects that have been hashed
+ * - received_objects: objects which have been downloaded
+ * - local_objects: locally-available objects that have been injected
+ *    in order to fix a thin pack.
+ * - received-bytes: size of the packfile received up to now
+ */
+typedef struct git_transfer_progress {
+	unsigned int total_objects;
+	unsigned int indexed_objects;
+	unsigned int received_objects;
+	unsigned int local_objects;
+	unsigned int total_deltas;
+	unsigned int indexed_deltas;
+	size_t received_bytes;
+} git_transfer_progress;
+
+/**
+ * Type for progress callbacks during indexing.  Return a value less than zero
+ * to cancel the transfer.
+ *
+ * @param stats Structure containing information about the state of the transfer
+ * @param payload Payload provided by caller
+ */
+typedef int (*git_transfer_progress_cb)(const git_transfer_progress *stats, void *payload);
+
+/**
+ * Type for messages delivered by the transport.  Return a negative value
+ * to cancel the network operation.
+ *
+ * @param str The message from the transport
+ * @param len The length of the message
+ * @param payload Payload provided by the caller
+ */
+typedef int (*git_transport_message_cb)(const char *str, int len, void *payload);
+
+
+/**
+ * Type of host certificate structure that is passed to the check callback
+ */
+typedef enum git_cert_t {
+	/**
+	 * No information about the certificate is available. This may
+	 * happen when using curl.
+	 */
+	GIT_CERT_NONE,
+        /**
+         * The `data` argument to the callback will be a pointer to
+         * the DER-encoded data.
+         */
+	GIT_CERT_X509,
+        /**
+         * The `data` argument to the callback will be a pointer to a
+         * `git_cert_hostkey` structure.
+         */
+	GIT_CERT_HOSTKEY_LIBSSH2,
+	/**
+	 * The `data` argument to the callback will be a pointer to a
+	 * `git_strarray` with `name:content` strings containing
+	 * information about the certificate. This is used when using
+	 * curl.
+	 */
+	GIT_CERT_STRARRAY,
+} git_cert_t;
+
+/**
+ * Parent type for `git_cert_hostkey` and `git_cert_x509`.
+ */
+typedef struct {
+	/**
+	 * Type of certificate. A `GIT_CERT_` value.
+	 */
+	git_cert_t cert_type;
+} git_cert;
+
+/**
+ * Callback for the user's custom certificate checks.
+ *
+ * @param cert The host certificate
+ * @param valid Whether the libgit2 checks (OpenSSL or WinHTTP) think
+ * this certificate is valid
+ * @param host Hostname of the host libgit2 connected to
+ * @param payload Payload provided by the caller
+ */
+typedef int (*git_transport_certificate_check_cb)(git_cert *cert, int valid, const char *host, void *payload);
+
+/**
+ * Opaque structure representing a submodule.
+ */
+typedef struct git_submodule git_submodule;
+
+/**
+ * Submodule update values
+ *
+ * These values represent settings for the `submodule.$name.update`
+ * configuration value which says how to handle `git submodule update` for
+ * this submodule.  The value is usually set in the ".gitmodules" file and
+ * copied to ".git/config" when the submodule is initialized.
+ *
+ * You can override this setting on a per-submodule basis with
+ * `git_submodule_set_update()` and write the changed value to disk using
+ * `git_submodule_save()`.  If you have overwritten the value, you can
+ * revert it by passing `GIT_SUBMODULE_UPDATE_RESET` to the set function.
+ *
+ * The values are:
+ *
+ * - GIT_SUBMODULE_UPDATE_CHECKOUT: the default; when a submodule is
+ *   updated, checkout the new detached HEAD to the submodule directory.
+ * - GIT_SUBMODULE_UPDATE_REBASE: update by rebasing the current checked
+ *   out branch onto the commit from the superproject.
+ * - GIT_SUBMODULE_UPDATE_MERGE: update by merging the commit in the
+ *   superproject into the current checkout out branch of the submodule.
+ * - GIT_SUBMODULE_UPDATE_NONE: do not update this submodule even when
+ *   the commit in the superproject is updated.
+ * - GIT_SUBMODULE_UPDATE_DEFAULT: not used except as static initializer
+ *   when we don't want any particular update rule to be specified.
+ */
+typedef enum {
+	GIT_SUBMODULE_UPDATE_CHECKOUT = 1,
+	GIT_SUBMODULE_UPDATE_REBASE   = 2,
+	GIT_SUBMODULE_UPDATE_MERGE    = 3,
+	GIT_SUBMODULE_UPDATE_NONE     = 4,
+
+	GIT_SUBMODULE_UPDATE_DEFAULT  = 0
+} git_submodule_update_t;
+
+/**
+ * Submodule ignore values
+ *
+ * These values represent settings for the `submodule.$name.ignore`
+ * configuration value which says how deeply to look at the working
+ * directory when getting submodule status.
+ *
+ * You can override this value in memory on a per-submodule basis with
+ * `git_submodule_set_ignore()` and can write the changed value to disk
+ * with `git_submodule_save()`.  If you have overwritten the value, you
+ * can revert to the on disk value by using `GIT_SUBMODULE_IGNORE_RESET`.
+ *
+ * The values are:
+ *
+ * - GIT_SUBMODULE_IGNORE_UNSPECIFIED: use the submodule's configuration
+ * - GIT_SUBMODULE_IGNORE_NONE: don't ignore any change - i.e. even an
+ *   untracked file, will mark the submodule as dirty.  Ignored files are
+ *   still ignored, of course.
+ * - GIT_SUBMODULE_IGNORE_UNTRACKED: ignore untracked files; only changes
+ *   to tracked files, or the index or the HEAD commit will matter.
+ * - GIT_SUBMODULE_IGNORE_DIRTY: ignore changes in the working directory,
+ *   only considering changes if the HEAD of submodule has moved from the
+ *   value in the superproject.
+ * - GIT_SUBMODULE_IGNORE_ALL: never check if the submodule is dirty
+ * - GIT_SUBMODULE_IGNORE_DEFAULT: not used except as static initializer
+ *   when we don't want any particular ignore rule to be specified.
+ */
+typedef enum {
+	GIT_SUBMODULE_IGNORE_UNSPECIFIED  = -1, /**< use the submodule's configuration */
+
+	GIT_SUBMODULE_IGNORE_NONE      = 1,  /**< any change or untracked == dirty */
+	GIT_SUBMODULE_IGNORE_UNTRACKED = 2,  /**< dirty if tracked files change */
+	GIT_SUBMODULE_IGNORE_DIRTY     = 3,  /**< only dirty if HEAD moved */
+	GIT_SUBMODULE_IGNORE_ALL       = 4,  /**< never dirty */
+} git_submodule_ignore_t;
+
+/**
+ * Options for submodule recurse.
+ *
+ * Represent the value of `submodule.$name.fetchRecurseSubmodules`
+ *
+ * * GIT_SUBMODULE_RECURSE_NO    - do no recurse into submodules
+ * * GIT_SUBMODULE_RECURSE_YES   - recurse into submodules
+ * * GIT_SUBMODULE_RECURSE_ONDEMAND - recurse into submodules only when
+ *                                    commit not already in local clone
+ */
+typedef enum {
+	GIT_SUBMODULE_RECURSE_NO = 0,
+	GIT_SUBMODULE_RECURSE_YES = 1,
+	GIT_SUBMODULE_RECURSE_ONDEMAND = 2,
+} git_submodule_recurse_t;
+
+/** A type to write in a streaming fashion, for example, for filters. */
+typedef struct git_writestream git_writestream;
+
+struct git_writestream {
+	int (*write)(git_writestream *stream, const char *buffer, size_t len);
+	int (*close)(git_writestream *stream);
+	void (*free)(git_writestream *stream);
+};
+
+/** @} */
+GIT_END_DECL
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/version.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/version.h
new file mode 100755
index 0000000..1c64bfd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/include/git2/version.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_version_h__
+#define INCLUDE_git_version_h__
+
+#define LIBGIT2_VERSION "0.23.3"
+#define LIBGIT2_VER_MAJOR 0
+#define LIBGIT2_VER_MINOR 23
+#define LIBGIT2_VER_REVISION 3
+#define LIBGIT2_VER_PATCH 0
+
+#define LIBGIT2_SOVERSION 23
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/libgit2.pc.in b/app/server/vendor/rugged-0.23.3/vendor/libgit2/libgit2.pc.in
new file mode 100755
index 0000000..3d825a4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/libgit2.pc.in
@@ -0,0 +1,12 @@
+libdir=@CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_DIR@
+includedir=@CMAKE_INSTALL_PREFIX@/@INCLUDE_INSTALL_DIR@
+
+Name: libgit2
+Description: The git library, take 2
+Version: @LIBGIT2_VERSION_STRING@
+
+Libs: -L${libdir} -lgit2
+Libs.private: @LIBGIT2_PC_LIBS@
+Requires.private: @LIBGIT2_PC_REQUIRES@
+
+Cflags: -I${includedir}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/libgit2_clar.supp b/app/server/vendor/rugged-0.23.3/vendor/libgit2/libgit2_clar.supp
new file mode 100755
index 0000000..bd22ada
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/libgit2_clar.supp
@@ -0,0 +1,49 @@
+{
+	ignore-zlib-errors-cond
+	Memcheck:Cond
+	obj:*libz.so*
+}
+
+{
+	ignore-giterr-set-leak
+	Memcheck:Leak
+	...
+	fun:giterr_set
+}
+
+{
+	ignore-git-global-state-leak
+	Memcheck:Leak
+	...
+	fun:git__global_state
+}
+
+{
+	ignore-openssl-ssl-leak
+	Memcheck:Leak
+	...
+	obj:*libssl.so*
+	...
+}
+
+{
+	ignore-openssl-crypto-leak
+	Memcheck:Leak
+	...
+	obj:*libcrypto.so*
+	...
+}
+
+{
+	ignore-openssl-crypto-cond
+	Memcheck:Cond
+	obj:*libcrypto.so*
+	...
+}
+
+{
+	ignore-glibc-getaddrinfo-cache
+	Memcheck:Leak
+	...
+	fun:__check_pf
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/script/appveyor-mingw.sh b/app/server/vendor/rugged-0.23.3/vendor/libgit2/script/appveyor-mingw.sh
new file mode 100755
index 0000000..48e0bad
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/script/appveyor-mingw.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+set -e
+cd `dirname "$0"`/..
+if [ "$ARCH" = "32" ]; then
+  echo 'C:\MinGW\ /MinGW' > /etc/fstab
+elif [ "$ARCH" = "i686" ]; then
+  f=i686-4.9.2-release-win32-sjlj-rt_v3-rev1.7z
+  if ! [ -e $f ]; then
+    curl -LsSO http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.2/threads-win32/sjlj/$f
+  fi
+  7z x $f > /dev/null
+  mv mingw32 /MinGW
+else
+  f=x86_64-4.9.2-release-win32-seh-rt_v3-rev1.7z
+  if ! [ -e $f ]; then
+    curl -LsSO http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.2/threads-win32/seh/$f
+  fi
+  7z x $f > /dev/null
+  mv mingw64 /MinGW
+fi
+cd build
+cmake -D ENABLE_TRACE=ON -D BUILD_CLAR=ON .. -G"$GENERATOR"
+cmake --build . --config RelWithDebInfo
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/script/cibuild.sh b/app/server/vendor/rugged-0.23.3/vendor/libgit2/script/cibuild.sh
new file mode 100755
index 0000000..de5df9e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/script/cibuild.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+if [ -n "$COVERITY" ];
+then
+	./script/coverity.sh;
+	exit $?;
+fi
+
+mkdir _build
+cd _build
+# shellcheck disable=SC2086
+cmake .. -DCMAKE_INSTALL_PREFIX=../_install $OPTIONS || exit $?
+make -j2 install || exit $?
+
+# If this platform doesn't support test execution, bail out now
+if [ -n "$SKIP_TESTS" ];
+then
+	exit $?;
+fi
+
+# Create a test repo which we can use for the online::push tests
+mkdir "$HOME"/_temp
+git init --bare "$HOME"/_temp/test.git
+git daemon --listen=localhost --export-all --enable=receive-pack --base-path="$HOME"/_temp "$HOME"/_temp 2>/dev/null &
+export GITTEST_REMOTE_URL="git://localhost/test.git"
+
+# Run the test suite
+ctest -V . || exit $?
+
+# Now that we've tested the raw git protocol, let's set up ssh to we
+# can do the push tests over it
+
+killall git-daemon
+
+if [ "$TRAVIS_OS_NAME" = "osx" ]; then
+    echo 'PasswordAuthentication yes' | sudo tee -a /etc/sshd_config
+fi
+
+ssh-keygen -t rsa -f ~/.ssh/id_rsa -N "" -q
+cat ~/.ssh/id_rsa.pub >>~/.ssh/authorized_keys
+ssh-keyscan -t rsa localhost >>~/.ssh/known_hosts
+
+# Get the fingerprint for localhost and remove the colons so we can parse it as a hex number
+export GITTEST_REMOTE_SSH_FINGERPRINT=$(ssh-keygen -F localhost -l | tail -n 1 | cut -d ' ' -f 2 | tr -d ':')
+
+export GITTEST_REMOTE_URL="ssh://localhost/$HOME/_temp/test.git"
+export GITTEST_REMOTE_USER=$USER
+export GITTEST_REMOTE_SSH_KEY="$HOME/.ssh/id_rsa"
+export GITTEST_REMOTE_SSH_PUBKEY="$HOME/.ssh/id_rsa.pub"
+export GITTEST_REMOTE_SSH_PASSPHRASE=""
+
+if [ -e ./libgit2_clar ]; then
+    ./libgit2_clar -sonline::push -sonline::clone::ssh_cert &&
+    ./libgit2_clar -sonline::clone::ssh_with_paths || exit $?
+    if [ "$TRAVIS_OS_NAME" = "linux" ]; then
+        ./libgit2_clar -sonline::clone::cred_callback || exit $?
+    fi
+fi
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/script/coverity.sh b/app/server/vendor/rugged-0.23.3/vendor/libgit2/script/coverity.sh
new file mode 100755
index 0000000..dcfeffc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/script/coverity.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+set -e
+
+# Environment check
+[ -z "$COVERITY_TOKEN" ] && echo "Need to set a coverity token" && exit 1
+
+# Only run this on our branches
+echo "Pull request: $TRAVIS_PULL_REQUEST  |  Slug: $TRAVIS_REPO_SLUG"
+if [ "$TRAVIS_PULL_REQUEST" != "false" -o "$TRAVIS_REPO_SLUG" != "libgit2/libgit2" ];
+then
+	echo "Only analyzing 'development' on the main repo."
+	exit 0
+fi
+
+COV_VERSION=6.6.1
+case $(uname -m) in
+	i?86)				BITS=32 ;;
+	amd64|x86_64)	BITS=64 ;;
+esac
+SCAN_TOOL=https://scan.coverity.com/download/linux-${BITS}
+TOOL_BASE=$(pwd)/_coverity-scan
+
+# Install coverity tools
+if [ ! -d "$TOOL_BASE" ]; then
+	echo "Downloading coverity..."
+	mkdir -p "$TOOL_BASE"
+	pushd "$TOOL_BASE"
+	wget -O coverity_tool.tgz $SCAN_TOOL \
+		--post-data "project=libgit2&token=$COVERITY_TOKEN"
+	tar xzf coverity_tool.tgz
+	popd
+	TOOL_DIR=$(find "$TOOL_BASE" -type d -name 'cov-analysis*')
+	ln -s "$TOOL_DIR" "$TOOL_BASE"/cov-analysis
+fi
+
+COV_BUILD="$TOOL_BASE/cov-analysis/bin/cov-build"
+
+# Configure and build
+rm -rf _build
+mkdir _build
+cd _build
+cmake .. -DTHREADSAFE=ON
+COVERITY_UNSUPPORTED=1 \
+	$COV_BUILD --dir cov-int \
+	cmake --build .
+
+# Upload results
+tar czf libgit2.tgz cov-int
+SHA=$(git rev-parse --short HEAD)
+curl \
+	--form project=libgit2 \
+	--form token="$COVERITY_TOKEN" \
+	--form email=bs at github.com \
+	--form file=@libgit2.tgz \
+	--form version="$SHA" \
+	--form description="Travis build" \
+	http://scan5.coverity.com/cgi-bin/upload.py
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/script/install-deps-osx.sh b/app/server/vendor/rugged-0.23.3/vendor/libgit2/script/install-deps-osx.sh
new file mode 100755
index 0000000..c2e0162
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/script/install-deps-osx.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+set -x
+
+brew install libssh2 cmake
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/script/toolchain-mingw32.cmake b/app/server/vendor/rugged-0.23.3/vendor/libgit2/script/toolchain-mingw32.cmake
new file mode 100755
index 0000000..2536b01
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/script/toolchain-mingw32.cmake
@@ -0,0 +1,13 @@
+# CMake toolchain file for Win32 cross-compile
+SET(CMAKE_SYSTEM_NAME Windows)
+
+SET(CMAKE_C_COMPILER i586-mingw32msvc-gcc)
+SET(CMAKE_RC_COMPILER i586-mingw32msvc-windres)
+
+SET(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc)
+
+SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+SET(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_FIND_ROOT_PATH}/lib/pkgconfig)
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/annotated_commit.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/annotated_commit.c
new file mode 100755
index 0000000..3f2d2ed
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/annotated_commit.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "annotated_commit.h"
+
+#include "git2/commit.h"
+#include "git2/refs.h"
+#include "git2/repository.h"
+#include "git2/annotated_commit.h"
+#include "git2/revparse.h"
+
+static int annotated_commit_init(
+	git_annotated_commit **out,
+	git_repository *repo,
+	const git_oid *id,
+	const char *ref_name,
+	const char *remote_url)
+{
+	git_annotated_commit *annotated_commit;
+	int error = 0;
+
+	assert(out && id);
+
+	*out = NULL;
+
+	annotated_commit = git__calloc(1, sizeof(git_annotated_commit));
+	GITERR_CHECK_ALLOC(annotated_commit);
+
+	if (ref_name) {
+		annotated_commit->ref_name = git__strdup(ref_name);
+		GITERR_CHECK_ALLOC(annotated_commit->ref_name);
+	}
+
+	if (remote_url) {
+		annotated_commit->remote_url = git__strdup(remote_url);
+		GITERR_CHECK_ALLOC(annotated_commit->remote_url);
+	}
+
+	git_oid_fmt(annotated_commit->id_str, id);
+	annotated_commit->id_str[GIT_OID_HEXSZ] = '\0';
+
+	if ((error = git_commit_lookup(&annotated_commit->commit, repo, id)) < 0) {
+		git_annotated_commit_free(annotated_commit);
+		return error;
+	}
+
+	*out = annotated_commit;
+	return error;
+}
+
+int git_annotated_commit_from_ref(
+	git_annotated_commit **out,
+	git_repository *repo,
+	const git_reference *ref)
+{
+	git_reference *resolved;
+	int error = 0;
+
+	assert(out && repo && ref);
+
+	*out = NULL;
+
+	if ((error = git_reference_resolve(&resolved, ref)) < 0)
+		return error;
+	
+	error = annotated_commit_init(out, repo, git_reference_target(resolved),
+		git_reference_name(ref), NULL);
+
+	git_reference_free(resolved);
+	return error;
+}
+
+int git_annotated_commit_lookup(
+	git_annotated_commit **out,
+	git_repository *repo,
+	const git_oid *id)
+{
+	assert(out && repo && id);
+
+	return annotated_commit_init(out, repo, id, NULL, NULL);
+}
+
+int git_annotated_commit_from_fetchhead(
+	git_annotated_commit **out,
+	git_repository *repo,
+	const char *branch_name,
+	const char *remote_url,
+	const git_oid *id)
+{
+	assert(repo && id && branch_name && remote_url);
+
+	return annotated_commit_init(out, repo, id, branch_name, remote_url);
+}
+
+int git_annotated_commit_from_revspec(
+	git_annotated_commit **out,
+	git_repository *repo,
+	const char *revspec)
+{
+	git_object *obj, *commit;
+	int error;
+
+	assert(out && repo && revspec);
+
+	if ((error = git_revparse_single(&obj, repo, revspec)) < 0)
+		return error;
+
+	if ((error = git_object_peel(&commit, obj, GIT_OBJ_COMMIT))) {
+		git_object_free(obj);
+		return error;
+	}
+
+	error = annotated_commit_init(out, repo, git_object_id(commit), revspec, NULL);
+
+	git_object_free(obj);
+	git_object_free(commit);
+
+	return error;
+}
+
+
+const git_oid *git_annotated_commit_id(
+	const git_annotated_commit *annotated_commit)
+{
+	assert(annotated_commit);
+	return git_commit_id(annotated_commit->commit);
+}
+
+void git_annotated_commit_free(git_annotated_commit *annotated_commit)
+{
+	if (annotated_commit == NULL)
+		return;
+
+	if (annotated_commit->commit != NULL)
+		git_commit_free(annotated_commit->commit);
+
+	if (annotated_commit->ref_name != NULL)
+		git__free(annotated_commit->ref_name);
+
+	if (annotated_commit->remote_url != NULL)
+		git__free(annotated_commit->remote_url);
+
+	git__free(annotated_commit);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/annotated_commit.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/annotated_commit.h
new file mode 100755
index 0000000..e873184
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/annotated_commit.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_annotated_commit_h__
+#define INCLUDE_annotated_commit_h__
+
+#include "git2/oid.h"
+
+/** Internal structure for merge inputs */
+struct git_annotated_commit {
+	git_commit *commit;
+
+	char *ref_name;
+	char *remote_url;
+
+	char id_str[GIT_OID_HEXSZ+1];
+};
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/array.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/array.h
new file mode 100755
index 0000000..7cd9b71
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/array.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_array_h__
+#define INCLUDE_array_h__
+
+#include "common.h"
+
+/*
+ * Use this to declare a typesafe resizable array of items, a la:
+ *
+ *     git_array_t(int) my_ints = GIT_ARRAY_INIT;
+ *     ...
+ *     int *i = git_array_alloc(my_ints);
+ *     GITERR_CHECK_ALLOC(i);
+ *     ...
+ *     git_array_clear(my_ints);
+ *
+ * You may also want to do things like:
+ *
+ *     typedef git_array_t(my_struct) my_struct_array_t;
+ */
+#define git_array_t(type) struct { type *ptr; size_t size, asize; }
+
+#define GIT_ARRAY_INIT { NULL, 0, 0 }
+
+#define git_array_init(a) \
+	do { (a).size = (a).asize = 0; (a).ptr = NULL; } while (0)
+
+#define git_array_init_to_size(a, desired) \
+	do { (a).size = 0; (a).asize = desired; (a).ptr = git__calloc(desired, sizeof(*(a).ptr)); } while (0)
+
+#define git_array_clear(a) \
+	do { git__free((a).ptr); git_array_init(a); } while (0)
+
+#define GITERR_CHECK_ARRAY(a) GITERR_CHECK_ALLOC((a).ptr)
+
+
+typedef git_array_t(char) git_array_generic_t;
+
+/* use a generic array for growth so this can return the new item */
+GIT_INLINE(void *) git_array_grow(void *_a, size_t item_size)
+{
+	volatile git_array_generic_t *a = _a;
+	size_t new_size;
+	char *new_array;
+
+	if (a->size < 8) {
+		new_size = 8;
+	} else {
+		if (GIT_MULTIPLY_SIZET_OVERFLOW(&new_size, a->size, 3))
+			goto on_oom;
+		new_size /= 2;
+	}
+
+	if ((new_array = git__reallocarray(a->ptr, new_size, item_size)) == NULL)
+		goto on_oom;
+
+	a->ptr = new_array; a->asize = new_size; a->size++;
+	return a->ptr + (a->size - 1) * item_size;
+
+on_oom:
+	git_array_clear(*a);
+	return NULL;
+}
+
+#define git_array_alloc(a) \
+	(((a).size >= (a).asize) ? \
+	git_array_grow(&(a), sizeof(*(a).ptr)) : \
+	((a).ptr ? &(a).ptr[(a).size++] : NULL))
+
+#define git_array_last(a) ((a).size ? &(a).ptr[(a).size - 1] : NULL)
+
+#define git_array_pop(a) ((a).size ? &(a).ptr[--(a).size] : NULL)
+
+#define git_array_get(a, i) (((i) < (a).size) ? &(a).ptr[(i)] : NULL)
+
+#define git_array_size(a) (a).size
+
+#define git_array_valid_index(a, i) ((i) < (a).size)
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attr.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attr.c
new file mode 100755
index 0000000..d43a15f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attr.c
@@ -0,0 +1,544 @@
+#include "common.h"
+#include "repository.h"
+#include "sysdir.h"
+#include "config.h"
+#include "attr_file.h"
+#include "ignore.h"
+#include "git2/oid.h"
+#include <ctype.h>
+
+GIT__USE_STRMAP
+
+const char *git_attr__true  = "[internal]__TRUE__";
+const char *git_attr__false = "[internal]__FALSE__";
+const char *git_attr__unset = "[internal]__UNSET__";
+
+git_attr_t git_attr_value(const char *attr)
+{
+	if (attr == NULL || attr == git_attr__unset)
+		return GIT_ATTR_UNSPECIFIED_T;
+
+	if (attr == git_attr__true)
+		return GIT_ATTR_TRUE_T;
+
+	if (attr == git_attr__false)
+		return GIT_ATTR_FALSE_T;
+
+	return GIT_ATTR_VALUE_T;
+}
+
+static int collect_attr_files(
+	git_repository *repo,
+	git_attr_session *attr_session,
+	uint32_t flags,
+	const char *path,
+	git_vector *files);
+
+static void release_attr_files(git_vector *files);
+
+int git_attr_get(
+	const char **value,
+	git_repository *repo,
+	uint32_t flags,
+	const char *pathname,
+	const char *name)
+{
+	int error;
+	git_attr_path path;
+	git_vector files = GIT_VECTOR_INIT;
+	size_t i, j;
+	git_attr_file *file;
+	git_attr_name attr;
+	git_attr_rule *rule;
+
+	assert(value && repo && name);
+
+	*value = NULL;
+
+	if (git_attr_path__init(&path, pathname, git_repository_workdir(repo), GIT_DIR_FLAG_UNKNOWN) < 0)
+		return -1;
+
+	if ((error = collect_attr_files(repo, NULL, flags, pathname, &files)) < 0)
+		goto cleanup;
+
+	memset(&attr, 0, sizeof(attr));
+	attr.name = name;
+	attr.name_hash = git_attr_file__name_hash(name);
+
+	git_vector_foreach(&files, i, file) {
+
+		git_attr_file__foreach_matching_rule(file, &path, j, rule) {
+			size_t pos;
+
+			if (!git_vector_bsearch(&pos, &rule->assigns, &attr)) {
+				*value = ((git_attr_assignment *)git_vector_get(
+							  &rule->assigns, pos))->value;
+				goto cleanup;
+			}
+		}
+	}
+
+cleanup:
+	release_attr_files(&files);
+	git_attr_path__free(&path);
+
+	return error;
+}
+
+
+typedef struct {
+	git_attr_name name;
+	git_attr_assignment *found;
+} attr_get_many_info;
+
+int git_attr_get_many_with_session(
+	const char **values,
+	git_repository *repo,
+	git_attr_session *attr_session,
+	uint32_t flags,
+	const char *pathname,
+	size_t num_attr,
+	const char **names)
+{
+	int error;
+	git_attr_path path;
+	git_vector files = GIT_VECTOR_INIT;
+	size_t i, j, k;
+	git_attr_file *file;
+	git_attr_rule *rule;
+	attr_get_many_info *info = NULL;
+	size_t num_found = 0;
+
+	if (!num_attr)
+		return 0;
+
+	assert(values && repo && names);
+
+	if (git_attr_path__init(&path, pathname, git_repository_workdir(repo), GIT_DIR_FLAG_UNKNOWN) < 0)
+		return -1;
+
+	if ((error = collect_attr_files(repo, attr_session, flags, pathname, &files)) < 0)
+		goto cleanup;
+
+	info = git__calloc(num_attr, sizeof(attr_get_many_info));
+	GITERR_CHECK_ALLOC(info);
+
+	git_vector_foreach(&files, i, file) {
+
+		git_attr_file__foreach_matching_rule(file, &path, j, rule) {
+
+			for (k = 0; k < num_attr; k++) {
+				size_t pos;
+
+				if (info[k].found != NULL) /* already found assignment */
+					continue;
+
+				if (!info[k].name.name) {
+					info[k].name.name = names[k];
+					info[k].name.name_hash = git_attr_file__name_hash(names[k]);
+				}
+
+				if (!git_vector_bsearch(&pos, &rule->assigns, &info[k].name)) {
+					info[k].found = (git_attr_assignment *)
+						git_vector_get(&rule->assigns, pos);
+					values[k] = info[k].found->value;
+
+					if (++num_found == num_attr)
+						goto cleanup;
+				}
+			}
+		}
+	}
+
+	for (k = 0; k < num_attr; k++) {
+		if (!info[k].found)
+			values[k] = NULL;
+	}
+
+cleanup:
+	release_attr_files(&files);
+	git_attr_path__free(&path);
+	git__free(info);
+
+	return error;
+}
+
+int git_attr_get_many(
+	const char **values,
+	git_repository *repo,
+	uint32_t flags,
+	const char *pathname,
+	size_t num_attr,
+	const char **names)
+{
+	return git_attr_get_many_with_session(
+		values, repo, NULL, flags, pathname, num_attr, names);
+}
+
+int git_attr_foreach(
+	git_repository *repo,
+	uint32_t flags,
+	const char *pathname,
+	int (*callback)(const char *name, const char *value, void *payload),
+	void *payload)
+{
+	int error;
+	git_attr_path path;
+	git_vector files = GIT_VECTOR_INIT;
+	size_t i, j, k;
+	git_attr_file *file;
+	git_attr_rule *rule;
+	git_attr_assignment *assign;
+	git_strmap *seen = NULL;
+
+	assert(repo && callback);
+
+	if (git_attr_path__init(&path, pathname, git_repository_workdir(repo), GIT_DIR_FLAG_UNKNOWN) < 0)
+		return -1;
+
+	if ((error = collect_attr_files(repo, NULL, flags, pathname, &files)) < 0 ||
+		(error = git_strmap_alloc(&seen)) < 0)
+		goto cleanup;
+
+	git_vector_foreach(&files, i, file) {
+
+		git_attr_file__foreach_matching_rule(file, &path, j, rule) {
+
+			git_vector_foreach(&rule->assigns, k, assign) {
+				/* skip if higher priority assignment was already seen */
+				if (git_strmap_exists(seen, assign->name))
+					continue;
+
+				git_strmap_insert(seen, assign->name, assign, error);
+				if (error < 0)
+					goto cleanup;
+
+				error = callback(assign->name, assign->value, payload);
+				if (error) {
+					giterr_set_after_callback(error);
+					goto cleanup;
+				}
+			}
+		}
+	}
+
+cleanup:
+	git_strmap_free(seen);
+	release_attr_files(&files);
+	git_attr_path__free(&path);
+
+	return error;
+}
+
+static int preload_attr_file(
+	git_repository *repo,
+	git_attr_session *attr_session,
+	git_attr_file_source source,
+	const char *base,
+	const char *file)
+{
+	int error;
+	git_attr_file *preload = NULL;
+
+	if (!file)
+		return 0;
+	if (!(error = git_attr_cache__get(
+			&preload, repo, attr_session, source, base, file, git_attr_file__parse_buffer)))
+		git_attr_file__free(preload);
+
+	return error;
+}
+
+static int system_attr_file(
+	git_buf *out,
+	git_attr_session *attr_session)
+{
+	int error;
+
+	if (!attr_session) {
+		error = git_sysdir_find_system_file(out, GIT_ATTR_FILE_SYSTEM);
+
+		if (error == GIT_ENOTFOUND)
+			giterr_clear();
+
+		return error;
+	}
+
+	if (!attr_session->init_sysdir) {
+		error = git_sysdir_find_system_file(&attr_session->sysdir, GIT_ATTR_FILE_SYSTEM);
+
+		if (error == GIT_ENOTFOUND)
+			giterr_clear();
+		else if (error)
+			return error;
+
+		attr_session->init_sysdir = 1;
+	}
+
+	if (attr_session->sysdir.size == 0)
+		return GIT_ENOTFOUND;
+
+	/* We can safely provide a git_buf with no allocation (asize == 0) to
+	 * a consumer. This allows them to treat this as a regular `git_buf`,
+	 * but their call to `git_buf_free` will not attempt to free it.
+	 */
+	git_buf_attach_notowned(
+		out, attr_session->sysdir.ptr, attr_session->sysdir.size);
+	return 0;
+}
+
+static int attr_setup(git_repository *repo, git_attr_session *attr_session)
+{
+	int error = 0;
+	const char *workdir = git_repository_workdir(repo);
+	git_index *idx = NULL;
+	git_buf sys = GIT_BUF_INIT;
+
+	if (attr_session && attr_session->init_setup)
+		return 0;
+
+	if ((error = git_attr_cache__init(repo)) < 0)
+		return error;
+
+	/* preload attribute files that could contain macros so the
+	 * definitions will be available for later file parsing
+	 */
+
+	error = system_attr_file(&sys, attr_session);
+
+	if (error == 0)
+		error = preload_attr_file(
+			repo, attr_session, GIT_ATTR_FILE__FROM_FILE, NULL, sys.ptr);
+
+	if (error != GIT_ENOTFOUND)
+		return error;
+
+	git_buf_free(&sys);
+
+	if ((error = preload_attr_file(
+			repo, attr_session, GIT_ATTR_FILE__FROM_FILE,
+			NULL, git_repository_attr_cache(repo)->cfg_attr_file)) < 0)
+		return error;
+
+	if ((error = preload_attr_file(
+			repo, attr_session, GIT_ATTR_FILE__FROM_FILE,
+			git_repository_path(repo), GIT_ATTR_FILE_INREPO)) < 0)
+		return error;
+
+	if (workdir != NULL &&
+		(error = preload_attr_file(
+			repo, attr_session, GIT_ATTR_FILE__FROM_FILE, workdir, GIT_ATTR_FILE)) < 0)
+		return error;
+
+	if ((error = git_repository_index__weakptr(&idx, repo)) < 0 ||
+		(error = preload_attr_file(
+			repo, attr_session, GIT_ATTR_FILE__FROM_INDEX, NULL, GIT_ATTR_FILE)) < 0)
+		return error;
+
+	if (attr_session)
+		attr_session->init_setup = 1;
+
+	return error;
+}
+
+int git_attr_add_macro(
+	git_repository *repo,
+	const char *name,
+	const char *values)
+{
+	int error;
+	git_attr_rule *macro = NULL;
+	git_pool *pool;
+
+	if ((error = git_attr_cache__init(repo)) < 0)
+		return error;
+
+	macro = git__calloc(1, sizeof(git_attr_rule));
+	GITERR_CHECK_ALLOC(macro);
+
+	pool = &git_repository_attr_cache(repo)->pool;
+
+	macro->match.pattern = git_pool_strdup(pool, name);
+	GITERR_CHECK_ALLOC(macro->match.pattern);
+
+	macro->match.length = strlen(macro->match.pattern);
+	macro->match.flags = GIT_ATTR_FNMATCH_MACRO;
+
+	error = git_attr_assignment__parse(repo, pool, &macro->assigns, &values);
+
+	if (!error)
+		error = git_attr_cache__insert_macro(repo, macro);
+
+	if (error < 0)
+		git_attr_rule__free(macro);
+
+	return error;
+}
+
+typedef struct {
+	git_repository *repo;
+	git_attr_session *attr_session;
+	uint32_t flags;
+	const char *workdir;
+	git_index *index;
+	git_vector *files;
+} attr_walk_up_info;
+
+static int attr_decide_sources(
+	uint32_t flags, bool has_wd, bool has_index, git_attr_file_source *srcs)
+{
+	int count = 0;
+
+	switch (flags & 0x03) {
+	case GIT_ATTR_CHECK_FILE_THEN_INDEX:
+		if (has_wd)
+			srcs[count++] = GIT_ATTR_FILE__FROM_FILE;
+		if (has_index)
+			srcs[count++] = GIT_ATTR_FILE__FROM_INDEX;
+		break;
+	case GIT_ATTR_CHECK_INDEX_THEN_FILE:
+		if (has_index)
+			srcs[count++] = GIT_ATTR_FILE__FROM_INDEX;
+		if (has_wd)
+			srcs[count++] = GIT_ATTR_FILE__FROM_FILE;
+		break;
+	case GIT_ATTR_CHECK_INDEX_ONLY:
+		if (has_index)
+			srcs[count++] = GIT_ATTR_FILE__FROM_INDEX;
+		break;
+	}
+
+	return count;
+}
+
+static int push_attr_file(
+	git_repository *repo,
+	git_attr_session *attr_session,
+	git_vector *list,
+	git_attr_file_source source,
+	const char *base,
+	const char *filename)
+{
+	int error = 0;
+	git_attr_file *file = NULL;
+
+	error = git_attr_cache__get(&file, repo, attr_session,
+		source, base, filename, git_attr_file__parse_buffer);
+
+	if (error < 0)
+		return error;
+
+	if (file != NULL) {
+		if ((error = git_vector_insert(list, file)) < 0)
+			git_attr_file__free(file);
+	}
+
+	return error;
+}
+
+static int push_one_attr(void *ref, const char *path)
+{
+	int error = 0, n_src, i;
+	attr_walk_up_info *info = (attr_walk_up_info *)ref;
+	git_attr_file_source src[2];
+
+	n_src = attr_decide_sources(
+		info->flags, info->workdir != NULL, info->index != NULL, src);
+
+	for (i = 0; !error && i < n_src; ++i)
+		error = push_attr_file(info->repo, info->attr_session,
+			info->files, src[i], path, GIT_ATTR_FILE);
+
+	return error;
+}
+
+static void release_attr_files(git_vector *files)
+{
+	size_t i;
+	git_attr_file *file;
+
+	git_vector_foreach(files, i, file) {
+		git_attr_file__free(file);
+		files->contents[i] = NULL;
+	}
+	git_vector_free(files);
+}
+
+static int collect_attr_files(
+	git_repository *repo,
+	git_attr_session *attr_session,
+	uint32_t flags,
+	const char *path,
+	git_vector *files)
+{
+	int error = 0;
+	git_buf dir = GIT_BUF_INIT;
+	const char *workdir = git_repository_workdir(repo);
+	attr_walk_up_info info = { NULL };
+
+	if ((error = attr_setup(repo, attr_session)) < 0)
+		return error;
+
+	/* Resolve path in a non-bare repo */
+	if (workdir != NULL)
+		error = git_path_find_dir(&dir, path, workdir);
+	else
+		error = git_path_dirname_r(&dir, path);
+	if (error < 0)
+		goto cleanup;
+
+	/* in precendence order highest to lowest:
+	 * - $GIT_DIR/info/attributes
+	 * - path components with .gitattributes
+	 * - config core.attributesfile
+	 * - $GIT_PREFIX/etc/gitattributes
+	 */
+
+	error = push_attr_file(
+		repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE,
+		git_repository_path(repo), GIT_ATTR_FILE_INREPO);
+	if (error < 0)
+		goto cleanup;
+
+	info.repo = repo;
+	info.attr_session = attr_session;
+	info.flags = flags;
+	info.workdir = workdir;
+	if (git_repository_index__weakptr(&info.index, repo) < 0)
+		giterr_clear(); /* no error even if there is no index */
+	info.files = files;
+
+	if (!strcmp(dir.ptr, "."))
+		error = push_one_attr(&info, "");
+	else
+		error = git_path_walk_up(&dir, workdir, push_one_attr, &info);
+
+	if (error < 0)
+		goto cleanup;
+
+	if (git_repository_attr_cache(repo)->cfg_attr_file != NULL) {
+		error = push_attr_file(
+			repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE,
+			NULL, git_repository_attr_cache(repo)->cfg_attr_file);
+		if (error < 0)
+			goto cleanup;
+	}
+
+	if ((flags & GIT_ATTR_CHECK_NO_SYSTEM) == 0) {
+		error = system_attr_file(&dir, attr_session);
+
+		if (!error)
+			error = push_attr_file(
+				repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE,
+				NULL, dir.ptr);
+		else if (error == GIT_ENOTFOUND)
+			error = 0;
+	}
+
+ cleanup:
+	if (error < 0)
+		release_attr_files(files);
+	git_buf_free(&dir);
+
+	return error;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attr.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attr.h
new file mode 100755
index 0000000..f9f216d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attr.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_attr_h__
+#define INCLUDE_attr_h__
+
+#include "attr_file.h"
+#include "attrcache.h"
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attr_file.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attr_file.c
new file mode 100755
index 0000000..8970686
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attr_file.c
@@ -0,0 +1,869 @@
+#include "common.h"
+#include "repository.h"
+#include "filebuf.h"
+#include "attr_file.h"
+#include "attrcache.h"
+#include "git2/blob.h"
+#include "git2/tree.h"
+#include "index.h"
+#include <ctype.h>
+
+static void attr_file_free(git_attr_file *file)
+{
+	bool unlock = !git_mutex_lock(&file->lock);
+	git_attr_file__clear_rules(file, false);
+	git_pool_clear(&file->pool);
+	if (unlock)
+		git_mutex_unlock(&file->lock);
+	git_mutex_free(&file->lock);
+
+	git__memzero(file, sizeof(*file));
+	git__free(file);
+}
+
+int git_attr_file__new(
+	git_attr_file **out,
+	git_attr_file_entry *entry,
+	git_attr_file_source source)
+{
+	git_attr_file *attrs = git__calloc(1, sizeof(git_attr_file));
+	GITERR_CHECK_ALLOC(attrs);
+
+	if (git_mutex_init(&attrs->lock) < 0) {
+		giterr_set(GITERR_OS, "Failed to initialize lock");
+		git__free(attrs);
+		return -1;
+	}
+
+	if (git_pool_init(&attrs->pool, 1, 0) < 0) {
+		attr_file_free(attrs);
+		return -1;
+	}
+
+	GIT_REFCOUNT_INC(attrs);
+	attrs->entry  = entry;
+	attrs->source = source;
+	*out = attrs;
+	return 0;
+}
+
+int git_attr_file__clear_rules(git_attr_file *file, bool need_lock)
+{
+	unsigned int i;
+	git_attr_rule *rule;
+
+	if (need_lock && git_mutex_lock(&file->lock) < 0) {
+		giterr_set(GITERR_OS, "Failed to lock attribute file");
+		return -1;
+	}
+
+	git_vector_foreach(&file->rules, i, rule)
+		git_attr_rule__free(rule);
+	git_vector_free(&file->rules);
+
+	if (need_lock)
+		git_mutex_unlock(&file->lock);
+
+	return 0;
+}
+
+void git_attr_file__free(git_attr_file *file)
+{
+	if (!file)
+		return;
+	GIT_REFCOUNT_DEC(file, attr_file_free);
+}
+
+static int attr_file_oid_from_index(
+	git_oid *oid, git_repository *repo, const char *path)
+{
+	int error;
+	git_index *idx;
+	size_t pos;
+	const git_index_entry *entry;
+
+	if ((error = git_repository_index__weakptr(&idx, repo)) < 0 ||
+		(error = git_index__find_pos(&pos, idx, path, 0, 0)) < 0)
+		return error;
+
+	if (!(entry = git_index_get_byindex(idx, pos)))
+		return GIT_ENOTFOUND;
+
+	*oid = entry->id;
+	return 0;
+}
+
+int git_attr_file__load(
+	git_attr_file **out,
+	git_repository *repo,
+	git_attr_session *attr_session,
+	git_attr_file_entry *entry,
+	git_attr_file_source source,
+	git_attr_file_parser parser)
+{
+	int error = 0;
+	git_blob *blob = NULL;
+	git_buf content = GIT_BUF_INIT;
+	git_attr_file *file;
+	struct stat st;
+	bool nonexistent = false;
+
+	*out = NULL;
+
+	switch (source) {
+	case GIT_ATTR_FILE__IN_MEMORY:
+		/* in-memory attribute file doesn't need data */
+		break;
+	case GIT_ATTR_FILE__FROM_INDEX: {
+		git_oid id;
+
+		if ((error = attr_file_oid_from_index(&id, repo, entry->path)) < 0 ||
+			(error = git_blob_lookup(&blob, repo, &id)) < 0)
+			return error;
+
+		/* Do not assume that data straight from the ODB is NULL-terminated;
+		 * copy the contents of a file to a buffer to work on */
+		git_buf_put(&content, git_blob_rawcontent(blob), git_blob_rawsize(blob));
+		break;
+	}
+	case GIT_ATTR_FILE__FROM_FILE: {
+		int fd;
+
+		/* For open or read errors, pretend that we got ENOTFOUND. */
+		/* TODO: issue warning when warning API is available */
+
+		if (p_stat(entry->fullpath, &st) < 0 ||
+			S_ISDIR(st.st_mode) ||
+			(fd = git_futils_open_ro(entry->fullpath)) < 0 ||
+			(error = git_futils_readbuffer_fd(&content, fd, (size_t)st.st_size)) < 0)
+			nonexistent = true;
+		else
+			p_close(fd);
+
+		break;
+	}
+	default:
+		giterr_set(GITERR_INVALID, "Unknown file source %d", source);
+		return -1;
+	}
+
+	if ((error = git_attr_file__new(&file, entry, source)) < 0)
+		goto cleanup;
+
+	/* store the key of the attr_reader; don't bother with cache
+	 * invalidation during the same attr reader session.
+	 */
+	if (attr_session)
+		file->session_key = attr_session->key;
+
+	if (parser && (error = parser(repo, file, git_buf_cstr(&content))) < 0) {
+		git_attr_file__free(file);
+		goto cleanup;
+	}
+
+	/* write cache breakers */
+	if (nonexistent)
+		file->nonexistent = 1;
+	else if (source == GIT_ATTR_FILE__FROM_INDEX)
+		git_oid_cpy(&file->cache_data.oid, git_blob_id(blob));
+	else if (source == GIT_ATTR_FILE__FROM_FILE)
+		git_futils_filestamp_set_from_stat(&file->cache_data.stamp, &st);
+	/* else always cacheable */
+
+	*out = file;
+
+cleanup:
+	git_blob_free(blob);
+	git_buf_free(&content);
+
+	return error;
+}
+
+int git_attr_file__out_of_date(
+	git_repository *repo,
+	git_attr_session *attr_session,
+	git_attr_file *file)
+{
+	if (!file)
+		return 1;
+
+	/* we are never out of date if we just created this data in the same
+	 * attr_session; otherwise, nonexistent files must be invalidated
+	 */
+	if (attr_session && attr_session->key == file->session_key)
+		return 0;
+	else if (file->nonexistent)
+		return 1;
+
+	switch (file->source) {
+	case GIT_ATTR_FILE__IN_MEMORY:
+		return 0;
+
+	case GIT_ATTR_FILE__FROM_FILE:
+		return git_futils_filestamp_check(
+			&file->cache_data.stamp, file->entry->fullpath);
+
+	case GIT_ATTR_FILE__FROM_INDEX: {
+		int error;
+		git_oid id;
+
+		if ((error = attr_file_oid_from_index(
+				&id, repo, file->entry->path)) < 0)
+			return error;
+
+		return (git_oid__cmp(&file->cache_data.oid, &id) != 0);
+	}
+
+	default:
+		giterr_set(GITERR_INVALID, "Invalid file type %d", file->source);
+		return -1;
+	}
+}
+
+static int sort_by_hash_and_name(const void *a_raw, const void *b_raw);
+static void git_attr_rule__clear(git_attr_rule *rule);
+static bool parse_optimized_patterns(
+	git_attr_fnmatch *spec,
+	git_pool *pool,
+	const char *pattern);
+
+int git_attr_file__parse_buffer(
+	git_repository *repo, git_attr_file *attrs, const char *data)
+{
+	int error = 0;
+	const char *scan = data, *context = NULL;
+	git_attr_rule *rule = NULL;
+
+	/* if subdir file path, convert context for file paths */
+	if (attrs->entry &&
+		git_path_root(attrs->entry->path) < 0 &&
+		!git__suffixcmp(attrs->entry->path, "/" GIT_ATTR_FILE))
+		context = attrs->entry->path;
+
+	if (git_mutex_lock(&attrs->lock) < 0) {
+		giterr_set(GITERR_OS, "Failed to lock attribute file");
+		return -1;
+	}
+
+	while (!error && *scan) {
+		/* allocate rule if needed */
+		if (!rule && !(rule = git__calloc(1, sizeof(*rule)))) {
+			error = -1;
+			break;
+		}
+
+		rule->match.flags =
+			GIT_ATTR_FNMATCH_ALLOWNEG | GIT_ATTR_FNMATCH_ALLOWMACRO;
+
+		/* parse the next "pattern attr attr attr" line */
+		if (!(error = git_attr_fnmatch__parse(
+				&rule->match, &attrs->pool, context, &scan)) &&
+			!(error = git_attr_assignment__parse(
+				repo, &attrs->pool, &rule->assigns, &scan)))
+		{
+			if (rule->match.flags & GIT_ATTR_FNMATCH_MACRO)
+				/* TODO: warning if macro found in file below repo root */
+				error = git_attr_cache__insert_macro(repo, rule);
+			else
+				error = git_vector_insert(&attrs->rules, rule);
+		}
+
+		/* if the rule wasn't a pattern, on to the next */
+		if (error < 0) {
+			git_attr_rule__clear(rule); /* reset rule contents */
+			if (error == GIT_ENOTFOUND)
+				error = 0;
+		} else {
+			rule = NULL; /* vector now "owns" the rule */
+		}
+	}
+
+	git_mutex_unlock(&attrs->lock);
+	git_attr_rule__free(rule);
+
+	return error;
+}
+
+uint32_t git_attr_file__name_hash(const char *name)
+{
+	uint32_t h = 5381;
+	int c;
+	assert(name);
+	while ((c = (int)*name++) != 0)
+		h = ((h << 5) + h) + c;
+	return h;
+}
+
+int git_attr_file__lookup_one(
+	git_attr_file *file,
+	git_attr_path *path,
+	const char *attr,
+	const char **value)
+{
+	size_t i;
+	git_attr_name name;
+	git_attr_rule *rule;
+
+	*value = NULL;
+
+	name.name = attr;
+	name.name_hash = git_attr_file__name_hash(attr);
+
+	git_attr_file__foreach_matching_rule(file, path, i, rule) {
+		size_t pos;
+
+		if (!git_vector_bsearch(&pos, &rule->assigns, &name)) {
+			*value = ((git_attr_assignment *)
+					  git_vector_get(&rule->assigns, pos))->value;
+			break;
+		}
+	}
+
+	return 0;
+}
+
+int git_attr_file__load_standalone(git_attr_file **out, const char *path)
+{
+	int error;
+	git_attr_file *file;
+	git_buf content = GIT_BUF_INIT;
+
+	error = git_attr_file__new(&file, NULL, GIT_ATTR_FILE__FROM_FILE);
+	if (error < 0)
+		return error;
+
+	error = git_attr_cache__alloc_file_entry(
+		&file->entry, NULL, path, &file->pool);
+	if (error < 0) {
+		git_attr_file__free(file);
+		return error;
+	}
+	/* because the cache entry is allocated from the file's own pool, we
+	 * don't have to free it - freeing file+pool will free cache entry, too.
+	 */
+
+	if (!(error = git_futils_readbuffer(&content, path))) {
+		error = git_attr_file__parse_buffer(NULL, file, content.ptr);
+		git_buf_free(&content);
+	}
+
+	if (error < 0)
+		git_attr_file__free(file);
+	else
+		*out = file;
+
+	return error;
+}
+
+bool git_attr_fnmatch__match(
+	git_attr_fnmatch *match,
+	git_attr_path *path)
+{
+	const char *relpath = path->path;
+	const char *filename;
+	int flags = 0;
+
+	/*
+	 * If the rule was generated in a subdirectory, we must only
+	 * use it for paths inside that directory. We can thus return
+	 * a non-match if the prefixes don't match.
+	 */
+	if (match->containing_dir) {
+		if (match->flags & GIT_ATTR_FNMATCH_ICASE) {
+			if (git__strncasecmp(path->path, match->containing_dir, match->containing_dir_length))
+				return 0;
+		} else {
+			if (git__prefixcmp(path->path, match->containing_dir))
+				return 0;
+		}
+
+		relpath += match->containing_dir_length;
+	}
+
+	if (match->flags & GIT_ATTR_FNMATCH_ICASE)
+		flags |= FNM_CASEFOLD;
+	if (match->flags & GIT_ATTR_FNMATCH_LEADINGDIR)
+		flags |= FNM_LEADING_DIR;
+
+	if (match->flags & GIT_ATTR_FNMATCH_FULLPATH) {
+		filename = relpath;
+		flags |= FNM_PATHNAME;
+	} else {
+		filename = path->basename;
+
+		if (path->is_dir)
+			flags |= FNM_LEADING_DIR;
+	}
+
+	if ((match->flags & GIT_ATTR_FNMATCH_DIRECTORY) && !path->is_dir) {
+		bool samename;
+
+		/* for attribute checks or root ignore checks, fail match */
+		if (!(match->flags & GIT_ATTR_FNMATCH_IGNORE) ||
+			path->basename == path->path)
+			return false;
+
+		flags |= FNM_LEADING_DIR;
+
+		/* fail match if this is a file with same name as ignored folder */
+		samename = (match->flags & GIT_ATTR_FNMATCH_ICASE) ?
+			!strcasecmp(match->pattern, relpath) :
+			!strcmp(match->pattern, relpath);
+
+		if (samename)
+			return false;
+
+		return (p_fnmatch(match->pattern, relpath, flags) != FNM_NOMATCH);
+	}
+
+	/* if path is a directory prefix of a negated pattern, then match */
+	if ((match->flags & GIT_ATTR_FNMATCH_NEGATIVE) && path->is_dir) {
+		size_t pathlen = strlen(relpath);
+		bool prefixed = (pathlen <= match->length) &&
+			((match->flags & GIT_ATTR_FNMATCH_ICASE) ?
+			!strncasecmp(match->pattern, relpath, pathlen) :
+			!strncmp(match->pattern, relpath, pathlen));
+
+		if (prefixed && git_path_at_end_of_segment(&match->pattern[pathlen]))
+			return true;
+	}
+
+	return (p_fnmatch(match->pattern, filename, flags) != FNM_NOMATCH);
+}
+
+bool git_attr_rule__match(
+	git_attr_rule *rule,
+	git_attr_path *path)
+{
+	bool matched = git_attr_fnmatch__match(&rule->match, path);
+
+	if (rule->match.flags & GIT_ATTR_FNMATCH_NEGATIVE)
+		matched = !matched;
+
+	return matched;
+}
+
+git_attr_assignment *git_attr_rule__lookup_assignment(
+	git_attr_rule *rule, const char *name)
+{
+	size_t pos;
+	git_attr_name key;
+	key.name = name;
+	key.name_hash = git_attr_file__name_hash(name);
+
+	if (git_vector_bsearch(&pos, &rule->assigns, &key))
+		return NULL;
+
+	return git_vector_get(&rule->assigns, pos);
+}
+
+int git_attr_path__init(
+	git_attr_path *info, const char *path, const char *base, git_dir_flag dir_flag)
+{
+	ssize_t root;
+
+	/* build full path as best we can */
+	git_buf_init(&info->full, 0);
+
+	if (git_path_join_unrooted(&info->full, path, base, &root) < 0)
+		return -1;
+
+	info->path = info->full.ptr + root;
+
+	/* remove trailing slashes */
+	while (info->full.size > 0) {
+		if (info->full.ptr[info->full.size - 1] != '/')
+			break;
+		info->full.size--;
+	}
+	info->full.ptr[info->full.size] = '\0';
+
+	/* skip leading slashes in path */
+	while (*info->path == '/')
+		info->path++;
+
+	/* find trailing basename component */
+	info->basename = strrchr(info->path, '/');
+	if (info->basename)
+		info->basename++;
+	if (!info->basename || !*info->basename)
+		info->basename = info->path;
+
+	switch (dir_flag)
+	{
+	case GIT_DIR_FLAG_FALSE:
+		info->is_dir = 0;
+		break;
+
+	case GIT_DIR_FLAG_TRUE:
+		info->is_dir = 1;
+		break;
+
+	case GIT_DIR_FLAG_UNKNOWN:
+	default:
+		info->is_dir = (int)git_path_isdir(info->full.ptr);
+		break;
+	}
+
+	return 0;
+}
+
+void git_attr_path__free(git_attr_path *info)
+{
+	git_buf_free(&info->full);
+	info->path = NULL;
+	info->basename = NULL;
+}
+
+/*
+ * From gitattributes(5):
+ *
+ * Patterns have the following format:
+ *
+ * - A blank line matches no files, so it can serve as a separator for
+ *   readability.
+ *
+ * - A line starting with # serves as a comment.
+ *
+ * - An optional prefix ! which negates the pattern; any matching file
+ *   excluded by a previous pattern will become included again. If a negated
+ *   pattern matches, this will override lower precedence patterns sources.
+ *
+ * - If the pattern ends with a slash, it is removed for the purpose of the
+ *   following description, but it would only find a match with a directory. In
+ *   other words, foo/ will match a directory foo and paths underneath it, but
+ *   will not match a regular file or a symbolic link foo (this is consistent
+ *   with the way how pathspec works in general in git).
+ *
+ * - If the pattern does not contain a slash /, git treats it as a shell glob
+ *   pattern and checks for a match against the pathname without leading
+ *   directories.
+ *
+ * - Otherwise, git treats the pattern as a shell glob suitable for consumption
+ *   by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the pattern will
+ *   not match a / in the pathname. For example, "Documentation/\*.html" matches
+ *   "Documentation/git.html" but not "Documentation/ppc/ppc.html". A leading
+ *   slash matches the beginning of the pathname; for example, "/\*.c" matches
+ *   "cat-file.c" but not "mozilla-sha1/sha1.c".
+ */
+
+/*
+ * This will return 0 if the spec was filled out,
+ * GIT_ENOTFOUND if the fnmatch does not require matching, or
+ * another error code there was an actual problem.
+ */
+int git_attr_fnmatch__parse(
+	git_attr_fnmatch *spec,
+	git_pool *pool,
+	const char *context,
+	const char **base)
+{
+	const char *pattern, *scan;
+	int slash_count, allow_space;
+
+	assert(spec && base && *base);
+
+	if (parse_optimized_patterns(spec, pool, *base))
+		return 0;
+
+	spec->flags = (spec->flags & GIT_ATTR_FNMATCH__INCOMING);
+	allow_space = ((spec->flags & GIT_ATTR_FNMATCH_ALLOWSPACE) != 0);
+
+	pattern = *base;
+
+	while (git__isspace(*pattern)) pattern++;
+	if (!*pattern || *pattern == '#') {
+		*base = git__next_line(pattern);
+		return GIT_ENOTFOUND;
+	}
+
+	if (*pattern == '[' && (spec->flags & GIT_ATTR_FNMATCH_ALLOWMACRO) != 0) {
+		if (strncmp(pattern, "[attr]", 6) == 0) {
+			spec->flags = spec->flags | GIT_ATTR_FNMATCH_MACRO;
+			pattern += 6;
+		}
+		/* else a character range like [a-e]* which is accepted */
+	}
+
+	if (*pattern == '!' && (spec->flags & GIT_ATTR_FNMATCH_ALLOWNEG) != 0) {
+		spec->flags = spec->flags |
+			GIT_ATTR_FNMATCH_NEGATIVE | GIT_ATTR_FNMATCH_LEADINGDIR;
+		pattern++;
+	}
+
+	slash_count = 0;
+	for (scan = pattern; *scan != '\0'; ++scan) {
+		/* scan until (non-escaped) white space */
+		if (git__isspace(*scan) && *(scan - 1) != '\\') {
+			if (!allow_space || (*scan != ' ' && *scan != '\t' && *scan != '\r'))
+				break;
+		}
+
+		if (*scan == '/') {
+			spec->flags = spec->flags | GIT_ATTR_FNMATCH_FULLPATH;
+			slash_count++;
+			if (pattern == scan)
+				pattern++;
+		}
+		/* remember if we see an unescaped wildcard in pattern */
+		else if (git__iswildcard(*scan) &&
+			(scan == pattern || (*(scan - 1) != '\\')))
+			spec->flags = spec->flags | GIT_ATTR_FNMATCH_HASWILD;
+	}
+
+	*base = scan;
+
+	if ((spec->length = scan - pattern) == 0)
+		return GIT_ENOTFOUND;
+
+	/*
+	 * Remove one trailing \r in case this is a CRLF delimited
+	 * file, in the case of Icon\r\r\n, we still leave the first
+	 * \r there to match against.
+	 */
+	if (pattern[spec->length - 1] == '\r')
+		if (--spec->length == 0)
+			return GIT_ENOTFOUND;
+
+	if (pattern[spec->length - 1] == '/') {
+		spec->length--;
+		spec->flags = spec->flags | GIT_ATTR_FNMATCH_DIRECTORY;
+		if (--slash_count <= 0)
+			spec->flags = spec->flags & ~GIT_ATTR_FNMATCH_FULLPATH;
+	}
+	if ((spec->flags & GIT_ATTR_FNMATCH_NOLEADINGDIR) == 0 &&
+		spec->length >= 2 &&
+		pattern[spec->length - 1] == '*' &&
+		pattern[spec->length - 2] == '/') {
+		spec->length -= 2;
+		spec->flags = spec->flags | GIT_ATTR_FNMATCH_LEADINGDIR;
+		/* leave FULLPATH match on, however */
+	}
+
+	if (context) {
+		char *slash = strrchr(context, '/');
+		size_t len;
+		if (slash) {
+			/* include the slash for easier matching */
+			len = slash - context + 1;
+			spec->containing_dir = git_pool_strndup(pool, context, len);
+			spec->containing_dir_length = len;
+		}
+	}
+
+	spec->pattern = git_pool_strndup(pool, pattern, spec->length);
+
+	if (!spec->pattern) {
+		*base = git__next_line(pattern);
+		return -1;
+	} else {
+		/* strip '\' that might have be used for internal whitespace */
+		spec->length = git__unescape(spec->pattern);
+		/* TODO: convert remaining '\' into '/' for POSIX ??? */
+	}
+
+	return 0;
+}
+
+static bool parse_optimized_patterns(
+	git_attr_fnmatch *spec,
+	git_pool *pool,
+	const char *pattern)
+{
+	if (!pattern[1] && (pattern[0] == '*' || pattern[0] == '.')) {
+		spec->flags = GIT_ATTR_FNMATCH_MATCH_ALL;
+		spec->pattern = git_pool_strndup(pool, pattern, 1);
+		spec->length = 1;
+
+		return true;
+	}
+
+	return false;
+}
+
+static int sort_by_hash_and_name(const void *a_raw, const void *b_raw)
+{
+	const git_attr_name *a = a_raw;
+	const git_attr_name *b = b_raw;
+
+	if (b->name_hash < a->name_hash)
+		return 1;
+	else if (b->name_hash > a->name_hash)
+		return -1;
+	else
+		return strcmp(b->name, a->name);
+}
+
+static void git_attr_assignment__free(git_attr_assignment *assign)
+{
+	/* name and value are stored in a git_pool associated with the
+	 * git_attr_file, so they do not need to be freed here
+	 */
+	assign->name = NULL;
+	assign->value = NULL;
+	git__free(assign);
+}
+
+static int merge_assignments(void **old_raw, void *new_raw)
+{
+	git_attr_assignment **old = (git_attr_assignment **)old_raw;
+	git_attr_assignment *new = (git_attr_assignment *)new_raw;
+
+	GIT_REFCOUNT_DEC(*old, git_attr_assignment__free);
+	*old = new;
+	return GIT_EEXISTS;
+}
+
+int git_attr_assignment__parse(
+	git_repository *repo,
+	git_pool *pool,
+	git_vector *assigns,
+	const char **base)
+{
+	int error;
+	const char *scan = *base;
+	git_attr_assignment *assign = NULL;
+
+	assert(assigns && !assigns->length);
+
+	git_vector_set_cmp(assigns, sort_by_hash_and_name);
+
+	while (*scan && *scan != '\n') {
+		const char *name_start, *value_start;
+
+		/* skip leading blanks */
+		while (git__isspace(*scan) && *scan != '\n') scan++;
+
+		/* allocate assign if needed */
+		if (!assign) {
+			assign = git__calloc(1, sizeof(git_attr_assignment));
+			GITERR_CHECK_ALLOC(assign);
+			GIT_REFCOUNT_INC(assign);
+		}
+
+		assign->name_hash = 5381;
+		assign->value = git_attr__true;
+
+		/* look for magic name prefixes */
+		if (*scan == '-') {
+			assign->value = git_attr__false;
+			scan++;
+		} else if (*scan == '!') {
+			assign->value = git_attr__unset; /* explicit unspecified state */
+			scan++;
+		} else if (*scan == '#') /* comment rest of line */
+			break;
+
+		/* find the name */
+		name_start = scan;
+		while (*scan && !git__isspace(*scan) && *scan != '=') {
+			assign->name_hash =
+				((assign->name_hash << 5) + assign->name_hash) + *scan;
+			scan++;
+		}
+		if (scan == name_start) {
+			/* must have found lone prefix (" - ") or leading = ("=foo")
+			 * or end of buffer -- advance until whitespace and continue
+			 */
+			while (*scan && !git__isspace(*scan)) scan++;
+			continue;
+		}
+
+		/* allocate permanent storage for name */
+		assign->name = git_pool_strndup(pool, name_start, scan - name_start);
+		GITERR_CHECK_ALLOC(assign->name);
+
+		/* if there is an equals sign, find the value */
+		if (*scan == '=') {
+			for (value_start = ++scan; *scan && !git__isspace(*scan); ++scan);
+
+			/* if we found a value, allocate permanent storage for it */
+			if (scan > value_start) {
+				assign->value = git_pool_strndup(pool, value_start, scan - value_start);
+				GITERR_CHECK_ALLOC(assign->value);
+			}
+		}
+
+		/* expand macros (if given a repo with a macro cache) */
+		if (repo != NULL && assign->value == git_attr__true) {
+			git_attr_rule *macro =
+				git_attr_cache__lookup_macro(repo, assign->name);
+
+			if (macro != NULL) {
+				unsigned int i;
+				git_attr_assignment *massign;
+
+				git_vector_foreach(&macro->assigns, i, massign) {
+					GIT_REFCOUNT_INC(massign);
+
+					error = git_vector_insert_sorted(
+						assigns, massign, &merge_assignments);
+					if (error < 0 && error != GIT_EEXISTS) {
+						git_attr_assignment__free(assign);
+						return error;
+					}
+				}
+			}
+		}
+
+		/* insert allocated assign into vector */
+		error = git_vector_insert_sorted(assigns, assign, &merge_assignments);
+		if (error < 0 && error != GIT_EEXISTS)
+			return error;
+
+		/* clear assign since it is now "owned" by the vector */
+		assign = NULL;
+	}
+
+	if (assign != NULL)
+		git_attr_assignment__free(assign);
+
+	*base = git__next_line(scan);
+
+	return (assigns->length == 0) ? GIT_ENOTFOUND : 0;
+}
+
+static void git_attr_rule__clear(git_attr_rule *rule)
+{
+	unsigned int i;
+	git_attr_assignment *assign;
+
+	if (!rule)
+		return;
+
+	if (!(rule->match.flags & GIT_ATTR_FNMATCH_IGNORE)) {
+		git_vector_foreach(&rule->assigns, i, assign)
+			GIT_REFCOUNT_DEC(assign, git_attr_assignment__free);
+		git_vector_free(&rule->assigns);
+	}
+
+	/* match.pattern is stored in a git_pool, so no need to free */
+	rule->match.pattern = NULL;
+	rule->match.length = 0;
+}
+
+void git_attr_rule__free(git_attr_rule *rule)
+{
+	git_attr_rule__clear(rule);
+	git__free(rule);
+}
+
+int git_attr_session__init(git_attr_session *session, git_repository *repo)
+{
+	assert(repo);
+
+	session->key = git_atomic_inc(&repo->attr_session_key);
+
+	return 0;
+}
+
+void git_attr_session__free(git_attr_session *session)
+{
+	if (!session)
+		return;
+
+	git_buf_free(&session->sysdir);
+	git_buf_free(&session->tmp);
+
+	memset(session, 0, sizeof(git_attr_session));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attr_file.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attr_file.h
new file mode 100755
index 0000000..388ecf4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attr_file.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_attr_file_h__
+#define INCLUDE_attr_file_h__
+
+#include "git2/oid.h"
+#include "git2/attr.h"
+#include "vector.h"
+#include "pool.h"
+#include "buffer.h"
+#include "fileops.h"
+
+#define GIT_ATTR_FILE			".gitattributes"
+#define GIT_ATTR_FILE_INREPO	"info/attributes"
+#define GIT_ATTR_FILE_SYSTEM	"gitattributes"
+#define GIT_ATTR_FILE_XDG		"attributes"
+
+#define GIT_ATTR_FNMATCH_NEGATIVE	(1U << 0)
+#define GIT_ATTR_FNMATCH_DIRECTORY	(1U << 1)
+#define GIT_ATTR_FNMATCH_FULLPATH	(1U << 2)
+#define GIT_ATTR_FNMATCH_MACRO		(1U << 3)
+#define GIT_ATTR_FNMATCH_IGNORE		(1U << 4)
+#define GIT_ATTR_FNMATCH_HASWILD	(1U << 5)
+#define GIT_ATTR_FNMATCH_ALLOWSPACE	(1U << 6)
+#define GIT_ATTR_FNMATCH_ICASE		(1U << 7)
+#define GIT_ATTR_FNMATCH_MATCH_ALL	(1U << 8)
+#define GIT_ATTR_FNMATCH_ALLOWNEG   (1U << 9)
+#define GIT_ATTR_FNMATCH_ALLOWMACRO (1U << 10)
+#define GIT_ATTR_FNMATCH_LEADINGDIR (1U << 11)
+#define GIT_ATTR_FNMATCH_NOLEADINGDIR (1U << 12)
+
+#define GIT_ATTR_FNMATCH__INCOMING \
+	(GIT_ATTR_FNMATCH_ALLOWSPACE | GIT_ATTR_FNMATCH_ALLOWNEG | \
+	 GIT_ATTR_FNMATCH_ALLOWMACRO | GIT_ATTR_FNMATCH_NOLEADINGDIR)
+
+typedef enum {
+	GIT_ATTR_FILE__IN_MEMORY   = 0,
+	GIT_ATTR_FILE__FROM_FILE   = 1,
+	GIT_ATTR_FILE__FROM_INDEX  = 2,
+
+	GIT_ATTR_FILE_NUM_SOURCES  = 3
+} git_attr_file_source;
+
+extern const char *git_attr__true;
+extern const char *git_attr__false;
+extern const char *git_attr__unset;
+
+typedef struct {
+	char *pattern;
+	size_t length;
+	char *containing_dir;
+	size_t containing_dir_length;
+	unsigned int flags;
+} git_attr_fnmatch;
+
+typedef struct {
+	git_attr_fnmatch match;
+	git_vector assigns;		/* vector of <git_attr_assignment*> */
+} git_attr_rule;
+
+typedef struct {
+	git_refcount unused;
+	const char *name;
+	uint32_t name_hash;
+} git_attr_name;
+
+typedef struct {
+	git_refcount rc;		/* for macros */
+	char *name;
+	uint32_t name_hash;
+	const char *value;
+} git_attr_assignment;
+
+typedef struct git_attr_file_entry git_attr_file_entry;
+
+typedef struct {
+	git_refcount rc;
+	git_mutex lock;
+	git_attr_file_entry *entry;
+	git_attr_file_source source;
+	git_vector rules;			/* vector of <rule*> or <fnmatch*> */
+	git_pool pool;
+	unsigned int nonexistent:1;
+	int session_key;
+	union {
+		git_oid oid;
+		git_futils_filestamp stamp;
+	} cache_data;
+} git_attr_file;
+
+struct git_attr_file_entry {
+	git_attr_file *file[GIT_ATTR_FILE_NUM_SOURCES];
+	const char *path; /* points into fullpath */
+	char fullpath[GIT_FLEX_ARRAY];
+};
+
+typedef struct {
+	git_buf  full;
+	char    *path;
+	char    *basename;
+	int      is_dir;
+} git_attr_path;
+
+/* A git_attr_session can provide an "instance" of reading, to prevent cache
+ * invalidation during a single operation instance (like checkout).
+ */
+
+typedef struct {
+	int key;
+	unsigned int init_setup:1,
+		init_sysdir:1;
+	git_buf sysdir;
+	git_buf tmp;
+} git_attr_session;
+
+extern int git_attr_session__init(git_attr_session *attr_session, git_repository *repo);
+extern void git_attr_session__free(git_attr_session *session);
+
+extern int git_attr_get_many_with_session(
+	const char **values_out,
+	git_repository *repo,
+	git_attr_session *attr_session,
+	uint32_t flags,
+	const char *path,
+	size_t num_attr,
+	const char **names);
+
+typedef int (*git_attr_file_parser)(
+	git_repository *repo,
+	git_attr_file *file,
+	const char *data);
+
+/*
+ * git_attr_file API
+ */
+
+int git_attr_file__new(
+	git_attr_file **out,
+	git_attr_file_entry *entry,
+	git_attr_file_source source);
+
+void git_attr_file__free(git_attr_file *file);
+
+int git_attr_file__load(
+	git_attr_file **out,
+	git_repository *repo,
+	git_attr_session *attr_session,
+	git_attr_file_entry *ce,
+	git_attr_file_source source,
+	git_attr_file_parser parser);
+
+int git_attr_file__load_standalone(
+	git_attr_file **out, const char *path);
+
+int git_attr_file__out_of_date(
+	git_repository *repo, git_attr_session *session, git_attr_file *file);
+
+int git_attr_file__parse_buffer(
+	git_repository *repo, git_attr_file *attrs, const char *data);
+
+int git_attr_file__clear_rules(
+	git_attr_file *file, bool need_lock);
+
+int git_attr_file__lookup_one(
+	git_attr_file *file,
+	git_attr_path *path,
+	const char *attr,
+	const char **value);
+
+/* loop over rules in file from bottom to top */
+#define git_attr_file__foreach_matching_rule(file, path, iter, rule)	\
+	git_vector_rforeach(&(file)->rules, (iter), (rule)) \
+		if (git_attr_rule__match((rule), (path)))
+
+uint32_t git_attr_file__name_hash(const char *name);
+
+
+/*
+ * other utilities
+ */
+
+extern int git_attr_fnmatch__parse(
+	git_attr_fnmatch *spec,
+	git_pool *pool,
+	const char *source,
+	const char **base);
+
+extern bool git_attr_fnmatch__match(
+	git_attr_fnmatch *rule,
+	git_attr_path *path);
+
+extern void git_attr_rule__free(git_attr_rule *rule);
+
+extern bool git_attr_rule__match(
+	git_attr_rule *rule,
+	git_attr_path *path);
+
+extern git_attr_assignment *git_attr_rule__lookup_assignment(
+	git_attr_rule *rule, const char *name);
+
+typedef enum { GIT_DIR_FLAG_TRUE = 1, GIT_DIR_FLAG_FALSE = 0, GIT_DIR_FLAG_UNKNOWN = -1 } git_dir_flag;
+
+extern int git_attr_path__init(
+	git_attr_path *info, const char *path, const char *base, git_dir_flag is_dir);
+
+extern void git_attr_path__free(git_attr_path *info);
+
+extern int git_attr_assignment__parse(
+	git_repository *repo, /* needed to expand macros */
+	git_pool *pool,
+	git_vector *assigns,
+	const char **scan);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attrcache.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attrcache.c
new file mode 100755
index 0000000..5bc2604
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attrcache.c
@@ -0,0 +1,455 @@
+#include "common.h"
+#include "repository.h"
+#include "attr_file.h"
+#include "config.h"
+#include "sysdir.h"
+#include "ignore.h"
+
+GIT__USE_STRMAP
+
+GIT_INLINE(int) attr_cache_lock(git_attr_cache *cache)
+{
+	GIT_UNUSED(cache); /* avoid warning if threading is off */
+
+	if (git_mutex_lock(&cache->lock) < 0) {
+		giterr_set(GITERR_OS, "Unable to get attr cache lock");
+		return -1;
+	}
+	return 0;
+}
+
+GIT_INLINE(void) attr_cache_unlock(git_attr_cache *cache)
+{
+	GIT_UNUSED(cache); /* avoid warning if threading is off */
+	git_mutex_unlock(&cache->lock);
+}
+
+GIT_INLINE(git_attr_file_entry *) attr_cache_lookup_entry(
+	git_attr_cache *cache, const char *path)
+{
+	khiter_t pos = git_strmap_lookup_index(cache->files, path);
+
+	if (git_strmap_valid_index(cache->files, pos))
+		return git_strmap_value_at(cache->files, pos);
+	else
+		return NULL;
+}
+
+int git_attr_cache__alloc_file_entry(
+	git_attr_file_entry **out,
+	const char *base,
+	const char *path,
+	git_pool *pool)
+{
+	size_t baselen = 0, pathlen = strlen(path);
+	size_t cachesize = sizeof(git_attr_file_entry) + pathlen + 1;
+	git_attr_file_entry *ce;
+
+	if (base != NULL && git_path_root(path) < 0) {
+		baselen = strlen(base);
+		cachesize += baselen;
+
+		if (baselen && base[baselen - 1] != '/')
+			cachesize++;
+	}
+
+	ce = git_pool_mallocz(pool, (uint32_t)cachesize);
+	GITERR_CHECK_ALLOC(ce);
+
+	if (baselen) {
+		memcpy(ce->fullpath, base, baselen);
+
+		if (base[baselen - 1] != '/')
+			ce->fullpath[baselen++] = '/';
+	}
+	memcpy(&ce->fullpath[baselen], path, pathlen);
+
+	ce->path = &ce->fullpath[baselen];
+	*out = ce;
+
+	return 0;
+}
+
+/* call with attrcache locked */
+static int attr_cache_make_entry(
+	git_attr_file_entry **out, git_repository *repo, const char *path)
+{
+	int error = 0;
+	git_attr_cache *cache = git_repository_attr_cache(repo);
+	git_attr_file_entry *entry = NULL;
+
+	error = git_attr_cache__alloc_file_entry(
+		&entry, git_repository_workdir(repo), path, &cache->pool);
+
+	if (!error) {
+		git_strmap_insert(cache->files, entry->path, entry, error);
+		if (error > 0)
+			error = 0;
+	}
+
+	*out = entry;
+	return error;
+}
+
+/* insert entry or replace existing if we raced with another thread */
+static int attr_cache_upsert(git_attr_cache *cache, git_attr_file *file)
+{
+	git_attr_file_entry *entry;
+	git_attr_file *old;
+
+	if (attr_cache_lock(cache) < 0)
+		return -1;
+
+	entry = attr_cache_lookup_entry(cache, file->entry->path);
+
+	GIT_REFCOUNT_OWN(file, entry);
+	GIT_REFCOUNT_INC(file);
+
+	old = git__compare_and_swap(
+		&entry->file[file->source], entry->file[file->source], file);
+
+	if (old) {
+		GIT_REFCOUNT_OWN(old, NULL);
+		git_attr_file__free(old);
+	}
+
+	attr_cache_unlock(cache);
+	return 0;
+}
+
+static int attr_cache_remove(git_attr_cache *cache, git_attr_file *file)
+{
+	int error = 0;
+	git_attr_file_entry *entry;
+
+	if (!file)
+		return 0;
+	if ((error = attr_cache_lock(cache)) < 0)
+		return error;
+
+	if ((entry = attr_cache_lookup_entry(cache, file->entry->path)) != NULL)
+		file = git__compare_and_swap(&entry->file[file->source], file, NULL);
+
+	attr_cache_unlock(cache);
+
+	if (file) {
+		GIT_REFCOUNT_OWN(file, NULL);
+		git_attr_file__free(file);
+	}
+
+	return error;
+}
+
+/* Look up cache entry and file.
+ * - If entry is not present, create it while the cache is locked.
+ * - If file is present, increment refcount before returning it, so the
+ *   cache can be unlocked and it won't go away.
+ */
+static int attr_cache_lookup(
+	git_attr_file **out_file,
+	git_attr_file_entry **out_entry,
+	git_repository *repo,
+	git_attr_session *attr_session,
+	git_attr_file_source source,
+	const char *base,
+	const char *filename)
+{
+	int error = 0;
+	git_buf path = GIT_BUF_INIT;
+	const char *wd = git_repository_workdir(repo), *relfile;
+	git_attr_cache *cache = git_repository_attr_cache(repo);
+	git_attr_file_entry *entry = NULL;
+	git_attr_file *file = NULL;
+
+	/* join base and path as needed */
+	if (base != NULL && git_path_root(filename) < 0) {
+		git_buf *p = attr_session ? &attr_session->tmp : &path;
+
+		if (git_buf_joinpath(p, base, filename) < 0)
+			return -1;
+
+		filename = p->ptr;
+	}
+
+	relfile = filename;
+	if (wd && !git__prefixcmp(relfile, wd))
+		relfile += strlen(wd);
+
+	/* check cache for existing entry */
+	if ((error = attr_cache_lock(cache)) < 0)
+		goto cleanup;
+
+	entry = attr_cache_lookup_entry(cache, relfile);
+	if (!entry)
+		error = attr_cache_make_entry(&entry, repo, relfile);
+	else if (entry->file[source] != NULL) {
+		file = entry->file[source];
+		GIT_REFCOUNT_INC(file);
+	}
+
+	attr_cache_unlock(cache);
+
+cleanup:
+	*out_file  = file;
+	*out_entry = entry;
+
+	git_buf_free(&path);
+	return error;
+}
+
+int git_attr_cache__get(
+	git_attr_file **out,
+	git_repository *repo,
+	git_attr_session *attr_session,
+	git_attr_file_source source,
+	const char *base,
+	const char *filename,
+	git_attr_file_parser parser)
+{
+	int error = 0;
+	git_attr_cache *cache = git_repository_attr_cache(repo);
+	git_attr_file_entry *entry = NULL;
+	git_attr_file *file = NULL, *updated = NULL;
+
+	if ((error = attr_cache_lookup(
+			&file, &entry, repo, attr_session, source, base, filename)) < 0)
+		return error;
+
+	/* load file if we don't have one or if existing one is out of date */
+	if (!file || (error = git_attr_file__out_of_date(repo, attr_session, file)) > 0)
+		error = git_attr_file__load(&updated, repo, attr_session, entry, source, parser);
+
+	/* if we loaded the file, insert into and/or update cache */
+	if (updated) {
+		if ((error = attr_cache_upsert(cache, updated)) < 0)
+			git_attr_file__free(updated);
+		else {
+			git_attr_file__free(file); /* offset incref from lookup */
+			file = updated;
+		}
+	}
+
+	/* if file could not be loaded */
+	if (error < 0) {
+		/* remove existing entry */
+		if (file) {
+			attr_cache_remove(cache, file);
+			git_attr_file__free(file); /* offset incref from lookup */
+			file = NULL;
+		}
+		/* no error if file simply doesn't exist */
+		if (error == GIT_ENOTFOUND) {
+			giterr_clear();
+			error = 0;
+		}
+	}
+
+	*out = file;
+	return error;
+}
+
+bool git_attr_cache__is_cached(
+	git_repository *repo,
+	git_attr_file_source source,
+	const char *filename)
+{
+	git_attr_cache *cache = git_repository_attr_cache(repo);
+	git_strmap *files;
+	khiter_t pos;
+	git_attr_file_entry *entry;
+
+	if (!cache || !(files = cache->files))
+		return false;
+
+	pos = git_strmap_lookup_index(files, filename);
+	if (!git_strmap_valid_index(files, pos))
+		return false;
+
+	entry = git_strmap_value_at(files, pos);
+
+	return entry && (entry->file[source] != NULL);
+}
+
+
+static int attr_cache__lookup_path(
+	char **out, git_config *cfg, const char *key, const char *fallback)
+{
+	git_buf buf = GIT_BUF_INIT;
+	int error;
+	git_config_entry *entry = NULL;
+
+	*out = NULL;
+
+	if ((error = git_config__lookup_entry(&entry, cfg, key, false)) < 0)
+		return error;
+
+	if (entry) {
+		const char *cfgval = entry->value;
+
+		/* expand leading ~/ as needed */
+		if (cfgval && cfgval[0] == '~' && cfgval[1] == '/' &&
+			!git_sysdir_find_global_file(&buf, &cfgval[2]))
+			*out = git_buf_detach(&buf);
+		else if (cfgval)
+			*out = git__strdup(cfgval);
+	}
+	else if (!git_sysdir_find_xdg_file(&buf, fallback))
+		*out = git_buf_detach(&buf);
+
+	git_config_entry_free(entry);
+	git_buf_free(&buf);
+
+	return error;
+}
+
+static void attr_cache__free(git_attr_cache *cache)
+{
+	bool unlock;
+
+	if (!cache)
+		return;
+
+	unlock = (git_mutex_lock(&cache->lock) == 0);
+
+	if (cache->files != NULL) {
+		git_attr_file_entry *entry;
+		git_attr_file *file;
+		int i;
+
+		git_strmap_foreach_value(cache->files, entry, {
+			for (i = 0; i < GIT_ATTR_FILE_NUM_SOURCES; ++i) {
+				if ((file = git__swap(entry->file[i], NULL)) != NULL) {
+					GIT_REFCOUNT_OWN(file, NULL);
+					git_attr_file__free(file);
+				}
+			}
+		});
+		git_strmap_free(cache->files);
+	}
+
+	if (cache->macros != NULL) {
+		git_attr_rule *rule;
+
+		git_strmap_foreach_value(cache->macros, rule, {
+			git_attr_rule__free(rule);
+		});
+		git_strmap_free(cache->macros);
+	}
+
+	git_pool_clear(&cache->pool);
+
+	git__free(cache->cfg_attr_file);
+	cache->cfg_attr_file = NULL;
+
+	git__free(cache->cfg_excl_file);
+	cache->cfg_excl_file = NULL;
+
+	if (unlock)
+		git_mutex_unlock(&cache->lock);
+	git_mutex_free(&cache->lock);
+
+	git__free(cache);
+}
+
+int git_attr_cache__do_init(git_repository *repo)
+{
+	int ret = 0;
+	git_attr_cache *cache = git_repository_attr_cache(repo);
+	git_config *cfg = NULL;
+
+	if (cache)
+		return 0;
+
+	cache = git__calloc(1, sizeof(git_attr_cache));
+	GITERR_CHECK_ALLOC(cache);
+
+	/* set up lock */
+	if (git_mutex_init(&cache->lock) < 0) {
+		giterr_set(GITERR_OS, "Unable to initialize lock for attr cache");
+		git__free(cache);
+		return -1;
+	}
+
+	if ((ret = git_repository_config_snapshot(&cfg, repo)) < 0)
+		goto cancel;
+
+	/* cache config settings for attributes and ignores */
+	ret = attr_cache__lookup_path(
+		&cache->cfg_attr_file, cfg, GIT_ATTR_CONFIG, GIT_ATTR_FILE_XDG);
+	if (ret < 0)
+		goto cancel;
+
+	ret = attr_cache__lookup_path(
+		&cache->cfg_excl_file, cfg, GIT_IGNORE_CONFIG, GIT_IGNORE_FILE_XDG);
+	if (ret < 0)
+		goto cancel;
+
+	/* allocate hashtable for attribute and ignore file contents,
+	 * hashtable for attribute macros, and string pool
+	 */
+	if ((ret = git_strmap_alloc(&cache->files)) < 0 ||
+		(ret = git_strmap_alloc(&cache->macros)) < 0 ||
+		(ret = git_pool_init(&cache->pool, 1, 0)) < 0)
+		goto cancel;
+
+	cache = git__compare_and_swap(&repo->attrcache, NULL, cache);
+	if (cache)
+		goto cancel; /* raced with another thread, free this but no error */
+
+	git_config_free(cfg);
+
+	/* insert default macros */
+	return git_attr_add_macro(repo, "binary", "-diff -crlf -text");
+
+cancel:
+	attr_cache__free(cache);
+	git_config_free(cfg);
+	return ret;
+}
+
+void git_attr_cache_flush(git_repository *repo)
+{
+	git_attr_cache *cache;
+
+	/* this could be done less expensively, but for now, we'll just free
+	 * the entire attrcache and let the next use reinitialize it...
+	 */
+	if (repo && (cache = git__swap(repo->attrcache, NULL)) != NULL)
+		attr_cache__free(cache);
+}
+
+int git_attr_cache__insert_macro(git_repository *repo, git_attr_rule *macro)
+{
+	git_attr_cache *cache = git_repository_attr_cache(repo);
+	git_strmap *macros = cache->macros;
+	int error;
+
+	/* TODO: generate warning log if (macro->assigns.length == 0) */
+	if (macro->assigns.length == 0)
+		return 0;
+
+	if (git_mutex_lock(&cache->lock) < 0) {
+		giterr_set(GITERR_OS, "Unable to get attr cache lock");
+		error = -1;
+	} else {
+		git_strmap_insert(macros, macro->match.pattern, macro, error);
+		git_mutex_unlock(&cache->lock);
+	}
+
+	return (error < 0) ? -1 : 0;
+}
+
+git_attr_rule *git_attr_cache__lookup_macro(
+	git_repository *repo, const char *name)
+{
+	git_strmap *macros = git_repository_attr_cache(repo)->macros;
+	khiter_t pos;
+
+	pos = git_strmap_lookup_index(macros, name);
+
+	if (!git_strmap_valid_index(macros, pos))
+		return NULL;
+
+	return (git_attr_rule *)git_strmap_value_at(macros, pos);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attrcache.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attrcache.h
new file mode 100755
index 0000000..44e1ffd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/attrcache.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_attrcache_h__
+#define INCLUDE_attrcache_h__
+
+#include "attr_file.h"
+#include "strmap.h"
+
+#define GIT_ATTR_CONFIG       "core.attributesfile"
+#define GIT_IGNORE_CONFIG     "core.excludesfile"
+
+typedef struct {
+	char *cfg_attr_file; /* cached value of core.attributesfile */
+	char *cfg_excl_file; /* cached value of core.excludesfile */
+	git_strmap *files;	 /* hash path to git_attr_cache_entry records */
+	git_strmap *macros;	 /* hash name to vector<git_attr_assignment> */
+	git_mutex lock;
+	git_pool  pool;
+} git_attr_cache;
+
+extern int git_attr_cache__do_init(git_repository *repo);
+
+#define git_attr_cache__init(REPO) \
+	(git_repository_attr_cache(REPO) ? 0 : git_attr_cache__do_init(REPO))
+
+/* get file - loading and reload as needed */
+extern int git_attr_cache__get(
+	git_attr_file **file,
+	git_repository *repo,
+	git_attr_session *attr_session,
+	git_attr_file_source source,
+	const char *base,
+	const char *filename,
+	git_attr_file_parser parser);
+
+extern bool git_attr_cache__is_cached(
+	git_repository *repo,
+	git_attr_file_source source,
+	const char *path);
+
+extern int git_attr_cache__alloc_file_entry(
+	git_attr_file_entry **out,
+	const char *base,
+	const char *path,
+	git_pool *pool);
+
+extern int git_attr_cache__insert_macro(
+	git_repository *repo, git_attr_rule *macro);
+
+extern git_attr_rule *git_attr_cache__lookup_macro(
+	git_repository *repo, const char *name);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/bitvec.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/bitvec.h
new file mode 100755
index 0000000..544832d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/bitvec.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_bitvec_h__
+#define INCLUDE_bitvec_h__
+
+#include "common.h"
+
+/*
+ * This is a silly little fixed length bit vector type that will store
+ * vectors of 64 bits or less directly in the structure and allocate
+ * memory for vectors longer than 64 bits.  You can use the two versions
+ * transparently through the API and avoid heap allocation completely when
+ * using a short bit vector as a result.
+ */
+typedef struct {
+	size_t length;
+	union {
+		uint64_t *words;
+		uint64_t bits;
+	} u;
+} git_bitvec;
+
+GIT_INLINE(int) git_bitvec_init(git_bitvec *bv, size_t capacity)
+{
+	memset(bv, 0x0, sizeof(*bv));
+
+	if (capacity >= 64) {
+		bv->length = (capacity / 64) + 1;
+		bv->u.words = git__calloc(bv->length, sizeof(uint64_t));
+		if (!bv->u.words)
+			return -1;
+	}
+
+	return 0;
+}
+
+#define GIT_BITVEC_MASK(BIT) ((uint64_t)1 << (BIT % 64))
+#define GIT_BITVEC_WORD(BV, BIT) (BV->length ? &BV->u.words[BIT / 64] : &BV->u.bits)
+
+GIT_INLINE(void) git_bitvec_set(git_bitvec *bv, size_t bit, bool on)
+{
+	uint64_t *word = GIT_BITVEC_WORD(bv, bit);
+	uint64_t mask = GIT_BITVEC_MASK(bit);
+
+	if (on)
+		*word |= mask;
+	else
+		*word &= ~mask;
+}
+
+GIT_INLINE(bool) git_bitvec_get(git_bitvec *bv, size_t bit)
+{
+	uint64_t *word = GIT_BITVEC_WORD(bv, bit);
+	return (*word & GIT_BITVEC_MASK(bit)) != 0;
+}
+
+GIT_INLINE(void) git_bitvec_clear(git_bitvec *bv)
+{
+	if (!bv->length)
+		bv->u.bits = 0;
+	else
+		memset(bv->u.words, 0x0, bv->length * sizeof(uint64_t));
+}
+
+GIT_INLINE(void) git_bitvec_free(git_bitvec *bv)
+{
+	if (bv->length)
+		git__free(bv->u.words);
+}
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blame.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blame.c
new file mode 100755
index 0000000..08a90dc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blame.c
@@ -0,0 +1,511 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "blame.h"
+#include "git2/commit.h"
+#include "git2/revparse.h"
+#include "git2/revwalk.h"
+#include "git2/tree.h"
+#include "git2/diff.h"
+#include "git2/blob.h"
+#include "git2/signature.h"
+#include "util.h"
+#include "repository.h"
+#include "blame_git.h"
+
+
+static int hunk_byfinalline_search_cmp(const void *key, const void *entry)
+{
+	git_blame_hunk *hunk = (git_blame_hunk*)entry;
+
+	size_t lineno = *(size_t*)key;
+	size_t lines_in_hunk = (size_t)hunk->lines_in_hunk;
+	size_t final_start_line_number = (size_t)hunk->final_start_line_number;
+
+	if (lineno < final_start_line_number)
+		return -1;
+	if (lineno >= final_start_line_number + lines_in_hunk)
+		return 1;
+	return 0;
+}
+
+static int paths_cmp(const void *a, const void *b) { return git__strcmp((char*)a, (char*)b); }
+static int hunk_cmp(const void *_a, const void *_b)
+{
+	git_blame_hunk *a = (git_blame_hunk*)_a,
+						*b = (git_blame_hunk*)_b;
+
+	return a->final_start_line_number - b->final_start_line_number;
+}
+
+static bool hunk_ends_at_or_before_line(git_blame_hunk *hunk, size_t line)
+{
+	return line >= (size_t)(hunk->final_start_line_number + hunk->lines_in_hunk - 1);
+}
+
+static bool hunk_starts_at_or_after_line(git_blame_hunk *hunk, size_t line)
+{
+	return line <= hunk->final_start_line_number;
+}
+
+static git_blame_hunk* new_hunk(
+		uint16_t start,
+		uint16_t lines,
+		uint16_t orig_start,
+		const char *path)
+{
+	git_blame_hunk *hunk = git__calloc(1, sizeof(git_blame_hunk));
+	if (!hunk) return NULL;
+
+	hunk->lines_in_hunk = lines;
+	hunk->final_start_line_number = start;
+	hunk->orig_start_line_number = orig_start;
+	hunk->orig_path = path ? git__strdup(path) : NULL;
+
+	return hunk;
+}
+
+static git_blame_hunk* dup_hunk(git_blame_hunk *hunk)
+{
+	git_blame_hunk *newhunk = new_hunk(
+			hunk->final_start_line_number,
+			hunk->lines_in_hunk,
+			hunk->orig_start_line_number,
+			hunk->orig_path);
+
+	if (!newhunk)
+		return NULL;
+
+	git_oid_cpy(&newhunk->orig_commit_id, &hunk->orig_commit_id);
+	git_oid_cpy(&newhunk->final_commit_id, &hunk->final_commit_id);
+	newhunk->boundary = hunk->boundary;
+	git_signature_dup(&newhunk->final_signature, hunk->final_signature);
+	git_signature_dup(&newhunk->orig_signature, hunk->orig_signature);
+	return newhunk;
+}
+
+static void free_hunk(git_blame_hunk *hunk)
+{
+	git__free((void*)hunk->orig_path);
+	git_signature_free(hunk->final_signature);
+	git_signature_free(hunk->orig_signature);
+	git__free(hunk);
+}
+
+/* Starting with the hunk that includes start_line, shift all following hunks'
+ * final_start_line by shift_by lines */
+static void shift_hunks_by(git_vector *v, size_t start_line, int shift_by)
+{
+	size_t i;
+
+	if (!git_vector_bsearch2(&i, v, hunk_byfinalline_search_cmp, &start_line)) {
+		for (; i < v->length; i++) {
+			git_blame_hunk *hunk = (git_blame_hunk*)v->contents[i];
+			hunk->final_start_line_number += shift_by;
+		}
+	}
+}
+
+git_blame* git_blame__alloc(
+	git_repository *repo,
+	git_blame_options opts,
+	const char *path)
+{
+	git_blame *gbr = git__calloc(1, sizeof(git_blame));
+	if (!gbr)
+		return NULL;
+
+	gbr->repository = repo;
+	gbr->options = opts;
+
+	if (git_vector_init(&gbr->hunks, 8, hunk_cmp) < 0 ||
+		git_vector_init(&gbr->paths, 8, paths_cmp) < 0 ||
+		(gbr->path = git__strdup(path)) == NULL ||
+		git_vector_insert(&gbr->paths, git__strdup(path)) < 0)
+	{
+		git_blame_free(gbr);
+		return NULL;
+	}
+
+	return gbr;
+}
+
+void git_blame_free(git_blame *blame)
+{
+	size_t i;
+	git_blame_hunk *hunk;
+
+	if (!blame) return;
+
+	git_vector_foreach(&blame->hunks, i, hunk)
+		free_hunk(hunk);
+	git_vector_free(&blame->hunks);
+
+	git_vector_free_deep(&blame->paths);
+
+	git_array_clear(blame->line_index);
+
+	git__free(blame->path);
+	git_blob_free(blame->final_blob);
+	git__free(blame);
+}
+
+uint32_t git_blame_get_hunk_count(git_blame *blame)
+{
+	assert(blame);
+	return (uint32_t)blame->hunks.length;
+}
+
+const git_blame_hunk *git_blame_get_hunk_byindex(git_blame *blame, uint32_t index)
+{
+	assert(blame);
+	return (git_blame_hunk*)git_vector_get(&blame->hunks, index);
+}
+
+const git_blame_hunk *git_blame_get_hunk_byline(git_blame *blame, uint32_t lineno)
+{
+	size_t i, new_lineno = (size_t)lineno;
+	assert(blame);
+
+	if (!git_vector_bsearch2(&i, &blame->hunks, hunk_byfinalline_search_cmp, &new_lineno)) {
+		return git_blame_get_hunk_byindex(blame, (uint32_t)i);
+	}
+
+	return NULL;
+}
+
+static void normalize_options(
+		git_blame_options *out,
+		const git_blame_options *in,
+		git_repository *repo)
+{
+	git_blame_options dummy = GIT_BLAME_OPTIONS_INIT;
+	if (!in) in = &dummy;
+
+	memcpy(out, in, sizeof(git_blame_options));
+
+	/* No newest_commit => HEAD */
+	if (git_oid_iszero(&out->newest_commit)) {
+		git_reference_name_to_id(&out->newest_commit, repo, "HEAD");
+	}
+
+	/* min_line 0 really means 1 */
+	if (!out->min_line) out->min_line = 1;
+	/* max_line 0 really means N, but we don't know N yet */
+
+	/* Fix up option implications */
+	if (out->flags & GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES)
+		out->flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES;
+	if (out->flags & GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES)
+		out->flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES;
+	if (out->flags & GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES)
+		out->flags |= GIT_BLAME_TRACK_COPIES_SAME_FILE;
+}
+
+static git_blame_hunk *split_hunk_in_vector(
+		git_vector *vec,
+		git_blame_hunk *hunk,
+		size_t rel_line,
+		bool return_new)
+{
+	size_t new_line_count;
+	git_blame_hunk *nh;
+
+	/* Don't split if already at a boundary */
+	if (rel_line <= 0 ||
+	    rel_line >= hunk->lines_in_hunk)
+	{
+		return hunk;
+	}
+
+	new_line_count = hunk->lines_in_hunk - rel_line;
+	nh = new_hunk((uint16_t)(hunk->final_start_line_number+rel_line), (uint16_t)new_line_count,
+			(uint16_t)(hunk->orig_start_line_number+rel_line), hunk->orig_path);
+
+	if (!nh)
+		return NULL;
+
+	git_oid_cpy(&nh->final_commit_id, &hunk->final_commit_id);
+	git_oid_cpy(&nh->orig_commit_id, &hunk->orig_commit_id);
+
+	/* Adjust hunk that was split */
+	hunk->lines_in_hunk -= (uint16_t)new_line_count;
+	git_vector_insert_sorted(vec, nh, NULL);
+	{
+		git_blame_hunk *ret = return_new ? nh : hunk;
+		return ret;
+	}
+}
+
+/*
+ * Construct a list of char indices for where lines begin
+ * Adapted from core git:
+ * https://github.com/gitster/git/blob/be5c9fb9049ed470e7005f159bb923a5f4de1309/builtin/blame.c#L1760-L1789
+ */
+static int index_blob_lines(git_blame *blame)
+{
+    const char *buf = blame->final_buf;
+    git_off_t len = blame->final_buf_size;
+    int num = 0, incomplete = 0, bol = 1;
+    size_t *i;
+
+    if (len && buf[len-1] != '\n')
+        incomplete++; /* incomplete line at the end */
+    while (len--) {
+        if (bol) {
+            i = git_array_alloc(blame->line_index);
+            GITERR_CHECK_ALLOC(i);
+            *i = buf - blame->final_buf;
+            bol = 0;
+        }
+        if (*buf++ == '\n') {
+            num++;
+            bol = 1;
+        }
+    }
+    i = git_array_alloc(blame->line_index);
+    GITERR_CHECK_ALLOC(i);
+    *i = buf - blame->final_buf;
+    blame->num_lines = num + incomplete;
+    return blame->num_lines;
+}
+
+static git_blame_hunk* hunk_from_entry(git_blame__entry *e)
+{
+	git_blame_hunk *h = new_hunk(
+			e->lno+1, e->num_lines, e->s_lno+1, e->suspect->path);
+
+	if (!h)
+		return NULL;
+
+	git_oid_cpy(&h->final_commit_id, git_commit_id(e->suspect->commit));
+	git_oid_cpy(&h->orig_commit_id, git_commit_id(e->suspect->commit));
+	git_signature_dup(&h->final_signature, git_commit_author(e->suspect->commit));
+	git_signature_dup(&h->orig_signature, git_commit_author(e->suspect->commit));
+	h->boundary = e->is_boundary ? 1 : 0;
+	return h;
+}
+
+static int load_blob(git_blame *blame)
+{
+	int error;
+
+	if (blame->final_blob) return 0;
+
+	error = git_commit_lookup(&blame->final, blame->repository, &blame->options.newest_commit);
+	if (error < 0)
+		goto cleanup;
+	error = git_object_lookup_bypath((git_object**)&blame->final_blob,
+			(git_object*)blame->final, blame->path, GIT_OBJ_BLOB);
+
+cleanup:
+	return error;
+}
+
+static int blame_internal(git_blame *blame)
+{
+	int error;
+	git_blame__entry *ent = NULL;
+	git_blame__origin *o;
+
+	if ((error = load_blob(blame)) < 0 ||
+	    (error = git_blame__get_origin(&o, blame, blame->final, blame->path)) < 0)
+		goto cleanup;
+	blame->final_buf = git_blob_rawcontent(blame->final_blob);
+	blame->final_buf_size = git_blob_rawsize(blame->final_blob);
+
+	ent = git__calloc(1, sizeof(git_blame__entry));
+	GITERR_CHECK_ALLOC(ent);
+
+	ent->num_lines = index_blob_lines(blame);
+	ent->lno = blame->options.min_line - 1;
+	ent->num_lines = ent->num_lines - blame->options.min_line + 1;
+	if (blame->options.max_line > 0)
+		ent->num_lines = blame->options.max_line - blame->options.min_line + 1;
+	ent->s_lno = ent->lno;
+	ent->suspect = o;
+
+	blame->ent = ent;
+
+	error = git_blame__like_git(blame, blame->options.flags);
+
+cleanup:
+	for (ent = blame->ent; ent; ) {
+		git_blame__entry *e = ent->next;
+		git_blame_hunk *h = hunk_from_entry(ent);
+
+		git_vector_insert(&blame->hunks, h);
+
+		git_blame__free_entry(ent);
+		ent = e;
+	}
+
+	return error;
+}
+
+/*******************************************************************************
+ * File blaming
+ ******************************************************************************/
+
+int git_blame_file(
+		git_blame **out,
+		git_repository *repo,
+		const char *path,
+		git_blame_options *options)
+{
+	int error = -1;
+	git_blame_options normOptions = GIT_BLAME_OPTIONS_INIT;
+	git_blame *blame = NULL;
+
+	assert(out && repo && path);
+	normalize_options(&normOptions, options, repo);
+
+	blame = git_blame__alloc(repo, normOptions, path);
+	GITERR_CHECK_ALLOC(blame);
+
+	if ((error = load_blob(blame)) < 0)
+		goto on_error;
+
+	if ((error = blame_internal(blame)) < 0)
+		goto on_error;
+
+	*out = blame;
+	return 0;
+
+on_error:
+	git_blame_free(blame);
+	return error;
+}
+
+/*******************************************************************************
+ * Buffer blaming
+ *******************************************************************************/
+
+static bool hunk_is_bufferblame(git_blame_hunk *hunk)
+{
+	return git_oid_iszero(&hunk->final_commit_id);
+}
+
+static int buffer_hunk_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	void *payload)
+{
+	git_blame *blame = (git_blame*)payload;
+	uint32_t wedge_line;
+
+	GIT_UNUSED(delta);
+
+	wedge_line = (hunk->old_lines == 0) ? hunk->new_start : hunk->old_start;
+	blame->current_diff_line = wedge_line;
+
+	blame->current_hunk = (git_blame_hunk*)git_blame_get_hunk_byline(blame, wedge_line);
+	if (!blame->current_hunk) {
+		/* Line added at the end of the file */
+		blame->current_hunk = new_hunk(wedge_line, 0, wedge_line, blame->path);
+		GITERR_CHECK_ALLOC(blame->current_hunk);
+
+		git_vector_insert(&blame->hunks, blame->current_hunk);
+	} else if (!hunk_starts_at_or_after_line(blame->current_hunk, wedge_line)){
+		/* If this hunk doesn't start between existing hunks, split a hunk up so it does */
+		blame->current_hunk = split_hunk_in_vector(&blame->hunks, blame->current_hunk,
+				wedge_line - blame->current_hunk->orig_start_line_number, true);
+		GITERR_CHECK_ALLOC(blame->current_hunk);
+	}
+
+	return 0;
+}
+
+static int ptrs_equal_cmp(const void *a, const void *b) { return a<b ? -1 : a>b ? 1 : 0; }
+static int buffer_line_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *payload)
+{
+	git_blame *blame = (git_blame*)payload;
+
+	GIT_UNUSED(delta);
+	GIT_UNUSED(hunk);
+	GIT_UNUSED(line);
+
+	if (line->origin == GIT_DIFF_LINE_ADDITION) {
+		if (hunk_is_bufferblame(blame->current_hunk) &&
+		    hunk_ends_at_or_before_line(blame->current_hunk, blame->current_diff_line)) {
+			/* Append to the current buffer-blame hunk */
+			blame->current_hunk->lines_in_hunk++;
+			shift_hunks_by(&blame->hunks, blame->current_diff_line+1, 1);
+		} else {
+			/* Create a new buffer-blame hunk with this line */
+			shift_hunks_by(&blame->hunks, blame->current_diff_line, 1);
+			blame->current_hunk = new_hunk((uint16_t)blame->current_diff_line, 1, 0, blame->path);
+			GITERR_CHECK_ALLOC(blame->current_hunk);
+
+			git_vector_insert_sorted(&blame->hunks, blame->current_hunk, NULL);
+		}
+		blame->current_diff_line++;
+	}
+
+	if (line->origin == GIT_DIFF_LINE_DELETION) {
+		/* Trim the line from the current hunk; remove it if it's now empty */
+		size_t shift_base = blame->current_diff_line + blame->current_hunk->lines_in_hunk+1;
+
+		if (--(blame->current_hunk->lines_in_hunk) == 0) {
+			size_t i;
+			shift_base--;
+			if (!git_vector_search2(&i, &blame->hunks, ptrs_equal_cmp, blame->current_hunk)) {
+				git_vector_remove(&blame->hunks, i);
+				free_hunk(blame->current_hunk);
+				blame->current_hunk = (git_blame_hunk*)git_blame_get_hunk_byindex(blame, (uint32_t)i);
+			}
+		}
+		shift_hunks_by(&blame->hunks, shift_base, -1);
+	}
+	return 0;
+}
+
+int git_blame_buffer(
+		git_blame **out,
+		git_blame *reference,
+		const char *buffer,
+		size_t buffer_len)
+{
+	git_blame *blame;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	size_t i;
+	git_blame_hunk *hunk;
+
+	diffopts.context_lines = 0;
+
+	assert(out && reference && buffer && buffer_len);
+
+	blame = git_blame__alloc(reference->repository, reference->options, reference->path);
+	GITERR_CHECK_ALLOC(blame);
+
+	/* Duplicate all of the hunk structures in the reference blame */
+	git_vector_foreach(&reference->hunks, i, hunk) {
+		git_blame_hunk *h = dup_hunk(hunk);
+		GITERR_CHECK_ALLOC(h);
+
+		git_vector_insert(&blame->hunks, h);
+	}
+
+	/* Diff to the reference blob */
+	git_diff_blob_to_buffer(reference->final_blob, blame->path,
+		buffer, buffer_len, blame->path, &diffopts,
+		NULL, NULL, buffer_hunk_cb, buffer_line_cb, blame);
+
+	*out = blame;
+	return 0;
+}
+
+int git_blame_init_options(git_blame_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_blame_options, GIT_BLAME_OPTIONS_INIT);
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blame.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blame.h
new file mode 100755
index 0000000..7e23de8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blame.h
@@ -0,0 +1,93 @@
+#ifndef INCLUDE_blame_h__
+#define INCLUDE_blame_h__
+
+#include "git2/blame.h"
+#include "common.h"
+#include "vector.h"
+#include "diff.h"
+#include "array.h"
+#include "git2/oid.h"
+
+/*
+ * One blob in a commit that is being suspected
+ */
+typedef struct git_blame__origin {
+	int refcnt;
+	struct git_blame__origin *previous;
+	git_commit *commit;
+	git_blob *blob;
+	char path[GIT_FLEX_ARRAY];
+} git_blame__origin;
+
+/*
+ * Each group of lines is described by a git_blame__entry; it can be split
+ * as we pass blame to the parents.  They form a linked list in the
+ * scoreboard structure, sorted by the target line number.
+ */
+typedef struct git_blame__entry {
+	struct git_blame__entry *prev;
+	struct git_blame__entry *next;
+
+	/* the first line of this group in the final image;
+	 * internally all line numbers are 0 based.
+	 */
+	int lno;
+
+	/* how many lines this group has */
+	int num_lines;
+
+	/* the commit that introduced this group into the final image */
+	git_blame__origin *suspect;
+
+	/* true if the suspect is truly guilty; false while we have not
+	 * checked if the group came from one of its parents.
+	 */
+	bool guilty;
+
+	/* true if the entry has been scanned for copies in the current parent
+	 */
+	bool scanned;
+
+	/* the line number of the first line of this group in the
+	 * suspect's file; internally all line numbers are 0 based.
+	 */
+	int s_lno;
+
+	/* how significant this entry is -- cached to avoid
+	 * scanning the lines over and over.
+	 */
+	unsigned score;
+
+	/* Whether this entry has been tracked to a boundary commit.
+	 */
+	bool is_boundary;
+} git_blame__entry;
+
+struct git_blame {
+	char *path;
+	git_repository *repository;
+	git_blame_options options;
+
+	git_vector hunks;
+	git_vector paths;
+
+	git_blob *final_blob;
+	git_array_t(size_t) line_index;
+
+	size_t current_diff_line;
+	git_blame_hunk *current_hunk;
+
+	/* Scoreboard fields */
+	git_commit *final;
+	git_blame__entry *ent;
+	int num_lines;
+	const char *final_buf;
+	git_off_t final_buf_size;
+};
+
+git_blame *git_blame__alloc(
+	git_repository *repo,
+	git_blame_options opts,
+	const char *path);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blame_git.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blame_git.c
new file mode 100755
index 0000000..67bae23
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blame_git.c
@@ -0,0 +1,643 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "blame_git.h"
+#include "commit.h"
+#include "blob.h"
+#include "xdiff/xinclude.h"
+#include "diff_xdiff.h"
+
+/*
+ * Origin is refcounted and usually we keep the blob contents to be
+ * reused.
+ */
+static git_blame__origin *origin_incref(git_blame__origin *o)
+{
+	if (o)
+		o->refcnt++;
+	return o;
+}
+
+static void origin_decref(git_blame__origin *o)
+{
+	if (o && --o->refcnt <= 0) {
+		if (o->previous)
+			origin_decref(o->previous);
+		git_blob_free(o->blob);
+		git_commit_free(o->commit);
+		git__free(o);
+	}
+}
+
+/* Given a commit and a path in it, create a new origin structure. */
+static int make_origin(git_blame__origin **out, git_commit *commit, const char *path)
+{
+	git_blame__origin *o;
+	size_t path_len = strlen(path), alloc_len;
+	int error = 0;
+
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, sizeof(*o), path_len);
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 1);
+	o = git__calloc(1, alloc_len);
+	GITERR_CHECK_ALLOC(o);
+
+	o->commit = commit;
+	o->refcnt = 1;
+	strcpy(o->path, path);
+
+	if (!(error = git_object_lookup_bypath((git_object**)&o->blob, (git_object*)commit,
+			path, GIT_OBJ_BLOB))) {
+		*out = o;
+	} else {
+		origin_decref(o);
+	}
+	return error;
+}
+
+/* Locate an existing origin or create a new one. */
+int git_blame__get_origin(
+		git_blame__origin **out,
+		git_blame *blame,
+		git_commit *commit,
+		const char *path)
+{
+	git_blame__entry *e;
+
+	for (e = blame->ent; e; e = e->next) {
+		if (e->suspect->commit == commit && !strcmp(e->suspect->path, path)) {
+			*out = origin_incref(e->suspect);
+		}
+	}
+	return make_origin(out, commit, path);
+}
+
+typedef struct blame_chunk_cb_data {
+	git_blame *blame;
+	git_blame__origin *target;
+	git_blame__origin *parent;
+	long tlno;
+	long plno;
+}blame_chunk_cb_data;
+
+static bool same_suspect(git_blame__origin *a, git_blame__origin *b)
+{
+	if (a == b)
+		return true;
+	if (git_oid_cmp(git_commit_id(a->commit), git_commit_id(b->commit)))
+		return false;
+	return 0 == strcmp(a->path, b->path);
+}
+
+/* find the line number of the last line the target is suspected for */
+static int find_last_in_target(git_blame *blame, git_blame__origin *target)
+{
+	git_blame__entry *e;
+	int last_in_target = -1;
+
+	for (e=blame->ent; e; e=e->next) {
+		if (e->guilty || !same_suspect(e->suspect, target))
+			continue;
+		if (last_in_target < e->s_lno + e->num_lines)
+			last_in_target = e->s_lno + e->num_lines;
+	}
+	return last_in_target;
+}
+
+/*
+ * It is known that lines between tlno to same came from parent, and e
+ * has an overlap with that range.  it also is known that parent's
+ * line plno corresponds to e's line tlno.
+ *
+ *                <---- e ----->
+ *                   <------>         (entirely within)
+ *                   <------------>   (extends past)
+ *             <------------>         (starts before)
+ *             <------------------>   (entirely encloses)
+ *
+ * Split e into potentially three parts; before this chunk, the chunk
+ * to be blamed for the parent, and after that portion.
+ */
+static void split_overlap(git_blame__entry *split, git_blame__entry *e,
+		int tlno, int plno, int same, git_blame__origin *parent)
+{
+	int chunk_end_lno;
+
+	if (e->s_lno < tlno) {
+		/* there is a pre-chunk part not blamed on the parent */
+		split[0].suspect = origin_incref(e->suspect);
+		split[0].lno = e->lno;
+		split[0].s_lno = e->s_lno;
+		split[0].num_lines = tlno - e->s_lno;
+		split[1].lno = e->lno + tlno - e->s_lno;
+		split[1].s_lno = plno;
+	} else {
+		split[1].lno = e->lno;
+		split[1].s_lno = plno + (e->s_lno - tlno);
+	}
+
+	if (same < e->s_lno + e->num_lines) {
+		/* there is a post-chunk part not blamed on parent */
+		split[2].suspect = origin_incref(e->suspect);
+		split[2].lno = e->lno + (same - e->s_lno);
+		split[2].s_lno = e->s_lno + (same - e->s_lno);
+		split[2].num_lines = e->s_lno + e->num_lines - same;
+		chunk_end_lno = split[2].lno;
+	} else {
+		chunk_end_lno = e->lno + e->num_lines;
+	}
+	split[1].num_lines = chunk_end_lno - split[1].lno;
+
+	/*
+	 * if it turns out there is nothing to blame the parent for, forget about
+	 * the splitting. !split[1].suspect signals this.
+	 */
+	if (split[1].num_lines < 1)
+		return;
+	split[1].suspect = origin_incref(parent);
+}
+
+/*
+ * Link in a new blame entry to the scoreboard. Entries that cover the same
+ * line range have been removed from the scoreboard previously.
+ */
+static void add_blame_entry(git_blame *blame, git_blame__entry *e)
+{
+	git_blame__entry *ent, *prev = NULL;
+
+	origin_incref(e->suspect);
+
+	for (ent = blame->ent; ent && ent->lno < e->lno; ent = ent->next)
+		prev = ent;
+
+	/* prev, if not NULL, is the last one that is below e */
+	e->prev = prev;
+	if (prev) {
+		e->next = prev->next;
+		prev->next = e;
+	} else {
+		e->next = blame->ent;
+		blame->ent = e;
+	}
+	if (e->next)
+		e->next->prev = e;
+}
+
+/*
+ * src typically is on-stack; we want to copy the information in it to
+ * a malloced blame_entry that is already on the linked list of the scoreboard.
+ * The origin of dst loses a refcnt while the origin of src gains one.
+ */
+static void dup_entry(git_blame__entry *dst, git_blame__entry *src)
+{
+	git_blame__entry *p, *n;
+
+	p = dst->prev;
+	n = dst->next;
+	origin_incref(src->suspect);
+	origin_decref(dst->suspect);
+	memcpy(dst, src, sizeof(*src));
+	dst->prev = p;
+	dst->next = n;
+	dst->score = 0;
+}
+
+/*
+ * split_overlap() divided an existing blame e into up to three parts in split.
+ * Adjust the linked list of blames in the scoreboard to reflect the split.
+ */
+static void split_blame(git_blame *blame, git_blame__entry *split, git_blame__entry *e)
+{
+	git_blame__entry *new_entry;
+
+	if (split[0].suspect && split[2].suspect) {
+		/* The first part (reuse storage for the existing entry e */
+		dup_entry(e, &split[0]);
+
+		/* The last part -- me */
+		new_entry = git__malloc(sizeof(*new_entry));
+		memcpy(new_entry, &(split[2]), sizeof(git_blame__entry));
+		add_blame_entry(blame, new_entry);
+
+		/* ... and the middle part -- parent */
+		new_entry = git__malloc(sizeof(*new_entry));
+		memcpy(new_entry, &(split[1]), sizeof(git_blame__entry));
+		add_blame_entry(blame, new_entry);
+	} else if (!split[0].suspect && !split[2].suspect) {
+		/*
+		 * The parent covers the entire area; reuse storage for e and replace it
+		 * with the parent
+		 */
+		dup_entry(e, &split[1]);
+	} else if (split[0].suspect) {
+		/* me and then parent */
+		dup_entry(e, &split[0]);
+		new_entry = git__malloc(sizeof(*new_entry));
+		memcpy(new_entry, &(split[1]), sizeof(git_blame__entry));
+		add_blame_entry(blame, new_entry);
+	} else {
+		/* parent and then me */
+		dup_entry(e, &split[1]);
+		new_entry = git__malloc(sizeof(*new_entry));
+		memcpy(new_entry, &(split[2]), sizeof(git_blame__entry));
+		add_blame_entry(blame, new_entry);
+	}
+}
+
+/* 
+ * After splitting the blame, the origins used by the on-stack blame_entry
+ * should lose one refcnt each.
+ */
+static void decref_split(git_blame__entry *split)
+{
+	int i;
+	for (i=0; i<3; i++)
+		origin_decref(split[i].suspect);
+}
+
+/*
+ * Helper for blame_chunk(). blame_entry e is known to overlap with the patch
+ * hunk; split it and pass blame to the parent.
+ */
+static void blame_overlap(
+		git_blame *blame,
+		git_blame__entry *e,
+		int tlno,
+		int plno,
+		int same,
+		git_blame__origin *parent)
+{
+	git_blame__entry split[3] = {{0}};
+
+	split_overlap(split, e, tlno, plno, same, parent);
+	if (split[1].suspect)
+		split_blame(blame, split, e);
+	decref_split(split);
+}
+
+/*
+ * Process one hunk from the patch between the current suspect for blame_entry
+ * e and its parent. Find and split the overlap, and pass blame to the
+ * overlapping part to the parent.
+ */
+static void blame_chunk(
+		git_blame *blame,
+		int tlno,
+		int plno,
+		int same,
+		git_blame__origin *target,
+		git_blame__origin *parent)
+{
+	git_blame__entry *e;
+
+	for (e = blame->ent; e; e = e->next) {
+		if (e->guilty || !same_suspect(e->suspect, target))
+			continue;
+		if (same <= e->s_lno)
+			continue;
+		if (tlno < e->s_lno + e->num_lines) {
+			blame_overlap(blame, e, tlno, plno, same, parent);
+		}
+	}
+}
+
+static int my_emit(
+	long start_a, long count_a,
+	long start_b, long count_b,
+	void *cb_data)
+{
+	blame_chunk_cb_data *d = (blame_chunk_cb_data *)cb_data;
+
+	blame_chunk(d->blame, d->tlno, d->plno, start_b, d->target, d->parent);
+	d->plno = start_a + count_a;
+	d->tlno = start_b + count_b;
+	
+	return 0;
+}
+
+static void trim_common_tail(mmfile_t *a, mmfile_t *b, long ctx)
+{
+	const int blk = 1024;
+	long trimmed = 0, recovered = 0;
+	char *ap = a->ptr + a->size;
+	char *bp = b->ptr + b->size;
+	long smaller = (long)((a->size < b->size) ? a->size : b->size);
+
+	if (ctx)
+		return;
+
+	while (blk + trimmed <= smaller && !memcmp(ap - blk, bp - blk, blk)) {
+		trimmed += blk;
+		ap -= blk;
+		bp -= blk;
+	}
+
+	while (recovered < trimmed)
+		if (ap[recovered++] == '\n')
+			break;
+	a->size -= trimmed - recovered;
+	b->size -= trimmed - recovered;
+}
+
+static int diff_hunks(mmfile_t file_a, mmfile_t file_b, void *cb_data)
+{
+	xpparam_t xpp = {0};
+	xdemitconf_t xecfg = {0};
+	xdemitcb_t ecb = {0};
+
+	xecfg.hunk_func = my_emit;
+	ecb.priv = cb_data;
+
+	trim_common_tail(&file_a, &file_b, 0);
+
+	if (file_a.size > GIT_XDIFF_MAX_SIZE ||
+		file_b.size > GIT_XDIFF_MAX_SIZE) {
+		giterr_set(GITERR_INVALID, "file too large to blame");
+		return -1;
+	}
+
+	return xdl_diff(&file_a, &file_b, &xpp, &xecfg, &ecb);
+}
+
+static void fill_origin_blob(git_blame__origin *o, mmfile_t *file)
+{
+	memset(file, 0, sizeof(*file));
+	if (o->blob) {
+		file->ptr = (char*)git_blob_rawcontent(o->blob);
+		file->size = (size_t)git_blob_rawsize(o->blob);
+	}
+}
+
+static int pass_blame_to_parent(
+		git_blame *blame,
+		git_blame__origin *target,
+		git_blame__origin *parent)
+{
+	int last_in_target;
+	mmfile_t file_p, file_o;
+	blame_chunk_cb_data d = { blame, target, parent, 0, 0 };
+
+	last_in_target = find_last_in_target(blame, target);
+	if (last_in_target < 0)
+		return 1; /* nothing remains for this target */
+
+	fill_origin_blob(parent, &file_p);
+	fill_origin_blob(target, &file_o);
+
+	if (diff_hunks(file_p, file_o, &d) < 0)
+		return -1;
+
+	/* The reset (i.e. anything after tlno) are the same as the parent */
+	blame_chunk(blame, d.tlno, d.plno, last_in_target, target, parent);
+
+	return 0;
+}
+
+static int paths_on_dup(void **old, void *new)
+{
+	GIT_UNUSED(old);
+	git__free(new);
+	return -1;
+}
+
+static git_blame__origin* find_origin(
+		git_blame *blame,
+		git_commit *parent,
+		git_blame__origin *origin)
+{
+	git_blame__origin *porigin = NULL;
+	git_diff *difflist = NULL;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_tree *otree=NULL, *ptree=NULL;
+
+	/* Get the trees from this commit and its parent */
+	if (0 != git_commit_tree(&otree, origin->commit) ||
+	    0 != git_commit_tree(&ptree, parent))
+		goto cleanup;
+
+	/* Configure the diff */
+	diffopts.context_lines = 0;
+	diffopts.flags = GIT_DIFF_SKIP_BINARY_CHECK;
+
+	/* Check to see if files we're interested have changed */
+	diffopts.pathspec.count = blame->paths.length;
+	diffopts.pathspec.strings = (char**)blame->paths.contents;
+	if (0 != git_diff_tree_to_tree(&difflist, blame->repository, ptree, otree, &diffopts))
+			goto cleanup;
+
+	if (!git_diff_num_deltas(difflist)) {
+		/* No changes; copy data */
+		git_blame__get_origin(&porigin, blame, parent, origin->path);
+	} else {
+		git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT;
+		int i;
+
+		/* Generate a full diff between the two trees */
+		git_diff_free(difflist);
+		diffopts.pathspec.count = 0;
+		if (0 != git_diff_tree_to_tree(&difflist, blame->repository, ptree, otree, &diffopts))
+			goto cleanup;
+
+		/* Let diff find renames */
+		findopts.flags = GIT_DIFF_FIND_RENAMES;
+		if (0 != git_diff_find_similar(difflist, &findopts))
+			goto cleanup;
+
+		/* Find one that matches */
+		for (i=0; i<(int)git_diff_num_deltas(difflist); i++) {
+			const git_diff_delta *delta = git_diff_get_delta(difflist, i);
+
+			if (!git_vector_bsearch(NULL, &blame->paths, delta->new_file.path))
+			{
+				git_vector_insert_sorted(&blame->paths, (void*)git__strdup(delta->old_file.path),
+						paths_on_dup);
+				make_origin(&porigin, parent, delta->old_file.path);
+			}
+		}
+	}
+
+cleanup:
+	git_diff_free(difflist);
+	git_tree_free(otree);
+	git_tree_free(ptree);
+	return porigin;
+}
+
+/*
+ * The blobs of origin and porigin exactly match, so everything origin is
+ * suspected for can be blamed on the parent.
+ */
+static void pass_whole_blame(git_blame *blame,
+		git_blame__origin *origin, git_blame__origin *porigin)
+{
+	git_blame__entry *e;
+
+	if (!porigin->blob)
+		git_object_lookup((git_object**)&porigin->blob, blame->repository,
+				git_blob_id(origin->blob), GIT_OBJ_BLOB);
+	for (e=blame->ent; e; e=e->next) {
+		if (!same_suspect(e->suspect, origin))
+			continue;
+		origin_incref(porigin);
+		origin_decref(e->suspect);
+		e->suspect = porigin;
+	}
+}
+
+static int pass_blame(git_blame *blame, git_blame__origin *origin, uint32_t opt)
+{
+	git_commit *commit = origin->commit;
+	int i, num_parents;
+	git_blame__origin *sg_buf[16];
+	git_blame__origin *porigin, **sg_origin = sg_buf;
+	int ret, error = 0;
+
+	num_parents = git_commit_parentcount(commit);
+	if (!git_oid_cmp(git_commit_id(commit), &blame->options.oldest_commit))
+		/* Stop at oldest specified commit */
+		num_parents = 0;
+	else if (opt & GIT_BLAME_FIRST_PARENT && num_parents > 1)
+		/* Limit search to the first parent */
+		num_parents = 1;
+
+	if (!num_parents) {
+		git_oid_cpy(&blame->options.oldest_commit, git_commit_id(commit));
+		goto finish;
+	}
+	else if (num_parents < (int)ARRAY_SIZE(sg_buf))
+		memset(sg_buf, 0, sizeof(sg_buf));
+	else
+		sg_origin = git__calloc(num_parents, sizeof(*sg_origin));
+
+	for (i=0; i<num_parents; i++) {
+		git_commit *p;
+		int j, same;
+
+		if (sg_origin[i])
+			continue;
+
+		git_commit_parent(&p, origin->commit, i);
+		porigin = find_origin(blame, p, origin);
+
+		if (!porigin)
+			continue;
+		if (porigin->blob && origin->blob &&
+		    !git_oid_cmp(git_blob_id(porigin->blob), git_blob_id(origin->blob))) {
+			pass_whole_blame(blame, origin, porigin);
+			origin_decref(porigin);
+			goto finish;
+		}
+		for (j = same = 0; j<i; j++)
+			if (sg_origin[j] &&
+				 !git_oid_cmp(git_blob_id(sg_origin[j]->blob), git_blob_id(porigin->blob))) {
+				same = 1;
+				break;
+			}
+		if (!same)
+			sg_origin[i] = porigin;
+		else
+			origin_decref(porigin);
+	}
+
+	/* Standard blame */
+	for (i=0; i<num_parents; i++) {
+		git_blame__origin *porigin = sg_origin[i];
+		if (!porigin)
+			continue;
+		if (!origin->previous) {
+			origin_incref(porigin);
+			origin->previous = porigin;
+		}
+
+		if ((ret = pass_blame_to_parent(blame, origin, porigin)) != 0) {
+			if (ret < 0)
+				error = -1;
+
+			goto finish;
+		}
+	}
+
+	/* TODO: optionally find moves in parents' files */
+
+	/* TODO: optionally find copies in parents' files */
+
+finish:
+	for (i=0; i<num_parents; i++)
+		if (sg_origin[i])
+			origin_decref(sg_origin[i]);
+	if (sg_origin != sg_buf)
+		git__free(sg_origin);
+	return error;
+}
+
+/*
+ * If two blame entries that are next to each other came from
+ * contiguous lines in the same origin (i.e. <commit, path> pair),
+ * merge them together.
+ */
+static void coalesce(git_blame *blame)
+{
+	git_blame__entry *ent, *next;
+
+	for (ent=blame->ent; ent && (next = ent->next); ent = next) {
+		if (same_suspect(ent->suspect, next->suspect) &&
+		    ent->guilty == next->guilty &&
+		    ent->s_lno + ent->num_lines == next->s_lno)
+		{
+			ent->num_lines += next->num_lines;
+			ent->next = next->next;
+			if (ent->next)
+				ent->next->prev = ent;
+			origin_decref(next->suspect);
+			git__free(next);
+			ent->score = 0;
+			next = ent; /* again */
+		}
+	}
+}
+
+int git_blame__like_git(git_blame *blame, uint32_t opt)
+{
+	while (true) {
+		git_blame__entry *ent;
+		git_blame__origin *suspect = NULL;
+
+		/* Find a suspect to break down */
+		for (ent = blame->ent; !suspect && ent; ent = ent->next)
+			if (!ent->guilty)
+				suspect = ent->suspect;
+		if (!suspect)
+			return 0; /* all done */
+
+		/* We'll use this suspect later in the loop, so hold on to it for now. */
+		origin_incref(suspect);
+
+		if (pass_blame(blame, suspect, opt) < 0)
+			return -1;
+
+		/* Take responsibility for the remaining entries */
+		for (ent = blame->ent; ent; ent = ent->next) {
+			if (same_suspect(ent->suspect, suspect)) {
+				ent->guilty = true;
+				ent->is_boundary = !git_oid_cmp(
+						git_commit_id(suspect->commit),
+						&blame->options.oldest_commit);
+			}
+		}
+		origin_decref(suspect);
+	}
+
+	coalesce(blame);
+
+	return 0;
+}
+
+void git_blame__free_entry(git_blame__entry *ent)
+{
+	if (!ent) return;
+	origin_decref(ent->suspect);
+	git__free(ent);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blame_git.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blame_git.h
new file mode 100755
index 0000000..1891b0e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blame_git.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_blame_git__
+#define INCLUDE_blame_git__
+
+#include "blame.h"
+
+int git_blame__get_origin(
+		git_blame__origin **out,
+		git_blame *sb,
+		git_commit *commit,
+		const char *path);
+void git_blame__free_entry(git_blame__entry *ent);
+int git_blame__like_git(git_blame *sb, uint32_t flags);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blob.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blob.c
new file mode 100755
index 0000000..ad0f4ac
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blob.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2/common.h"
+#include "git2/object.h"
+#include "git2/repository.h"
+#include "git2/odb_backend.h"
+
+#include "common.h"
+#include "filebuf.h"
+#include "blob.h"
+#include "filter.h"
+#include "buf_text.h"
+
+const void *git_blob_rawcontent(const git_blob *blob)
+{
+	assert(blob);
+	return git_odb_object_data(blob->odb_object);
+}
+
+git_off_t git_blob_rawsize(const git_blob *blob)
+{
+	assert(blob);
+	return (git_off_t)git_odb_object_size(blob->odb_object);
+}
+
+int git_blob__getbuf(git_buf *buffer, git_blob *blob)
+{
+	return git_buf_set(
+		buffer,
+		git_odb_object_data(blob->odb_object),
+		git_odb_object_size(blob->odb_object));
+}
+
+void git_blob__free(void *blob)
+{
+	git_odb_object_free(((git_blob *)blob)->odb_object);
+	git__free(blob);
+}
+
+int git_blob__parse(void *blob, git_odb_object *odb_obj)
+{
+	assert(blob);
+	git_cached_obj_incref((git_cached_obj *)odb_obj);
+	((git_blob *)blob)->odb_object = odb_obj;
+	return 0;
+}
+
+int git_blob_create_frombuffer(
+	git_oid *id, git_repository *repo, const void *buffer, size_t len)
+{
+	int error;
+	git_odb *odb;
+	git_odb_stream *stream;
+
+	assert(id && repo);
+
+	if ((error = git_repository_odb__weakptr(&odb, repo)) < 0 ||
+		(error = git_odb_open_wstream(&stream, odb, len, GIT_OBJ_BLOB)) < 0)
+		return error;
+
+	if ((error = git_odb_stream_write(stream, buffer, len)) == 0)
+		error = git_odb_stream_finalize_write(id, stream);
+
+	git_odb_stream_free(stream);
+	return error;
+}
+
+static int write_file_stream(
+	git_oid *id, git_odb *odb, const char *path, git_off_t file_size)
+{
+	int fd, error;
+	char buffer[FILEIO_BUFSIZE];
+	git_odb_stream *stream = NULL;
+	ssize_t read_len = -1;
+	git_off_t written = 0;
+
+	if ((error = git_odb_open_wstream(
+			&stream, odb, file_size, GIT_OBJ_BLOB)) < 0)
+		return error;
+
+	if ((fd = git_futils_open_ro(path)) < 0) {
+		git_odb_stream_free(stream);
+		return -1;
+	}
+
+	while (!error && (read_len = p_read(fd, buffer, sizeof(buffer))) > 0) {
+		error = git_odb_stream_write(stream, buffer, read_len);
+		written += read_len;
+	}
+
+	p_close(fd);
+
+	if (written != file_size || read_len < 0) {
+		giterr_set(GITERR_OS, "Failed to read file into stream");
+		error = -1;
+	}
+
+	if (!error)
+		error = git_odb_stream_finalize_write(id, stream);
+
+	git_odb_stream_free(stream);
+	return error;
+}
+
+static int write_file_filtered(
+	git_oid *id,
+	git_off_t *size,
+	git_odb *odb,
+	const char *full_path,
+	git_filter_list *fl)
+{
+	int error;
+	git_buf tgt = GIT_BUF_INIT;
+
+	error = git_filter_list_apply_to_file(&tgt, fl, NULL, full_path);
+
+	/* Write the file to disk if it was properly filtered */
+	if (!error) {
+		*size = tgt.size;
+
+		error = git_odb_write(id, odb, tgt.ptr, tgt.size, GIT_OBJ_BLOB);
+	}
+
+	git_buf_free(&tgt);
+	return error;
+}
+
+static int write_symlink(
+	git_oid *id, git_odb *odb, const char *path, size_t link_size)
+{
+	char *link_data;
+	ssize_t read_len;
+	int error;
+
+	link_data = git__malloc(link_size);
+	GITERR_CHECK_ALLOC(link_data);
+
+	read_len = p_readlink(path, link_data, link_size);
+	if (read_len != (ssize_t)link_size) {
+		giterr_set(GITERR_OS, "Failed to create blob.  Can't read symlink '%s'", path);
+		git__free(link_data);
+		return -1;
+	}
+
+	error = git_odb_write(id, odb, (void *)link_data, link_size, GIT_OBJ_BLOB);
+	git__free(link_data);
+	return error;
+}
+
+int git_blob__create_from_paths(
+	git_oid *id,
+	struct stat *out_st,
+	git_repository *repo,
+	const char *content_path,
+	const char *hint_path,
+	mode_t hint_mode,
+	bool try_load_filters)
+{
+	int error;
+	struct stat st;
+	git_odb *odb = NULL;
+	git_off_t size;
+	mode_t mode;
+	git_buf path = GIT_BUF_INIT;
+
+	assert(hint_path || !try_load_filters);
+
+	if (!content_path) {
+		if (git_repository__ensure_not_bare(repo, "create blob from file") < 0)
+			return GIT_EBAREREPO;
+
+		if (git_buf_joinpath(
+				&path, git_repository_workdir(repo), hint_path) < 0)
+			return -1;
+
+		content_path = path.ptr;
+	}
+
+	if ((error = git_path_lstat(content_path, &st)) < 0 ||
+		(error = git_repository_odb(&odb, repo)) < 0)
+		goto done;
+
+	if (S_ISDIR(st.st_mode)) {
+		giterr_set(GITERR_ODB, "cannot create blob from '%s'; it is a directory", content_path);
+		error = GIT_EDIRECTORY;
+		goto done;
+	}
+
+	if (out_st)
+		memcpy(out_st, &st, sizeof(st));
+
+	size = st.st_size;
+	mode = hint_mode ? hint_mode : st.st_mode;
+
+	if (S_ISLNK(mode)) {
+		error = write_symlink(id, odb, content_path, (size_t)size);
+	} else {
+		git_filter_list *fl = NULL;
+
+		if (try_load_filters)
+			/* Load the filters for writing this file to the ODB */
+			error = git_filter_list_load(
+				&fl, repo, NULL, hint_path,
+				GIT_FILTER_TO_ODB, GIT_FILTER_DEFAULT);
+
+		if (error < 0)
+			/* well, that didn't work */;
+		else if (fl == NULL)
+			/* No filters need to be applied to the document: we can stream
+			 * directly from disk */
+			error = write_file_stream(id, odb, content_path, size);
+		else {
+			/* We need to apply one or more filters */
+			error = write_file_filtered(id, &size, odb, content_path, fl);
+
+			git_filter_list_free(fl);
+		}
+
+		/*
+		 * TODO: eventually support streaming filtered files, for files
+		 * which are bigger than a given threshold. This is not a priority
+		 * because applying a filter in streaming mode changes the final
+		 * size of the blob, and without knowing its final size, the blob
+		 * cannot be written in stream mode to the ODB.
+		 *
+		 * The plan is to do streaming writes to a tempfile on disk and then
+		 * opening streaming that file to the ODB, using
+		 * `write_file_stream`.
+		 *
+		 * CAREFULLY DESIGNED APIS YO
+		 */
+	}
+
+done:
+	git_odb_free(odb);
+	git_buf_free(&path);
+
+	return error;
+}
+
+int git_blob_create_fromworkdir(
+	git_oid *id, git_repository *repo, const char *path)
+{
+	return git_blob__create_from_paths(id, NULL, repo, NULL, path, 0, true);
+}
+
+int git_blob_create_fromdisk(
+	git_oid *id, git_repository *repo, const char *path)
+{
+	int error;
+	git_buf full_path = GIT_BUF_INIT;
+	const char *workdir, *hintpath;
+
+	if ((error = git_path_prettify(&full_path, path, NULL)) < 0) {
+		git_buf_free(&full_path);
+		return error;
+	}
+
+	hintpath = git_buf_cstr(&full_path);
+	workdir  = git_repository_workdir(repo);
+
+	if (workdir && !git__prefixcmp(hintpath, workdir))
+		hintpath += strlen(workdir);
+
+	error = git_blob__create_from_paths(
+		id, NULL, repo, git_buf_cstr(&full_path), hintpath, 0, true);
+
+	git_buf_free(&full_path);
+	return error;
+}
+
+#define BUFFER_SIZE 4096
+
+int git_blob_create_fromchunks(
+	git_oid *id,
+	git_repository *repo,
+	const char *hintpath,
+	int (*source_cb)(char *content, size_t max_length, void *payload),
+	void *payload)
+{
+	int error;
+	char *content = NULL;
+	git_filebuf file = GIT_FILEBUF_INIT;
+	git_buf path = GIT_BUF_INIT;
+
+	assert(id && repo && source_cb);
+
+	if ((error = git_buf_joinpath(
+			&path, git_repository_path(repo), GIT_OBJECTS_DIR "streamed")) < 0)
+		goto cleanup;
+
+	content = git__malloc(BUFFER_SIZE);
+	GITERR_CHECK_ALLOC(content);
+
+	if ((error = git_filebuf_open(
+			&file, git_buf_cstr(&path), GIT_FILEBUF_TEMPORARY, 0666)) < 0)
+		goto cleanup;
+
+	while (1) {
+		int read_bytes = source_cb(content, BUFFER_SIZE, payload);
+
+		if (!read_bytes)
+			break;
+
+		if (read_bytes > BUFFER_SIZE) {
+			giterr_set(GITERR_OBJECT, "Invalid chunk size while creating blob");
+			error = GIT_EBUFS;
+		} else if (read_bytes < 0) {
+			error = giterr_set_after_callback(read_bytes);
+		} else {
+			error = git_filebuf_write(&file, content, read_bytes);
+		}
+
+		if (error < 0)
+			goto cleanup;
+	}
+
+	if ((error = git_filebuf_flush(&file)) < 0)
+		goto cleanup;
+
+	error = git_blob__create_from_paths(
+		id, NULL, repo, file.path_lock, hintpath, 0, hintpath != NULL);
+
+cleanup:
+	git_buf_free(&path);
+	git_filebuf_cleanup(&file);
+	git__free(content);
+
+	return error;
+}
+
+int git_blob_is_binary(const git_blob *blob)
+{
+	git_buf content = GIT_BUF_INIT;
+
+	assert(blob);
+
+	git_buf_attach_notowned(&content, blob->odb_object->buffer,
+		min(blob->odb_object->cached.size,
+		GIT_FILTER_BYTES_TO_CHECK_NUL));
+	return git_buf_text_is_binary(&content);
+}
+
+int git_blob_filtered_content(
+	git_buf *out,
+	git_blob *blob,
+	const char *path,
+	int check_for_binary_data)
+{
+	int error = 0;
+	git_filter_list *fl = NULL;
+
+	assert(blob && path && out);
+
+	git_buf_sanitize(out);
+
+	if (check_for_binary_data && git_blob_is_binary(blob))
+		return 0;
+
+	if (!(error = git_filter_list_load(
+			&fl, git_blob_owner(blob), blob, path,
+			GIT_FILTER_TO_WORKTREE, GIT_FILTER_DEFAULT))) {
+
+		error = git_filter_list_apply_to_blob(out, fl, blob);
+
+		git_filter_list_free(fl);
+	}
+
+	return error;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blob.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blob.h
new file mode 100755
index 0000000..4cd9f1e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/blob.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_blob_h__
+#define INCLUDE_blob_h__
+
+#include "git2/blob.h"
+#include "repository.h"
+#include "odb.h"
+#include "fileops.h"
+
+struct git_blob {
+	git_object object;
+	git_odb_object *odb_object;
+};
+
+void git_blob__free(void *blob);
+int git_blob__parse(void *blob, git_odb_object *obj);
+int git_blob__getbuf(git_buf *buffer, git_blob *blob);
+
+extern int git_blob__create_from_paths(
+	git_oid *out_oid,
+	struct stat *out_st,
+	git_repository *repo,
+	const char *full_path,
+	const char *hint_path,
+	mode_t hint_mode,
+	bool apply_filters);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/branch.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/branch.c
new file mode 100755
index 0000000..791d551
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/branch.c
@@ -0,0 +1,669 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "commit.h"
+#include "tag.h"
+#include "config.h"
+#include "refspec.h"
+#include "refs.h"
+#include "remote.h"
+#include "annotated_commit.h"
+
+#include "git2/branch.h"
+
+static int retrieve_branch_reference(
+	git_reference **branch_reference_out,
+	git_repository *repo,
+	const char *branch_name,
+	int is_remote)
+{
+	git_reference *branch = NULL;
+	int error = 0;
+	char *prefix;
+	git_buf ref_name = GIT_BUF_INIT;
+
+	prefix = is_remote ? GIT_REFS_REMOTES_DIR : GIT_REFS_HEADS_DIR;
+
+	if ((error = git_buf_joinpath(&ref_name, prefix, branch_name)) < 0)
+		/* OOM */;
+	else if ((error = git_reference_lookup(&branch, repo, ref_name.ptr)) < 0)
+		giterr_set(
+			GITERR_REFERENCE, "Cannot locate %s branch '%s'",
+			is_remote ? "remote-tracking" : "local", branch_name);
+
+	*branch_reference_out = branch; /* will be NULL on error */
+
+	git_buf_free(&ref_name);
+	return error;
+}
+
+static int not_a_local_branch(const char *reference_name)
+{
+	giterr_set(
+		GITERR_INVALID,
+		"Reference '%s' is not a local branch.", reference_name);
+	return -1;
+}
+
+static int create_branch(
+	git_reference **ref_out,
+	git_repository *repository,
+	const char *branch_name,
+	const git_commit *commit,
+	const char *from,
+	int force)
+{
+	int is_head = 0;
+	git_reference *branch = NULL;
+	git_buf canonical_branch_name = GIT_BUF_INIT,
+			  log_message = GIT_BUF_INIT;
+	int error = -1;
+
+	assert(branch_name && commit && ref_out);
+	assert(git_object_owner((const git_object *)commit) == repository);
+
+	if (force && git_branch_lookup(&branch, repository, branch_name, GIT_BRANCH_LOCAL) == 0) {
+		error = git_branch_is_head(branch);
+		git_reference_free(branch);
+		branch = NULL;
+
+		if (error < 0)
+			goto cleanup;
+
+		is_head = error;
+	}
+
+	if (is_head && force) {
+		giterr_set(GITERR_REFERENCE, "Cannot force update branch '%s' as it is "
+			"the current HEAD of the repository.", branch_name);
+		error = -1;
+		goto cleanup;
+	}
+
+	if (git_buf_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0)
+		goto cleanup;
+
+	if (git_buf_printf(&log_message, "branch: Created from %s", from) < 0)
+		goto cleanup;
+
+	error = git_reference_create(&branch, repository,
+		git_buf_cstr(&canonical_branch_name), git_commit_id(commit), force,
+		git_buf_cstr(&log_message));
+
+	if (!error)
+		*ref_out = branch;
+
+cleanup:
+	git_buf_free(&canonical_branch_name);
+	git_buf_free(&log_message);
+	return error;
+}
+
+int git_branch_create(
+	git_reference **ref_out,
+	git_repository *repository,
+	const char *branch_name,
+	const git_commit *commit,
+	int force)
+{
+	return create_branch(ref_out, repository, branch_name, commit, git_oid_tostr_s(git_commit_id(commit)), force);
+}
+
+int git_branch_create_from_annotated(
+	git_reference **ref_out,
+	git_repository *repository,
+	const char *branch_name,
+	const git_annotated_commit *commit,
+	int force)
+{
+	return create_branch(ref_out, repository, branch_name, commit->commit, commit->ref_name, force);
+}
+
+int git_branch_delete(git_reference *branch)
+{
+	int is_head;
+	git_buf config_section = GIT_BUF_INIT;
+	int error = -1;
+
+	assert(branch);
+
+	if (!git_reference_is_branch(branch) && !git_reference_is_remote(branch)) {
+		giterr_set(GITERR_INVALID, "Reference '%s' is not a valid branch.",
+			git_reference_name(branch));
+		return GIT_ENOTFOUND;
+	}
+
+	if ((is_head = git_branch_is_head(branch)) < 0)
+		return is_head;
+
+	if (is_head) {
+		giterr_set(GITERR_REFERENCE, "Cannot delete branch '%s' as it is "
+			"the current HEAD of the repository.", git_reference_name(branch));
+		return -1;
+	}
+
+	if (git_buf_join(&config_section, '.', "branch",
+			git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0)
+		goto on_error;
+
+	if (git_config_rename_section(
+		git_reference_owner(branch), git_buf_cstr(&config_section), NULL) < 0)
+		goto on_error;
+
+	if (git_reference_delete(branch) < 0)
+		goto on_error;
+
+	if ((error = git_reflog_delete(git_reference_owner(branch), git_reference_name(branch))) < 0) {
+		if (error == GIT_ENOTFOUND) {
+			giterr_clear();
+			error = 0;
+		}
+		goto on_error;
+	}
+
+	error = 0;
+
+on_error:
+	git_buf_free(&config_section);
+	return error;
+}
+
+typedef struct {
+	git_reference_iterator *iter;
+	unsigned int flags;
+} branch_iter;
+
+int git_branch_next(git_reference **out, git_branch_t *out_type, git_branch_iterator *_iter)
+{
+	branch_iter *iter = (branch_iter *) _iter;
+	git_reference *ref;
+	int error;
+
+	while ((error = git_reference_next(&ref, iter->iter)) == 0) {
+		if ((iter->flags & GIT_BRANCH_LOCAL) &&
+		    !git__prefixcmp(ref->name, GIT_REFS_HEADS_DIR)) {
+			*out = ref;
+			*out_type = GIT_BRANCH_LOCAL;
+
+			return 0;
+		} else  if ((iter->flags & GIT_BRANCH_REMOTE) &&
+			    !git__prefixcmp(ref->name, GIT_REFS_REMOTES_DIR)) {
+			*out = ref;
+			*out_type = GIT_BRANCH_REMOTE;
+
+			return 0;
+		} else {
+			git_reference_free(ref);
+		}
+	}
+
+	return error;
+}
+
+int git_branch_iterator_new(
+	git_branch_iterator **out,
+	git_repository *repo,
+	git_branch_t list_flags)
+{
+	branch_iter *iter;
+
+	iter = git__calloc(1, sizeof(branch_iter));
+	GITERR_CHECK_ALLOC(iter);
+
+	iter->flags = list_flags;
+
+	if (git_reference_iterator_new(&iter->iter, repo) < 0) {
+		git__free(iter);
+		return -1;
+	}
+
+	*out = (git_branch_iterator *) iter;
+
+	return 0;
+}
+
+void git_branch_iterator_free(git_branch_iterator *_iter)
+{
+	branch_iter *iter = (branch_iter *) _iter;
+
+	if (iter == NULL)
+		return;
+
+	git_reference_iterator_free(iter->iter);
+	git__free(iter);
+}
+
+int git_branch_move(
+	git_reference **out,
+	git_reference *branch,
+	const char *new_branch_name,
+	int force)
+{
+	git_buf new_reference_name = GIT_BUF_INIT,
+	        old_config_section = GIT_BUF_INIT,
+	        new_config_section = GIT_BUF_INIT,
+	        log_message = GIT_BUF_INIT;
+	int error;
+
+	assert(branch && new_branch_name);
+
+	if (!git_reference_is_branch(branch))
+		return not_a_local_branch(git_reference_name(branch));
+
+	if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0)
+		goto done;
+
+	if ((error = git_buf_printf(&log_message, "branch: renamed %s to %s",
+				    git_reference_name(branch), git_buf_cstr(&new_reference_name))) < 0)
+			goto done;
+
+	/* first update ref then config so failure won't trash config */
+
+	error = git_reference_rename(
+		out, branch, git_buf_cstr(&new_reference_name), force,
+		git_buf_cstr(&log_message));
+	if (error < 0)
+		goto done;
+
+	git_buf_join(&old_config_section, '.', "branch",
+		git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR));
+	git_buf_join(&new_config_section, '.', "branch", new_branch_name);
+
+	error = git_config_rename_section(
+		git_reference_owner(branch),
+		git_buf_cstr(&old_config_section),
+		git_buf_cstr(&new_config_section));
+
+done:
+	git_buf_free(&new_reference_name);
+	git_buf_free(&old_config_section);
+	git_buf_free(&new_config_section);
+	git_buf_free(&log_message);
+
+	return error;
+}
+
+int git_branch_lookup(
+	git_reference **ref_out,
+	git_repository *repo,
+	const char *branch_name,
+	git_branch_t branch_type)
+{
+	assert(ref_out && repo && branch_name);
+
+	return retrieve_branch_reference(ref_out, repo, branch_name, branch_type == GIT_BRANCH_REMOTE);
+}
+
+int git_branch_name(
+	const char **out,
+	const git_reference *ref)
+{
+	const char *branch_name;
+
+	assert(out && ref);
+
+	branch_name = ref->name;
+
+	if (git_reference_is_branch(ref)) {
+		branch_name += strlen(GIT_REFS_HEADS_DIR);
+	} else if (git_reference_is_remote(ref)) {
+		branch_name += strlen(GIT_REFS_REMOTES_DIR);
+	} else {
+		giterr_set(GITERR_INVALID,
+				"Reference '%s' is neither a local nor a remote branch.", ref->name);
+		return -1;
+	}
+	*out = branch_name;
+	return 0;
+}
+
+static int retrieve_upstream_configuration(
+	git_buf *out,
+	const git_config *config,
+	const char *canonical_branch_name,
+	const char *format)
+{
+	git_buf buf = GIT_BUF_INIT;
+	int error;
+
+	if (git_buf_printf(&buf, format,
+		canonical_branch_name + strlen(GIT_REFS_HEADS_DIR)) < 0)
+			return -1;
+
+	error = git_config_get_string_buf(out, config, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+	return error;
+}
+
+int git_branch_upstream_name(
+	git_buf *out,
+	git_repository *repo,
+	const char *refname)
+{
+	git_buf remote_name = GIT_BUF_INIT;
+	git_buf merge_name = GIT_BUF_INIT;
+	git_buf buf = GIT_BUF_INIT;
+	int error = -1;
+	git_remote *remote = NULL;
+	const git_refspec *refspec;
+	git_config *config;
+
+	assert(out && refname);
+
+	git_buf_sanitize(out);
+
+	if (!git_reference__is_branch(refname))
+		return not_a_local_branch(refname);
+
+	if ((error = git_repository_config_snapshot(&config, repo)) < 0)
+		return error;
+
+	if ((error = retrieve_upstream_configuration(
+		&remote_name, config, refname, "branch.%s.remote")) < 0)
+			goto cleanup;
+
+	if ((error = retrieve_upstream_configuration(
+		&merge_name, config, refname, "branch.%s.merge")) < 0)
+			goto cleanup;
+
+	if (git_buf_len(&remote_name) == 0 || git_buf_len(&merge_name) == 0) {
+		giterr_set(GITERR_REFERENCE,
+			"branch '%s' does not have an upstream", refname);
+		error = GIT_ENOTFOUND;
+		goto cleanup;
+	}
+
+	if (strcmp(".", git_buf_cstr(&remote_name)) != 0) {
+		if ((error = git_remote_lookup(&remote, repo, git_buf_cstr(&remote_name))) < 0)
+			goto cleanup;
+
+		refspec = git_remote__matching_refspec(remote, git_buf_cstr(&merge_name));
+		if (!refspec) {
+			error = GIT_ENOTFOUND;
+			goto cleanup;
+		}
+
+		if (git_refspec_transform(&buf, refspec, git_buf_cstr(&merge_name)) < 0)
+			goto cleanup;
+	} else
+		if (git_buf_set(&buf, git_buf_cstr(&merge_name), git_buf_len(&merge_name)) < 0)
+			goto cleanup;
+
+	error = git_buf_set(out, git_buf_cstr(&buf), git_buf_len(&buf));
+
+cleanup:
+	git_config_free(config);
+	git_remote_free(remote);
+	git_buf_free(&remote_name);
+	git_buf_free(&merge_name);
+	git_buf_free(&buf);
+	return error;
+}
+
+int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname)
+{
+	int error;
+	git_config *cfg;
+
+	if (!git_reference__is_branch(refname))
+		return not_a_local_branch(refname);
+
+	if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
+		return error;
+
+	git_buf_sanitize(buf);
+
+	if ((error = retrieve_upstream_configuration(buf, cfg, refname, "branch.%s.remote")) < 0)
+		return error;
+
+	if (git_buf_len(buf) == 0) {
+		giterr_set(GITERR_REFERENCE, "branch '%s' does not have an upstream remote", refname);
+		error = GIT_ENOTFOUND;
+		git_buf_clear(buf);
+	}
+
+	return error;
+}
+
+int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refname)
+{
+	git_strarray remote_list = {0};
+	size_t i;
+	git_remote *remote;
+	const git_refspec *fetchspec;
+	int error = 0;
+	char *remote_name = NULL;
+
+	assert(buf && repo && refname);
+
+	git_buf_sanitize(buf);
+
+	/* Verify that this is a remote branch */
+	if (!git_reference__is_remote(refname)) {
+		giterr_set(GITERR_INVALID, "Reference '%s' is not a remote branch.",
+			refname);
+		error = GIT_ERROR;
+		goto cleanup;
+	}
+
+	/* Get the remotes */
+	if ((error = git_remote_list(&remote_list, repo)) < 0)
+		goto cleanup;
+
+	/* Find matching remotes */
+	for (i = 0; i < remote_list.count; i++) {
+		if ((error = git_remote_lookup(&remote, repo, remote_list.strings[i])) < 0)
+			continue;
+
+		fetchspec = git_remote__matching_dst_refspec(remote, refname);
+		if (fetchspec) {
+			/* If we have not already set out yet, then set
+			 * it to the matching remote name. Otherwise
+			 * multiple remotes match this reference, and it
+			 * is ambiguous. */
+			if (!remote_name) {
+				remote_name = remote_list.strings[i];
+			} else {
+				git_remote_free(remote);
+
+				giterr_set(GITERR_REFERENCE,
+					"Reference '%s' is ambiguous", refname);
+				error = GIT_EAMBIGUOUS;
+				goto cleanup;
+			}
+		}
+
+		git_remote_free(remote);
+	}
+
+	if (remote_name) {
+		git_buf_clear(buf);
+		error = git_buf_puts(buf, remote_name);
+	} else {
+		giterr_set(GITERR_REFERENCE,
+			"Could not determine remote for '%s'", refname);
+		error = GIT_ENOTFOUND;
+	}
+
+cleanup:
+	if (error < 0)
+		git_buf_free(buf);
+
+	git_strarray_free(&remote_list);
+	return error;
+}
+
+int git_branch_upstream(
+	git_reference **tracking_out,
+	const git_reference *branch)
+{
+	int error;
+	git_buf tracking_name = GIT_BUF_INIT;
+
+	if ((error = git_branch_upstream_name(&tracking_name,
+		git_reference_owner(branch), git_reference_name(branch))) < 0)
+			return error;
+
+	error = git_reference_lookup(
+		tracking_out,
+		git_reference_owner(branch),
+		git_buf_cstr(&tracking_name));
+
+	git_buf_free(&tracking_name);
+	return error;
+}
+
+static int unset_upstream(git_config *config, const char *shortname)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	if (git_buf_printf(&buf, "branch.%s.remote", shortname) < 0)
+		return -1;
+
+	if (git_config_delete_entry(config, git_buf_cstr(&buf)) < 0)
+		goto on_error;
+
+	git_buf_clear(&buf);
+	if (git_buf_printf(&buf, "branch.%s.merge", shortname) < 0)
+		goto on_error;
+
+	if (git_config_delete_entry(config, git_buf_cstr(&buf)) < 0)
+		goto on_error;
+
+	git_buf_free(&buf);
+	return 0;
+
+on_error:
+	git_buf_free(&buf);
+	return -1;
+}
+
+int git_branch_set_upstream(git_reference *branch, const char *upstream_name)
+{
+	git_buf key = GIT_BUF_INIT, value = GIT_BUF_INIT;
+	git_reference *upstream;
+	git_repository *repo;
+	git_remote *remote = NULL;
+	git_config *config;
+	const char *name, *shortname;
+	int local, error;
+	const git_refspec *fetchspec;
+
+	name = git_reference_name(branch);
+	if (!git_reference__is_branch(name))
+		return not_a_local_branch(name);
+
+	if (git_repository_config__weakptr(&config, git_reference_owner(branch)) < 0)
+		return -1;
+
+	shortname = name + strlen(GIT_REFS_HEADS_DIR);
+
+	if (upstream_name == NULL)
+		return unset_upstream(config, shortname);
+
+	repo = git_reference_owner(branch);
+
+	/* First we need to figure out whether it's a branch or remote-tracking */
+	if (git_branch_lookup(&upstream, repo, upstream_name, GIT_BRANCH_LOCAL) == 0)
+		local = 1;
+	else if (git_branch_lookup(&upstream, repo, upstream_name, GIT_BRANCH_REMOTE) == 0)
+		local = 0;
+	else {
+		giterr_set(GITERR_REFERENCE,
+			"Cannot set upstream for branch '%s'", shortname);
+		return GIT_ENOTFOUND;
+	}
+
+	/*
+	 * If it's local, the remote is "." and the branch name is
+	 * simply the refname. Otherwise we need to figure out what
+	 * the remote-tracking branch's name on the remote is and use
+	 * that.
+	 */
+	if (local)
+		error = git_buf_puts(&value, ".");
+	else
+		error = git_branch_remote_name(&value, repo, git_reference_name(upstream));
+
+	if (error < 0)
+		goto on_error;
+
+	if (git_buf_printf(&key, "branch.%s.remote", shortname) < 0)
+		goto on_error;
+
+	if (git_config_set_string(config, git_buf_cstr(&key), git_buf_cstr(&value)) < 0)
+		goto on_error;
+
+	if (local) {
+		git_buf_clear(&value);
+		if (git_buf_puts(&value, git_reference_name(upstream)) < 0)
+			goto on_error;
+	} else {
+		/* Get the remoe-tracking branch's refname in its repo */
+		if (git_remote_lookup(&remote, repo, git_buf_cstr(&value)) < 0)
+			goto on_error;
+
+		fetchspec = git_remote__matching_dst_refspec(remote, git_reference_name(upstream));
+		git_buf_clear(&value);
+		if (!fetchspec || git_refspec_rtransform(&value, fetchspec, git_reference_name(upstream)) < 0)
+			goto on_error;
+
+		git_remote_free(remote);
+		remote = NULL;
+	}
+
+	git_buf_clear(&key);
+	if (git_buf_printf(&key, "branch.%s.merge", shortname) < 0)
+		goto on_error;
+
+	if (git_config_set_string(config, git_buf_cstr(&key), git_buf_cstr(&value)) < 0)
+		goto on_error;
+
+	git_reference_free(upstream);
+	git_buf_free(&key);
+	git_buf_free(&value);
+
+	return 0;
+
+on_error:
+	git_reference_free(upstream);
+	git_buf_free(&key);
+	git_buf_free(&value);
+	git_remote_free(remote);
+
+	return -1;
+}
+
+int git_branch_is_head(
+		const git_reference *branch)
+{
+	git_reference *head;
+	bool is_same = false;
+	int error;
+
+	assert(branch);
+
+	if (!git_reference_is_branch(branch))
+		return false;
+
+	error = git_repository_head(&head, git_reference_owner(branch));
+
+	if (error == GIT_EUNBORNBRANCH || error == GIT_ENOTFOUND)
+		return false;
+
+	if (error < 0)
+		return -1;
+
+	is_same = strcmp(
+		git_reference_name(branch),
+		git_reference_name(head)) == 0;
+
+	git_reference_free(head);
+
+	return is_same;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/branch.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/branch.h
new file mode 100755
index 0000000..d02f2af
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/branch.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_branch_h__
+#define INCLUDE_branch_h__
+
+#include "buffer.h"
+
+int git_branch_upstream__name(
+	git_buf *tracking_name,
+	git_repository *repo,
+	const char *canonical_branch_name);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/buf_text.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/buf_text.c
new file mode 100755
index 0000000..7e6779d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/buf_text.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "buf_text.h"
+
+int git_buf_text_puts_escaped(
+	git_buf *buf,
+	const char *string,
+	const char *esc_chars,
+	const char *esc_with)
+{
+	const char *scan;
+	size_t total = 0, esc_len = strlen(esc_with), count, alloclen;
+
+	if (!string)
+		return 0;
+
+	for (scan = string; *scan; ) {
+		/* count run of non-escaped characters */
+		count = strcspn(scan, esc_chars);
+		total += count;
+		scan += count;
+		/* count run of escaped characters */
+		count = strspn(scan, esc_chars);
+		total += count * (esc_len + 1);
+		scan += count;
+	}
+
+	GITERR_CHECK_ALLOC_ADD(&alloclen, total, 1);
+	if (git_buf_grow_by(buf, alloclen) < 0)
+		return -1;
+
+	for (scan = string; *scan; ) {
+		count = strcspn(scan, esc_chars);
+
+		memmove(buf->ptr + buf->size, scan, count);
+		scan += count;
+		buf->size += count;
+
+		for (count = strspn(scan, esc_chars); count > 0; --count) {
+			/* copy escape sequence */
+			memmove(buf->ptr + buf->size, esc_with, esc_len);
+			buf->size += esc_len;
+			/* copy character to be escaped */
+			buf->ptr[buf->size] = *scan;
+			buf->size++;
+			scan++;
+		}
+	}
+
+	buf->ptr[buf->size] = '\0';
+
+	return 0;
+}
+
+void git_buf_text_unescape(git_buf *buf)
+{
+	buf->size = git__unescape(buf->ptr);
+}
+
+int git_buf_text_crlf_to_lf(git_buf *tgt, const git_buf *src)
+{
+	const char *scan = src->ptr;
+	const char *scan_end = src->ptr + src->size;
+	const char *next = memchr(scan, '\r', src->size);
+	size_t new_size;
+	char *out;
+
+	assert(tgt != src);
+
+	if (!next)
+		return git_buf_set(tgt, src->ptr, src->size);
+
+	/* reduce reallocs while in the loop */
+	GITERR_CHECK_ALLOC_ADD(&new_size, src->size, 1);
+	if (git_buf_grow(tgt, new_size) < 0)
+		return -1;
+
+	out = tgt->ptr;
+	tgt->size = 0;
+
+	/* Find the next \r and copy whole chunk up to there to tgt */
+	for (; next; scan = next + 1, next = memchr(scan, '\r', scan_end - scan)) {
+		if (next > scan) {
+			size_t copylen = (size_t)(next - scan);
+			memcpy(out, scan, copylen);
+			out += copylen;
+		}
+
+		/* Do not drop \r unless it is followed by \n */
+		if (next + 1 == scan_end || next[1] != '\n')
+			*out++ = '\r';
+	}
+
+	/* Copy remaining input into dest */
+	if (scan < scan_end) {
+		size_t remaining = (size_t)(scan_end - scan);
+		memcpy(out, scan, remaining);
+		out += remaining;
+	}
+
+	tgt->size = (size_t)(out - tgt->ptr);
+	tgt->ptr[tgt->size] = '\0';
+
+	return 0;
+}
+
+int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src)
+{
+	const char *start = src->ptr;
+	const char *end = start + src->size;
+	const char *scan = start;
+	const char *next = memchr(scan, '\n', src->size);
+	size_t alloclen;
+
+	assert(tgt != src);
+
+	if (!next)
+		return git_buf_set(tgt, src->ptr, src->size);
+
+	/* attempt to reduce reallocs while in the loop */
+	GITERR_CHECK_ALLOC_ADD(&alloclen, src->size, src->size >> 4);
+	GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
+	if (git_buf_grow(tgt, alloclen) < 0)
+		return -1;
+	tgt->size = 0;
+
+	for (; next; scan = next + 1, next = memchr(scan, '\n', end - scan)) {
+		size_t copylen = next - scan;
+
+		/* if we find mixed line endings, carry on */
+		if (copylen && next[-1] == '\r')
+			copylen--;
+
+		GITERR_CHECK_ALLOC_ADD(&alloclen, copylen, 3);
+		if (git_buf_grow_by(tgt, alloclen) < 0)
+			return -1;
+
+		if (copylen) {
+			memcpy(tgt->ptr + tgt->size, scan, copylen);
+			tgt->size += copylen;
+		}
+
+		tgt->ptr[tgt->size++] = '\r';
+		tgt->ptr[tgt->size++] = '\n';
+	}
+
+	tgt->ptr[tgt->size] = '\0';
+	return git_buf_put(tgt, scan, end - scan);
+}
+
+int git_buf_text_common_prefix(git_buf *buf, const git_strarray *strings)
+{
+	size_t i;
+	const char *str, *pfx;
+
+	git_buf_clear(buf);
+
+	if (!strings || !strings->count)
+		return 0;
+
+	/* initialize common prefix to first string */
+	if (git_buf_sets(buf, strings->strings[0]) < 0)
+		return -1;
+
+	/* go through the rest of the strings, truncating to shared prefix */
+	for (i = 1; i < strings->count; ++i) {
+
+		for (str = strings->strings[i], pfx = buf->ptr;
+			 *str && *str == *pfx; str++, pfx++)
+			/* scanning */;
+
+		git_buf_truncate(buf, pfx - buf->ptr);
+
+		if (!buf->size)
+			break;
+	}
+
+	return 0;
+}
+
+bool git_buf_text_is_binary(const git_buf *buf)
+{
+	const char *scan = buf->ptr, *end = buf->ptr + buf->size;
+	git_bom_t bom;
+	int printable = 0, nonprintable = 0;
+
+	scan += git_buf_text_detect_bom(&bom, buf, 0);
+
+	if (bom > GIT_BOM_UTF8)
+		return 1;
+
+	while (scan < end) {
+		unsigned char c = *scan++;
+
+		/* Printable characters are those above SPACE (0x1F) excluding DEL,
+		 * and including BS, ESC and FF.
+		 */
+		if ((c > 0x1F && c != 127) || c == '\b' || c == '\033' || c == '\014')
+			printable++;
+		else if (c == '\0')
+			return true;
+		else if (!git__isspace(c))
+			nonprintable++;
+	}
+
+	return ((printable >> 7) < nonprintable);
+}
+
+bool git_buf_text_contains_nul(const git_buf *buf)
+{
+	return (memchr(buf->ptr, '\0', buf->size) != NULL);
+}
+
+int git_buf_text_detect_bom(git_bom_t *bom, const git_buf *buf, size_t offset)
+{
+	const char *ptr;
+	size_t len;
+
+	*bom = GIT_BOM_NONE;
+	/* need at least 2 bytes after offset to look for any BOM */
+	if (buf->size < offset + 2)
+		return 0;
+
+	ptr = buf->ptr + offset;
+	len = buf->size - offset;
+
+	switch (*ptr++) {
+	case 0:
+		if (len >= 4 && ptr[0] == 0 && ptr[1] == '\xFE' && ptr[2] == '\xFF') {
+			*bom = GIT_BOM_UTF32_BE;
+			return 4;
+		}
+		break;
+	case '\xEF':
+		if (len >= 3 && ptr[0] == '\xBB' && ptr[1] == '\xBF') {
+			*bom = GIT_BOM_UTF8;
+			return 3;
+		}
+		break;
+	case '\xFE':
+		if (*ptr == '\xFF') {
+			*bom = GIT_BOM_UTF16_BE;
+			return 2;
+		}
+		break;
+	case '\xFF':
+		if (*ptr != '\xFE')
+			break;
+		if (len >= 4 && ptr[1] == 0 && ptr[2] == 0) {
+			*bom = GIT_BOM_UTF32_LE;
+			return 4;
+		} else {
+			*bom = GIT_BOM_UTF16_LE;
+			return 2;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+bool git_buf_text_gather_stats(
+	git_buf_text_stats *stats, const git_buf *buf, bool skip_bom)
+{
+	const char *scan = buf->ptr, *end = buf->ptr + buf->size;
+	int skip;
+
+	memset(stats, 0, sizeof(*stats));
+
+	/* BOM detection */
+	skip = git_buf_text_detect_bom(&stats->bom, buf, 0);
+	if (skip_bom)
+		scan += skip;
+
+	/* Ignore EOF character */
+	if (buf->size > 0 && end[-1] == '\032')
+		end--;
+
+	/* Counting loop */
+	while (scan < end) {
+		unsigned char c = *scan++;
+
+		if (c > 0x1F && c != 0x7F)
+			stats->printable++;
+		else switch (c) {
+			case '\0':
+				stats->nul++;
+				stats->nonprintable++;
+				break;
+			case '\n':
+				stats->lf++;
+				break;
+			case '\r':
+				stats->cr++;
+				if (scan < end && *scan == '\n')
+					stats->crlf++;
+				break;
+			case '\t': case '\f': case '\v': case '\b': case 0x1b: /*ESC*/
+				stats->printable++;
+				break;
+			default:
+				stats->nonprintable++;
+				break;
+			}
+	}
+
+	return (stats->nul > 0 ||
+		((stats->printable >> 7) < stats->nonprintable));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/buf_text.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/buf_text.h
new file mode 100755
index 0000000..c9c55af
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/buf_text.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_buf_text_h__
+#define INCLUDE_buf_text_h__
+
+#include "buffer.h"
+
+typedef enum {
+	GIT_BOM_NONE = 0,
+	GIT_BOM_UTF8 = 1,
+	GIT_BOM_UTF16_LE = 2,
+	GIT_BOM_UTF16_BE = 3,
+	GIT_BOM_UTF32_LE = 4,
+	GIT_BOM_UTF32_BE = 5
+} git_bom_t;
+
+typedef struct {
+	git_bom_t bom; /* BOM found at head of text */
+	unsigned int nul, cr, lf, crlf; /* NUL, CR, LF and CRLF counts */
+	unsigned int printable, nonprintable; /* These are just approximations! */
+} git_buf_text_stats;
+
+/**
+ * Append string to buffer, prefixing each character from `esc_chars` with
+ * `esc_with` string.
+ *
+ * @param buf Buffer to append data to
+ * @param string String to escape and append
+ * @param esc_chars Characters to be escaped
+ * @param esc_with String to insert in from of each found character
+ * @return 0 on success, <0 on failure (probably allocation problem)
+ */
+extern int git_buf_text_puts_escaped(
+	git_buf *buf,
+	const char *string,
+	const char *esc_chars,
+	const char *esc_with);
+
+/**
+ * Append string escaping characters that are regex special
+ */
+GIT_INLINE(int) git_buf_text_puts_escape_regex(git_buf *buf, const char *string)
+{
+	return git_buf_text_puts_escaped(buf, string, "^.[]$()|*+?{}\\", "\\");
+}
+
+/**
+ * Unescape all characters in a buffer in place
+ *
+ * I.e. remove backslashes
+ */
+extern void git_buf_text_unescape(git_buf *buf);
+
+/**
+ * Replace all \r\n with \n.
+ *
+ * @return 0 on success, -1 on memory error
+ */
+extern int git_buf_text_crlf_to_lf(git_buf *tgt, const git_buf *src);
+
+/**
+ * Replace all \n with \r\n. Does not modify existing \r\n.
+ *
+ * @return 0 on success, -1 on memory error
+ */
+extern int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src);
+
+/**
+ * Fill buffer with the common prefix of a array of strings
+ *
+ * Buffer will be set to empty if there is no common prefix
+ */
+extern int git_buf_text_common_prefix(git_buf *buf, const git_strarray *strs);
+
+/**
+ * Check quickly if buffer looks like it contains binary data
+ *
+ * @param buf Buffer to check
+ * @return true if buffer looks like non-text data
+ */
+extern bool git_buf_text_is_binary(const git_buf *buf);
+
+/**
+ * Check quickly if buffer contains a NUL byte
+ *
+ * @param buf Buffer to check
+ * @return true if buffer contains a NUL byte
+ */
+extern bool git_buf_text_contains_nul(const git_buf *buf);
+
+/**
+ * Check if a buffer begins with a UTF BOM
+ *
+ * @param bom Set to the type of BOM detected or GIT_BOM_NONE
+ * @param buf Buffer in which to check the first bytes for a BOM
+ * @param offset Offset into buffer to look for BOM
+ * @return Number of bytes of BOM data (or 0 if no BOM found)
+ */
+extern int git_buf_text_detect_bom(
+	git_bom_t *bom, const git_buf *buf, size_t offset);
+
+/**
+ * Gather stats for a piece of text
+ *
+ * Fill the `stats` structure with counts of unreadable characters, carriage
+ * returns, etc, so it can be used in heuristics.  This automatically skips
+ * a trailing EOF (\032 character).  Also it will look for a BOM at the
+ * start of the text and can be told to skip that as well.
+ *
+ * @param stats Structure to be filled in
+ * @param buf Text to process
+ * @param skip_bom Exclude leading BOM from stats if true
+ * @return Does the buffer heuristically look like binary data
+ */
+extern bool git_buf_text_gather_stats(
+	git_buf_text_stats *stats, const git_buf *buf, bool skip_bom);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/buffer.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/buffer.c
new file mode 100755
index 0000000..1a5809c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/buffer.c
@@ -0,0 +1,768 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "buffer.h"
+#include "posix.h"
+#include "git2/buffer.h"
+#include "buf_text.h"
+#include <ctype.h>
+
+/* Used as default value for git_buf->ptr so that people can always
+ * assume ptr is non-NULL and zero terminated even for new git_bufs.
+ */
+char git_buf__initbuf[1];
+
+char git_buf__oom[1];
+
+#define ENSURE_SIZE(b, d) \
+	if ((d) > buf->asize && git_buf_grow(b, (d)) < 0)\
+		return -1;
+
+
+void git_buf_init(git_buf *buf, size_t initial_size)
+{
+	buf->asize = 0;
+	buf->size = 0;
+	buf->ptr = git_buf__initbuf;
+
+	if (initial_size)
+		git_buf_grow(buf, initial_size);
+}
+
+int git_buf_try_grow(
+	git_buf *buf, size_t target_size, bool mark_oom)
+{
+	char *new_ptr;
+	size_t new_size;
+
+	if (buf->ptr == git_buf__oom)
+		return -1;
+
+	if (buf->asize == 0 && buf->size != 0) {
+		giterr_set(GITERR_INVALID, "cannot grow a borrowed buffer");
+		return GIT_EINVALID;
+	}
+
+	if (!target_size)
+		target_size = buf->size;
+
+	if (target_size <= buf->asize)
+		return 0;
+
+	if (buf->asize == 0) {
+		new_size = target_size;
+		new_ptr = NULL;
+	} else {
+		new_size = buf->asize;
+		new_ptr = buf->ptr;
+	}
+
+	/* grow the buffer size by 1.5, until it's big enough
+	 * to fit our target size */
+	while (new_size < target_size)
+		new_size = (new_size << 1) - (new_size >> 1);
+
+	/* round allocation up to multiple of 8 */
+	new_size = (new_size + 7) & ~7;
+
+	if (new_size < buf->size) {
+		if (mark_oom)
+			buf->ptr = git_buf__oom;
+
+		giterr_set_oom();
+		return -1;
+	}
+
+	new_ptr = git__realloc(new_ptr, new_size);
+
+	if (!new_ptr) {
+		if (mark_oom) {
+			if (buf->ptr && (buf->ptr != git_buf__initbuf))
+				git__free(buf->ptr);
+			buf->ptr = git_buf__oom;
+		}
+		return -1;
+	}
+
+	buf->asize = new_size;
+	buf->ptr   = new_ptr;
+
+	/* truncate the existing buffer size if necessary */
+	if (buf->size >= buf->asize)
+		buf->size = buf->asize - 1;
+	buf->ptr[buf->size] = '\0';
+
+	return 0;
+}
+
+int git_buf_grow(git_buf *buffer, size_t target_size)
+{
+	return git_buf_try_grow(buffer, target_size, true);
+}
+
+int git_buf_grow_by(git_buf *buffer, size_t additional_size)
+{
+	size_t newsize;
+
+	if (GIT_ADD_SIZET_OVERFLOW(&newsize, buffer->size, additional_size)) {
+		buffer->ptr = git_buf__oom;
+		return -1;
+	}
+
+	return git_buf_try_grow(buffer, newsize, true);
+}
+
+void git_buf_free(git_buf *buf)
+{
+	if (!buf) return;
+
+	if (buf->asize > 0 && buf->ptr != NULL && buf->ptr != git_buf__oom)
+		git__free(buf->ptr);
+
+	git_buf_init(buf, 0);
+}
+
+void git_buf_sanitize(git_buf *buf)
+{
+	if (buf->ptr == NULL) {
+		assert(buf->size == 0 && buf->asize == 0);
+		buf->ptr = git_buf__initbuf;
+	} else if (buf->asize > buf->size)
+		buf->ptr[buf->size] = '\0';
+}
+
+void git_buf_clear(git_buf *buf)
+{
+	buf->size = 0;
+
+	if (!buf->ptr) {
+		buf->ptr = git_buf__initbuf;
+		buf->asize = 0;
+	}
+
+	if (buf->asize > 0)
+		buf->ptr[0] = '\0';
+}
+
+int git_buf_set(git_buf *buf, const void *data, size_t len)
+{
+	size_t alloclen;
+
+	if (len == 0 || data == NULL) {
+		git_buf_clear(buf);
+	} else {
+		if (data != buf->ptr) {
+			GITERR_CHECK_ALLOC_ADD(&alloclen, len, 1);
+			ENSURE_SIZE(buf, alloclen);
+			memmove(buf->ptr, data, len);
+		}
+
+		buf->size = len;
+		if (buf->asize > buf->size)
+			buf->ptr[buf->size] = '\0';
+
+	}
+	return 0;
+}
+
+int git_buf_is_binary(const git_buf *buf)
+{
+	return git_buf_text_is_binary(buf);
+}
+
+int git_buf_contains_nul(const git_buf *buf)
+{
+	return git_buf_text_contains_nul(buf);
+}
+
+int git_buf_sets(git_buf *buf, const char *string)
+{
+	return git_buf_set(buf, string, string ? strlen(string) : 0);
+}
+
+int git_buf_putc(git_buf *buf, char c)
+{
+	size_t new_size;
+	GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, 2);
+	ENSURE_SIZE(buf, new_size);
+	buf->ptr[buf->size++] = c;
+	buf->ptr[buf->size] = '\0';
+	return 0;
+}
+
+int git_buf_putcn(git_buf *buf, char c, size_t len)
+{
+	size_t new_size;
+	GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, len);
+	GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
+	ENSURE_SIZE(buf, new_size);
+	memset(buf->ptr + buf->size, c, len);
+	buf->size += len;
+	buf->ptr[buf->size] = '\0';
+	return 0;
+}
+
+int git_buf_put(git_buf *buf, const char *data, size_t len)
+{
+	if (len) {
+		size_t new_size;
+
+		assert(data);
+		
+		GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, len);
+		GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
+		ENSURE_SIZE(buf, new_size);
+		memmove(buf->ptr + buf->size, data, len);
+		buf->size += len;
+		buf->ptr[buf->size] = '\0';
+	}
+	return 0;
+}
+
+int git_buf_puts(git_buf *buf, const char *string)
+{
+	assert(string);
+	return git_buf_put(buf, string, strlen(string));
+}
+
+static const char base64_encode[] =
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+int git_buf_encode_base64(git_buf *buf, const char *data, size_t len)
+{
+	size_t extra = len % 3;
+	uint8_t *write, a, b, c;
+	const uint8_t *read = (const uint8_t *)data;
+	size_t blocks = (len / 3) + !!extra, alloclen;
+
+	GITERR_CHECK_ALLOC_ADD(&blocks, blocks, 1);
+	GITERR_CHECK_ALLOC_MULTIPLY(&alloclen, blocks, 4);
+	GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, buf->size);
+
+	ENSURE_SIZE(buf, alloclen);
+	write = (uint8_t *)&buf->ptr[buf->size];
+
+	/* convert each run of 3 bytes into 4 output bytes */
+	for (len -= extra; len > 0; len -= 3) {
+		a = *read++;
+		b = *read++;
+		c = *read++;
+
+		*write++ = base64_encode[a >> 2];
+		*write++ = base64_encode[(a & 0x03) << 4 | b >> 4];
+		*write++ = base64_encode[(b & 0x0f) << 2 | c >> 6];
+		*write++ = base64_encode[c & 0x3f];
+	}
+
+	if (extra > 0) {
+		a = *read++;
+		b = (extra > 1) ? *read++ : 0;
+
+		*write++ = base64_encode[a >> 2];
+		*write++ = base64_encode[(a & 0x03) << 4 | b >> 4];
+		*write++ = (extra > 1) ? base64_encode[(b & 0x0f) << 2] : '=';
+		*write++ = '=';
+	}
+
+	buf->size = ((char *)write) - buf->ptr;
+	buf->ptr[buf->size] = '\0';
+
+	return 0;
+}
+
+/* The inverse of base64_encode, offset by '+' == 43. */
+static const int8_t base64_decode[] = {
+	62,
+	-1, -1, -1,
+	63,
+	52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+	-1, -1, -1, 0, -1, -1, -1,
+	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+	13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+	-1, -1, -1, -1, -1, -1,
+	26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+	39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
+};
+
+#define BASE64_DECODE_VALUE(c) (((c) < 43 || (c) > 122) ? -1 : base64_decode[c - 43])
+
+int git_buf_decode_base64(git_buf *buf, const char *base64, size_t len)
+{
+	size_t i;
+	int8_t a, b, c, d;
+	size_t orig_size = buf->size, new_size;
+
+	assert(len % 4 == 0);
+	GITERR_CHECK_ALLOC_ADD(&new_size, (len / 4 * 3), buf->size);
+	GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
+	ENSURE_SIZE(buf, new_size);
+
+	for (i = 0; i < len; i += 4) {
+		if ((a = BASE64_DECODE_VALUE(base64[i])) < 0 ||
+			(b = BASE64_DECODE_VALUE(base64[i+1])) < 0 ||
+			(c = BASE64_DECODE_VALUE(base64[i+2])) < 0 ||
+			(d = BASE64_DECODE_VALUE(base64[i+3])) < 0) {
+			buf->size = orig_size;
+			buf->ptr[buf->size] = '\0';
+
+			giterr_set(GITERR_INVALID, "Invalid base64 input");
+			return -1;
+		}
+
+		buf->ptr[buf->size++] = ((a << 2) | (b & 0x30) >> 4);
+		buf->ptr[buf->size++] = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2);
+		buf->ptr[buf->size++] = (c & 0x03) << 6 | (d & 0x3f);
+	}
+
+	buf->ptr[buf->size] = '\0';
+	return 0;
+}
+
+static const char b85str[] =
+	"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
+
+int git_buf_encode_base85(git_buf *buf, const char *data, size_t len)
+{
+	size_t blocks = (len / 4) + !!(len % 4), alloclen;
+
+	GITERR_CHECK_ALLOC_MULTIPLY(&alloclen, blocks, 5);
+	GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, buf->size);
+	GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
+
+	ENSURE_SIZE(buf, alloclen);
+
+	while (len) {
+		uint32_t acc = 0;
+		char b85[5];
+		int i;
+
+		for (i = 24; i >= 0; i -= 8) {
+			uint8_t ch = *data++;
+			acc |= ch << i;
+
+			if (--len == 0)
+				break;
+		}
+
+		for (i = 4; i >= 0; i--) {
+			int val = acc % 85;
+			acc /= 85;
+
+			b85[i] = b85str[val];
+		}
+
+		for (i = 0; i < 5; i++)
+			buf->ptr[buf->size++] = b85[i];
+	}
+
+	buf->ptr[buf->size] = '\0';
+
+	return 0;
+}
+
+int git_buf_vprintf(git_buf *buf, const char *format, va_list ap)
+{
+	size_t expected_size, new_size;
+	int len;
+
+	GITERR_CHECK_ALLOC_MULTIPLY(&expected_size, strlen(format), 2);
+	GITERR_CHECK_ALLOC_ADD(&expected_size, expected_size, buf->size);
+	ENSURE_SIZE(buf, expected_size);
+
+	while (1) {
+		va_list args;
+		va_copy(args, ap);
+
+		len = p_vsnprintf(
+			buf->ptr + buf->size,
+			buf->asize - buf->size,
+			format, args
+		);
+
+		va_end(args);
+
+		if (len < 0) {
+			git__free(buf->ptr);
+			buf->ptr = git_buf__oom;
+			return -1;
+		}
+
+		if ((size_t)len + 1 <= buf->asize - buf->size) {
+			buf->size += len;
+			break;
+		}
+
+		GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, len);
+		GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
+		ENSURE_SIZE(buf, new_size);
+	}
+
+	return 0;
+}
+
+int git_buf_printf(git_buf *buf, const char *format, ...)
+{
+	int r;
+	va_list ap;
+
+	va_start(ap, format);
+	r = git_buf_vprintf(buf, format, ap);
+	va_end(ap);
+
+	return r;
+}
+
+void git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf)
+{
+	size_t copylen;
+
+	assert(data && datasize && buf);
+
+	data[0] = '\0';
+
+	if (buf->size == 0 || buf->asize <= 0)
+		return;
+
+	copylen = buf->size;
+	if (copylen > datasize - 1)
+		copylen = datasize - 1;
+	memmove(data, buf->ptr, copylen);
+	data[copylen] = '\0';
+}
+
+void git_buf_consume(git_buf *buf, const char *end)
+{
+	if (end > buf->ptr && end <= buf->ptr + buf->size) {
+		size_t consumed = end - buf->ptr;
+		memmove(buf->ptr, end, buf->size - consumed);
+		buf->size -= consumed;
+		buf->ptr[buf->size] = '\0';
+	}
+}
+
+void git_buf_truncate(git_buf *buf, size_t len)
+{
+	if (len >= buf->size)
+		return;
+
+	buf->size = len;
+	if (buf->size < buf->asize)
+		buf->ptr[buf->size] = '\0';
+}
+
+void git_buf_shorten(git_buf *buf, size_t amount)
+{
+	if (buf->size > amount)
+		git_buf_truncate(buf, buf->size - amount);
+	else
+		git_buf_clear(buf);
+}
+
+void git_buf_rtruncate_at_char(git_buf *buf, char separator)
+{
+	ssize_t idx = git_buf_rfind_next(buf, separator);
+	git_buf_truncate(buf, idx < 0 ? 0 : (size_t)idx);
+}
+
+void git_buf_swap(git_buf *buf_a, git_buf *buf_b)
+{
+	git_buf t = *buf_a;
+	*buf_a = *buf_b;
+	*buf_b = t;
+}
+
+char *git_buf_detach(git_buf *buf)
+{
+	char *data = buf->ptr;
+
+	if (buf->asize == 0 || buf->ptr == git_buf__oom)
+		return NULL;
+
+	git_buf_init(buf, 0);
+
+	return data;
+}
+
+void git_buf_attach(git_buf *buf, char *ptr, size_t asize)
+{
+	git_buf_free(buf);
+
+	if (ptr) {
+		buf->ptr = ptr;
+		buf->size = strlen(ptr);
+		if (asize)
+			buf->asize = (asize < buf->size) ? buf->size + 1 : asize;
+		else /* pass 0 to fall back on strlen + 1 */
+			buf->asize = buf->size + 1;
+	} else {
+		git_buf_grow(buf, asize);
+	}
+}
+
+void git_buf_attach_notowned(git_buf *buf, const char *ptr, size_t size)
+{
+	if (git_buf_is_allocated(buf))
+		git_buf_free(buf);
+
+	if (!size) {
+		git_buf_init(buf, 0);
+	} else {
+		buf->ptr = (char *)ptr;
+		buf->asize = 0;
+		buf->size = size;
+	}
+}
+
+int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
+{
+	va_list ap;
+	int i;
+	size_t total_size = 0, original_size = buf->size;
+	char *out, *original = buf->ptr;
+
+	if (buf->size > 0 && buf->ptr[buf->size - 1] != separator)
+		++total_size; /* space for initial separator */
+
+	/* Make two passes to avoid multiple reallocation */
+
+	va_start(ap, nbuf);
+	for (i = 0; i < nbuf; ++i) {
+		const char* segment;
+		size_t segment_len;
+
+		segment = va_arg(ap, const char *);
+		if (!segment)
+			continue;
+
+		segment_len = strlen(segment);
+
+		GITERR_CHECK_ALLOC_ADD(&total_size, total_size, segment_len);
+
+		if (segment_len == 0 || segment[segment_len - 1] != separator)
+			GITERR_CHECK_ALLOC_ADD(&total_size, total_size, 1);
+	}
+	va_end(ap);
+
+	/* expand buffer if needed */
+	if (total_size == 0)
+		return 0;
+
+	GITERR_CHECK_ALLOC_ADD(&total_size, total_size, 1);
+	if (git_buf_grow_by(buf, total_size) < 0)
+		return -1;
+
+	out = buf->ptr + buf->size;
+
+	/* append separator to existing buf if needed */
+	if (buf->size > 0 && out[-1] != separator)
+		*out++ = separator;
+
+	va_start(ap, nbuf);
+	for (i = 0; i < nbuf; ++i) {
+		const char* segment;
+		size_t segment_len;
+
+		segment = va_arg(ap, const char *);
+		if (!segment)
+			continue;
+
+		/* deal with join that references buffer's original content */
+		if (segment >= original && segment < original + original_size) {
+			size_t offset = (segment - original);
+			segment = buf->ptr + offset;
+			segment_len = original_size - offset;
+		} else {
+			segment_len = strlen(segment);
+		}
+
+		/* skip leading separators */
+		if (out > buf->ptr && out[-1] == separator)
+			while (segment_len > 0 && *segment == separator) {
+				segment++;
+				segment_len--;
+			}
+
+		/* copy over next buffer */
+		if (segment_len > 0) {
+			memmove(out, segment, segment_len);
+			out += segment_len;
+		}
+
+		/* append trailing separator (except for last item) */
+		if (i < nbuf - 1 && out > buf->ptr && out[-1] != separator)
+			*out++ = separator;
+	}
+	va_end(ap);
+
+	/* set size based on num characters actually written */
+	buf->size = out - buf->ptr;
+	buf->ptr[buf->size] = '\0';
+
+	return 0;
+}
+
+int git_buf_join(
+	git_buf *buf,
+	char separator,
+	const char *str_a,
+	const char *str_b)
+{
+	size_t strlen_a = str_a ? strlen(str_a) : 0;
+	size_t strlen_b = strlen(str_b);
+	size_t alloc_len;
+	int need_sep = 0;
+	ssize_t offset_a = -1;
+
+	/* not safe to have str_b point internally to the buffer */
+	assert(str_b < buf->ptr || str_b >= buf->ptr + buf->size);
+
+	/* figure out if we need to insert a separator */
+	if (separator && strlen_a) {
+		while (*str_b == separator) { str_b++; strlen_b--; }
+		if (str_a[strlen_a - 1] != separator)
+			need_sep = 1;
+	}
+
+	/* str_a could be part of the buffer */
+	if (str_a >= buf->ptr && str_a < buf->ptr + buf->size)
+		offset_a = str_a - buf->ptr;
+
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, strlen_a, strlen_b);
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, need_sep);
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 1);
+	if (git_buf_grow(buf, alloc_len) < 0)
+		return -1;
+	assert(buf->ptr);
+
+	/* fix up internal pointers */
+	if (offset_a >= 0)
+		str_a = buf->ptr + offset_a;
+
+	/* do the actual copying */
+	if (offset_a != 0 && str_a)
+		memmove(buf->ptr, str_a, strlen_a);
+	if (need_sep)
+		buf->ptr[strlen_a] = separator;
+	memcpy(buf->ptr + strlen_a + need_sep, str_b, strlen_b);
+
+	buf->size = strlen_a + strlen_b + need_sep;
+	buf->ptr[buf->size] = '\0';
+
+	return 0;
+}
+
+int git_buf_join3(
+	git_buf *buf,
+	char separator,
+	const char *str_a,
+	const char *str_b,
+	const char *str_c)
+{
+	size_t len_a = strlen(str_a),
+		len_b = strlen(str_b),
+		len_c = strlen(str_c),
+		len_total;
+	int sep_a = 0, sep_b = 0;
+	char *tgt;
+
+	/* for this function, disallow pointers into the existing buffer */
+	assert(str_a < buf->ptr || str_a >= buf->ptr + buf->size);
+	assert(str_b < buf->ptr || str_b >= buf->ptr + buf->size);
+	assert(str_c < buf->ptr || str_c >= buf->ptr + buf->size);
+
+	if (separator) {
+		if (len_a > 0) {
+			while (*str_b == separator) { str_b++; len_b--; }
+			sep_a = (str_a[len_a - 1] != separator);
+		}
+		if (len_a > 0 || len_b > 0)
+			while (*str_c == separator) { str_c++; len_c--; }
+		if (len_b > 0)
+			sep_b = (str_b[len_b - 1] != separator);
+	}
+
+	GITERR_CHECK_ALLOC_ADD(&len_total, len_a, sep_a);
+	GITERR_CHECK_ALLOC_ADD(&len_total, len_total, len_b);
+	GITERR_CHECK_ALLOC_ADD(&len_total, len_total, sep_b);
+	GITERR_CHECK_ALLOC_ADD(&len_total, len_total, len_c);
+	GITERR_CHECK_ALLOC_ADD(&len_total, len_total, 1);
+	if (git_buf_grow(buf, len_total) < 0)
+		return -1;
+
+	tgt = buf->ptr;
+
+	if (len_a) {
+		memcpy(tgt, str_a, len_a);
+		tgt += len_a;
+	}
+	if (sep_a)
+		*tgt++ = separator;
+	if (len_b) {
+		memcpy(tgt, str_b, len_b);
+		tgt += len_b;
+	}
+	if (sep_b)
+		*tgt++ = separator;
+	if (len_c)
+		memcpy(tgt, str_c, len_c);
+
+	buf->size = len_a + sep_a + len_b + sep_b + len_c;
+	buf->ptr[buf->size] = '\0';
+
+	return 0;
+}
+
+void git_buf_rtrim(git_buf *buf)
+{
+	while (buf->size > 0) {
+		if (!git__isspace(buf->ptr[buf->size - 1]))
+			break;
+
+		buf->size--;
+	}
+
+	if (buf->asize > buf->size)
+		buf->ptr[buf->size] = '\0';
+}
+
+int git_buf_cmp(const git_buf *a, const git_buf *b)
+{
+	int result = memcmp(a->ptr, b->ptr, min(a->size, b->size));
+	return (result != 0) ? result :
+		(a->size < b->size) ? -1 : (a->size > b->size) ? 1 : 0;
+}
+
+int git_buf_splice(
+	git_buf *buf,
+	size_t where,
+	size_t nb_to_remove,
+	const char *data,
+	size_t nb_to_insert)
+{
+	char *splice_loc;
+	size_t new_size, alloc_size;
+
+	assert(buf && where <= buf->size && nb_to_remove <= buf->size - where);
+
+	splice_loc = buf->ptr + where;
+
+	/* Ported from git.git
+	 * https://github.com/git/git/blob/16eed7c/strbuf.c#L159-176
+	 */
+	GITERR_CHECK_ALLOC_ADD(&new_size, (buf->size - nb_to_remove), nb_to_insert);
+	GITERR_CHECK_ALLOC_ADD(&alloc_size, new_size, 1);
+	ENSURE_SIZE(buf, alloc_size);
+
+	memmove(splice_loc + nb_to_insert,
+		splice_loc + nb_to_remove,
+		buf->size - where - nb_to_remove);
+
+	memcpy(splice_loc, data, nb_to_insert);
+
+	buf->size = new_size;
+	buf->ptr[buf->size] = '\0';
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/buffer.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/buffer.h
new file mode 100755
index 0000000..e46ee5d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/buffer.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_buffer_h__
+#define INCLUDE_buffer_h__
+
+#include "common.h"
+#include "git2/strarray.h"
+#include "git2/buffer.h"
+
+/* typedef struct {
+ *  	char   *ptr;
+ *  	size_t asize, size;
+ * } git_buf;
+ */
+
+extern char git_buf__initbuf[];
+extern char git_buf__oom[];
+
+/* Use to initialize buffer structure when git_buf is on stack */
+#define GIT_BUF_INIT { git_buf__initbuf, 0, 0 }
+
+GIT_INLINE(bool) git_buf_is_allocated(const git_buf *buf)
+{
+	return (buf->ptr != NULL && buf->asize > 0);
+}
+
+/**
+ * Initialize a git_buf structure.
+ *
+ * For the cases where GIT_BUF_INIT cannot be used to do static
+ * initialization.
+ */
+extern void git_buf_init(git_buf *buf, size_t initial_size);
+
+/**
+ * Resize the buffer allocation to make more space.
+ *
+ * This will attempt to grow the buffer to accommodate the additional size.
+ * It is similar to `git_buf_grow`, but performs the new size calculation,
+ * checking for overflow.
+ *
+ * Like `git_buf_grow`, if this is a user-supplied buffer, this will allocate
+ * a new buffer.
+ */
+extern int git_buf_grow_by(git_buf *buffer, size_t additional_size);
+
+/**
+ * Attempt to grow the buffer to hold at least `target_size` bytes.
+ *
+ * If the allocation fails, this will return an error.  If `mark_oom` is true,
+ * this will mark the buffer as invalid for future operations; if false,
+ * existing buffer content will be preserved, but calling code must handle
+ * that buffer was not expanded.  If `preserve_external` is true, then any
+ * existing data pointed to be `ptr` even if `asize` is zero will be copied
+ * into the newly allocated buffer.
+ */
+extern int git_buf_try_grow(
+	git_buf *buf, size_t target_size, bool mark_oom);
+
+/**
+ * Sanitizes git_buf structures provided from user input.  Users of the
+ * library, when providing git_buf's, may wish to provide a NULL ptr for
+ * ease of handling.  The buffer routines, however, expect a non-NULL ptr
+ * always.  This helper method simply handles NULL input, converting to a
+ * git_buf__initbuf.
+ */
+extern void git_buf_sanitize(git_buf *buf);
+
+extern void git_buf_swap(git_buf *buf_a, git_buf *buf_b);
+extern char *git_buf_detach(git_buf *buf);
+extern void git_buf_attach(git_buf *buf, char *ptr, size_t asize);
+
+/* Populates a `git_buf` where the contents are not "owned" by the
+ * buffer, and calls to `git_buf_free` will not free the given buf.
+ */
+extern void git_buf_attach_notowned(
+	git_buf *buf, const char *ptr, size_t size);
+
+/**
+ * Test if there have been any reallocation failures with this git_buf.
+ *
+ * Any function that writes to a git_buf can fail due to memory allocation
+ * issues.  If one fails, the git_buf will be marked with an OOM error and
+ * further calls to modify the buffer will fail.  Check git_buf_oom() at the
+ * end of your sequence and it will be true if you ran out of memory at any
+ * point with that buffer.
+ *
+ * @return false if no error, true if allocation error
+ */
+GIT_INLINE(bool) git_buf_oom(const git_buf *buf)
+{
+	return (buf->ptr == git_buf__oom);
+}
+
+/*
+ * Functions below that return int value error codes will return 0 on
+ * success or -1 on failure (which generally means an allocation failed).
+ * Using a git_buf where the allocation has failed with result in -1 from
+ * all further calls using that buffer.  As a result, you can ignore the
+ * return code of these functions and call them in a series then just call
+ * git_buf_oom at the end.
+ */
+int git_buf_sets(git_buf *buf, const char *string);
+int git_buf_putc(git_buf *buf, char c);
+int git_buf_putcn(git_buf *buf, char c, size_t len);
+int git_buf_put(git_buf *buf, const char *data, size_t len);
+int git_buf_puts(git_buf *buf, const char *string);
+int git_buf_printf(git_buf *buf, const char *format, ...) GIT_FORMAT_PRINTF(2, 3);
+int git_buf_vprintf(git_buf *buf, const char *format, va_list ap);
+void git_buf_clear(git_buf *buf);
+void git_buf_consume(git_buf *buf, const char *end);
+void git_buf_truncate(git_buf *buf, size_t len);
+void git_buf_shorten(git_buf *buf, size_t amount);
+void git_buf_rtruncate_at_char(git_buf *path, char separator);
+
+/** General join with separator */
+int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...);
+/** Fast join of two strings - first may legally point into `buf` data */
+int git_buf_join(git_buf *buf, char separator, const char *str_a, const char *str_b);
+/** Fast join of three strings - cannot reference `buf` data */
+int git_buf_join3(git_buf *buf, char separator, const char *str_a, const char *str_b, const char *str_c);
+
+/**
+ * Join two strings as paths, inserting a slash between as needed.
+ * @return 0 on success, -1 on failure
+ */
+GIT_INLINE(int) git_buf_joinpath(git_buf *buf, const char *a, const char *b)
+{
+	return git_buf_join(buf, '/', a, b);
+}
+
+GIT_INLINE(const char *) git_buf_cstr(const git_buf *buf)
+{
+	return buf->ptr;
+}
+
+GIT_INLINE(size_t) git_buf_len(const git_buf *buf)
+{
+	return buf->size;
+}
+
+void git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf);
+
+#define git_buf_PUTS(buf, str) git_buf_put(buf, str, sizeof(str) - 1)
+
+GIT_INLINE(ssize_t) git_buf_rfind_next(const git_buf *buf, char ch)
+{
+	ssize_t idx = (ssize_t)buf->size - 1;
+	while (idx >= 0 && buf->ptr[idx] == ch) idx--;
+	while (idx >= 0 && buf->ptr[idx] != ch) idx--;
+	return idx;
+}
+
+GIT_INLINE(ssize_t) git_buf_rfind(const git_buf *buf, char ch)
+{
+	ssize_t idx = (ssize_t)buf->size - 1;
+	while (idx >= 0 && buf->ptr[idx] != ch) idx--;
+	return idx;
+}
+
+GIT_INLINE(ssize_t) git_buf_find(const git_buf *buf, char ch)
+{
+	void *found = memchr(buf->ptr, ch, buf->size);
+	return found ? (ssize_t)((const char *)found - buf->ptr) : -1;
+}
+
+/* Remove whitespace from the end of the buffer */
+void git_buf_rtrim(git_buf *buf);
+
+int git_buf_cmp(const git_buf *a, const git_buf *b);
+
+/* Write data as base64 encoded in buffer */
+int git_buf_encode_base64(git_buf *buf, const char *data, size_t len);
+/* Decode the given bas64 and write the result to the buffer */
+int git_buf_decode_base64(git_buf *buf, const char *base64, size_t len);
+
+/* Write data as "base85" encoded in buffer */
+int git_buf_encode_base85(git_buf *buf, const char *data, size_t len);
+
+/*
+ * Insert, remove or replace a portion of the buffer.
+ *
+ * @param buf The buffer to work with
+ *
+ * @param where The location in the buffer where the transformation
+ * should be applied.
+ *
+ * @param nb_to_remove The number of chars to be removed. 0 to not
+ * remove any character in the buffer.
+ *
+ * @param data A pointer to the data which should be inserted.
+ *
+ * @param nb_to_insert The number of chars to be inserted. 0 to not
+ * insert any character from the buffer.
+ *
+ * @return 0 or an error code.
+ */
+int git_buf_splice(
+	git_buf *buf,
+	size_t where,
+	size_t nb_to_remove,
+	const char *data,
+	size_t nb_to_insert);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/cache.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/cache.c
new file mode 100755
index 0000000..ca5173c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/cache.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "repository.h"
+#include "commit.h"
+#include "thread-utils.h"
+#include "util.h"
+#include "cache.h"
+#include "odb.h"
+#include "object.h"
+#include "git2/oid.h"
+
+GIT__USE_OIDMAP
+
+bool git_cache__enabled = true;
+ssize_t git_cache__max_storage = (256 * 1024 * 1024);
+git_atomic_ssize git_cache__current_storage = {0};
+
+static size_t git_cache__max_object_size[8] = {
+	0,     /* GIT_OBJ__EXT1 */
+	4096,  /* GIT_OBJ_COMMIT */
+	4096,  /* GIT_OBJ_TREE */
+	0,     /* GIT_OBJ_BLOB */
+	4096,  /* GIT_OBJ_TAG */
+	0,     /* GIT_OBJ__EXT2 */
+	0,     /* GIT_OBJ_OFS_DELTA */
+	0      /* GIT_OBJ_REF_DELTA */
+};
+
+int git_cache_set_max_object_size(git_otype type, size_t size)
+{
+	if (type < 0 || (size_t)type >= ARRAY_SIZE(git_cache__max_object_size)) {
+		giterr_set(GITERR_INVALID, "type out of range");
+		return -1;
+	}
+
+	git_cache__max_object_size[type] = size;
+	return 0;
+}
+
+void git_cache_dump_stats(git_cache *cache)
+{
+	git_cached_obj *object;
+
+	if (kh_size(cache->map) == 0)
+		return;
+
+	printf("Cache %p: %d items cached, %"PRIdZ" bytes\n",
+		cache, kh_size(cache->map), cache->used_memory);
+
+	kh_foreach_value(cache->map, object, {
+		char oid_str[9];
+		printf(" %s%c %s (%"PRIuZ")\n",
+			git_object_type2string(object->type),
+			object->flags == GIT_CACHE_STORE_PARSED ? '*' : ' ',
+			git_oid_tostr(oid_str, sizeof(oid_str), &object->oid),
+			object->size
+		);
+	});
+}
+
+int git_cache_init(git_cache *cache)
+{
+	memset(cache, 0, sizeof(*cache));
+	cache->map = git_oidmap_alloc();
+	GITERR_CHECK_ALLOC(cache->map);
+	if (git_rwlock_init(&cache->lock)) {
+		giterr_set(GITERR_OS, "Failed to initialize cache rwlock");
+		return -1;
+	}
+	return 0;
+}
+
+/* called with lock */
+static void clear_cache(git_cache *cache)
+{
+	git_cached_obj *evict = NULL;
+
+	if (kh_size(cache->map) == 0)
+		return;
+
+	kh_foreach_value(cache->map, evict, {
+		git_cached_obj_decref(evict);
+	});
+
+	kh_clear(oid, cache->map);
+	git_atomic_ssize_add(&git_cache__current_storage, -cache->used_memory);
+	cache->used_memory = 0;
+}
+
+void git_cache_clear(git_cache *cache)
+{
+	if (git_rwlock_wrlock(&cache->lock) < 0)
+		return;
+
+	clear_cache(cache);
+
+	git_rwlock_wrunlock(&cache->lock);
+}
+
+void git_cache_free(git_cache *cache)
+{
+	git_cache_clear(cache);
+	git_oidmap_free(cache->map);
+	git_rwlock_free(&cache->lock);
+	git__memzero(cache, sizeof(*cache));
+}
+
+/* Called with lock */
+static void cache_evict_entries(git_cache *cache)
+{
+	uint32_t seed = rand();
+	size_t evict_count = 8;
+	ssize_t evicted_memory = 0;
+
+	/* do not infinite loop if there's not enough entries to evict  */
+	if (evict_count > kh_size(cache->map)) {
+		clear_cache(cache);
+		return;
+	}
+
+	while (evict_count > 0) {
+		khiter_t pos = seed++ % kh_end(cache->map);
+
+		if (kh_exist(cache->map, pos)) {
+			git_cached_obj *evict = kh_val(cache->map, pos);
+
+			evict_count--;
+			evicted_memory += evict->size;
+			git_cached_obj_decref(evict);
+
+			kh_del(oid, cache->map, pos);
+		}
+	}
+
+	cache->used_memory -= evicted_memory;
+	git_atomic_ssize_add(&git_cache__current_storage, -evicted_memory);
+}
+
+static bool cache_should_store(git_otype object_type, size_t object_size)
+{
+	size_t max_size = git_cache__max_object_size[object_type];
+	return git_cache__enabled && object_size < max_size;
+}
+
+static void *cache_get(git_cache *cache, const git_oid *oid, unsigned int flags)
+{
+	khiter_t pos;
+	git_cached_obj *entry = NULL;
+
+	if (!git_cache__enabled || git_rwlock_rdlock(&cache->lock) < 0)
+		return NULL;
+
+	pos = kh_get(oid, cache->map, oid);
+	if (pos != kh_end(cache->map)) {
+		entry = kh_val(cache->map, pos);
+
+		if (flags && entry->flags != flags) {
+			entry = NULL;
+		} else {
+			git_cached_obj_incref(entry);
+		}
+	}
+
+	git_rwlock_rdunlock(&cache->lock);
+
+	return entry;
+}
+
+static void *cache_store(git_cache *cache, git_cached_obj *entry)
+{
+	khiter_t pos;
+
+	git_cached_obj_incref(entry);
+
+	if (!git_cache__enabled && cache->used_memory > 0) {
+		git_cache_clear(cache);
+		return entry;
+	}
+
+	if (!cache_should_store(entry->type, entry->size))
+		return entry;
+
+	if (git_rwlock_wrlock(&cache->lock) < 0)
+		return entry;
+
+	/* soften the load on the cache */
+	if (git_cache__current_storage.val > git_cache__max_storage)
+		cache_evict_entries(cache);
+
+	pos = kh_get(oid, cache->map, &entry->oid);
+
+	/* not found */
+	if (pos == kh_end(cache->map)) {
+		int rval;
+
+		pos = kh_put(oid, cache->map, &entry->oid, &rval);
+		if (rval >= 0) {
+			kh_key(cache->map, pos) = &entry->oid;
+			kh_val(cache->map, pos) = entry;
+			git_cached_obj_incref(entry);
+			cache->used_memory += entry->size;
+			git_atomic_ssize_add(&git_cache__current_storage, (ssize_t)entry->size);
+		}
+	}
+	/* found */
+	else {
+		git_cached_obj *stored_entry = kh_val(cache->map, pos);
+
+		if (stored_entry->flags == entry->flags) {
+			git_cached_obj_decref(entry);
+			git_cached_obj_incref(stored_entry);
+			entry = stored_entry;
+		} else if (stored_entry->flags == GIT_CACHE_STORE_RAW &&
+			entry->flags == GIT_CACHE_STORE_PARSED) {
+			git_cached_obj_decref(stored_entry);
+			git_cached_obj_incref(entry);
+
+			kh_key(cache->map, pos) = &entry->oid;
+			kh_val(cache->map, pos) = entry;
+		} else {
+			/* NO OP */
+		}
+	}
+
+	git_rwlock_wrunlock(&cache->lock);
+	return entry;
+}
+
+void *git_cache_store_raw(git_cache *cache, git_odb_object *entry)
+{
+	entry->cached.flags = GIT_CACHE_STORE_RAW;
+	return cache_store(cache, (git_cached_obj *)entry);
+}
+
+void *git_cache_store_parsed(git_cache *cache, git_object *entry)
+{
+	entry->cached.flags = GIT_CACHE_STORE_PARSED;
+	return cache_store(cache, (git_cached_obj *)entry);
+}
+
+git_odb_object *git_cache_get_raw(git_cache *cache, const git_oid *oid)
+{
+	return cache_get(cache, oid, GIT_CACHE_STORE_RAW);
+}
+
+git_object *git_cache_get_parsed(git_cache *cache, const git_oid *oid)
+{
+	return cache_get(cache, oid, GIT_CACHE_STORE_PARSED);
+}
+
+void *git_cache_get_any(git_cache *cache, const git_oid *oid)
+{
+	return cache_get(cache, oid, GIT_CACHE_STORE_ANY);
+}
+
+void git_cached_obj_decref(void *_obj)
+{
+	git_cached_obj *obj = _obj;
+
+	if (git_atomic_dec(&obj->refcount) == 0) {
+		switch (obj->flags) {
+		case GIT_CACHE_STORE_RAW:
+			git_odb_object__free(_obj);
+			break;
+
+		case GIT_CACHE_STORE_PARSED:
+			git_object__free(_obj);
+			break;
+
+		default:
+			git__free(_obj);
+			break;
+		}
+	}
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/cache.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/cache.h
new file mode 100755
index 0000000..6971237
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/cache.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_cache_h__
+#define INCLUDE_cache_h__
+
+#include "git2/common.h"
+#include "git2/oid.h"
+#include "git2/odb.h"
+
+#include "thread-utils.h"
+#include "oidmap.h"
+
+enum {
+	GIT_CACHE_STORE_ANY = 0,
+	GIT_CACHE_STORE_RAW = 1,
+	GIT_CACHE_STORE_PARSED = 2
+};
+
+typedef struct {
+	git_oid    oid;
+	int16_t    type;  /* git_otype value */
+	uint16_t   flags; /* GIT_CACHE_STORE value */
+	size_t     size;
+	git_atomic refcount;
+} git_cached_obj;
+
+typedef struct {
+	git_oidmap *map;
+	git_rwlock  lock;
+	ssize_t     used_memory;
+} git_cache;
+
+extern bool git_cache__enabled;
+extern ssize_t git_cache__max_storage;
+extern git_atomic_ssize git_cache__current_storage;
+
+int git_cache_set_max_object_size(git_otype type, size_t size);
+
+int git_cache_init(git_cache *cache);
+void git_cache_free(git_cache *cache);
+void git_cache_clear(git_cache *cache);
+
+void *git_cache_store_raw(git_cache *cache, git_odb_object *entry);
+void *git_cache_store_parsed(git_cache *cache, git_object *entry);
+
+git_odb_object *git_cache_get_raw(git_cache *cache, const git_oid *oid);
+git_object *git_cache_get_parsed(git_cache *cache, const git_oid *oid);
+void *git_cache_get_any(git_cache *cache, const git_oid *oid);
+
+GIT_INLINE(size_t) git_cache_size(git_cache *cache)
+{
+	return (size_t)kh_size(cache->map);
+}
+
+GIT_INLINE(void) git_cached_obj_incref(void *_obj)
+{
+	git_cached_obj *obj = _obj;
+	git_atomic_inc(&obj->refcount);
+}
+
+void git_cached_obj_decref(void *_obj);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/cc-compat.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/cc-compat.h
new file mode 100755
index 0000000..cefdc92
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/cc-compat.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_compat_h__
+#define INCLUDE_compat_h__
+
+#include <stdarg.h>
+
+/*
+ * See if our compiler is known to support flexible array members.
+ */
+#ifndef GIT_FLEX_ARRAY
+#	if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+#		define GIT_FLEX_ARRAY /* empty */
+#	elif defined(__GNUC__)
+#		if (__GNUC__ >= 3)
+#			define GIT_FLEX_ARRAY /* empty */
+#		else
+#			define GIT_FLEX_ARRAY 0 /* older GNU extension */
+#		endif
+#	endif
+
+/* Default to safer but a bit wasteful traditional style */
+#	ifndef GIT_FLEX_ARRAY
+#		define GIT_FLEX_ARRAY 1
+#	endif
+#endif
+
+#ifdef __GNUC__
+#	define GIT_TYPEOF(x) (__typeof__(x))
+#else
+#	define GIT_TYPEOF(x)
+#endif
+
+#if defined(__GNUC__)
+#	define GIT_ALIGN(x,size) x __attribute__ ((aligned(size)))
+#elif defined(_MSC_VER)
+#	define GIT_ALIGN(x,size) __declspec(align(size)) x
+#else
+#	define GIT_ALIGN(x,size) x
+#endif
+
+#define GIT_UNUSED(x) ((void)(x))
+
+/* Define the printf format specifer to use for size_t output */
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#	define PRIuZ "Iu"
+#	define PRIxZ "Ix"
+#	define PRIdZ "Id"
+#else
+#	define PRIuZ "zu"
+#	define PRIxZ "zx"
+#	define PRIdZ "zd"
+#endif
+
+/* Micosoft Visual C/C++ */
+#if defined(_MSC_VER)
+/* disable "deprecated function" warnings */
+#	pragma warning ( disable : 4996 )
+/* disable "conditional expression is constant" level 4 warnings */
+#	pragma warning ( disable : 4127 )
+#endif
+
+#if defined (_MSC_VER)
+	typedef unsigned char bool;
+#	ifndef true
+#		define true 1
+#	endif
+#	ifndef false
+#		define false 0
+#	endif
+#else
+#	include <stdbool.h>
+#endif
+
+#ifndef va_copy
+#	ifdef __va_copy
+#		define va_copy(dst, src) __va_copy(dst, src)
+#	else
+#		define va_copy(dst, src) ((dst) = (src))
+#	endif
+#endif
+
+#endif /* INCLUDE_compat_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/checkout.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/checkout.c
new file mode 100755
index 0000000..e7699d9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/checkout.c
@@ -0,0 +1,2708 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include <assert.h>
+
+#include "checkout.h"
+
+#include "git2/repository.h"
+#include "git2/refs.h"
+#include "git2/tree.h"
+#include "git2/blob.h"
+#include "git2/config.h"
+#include "git2/diff.h"
+#include "git2/submodule.h"
+#include "git2/sys/index.h"
+#include "git2/sys/filter.h"
+#include "git2/merge.h"
+
+#include "refs.h"
+#include "repository.h"
+#include "index.h"
+#include "filter.h"
+#include "blob.h"
+#include "diff.h"
+#include "pathspec.h"
+#include "buf_text.h"
+#include "diff_xdiff.h"
+#include "path.h"
+#include "attr.h"
+#include "pool.h"
+#include "strmap.h"
+
+GIT__USE_STRMAP
+
+/* See docs/checkout-internals.md for more information */
+
+enum {
+	CHECKOUT_ACTION__NONE = 0,
+	CHECKOUT_ACTION__REMOVE = 1,
+	CHECKOUT_ACTION__UPDATE_BLOB = 2,
+	CHECKOUT_ACTION__UPDATE_SUBMODULE = 4,
+	CHECKOUT_ACTION__CONFLICT = 8,
+	CHECKOUT_ACTION__REMOVE_CONFLICT = 16,
+	CHECKOUT_ACTION__UPDATE_CONFLICT = 32,
+	CHECKOUT_ACTION__MAX = 32,
+	CHECKOUT_ACTION__DEFER_REMOVE = 64,
+	CHECKOUT_ACTION__REMOVE_AND_UPDATE =
+		(CHECKOUT_ACTION__UPDATE_BLOB | CHECKOUT_ACTION__REMOVE),
+};
+
+typedef struct {
+	git_repository *repo;
+	git_iterator *target;
+	git_diff *diff;
+	git_checkout_options opts;
+	bool opts_free_baseline;
+	char *pfx;
+	git_index *index;
+	git_pool pool;
+	git_vector removes;
+	git_vector remove_conflicts;
+	git_vector update_conflicts;
+	git_vector *update_reuc;
+	git_vector *update_names;
+	git_buf path;
+	size_t workdir_len;
+	git_buf tmp;
+	unsigned int strategy;
+	int can_symlink;
+	bool reload_submodules;
+	size_t total_steps;
+	size_t completed_steps;
+	git_checkout_perfdata perfdata;
+	git_strmap *mkdir_map;
+	git_attr_session attr_session;
+} checkout_data;
+
+typedef struct {
+	const git_index_entry *ancestor;
+	const git_index_entry *ours;
+	const git_index_entry *theirs;
+
+	int name_collision:1,
+		directoryfile:1,
+		one_to_two:1,
+		binary:1,
+		submodule:1;
+} checkout_conflictdata;
+
+static int checkout_notify(
+	checkout_data *data,
+	git_checkout_notify_t why,
+	const git_diff_delta *delta,
+	const git_index_entry *wditem)
+{
+	git_diff_file wdfile;
+	const git_diff_file *baseline = NULL, *target = NULL, *workdir = NULL;
+	const char *path = NULL;
+
+	if (!data->opts.notify_cb ||
+		(why & data->opts.notify_flags) == 0)
+		return 0;
+
+	if (wditem) {
+		memset(&wdfile, 0, sizeof(wdfile));
+
+		git_oid_cpy(&wdfile.id, &wditem->id);
+		wdfile.path = wditem->path;
+		wdfile.size = wditem->file_size;
+		wdfile.flags = GIT_DIFF_FLAG_VALID_ID;
+		wdfile.mode = wditem->mode;
+
+		workdir = &wdfile;
+
+		path = wditem->path;
+	}
+
+	if (delta) {
+		switch (delta->status) {
+		case GIT_DELTA_UNMODIFIED:
+		case GIT_DELTA_MODIFIED:
+		case GIT_DELTA_TYPECHANGE:
+		default:
+			baseline = &delta->old_file;
+			target = &delta->new_file;
+			break;
+		case GIT_DELTA_ADDED:
+		case GIT_DELTA_IGNORED:
+		case GIT_DELTA_UNTRACKED:
+		case GIT_DELTA_UNREADABLE:
+			target = &delta->new_file;
+			break;
+		case GIT_DELTA_DELETED:
+			baseline = &delta->old_file;
+			break;
+		}
+
+		path = delta->old_file.path;
+	}
+
+	{
+		int error = data->opts.notify_cb(
+			why, path, baseline, target, workdir, data->opts.notify_payload);
+
+		return giterr_set_after_callback_function(
+			error, "git_checkout notification");
+	}
+}
+
+GIT_INLINE(bool) is_workdir_base_or_new(
+	const git_oid *workdir_id,
+	const git_diff_file *baseitem,
+	const git_diff_file *newitem)
+{
+	return (git_oid__cmp(&baseitem->id, workdir_id) == 0 ||
+		git_oid__cmp(&newitem->id, workdir_id) == 0);
+}
+
+static bool checkout_is_workdir_modified(
+	checkout_data *data,
+	const git_diff_file *baseitem,
+	const git_diff_file *newitem,
+	const git_index_entry *wditem)
+{
+	git_oid oid;
+	const git_index_entry *ie;
+
+	/* handle "modified" submodule */
+	if (wditem->mode == GIT_FILEMODE_COMMIT) {
+		git_submodule *sm;
+		unsigned int sm_status = 0;
+		const git_oid *sm_oid = NULL;
+		bool rval = false;
+
+		if (git_submodule_lookup(&sm, data->repo, wditem->path) < 0) {
+			giterr_clear();
+			return true;
+		}
+
+		if (git_submodule_status(&sm_status, data->repo, wditem->path, GIT_SUBMODULE_IGNORE_UNSPECIFIED) < 0 ||
+			GIT_SUBMODULE_STATUS_IS_WD_DIRTY(sm_status))
+			rval = true;
+		else if ((sm_oid = git_submodule_wd_id(sm)) == NULL)
+			rval = false;
+		else
+			rval = (git_oid__cmp(&baseitem->id, sm_oid) != 0);
+
+		git_submodule_free(sm);
+		return rval;
+	}
+
+	/* Look at the cache to decide if the workdir is modified.  If not,
+	 * we can simply compare the oid in the cache to the baseitem instead
+	 * of hashing the file.  If so, we allow the checkout to proceed if the
+	 * oid is identical (ie, the staged item is what we're trying to check
+	 * out.)
+	 */
+	if ((ie = git_index_get_bypath(data->index, wditem->path, 0)) != NULL) {
+		if (wditem->mtime.seconds == ie->mtime.seconds &&
+			wditem->mtime.nanoseconds == ie->mtime.nanoseconds &&
+			wditem->file_size == ie->file_size)
+			return !is_workdir_base_or_new(&ie->id, baseitem, newitem);
+	}
+
+	/* depending on where base is coming from, we may or may not know
+	 * the actual size of the data, so we can't rely on this shortcut.
+	 */
+	if (baseitem->size && wditem->file_size != baseitem->size)
+		return true;
+
+	if (git_diff__oid_for_entry(&oid, data->diff, wditem, wditem->mode, NULL) < 0)
+		return false;
+
+	/* Allow the checkout if the workdir is not modified *or* if the checkout
+	 * target's contents are already in the working directory.
+	 */
+	return !is_workdir_base_or_new(&oid, baseitem, newitem);
+}
+
+#define CHECKOUT_ACTION_IF(FLAG,YES,NO) \
+	((data->strategy & GIT_CHECKOUT_##FLAG) ? CHECKOUT_ACTION__##YES : CHECKOUT_ACTION__##NO)
+
+static int checkout_action_common(
+	int *action,
+	checkout_data *data,
+	const git_diff_delta *delta,
+	const git_index_entry *wd)
+{
+	git_checkout_notify_t notify = GIT_CHECKOUT_NOTIFY_NONE;
+
+	if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0)
+		*action = (*action & ~CHECKOUT_ACTION__REMOVE);
+
+	if ((*action & CHECKOUT_ACTION__UPDATE_BLOB) != 0) {
+		if (S_ISGITLINK(delta->new_file.mode))
+			*action = (*action & ~CHECKOUT_ACTION__UPDATE_BLOB) |
+				CHECKOUT_ACTION__UPDATE_SUBMODULE;
+
+		/* to "update" a symlink, we must remove the old one first */
+		if (delta->new_file.mode == GIT_FILEMODE_LINK && wd != NULL)
+			*action |= CHECKOUT_ACTION__REMOVE;
+
+		notify = GIT_CHECKOUT_NOTIFY_UPDATED;
+	}
+
+	if ((*action & CHECKOUT_ACTION__CONFLICT) != 0)
+		notify = GIT_CHECKOUT_NOTIFY_CONFLICT;
+
+	return checkout_notify(data, notify, delta, wd);
+}
+
+static int checkout_action_no_wd(
+	int *action,
+	checkout_data *data,
+	const git_diff_delta *delta)
+{
+	int error = 0;
+
+	*action = CHECKOUT_ACTION__NONE;
+
+	switch (delta->status) {
+	case GIT_DELTA_UNMODIFIED: /* case 12 */
+		error = checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, NULL);
+		if (error)
+			return error;
+		*action = CHECKOUT_ACTION_IF(RECREATE_MISSING, UPDATE_BLOB, NONE);
+		break;
+	case GIT_DELTA_ADDED:    /* case 2 or 28 (and 5 but not really) */
+		*action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
+		break;
+	case GIT_DELTA_MODIFIED: /* case 13 (and 35 but not really) */
+		*action = CHECKOUT_ACTION_IF(RECREATE_MISSING, UPDATE_BLOB, CONFLICT);
+		break;
+	case GIT_DELTA_TYPECHANGE: /* case 21 (B->T) and 28 (T->B)*/
+		if (delta->new_file.mode == GIT_FILEMODE_TREE)
+			*action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
+		break;
+	case GIT_DELTA_DELETED: /* case 8 or 25 */
+		*action = CHECKOUT_ACTION_IF(SAFE, REMOVE, NONE);
+		break;
+	default: /* impossible */
+		break;
+	}
+
+	return checkout_action_common(action, data, delta, NULL);
+}
+
+static bool wd_item_is_removable(git_iterator *iter, const git_index_entry *wd)
+{
+	git_buf *full = NULL;
+
+	if (wd->mode != GIT_FILEMODE_TREE)
+		return true;
+	if (git_iterator_current_workdir_path(&full, iter) < 0)
+		return true;
+	return !full || !git_path_contains(full, DOT_GIT);
+}
+
+static int checkout_queue_remove(checkout_data *data, const char *path)
+{
+	char *copy = git_pool_strdup(&data->pool, path);
+	GITERR_CHECK_ALLOC(copy);
+	return git_vector_insert(&data->removes, copy);
+}
+
+/* note that this advances the iterator over the wd item */
+static int checkout_action_wd_only(
+	checkout_data *data,
+	git_iterator *workdir,
+	const git_index_entry **wditem,
+	git_vector *pathspec)
+{
+	int error = 0;
+	bool remove = false;
+	git_checkout_notify_t notify = GIT_CHECKOUT_NOTIFY_NONE;
+	const git_index_entry *wd = *wditem;
+
+	if (!git_pathspec__match(
+			pathspec, wd->path,
+			(data->strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH) != 0,
+			git_iterator_ignore_case(workdir), NULL, NULL))
+		return git_iterator_advance(wditem, workdir);
+
+	/* check if item is tracked in the index but not in the checkout diff */
+	if (data->index != NULL) {
+		size_t pos;
+
+		error = git_index__find_pos(
+			&pos, data->index, wd->path, 0, GIT_INDEX_STAGE_ANY);
+
+		if (wd->mode != GIT_FILEMODE_TREE) {
+			if (!error) { /* found by git_index__find_pos call */
+				notify = GIT_CHECKOUT_NOTIFY_DIRTY;
+				remove = ((data->strategy & GIT_CHECKOUT_FORCE) != 0);
+			} else if (error != GIT_ENOTFOUND)
+				return error;
+			else
+				error = 0; /* git_index__find_pos does not set error msg */
+		} else {
+			/* for tree entries, we have to see if there are any index
+			 * entries that are contained inside that tree
+			 */
+			const git_index_entry *e = git_index_get_byindex(data->index, pos);
+
+			if (e != NULL && data->diff->pfxcomp(e->path, wd->path) == 0) {
+				notify = GIT_CHECKOUT_NOTIFY_DIRTY;
+				remove = ((data->strategy & GIT_CHECKOUT_FORCE) != 0);
+			}
+		}
+	}
+
+	if (notify != GIT_CHECKOUT_NOTIFY_NONE) {
+		/* if we found something in the index, notify and advance */
+		if ((error = checkout_notify(data, notify, NULL, wd)) != 0)
+			return error;
+
+		if (remove && wd_item_is_removable(workdir, wd))
+			error = checkout_queue_remove(data, wd->path);
+
+		if (!error)
+			error = git_iterator_advance(wditem, workdir);
+	} else {
+		/* untracked or ignored - can't know which until we advance through */
+		bool over = false, removable = wd_item_is_removable(workdir, wd);
+		git_iterator_status_t untracked_state;
+
+		/* copy the entry for issuing notification callback later */
+		git_index_entry saved_wd = *wd;
+		git_buf_sets(&data->tmp, wd->path);
+		saved_wd.path = data->tmp.ptr;
+
+		error = git_iterator_advance_over_with_status(
+			wditem, &untracked_state, workdir);
+		if (error == GIT_ITEROVER)
+			over = true;
+		else if (error < 0)
+			return error;
+
+		if (untracked_state == GIT_ITERATOR_STATUS_IGNORED) {
+			notify = GIT_CHECKOUT_NOTIFY_IGNORED;
+			remove = ((data->strategy & GIT_CHECKOUT_REMOVE_IGNORED) != 0);
+		} else {
+			notify = GIT_CHECKOUT_NOTIFY_UNTRACKED;
+			remove = ((data->strategy & GIT_CHECKOUT_REMOVE_UNTRACKED) != 0);
+		}
+
+		if ((error = checkout_notify(data, notify, NULL, &saved_wd)) != 0)
+			return error;
+
+		if (remove && removable)
+			error = checkout_queue_remove(data, saved_wd.path);
+
+		if (!error && over) /* restore ITEROVER if needed */
+			error = GIT_ITEROVER;
+	}
+
+	return error;
+}
+
+static bool submodule_is_config_only(
+	checkout_data *data,
+	const char *path)
+{
+	git_submodule *sm = NULL;
+	unsigned int sm_loc = 0;
+	bool rval = false;
+
+	if (git_submodule_lookup(&sm, data->repo, path) < 0)
+		return true;
+
+	if (git_submodule_location(&sm_loc, sm) < 0 ||
+		sm_loc == GIT_SUBMODULE_STATUS_IN_CONFIG)
+		rval = true;
+
+	git_submodule_free(sm);
+
+	return rval;
+}
+
+static bool checkout_is_empty_dir(checkout_data *data, const char *path)
+{
+	git_buf_truncate(&data->path, data->workdir_len);
+	if (git_buf_puts(&data->path, path) < 0)
+		return false;
+	return git_path_is_empty_dir(data->path.ptr);
+}
+
+static int checkout_action_with_wd(
+	int *action,
+	checkout_data *data,
+	const git_diff_delta *delta,
+	git_iterator *workdir,
+	const git_index_entry *wd)
+{
+	*action = CHECKOUT_ACTION__NONE;
+
+	switch (delta->status) {
+	case GIT_DELTA_UNMODIFIED: /* case 14/15 or 33 */
+		if (checkout_is_workdir_modified(data, &delta->old_file, &delta->new_file, wd)) {
+			GITERR_CHECK_ERROR(
+				checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, wd) );
+			*action = CHECKOUT_ACTION_IF(FORCE, UPDATE_BLOB, NONE);
+		}
+		break;
+	case GIT_DELTA_ADDED: /* case 3, 4 or 6 */
+		if (git_iterator_current_is_ignored(workdir))
+			*action = CHECKOUT_ACTION_IF(DONT_OVERWRITE_IGNORED, CONFLICT, UPDATE_BLOB);
+		else
+			*action = CHECKOUT_ACTION_IF(FORCE, UPDATE_BLOB, CONFLICT);
+		break;
+	case GIT_DELTA_DELETED: /* case 9 or 10 (or 26 but not really) */
+		if (checkout_is_workdir_modified(data, &delta->old_file, &delta->new_file, wd))
+			*action = CHECKOUT_ACTION_IF(FORCE, REMOVE, CONFLICT);
+		else
+			*action = CHECKOUT_ACTION_IF(SAFE, REMOVE, NONE);
+		break;
+	case GIT_DELTA_MODIFIED: /* case 16, 17, 18 (or 36 but not really) */
+		if (checkout_is_workdir_modified(data, &delta->old_file, &delta->new_file, wd))
+			*action = CHECKOUT_ACTION_IF(FORCE, UPDATE_BLOB, CONFLICT);
+		else
+			*action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
+		break;
+	case GIT_DELTA_TYPECHANGE: /* case 22, 23, 29, 30 */
+		if (delta->old_file.mode == GIT_FILEMODE_TREE) {
+			if (wd->mode == GIT_FILEMODE_TREE)
+				/* either deleting items in old tree will delete the wd dir,
+				 * or we'll get a conflict when we attempt blob update...
+				 */
+				*action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
+			else if (wd->mode == GIT_FILEMODE_COMMIT) {
+				/* workdir is possibly a "phantom" submodule - treat as a
+				 * tree if the only submodule info came from the config
+				 */
+				if (submodule_is_config_only(data, wd->path))
+					*action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
+				else
+					*action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT);
+			} else
+				*action = CHECKOUT_ACTION_IF(FORCE, REMOVE, CONFLICT);
+		}
+		else if (checkout_is_workdir_modified(data, &delta->old_file, &delta->new_file, wd))
+			*action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT);
+		else
+			*action = CHECKOUT_ACTION_IF(SAFE, REMOVE_AND_UPDATE, NONE);
+
+		/* don't update if the typechange is to a tree */
+		if (delta->new_file.mode == GIT_FILEMODE_TREE)
+			*action = (*action & ~CHECKOUT_ACTION__UPDATE_BLOB);
+		break;
+	default: /* impossible */
+		break;
+	}
+
+	return checkout_action_common(action, data, delta, wd);
+}
+
+static int checkout_action_with_wd_blocker(
+	int *action,
+	checkout_data *data,
+	const git_diff_delta *delta,
+	const git_index_entry *wd)
+{
+	*action = CHECKOUT_ACTION__NONE;
+
+	switch (delta->status) {
+	case GIT_DELTA_UNMODIFIED:
+		/* should show delta as dirty / deleted */
+		GITERR_CHECK_ERROR(
+			checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, wd) );
+		*action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, NONE);
+		break;
+	case GIT_DELTA_ADDED:
+	case GIT_DELTA_MODIFIED:
+		*action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT);
+		break;
+	case GIT_DELTA_DELETED:
+		*action = CHECKOUT_ACTION_IF(FORCE, REMOVE, CONFLICT);
+		break;
+	case GIT_DELTA_TYPECHANGE:
+		/* not 100% certain about this... */
+		*action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT);
+		break;
+	default: /* impossible */
+		break;
+	}
+
+	return checkout_action_common(action, data, delta, wd);
+}
+
+static int checkout_action_with_wd_dir(
+	int *action,
+	checkout_data *data,
+	const git_diff_delta *delta,
+	git_iterator *workdir,
+	const git_index_entry *wd)
+{
+	*action = CHECKOUT_ACTION__NONE;
+
+	switch (delta->status) {
+	case GIT_DELTA_UNMODIFIED: /* case 19 or 24 (or 34 but not really) */
+		GITERR_CHECK_ERROR(
+			checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, NULL));
+		GITERR_CHECK_ERROR(
+			checkout_notify(data, GIT_CHECKOUT_NOTIFY_UNTRACKED, NULL, wd));
+		*action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, NONE);
+		break;
+	case GIT_DELTA_ADDED:/* case 4 (and 7 for dir) */
+	case GIT_DELTA_MODIFIED: /* case 20 (or 37 but not really) */
+		if (delta->old_file.mode == GIT_FILEMODE_COMMIT)
+			/* expected submodule (and maybe found one) */;
+		else if (delta->new_file.mode != GIT_FILEMODE_TREE)
+			*action = git_iterator_current_is_ignored(workdir) ?
+				CHECKOUT_ACTION_IF(DONT_OVERWRITE_IGNORED, CONFLICT, REMOVE_AND_UPDATE) :
+				CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT);
+		break;
+	case GIT_DELTA_DELETED: /* case 11 (and 27 for dir) */
+		if (delta->old_file.mode != GIT_FILEMODE_TREE)
+			GITERR_CHECK_ERROR(
+				checkout_notify(data, GIT_CHECKOUT_NOTIFY_UNTRACKED, NULL, wd));
+		break;
+	case GIT_DELTA_TYPECHANGE: /* case 24 or 31 */
+		if (delta->old_file.mode == GIT_FILEMODE_TREE) {
+			/* For typechange from dir, remove dir and add blob, but it is
+			 * not safe to remove dir if it contains modified files.
+			 * However, safely removing child files will remove the parent
+			 * directory if is it left empty, so we can defer removing the
+			 * dir and it will succeed if no children are left.
+			 */
+			*action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
+		}
+		else if (delta->new_file.mode != GIT_FILEMODE_TREE)
+			/* For typechange to dir, dir is already created so no action */
+			*action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT);
+		break;
+	default: /* impossible */
+		break;
+	}
+
+	return checkout_action_common(action, data, delta, wd);
+}
+
+static int checkout_action_with_wd_dir_empty(
+	int *action,
+	checkout_data *data,
+	const git_diff_delta *delta)
+{
+	int error = checkout_action_no_wd(action, data, delta);
+
+	/* We can always safely remove an empty directory. */
+	if (error == 0 && *action != CHECKOUT_ACTION__NONE)
+		*action |= CHECKOUT_ACTION__REMOVE;
+
+	return error;
+}
+
+static int checkout_action(
+	int *action,
+	checkout_data *data,
+	git_diff_delta *delta,
+	git_iterator *workdir,
+	const git_index_entry **wditem,
+	git_vector *pathspec)
+{
+	int cmp = -1, error;
+	int (*strcomp)(const char *, const char *) = data->diff->strcomp;
+	int (*pfxcomp)(const char *str, const char *pfx) = data->diff->pfxcomp;
+	int (*advance)(const git_index_entry **, git_iterator *) = NULL;
+
+	/* move workdir iterator to follow along with deltas */
+
+	while (1) {
+		const git_index_entry *wd = *wditem;
+
+		if (!wd)
+			return checkout_action_no_wd(action, data, delta);
+
+		cmp = strcomp(wd->path, delta->old_file.path);
+
+		/* 1. wd before delta ("a/a" before "a/b")
+		 * 2. wd prefixes delta & should expand ("a/" before "a/b")
+		 * 3. wd prefixes delta & cannot expand ("a/b" before "a/b/c")
+		 * 4. wd equals delta ("a/b" and "a/b")
+		 * 5. wd after delta & delta prefixes wd ("a/b/c" after "a/b/" or "a/b")
+		 * 6. wd after delta ("a/c" after "a/b")
+		 */
+
+		if (cmp < 0) {
+			cmp = pfxcomp(delta->old_file.path, wd->path);
+
+			if (cmp == 0) {
+				if (wd->mode == GIT_FILEMODE_TREE) {
+					/* case 2 - entry prefixed by workdir tree */
+					error = git_iterator_advance_into_or_over(wditem, workdir);
+					if (error < 0 && error != GIT_ITEROVER)
+						goto done;
+					continue;
+				}
+
+				/* case 3 maybe - wd contains non-dir where dir expected */
+				if (delta->old_file.path[strlen(wd->path)] == '/') {
+					error = checkout_action_with_wd_blocker(
+						action, data, delta, wd);
+					advance = git_iterator_advance;
+					goto done;
+				}
+			}
+
+			/* case 1 - handle wd item (if it matches pathspec) */
+			error = checkout_action_wd_only(data, workdir, wditem, pathspec);
+			if (error && error != GIT_ITEROVER)
+				goto done;
+			continue;
+		}
+
+		if (cmp == 0) {
+			/* case 4 */
+			error = checkout_action_with_wd(action, data, delta, workdir, wd);
+			advance = git_iterator_advance;
+			goto done;
+		}
+
+		cmp = pfxcomp(wd->path, delta->old_file.path);
+
+		if (cmp == 0) { /* case 5 */
+			if (wd->path[strlen(delta->old_file.path)] != '/')
+				return checkout_action_no_wd(action, data, delta);
+
+			if (delta->status == GIT_DELTA_TYPECHANGE) {
+				if (delta->old_file.mode == GIT_FILEMODE_TREE) {
+					error = checkout_action_with_wd(action, data, delta, workdir, wd);
+					advance = git_iterator_advance_into;
+					goto done;
+				}
+
+				if (delta->new_file.mode == GIT_FILEMODE_TREE ||
+					delta->new_file.mode == GIT_FILEMODE_COMMIT ||
+					delta->old_file.mode == GIT_FILEMODE_COMMIT)
+				{
+					error = checkout_action_with_wd(action, data, delta, workdir, wd);
+					advance = git_iterator_advance;
+					goto done;
+				}
+			}
+
+			return checkout_is_empty_dir(data, wd->path) ?
+				checkout_action_with_wd_dir_empty(action, data, delta) :
+				checkout_action_with_wd_dir(action, data, delta, workdir, wd);
+		}
+
+		/* case 6 - wd is after delta */
+		return checkout_action_no_wd(action, data, delta);
+	}
+
+done:
+	if (!error && advance != NULL &&
+		(error = advance(wditem, workdir)) < 0) {
+		*wditem = NULL;
+		if (error == GIT_ITEROVER)
+			error = 0;
+	}
+
+	return error;
+}
+
+static int checkout_remaining_wd_items(
+	checkout_data *data,
+	git_iterator *workdir,
+	const git_index_entry *wd,
+	git_vector *spec)
+{
+	int error = 0;
+
+	while (wd && !error)
+		error = checkout_action_wd_only(data, workdir, &wd, spec);
+
+	if (error == GIT_ITEROVER)
+		error = 0;
+
+	return error;
+}
+
+GIT_INLINE(int) checkout_idxentry_cmp(
+	const git_index_entry *a,
+	const git_index_entry *b)
+{
+	if (!a && !b)
+		return 0;
+	else if (!a && b)
+		return -1;
+	else if(a && !b)
+		return 1;
+	else
+		return strcmp(a->path, b->path);
+}
+
+static int checkout_conflictdata_cmp(const void *a, const void *b)
+{
+	const checkout_conflictdata *ca = a;
+	const checkout_conflictdata *cb = b;
+	int diff;
+
+	if ((diff = checkout_idxentry_cmp(ca->ancestor, cb->ancestor)) == 0 &&
+		(diff = checkout_idxentry_cmp(ca->ours, cb->theirs)) == 0)
+		diff = checkout_idxentry_cmp(ca->theirs, cb->theirs);
+
+	return diff;
+}
+
+int checkout_conflictdata_empty(
+	const git_vector *conflicts, size_t idx, void *payload)
+{
+	checkout_conflictdata *conflict;
+
+	GIT_UNUSED(payload);
+
+	if ((conflict = git_vector_get(conflicts, idx)) == NULL)
+		return -1;
+
+	if (conflict->ancestor || conflict->ours || conflict->theirs)
+		return 0;
+
+	git__free(conflict);
+	return 1;
+}
+
+GIT_INLINE(bool) conflict_pathspec_match(
+	checkout_data *data,
+	git_iterator *workdir,
+	git_vector *pathspec,
+	const git_index_entry *ancestor,
+	const git_index_entry *ours,
+	const git_index_entry *theirs)
+{
+	/* if the pathspec matches ours *or* theirs, proceed */
+	if (ours && git_pathspec__match(pathspec, ours->path,
+		(data->strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH) != 0,
+		git_iterator_ignore_case(workdir), NULL, NULL))
+		return true;
+
+	if (theirs && git_pathspec__match(pathspec, theirs->path,
+		(data->strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH) != 0,
+		git_iterator_ignore_case(workdir), NULL, NULL))
+		return true;
+
+	if (ancestor && git_pathspec__match(pathspec, ancestor->path,
+		(data->strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH) != 0,
+		git_iterator_ignore_case(workdir), NULL, NULL))
+		return true;
+
+	return false;
+}
+
+GIT_INLINE(int) checkout_conflict_detect_submodule(checkout_conflictdata *conflict)
+{
+	conflict->submodule = ((conflict->ancestor && S_ISGITLINK(conflict->ancestor->mode)) ||
+		(conflict->ours && S_ISGITLINK(conflict->ours->mode)) ||
+		(conflict->theirs && S_ISGITLINK(conflict->theirs->mode)));
+	return 0;
+}
+
+GIT_INLINE(int) checkout_conflict_detect_binary(git_repository *repo, checkout_conflictdata *conflict)
+{
+	git_blob *ancestor_blob = NULL, *our_blob = NULL, *their_blob = NULL;
+	int error = 0;
+
+	if (conflict->submodule)
+		return 0;
+
+	if (conflict->ancestor) {
+		if ((error = git_blob_lookup(&ancestor_blob, repo, &conflict->ancestor->id)) < 0)
+			goto done;
+
+		conflict->binary = git_blob_is_binary(ancestor_blob);
+	}
+
+	if (!conflict->binary && conflict->ours) {
+		if ((error = git_blob_lookup(&our_blob, repo, &conflict->ours->id)) < 0)
+			goto done;
+
+		conflict->binary = git_blob_is_binary(our_blob);
+	}
+
+	if (!conflict->binary && conflict->theirs) {
+		if ((error = git_blob_lookup(&their_blob, repo, &conflict->theirs->id)) < 0)
+			goto done;
+
+		conflict->binary = git_blob_is_binary(their_blob);
+	}
+
+done:
+	git_blob_free(ancestor_blob);
+	git_blob_free(our_blob);
+	git_blob_free(their_blob);
+
+	return error;
+}
+
+static int checkout_conflict_append_update(
+	const git_index_entry *ancestor,
+	const git_index_entry *ours,
+	const git_index_entry *theirs,
+	void *payload)
+{
+	checkout_data *data = payload;
+	checkout_conflictdata *conflict;
+	int error;
+
+	conflict = git__calloc(1, sizeof(checkout_conflictdata));
+	GITERR_CHECK_ALLOC(conflict);
+
+	conflict->ancestor = ancestor;
+	conflict->ours = ours;
+	conflict->theirs = theirs;
+
+	if ((error = checkout_conflict_detect_submodule(conflict)) < 0 ||
+		(error = checkout_conflict_detect_binary(data->repo, conflict)) < 0)
+	{
+		git__free(conflict);
+		return error;
+	}
+
+	if (git_vector_insert(&data->update_conflicts, conflict))
+		return -1;
+
+	return 0;
+}
+
+static int checkout_conflicts_foreach(
+	checkout_data *data,
+	git_index *index,
+	git_iterator *workdir,
+	git_vector *pathspec,
+	int (*cb)(const git_index_entry *, const git_index_entry *, const git_index_entry *, void *),
+	void *payload)
+{
+	git_index_conflict_iterator *iterator = NULL;
+	const git_index_entry *ancestor, *ours, *theirs;
+	int error = 0;
+
+	if ((error = git_index_conflict_iterator_new(&iterator, index)) < 0)
+		goto done;
+
+	/* Collect the conflicts */
+	while ((error = git_index_conflict_next(&ancestor, &ours, &theirs, iterator)) == 0) {
+		if (!conflict_pathspec_match(data, workdir, pathspec, ancestor, ours, theirs))
+			continue;
+
+		if ((error = cb(ancestor, ours, theirs, payload)) < 0)
+			goto done;
+	}
+
+	if (error == GIT_ITEROVER)
+		error = 0;
+
+done:
+	git_index_conflict_iterator_free(iterator);
+
+	return error;
+}
+
+static int checkout_conflicts_load(checkout_data *data, git_iterator *workdir, git_vector *pathspec)
+{
+	git_index *index;
+
+	/* Only write conficts from sources that have them: indexes. */
+	if ((index = git_iterator_get_index(data->target)) == NULL)
+		return 0;
+
+	data->update_conflicts._cmp = checkout_conflictdata_cmp;
+
+	if (checkout_conflicts_foreach(data, index, workdir, pathspec, checkout_conflict_append_update, data) < 0)
+		return -1;
+
+	/* Collect the REUC and NAME entries */
+	data->update_reuc = &index->reuc;
+	data->update_names = &index->names;
+
+	return 0;
+}
+
+GIT_INLINE(int) checkout_conflicts_cmp_entry(
+	const char *path,
+	const git_index_entry *entry)
+{
+	return strcmp((const char *)path, entry->path);
+}
+
+static int checkout_conflicts_cmp_ancestor(const void *p, const void *c)
+{
+	const char *path = p;
+	const checkout_conflictdata *conflict = c;
+
+	if (!conflict->ancestor)
+		return 1;
+
+	return checkout_conflicts_cmp_entry(path, conflict->ancestor);
+}
+
+static checkout_conflictdata *checkout_conflicts_search_ancestor(
+	checkout_data *data,
+	const char *path)
+{
+	size_t pos;
+
+	if (git_vector_bsearch2(&pos, &data->update_conflicts, checkout_conflicts_cmp_ancestor, path) < 0)
+		return NULL;
+
+	return git_vector_get(&data->update_conflicts, pos);
+}
+
+static checkout_conflictdata *checkout_conflicts_search_branch(
+	checkout_data *data,
+	const char *path)
+{
+	checkout_conflictdata *conflict;
+	size_t i;
+
+	git_vector_foreach(&data->update_conflicts, i, conflict) {
+		int cmp = -1;
+
+		if (conflict->ancestor)
+			break;
+
+		if (conflict->ours)
+			cmp = checkout_conflicts_cmp_entry(path, conflict->ours);
+		else if (conflict->theirs)
+			cmp = checkout_conflicts_cmp_entry(path, conflict->theirs);
+
+		if (cmp == 0)
+			return conflict;
+	}
+
+	return NULL;
+}
+
+static int checkout_conflicts_load_byname_entry(
+	checkout_conflictdata **ancestor_out,
+	checkout_conflictdata **ours_out,
+	checkout_conflictdata **theirs_out,
+	checkout_data *data,
+	const git_index_name_entry *name_entry)
+{
+	checkout_conflictdata *ancestor, *ours = NULL, *theirs = NULL;
+	int error = 0;
+
+	*ancestor_out = NULL;
+	*ours_out = NULL;
+	*theirs_out = NULL;
+
+	if (!name_entry->ancestor) {
+		giterr_set(GITERR_INDEX, "A NAME entry exists without an ancestor");
+		error = -1;
+		goto done;
+	}
+
+	if (!name_entry->ours && !name_entry->theirs) {
+		giterr_set(GITERR_INDEX, "A NAME entry exists without an ours or theirs");
+		error = -1;
+		goto done;
+	}
+
+	if ((ancestor = checkout_conflicts_search_ancestor(data,
+		name_entry->ancestor)) == NULL) {
+		giterr_set(GITERR_INDEX,
+			"A NAME entry referenced ancestor entry '%s' which does not exist in the main index",
+			name_entry->ancestor);
+		error = -1;
+		goto done;
+	}
+
+	if (name_entry->ours) {
+		if (strcmp(name_entry->ancestor, name_entry->ours) == 0)
+			ours = ancestor;
+		else if ((ours = checkout_conflicts_search_branch(data, name_entry->ours)) == NULL ||
+			ours->ours == NULL) {
+			giterr_set(GITERR_INDEX,
+				"A NAME entry referenced our entry '%s' which does not exist in the main index",
+				name_entry->ours);
+			error = -1;
+			goto done;
+		}
+	}
+
+	if (name_entry->theirs) {
+		if (strcmp(name_entry->ancestor, name_entry->theirs) == 0)
+			theirs = ancestor;
+		else if (name_entry->ours && strcmp(name_entry->ours, name_entry->theirs) == 0)
+			theirs = ours;
+		else if ((theirs = checkout_conflicts_search_branch(data, name_entry->theirs)) == NULL ||
+			theirs->theirs == NULL) {
+			giterr_set(GITERR_INDEX,
+				"A NAME entry referenced their entry '%s' which does not exist in the main index",
+				name_entry->theirs);
+			error = -1;
+			goto done;
+		}
+	}
+
+	*ancestor_out = ancestor;
+	*ours_out = ours;
+	*theirs_out = theirs;
+
+done:
+	return error;
+}
+
+static int checkout_conflicts_coalesce_renames(
+	checkout_data *data)
+{
+	git_index *index;
+	const git_index_name_entry *name_entry;
+	checkout_conflictdata *ancestor_conflict, *our_conflict, *their_conflict;
+	size_t i, names;
+	int error = 0;
+
+	if ((index = git_iterator_get_index(data->target)) == NULL)
+		return 0;
+
+	/* Juggle entries based on renames */
+	names = git_index_name_entrycount(index);
+
+	for (i = 0; i < names; i++) {
+		name_entry = git_index_name_get_byindex(index, i);
+
+		if ((error = checkout_conflicts_load_byname_entry(
+			&ancestor_conflict, &our_conflict, &their_conflict,
+			data, name_entry)) < 0)
+			goto done;
+
+		if (our_conflict && our_conflict != ancestor_conflict) {
+			ancestor_conflict->ours = our_conflict->ours;
+			our_conflict->ours = NULL;
+
+			if (our_conflict->theirs)
+				our_conflict->name_collision = 1;
+
+			if (our_conflict->name_collision)
+				ancestor_conflict->name_collision = 1;
+		}
+
+		if (their_conflict && their_conflict != ancestor_conflict) {
+			ancestor_conflict->theirs = their_conflict->theirs;
+			their_conflict->theirs = NULL;
+
+			if (their_conflict->ours)
+				their_conflict->name_collision = 1;
+
+			if (their_conflict->name_collision)
+				ancestor_conflict->name_collision = 1;
+		}
+
+		if (our_conflict && our_conflict != ancestor_conflict &&
+			their_conflict && their_conflict != ancestor_conflict)
+			ancestor_conflict->one_to_two = 1;
+	}
+
+	git_vector_remove_matching(
+		&data->update_conflicts, checkout_conflictdata_empty, NULL);
+
+done:
+	return error;
+}
+
+static int checkout_conflicts_mark_directoryfile(
+	checkout_data *data)
+{
+	git_index *index;
+	checkout_conflictdata *conflict;
+	const git_index_entry *entry;
+	size_t i, j, len;
+	const char *path;
+	int prefixed, error = 0;
+
+	if ((index = git_iterator_get_index(data->target)) == NULL)
+		return 0;
+
+	len = git_index_entrycount(index);
+
+	/* Find d/f conflicts */
+	git_vector_foreach(&data->update_conflicts, i, conflict) {
+		if ((conflict->ours && conflict->theirs) ||
+			(!conflict->ours && !conflict->theirs))
+			continue;
+
+		path = conflict->ours ?
+			conflict->ours->path : conflict->theirs->path;
+
+		if ((error = git_index_find(&j, index, path)) < 0) {
+			if (error == GIT_ENOTFOUND)
+				giterr_set(GITERR_INDEX,
+					"Index inconsistency, could not find entry for expected conflict '%s'", path);
+
+			goto done;
+		}
+
+		for (; j < len; j++) {
+			if ((entry = git_index_get_byindex(index, j)) == NULL) {
+				giterr_set(GITERR_INDEX,
+					"Index inconsistency, truncated index while loading expected conflict '%s'", path);
+				error = -1;
+				goto done;
+			}
+
+			prefixed = git_path_equal_or_prefixed(path, entry->path, NULL);
+
+			if (prefixed == GIT_PATH_EQUAL)
+				continue;
+
+			if (prefixed == GIT_PATH_PREFIX)
+				conflict->directoryfile = 1;
+
+			break;
+		}
+	}
+
+done:
+	return error;
+}
+
+static int checkout_get_update_conflicts(
+	checkout_data *data,
+	git_iterator *workdir,
+	git_vector *pathspec)
+{
+	int error = 0;
+
+	if (data->strategy & GIT_CHECKOUT_SKIP_UNMERGED)
+		return 0;
+
+	if ((error = checkout_conflicts_load(data, workdir, pathspec)) < 0 ||
+		(error = checkout_conflicts_coalesce_renames(data)) < 0 ||
+		(error = checkout_conflicts_mark_directoryfile(data)) < 0)
+		goto done;
+
+done:
+	return error;
+}
+
+static int checkout_conflict_append_remove(
+	const git_index_entry *ancestor,
+	const git_index_entry *ours,
+	const git_index_entry *theirs,
+	void *payload)
+{
+	checkout_data *data = payload;
+	const char *name;
+
+	assert(ancestor || ours || theirs);
+
+	if (ancestor)
+		name = git__strdup(ancestor->path);
+	else if (ours)
+		name = git__strdup(ours->path);
+	else if (theirs)
+		name = git__strdup(theirs->path);
+	else
+		abort();
+
+	GITERR_CHECK_ALLOC(name);
+
+	return git_vector_insert(&data->remove_conflicts, (char *)name);
+}
+
+static int checkout_get_remove_conflicts(
+	checkout_data *data,
+	git_iterator *workdir,
+	git_vector *pathspec)
+{
+	if ((data->strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX) != 0)
+		return 0;
+
+	return checkout_conflicts_foreach(data, data->index, workdir, pathspec, checkout_conflict_append_remove, data);
+}
+
+static int checkout_verify_paths(
+	git_repository *repo,
+	int action,
+	git_diff_delta *delta)
+{
+	unsigned int flags = GIT_PATH_REJECT_DEFAULTS | GIT_PATH_REJECT_DOT_GIT;
+
+	if (action & CHECKOUT_ACTION__REMOVE) {
+		if (!git_path_isvalid(repo, delta->old_file.path, flags)) {
+			giterr_set(GITERR_CHECKOUT, "Cannot remove invalid path '%s'", delta->old_file.path);
+			return -1;
+		}
+	}
+
+	if (action & ~CHECKOUT_ACTION__REMOVE) {
+		if (!git_path_isvalid(repo, delta->new_file.path, flags)) {
+			giterr_set(GITERR_CHECKOUT, "Cannot checkout to invalid path '%s'", delta->new_file.path);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int checkout_get_actions(
+	uint32_t **actions_ptr,
+	size_t **counts_ptr,
+	checkout_data *data,
+	git_iterator *workdir)
+{
+	int error = 0, act;
+	const git_index_entry *wditem;
+	git_vector pathspec = GIT_VECTOR_INIT, *deltas;
+	git_pool pathpool = GIT_POOL_INIT_STRINGPOOL;
+	git_diff_delta *delta;
+	size_t i, *counts = NULL;
+	uint32_t *actions = NULL;
+
+	if (data->opts.paths.count > 0 &&
+		git_pathspec__vinit(&pathspec, &data->opts.paths, &pathpool) < 0)
+		return -1;
+
+	if ((error = git_iterator_current(&wditem, workdir)) < 0 &&
+		error != GIT_ITEROVER)
+		goto fail;
+
+	deltas = &data->diff->deltas;
+
+	*counts_ptr = counts = git__calloc(CHECKOUT_ACTION__MAX+1, sizeof(size_t));
+	*actions_ptr = actions = git__calloc(
+		deltas->length ? deltas->length : 1, sizeof(uint32_t));
+	if (!counts || !actions) {
+		error = -1;
+		goto fail;
+	}
+
+	git_vector_foreach(deltas, i, delta) {
+		if ((error = checkout_action(&act, data, delta, workdir, &wditem, &pathspec)) == 0)
+			error = checkout_verify_paths(data->repo, act, delta);
+
+		if (error != 0)
+			goto fail;
+
+		actions[i] = act;
+
+		if (act & CHECKOUT_ACTION__REMOVE)
+			counts[CHECKOUT_ACTION__REMOVE]++;
+		if (act & CHECKOUT_ACTION__UPDATE_BLOB)
+			counts[CHECKOUT_ACTION__UPDATE_BLOB]++;
+		if (act & CHECKOUT_ACTION__UPDATE_SUBMODULE)
+			counts[CHECKOUT_ACTION__UPDATE_SUBMODULE]++;
+		if (act & CHECKOUT_ACTION__CONFLICT)
+			counts[CHECKOUT_ACTION__CONFLICT]++;
+	}
+
+	error = checkout_remaining_wd_items(data, workdir, wditem, &pathspec);
+	if (error)
+		goto fail;
+
+	counts[CHECKOUT_ACTION__REMOVE] += data->removes.length;
+
+	if (counts[CHECKOUT_ACTION__CONFLICT] > 0 &&
+		(data->strategy & GIT_CHECKOUT_ALLOW_CONFLICTS) == 0)
+	{
+		giterr_set(GITERR_CHECKOUT, "%"PRIuZ" %s checkout",
+			counts[CHECKOUT_ACTION__CONFLICT],
+			counts[CHECKOUT_ACTION__CONFLICT] == 1 ?
+			"conflict prevents" : "conflicts prevent");
+		error = GIT_ECONFLICT;
+		goto fail;
+	}
+
+
+	if ((error = checkout_get_remove_conflicts(data, workdir, &pathspec)) < 0 ||
+		(error = checkout_get_update_conflicts(data, workdir, &pathspec)) < 0)
+		goto fail;
+
+	counts[CHECKOUT_ACTION__REMOVE_CONFLICT] = git_vector_length(&data->remove_conflicts);
+	counts[CHECKOUT_ACTION__UPDATE_CONFLICT] = git_vector_length(&data->update_conflicts);
+
+	git_pathspec__vfree(&pathspec);
+	git_pool_clear(&pathpool);
+
+	return 0;
+
+fail:
+	*counts_ptr = NULL;
+	git__free(counts);
+	*actions_ptr = NULL;
+	git__free(actions);
+
+	git_pathspec__vfree(&pathspec);
+	git_pool_clear(&pathpool);
+
+	return error;
+}
+
+static bool should_remove_existing(checkout_data *data)
+{
+	int ignorecase = 0;
+
+	git_repository__cvar(&ignorecase, data->repo, GIT_CVAR_IGNORECASE);
+
+	return (ignorecase &&
+		(data->strategy & GIT_CHECKOUT_DONT_REMOVE_EXISTING) == 0);
+}
+
+#define MKDIR_NORMAL \
+	GIT_MKDIR_PATH | GIT_MKDIR_VERIFY_DIR
+#define MKDIR_REMOVE_EXISTING \
+	MKDIR_NORMAL | GIT_MKDIR_REMOVE_FILES | GIT_MKDIR_REMOVE_SYMLINKS
+
+static int checkout_mkdir(
+	checkout_data *data,
+	const char *path,
+	const char *base,
+	mode_t mode,
+	unsigned int flags)
+{
+	struct git_futils_mkdir_options mkdir_opts = {0};
+	int error;
+
+	mkdir_opts.dir_map = data->mkdir_map;
+	mkdir_opts.pool = &data->pool;
+
+	error = git_futils_mkdir_ext(
+		path, base, mode, flags, &mkdir_opts);
+
+	data->perfdata.mkdir_calls += mkdir_opts.perfdata.mkdir_calls;
+	data->perfdata.stat_calls += mkdir_opts.perfdata.stat_calls;
+	data->perfdata.chmod_calls += mkdir_opts.perfdata.chmod_calls;
+
+	return error;
+}
+
+static int mkpath2file(
+	checkout_data *data, const char *path, unsigned int mode)
+{
+	struct stat st;
+	bool remove_existing = should_remove_existing(data);
+	unsigned int flags =
+		(remove_existing ? MKDIR_REMOVE_EXISTING : MKDIR_NORMAL) |
+		GIT_MKDIR_SKIP_LAST;
+	int error;
+
+	if ((error = checkout_mkdir(
+			data, path, data->opts.target_directory, mode, flags)) < 0)
+		return error;
+
+	if (remove_existing) {
+		data->perfdata.stat_calls++;
+
+		if (p_lstat(path, &st) == 0) {
+
+			/* Some file, symlink or folder already exists at this name.
+			 * We would have removed it in remove_the_old unless we're on
+			 * a case inensitive filesystem (or the user has asked us not
+			 * to).  Remove the similarly named file to write the new.
+			 */
+			error = git_futils_rmdir_r(path, NULL, GIT_RMDIR_REMOVE_FILES);
+		} else if (errno != ENOENT) {
+			giterr_set(GITERR_OS, "Failed to stat file '%s'", path);
+			return GIT_EEXISTS;
+		} else {
+			giterr_clear();
+		}
+	}
+
+	return error;
+}
+
+struct checkout_stream {
+	git_writestream base;
+	const char *path;
+	int fd;
+	int open;
+};
+
+static int checkout_stream_write(
+	git_writestream *s, const char *buffer, size_t len)
+{
+	struct checkout_stream *stream = (struct checkout_stream *)s;
+	int ret;
+
+	if ((ret = p_write(stream->fd, buffer, len)) < 0)
+		giterr_set(GITERR_OS, "Could not write to '%s'", stream->path);
+
+	return ret;
+}
+
+static int checkout_stream_close(git_writestream *s)
+{
+	struct checkout_stream *stream = (struct checkout_stream *)s;
+	assert(stream && stream->open);
+
+	stream->open = 0;
+	return p_close(stream->fd);
+}
+
+static void checkout_stream_free(git_writestream *s)
+{
+	GIT_UNUSED(s);
+}
+
+static int blob_content_to_file(
+	checkout_data *data,
+	struct stat *st,
+	git_blob *blob,
+	const char *path,
+	const char *hint_path,
+	mode_t entry_filemode)
+{
+	int flags = data->opts.file_open_flags;
+	mode_t file_mode = data->opts.file_mode ?
+		data->opts.file_mode : entry_filemode;
+	git_filter_options filter_opts = GIT_FILTER_OPTIONS_INIT;
+	struct checkout_stream writer;
+	mode_t mode;
+	git_filter_list *fl = NULL;
+	int fd;
+	int error = 0;
+
+	if (hint_path == NULL)
+		hint_path = path;
+
+	if ((error = mkpath2file(data, path, data->opts.dir_mode)) < 0)
+		return error;
+
+	if (flags <= 0)
+		flags = O_CREAT | O_TRUNC | O_WRONLY;
+	if (!(mode = file_mode))
+		mode = GIT_FILEMODE_BLOB;
+
+	if ((fd = p_open(path, flags, mode)) < 0) {
+		giterr_set(GITERR_OS, "Could not open '%s' for writing", path);
+		return fd;
+	}
+
+	filter_opts.attr_session = &data->attr_session;
+	filter_opts.temp_buf = &data->tmp;
+
+	if (!data->opts.disable_filters &&
+		(error = git_filter_list__load_ext(
+			&fl, data->repo, blob, hint_path,
+			GIT_FILTER_TO_WORKTREE, &filter_opts)))
+		return error;
+
+	/* setup the writer */
+	memset(&writer, 0, sizeof(struct checkout_stream));
+	writer.base.write = checkout_stream_write;
+	writer.base.close = checkout_stream_close;
+	writer.base.free = checkout_stream_free;
+	writer.path = path;
+	writer.fd = fd;
+	writer.open = 1;
+
+	error = git_filter_list_stream_blob(fl, blob, &writer.base);
+
+	assert(writer.open == 0);
+
+	git_filter_list_free(fl);
+
+	if (error < 0)
+		return error;
+
+	if (GIT_PERMS_IS_EXEC(mode)) {
+		data->perfdata.chmod_calls++;
+
+		if ((error = p_chmod(path, mode)) < 0) {
+			giterr_set(GITERR_OS, "Failed to set permissions on '%s'", path);
+			return error;
+		}
+	}
+
+	if (st) {
+		data->perfdata.stat_calls++;
+
+		if ((error = p_stat(path, st)) < 0) {
+			giterr_set(GITERR_OS, "Error statting '%s'", path);
+			return error;
+		}
+
+		st->st_mode = entry_filemode;
+	}
+
+	return 0;
+}
+
+static int blob_content_to_link(
+	checkout_data *data,
+	struct stat *st,
+	git_blob *blob,
+	const char *path)
+{
+	git_buf linktarget = GIT_BUF_INIT;
+	int error;
+
+	if ((error = mkpath2file(data, path, data->opts.dir_mode)) < 0)
+		return error;
+
+	if ((error = git_blob__getbuf(&linktarget, blob)) < 0)
+		return error;
+
+	if (data->can_symlink) {
+		if ((error = p_symlink(git_buf_cstr(&linktarget), path)) < 0)
+			giterr_set(GITERR_OS, "Could not create symlink %s", path);
+	} else {
+		error = git_futils_fake_symlink(git_buf_cstr(&linktarget), path);
+	}
+
+	if (!error) {
+		data->perfdata.stat_calls++;
+
+		if ((error = p_lstat(path, st)) < 0)
+			giterr_set(GITERR_CHECKOUT, "Could not stat symlink %s", path);
+
+		st->st_mode = GIT_FILEMODE_LINK;
+	}
+
+	git_buf_free(&linktarget);
+
+	return error;
+}
+
+static int checkout_update_index(
+	checkout_data *data,
+	const git_diff_file *file,
+	struct stat *st)
+{
+	git_index_entry entry;
+
+	if (!data->index)
+		return 0;
+
+	memset(&entry, 0, sizeof(entry));
+	entry.path = (char *)file->path; /* cast to prevent warning */
+	git_index_entry__init_from_stat(&entry, st, true);
+	git_oid_cpy(&entry.id, &file->id);
+
+	return git_index_add(data->index, &entry);
+}
+
+static int checkout_submodule_update_index(
+	checkout_data *data,
+	const git_diff_file *file)
+{
+	struct stat st;
+
+	/* update the index unless prevented */
+	if ((data->strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX) != 0)
+		return 0;
+
+	git_buf_truncate(&data->path, data->workdir_len);
+	if (git_buf_puts(&data->path, file->path) < 0)
+		return -1;
+
+	data->perfdata.stat_calls++;
+	if (p_stat(git_buf_cstr(&data->path), &st) < 0) {
+		giterr_set(
+			GITERR_CHECKOUT, "Could not stat submodule %s\n", file->path);
+		return GIT_ENOTFOUND;
+	}
+
+	st.st_mode = GIT_FILEMODE_COMMIT;
+
+	return checkout_update_index(data, file, &st);
+}
+
+static int checkout_submodule(
+	checkout_data *data,
+	const git_diff_file *file)
+{
+	bool remove_existing = should_remove_existing(data);
+	int error = 0;
+
+	/* Until submodules are supported, UPDATE_ONLY means do nothing here */
+	if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0)
+		return 0;
+
+	if ((error = checkout_mkdir(
+			data,
+			file->path, data->opts.target_directory, data->opts.dir_mode,
+			remove_existing ? MKDIR_REMOVE_EXISTING : MKDIR_NORMAL)) < 0)
+		return error;
+
+	if ((error = git_submodule_lookup(NULL, data->repo, file->path)) < 0) {
+		/* I've observed repos with submodules in the tree that do not
+		 * have a .gitmodules - core Git just makes an empty directory
+		 */
+		if (error == GIT_ENOTFOUND) {
+			giterr_clear();
+			return checkout_submodule_update_index(data, file);
+		}
+
+		return error;
+	}
+
+	/* TODO: Support checkout_strategy options.  Two circumstances:
+	 * 1 - submodule already checked out, but we need to move the HEAD
+	 *     to the new OID, or
+	 * 2 - submodule not checked out and we should recursively check it out
+	 *
+	 * Checkout will not execute a pull on the submodule, but a clone
+	 * command should probably be able to.  Do we need a submodule callback?
+	 */
+
+	return checkout_submodule_update_index(data, file);
+}
+
+static void report_progress(
+	checkout_data *data,
+	const char *path)
+{
+	if (data->opts.progress_cb)
+		data->opts.progress_cb(
+			path, data->completed_steps, data->total_steps,
+			data->opts.progress_payload);
+}
+
+static int checkout_safe_for_update_only(
+	checkout_data *data, const char *path, mode_t expected_mode)
+{
+	struct stat st;
+
+	data->perfdata.stat_calls++;
+
+	if (p_lstat(path, &st) < 0) {
+		/* if doesn't exist, then no error and no update */
+		if (errno == ENOENT || errno == ENOTDIR)
+			return 0;
+
+		/* otherwise, stat error and no update */
+		giterr_set(GITERR_OS, "Failed to stat file '%s'", path);
+		return -1;
+	}
+
+	/* only safe for update if this is the same type of file */
+	if ((st.st_mode & ~0777) == (expected_mode & ~0777))
+		return 1;
+
+	return 0;
+}
+
+static int checkout_write_content(
+	checkout_data *data,
+	const git_oid *oid,
+	const char *full_path,
+	const char *hint_path,
+	unsigned int mode,
+	struct stat *st)
+{
+	int error = 0;
+	git_blob *blob;
+
+	if ((error = git_blob_lookup(&blob, data->repo, oid)) < 0)
+		return error;
+
+	if (S_ISLNK(mode))
+		error = blob_content_to_link(data, st, blob, full_path);
+	else
+		error = blob_content_to_file(data, st, blob, full_path, hint_path, mode);
+
+	git_blob_free(blob);
+
+	/* if we try to create the blob and an existing directory blocks it from
+	 * being written, then there must have been a typechange conflict in a
+	 * parent directory - suppress the error and try to continue.
+	 */
+	if ((data->strategy & GIT_CHECKOUT_ALLOW_CONFLICTS) != 0 &&
+		(error == GIT_ENOTFOUND || error == GIT_EEXISTS))
+	{
+		giterr_clear();
+		error = 0;
+	}
+
+	return error;
+}
+
+static int checkout_blob(
+	checkout_data *data,
+	const git_diff_file *file)
+{
+	int error = 0;
+	struct stat st;
+
+	git_buf_truncate(&data->path, data->workdir_len);
+	if (git_buf_puts(&data->path, file->path) < 0)
+		return -1;
+
+	if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0) {
+		int rval = checkout_safe_for_update_only(
+			data, git_buf_cstr(&data->path), file->mode);
+		if (rval <= 0)
+			return rval;
+	}
+
+	error = checkout_write_content(
+		data, &file->id, git_buf_cstr(&data->path), NULL, file->mode, &st);
+
+	/* update the index unless prevented */
+	if (!error && (data->strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX) == 0)
+		error = checkout_update_index(data, file, &st);
+
+	/* update the submodule data if this was a new .gitmodules file */
+	if (!error && strcmp(file->path, ".gitmodules") == 0)
+		data->reload_submodules = true;
+
+	return error;
+}
+
+static int checkout_remove_the_old(
+	unsigned int *actions,
+	checkout_data *data)
+{
+	int error = 0;
+	git_diff_delta *delta;
+	const char *str;
+	size_t i;
+	const char *workdir = git_buf_cstr(&data->path);
+	uint32_t flg = GIT_RMDIR_EMPTY_PARENTS |
+		GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_REMOVE_BLOCKERS;
+
+	if (data->opts.checkout_strategy & GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES)
+		flg |= GIT_RMDIR_SKIP_NONEMPTY;
+
+	git_buf_truncate(&data->path, data->workdir_len);
+
+	git_vector_foreach(&data->diff->deltas, i, delta) {
+		if (actions[i] & CHECKOUT_ACTION__REMOVE) {
+			error = git_futils_rmdir_r(delta->old_file.path, workdir, flg);
+			if (error < 0)
+				return error;
+
+			data->completed_steps++;
+			report_progress(data, delta->old_file.path);
+
+			if ((actions[i] & CHECKOUT_ACTION__UPDATE_BLOB) == 0 &&
+				(data->strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX) == 0 &&
+				data->index != NULL)
+			{
+				(void)git_index_remove(data->index, delta->old_file.path, 0);
+			}
+		}
+	}
+
+	git_vector_foreach(&data->removes, i, str) {
+		error = git_futils_rmdir_r(str, workdir, flg);
+		if (error < 0)
+			return error;
+
+		data->completed_steps++;
+		report_progress(data, str);
+
+		if ((data->strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX) == 0 &&
+			data->index != NULL)
+		{
+			if (str[strlen(str) - 1] == '/')
+				(void)git_index_remove_directory(data->index, str, 0);
+			else
+				(void)git_index_remove(data->index, str, 0);
+		}
+	}
+
+	return 0;
+}
+
+static int checkout_deferred_remove(git_repository *repo, const char *path)
+{
+#if 0
+	int error = git_futils_rmdir_r(
+		path, data->opts.target_directory, GIT_RMDIR_EMPTY_PARENTS);
+
+	if (error == GIT_ENOTFOUND) {
+		error = 0;
+		giterr_clear();
+	}
+
+	return error;
+#else
+	GIT_UNUSED(repo);
+	GIT_UNUSED(path);
+	assert(false);
+	return 0;
+#endif
+}
+
+static int checkout_create_the_new(
+	unsigned int *actions,
+	checkout_data *data)
+{
+	int error = 0;
+	git_diff_delta *delta;
+	size_t i;
+
+	git_vector_foreach(&data->diff->deltas, i, delta) {
+		if (actions[i] & CHECKOUT_ACTION__DEFER_REMOVE) {
+			/* this had a blocker directory that should only be removed iff
+			 * all of the contents of the directory were safely removed
+			 */
+			if ((error = checkout_deferred_remove(
+					data->repo, delta->old_file.path)) < 0)
+				return error;
+		}
+
+		if (actions[i] & CHECKOUT_ACTION__UPDATE_BLOB) {
+			error = checkout_blob(data, &delta->new_file);
+			if (error < 0)
+				return error;
+
+			data->completed_steps++;
+			report_progress(data, delta->new_file.path);
+		}
+	}
+
+	return 0;
+}
+
+static int checkout_create_submodules(
+	unsigned int *actions,
+	checkout_data *data)
+{
+	int error = 0;
+	git_diff_delta *delta;
+	size_t i;
+
+	git_vector_foreach(&data->diff->deltas, i, delta) {
+		if (actions[i] & CHECKOUT_ACTION__DEFER_REMOVE) {
+			/* this has a blocker directory that should only be removed iff
+			 * all of the contents of the directory were safely removed
+			 */
+			if ((error = checkout_deferred_remove(
+					data->repo, delta->old_file.path)) < 0)
+				return error;
+		}
+
+		if (actions[i] & CHECKOUT_ACTION__UPDATE_SUBMODULE) {
+			int error = checkout_submodule(data, &delta->new_file);
+			if (error < 0)
+				return error;
+
+			data->completed_steps++;
+			report_progress(data, delta->new_file.path);
+		}
+	}
+
+	return 0;
+}
+
+static int checkout_lookup_head_tree(git_tree **out, git_repository *repo)
+{
+	int error = 0;
+	git_reference *ref = NULL;
+	git_object *head;
+
+	if (!(error = git_repository_head(&ref, repo)) &&
+		!(error = git_reference_peel(&head, ref, GIT_OBJ_TREE)))
+		*out = (git_tree *)head;
+
+	git_reference_free(ref);
+
+	return error;
+}
+
+
+static int conflict_entry_name(
+	git_buf *out,
+	const char *side_name,
+	const char *filename)
+{
+	if (git_buf_puts(out, side_name) < 0 ||
+		git_buf_putc(out, ':') < 0 ||
+		git_buf_puts(out, filename) < 0)
+		return -1;
+
+	return 0;
+}
+
+static int checkout_path_suffixed(git_buf *path, const char *suffix)
+{
+	size_t path_len;
+	int i = 0, error = 0;
+
+	if ((error = git_buf_putc(path, '~')) < 0 || (error = git_buf_puts(path, suffix)) < 0)
+		return -1;
+
+	path_len = git_buf_len(path);
+
+	while (git_path_exists(git_buf_cstr(path)) && i < INT_MAX) {
+		git_buf_truncate(path, path_len);
+
+		if ((error = git_buf_putc(path, '_')) < 0 ||
+			(error = git_buf_printf(path, "%d", i)) < 0)
+			return error;
+
+		i++;
+	}
+
+	if (i == INT_MAX) {
+		git_buf_truncate(path, path_len);
+
+		giterr_set(GITERR_CHECKOUT, "Could not write '%s': working directory file exists", path);
+		return GIT_EEXISTS;
+	}
+
+	return 0;
+}
+
+static int checkout_write_entry(
+	checkout_data *data,
+	checkout_conflictdata *conflict,
+	const git_index_entry *side)
+{
+	const char *hint_path = NULL, *suffix;
+	struct stat st;
+	int error;
+
+	assert (side == conflict->ours || side == conflict->theirs);
+
+	git_buf_truncate(&data->path, data->workdir_len);
+	if (git_buf_puts(&data->path, side->path) < 0)
+		return -1;
+
+	if ((conflict->name_collision || conflict->directoryfile) &&
+		(data->strategy & GIT_CHECKOUT_USE_OURS) == 0 &&
+		(data->strategy & GIT_CHECKOUT_USE_THEIRS) == 0) {
+
+		if (side == conflict->ours)
+			suffix = data->opts.our_label ? data->opts.our_label :
+				"ours";
+		else
+			suffix = data->opts.their_label ? data->opts.their_label :
+				"theirs";
+
+		if (checkout_path_suffixed(&data->path, suffix) < 0)
+			return -1;
+
+		hint_path = side->path;
+	}
+
+	if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0 &&
+		(error = checkout_safe_for_update_only(data, git_buf_cstr(&data->path), side->mode)) <= 0)
+		return error;
+
+	return checkout_write_content(data,
+		&side->id, git_buf_cstr(&data->path), hint_path, side->mode, &st);
+}
+
+static int checkout_write_entries(
+	checkout_data *data,
+	checkout_conflictdata *conflict)
+{
+	int error = 0;
+
+	if ((error = checkout_write_entry(data, conflict, conflict->ours)) >= 0)
+		error = checkout_write_entry(data, conflict, conflict->theirs);
+
+	return error;
+}
+
+static int checkout_merge_path(
+	git_buf *out,
+	checkout_data *data,
+	checkout_conflictdata *conflict,
+	git_merge_file_result *result)
+{
+	const char *our_label_raw, *their_label_raw, *suffix;
+	int error = 0;
+
+	if ((error = git_buf_joinpath(out, git_repository_workdir(data->repo), result->path)) < 0)
+		return error;
+
+	/* Most conflicts simply use the filename in the index */
+	if (!conflict->name_collision)
+		return 0;
+
+	/* Rename 2->1 conflicts need the branch name appended */
+	our_label_raw = data->opts.our_label ? data->opts.our_label : "ours";
+	their_label_raw = data->opts.their_label ? data->opts.their_label : "theirs";
+	suffix = strcmp(result->path, conflict->ours->path) == 0 ? our_label_raw : their_label_raw;
+
+	if ((error = checkout_path_suffixed(out, suffix)) < 0)
+		return error;
+
+	return 0;
+}
+
+static int checkout_write_merge(
+	checkout_data *data,
+	checkout_conflictdata *conflict)
+{
+	git_buf our_label = GIT_BUF_INIT, their_label = GIT_BUF_INIT,
+		path_suffixed = GIT_BUF_INIT, path_workdir = GIT_BUF_INIT,
+		in_data = GIT_BUF_INIT, out_data = GIT_BUF_INIT;
+	git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
+	git_merge_file_result result = {0};
+	git_filebuf output = GIT_FILEBUF_INIT;
+	git_filter_list *fl = NULL;
+	git_filter_options filter_opts = GIT_FILTER_OPTIONS_INIT;
+	int error = 0;
+
+	if (data->opts.checkout_strategy & GIT_CHECKOUT_CONFLICT_STYLE_DIFF3)
+		opts.flags |= GIT_MERGE_FILE_STYLE_DIFF3;
+
+	opts.ancestor_label = data->opts.ancestor_label ?
+		data->opts.ancestor_label : "ancestor";
+	opts.our_label = data->opts.our_label ?
+		data->opts.our_label : "ours";
+	opts.their_label = data->opts.their_label ?
+		data->opts.their_label : "theirs";
+
+	/* If all the paths are identical, decorate the diff3 file with the branch
+	 * names.  Otherwise, append branch_name:path.
+	 */
+	if (conflict->ours && conflict->theirs &&
+		strcmp(conflict->ours->path, conflict->theirs->path) != 0) {
+
+		if ((error = conflict_entry_name(
+			&our_label, opts.our_label, conflict->ours->path)) < 0 ||
+			(error = conflict_entry_name(
+			&their_label, opts.their_label, conflict->theirs->path)) < 0)
+			goto done;
+
+		opts.our_label = git_buf_cstr(&our_label);
+		opts.their_label = git_buf_cstr(&their_label);
+	}
+
+	if ((error = git_merge_file_from_index(&result, data->repo,
+		conflict->ancestor, conflict->ours, conflict->theirs, &opts)) < 0)
+		goto done;
+
+	if (result.path == NULL || result.mode == 0) {
+		giterr_set(GITERR_CHECKOUT, "Could not merge contents of file");
+		error = GIT_ECONFLICT;
+		goto done;
+	}
+
+	if ((error = checkout_merge_path(&path_workdir, data, conflict, &result)) < 0)
+		goto done;
+
+	if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0 &&
+		(error = checkout_safe_for_update_only(data, git_buf_cstr(&path_workdir), result.mode)) <= 0)
+		goto done;
+
+	if (!data->opts.disable_filters) {
+		in_data.ptr = (char *)result.ptr;
+		in_data.size = result.len;
+
+		filter_opts.attr_session = &data->attr_session;
+		filter_opts.temp_buf = &data->tmp;
+
+		if ((error = git_filter_list__load_ext(
+				&fl, data->repo, NULL, git_buf_cstr(&path_workdir),
+				GIT_FILTER_TO_WORKTREE, &filter_opts)) < 0 ||
+			(error = git_filter_list_apply_to_data(&out_data, fl, &in_data)) < 0)
+			goto done;
+	} else {
+		out_data.ptr = (char *)result.ptr;
+		out_data.size = result.len;
+	}
+
+	if ((error = mkpath2file(data, path_workdir.ptr, data->opts.dir_mode)) < 0 ||
+		(error = git_filebuf_open(&output, git_buf_cstr(&path_workdir), GIT_FILEBUF_DO_NOT_BUFFER, result.mode)) < 0 ||
+		(error = git_filebuf_write(&output, out_data.ptr, out_data.size)) < 0 ||
+		(error = git_filebuf_commit(&output)) < 0)
+		goto done;
+
+done:
+	git_filter_list_free(fl);
+
+	git_buf_free(&out_data);
+	git_buf_free(&our_label);
+	git_buf_free(&their_label);
+
+	git_merge_file_result_free(&result);
+	git_buf_free(&path_workdir);
+	git_buf_free(&path_suffixed);
+
+	return error;
+}
+
+static int checkout_conflict_add(
+	checkout_data *data,
+	const git_index_entry *conflict)
+{
+	int error = git_index_remove(data->index, conflict->path, 0);
+
+	if (error == GIT_ENOTFOUND)
+		giterr_clear();
+	else if (error < 0)
+		return error;
+
+	return git_index_add(data->index, conflict);
+}
+
+static int checkout_conflict_update_index(
+	checkout_data *data,
+	checkout_conflictdata *conflict)
+{
+	int error = 0;
+
+	if (conflict->ancestor)
+		error = checkout_conflict_add(data, conflict->ancestor);
+
+	if (!error && conflict->ours)
+		error = checkout_conflict_add(data, conflict->ours);
+
+	if (!error && conflict->theirs)
+		error = checkout_conflict_add(data, conflict->theirs);
+
+	return error;
+}
+
+static int checkout_create_conflicts(checkout_data *data)
+{
+	checkout_conflictdata *conflict;
+	size_t i;
+	int error = 0;
+
+	git_vector_foreach(&data->update_conflicts, i, conflict) {
+
+		/* Both deleted: nothing to do */
+		if (conflict->ours == NULL && conflict->theirs == NULL)
+			error = 0;
+
+		else if ((data->strategy & GIT_CHECKOUT_USE_OURS) &&
+			conflict->ours)
+			error = checkout_write_entry(data, conflict, conflict->ours);
+		else if ((data->strategy & GIT_CHECKOUT_USE_THEIRS) &&
+			conflict->theirs)
+			error = checkout_write_entry(data, conflict, conflict->theirs);
+
+		/* Ignore the other side of name collisions. */
+		else if ((data->strategy & GIT_CHECKOUT_USE_OURS) &&
+			!conflict->ours && conflict->name_collision)
+			error = 0;
+		else if ((data->strategy & GIT_CHECKOUT_USE_THEIRS) &&
+			!conflict->theirs && conflict->name_collision)
+			error = 0;
+
+		/* For modify/delete, name collisions and d/f conflicts, write
+		 * the file (potentially with the name mangled.
+		 */
+		else if (conflict->ours != NULL && conflict->theirs == NULL)
+			error = checkout_write_entry(data, conflict, conflict->ours);
+		else if (conflict->ours == NULL && conflict->theirs != NULL)
+			error = checkout_write_entry(data, conflict, conflict->theirs);
+
+		/* Add/add conflicts and rename 1->2 conflicts, write the
+		 * ours/theirs sides (potentially name mangled).
+		 */
+		else if (conflict->one_to_two)
+			error = checkout_write_entries(data, conflict);
+
+		/* If all sides are links, write the ours side */
+		else if (S_ISLNK(conflict->ours->mode) &&
+			S_ISLNK(conflict->theirs->mode))
+			error = checkout_write_entry(data, conflict, conflict->ours);
+		/* Link/file conflicts, write the file side */
+		else if (S_ISLNK(conflict->ours->mode))
+			error = checkout_write_entry(data, conflict, conflict->theirs);
+		else if (S_ISLNK(conflict->theirs->mode))
+			error = checkout_write_entry(data, conflict, conflict->ours);
+
+		/* If any side is a gitlink, do nothing. */
+		else if (conflict->submodule)
+			error = 0;
+
+		/* If any side is binary, write the ours side */
+		else if (conflict->binary)
+			error = checkout_write_entry(data, conflict, conflict->ours);
+
+		else if (!error)
+			error = checkout_write_merge(data, conflict);
+
+		/* Update the index extensions (REUC and NAME) if we're checking
+		 * out a different index. (Otherwise just leave them there.)
+		 */
+		if (!error && (data->strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX) == 0)
+			error = checkout_conflict_update_index(data, conflict);
+
+		if (error)
+			break;
+
+		data->completed_steps++;
+		report_progress(data,
+			conflict->ours ? conflict->ours->path :
+			(conflict->theirs ? conflict->theirs->path : conflict->ancestor->path));
+	}
+
+	return error;
+}
+
+static int checkout_remove_conflicts(checkout_data *data)
+{
+	const char *conflict;
+	size_t i;
+
+	git_vector_foreach(&data->remove_conflicts, i, conflict) {
+		if (git_index_conflict_remove(data->index, conflict) < 0)
+			return -1;
+
+		data->completed_steps++;
+	}
+
+	return 0;
+}
+
+static int checkout_extensions_update_index(checkout_data *data)
+{
+	const git_index_reuc_entry *reuc_entry;
+	const git_index_name_entry *name_entry;
+	size_t i;
+	int error = 0;
+
+	if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0)
+		return 0;
+
+	if (data->update_reuc) {
+		git_vector_foreach(data->update_reuc, i, reuc_entry) {
+			if ((error = git_index_reuc_add(data->index, reuc_entry->path,
+				reuc_entry->mode[0], &reuc_entry->oid[0],
+				reuc_entry->mode[1], &reuc_entry->oid[1],
+				reuc_entry->mode[2], &reuc_entry->oid[2])) < 0)
+				goto done;
+		}
+	}
+
+	if (data->update_names) {
+		git_vector_foreach(data->update_names, i, name_entry) {
+			if ((error = git_index_name_add(data->index, name_entry->ancestor,
+				name_entry->ours, name_entry->theirs)) < 0)
+				goto done;
+		}
+	}
+
+done:
+	return error;
+}
+
+static void checkout_data_clear(checkout_data *data)
+{
+	if (data->opts_free_baseline) {
+		git_tree_free(data->opts.baseline);
+		data->opts.baseline = NULL;
+	}
+
+	git_vector_free(&data->removes);
+	git_pool_clear(&data->pool);
+
+	git_vector_free_deep(&data->remove_conflicts);
+	git_vector_free_deep(&data->update_conflicts);
+
+	git__free(data->pfx);
+	data->pfx = NULL;
+
+	git_strmap_free(data->mkdir_map);
+
+	git_buf_free(&data->path);
+	git_buf_free(&data->tmp);
+
+	git_index_free(data->index);
+	data->index = NULL;
+
+	git_strmap_free(data->mkdir_map);
+
+	git_attr_session__free(&data->attr_session);
+}
+
+static int checkout_data_init(
+	checkout_data *data,
+	git_iterator *target,
+	const git_checkout_options *proposed)
+{
+	int error = 0;
+	git_repository *repo = git_iterator_owner(target);
+
+	memset(data, 0, sizeof(*data));
+
+	if (!repo) {
+		giterr_set(GITERR_CHECKOUT, "Cannot checkout nothing");
+		return -1;
+	}
+
+	if ((!proposed || !proposed->target_directory) &&
+		(error = git_repository__ensure_not_bare(repo, "checkout")) < 0)
+		return error;
+
+	data->repo = repo;
+	data->target = target;
+
+	GITERR_CHECK_VERSION(
+		proposed, GIT_CHECKOUT_OPTIONS_VERSION, "git_checkout_options");
+
+	if (!proposed)
+		GIT_INIT_STRUCTURE(&data->opts, GIT_CHECKOUT_OPTIONS_VERSION);
+	else
+		memmove(&data->opts, proposed, sizeof(git_checkout_options));
+
+	if (!data->opts.target_directory)
+		data->opts.target_directory = git_repository_workdir(repo);
+	else if (!git_path_isdir(data->opts.target_directory) &&
+			 (error = checkout_mkdir(data,
+				data->opts.target_directory, NULL,
+				GIT_DIR_MODE, GIT_MKDIR_VERIFY_DIR)) < 0)
+		goto cleanup;
+
+	/* refresh config and index content unless NO_REFRESH is given */
+	if ((data->opts.checkout_strategy & GIT_CHECKOUT_NO_REFRESH) == 0) {
+		git_config *cfg;
+
+		if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
+			goto cleanup;
+
+		/* Get the repository index and reload it (unless we're checking
+		 * out the index; then it has the changes we're trying to check
+		 * out and those should not be overwritten.)
+		 */
+		if ((error = git_repository_index(&data->index, data->repo)) < 0)
+			goto cleanup;
+
+		if (data->index != git_iterator_get_index(target)) {
+			if ((error = git_index_read(data->index, true)) < 0)
+				goto cleanup;
+
+			/* cannot checkout if unresolved conflicts exist */
+			if ((data->opts.checkout_strategy & GIT_CHECKOUT_FORCE) == 0 &&
+				git_index_has_conflicts(data->index)) {
+				error = GIT_ECONFLICT;
+				giterr_set(GITERR_CHECKOUT,
+					"unresolved conflicts exist in the index");
+				goto cleanup;
+			}
+
+			/* clean conflict data in the current index */
+			git_index_name_clear(data->index);
+			git_index_reuc_clear(data->index);
+		}
+	}
+
+	/* if you are forcing, allow all safe updates, plus recreate missing */
+	if ((data->opts.checkout_strategy & GIT_CHECKOUT_FORCE) != 0)
+		data->opts.checkout_strategy |= GIT_CHECKOUT_SAFE |
+			GIT_CHECKOUT_RECREATE_MISSING;
+
+	/* if the repository does not actually have an index file, then this
+	 * is an initial checkout (perhaps from clone), so we allow safe updates
+	 */
+	if (!data->index->on_disk &&
+		(data->opts.checkout_strategy & GIT_CHECKOUT_SAFE) != 0)
+		data->opts.checkout_strategy |= GIT_CHECKOUT_RECREATE_MISSING;
+
+	data->strategy = data->opts.checkout_strategy;
+
+	/* opts->disable_filters is false by default */
+
+	if (!data->opts.dir_mode)
+		data->opts.dir_mode = GIT_DIR_MODE;
+
+	if (!data->opts.file_open_flags)
+		data->opts.file_open_flags = O_CREAT | O_TRUNC | O_WRONLY;
+
+	data->pfx = git_pathspec_prefix(&data->opts.paths);
+
+	if ((error = git_repository__cvar(
+			 &data->can_symlink, repo, GIT_CVAR_SYMLINKS)) < 0)
+		goto cleanup;
+
+	if (!data->opts.baseline && !data->opts.baseline_index) {
+		data->opts_free_baseline = true;
+
+		error = checkout_lookup_head_tree(&data->opts.baseline, repo);
+
+		if (error == GIT_EUNBORNBRANCH) {
+			error = 0;
+			giterr_clear();
+		}
+
+		if (error < 0)
+			goto cleanup;
+	}
+
+	if ((data->opts.checkout_strategy &
+		(GIT_CHECKOUT_CONFLICT_STYLE_MERGE | GIT_CHECKOUT_CONFLICT_STYLE_DIFF3)) == 0) {
+		git_config_entry *conflict_style = NULL;
+		git_config *cfg = NULL;
+
+		if ((error = git_repository_config__weakptr(&cfg, repo)) < 0 ||
+			(error = git_config_get_entry(&conflict_style, cfg, "merge.conflictstyle")) < 0 ||
+			error == GIT_ENOTFOUND)
+			;
+		else if (error)
+			goto cleanup;
+		else if (strcmp(conflict_style->value, "merge") == 0)
+			data->opts.checkout_strategy |= GIT_CHECKOUT_CONFLICT_STYLE_MERGE;
+		else if (strcmp(conflict_style->value, "diff3") == 0)
+			data->opts.checkout_strategy |= GIT_CHECKOUT_CONFLICT_STYLE_DIFF3;
+		else {
+			giterr_set(GITERR_CHECKOUT, "unknown style '%s' given for 'merge.conflictstyle'",
+				conflict_style);
+			error = -1;
+			git_config_entry_free(conflict_style);
+			goto cleanup;
+		}
+		git_config_entry_free(conflict_style);
+	}
+
+	if ((error = git_vector_init(&data->removes, 0, git__strcmp_cb)) < 0 ||
+		(error = git_vector_init(&data->remove_conflicts, 0, NULL)) < 0 ||
+		(error = git_vector_init(&data->update_conflicts, 0, NULL)) < 0 ||
+		(error = git_pool_init(&data->pool, 1, 0)) < 0 ||
+		(error = git_buf_puts(&data->path, data->opts.target_directory)) < 0 ||
+		(error = git_path_to_dir(&data->path)) < 0 ||
+		(error = git_strmap_alloc(&data->mkdir_map)) < 0)
+		goto cleanup;
+
+	data->workdir_len = git_buf_len(&data->path);
+
+	git_attr_session__init(&data->attr_session, data->repo);
+
+cleanup:
+	if (error < 0)
+		checkout_data_clear(data);
+
+	return error;
+}
+
+#define CHECKOUT_INDEX_DONT_WRITE_MASK \
+	(GIT_CHECKOUT_DONT_UPDATE_INDEX | GIT_CHECKOUT_DONT_WRITE_INDEX)
+
+int git_checkout_iterator(
+	git_iterator *target,
+	git_index *index,
+	const git_checkout_options *opts)
+{
+	int error = 0;
+	git_iterator *baseline = NULL, *workdir = NULL;
+	checkout_data data = {0};
+	git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
+	uint32_t *actions = NULL;
+	size_t *counts = NULL;
+	git_iterator_flag_t iterflags = 0;
+
+	/* initialize structures and options */
+	error = checkout_data_init(&data, target, opts);
+	if (error < 0)
+		return error;
+
+	diff_opts.flags =
+		GIT_DIFF_INCLUDE_UNMODIFIED |
+		GIT_DIFF_INCLUDE_UNREADABLE |
+		GIT_DIFF_INCLUDE_UNTRACKED |
+		GIT_DIFF_RECURSE_UNTRACKED_DIRS | /* needed to match baseline */
+		GIT_DIFF_INCLUDE_IGNORED |
+		GIT_DIFF_INCLUDE_TYPECHANGE |
+		GIT_DIFF_INCLUDE_TYPECHANGE_TREES |
+		GIT_DIFF_SKIP_BINARY_CHECK |
+		GIT_DIFF_INCLUDE_CASECHANGE;
+	if (data.opts.checkout_strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH)
+		diff_opts.flags |= GIT_DIFF_DISABLE_PATHSPEC_MATCH;
+	if (data.opts.paths.count > 0)
+		diff_opts.pathspec = data.opts.paths;
+
+	/* set up iterators */
+
+	iterflags = git_iterator_ignore_case(target) ?
+		GIT_ITERATOR_IGNORE_CASE : GIT_ITERATOR_DONT_IGNORE_CASE;
+
+	if ((error = git_iterator_reset(target, data.pfx, data.pfx)) < 0 ||
+		(error = git_iterator_for_workdir_ext(
+			&workdir, data.repo, data.opts.target_directory, index, NULL,
+			iterflags | GIT_ITERATOR_DONT_AUTOEXPAND,
+			data.pfx, data.pfx)) < 0)
+		goto cleanup;
+
+	if (data.opts.baseline_index) {
+		if ((error = git_iterator_for_index(
+				&baseline, data.opts.baseline_index,
+				iterflags, data.pfx, data.pfx)) < 0)
+			goto cleanup;
+	} else {
+		if ((error = git_iterator_for_tree(
+				&baseline, data.opts.baseline,
+				iterflags, data.pfx, data.pfx)) < 0)
+			goto cleanup;
+	}
+
+	/* Should not have case insensitivity mismatch */
+	assert(git_iterator_ignore_case(workdir) == git_iterator_ignore_case(baseline));
+
+	/* Generate baseline-to-target diff which will include an entry for
+	 * every possible update that might need to be made.
+	 */
+	if ((error = git_diff__from_iterators(
+			&data.diff, data.repo, baseline, target, &diff_opts)) < 0)
+		goto cleanup;
+
+	/* Loop through diff (and working directory iterator) building a list of
+	 * actions to be taken, plus look for conflicts and send notifications,
+	 * then loop through conflicts.
+	 */
+	if ((error = checkout_get_actions(&actions, &counts, &data, workdir)) != 0)
+		goto cleanup;
+
+	data.total_steps = counts[CHECKOUT_ACTION__REMOVE] +
+		counts[CHECKOUT_ACTION__REMOVE_CONFLICT] +
+		counts[CHECKOUT_ACTION__UPDATE_BLOB] +
+		counts[CHECKOUT_ACTION__UPDATE_SUBMODULE] +
+		counts[CHECKOUT_ACTION__UPDATE_CONFLICT];
+
+	report_progress(&data, NULL); /* establish 0 baseline */
+
+	/* To deal with some order dependencies, perform remaining checkout
+	 * in three passes: removes, then update blobs, then update submodules.
+	 */
+	if (counts[CHECKOUT_ACTION__REMOVE] > 0 &&
+		(error = checkout_remove_the_old(actions, &data)) < 0)
+		goto cleanup;
+
+	if (counts[CHECKOUT_ACTION__REMOVE_CONFLICT] > 0 &&
+		(error = checkout_remove_conflicts(&data)) < 0)
+		goto cleanup;
+
+	if (counts[CHECKOUT_ACTION__UPDATE_BLOB] > 0 &&
+		(error = checkout_create_the_new(actions, &data)) < 0)
+		goto cleanup;
+
+	if (counts[CHECKOUT_ACTION__UPDATE_SUBMODULE] > 0 &&
+		(error = checkout_create_submodules(actions, &data)) < 0)
+		goto cleanup;
+
+	if (counts[CHECKOUT_ACTION__UPDATE_CONFLICT] > 0 &&
+		(error = checkout_create_conflicts(&data)) < 0)
+		goto cleanup;
+
+	if (data.index != git_iterator_get_index(target) &&
+		(error = checkout_extensions_update_index(&data)) < 0)
+		goto cleanup;
+
+	assert(data.completed_steps == data.total_steps);
+
+	if (data.opts.perfdata_cb)
+		data.opts.perfdata_cb(&data.perfdata, data.opts.perfdata_payload);
+
+cleanup:
+	if (!error && data.index != NULL &&
+		(data.strategy & CHECKOUT_INDEX_DONT_WRITE_MASK) == 0)
+		error = git_index_write(data.index);
+
+	git_diff_free(data.diff);
+	git_iterator_free(workdir);
+	git_iterator_free(baseline);
+	git__free(actions);
+	git__free(counts);
+	checkout_data_clear(&data);
+
+	return error;
+}
+
+int git_checkout_index(
+	git_repository *repo,
+	git_index *index,
+	const git_checkout_options *opts)
+{
+	int error, owned = 0;
+	git_iterator *index_i;
+
+	if (!index && !repo) {
+		giterr_set(GITERR_CHECKOUT,
+			"Must provide either repository or index to checkout");
+		return -1;
+	}
+
+	if (index && repo &&
+		git_index_owner(index) &&
+		git_index_owner(index) != repo) {
+		giterr_set(GITERR_CHECKOUT,
+			"Index to checkout does not match repository");
+		return -1;
+	} else if(index && repo && !git_index_owner(index)) {
+		GIT_REFCOUNT_OWN(index, repo);
+		owned = 1;
+	}
+
+	if (!repo)
+		repo = git_index_owner(index);
+
+	if (!index && (error = git_repository_index__weakptr(&index, repo)) < 0)
+		return error;
+	GIT_REFCOUNT_INC(index);
+
+	if (!(error = git_iterator_for_index(&index_i, index, 0, NULL, NULL)))
+		error = git_checkout_iterator(index_i, index, opts);
+
+	if (owned)
+		GIT_REFCOUNT_OWN(index, NULL);
+
+	git_iterator_free(index_i);
+	git_index_free(index);
+
+	return error;
+}
+
+int git_checkout_tree(
+	git_repository *repo,
+	const git_object *treeish,
+	const git_checkout_options *opts)
+{
+	int error;
+	git_index *index;
+	git_tree *tree = NULL;
+	git_iterator *tree_i = NULL;
+
+	if (!treeish && !repo) {
+		giterr_set(GITERR_CHECKOUT,
+			"Must provide either repository or tree to checkout");
+		return -1;
+	}
+	if (treeish && repo && git_object_owner(treeish) != repo) {
+		giterr_set(GITERR_CHECKOUT,
+			"Object to checkout does not match repository");
+		return -1;
+	}
+
+	if (!repo)
+		repo = git_object_owner(treeish);
+
+	if (treeish) {
+		if (git_object_peel((git_object **)&tree, treeish, GIT_OBJ_TREE) < 0) {
+			giterr_set(
+				GITERR_CHECKOUT, "Provided object cannot be peeled to a tree");
+			return -1;
+		}
+	}
+	else {
+		if ((error = checkout_lookup_head_tree(&tree, repo)) < 0) {
+			if (error != GIT_EUNBORNBRANCH)
+				giterr_set(
+					GITERR_CHECKOUT,
+					"HEAD could not be peeled to a tree and no treeish given");
+			return error;
+		}
+	}
+
+	if ((error = git_repository_index(&index, repo)) < 0)
+		return error;
+
+	if (!(error = git_iterator_for_tree(&tree_i, tree, 0, NULL, NULL)))
+		error = git_checkout_iterator(tree_i, index, opts);
+
+	git_iterator_free(tree_i);
+	git_index_free(index);
+	git_tree_free(tree);
+
+	return error;
+}
+
+int git_checkout_head(
+	git_repository *repo,
+	const git_checkout_options *opts)
+{
+	assert(repo);
+	return git_checkout_tree(repo, NULL, opts);
+}
+
+int git_checkout_init_options(git_checkout_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_checkout_options, GIT_CHECKOUT_OPTIONS_INIT);
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/checkout.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/checkout.h
new file mode 100755
index 0000000..60aa29b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/checkout.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_checkout_h__
+#define INCLUDE_checkout_h__
+
+#include "git2/checkout.h"
+#include "iterator.h"
+
+#define GIT_CHECKOUT__NOTIFY_CONFLICT_TREE (1u << 12)
+
+/**
+ * Update the working directory to match the target iterator.  The
+ * expected baseline value can be passed in via the checkout options
+ * or else will default to the HEAD commit.
+ */
+extern int git_checkout_iterator(
+	git_iterator *target,
+	git_index *index,
+	const git_checkout_options *opts);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/cherrypick.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/cherrypick.c
new file mode 100755
index 0000000..c929751
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/cherrypick.c
@@ -0,0 +1,229 @@
+/*
+* Copyright (C) the libgit2 contributors. All rights reserved.
+*
+* This file is part of libgit2, distributed under the GNU GPL v2 with
+* a Linking Exception. For full terms see the included COPYING file.
+*/
+
+#include "common.h"
+#include "repository.h"
+#include "filebuf.h"
+#include "merge.h"
+#include "vector.h"
+#include "index.h"
+
+#include "git2/types.h"
+#include "git2/merge.h"
+#include "git2/cherrypick.h"
+#include "git2/commit.h"
+#include "git2/sys/commit.h"
+
+#define GIT_CHERRYPICK_FILE_MODE		0666
+
+static int write_cherrypick_head(
+	git_repository *repo,
+	const char *commit_oidstr)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	git_buf file_path = GIT_BUF_INIT;
+	int error = 0;
+
+	if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_CHERRYPICK_HEAD_FILE)) >= 0 &&
+		(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_CHERRYPICK_FILE_MODE)) >= 0 &&
+		(error = git_filebuf_printf(&file, "%s\n", commit_oidstr)) >= 0)
+		error = git_filebuf_commit(&file);
+
+	if (error < 0)
+		git_filebuf_cleanup(&file);
+
+	git_buf_free(&file_path);
+
+	return error;
+}
+
+static int write_merge_msg(
+	git_repository *repo,
+	const char *commit_msg)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	git_buf file_path = GIT_BUF_INIT;
+	int error = 0;
+
+	if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_MSG_FILE)) < 0 ||
+		(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_CHERRYPICK_FILE_MODE)) < 0 ||
+		(error = git_filebuf_printf(&file, "%s", commit_msg)) < 0)
+		goto cleanup;
+
+	error = git_filebuf_commit(&file);
+
+cleanup:
+	if (error < 0)
+		git_filebuf_cleanup(&file);
+
+	git_buf_free(&file_path);
+
+	return error;
+}
+
+static int cherrypick_normalize_opts(
+	git_repository *repo,
+	git_cherrypick_options *opts,
+	const git_cherrypick_options *given,
+	const char *their_label)
+{
+	int error = 0;
+	unsigned int default_checkout_strategy = GIT_CHECKOUT_SAFE |
+		GIT_CHECKOUT_ALLOW_CONFLICTS;
+
+	GIT_UNUSED(repo);
+
+	if (given != NULL)
+		memcpy(opts, given, sizeof(git_cherrypick_options));
+	else {
+		git_cherrypick_options default_opts = GIT_CHERRYPICK_OPTIONS_INIT;
+		memcpy(opts, &default_opts, sizeof(git_cherrypick_options));
+	}
+
+	if (!opts->checkout_opts.checkout_strategy)
+		opts->checkout_opts.checkout_strategy = default_checkout_strategy;
+
+	if (!opts->checkout_opts.our_label)
+		opts->checkout_opts.our_label = "HEAD";
+
+	if (!opts->checkout_opts.their_label)
+		opts->checkout_opts.their_label = their_label;
+
+	return error;
+}
+
+static int cherrypick_state_cleanup(git_repository *repo)
+{
+	const char *state_files[] = { GIT_CHERRYPICK_HEAD_FILE, GIT_MERGE_MSG_FILE };
+
+	return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files));
+}
+
+static int cherrypick_seterr(git_commit *commit, const char *fmt)
+{
+	char commit_oidstr[GIT_OID_HEXSZ + 1];
+
+	giterr_set(GITERR_CHERRYPICK, fmt,
+		git_oid_tostr(commit_oidstr, GIT_OID_HEXSZ + 1, git_commit_id(commit)));
+
+	return -1;
+}
+
+int git_cherrypick_commit(
+	git_index **out,
+	git_repository *repo,
+	git_commit *cherrypick_commit,
+	git_commit *our_commit,
+	unsigned int mainline,
+	const git_merge_options *merge_opts)
+{
+	git_commit *parent_commit = NULL;
+	git_tree *parent_tree = NULL, *our_tree = NULL, *cherrypick_tree = NULL;
+	int parent = 0, error = 0;
+
+	assert(out && repo && cherrypick_commit && our_commit);
+
+	if (git_commit_parentcount(cherrypick_commit) > 1) {
+		if (!mainline)
+			return cherrypick_seterr(cherrypick_commit,
+				"Mainline branch is not specified but %s is a merge commit");
+
+		parent = mainline;
+	} else {
+		if (mainline)
+			return cherrypick_seterr(cherrypick_commit,
+				"Mainline branch specified but %s is not a merge commit");
+
+		parent = git_commit_parentcount(cherrypick_commit);
+	}
+
+	if (parent &&
+		((error = git_commit_parent(&parent_commit, cherrypick_commit, (parent - 1))) < 0 ||
+		(error = git_commit_tree(&parent_tree, parent_commit)) < 0))
+		goto done;
+
+	if ((error = git_commit_tree(&cherrypick_tree, cherrypick_commit)) < 0 ||
+		(error = git_commit_tree(&our_tree, our_commit)) < 0)
+		goto done;
+
+	error = git_merge_trees(out, repo, parent_tree, our_tree, cherrypick_tree, merge_opts);
+
+done:
+	git_tree_free(parent_tree);
+	git_tree_free(our_tree);
+	git_tree_free(cherrypick_tree);
+	git_commit_free(parent_commit);
+
+	return error;
+}
+
+int git_cherrypick(
+	git_repository *repo,
+	git_commit *commit,
+	const git_cherrypick_options *given_opts)
+{
+	git_cherrypick_options opts;
+	git_reference *our_ref = NULL;
+	git_commit *our_commit = NULL;
+	char commit_oidstr[GIT_OID_HEXSZ + 1];
+	const char *commit_msg, *commit_summary;
+	git_buf their_label = GIT_BUF_INIT;
+	git_index *index = NULL;
+	git_indexwriter indexwriter = GIT_INDEXWRITER_INIT;
+	int error = 0;
+
+	assert(repo && commit);
+
+	GITERR_CHECK_VERSION(given_opts, GIT_CHERRYPICK_OPTIONS_VERSION, "git_cherrypick_options");
+
+	if ((error = git_repository__ensure_not_bare(repo, "cherry-pick")) < 0)
+		return error;
+
+	if ((commit_msg = git_commit_message(commit)) == NULL ||
+		(commit_summary = git_commit_summary(commit)) == NULL) {
+		error = -1;
+		goto on_error;
+	}
+
+	git_oid_nfmt(commit_oidstr, sizeof(commit_oidstr), git_commit_id(commit));
+
+	if ((error = write_merge_msg(repo, commit_msg)) < 0 ||
+		(error = git_buf_printf(&their_label, "%.7s... %s", commit_oidstr, commit_summary)) < 0 ||
+		(error = cherrypick_normalize_opts(repo, &opts, given_opts, git_buf_cstr(&their_label))) < 0 ||
+		(error = git_indexwriter_init_for_operation(&indexwriter, repo, &opts.checkout_opts.checkout_strategy)) < 0 ||
+		(error = write_cherrypick_head(repo, commit_oidstr)) < 0 ||
+		(error = git_repository_head(&our_ref, repo)) < 0 ||
+		(error = git_reference_peel((git_object **)&our_commit, our_ref, GIT_OBJ_COMMIT)) < 0 ||
+		(error = git_cherrypick_commit(&index, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 ||
+		(error = git_merge__check_result(repo, index)) < 0 ||
+		(error = git_merge__append_conflicts_to_merge_msg(repo, index)) < 0 ||
+		(error = git_checkout_index(repo, index, &opts.checkout_opts)) < 0 ||
+		(error = git_indexwriter_commit(&indexwriter)) < 0)
+		goto on_error;
+
+	goto done;
+
+on_error:
+	cherrypick_state_cleanup(repo);
+
+done:
+	git_indexwriter_cleanup(&indexwriter);
+	git_index_free(index);
+	git_commit_free(our_commit);
+	git_reference_free(our_ref);
+	git_buf_free(&their_label);
+
+	return error;
+}
+
+int git_cherrypick_init_options(
+	git_cherrypick_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_cherrypick_options, GIT_CHERRYPICK_OPTIONS_INIT);
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/clone.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/clone.c
new file mode 100755
index 0000000..070daf9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/clone.c
@@ -0,0 +1,566 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include <assert.h>
+
+#include "git2/clone.h"
+#include "git2/remote.h"
+#include "git2/revparse.h"
+#include "git2/branch.h"
+#include "git2/config.h"
+#include "git2/checkout.h"
+#include "git2/commit.h"
+#include "git2/tree.h"
+
+#include "common.h"
+#include "remote.h"
+#include "fileops.h"
+#include "refs.h"
+#include "path.h"
+#include "repository.h"
+#include "odb.h"
+
+static int clone_local_into(git_repository *repo, git_remote *remote, const git_fetch_options *fetch_opts, const git_checkout_options *co_opts, const char *branch, int link);
+
+static int create_branch(
+	git_reference **branch,
+	git_repository *repo,
+	const git_oid *target,
+	const char *name,
+	const char *log_message)
+{
+	git_commit *head_obj = NULL;
+	git_reference *branch_ref = NULL;
+	git_buf refname = GIT_BUF_INIT;
+	int error;
+
+	/* Find the target commit */
+	if ((error = git_commit_lookup(&head_obj, repo, target)) < 0)
+		return error;
+
+	/* Create the new branch */
+	if ((error = git_buf_printf(&refname, GIT_REFS_HEADS_DIR "%s", name)) < 0)
+		return error;
+
+	error = git_reference_create(&branch_ref, repo, git_buf_cstr(&refname), target, 0, log_message);
+	git_buf_free(&refname);
+	git_commit_free(head_obj);
+
+	if (!error)
+		*branch = branch_ref;
+	else
+		git_reference_free(branch_ref);
+
+	return error;
+}
+
+static int setup_tracking_config(
+	git_repository *repo,
+	const char *branch_name,
+	const char *remote_name,
+	const char *merge_target)
+{
+	git_config *cfg;
+	git_buf remote_key = GIT_BUF_INIT, merge_key = GIT_BUF_INIT;
+	int error = -1;
+
+	if (git_repository_config__weakptr(&cfg, repo) < 0)
+		return -1;
+
+	if (git_buf_printf(&remote_key, "branch.%s.remote", branch_name) < 0)
+		goto cleanup;
+
+	if (git_buf_printf(&merge_key, "branch.%s.merge", branch_name) < 0)
+		goto cleanup;
+
+	if (git_config_set_string(cfg, git_buf_cstr(&remote_key), remote_name) < 0)
+		goto cleanup;
+
+	if (git_config_set_string(cfg, git_buf_cstr(&merge_key), merge_target) < 0)
+		goto cleanup;
+
+	error = 0;
+
+cleanup:
+	git_buf_free(&remote_key);
+	git_buf_free(&merge_key);
+	return error;
+}
+
+static int create_tracking_branch(
+	git_reference **branch,
+	git_repository *repo,
+	const git_oid *target,
+	const char *branch_name,
+	const char *log_message)
+{
+	int error;
+
+	if ((error = create_branch(branch, repo, target, branch_name, log_message)) < 0)
+		return error;
+
+	return setup_tracking_config(
+		repo,
+		branch_name,
+		GIT_REMOTE_ORIGIN,
+		git_reference_name(*branch));
+}
+
+static int update_head_to_new_branch(
+	git_repository *repo,
+	const git_oid *target,
+	const char *name,
+	const char *reflog_message)
+{
+	git_reference *tracking_branch = NULL;
+	int error;
+
+	if (!git__prefixcmp(name, GIT_REFS_HEADS_DIR))
+		name += strlen(GIT_REFS_HEADS_DIR);
+
+	error = create_tracking_branch(&tracking_branch, repo, target, name,
+			reflog_message);
+
+	if (!error)
+		error = git_repository_set_head(
+			repo, git_reference_name(tracking_branch));
+
+	git_reference_free(tracking_branch);
+
+	/* if it already existed, then the user's refspec created it for us, ignore it' */
+	if (error == GIT_EEXISTS)
+		error = 0;
+
+	return error;
+}
+
+static int update_head_to_remote(
+		git_repository *repo,
+		git_remote *remote,
+		const char *reflog_message)
+{
+	int error = 0;
+	size_t refs_len;
+	git_refspec *refspec;
+	const git_remote_head *remote_head, **refs;
+	const git_oid *remote_head_id;
+	git_buf remote_master_name = GIT_BUF_INIT;
+	git_buf branch = GIT_BUF_INIT;
+
+	if ((error = git_remote_ls(&refs, &refs_len, remote)) < 0)
+		return error;
+
+	/* We cloned an empty repository or one with an unborn HEAD */
+	if (refs_len == 0 || strcmp(refs[0]->name, GIT_HEAD_FILE))
+		return setup_tracking_config(
+			repo, "master", GIT_REMOTE_ORIGIN, GIT_REFS_HEADS_MASTER_FILE);
+
+	/* We know we have HEAD, let's see where it points */
+	remote_head = refs[0];
+	assert(remote_head);
+
+	remote_head_id = &remote_head->oid;
+
+	error = git_remote_default_branch(&branch, remote);
+	if (error == GIT_ENOTFOUND) {
+		error = git_repository_set_head_detached(
+			repo, remote_head_id);
+		goto cleanup;
+	}
+
+	refspec = git_remote__matching_refspec(remote, git_buf_cstr(&branch));
+
+	if (refspec == NULL) {
+		giterr_set(GITERR_NET, "the remote's default branch does not fit the refspec configuration");
+		error = GIT_EINVALIDSPEC;
+		goto cleanup;
+	}
+
+	/* Determine the remote tracking reference name from the local master */
+	if ((error = git_refspec_transform(
+		&remote_master_name,
+		refspec,
+		git_buf_cstr(&branch))) < 0)
+		goto cleanup;
+
+	error = update_head_to_new_branch(
+		repo,
+		remote_head_id,
+		git_buf_cstr(&branch),
+		reflog_message);
+
+cleanup:
+	git_buf_free(&remote_master_name);
+	git_buf_free(&branch);
+
+	return error;
+}
+
+static int update_head_to_branch(
+		git_repository *repo,
+		const char *remote_name,
+		const char *branch,
+		const char *reflog_message)
+{
+	int retcode;
+	git_buf remote_branch_name = GIT_BUF_INIT;
+	git_reference* remote_ref = NULL;
+
+	assert(remote_name && branch);
+
+	if ((retcode = git_buf_printf(&remote_branch_name, GIT_REFS_REMOTES_DIR "%s/%s",
+		remote_name, branch)) < 0 )
+		goto cleanup;
+
+	if ((retcode = git_reference_lookup(&remote_ref, repo, git_buf_cstr(&remote_branch_name))) < 0)
+		goto cleanup;
+
+	retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch,
+			reflog_message);
+
+cleanup:
+	git_reference_free(remote_ref);
+	git_buf_free(&remote_branch_name);
+	return retcode;
+}
+
+static int default_repository_create(git_repository **out, const char *path, int bare, void *payload)
+{
+	GIT_UNUSED(payload);
+
+	return git_repository_init(out, path, bare);
+}
+
+static int default_remote_create(
+		git_remote **out,
+		git_repository *repo,
+		const char *name,
+		const char *url,
+		void *payload)
+{
+	GIT_UNUSED(payload);
+
+	return git_remote_create(out, repo, name, url);
+}
+
+/*
+ * submodules?
+ */
+
+static int create_and_configure_origin(
+		git_remote **out,
+		git_repository *repo,
+		const char *url,
+		const git_clone_options *options)
+{
+	int error;
+	git_remote *origin = NULL;
+	char buf[GIT_PATH_MAX];
+	git_remote_create_cb remote_create = options->remote_cb;
+	void *payload = options->remote_cb_payload;
+
+	/* If the path exists and is a dir, the url should be the absolute path */
+	if (git_path_root(url) < 0 && git_path_exists(url) && git_path_isdir(url)) {
+		if (p_realpath(url, buf) == NULL)
+			return -1;
+
+		url = buf;
+	}
+
+	if (!remote_create) {
+		remote_create = default_remote_create;
+		payload = NULL;
+	}
+
+	if ((error = remote_create(&origin, repo, "origin", url, payload)) < 0)
+		goto on_error;
+
+	*out = origin;
+	return 0;
+
+on_error:
+	git_remote_free(origin);
+	return error;
+}
+
+static bool should_checkout(
+	git_repository *repo,
+	bool is_bare,
+	const git_checkout_options *opts)
+{
+	if (is_bare)
+		return false;
+
+	if (!opts)
+		return false;
+
+	if (opts->checkout_strategy == GIT_CHECKOUT_NONE)
+		return false;
+
+	return !git_repository_head_unborn(repo);
+}
+
+static int checkout_branch(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, const char *reflog_message)
+{
+	int error;
+
+	if (branch)
+		error = update_head_to_branch(repo, git_remote_name(remote), branch,
+				reflog_message);
+	/* Point HEAD to the same ref as the remote's head */
+	else
+		error = update_head_to_remote(repo, remote, reflog_message);
+
+	if (!error && should_checkout(repo, git_repository_is_bare(repo), co_opts))
+		error = git_checkout_head(repo, co_opts);
+
+	return error;
+}
+
+static int clone_into(git_repository *repo, git_remote *_remote, const git_fetch_options *opts, const git_checkout_options *co_opts, const char *branch)
+{
+	int error;
+	git_buf reflog_message = GIT_BUF_INIT;
+	git_fetch_options fetch_opts;
+	git_remote *remote;
+
+	assert(repo && _remote);
+
+	if (!git_repository_is_empty(repo)) {
+		giterr_set(GITERR_INVALID, "the repository is not empty");
+		return -1;
+	}
+
+	if ((error = git_remote_dup(&remote, _remote)) < 0)
+		return error;
+
+	memcpy(&fetch_opts, opts, sizeof(git_fetch_options));
+	fetch_opts.update_fetchhead = 0;
+	fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL;
+	git_buf_printf(&reflog_message, "clone: from %s", git_remote_url(remote));
+
+	if ((error = git_remote_fetch(remote, NULL, &fetch_opts, git_buf_cstr(&reflog_message))) != 0)
+		goto cleanup;
+
+	error = checkout_branch(repo, remote, co_opts, branch, git_buf_cstr(&reflog_message));
+
+cleanup:
+	git_remote_free(remote);
+	git_buf_free(&reflog_message);
+
+	return error;
+}
+
+int git_clone__should_clone_local(const char *url_or_path, git_clone_local_t local)
+{
+	git_buf fromurl = GIT_BUF_INIT;
+	const char *path = url_or_path;
+	bool is_url, is_local;
+
+	if (local == GIT_CLONE_NO_LOCAL)
+		return 0;
+
+	if ((is_url = git_path_is_local_file_url(url_or_path)) != 0) {
+		if (git_path_fromurl(&fromurl, url_or_path) < 0) {
+			is_local = -1;
+			goto done;
+		}
+
+		path = fromurl.ptr;
+	}
+
+	is_local = (!is_url || local != GIT_CLONE_LOCAL_AUTO) &&
+		git_path_isdir(path);
+
+done:
+	git_buf_free(&fromurl);
+	return is_local;
+}
+
+int git_clone(
+	git_repository **out,
+	const char *url,
+	const char *local_path,
+	const git_clone_options *_options)
+{
+	int error = 0;
+	git_repository *repo = NULL;
+	git_remote *origin;
+	git_clone_options options = GIT_CLONE_OPTIONS_INIT;
+	uint32_t rmdir_flags = GIT_RMDIR_REMOVE_FILES;
+	git_repository_create_cb repository_cb;
+
+	assert(out && url && local_path);
+
+	if (_options)
+		memcpy(&options, _options, sizeof(git_clone_options));
+
+	GITERR_CHECK_VERSION(&options, GIT_CLONE_OPTIONS_VERSION, "git_clone_options");
+
+	/* Only clone to a new directory or an empty directory */
+	if (git_path_exists(local_path) && !git_path_is_empty_dir(local_path)) {
+		giterr_set(GITERR_INVALID,
+			"'%s' exists and is not an empty directory", local_path);
+		return GIT_EEXISTS;
+	}
+
+	/* Only remove the root directory on failure if we create it */
+	if (git_path_exists(local_path))
+		rmdir_flags |= GIT_RMDIR_SKIP_ROOT;
+
+	if (options.repository_cb)
+		repository_cb = options.repository_cb;
+	else
+		repository_cb = default_repository_create;
+
+	if ((error = repository_cb(&repo, local_path, options.bare, options.repository_cb_payload)) < 0)
+		return error;
+
+	if (!(error = create_and_configure_origin(&origin, repo, url, &options))) {
+		int clone_local = git_clone__should_clone_local(url, options.local);
+		int link = options.local != GIT_CLONE_LOCAL_NO_LINKS;
+
+		if (clone_local == 1)
+			error = clone_local_into(
+				repo, origin, &options.fetch_opts, &options.checkout_opts,
+				options.checkout_branch, link);
+		else if (clone_local == 0)
+			error = clone_into(
+				repo, origin, &options.fetch_opts, &options.checkout_opts,
+				options.checkout_branch);
+		else
+			error = -1;
+
+		git_remote_free(origin);
+	}
+
+	if (error != 0) {
+		git_error_state last_error = {0};
+		giterr_capture(&last_error, error);
+
+		git_repository_free(repo);
+		repo = NULL;
+
+		(void)git_futils_rmdir_r(local_path, NULL, rmdir_flags);
+
+		giterr_restore(&last_error);
+	}
+
+	*out = repo;
+	return error;
+}
+
+int git_clone_init_options(git_clone_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_clone_options, GIT_CLONE_OPTIONS_INIT);
+	return 0;
+}
+
+static const char *repository_base(git_repository *repo)
+{
+	if (git_repository_is_bare(repo))
+		return git_repository_path(repo);
+
+	return git_repository_workdir(repo);
+}
+
+static bool can_link(const char *src, const char *dst, int link)
+{
+#ifdef GIT_WIN32
+	GIT_UNUSED(src);
+	GIT_UNUSED(dst);
+	GIT_UNUSED(link);
+	return false;
+#else
+
+	struct stat st_src, st_dst;
+
+	if (!link)
+		return false;
+
+	if (p_stat(src, &st_src) < 0)
+		return false;
+
+	if (p_stat(dst, &st_dst) < 0)
+		return false;
+
+	return st_src.st_dev == st_dst.st_dev;
+#endif
+}
+
+static int clone_local_into(git_repository *repo, git_remote *remote, const git_fetch_options *fetch_opts, const git_checkout_options *co_opts, const char *branch, int link)
+{
+	int error, flags;
+	git_repository *src;
+	git_buf src_odb = GIT_BUF_INIT, dst_odb = GIT_BUF_INIT, src_path = GIT_BUF_INIT;
+	git_buf reflog_message = GIT_BUF_INIT;
+
+	assert(repo && remote);
+
+	if (!git_repository_is_empty(repo)) {
+		giterr_set(GITERR_INVALID, "the repository is not empty");
+		return -1;
+	}
+
+	/*
+	 * Let's figure out what path we should use for the source
+	 * repo, if it's not rooted, the path should be relative to
+	 * the repository's worktree/gitdir.
+	 */
+	if ((error = git_path_from_url_or_path(&src_path, git_remote_url(remote))) < 0)
+		return error;
+
+	/* Copy .git/objects/ from the source to the target */
+	if ((error = git_repository_open(&src, git_buf_cstr(&src_path))) < 0) {
+		git_buf_free(&src_path);
+		return error;
+	}
+
+	git_buf_joinpath(&src_odb, git_repository_path(src), GIT_OBJECTS_DIR);
+	git_buf_joinpath(&dst_odb, git_repository_path(repo), GIT_OBJECTS_DIR);
+	if (git_buf_oom(&src_odb) || git_buf_oom(&dst_odb)) {
+		error = -1;
+		goto cleanup;
+	}
+
+	flags = 0;
+	if (can_link(git_repository_path(src), git_repository_path(repo), link))
+		flags |= GIT_CPDIR_LINK_FILES;
+
+	error = git_futils_cp_r(git_buf_cstr(&src_odb), git_buf_cstr(&dst_odb),
+				flags, GIT_OBJECT_DIR_MODE);
+
+	/*
+	 * can_link() doesn't catch all variations, so if we hit an
+	 * error and did want to link, let's try again without trying
+	 * to link.
+	 */
+	if (error < 0 && link) {
+		flags &= ~GIT_CPDIR_LINK_FILES;
+		error = git_futils_cp_r(git_buf_cstr(&src_odb), git_buf_cstr(&dst_odb),
+					flags, GIT_OBJECT_DIR_MODE);
+	}
+
+	if (error < 0)
+		goto cleanup;
+
+	git_buf_printf(&reflog_message, "clone: from %s", git_remote_url(remote));
+
+	if ((error = git_remote_fetch(remote, NULL, fetch_opts, git_buf_cstr(&reflog_message))) != 0)
+		goto cleanup;
+
+	error = checkout_branch(repo, remote, co_opts, branch, git_buf_cstr(&reflog_message));
+
+cleanup:
+	git_buf_free(&reflog_message);
+	git_buf_free(&src_path);
+	git_buf_free(&src_odb);
+	git_buf_free(&dst_odb);
+	git_repository_free(src);
+	return error;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/clone.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/clone.h
new file mode 100755
index 0000000..14ca5d4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/clone.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_clone_h__
+#define INCLUDE_clone_h__
+
+extern int git_clone__should_clone_local(const char *url, git_clone_local_t local);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/commit.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/commit.c
new file mode 100755
index 0000000..616f947
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/commit.c
@@ -0,0 +1,575 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2/common.h"
+#include "git2/object.h"
+#include "git2/repository.h"
+#include "git2/signature.h"
+#include "git2/sys/commit.h"
+
+#include "common.h"
+#include "odb.h"
+#include "commit.h"
+#include "signature.h"
+#include "message.h"
+#include "refs.h"
+
+void git_commit__free(void *_commit)
+{
+	git_commit *commit = _commit;
+
+	git_array_clear(commit->parent_ids);
+
+	git_signature_free(commit->author);
+	git_signature_free(commit->committer);
+
+	git__free(commit->raw_header);
+	git__free(commit->raw_message);
+	git__free(commit->message_encoding);
+	git__free(commit->summary);
+
+	git__free(commit);
+}
+
+int git_commit_create_from_callback(
+	git_oid *id,
+	git_repository *repo,
+	const char *update_ref,
+	const git_signature *author,
+	const git_signature *committer,
+	const char *message_encoding,
+	const char *message,
+	const git_oid *tree,
+	git_commit_parent_callback parent_cb,
+	void *parent_payload)
+{
+	git_reference *ref = NULL;
+	int error = 0, matched_parent = 0;
+	const git_oid *current_id = NULL;
+	git_buf commit = GIT_BUF_INIT;
+	size_t i = 0;
+	git_odb *odb;
+	const git_oid *parent;
+
+	assert(id && repo && tree && parent_cb);
+
+	if (update_ref) {
+		error = git_reference_lookup_resolved(&ref, repo, update_ref, 10);
+		if (error < 0 && error != GIT_ENOTFOUND)
+			return error;
+	}
+	giterr_clear();
+
+	if (ref)
+		current_id = git_reference_target(ref);
+
+	git_oid__writebuf(&commit, "tree ", tree);
+
+	while ((parent = parent_cb(i, parent_payload)) != NULL) {
+		git_oid__writebuf(&commit, "parent ", parent);
+		if (i == 0 && current_id && git_oid_equal(current_id, parent))
+			matched_parent = 1;
+		i++;
+	}
+
+	if (ref && !matched_parent) {
+		git_reference_free(ref);
+		git_buf_free(&commit);
+		giterr_set(GITERR_OBJECT, "failed to create commit: current tip is not the first parent");
+		return GIT_EMODIFIED;
+	}
+
+	git_signature__writebuf(&commit, "author ", author);
+	git_signature__writebuf(&commit, "committer ", committer);
+
+	if (message_encoding != NULL)
+		git_buf_printf(&commit, "encoding %s\n", message_encoding);
+
+	git_buf_putc(&commit, '\n');
+
+	if (git_buf_puts(&commit, message) < 0)
+		goto on_error;
+
+	if (git_repository_odb__weakptr(&odb, repo) < 0)
+		goto on_error;
+
+	if (git_odb_write(id, odb, commit.ptr, commit.size, GIT_OBJ_COMMIT) < 0)
+		goto on_error;
+
+	git_buf_free(&commit);
+
+	if (update_ref != NULL) {
+		error = git_reference__update_for_commit(
+			repo, ref, update_ref, id, "commit");
+		git_reference_free(ref);
+		return error;
+	}
+
+	return 0;
+
+on_error:
+	git_buf_free(&commit);
+	giterr_set(GITERR_OBJECT, "Failed to create commit.");
+	return -1;
+}
+
+typedef struct {
+	size_t total;
+	va_list args;
+} commit_parent_varargs;
+
+static const git_oid *commit_parent_from_varargs(size_t curr, void *payload)
+{
+	commit_parent_varargs *data = payload;
+	const git_commit *commit;
+	if (curr >= data->total)
+		return NULL;
+	commit = va_arg(data->args, const git_commit *);
+	return commit ? git_commit_id(commit) : NULL;
+}
+
+int git_commit_create_v(
+	git_oid *id,
+	git_repository *repo,
+	const char *update_ref,
+	const git_signature *author,
+	const git_signature *committer,
+	const char *message_encoding,
+	const char *message,
+	const git_tree *tree,
+	size_t parent_count,
+	...)
+{
+	int error = 0;
+	commit_parent_varargs data;
+
+	assert(tree && git_tree_owner(tree) == repo);
+
+	data.total = parent_count;
+	va_start(data.args, parent_count);
+
+	error = git_commit_create_from_callback(
+		id, repo, update_ref, author, committer,
+		message_encoding, message, git_tree_id(tree),
+		commit_parent_from_varargs, &data);
+
+	va_end(data.args);
+	return error;
+}
+
+typedef struct {
+	size_t total;
+	const git_oid **parents;
+} commit_parent_oids;
+
+static const git_oid *commit_parent_from_ids(size_t curr, void *payload)
+{
+	commit_parent_oids *data = payload;
+	return (curr < data->total) ? data->parents[curr] : NULL;
+}
+
+int git_commit_create_from_ids(
+	git_oid *id,
+	git_repository *repo,
+	const char *update_ref,
+	const git_signature *author,
+	const git_signature *committer,
+	const char *message_encoding,
+	const char *message,
+	const git_oid *tree,
+	size_t parent_count,
+	const git_oid *parents[])
+{
+	commit_parent_oids data = { parent_count, parents };
+
+	return git_commit_create_from_callback(
+		id, repo, update_ref, author, committer,
+		message_encoding, message, tree,
+		commit_parent_from_ids, &data);
+}
+
+typedef struct {
+	size_t total;
+	const git_commit **parents;
+	git_repository *repo;
+} commit_parent_data;
+
+static const git_oid *commit_parent_from_array(size_t curr, void *payload)
+{
+	commit_parent_data *data = payload;
+	const git_commit *commit;
+	if (curr >= data->total)
+		return NULL;
+	commit = data->parents[curr];
+	if (git_commit_owner(commit) != data->repo)
+		return NULL;
+	return git_commit_id(commit);
+}
+
+int git_commit_create(
+	git_oid *id,
+	git_repository *repo,
+	const char *update_ref,
+	const git_signature *author,
+	const git_signature *committer,
+	const char *message_encoding,
+	const char *message,
+	const git_tree *tree,
+	size_t parent_count,
+	const git_commit *parents[])
+{
+	commit_parent_data data = { parent_count, parents, repo };
+
+	assert(tree && git_tree_owner(tree) == repo);
+
+	return git_commit_create_from_callback(
+		id, repo, update_ref, author, committer,
+		message_encoding, message, git_tree_id(tree),
+		commit_parent_from_array, &data);
+}
+
+static const git_oid *commit_parent_for_amend(size_t curr, void *payload)
+{
+	const git_commit *commit_to_amend = payload;
+	if (curr >= git_array_size(commit_to_amend->parent_ids))
+		return NULL;
+	return git_array_get(commit_to_amend->parent_ids, curr);
+}
+
+int git_commit_amend(
+	git_oid *id,
+	const git_commit *commit_to_amend,
+	const char *update_ref,
+	const git_signature *author,
+	const git_signature *committer,
+	const char *message_encoding,
+	const char *message,
+	const git_tree *tree)
+{
+	git_repository *repo;
+	git_oid tree_id;
+	git_reference *ref;
+	int error;
+
+	assert(id && commit_to_amend);
+
+	repo = git_commit_owner(commit_to_amend);
+
+	if (!author)
+		author = git_commit_author(commit_to_amend);
+	if (!committer)
+		committer = git_commit_committer(commit_to_amend);
+	if (!message_encoding)
+		message_encoding = git_commit_message_encoding(commit_to_amend);
+	if (!message)
+		message = git_commit_message(commit_to_amend);
+
+	if (!tree) {
+		git_tree *old_tree;
+		GITERR_CHECK_ERROR( git_commit_tree(&old_tree, commit_to_amend) );
+		git_oid_cpy(&tree_id, git_tree_id(old_tree));
+		git_tree_free(old_tree);
+	} else {
+		assert(git_tree_owner(tree) == repo);
+		git_oid_cpy(&tree_id, git_tree_id(tree));
+	}
+
+	if (update_ref) {
+		if ((error = git_reference_lookup_resolved(&ref, repo, update_ref, 5)) < 0)
+			return error;
+
+		if (git_oid_cmp(git_commit_id(commit_to_amend), git_reference_target(ref))) {
+			git_reference_free(ref);
+			giterr_set(GITERR_REFERENCE, "commit to amend is not the tip of the given branch");
+			return -1;
+		}
+	}
+
+	error = git_commit_create_from_callback(
+		id, repo, NULL, author, committer, message_encoding, message,
+		&tree_id, commit_parent_for_amend, (void *)commit_to_amend);
+
+	if (!error && update_ref) {
+		error = git_reference__update_for_commit(
+			repo, ref, NULL, id, "commit");
+		git_reference_free(ref);
+	}
+
+	return error;
+}
+
+int git_commit__parse(void *_commit, git_odb_object *odb_obj)
+{
+	git_commit *commit = _commit;
+	const char *buffer_start = git_odb_object_data(odb_obj), *buffer;
+	const char *buffer_end = buffer_start + git_odb_object_size(odb_obj);
+	git_oid parent_id;
+	size_t header_len;
+	git_signature dummy_sig;
+
+	buffer = buffer_start;
+
+	/* Allocate for one, which will allow not to realloc 90% of the time  */
+	git_array_init_to_size(commit->parent_ids, 1);
+	GITERR_CHECK_ARRAY(commit->parent_ids);
+
+	/* The tree is always the first field */
+	if (git_oid__parse(&commit->tree_id, &buffer, buffer_end, "tree ") < 0)
+		goto bad_buffer;
+
+	/*
+	 * TODO: commit grafts!
+	 */
+
+	while (git_oid__parse(&parent_id, &buffer, buffer_end, "parent ") == 0) {
+		git_oid *new_id = git_array_alloc(commit->parent_ids);
+		GITERR_CHECK_ALLOC(new_id);
+
+		git_oid_cpy(new_id, &parent_id);
+	}
+
+	commit->author = git__malloc(sizeof(git_signature));
+	GITERR_CHECK_ALLOC(commit->author);
+
+	if (git_signature__parse(commit->author, &buffer, buffer_end, "author ", '\n') < 0)
+		return -1;
+
+	/* Some tools create multiple author fields, ignore the extra ones */
+	while ((size_t)(buffer_end - buffer) >= strlen("author ") && !git__prefixcmp(buffer, "author ")) {
+		if (git_signature__parse(&dummy_sig, &buffer, buffer_end, "author ", '\n') < 0)
+			return -1;
+
+		git__free(dummy_sig.name);
+		git__free(dummy_sig.email);
+	}
+
+	/* Always parse the committer; we need the commit time */
+	commit->committer = git__malloc(sizeof(git_signature));
+	GITERR_CHECK_ALLOC(commit->committer);
+
+	if (git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n') < 0)
+		return -1;
+
+	/* Parse add'l header entries */
+	while (buffer < buffer_end) {
+		const char *eoln = buffer;
+		if (buffer[-1] == '\n' && buffer[0] == '\n')
+			break;
+
+		while (eoln < buffer_end && *eoln != '\n')
+			++eoln;
+
+		if (git__prefixcmp(buffer, "encoding ") == 0) {
+			buffer += strlen("encoding ");
+
+			commit->message_encoding = git__strndup(buffer, eoln - buffer);
+			GITERR_CHECK_ALLOC(commit->message_encoding);
+		}
+
+		if (eoln < buffer_end && *eoln == '\n')
+			++eoln;
+		buffer = eoln;
+	}
+
+	header_len = buffer - buffer_start;
+	commit->raw_header = git__strndup(buffer_start, header_len);
+	GITERR_CHECK_ALLOC(commit->raw_header);
+
+	/* point "buffer" to data after header, +1 for the final LF */
+	buffer = buffer_start + header_len + 1;
+
+	/* extract commit message */
+	if (buffer <= buffer_end) {
+		commit->raw_message = git__strndup(buffer, buffer_end - buffer);
+		GITERR_CHECK_ALLOC(commit->raw_message);
+	}
+
+	return 0;
+
+bad_buffer:
+	giterr_set(GITERR_OBJECT, "Failed to parse bad commit object");
+	return -1;
+}
+
+#define GIT_COMMIT_GETTER(_rvalue, _name, _return) \
+	_rvalue git_commit_##_name(const git_commit *commit) \
+	{\
+		assert(commit); \
+		return _return; \
+	}
+
+GIT_COMMIT_GETTER(const git_signature *, author, commit->author)
+GIT_COMMIT_GETTER(const git_signature *, committer, commit->committer)
+GIT_COMMIT_GETTER(const char *, message_raw, commit->raw_message)
+GIT_COMMIT_GETTER(const char *, message_encoding, commit->message_encoding)
+GIT_COMMIT_GETTER(const char *, raw_header, commit->raw_header)
+GIT_COMMIT_GETTER(git_time_t, time, commit->committer->when.time)
+GIT_COMMIT_GETTER(int, time_offset, commit->committer->when.offset)
+GIT_COMMIT_GETTER(unsigned int, parentcount, (unsigned int)git_array_size(commit->parent_ids))
+GIT_COMMIT_GETTER(const git_oid *, tree_id, &commit->tree_id)
+
+const char *git_commit_message(const git_commit *commit)
+{
+	const char *message;
+
+	assert(commit);
+
+	message = commit->raw_message;
+
+	/* trim leading newlines from raw message */
+	while (*message && *message == '\n')
+		++message;
+
+	return message;
+}
+
+const char *git_commit_summary(git_commit *commit)
+{
+	git_buf summary = GIT_BUF_INIT;
+	const char *msg, *space;
+
+	assert(commit);
+
+	if (!commit->summary) {
+		for (msg = git_commit_message(commit), space = NULL; *msg; ++msg) {
+			if (msg[0] == '\n' && (!msg[1] || msg[1] == '\n'))
+				break;
+			else if (msg[0] == '\n')
+				git_buf_putc(&summary, ' ');
+			else if (git__isspace(msg[0]))
+				space = space ? space : msg;
+			else if (space) {
+				git_buf_put(&summary, space, (msg - space) + 1);
+				space = NULL;
+			} else
+				git_buf_putc(&summary, *msg);
+		}
+
+		commit->summary = git_buf_detach(&summary);
+		if (!commit->summary)
+			commit->summary = git__strdup("");
+	}
+
+	return commit->summary;
+}
+
+int git_commit_tree(git_tree **tree_out, const git_commit *commit)
+{
+	assert(commit);
+	return git_tree_lookup(tree_out, commit->object.repo, &commit->tree_id);
+}
+
+const git_oid *git_commit_parent_id(
+	const git_commit *commit, unsigned int n)
+{
+	assert(commit);
+
+	return git_array_get(commit->parent_ids, n);
+}
+
+int git_commit_parent(
+	git_commit **parent, const git_commit *commit, unsigned int n)
+{
+	const git_oid *parent_id;
+	assert(commit);
+
+	parent_id = git_commit_parent_id(commit, n);
+	if (parent_id == NULL) {
+		giterr_set(GITERR_INVALID, "Parent %u does not exist", n);
+		return GIT_ENOTFOUND;
+	}
+
+	return git_commit_lookup(parent, commit->object.repo, parent_id);
+}
+
+int git_commit_nth_gen_ancestor(
+	git_commit **ancestor,
+	const git_commit *commit,
+	unsigned int n)
+{
+	git_commit *current, *parent = NULL;
+	int error;
+
+	assert(ancestor && commit);
+
+	if (git_object_dup((git_object **) &current, (git_object *) commit) < 0)
+		return -1;
+
+	if (n == 0) {
+		*ancestor = current;
+		return 0;
+	}
+
+	while (n--) {
+		error = git_commit_parent(&parent, current, 0);
+
+		git_commit_free(current);
+
+		if (error < 0)
+			return error;
+
+		current = parent;
+	}
+
+	*ancestor = parent;
+	return 0;
+}
+
+int git_commit_header_field(git_buf *out, const git_commit *commit, const char *field)
+{
+	const char *buf = commit->raw_header;
+	const char *h, *eol;
+
+	git_buf_sanitize(out);
+	while ((h = strchr(buf, '\n')) && h[1] != '\0' && h[1] != '\n') {
+		h++;
+		if (git__prefixcmp(h, field)) {
+			buf = h;
+			continue;
+		}
+
+		h += strlen(field);
+		eol = strchr(h, '\n');
+		if (h[0] != ' ') {
+			buf = h;
+			continue;
+		}
+		if (!eol)
+			goto malformed;
+
+		h++; /* skip the SP */
+
+		git_buf_put(out, h, eol - h);
+		if (git_buf_oom(out))
+			goto oom;
+
+		/* If the next line starts with SP, it's multi-line, we must continue */
+		while (eol[1] == ' ') {
+			git_buf_putc(out, '\n');
+			h = eol + 2;
+			eol = strchr(h, '\n');
+			if (!eol)
+				goto malformed;
+
+			git_buf_put(out, h, eol - h);
+		}
+
+		if (git_buf_oom(out))
+			goto oom;
+
+		return 0;
+	}
+
+	return GIT_ENOTFOUND;
+
+malformed:
+	giterr_set(GITERR_OBJECT, "malformed header");
+	return -1;
+oom:
+	giterr_set_oom();
+	return -1;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/commit.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/commit.h
new file mode 100755
index 0000000..efb080b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/commit.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_commit_h__
+#define INCLUDE_commit_h__
+
+#include "git2/commit.h"
+#include "tree.h"
+#include "repository.h"
+#include "array.h"
+
+#include <time.h>
+
+struct git_commit {
+	git_object object;
+
+	git_array_t(git_oid) parent_ids;
+	git_oid tree_id;
+
+	git_signature *author;
+	git_signature *committer;
+
+	char *message_encoding;
+	char *raw_message;
+	char *raw_header;
+
+	char *summary;
+};
+
+void git_commit__free(void *commit);
+int git_commit__parse(void *commit, git_odb_object *obj);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/commit_list.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/commit_list.c
new file mode 100755
index 0000000..3054c18
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/commit_list.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "commit_list.h"
+#include "common.h"
+#include "revwalk.h"
+#include "pool.h"
+#include "odb.h"
+
+int git_commit_list_time_cmp(const void *a, const void *b)
+{
+	const git_commit_list_node *commit_a = a;
+	const git_commit_list_node *commit_b = b;
+
+	return (commit_a->time < commit_b->time);
+}
+
+git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p)
+{
+	git_commit_list *new_list = git__malloc(sizeof(git_commit_list));
+	if (new_list != NULL) {
+		new_list->item = item;
+		new_list->next = *list_p;
+	}
+	*list_p = new_list;
+	return new_list;
+}
+
+git_commit_list *git_commit_list_insert_by_date(git_commit_list_node *item, git_commit_list **list_p)
+{
+	git_commit_list **pp = list_p;
+	git_commit_list *p;
+
+	while ((p = *pp) != NULL) {
+		if (git_commit_list_time_cmp(p->item, item) > 0)
+			break;
+
+		pp = &p->next;
+	}
+
+	return git_commit_list_insert(item, pp);
+}
+
+git_commit_list_node *git_commit_list_alloc_node(git_revwalk *walk)
+{
+	return (git_commit_list_node *)git_pool_malloc(&walk->commit_pool, COMMIT_ALLOC);
+}
+
+static int commit_error(git_commit_list_node *commit, const char *msg)
+{
+	char commit_oid[GIT_OID_HEXSZ + 1];
+	git_oid_fmt(commit_oid, &commit->oid);
+	commit_oid[GIT_OID_HEXSZ] = '\0';
+
+	giterr_set(GITERR_ODB, "Failed to parse commit %s - %s", commit_oid, msg);
+
+	return -1;
+}
+
+static git_commit_list_node **alloc_parents(
+	git_revwalk *walk, git_commit_list_node *commit, size_t n_parents)
+{
+	if (n_parents <= PARENTS_PER_COMMIT)
+		return (git_commit_list_node **)((char *)commit + sizeof(git_commit_list_node));
+
+	return (git_commit_list_node **)git_pool_malloc(
+		&walk->commit_pool, (uint32_t)(n_parents * sizeof(git_commit_list_node *)));
+}
+
+
+void git_commit_list_free(git_commit_list **list_p)
+{
+	git_commit_list *list = *list_p;
+
+	if (list == NULL)
+		return;
+
+	while (list) {
+		git_commit_list *temp = list;
+		list = temp->next;
+		git__free(temp);
+	}
+
+	*list_p = NULL;
+}
+
+git_commit_list_node *git_commit_list_pop(git_commit_list **stack)
+{
+	git_commit_list *top = *stack;
+	git_commit_list_node *item = top ? top->item : NULL;
+
+	if (top) {
+		*stack = top->next;
+		git__free(top);
+	}
+	return item;
+}
+
+static int commit_quick_parse(
+	git_revwalk *walk,
+	git_commit_list_node *commit,
+	const uint8_t *buffer,
+	size_t buffer_len)
+{
+	const size_t parent_len = strlen("parent ") + GIT_OID_HEXSZ + 1;
+	const uint8_t *buffer_end = buffer + buffer_len;
+	const uint8_t *parents_start, *committer_start;
+	int i, parents = 0;
+	int commit_time;
+
+	buffer += strlen("tree ") + GIT_OID_HEXSZ + 1;
+
+	parents_start = buffer;
+	while (buffer + parent_len < buffer_end && memcmp(buffer, "parent ", strlen("parent ")) == 0) {
+		parents++;
+		buffer += parent_len;
+	}
+
+	commit->parents = alloc_parents(walk, commit, parents);
+	GITERR_CHECK_ALLOC(commit->parents);
+
+	buffer = parents_start;
+	for (i = 0; i < parents; ++i) {
+		git_oid oid;
+
+		if (git_oid_fromstr(&oid, (const char *)buffer + strlen("parent ")) < 0)
+			return -1;
+
+		commit->parents[i] = git_revwalk__commit_lookup(walk, &oid);
+		if (commit->parents[i] == NULL)
+			return -1;
+
+		buffer += parent_len;
+	}
+
+	commit->out_degree = (unsigned short)parents;
+
+	if ((committer_start = buffer = memchr(buffer, '\n', buffer_end - buffer)) == NULL)
+		return commit_error(commit, "object is corrupted");
+
+	buffer++;
+
+	if ((buffer = memchr(buffer, '\n', buffer_end - buffer)) == NULL)
+		return commit_error(commit, "object is corrupted");
+
+	/* Skip trailing spaces */
+	while (buffer > committer_start && git__isspace(*buffer))
+		buffer--;
+
+	/* Seek for the beginning of the pack of digits */
+	while (buffer > committer_start && git__isdigit(*buffer))
+		buffer--;
+
+	/* Skip potential timezone offset */
+	if ((buffer > committer_start) && (*buffer == '+' || *buffer == '-')) {
+		buffer--;
+
+		while (buffer > committer_start && git__isspace(*buffer))
+			buffer--;
+
+		while (buffer > committer_start && git__isdigit(*buffer))
+			buffer--;
+	}
+
+	if ((buffer == committer_start) || (git__strtol32(&commit_time, (char *)(buffer + 1), NULL, 10) < 0))
+		return commit_error(commit, "cannot parse commit time");
+
+	commit->time = (time_t)commit_time;
+	commit->parsed = 1;
+	return 0;
+}
+
+int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit)
+{
+	git_odb_object *obj;
+	int error;
+
+	if (commit->parsed)
+		return 0;
+
+	if ((error = git_odb_read(&obj, walk->odb, &commit->oid)) < 0)
+		return error;
+
+	if (obj->cached.type != GIT_OBJ_COMMIT) {
+		giterr_set(GITERR_INVALID, "Object is no commit object");
+		error = -1;
+	} else
+		error = commit_quick_parse(
+			walk, commit,
+			(const uint8_t *)git_odb_object_data(obj),
+			git_odb_object_size(obj));
+
+	git_odb_object_free(obj);
+	return error;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/commit_list.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/commit_list.h
new file mode 100755
index 0000000..6b3f473
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/commit_list.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_commit_list_h__
+#define INCLUDE_commit_list_h__
+
+#include "git2/oid.h"
+
+#define PARENT1  (1 << 0)
+#define PARENT2  (1 << 1)
+#define RESULT   (1 << 2)
+#define STALE    (1 << 3)
+
+#define PARENTS_PER_COMMIT	2
+#define COMMIT_ALLOC \
+	(sizeof(git_commit_list_node) + PARENTS_PER_COMMIT * sizeof(git_commit_list_node *))
+
+#define FLAG_BITS 4
+
+typedef struct git_commit_list_node {
+	git_oid oid;
+	uint32_t time;
+	unsigned int seen:1,
+			 uninteresting:1,
+			 topo_delay:1,
+			 parsed:1,
+			 flags : FLAG_BITS;
+
+	unsigned short in_degree;
+	unsigned short out_degree;
+
+	struct git_commit_list_node **parents;
+} git_commit_list_node;
+
+typedef struct git_commit_list {
+	git_commit_list_node *item;
+	struct git_commit_list *next;
+} git_commit_list;
+
+git_commit_list_node *git_commit_list_alloc_node(git_revwalk *walk);
+int git_commit_list_time_cmp(const void *a, const void *b);
+void git_commit_list_free(git_commit_list **list_p);
+git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p);
+git_commit_list *git_commit_list_insert_by_date(git_commit_list_node *item, git_commit_list **list_p);
+int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit);
+git_commit_list_node *git_commit_list_pop(git_commit_list **stack);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/common.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/common.h
new file mode 100755
index 0000000..9056dea
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/common.h
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_common_h__
+#define INCLUDE_common_h__
+
+#include "git2/common.h"
+#include "cc-compat.h"
+
+/** Declare a function as always inlined. */
+#if defined(_MSC_VER)
+# define GIT_INLINE(type) static __inline type
+#else
+# define GIT_INLINE(type) static inline type
+#endif
+
+/** Support for gcc/clang __has_builtin intrinsic */
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef GIT_WIN32
+
+# include <io.h>
+# include <direct.h>
+# include <winsock2.h>
+# include <windows.h>
+# include <ws2tcpip.h>
+# include "win32/msvc-compat.h"
+# include "win32/mingw-compat.h"
+# include "win32/error.h"
+# include "win32/version.h"
+# ifdef GIT_THREADS
+#	include "win32/pthread.h"
+# endif
+
+#else
+
+# include <unistd.h>
+# include <strings.h>
+# ifdef GIT_THREADS
+#	include <pthread.h>
+#	include <sched.h>
+# endif
+#define GIT_STDLIB_CALL
+
+# include <arpa/inet.h>
+
+#endif
+
+#include "git2/types.h"
+#include "git2/errors.h"
+#include "thread-utils.h"
+#include "integer.h"
+
+#include <regex.h>
+
+#define DEFAULT_BUFSIZE 65536
+#define FILEIO_BUFSIZE DEFAULT_BUFSIZE
+#define FILTERIO_BUFSIZE DEFAULT_BUFSIZE
+#define NETIO_BUFSIZE DEFAULT_BUFSIZE
+
+/**
+ * Check a pointer allocation result, returning -1 if it failed.
+ */
+#define GITERR_CHECK_ALLOC(ptr) if (ptr == NULL) { return -1; }
+
+/**
+ * Check a return value and propagate result if non-zero.
+ */
+#define GITERR_CHECK_ERROR(code) \
+	do { int _err = (code); if (_err) return _err; } while (0)
+
+/**
+ * Set the error message for this thread, formatting as needed.
+ */
+void giterr_set(int error_class, const char *string, ...);
+
+/**
+ * Set the error message for a regex failure, using the internal regex
+ * error code lookup and return a libgit error code.
+ */
+int giterr_set_regex(const regex_t *regex, int error_code);
+
+/**
+ * Set error message for user callback if needed.
+ *
+ * If the error code in non-zero and no error message is set, this
+ * sets a generic error message.
+ *
+ * @return This always returns the `error_code` parameter.
+ */
+GIT_INLINE(int) giterr_set_after_callback_function(
+	int error_code, const char *action)
+{
+	if (error_code) {
+		const git_error *e = giterr_last();
+		if (!e || !e->message)
+			giterr_set(e ? e->klass : GITERR_CALLBACK,
+				"%s callback returned %d", action, error_code);
+	}
+	return error_code;
+}
+
+#ifdef GIT_WIN32
+#define giterr_set_after_callback(code) \
+	giterr_set_after_callback_function((code), __FUNCTION__)
+#else
+#define giterr_set_after_callback(code) \
+	giterr_set_after_callback_function((code), __func__)
+#endif
+
+/**
+ * Gets the system error code for this thread.
+ */
+int giterr_system_last(void);
+
+/**
+ * Sets the system error code for this thread.
+ */
+void giterr_system_set(int code);
+
+/**
+ * Structure to preserve libgit2 error state
+ */
+typedef struct {
+	int       error_code;
+	git_error error_msg;
+} git_error_state;
+
+/**
+ * Capture current error state to restore later, returning error code.
+ * If `error_code` is zero, this does nothing and returns zero.
+ */
+int giterr_capture(git_error_state *state, int error_code);
+
+/**
+ * Restore error state to a previous value, returning saved error code.
+ */
+int giterr_restore(git_error_state *state);
+
+/**
+ * Check a versioned structure for validity
+ */
+GIT_INLINE(int) giterr__check_version(const void *structure, unsigned int expected_max, const char *name)
+{
+	unsigned int actual;
+
+	if (!structure)
+		return 0;
+
+	actual = *(const unsigned int*)structure;
+	if (actual > 0 && actual <= expected_max)
+		return 0;
+
+	giterr_set(GITERR_INVALID, "Invalid version %d on %s", actual, name);
+	return -1;
+}
+#define GITERR_CHECK_VERSION(S,V,N) if (giterr__check_version(S,V,N) < 0) return -1
+
+/**
+ * Initialize a structure with a version.
+ */
+GIT_INLINE(void) git__init_structure(void *structure, size_t len, unsigned int version)
+{
+	memset(structure, 0, len);
+	*((int*)structure) = version;
+}
+#define GIT_INIT_STRUCTURE(S,V) git__init_structure(S, sizeof(*S), V)
+
+#define GIT_INIT_STRUCTURE_FROM_TEMPLATE(PTR,VERSION,TYPE,TPL) do { \
+	TYPE _tmpl = TPL; \
+	GITERR_CHECK_VERSION(&(VERSION), _tmpl.version, #TYPE);	\
+	memcpy((PTR), &_tmpl, sizeof(_tmpl)); } while (0)
+
+
+/** Check for additive overflow, setting an error if would occur. */
+#define GIT_ADD_SIZET_OVERFLOW(out, one, two) \
+	(git__add_sizet_overflow(out, one, two) ? (giterr_set_oom(), 1) : 0)
+
+/** Check for additive overflow, setting an error if would occur. */
+#define GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize) \
+	(git__multiply_sizet_overflow(out, nelem, elsize) ? (giterr_set_oom(), 1) : 0)
+
+/** Check for additive overflow, failing if it would occur. */
+#define GITERR_CHECK_ALLOC_ADD(out, one, two) \
+	if (GIT_ADD_SIZET_OVERFLOW(out, one, two)) { return -1; }
+
+#define GITERR_CHECK_ALLOC_ADD3(out, one, two, three) \
+	if (GIT_ADD_SIZET_OVERFLOW(out, one, two) || \
+		GIT_ADD_SIZET_OVERFLOW(out, *(out), three)) { return -1; }
+
+#define GITERR_CHECK_ALLOC_ADD4(out, one, two, three, four) \
+	if (GIT_ADD_SIZET_OVERFLOW(out, one, two) || \
+		GIT_ADD_SIZET_OVERFLOW(out, *(out), three) || \
+		GIT_ADD_SIZET_OVERFLOW(out, *(out), four)) { return -1; }
+
+/** Check for multiplicative overflow, failing if it would occur. */
+#define GITERR_CHECK_ALLOC_MULTIPLY(out, nelem, elsize) \
+	if (GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize)) { return -1; }
+
+/* NOTE: other giterr functions are in the public errors.h header file */
+
+#include "util.h"
+
+#endif /* INCLUDE_common_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/config.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/config.c
new file mode 100755
index 0000000..77cf573
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/config.c
@@ -0,0 +1,1437 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "sysdir.h"
+#include "config.h"
+#include "git2/config.h"
+#include "git2/sys/config.h"
+#include "vector.h"
+#include "buf_text.h"
+#include "config_file.h"
+#if GIT_WIN32
+# include <windows.h>
+#endif
+
+#include <ctype.h>
+
+void git_config_entry_free(git_config_entry *entry)
+{
+	if (!entry)
+		return;
+
+	entry->free(entry);
+}
+
+typedef struct {
+	git_refcount rc;
+
+	git_config_backend *file;
+	git_config_level_t level;
+} file_internal;
+
+static void file_internal_free(file_internal *internal)
+{
+	git_config_backend *file;
+
+	file = internal->file;
+	file->free(file);
+	git__free(internal);
+}
+
+static void config_free(git_config *cfg)
+{
+	size_t i;
+	file_internal *internal;
+
+	for (i = 0; i < cfg->files.length; ++i) {
+		internal = git_vector_get(&cfg->files, i);
+		GIT_REFCOUNT_DEC(internal, file_internal_free);
+	}
+
+	git_vector_free(&cfg->files);
+
+	git__memzero(cfg, sizeof(*cfg));
+	git__free(cfg);
+}
+
+void git_config_free(git_config *cfg)
+{
+	if (cfg == NULL)
+		return;
+
+	GIT_REFCOUNT_DEC(cfg, config_free);
+}
+
+static int config_backend_cmp(const void *a, const void *b)
+{
+	const file_internal *bk_a = (const file_internal *)(a);
+	const file_internal *bk_b = (const file_internal *)(b);
+
+	return bk_b->level - bk_a->level;
+}
+
+int git_config_new(git_config **out)
+{
+	git_config *cfg;
+
+	cfg = git__malloc(sizeof(git_config));
+	GITERR_CHECK_ALLOC(cfg);
+
+	memset(cfg, 0x0, sizeof(git_config));
+
+	if (git_vector_init(&cfg->files, 3, config_backend_cmp) < 0) {
+		git__free(cfg);
+		return -1;
+	}
+
+	*out = cfg;
+	GIT_REFCOUNT_INC(cfg);
+	return 0;
+}
+
+int git_config_add_file_ondisk(
+	git_config *cfg,
+	const char *path,
+	git_config_level_t level,
+	int force)
+{
+	git_config_backend *file = NULL;
+	struct stat st;
+	int res;
+
+	assert(cfg && path);
+
+	res = p_stat(path, &st);
+	if (res < 0 && errno != ENOENT) {
+		giterr_set(GITERR_CONFIG, "Error stat'ing config file '%s'", path);
+		return -1;
+	}
+
+	if (git_config_file__ondisk(&file, path) < 0)
+		return -1;
+
+	if ((res = git_config_add_backend(cfg, file, level, force)) < 0) {
+		/*
+		 * free manually; the file is not owned by the config
+		 * instance yet and will not be freed on cleanup
+		 */
+		file->free(file);
+		return res;
+	}
+
+	return 0;
+}
+
+int git_config_open_ondisk(git_config **out, const char *path)
+{
+	int error;
+	git_config *config;
+
+	*out = NULL;
+
+	if (git_config_new(&config) < 0)
+		return -1;
+
+	if ((error = git_config_add_file_ondisk(config, path, GIT_CONFIG_LEVEL_LOCAL, 0)) < 0)
+		git_config_free(config);
+	else
+		*out = config;
+
+	return error;
+}
+
+int git_config_snapshot(git_config **out, git_config *in)
+{
+	int error = 0;
+	size_t i;
+	file_internal *internal;
+	git_config *config;
+
+	*out = NULL;
+
+	if (git_config_new(&config) < 0)
+		return -1;
+
+	git_vector_foreach(&in->files, i, internal) {
+		git_config_backend *b;
+
+		if ((error = internal->file->snapshot(&b, internal->file)) < 0)
+			break;
+
+		if ((error = git_config_add_backend(config, b, internal->level, 0)) < 0) {
+			b->free(b);
+			break;
+		}
+	}
+
+	if (error < 0)
+		git_config_free(config);
+	else
+		*out = config;
+
+	return error;
+}
+
+static int find_internal_file_by_level(
+	file_internal **internal_out,
+	const git_config *cfg,
+	git_config_level_t level)
+{
+	int pos = -1;
+	file_internal *internal;
+	size_t i;
+
+	/* when passing GIT_CONFIG_HIGHEST_LEVEL, the idea is to get the config file
+	 * which has the highest level. As config files are stored in a vector
+	 * sorted by decreasing order of level, getting the file at position 0
+	 * will do the job.
+	 */
+	if (level == GIT_CONFIG_HIGHEST_LEVEL) {
+		pos = 0;
+	} else {
+		git_vector_foreach(&cfg->files, i, internal) {
+			if (internal->level == level)
+				pos = (int)i;
+		}
+	}
+
+	if (pos == -1) {
+		giterr_set(GITERR_CONFIG,
+			"No config file exists for the given level '%i'", (int)level);
+		return GIT_ENOTFOUND;
+	}
+
+	*internal_out = git_vector_get(&cfg->files, pos);
+
+	return 0;
+}
+
+static int duplicate_level(void **old_raw, void *new_raw)
+{
+	file_internal **old = (file_internal **)old_raw;
+
+	GIT_UNUSED(new_raw);
+
+	giterr_set(GITERR_CONFIG, "A file with the same level (%i) has already been added to the config", (int)(*old)->level);
+	return GIT_EEXISTS;
+}
+
+static void try_remove_existing_file_internal(
+	git_config *cfg,
+	git_config_level_t level)
+{
+	int pos = -1;
+	file_internal *internal;
+	size_t i;
+
+	git_vector_foreach(&cfg->files, i, internal) {
+		if (internal->level == level)
+			pos = (int)i;
+	}
+
+	if (pos == -1)
+		return;
+
+	internal = git_vector_get(&cfg->files, pos);
+
+	if (git_vector_remove(&cfg->files, pos) < 0)
+		return;
+
+	GIT_REFCOUNT_DEC(internal, file_internal_free);
+}
+
+static int git_config__add_internal(
+	git_config *cfg,
+	file_internal *internal,
+	git_config_level_t level,
+	int force)
+{
+	int result;
+
+	/* delete existing config file for level if it exists */
+	if (force)
+		try_remove_existing_file_internal(cfg, level);
+
+	if ((result = git_vector_insert_sorted(&cfg->files,
+			internal, &duplicate_level)) < 0)
+		return result;
+
+	git_vector_sort(&cfg->files);
+	internal->file->cfg = cfg;
+
+	GIT_REFCOUNT_INC(internal);
+
+	return 0;
+}
+
+int git_config_open_global(git_config **cfg_out, git_config *cfg)
+{
+	if (!git_config_open_level(cfg_out, cfg, GIT_CONFIG_LEVEL_XDG))
+		return 0;
+
+	return git_config_open_level(cfg_out, cfg, GIT_CONFIG_LEVEL_GLOBAL);
+}
+
+int git_config_open_level(
+	git_config **cfg_out,
+	const git_config *cfg_parent,
+	git_config_level_t level)
+{
+	git_config *cfg;
+	file_internal *internal;
+	int res;
+
+	if ((res = find_internal_file_by_level(&internal, cfg_parent, level)) < 0)
+		return res;
+
+	if ((res = git_config_new(&cfg)) < 0)
+		return res;
+
+	if ((res = git_config__add_internal(cfg, internal, level, true)) < 0) {
+		git_config_free(cfg);
+		return res;
+	}
+
+	*cfg_out = cfg;
+
+	return 0;
+}
+
+int git_config_add_backend(
+	git_config *cfg,
+	git_config_backend *file,
+	git_config_level_t level,
+	int force)
+{
+	file_internal *internal;
+	int result;
+
+	assert(cfg && file);
+
+	GITERR_CHECK_VERSION(file, GIT_CONFIG_BACKEND_VERSION, "git_config_backend");
+
+	if ((result = file->open(file, level)) < 0)
+		return result;
+
+	internal = git__malloc(sizeof(file_internal));
+	GITERR_CHECK_ALLOC(internal);
+
+	memset(internal, 0x0, sizeof(file_internal));
+
+	internal->file = file;
+	internal->level = level;
+
+	if ((result = git_config__add_internal(cfg, internal, level, force)) < 0) {
+		git__free(internal);
+		return result;
+	}
+
+	return 0;
+}
+
+/*
+ * Loop over all the variables
+ */
+
+typedef struct {
+	git_config_iterator parent;
+	git_config_iterator *current;
+	const git_config *cfg;
+	regex_t regex;
+	size_t i;
+} all_iter;
+
+static int find_next_backend(size_t *out, const git_config *cfg, size_t i)
+{
+	file_internal *internal;
+
+	for (; i > 0; --i) {
+		internal = git_vector_get(&cfg->files, i - 1);
+		if (!internal || !internal->file)
+			continue;
+
+		*out = i;
+		return 0;
+	}
+
+	return -1;
+}
+
+static int all_iter_next(git_config_entry **entry, git_config_iterator *_iter)
+{
+	all_iter *iter = (all_iter *) _iter;
+	file_internal *internal;
+	git_config_backend *backend;
+	size_t i;
+	int error = 0;
+
+	if (iter->current != NULL &&
+	    (error = iter->current->next(entry, iter->current)) == 0) {
+		return 0;
+	}
+
+	if (error < 0 && error != GIT_ITEROVER)
+		return error;
+
+	do {
+		if (find_next_backend(&i, iter->cfg, iter->i) < 0)
+			return GIT_ITEROVER;
+
+		internal = git_vector_get(&iter->cfg->files, i - 1);
+		backend = internal->file;
+		iter->i = i - 1;
+
+		if (iter->current)
+			iter->current->free(iter->current);
+
+		iter->current = NULL;
+		error = backend->iterator(&iter->current, backend);
+		if (error == GIT_ENOTFOUND)
+			continue;
+
+		if (error < 0)
+			return error;
+
+		error = iter->current->next(entry, iter->current);
+		/* If this backend is empty, then keep going */
+		if (error == GIT_ITEROVER)
+			continue;
+
+		return error;
+
+	} while(1);
+
+	return GIT_ITEROVER;
+}
+
+static int all_iter_glob_next(git_config_entry **entry, git_config_iterator *_iter)
+{
+	int error;
+	all_iter *iter = (all_iter *) _iter;
+
+	/*
+	 * We use the "normal" function to grab the next one across
+	 * backends and then apply the regex
+	 */
+	while ((error = all_iter_next(entry, _iter)) == 0) {
+		/* skip non-matching keys if regexp was provided */
+		if (regexec(&iter->regex, (*entry)->name, 0, NULL, 0) != 0)
+			continue;
+
+		/* and simply return if we like the entry's name */
+		return 0;
+	}
+
+	return error;
+}
+
+static void all_iter_free(git_config_iterator *_iter)
+{
+	all_iter *iter = (all_iter *) _iter;
+
+	if (iter->current)
+		iter->current->free(iter->current);
+
+	git__free(iter);
+}
+
+static void all_iter_glob_free(git_config_iterator *_iter)
+{
+	all_iter *iter = (all_iter *) _iter;
+
+	regfree(&iter->regex);
+	all_iter_free(_iter);
+}
+
+int git_config_iterator_new(git_config_iterator **out, const git_config *cfg)
+{
+	all_iter *iter;
+
+	iter = git__calloc(1, sizeof(all_iter));
+	GITERR_CHECK_ALLOC(iter);
+
+	iter->parent.free = all_iter_free;
+	iter->parent.next = all_iter_next;
+
+	iter->i = cfg->files.length;
+	iter->cfg = cfg;
+
+	*out = (git_config_iterator *) iter;
+
+	return 0;
+}
+
+int git_config_iterator_glob_new(git_config_iterator **out, const git_config *cfg, const char *regexp)
+{
+	all_iter *iter;
+	int result;
+
+	if (regexp == NULL)
+		return git_config_iterator_new(out, cfg);
+
+	iter = git__calloc(1, sizeof(all_iter));
+	GITERR_CHECK_ALLOC(iter);
+
+	if ((result = regcomp(&iter->regex, regexp, REG_EXTENDED)) != 0) {
+		giterr_set_regex(&iter->regex, result);
+		git__free(iter);
+		return -1;
+	}
+
+	iter->parent.next = all_iter_glob_next;
+	iter->parent.free = all_iter_glob_free;
+	iter->i = cfg->files.length;
+	iter->cfg = cfg;
+
+	*out = (git_config_iterator *) iter;
+
+	return 0;
+}
+
+int git_config_foreach(
+	const git_config *cfg, git_config_foreach_cb cb, void *payload)
+{
+	return git_config_foreach_match(cfg, NULL, cb, payload);
+}
+
+int git_config_backend_foreach_match(
+	git_config_backend *backend,
+	const char *regexp,
+	git_config_foreach_cb cb,
+	void *payload)
+{
+	git_config_entry *entry;
+	git_config_iterator* iter;
+	regex_t regex;
+	int error = 0;
+
+	if (regexp != NULL) {
+		if ((error = regcomp(&regex, regexp, REG_EXTENDED)) != 0) {
+			giterr_set_regex(&regex, error);
+			regfree(&regex);
+			return -1;
+		}
+	}
+
+	if ((error = backend->iterator(&iter, backend)) < 0) {
+		iter = NULL;
+		return -1;
+	}
+
+	while (!(iter->next(&entry, iter) < 0)) {
+		/* skip non-matching keys if regexp was provided */
+		if (regexp && regexec(&regex, entry->name, 0, NULL, 0) != 0)
+			continue;
+
+		/* abort iterator on non-zero return value */
+		if ((error = cb(entry, payload)) != 0) {
+			giterr_set_after_callback(error);
+			break;
+		}
+	}
+
+	if (regexp != NULL)
+		regfree(&regex);
+
+	iter->free(iter);
+
+	return error;
+}
+
+int git_config_foreach_match(
+	const git_config *cfg,
+	const char *regexp,
+	git_config_foreach_cb cb,
+	void *payload)
+{
+	int error;
+	git_config_iterator *iter;
+	git_config_entry *entry;
+
+	if ((error = git_config_iterator_glob_new(&iter, cfg, regexp)) < 0)
+		return error;
+
+	while (!(error = git_config_next(&entry, iter))) {
+		if ((error = cb(entry, payload)) != 0) {
+			giterr_set_after_callback(error);
+			break;
+		}
+	}
+
+	git_config_iterator_free(iter);
+
+	if (error == GIT_ITEROVER)
+		error = 0;
+
+	return error;
+}
+
+/**************
+ * Setters
+ **************/
+
+static int config_error_nofiles(const char *name)
+{
+	giterr_set(GITERR_CONFIG,
+		"Cannot set value for '%s' when no config files exist", name);
+	return GIT_ENOTFOUND;
+}
+
+int git_config_delete_entry(git_config *cfg, const char *name)
+{
+	git_config_backend *file;
+	file_internal *internal;
+
+	internal = git_vector_get(&cfg->files, 0);
+	if (!internal || !internal->file)
+		return config_error_nofiles(name);
+	file = internal->file;
+
+	return file->del(file, name);
+}
+
+int git_config_set_int64(git_config *cfg, const char *name, int64_t value)
+{
+	char str_value[32]; /* All numbers should fit in here */
+	p_snprintf(str_value, sizeof(str_value), "%" PRId64, value);
+	return git_config_set_string(cfg, name, str_value);
+}
+
+int git_config_set_int32(git_config *cfg, const char *name, int32_t value)
+{
+	return git_config_set_int64(cfg, name, (int64_t)value);
+}
+
+int git_config_set_bool(git_config *cfg, const char *name, int value)
+{
+	return git_config_set_string(cfg, name, value ? "true" : "false");
+}
+
+int git_config_set_string(git_config *cfg, const char *name, const char *value)
+{
+	int error;
+	git_config_backend *file;
+	file_internal *internal;
+
+	if (!value) {
+		giterr_set(GITERR_CONFIG, "The value to set cannot be NULL");
+		return -1;
+	}
+
+	internal = git_vector_get(&cfg->files, 0);
+	if (!internal || !internal->file)
+		return config_error_nofiles(name);
+	file = internal->file;
+
+	error = file->set(file, name, value);
+
+	if (!error && GIT_REFCOUNT_OWNER(cfg) != NULL)
+		git_repository__cvar_cache_clear(GIT_REFCOUNT_OWNER(cfg));
+
+	return error;
+}
+
+int git_config__update_entry(
+	git_config *config,
+	const char *key,
+	const char *value,
+	bool overwrite_existing,
+	bool only_if_existing)
+{
+	int error = 0;
+	git_config_entry *ce = NULL;
+
+	if ((error = git_config__lookup_entry(&ce, config, key, false)) < 0)
+		return error;
+
+	if (!ce && only_if_existing) /* entry doesn't exist */
+		return 0;
+	if (ce && !overwrite_existing) /* entry would be overwritten */
+		return 0;
+	if (value && ce && ce->value && !strcmp(ce->value, value)) /* no change */
+		return 0;
+	if (!value && (!ce || !ce->value)) /* asked to delete absent entry */
+		return 0;
+
+	if (!value)
+		error = git_config_delete_entry(config, key);
+	else
+		error = git_config_set_string(config, key, value);
+
+	git_config_entry_free(ce);
+	return error;
+}
+
+/***********
+ * Getters
+ ***********/
+
+static int config_error_notfound(const char *name)
+{
+	giterr_set(GITERR_CONFIG, "Config value '%s' was not found", name);
+	return GIT_ENOTFOUND;
+}
+
+enum {
+	GET_ALL_ERRORS = 0,
+	GET_NO_MISSING = 1,
+	GET_NO_ERRORS  = 2
+};
+
+static int get_entry(
+	git_config_entry **out,
+	const git_config *cfg,
+	const char *name,
+	bool normalize_name,
+	int want_errors)
+{
+	int res = GIT_ENOTFOUND;
+	const char *key = name;
+	char *normalized = NULL;
+	size_t i;
+	file_internal *internal;
+
+	*out = NULL;
+
+	if (normalize_name) {
+		if ((res = git_config__normalize_name(name, &normalized)) < 0)
+			goto cleanup;
+		key = normalized;
+	}
+
+	res = GIT_ENOTFOUND;
+	git_vector_foreach(&cfg->files, i, internal) {
+		if (!internal || !internal->file)
+			continue;
+
+		res = internal->file->get(internal->file, key, out);
+		if (res != GIT_ENOTFOUND)
+			break;
+	}
+
+	git__free(normalized);
+
+cleanup:
+	if (res == GIT_ENOTFOUND)
+		res = (want_errors > GET_ALL_ERRORS) ? 0 : config_error_notfound(name);
+	else if (res && (want_errors == GET_NO_ERRORS)) {
+		giterr_clear();
+		res = 0;
+	}
+
+	return res;
+}
+
+int git_config_get_entry(
+	git_config_entry **out, const git_config *cfg, const char *name)
+{
+	return get_entry(out, cfg, name, true, GET_ALL_ERRORS);
+}
+
+int git_config__lookup_entry(
+	git_config_entry **out,
+	const git_config *cfg,
+	const char *key,
+	bool no_errors)
+{
+	return get_entry(
+		out, cfg, key, false, no_errors ? GET_NO_ERRORS : GET_NO_MISSING);
+}
+
+int git_config_get_mapped(
+	int *out,
+	const git_config *cfg,
+	const char *name,
+	const git_cvar_map *maps,
+	size_t map_n)
+{
+	git_config_entry *entry;
+	int ret;
+
+	if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
+		return ret;
+
+	ret = git_config_lookup_map_value(out, maps, map_n, entry->value);
+	git_config_entry_free(entry);
+
+	return ret;
+}
+
+int git_config_get_int64(int64_t *out, const git_config *cfg, const char *name)
+{
+	git_config_entry *entry;
+	int ret;
+
+	if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
+		return ret;
+
+	ret = git_config_parse_int64(out, entry->value);
+	git_config_entry_free(entry);
+
+	return ret;
+}
+
+int git_config_get_int32(int32_t *out, const git_config *cfg, const char *name)
+{
+	git_config_entry *entry;
+	int ret;
+
+	if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
+		return ret;
+
+	ret = git_config_parse_int32(out, entry->value);
+	git_config_entry_free(entry);
+
+	return ret;
+}
+
+int git_config_get_bool(int *out, const git_config *cfg, const char *name)
+{
+	git_config_entry *entry;
+	int ret;
+
+	if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
+		return ret;
+
+	ret = git_config_parse_bool(out, entry->value);
+	git_config_entry_free(entry);
+
+	return ret;
+}
+
+static int is_readonly(const git_config *cfg)
+{
+	size_t i;
+	file_internal *internal;
+
+	git_vector_foreach(&cfg->files, i, internal) {
+		if (!internal || !internal->file)
+			continue;
+
+		if (!internal->file->readonly)
+			return 0;
+	}
+
+	return 1;
+}
+
+int git_config_get_path(git_buf *out, const git_config *cfg, const char *name)
+{
+	git_config_entry *entry;
+	int error;
+
+	if ((error = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
+		return error;
+
+	 error = git_config_parse_path(out, entry->value);
+	 git_config_entry_free(entry);
+
+	 return error;
+}
+
+int git_config_get_string(
+	const char **out, const git_config *cfg, const char *name)
+{
+	git_config_entry *entry;
+	int ret;
+
+	if (!is_readonly(cfg)) {
+		giterr_set(GITERR_CONFIG, "get_string called on a live config object");
+		return -1;
+	}
+
+	ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS);
+	*out = !ret ? (entry->value ? entry->value : "") : NULL;
+
+	git_config_entry_free(entry);
+
+	return ret;
+}
+
+int git_config_get_string_buf(
+	git_buf *out, const git_config *cfg, const char *name)
+{
+	git_config_entry *entry;
+	int ret;
+	const char *str;
+
+	git_buf_sanitize(out);
+
+	ret  = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS);
+	str = !ret ? (entry->value ? entry->value : "") : NULL;
+
+	if (str)
+		ret = git_buf_puts(out, str);
+
+	git_config_entry_free(entry);
+
+	return ret;
+}
+
+char *git_config__get_string_force(
+	const git_config *cfg, const char *key, const char *fallback_value)
+{
+	git_config_entry *entry;
+	char *ret;
+
+	get_entry(&entry, cfg, key, false, GET_NO_ERRORS);
+	ret = (entry && entry->value) ? git__strdup(entry->value) : fallback_value ? git__strdup(fallback_value) : NULL;
+	git_config_entry_free(entry);
+
+	return ret;
+}
+
+int git_config__get_bool_force(
+	const git_config *cfg, const char *key, int fallback_value)
+{
+	int val = fallback_value;
+	git_config_entry *entry;
+
+	get_entry(&entry, cfg, key, false, GET_NO_ERRORS);
+
+	if (entry && git_config_parse_bool(&val, entry->value) < 0)
+		giterr_clear();
+
+	git_config_entry_free(entry);
+	return val;
+}
+
+int git_config__get_int_force(
+	const git_config *cfg, const char *key, int fallback_value)
+{
+	int32_t val = (int32_t)fallback_value;
+	git_config_entry *entry;
+
+	get_entry(&entry, cfg, key, false, GET_NO_ERRORS);
+
+	if (entry && git_config_parse_int32(&val, entry->value) < 0)
+		giterr_clear();
+
+	git_config_entry_free(entry);
+	return (int)val;
+}
+
+int git_config_get_multivar_foreach(
+	const git_config *cfg, const char *name, const char *regexp,
+	git_config_foreach_cb cb, void *payload)
+{
+	int err, found;
+	git_config_iterator *iter;
+	git_config_entry *entry;
+
+	if ((err = git_config_multivar_iterator_new(&iter, cfg, name, regexp)) < 0)
+		return err;
+
+	found = 0;
+	while ((err = iter->next(&entry, iter)) == 0) {
+		found = 1;
+
+		if ((err = cb(entry, payload)) != 0) {
+			giterr_set_after_callback(err);
+			break;
+		}
+	}
+
+	iter->free(iter);
+	if (err == GIT_ITEROVER)
+		err = 0;
+
+	if (found == 0 && err == 0)
+		err = config_error_notfound(name);
+
+	return err;
+}
+
+typedef struct {
+	git_config_iterator parent;
+	git_config_iterator *iter;
+	char *name;
+	regex_t regex;
+	int have_regex;
+} multivar_iter;
+
+static int multivar_iter_next(git_config_entry **entry, git_config_iterator *_iter)
+{
+	multivar_iter *iter = (multivar_iter *) _iter;
+	int error = 0;
+
+	while ((error = iter->iter->next(entry, iter->iter)) == 0) {
+		if (git__strcmp(iter->name, (*entry)->name))
+			continue;
+
+		if (!iter->have_regex)
+			return 0;
+
+		if (regexec(&iter->regex, (*entry)->value, 0, NULL, 0) == 0)
+			return 0;
+	}
+
+	return error;
+}
+
+void multivar_iter_free(git_config_iterator *_iter)
+{
+	multivar_iter *iter = (multivar_iter *) _iter;
+
+	iter->iter->free(iter->iter);
+
+	git__free(iter->name);
+	if (iter->have_regex)
+		regfree(&iter->regex);
+	git__free(iter);
+}
+
+int git_config_multivar_iterator_new(git_config_iterator **out, const git_config *cfg, const char *name, const char *regexp)
+{
+	multivar_iter *iter = NULL;
+	git_config_iterator *inner = NULL;
+	int error;
+
+	if ((error = git_config_iterator_new(&inner, cfg)) < 0)
+		return error;
+
+	iter = git__calloc(1, sizeof(multivar_iter));
+	GITERR_CHECK_ALLOC(iter);
+
+	if ((error = git_config__normalize_name(name, &iter->name)) < 0)
+		goto on_error;
+
+	if (regexp != NULL) {
+		error = regcomp(&iter->regex, regexp, REG_EXTENDED);
+		if (error != 0) {
+			giterr_set_regex(&iter->regex, error);
+			error = -1;
+			regfree(&iter->regex);
+			goto on_error;
+		}
+
+		iter->have_regex = 1;
+	}
+
+	iter->iter = inner;
+	iter->parent.free = multivar_iter_free;
+	iter->parent.next = multivar_iter_next;
+
+	*out = (git_config_iterator *) iter;
+
+	return 0;
+
+on_error:
+
+	inner->free(inner);
+	git__free(iter);
+	return error;
+}
+
+int git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value)
+{
+	git_config_backend *file;
+	file_internal *internal;
+
+	internal = git_vector_get(&cfg->files, 0);
+	if (!internal || !internal->file)
+		return config_error_nofiles(name);
+	file = internal->file;
+
+	return file->set_multivar(file, name, regexp, value);
+}
+
+int git_config_delete_multivar(git_config *cfg, const char *name, const char *regexp)
+{
+	git_config_backend *file;
+	file_internal *internal;
+
+	internal = git_vector_get(&cfg->files, 0);
+	if (!internal || !internal->file)
+		return config_error_nofiles(name);
+	file = internal->file;
+
+	return file->del_multivar(file, name, regexp);
+}
+
+int git_config_next(git_config_entry **entry, git_config_iterator *iter)
+{
+	return iter->next(entry, iter);
+}
+
+void git_config_iterator_free(git_config_iterator *iter)
+{
+	if (iter == NULL)
+		return;
+
+	iter->free(iter);
+}
+
+int git_config_find_global(git_buf *path)
+{
+	git_buf_sanitize(path);
+	return git_sysdir_find_global_file(path, GIT_CONFIG_FILENAME_GLOBAL);
+}
+
+int git_config_find_xdg(git_buf *path)
+{
+	git_buf_sanitize(path);
+	return git_sysdir_find_xdg_file(path, GIT_CONFIG_FILENAME_XDG);
+}
+
+int git_config_find_system(git_buf *path)
+{
+	git_buf_sanitize(path);
+	return git_sysdir_find_system_file(path, GIT_CONFIG_FILENAME_SYSTEM);
+}
+
+int git_config__global_location(git_buf *buf)
+{
+	const git_buf *paths;
+	const char *sep, *start;
+
+	if (git_sysdir_get(&paths, GIT_SYSDIR_GLOBAL) < 0)
+		return -1;
+
+	/* no paths, so give up */
+	if (!paths || !git_buf_len(paths))
+		return -1;
+
+	/* find unescaped separator or end of string */
+	for (sep = start = git_buf_cstr(paths); *sep; ++sep) {
+		if (*sep == GIT_PATH_LIST_SEPARATOR &&
+			(sep <= start || sep[-1] != '\\'))
+			break;
+	}
+
+	if (git_buf_set(buf, start, (size_t)(sep - start)) < 0)
+		return -1;
+
+	return git_buf_joinpath(buf, buf->ptr, GIT_CONFIG_FILENAME_GLOBAL);
+}
+
+int git_config_open_default(git_config **out)
+{
+	int error;
+	git_config *cfg = NULL;
+	git_buf buf = GIT_BUF_INIT;
+
+	if ((error = git_config_new(&cfg)) < 0)
+		return error;
+
+	if (!git_config_find_global(&buf) || !git_config__global_location(&buf)) {
+		error = git_config_add_file_ondisk(cfg, buf.ptr,
+			GIT_CONFIG_LEVEL_GLOBAL, 0);
+	}
+
+	if (!error && !git_config_find_xdg(&buf))
+		error = git_config_add_file_ondisk(cfg, buf.ptr,
+			GIT_CONFIG_LEVEL_XDG, 0);
+
+	if (!error && !git_config_find_system(&buf))
+		error = git_config_add_file_ondisk(cfg, buf.ptr,
+			GIT_CONFIG_LEVEL_SYSTEM, 0);
+
+	git_buf_free(&buf);
+
+	if (error) {
+		git_config_free(cfg);
+		cfg = NULL;
+	}
+
+	*out = cfg;
+
+	return error;
+}
+
+/***********
+ * Parsers
+ ***********/
+
+int git_config_lookup_map_value(
+	int *out,
+	const git_cvar_map *maps,
+	size_t map_n,
+	const char *value)
+{
+	size_t i;
+
+	if (!value)
+		goto fail_parse;
+
+	for (i = 0; i < map_n; ++i) {
+		const git_cvar_map *m = maps + i;
+
+		switch (m->cvar_type) {
+		case GIT_CVAR_FALSE:
+		case GIT_CVAR_TRUE: {
+			int bool_val;
+
+			if (git__parse_bool(&bool_val, value) == 0 &&
+				bool_val == (int)m->cvar_type) {
+				*out = m->map_value;
+				return 0;
+			}
+			break;
+		}
+
+		case GIT_CVAR_INT32:
+			if (git_config_parse_int32(out, value) == 0)
+				return 0;
+			break;
+
+		case GIT_CVAR_STRING:
+			if (strcasecmp(value, m->str_match) == 0) {
+				*out = m->map_value;
+				return 0;
+			}
+			break;
+		}
+	}
+
+fail_parse:
+	giterr_set(GITERR_CONFIG, "Failed to map '%s'", value);
+	return -1;
+}
+
+int git_config_lookup_map_enum(git_cvar_t *type_out, const char **str_out,
+			       const git_cvar_map *maps, size_t map_n, int enum_val)
+{
+	size_t i;
+
+	for (i = 0; i < map_n; i++) {
+		const git_cvar_map *m = &maps[i];
+
+		if (m->map_value != enum_val)
+			continue;
+
+		*type_out = m->cvar_type;
+		*str_out = m->str_match;
+		return 0;
+	}
+
+	giterr_set(GITERR_CONFIG, "invalid enum value");
+	return GIT_ENOTFOUND;
+}
+
+int git_config_parse_bool(int *out, const char *value)
+{
+	if (git__parse_bool(out, value) == 0)
+		return 0;
+
+	if (git_config_parse_int32(out, value) == 0) {
+		*out = !!(*out);
+		return 0;
+	}
+
+	giterr_set(GITERR_CONFIG, "Failed to parse '%s' as a boolean value", value);
+	return -1;
+}
+
+int git_config_parse_int64(int64_t *out, const char *value)
+{
+	const char *num_end;
+	int64_t num;
+
+	if (!value || git__strtol64(&num, value, &num_end, 0) < 0)
+		goto fail_parse;
+
+	switch (*num_end) {
+	case 'g':
+	case 'G':
+		num *= 1024;
+		/* fallthrough */
+
+	case 'm':
+	case 'M':
+		num *= 1024;
+		/* fallthrough */
+
+	case 'k':
+	case 'K':
+		num *= 1024;
+
+		/* check that that there are no more characters after the
+		 * given modifier suffix */
+		if (num_end[1] != '\0')
+			return -1;
+
+		/* fallthrough */
+
+	case '\0':
+		*out = num;
+		return 0;
+
+	default:
+		goto fail_parse;
+	}
+
+fail_parse:
+	giterr_set(GITERR_CONFIG, "Failed to parse '%s' as an integer", value ? value : "(null)");
+	return -1;
+}
+
+int git_config_parse_int32(int32_t *out, const char *value)
+{
+	int64_t tmp;
+	int32_t truncate;
+
+	if (git_config_parse_int64(&tmp, value) < 0)
+		goto fail_parse;
+
+	truncate = tmp & 0xFFFFFFFF;
+	if (truncate != tmp)
+		goto fail_parse;
+
+	*out = truncate;
+	return 0;
+
+fail_parse:
+	giterr_set(GITERR_CONFIG, "Failed to parse '%s' as a 32-bit integer", value ? value : "(null)");
+	return -1;
+}
+
+int git_config_parse_path(git_buf *out, const char *value)
+{
+	int error = 0;
+	const git_buf *home;
+
+	assert(out && value);
+
+	git_buf_sanitize(out);
+
+	if (value[0] == '~') {
+		if (value[1] != '\0' && value[1] != '/') {
+			giterr_set(GITERR_CONFIG, "retrieving a homedir by name is not supported");
+			return -1;
+		}
+
+		if ((error = git_sysdir_get(&home, GIT_SYSDIR_GLOBAL)) < 0)
+			return error;
+
+		git_buf_sets(out, home->ptr);
+		git_buf_puts(out, value + 1);
+
+		if (git_buf_oom(out))
+			return -1;
+
+		return 0;
+	}
+
+	return git_buf_sets(out, value);
+}
+
+/* Take something the user gave us and make it nice for our hash function */
+int git_config__normalize_name(const char *in, char **out)
+{
+	char *name, *fdot, *ldot;
+
+	assert(in && out);
+
+	name = git__strdup(in);
+	GITERR_CHECK_ALLOC(name);
+
+	fdot = strchr(name, '.');
+	ldot = strrchr(name, '.');
+
+	if (fdot == NULL || fdot == name || ldot == NULL || !ldot[1])
+		goto invalid;
+
+	/* Validate and downcase up to first dot and after last dot */
+	if (git_config_file_normalize_section(name, fdot) < 0 ||
+		git_config_file_normalize_section(ldot + 1, NULL) < 0)
+		goto invalid;
+
+	/* If there is a middle range, make sure it doesn't have newlines */
+	while (fdot < ldot)
+		if (*fdot++ == '\n')
+			goto invalid;
+
+	*out = name;
+	return 0;
+
+invalid:
+	git__free(name);
+	giterr_set(GITERR_CONFIG, "Invalid config item name '%s'", in);
+	return GIT_EINVALIDSPEC;
+}
+
+struct rename_data {
+	git_config *config;
+	git_buf *name;
+	size_t old_len;
+};
+
+static int rename_config_entries_cb(
+	const git_config_entry *entry,
+	void *payload)
+{
+	int error = 0;
+	struct rename_data *data = (struct rename_data *)payload;
+	size_t base_len = git_buf_len(data->name);
+
+	if (base_len > 0 &&
+		!(error = git_buf_puts(data->name, entry->name + data->old_len)))
+	{
+		error = git_config_set_string(
+			data->config, git_buf_cstr(data->name), entry->value);
+
+		git_buf_truncate(data->name, base_len);
+	}
+
+	if (!error)
+		error = git_config_delete_entry(data->config, entry->name);
+
+	return error;
+}
+
+int git_config_rename_section(
+	git_repository *repo,
+	const char *old_section_name,
+	const char *new_section_name)
+{
+	git_config *config;
+	git_buf pattern = GIT_BUF_INIT, replace = GIT_BUF_INIT;
+	int error = 0;
+	struct rename_data data;
+
+	git_buf_text_puts_escape_regex(&pattern, old_section_name);
+
+	if ((error = git_buf_puts(&pattern, "\\..+")) < 0)
+		goto cleanup;
+
+	if ((error = git_repository_config__weakptr(&config, repo)) < 0)
+		goto cleanup;
+
+	data.config  = config;
+	data.name    = &replace;
+	data.old_len = strlen(old_section_name) + 1;
+
+	if ((error = git_buf_join(&replace, '.', new_section_name, "")) < 0)
+		goto cleanup;
+
+	if (new_section_name != NULL &&
+		(error = git_config_file_normalize_section(
+			replace.ptr, strchr(replace.ptr, '.'))) < 0)
+	{
+		giterr_set(
+			GITERR_CONFIG, "Invalid config section '%s'", new_section_name);
+		goto cleanup;
+	}
+
+	error = git_config_foreach_match(
+		config, git_buf_cstr(&pattern), rename_config_entries_cb, &data);
+
+cleanup:
+	git_buf_free(&pattern);
+	git_buf_free(&replace);
+
+	return error;
+}
+
+int git_config_init_backend(git_config_backend *backend, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		backend, version, git_config_backend, GIT_CONFIG_BACKEND_INIT);
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/config.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/config.h
new file mode 100755
index 0000000..f257cc9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/config.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_config_h__
+#define INCLUDE_config_h__
+
+#include "git2.h"
+#include "git2/config.h"
+#include "vector.h"
+#include "repository.h"
+
+#define GIT_CONFIG_FILENAME_SYSTEM "gitconfig"
+#define GIT_CONFIG_FILENAME_GLOBAL ".gitconfig"
+#define GIT_CONFIG_FILENAME_XDG    "config"
+
+#define GIT_CONFIG_FILENAME_INREPO "config"
+#define GIT_CONFIG_FILE_MODE 0666
+
+struct git_config {
+	git_refcount rc;
+	git_vector files;
+};
+
+extern int git_config__global_location(git_buf *buf);
+
+extern int git_config_rename_section(
+	git_repository *repo,
+	const char *old_section_name,	/* eg "branch.dummy" */
+	const char *new_section_name);	/* NULL to drop the old section */
+
+/**
+ * Create a configuration file backend for ondisk files
+ *
+ * These are the normal `.gitconfig` files that Core Git
+ * processes. Note that you first have to add this file to a
+ * configuration object before you can query it for configuration
+ * variables.
+ *
+ * @param out the new backend
+ * @param path where the config file is located
+ */
+extern int git_config_file__ondisk(git_config_backend **out, const char *path);
+
+extern int git_config__normalize_name(const char *in, char **out);
+
+/* internal only: does not normalize key and sets out to NULL if not found */
+extern int git_config__lookup_entry(
+	git_config_entry **out,
+	const git_config *cfg,
+	const char *key,
+	bool no_errors);
+
+/* internal only: update and/or delete entry string with constraints */
+extern int git_config__update_entry(
+	git_config *cfg,
+	const char *key,
+	const char *value,
+	bool overwrite_existing,
+	bool only_if_existing);
+
+/*
+ * Lookup functions that cannot fail.  These functions look up a config
+ * value and return a fallback value if the value is missing or if any
+ * failures occur while trying to access the value.
+ */
+
+extern char *git_config__get_string_force(
+	const git_config *cfg, const char *key, const char *fallback_value);
+
+extern int git_config__get_bool_force(
+	const git_config *cfg, const char *key, int fallback_value);
+
+extern int git_config__get_int_force(
+	const git_config *cfg, const char *key, int fallback_value);
+
+/* API for repository cvar-style lookups from config - not cached, but
+ * uses cvar value maps and fallbacks
+ */
+extern int git_config__cvar(
+	int *out, git_config *config, git_cvar_cached cvar);
+
+/**
+ * The opposite of git_config_lookup_map_value, we take an enum value
+ * and map it to the string or bool value on the config.
+ */
+int git_config_lookup_map_enum(git_cvar_t *type_out, const char **str_out,
+			       const git_cvar_map *maps, size_t map_n, int enum_val);
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/config_cache.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/config_cache.c
new file mode 100755
index 0000000..c859ec1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/config_cache.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "fileops.h"
+#include "repository.h"
+#include "config.h"
+#include "git2/config.h"
+#include "vector.h"
+#include "filter.h"
+
+struct map_data {
+	const char *cvar_name;
+	git_cvar_map *maps;
+	size_t map_count;
+	int default_value;
+};
+
+/*
+ *	core.eol
+ *		Sets the line ending type to use in the working directory for
+ *	files that have the text property set. Alternatives are lf, crlf
+ *	and native, which uses the platform's native line ending. The default
+ *	value is native. See gitattributes(5) for more information on
+ *	end-of-line conversion.
+ */
+static git_cvar_map _cvar_map_eol[] = {
+	{GIT_CVAR_FALSE, NULL, GIT_EOL_UNSET},
+	{GIT_CVAR_STRING, "lf", GIT_EOL_LF},
+	{GIT_CVAR_STRING, "crlf", GIT_EOL_CRLF},
+	{GIT_CVAR_STRING, "native", GIT_EOL_NATIVE}
+};
+
+/*
+ *	core.autocrlf
+ *		Setting this variable to "true" is almost the same as setting
+ *	the text attribute to "auto" on all files except that text files are
+ *	not guaranteed to be normalized: files that contain CRLF in the
+ *	repository will not be touched. Use this setting if you want to have
+ *	CRLF line endings in your working directory even though the repository
+ *	does not have normalized line endings. This variable can be set to input,
+ *	in which case no output conversion is performed.
+ */
+static git_cvar_map _cvar_map_autocrlf[] = {
+	{GIT_CVAR_FALSE, NULL, GIT_AUTO_CRLF_FALSE},
+	{GIT_CVAR_TRUE, NULL, GIT_AUTO_CRLF_TRUE},
+	{GIT_CVAR_STRING, "input", GIT_AUTO_CRLF_INPUT}
+};
+
+static git_cvar_map _cvar_map_safecrlf[] = {
+	{GIT_CVAR_FALSE, NULL, GIT_SAFE_CRLF_FALSE},
+	{GIT_CVAR_TRUE, NULL, GIT_SAFE_CRLF_FAIL},
+	{GIT_CVAR_STRING, "warn", GIT_SAFE_CRLF_WARN}
+};
+
+/*
+ * Generic map for integer values
+ */
+static git_cvar_map _cvar_map_int[] = {
+	{GIT_CVAR_INT32, NULL, 0},
+};
+
+static struct map_data _cvar_maps[] = {
+	{"core.autocrlf", _cvar_map_autocrlf, ARRAY_SIZE(_cvar_map_autocrlf), GIT_AUTO_CRLF_DEFAULT},
+	{"core.eol", _cvar_map_eol, ARRAY_SIZE(_cvar_map_eol), GIT_EOL_DEFAULT},
+	{"core.symlinks", NULL, 0, GIT_SYMLINKS_DEFAULT },
+	{"core.ignorecase", NULL, 0, GIT_IGNORECASE_DEFAULT },
+	{"core.filemode", NULL, 0, GIT_FILEMODE_DEFAULT },
+	{"core.ignorestat", NULL, 0, GIT_IGNORESTAT_DEFAULT },
+	{"core.trustctime", NULL, 0, GIT_TRUSTCTIME_DEFAULT },
+	{"core.abbrev", _cvar_map_int, 1, GIT_ABBREV_DEFAULT },
+	{"core.precomposeunicode", NULL, 0, GIT_PRECOMPOSE_DEFAULT },
+	{"core.safecrlf", _cvar_map_safecrlf, ARRAY_SIZE(_cvar_map_safecrlf), GIT_SAFE_CRLF_DEFAULT},
+	{"core.logallrefupdates", NULL, 0, GIT_LOGALLREFUPDATES_DEFAULT },
+	{"core.protecthfs", NULL, 0, GIT_PROTECTHFS_DEFAULT },
+	{"core.protectntfs", NULL, 0, GIT_PROTECTNTFS_DEFAULT },
+};
+
+int git_config__cvar(int *out, git_config *config, git_cvar_cached cvar)
+{
+	int error = 0;
+	struct map_data *data = &_cvar_maps[(int)cvar];
+	git_config_entry *entry;
+
+	git_config__lookup_entry(&entry, config, data->cvar_name, false);
+
+	if (!entry)
+		*out = data->default_value;
+	else if (data->maps)
+		error = git_config_lookup_map_value(
+			out, data->maps, data->map_count, entry->value);
+	else
+		error = git_config_parse_bool(out, entry->value);
+
+	git_config_entry_free(entry);
+	return error;
+}
+
+int git_repository__cvar(int *out, git_repository *repo, git_cvar_cached cvar)
+{
+	*out = repo->cvar_cache[(int)cvar];
+
+	if (*out == GIT_CVAR_NOT_CACHED) {
+		int error;
+		git_config *config;
+
+		if ((error = git_repository_config__weakptr(&config, repo)) < 0 ||
+			(error = git_config__cvar(out, config, cvar)) < 0)
+			return error;
+
+		repo->cvar_cache[(int)cvar] = *out;
+	}
+
+	return 0;
+}
+
+void git_repository__cvar_cache_clear(git_repository *repo)
+{
+	int i;
+
+	for (i = 0; i < GIT_CVAR_CACHE_MAX; ++i)
+		repo->cvar_cache[i] = GIT_CVAR_NOT_CACHED;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/config_file.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/config_file.c
new file mode 100755
index 0000000..52a5376
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/config_file.c
@@ -0,0 +1,1856 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "config.h"
+#include "filebuf.h"
+#include "sysdir.h"
+#include "buffer.h"
+#include "buf_text.h"
+#include "git2/config.h"
+#include "git2/sys/config.h"
+#include "git2/types.h"
+#include "strmap.h"
+#include "array.h"
+
+#include <ctype.h>
+#include <sys/types.h>
+#include <regex.h>
+
+GIT__USE_STRMAP
+
+typedef struct cvar_t {
+	struct cvar_t *next;
+	git_config_entry *entry;
+	bool included; /* whether this is part of [include] */
+} cvar_t;
+
+typedef struct git_config_file_iter {
+	git_config_iterator parent;
+	git_strmap_iter iter;
+	cvar_t* next_var;
+} git_config_file_iter;
+
+/* Max depth for [include] directives */
+#define MAX_INCLUDE_DEPTH 10
+
+#define CVAR_LIST_HEAD(list) ((list)->head)
+
+#define CVAR_LIST_TAIL(list) ((list)->tail)
+
+#define CVAR_LIST_NEXT(var) ((var)->next)
+
+#define CVAR_LIST_EMPTY(list) ((list)->head == NULL)
+
+#define CVAR_LIST_APPEND(list, var) do {\
+	if (CVAR_LIST_EMPTY(list)) {\
+		CVAR_LIST_HEAD(list) = CVAR_LIST_TAIL(list) = var;\
+	} else {\
+		CVAR_LIST_NEXT(CVAR_LIST_TAIL(list)) = var;\
+		CVAR_LIST_TAIL(list) = var;\
+	}\
+} while(0)
+
+#define CVAR_LIST_REMOVE_HEAD(list) do {\
+	CVAR_LIST_HEAD(list) = CVAR_LIST_NEXT(CVAR_LIST_HEAD(list));\
+} while(0)
+
+#define CVAR_LIST_REMOVE_AFTER(var) do {\
+	CVAR_LIST_NEXT(var) = CVAR_LIST_NEXT(CVAR_LIST_NEXT(var));\
+} while(0)
+
+#define CVAR_LIST_FOREACH(list, iter)\
+	for ((iter) = CVAR_LIST_HEAD(list);\
+		 (iter) != NULL;\
+		 (iter) = CVAR_LIST_NEXT(iter))
+
+/*
+ * Inspired by the FreeBSD functions
+ */
+#define CVAR_LIST_FOREACH_SAFE(start, iter, tmp)\
+	for ((iter) = CVAR_LIST_HEAD(vars);\
+		 (iter) && (((tmp) = CVAR_LIST_NEXT(iter) || 1));\
+		 (iter) = (tmp))
+
+struct reader {
+	time_t file_mtime;
+	size_t file_size;
+	char *file_path;
+	git_buf buffer;
+	char *read_ptr;
+	int line_number;
+	int eof;
+};
+
+typedef struct {
+	git_atomic refcount;
+	git_strmap *values;
+} refcounted_strmap;
+
+typedef struct {
+	git_config_backend parent;
+	/* mutex to coordinate accessing the values */
+	git_mutex values_mutex;
+	refcounted_strmap *values;
+} diskfile_header;
+
+typedef struct {
+	diskfile_header header;
+
+	git_config_level_t level;
+
+	git_array_t(struct reader) readers;
+
+	char  *file_path;
+} diskfile_backend;
+
+typedef struct {
+	diskfile_header header;
+
+	diskfile_backend *snapshot_from;
+} diskfile_readonly_backend;
+
+static int config_read(git_strmap *values, diskfile_backend *cfg_file, struct reader *reader, git_config_level_t level, int depth);
+static int config_write(diskfile_backend *cfg, const char *key, const regex_t *preg, const char *value);
+static char *escape_value(const char *ptr);
+
+int git_config_file__snapshot(git_config_backend **out, diskfile_backend *in);
+static int config_snapshot(git_config_backend **out, git_config_backend *in);
+
+static void set_parse_error(struct reader *reader, int col, const char *error_str)
+{
+	giterr_set(GITERR_CONFIG, "Failed to parse config file: %s (in %s:%d, column %d)",
+		error_str, reader->file_path, reader->line_number, col);
+}
+
+static int config_error_readonly(void)
+{
+	giterr_set(GITERR_CONFIG, "this backend is read-only");
+	return -1;
+}
+
+static void cvar_free(cvar_t *var)
+{
+	if (var == NULL)
+		return;
+
+	git__free((char*)var->entry->name);
+	git__free((char *)var->entry->value);
+	git__free(var->entry);
+	git__free(var);
+}
+
+int git_config_file_normalize_section(char *start, char *end)
+{
+	char *scan;
+
+	if (start == end)
+		return GIT_EINVALIDSPEC;
+
+	/* Validate and downcase range */
+	for (scan = start; *scan; ++scan) {
+		if (end && scan >= end)
+			break;
+		if (isalnum(*scan))
+			*scan = (char)git__tolower(*scan);
+		else if (*scan != '-' || scan == start)
+			return GIT_EINVALIDSPEC;
+	}
+
+	if (scan == start)
+		return GIT_EINVALIDSPEC;
+
+	return 0;
+}
+
+/* Add or append the new config option */
+static int append_entry(git_strmap *values, cvar_t *var)
+{
+	git_strmap_iter pos;
+	cvar_t *existing;
+	int error = 0;
+
+	pos = git_strmap_lookup_index(values, var->entry->name);
+	if (!git_strmap_valid_index(values, pos)) {
+		git_strmap_insert(values, var->entry->name, var, error);
+	} else {
+		existing = git_strmap_value_at(values, pos);
+		while (existing->next != NULL) {
+			existing = existing->next;
+		}
+		existing->next = var;
+	}
+
+	if (error > 0)
+		error = 0;
+
+	return error;
+}
+
+static void free_vars(git_strmap *values)
+{
+	cvar_t *var = NULL;
+
+	if (values == NULL)
+		return;
+
+	git_strmap_foreach_value(values, var,
+		while (var != NULL) {
+			cvar_t *next = CVAR_LIST_NEXT(var);
+			cvar_free(var);
+			var = next;
+		});
+
+	git_strmap_free(values);
+}
+
+static void refcounted_strmap_free(refcounted_strmap *map)
+{
+	if (!map)
+		return;
+
+	if (git_atomic_dec(&map->refcount) != 0)
+		return;
+
+	free_vars(map->values);
+	git__free(map);
+}
+
+/**
+ * Take the current values map from the backend and increase its
+ * refcount. This is its own function to make sure we use the mutex to
+ * avoid the map pointer from changing under us.
+ */
+static refcounted_strmap *refcounted_strmap_take(diskfile_header *h)
+{
+	refcounted_strmap *map;
+
+	git_mutex_lock(&h->values_mutex);
+
+	map = h->values;
+	git_atomic_inc(&map->refcount);
+
+	git_mutex_unlock(&h->values_mutex);
+
+	return map;
+}
+
+static int refcounted_strmap_alloc(refcounted_strmap **out)
+{
+	refcounted_strmap *map;
+	int error;
+
+	map = git__calloc(1, sizeof(refcounted_strmap));
+	GITERR_CHECK_ALLOC(map);
+
+	git_atomic_set(&map->refcount, 1);
+
+	if ((error = git_strmap_alloc(&map->values)) < 0)
+		git__free(map);
+	else
+		*out = map;
+
+	return error;
+}
+
+static int config_open(git_config_backend *cfg, git_config_level_t level)
+{
+	int res;
+	struct reader *reader;
+	diskfile_backend *b = (diskfile_backend *)cfg;
+
+	b->level = level;
+
+	if ((res = refcounted_strmap_alloc(&b->header.values)) < 0)
+		return res;
+
+	git_array_init(b->readers);
+	reader = git_array_alloc(b->readers);
+	if (!reader) {
+		refcounted_strmap_free(b->header.values);
+		return -1;
+	}
+	memset(reader, 0, sizeof(struct reader));
+
+	reader->file_path = git__strdup(b->file_path);
+	GITERR_CHECK_ALLOC(reader->file_path);
+
+	git_buf_init(&reader->buffer, 0);
+	res = git_futils_readbuffer_updated(
+		&reader->buffer, b->file_path, &reader->file_mtime, &reader->file_size, NULL);
+
+	/* It's fine if the file doesn't exist */
+	if (res == GIT_ENOTFOUND)
+		return 0;
+
+	if (res < 0 || (res = config_read(b->header.values->values, b, reader, level, 0)) < 0) {
+		refcounted_strmap_free(b->header.values);
+		b->header.values = NULL;
+	}
+
+	reader = git_array_get(b->readers, 0);
+	git_buf_free(&reader->buffer);
+
+	return res;
+}
+
+/* The meat of the refresh, as we want to use it in different places */
+static int config__refresh(git_config_backend *cfg)
+{
+	refcounted_strmap *values = NULL, *tmp;
+	diskfile_backend *b = (diskfile_backend *)cfg;
+	struct reader *reader = NULL;
+	int error = 0;
+
+	if ((error = refcounted_strmap_alloc(&values)) < 0)
+		goto out;
+
+	reader = git_array_get(b->readers, git_array_size(b->readers) - 1);
+	GITERR_CHECK_ALLOC(reader);
+
+	if ((error = config_read(values->values, b, reader, b->level, 0)) < 0)
+		goto out;
+
+	git_mutex_lock(&b->header.values_mutex);
+
+	tmp = b->header.values;
+	b->header.values = values;
+	values = tmp;
+
+	git_mutex_unlock(&b->header.values_mutex);
+
+out:
+	refcounted_strmap_free(values);
+	if (reader)
+		git_buf_free(&reader->buffer);
+	return error;
+}
+
+static int config_refresh(git_config_backend *cfg)
+{
+	int error = 0, updated = 0, any_updated = 0;
+	diskfile_backend *b = (diskfile_backend *)cfg;
+	struct reader *reader = NULL;
+	uint32_t i;
+
+	for (i = 0; i < git_array_size(b->readers); i++) {
+		reader = git_array_get(b->readers, i);
+		error = git_futils_readbuffer_updated(
+			&reader->buffer, reader->file_path,
+			&reader->file_mtime, &reader->file_size, &updated);
+
+		if (error < 0 && error != GIT_ENOTFOUND)
+			return error;
+
+		if (updated)
+			any_updated = 1;
+	}
+
+	if (!any_updated)
+		return (error == GIT_ENOTFOUND) ? 0 : error;
+
+	return config__refresh(cfg);
+}
+
+static void backend_free(git_config_backend *_backend)
+{
+	diskfile_backend *backend = (diskfile_backend *)_backend;
+	uint32_t i;
+
+	if (backend == NULL)
+		return;
+
+	for (i = 0; i < git_array_size(backend->readers); i++) {
+		struct reader *r = git_array_get(backend->readers, i);
+		git__free(r->file_path);
+	}
+	git_array_clear(backend->readers);
+
+	git__free(backend->file_path);
+	refcounted_strmap_free(backend->header.values);
+	git_mutex_free(&backend->header.values_mutex);
+	git__free(backend);
+}
+
+static void config_iterator_free(
+	git_config_iterator* iter)
+{
+	iter->backend->free(iter->backend);
+	git__free(iter);
+}
+
+static int config_iterator_next(
+	git_config_entry **entry,
+	git_config_iterator *iter)
+{
+	git_config_file_iter *it = (git_config_file_iter *) iter;
+	diskfile_header *h = (diskfile_header *) it->parent.backend;
+	git_strmap *values = h->values->values;
+	int err = 0;
+	cvar_t * var;
+
+	if (it->next_var == NULL) {
+		err = git_strmap_next((void**) &var, &(it->iter), values);
+	} else {
+		var = it->next_var;
+	}
+
+	if (err < 0) {
+		it->next_var = NULL;
+		return err;
+	}
+
+	*entry = var->entry;
+	it->next_var = CVAR_LIST_NEXT(var);
+
+	return 0;
+}
+
+static int config_iterator_new(
+	git_config_iterator **iter,
+	struct git_config_backend* backend)
+{
+	diskfile_header *h;
+	git_config_file_iter *it;
+	git_config_backend *snapshot;
+	diskfile_backend *b = (diskfile_backend *) backend;
+	int error;
+
+	if ((error = config_snapshot(&snapshot, backend)) < 0)
+		return error;
+
+	if ((error = snapshot->open(snapshot, b->level)) < 0)
+		return error;
+
+	it = git__calloc(1, sizeof(git_config_file_iter));
+	GITERR_CHECK_ALLOC(it);
+
+	h = (diskfile_header *)snapshot;
+
+	/* strmap_begin() is currently a macro returning 0 */
+	GIT_UNUSED(h);
+
+	it->parent.backend = snapshot;
+	it->iter = git_strmap_begin(h->values);
+	it->next_var = NULL;
+
+	it->parent.next = config_iterator_next;
+	it->parent.free = config_iterator_free;
+	*iter = (git_config_iterator *) it;
+
+	return 0;
+}
+
+static int config_set(git_config_backend *cfg, const char *name, const char *value)
+{
+	diskfile_backend *b = (diskfile_backend *)cfg;
+	refcounted_strmap *map;
+	git_strmap *values;
+	char *key, *esc_value = NULL;
+	khiter_t pos;
+	int rval, ret;
+
+	if ((rval = git_config__normalize_name(name, &key)) < 0)
+		return rval;
+
+	map = refcounted_strmap_take(&b->header);
+	values = map->values;
+
+	/*
+	 * Try to find it in the existing values and update it if it
+	 * only has one value.
+	 */
+	pos = git_strmap_lookup_index(values, key);
+	if (git_strmap_valid_index(values, pos)) {
+		cvar_t *existing = git_strmap_value_at(values, pos);
+
+		if (existing->next != NULL) {
+			giterr_set(GITERR_CONFIG, "Multivar incompatible with simple set");
+			ret = -1;
+			goto out;
+		}
+
+		/* don't update if old and new values already match */
+		if ((!existing->entry->value && !value) ||
+			(existing->entry->value && value &&
+			 !strcmp(existing->entry->value, value))) {
+			ret = 0;
+			goto out;
+		}
+	}
+
+	/* No early returns due to sanity checks, let's write it out and refresh */
+
+	if (value) {
+		esc_value = escape_value(value);
+		GITERR_CHECK_ALLOC(esc_value);
+	}
+
+	if ((ret = config_write(b, key, NULL, esc_value)) < 0)
+		goto out;
+
+	ret = config_refresh(cfg);
+
+out:
+	refcounted_strmap_free(map);
+	git__free(esc_value);
+	git__free(key);
+	return ret;
+}
+
+/* release the map containing the entry as an equivalent to freeing it */
+static void release_map(git_config_entry *entry)
+{
+	refcounted_strmap *map = (refcounted_strmap *) entry->payload;
+	refcounted_strmap_free(map);
+}
+
+/*
+ * Internal function that actually gets the value in string form
+ */
+static int config_get(git_config_backend *cfg, const char *key, git_config_entry **out)
+{
+	diskfile_header *h = (diskfile_header *)cfg;
+	refcounted_strmap *map;
+	git_strmap *values;
+	khiter_t pos;
+	cvar_t *var;
+	int error = 0;
+
+	if (!h->parent.readonly && ((error = config_refresh(cfg)) < 0))
+		return error;
+
+	map = refcounted_strmap_take(h);
+	values = map->values;
+
+	pos = git_strmap_lookup_index(values, key);
+
+	/* no error message; the config system will write one */
+	if (!git_strmap_valid_index(values, pos)) {
+		refcounted_strmap_free(map);
+		return GIT_ENOTFOUND;
+	}
+
+	var = git_strmap_value_at(values, pos);
+	while (var->next)
+		var = var->next;
+
+	*out = var->entry;
+	(*out)->free = release_map;
+	(*out)->payload = map;
+
+	return error;
+}
+
+static int config_set_multivar(
+	git_config_backend *cfg, const char *name, const char *regexp, const char *value)
+{
+	diskfile_backend *b = (diskfile_backend *)cfg;
+	refcounted_strmap *map;
+	git_strmap *values;
+	char *key;
+	regex_t preg;
+	int result;
+	khiter_t pos;
+
+	assert(regexp);
+
+	if ((result = git_config__normalize_name(name, &key)) < 0)
+		return result;
+
+	map = refcounted_strmap_take(&b->header);
+	values = b->header.values->values;
+
+	pos = git_strmap_lookup_index(values, key);
+	if (!git_strmap_valid_index(values, pos)) {
+		/* If we don't have it, behave like a normal set */
+		result = config_set(cfg, name, value);
+		refcounted_strmap_free(map);
+		git__free(key);
+		return result;
+	}
+
+	result = regcomp(&preg, regexp, REG_EXTENDED);
+	if (result != 0) {
+		giterr_set_regex(&preg, result);
+		result = -1;
+		goto out;
+	}
+
+	/* If we do have it, set call config_write() and reload */
+	if ((result = config_write(b, key, &preg, value)) < 0)
+		goto out;
+
+	result = config_refresh(cfg);
+
+out:
+	refcounted_strmap_free(map);
+	git__free(key);
+	regfree(&preg);
+
+	return result;
+}
+
+static int config_delete(git_config_backend *cfg, const char *name)
+{
+	cvar_t *var;
+	diskfile_backend *b = (diskfile_backend *)cfg;
+	refcounted_strmap *map;	git_strmap *values;
+	char *key;
+	int result;
+	khiter_t pos;
+
+	if ((result = git_config__normalize_name(name, &key)) < 0)
+		return result;
+
+	map = refcounted_strmap_take(&b->header);
+	values = b->header.values->values;
+
+	pos = git_strmap_lookup_index(values, key);
+	git__free(key);
+
+	if (!git_strmap_valid_index(values, pos)) {
+		refcounted_strmap_free(map);
+		giterr_set(GITERR_CONFIG, "Could not find key '%s' to delete", name);
+		return GIT_ENOTFOUND;
+	}
+
+	var = git_strmap_value_at(values, pos);
+	refcounted_strmap_free(map);
+
+	if (var->next != NULL) {
+		giterr_set(GITERR_CONFIG, "Cannot delete multivar with a single delete");
+		return -1;
+	}
+
+	if ((result = config_write(b, var->entry->name, NULL, NULL)) < 0)
+		return result;
+
+	return config_refresh(cfg);
+}
+
+static int config_delete_multivar(git_config_backend *cfg, const char *name, const char *regexp)
+{
+	diskfile_backend *b = (diskfile_backend *)cfg;
+	refcounted_strmap *map;
+	git_strmap *values;
+	char *key;
+	regex_t preg;
+	int result;
+	khiter_t pos;
+
+	if ((result = git_config__normalize_name(name, &key)) < 0)
+		return result;
+
+	map = refcounted_strmap_take(&b->header);
+	values = b->header.values->values;
+
+	pos = git_strmap_lookup_index(values, key);
+
+	if (!git_strmap_valid_index(values, pos)) {
+		refcounted_strmap_free(map);
+		git__free(key);
+		giterr_set(GITERR_CONFIG, "Could not find key '%s' to delete", name);
+		return GIT_ENOTFOUND;
+	}
+
+	refcounted_strmap_free(map);
+
+	result = regcomp(&preg, regexp, REG_EXTENDED);
+	if (result != 0) {
+		giterr_set_regex(&preg, result);
+		result = -1;
+		goto out;
+	}
+
+	if ((result = config_write(b, key, &preg, NULL)) < 0)
+		goto out;
+
+	result = config_refresh(cfg);
+
+out:
+	git__free(key);
+	regfree(&preg);
+	return result;
+}
+
+static int config_snapshot(git_config_backend **out, git_config_backend *in)
+{
+	diskfile_backend *b = (diskfile_backend *) in;
+
+	return git_config_file__snapshot(out, b);
+}
+
+int git_config_file__ondisk(git_config_backend **out, const char *path)
+{
+	diskfile_backend *backend;
+
+	backend = git__calloc(1, sizeof(diskfile_backend));
+	GITERR_CHECK_ALLOC(backend);
+
+	backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
+	git_mutex_init(&backend->header.values_mutex);
+
+	backend->file_path = git__strdup(path);
+	GITERR_CHECK_ALLOC(backend->file_path);
+
+	backend->header.parent.open = config_open;
+	backend->header.parent.get = config_get;
+	backend->header.parent.set = config_set;
+	backend->header.parent.set_multivar = config_set_multivar;
+	backend->header.parent.del = config_delete;
+	backend->header.parent.del_multivar = config_delete_multivar;
+	backend->header.parent.iterator = config_iterator_new;
+	backend->header.parent.snapshot = config_snapshot;
+	backend->header.parent.free = backend_free;
+
+	*out = (git_config_backend *)backend;
+
+	return 0;
+}
+
+static int config_set_readonly(git_config_backend *cfg, const char *name, const char *value)
+{
+	GIT_UNUSED(cfg);
+	GIT_UNUSED(name);
+	GIT_UNUSED(value);
+
+	return config_error_readonly();
+}
+
+static int config_set_multivar_readonly(
+	git_config_backend *cfg, const char *name, const char *regexp, const char *value)
+{
+	GIT_UNUSED(cfg);
+	GIT_UNUSED(name);
+	GIT_UNUSED(regexp);
+	GIT_UNUSED(value);
+
+	return config_error_readonly();
+}
+
+static int config_delete_multivar_readonly(git_config_backend *cfg, const char *name, const char *regexp)
+{
+	GIT_UNUSED(cfg);
+	GIT_UNUSED(name);
+	GIT_UNUSED(regexp);
+
+	return config_error_readonly();
+}
+
+static int config_delete_readonly(git_config_backend *cfg, const char *name)
+{
+	GIT_UNUSED(cfg);
+	GIT_UNUSED(name);
+
+	return config_error_readonly();
+}
+
+static void backend_readonly_free(git_config_backend *_backend)
+{
+	diskfile_backend *backend = (diskfile_backend *)_backend;
+
+	if (backend == NULL)
+		return;
+
+	refcounted_strmap_free(backend->header.values);
+	git_mutex_free(&backend->header.values_mutex);
+	git__free(backend);
+}
+
+static int config_readonly_open(git_config_backend *cfg, git_config_level_t level)
+{
+	diskfile_readonly_backend *b = (diskfile_readonly_backend *) cfg;
+	diskfile_backend *src = b->snapshot_from;
+	diskfile_header *src_header = &src->header;
+	refcounted_strmap *src_map;
+	int error;
+
+	if (!src_header->parent.readonly && (error = config_refresh(&src_header->parent)) < 0)
+		return error;
+
+	/* We're just copying data, don't care about the level */
+	GIT_UNUSED(level);
+
+	src_map = refcounted_strmap_take(src_header);
+	b->header.values = src_map;
+
+	return 0;
+}
+
+int git_config_file__snapshot(git_config_backend **out, diskfile_backend *in)
+{
+	diskfile_readonly_backend *backend;
+
+	backend = git__calloc(1, sizeof(diskfile_readonly_backend));
+	GITERR_CHECK_ALLOC(backend);
+
+	backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
+	git_mutex_init(&backend->header.values_mutex);
+
+	backend->snapshot_from = in;
+
+	backend->header.parent.readonly = 1;
+	backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
+	backend->header.parent.open = config_readonly_open;
+	backend->header.parent.get = config_get;
+	backend->header.parent.set = config_set_readonly;
+	backend->header.parent.set_multivar = config_set_multivar_readonly;
+	backend->header.parent.del = config_delete_readonly;
+	backend->header.parent.del_multivar = config_delete_multivar_readonly;
+	backend->header.parent.iterator = config_iterator_new;
+	backend->header.parent.free = backend_readonly_free;
+
+	*out = (git_config_backend *)backend;
+
+	return 0;
+}
+
+static int reader_getchar_raw(struct reader *reader)
+{
+	int c;
+
+	c = *reader->read_ptr++;
+
+	/*
+	Win 32 line breaks: if we find a \r\n sequence,
+	return only the \n as a newline
+	*/
+	if (c == '\r' && *reader->read_ptr == '\n') {
+		reader->read_ptr++;
+		c = '\n';
+	}
+
+	if (c == '\n')
+		reader->line_number++;
+
+	if (c == 0) {
+		reader->eof = 1;
+		c = '\0';
+	}
+
+	return c;
+}
+
+#define SKIP_WHITESPACE (1 << 1)
+#define SKIP_COMMENTS (1 << 2)
+
+static int reader_getchar(struct reader *reader, int flags)
+{
+	const int skip_whitespace = (flags & SKIP_WHITESPACE);
+	const int skip_comments = (flags & SKIP_COMMENTS);
+	int c;
+
+	assert(reader->read_ptr);
+
+	do {
+		c = reader_getchar_raw(reader);
+	} while (c != '\n' && c != '\0' && skip_whitespace && git__isspace(c));
+
+	if (skip_comments && (c == '#' || c == ';')) {
+		do {
+			c = reader_getchar_raw(reader);
+		} while (c != '\n' && c != '\0');
+	}
+
+	return c;
+}
+
+/*
+ * Read the next char, but don't move the reading pointer.
+ */
+static int reader_peek(struct reader *reader, int flags)
+{
+	void *old_read_ptr;
+	int old_lineno, old_eof;
+	int ret;
+
+	assert(reader->read_ptr);
+
+	old_read_ptr = reader->read_ptr;
+	old_lineno = reader->line_number;
+	old_eof = reader->eof;
+
+	ret = reader_getchar(reader, flags);
+
+	reader->read_ptr = old_read_ptr;
+	reader->line_number = old_lineno;
+	reader->eof = old_eof;
+
+	return ret;
+}
+
+/*
+ * Read and consume a line, returning it in newly-allocated memory.
+ */
+static char *reader_readline(struct reader *reader, bool skip_whitespace)
+{
+	char *line = NULL;
+	char *line_src, *line_end;
+	size_t line_len, alloc_len;
+
+	line_src = reader->read_ptr;
+
+	if (skip_whitespace) {
+		/* Skip empty empty lines */
+		while (git__isspace(*line_src))
+			++line_src;
+	}
+
+	line_end = strchr(line_src, '\n');
+
+	/* no newline at EOF */
+	if (line_end == NULL)
+		line_end = strchr(line_src, 0);
+
+	line_len = line_end - line_src;
+
+	if (GIT_ADD_SIZET_OVERFLOW(&alloc_len, line_len, 1) ||
+		(line = git__malloc(alloc_len)) == NULL) {
+		return NULL;
+	}
+
+	memcpy(line, line_src, line_len);
+
+	do line[line_len] = '\0';
+	while (line_len-- > 0 && git__isspace(line[line_len]));
+
+	if (*line_end == '\n')
+		line_end++;
+
+	if (*line_end == '\0')
+		reader->eof = 1;
+
+	reader->line_number++;
+	reader->read_ptr = line_end;
+
+	return line;
+}
+
+/*
+ * Consume a line, without storing it anywhere
+ */
+static void reader_consume_line(struct reader *reader)
+{
+	char *line_start, *line_end;
+
+	line_start = reader->read_ptr;
+	line_end = strchr(line_start, '\n');
+	/* No newline at EOF */
+	if(line_end == NULL){
+		line_end = strchr(line_start, '\0');
+	}
+
+	if (*line_end == '\n')
+		line_end++;
+
+	if (*line_end == '\0')
+		reader->eof = 1;
+
+	reader->line_number++;
+	reader->read_ptr = line_end;
+}
+
+GIT_INLINE(int) config_keychar(int c)
+{
+	return isalnum(c) || c == '-';
+}
+
+static int parse_section_header_ext(struct reader *reader, const char *line, const char *base_name, char **section_name)
+{
+	int c, rpos;
+	char *first_quote, *last_quote;
+	git_buf buf = GIT_BUF_INIT;
+	size_t quoted_len, alloc_len, base_name_len = strlen(base_name);
+
+	/*
+	 * base_name is what came before the space. We should be at the
+	 * first quotation mark, except for now, line isn't being kept in
+	 * sync so we only really use it to calculate the length.
+	 */
+
+	first_quote = strchr(line, '"');
+	last_quote = strrchr(line, '"');
+	quoted_len = last_quote - first_quote;
+
+	if (quoted_len == 0) {
+		set_parse_error(reader, 0, "Missing closing quotation mark in section header");
+		return -1;
+	}
+
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, base_name_len, quoted_len);
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
+
+	git_buf_grow(&buf, alloc_len);
+	git_buf_printf(&buf, "%s.", base_name);
+
+	rpos = 0;
+
+	line = first_quote;
+	c = line[++rpos];
+
+	/*
+	 * At the end of each iteration, whatever is stored in c will be
+	 * added to the string. In case of error, jump to out
+	 */
+	do {
+
+		switch (c) {
+		case 0:
+			set_parse_error(reader, 0, "Unexpected end-of-line in section header");
+			git_buf_free(&buf);
+			return -1;
+
+		case '"':
+			goto end_parse;
+
+		case '\\':
+			c = line[++rpos];
+
+			if (c == 0) {
+				set_parse_error(reader, rpos, "Unexpected end-of-line in section header");
+				git_buf_free(&buf);
+				return -1;
+			}
+
+		default:
+			break;
+		}
+
+		git_buf_putc(&buf, (char)c);
+		c = line[++rpos];
+	} while (line + rpos < last_quote);
+
+end_parse:
+	if (line[rpos] != '"' || line[rpos + 1] != ']') {
+		set_parse_error(reader, rpos, "Unexpected text after closing quotes");
+		git_buf_free(&buf);
+		return -1;
+	}
+
+	*section_name = git_buf_detach(&buf);
+	return 0;
+}
+
+static int parse_section_header(struct reader *reader, char **section_out)
+{
+	char *name, *name_end;
+	int name_length, c, pos;
+	int result;
+	char *line;
+	size_t line_len;
+
+	line = reader_readline(reader, true);
+	if (line == NULL)
+		return -1;
+
+	/* find the end of the variable's name */
+	name_end = strrchr(line, ']');
+	if (name_end == NULL) {
+		git__free(line);
+		set_parse_error(reader, 0, "Missing ']' in section header");
+		return -1;
+	}
+
+	GITERR_CHECK_ALLOC_ADD(&line_len, (size_t)(name_end - line), 1);
+	name = git__malloc(line_len);
+	GITERR_CHECK_ALLOC(name);
+
+	name_length = 0;
+	pos = 0;
+
+	/* Make sure we were given a section header */
+	c = line[pos++];
+	assert(c == '[');
+
+	c = line[pos++];
+
+	do {
+		if (git__isspace(c)){
+			name[name_length] = '\0';
+			result = parse_section_header_ext(reader, line, name, section_out);
+			git__free(line);
+			git__free(name);
+			return result;
+		}
+
+		if (!config_keychar(c) && c != '.') {
+			set_parse_error(reader, pos, "Unexpected character in header");
+			goto fail_parse;
+		}
+
+		name[name_length++] = (char)git__tolower(c);
+
+	} while ((c = line[pos++]) != ']');
+
+	if (line[pos - 1] != ']') {
+		set_parse_error(reader, pos, "Unexpected end of file");
+		goto fail_parse;
+	}
+
+	git__free(line);
+
+	name[name_length] = 0;
+	*section_out = name;
+
+	return 0;
+
+fail_parse:
+	git__free(line);
+	git__free(name);
+	return -1;
+}
+
+static int skip_bom(struct reader *reader)
+{
+	git_bom_t bom;
+	int bom_offset = git_buf_text_detect_bom(&bom,
+		&reader->buffer, reader->read_ptr - reader->buffer.ptr);
+
+	if (bom == GIT_BOM_UTF8)
+		reader->read_ptr += bom_offset;
+
+	/* TODO: reference implementation is pretty stupid with BoM */
+
+	return 0;
+}
+
+/*
+	(* basic types *)
+	digit = "0".."9"
+	integer = digit { digit }
+	alphabet = "a".."z" + "A" .. "Z"
+
+	section_char = alphabet | "." | "-"
+	extension_char = (* any character except newline *)
+	any_char = (* any character *)
+	variable_char = "alphabet" | "-"
+
+
+	(* actual grammar *)
+	config = { section }
+
+	section = header { definition }
+
+	header = "[" section [subsection | subsection_ext] "]"
+
+	subsection = "." section
+	subsection_ext = "\"" extension "\""
+
+	section = section_char { section_char }
+	extension = extension_char { extension_char }
+
+	definition = variable_name ["=" variable_value] "\n"
+
+	variable_name = variable_char { variable_char }
+	variable_value = string | boolean | integer
+
+	string = quoted_string | plain_string
+	quoted_string = "\"" plain_string "\""
+	plain_string = { any_char }
+
+	boolean = boolean_true | boolean_false
+	boolean_true = "yes" | "1" | "true" | "on"
+	boolean_false = "no" | "0" | "false" | "off"
+*/
+
+static int strip_comments(char *line, int in_quotes)
+{
+	int quote_count = in_quotes, backslash_count = 0;
+	char *ptr;
+
+	for (ptr = line; *ptr; ++ptr) {
+		if (ptr[0] == '"' && ptr > line && ptr[-1] != '\\')
+			quote_count++;
+
+		if ((ptr[0] == ';' || ptr[0] == '#') &&
+			(quote_count % 2) == 0 &&
+			(backslash_count % 2) == 0) {
+			ptr[0] = '\0';
+			break;
+		}
+
+		if (ptr[0] == '\\')
+			backslash_count++;
+		else
+			backslash_count = 0;
+	}
+
+	/* skip any space at the end */
+	while (ptr > line && git__isspace(ptr[-1])) {
+		ptr--;
+	}
+	ptr[0] = '\0';
+
+	return quote_count;
+}
+
+static int included_path(git_buf *out, const char *dir, const char *path)
+{
+	/* From the user's home */
+	if (path[0] == '~' && path[1] == '/')
+		return git_sysdir_find_global_file(out, &path[1]);
+
+	return git_path_join_unrooted(out, path, dir, NULL);
+}
+
+static const char *escapes = "ntb\"\\";
+static const char *escaped = "\n\t\b\"\\";
+
+/* Escape the values to write them to the file */
+static char *escape_value(const char *ptr)
+{
+	git_buf buf = GIT_BUF_INIT;
+	size_t len;
+	const char *esc;
+
+	assert(ptr);
+
+	len = strlen(ptr);
+	if (!len)
+		return git__calloc(1, sizeof(char));
+
+	git_buf_grow(&buf, len);
+
+	while (*ptr != '\0') {
+		if ((esc = strchr(escaped, *ptr)) != NULL) {
+			git_buf_putc(&buf, '\\');
+			git_buf_putc(&buf, escapes[esc - escaped]);
+		} else {
+			git_buf_putc(&buf, *ptr);
+		}
+		ptr++;
+	}
+
+	if (git_buf_oom(&buf)) {
+		git_buf_free(&buf);
+		return NULL;
+	}
+
+	return git_buf_detach(&buf);
+}
+
+/* '\"' -> '"' etc */
+static int unescape_line(
+	char **out, bool *is_multi, const char *ptr, int quote_count)
+{
+	char *str, *fixed, *esc;
+	size_t ptr_len = strlen(ptr), alloc_len;
+
+	*is_multi = false;
+
+	if (GIT_ADD_SIZET_OVERFLOW(&alloc_len, ptr_len, 1) ||
+		(str = git__malloc(alloc_len)) == NULL) {
+		return -1;
+	}
+
+	fixed = str;
+
+	while (*ptr != '\0') {
+		if (*ptr == '"') {
+			quote_count++;
+		} else if (*ptr != '\\') {
+			*fixed++ = *ptr;
+		} else {
+			/* backslash, check the next char */
+			ptr++;
+			/* if we're at the end, it's a multiline, so keep the backslash */
+			if (*ptr == '\0') {
+				*is_multi = true;
+				goto done;
+			}
+			if ((esc = strchr(escapes, *ptr)) != NULL) {
+				*fixed++ = escaped[esc - escapes];
+			} else {
+				git__free(str);
+				giterr_set(GITERR_CONFIG, "Invalid escape at %s", ptr);
+				return -1;
+			}
+		}
+		ptr++;
+	}
+
+done:
+	*fixed = '\0';
+	*out = str;
+
+	return 0;
+}
+
+static int parse_multiline_variable(struct reader *reader, git_buf *value, int in_quotes)
+{
+	char *line = NULL, *proc_line = NULL;
+	int quote_count;
+	bool multiline;
+
+	/* Check that the next line exists */
+	line = reader_readline(reader, false);
+	if (line == NULL)
+		return -1;
+
+	/* We've reached the end of the file, there is no continuation.
+	 * (this is not an error).
+	 */
+	if (line[0] == '\0') {
+		git__free(line);
+		return 0;
+	}
+
+	quote_count = strip_comments(line, !!in_quotes);
+
+	/* If it was just a comment, pretend it didn't exist */
+	if (line[0] == '\0') {
+		git__free(line);
+		return parse_multiline_variable(reader, value, quote_count);
+		/* TODO: unbounded recursion. This **could** be exploitable */
+	}
+
+	if (unescape_line(&proc_line, &multiline, line, in_quotes) < 0) {
+		git__free(line);
+		return -1;
+	}
+	/* add this line to the multiline var */
+
+	git_buf_puts(value, proc_line);
+	git__free(line);
+	git__free(proc_line);
+
+	/*
+	 * If we need to continue reading the next line, let's just
+	 * keep putting stuff in the buffer
+	 */
+	if (multiline)
+		return parse_multiline_variable(reader, value, quote_count);
+
+	return 0;
+}
+
+GIT_INLINE(bool) is_namechar(char c)
+{
+	return isalnum(c) || c == '-';
+}
+
+static int parse_name(
+	char **name, const char **value, struct reader *reader, const char *line)
+{
+	const char *name_end = line, *value_start;
+
+	*name = NULL;
+	*value = NULL;
+
+	while (*name_end && is_namechar(*name_end))
+		name_end++;
+
+	if (line == name_end) {
+		set_parse_error(reader, 0, "Invalid configuration key");
+		return -1;
+	}
+
+	value_start = name_end;
+
+	while (*value_start && git__isspace(*value_start))
+		value_start++;
+
+	if (*value_start == '=') {
+		*value = value_start + 1;
+	} else if (*value_start) {
+		set_parse_error(reader, 0, "Invalid configuration key");
+		return -1;
+	}
+
+	if ((*name = git__strndup(line, name_end - line)) == NULL)
+		return -1;
+
+	return 0;
+}
+
+static int parse_variable(struct reader *reader, char **var_name, char **var_value)
+{
+	const char *value_start = NULL;
+	char *line;
+	int quote_count;
+	bool multiline;
+
+	line = reader_readline(reader, true);
+	if (line == NULL)
+		return -1;
+
+	quote_count = strip_comments(line, 0);
+
+	/* If there is no value, boolean true is assumed */
+	*var_value = NULL;
+
+	if (parse_name(var_name, &value_start, reader, line) < 0)
+		goto on_error;
+
+	/*
+	 * Now, let's try to parse the value
+	 */
+	if (value_start != NULL) {
+		while (git__isspace(value_start[0]))
+			value_start++;
+
+		if (unescape_line(var_value, &multiline, value_start, 0) < 0)
+			goto on_error;
+
+		if (multiline) {
+			git_buf multi_value = GIT_BUF_INIT;
+			git_buf_attach(&multi_value, *var_value, 0);
+
+			if (parse_multiline_variable(reader, &multi_value, quote_count) < 0 ||
+				git_buf_oom(&multi_value)) {
+				git_buf_free(&multi_value);
+				goto on_error;
+			}
+
+			*var_value = git_buf_detach(&multi_value);
+		}
+	}
+
+	git__free(line);
+	return 0;
+
+on_error:
+	git__free(*var_name);
+	git__free(line);
+	return -1;
+}
+
+static int config_parse(
+	struct reader *reader,
+	int (*on_section)(struct reader **reader, const char *current_section, const char *line, size_t line_len, void *data),
+	int (*on_variable)(struct reader **reader, const char *current_section, char *var_name, char *var_value, const char *line, size_t line_len, void *data),
+	int (*on_comment)(struct reader **reader, const char *line, size_t line_len, void *data),
+	int (*on_eof)(struct reader **reader, void *data),
+	void *data)
+{
+	char *current_section = NULL, *var_name, *var_value, *line_start;
+	char c;
+	size_t line_len;
+	int result = 0;
+
+	skip_bom(reader);
+
+	while (result == 0 && !reader->eof) {
+		line_start = reader->read_ptr;
+
+		c = reader_peek(reader, SKIP_WHITESPACE);
+
+		switch (c) {
+		case '\0': /* EOF when peeking, set EOF in the reader to exit the loop */
+			reader->eof = 1;
+			break;
+
+		case '[': /* section header, new section begins */
+			git__free(current_section);
+			current_section = NULL;
+
+			if ((result = parse_section_header(reader, &current_section)) == 0 && on_section) {
+				line_len = reader->read_ptr - line_start;
+				result = on_section(&reader, current_section, line_start, line_len, data);
+			}
+			break;
+
+		case '\n': /* comment or whitespace-only */
+		case ';':
+		case '#':
+			reader_consume_line(reader);
+
+			if (on_comment) {
+				line_len = reader->read_ptr - line_start;
+				result = on_comment(&reader, line_start, line_len, data);
+			}
+			break;
+
+		default: /* assume variable declaration */
+			if ((result = parse_variable(reader, &var_name, &var_value)) == 0 && on_variable) {
+				line_len = reader->read_ptr - line_start;
+				result = on_variable(&reader, current_section, var_name, var_value, line_start, line_len, data);
+			}
+			break;
+		}
+	}
+
+	if (on_eof)
+		result = on_eof(&reader, data);
+
+	git__free(current_section);
+	return result;
+}
+
+struct parse_data {
+	git_strmap *values;
+	diskfile_backend *cfg_file;
+	uint32_t reader_idx;
+	git_config_level_t level;
+	int depth;
+};
+
+static int read_on_variable(
+	struct reader **reader,
+	const char *current_section,
+	char *var_name,
+	char *var_value,
+	const char *line,
+	size_t line_len,
+	void *data)
+{
+	struct parse_data *parse_data = (struct parse_data *)data;
+	git_buf buf = GIT_BUF_INIT;
+	cvar_t *var;
+	int result = 0;
+
+	GIT_UNUSED(line);
+	GIT_UNUSED(line_len);
+
+	git__strtolower(var_name);
+	git_buf_printf(&buf, "%s.%s", current_section, var_name);
+	git__free(var_name);
+
+	if (git_buf_oom(&buf)) {
+		git__free(var_value);
+		return -1;
+	}
+
+	var = git__calloc(1, sizeof(cvar_t));
+	GITERR_CHECK_ALLOC(var);
+	var->entry = git__calloc(1, sizeof(git_config_entry));
+	GITERR_CHECK_ALLOC(var->entry);
+
+	var->entry->name = git_buf_detach(&buf);
+	var->entry->value = var_value;
+	var->entry->level = parse_data->level;
+	var->included = !!parse_data->depth;
+
+	if ((result = append_entry(parse_data->values, var)) < 0)
+		return result;
+
+	result = 0;
+
+	/* Add or append the new config option */
+	if (!git__strcmp(var->entry->name, "include.path")) {
+		struct reader *r;
+		git_buf path = GIT_BUF_INIT;
+		char *dir;
+		uint32_t index;
+
+		r = git_array_alloc(parse_data->cfg_file->readers);
+		/* The reader may have been reallocated */
+		*reader = git_array_get(parse_data->cfg_file->readers, parse_data->reader_idx);
+		memset(r, 0, sizeof(struct reader));
+
+		if ((result = git_path_dirname_r(&path, (*reader)->file_path)) < 0)
+			return result;
+
+		/* We need to know our index in the array, as the next config_parse call may realloc */
+		index = git_array_size(parse_data->cfg_file->readers) - 1;
+		dir = git_buf_detach(&path);
+		result = included_path(&path, dir, var->entry->value);
+		git__free(dir);
+
+		if (result < 0)
+			return result;
+
+		r->file_path = git_buf_detach(&path);
+		git_buf_init(&r->buffer, 0);
+
+		result = git_futils_readbuffer_updated(
+			&r->buffer, r->file_path, &r->file_mtime, &r->file_size, NULL);
+
+		if (result == 0) {
+			result = config_read(parse_data->values, parse_data->cfg_file, r, parse_data->level, parse_data->depth+1);
+			r = git_array_get(parse_data->cfg_file->readers, index);
+			*reader = git_array_get(parse_data->cfg_file->readers, parse_data->reader_idx);
+		} else if (result == GIT_ENOTFOUND) {
+			giterr_clear();
+			result = 0;
+		}
+
+		git_buf_free(&r->buffer);
+	}
+
+	return result;
+}
+
+static int config_read(git_strmap *values, diskfile_backend *cfg_file, struct reader *reader, git_config_level_t level, int depth)
+{
+	struct parse_data parse_data;
+
+	if (depth >= MAX_INCLUDE_DEPTH) {
+		giterr_set(GITERR_CONFIG, "Maximum config include depth reached");
+		return -1;
+	}
+
+	/* Initialize the reading position */
+	reader->read_ptr = reader->buffer.ptr;
+	reader->eof = 0;
+
+	/* If the file is empty, there's nothing for us to do */
+	if (*reader->read_ptr == '\0')
+		return 0;
+
+	parse_data.values = values;
+	parse_data.cfg_file = cfg_file;
+	parse_data.reader_idx = git_array_size(cfg_file->readers) - 1;
+	parse_data.level = level;
+	parse_data.depth = depth;
+
+	return config_parse(reader, NULL, read_on_variable, NULL, NULL, &parse_data);
+}
+
+static int write_section(git_filebuf *file, const char *key)
+{
+	int result;
+	const char *dot;
+	git_buf buf = GIT_BUF_INIT;
+
+	/* All of this just for [section "subsection"] */
+	dot = strchr(key, '.');
+	git_buf_putc(&buf, '[');
+	if (dot == NULL) {
+		git_buf_puts(&buf, key);
+	} else {
+		char *escaped;
+		git_buf_put(&buf, key, dot - key);
+		escaped = escape_value(dot + 1);
+		GITERR_CHECK_ALLOC(escaped);
+		git_buf_printf(&buf, " \"%s\"", escaped);
+		git__free(escaped);
+	}
+	git_buf_puts(&buf, "]\n");
+
+	if (git_buf_oom(&buf))
+		return -1;
+
+	result = git_filebuf_write(file, git_buf_cstr(&buf), buf.size);
+	git_buf_free(&buf);
+
+	return result;
+}
+
+static const char *quotes_for_value(const char *value)
+{
+	const char *ptr;
+
+	if (value[0] == ' ' || value[0] == '\0')
+		return "\"";
+
+	for (ptr = value; *ptr; ++ptr) {
+		if (*ptr == ';' || *ptr == '#')
+			return "\"";
+	}
+
+	if (ptr[-1] == ' ')
+		return "\"";
+
+	return "";
+}
+
+struct write_data {
+	git_filebuf *file;
+	unsigned int in_section : 1,
+		preg_replaced : 1;
+	const char *section;
+	const char *name;
+	const regex_t *preg;
+	const char *value;
+};
+
+static int write_line(struct write_data *write_data, const char *line, size_t line_len)
+{
+	int result = git_filebuf_write(write_data->file, line, line_len);
+
+	if (!result && line_len && line[line_len-1] != '\n')
+		result = git_filebuf_printf(write_data->file, "\n");
+
+	return result;
+}
+
+static int write_value(struct write_data *write_data)
+{
+	const char *q;
+	int result;
+
+	q = quotes_for_value(write_data->value);
+	result = git_filebuf_printf(write_data->file,
+		"\t%s = %s%s%s\n", write_data->name, q, write_data->value, q);
+
+	/* If we are updating a single name/value, we're done.  Setting `value`
+	 * to `NULL` will prevent us from trying to write it again later (in
+	 * `write_on_section`) if we see the same section repeated.
+	 */
+	if (!write_data->preg)
+		write_data->value = NULL;
+
+	return result;
+}
+
+static int write_on_section(
+	struct reader **reader,
+	const char *current_section,
+	const char *line,
+	size_t line_len,
+	void *data)
+{
+	struct write_data *write_data = (struct write_data *)data;
+	int result = 0;
+
+	GIT_UNUSED(reader);
+
+	/* If we were previously in the correct section (but aren't anymore)
+	 * and haven't written our value (for a simple name/value set, not
+	 * a multivar), then append it to the end of the section before writing
+	 * the new one.
+	 */
+	if (write_data->in_section && !write_data->preg && write_data->value)
+		result = write_value(write_data);
+
+	write_data->in_section = strcmp(current_section, write_data->section) == 0;
+
+	if (!result)
+		result = write_line(write_data, line, line_len);
+
+	return result;
+}
+
+static int write_on_variable(
+	struct reader **reader,
+	const char *current_section,
+	char *var_name,
+	char *var_value,
+	const char *line,
+	size_t line_len,
+	void *data)
+{
+	struct write_data *write_data = (struct write_data *)data;
+	bool has_matched = false;
+
+	GIT_UNUSED(reader);
+	GIT_UNUSED(current_section);
+
+	/* See if we are to update this name/value pair; first examine name */
+	if (write_data->in_section &&
+		strcasecmp(write_data->name, var_name) == 0)
+		has_matched = true;
+
+	/* If we have a regex to match the value, see if it matches */
+	if (has_matched && write_data->preg != NULL)
+		has_matched = (regexec(write_data->preg, var_value, 0, NULL, 0) == 0);
+
+	git__free(var_name);
+	git__free(var_value);
+
+	/* If this isn't the name/value we're looking for, simply dump the
+	 * existing data back out and continue on.
+	 */
+	if (!has_matched)
+		return write_line(write_data, line, line_len);
+
+	write_data->preg_replaced = 1;
+
+	/* If value is NULL, we are deleting this value; write nothing. */
+	if (!write_data->value)
+		return 0;
+
+	return write_value(write_data);
+}
+
+static int write_on_comment(struct reader **reader, const char *line, size_t line_len, void *data)
+{
+	struct write_data *write_data;
+
+	GIT_UNUSED(reader);
+
+	write_data = (struct write_data *)data;
+	return write_line(write_data, line, line_len);
+}
+
+static int write_on_eof(struct reader **reader, void *data)
+{
+	struct write_data *write_data = (struct write_data *)data;
+	int result = 0;
+
+	GIT_UNUSED(reader);
+
+	/* If we are at the EOF and have not written our value (again, for a
+	 * simple name/value set, not a multivar) then we have never seen the
+	 * section in question and should create a new section and write the
+	 * value.
+	 */
+	if ((!write_data->preg || !write_data->preg_replaced) && write_data->value) {
+		if ((result = write_section(write_data->file, write_data->section)) == 0)
+			result = write_value(write_data);
+	}
+
+	return result;
+}
+
+/*
+ * This is pretty much the parsing, except we write out anything we don't have
+ */
+static int config_write(diskfile_backend *cfg, const char *key, const regex_t *preg, const char* value)
+{
+	int result;
+	char *section, *name, *ldot;
+	git_filebuf file = GIT_FILEBUF_INIT;
+	struct reader *reader = git_array_get(cfg->readers, 0);
+	struct write_data write_data;
+
+	/* Lock the file */
+	if ((result = git_filebuf_open(
+		&file, cfg->file_path, 0, GIT_CONFIG_FILE_MODE)) < 0) {
+			git_buf_free(&reader->buffer);
+			return result;
+	}
+
+	/* We need to read in our own config file */
+	result = git_futils_readbuffer(&reader->buffer, cfg->file_path);
+
+	/* Initialise the reading position */
+	if (result == GIT_ENOTFOUND) {
+		reader->read_ptr = NULL;
+		reader->eof = 1;
+		git_buf_clear(&reader->buffer);
+	} else if (result == 0) {
+		reader->read_ptr = reader->buffer.ptr;
+		reader->eof = 0;
+	} else {
+		git_filebuf_cleanup(&file);
+		return -1; /* OS error when reading the file */
+	}
+
+	ldot = strrchr(key, '.');
+	name = ldot + 1;
+	section = git__strndup(key, ldot - key);
+
+	write_data.file = &file;
+	write_data.section = section;
+	write_data.in_section = 0;
+	write_data.preg_replaced = 0;
+	write_data.name = name;
+	write_data.preg = preg;
+	write_data.value = value;
+
+	result = config_parse(reader, write_on_section, write_on_variable, write_on_comment, write_on_eof, &write_data);
+	git__free(section);
+
+	if (result < 0) {
+		git_filebuf_cleanup(&file);
+		goto done;
+	}
+
+	/* refresh stats - if this errors, then commit will error too */
+	(void)git_filebuf_stats(&reader->file_mtime, &reader->file_size, &file);
+
+	result = git_filebuf_commit(&file);
+	git_buf_free(&reader->buffer);
+
+done:
+	git_buf_free(&reader->buffer);
+	return result;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/config_file.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/config_file.h
new file mode 100755
index 0000000..0d8bf74
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/config_file.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_config_file_h__
+#define INCLUDE_config_file_h__
+
+#include "git2/config.h"
+
+GIT_INLINE(int) git_config_file_open(git_config_backend *cfg, unsigned int level)
+{
+	return cfg->open(cfg, level);
+}
+
+GIT_INLINE(void) git_config_file_free(git_config_backend *cfg)
+{
+	if (cfg)
+		cfg->free(cfg);
+}
+
+GIT_INLINE(int) git_config_file_get_string(
+	git_config_entry **out, git_config_backend *cfg, const char *name)
+{
+	return cfg->get(cfg, name, out);
+}
+
+GIT_INLINE(int) git_config_file_set_string(
+	git_config_backend *cfg, const char *name, const char *value)
+{
+	return cfg->set(cfg, name, value);
+}
+
+GIT_INLINE(int) git_config_file_delete(
+	git_config_backend *cfg, const char *name)
+{
+	return cfg->del(cfg, name);
+}
+
+GIT_INLINE(int) git_config_file_foreach(
+	git_config_backend *cfg,
+	int (*fn)(const git_config_entry *entry, void *data),
+	void *data)
+{
+	return git_config_backend_foreach_match(cfg, NULL, fn, data);
+}
+
+GIT_INLINE(int) git_config_file_foreach_match(
+	git_config_backend *cfg,
+	const char *regexp,
+	int (*fn)(const git_config_entry *entry, void *data),
+	void *data)
+{
+	return git_config_backend_foreach_match(cfg, regexp, fn, data);
+}
+
+extern int git_config_file_normalize_section(char *start, char *end);
+
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/crlf.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/crlf.c
new file mode 100755
index 0000000..f391137
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/crlf.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2/attr.h"
+#include "git2/blob.h"
+#include "git2/index.h"
+#include "git2/sys/filter.h"
+
+#include "common.h"
+#include "fileops.h"
+#include "hash.h"
+#include "filter.h"
+#include "buf_text.h"
+#include "repository.h"
+
+struct crlf_attrs {
+	int crlf_action;
+	int eol;
+	int auto_crlf;
+	int safe_crlf;
+};
+
+struct crlf_filter {
+	git_filter f;
+};
+
+static int check_crlf(const char *value)
+{
+	if (GIT_ATTR_TRUE(value))
+		return GIT_CRLF_TEXT;
+
+	if (GIT_ATTR_FALSE(value))
+		return GIT_CRLF_BINARY;
+
+	if (GIT_ATTR_UNSPECIFIED(value))
+		return GIT_CRLF_GUESS;
+
+	if (strcmp(value, "input") == 0)
+		return GIT_CRLF_INPUT;
+
+	if (strcmp(value, "auto") == 0)
+		return GIT_CRLF_AUTO;
+
+	return GIT_CRLF_GUESS;
+}
+
+static int check_eol(const char *value)
+{
+	if (GIT_ATTR_UNSPECIFIED(value))
+		return GIT_EOL_UNSET;
+
+	if (strcmp(value, "lf") == 0)
+		return GIT_EOL_LF;
+
+	if (strcmp(value, "crlf") == 0)
+		return GIT_EOL_CRLF;
+
+	return GIT_EOL_UNSET;
+}
+
+static int crlf_input_action(struct crlf_attrs *ca)
+{
+	if (ca->crlf_action == GIT_CRLF_BINARY)
+		return GIT_CRLF_BINARY;
+
+	if (ca->eol == GIT_EOL_LF)
+		return GIT_CRLF_INPUT;
+
+	if (ca->eol == GIT_EOL_CRLF)
+		return GIT_CRLF_CRLF;
+
+	return ca->crlf_action;
+}
+
+static int has_cr_in_index(const git_filter_source *src)
+{
+	git_repository *repo = git_filter_source_repo(src);
+	const char *path = git_filter_source_path(src);
+	git_index *index;
+	const git_index_entry *entry;
+	git_blob *blob;
+	const void *blobcontent;
+	git_off_t blobsize;
+	bool found_cr;
+
+	if (!path)
+		return false;
+
+	if (git_repository_index__weakptr(&index, repo) < 0) {
+		giterr_clear();
+		return false;
+	}
+
+	if (!(entry = git_index_get_bypath(index, path, 0)) &&
+		!(entry = git_index_get_bypath(index, path, 1)))
+		return false;
+
+	if (!S_ISREG(entry->mode)) /* don't crlf filter non-blobs */
+		return true;
+
+	if (git_blob_lookup(&blob, repo, &entry->id) < 0)
+		return false;
+
+	blobcontent = git_blob_rawcontent(blob);
+	blobsize    = git_blob_rawsize(blob);
+	if (!git__is_sizet(blobsize))
+		blobsize = (size_t)-1;
+
+	found_cr = (blobcontent != NULL &&
+		blobsize > 0 &&
+		memchr(blobcontent, '\r', (size_t)blobsize) != NULL);
+
+	git_blob_free(blob);
+	return found_cr;
+}
+
+static int crlf_apply_to_odb(
+	struct crlf_attrs *ca,
+	git_buf *to,
+	const git_buf *from,
+	const git_filter_source *src)
+{
+	/* Empty file? Nothing to do */
+	if (!git_buf_len(from))
+		return 0;
+
+	/* Heuristics to see if we can skip the conversion.
+	 * Straight from Core Git.
+	 */
+	if (ca->crlf_action == GIT_CRLF_AUTO || ca->crlf_action == GIT_CRLF_GUESS) {
+		git_buf_text_stats stats;
+
+		/* Check heuristics for binary vs text - returns true if binary */
+		if (git_buf_text_gather_stats(&stats, from, false))
+			return GIT_PASSTHROUGH;
+
+		/* If there are no CR characters to filter out, then just pass */
+		if (!stats.cr)
+			return GIT_PASSTHROUGH;
+
+		/* If safecrlf is enabled, sanity-check the result. */
+		if (stats.cr != stats.crlf || stats.lf != stats.crlf) {
+			switch (ca->safe_crlf) {
+			case GIT_SAFE_CRLF_FAIL:
+				giterr_set(
+					GITERR_FILTER, "LF would be replaced by CRLF in '%s'",
+					git_filter_source_path(src));
+				return -1;
+			case GIT_SAFE_CRLF_WARN:
+				/* TODO: issue warning when warning API is available */;
+				break;
+			default:
+				break;
+			}
+		}
+
+		/*
+		 * We're currently not going to even try to convert stuff
+		 * that has bare CR characters. Does anybody do that crazy
+		 * stuff?
+		 */
+		if (stats.cr != stats.crlf)
+			return GIT_PASSTHROUGH;
+
+		if (ca->crlf_action == GIT_CRLF_GUESS) {
+			/*
+			 * If the file in the index has any CR in it, do not convert.
+			 * This is the new safer autocrlf handling.
+			 */
+			if (has_cr_in_index(src))
+				return GIT_PASSTHROUGH;
+		}
+
+		if (!stats.cr)
+			return GIT_PASSTHROUGH;
+	}
+
+	/* Actually drop the carriage returns */
+	return git_buf_text_crlf_to_lf(to, from);
+}
+
+static const char *line_ending(struct crlf_attrs *ca)
+{
+	switch (ca->crlf_action) {
+	case GIT_CRLF_BINARY:
+	case GIT_CRLF_INPUT:
+		return "\n";
+
+	case GIT_CRLF_CRLF:
+		return "\r\n";
+
+	case GIT_CRLF_GUESS:
+		if (ca->auto_crlf == GIT_AUTO_CRLF_FALSE)
+			return "\n";
+		break;
+
+	case GIT_CRLF_AUTO:
+	case GIT_CRLF_TEXT:
+		break;
+
+	default:
+		goto line_ending_error;
+	}
+
+	if (ca->auto_crlf == GIT_AUTO_CRLF_TRUE)
+		return "\r\n";
+	else if (ca->auto_crlf == GIT_AUTO_CRLF_INPUT)
+		return "\n";
+	else if (ca->eol == GIT_EOL_UNSET)
+		return GIT_EOL_NATIVE == GIT_EOL_CRLF ? "\r\n" : "\n";
+	else if (ca->eol == GIT_EOL_LF)
+		return "\n";
+	else if (ca->eol == GIT_EOL_CRLF)
+		return "\r\n";
+
+line_ending_error:
+	giterr_set(GITERR_INVALID, "Invalid input to line ending filter");
+	return NULL;
+}
+
+static int crlf_apply_to_workdir(
+	struct crlf_attrs *ca, git_buf *to, const git_buf *from)
+{
+	git_buf_text_stats stats;
+	const char *workdir_ending = NULL;
+	bool is_binary;
+
+	/* Empty file? Nothing to do. */
+	if (git_buf_len(from) == 0)
+		return 0;
+
+	/* Determine proper line ending */
+	workdir_ending = line_ending(ca);
+	if (!workdir_ending)
+		return -1;
+
+	/* only LF->CRLF conversion is supported, do nothing on LF platforms */
+	if (strcmp(workdir_ending, "\r\n") != 0)
+		return GIT_PASSTHROUGH;
+
+	/* If there are no LFs, or all LFs are part of a CRLF, nothing to do */
+	is_binary = git_buf_text_gather_stats(&stats, from, false);
+
+	if (stats.lf == 0 || stats.lf == stats.crlf)
+		return GIT_PASSTHROUGH;
+
+	if (ca->crlf_action == GIT_CRLF_AUTO ||
+		ca->crlf_action == GIT_CRLF_GUESS) {
+
+		/* If we have any existing CR or CRLF line endings, do nothing */
+		if (ca->crlf_action == GIT_CRLF_GUESS &&
+			stats.cr > 0 && stats.crlf > 0)
+			return GIT_PASSTHROUGH;
+
+		/* If we have bare CR characters, do nothing */
+		if (stats.cr != stats.crlf)
+			return GIT_PASSTHROUGH;
+
+		/* Don't filter binary files */
+		if (is_binary)
+			return GIT_PASSTHROUGH;
+	}
+
+	return git_buf_text_lf_to_crlf(to, from);
+}
+
+static int crlf_check(
+	git_filter        *self,
+	void              **payload, /* points to NULL ptr on entry, may be set */
+	const git_filter_source *src,
+	const char **attr_values)
+{
+	int error;
+	struct crlf_attrs ca;
+
+	GIT_UNUSED(self);
+
+	if (!attr_values) {
+		ca.crlf_action = GIT_CRLF_GUESS;
+		ca.eol = GIT_EOL_UNSET;
+	} else {
+		ca.crlf_action = check_crlf(attr_values[2]); /* text */
+		if (ca.crlf_action == GIT_CRLF_GUESS)
+			ca.crlf_action = check_crlf(attr_values[0]); /* clrf */
+		ca.eol = check_eol(attr_values[1]); /* eol */
+	}
+	ca.auto_crlf = GIT_AUTO_CRLF_DEFAULT;
+
+	/*
+	 * Use the core Git logic to see if we should perform CRLF for this file
+	 * based on its attributes & the value of `core.autocrlf`
+	 */
+	ca.crlf_action = crlf_input_action(&ca);
+
+	if (ca.crlf_action == GIT_CRLF_BINARY)
+		return GIT_PASSTHROUGH;
+
+	if (ca.crlf_action == GIT_CRLF_GUESS ||
+		((ca.crlf_action == GIT_CRLF_AUTO || ca.crlf_action == GIT_CRLF_TEXT) &&
+		git_filter_source_mode(src) == GIT_FILTER_SMUDGE)) {
+
+		error = git_repository__cvar(
+			&ca.auto_crlf, git_filter_source_repo(src), GIT_CVAR_AUTO_CRLF);
+		if (error < 0)
+			return error;
+
+		if (ca.crlf_action == GIT_CRLF_GUESS &&
+			ca.auto_crlf == GIT_AUTO_CRLF_FALSE)
+			return GIT_PASSTHROUGH;
+
+		if (ca.auto_crlf == GIT_AUTO_CRLF_INPUT &&
+			git_filter_source_mode(src) == GIT_FILTER_SMUDGE)
+			return GIT_PASSTHROUGH;
+	}
+
+	if (git_filter_source_mode(src) == GIT_FILTER_CLEAN) {
+		error = git_repository__cvar(
+			&ca.safe_crlf, git_filter_source_repo(src), GIT_CVAR_SAFE_CRLF);
+		if (error < 0)
+			return error;
+
+		/* downgrade FAIL to WARN if ALLOW_UNSAFE option is used */
+		if ((git_filter_source_flags(src) & GIT_FILTER_ALLOW_UNSAFE) &&
+			ca.safe_crlf == GIT_SAFE_CRLF_FAIL)
+			ca.safe_crlf = GIT_SAFE_CRLF_WARN;
+	}
+
+	*payload = git__malloc(sizeof(ca));
+	GITERR_CHECK_ALLOC(*payload);
+	memcpy(*payload, &ca, sizeof(ca));
+
+	return 0;
+}
+
+static int crlf_apply(
+	git_filter    *self,
+	void         **payload, /* may be read and/or set */
+	git_buf       *to,
+	const git_buf *from,
+	const git_filter_source *src)
+{
+	/* initialize payload in case `check` was bypassed */
+	if (!*payload) {
+		int error = crlf_check(self, payload, src, NULL);
+		if (error < 0 && error != GIT_PASSTHROUGH)
+			return error;
+	}
+
+	if (git_filter_source_mode(src) == GIT_FILTER_SMUDGE)
+		return crlf_apply_to_workdir(*payload, to, from);
+	else
+		return crlf_apply_to_odb(*payload, to, from, src);
+}
+
+static void crlf_cleanup(
+	git_filter *self,
+	void       *payload)
+{
+	GIT_UNUSED(self);
+	git__free(payload);
+}
+
+git_filter *git_crlf_filter_new(void)
+{
+	struct crlf_filter *f = git__calloc(1, sizeof(struct crlf_filter));
+	if (f == NULL)
+		return NULL;
+
+	f->f.version = GIT_FILTER_VERSION;
+	f->f.attributes = "crlf eol text";
+	f->f.initialize = NULL;
+	f->f.shutdown = git_filter_free;
+	f->f.check    = crlf_check;
+	f->f.apply    = crlf_apply;
+	f->f.cleanup  = crlf_cleanup;
+
+	return (git_filter *)f;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/curl_stream.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/curl_stream.c
new file mode 100755
index 0000000..ca06c20
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/curl_stream.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifdef GIT_CURL
+
+#include <curl/curl.h>
+
+#include "stream.h"
+#include "git2/transport.h"
+#include "buffer.h"
+#include "vector.h"
+
+typedef struct {
+	git_stream parent;
+	CURL *handle;
+	curl_socket_t socket;
+	char curl_error[CURL_ERROR_SIZE + 1];
+	git_cert_x509 cert_info;
+	git_strarray cert_info_strings;
+} curl_stream;
+
+static int seterr_curl(curl_stream *s)
+{
+	giterr_set(GITERR_NET, "curl error: %s\n", s->curl_error);
+	return -1;
+}
+
+static int curls_connect(git_stream *stream)
+{
+	curl_stream *s = (curl_stream *) stream;
+	long sockextr;
+	int failed_cert = 0;
+	CURLcode res;
+	res = curl_easy_perform(s->handle);
+
+	if (res != CURLE_OK && res != CURLE_PEER_FAILED_VERIFICATION)
+		return seterr_curl(s);
+	if (res == CURLE_PEER_FAILED_VERIFICATION)
+		failed_cert = 1;
+
+	if ((res = curl_easy_getinfo(s->handle, CURLINFO_LASTSOCKET, &sockextr)) != CURLE_OK)
+		return seterr_curl(s);
+
+	s->socket = sockextr;
+
+	if (s->parent.encrypted && failed_cert)
+		return GIT_ECERTIFICATE;
+
+	return 0;
+}
+
+static int curls_certificate(git_cert **out, git_stream *stream)
+{
+	int error;
+	CURLcode res;
+	struct curl_slist *slist;
+	struct curl_certinfo *certinfo;
+	git_vector strings = GIT_VECTOR_INIT;
+	curl_stream *s = (curl_stream *) stream;
+
+	if ((res = curl_easy_getinfo(s->handle, CURLINFO_CERTINFO, &certinfo)) != CURLE_OK)
+		return seterr_curl(s);
+
+	/* No information is available, can happen with SecureTransport */
+	if (certinfo->num_of_certs == 0) {
+		s->cert_info.cert_type = GIT_CERT_NONE;
+		s->cert_info.data      = NULL;
+		s->cert_info.len       = 0;
+		return 0;
+	}
+
+	if ((error = git_vector_init(&strings, 8, NULL)) < 0)
+		return error;
+
+	for (slist = certinfo->certinfo[0]; slist; slist = slist->next) {
+		char *str = git__strdup(slist->data);
+		GITERR_CHECK_ALLOC(str);
+	}
+
+	/* Copy the contents of the vector into a strarray so we can expose them */
+	s->cert_info_strings.strings = (char **) strings.contents;
+	s->cert_info_strings.count   = strings.length;
+
+	s->cert_info.cert_type = GIT_CERT_STRARRAY;
+	s->cert_info.data      = &s->cert_info_strings;
+	s->cert_info.len       = strings.length;
+
+	*out = (git_cert *) &s->cert_info;
+
+	return 0;
+}
+
+static int curls_set_proxy(git_stream *stream, const char *proxy_url)
+{
+	CURLcode res;
+	curl_stream *s = (curl_stream *) stream;
+
+	if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXY, proxy_url)) != CURLE_OK)
+		return seterr_curl(s);
+
+	return 0;
+}
+
+static int wait_for(curl_socket_t fd, bool reading)
+{
+	int ret;
+	fd_set infd, outfd, errfd;
+
+	FD_ZERO(&infd);
+	FD_ZERO(&outfd);
+	FD_ZERO(&errfd);
+
+	FD_SET(fd, &errfd);
+	if (reading)
+		FD_SET(fd, &infd);
+	else
+		FD_SET(fd, &outfd);
+
+	if ((ret = select(fd + 1, &infd, &outfd, &errfd, NULL)) < 0) {
+		giterr_set(GITERR_OS, "error in select");
+		return -1;
+	}
+
+	return 0;
+}
+
+static ssize_t curls_write(git_stream *stream, const char *data, size_t len, int flags)
+{
+	int error;
+	size_t off = 0, sent;
+	CURLcode res;
+	curl_stream *s = (curl_stream *) stream;
+
+	GIT_UNUSED(flags);
+
+	do {
+		if ((error = wait_for(s->socket, false)) < 0)
+			return error;
+
+		res = curl_easy_send(s->handle, data + off, len - off, &sent);
+		if (res == CURLE_OK)
+			off += sent;
+	} while ((res == CURLE_OK || res == CURLE_AGAIN) && off < len);
+
+	if (res != CURLE_OK)
+		return seterr_curl(s);
+
+	return len;
+}
+
+static ssize_t curls_read(git_stream *stream, void *data, size_t len)
+{
+	int error;
+	size_t read;
+	CURLcode res;
+	curl_stream *s = (curl_stream *) stream;
+
+	do {
+		if ((error = wait_for(s->socket, true)) < 0)
+			return error;
+
+		res = curl_easy_recv(s->handle, data, len, &read);
+	} while (res == CURLE_AGAIN);
+
+	if (res != CURLE_OK)
+		return seterr_curl(s);
+
+	return read;
+}
+
+static int curls_close(git_stream *stream)
+{
+	curl_stream *s = (curl_stream *) stream;
+
+	if (!s->handle)
+		return 0;
+
+	curl_easy_cleanup(s->handle);
+	s->handle = NULL;
+	s->socket = 0;
+
+	return 0;
+}
+
+static void curls_free(git_stream *stream)
+{
+	curl_stream *s = (curl_stream *) stream;
+
+	curls_close(stream);
+	git_strarray_free(&s->cert_info_strings);
+	git__free(s);
+}
+
+int git_curl_stream_new(git_stream **out, const char *host, const char *port)
+{
+	curl_stream *st;
+	CURL *handle;
+	int iport = 0, error;
+
+	st = git__calloc(1, sizeof(curl_stream));
+	GITERR_CHECK_ALLOC(st);
+
+	handle = curl_easy_init();
+	if (handle == NULL) {
+		giterr_set(GITERR_NET, "failed to create curl handle");
+		return -1;
+	}
+
+	if ((error = git__strtol32(&iport, port, NULL, 10)) < 0)
+		return error;
+
+	curl_easy_setopt(handle, CURLOPT_URL, host);
+	curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, st->curl_error);
+	curl_easy_setopt(handle, CURLOPT_PORT, iport);
+	curl_easy_setopt(handle, CURLOPT_CONNECT_ONLY, 1);
+	curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 1);
+	curl_easy_setopt(handle, CURLOPT_CERTINFO, 1);
+	curl_easy_setopt(handle, CURLOPT_HTTPPROXYTUNNEL, 1);
+	curl_easy_setopt(handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
+
+	/* curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); */
+
+	st->parent.version = GIT_STREAM_VERSION;
+	st->parent.encrypted = 0; /* we don't encrypt ourselves */
+	st->parent.proxy_support = 1;
+	st->parent.connect = curls_connect;
+	st->parent.certificate = curls_certificate;
+	st->parent.set_proxy = curls_set_proxy;
+	st->parent.read = curls_read;
+	st->parent.write = curls_write;
+	st->parent.close = curls_close;
+	st->parent.free = curls_free;
+	st->handle = handle;
+
+	*out = (git_stream *) st;
+	return 0;
+}
+
+#else
+
+#include "stream.h"
+
+int git_curl_stream_new(git_stream **out, const char *host, const char *port)
+{
+	GIT_UNUSED(out);
+	GIT_UNUSED(host);
+	GIT_UNUSED(port);
+
+	giterr_set(GITERR_NET, "curl is not supported in this version");
+	return -1;
+}
+
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/curl_stream.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/curl_stream.h
new file mode 100755
index 0000000..283f0fe
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/curl_stream.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_curl_stream_h__
+#define INCLUDE_curl_stream_h__
+
+#include "git2/sys/stream.h"
+
+extern int git_curl_stream_new(git_stream **out, const char *host, const char *port);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/date.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/date.c
new file mode 100755
index 0000000..0e1b31a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/date.c
@@ -0,0 +1,904 @@
+/*
+ * GIT - The information manager from hell
+ *
+ * Copyright (C) Linus Torvalds, 2005
+ */
+
+#include "common.h"
+
+#ifndef GIT_WIN32
+#include <sys/time.h>
+#endif
+
+#include "util.h"
+#include "cache.h"
+#include "posix.h"
+
+#include <ctype.h>
+#include <time.h>
+
+typedef enum {
+	DATE_NORMAL = 0,
+	DATE_RELATIVE,
+	DATE_SHORT,
+	DATE_LOCAL,
+	DATE_ISO8601,
+	DATE_RFC2822,
+	DATE_RAW
+} date_mode;
+
+/*
+ * This is like mktime, but without normalization of tm_wday and tm_yday.
+ */
+static git_time_t tm_to_time_t(const struct tm *tm)
+{
+	static const int mdays[] = {
+	    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+	};
+	int year = tm->tm_year - 70;
+	int month = tm->tm_mon;
+	int day = tm->tm_mday;
+
+	if (year < 0 || year > 129) /* algo only works for 1970-2099 */
+		return -1;
+	if (month < 0 || month > 11) /* array bounds */
+		return -1;
+	if (month < 2 || (year + 2) % 4)
+		day--;
+	if (tm->tm_hour < 0 || tm->tm_min < 0 || tm->tm_sec < 0)
+		return -1;
+	return (year * 365 + (year + 1) / 4 + mdays[month] + day) * 24*60*60UL +
+		tm->tm_hour * 60*60 + tm->tm_min * 60 + tm->tm_sec;
+}
+
+static const char *month_names[] = {
+	"January", "February", "March", "April", "May", "June",
+	"July", "August", "September", "October", "November", "December"
+};
+
+static const char *weekday_names[] = {
+	"Sundays", "Mondays", "Tuesdays", "Wednesdays", "Thursdays", "Fridays", "Saturdays"
+};
+
+
+
+/*
+ * Check these. And note how it doesn't do the summer-time conversion.
+ *
+ * In my world, it's always summer, and things are probably a bit off
+ * in other ways too.
+ */
+static const struct {
+	const char *name;
+	int offset;
+	int dst;
+} timezone_names[] = {
+	{ "IDLW", -12, 0, },	/* International Date Line West */
+	{ "NT",   -11, 0, },	/* Nome */
+	{ "CAT",  -10, 0, },	/* Central Alaska */
+	{ "HST",  -10, 0, },	/* Hawaii Standard */
+	{ "HDT",  -10, 1, },	/* Hawaii Daylight */
+	{ "YST",   -9, 0, },	/* Yukon Standard */
+	{ "YDT",   -9, 1, },	/* Yukon Daylight */
+	{ "PST",   -8, 0, },	/* Pacific Standard */
+	{ "PDT",   -8, 1, },	/* Pacific Daylight */
+	{ "MST",   -7, 0, },	/* Mountain Standard */
+	{ "MDT",   -7, 1, },	/* Mountain Daylight */
+	{ "CST",   -6, 0, },	/* Central Standard */
+	{ "CDT",   -6, 1, },	/* Central Daylight */
+	{ "EST",   -5, 0, },	/* Eastern Standard */
+	{ "EDT",   -5, 1, },	/* Eastern Daylight */
+	{ "AST",   -3, 0, },	/* Atlantic Standard */
+	{ "ADT",   -3, 1, },	/* Atlantic Daylight */
+	{ "WAT",   -1, 0, },	/* West Africa */
+
+	{ "GMT",    0, 0, },	/* Greenwich Mean */
+	{ "UTC",    0, 0, },	/* Universal (Coordinated) */
+	{ "Z",      0, 0, },    /* Zulu, alias for UTC */
+
+	{ "WET",    0, 0, },	/* Western European */
+	{ "BST",    0, 1, },	/* British Summer */
+	{ "CET",   +1, 0, },	/* Central European */
+	{ "MET",   +1, 0, },	/* Middle European */
+	{ "MEWT",  +1, 0, },	/* Middle European Winter */
+	{ "MEST",  +1, 1, },	/* Middle European Summer */
+	{ "CEST",  +1, 1, },	/* Central European Summer */
+	{ "MESZ",  +1, 1, },	/* Middle European Summer */
+	{ "FWT",   +1, 0, },	/* French Winter */
+	{ "FST",   +1, 1, },	/* French Summer */
+	{ "EET",   +2, 0, },	/* Eastern Europe */
+	{ "EEST",  +2, 1, },	/* Eastern European Daylight */
+	{ "WAST",  +7, 0, },	/* West Australian Standard */
+	{ "WADT",  +7, 1, },	/* West Australian Daylight */
+	{ "CCT",   +8, 0, },	/* China Coast */
+	{ "JST",   +9, 0, },	/* Japan Standard */
+	{ "EAST", +10, 0, },	/* Eastern Australian Standard */
+	{ "EADT", +10, 1, },	/* Eastern Australian Daylight */
+	{ "GST",  +10, 0, },	/* Guam Standard */
+	{ "NZT",  +12, 0, },	/* New Zealand */
+	{ "NZST", +12, 0, },	/* New Zealand Standard */
+	{ "NZDT", +12, 1, },	/* New Zealand Daylight */
+	{ "IDLE", +12, 0, },	/* International Date Line East */
+};
+
+static size_t match_string(const char *date, const char *str)
+{
+	size_t i = 0;
+
+	for (i = 0; *date; date++, str++, i++) {
+		if (*date == *str)
+			continue;
+		if (toupper(*date) == toupper(*str))
+			continue;
+		if (!isalnum(*date))
+			break;
+		return 0;
+	}
+	return i;
+}
+
+static int skip_alpha(const char *date)
+{
+	int i = 0;
+	do {
+		i++;
+	} while (isalpha(date[i]));
+	return i;
+}
+
+/*
+* Parse month, weekday, or timezone name
+*/
+static size_t match_alpha(const char *date, struct tm *tm, int *offset)
+{
+	unsigned int i;
+
+	for (i = 0; i < 12; i++) {
+		size_t match = match_string(date, month_names[i]);
+		if (match >= 3) {
+			tm->tm_mon = i;
+			return match;
+		}
+	}
+
+	for (i = 0; i < 7; i++) {
+		size_t match = match_string(date, weekday_names[i]);
+		if (match >= 3) {
+			tm->tm_wday = i;
+			return match;
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(timezone_names); i++) {
+		size_t match = match_string(date, timezone_names[i].name);
+		if (match >= 3 || match == strlen(timezone_names[i].name)) {
+			int off = timezone_names[i].offset;
+
+			/* This is bogus, but we like summer */
+			off += timezone_names[i].dst;
+
+			/* Only use the tz name offset if we don't have anything better */
+			if (*offset == -1)
+				*offset = 60*off;
+
+			return match;
+		}
+	}
+
+	if (match_string(date, "PM") == 2) {
+		tm->tm_hour = (tm->tm_hour % 12) + 12;
+		return 2;
+	}
+
+	if (match_string(date, "AM") == 2) {
+		tm->tm_hour = (tm->tm_hour % 12) + 0;
+		return 2;
+	}
+
+	/* BAD */
+	return skip_alpha(date);
+}
+
+static int is_date(int year, int month, int day, struct tm *now_tm, time_t now, struct tm *tm)
+{
+	if (month > 0 && month < 13 && day > 0 && day < 32) {
+		struct tm check = *tm;
+		struct tm *r = (now_tm ? &check : tm);
+		time_t specified;
+
+		r->tm_mon = month - 1;
+		r->tm_mday = day;
+		if (year == -1) {
+			if (!now_tm)
+				return 1;
+			r->tm_year = now_tm->tm_year;
+		}
+		else if (year >= 1970 && year < 2100)
+			r->tm_year = year - 1900;
+		else if (year > 70 && year < 100)
+			r->tm_year = year;
+		else if (year < 38)
+			r->tm_year = year + 100;
+		else
+			return 0;
+		if (!now_tm)
+			return 1;
+
+		specified = tm_to_time_t(r);
+
+		/* Be it commit time or author time, it does not make
+		 * sense to specify timestamp way into the future.  Make
+		 * sure it is not later than ten days from now...
+		 */
+		if (now + 10*24*3600 < specified)
+			return 0;
+		tm->tm_mon = r->tm_mon;
+		tm->tm_mday = r->tm_mday;
+		if (year != -1)
+			tm->tm_year = r->tm_year;
+		return 1;
+	}
+	return 0;
+}
+
+static size_t match_multi_number(unsigned long num, char c, const char *date, char *end, struct tm *tm)
+{
+	time_t now;
+	struct tm now_tm;
+	struct tm *refuse_future;
+	long num2, num3;
+
+	num2 = strtol(end+1, &end, 10);
+	num3 = -1;
+	if (*end == c && isdigit(end[1]))
+		num3 = strtol(end+1, &end, 10);
+
+	/* Time? Date? */
+	switch (c) {
+	case ':':
+		if (num3 < 0)
+			num3 = 0;
+		if (num < 25 && num2 >= 0 && num2 < 60 && num3 >= 0 && num3 <= 60) {
+			tm->tm_hour = num;
+			tm->tm_min = num2;
+			tm->tm_sec = num3;
+			break;
+		}
+		return 0;
+
+	case '-':
+	case '/':
+	case '.':
+		now = time(NULL);
+		refuse_future = NULL;
+		if (p_gmtime_r(&now, &now_tm))
+			refuse_future = &now_tm;
+
+		if (num > 70) {
+			/* yyyy-mm-dd? */
+			if (is_date(num, num2, num3, refuse_future, now, tm))
+				break;
+			/* yyyy-dd-mm? */
+			if (is_date(num, num3, num2, refuse_future, now, tm))
+				break;
+		}
+		/* Our eastern European friends say dd.mm.yy[yy]
+		 * is the norm there, so giving precedence to
+		 * mm/dd/yy[yy] form only when separator is not '.'
+		 */
+		if (c != '.' &&
+		    is_date(num3, num, num2, refuse_future, now, tm))
+			break;
+		/* European dd.mm.yy[yy] or funny US dd/mm/yy[yy] */
+		if (is_date(num3, num2, num, refuse_future, now, tm))
+			break;
+		/* Funny European mm.dd.yy */
+		if (c == '.' &&
+		    is_date(num3, num, num2, refuse_future, now, tm))
+			break;
+		return 0;
+	}
+	return end - date;
+}
+
+/*
+ * Have we filled in any part of the time/date yet?
+ * We just do a binary 'and' to see if the sign bit
+ * is set in all the values.
+ */
+static int nodate(struct tm *tm)
+{
+	return (tm->tm_year &
+		tm->tm_mon &
+		tm->tm_mday &
+		tm->tm_hour &
+		tm->tm_min &
+		tm->tm_sec) < 0;
+}
+
+/*
+ * We've seen a digit. Time? Year? Date?
+ */
+static size_t match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt)
+{
+	size_t n;
+	char *end;
+	unsigned long num;
+
+	num = strtoul(date, &end, 10);
+
+	/*
+	 * Seconds since 1970? We trigger on that for any numbers with
+	 * more than 8 digits. This is because we don't want to rule out
+	 * numbers like 20070606 as a YYYYMMDD date.
+	 */
+	if (num >= 100000000 && nodate(tm)) {
+		time_t time = num;
+		if (p_gmtime_r(&time, tm)) {
+			*tm_gmt = 1;
+			return end - date;
+		}
+	}
+
+	/*
+	 * Check for special formats: num[-.:/]num[same]num
+	 */
+	switch (*end) {
+	case ':':
+	case '.':
+	case '/':
+	case '-':
+		if (isdigit(end[1])) {
+			size_t match = match_multi_number(num, *end, date, end, tm);
+			if (match)
+				return match;
+		}
+	}
+
+	/*
+	 * None of the special formats? Try to guess what
+	 * the number meant. We use the number of digits
+	 * to make a more educated guess..
+	 */
+	n = 0;
+	do {
+		n++;
+	} while (isdigit(date[n]));
+
+	/* Four-digit year or a timezone? */
+	if (n == 4) {
+		if (num <= 1400 && *offset == -1) {
+			unsigned int minutes = num % 100;
+			unsigned int hours = num / 100;
+			*offset = hours*60 + minutes;
+		} else if (num > 1900 && num < 2100)
+			tm->tm_year = num - 1900;
+		return n;
+	}
+
+	/*
+	 * Ignore lots of numerals. We took care of 4-digit years above.
+	 * Days or months must be one or two digits.
+	 */
+	if (n > 2)
+		return n;
+
+	/*
+	 * NOTE! We will give precedence to day-of-month over month or
+	 * year numbers in the 1-12 range. So 05 is always "mday 5",
+	 * unless we already have a mday..
+	 *
+	 * IOW, 01 Apr 05 parses as "April 1st, 2005".
+	 */
+	if (num > 0 && num < 32 && tm->tm_mday < 0) {
+		tm->tm_mday = num;
+		return n;
+	}
+
+	/* Two-digit year? */
+	if (n == 2 && tm->tm_year < 0) {
+		if (num < 10 && tm->tm_mday >= 0) {
+			tm->tm_year = num + 100;
+			return n;
+		}
+		if (num >= 70) {
+			tm->tm_year = num;
+			return n;
+		}
+	}
+
+	if (num > 0 && num < 13 && tm->tm_mon < 0)
+		tm->tm_mon = num-1;
+
+	return n;
+}
+
+static size_t match_tz(const char *date, int *offp)
+{
+	char *end;
+	int hour = strtoul(date + 1, &end, 10);
+	size_t n = end - (date + 1);
+	int min = 0;
+
+	if (n == 4) {
+		/* hhmm */
+		min = hour % 100;
+		hour = hour / 100;
+	} else if (n != 2) {
+		min = 99; /* random stuff */
+	} else if (*end == ':') {
+		/* hh:mm? */
+		min = strtoul(end + 1, &end, 10);
+		if (end - (date + 1) != 5)
+			min = 99; /* random stuff */
+	} /* otherwise we parsed "hh" */
+
+	/*
+	 * Don't accept any random stuff. Even though some places have
+	 * offset larger than 12 hours (e.g. Pacific/Kiritimati is at
+	 * UTC+14), there is something wrong if hour part is much
+	 * larger than that. We might also want to check that the
+	 * minutes are divisible by 15 or something too. (Offset of
+	 * Kathmandu, Nepal is UTC+5:45)
+	 */
+	if (min < 60 && hour < 24) {
+		int offset = hour * 60 + min;
+		if (*date == '-')
+			offset = -offset;
+		*offp = offset;
+	}
+	return end - date;
+}
+
+/*
+ * Parse a string like "0 +0000" as ancient timestamp near epoch, but
+ * only when it appears not as part of any other string.
+ */
+static int match_object_header_date(const char *date, git_time_t *timestamp, int *offset)
+{
+	char *end;
+	unsigned long stamp;
+	int ofs;
+
+	if (*date < '0' || '9' <= *date)
+		return -1;
+	stamp = strtoul(date, &end, 10);
+	if (*end != ' ' || stamp == ULONG_MAX || (end[1] != '+' && end[1] != '-'))
+		return -1;
+	date = end + 2;
+	ofs = strtol(date, &end, 10);
+	if ((*end != '\0' && (*end != '\n')) || end != date + 4)
+		return -1;
+	ofs = (ofs / 100) * 60 + (ofs % 100);
+	if (date[-1] == '-')
+		ofs = -ofs;
+	*timestamp = stamp;
+	*offset = ofs;
+	return 0;
+}
+
+/* Gr. strptime is crap for this; it doesn't have a way to require RFC2822
+   (i.e. English) day/month names, and it doesn't work correctly with %z. */
+static int parse_date_basic(const char *date, git_time_t *timestamp, int *offset)
+{
+	struct tm tm;
+	int tm_gmt;
+	git_time_t dummy_timestamp;
+	int dummy_offset;
+
+	if (!timestamp)
+		timestamp = &dummy_timestamp;
+	if (!offset)
+		offset = &dummy_offset;
+
+	memset(&tm, 0, sizeof(tm));
+	tm.tm_year = -1;
+	tm.tm_mon = -1;
+	tm.tm_mday = -1;
+	tm.tm_isdst = -1;
+	tm.tm_hour = -1;
+	tm.tm_min = -1;
+	tm.tm_sec = -1;
+	*offset = -1;
+	tm_gmt = 0;
+
+	if (*date == '@' &&
+	    !match_object_header_date(date + 1, timestamp, offset))
+		return 0; /* success */
+	for (;;) {
+		size_t match = 0;
+		unsigned char c = *date;
+
+		/* Stop at end of string or newline */
+		if (!c || c == '\n')
+			break;
+
+		if (isalpha(c))
+			match = match_alpha(date, &tm, offset);
+		else if (isdigit(c))
+			match = match_digit(date, &tm, offset, &tm_gmt);
+		else if ((c == '-' || c == '+') && isdigit(date[1]))
+			match = match_tz(date, offset);
+
+		if (!match) {
+			/* BAD */
+			match = 1;
+		}
+
+		date += match;
+	}
+
+	/* mktime uses local timezone */
+	*timestamp = tm_to_time_t(&tm);
+	if (*offset == -1)
+		*offset = (int)((time_t)*timestamp - mktime(&tm)) / 60;
+
+	if (*timestamp == (git_time_t)-1)
+		return -1;
+
+	if (!tm_gmt)
+		*timestamp -= *offset * 60;
+	return 0; /* success */
+}
+
+
+/*
+ * Relative time update (eg "2 days ago").  If we haven't set the time
+ * yet, we need to set it from current time.
+ */
+static git_time_t update_tm(struct tm *tm, struct tm *now, unsigned long sec)
+{
+	time_t n;
+
+	if (tm->tm_mday < 0)
+		tm->tm_mday = now->tm_mday;
+	if (tm->tm_mon < 0)
+		tm->tm_mon = now->tm_mon;
+	if (tm->tm_year < 0) {
+		tm->tm_year = now->tm_year;
+		if (tm->tm_mon > now->tm_mon)
+			tm->tm_year--;
+	}
+
+	n = mktime(tm) - sec;
+	p_localtime_r(&n, tm);
+	return n;
+}
+
+static void date_now(struct tm *tm, struct tm *now, int *num)
+{
+   GIT_UNUSED(num);
+	update_tm(tm, now, 0);
+}
+
+static void date_yesterday(struct tm *tm, struct tm *now, int *num)
+{
+   GIT_UNUSED(num);
+	update_tm(tm, now, 24*60*60);
+}
+
+static void date_time(struct tm *tm, struct tm *now, int hour)
+{
+	if (tm->tm_hour < hour)
+		date_yesterday(tm, now, NULL);
+	tm->tm_hour = hour;
+	tm->tm_min = 0;
+	tm->tm_sec = 0;
+}
+
+static void date_midnight(struct tm *tm, struct tm *now, int *num)
+{
+   GIT_UNUSED(num);
+	date_time(tm, now, 0);
+}
+
+static void date_noon(struct tm *tm, struct tm *now, int *num)
+{
+   GIT_UNUSED(num);
+	date_time(tm, now, 12);
+}
+
+static void date_tea(struct tm *tm, struct tm *now, int *num)
+{
+   GIT_UNUSED(num);
+	date_time(tm, now, 17);
+}
+
+static void date_pm(struct tm *tm, struct tm *now, int *num)
+{
+	int hour, n = *num;
+	*num = 0;
+   GIT_UNUSED(now);
+
+	hour = tm->tm_hour;
+	if (n) {
+		hour = n;
+		tm->tm_min = 0;
+		tm->tm_sec = 0;
+	}
+	tm->tm_hour = (hour % 12) + 12;
+}
+
+static void date_am(struct tm *tm, struct tm *now, int *num)
+{
+	int hour, n = *num;
+	*num = 0;
+   GIT_UNUSED(now);
+
+	hour = tm->tm_hour;
+	if (n) {
+		hour = n;
+		tm->tm_min = 0;
+		tm->tm_sec = 0;
+	}
+	tm->tm_hour = (hour % 12);
+}
+
+static void date_never(struct tm *tm, struct tm *now, int *num)
+{
+	time_t n = 0;
+   GIT_UNUSED(now);
+   GIT_UNUSED(num);
+	p_localtime_r(&n, tm);
+}
+
+static const struct special {
+	const char *name;
+	void (*fn)(struct tm *, struct tm *, int *);
+} special[] = {
+	{ "yesterday", date_yesterday },
+	{ "noon", date_noon },
+	{ "midnight", date_midnight },
+	{ "tea", date_tea },
+	{ "PM", date_pm },
+	{ "AM", date_am },
+	{ "never", date_never },
+	{ "now", date_now },
+	{ NULL }
+};
+
+static const char *number_name[] = {
+	"zero", "one", "two", "three", "four",
+	"five", "six", "seven", "eight", "nine", "ten",
+};
+
+static const struct typelen {
+	const char *type;
+	int length;
+} typelen[] = {
+	{ "seconds", 1 },
+	{ "minutes", 60 },
+	{ "hours", 60*60 },
+	{ "days", 24*60*60 },
+	{ "weeks", 7*24*60*60 },
+	{ NULL }
+};
+
+static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm *now, int *num, int *touched)
+{
+	const struct typelen *tl;
+	const struct special *s;
+	const char *end = date;
+	int i;
+
+	while (isalpha(*++end))
+		/* scan to non-alpha */;
+
+	for (i = 0; i < 12; i++) {
+		size_t match = match_string(date, month_names[i]);
+		if (match >= 3) {
+			tm->tm_mon = i;
+			*touched = 1;
+			return end;
+		}
+	}
+
+	for (s = special; s->name; s++) {
+		size_t len = strlen(s->name);
+		if (match_string(date, s->name) == len) {
+			s->fn(tm, now, num);
+			*touched = 1;
+			return end;
+		}
+	}
+
+	if (!*num) {
+		for (i = 1; i < 11; i++) {
+			size_t len = strlen(number_name[i]);
+			if (match_string(date, number_name[i]) == len) {
+				*num = i;
+				*touched = 1;
+				return end;
+			}
+		}
+		if (match_string(date, "last") == 4) {
+			*num = 1;
+			*touched = 1;
+		}
+		return end;
+	}
+
+	tl = typelen;
+	while (tl->type) {
+		size_t len = strlen(tl->type);
+		if (match_string(date, tl->type) >= len-1) {
+			update_tm(tm, now, tl->length * *num);
+			*num = 0;
+			*touched = 1;
+			return end;
+		}
+		tl++;
+	}
+
+	for (i = 0; i < 7; i++) {
+		size_t match = match_string(date, weekday_names[i]);
+		if (match >= 3) {
+			int diff, n = *num -1;
+			*num = 0;
+
+			diff = tm->tm_wday - i;
+			if (diff <= 0)
+				n++;
+			diff += 7*n;
+
+			update_tm(tm, now, diff * 24 * 60 * 60);
+			*touched = 1;
+			return end;
+		}
+	}
+
+	if (match_string(date, "months") >= 5) {
+		int n;
+		update_tm(tm, now, 0); /* fill in date fields if needed */
+		n = tm->tm_mon - *num;
+		*num = 0;
+		while (n < 0) {
+			n += 12;
+			tm->tm_year--;
+		}
+		tm->tm_mon = n;
+		*touched = 1;
+		return end;
+	}
+
+	if (match_string(date, "years") >= 4) {
+		update_tm(tm, now, 0); /* fill in date fields if needed */
+		tm->tm_year -= *num;
+		*num = 0;
+		*touched = 1;
+		return end;
+	}
+
+	return end;
+}
+
+static const char *approxidate_digit(const char *date, struct tm *tm, int *num)
+{
+	char *end;
+	unsigned long number = strtoul(date, &end, 10);
+
+	switch (*end) {
+	case ':':
+	case '.':
+	case '/':
+	case '-':
+		if (isdigit(end[1])) {
+			size_t match = match_multi_number(number, *end, date, end, tm);
+			if (match)
+				return date + match;
+		}
+	}
+
+	/* Accept zero-padding only for small numbers ("Dec 02", never "Dec 0002") */
+	if (date[0] != '0' || end - date <= 2)
+		*num = number;
+	return end;
+}
+
+/*
+ * Do we have a pending number at the end, or when
+ * we see a new one? Let's assume it's a month day,
+ * as in "Dec 6, 1992"
+ */
+static void pending_number(struct tm *tm, int *num)
+{
+	int number = *num;
+
+	if (number) {
+		*num = 0;
+		if (tm->tm_mday < 0 && number < 32)
+			tm->tm_mday = number;
+		else if (tm->tm_mon < 0 && number < 13)
+			tm->tm_mon = number-1;
+		else if (tm->tm_year < 0) {
+			if (number > 1969 && number < 2100)
+				tm->tm_year = number - 1900;
+			else if (number > 69 && number < 100)
+				tm->tm_year = number;
+			else if (number < 38)
+				tm->tm_year = 100 + number;
+			/* We mess up for number = 00 ? */
+		}
+	}
+}
+
+static git_time_t approxidate_str(const char *date,
+	time_t time_sec,
+	int *error_ret)
+{
+	int number = 0;
+	int touched = 0;
+	struct tm tm = {0}, now;
+
+	p_localtime_r(&time_sec, &tm);
+	now = tm;
+
+	tm.tm_year = -1;
+	tm.tm_mon = -1;
+	tm.tm_mday = -1;
+
+	for (;;) {
+		unsigned char c = *date;
+		if (!c)
+			break;
+		date++;
+		if (isdigit(c)) {
+			pending_number(&tm, &number);
+			date = approxidate_digit(date-1, &tm, &number);
+			touched = 1;
+			continue;
+		}
+		if (isalpha(c))
+			date = approxidate_alpha(date-1, &tm, &now, &number, &touched);
+	}
+	pending_number(&tm, &number);
+	if (!touched)
+		*error_ret = 1;
+	return update_tm(&tm, &now, 0);
+}
+
+int git__date_parse(git_time_t *out, const char *date)
+{
+	time_t time_sec;
+	git_time_t timestamp;
+	int offset, error_ret=0;
+
+	if (!parse_date_basic(date, &timestamp, &offset)) {
+		*out = timestamp;
+		return 0;
+	}
+
+	if (time(&time_sec) == -1)
+		return -1;
+
+	*out = approxidate_str(date, time_sec, &error_ret);
+   return error_ret;
+}
+
+int git__date_rfc2822_fmt(char *out, size_t len, const git_time *date)
+{
+	int written;
+	struct tm gmt;
+	time_t t;
+
+	assert(out && date);
+
+	t = (time_t) (date->time + date->offset * 60);
+
+	if (p_gmtime_r (&t, &gmt) == NULL)
+		return -1;
+
+	written = p_snprintf(out, len, "%.3s, %u %.3s %.4u %02u:%02u:%02u %+03d%02d",
+		weekday_names[gmt.tm_wday],
+		gmt.tm_mday,
+		month_names[gmt.tm_mon],
+		gmt.tm_year + 1900,
+		gmt.tm_hour, gmt.tm_min, gmt.tm_sec,
+		date->offset / 60, date->offset % 60);
+
+	if (written < 0 || (written > (int) len - 1))
+		return -1;
+
+	return 0;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/delta-apply.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/delta-apply.c
new file mode 100755
index 0000000..89745fa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/delta-apply.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "git2/odb.h"
+#include "delta-apply.h"
+
+/*
+ * This file was heavily cribbed from BinaryDelta.java in JGit, which
+ * itself was heavily cribbed from <code>patch-delta.c</code> in the
+ * GIT project.	The original delta patching code was written by
+ * Nicolas Pitre <nico at cam.org>.
+ */
+
+static int hdr_sz(
+	size_t *size,
+	const unsigned char **delta,
+	const unsigned char *end)
+{
+	const unsigned char *d = *delta;
+	size_t r = 0;
+	unsigned int c, shift = 0;
+
+	do {
+		if (d == end)
+			return -1;
+		c = *d++;
+		r |= (c & 0x7f) << shift;
+		shift += 7;
+	} while (c & 0x80);
+	*delta = d;
+	*size = r;
+	return 0;
+}
+
+int git__delta_read_header(
+	const unsigned char *delta,
+	size_t delta_len,
+	size_t *base_sz,
+	size_t *res_sz)
+{
+	const unsigned char *delta_end = delta + delta_len;
+	if ((hdr_sz(base_sz, &delta, delta_end) < 0) ||
+	    (hdr_sz(res_sz, &delta, delta_end) < 0))
+		return -1;
+	return 0;
+}
+
+int git__delta_apply(
+	git_rawobj *out,
+	const unsigned char *base,
+	size_t base_len,
+	const unsigned char *delta,
+	size_t delta_len)
+{
+	const unsigned char *delta_end = delta + delta_len;
+	size_t base_sz, res_sz, alloc_sz;
+	unsigned char *res_dp;
+
+	/* Check that the base size matches the data we were given;
+	 * if not we would underflow while accessing data from the
+	 * base object, resulting in data corruption or segfault.
+	 */
+	if ((hdr_sz(&base_sz, &delta, delta_end) < 0) || (base_sz != base_len)) {
+		giterr_set(GITERR_INVALID, "Failed to apply delta. Base size does not match given data");
+		return -1;
+	}
+
+	if (hdr_sz(&res_sz, &delta, delta_end) < 0) {
+		giterr_set(GITERR_INVALID, "Failed to apply delta. Base size does not match given data");
+		return -1;
+	}
+
+	GITERR_CHECK_ALLOC_ADD(&alloc_sz, res_sz, 1);
+	res_dp = git__malloc(alloc_sz);
+	GITERR_CHECK_ALLOC(res_dp);
+
+	res_dp[res_sz] = '\0';
+	out->data = res_dp;
+	out->len = res_sz;
+
+	while (delta < delta_end) {
+		unsigned char cmd = *delta++;
+		if (cmd & 0x80) {
+			/* cmd is a copy instruction; copy from the base.
+			 */
+			size_t off = 0, len = 0;
+
+			if (cmd & 0x01) off = *delta++;
+			if (cmd & 0x02) off |= *delta++ << 8;
+			if (cmd & 0x04) off |= *delta++ << 16;
+			if (cmd & 0x08) off |= *delta++ << 24;
+
+			if (cmd & 0x10) len = *delta++;
+			if (cmd & 0x20) len |= *delta++ << 8;
+			if (cmd & 0x40) len |= *delta++ << 16;
+			if (!len)		len = 0x10000;
+
+			if (base_len < off + len || res_sz < len)
+				goto fail;
+			memcpy(res_dp, base + off, len);
+			res_dp += len;
+			res_sz -= len;
+
+		} else if (cmd) {
+			/* cmd is a literal insert instruction; copy from
+			 * the delta stream itself.
+			 */
+			if (delta_end - delta < cmd || res_sz < cmd)
+				goto fail;
+			memcpy(res_dp, delta, cmd);
+			delta += cmd;
+			res_dp += cmd;
+			res_sz -= cmd;
+
+		} else {
+			/* cmd == 0 is reserved for future encodings.
+			 */
+			goto fail;
+		}
+	}
+
+	if (delta != delta_end || res_sz)
+		goto fail;
+	return 0;
+
+fail:
+	git__free(out->data);
+	out->data = NULL;
+	giterr_set(GITERR_INVALID, "Failed to apply delta");
+	return -1;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/delta-apply.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/delta-apply.h
new file mode 100755
index 0000000..d7d99d0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/delta-apply.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_delta_apply_h__
+#define INCLUDE_delta_apply_h__
+
+#include "odb.h"
+
+/**
+ * Apply a git binary delta to recover the original content.
+ *
+ * @param out the output buffer to receive the original data.
+ *		Only out->data and out->len are populated, as this is
+ *		the only information available in the delta.
+ * @param base the base to copy from during copy instructions.
+ * @param base_len number of bytes available at base.
+ * @param delta the delta to execute copy/insert instructions from.
+ * @param delta_len total number of bytes in the delta.
+ * @return
+ * - 0 on a successful delta unpack.
+ * - GIT_ERROR if the delta is corrupt or doesn't match the base.
+ */
+extern int git__delta_apply(
+	git_rawobj *out,
+	const unsigned char *base,
+	size_t base_len,
+	const unsigned char *delta,
+	size_t delta_len);
+
+/**
+ * Read the header of a git binary delta.
+ *
+ * @param delta the delta to execute copy/insert instructions from.
+ * @param delta_len total number of bytes in the delta.
+ * @param base_sz pointer to store the base size field.
+ * @param res_sz pointer to store the result size field.
+ * @return
+ * - 0 on a successful decoding the header.
+ * - GIT_ERROR if the delta is corrupt.
+ */
+extern int git__delta_read_header(
+	const unsigned char *delta,
+	size_t delta_len,
+	size_t *base_sz,
+	size_t *res_sz);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/delta.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/delta.c
new file mode 100755
index 0000000..d72d820
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/delta.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "delta.h"
+
+/* maximum hash entry list for the same hash bucket */
+#define HASH_LIMIT 64
+
+#define RABIN_SHIFT 23
+#define RABIN_WINDOW 16
+
+static const unsigned int T[256] = {
+	0x00000000, 0xab59b4d1, 0x56b369a2, 0xfdeadd73, 0x063f6795, 0xad66d344,
+	0x508c0e37, 0xfbd5bae6, 0x0c7ecf2a, 0xa7277bfb, 0x5acda688, 0xf1941259,
+	0x0a41a8bf, 0xa1181c6e, 0x5cf2c11d, 0xf7ab75cc, 0x18fd9e54, 0xb3a42a85,
+	0x4e4ef7f6, 0xe5174327, 0x1ec2f9c1, 0xb59b4d10, 0x48719063, 0xe32824b2,
+	0x1483517e, 0xbfdae5af, 0x423038dc, 0xe9698c0d, 0x12bc36eb, 0xb9e5823a,
+	0x440f5f49, 0xef56eb98, 0x31fb3ca8, 0x9aa28879, 0x6748550a, 0xcc11e1db,
+	0x37c45b3d, 0x9c9defec, 0x6177329f, 0xca2e864e, 0x3d85f382, 0x96dc4753,
+	0x6b369a20, 0xc06f2ef1, 0x3bba9417, 0x90e320c6, 0x6d09fdb5, 0xc6504964,
+	0x2906a2fc, 0x825f162d, 0x7fb5cb5e, 0xd4ec7f8f, 0x2f39c569, 0x846071b8,
+	0x798aaccb, 0xd2d3181a, 0x25786dd6, 0x8e21d907, 0x73cb0474, 0xd892b0a5,
+	0x23470a43, 0x881ebe92, 0x75f463e1, 0xdeadd730, 0x63f67950, 0xc8afcd81,
+	0x354510f2, 0x9e1ca423, 0x65c91ec5, 0xce90aa14, 0x337a7767, 0x9823c3b6,
+	0x6f88b67a, 0xc4d102ab, 0x393bdfd8, 0x92626b09, 0x69b7d1ef, 0xc2ee653e,
+	0x3f04b84d, 0x945d0c9c, 0x7b0be704, 0xd05253d5, 0x2db88ea6, 0x86e13a77,
+	0x7d348091, 0xd66d3440, 0x2b87e933, 0x80de5de2, 0x7775282e, 0xdc2c9cff,
+	0x21c6418c, 0x8a9ff55d, 0x714a4fbb, 0xda13fb6a, 0x27f92619, 0x8ca092c8,
+	0x520d45f8, 0xf954f129, 0x04be2c5a, 0xafe7988b, 0x5432226d, 0xff6b96bc,
+	0x02814bcf, 0xa9d8ff1e, 0x5e738ad2, 0xf52a3e03, 0x08c0e370, 0xa39957a1,
+	0x584ced47, 0xf3155996, 0x0eff84e5, 0xa5a63034, 0x4af0dbac, 0xe1a96f7d,
+	0x1c43b20e, 0xb71a06df, 0x4ccfbc39, 0xe79608e8, 0x1a7cd59b, 0xb125614a,
+	0x468e1486, 0xedd7a057, 0x103d7d24, 0xbb64c9f5, 0x40b17313, 0xebe8c7c2,
+	0x16021ab1, 0xbd5bae60, 0x6cb54671, 0xc7ecf2a0, 0x3a062fd3, 0x915f9b02,
+	0x6a8a21e4, 0xc1d39535, 0x3c394846, 0x9760fc97, 0x60cb895b, 0xcb923d8a,
+	0x3678e0f9, 0x9d215428, 0x66f4eece, 0xcdad5a1f, 0x3047876c, 0x9b1e33bd,
+	0x7448d825, 0xdf116cf4, 0x22fbb187, 0x89a20556, 0x7277bfb0, 0xd92e0b61,
+	0x24c4d612, 0x8f9d62c3, 0x7836170f, 0xd36fa3de, 0x2e857ead, 0x85dcca7c,
+	0x7e09709a, 0xd550c44b, 0x28ba1938, 0x83e3ade9, 0x5d4e7ad9, 0xf617ce08,
+	0x0bfd137b, 0xa0a4a7aa, 0x5b711d4c, 0xf028a99d, 0x0dc274ee, 0xa69bc03f,
+	0x5130b5f3, 0xfa690122, 0x0783dc51, 0xacda6880, 0x570fd266, 0xfc5666b7,
+	0x01bcbbc4, 0xaae50f15, 0x45b3e48d, 0xeeea505c, 0x13008d2f, 0xb85939fe,
+	0x438c8318, 0xe8d537c9, 0x153feaba, 0xbe665e6b, 0x49cd2ba7, 0xe2949f76,
+	0x1f7e4205, 0xb427f6d4, 0x4ff24c32, 0xe4abf8e3, 0x19412590, 0xb2189141,
+	0x0f433f21, 0xa41a8bf0, 0x59f05683, 0xf2a9e252, 0x097c58b4, 0xa225ec65,
+	0x5fcf3116, 0xf49685c7, 0x033df00b, 0xa86444da, 0x558e99a9, 0xfed72d78,
+	0x0502979e, 0xae5b234f, 0x53b1fe3c, 0xf8e84aed, 0x17bea175, 0xbce715a4,
+	0x410dc8d7, 0xea547c06, 0x1181c6e0, 0xbad87231, 0x4732af42, 0xec6b1b93,
+	0x1bc06e5f, 0xb099da8e, 0x4d7307fd, 0xe62ab32c, 0x1dff09ca, 0xb6a6bd1b,
+	0x4b4c6068, 0xe015d4b9, 0x3eb80389, 0x95e1b758, 0x680b6a2b, 0xc352defa,
+	0x3887641c, 0x93ded0cd, 0x6e340dbe, 0xc56db96f, 0x32c6cca3, 0x999f7872,
+	0x6475a501, 0xcf2c11d0, 0x34f9ab36, 0x9fa01fe7, 0x624ac294, 0xc9137645,
+	0x26459ddd, 0x8d1c290c, 0x70f6f47f, 0xdbaf40ae, 0x207afa48, 0x8b234e99,
+	0x76c993ea, 0xdd90273b, 0x2a3b52f7, 0x8162e626, 0x7c883b55, 0xd7d18f84,
+	0x2c043562, 0x875d81b3, 0x7ab75cc0, 0xd1eee811
+};
+
+static const unsigned int U[256] = {
+	0x00000000, 0x7eb5200d, 0x5633f4cb, 0x2886d4c6, 0x073e5d47, 0x798b7d4a,
+	0x510da98c, 0x2fb88981, 0x0e7cba8e, 0x70c99a83, 0x584f4e45, 0x26fa6e48,
+	0x0942e7c9, 0x77f7c7c4, 0x5f711302, 0x21c4330f, 0x1cf9751c, 0x624c5511,
+	0x4aca81d7, 0x347fa1da, 0x1bc7285b, 0x65720856, 0x4df4dc90, 0x3341fc9d,
+	0x1285cf92, 0x6c30ef9f, 0x44b63b59, 0x3a031b54, 0x15bb92d5, 0x6b0eb2d8,
+	0x4388661e, 0x3d3d4613, 0x39f2ea38, 0x4747ca35, 0x6fc11ef3, 0x11743efe,
+	0x3eccb77f, 0x40799772, 0x68ff43b4, 0x164a63b9, 0x378e50b6, 0x493b70bb,
+	0x61bda47d, 0x1f088470, 0x30b00df1, 0x4e052dfc, 0x6683f93a, 0x1836d937,
+	0x250b9f24, 0x5bbebf29, 0x73386bef, 0x0d8d4be2, 0x2235c263, 0x5c80e26e,
+	0x740636a8, 0x0ab316a5, 0x2b7725aa, 0x55c205a7, 0x7d44d161, 0x03f1f16c,
+	0x2c4978ed, 0x52fc58e0, 0x7a7a8c26, 0x04cfac2b, 0x73e5d470, 0x0d50f47d,
+	0x25d620bb, 0x5b6300b6, 0x74db8937, 0x0a6ea93a, 0x22e87dfc, 0x5c5d5df1,
+	0x7d996efe, 0x032c4ef3, 0x2baa9a35, 0x551fba38, 0x7aa733b9, 0x041213b4,
+	0x2c94c772, 0x5221e77f, 0x6f1ca16c, 0x11a98161, 0x392f55a7, 0x479a75aa,
+	0x6822fc2b, 0x1697dc26, 0x3e1108e0, 0x40a428ed, 0x61601be2, 0x1fd53bef,
+	0x3753ef29, 0x49e6cf24, 0x665e46a5, 0x18eb66a8, 0x306db26e, 0x4ed89263,
+	0x4a173e48, 0x34a21e45, 0x1c24ca83, 0x6291ea8e, 0x4d29630f, 0x339c4302,
+	0x1b1a97c4, 0x65afb7c9, 0x446b84c6, 0x3adea4cb, 0x1258700d, 0x6ced5000,
+	0x4355d981, 0x3de0f98c, 0x15662d4a, 0x6bd30d47, 0x56ee4b54, 0x285b6b59,
+	0x00ddbf9f, 0x7e689f92, 0x51d01613, 0x2f65361e, 0x07e3e2d8, 0x7956c2d5,
+	0x5892f1da, 0x2627d1d7, 0x0ea10511, 0x7014251c, 0x5facac9d, 0x21198c90,
+	0x099f5856, 0x772a785b, 0x4c921c31, 0x32273c3c, 0x1aa1e8fa, 0x6414c8f7,
+	0x4bac4176, 0x3519617b, 0x1d9fb5bd, 0x632a95b0, 0x42eea6bf, 0x3c5b86b2,
+	0x14dd5274, 0x6a687279, 0x45d0fbf8, 0x3b65dbf5, 0x13e30f33, 0x6d562f3e,
+	0x506b692d, 0x2ede4920, 0x06589de6, 0x78edbdeb, 0x5755346a, 0x29e01467,
+	0x0166c0a1, 0x7fd3e0ac, 0x5e17d3a3, 0x20a2f3ae, 0x08242768, 0x76910765,
+	0x59298ee4, 0x279caee9, 0x0f1a7a2f, 0x71af5a22, 0x7560f609, 0x0bd5d604,
+	0x235302c2, 0x5de622cf, 0x725eab4e, 0x0ceb8b43, 0x246d5f85, 0x5ad87f88,
+	0x7b1c4c87, 0x05a96c8a, 0x2d2fb84c, 0x539a9841, 0x7c2211c0, 0x029731cd,
+	0x2a11e50b, 0x54a4c506, 0x69998315, 0x172ca318, 0x3faa77de, 0x411f57d3,
+	0x6ea7de52, 0x1012fe5f, 0x38942a99, 0x46210a94, 0x67e5399b, 0x19501996,
+	0x31d6cd50, 0x4f63ed5d, 0x60db64dc, 0x1e6e44d1, 0x36e89017, 0x485db01a,
+	0x3f77c841, 0x41c2e84c, 0x69443c8a, 0x17f11c87, 0x38499506, 0x46fcb50b,
+	0x6e7a61cd, 0x10cf41c0, 0x310b72cf, 0x4fbe52c2, 0x67388604, 0x198da609,
+	0x36352f88, 0x48800f85, 0x6006db43, 0x1eb3fb4e, 0x238ebd5d, 0x5d3b9d50,
+	0x75bd4996, 0x0b08699b, 0x24b0e01a, 0x5a05c017, 0x728314d1, 0x0c3634dc,
+	0x2df207d3, 0x534727de, 0x7bc1f318, 0x0574d315, 0x2acc5a94, 0x54797a99,
+	0x7cffae5f, 0x024a8e52, 0x06852279, 0x78300274, 0x50b6d6b2, 0x2e03f6bf,
+	0x01bb7f3e, 0x7f0e5f33, 0x57888bf5, 0x293dabf8, 0x08f998f7, 0x764cb8fa,
+	0x5eca6c3c, 0x207f4c31, 0x0fc7c5b0, 0x7172e5bd, 0x59f4317b, 0x27411176,
+	0x1a7c5765, 0x64c97768, 0x4c4fa3ae, 0x32fa83a3, 0x1d420a22, 0x63f72a2f,
+	0x4b71fee9, 0x35c4dee4, 0x1400edeb, 0x6ab5cde6, 0x42331920, 0x3c86392d,
+	0x133eb0ac, 0x6d8b90a1, 0x450d4467, 0x3bb8646a
+};
+
+struct index_entry {
+	const unsigned char *ptr;
+	unsigned int val;
+	struct index_entry *next;
+};
+
+struct git_delta_index {
+	unsigned long memsize;
+	const void *src_buf;
+	unsigned long src_size;
+	unsigned int hash_mask;
+	struct index_entry *hash[GIT_FLEX_ARRAY];
+};
+
+static int lookup_index_alloc(
+	void **out, unsigned long *out_len, size_t entries, size_t hash_count)
+{
+	size_t entries_len, hash_len, index_len;
+
+	GITERR_CHECK_ALLOC_MULTIPLY(&entries_len, entries, sizeof(struct index_entry));
+	GITERR_CHECK_ALLOC_MULTIPLY(&hash_len, hash_count, sizeof(struct index_entry *));
+
+	GITERR_CHECK_ALLOC_ADD(&index_len, sizeof(struct git_delta_index), entries_len);
+	GITERR_CHECK_ALLOC_ADD(&index_len, index_len, hash_len);
+
+	if (!git__is_ulong(index_len)) {
+		giterr_set(GITERR_NOMEMORY, "Overly large delta");
+		return -1;
+	}
+
+	*out = git__malloc(index_len);
+	GITERR_CHECK_ALLOC(*out);
+
+	*out_len = index_len;
+	return 0;
+}
+
+struct git_delta_index *
+git_delta_create_index(const void *buf, unsigned long bufsize)
+{
+	unsigned int i, hsize, hmask, entries, prev_val, *hash_count;
+	const unsigned char *data, *buffer = buf;
+	struct git_delta_index *index;
+	struct index_entry *entry, **hash;
+	void *mem;
+	unsigned long memsize;
+
+	if (!buf || !bufsize)
+		return NULL;
+
+	/* Determine index hash size.  Note that indexing skips the
+	   first byte to allow for optimizing the rabin polynomial
+	   initialization in create_delta(). */
+	entries = (unsigned int)(bufsize - 1) / RABIN_WINDOW;
+	if (bufsize >= 0xffffffffUL) {
+		/*
+		 * Current delta format can't encode offsets into
+		 * reference buffer with more than 32 bits.
+		 */
+		entries = 0xfffffffeU / RABIN_WINDOW;
+	}
+	hsize = entries / 4;
+	for (i = 4; i < 31 && (1u << i) < hsize; i++);
+	hsize = 1 << i;
+	hmask = hsize - 1;
+
+	if (lookup_index_alloc(&mem, &memsize, entries, hsize) < 0)
+		return NULL;
+
+	index = mem;
+	mem = index->hash;
+	hash = mem;
+	mem = hash + hsize;
+	entry = mem;
+
+	index->memsize = memsize;
+	index->src_buf = buf;
+	index->src_size = bufsize;
+	index->hash_mask = hmask;
+	memset(hash, 0, hsize * sizeof(*hash));
+
+	/* allocate an array to count hash entries */
+	hash_count = git__calloc(hsize, sizeof(*hash_count));
+	if (!hash_count) {
+		git__free(index);
+		return NULL;
+	}
+
+	/* then populate the index */
+	prev_val = ~0;
+	for (data = buffer + entries * RABIN_WINDOW - RABIN_WINDOW;
+	     data >= buffer;
+	     data -= RABIN_WINDOW) {
+		unsigned int val = 0;
+		for (i = 1; i <= RABIN_WINDOW; i++)
+			val = ((val << 8) | data[i]) ^ T[val >> RABIN_SHIFT];
+		if (val == prev_val) {
+			/* keep the lowest of consecutive identical blocks */
+			entry[-1].ptr = data + RABIN_WINDOW;
+		} else {
+			prev_val = val;
+			i = val & hmask;
+			entry->ptr = data + RABIN_WINDOW;
+			entry->val = val;
+			entry->next = hash[i];
+			hash[i] = entry++;
+			hash_count[i]++;
+		}
+	}
+
+	/*
+	 * Determine a limit on the number of entries in the same hash
+	 * bucket.  This guard us against patological data sets causing
+	 * really bad hash distribution with most entries in the same hash
+	 * bucket that would bring us to O(m*n) computing costs (m and n
+	 * corresponding to reference and target buffer sizes).
+	 *
+	 * Make sure none of the hash buckets has more entries than
+	 * we're willing to test.  Otherwise we cull the entry list
+	 * uniformly to still preserve a good repartition across
+	 * the reference buffer.
+	 */
+	for (i = 0; i < hsize; i++) {
+		if (hash_count[i] < HASH_LIMIT)
+			continue;
+
+		entry = hash[i];
+		do {
+			struct index_entry *keep = entry;
+			int skip = hash_count[i] / HASH_LIMIT / 2;
+			do {
+				entry = entry->next;
+			} while(--skip && entry);
+			keep->next = entry;
+		} while (entry);
+	}
+	git__free(hash_count);
+
+	return index;
+}
+
+void git_delta_free_index(struct git_delta_index *index)
+{
+	git__free(index);
+}
+
+unsigned long git_delta_sizeof_index(struct git_delta_index *index)
+{
+	if (index)
+		return index->memsize;
+	else
+		return 0;
+}
+
+/*
+ * The maximum size for any opcode sequence, including the initial header
+ * plus rabin window plus biggest copy.
+ */
+#define MAX_OP_SIZE	(5 + 5 + 1 + RABIN_WINDOW + 7)
+
+void *
+git_delta_create(
+	const struct git_delta_index *index,
+	const void *trg_buf,
+	unsigned long trg_size,
+	unsigned long *delta_size,
+	unsigned long max_size)
+{
+	unsigned int i, outpos, outsize, moff, msize, val;
+	int inscnt;
+	const unsigned char *ref_data, *ref_top, *data, *top;
+	unsigned char *out;
+
+	if (!trg_buf || !trg_size)
+		return NULL;
+
+	outpos = 0;
+	outsize = 8192;
+	if (max_size && outsize >= max_size)
+		outsize = (unsigned int)(max_size + MAX_OP_SIZE + 1);
+	out = git__malloc(outsize);
+	if (!out)
+		return NULL;
+
+	/* store reference buffer size */
+	i = index->src_size;
+	while (i >= 0x80) {
+		out[outpos++] = i | 0x80;
+		i >>= 7;
+	}
+	out[outpos++] = i;
+
+	/* store target buffer size */
+	i = trg_size;
+	while (i >= 0x80) {
+		out[outpos++] = i | 0x80;
+		i >>= 7;
+	}
+	out[outpos++] = i;
+
+	ref_data = index->src_buf;
+	ref_top = ref_data + index->src_size;
+	data = trg_buf;
+	top = (const unsigned char *) trg_buf + trg_size;
+
+	outpos++;
+	val = 0;
+	for (i = 0; i < RABIN_WINDOW && data < top; i++, data++) {
+		out[outpos++] = *data;
+		val = ((val << 8) | *data) ^ T[val >> RABIN_SHIFT];
+	}
+	inscnt = i;
+
+	moff = 0;
+	msize = 0;
+	while (data < top) {
+		if (msize < 4096) {
+			struct index_entry *entry;
+			val ^= U[data[-RABIN_WINDOW]];
+			val = ((val << 8) | *data) ^ T[val >> RABIN_SHIFT];
+			i = val & index->hash_mask;
+			for (entry = index->hash[i]; entry; entry = entry->next) {
+				const unsigned char *ref = entry->ptr;
+				const unsigned char *src = data;
+				unsigned int ref_size = (unsigned int)(ref_top - ref);
+				if (entry->val != val)
+					continue;
+				if (ref_size > (unsigned int)(top - src))
+					ref_size = (unsigned int)(top - src);
+				if (ref_size <= msize)
+					break;
+				while (ref_size-- && *src++ == *ref)
+					ref++;
+				if (msize < (unsigned int)(ref - entry->ptr)) {
+					/* this is our best match so far */
+					msize = (unsigned int)(ref - entry->ptr);
+					moff = (unsigned int)(entry->ptr - ref_data);
+					if (msize >= 4096) /* good enough */
+						break;
+				}
+			}
+		}
+
+		if (msize < 4) {
+			if (!inscnt)
+				outpos++;
+			out[outpos++] = *data++;
+			inscnt++;
+			if (inscnt == 0x7f) {
+				out[outpos - inscnt - 1] = inscnt;
+				inscnt = 0;
+			}
+			msize = 0;
+		} else {
+			unsigned int left;
+			unsigned char *op;
+
+			if (inscnt) {
+				while (moff && ref_data[moff-1] == data[-1]) {
+					/* we can match one byte back */
+					msize++;
+					moff--;
+					data--;
+					outpos--;
+					if (--inscnt)
+						continue;
+					outpos--;  /* remove count slot */
+					inscnt--;  /* make it -1 */
+					break;
+				}
+				out[outpos - inscnt - 1] = inscnt;
+				inscnt = 0;
+			}
+
+			/* A copy op is currently limited to 64KB (pack v2) */
+			left = (msize < 0x10000) ? 0 : (msize - 0x10000);
+			msize -= left;
+
+			op = out + outpos++;
+			i = 0x80;
+
+			if (moff & 0x000000ff)
+				out[outpos++] = moff >> 0,  i |= 0x01;
+			if (moff & 0x0000ff00)
+				out[outpos++] = moff >> 8,  i |= 0x02;
+			if (moff & 0x00ff0000)
+				out[outpos++] = moff >> 16, i |= 0x04;
+			if (moff & 0xff000000)
+				out[outpos++] = moff >> 24, i |= 0x08;
+
+			if (msize & 0x00ff)
+				out[outpos++] = msize >> 0, i |= 0x10;
+			if (msize & 0xff00)
+				out[outpos++] = msize >> 8, i |= 0x20;
+
+			*op = i;
+
+			data += msize;
+			moff += msize;
+			msize = left;
+
+			if (msize < 4096) {
+				int j;
+				val = 0;
+				for (j = -RABIN_WINDOW; j < 0; j++)
+					val = ((val << 8) | data[j])
+					      ^ T[val >> RABIN_SHIFT];
+			}
+		}
+
+		if (outpos >= outsize - MAX_OP_SIZE) {
+			void *tmp = out;
+			outsize = outsize * 3 / 2;
+			if (max_size && outsize >= max_size)
+				outsize = max_size + MAX_OP_SIZE + 1;
+			if (max_size && outpos > max_size)
+				break;
+			out = git__realloc(out, outsize);
+			if (!out) {
+				git__free(tmp);
+				return NULL;
+			}
+		}
+	}
+
+	if (inscnt)
+		out[outpos - inscnt - 1] = inscnt;
+
+	if (max_size && outpos > max_size) {
+		git__free(out);
+		return NULL;
+	}
+
+	*delta_size = outpos;
+	return out;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/delta.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/delta.h
new file mode 100755
index 0000000..4ca3279
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/delta.h
@@ -0,0 +1,114 @@
+/*
+ * diff-delta code taken from git.git. See diff-delta.c for details.
+ *
+ */
+#ifndef INCLUDE_git_delta_h__
+#define INCLUDE_git_delta_h__
+
+#include "common.h"
+
+/* opaque object for delta index */
+struct git_delta_index;
+
+/*
+ * create_delta_index: compute index data from given buffer
+ *
+ * This returns a pointer to a struct delta_index that should be passed to
+ * subsequent create_delta() calls, or to free_delta_index().  A NULL pointer
+ * is returned on failure.  The given buffer must not be freed nor altered
+ * before free_delta_index() is called.  The returned pointer must be freed
+ * using free_delta_index().
+ */
+extern struct git_delta_index *
+git_delta_create_index(const void *buf, unsigned long bufsize);
+
+/*
+ * free_delta_index: free the index created by create_delta_index()
+ *
+ * Given pointer must be what create_delta_index() returned, or NULL.
+ */
+extern void git_delta_free_index(struct git_delta_index *index);
+
+/*
+ * sizeof_delta_index: returns memory usage of delta index
+ *
+ * Given pointer must be what create_delta_index() returned, or NULL.
+ */
+extern unsigned long git_delta_sizeof_index(struct git_delta_index *index);
+
+/*
+ * create_delta: create a delta from given index for the given buffer
+ *
+ * This function may be called multiple times with different buffers using
+ * the same delta_index pointer.  If max_delta_size is non-zero and the
+ * resulting delta is to be larger than max_delta_size then NULL is returned.
+ * On success, a non-NULL pointer to the buffer with the delta data is
+ * returned and *delta_size is updated with its size.  The returned buffer
+ * must be freed by the caller.
+ */
+extern void *git_delta_create(
+	const struct git_delta_index *index,
+	const void *buf,
+	unsigned long bufsize,
+	unsigned long *delta_size,
+	unsigned long max_delta_size);
+
+/*
+ * diff_delta: create a delta from source buffer to target buffer
+ *
+ * If max_delta_size is non-zero and the resulting delta is to be larger
+ * than max_delta_size then NULL is returned.  On success, a non-NULL
+ * pointer to the buffer with the delta data is returned and *delta_size is
+ * updated with its size.  The returned buffer must be freed by the caller.
+ */
+GIT_INLINE(void *) git_delta(
+	const void *src_buf, unsigned long src_bufsize,
+	const void *trg_buf, unsigned long trg_bufsize,
+	unsigned long *delta_size,
+	unsigned long max_delta_size)
+{
+	struct git_delta_index *index = git_delta_create_index(src_buf, src_bufsize);
+	if (index) {
+		void *delta = git_delta_create(
+			index, trg_buf, trg_bufsize, delta_size, max_delta_size);
+		git_delta_free_index(index);
+		return delta;
+	}
+	return NULL;
+}
+
+/*
+ * patch_delta: recreate target buffer given source buffer and delta data
+ *
+ * On success, a non-NULL pointer to the target buffer is returned and
+ * *trg_bufsize is updated with its size.  On failure a NULL pointer is
+ * returned.  The returned buffer must be freed by the caller.
+ */
+extern void *git_delta_patch(
+	const void *src_buf, unsigned long src_size,
+	const void *delta_buf, unsigned long delta_size,
+	unsigned long *dst_size);
+
+/* the smallest possible delta size is 4 bytes */
+#define GIT_DELTA_SIZE_MIN	4
+
+/*
+ * This must be called twice on the delta data buffer, first to get the
+ * expected source buffer size, and again to get the target buffer size.
+ */
+GIT_INLINE(unsigned long) git_delta_get_hdr_size(
+	const unsigned char **datap, const unsigned char *top)
+{
+	const unsigned char *data = *datap;
+	unsigned long cmd, size = 0;
+	int i = 0;
+	do {
+		cmd = *data++;
+		size |= (cmd & 0x7f) << i;
+		i += 7;
+	} while (cmd & 0x80 && data < top);
+	*datap = data;
+	return size;
+}
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/describe.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/describe.c
new file mode 100755
index 0000000..48f04e8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/describe.c
@@ -0,0 +1,892 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "git2/describe.h"
+#include "git2/strarray.h"
+#include "git2/diff.h"
+#include "git2/status.h"
+
+#include "common.h"
+#include "commit.h"
+#include "commit_list.h"
+#include "oidmap.h"
+#include "refs.h"
+#include "revwalk.h"
+#include "tag.h"
+#include "vector.h"
+#include "repository.h"
+
+GIT__USE_OIDMAP
+
+/* Ported from https://github.com/git/git/blob/89dde7882f71f846ccd0359756d27bebc31108de/builtin/describe.c */
+
+struct commit_name {
+	git_tag *tag;
+	unsigned prio:2; /* annotated tag = 2, tag = 1, head = 0 */
+	unsigned name_checked:1;
+	git_oid sha1;
+	char *path;
+
+	/* Khash workaround. They original key has to still be reachable */
+	git_oid peeled;
+};
+
+static void *oidmap_value_bykey(git_oidmap *map, const git_oid *key)
+{
+	khint_t pos = git_oidmap_lookup_index(map, key);
+
+	if (!git_oidmap_valid_index(map, pos))
+		return NULL;
+
+	return git_oidmap_value_at(map, pos);
+}
+
+static struct commit_name *find_commit_name(
+	git_oidmap *names,
+	const git_oid *peeled)
+{
+	return (struct commit_name *)(oidmap_value_bykey(names, peeled));
+}
+
+static int replace_name(
+	git_tag **tag,
+	git_repository *repo,
+	struct commit_name *e,
+	unsigned int prio,
+	const git_oid *sha1)
+{
+	git_time_t e_time = 0, t_time = 0;
+
+	if (!e || e->prio < prio)
+		return 1;
+
+	if (e->prio == 2 && prio == 2) {
+		/* Multiple annotated tags point to the same commit.
+		 * Select one to keep based upon their tagger date.
+		 */
+		git_tag *t = NULL;
+
+		if (!e->tag) {
+			if (git_tag_lookup(&t, repo, &e->sha1) < 0)
+				return 1;
+			e->tag = t;
+		}
+
+		if (git_tag_lookup(&t, repo, sha1) < 0)
+			return 0;
+
+		*tag = t;
+
+		if (e->tag->tagger)
+			e_time = e->tag->tagger->when.time;
+
+		if (t->tagger)
+			t_time = t->tagger->when.time;
+
+		if (e_time < t_time)
+			return 1;
+	}
+
+	return 0;
+}
+
+static int add_to_known_names(
+	git_repository *repo,
+	git_oidmap *names,
+	const char *path,
+	const git_oid *peeled,
+	unsigned int prio,
+	const git_oid *sha1)
+{
+	struct commit_name *e = find_commit_name(names, peeled);
+	bool found = (e != NULL);
+
+	git_tag *tag = NULL;
+	if (replace_name(&tag, repo, e, prio, sha1)) {
+		if (!found) {
+			e = git__malloc(sizeof(struct commit_name));
+			GITERR_CHECK_ALLOC(e);
+
+			e->path = NULL;
+			e->tag = NULL;
+		}
+
+		if (e->tag)
+			git_tag_free(e->tag);
+		e->tag = tag;
+		e->prio = prio;
+		e->name_checked = 0;
+		git_oid_cpy(&e->sha1, sha1);
+		git__free(e->path);
+		e->path = git__strdup(path);
+		git_oid_cpy(&e->peeled, peeled);
+
+		if (!found) {
+			int ret;
+
+			git_oidmap_insert(names, &e->peeled, e, ret);
+			if (ret < 0)
+				return -1;
+		}
+	}
+	else
+		git_tag_free(tag);
+
+	return 0;
+}
+
+static int retrieve_peeled_tag_or_object_oid(
+	git_oid *peeled_out,
+	git_oid *ref_target_out,
+	git_repository *repo,
+	const char *refname)
+{
+	git_reference *ref;
+	git_object *peeled = NULL;
+	int error;
+
+	if ((error = git_reference_lookup_resolved(&ref, repo, refname, -1)) < 0)
+		return error;
+
+	if ((error = git_reference_peel(&peeled, ref, GIT_OBJ_ANY)) < 0)
+		goto cleanup;
+
+	git_oid_cpy(ref_target_out, git_reference_target(ref));
+	git_oid_cpy(peeled_out, git_object_id(peeled));
+
+	if (git_oid_cmp(ref_target_out, peeled_out) != 0)
+		error = 1; /* The reference was pointing to a annotated tag */
+	else
+		error = 0; /* Any other object */
+
+cleanup:
+	git_reference_free(ref);
+	git_object_free(peeled);
+	return error;
+}
+
+struct git_describe_result {
+	int dirty;
+	int exact_match;
+	int fallback_to_id;
+	git_oid commit_id;
+	git_repository *repo;
+	struct commit_name *name;
+	struct possible_tag *tag;
+};
+
+struct get_name_data
+{
+	git_describe_options *opts;
+	git_repository *repo;
+	git_oidmap *names;
+	git_describe_result *result;
+};
+
+static int commit_name_dup(struct commit_name **out, struct commit_name *in)
+{
+	struct commit_name *name;
+
+	name = git__malloc(sizeof(struct commit_name));
+	GITERR_CHECK_ALLOC(name);
+
+	memcpy(name, in,  sizeof(struct commit_name));
+	name->tag = NULL;
+	name->path = NULL;
+
+	if (in->tag && git_object_dup((git_object **) &name->tag, (git_object *) in->tag) < 0)
+		return -1;
+
+	name->path = git__strdup(in->path);
+	GITERR_CHECK_ALLOC(name->path);
+
+	*out = name;
+	return 0;
+}
+
+static int get_name(const char *refname, void *payload)
+{
+	struct get_name_data *data;
+	bool is_tag, is_annotated, all;
+	git_oid peeled, sha1;
+	unsigned int prio;
+	int error = 0;
+
+	data = (struct get_name_data *)payload;
+	is_tag = !git__prefixcmp(refname, GIT_REFS_TAGS_DIR);
+	all = data->opts->describe_strategy == GIT_DESCRIBE_ALL;
+
+	/* Reject anything outside refs/tags/ unless --all */
+	if (!all && !is_tag)
+		return 0;
+
+	/* Accept only tags that match the pattern, if given */
+	if (data->opts->pattern && (!is_tag || p_fnmatch(data->opts->pattern,
+		refname + strlen(GIT_REFS_TAGS_DIR), 0)))
+				return 0;
+
+	/* Is it annotated? */
+	if ((error = retrieve_peeled_tag_or_object_oid(
+		&peeled, &sha1, data->repo, refname)) < 0)
+		return error;
+
+	is_annotated = error;
+
+	/*
+	 * By default, we only use annotated tags, but with --tags
+	 * we fall back to lightweight ones (even without --tags,
+	 * we still remember lightweight ones, only to give hints
+	 * in an error message).  --all allows any refs to be used.
+	 */
+	if (is_annotated)
+		prio = 2;
+	else if (is_tag)
+		prio = 1;
+	else
+		prio = 0;
+
+	add_to_known_names(data->repo, data->names,
+		all ? refname + strlen(GIT_REFS_DIR) : refname + strlen(GIT_REFS_TAGS_DIR),
+		&peeled, prio, &sha1);
+	return 0;
+}
+
+struct possible_tag {
+	struct commit_name *name;
+	int depth;
+	int found_order;
+	unsigned flag_within;
+};
+
+static int possible_tag_dup(struct possible_tag **out, struct possible_tag *in)
+{
+	struct possible_tag *tag;
+	int error;
+
+	tag = git__malloc(sizeof(struct possible_tag));
+	GITERR_CHECK_ALLOC(tag);
+
+	memcpy(tag, in, sizeof(struct possible_tag));
+	tag->name = NULL;
+
+	if ((error = commit_name_dup(&tag->name, in->name)) < 0) {
+		git__free(tag);
+		*out = NULL;
+		return error;
+	}
+
+	*out = tag;
+	return 0;
+}
+
+static int compare_pt(const void *a_, const void *b_)
+{
+	struct possible_tag *a = (struct possible_tag *)a_;
+	struct possible_tag *b = (struct possible_tag *)b_;
+	if (a->depth != b->depth)
+		return a->depth - b->depth;
+	if (a->found_order != b->found_order)
+		return a->found_order - b->found_order;
+	return 0;
+}
+
+#define SEEN (1u << 0)
+
+static unsigned long finish_depth_computation(
+	git_pqueue *list,
+	git_revwalk *walk,
+	struct possible_tag *best)
+{
+	unsigned long seen_commits = 0;
+	int error, i;
+
+	while (git_pqueue_size(list) > 0) {
+		git_commit_list_node *c = git_pqueue_pop(list);
+		seen_commits++;
+		if (c->flags & best->flag_within) {
+			size_t index = 0;
+			while (git_pqueue_size(list) > index) {
+				git_commit_list_node *i = git_pqueue_get(list, index);
+				if (!(i->flags & best->flag_within))
+					break;
+				index++;
+			}
+			if (index > git_pqueue_size(list))
+				break;
+		} else
+			best->depth++;
+		for (i = 0; i < c->out_degree; i++) {
+			git_commit_list_node *p = c->parents[i];
+			if ((error = git_commit_list_parse(walk, p)) < 0)
+				return error;
+			if (!(p->flags & SEEN))
+				if ((error = git_pqueue_insert(list, p)) < 0)
+					return error;
+			p->flags |= c->flags;
+		}
+	}
+	return seen_commits;
+}
+
+static int display_name(git_buf *buf, git_repository *repo, struct commit_name *n)
+{
+	if (n->prio == 2 && !n->tag) {
+		if (git_tag_lookup(&n->tag, repo, &n->sha1) < 0) {
+			giterr_set(GITERR_TAG, "Annotated tag '%s' not available", n->path);
+			return -1;
+		}
+	}
+
+	if (n->tag && !n->name_checked) {
+		if (!git_tag_name(n->tag)) {
+			giterr_set(GITERR_TAG, "Annotated tag '%s' has no embedded name", n->path);
+			return -1;
+		}
+
+		/* TODO: Cope with warnings
+		if (strcmp(n->tag->tag, all ? n->path + 5 : n->path))
+			warning(_("tag '%s' is really '%s' here"), n->tag->tag, n->path);
+		*/
+
+		n->name_checked = 1;
+	}
+
+	if (n->tag)
+		git_buf_printf(buf, "%s", git_tag_name(n->tag));
+	else
+		git_buf_printf(buf, "%s", n->path);
+
+	return 0;
+}
+
+static int find_unique_abbrev_size(
+	int *out,
+	git_repository *repo,
+	const git_oid *oid_in,
+	int abbreviated_size)
+{
+	size_t size = abbreviated_size;
+	git_odb *odb;
+	git_oid dummy;
+	int error;
+
+	if ((error = git_repository_odb__weakptr(&odb, repo)) < 0)
+		return error;
+
+	while (size < GIT_OID_HEXSZ) {
+		if ((error = git_odb_exists_prefix(&dummy, odb, oid_in, size)) == 0) {
+			*out = (int) size;
+			return 0;
+		}
+
+		/* If the error wasn't that it's not unique, then it's a proper error */
+		if (error != GIT_EAMBIGUOUS)
+			return error;
+
+		/* Try again with a larger size */
+		size++;
+	}
+
+	/* If we didn't find any shorter prefix, we have to do the whole thing */
+	*out = GIT_OID_HEXSZ;
+	
+	return 0;
+}
+
+static int show_suffix(
+	git_buf *buf,
+	int depth,
+	git_repository *repo,
+	const git_oid* id,
+	size_t abbrev_size)
+{
+	int error, size = 0;
+
+	char hex_oid[GIT_OID_HEXSZ];
+
+	if ((error = find_unique_abbrev_size(&size, repo, id, abbrev_size)) < 0)
+		return error;
+
+	git_oid_fmt(hex_oid, id);
+
+	git_buf_printf(buf, "-%d-g", depth);
+
+	git_buf_put(buf, hex_oid, size);
+
+	return git_buf_oom(buf) ? -1 : 0;
+}
+
+#define MAX_CANDIDATES_TAGS FLAG_BITS - 1
+
+static int describe_not_found(const git_oid *oid, const char *message_format) {
+	char oid_str[GIT_OID_HEXSZ + 1];
+	git_oid_tostr(oid_str, sizeof(oid_str), oid);
+
+	giterr_set(GITERR_DESCRIBE, message_format, oid_str);
+	return GIT_ENOTFOUND;
+}
+
+static int describe(
+	struct get_name_data *data,
+	git_commit *commit)
+{
+	struct commit_name *n;
+	struct possible_tag *best;
+	bool all, tags;
+	git_revwalk *walk = NULL;
+	git_pqueue list;
+	git_commit_list_node *cmit, *gave_up_on = NULL;
+	git_vector all_matches = GIT_VECTOR_INIT;
+	unsigned int match_cnt = 0, annotated_cnt = 0, cur_match;
+	unsigned long seen_commits = 0;	/* TODO: Check long */
+	unsigned int unannotated_cnt = 0;
+	int error;
+
+	if (git_vector_init(&all_matches, MAX_CANDIDATES_TAGS, compare_pt) < 0)
+		return -1;
+
+	if ((error = git_pqueue_init(&list, 0, 2, git_commit_list_time_cmp)) < 0)
+		goto cleanup;
+
+	all = data->opts->describe_strategy == GIT_DESCRIBE_ALL;
+	tags = data->opts->describe_strategy == GIT_DESCRIBE_TAGS;
+
+	git_oid_cpy(&data->result->commit_id, git_commit_id(commit));
+
+	n = find_commit_name(data->names, git_commit_id(commit));
+	if (n && (tags || all || n->prio == 2)) {
+		/*
+		 * Exact match to an existing ref.
+		 */
+		data->result->exact_match = 1;
+		if ((error = commit_name_dup(&data->result->name, n)) < 0)
+			goto cleanup;
+
+		goto cleanup;
+	}
+
+	if (!data->opts->max_candidates_tags) {
+		error = describe_not_found(
+			git_commit_id(commit),
+			"Cannot describe - no tag exactly matches '%s'");
+
+		goto cleanup;
+	}
+
+	if ((error = git_revwalk_new(&walk, git_commit_owner(commit))) < 0)
+		goto cleanup;
+
+	if ((cmit = git_revwalk__commit_lookup(walk, git_commit_id(commit))) == NULL)
+		goto cleanup;
+
+	if ((error = git_commit_list_parse(walk, cmit)) < 0)
+		goto cleanup;
+
+	cmit->flags = SEEN;
+
+	if ((error = git_pqueue_insert(&list, cmit)) < 0)
+		goto cleanup;
+
+	while (git_pqueue_size(&list) > 0)
+	{
+		int i;
+
+		git_commit_list_node *c = (git_commit_list_node *)git_pqueue_pop(&list);
+		seen_commits++;
+
+		n = find_commit_name(data->names, &c->oid);
+
+		if (n) {
+			if (!tags && !all && n->prio < 2) {
+				unannotated_cnt++;
+			} else if (match_cnt < data->opts->max_candidates_tags) {
+				struct possible_tag *t = git__malloc(sizeof(struct commit_name));
+				GITERR_CHECK_ALLOC(t);
+				if ((error = git_vector_insert(&all_matches, t)) < 0)
+					goto cleanup;
+
+				match_cnt++;
+
+				t->name = n;
+				t->depth = seen_commits - 1;
+				t->flag_within = 1u << match_cnt;
+				t->found_order = match_cnt;
+				c->flags |= t->flag_within;
+				if (n->prio == 2)
+					annotated_cnt++;
+			}
+			else {
+				gave_up_on = c;
+				break;
+			}
+		}
+
+		for (cur_match = 0; cur_match < match_cnt; cur_match++) {
+			struct possible_tag *t = git_vector_get(&all_matches, cur_match);
+			if (!(c->flags & t->flag_within))
+				t->depth++;
+		}
+
+		if (annotated_cnt && (git_pqueue_size(&list) == 0)) {
+			/*
+			if (debug) {
+				char oid_str[GIT_OID_HEXSZ + 1];
+				git_oid_tostr(oid_str, sizeof(oid_str), &c->oid);
+
+				fprintf(stderr, "finished search at %s\n", oid_str);
+			}
+			*/
+			break;
+		}
+		for (i = 0; i < c->out_degree; i++) {
+			git_commit_list_node *p = c->parents[i];
+			if ((error = git_commit_list_parse(walk, p)) < 0)
+				goto cleanup;
+			if (!(p->flags & SEEN))
+				if ((error = git_pqueue_insert(&list, p)) < 0)
+					goto cleanup;
+			p->flags |= c->flags;
+
+			if (data->opts->only_follow_first_parent)
+				break;
+		}
+	}
+
+	if (!match_cnt) {
+		if (data->opts->show_commit_oid_as_fallback) {
+			data->result->fallback_to_id = 1;
+			git_oid_cpy(&data->result->commit_id, &cmit->oid);
+
+			goto cleanup;
+		}
+		if (unannotated_cnt) {
+			error = describe_not_found(git_commit_id(commit), 
+				"Cannot describe - "
+				"No annotated tags can describe '%s'."
+			    "However, there were unannotated tags.");
+			goto cleanup;
+		}
+		else {
+			error = describe_not_found(git_commit_id(commit), 
+				"Cannot describe - "
+				"No tags can describe '%s'.");
+			goto cleanup;
+		}
+	}
+
+	git_vector_sort(&all_matches);
+
+	best = (struct possible_tag *)git_vector_get(&all_matches, 0);
+
+	if (gave_up_on) {
+		git_pqueue_insert(&list, gave_up_on);
+		seen_commits--;
+	}
+	if ((error = finish_depth_computation(
+		&list, walk, best)) < 0)
+		goto cleanup;
+
+	seen_commits += error;
+	if ((error = possible_tag_dup(&data->result->tag, best)) < 0)
+		goto cleanup;
+
+	/*
+	{
+		static const char *prio_names[] = {
+			"head", "lightweight", "annotated",
+		};
+
+		char oid_str[GIT_OID_HEXSZ + 1];
+
+		if (debug) {
+			for (cur_match = 0; cur_match < match_cnt; cur_match++) {
+				struct possible_tag *t = (struct possible_tag *)git_vector_get(&all_matches, cur_match);
+				fprintf(stderr, " %-11s %8d %s\n",
+					prio_names[t->name->prio],
+					t->depth, t->name->path);
+			}
+			fprintf(stderr, "traversed %lu commits\n", seen_commits);
+			if (gave_up_on) {
+				git_oid_tostr(oid_str, sizeof(oid_str), &gave_up_on->oid);
+				fprintf(stderr,
+					"more than %i tags found; listed %i most recent\n"
+					"gave up search at %s\n",
+					data->opts->max_candidates_tags, data->opts->max_candidates_tags,
+					oid_str);
+			}
+		}
+	}
+	*/
+
+	git_oid_cpy(&data->result->commit_id, &cmit->oid);
+
+cleanup:
+	{
+		size_t i;
+		struct possible_tag *match;
+		git_vector_foreach(&all_matches, i, match) {
+			git__free(match);
+		}
+	}
+	git_vector_free(&all_matches);
+	git_pqueue_free(&list);
+	git_revwalk_free(walk);
+	return error;
+}
+
+static int normalize_options(
+	git_describe_options *dst,
+	const git_describe_options *src)
+{
+	git_describe_options default_options = GIT_DESCRIBE_OPTIONS_INIT;
+	if (!src) src = &default_options;
+
+	*dst = *src;
+
+	if (dst->max_candidates_tags > GIT_DESCRIBE_DEFAULT_MAX_CANDIDATES_TAGS)
+		dst->max_candidates_tags = GIT_DESCRIBE_DEFAULT_MAX_CANDIDATES_TAGS;
+
+	return 0;
+}
+
+int git_describe_commit(
+	git_describe_result **result,
+	git_object *committish,
+	git_describe_options *opts)
+{
+	struct get_name_data data;
+	struct commit_name *name;
+	git_commit *commit;
+	int error = -1;
+	git_describe_options normalized;
+
+	assert(committish);
+
+	data.result = git__calloc(1, sizeof(git_describe_result));
+	GITERR_CHECK_ALLOC(data.result);
+	data.result->repo = git_object_owner(committish);
+
+	data.repo = git_object_owner(committish);
+
+	if ((error = normalize_options(&normalized, opts)) < 0)
+		return error;
+
+	GITERR_CHECK_VERSION(
+		&normalized,
+		GIT_DESCRIBE_OPTIONS_VERSION,
+		"git_describe_options");
+	data.opts = &normalized;
+
+	data.names = git_oidmap_alloc();
+	GITERR_CHECK_ALLOC(data.names);
+
+	/** TODO: contains to be implemented */
+
+	if ((error = git_object_peel((git_object **)(&commit), committish, GIT_OBJ_COMMIT)) < 0)
+		goto cleanup;
+
+	if ((error = git_reference_foreach_name(
+			git_object_owner(committish),
+			get_name, &data)) < 0)
+				goto cleanup;
+
+	if (git_oidmap_size(data.names) == 0 && !opts->show_commit_oid_as_fallback) {
+		giterr_set(GITERR_DESCRIBE, "Cannot describe - "
+			"No reference found, cannot describe anything.");
+		error = -1;
+		goto cleanup;
+	}
+
+	if ((error = describe(&data, commit)) < 0)
+		goto cleanup;
+
+cleanup:
+	git_commit_free(commit);
+
+	git_oidmap_foreach_value(data.names, name, {
+		git_tag_free(name->tag);
+		git__free(name->path);
+		git__free(name);
+	});
+
+	git_oidmap_free(data.names);
+
+	if (error < 0)
+		git_describe_result_free(data.result);
+	else
+		*result = data.result;
+
+	return error;
+}
+
+int git_describe_workdir(
+	git_describe_result **out,
+	git_repository *repo,
+	git_describe_options *opts)
+{
+	int error;
+	git_oid current_id;
+	git_status_list *status = NULL;
+	git_status_options status_opts = GIT_STATUS_OPTIONS_INIT;
+	git_describe_result *result = NULL;
+	git_object *commit;
+
+	if ((error = git_reference_name_to_id(&current_id, repo, GIT_HEAD_FILE)) < 0)
+		return error;
+
+	if ((error = git_object_lookup(&commit, repo, &current_id, GIT_OBJ_COMMIT)) < 0)
+		return error;
+
+	/* The first step is to perform a describe of HEAD, so we can leverage this */
+	if ((error = git_describe_commit(&result, commit, opts)) < 0)
+		goto out;
+
+	if ((error = git_status_list_new(&status, repo, &status_opts)) < 0)
+		goto out;
+
+
+	if (git_status_list_entrycount(status) > 0)
+		result->dirty = 1;
+
+out:
+	git_object_free(commit);
+	git_status_list_free(status);
+
+	if (error < 0)
+		git_describe_result_free(result);
+	else
+		*out = result;
+
+	return error;
+}
+
+static int normalize_format_options(
+	git_describe_format_options *dst,
+	const git_describe_format_options *src)
+{
+	if (!src) {
+		git_describe_init_format_options(dst, GIT_DESCRIBE_FORMAT_OPTIONS_VERSION);
+		return 0;
+	}
+
+	memcpy(dst, src, sizeof(git_describe_format_options));
+	return 0;
+}
+
+int git_describe_format(git_buf *out, const git_describe_result *result, const git_describe_format_options *given)
+{
+	int error;
+	git_repository *repo;
+	struct commit_name *name;
+	git_describe_format_options opts;
+
+	assert(out && result);
+
+	GITERR_CHECK_VERSION(given, GIT_DESCRIBE_FORMAT_OPTIONS_VERSION, "git_describe_format_options");
+	normalize_format_options(&opts, given);
+
+	git_buf_sanitize(out);
+
+
+	if (opts.always_use_long_format && opts.abbreviated_size == 0) {
+		giterr_set(GITERR_DESCRIBE, "Cannot describe - "
+			"'always_use_long_format' is incompatible with a zero"
+			"'abbreviated_size'");
+		return -1;
+	}
+
+
+	repo = result->repo;
+
+	/* If we did find an exact match, then it's the easier method */
+	if (result->exact_match) {
+		name = result->name;
+		if ((error = display_name(out, repo, name)) < 0)
+			return error;
+
+		if (opts.always_use_long_format) {
+			const git_oid *id = name->tag ? git_tag_target_id(name->tag) : &result->commit_id;
+			if ((error = show_suffix(out, 0, repo, id, opts.abbreviated_size)) < 0)
+				return error;
+		}
+
+		if (result->dirty && opts.dirty_suffix)
+			git_buf_puts(out, opts.dirty_suffix);
+
+		return git_buf_oom(out) ? -1 : 0;
+	}
+
+	/* If we didn't find *any* tags, we fall back to the commit's id */
+	if (result->fallback_to_id) {
+		char hex_oid[GIT_OID_HEXSZ + 1] = {0};
+		int size = 0;
+
+		if ((error = find_unique_abbrev_size(
+			     &size, repo, &result->commit_id, opts.abbreviated_size)) < 0)
+			return -1;
+
+		git_oid_fmt(hex_oid, &result->commit_id);
+		git_buf_put(out, hex_oid, size);
+
+		if (result->dirty && opts.dirty_suffix)
+			git_buf_puts(out, opts.dirty_suffix);
+
+		return git_buf_oom(out) ? -1 : 0;
+	}
+
+	/* Lastly, if we found a matching tag, we show that */
+	name = result->tag->name;
+
+	if ((error = display_name(out, repo, name)) < 0)
+		return error;
+
+	if (opts.abbreviated_size) {
+		if ((error = show_suffix(out, result->tag->depth, repo,
+			&result->commit_id, opts.abbreviated_size)) < 0)
+			return error;
+	}
+
+	if (result->dirty && opts.dirty_suffix) {
+		git_buf_puts(out, opts.dirty_suffix);
+	}
+
+	return git_buf_oom(out) ? -1 : 0;
+}
+
+void git_describe_result_free(git_describe_result *result)
+{
+	if (result == NULL)
+		return;
+
+	if (result->name) {
+		git_tag_free(result->name->tag);
+		git__free(result->name->path);
+		git__free(result->name);
+	}
+
+	if (result->tag) {
+		git_tag_free(result->tag->name->tag);
+		git__free(result->tag->name->path);
+		git__free(result->tag->name);
+		git__free(result->tag);
+	}
+
+	git__free(result);
+}
+
+int git_describe_init_options(git_describe_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_describe_options, GIT_DESCRIBE_OPTIONS_INIT);
+	return 0;
+}
+
+int git_describe_init_format_options(git_describe_format_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_describe_format_options, GIT_DESCRIBE_FORMAT_OPTIONS_INIT);
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff.c
new file mode 100755
index 0000000..c1adcc6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff.c
@@ -0,0 +1,1792 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "diff.h"
+#include "fileops.h"
+#include "config.h"
+#include "attr_file.h"
+#include "filter.h"
+#include "pathspec.h"
+#include "index.h"
+#include "odb.h"
+#include "submodule.h"
+
+#define DIFF_FLAG_IS_SET(DIFF,FLAG) (((DIFF)->opts.flags & (FLAG)) != 0)
+#define DIFF_FLAG_ISNT_SET(DIFF,FLAG) (((DIFF)->opts.flags & (FLAG)) == 0)
+#define DIFF_FLAG_SET(DIFF,FLAG,VAL) (DIFF)->opts.flags = \
+	(VAL) ? ((DIFF)->opts.flags | (FLAG)) : ((DIFF)->opts.flags & ~(VAL))
+
+static git_diff_delta *diff_delta__alloc(
+	git_diff *diff,
+	git_delta_t status,
+	const char *path)
+{
+	git_diff_delta *delta = git__calloc(1, sizeof(git_diff_delta));
+	if (!delta)
+		return NULL;
+
+	delta->old_file.path = git_pool_strdup(&diff->pool, path);
+	if (delta->old_file.path == NULL) {
+		git__free(delta);
+		return NULL;
+	}
+
+	delta->new_file.path = delta->old_file.path;
+
+	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_REVERSE)) {
+		switch (status) {
+		case GIT_DELTA_ADDED:   status = GIT_DELTA_DELETED; break;
+		case GIT_DELTA_DELETED: status = GIT_DELTA_ADDED; break;
+		default: break; /* leave other status values alone */
+		}
+	}
+	delta->status = status;
+
+	return delta;
+}
+
+static int diff_insert_delta(
+	git_diff *diff, git_diff_delta *delta, const char *matched_pathspec)
+{
+	int error = 0;
+
+	if (diff->opts.notify_cb) {
+		error = diff->opts.notify_cb(
+			diff, delta, matched_pathspec, diff->opts.notify_payload);
+
+		if (error) {
+			git__free(delta);
+
+			if (error > 0)	/* positive value means to skip this delta */
+				return 0;
+			else			/* negative value means to cancel diff */
+				return giterr_set_after_callback_function(error, "git_diff");
+		}
+	}
+
+	if ((error = git_vector_insert(&diff->deltas, delta)) < 0)
+		git__free(delta);
+
+	return error;
+}
+
+static int diff_delta__from_one(
+	git_diff *diff,
+	git_delta_t status,
+	const git_index_entry *oitem,
+	const git_index_entry *nitem)
+{
+	const git_index_entry *entry = nitem;
+	bool has_old = false;
+	git_diff_delta *delta;
+	const char *matched_pathspec;
+
+	assert((oitem != NULL) ^ (nitem != NULL));
+
+	if (oitem) {
+		entry = oitem;
+		has_old = true;
+	}
+
+	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_REVERSE))
+		has_old = !has_old;
+
+	if ((entry->flags & GIT_IDXENTRY_VALID) != 0)
+		return 0;
+
+	if (status == GIT_DELTA_IGNORED &&
+		DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_INCLUDE_IGNORED))
+		return 0;
+
+	if (status == GIT_DELTA_UNTRACKED &&
+		DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_INCLUDE_UNTRACKED))
+		return 0;
+	
+	if (status == GIT_DELTA_UNREADABLE &&
+		DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_INCLUDE_UNREADABLE))
+		return 0;
+
+	if (!git_pathspec__match(
+			&diff->pathspec, entry->path,
+			DIFF_FLAG_IS_SET(diff, GIT_DIFF_DISABLE_PATHSPEC_MATCH),
+			DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE),
+			&matched_pathspec, NULL))
+		return 0;
+
+	delta = diff_delta__alloc(diff, status, entry->path);
+	GITERR_CHECK_ALLOC(delta);
+
+	/* This fn is just for single-sided diffs */
+	assert(status != GIT_DELTA_MODIFIED);
+	delta->nfiles = 1;
+
+	if (has_old) {
+		delta->old_file.mode = entry->mode;
+		delta->old_file.size = entry->file_size;
+		delta->old_file.flags |= GIT_DIFF_FLAG_EXISTS;
+		git_oid_cpy(&delta->old_file.id, &entry->id);
+	} else /* ADDED, IGNORED, UNTRACKED */ {
+		delta->new_file.mode = entry->mode;
+		delta->new_file.size = entry->file_size;
+		delta->new_file.flags |= GIT_DIFF_FLAG_EXISTS;
+		git_oid_cpy(&delta->new_file.id, &entry->id);
+	}
+
+	delta->old_file.flags |= GIT_DIFF_FLAG_VALID_ID;
+
+	if (has_old || !git_oid_iszero(&delta->new_file.id))
+		delta->new_file.flags |= GIT_DIFF_FLAG_VALID_ID;
+
+	return diff_insert_delta(diff, delta, matched_pathspec);
+}
+
+static int diff_delta__from_two(
+	git_diff *diff,
+	git_delta_t status,
+	const git_index_entry *old_entry,
+	uint32_t old_mode,
+	const git_index_entry *new_entry,
+	uint32_t new_mode,
+	const git_oid *new_id,
+	const char *matched_pathspec)
+{
+	const git_oid *old_id = &old_entry->id;
+	git_diff_delta *delta;
+	const char *canonical_path = old_entry->path;
+
+	if (status == GIT_DELTA_UNMODIFIED &&
+		DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_INCLUDE_UNMODIFIED))
+		return 0;
+
+	if (!new_id)
+		new_id = &new_entry->id;
+
+	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_REVERSE)) {
+		uint32_t temp_mode = old_mode;
+		const git_index_entry *temp_entry = old_entry;
+		const git_oid *temp_id = old_id;
+
+		old_entry = new_entry;
+		new_entry = temp_entry;
+		old_mode = new_mode;
+		new_mode = temp_mode;
+		old_id = new_id;
+		new_id = temp_id;
+	}
+
+	delta = diff_delta__alloc(diff, status, canonical_path);
+	GITERR_CHECK_ALLOC(delta);
+	delta->nfiles = 2;
+
+	if (!git_index_entry_is_conflict(old_entry)) {
+		delta->old_file.size = old_entry->file_size;
+		delta->old_file.mode = old_mode;
+		git_oid_cpy(&delta->old_file.id, old_id);
+		delta->old_file.flags |= GIT_DIFF_FLAG_VALID_ID |
+			GIT_DIFF_FLAG_EXISTS;
+	}
+
+	if (!git_index_entry_is_conflict(new_entry)) {
+		git_oid_cpy(&delta->new_file.id, new_id);
+		delta->new_file.size = new_entry->file_size;
+		delta->new_file.mode = new_mode;
+		delta->old_file.flags |= GIT_DIFF_FLAG_EXISTS;
+		delta->new_file.flags |= GIT_DIFF_FLAG_EXISTS;
+
+		if (!git_oid_iszero(&new_entry->id))
+			delta->new_file.flags |= GIT_DIFF_FLAG_VALID_ID;
+	}
+
+	return diff_insert_delta(diff, delta, matched_pathspec);
+}
+
+static git_diff_delta *diff_delta__last_for_item(
+	git_diff *diff,
+	const git_index_entry *item)
+{
+	git_diff_delta *delta = git_vector_last(&diff->deltas);
+	if (!delta)
+		return NULL;
+
+	switch (delta->status) {
+	case GIT_DELTA_UNMODIFIED:
+	case GIT_DELTA_DELETED:
+		if (git_oid__cmp(&delta->old_file.id, &item->id) == 0)
+			return delta;
+		break;
+	case GIT_DELTA_ADDED:
+		if (git_oid__cmp(&delta->new_file.id, &item->id) == 0)
+			return delta;
+		break;
+	case GIT_DELTA_UNREADABLE:
+	case GIT_DELTA_UNTRACKED:
+		if (diff->strcomp(delta->new_file.path, item->path) == 0 &&
+			git_oid__cmp(&delta->new_file.id, &item->id) == 0)
+			return delta;
+		break;
+	case GIT_DELTA_MODIFIED:
+		if (git_oid__cmp(&delta->old_file.id, &item->id) == 0 ||
+			git_oid__cmp(&delta->new_file.id, &item->id) == 0)
+			return delta;
+		break;
+	default:
+		break;
+	}
+
+	return NULL;
+}
+
+static char *diff_strdup_prefix(git_pool *pool, const char *prefix)
+{
+	size_t len = strlen(prefix);
+
+	/* append '/' at end if needed */
+	if (len > 0 && prefix[len - 1] != '/')
+		return git_pool_strcat(pool, prefix, "/");
+	else
+		return git_pool_strndup(pool, prefix, len + 1);
+}
+
+GIT_INLINE(const char *) diff_delta__path(const git_diff_delta *delta)
+{
+	const char *str = delta->old_file.path;
+
+	if (!str ||
+		delta->status == GIT_DELTA_ADDED ||
+		delta->status == GIT_DELTA_RENAMED ||
+		delta->status == GIT_DELTA_COPIED)
+		str = delta->new_file.path;
+
+	return str;
+}
+
+const char *git_diff_delta__path(const git_diff_delta *delta)
+{
+	return diff_delta__path(delta);
+}
+
+int git_diff_delta__cmp(const void *a, const void *b)
+{
+	const git_diff_delta *da = a, *db = b;
+	int val = strcmp(diff_delta__path(da), diff_delta__path(db));
+	return val ? val : ((int)da->status - (int)db->status);
+}
+
+int git_diff_delta__casecmp(const void *a, const void *b)
+{
+	const git_diff_delta *da = a, *db = b;
+	int val = strcasecmp(diff_delta__path(da), diff_delta__path(db));
+	return val ? val : ((int)da->status - (int)db->status);
+}
+
+GIT_INLINE(const char *) diff_delta__i2w_path(const git_diff_delta *delta)
+{
+	return delta->old_file.path ?
+		delta->old_file.path : delta->new_file.path;
+}
+
+int git_diff_delta__i2w_cmp(const void *a, const void *b)
+{
+	const git_diff_delta *da = a, *db = b;
+	int val = strcmp(diff_delta__i2w_path(da), diff_delta__i2w_path(db));
+	return val ? val : ((int)da->status - (int)db->status);
+}
+
+int git_diff_delta__i2w_casecmp(const void *a, const void *b)
+{
+	const git_diff_delta *da = a, *db = b;
+	int val = strcasecmp(diff_delta__i2w_path(da), diff_delta__i2w_path(db));
+	return val ? val : ((int)da->status - (int)db->status);
+}
+
+bool git_diff_delta__should_skip(
+	const git_diff_options *opts, const git_diff_delta *delta)
+{
+	uint32_t flags = opts ? opts->flags : 0;
+
+	if (delta->status == GIT_DELTA_UNMODIFIED &&
+		(flags & GIT_DIFF_INCLUDE_UNMODIFIED) == 0)
+		return true;
+
+	if (delta->status == GIT_DELTA_IGNORED &&
+		(flags & GIT_DIFF_INCLUDE_IGNORED) == 0)
+		return true;
+
+	if (delta->status == GIT_DELTA_UNTRACKED &&
+		(flags & GIT_DIFF_INCLUDE_UNTRACKED) == 0)
+		return true;
+
+	if (delta->status == GIT_DELTA_UNREADABLE &&
+		(flags & GIT_DIFF_INCLUDE_UNREADABLE) == 0)
+		return true;
+
+	return false;
+}
+
+
+static const char *diff_mnemonic_prefix(
+	git_iterator_type_t type, bool left_side)
+{
+	const char *pfx = "";
+
+	switch (type) {
+	case GIT_ITERATOR_TYPE_EMPTY:   pfx = "c"; break;
+	case GIT_ITERATOR_TYPE_TREE:    pfx = "c"; break;
+	case GIT_ITERATOR_TYPE_INDEX:   pfx = "i"; break;
+	case GIT_ITERATOR_TYPE_WORKDIR: pfx = "w"; break;
+	case GIT_ITERATOR_TYPE_FS:      pfx = left_side ? "1" : "2"; break;
+	default: break;
+	}
+
+	/* note: without a deeper look at pathspecs, there is no easy way
+	 * to get the (o)bject / (w)ork tree mnemonics working...
+	 */
+
+	return pfx;
+}
+
+static int diff_entry_cmp(const void *a, const void *b)
+{
+	const git_index_entry *entry_a = a;
+	const git_index_entry *entry_b = b;
+
+	return strcmp(entry_a->path, entry_b->path);
+}
+
+static int diff_entry_icmp(const void *a, const void *b)
+{
+	const git_index_entry *entry_a = a;
+	const git_index_entry *entry_b = b;
+
+	return strcasecmp(entry_a->path, entry_b->path);
+}
+
+static void diff_set_ignore_case(git_diff *diff, bool ignore_case)
+{
+	if (!ignore_case) {
+		diff->opts.flags &= ~GIT_DIFF_IGNORE_CASE;
+
+		diff->strcomp    = git__strcmp;
+		diff->strncomp   = git__strncmp;
+		diff->pfxcomp    = git__prefixcmp;
+		diff->entrycomp  = diff_entry_cmp;
+
+		git_vector_set_cmp(&diff->deltas, git_diff_delta__cmp);
+	} else {
+		diff->opts.flags |= GIT_DIFF_IGNORE_CASE;
+
+		diff->strcomp    = git__strcasecmp;
+		diff->strncomp   = git__strncasecmp;
+		diff->pfxcomp    = git__prefixcmp_icase;
+		diff->entrycomp  = diff_entry_icmp;
+
+		git_vector_set_cmp(&diff->deltas, git_diff_delta__casecmp);
+	}
+
+	git_vector_sort(&diff->deltas);
+}
+
+static git_diff *diff_list_alloc(
+	git_repository *repo,
+	git_iterator *old_iter,
+	git_iterator *new_iter)
+{
+	git_diff_options dflt = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = git__calloc(1, sizeof(git_diff));
+	if (!diff)
+		return NULL;
+
+	assert(repo && old_iter && new_iter);
+
+	GIT_REFCOUNT_INC(diff);
+	diff->repo = repo;
+	diff->old_src = old_iter->type;
+	diff->new_src = new_iter->type;
+	memcpy(&diff->opts, &dflt, sizeof(diff->opts));
+
+	if (git_vector_init(&diff->deltas, 0, git_diff_delta__cmp) < 0 ||
+		git_pool_init(&diff->pool, 1, 0) < 0) {
+		git_diff_free(diff);
+		return NULL;
+	}
+
+	/* Use case-insensitive compare if either iterator has
+	 * the ignore_case bit set */
+	diff_set_ignore_case(
+		diff,
+		git_iterator_ignore_case(old_iter) ||
+		git_iterator_ignore_case(new_iter));
+
+	return diff;
+}
+
+static int diff_list_apply_options(
+	git_diff *diff,
+	const git_diff_options *opts)
+{
+	git_config *cfg = NULL;
+	git_repository *repo = diff->repo;
+	git_pool *pool = &diff->pool;
+	int val;
+
+	if (opts) {
+		/* copy user options (except case sensitivity info from iterators) */
+		bool icase = DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE);
+		memcpy(&diff->opts, opts, sizeof(diff->opts));
+		DIFF_FLAG_SET(diff, GIT_DIFF_IGNORE_CASE, icase);
+
+		/* initialize pathspec from options */
+		if (git_pathspec__vinit(&diff->pathspec, &opts->pathspec, pool) < 0)
+			return -1;
+	}
+
+	/* flag INCLUDE_TYPECHANGE_TREES implies INCLUDE_TYPECHANGE */
+	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_TYPECHANGE_TREES))
+		diff->opts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE;
+
+	/* flag INCLUDE_UNTRACKED_CONTENT implies INCLUDE_UNTRACKED */
+	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_SHOW_UNTRACKED_CONTENT))
+		diff->opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED;
+
+	/* load config values that affect diff behavior */
+	if ((val = git_repository_config_snapshot(&cfg, repo)) < 0)
+		return val;
+
+	if (!git_config__cvar(&val, cfg, GIT_CVAR_SYMLINKS) && val)
+		diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_HAS_SYMLINKS;
+
+	if (!git_config__cvar(&val, cfg, GIT_CVAR_IGNORESTAT) && val)
+		diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_IGNORE_STAT;
+
+	if ((diff->opts.flags & GIT_DIFF_IGNORE_FILEMODE) == 0 &&
+		!git_config__cvar(&val, cfg, GIT_CVAR_FILEMODE) && val)
+		diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_TRUST_MODE_BITS;
+
+	if (!git_config__cvar(&val, cfg, GIT_CVAR_TRUSTCTIME) && val)
+		diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_TRUST_CTIME;
+
+	/* Don't set GIT_DIFFCAPS_USE_DEV - compile time option in core git */
+
+	/* Set GIT_DIFFCAPS_TRUST_NANOSECS on a platform basis */
+	diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_TRUST_NANOSECS;
+
+	/* If not given explicit `opts`, check `diff.xyz` configs */
+	if (!opts) {
+		int context = git_config__get_int_force(cfg, "diff.context", 3);
+		diff->opts.context_lines = context >= 0 ? (uint32_t)context : 3;
+
+		/* add other defaults here */
+	}
+
+	/* Reverse src info if diff is reversed */
+	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_REVERSE)) {
+		git_iterator_type_t tmp_src = diff->old_src;
+		diff->old_src = diff->new_src;
+		diff->new_src = tmp_src;
+	}
+
+	/* Unset UPDATE_INDEX unless diffing workdir and index */
+	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_UPDATE_INDEX) &&
+		(!(diff->old_src == GIT_ITERATOR_TYPE_WORKDIR ||
+		   diff->new_src == GIT_ITERATOR_TYPE_WORKDIR) ||
+		 !(diff->old_src == GIT_ITERATOR_TYPE_INDEX ||
+		   diff->new_src == GIT_ITERATOR_TYPE_INDEX)))
+		diff->opts.flags &= ~GIT_DIFF_UPDATE_INDEX;
+
+	/* if ignore_submodules not explicitly set, check diff config */
+	if (diff->opts.ignore_submodules <= 0) {
+		 git_config_entry *entry;
+		git_config__lookup_entry(&entry, cfg, "diff.ignoresubmodules", true);
+
+		if (entry && git_submodule_parse_ignore(
+				&diff->opts.ignore_submodules, entry->value) < 0)
+			giterr_clear();
+		git_config_entry_free(entry);
+	}
+
+	/* if either prefix is not set, figure out appropriate value */
+	if (!diff->opts.old_prefix || !diff->opts.new_prefix) {
+		const char *use_old = DIFF_OLD_PREFIX_DEFAULT;
+		const char *use_new = DIFF_NEW_PREFIX_DEFAULT;
+
+		if (git_config__get_bool_force(cfg, "diff.noprefix", 0))
+			use_old = use_new = "";
+		else if (git_config__get_bool_force(cfg, "diff.mnemonicprefix", 0)) {
+			use_old = diff_mnemonic_prefix(diff->old_src, true);
+			use_new = diff_mnemonic_prefix(diff->new_src, false);
+		}
+
+		if (!diff->opts.old_prefix)
+			diff->opts.old_prefix = use_old;
+		if (!diff->opts.new_prefix)
+			diff->opts.new_prefix = use_new;
+	}
+
+	/* strdup prefix from pool so we're not dependent on external data */
+	diff->opts.old_prefix = diff_strdup_prefix(pool, diff->opts.old_prefix);
+	diff->opts.new_prefix = diff_strdup_prefix(pool, diff->opts.new_prefix);
+
+	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_REVERSE)) {
+		const char *tmp_prefix = diff->opts.old_prefix;
+		diff->opts.old_prefix  = diff->opts.new_prefix;
+		diff->opts.new_prefix  = tmp_prefix;
+	}
+
+	git_config_free(cfg);
+
+	/* check strdup results for error */
+	return (!diff->opts.old_prefix || !diff->opts.new_prefix) ? -1 : 0;
+}
+
+static void diff_list_free(git_diff *diff)
+{
+	git_vector_free_deep(&diff->deltas);
+
+	git_pathspec__vfree(&diff->pathspec);
+	git_pool_clear(&diff->pool);
+
+	git__memzero(diff, sizeof(*diff));
+	git__free(diff);
+}
+
+void git_diff_free(git_diff *diff)
+{
+	if (!diff)
+		return;
+
+	GIT_REFCOUNT_DEC(diff, diff_list_free);
+}
+
+void git_diff_addref(git_diff *diff)
+{
+	GIT_REFCOUNT_INC(diff);
+}
+
+int git_diff__oid_for_file(
+	git_oid *out,
+	git_diff *diff,
+	const char *path,
+	uint16_t mode,
+	git_off_t size)
+{
+	git_index_entry entry;
+
+	memset(&entry, 0, sizeof(entry));
+	entry.mode = mode;
+	entry.file_size = size;
+	entry.path = (char *)path;
+
+	return git_diff__oid_for_entry(out, diff, &entry, mode, NULL);
+}
+
+int git_diff__oid_for_entry(
+	git_oid *out,
+	git_diff *diff,
+	const git_index_entry *src,
+	uint16_t mode,
+	const git_oid *update_match)
+{
+	int error = 0;
+	git_buf full_path = GIT_BUF_INIT;
+	git_index_entry entry = *src;
+	git_filter_list *fl = NULL;
+
+	memset(out, 0, sizeof(*out));
+
+	if (git_buf_joinpath(
+		&full_path, git_repository_workdir(diff->repo), entry.path) < 0)
+		return -1;
+
+	if (!mode) {
+		struct stat st;
+
+		diff->perf.stat_calls++;
+
+		if (p_stat(full_path.ptr, &st) < 0) {
+			error = git_path_set_error(errno, entry.path, "stat");
+			git_buf_free(&full_path);
+			return error;
+		}
+
+		git_index_entry__init_from_stat(
+			&entry, &st, (diff->diffcaps & GIT_DIFFCAPS_TRUST_MODE_BITS) != 0);
+	}
+
+	/* calculate OID for file if possible */
+	if (S_ISGITLINK(mode)) {
+		git_submodule *sm;
+
+		if (!git_submodule_lookup(&sm, diff->repo, entry.path)) {
+			const git_oid *sm_oid = git_submodule_wd_id(sm);
+			if (sm_oid)
+				git_oid_cpy(out, sm_oid);
+			git_submodule_free(sm);
+		} else {
+			/* if submodule lookup failed probably just in an intermediate
+			 * state where some init hasn't happened, so ignore the error
+			 */
+			giterr_clear();
+		}
+	} else if (S_ISLNK(mode)) {
+		error = git_odb__hashlink(out, full_path.ptr);
+		diff->perf.oid_calculations++;
+	} else if (!git__is_sizet(entry.file_size)) {
+		giterr_set(GITERR_OS, "File size overflow (for 32-bits) on '%s'",
+			entry.path);
+		error = -1;
+	} else if (!(error = git_filter_list_load(
+		&fl, diff->repo, NULL, entry.path,
+		GIT_FILTER_TO_ODB, GIT_FILTER_ALLOW_UNSAFE)))
+	{
+		int fd = git_futils_open_ro(full_path.ptr);
+		if (fd < 0)
+			error = fd;
+		else {
+			error = git_odb__hashfd_filtered(
+				out, fd, (size_t)entry.file_size, GIT_OBJ_BLOB, fl);
+			p_close(fd);
+			diff->perf.oid_calculations++;
+		}
+
+		git_filter_list_free(fl);
+	}
+
+	/* update index for entry if requested */
+	if (!error && update_match && git_oid_equal(out, update_match)) {
+		git_index *idx;
+		git_index_entry updated_entry;
+
+		memcpy(&updated_entry, &entry, sizeof(git_index_entry));
+		updated_entry.mode = mode;
+		git_oid_cpy(&updated_entry.id, out);
+
+		if (!(error = git_repository_index__weakptr(&idx, diff->repo))) {
+			error = git_index_add(idx, &updated_entry);
+			diff->index_updated = true;
+		}
+ 	}
+
+	git_buf_free(&full_path);
+	return error;
+}
+
+static bool diff_time_eq(
+	const git_index_time *a, const git_index_time *b, bool use_nanos)
+{
+	return a->seconds == b->seconds &&
+		(!use_nanos || a->nanoseconds == b->nanoseconds);
+}
+
+typedef struct {
+	git_repository *repo;
+	git_iterator *old_iter;
+	git_iterator *new_iter;
+	const git_index_entry *oitem;
+	const git_index_entry *nitem;
+} diff_in_progress;
+
+#define MODE_BITS_MASK 0000777
+
+static int maybe_modified_submodule(
+	git_delta_t *status,
+	git_oid *found_oid,
+	git_diff *diff,
+	diff_in_progress *info)
+{
+	int error = 0;
+	git_submodule *sub;
+	unsigned int sm_status = 0;
+	git_submodule_ignore_t ign = diff->opts.ignore_submodules;
+
+	*status = GIT_DELTA_UNMODIFIED;
+
+	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_SUBMODULES) ||
+		ign == GIT_SUBMODULE_IGNORE_ALL)
+		return 0;
+
+	if ((error = git_submodule_lookup(
+			&sub, diff->repo, info->nitem->path)) < 0) {
+
+		/* GIT_EEXISTS means dir with .git in it was found - ignore it */
+		if (error == GIT_EEXISTS) {
+			giterr_clear();
+			error = 0;
+		}
+		return error;
+	}
+
+	if (ign <= 0 && git_submodule_ignore(sub) == GIT_SUBMODULE_IGNORE_ALL)
+		/* ignore it */;
+	else if ((error = git_submodule__status(
+			&sm_status, NULL, NULL, found_oid, sub, ign)) < 0)
+		/* return error below */;
+
+	/* check IS_WD_UNMODIFIED because this case is only used
+	 * when the new side of the diff is the working directory
+	 */
+	else if (!GIT_SUBMODULE_STATUS_IS_WD_UNMODIFIED(sm_status))
+		*status = GIT_DELTA_MODIFIED;
+
+	/* now that we have a HEAD OID, check if HEAD moved */
+	else if ((sm_status & GIT_SUBMODULE_STATUS_IN_WD) != 0 &&
+		!git_oid_equal(&info->oitem->id, found_oid))
+		*status = GIT_DELTA_MODIFIED;
+
+	git_submodule_free(sub);
+	return error;
+}
+
+static int maybe_modified(
+	git_diff *diff,
+	diff_in_progress *info)
+{
+	git_oid noid;
+	git_delta_t status = GIT_DELTA_MODIFIED;
+	const git_index_entry *oitem = info->oitem;
+	const git_index_entry *nitem = info->nitem;
+	unsigned int omode = oitem->mode;
+	unsigned int nmode = nitem->mode;
+	bool new_is_workdir = (info->new_iter->type == GIT_ITERATOR_TYPE_WORKDIR);
+	bool modified_uncertain = false;
+	const char *matched_pathspec;
+	int error = 0;
+
+	if (!git_pathspec__match(
+			&diff->pathspec, oitem->path,
+			DIFF_FLAG_IS_SET(diff, GIT_DIFF_DISABLE_PATHSPEC_MATCH),
+			DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE),
+			&matched_pathspec, NULL))
+		return 0;
+
+	memset(&noid, 0, sizeof(noid));
+
+	/* on platforms with no symlinks, preserve mode of existing symlinks */
+	if (S_ISLNK(omode) && S_ISREG(nmode) && new_is_workdir &&
+		!(diff->diffcaps & GIT_DIFFCAPS_HAS_SYMLINKS))
+		nmode = omode;
+
+	/* on platforms with no execmode, just preserve old mode */
+	if (!(diff->diffcaps & GIT_DIFFCAPS_TRUST_MODE_BITS) &&
+		(nmode & MODE_BITS_MASK) != (omode & MODE_BITS_MASK) &&
+		new_is_workdir)
+		nmode = (nmode & ~MODE_BITS_MASK) | (omode & MODE_BITS_MASK);
+
+	/* if one side is a conflict, mark the whole delta as conflicted */
+	if (git_index_entry_is_conflict(oitem) ||
+			git_index_entry_is_conflict(nitem)) {
+		status = GIT_DELTA_CONFLICTED;
+
+	/* support "assume unchanged" (poorly, b/c we still stat everything) */
+	} else if ((oitem->flags & GIT_IDXENTRY_VALID) != 0) {
+		status = GIT_DELTA_UNMODIFIED;
+
+	/* support "skip worktree" index bit */
+	} else if ((oitem->flags_extended & GIT_IDXENTRY_SKIP_WORKTREE) != 0) {
+		status = GIT_DELTA_UNMODIFIED;
+
+	/* if basic type of file changed, then split into delete and add */
+	} else if (GIT_MODE_TYPE(omode) != GIT_MODE_TYPE(nmode)) {
+		if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_TYPECHANGE)) {
+			status = GIT_DELTA_TYPECHANGE;
+		}
+
+		else if (nmode == GIT_FILEMODE_UNREADABLE) {
+			if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem, NULL)))
+				error = diff_delta__from_one(diff, GIT_DELTA_UNREADABLE, NULL, nitem);
+			return error;
+		}
+
+		else {
+			if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem, NULL)))
+				error = diff_delta__from_one(diff, GIT_DELTA_ADDED, NULL, nitem);
+			return error;
+		}
+
+	/* if oids and modes match (and are valid), then file is unmodified */
+	} else if (git_oid_equal(&oitem->id, &nitem->id) &&
+			 omode == nmode &&
+			 !git_oid_iszero(&oitem->id)) {
+		status = GIT_DELTA_UNMODIFIED;
+
+	/* if we have an unknown OID and a workdir iterator, then check some
+	 * circumstances that can accelerate things or need special handling
+	 */
+	} else if (git_oid_iszero(&nitem->id) && new_is_workdir) {
+		bool use_ctime = ((diff->diffcaps & GIT_DIFFCAPS_TRUST_CTIME) != 0);
+		bool use_nanos = ((diff->diffcaps & GIT_DIFFCAPS_TRUST_NANOSECS) != 0);
+		git_index *index;
+		git_iterator_index(&index, info->new_iter);
+
+		status = GIT_DELTA_UNMODIFIED;
+
+		if (S_ISGITLINK(nmode)) {
+			if ((error = maybe_modified_submodule(&status, &noid, diff, info)) < 0)
+				return error;
+		}
+
+		/* if the stat data looks different, then mark modified - this just
+		 * means that the OID will be recalculated below to confirm change
+		 */
+		else if (omode != nmode || oitem->file_size != nitem->file_size) {
+			status = GIT_DELTA_MODIFIED;
+			modified_uncertain =
+				(oitem->file_size <= 0 && nitem->file_size > 0);
+		}
+		else if (!diff_time_eq(&oitem->mtime, &nitem->mtime, use_nanos) ||
+			(use_ctime &&
+			 !diff_time_eq(&oitem->ctime, &nitem->ctime, use_nanos)) ||
+			oitem->ino != nitem->ino ||
+			oitem->uid != nitem->uid ||
+			oitem->gid != nitem->gid ||
+			(index && nitem->mtime.seconds >= index->stamp.mtime))
+		{
+			status = GIT_DELTA_MODIFIED;
+			modified_uncertain = true;
+		}
+
+	/* if mode is GITLINK and submodules are ignored, then skip */
+	} else if (S_ISGITLINK(nmode) &&
+			 DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_SUBMODULES)) {
+		status = GIT_DELTA_UNMODIFIED;
+	}
+
+	/* if we got here and decided that the files are modified, but we
+	 * haven't calculated the OID of the new item, then calculate it now
+	 */
+	if (modified_uncertain && git_oid_iszero(&nitem->id)) {
+		const git_oid *update_check =
+			DIFF_FLAG_IS_SET(diff, GIT_DIFF_UPDATE_INDEX) && omode == nmode ?
+			&oitem->id : NULL;
+
+		if ((error = git_diff__oid_for_entry(
+				&noid, diff, nitem, nmode, update_check)) < 0)
+			return error;
+
+		/* if oid matches, then mark unmodified (except submodules, where
+		 * the filesystem content may be modified even if the oid still
+		 * matches between the index and the workdir HEAD)
+		 */
+		if (omode == nmode && !S_ISGITLINK(omode) &&
+			git_oid_equal(&oitem->id, &noid))
+			status = GIT_DELTA_UNMODIFIED;
+	}
+
+	/* If we want case changes, then break this into a delete of the old
+	 * and an add of the new so that consumers can act accordingly (eg,
+	 * checkout will update the case on disk.)
+	 */
+	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE) &&
+		DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_CASECHANGE) &&
+		strcmp(oitem->path, nitem->path) != 0) {
+
+		if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem, NULL)))
+			error = diff_delta__from_one(diff, GIT_DELTA_ADDED, NULL, nitem);
+
+		return error;
+	}
+
+	return diff_delta__from_two(
+		diff, status, oitem, omode, nitem, nmode,
+		git_oid_iszero(&noid) ? NULL : &noid, matched_pathspec);
+}
+
+static bool entry_is_prefixed(
+	git_diff *diff,
+	const git_index_entry *item,
+	const git_index_entry *prefix_item)
+{
+	size_t pathlen;
+
+	if (!item || diff->pfxcomp(item->path, prefix_item->path) != 0)
+		return false;
+
+	pathlen = strlen(prefix_item->path);
+
+	return (prefix_item->path[pathlen - 1] == '/' ||
+			item->path[pathlen] == '\0' ||
+			item->path[pathlen] == '/');
+}
+
+static int iterator_current(
+	const git_index_entry **entry,
+	git_iterator *iterator)
+{
+	int error;
+
+	if ((error = git_iterator_current(entry, iterator)) == GIT_ITEROVER) {
+		*entry = NULL;
+		error = 0;
+	}
+
+	return error;
+}
+
+static int iterator_advance(
+	const git_index_entry **entry,
+	git_iterator *iterator)
+{
+	const git_index_entry *prev_entry = *entry;
+	int cmp, error;
+
+	/* if we're looking for conflicts, we only want to report
+	 * one conflict for each file, instead of all three sides.
+	 * so if this entry is a conflict for this file, and the
+	 * previous one was a conflict for the same file, skip it.
+	 */
+	while ((error = git_iterator_advance(entry, iterator)) == 0) {
+		if (!(iterator->flags & GIT_ITERATOR_INCLUDE_CONFLICTS) ||
+			!git_index_entry_is_conflict(prev_entry) ||
+			!git_index_entry_is_conflict(*entry))
+			break;
+
+		cmp = (iterator->flags & GIT_ITERATOR_IGNORE_CASE) ?
+			strcasecmp(prev_entry->path, (*entry)->path) :
+			strcmp(prev_entry->path, (*entry)->path);
+
+		if (cmp)
+			break;
+	}
+
+	if (error == GIT_ITEROVER) {
+		*entry = NULL;
+		error = 0;
+	}
+
+	return error;
+}
+
+static int iterator_advance_into(
+	const git_index_entry **entry,
+	git_iterator *iterator)
+{
+	int error;
+
+	if ((error = git_iterator_advance_into(entry, iterator)) == GIT_ITEROVER) {
+		*entry = NULL;
+		error = 0;
+	}
+
+	return error;
+}
+
+static int iterator_advance_over_with_status(
+	const git_index_entry **entry,
+	git_iterator_status_t *status,
+	git_iterator *iterator)
+{
+	int error;
+
+	if ((error = git_iterator_advance_over_with_status(
+			entry, status, iterator)) == GIT_ITEROVER) {
+		*entry = NULL;
+		error = 0;
+	}
+
+	return error;
+}
+
+static int handle_unmatched_new_item(
+	git_diff *diff, diff_in_progress *info)
+{
+	int error = 0;
+	const git_index_entry *nitem = info->nitem;
+	git_delta_t delta_type = GIT_DELTA_UNTRACKED;
+	bool contains_oitem;
+
+	/* check if this is a prefix of the other side */
+	contains_oitem = entry_is_prefixed(diff, info->oitem, nitem);
+
+	/* update delta_type if this item is conflicted */
+	if (git_index_entry_is_conflict(nitem))
+		delta_type = GIT_DELTA_CONFLICTED;
+
+	/* update delta_type if this item is ignored */
+	else if (git_iterator_current_is_ignored(info->new_iter))
+		delta_type = GIT_DELTA_IGNORED;
+
+	if (nitem->mode == GIT_FILEMODE_TREE) {
+		bool recurse_into_dir = contains_oitem;
+
+		/* check if user requests recursion into this type of dir */
+		recurse_into_dir = contains_oitem ||
+			(delta_type == GIT_DELTA_UNTRACKED &&
+			 DIFF_FLAG_IS_SET(diff, GIT_DIFF_RECURSE_UNTRACKED_DIRS)) ||
+			(delta_type == GIT_DELTA_IGNORED &&
+			 DIFF_FLAG_IS_SET(diff, GIT_DIFF_RECURSE_IGNORED_DIRS));
+
+		/* do not advance into directories that contain a .git file */
+		if (recurse_into_dir && !contains_oitem) {
+			git_buf *full = NULL;
+			if (git_iterator_current_workdir_path(&full, info->new_iter) < 0)
+				return -1;
+			if (full && git_path_contains(full, DOT_GIT)) {
+				/* TODO: warning if not a valid git repository */
+				recurse_into_dir = false;
+			}
+		}
+
+		/* still have to look into untracked directories to match core git -
+		 * with no untracked files, directory is treated as ignored
+		 */
+		if (!recurse_into_dir &&
+			delta_type == GIT_DELTA_UNTRACKED &&
+			DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS))
+		{
+			git_diff_delta *last;
+			git_iterator_status_t untracked_state;
+
+			/* attempt to insert record for this directory */
+			if ((error = diff_delta__from_one(diff, delta_type, NULL, nitem)) != 0)
+				return error;
+
+			/* if delta wasn't created (because of rules), just skip ahead */
+			last = diff_delta__last_for_item(diff, nitem);
+			if (!last)
+				return iterator_advance(&info->nitem, info->new_iter);
+
+			/* iterate into dir looking for an actual untracked file */
+			if ((error = iterator_advance_over_with_status(
+					&info->nitem, &untracked_state, info->new_iter)) < 0)
+				return error;
+
+			/* if we found nothing or just ignored items, update the record */
+			if (untracked_state == GIT_ITERATOR_STATUS_IGNORED ||
+				untracked_state == GIT_ITERATOR_STATUS_EMPTY) {
+				last->status = GIT_DELTA_IGNORED;
+
+				/* remove the record if we don't want ignored records */
+				if (DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_INCLUDE_IGNORED)) {
+					git_vector_pop(&diff->deltas);
+					git__free(last);
+				}
+			}
+
+			return 0;
+		}
+
+		/* try to advance into directory if necessary */
+		if (recurse_into_dir) {
+			error = iterator_advance_into(&info->nitem, info->new_iter);
+
+			/* if real error or no error, proceed with iteration */
+			if (error != GIT_ENOTFOUND)
+				return error;
+			giterr_clear();
+
+			/* if directory is empty, can't advance into it, so either skip
+			 * it or ignore it
+			 */
+			if (contains_oitem)
+				return iterator_advance(&info->nitem, info->new_iter);
+			delta_type = GIT_DELTA_IGNORED;
+		}
+	}
+
+	else if (delta_type == GIT_DELTA_IGNORED &&
+		DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_RECURSE_IGNORED_DIRS) &&
+		git_iterator_current_tree_is_ignored(info->new_iter))
+		/* item contained in ignored directory, so skip over it */
+		return iterator_advance(&info->nitem, info->new_iter);
+
+	else if (info->new_iter->type != GIT_ITERATOR_TYPE_WORKDIR) {
+		if (delta_type != GIT_DELTA_CONFLICTED)
+			delta_type = GIT_DELTA_ADDED;
+	}
+
+	else if (nitem->mode == GIT_FILEMODE_COMMIT) {
+		/* ignore things that are not actual submodules */
+		if (git_submodule_lookup(NULL, info->repo, nitem->path) != 0) {
+			giterr_clear();
+			delta_type = GIT_DELTA_IGNORED;
+
+			/* if this contains a tracked item, treat as normal TREE */
+			if (contains_oitem) {
+				error = iterator_advance_into(&info->nitem, info->new_iter);
+				if (error != GIT_ENOTFOUND)
+					return error;
+
+				giterr_clear();
+				return iterator_advance(&info->nitem, info->new_iter);
+			}
+		}
+	}
+
+	else if (nitem->mode == GIT_FILEMODE_UNREADABLE) {
+		if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED))
+			delta_type = GIT_DELTA_UNTRACKED;
+		else
+			delta_type = GIT_DELTA_UNREADABLE;
+	}
+
+	/* Actually create the record for this item if necessary */
+	if ((error = diff_delta__from_one(diff, delta_type, NULL, nitem)) != 0)
+		return error;
+
+	/* If user requested TYPECHANGE records, then check for that instead of
+	 * just generating an ADDED/UNTRACKED record
+	 */
+	if (delta_type != GIT_DELTA_IGNORED &&
+		DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_TYPECHANGE_TREES) &&
+		contains_oitem)
+	{
+		/* this entry was prefixed with a tree - make TYPECHANGE */
+		git_diff_delta *last = diff_delta__last_for_item(diff, nitem);
+		if (last) {
+			last->status = GIT_DELTA_TYPECHANGE;
+			last->old_file.mode = GIT_FILEMODE_TREE;
+		}
+	}
+
+	return iterator_advance(&info->nitem, info->new_iter);
+}
+
+static int handle_unmatched_old_item(
+	git_diff *diff, diff_in_progress *info)
+{
+	git_delta_t delta_type = GIT_DELTA_DELETED;
+	int error;
+
+	/* update delta_type if this item is conflicted */
+	if (git_index_entry_is_conflict(info->oitem))
+		delta_type = GIT_DELTA_CONFLICTED;
+
+	if ((error = diff_delta__from_one(diff, delta_type, info->oitem, NULL)) < 0)
+		return error;
+
+	/* if we are generating TYPECHANGE records then check for that
+	 * instead of just generating a DELETE record
+	 */
+	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_TYPECHANGE_TREES) &&
+		entry_is_prefixed(diff, info->nitem, info->oitem))
+	{
+		/* this entry has become a tree! convert to TYPECHANGE */
+		git_diff_delta *last = diff_delta__last_for_item(diff, info->oitem);
+		if (last) {
+			last->status = GIT_DELTA_TYPECHANGE;
+			last->new_file.mode = GIT_FILEMODE_TREE;
+		}
+
+		/* If new_iter is a workdir iterator, then this situation
+		 * will certainly be followed by a series of untracked items.
+		 * Unless RECURSE_UNTRACKED_DIRS is set, skip over them...
+		 */
+		if (S_ISDIR(info->nitem->mode) &&
+			DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_RECURSE_UNTRACKED_DIRS))
+			return iterator_advance(&info->nitem, info->new_iter);
+	}
+
+	return iterator_advance(&info->oitem, info->old_iter);
+}
+
+static int handle_matched_item(
+	git_diff *diff, diff_in_progress *info)
+{
+	int error = 0;
+
+	if ((error = maybe_modified(diff, info)) < 0)
+		return error;
+
+	if (!(error = iterator_advance(&info->oitem, info->old_iter)))
+		error = iterator_advance(&info->nitem, info->new_iter);
+
+	return error;
+}
+
+int git_diff__from_iterators(
+	git_diff **diff_ptr,
+	git_repository *repo,
+	git_iterator *old_iter,
+	git_iterator *new_iter,
+	const git_diff_options *opts)
+{
+	int error = 0;
+	diff_in_progress info;
+	git_diff *diff;
+
+	*diff_ptr = NULL;
+
+	diff = diff_list_alloc(repo, old_iter, new_iter);
+	GITERR_CHECK_ALLOC(diff);
+
+	info.repo = repo;
+	info.old_iter = old_iter;
+	info.new_iter = new_iter;
+
+	/* make iterators have matching icase behavior */
+	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE)) {
+		if ((error = git_iterator_set_ignore_case(old_iter, true)) < 0 ||
+			(error = git_iterator_set_ignore_case(new_iter, true)) < 0)
+			goto cleanup;
+	}
+
+	/* finish initialization */
+	if ((error = diff_list_apply_options(diff, opts)) < 0)
+		goto cleanup;
+
+	if ((error = iterator_current(&info.oitem, old_iter)) < 0 ||
+		(error = iterator_current(&info.nitem, new_iter)) < 0)
+		goto cleanup;
+
+	/* run iterators building diffs */
+	while (!error && (info.oitem || info.nitem)) {
+		int cmp = info.oitem ?
+			(info.nitem ? diff->entrycomp(info.oitem, info.nitem) : -1) : 1;
+
+		/* create DELETED records for old items not matched in new */
+		if (cmp < 0)
+			error = handle_unmatched_old_item(diff, &info);
+
+		/* create ADDED, TRACKED, or IGNORED records for new items not
+		 * matched in old (and/or descend into directories as needed)
+		 */
+		else if (cmp > 0)
+			error = handle_unmatched_new_item(diff, &info);
+
+		/* otherwise item paths match, so create MODIFIED record
+		 * (or ADDED and DELETED pair if type changed)
+		 */
+		else
+			error = handle_matched_item(diff, &info);
+	}
+
+	diff->perf.stat_calls += old_iter->stat_calls + new_iter->stat_calls;
+
+cleanup:
+	if (!error)
+		*diff_ptr = diff;
+	else
+		git_diff_free(diff);
+
+	return error;
+}
+
+#define DIFF_FROM_ITERATORS(MAKE_FIRST, MAKE_SECOND) do { \
+	git_iterator *a = NULL, *b = NULL; \
+	char *pfx = opts ? git_pathspec_prefix(&opts->pathspec) : NULL; \
+	GITERR_CHECK_VERSION(opts, GIT_DIFF_OPTIONS_VERSION, "git_diff_options"); \
+	if (!(error = MAKE_FIRST) && !(error = MAKE_SECOND)) \
+		error = git_diff__from_iterators(diff, repo, a, b, opts); \
+	git__free(pfx); git_iterator_free(a); git_iterator_free(b); \
+} while (0)
+
+int git_diff_tree_to_tree(
+	git_diff **diff,
+	git_repository *repo,
+	git_tree *old_tree,
+	git_tree *new_tree,
+	const git_diff_options *opts)
+{
+	int error = 0;
+	git_iterator_flag_t iflag = GIT_ITERATOR_DONT_IGNORE_CASE;
+
+	assert(diff && repo);
+
+	/* for tree to tree diff, be case sensitive even if the index is
+	 * currently case insensitive, unless the user explicitly asked
+	 * for case insensitivity
+	 */
+	if (opts && (opts->flags & GIT_DIFF_IGNORE_CASE) != 0)
+		iflag = GIT_ITERATOR_IGNORE_CASE;
+
+	DIFF_FROM_ITERATORS(
+		git_iterator_for_tree(&a, old_tree, iflag, pfx, pfx),
+		git_iterator_for_tree(&b, new_tree, iflag, pfx, pfx)
+	);
+
+	return error;
+}
+
+static int diff_load_index(git_index **index, git_repository *repo)
+{
+	int error = git_repository_index__weakptr(index, repo);
+
+	/* reload the repository index when user did not pass one in */
+	if (!error && git_index_read(*index, false) < 0)
+		giterr_clear();
+
+	return error;
+}
+
+int git_diff_tree_to_index(
+	git_diff **diff,
+	git_repository *repo,
+	git_tree *old_tree,
+	git_index *index,
+	const git_diff_options *opts)
+{
+	int error = 0;
+	bool index_ignore_case = false;
+	git_iterator_flag_t iflag = GIT_ITERATOR_DONT_IGNORE_CASE |
+		GIT_ITERATOR_INCLUDE_CONFLICTS;
+
+	assert(diff && repo);
+
+	if (!index && (error = diff_load_index(&index, repo)) < 0)
+		return error;
+
+	index_ignore_case = index->ignore_case;
+
+	DIFF_FROM_ITERATORS(
+		git_iterator_for_tree(&a, old_tree, iflag, pfx, pfx),
+		git_iterator_for_index(&b, index, iflag, pfx, pfx)
+	);
+
+	/* if index is in case-insensitive order, re-sort deltas to match */
+	if (!error && index_ignore_case)
+		diff_set_ignore_case(*diff, true);
+
+	return error;
+}
+
+int git_diff_index_to_workdir(
+	git_diff **diff,
+	git_repository *repo,
+	git_index *index,
+	const git_diff_options *opts)
+{
+	int error = 0;
+
+	assert(diff && repo);
+
+	if (!index && (error = diff_load_index(&index, repo)) < 0)
+		return error;
+
+	DIFF_FROM_ITERATORS(
+		git_iterator_for_index(
+			&a, index, GIT_ITERATOR_INCLUDE_CONFLICTS, pfx, pfx),
+		git_iterator_for_workdir(
+			&b, repo, index, NULL, GIT_ITERATOR_DONT_AUTOEXPAND, pfx, pfx)
+	);
+
+	if (!error && DIFF_FLAG_IS_SET(*diff, GIT_DIFF_UPDATE_INDEX) && (*diff)->index_updated)
+		error = git_index_write(index);
+
+	return error;
+}
+
+int git_diff_tree_to_workdir(
+	git_diff **diff,
+	git_repository *repo,
+	git_tree *old_tree,
+	const git_diff_options *opts)
+{
+	int error = 0;
+	git_index *index;
+
+	assert(diff && repo);
+
+	if ((error = git_repository_index__weakptr(&index, repo)))
+		return error;
+
+	DIFF_FROM_ITERATORS(
+		git_iterator_for_tree(&a, old_tree, 0, pfx, pfx),
+		git_iterator_for_workdir(
+			&b, repo, index, old_tree, GIT_ITERATOR_DONT_AUTOEXPAND, pfx, pfx)
+	);
+
+	return error;
+}
+
+int git_diff_tree_to_workdir_with_index(
+	git_diff **diff,
+	git_repository *repo,
+	git_tree *old_tree,
+	const git_diff_options *opts)
+{
+	int error = 0;
+	git_diff *d1 = NULL, *d2 = NULL;
+	git_index *index = NULL;
+
+	assert(diff && repo);
+
+	if ((error = diff_load_index(&index, repo)) < 0)
+		return error;
+
+	if (!(error = git_diff_tree_to_index(&d1, repo, old_tree, index, opts)) &&
+		!(error = git_diff_index_to_workdir(&d2, repo, index, opts)))
+		error = git_diff_merge(d1, d2);
+
+	git_diff_free(d2);
+
+	if (error) {
+		git_diff_free(d1);
+		d1 = NULL;
+	}
+
+	*diff = d1;
+	return error;
+}
+
+size_t git_diff_num_deltas(const git_diff *diff)
+{
+	assert(diff);
+	return diff->deltas.length;
+}
+
+size_t git_diff_num_deltas_of_type(const git_diff *diff, git_delta_t type)
+{
+	size_t i, count = 0;
+	const git_diff_delta *delta;
+
+	assert(diff);
+
+	git_vector_foreach(&diff->deltas, i, delta) {
+		count += (delta->status == type);
+	}
+
+	return count;
+}
+
+const git_diff_delta *git_diff_get_delta(const git_diff *diff, size_t idx)
+{
+	assert(diff);
+	return git_vector_get(&diff->deltas, idx);
+}
+
+int git_diff_is_sorted_icase(const git_diff *diff)
+{
+	return (diff->opts.flags & GIT_DIFF_IGNORE_CASE) != 0;
+}
+
+int git_diff_get_perfdata(git_diff_perfdata *out, const git_diff *diff)
+{
+	assert(out);
+	GITERR_CHECK_VERSION(out, GIT_DIFF_PERFDATA_VERSION, "git_diff_perfdata");
+	out->stat_calls = diff->perf.stat_calls;
+	out->oid_calculations = diff->perf.oid_calculations;
+	return 0;
+}
+
+int git_diff__paired_foreach(
+	git_diff *head2idx,
+	git_diff *idx2wd,
+	int (*cb)(git_diff_delta *h2i, git_diff_delta *i2w, void *payload),
+	void *payload)
+{
+	int cmp, error = 0;
+	git_diff_delta *h2i, *i2w;
+	size_t i, j, i_max, j_max;
+	int (*strcomp)(const char *, const char *) = git__strcmp;
+	bool h2i_icase, i2w_icase, icase_mismatch;
+
+	i_max = head2idx ? head2idx->deltas.length : 0;
+	j_max = idx2wd ? idx2wd->deltas.length : 0;
+	if (!i_max && !j_max)
+		return 0;
+
+	/* At some point, tree-to-index diffs will probably never ignore case,
+	 * even if that isn't true now.  Index-to-workdir diffs may or may not
+	 * ignore case, but the index filename for the idx2wd diff should
+	 * still be using the canonical case-preserving name.
+	 *
+	 * Therefore the main thing we need to do here is make sure the diffs
+	 * are traversed in a compatible order.  To do this, we temporarily
+	 * resort a mismatched diff to get the order correct.
+	 *
+	 * In order to traverse renames in the index->workdir, we need to
+	 * ensure that we compare the index name on both sides, so we
+	 * always sort by the old name in the i2w list.
+	 */
+	h2i_icase = head2idx != NULL &&
+		(head2idx->opts.flags & GIT_DIFF_IGNORE_CASE) != 0;
+
+	i2w_icase = idx2wd != NULL &&
+		(idx2wd->opts.flags & GIT_DIFF_IGNORE_CASE) != 0;
+
+	icase_mismatch =
+		(head2idx != NULL && idx2wd != NULL && h2i_icase != i2w_icase);
+
+	if (icase_mismatch && h2i_icase) {
+		git_vector_set_cmp(&head2idx->deltas, git_diff_delta__cmp);
+		git_vector_sort(&head2idx->deltas);
+	}
+
+	if (i2w_icase && !icase_mismatch) {
+		strcomp = git__strcasecmp;
+
+		git_vector_set_cmp(&idx2wd->deltas, git_diff_delta__i2w_casecmp);
+		git_vector_sort(&idx2wd->deltas);
+	} else if (idx2wd != NULL) {
+		git_vector_set_cmp(&idx2wd->deltas, git_diff_delta__i2w_cmp);
+		git_vector_sort(&idx2wd->deltas);
+	}
+
+	for (i = 0, j = 0; i < i_max || j < j_max; ) {
+		h2i = head2idx ? GIT_VECTOR_GET(&head2idx->deltas, i) : NULL;
+		i2w = idx2wd ? GIT_VECTOR_GET(&idx2wd->deltas, j) : NULL;
+
+		cmp = !i2w ? -1 : !h2i ? 1 :
+			strcomp(h2i->new_file.path, i2w->old_file.path);
+
+		if (cmp < 0) {
+			i++; i2w = NULL;
+		} else if (cmp > 0) {
+			j++; h2i = NULL;
+		} else {
+			i++; j++;
+		}
+
+		if ((error = cb(h2i, i2w, payload)) != 0) {
+			giterr_set_after_callback(error);
+			break;
+		}
+	}
+
+	/* restore case-insensitive delta sort */
+	if (icase_mismatch && h2i_icase) {
+		git_vector_set_cmp(&head2idx->deltas, git_diff_delta__casecmp);
+		git_vector_sort(&head2idx->deltas);
+	}
+
+	/* restore idx2wd sort by new path */
+	if (idx2wd != NULL) {
+		git_vector_set_cmp(&idx2wd->deltas,
+			i2w_icase ? git_diff_delta__casecmp : git_diff_delta__cmp);
+		git_vector_sort(&idx2wd->deltas);
+	}
+
+	return error;
+}
+
+int git_diff__commit(
+	git_diff **diff,
+	git_repository *repo,
+	const git_commit *commit,
+	const git_diff_options *opts)
+{
+	git_commit *parent = NULL;
+	git_diff *commit_diff = NULL;
+	git_tree *old_tree = NULL, *new_tree = NULL;
+	size_t parents;
+	int error = 0;
+
+	if ((parents = git_commit_parentcount(commit)) > 1) {
+		char commit_oidstr[GIT_OID_HEXSZ + 1];
+
+		error = -1;
+		giterr_set(GITERR_INVALID, "Commit %s is a merge commit",
+			git_oid_tostr(commit_oidstr, GIT_OID_HEXSZ + 1, git_commit_id(commit)));
+		goto on_error;
+	}
+
+	if (parents > 0)
+		if ((error = git_commit_parent(&parent, commit, 0)) < 0 ||
+			(error = git_commit_tree(&old_tree, parent)) < 0)
+				goto on_error;
+
+	if ((error = git_commit_tree(&new_tree, commit)) < 0 ||
+		(error = git_diff_tree_to_tree(&commit_diff, repo, old_tree, new_tree, opts)) < 0)
+			goto on_error;
+
+	*diff = commit_diff;
+
+on_error:
+	git_tree_free(new_tree);
+	git_tree_free(old_tree);
+	git_commit_free(parent);
+
+	return error;
+}
+
+int git_diff_format_email__append_header_tobuf(
+	git_buf *out,
+	const git_oid *id,
+	const git_signature *author,
+	const char *summary,
+	size_t patch_no,
+	size_t total_patches,
+	bool exclude_patchno_marker)
+{
+	char idstr[GIT_OID_HEXSZ + 1];
+	char date_str[GIT_DATE_RFC2822_SZ];
+	int error = 0;
+
+	git_oid_fmt(idstr, id);
+	idstr[GIT_OID_HEXSZ] = '\0';
+
+	if ((error = git__date_rfc2822_fmt(date_str, sizeof(date_str), &author->when)) < 0)
+		return error;
+
+	error = git_buf_printf(out,
+				"From %s Mon Sep 17 00:00:00 2001\n" \
+				"From: %s <%s>\n" \
+				"Date: %s\n" \
+				"Subject: ",
+				idstr,
+				author->name, author->email,
+				date_str);
+
+	if (error < 0)
+		return error;
+
+	if (!exclude_patchno_marker) {
+		if (total_patches == 1) {
+			error = git_buf_puts(out, "[PATCH] ");
+		} else {
+			error = git_buf_printf(out, "[PATCH %"PRIuZ"/%"PRIuZ"] ", patch_no, total_patches);
+		}
+
+		if (error < 0)
+			return error;
+	}
+
+	error = git_buf_printf(out, "%s\n\n", summary);
+
+	return error;
+}
+
+int git_diff_format_email__append_patches_tobuf(
+	git_buf *out,
+	git_diff *diff)
+{
+	size_t i, deltas;
+	int error = 0;
+
+	deltas = git_diff_num_deltas(diff);
+
+	for (i = 0; i < deltas; ++i) {
+		git_patch *patch = NULL;
+
+		if ((error = git_patch_from_diff(&patch, diff, i)) >= 0)
+			error = git_patch_to_buf(out, patch);
+
+		git_patch_free(patch);
+
+		if (error < 0)
+			break;
+	}
+
+	return error;
+}
+
+int git_diff_format_email(
+	git_buf *out,
+	git_diff *diff,
+	const git_diff_format_email_options *opts)
+{
+	git_diff_stats *stats = NULL;
+	char *summary = NULL, *loc = NULL;
+	bool ignore_marker;
+	unsigned int format_flags = 0;
+	size_t allocsize;
+	int error;
+
+	assert(out && diff && opts);
+	assert(opts->summary && opts->id && opts->author);
+
+	GITERR_CHECK_VERSION(opts, GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION, "git_format_email_options");
+
+	if ((ignore_marker = opts->flags & GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER) == false) {
+		if (opts->patch_no > opts->total_patches) {
+			giterr_set(GITERR_INVALID, "patch %"PRIuZ" out of range. max %"PRIuZ, opts->patch_no, opts->total_patches);
+			return -1;
+		}
+
+		if (opts->patch_no == 0) {
+			giterr_set(GITERR_INVALID, "invalid patch no %"PRIuZ". should be >0", opts->patch_no);
+			return -1;
+		}
+	}
+
+	/* the summary we receive may not be clean.
+	 * it could potentially contain new line characters
+	 * or not be set, sanitize, */
+	if ((loc = strpbrk(opts->summary, "\r\n")) != NULL) {
+		size_t offset = 0;
+
+		if ((offset = (loc - opts->summary)) == 0) {
+			giterr_set(GITERR_INVALID, "summary is empty");
+			error = -1;
+			goto on_error;
+		}
+
+		GITERR_CHECK_ALLOC_ADD(&allocsize, offset, 1);
+		summary = git__calloc(allocsize, sizeof(char));
+		GITERR_CHECK_ALLOC(summary);
+
+		strncpy(summary, opts->summary, offset);
+	}
+
+	error = git_diff_format_email__append_header_tobuf(out,
+				opts->id, opts->author, summary == NULL ? opts->summary : summary,
+				opts->patch_no, opts->total_patches, ignore_marker);
+
+	if (error < 0)
+		goto on_error;
+
+	format_flags = GIT_DIFF_STATS_FULL | GIT_DIFF_STATS_INCLUDE_SUMMARY;
+
+	if ((error = git_buf_puts(out, "---\n")) < 0 ||
+		(error = git_diff_get_stats(&stats, diff)) < 0 ||
+		(error = git_diff_stats_to_buf(out, stats, format_flags, 0)) < 0 ||
+		(error = git_buf_putc(out, '\n')) < 0 ||
+		(error = git_diff_format_email__append_patches_tobuf(out, diff)) < 0)
+			goto on_error;
+
+	error = git_buf_puts(out, "--\nlibgit2 " LIBGIT2_VERSION "\n\n");
+
+on_error:
+	git__free(summary);
+	git_diff_stats_free(stats);
+
+	return error;
+}
+
+int git_diff_commit_as_email(
+	git_buf *out,
+	git_repository *repo,
+	git_commit *commit,
+	size_t patch_no,
+	size_t total_patches,
+	git_diff_format_email_flags_t flags,
+	const git_diff_options *diff_opts)
+{
+	git_diff *diff = NULL;
+	git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT;
+	int error;
+
+	assert (out && repo && commit);
+
+	opts.flags = flags;
+	opts.patch_no = patch_no;
+	opts.total_patches = total_patches;
+	opts.id = git_commit_id(commit);
+	opts.summary = git_commit_summary(commit);
+	opts.author = git_commit_author(commit);
+
+	if ((error = git_diff__commit(&diff, repo, commit, diff_opts)) < 0)
+		return error;
+
+	error = git_diff_format_email(out, diff, &opts);
+
+	git_diff_free(diff);
+	return error;
+}
+
+int git_diff_init_options(git_diff_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_diff_options, GIT_DIFF_OPTIONS_INIT);
+	return 0;
+}
+
+int git_diff_find_init_options(
+	git_diff_find_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_diff_find_options, GIT_DIFF_FIND_OPTIONS_INIT);
+	return 0;
+}
+
+int git_diff_format_email_init_options(
+	git_diff_format_email_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_diff_format_email_options,
+		GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT);
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff.h
new file mode 100755
index 0000000..2dfc2c6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_diff_h__
+#define INCLUDE_diff_h__
+
+#include "git2/diff.h"
+#include "git2/sys/diff.h"
+#include "git2/oid.h"
+
+#include <stdio.h>
+#include "vector.h"
+#include "buffer.h"
+#include "iterator.h"
+#include "repository.h"
+#include "pool.h"
+#include "odb.h"
+
+#define DIFF_OLD_PREFIX_DEFAULT "a/"
+#define DIFF_NEW_PREFIX_DEFAULT "b/"
+
+enum {
+	GIT_DIFFCAPS_HAS_SYMLINKS     = (1 << 0), /* symlinks on platform? */
+	GIT_DIFFCAPS_IGNORE_STAT      = (1 << 1), /* use stat? */
+	GIT_DIFFCAPS_TRUST_MODE_BITS  = (1 << 2), /* use st_mode? */
+	GIT_DIFFCAPS_TRUST_CTIME      = (1 << 3), /* use st_ctime? */
+	GIT_DIFFCAPS_USE_DEV          = (1 << 4), /* use st_dev? */
+	GIT_DIFFCAPS_TRUST_NANOSECS   = (1 << 5), /* use stat time nanoseconds */
+};
+
+#define DIFF_FLAGS_KNOWN_BINARY (GIT_DIFF_FLAG_BINARY|GIT_DIFF_FLAG_NOT_BINARY)
+#define DIFF_FLAGS_NOT_BINARY   (GIT_DIFF_FLAG_NOT_BINARY|GIT_DIFF_FLAG__NO_DATA)
+
+enum {
+	GIT_DIFF_FLAG__FREE_PATH  = (1 << 7),  /* `path` is allocated memory */
+	GIT_DIFF_FLAG__FREE_DATA  = (1 << 8),  /* internal file data is allocated */
+	GIT_DIFF_FLAG__UNMAP_DATA = (1 << 9),  /* internal file data is mmap'ed */
+	GIT_DIFF_FLAG__NO_DATA    = (1 << 10), /* file data should not be loaded */
+	GIT_DIFF_FLAG__FREE_BLOB  = (1 << 11), /* release the blob when done */
+	GIT_DIFF_FLAG__LOADED     = (1 << 12), /* file data has been loaded */
+
+	GIT_DIFF_FLAG__TO_DELETE  = (1 << 16), /* delete entry during rename det. */
+	GIT_DIFF_FLAG__TO_SPLIT   = (1 << 17), /* split entry during rename det. */
+	GIT_DIFF_FLAG__IS_RENAME_TARGET = (1 << 18),
+	GIT_DIFF_FLAG__IS_RENAME_SOURCE = (1 << 19),
+	GIT_DIFF_FLAG__HAS_SELF_SIMILARITY = (1 << 20),
+};
+
+#define GIT_DIFF_FLAG__CLEAR_INTERNAL(F) (F) = ((F) & 0x00FFFF)
+
+#define GIT_DIFF__VERBOSE  (1 << 30)
+
+struct git_diff {
+	git_refcount     rc;
+	git_repository   *repo;
+	git_diff_options opts;
+	git_vector       pathspec;
+	git_vector       deltas;    /* vector of git_diff_delta */
+	git_pool pool;
+	git_iterator_type_t old_src;
+	git_iterator_type_t new_src;
+	uint32_t diffcaps;
+	git_diff_perfdata perf;
+	bool index_updated;
+
+	int (*strcomp)(const char *, const char *);
+	int (*strncomp)(const char *, const char *, size_t);
+	int (*pfxcomp)(const char *str, const char *pfx);
+	int (*entrycomp)(const void *a, const void *b);
+};
+
+extern void git_diff__cleanup_modes(
+	uint32_t diffcaps, uint32_t *omode, uint32_t *nmode);
+
+extern void git_diff_addref(git_diff *diff);
+
+extern int git_diff_delta__cmp(const void *a, const void *b);
+extern int git_diff_delta__casecmp(const void *a, const void *b);
+
+extern const char *git_diff_delta__path(const git_diff_delta *delta);
+
+extern bool git_diff_delta__should_skip(
+	const git_diff_options *opts, const git_diff_delta *delta);
+
+extern int git_diff_delta__format_file_header(
+	git_buf *out,
+	const git_diff_delta *delta,
+	const char *oldpfx,
+	const char *newpfx,
+	int oid_strlen);
+
+extern int git_diff__oid_for_file(
+	git_oid *out, git_diff *, const char *, uint16_t, git_off_t);
+extern int git_diff__oid_for_entry(
+	git_oid *out, git_diff *, const git_index_entry *, uint16_t, const git_oid *update);
+
+extern int git_diff__from_iterators(
+	git_diff **diff_ptr,
+	git_repository *repo,
+	git_iterator *old_iter,
+	git_iterator *new_iter,
+	const git_diff_options *opts);
+
+extern int git_diff__paired_foreach(
+	git_diff *idx2head,
+	git_diff *wd2idx,
+	int (*cb)(git_diff_delta *i2h, git_diff_delta *w2i, void *payload),
+	void *payload);
+
+extern int git_diff_find_similar__hashsig_for_file(
+	void **out, const git_diff_file *f, const char *path, void *p);
+
+extern int git_diff_find_similar__hashsig_for_buf(
+	void **out, const git_diff_file *f, const char *buf, size_t len, void *p);
+
+extern void git_diff_find_similar__hashsig_free(void *sig, void *payload);
+
+extern int git_diff_find_similar__calc_similarity(
+	int *score, void *siga, void *sigb, void *payload);
+
+extern int git_diff__commit(
+	git_diff **diff, git_repository *repo, const git_commit *commit, const git_diff_options *opts);
+
+/* Merge two `git_diff`s according to the callback given by `cb`. */
+
+typedef git_diff_delta *(*git_diff__merge_cb)(
+	const git_diff_delta *left,
+	const git_diff_delta *right,
+	git_pool *pool);
+
+extern int git_diff__merge(
+	git_diff *onto, const git_diff *from, git_diff__merge_cb cb);
+
+extern git_diff_delta *git_diff__merge_like_cgit(
+	const git_diff_delta *a,
+	const git_diff_delta *b,
+	git_pool *pool);
+
+/* Duplicate a `git_diff_delta` out of the `git_pool` */
+extern git_diff_delta *git_diff__delta_dup(
+	const git_diff_delta *d, git_pool *pool);
+
+/*
+ * Sometimes a git_diff_file will have a zero size; this attempts to
+ * fill in the size without loading the blob if possible.  If that is
+ * not possible, then it will return the git_odb_object that had to be
+ * loaded and the caller can use it or dispose of it as needed.
+ */
+GIT_INLINE(int) git_diff_file__resolve_zero_size(
+	git_diff_file *file, git_odb_object **odb_obj, git_repository *repo)
+{
+	int error;
+	git_odb *odb;
+	size_t len;
+	git_otype type;
+
+	if ((error = git_repository_odb(&odb, repo)) < 0)
+		return error;
+
+	error = git_odb__read_header_or_object(
+		odb_obj, &len, &type, odb, &file->id);
+
+	git_odb_free(odb);
+
+	if (!error)
+		file->size = (git_off_t)len;
+
+	return error;
+}
+
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_driver.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_driver.c
new file mode 100755
index 0000000..bc35189
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_driver.c
@@ -0,0 +1,523 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+
+#include "git2/attr.h"
+
+#include "diff.h"
+#include "diff_patch.h"
+#include "diff_driver.h"
+#include "strmap.h"
+#include "map.h"
+#include "buf_text.h"
+#include "config.h"
+#include "repository.h"
+
+GIT__USE_STRMAP
+
+typedef enum {
+	DIFF_DRIVER_AUTO = 0,
+	DIFF_DRIVER_BINARY = 1,
+	DIFF_DRIVER_TEXT = 2,
+	DIFF_DRIVER_PATTERNLIST = 3,
+} git_diff_driver_t;
+
+typedef struct {
+	regex_t re;
+	int flags;
+} git_diff_driver_pattern;
+
+enum {
+	REG_NEGATE = (1 << 15) /* get out of the way of existing flags */
+};
+
+/* data for finding function context for a given file type */
+struct git_diff_driver {
+	git_diff_driver_t type;
+	uint32_t binary_flags;
+	uint32_t other_flags;
+	git_array_t(git_diff_driver_pattern) fn_patterns;
+	regex_t  word_pattern;
+	char name[GIT_FLEX_ARRAY];
+};
+
+#include "userdiff.h"
+
+struct git_diff_driver_registry {
+	git_strmap *drivers;
+};
+
+#define FORCE_DIFFABLE (GIT_DIFF_FORCE_TEXT | GIT_DIFF_FORCE_BINARY)
+
+static git_diff_driver global_drivers[3] = {
+	{ DIFF_DRIVER_AUTO,   0, 0, },
+	{ DIFF_DRIVER_BINARY, GIT_DIFF_FORCE_BINARY, 0 },
+	{ DIFF_DRIVER_TEXT,   GIT_DIFF_FORCE_TEXT, 0 },
+};
+
+git_diff_driver_registry *git_diff_driver_registry_new()
+{
+	git_diff_driver_registry *reg =
+		git__calloc(1, sizeof(git_diff_driver_registry));
+	if (!reg)
+		return NULL;
+
+	if (git_strmap_alloc(&reg->drivers) < 0) {
+		git_diff_driver_registry_free(reg);
+		return NULL;
+	}
+
+	return reg;
+}
+
+void git_diff_driver_registry_free(git_diff_driver_registry *reg)
+{
+	git_diff_driver *drv;
+
+	if (!reg)
+		return;
+
+	git_strmap_foreach_value(reg->drivers, drv, git_diff_driver_free(drv));
+	git_strmap_free(reg->drivers);
+	git__free(reg);
+}
+
+static int diff_driver_add_patterns(
+	git_diff_driver *drv, const char *regex_str, int regex_flags)
+{
+	int error = 0;
+	const char *scan, *end;
+	git_diff_driver_pattern *pat = NULL;
+	git_buf buf = GIT_BUF_INIT;
+
+	for (scan = regex_str; scan; scan = end) {
+		/* get pattern to fill in */
+		if ((pat = git_array_alloc(drv->fn_patterns)) == NULL) {
+			return -1;
+		}
+
+		pat->flags = regex_flags;
+		if (*scan == '!') {
+			pat->flags |= REG_NEGATE;
+			++scan;
+		}
+
+		if ((end = strchr(scan, '\n')) != NULL) {
+			error = git_buf_set(&buf, scan, end - scan);
+			end++;
+		} else {
+			error = git_buf_sets(&buf, scan);
+		}
+		if (error < 0)
+			break;
+
+		if ((error = regcomp(&pat->re, buf.ptr, regex_flags)) != 0) {
+			/*
+			 * TODO: issue a warning
+			 */
+		}
+	}
+
+	if (error && pat != NULL)
+		(void)git_array_pop(drv->fn_patterns); /* release last item */
+	git_buf_free(&buf);
+
+	/* We want to ignore bad patterns, so return success regardless */
+	return 0;
+}
+
+static int diff_driver_xfuncname(const git_config_entry *entry, void *payload)
+{
+	return diff_driver_add_patterns(payload, entry->value, REG_EXTENDED);
+}
+
+static int diff_driver_funcname(const git_config_entry *entry, void *payload)
+{
+	return diff_driver_add_patterns(payload, entry->value, 0);
+}
+
+static git_diff_driver_registry *git_repository_driver_registry(
+	git_repository *repo)
+{
+	if (!repo->diff_drivers) {
+		git_diff_driver_registry *reg = git_diff_driver_registry_new();
+		reg = git__compare_and_swap(&repo->diff_drivers, NULL, reg);
+
+		if (reg != NULL) /* if we race, free losing allocation */
+			git_diff_driver_registry_free(reg);
+	}
+
+	if (!repo->diff_drivers)
+		giterr_set(GITERR_REPOSITORY, "Unable to create diff driver registry");
+
+	return repo->diff_drivers;
+}
+
+static int diff_driver_alloc(
+	git_diff_driver **out, size_t *namelen_out, const char *name)
+{
+	git_diff_driver *driver;
+	size_t driverlen = sizeof(git_diff_driver),
+		namelen = strlen(name),
+		alloclen;
+
+	GITERR_CHECK_ALLOC_ADD(&alloclen, driverlen, namelen);
+	GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
+
+	driver = git__calloc(1, alloclen);
+	GITERR_CHECK_ALLOC(driver);
+
+	memcpy(driver->name, name, namelen);
+
+	*out = driver;
+
+	if (namelen_out)
+		*namelen_out = namelen;
+
+	return 0;
+}
+
+static int git_diff_driver_builtin(
+	git_diff_driver **out,
+	git_diff_driver_registry *reg,
+	const char *driver_name)
+{
+	int error = 0;
+	git_diff_driver_definition *ddef = NULL;
+	git_diff_driver *drv = NULL;
+	size_t idx;
+
+	for (idx = 0; idx < ARRAY_SIZE(builtin_defs); ++idx) {
+		if (!strcasecmp(driver_name, builtin_defs[idx].name)) {
+			ddef = &builtin_defs[idx];
+			break;
+		}
+	}
+	if (!ddef)
+		goto done;
+
+	if ((error = diff_driver_alloc(&drv, NULL, ddef->name)) < 0)
+		goto done;
+
+	drv->type = DIFF_DRIVER_PATTERNLIST;
+
+	if (ddef->fns &&
+		(error = diff_driver_add_patterns(
+			drv, ddef->fns, ddef->flags | REG_EXTENDED)) < 0)
+		goto done;
+
+	if (ddef->words &&
+		(error = regcomp(
+			&drv->word_pattern, ddef->words, ddef->flags | REG_EXTENDED)))
+	{
+		error = giterr_set_regex(&drv->word_pattern, error);
+		goto done;
+	}
+
+	git_strmap_insert(reg->drivers, drv->name, drv, error);
+	if (error > 0)
+		error = 0;
+
+done:
+	if (error && drv)
+		git_diff_driver_free(drv);
+	else
+		*out = drv;
+
+	return error;
+}
+
+static int git_diff_driver_load(
+	git_diff_driver **out, git_repository *repo, const char *driver_name)
+{
+	int error = 0;
+	git_diff_driver_registry *reg;
+	git_diff_driver *drv = NULL;
+	size_t namelen;
+	khiter_t pos;
+	git_config *cfg = NULL;
+	git_buf name = GIT_BUF_INIT;
+	git_config_entry *ce = NULL;
+	bool found_driver = false;
+
+	if ((reg = git_repository_driver_registry(repo)) == NULL)
+		return -1;
+
+	pos = git_strmap_lookup_index(reg->drivers, driver_name);
+	if (git_strmap_valid_index(reg->drivers, pos)) {
+		*out = git_strmap_value_at(reg->drivers, pos);
+		return 0;
+	}
+
+	if ((error = diff_driver_alloc(&drv, &namelen, driver_name)) < 0)
+		goto done;
+
+	drv->type = DIFF_DRIVER_AUTO;
+
+	/* if you can't read config for repo, just use default driver */
+	if (git_repository_config_snapshot(&cfg, repo) < 0) {
+		giterr_clear();
+		goto done;
+	}
+
+	if ((error = git_buf_printf(&name, "diff.%s.binary", driver_name)) < 0)
+		goto done;
+
+	switch (git_config__get_bool_force(cfg, name.ptr, -1)) {
+	case true:
+		/* if diff.<driver>.binary is true, just return the binary driver */
+		*out = &global_drivers[DIFF_DRIVER_BINARY];
+		goto done;
+	case false:
+		/* if diff.<driver>.binary is false, force binary checks off */
+		/* but still may have custom function context patterns, etc. */
+		drv->binary_flags = GIT_DIFF_FORCE_TEXT;
+		found_driver = true;
+		break;
+	default:
+		/* diff.<driver>.binary unspecified or "auto", so just continue */
+		break;
+	}
+
+	/* TODO: warn if diff.<name>.command or diff.<name>.textconv are set */
+
+	git_buf_truncate(&name, namelen + strlen("diff.."));
+	git_buf_put(&name, "xfuncname", strlen("xfuncname"));
+	if ((error = git_config_get_multivar_foreach(
+			cfg, name.ptr, NULL, diff_driver_xfuncname, drv)) < 0) {
+		if (error != GIT_ENOTFOUND)
+			goto done;
+		giterr_clear(); /* no diff.<driver>.xfuncname, so just continue */
+	}
+
+	git_buf_truncate(&name, namelen + strlen("diff.."));
+	git_buf_put(&name, "funcname", strlen("funcname"));
+	if ((error = git_config_get_multivar_foreach(
+			cfg, name.ptr, NULL, diff_driver_funcname, drv)) < 0) {
+		if (error != GIT_ENOTFOUND)
+			goto done;
+		giterr_clear(); /* no diff.<driver>.funcname, so just continue */
+	}
+
+	/* if we found any patterns, set driver type to use correct callback */
+	if (git_array_size(drv->fn_patterns) > 0) {
+		drv->type = DIFF_DRIVER_PATTERNLIST;
+		found_driver = true;
+	}
+
+	git_buf_truncate(&name, namelen + strlen("diff.."));
+	git_buf_put(&name, "wordregex", strlen("wordregex"));
+	if ((error = git_config__lookup_entry(&ce, cfg, name.ptr, false)) < 0)
+		goto done;
+	if (!ce || !ce->value)
+		/* no diff.<driver>.wordregex, so just continue */;
+	else if (!(error = regcomp(&drv->word_pattern, ce->value, REG_EXTENDED)))
+		found_driver = true;
+	else {
+		/* TODO: warn about bad regex instead of failure */
+		error = giterr_set_regex(&drv->word_pattern, error);
+		goto done;
+	}
+
+	/* TODO: look up diff.<driver>.algorithm to turn on minimal / patience
+	 * diff in drv->other_flags
+	 */
+
+	/* if no driver config found at all, fall back on AUTO driver */
+	if (!found_driver)
+		goto done;
+
+	/* store driver in registry */
+	git_strmap_insert(reg->drivers, drv->name, drv, error);
+	if (error < 0)
+		goto done;
+	error = 0;
+
+	*out = drv;
+
+done:
+	git_config_entry_free(ce);
+	git_buf_free(&name);
+	git_config_free(cfg);
+
+	if (!*out) {
+		int error2 = git_diff_driver_builtin(out, reg, driver_name);
+		if (!error)
+			error = error2;
+	}
+
+	if (drv && drv != *out)
+		git_diff_driver_free(drv);
+
+	return error;
+}
+
+int git_diff_driver_lookup(
+	git_diff_driver **out, git_repository *repo, const char *path)
+{
+	int error = 0;
+	const char *value;
+
+	assert(out);
+	*out = NULL;
+
+	if (!repo || !path || !strlen(path))
+		/* just use the auto value */;
+	else if ((error = git_attr_get(&value, repo, 0, path, "diff")) < 0)
+		/* return error below */;
+	else if (GIT_ATTR_UNSPECIFIED(value))
+		/* just use the auto value */;
+	else if (GIT_ATTR_FALSE(value))
+		*out = &global_drivers[DIFF_DRIVER_BINARY];
+	else if (GIT_ATTR_TRUE(value))
+		*out = &global_drivers[DIFF_DRIVER_TEXT];
+
+	/* otherwise look for driver information in config and build driver */
+	else if ((error = git_diff_driver_load(out, repo, value)) < 0) {
+		if (error == GIT_ENOTFOUND) {
+			error = 0;
+			giterr_clear();
+		}
+	}
+
+	if (!*out)
+		*out = &global_drivers[DIFF_DRIVER_AUTO];
+
+	return error;
+}
+
+void git_diff_driver_free(git_diff_driver *driver)
+{
+	size_t i;
+
+	if (!driver)
+		return;
+
+	for (i = 0; i < git_array_size(driver->fn_patterns); ++i)
+		regfree(& git_array_get(driver->fn_patterns, i)->re);
+	git_array_clear(driver->fn_patterns);
+
+	regfree(&driver->word_pattern);
+
+	git__free(driver);
+}
+
+void git_diff_driver_update_options(
+	uint32_t *option_flags, git_diff_driver *driver)
+{
+	if ((*option_flags & FORCE_DIFFABLE) == 0)
+		*option_flags |= driver->binary_flags;
+
+	*option_flags |= driver->other_flags;
+}
+
+int git_diff_driver_content_is_binary(
+	git_diff_driver *driver, const char *content, size_t content_len)
+{
+	git_buf search = GIT_BUF_INIT;
+
+	GIT_UNUSED(driver);
+
+	git_buf_attach_notowned(&search, content,
+		min(content_len, GIT_FILTER_BYTES_TO_CHECK_NUL));
+
+	/* TODO: provide encoding / binary detection callbacks that can
+	 * be UTF-8 aware, etc.  For now, instead of trying to be smart,
+	 * let's just use the simple NUL-byte detection that core git uses.
+	 */
+
+	/* previously was: if (git_buf_text_is_binary(&search)) */
+	if (git_buf_text_contains_nul(&search))
+		return 1;
+
+	return 0;
+}
+
+static int diff_context_line__simple(
+	git_diff_driver *driver, git_buf *line)
+{
+	char firstch = line->ptr[0];
+	GIT_UNUSED(driver);
+	return (git__isalpha(firstch) || firstch == '_' || firstch == '$');
+}
+
+static int diff_context_line__pattern_match(
+	git_diff_driver *driver, git_buf *line)
+{
+	size_t i, maxi = git_array_size(driver->fn_patterns);
+	regmatch_t pmatch[2];
+
+	for (i = 0; i < maxi; ++i) {
+		git_diff_driver_pattern *pat = git_array_get(driver->fn_patterns, i);
+
+		if (!regexec(&pat->re, line->ptr, 2, pmatch, 0)) {
+			if (pat->flags & REG_NEGATE)
+				return false;
+
+			/* use pmatch data to trim line data */
+			i = (pmatch[1].rm_so >= 0) ? 1 : 0;
+			git_buf_consume(line, git_buf_cstr(line) + pmatch[i].rm_so);
+			git_buf_truncate(line, pmatch[i].rm_eo - pmatch[i].rm_so);
+			git_buf_rtrim(line);
+
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static long diff_context_find(
+	const char *line,
+	long line_len,
+	char *out,
+	long out_size,
+	void *payload)
+{
+	git_diff_find_context_payload *ctxt = payload;
+
+	if (git_buf_set(&ctxt->line, line, (size_t)line_len) < 0)
+		return -1;
+	git_buf_rtrim(&ctxt->line);
+
+	if (!ctxt->line.size)
+		return -1;
+
+	if (!ctxt->match_line || !ctxt->match_line(ctxt->driver, &ctxt->line))
+		return -1;
+
+	if (out_size > (long)ctxt->line.size)
+		out_size = (long)ctxt->line.size;
+	memcpy(out, ctxt->line.ptr, (size_t)out_size);
+
+	return out_size;
+}
+
+void git_diff_find_context_init(
+	git_diff_find_context_fn *findfn_out,
+	git_diff_find_context_payload *payload_out,
+	git_diff_driver *driver)
+{
+	*findfn_out = driver ? diff_context_find : NULL;
+
+	memset(payload_out, 0, sizeof(*payload_out));
+	if (driver) {
+		payload_out->driver = driver;
+		payload_out->match_line = (driver->type == DIFF_DRIVER_PATTERNLIST) ?
+			diff_context_line__pattern_match : diff_context_line__simple;
+		git_buf_init(&payload_out->line, 0);
+	}
+}
+
+void git_diff_find_context_clear(git_diff_find_context_payload *payload)
+{
+	if (payload) {
+		git_buf_free(&payload->line);
+		payload->driver = NULL;
+	}
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_driver.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_driver.h
new file mode 100755
index 0000000..0706dcf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_driver.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_diff_driver_h__
+#define INCLUDE_diff_driver_h__
+
+#include "common.h"
+#include "buffer.h"
+
+typedef struct git_diff_driver_registry git_diff_driver_registry;
+
+git_diff_driver_registry *git_diff_driver_registry_new(void);
+void git_diff_driver_registry_free(git_diff_driver_registry *);
+
+typedef struct git_diff_driver git_diff_driver;
+
+int git_diff_driver_lookup(git_diff_driver **, git_repository *, const char *);
+void git_diff_driver_free(git_diff_driver *);
+
+/* diff option flags to force off and on for this driver */
+void git_diff_driver_update_options(uint32_t *option_flags, git_diff_driver *);
+
+/* returns -1 meaning "unknown", 0 meaning not binary, 1 meaning binary */
+int git_diff_driver_content_is_binary(
+	git_diff_driver *, const char *content, size_t content_len);
+
+typedef long (*git_diff_find_context_fn)(
+	const char *, long, char *, long, void *);
+
+typedef int (*git_diff_find_context_line)(
+	git_diff_driver *, git_buf *);
+
+typedef struct {
+	git_diff_driver *driver;
+	git_diff_find_context_line match_line;
+	git_buf line;
+} git_diff_find_context_payload;
+
+void git_diff_find_context_init(
+	git_diff_find_context_fn *findfn_out,
+	git_diff_find_context_payload *payload_out,
+	git_diff_driver *driver);
+
+void git_diff_find_context_clear(git_diff_find_context_payload *);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_file.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_file.c
new file mode 100755
index 0000000..c603628
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_file.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "git2/blob.h"
+#include "git2/submodule.h"
+#include "diff.h"
+#include "diff_file.h"
+#include "odb.h"
+#include "fileops.h"
+#include "filter.h"
+
+#define DIFF_MAX_FILESIZE 0x20000000
+
+static bool diff_file_content_binary_by_size(git_diff_file_content *fc)
+{
+	/* if we have diff opts, check max_size vs file size */
+	if ((fc->file->flags & DIFF_FLAGS_KNOWN_BINARY) == 0 &&
+		fc->opts_max_size > 0 &&
+		fc->file->size > fc->opts_max_size)
+		fc->file->flags |= GIT_DIFF_FLAG_BINARY;
+
+	return ((fc->file->flags & GIT_DIFF_FLAG_BINARY) != 0);
+}
+
+static void diff_file_content_binary_by_content(git_diff_file_content *fc)
+{
+	if ((fc->file->flags & DIFF_FLAGS_KNOWN_BINARY) != 0)
+		return;
+
+	switch (git_diff_driver_content_is_binary(
+		fc->driver, fc->map.data, fc->map.len)) {
+	case 0: fc->file->flags |= GIT_DIFF_FLAG_NOT_BINARY; break;
+	case 1: fc->file->flags |= GIT_DIFF_FLAG_BINARY; break;
+	default: break;
+	}
+}
+
+static int diff_file_content_init_common(
+	git_diff_file_content *fc, const git_diff_options *opts)
+{
+	fc->opts_flags = opts ? opts->flags : GIT_DIFF_NORMAL;
+
+	if (opts && opts->max_size >= 0)
+		fc->opts_max_size = opts->max_size ?
+			opts->max_size : DIFF_MAX_FILESIZE;
+
+	if (fc->src == GIT_ITERATOR_TYPE_EMPTY)
+		fc->src = GIT_ITERATOR_TYPE_TREE;
+
+	if (!fc->driver &&
+		git_diff_driver_lookup(&fc->driver, fc->repo, fc->file->path) < 0)
+		return -1;
+
+	/* give driver a chance to modify options */
+	git_diff_driver_update_options(&fc->opts_flags, fc->driver);
+
+	/* make sure file is conceivable mmap-able */
+	if ((git_off_t)((size_t)fc->file->size) != fc->file->size)
+		fc->file->flags |= GIT_DIFF_FLAG_BINARY;
+	/* check if user is forcing text diff the file */
+	else if (fc->opts_flags & GIT_DIFF_FORCE_TEXT) {
+		fc->file->flags &= ~GIT_DIFF_FLAG_BINARY;
+		fc->file->flags |= GIT_DIFF_FLAG_NOT_BINARY;
+	}
+	/* check if user is forcing binary diff the file */
+	else if (fc->opts_flags & GIT_DIFF_FORCE_BINARY) {
+		fc->file->flags &= ~GIT_DIFF_FLAG_NOT_BINARY;
+		fc->file->flags |= GIT_DIFF_FLAG_BINARY;
+	}
+
+	diff_file_content_binary_by_size(fc);
+
+	if ((fc->flags & GIT_DIFF_FLAG__NO_DATA) != 0) {
+		fc->flags |= GIT_DIFF_FLAG__LOADED;
+		fc->map.len  = 0;
+		fc->map.data = "";
+	}
+
+	if ((fc->flags & GIT_DIFF_FLAG__LOADED) != 0)
+		diff_file_content_binary_by_content(fc);
+
+	return 0;
+}
+
+int git_diff_file_content__init_from_diff(
+	git_diff_file_content *fc,
+	git_diff *diff,
+	git_diff_delta *delta,
+	bool use_old)
+{
+	bool has_data = true;
+
+	memset(fc, 0, sizeof(*fc));
+	fc->repo = diff->repo;
+	fc->file = use_old ? &delta->old_file : &delta->new_file;
+	fc->src  = use_old ? diff->old_src : diff->new_src;
+
+	if (git_diff_driver_lookup(&fc->driver, fc->repo, fc->file->path) < 0)
+		return -1;
+
+	switch (delta->status) {
+	case GIT_DELTA_ADDED:
+		has_data = !use_old; break;
+	case GIT_DELTA_DELETED:
+		has_data = use_old; break;
+	case GIT_DELTA_UNTRACKED:
+		has_data = !use_old &&
+			(diff->opts.flags & GIT_DIFF_SHOW_UNTRACKED_CONTENT) != 0;
+		break;
+	case GIT_DELTA_UNREADABLE:
+	case GIT_DELTA_MODIFIED:
+	case GIT_DELTA_COPIED:
+	case GIT_DELTA_RENAMED:
+		break;
+	default:
+		has_data = false;
+		break;
+	}
+
+	if (!has_data)
+		fc->flags |= GIT_DIFF_FLAG__NO_DATA;
+
+	return diff_file_content_init_common(fc, &diff->opts);
+}
+
+int git_diff_file_content__init_from_src(
+	git_diff_file_content *fc,
+	git_repository *repo,
+	const git_diff_options *opts,
+	const git_diff_file_content_src *src,
+	git_diff_file *as_file)
+{
+	memset(fc, 0, sizeof(*fc));
+	fc->repo = repo;
+	fc->file = as_file;
+	fc->blob = src->blob;
+
+	if (!src->blob && !src->buf) {
+		fc->flags |= GIT_DIFF_FLAG__NO_DATA;
+	} else {
+		fc->flags |= GIT_DIFF_FLAG__LOADED;
+		fc->file->flags |= GIT_DIFF_FLAG_VALID_ID;
+		fc->file->mode = GIT_FILEMODE_BLOB;
+
+		if (src->blob) {
+			fc->file->size = git_blob_rawsize(src->blob);
+			git_oid_cpy(&fc->file->id, git_blob_id(src->blob));
+
+			fc->map.len  = (size_t)fc->file->size;
+			fc->map.data = (char *)git_blob_rawcontent(src->blob);
+		} else {
+			fc->file->size = src->buflen;
+			git_odb_hash(&fc->file->id, src->buf, src->buflen, GIT_OBJ_BLOB);
+
+			fc->map.len  = src->buflen;
+			fc->map.data = (char *)src->buf;
+		}
+	}
+
+	return diff_file_content_init_common(fc, opts);
+}
+
+static int diff_file_content_commit_to_str(
+	git_diff_file_content *fc, bool check_status)
+{
+	char oid[GIT_OID_HEXSZ+1];
+	git_buf content = GIT_BUF_INIT;
+	const char *status = "";
+
+	if (check_status) {
+		int error = 0;
+		git_submodule *sm = NULL;
+		unsigned int sm_status = 0;
+		const git_oid *sm_head;
+
+		if ((error = git_submodule_lookup(&sm, fc->repo, fc->file->path)) < 0) {
+			/* GIT_EEXISTS means a "submodule" that has not been git added */
+			if (error == GIT_EEXISTS) {
+				giterr_clear();
+				error = 0;
+			}
+			return error;
+		}
+
+		if ((error = git_submodule_status(&sm_status, fc->repo, fc->file->path, GIT_SUBMODULE_IGNORE_UNSPECIFIED)) < 0) {
+			git_submodule_free(sm);
+			return error;
+		}
+
+		/* update OID if we didn't have it previously */
+		if ((fc->file->flags & GIT_DIFF_FLAG_VALID_ID) == 0 &&
+			((sm_head = git_submodule_wd_id(sm)) != NULL ||
+			 (sm_head = git_submodule_head_id(sm)) != NULL))
+		{
+			git_oid_cpy(&fc->file->id, sm_head);
+			fc->file->flags |= GIT_DIFF_FLAG_VALID_ID;
+		}
+
+		if (GIT_SUBMODULE_STATUS_IS_WD_DIRTY(sm_status))
+			status = "-dirty";
+
+		git_submodule_free(sm);
+	}
+
+	git_oid_tostr(oid, sizeof(oid), &fc->file->id);
+	if (git_buf_printf(&content, "Subproject commit %s%s\n", oid, status) < 0)
+		return -1;
+
+	fc->map.len  = git_buf_len(&content);
+	fc->map.data = git_buf_detach(&content);
+	fc->flags |= GIT_DIFF_FLAG__FREE_DATA;
+
+	return 0;
+}
+
+static int diff_file_content_load_blob(
+	git_diff_file_content *fc,
+	git_diff_options *opts)
+{
+	int error = 0;
+	git_odb_object *odb_obj = NULL;
+
+	if (git_oid_iszero(&fc->file->id))
+		return 0;
+
+	if (fc->file->mode == GIT_FILEMODE_COMMIT)
+		return diff_file_content_commit_to_str(fc, false);
+
+	/* if we don't know size, try to peek at object header first */
+	if (!fc->file->size) {
+		if ((error = git_diff_file__resolve_zero_size(
+				fc->file, &odb_obj, fc->repo)) < 0)
+			return error;
+	}
+
+	if ((opts->flags & GIT_DIFF_SHOW_BINARY) == 0 &&
+		diff_file_content_binary_by_size(fc))
+		return 0;
+
+	if (odb_obj != NULL) {
+		error = git_object__from_odb_object(
+			(git_object **)&fc->blob, fc->repo, odb_obj, GIT_OBJ_BLOB);
+		git_odb_object_free(odb_obj);
+	} else {
+		error = git_blob_lookup(
+			(git_blob **)&fc->blob, fc->repo, &fc->file->id);
+	}
+
+	if (!error) {
+		fc->flags |= GIT_DIFF_FLAG__FREE_BLOB;
+		fc->map.data = (void *)git_blob_rawcontent(fc->blob);
+		fc->map.len  = (size_t)git_blob_rawsize(fc->blob);
+	}
+
+	return error;
+}
+
+static int diff_file_content_load_workdir_symlink(
+	git_diff_file_content *fc, git_buf *path)
+{
+	ssize_t alloc_len, read_len;
+
+	/* link path on disk could be UTF-16, so prepare a buffer that is
+	 * big enough to handle some UTF-8 data expansion
+	 */
+	alloc_len = (ssize_t)(fc->file->size * 2) + 1;
+
+	fc->map.data = git__calloc(alloc_len, sizeof(char));
+	GITERR_CHECK_ALLOC(fc->map.data);
+
+	fc->flags |= GIT_DIFF_FLAG__FREE_DATA;
+
+	read_len = p_readlink(git_buf_cstr(path), fc->map.data, alloc_len);
+	if (read_len < 0) {
+		giterr_set(GITERR_OS, "Failed to read symlink '%s'", fc->file->path);
+		return -1;
+	}
+
+	fc->map.len = read_len;
+	return 0;
+}
+
+static int diff_file_content_load_workdir_file(
+	git_diff_file_content *fc,
+	git_buf *path,
+	git_diff_options *diff_opts)
+{
+	int error = 0;
+	git_filter_list *fl = NULL;
+	git_file fd = git_futils_open_ro(git_buf_cstr(path));
+	git_buf raw = GIT_BUF_INIT;
+
+	if (fd < 0)
+		return fd;
+
+	if (!fc->file->size &&
+		!(fc->file->size = git_futils_filesize(fd)))
+		goto cleanup;
+
+	if ((diff_opts->flags & GIT_DIFF_SHOW_BINARY) == 0 &&
+		diff_file_content_binary_by_size(fc))
+		goto cleanup;
+
+	if ((error = git_filter_list_load(
+			&fl, fc->repo, NULL, fc->file->path,
+			GIT_FILTER_TO_ODB, GIT_FILTER_ALLOW_UNSAFE)) < 0)
+		goto cleanup;
+
+	/* if there are no filters, try to mmap the file */
+	if (fl == NULL) {
+		if (!(error = git_futils_mmap_ro(
+				&fc->map, fd, 0, (size_t)fc->file->size))) {
+			fc->flags |= GIT_DIFF_FLAG__UNMAP_DATA;
+			goto cleanup;
+		}
+
+		/* if mmap failed, fall through to try readbuffer below */
+		giterr_clear();
+	}
+
+	if (!(error = git_futils_readbuffer_fd(&raw, fd, (size_t)fc->file->size))) {
+		git_buf out = GIT_BUF_INIT;
+
+		error = git_filter_list_apply_to_data(&out, fl, &raw);
+
+		if (out.ptr != raw.ptr)
+			git_buf_free(&raw);
+
+		if (!error) {
+			fc->map.len  = out.size;
+			fc->map.data = out.ptr;
+			fc->flags |= GIT_DIFF_FLAG__FREE_DATA;
+		}
+	}
+
+cleanup:
+	git_filter_list_free(fl);
+	p_close(fd);
+
+	return error;
+}
+
+static int diff_file_content_load_workdir(
+	git_diff_file_content *fc,
+	git_diff_options *diff_opts)
+{
+	int error = 0;
+	git_buf path = GIT_BUF_INIT;
+
+	if (fc->file->mode == GIT_FILEMODE_COMMIT)
+		return diff_file_content_commit_to_str(fc, true);
+
+	if (fc->file->mode == GIT_FILEMODE_TREE)
+		return 0;
+
+	if (git_buf_joinpath(
+			&path, git_repository_workdir(fc->repo), fc->file->path) < 0)
+		return -1;
+
+	if (S_ISLNK(fc->file->mode))
+		error = diff_file_content_load_workdir_symlink(fc, &path);
+	else
+		error = diff_file_content_load_workdir_file(fc, &path, diff_opts);
+
+	/* once data is loaded, update OID if we didn't have it previously */
+	if (!error && (fc->file->flags & GIT_DIFF_FLAG_VALID_ID) == 0) {
+		error = git_odb_hash(
+			&fc->file->id, fc->map.data, fc->map.len, GIT_OBJ_BLOB);
+		fc->file->flags |= GIT_DIFF_FLAG_VALID_ID;
+	}
+
+	git_buf_free(&path);
+	return error;
+}
+
+int git_diff_file_content__load(
+	git_diff_file_content *fc,
+	git_diff_options *diff_opts)
+{
+	int error = 0;
+
+	if ((fc->flags & GIT_DIFF_FLAG__LOADED) != 0)
+		return 0;
+
+	if ((fc->file->flags & GIT_DIFF_FLAG_BINARY) != 0 &&
+		(diff_opts->flags & GIT_DIFF_SHOW_BINARY) == 0)
+		return 0;
+
+	if (fc->src == GIT_ITERATOR_TYPE_WORKDIR)
+		error = diff_file_content_load_workdir(fc, diff_opts);
+	else
+		error = diff_file_content_load_blob(fc, diff_opts);
+	if (error)
+		return error;
+
+	fc->flags |= GIT_DIFF_FLAG__LOADED;
+
+	diff_file_content_binary_by_content(fc);
+
+	return 0;
+}
+
+void git_diff_file_content__unload(git_diff_file_content *fc)
+{
+	if ((fc->flags & GIT_DIFF_FLAG__LOADED) == 0)
+		return;
+
+	if (fc->flags & GIT_DIFF_FLAG__FREE_DATA) {
+		git__free(fc->map.data);
+		fc->map.data = "";
+		fc->map.len  = 0;
+		fc->flags &= ~GIT_DIFF_FLAG__FREE_DATA;
+	}
+	else if (fc->flags & GIT_DIFF_FLAG__UNMAP_DATA) {
+		git_futils_mmap_free(&fc->map);
+		fc->map.data = "";
+		fc->map.len  = 0;
+		fc->flags &= ~GIT_DIFF_FLAG__UNMAP_DATA;
+	}
+
+	if (fc->flags & GIT_DIFF_FLAG__FREE_BLOB) {
+		git_blob_free((git_blob *)fc->blob);
+		fc->blob = NULL;
+		fc->flags &= ~GIT_DIFF_FLAG__FREE_BLOB;
+	}
+
+	fc->flags &= ~GIT_DIFF_FLAG__LOADED;
+}
+
+void git_diff_file_content__clear(git_diff_file_content *fc)
+{
+	git_diff_file_content__unload(fc);
+
+	/* for now, nothing else to do */
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_file.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_file.h
new file mode 100755
index 0000000..0d54b6d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_file.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_diff_file_h__
+#define INCLUDE_diff_file_h__
+
+#include "common.h"
+#include "diff.h"
+#include "diff_driver.h"
+#include "map.h"
+
+/* expanded information for one side of a delta */
+typedef struct {
+	git_repository *repo;
+	git_diff_file *file;
+	git_diff_driver *driver;
+	uint32_t flags;
+	uint32_t opts_flags;
+	git_off_t opts_max_size;
+	git_iterator_type_t src;
+	const git_blob *blob;
+	git_map map;
+} git_diff_file_content;
+
+extern int git_diff_file_content__init_from_diff(
+	git_diff_file_content *fc,
+	git_diff *diff,
+	git_diff_delta *delta,
+	bool use_old);
+
+typedef struct {
+	const git_blob *blob;
+	const void *buf;
+	size_t buflen;
+	const char *as_path;
+} git_diff_file_content_src;
+
+#define GIT_DIFF_FILE_CONTENT_SRC__BLOB(BLOB,PATH) { (BLOB),NULL,0,(PATH) }
+#define GIT_DIFF_FILE_CONTENT_SRC__BUF(BUF,LEN,PATH) { NULL,(BUF),(LEN),(PATH) }
+
+extern int git_diff_file_content__init_from_src(
+	git_diff_file_content *fc,
+	git_repository *repo,
+	const git_diff_options *opts,
+	const git_diff_file_content_src *src,
+	git_diff_file *as_file);
+
+/* this loads the blob/file-on-disk as needed */
+extern int git_diff_file_content__load(
+	git_diff_file_content *fc,
+	git_diff_options *diff_opts);
+
+/* this releases the blob/file-in-memory */
+extern void git_diff_file_content__unload(git_diff_file_content *fc);
+
+/* this unloads and also releases any other resources */
+extern void git_diff_file_content__clear(git_diff_file_content *fc);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_patch.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_patch.c
new file mode 100755
index 0000000..50faa3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_patch.c
@@ -0,0 +1,1142 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "git2/blob.h"
+#include "diff.h"
+#include "diff_file.h"
+#include "diff_driver.h"
+#include "diff_patch.h"
+#include "diff_xdiff.h"
+#include "delta.h"
+#include "zstream.h"
+#include "fileops.h"
+
+static void diff_output_init(
+	git_diff_output*, const git_diff_options*, git_diff_file_cb,
+	git_diff_binary_cb, git_diff_hunk_cb, git_diff_line_cb, void*);
+
+static void diff_output_to_patch(git_diff_output *, git_patch *);
+
+static void diff_patch_update_binary(git_patch *patch)
+{
+	if ((patch->delta->flags & DIFF_FLAGS_KNOWN_BINARY) != 0)
+		return;
+
+	if ((patch->ofile.file->flags & GIT_DIFF_FLAG_BINARY) != 0 ||
+		(patch->nfile.file->flags & GIT_DIFF_FLAG_BINARY) != 0)
+		patch->delta->flags |= GIT_DIFF_FLAG_BINARY;
+
+	else if (patch->ofile.file->size > GIT_XDIFF_MAX_SIZE ||
+			 patch->nfile.file->size > GIT_XDIFF_MAX_SIZE)
+		patch->delta->flags |= GIT_DIFF_FLAG_BINARY;
+
+	else if ((patch->ofile.file->flags & DIFF_FLAGS_NOT_BINARY) != 0 &&
+			 (patch->nfile.file->flags & DIFF_FLAGS_NOT_BINARY) != 0)
+		patch->delta->flags |= GIT_DIFF_FLAG_NOT_BINARY;
+}
+
+static void diff_patch_init_common(git_patch *patch)
+{
+	diff_patch_update_binary(patch);
+
+	patch->flags |= GIT_DIFF_PATCH_INITIALIZED;
+
+	if (patch->diff)
+		git_diff_addref(patch->diff);
+}
+
+static int diff_patch_normalize_options(
+	git_diff_options *out,
+	const git_diff_options *opts)
+{
+	if (opts) {
+		GITERR_CHECK_VERSION(opts, GIT_DIFF_OPTIONS_VERSION, "git_diff_options");
+		memcpy(out, opts, sizeof(git_diff_options));
+	} else {
+		git_diff_options default_opts = GIT_DIFF_OPTIONS_INIT;
+		memcpy(out, &default_opts, sizeof(git_diff_options));
+	}
+
+	out->old_prefix = opts && opts->old_prefix ?
+		git__strdup(opts->old_prefix) :
+		git__strdup(DIFF_OLD_PREFIX_DEFAULT);
+
+	out->new_prefix = opts && opts->new_prefix ?
+		git__strdup(opts->new_prefix) :
+		git__strdup(DIFF_NEW_PREFIX_DEFAULT);
+
+	GITERR_CHECK_ALLOC(out->old_prefix);
+	GITERR_CHECK_ALLOC(out->new_prefix);
+
+	return 0;
+}
+
+static int diff_patch_init_from_diff(
+	git_patch *patch, git_diff *diff, size_t delta_index)
+{
+	int error = 0;
+
+	memset(patch, 0, sizeof(*patch));
+	patch->diff  = diff;
+	patch->delta = git_vector_get(&diff->deltas, delta_index);
+	patch->delta_index = delta_index;
+
+	if ((error = diff_patch_normalize_options(
+			&patch->diff_opts, &diff->opts)) < 0 ||
+		(error = git_diff_file_content__init_from_diff(
+			&patch->ofile, diff, patch->delta, true)) < 0 ||
+		(error = git_diff_file_content__init_from_diff(
+			&patch->nfile, diff, patch->delta, false)) < 0)
+		return error;
+
+	diff_patch_init_common(patch);
+
+	return 0;
+}
+
+static int diff_patch_alloc_from_diff(
+	git_patch **out, git_diff *diff, size_t delta_index)
+{
+	int error;
+	git_patch *patch = git__calloc(1, sizeof(git_patch));
+	GITERR_CHECK_ALLOC(patch);
+
+	if (!(error = diff_patch_init_from_diff(patch, diff, delta_index))) {
+		patch->flags |= GIT_DIFF_PATCH_ALLOCATED;
+		GIT_REFCOUNT_INC(patch);
+	} else {
+		git__free(patch);
+		patch = NULL;
+	}
+
+	*out = patch;
+	return error;
+}
+
+GIT_INLINE(bool) should_skip_binary(git_patch *patch, git_diff_file *file)
+{
+	if ((patch->diff_opts.flags & GIT_DIFF_SHOW_BINARY) != 0)
+		return false;
+
+	return (file->flags & GIT_DIFF_FLAG_BINARY) != 0;
+}
+
+static bool diff_patch_diffable(git_patch *patch)
+{
+	size_t olen, nlen;
+
+	if (patch->delta->status == GIT_DELTA_UNMODIFIED)
+		return false;
+
+	/* if we've determined this to be binary (and we are not showing binary
+	 * data) then we have skipped loading the map data.  instead, query the
+	 * file data itself.
+	 */
+	if ((patch->delta->flags & GIT_DIFF_FLAG_BINARY) != 0 &&
+		(patch->diff_opts.flags & GIT_DIFF_SHOW_BINARY) == 0) {
+		olen = (size_t)patch->ofile.file->size;
+		nlen = (size_t)patch->nfile.file->size;
+	} else {
+		olen = patch->ofile.map.len;
+		nlen = patch->nfile.map.len;
+	}
+
+	/* if both sides are empty, files are identical */
+	if (!olen && !nlen)
+		return false;
+
+	/* otherwise, check the file sizes and the oid */
+	return (olen != nlen ||
+		!git_oid_equal(&patch->ofile.file->id, &patch->nfile.file->id));
+}
+
+static int diff_patch_load(git_patch *patch, git_diff_output *output)
+{
+	int error = 0;
+	bool incomplete_data;
+
+	if ((patch->flags & GIT_DIFF_PATCH_LOADED) != 0)
+		return 0;
+
+	/* if no hunk and data callbacks and user doesn't care if data looks
+	 * binary, then there is no need to actually load the data
+	 */
+	if ((patch->ofile.opts_flags & GIT_DIFF_SKIP_BINARY_CHECK) != 0 &&
+		output && !output->binary_cb && !output->hunk_cb && !output->data_cb)
+		return 0;
+
+	incomplete_data =
+		(((patch->ofile.flags & GIT_DIFF_FLAG__NO_DATA) != 0 ||
+		  (patch->ofile.file->flags & GIT_DIFF_FLAG_VALID_ID) != 0) &&
+		 ((patch->nfile.flags & GIT_DIFF_FLAG__NO_DATA) != 0 ||
+		  (patch->nfile.file->flags & GIT_DIFF_FLAG_VALID_ID) != 0));
+
+	/* always try to load workdir content first because filtering may
+	 * need 2x data size and this minimizes peak memory footprint
+	 */
+	if (patch->ofile.src == GIT_ITERATOR_TYPE_WORKDIR) {
+		if ((error = git_diff_file_content__load(
+				&patch->ofile, &patch->diff_opts)) < 0 ||
+			should_skip_binary(patch, patch->ofile.file))
+			goto cleanup;
+	}
+	if (patch->nfile.src == GIT_ITERATOR_TYPE_WORKDIR) {
+		if ((error = git_diff_file_content__load(
+				&patch->nfile, &patch->diff_opts)) < 0 ||
+			should_skip_binary(patch, patch->nfile.file))
+			goto cleanup;
+	}
+
+	/* once workdir has been tried, load other data as needed */
+	if (patch->ofile.src != GIT_ITERATOR_TYPE_WORKDIR) {
+		if ((error = git_diff_file_content__load(
+				&patch->ofile, &patch->diff_opts)) < 0 ||
+			should_skip_binary(patch, patch->ofile.file))
+			goto cleanup;
+	}
+	if (patch->nfile.src != GIT_ITERATOR_TYPE_WORKDIR) {
+		if ((error = git_diff_file_content__load(
+				&patch->nfile, &patch->diff_opts)) < 0 ||
+			should_skip_binary(patch, patch->nfile.file))
+			goto cleanup;
+	}
+
+	/* if previously missing an oid, and now that we have it the two sides
+	 * are the same (and not submodules), update MODIFIED -> UNMODIFIED
+	 */
+	if (incomplete_data &&
+		patch->ofile.file->mode == patch->nfile.file->mode &&
+		patch->ofile.file->mode != GIT_FILEMODE_COMMIT &&
+		git_oid_equal(&patch->ofile.file->id, &patch->nfile.file->id) &&
+		patch->delta->status == GIT_DELTA_MODIFIED) /* not RENAMED/COPIED! */
+		patch->delta->status = GIT_DELTA_UNMODIFIED;
+
+cleanup:
+	diff_patch_update_binary(patch);
+
+	if (!error) {
+		if (diff_patch_diffable(patch))
+			patch->flags |= GIT_DIFF_PATCH_DIFFABLE;
+
+		patch->flags |= GIT_DIFF_PATCH_LOADED;
+	}
+
+	return error;
+}
+
+static int diff_patch_invoke_file_callback(
+	git_patch *patch, git_diff_output *output)
+{
+	float progress = patch->diff ?
+		((float)patch->delta_index / patch->diff->deltas.length) : 1.0f;
+
+	if (!output->file_cb)
+		return 0;
+
+	return giterr_set_after_callback_function(
+		output->file_cb(patch->delta, progress, output->payload),
+		"git_patch");
+}
+
+static int create_binary(
+	git_diff_binary_t *out_type,
+	char **out_data,
+	size_t *out_datalen,
+	size_t *out_inflatedlen,
+	const char *a_data,
+	size_t a_datalen,
+	const char *b_data,
+	size_t b_datalen)
+{
+	git_buf deflate = GIT_BUF_INIT, delta = GIT_BUF_INIT;
+	unsigned long delta_data_len;
+	int error;
+
+	/* The git_delta function accepts unsigned long only */
+	if (!git__is_ulong(a_datalen) || !git__is_ulong(b_datalen))
+		return GIT_EBUFS;
+
+	if ((error = git_zstream_deflatebuf(&deflate, b_data, b_datalen)) < 0)
+		goto done;
+
+	/* The git_delta function accepts unsigned long only */
+	if (!git__is_ulong(deflate.size)) {
+		error = GIT_EBUFS;
+		goto done;
+	}
+
+	if (a_datalen && b_datalen) {
+		void *delta_data = git_delta(
+			a_data, (unsigned long)a_datalen,
+			b_data, (unsigned long)b_datalen,
+			&delta_data_len, (unsigned long)deflate.size);
+
+		if (delta_data) {
+			error = git_zstream_deflatebuf(
+				&delta, delta_data, (size_t)delta_data_len);
+
+			git__free(delta_data);
+
+			if (error < 0)
+				goto done;
+		}
+	}
+
+	if (delta.size && delta.size < deflate.size) {
+		*out_type = GIT_DIFF_BINARY_DELTA;
+		*out_datalen = delta.size;
+		*out_data = git_buf_detach(&delta);
+		*out_inflatedlen = delta_data_len;
+	} else {
+		*out_type = GIT_DIFF_BINARY_LITERAL;
+		*out_datalen = deflate.size;
+		*out_data = git_buf_detach(&deflate);
+		*out_inflatedlen = b_datalen;
+	}
+
+done:
+	git_buf_free(&deflate);
+	git_buf_free(&delta);
+
+	return error;
+}
+
+static int diff_binary(git_diff_output *output, git_patch *patch)
+{
+	git_diff_binary binary = {{0}};
+	const char *old_data = patch->ofile.map.data;
+	const char *new_data = patch->nfile.map.data;
+	size_t old_len = patch->ofile.map.len,
+		new_len = patch->nfile.map.len;
+	int error;
+
+	/* Create the old->new delta (as the "new" side of the patch),
+	 * and the new->old delta (as the "old" side)
+	 */
+	if ((error = create_binary(&binary.old_file.type,
+			(char **)&binary.old_file.data,
+			&binary.old_file.datalen,
+			&binary.old_file.inflatedlen,
+			new_data, new_len, old_data, old_len)) < 0 ||
+		(error = create_binary(&binary.new_file.type,
+			(char **)&binary.new_file.data,
+			&binary.new_file.datalen,
+			&binary.new_file.inflatedlen,
+			old_data, old_len, new_data, new_len)) < 0)
+		return error;
+
+	error = giterr_set_after_callback_function(
+		output->binary_cb(patch->delta, &binary, output->payload),
+		"git_patch");
+
+	git__free((char *) binary.old_file.data);
+	git__free((char *) binary.new_file.data);
+
+	return error;
+}
+
+static int diff_patch_generate(git_patch *patch, git_diff_output *output)
+{
+	int error = 0;
+
+	if ((patch->flags & GIT_DIFF_PATCH_DIFFED) != 0)
+		return 0;
+
+	/* if we are not looking at the binary or text data, don't do the diff */
+	if (!output->binary_cb && !output->hunk_cb && !output->data_cb)
+		return 0;
+
+	if ((patch->flags & GIT_DIFF_PATCH_LOADED) == 0 &&
+		(error = diff_patch_load(patch, output)) < 0)
+		return error;
+
+	if ((patch->flags & GIT_DIFF_PATCH_DIFFABLE) == 0)
+		return 0;
+
+	if ((patch->delta->flags & GIT_DIFF_FLAG_BINARY) != 0) {
+		if (output->binary_cb)
+			error = diff_binary(output, patch);
+	}
+	else {
+		if (output->diff_cb)
+			error = output->diff_cb(output, patch);
+	}
+
+	patch->flags |= GIT_DIFF_PATCH_DIFFED;
+	return error;
+}
+
+static void diff_patch_free(git_patch *patch)
+{
+	git_diff_file_content__clear(&patch->ofile);
+	git_diff_file_content__clear(&patch->nfile);
+
+	git_array_clear(patch->lines);
+	git_array_clear(patch->hunks);
+
+	git_diff_free(patch->diff); /* decrements refcount */
+	patch->diff = NULL;
+
+	git_pool_clear(&patch->flattened);
+
+	git__free((char *)patch->diff_opts.old_prefix);
+	git__free((char *)patch->diff_opts.new_prefix);
+
+	git__free((char *)patch->binary.old_file.data);
+	git__free((char *)patch->binary.new_file.data);
+
+	if (patch->flags & GIT_DIFF_PATCH_ALLOCATED)
+		git__free(patch);
+}
+
+static int diff_required(git_diff *diff, const char *action)
+{
+	if (diff)
+		return 0;
+	giterr_set(GITERR_INVALID, "Must provide valid diff to %s", action);
+	return -1;
+}
+
+int git_diff_foreach(
+	git_diff *diff,
+	git_diff_file_cb file_cb,
+	git_diff_binary_cb binary_cb,
+	git_diff_hunk_cb hunk_cb,
+	git_diff_line_cb data_cb,
+	void *payload)
+{
+	int error = 0;
+	git_xdiff_output xo;
+	size_t idx;
+	git_patch patch;
+
+	if ((error = diff_required(diff, "git_diff_foreach")) < 0)
+		return error;
+
+	memset(&xo, 0, sizeof(xo));
+	memset(&patch, 0, sizeof(patch));
+	diff_output_init(
+		&xo.output, &diff->opts, file_cb, binary_cb, hunk_cb, data_cb, payload);
+	git_xdiff_init(&xo, &diff->opts);
+
+	git_vector_foreach(&diff->deltas, idx, patch.delta) {
+
+		/* check flags against patch status */
+		if (git_diff_delta__should_skip(&diff->opts, patch.delta))
+			continue;
+
+		if (binary_cb || hunk_cb || data_cb) {
+			if ((error = diff_patch_init_from_diff(&patch, diff, idx)) != 0 ||
+				(error = diff_patch_load(&patch, &xo.output)) != 0)
+				return error;
+		}
+
+		if ((error = diff_patch_invoke_file_callback(&patch, &xo.output)) == 0) {
+			if (binary_cb || hunk_cb || data_cb)
+					error = diff_patch_generate(&patch, &xo.output);
+		}
+
+		git_patch_free(&patch);
+
+		if (error)
+			break;
+	}
+
+	return error;
+}
+
+typedef struct {
+	git_patch patch;
+	git_diff_delta delta;
+	char paths[GIT_FLEX_ARRAY];
+} diff_patch_with_delta;
+
+static int diff_single_generate(diff_patch_with_delta *pd, git_xdiff_output *xo)
+{
+	int error = 0;
+	git_patch *patch = &pd->patch;
+	bool has_old = ((patch->ofile.flags & GIT_DIFF_FLAG__NO_DATA) == 0);
+	bool has_new = ((patch->nfile.flags & GIT_DIFF_FLAG__NO_DATA) == 0);
+
+	pd->delta.status = has_new ?
+		(has_old ? GIT_DELTA_MODIFIED : GIT_DELTA_ADDED) :
+		(has_old ? GIT_DELTA_DELETED : GIT_DELTA_UNTRACKED);
+
+	if (git_oid_equal(&patch->nfile.file->id, &patch->ofile.file->id))
+		pd->delta.status = GIT_DELTA_UNMODIFIED;
+
+	patch->delta = &pd->delta;
+
+	diff_patch_init_common(patch);
+
+	if (pd->delta.status == GIT_DELTA_UNMODIFIED &&
+		!(patch->ofile.opts_flags & GIT_DIFF_INCLUDE_UNMODIFIED))
+		return error;
+
+	error = diff_patch_invoke_file_callback(patch, (git_diff_output *)xo);
+
+	if (!error)
+		error = diff_patch_generate(patch, (git_diff_output *)xo);
+
+	return error;
+}
+
+static int diff_patch_from_sources(
+	diff_patch_with_delta *pd,
+	git_xdiff_output *xo,
+	git_diff_file_content_src *oldsrc,
+	git_diff_file_content_src *newsrc,
+	const git_diff_options *opts)
+{
+	int error = 0;
+	git_repository *repo =
+		oldsrc->blob ? git_blob_owner(oldsrc->blob) :
+		newsrc->blob ? git_blob_owner(newsrc->blob) : NULL;
+	git_diff_file *lfile = &pd->delta.old_file, *rfile = &pd->delta.new_file;
+	git_diff_file_content *ldata = &pd->patch.ofile, *rdata = &pd->patch.nfile;
+
+	if ((error = diff_patch_normalize_options(&pd->patch.diff_opts, opts)) < 0)
+		return error;
+
+	if (opts && (opts->flags & GIT_DIFF_REVERSE) != 0) {
+		void *tmp = lfile; lfile = rfile; rfile = tmp;
+		tmp = ldata; ldata = rdata; rdata = tmp;
+	}
+
+	pd->patch.delta = &pd->delta;
+
+	if (!oldsrc->as_path) {
+		if (newsrc->as_path)
+			oldsrc->as_path = newsrc->as_path;
+		else
+			oldsrc->as_path = newsrc->as_path = "file";
+	}
+	else if (!newsrc->as_path)
+		newsrc->as_path = oldsrc->as_path;
+
+	lfile->path = oldsrc->as_path;
+	rfile->path = newsrc->as_path;
+
+	if ((error = git_diff_file_content__init_from_src(
+			ldata, repo, opts, oldsrc, lfile)) < 0 ||
+		(error = git_diff_file_content__init_from_src(
+			rdata, repo, opts, newsrc, rfile)) < 0)
+		return error;
+
+	return diff_single_generate(pd, xo);
+}
+
+static int diff_patch_with_delta_alloc(
+	diff_patch_with_delta **out,
+	const char **old_path,
+	const char **new_path)
+{
+	diff_patch_with_delta *pd;
+	size_t old_len = *old_path ? strlen(*old_path) : 0;
+	size_t new_len = *new_path ? strlen(*new_path) : 0;
+	size_t alloc_len;
+
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, sizeof(*pd), old_len);
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, new_len);
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
+
+	*out = pd = git__calloc(1, alloc_len);
+	GITERR_CHECK_ALLOC(pd);
+
+	pd->patch.flags = GIT_DIFF_PATCH_ALLOCATED;
+
+	if (*old_path) {
+		memcpy(&pd->paths[0], *old_path, old_len);
+		*old_path = &pd->paths[0];
+	} else if (*new_path)
+		*old_path = &pd->paths[old_len + 1];
+
+	if (*new_path) {
+		memcpy(&pd->paths[old_len + 1], *new_path, new_len);
+		*new_path = &pd->paths[old_len + 1];
+	} else if (*old_path)
+		*new_path = &pd->paths[0];
+
+	return 0;
+}
+
+static int diff_from_sources(
+	git_diff_file_content_src *oldsrc,
+	git_diff_file_content_src *newsrc,
+	const git_diff_options *opts,
+	git_diff_file_cb file_cb,
+	git_diff_binary_cb binary_cb,
+	git_diff_hunk_cb hunk_cb,
+	git_diff_line_cb data_cb,
+	void *payload)
+{
+	int error = 0;
+	diff_patch_with_delta pd;
+	git_xdiff_output xo;
+
+	memset(&xo, 0, sizeof(xo));
+	diff_output_init(
+		&xo.output, opts, file_cb, binary_cb, hunk_cb, data_cb, payload);
+	git_xdiff_init(&xo, opts);
+
+	memset(&pd, 0, sizeof(pd));
+
+	error = diff_patch_from_sources(&pd, &xo, oldsrc, newsrc, opts);
+
+	git_patch_free(&pd.patch);
+
+	return error;
+}
+
+static int patch_from_sources(
+	git_patch **out,
+	git_diff_file_content_src *oldsrc,
+	git_diff_file_content_src *newsrc,
+	const git_diff_options *opts)
+{
+	int error = 0;
+	diff_patch_with_delta *pd;
+	git_xdiff_output xo;
+
+	assert(out);
+	*out = NULL;
+
+	if ((error = diff_patch_with_delta_alloc(
+			&pd, &oldsrc->as_path, &newsrc->as_path)) < 0)
+		return error;
+
+	memset(&xo, 0, sizeof(xo));
+	diff_output_to_patch(&xo.output, &pd->patch);
+	git_xdiff_init(&xo, opts);
+
+	if (!(error = diff_patch_from_sources(pd, &xo, oldsrc, newsrc, opts)))
+		*out = (git_patch *)pd;
+	else
+		git_patch_free((git_patch *)pd);
+
+	return error;
+}
+
+int git_diff_blobs(
+	const git_blob *old_blob,
+	const char *old_path,
+	const git_blob *new_blob,
+	const char *new_path,
+	const git_diff_options *opts,
+	git_diff_file_cb file_cb,
+	git_diff_binary_cb binary_cb,
+	git_diff_hunk_cb hunk_cb,
+	git_diff_line_cb data_cb,
+	void *payload)
+{
+	git_diff_file_content_src osrc =
+		GIT_DIFF_FILE_CONTENT_SRC__BLOB(old_blob, old_path);
+	git_diff_file_content_src nsrc =
+		GIT_DIFF_FILE_CONTENT_SRC__BLOB(new_blob, new_path);
+	return diff_from_sources(
+		&osrc, &nsrc, opts, file_cb, binary_cb, hunk_cb, data_cb, payload);
+}
+
+int git_patch_from_blobs(
+	git_patch **out,
+	const git_blob *old_blob,
+	const char *old_path,
+	const git_blob *new_blob,
+	const char *new_path,
+	const git_diff_options *opts)
+{
+	git_diff_file_content_src osrc =
+		GIT_DIFF_FILE_CONTENT_SRC__BLOB(old_blob, old_path);
+	git_diff_file_content_src nsrc =
+		GIT_DIFF_FILE_CONTENT_SRC__BLOB(new_blob, new_path);
+	return patch_from_sources(out, &osrc, &nsrc, opts);
+}
+
+int git_diff_blob_to_buffer(
+	const git_blob *old_blob,
+	const char *old_path,
+	const char *buf,
+	size_t buflen,
+	const char *buf_path,
+	const git_diff_options *opts,
+	git_diff_file_cb file_cb,
+	git_diff_binary_cb binary_cb,
+	git_diff_hunk_cb hunk_cb,
+	git_diff_line_cb data_cb,
+	void *payload)
+{
+	git_diff_file_content_src osrc =
+		GIT_DIFF_FILE_CONTENT_SRC__BLOB(old_blob, old_path);
+	git_diff_file_content_src nsrc =
+		GIT_DIFF_FILE_CONTENT_SRC__BUF(buf, buflen, buf_path);
+	return diff_from_sources(
+		&osrc, &nsrc, opts, file_cb, binary_cb, hunk_cb, data_cb, payload);
+}
+
+int git_patch_from_blob_and_buffer(
+	git_patch **out,
+	const git_blob *old_blob,
+	const char *old_path,
+	const char *buf,
+	size_t buflen,
+	const char *buf_path,
+	const git_diff_options *opts)
+{
+	git_diff_file_content_src osrc =
+		GIT_DIFF_FILE_CONTENT_SRC__BLOB(old_blob, old_path);
+	git_diff_file_content_src nsrc =
+		GIT_DIFF_FILE_CONTENT_SRC__BUF(buf, buflen, buf_path);
+	return patch_from_sources(out, &osrc, &nsrc, opts);
+}
+
+int git_diff_buffers(
+	const void *old_buf,
+	size_t old_len,
+	const char *old_path,
+	const void *new_buf,
+	size_t new_len,
+	const char *new_path,
+	const git_diff_options *opts,
+	git_diff_file_cb file_cb,
+	git_diff_binary_cb binary_cb,
+	git_diff_hunk_cb hunk_cb,
+	git_diff_line_cb data_cb,
+	void *payload)
+{
+	git_diff_file_content_src osrc =
+		GIT_DIFF_FILE_CONTENT_SRC__BUF(old_buf, old_len, old_path);
+	git_diff_file_content_src nsrc =
+		GIT_DIFF_FILE_CONTENT_SRC__BUF(new_buf, new_len, new_path);
+	return diff_from_sources(
+		&osrc, &nsrc, opts, file_cb, binary_cb, hunk_cb, data_cb, payload);
+}
+
+int git_patch_from_buffers(
+	git_patch **out,
+	const void *old_buf,
+	size_t old_len,
+	const char *old_path,
+	const char *new_buf,
+	size_t new_len,
+	const char *new_path,
+	const git_diff_options *opts)
+{
+	git_diff_file_content_src osrc =
+		GIT_DIFF_FILE_CONTENT_SRC__BUF(old_buf, old_len, old_path);
+	git_diff_file_content_src nsrc =
+		GIT_DIFF_FILE_CONTENT_SRC__BUF(new_buf, new_len, new_path);
+	return patch_from_sources(out, &osrc, &nsrc, opts);
+}
+
+int git_patch_from_diff(
+	git_patch **patch_ptr, git_diff *diff, size_t idx)
+{
+	int error = 0;
+	git_xdiff_output xo;
+	git_diff_delta *delta = NULL;
+	git_patch *patch = NULL;
+
+	if (patch_ptr) *patch_ptr = NULL;
+
+	if (diff_required(diff, "git_patch_from_diff") < 0)
+		return -1;
+
+	delta = git_vector_get(&diff->deltas, idx);
+	if (!delta) {
+		giterr_set(GITERR_INVALID, "Index out of range for delta in diff");
+		return GIT_ENOTFOUND;
+	}
+
+	if (git_diff_delta__should_skip(&diff->opts, delta))
+		return 0;
+
+	/* don't load the patch data unless we need it for binary check */
+	if (!patch_ptr &&
+		((delta->flags & DIFF_FLAGS_KNOWN_BINARY) != 0 ||
+		 (diff->opts.flags & GIT_DIFF_SKIP_BINARY_CHECK) != 0))
+		return 0;
+
+	if ((error = diff_patch_alloc_from_diff(&patch, diff, idx)) < 0)
+		return error;
+
+	memset(&xo, 0, sizeof(xo));
+	diff_output_to_patch(&xo.output, patch);
+	git_xdiff_init(&xo, &diff->opts);
+
+	error = diff_patch_invoke_file_callback(patch, &xo.output);
+
+	if (!error)
+		error = diff_patch_generate(patch, &xo.output);
+
+	if (!error) {
+		/* TODO: if cumulative diff size is < 0.5 total size, flatten patch */
+		/* TODO: and unload the file content */
+	}
+
+	if (error || !patch_ptr)
+		git_patch_free(patch);
+	else
+		*patch_ptr = patch;
+
+	return error;
+}
+
+void git_patch_free(git_patch *patch)
+{
+	if (patch)
+		GIT_REFCOUNT_DEC(patch, diff_patch_free);
+}
+
+const git_diff_delta *git_patch_get_delta(const git_patch *patch)
+{
+	assert(patch);
+	return patch->delta;
+}
+
+size_t git_patch_num_hunks(const git_patch *patch)
+{
+	assert(patch);
+	return git_array_size(patch->hunks);
+}
+
+int git_patch_line_stats(
+	size_t *total_ctxt,
+	size_t *total_adds,
+	size_t *total_dels,
+	const git_patch *patch)
+{
+	size_t totals[3], idx;
+
+	memset(totals, 0, sizeof(totals));
+
+	for (idx = 0; idx < git_array_size(patch->lines); ++idx) {
+		git_diff_line *line = git_array_get(patch->lines, idx);
+		if (!line)
+			continue;
+
+		switch (line->origin) {
+		case GIT_DIFF_LINE_CONTEXT:  totals[0]++; break;
+		case GIT_DIFF_LINE_ADDITION: totals[1]++; break;
+		case GIT_DIFF_LINE_DELETION: totals[2]++; break;
+		default:
+			/* diff --stat and --numstat don't count EOFNL marks because
+			 * they will always be paired with a ADDITION or DELETION line.
+			 */
+			break;
+		}
+	}
+
+	if (total_ctxt)
+		*total_ctxt = totals[0];
+	if (total_adds)
+		*total_adds = totals[1];
+	if (total_dels)
+		*total_dels = totals[2];
+
+	return 0;
+}
+
+static int diff_error_outofrange(const char *thing)
+{
+	giterr_set(GITERR_INVALID, "Diff patch %s index out of range", thing);
+	return GIT_ENOTFOUND;
+}
+
+int git_patch_get_hunk(
+	const git_diff_hunk **out,
+	size_t *lines_in_hunk,
+	git_patch *patch,
+	size_t hunk_idx)
+{
+	diff_patch_hunk *hunk;
+	assert(patch);
+
+	hunk = git_array_get(patch->hunks, hunk_idx);
+
+	if (!hunk) {
+		if (out) *out = NULL;
+		if (lines_in_hunk) *lines_in_hunk = 0;
+		return diff_error_outofrange("hunk");
+	}
+
+	if (out) *out = &hunk->hunk;
+	if (lines_in_hunk) *lines_in_hunk = hunk->line_count;
+	return 0;
+}
+
+int git_patch_num_lines_in_hunk(const git_patch *patch, size_t hunk_idx)
+{
+	diff_patch_hunk *hunk;
+	assert(patch);
+
+	if (!(hunk = git_array_get(patch->hunks, hunk_idx)))
+		return diff_error_outofrange("hunk");
+	return (int)hunk->line_count;
+}
+
+int git_patch_get_line_in_hunk(
+	const git_diff_line **out,
+	git_patch *patch,
+	size_t hunk_idx,
+	size_t line_of_hunk)
+{
+	diff_patch_hunk *hunk;
+	git_diff_line *line;
+
+	assert(patch);
+
+	if (!(hunk = git_array_get(patch->hunks, hunk_idx))) {
+		if (out) *out = NULL;
+		return diff_error_outofrange("hunk");
+	}
+
+	if (line_of_hunk >= hunk->line_count ||
+		!(line = git_array_get(
+			patch->lines, hunk->line_start + line_of_hunk))) {
+		if (out) *out = NULL;
+		return diff_error_outofrange("line");
+	}
+
+	if (out) *out = line;
+	return 0;
+}
+
+size_t git_patch_size(
+	git_patch *patch,
+	int include_context,
+	int include_hunk_headers,
+	int include_file_headers)
+{
+	size_t out;
+
+	assert(patch);
+
+	out = patch->content_size;
+
+	if (!include_context)
+		out -= patch->context_size;
+
+	if (include_hunk_headers)
+		out += patch->header_size;
+
+	if (include_file_headers) {
+		git_buf file_header = GIT_BUF_INIT;
+
+		if (git_diff_delta__format_file_header(
+				&file_header, patch->delta, NULL, NULL, 0) < 0)
+			giterr_clear();
+		else
+			out += git_buf_len(&file_header);
+
+		git_buf_free(&file_header);
+	}
+
+	return out;
+}
+
+git_diff *git_patch__diff(git_patch *patch)
+{
+	return patch->diff;
+}
+
+git_diff_driver *git_patch__driver(git_patch *patch)
+{
+	/* ofile driver is representative for whole patch */
+	return patch->ofile.driver;
+}
+
+void git_patch__old_data(
+	char **ptr, size_t *len, git_patch *patch)
+{
+	*ptr = patch->ofile.map.data;
+	*len = patch->ofile.map.len;
+}
+
+void git_patch__new_data(
+	char **ptr, size_t *len, git_patch *patch)
+{
+	*ptr = patch->nfile.map.data;
+	*len = patch->nfile.map.len;
+}
+
+int git_patch__invoke_callbacks(
+	git_patch *patch,
+	git_diff_file_cb file_cb,
+	git_diff_binary_cb binary_cb,
+	git_diff_hunk_cb hunk_cb,
+	git_diff_line_cb line_cb,
+	void *payload)
+{
+	int error = 0;
+	uint32_t i, j;
+
+	if (file_cb)
+		error = file_cb(patch->delta, 0, payload);
+
+	if ((patch->delta->flags & GIT_DIFF_FLAG_BINARY) != 0) {
+		if (binary_cb)
+			error = binary_cb(patch->delta, &patch->binary, payload);
+
+		return error;
+	}
+
+	if (!hunk_cb && !line_cb)
+		return error;
+
+	for (i = 0; !error && i < git_array_size(patch->hunks); ++i) {
+		diff_patch_hunk *h = git_array_get(patch->hunks, i);
+
+		if (hunk_cb)
+			error = hunk_cb(patch->delta, &h->hunk, payload);
+
+		if (!line_cb)
+			continue;
+
+		for (j = 0; !error && j < h->line_count; ++j) {
+			git_diff_line *l =
+				git_array_get(patch->lines, h->line_start + j);
+
+			error = line_cb(patch->delta, &h->hunk, l, payload);
+		}
+	}
+
+	return error;
+}
+
+
+static int diff_patch_file_cb(
+	const git_diff_delta *delta,
+	float progress,
+	void *payload)
+{
+	GIT_UNUSED(delta); GIT_UNUSED(progress); GIT_UNUSED(payload);
+	return 0;
+}
+
+static int diff_patch_binary_cb(
+	const git_diff_delta *delta,
+	const git_diff_binary *binary,
+	void *payload)
+{
+	git_patch *patch = payload;
+
+	GIT_UNUSED(delta);
+
+	memcpy(&patch->binary, binary, sizeof(git_diff_binary));
+
+	if (binary->old_file.data) {
+		patch->binary.old_file.data = git__malloc(binary->old_file.datalen);
+		GITERR_CHECK_ALLOC(patch->binary.old_file.data);
+
+		memcpy((char *)patch->binary.old_file.data,
+			binary->old_file.data, binary->old_file.datalen);
+	}
+
+	if (binary->new_file.data) {
+		patch->binary.new_file.data = git__malloc(binary->new_file.datalen);
+		GITERR_CHECK_ALLOC(patch->binary.new_file.data);
+
+		memcpy((char *)patch->binary.new_file.data,
+			binary->new_file.data, binary->new_file.datalen);
+	}
+
+	return 0;
+}
+
+static int diff_patch_hunk_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk_,
+	void *payload)
+{
+	git_patch *patch = payload;
+	diff_patch_hunk *hunk;
+
+	GIT_UNUSED(delta);
+
+	hunk = git_array_alloc(patch->hunks);
+	GITERR_CHECK_ALLOC(hunk);
+
+	memcpy(&hunk->hunk, hunk_, sizeof(hunk->hunk));
+
+	patch->header_size += hunk_->header_len;
+
+	hunk->line_start = git_array_size(patch->lines);
+	hunk->line_count = 0;
+
+	return 0;
+}
+
+static int diff_patch_line_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk_,
+	const git_diff_line *line_,
+	void *payload)
+{
+	git_patch *patch = payload;
+	diff_patch_hunk *hunk;
+	git_diff_line   *line;
+
+	GIT_UNUSED(delta);
+	GIT_UNUSED(hunk_);
+
+	hunk = git_array_last(patch->hunks);
+	assert(hunk); /* programmer error if no hunk is available */
+
+	line = git_array_alloc(patch->lines);
+	GITERR_CHECK_ALLOC(line);
+
+	memcpy(line, line_, sizeof(*line));
+
+	/* do some bookkeeping so we can provide old/new line numbers */
+
+	patch->content_size += line->content_len;
+
+	if (line->origin == GIT_DIFF_LINE_ADDITION ||
+		line->origin == GIT_DIFF_LINE_DELETION)
+		patch->content_size += 1;
+	else if (line->origin == GIT_DIFF_LINE_CONTEXT) {
+		patch->content_size += 1;
+		patch->context_size += line->content_len + 1;
+	} else if (line->origin == GIT_DIFF_LINE_CONTEXT_EOFNL)
+		patch->context_size += line->content_len;
+
+	hunk->line_count++;
+
+	return 0;
+}
+
+static void diff_output_init(
+	git_diff_output *out,
+	const git_diff_options *opts,
+	git_diff_file_cb file_cb,
+	git_diff_binary_cb binary_cb,
+	git_diff_hunk_cb hunk_cb,
+	git_diff_line_cb data_cb,
+	void *payload)
+{
+	GIT_UNUSED(opts);
+
+	memset(out, 0, sizeof(*out));
+
+	out->file_cb = file_cb;
+	out->binary_cb = binary_cb;
+	out->hunk_cb = hunk_cb;
+	out->data_cb = data_cb;
+	out->payload = payload;
+}
+
+static void diff_output_to_patch(git_diff_output *out, git_patch *patch)
+{
+	diff_output_init(
+		out,
+		NULL,
+		diff_patch_file_cb,
+		diff_patch_binary_cb,
+		diff_patch_hunk_cb,
+		diff_patch_line_cb,
+		patch);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_patch.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_patch.h
new file mode 100755
index 0000000..7b4dacd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_patch.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_diff_patch_h__
+#define INCLUDE_diff_patch_h__
+
+#include "common.h"
+#include "diff.h"
+#include "diff_file.h"
+#include "array.h"
+#include "git2/patch.h"
+
+ /* cached information about a hunk in a diff */
+typedef struct diff_patch_hunk {
+	git_diff_hunk hunk;
+	size_t line_start;
+	size_t line_count;
+} diff_patch_hunk;
+
+enum {
+	GIT_DIFF_PATCH_ALLOCATED = (1 << 0),
+	GIT_DIFF_PATCH_INITIALIZED = (1 << 1),
+	GIT_DIFF_PATCH_LOADED = (1 << 2),
+	/* the two sides are different */
+	GIT_DIFF_PATCH_DIFFABLE = (1 << 3),
+	/* the difference between the two sides has been computed */
+	GIT_DIFF_PATCH_DIFFED = (1 << 4),
+	GIT_DIFF_PATCH_FLATTENED = (1 << 5),
+};
+
+struct git_patch {
+	git_refcount rc;
+	git_diff *diff; /* for refcount purposes, maybe NULL for blob diffs */
+	git_diff_options diff_opts;
+	git_diff_delta *delta;
+	size_t delta_index;
+	git_diff_file_content ofile;
+	git_diff_file_content nfile;
+	uint32_t flags;
+	git_diff_binary binary;
+	git_array_t(diff_patch_hunk) hunks;
+	git_array_t(git_diff_line)   lines;
+	size_t content_size, context_size, header_size;
+	git_pool flattened;
+};
+
+extern git_diff *git_patch__diff(git_patch *);
+
+extern git_diff_driver *git_patch__driver(git_patch *);
+
+extern void git_patch__old_data(char **, size_t *, git_patch *);
+extern void git_patch__new_data(char **, size_t *, git_patch *);
+
+extern int git_patch__invoke_callbacks(
+	git_patch *patch,
+	git_diff_file_cb file_cb,
+	git_diff_binary_cb binary_cb,
+	git_diff_hunk_cb hunk_cb,
+	git_diff_line_cb line_cb,
+	void *payload);
+
+typedef struct git_diff_output git_diff_output;
+struct git_diff_output {
+	/* these callbacks are issued with the diff data */
+	git_diff_file_cb file_cb;
+	git_diff_binary_cb binary_cb;
+	git_diff_hunk_cb hunk_cb;
+	git_diff_line_cb data_cb;
+	void *payload;
+
+	/* this records the actual error in cases where it may be obscured */
+	int error;
+
+	/* this callback is used to do the diff and drive the other callbacks.
+	 * see diff_xdiff.h for how to use this in practice for now.
+	 */
+	int (*diff_cb)(git_diff_output *output, git_patch *patch);
+};
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_print.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_print.c
new file mode 100755
index 0000000..d406a44
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_print.c
@@ -0,0 +1,664 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "diff.h"
+#include "diff_patch.h"
+#include "fileops.h"
+#include "zstream.h"
+#include "blob.h"
+#include "delta.h"
+#include "git2/sys/diff.h"
+
+typedef struct {
+	git_diff *diff;
+	git_diff_format_t format;
+	git_diff_line_cb print_cb;
+	void *payload;
+	git_buf *buf;
+	uint32_t flags;
+	int oid_strlen;
+	git_diff_line line;
+	unsigned int
+		content_loaded : 1,
+		content_allocated : 1;
+	git_diff_file_content *ofile;
+	git_diff_file_content *nfile;
+} diff_print_info;
+
+static int diff_print_info_init__common(
+	diff_print_info *pi,
+	git_buf *out,
+	git_repository *repo,
+	git_diff_format_t format,
+	git_diff_line_cb cb,
+	void *payload)
+{
+	pi->format = format;
+	pi->print_cb = cb;
+	pi->payload = payload;
+	pi->buf = out;
+
+	if (!pi->oid_strlen) {
+		if (!repo)
+			pi->oid_strlen = GIT_ABBREV_DEFAULT;
+		else if (git_repository__cvar(&pi->oid_strlen, repo, GIT_CVAR_ABBREV) < 0)
+			return -1;
+	}
+
+	pi->oid_strlen += 1; /* for NUL byte */
+
+	if (pi->oid_strlen > GIT_OID_HEXSZ + 1)
+		pi->oid_strlen = GIT_OID_HEXSZ + 1;
+
+	memset(&pi->line, 0, sizeof(pi->line));
+	pi->line.old_lineno = -1;
+	pi->line.new_lineno = -1;
+	pi->line.num_lines = 1;
+
+	return 0;
+}
+
+static int diff_print_info_init_fromdiff(
+	diff_print_info *pi,
+	git_buf *out,
+	git_diff *diff,
+	git_diff_format_t format,
+	git_diff_line_cb cb,
+	void *payload)
+{
+	git_repository *repo = diff ? diff->repo : NULL;
+
+	memset(pi, 0, sizeof(diff_print_info));
+
+	pi->diff = diff;
+
+	if (diff) {
+		pi->flags = diff->opts.flags;
+		pi->oid_strlen = diff->opts.id_abbrev;
+	}
+
+	return diff_print_info_init__common(pi, out, repo, format, cb, payload);
+}
+
+static int diff_print_info_init_frompatch(
+	diff_print_info *pi,
+	git_buf *out,
+	git_patch *patch,
+	git_diff_format_t format,
+	git_diff_line_cb cb,
+	void *payload)
+{
+	git_repository *repo = patch && patch->diff ? patch->diff->repo : NULL;
+
+	memset(pi, 0, sizeof(diff_print_info));
+
+	pi->diff = patch->diff;
+
+	pi->flags = patch->diff_opts.flags;
+	pi->oid_strlen = patch->diff_opts.id_abbrev;
+
+	pi->content_loaded = 1;
+	pi->ofile = &patch->ofile;
+	pi->nfile = &patch->nfile;
+
+	return diff_print_info_init__common(pi, out, repo, format, cb, payload);
+}
+
+static char diff_pick_suffix(int mode)
+{
+	if (S_ISDIR(mode))
+		return '/';
+	else if (GIT_PERMS_IS_EXEC(mode)) /* -V536 */
+		/* in git, modes are very regular, so we must have 0100755 mode */
+		return '*';
+	else
+		return ' ';
+}
+
+char git_diff_status_char(git_delta_t status)
+{
+	char code;
+
+	switch (status) {
+	case GIT_DELTA_ADDED:      code = 'A'; break;
+	case GIT_DELTA_DELETED:    code = 'D'; break;
+	case GIT_DELTA_MODIFIED:   code = 'M'; break;
+	case GIT_DELTA_RENAMED:    code = 'R'; break;
+	case GIT_DELTA_COPIED:     code = 'C'; break;
+	case GIT_DELTA_IGNORED:    code = 'I'; break;
+	case GIT_DELTA_UNTRACKED:  code = '?'; break;
+	case GIT_DELTA_UNREADABLE: code = 'X'; break;
+	default:                   code = ' '; break;
+	}
+
+	return code;
+}
+
+static int diff_print_one_name_only(
+	const git_diff_delta *delta, float progress, void *data)
+{
+	diff_print_info *pi = data;
+	git_buf *out = pi->buf;
+
+	GIT_UNUSED(progress);
+
+	if ((pi->flags & GIT_DIFF_SHOW_UNMODIFIED) == 0 &&
+		delta->status == GIT_DELTA_UNMODIFIED)
+		return 0;
+
+	git_buf_clear(out);
+	git_buf_puts(out, delta->new_file.path);
+	git_buf_putc(out, '\n');
+	if (git_buf_oom(out))
+		return -1;
+
+	pi->line.origin      = GIT_DIFF_LINE_FILE_HDR;
+	pi->line.content     = git_buf_cstr(out);
+	pi->line.content_len = git_buf_len(out);
+
+	return pi->print_cb(delta, NULL, &pi->line, pi->payload);
+}
+
+static int diff_print_one_name_status(
+	const git_diff_delta *delta, float progress, void *data)
+{
+	diff_print_info *pi = data;
+	git_buf *out = pi->buf;
+	char old_suffix, new_suffix, code = git_diff_status_char(delta->status);
+	int (*strcomp)(const char *, const char *) =
+		pi->diff ? pi->diff->strcomp : git__strcmp;
+
+	GIT_UNUSED(progress);
+
+	if ((pi->flags & GIT_DIFF_SHOW_UNMODIFIED) == 0 && code == ' ')
+		return 0;
+
+	old_suffix = diff_pick_suffix(delta->old_file.mode);
+	new_suffix = diff_pick_suffix(delta->new_file.mode);
+
+	git_buf_clear(out);
+
+	if (delta->old_file.path != delta->new_file.path &&
+		strcomp(delta->old_file.path,delta->new_file.path) != 0)
+		git_buf_printf(out, "%c\t%s%c %s%c\n", code,
+			delta->old_file.path, old_suffix, delta->new_file.path, new_suffix);
+	else if (delta->old_file.mode != delta->new_file.mode &&
+		delta->old_file.mode != 0 && delta->new_file.mode != 0)
+		git_buf_printf(out, "%c\t%s%c %s%c\n", code,
+			delta->old_file.path, old_suffix, delta->new_file.path, new_suffix);
+	else if (old_suffix != ' ')
+		git_buf_printf(out, "%c\t%s%c\n", code, delta->old_file.path, old_suffix);
+	else
+		git_buf_printf(out, "%c\t%s\n", code, delta->old_file.path);
+	if (git_buf_oom(out))
+		return -1;
+
+	pi->line.origin      = GIT_DIFF_LINE_FILE_HDR;
+	pi->line.content     = git_buf_cstr(out);
+	pi->line.content_len = git_buf_len(out);
+
+	return pi->print_cb(delta, NULL, &pi->line, pi->payload);
+}
+
+static int diff_print_one_raw(
+	const git_diff_delta *delta, float progress, void *data)
+{
+	diff_print_info *pi = data;
+	git_buf *out = pi->buf;
+	char code = git_diff_status_char(delta->status);
+	char start_oid[GIT_OID_HEXSZ+1], end_oid[GIT_OID_HEXSZ+1];
+
+	GIT_UNUSED(progress);
+
+	if ((pi->flags & GIT_DIFF_SHOW_UNMODIFIED) == 0 && code == ' ')
+		return 0;
+
+	git_buf_clear(out);
+
+	git_oid_tostr(start_oid, pi->oid_strlen, &delta->old_file.id);
+	git_oid_tostr(end_oid, pi->oid_strlen, &delta->new_file.id);
+
+	git_buf_printf(
+		out, (pi->oid_strlen <= GIT_OID_HEXSZ) ?
+			":%06o %06o %s... %s... %c" : ":%06o %06o %s %s %c",
+		delta->old_file.mode, delta->new_file.mode, start_oid, end_oid, code);
+
+	if (delta->similarity > 0)
+		git_buf_printf(out, "%03u", delta->similarity);
+
+	if (delta->old_file.path != delta->new_file.path)
+		git_buf_printf(
+			out, "\t%s %s\n", delta->old_file.path, delta->new_file.path);
+	else
+		git_buf_printf(
+			out, "\t%s\n", delta->old_file.path ?
+			delta->old_file.path : delta->new_file.path);
+
+	if (git_buf_oom(out))
+		return -1;
+
+	pi->line.origin      = GIT_DIFF_LINE_FILE_HDR;
+	pi->line.content     = git_buf_cstr(out);
+	pi->line.content_len = git_buf_len(out);
+
+	return pi->print_cb(delta, NULL, &pi->line, pi->payload);
+}
+
+static int diff_print_oid_range(
+	git_buf *out, const git_diff_delta *delta, int oid_strlen)
+{
+	char start_oid[GIT_OID_HEXSZ+1], end_oid[GIT_OID_HEXSZ+1];
+
+	git_oid_tostr(start_oid, oid_strlen, &delta->old_file.id);
+	git_oid_tostr(end_oid, oid_strlen, &delta->new_file.id);
+
+	/* TODO: Match git diff more closely */
+	if (delta->old_file.mode == delta->new_file.mode) {
+		git_buf_printf(out, "index %s..%s %o\n",
+			start_oid, end_oid, delta->old_file.mode);
+	} else {
+		if (delta->old_file.mode == 0) {
+			git_buf_printf(out, "new file mode %o\n", delta->new_file.mode);
+		} else if (delta->new_file.mode == 0) {
+			git_buf_printf(out, "deleted file mode %o\n", delta->old_file.mode);
+		} else {
+			git_buf_printf(out, "old mode %o\n", delta->old_file.mode);
+			git_buf_printf(out, "new mode %o\n", delta->new_file.mode);
+		}
+		git_buf_printf(out, "index %s..%s\n", start_oid, end_oid);
+	}
+
+	return git_buf_oom(out) ? -1 : 0;
+}
+
+static int diff_delta_format_with_paths(
+	git_buf *out,
+	const git_diff_delta *delta,
+	const char *oldpfx,
+	const char *newpfx,
+	const char *template)
+{
+	const char *oldpath = delta->old_file.path;
+	const char *newpath = delta->new_file.path;
+
+	if (git_oid_iszero(&delta->old_file.id)) {
+		oldpfx = "";
+		oldpath = "/dev/null";
+	}
+	if (git_oid_iszero(&delta->new_file.id)) {
+		newpfx = "";
+		newpath = "/dev/null";
+	}
+
+	return git_buf_printf(out, template, oldpfx, oldpath, newpfx, newpath);
+}
+
+int git_diff_delta__format_file_header(
+	git_buf *out,
+	const git_diff_delta *delta,
+	const char *oldpfx,
+	const char *newpfx,
+	int oid_strlen)
+{
+	if (!oldpfx)
+		oldpfx = DIFF_OLD_PREFIX_DEFAULT;
+	if (!newpfx)
+		newpfx = DIFF_NEW_PREFIX_DEFAULT;
+	if (!oid_strlen)
+		oid_strlen = GIT_ABBREV_DEFAULT + 1;
+
+	git_buf_clear(out);
+
+	git_buf_printf(out, "diff --git %s%s %s%s\n",
+		oldpfx, delta->old_file.path, newpfx, delta->new_file.path);
+
+	GITERR_CHECK_ERROR(diff_print_oid_range(out, delta, oid_strlen));
+
+	if ((delta->flags & GIT_DIFF_FLAG_BINARY) == 0)
+		diff_delta_format_with_paths(
+			out, delta, oldpfx, newpfx, "--- %s%s\n+++ %s%s\n");
+
+	return git_buf_oom(out) ? -1 : 0;
+}
+
+static int format_binary(
+	diff_print_info *pi,
+	git_diff_binary_t type,
+	const char *data,
+	size_t datalen,
+	size_t inflatedlen)
+{
+	const char *typename = type == GIT_DIFF_BINARY_DELTA ?
+		"delta" : "literal";
+	const char *scan, *end;
+
+	git_buf_printf(pi->buf, "%s %" PRIuZ "\n", typename, inflatedlen);
+	pi->line.num_lines++;
+
+	for (scan = data, end = data + datalen; scan < end; ) {
+		size_t chunk_len = end - scan;
+		if (chunk_len > 52)
+			chunk_len = 52;
+
+		if (chunk_len <= 26)
+			git_buf_putc(pi->buf, (char)chunk_len + 'A' - 1);
+		else
+			git_buf_putc(pi->buf, (char)chunk_len - 26 + 'a' - 1);
+
+		git_buf_encode_base85(pi->buf, scan, chunk_len);
+		git_buf_putc(pi->buf, '\n');
+
+		if (git_buf_oom(pi->buf))
+			return -1;
+
+		scan += chunk_len;
+		pi->line.num_lines++;
+	}
+
+	return 0;
+}
+
+static int diff_print_load_content(
+	diff_print_info *pi,
+	git_diff_delta *delta)
+{
+	git_diff_file_content *ofile, *nfile;
+	int error;
+
+	assert(pi->diff);
+
+	ofile = git__calloc(1, sizeof(git_diff_file_content));
+	nfile = git__calloc(1, sizeof(git_diff_file_content));
+
+	GITERR_CHECK_ALLOC(ofile);
+	GITERR_CHECK_ALLOC(nfile);
+
+	if ((error = git_diff_file_content__init_from_diff(
+			ofile, pi->diff, delta, true)) < 0 ||
+		(error = git_diff_file_content__init_from_diff(
+			nfile, pi->diff, delta, true)) < 0) {
+
+		git__free(ofile);
+		git__free(nfile);
+		return error;
+	}
+
+	pi->content_loaded = 1;
+	pi->content_allocated = 1;
+	pi->ofile = ofile;
+	pi->nfile = nfile;
+
+	return 0;
+}
+
+static int diff_print_patch_file_binary(
+	diff_print_info *pi, git_diff_delta *delta,
+	const char *old_pfx, const char *new_pfx,
+	const git_diff_binary *binary)
+{
+	size_t pre_binary_size;
+	int error;
+
+	if ((pi->flags & GIT_DIFF_SHOW_BINARY) == 0)
+		goto noshow;
+
+	if (!pi->content_loaded &&
+		(error = diff_print_load_content(pi, delta)) < 0)
+		return error;
+
+	pre_binary_size = pi->buf->size;
+	git_buf_printf(pi->buf, "GIT binary patch\n");
+	pi->line.num_lines++;
+
+	if ((error = format_binary(pi, binary->new_file.type, binary->new_file.data,
+		binary->new_file.datalen, binary->new_file.inflatedlen)) < 0 ||
+		(error = git_buf_putc(pi->buf, '\n')) < 0 ||
+		(error = format_binary(pi, binary->old_file.type, binary->old_file.data,
+			binary->old_file.datalen, binary->old_file.inflatedlen)) < 0) {
+
+		if (error == GIT_EBUFS) {
+			giterr_clear();
+			git_buf_truncate(pi->buf, pre_binary_size);
+			goto noshow;
+		}
+	}
+
+	pi->line.num_lines++;
+	return error;
+
+noshow:
+	pi->line.num_lines = 1;
+	return diff_delta_format_with_paths(
+		pi->buf, delta, old_pfx, new_pfx,
+		"Binary files %s%s and %s%s differ\n");
+}
+
+static int diff_print_patch_file(
+	const git_diff_delta *delta, float progress, void *data)
+{
+	int error;
+	diff_print_info *pi = data;
+	const char *oldpfx =
+		pi->diff ? pi->diff->opts.old_prefix : DIFF_OLD_PREFIX_DEFAULT;
+	const char *newpfx =
+		pi->diff ? pi->diff->opts.new_prefix : DIFF_NEW_PREFIX_DEFAULT;
+
+	bool binary = (delta->flags & GIT_DIFF_FLAG_BINARY) ||
+		(pi->flags & GIT_DIFF_FORCE_BINARY);
+	bool show_binary = !!(pi->flags & GIT_DIFF_SHOW_BINARY);
+	int oid_strlen = binary && show_binary ?
+		GIT_OID_HEXSZ + 1 : pi->oid_strlen;
+
+	GIT_UNUSED(progress);
+
+	if (S_ISDIR(delta->new_file.mode) ||
+		delta->status == GIT_DELTA_UNMODIFIED ||
+		delta->status == GIT_DELTA_IGNORED ||
+		delta->status == GIT_DELTA_UNREADABLE ||
+		(delta->status == GIT_DELTA_UNTRACKED &&
+		 (pi->flags & GIT_DIFF_SHOW_UNTRACKED_CONTENT) == 0))
+		return 0;
+
+	if ((error = git_diff_delta__format_file_header(
+			pi->buf, delta, oldpfx, newpfx, oid_strlen)) < 0)
+		return error;
+
+	pi->line.origin      = GIT_DIFF_LINE_FILE_HDR;
+	pi->line.content     = git_buf_cstr(pi->buf);
+	pi->line.content_len = git_buf_len(pi->buf);
+
+	return pi->print_cb(delta, NULL, &pi->line, pi->payload);
+}
+
+static int diff_print_patch_binary(
+	const git_diff_delta *delta,
+	const git_diff_binary *binary,
+	void *data)
+{
+	diff_print_info *pi = data;
+	const char *old_pfx =
+		pi->diff ? pi->diff->opts.old_prefix : DIFF_OLD_PREFIX_DEFAULT;
+	const char *new_pfx =
+		pi->diff ? pi->diff->opts.new_prefix : DIFF_NEW_PREFIX_DEFAULT;
+	int error;
+
+	git_buf_clear(pi->buf);
+
+	if ((error = diff_print_patch_file_binary(
+		pi, (git_diff_delta *)delta, old_pfx, new_pfx, binary)) < 0)
+		return error;
+
+	pi->line.origin = GIT_DIFF_LINE_BINARY;
+	pi->line.content = git_buf_cstr(pi->buf);
+	pi->line.content_len = git_buf_len(pi->buf);
+
+	return pi->print_cb(delta, NULL, &pi->line, pi->payload);
+}
+
+static int diff_print_patch_hunk(
+	const git_diff_delta *d,
+	const git_diff_hunk *h,
+	void *data)
+{
+	diff_print_info *pi = data;
+
+	if (S_ISDIR(d->new_file.mode))
+		return 0;
+
+	pi->line.origin      = GIT_DIFF_LINE_HUNK_HDR;
+	pi->line.content     = h->header;
+	pi->line.content_len = h->header_len;
+
+	return pi->print_cb(d, h, &pi->line, pi->payload);
+}
+
+static int diff_print_patch_line(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *data)
+{
+	diff_print_info *pi = data;
+
+	if (S_ISDIR(delta->new_file.mode))
+		return 0;
+
+	return pi->print_cb(delta, hunk, line, pi->payload);
+}
+
+/* print a git_diff to an output callback */
+int git_diff_print(
+	git_diff *diff,
+	git_diff_format_t format,
+	git_diff_line_cb print_cb,
+	void *payload)
+{
+	int error;
+	git_buf buf = GIT_BUF_INIT;
+	diff_print_info pi;
+	git_diff_file_cb print_file = NULL;
+	git_diff_binary_cb print_binary = NULL;
+	git_diff_hunk_cb print_hunk = NULL;
+	git_diff_line_cb print_line = NULL;
+
+	switch (format) {
+	case GIT_DIFF_FORMAT_PATCH:
+		print_file = diff_print_patch_file;
+		print_binary = diff_print_patch_binary;
+		print_hunk = diff_print_patch_hunk;
+		print_line = diff_print_patch_line;
+		break;
+	case GIT_DIFF_FORMAT_PATCH_HEADER:
+		print_file = diff_print_patch_file;
+		break;
+	case GIT_DIFF_FORMAT_RAW:
+		print_file = diff_print_one_raw;
+		break;
+	case GIT_DIFF_FORMAT_NAME_ONLY:
+		print_file = diff_print_one_name_only;
+		break;
+	case GIT_DIFF_FORMAT_NAME_STATUS:
+		print_file = diff_print_one_name_status;
+		break;
+	default:
+		giterr_set(GITERR_INVALID, "Unknown diff output format (%d)", format);
+		return -1;
+	}
+
+	if (!(error = diff_print_info_init_fromdiff(
+			&pi, &buf, diff, format, print_cb, payload))) {
+		error = git_diff_foreach(
+			diff, print_file, print_binary, print_hunk, print_line, &pi);
+
+		if (error) /* make sure error message is set */
+			giterr_set_after_callback_function(error, "git_diff_print");
+	}
+
+	git__free(pi.nfile);
+	git__free(pi.ofile);
+
+	git_buf_free(&buf);
+
+	return error;
+}
+
+/* print a git_patch to an output callback */
+int git_patch_print(
+	git_patch *patch,
+	git_diff_line_cb print_cb,
+	void *payload)
+{
+	int error;
+	git_buf temp = GIT_BUF_INIT;
+	diff_print_info pi;
+
+	assert(patch && print_cb);
+
+	if (!(error = diff_print_info_init_frompatch(
+			&pi, &temp, patch,
+			GIT_DIFF_FORMAT_PATCH, print_cb, payload)))
+	{
+		error = git_patch__invoke_callbacks(
+			patch, diff_print_patch_file, diff_print_patch_binary,
+			diff_print_patch_hunk, diff_print_patch_line, &pi);
+
+		if (error) /* make sure error message is set */
+			giterr_set_after_callback_function(error, "git_patch_print");
+	}
+
+	git_buf_free(&temp);
+
+	return error;
+}
+
+int git_diff_print_callback__to_buf(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *payload)
+{
+	git_buf *output = payload;
+	GIT_UNUSED(delta); GIT_UNUSED(hunk);
+
+	if (!output) {
+		giterr_set(GITERR_INVALID, "Buffer pointer must be provided");
+		return -1;
+	}
+
+	if (line->origin == GIT_DIFF_LINE_ADDITION ||
+		line->origin == GIT_DIFF_LINE_DELETION ||
+		line->origin == GIT_DIFF_LINE_CONTEXT)
+		git_buf_putc(output, line->origin);
+
+	return git_buf_put(output, line->content, line->content_len);
+}
+
+int git_diff_print_callback__to_file_handle(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *payload)
+{
+	FILE *fp = payload ? payload : stdout;
+
+	GIT_UNUSED(delta); GIT_UNUSED(hunk);
+
+	if (line->origin == GIT_DIFF_LINE_CONTEXT ||
+		line->origin == GIT_DIFF_LINE_ADDITION ||
+		line->origin == GIT_DIFF_LINE_DELETION)
+		fputc(line->origin, fp);
+	fwrite(line->content, 1, line->content_len, fp);
+	return 0;
+}
+
+/* print a git_patch to a git_buf */
+int git_patch_to_buf(git_buf *out, git_patch *patch)
+{
+	assert(out && patch);
+	git_buf_sanitize(out);
+	return git_patch_print(patch, git_diff_print_callback__to_buf, out);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_stats.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_stats.c
new file mode 100755
index 0000000..42ccbfb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_stats.c
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "vector.h"
+#include "diff.h"
+#include "diff_patch.h"
+
+#define DIFF_RENAME_FILE_SEPARATOR " => "
+#define STATS_FULL_MIN_SCALE 7
+
+typedef struct {
+	size_t insertions;
+	size_t deletions;
+} diff_file_stats;
+
+struct git_diff_stats {
+	git_diff *diff;
+	diff_file_stats *filestats;
+
+	size_t files_changed;
+	size_t insertions;
+	size_t deletions;
+	size_t renames;
+
+	size_t max_name;
+	size_t max_filestat;
+	int max_digits;
+};
+
+static int digits_for_value(size_t val)
+{
+	int count = 1;
+	size_t placevalue = 10;
+
+	while (val >= placevalue) {
+		++count;
+		placevalue *= 10;
+	}
+
+	return count;
+}
+
+int git_diff_file_stats__full_to_buf(
+	git_buf *out,
+	const git_diff_delta *delta,
+	const diff_file_stats *filestat,
+	const git_diff_stats *stats,
+	size_t width)
+{
+	const char *old_path = NULL, *new_path = NULL;
+	size_t padding, old_size, new_size;
+
+	old_path = delta->old_file.path;
+	new_path = delta->new_file.path;
+	old_size = delta->old_file.size;
+	new_size = delta->new_file.size;
+
+	if (git_buf_printf(out, " %s", old_path) < 0)
+		goto on_error;
+
+	if (strcmp(old_path, new_path) != 0) {
+		padding = stats->max_name - strlen(old_path) - strlen(new_path);
+
+		if (git_buf_printf(out, DIFF_RENAME_FILE_SEPARATOR "%s", new_path) < 0)
+			goto on_error;
+	} else {
+		padding = stats->max_name - strlen(old_path);
+
+		if (stats->renames > 0)
+			padding += strlen(DIFF_RENAME_FILE_SEPARATOR);
+	}
+
+	if (git_buf_putcn(out, ' ', padding) < 0 ||
+		git_buf_puts(out, " | ") < 0)
+		goto on_error;
+
+	if (delta->flags & GIT_DIFF_FLAG_BINARY) {
+		if (git_buf_printf(out,
+				"Bin %" PRIuZ " -> %" PRIuZ " bytes", old_size, new_size) < 0)
+			goto on_error;
+	}
+	else {
+		if (git_buf_printf(out,
+				"%*" PRIuZ, stats->max_digits,
+				filestat->insertions + filestat->deletions) < 0)
+			goto on_error;
+
+		if (filestat->insertions || filestat->deletions) {
+			if (git_buf_putc(out, ' ') < 0)
+				goto on_error;
+
+			if (!width) {
+				if (git_buf_putcn(out, '+', filestat->insertions) < 0 ||
+					git_buf_putcn(out, '-', filestat->deletions) < 0)
+					goto on_error;
+			} else {
+				size_t total = filestat->insertions + filestat->deletions;
+				size_t full = (total * width + stats->max_filestat / 2) /
+					stats->max_filestat;
+				size_t plus = full * filestat->insertions / total;
+				size_t minus = full - plus;
+
+				if (git_buf_putcn(out, '+', max(plus,  1)) < 0 ||
+					git_buf_putcn(out, '-', max(minus, 1)) < 0)
+					goto on_error;
+			}
+		}
+	}
+
+	git_buf_putc(out, '\n');
+
+on_error:
+	return (git_buf_oom(out) ? -1 : 0);
+}
+
+int git_diff_file_stats__number_to_buf(
+	git_buf *out,
+	const git_diff_delta *delta,
+	const diff_file_stats *filestats)
+{
+	int error;
+	const char *path = delta->new_file.path;
+
+	if (delta->flags & GIT_DIFF_FLAG_BINARY)
+		error = git_buf_printf(out, "%-8c" "%-8c" "%s\n", '-', '-', path);
+	else
+		error = git_buf_printf(out, "%-8" PRIuZ "%-8" PRIuZ "%s\n",
+			filestats->insertions, filestats->deletions, path);
+
+	return error;
+}
+
+int git_diff_file_stats__summary_to_buf(
+	git_buf *out,
+	const git_diff_delta *delta)
+{
+	if (delta->old_file.mode != delta->new_file.mode) {
+		if (delta->old_file.mode == 0) {
+			git_buf_printf(out, " create mode %06o %s\n",
+				delta->new_file.mode, delta->new_file.path);
+		}
+		else if (delta->new_file.mode == 0) {
+			git_buf_printf(out, " delete mode %06o %s\n",
+				delta->old_file.mode, delta->old_file.path);
+		}
+		else {
+			git_buf_printf(out, " mode change %06o => %06o %s\n",
+				delta->old_file.mode, delta->new_file.mode, delta->new_file.path);
+		}
+	}
+
+	return 0;
+}
+
+int git_diff_get_stats(
+	git_diff_stats **out,
+	git_diff *diff)
+{
+	size_t i, deltas;
+	size_t total_insertions = 0, total_deletions = 0;
+	git_diff_stats *stats = NULL;
+	int error = 0;
+
+	assert(out && diff);
+
+	stats = git__calloc(1, sizeof(git_diff_stats));
+	GITERR_CHECK_ALLOC(stats);
+
+	deltas = git_diff_num_deltas(diff);
+
+	stats->filestats = git__calloc(deltas, sizeof(diff_file_stats));
+	if (!stats->filestats) {
+		git__free(stats);
+		return -1;
+	}
+
+	stats->diff = diff;
+	GIT_REFCOUNT_INC(diff);
+
+	for (i = 0; i < deltas && !error; ++i) {
+		git_patch *patch = NULL;
+		size_t add = 0, remove = 0, namelen;
+		const git_diff_delta *delta;
+
+		if ((error = git_patch_from_diff(&patch, diff, i)) < 0)
+			break;
+
+		/* keep a count of renames because it will affect formatting */
+		delta = git_patch_get_delta(patch);
+
+		namelen = strlen(delta->new_file.path);
+		if (strcmp(delta->old_file.path, delta->new_file.path) != 0) {
+			namelen += strlen(delta->old_file.path);
+			stats->renames++;
+		}
+
+		/* and, of course, count the line stats */
+		error = git_patch_line_stats(NULL, &add, &remove, patch);
+
+		git_patch_free(patch);
+
+		stats->filestats[i].insertions = add;
+		stats->filestats[i].deletions = remove;
+
+		total_insertions += add;
+		total_deletions += remove;
+
+		if (stats->max_name < namelen)
+			stats->max_name = namelen;
+		if (stats->max_filestat < add + remove)
+			stats->max_filestat = add + remove;
+	}
+
+	stats->files_changed = deltas;
+	stats->insertions = total_insertions;
+	stats->deletions = total_deletions;
+	stats->max_digits = digits_for_value(stats->max_filestat + 1);
+
+	if (error < 0) {
+		git_diff_stats_free(stats);
+		stats = NULL;
+	}
+
+	*out = stats;
+	return error;
+}
+
+size_t git_diff_stats_files_changed(
+	const git_diff_stats *stats)
+{
+	assert(stats);
+
+	return stats->files_changed;
+}
+
+size_t git_diff_stats_insertions(
+	const git_diff_stats *stats)
+{
+	assert(stats);
+
+	return stats->insertions;
+}
+
+size_t git_diff_stats_deletions(
+	const git_diff_stats *stats)
+{
+	assert(stats);
+
+	return stats->deletions;
+}
+
+int git_diff_stats_to_buf(
+	git_buf *out,
+	const git_diff_stats *stats,
+	git_diff_stats_format_t format,
+	size_t width)
+{
+	int error = 0;
+	size_t i;
+	const git_diff_delta *delta;
+
+	assert(out && stats);
+
+	if (format & GIT_DIFF_STATS_NUMBER) {
+		for (i = 0; i < stats->files_changed; ++i) {
+			if ((delta = git_diff_get_delta(stats->diff, i)) == NULL)
+				continue;
+
+			error = git_diff_file_stats__number_to_buf(
+				out, delta, &stats->filestats[i]);
+			if (error < 0)
+				return error;
+		}
+	}
+
+	if (format & GIT_DIFF_STATS_FULL) {
+		if (width > 0) {
+			if (width > stats->max_name + stats->max_digits + 5)
+				width -= (stats->max_name + stats->max_digits + 5);
+			if (width < STATS_FULL_MIN_SCALE)
+				width = STATS_FULL_MIN_SCALE;
+		}
+		if (width > stats->max_filestat)
+			width = 0;
+
+		for (i = 0; i < stats->files_changed; ++i) {
+			if ((delta = git_diff_get_delta(stats->diff, i)) == NULL)
+				continue;
+
+			error = git_diff_file_stats__full_to_buf(
+				out, delta, &stats->filestats[i], stats, width);
+			if (error < 0)
+				return error;
+		}
+	}
+
+	if (format & GIT_DIFF_STATS_FULL || format & GIT_DIFF_STATS_SHORT) {
+		error = git_buf_printf(
+			out, " %" PRIuZ " file%s changed, %" PRIuZ
+			" insertion%s(+), %" PRIuZ " deletion%s(-)\n",
+			stats->files_changed, stats->files_changed != 1 ? "s" : "",
+			stats->insertions, stats->insertions != 1 ? "s" : "",
+			stats->deletions, stats->deletions != 1 ? "s" : "");
+
+		if (error < 0)
+			return error;
+	}
+
+	if (format & GIT_DIFF_STATS_INCLUDE_SUMMARY) {
+		for (i = 0; i < stats->files_changed; ++i) {
+			if ((delta = git_diff_get_delta(stats->diff, i)) == NULL)
+				continue;
+
+			error = git_diff_file_stats__summary_to_buf(out, delta);
+			if (error < 0)
+				return error;
+		}
+	}
+
+	return error;
+}
+
+void git_diff_stats_free(git_diff_stats *stats)
+{
+	if (stats == NULL)
+		return;
+
+	git_diff_free(stats->diff); /* bumped refcount in constructor */
+	git__free(stats->filestats);
+	git__free(stats);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_tform.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_tform.c
new file mode 100755
index 0000000..92647e3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_tform.c
@@ -0,0 +1,1107 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+
+#include "git2/config.h"
+#include "git2/blob.h"
+#include "git2/sys/hashsig.h"
+
+#include "diff.h"
+#include "path.h"
+#include "fileops.h"
+#include "config.h"
+
+git_diff_delta *git_diff__delta_dup(
+	const git_diff_delta *d, git_pool *pool)
+{
+	git_diff_delta *delta = git__malloc(sizeof(git_diff_delta));
+	if (!delta)
+		return NULL;
+
+	memcpy(delta, d, sizeof(git_diff_delta));
+	GIT_DIFF_FLAG__CLEAR_INTERNAL(delta->flags);
+
+	if (d->old_file.path != NULL) {
+		delta->old_file.path = git_pool_strdup(pool, d->old_file.path);
+		if (delta->old_file.path == NULL)
+			goto fail;
+	}
+
+	if (d->new_file.path != d->old_file.path && d->new_file.path != NULL) {
+		delta->new_file.path = git_pool_strdup(pool, d->new_file.path);
+		if (delta->new_file.path == NULL)
+			goto fail;
+	} else {
+		delta->new_file.path = delta->old_file.path;
+	}
+
+	return delta;
+
+fail:
+	git__free(delta);
+	return NULL;
+}
+
+git_diff_delta *git_diff__merge_like_cgit(
+	const git_diff_delta *a,
+	const git_diff_delta *b,
+	git_pool *pool)
+{
+	git_diff_delta *dup;
+
+	/* Emulate C git for merging two diffs (a la 'git diff <sha>').
+	 *
+	 * When C git does a diff between the work dir and a tree, it actually
+	 * diffs with the index but uses the workdir contents.  This emulates
+	 * those choices so we can emulate the type of diff.
+	 *
+	 * We have three file descriptions here, let's call them:
+	 *  f1 = a->old_file
+	 *  f2 = a->new_file AND b->old_file
+	 *  f3 = b->new_file
+	 */
+
+	/* If one of the diffs is a conflict, just dup it */
+	if (b->status == GIT_DELTA_CONFLICTED)
+		return git_diff__delta_dup(b, pool);
+	if (a->status == GIT_DELTA_CONFLICTED)
+		return git_diff__delta_dup(a, pool);
+
+	/* if f2 == f3 or f2 is deleted, then just dup the 'a' diff */
+	if (b->status == GIT_DELTA_UNMODIFIED || a->status == GIT_DELTA_DELETED)
+		return git_diff__delta_dup(a, pool);
+
+	/* otherwise, base this diff on the 'b' diff */
+	if ((dup = git_diff__delta_dup(b, pool)) == NULL)
+		return NULL;
+
+	/* If 'a' status is uninteresting, then we're done */
+	if (a->status == GIT_DELTA_UNMODIFIED ||
+		a->status == GIT_DELTA_UNTRACKED ||
+		a->status == GIT_DELTA_UNREADABLE)
+		return dup;
+
+	assert(b->status != GIT_DELTA_UNMODIFIED);
+
+	/* A cgit exception is that the diff of a file that is only in the
+	 * index (i.e. not in HEAD nor workdir) is given as empty.
+	 */
+	if (dup->status == GIT_DELTA_DELETED) {
+		if (a->status == GIT_DELTA_ADDED) {
+			dup->status = GIT_DELTA_UNMODIFIED;
+			dup->nfiles = 2;
+		}
+		/* else don't overwrite DELETE status */
+	} else {
+		dup->status = a->status;
+		dup->nfiles = a->nfiles;
+	}
+
+	git_oid_cpy(&dup->old_file.id, &a->old_file.id);
+	dup->old_file.mode  = a->old_file.mode;
+	dup->old_file.size  = a->old_file.size;
+	dup->old_file.flags = a->old_file.flags;
+
+	return dup;
+}
+
+int git_diff__merge(
+	git_diff *onto, const git_diff *from, git_diff__merge_cb cb)
+{
+	int error = 0;
+	git_pool onto_pool;
+	git_vector onto_new;
+	git_diff_delta *delta;
+	bool ignore_case, reversed;
+	unsigned int i, j;
+
+	assert(onto && from);
+
+	if (!from->deltas.length)
+		return 0;
+
+	ignore_case = ((onto->opts.flags & GIT_DIFF_IGNORE_CASE) != 0);
+	reversed    = ((onto->opts.flags & GIT_DIFF_REVERSE) != 0);
+
+	if (ignore_case != ((from->opts.flags & GIT_DIFF_IGNORE_CASE) != 0) ||
+		reversed    != ((from->opts.flags & GIT_DIFF_REVERSE) != 0)) {
+		giterr_set(GITERR_INVALID,
+			"Attempt to merge diffs created with conflicting options");
+		return -1;
+	}
+
+	if (git_vector_init(
+			&onto_new, onto->deltas.length, git_diff_delta__cmp) < 0 ||
+		git_pool_init(&onto_pool, 1, 0) < 0)
+		return -1;
+
+	for (i = 0, j = 0; i < onto->deltas.length || j < from->deltas.length; ) {
+		git_diff_delta *o = GIT_VECTOR_GET(&onto->deltas, i);
+		const git_diff_delta *f = GIT_VECTOR_GET(&from->deltas, j);
+		int cmp = !f ? -1 : !o ? 1 :
+			STRCMP_CASESELECT(ignore_case, o->old_file.path, f->old_file.path);
+
+		if (cmp < 0) {
+			delta = git_diff__delta_dup(o, &onto_pool);
+			i++;
+		} else if (cmp > 0) {
+			delta = git_diff__delta_dup(f, &onto_pool);
+			j++;
+		} else {
+			const git_diff_delta *left = reversed ? f : o;
+			const git_diff_delta *right = reversed ? o : f;
+
+			delta = cb(left, right, &onto_pool);
+			i++;
+			j++;
+		}
+
+		/* the ignore rules for the target may not match the source
+		 * or the result of a merged delta could be skippable...
+		 */
+		if (delta && git_diff_delta__should_skip(&onto->opts, delta)) {
+			git__free(delta);
+			continue;
+		}
+
+		if ((error = !delta ? -1 : git_vector_insert(&onto_new, delta)) < 0)
+			break;
+	}
+
+	if (!error) {
+		git_vector_swap(&onto->deltas, &onto_new);
+		git_pool_swap(&onto->pool, &onto_pool);
+
+		if ((onto->opts.flags & GIT_DIFF_REVERSE) != 0)
+			onto->old_src = from->old_src;
+		else
+			onto->new_src = from->new_src;
+
+		/* prefix strings also come from old pool, so recreate those.*/
+		onto->opts.old_prefix =
+			git_pool_strdup_safe(&onto->pool, onto->opts.old_prefix);
+		onto->opts.new_prefix =
+			git_pool_strdup_safe(&onto->pool, onto->opts.new_prefix);
+	}
+
+	git_vector_free_deep(&onto_new);
+	git_pool_clear(&onto_pool);
+
+	return error;
+}
+
+int git_diff_merge(git_diff *onto, const git_diff *from)
+{
+	return git_diff__merge(onto, from, git_diff__merge_like_cgit);
+}
+
+int git_diff_find_similar__hashsig_for_file(
+	void **out, const git_diff_file *f, const char *path, void *p)
+{
+	git_hashsig_option_t opt = (git_hashsig_option_t)(intptr_t)p;
+
+	GIT_UNUSED(f);
+	return git_hashsig_create_fromfile((git_hashsig **)out, path, opt);
+}
+
+int git_diff_find_similar__hashsig_for_buf(
+	void **out, const git_diff_file *f, const char *buf, size_t len, void *p)
+{
+	git_hashsig_option_t opt = (git_hashsig_option_t)(intptr_t)p;
+
+	GIT_UNUSED(f);
+	return git_hashsig_create((git_hashsig **)out, buf, len, opt);
+}
+
+void git_diff_find_similar__hashsig_free(void *sig, void *payload)
+{
+	GIT_UNUSED(payload);
+	git_hashsig_free(sig);
+}
+
+int git_diff_find_similar__calc_similarity(
+	int *score, void *siga, void *sigb, void *payload)
+{
+	int error;
+
+	GIT_UNUSED(payload);
+	error = git_hashsig_compare(siga, sigb);
+	if (error < 0)
+		return error;
+
+	*score = error;
+	return 0;
+}
+
+#define DEFAULT_THRESHOLD 50
+#define DEFAULT_BREAK_REWRITE_THRESHOLD 60
+#define DEFAULT_RENAME_LIMIT 200
+
+static int normalize_find_opts(
+	git_diff *diff,
+	git_diff_find_options *opts,
+	const git_diff_find_options *given)
+{
+	git_config *cfg = NULL;
+	git_hashsig_option_t hashsig_opts;
+
+	GITERR_CHECK_VERSION(given, GIT_DIFF_FIND_OPTIONS_VERSION, "git_diff_find_options");
+
+	if (diff->repo != NULL &&
+		git_repository_config__weakptr(&cfg, diff->repo) < 0)
+		return -1;
+
+	if (given)
+		memcpy(opts, given, sizeof(*opts));
+
+	if (!given ||
+		 (given->flags & GIT_DIFF_FIND_ALL) == GIT_DIFF_FIND_BY_CONFIG)
+	{
+		char *rule =
+			git_config__get_string_force(cfg, "diff.renames", "true");
+		int boolval;
+
+		if (!git__parse_bool(&boolval, rule) && !boolval)
+			/* don't set FIND_RENAMES if bool value is false */;
+		else if (!strcasecmp(rule, "copies") || !strcasecmp(rule, "copy"))
+			opts->flags |= GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_COPIES;
+		else
+			opts->flags |= GIT_DIFF_FIND_RENAMES;
+
+		git__free(rule);
+	}
+
+	/* some flags imply others */
+
+	if (opts->flags & GIT_DIFF_FIND_EXACT_MATCH_ONLY) {
+		/* if we are only looking for exact matches, then don't turn
+		 * MODIFIED items into ADD/DELETE pairs because it's too picky
+		 */
+		opts->flags &= ~(GIT_DIFF_FIND_REWRITES | GIT_DIFF_BREAK_REWRITES);
+
+		/* similarly, don't look for self-rewrites to split */
+		opts->flags &= ~GIT_DIFF_FIND_RENAMES_FROM_REWRITES;
+	}
+
+	if (opts->flags & GIT_DIFF_FIND_RENAMES_FROM_REWRITES)
+		opts->flags |= GIT_DIFF_FIND_RENAMES;
+
+	if (opts->flags & GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED)
+		opts->flags |= GIT_DIFF_FIND_COPIES;
+
+	if (opts->flags & GIT_DIFF_BREAK_REWRITES)
+		opts->flags |= GIT_DIFF_FIND_REWRITES;
+
+#define USE_DEFAULT(X) ((X) == 0 || (X) > 100)
+
+	if (USE_DEFAULT(opts->rename_threshold))
+		opts->rename_threshold = DEFAULT_THRESHOLD;
+
+	if (USE_DEFAULT(opts->rename_from_rewrite_threshold))
+		opts->rename_from_rewrite_threshold = DEFAULT_THRESHOLD;
+
+	if (USE_DEFAULT(opts->copy_threshold))
+		opts->copy_threshold = DEFAULT_THRESHOLD;
+
+	if (USE_DEFAULT(opts->break_rewrite_threshold))
+		opts->break_rewrite_threshold = DEFAULT_BREAK_REWRITE_THRESHOLD;
+
+#undef USE_DEFAULT
+
+	if (!opts->rename_limit) {
+		opts->rename_limit = git_config__get_int_force(
+			cfg, "diff.renamelimit", DEFAULT_RENAME_LIMIT);
+
+		if (opts->rename_limit <= 0)
+			opts->rename_limit = DEFAULT_RENAME_LIMIT;
+	}
+
+	/* assign the internal metric with whitespace flag as payload */
+	if (!opts->metric) {
+		opts->metric = git__malloc(sizeof(git_diff_similarity_metric));
+		GITERR_CHECK_ALLOC(opts->metric);
+
+		opts->metric->file_signature = git_diff_find_similar__hashsig_for_file;
+		opts->metric->buffer_signature = git_diff_find_similar__hashsig_for_buf;
+		opts->metric->free_signature = git_diff_find_similar__hashsig_free;
+		opts->metric->similarity = git_diff_find_similar__calc_similarity;
+
+		if (opts->flags & GIT_DIFF_FIND_IGNORE_WHITESPACE)
+			hashsig_opts = GIT_HASHSIG_IGNORE_WHITESPACE;
+		else if (opts->flags & GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE)
+			hashsig_opts = GIT_HASHSIG_NORMAL;
+		else
+			hashsig_opts = GIT_HASHSIG_SMART_WHITESPACE;
+		hashsig_opts |= GIT_HASHSIG_ALLOW_SMALL_FILES;
+		opts->metric->payload = (void *)hashsig_opts;
+	}
+
+	return 0;
+}
+
+static int insert_delete_side_of_split(
+	git_diff *diff, git_vector *onto, const git_diff_delta *delta)
+{
+	/* make new record for DELETED side of split */
+	git_diff_delta *deleted = git_diff__delta_dup(delta, &diff->pool);
+	GITERR_CHECK_ALLOC(deleted);
+
+	deleted->status = GIT_DELTA_DELETED;
+	deleted->nfiles = 1;
+	memset(&deleted->new_file, 0, sizeof(deleted->new_file));
+	deleted->new_file.path = deleted->old_file.path;
+	deleted->new_file.flags |= GIT_DIFF_FLAG_VALID_ID;
+
+	return git_vector_insert(onto, deleted);
+}
+
+static int apply_splits_and_deletes(
+	git_diff *diff, size_t expected_size, bool actually_split)
+{
+	git_vector onto = GIT_VECTOR_INIT;
+	size_t i;
+	git_diff_delta *delta;
+
+	if (git_vector_init(&onto, expected_size, git_diff_delta__cmp) < 0)
+		return -1;
+
+	/* build new delta list without TO_DELETE and splitting TO_SPLIT */
+	git_vector_foreach(&diff->deltas, i, delta) {
+		if ((delta->flags & GIT_DIFF_FLAG__TO_DELETE) != 0)
+			continue;
+
+		if ((delta->flags & GIT_DIFF_FLAG__TO_SPLIT) != 0 && actually_split) {
+			delta->similarity = 0;
+
+			if (insert_delete_side_of_split(diff, &onto, delta) < 0)
+				goto on_error;
+
+			if (diff->new_src == GIT_ITERATOR_TYPE_WORKDIR)
+				delta->status = GIT_DELTA_UNTRACKED;
+			else
+				delta->status = GIT_DELTA_ADDED;
+			delta->nfiles = 1;
+			memset(&delta->old_file, 0, sizeof(delta->old_file));
+			delta->old_file.path = delta->new_file.path;
+			delta->old_file.flags |= GIT_DIFF_FLAG_VALID_ID;
+		}
+
+		/* clean up delta before inserting into new list */
+		GIT_DIFF_FLAG__CLEAR_INTERNAL(delta->flags);
+
+		if (delta->status != GIT_DELTA_COPIED &&
+			delta->status != GIT_DELTA_RENAMED &&
+			(delta->status != GIT_DELTA_MODIFIED || actually_split))
+			delta->similarity = 0;
+
+		/* insert into new list */
+		if (git_vector_insert(&onto, delta) < 0)
+			goto on_error;
+	}
+
+	/* cannot return an error past this point */
+
+	/* free deltas from old list that didn't make it to the new one */
+	git_vector_foreach(&diff->deltas, i, delta) {
+		if ((delta->flags & GIT_DIFF_FLAG__TO_DELETE) != 0)
+			git__free(delta);
+	}
+
+	/* swap new delta list into place */
+	git_vector_swap(&diff->deltas, &onto);
+	git_vector_free(&onto);
+	git_vector_sort(&diff->deltas);
+
+	return 0;
+
+on_error:
+	git_vector_free_deep(&onto);
+
+	return -1;
+}
+
+GIT_INLINE(git_diff_file *) similarity_get_file(git_diff *diff, size_t idx)
+{
+	git_diff_delta *delta = git_vector_get(&diff->deltas, idx / 2);
+	return (idx & 1) ? &delta->new_file : &delta->old_file;
+}
+
+typedef struct {
+	size_t idx;
+	git_iterator_type_t src;
+	git_repository *repo;
+	git_diff_file *file;
+	git_buf data;
+	git_odb_object *odb_obj;
+	git_blob *blob;
+} similarity_info;
+
+static int similarity_init(
+	similarity_info *info, git_diff *diff, size_t file_idx)
+{
+	info->idx  = file_idx;
+	info->src  = (file_idx & 1) ? diff->new_src : diff->old_src;
+	info->repo = diff->repo;
+	info->file = similarity_get_file(diff, file_idx);
+	info->odb_obj = NULL;
+	info->blob = NULL;
+	git_buf_init(&info->data, 0);
+
+	if (info->file->size > 0 || info->src == GIT_ITERATOR_TYPE_WORKDIR)
+		return 0;
+
+	return git_diff_file__resolve_zero_size(
+		info->file, &info->odb_obj, info->repo);
+}
+
+static int similarity_sig(
+	similarity_info *info,
+	const git_diff_find_options *opts,
+	void **cache)
+{
+	int error = 0;
+	git_diff_file *file = info->file;
+
+	if (info->src == GIT_ITERATOR_TYPE_WORKDIR) {
+		if ((error = git_buf_joinpath(
+			&info->data, git_repository_workdir(info->repo), file->path)) < 0)
+			return error;
+
+		/* if path is not a regular file, just skip this item */
+		if (!git_path_isfile(info->data.ptr))
+			return 0;
+
+		/* TODO: apply wd-to-odb filters to file data if necessary */
+
+		error = opts->metric->file_signature(
+			&cache[info->idx], info->file,
+			info->data.ptr, opts->metric->payload);
+	} else {
+		/* if we didn't initially know the size, we might have an odb_obj
+		 * around from earlier, so convert that, otherwise load the blob now
+		 */
+		if (info->odb_obj != NULL)
+			error = git_object__from_odb_object(
+				(git_object **)&info->blob, info->repo,
+				info->odb_obj, GIT_OBJ_BLOB);
+		else
+			error = git_blob_lookup(&info->blob, info->repo, &file->id);
+
+		if (error < 0) {
+			/* if lookup fails, just skip this item in similarity calc */
+			giterr_clear();
+		} else {
+			size_t sz;
+
+			/* index size may not be actual blob size if filtered */
+			if (file->size != git_blob_rawsize(info->blob))
+				file->size = git_blob_rawsize(info->blob);
+
+			sz = (size_t)(git__is_sizet(file->size) ? file->size : -1);
+
+			error = opts->metric->buffer_signature(
+				&cache[info->idx], info->file,
+				git_blob_rawcontent(info->blob), sz, opts->metric->payload);
+		}
+	}
+
+	return error;
+}
+
+static void similarity_unload(similarity_info *info)
+{
+	if (info->odb_obj)
+		git_odb_object_free(info->odb_obj);
+
+	if (info->blob)
+		git_blob_free(info->blob);
+	else
+		git_buf_free(&info->data);
+}
+
+#define FLAG_SET(opts,flag_name) (((opts)->flags & flag_name) != 0)
+
+/* - score < 0 means files cannot be compared
+ * - score >= 100 means files are exact match
+ * - score == 0 means files are completely different
+ */
+static int similarity_measure(
+	int *score,
+	git_diff *diff,
+	const git_diff_find_options *opts,
+	void **cache,
+	size_t a_idx,
+	size_t b_idx)
+{
+	git_diff_file *a_file = similarity_get_file(diff, a_idx);
+	git_diff_file *b_file = similarity_get_file(diff, b_idx);
+	bool exact_match = FLAG_SET(opts, GIT_DIFF_FIND_EXACT_MATCH_ONLY);
+	int error = 0;
+	similarity_info a_info, b_info;
+
+	*score = -1;
+
+	/* don't try to compare files of different types */
+	if (GIT_MODE_TYPE(a_file->mode) != GIT_MODE_TYPE(b_file->mode))
+		return 0;
+
+	/* if exact match is requested, force calculation of missing OIDs now */
+	if (exact_match) {
+		if (git_oid_iszero(&a_file->id) &&
+			diff->old_src == GIT_ITERATOR_TYPE_WORKDIR &&
+			!git_diff__oid_for_file(&a_file->id,
+				diff, a_file->path, a_file->mode, a_file->size))
+			a_file->flags |= GIT_DIFF_FLAG_VALID_ID;
+
+		if (git_oid_iszero(&b_file->id) &&
+			diff->new_src == GIT_ITERATOR_TYPE_WORKDIR &&
+			!git_diff__oid_for_file(&b_file->id,
+				diff, b_file->path, b_file->mode, b_file->size))
+			b_file->flags |= GIT_DIFF_FLAG_VALID_ID;
+	}
+
+	/* check OID match as a quick test */
+	if (git_oid__cmp(&a_file->id, &b_file->id) == 0) {
+		*score = 100;
+		return 0;
+	}
+
+	/* don't calculate signatures if we are doing exact match */
+	if (exact_match) {
+		*score = 0;
+		return 0;
+	}
+
+	memset(&a_info, 0, sizeof(a_info));
+	memset(&b_info, 0, sizeof(b_info));
+
+	/* set up similarity data (will try to update missing file sizes) */
+	if (!cache[a_idx] && (error = similarity_init(&a_info, diff, a_idx)) < 0)
+		return error;
+	if (!cache[b_idx] && (error = similarity_init(&b_info, diff, b_idx)) < 0)
+		goto cleanup;
+
+	/* check if file sizes are nowhere near each other */
+	if (a_file->size > 127 &&
+		b_file->size > 127 &&
+		(a_file->size > (b_file->size << 3) ||
+		 b_file->size > (a_file->size << 3)))
+		goto cleanup;
+
+	/* update signature cache if needed */
+	if (!cache[a_idx]) {
+		if ((error = similarity_sig(&a_info, opts, cache)) < 0)
+			goto cleanup;
+	}
+	if (!cache[b_idx]) {
+		if ((error = similarity_sig(&b_info, opts, cache)) < 0)
+			goto cleanup;
+	}
+
+	/* calculate similarity provided that the metric choose to process
+	 * both the a and b files (some may not if file is too big, etc).
+	 */
+	if (cache[a_idx] && cache[b_idx])
+		error = opts->metric->similarity(
+			score, cache[a_idx], cache[b_idx], opts->metric->payload);
+
+cleanup:
+	similarity_unload(&a_info);
+	similarity_unload(&b_info);
+
+	return error;
+}
+
+static int calc_self_similarity(
+	git_diff *diff,
+	const git_diff_find_options *opts,
+	size_t delta_idx,
+	void **cache)
+{
+	int error, similarity = -1;
+	git_diff_delta *delta = GIT_VECTOR_GET(&diff->deltas, delta_idx);
+
+	if ((delta->flags & GIT_DIFF_FLAG__HAS_SELF_SIMILARITY) != 0)
+		return 0;
+
+	error = similarity_measure(
+		&similarity, diff, opts, cache, 2 * delta_idx, 2 * delta_idx + 1);
+	if (error < 0)
+		return error;
+
+	if (similarity >= 0) {
+		delta->similarity = (uint16_t)similarity;
+		delta->flags |= GIT_DIFF_FLAG__HAS_SELF_SIMILARITY;
+	}
+
+	return 0;
+}
+
+static bool is_rename_target(
+	git_diff *diff,
+	const git_diff_find_options *opts,
+	size_t delta_idx,
+	void **cache)
+{
+	git_diff_delta *delta = GIT_VECTOR_GET(&diff->deltas, delta_idx);
+
+	/* skip things that aren't plain blobs */
+	if (!GIT_MODE_ISBLOB(delta->new_file.mode))
+		return false;
+
+	/* only consider ADDED, RENAMED, COPIED, and split MODIFIED as
+	 * targets; maybe include UNTRACKED if requested.
+	 */
+	switch (delta->status) {
+	case GIT_DELTA_UNMODIFIED:
+	case GIT_DELTA_DELETED:
+	case GIT_DELTA_IGNORED:
+	case GIT_DELTA_CONFLICTED:
+		return false;
+
+	case GIT_DELTA_MODIFIED:
+		if (!FLAG_SET(opts, GIT_DIFF_FIND_REWRITES) &&
+			!FLAG_SET(opts, GIT_DIFF_FIND_RENAMES_FROM_REWRITES))
+			return false;
+
+		if (calc_self_similarity(diff, opts, delta_idx, cache) < 0)
+			return false;
+
+		if (FLAG_SET(opts, GIT_DIFF_BREAK_REWRITES) &&
+			delta->similarity < opts->break_rewrite_threshold) {
+			delta->flags |= GIT_DIFF_FLAG__TO_SPLIT;
+			break;
+		}
+		if (FLAG_SET(opts, GIT_DIFF_FIND_RENAMES_FROM_REWRITES) &&
+			delta->similarity < opts->rename_from_rewrite_threshold)
+			break;
+
+		return false;
+
+	case GIT_DELTA_UNTRACKED:
+		if (!FLAG_SET(opts, GIT_DIFF_FIND_FOR_UNTRACKED))
+			return false;
+		break;
+
+	default: /* all other status values should be checked */
+		break;
+	}
+
+	delta->flags |= GIT_DIFF_FLAG__IS_RENAME_TARGET;
+	return true;
+}
+
+static bool is_rename_source(
+	git_diff *diff,
+	const git_diff_find_options *opts,
+	size_t delta_idx,
+	void **cache)
+{
+	git_diff_delta *delta = GIT_VECTOR_GET(&diff->deltas, delta_idx);
+
+	/* skip things that aren't blobs */
+	if (!GIT_MODE_ISBLOB(delta->old_file.mode))
+		return false;
+
+	switch (delta->status) {
+	case GIT_DELTA_ADDED:
+	case GIT_DELTA_UNTRACKED:
+	case GIT_DELTA_UNREADABLE:
+	case GIT_DELTA_IGNORED:
+	case GIT_DELTA_CONFLICTED:
+		return false;
+
+	case GIT_DELTA_DELETED:
+	case GIT_DELTA_TYPECHANGE:
+		break;
+
+	case GIT_DELTA_UNMODIFIED:
+		if (!FLAG_SET(opts, GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED))
+			return false;
+		if (FLAG_SET(opts, GIT_DIFF_FIND_REMOVE_UNMODIFIED))
+			delta->flags |= GIT_DIFF_FLAG__TO_DELETE;
+		break;
+
+	default: /* MODIFIED, RENAMED, COPIED */
+		/* if we're finding copies, this could be a source */
+		if (FLAG_SET(opts, GIT_DIFF_FIND_COPIES))
+			break;
+
+		/* otherwise, this is only a source if we can split it */
+		if (!FLAG_SET(opts, GIT_DIFF_FIND_REWRITES) &&
+			!FLAG_SET(opts, GIT_DIFF_FIND_RENAMES_FROM_REWRITES))
+			return false;
+
+		if (calc_self_similarity(diff, opts, delta_idx, cache) < 0)
+			return false;
+
+		if (FLAG_SET(opts, GIT_DIFF_BREAK_REWRITES) &&
+			delta->similarity < opts->break_rewrite_threshold) {
+			delta->flags |= GIT_DIFF_FLAG__TO_SPLIT;
+			break;
+		}
+
+		if (FLAG_SET(opts, GIT_DIFF_FIND_RENAMES_FROM_REWRITES) &&
+			delta->similarity < opts->rename_from_rewrite_threshold)
+			break;
+
+		return false;
+	}
+
+	delta->flags |= GIT_DIFF_FLAG__IS_RENAME_SOURCE;
+	return true;
+}
+
+GIT_INLINE(bool) delta_is_split(git_diff_delta *delta)
+{
+	return (delta->status == GIT_DELTA_TYPECHANGE ||
+			(delta->flags & GIT_DIFF_FLAG__TO_SPLIT) != 0);
+}
+
+GIT_INLINE(bool) delta_is_new_only(git_diff_delta *delta)
+{
+	return (delta->status == GIT_DELTA_ADDED ||
+			delta->status == GIT_DELTA_UNTRACKED ||
+			delta->status == GIT_DELTA_UNREADABLE ||
+			delta->status == GIT_DELTA_IGNORED);
+}
+
+GIT_INLINE(void) delta_make_rename(
+	git_diff_delta *to, const git_diff_delta *from, uint16_t similarity)
+{
+	to->status     = GIT_DELTA_RENAMED;
+	to->similarity = similarity;
+	to->nfiles     = 2;
+	memcpy(&to->old_file, &from->old_file, sizeof(to->old_file));
+	to->flags &= ~GIT_DIFF_FLAG__TO_SPLIT;
+}
+
+typedef struct {
+	size_t   idx;
+	uint16_t similarity;
+} diff_find_match;
+
+int git_diff_find_similar(
+	git_diff *diff,
+	const git_diff_find_options *given_opts)
+{
+	size_t s, t;
+	int error = 0, result;
+	uint16_t similarity;
+	git_diff_delta *src, *tgt;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	size_t num_deltas, num_srcs = 0, num_tgts = 0;
+	size_t tried_srcs = 0, tried_tgts = 0;
+	size_t num_rewrites = 0, num_updates = 0, num_bumped = 0;
+	size_t sigcache_size;
+	void **sigcache = NULL; /* cache of similarity metric file signatures */
+	diff_find_match *tgt2src = NULL;
+	diff_find_match *src2tgt = NULL;
+	diff_find_match *tgt2src_copy = NULL;
+	diff_find_match *best_match;
+	git_diff_file swap;
+
+	if ((error = normalize_find_opts(diff, &opts, given_opts)) < 0)
+		return error;
+
+	num_deltas = diff->deltas.length;
+
+	/* TODO: maybe abort if deltas.length > rename_limit ??? */
+	if (!git__is_uint32(num_deltas))
+		goto cleanup;
+
+	/* No flags set; nothing to do */
+	if ((opts.flags & GIT_DIFF_FIND_ALL) == 0)
+		goto cleanup;
+
+	GITERR_CHECK_ALLOC_MULTIPLY(&sigcache_size, num_deltas, 2);
+	sigcache = git__calloc(sigcache_size, sizeof(void *));
+	GITERR_CHECK_ALLOC(sigcache);
+
+	/* Label rename sources and targets
+	 *
+	 * This will also set self-similarity scores for MODIFIED files and
+	 * mark them for splitting if break-rewrites is enabled
+	 */
+	git_vector_foreach(&diff->deltas, t, tgt) {
+		if (is_rename_source(diff, &opts, t, sigcache))
+			++num_srcs;
+
+		if (is_rename_target(diff, &opts, t, sigcache))
+			++num_tgts;
+
+		if ((tgt->flags & GIT_DIFF_FLAG__TO_SPLIT) != 0)
+			num_rewrites++;
+	}
+
+	/* if there are no candidate srcs or tgts, we're done */
+	if (!num_srcs || !num_tgts)
+		goto cleanup;
+
+	src2tgt = git__calloc(num_deltas, sizeof(diff_find_match));
+	GITERR_CHECK_ALLOC(src2tgt);
+	tgt2src = git__calloc(num_deltas, sizeof(diff_find_match));
+	GITERR_CHECK_ALLOC(tgt2src);
+
+	if (FLAG_SET(&opts, GIT_DIFF_FIND_COPIES)) {
+		tgt2src_copy = git__calloc(num_deltas, sizeof(diff_find_match));
+		GITERR_CHECK_ALLOC(tgt2src_copy);
+	}
+
+	/*
+	 * Find best-fit matches for rename / copy candidates
+	 */
+
+find_best_matches:
+	tried_tgts = num_bumped = 0;
+
+	git_vector_foreach(&diff->deltas, t, tgt) {
+		/* skip things that are not rename targets */
+		if ((tgt->flags & GIT_DIFF_FLAG__IS_RENAME_TARGET) == 0)
+			continue;
+
+		tried_srcs = 0;
+
+		git_vector_foreach(&diff->deltas, s, src) {
+			/* skip things that are not rename sources */
+			if ((src->flags & GIT_DIFF_FLAG__IS_RENAME_SOURCE) == 0)
+				continue;
+
+			/* calculate similarity for this pair and find best match */
+			if (s == t)
+				result = -1; /* don't measure self-similarity here */
+			else if ((error = similarity_measure(
+				&result, diff, &opts, sigcache, 2 * s, 2 * t + 1)) < 0)
+				goto cleanup;
+
+			if (result < 0)
+				continue;
+			similarity = (uint16_t)result;
+
+			/* is this a better rename? */
+			if (tgt2src[t].similarity < similarity &&
+				src2tgt[s].similarity < similarity)
+			{
+				/* eject old mapping */
+				if (src2tgt[s].similarity > 0) {
+					tgt2src[src2tgt[s].idx].similarity = 0;
+					num_bumped++;
+				}
+				if (tgt2src[t].similarity > 0) {
+					src2tgt[tgt2src[t].idx].similarity = 0;
+					num_bumped++;
+				}
+
+				/* write new mapping */
+				tgt2src[t].idx = s;
+				tgt2src[t].similarity = similarity;
+				src2tgt[s].idx = t;
+				src2tgt[s].similarity = similarity;
+			}
+
+			/* keep best absolute match for copies */
+			if (tgt2src_copy != NULL &&
+				tgt2src_copy[t].similarity < similarity)
+			{
+				tgt2src_copy[t].idx = s;
+				tgt2src_copy[t].similarity = similarity;
+			}
+
+			if (++tried_srcs >= num_srcs)
+				break;
+
+			/* cap on maximum targets we'll examine (per "tgt" file) */
+			if (tried_srcs > opts.rename_limit)
+				break;
+		}
+
+		if (++tried_tgts >= num_tgts)
+			break;
+	}
+
+	if (num_bumped > 0) /* try again if we bumped some items */
+		goto find_best_matches;
+
+	/*
+	 * Rewrite the diffs with renames / copies
+	 */
+
+	git_vector_foreach(&diff->deltas, t, tgt) {
+		/* skip things that are not rename targets */
+		if ((tgt->flags & GIT_DIFF_FLAG__IS_RENAME_TARGET) == 0)
+			continue;
+
+		/* check if this delta was the target of a similarity */
+		if (tgt2src[t].similarity)
+			best_match = &tgt2src[t];
+		else if (tgt2src_copy && tgt2src_copy[t].similarity)
+			best_match = &tgt2src_copy[t];
+		else
+			continue;
+
+		s = best_match->idx;
+		src = GIT_VECTOR_GET(&diff->deltas, s);
+
+		/* possible scenarios:
+		 * 1. from DELETE to ADD/UNTRACK/IGNORE = RENAME
+		 * 2. from DELETE to SPLIT/TYPECHANGE = RENAME + DELETE
+		 * 3. from SPLIT/TYPECHANGE to ADD/UNTRACK/IGNORE = ADD + RENAME
+		 * 4. from SPLIT/TYPECHANGE to SPLIT/TYPECHANGE = RENAME + SPLIT
+		 * 5. from OTHER to ADD/UNTRACK/IGNORE = OTHER + COPY
+		 */
+
+		if (src->status == GIT_DELTA_DELETED) {
+
+			if (delta_is_new_only(tgt)) {
+
+				if (best_match->similarity < opts.rename_threshold)
+					continue;
+
+				delta_make_rename(tgt, src, best_match->similarity);
+
+				src->flags |= GIT_DIFF_FLAG__TO_DELETE;
+				num_rewrites++;
+			} else {
+				assert(delta_is_split(tgt));
+
+				if (best_match->similarity < opts.rename_from_rewrite_threshold)
+					continue;
+
+				memcpy(&swap, &tgt->old_file, sizeof(swap));
+
+				delta_make_rename(tgt, src, best_match->similarity);
+				num_rewrites--;
+
+				assert(src->status == GIT_DELTA_DELETED);
+				memcpy(&src->old_file, &swap, sizeof(src->old_file));
+				memset(&src->new_file, 0, sizeof(src->new_file));
+				src->new_file.path = src->old_file.path;
+				src->new_file.flags |= GIT_DIFF_FLAG_VALID_ID;
+
+				num_updates++;
+
+				if (src2tgt[t].similarity > 0 && src2tgt[t].idx > t) {
+					/* what used to be at src t is now at src s */
+					tgt2src[src2tgt[t].idx].idx = s;
+				}
+			}
+		}
+
+		else if (delta_is_split(src)) {
+
+			if (delta_is_new_only(tgt)) {
+
+				if (best_match->similarity < opts.rename_threshold)
+					continue;
+
+				delta_make_rename(tgt, src, best_match->similarity);
+
+				src->status = (diff->new_src == GIT_ITERATOR_TYPE_WORKDIR) ?
+					GIT_DELTA_UNTRACKED : GIT_DELTA_ADDED;
+				src->nfiles = 1;
+				memset(&src->old_file, 0, sizeof(src->old_file));
+				src->old_file.path = src->new_file.path;
+				src->old_file.flags |= GIT_DIFF_FLAG_VALID_ID;
+
+				src->flags &= ~GIT_DIFF_FLAG__TO_SPLIT;
+				num_rewrites--;
+
+				num_updates++;
+			} else {
+				assert(delta_is_split(src));
+
+				if (best_match->similarity < opts.rename_from_rewrite_threshold)
+					continue;
+
+				memcpy(&swap, &tgt->old_file, sizeof(swap));
+
+				delta_make_rename(tgt, src, best_match->similarity);
+				num_rewrites--;
+				num_updates++;
+
+				memcpy(&src->old_file, &swap, sizeof(src->old_file));
+
+				/* if we've just swapped the new element into the correct
+				 * place, clear the SPLIT flag
+				 */
+				if (tgt2src[s].idx == t &&
+					tgt2src[s].similarity >
+					opts.rename_from_rewrite_threshold) {
+					src->status     = GIT_DELTA_RENAMED;
+					src->similarity = tgt2src[s].similarity;
+					tgt2src[s].similarity = 0;
+					src->flags &= ~GIT_DIFF_FLAG__TO_SPLIT;
+					num_rewrites--;
+				}
+				/* otherwise, if we just overwrote a source, update mapping */
+				else if (src2tgt[t].similarity > 0 && src2tgt[t].idx > t) {
+					/* what used to be at src t is now at src s */
+					tgt2src[src2tgt[t].idx].idx = s;
+				}
+
+				num_updates++;
+			}
+		}
+
+		else if (FLAG_SET(&opts, GIT_DIFF_FIND_COPIES)) {
+			if (tgt2src_copy[t].similarity < opts.copy_threshold)
+				continue;
+
+			/* always use best possible source for copy */
+			best_match = &tgt2src_copy[t];
+			src = GIT_VECTOR_GET(&diff->deltas, best_match->idx);
+
+			if (delta_is_split(tgt)) {
+				error = insert_delete_side_of_split(diff, &diff->deltas, tgt);
+				if (error < 0)
+					goto cleanup;
+				num_rewrites--;
+			}
+
+			if (!delta_is_split(tgt) && !delta_is_new_only(tgt))
+				continue;
+
+			tgt->status     = GIT_DELTA_COPIED;
+			tgt->similarity = best_match->similarity;
+			tgt->nfiles     = 2;
+			memcpy(&tgt->old_file, &src->old_file, sizeof(tgt->old_file));
+			tgt->flags &= ~GIT_DIFF_FLAG__TO_SPLIT;
+
+			num_updates++;
+		}
+	}
+
+	/*
+	 * Actually split and delete entries as needed
+	 */
+
+	if (num_rewrites > 0 || num_updates > 0)
+		error = apply_splits_and_deletes(
+			diff, diff->deltas.length - num_rewrites,
+			FLAG_SET(&opts, GIT_DIFF_BREAK_REWRITES) &&
+			!FLAG_SET(&opts, GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY));
+
+cleanup:
+	git__free(tgt2src);
+	git__free(src2tgt);
+	git__free(tgt2src_copy);
+
+	if (sigcache) {
+		for (t = 0; t < num_deltas * 2; ++t) {
+			if (sigcache[t] != NULL)
+				opts.metric->free_signature(sigcache[t], opts.metric->payload);
+		}
+		git__free(sigcache);
+	}
+
+	if (!given_opts || !given_opts->metric)
+		git__free(opts.metric);
+
+	return error;
+}
+
+#undef FLAG_SET
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_xdiff.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_xdiff.c
new file mode 100755
index 0000000..1057df3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_xdiff.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "git2/errors.h"
+#include "common.h"
+#include "diff.h"
+#include "diff_driver.h"
+#include "diff_patch.h"
+#include "diff_xdiff.h"
+
+static int git_xdiff_scan_int(const char **str, int *value)
+{
+	const char *scan = *str;
+	int v = 0, digits = 0;
+	/* find next digit */
+	for (scan = *str; *scan && !git__isdigit(*scan); scan++);
+	/* parse next number */
+	for (; git__isdigit(*scan); scan++, digits++)
+		v = (v * 10) + (*scan - '0');
+	*str = scan;
+	*value = v;
+	return (digits > 0) ? 0 : -1;
+}
+
+static int git_xdiff_parse_hunk(git_diff_hunk *hunk, const char *header)
+{
+	/* expect something of the form "@@ -%d[,%d] +%d[,%d] @@" */
+	if (*header != '@')
+		goto fail;
+	if (git_xdiff_scan_int(&header, &hunk->old_start) < 0)
+		goto fail;
+	if (*header == ',') {
+		if (git_xdiff_scan_int(&header, &hunk->old_lines) < 0)
+			goto fail;
+	} else
+		hunk->old_lines = 1;
+	if (git_xdiff_scan_int(&header, &hunk->new_start) < 0)
+		goto fail;
+	if (*header == ',') {
+		if (git_xdiff_scan_int(&header, &hunk->new_lines) < 0)
+			goto fail;
+	} else
+		hunk->new_lines = 1;
+	if (hunk->old_start < 0 || hunk->new_start < 0)
+		goto fail;
+
+	return 0;
+
+fail:
+	giterr_set(GITERR_INVALID, "Malformed hunk header from xdiff");
+	return -1;
+}
+
+typedef struct {
+	git_xdiff_output *xo;
+	git_patch *patch;
+	git_diff_hunk hunk;
+	int old_lineno, new_lineno;
+	mmfile_t xd_old_data, xd_new_data;
+} git_xdiff_info;
+
+static int diff_update_lines(
+	git_xdiff_info *info,
+	git_diff_line *line,
+	const char *content,
+	size_t content_len)
+{
+	const char *scan = content, *scan_end = content + content_len;
+
+	for (line->num_lines = 0; scan < scan_end; ++scan)
+		if (*scan == '\n')
+			++line->num_lines;
+
+	line->content     = content;
+	line->content_len = content_len;
+
+	/* expect " "/"-"/"+", then data */
+	switch (line->origin) {
+	case GIT_DIFF_LINE_ADDITION:
+	case GIT_DIFF_LINE_DEL_EOFNL:
+		line->old_lineno = -1;
+		line->new_lineno = info->new_lineno;
+		info->new_lineno += (int)line->num_lines;
+		break;
+	case GIT_DIFF_LINE_DELETION:
+	case GIT_DIFF_LINE_ADD_EOFNL:
+		line->old_lineno = info->old_lineno;
+		line->new_lineno = -1;
+		info->old_lineno += (int)line->num_lines;
+		break;
+	case GIT_DIFF_LINE_CONTEXT:
+	case GIT_DIFF_LINE_CONTEXT_EOFNL:
+		line->old_lineno = info->old_lineno;
+		line->new_lineno = info->new_lineno;
+		info->old_lineno += (int)line->num_lines;
+		info->new_lineno += (int)line->num_lines;
+		break;
+	default:
+		giterr_set(GITERR_INVALID, "Unknown diff line origin %02x",
+			(unsigned int)line->origin);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len)
+{
+	git_xdiff_info *info = priv;
+	git_patch *patch = info->patch;
+	const git_diff_delta *delta = git_patch_get_delta(patch);
+	git_diff_output *output = &info->xo->output;
+	git_diff_line line;
+
+	if (len == 1) {
+		output->error = git_xdiff_parse_hunk(&info->hunk, bufs[0].ptr);
+		if (output->error < 0)
+			return output->error;
+
+		info->hunk.header_len = bufs[0].size;
+		if (info->hunk.header_len >= sizeof(info->hunk.header))
+			info->hunk.header_len = sizeof(info->hunk.header) - 1;
+		memcpy(info->hunk.header, bufs[0].ptr, info->hunk.header_len);
+		info->hunk.header[info->hunk.header_len] = '\0';
+
+		if (output->hunk_cb != NULL &&
+			(output->error = output->hunk_cb(
+				delta, &info->hunk, output->payload)))
+			return output->error;
+
+		info->old_lineno = info->hunk.old_start;
+		info->new_lineno = info->hunk.new_start;
+	}
+
+	if (len == 2 || len == 3) {
+		/* expect " "/"-"/"+", then data */
+		line.origin =
+			(*bufs[0].ptr == '+') ? GIT_DIFF_LINE_ADDITION :
+			(*bufs[0].ptr == '-') ? GIT_DIFF_LINE_DELETION :
+			GIT_DIFF_LINE_CONTEXT;
+
+		if (line.origin == GIT_DIFF_LINE_ADDITION)
+			line.content_offset = bufs[1].ptr - info->xd_new_data.ptr;
+		else if (line.origin == GIT_DIFF_LINE_DELETION)
+			line.content_offset = bufs[1].ptr - info->xd_old_data.ptr;
+		else
+			line.content_offset = -1;
+
+		output->error = diff_update_lines(
+			info, &line, bufs[1].ptr, bufs[1].size);
+
+		if (!output->error && output->data_cb != NULL)
+			output->error = output->data_cb(
+				delta, &info->hunk, &line, output->payload);
+	}
+
+	if (len == 3 && !output->error) {
+		/* If we have a '+' and a third buf, then we have added a line
+		 * without a newline and the old code had one, so DEL_EOFNL.
+		 * If we have a '-' and a third buf, then we have removed a line
+		 * with out a newline but added a blank line, so ADD_EOFNL.
+		 */
+		line.origin =
+			(*bufs[0].ptr == '+') ? GIT_DIFF_LINE_DEL_EOFNL :
+			(*bufs[0].ptr == '-') ? GIT_DIFF_LINE_ADD_EOFNL :
+			GIT_DIFF_LINE_CONTEXT_EOFNL;
+
+		line.content_offset = -1;
+
+		output->error = diff_update_lines(
+			info, &line, bufs[2].ptr, bufs[2].size);
+
+		if (!output->error && output->data_cb != NULL)
+			output->error = output->data_cb(
+				delta, &info->hunk, &line, output->payload);
+	}
+
+	return output->error;
+}
+
+static int git_xdiff(git_diff_output *output, git_patch *patch)
+{
+	git_xdiff_output *xo = (git_xdiff_output *)output;
+	git_xdiff_info info;
+	git_diff_find_context_payload findctxt;
+
+	memset(&info, 0, sizeof(info));
+	info.patch = patch;
+	info.xo    = xo;
+
+	xo->callback.priv = &info;
+
+	git_diff_find_context_init(
+		&xo->config.find_func, &findctxt, git_patch__driver(patch));
+	xo->config.find_func_priv = &findctxt;
+
+	if (xo->config.find_func != NULL)
+		xo->config.flags |= XDL_EMIT_FUNCNAMES;
+	else
+		xo->config.flags &= ~XDL_EMIT_FUNCNAMES;
+
+	/* TODO: check ofile.opts_flags to see if driver-specific per-file
+	 * updates are needed to xo->params.flags
+	 */
+
+	git_patch__old_data(&info.xd_old_data.ptr, &info.xd_old_data.size, patch);
+	git_patch__new_data(&info.xd_new_data.ptr, &info.xd_new_data.size, patch);
+
+	if (info.xd_old_data.size > GIT_XDIFF_MAX_SIZE ||
+		info.xd_new_data.size > GIT_XDIFF_MAX_SIZE) {
+		giterr_set(GITERR_INVALID, "files too large for diff");
+		return -1;
+	}
+
+	xdl_diff(&info.xd_old_data, &info.xd_new_data,
+		&xo->params, &xo->config, &xo->callback);
+
+	git_diff_find_context_clear(&findctxt);
+
+	return xo->output.error;
+}
+
+void git_xdiff_init(git_xdiff_output *xo, const git_diff_options *opts)
+{
+	uint32_t flags = opts ? opts->flags : 0;
+
+	xo->output.diff_cb = git_xdiff;
+
+	xo->config.ctxlen = opts ? opts->context_lines : 3;
+	xo->config.interhunkctxlen = opts ? opts->interhunk_lines : 0;
+
+	if (flags & GIT_DIFF_IGNORE_WHITESPACE)
+		xo->params.flags |= XDF_WHITESPACE_FLAGS;
+	if (flags & GIT_DIFF_IGNORE_WHITESPACE_CHANGE)
+		xo->params.flags |= XDF_IGNORE_WHITESPACE_CHANGE;
+	if (flags & GIT_DIFF_IGNORE_WHITESPACE_EOL)
+		xo->params.flags |= XDF_IGNORE_WHITESPACE_AT_EOL;
+
+	if (flags & GIT_DIFF_PATIENCE)
+		xo->params.flags |= XDF_PATIENCE_DIFF;
+	if (flags & GIT_DIFF_MINIMAL)
+		xo->params.flags |= XDF_NEED_MINIMAL;
+
+	xo->callback.outf = git_xdiff_cb;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_xdiff.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_xdiff.h
new file mode 100755
index 0000000..98e11b2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/diff_xdiff.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_diff_xdiff_h__
+#define INCLUDE_diff_xdiff_h__
+
+#include "diff.h"
+#include "diff_patch.h"
+#include "xdiff/xdiff.h"
+
+/* xdiff cannot cope with large files.  these files should not be passed to
+ * xdiff.  callers should treat these large files as binary.
+ */
+#define GIT_XDIFF_MAX_SIZE (1024LL * 1024 * 1023)
+
+/* A git_xdiff_output is a git_diff_output with extra fields necessary
+ * to use libxdiff.  Calling git_xdiff_init() will set the diff_cb field
+ * of the output to use xdiff to generate the diffs.
+ */
+typedef struct {
+	git_diff_output output;
+
+	xdemitconf_t config;
+	xpparam_t    params;
+	xdemitcb_t   callback;
+} git_xdiff_output;
+
+void git_xdiff_init(git_xdiff_output *xo, const git_diff_options *opts);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/errors.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/errors.c
new file mode 100755
index 0000000..7a26005
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/errors.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "global.h"
+#include "posix.h"
+#include "buffer.h"
+
+/********************************************
+ * New error handling
+ ********************************************/
+
+static git_error g_git_oom_error = {
+	"Out of memory",
+	GITERR_NOMEMORY
+};
+
+static void set_error(int error_class, char *string)
+{
+	git_error *error = &GIT_GLOBAL->error_t;
+
+	if (error->message != string)
+		git__free(error->message);
+
+	error->message = string;
+	error->klass = error_class;
+
+	GIT_GLOBAL->last_error = error;
+}
+
+void giterr_set_oom(void)
+{
+	GIT_GLOBAL->last_error = &g_git_oom_error;
+}
+
+void giterr_set(int error_class, const char *string, ...)
+{
+	git_buf buf = GIT_BUF_INIT;
+	va_list arglist;
+#ifdef GIT_WIN32
+	DWORD win32_error_code = (error_class == GITERR_OS) ? GetLastError() : 0;
+#endif
+	int error_code = (error_class == GITERR_OS) ? errno : 0;
+
+	if (string) {
+		va_start(arglist, string);
+		git_buf_vprintf(&buf, string, arglist);
+		va_end(arglist);
+
+		if (error_class == GITERR_OS)
+			git_buf_PUTS(&buf, ": ");
+	}
+
+	if (error_class == GITERR_OS) {
+#ifdef GIT_WIN32
+		char * win32_error = git_win32_get_error_message(win32_error_code);
+		if (win32_error) {
+			git_buf_puts(&buf, win32_error);
+			git__free(win32_error);
+
+			SetLastError(0);
+		}
+		else
+#endif
+		if (error_code)
+			git_buf_puts(&buf, strerror(error_code));
+
+		if (error_code)
+			errno = 0;
+	}
+
+	if (!git_buf_oom(&buf))
+		set_error(error_class, git_buf_detach(&buf));
+}
+
+void giterr_set_str(int error_class, const char *string)
+{
+	char *message;
+
+	assert(string);
+
+	message = git__strdup(string);
+
+	if (message)
+		set_error(error_class, message);
+}
+
+int giterr_set_regex(const regex_t *regex, int error_code)
+{
+	char error_buf[1024];
+
+	assert(error_code);
+
+	regerror(error_code, regex, error_buf, sizeof(error_buf));
+	giterr_set_str(GITERR_REGEX, error_buf);
+
+	if (error_code == REG_NOMATCH)
+		return GIT_ENOTFOUND;
+
+	return GIT_EINVALIDSPEC;
+}
+
+void giterr_clear(void)
+{
+	if (GIT_GLOBAL->last_error != NULL) {
+		set_error(0, NULL);
+		GIT_GLOBAL->last_error = NULL;
+	}
+
+	errno = 0;
+#ifdef GIT_WIN32
+	SetLastError(0);
+#endif
+}
+
+int giterr_detach(git_error *cpy)
+{
+	git_error *error = GIT_GLOBAL->last_error;
+
+	assert(cpy);
+
+	if (!error)
+		return -1;
+
+	cpy->message = error->message;
+	cpy->klass = error->klass;
+
+	error->message = NULL;
+	giterr_clear();
+
+	return 0;
+}
+
+const git_error *giterr_last(void)
+{
+	return GIT_GLOBAL->last_error;
+}
+
+int giterr_capture(git_error_state *state, int error_code)
+{
+	state->error_code = error_code;
+	if (error_code)
+		giterr_detach(&state->error_msg);
+	return error_code;
+}
+
+int giterr_restore(git_error_state *state)
+{
+	if (state && state->error_code && state->error_msg.message)
+		set_error(state->error_msg.klass, state->error_msg.message);
+	else
+		giterr_clear();
+
+	return state ? state->error_code : 0;
+}
+
+int giterr_system_last(void)
+{
+#ifdef GIT_WIN32
+	return GetLastError();
+#else
+	return errno;
+#endif
+}
+
+void giterr_system_set(int code)
+{
+#ifdef GIT_WIN32
+	SetLastError(code);
+#else
+	errno = code;
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fetch.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fetch.c
new file mode 100755
index 0000000..4d89575
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fetch.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2/oid.h"
+#include "git2/refs.h"
+#include "git2/revwalk.h"
+#include "git2/transport.h"
+
+#include "common.h"
+#include "remote.h"
+#include "refspec.h"
+#include "pack.h"
+#include "fetch.h"
+#include "netops.h"
+#include "repository.h"
+#include "refs.h"
+
+static int maybe_want(git_remote *remote, git_remote_head *head, git_odb *odb, git_refspec *tagspec, git_remote_autotag_option_t tagopt)
+{
+	int match = 0;
+
+	if (!git_reference_is_valid_name(head->name))
+		return 0;
+
+	if (tagopt == GIT_REMOTE_DOWNLOAD_TAGS_ALL) {
+		/*
+		 * If tagopt is --tags, always request tags
+		 * in addition to the remote's refspecs
+		 */
+		if (git_refspec_src_matches(tagspec, head->name))
+			match = 1;
+	}
+
+	if (!match && git_remote__matching_refspec(remote, head->name))
+		match = 1;
+
+	if (!match)
+		return 0;
+
+	/* If we have the object, mark it so we don't ask for it */
+	if (git_odb_exists(odb, &head->oid)) {
+		head->local = 1;
+	}
+	else
+		remote->need_pack = 1;
+
+	return git_vector_insert(&remote->refs, head);
+}
+
+static int filter_wants(git_remote *remote, const git_fetch_options *opts)
+{
+	git_remote_head **heads;
+	git_refspec tagspec, head;
+	int error = 0;
+	git_odb *odb;
+	size_t i, heads_len;
+	git_remote_autotag_option_t tagopt = remote->download_tags;
+
+	if (opts && opts->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED)
+		tagopt = opts->download_tags;
+
+	git_vector_clear(&remote->refs);
+	if ((error = git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true)) < 0)
+		return error;
+
+	/*
+	 * The fetch refspec can be NULL, and what this means is that the
+	 * user didn't specify one. This is fine, as it means that we're
+	 * not interested in any particular branch but just the remote's
+	 * HEAD, which will be stored in FETCH_HEAD after the fetch.
+	 */
+	if (remote->active_refspecs.length == 0) {
+		if ((error = git_refspec__parse(&head, "HEAD", true)) < 0)
+			goto cleanup;
+
+		error = git_refspec__dwim_one(&remote->active_refspecs, &head, &remote->refs);
+		git_refspec__free(&head);
+
+		if (error < 0)
+			goto cleanup;
+	}
+
+	if (git_repository_odb__weakptr(&odb, remote->repo) < 0)
+		goto cleanup;
+
+	if (git_remote_ls((const git_remote_head ***)&heads, &heads_len, remote) < 0)
+		goto cleanup;
+
+	for (i = 0; i < heads_len; i++) {
+		if ((error = maybe_want(remote, heads[i], odb, &tagspec, tagopt)) < 0)
+			break;
+	}
+
+cleanup:
+	git_refspec__free(&tagspec);
+
+	return error;
+}
+
+/*
+ * In this first version, we push all our refs in and start sending
+ * them out. When we get an ACK we hide that commit and continue
+ * traversing until we're done
+ */
+int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts)
+{
+	git_transport *t = remote->transport;
+
+	remote->need_pack = 0;
+
+	if (filter_wants(remote, opts) < 0) {
+		giterr_set(GITERR_NET, "Failed to filter the reference list for wants");
+		return -1;
+	}
+
+	/* Don't try to negotiate when we don't want anything */
+	if (!remote->need_pack)
+		return 0;
+
+	/*
+	 * Now we have everything set up so we can start tell the
+	 * server what we want and what we have.
+	 */
+	return t->negotiate_fetch(t,
+		remote->repo,
+		(const git_remote_head * const *)remote->refs.contents,
+		remote->refs.length);
+}
+
+int git_fetch_download_pack(git_remote *remote, const git_remote_callbacks *callbacks)
+{
+	git_transport *t = remote->transport;
+	git_transfer_progress_cb progress = NULL;
+	void *payload = NULL;
+
+	if (!remote->need_pack)
+		return 0;
+
+	if (callbacks) {
+		progress = callbacks->transfer_progress;
+		payload  = callbacks->payload;
+	}
+
+	return t->download_pack(t, remote->repo, &remote->stats, progress, payload);
+}
+
+int git_fetch_init_options(git_fetch_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_fetch_options, GIT_FETCH_OPTIONS_INIT);
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fetch.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fetch.h
new file mode 100755
index 0000000..0412d4e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fetch.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_fetch_h__
+#define INCLUDE_fetch_h__
+
+#include "netops.h"
+
+int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts);
+
+int git_fetch_download_pack(git_remote *remote, const git_remote_callbacks *callbacks);
+
+int git_fetch_setup_walk(git_revwalk **out, git_repository *repo);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fetchhead.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fetchhead.c
new file mode 100755
index 0000000..a95ea4c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fetchhead.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2/types.h"
+#include "git2/oid.h"
+
+#include "fetchhead.h"
+#include "common.h"
+#include "buffer.h"
+#include "fileops.h"
+#include "filebuf.h"
+#include "refs.h"
+#include "repository.h"
+
+int git_fetchhead_ref_cmp(const void *a, const void *b)
+{
+	const git_fetchhead_ref *one = (const git_fetchhead_ref *)a;
+	const git_fetchhead_ref *two = (const git_fetchhead_ref *)b;
+
+	if (one->is_merge && !two->is_merge)
+		return -1;
+	if (two->is_merge && !one->is_merge)
+		return 1;
+
+	if (one->ref_name && two->ref_name)
+		return strcmp(one->ref_name, two->ref_name);
+	else if (one->ref_name)
+		return -1;
+	else if (two->ref_name)
+		return 1;
+
+	return 0;
+}
+
+int git_fetchhead_ref_create(
+	git_fetchhead_ref **out,
+	git_oid *oid,
+	unsigned int is_merge,
+	const char *ref_name,
+	const char *remote_url)
+{
+	git_fetchhead_ref *fetchhead_ref;
+
+	assert(out && oid);
+
+	*out = NULL;
+
+	fetchhead_ref = git__malloc(sizeof(git_fetchhead_ref));
+	GITERR_CHECK_ALLOC(fetchhead_ref);
+
+	memset(fetchhead_ref, 0x0, sizeof(git_fetchhead_ref));
+
+	git_oid_cpy(&fetchhead_ref->oid, oid);
+	fetchhead_ref->is_merge = is_merge;
+
+	if (ref_name)
+		fetchhead_ref->ref_name = git__strdup(ref_name);
+
+	if (remote_url)
+		fetchhead_ref->remote_url = git__strdup(remote_url);
+
+	*out = fetchhead_ref;
+
+	return 0;
+}
+
+static int fetchhead_ref_write(
+	git_filebuf *file,
+	git_fetchhead_ref *fetchhead_ref)
+{
+	char oid[GIT_OID_HEXSZ + 1];
+	const char *type, *name;
+	int head = 0;
+
+	assert(file && fetchhead_ref);
+
+	git_oid_fmt(oid, &fetchhead_ref->oid);
+	oid[GIT_OID_HEXSZ] = '\0';
+
+	if (git__prefixcmp(fetchhead_ref->ref_name, GIT_REFS_HEADS_DIR) == 0) {
+		type = "branch ";
+		name = fetchhead_ref->ref_name + strlen(GIT_REFS_HEADS_DIR);
+	} else if(git__prefixcmp(fetchhead_ref->ref_name,
+		GIT_REFS_TAGS_DIR) == 0) {
+		type = "tag ";
+		name = fetchhead_ref->ref_name + strlen(GIT_REFS_TAGS_DIR);
+	} else if (!git__strcmp(fetchhead_ref->ref_name, GIT_HEAD_FILE)) {
+		head = 1;
+	} else {
+		type = "";
+		name = fetchhead_ref->ref_name;
+	}
+
+	if (head)
+		return git_filebuf_printf(file, "%s\t\t%s\n", oid, fetchhead_ref->remote_url);
+
+	return git_filebuf_printf(file, "%s\t%s\t%s'%s' of %s\n",
+		oid,
+		(fetchhead_ref->is_merge) ? "" : "not-for-merge",
+		type,
+		name,
+		fetchhead_ref->remote_url);
+}
+
+int git_fetchhead_write(git_repository *repo, git_vector *fetchhead_refs)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	git_buf path = GIT_BUF_INIT;
+	unsigned int i;
+	git_fetchhead_ref *fetchhead_ref;
+
+	assert(repo && fetchhead_refs);
+
+	if (git_buf_joinpath(&path, repo->path_repository, GIT_FETCH_HEAD_FILE) < 0)
+		return -1;
+
+	if (git_filebuf_open(&file, path.ptr, GIT_FILEBUF_FORCE, GIT_REFS_FILE_MODE) < 0) {
+		git_buf_free(&path);
+		return -1;
+	}
+
+	git_buf_free(&path);
+
+	git_vector_sort(fetchhead_refs);
+
+	git_vector_foreach(fetchhead_refs, i, fetchhead_ref)
+		fetchhead_ref_write(&file, fetchhead_ref);
+
+	return git_filebuf_commit(&file);
+}
+
+static int fetchhead_ref_parse(
+	git_oid *oid,
+	unsigned int *is_merge,
+	git_buf *ref_name,
+	const char **remote_url,
+	char *line,
+	size_t line_num)
+{
+	char *oid_str, *is_merge_str, *desc, *name = NULL;
+	const char *type = NULL;
+	int error = 0;
+
+	*remote_url = NULL;
+
+	if (!*line) {
+		giterr_set(GITERR_FETCHHEAD,
+			"Empty line in FETCH_HEAD line %d", line_num);
+		return -1;
+	}
+
+	/* Compat with old git clients that wrote FETCH_HEAD like a loose ref. */
+	if ((oid_str = git__strsep(&line, "\t")) == NULL) {
+		oid_str = line;
+		line += strlen(line);
+
+		*is_merge = 1;
+	}
+
+	if (strlen(oid_str) != GIT_OID_HEXSZ) {
+		giterr_set(GITERR_FETCHHEAD,
+			"Invalid object ID in FETCH_HEAD line %d", line_num);
+		return -1;
+	}
+
+	if (git_oid_fromstr(oid, oid_str) < 0) {
+		const git_error *oid_err = giterr_last();
+		const char *err_msg = oid_err ? oid_err->message : "Invalid object ID";
+
+		giterr_set(GITERR_FETCHHEAD, "%s in FETCH_HEAD line %d",
+			err_msg, line_num);
+		return -1;
+	}
+
+	/* Parse new data from newer git clients */
+	if (*line) {
+		if ((is_merge_str = git__strsep(&line, "\t")) == NULL) {
+			giterr_set(GITERR_FETCHHEAD,
+				"Invalid description data in FETCH_HEAD line %d", line_num);
+			return -1;
+		}
+
+		if (*is_merge_str == '\0')
+			*is_merge = 1;
+		else if (strcmp(is_merge_str, "not-for-merge") == 0)
+			*is_merge = 0;
+		else {
+			giterr_set(GITERR_FETCHHEAD,
+				"Invalid for-merge entry in FETCH_HEAD line %d", line_num);
+			return -1;
+		}
+
+		if ((desc = line) == NULL) {
+			giterr_set(GITERR_FETCHHEAD,
+				"Invalid description in FETCH_HEAD line %d", line_num);
+			return -1;
+		}
+
+		if (git__prefixcmp(desc, "branch '") == 0) {
+			type = GIT_REFS_HEADS_DIR;
+			name = desc + 8;
+		} else if (git__prefixcmp(desc, "tag '") == 0) {
+			type = GIT_REFS_TAGS_DIR;
+			name = desc + 5;
+		} else if (git__prefixcmp(desc, "'") == 0)
+			name = desc + 1;
+
+		if (name) {
+			if ((desc = strstr(name, "' ")) == NULL ||
+				git__prefixcmp(desc, "' of ") != 0) {
+				giterr_set(GITERR_FETCHHEAD,
+					"Invalid description in FETCH_HEAD line %d", line_num);
+				return -1;
+			}
+
+			*desc = '\0';
+			desc += 5;
+		}
+
+		*remote_url = desc;
+	}
+
+	git_buf_clear(ref_name);
+
+	if (type)
+		git_buf_join(ref_name, '/', type, name);
+	else if(name)
+		git_buf_puts(ref_name, name);
+
+	return error;
+}
+
+int git_repository_fetchhead_foreach(git_repository *repo,
+	git_repository_fetchhead_foreach_cb cb,
+	void *payload)
+{
+	git_buf path = GIT_BUF_INIT, file = GIT_BUF_INIT, name = GIT_BUF_INIT;
+	const char *ref_name;
+	git_oid oid;
+	const char *remote_url;
+	unsigned int is_merge = 0;
+	char *buffer, *line;
+	size_t line_num = 0;
+	int error = 0;
+
+	assert(repo && cb);
+
+	if (git_buf_joinpath(&path, repo->path_repository, GIT_FETCH_HEAD_FILE) < 0)
+		return -1;
+
+	if ((error = git_futils_readbuffer(&file, git_buf_cstr(&path))) < 0)
+		goto done;
+
+	buffer = file.ptr;
+
+	while ((line = git__strsep(&buffer, "\n")) != NULL) {
+		++line_num;
+
+		if ((error = fetchhead_ref_parse(
+				&oid, &is_merge, &name, &remote_url, line, line_num)) < 0)
+			goto done;
+
+		if (git_buf_len(&name) > 0)
+			ref_name = git_buf_cstr(&name);
+		else
+			ref_name = NULL;
+
+		error = cb(ref_name, remote_url, &oid, is_merge, payload);
+		if (error) {
+			giterr_set_after_callback(error);
+			goto done;
+		}
+	}
+
+	if (*buffer) {
+		giterr_set(GITERR_FETCHHEAD, "No EOL at line %d", line_num+1);
+		error = -1;
+		goto done;
+	}
+
+done:
+	git_buf_free(&file);
+	git_buf_free(&path);
+	git_buf_free(&name);
+
+	return error;
+}
+
+void git_fetchhead_ref_free(git_fetchhead_ref *fetchhead_ref)
+{
+	if (fetchhead_ref == NULL)
+		return;
+
+	git__free(fetchhead_ref->remote_url);
+	git__free(fetchhead_ref->ref_name);
+	git__free(fetchhead_ref);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fetchhead.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fetchhead.h
new file mode 100755
index 0000000..b03bd0f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fetchhead.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_fetchhead_h__
+#define INCLUDE_fetchhead_h__
+
+#include "vector.h"
+
+typedef struct git_fetchhead_ref {
+	git_oid oid;
+	unsigned int is_merge;
+	char *ref_name;
+	char *remote_url;
+} git_fetchhead_ref;
+
+int git_fetchhead_ref_create(
+	git_fetchhead_ref **fetchhead_ref_out,
+	git_oid *oid,
+	unsigned int is_merge,
+	const char *ref_name,
+	const char *remote_url);
+
+int git_fetchhead_ref_cmp(const void *a, const void *b);
+
+int git_fetchhead_write(git_repository *repo, git_vector *fetchhead_refs);
+
+void git_fetchhead_ref_free(git_fetchhead_ref *fetchhead_ref);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/filebuf.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/filebuf.c
new file mode 100755
index 0000000..838f4b4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/filebuf.c
@@ -0,0 +1,491 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "filebuf.h"
+#include "fileops.h"
+
+static const size_t WRITE_BUFFER_SIZE = (4096 * 2);
+
+enum buferr_t {
+	BUFERR_OK = 0,
+	BUFERR_WRITE,
+	BUFERR_ZLIB,
+	BUFERR_MEM
+};
+
+#define ENSURE_BUF_OK(buf) if ((buf)->last_error != BUFERR_OK) { return -1; }
+
+static int verify_last_error(git_filebuf *file)
+{
+	switch (file->last_error) {
+	case BUFERR_WRITE:
+		giterr_set(GITERR_OS, "Failed to write out file");
+		return -1;
+
+	case BUFERR_MEM:
+		giterr_set_oom();
+		return -1;
+
+	case BUFERR_ZLIB:
+		giterr_set(GITERR_ZLIB,
+			"Buffer error when writing out ZLib data");
+		return -1;
+
+	default:
+		return 0;
+	}
+}
+
+static int lock_file(git_filebuf *file, int flags, mode_t mode)
+{
+	if (git_path_exists(file->path_lock) == true) {
+		if (flags & GIT_FILEBUF_FORCE)
+			p_unlink(file->path_lock);
+		else {
+			giterr_clear(); /* actual OS error code just confuses */
+			giterr_set(GITERR_OS,
+				"Failed to lock file '%s' for writing", file->path_lock);
+			return GIT_ELOCKED;
+		}
+	}
+
+	/* create path to the file buffer is required */
+	if (flags & GIT_FILEBUF_FORCE) {
+		/* XXX: Should dirmode here be configurable? Or is 0777 always fine? */
+		file->fd = git_futils_creat_locked_withpath(file->path_lock, 0777, mode);
+	} else {
+		file->fd = git_futils_creat_locked(file->path_lock, mode);
+	}
+
+	if (file->fd < 0)
+		return file->fd;
+
+	file->fd_is_open = true;
+
+	if ((flags & GIT_FILEBUF_APPEND) && git_path_exists(file->path_original) == true) {
+		git_file source;
+		char buffer[FILEIO_BUFSIZE];
+		ssize_t read_bytes;
+
+		source = p_open(file->path_original, O_RDONLY);
+		if (source < 0) {
+			giterr_set(GITERR_OS,
+				"Failed to open file '%s' for reading",
+				file->path_original);
+			return -1;
+		}
+
+		while ((read_bytes = p_read(source, buffer, sizeof(buffer))) > 0) {
+			p_write(file->fd, buffer, read_bytes);
+			if (file->compute_digest)
+				git_hash_update(&file->digest, buffer, read_bytes);
+		}
+
+		p_close(source);
+
+		if (read_bytes < 0) {
+			giterr_set(GITERR_OS, "Failed to read file '%s'", file->path_original);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+void git_filebuf_cleanup(git_filebuf *file)
+{
+	if (file->fd_is_open && file->fd >= 0)
+		p_close(file->fd);
+
+	if (file->created_lock && !file->did_rename && file->path_lock && git_path_exists(file->path_lock))
+		p_unlink(file->path_lock);
+
+	if (file->compute_digest) {
+		git_hash_ctx_cleanup(&file->digest);
+		file->compute_digest = 0;
+	}
+
+	if (file->buffer)
+		git__free(file->buffer);
+
+	/* use the presence of z_buf to decide if we need to deflateEnd */
+	if (file->z_buf) {
+		git__free(file->z_buf);
+		deflateEnd(&file->zs);
+	}
+
+	if (file->path_original)
+		git__free(file->path_original);
+	if (file->path_lock)
+		git__free(file->path_lock);
+
+	memset(file, 0x0, sizeof(git_filebuf));
+	file->fd = -1;
+}
+
+GIT_INLINE(int) flush_buffer(git_filebuf *file)
+{
+	int result = file->write(file, file->buffer, file->buf_pos);
+	file->buf_pos = 0;
+	return result;
+}
+
+int git_filebuf_flush(git_filebuf *file)
+{
+	return flush_buffer(file);
+}
+
+static int write_normal(git_filebuf *file, void *source, size_t len)
+{
+	if (len > 0) {
+		if (p_write(file->fd, (void *)source, len) < 0) {
+			file->last_error = BUFERR_WRITE;
+			return -1;
+		}
+
+		if (file->compute_digest)
+			git_hash_update(&file->digest, source, len);
+	}
+
+	return 0;
+}
+
+static int write_deflate(git_filebuf *file, void *source, size_t len)
+{
+	z_stream *zs = &file->zs;
+
+	if (len > 0 || file->flush_mode == Z_FINISH) {
+		zs->next_in = source;
+		zs->avail_in = (uInt)len;
+
+		do {
+			size_t have;
+
+			zs->next_out = file->z_buf;
+			zs->avail_out = (uInt)file->buf_size;
+
+			if (deflate(zs, file->flush_mode) == Z_STREAM_ERROR) {
+				file->last_error = BUFERR_ZLIB;
+				return -1;
+			}
+
+			have = file->buf_size - (size_t)zs->avail_out;
+
+			if (p_write(file->fd, file->z_buf, have) < 0) {
+				file->last_error = BUFERR_WRITE;
+				return -1;
+			}
+
+		} while (zs->avail_out == 0);
+
+		assert(zs->avail_in == 0);
+
+		if (file->compute_digest)
+			git_hash_update(&file->digest, source, len);
+	}
+
+	return 0;
+}
+
+int git_filebuf_open(git_filebuf *file, const char *path, int flags, mode_t mode)
+{
+	int compression, error = -1;
+	size_t path_len, alloc_len;
+
+	/* opening an already open buffer is a programming error;
+	 * assert that this never happens instead of returning
+	 * an error code */
+	assert(file && path && file->buffer == NULL);
+
+	memset(file, 0x0, sizeof(git_filebuf));
+
+	if (flags & GIT_FILEBUF_DO_NOT_BUFFER)
+		file->do_not_buffer = true;
+
+	file->buf_size = WRITE_BUFFER_SIZE;
+	file->buf_pos = 0;
+	file->fd = -1;
+	file->last_error = BUFERR_OK;
+
+	/* Allocate the main cache buffer */
+	if (!file->do_not_buffer) {
+		file->buffer = git__malloc(file->buf_size);
+		GITERR_CHECK_ALLOC(file->buffer);
+	}
+
+	/* If we are hashing on-write, allocate a new hash context */
+	if (flags & GIT_FILEBUF_HASH_CONTENTS) {
+		file->compute_digest = 1;
+
+		if (git_hash_ctx_init(&file->digest) < 0)
+			goto cleanup;
+	}
+
+	compression = flags >> GIT_FILEBUF_DEFLATE_SHIFT;
+
+	/* If we are deflating on-write, */
+	if (compression != 0) {
+		/* Initialize the ZLib stream */
+		if (deflateInit(&file->zs, compression) != Z_OK) {
+			giterr_set(GITERR_ZLIB, "Failed to initialize zlib");
+			goto cleanup;
+		}
+
+		/* Allocate the Zlib cache buffer */
+		file->z_buf = git__malloc(file->buf_size);
+		GITERR_CHECK_ALLOC(file->z_buf);
+
+		/* Never flush */
+		file->flush_mode = Z_NO_FLUSH;
+		file->write = &write_deflate;
+	} else {
+		file->write = &write_normal;
+	}
+
+	/* If we are writing to a temp file */
+	if (flags & GIT_FILEBUF_TEMPORARY) {
+		git_buf tmp_path = GIT_BUF_INIT;
+
+		/* Open the file as temporary for locking */
+		file->fd = git_futils_mktmp(&tmp_path, path, mode);
+
+		if (file->fd < 0) {
+			git_buf_free(&tmp_path);
+			goto cleanup;
+		}
+		file->fd_is_open = true;
+		file->created_lock = true;
+
+		/* No original path */
+		file->path_original = NULL;
+		file->path_lock = git_buf_detach(&tmp_path);
+		GITERR_CHECK_ALLOC(file->path_lock);
+	} else {
+		path_len = strlen(path);
+
+		/* Save the original path of the file */
+		file->path_original = git__strdup(path);
+		GITERR_CHECK_ALLOC(file->path_original);
+
+		/* create the locking path by appending ".lock" to the original */
+		GITERR_CHECK_ALLOC_ADD(&alloc_len, path_len, GIT_FILELOCK_EXTLENGTH);
+		file->path_lock = git__malloc(alloc_len);
+		GITERR_CHECK_ALLOC(file->path_lock);
+
+		memcpy(file->path_lock, file->path_original, path_len);
+		memcpy(file->path_lock + path_len, GIT_FILELOCK_EXTENSION, GIT_FILELOCK_EXTLENGTH);
+
+		/* open the file for locking */
+		if ((error = lock_file(file, flags, mode)) < 0)
+			goto cleanup;
+
+		file->created_lock = true;
+	}
+
+	return 0;
+
+cleanup:
+	git_filebuf_cleanup(file);
+	return error;
+}
+
+int git_filebuf_hash(git_oid *oid, git_filebuf *file)
+{
+	assert(oid && file && file->compute_digest);
+
+	flush_buffer(file);
+
+	if (verify_last_error(file) < 0)
+		return -1;
+
+	git_hash_final(oid, &file->digest);
+	git_hash_ctx_cleanup(&file->digest);
+	file->compute_digest = 0;
+
+	return 0;
+}
+
+int git_filebuf_commit_at(git_filebuf *file, const char *path)
+{
+	git__free(file->path_original);
+	file->path_original = git__strdup(path);
+	GITERR_CHECK_ALLOC(file->path_original);
+
+	return git_filebuf_commit(file);
+}
+
+int git_filebuf_commit(git_filebuf *file)
+{
+	/* temporary files cannot be committed */
+	assert(file && file->path_original);
+
+	file->flush_mode = Z_FINISH;
+	flush_buffer(file);
+
+	if (verify_last_error(file) < 0)
+		goto on_error;
+
+	file->fd_is_open = false;
+
+	if (p_close(file->fd) < 0) {
+		giterr_set(GITERR_OS, "Failed to close file at '%s'", file->path_lock);
+		goto on_error;
+	}
+
+	file->fd = -1;
+
+	if (p_rename(file->path_lock, file->path_original) < 0) {
+		giterr_set(GITERR_OS, "Failed to rename lockfile to '%s'", file->path_original);
+		goto on_error;
+	}
+
+	file->did_rename = true;
+
+	git_filebuf_cleanup(file);
+	return 0;
+
+on_error:
+	git_filebuf_cleanup(file);
+	return -1;
+}
+
+GIT_INLINE(void) add_to_cache(git_filebuf *file, const void *buf, size_t len)
+{
+	memcpy(file->buffer + file->buf_pos, buf, len);
+	file->buf_pos += len;
+}
+
+int git_filebuf_write(git_filebuf *file, const void *buff, size_t len)
+{
+	const unsigned char *buf = buff;
+
+	ENSURE_BUF_OK(file);
+
+	if (file->do_not_buffer)
+		return file->write(file, (void *)buff, len);
+
+	for (;;) {
+		size_t space_left = file->buf_size - file->buf_pos;
+
+		/* cache if it's small */
+		if (space_left > len) {
+			add_to_cache(file, buf, len);
+			return 0;
+		}
+
+		add_to_cache(file, buf, space_left);
+		if (flush_buffer(file) < 0)
+			return -1;
+
+		len -= space_left;
+		buf += space_left;
+	}
+}
+
+int git_filebuf_reserve(git_filebuf *file, void **buffer, size_t len)
+{
+	size_t space_left = file->buf_size - file->buf_pos;
+
+	*buffer = NULL;
+
+	ENSURE_BUF_OK(file);
+
+	if (len > file->buf_size) {
+		file->last_error = BUFERR_MEM;
+		return -1;
+	}
+
+	if (space_left <= len) {
+		if (flush_buffer(file) < 0)
+			return -1;
+	}
+
+	*buffer = (file->buffer + file->buf_pos);
+	file->buf_pos += len;
+
+	return 0;
+}
+
+int git_filebuf_printf(git_filebuf *file, const char *format, ...)
+{
+	va_list arglist;
+	size_t space_left, len, alloclen;
+	int written, res;
+	char *tmp_buffer;
+
+	ENSURE_BUF_OK(file);
+
+	space_left = file->buf_size - file->buf_pos;
+
+	do {
+		va_start(arglist, format);
+		written = p_vsnprintf((char *)file->buffer + file->buf_pos, space_left, format, arglist);
+		va_end(arglist);
+
+		if (written < 0) {
+			file->last_error = BUFERR_MEM;
+			return -1;
+		}
+
+		len = written;
+		if (len + 1 <= space_left) {
+			file->buf_pos += len;
+			return 0;
+		}
+
+		if (flush_buffer(file) < 0)
+			return -1;
+
+		space_left = file->buf_size - file->buf_pos;
+
+	} while (len + 1 <= space_left);
+
+	if (GIT_ADD_SIZET_OVERFLOW(&alloclen, len, 1) ||
+		!(tmp_buffer = git__malloc(alloclen))) {
+		file->last_error = BUFERR_MEM;
+		return -1;
+	}
+
+	va_start(arglist, format);
+	written = p_vsnprintf(tmp_buffer, len + 1, format, arglist);
+	va_end(arglist);
+
+	if (written < 0) {
+		git__free(tmp_buffer);
+		file->last_error = BUFERR_MEM;
+		return -1;
+	}
+
+	res = git_filebuf_write(file, tmp_buffer, len);
+	git__free(tmp_buffer);
+
+	return res;
+}
+
+int git_filebuf_stats(time_t *mtime, size_t *size, git_filebuf *file)
+{
+	int res;
+	struct stat st;
+
+	if (file->fd_is_open)
+		res = p_fstat(file->fd, &st);
+	else
+		res = p_stat(file->path_original, &st);
+
+	if (res < 0) {
+		giterr_set(GITERR_OS, "Could not get stat info for '%s'",
+			file->path_original);
+		return res;
+	}
+
+	if (mtime)
+		*mtime = st.st_mtime;
+	if (size)
+		*size = (size_t)st.st_size;
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/filebuf.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/filebuf.h
new file mode 100755
index 0000000..f4d255b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/filebuf.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_filebuf_h__
+#define INCLUDE_filebuf_h__
+
+#include "fileops.h"
+#include "hash.h"
+#include <zlib.h>
+
+#ifdef GIT_THREADS
+#	define GIT_FILEBUF_THREADS
+#endif
+
+#define GIT_FILEBUF_HASH_CONTENTS		(1 << 0)
+#define GIT_FILEBUF_APPEND				(1 << 2)
+#define GIT_FILEBUF_FORCE				(1 << 3)
+#define GIT_FILEBUF_TEMPORARY			(1 << 4)
+#define GIT_FILEBUF_DO_NOT_BUFFER		(1 << 5)
+#define GIT_FILEBUF_DEFLATE_SHIFT		(6)
+
+#define GIT_FILELOCK_EXTENSION ".lock\0"
+#define GIT_FILELOCK_EXTLENGTH 6
+
+typedef struct git_filebuf git_filebuf;
+struct git_filebuf {
+	char *path_original;
+	char *path_lock;
+
+	int (*write)(git_filebuf *file, void *source, size_t len);
+
+	bool compute_digest;
+	git_hash_ctx digest;
+
+	unsigned char *buffer;
+	unsigned char *z_buf;
+
+	z_stream zs;
+	int flush_mode;
+
+	size_t buf_size, buf_pos;
+	git_file fd;
+	bool fd_is_open;
+	bool created_lock;
+	bool did_rename;
+	bool do_not_buffer;
+	int last_error;
+};
+
+#define GIT_FILEBUF_INIT {0}
+
+/*
+ * The git_filebuf object lifecycle is:
+ * - Allocate git_filebuf, preferably using GIT_FILEBUF_INIT.
+ *
+ * - Call git_filebuf_open() to initialize the filebuf for use.
+ *
+ * - Make as many calls to git_filebuf_write(), git_filebuf_printf(),
+ *   git_filebuf_reserve() as you like. The error codes for these
+ *   functions don't need to be checked. They are stored internally
+ *   by the file buffer.
+ *
+ * - While you are writing, you may call git_filebuf_hash() to get
+ *   the hash of all you have written so far. This function will
+ *   fail if any of the previous writes to the buffer failed.
+ *
+ * - To close the git_filebuf, you may call git_filebuf_commit() or
+ *   git_filebuf_commit_at() to save the file, or
+ *   git_filebuf_cleanup() to abandon the file.  All of these will
+ *   free the git_filebuf object. Likewise, all of these will fail
+ *   if any of the previous writes to the buffer failed, and set
+ *   an error code accordingly.
+ */
+int git_filebuf_write(git_filebuf *lock, const void *buff, size_t len);
+int git_filebuf_reserve(git_filebuf *file, void **buff, size_t len);
+int git_filebuf_printf(git_filebuf *file, const char *format, ...) GIT_FORMAT_PRINTF(2, 3);
+
+int git_filebuf_open(git_filebuf *lock, const char *path, int flags, mode_t mode);
+int git_filebuf_commit(git_filebuf *lock);
+int git_filebuf_commit_at(git_filebuf *lock, const char *path);
+void git_filebuf_cleanup(git_filebuf *lock);
+int git_filebuf_hash(git_oid *oid, git_filebuf *file);
+int git_filebuf_flush(git_filebuf *file);
+int git_filebuf_stats(time_t *mtime, size_t *size, git_filebuf *file);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fileops.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fileops.c
new file mode 100755
index 0000000..b7b5515
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fileops.c
@@ -0,0 +1,971 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "fileops.h"
+#include "global.h"
+#include "strmap.h"
+#include <ctype.h>
+#if GIT_WIN32
+#include "win32/findfile.h"
+#endif
+
+GIT__USE_STRMAP
+
+int git_futils_mkpath2file(const char *file_path, const mode_t mode)
+{
+	return git_futils_mkdir(
+		file_path, NULL, mode,
+		GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST | GIT_MKDIR_VERIFY_DIR);
+}
+
+int git_futils_mktmp(git_buf *path_out, const char *filename, mode_t mode)
+{
+	int fd;
+	mode_t mask;
+
+	p_umask(mask = p_umask(0));
+
+	git_buf_sets(path_out, filename);
+	git_buf_puts(path_out, "_git2_XXXXXX");
+
+	if (git_buf_oom(path_out))
+		return -1;
+
+	if ((fd = p_mkstemp(path_out->ptr)) < 0) {
+		giterr_set(GITERR_OS,
+			"Failed to create temporary file '%s'", path_out->ptr);
+		return -1;
+	}
+
+	if (p_chmod(path_out->ptr, (mode & ~mask))) {
+		giterr_set(GITERR_OS,
+			"Failed to set permissions on file '%s'", path_out->ptr);
+		return -1;
+	}
+
+	return fd;
+}
+
+int git_futils_creat_withpath(const char *path, const mode_t dirmode, const mode_t mode)
+{
+	int fd;
+
+	if (git_futils_mkpath2file(path, dirmode) < 0)
+		return -1;
+
+	fd = p_creat(path, mode);
+	if (fd < 0) {
+		giterr_set(GITERR_OS, "Failed to create file '%s'", path);
+		return -1;
+	}
+
+	return fd;
+}
+
+int git_futils_creat_locked(const char *path, const mode_t mode)
+{
+	int fd = p_open(path, O_WRONLY | O_CREAT | O_TRUNC |
+		O_EXCL | O_BINARY | O_CLOEXEC, mode);
+
+	if (fd < 0) {
+		giterr_set(GITERR_OS, "Failed to create locked file '%s'", path);
+		return errno == EEXIST ? GIT_ELOCKED : -1;
+	}
+
+	return fd;
+}
+
+int git_futils_creat_locked_withpath(const char *path, const mode_t dirmode, const mode_t mode)
+{
+	if (git_futils_mkpath2file(path, dirmode) < 0)
+		return -1;
+
+	return git_futils_creat_locked(path, mode);
+}
+
+int git_futils_open_ro(const char *path)
+{
+	int fd = p_open(path, O_RDONLY);
+	if (fd < 0)
+		return git_path_set_error(errno, path, "open");
+	return fd;
+}
+
+git_off_t git_futils_filesize(git_file fd)
+{
+	struct stat sb;
+
+	if (p_fstat(fd, &sb)) {
+		giterr_set(GITERR_OS, "Failed to stat file descriptor");
+		return -1;
+	}
+
+	return sb.st_size;
+}
+
+mode_t git_futils_canonical_mode(mode_t raw_mode)
+{
+	if (S_ISREG(raw_mode))
+		return S_IFREG | GIT_PERMS_CANONICAL(raw_mode);
+	else if (S_ISLNK(raw_mode))
+		return S_IFLNK;
+	else if (S_ISGITLINK(raw_mode))
+		return S_IFGITLINK;
+	else if (S_ISDIR(raw_mode))
+		return S_IFDIR;
+	else
+		return 0;
+}
+
+int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len)
+{
+	ssize_t read_size = 0;
+	size_t alloc_len;
+
+	git_buf_clear(buf);
+
+	if (!git__is_ssizet(len)) {
+		giterr_set(GITERR_INVALID, "Read too large.");
+		return -1;
+	}
+
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, len, 1);
+	if (git_buf_grow(buf, alloc_len) < 0)
+		return -1;
+
+	/* p_read loops internally to read len bytes */
+	read_size = p_read(fd, buf->ptr, len);
+
+	if (read_size != (ssize_t)len) {
+		giterr_set(GITERR_OS, "Failed to read descriptor");
+		git_buf_free(buf);
+		return -1;
+	}
+
+	buf->ptr[read_size] = '\0';
+	buf->size = read_size;
+
+	return 0;
+}
+
+int git_futils_readbuffer_updated(
+	git_buf *buf, const char *path, time_t *mtime, size_t *size, int *updated)
+{
+	git_file fd;
+	struct stat st;
+	bool changed = false;
+
+	assert(buf && path && *path);
+
+	if (updated != NULL)
+		*updated = 0;
+
+	if (p_stat(path, &st) < 0)
+		return git_path_set_error(errno, path, "stat");
+
+
+	if (S_ISDIR(st.st_mode)) {
+		giterr_set(GITERR_INVALID, "requested file is a directory");
+		return GIT_ENOTFOUND;
+	}
+
+	if (!git__is_sizet(st.st_size+1)) {
+		giterr_set(GITERR_OS, "Invalid regular file stat for '%s'", path);
+		return -1;
+	}
+
+	/*
+	 * If we were given a time and/or a size, we only want to read the file
+	 * if it has been modified.
+	 */
+	if (size && *size != (size_t)st.st_size)
+		changed = true;
+	if (mtime && *mtime != (time_t)st.st_mtime)
+		changed = true;
+	if (!size && !mtime)
+		changed = true;
+
+	if (!changed) {
+		return 0;
+	}
+
+	if (mtime != NULL)
+		*mtime = st.st_mtime;
+	if (size != NULL)
+		*size = (size_t)st.st_size;
+
+	if ((fd = git_futils_open_ro(path)) < 0)
+		return fd;
+
+	if (git_futils_readbuffer_fd(buf, fd, (size_t)st.st_size) < 0) {
+		p_close(fd);
+		return -1;
+	}
+
+	p_close(fd);
+
+	if (updated != NULL)
+		*updated = 1;
+
+	return 0;
+}
+
+int git_futils_readbuffer(git_buf *buf, const char *path)
+{
+	return git_futils_readbuffer_updated(buf, path, NULL, NULL, NULL);
+}
+
+int git_futils_writebuffer(
+	const git_buf *buf,	const char *path, int flags, mode_t mode)
+{
+	int fd, error = 0;
+
+	if (flags <= 0)
+		flags = O_CREAT | O_TRUNC | O_WRONLY;
+	if (!mode)
+		mode = GIT_FILEMODE_BLOB;
+
+	if ((fd = p_open(path, flags, mode)) < 0) {
+		giterr_set(GITERR_OS, "Could not open '%s' for writing", path);
+		return fd;
+	}
+
+	if ((error = p_write(fd, git_buf_cstr(buf), git_buf_len(buf))) < 0) {
+		giterr_set(GITERR_OS, "Could not write to '%s'", path);
+		(void)p_close(fd);
+		return error;
+	}
+
+	if ((error = p_close(fd)) < 0)
+		giterr_set(GITERR_OS, "Error while closing '%s'", path);
+
+	return error;
+}
+
+int git_futils_mv_withpath(const char *from, const char *to, const mode_t dirmode)
+{
+	if (git_futils_mkpath2file(to, dirmode) < 0)
+		return -1;
+
+	if (p_rename(from, to) < 0) {
+		giterr_set(GITERR_OS, "Failed to rename '%s' to '%s'", from, to);
+		return -1;
+	}
+
+	return 0;
+}
+
+int git_futils_mmap_ro(git_map *out, git_file fd, git_off_t begin, size_t len)
+{
+	return p_mmap(out, len, GIT_PROT_READ, GIT_MAP_SHARED, fd, begin);
+}
+
+int git_futils_mmap_ro_file(git_map *out, const char *path)
+{
+	git_file fd = git_futils_open_ro(path);
+	git_off_t len;
+	int result;
+
+	if (fd < 0)
+		return fd;
+
+	len = git_futils_filesize(fd);
+	if (!git__is_sizet(len)) {
+		giterr_set(GITERR_OS, "File `%s` too large to mmap", path);
+		return -1;
+	}
+
+	result = git_futils_mmap_ro(out, fd, 0, (size_t)len);
+	p_close(fd);
+	return result;
+}
+
+void git_futils_mmap_free(git_map *out)
+{
+	p_munmap(out);
+}
+
+GIT_INLINE(int) validate_existing(
+	const char *make_path,
+	struct stat *st,
+	mode_t mode,
+	uint32_t flags,
+	struct git_futils_mkdir_perfdata *perfdata)
+{
+	if ((S_ISREG(st->st_mode) && (flags & GIT_MKDIR_REMOVE_FILES)) ||
+		(S_ISLNK(st->st_mode) && (flags & GIT_MKDIR_REMOVE_SYMLINKS))) {
+		if (p_unlink(make_path) < 0) {
+			giterr_set(GITERR_OS, "Failed to remove %s '%s'",
+				S_ISLNK(st->st_mode) ? "symlink" : "file", make_path);
+			return GIT_EEXISTS;
+		}
+
+		perfdata->mkdir_calls++;
+
+		if (p_mkdir(make_path, mode) < 0) {
+			giterr_set(GITERR_OS, "Failed to make directory '%s'", make_path);
+			return GIT_EEXISTS;
+		}
+	}
+
+	else if (S_ISLNK(st->st_mode)) {
+		/* Re-stat the target, make sure it's a directory */
+		perfdata->stat_calls++;
+
+		if (p_stat(make_path, st) < 0) {
+			giterr_set(GITERR_OS, "Failed to make directory '%s'", make_path);
+			return GIT_EEXISTS;
+		}
+	}
+
+	else if (!S_ISDIR(st->st_mode)) {
+		giterr_set(GITERR_FILESYSTEM,
+			"Failed to make directory '%s': directory exists", make_path);
+		return GIT_EEXISTS;
+	}
+
+	return 0;
+}
+
+int git_futils_mkdir_ext(
+	const char *path,
+	const char *base,
+	mode_t mode,
+	uint32_t flags,
+	struct git_futils_mkdir_options *opts)
+{
+	int error = -1;
+	git_buf make_path = GIT_BUF_INIT;
+	ssize_t root = 0, min_root_len, root_len;
+	char lastch = '/', *tail;
+	struct stat st;
+
+	/* build path and find "root" where we should start calling mkdir */
+	if (git_path_join_unrooted(&make_path, path, base, &root) < 0)
+		return -1;
+
+	if (make_path.size == 0) {
+		giterr_set(GITERR_OS, "Attempt to create empty path");
+		goto done;
+	}
+
+	/* Trim trailing slashes (except the root) */
+	if ((root_len = git_path_root(make_path.ptr)) < 0)
+		root_len = 0;
+	else
+		root_len++;
+
+	while (make_path.size > (size_t)root_len &&
+		make_path.ptr[make_path.size - 1] == '/')
+		make_path.ptr[--make_path.size] = '\0';
+
+	/* if we are not supposed to made the last element, truncate it */
+	if ((flags & GIT_MKDIR_SKIP_LAST2) != 0) {
+		git_path_dirname_r(&make_path, make_path.ptr);
+		flags |= GIT_MKDIR_SKIP_LAST;
+	}
+	if ((flags & GIT_MKDIR_SKIP_LAST) != 0) {
+		git_path_dirname_r(&make_path, make_path.ptr);
+	}
+
+	/* We were either given the root path (or trimmed it to
+	 * the root), we don't have anything to do.
+	 */
+	if (make_path.size <= (size_t)root_len) {
+		error = 0;
+		goto done;
+	}
+
+	/* if we are not supposed to make the whole path, reset root */
+	if ((flags & GIT_MKDIR_PATH) == 0)
+		root = git_buf_rfind(&make_path, '/');
+
+	/* advance root past drive name or network mount prefix */
+	min_root_len = git_path_root(make_path.ptr);
+	if (root < min_root_len)
+		root = min_root_len;
+	while (root >= 0 && make_path.ptr[root] == '/')
+		++root;
+
+	/* clip root to make_path length */
+	if (root > (ssize_t)make_path.size)
+		root = (ssize_t)make_path.size; /* i.e. NUL byte of string */
+	if (root < 0)
+		root = 0;
+
+	/* walk down tail of path making each directory */
+	for (tail = &make_path.ptr[root]; *tail; *tail = lastch) {
+		bool mkdir_attempted = false;
+
+		/* advance tail to include next path component */
+		while (*tail == '/')
+			tail++;
+		while (*tail && *tail != '/')
+			tail++;
+
+		/* truncate path at next component */
+		lastch = *tail;
+		*tail = '\0';
+		st.st_mode = 0;
+
+		if (opts->dir_map && git_strmap_exists(opts->dir_map, make_path.ptr))
+			continue;
+
+		/* See what's going on with this path component */
+		opts->perfdata.stat_calls++;
+
+retry_lstat:
+		if (p_lstat(make_path.ptr, &st) < 0) {
+			if (mkdir_attempted || errno != ENOENT) {
+				giterr_set(GITERR_OS, "Cannot access component in path '%s'", make_path.ptr);
+				error = -1;
+				goto done;
+			}
+
+			giterr_clear();
+			opts->perfdata.mkdir_calls++;
+			mkdir_attempted = true;
+			if (p_mkdir(make_path.ptr, mode) < 0) {
+				if (errno == EEXIST)
+					goto retry_lstat;
+				giterr_set(GITERR_OS, "Failed to make directory '%s'", make_path.ptr);
+				error = -1;
+				goto done;
+			}
+		} else {
+			/* with exclusive create, existing dir is an error */
+			if ((flags & GIT_MKDIR_EXCL) != 0) {
+				giterr_set(GITERR_FILESYSTEM, "Failed to make directory '%s': directory exists", make_path.ptr);
+				error = GIT_EEXISTS;
+				goto done;
+			}
+
+			if ((error = validate_existing(
+				make_path.ptr, &st, mode, flags, &opts->perfdata)) < 0)
+					goto done;
+		}
+
+		/* chmod if requested and necessary */
+		if (((flags & GIT_MKDIR_CHMOD_PATH) != 0 ||
+			 (lastch == '\0' && (flags & GIT_MKDIR_CHMOD) != 0)) &&
+			st.st_mode != mode) {
+
+			opts->perfdata.chmod_calls++;
+
+			if ((error = p_chmod(make_path.ptr, mode)) < 0 &&
+				lastch == '\0') {
+				giterr_set(GITERR_OS, "Failed to set permissions on '%s'",
+					make_path.ptr);
+				goto done;
+			}
+		}
+
+		if (opts->dir_map && opts->pool) {
+			char *cache_path;
+			size_t alloc_size;
+
+			GITERR_CHECK_ALLOC_ADD(&alloc_size, make_path.size, 1);
+			if (!git__is_uint32(alloc_size))
+				return -1;
+			cache_path = git_pool_malloc(opts->pool, (uint32_t)alloc_size);
+			GITERR_CHECK_ALLOC(cache_path);
+
+			memcpy(cache_path, make_path.ptr, make_path.size + 1);
+
+			git_strmap_insert(opts->dir_map, cache_path, cache_path, error);
+			if (error < 0)
+				goto done;
+		}
+	}
+
+	error = 0;
+
+	/* check that full path really is a directory if requested & needed */
+	if ((flags & GIT_MKDIR_VERIFY_DIR) != 0 &&
+		lastch != '\0') {
+		opts->perfdata.stat_calls++;
+
+		if (p_stat(make_path.ptr, &st) < 0 || !S_ISDIR(st.st_mode)) {
+			giterr_set(GITERR_OS, "Path is not a directory '%s'",
+				make_path.ptr);
+			error = GIT_ENOTFOUND;
+		}
+	}
+
+done:
+	git_buf_free(&make_path);
+	return error;
+}
+
+int git_futils_mkdir(
+	const char *path,
+	const char *base,
+	mode_t mode,
+	uint32_t flags)
+{
+	struct git_futils_mkdir_options options = {0};
+	return git_futils_mkdir_ext(path, base, mode, flags, &options);
+}
+
+int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode)
+{
+	return git_futils_mkdir(path, base, mode, GIT_MKDIR_PATH);
+}
+
+typedef struct {
+	const char *base;
+	size_t baselen;
+	uint32_t flags;
+	int depth;
+} futils__rmdir_data;
+
+#define FUTILS_MAX_DEPTH 100
+
+static int futils__error_cannot_rmdir(const char *path, const char *filemsg)
+{
+	if (filemsg)
+		giterr_set(GITERR_OS, "Could not remove directory. File '%s' %s",
+				   path, filemsg);
+	else
+		giterr_set(GITERR_OS, "Could not remove directory '%s'", path);
+
+	return -1;
+}
+
+static int futils__rm_first_parent(git_buf *path, const char *ceiling)
+{
+	int error = GIT_ENOTFOUND;
+	struct stat st;
+
+	while (error == GIT_ENOTFOUND) {
+		git_buf_rtruncate_at_char(path, '/');
+
+		if (!path->size || git__prefixcmp(path->ptr, ceiling) != 0)
+			error = 0;
+		else if (p_lstat_posixly(path->ptr, &st) == 0) {
+			if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))
+				error = p_unlink(path->ptr);
+			else if (!S_ISDIR(st.st_mode))
+				error = -1; /* fail to remove non-regular file */
+		} else if (errno != ENOTDIR)
+			error = -1;
+	}
+
+	if (error)
+		futils__error_cannot_rmdir(path->ptr, "cannot remove parent");
+
+	return error;
+}
+
+static int futils__rmdir_recurs_foreach(void *opaque, git_buf *path)
+{
+	int error = 0;
+	futils__rmdir_data *data = opaque;
+	struct stat st;
+
+	if (data->depth > FUTILS_MAX_DEPTH)
+		error = futils__error_cannot_rmdir(
+			path->ptr, "directory nesting too deep");
+
+	else if ((error = p_lstat_posixly(path->ptr, &st)) < 0) {
+		if (errno == ENOENT)
+			error = 0;
+		else if (errno == ENOTDIR) {
+			/* asked to remove a/b/c/d/e and a/b is a normal file */
+			if ((data->flags & GIT_RMDIR_REMOVE_BLOCKERS) != 0)
+				error = futils__rm_first_parent(path, data->base);
+			else
+				futils__error_cannot_rmdir(
+					path->ptr, "parent is not directory");
+		}
+		else
+			error = git_path_set_error(errno, path->ptr, "rmdir");
+	}
+
+	else if (S_ISDIR(st.st_mode)) {
+		data->depth++;
+
+		error = git_path_direach(path, 0, futils__rmdir_recurs_foreach, data);
+
+		data->depth--;
+
+		if (error < 0)
+			return error;
+
+		if (data->depth == 0 && (data->flags & GIT_RMDIR_SKIP_ROOT) != 0)
+			return error;
+
+		if ((error = p_rmdir(path->ptr)) < 0) {
+			if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) != 0 &&
+				(errno == ENOTEMPTY || errno == EEXIST || errno == EBUSY))
+				error = 0;
+			else
+				error = git_path_set_error(errno, path->ptr, "rmdir");
+		}
+	}
+
+	else if ((data->flags & GIT_RMDIR_REMOVE_FILES) != 0) {
+		if (p_unlink(path->ptr) < 0)
+			error = git_path_set_error(errno, path->ptr, "remove");
+	}
+
+	else if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) == 0)
+		error = futils__error_cannot_rmdir(path->ptr, "still present");
+
+	return error;
+}
+
+static int futils__rmdir_empty_parent(void *opaque, const char *path)
+{
+	futils__rmdir_data *data = opaque;
+	int error = 0;
+
+	if (strlen(path) <= data->baselen)
+		error = GIT_ITEROVER;
+
+	else if (p_rmdir(path) < 0) {
+		int en = errno;
+
+		if (en == ENOENT || en == ENOTDIR) {
+			/* do nothing */
+		} else if (en == ENOTEMPTY || en == EEXIST || en == EBUSY) {
+			error = GIT_ITEROVER;
+		} else {
+			error = git_path_set_error(errno, path, "rmdir");
+		}
+	}
+
+	return error;
+}
+
+int git_futils_rmdir_r(
+	const char *path, const char *base, uint32_t flags)
+{
+	int error;
+	git_buf fullpath = GIT_BUF_INIT;
+	futils__rmdir_data data;
+
+	/* build path and find "root" where we should start calling mkdir */
+	if (git_path_join_unrooted(&fullpath, path, base, NULL) < 0)
+		return -1;
+
+	memset(&data, 0, sizeof(data));
+	data.base    = base ? base : "";
+	data.baselen = base ? strlen(base) : 0;
+	data.flags   = flags;
+
+	error = futils__rmdir_recurs_foreach(&data, &fullpath);
+
+	/* remove now-empty parents if requested */
+	if (!error && (flags & GIT_RMDIR_EMPTY_PARENTS) != 0)
+		error = git_path_walk_up(
+			&fullpath, base, futils__rmdir_empty_parent, &data);
+
+	if (error == GIT_ITEROVER) {
+		giterr_clear();
+		error = 0;
+	}
+
+	git_buf_free(&fullpath);
+
+	return error;
+}
+
+int git_futils_fake_symlink(const char *old, const char *new)
+{
+	int retcode = GIT_ERROR;
+	int fd = git_futils_creat_withpath(new, 0755, 0644);
+	if (fd >= 0) {
+		retcode = p_write(fd, old, strlen(old));
+		p_close(fd);
+	}
+	return retcode;
+}
+
+static int cp_by_fd(int ifd, int ofd, bool close_fd_when_done)
+{
+	int error = 0;
+	char buffer[FILEIO_BUFSIZE];
+	ssize_t len = 0;
+
+	while (!error && (len = p_read(ifd, buffer, sizeof(buffer))) > 0)
+		/* p_write() does not have the same semantics as write().  It loops
+		 * internally and will return 0 when it has completed writing.
+		 */
+		error = p_write(ofd, buffer, len);
+
+	if (len < 0) {
+		giterr_set(GITERR_OS, "Read error while copying file");
+		error = (int)len;
+	}
+
+	if (error < 0)
+		giterr_set(GITERR_OS, "write error while copying file");
+
+	if (close_fd_when_done) {
+		p_close(ifd);
+		p_close(ofd);
+	}
+
+	return error;
+}
+
+int git_futils_cp(const char *from, const char *to, mode_t filemode)
+{
+	int ifd, ofd;
+
+	if ((ifd = git_futils_open_ro(from)) < 0)
+		return ifd;
+
+	if ((ofd = p_open(to, O_WRONLY | O_CREAT | O_EXCL, filemode)) < 0) {
+		p_close(ifd);
+		return git_path_set_error(errno, to, "open for writing");
+	}
+
+	return cp_by_fd(ifd, ofd, true);
+}
+
+static int cp_link(const char *from, const char *to, size_t link_size)
+{
+	int error = 0;
+	ssize_t read_len;
+	char *link_data;
+	size_t alloc_size;
+
+	GITERR_CHECK_ALLOC_ADD(&alloc_size, link_size, 1);
+	link_data = git__malloc(alloc_size);
+	GITERR_CHECK_ALLOC(link_data);
+
+	read_len = p_readlink(from, link_data, link_size);
+	if (read_len != (ssize_t)link_size) {
+		giterr_set(GITERR_OS, "Failed to read symlink data for '%s'", from);
+		error = -1;
+	}
+	else {
+		link_data[read_len] = '\0';
+
+		if (p_symlink(link_data, to) < 0) {
+			giterr_set(GITERR_OS, "Could not symlink '%s' as '%s'",
+				link_data, to);
+			error = -1;
+		}
+	}
+
+	git__free(link_data);
+	return error;
+}
+
+typedef struct {
+	const char *to_root;
+	git_buf to;
+	ssize_t from_prefix;
+	uint32_t flags;
+	uint32_t mkdir_flags;
+	mode_t dirmode;
+} cp_r_info;
+
+#define GIT_CPDIR__MKDIR_DONE_FOR_TO_ROOT (1u << 10)
+
+static int _cp_r_mkdir(cp_r_info *info, git_buf *from)
+{
+	int error = 0;
+
+	/* create root directory the first time we need to create a directory */
+	if ((info->flags & GIT_CPDIR__MKDIR_DONE_FOR_TO_ROOT) == 0) {
+		error = git_futils_mkdir(
+			info->to_root, NULL, info->dirmode,
+			(info->flags & GIT_CPDIR_CHMOD_DIRS) ? GIT_MKDIR_CHMOD : 0);
+
+		info->flags |= GIT_CPDIR__MKDIR_DONE_FOR_TO_ROOT;
+	}
+
+	/* create directory with root as base to prevent excess chmods */
+	if (!error)
+		error = git_futils_mkdir(
+			from->ptr + info->from_prefix, info->to_root,
+			info->dirmode, info->mkdir_flags);
+
+	return error;
+}
+
+static int _cp_r_callback(void *ref, git_buf *from)
+{
+	int error = 0;
+	cp_r_info *info = ref;
+	struct stat from_st, to_st;
+	bool exists = false;
+
+	if ((info->flags & GIT_CPDIR_COPY_DOTFILES) == 0 &&
+		from->ptr[git_path_basename_offset(from)] == '.')
+		return 0;
+
+	if ((error = git_buf_joinpath(
+			&info->to, info->to_root, from->ptr + info->from_prefix)) < 0)
+		return error;
+
+	if (!(error = git_path_lstat(info->to.ptr, &to_st)))
+		exists = true;
+	else if (error != GIT_ENOTFOUND)
+		return error;
+	else {
+		giterr_clear();
+		error = 0;
+	}
+
+	if ((error = git_path_lstat(from->ptr, &from_st)) < 0)
+		return error;
+
+	if (S_ISDIR(from_st.st_mode)) {
+		mode_t oldmode = info->dirmode;
+
+		/* if we are not chmod'ing, then overwrite dirmode */
+		if ((info->flags & GIT_CPDIR_CHMOD_DIRS) == 0)
+			info->dirmode = from_st.st_mode;
+
+		/* make directory now if CREATE_EMPTY_DIRS is requested and needed */
+		if (!exists && (info->flags & GIT_CPDIR_CREATE_EMPTY_DIRS) != 0)
+			error = _cp_r_mkdir(info, from);
+
+		/* recurse onto target directory */
+		if (!error && (!exists || S_ISDIR(to_st.st_mode)))
+			error = git_path_direach(from, 0, _cp_r_callback, info);
+
+		if (oldmode != 0)
+			info->dirmode = oldmode;
+
+		return error;
+	}
+
+	if (exists) {
+		if ((info->flags & GIT_CPDIR_OVERWRITE) == 0)
+			return 0;
+
+		if (p_unlink(info->to.ptr) < 0) {
+			giterr_set(GITERR_OS, "Cannot overwrite existing file '%s'",
+				info->to.ptr);
+			return GIT_EEXISTS;
+		}
+	}
+
+	/* Done if this isn't a regular file or a symlink */
+	if (!S_ISREG(from_st.st_mode) &&
+		(!S_ISLNK(from_st.st_mode) ||
+		 (info->flags & GIT_CPDIR_COPY_SYMLINKS) == 0))
+		return 0;
+
+	/* Make container directory on demand if needed */
+	if ((info->flags & GIT_CPDIR_CREATE_EMPTY_DIRS) == 0 &&
+		(error = _cp_r_mkdir(info, from)) < 0)
+		return error;
+
+	/* make symlink or regular file */
+	if (info->flags & GIT_CPDIR_LINK_FILES) {
+		if ((error = p_link(from->ptr, info->to.ptr)) < 0)
+			giterr_set(GITERR_OS, "failed to link '%s'", from->ptr);
+	} else if (S_ISLNK(from_st.st_mode)) {
+		error = cp_link(from->ptr, info->to.ptr, (size_t)from_st.st_size);
+	} else {
+		mode_t usemode = from_st.st_mode;
+
+		if ((info->flags & GIT_CPDIR_SIMPLE_TO_MODE) != 0)
+			usemode = GIT_PERMS_FOR_WRITE(usemode);
+
+		error = git_futils_cp(from->ptr, info->to.ptr, usemode);
+	}
+
+	return error;
+}
+
+int git_futils_cp_r(
+	const char *from,
+	const char *to,
+	uint32_t flags,
+	mode_t dirmode)
+{
+	int error;
+	git_buf path = GIT_BUF_INIT;
+	cp_r_info info;
+
+	if (git_buf_joinpath(&path, from, "") < 0) /* ensure trailing slash */
+		return -1;
+
+	memset(&info, 0, sizeof(info));
+	info.to_root = to;
+	info.flags   = flags;
+	info.dirmode = dirmode;
+	info.from_prefix = path.size;
+	git_buf_init(&info.to, 0);
+
+	/* precalculate mkdir flags */
+	if ((flags & GIT_CPDIR_CREATE_EMPTY_DIRS) == 0) {
+		/* if not creating empty dirs, then use mkdir to create the path on
+		 * demand right before files are copied.
+		 */
+		info.mkdir_flags = GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST;
+		if ((flags & GIT_CPDIR_CHMOD_DIRS) != 0)
+			info.mkdir_flags |= GIT_MKDIR_CHMOD_PATH;
+	} else {
+		/* otherwise, we will do simple mkdir as directories are encountered */
+		info.mkdir_flags =
+			((flags & GIT_CPDIR_CHMOD_DIRS) != 0) ? GIT_MKDIR_CHMOD : 0;
+	}
+
+	error = _cp_r_callback(&info, &path);
+
+	git_buf_free(&path);
+	git_buf_free(&info.to);
+
+	return error;
+}
+
+int git_futils_filestamp_check(
+	git_futils_filestamp *stamp, const char *path)
+{
+	struct stat st;
+
+	/* if the stamp is NULL, then always reload */
+	if (stamp == NULL)
+		return 1;
+
+	if (p_stat(path, &st) < 0)
+		return GIT_ENOTFOUND;
+
+	if (stamp->mtime == (git_time_t)st.st_mtime &&
+		stamp->size  == (git_off_t)st.st_size   &&
+		stamp->ino   == (unsigned int)st.st_ino)
+		return 0;
+
+	stamp->mtime = (git_time_t)st.st_mtime;
+	stamp->size  = (git_off_t)st.st_size;
+	stamp->ino   = (unsigned int)st.st_ino;
+
+	return 1;
+}
+
+void git_futils_filestamp_set(
+	git_futils_filestamp *target, const git_futils_filestamp *source)
+{
+	assert(target);
+
+	if (source)
+		memcpy(target, source, sizeof(*target));
+	else
+		memset(target, 0, sizeof(*target));
+}
+
+
+void git_futils_filestamp_set_from_stat(
+	git_futils_filestamp *stamp, struct stat *st)
+{
+	if (st) {
+		stamp->mtime = (git_time_t)st->st_mtime;
+		stamp->size  = (git_off_t)st->st_size;
+		stamp->ino   = (unsigned int)st->st_ino;
+	} else {
+		memset(stamp, 0, sizeof(*stamp));
+	}
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fileops.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fileops.h
new file mode 100755
index 0000000..0f6466c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fileops.h
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_fileops_h__
+#define INCLUDE_fileops_h__
+
+#include "common.h"
+#include "map.h"
+#include "posix.h"
+#include "path.h"
+#include "pool.h"
+#include "strmap.h"
+
+/**
+ * Filebuffer methods
+ *
+ * Read whole files into an in-memory buffer for processing
+ */
+extern int git_futils_readbuffer(git_buf *obj, const char *path);
+extern int git_futils_readbuffer_updated(
+	git_buf *obj, const char *path, time_t *mtime, size_t *size, int *updated);
+extern int git_futils_readbuffer_fd(git_buf *obj, git_file fd, size_t len);
+
+extern int git_futils_writebuffer(
+	const git_buf *buf, const char *path, int open_flags, mode_t mode);
+
+/**
+ * File utils
+ *
+ * These are custom filesystem-related helper methods. They are
+ * rather high level, and wrap the underlying POSIX methods
+ *
+ * All these methods return 0 on success,
+ * or an error code on failure and an error message is set.
+ */
+
+/**
+ * Create and open a file, while also
+ * creating all the folders in its path
+ */
+extern int git_futils_creat_withpath(const char *path, const mode_t dirmode, const mode_t mode);
+
+/**
+ * Create an open a process-locked file
+ */
+extern int git_futils_creat_locked(const char *path, const mode_t mode);
+
+/**
+ * Create an open a process-locked file, while
+ * also creating all the folders in its path
+ */
+extern int git_futils_creat_locked_withpath(const char *path, const mode_t dirmode, const mode_t mode);
+
+/**
+ * Create a path recursively
+ *
+ * If a base parameter is being passed, it's expected to be valued with a
+ * path pointing to an already existing directory.
+ */
+extern int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode);
+
+/**
+ * Flags to pass to `git_futils_mkdir`.
+ *
+ * * GIT_MKDIR_EXCL is "exclusive" - i.e. generate an error if dir exists.
+ * * GIT_MKDIR_PATH says to make all components in the path.
+ * * GIT_MKDIR_CHMOD says to chmod the final directory entry after creation
+ * * GIT_MKDIR_CHMOD_PATH says to chmod each directory component in the path
+ * * GIT_MKDIR_SKIP_LAST says to leave off the last element of the path
+ * * GIT_MKDIR_SKIP_LAST2 says to leave off the last 2 elements of the path
+ * * GIT_MKDIR_VERIFY_DIR says confirm final item is a dir, not just EEXIST
+ * * GIT_MKDIR_REMOVE_FILES says to remove files and recreate dirs
+ * * GIT_MKDIR_REMOVE_SYMLINKS says to remove symlinks and recreate dirs
+ *
+ * Note that the chmod options will be executed even if the directory already
+ * exists, unless GIT_MKDIR_EXCL is given.
+ */
+typedef enum {
+	GIT_MKDIR_EXCL = 1,
+	GIT_MKDIR_PATH = 2,
+	GIT_MKDIR_CHMOD = 4,
+	GIT_MKDIR_CHMOD_PATH = 8,
+	GIT_MKDIR_SKIP_LAST = 16,
+	GIT_MKDIR_SKIP_LAST2 = 32,
+	GIT_MKDIR_VERIFY_DIR = 64,
+	GIT_MKDIR_REMOVE_FILES = 128,
+	GIT_MKDIR_REMOVE_SYMLINKS = 256,
+} git_futils_mkdir_flags;
+
+struct git_futils_mkdir_perfdata
+{
+	size_t stat_calls;
+	size_t mkdir_calls;
+	size_t chmod_calls;
+};
+
+struct git_futils_mkdir_options
+{
+	git_strmap *dir_map;
+	git_pool *pool;
+	struct git_futils_mkdir_perfdata perfdata;
+};
+
+/**
+ * Create a directory or entire path.
+ *
+ * This makes a directory (and the entire path leading up to it if requested),
+ * and optionally chmods the directory immediately after (or each part of the
+ * path if requested).
+ *
+ * @param path The path to create.
+ * @param base Root for relative path.  These directories will never be made.
+ * @param mode The mode to use for created directories.
+ * @param flags Combination of the mkdir flags above.
+ * @param opts Extended options, use `git_futils_mkdir` if you are not interested.
+ * @return 0 on success, else error code
+ */
+extern int git_futils_mkdir_ext(const char *path, const char *base, mode_t mode, uint32_t flags, struct git_futils_mkdir_options *opts);
+
+/**
+ * Create a directory or entire path.  Similar to `git_futils_mkdir_withperf`
+ * without performance data.
+ */
+extern int git_futils_mkdir(const char *path, const char *base, mode_t mode, uint32_t flags);
+
+/**
+ * Create all the folders required to contain
+ * the full path of a file
+ */
+extern int git_futils_mkpath2file(const char *path, const mode_t mode);
+
+/**
+ * Flags to pass to `git_futils_rmdir_r`.
+ *
+ * * GIT_RMDIR_EMPTY_HIERARCHY - the default; remove hierarchy of empty
+ *       dirs and generate error if any files are found.
+ * * GIT_RMDIR_REMOVE_FILES    - attempt to remove files in the hierarchy.
+ * * GIT_RMDIR_SKIP_NONEMPTY   - skip non-empty directories with no error.
+ * * GIT_RMDIR_EMPTY_PARENTS   - remove containing directories up to base
+ *       if removing this item leaves them empty
+ * * GIT_RMDIR_REMOVE_BLOCKERS - remove blocking file that causes ENOTDIR
+ * * GIT_RMDIR_SKIP_ROOT       - don't remove root directory itself
+ */
+typedef enum {
+	GIT_RMDIR_EMPTY_HIERARCHY = 0,
+	GIT_RMDIR_REMOVE_FILES    = (1 << 0),
+	GIT_RMDIR_SKIP_NONEMPTY   = (1 << 1),
+	GIT_RMDIR_EMPTY_PARENTS   = (1 << 2),
+	GIT_RMDIR_REMOVE_BLOCKERS = (1 << 3),
+	GIT_RMDIR_SKIP_ROOT       = (1 << 4),
+} git_futils_rmdir_flags;
+
+/**
+ * Remove path and any files and directories beneath it.
+ *
+ * @param path Path to the top level directory to process.
+ * @param base Root for relative path.
+ * @param flags Combination of git_futils_rmdir_flags values
+ * @return 0 on success; -1 on error.
+ */
+extern int git_futils_rmdir_r(const char *path, const char *base, uint32_t flags);
+
+/**
+ * Create and open a temporary file with a `_git2_` suffix.
+ * Writes the filename into path_out.
+ * @return On success, an open file descriptor, else an error code < 0.
+ */
+extern int git_futils_mktmp(git_buf *path_out, const char *filename, mode_t mode);
+
+/**
+ * Move a file on the filesystem, create the
+ * destination path if it doesn't exist
+ */
+extern int git_futils_mv_withpath(const char *from, const char *to, const mode_t dirmode);
+
+/**
+ * Copy a file
+ *
+ * The filemode will be used for the newly created file.
+ */
+extern int git_futils_cp(
+	const char *from,
+	const char *to,
+	mode_t filemode);
+
+/**
+ * Flags that can be passed to `git_futils_cp_r`.
+ *
+ * - GIT_CPDIR_CREATE_EMPTY_DIRS: create directories even if there are no
+ *   files under them (otherwise directories will only be created lazily
+ *   when a file inside them is copied).
+ * - GIT_CPDIR_COPY_SYMLINKS: copy symlinks, otherwise they are ignored.
+ * - GIT_CPDIR_COPY_DOTFILES: copy files with leading '.', otherwise ignored.
+ * - GIT_CPDIR_OVERWRITE: overwrite pre-existing files with source content,
+ *   otherwise they are silently skipped.
+ * - GIT_CPDIR_CHMOD_DIRS: explicitly chmod directories to `dirmode`
+ * - GIT_CPDIR_SIMPLE_TO_MODE: default tries to replicate the mode of the
+ *   source file to the target; with this flag, always use 0666 (or 0777 if
+ *   source has exec bits set) for target.
+ * - GIT_CPDIR_LINK_FILES will try to use hardlinks for the files
+ */
+typedef enum {
+	GIT_CPDIR_CREATE_EMPTY_DIRS = (1u << 0),
+	GIT_CPDIR_COPY_SYMLINKS     = (1u << 1),
+	GIT_CPDIR_COPY_DOTFILES     = (1u << 2),
+	GIT_CPDIR_OVERWRITE         = (1u << 3),
+	GIT_CPDIR_CHMOD_DIRS        = (1u << 4),
+	GIT_CPDIR_SIMPLE_TO_MODE    = (1u << 5),
+	GIT_CPDIR_LINK_FILES        = (1u << 6),
+} git_futils_cpdir_flags;
+
+/**
+ * Copy a directory tree.
+ *
+ * This copies directories and files from one root to another.  You can
+ * pass a combinationof GIT_CPDIR flags as defined above.
+ *
+ * If you pass the CHMOD flag, then the dirmode will be applied to all
+ * directories that are created during the copy, overiding the natural
+ * permissions.  If you do not pass the CHMOD flag, then the dirmode
+ * will actually be copied from the source files and the `dirmode` arg
+ * will be ignored.
+ */
+extern int git_futils_cp_r(
+	const char *from,
+	const char *to,
+	uint32_t flags,
+	mode_t dirmode);
+
+/**
+ * Open a file readonly and set error if needed.
+ */
+extern int git_futils_open_ro(const char *path);
+
+/**
+ * Get the filesize in bytes of a file
+ */
+extern git_off_t git_futils_filesize(git_file fd);
+
+#define GIT_PERMS_IS_EXEC(MODE)		(((MODE) & 0111) != 0)
+#define GIT_PERMS_CANONICAL(MODE)	(GIT_PERMS_IS_EXEC(MODE) ? 0755 : 0644)
+#define GIT_PERMS_FOR_WRITE(MODE)   (GIT_PERMS_IS_EXEC(MODE) ? 0777 : 0666)
+
+#define GIT_MODE_PERMS_MASK			0777
+#define GIT_MODE_TYPE_MASK			0170000
+#define GIT_MODE_TYPE(MODE)			((MODE) & GIT_MODE_TYPE_MASK)
+#define GIT_MODE_ISBLOB(MODE)		(GIT_MODE_TYPE(MODE) == GIT_MODE_TYPE(GIT_FILEMODE_BLOB))
+
+/**
+ * Convert a mode_t from the OS to a legal git mode_t value.
+ */
+extern mode_t git_futils_canonical_mode(mode_t raw_mode);
+
+
+/**
+ * Read-only map all or part of a file into memory.
+ * When possible this function should favor a virtual memory
+ * style mapping over some form of malloc()+read(), as the
+ * data access will be random and is not likely to touch the
+ * majority of the region requested.
+ *
+ * @param out buffer to populate with the mapping information.
+ * @param fd open descriptor to configure the mapping from.
+ * @param begin first byte to map, this should be page aligned.
+ * @param len number of bytes to map.
+ * @return
+ * - 0 on success;
+ * - -1 on error.
+ */
+extern int git_futils_mmap_ro(
+	git_map *out,
+	git_file fd,
+	git_off_t begin,
+	size_t len);
+
+/**
+ * Read-only map an entire file.
+ *
+ * @param out buffer to populate with the mapping information.
+ * @param path path to file to be opened.
+ * @return
+ * - 0 on success;
+ * - GIT_ENOTFOUND if not found;
+ * - -1 on an unspecified OS related error.
+ */
+extern int git_futils_mmap_ro_file(
+	git_map *out,
+	const char *path);
+
+/**
+ * Release the memory associated with a previous memory mapping.
+ * @param map the mapping description previously configured.
+ */
+extern void git_futils_mmap_free(git_map *map);
+
+/**
+ * Create a "fake" symlink (text file containing the target path).
+ *
+ * @param new symlink file to be created
+ * @param old original symlink target
+ * @return 0 on success, -1 on error
+ */
+extern int git_futils_fake_symlink(const char *new, const char *old);
+
+/**
+ * A file stamp represents a snapshot of information about a file that can
+ * be used to test if the file changes.  This portable implementation is
+ * based on stat data about that file, but it is possible that OS specific
+ * versions could be implemented in the future.
+ */
+typedef struct {
+	git_time_t mtime;
+	git_off_t  size;
+	unsigned int ino;
+} git_futils_filestamp;
+
+/**
+ * Compare stat information for file with reference info.
+ *
+ * This function updates the file stamp to current data for the given path
+ * and returns 0 if the file is up-to-date relative to the prior setting,
+ * 1 if the file has been changed, or GIT_ENOTFOUND if the file doesn't
+ * exist.  This will not call giterr_set, so you must set the error if you
+ * plan to return an error.
+ *
+ * @param stamp File stamp to be checked
+ * @param path Path to stat and check if changed
+ * @return 0 if up-to-date, 1 if out-of-date, GIT_ENOTFOUND if cannot stat
+ */
+extern int git_futils_filestamp_check(
+	git_futils_filestamp *stamp, const char *path);
+
+/**
+ * Set or reset file stamp data
+ *
+ * This writes the target file stamp.  If the source is NULL, this will set
+ * the target stamp to values that will definitely be out of date.  If the
+ * source is not NULL, this copies the source values to the target.
+ *
+ * @param tgt File stamp to write to
+ * @param src File stamp to copy from or NULL to clear the target
+ */
+extern void git_futils_filestamp_set(
+	git_futils_filestamp *tgt, const git_futils_filestamp *src);
+
+/**
+ * Set file stamp data from stat structure
+ */
+extern void git_futils_filestamp_set_from_stat(
+	git_futils_filestamp *stamp, struct stat *st);
+
+#endif /* INCLUDE_fileops_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/filter.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/filter.c
new file mode 100755
index 0000000..4006351
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/filter.c
@@ -0,0 +1,980 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "fileops.h"
+#include "hash.h"
+#include "filter.h"
+#include "repository.h"
+#include "global.h"
+#include "git2/sys/filter.h"
+#include "git2/config.h"
+#include "blob.h"
+#include "attr_file.h"
+#include "array.h"
+
+struct git_filter_source {
+	git_repository *repo;
+	const char     *path;
+	git_oid         oid;  /* zero if unknown (which is likely) */
+	uint16_t        filemode; /* zero if unknown */
+	git_filter_mode_t mode;
+	uint32_t        flags;
+};
+
+typedef struct {
+	const char *filter_name;
+	git_filter *filter;
+	void *payload;
+} git_filter_entry;
+
+struct git_filter_list {
+	git_array_t(git_filter_entry) filters;
+	git_filter_source source;
+	git_buf *temp_buf;
+	char path[GIT_FLEX_ARRAY];
+};
+
+typedef struct {
+	char *filter_name;
+	git_filter *filter;
+	int priority;
+	int initialized;
+	size_t nattrs, nmatches;
+	char *attrdata;
+	const char *attrs[GIT_FLEX_ARRAY];
+} git_filter_def;
+
+static int filter_def_priority_cmp(const void *a, const void *b)
+{
+	int pa = ((const git_filter_def *)a)->priority;
+	int pb = ((const git_filter_def *)b)->priority;
+	return (pa < pb) ? -1 : (pa > pb) ? 1 : 0;
+}
+
+struct filter_registry {
+	git_vector filters;
+};
+
+static struct filter_registry *git__filter_registry = NULL;
+
+static void filter_registry_shutdown(void)
+{
+	struct filter_registry *reg = NULL;
+	size_t pos;
+	git_filter_def *fdef;
+
+	if ((reg = git__swap(git__filter_registry, NULL)) == NULL)
+		return;
+
+	git_vector_foreach(&reg->filters, pos, fdef) {
+		if (fdef->filter && fdef->filter->shutdown) {
+			fdef->filter->shutdown(fdef->filter);
+			fdef->initialized = false;
+		}
+
+		git__free(fdef->filter_name);
+		git__free(fdef->attrdata);
+		git__free(fdef);
+	}
+
+	git_vector_free(&reg->filters);
+	git__free(reg);
+}
+
+static int filter_registry_initialize(void)
+{
+	int error = 0;
+	struct filter_registry *reg;
+
+	if (git__filter_registry)
+		return 0;
+
+	reg = git__calloc(1, sizeof(struct filter_registry));
+	GITERR_CHECK_ALLOC(reg);
+
+	if ((error = git_vector_init(
+			&reg->filters, 2, filter_def_priority_cmp)) < 0)
+		goto cleanup;
+
+	reg = git__compare_and_swap(&git__filter_registry, NULL, reg);
+	if (reg != NULL)
+		goto cleanup;
+
+	git__on_shutdown(filter_registry_shutdown);
+
+	/* try to register both default filters */
+	{
+		git_filter *crlf = git_crlf_filter_new();
+		git_filter *ident = git_ident_filter_new();
+
+		if (crlf && git_filter_register(
+				GIT_FILTER_CRLF, crlf, GIT_FILTER_CRLF_PRIORITY) < 0)
+			crlf = NULL;
+		if (ident && git_filter_register(
+				GIT_FILTER_IDENT, ident, GIT_FILTER_IDENT_PRIORITY) < 0)
+			ident = NULL;
+
+		if (!crlf || !ident)
+			return -1;
+	}
+
+	return 0;
+
+cleanup:
+	git_vector_free(&reg->filters);
+	git__free(reg);
+	return error;
+}
+
+static int filter_def_scan_attrs(
+	git_buf *attrs, size_t *nattr, size_t *nmatch, const char *attr_str)
+{
+	const char *start, *scan = attr_str;
+	int has_eq;
+
+	*nattr = *nmatch = 0;
+
+	if (!scan)
+		return 0;
+
+	while (*scan) {
+		while (git__isspace(*scan)) scan++;
+
+		for (start = scan, has_eq = 0; *scan && !git__isspace(*scan); ++scan) {
+			if (*scan == '=')
+				has_eq = 1;
+		}
+
+		if (scan > start) {
+			(*nattr)++;
+			if (has_eq || *start == '-' || *start == '+' || *start == '!')
+				(*nmatch)++;
+
+			if (has_eq)
+				git_buf_putc(attrs, '=');
+			git_buf_put(attrs, start, scan - start);
+			git_buf_putc(attrs, '\0');
+		}
+	}
+
+	return 0;
+}
+
+static void filter_def_set_attrs(git_filter_def *fdef)
+{
+	char *scan = fdef->attrdata;
+	size_t i;
+
+	for (i = 0; i < fdef->nattrs; ++i) {
+		const char *name, *value;
+
+		switch (*scan) {
+		case '=':
+			name = scan + 1;
+			for (scan++; *scan != '='; scan++) /* find '=' */;
+			*scan++ = '\0';
+			value = scan;
+			break;
+		case '-':
+			name = scan + 1; value = git_attr__false; break;
+		case '+':
+			name = scan + 1; value = git_attr__true;  break;
+		case '!':
+			name = scan + 1; value = git_attr__unset; break;
+		default:
+			name = scan;     value = NULL; break;
+		}
+
+		fdef->attrs[i] = name;
+		fdef->attrs[i + fdef->nattrs] = value;
+
+		scan += strlen(scan) + 1;
+	}
+}
+
+static int filter_def_name_key_check(const void *key, const void *fdef)
+{
+	const char *name =
+		fdef ? ((const git_filter_def *)fdef)->filter_name : NULL;
+	return name ? git__strcmp(key, name) : -1;
+}
+
+static int filter_def_filter_key_check(const void *key, const void *fdef)
+{
+	const void *filter = fdef ? ((const git_filter_def *)fdef)->filter : NULL;
+	return (key == filter) ? 0 : -1;
+}
+
+static int filter_registry_find(size_t *pos, const char *name)
+{
+	return git_vector_search2(
+		pos, &git__filter_registry->filters, filter_def_name_key_check, name);
+}
+
+static git_filter_def *filter_registry_lookup(size_t *pos, const char *name)
+{
+	git_filter_def *fdef = NULL;
+
+	if (!filter_registry_find(pos, name))
+		fdef = git_vector_get(&git__filter_registry->filters, *pos);
+
+	return fdef;
+}
+
+int git_filter_register(
+	const char *name, git_filter *filter, int priority)
+{
+	git_filter_def *fdef;
+	size_t nattr = 0, nmatch = 0, alloc_len;
+	git_buf attrs = GIT_BUF_INIT;
+
+	assert(name && filter);
+
+	if (filter_registry_initialize() < 0)
+		return -1;
+
+	if (!filter_registry_find(NULL, name)) {
+		giterr_set(
+			GITERR_FILTER, "Attempt to reregister existing filter '%s'", name);
+		return GIT_EEXISTS;
+	}
+
+	if (filter_def_scan_attrs(&attrs, &nattr, &nmatch, filter->attributes) < 0)
+		return -1;
+
+	GITERR_CHECK_ALLOC_MULTIPLY(&alloc_len, nattr, 2);
+	GITERR_CHECK_ALLOC_MULTIPLY(&alloc_len, alloc_len, sizeof(char *));
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, sizeof(git_filter_def));
+
+	fdef = git__calloc(1, alloc_len);
+	GITERR_CHECK_ALLOC(fdef);
+
+	fdef->filter_name = git__strdup(name);
+	GITERR_CHECK_ALLOC(fdef->filter_name);
+
+	fdef->filter      = filter;
+	fdef->priority    = priority;
+	fdef->nattrs      = nattr;
+	fdef->nmatches    = nmatch;
+	fdef->attrdata    = git_buf_detach(&attrs);
+
+	filter_def_set_attrs(fdef);
+
+	if (git_vector_insert(&git__filter_registry->filters, fdef) < 0) {
+		git__free(fdef->filter_name);
+		git__free(fdef->attrdata);
+		git__free(fdef);
+		return -1;
+	}
+
+	git_vector_sort(&git__filter_registry->filters);
+	return 0;
+}
+
+int git_filter_unregister(const char *name)
+{
+	size_t pos;
+	git_filter_def *fdef;
+
+	assert(name);
+
+	/* cannot unregister default filters */
+	if (!strcmp(GIT_FILTER_CRLF, name) || !strcmp(GIT_FILTER_IDENT, name)) {
+		giterr_set(GITERR_FILTER, "Cannot unregister filter '%s'", name);
+		return -1;
+	}
+
+	if ((fdef = filter_registry_lookup(&pos, name)) == NULL) {
+		giterr_set(GITERR_FILTER, "Cannot find filter '%s' to unregister", name);
+		return GIT_ENOTFOUND;
+	}
+
+	(void)git_vector_remove(&git__filter_registry->filters, pos);
+
+	if (fdef->initialized && fdef->filter && fdef->filter->shutdown) {
+		fdef->filter->shutdown(fdef->filter);
+		fdef->initialized = false;
+	}
+
+	git__free(fdef->filter_name);
+	git__free(fdef->attrdata);
+	git__free(fdef);
+
+	return 0;
+}
+
+static int filter_initialize(git_filter_def *fdef)
+{
+	int error = 0;
+
+	if (!fdef->initialized &&
+		fdef->filter &&
+		fdef->filter->initialize &&
+		(error = fdef->filter->initialize(fdef->filter)) < 0)
+	{
+		/* auto-unregister if initialize fails */
+		git_filter_unregister(fdef->filter_name);
+		return error;
+	}
+
+	fdef->initialized = true;
+	return 0;
+}
+
+git_filter *git_filter_lookup(const char *name)
+{
+	size_t pos;
+	git_filter_def *fdef;
+
+	if (filter_registry_initialize() < 0)
+		return NULL;
+
+	if ((fdef = filter_registry_lookup(&pos, name)) == NULL)
+		return NULL;
+
+	if (!fdef->initialized && filter_initialize(fdef) < 0)
+		return NULL;
+
+	return fdef->filter;
+}
+
+void git_filter_free(git_filter *filter)
+{
+	git__free(filter);
+}
+
+git_repository *git_filter_source_repo(const git_filter_source *src)
+{
+	return src->repo;
+}
+
+const char *git_filter_source_path(const git_filter_source *src)
+{
+	return src->path;
+}
+
+uint16_t git_filter_source_filemode(const git_filter_source *src)
+{
+	return src->filemode;
+}
+
+const git_oid *git_filter_source_id(const git_filter_source *src)
+{
+	return git_oid_iszero(&src->oid) ? NULL : &src->oid;
+}
+
+git_filter_mode_t git_filter_source_mode(const git_filter_source *src)
+{
+	return src->mode;
+}
+
+uint32_t git_filter_source_flags(const git_filter_source *src)
+{
+	return src->flags;
+}
+
+static int filter_list_new(
+	git_filter_list **out, const git_filter_source *src)
+{
+	git_filter_list *fl = NULL;
+	size_t pathlen = src->path ? strlen(src->path) : 0, alloclen;
+
+	GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(git_filter_list), pathlen);
+	GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
+
+	fl = git__calloc(1, alloclen);
+	GITERR_CHECK_ALLOC(fl);
+
+	if (src->path)
+		memcpy(fl->path, src->path, pathlen);
+	fl->source.repo = src->repo;
+	fl->source.path = fl->path;
+	fl->source.mode = src->mode;
+	fl->source.flags = src->flags;
+
+	*out = fl;
+	return 0;
+}
+
+static int filter_list_check_attributes(
+	const char ***out,
+	git_repository *repo,
+	git_attr_session *attr_session,
+	git_filter_def *fdef,
+	const git_filter_source *src)
+{
+	int error;
+	size_t i;
+	const char **strs = git__calloc(fdef->nattrs, sizeof(const char *));
+	GITERR_CHECK_ALLOC(strs);
+
+	error = git_attr_get_many_with_session(
+		strs, repo, attr_session, 0, src->path, fdef->nattrs, fdef->attrs);
+
+	/* if no values were found but no matches are needed, it's okay! */
+	if (error == GIT_ENOTFOUND && !fdef->nmatches) {
+		giterr_clear();
+		git__free((void *)strs);
+		return 0;
+	}
+
+	for (i = 0; !error && i < fdef->nattrs; ++i) {
+		const char *want = fdef->attrs[fdef->nattrs + i];
+		git_attr_t want_type, found_type;
+
+		if (!want)
+			continue;
+
+		want_type  = git_attr_value(want);
+		found_type = git_attr_value(strs[i]);
+
+		if (want_type != found_type ||
+			(want_type == GIT_ATTR_VALUE_T && strcmp(want, strs[i])))
+			error = GIT_ENOTFOUND;
+	}
+
+	if (error)
+		git__free((void *)strs);
+	else
+		*out = strs;
+
+	return error;
+}
+
+int git_filter_list_new(
+	git_filter_list **out,
+	git_repository *repo,
+	git_filter_mode_t mode,
+	uint32_t flags)
+{
+	git_filter_source src = { 0 };
+	src.repo = repo;
+	src.path = NULL;
+	src.mode = mode;
+	src.flags = flags;
+	return filter_list_new(out, &src);
+}
+
+int git_filter_list__load_ext(
+	git_filter_list **filters,
+	git_repository *repo,
+	git_blob *blob, /* can be NULL */
+	const char *path,
+	git_filter_mode_t mode,
+	git_filter_options *filter_opts)
+{
+	int error = 0;
+	git_filter_list *fl = NULL;
+	git_filter_source src = { 0 };
+	git_filter_entry *fe;
+	size_t idx;
+	git_filter_def *fdef;
+
+	if (filter_registry_initialize() < 0)
+		return -1;
+
+	src.repo = repo;
+	src.path = path;
+	src.mode = mode;
+	src.flags = filter_opts->flags;
+
+	if (blob)
+		git_oid_cpy(&src.oid, git_blob_id(blob));
+
+	git_vector_foreach(&git__filter_registry->filters, idx, fdef) {
+		const char **values = NULL;
+		void *payload = NULL;
+
+		if (!fdef || !fdef->filter)
+			continue;
+
+		if (fdef->nattrs > 0) {
+			error = filter_list_check_attributes(
+				&values, repo, filter_opts->attr_session, fdef, &src);
+
+			if (error == GIT_ENOTFOUND) {
+				error = 0;
+				continue;
+			} else if (error < 0)
+				break;
+		}
+
+		if (!fdef->initialized && (error = filter_initialize(fdef)) < 0)
+			break;
+
+		if (fdef->filter->check)
+			error = fdef->filter->check(
+				fdef->filter, &payload, &src, values);
+
+		git__free((void *)values);
+
+		if (error == GIT_PASSTHROUGH)
+			error = 0;
+		else if (error < 0)
+			break;
+		else {
+			if (!fl) {
+				if ((error = filter_list_new(&fl, &src)) < 0)
+					return error;
+
+				fl->temp_buf = filter_opts->temp_buf;
+			}
+
+			fe = git_array_alloc(fl->filters);
+			GITERR_CHECK_ALLOC(fe);
+
+			fe->filter = fdef->filter;
+			fe->filter_name = fdef->filter_name;
+			fe->payload = payload;
+		}
+	}
+
+	if (error && fl != NULL) {
+		git_array_clear(fl->filters);
+		git__free(fl);
+		fl = NULL;
+	}
+
+	*filters = fl;
+	return error;
+}
+
+int git_filter_list_load(
+	git_filter_list **filters,
+	git_repository *repo,
+	git_blob *blob, /* can be NULL */
+	const char *path,
+	git_filter_mode_t mode,
+	uint32_t flags)
+{
+	git_filter_options filter_opts = GIT_FILTER_OPTIONS_INIT;
+
+	filter_opts.flags = flags;
+
+	return git_filter_list__load_ext(
+		filters, repo, blob, path, mode, &filter_opts);
+}
+
+void git_filter_list_free(git_filter_list *fl)
+{
+	uint32_t i;
+
+	if (!fl)
+		return;
+
+	for (i = 0; i < git_array_size(fl->filters); ++i) {
+		git_filter_entry *fe = git_array_get(fl->filters, i);
+		if (fe->filter->cleanup)
+			fe->filter->cleanup(fe->filter, fe->payload);
+	}
+
+	git_array_clear(fl->filters);
+	git__free(fl);
+}
+
+int git_filter_list_contains(
+	git_filter_list *fl,
+	const char *name)
+{
+	size_t i;
+
+	assert(name);
+
+	if (!fl)
+		return 0;
+
+	for (i = 0; i < fl->filters.size; i++) {
+		if (strcmp(fl->filters.ptr[i].filter_name, name) == 0)
+			return 1;
+	}
+
+	return 0;
+}
+
+int git_filter_list_push(
+	git_filter_list *fl, git_filter *filter, void *payload)
+{
+	int error = 0;
+	size_t pos;
+	git_filter_def *fdef;
+	git_filter_entry *fe;
+
+	assert(fl && filter);
+
+	if (git_vector_search2(
+			&pos, &git__filter_registry->filters,
+			filter_def_filter_key_check, filter) < 0) {
+		giterr_set(GITERR_FILTER, "Cannot use an unregistered filter");
+		return -1;
+	}
+
+	fdef = git_vector_get(&git__filter_registry->filters, pos);
+
+	if (!fdef->initialized && (error = filter_initialize(fdef)) < 0)
+		return error;
+
+	fe = git_array_alloc(fl->filters);
+	GITERR_CHECK_ALLOC(fe);
+	fe->filter  = filter;
+	fe->payload = payload;
+
+	return 0;
+}
+
+size_t git_filter_list_length(const git_filter_list *fl)
+{
+	return fl ? git_array_size(fl->filters) : 0;
+}
+
+struct buf_stream {
+	git_writestream parent;
+	git_buf *target;
+	bool complete;
+};
+
+static int buf_stream_write(
+	git_writestream *s, const char *buffer, size_t len)
+{
+	struct buf_stream *buf_stream = (struct buf_stream *)s;
+	assert(buf_stream);
+
+	assert(buf_stream->complete == 0);
+
+	return git_buf_put(buf_stream->target, buffer, len);
+}
+
+static int buf_stream_close(git_writestream *s)
+{
+	struct buf_stream *buf_stream = (struct buf_stream *)s;
+	assert(buf_stream);
+
+	assert(buf_stream->complete == 0);
+	buf_stream->complete = 1;
+
+	return 0;
+}
+
+static void buf_stream_free(git_writestream *s)
+{
+	GIT_UNUSED(s);
+}
+
+static void buf_stream_init(struct buf_stream *writer, git_buf *target)
+{
+	memset(writer, 0, sizeof(struct buf_stream));
+
+	writer->parent.write = buf_stream_write;
+	writer->parent.close = buf_stream_close;
+	writer->parent.free = buf_stream_free;
+	writer->target = target;
+
+	git_buf_clear(target);
+}
+
+int git_filter_list_apply_to_data(
+	git_buf *tgt, git_filter_list *filters, git_buf *src)
+{
+	struct buf_stream writer;
+	int error;
+
+	git_buf_sanitize(tgt);
+	git_buf_sanitize(src);
+
+	if (!filters) {
+		git_buf_attach_notowned(tgt, src->ptr, src->size);
+		return 0;
+	}
+
+	buf_stream_init(&writer, tgt);
+
+	if ((error = git_filter_list_stream_data(filters, src,
+		&writer.parent)) < 0)
+			return error;
+
+	assert(writer.complete);
+	return error;
+}
+
+int git_filter_list_apply_to_file(
+	git_buf *out,
+	git_filter_list *filters,
+	git_repository *repo,
+	const char *path)
+{
+	struct buf_stream writer;
+	int error;
+
+	buf_stream_init(&writer, out);
+
+	if ((error = git_filter_list_stream_file(
+		filters, repo, path, &writer.parent)) < 0)
+			return error;
+
+	assert(writer.complete);
+	return error;
+}
+
+static int buf_from_blob(git_buf *out, git_blob *blob)
+{
+	git_off_t rawsize = git_blob_rawsize(blob);
+
+	if (!git__is_sizet(rawsize)) {
+		giterr_set(GITERR_OS, "Blob is too large to filter");
+		return -1;
+	}
+
+	git_buf_attach_notowned(out, git_blob_rawcontent(blob), (size_t)rawsize);
+	return 0;
+}
+
+int git_filter_list_apply_to_blob(
+	git_buf *out,
+	git_filter_list *filters,
+	git_blob *blob)
+{
+	struct buf_stream writer;
+	int error;
+
+	buf_stream_init(&writer, out);
+
+	if ((error = git_filter_list_stream_blob(
+		filters, blob, &writer.parent)) < 0)
+			return error;
+
+	assert(writer.complete);
+	return error;
+}
+
+struct proxy_stream {
+	git_writestream parent;
+	git_filter *filter;
+	const git_filter_source *source;
+	void **payload;
+	git_buf input;
+	git_buf temp_buf;
+	git_buf *output;
+	git_writestream *target;
+};
+
+static int proxy_stream_write(
+	git_writestream *s, const char *buffer, size_t len)
+{
+	struct proxy_stream *proxy_stream = (struct proxy_stream *)s;
+	assert(proxy_stream);
+
+	return git_buf_put(&proxy_stream->input, buffer, len);
+}
+
+static int proxy_stream_close(git_writestream *s)
+{
+	struct proxy_stream *proxy_stream = (struct proxy_stream *)s;
+	git_buf *writebuf;
+	int error;
+
+	assert(proxy_stream);
+
+	error = proxy_stream->filter->apply(
+		proxy_stream->filter,
+		proxy_stream->payload,
+		proxy_stream->output,
+		&proxy_stream->input,
+		proxy_stream->source);
+
+	if (error == GIT_PASSTHROUGH) {
+		writebuf = &proxy_stream->input;
+	} else if (error == 0) {
+		git_buf_sanitize(proxy_stream->output);
+		writebuf = proxy_stream->output;
+	} else {
+		return error;
+	}
+
+	if ((error = proxy_stream->target->write(
+			proxy_stream->target, writebuf->ptr, writebuf->size)) == 0)
+		error = proxy_stream->target->close(proxy_stream->target);
+
+	return error;
+}
+
+static void proxy_stream_free(git_writestream *s)
+{
+	struct proxy_stream *proxy_stream = (struct proxy_stream *)s;
+	assert(proxy_stream);
+
+	git_buf_free(&proxy_stream->input);
+	git_buf_free(&proxy_stream->temp_buf);
+	git__free(proxy_stream);
+}
+
+static int proxy_stream_init(
+	git_writestream **out,
+	git_filter *filter,
+	git_buf *temp_buf,
+	void **payload,
+	const git_filter_source *source,
+	git_writestream *target)
+{
+	struct proxy_stream *proxy_stream = git__calloc(1, sizeof(struct proxy_stream));
+	GITERR_CHECK_ALLOC(proxy_stream);
+
+	proxy_stream->parent.write = proxy_stream_write;
+	proxy_stream->parent.close = proxy_stream_close;
+	proxy_stream->parent.free = proxy_stream_free;
+	proxy_stream->filter = filter;
+	proxy_stream->payload = payload;
+	proxy_stream->source = source;
+	proxy_stream->target = target;
+	proxy_stream->output = temp_buf ? temp_buf : &proxy_stream->temp_buf;
+
+	if (temp_buf)
+		git_buf_clear(temp_buf);
+
+	*out = (git_writestream *)proxy_stream;
+	return 0;
+}
+
+static int stream_list_init(
+	git_writestream **out,
+	git_vector *streams,
+	git_filter_list *filters,
+	git_writestream *target)
+{
+	git_writestream *last_stream = target;
+	size_t i;
+	int error = 0;
+
+	*out = NULL;
+
+	if (!filters) {
+		*out = target;
+		return 0;
+	}
+
+	/* Create filters last to first to get the chaining direction */
+	for (i = 0; i < git_array_size(filters->filters); ++i) {
+		size_t filter_idx = (filters->source.mode == GIT_FILTER_TO_WORKTREE) ?
+			git_array_size(filters->filters) - 1 - i : i;
+		git_filter_entry *fe = git_array_get(filters->filters, filter_idx);
+		git_writestream *filter_stream;
+		
+		assert(fe->filter->stream || fe->filter->apply);
+
+		/* If necessary, create a stream that proxies the traditional
+		 * application.
+		 */
+		if (fe->filter->stream)
+			error = fe->filter->stream(&filter_stream, fe->filter,
+				&fe->payload, &filters->source, last_stream);
+		else
+			/* Create a stream that proxies the one-shot apply */
+			error = proxy_stream_init(&filter_stream, fe->filter,
+				filters->temp_buf, &fe->payload, &filters->source,
+				last_stream);
+
+		if (error < 0)
+			return error;
+
+		git_vector_insert(streams, filter_stream);
+		last_stream = filter_stream;
+	}
+
+	*out = last_stream;
+	return 0;
+}
+
+void stream_list_free(git_vector *streams)
+{
+	git_writestream *stream;
+	size_t i;
+
+	git_vector_foreach(streams, i, stream)
+		stream->free(stream);
+	git_vector_free(streams);
+}
+
+int git_filter_list_stream_file(
+	git_filter_list *filters,
+	git_repository *repo,
+	const char *path,
+	git_writestream *target)
+{
+	char buf[FILTERIO_BUFSIZE];
+	git_buf abspath = GIT_BUF_INIT;
+	const char *base = repo ? git_repository_workdir(repo) : NULL;
+	git_vector filter_streams = GIT_VECTOR_INIT;
+	git_writestream *stream_start;
+	ssize_t readlen;
+	int fd = -1, error;
+
+	if ((error = stream_list_init(
+			&stream_start, &filter_streams, filters, target)) < 0 ||
+		(error = git_path_join_unrooted(&abspath, path, base, NULL)) < 0)
+		goto done;
+
+	if ((fd = git_futils_open_ro(abspath.ptr)) < 0) {
+		error = fd;
+		goto done;
+	}
+
+	while ((readlen = p_read(fd, buf, sizeof(buf))) > 0) {
+		if ((error = stream_start->write(stream_start, buf, readlen)) < 0)
+			goto done;
+	}
+
+	if (!readlen)
+		error = stream_start->close(stream_start);
+	else if (readlen < 0)
+		error = readlen;
+
+
+done:
+	if (fd >= 0)
+		p_close(fd);
+	stream_list_free(&filter_streams);
+	git_buf_free(&abspath);
+	return error;
+}
+
+int git_filter_list_stream_data(
+	git_filter_list *filters,
+	git_buf *data,
+	git_writestream *target)
+{
+	git_vector filter_streams = GIT_VECTOR_INIT;
+	git_writestream *stream_start;
+	int error = 0, close_error;
+
+	git_buf_sanitize(data);
+
+	if ((error = stream_list_init(&stream_start, &filter_streams, filters, target)) < 0)
+		goto out;
+
+	error = stream_start->write(stream_start, data->ptr, data->size);
+
+out:
+	close_error = stream_start->close(stream_start);
+	stream_list_free(&filter_streams);
+	/* propagate the stream init or write error */
+	return error < 0 ? error : close_error;
+}
+
+int git_filter_list_stream_blob(
+	git_filter_list *filters,
+	git_blob *blob,
+	git_writestream *target)
+{
+	git_buf in = GIT_BUF_INIT;
+
+	if (buf_from_blob(&in, blob) < 0)
+		return -1;
+
+	if (filters)
+		git_oid_cpy(&filters->source.oid, git_blob_id(blob));
+
+	return git_filter_list_stream_data(filters, &in, target);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/filter.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/filter.h
new file mode 100755
index 0000000..5062afb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/filter.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_filter_h__
+#define INCLUDE_filter_h__
+
+#include "common.h"
+#include "attr_file.h"
+#include "git2/filter.h"
+
+/* Amount of file to examine for NUL byte when checking binary-ness */
+#define GIT_FILTER_BYTES_TO_CHECK_NUL 8000
+
+/* Possible CRLF values */
+typedef enum {
+	GIT_CRLF_GUESS = -1,
+	GIT_CRLF_BINARY = 0,
+	GIT_CRLF_TEXT,
+	GIT_CRLF_INPUT,
+	GIT_CRLF_CRLF,
+	GIT_CRLF_AUTO,
+} git_crlf_t;
+
+typedef struct {
+	git_attr_session *attr_session;
+	git_buf *temp_buf;
+	uint32_t flags;
+} git_filter_options;
+
+#define GIT_FILTER_OPTIONS_INIT {0}
+
+extern void git_filter_free(git_filter *filter);
+
+extern int git_filter_list__load_ext(
+	git_filter_list **filters,
+	git_repository *repo,
+	git_blob *blob, /* can be NULL */
+	const char *path,
+	git_filter_mode_t mode,
+	git_filter_options *filter_opts);
+
+/*
+ * Available filters
+ */
+
+extern git_filter *git_crlf_filter_new(void);
+extern git_filter *git_ident_filter_new(void);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fnmatch.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fnmatch.c
new file mode 100755
index 0000000..a2945b8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fnmatch.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+/*
+ * This file contains code originally derrived from OpenBSD fnmatch.c 
+ *
+ * Copyright (c) 1989, 1993, 1994
+ *      The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
+ * Compares a filename or pathname to a pattern.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "fnmatch.h"
+
+#define EOS		'\0'
+
+#define RANGE_MATCH		1
+#define RANGE_NOMATCH		0
+#define RANGE_ERROR		(-1)
+
+static int rangematch(const char *, char, int, char **);
+
+static int
+p_fnmatchx(const char *pattern, const char *string, int flags, size_t recurs)
+{
+		const char *stringstart;
+		char *newp;
+		char c, test;
+		int recurs_flags = flags & ~FNM_PERIOD;
+
+		if (recurs-- == 0)
+				return FNM_NORES;
+
+		for (stringstart = string;;)
+				switch (c = *pattern++) {
+				case EOS:
+						if ((flags & FNM_LEADING_DIR) && *string == '/')
+								return (0);
+						return (*string == EOS ? 0 : FNM_NOMATCH);
+				case '?':
+						if (*string == EOS)
+								return (FNM_NOMATCH);
+						if (*string == '/' && (flags & FNM_PATHNAME))
+								return (FNM_NOMATCH);
+						if (*string == '.' && (flags & FNM_PERIOD) &&
+							(string == stringstart ||
+							((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+								return (FNM_NOMATCH);
+						++string;
+						break;
+				case '*':
+						c = *pattern;
+
+						/* Let '**' override PATHNAME match for this segment.
+						 * It will be restored if/when we recurse below.
+						 */
+						if (c == '*') {
+							flags &= ~FNM_PATHNAME;
+							while (c == '*')
+								c = *++pattern;
+							if (c == '/')
+								c = *++pattern;
+						}
+
+						if (*string == '.' && (flags & FNM_PERIOD) &&
+							(string == stringstart ||
+							((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+								return (FNM_NOMATCH);
+
+						/* Optimize for pattern with * at end or before /. */
+						if (c == EOS) {
+								if (flags & FNM_PATHNAME)
+										return ((flags & FNM_LEADING_DIR) ||
+											strchr(string, '/') == NULL ?
+											0 : FNM_NOMATCH);
+								else
+										return (0);
+						} else if (c == '/' && (flags & FNM_PATHNAME)) {
+								if ((string = strchr(string, '/')) == NULL)
+										return (FNM_NOMATCH);
+								break;
+						}
+
+						/* General case, use recursion. */
+						while ((test = *string) != EOS) {
+								int e;
+
+								e = p_fnmatchx(pattern, string, recurs_flags, recurs);
+								if (e != FNM_NOMATCH)
+										return e;
+								if (test == '/' && (flags & FNM_PATHNAME))
+										break;
+								++string;
+						}
+						return (FNM_NOMATCH);
+				case '[':
+						if (*string == EOS)
+								return (FNM_NOMATCH);
+						if (*string == '/' && (flags & FNM_PATHNAME))
+								return (FNM_NOMATCH);
+						if (*string == '.' && (flags & FNM_PERIOD) &&
+							(string == stringstart ||
+							((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+								return (FNM_NOMATCH);
+
+						switch (rangematch(pattern, *string, flags, &newp)) {
+						case RANGE_ERROR:
+								/* not a good range, treat as normal text */
+								goto normal;
+						case RANGE_MATCH:
+								pattern = newp;
+								break;
+						case RANGE_NOMATCH:
+								return (FNM_NOMATCH);
+						}
+						++string;
+						break;
+				case '\\':
+						if (!(flags & FNM_NOESCAPE)) {
+								if ((c = *pattern++) == EOS) {
+										c = '\\';
+										--pattern;
+								}
+						}
+						/* FALLTHROUGH */
+				default:
+				normal:
+						if (c != *string && !((flags & FNM_CASEFOLD) &&
+									(git__tolower((unsigned char)c) ==
+									git__tolower((unsigned char)*string))))
+								return (FNM_NOMATCH);
+						++string;
+						break;
+				}
+		/* NOTREACHED */
+}
+
+static int
+rangematch(const char *pattern, char test, int flags, char **newp)
+{
+		int negate, ok;
+		char c, c2;
+
+		/*
+			* A bracket expression starting with an unquoted circumflex
+			* character produces unspecified results (IEEE 1003.2-1992,
+			* 3.13.2). This implementation treats it like '!', for
+			* consistency with the regular expression syntax.
+			* J.T. Conklin (conklin at ngai.kaleida.com)
+			*/
+		if ((negate = (*pattern == '!' || *pattern == '^')) != 0)
+				++pattern;
+
+		if (flags & FNM_CASEFOLD)
+				test = (char)git__tolower((unsigned char)test);
+
+		/*
+			* A right bracket shall lose its special meaning and represent
+			* itself in a bracket expression if it occurs first in the list.
+			* -- POSIX.2 2.8.3.2
+			*/
+		ok = 0;
+		c = *pattern++;
+		do {
+				if (c == '\\' && !(flags & FNM_NOESCAPE))
+						c = *pattern++;
+				if (c == EOS)
+						return (RANGE_ERROR);
+				if (c == '/' && (flags & FNM_PATHNAME))
+						return (RANGE_NOMATCH);
+				if ((flags & FNM_CASEFOLD))
+						c = (char)git__tolower((unsigned char)c);
+				if (*pattern == '-'
+					&& (c2 = *(pattern+1)) != EOS && c2 != ']') {
+						pattern += 2;
+						if (c2 == '\\' && !(flags & FNM_NOESCAPE))
+								c2 = *pattern++;
+						if (c2 == EOS)
+								return (RANGE_ERROR);
+						if (flags & FNM_CASEFOLD)
+								c2 = (char)git__tolower((unsigned char)c2);
+						if (c <= test && test <= c2)
+								ok = 1;
+				} else if (c == test)
+						ok = 1;
+		} while ((c = *pattern++) != ']');
+
+		*newp = (char *)pattern;
+		return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH);
+}
+
+int
+p_fnmatch(const char *pattern, const char *string, int flags)
+{
+		return p_fnmatchx(pattern, string, flags, 64);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fnmatch.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fnmatch.h
new file mode 100755
index 0000000..88af459
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/fnmatch.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef INCLUDE_fnmatch__compat_h__
+#define INCLUDE_fnmatch__compat_h__
+
+#include "common.h"
+
+#define FNM_NOMATCH		1		/* Match failed. */
+#define FNM_NOSYS		2		/* Function not supported (unused). */
+#define	FNM_NORES		3		/* Out of resources */
+
+#define FNM_NOESCAPE	0x01		/* Disable backslash escaping. */
+#define FNM_PATHNAME	0x02		/* Slash must be matched by slash. */
+#define FNM_PERIOD		0x04		/* Period must be matched by period. */
+#define FNM_LEADING_DIR 0x08		/* Ignore /<tail> after Imatch. */
+#define FNM_CASEFOLD	0x10		/* Case insensitive search. */
+
+#define FNM_IGNORECASE	FNM_CASEFOLD
+#define FNM_FILE_NAME	FNM_PATHNAME
+
+extern int p_fnmatch(const char *pattern, const char *string, int flags);
+
+#endif /* _FNMATCH_H */
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/global.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/global.c
new file mode 100755
index 0000000..3f20bfd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/global.c
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "global.h"
+#include "hash.h"
+#include "sysdir.h"
+#include "git2/global.h"
+#include "git2/sys/openssl.h"
+#include "thread-utils.h"
+
+
+git_mutex git__mwindow_mutex;
+
+#define MAX_SHUTDOWN_CB 8
+
+#ifdef GIT_OPENSSL
+# include <openssl/ssl.h>
+SSL_CTX *git__ssl_ctx;
+# ifdef GIT_THREADS
+static git_mutex *openssl_locks;
+# endif
+#endif
+
+static git_global_shutdown_fn git__shutdown_callbacks[MAX_SHUTDOWN_CB];
+static git_atomic git__n_shutdown_callbacks;
+static git_atomic git__n_inits;
+
+void git__on_shutdown(git_global_shutdown_fn callback)
+{
+	int count = git_atomic_inc(&git__n_shutdown_callbacks);
+	assert(count <= MAX_SHUTDOWN_CB && count > 0);
+	git__shutdown_callbacks[count - 1] = callback;
+}
+
+static void git__global_state_cleanup(git_global_st *st)
+{
+	if (!st)
+		return;
+
+	git__free(st->error_t.message);
+	st->error_t.message = NULL;
+}
+
+static void git__shutdown(void)
+{
+	int pos;
+
+	/* Shutdown subsystems that have registered */
+	for (pos = git_atomic_get(&git__n_shutdown_callbacks); pos > 0; pos = git_atomic_dec(&git__n_shutdown_callbacks)) {
+		git_global_shutdown_fn cb = git__swap(git__shutdown_callbacks[pos - 1], NULL);
+		if (cb != NULL)
+			cb();
+	}
+}
+
+#if defined(GIT_THREADS) && defined(GIT_OPENSSL)
+void openssl_locking_function(int mode, int n, const char *file, int line)
+{
+	int lock;
+
+	GIT_UNUSED(file);
+	GIT_UNUSED(line);
+
+	lock = mode & CRYPTO_LOCK;
+
+	if (lock) {
+		git_mutex_lock(&openssl_locks[n]);
+	} else {
+		git_mutex_unlock(&openssl_locks[n]);
+	}
+}
+
+static void shutdown_ssl_locking(void)
+{
+	int num_locks, i;
+
+	num_locks = CRYPTO_num_locks();
+	CRYPTO_set_locking_callback(NULL);
+
+	for (i = 0; i < num_locks; ++i)
+		git_mutex_free(openssl_locks);
+	git__free(openssl_locks);
+}
+#endif
+
+static void init_ssl(void)
+{
+#ifdef GIT_OPENSSL
+	long ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
+
+	/* Older OpenSSL and MacOS OpenSSL doesn't have this */
+#ifdef SSL_OP_NO_COMPRESSION
+	ssl_opts |= SSL_OP_NO_COMPRESSION;
+#endif
+
+	SSL_load_error_strings();
+	OpenSSL_add_ssl_algorithms();
+	/*
+	 * Load SSLv{2,3} and TLSv1 so that we can talk with servers
+	 * which use the SSL hellos, which are often used for
+	 * compatibility. We then disable SSL so we only allow OpenSSL
+	 * to speak TLSv1 to perform the encryption itself.
+	 */
+	git__ssl_ctx = SSL_CTX_new(SSLv23_method());
+	SSL_CTX_set_options(git__ssl_ctx, ssl_opts);
+	SSL_CTX_set_mode(git__ssl_ctx, SSL_MODE_AUTO_RETRY);
+	SSL_CTX_set_verify(git__ssl_ctx, SSL_VERIFY_NONE, NULL);
+	if (!SSL_CTX_set_default_verify_paths(git__ssl_ctx)) {
+		SSL_CTX_free(git__ssl_ctx);
+		git__ssl_ctx = NULL;
+	}
+#endif
+}
+
+/**
+ * This function aims to clean-up the SSL context which
+ * we allocated.
+ */
+static void uninit_ssl(void)
+{
+#ifdef GIT_OPENSSL
+	if (git__ssl_ctx) {
+		SSL_CTX_free(git__ssl_ctx);
+		git__ssl_ctx = NULL;
+	}
+#endif
+}
+
+int git_openssl_set_locking(void)
+{
+#ifdef GIT_OPENSSL
+# ifdef GIT_THREADS
+	int num_locks, i;
+
+	num_locks = CRYPTO_num_locks();
+	openssl_locks = git__calloc(num_locks, sizeof(git_mutex));
+	GITERR_CHECK_ALLOC(openssl_locks);
+
+	for (i = 0; i < num_locks; i++) {
+		if (git_mutex_init(&openssl_locks[i]) != 0) {
+			giterr_set(GITERR_SSL, "failed to initialize openssl locks");
+			return -1;
+		}
+	}
+
+	CRYPTO_set_locking_callback(openssl_locking_function);
+	git__on_shutdown(shutdown_ssl_locking);
+	return 0;
+# else
+	giterr_set(GITERR_THREAD, "libgit2 as not built with threads");
+	return -1;
+# endif
+#else
+	giterr_set(GITERR_SSL, "libgit2 was not built with OpenSSL support");
+	return -1;
+#endif
+}
+
+/**
+ * Handle the global state with TLS
+ *
+ * If libgit2 is built with GIT_THREADS enabled,
+ * the `git_libgit2_init()` function must be called
+ * before calling any other function of the library.
+ *
+ * This function allocates a TLS index (using pthreads
+ * or the native Win32 API) to store the global state
+ * on a per-thread basis.
+ *
+ * Any internal method that requires global state will
+ * then call `git__global_state()` which returns a pointer
+ * to the global state structure; this pointer is lazily
+ * allocated on each thread.
+ *
+ * Before shutting down the library, the
+ * `git_libgit2_shutdown` method must be called to free
+ * the previously reserved TLS index.
+ *
+ * If libgit2 is built without threading support, the
+ * `git__global_statestate()` call returns a pointer to a single,
+ * statically allocated global state. The `git_thread_`
+ * functions are not available in that case.
+ */
+
+/*
+ * `git_libgit2_init()` allows subsystems to perform global setup,
+ * which may take place in the global scope.  An explicit memory
+ * fence exists at the exit of `git_libgit2_init()`.  Without this,
+ * CPU cores are free to reorder cache invalidation of `_tls_init`
+ * before cache invalidation of the subsystems' newly written global
+ * state.
+ */
+#if defined(GIT_THREADS) && defined(GIT_WIN32)
+
+static DWORD _tls_index;
+static volatile LONG _mutex = 0;
+
+static int synchronized_threads_init(void)
+{
+	int error;
+
+	_tls_index = TlsAlloc();
+	if (git_mutex_init(&git__mwindow_mutex))
+		return -1;
+
+	/* Initialize any other subsystems that have global state */
+	if ((error = git_hash_global_init()) >= 0)
+		error = git_sysdir_global_init();
+
+	win32_pthread_initialize();
+
+	return error;
+}
+
+int git_libgit2_init(void)
+{
+	int ret;
+
+	/* Enter the lock */
+	while (InterlockedCompareExchange(&_mutex, 1, 0)) { Sleep(0); }
+
+	/* Only do work on a 0 -> 1 transition of the refcount */
+	if ((ret = git_atomic_inc(&git__n_inits)) == 1) {
+		if (synchronized_threads_init() < 0)
+			ret = -1;
+	}
+
+	/* Exit the lock */
+	InterlockedExchange(&_mutex, 0);
+
+	return ret;
+}
+
+static void synchronized_threads_shutdown(void)
+{
+	/* Shut down any subsystems that have global state */
+	git__shutdown();
+
+	git__free_tls_data();
+
+	TlsFree(_tls_index);
+	git_mutex_free(&git__mwindow_mutex);
+}
+
+int git_libgit2_shutdown(void)
+{
+	int ret;
+
+	/* Enter the lock */
+	while (InterlockedCompareExchange(&_mutex, 1, 0)) { Sleep(0); }
+
+	/* Only do work on a 1 -> 0 transition of the refcount */
+	if ((ret = git_atomic_dec(&git__n_inits)) == 0)
+		synchronized_threads_shutdown();
+
+	/* Exit the lock */
+	InterlockedExchange(&_mutex, 0);
+
+	return ret;
+}
+
+git_global_st *git__global_state(void)
+{
+	void *ptr;
+
+	assert(git_atomic_get(&git__n_inits) > 0);
+
+	if ((ptr = TlsGetValue(_tls_index)) != NULL)
+		return ptr;
+
+	ptr = git__malloc(sizeof(git_global_st));
+	if (!ptr)
+		return NULL;
+
+	memset(ptr, 0x0, sizeof(git_global_st));
+	TlsSetValue(_tls_index, ptr);
+	return ptr;
+}
+
+/**
+ * Free the TLS data associated with this thread.
+ * This should only be used by the thread as it
+ * is exiting.
+ */
+void git__free_tls_data(void)
+{
+	void *ptr = TlsGetValue(_tls_index);
+	if (!ptr)
+		return;
+
+	git__global_state_cleanup(ptr);
+	git__free(ptr);
+	TlsSetValue(_tls_index, NULL);
+}
+
+#elif defined(GIT_THREADS) && defined(_POSIX_THREADS)
+
+static pthread_key_t _tls_key;
+static pthread_once_t _once_init = PTHREAD_ONCE_INIT;
+int init_error = 0;
+
+static void cb__free_status(void *st)
+{
+	git__global_state_cleanup(st);
+	git__free(st);
+}
+
+static void init_once(void)
+{
+	if ((init_error = git_mutex_init(&git__mwindow_mutex)) != 0)
+		return;
+	pthread_key_create(&_tls_key, &cb__free_status);
+
+
+	/* Initialize any other subsystems that have global state */
+	if ((init_error = git_hash_global_init()) >= 0)
+		init_error = git_sysdir_global_init();
+
+	/* OpenSSL needs to be initialized from the main thread */
+	init_ssl();
+
+	GIT_MEMORY_BARRIER;
+}
+
+int git_libgit2_init(void)
+{
+	int ret;
+
+	pthread_once(&_once_init, init_once);
+	ret = git_atomic_inc(&git__n_inits);
+
+	return init_error ? init_error : ret;
+}
+
+int git_libgit2_shutdown(void)
+{
+	void *ptr = NULL;
+	pthread_once_t new_once = PTHREAD_ONCE_INIT;
+	int ret;
+
+	if ((ret = git_atomic_dec(&git__n_inits)) != 0)
+		return ret;
+
+	/* Shut down any subsystems that have global state */
+	git__shutdown();
+	uninit_ssl();
+
+	ptr = pthread_getspecific(_tls_key);
+	pthread_setspecific(_tls_key, NULL);
+
+	git__global_state_cleanup(ptr);
+	git__free(ptr);
+
+	pthread_key_delete(_tls_key);
+	git_mutex_free(&git__mwindow_mutex);
+	_once_init = new_once;
+
+	return 0;
+}
+
+git_global_st *git__global_state(void)
+{
+	void *ptr;
+
+	assert(git_atomic_get(&git__n_inits) > 0);
+
+	if ((ptr = pthread_getspecific(_tls_key)) != NULL)
+		return ptr;
+
+	ptr = git__malloc(sizeof(git_global_st));
+	if (!ptr)
+		return NULL;
+
+	memset(ptr, 0x0, sizeof(git_global_st));
+	pthread_setspecific(_tls_key, ptr);
+	return ptr;
+}
+
+#else
+
+static git_global_st __state;
+
+int git_libgit2_init(void)
+{
+	static int ssl_inited = 0;
+
+	if (!ssl_inited) {
+		init_ssl();
+		ssl_inited = 1;
+	}
+
+	return git_atomic_inc(&git__n_inits);
+}
+
+int git_libgit2_shutdown(void)
+{
+	int ret;
+
+	/* Shut down any subsystems that have global state */
+	if ((ret = git_atomic_dec(&git__n_inits)) != 0)
+		return ret;
+
+	git__shutdown();
+	git__global_state_cleanup(&__state);
+	uninit_ssl();
+
+	return 0;
+}
+
+git_global_st *git__global_state(void)
+{
+	return &__state;
+}
+
+#endif /* GIT_THREADS */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/global.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/global.h
new file mode 100755
index 0000000..fdad6ba
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/global.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_global_h__
+#define INCLUDE_global_h__
+
+#include "common.h"
+#include "mwindow.h"
+#include "hash.h"
+
+typedef struct {
+	git_error *last_error;
+	git_error error_t;
+	char oid_fmt[GIT_OID_HEXSZ+1];
+} git_global_st;
+
+#ifdef GIT_OPENSSL
+# include <openssl/ssl.h>
+extern SSL_CTX *git__ssl_ctx;
+#endif
+
+git_global_st *git__global_state(void);
+
+extern git_mutex git__mwindow_mutex;
+
+#define GIT_GLOBAL (git__global_state())
+
+typedef void (*git_global_shutdown_fn)(void);
+
+extern void git__on_shutdown(git_global_shutdown_fn callback);
+
+extern void git__free_tls_data(void);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/graph.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/graph.c
new file mode 100755
index 0000000..8accd80
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/graph.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "revwalk.h"
+#include "merge.h"
+#include "git2/graph.h"
+
+static int interesting(git_pqueue *list, git_commit_list *roots)
+{
+	unsigned int i;
+
+	for (i = 0; i < git_pqueue_size(list); i++) {
+		git_commit_list_node *commit = git_pqueue_get(list, i);
+		if ((commit->flags & STALE) == 0)
+			return 1;
+	}
+
+	while(roots) {
+		if ((roots->item->flags & STALE) == 0)
+			return 1;
+		roots = roots->next;
+	}
+
+	return 0;
+}
+
+static int mark_parents(git_revwalk *walk, git_commit_list_node *one,
+	git_commit_list_node *two)
+{
+	unsigned int i;
+	git_commit_list *roots = NULL;
+	git_pqueue list;
+
+	/* if the commit is repeated, we have a our merge base already */
+	if (one == two) {
+		one->flags |= PARENT1 | PARENT2 | RESULT;
+		return 0;
+	}
+
+	if (git_pqueue_init(&list, 0, 2, git_commit_list_time_cmp) < 0)
+		return -1;
+
+	if (git_commit_list_parse(walk, one) < 0)
+		goto on_error;
+	one->flags |= PARENT1;
+	if (git_pqueue_insert(&list, one) < 0)
+		goto on_error;
+
+	if (git_commit_list_parse(walk, two) < 0)
+		goto on_error;
+	two->flags |= PARENT2;
+	if (git_pqueue_insert(&list, two) < 0)
+		goto on_error;
+
+	/* as long as there are non-STALE commits */
+	while (interesting(&list, roots)) {
+		git_commit_list_node *commit = git_pqueue_pop(&list);
+		int flags;
+
+		if (commit == NULL)
+			break;
+
+		flags = commit->flags & (PARENT1 | PARENT2 | STALE);
+		if (flags == (PARENT1 | PARENT2)) {
+			if (!(commit->flags & RESULT))
+				commit->flags |= RESULT;
+			/* we mark the parents of a merge stale */
+			flags |= STALE;
+		}
+
+		for (i = 0; i < commit->out_degree; i++) {
+			git_commit_list_node *p = commit->parents[i];
+			if ((p->flags & flags) == flags)
+				continue;
+
+			if (git_commit_list_parse(walk, p) < 0)
+				goto on_error;
+
+			p->flags |= flags;
+			if (git_pqueue_insert(&list, p) < 0)
+				goto on_error;
+		}
+
+		/* Keep track of root commits, to make sure the path gets marked */
+		if (commit->out_degree == 0) {
+			if (git_commit_list_insert(commit, &roots) == NULL)
+				goto on_error;
+		}
+	}
+
+	git_commit_list_free(&roots);
+	git_pqueue_free(&list);
+	return 0;
+
+on_error:
+	git_commit_list_free(&roots);
+	git_pqueue_free(&list);
+	return -1;
+}
+
+
+static int ahead_behind(git_commit_list_node *one, git_commit_list_node *two,
+	size_t *ahead, size_t *behind)
+{
+	git_commit_list_node *commit;
+	git_pqueue pq;
+	int error = 0, i;
+	*ahead = 0;
+	*behind = 0;
+
+	if (git_pqueue_init(&pq, 0, 2, git_commit_list_time_cmp) < 0)
+		return -1;
+
+	if ((error = git_pqueue_insert(&pq, one)) < 0 ||
+		(error = git_pqueue_insert(&pq, two)) < 0)
+		goto done;
+
+	while ((commit = git_pqueue_pop(&pq)) != NULL) {
+		if (commit->flags & RESULT ||
+			(commit->flags & (PARENT1 | PARENT2)) == (PARENT1 | PARENT2))
+			continue;
+		else if (commit->flags & PARENT1)
+			(*ahead)++;
+		else if (commit->flags & PARENT2)
+			(*behind)++;
+
+		for (i = 0; i < commit->out_degree; i++) {
+			git_commit_list_node *p = commit->parents[i];
+			if ((error = git_pqueue_insert(&pq, p)) < 0)
+				goto done;
+		}
+		commit->flags |= RESULT;
+	}
+
+done:
+	git_pqueue_free(&pq);
+	return error;
+}
+
+int git_graph_ahead_behind(size_t *ahead, size_t *behind, git_repository *repo,
+	const git_oid *local, const git_oid *upstream)
+{
+	git_revwalk *walk;
+	git_commit_list_node *commit_u, *commit_l;
+
+	if (git_revwalk_new(&walk, repo) < 0)
+		return -1;
+
+	commit_u = git_revwalk__commit_lookup(walk, upstream);
+	if (commit_u == NULL)
+		goto on_error;
+
+	commit_l = git_revwalk__commit_lookup(walk, local);
+	if (commit_l == NULL)
+		goto on_error;
+
+	if (mark_parents(walk, commit_l, commit_u) < 0)
+		goto on_error;
+	if (ahead_behind(commit_l, commit_u, ahead, behind) < 0)
+		goto on_error;
+
+	git_revwalk_free(walk);
+
+	return 0;
+
+on_error:
+	git_revwalk_free(walk);
+	return -1;
+}
+
+int git_graph_descendant_of(git_repository *repo, const git_oid *commit, const git_oid *ancestor)
+{
+	git_oid merge_base;
+	int error;
+
+	if (git_oid_equal(commit, ancestor))
+		return 0;
+
+	error = git_merge_base(&merge_base, repo, commit, ancestor);
+	/* No merge-base found, it's not a descendant */
+	if (error == GIT_ENOTFOUND)
+		return 0;
+
+	if (error < 0)
+		return error;
+
+	return git_oid_equal(&merge_base, ancestor);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash.c
new file mode 100755
index 0000000..f3645a9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "hash.h"
+
+int git_hash_buf(git_oid *out, const void *data, size_t len)
+{
+	git_hash_ctx ctx;
+	int error = 0;
+
+	if (git_hash_ctx_init(&ctx) < 0)
+		return -1;
+
+	if ((error = git_hash_update(&ctx, data, len)) >= 0)
+		error = git_hash_final(out, &ctx);
+
+	git_hash_ctx_cleanup(&ctx);
+	
+	return error;
+}
+
+int git_hash_vec(git_oid *out, git_buf_vec *vec, size_t n)
+{
+	git_hash_ctx ctx;
+	size_t i;
+	int error = 0;
+
+	if (git_hash_ctx_init(&ctx) < 0)
+		return -1;
+
+	for (i = 0; i < n; i++) {
+		if ((error = git_hash_update(&ctx, vec[i].data, vec[i].len)) < 0)
+			goto done;
+	}
+
+	error = git_hash_final(out, &ctx);
+
+done:
+	git_hash_ctx_cleanup(&ctx);
+
+	return error;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash.h
new file mode 100755
index 0000000..0bc02a8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_hash_h__
+#define INCLUDE_hash_h__
+
+#include "git2/oid.h"
+
+typedef struct git_hash_prov git_hash_prov;
+typedef struct git_hash_ctx git_hash_ctx;
+
+int git_hash_global_init(void);
+int git_hash_ctx_init(git_hash_ctx *ctx);
+void git_hash_ctx_cleanup(git_hash_ctx *ctx);
+
+#if defined(GIT_COMMON_CRYPTO)
+# include "hash/hash_common_crypto.h"
+#elif defined(OPENSSL_SHA1)
+# include "hash/hash_openssl.h"
+#elif defined(WIN32_SHA1)
+# include "hash/hash_win32.h"
+#else
+# include "hash/hash_generic.h"
+#endif
+
+typedef struct {
+	void *data;
+	size_t len;
+} git_buf_vec;
+
+int git_hash_init(git_hash_ctx *c);
+int git_hash_update(git_hash_ctx *c, const void *data, size_t len);
+int git_hash_final(git_oid *out, git_hash_ctx *c);
+
+int git_hash_buf(git_oid *out, const void *data, size_t len);
+int git_hash_vec(git_oid *out, git_buf_vec *vec, size_t n);
+
+#endif /* INCLUDE_hash_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_common_crypto.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_common_crypto.h
new file mode 100755
index 0000000..eeeddd0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_common_crypto.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_hash_common_crypto_h__
+#define INCLUDE_hash_common_crypto_h__
+
+#include "hash.h"
+
+#include <CommonCrypto/CommonDigest.h>
+
+struct git_hash_ctx {
+	CC_SHA1_CTX c;
+};
+
+#define git_hash_global_init() 0
+#define git_hash_ctx_init(ctx) git_hash_init(ctx)
+#define git_hash_ctx_cleanup(ctx)
+
+GIT_INLINE(int) git_hash_init(git_hash_ctx *ctx)
+{
+	assert(ctx);
+	CC_SHA1_Init(&ctx->c);
+	return 0;
+}
+
+GIT_INLINE(int) git_hash_update(git_hash_ctx *ctx, const void *data, size_t len)
+{
+	assert(ctx);
+	CC_SHA1_Update(&ctx->c, data, len);
+	return 0;
+}
+
+GIT_INLINE(int) git_hash_final(git_oid *out, git_hash_ctx *ctx)
+{
+	assert(ctx);
+	CC_SHA1_Final(out->id, &ctx->c);
+	return 0;
+}
+
+#endif /* INCLUDE_hash_common_crypto_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_generic.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_generic.c
new file mode 100755
index 0000000..472a7a6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_generic.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "hash.h"
+#include "hash/hash_generic.h"
+
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+
+/*
+ * Force usage of rol or ror by selecting the one with the smaller constant.
+ * It _can_ generate slightly smaller code (a constant of 1 is special), but
+ * perhaps more importantly it's possibly faster on any uarch that does a
+ * rotate with a loop.
+ */
+
+#define SHA_ASM(op, x, n) (__extension__ ({ unsigned int __res; __asm__(op " %1,%0":"=r" (__res):"i" (n), "0" (x)); __res; }))
+#define SHA_ROL(x,n)	SHA_ASM("rol", x, n)
+#define SHA_ROR(x,n)	SHA_ASM("ror", x, n)
+
+#else
+
+#define SHA_ROT(X,l,r)	(((X) << (l)) | ((X) >> (r)))
+#define SHA_ROL(X,n)	SHA_ROT(X,n,32-(n))
+#define SHA_ROR(X,n)	SHA_ROT(X,32-(n),n)
+
+#endif
+
+/*
+ * If you have 32 registers or more, the compiler can (and should)
+ * try to change the array[] accesses into registers. However, on
+ * machines with less than ~25 registers, that won't really work,
+ * and at least gcc will make an unholy mess of it.
+ *
+ * So to avoid that mess which just slows things down, we force
+ * the stores to memory to actually happen (we might be better off
+ * with a 'W(t)=(val);asm("":"+m" (W(t))' there instead, as
+ * suggested by Artur Skawina - that will also make gcc unable to
+ * try to do the silly "optimize away loads" part because it won't
+ * see what the value will be).
+ *
+ * Ben Herrenschmidt reports that on PPC, the C version comes close
+ * to the optimized asm with this (ie on PPC you don't want that
+ * 'volatile', since there are lots of registers).
+ *
+ * On ARM we get the best code generation by forcing a full memory barrier
+ * between each SHA_ROUND, otherwise gcc happily get wild with spilling and
+ * the stack frame size simply explode and performance goes down the drain.
+ */
+
+#if defined(__i386__) || defined(__x86_64__)
+ #define setW(x, val) (*(volatile unsigned int *)&W(x) = (val))
+#elif defined(__GNUC__) && defined(__arm__)
+ #define setW(x, val) do { W(x) = (val); __asm__("":::"memory"); } while (0)
+#else
+ #define setW(x, val) (W(x) = (val))
+#endif
+
+/*
+ * Performance might be improved if the CPU architecture is OK with
+ * unaligned 32-bit loads and a fast ntohl() is available.
+ * Otherwise fall back to byte loads and shifts which is portable,
+ * and is faster on architectures with memory alignment issues.
+ */
+
+#if defined(__i386__) || defined(__x86_64__) || \
+	defined(_M_IX86) || defined(_M_X64) || \
+	defined(__ppc__) || defined(__ppc64__) || \
+	defined(__powerpc__) || defined(__powerpc64__) || \
+	defined(__s390__) || defined(__s390x__)
+
+#define get_be32(p)	ntohl(*(const unsigned int *)(p))
+#define put_be32(p, v)	do { *(unsigned int *)(p) = htonl(v); } while (0)
+
+#else
+
+#define get_be32(p)	( \
+	(*((const unsigned char *)(p) + 0) << 24) | \
+	(*((const unsigned char *)(p) + 1) << 16) | \
+	(*((const unsigned char *)(p) + 2) << 8) | \
+	(*((const unsigned char *)(p) + 3) << 0) )
+#define put_be32(p, v)	do { \
+	unsigned int __v = (v); \
+	*((unsigned char *)(p) + 0) = __v >> 24; \
+	*((unsigned char *)(p) + 1) = __v >> 16; \
+	*((unsigned char *)(p) + 2) = __v >> 8; \
+	*((unsigned char *)(p) + 3) = __v >> 0; } while (0)
+
+#endif
+
+/* This "rolls" over the 512-bit array */
+#define W(x) (array[(x)&15])
+
+/*
+ * Where do we get the source from? The first 16 iterations get it from
+ * the input data, the next mix it from the 512-bit array.
+ */
+#define SHA_SRC(t) get_be32(data + t)
+#define SHA_MIX(t) SHA_ROL(W(t+13) ^ W(t+8) ^ W(t+2) ^ W(t), 1)
+
+#define SHA_ROUND(t, input, fn, constant, A, B, C, D, E) do { \
+	unsigned int TEMP = input(t); setW(t, TEMP); \
+	E += TEMP + SHA_ROL(A,5) + (fn) + (constant); \
+	B = SHA_ROR(B, 2); } while (0)
+
+#define T_0_15(t, A, B, C, D, E) SHA_ROUND(t, SHA_SRC, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )
+#define T_16_19(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )
+#define T_20_39(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0x6ed9eba1, A, B, C, D, E )
+#define T_40_59(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, ((B&C)+(D&(B^C))) , 0x8f1bbcdc, A, B, C, D, E )
+#define T_60_79(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0xca62c1d6, A, B, C, D, E )
+
+static void hash__block(git_hash_ctx *ctx, const unsigned int *data)
+{
+	unsigned int A,B,C,D,E;
+	unsigned int array[16];
+
+	A = ctx->H[0];
+	B = ctx->H[1];
+	C = ctx->H[2];
+	D = ctx->H[3];
+	E = ctx->H[4];
+
+	/* Round 1 - iterations 0-16 take their input from 'data' */
+	T_0_15( 0, A, B, C, D, E);
+	T_0_15( 1, E, A, B, C, D);
+	T_0_15( 2, D, E, A, B, C);
+	T_0_15( 3, C, D, E, A, B);
+	T_0_15( 4, B, C, D, E, A);
+	T_0_15( 5, A, B, C, D, E);
+	T_0_15( 6, E, A, B, C, D);
+	T_0_15( 7, D, E, A, B, C);
+	T_0_15( 8, C, D, E, A, B);
+	T_0_15( 9, B, C, D, E, A);
+	T_0_15(10, A, B, C, D, E);
+	T_0_15(11, E, A, B, C, D);
+	T_0_15(12, D, E, A, B, C);
+	T_0_15(13, C, D, E, A, B);
+	T_0_15(14, B, C, D, E, A);
+	T_0_15(15, A, B, C, D, E);
+
+	/* Round 1 - tail. Input from 512-bit mixing array */
+	T_16_19(16, E, A, B, C, D);
+	T_16_19(17, D, E, A, B, C);
+	T_16_19(18, C, D, E, A, B);
+	T_16_19(19, B, C, D, E, A);
+
+	/* Round 2 */
+	T_20_39(20, A, B, C, D, E);
+	T_20_39(21, E, A, B, C, D);
+	T_20_39(22, D, E, A, B, C);
+	T_20_39(23, C, D, E, A, B);
+	T_20_39(24, B, C, D, E, A);
+	T_20_39(25, A, B, C, D, E);
+	T_20_39(26, E, A, B, C, D);
+	T_20_39(27, D, E, A, B, C);
+	T_20_39(28, C, D, E, A, B);
+	T_20_39(29, B, C, D, E, A);
+	T_20_39(30, A, B, C, D, E);
+	T_20_39(31, E, A, B, C, D);
+	T_20_39(32, D, E, A, B, C);
+	T_20_39(33, C, D, E, A, B);
+	T_20_39(34, B, C, D, E, A);
+	T_20_39(35, A, B, C, D, E);
+	T_20_39(36, E, A, B, C, D);
+	T_20_39(37, D, E, A, B, C);
+	T_20_39(38, C, D, E, A, B);
+	T_20_39(39, B, C, D, E, A);
+
+	/* Round 3 */
+	T_40_59(40, A, B, C, D, E);
+	T_40_59(41, E, A, B, C, D);
+	T_40_59(42, D, E, A, B, C);
+	T_40_59(43, C, D, E, A, B);
+	T_40_59(44, B, C, D, E, A);
+	T_40_59(45, A, B, C, D, E);
+	T_40_59(46, E, A, B, C, D);
+	T_40_59(47, D, E, A, B, C);
+	T_40_59(48, C, D, E, A, B);
+	T_40_59(49, B, C, D, E, A);
+	T_40_59(50, A, B, C, D, E);
+	T_40_59(51, E, A, B, C, D);
+	T_40_59(52, D, E, A, B, C);
+	T_40_59(53, C, D, E, A, B);
+	T_40_59(54, B, C, D, E, A);
+	T_40_59(55, A, B, C, D, E);
+	T_40_59(56, E, A, B, C, D);
+	T_40_59(57, D, E, A, B, C);
+	T_40_59(58, C, D, E, A, B);
+	T_40_59(59, B, C, D, E, A);
+
+	/* Round 4 */
+	T_60_79(60, A, B, C, D, E);
+	T_60_79(61, E, A, B, C, D);
+	T_60_79(62, D, E, A, B, C);
+	T_60_79(63, C, D, E, A, B);
+	T_60_79(64, B, C, D, E, A);
+	T_60_79(65, A, B, C, D, E);
+	T_60_79(66, E, A, B, C, D);
+	T_60_79(67, D, E, A, B, C);
+	T_60_79(68, C, D, E, A, B);
+	T_60_79(69, B, C, D, E, A);
+	T_60_79(70, A, B, C, D, E);
+	T_60_79(71, E, A, B, C, D);
+	T_60_79(72, D, E, A, B, C);
+	T_60_79(73, C, D, E, A, B);
+	T_60_79(74, B, C, D, E, A);
+	T_60_79(75, A, B, C, D, E);
+	T_60_79(76, E, A, B, C, D);
+	T_60_79(77, D, E, A, B, C);
+	T_60_79(78, C, D, E, A, B);
+	T_60_79(79, B, C, D, E, A);
+
+	ctx->H[0] += A;
+	ctx->H[1] += B;
+	ctx->H[2] += C;
+	ctx->H[3] += D;
+	ctx->H[4] += E;
+}
+
+int git_hash_init(git_hash_ctx *ctx)
+{
+	ctx->size = 0;
+
+	/* Initialize H with the magic constants (see FIPS180 for constants) */
+	ctx->H[0] = 0x67452301;
+	ctx->H[1] = 0xefcdab89;
+	ctx->H[2] = 0x98badcfe;
+	ctx->H[3] = 0x10325476;
+	ctx->H[4] = 0xc3d2e1f0;
+
+	return 0;
+}
+
+int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len)
+{
+	unsigned int lenW = ctx->size & 63;
+
+	ctx->size += len;
+
+	/* Read the data into W and process blocks as they get full */
+	if (lenW) {
+		unsigned int left = 64 - lenW;
+		if (len < left)
+			left = (unsigned int)len;
+		memcpy(lenW + (char *)ctx->W, data, left);
+		lenW = (lenW + left) & 63;
+		len -= left;
+		data = ((const char *)data + left);
+		if (lenW)
+			return 0;
+		hash__block(ctx, ctx->W);
+	}
+	while (len >= 64) {
+		hash__block(ctx, data);
+		data = ((const char *)data + 64);
+		len -= 64;
+	}
+	if (len)
+		memcpy(ctx->W, data, len);
+
+	return 0;
+}
+
+int git_hash_final(git_oid *out, git_hash_ctx *ctx)
+{
+	static const unsigned char pad[64] = { 0x80 };
+	unsigned int padlen[2];
+	int i;
+
+	/* Pad with a binary 1 (ie 0x80), then zeroes, then length */
+	padlen[0] = htonl((uint32_t)(ctx->size >> 29));
+	padlen[1] = htonl((uint32_t)(ctx->size << 3));
+
+	i = ctx->size & 63;
+	git_hash_update(ctx, pad, 1+ (63 & (55 - i)));
+	git_hash_update(ctx, padlen, 8);
+
+	/* Output hash */
+	for (i = 0; i < 5; i++)
+		put_be32(out->id + i*4, ctx->H[i]);
+
+	return 0;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_generic.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_generic.h
new file mode 100755
index 0000000..daeb1cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_generic.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_hash_generic_h__
+#define INCLUDE_hash_generic_h__
+
+#include "hash.h"
+
+struct git_hash_ctx {
+	unsigned long long size;
+	unsigned int H[5];
+	unsigned int W[16];
+};
+
+#define git_hash_global_init() 0
+#define git_hash_ctx_init(ctx) git_hash_init(ctx)
+#define git_hash_ctx_cleanup(ctx)
+
+#endif /* INCLUDE_hash_generic_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_openssl.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_openssl.h
new file mode 100755
index 0000000..9a55d47
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_openssl.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_hash_openssl_h__
+#define INCLUDE_hash_openssl_h__
+
+#include "hash.h"
+
+#include <openssl/sha.h>
+
+struct git_hash_ctx {
+	SHA_CTX c;
+};
+
+#define git_hash_global_init() 0
+#define git_hash_ctx_init(ctx) git_hash_init(ctx)
+#define git_hash_ctx_cleanup(ctx)
+
+GIT_INLINE(int) git_hash_init(git_hash_ctx *ctx)
+{
+	assert(ctx);
+	SHA1_Init(&ctx->c);
+	return 0;
+}
+
+GIT_INLINE(int) git_hash_update(git_hash_ctx *ctx, const void *data, size_t len)
+{
+	assert(ctx);
+	SHA1_Update(&ctx->c, data, len);
+	return 0;
+}
+
+GIT_INLINE(int) git_hash_final(git_oid *out, git_hash_ctx *ctx)
+{
+	assert(ctx);
+	SHA1_Final(out->id, &ctx->c);
+	return 0;
+}
+
+#endif /* INCLUDE_hash_openssl_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_win32.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_win32.c
new file mode 100755
index 0000000..6bae53e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_win32.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "global.h"
+#include "hash.h"
+#include "hash/hash_win32.h"
+
+#include <wincrypt.h>
+#include <strsafe.h>
+
+static struct git_hash_prov hash_prov = {0};
+
+/* Hash initialization */
+
+/* Initialize CNG, if available */
+GIT_INLINE(int) hash_cng_prov_init(void)
+{
+	char dll_path[MAX_PATH];
+	DWORD dll_path_len, size_len;
+
+	/* Only use CNG on Windows 2008 / Vista SP1  or better (Windows 6.0 SP1) */
+	if (!git_has_win32_version(6, 0, 1))
+		return -1;
+
+	/* Load bcrypt.dll explicitly from the system directory */
+	if ((dll_path_len = GetSystemDirectory(dll_path, MAX_PATH)) == 0 ||
+		dll_path_len > MAX_PATH ||
+		StringCchCat(dll_path, MAX_PATH, "\\") < 0 ||
+		StringCchCat(dll_path, MAX_PATH, GIT_HASH_CNG_DLL_NAME) < 0 ||
+		(hash_prov.prov.cng.dll = LoadLibrary(dll_path)) == NULL)
+		return -1;
+
+	/* Load the function addresses */
+	if ((hash_prov.prov.cng.open_algorithm_provider = (hash_win32_cng_open_algorithm_provider_fn)GetProcAddress(hash_prov.prov.cng.dll, "BCryptOpenAlgorithmProvider")) == NULL ||
+		(hash_prov.prov.cng.get_property = (hash_win32_cng_get_property_fn)GetProcAddress(hash_prov.prov.cng.dll, "BCryptGetProperty")) == NULL ||
+		(hash_prov.prov.cng.create_hash = (hash_win32_cng_create_hash_fn)GetProcAddress(hash_prov.prov.cng.dll, "BCryptCreateHash")) == NULL ||
+		(hash_prov.prov.cng.finish_hash = (hash_win32_cng_finish_hash_fn)GetProcAddress(hash_prov.prov.cng.dll, "BCryptFinishHash")) == NULL ||
+		(hash_prov.prov.cng.hash_data = (hash_win32_cng_hash_data_fn)GetProcAddress(hash_prov.prov.cng.dll, "BCryptHashData")) == NULL ||
+		(hash_prov.prov.cng.destroy_hash = (hash_win32_cng_destroy_hash_fn)GetProcAddress(hash_prov.prov.cng.dll, "BCryptDestroyHash")) == NULL ||
+		(hash_prov.prov.cng.close_algorithm_provider = (hash_win32_cng_close_algorithm_provider_fn)GetProcAddress(hash_prov.prov.cng.dll, "BCryptCloseAlgorithmProvider")) == NULL) {
+		FreeLibrary(hash_prov.prov.cng.dll);
+		return -1;
+	}
+
+	/* Load the SHA1 algorithm */
+	if (hash_prov.prov.cng.open_algorithm_provider(&hash_prov.prov.cng.handle, GIT_HASH_CNG_HASH_TYPE, NULL, GIT_HASH_CNG_HASH_REUSABLE) < 0) {
+		FreeLibrary(hash_prov.prov.cng.dll);
+		return -1;
+	}
+
+	/* Get storage space for the hash object */
+	if (hash_prov.prov.cng.get_property(hash_prov.prov.cng.handle, GIT_HASH_CNG_HASH_OBJECT_LEN, (PBYTE)&hash_prov.prov.cng.hash_object_size, sizeof(DWORD), &size_len, 0) < 0) {
+		hash_prov.prov.cng.close_algorithm_provider(hash_prov.prov.cng.handle, 0);
+		FreeLibrary(hash_prov.prov.cng.dll);
+		return -1;
+	}
+
+	hash_prov.type = CNG;
+	return 0;
+}
+
+GIT_INLINE(void) hash_cng_prov_shutdown(void)
+{
+	hash_prov.prov.cng.close_algorithm_provider(hash_prov.prov.cng.handle, 0);
+	FreeLibrary(hash_prov.prov.cng.dll);
+
+	hash_prov.type = INVALID;
+}
+
+/* Initialize CryptoAPI */
+GIT_INLINE(int) hash_cryptoapi_prov_init()
+{
+	if (!CryptAcquireContext(&hash_prov.prov.cryptoapi.handle, NULL, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
+		return -1;
+
+	hash_prov.type = CRYPTOAPI;
+	return 0;
+}
+
+GIT_INLINE(void) hash_cryptoapi_prov_shutdown(void)
+{
+	CryptReleaseContext(hash_prov.prov.cryptoapi.handle, 0);
+
+	hash_prov.type = INVALID;
+}
+
+static void git_hash_global_shutdown(void)
+{
+	if (hash_prov.type == CNG)
+		hash_cng_prov_shutdown();
+	else if(hash_prov.type == CRYPTOAPI)
+		hash_cryptoapi_prov_shutdown();
+}
+
+int git_hash_global_init(void)
+{
+	int error = 0;
+
+	if (hash_prov.type != INVALID)
+		return 0;
+
+	if ((error = hash_cng_prov_init()) < 0)
+		error = hash_cryptoapi_prov_init();
+
+	git__on_shutdown(git_hash_global_shutdown);
+
+	return error;
+}
+
+/* CryptoAPI: available in Windows XP and newer */
+
+GIT_INLINE(int) hash_ctx_cryptoapi_init(git_hash_ctx *ctx)
+{
+	ctx->type = CRYPTOAPI;
+	ctx->prov = &hash_prov;
+
+	return git_hash_init(ctx);
+}
+
+GIT_INLINE(int) hash_cryptoapi_init(git_hash_ctx *ctx)
+{
+	if (ctx->ctx.cryptoapi.valid)
+		CryptDestroyHash(ctx->ctx.cryptoapi.hash_handle);
+
+	if (!CryptCreateHash(ctx->prov->prov.cryptoapi.handle, CALG_SHA1, 0, 0, &ctx->ctx.cryptoapi.hash_handle)) {
+		ctx->ctx.cryptoapi.valid = 0;
+		return -1;
+	}
+
+	ctx->ctx.cryptoapi.valid = 1;
+	return 0;
+}
+
+GIT_INLINE(int) hash_cryptoapi_update(git_hash_ctx *ctx, const void *data, size_t len)
+{
+	assert(ctx->ctx.cryptoapi.valid);
+
+	if (!CryptHashData(ctx->ctx.cryptoapi.hash_handle, (const BYTE *)data, (DWORD)len, 0))
+		return -1;
+
+	return 0;
+}
+
+GIT_INLINE(int) hash_cryptoapi_final(git_oid *out, git_hash_ctx *ctx)
+{
+	DWORD len = 20;
+	int error = 0;
+
+	assert(ctx->ctx.cryptoapi.valid);
+
+	if (!CryptGetHashParam(ctx->ctx.cryptoapi.hash_handle, HP_HASHVAL, out->id, &len, 0))
+		error = -1;
+
+	CryptDestroyHash(ctx->ctx.cryptoapi.hash_handle);
+	ctx->ctx.cryptoapi.valid = 0;
+
+	return error;
+}
+
+GIT_INLINE(void) hash_ctx_cryptoapi_cleanup(git_hash_ctx *ctx)
+{
+	if (ctx->ctx.cryptoapi.valid)
+		CryptDestroyHash(ctx->ctx.cryptoapi.hash_handle);
+}
+
+/* CNG: Available in Windows Server 2008 and newer */
+
+GIT_INLINE(int) hash_ctx_cng_init(git_hash_ctx *ctx)
+{
+	if ((ctx->ctx.cng.hash_object = git__malloc(hash_prov.prov.cng.hash_object_size)) == NULL)
+		return -1;
+
+	if (hash_prov.prov.cng.create_hash(hash_prov.prov.cng.handle, &ctx->ctx.cng.hash_handle, ctx->ctx.cng.hash_object, hash_prov.prov.cng.hash_object_size, NULL, 0, 0) < 0) {
+		git__free(ctx->ctx.cng.hash_object);
+		return -1;
+	}
+
+	ctx->type = CNG;
+	ctx->prov = &hash_prov;
+
+	return 0;
+}
+
+GIT_INLINE(int) hash_cng_init(git_hash_ctx *ctx)
+{
+	BYTE hash[GIT_OID_RAWSZ];
+
+	if (!ctx->ctx.cng.updated)
+		return 0;
+
+	/* CNG needs to be finished to restart */
+	if (ctx->prov->prov.cng.finish_hash(ctx->ctx.cng.hash_handle, hash, GIT_OID_RAWSZ, 0) < 0)
+		return -1;
+
+	ctx->ctx.cng.updated = 0;
+
+	return 0;
+}
+
+GIT_INLINE(int) hash_cng_update(git_hash_ctx *ctx, const void *data, size_t len)
+{
+	if (ctx->prov->prov.cng.hash_data(ctx->ctx.cng.hash_handle, (PBYTE)data, (ULONG)len, 0) < 0)
+		return -1;
+
+	return 0;
+}
+
+GIT_INLINE(int) hash_cng_final(git_oid *out, git_hash_ctx *ctx)
+{
+	if (ctx->prov->prov.cng.finish_hash(ctx->ctx.cng.hash_handle, out->id, GIT_OID_RAWSZ, 0) < 0)
+		return -1;
+
+	ctx->ctx.cng.updated = 0;
+
+	return 0;
+}
+
+GIT_INLINE(void) hash_ctx_cng_cleanup(git_hash_ctx *ctx)
+{
+	ctx->prov->prov.cng.destroy_hash(ctx->ctx.cng.hash_handle);
+	git__free(ctx->ctx.cng.hash_object);
+}
+
+/* Indirection between CryptoAPI and CNG */
+
+int git_hash_ctx_init(git_hash_ctx *ctx)
+{
+	int error = 0;
+
+	assert(ctx);
+
+	/*
+	 * When compiled with GIT_THREADS, the global hash_prov data is
+	 * initialized with git_libgit2_init.  Otherwise, it must be initialized
+	 * at first use.
+	 */
+	if (hash_prov.type == INVALID && (error = git_hash_global_init()) < 0)
+		return error;
+
+	memset(ctx, 0x0, sizeof(git_hash_ctx));
+
+	return (hash_prov.type == CNG) ? hash_ctx_cng_init(ctx) : hash_ctx_cryptoapi_init(ctx);
+}
+
+int git_hash_init(git_hash_ctx *ctx)
+{
+	assert(ctx && ctx->type);
+	return (ctx->type == CNG) ? hash_cng_init(ctx) : hash_cryptoapi_init(ctx);
+}
+
+int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len)
+{
+	assert(ctx && ctx->type);
+	return (ctx->type == CNG) ? hash_cng_update(ctx, data, len) : hash_cryptoapi_update(ctx, data, len);
+}
+
+int git_hash_final(git_oid *out, git_hash_ctx *ctx)
+{
+	assert(ctx && ctx->type);
+	return (ctx->type == CNG) ? hash_cng_final(out, ctx) : hash_cryptoapi_final(out, ctx);
+}
+
+void git_hash_ctx_cleanup(git_hash_ctx *ctx)
+{
+	assert(ctx);
+
+	if (ctx->type == CNG)
+		hash_ctx_cng_cleanup(ctx);
+	else if(ctx->type == CRYPTOAPI)
+		hash_ctx_cryptoapi_cleanup(ctx);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_win32.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_win32.h
new file mode 100755
index 0000000..2eee5ca
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hash/hash_win32.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_hash_win32_h__
+#define INCLUDE_hash_win32_h__
+
+#include "common.h"
+#include "hash.h"
+
+#include <wincrypt.h>
+#include <strsafe.h>
+
+enum hash_win32_prov_type {
+	INVALID = 0,
+	CRYPTOAPI,
+	CNG
+};
+
+/*
+ * CryptoAPI is available for hashing on Windows XP and newer.
+ */
+
+struct hash_cryptoapi_prov {
+	HCRYPTPROV handle;
+};
+
+/*
+ * CNG (bcrypt.dll) is significantly more performant than CryptoAPI and is
+ * preferred, however it is only available on Windows 2008 and newer and
+ * must therefore be dynamically loaded, and we must inline constants that
+ * would not exist when building in pre-Windows 2008 environments.
+ */
+
+#define GIT_HASH_CNG_DLL_NAME           "bcrypt.dll"
+
+/* BCRYPT_SHA1_ALGORITHM */
+#define GIT_HASH_CNG_HASH_TYPE          L"SHA1"
+
+/* BCRYPT_OBJECT_LENGTH */
+#define GIT_HASH_CNG_HASH_OBJECT_LEN    L"ObjectLength"
+
+/* BCRYPT_HASH_REUSEABLE_FLAGS */
+#define GIT_HASH_CNG_HASH_REUSABLE      0x00000020
+
+/* Function declarations for CNG */
+typedef NTSTATUS (WINAPI *hash_win32_cng_open_algorithm_provider_fn)(
+	HANDLE /* BCRYPT_ALG_HANDLE */ *phAlgorithm,
+	LPCWSTR pszAlgId,
+	LPCWSTR pszImplementation,
+	DWORD dwFlags);
+
+typedef NTSTATUS (WINAPI *hash_win32_cng_get_property_fn)(
+	HANDLE /* BCRYPT_HANDLE */ hObject,
+	LPCWSTR pszProperty,
+	PUCHAR pbOutput,
+	ULONG cbOutput,
+	ULONG *pcbResult,
+	ULONG dwFlags);
+
+typedef NTSTATUS (WINAPI *hash_win32_cng_create_hash_fn)(
+	HANDLE /* BCRYPT_ALG_HANDLE */ hAlgorithm,
+	HANDLE /* BCRYPT_HASH_HANDLE */ *phHash,
+	PUCHAR pbHashObject, ULONG cbHashObject,
+	PUCHAR pbSecret,
+	ULONG cbSecret,
+	ULONG dwFlags);
+
+typedef NTSTATUS (WINAPI *hash_win32_cng_finish_hash_fn)(
+	HANDLE /* BCRYPT_HASH_HANDLE */ hHash,
+	PUCHAR pbOutput,
+	ULONG cbOutput,
+	ULONG dwFlags);
+
+typedef NTSTATUS (WINAPI *hash_win32_cng_hash_data_fn)(
+	HANDLE /* BCRYPT_HASH_HANDLE */ hHash,
+	PUCHAR pbInput,
+	ULONG cbInput,
+	ULONG dwFlags);
+
+typedef NTSTATUS (WINAPI *hash_win32_cng_destroy_hash_fn)(
+	HANDLE /* BCRYPT_HASH_HANDLE */ hHash);
+
+typedef NTSTATUS (WINAPI *hash_win32_cng_close_algorithm_provider_fn)(
+	HANDLE /* BCRYPT_ALG_HANDLE */ hAlgorithm,
+	ULONG dwFlags);
+
+struct hash_cng_prov {
+	/* DLL for CNG */
+	HINSTANCE dll;
+
+	/* Function pointers for CNG */
+	hash_win32_cng_open_algorithm_provider_fn open_algorithm_provider;
+	hash_win32_cng_get_property_fn get_property;
+	hash_win32_cng_create_hash_fn create_hash;
+	hash_win32_cng_finish_hash_fn finish_hash;
+	hash_win32_cng_hash_data_fn hash_data;
+	hash_win32_cng_destroy_hash_fn destroy_hash;
+	hash_win32_cng_close_algorithm_provider_fn close_algorithm_provider;
+
+	HANDLE /* BCRYPT_ALG_HANDLE */ handle;
+	DWORD hash_object_size;
+};
+
+struct git_hash_prov {
+	enum hash_win32_prov_type type;
+
+	union {
+		struct hash_cryptoapi_prov cryptoapi;
+		struct hash_cng_prov cng;
+	} prov;
+};
+
+/* Hash contexts */
+
+struct hash_cryptoapi_ctx {
+	bool valid;
+	HCRYPTHASH hash_handle;
+};
+
+struct hash_cng_ctx {
+	bool updated;
+	HANDLE /* BCRYPT_HASH_HANDLE */ hash_handle;
+	PBYTE hash_object;
+};
+
+struct git_hash_ctx {
+	enum hash_win32_prov_type type;
+	git_hash_prov *prov;
+
+	union {
+		struct hash_cryptoapi_ctx cryptoapi;
+		struct hash_cng_ctx cng;
+	} ctx;
+};
+
+#endif /* INCLUDE_hash_openssl_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hashsig.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hashsig.c
new file mode 100755
index 0000000..e99637d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/hashsig.c
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "git2/sys/hashsig.h"
+#include "fileops.h"
+#include "util.h"
+
+typedef uint32_t hashsig_t;
+typedef uint64_t hashsig_state;
+
+#define HASHSIG_SCALE 100
+
+#define HASHSIG_MAX_RUN 80
+#define HASHSIG_HASH_START	0x012345678ABCDEF0LL
+#define HASHSIG_HASH_SHIFT  5
+
+#define HASHSIG_HASH_MIX(S,CH) \
+	(S) = ((S) << HASHSIG_HASH_SHIFT) - (S) + (hashsig_state)(CH)
+
+#define HASHSIG_HEAP_SIZE ((1 << 7) - 1)
+#define HASHSIG_HEAP_MIN_SIZE 4
+
+typedef int (*hashsig_cmp)(const void *a, const void *b, void *);
+
+typedef struct {
+	int size, asize;
+	hashsig_cmp cmp;
+	hashsig_t values[HASHSIG_HEAP_SIZE];
+} hashsig_heap;
+
+struct git_hashsig {
+	hashsig_heap mins;
+	hashsig_heap maxs;
+	size_t lines;
+	git_hashsig_option_t opt;
+};
+
+#define HEAP_LCHILD_OF(I) (((I)<<1)+1)
+#define HEAP_RCHILD_OF(I) (((I)<<1)+2)
+#define HEAP_PARENT_OF(I) (((I)-1)>>1)
+
+static void hashsig_heap_init(hashsig_heap *h, hashsig_cmp cmp)
+{
+	h->size  = 0;
+	h->asize = HASHSIG_HEAP_SIZE;
+	h->cmp   = cmp;
+}
+
+static int hashsig_cmp_max(const void *a, const void *b, void *payload)
+{
+	hashsig_t av = *(const hashsig_t *)a, bv = *(const hashsig_t *)b;
+	GIT_UNUSED(payload);
+	return (av < bv) ? -1 : (av > bv) ? 1 : 0;
+}
+
+static int hashsig_cmp_min(const void *a, const void *b, void *payload)
+{
+	hashsig_t av = *(const hashsig_t *)a, bv = *(const hashsig_t *)b;
+	GIT_UNUSED(payload);
+	return (av > bv) ? -1 : (av < bv) ? 1 : 0;
+}
+
+static void hashsig_heap_up(hashsig_heap *h, int el)
+{
+	int parent_el = HEAP_PARENT_OF(el);
+
+	while (el > 0 && h->cmp(&h->values[parent_el], &h->values[el], NULL) > 0) {
+		hashsig_t t = h->values[el];
+		h->values[el] = h->values[parent_el];
+		h->values[parent_el] = t;
+
+		el = parent_el;
+		parent_el = HEAP_PARENT_OF(el);
+	}
+}
+
+static void hashsig_heap_down(hashsig_heap *h, int el)
+{
+	hashsig_t v, lv, rv;
+
+	/* 'el < h->size / 2' tests if el is bottom row of heap */
+
+	while (el < h->size / 2) {
+		int lel = HEAP_LCHILD_OF(el), rel = HEAP_RCHILD_OF(el), swapel;
+
+		v  = h->values[el];
+		lv = h->values[lel];
+		rv = h->values[rel];
+
+		if (h->cmp(&v, &lv, NULL) < 0 && h->cmp(&v, &rv, NULL) < 0)
+			break;
+
+		swapel = (h->cmp(&lv, &rv, NULL) < 0) ? lel : rel;
+
+		h->values[el] = h->values[swapel];
+		h->values[swapel] = v;
+
+		el = swapel;
+	}
+}
+
+static void hashsig_heap_sort(hashsig_heap *h)
+{
+	/* only need to do this at the end for signature comparison */
+	git__qsort_r(h->values, h->size, sizeof(hashsig_t), h->cmp, NULL);
+}
+
+static void hashsig_heap_insert(hashsig_heap *h, hashsig_t val)
+{
+	/* if heap is not full, insert new element */
+	if (h->size < h->asize) {
+		h->values[h->size++] = val;
+		hashsig_heap_up(h, h->size - 1);
+	}
+
+	/* if heap is full, pop top if new element should replace it */
+	else if (h->cmp(&val, &h->values[0], NULL) > 0) {
+		h->size--;
+		h->values[0] = h->values[h->size];
+		hashsig_heap_down(h, 0);
+	}
+
+}
+
+typedef struct {
+	int use_ignores;
+	uint8_t ignore_ch[256];
+} hashsig_in_progress;
+
+static void hashsig_in_progress_init(
+	hashsig_in_progress *prog, git_hashsig *sig)
+{
+	int i;
+
+	/* no more than one can be set */
+	assert(!(sig->opt & GIT_HASHSIG_IGNORE_WHITESPACE) ||
+		   !(sig->opt & GIT_HASHSIG_SMART_WHITESPACE));
+
+	if (sig->opt & GIT_HASHSIG_IGNORE_WHITESPACE) {
+		for (i = 0; i < 256; ++i)
+			prog->ignore_ch[i] = git__isspace_nonlf(i);
+		prog->use_ignores = 1;
+	} else if (sig->opt & GIT_HASHSIG_SMART_WHITESPACE) {
+		for (i = 0; i < 256; ++i)
+			prog->ignore_ch[i] = git__isspace(i);
+		prog->use_ignores = 1;
+	} else {
+		memset(prog, 0, sizeof(*prog));
+	}
+}
+
+static int hashsig_add_hashes(
+	git_hashsig *sig,
+	const uint8_t *data,
+	size_t size,
+	hashsig_in_progress *prog)
+{
+	const uint8_t *scan = data, *end = data + size;
+	hashsig_state state = HASHSIG_HASH_START;
+	int use_ignores = prog->use_ignores, len;
+	uint8_t ch;
+
+	while (scan < end) {
+		state = HASHSIG_HASH_START;
+
+		for (len = 0; scan < end && len < HASHSIG_MAX_RUN; ) {
+			ch = *scan;
+
+			if (use_ignores)
+				for (; scan < end && git__isspace_nonlf(ch); ch = *scan)
+					++scan;
+			else if (sig->opt &
+					 (GIT_HASHSIG_IGNORE_WHITESPACE | GIT_HASHSIG_SMART_WHITESPACE))
+				for (; scan < end && ch == '\r'; ch = *scan)
+					++scan;
+
+			/* peek at next character to decide what to do next */
+			if (sig->opt & GIT_HASHSIG_SMART_WHITESPACE)
+				use_ignores = (ch == '\n');
+
+			if (scan >= end)
+				break;
+			++scan;
+
+			/* check run terminator */
+			if (ch == '\n' || ch == '\0') {
+				sig->lines++;
+				break;
+			}
+
+			++len;
+			HASHSIG_HASH_MIX(state, ch);
+		}
+
+		if (len > 0) {
+			hashsig_heap_insert(&sig->mins, (hashsig_t)state);
+			hashsig_heap_insert(&sig->maxs, (hashsig_t)state);
+
+			while (scan < end && (*scan == '\n' || !*scan))
+				++scan;
+		}
+	}
+
+	prog->use_ignores = use_ignores;
+
+	return 0;
+}
+
+static int hashsig_finalize_hashes(git_hashsig *sig)
+{
+	if (sig->mins.size < HASHSIG_HEAP_MIN_SIZE &&
+		!(sig->opt & GIT_HASHSIG_ALLOW_SMALL_FILES)) {
+		giterr_set(GITERR_INVALID,
+			"File too small for similarity signature calculation");
+		return GIT_EBUFS;
+	}
+
+	hashsig_heap_sort(&sig->mins);
+	hashsig_heap_sort(&sig->maxs);
+
+	return 0;
+}
+
+static git_hashsig *hashsig_alloc(git_hashsig_option_t opts)
+{
+	git_hashsig *sig = git__calloc(1, sizeof(git_hashsig));
+	if (!sig)
+		return NULL;
+
+	hashsig_heap_init(&sig->mins, hashsig_cmp_min);
+	hashsig_heap_init(&sig->maxs, hashsig_cmp_max);
+	sig->opt = opts;
+
+	return sig;
+}
+
+int git_hashsig_create(
+	git_hashsig **out,
+	const char *buf,
+	size_t buflen,
+	git_hashsig_option_t opts)
+{
+	int error;
+	hashsig_in_progress prog;
+	git_hashsig *sig = hashsig_alloc(opts);
+	GITERR_CHECK_ALLOC(sig);
+
+	hashsig_in_progress_init(&prog, sig);
+
+	error = hashsig_add_hashes(sig, (const uint8_t *)buf, buflen, &prog);
+
+	if (!error)
+		error = hashsig_finalize_hashes(sig);
+
+	if (!error)
+		*out = sig;
+	else
+		git_hashsig_free(sig);
+
+	return error;
+}
+
+int git_hashsig_create_fromfile(
+	git_hashsig **out,
+	const char *path,
+	git_hashsig_option_t opts)
+{
+	uint8_t buf[0x1000];
+	ssize_t buflen = 0;
+	int error = 0, fd;
+	hashsig_in_progress prog;
+	git_hashsig *sig = hashsig_alloc(opts);
+	GITERR_CHECK_ALLOC(sig);
+
+	if ((fd = git_futils_open_ro(path)) < 0) {
+		git__free(sig);
+		return fd;
+	}
+
+	hashsig_in_progress_init(&prog, sig);
+
+	while (!error) {
+		if ((buflen = p_read(fd, buf, sizeof(buf))) <= 0) {
+			if ((error = (int)buflen) < 0)
+				giterr_set(GITERR_OS,
+					"Read error on '%s' calculating similarity hashes", path);
+			break;
+		}
+
+		error = hashsig_add_hashes(sig, buf, buflen, &prog);
+	}
+
+	p_close(fd);
+
+	if (!error)
+		error = hashsig_finalize_hashes(sig);
+
+	if (!error)
+		*out = sig;
+	else
+		git_hashsig_free(sig);
+
+	return error;
+}
+
+void git_hashsig_free(git_hashsig *sig)
+{
+	git__free(sig);
+}
+
+static int hashsig_heap_compare(const hashsig_heap *a, const hashsig_heap *b)
+{
+	int matches = 0, i, j, cmp;
+
+	assert(a->cmp == b->cmp);
+
+	/* hash heaps are sorted - just look for overlap vs total */
+
+	for (i = 0, j = 0; i < a->size && j < b->size; ) {
+		cmp = a->cmp(&a->values[i], &b->values[j], NULL);
+
+		if (cmp < 0)
+			++i;
+		else if (cmp > 0)
+			++j;
+		else {
+			++i; ++j; ++matches;
+		}
+	}
+
+	return HASHSIG_SCALE * (matches * 2) / (a->size + b->size);
+}
+
+int git_hashsig_compare(const git_hashsig *a, const git_hashsig *b)
+{
+	/* if we have no elements in either file then each file is either
+	 * empty or blank.  if we're ignoring whitespace then the files are
+	 * similar, otherwise they're dissimilar.
+	 */
+	if (a->mins.size == 0 && b->mins.size == 0) {
+		if ((!a->lines && !b->lines) ||
+			(a->opt & GIT_HASHSIG_IGNORE_WHITESPACE))
+			return HASHSIG_SCALE;
+		else
+			return 0;
+	}
+
+	/* if we have fewer than the maximum number of elements, then just use
+	 * one array since the two arrays will be the same
+	 */
+	if (a->mins.size < HASHSIG_HEAP_SIZE)
+		return hashsig_heap_compare(&a->mins, &b->mins);
+	else
+		return (hashsig_heap_compare(&a->mins, &b->mins) +
+				hashsig_heap_compare(&a->maxs, &b->maxs)) / 2;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/ident.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/ident.c
new file mode 100755
index 0000000..4718ed6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/ident.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2/sys/filter.h"
+#include "filter.h"
+#include "buffer.h"
+#include "buf_text.h"
+
+static int ident_find_id(
+	const char **id_start, const char **id_end, const char *start, size_t len)
+{
+	const char *end = start + len, *found = NULL;
+
+	while (len > 3 && (found = memchr(start, '$', len)) != NULL) {
+		size_t remaining = (size_t)(end - found) - 1;
+		if (remaining < 3)
+			return GIT_ENOTFOUND;
+
+		start = found + 1;
+		len   = remaining;
+
+		if (start[0] == 'I' && start[1] == 'd')
+			break;
+	}
+
+	if (len < 3 || !found)
+		return GIT_ENOTFOUND;
+	*id_start = found;
+
+	if ((found = memchr(start + 2, '$', len - 2)) == NULL)
+		return GIT_ENOTFOUND;
+
+	*id_end = found + 1;
+	return 0;
+}
+
+static int ident_insert_id(
+	git_buf *to, const git_buf *from, const git_filter_source *src)
+{
+	char oid[GIT_OID_HEXSZ+1];
+	const char *id_start, *id_end, *from_end = from->ptr + from->size;
+	size_t need_size;
+
+	/* replace $Id$ with blob id */
+
+	if (!git_filter_source_id(src))
+		return GIT_PASSTHROUGH;
+
+	git_oid_tostr(oid, sizeof(oid), git_filter_source_id(src));
+
+	if (ident_find_id(&id_start, &id_end, from->ptr, from->size) < 0)
+		return GIT_PASSTHROUGH;
+
+	need_size = (size_t)(id_start - from->ptr) +
+		5 /* "$Id: " */ + GIT_OID_HEXSZ + 2 /* " $" */ +
+		(size_t)(from_end - id_end);
+
+	if (git_buf_grow(to, need_size) < 0)
+		return -1;
+
+	git_buf_set(to, from->ptr, (size_t)(id_start - from->ptr));
+	git_buf_put(to, "$Id: ", 5);
+	git_buf_put(to, oid, GIT_OID_HEXSZ);
+	git_buf_put(to, " $", 2);
+	git_buf_put(to, id_end, (size_t)(from_end - id_end));
+
+	return git_buf_oom(to) ? -1 : 0;
+}
+
+static int ident_remove_id(
+	git_buf *to, const git_buf *from)
+{
+	const char *id_start, *id_end, *from_end = from->ptr + from->size;
+	size_t need_size;
+
+	if (ident_find_id(&id_start, &id_end, from->ptr, from->size) < 0)
+		return GIT_PASSTHROUGH;
+
+	need_size = (size_t)(id_start - from->ptr) +
+		4 /* "$Id$" */ + (size_t)(from_end - id_end);
+
+	if (git_buf_grow(to, need_size) < 0)
+		return -1;
+
+	git_buf_set(to, from->ptr, (size_t)(id_start - from->ptr));
+	git_buf_put(to, "$Id$", 4);
+	git_buf_put(to, id_end, (size_t)(from_end - id_end));
+
+	return git_buf_oom(to) ? -1 : 0;
+}
+
+static int ident_apply(
+	git_filter     *self,
+	void          **payload,
+	git_buf        *to,
+	const git_buf  *from,
+	const git_filter_source *src)
+{
+	GIT_UNUSED(self); GIT_UNUSED(payload);
+
+	/* Don't filter binary files */
+	if (git_buf_text_is_binary(from))
+		return GIT_PASSTHROUGH;
+
+	if (git_filter_source_mode(src) == GIT_FILTER_SMUDGE)
+		return ident_insert_id(to, from, src);
+	else
+		return ident_remove_id(to, from);
+}
+
+git_filter *git_ident_filter_new(void)
+{
+	git_filter *f = git__calloc(1, sizeof(git_filter));
+	if (f == NULL)
+		return NULL;
+
+	f->version = GIT_FILTER_VERSION;
+	f->attributes = "+ident"; /* apply to files with ident attribute set */
+	f->shutdown = git_filter_free;
+	f->apply    = ident_apply;
+
+	return f;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/ignore.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/ignore.c
new file mode 100755
index 0000000..0031e46
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/ignore.c
@@ -0,0 +1,573 @@
+#include "git2/ignore.h"
+#include "common.h"
+#include "ignore.h"
+#include "attrcache.h"
+#include "path.h"
+#include "config.h"
+#include "fnmatch.h"
+
+#define GIT_IGNORE_INTERNAL		"[internal]exclude"
+
+#define GIT_IGNORE_DEFAULT_RULES ".\n..\n.git\n"
+
+/**
+ * A negative ignore pattern can match a positive one without
+ * wildcards if its pattern equals the tail of the positive
+ * pattern. Thus
+ *
+ * foo/bar
+ * !bar
+ *
+ * would result in foo/bar being unignored again.
+ */
+static int does_negate_pattern(git_attr_fnmatch *rule, git_attr_fnmatch *neg)
+{
+	char *p;
+
+	if ((rule->flags & GIT_ATTR_FNMATCH_NEGATIVE) == 0
+		&& (neg->flags & GIT_ATTR_FNMATCH_NEGATIVE) != 0) {
+		/*
+		 * no chance of matching if rule is shorter than
+		 * the negated one
+		 */
+		if (rule->length < neg->length)
+			return false;
+
+		/*
+		 * shift pattern so its tail aligns with the
+		 * negated pattern
+		 */
+		p = rule->pattern + rule->length - neg->length;
+		if (strcmp(p, neg->pattern) == 0)
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * A negative ignore can only unignore a file which is given explicitly before, thus
+ *
+ *    foo
+ *    !foo/bar
+ *
+ * does not unignore 'foo/bar' as it's not in the list. However
+ *
+ *    foo/<star>
+ *    !foo/bar
+ *
+ * does unignore 'foo/bar', as it is contained within the 'foo/<star>' rule.
+ */
+static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match)
+{
+	int error = 0;
+	size_t i;
+	git_attr_fnmatch *rule;
+	char *path;
+	git_buf buf = GIT_BUF_INIT;
+
+	*out = 0;
+
+	/* path of the file relative to the workdir, so we match the rules in subdirs */
+	if (match->containing_dir) {
+		git_buf_puts(&buf, match->containing_dir);
+	}
+	if (git_buf_puts(&buf, match->pattern) < 0)
+		return -1;
+
+	path = git_buf_detach(&buf);
+
+	git_vector_foreach(rules, i, rule) {
+		if (!(rule->flags & GIT_ATTR_FNMATCH_HASWILD)) {
+			if (does_negate_pattern(rule, match)) {
+				error = 0;
+				*out = 1;
+				goto out;
+			}
+			else
+				continue;
+		}
+
+	/*
+	 * If we're dealing with a directory (which we know via the
+	 * strchr() check) we want to use 'dirname/<star>' as the
+	 * pattern so p_fnmatch() honours FNM_PATHNAME
+	 */
+		git_buf_clear(&buf);
+		if (rule->containing_dir) {
+			git_buf_puts(&buf, rule->containing_dir);
+		}
+		if (!strchr(rule->pattern, '*'))
+			error = git_buf_printf(&buf, "%s/*", rule->pattern);
+		else
+			error = git_buf_puts(&buf, rule->pattern);
+
+		if (error < 0)
+			goto out;
+
+		if ((error = p_fnmatch(git_buf_cstr(&buf), path, FNM_PATHNAME)) < 0) {
+			giterr_set(GITERR_INVALID, "error matching pattern");
+			goto out;
+		}
+
+		/* if we found a match, we want to keep this rule */
+		if (error != FNM_NOMATCH) {
+			*out = 1;
+			error = 0;
+			goto out;
+		}
+	}
+
+	error = 0;
+
+out:
+	git__free(path);
+	git_buf_free(&buf);
+	return error;
+}
+
+static int parse_ignore_file(
+	git_repository *repo, git_attr_file *attrs, const char *data)
+{
+	int error = 0;
+	int ignore_case = false;
+	const char *scan = data, *context = NULL;
+	git_attr_fnmatch *match = NULL;
+
+	if (git_repository__cvar(&ignore_case, repo, GIT_CVAR_IGNORECASE) < 0)
+		giterr_clear();
+
+	/* if subdir file path, convert context for file paths */
+	if (attrs->entry &&
+		git_path_root(attrs->entry->path) < 0 &&
+		!git__suffixcmp(attrs->entry->path, "/" GIT_IGNORE_FILE))
+		context = attrs->entry->path;
+
+	if (git_mutex_lock(&attrs->lock) < 0) {
+		giterr_set(GITERR_OS, "Failed to lock ignore file");
+		return -1;
+	}
+
+	while (!error && *scan) {
+		int valid_rule = 1;
+
+		if (!match && !(match = git__calloc(1, sizeof(*match)))) {
+			error = -1;
+			break;
+		}
+
+		match->flags = GIT_ATTR_FNMATCH_ALLOWSPACE | GIT_ATTR_FNMATCH_ALLOWNEG;
+
+		if (!(error = git_attr_fnmatch__parse(
+			match, &attrs->pool, context, &scan)))
+		{
+			match->flags |= GIT_ATTR_FNMATCH_IGNORE;
+
+			if (ignore_case)
+				match->flags |= GIT_ATTR_FNMATCH_ICASE;
+
+			scan = git__next_line(scan);
+
+			/* if a negative match doesn't actually do anything, throw it away */
+			if (match->flags & GIT_ATTR_FNMATCH_NEGATIVE)
+				error = does_negate_rule(&valid_rule, &attrs->rules, match);
+
+			if (!error && valid_rule)
+				error = git_vector_insert(&attrs->rules, match);
+		}
+
+		if (error != 0 || !valid_rule) {
+			match->pattern = NULL;
+
+			if (error == GIT_ENOTFOUND)
+				error = 0;
+		} else {
+			match = NULL; /* vector now "owns" the match */
+		}
+	}
+
+	git_mutex_unlock(&attrs->lock);
+	git__free(match);
+
+	return error;
+}
+
+static int push_ignore_file(
+	git_ignores *ignores,
+	git_vector *which_list,
+	const char *base,
+	const char *filename)
+{
+	int error = 0;
+	git_attr_file *file = NULL;
+
+	error = git_attr_cache__get(
+		&file, ignores->repo, NULL, GIT_ATTR_FILE__FROM_FILE,
+		base, filename, parse_ignore_file);
+	if (error < 0)
+		return error;
+
+	if (file != NULL) {
+		if ((error = git_vector_insert(which_list, file)) < 0)
+			git_attr_file__free(file);
+	}
+
+	return error;
+}
+
+static int push_one_ignore(void *payload, const char *path)
+{
+	git_ignores *ign = payload;
+	ign->depth++;
+	return push_ignore_file(ign, &ign->ign_path, path, GIT_IGNORE_FILE);
+}
+
+static int get_internal_ignores(git_attr_file **out, git_repository *repo)
+{
+	int error;
+
+	if ((error = git_attr_cache__init(repo)) < 0)
+		return error;
+
+	error = git_attr_cache__get(
+		out, repo, NULL, GIT_ATTR_FILE__IN_MEMORY, NULL, GIT_IGNORE_INTERNAL, NULL);
+
+	/* if internal rules list is empty, insert default rules */
+	if (!error && !(*out)->rules.length)
+		error = parse_ignore_file(repo, *out, GIT_IGNORE_DEFAULT_RULES);
+
+	return error;
+}
+
+int git_ignore__for_path(
+	git_repository *repo,
+	const char *path,
+	git_ignores *ignores)
+{
+	int error = 0;
+	const char *workdir = git_repository_workdir(repo);
+
+	assert(ignores && path);
+
+	memset(ignores, 0, sizeof(*ignores));
+	ignores->repo = repo;
+
+	/* Read the ignore_case flag */
+	if ((error = git_repository__cvar(
+			&ignores->ignore_case, repo, GIT_CVAR_IGNORECASE)) < 0)
+		goto cleanup;
+
+	if ((error = git_attr_cache__init(repo)) < 0)
+		goto cleanup;
+
+	/* given a unrooted path in a non-bare repo, resolve it */
+	if (workdir && git_path_root(path) < 0)
+		error = git_path_find_dir(&ignores->dir, path, workdir);
+	else
+		error = git_buf_joinpath(&ignores->dir, path, "");
+	if (error < 0)
+		goto cleanup;
+
+	if (workdir && !git__prefixcmp(ignores->dir.ptr, workdir))
+		ignores->dir_root = strlen(workdir);
+
+	/* set up internals */
+	if ((error = get_internal_ignores(&ignores->ign_internal, repo)) < 0)
+		goto cleanup;
+
+	/* load .gitignore up the path */
+	if (workdir != NULL) {
+		error = git_path_walk_up(
+			&ignores->dir, workdir, push_one_ignore, ignores);
+		if (error < 0)
+			goto cleanup;
+	}
+
+	/* load .git/info/exclude */
+	error = push_ignore_file(
+		ignores, &ignores->ign_global,
+		git_repository_path(repo), GIT_IGNORE_FILE_INREPO);
+	if (error < 0)
+		goto cleanup;
+
+	/* load core.excludesfile */
+	if (git_repository_attr_cache(repo)->cfg_excl_file != NULL)
+		error = push_ignore_file(
+			ignores, &ignores->ign_global, NULL,
+			git_repository_attr_cache(repo)->cfg_excl_file);
+
+cleanup:
+	if (error < 0)
+		git_ignore__free(ignores);
+
+	return error;
+}
+
+int git_ignore__push_dir(git_ignores *ign, const char *dir)
+{
+	if (git_buf_joinpath(&ign->dir, ign->dir.ptr, dir) < 0)
+		return -1;
+
+	ign->depth++;
+
+	return push_ignore_file(
+		ign, &ign->ign_path, ign->dir.ptr, GIT_IGNORE_FILE);
+}
+
+int git_ignore__pop_dir(git_ignores *ign)
+{
+	if (ign->ign_path.length > 0) {
+		git_attr_file *file = git_vector_last(&ign->ign_path);
+		const char *start = file->entry->path, *end;
+
+		/* - ign->dir looks something like "/home/user/a/b/" (or "a/b/c/d/")
+		 * - file->path looks something like "a/b/.gitignore
+		 *
+		 * We are popping the last directory off ign->dir.  We also want
+		 * to remove the file from the vector if the popped directory
+		 * matches the ignore path.  We need to test if the "a/b" part of
+		 * the file key matches the path we are about to pop.
+		 */
+
+		if ((end = strrchr(start, '/')) != NULL) {
+			size_t dirlen = (end - start) + 1;
+			const char *relpath = ign->dir.ptr + ign->dir_root;
+			size_t pathlen = ign->dir.size - ign->dir_root;
+
+			if (pathlen == dirlen && !memcmp(relpath, start, dirlen)) {
+				git_vector_pop(&ign->ign_path);
+				git_attr_file__free(file);
+			}
+		}
+	}
+
+	if (--ign->depth > 0) {
+		git_buf_rtruncate_at_char(&ign->dir, '/');
+		git_path_to_dir(&ign->dir);
+	}
+
+	return 0;
+}
+
+void git_ignore__free(git_ignores *ignores)
+{
+	unsigned int i;
+	git_attr_file *file;
+
+	git_attr_file__free(ignores->ign_internal);
+
+	git_vector_foreach(&ignores->ign_path, i, file) {
+		git_attr_file__free(file);
+		ignores->ign_path.contents[i] = NULL;
+	}
+	git_vector_free(&ignores->ign_path);
+
+	git_vector_foreach(&ignores->ign_global, i, file) {
+		git_attr_file__free(file);
+		ignores->ign_global.contents[i] = NULL;
+	}
+	git_vector_free(&ignores->ign_global);
+
+	git_buf_free(&ignores->dir);
+}
+
+static bool ignore_lookup_in_rules(
+	int *ignored, git_attr_file *file, git_attr_path *path)
+{
+	size_t j;
+	git_attr_fnmatch *match;
+
+	git_vector_rforeach(&file->rules, j, match) {
+		if (git_attr_fnmatch__match(match, path)) {
+			*ignored = ((match->flags & GIT_ATTR_FNMATCH_NEGATIVE) == 0) ?
+				GIT_IGNORE_TRUE : GIT_IGNORE_FALSE;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+int git_ignore__lookup(
+	int *out, git_ignores *ignores, const char *pathname, git_dir_flag dir_flag)
+{
+	unsigned int i;
+	git_attr_file *file;
+	git_attr_path path;
+
+	*out = GIT_IGNORE_NOTFOUND;
+
+	if (git_attr_path__init(
+		&path, pathname, git_repository_workdir(ignores->repo), dir_flag) < 0)
+		return -1;
+
+	/* first process builtins - success means path was found */
+	if (ignore_lookup_in_rules(out, ignores->ign_internal, &path))
+		goto cleanup;
+
+	/* next process files in the path */
+	git_vector_foreach(&ignores->ign_path, i, file) {
+		if (ignore_lookup_in_rules(out, file, &path))
+			goto cleanup;
+	}
+
+	/* last process global ignores */
+	git_vector_foreach(&ignores->ign_global, i, file) {
+		if (ignore_lookup_in_rules(out, file, &path))
+			goto cleanup;
+	}
+
+cleanup:
+	git_attr_path__free(&path);
+	return 0;
+}
+
+int git_ignore_add_rule(git_repository *repo, const char *rules)
+{
+	int error;
+	git_attr_file *ign_internal = NULL;
+
+	if ((error = get_internal_ignores(&ign_internal, repo)) < 0)
+		return error;
+
+	error = parse_ignore_file(repo, ign_internal, rules);
+	git_attr_file__free(ign_internal);
+
+	return error;
+}
+
+int git_ignore_clear_internal_rules(git_repository *repo)
+{
+	int error;
+	git_attr_file *ign_internal;
+
+	if ((error = get_internal_ignores(&ign_internal, repo)) < 0)
+		return error;
+
+	if (!(error = git_attr_file__clear_rules(ign_internal, true)))
+		error = parse_ignore_file(
+			repo, ign_internal, GIT_IGNORE_DEFAULT_RULES);
+
+	git_attr_file__free(ign_internal);
+	return error;
+}
+
+int git_ignore_path_is_ignored(
+	int *ignored,
+	git_repository *repo,
+	const char *pathname)
+{
+	int error;
+	const char *workdir;
+	git_attr_path path;
+	git_ignores ignores;
+	unsigned int i;
+	git_attr_file *file;
+
+	assert(ignored && pathname);
+
+	workdir = repo ? git_repository_workdir(repo) : NULL;
+
+	memset(&path, 0, sizeof(path));
+	memset(&ignores, 0, sizeof(ignores));
+
+	if ((error = git_attr_path__init(&path, pathname, workdir, GIT_DIR_FLAG_UNKNOWN)) < 0 ||
+		(error = git_ignore__for_path(repo, path.path, &ignores)) < 0)
+		goto cleanup;
+
+	while (1) {
+		/* first process builtins - success means path was found */
+		if (ignore_lookup_in_rules(ignored, ignores.ign_internal, &path))
+			goto cleanup;
+
+		/* next process files in the path */
+		git_vector_foreach(&ignores.ign_path, i, file) {
+			if (ignore_lookup_in_rules(ignored, file, &path))
+				goto cleanup;
+		}
+
+		/* last process global ignores */
+		git_vector_foreach(&ignores.ign_global, i, file) {
+			if (ignore_lookup_in_rules(ignored, file, &path))
+				goto cleanup;
+		}
+
+		/* move up one directory */
+		if (path.basename == path.path)
+			break;
+		path.basename[-1] = '\0';
+		while (path.basename > path.path && *path.basename != '/')
+			path.basename--;
+		if (path.basename > path.path)
+			path.basename++;
+		path.is_dir = 1;
+
+		if ((error = git_ignore__pop_dir(&ignores)) < 0)
+			break;
+	}
+
+	*ignored = 0;
+
+cleanup:
+	git_attr_path__free(&path);
+	git_ignore__free(&ignores);
+	return error;
+}
+
+int git_ignore__check_pathspec_for_exact_ignores(
+	git_repository *repo,
+	git_vector *vspec,
+	bool no_fnmatch)
+{
+	int error = 0;
+	size_t i;
+	git_attr_fnmatch *match;
+	int ignored;
+	git_buf path = GIT_BUF_INIT;
+	const char *wd, *filename;
+	git_index *idx;
+
+	if ((error = git_repository__ensure_not_bare(
+			repo, "validate pathspec")) < 0 ||
+		(error = git_repository_index(&idx, repo)) < 0)
+		return error;
+
+	wd = git_repository_workdir(repo);
+
+	git_vector_foreach(vspec, i, match) {
+		/* skip wildcard matches (if they are being used) */
+		if ((match->flags & GIT_ATTR_FNMATCH_HASWILD) != 0 &&
+			!no_fnmatch)
+			continue;
+
+		filename = match->pattern;
+
+		/* if file is already in the index, it's fine */
+		if (git_index_get_bypath(idx, filename, 0) != NULL)
+			continue;
+
+		if ((error = git_buf_joinpath(&path, wd, filename)) < 0)
+			break;
+
+		/* is there a file on disk that matches this exactly? */
+		if (!git_path_isfile(path.ptr))
+			continue;
+
+		/* is that file ignored? */
+		if ((error = git_ignore_path_is_ignored(&ignored, repo, filename)) < 0)
+			break;
+
+		if (ignored) {
+			giterr_set(GITERR_INVALID, "pathspec contains ignored file '%s'",
+				filename);
+			error = GIT_EINVALIDSPEC;
+			break;
+		}
+	}
+
+	git_index_free(idx);
+	git_buf_free(&path);
+
+	return error;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/ignore.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/ignore.h
new file mode 100755
index 0000000..d40bd60
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/ignore.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_ignore_h__
+#define INCLUDE_ignore_h__
+
+#include "repository.h"
+#include "vector.h"
+#include "attr_file.h"
+
+#define GIT_IGNORE_FILE			".gitignore"
+#define GIT_IGNORE_FILE_INREPO	"info/exclude"
+#define GIT_IGNORE_FILE_XDG		"ignore"
+
+/* The git_ignores structure maintains three sets of ignores:
+ * - internal ignores
+ * - per directory ignores
+ * - global ignores (at lower priority than the others)
+ * As you traverse from one directory to another, you can push and pop
+ * directories onto git_ignores list efficiently.
+ */
+typedef struct {
+	git_repository *repo;
+	git_buf dir; /* current directory reflected in ign_path */
+	git_attr_file *ign_internal;
+	git_vector ign_path;
+	git_vector ign_global;
+	size_t dir_root; /* offset in dir to repo root */
+	int ignore_case;
+	int depth;
+} git_ignores;
+
+extern int git_ignore__for_path(
+	git_repository *repo, const char *path, git_ignores *ign);
+
+extern int git_ignore__push_dir(git_ignores *ign, const char *dir);
+
+extern int git_ignore__pop_dir(git_ignores *ign);
+
+extern void git_ignore__free(git_ignores *ign);
+
+enum {
+	GIT_IGNORE_UNCHECKED = -2,
+	GIT_IGNORE_NOTFOUND = -1,
+	GIT_IGNORE_FALSE = 0,
+	GIT_IGNORE_TRUE = 1,
+};
+
+extern int git_ignore__lookup(int *out, git_ignores *ign, const char *path, git_dir_flag dir_flag);
+
+/* command line Git sometimes generates an error message if given a
+ * pathspec that contains an exact match to an ignored file (provided
+ * --force isn't also given).  This makes it easy to check it that has
+ * happened.  Returns GIT_EINVALIDSPEC if the pathspec contains ignored
+ * exact matches (that are not already present in the index).
+ */
+extern int git_ignore__check_pathspec_for_exact_ignores(
+	git_repository *repo, git_vector *pathspec, bool no_fnmatch);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/index.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/index.c
new file mode 100755
index 0000000..73f0b3d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/index.c
@@ -0,0 +1,3140 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include <stddef.h>
+
+#include "common.h"
+#include "repository.h"
+#include "index.h"
+#include "tree.h"
+#include "tree-cache.h"
+#include "hash.h"
+#include "iterator.h"
+#include "pathspec.h"
+#include "ignore.h"
+#include "blob.h"
+
+#include "git2/odb.h"
+#include "git2/oid.h"
+#include "git2/blob.h"
+#include "git2/config.h"
+#include "git2/sys/index.h"
+
+static int index_apply_to_wd_diff(git_index *index, int action, const git_strarray *paths,
+				  unsigned int flags,
+				  git_index_matched_path_cb cb, void *payload);
+
+#define entry_size(type,len) ((offsetof(type, path) + (len) + 8) & ~7)
+#define short_entry_size(len) entry_size(struct entry_short, len)
+#define long_entry_size(len) entry_size(struct entry_long, len)
+
+#define minimal_entry_size (offsetof(struct entry_short, path))
+
+static const size_t INDEX_FOOTER_SIZE = GIT_OID_RAWSZ;
+static const size_t INDEX_HEADER_SIZE = 12;
+
+static const unsigned int INDEX_VERSION_NUMBER = 2;
+static const unsigned int INDEX_VERSION_NUMBER_EXT = 3;
+
+static const unsigned int INDEX_HEADER_SIG = 0x44495243;
+static const char INDEX_EXT_TREECACHE_SIG[] = {'T', 'R', 'E', 'E'};
+static const char INDEX_EXT_UNMERGED_SIG[] = {'R', 'E', 'U', 'C'};
+static const char INDEX_EXT_CONFLICT_NAME_SIG[] = {'N', 'A', 'M', 'E'};
+
+#define INDEX_OWNER(idx) ((git_repository *)(GIT_REFCOUNT_OWNER(idx)))
+
+struct index_header {
+	uint32_t signature;
+	uint32_t version;
+	uint32_t entry_count;
+};
+
+struct index_extension {
+	char signature[4];
+	uint32_t extension_size;
+};
+
+struct entry_time {
+	uint32_t seconds;
+	uint32_t nanoseconds;
+};
+
+struct entry_short {
+	struct entry_time ctime;
+	struct entry_time mtime;
+	uint32_t dev;
+	uint32_t ino;
+	uint32_t mode;
+	uint32_t uid;
+	uint32_t gid;
+	uint32_t file_size;
+	git_oid oid;
+	uint16_t flags;
+	char path[1]; /* arbitrary length */
+};
+
+struct entry_long {
+	struct entry_time ctime;
+	struct entry_time mtime;
+	uint32_t dev;
+	uint32_t ino;
+	uint32_t mode;
+	uint32_t uid;
+	uint32_t gid;
+	uint32_t file_size;
+	git_oid oid;
+	uint16_t flags;
+	uint16_t flags_extended;
+	char path[1]; /* arbitrary length */
+};
+
+struct entry_srch_key {
+	const char *path;
+	size_t pathlen;
+	int stage;
+};
+
+struct entry_internal {
+	git_index_entry entry;
+	size_t pathlen;
+	char path[GIT_FLEX_ARRAY];
+};
+
+struct reuc_entry_internal {
+	git_index_reuc_entry entry;
+	size_t pathlen;
+	char path[GIT_FLEX_ARRAY];
+};
+
+/* local declarations */
+static size_t read_extension(git_index *index, const char *buffer, size_t buffer_size);
+static int read_header(struct index_header *dest, const void *buffer);
+
+static int parse_index(git_index *index, const char *buffer, size_t buffer_size);
+static bool is_index_extended(git_index *index);
+static int write_index(git_oid *checksum, git_index *index, git_filebuf *file);
+
+static void index_entry_free(git_index_entry *entry);
+static void index_entry_reuc_free(git_index_reuc_entry *reuc);
+
+int git_index_entry_srch(const void *key, const void *array_member)
+{
+	const struct entry_srch_key *srch_key = key;
+	const struct entry_internal *entry = array_member;
+	int cmp;
+	size_t len1, len2, len;
+
+	len1 = srch_key->pathlen;
+	len2 = entry->pathlen;
+	len = len1 < len2 ? len1 : len2;
+
+	cmp = memcmp(srch_key->path, entry->path, len);
+	if (cmp)
+		return cmp;
+	if (len1 < len2)
+		return -1;
+	if (len1 > len2)
+		return 1;
+
+	if (srch_key->stage != GIT_INDEX_STAGE_ANY)
+		return srch_key->stage - GIT_IDXENTRY_STAGE(&entry->entry);
+
+	return 0;
+}
+
+int git_index_entry_isrch(const void *key, const void *array_member)
+{
+	const struct entry_srch_key *srch_key = key;
+	const struct entry_internal *entry = array_member;
+	int cmp;
+	size_t len1, len2, len;
+
+	len1 = srch_key->pathlen;
+	len2 = entry->pathlen;
+	len = len1 < len2 ? len1 : len2;
+
+	cmp = strncasecmp(srch_key->path, entry->path, len);
+
+	if (cmp)
+		return cmp;
+	if (len1 < len2)
+		return -1;
+	if (len1 > len2)
+		return 1;
+
+	if (srch_key->stage != GIT_INDEX_STAGE_ANY)
+		return srch_key->stage - GIT_IDXENTRY_STAGE(&entry->entry);
+
+	return 0;
+}
+
+static int index_entry_srch_path(const void *path, const void *array_member)
+{
+	const git_index_entry *entry = array_member;
+
+	return strcmp((const char *)path, entry->path);
+}
+
+static int index_entry_isrch_path(const void *path, const void *array_member)
+{
+	const git_index_entry *entry = array_member;
+
+	return strcasecmp((const char *)path, entry->path);
+}
+
+int git_index_entry_cmp(const void *a, const void *b)
+{
+	int diff;
+	const git_index_entry *entry_a = a;
+	const git_index_entry *entry_b = b;
+
+	diff = strcmp(entry_a->path, entry_b->path);
+
+	if (diff == 0)
+		diff = (GIT_IDXENTRY_STAGE(entry_a) - GIT_IDXENTRY_STAGE(entry_b));
+
+	return diff;
+}
+
+int git_index_entry_icmp(const void *a, const void *b)
+{
+	int diff;
+	const git_index_entry *entry_a = a;
+	const git_index_entry *entry_b = b;
+
+	diff = strcasecmp(entry_a->path, entry_b->path);
+
+	if (diff == 0)
+		diff = (GIT_IDXENTRY_STAGE(entry_a) - GIT_IDXENTRY_STAGE(entry_b));
+
+	return diff;
+}
+
+static int conflict_name_cmp(const void *a, const void *b)
+{
+	const git_index_name_entry *name_a = a;
+	const git_index_name_entry *name_b = b;
+
+	if (name_a->ancestor && !name_b->ancestor)
+		return 1;
+
+	if (!name_a->ancestor && name_b->ancestor)
+		return -1;
+
+	if (name_a->ancestor)
+		return strcmp(name_a->ancestor, name_b->ancestor);
+
+	if (!name_a->ours || !name_b->ours)
+		return 0;
+
+	return strcmp(name_a->ours, name_b->ours);
+}
+
+/**
+ * TODO: enable this when resolving case insensitive conflicts
+ */
+#if 0
+static int conflict_name_icmp(const void *a, const void *b)
+{
+	const git_index_name_entry *name_a = a;
+	const git_index_name_entry *name_b = b;
+
+	if (name_a->ancestor && !name_b->ancestor)
+		return 1;
+
+	if (!name_a->ancestor && name_b->ancestor)
+		return -1;
+
+	if (name_a->ancestor)
+		return strcasecmp(name_a->ancestor, name_b->ancestor);
+
+	if (!name_a->ours || !name_b->ours)
+		return 0;
+
+	return strcasecmp(name_a->ours, name_b->ours);
+}
+#endif
+
+static int reuc_srch(const void *key, const void *array_member)
+{
+	const git_index_reuc_entry *reuc = array_member;
+
+	return strcmp(key, reuc->path);
+}
+
+static int reuc_isrch(const void *key, const void *array_member)
+{
+	const git_index_reuc_entry *reuc = array_member;
+
+	return strcasecmp(key, reuc->path);
+}
+
+static int reuc_cmp(const void *a, const void *b)
+{
+	const git_index_reuc_entry *info_a = a;
+	const git_index_reuc_entry *info_b = b;
+
+	return strcmp(info_a->path, info_b->path);
+}
+
+static int reuc_icmp(const void *a, const void *b)
+{
+	const git_index_reuc_entry *info_a = a;
+	const git_index_reuc_entry *info_b = b;
+
+	return strcasecmp(info_a->path, info_b->path);
+}
+
+static void index_entry_reuc_free(git_index_reuc_entry *reuc)
+{
+	git__free(reuc);
+}
+
+static void index_entry_free(git_index_entry *entry)
+{
+	if (!entry)
+		return;
+
+	memset(&entry->id, 0, sizeof(entry->id));
+	git__free(entry);
+}
+
+unsigned int git_index__create_mode(unsigned int mode)
+{
+	if (S_ISLNK(mode))
+		return S_IFLNK;
+
+	if (S_ISDIR(mode) || (mode & S_IFMT) == (S_IFLNK | S_IFDIR))
+		return (S_IFLNK | S_IFDIR);
+
+	return S_IFREG | GIT_PERMS_CANONICAL(mode);
+}
+
+static unsigned int index_merge_mode(
+	git_index *index, git_index_entry *existing, unsigned int mode)
+{
+	if (index->no_symlinks && S_ISREG(mode) &&
+		existing && S_ISLNK(existing->mode))
+		return existing->mode;
+
+	if (index->distrust_filemode && S_ISREG(mode))
+		return (existing && S_ISREG(existing->mode)) ?
+			existing->mode : git_index__create_mode(0666);
+
+	return git_index__create_mode(mode);
+}
+
+static int index_sort_if_needed(git_index *index, bool need_lock)
+{
+	/* not truly threadsafe because between when this checks and/or
+	 * sorts the array another thread could come in and unsort it
+	 */
+
+	if (git_vector_is_sorted(&index->entries))
+		return 0;
+
+	if (need_lock && git_mutex_lock(&index->lock) < 0) {
+		giterr_set(GITERR_OS, "Unable to lock index");
+		return -1;
+	}
+
+	git_vector_sort(&index->entries);
+
+	if (need_lock)
+		git_mutex_unlock(&index->lock);
+
+	return 0;
+}
+
+GIT_INLINE(int) index_find_in_entries(
+	size_t *out, git_vector *entries, git_vector_cmp entry_srch,
+	const char *path, size_t path_len, int stage)
+{
+	struct entry_srch_key srch_key;
+	srch_key.path = path;
+	srch_key.pathlen = !path_len ? strlen(path) : path_len;
+	srch_key.stage = stage;
+	return git_vector_bsearch2(out, entries, entry_srch, &srch_key);
+}
+
+GIT_INLINE(int) index_find(
+	size_t *out, git_index *index,
+	const char *path, size_t path_len, int stage, bool need_lock)
+{
+	if (index_sort_if_needed(index, need_lock) < 0)
+		return -1;
+
+	return index_find_in_entries(
+		out, &index->entries, index->entries_search, path, path_len, stage);
+}
+
+void git_index__set_ignore_case(git_index *index, bool ignore_case)
+{
+	index->ignore_case = ignore_case;
+
+	if (ignore_case) {
+		index->entries_cmp_path    = git__strcasecmp_cb;
+		index->entries_search      = git_index_entry_isrch;
+		index->entries_search_path = index_entry_isrch_path;
+		index->reuc_search         = reuc_isrch;
+	} else {
+		index->entries_cmp_path    = git__strcmp_cb;
+		index->entries_search      = git_index_entry_srch;
+		index->entries_search_path = index_entry_srch_path;
+		index->reuc_search         = reuc_srch;
+	}
+
+	git_vector_set_cmp(&index->entries,
+		ignore_case ? git_index_entry_icmp : git_index_entry_cmp);
+	index_sort_if_needed(index, true);
+
+	git_vector_set_cmp(&index->reuc, ignore_case ? reuc_icmp : reuc_cmp);
+	git_vector_sort(&index->reuc);
+}
+
+int git_index_open(git_index **index_out, const char *index_path)
+{
+	git_index *index;
+	int error = -1;
+
+	assert(index_out);
+
+	index = git__calloc(1, sizeof(git_index));
+	GITERR_CHECK_ALLOC(index);
+
+	if (git_mutex_init(&index->lock)) {
+		giterr_set(GITERR_OS, "Failed to initialize lock");
+		git__free(index);
+		return -1;
+	}
+
+	git_pool_init(&index->tree_pool, 1, 0);
+
+	if (index_path != NULL) {
+		index->index_file_path = git__strdup(index_path);
+		if (!index->index_file_path)
+			goto fail;
+
+		/* Check if index file is stored on disk already */
+		if (git_path_exists(index->index_file_path) == true)
+			index->on_disk = 1;
+	}
+
+	if (git_vector_init(&index->entries, 32, git_index_entry_cmp) < 0 ||
+		git_vector_init(&index->names, 8, conflict_name_cmp) < 0 ||
+		git_vector_init(&index->reuc, 8, reuc_cmp) < 0 ||
+		git_vector_init(&index->deleted, 8, git_index_entry_cmp) < 0)
+		goto fail;
+
+	index->entries_cmp_path = git__strcmp_cb;
+	index->entries_search = git_index_entry_srch;
+	index->entries_search_path = index_entry_srch_path;
+	index->reuc_search = reuc_srch;
+
+	if (index_path != NULL && (error = git_index_read(index, true)) < 0)
+		goto fail;
+
+	*index_out = index;
+	GIT_REFCOUNT_INC(index);
+
+	return 0;
+
+fail:
+	git_pool_clear(&index->tree_pool);
+	git_index_free(index);
+	return error;
+}
+
+int git_index_new(git_index **out)
+{
+	return git_index_open(out, NULL);
+}
+
+static void index_free(git_index *index)
+{
+	/* index iterators increment the refcount of the index, so if we
+	 * get here then there should be no outstanding iterators.
+	 */
+	assert(!git_atomic_get(&index->readers));
+
+	git_index_clear(index);
+	git_vector_free(&index->entries);
+	git_vector_free(&index->names);
+	git_vector_free(&index->reuc);
+	git_vector_free(&index->deleted);
+
+	git__free(index->index_file_path);
+	git_mutex_free(&index->lock);
+
+	git__memzero(index, sizeof(*index));
+	git__free(index);
+}
+
+void git_index_free(git_index *index)
+{
+	if (index == NULL)
+		return;
+
+	GIT_REFCOUNT_DEC(index, index_free);
+}
+
+/* call with locked index */
+static void index_free_deleted(git_index *index)
+{
+	int readers = (int)git_atomic_get(&index->readers);
+	size_t i;
+
+	if (readers > 0 || !index->deleted.length)
+		return;
+
+	for (i = 0; i < index->deleted.length; ++i) {
+		git_index_entry *ie = git__swap(index->deleted.contents[i], NULL);
+		index_entry_free(ie);
+	}
+
+	git_vector_clear(&index->deleted);
+}
+
+/* call with locked index */
+static int index_remove_entry(git_index *index, size_t pos)
+{
+	int error = 0;
+	git_index_entry *entry = git_vector_get(&index->entries, pos);
+
+	if (entry != NULL)
+		git_tree_cache_invalidate_path(index->tree, entry->path);
+
+	error = git_vector_remove(&index->entries, pos);
+
+	if (!error) {
+		if (git_atomic_get(&index->readers) > 0) {
+			error = git_vector_insert(&index->deleted, entry);
+		} else {
+			index_entry_free(entry);
+		}
+	}
+
+	return error;
+}
+
+int git_index_clear(git_index *index)
+{
+	int error = 0;
+
+	assert(index);
+
+	index->tree = NULL;
+	git_pool_clear(&index->tree_pool);
+
+	if (git_mutex_lock(&index->lock) < 0) {
+		giterr_set(GITERR_OS, "Failed to lock index");
+		return -1;
+	}
+
+	while (!error && index->entries.length > 0)
+		error = index_remove_entry(index, index->entries.length - 1);
+	index_free_deleted(index);
+
+	git_index_reuc_clear(index);
+	git_index_name_clear(index);
+
+	git_futils_filestamp_set(&index->stamp, NULL);
+
+	git_mutex_unlock(&index->lock);
+
+	return error;
+}
+
+static int create_index_error(int error, const char *msg)
+{
+	giterr_set(GITERR_INDEX, msg);
+	return error;
+}
+
+int git_index_set_caps(git_index *index, int caps)
+{
+	unsigned int old_ignore_case;
+
+	assert(index);
+
+	old_ignore_case = index->ignore_case;
+
+	if (caps == GIT_INDEXCAP_FROM_OWNER) {
+		git_repository *repo = INDEX_OWNER(index);
+		int val;
+
+		if (!repo)
+			return create_index_error(
+				-1, "Cannot access repository to set index caps");
+
+		if (!git_repository__cvar(&val, repo, GIT_CVAR_IGNORECASE))
+			index->ignore_case = (val != 0);
+		if (!git_repository__cvar(&val, repo, GIT_CVAR_FILEMODE))
+			index->distrust_filemode = (val == 0);
+		if (!git_repository__cvar(&val, repo, GIT_CVAR_SYMLINKS))
+			index->no_symlinks = (val == 0);
+	}
+	else {
+		index->ignore_case = ((caps & GIT_INDEXCAP_IGNORE_CASE) != 0);
+		index->distrust_filemode = ((caps & GIT_INDEXCAP_NO_FILEMODE) != 0);
+		index->no_symlinks = ((caps & GIT_INDEXCAP_NO_SYMLINKS) != 0);
+	}
+
+	if (old_ignore_case != index->ignore_case) {
+		git_index__set_ignore_case(index, (bool)index->ignore_case);
+	}
+
+	return 0;
+}
+
+int git_index_caps(const git_index *index)
+{
+	return ((index->ignore_case ? GIT_INDEXCAP_IGNORE_CASE : 0) |
+			(index->distrust_filemode ? GIT_INDEXCAP_NO_FILEMODE : 0) |
+			(index->no_symlinks ? GIT_INDEXCAP_NO_SYMLINKS : 0));
+}
+
+const git_oid *git_index_checksum(git_index *index)
+{
+	return &index->checksum;
+}
+
+/**
+ * Returns 1 for changed, 0 for not changed and <0 for errors
+ */
+static int compare_checksum(git_index *index)
+{
+	int fd, error;
+	ssize_t bytes_read;
+	git_oid checksum = {{ 0 }};
+
+	if ((fd = p_open(index->index_file_path, O_RDONLY)) < 0)
+		return fd;
+
+	if ((error = p_lseek(fd, -20, SEEK_END)) < 0) {
+		p_close(fd);
+		giterr_set(GITERR_OS, "failed to seek to end of file");
+		return -1;
+	}
+
+	bytes_read = p_read(fd, &checksum, GIT_OID_RAWSZ);
+	p_close(fd);
+
+	if (bytes_read < 0)
+		return -1;
+
+	return !!git_oid_cmp(&checksum, &index->checksum);
+}
+
+int git_index_read(git_index *index, int force)
+{
+	int error = 0, updated;
+	git_buf buffer = GIT_BUF_INIT;
+	git_futils_filestamp stamp = index->stamp;
+
+	if (!index->index_file_path)
+		return create_index_error(-1,
+			"Failed to read index: The index is in-memory only");
+
+	index->on_disk = git_path_exists(index->index_file_path);
+
+	if (!index->on_disk) {
+		if (force)
+			return git_index_clear(index);
+		return 0;
+	}
+
+	if ((updated = git_futils_filestamp_check(&stamp, index->index_file_path) < 0) ||
+	    ((updated = compare_checksum(index)) < 0)) {
+		giterr_set(
+			GITERR_INDEX,
+			"Failed to read index: '%s' no longer exists",
+			index->index_file_path);
+		return updated;
+	}
+	if (!updated && !force)
+		return 0;
+
+	error = git_futils_readbuffer(&buffer, index->index_file_path);
+	if (error < 0)
+		return error;
+
+	index->tree = NULL;
+	git_pool_clear(&index->tree_pool);
+
+	error = git_index_clear(index);
+
+	if (!error)
+		error = parse_index(index, buffer.ptr, buffer.size);
+
+	if (!error)
+		git_futils_filestamp_set(&index->stamp, &stamp);
+
+	git_buf_free(&buffer);
+	return error;
+}
+
+int git_index__changed_relative_to(
+	git_index *index, const git_oid *checksum)
+{
+	/* attempt to update index (ignoring errors) */
+	if (git_index_read(index, false) < 0)
+		giterr_clear();
+
+	return !!git_oid_cmp(&index->checksum, checksum);
+}
+
+static bool is_racy_timestamp(git_time_t stamp, git_index_entry *entry)
+{
+	/* Git special-cases submodules in the check */
+	if (S_ISGITLINK(entry->mode))
+		return false;
+
+	/* If we never read the index, we can't have this race either */
+	if (stamp == 0)
+		return false;
+
+	/* If the timestamp is the same or newer than the index, it's racy */
+	return ((int32_t) stamp) <= entry->mtime.seconds;
+}
+
+/*
+ * Force the next diff to take a look at those entries which have the
+ * same timestamp as the current index.
+ */
+static int truncate_racily_clean(git_index *index)
+{
+	size_t i;
+	int error;
+	git_index_entry *entry;
+	git_time_t ts = index->stamp.mtime;
+	git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff;
+
+	/* Nothing to do if there's no repo to talk about */
+	if (!INDEX_OWNER(index))
+		return 0;
+
+	/* If there's no workdir, we can't know where to even check */
+	if (!git_repository_workdir(INDEX_OWNER(index)))
+		return 0;
+
+	diff_opts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE | GIT_DIFF_IGNORE_SUBMODULES | GIT_DIFF_DISABLE_PATHSPEC_MATCH;
+	git_vector_foreach(&index->entries, i, entry) {
+		if (!is_racy_timestamp(ts, entry))
+			continue;
+
+		diff_opts.pathspec.count = 1;
+		diff_opts.pathspec.strings = (char **) &entry->path;
+
+		if ((error = git_diff_index_to_workdir(&diff, INDEX_OWNER(index), index, &diff_opts)) < 0)
+			return error;
+
+		if (git_diff_num_deltas(diff) > 0)
+			entry->file_size = 0;
+
+		git_diff_free(diff);
+	}
+
+	return 0;
+}
+
+int git_index_write(git_index *index)
+{
+	git_indexwriter writer = GIT_INDEXWRITER_INIT;
+	int error;
+
+	truncate_racily_clean(index);
+
+	if ((error = git_indexwriter_init(&writer, index)) == 0)
+		error = git_indexwriter_commit(&writer);
+
+	git_indexwriter_cleanup(&writer);
+
+	return error;
+}
+
+const char * git_index_path(const git_index *index)
+{
+	assert(index);
+	return index->index_file_path;
+}
+
+int git_index_write_tree(git_oid *oid, git_index *index)
+{
+	git_repository *repo;
+
+	assert(oid && index);
+
+	repo = INDEX_OWNER(index);
+
+	if (repo == NULL)
+		return create_index_error(-1, "Failed to write tree. "
+		  "The index file is not backed up by an existing repository");
+
+	return git_tree__write_index(oid, index, repo);
+}
+
+int git_index_write_tree_to(
+	git_oid *oid, git_index *index, git_repository *repo)
+{
+	assert(oid && index && repo);
+	return git_tree__write_index(oid, index, repo);
+}
+
+size_t git_index_entrycount(const git_index *index)
+{
+	assert(index);
+	return index->entries.length;
+}
+
+const git_index_entry *git_index_get_byindex(
+	git_index *index, size_t n)
+{
+	assert(index);
+	if (index_sort_if_needed(index, true) < 0)
+		return NULL;
+	return git_vector_get(&index->entries, n);
+}
+
+const git_index_entry *git_index_get_bypath(
+	git_index *index, const char *path, int stage)
+{
+	size_t pos;
+
+	assert(index);
+
+	if (index_find(&pos, index, path, 0, stage, true) < 0) {
+		giterr_set(GITERR_INDEX, "Index does not contain %s", path);
+		return NULL;
+	}
+
+	return git_index_get_byindex(index, pos);
+}
+
+void git_index_entry__init_from_stat(
+	git_index_entry *entry, struct stat *st, bool trust_mode)
+{
+	entry->ctime.seconds = (git_time_t)st->st_ctime;
+	entry->mtime.seconds = (git_time_t)st->st_mtime;
+	/* entry->mtime.nanoseconds = st->st_mtimensec; */
+	/* entry->ctime.nanoseconds = st->st_ctimensec; */
+	entry->dev  = st->st_rdev;
+	entry->ino  = st->st_ino;
+	entry->mode = (!trust_mode && S_ISREG(st->st_mode)) ?
+		git_index__create_mode(0666) : git_index__create_mode(st->st_mode);
+	entry->uid  = st->st_uid;
+	entry->gid  = st->st_gid;
+	entry->file_size = st->st_size;
+}
+
+static int index_entry_create(
+	git_index_entry **out,
+	git_repository *repo,
+	const char *path)
+{
+	size_t pathlen = strlen(path), alloclen;
+	struct entry_internal *entry;
+
+	if (!git_path_isvalid(repo, path,
+		GIT_PATH_REJECT_DEFAULTS | GIT_PATH_REJECT_DOT_GIT)) {
+		giterr_set(GITERR_INDEX, "Invalid path: '%s'", path);
+		return -1;
+	}
+
+	GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(struct entry_internal), pathlen);
+	GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
+	entry = git__calloc(1, alloclen);
+	GITERR_CHECK_ALLOC(entry);
+
+	entry->pathlen = pathlen;
+	memcpy(entry->path, path, pathlen);
+	entry->entry.path = entry->path;
+
+	*out = (git_index_entry *)entry;
+	return 0;
+}
+
+static int index_entry_init(
+	git_index_entry **entry_out,
+	git_index *index,
+	const char *rel_path)
+{
+	int error = 0;
+	git_index_entry *entry = NULL;
+	struct stat st;
+	git_oid oid;
+
+	if (INDEX_OWNER(index) == NULL)
+		return create_index_error(-1,
+			"Could not initialize index entry. "
+			"Index is not backed up by an existing repository.");
+
+	if (index_entry_create(&entry, INDEX_OWNER(index), rel_path) < 0)
+		return -1;
+
+	/* write the blob to disk and get the oid and stat info */
+	error = git_blob__create_from_paths(
+		&oid, &st, INDEX_OWNER(index), NULL, rel_path, 0, true);
+
+	if (error < 0) {
+		index_entry_free(entry);
+		return error;
+	}
+
+	entry->id = oid;
+	git_index_entry__init_from_stat(entry, &st, !index->distrust_filemode);
+
+	*entry_out = (git_index_entry *)entry;
+	return 0;
+}
+
+static git_index_reuc_entry *reuc_entry_alloc(const char *path)
+{
+	size_t pathlen = strlen(path),
+		structlen = sizeof(struct reuc_entry_internal),
+		alloclen;
+	struct reuc_entry_internal *entry;
+
+	if (GIT_ADD_SIZET_OVERFLOW(&alloclen, structlen, pathlen) ||
+		GIT_ADD_SIZET_OVERFLOW(&alloclen, alloclen, 1))
+		return NULL;
+
+	entry = git__calloc(1, alloclen);
+	if (!entry)
+		return NULL;
+
+	entry->pathlen = pathlen;
+	memcpy(entry->path, path, pathlen);
+	entry->entry.path = entry->path;
+
+	return (git_index_reuc_entry *)entry;
+}
+
+static int index_entry_reuc_init(git_index_reuc_entry **reuc_out,
+	const char *path,
+	int ancestor_mode, const git_oid *ancestor_oid,
+	int our_mode, const git_oid *our_oid,
+	int their_mode, const git_oid *their_oid)
+{
+	git_index_reuc_entry *reuc = NULL;
+
+	assert(reuc_out && path);
+
+	*reuc_out = reuc = reuc_entry_alloc(path);
+	GITERR_CHECK_ALLOC(reuc);
+
+	if ((reuc->mode[0] = ancestor_mode) > 0)
+		git_oid_cpy(&reuc->oid[0], ancestor_oid);
+
+	if ((reuc->mode[1] = our_mode) > 0)
+		git_oid_cpy(&reuc->oid[1], our_oid);
+
+	if ((reuc->mode[2] = their_mode) > 0)
+		git_oid_cpy(&reuc->oid[2], their_oid);
+
+	return 0;
+}
+
+static void index_entry_cpy(git_index_entry *tgt, const git_index_entry *src)
+{
+	const char *tgt_path = tgt->path;
+	memcpy(tgt, src, sizeof(*tgt));
+	tgt->path = tgt_path; /* reset to existing path data */
+}
+
+static int index_entry_dup(
+	git_index_entry **out,
+	git_repository *repo,
+	const git_index_entry *src)
+{
+	git_index_entry *entry;
+
+	if (!src) {
+		*out = NULL;
+		return 0;
+	}
+
+	if (index_entry_create(&entry, repo, src->path) < 0)
+		return -1;
+
+	index_entry_cpy(entry, src);
+	*out = entry;
+	return 0;
+}
+
+static int has_file_name(git_index *index,
+	 const git_index_entry *entry, size_t pos, int ok_to_replace)
+{
+	int retval = 0;
+	size_t len = strlen(entry->path);
+	int stage = GIT_IDXENTRY_STAGE(entry);
+	const char *name = entry->path;
+
+	while (pos < index->entries.length) {
+		struct entry_internal *p = index->entries.contents[pos++];
+
+		if (len >= p->pathlen)
+			break;
+		if (memcmp(name, p->path, len))
+			break;
+		if (GIT_IDXENTRY_STAGE(&p->entry) != stage)
+			continue;
+		if (p->path[len] != '/')
+			continue;
+		retval = -1;
+		if (!ok_to_replace)
+			break;
+
+		if (index_remove_entry(index, --pos) < 0)
+			break;
+	}
+	return retval;
+}
+
+/*
+ * Do we have another file with a pathname that is a proper
+ * subset of the name we're trying to add?
+ */
+static int has_dir_name(git_index *index,
+		const git_index_entry *entry, int ok_to_replace)
+{
+	int retval = 0;
+	int stage = GIT_IDXENTRY_STAGE(entry);
+	const char *name = entry->path;
+	const char *slash = name + strlen(name);
+
+	for (;;) {
+		size_t len, pos;
+
+		for (;;) {
+			if (*--slash == '/')
+				break;
+			if (slash <= entry->path)
+				return retval;
+		}
+		len = slash - name;
+
+		if (!index_find(&pos, index, name, len, stage, false)) {
+			retval = -1;
+			if (!ok_to_replace)
+				break;
+
+			if (index_remove_entry(index, pos) < 0)
+				break;
+			continue;
+		}
+
+		/*
+		 * Trivial optimization: if we find an entry that
+		 * already matches the sub-directory, then we know
+		 * we're ok, and we can exit.
+		 */
+		for (; pos < index->entries.length; ++pos) {
+			struct entry_internal *p = index->entries.contents[pos];
+
+			if (p->pathlen <= len ||
+			    p->path[len] != '/' ||
+			    memcmp(p->path, name, len))
+				break; /* not our subdirectory */
+
+			if (GIT_IDXENTRY_STAGE(&p->entry) == stage)
+				return retval;
+		}
+	}
+
+	return retval;
+}
+
+static int check_file_directory_collision(git_index *index,
+		git_index_entry *entry, size_t pos, int ok_to_replace)
+{
+	int retval = has_file_name(index, entry, pos, ok_to_replace);
+	retval = retval + has_dir_name(index, entry, ok_to_replace);
+
+	if (retval) {
+		giterr_set(GITERR_INDEX,
+			"'%s' appears as both a file and a directory", entry->path);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int index_no_dups(void **old, void *new)
+{
+	const git_index_entry *entry = new;
+	GIT_UNUSED(old);
+	giterr_set(GITERR_INDEX, "'%s' appears multiple times at stage %d",
+		entry->path, GIT_IDXENTRY_STAGE(entry));
+	return GIT_EEXISTS;
+}
+
+/* index_insert takes ownership of the new entry - if it can't insert
+ * it, then it will return an error **and also free the entry**.  When
+ * it replaces an existing entry, it will update the entry_ptr with the
+ * actual entry in the index (and free the passed in one).
+ * trust_mode is whether we trust the mode in entry_ptr.
+ */
+static int index_insert(
+	git_index *index, git_index_entry **entry_ptr, int replace, bool trust_mode)
+{
+	int error = 0;
+	size_t path_length, position;
+	git_index_entry *existing = NULL, *entry;
+
+	assert(index && entry_ptr);
+
+	entry = *entry_ptr;
+
+	/* make sure that the path length flag is correct */
+	path_length = ((struct entry_internal *)entry)->pathlen;
+
+	entry->flags &= ~GIT_IDXENTRY_NAMEMASK;
+
+	if (path_length < GIT_IDXENTRY_NAMEMASK)
+		entry->flags |= path_length & GIT_IDXENTRY_NAMEMASK;
+	else
+		entry->flags |= GIT_IDXENTRY_NAMEMASK;
+
+	if (git_mutex_lock(&index->lock) < 0) {
+		giterr_set(GITERR_OS, "Unable to acquire index lock");
+		return -1;
+	}
+
+	git_vector_sort(&index->entries);
+
+	/* look if an entry with this path already exists */
+	if (!index_find(
+			&position, index, entry->path, 0, GIT_IDXENTRY_STAGE(entry), false)) {
+		existing = index->entries.contents[position];
+		/* update filemode to existing values if stat is not trusted */
+		if (trust_mode)
+			entry->mode = git_index__create_mode(entry->mode);
+		else
+			entry->mode = index_merge_mode(index, existing, entry->mode);
+	}
+
+	/* look for tree / blob name collisions, removing conflicts if requested */
+	error = check_file_directory_collision(index, entry, position, replace);
+	if (error < 0)
+		/* skip changes */;
+
+	/* if we are replacing an existing item, overwrite the existing entry
+	 * and return it in place of the passed in one.
+	 */
+	else if (existing) {
+		if (replace)
+			index_entry_cpy(existing, entry);
+		index_entry_free(entry);
+		*entry_ptr = entry = existing;
+	}
+	else {
+		/* if replace is not requested or no existing entry exists, insert
+		 * at the sorted position.  (Since we re-sort after each insert to
+		 * check for dups, this is actually cheaper in the long run.)
+		 */
+		error = git_vector_insert_sorted(&index->entries, entry, index_no_dups);
+	}
+
+	if (error < 0) {
+		index_entry_free(*entry_ptr);
+		*entry_ptr = NULL;
+	}
+
+	git_mutex_unlock(&index->lock);
+
+	return error;
+}
+
+static int index_conflict_to_reuc(git_index *index, const char *path)
+{
+	const git_index_entry *conflict_entries[3];
+	int ancestor_mode, our_mode, their_mode;
+	git_oid const *ancestor_oid, *our_oid, *their_oid;
+	int ret;
+
+	if ((ret = git_index_conflict_get(&conflict_entries[0],
+		&conflict_entries[1], &conflict_entries[2], index, path)) < 0)
+		return ret;
+
+	ancestor_mode = conflict_entries[0] == NULL ? 0 : conflict_entries[0]->mode;
+	our_mode = conflict_entries[1] == NULL ? 0 : conflict_entries[1]->mode;
+	their_mode = conflict_entries[2] == NULL ? 0 : conflict_entries[2]->mode;
+
+	ancestor_oid = conflict_entries[0] == NULL ? NULL : &conflict_entries[0]->id;
+	our_oid = conflict_entries[1] == NULL ? NULL : &conflict_entries[1]->id;
+	their_oid = conflict_entries[2] == NULL ? NULL : &conflict_entries[2]->id;
+
+	if ((ret = git_index_reuc_add(index, path, ancestor_mode, ancestor_oid,
+		our_mode, our_oid, their_mode, their_oid)) >= 0)
+		ret = git_index_conflict_remove(index, path);
+
+	return ret;
+}
+
+static bool valid_filemode(const int filemode)
+{
+	return (filemode == GIT_FILEMODE_BLOB ||
+		filemode == GIT_FILEMODE_BLOB_EXECUTABLE ||
+		filemode == GIT_FILEMODE_LINK ||
+		filemode == GIT_FILEMODE_COMMIT);
+}
+
+int git_index_add_frombuffer(
+    git_index *index, const git_index_entry *source_entry,
+    const void *buffer, size_t len)
+{
+	git_index_entry *entry = NULL;
+	int error = 0;
+	git_oid id;
+
+	assert(index && source_entry->path);
+
+	if (INDEX_OWNER(index) == NULL)
+		return create_index_error(-1,
+			"Could not initialize index entry. "
+			"Index is not backed up by an existing repository.");
+
+	if (!valid_filemode(source_entry->mode)) {
+		giterr_set(GITERR_INDEX, "invalid filemode");
+		return -1;
+	}
+
+	if (index_entry_dup(&entry, INDEX_OWNER(index), source_entry) < 0)
+		return -1;
+
+	error = git_blob_create_frombuffer(&id, INDEX_OWNER(index), buffer, len);
+	if (error < 0) {
+		index_entry_free(entry);
+		return error;
+	}
+
+	git_oid_cpy(&entry->id, &id);
+	entry->file_size = len;
+
+	if ((error = index_insert(index, &entry, 1, true)) < 0)
+		return error;
+
+	/* Adding implies conflict was resolved, move conflict entries to REUC */
+	if ((error = index_conflict_to_reuc(index, entry->path)) < 0 && error != GIT_ENOTFOUND)
+		return error;
+
+	git_tree_cache_invalidate_path(index->tree, entry->path);
+	return 0;
+}
+
+static int add_repo_as_submodule(git_index_entry **out, git_index *index, const char *path)
+{
+	git_repository *sub;
+	git_buf abspath = GIT_BUF_INIT;
+	git_repository *repo = INDEX_OWNER(index);
+	git_reference *head;
+	git_index_entry *entry;
+	struct stat st;
+	int error;
+
+	if (index_entry_create(&entry, INDEX_OWNER(index), path) < 0)
+		return -1;
+
+	if ((error = git_buf_joinpath(&abspath, git_repository_workdir(repo), path)) < 0)
+		return error;
+
+	if ((error = p_stat(abspath.ptr, &st)) < 0) {
+		giterr_set(GITERR_OS, "failed to stat repository dir");
+		return -1;
+	}
+
+	git_index_entry__init_from_stat(entry, &st, !index->distrust_filemode);
+
+	if ((error = git_repository_open(&sub, abspath.ptr)) < 0)
+		return error;
+
+	if ((error = git_repository_head(&head, sub)) < 0)
+		return error;
+
+	git_oid_cpy(&entry->id, git_reference_target(head));
+	entry->mode = GIT_FILEMODE_COMMIT;
+
+	git_reference_free(head);
+	git_repository_free(sub);
+	git_buf_free(&abspath);
+
+	*out = entry;
+	return 0;
+}
+
+int git_index_add_bypath(git_index *index, const char *path)
+{
+	git_index_entry *entry = NULL;
+	int ret;
+
+	assert(index && path);
+
+	if ((ret = index_entry_init(&entry, index, path)) == 0)
+		ret = index_insert(index, &entry, 1, false);
+
+	/* If we were given a directory, let's see if it's a submodule */
+	if (ret < 0 && ret != GIT_EDIRECTORY)
+		return ret;
+
+	if (ret == GIT_EDIRECTORY) {
+		git_submodule *sm;
+		git_error_state err;
+
+		giterr_capture(&err, ret);
+
+		ret = git_submodule_lookup(&sm, INDEX_OWNER(index), path);
+		if (ret == GIT_ENOTFOUND)
+			return giterr_restore(&err);
+
+		git__free(err.error_msg.message);
+
+		/*
+		 * EEXISTS means that there is a repository at that path, but it's not known
+		 * as a submodule. We add its HEAD as an entry and don't register it.
+		 */
+		if (ret == GIT_EEXISTS) {
+			if ((ret = add_repo_as_submodule(&entry, index, path)) < 0)
+				return ret;
+
+			if ((ret = index_insert(index, &entry, 1, false)) < 0)
+				return ret;
+		} else if (ret < 0) {
+			return ret;
+		} else {
+			ret = git_submodule_add_to_index(sm, false);
+			git_submodule_free(sm);
+			return ret;
+		}
+	}
+
+	/* Adding implies conflict was resolved, move conflict entries to REUC */
+	if ((ret = index_conflict_to_reuc(index, path)) < 0 && ret != GIT_ENOTFOUND)
+		return ret;
+
+	git_tree_cache_invalidate_path(index->tree, entry->path);
+	return 0;
+}
+
+int git_index_remove_bypath(git_index *index, const char *path)
+{
+	int ret;
+
+	assert(index && path);
+
+	if (((ret = git_index_remove(index, path, 0)) < 0 &&
+		ret != GIT_ENOTFOUND) ||
+		((ret = index_conflict_to_reuc(index, path)) < 0 &&
+		ret != GIT_ENOTFOUND))
+		return ret;
+
+	if (ret == GIT_ENOTFOUND)
+		giterr_clear();
+
+	return 0;
+}
+
+
+int git_index_add(git_index *index, const git_index_entry *source_entry)
+{
+	git_index_entry *entry = NULL;
+	int ret;
+
+	assert(index && source_entry && source_entry->path);
+
+	if (!valid_filemode(source_entry->mode)) {
+		giterr_set(GITERR_INDEX, "invalid filemode");
+		return -1;
+	}
+
+	if ((ret = index_entry_dup(&entry, INDEX_OWNER(index), source_entry)) < 0 ||
+		(ret = index_insert(index, &entry, 1, true)) < 0)
+		return ret;
+
+	git_tree_cache_invalidate_path(index->tree, entry->path);
+	return 0;
+}
+
+int git_index_remove(git_index *index, const char *path, int stage)
+{
+	int error;
+	size_t position;
+
+	if (git_mutex_lock(&index->lock) < 0) {
+		giterr_set(GITERR_OS, "Failed to lock index");
+		return -1;
+	}
+
+	if (index_find(&position, index, path, 0, stage, false) < 0) {
+		giterr_set(
+			GITERR_INDEX, "Index does not contain %s at stage %d", path, stage);
+		error = GIT_ENOTFOUND;
+	} else {
+		error = index_remove_entry(index, position);
+	}
+
+	git_mutex_unlock(&index->lock);
+	return error;
+}
+
+int git_index_remove_directory(git_index *index, const char *dir, int stage)
+{
+	git_buf pfx = GIT_BUF_INIT;
+	int error = 0;
+	size_t pos;
+	git_index_entry *entry;
+
+	if (git_mutex_lock(&index->lock) < 0) {
+		giterr_set(GITERR_OS, "Failed to lock index");
+		return -1;
+	}
+
+	if (!(error = git_buf_sets(&pfx, dir)) &&
+		!(error = git_path_to_dir(&pfx)))
+		index_find(&pos, index, pfx.ptr, pfx.size, GIT_INDEX_STAGE_ANY, false);
+
+	while (!error) {
+		entry = git_vector_get(&index->entries, pos);
+		if (!entry || git__prefixcmp(entry->path, pfx.ptr) != 0)
+			break;
+
+		if (GIT_IDXENTRY_STAGE(entry) != stage) {
+			++pos;
+			continue;
+		}
+
+		error = index_remove_entry(index, pos);
+
+		/* removed entry at 'pos' so we don't need to increment */
+	}
+
+	git_mutex_unlock(&index->lock);
+	git_buf_free(&pfx);
+
+	return error;
+}
+
+int git_index__find_pos(
+	size_t *out, git_index *index, const char *path, size_t path_len, int stage)
+{
+	assert(index && path);
+	return index_find(out, index, path, path_len, stage, true);
+}
+
+int git_index_find(size_t *at_pos, git_index *index, const char *path)
+{
+	size_t pos;
+
+	assert(index && path);
+
+	if (git_mutex_lock(&index->lock) < 0) {
+		giterr_set(GITERR_OS, "Failed to lock index");
+		return -1;
+	}
+
+	if (git_vector_bsearch2(
+			&pos, &index->entries, index->entries_search_path, path) < 0) {
+		git_mutex_unlock(&index->lock);
+		giterr_set(GITERR_INDEX, "Index does not contain %s", path);
+		return GIT_ENOTFOUND;
+	}
+
+	/* Since our binary search only looked at path, we may be in the
+	 * middle of a list of stages.
+	 */
+	for (; pos > 0; --pos) {
+		const git_index_entry *prev = git_vector_get(&index->entries, pos - 1);
+
+		if (index->entries_cmp_path(prev->path, path) != 0)
+			break;
+	}
+
+	if (at_pos)
+		*at_pos = pos;
+
+	git_mutex_unlock(&index->lock);
+	return 0;
+}
+
+int git_index_conflict_add(git_index *index,
+	const git_index_entry *ancestor_entry,
+	const git_index_entry *our_entry,
+	const git_index_entry *their_entry)
+{
+	git_index_entry *entries[3] = { 0 };
+	unsigned short i;
+	int ret = 0;
+
+	assert (index);
+
+	if ((ret = index_entry_dup(&entries[0], INDEX_OWNER(index), ancestor_entry)) < 0 ||
+		(ret = index_entry_dup(&entries[1], INDEX_OWNER(index), our_entry)) < 0 ||
+		(ret = index_entry_dup(&entries[2], INDEX_OWNER(index), their_entry)) < 0)
+		goto on_error;
+
+	/* Validate entries */
+	for (i = 0; i < 3; i++) {
+		if (entries[i] && !valid_filemode(entries[i]->mode)) {
+			giterr_set(GITERR_INDEX, "invalid filemode for stage %d entry",
+				i);
+			return -1;
+		}
+	}
+
+	/* Remove existing index entries for each path */
+	for (i = 0; i < 3; i++) {
+		if (entries[i] == NULL)
+			continue;
+
+		if ((ret = git_index_remove(index, entries[i]->path, 0)) != 0) {
+			if (ret != GIT_ENOTFOUND)
+				goto on_error;
+
+			giterr_clear();
+			ret = 0;
+		}
+	}
+
+	/* Add the conflict entries */
+	for (i = 0; i < 3; i++) {
+		if (entries[i] == NULL)
+			continue;
+
+		/* Make sure stage is correct */
+		GIT_IDXENTRY_STAGE_SET(entries[i], i + 1);
+
+		if ((ret = index_insert(index, &entries[i], 0, true)) < 0)
+			goto on_error;
+
+		entries[i] = NULL; /* don't free if later entry fails */
+	}
+
+	return 0;
+
+on_error:
+	for (i = 0; i < 3; i++) {
+		if (entries[i] != NULL)
+			index_entry_free(entries[i]);
+	}
+
+	return ret;
+}
+
+static int index_conflict__get_byindex(
+	const git_index_entry **ancestor_out,
+	const git_index_entry **our_out,
+	const git_index_entry **their_out,
+	git_index *index,
+	size_t n)
+{
+	const git_index_entry *conflict_entry;
+	const char *path = NULL;
+	size_t count;
+	int stage, len = 0;
+
+	assert(ancestor_out && our_out && their_out && index);
+
+	*ancestor_out = NULL;
+	*our_out = NULL;
+	*their_out = NULL;
+
+	for (count = git_index_entrycount(index); n < count; ++n) {
+		conflict_entry = git_vector_get(&index->entries, n);
+
+		if (path && index->entries_cmp_path(conflict_entry->path, path) != 0)
+			break;
+
+		stage = GIT_IDXENTRY_STAGE(conflict_entry);
+		path = conflict_entry->path;
+
+		switch (stage) {
+		case 3:
+			*their_out = conflict_entry;
+			len++;
+			break;
+		case 2:
+			*our_out = conflict_entry;
+			len++;
+			break;
+		case 1:
+			*ancestor_out = conflict_entry;
+			len++;
+			break;
+		default:
+			break;
+		};
+	}
+
+	return len;
+}
+
+int git_index_conflict_get(
+	const git_index_entry **ancestor_out,
+	const git_index_entry **our_out,
+	const git_index_entry **their_out,
+	git_index *index,
+	const char *path)
+{
+	size_t pos;
+	int len = 0;
+
+	assert(ancestor_out && our_out && their_out && index && path);
+
+	*ancestor_out = NULL;
+	*our_out = NULL;
+	*their_out = NULL;
+
+	if (git_index_find(&pos, index, path) < 0)
+		return GIT_ENOTFOUND;
+
+	if ((len = index_conflict__get_byindex(
+		ancestor_out, our_out, their_out, index, pos)) < 0)
+		return len;
+	else if (len == 0)
+		return GIT_ENOTFOUND;
+
+	return 0;
+}
+
+static int index_conflict_remove(git_index *index, const char *path)
+{
+	size_t pos = 0;
+	git_index_entry *conflict_entry;
+	int error = 0;
+
+	if (path != NULL && git_index_find(&pos, index, path) < 0)
+		return GIT_ENOTFOUND;
+
+	if (git_mutex_lock(&index->lock) < 0) {
+		giterr_set(GITERR_OS, "Unable to lock index");
+		return -1;
+	}
+
+	while ((conflict_entry = git_vector_get(&index->entries, pos)) != NULL) {
+
+		if (path != NULL &&
+			index->entries_cmp_path(conflict_entry->path, path) != 0)
+			break;
+
+		if (GIT_IDXENTRY_STAGE(conflict_entry) == 0) {
+			pos++;
+			continue;
+		}
+
+		if ((error = index_remove_entry(index, pos)) < 0)
+			break;
+	}
+
+	git_mutex_unlock(&index->lock);
+
+	return error;
+}
+
+int git_index_conflict_remove(git_index *index, const char *path)
+{
+	assert(index && path);
+	return index_conflict_remove(index, path);
+}
+
+int git_index_conflict_cleanup(git_index *index)
+{
+	assert(index);
+	return index_conflict_remove(index, NULL);
+}
+
+int git_index_has_conflicts(const git_index *index)
+{
+	size_t i;
+	git_index_entry *entry;
+
+	assert(index);
+
+	git_vector_foreach(&index->entries, i, entry) {
+		if (GIT_IDXENTRY_STAGE(entry) > 0)
+			return 1;
+	}
+
+	return 0;
+}
+
+int git_index_conflict_iterator_new(
+	git_index_conflict_iterator **iterator_out,
+	git_index *index)
+{
+	git_index_conflict_iterator *it = NULL;
+
+	assert(iterator_out && index);
+
+	it = git__calloc(1, sizeof(git_index_conflict_iterator));
+	GITERR_CHECK_ALLOC(it);
+
+	it->index = index;
+
+	*iterator_out = it;
+	return 0;
+}
+
+int git_index_conflict_next(
+	const git_index_entry **ancestor_out,
+	const git_index_entry **our_out,
+	const git_index_entry **their_out,
+	git_index_conflict_iterator *iterator)
+{
+	const git_index_entry *entry;
+	int len;
+
+	assert(ancestor_out && our_out && their_out && iterator);
+
+	*ancestor_out = NULL;
+	*our_out = NULL;
+	*their_out = NULL;
+
+	while (iterator->cur < iterator->index->entries.length) {
+		entry = git_index_get_byindex(iterator->index, iterator->cur);
+
+		if (git_index_entry_is_conflict(entry)) {
+			if ((len = index_conflict__get_byindex(
+				ancestor_out,
+				our_out,
+				their_out,
+				iterator->index,
+				iterator->cur)) < 0)
+				return len;
+
+			iterator->cur += len;
+			return 0;
+		}
+
+		iterator->cur++;
+	}
+
+	return GIT_ITEROVER;
+}
+
+void git_index_conflict_iterator_free(git_index_conflict_iterator *iterator)
+{
+	if (iterator == NULL)
+		return;
+
+	git__free(iterator);
+}
+
+size_t git_index_name_entrycount(git_index *index)
+{
+	assert(index);
+	return index->names.length;
+}
+
+const git_index_name_entry *git_index_name_get_byindex(
+	git_index *index, size_t n)
+{
+	assert(index);
+
+	git_vector_sort(&index->names);
+	return git_vector_get(&index->names, n);
+}
+
+static void index_name_entry_free(git_index_name_entry *ne)
+{
+	if (!ne)
+		return;
+	git__free(ne->ancestor);
+	git__free(ne->ours);
+	git__free(ne->theirs);
+	git__free(ne);
+}
+
+int git_index_name_add(git_index *index,
+	const char *ancestor, const char *ours, const char *theirs)
+{
+	git_index_name_entry *conflict_name;
+
+	assert((ancestor && ours) || (ancestor && theirs) || (ours && theirs));
+
+	conflict_name = git__calloc(1, sizeof(git_index_name_entry));
+	GITERR_CHECK_ALLOC(conflict_name);
+
+	if ((ancestor && !(conflict_name->ancestor = git__strdup(ancestor))) ||
+		(ours     && !(conflict_name->ours     = git__strdup(ours))) ||
+		(theirs   && !(conflict_name->theirs   = git__strdup(theirs))) ||
+		git_vector_insert(&index->names, conflict_name) < 0)
+	{
+		index_name_entry_free(conflict_name);
+		return -1;
+	}
+
+	return 0;
+}
+
+void git_index_name_clear(git_index *index)
+{
+	size_t i;
+	git_index_name_entry *conflict_name;
+
+	assert(index);
+
+	git_vector_foreach(&index->names, i, conflict_name)
+		index_name_entry_free(conflict_name);
+
+	git_vector_clear(&index->names);
+}
+
+size_t git_index_reuc_entrycount(git_index *index)
+{
+	assert(index);
+	return index->reuc.length;
+}
+
+static int index_reuc_insert(
+	git_index *index,
+	git_index_reuc_entry *reuc,
+	int replace)
+{
+	git_index_reuc_entry **existing = NULL;
+	size_t position;
+
+	assert(index && reuc && reuc->path != NULL);
+
+	if (!git_index_reuc_find(&position, index, reuc->path))
+		existing = (git_index_reuc_entry **)&index->reuc.contents[position];
+
+	if (!replace || !existing)
+		return git_vector_insert(&index->reuc, reuc);
+
+	/* exists, replace it */
+	git__free(*existing);
+	*existing = reuc;
+
+	return 0;
+}
+
+int git_index_reuc_add(git_index *index, const char *path,
+	int ancestor_mode, const git_oid *ancestor_oid,
+	int our_mode, const git_oid *our_oid,
+	int their_mode, const git_oid *their_oid)
+{
+	git_index_reuc_entry *reuc = NULL;
+	int error = 0;
+
+	assert(index && path);
+
+	if ((error = index_entry_reuc_init(&reuc, path, ancestor_mode,
+			ancestor_oid, our_mode, our_oid, their_mode, their_oid)) < 0 ||
+		(error = index_reuc_insert(index, reuc, 1)) < 0)
+		index_entry_reuc_free(reuc);
+
+	return error;
+}
+
+int git_index_reuc_find(size_t *at_pos, git_index *index, const char *path)
+{
+	return git_vector_bsearch2(at_pos, &index->reuc, index->reuc_search, path);
+}
+
+const git_index_reuc_entry *git_index_reuc_get_bypath(
+	git_index *index, const char *path)
+{
+	size_t pos;
+	assert(index && path);
+
+	if (!index->reuc.length)
+		return NULL;
+
+	git_vector_sort(&index->reuc);
+
+	if (git_index_reuc_find(&pos, index, path) < 0)
+		return NULL;
+
+	return git_vector_get(&index->reuc, pos);
+}
+
+const git_index_reuc_entry *git_index_reuc_get_byindex(
+	git_index *index, size_t n)
+{
+	assert(index);
+
+	git_vector_sort(&index->reuc);
+	return git_vector_get(&index->reuc, n);
+}
+
+int git_index_reuc_remove(git_index *index, size_t position)
+{
+	int error;
+	git_index_reuc_entry *reuc;
+
+	git_vector_sort(&index->reuc);
+
+	reuc = git_vector_get(&index->reuc, position);
+	error = git_vector_remove(&index->reuc, position);
+
+	if (!error)
+		index_entry_reuc_free(reuc);
+
+	return error;
+}
+
+void git_index_reuc_clear(git_index *index)
+{
+	size_t i;
+
+	assert(index);
+
+	for (i = 0; i < index->reuc.length; ++i)
+		index_entry_reuc_free(git__swap(index->reuc.contents[i], NULL));
+
+	git_vector_clear(&index->reuc);
+}
+
+static int index_error_invalid(const char *message)
+{
+	giterr_set(GITERR_INDEX, "Invalid data in index - %s", message);
+	return -1;
+}
+
+static int read_reuc(git_index *index, const char *buffer, size_t size)
+{
+	const char *endptr;
+	size_t len;
+	int i;
+
+	/* If called multiple times, the vector might already be initialized */
+	if (index->reuc._alloc_size == 0 &&
+		git_vector_init(&index->reuc, 16, reuc_cmp) < 0)
+		return -1;
+
+	while (size) {
+		git_index_reuc_entry *lost;
+
+		len = p_strnlen(buffer, size) + 1;
+		if (size <= len)
+			return index_error_invalid("reading reuc entries");
+
+		lost = reuc_entry_alloc(buffer);
+		GITERR_CHECK_ALLOC(lost);
+
+		size -= len;
+		buffer += len;
+
+		/* read 3 ASCII octal numbers for stage entries */
+		for (i = 0; i < 3; i++) {
+			int tmp;
+
+			if (git__strtol32(&tmp, buffer, &endptr, 8) < 0 ||
+				!endptr || endptr == buffer || *endptr ||
+				(unsigned)tmp > UINT_MAX) {
+				index_entry_reuc_free(lost);
+				return index_error_invalid("reading reuc entry stage");
+			}
+
+			lost->mode[i] = tmp;
+
+			len = (endptr + 1) - buffer;
+			if (size <= len) {
+				index_entry_reuc_free(lost);
+				return index_error_invalid("reading reuc entry stage");
+			}
+
+			size -= len;
+			buffer += len;
+		}
+
+		/* read up to 3 OIDs for stage entries */
+		for (i = 0; i < 3; i++) {
+			if (!lost->mode[i])
+				continue;
+			if (size < 20) {
+				index_entry_reuc_free(lost);
+				return index_error_invalid("reading reuc entry oid");
+			}
+
+			git_oid_fromraw(&lost->oid[i], (const unsigned char *) buffer);
+			size -= 20;
+			buffer += 20;
+		}
+
+		/* entry was read successfully - insert into reuc vector */
+		if (git_vector_insert(&index->reuc, lost) < 0)
+			return -1;
+	}
+
+	/* entries are guaranteed to be sorted on-disk */
+	git_vector_set_sorted(&index->reuc, true);
+
+	return 0;
+}
+
+
+static int read_conflict_names(git_index *index, const char *buffer, size_t size)
+{
+	size_t len;
+
+	/* This gets called multiple times, the vector might already be initialized */
+	if (index->names._alloc_size == 0 &&
+		git_vector_init(&index->names, 16, conflict_name_cmp) < 0)
+		return -1;
+
+#define read_conflict_name(ptr) \
+	len = p_strnlen(buffer, size) + 1; \
+	if (size < len) \
+		return index_error_invalid("reading conflict name entries"); \
+	\
+	if (len == 1) \
+		ptr = NULL; \
+	else { \
+		ptr = git__malloc(len); \
+		GITERR_CHECK_ALLOC(ptr); \
+		memcpy(ptr, buffer, len); \
+	} \
+	\
+	buffer += len; \
+	size -= len;
+
+	while (size) {
+		git_index_name_entry *conflict_name = git__calloc(1, sizeof(git_index_name_entry));
+		GITERR_CHECK_ALLOC(conflict_name);
+
+		read_conflict_name(conflict_name->ancestor);
+		read_conflict_name(conflict_name->ours);
+		read_conflict_name(conflict_name->theirs);
+
+		if (git_vector_insert(&index->names, conflict_name) < 0)
+			return -1;
+	}
+
+#undef read_conflict_name
+
+	/* entries are guaranteed to be sorted on-disk */
+	git_vector_set_sorted(&index->names, true);
+
+	return 0;
+}
+
+static size_t read_entry(
+	git_index_entry **out,
+	git_index *index,
+	const void *buffer,
+	size_t buffer_size)
+{
+	size_t path_length, entry_size;
+	const char *path_ptr;
+	struct entry_short source;
+	git_index_entry entry = {{0}};
+
+	if (INDEX_FOOTER_SIZE + minimal_entry_size > buffer_size)
+		return 0;
+
+	/* buffer is not guaranteed to be aligned */
+	memcpy(&source, buffer, sizeof(struct entry_short));
+
+	entry.ctime.seconds = (git_time_t)ntohl(source.ctime.seconds);
+	entry.ctime.nanoseconds = ntohl(source.ctime.nanoseconds);
+	entry.mtime.seconds = (git_time_t)ntohl(source.mtime.seconds);
+	entry.mtime.nanoseconds = ntohl(source.mtime.nanoseconds);
+	entry.dev = ntohl(source.dev);
+	entry.ino = ntohl(source.ino);
+	entry.mode = ntohl(source.mode);
+	entry.uid = ntohl(source.uid);
+	entry.gid = ntohl(source.gid);
+	entry.file_size = ntohl(source.file_size);
+	git_oid_cpy(&entry.id, &source.oid);
+	entry.flags = ntohs(source.flags);
+
+	if (entry.flags & GIT_IDXENTRY_EXTENDED) {
+		uint16_t flags_raw;
+		size_t flags_offset;
+
+		flags_offset = offsetof(struct entry_long, flags_extended);
+		memcpy(&flags_raw, (const char *) buffer + flags_offset,
+			sizeof(flags_raw));
+		flags_raw = ntohs(flags_raw);
+
+		memcpy(&entry.flags_extended, &flags_raw, sizeof(flags_raw));
+		path_ptr = (const char *) buffer + offsetof(struct entry_long, path);
+	} else
+		path_ptr = (const char *) buffer + offsetof(struct entry_short, path);
+
+	path_length = entry.flags & GIT_IDXENTRY_NAMEMASK;
+
+	/* if this is a very long string, we must find its
+	 * real length without overflowing */
+	if (path_length == 0xFFF) {
+		const char *path_end;
+
+		path_end = memchr(path_ptr, '\0', buffer_size);
+		if (path_end == NULL)
+			return 0;
+
+		path_length = path_end - path_ptr;
+	}
+
+	if (entry.flags & GIT_IDXENTRY_EXTENDED)
+		entry_size = long_entry_size(path_length);
+	else
+		entry_size = short_entry_size(path_length);
+
+	if (INDEX_FOOTER_SIZE + entry_size > buffer_size)
+		return 0;
+
+	entry.path = (char *)path_ptr;
+
+	if (index_entry_dup(out, INDEX_OWNER(index), &entry) < 0)
+		return 0;
+
+	return entry_size;
+}
+
+static int read_header(struct index_header *dest, const void *buffer)
+{
+	const struct index_header *source = buffer;
+
+	dest->signature = ntohl(source->signature);
+	if (dest->signature != INDEX_HEADER_SIG)
+		return index_error_invalid("incorrect header signature");
+
+	dest->version = ntohl(source->version);
+	if (dest->version != INDEX_VERSION_NUMBER_EXT &&
+		dest->version != INDEX_VERSION_NUMBER)
+		return index_error_invalid("incorrect header version");
+
+	dest->entry_count = ntohl(source->entry_count);
+	return 0;
+}
+
+static size_t read_extension(git_index *index, const char *buffer, size_t buffer_size)
+{
+	struct index_extension dest;
+	size_t total_size;
+
+	/* buffer is not guaranteed to be aligned */
+	memcpy(&dest, buffer, sizeof(struct index_extension));
+	dest.extension_size = ntohl(dest.extension_size);
+
+	total_size = dest.extension_size + sizeof(struct index_extension);
+
+	if (dest.extension_size > total_size ||
+		buffer_size < total_size ||
+		buffer_size - total_size < INDEX_FOOTER_SIZE)
+		return 0;
+
+	/* optional extension */
+	if (dest.signature[0] >= 'A' && dest.signature[0] <= 'Z') {
+		/* tree cache */
+		if (memcmp(dest.signature, INDEX_EXT_TREECACHE_SIG, 4) == 0) {
+			if (git_tree_cache_read(&index->tree, buffer + 8, dest.extension_size, &index->tree_pool) < 0)
+				return 0;
+		} else if (memcmp(dest.signature, INDEX_EXT_UNMERGED_SIG, 4) == 0) {
+			if (read_reuc(index, buffer + 8, dest.extension_size) < 0)
+				return 0;
+		} else if (memcmp(dest.signature, INDEX_EXT_CONFLICT_NAME_SIG, 4) == 0) {
+			if (read_conflict_names(index, buffer + 8, dest.extension_size) < 0)
+				return 0;
+		}
+		/* else, unsupported extension. We cannot parse this, but we can skip
+		 * it by returning `total_size */
+	} else {
+		/* we cannot handle non-ignorable extensions;
+		 * in fact they aren't even defined in the standard */
+		return 0;
+	}
+
+	return total_size;
+}
+
+static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
+{
+	int error = 0;
+	unsigned int i;
+	struct index_header header = { 0 };
+	git_oid checksum_calculated, checksum_expected;
+
+#define seek_forward(_increase) { \
+	if (_increase >= buffer_size) { \
+		error = index_error_invalid("ran out of data while parsing"); \
+		goto done; } \
+	buffer += _increase; \
+	buffer_size -= _increase;\
+}
+
+	if (buffer_size < INDEX_HEADER_SIZE + INDEX_FOOTER_SIZE)
+		return index_error_invalid("insufficient buffer space");
+
+	/* Precalculate the SHA1 of the files's contents -- we'll match it to
+	 * the provided SHA1 in the footer */
+	git_hash_buf(&checksum_calculated, buffer, buffer_size - INDEX_FOOTER_SIZE);
+
+	/* Parse header */
+	if ((error = read_header(&header, buffer)) < 0)
+		return error;
+
+	seek_forward(INDEX_HEADER_SIZE);
+
+	if (git_mutex_lock(&index->lock) < 0) {
+		giterr_set(GITERR_OS, "Unable to acquire index lock");
+		return -1;
+	}
+
+	assert(!index->entries.length);
+
+	/* Parse all the entries */
+	for (i = 0; i < header.entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) {
+		git_index_entry *entry;
+		size_t entry_size = read_entry(&entry, index, buffer, buffer_size);
+
+		/* 0 bytes read means an object corruption */
+		if (entry_size == 0) {
+			error = index_error_invalid("invalid entry");
+			goto done;
+		}
+
+		if ((error = git_vector_insert(&index->entries, entry)) < 0) {
+			index_entry_free(entry);
+			goto done;
+		}
+
+		seek_forward(entry_size);
+	}
+
+	if (i != header.entry_count) {
+		error = index_error_invalid("header entries changed while parsing");
+		goto done;
+	}
+
+	/* There's still space for some extensions! */
+	while (buffer_size > INDEX_FOOTER_SIZE) {
+		size_t extension_size;
+
+		extension_size = read_extension(index, buffer, buffer_size);
+
+		/* see if we have read any bytes from the extension */
+		if (extension_size == 0) {
+			error = index_error_invalid("extension is truncated");
+			goto done;
+		}
+
+		seek_forward(extension_size);
+	}
+
+	if (buffer_size != INDEX_FOOTER_SIZE) {
+		error = index_error_invalid(
+			"buffer size does not match index footer size");
+		goto done;
+	}
+
+	/* 160-bit SHA-1 over the content of the index file before this checksum. */
+	git_oid_fromraw(&checksum_expected, (const unsigned char *)buffer);
+
+	if (git_oid__cmp(&checksum_calculated, &checksum_expected) != 0) {
+		error = index_error_invalid(
+			"calculated checksum does not match expected");
+		goto done;
+	}
+
+	git_oid_cpy(&index->checksum, &checksum_calculated);
+
+#undef seek_forward
+
+	/* Entries are stored case-sensitively on disk, so re-sort now if
+	 * in-memory index is supposed to be case-insensitive
+	 */
+	git_vector_set_sorted(&index->entries, !index->ignore_case);
+	error = index_sort_if_needed(index, false);
+
+done:
+	git_mutex_unlock(&index->lock);
+	return error;
+}
+
+static bool is_index_extended(git_index *index)
+{
+	size_t i, extended;
+	git_index_entry *entry;
+
+	extended = 0;
+
+	git_vector_foreach(&index->entries, i, entry) {
+		entry->flags &= ~GIT_IDXENTRY_EXTENDED;
+		if (entry->flags_extended & GIT_IDXENTRY_EXTENDED_FLAGS) {
+			extended++;
+			entry->flags |= GIT_IDXENTRY_EXTENDED;
+		}
+	}
+
+	return (extended > 0);
+}
+
+static int write_disk_entry(git_filebuf *file, git_index_entry *entry)
+{
+	void *mem = NULL;
+	struct entry_short *ondisk;
+	size_t path_len, disk_size;
+	char *path;
+
+	path_len = ((struct entry_internal *)entry)->pathlen;
+
+	if (entry->flags & GIT_IDXENTRY_EXTENDED)
+		disk_size = long_entry_size(path_len);
+	else
+		disk_size = short_entry_size(path_len);
+
+	if (git_filebuf_reserve(file, &mem, disk_size) < 0)
+		return -1;
+
+	ondisk = (struct entry_short *)mem;
+
+	memset(ondisk, 0x0, disk_size);
+
+	/**
+	 * Yes, we have to truncate.
+	 *
+	 * The on-disk format for Index entries clearly defines
+	 * the time and size fields to be 4 bytes each -- so even if
+	 * we store these values with 8 bytes on-memory, they must
+	 * be truncated to 4 bytes before writing to disk.
+	 *
+	 * In 2038 I will be either too dead or too rich to care about this
+	 */
+	ondisk->ctime.seconds = htonl((uint32_t)entry->ctime.seconds);
+	ondisk->mtime.seconds = htonl((uint32_t)entry->mtime.seconds);
+	ondisk->ctime.nanoseconds = htonl(entry->ctime.nanoseconds);
+	ondisk->mtime.nanoseconds = htonl(entry->mtime.nanoseconds);
+	ondisk->dev = htonl(entry->dev);
+	ondisk->ino = htonl(entry->ino);
+	ondisk->mode = htonl(entry->mode);
+	ondisk->uid = htonl(entry->uid);
+	ondisk->gid = htonl(entry->gid);
+	ondisk->file_size = htonl((uint32_t)entry->file_size);
+
+	git_oid_cpy(&ondisk->oid, &entry->id);
+
+	ondisk->flags = htons(entry->flags);
+
+	if (entry->flags & GIT_IDXENTRY_EXTENDED) {
+		struct entry_long *ondisk_ext;
+		ondisk_ext = (struct entry_long *)ondisk;
+		ondisk_ext->flags_extended = htons(entry->flags_extended);
+		path = ondisk_ext->path;
+	}
+	else
+		path = ondisk->path;
+
+	memcpy(path, entry->path, path_len);
+
+	return 0;
+}
+
+static int write_entries(git_index *index, git_filebuf *file)
+{
+	int error = 0;
+	size_t i;
+	git_vector case_sorted, *entries;
+	git_index_entry *entry;
+
+	if (git_mutex_lock(&index->lock) < 0) {
+		giterr_set(GITERR_OS, "Failed to lock index");
+		return -1;
+	}
+
+	/* If index->entries is sorted case-insensitively, then we need
+	 * to re-sort it case-sensitively before writing */
+	if (index->ignore_case) {
+		git_vector_dup(&case_sorted, &index->entries, git_index_entry_cmp);
+		git_vector_sort(&case_sorted);
+		entries = &case_sorted;
+	} else {
+		entries = &index->entries;
+	}
+
+	git_vector_foreach(entries, i, entry)
+		if ((error = write_disk_entry(file, entry)) < 0)
+			break;
+
+	git_mutex_unlock(&index->lock);
+
+	if (index->ignore_case)
+		git_vector_free(&case_sorted);
+
+	return error;
+}
+
+static int write_extension(git_filebuf *file, struct index_extension *header, git_buf *data)
+{
+	struct index_extension ondisk;
+
+	memset(&ondisk, 0x0, sizeof(struct index_extension));
+	memcpy(&ondisk, header, 4);
+	ondisk.extension_size = htonl(header->extension_size);
+
+	git_filebuf_write(file, &ondisk, sizeof(struct index_extension));
+	return git_filebuf_write(file, data->ptr, data->size);
+}
+
+static int create_name_extension_data(git_buf *name_buf, git_index_name_entry *conflict_name)
+{
+	int error = 0;
+
+	if (conflict_name->ancestor == NULL)
+		error = git_buf_put(name_buf, "\0", 1);
+	else
+		error = git_buf_put(name_buf, conflict_name->ancestor, strlen(conflict_name->ancestor) + 1);
+
+	if (error != 0)
+		goto on_error;
+
+	if (conflict_name->ours == NULL)
+		error = git_buf_put(name_buf, "\0", 1);
+	else
+		error = git_buf_put(name_buf, conflict_name->ours, strlen(conflict_name->ours) + 1);
+
+	if (error != 0)
+		goto on_error;
+
+	if (conflict_name->theirs == NULL)
+		error = git_buf_put(name_buf, "\0", 1);
+	else
+		error = git_buf_put(name_buf, conflict_name->theirs, strlen(conflict_name->theirs) + 1);
+
+on_error:
+	return error;
+}
+
+static int write_name_extension(git_index *index, git_filebuf *file)
+{
+	git_buf name_buf = GIT_BUF_INIT;
+	git_vector *out = &index->names;
+	git_index_name_entry *conflict_name;
+	struct index_extension extension;
+	size_t i;
+	int error = 0;
+
+	git_vector_foreach(out, i, conflict_name) {
+		if ((error = create_name_extension_data(&name_buf, conflict_name)) < 0)
+			goto done;
+	}
+
+	memset(&extension, 0x0, sizeof(struct index_extension));
+	memcpy(&extension.signature, INDEX_EXT_CONFLICT_NAME_SIG, 4);
+	extension.extension_size = (uint32_t)name_buf.size;
+
+	error = write_extension(file, &extension, &name_buf);
+
+	git_buf_free(&name_buf);
+
+done:
+	return error;
+}
+
+static int create_reuc_extension_data(git_buf *reuc_buf, git_index_reuc_entry *reuc)
+{
+	int i;
+	int error = 0;
+
+	if ((error = git_buf_put(reuc_buf, reuc->path, strlen(reuc->path) + 1)) < 0)
+		return error;
+
+	for (i = 0; i < 3; i++) {
+		if ((error = git_buf_printf(reuc_buf, "%o", reuc->mode[i])) < 0 ||
+			(error = git_buf_put(reuc_buf, "\0", 1)) < 0)
+			return error;
+	}
+
+	for (i = 0; i < 3; i++) {
+		if (reuc->mode[i] && (error = git_buf_put(reuc_buf, (char *)&reuc->oid[i].id, GIT_OID_RAWSZ)) < 0)
+			return error;
+	}
+
+	return 0;
+}
+
+static int write_reuc_extension(git_index *index, git_filebuf *file)
+{
+	git_buf reuc_buf = GIT_BUF_INIT;
+	git_vector *out = &index->reuc;
+	git_index_reuc_entry *reuc;
+	struct index_extension extension;
+	size_t i;
+	int error = 0;
+
+	git_vector_foreach(out, i, reuc) {
+		if ((error = create_reuc_extension_data(&reuc_buf, reuc)) < 0)
+			goto done;
+	}
+
+	memset(&extension, 0x0, sizeof(struct index_extension));
+	memcpy(&extension.signature, INDEX_EXT_UNMERGED_SIG, 4);
+	extension.extension_size = (uint32_t)reuc_buf.size;
+
+	error = write_extension(file, &extension, &reuc_buf);
+
+	git_buf_free(&reuc_buf);
+
+done:
+	return error;
+}
+
+static int write_tree_extension(git_index *index, git_filebuf *file)
+{
+	struct index_extension extension;
+	git_buf buf = GIT_BUF_INIT;
+	int error;
+
+	if (index->tree == NULL)
+		return 0;
+
+	if ((error = git_tree_cache_write(&buf, index->tree)) < 0)
+		return error;
+
+	memset(&extension, 0x0, sizeof(struct index_extension));
+	memcpy(&extension.signature, INDEX_EXT_TREECACHE_SIG, 4);
+	extension.extension_size = (uint32_t)buf.size;
+
+	error = write_extension(file, &extension, &buf);
+
+	git_buf_free(&buf);
+
+	return error;
+}
+
+static int write_index(git_oid *checksum, git_index *index, git_filebuf *file)
+{
+	git_oid hash_final;
+	struct index_header header;
+	bool is_extended;
+	uint32_t index_version_number;
+
+	assert(index && file);
+
+	is_extended = is_index_extended(index);
+	index_version_number = is_extended ? INDEX_VERSION_NUMBER_EXT : INDEX_VERSION_NUMBER;
+
+	header.signature = htonl(INDEX_HEADER_SIG);
+	header.version = htonl(index_version_number);
+	header.entry_count = htonl((uint32_t)index->entries.length);
+
+	if (git_filebuf_write(file, &header, sizeof(struct index_header)) < 0)
+		return -1;
+
+	if (write_entries(index, file) < 0)
+		return -1;
+
+	/* write the tree cache extension */
+	if (index->tree != NULL && write_tree_extension(index, file) < 0)
+		return -1;
+
+	/* write the rename conflict extension */
+	if (index->names.length > 0 && write_name_extension(index, file) < 0)
+		return -1;
+
+	/* write the reuc extension */
+	if (index->reuc.length > 0 && write_reuc_extension(index, file) < 0)
+		return -1;
+
+	/* get out the hash for all the contents we've appended to the file */
+	git_filebuf_hash(&hash_final, file);
+	git_oid_cpy(checksum, &hash_final);
+
+	/* write it at the end of the file */
+	return git_filebuf_write(file, hash_final.id, GIT_OID_RAWSZ);
+}
+
+int git_index_entry_stage(const git_index_entry *entry)
+{
+	return GIT_IDXENTRY_STAGE(entry);
+}
+
+int git_index_entry_is_conflict(const git_index_entry *entry)
+{
+	return (GIT_IDXENTRY_STAGE(entry) > 0);
+}
+
+typedef struct read_tree_data {
+	git_index *index;
+	git_vector *old_entries;
+	git_vector *new_entries;
+	git_vector_cmp entry_cmp;
+	git_tree_cache *tree;
+} read_tree_data;
+
+static int read_tree_cb(
+	const char *root, const git_tree_entry *tentry, void *payload)
+{
+	read_tree_data *data = payload;
+	git_index_entry *entry = NULL, *old_entry;
+	git_buf path = GIT_BUF_INIT;
+	size_t pos;
+
+	if (git_tree_entry__is_tree(tentry))
+		return 0;
+
+	if (git_buf_joinpath(&path, root, tentry->filename) < 0)
+		return -1;
+
+	if (index_entry_create(&entry, INDEX_OWNER(data->index), path.ptr) < 0)
+		return -1;
+
+	entry->mode = tentry->attr;
+	entry->id = tentry->oid;
+
+	/* look for corresponding old entry and copy data to new entry */
+	if (data->old_entries != NULL &&
+		!index_find_in_entries(
+			&pos, data->old_entries, data->entry_cmp, path.ptr, 0, 0) &&
+		(old_entry = git_vector_get(data->old_entries, pos)) != NULL &&
+		entry->mode == old_entry->mode &&
+		git_oid_equal(&entry->id, &old_entry->id))
+	{
+		index_entry_cpy(entry, old_entry);
+		entry->flags_extended = 0;
+	}
+
+	if (path.size < GIT_IDXENTRY_NAMEMASK)
+		entry->flags = path.size & GIT_IDXENTRY_NAMEMASK;
+	else
+		entry->flags = GIT_IDXENTRY_NAMEMASK;
+
+	git_buf_free(&path);
+
+	if (git_vector_insert(data->new_entries, entry) < 0) {
+		index_entry_free(entry);
+		return -1;
+	}
+
+	return 0;
+}
+
+int git_index_read_tree(git_index *index, const git_tree *tree)
+{
+	int error = 0;
+	git_vector entries = GIT_VECTOR_INIT;
+	read_tree_data data;
+
+	git_vector_set_cmp(&entries, index->entries._cmp); /* match sort */
+
+	data.index = index;
+	data.old_entries = &index->entries;
+	data.new_entries = &entries;
+	data.entry_cmp   = index->entries_search;
+
+	index->tree = NULL;
+	git_pool_clear(&index->tree_pool);
+
+	if (index_sort_if_needed(index, true) < 0)
+		return -1;
+
+	error = git_tree_walk(tree, GIT_TREEWALK_POST, read_tree_cb, &data);
+
+	if (!error) {
+		git_vector_sort(&entries);
+
+		if ((error = git_index_clear(index)) < 0)
+			/* well, this isn't good */;
+		else if (git_mutex_lock(&index->lock) < 0) {
+			giterr_set(GITERR_OS, "Unable to acquire index lock");
+			error = -1;
+		} else {
+			git_vector_swap(&entries, &index->entries);
+			git_mutex_unlock(&index->lock);
+		}
+	}
+
+	git_vector_free(&entries);
+	if (error < 0)
+		return error;
+
+	error = git_tree_cache_read_tree(&index->tree, tree, &index->tree_pool);
+
+	return error;
+}
+
+int git_index_read_index(
+	git_index *index,
+	const git_index *new_index)
+{
+	git_vector new_entries = GIT_VECTOR_INIT,
+		remove_entries = GIT_VECTOR_INIT;
+	git_iterator *index_iterator = NULL;
+	git_iterator *new_iterator = NULL;
+	const git_index_entry *old_entry, *new_entry;
+	git_index_entry *entry;
+	size_t i;
+	int error;
+
+	if ((error = git_vector_init(&new_entries, new_index->entries.length, index->entries._cmp)) < 0 ||
+		(error = git_vector_init(&remove_entries, index->entries.length, NULL)) < 0)
+		goto done;
+
+	if ((error = git_iterator_for_index(&index_iterator,
+			index, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
+		(error = git_iterator_for_index(&new_iterator,
+			(git_index *)new_index, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0)
+		goto done;
+
+	if (((error = git_iterator_current(&old_entry, index_iterator)) < 0 && 
+			error != GIT_ITEROVER) ||
+		((error = git_iterator_current(&new_entry, new_iterator)) < 0 && 
+			error != GIT_ITEROVER))
+		goto done;
+
+	while (true) {
+		int diff;
+
+		if (old_entry && new_entry)
+			diff = git_index_entry_cmp(old_entry, new_entry);
+		else if (!old_entry && new_entry)
+			diff = 1;
+		else if (old_entry && !new_entry)
+			diff = -1;
+		else
+			break;
+
+		if (diff < 0) {
+			git_vector_insert(&remove_entries, (git_index_entry *)old_entry);
+		} else if (diff > 0) {
+			if ((error = index_entry_dup(&entry, git_index_owner(index), new_entry)) < 0)
+				goto done;
+
+			git_vector_insert(&new_entries, entry);
+		} else {
+			/* Path and stage are equal, if the OID is equal, keep it to
+			 * keep the stat cache data.
+			 */
+			if (git_oid_equal(&old_entry->id, &new_entry->id)) {
+				git_vector_insert(&new_entries, (git_index_entry *)old_entry);
+			} else {
+				if ((error = index_entry_dup(&entry, git_index_owner(index), new_entry)) < 0)
+					goto done;
+
+				git_vector_insert(&new_entries, entry);
+				git_vector_insert(&remove_entries, (git_index_entry *)old_entry);
+			}
+		}
+
+		if (diff <= 0) {
+			if ((error = git_iterator_advance(&old_entry, index_iterator)) < 0 &&
+				error != GIT_ITEROVER)
+				goto done;
+		}
+
+		if (diff >= 0) {
+			if ((error = git_iterator_advance(&new_entry, new_iterator)) < 0 &&
+				error != GIT_ITEROVER)
+				goto done;
+		}
+	}
+
+	git_index_name_clear(index);
+	git_index_reuc_clear(index);
+
+	git_vector_swap(&new_entries, &index->entries);
+
+	git_vector_foreach(&remove_entries, i, entry) {
+		if (index->tree)
+			git_tree_cache_invalidate_path(index->tree, entry->path);
+
+		index_entry_free(entry);
+	}
+
+	error = 0;
+
+done:
+	git_vector_free(&new_entries);
+	git_vector_free(&remove_entries);
+	git_iterator_free(index_iterator);
+	git_iterator_free(new_iterator);
+	return error;
+}
+
+git_repository *git_index_owner(const git_index *index)
+{
+	return INDEX_OWNER(index);
+}
+
+enum {
+	INDEX_ACTION_NONE = 0,
+	INDEX_ACTION_UPDATE = 1,
+	INDEX_ACTION_REMOVE = 2,
+	INDEX_ACTION_ADDALL = 3,
+};
+
+int git_index_add_all(
+	git_index *index,
+	const git_strarray *paths,
+	unsigned int flags,
+	git_index_matched_path_cb cb,
+	void *payload)
+{
+	int error;
+	git_repository *repo;
+	git_iterator *wditer = NULL;
+	git_pathspec ps;
+	bool no_fnmatch = (flags & GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH) != 0;
+
+	assert(index);
+
+	repo = INDEX_OWNER(index);
+	if ((error = git_repository__ensure_not_bare(repo, "index add all")) < 0)
+		return error;
+
+	if ((error = git_pathspec__init(&ps, paths)) < 0)
+		return error;
+
+	/* optionally check that pathspec doesn't mention any ignored files */
+	if ((flags & GIT_INDEX_ADD_CHECK_PATHSPEC) != 0 &&
+		(flags & GIT_INDEX_ADD_FORCE) == 0 &&
+		(error = git_ignore__check_pathspec_for_exact_ignores(
+			repo, &ps.pathspec, no_fnmatch)) < 0)
+		goto cleanup;
+
+	error = index_apply_to_wd_diff(index, INDEX_ACTION_ADDALL, paths, flags, cb, payload);
+
+	if (error)
+		giterr_set_after_callback(error);
+
+cleanup:
+	git_iterator_free(wditer);
+	git_pathspec__clear(&ps);
+
+	return error;
+}
+
+struct foreach_diff_data {
+	git_index *index;
+	const git_pathspec *pathspec;
+	unsigned int flags;
+	git_index_matched_path_cb cb;
+	void *payload;
+};
+
+static int apply_each_file(const git_diff_delta *delta, float progress, void *payload)
+{
+	struct foreach_diff_data *data = payload;
+	const char *match, *path;
+	int error = 0;
+
+	GIT_UNUSED(progress);
+
+	path = delta->old_file.path;
+
+	/* We only want those which match the pathspecs */
+	if (!git_pathspec__match(
+		    &data->pathspec->pathspec, path, false, (bool)data->index->ignore_case,
+		    &match, NULL))
+		return 0;
+
+	if (data->cb)
+		error = data->cb(path, match, data->payload);
+
+	if (error > 0) /* skip this entry */
+		return 0;
+	if (error < 0) /* actual error */
+		return error;
+
+	/* If the workdir item does not exist, remove it from the index. */
+	if ((delta->new_file.flags & GIT_DIFF_FLAG_EXISTS) == 0)
+		error = git_index_remove_bypath(data->index, path);
+	else
+		error = git_index_add_bypath(data->index, delta->new_file.path);
+
+	return error;
+}
+
+static int index_apply_to_wd_diff(git_index *index, int action, const git_strarray *paths,
+				  unsigned int flags,
+				  git_index_matched_path_cb cb, void *payload)
+{
+	int error;
+	git_diff *diff;
+	git_pathspec ps;
+	git_repository *repo;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	struct foreach_diff_data data = {
+		index,
+		NULL,
+		flags,
+		cb,
+		payload,
+	};
+
+	assert(index);
+	assert(action == INDEX_ACTION_UPDATE || action == INDEX_ACTION_ADDALL);
+
+	repo = INDEX_OWNER(index);
+
+	if (!repo) {
+		return create_index_error(-1,
+			"cannot run update; the index is not backed up by a repository.");
+	}
+
+	/*
+	 * We do the matching ourselves intead of passing the list to
+	 * diff because we want to tell the callback which one
+	 * matched, which we do not know if we ask diff to filter for us.
+	 */
+	if ((error = git_pathspec__init(&ps, paths)) < 0)
+		return error;
+
+	opts.flags = GIT_DIFF_INCLUDE_TYPECHANGE;
+	if (action == INDEX_ACTION_ADDALL) {
+		opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED |
+			GIT_DIFF_RECURSE_UNTRACKED_DIRS;
+
+		if (flags == GIT_INDEX_ADD_FORCE)
+			opts.flags |= GIT_DIFF_INCLUDE_IGNORED;
+	}
+
+	if ((error = git_diff_index_to_workdir(&diff, repo, index, &opts)) < 0)
+		goto cleanup;
+
+	data.pathspec = &ps;
+	error = git_diff_foreach(diff, apply_each_file, NULL, NULL, NULL, &data);
+	git_diff_free(diff);
+
+	if (error) /* make sure error is set if callback stopped iteration */
+		giterr_set_after_callback(error);
+
+cleanup:
+	git_pathspec__clear(&ps);
+	return error;
+}
+
+static int index_apply_to_all(
+	git_index *index,
+	int action,
+	const git_strarray *paths,
+	git_index_matched_path_cb cb,
+	void *payload)
+{
+	int error = 0;
+	size_t i;
+	git_pathspec ps;
+	const char *match;
+	git_buf path = GIT_BUF_INIT;
+
+	assert(index);
+
+	if ((error = git_pathspec__init(&ps, paths)) < 0)
+		return error;
+
+	git_vector_sort(&index->entries);
+
+	for (i = 0; !error && i < index->entries.length; ++i) {
+		git_index_entry *entry = git_vector_get(&index->entries, i);
+
+		/* check if path actually matches */
+		if (!git_pathspec__match(
+				&ps.pathspec, entry->path, false, (bool)index->ignore_case,
+				&match, NULL))
+			continue;
+
+		/* issue notification callback if requested */
+		if (cb && (error = cb(entry->path, match, payload)) != 0) {
+			if (error > 0) { /* return > 0 means skip this one */
+				error = 0;
+				continue;
+			}
+			if (error < 0)   /* return < 0 means abort */
+				break;
+		}
+
+		/* index manipulation may alter entry, so don't depend on it */
+		if ((error = git_buf_sets(&path, entry->path)) < 0)
+			break;
+
+		switch (action) {
+		case INDEX_ACTION_NONE:
+			break;
+		case INDEX_ACTION_UPDATE:
+			error = git_index_add_bypath(index, path.ptr);
+
+			if (error == GIT_ENOTFOUND) {
+				giterr_clear();
+
+				error = git_index_remove_bypath(index, path.ptr);
+
+				if (!error) /* back up foreach if we removed this */
+					i--;
+			}
+			break;
+		case INDEX_ACTION_REMOVE:
+			if (!(error = git_index_remove_bypath(index, path.ptr)))
+				i--; /* back up foreach if we removed this */
+			break;
+		default:
+			giterr_set(GITERR_INVALID, "Unknown index action %d", action);
+			error = -1;
+			break;
+		}
+	}
+
+	git_buf_free(&path);
+	git_pathspec__clear(&ps);
+
+	return error;
+}
+
+int git_index_remove_all(
+	git_index *index,
+	const git_strarray *pathspec,
+	git_index_matched_path_cb cb,
+	void *payload)
+{
+	int error = index_apply_to_all(
+		index, INDEX_ACTION_REMOVE, pathspec, cb, payload);
+
+	if (error) /* make sure error is set if callback stopped iteration */
+		giterr_set_after_callback(error);
+
+	return error;
+}
+
+int git_index_update_all(
+	git_index *index,
+	const git_strarray *pathspec,
+	git_index_matched_path_cb cb,
+	void *payload)
+{
+	int error = index_apply_to_wd_diff(index, INDEX_ACTION_UPDATE, pathspec, 0, cb, payload);
+	if (error) /* make sure error is set if callback stopped iteration */
+		giterr_set_after_callback(error);
+
+	return error;
+}
+
+int git_index_snapshot_new(git_vector *snap, git_index *index)
+{
+	int error;
+
+	GIT_REFCOUNT_INC(index);
+
+	if (git_mutex_lock(&index->lock) < 0) {
+		giterr_set(GITERR_OS, "Failed to lock index");
+		return -1;
+	}
+
+	git_atomic_inc(&index->readers);
+	git_vector_sort(&index->entries);
+
+	error = git_vector_dup(snap, &index->entries, index->entries._cmp);
+
+	git_mutex_unlock(&index->lock);
+
+	if (error < 0)
+		git_index_free(index);
+
+	return error;
+}
+
+void git_index_snapshot_release(git_vector *snap, git_index *index)
+{
+	git_vector_free(snap);
+
+	git_atomic_dec(&index->readers);
+
+	if (!git_mutex_lock(&index->lock)) {
+		index_free_deleted(index); /* try to free pending deleted items */
+		git_mutex_unlock(&index->lock);
+	}
+
+	git_index_free(index);
+}
+
+int git_index_snapshot_find(
+	size_t *out, git_vector *entries, git_vector_cmp entry_srch,
+	const char *path, size_t path_len, int stage)
+{
+	return index_find_in_entries(out, entries, entry_srch, path, path_len, stage);
+}
+
+int git_indexwriter_init(
+	git_indexwriter *writer,
+	git_index *index)
+{
+	int error;
+
+	GIT_REFCOUNT_INC(index);
+
+	writer->index = index;
+
+	if (!index->index_file_path)
+		return create_index_error(-1,
+			"Failed to write index: The index is in-memory only");
+
+	if ((error = git_filebuf_open(
+		&writer->file, index->index_file_path, GIT_FILEBUF_HASH_CONTENTS, GIT_INDEX_FILE_MODE)) < 0) {
+
+		if (error == GIT_ELOCKED)
+			giterr_set(GITERR_INDEX, "The index is locked. This might be due to a concurrent or crashed process");
+
+		return error;
+	}
+
+	writer->should_write = 1;
+
+	return 0;
+}
+
+int git_indexwriter_init_for_operation(
+	git_indexwriter *writer,
+	git_repository *repo,
+	unsigned int *checkout_strategy)
+{
+	git_index *index;
+	int error;
+
+	if ((error = git_repository_index__weakptr(&index, repo)) < 0 ||
+		(error = git_indexwriter_init(writer, index)) < 0)
+		return error;
+
+	writer->should_write = (*checkout_strategy & GIT_CHECKOUT_DONT_WRITE_INDEX) == 0;
+	*checkout_strategy |= GIT_CHECKOUT_DONT_WRITE_INDEX;
+
+	return 0;
+}
+
+int git_indexwriter_commit(git_indexwriter *writer)
+{
+	int error;
+	git_oid checksum = {{ 0 }};
+
+	if (!writer->should_write)
+		return 0;
+
+	if (index_sort_if_needed(writer->index, true) < 0)
+		return -1;
+
+	git_vector_sort(&writer->index->reuc);
+
+	if ((error = write_index(&checksum, writer->index, &writer->file)) < 0) {
+		git_indexwriter_cleanup(writer);
+		return error;
+	}
+
+	if ((error = git_filebuf_commit(&writer->file)) < 0)
+		return error;
+
+	if ((error = git_futils_filestamp_check(
+		&writer->index->stamp, writer->index->index_file_path)) < 0) {
+		giterr_set(GITERR_OS, "Could not read index timestamp");
+		return -1;
+	}
+
+	writer->index->on_disk = 1;
+	git_oid_cpy(&writer->index->checksum, &checksum);
+
+	git_index_free(writer->index);
+	writer->index = NULL;
+
+	return 0;
+}
+
+void git_indexwriter_cleanup(git_indexwriter *writer)
+{
+	git_filebuf_cleanup(&writer->file);
+
+	git_index_free(writer->index);
+	writer->index = NULL;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/index.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/index.h
new file mode 100755
index 0000000..9c60b01
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/index.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_index_h__
+#define INCLUDE_index_h__
+
+#include "fileops.h"
+#include "filebuf.h"
+#include "vector.h"
+#include "tree-cache.h"
+#include "git2/odb.h"
+#include "git2/index.h"
+
+#define GIT_INDEX_FILE "index"
+#define GIT_INDEX_FILE_MODE 0666
+
+struct git_index {
+	git_refcount rc;
+
+	char *index_file_path;
+	git_futils_filestamp stamp;
+	git_oid checksum;   /* checksum at the end of the file */
+
+	git_vector entries;
+
+	git_mutex  lock;    /* lock held while entries is being changed */
+	git_vector deleted; /* deleted entries if readers > 0 */
+	git_atomic readers; /* number of active iterators */
+
+	unsigned int on_disk:1;
+	unsigned int ignore_case:1;
+	unsigned int distrust_filemode:1;
+	unsigned int no_symlinks:1;
+
+	git_tree_cache *tree;
+	git_pool tree_pool;
+
+	git_vector names;
+	git_vector reuc;
+
+	git_vector_cmp entries_cmp_path;
+	git_vector_cmp entries_search;
+	git_vector_cmp entries_search_path;
+	git_vector_cmp reuc_search;
+};
+
+struct git_index_conflict_iterator {
+	git_index *index;
+	size_t cur;
+};
+
+extern void git_index_entry__init_from_stat(
+	git_index_entry *entry, struct stat *st, bool trust_mode);
+
+/* Index entry comparison functions for array sorting */
+extern int git_index_entry_cmp(const void *a, const void *b);
+extern int git_index_entry_icmp(const void *a, const void *b);
+
+/* Index entry search functions for search using a search spec */
+extern int git_index_entry_srch(const void *a, const void *b);
+extern int git_index_entry_isrch(const void *a, const void *b);
+
+/* Search index for `path`, returning GIT_ENOTFOUND if it does not exist
+ * (but not setting an error message).
+ *
+ * `at_pos` is set to the position where it is or would be inserted.
+ * Pass `path_len` as strlen of path or 0 to call strlen internally.
+ */
+extern int git_index__find_pos(
+	size_t *at_pos, git_index *index, const char *path, size_t path_len, int stage);
+
+extern void git_index__set_ignore_case(git_index *index, bool ignore_case);
+
+extern unsigned int git_index__create_mode(unsigned int mode);
+
+GIT_INLINE(const git_futils_filestamp *) git_index__filestamp(git_index *index)
+{
+   return &index->stamp;
+}
+
+extern int git_index__changed_relative_to(git_index *index, const git_oid *checksum);
+
+/* Copy the current entries vector *and* increment the index refcount.
+ * Call `git_index__release_snapshot` when done.
+ */
+extern int git_index_snapshot_new(git_vector *snap, git_index *index);
+extern void git_index_snapshot_release(git_vector *snap, git_index *index);
+
+/* Allow searching in a snapshot; entries must already be sorted! */
+extern int git_index_snapshot_find(
+	size_t *at_pos, git_vector *snap, git_vector_cmp entry_srch,
+	const char *path, size_t path_len, int stage);
+
+/* Replace an index with a new index */
+int git_index_read_index(git_index *index, const git_index *new_index);
+
+typedef struct {
+	git_index *index;
+	git_filebuf file;
+	unsigned int should_write:1;
+} git_indexwriter;
+
+#define GIT_INDEXWRITER_INIT { NULL, GIT_FILEBUF_INIT }
+
+/* Lock the index for eventual writing. */
+extern int git_indexwriter_init(git_indexwriter *writer, git_index *index);
+
+/* Lock the index for eventual writing by a repository operation: a merge,
+ * revert, cherry-pick or a rebase.  Note that the given checkout strategy
+ * will be updated for the operation's use so that checkout will not write
+ * the index.
+ */
+extern int git_indexwriter_init_for_operation(
+	git_indexwriter *writer,
+	git_repository *repo,
+	unsigned int *checkout_strategy);
+
+/* Write the index and unlock it. */
+extern int git_indexwriter_commit(git_indexwriter *writer);
+
+/* Cleanup an index writing session, unlocking the file (if it is still
+ * locked and freeing any data structures.
+ */
+extern void git_indexwriter_cleanup(git_indexwriter *writer);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/indexer.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/indexer.c
new file mode 100755
index 0000000..9aa0925
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/indexer.c
@@ -0,0 +1,1091 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2/indexer.h"
+#include "git2/object.h"
+
+#include "common.h"
+#include "pack.h"
+#include "mwindow.h"
+#include "posix.h"
+#include "pack.h"
+#include "filebuf.h"
+#include "oid.h"
+#include "oidmap.h"
+#include "zstream.h"
+
+GIT__USE_OIDMAP
+
+extern git_mutex git__mwindow_mutex;
+
+#define UINT31_MAX (0x7FFFFFFF)
+
+struct entry {
+	git_oid oid;
+	uint32_t crc;
+	uint32_t offset;
+	uint64_t offset_long;
+};
+
+struct git_indexer {
+	unsigned int parsed_header :1,
+		opened_pack :1,
+		have_stream :1,
+		have_delta :1;
+	struct git_pack_header hdr;
+	struct git_pack_file *pack;
+	unsigned int mode;
+	git_off_t off;
+	git_off_t entry_start;
+	git_packfile_stream stream;
+	size_t nr_objects;
+	git_vector objects;
+	git_vector deltas;
+	unsigned int fanout[256];
+	git_hash_ctx hash_ctx;
+	git_oid hash;
+	git_transfer_progress_cb progress_cb;
+	void *progress_payload;
+	char objbuf[8*1024];
+
+	/* Needed to look up objects which we want to inject to fix a thin pack */
+	git_odb *odb;
+
+	/* Fields for calculating the packfile trailer (hash of everything before it) */
+	char inbuf[GIT_OID_RAWSZ];
+	size_t inbuf_len;
+	git_hash_ctx trailer;
+};
+
+struct delta_info {
+	git_off_t delta_off;
+};
+
+const git_oid *git_indexer_hash(const git_indexer *idx)
+{
+	return &idx->hash;
+}
+
+static int parse_header(struct git_pack_header *hdr, struct git_pack_file *pack)
+{
+	int error;
+	git_map map;
+
+	if ((error = p_mmap(&map, sizeof(*hdr), GIT_PROT_READ, GIT_MAP_SHARED, pack->mwf.fd, 0)) < 0)
+		return error;
+
+	memcpy(hdr, map.data, sizeof(*hdr));
+	p_munmap(&map);
+
+	/* Verify we recognize this pack file format. */
+	if (hdr->hdr_signature != ntohl(PACK_SIGNATURE)) {
+		giterr_set(GITERR_INDEXER, "Wrong pack signature");
+		return -1;
+	}
+
+	if (!pack_version_ok(hdr->hdr_version)) {
+		giterr_set(GITERR_INDEXER, "Wrong pack version");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int objects_cmp(const void *a, const void *b)
+{
+	const struct entry *entrya = a;
+	const struct entry *entryb = b;
+
+	return git_oid__cmp(&entrya->oid, &entryb->oid);
+}
+
+int git_indexer_new(
+		git_indexer **out,
+		const char *prefix,
+		unsigned int mode,
+		git_odb *odb,
+		git_transfer_progress_cb progress_cb,
+		void *progress_payload)
+{
+	git_indexer *idx;
+	git_buf path = GIT_BUF_INIT, tmp_path = GIT_BUF_INIT;
+	static const char suff[] = "/pack";
+	int error, fd = -1;
+
+	idx = git__calloc(1, sizeof(git_indexer));
+	GITERR_CHECK_ALLOC(idx);
+	idx->odb = odb;
+	idx->progress_cb = progress_cb;
+	idx->progress_payload = progress_payload;
+	idx->mode = mode ? mode : GIT_PACK_FILE_MODE;
+	git_hash_ctx_init(&idx->hash_ctx);
+	git_hash_ctx_init(&idx->trailer);
+
+	error = git_buf_joinpath(&path, prefix, suff);
+	if (error < 0)
+		goto cleanup;
+
+	fd = git_futils_mktmp(&tmp_path, git_buf_cstr(&path), idx->mode);
+	git_buf_free(&path);
+	if (fd < 0)
+		goto cleanup;
+
+	error = git_packfile_alloc(&idx->pack, git_buf_cstr(&tmp_path));
+	git_buf_free(&tmp_path);
+
+	if (error < 0)
+		goto cleanup;
+
+	idx->pack->mwf.fd = fd;
+	if ((error = git_mwindow_file_register(&idx->pack->mwf)) < 0)
+		goto cleanup;
+
+	*out = idx;
+	return 0;
+
+cleanup:
+	if (fd != -1)
+		p_close(fd);
+
+	git_buf_free(&path);
+	git_buf_free(&tmp_path);
+	git__free(idx);
+	return -1;
+}
+
+/* Try to store the delta so we can try to resolve it later */
+static int store_delta(git_indexer *idx)
+{
+	struct delta_info *delta;
+
+	delta = git__calloc(1, sizeof(struct delta_info));
+	GITERR_CHECK_ALLOC(delta);
+	delta->delta_off = idx->entry_start;
+
+	if (git_vector_insert(&idx->deltas, delta) < 0)
+		return -1;
+
+	return 0;
+}
+
+static void hash_header(git_hash_ctx *ctx, git_off_t len, git_otype type)
+{
+	char buffer[64];
+	size_t hdrlen;
+
+	hdrlen = git_odb__format_object_header(buffer, sizeof(buffer), (size_t)len, type);
+	git_hash_update(ctx, buffer, hdrlen);
+}
+
+static int hash_object_stream(git_indexer*idx, git_packfile_stream *stream)
+{
+	ssize_t read;
+
+	assert(idx && stream);
+
+	do {
+		if ((read = git_packfile_stream_read(stream, idx->objbuf, sizeof(idx->objbuf))) < 0)
+			break;
+
+		git_hash_update(&idx->hash_ctx, idx->objbuf, read);
+	} while (read > 0);
+
+	if (read < 0)
+		return (int)read;
+
+	return 0;
+}
+
+/* In order to create the packfile stream, we need to skip over the delta base description */
+static int advance_delta_offset(git_indexer *idx, git_otype type)
+{
+	git_mwindow *w = NULL;
+
+	assert(type == GIT_OBJ_REF_DELTA || type == GIT_OBJ_OFS_DELTA);
+
+	if (type == GIT_OBJ_REF_DELTA) {
+		idx->off += GIT_OID_RAWSZ;
+	} else {
+		git_off_t base_off = get_delta_base(idx->pack, &w, &idx->off, type, idx->entry_start);
+		git_mwindow_close(&w);
+		if (base_off < 0)
+			return (int)base_off;
+	}
+
+	return 0;
+}
+
+/* Read from the stream and discard any output */
+static int read_object_stream(git_indexer *idx, git_packfile_stream *stream)
+{
+	ssize_t read;
+
+	assert(stream);
+
+	do {
+		read = git_packfile_stream_read(stream, idx->objbuf, sizeof(idx->objbuf));
+	} while (read > 0);
+
+	if (read < 0)
+		return (int)read;
+
+	return 0;
+}
+
+static int crc_object(uint32_t *crc_out, git_mwindow_file *mwf, git_off_t start, git_off_t size)
+{
+	void *ptr;
+	uint32_t crc;
+	unsigned int left, len;
+	git_mwindow *w = NULL;
+
+	crc = crc32(0L, Z_NULL, 0);
+	while (size) {
+		ptr = git_mwindow_open(mwf, &w, start, (size_t)size, &left);
+		if (ptr == NULL)
+			return -1;
+
+		len = min(left, (unsigned int)size);
+		crc = crc32(crc, ptr, len);
+		size -= len;
+		start += len;
+		git_mwindow_close(&w);
+	}
+
+	*crc_out = htonl(crc);
+	return 0;
+}
+
+static int store_object(git_indexer *idx)
+{
+	int i, error;
+	khiter_t k;
+	git_oid oid;
+	struct entry *entry;
+	git_off_t entry_size;
+	struct git_pack_entry *pentry;
+	git_off_t entry_start = idx->entry_start;
+
+	entry = git__calloc(1, sizeof(*entry));
+	GITERR_CHECK_ALLOC(entry);
+
+	pentry = git__calloc(1, sizeof(struct git_pack_entry));
+	GITERR_CHECK_ALLOC(pentry);
+
+	git_hash_final(&oid, &idx->hash_ctx);
+	entry_size = idx->off - entry_start;
+	if (entry_start > UINT31_MAX) {
+		entry->offset = UINT32_MAX;
+		entry->offset_long = entry_start;
+	} else {
+		entry->offset = (uint32_t)entry_start;
+	}
+
+	git_oid_cpy(&pentry->sha1, &oid);
+	pentry->offset = entry_start;
+
+	k = kh_put(oid, idx->pack->idx_cache, &pentry->sha1, &error);
+	if (error == -1) {
+		git__free(pentry);
+		giterr_set_oom();
+		goto on_error;
+	}
+
+	if (error == 0) {
+		giterr_set(GITERR_INDEXER, "duplicate object %s found in pack", git_oid_tostr_s(&pentry->sha1));
+		git__free(pentry);
+		goto on_error;
+	}
+
+
+	kh_value(idx->pack->idx_cache, k) = pentry;
+
+	git_oid_cpy(&entry->oid, &oid);
+
+	if (crc_object(&entry->crc, &idx->pack->mwf, entry_start, entry_size) < 0)
+		goto on_error;
+
+	/* Add the object to the list */
+	if (git_vector_insert(&idx->objects, entry) < 0)
+		goto on_error;
+
+	for (i = oid.id[0]; i < 256; ++i) {
+		idx->fanout[i]++;
+	}
+
+	return 0;
+
+on_error:
+	git__free(entry);
+
+	return -1;
+}
+
+GIT_INLINE(bool) has_entry(git_indexer *idx, git_oid *id)
+{
+	khiter_t k;
+	k = kh_get(oid, idx->pack->idx_cache, id);
+	return (k != kh_end(idx->pack->idx_cache));
+}
+
+static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_entry *pentry, git_off_t entry_start)
+{
+	int i, error;
+	khiter_t k;
+
+	if (entry_start > UINT31_MAX) {
+		entry->offset = UINT32_MAX;
+		entry->offset_long = entry_start;
+	} else {
+		entry->offset = (uint32_t)entry_start;
+	}
+
+	pentry->offset = entry_start;
+	k = kh_put(oid, idx->pack->idx_cache, &pentry->sha1, &error);
+
+	if (error <= 0) {
+		giterr_set(GITERR_INDEXER, "cannot insert object into pack");
+		return -1;
+	}
+
+	kh_value(idx->pack->idx_cache, k) = pentry;
+
+	/* Add the object to the list */
+	if (git_vector_insert(&idx->objects, entry) < 0)
+		return -1;
+
+	for (i = entry->oid.id[0]; i < 256; ++i) {
+		idx->fanout[i]++;
+	}
+
+	return 0;
+}
+
+static int hash_and_save(git_indexer *idx, git_rawobj *obj, git_off_t entry_start)
+{
+	git_oid oid;
+	size_t entry_size;
+	struct entry *entry;
+	struct git_pack_entry *pentry = NULL;
+
+	entry = git__calloc(1, sizeof(*entry));
+	GITERR_CHECK_ALLOC(entry);
+
+	if (git_odb__hashobj(&oid, obj) < 0) {
+		giterr_set(GITERR_INDEXER, "Failed to hash object");
+		goto on_error;
+	}
+
+	pentry = git__calloc(1, sizeof(struct git_pack_entry));
+	GITERR_CHECK_ALLOC(pentry);
+
+	git_oid_cpy(&pentry->sha1, &oid);
+	git_oid_cpy(&entry->oid, &oid);
+	entry->crc = crc32(0L, Z_NULL, 0);
+
+	entry_size = (size_t)(idx->off - entry_start);
+	if (crc_object(&entry->crc, &idx->pack->mwf, entry_start, entry_size) < 0)
+		goto on_error;
+
+	return save_entry(idx, entry, pentry, entry_start);
+
+on_error:
+	git__free(pentry);
+	git__free(entry);
+	git__free(obj->data);
+	return -1;
+}
+
+static int do_progress_callback(git_indexer *idx, git_transfer_progress *stats)
+{
+	if (idx->progress_cb)
+		return giterr_set_after_callback_function(
+			idx->progress_cb(stats, idx->progress_payload),
+			"indexer progress");
+	return 0;
+}
+
+/* Hash everything but the last 20B of input */
+static void hash_partially(git_indexer *idx, const uint8_t *data, size_t size)
+{
+	size_t to_expell, to_keep;
+
+	if (size == 0)
+		return;
+
+	/* Easy case, dump the buffer and the data minus the last 20 bytes */
+	if (size >= GIT_OID_RAWSZ) {
+		git_hash_update(&idx->trailer, idx->inbuf, idx->inbuf_len);
+		git_hash_update(&idx->trailer, data, size - GIT_OID_RAWSZ);
+
+		data += size - GIT_OID_RAWSZ;
+		memcpy(idx->inbuf, data, GIT_OID_RAWSZ);
+		idx->inbuf_len = GIT_OID_RAWSZ;
+		return;
+	}
+
+	/* We can just append */
+	if (idx->inbuf_len + size <= GIT_OID_RAWSZ) {
+		memcpy(idx->inbuf + idx->inbuf_len, data, size);
+		idx->inbuf_len += size;
+		return;
+	}
+
+	/* We need to partially drain the buffer and then append */
+	to_keep   = GIT_OID_RAWSZ - size;
+	to_expell = idx->inbuf_len - to_keep;
+
+	git_hash_update(&idx->trailer, idx->inbuf, to_expell);
+
+	memmove(idx->inbuf, idx->inbuf + to_expell, to_keep);
+	memcpy(idx->inbuf + to_keep, data, size);
+	idx->inbuf_len += size - to_expell;
+}
+
+static int write_at(git_indexer *idx, const void *data, git_off_t offset, size_t size)
+{
+	git_file fd = idx->pack->mwf.fd;
+	size_t page_size;
+	size_t page_offset;
+	git_off_t page_start;
+	unsigned char *map_data;
+	git_map map;
+	int error;
+
+	assert(data && size);
+
+	if ((error = git__page_size(&page_size)) < 0)
+		return error;
+
+	/* the offset needs to be at the beginning of the a page boundary */
+	page_offset = offset % page_size;
+	page_start = offset - page_offset;
+
+	if ((error = p_mmap(&map, page_offset + size, GIT_PROT_WRITE, GIT_MAP_SHARED, fd, page_start)) < 0)
+		return error;
+
+	map_data = (unsigned char *)map.data;
+	memcpy(map_data + page_offset, data, size);
+	p_munmap(&map);
+
+	return 0;
+}
+
+static int append_to_pack(git_indexer *idx, const void *data, size_t size)
+{
+	git_off_t current_size = idx->pack->mwf.size;
+	int fd = idx->pack->mwf.fd;
+
+	if (!size)
+		return 0;
+
+	if (p_lseek(fd, current_size + size - 1, SEEK_SET) < 0 ||
+	    p_write(idx->pack->mwf.fd, data, 1) < 0) {
+		giterr_set(GITERR_OS, "cannot extend packfile '%s'", idx->pack->pack_name);
+		return -1;
+	}
+
+	return write_at(idx, data, idx->pack->mwf.size, size);
+}
+
+int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_transfer_progress *stats)
+{
+	int error = -1;
+	size_t processed;
+	struct git_pack_header *hdr = &idx->hdr;
+	git_mwindow_file *mwf = &idx->pack->mwf;
+
+	assert(idx && data && stats);
+
+	processed = stats->indexed_objects;
+
+	if ((error = append_to_pack(idx, data, size)) < 0)
+		return error;
+
+	hash_partially(idx, data, (int)size);
+
+	/* Make sure we set the new size of the pack */
+	idx->pack->mwf.size += size;
+
+	if (!idx->parsed_header) {
+		unsigned int total_objects;
+
+		if ((unsigned)idx->pack->mwf.size < sizeof(struct git_pack_header))
+			return 0;
+
+		if ((error = parse_header(&idx->hdr, idx->pack)) < 0)
+			return error;
+
+		idx->parsed_header = 1;
+		idx->nr_objects = ntohl(hdr->hdr_entries);
+		idx->off = sizeof(struct git_pack_header);
+
+		/* for now, limit to 2^32 objects */
+		assert(idx->nr_objects == (size_t)((unsigned int)idx->nr_objects));
+		if (idx->nr_objects == (size_t)((unsigned int)idx->nr_objects))
+			total_objects = (unsigned int)idx->nr_objects;
+		else
+			total_objects = UINT_MAX;
+
+		idx->pack->idx_cache = git_oidmap_alloc();
+		GITERR_CHECK_ALLOC(idx->pack->idx_cache);
+
+		idx->pack->has_cache = 1;
+		if (git_vector_init(&idx->objects, total_objects, objects_cmp) < 0)
+			return -1;
+
+		if (git_vector_init(&idx->deltas, total_objects / 2, NULL) < 0)
+			return -1;
+
+		stats->received_objects = 0;
+		stats->local_objects = 0;
+		stats->total_deltas = 0;
+		stats->indexed_deltas = 0;
+		processed = stats->indexed_objects = 0;
+		stats->total_objects = total_objects;
+
+		if ((error = do_progress_callback(idx, stats)) != 0)
+			return error;
+	}
+
+	/* Now that we have data in the pack, let's try to parse it */
+
+	/* As the file grows any windows we try to use will be out of date */
+	git_mwindow_free_all(mwf);
+
+	while (processed < idx->nr_objects) {
+		git_packfile_stream *stream = &idx->stream;
+		git_off_t entry_start = idx->off;
+		size_t entry_size;
+		git_otype type;
+		git_mwindow *w = NULL;
+
+		if (idx->pack->mwf.size <= idx->off + 20)
+			return 0;
+
+		if (!idx->have_stream) {
+			error = git_packfile_unpack_header(&entry_size, &type, mwf, &w, &idx->off);
+			if (error == GIT_EBUFS) {
+				idx->off = entry_start;
+				return 0;
+			}
+			if (error < 0)
+				goto on_error;
+
+			git_mwindow_close(&w);
+			idx->entry_start = entry_start;
+			git_hash_init(&idx->hash_ctx);
+
+			if (type == GIT_OBJ_REF_DELTA || type == GIT_OBJ_OFS_DELTA) {
+				error = advance_delta_offset(idx, type);
+				if (error == GIT_EBUFS) {
+					idx->off = entry_start;
+					return 0;
+				}
+				if (error < 0)
+					goto on_error;
+
+				idx->have_delta = 1;
+			} else {
+				idx->have_delta = 0;
+				hash_header(&idx->hash_ctx, entry_size, type);
+			}
+
+			idx->have_stream = 1;
+
+			error = git_packfile_stream_open(stream, idx->pack, idx->off);
+			if (error < 0)
+				goto on_error;
+		}
+
+		if (idx->have_delta) {
+			error = read_object_stream(idx, stream);
+		} else {
+			error = hash_object_stream(idx, stream);
+		}
+
+		idx->off = stream->curpos;
+		if (error == GIT_EBUFS)
+			return 0;
+
+		/* We want to free the stream reasorces no matter what here */
+		idx->have_stream = 0;
+		git_packfile_stream_free(stream);
+
+		if (error < 0)
+			goto on_error;
+
+		if (idx->have_delta) {
+			error = store_delta(idx);
+		} else {
+			error = store_object(idx);
+		}
+
+		if (error < 0)
+			goto on_error;
+
+		if (!idx->have_delta) {
+			stats->indexed_objects = (unsigned int)++processed;
+		}
+		stats->received_objects++;
+
+		if ((error = do_progress_callback(idx, stats)) != 0)
+			goto on_error;
+	}
+
+	return 0;
+
+on_error:
+	git_mwindow_free_all(mwf);
+	return error;
+}
+
+static int index_path(git_buf *path, git_indexer *idx, const char *suffix)
+{
+	const char prefix[] = "pack-";
+	size_t slash = (size_t)path->size;
+
+	/* search backwards for '/' */
+	while (slash > 0 && path->ptr[slash - 1] != '/')
+		slash--;
+
+	if (git_buf_grow(path, slash + 1 + strlen(prefix) +
+					 GIT_OID_HEXSZ + strlen(suffix) + 1) < 0)
+		return -1;
+
+	git_buf_truncate(path, slash);
+	git_buf_puts(path, prefix);
+	git_oid_fmt(path->ptr + git_buf_len(path), &idx->hash);
+	path->size += GIT_OID_HEXSZ;
+	git_buf_puts(path, suffix);
+
+	return git_buf_oom(path) ? -1 : 0;
+}
+
+/**
+ * Rewind the packfile by the trailer, as we might need to fix the
+ * packfile by injecting objects at the tail and must overwrite it.
+ */
+static void seek_back_trailer(git_indexer *idx)
+{
+	idx->pack->mwf.size -= GIT_OID_RAWSZ;
+	git_mwindow_free_all(&idx->pack->mwf);
+}
+
+static int inject_object(git_indexer *idx, git_oid *id)
+{
+	git_odb_object *obj;
+	struct entry *entry;
+	struct git_pack_entry *pentry = NULL;
+	git_oid foo = {{0}};
+	unsigned char hdr[64];
+	git_buf buf = GIT_BUF_INIT;
+	git_off_t entry_start;
+	const void *data;
+	size_t len, hdr_len;
+	int error;
+
+	seek_back_trailer(idx);
+	entry_start = idx->pack->mwf.size;
+
+	if (git_odb_read(&obj, idx->odb, id) < 0) {
+		giterr_set(GITERR_INDEXER, "missing delta bases");
+		return -1;
+	}
+
+	data = git_odb_object_data(obj);
+	len = git_odb_object_size(obj);
+
+	entry = git__calloc(1, sizeof(*entry));
+	GITERR_CHECK_ALLOC(entry);
+
+	entry->crc = crc32(0L, Z_NULL, 0);
+
+	/* Write out the object header */
+	hdr_len = git_packfile__object_header(hdr, len, git_odb_object_type(obj));
+	if ((error = append_to_pack(idx, hdr, hdr_len)) < 0)
+		goto cleanup;
+
+	idx->pack->mwf.size += hdr_len;
+	entry->crc = crc32(entry->crc, hdr, (uInt)hdr_len);
+
+	if ((error = git_zstream_deflatebuf(&buf, data, len)) < 0)
+		goto cleanup;
+
+	/* And then the compressed object */
+	if ((error = append_to_pack(idx, buf.ptr, buf.size)) < 0)
+		goto cleanup;
+
+	idx->pack->mwf.size += buf.size;
+	entry->crc = htonl(crc32(entry->crc, (unsigned char *)buf.ptr, (uInt)buf.size));
+	git_buf_free(&buf);
+
+	/* Write a fake trailer so the pack functions play ball */
+
+	if ((error = append_to_pack(idx, &foo, GIT_OID_RAWSZ)) < 0)
+		goto cleanup;
+
+	idx->pack->mwf.size += GIT_OID_RAWSZ;
+
+	pentry = git__calloc(1, sizeof(struct git_pack_entry));
+	GITERR_CHECK_ALLOC(pentry);
+
+	git_oid_cpy(&pentry->sha1, id);
+	git_oid_cpy(&entry->oid, id);
+	idx->off = entry_start + hdr_len + len;
+
+	error = save_entry(idx, entry, pentry, entry_start);
+
+cleanup:
+	if (error) {
+		git__free(entry);
+		git__free(pentry);
+	}
+
+	git_odb_object_free(obj);
+	return error;
+}
+
+static int fix_thin_pack(git_indexer *idx, git_transfer_progress *stats)
+{
+	int error, found_ref_delta = 0;
+	unsigned int i;
+	struct delta_info *delta;
+	size_t size;
+	git_otype type;
+	git_mwindow *w = NULL;
+	git_off_t curpos = 0;
+	unsigned char *base_info;
+	unsigned int left = 0;
+	git_oid base;
+
+	assert(git_vector_length(&idx->deltas) > 0);
+
+	if (idx->odb == NULL) {
+		giterr_set(GITERR_INDEXER, "cannot fix a thin pack without an ODB");
+		return -1;
+	}
+
+	/* Loop until we find the first REF delta */
+	git_vector_foreach(&idx->deltas, i, delta) {
+		if (!delta)
+			continue;
+
+		curpos = delta->delta_off;
+		error = git_packfile_unpack_header(&size, &type, &idx->pack->mwf, &w, &curpos);
+		git_mwindow_close(&w);
+		if (error < 0)
+			return error;
+
+		if (type == GIT_OBJ_REF_DELTA) {
+			found_ref_delta = 1;
+			break;
+		}
+	}
+
+	if (!found_ref_delta) {
+		giterr_set(GITERR_INDEXER, "no REF_DELTA found, cannot inject object");
+		return -1;
+	}
+
+	/* curpos now points to the base information, which is an OID */
+	base_info = git_mwindow_open(&idx->pack->mwf, &w, curpos, GIT_OID_RAWSZ, &left);
+	if (base_info == NULL) {
+		giterr_set(GITERR_INDEXER, "failed to map delta information");
+		return -1;
+	}
+
+	git_oid_fromraw(&base, base_info);
+	git_mwindow_close(&w);
+
+	if (has_entry(idx, &base))
+		return 0;
+
+	if (inject_object(idx, &base) < 0)
+		return -1;
+
+	stats->local_objects++;
+
+	return 0;
+}
+
+static int resolve_deltas(git_indexer *idx, git_transfer_progress *stats)
+{
+	unsigned int i;
+	struct delta_info *delta;
+	int progressed = 0, non_null = 0, progress_cb_result;
+
+	while (idx->deltas.length > 0) {
+		progressed = 0;
+		non_null = 0;
+		git_vector_foreach(&idx->deltas, i, delta) {
+			git_rawobj obj = {NULL};
+
+			if (!delta)
+				continue;
+
+			non_null = 1;
+			idx->off = delta->delta_off;
+			if (git_packfile_unpack(&obj, idx->pack, &idx->off) < 0)
+				continue;
+
+			if (hash_and_save(idx, &obj, delta->delta_off) < 0)
+				continue;
+
+			git__free(obj.data);
+			stats->indexed_objects++;
+			stats->indexed_deltas++;
+			progressed = 1;
+			if ((progress_cb_result = do_progress_callback(idx, stats)) < 0)
+				return progress_cb_result;
+
+			/* remove from the list */
+			git_vector_set(NULL, &idx->deltas, i, NULL);
+			git__free(delta);
+		}
+
+		/* if none were actually set, we're done */
+		if (!non_null)
+			break;
+
+		if (!progressed && (fix_thin_pack(idx, stats) < 0)) {
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int update_header_and_rehash(git_indexer *idx, git_transfer_progress *stats)
+{
+	void *ptr;
+	size_t chunk = 1024*1024;
+	git_off_t hashed = 0;
+	git_mwindow *w = NULL;
+	git_mwindow_file *mwf;
+	unsigned int left;
+
+	mwf = &idx->pack->mwf;
+
+	git_hash_init(&idx->trailer);
+
+
+	/* Update the header to include the numer of local objects we injected */
+	idx->hdr.hdr_entries = htonl(stats->total_objects + stats->local_objects);
+	if (write_at(idx, &idx->hdr, 0, sizeof(struct git_pack_header)) < 0)
+		return -1;
+
+	/*
+	 * We now use the same technique as before to determine the
+	 * hash. We keep reading up to the end and let
+	 * hash_partially() keep the existing trailer out of the
+	 * calculation.
+	 */
+	git_mwindow_free_all(mwf);
+	idx->inbuf_len = 0;
+	while (hashed < mwf->size) {
+		ptr = git_mwindow_open(mwf, &w, hashed, chunk, &left);
+		if (ptr == NULL)
+			return -1;
+
+		hash_partially(idx, ptr, left);
+		hashed += left;
+
+		git_mwindow_close(&w);
+	}
+
+	return 0;
+}
+
+int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
+{
+	git_mwindow *w = NULL;
+	unsigned int i, long_offsets = 0, left;
+	int error;
+	struct git_pack_idx_header hdr;
+	git_buf filename = GIT_BUF_INIT;
+	struct entry *entry;
+	git_oid trailer_hash, file_hash;
+	git_hash_ctx ctx;
+	git_filebuf index_file = {0};
+	void *packfile_trailer;
+
+	if (git_hash_ctx_init(&ctx) < 0)
+		return -1;
+
+	/* Test for this before resolve_deltas(), as it plays with idx->off */
+	if (idx->off < idx->pack->mwf.size - 20) {
+		giterr_set(GITERR_INDEXER, "Unexpected data at the end of the pack");
+		return -1;
+	}
+
+	packfile_trailer = git_mwindow_open(&idx->pack->mwf, &w, idx->pack->mwf.size - GIT_OID_RAWSZ, GIT_OID_RAWSZ, &left);
+	if (packfile_trailer == NULL) {
+		git_mwindow_close(&w);
+		goto on_error;
+	}
+
+	/* Compare the packfile trailer as it was sent to us and what we calculated */
+	git_oid_fromraw(&file_hash, packfile_trailer);
+	git_mwindow_close(&w);
+
+	git_hash_final(&trailer_hash, &idx->trailer);
+	if (git_oid_cmp(&file_hash, &trailer_hash)) {
+		giterr_set(GITERR_INDEXER, "packfile trailer mismatch");
+		return -1;
+	}
+
+	/* Freeze the number of deltas */
+	stats->total_deltas = stats->total_objects - stats->indexed_objects;
+
+	if ((error = resolve_deltas(idx, stats)) < 0)
+		return error;
+
+	if (stats->indexed_objects != stats->total_objects) {
+		giterr_set(GITERR_INDEXER, "early EOF");
+		return -1;
+	}
+
+	if (stats->local_objects > 0) {
+		if (update_header_and_rehash(idx, stats) < 0)
+			return -1;
+
+		git_hash_final(&trailer_hash, &idx->trailer);
+		write_at(idx, &trailer_hash, idx->pack->mwf.size - GIT_OID_RAWSZ, GIT_OID_RAWSZ);
+	}
+
+	git_vector_sort(&idx->objects);
+
+	git_buf_sets(&filename, idx->pack->pack_name);
+	git_buf_shorten(&filename, strlen("pack"));
+	git_buf_puts(&filename, "idx");
+	if (git_buf_oom(&filename))
+		return -1;
+
+	if (git_filebuf_open(&index_file, filename.ptr,
+		GIT_FILEBUF_HASH_CONTENTS, idx->mode) < 0)
+		goto on_error;
+
+	/* Write out the header */
+	hdr.idx_signature = htonl(PACK_IDX_SIGNATURE);
+	hdr.idx_version = htonl(2);
+	git_filebuf_write(&index_file, &hdr, sizeof(hdr));
+
+	/* Write out the fanout table */
+	for (i = 0; i < 256; ++i) {
+		uint32_t n = htonl(idx->fanout[i]);
+		git_filebuf_write(&index_file, &n, sizeof(n));
+	}
+
+	/* Write out the object names (SHA-1 hashes) */
+	git_vector_foreach(&idx->objects, i, entry) {
+		git_filebuf_write(&index_file, &entry->oid, sizeof(git_oid));
+		git_hash_update(&ctx, &entry->oid, GIT_OID_RAWSZ);
+	}
+	git_hash_final(&idx->hash, &ctx);
+
+	/* Write out the CRC32 values */
+	git_vector_foreach(&idx->objects, i, entry) {
+		git_filebuf_write(&index_file, &entry->crc, sizeof(uint32_t));
+	}
+
+	/* Write out the offsets */
+	git_vector_foreach(&idx->objects, i, entry) {
+		uint32_t n;
+
+		if (entry->offset == UINT32_MAX)
+			n = htonl(0x80000000 | long_offsets++);
+		else
+			n = htonl(entry->offset);
+
+		git_filebuf_write(&index_file, &n, sizeof(uint32_t));
+	}
+
+	/* Write out the long offsets */
+	git_vector_foreach(&idx->objects, i, entry) {
+		uint32_t split[2];
+
+		if (entry->offset != UINT32_MAX)
+			continue;
+
+		split[0] = htonl(entry->offset_long >> 32);
+		split[1] = htonl(entry->offset_long & 0xffffffff);
+
+		git_filebuf_write(&index_file, &split, sizeof(uint32_t) * 2);
+	}
+
+	/* Write out the packfile trailer to the index */
+	if (git_filebuf_write(&index_file, &trailer_hash, GIT_OID_RAWSZ) < 0)
+		goto on_error;
+
+	/* Write out the hash of the idx */
+	if (git_filebuf_hash(&trailer_hash, &index_file) < 0)
+		goto on_error;
+
+	git_filebuf_write(&index_file, &trailer_hash, sizeof(git_oid));
+
+	/* Figure out what the final name should be */
+	if (index_path(&filename, idx, ".idx") < 0)
+		goto on_error;
+
+	/* Commit file */
+	if (git_filebuf_commit_at(&index_file, filename.ptr) < 0)
+		goto on_error;
+
+	git_mwindow_free_all(&idx->pack->mwf);
+	/* We need to close the descriptor here so Windows doesn't choke on commit_at */
+	if (p_close(idx->pack->mwf.fd) < 0) {
+		giterr_set(GITERR_OS, "failed to close packfile");
+		goto on_error;
+	}
+
+	idx->pack->mwf.fd = -1;
+
+	if (index_path(&filename, idx, ".pack") < 0)
+		goto on_error;
+
+	/* And don't forget to rename the packfile to its new place. */
+	p_rename(idx->pack->pack_name, git_buf_cstr(&filename));
+
+	git_buf_free(&filename);
+	git_hash_ctx_cleanup(&ctx);
+	return 0;
+
+on_error:
+	git_mwindow_free_all(&idx->pack->mwf);
+	git_filebuf_cleanup(&index_file);
+	git_buf_free(&filename);
+	git_hash_ctx_cleanup(&ctx);
+	return -1;
+}
+
+void git_indexer_free(git_indexer *idx)
+{
+	if (idx == NULL)
+		return;
+
+	git_vector_free_deep(&idx->objects);
+
+	if (idx->pack && idx->pack->idx_cache) {
+		struct git_pack_entry *pentry;
+		kh_foreach_value(
+			idx->pack->idx_cache, pentry, { git__free(pentry); });
+
+		git_oidmap_free(idx->pack->idx_cache);
+	}
+
+	git_vector_free_deep(&idx->deltas);
+
+	if (!git_mutex_lock(&git__mwindow_mutex)) {
+		git_packfile_free(idx->pack);
+		git_mutex_unlock(&git__mwindow_mutex);
+	}
+
+	git_hash_ctx_cleanup(&idx->trailer);
+	git_hash_ctx_cleanup(&idx->hash_ctx);
+	git__free(idx);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/integer.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/integer.h
new file mode 100755
index 0000000..b08094c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/integer.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_integer_h__
+#define INCLUDE_integer_h__
+
+/** @return true if p fits into the range of a size_t */
+GIT_INLINE(int) git__is_sizet(git_off_t p)
+{
+	size_t r = (size_t)p;
+	return p == (git_off_t)r;
+}
+
+/** @return true if p fits into the range of an ssize_t */
+GIT_INLINE(int) git__is_ssizet(size_t p)
+{
+	ssize_t r = (ssize_t)p;
+	return p == (size_t)r;
+}
+
+/** @return true if p fits into the range of a uint32_t */
+GIT_INLINE(int) git__is_uint32(size_t p)
+{
+	uint32_t r = (uint32_t)p;
+	return p == (size_t)r;
+}
+
+/** @return true if p fits into the range of an unsigned long */
+GIT_INLINE(int) git__is_ulong(git_off_t p)
+{
+	unsigned long r = (unsigned long)p;
+	return p == (git_off_t)r;
+}
+
+/** @return true if p fits into the range of an int */
+GIT_INLINE(int) git__is_int(long long p)
+{
+	int r = (int)p;
+	return p == (long long)r;
+}
+
+/**
+ * Sets `one + two` into `out`, unless the arithmetic would overflow.
+ * @return true if the result fits in a `uint64_t`, false on overflow.
+ */
+GIT_INLINE(bool) git__add_uint64_overflow(uint64_t *out, uint64_t one, uint64_t two)
+{
+	if (UINT64_MAX - one < two)
+		return true;
+	*out = one + two;
+	return false;
+}
+
+/* Use clang/gcc compiler intrinsics whenever possible */
+#if (SIZE_MAX == UINT_MAX) && __has_builtin(__builtin_uadd_overflow)
+# define git__add_sizet_overflow(out, one, two) \
+	__builtin_uadd_overflow(one, two, out)
+# define git__multiply_sizet_overflow(out, one, two) \
+	__builtin_umul_overflow(one, two, out)
+#elif (SIZE_MAX == ULONG_MAX) && __has_builtin(__builtin_uaddl_overflow)
+# define git__add_sizet_overflow(out, one, two) \
+	__builtin_uaddl_overflow(one, two, out)
+# define git__multiply_sizet_overflow(out, one, two) \
+	__builtin_umull_overflow(one, two, out)
+#else
+
+/**
+ * Sets `one + two` into `out`, unless the arithmetic would overflow.
+ * @return true if the result fits in a `size_t`, false on overflow.
+ */
+GIT_INLINE(bool) git__add_sizet_overflow(size_t *out, size_t one, size_t two)
+{
+	if (SIZE_MAX - one < two)
+		return true;
+	*out = one + two;
+	return false;
+}
+
+/**
+ * Sets `one * two` into `out`, unless the arithmetic would overflow.
+ * @return true if the result fits in a `size_t`, false on overflow.
+ */
+GIT_INLINE(bool) git__multiply_sizet_overflow(size_t *out, size_t one, size_t two)
+{
+	if (one && SIZE_MAX / one < two)
+		return true;
+	*out = one * two;
+	return false;
+}
+
+#endif
+
+#endif /* INCLUDE_integer_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/iterator.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/iterator.c
new file mode 100755
index 0000000..cf51a34
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/iterator.c
@@ -0,0 +1,1934 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "iterator.h"
+#include "tree.h"
+#include "index.h"
+#include "ignore.h"
+#include "buffer.h"
+#include "submodule.h"
+#include <ctype.h>
+
+#define ITERATOR_SET_CB(P,NAME_LC) do { \
+	(P)->cb.current = NAME_LC ## _iterator__current; \
+	(P)->cb.advance = NAME_LC ## _iterator__advance; \
+	(P)->cb.advance_into = NAME_LC ## _iterator__advance_into; \
+	(P)->cb.seek    = NAME_LC ## _iterator__seek; \
+	(P)->cb.reset   = NAME_LC ## _iterator__reset; \
+	(P)->cb.at_end  = NAME_LC ## _iterator__at_end; \
+	(P)->cb.free    = NAME_LC ## _iterator__free; \
+	} while (0)
+
+#define ITERATOR_CASE_FLAGS \
+	(GIT_ITERATOR_IGNORE_CASE | GIT_ITERATOR_DONT_IGNORE_CASE)
+
+#define ITERATOR_BASE_INIT(P,NAME_LC,NAME_UC,REPO) do { \
+	(P)->base.type    = GIT_ITERATOR_TYPE_ ## NAME_UC; \
+	(P)->base.cb      = &(P)->cb; \
+	ITERATOR_SET_CB(P,NAME_LC); \
+	(P)->base.repo    = (REPO); \
+	(P)->base.start   = start ? git__strdup(start) : NULL; \
+	(P)->base.end     = end ? git__strdup(end) : NULL; \
+	if ((start && !(P)->base.start) || (end && !(P)->base.end)) { \
+		git__free(P); return -1; } \
+	(P)->base.prefixcomp = git__prefixcmp; \
+	(P)->base.flags = flags & ~ITERATOR_CASE_FLAGS; \
+	if ((P)->base.flags & GIT_ITERATOR_DONT_AUTOEXPAND) \
+		(P)->base.flags |= GIT_ITERATOR_INCLUDE_TREES; \
+	} while (0)
+
+#define iterator__flag(I,F) ((((git_iterator *)(I))->flags & GIT_ITERATOR_ ## F) != 0)
+#define iterator__ignore_case(I)     iterator__flag(I,IGNORE_CASE)
+#define iterator__include_trees(I)   iterator__flag(I,INCLUDE_TREES)
+#define iterator__dont_autoexpand(I) iterator__flag(I,DONT_AUTOEXPAND)
+#define iterator__do_autoexpand(I)   !iterator__flag(I,DONT_AUTOEXPAND)
+#define iterator__include_conflicts(I) iterator__flag(I, INCLUDE_CONFLICTS)
+
+#define GIT_ITERATOR_FIRST_ACCESS (1 << 15)
+#define iterator__has_been_accessed(I) iterator__flag(I,FIRST_ACCESS)
+
+#define iterator__end(I) ((git_iterator *)(I))->end
+#define iterator__past_end(I,PATH) \
+	(iterator__end(I) && ((git_iterator *)(I))->prefixcomp((PATH),iterator__end(I)) > 0)
+
+
+static int iterator__reset_range(
+	git_iterator *iter, const char *start, const char *end)
+{
+	if (start) {
+		if (iter->start)
+			git__free(iter->start);
+		iter->start = git__strdup(start);
+		GITERR_CHECK_ALLOC(iter->start);
+	}
+
+	if (end) {
+		if (iter->end)
+			git__free(iter->end);
+		iter->end = git__strdup(end);
+		GITERR_CHECK_ALLOC(iter->end);
+	}
+
+	iter->flags &= ~GIT_ITERATOR_FIRST_ACCESS;
+
+	return 0;
+}
+
+static int iterator__update_ignore_case(
+	git_iterator *iter,
+	git_iterator_flag_t flags)
+{
+	int error = 0, ignore_case = -1;
+
+	if ((flags & GIT_ITERATOR_IGNORE_CASE) != 0)
+		ignore_case = true;
+	else if ((flags & GIT_ITERATOR_DONT_IGNORE_CASE) != 0)
+		ignore_case = false;
+	else {
+		git_index *index;
+
+		if (!(error = git_repository_index__weakptr(&index, iter->repo)))
+			ignore_case = (index->ignore_case != false);
+	}
+
+	if (ignore_case > 0)
+		iter->flags = (iter->flags | GIT_ITERATOR_IGNORE_CASE);
+	else if (ignore_case == 0)
+		iter->flags = (iter->flags & ~GIT_ITERATOR_IGNORE_CASE);
+
+	iter->prefixcomp = iterator__ignore_case(iter) ?
+		git__prefixcmp_icase : git__prefixcmp;
+
+	return error;
+}
+
+GIT_INLINE(void) iterator__clear_entry(const git_index_entry **entry)
+{
+	if (entry) *entry = NULL;
+}
+
+
+static int empty_iterator__noop(const git_index_entry **e, git_iterator *i)
+{
+	GIT_UNUSED(i);
+	iterator__clear_entry(e);
+	return GIT_ITEROVER;
+}
+
+static int empty_iterator__seek(git_iterator *i, const char *p)
+{
+	GIT_UNUSED(i); GIT_UNUSED(p);
+	return -1;
+}
+
+static int empty_iterator__reset(git_iterator *i, const char *s, const char *e)
+{
+	GIT_UNUSED(i); GIT_UNUSED(s); GIT_UNUSED(e);
+	return 0;
+}
+
+static int empty_iterator__at_end(git_iterator *i)
+{
+	GIT_UNUSED(i);
+	return 1;
+}
+
+static void empty_iterator__free(git_iterator *i)
+{
+	GIT_UNUSED(i);
+}
+
+typedef struct {
+	git_iterator base;
+	git_iterator_callbacks cb;
+} empty_iterator;
+
+int git_iterator_for_nothing(
+	git_iterator **iter,
+	git_iterator_flag_t flags,
+	const char *start,
+	const char *end)
+{
+	empty_iterator *i = git__calloc(1, sizeof(empty_iterator));
+	GITERR_CHECK_ALLOC(i);
+
+#define empty_iterator__current empty_iterator__noop
+#define empty_iterator__advance empty_iterator__noop
+#define empty_iterator__advance_into empty_iterator__noop
+
+	ITERATOR_BASE_INIT(i, empty, EMPTY, NULL);
+
+	if ((flags & GIT_ITERATOR_IGNORE_CASE) != 0)
+		i->base.flags |= GIT_ITERATOR_IGNORE_CASE;
+
+	*iter = (git_iterator *)i;
+	return 0;
+}
+
+
+typedef struct tree_iterator_entry tree_iterator_entry;
+struct tree_iterator_entry {
+	tree_iterator_entry *parent;
+	const git_tree_entry *te;
+	git_tree *tree;
+};
+
+typedef struct tree_iterator_frame tree_iterator_frame;
+struct tree_iterator_frame {
+	tree_iterator_frame *up, *down;
+
+	size_t n_entries; /* items in this frame */
+	size_t current;   /* start of currently active range in frame */
+	size_t next;      /* start of next range in frame */
+
+	const char *start;
+	size_t startlen;
+
+	tree_iterator_entry *entries[GIT_FLEX_ARRAY];
+};
+
+typedef struct {
+	git_iterator base;
+	git_iterator_callbacks cb;
+	tree_iterator_frame *head, *root;
+	git_pool pool;
+	git_index_entry entry;
+	git_buf path;
+	int path_ambiguities;
+	bool path_has_filename;
+	bool entry_is_current;
+	int (*strncomp)(const char *a, const char *b, size_t sz);
+} tree_iterator;
+
+static char *tree_iterator__current_filename(
+	tree_iterator *ti, const git_tree_entry *te)
+{
+	if (!ti->path_has_filename) {
+		if (git_buf_joinpath(&ti->path, ti->path.ptr, te->filename) < 0)
+			return NULL;
+
+		if (git_tree_entry__is_tree(te) && git_buf_putc(&ti->path, '/') < 0)
+			return NULL;
+
+		ti->path_has_filename = true;
+	}
+
+	return ti->path.ptr;
+}
+
+static void tree_iterator__rewrite_filename(tree_iterator *ti)
+{
+	tree_iterator_entry *scan = ti->head->entries[ti->head->current];
+	ssize_t strpos = ti->path.size;
+	const git_tree_entry *te;
+
+	if (strpos && ti->path.ptr[strpos - 1] == '/')
+		strpos--;
+
+	for (; scan && (te = scan->te); scan = scan->parent) {
+		strpos -= te->filename_len;
+		memcpy(&ti->path.ptr[strpos], te->filename, te->filename_len);
+		strpos -= 1; /* separator */
+	}
+}
+
+static int tree_iterator__te_cmp(
+	const git_tree_entry *a,
+	const git_tree_entry *b,
+	int (*compare)(const char *, const char *, size_t))
+{
+	return git_path_cmp(
+		a->filename, a->filename_len, a->attr == GIT_FILEMODE_TREE,
+		b->filename, b->filename_len, b->attr == GIT_FILEMODE_TREE,
+		compare);
+}
+
+static int tree_iterator__ci_cmp(const void *a, const void *b, void *p)
+{
+	const tree_iterator_entry *ae = a, *be = b;
+	int cmp = tree_iterator__te_cmp(ae->te, be->te, git__strncasecmp);
+
+	if (!cmp) {
+		/* stabilize sort order among equivalent names */
+		if (!ae->parent->te || !be->parent->te)
+			cmp = tree_iterator__te_cmp(ae->te, be->te, git__strncmp);
+		else
+			cmp = tree_iterator__ci_cmp(ae->parent, be->parent, p);
+	}
+
+	return cmp;
+}
+
+static int tree_iterator__search_cmp(const void *key, const void *val, void *p)
+{
+	const tree_iterator_frame *tf = key;
+	const git_tree_entry *te = ((tree_iterator_entry *)val)->te;
+
+	return git_path_cmp(
+		tf->start, tf->startlen, false,
+		te->filename, te->filename_len, te->attr == GIT_FILEMODE_TREE,
+		((tree_iterator *)p)->strncomp);
+}
+
+static bool tree_iterator__move_to_next(
+	tree_iterator *ti, tree_iterator_frame *tf)
+{
+	if (tf->next > tf->current + 1)
+		ti->path_ambiguities--;
+
+	if (!tf->up) { /* at root */
+		tf->current = tf->next;
+		return false;
+	}
+
+	for (; tf->current < tf->next; tf->current++) {
+		git_tree_free(tf->entries[tf->current]->tree);
+		tf->entries[tf->current]->tree = NULL;
+	}
+
+	return (tf->current < tf->n_entries);
+}
+
+static int tree_iterator__set_next(tree_iterator *ti, tree_iterator_frame *tf)
+{
+	int error = 0;
+	const git_tree_entry *te, *last = NULL;
+
+	tf->next = tf->current;
+
+	for (; tf->next < tf->n_entries; tf->next++, last = te) {
+		te = tf->entries[tf->next]->te;
+
+		if (last && tree_iterator__te_cmp(last, te, ti->strncomp))
+			break;
+
+		/* try to load trees for items in [current,next) range */
+		if (!error && git_tree_entry__is_tree(te))
+			error = git_tree_lookup(
+				&tf->entries[tf->next]->tree, ti->base.repo, &te->oid);
+	}
+
+	if (tf->next > tf->current + 1)
+		ti->path_ambiguities++;
+
+	/* if a tree lookup failed, advance over this span and return failure */
+	if (error < 0) {
+		tree_iterator__move_to_next(ti, tf);
+		return error;
+	}
+
+	if (last && !tree_iterator__current_filename(ti, last))
+		return -1; /* must have been allocation failure */
+
+	return 0;
+}
+
+GIT_INLINE(bool) tree_iterator__at_tree(tree_iterator *ti)
+{
+	return (ti->head->current < ti->head->n_entries &&
+			ti->head->entries[ti->head->current]->tree != NULL);
+}
+
+static int tree_iterator__push_frame(tree_iterator *ti)
+{
+	int error = 0;
+	tree_iterator_frame *head = ti->head, *tf = NULL;
+	size_t i, n_entries = 0, alloclen;
+
+	if (head->current >= head->n_entries || !head->entries[head->current]->tree)
+		return GIT_ITEROVER;
+
+	for (i = head->current; i < head->next; ++i)
+		n_entries += git_tree_entrycount(head->entries[i]->tree);
+
+	GITERR_CHECK_ALLOC_MULTIPLY(&alloclen, sizeof(tree_iterator_entry *), n_entries);
+	GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, sizeof(tree_iterator_frame));
+
+	tf = git__calloc(1, alloclen);
+	GITERR_CHECK_ALLOC(tf);
+
+	tf->n_entries = n_entries;
+
+	tf->up     = head;
+	head->down = tf;
+	ti->head   = tf;
+
+	for (i = head->current, n_entries = 0; i < head->next; ++i) {
+		git_tree *tree = head->entries[i]->tree;
+		size_t j, max_j = git_tree_entrycount(tree);
+
+		for (j = 0; j < max_j; ++j) {
+			tree_iterator_entry *entry = git_pool_malloc(&ti->pool, 1);
+			GITERR_CHECK_ALLOC(entry);
+
+			entry->parent = head->entries[i];
+			entry->te     = git_tree_entry_byindex(tree, j);
+			entry->tree   = NULL;
+
+			tf->entries[n_entries++] = entry;
+		}
+	}
+
+	/* if ignore_case, sort entries case insensitively */
+	if (iterator__ignore_case(ti))
+		git__tsort_r(
+			(void **)tf->entries, tf->n_entries, tree_iterator__ci_cmp, tf);
+
+	/* pick tf->current based on "start" (or start at zero) */
+	if (head->startlen > 0) {
+		git__bsearch_r((void **)tf->entries, tf->n_entries, head,
+			tree_iterator__search_cmp, ti, &tf->current);
+
+		while (tf->current &&
+			   !tree_iterator__search_cmp(head, tf->entries[tf->current-1], ti))
+			tf->current--;
+
+		if ((tf->start = strchr(head->start, '/')) != NULL) {
+			tf->start++;
+			tf->startlen = strlen(tf->start);
+		}
+	}
+
+	ti->path_has_filename = ti->entry_is_current = false;
+
+	if ((error = tree_iterator__set_next(ti, tf)) < 0)
+		return error;
+
+	/* autoexpand as needed */
+	if (!iterator__include_trees(ti) && tree_iterator__at_tree(ti))
+		return tree_iterator__push_frame(ti);
+
+	return 0;
+}
+
+static bool tree_iterator__pop_frame(tree_iterator *ti, bool final)
+{
+	tree_iterator_frame *tf = ti->head;
+
+	if (!tf->up)
+		return false;
+
+	ti->head = tf->up;
+	ti->head->down = NULL;
+
+	tree_iterator__move_to_next(ti, tf);
+
+	if (!final) { /* if final, don't bother to clean up */
+		git_pool_free_array(&ti->pool, tf->n_entries, (void **)tf->entries);
+		git_buf_rtruncate_at_char(&ti->path, '/');
+	}
+
+	git__free(tf);
+
+	return true;
+}
+
+static void tree_iterator__pop_all(tree_iterator *ti, bool to_end, bool final)
+{
+	while (tree_iterator__pop_frame(ti, final)) /* pop to root */;
+
+	if (!final) {
+		ti->head->current = to_end ? ti->head->n_entries : 0;
+		ti->path_ambiguities = 0;
+		git_buf_clear(&ti->path);
+	}
+}
+
+static int tree_iterator__update_entry(tree_iterator *ti)
+{
+	tree_iterator_frame *tf;
+    const git_tree_entry *te;
+
+	if (ti->entry_is_current)
+        return 0;
+
+	tf = ti->head;
+    te = tf->entries[tf->current]->te;
+
+	ti->entry.mode = te->attr;
+	git_oid_cpy(&ti->entry.id, &te->oid);
+
+	ti->entry.path = tree_iterator__current_filename(ti, te);
+	GITERR_CHECK_ALLOC(ti->entry.path);
+
+	if (ti->path_ambiguities > 0)
+		tree_iterator__rewrite_filename(ti);
+
+	if (iterator__past_end(ti, ti->entry.path)) {
+		tree_iterator__pop_all(ti, true, false);
+		return GIT_ITEROVER;
+	}
+
+	ti->entry_is_current = true;
+
+	return 0;
+}
+
+static int tree_iterator__current(
+	const git_index_entry **entry, git_iterator *self)
+{
+	int error;
+	tree_iterator *ti = (tree_iterator *)self;
+	tree_iterator_frame *tf = ti->head;
+
+	iterator__clear_entry(entry);
+
+	if (tf->current >= tf->n_entries)
+		return GIT_ITEROVER;
+
+	if ((error = tree_iterator__update_entry(ti)) < 0)
+		return error;
+
+	if (entry)
+		*entry = &ti->entry;
+
+	ti->base.flags |= GIT_ITERATOR_FIRST_ACCESS;
+
+	return 0;
+}
+
+static int tree_iterator__advance_into(
+	const git_index_entry **entry, git_iterator *self)
+{
+	int error = 0;
+	tree_iterator *ti = (tree_iterator *)self;
+
+	iterator__clear_entry(entry);
+
+	if (tree_iterator__at_tree(ti))
+		error = tree_iterator__push_frame(ti);
+
+	if (!error && entry)
+		error = tree_iterator__current(entry, self);
+
+	return error;
+}
+
+static int tree_iterator__advance(
+	const git_index_entry **entry, git_iterator *self)
+{
+	int error;
+	tree_iterator *ti = (tree_iterator *)self;
+	tree_iterator_frame *tf = ti->head;
+
+	iterator__clear_entry(entry);
+
+	if (tf->current >= tf->n_entries)
+		return GIT_ITEROVER;
+
+	if (!iterator__has_been_accessed(ti))
+		return tree_iterator__current(entry, self);
+
+	if (iterator__do_autoexpand(ti) && iterator__include_trees(ti) &&
+		tree_iterator__at_tree(ti))
+		return tree_iterator__advance_into(entry, self);
+
+	if (ti->path_has_filename) {
+		git_buf_rtruncate_at_char(&ti->path, '/');
+		ti->path_has_filename = ti->entry_is_current = false;
+	}
+
+	/* scan forward and up, advancing in frame or popping frame when done */
+	while (!tree_iterator__move_to_next(ti, tf) &&
+		   tree_iterator__pop_frame(ti, false))
+		tf = ti->head;
+
+	/* find next and load trees */
+	if ((error = tree_iterator__set_next(ti, tf)) < 0)
+		return error;
+
+	/* deal with include_trees / auto_expand as needed */
+	if (!iterator__include_trees(ti) && tree_iterator__at_tree(ti))
+		return tree_iterator__advance_into(entry, self);
+
+	return tree_iterator__current(entry, self);
+}
+
+static int tree_iterator__seek(git_iterator *self, const char *prefix)
+{
+	GIT_UNUSED(self); GIT_UNUSED(prefix);
+	return -1;
+}
+
+static int tree_iterator__reset(
+	git_iterator *self, const char *start, const char *end)
+{
+	tree_iterator *ti = (tree_iterator *)self;
+
+	tree_iterator__pop_all(ti, false, false);
+
+	if (iterator__reset_range(self, start, end) < 0)
+		return -1;
+
+	return tree_iterator__push_frame(ti); /* re-expand root tree */
+}
+
+static int tree_iterator__at_end(git_iterator *self)
+{
+	tree_iterator *ti = (tree_iterator *)self;
+	return (ti->head->current >= ti->head->n_entries);
+}
+
+static void tree_iterator__free(git_iterator *self)
+{
+	tree_iterator *ti = (tree_iterator *)self;
+
+	tree_iterator__pop_all(ti, true, false);
+
+	git_tree_free(ti->head->entries[0]->tree);
+	git__free(ti->head);
+	git_pool_clear(&ti->pool);
+	git_buf_free(&ti->path);
+}
+
+static int tree_iterator__create_root_frame(tree_iterator *ti, git_tree *tree)
+{
+	size_t sz = sizeof(tree_iterator_frame) + sizeof(tree_iterator_entry);
+	tree_iterator_frame *root = git__calloc(sz, sizeof(char));
+	GITERR_CHECK_ALLOC(root);
+
+	root->n_entries  = 1;
+	root->next       = 1;
+	root->start      = ti->base.start;
+	root->startlen   = root->start ? strlen(root->start) : 0;
+	root->entries[0] = git_pool_mallocz(&ti->pool, 1);
+	GITERR_CHECK_ALLOC(root->entries[0]);
+	root->entries[0]->tree = tree;
+
+	ti->head = ti->root = root;
+
+	return 0;
+}
+
+int git_iterator_for_tree(
+	git_iterator **iter,
+	git_tree *tree,
+	git_iterator_flag_t flags,
+	const char *start,
+	const char *end)
+{
+	int error;
+	tree_iterator *ti;
+
+	if (tree == NULL)
+		return git_iterator_for_nothing(iter, flags, start, end);
+
+	if ((error = git_object_dup((git_object **)&tree, (git_object *)tree)) < 0)
+		return error;
+
+	ti = git__calloc(1, sizeof(tree_iterator));
+	GITERR_CHECK_ALLOC(ti);
+
+	ITERATOR_BASE_INIT(ti, tree, TREE, git_tree_owner(tree));
+
+	if ((error = iterator__update_ignore_case((git_iterator *)ti, flags)) < 0)
+		goto fail;
+	ti->strncomp = iterator__ignore_case(ti) ? git__strncasecmp : git__strncmp;
+
+	if ((error = git_pool_init(&ti->pool, sizeof(tree_iterator_entry),0)) < 0 ||
+		(error = tree_iterator__create_root_frame(ti, tree)) < 0 ||
+		(error = tree_iterator__push_frame(ti)) < 0) /* expand root now */
+		goto fail;
+
+	*iter = (git_iterator *)ti;
+	return 0;
+
+fail:
+	git_iterator_free((git_iterator *)ti);
+	return error;
+}
+
+
+typedef struct {
+	git_iterator base;
+	git_iterator_callbacks cb;
+	git_index *index;
+	git_vector entries;
+	git_vector_cmp entry_srch;
+	size_t current;
+	/* when not in autoexpand mode, use these to represent "tree" state */
+	git_buf partial;
+	size_t partial_pos;
+	char restore_terminator;
+	git_index_entry tree_entry;
+} index_iterator;
+
+static const git_index_entry *index_iterator__index_entry(index_iterator *ii)
+{
+	const git_index_entry *ie = git_vector_get(&ii->entries, ii->current);
+
+	if (ie != NULL && iterator__past_end(ii, ie->path)) {
+		ii->current = git_vector_length(&ii->entries);
+		ie = NULL;
+	}
+
+	return ie;
+}
+
+static const git_index_entry *index_iterator__advance_over_conflicts(index_iterator *ii)
+{
+	const git_index_entry *ie = index_iterator__index_entry(ii);
+
+	if (!iterator__include_conflicts(ii)) {
+		while (ie && git_index_entry_is_conflict(ie)) {
+			ii->current++;
+			ie = index_iterator__index_entry(ii);
+		}
+	}
+
+	return ie;
+}
+
+static void index_iterator__next_prefix_tree(index_iterator *ii)
+{
+	const char *slash;
+
+	if (!iterator__include_trees(ii))
+		return;
+
+	slash = strchr(&ii->partial.ptr[ii->partial_pos], '/');
+
+	if (slash != NULL) {
+		ii->partial_pos = (slash - ii->partial.ptr) + 1;
+		ii->restore_terminator = ii->partial.ptr[ii->partial_pos];
+		ii->partial.ptr[ii->partial_pos] = '\0';
+	} else {
+		ii->partial_pos = ii->partial.size;
+	}
+
+	if (index_iterator__index_entry(ii) == NULL)
+		ii->partial_pos = ii->partial.size;
+}
+
+static int index_iterator__first_prefix_tree(index_iterator *ii)
+{
+	const git_index_entry *ie = index_iterator__advance_over_conflicts(ii);
+	const char *scan, *prior, *slash;
+
+	if (!ie || !iterator__include_trees(ii))
+		return 0;
+
+	/* find longest common prefix with prior index entry */
+	for (scan = slash = ie->path, prior = ii->partial.ptr;
+		 *scan && *scan == *prior; ++scan, ++prior)
+		if (*scan == '/')
+			slash = scan;
+
+	if (git_buf_sets(&ii->partial, ie->path) < 0)
+		return -1;
+
+	ii->partial_pos = (slash - ie->path) + 1;
+	index_iterator__next_prefix_tree(ii);
+
+	return 0;
+}
+
+#define index_iterator__at_tree(I) \
+	(iterator__include_trees(I) && (I)->partial_pos < (I)->partial.size)
+
+static int index_iterator__current(
+	const git_index_entry **entry, git_iterator *self)
+{
+	index_iterator *ii = (index_iterator *)self;
+	const git_index_entry *ie = git_vector_get(&ii->entries, ii->current);
+
+	if (ie != NULL && index_iterator__at_tree(ii)) {
+		ii->tree_entry.path = ii->partial.ptr;
+		ie = &ii->tree_entry;
+	}
+
+	if (entry)
+		*entry = ie;
+
+	ii->base.flags |= GIT_ITERATOR_FIRST_ACCESS;
+
+	return (ie != NULL) ? 0 : GIT_ITEROVER;
+}
+
+static int index_iterator__at_end(git_iterator *self)
+{
+	index_iterator *ii = (index_iterator *)self;
+	return (ii->current >= git_vector_length(&ii->entries));
+}
+
+static int index_iterator__advance(
+	const git_index_entry **entry, git_iterator *self)
+{
+	index_iterator *ii = (index_iterator *)self;
+	size_t entrycount = git_vector_length(&ii->entries);
+	const git_index_entry *ie;
+
+	if (!iterator__has_been_accessed(ii))
+		return index_iterator__current(entry, self);
+
+	if (index_iterator__at_tree(ii)) {
+		if (iterator__do_autoexpand(ii)) {
+			ii->partial.ptr[ii->partial_pos] = ii->restore_terminator;
+			index_iterator__next_prefix_tree(ii);
+		} else {
+			/* advance to sibling tree (i.e. find entry with new prefix) */
+			while (ii->current < entrycount) {
+				ii->current++;
+
+				if (!(ie = git_vector_get(&ii->entries, ii->current)) ||
+					ii->base.prefixcomp(ie->path, ii->partial.ptr) != 0)
+					break;
+			}
+
+			if (index_iterator__first_prefix_tree(ii) < 0)
+				return -1;
+		}
+	} else {
+		if (ii->current < entrycount)
+			ii->current++;
+
+		if (index_iterator__first_prefix_tree(ii) < 0)
+			return -1;
+	}
+
+	return index_iterator__current(entry, self);
+}
+
+static int index_iterator__advance_into(
+	const git_index_entry **entry, git_iterator *self)
+{
+	index_iterator *ii = (index_iterator *)self;
+	const git_index_entry *ie = git_vector_get(&ii->entries, ii->current);
+
+	if (ie != NULL && index_iterator__at_tree(ii)) {
+		if (ii->restore_terminator)
+			ii->partial.ptr[ii->partial_pos] = ii->restore_terminator;
+		index_iterator__next_prefix_tree(ii);
+	}
+
+	return index_iterator__current(entry, self);
+}
+
+static int index_iterator__seek(git_iterator *self, const char *prefix)
+{
+	GIT_UNUSED(self); GIT_UNUSED(prefix);
+	return -1;
+}
+
+static int index_iterator__reset(
+	git_iterator *self, const char *start, const char *end)
+{
+	index_iterator *ii = (index_iterator *)self;
+	const git_index_entry *ie;
+
+	if (iterator__reset_range(self, start, end) < 0)
+		return -1;
+
+	ii->current = 0;
+
+	if (ii->base.start)
+		git_index_snapshot_find(
+			&ii->current, &ii->entries, ii->entry_srch, ii->base.start, 0, 0);
+
+	if ((ie = index_iterator__advance_over_conflicts(ii)) == NULL)
+		return 0;
+
+	if (git_buf_sets(&ii->partial, ie->path) < 0)
+		return -1;
+
+	ii->partial_pos = 0;
+
+	if (ii->base.start) {
+		size_t startlen = strlen(ii->base.start);
+
+		ii->partial_pos = (startlen > ii->partial.size) ?
+			ii->partial.size : startlen;
+	}
+
+	index_iterator__next_prefix_tree(ii);
+
+	return 0;
+}
+
+static void index_iterator__free(git_iterator *self)
+{
+	index_iterator *ii = (index_iterator *)self;
+	git_index_snapshot_release(&ii->entries, ii->index);
+	ii->index = NULL;
+	git_buf_free(&ii->partial);
+}
+
+int git_iterator_for_index(
+	git_iterator **iter,
+	git_index  *index,
+	git_iterator_flag_t flags,
+	const char *start,
+	const char *end)
+{
+	int error = 0;
+	index_iterator *ii = git__calloc(1, sizeof(index_iterator));
+	GITERR_CHECK_ALLOC(ii);
+
+	if ((error = git_index_snapshot_new(&ii->entries, index)) < 0) {
+		git__free(ii);
+		return error;
+	}
+	ii->index = index;
+
+	ITERATOR_BASE_INIT(ii, index, INDEX, git_index_owner(index));
+
+	if ((error = iterator__update_ignore_case((git_iterator *)ii, flags)) < 0) {
+		git_iterator_free((git_iterator *)ii);
+		return error;
+	}
+
+	ii->entry_srch = iterator__ignore_case(ii) ?
+		git_index_entry_isrch : git_index_entry_srch;
+
+	git_vector_set_cmp(&ii->entries, iterator__ignore_case(ii) ?
+		git_index_entry_icmp : git_index_entry_cmp);
+	git_vector_sort(&ii->entries);
+
+	git_buf_init(&ii->partial, 0);
+	ii->tree_entry.mode = GIT_FILEMODE_TREE;
+
+	index_iterator__reset((git_iterator *)ii, NULL, NULL);
+
+	*iter = (git_iterator *)ii;
+	return 0;
+}
+
+
+typedef struct fs_iterator_frame fs_iterator_frame;
+struct fs_iterator_frame {
+	fs_iterator_frame *next;
+	git_vector entries;
+	size_t index;
+	int is_ignored;
+};
+
+typedef struct fs_iterator fs_iterator;
+struct fs_iterator {
+	git_iterator base;
+	git_iterator_callbacks cb;
+	fs_iterator_frame *stack;
+	git_index_entry entry;
+	git_buf path;
+	size_t root_len;
+	uint32_t dirload_flags;
+	int depth;
+
+	int (*enter_dir_cb)(fs_iterator *self);
+	int (*leave_dir_cb)(fs_iterator *self);
+	int (*update_entry_cb)(fs_iterator *self);
+};
+
+#define FS_MAX_DEPTH 100
+
+typedef struct {
+	struct stat st;
+	size_t      path_len;
+	char        path[GIT_FLEX_ARRAY];
+} fs_iterator_path_with_stat;
+
+static int fs_iterator_path_with_stat_cmp(const void *a, const void *b)
+{
+	const fs_iterator_path_with_stat *psa = a, *psb = b;
+	return strcmp(psa->path, psb->path);
+}
+
+static int fs_iterator_path_with_stat_cmp_icase(const void *a, const void *b)
+{
+	const fs_iterator_path_with_stat *psa = a, *psb = b;
+	return strcasecmp(psa->path, psb->path);
+}
+
+static fs_iterator_frame *fs_iterator__alloc_frame(fs_iterator *fi)
+{
+	fs_iterator_frame *ff = git__calloc(1, sizeof(fs_iterator_frame));
+	git_vector_cmp entry_compare = CASESELECT(
+		iterator__ignore_case(fi),
+		fs_iterator_path_with_stat_cmp_icase,
+		fs_iterator_path_with_stat_cmp);
+
+	if (ff && git_vector_init(&ff->entries, 0, entry_compare) < 0) {
+		git__free(ff);
+		ff = NULL;
+	}
+
+	return ff;
+}
+
+static void fs_iterator__free_frame(fs_iterator_frame *ff)
+{
+	git_vector_free_deep(&ff->entries);
+	git__free(ff);
+}
+
+static void fs_iterator__pop_frame(
+	fs_iterator *fi, fs_iterator_frame *ff, bool pop_last)
+{
+	if (fi && fi->stack == ff) {
+		if (!ff->next && !pop_last) {
+			memset(&fi->entry, 0, sizeof(fi->entry));
+			return;
+		}
+
+		if (fi->leave_dir_cb)
+			(void)fi->leave_dir_cb(fi);
+
+		fi->stack = ff->next;
+		fi->depth--;
+	}
+
+	fs_iterator__free_frame(ff);
+}
+
+static int fs_iterator__update_entry(fs_iterator *fi);
+static int fs_iterator__advance_over(
+	const git_index_entry **entry, git_iterator *self);
+
+static int fs_iterator__entry_cmp(const void *i, const void *item)
+{
+	const fs_iterator *fi = (const fs_iterator *)i;
+	const fs_iterator_path_with_stat *ps = item;
+	return fi->base.prefixcomp(fi->base.start, ps->path);
+}
+
+static void fs_iterator__seek_frame_start(
+	fs_iterator *fi, fs_iterator_frame *ff)
+{
+	if (!ff)
+		return;
+
+	if (fi->base.start)
+		git_vector_bsearch2(
+			&ff->index, &ff->entries, fs_iterator__entry_cmp, fi);
+	else
+		ff->index = 0;
+}
+
+static int dirload_with_stat(
+	const char *dirpath,
+	size_t prefix_len,
+	unsigned int flags,
+	const char *start_stat,
+	const char *end_stat,
+	git_vector *contents)
+{
+	git_path_diriter diriter = GIT_PATH_DIRITER_INIT;
+	const char *path;
+	int (*strncomp)(const char *a, const char *b, size_t sz);
+	size_t start_len = start_stat ? strlen(start_stat) : 0;
+	size_t end_len = end_stat ? strlen(end_stat) : 0;
+	fs_iterator_path_with_stat *ps;
+	size_t path_len, cmp_len, ps_size;
+	int error;
+
+	strncomp = (flags & GIT_PATH_DIR_IGNORE_CASE) != 0 ?
+		git__strncasecmp : git__strncmp;
+
+	/* Any error here is equivalent to the dir not existing, skip over it */
+	if ((error = git_path_diriter_init(&diriter, dirpath, flags)) < 0) {
+		error = GIT_ENOTFOUND;
+		goto done;
+	}
+
+	while ((error = git_path_diriter_next(&diriter)) == 0) {
+		if ((error = git_path_diriter_fullpath(&path, &path_len, &diriter)) < 0)
+			goto done;
+
+		assert(path_len > prefix_len);
+
+		/* remove the prefix if requested */
+		path += prefix_len;
+		path_len -= prefix_len;
+
+		/* skip if before start_stat or after end_stat */
+		cmp_len = min(start_len, path_len);
+		if (cmp_len && strncomp(path, start_stat, cmp_len) < 0)
+			continue;
+		cmp_len = min(end_len, path_len);
+		if (cmp_len && strncomp(path, end_stat, cmp_len) > 0)
+			continue;
+
+		/* Make sure to append two bytes, one for the path's null
+		 * termination, one for a possible trailing '/' for folders.
+		 */
+		GITERR_CHECK_ALLOC_ADD(&ps_size, sizeof(fs_iterator_path_with_stat), path_len);
+		GITERR_CHECK_ALLOC_ADD(&ps_size, ps_size, 2);
+
+		ps = git__calloc(1, ps_size);
+		ps->path_len = path_len;
+
+		memcpy(ps->path, path, path_len);
+
+		if ((error = git_path_diriter_stat(&ps->st, &diriter)) < 0) {
+			if (error == GIT_ENOTFOUND) {
+				/* file was removed between readdir and lstat */
+				git__free(ps);
+				continue;
+			}
+
+			/* Treat the file as unreadable if we get any other error */
+			memset(&ps->st, 0, sizeof(ps->st));
+			ps->st.st_mode = GIT_FILEMODE_UNREADABLE;
+
+			giterr_clear();
+			error = 0;
+		} else if (S_ISDIR(ps->st.st_mode)) {
+			/* Suffix directory paths with a '/' */
+			ps->path[ps->path_len++] = '/';
+			ps->path[ps->path_len] = '\0';
+		} else if(!S_ISREG(ps->st.st_mode) && !S_ISLNK(ps->st.st_mode)) {
+			/* Ignore wacky things in the filesystem */
+			git__free(ps);
+			continue;
+		}
+
+		git_vector_insert(contents, ps);
+	}
+
+	if (error == GIT_ITEROVER)
+		error = 0;
+
+	/* sort now that directory suffix is added */
+	git_vector_sort(contents);
+
+done:
+	git_path_diriter_free(&diriter);
+	return error;
+}
+
+
+static int fs_iterator__expand_dir(fs_iterator *fi)
+{
+	int error;
+	fs_iterator_frame *ff;
+
+	if (fi->depth > FS_MAX_DEPTH) {
+		giterr_set(GITERR_REPOSITORY,
+			"Directory nesting is too deep (%d)", fi->depth);
+		return -1;
+	}
+
+	ff = fs_iterator__alloc_frame(fi);
+	GITERR_CHECK_ALLOC(ff);
+
+	error = dirload_with_stat(
+		fi->path.ptr, fi->root_len, fi->dirload_flags,
+		fi->base.start, fi->base.end, &ff->entries);
+
+	if (error < 0) {
+		git_error_state last_error = { 0 };
+		giterr_capture(&last_error, error);
+
+		/* these callbacks may clear the error message */
+		fs_iterator__free_frame(ff);
+		fs_iterator__advance_over(NULL, (git_iterator *)fi);
+		/* next time return value we skipped to */
+		fi->base.flags &= ~GIT_ITERATOR_FIRST_ACCESS;
+
+		return giterr_restore(&last_error);
+	}
+
+	if (ff->entries.length == 0) {
+		fs_iterator__free_frame(ff);
+		return GIT_ENOTFOUND;
+	}
+	fi->base.stat_calls += ff->entries.length;
+
+	fs_iterator__seek_frame_start(fi, ff);
+
+	ff->next  = fi->stack;
+	fi->stack = ff;
+	fi->depth++;
+
+	if (fi->enter_dir_cb && (error = fi->enter_dir_cb(fi)) < 0)
+		return error;
+
+	return fs_iterator__update_entry(fi);
+}
+
+static int fs_iterator__current(
+	const git_index_entry **entry, git_iterator *self)
+{
+	fs_iterator *fi = (fs_iterator *)self;
+	const git_index_entry *fe = (fi->entry.path == NULL) ? NULL : &fi->entry;
+
+	if (entry)
+		*entry = fe;
+
+	fi->base.flags |= GIT_ITERATOR_FIRST_ACCESS;
+
+	return (fe != NULL) ? 0 : GIT_ITEROVER;
+}
+
+static int fs_iterator__at_end(git_iterator *self)
+{
+	return (((fs_iterator *)self)->entry.path == NULL);
+}
+
+static int fs_iterator__advance_into(
+	const git_index_entry **entry, git_iterator *iter)
+{
+	int error = 0;
+	fs_iterator *fi = (fs_iterator *)iter;
+
+	iterator__clear_entry(entry);
+
+	/* Allow you to explicitly advance into a commit/submodule (as well as a
+	 * tree) to avoid cases where an entry is mislabeled as a submodule in
+	 * the working directory.  The fs iterator will never have COMMMIT
+	 * entries on it's own, but a wrapper might add them.
+	 */
+	if (fi->entry.path != NULL &&
+		(fi->entry.mode == GIT_FILEMODE_TREE ||
+		 fi->entry.mode == GIT_FILEMODE_COMMIT))
+		/* returns GIT_ENOTFOUND if the directory is empty */
+		error = fs_iterator__expand_dir(fi);
+
+	if (!error && entry)
+		error = fs_iterator__current(entry, iter);
+
+	if (!error && !fi->entry.path)
+		error = GIT_ITEROVER;
+
+	return error;
+}
+
+static int fs_iterator__advance_over(
+	const git_index_entry **entry, git_iterator *self)
+{
+	int error = 0;
+	fs_iterator *fi = (fs_iterator *)self;
+	fs_iterator_frame *ff;
+	fs_iterator_path_with_stat *next;
+
+	if (entry != NULL)
+		*entry = NULL;
+
+	while (fi->entry.path != NULL) {
+		ff   = fi->stack;
+		next = git_vector_get(&ff->entries, ++ff->index);
+
+		if (next != NULL)
+			break;
+
+		fs_iterator__pop_frame(fi, ff, false);
+	}
+
+	error = fs_iterator__update_entry(fi);
+
+	if (!error && entry != NULL)
+		error = fs_iterator__current(entry, self);
+
+	return error;
+}
+
+static int fs_iterator__advance(
+	const git_index_entry **entry, git_iterator *self)
+{
+	fs_iterator *fi = (fs_iterator *)self;
+
+	if (!iterator__has_been_accessed(fi))
+		return fs_iterator__current(entry, self);
+
+	/* given include_trees & autoexpand, we might have to go into a tree */
+	if (iterator__do_autoexpand(fi) &&
+		fi->entry.path != NULL &&
+		fi->entry.mode == GIT_FILEMODE_TREE)
+	{
+		int error = fs_iterator__advance_into(entry, self);
+		if (error != GIT_ENOTFOUND)
+			return error;
+		/* continue silently past empty directories if autoexpanding */
+		giterr_clear();
+	}
+
+	return fs_iterator__advance_over(entry, self);
+}
+
+static int fs_iterator__seek(git_iterator *self, const char *prefix)
+{
+	GIT_UNUSED(self);
+	GIT_UNUSED(prefix);
+	/* pop stack until matching prefix */
+	/* find prefix item in current frame */
+	/* push subdirectories as deep as possible while matching */
+	return 0;
+}
+
+static int fs_iterator__reset(
+	git_iterator *self, const char *start, const char *end)
+{
+	int error;
+	fs_iterator *fi = (fs_iterator *)self;
+
+	while (fi->stack != NULL && fi->stack->next != NULL)
+		fs_iterator__pop_frame(fi, fi->stack, false);
+	fi->depth = 0;
+
+	if ((error = iterator__reset_range(self, start, end)) < 0)
+		return error;
+
+	fs_iterator__seek_frame_start(fi, fi->stack);
+
+	error = fs_iterator__update_entry(fi);
+	if (error == GIT_ITEROVER)
+		error = 0;
+
+	return error;
+}
+
+static void fs_iterator__free(git_iterator *self)
+{
+	fs_iterator *fi = (fs_iterator *)self;
+
+	while (fi->stack != NULL)
+		fs_iterator__pop_frame(fi, fi->stack, true);
+
+	git_buf_free(&fi->path);
+}
+
+static int fs_iterator__update_entry(fs_iterator *fi)
+{
+	fs_iterator_path_with_stat *ps;
+
+	memset(&fi->entry, 0, sizeof(fi->entry));
+
+	if (!fi->stack)
+		return GIT_ITEROVER;
+
+	ps = git_vector_get(&fi->stack->entries, fi->stack->index);
+	if (!ps)
+		return GIT_ITEROVER;
+
+	git_buf_truncate(&fi->path, fi->root_len);
+	if (git_buf_put(&fi->path, ps->path, ps->path_len) < 0)
+		return -1;
+
+	if (iterator__past_end(fi, fi->path.ptr + fi->root_len))
+		return GIT_ITEROVER;
+
+	fi->entry.path = ps->path;
+	git_index_entry__init_from_stat(&fi->entry, &ps->st, true);
+
+	/* need different mode here to keep directories during iteration */
+	fi->entry.mode = git_futils_canonical_mode(ps->st.st_mode);
+
+	/* allow wrapper to check/update the entry (can force skip) */
+	if (fi->update_entry_cb &&
+		fi->update_entry_cb(fi) == GIT_ENOTFOUND)
+		return fs_iterator__advance_over(NULL, (git_iterator *)fi);
+
+	/* if this is a tree and trees aren't included, then skip */
+	if (fi->entry.mode == GIT_FILEMODE_TREE && !iterator__include_trees(fi)) {
+		int error = fs_iterator__advance_into(NULL, (git_iterator *)fi);
+		if (error != GIT_ENOTFOUND)
+			return error;
+		giterr_clear();
+		return fs_iterator__advance_over(NULL, (git_iterator *)fi);
+	}
+
+	return 0;
+}
+
+static int fs_iterator__initialize(
+	git_iterator **out, fs_iterator *fi, const char *root)
+{
+	int error;
+
+	if (git_buf_sets(&fi->path, root) < 0 || git_path_to_dir(&fi->path) < 0) {
+		git__free(fi);
+		return -1;
+	}
+	fi->root_len = fi->path.size;
+
+	fi->dirload_flags =
+		(iterator__ignore_case(fi) ? GIT_PATH_DIR_IGNORE_CASE : 0) |
+		(iterator__flag(fi, PRECOMPOSE_UNICODE) ?
+			GIT_PATH_DIR_PRECOMPOSE_UNICODE : 0);
+
+	if ((error = fs_iterator__expand_dir(fi)) < 0) {
+		if (error == GIT_ENOTFOUND || error == GIT_ITEROVER) {
+			giterr_clear();
+			error = 0;
+		} else {
+			git_iterator_free((git_iterator *)fi);
+			fi = NULL;
+		}
+	}
+
+	*out = (git_iterator *)fi;
+	return error;
+}
+
+int git_iterator_for_filesystem(
+	git_iterator **out,
+	const char *root,
+	git_iterator_flag_t flags,
+	const char *start,
+	const char *end)
+{
+	fs_iterator *fi = git__calloc(1, sizeof(fs_iterator));
+	GITERR_CHECK_ALLOC(fi);
+
+	ITERATOR_BASE_INIT(fi, fs, FS, NULL);
+
+	if ((flags & GIT_ITERATOR_IGNORE_CASE) != 0)
+		fi->base.flags |= GIT_ITERATOR_IGNORE_CASE;
+
+	return fs_iterator__initialize(out, fi, root);
+}
+
+
+typedef struct {
+	fs_iterator fi;
+	git_ignores ignores;
+	int is_ignored;
+
+	/*
+	 * We may have a tree or the index+snapshot to compare against
+	 * when checking for submodules.
+	 */
+	git_tree *tree;
+	git_index *index;
+	git_vector index_snapshot;
+	git_vector_cmp entry_srch;
+
+} workdir_iterator;
+
+GIT_INLINE(bool) workdir_path_is_dotgit(const git_buf *path)
+{
+	size_t len;
+
+	if (!path || (len = path->size) < 4)
+		return false;
+
+	if (path->ptr[len - 1] == '/')
+		len--;
+
+	if (git__tolower(path->ptr[len - 1]) != 't' ||
+		git__tolower(path->ptr[len - 2]) != 'i' ||
+		git__tolower(path->ptr[len - 3]) != 'g' ||
+		git__tolower(path->ptr[len - 4]) != '.')
+		return false;
+
+	return (len == 4 || path->ptr[len - 5] == '/');
+}
+
+/**
+ * Figure out if an entry is a submodule.
+ *
+ * We consider it a submodule if the path is listed as a submodule in
+ * either the tree or the index.
+ */
+static int is_submodule(workdir_iterator *wi, fs_iterator_path_with_stat *ie)
+{
+	int error, is_submodule = 0;
+
+	if (wi->tree) {
+		git_tree_entry *e;
+
+		/* remove the trailing slash for finding */
+		ie->path[ie->path_len-1] = '\0';
+		error = git_tree_entry_bypath(&e, wi->tree, ie->path);
+		ie->path[ie->path_len-1] = '/';
+		if (error < 0 && error != GIT_ENOTFOUND)
+			return 0;
+		if (!error) {
+			is_submodule = e->attr == GIT_FILEMODE_COMMIT;
+			git_tree_entry_free(e);
+		}
+	}
+
+	if (!is_submodule && wi->index) {
+		git_index_entry *e;
+		size_t pos;
+
+		error = git_index_snapshot_find(&pos, &wi->index_snapshot, wi->entry_srch, ie->path, ie->path_len-1, 0);
+		if (error < 0 && error != GIT_ENOTFOUND)
+			return 0;
+
+		if (!error) {
+			e = git_vector_get(&wi->index_snapshot, pos);
+
+			is_submodule = e->mode == GIT_FILEMODE_COMMIT;
+		}
+	}
+
+	return is_submodule;
+}
+
+GIT_INLINE(git_dir_flag) git_entry__dir_flag(git_index_entry *entry) {
+#if defined(GIT_WIN32) && !defined(__MINGW32__)
+	return (entry && entry->mode)
+		? S_ISDIR(entry->mode) ? GIT_DIR_FLAG_TRUE : GIT_DIR_FLAG_FALSE
+		: GIT_DIR_FLAG_UNKNOWN;
+#else
+	GIT_UNUSED(entry);
+	return GIT_DIR_FLAG_UNKNOWN;
+#endif
+}
+
+static int workdir_iterator__enter_dir(fs_iterator *fi)
+{
+	workdir_iterator *wi = (workdir_iterator *)fi;
+	fs_iterator_frame *ff = fi->stack;
+	size_t pos;
+	fs_iterator_path_with_stat *entry;
+	bool found_submodules = false;
+
+	git_dir_flag dir_flag = git_entry__dir_flag(&fi->entry);
+
+	/* check if this directory is ignored */
+	if (git_ignore__lookup(&ff->is_ignored, &wi->ignores, fi->path.ptr + fi->root_len, dir_flag) < 0) {
+		giterr_clear();
+		ff->is_ignored = GIT_IGNORE_NOTFOUND;
+	}
+
+	/* if this is not the top level directory... */
+	if (ff->next != NULL) {
+		ssize_t slash_pos = git_buf_rfind_next(&fi->path, '/');
+
+		/* inherit ignored from parent if no rule specified */
+		if (ff->is_ignored <= GIT_IGNORE_NOTFOUND)
+			ff->is_ignored = ff->next->is_ignored;
+
+		/* push new ignores for files in this directory */
+		(void)git_ignore__push_dir(&wi->ignores, &fi->path.ptr[slash_pos + 1]);
+	}
+
+	/* convert submodules to GITLINK and remove trailing slashes */
+	git_vector_foreach(&ff->entries, pos, entry) {
+		if (!S_ISDIR(entry->st.st_mode) || !strcmp(GIT_DIR, entry->path))
+			continue;
+
+		if (is_submodule(wi, entry)) {
+			entry->st.st_mode = GIT_FILEMODE_COMMIT;
+			entry->path_len--;
+			entry->path[entry->path_len] = '\0';
+			found_submodules = true;
+		}
+	}
+
+	/* if we renamed submodules, re-sort and re-seek to start */
+	if (found_submodules) {
+		git_vector_set_sorted(&ff->entries, 0);
+		git_vector_sort(&ff->entries);
+		fs_iterator__seek_frame_start(fi, ff);
+	}
+
+	return 0;
+}
+
+static int workdir_iterator__leave_dir(fs_iterator *fi)
+{
+	workdir_iterator *wi = (workdir_iterator *)fi;
+	git_ignore__pop_dir(&wi->ignores);
+	return 0;
+}
+
+static int workdir_iterator__update_entry(fs_iterator *fi)
+{
+	workdir_iterator *wi = (workdir_iterator *)fi;
+
+	/* skip over .git entries */
+	if (workdir_path_is_dotgit(&fi->path))
+		return GIT_ENOTFOUND;
+
+	/* reset is_ignored since we haven't checked yet */
+	wi->is_ignored = GIT_IGNORE_UNCHECKED;
+
+	return 0;
+}
+
+static void workdir_iterator__free(git_iterator *self)
+{
+	workdir_iterator *wi = (workdir_iterator *)self;
+	if (wi->index)
+		git_index_snapshot_release(&wi->index_snapshot, wi->index);
+	git_tree_free(wi->tree);
+	fs_iterator__free(self);
+	git_ignore__free(&wi->ignores);
+}
+
+int git_iterator_for_workdir_ext(
+	git_iterator **out,
+	git_repository *repo,
+	const char *repo_workdir,
+	git_index *index,
+	git_tree *tree,
+	git_iterator_flag_t flags,
+	const char *start,
+	const char *end)
+{
+	int error, precompose = 0;
+	workdir_iterator *wi;
+
+	if (!repo_workdir) {
+		if (git_repository__ensure_not_bare(repo, "scan working directory") < 0)
+			return GIT_EBAREREPO;
+		repo_workdir = git_repository_workdir(repo);
+	}
+
+	/* initialize as an fs iterator then do overrides */
+	wi = git__calloc(1, sizeof(workdir_iterator));
+	GITERR_CHECK_ALLOC(wi);
+	ITERATOR_BASE_INIT((&wi->fi), fs, FS, repo);
+
+	wi->fi.base.type = GIT_ITERATOR_TYPE_WORKDIR;
+	wi->fi.cb.free = workdir_iterator__free;
+	wi->fi.enter_dir_cb = workdir_iterator__enter_dir;
+	wi->fi.leave_dir_cb = workdir_iterator__leave_dir;
+	wi->fi.update_entry_cb = workdir_iterator__update_entry;
+
+	if ((error = iterator__update_ignore_case((git_iterator *)wi, flags)) < 0 ||
+		(error = git_ignore__for_path(repo, ".gitignore", &wi->ignores)) < 0)
+	{
+		git_iterator_free((git_iterator *)wi);
+		return error;
+	}
+
+	if (tree && (error = git_object_dup((git_object **)&wi->tree, (git_object *)tree)) < 0)
+		return error;
+
+	wi->index = index;
+	if (index && (error = git_index_snapshot_new(&wi->index_snapshot, index)) < 0) {
+		git_iterator_free((git_iterator *)wi);
+		return error;
+	}
+	wi->entry_srch = iterator__ignore_case(wi) ?
+		git_index_entry_isrch : git_index_entry_srch;
+
+
+	/* try to look up precompose and set flag if appropriate */
+	if (git_repository__cvar(&precompose, repo, GIT_CVAR_PRECOMPOSE) < 0)
+		giterr_clear();
+	else if (precompose)
+		wi->fi.base.flags |= GIT_ITERATOR_PRECOMPOSE_UNICODE;
+
+	return fs_iterator__initialize(out, &wi->fi, repo_workdir);
+}
+
+void git_iterator_free(git_iterator *iter)
+{
+	if (iter == NULL)
+		return;
+
+	iter->cb->free(iter);
+
+	git__free(iter->start);
+	git__free(iter->end);
+
+	memset(iter, 0, sizeof(*iter));
+
+	git__free(iter);
+}
+
+int git_iterator_set_ignore_case(git_iterator *iter, bool ignore_case)
+{
+	bool desire_ignore_case  = (ignore_case != 0);
+
+	if (iterator__ignore_case(iter) == desire_ignore_case)
+		return 0;
+
+	if (iter->type == GIT_ITERATOR_TYPE_EMPTY) {
+		if (desire_ignore_case)
+			iter->flags |= GIT_ITERATOR_IGNORE_CASE;
+		else
+			iter->flags &= ~GIT_ITERATOR_IGNORE_CASE;
+	} else {
+		giterr_set(GITERR_INVALID,
+			"Cannot currently set ignore case on non-empty iterators");
+		return -1;
+	}
+
+	return 0;
+}
+
+git_index *git_iterator_get_index(git_iterator *iter)
+{
+	if (iter->type == GIT_ITERATOR_TYPE_INDEX)
+		return ((index_iterator *)iter)->index;
+	return NULL;
+}
+
+int git_iterator_current_tree_entry(
+	const git_tree_entry **tree_entry, git_iterator *iter)
+{
+	if (iter->type != GIT_ITERATOR_TYPE_TREE)
+		*tree_entry = NULL;
+	else {
+		tree_iterator_frame *tf = ((tree_iterator *)iter)->head;
+		*tree_entry = (tf->current < tf->n_entries) ?
+			tf->entries[tf->current]->te : NULL;
+	}
+
+	return 0;
+}
+
+int git_iterator_current_parent_tree(
+	const git_tree **tree_ptr,
+	git_iterator *iter,
+	const char *parent_path)
+{
+	tree_iterator *ti = (tree_iterator *)iter;
+	tree_iterator_frame *tf;
+	const char *scan = parent_path;
+	const git_tree_entry *te;
+
+	*tree_ptr = NULL;
+
+	if (iter->type != GIT_ITERATOR_TYPE_TREE)
+		return 0;
+
+	for (tf = ti->root; *scan; ) {
+		if (!(tf = tf->down) ||
+			tf->current >= tf->n_entries ||
+			!(te = tf->entries[tf->current]->te) ||
+			ti->strncomp(scan, te->filename, te->filename_len) != 0)
+			return 0;
+
+		scan += te->filename_len;
+		if (*scan == '/')
+			scan++;
+	}
+
+	*tree_ptr = tf->entries[tf->current]->tree;
+	return 0;
+}
+
+static void workdir_iterator_update_is_ignored(workdir_iterator *wi)
+{
+	git_dir_flag dir_flag = git_entry__dir_flag(&wi->fi.entry);
+
+	if (git_ignore__lookup(&wi->is_ignored, &wi->ignores, wi->fi.entry.path, dir_flag) < 0) {
+		giterr_clear();
+		wi->is_ignored = GIT_IGNORE_NOTFOUND;
+	}
+
+	/* use ignore from containing frame stack */
+	if (wi->is_ignored <= GIT_IGNORE_NOTFOUND)
+		wi->is_ignored = wi->fi.stack->is_ignored;
+}
+
+bool git_iterator_current_is_ignored(git_iterator *iter)
+{
+	workdir_iterator *wi = (workdir_iterator *)iter;
+
+	if (iter->type != GIT_ITERATOR_TYPE_WORKDIR)
+		return false;
+
+	if (wi->is_ignored != GIT_IGNORE_UNCHECKED)
+		return (bool)(wi->is_ignored == GIT_IGNORE_TRUE);
+
+	workdir_iterator_update_is_ignored(wi);
+
+	return (bool)(wi->is_ignored == GIT_IGNORE_TRUE);
+}
+
+bool git_iterator_current_tree_is_ignored(git_iterator *iter)
+{
+	workdir_iterator *wi = (workdir_iterator *)iter;
+
+	if (iter->type != GIT_ITERATOR_TYPE_WORKDIR)
+		return false;
+
+	return (bool)(wi->fi.stack->is_ignored == GIT_IGNORE_TRUE);
+}
+
+int git_iterator_cmp(git_iterator *iter, const char *path_prefix)
+{
+	const git_index_entry *entry;
+
+	/* a "done" iterator is after every prefix */
+	if (git_iterator_current(&entry, iter) < 0 || entry == NULL)
+		return 1;
+
+	/* a NULL prefix is after any valid iterator */
+	if (!path_prefix)
+		return -1;
+
+	return iter->prefixcomp(entry->path, path_prefix);
+}
+
+int git_iterator_current_workdir_path(git_buf **path, git_iterator *iter)
+{
+	workdir_iterator *wi = (workdir_iterator *)iter;
+
+	if (iter->type != GIT_ITERATOR_TYPE_WORKDIR || !wi->fi.entry.path)
+		*path = NULL;
+	else
+		*path = &wi->fi.path;
+
+	return 0;
+}
+
+int git_iterator_index(git_index **out, git_iterator *iter)
+{
+	workdir_iterator *wi = (workdir_iterator *)iter;
+
+	if (iter->type != GIT_ITERATOR_TYPE_WORKDIR)
+		*out = NULL;
+
+	*out = wi->index;
+
+	return 0;
+}
+
+int git_iterator_advance_over_with_status(
+	const git_index_entry **entryptr,
+	git_iterator_status_t *status,
+	git_iterator *iter)
+{
+	int error = 0;
+	workdir_iterator *wi = (workdir_iterator *)iter;
+	char *base = NULL;
+	const git_index_entry *entry;
+
+	*status = GIT_ITERATOR_STATUS_NORMAL;
+
+	if (iter->type != GIT_ITERATOR_TYPE_WORKDIR)
+		return git_iterator_advance(entryptr, iter);
+	if ((error = git_iterator_current(&entry, iter)) < 0)
+		return error;
+
+	if (!S_ISDIR(entry->mode)) {
+		workdir_iterator_update_is_ignored(wi);
+		if (wi->is_ignored == GIT_IGNORE_TRUE)
+			*status = GIT_ITERATOR_STATUS_IGNORED;
+		return git_iterator_advance(entryptr, iter);
+	}
+
+	*status = GIT_ITERATOR_STATUS_EMPTY;
+
+	base = git__strdup(entry->path);
+	GITERR_CHECK_ALLOC(base);
+
+	/* scan inside directory looking for a non-ignored item */
+	while (entry && !iter->prefixcomp(entry->path, base)) {
+		workdir_iterator_update_is_ignored(wi);
+
+		/* if we found an explicitly ignored item, then update from
+		 * EMPTY to IGNORED
+		 */
+		if (wi->is_ignored == GIT_IGNORE_TRUE)
+			*status = GIT_ITERATOR_STATUS_IGNORED;
+		else if (S_ISDIR(entry->mode)) {
+			error = git_iterator_advance_into(&entry, iter);
+
+			if (!error)
+				continue;
+			else if (error == GIT_ENOTFOUND) {
+				error = 0;
+				wi->is_ignored = GIT_IGNORE_TRUE; /* mark empty dirs ignored */
+			} else
+				break; /* real error, stop here */
+		} else {
+			/* we found a non-ignored item, treat parent as untracked */
+			*status = GIT_ITERATOR_STATUS_NORMAL;
+			break;
+		}
+
+		if ((error = git_iterator_advance(&entry, iter)) < 0)
+			break;
+	}
+
+	/* wrap up scan back to base directory */
+	while (entry && !iter->prefixcomp(entry->path, base))
+		if ((error = git_iterator_advance(&entry, iter)) < 0)
+			break;
+
+	*entryptr = entry;
+	git__free(base);
+
+	return error;
+}
+
+int git_iterator_walk(
+	git_iterator **iterators,
+	size_t cnt,
+	git_iterator_walk_cb cb,
+	void *data)
+{
+	const git_index_entry **iterator_item;	/* next in each iterator */
+	const git_index_entry **cur_items;		/* current path in each iter */
+	const git_index_entry *first_match;
+	size_t i, j;
+	int error = 0;
+
+	iterator_item = git__calloc(cnt, sizeof(git_index_entry *));
+	cur_items = git__calloc(cnt, sizeof(git_index_entry *));
+
+	GITERR_CHECK_ALLOC(iterator_item);
+	GITERR_CHECK_ALLOC(cur_items);
+
+	/* Set up the iterators */
+	for (i = 0; i < cnt; i++) {
+		error = git_iterator_current(&iterator_item[i], iterators[i]);
+
+		if (error < 0 && error != GIT_ITEROVER)
+			goto done;
+	}
+
+	while (true) {
+		for (i = 0; i < cnt; i++)
+			cur_items[i] = NULL;
+
+		first_match = NULL;
+
+		/* Find the next path(s) to consume from each iterator */
+		for (i = 0; i < cnt; i++) {
+			if (iterator_item[i] == NULL)
+				continue;
+
+			if (first_match == NULL) {
+				first_match = iterator_item[i];
+				cur_items[i] = iterator_item[i];
+			} else {
+				int path_diff = git_index_entry_cmp(iterator_item[i], first_match);
+
+				if (path_diff < 0) {
+					/* Found an index entry that sorts before the one we're
+					 * looking at.  Forget that we've seen the other and
+					 * look at the other iterators for this path.
+					 */
+					for (j = 0; j < i; j++)
+						cur_items[j] = NULL;
+
+					first_match = iterator_item[i];
+					cur_items[i] = iterator_item[i];
+				} else if (path_diff == 0) {
+					cur_items[i] = iterator_item[i];
+				}
+			}
+		}
+
+		if (first_match == NULL)
+			break;
+
+		if ((error = cb(cur_items, data)) != 0)
+			goto done;
+
+		/* Advance each iterator that participated */
+		for (i = 0; i < cnt; i++) {
+			if (cur_items[i] == NULL)
+				continue;
+
+			error = git_iterator_advance(&iterator_item[i], iterators[i]);
+
+			if (error < 0 && error != GIT_ITEROVER)
+				goto done;
+		}
+	}
+
+done:
+	git__free((git_index_entry **)iterator_item);
+	git__free((git_index_entry **)cur_items);
+
+	if (error == GIT_ITEROVER)
+		error = 0;
+
+	return error;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/iterator.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/iterator.h
new file mode 100755
index 0000000..893e5db
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/iterator.h
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_iterator_h__
+#define INCLUDE_iterator_h__
+
+#include "common.h"
+#include "git2/index.h"
+#include "vector.h"
+#include "buffer.h"
+#include "ignore.h"
+
+typedef struct git_iterator git_iterator;
+
+typedef enum {
+	GIT_ITERATOR_TYPE_EMPTY = 0,
+	GIT_ITERATOR_TYPE_TREE = 1,
+	GIT_ITERATOR_TYPE_INDEX = 2,
+	GIT_ITERATOR_TYPE_WORKDIR = 3,
+	GIT_ITERATOR_TYPE_FS = 4,
+} git_iterator_type_t;
+
+typedef enum {
+	/** ignore case for entry sort order */
+	GIT_ITERATOR_IGNORE_CASE = (1u << 0),
+	/** force case sensitivity for entry sort order */
+	GIT_ITERATOR_DONT_IGNORE_CASE = (1u << 1),
+	/** return tree items in addition to blob items */
+	GIT_ITERATOR_INCLUDE_TREES    = (1u << 2),
+	/** don't flatten trees, requiring advance_into (implies INCLUDE_TREES) */
+	GIT_ITERATOR_DONT_AUTOEXPAND  = (1u << 3),
+	/** convert precomposed unicode to decomposed unicode */
+	GIT_ITERATOR_PRECOMPOSE_UNICODE = (1u << 4),
+	/** include conflicts */
+	GIT_ITERATOR_INCLUDE_CONFLICTS = (1u << 5),
+} git_iterator_flag_t;
+
+typedef struct {
+	int (*current)(const git_index_entry **, git_iterator *);
+	int (*advance)(const git_index_entry **, git_iterator *);
+	int (*advance_into)(const git_index_entry **, git_iterator *);
+	int (*seek)(git_iterator *, const char *prefix);
+	int (*reset)(git_iterator *, const char *start, const char *end);
+	int (*at_end)(git_iterator *);
+	void (*free)(git_iterator *);
+} git_iterator_callbacks;
+
+struct git_iterator {
+	git_iterator_type_t type;
+	git_iterator_callbacks *cb;
+	git_repository *repo;
+	char *start;
+	char *end;
+	int (*prefixcomp)(const char *str, const char *prefix);
+	size_t stat_calls;
+	unsigned int flags;
+};
+
+extern int git_iterator_for_nothing(
+	git_iterator **out,
+	git_iterator_flag_t flags,
+	const char *start,
+	const char *end);
+
+/* tree iterators will match the ignore_case value from the index of the
+ * repository, unless you override with a non-zero flag value
+ */
+extern int git_iterator_for_tree(
+	git_iterator **out,
+	git_tree *tree,
+	git_iterator_flag_t flags,
+	const char *start,
+	const char *end);
+
+/* index iterators will take the ignore_case value from the index; the
+ * ignore_case flags are not used
+ */
+extern int git_iterator_for_index(
+	git_iterator **out,
+	git_index *index,
+	git_iterator_flag_t flags,
+	const char *start,
+	const char *end);
+
+extern int git_iterator_for_workdir_ext(
+	git_iterator **out,
+	git_repository *repo,
+	const char *repo_workdir,
+	git_index *index,
+	git_tree *tree,
+	git_iterator_flag_t flags,
+	const char *start,
+	const char *end);
+
+/* workdir iterators will match the ignore_case value from the index of the
+ * repository, unless you override with a non-zero flag value
+ */
+GIT_INLINE(int) git_iterator_for_workdir(
+	git_iterator **out,
+	git_repository *repo,
+	git_index *index,
+	git_tree *tree,
+	git_iterator_flag_t flags,
+	const char *start,
+	const char *end)
+{
+	return git_iterator_for_workdir_ext(out, repo, NULL, index, tree, flags, start, end);
+}
+
+/* for filesystem iterators, you have to explicitly pass in the ignore_case
+ * behavior that you desire
+ */
+extern int git_iterator_for_filesystem(
+	git_iterator **out,
+	const char *root,
+	git_iterator_flag_t flags,
+	const char *start,
+	const char *end);
+
+extern void git_iterator_free(git_iterator *iter);
+
+/* Return a git_index_entry structure for the current value the iterator
+ * is looking at or NULL if the iterator is at the end.
+ *
+ * The entry may noy be fully populated.  Tree iterators will only have a
+ * value mode, OID, and path.  Workdir iterators will not have an OID (but
+ * you can use `git_iterator_current_oid()` to calculate it on demand).
+ *
+ * You do not need to free the entry.  It is still "owned" by the iterator.
+ * Once you call `git_iterator_advance()` then the old entry is no longer
+ * guaranteed to be valid - it may be freed or just overwritten in place.
+ */
+GIT_INLINE(int) git_iterator_current(
+	const git_index_entry **entry, git_iterator *iter)
+{
+	return iter->cb->current(entry, iter);
+}
+
+/**
+ * Advance to the next item for the iterator.
+ *
+ * If GIT_ITERATOR_INCLUDE_TREES is set, this may be a tree item.  If
+ * GIT_ITERATOR_DONT_AUTOEXPAND is set, calling this again when on a tree
+ * item will skip over all the items under that tree.
+ */
+GIT_INLINE(int) git_iterator_advance(
+	const git_index_entry **entry, git_iterator *iter)
+{
+	return iter->cb->advance(entry, iter);
+}
+
+/**
+ * Iterate into a tree item (when GIT_ITERATOR_DONT_AUTOEXPAND is set).
+ *
+ * git_iterator_advance() steps through all items being iterated over
+ * (either with or without trees, depending on GIT_ITERATOR_INCLUDE_TREES),
+ * but if GIT_ITERATOR_DONT_AUTOEXPAND is set, it will skip to the next
+ * sibling of a tree instead of going to the first child of the tree.  In
+ * that case, use this function to advance to the first child of the tree.
+ *
+ * If the current item is not a tree, this is a no-op.
+ *
+ * For filesystem and working directory iterators, a tree (i.e. directory)
+ * can be empty.  In that case, this function returns GIT_ENOTFOUND and
+ * does not advance.  That can't happen for tree and index iterators.
+ */
+GIT_INLINE(int) git_iterator_advance_into(
+	const git_index_entry **entry, git_iterator *iter)
+{
+	return iter->cb->advance_into(entry, iter);
+}
+
+/**
+ * Advance into a tree or skip over it if it is empty.
+ *
+ * Because `git_iterator_advance_into` may return GIT_ENOTFOUND if the
+ * directory is empty (only with filesystem and working directory
+ * iterators) and a common response is to just call `git_iterator_advance`
+ * when that happens, this bundles the two into a single simple call.
+ */
+GIT_INLINE(int) git_iterator_advance_into_or_over(
+	const git_index_entry **entry, git_iterator *iter)
+{
+	int error = iter->cb->advance_into(entry, iter);
+	if (error == GIT_ENOTFOUND) {
+		giterr_clear();
+		error = iter->cb->advance(entry, iter);
+	}
+	return error;
+}
+
+/* Seek is currently unimplemented */
+GIT_INLINE(int) git_iterator_seek(
+	git_iterator *iter, const char *prefix)
+{
+	return iter->cb->seek(iter, prefix);
+}
+
+/**
+ * Go back to the start of the iteration.
+ *
+ * This resets the iterator to the start of the iteration.  It also allows
+ * you to reset the `start` and `end` pathname boundaries of the iteration
+ * when doing so.
+ */
+GIT_INLINE(int) git_iterator_reset(
+	git_iterator *iter, const char *start, const char *end)
+{
+	return iter->cb->reset(iter, start, end);
+}
+
+/**
+ * Check if the iterator is at the end
+ *
+ * @return 0 if not at end, >0 if at end
+ */
+GIT_INLINE(int) git_iterator_at_end(git_iterator *iter)
+{
+	return iter->cb->at_end(iter);
+}
+
+GIT_INLINE(git_iterator_type_t) git_iterator_type(git_iterator *iter)
+{
+	return iter->type;
+}
+
+GIT_INLINE(git_repository *) git_iterator_owner(git_iterator *iter)
+{
+	return iter->repo;
+}
+
+GIT_INLINE(git_iterator_flag_t) git_iterator_flags(git_iterator *iter)
+{
+	return iter->flags;
+}
+
+GIT_INLINE(bool) git_iterator_ignore_case(git_iterator *iter)
+{
+	return ((iter->flags & GIT_ITERATOR_IGNORE_CASE) != 0);
+}
+
+extern int git_iterator_set_ignore_case(git_iterator *iter, bool ignore_case);
+
+extern int git_iterator_current_tree_entry(
+	const git_tree_entry **entry_out, git_iterator *iter);
+
+extern int git_iterator_current_parent_tree(
+	const git_tree **tree_out, git_iterator *iter, const char *parent_path);
+
+extern bool git_iterator_current_is_ignored(git_iterator *iter);
+
+extern bool git_iterator_current_tree_is_ignored(git_iterator *iter);
+
+extern int git_iterator_cmp(
+	git_iterator *iter, const char *path_prefix);
+
+/**
+ * Get full path of the current item from a workdir iterator.  This will
+ * return NULL for a non-workdir iterator.  The git_buf is still owned by
+ * the iterator; this is exposed just for efficiency.
+ */
+extern int git_iterator_current_workdir_path(
+	git_buf **path, git_iterator *iter);
+
+/* Return index pointer if index iterator, else NULL */
+extern git_index *git_iterator_get_index(git_iterator *iter);
+
+typedef enum {
+	GIT_ITERATOR_STATUS_NORMAL = 0,
+	GIT_ITERATOR_STATUS_IGNORED = 1,
+	GIT_ITERATOR_STATUS_EMPTY = 2
+} git_iterator_status_t;
+
+/* Advance over a directory and check if it contains no files or just
+ * ignored files.
+ *
+ * In a tree or the index, all directories will contain files, but in the
+ * working directory it is possible to have an empty directory tree or a
+ * tree that only contains ignored files.  Many Git operations treat these
+ * cases specially.  This advances over a directory (presumably an
+ * untracked directory) but checks during the scan if there are any files
+ * and any non-ignored files.
+ */
+extern int git_iterator_advance_over_with_status(
+	const git_index_entry **entry, git_iterator_status_t *status, git_iterator *iter);
+
+/**
+ * Retrieve the index stored in the iterator.
+ *
+ * Only implemented for the workdir iterator
+ */
+extern int git_iterator_index(git_index **out, git_iterator *iter);
+
+typedef int (*git_iterator_walk_cb)(
+	const git_index_entry **entries,
+	void *data);
+
+/**
+ * Walk the given iterators in lock-step.  The given callback will be
+ * called for each unique path, with the index entry in each iterator
+ * (or NULL if the given iterator does not contain that path).
+ */
+extern int git_iterator_walk(
+	git_iterator **iterators,
+	size_t cnt,
+	git_iterator_walk_cb cb,
+	void *data);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/khash.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/khash.h
new file mode 100755
index 0000000..71eb583
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/khash.h
@@ -0,0 +1,622 @@
+/* The MIT License
+
+   Copyright (c) 2008, 2009, 2011 by Attractive Chaos <attractor at live.co.uk>
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   "Software"), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be
+   included in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+   SOFTWARE.
+*/
+
+/*
+  An example:
+
+#include "khash.h"
+KHASH_MAP_INIT_INT(32, char)
+int main() {
+	int ret, is_missing;
+	khiter_t k;
+	khash_t(32) *h = kh_init(32);
+	k = kh_put(32, h, 5, &ret);
+	kh_value(h, k) = 10;
+	k = kh_get(32, h, 10);
+	is_missing = (k == kh_end(h));
+	k = kh_get(32, h, 5);
+	kh_del(32, h, k);
+	for (k = kh_begin(h); k != kh_end(h); ++k)
+		if (kh_exist(h, k)) kh_value(h, k) = 1;
+	kh_destroy(32, h);
+	return 0;
+}
+*/
+
+/*
+  2013-05-02 (0.2.8):
+
+	* Use quadratic probing. When the capacity is power of 2, stepping function
+	  i*(i+1)/2 guarantees to traverse each bucket. It is better than double
+	  hashing on cache performance and is more robust than linear probing.
+
+	  In theory, double hashing should be more robust than quadratic probing.
+	  However, my implementation is probably not for large hash tables, because
+	  the second hash function is closely tied to the first hash function,
+	  which reduce the effectiveness of double hashing.
+
+	Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php
+
+  2011-12-29 (0.2.7):
+
+    * Minor code clean up; no actual effect.
+
+  2011-09-16 (0.2.6):
+
+	* The capacity is a power of 2. This seems to dramatically improve the
+	  speed for simple keys. Thank Zilong Tan for the suggestion. Reference:
+
+	   - http://code.google.com/p/ulib/
+	   - http://nothings.org/computer/judy/
+
+	* Allow to optionally use linear probing which usually has better
+	  performance for random input. Double hashing is still the default as it
+	  is more robust to certain non-random input.
+
+	* Added Wang's integer hash function (not used by default). This hash
+	  function is more robust to certain non-random input.
+
+  2011-02-14 (0.2.5):
+
+    * Allow to declare global functions.
+
+  2009-09-26 (0.2.4):
+
+    * Improve portability
+
+  2008-09-19 (0.2.3):
+
+	* Corrected the example
+	* Improved interfaces
+
+  2008-09-11 (0.2.2):
+
+	* Improved speed a little in kh_put()
+
+  2008-09-10 (0.2.1):
+
+	* Added kh_clear()
+	* Fixed a compiling error
+
+  2008-09-02 (0.2.0):
+
+	* Changed to token concatenation which increases flexibility.
+
+  2008-08-31 (0.1.2):
+
+	* Fixed a bug in kh_get(), which has not been tested previously.
+
+  2008-08-31 (0.1.1):
+
+	* Added destructor
+*/
+
+
+#ifndef __AC_KHASH_H
+#define __AC_KHASH_H
+
+/*!
+  @header
+
+  Generic hash table library.
+ */
+
+#define AC_VERSION_KHASH_H "0.2.8"
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+/* compiler specific configuration */
+
+#if UINT_MAX == 0xffffffffu
+typedef unsigned int khint32_t;
+#elif ULONG_MAX == 0xffffffffu
+typedef unsigned long khint32_t;
+#endif
+
+#if ULONG_MAX == ULLONG_MAX
+typedef unsigned long khint64_t;
+#else
+typedef unsigned long long khint64_t;
+#endif
+
+#ifndef kh_inline
+#ifdef _MSC_VER
+#define kh_inline __inline
+#else
+#define kh_inline inline
+#endif
+#endif /* kh_inline */
+
+typedef khint32_t khint_t;
+typedef khint_t khiter_t;
+
+#define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2)
+#define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1)
+#define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3)
+#define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1)))
+#define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1)))
+#define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1)))
+#define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1))
+
+#define __ac_fsize(m) ((m) < 16? 1 : (m)>>4)
+
+#ifndef kroundup32
+#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
+#endif
+
+#ifndef kcalloc
+#define kcalloc(N,Z) calloc(N,Z)
+#endif
+#ifndef kmalloc
+#define kmalloc(Z) malloc(Z)
+#endif
+#ifndef krealloc
+#define krealloc(P,Z) realloc(P,Z)
+#endif
+#ifndef kreallocarray
+#define kreallocarray(P,N,Z) ((SIZE_MAX - N < Z) ? NULL : krealloc(P, (N*Z)))
+#endif
+#ifndef kfree
+#define kfree(P) free(P)
+#endif
+
+static const double __ac_HASH_UPPER = 0.77;
+
+#define __KHASH_TYPE(name, khkey_t, khval_t) \
+	typedef struct kh_##name##_s { \
+		khint_t n_buckets, size, n_occupied, upper_bound; \
+		khint32_t *flags; \
+		khkey_t *keys; \
+		khval_t *vals; \
+	} kh_##name##_t;
+
+#define __KHASH_PROTOTYPES(name, khkey_t, khval_t)	 					\
+	extern kh_##name##_t *kh_init_##name(void);							\
+	extern void kh_destroy_##name(kh_##name##_t *h);					\
+	extern void kh_clear_##name(kh_##name##_t *h);						\
+	extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); 	\
+	extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \
+	extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \
+	extern void kh_del_##name(kh_##name##_t *h, khint_t x);
+
+#define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
+	SCOPE kh_##name##_t *kh_init_##name(void) {							\
+		return (kh_##name##_t*)kcalloc(1, sizeof(kh_##name##_t));		\
+	}																	\
+	SCOPE void kh_destroy_##name(kh_##name##_t *h)						\
+	{																	\
+		if (h) {														\
+			kfree((void *)h->keys); kfree(h->flags);					\
+			kfree((void *)h->vals);										\
+			kfree(h);													\
+		}																\
+	}																	\
+	SCOPE void kh_clear_##name(kh_##name##_t *h)						\
+	{																	\
+		if (h && h->flags) {											\
+			memset(h->flags, 0xaa, __ac_fsize(h->n_buckets) * sizeof(khint32_t)); \
+			h->size = h->n_occupied = 0;								\
+		}																\
+	}																	\
+	SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) 	\
+	{																	\
+		if (h->n_buckets) {												\
+			khint_t k, i, last, mask, step = 0; \
+			mask = h->n_buckets - 1;									\
+			k = __hash_func(key); i = k & mask;							\
+			last = i; \
+			while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
+				i = (i + (++step)) & mask; \
+				if (i == last) return h->n_buckets;						\
+			}															\
+			return __ac_iseither(h->flags, i)? h->n_buckets : i;		\
+		} else return 0;												\
+	}																	\
+	SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
+	{ /* This function uses 0.25*n_buckets bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \
+		khint32_t *new_flags = 0;										\
+		khint_t j = 1;													\
+		{																\
+			kroundup32(new_n_buckets); 									\
+			if (new_n_buckets < 4) new_n_buckets = 4;					\
+			if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0;	/* requested size is too small */ \
+			else { /* hash table size to be changed (shrink or expand); rehash */ \
+				new_flags = (khint32_t*)kreallocarray(NULL, __ac_fsize(new_n_buckets), sizeof(khint32_t)); \
+				if (!new_flags) return -1;								\
+				memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
+				if (h->n_buckets < new_n_buckets) {	/* expand */		\
+					khkey_t *new_keys = (khkey_t*)kreallocarray((void *)h->keys, new_n_buckets, sizeof(khkey_t)); \
+					if (!new_keys) { kfree(new_flags); return -1; }		\
+					h->keys = new_keys;									\
+					if (kh_is_map) {									\
+						khval_t *new_vals = (khval_t*)kreallocarray((void *)h->vals, new_n_buckets, sizeof(khval_t)); \
+						if (!new_vals) { kfree(new_flags); return -1; }	\
+						h->vals = new_vals;								\
+					}													\
+				} /* otherwise shrink */								\
+			}															\
+		}																\
+		if (j) { /* rehashing is needed */								\
+			for (j = 0; j != h->n_buckets; ++j) {						\
+				if (__ac_iseither(h->flags, j) == 0) {					\
+					khkey_t key = h->keys[j];							\
+					khval_t val;										\
+					khint_t new_mask;									\
+					new_mask = new_n_buckets - 1; 						\
+					if (kh_is_map) val = h->vals[j];					\
+					__ac_set_isdel_true(h->flags, j);					\
+					while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \
+						khint_t k, i, step = 0; \
+						k = __hash_func(key);							\
+						i = k & new_mask;								\
+						while (!__ac_isempty(new_flags, i)) i = (i + (++step)) & new_mask; \
+						__ac_set_isempty_false(new_flags, i);			\
+						if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { /* kick out the existing element */ \
+							{ khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \
+							if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \
+							__ac_set_isdel_true(h->flags, i); /* mark it as deleted in the old hash table */ \
+						} else { /* write the element and jump out of the loop */ \
+							h->keys[i] = key;							\
+							if (kh_is_map) h->vals[i] = val;			\
+							break;										\
+						}												\
+					}													\
+				}														\
+			}															\
+			if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \
+				h->keys = (khkey_t*)kreallocarray((void *)h->keys, new_n_buckets, sizeof(khkey_t)); \
+				if (kh_is_map) h->vals = (khval_t*)kreallocarray((void *)h->vals, new_n_buckets, sizeof(khval_t)); \
+			}															\
+			kfree(h->flags); /* free the working space */				\
+			h->flags = new_flags;										\
+			h->n_buckets = new_n_buckets;								\
+			h->n_occupied = h->size;									\
+			h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \
+		}																\
+		return 0;														\
+	}																	\
+	SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \
+	{																	\
+		khint_t x;														\
+		if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \
+			if (h->n_buckets > (h->size<<1)) {							\
+				if (kh_resize_##name(h, h->n_buckets - 1) < 0) { /* clear "deleted" elements */ \
+					*ret = -1; return h->n_buckets;						\
+				}														\
+			} else if (kh_resize_##name(h, h->n_buckets + 1) < 0) { /* expand the hash table */ \
+				*ret = -1; return h->n_buckets;							\
+			}															\
+		} /* TODO: to implement automatically shrinking; resize() already support shrinking */ \
+		{																\
+			khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \
+			x = site = h->n_buckets; k = __hash_func(key); i = k & mask; \
+			if (__ac_isempty(h->flags, i)) x = i; /* for speed up */	\
+			else {														\
+				last = i; \
+				while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
+					if (__ac_isdel(h->flags, i)) site = i;				\
+					i = (i + (++step)) & mask; \
+					if (i == last) { x = site; break; }					\
+				}														\
+				if (x == h->n_buckets) {								\
+					if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \
+					else x = i;											\
+				}														\
+			}															\
+		}																\
+		if (__ac_isempty(h->flags, x)) { /* not present at all */		\
+			h->keys[x] = key;											\
+			__ac_set_isboth_false(h->flags, x);							\
+			++h->size; ++h->n_occupied;									\
+			*ret = 1;													\
+		} else if (__ac_isdel(h->flags, x)) { /* deleted */				\
+			h->keys[x] = key;											\
+			__ac_set_isboth_false(h->flags, x);							\
+			++h->size;													\
+			*ret = 2;													\
+		} else *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \
+		return x;														\
+	}																	\
+	SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x)				\
+	{																	\
+		if (x != h->n_buckets && !__ac_iseither(h->flags, x)) {			\
+			__ac_set_isdel_true(h->flags, x);							\
+			--h->size;													\
+		}																\
+	}
+
+#define KHASH_DECLARE(name, khkey_t, khval_t)		 					\
+	__KHASH_TYPE(name, khkey_t, khval_t) 								\
+	__KHASH_PROTOTYPES(name, khkey_t, khval_t)
+
+#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
+	__KHASH_TYPE(name, khkey_t, khval_t) 								\
+	__KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
+
+#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
+	KHASH_INIT2(name, static kh_inline, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
+
+/* --- BEGIN OF HASH FUNCTIONS --- */
+
+/*! @function
+  @abstract     Integer hash function
+  @param  key   The integer [khint32_t]
+  @return       The hash value [khint_t]
+ */
+#define kh_int_hash_func(key) (khint32_t)(key)
+/*! @function
+  @abstract     Integer comparison function
+ */
+#define kh_int_hash_equal(a, b) ((a) == (b))
+/*! @function
+  @abstract     64-bit integer hash function
+  @param  key   The integer [khint64_t]
+  @return       The hash value [khint_t]
+ */
+#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11)
+/*! @function
+  @abstract     64-bit integer comparison function
+ */
+#define kh_int64_hash_equal(a, b) ((a) == (b))
+/*! @function
+  @abstract     const char* hash function
+  @param  s     Pointer to a null terminated string
+  @return       The hash value
+ */
+static kh_inline khint_t __ac_X31_hash_string(const char *s)
+{
+	khint_t h = (khint_t)*s;
+	if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)*s;
+	return h;
+}
+/*! @function
+  @abstract     Another interface to const char* hash function
+  @param  key   Pointer to a null terminated string [const char*]
+  @return       The hash value [khint_t]
+ */
+#define kh_str_hash_func(key) __ac_X31_hash_string(key)
+/*! @function
+  @abstract     Const char* comparison function
+ */
+#define kh_str_hash_equal(a, b) (strcmp(a, b) == 0)
+
+static kh_inline khint_t __ac_Wang_hash(khint_t key)
+{
+    key += ~(key << 15);
+    key ^=  (key >> 10);
+    key +=  (key << 3);
+    key ^=  (key >> 6);
+    key += ~(key << 11);
+    key ^=  (key >> 16);
+    return key;
+}
+#define kh_int_hash_func2(k) __ac_Wang_hash((khint_t)key)
+
+/* --- END OF HASH FUNCTIONS --- */
+
+/* Other convenient macros... */
+
+/*!
+  @abstract Type of the hash table.
+  @param  name  Name of the hash table [symbol]
+ */
+#define khash_t(name) kh_##name##_t
+
+/*! @function
+  @abstract     Initiate a hash table.
+  @param  name  Name of the hash table [symbol]
+  @return       Pointer to the hash table [khash_t(name)*]
+ */
+#define kh_init(name) kh_init_##name()
+
+/*! @function
+  @abstract     Destroy a hash table.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+ */
+#define kh_destroy(name, h) kh_destroy_##name(h)
+
+/*! @function
+  @abstract     Reset a hash table without deallocating memory.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+ */
+#define kh_clear(name, h) kh_clear_##name(h)
+
+/*! @function
+  @abstract     Resize a hash table.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  s     New size [khint_t]
+ */
+#define kh_resize(name, h, s) kh_resize_##name(h, s)
+
+/*! @function
+  @abstract     Insert a key to the hash table.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  k     Key [type of keys]
+  @param  r     Extra return code: -1 if the operation failed;
+                0 if the key is present in the hash table;
+                1 if the bucket is empty (never used); 2 if the element in
+				the bucket has been deleted [int*]
+  @return       Iterator to the inserted element [khint_t]
+ */
+#define kh_put(name, h, k, r) kh_put_##name(h, k, r)
+
+/*! @function
+  @abstract     Retrieve a key from the hash table.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  k     Key [type of keys]
+  @return       Iterator to the found element, or kh_end(h) if the element is absent [khint_t]
+ */
+#define kh_get(name, h, k) kh_get_##name(h, k)
+
+/*! @function
+  @abstract     Remove a key from the hash table.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  k     Iterator to the element to be deleted [khint_t]
+ */
+#define kh_del(name, h, k) kh_del_##name(h, k)
+
+/*! @function
+  @abstract     Test whether a bucket contains data.
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  x     Iterator to the bucket [khint_t]
+  @return       1 if containing data; 0 otherwise [int]
+ */
+#define kh_exist(h, x) (!__ac_iseither((h)->flags, (x)))
+
+/*! @function
+  @abstract     Get key given an iterator
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  x     Iterator to the bucket [khint_t]
+  @return       Key [type of keys]
+ */
+#define kh_key(h, x) ((h)->keys[x])
+
+/*! @function
+  @abstract     Get value given an iterator
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  x     Iterator to the bucket [khint_t]
+  @return       Value [type of values]
+  @discussion   For hash sets, calling this results in segfault.
+ */
+#define kh_val(h, x) ((h)->vals[x])
+
+/*! @function
+  @abstract     Alias of kh_val()
+ */
+#define kh_value(h, x) ((h)->vals[x])
+
+/*! @function
+  @abstract     Get the start iterator
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @return       The start iterator [khint_t]
+ */
+#define kh_begin(h) (khint_t)(0)
+
+/*! @function
+  @abstract     Get the end iterator
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @return       The end iterator [khint_t]
+ */
+#define kh_end(h) ((h)->n_buckets)
+
+/*! @function
+  @abstract     Get the number of elements in the hash table
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @return       Number of elements in the hash table [khint_t]
+ */
+#define kh_size(h) ((h)->size)
+
+/*! @function
+  @abstract     Get the number of buckets in the hash table
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @return       Number of buckets in the hash table [khint_t]
+ */
+#define kh_n_buckets(h) ((h)->n_buckets)
+
+/*! @function
+  @abstract     Iterate over the entries in the hash table
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  kvar  Variable to which key will be assigned
+  @param  vvar  Variable to which value will be assigned
+  @param  code  Block of code to execute
+ */
+#define kh_foreach(h, kvar, vvar, code) { khint_t __i;		\
+	for (__i = kh_begin(h); __i != kh_end(h); ++__i) {		\
+		if (!kh_exist(h,__i)) continue;						\
+		(kvar) = kh_key(h,__i);								\
+		(vvar) = kh_val(h,__i);								\
+		code;												\
+	} }
+
+/*! @function
+  @abstract     Iterate over the values in the hash table
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  vvar  Variable to which value will be assigned
+  @param  code  Block of code to execute
+ */
+#define kh_foreach_value(h, vvar, code) { khint_t __i;		\
+	for (__i = kh_begin(h); __i != kh_end(h); ++__i) {		\
+		if (!kh_exist(h,__i)) continue;						\
+		(vvar) = kh_val(h,__i);								\
+		code;												\
+	} }
+
+/* More conenient interfaces */
+
+/*! @function
+  @abstract     Instantiate a hash set containing integer keys
+  @param  name  Name of the hash table [symbol]
+ */
+#define KHASH_SET_INIT_INT(name)										\
+	KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal)
+
+/*! @function
+  @abstract     Instantiate a hash map containing integer keys
+  @param  name  Name of the hash table [symbol]
+  @param  khval_t  Type of values [type]
+ */
+#define KHASH_MAP_INIT_INT(name, khval_t)								\
+	KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal)
+
+/*! @function
+  @abstract     Instantiate a hash map containing 64-bit integer keys
+  @param  name  Name of the hash table [symbol]
+ */
+#define KHASH_SET_INIT_INT64(name)										\
+	KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal)
+
+/*! @function
+  @abstract     Instantiate a hash map containing 64-bit integer keys
+  @param  name  Name of the hash table [symbol]
+  @param  khval_t  Type of values [type]
+ */
+#define KHASH_MAP_INIT_INT64(name, khval_t)								\
+	KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal)
+
+typedef const char *kh_cstr_t;
+/*! @function
+  @abstract     Instantiate a hash map containing const char* keys
+  @param  name  Name of the hash table [symbol]
+ */
+#define KHASH_SET_INIT_STR(name)										\
+	KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal)
+
+/*! @function
+  @abstract     Instantiate a hash map containing const char* keys
+  @param  name  Name of the hash table [symbol]
+  @param  khval_t  Type of values [type]
+ */
+#define KHASH_MAP_INIT_STR(name, khval_t)								\
+	KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal)
+
+#endif /* __AC_KHASH_H */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/map.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/map.h
new file mode 100755
index 0000000..da3d1e1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/map.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_map_h__
+#define INCLUDE_map_h__
+
+#include "common.h"
+
+
+/* p_mmap() prot values */
+#define GIT_PROT_NONE 0x0
+#define GIT_PROT_READ 0x1
+#define GIT_PROT_WRITE 0x2
+#define GIT_PROT_EXEC 0x4
+
+/* git__mmmap() flags values */
+#define GIT_MAP_FILE	0
+#define GIT_MAP_SHARED 1
+#define GIT_MAP_PRIVATE 2
+#define GIT_MAP_TYPE	0xf
+#define GIT_MAP_FIXED	0x10
+
+#ifdef __amigaos4__
+#define MAP_FAILED 0
+#endif
+
+typedef struct { /* memory mapped buffer	*/
+	void *data; /* data bytes			*/
+	size_t len; /* data length			*/
+#ifdef GIT_WIN32
+	HANDLE fmh; /* file mapping handle */
+#endif
+} git_map;
+
+#define GIT_MMAP_VALIDATE(out, len, prot, flags) do { \
+	assert(out != NULL && len > 0); \
+	assert((prot & GIT_PROT_WRITE) || (prot & GIT_PROT_READ)); \
+	assert((flags & GIT_MAP_FIXED) == 0); } while (0)
+
+extern int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset);
+extern int p_munmap(git_map *map);
+
+#endif /* INCLUDE_map_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/merge.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/merge.c
new file mode 100755
index 0000000..13b524b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/merge.c
@@ -0,0 +1,2696 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "posix.h"
+#include "buffer.h"
+#include "repository.h"
+#include "revwalk.h"
+#include "commit_list.h"
+#include "merge.h"
+#include "path.h"
+#include "refs.h"
+#include "object.h"
+#include "iterator.h"
+#include "refs.h"
+#include "diff.h"
+#include "checkout.h"
+#include "tree.h"
+#include "blob.h"
+#include "oid.h"
+#include "index.h"
+#include "filebuf.h"
+#include "config.h"
+#include "oidarray.h"
+#include "annotated_commit.h"
+
+#include "git2/types.h"
+#include "git2/repository.h"
+#include "git2/object.h"
+#include "git2/commit.h"
+#include "git2/merge.h"
+#include "git2/refs.h"
+#include "git2/reset.h"
+#include "git2/checkout.h"
+#include "git2/signature.h"
+#include "git2/config.h"
+#include "git2/tree.h"
+#include "git2/oidarray.h"
+#include "git2/annotated_commit.h"
+#include "git2/sys/index.h"
+#include "git2/sys/hashsig.h"
+
+#define GIT_MERGE_INDEX_ENTRY_EXISTS(X)	((X).mode != 0)
+#define GIT_MERGE_INDEX_ENTRY_ISFILE(X) S_ISREG((X).mode)
+
+typedef enum {
+	TREE_IDX_ANCESTOR = 0,
+	TREE_IDX_OURS = 1,
+	TREE_IDX_THEIRS = 2
+} merge_tree_index_t;
+
+/* Tracks D/F conflicts */
+struct merge_diff_df_data {
+	const char *df_path;
+	const char *prev_path;
+	git_merge_diff *prev_conflict;
+};
+
+/* Merge base computation */
+
+int merge_bases_many(git_commit_list **out, git_revwalk **walk_out, git_repository *repo, size_t length, const git_oid input_array[])
+{
+	git_revwalk *walk = NULL;
+	git_vector list;
+	git_commit_list *result = NULL;
+	git_commit_list_node *commit;
+	int error = -1;
+	unsigned int i;
+
+	if (length < 2) {
+		giterr_set(GITERR_INVALID, "At least two commits are required to find an ancestor. Provided 'length' was %" PRIuZ ".", length);
+		return -1;
+	}
+
+	if (git_vector_init(&list, length - 1, NULL) < 0)
+		return -1;
+
+	if (git_revwalk_new(&walk, repo) < 0)
+		goto on_error;
+
+	for (i = 1; i < length; i++) {
+		commit = git_revwalk__commit_lookup(walk, &input_array[i]);
+		if (commit == NULL)
+			goto on_error;
+
+		git_vector_insert(&list, commit);
+	}
+
+	commit = git_revwalk__commit_lookup(walk, &input_array[0]);
+	if (commit == NULL)
+		goto on_error;
+
+	if (git_merge__bases_many(&result, walk, commit, &list) < 0)
+		goto on_error;
+
+	if (!result) {
+		giterr_set(GITERR_MERGE, "No merge base found");
+		error = GIT_ENOTFOUND;
+		goto on_error;
+	}
+
+	*out = result;
+	*walk_out = walk;
+
+	git_vector_free(&list);
+	return 0;
+
+on_error:
+	git_vector_free(&list);
+	git_revwalk_free(walk);
+	return error;
+}
+
+int git_merge_base_many(git_oid *out, git_repository *repo, size_t length, const git_oid input_array[])
+{
+	git_revwalk *walk;
+	git_commit_list *result = NULL;
+	int error = 0;
+
+	assert(out && repo && input_array);
+
+	if ((error = merge_bases_many(&result, &walk, repo, length, input_array)) < 0)
+		return error;
+
+	git_oid_cpy(out, &result->item->oid);
+
+	git_commit_list_free(&result);
+	git_revwalk_free(walk);
+
+	return 0;
+}
+
+int git_merge_bases_many(git_oidarray *out, git_repository *repo, size_t length, const git_oid input_array[])
+{
+	git_revwalk *walk;
+	git_commit_list *list, *result = NULL;
+	int error = 0;
+	git_array_oid_t array;
+
+	assert(out && repo && input_array);
+
+	if ((error = merge_bases_many(&result, &walk, repo, length, input_array)) < 0)
+		return error;
+
+	git_array_init(array);
+
+	list = result;
+	while (list) {
+		git_oid *id = git_array_alloc(array);
+		if (id == NULL) {
+			error = -1;
+			goto cleanup;
+		}
+
+		git_oid_cpy(id, &list->item->oid);
+		list = list->next;
+	}
+
+	git_oidarray__from_array(out, &array);
+
+cleanup:
+	git_commit_list_free(&result);
+	git_revwalk_free(walk);
+
+	return error;
+}
+
+int git_merge_base_octopus(git_oid *out, git_repository *repo, size_t length, const git_oid input_array[])
+{
+	git_oid result;
+	unsigned int i;
+	int error = -1;
+
+	assert(out && repo && input_array);
+
+	if (length < 2) {
+		giterr_set(GITERR_INVALID, "At least two commits are required to find an ancestor. Provided 'length' was %" PRIuZ ".", length);
+		return -1;
+	}
+
+	result = input_array[0];
+	for (i = 1; i < length; i++) {
+		error = git_merge_base(&result, repo, &result, &input_array[i]);
+		if (error < 0)
+			return error;
+	}
+
+	*out = result;
+
+	return 0;
+}
+
+static int merge_bases(git_commit_list **out, git_revwalk **walk_out, git_repository *repo, const git_oid *one, const git_oid *two)
+{
+	git_revwalk *walk;
+	git_vector list;
+	git_commit_list *result = NULL;
+	git_commit_list_node *commit;
+	void *contents[1];
+
+	if (git_revwalk_new(&walk, repo) < 0)
+		return -1;
+
+	commit = git_revwalk__commit_lookup(walk, two);
+	if (commit == NULL)
+		goto on_error;
+
+	/* This is just one value, so we can do it on the stack */
+	memset(&list, 0x0, sizeof(git_vector));
+	contents[0] = commit;
+	list.length = 1;
+	list.contents = contents;
+
+	commit = git_revwalk__commit_lookup(walk, one);
+	if (commit == NULL)
+		goto on_error;
+
+	if (git_merge__bases_many(&result, walk, commit, &list) < 0)
+		goto on_error;
+
+	if (!result) {
+		git_revwalk_free(walk);
+		giterr_set(GITERR_MERGE, "No merge base found");
+		return GIT_ENOTFOUND;
+	}
+
+	*out = result;
+	*walk_out = walk;
+
+	return 0;
+
+on_error:
+	git_revwalk_free(walk);
+	return -1;
+
+}
+
+int git_merge_base(git_oid *out, git_repository *repo, const git_oid *one, const git_oid *two)
+{
+	int error;
+	git_revwalk *walk;
+	git_commit_list *result;
+
+	if ((error = merge_bases(&result, &walk, repo, one, two)) < 0)
+		return error;
+
+	git_oid_cpy(out, &result->item->oid);
+	git_commit_list_free(&result);
+	git_revwalk_free(walk);
+
+	return 0;
+}
+
+int git_merge_bases(git_oidarray *out, git_repository *repo, const git_oid *one, const git_oid *two)
+{
+	int error;
+        git_revwalk *walk;
+	git_commit_list *result, *list;
+	git_array_oid_t array;
+
+	git_array_init(array);
+
+	if ((error = merge_bases(&result, &walk, repo, one, two)) < 0)
+		return error;
+
+	list = result;
+	while (list) {
+		git_oid *id = git_array_alloc(array);
+		if (id == NULL)
+			goto on_error;
+
+		git_oid_cpy(id, &list->item->oid);
+		list = list->next;
+	}
+
+	git_oidarray__from_array(out, &array);
+	git_commit_list_free(&result);
+	git_revwalk_free(walk);
+
+	return 0;
+
+on_error:
+	git_commit_list_free(&result);
+	git_revwalk_free(walk);
+	return -1;
+}
+
+static int interesting(git_pqueue *list)
+{
+	size_t i;
+
+	for (i = 0; i < git_pqueue_size(list); i++) {
+		git_commit_list_node *commit = git_pqueue_get(list, i);
+		if ((commit->flags & STALE) == 0)
+			return 1;
+	}
+
+	return 0;
+}
+
+int git_merge__bases_many(git_commit_list **out, git_revwalk *walk, git_commit_list_node *one, git_vector *twos)
+{
+	int error;
+	unsigned int i;
+	git_commit_list_node *two;
+	git_commit_list *result = NULL, *tmp = NULL;
+	git_pqueue list;
+
+	/* If there's only the one commit, there can be no merge bases */
+	if (twos->length == 0) {
+		*out = NULL;
+		return 0;
+	}
+
+	/* if the commit is repeated, we have a our merge base already */
+	git_vector_foreach(twos, i, two) {
+		if (one == two)
+			return git_commit_list_insert(one, out) ? 0 : -1;
+	}
+
+	if (git_pqueue_init(&list, 0, twos->length * 2, git_commit_list_time_cmp) < 0)
+		return -1;
+
+	if (git_commit_list_parse(walk, one) < 0)
+		return -1;
+
+	one->flags |= PARENT1;
+	if (git_pqueue_insert(&list, one) < 0)
+		return -1;
+
+	git_vector_foreach(twos, i, two) {
+		if (git_commit_list_parse(walk, two) < 0)
+			return -1;
+
+		two->flags |= PARENT2;
+
+		if (git_pqueue_insert(&list, two) < 0)
+			return -1;
+	}
+
+	/* as long as there are non-STALE commits */
+	while (interesting(&list)) {
+		git_commit_list_node *commit = git_pqueue_pop(&list);
+		int flags;
+
+		if (commit == NULL)
+			break;
+
+		flags = commit->flags & (PARENT1 | PARENT2 | STALE);
+		if (flags == (PARENT1 | PARENT2)) {
+			if (!(commit->flags & RESULT)) {
+				commit->flags |= RESULT;
+				if (git_commit_list_insert(commit, &result) == NULL)
+					return -1;
+			}
+			/* we mark the parents of a merge stale */
+			flags |= STALE;
+		}
+
+		for (i = 0; i < commit->out_degree; i++) {
+			git_commit_list_node *p = commit->parents[i];
+			if ((p->flags & flags) == flags)
+				continue;
+
+			if ((error = git_commit_list_parse(walk, p)) < 0)
+				return error;
+
+			p->flags |= flags;
+			if (git_pqueue_insert(&list, p) < 0)
+				return -1;
+		}
+	}
+
+	git_pqueue_free(&list);
+
+	/* filter out any stale commits in the results */
+	tmp = result;
+	result = NULL;
+
+	while (tmp) {
+		struct git_commit_list *next = tmp->next;
+		if (!(tmp->item->flags & STALE))
+			if (git_commit_list_insert_by_date(tmp->item, &result) == NULL)
+				return -1;
+
+		git__free(tmp);
+		tmp = next;
+	}
+
+	*out = result;
+	return 0;
+}
+
+int git_repository_mergehead_foreach(
+	git_repository *repo,
+	git_repository_mergehead_foreach_cb cb,
+	void *payload)
+{
+	git_buf merge_head_path = GIT_BUF_INIT, merge_head_file = GIT_BUF_INIT;
+	char *buffer, *line;
+	size_t line_num = 1;
+	git_oid oid;
+	int error = 0;
+
+	assert(repo && cb);
+
+	if ((error = git_buf_joinpath(&merge_head_path, repo->path_repository,
+		GIT_MERGE_HEAD_FILE)) < 0)
+		return error;
+
+	if ((error = git_futils_readbuffer(&merge_head_file,
+		git_buf_cstr(&merge_head_path))) < 0)
+		goto cleanup;
+
+	buffer = merge_head_file.ptr;
+
+	while ((line = git__strsep(&buffer, "\n")) != NULL) {
+		if (strlen(line) != GIT_OID_HEXSZ) {
+			giterr_set(GITERR_INVALID, "Unable to parse OID - invalid length");
+			error = -1;
+			goto cleanup;
+		}
+
+		if ((error = git_oid_fromstr(&oid, line)) < 0)
+			goto cleanup;
+
+		if ((error = cb(&oid, payload)) != 0) {
+			giterr_set_after_callback(error);
+			goto cleanup;
+		}
+
+		++line_num;
+	}
+
+	if (*buffer) {
+		giterr_set(GITERR_MERGE, "No EOL at line %d", line_num);
+		error = -1;
+		goto cleanup;
+	}
+
+cleanup:
+	git_buf_free(&merge_head_path);
+	git_buf_free(&merge_head_file);
+
+	return error;
+}
+
+GIT_INLINE(int) index_entry_cmp(const git_index_entry *a, const git_index_entry *b)
+{
+	int value = 0;
+
+	if (a->path == NULL)
+		return (b->path == NULL) ? 0 : 1;
+
+	if ((value = a->mode - b->mode) == 0 &&
+		(value = git_oid__cmp(&a->id, &b->id)) == 0)
+		value = strcmp(a->path, b->path);
+
+	return value;
+}
+
+/* Conflict resolution */
+
+static int merge_conflict_resolve_trivial(
+	int *resolved,
+	git_merge_diff_list *diff_list,
+	const git_merge_diff *conflict)
+{
+	int ours_empty, theirs_empty;
+	int ours_changed, theirs_changed, ours_theirs_differ;
+	git_index_entry const *result = NULL;
+	int error = 0;
+
+	assert(resolved && diff_list && conflict);
+
+	*resolved = 0;
+
+	if (conflict->type == GIT_MERGE_DIFF_DIRECTORY_FILE ||
+		conflict->type == GIT_MERGE_DIFF_RENAMED_ADDED)
+		return 0;
+
+	if (conflict->our_status == GIT_DELTA_RENAMED ||
+		conflict->their_status == GIT_DELTA_RENAMED)
+		return 0;
+
+	ours_empty = !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry);
+	theirs_empty = !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry);
+
+	ours_changed = (conflict->our_status != GIT_DELTA_UNMODIFIED);
+	theirs_changed = (conflict->their_status != GIT_DELTA_UNMODIFIED);
+	ours_theirs_differ = ours_changed && theirs_changed &&
+		index_entry_cmp(&conflict->our_entry, &conflict->their_entry);
+
+	/*
+	 * Note: with only one ancestor, some cases are not distinct:
+	 *
+	 * 16: ancest:anc1/anc2, head:anc1, remote:anc2 = result:no merge
+	 * 3: ancest:(empty)^, head:head, remote:(empty) = result:no merge
+	 * 2: ancest:(empty)^, head:(empty), remote:remote = result:no merge
+	 *
+	 * Note that the two cases that take D/F conflicts into account
+	 * specifically do not need to be explicitly tested, as D/F conflicts
+	 * would fail the *empty* test:
+	 *
+	 * 3ALT: ancest:(empty)+, head:head, remote:*empty* = result:head
+	 * 2ALT: ancest:(empty)+, head:*empty*, remote:remote = result:remote
+	 *
+	 * Note that many of these cases need not be explicitly tested, as
+	 * they simply degrade to "all different" cases (eg, 11):
+	 *
+	 * 4: ancest:(empty)^, head:head, remote:remote = result:no merge
+	 * 7: ancest:ancest+, head:(empty), remote:remote = result:no merge
+	 * 9: ancest:ancest+, head:head, remote:(empty) = result:no merge
+	 * 11: ancest:ancest+, head:head, remote:remote = result:no merge
+	 */
+
+	/* 5ALT: ancest:*, head:head, remote:head = result:head */
+	if (ours_changed && !ours_empty && !ours_theirs_differ)
+		result = &conflict->our_entry;
+	/* 6: ancest:ancest+, head:(empty), remote:(empty) = result:no merge */
+	else if (ours_changed && ours_empty && theirs_empty)
+		*resolved = 0;
+	/* 8: ancest:ancest^, head:(empty), remote:ancest = result:no merge */
+	else if (ours_empty && !theirs_changed)
+		*resolved = 0;
+	/* 10: ancest:ancest^, head:ancest, remote:(empty) = result:no merge */
+	else if (!ours_changed && theirs_empty)
+		*resolved = 0;
+	/* 13: ancest:ancest+, head:head, remote:ancest = result:head */
+	else if (ours_changed && !theirs_changed)
+		result = &conflict->our_entry;
+	/* 14: ancest:ancest+, head:ancest, remote:remote = result:remote */
+	else if (!ours_changed && theirs_changed)
+		result = &conflict->their_entry;
+	else
+		*resolved = 0;
+
+	if (result != NULL &&
+		GIT_MERGE_INDEX_ENTRY_EXISTS(*result) &&
+		(error = git_vector_insert(&diff_list->staged, (void *)result)) >= 0)
+		*resolved = 1;
+
+	/* Note: trivial resolution does not update the REUC. */
+
+	return error;
+}
+
+static int merge_conflict_resolve_one_removed(
+	int *resolved,
+	git_merge_diff_list *diff_list,
+	const git_merge_diff *conflict)
+{
+	int ours_empty, theirs_empty;
+	int ours_changed, theirs_changed;
+	int error = 0;
+
+	assert(resolved && diff_list && conflict);
+
+	*resolved = 0;
+
+	if (conflict->type == GIT_MERGE_DIFF_DIRECTORY_FILE ||
+		conflict->type == GIT_MERGE_DIFF_RENAMED_ADDED)
+		return 0;
+
+	ours_empty = !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry);
+	theirs_empty = !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry);
+
+	ours_changed = (conflict->our_status != GIT_DELTA_UNMODIFIED);
+	theirs_changed = (conflict->their_status != GIT_DELTA_UNMODIFIED);
+
+	/* Removed in both */
+	if (ours_changed && ours_empty && theirs_empty)
+		*resolved = 1;
+	/* Removed in ours */
+	else if (ours_empty && !theirs_changed)
+		*resolved = 1;
+	/* Removed in theirs */
+	else if (!ours_changed && theirs_empty)
+		*resolved = 1;
+
+	if (*resolved)
+		git_vector_insert(&diff_list->resolved, (git_merge_diff *)conflict);
+
+	return error;
+}
+
+static int merge_conflict_resolve_one_renamed(
+	int *resolved,
+	git_merge_diff_list *diff_list,
+	const git_merge_diff *conflict)
+{
+	int ours_renamed, theirs_renamed;
+	int ours_changed, theirs_changed;
+	git_index_entry *merged;
+	int error = 0;
+
+	assert(resolved && diff_list && conflict);
+
+	*resolved = 0;
+
+	if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ||
+		!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry))
+		return 0;
+
+	ours_renamed = (conflict->our_status == GIT_DELTA_RENAMED);
+	theirs_renamed = (conflict->their_status == GIT_DELTA_RENAMED);
+
+	if (!ours_renamed && !theirs_renamed)
+		return 0;
+
+	/* Reject one file in a 2->1 conflict */
+	if (conflict->type == GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1 ||
+		conflict->type == GIT_MERGE_DIFF_BOTH_RENAMED_1_TO_2 ||
+		conflict->type == GIT_MERGE_DIFF_RENAMED_ADDED)
+		return 0;
+
+	ours_changed = (git_oid__cmp(&conflict->ancestor_entry.id, &conflict->our_entry.id) != 0);
+	theirs_changed = (git_oid__cmp(&conflict->ancestor_entry.id, &conflict->their_entry.id) != 0);
+
+	/* if both are modified (and not to a common target) require a merge */
+	if (ours_changed && theirs_changed &&
+		git_oid__cmp(&conflict->our_entry.id, &conflict->their_entry.id) != 0)
+		return 0;
+
+	if ((merged = git_pool_malloc(&diff_list->pool, sizeof(git_index_entry))) == NULL)
+		return -1;
+
+	if (ours_changed)
+		memcpy(merged, &conflict->our_entry, sizeof(git_index_entry));
+	else
+		memcpy(merged, &conflict->their_entry, sizeof(git_index_entry));
+
+	if (ours_renamed)
+		merged->path = conflict->our_entry.path;
+	else
+		merged->path = conflict->their_entry.path;
+
+	*resolved = 1;
+
+	git_vector_insert(&diff_list->staged, merged);
+	git_vector_insert(&diff_list->resolved, (git_merge_diff *)conflict);
+
+	return error;
+}
+
+static int merge_conflict_resolve_automerge(
+	int *resolved,
+	git_merge_diff_list *diff_list,
+	const git_merge_diff *conflict,
+	unsigned int merge_file_favor,
+	unsigned int file_flags)
+{
+	const git_index_entry *ancestor = NULL, *ours = NULL, *theirs = NULL;
+	git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
+	git_merge_file_result result = {0};
+	git_index_entry *index_entry;
+	git_odb *odb = NULL;
+	git_oid automerge_oid;
+	int error = 0;
+
+	assert(resolved && diff_list && conflict);
+
+	*resolved = 0;
+
+	if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ||
+		!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry))
+		return 0;
+
+	/* Reject D/F conflicts */
+	if (conflict->type == GIT_MERGE_DIFF_DIRECTORY_FILE)
+		return 0;
+
+	/* Reject submodules. */
+	if (S_ISGITLINK(conflict->ancestor_entry.mode) ||
+		S_ISGITLINK(conflict->our_entry.mode) ||
+		S_ISGITLINK(conflict->their_entry.mode))
+		return 0;
+
+	/* Reject link/file conflicts. */
+	if ((S_ISLNK(conflict->ancestor_entry.mode) ^ S_ISLNK(conflict->our_entry.mode)) ||
+		(S_ISLNK(conflict->ancestor_entry.mode) ^ S_ISLNK(conflict->their_entry.mode)))
+		return 0;
+
+	/* Reject name conflicts */
+	if (conflict->type == GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1 ||
+		conflict->type == GIT_MERGE_DIFF_RENAMED_ADDED)
+		return 0;
+
+	if ((conflict->our_status & GIT_DELTA_RENAMED) == GIT_DELTA_RENAMED &&
+		(conflict->their_status & GIT_DELTA_RENAMED) == GIT_DELTA_RENAMED &&
+		strcmp(conflict->ancestor_entry.path, conflict->their_entry.path) != 0)
+		return 0;
+
+	ancestor = GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry) ?
+		&conflict->ancestor_entry : NULL;
+	ours = GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
+		&conflict->our_entry : NULL;
+	theirs = GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
+		&conflict->their_entry : NULL;
+
+	opts.favor = merge_file_favor;
+	opts.flags = file_flags;
+
+	if ((error = git_repository_odb(&odb, diff_list->repo)) < 0 ||
+		(error = git_merge_file_from_index(&result, diff_list->repo, ancestor, ours, theirs, &opts)) < 0 ||
+		!result.automergeable ||
+		(error = git_odb_write(&automerge_oid, odb, result.ptr, result.len, GIT_OBJ_BLOB)) < 0)
+		goto done;
+
+	if ((index_entry = git_pool_malloc(&diff_list->pool, sizeof(git_index_entry))) == NULL)
+	GITERR_CHECK_ALLOC(index_entry);
+
+	index_entry->path = git_pool_strdup(&diff_list->pool, result.path);
+	GITERR_CHECK_ALLOC(index_entry->path);
+
+	index_entry->file_size = result.len;
+	index_entry->mode = result.mode;
+	git_oid_cpy(&index_entry->id, &automerge_oid);
+
+	git_vector_insert(&diff_list->staged, index_entry);
+	git_vector_insert(&diff_list->resolved, (git_merge_diff *)conflict);
+
+	*resolved = 1;
+
+done:
+	git_merge_file_result_free(&result);
+	git_odb_free(odb);
+
+	return error;
+}
+
+static int merge_conflict_resolve(
+	int *out,
+	git_merge_diff_list *diff_list,
+	const git_merge_diff *conflict,
+	unsigned int merge_file_favor,
+	unsigned int file_flags)
+{
+	int resolved = 0;
+	int error = 0;
+
+	*out = 0;
+
+	if ((error = merge_conflict_resolve_trivial(&resolved, diff_list, conflict)) < 0)
+		goto done;
+
+	if (!resolved && (error = merge_conflict_resolve_one_removed(&resolved, diff_list, conflict)) < 0)
+		goto done;
+
+	if (!resolved && (error = merge_conflict_resolve_one_renamed(&resolved, diff_list, conflict)) < 0)
+		goto done;
+
+	if (!resolved && (error = merge_conflict_resolve_automerge(&resolved, diff_list, conflict,
+		merge_file_favor, file_flags)) < 0)
+		goto done;
+
+	*out = resolved;
+
+done:
+	return error;
+}
+
+/* Rename detection and coalescing */
+
+struct merge_diff_similarity {
+	unsigned char similarity;
+	size_t other_idx;
+};
+
+static int index_entry_similarity_exact(
+	git_repository *repo,
+	git_index_entry *a,
+	size_t a_idx,
+	git_index_entry *b,
+	size_t b_idx,
+	void **cache,
+	const git_merge_options *opts)
+{
+	GIT_UNUSED(repo);
+	GIT_UNUSED(a_idx);
+	GIT_UNUSED(b_idx);
+	GIT_UNUSED(cache);
+	GIT_UNUSED(opts);
+
+	if (git_oid__cmp(&a->id, &b->id) == 0)
+		return 100;
+
+	return 0;
+}
+
+static int index_entry_similarity_calc(
+	void **out,
+	git_repository *repo,
+	git_index_entry *entry,
+	const git_merge_options *opts)
+{
+	git_blob *blob;
+	git_diff_file diff_file = {{{0}}};
+	git_off_t blobsize;
+	int error;
+
+	*out = NULL;
+
+	if ((error = git_blob_lookup(&blob, repo, &entry->id)) < 0)
+		return error;
+
+	git_oid_cpy(&diff_file.id, &entry->id);
+	diff_file.path = entry->path;
+	diff_file.size = entry->file_size;
+	diff_file.mode = entry->mode;
+	diff_file.flags = 0;
+
+	blobsize = git_blob_rawsize(blob);
+
+	/* file too big for rename processing */
+	if (!git__is_sizet(blobsize))
+		return 0;
+
+	error = opts->metric->buffer_signature(out, &diff_file,
+		git_blob_rawcontent(blob), (size_t)blobsize,
+		opts->metric->payload);
+
+	git_blob_free(blob);
+
+	return error;
+}
+
+static int index_entry_similarity_inexact(
+	git_repository *repo,
+	git_index_entry *a,
+	size_t a_idx,
+	git_index_entry *b,
+	size_t b_idx,
+	void **cache,
+	const git_merge_options *opts)
+{
+	int score = 0;
+	int error = 0;
+
+	if (GIT_MODE_TYPE(a->mode) != GIT_MODE_TYPE(b->mode))
+		return 0;
+
+	/* update signature cache if needed */
+	if (!cache[a_idx] && (error = index_entry_similarity_calc(&cache[a_idx], repo, a, opts)) < 0)
+		return error;
+	if (!cache[b_idx] && (error = index_entry_similarity_calc(&cache[b_idx], repo, b, opts)) < 0)
+		return error;
+
+	/* some metrics may not wish to process this file (too big / too small) */
+	if (!cache[a_idx] || !cache[b_idx])
+		return 0;
+
+	/* compare signatures */
+	if (opts->metric->similarity(
+		&score, cache[a_idx], cache[b_idx], opts->metric->payload) < 0)
+		return -1;
+
+	/* clip score */
+	if (score < 0)
+		score = 0;
+	else if (score > 100)
+		score = 100;
+
+	return score;
+}
+
+static int merge_diff_mark_similarity(
+	git_repository *repo,
+	git_merge_diff_list *diff_list,
+	struct merge_diff_similarity *similarity_ours,
+	struct merge_diff_similarity *similarity_theirs,
+	int (*similarity_fn)(git_repository *, git_index_entry *, size_t, git_index_entry *, size_t, void **, const git_merge_options *),
+	void **cache,
+	const git_merge_options *opts)
+{
+	size_t i, j;
+	git_merge_diff *conflict_src, *conflict_tgt;
+	int similarity;
+
+	git_vector_foreach(&diff_list->conflicts, i, conflict_src) {
+		/* Items can be the source of a rename iff they have an item in the
+		 * ancestor slot and lack an item in the ours or theirs slot. */
+		if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->ancestor_entry) ||
+			(GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->our_entry) &&
+			 GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->their_entry)))
+			continue;
+
+		git_vector_foreach(&diff_list->conflicts, j, conflict_tgt) {
+			size_t our_idx = diff_list->conflicts.length + j;
+			size_t their_idx = (diff_list->conflicts.length * 2) + j;
+
+			if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_tgt->ancestor_entry))
+				continue;
+
+			if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_tgt->our_entry) &&
+				!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->our_entry)) {
+				similarity = similarity_fn(repo, &conflict_src->ancestor_entry, i, &conflict_tgt->our_entry, our_idx, cache, opts);
+
+				if (similarity == GIT_EBUFS)
+					continue;
+				else if (similarity < 0)
+					return similarity;
+
+				if (similarity > similarity_ours[i].similarity &&
+					similarity > similarity_ours[j].similarity) {
+					/* Clear previous best similarity */
+					if (similarity_ours[i].similarity > 0)
+						similarity_ours[similarity_ours[i].other_idx].similarity = 0;
+
+					if (similarity_ours[j].similarity > 0)
+						similarity_ours[similarity_ours[j].other_idx].similarity = 0;
+
+					similarity_ours[i].similarity = similarity;
+					similarity_ours[i].other_idx = j;
+
+					similarity_ours[j].similarity = similarity;
+					similarity_ours[j].other_idx = i;
+				}
+			}
+
+			if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_tgt->their_entry) &&
+				!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->their_entry)) {
+				similarity = similarity_fn(repo, &conflict_src->ancestor_entry, i, &conflict_tgt->their_entry, their_idx, cache, opts);
+
+				if (similarity > similarity_theirs[i].similarity &&
+					similarity > similarity_theirs[j].similarity) {
+					/* Clear previous best similarity */
+					if (similarity_theirs[i].similarity > 0)
+						similarity_theirs[similarity_theirs[i].other_idx].similarity = 0;
+
+					if (similarity_theirs[j].similarity > 0)
+						similarity_theirs[similarity_theirs[j].other_idx].similarity = 0;
+
+					similarity_theirs[i].similarity = similarity;
+					similarity_theirs[i].other_idx = j;
+
+					similarity_theirs[j].similarity = similarity;
+					similarity_theirs[j].other_idx = i;
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Rename conflicts:
+ *
+ *      Ancestor   Ours   Theirs
+ *
+ * 0a   A          A      A        No rename
+ *  b   A          A*     A        No rename (ours was rewritten)
+ *  c   A          A      A*       No rename (theirs rewritten)
+ * 1a   A          A      B[A]     Rename or rename/edit
+ *  b   A          B[A]   A        (automergeable)
+ * 2    A          B[A]   B[A]     Both renamed (automergeable)
+ * 3a   A          B[A]            Rename/delete
+ *  b   A                 B[A]      (same)
+ * 4a   A          B[A]   B        Rename/add [B~ours B~theirs]
+ *  b   A          B      B[A]      (same)
+ * 5    A          B[A]   C[A]     Both renamed ("1 -> 2")
+ * 6    A          C[A]            Both renamed ("2 -> 1")
+ *      B                 C[B]     [C~ours C~theirs]    (automergeable)
+ */
+static void merge_diff_mark_rename_conflict(
+	git_merge_diff_list *diff_list,
+	struct merge_diff_similarity *similarity_ours,
+	bool ours_renamed,
+	size_t ours_source_idx,
+	struct merge_diff_similarity *similarity_theirs,
+	bool theirs_renamed,
+	size_t theirs_source_idx,
+	git_merge_diff *target,
+	const git_merge_options *opts)
+{
+	git_merge_diff *ours_source = NULL, *theirs_source = NULL;
+
+	if (ours_renamed)
+		ours_source = diff_list->conflicts.contents[ours_source_idx];
+
+	if (theirs_renamed)
+		theirs_source = diff_list->conflicts.contents[theirs_source_idx];
+
+	/* Detect 2->1 conflicts */
+	if (ours_renamed && theirs_renamed) {
+		/* Both renamed to the same target name. */
+		if (ours_source_idx == theirs_source_idx)
+			ours_source->type = GIT_MERGE_DIFF_BOTH_RENAMED;
+		else {
+			ours_source->type = GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1;
+			theirs_source->type = GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1;
+		}
+	} else if (ours_renamed) {
+		/* If our source was also renamed in theirs, this is a 1->2 */
+		if (similarity_theirs[ours_source_idx].similarity >= opts->rename_threshold)
+			ours_source->type = GIT_MERGE_DIFF_BOTH_RENAMED_1_TO_2;
+
+		else if (GIT_MERGE_INDEX_ENTRY_EXISTS(target->their_entry)) {
+			ours_source->type = GIT_MERGE_DIFF_RENAMED_ADDED;
+			target->type = GIT_MERGE_DIFF_RENAMED_ADDED;
+		}
+
+		else if (!GIT_MERGE_INDEX_ENTRY_EXISTS(ours_source->their_entry))
+			ours_source->type = GIT_MERGE_DIFF_RENAMED_DELETED;
+
+		else if (ours_source->type == GIT_MERGE_DIFF_MODIFIED_DELETED)
+			ours_source->type = GIT_MERGE_DIFF_RENAMED_MODIFIED;
+	} else if (theirs_renamed) {
+		/* If their source was also renamed in ours, this is a 1->2 */
+		if (similarity_ours[theirs_source_idx].similarity >= opts->rename_threshold)
+			theirs_source->type = GIT_MERGE_DIFF_BOTH_RENAMED_1_TO_2;
+
+		else if (GIT_MERGE_INDEX_ENTRY_EXISTS(target->our_entry)) {
+			theirs_source->type = GIT_MERGE_DIFF_RENAMED_ADDED;
+			target->type = GIT_MERGE_DIFF_RENAMED_ADDED;
+		}
+
+		else if (!GIT_MERGE_INDEX_ENTRY_EXISTS(theirs_source->our_entry))
+			theirs_source->type = GIT_MERGE_DIFF_RENAMED_DELETED;
+
+		else if (theirs_source->type == GIT_MERGE_DIFF_MODIFIED_DELETED)
+			theirs_source->type = GIT_MERGE_DIFF_RENAMED_MODIFIED;
+	}
+}
+
+GIT_INLINE(void) merge_diff_coalesce_rename(
+	git_index_entry *source_entry,
+	git_delta_t *source_status,
+	git_index_entry *target_entry,
+	git_delta_t *target_status)
+{
+	/* Coalesce the rename target into the rename source. */
+	memcpy(source_entry, target_entry, sizeof(git_index_entry));
+	*source_status = GIT_DELTA_RENAMED;
+
+	memset(target_entry, 0x0, sizeof(git_index_entry));
+	*target_status = GIT_DELTA_UNMODIFIED;
+}
+
+static void merge_diff_list_coalesce_renames(
+	git_merge_diff_list *diff_list,
+	struct merge_diff_similarity *similarity_ours,
+	struct merge_diff_similarity *similarity_theirs,
+	const git_merge_options *opts)
+{
+	size_t i;
+	bool ours_renamed = 0, theirs_renamed = 0;
+	size_t ours_source_idx = 0, theirs_source_idx = 0;
+	git_merge_diff *ours_source, *theirs_source, *target;
+
+	for (i = 0; i < diff_list->conflicts.length; i++) {
+		target = diff_list->conflicts.contents[i];
+
+		ours_renamed = 0;
+		theirs_renamed = 0;
+
+		if (GIT_MERGE_INDEX_ENTRY_EXISTS(target->our_entry) &&
+			similarity_ours[i].similarity >= opts->rename_threshold) {
+			ours_source_idx = similarity_ours[i].other_idx;
+
+			ours_source = diff_list->conflicts.contents[ours_source_idx];
+
+			merge_diff_coalesce_rename(
+				&ours_source->our_entry,
+				&ours_source->our_status,
+				&target->our_entry,
+				&target->our_status);
+
+			similarity_ours[ours_source_idx].similarity = 0;
+			similarity_ours[i].similarity = 0;
+
+			ours_renamed = 1;
+		}
+
+		/* insufficient to determine direction */
+		if (GIT_MERGE_INDEX_ENTRY_EXISTS(target->their_entry) &&
+			similarity_theirs[i].similarity >= opts->rename_threshold) {
+			theirs_source_idx = similarity_theirs[i].other_idx;
+
+			theirs_source = diff_list->conflicts.contents[theirs_source_idx];
+
+			merge_diff_coalesce_rename(
+				&theirs_source->their_entry,
+				&theirs_source->their_status,
+				&target->their_entry,
+				&target->their_status);
+
+			similarity_theirs[theirs_source_idx].similarity = 0;
+			similarity_theirs[i].similarity = 0;
+
+			theirs_renamed = 1;
+		}
+
+		merge_diff_mark_rename_conflict(diff_list,
+			similarity_ours, ours_renamed, ours_source_idx,
+			similarity_theirs, theirs_renamed, theirs_source_idx,
+			target, opts);
+	}
+}
+
+static int merge_diff_empty(const git_vector *conflicts, size_t idx, void *p)
+{
+	git_merge_diff *conflict = conflicts->contents[idx];
+
+	GIT_UNUSED(p);
+
+	return (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry) &&
+		!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) &&
+		!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry));
+}
+
+static void merge_diff_list_count_candidates(
+	git_merge_diff_list *diff_list,
+	size_t *src_count,
+	size_t *tgt_count)
+{
+	git_merge_diff *entry;
+	size_t i;
+
+	*src_count = 0;
+	*tgt_count = 0;
+
+	git_vector_foreach(&diff_list->conflicts, i, entry) {
+		if (GIT_MERGE_INDEX_ENTRY_EXISTS(entry->ancestor_entry) &&
+			(!GIT_MERGE_INDEX_ENTRY_EXISTS(entry->our_entry) ||
+			!GIT_MERGE_INDEX_ENTRY_EXISTS(entry->their_entry)))
+			(*src_count)++;
+		else if (!GIT_MERGE_INDEX_ENTRY_EXISTS(entry->ancestor_entry))
+			(*tgt_count)++;
+	}
+}
+
+int git_merge_diff_list__find_renames(
+	git_repository *repo,
+	git_merge_diff_list *diff_list,
+	const git_merge_options *opts)
+{
+	struct merge_diff_similarity *similarity_ours, *similarity_theirs;
+	void **cache = NULL;
+	size_t cache_size = 0;
+	size_t src_count, tgt_count, i;
+	int error = 0;
+
+	assert(diff_list && opts);
+
+	if ((opts->tree_flags & GIT_MERGE_TREE_FIND_RENAMES) == 0)
+		return 0;
+
+	similarity_ours = git__calloc(diff_list->conflicts.length,
+		sizeof(struct merge_diff_similarity));
+	GITERR_CHECK_ALLOC(similarity_ours);
+
+	similarity_theirs = git__calloc(diff_list->conflicts.length,
+		sizeof(struct merge_diff_similarity));
+	GITERR_CHECK_ALLOC(similarity_theirs);
+
+	/* Calculate similarity between items that were deleted from the ancestor
+	 * and added in the other branch.
+	 */
+	if ((error = merge_diff_mark_similarity(repo, diff_list, similarity_ours,
+		similarity_theirs, index_entry_similarity_exact, NULL, opts)) < 0)
+		goto done;
+
+	if (diff_list->conflicts.length <= opts->target_limit) {
+		GITERR_CHECK_ALLOC_MULTIPLY(&cache_size, diff_list->conflicts.length, 3);
+		cache = git__calloc(cache_size, sizeof(void *));
+		GITERR_CHECK_ALLOC(cache);
+
+		merge_diff_list_count_candidates(diff_list, &src_count, &tgt_count);
+
+		if (src_count > opts->target_limit || tgt_count > opts->target_limit) {
+			/* TODO: report! */
+		} else {
+			if ((error = merge_diff_mark_similarity(
+				repo, diff_list, similarity_ours, similarity_theirs,
+				index_entry_similarity_inexact, cache, opts)) < 0)
+				goto done;
+		}
+	}
+
+	/* For entries that are appropriately similar, merge the new name's entry
+	 * into the old name.
+	 */
+	merge_diff_list_coalesce_renames(diff_list, similarity_ours, similarity_theirs, opts);
+
+	/* And remove any entries that were merged and are now empty. */
+	git_vector_remove_matching(&diff_list->conflicts, merge_diff_empty, NULL);
+
+done:
+	if (cache != NULL) {
+		for (i = 0; i < cache_size; ++i) {
+			if (cache[i] != NULL)
+				opts->metric->free_signature(cache[i], opts->metric->payload);
+		}
+
+		git__free(cache);
+	}
+
+	git__free(similarity_ours);
+	git__free(similarity_theirs);
+
+	return error;
+}
+
+/* Directory/file conflict handling */
+
+GIT_INLINE(const char *) merge_diff_path(
+	const git_merge_diff *conflict)
+{
+	if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry))
+		return conflict->ancestor_entry.path;
+	else if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry))
+		return conflict->our_entry.path;
+	else if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry))
+		return conflict->their_entry.path;
+
+	return NULL;
+}
+
+GIT_INLINE(bool) merge_diff_any_side_added_or_modified(
+	const git_merge_diff *conflict)
+{
+	if (conflict->our_status == GIT_DELTA_ADDED ||
+		conflict->our_status == GIT_DELTA_MODIFIED ||
+		conflict->their_status == GIT_DELTA_ADDED ||
+		conflict->their_status == GIT_DELTA_MODIFIED)
+		return true;
+
+	return false;
+}
+
+GIT_INLINE(bool) path_is_prefixed(const char *parent, const char *child)
+{
+	size_t child_len = strlen(child);
+	size_t parent_len = strlen(parent);
+
+	if (child_len < parent_len ||
+		strncmp(parent, child, parent_len) != 0)
+		return 0;
+
+	return (child[parent_len] == '/');
+}
+
+GIT_INLINE(int) merge_diff_detect_df_conflict(
+	struct merge_diff_df_data *df_data,
+	git_merge_diff *conflict)
+{
+	const char *cur_path = merge_diff_path(conflict);
+
+	/* Determine if this is a D/F conflict or the child of one */
+	if (df_data->df_path &&
+		path_is_prefixed(df_data->df_path, cur_path))
+		conflict->type = GIT_MERGE_DIFF_DF_CHILD;
+	else if(df_data->df_path)
+		df_data->df_path = NULL;
+	else if (df_data->prev_path &&
+		merge_diff_any_side_added_or_modified(df_data->prev_conflict) &&
+		merge_diff_any_side_added_or_modified(conflict) &&
+		path_is_prefixed(df_data->prev_path, cur_path)) {
+		conflict->type = GIT_MERGE_DIFF_DF_CHILD;
+
+		df_data->prev_conflict->type = GIT_MERGE_DIFF_DIRECTORY_FILE;
+		df_data->df_path = df_data->prev_path;
+	}
+
+	df_data->prev_path = cur_path;
+	df_data->prev_conflict = conflict;
+
+	return 0;
+}
+
+/* Conflict handling */
+
+GIT_INLINE(int) merge_diff_detect_type(
+	git_merge_diff *conflict)
+{
+	if (conflict->our_status == GIT_DELTA_ADDED &&
+		conflict->their_status == GIT_DELTA_ADDED)
+		conflict->type = GIT_MERGE_DIFF_BOTH_ADDED;
+	else if (conflict->our_status == GIT_DELTA_MODIFIED &&
+			 conflict->their_status == GIT_DELTA_MODIFIED)
+		conflict->type = GIT_MERGE_DIFF_BOTH_MODIFIED;
+	else if (conflict->our_status == GIT_DELTA_DELETED &&
+			 conflict->their_status == GIT_DELTA_DELETED)
+		conflict->type = GIT_MERGE_DIFF_BOTH_DELETED;
+	else if (conflict->our_status == GIT_DELTA_MODIFIED &&
+			 conflict->their_status == GIT_DELTA_DELETED)
+		conflict->type = GIT_MERGE_DIFF_MODIFIED_DELETED;
+	else if (conflict->our_status == GIT_DELTA_DELETED &&
+			 conflict->their_status == GIT_DELTA_MODIFIED)
+		conflict->type = GIT_MERGE_DIFF_MODIFIED_DELETED;
+	else
+		conflict->type = GIT_MERGE_DIFF_NONE;
+
+	return 0;
+}
+
+GIT_INLINE(int) index_entry_dup_pool(
+	git_index_entry *out,
+	git_pool *pool,
+	const git_index_entry *src)
+{
+	if (src != NULL) {
+		memcpy(out, src, sizeof(git_index_entry));
+
+		if ((out->path = git_pool_strdup(pool, src->path)) == NULL)
+			return -1;
+	}
+
+	return 0;
+}
+
+GIT_INLINE(int) merge_delta_type_from_index_entries(
+	const git_index_entry *ancestor,
+	const git_index_entry *other)
+{
+	if (ancestor == NULL && other == NULL)
+		return GIT_DELTA_UNMODIFIED;
+	else if (ancestor == NULL && other != NULL)
+		return GIT_DELTA_ADDED;
+	else if (ancestor != NULL && other == NULL)
+		return GIT_DELTA_DELETED;
+	else if (S_ISDIR(ancestor->mode) ^ S_ISDIR(other->mode))
+		return GIT_DELTA_TYPECHANGE;
+	else if(S_ISLNK(ancestor->mode) ^ S_ISLNK(other->mode))
+		return GIT_DELTA_TYPECHANGE;
+	else if (git_oid__cmp(&ancestor->id, &other->id) ||
+			 ancestor->mode != other->mode)
+		return GIT_DELTA_MODIFIED;
+
+	return GIT_DELTA_UNMODIFIED;
+}
+
+static git_merge_diff *merge_diff_from_index_entries(
+	git_merge_diff_list *diff_list,
+	const git_index_entry **entries)
+{
+	git_merge_diff *conflict;
+	git_pool *pool = &diff_list->pool;
+
+	if ((conflict = git_pool_malloc(pool, sizeof(git_merge_diff))) == NULL)
+		return NULL;
+
+	if (index_entry_dup_pool(&conflict->ancestor_entry, pool, entries[TREE_IDX_ANCESTOR]) < 0 ||
+		index_entry_dup_pool(&conflict->our_entry, pool, entries[TREE_IDX_OURS]) < 0 ||
+		index_entry_dup_pool(&conflict->their_entry, pool, entries[TREE_IDX_THEIRS]) < 0)
+		return NULL;
+
+	conflict->our_status = merge_delta_type_from_index_entries(
+		entries[TREE_IDX_ANCESTOR], entries[TREE_IDX_OURS]);
+	conflict->their_status = merge_delta_type_from_index_entries(
+		entries[TREE_IDX_ANCESTOR], entries[TREE_IDX_THEIRS]);
+
+	return conflict;
+}
+
+/* Merge trees */
+
+static int merge_diff_list_insert_conflict(
+	git_merge_diff_list *diff_list,
+	struct merge_diff_df_data *merge_df_data,
+	const git_index_entry *tree_items[3])
+{
+	git_merge_diff *conflict;
+
+	if ((conflict = merge_diff_from_index_entries(diff_list, tree_items)) == NULL ||
+		merge_diff_detect_type(conflict) < 0 ||
+		merge_diff_detect_df_conflict(merge_df_data, conflict) < 0 ||
+		git_vector_insert(&diff_list->conflicts, conflict) < 0)
+		return -1;
+
+	return 0;
+}
+
+static int merge_diff_list_insert_unmodified(
+	git_merge_diff_list *diff_list,
+	const git_index_entry *tree_items[3])
+{
+	int error = 0;
+	git_index_entry *entry;
+
+	entry = git_pool_malloc(&diff_list->pool, sizeof(git_index_entry));
+	GITERR_CHECK_ALLOC(entry);
+
+	if ((error = index_entry_dup_pool(entry, &diff_list->pool, tree_items[0])) >= 0)
+		error = git_vector_insert(&diff_list->staged, entry);
+
+	return error;
+}
+
+struct merge_diff_find_data {
+	git_merge_diff_list *diff_list;
+	struct merge_diff_df_data df_data;
+};
+
+static int queue_difference(const git_index_entry **entries, void *data)
+{
+	struct merge_diff_find_data *find_data = data;
+	bool item_modified = false;
+	size_t i;
+
+	if (!entries[0] || !entries[1] || !entries[2]) {
+		item_modified = true;
+	} else {
+		for (i = 1; i < 3; i++) {
+			if (index_entry_cmp(entries[0], entries[i]) != 0) {
+				item_modified = true;
+				break;
+			}
+		}
+	}
+
+	return item_modified ?
+		merge_diff_list_insert_conflict(
+			find_data->diff_list, &find_data->df_data, entries) :
+		merge_diff_list_insert_unmodified(find_data->diff_list, entries);
+}
+
+int git_merge_diff_list__find_differences(
+	git_merge_diff_list *diff_list,
+	git_iterator *ancestor_iter,
+	git_iterator *our_iter,
+	git_iterator *their_iter)
+{
+	git_iterator *iterators[3] = { ancestor_iter, our_iter, their_iter };
+	struct merge_diff_find_data find_data = { diff_list };
+
+	return git_iterator_walk(iterators, 3, queue_difference, &find_data);
+}
+
+git_merge_diff_list *git_merge_diff_list__alloc(git_repository *repo)
+{
+	git_merge_diff_list *diff_list = git__calloc(1, sizeof(git_merge_diff_list));
+
+	if (diff_list == NULL)
+		return NULL;
+
+	diff_list->repo = repo;
+
+	if (git_vector_init(&diff_list->staged, 0, NULL) < 0 ||
+		git_vector_init(&diff_list->conflicts, 0, NULL) < 0 ||
+		git_vector_init(&diff_list->resolved, 0, NULL) < 0 ||
+		git_pool_init(&diff_list->pool, 1, 0) < 0) {
+		git_merge_diff_list__free(diff_list);
+		return NULL;
+	}
+
+	return diff_list;
+}
+
+void git_merge_diff_list__free(git_merge_diff_list *diff_list)
+{
+	if (!diff_list)
+		return;
+
+	git_vector_free(&diff_list->staged);
+	git_vector_free(&diff_list->conflicts);
+	git_vector_free(&diff_list->resolved);
+	git_pool_clear(&diff_list->pool);
+	git__free(diff_list);
+}
+
+static int merge_normalize_opts(
+	git_repository *repo,
+	git_merge_options *opts,
+	const git_merge_options *given)
+{
+	git_config *cfg = NULL;
+	int error = 0;
+
+	assert(repo && opts);
+
+	if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
+		return error;
+
+	if (given != NULL)
+		memcpy(opts, given, sizeof(git_merge_options));
+	else {
+		git_merge_options init = GIT_MERGE_OPTIONS_INIT;
+		memcpy(opts, &init, sizeof(init));
+
+		opts->tree_flags = GIT_MERGE_TREE_FIND_RENAMES;
+		opts->rename_threshold = GIT_MERGE_TREE_RENAME_THRESHOLD;
+	}
+
+	if (!opts->target_limit) {
+		int limit = git_config__get_int_force(cfg, "merge.renamelimit", 0);
+
+		if (!limit)
+			limit = git_config__get_int_force(cfg, "diff.renamelimit", 0);
+
+		opts->target_limit = (limit <= 0) ?
+			GIT_MERGE_TREE_TARGET_LIMIT : (unsigned int)limit;
+	}
+
+	/* assign the internal metric with whitespace flag as payload */
+	if (!opts->metric) {
+		opts->metric = git__malloc(sizeof(git_diff_similarity_metric));
+		GITERR_CHECK_ALLOC(opts->metric);
+
+		opts->metric->file_signature = git_diff_find_similar__hashsig_for_file;
+		opts->metric->buffer_signature = git_diff_find_similar__hashsig_for_buf;
+		opts->metric->free_signature = git_diff_find_similar__hashsig_free;
+		opts->metric->similarity = git_diff_find_similar__calc_similarity;
+		opts->metric->payload = (void *)GIT_HASHSIG_SMART_WHITESPACE;
+	}
+
+	return 0;
+}
+
+
+static int merge_index_insert_reuc(
+	git_index *index,
+	size_t idx,
+	const git_index_entry *entry)
+{
+	const git_index_reuc_entry *reuc;
+	int mode[3] = { 0, 0, 0 };
+	git_oid const *oid[3] = { NULL, NULL, NULL };
+	size_t i;
+
+	if (!GIT_MERGE_INDEX_ENTRY_EXISTS(*entry))
+		return 0;
+
+	if ((reuc = git_index_reuc_get_bypath(index, entry->path)) != NULL) {
+		for (i = 0; i < 3; i++) {
+			mode[i] = reuc->mode[i];
+			oid[i] = &reuc->oid[i];
+		}
+	}
+
+	mode[idx] = entry->mode;
+	oid[idx] = &entry->id;
+
+	return git_index_reuc_add(index, entry->path,
+		mode[0], oid[0], mode[1], oid[1], mode[2], oid[2]);
+}
+
+int index_from_diff_list(git_index **out, git_merge_diff_list *diff_list)
+{
+	git_index *index;
+	size_t i;
+	git_index_entry *entry;
+	git_merge_diff *conflict;
+	int error = 0;
+
+	*out = NULL;
+
+	if ((error = git_index_new(&index)) < 0)
+		return error;
+
+	git_vector_foreach(&diff_list->staged, i, entry) {
+		if ((error = git_index_add(index, entry)) < 0)
+			goto on_error;
+	}
+
+	git_vector_foreach(&diff_list->conflicts, i, conflict) {
+		const git_index_entry *ancestor =
+			GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry) ?
+			&conflict->ancestor_entry : NULL;
+
+		const git_index_entry *ours =
+			GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
+			&conflict->our_entry : NULL;
+
+		const git_index_entry *theirs =
+			GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
+			&conflict->their_entry : NULL;
+
+		if ((error = git_index_conflict_add(index, ancestor, ours, theirs)) < 0)
+			goto on_error;
+	}
+
+	/* Add each rename entry to the rename portion of the index. */
+	git_vector_foreach(&diff_list->conflicts, i, conflict) {
+		const char *ancestor_path, *our_path, *their_path;
+
+		if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry))
+			continue;
+
+		ancestor_path = conflict->ancestor_entry.path;
+
+		our_path =
+			GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
+			conflict->our_entry.path : NULL;
+
+		their_path =
+			GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
+			conflict->their_entry.path : NULL;
+
+		if ((our_path && strcmp(ancestor_path, our_path) != 0) ||
+			(their_path && strcmp(ancestor_path, their_path) != 0)) {
+			if ((error = git_index_name_add(index, ancestor_path, our_path, their_path)) < 0)
+				goto on_error;
+		}
+	}
+
+	/* Add each entry in the resolved conflict to the REUC independently, since
+	 * the paths may differ due to renames. */
+	git_vector_foreach(&diff_list->resolved, i, conflict) {
+		const git_index_entry *ancestor =
+			GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry) ?
+			&conflict->ancestor_entry : NULL;
+
+		const git_index_entry *ours =
+			GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
+			&conflict->our_entry : NULL;
+
+		const git_index_entry *theirs =
+			GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
+			&conflict->their_entry : NULL;
+
+		if (ancestor != NULL &&
+			(error = merge_index_insert_reuc(index, TREE_IDX_ANCESTOR, ancestor)) < 0)
+			goto on_error;
+
+		if (ours != NULL &&
+			(error = merge_index_insert_reuc(index, TREE_IDX_OURS, ours)) < 0)
+			goto on_error;
+
+		if (theirs != NULL &&
+			(error = merge_index_insert_reuc(index, TREE_IDX_THEIRS, theirs)) < 0)
+			goto on_error;
+	}
+
+	*out = index;
+	return 0;
+
+on_error:
+	git_index_free(index);
+
+	return error;
+}
+
+static git_iterator *iterator_given_or_empty(git_iterator **empty, git_iterator *given)
+{
+	if (given)
+		return given;
+
+	if (git_iterator_for_nothing(empty, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL) < 0)
+		return NULL;
+
+	return *empty;
+}
+
+int git_merge__iterators(
+	git_index **out,
+	git_repository *repo,
+	git_iterator *ancestor_iter,
+	git_iterator *our_iter,
+	git_iterator *theirs_iter,
+	const git_merge_options *given_opts)
+{
+	git_iterator *empty_ancestor = NULL,
+		*empty_ours = NULL,
+		*empty_theirs = NULL;
+	git_merge_diff_list *diff_list;
+	git_merge_options opts;
+	git_merge_diff *conflict;
+	git_vector changes;
+	size_t i;
+	int error = 0;
+
+	assert(out && repo);
+
+	*out = NULL;
+
+	GITERR_CHECK_VERSION(
+		given_opts, GIT_MERGE_OPTIONS_VERSION, "git_merge_options");
+
+	if ((error = merge_normalize_opts(repo, &opts, given_opts)) < 0)
+		return error;
+
+	diff_list = git_merge_diff_list__alloc(repo);
+	GITERR_CHECK_ALLOC(diff_list);
+
+	ancestor_iter = iterator_given_or_empty(&empty_ancestor, ancestor_iter);
+	our_iter = iterator_given_or_empty(&empty_ours, our_iter);
+	theirs_iter = iterator_given_or_empty(&empty_theirs, theirs_iter);
+
+	if ((error = git_merge_diff_list__find_differences(
+			diff_list, ancestor_iter, our_iter, theirs_iter)) < 0 ||
+		(error = git_merge_diff_list__find_renames(repo, diff_list, &opts)) < 0)
+		goto done;
+
+	memcpy(&changes, &diff_list->conflicts, sizeof(git_vector));
+	git_vector_clear(&diff_list->conflicts);
+
+	git_vector_foreach(&changes, i, conflict) {
+		int resolved = 0;
+
+		if ((error = merge_conflict_resolve(&resolved, diff_list, conflict, opts.file_favor, opts.file_flags)) < 0)
+			goto done;
+
+		if (!resolved)
+			git_vector_insert(&diff_list->conflicts, conflict);
+	}
+
+	if (!given_opts || !given_opts->metric)
+		git__free(opts.metric);
+
+	error = index_from_diff_list(out, diff_list);
+
+done:
+	git_merge_diff_list__free(diff_list);
+	git_iterator_free(empty_ancestor);
+	git_iterator_free(empty_ours);
+	git_iterator_free(empty_theirs);
+
+	return error;
+}
+
+int git_merge_trees(
+	git_index **out,
+	git_repository *repo,
+	const git_tree *ancestor_tree,
+	const git_tree *our_tree,
+	const git_tree *their_tree,
+	const git_merge_options *merge_opts)
+{
+	git_iterator *ancestor_iter = NULL, *our_iter = NULL, *their_iter = NULL;
+	int error;
+
+	if ((error = git_iterator_for_tree(&ancestor_iter, (git_tree *)ancestor_tree,
+			GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
+		(error = git_iterator_for_tree(&our_iter, (git_tree *)our_tree,
+			GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
+		(error = git_iterator_for_tree(&their_iter, (git_tree *)their_tree,
+			GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0)
+		goto done;
+
+	error = git_merge__iterators(
+		out, repo, ancestor_iter, our_iter, their_iter, merge_opts);
+
+done:
+	git_iterator_free(ancestor_iter);
+	git_iterator_free(our_iter);
+	git_iterator_free(their_iter);
+
+	return error;
+}
+
+
+int git_merge_commits(
+	git_index **out,
+	git_repository *repo,
+	const git_commit *our_commit,
+	const git_commit *their_commit,
+	const git_merge_options *opts)
+{
+	git_oid ancestor_oid;
+	git_commit *ancestor_commit = NULL;
+	git_tree *our_tree = NULL, *their_tree = NULL, *ancestor_tree = NULL;
+	int error = 0;
+
+	if ((error = git_merge_base(&ancestor_oid, repo, git_commit_id(our_commit), git_commit_id(their_commit))) < 0 &&
+		error == GIT_ENOTFOUND)
+		giterr_clear();
+	else if (error < 0 ||
+		(error = git_commit_lookup(&ancestor_commit, repo, &ancestor_oid)) < 0 ||
+		(error = git_commit_tree(&ancestor_tree, ancestor_commit)) < 0)
+		goto done;
+
+	if ((error = git_commit_tree(&our_tree, our_commit)) < 0 ||
+		(error = git_commit_tree(&their_tree, their_commit)) < 0 ||
+		(error = git_merge_trees(out, repo, ancestor_tree, our_tree, their_tree, opts)) < 0)
+		goto done;
+
+done:
+	git_commit_free(ancestor_commit);
+	git_tree_free(our_tree);
+	git_tree_free(their_tree);
+	git_tree_free(ancestor_tree);
+
+	return error;
+}
+
+/* Merge setup / cleanup */
+
+static int write_merge_head(
+	git_repository *repo,
+	const git_annotated_commit *heads[],
+	size_t heads_len)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	git_buf file_path = GIT_BUF_INIT;
+	size_t i;
+	int error = 0;
+
+	assert(repo && heads);
+
+	if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_HEAD_FILE)) < 0 ||
+		(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_MERGE_FILE_MODE)) < 0)
+		goto cleanup;
+
+	for (i = 0; i < heads_len; i++) {
+		if ((error = git_filebuf_printf(&file, "%s\n", heads[i]->id_str)) < 0)
+			goto cleanup;
+	}
+
+	error = git_filebuf_commit(&file);
+
+cleanup:
+	if (error < 0)
+		git_filebuf_cleanup(&file);
+
+	git_buf_free(&file_path);
+
+	return error;
+}
+
+static int write_merge_mode(git_repository *repo)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	git_buf file_path = GIT_BUF_INIT;
+	int error = 0;
+
+	assert(repo);
+
+	if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_MODE_FILE)) < 0 ||
+		(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_MERGE_FILE_MODE)) < 0)
+		goto cleanup;
+
+	if ((error = git_filebuf_write(&file, "no-ff", 5)) < 0)
+		goto cleanup;
+
+	error = git_filebuf_commit(&file);
+
+cleanup:
+	if (error < 0)
+		git_filebuf_cleanup(&file);
+
+	git_buf_free(&file_path);
+
+	return error;
+}
+
+struct merge_msg_entry {
+	const git_annotated_commit *merge_head;
+	bool written;
+};
+
+static int msg_entry_is_branch(
+	const struct merge_msg_entry *entry,
+	git_vector *entries)
+{
+	GIT_UNUSED(entries);
+
+	return (entry->written == 0 &&
+		entry->merge_head->remote_url == NULL &&
+		entry->merge_head->ref_name != NULL &&
+		git__strncmp(GIT_REFS_HEADS_DIR, entry->merge_head->ref_name, strlen(GIT_REFS_HEADS_DIR)) == 0);
+}
+
+static int msg_entry_is_tracking(
+	const struct merge_msg_entry *entry,
+	git_vector *entries)
+{
+	GIT_UNUSED(entries);
+
+	return (entry->written == 0 &&
+		entry->merge_head->remote_url == NULL &&
+		entry->merge_head->ref_name != NULL &&
+		git__strncmp(GIT_REFS_REMOTES_DIR, entry->merge_head->ref_name, strlen(GIT_REFS_REMOTES_DIR)) == 0);
+}
+
+static int msg_entry_is_tag(
+	const struct merge_msg_entry *entry,
+	git_vector *entries)
+{
+	GIT_UNUSED(entries);
+
+	return (entry->written == 0 &&
+		entry->merge_head->remote_url == NULL &&
+		entry->merge_head->ref_name != NULL &&
+		git__strncmp(GIT_REFS_TAGS_DIR, entry->merge_head->ref_name, strlen(GIT_REFS_TAGS_DIR)) == 0);
+}
+
+static int msg_entry_is_remote(
+	const struct merge_msg_entry *entry,
+	git_vector *entries)
+{
+	if (entry->written == 0 &&
+		entry->merge_head->remote_url != NULL &&
+		entry->merge_head->ref_name != NULL &&
+		git__strncmp(GIT_REFS_HEADS_DIR, entry->merge_head->ref_name, strlen(GIT_REFS_HEADS_DIR)) == 0)
+	{
+		struct merge_msg_entry *existing;
+
+		/* Match only branches from the same remote */
+		if (entries->length == 0)
+			return 1;
+
+		existing = git_vector_get(entries, 0);
+
+		return (git__strcmp(existing->merge_head->remote_url,
+			entry->merge_head->remote_url) == 0);
+	}
+
+	return 0;
+}
+
+static int msg_entry_is_oid(
+	const struct merge_msg_entry *merge_msg_entry)
+{
+	return (merge_msg_entry->written == 0 &&
+		merge_msg_entry->merge_head->ref_name == NULL &&
+		merge_msg_entry->merge_head->remote_url == NULL);
+}
+
+static int merge_msg_entry_written(
+	const struct merge_msg_entry *merge_msg_entry)
+{
+	return (merge_msg_entry->written == 1);
+}
+
+static int merge_msg_entries(
+	git_vector *v,
+	const struct merge_msg_entry *entries,
+	size_t len,
+	int (*match)(const struct merge_msg_entry *entry, git_vector *entries))
+{
+	size_t i;
+	int matches, total = 0;
+
+	git_vector_clear(v);
+
+	for (i = 0; i < len; i++) {
+		if ((matches = match(&entries[i], v)) < 0)
+			return matches;
+		else if (!matches)
+			continue;
+
+		git_vector_insert(v, (struct merge_msg_entry *)&entries[i]);
+		total++;
+	}
+
+	return total;
+}
+
+static int merge_msg_write_entries(
+	git_filebuf *file,
+	git_vector *entries,
+	const char *item_name,
+	const char *item_plural_name,
+	size_t ref_name_skip,
+	const char *source,
+	char sep)
+{
+	struct merge_msg_entry *entry;
+	size_t i;
+	int error = 0;
+
+	if (entries->length == 0)
+		return 0;
+
+	if (sep && (error = git_filebuf_printf(file, "%c ", sep)) < 0)
+		goto done;
+
+	if ((error = git_filebuf_printf(file, "%s ",
+		(entries->length == 1) ? item_name : item_plural_name)) < 0)
+		goto done;
+
+	git_vector_foreach(entries, i, entry) {
+		if (i > 0 &&
+			(error = git_filebuf_printf(file, "%s", (i == entries->length - 1) ? " and " : ", ")) < 0)
+			goto done;
+
+		if ((error = git_filebuf_printf(file, "'%s'", entry->merge_head->ref_name + ref_name_skip)) < 0)
+			goto done;
+
+		entry->written = 1;
+	}
+
+	if (source)
+		error = git_filebuf_printf(file, " of %s", source);
+
+done:
+	return error;
+}
+
+static int merge_msg_write_branches(
+	git_filebuf *file,
+	git_vector *entries,
+	char sep)
+{
+	return merge_msg_write_entries(file, entries,
+		"branch", "branches", strlen(GIT_REFS_HEADS_DIR), NULL, sep);
+}
+
+static int merge_msg_write_tracking(
+	git_filebuf *file,
+	git_vector *entries,
+	char sep)
+{
+	return merge_msg_write_entries(file, entries,
+		"remote-tracking branch", "remote-tracking branches", 0, NULL, sep);
+}
+
+static int merge_msg_write_tags(
+	git_filebuf *file,
+	git_vector *entries,
+	char sep)
+{
+	return merge_msg_write_entries(file, entries,
+		"tag", "tags", strlen(GIT_REFS_TAGS_DIR), NULL, sep);
+}
+
+static int merge_msg_write_remotes(
+	git_filebuf *file,
+	git_vector *entries,
+	char sep)
+{
+	const char *source;
+
+	if (entries->length == 0)
+		return 0;
+
+	source = ((struct merge_msg_entry *)entries->contents[0])->merge_head->remote_url;
+
+	return merge_msg_write_entries(file, entries,
+		"branch", "branches", strlen(GIT_REFS_HEADS_DIR), source, sep);
+}
+
+static int write_merge_msg(
+	git_repository *repo,
+	const git_annotated_commit *heads[],
+	size_t heads_len)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	git_buf file_path = GIT_BUF_INIT;
+	struct merge_msg_entry *entries;
+	git_vector matching = GIT_VECTOR_INIT;
+	size_t i;
+	char sep = 0;
+	int error = 0;
+
+	assert(repo && heads);
+
+	entries = git__calloc(heads_len, sizeof(struct merge_msg_entry));
+	GITERR_CHECK_ALLOC(entries); 
+
+	if (git_vector_init(&matching, heads_len, NULL) < 0) {
+		git__free(entries);
+		return -1;
+	}
+
+	for (i = 0; i < heads_len; i++)
+		entries[i].merge_head = heads[i];
+
+	if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_MSG_FILE)) < 0 ||
+		(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_MERGE_FILE_MODE)) < 0 ||
+		(error = git_filebuf_write(&file, "Merge ", 6)) < 0)
+		goto cleanup;
+
+	/*
+	 * This is to emulate the format of MERGE_MSG by core git.
+	 *
+	 * Core git will write all the commits specified by OID, in the order
+	 * provided, until the first named branch or tag is reached, at which
+	 * point all branches will be written in the order provided, then all
+	 * tags, then all remote tracking branches and finally all commits that
+	 * were specified by OID that were not already written.
+	 *
+	 * Yes.  Really.
+	 */
+	for (i = 0; i < heads_len; i++) {
+		if (!msg_entry_is_oid(&entries[i]))
+			break;
+
+		if ((error = git_filebuf_printf(&file,
+			"%scommit '%s'", (i > 0) ? "; " : "",
+			entries[i].merge_head->id_str)) < 0)
+			goto cleanup;
+
+		entries[i].written = 1;
+	}
+
+	if (i)
+		sep = ';';
+
+	if ((error = merge_msg_entries(&matching, entries, heads_len, msg_entry_is_branch)) < 0 ||
+		(error = merge_msg_write_branches(&file, &matching, sep)) < 0)
+		goto cleanup;
+
+	if (matching.length)
+		sep =',';
+
+	if ((error = merge_msg_entries(&matching, entries, heads_len, msg_entry_is_tracking)) < 0 ||
+		(error = merge_msg_write_tracking(&file, &matching, sep)) < 0)
+		goto cleanup;
+
+	if (matching.length)
+		sep =',';
+	
+	if ((error = merge_msg_entries(&matching, entries, heads_len, msg_entry_is_tag)) < 0 ||
+		(error = merge_msg_write_tags(&file, &matching, sep)) < 0)
+		goto cleanup;
+
+	if (matching.length)
+		sep =',';
+
+	/* We should never be called with multiple remote branches, but handle
+	 * it in case we are... */
+	while ((error = merge_msg_entries(&matching, entries, heads_len, msg_entry_is_remote)) > 0) {
+		if ((error = merge_msg_write_remotes(&file, &matching, sep)) < 0)
+			goto cleanup;
+
+		if (matching.length)
+			sep =',';
+	}
+
+	if (error < 0)
+		goto cleanup;
+
+	for (i = 0; i < heads_len; i++) {
+		if (merge_msg_entry_written(&entries[i]))
+			continue;
+
+		if ((error = git_filebuf_printf(&file, "; commit '%s'",
+			entries[i].merge_head->id_str)) < 0)
+			goto cleanup;
+	}
+
+	if ((error = git_filebuf_printf(&file, "\n")) < 0 ||
+		(error = git_filebuf_commit(&file)) < 0)
+		goto cleanup;
+
+cleanup:
+	if (error < 0)
+		git_filebuf_cleanup(&file);
+
+	git_buf_free(&file_path);
+
+	git_vector_free(&matching);
+	git__free(entries);
+
+	return error;
+}
+
+int git_merge__setup(
+	git_repository *repo,
+	const git_annotated_commit *our_head,
+	const git_annotated_commit *heads[],
+	size_t heads_len)
+{
+	int error = 0;
+
+	assert (repo && our_head && heads);
+
+	if ((error = git_repository__set_orig_head(repo, git_annotated_commit_id(our_head))) == 0 &&
+		(error = write_merge_head(repo, heads, heads_len)) == 0 &&
+		(error = write_merge_mode(repo)) == 0) {
+		error = write_merge_msg(repo, heads, heads_len);
+	}
+
+	return error;
+}
+
+/* Merge branches */
+
+static int merge_ancestor_head(
+	git_annotated_commit **ancestor_head,
+	git_repository *repo,
+	const git_annotated_commit *our_head,
+	const git_annotated_commit **their_heads,
+	size_t their_heads_len)
+{
+	git_oid *oids, ancestor_oid;
+	size_t i, alloc_len;
+	int error = 0;
+
+	assert(repo && our_head && their_heads);
+
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, their_heads_len, 1);
+	oids = git__calloc(alloc_len, sizeof(git_oid));
+	GITERR_CHECK_ALLOC(oids);
+
+	git_oid_cpy(&oids[0], git_commit_id(our_head->commit));
+
+	for (i = 0; i < their_heads_len; i++)
+		git_oid_cpy(&oids[i + 1], git_annotated_commit_id(their_heads[i]));
+
+	if ((error = git_merge_base_many(&ancestor_oid, repo, their_heads_len + 1, oids)) < 0)
+		goto on_error;
+
+	error = git_annotated_commit_lookup(ancestor_head, repo, &ancestor_oid);
+
+on_error:
+	git__free(oids);
+	return error;
+}
+
+const char *merge_their_label(const char *branchname)
+{
+	const char *slash;
+
+	if ((slash = strrchr(branchname, '/')) == NULL)
+		return branchname;
+
+	if (*(slash+1) == '\0')
+		return "theirs";
+
+	return slash+1;
+}
+
+static int merge_normalize_checkout_opts(
+	git_repository *repo,
+	git_checkout_options *checkout_opts,
+	const git_checkout_options *given_checkout_opts,
+	const git_annotated_commit *ancestor_head,
+	const git_annotated_commit *our_head,
+	size_t their_heads_len,
+	const git_annotated_commit **their_heads)
+{
+	int error = 0;
+
+	GIT_UNUSED(repo);
+
+	if (given_checkout_opts != NULL)
+		memcpy(checkout_opts, given_checkout_opts, sizeof(git_checkout_options));
+	else {
+		git_checkout_options default_checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
+		default_checkout_opts.checkout_strategy =  GIT_CHECKOUT_SAFE;
+
+		memcpy(checkout_opts, &default_checkout_opts, sizeof(git_checkout_options));
+	}
+
+	/* TODO: for multiple ancestors in merge-recursive, this is "merged common ancestors" */
+	if (!checkout_opts->ancestor_label) {
+		if (ancestor_head && ancestor_head->commit)
+			checkout_opts->ancestor_label = git_commit_summary(ancestor_head->commit);
+		else
+			checkout_opts->ancestor_label = "ancestor";
+	}
+
+	if (!checkout_opts->our_label) {
+		if (our_head && our_head->ref_name)
+			checkout_opts->our_label = our_head->ref_name;
+		else
+			checkout_opts->our_label = "ours";
+	}
+
+	if (!checkout_opts->their_label) {
+		if (their_heads_len == 1 && their_heads[0]->ref_name)
+			checkout_opts->their_label = merge_their_label(their_heads[0]->ref_name);
+		else if (their_heads_len == 1)
+			checkout_opts->their_label = their_heads[0]->id_str;
+		else
+			checkout_opts->their_label = "theirs";
+	}
+
+	return error;
+}
+
+static int merge_check_index(size_t *conflicts, git_repository *repo, git_index *index_new, git_vector *merged_paths)
+{
+	git_tree *head_tree = NULL;
+	git_index *index_repo = NULL;
+	git_iterator *iter_repo = NULL, *iter_new = NULL;
+	git_diff *staged_diff_list = NULL, *index_diff_list = NULL;
+	git_diff_delta *delta;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_vector staged_paths = GIT_VECTOR_INIT;
+	size_t i;
+	int error = 0;
+
+	GIT_UNUSED(merged_paths);
+
+	*conflicts = 0;
+
+	/* No staged changes may exist unless the change staged is identical to
+	 * the result of the merge.  This allows one to apply to merge manually,
+	 * then run merge.  Any other staged change would be overwritten by
+	 * a reset merge.
+	 */
+	if ((error = git_repository_head_tree(&head_tree, repo)) < 0 ||
+		(error = git_repository_index(&index_repo, repo)) < 0 ||
+		(error = git_diff_tree_to_index(&staged_diff_list, repo, head_tree, index_repo, &opts)) < 0)
+		goto done;
+
+	if (staged_diff_list->deltas.length == 0)
+		goto done;
+
+	git_vector_foreach(&staged_diff_list->deltas, i, delta) {
+		if ((error = git_vector_insert(&staged_paths, (char *)delta->new_file.path)) < 0)
+			goto done;
+	}
+
+	opts.pathspec.count = staged_paths.length;
+	opts.pathspec.strings = (char **)staged_paths.contents;
+
+	if ((error = git_iterator_for_index(&iter_repo, index_repo, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
+		(error = git_iterator_for_index(&iter_new, index_new, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
+		(error = git_diff__from_iterators(&index_diff_list, repo, iter_repo, iter_new, &opts)) < 0)
+		goto done;
+
+	*conflicts = index_diff_list->deltas.length;
+
+done:
+	git_tree_free(head_tree);
+	git_index_free(index_repo);
+	git_iterator_free(iter_repo);
+	git_iterator_free(iter_new);
+	git_diff_free(staged_diff_list);
+	git_diff_free(index_diff_list);
+	git_vector_free(&staged_paths);
+
+	return error;
+}
+
+static int merge_check_workdir(size_t *conflicts, git_repository *repo, git_index *index_new, git_vector *merged_paths)
+{
+	git_diff *wd_diff_list = NULL;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	int error = 0;
+
+	GIT_UNUSED(index_new);
+
+	*conflicts = 0;
+
+	/* We need to have merged at least 1 file for the possibility to exist to
+	 * have conflicts with the workdir. Passing 0 as the pathspec count paramter
+	 * will consider all files in the working directory, that is, we may detect
+	 * a conflict if there were untracked files in the workdir prior to starting
+	 * the merge. This typically happens when cherry-picking a commmit whose
+	 * changes have already been applied.
+	 */
+	if (merged_paths->length == 0)
+		return 0;
+
+	opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED;
+
+	/* Workdir changes may exist iff they do not conflict with changes that
+	 * will be applied by the merge (including conflicts).  Ensure that there
+	 * are no changes in the workdir to these paths.
+	 */
+	opts.pathspec.count = merged_paths->length;
+	opts.pathspec.strings = (char **)merged_paths->contents;
+
+	if ((error = git_diff_index_to_workdir(&wd_diff_list, repo, NULL, &opts)) < 0)
+		goto done;
+
+	*conflicts = wd_diff_list->deltas.length;
+
+done:
+	git_diff_free(wd_diff_list);
+
+	return error;
+}
+
+int git_merge__check_result(git_repository *repo, git_index *index_new)
+{
+	git_tree *head_tree = NULL;
+	git_iterator *iter_head = NULL, *iter_new = NULL;
+	git_diff *merged_list = NULL;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_delta *delta;
+	git_vector paths = GIT_VECTOR_INIT;
+	size_t i, index_conflicts = 0, wd_conflicts = 0, conflicts;
+	const git_index_entry *e;
+	int error = 0;
+
+	if ((error = git_repository_head_tree(&head_tree, repo)) < 0 ||
+		(error = git_iterator_for_tree(&iter_head, head_tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
+		(error = git_iterator_for_index(&iter_new, index_new, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
+		(error = git_diff__from_iterators(&merged_list, repo, iter_head, iter_new, &opts)) < 0)
+		goto done;
+
+	git_vector_foreach(&merged_list->deltas, i, delta) {
+		if ((error = git_vector_insert(&paths, (char *)delta->new_file.path)) < 0)
+			goto done;
+	}
+
+	for (i = 0; i < git_index_entrycount(index_new); i++) {
+		e = git_index_get_byindex(index_new, i);
+
+		if (git_index_entry_is_conflict(e) &&
+			(git_vector_last(&paths) == NULL ||
+			strcmp(git_vector_last(&paths), e->path) != 0)) {
+
+			if ((error = git_vector_insert(&paths, (char *)e->path)) < 0)
+				goto done;
+		}
+	}
+
+	/* Make sure the index and workdir state do not prevent merging */
+	if ((error = merge_check_index(&index_conflicts, repo, index_new, &paths)) < 0 ||
+		(error = merge_check_workdir(&wd_conflicts, repo, index_new, &paths)) < 0)
+		goto done;
+
+	if ((conflicts = index_conflicts + wd_conflicts) > 0) {
+		giterr_set(GITERR_MERGE, "%" PRIuZ " uncommitted change%s would be overwritten by merge",
+			conflicts, (conflicts != 1) ? "s" : "");
+		error = GIT_ECONFLICT;
+	}
+
+done:
+	git_vector_free(&paths);
+	git_tree_free(head_tree);
+	git_iterator_free(iter_head);
+	git_iterator_free(iter_new);
+	git_diff_free(merged_list);
+
+	return error;
+}
+
+int git_merge__append_conflicts_to_merge_msg(
+	git_repository *repo,
+	git_index *index)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	git_buf file_path = GIT_BUF_INIT;
+	const char *last = NULL;
+	size_t i;
+	int error;
+
+	if (!git_index_has_conflicts(index))
+		return 0;
+
+	if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_MSG_FILE)) < 0 ||
+		(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_APPEND, GIT_MERGE_FILE_MODE)) < 0)
+		goto cleanup;
+
+	git_filebuf_printf(&file, "\nConflicts:\n");
+
+	for (i = 0; i < git_index_entrycount(index); i++) {
+		const git_index_entry *e = git_index_get_byindex(index, i);
+
+		if (!git_index_entry_is_conflict(e))
+			continue;
+
+		if (last == NULL || strcmp(e->path, last) != 0)
+			git_filebuf_printf(&file, "\t%s\n", e->path);
+
+		last = e->path;
+	}
+
+	error = git_filebuf_commit(&file);
+
+cleanup:
+	if (error < 0)
+		git_filebuf_cleanup(&file);
+
+	git_buf_free(&file_path);
+
+	return error;
+}
+
+static int merge_state_cleanup(git_repository *repo)
+{
+	const char *state_files[] = {
+		GIT_MERGE_HEAD_FILE,
+		GIT_MERGE_MODE_FILE,
+		GIT_MERGE_MSG_FILE,
+	};
+
+	return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files));
+}
+
+static int merge_heads(
+	git_annotated_commit **ancestor_head_out,
+	git_annotated_commit **our_head_out,
+	git_repository *repo,
+	const git_annotated_commit **their_heads,
+	size_t their_heads_len)
+{
+	git_annotated_commit *ancestor_head = NULL, *our_head = NULL;
+	git_reference *our_ref = NULL;
+	int error = 0;
+
+	*ancestor_head_out = NULL;
+	*our_head_out = NULL;
+
+	if ((error = git_repository__ensure_not_bare(repo, "merge")) < 0)
+		goto done;
+
+	if ((error = git_reference_lookup(&our_ref, repo, GIT_HEAD_FILE)) < 0 ||
+		(error = git_annotated_commit_from_ref(&our_head, repo, our_ref)) < 0)
+		goto done;
+
+	if ((error = merge_ancestor_head(&ancestor_head, repo, our_head, their_heads, their_heads_len)) < 0) {
+		if (error != GIT_ENOTFOUND)
+			goto done;
+
+		giterr_clear();
+		error = 0;
+	}
+
+	*ancestor_head_out = ancestor_head;
+	*our_head_out = our_head;
+
+done:
+	if (error < 0) {
+		git_annotated_commit_free(ancestor_head);
+		git_annotated_commit_free(our_head);
+	}
+
+	git_reference_free(our_ref);
+
+	return error;
+}
+
+static int merge_preference(git_merge_preference_t *out, git_repository *repo)
+{
+	git_config *config;
+	const char *value;
+	int bool_value, error = 0;
+
+	*out = GIT_MERGE_PREFERENCE_NONE;
+
+	if ((error = git_repository_config_snapshot(&config, repo)) < 0)
+		goto done;
+
+	if ((error = git_config_get_string(&value, config, "merge.ff")) < 0) {
+		if (error == GIT_ENOTFOUND) {
+			giterr_clear();
+			error = 0;
+		}
+
+		goto done;
+	}
+
+	if (git_config_parse_bool(&bool_value, value) == 0) {
+		if (!bool_value)
+			*out |= GIT_MERGE_PREFERENCE_NO_FASTFORWARD;
+	} else {
+		if (strcasecmp(value, "only") == 0)
+			*out |= GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY;
+	}
+
+done:
+	git_config_free(config);
+	return error;
+}
+
+int git_merge_analysis(
+	git_merge_analysis_t *analysis_out,
+	git_merge_preference_t *preference_out,
+	git_repository *repo,
+	const git_annotated_commit **their_heads,
+	size_t their_heads_len)
+{
+	git_annotated_commit *ancestor_head = NULL, *our_head = NULL;
+	int error = 0;
+
+	assert(analysis_out && preference_out && repo && their_heads);
+
+	if (their_heads_len != 1) {
+		giterr_set(GITERR_MERGE, "Can only merge a single branch");
+		error = -1;
+		goto done;
+	}
+
+	*analysis_out = GIT_MERGE_ANALYSIS_NONE;
+
+	if ((error = merge_preference(preference_out, repo)) < 0)
+		goto done;
+
+	if (git_repository_head_unborn(repo)) {
+		*analysis_out |= GIT_MERGE_ANALYSIS_FASTFORWARD | GIT_MERGE_ANALYSIS_UNBORN;
+		goto done;
+	}
+
+	if ((error = merge_heads(&ancestor_head, &our_head, repo, their_heads, their_heads_len)) < 0)
+		goto done;
+
+	/* We're up-to-date if we're trying to merge our own common ancestor. */
+	if (ancestor_head && git_oid_equal(
+		git_annotated_commit_id(ancestor_head), git_annotated_commit_id(their_heads[0])))
+		*analysis_out |= GIT_MERGE_ANALYSIS_UP_TO_DATE;
+
+	/* We're fastforwardable if we're our own common ancestor. */
+	else if (ancestor_head && git_oid_equal(
+		git_annotated_commit_id(ancestor_head), git_annotated_commit_id(our_head)))
+		*analysis_out |= GIT_MERGE_ANALYSIS_FASTFORWARD | GIT_MERGE_ANALYSIS_NORMAL;
+
+	/* Otherwise, just a normal merge is possible. */
+	else
+		*analysis_out |= GIT_MERGE_ANALYSIS_NORMAL;
+
+done:
+	git_annotated_commit_free(ancestor_head);
+	git_annotated_commit_free(our_head);
+	return error;
+}
+
+int git_merge(
+	git_repository *repo,
+	const git_annotated_commit **their_heads,
+	size_t their_heads_len,
+	const git_merge_options *merge_opts,
+	const git_checkout_options *given_checkout_opts)
+{
+	git_reference *our_ref = NULL;
+	git_checkout_options checkout_opts;
+	git_annotated_commit *ancestor_head = NULL, *our_head = NULL;
+	git_tree *ancestor_tree = NULL, *our_tree = NULL, **their_trees = NULL;
+	git_index *index = NULL;
+	git_indexwriter indexwriter = GIT_INDEXWRITER_INIT;
+	size_t i;
+	int error = 0;
+
+	assert(repo && their_heads);
+
+	if (their_heads_len != 1) {
+		giterr_set(GITERR_MERGE, "Can only merge a single branch");
+		return -1;
+	}
+
+	their_trees = git__calloc(their_heads_len, sizeof(git_tree *));
+	GITERR_CHECK_ALLOC(their_trees);
+
+	if ((error = merge_heads(&ancestor_head, &our_head, repo, their_heads, their_heads_len)) < 0 ||
+		(error = merge_normalize_checkout_opts(repo, &checkout_opts, given_checkout_opts,
+			ancestor_head, our_head, their_heads_len, their_heads)) < 0 ||
+		(error = git_indexwriter_init_for_operation(&indexwriter, repo, &checkout_opts.checkout_strategy)) < 0)
+		goto on_error;
+
+	/* Write the merge files to the repository. */
+	if ((error = git_merge__setup(repo, our_head, their_heads, their_heads_len)) < 0)
+		goto on_error;
+
+	if (ancestor_head != NULL &&
+		(error = git_commit_tree(&ancestor_tree, ancestor_head->commit)) < 0)
+			goto on_error;
+
+	if ((error = git_commit_tree(&our_tree, our_head->commit)) < 0)
+		goto on_error;
+
+	for (i = 0; i < their_heads_len; i++) {
+		if ((error = git_commit_tree(&their_trees[i], their_heads[i]->commit)) < 0)
+			goto on_error;
+	}
+
+	/* TODO: recursive, octopus, etc... */
+
+	if ((error = git_merge_trees(&index, repo, ancestor_tree, our_tree, their_trees[0], merge_opts)) < 0 ||
+		(error = git_merge__check_result(repo, index)) < 0 ||
+		(error = git_merge__append_conflicts_to_merge_msg(repo, index)) < 0 ||
+		(error = git_checkout_index(repo, index, &checkout_opts)) < 0 ||
+		(error = git_indexwriter_commit(&indexwriter)) < 0)
+		goto on_error;
+
+	goto done;
+
+on_error:
+	merge_state_cleanup(repo);
+
+done:
+	git_indexwriter_cleanup(&indexwriter);
+
+	git_index_free(index);
+
+	git_tree_free(ancestor_tree);
+	git_tree_free(our_tree);
+
+	for (i = 0; i < their_heads_len; i++)
+		git_tree_free(their_trees[i]);
+
+	git__free(their_trees);
+
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(ancestor_head);
+
+	git_reference_free(our_ref);
+
+	return error;
+}
+
+int git_merge_init_options(git_merge_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_merge_options, GIT_MERGE_OPTIONS_INIT);
+	return 0;
+}
+
+int git_merge_file_init_input(git_merge_file_input *input, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		input, version, git_merge_file_input, GIT_MERGE_FILE_INPUT_INIT);
+	return 0;
+}
+
+int git_merge_file_init_options(
+	git_merge_file_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_merge_file_options, GIT_MERGE_FILE_OPTIONS_INIT);
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/merge.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/merge.h
new file mode 100755
index 0000000..3caf617
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/merge.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_merge_h__
+#define INCLUDE_merge_h__
+
+#include "vector.h"
+#include "commit_list.h"
+#include "pool.h"
+#include "iterator.h"
+
+#include "git2/merge.h"
+#include "git2/types.h"
+
+#define GIT_MERGE_MSG_FILE		"MERGE_MSG"
+#define GIT_MERGE_MODE_FILE		"MERGE_MODE"
+#define GIT_MERGE_FILE_MODE		0666
+
+#define GIT_MERGE_TREE_RENAME_THRESHOLD	50
+#define GIT_MERGE_TREE_TARGET_LIMIT		1000
+
+/** Types of changes when files are merged from branch to branch. */
+typedef enum {
+	/* No conflict - a change only occurs in one branch. */
+	GIT_MERGE_DIFF_NONE = 0,
+
+	/* Occurs when a file is modified in both branches. */
+	GIT_MERGE_DIFF_BOTH_MODIFIED = (1 << 0),
+
+	/* Occurs when a file is added in both branches. */
+	GIT_MERGE_DIFF_BOTH_ADDED = (1 << 1),
+
+	/* Occurs when a file is deleted in both branches. */
+	GIT_MERGE_DIFF_BOTH_DELETED = (1 << 2),
+
+	/* Occurs when a file is modified in one branch and deleted in the other. */
+	GIT_MERGE_DIFF_MODIFIED_DELETED = (1 << 3),
+
+	/* Occurs when a file is renamed in one branch and modified in the other. */
+	GIT_MERGE_DIFF_RENAMED_MODIFIED = (1 << 4),
+
+	/* Occurs when a file is renamed in one branch and deleted in the other. */
+	GIT_MERGE_DIFF_RENAMED_DELETED = (1 << 5),
+
+	/* Occurs when a file is renamed in one branch and a file with the same
+	 * name is added in the other.  Eg, A->B and new file B.  Core git calls
+	 * this a "rename/delete". */
+	GIT_MERGE_DIFF_RENAMED_ADDED = (1 << 6),
+
+	/* Occurs when both a file is renamed to the same name in the ours and
+	 * theirs branches.  Eg, A->B and A->B in both.  Automergeable. */
+	GIT_MERGE_DIFF_BOTH_RENAMED = (1 << 7),
+
+	/* Occurs when a file is renamed to different names in the ours and theirs
+	 * branches.  Eg, A->B and A->C. */
+	GIT_MERGE_DIFF_BOTH_RENAMED_1_TO_2 = (1 << 8),
+
+	/* Occurs when two files are renamed to the same name in the ours and
+	 * theirs branches.  Eg, A->C and B->C. */
+	GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1 = (1 << 9),
+
+	/* Occurs when an item at a path in one branch is a directory, and an
+	 * item at the same path in a different branch is a file. */
+	GIT_MERGE_DIFF_DIRECTORY_FILE = (1 << 10),
+
+	/* The child of a folder that is in a directory/file conflict. */
+	GIT_MERGE_DIFF_DF_CHILD = (1 << 11),
+} git_merge_diff_type_t;
+
+
+typedef struct {
+	git_repository *repo;
+	git_pool pool;
+
+	/* Vector of git_index_entry that represent the merged items that
+	 * have been staged, either because only one side changed, or because
+	 * the two changes were non-conflicting and mergeable.  These items
+	 * will be written as staged entries in the main index.
+	 */
+	git_vector staged;
+
+	/* Vector of git_merge_diff entries that represent the conflicts that
+	 * have not been automerged.  These items will be written to high-stage
+	 * entries in the main index.
+	 */
+	git_vector conflicts;
+
+	/* Vector of git_merge_diff that have been automerged.  These items
+	 * will be written to the REUC when the index is produced.
+	 */
+	git_vector resolved;
+} git_merge_diff_list;
+
+/**
+ * Description of changes to one file across three trees.
+ */
+typedef struct {
+	git_merge_diff_type_t type;
+
+	git_index_entry ancestor_entry;
+
+	git_index_entry our_entry;
+	git_delta_t our_status;
+
+	git_index_entry their_entry;
+	git_delta_t their_status;
+
+} git_merge_diff;
+
+int git_merge__bases_many(
+	git_commit_list **out,
+	git_revwalk *walk,
+	git_commit_list_node *one,
+	git_vector *twos);
+
+/*
+ * Three-way tree differencing
+ */
+
+git_merge_diff_list *git_merge_diff_list__alloc(git_repository *repo);
+
+int git_merge_diff_list__find_differences(
+	git_merge_diff_list *merge_diff_list,
+	git_iterator *ancestor_iterator,
+	git_iterator *ours_iter,
+	git_iterator *theirs_iter);
+
+int git_merge_diff_list__find_renames(git_repository *repo, git_merge_diff_list *merge_diff_list, const git_merge_options *opts);
+
+void git_merge_diff_list__free(git_merge_diff_list *diff_list);
+
+/* Merge metadata setup */
+
+int git_merge__setup(
+	git_repository *repo,
+	const git_annotated_commit *our_head,
+	const git_annotated_commit *heads[],
+	size_t heads_len);
+
+int git_merge__iterators(
+	git_index **out,
+	git_repository *repo,
+	git_iterator *ancestor_iter,
+	git_iterator *our_iter,
+	git_iterator *their_iter,
+	const git_merge_options *given_opts);
+
+int git_merge__check_result(git_repository *repo, git_index *index_new);
+
+int git_merge__append_conflicts_to_merge_msg(git_repository *repo, git_index *index);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/merge_file.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/merge_file.c
new file mode 100755
index 0000000..6d47380
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/merge_file.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "repository.h"
+#include "posix.h"
+#include "fileops.h"
+#include "index.h"
+#include "diff_xdiff.h"
+
+#include "git2/repository.h"
+#include "git2/object.h"
+#include "git2/index.h"
+#include "git2/merge.h"
+
+#include "xdiff/xdiff.h"
+
+/* only examine the first 8000 bytes for binaryness.
+ * https://github.com/git/git/blob/77bd3ea9f54f1584147b594abc04c26ca516d987/xdiff-interface.c#L197
+ */
+#define GIT_MERGE_FILE_BINARY_SIZE 8000
+
+#define GIT_MERGE_FILE_SIDE_EXISTS(X)	((X)->mode != 0)
+
+GIT_INLINE(const char *) merge_file_best_path(
+	const git_merge_file_input *ancestor,
+	const git_merge_file_input *ours,
+	const git_merge_file_input *theirs)
+{
+	if (!ancestor) {
+		if (ours && theirs && strcmp(ours->path, theirs->path) == 0)
+			return ours->path;
+
+		return NULL;
+	}
+
+	if (ours && strcmp(ancestor->path, ours->path) == 0)
+		return theirs ? theirs->path : NULL;
+	else if(theirs && strcmp(ancestor->path, theirs->path) == 0)
+		return ours ? ours->path : NULL;
+
+	return NULL;
+}
+
+GIT_INLINE(int) merge_file_best_mode(
+	const git_merge_file_input *ancestor,
+	const git_merge_file_input *ours,
+	const git_merge_file_input *theirs)
+{
+	/*
+	 * If ancestor didn't exist and either ours or theirs is executable,
+	 * assume executable.  Otherwise, if any mode changed from the ancestor,
+	 * use that one.
+	 */
+	if (!ancestor) {
+		if ((ours && ours->mode == GIT_FILEMODE_BLOB_EXECUTABLE) ||
+			(theirs && theirs->mode == GIT_FILEMODE_BLOB_EXECUTABLE))
+			return GIT_FILEMODE_BLOB_EXECUTABLE;
+
+		return GIT_FILEMODE_BLOB;
+	} else if (ours && theirs) {
+		if (ancestor->mode == ours->mode)
+			return theirs->mode;
+
+		return ours->mode;
+	}
+
+	return 0;
+}
+
+int git_merge_file__input_from_index(
+	git_merge_file_input *input_out,
+	git_odb_object **odb_object_out,
+	git_odb *odb,
+	const git_index_entry *entry)
+{
+	int error = 0;
+
+	assert(input_out && odb_object_out && odb && entry);
+
+	if ((error = git_odb_read(odb_object_out, odb, &entry->id)) < 0)
+		goto done;
+
+	input_out->path = entry->path;
+	input_out->mode = entry->mode;
+	input_out->ptr = (char *)git_odb_object_data(*odb_object_out);
+	input_out->size = git_odb_object_size(*odb_object_out);
+
+done:
+	return error;
+}
+
+static void merge_file_normalize_opts(
+	git_merge_file_options *out,
+	const git_merge_file_options *given_opts)
+{
+	if (given_opts)
+		memcpy(out, given_opts, sizeof(git_merge_file_options));
+	else {
+		git_merge_file_options default_opts = GIT_MERGE_FILE_OPTIONS_INIT;
+		memcpy(out, &default_opts, sizeof(git_merge_file_options));
+	}
+}
+
+static int merge_file__xdiff(
+	git_merge_file_result *out,
+	const git_merge_file_input *ancestor,
+	const git_merge_file_input *ours,
+	const git_merge_file_input *theirs,
+	const git_merge_file_options *given_opts)
+{
+	xmparam_t xmparam;
+	mmfile_t ancestor_mmfile = {0}, our_mmfile = {0}, their_mmfile = {0};
+	mmbuffer_t mmbuffer;
+	git_merge_file_options options = GIT_MERGE_FILE_OPTIONS_INIT;
+	const char *path;
+	int xdl_result;
+	int error = 0;
+
+	memset(out, 0x0, sizeof(git_merge_file_result));
+
+	merge_file_normalize_opts(&options, given_opts);
+
+	memset(&xmparam, 0x0, sizeof(xmparam_t));
+
+	if (ancestor) {
+		xmparam.ancestor = (options.ancestor_label) ?
+			options.ancestor_label : ancestor->path;
+		ancestor_mmfile.ptr = (char *)ancestor->ptr;
+		ancestor_mmfile.size = ancestor->size;
+	}
+
+	xmparam.file1 = (options.our_label) ?
+		options.our_label : ours->path;
+	our_mmfile.ptr = (char *)ours->ptr;
+	our_mmfile.size = ours->size;
+
+	xmparam.file2 = (options.their_label) ?
+		options.their_label : theirs->path;
+	their_mmfile.ptr = (char *)theirs->ptr;
+	their_mmfile.size = theirs->size;
+
+	if (options.favor == GIT_MERGE_FILE_FAVOR_OURS)
+		xmparam.favor = XDL_MERGE_FAVOR_OURS;
+	else if (options.favor == GIT_MERGE_FILE_FAVOR_THEIRS)
+		xmparam.favor = XDL_MERGE_FAVOR_THEIRS;
+	else if (options.favor == GIT_MERGE_FILE_FAVOR_UNION)
+		xmparam.favor = XDL_MERGE_FAVOR_UNION;
+
+	xmparam.level = (options.flags & GIT_MERGE_FILE_SIMPLIFY_ALNUM) ?
+		XDL_MERGE_ZEALOUS_ALNUM : XDL_MERGE_ZEALOUS;
+
+	if (options.flags & GIT_MERGE_FILE_STYLE_DIFF3)
+		xmparam.style = XDL_MERGE_DIFF3;
+
+	if (options.flags & GIT_MERGE_FILE_IGNORE_WHITESPACE)
+		xmparam.xpp.flags |= XDF_IGNORE_WHITESPACE;
+	if (options.flags & GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE)
+		xmparam.xpp.flags |= XDF_IGNORE_WHITESPACE_CHANGE;
+	if (options.flags & GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL)
+		xmparam.xpp.flags |= XDF_IGNORE_WHITESPACE_AT_EOL;
+
+	if (options.flags & GIT_MERGE_FILE_DIFF_PATIENCE)
+		xmparam.xpp.flags |= XDF_PATIENCE_DIFF;
+
+	if (options.flags & GIT_MERGE_FILE_DIFF_MINIMAL)
+		xmparam.xpp.flags |= XDF_NEED_MINIMAL;
+
+	if ((xdl_result = xdl_merge(&ancestor_mmfile, &our_mmfile,
+		&their_mmfile, &xmparam, &mmbuffer)) < 0) {
+		giterr_set(GITERR_MERGE, "Failed to merge files.");
+		error = -1;
+		goto done;
+	}
+
+	if ((path = merge_file_best_path(ancestor, ours, theirs)) != NULL &&
+		(out->path = strdup(path)) == NULL) {
+		error = -1;
+		goto done;
+	}
+
+	out->automergeable = (xdl_result == 0);
+	out->ptr = (const char *)mmbuffer.ptr;
+	out->len = mmbuffer.size;
+	out->mode = merge_file_best_mode(ancestor, ours, theirs);
+
+done:
+	if (error < 0)
+		git_merge_file_result_free(out);
+
+	return error;
+}
+
+static bool merge_file__is_binary(const git_merge_file_input *file)
+{
+	size_t len = file ? file->size : 0;
+
+	if (len > GIT_XDIFF_MAX_SIZE)
+		return true;
+	if (len > GIT_MERGE_FILE_BINARY_SIZE)
+		len = GIT_MERGE_FILE_BINARY_SIZE;
+
+	return len ? (memchr(file->ptr, 0, len) != NULL) : false;
+}
+
+static int merge_file__binary(
+	git_merge_file_result *out,
+	const git_merge_file_input *ours,
+	const git_merge_file_input *theirs,
+	const git_merge_file_options *given_opts)
+{
+	const git_merge_file_input *favored = NULL;
+
+	memset(out, 0x0, sizeof(git_merge_file_result));
+
+	if (given_opts && given_opts->favor == GIT_MERGE_FILE_FAVOR_OURS)
+		favored = ours;
+	else if (given_opts && given_opts->favor == GIT_MERGE_FILE_FAVOR_THEIRS)
+		favored = theirs;
+	else
+		goto done;
+
+	if ((out->path = git__strdup(favored->path)) == NULL ||
+		(out->ptr = git__malloc(favored->size)) == NULL)
+		goto done;
+
+	memcpy((char *)out->ptr, favored->ptr, favored->size);
+	out->len = favored->size;
+	out->mode = favored->mode;
+	out->automergeable = 1;
+
+done:
+	return 0;
+}
+
+static int merge_file__from_inputs(
+	git_merge_file_result *out,
+	const git_merge_file_input *ancestor,
+	const git_merge_file_input *ours,
+	const git_merge_file_input *theirs,
+	const git_merge_file_options *given_opts)
+{
+	if (merge_file__is_binary(ancestor) ||
+		merge_file__is_binary(ours) ||
+		merge_file__is_binary(theirs))
+		return merge_file__binary(out, ours, theirs, given_opts);
+
+	return merge_file__xdiff(out, ancestor, ours, theirs, given_opts);
+}
+
+static git_merge_file_input *git_merge_file__normalize_inputs(
+	git_merge_file_input *out,
+	const git_merge_file_input *given)
+{
+	memcpy(out, given, sizeof(git_merge_file_input));
+
+	if (!out->path)
+		out->path = "file.txt";
+
+	if (!out->mode)
+		out->mode = 0100644;
+
+	return out;
+}
+
+int git_merge_file(
+	git_merge_file_result *out,
+	const git_merge_file_input *ancestor,
+	const git_merge_file_input *ours,
+	const git_merge_file_input *theirs,
+	const git_merge_file_options *options)
+{
+	git_merge_file_input inputs[3] = { {0} };
+
+	assert(out && ours && theirs);
+
+	memset(out, 0x0, sizeof(git_merge_file_result));
+
+	if (ancestor)
+		ancestor = git_merge_file__normalize_inputs(&inputs[0], ancestor);
+
+	ours = git_merge_file__normalize_inputs(&inputs[1], ours);
+	theirs = git_merge_file__normalize_inputs(&inputs[2], theirs);
+
+	return merge_file__from_inputs(out, ancestor, ours, theirs, options);
+}
+
+int git_merge_file_from_index(
+	git_merge_file_result *out,
+	git_repository *repo,
+	const git_index_entry *ancestor,
+	const git_index_entry *ours,
+	const git_index_entry *theirs,
+	const git_merge_file_options *options)
+{
+	git_merge_file_input *ancestor_ptr = NULL,
+		ancestor_input = {0}, our_input = {0}, their_input = {0};
+	git_odb *odb = NULL;
+	git_odb_object *odb_object[3] = { 0 };
+	int error = 0;
+
+	assert(out && repo && ours && theirs);
+
+	memset(out, 0x0, sizeof(git_merge_file_result));
+
+	if ((error = git_repository_odb(&odb, repo)) < 0)
+		goto done;
+
+	if (ancestor) {
+		if ((error = git_merge_file__input_from_index(
+			&ancestor_input, &odb_object[0], odb, ancestor)) < 0)
+			goto done;
+
+		ancestor_ptr = &ancestor_input;
+	}
+
+	if ((error = git_merge_file__input_from_index(
+			&our_input, &odb_object[1], odb, ours)) < 0 ||
+		(error = git_merge_file__input_from_index(
+			&their_input, &odb_object[2], odb, theirs)) < 0)
+		goto done;
+
+	error = merge_file__from_inputs(out,
+		ancestor_ptr, &our_input, &their_input, options);
+
+done:
+	git_odb_object_free(odb_object[0]);
+	git_odb_object_free(odb_object[1]);
+	git_odb_object_free(odb_object[2]);
+	git_odb_free(odb);
+
+	return error;
+}
+
+void git_merge_file_result_free(git_merge_file_result *result)
+{
+	if (result == NULL)
+		return;
+
+	git__free((char *)result->path);
+	git__free((char *)result->ptr);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/message.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/message.c
new file mode 100755
index 0000000..6c5a237
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/message.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "message.h"
+
+static size_t line_length_without_trailing_spaces(const char *line, size_t len)
+{
+	while (len) {
+		unsigned char c = line[len - 1];
+		if (!git__isspace(c))
+			break;
+		len--;
+	}
+
+	return len;
+}
+
+/* Greatly inspired from git.git "stripspace" */
+/* see https://github.com/git/git/blob/497215d8811ac7b8955693ceaad0899ecd894ed2/builtin/stripspace.c#L4-67 */
+int git_message_prettify(git_buf *message_out, const char *message, int strip_comments, char comment_char)
+{
+	const size_t message_len = strlen(message);
+
+	int consecutive_empty_lines = 0;
+	size_t i, line_length, rtrimmed_line_length;
+	char *next_newline;
+
+	git_buf_sanitize(message_out);
+
+	for (i = 0; i < strlen(message); i += line_length) {
+		next_newline = memchr(message + i, '\n', message_len - i);
+
+		if (next_newline != NULL) {
+			line_length = next_newline - (message + i) + 1;
+		} else {
+			line_length = message_len - i;
+		}
+
+		if (strip_comments && line_length && message[i] == comment_char)
+			continue;
+
+		rtrimmed_line_length = line_length_without_trailing_spaces(message + i, line_length);
+
+		if (!rtrimmed_line_length) {
+			consecutive_empty_lines++;
+			continue;
+		}
+
+		if (consecutive_empty_lines > 0 && message_out->size > 0)
+			git_buf_putc(message_out, '\n');
+
+		consecutive_empty_lines = 0;
+		git_buf_put(message_out, message + i, rtrimmed_line_length);
+		git_buf_putc(message_out, '\n');
+	}
+
+	return git_buf_oom(message_out) ? -1 : 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/message.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/message.h
new file mode 100755
index 0000000..3c4b8dc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/message.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_message_h__
+#define INCLUDE_message_h__
+
+#include "git2/message.h"
+#include "buffer.h"
+
+int git_message__prettify(git_buf *message_out, const char *message, int strip_comments);
+
+#endif /* INCLUDE_message_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/mwindow.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/mwindow.c
new file mode 100755
index 0000000..55c8d89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/mwindow.c
@@ -0,0 +1,430 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "mwindow.h"
+#include "vector.h"
+#include "fileops.h"
+#include "map.h"
+#include "global.h"
+#include "strmap.h"
+#include "pack.h"
+
+GIT__USE_STRMAP
+
+#define DEFAULT_WINDOW_SIZE \
+	(sizeof(void*) >= 8 \
+		? 1 * 1024 * 1024 * 1024 \
+		: 32 * 1024 * 1024)
+
+#define DEFAULT_MAPPED_LIMIT \
+	((1024 * 1024) * (sizeof(void*) >= 8 ? 8192ULL : 256UL))
+
+size_t git_mwindow__window_size = DEFAULT_WINDOW_SIZE;
+size_t git_mwindow__mapped_limit = DEFAULT_MAPPED_LIMIT;
+
+/* Whenever you want to read or modify this, grab git__mwindow_mutex */
+static git_mwindow_ctl mem_ctl;
+
+/* Global list of mwindow files, to open packs once across repos */
+git_strmap *git__pack_cache = NULL;
+
+/**
+ * Run under mwindow lock
+ */
+int git_mwindow_files_init(void)
+{
+	if (git__pack_cache)
+		return 0;
+
+	git__on_shutdown(git_mwindow_files_free);
+
+	return git_strmap_alloc(&git__pack_cache);
+}
+
+void git_mwindow_files_free(void)
+{
+	git_strmap *tmp = git__pack_cache;
+
+	git__pack_cache = NULL;
+	git_strmap_free(tmp);
+}
+
+int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
+{
+	int error;
+	char *packname;
+	git_strmap_iter pos;
+	struct git_pack_file *pack;
+
+	if ((error = git_packfile__name(&packname, path)) < 0)
+		return error;
+
+	if (git_mutex_lock(&git__mwindow_mutex) < 0) {
+		giterr_set(GITERR_OS, "failed to lock mwindow mutex");
+		return -1;
+	}
+
+	if (git_mwindow_files_init() < 0) {
+		git_mutex_unlock(&git__mwindow_mutex);
+		git__free(packname);
+		return -1;
+	}
+
+	pos = git_strmap_lookup_index(git__pack_cache, packname);
+	git__free(packname);
+
+	if (git_strmap_valid_index(git__pack_cache, pos)) {
+		pack = git_strmap_value_at(git__pack_cache, pos);
+		git_atomic_inc(&pack->refcount);
+
+		git_mutex_unlock(&git__mwindow_mutex);
+		*out = pack;
+		return 0;
+	}
+
+	/* If we didn't find it, we need to create it */
+	if ((error = git_packfile_alloc(&pack, path)) < 0) {
+		git_mutex_unlock(&git__mwindow_mutex);
+		return error;
+	}
+
+	git_atomic_inc(&pack->refcount);
+
+	git_strmap_insert(git__pack_cache, pack->pack_name, pack, error);
+	git_mutex_unlock(&git__mwindow_mutex);
+
+	if (error < 0) {
+		git_packfile_free(pack);
+		return -1;
+	}
+
+	*out = pack;
+	return 0;
+}
+
+void git_mwindow_put_pack(struct git_pack_file *pack)
+{
+	int count;
+	git_strmap_iter pos;
+
+	if (git_mutex_lock(&git__mwindow_mutex) < 0)
+		return;
+
+	/* put before get would be a corrupted state */
+	assert(git__pack_cache);
+
+	pos = git_strmap_lookup_index(git__pack_cache, pack->pack_name);
+	/* if we cannot find it, the state is corrupted */
+	assert(git_strmap_valid_index(git__pack_cache, pos));
+
+	count = git_atomic_dec(&pack->refcount);
+	if (count == 0) {
+		git_strmap_delete_at(git__pack_cache, pos);
+		git_packfile_free(pack);
+	}
+
+	git_mutex_unlock(&git__mwindow_mutex);
+	return;
+}
+
+void git_mwindow_free_all(git_mwindow_file *mwf)
+{
+	if (git_mutex_lock(&git__mwindow_mutex)) {
+		giterr_set(GITERR_THREAD, "unable to lock mwindow mutex");
+		return;
+	}
+
+	git_mwindow_free_all_locked(mwf);
+
+	git_mutex_unlock(&git__mwindow_mutex);
+}
+
+/*
+ * Free all the windows in a sequence, typically because we're done
+ * with the file
+ */
+void git_mwindow_free_all_locked(git_mwindow_file *mwf)
+{
+	git_mwindow_ctl *ctl = &mem_ctl;
+	size_t i;
+
+	/*
+	 * Remove these windows from the global list
+	 */
+	for (i = 0; i < ctl->windowfiles.length; ++i){
+		if (git_vector_get(&ctl->windowfiles, i) == mwf) {
+			git_vector_remove(&ctl->windowfiles, i);
+			break;
+		}
+	}
+
+	if (ctl->windowfiles.length == 0) {
+		git_vector_free(&ctl->windowfiles);
+		ctl->windowfiles.contents = NULL;
+	}
+
+	while (mwf->windows) {
+		git_mwindow *w = mwf->windows;
+		assert(w->inuse_cnt == 0);
+
+		ctl->mapped -= w->window_map.len;
+		ctl->open_windows--;
+
+		git_futils_mmap_free(&w->window_map);
+
+		mwf->windows = w->next;
+		git__free(w);
+	}
+}
+
+/*
+ * Check if a window 'win' contains the address 'offset'
+ */
+int git_mwindow_contains(git_mwindow *win, git_off_t offset)
+{
+	git_off_t win_off = win->offset;
+	return win_off <= offset
+		&& offset <= (git_off_t)(win_off + win->window_map.len);
+}
+
+/*
+ * Find the least-recently-used window in a file
+ */
+static void git_mwindow_scan_lru(
+	git_mwindow_file *mwf,
+	git_mwindow **lru_w,
+	git_mwindow **lru_l)
+{
+	git_mwindow *w, *w_l;
+
+	for (w_l = NULL, w = mwf->windows; w; w = w->next) {
+		if (!w->inuse_cnt) {
+			/*
+			 * If the current one is more recent than the last one,
+			 * store it in the output parameter. If lru_w is NULL,
+			 * it's the first loop, so store it as well.
+			 */
+			if (!*lru_w || w->last_used < (*lru_w)->last_used) {
+				*lru_w = w;
+				*lru_l = w_l;
+			}
+		}
+		w_l = w;
+	}
+}
+
+/*
+ * Close the least recently used window. You should check to see if
+ * the file descriptors need closing from time to time. Called under
+ * lock from new_window.
+ */
+static int git_mwindow_close_lru(git_mwindow_file *mwf)
+{
+	git_mwindow_ctl *ctl = &mem_ctl;
+	size_t i;
+	git_mwindow *lru_w = NULL, *lru_l = NULL, **list = &mwf->windows;
+
+	/* FIXME: Does this give us any advantage? */
+	if(mwf->windows)
+		git_mwindow_scan_lru(mwf, &lru_w, &lru_l);
+
+	for (i = 0; i < ctl->windowfiles.length; ++i) {
+		git_mwindow *last = lru_w;
+		git_mwindow_file *cur = git_vector_get(&ctl->windowfiles, i);
+		git_mwindow_scan_lru(cur, &lru_w, &lru_l);
+		if (lru_w != last)
+			list = &cur->windows;
+	}
+
+	if (!lru_w) {
+		giterr_set(GITERR_OS, "Failed to close memory window. Couldn't find LRU");
+		return -1;
+	}
+
+	ctl->mapped -= lru_w->window_map.len;
+	git_futils_mmap_free(&lru_w->window_map);
+
+	if (lru_l)
+		lru_l->next = lru_w->next;
+	else
+		*list = lru_w->next;
+
+	git__free(lru_w);
+	ctl->open_windows--;
+
+	return 0;
+}
+
+/* This gets called under lock from git_mwindow_open */
+static git_mwindow *new_window(
+	git_mwindow_file *mwf,
+	git_file fd,
+	git_off_t size,
+	git_off_t offset)
+{
+	git_mwindow_ctl *ctl = &mem_ctl;
+	size_t walign = git_mwindow__window_size / 2;
+	git_off_t len;
+	git_mwindow *w;
+
+	w = git__malloc(sizeof(*w));
+
+	if (w == NULL)
+		return NULL;
+
+	memset(w, 0x0, sizeof(*w));
+	w->offset = (offset / walign) * walign;
+
+	len = size - w->offset;
+	if (len > (git_off_t)git_mwindow__window_size)
+		len = (git_off_t)git_mwindow__window_size;
+
+	ctl->mapped += (size_t)len;
+
+	while (git_mwindow__mapped_limit < ctl->mapped &&
+			git_mwindow_close_lru(mwf) == 0) /* nop */;
+
+	/*
+	 * We treat `mapped_limit` as a soft limit. If we can't find a
+	 * window to close and are above the limit, we still mmap the new
+	 * window.
+	 */
+
+	if (git_futils_mmap_ro(&w->window_map, fd, w->offset, (size_t)len) < 0) {
+		git__free(w);
+		return NULL;
+	}
+
+	ctl->mmap_calls++;
+	ctl->open_windows++;
+
+	if (ctl->mapped > ctl->peak_mapped)
+		ctl->peak_mapped = ctl->mapped;
+
+	if (ctl->open_windows > ctl->peak_open_windows)
+		ctl->peak_open_windows = ctl->open_windows;
+
+	return w;
+}
+
+/*
+ * Open a new window, closing the least recenty used until we have
+ * enough space. Don't forget to add it to your list
+ */
+unsigned char *git_mwindow_open(
+	git_mwindow_file *mwf,
+	git_mwindow **cursor,
+	git_off_t offset,
+	size_t extra,
+	unsigned int *left)
+{
+	git_mwindow_ctl *ctl = &mem_ctl;
+	git_mwindow *w = *cursor;
+
+	if (git_mutex_lock(&git__mwindow_mutex)) {
+		giterr_set(GITERR_THREAD, "unable to lock mwindow mutex");
+		return NULL;
+	}
+
+	if (!w || !(git_mwindow_contains(w, offset) && git_mwindow_contains(w, offset + extra))) {
+		if (w) {
+			w->inuse_cnt--;
+		}
+
+		for (w = mwf->windows; w; w = w->next) {
+			if (git_mwindow_contains(w, offset) &&
+				git_mwindow_contains(w, offset + extra))
+				break;
+		}
+
+		/*
+		 * If there isn't a suitable window, we need to create a new
+		 * one.
+		 */
+		if (!w) {
+			w = new_window(mwf, mwf->fd, mwf->size, offset);
+			if (w == NULL) {
+				git_mutex_unlock(&git__mwindow_mutex);
+				return NULL;
+			}
+			w->next = mwf->windows;
+			mwf->windows = w;
+		}
+	}
+
+	/* If we changed w, store it in the cursor */
+	if (w != *cursor) {
+		w->last_used = ctl->used_ctr++;
+		w->inuse_cnt++;
+		*cursor = w;
+	}
+
+	offset -= w->offset;
+
+	if (left)
+		*left = (unsigned int)(w->window_map.len - offset);
+
+	git_mutex_unlock(&git__mwindow_mutex);
+	return (unsigned char *) w->window_map.data + offset;
+}
+
+int git_mwindow_file_register(git_mwindow_file *mwf)
+{
+	git_mwindow_ctl *ctl = &mem_ctl;
+	int ret;
+
+	if (git_mutex_lock(&git__mwindow_mutex)) {
+		giterr_set(GITERR_THREAD, "unable to lock mwindow mutex");
+		return -1;
+	}
+
+	if (ctl->windowfiles.length == 0 &&
+	    git_vector_init(&ctl->windowfiles, 8, NULL) < 0) {
+		git_mutex_unlock(&git__mwindow_mutex);
+		return -1;
+	}
+
+	ret = git_vector_insert(&ctl->windowfiles, mwf);
+	git_mutex_unlock(&git__mwindow_mutex);
+
+	return ret;
+}
+
+void git_mwindow_file_deregister(git_mwindow_file *mwf)
+{
+	git_mwindow_ctl *ctl = &mem_ctl;
+	git_mwindow_file *cur;
+	size_t i;
+
+	if (git_mutex_lock(&git__mwindow_mutex))
+		return;
+
+	git_vector_foreach(&ctl->windowfiles, i, cur) {
+		if (cur == mwf) {
+			git_vector_remove(&ctl->windowfiles, i);
+			git_mutex_unlock(&git__mwindow_mutex);
+			return;
+		}
+	}
+	git_mutex_unlock(&git__mwindow_mutex);
+}
+
+void git_mwindow_close(git_mwindow **window)
+{
+	git_mwindow *w = *window;
+	if (w) {
+		if (git_mutex_lock(&git__mwindow_mutex)) {
+			giterr_set(GITERR_THREAD, "unable to lock mwindow mutex");
+			return;
+		}
+
+		w->inuse_cnt--;
+		git_mutex_unlock(&git__mwindow_mutex);
+		*window = NULL;
+	}
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/mwindow.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/mwindow.h
new file mode 100755
index 0000000..63418e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/mwindow.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_mwindow__
+#define INCLUDE_mwindow__
+
+#include "map.h"
+#include "vector.h"
+
+typedef struct git_mwindow {
+	struct git_mwindow *next;
+	git_map window_map;
+	git_off_t offset;
+	size_t last_used;
+	size_t inuse_cnt;
+} git_mwindow;
+
+typedef struct git_mwindow_file {
+	git_mwindow *windows;
+	int fd;
+	git_off_t size;
+} git_mwindow_file;
+
+typedef struct git_mwindow_ctl {
+	size_t mapped;
+	unsigned int open_windows;
+	unsigned int mmap_calls;
+	unsigned int peak_open_windows;
+	size_t peak_mapped;
+	size_t used_ctr;
+	git_vector windowfiles;
+} git_mwindow_ctl;
+
+int git_mwindow_contains(git_mwindow *win, git_off_t offset);
+void git_mwindow_free_all(git_mwindow_file *mwf); /* locks */
+void git_mwindow_free_all_locked(git_mwindow_file *mwf); /* run under lock */
+unsigned char *git_mwindow_open(git_mwindow_file *mwf, git_mwindow **cursor, git_off_t offset, size_t extra, unsigned int *left);
+int git_mwindow_file_register(git_mwindow_file *mwf);
+void git_mwindow_file_deregister(git_mwindow_file *mwf);
+void git_mwindow_close(git_mwindow **w_cursor);
+
+int git_mwindow_files_init(void);
+void git_mwindow_files_free(void);
+
+struct git_pack_file; /* just declaration to avoid cyclical includes */
+int git_mwindow_get_pack(struct git_pack_file **out, const char *path);
+void git_mwindow_put_pack(struct git_pack_file *pack);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/netops.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/netops.c
new file mode 100755
index 0000000..5e80755
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/netops.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include <ctype.h>
+#include "git2/errors.h"
+
+#include "common.h"
+#include "netops.h"
+#include "posix.h"
+#include "buffer.h"
+#include "http_parser.h"
+#include "global.h"
+
+int gitno_recv(gitno_buffer *buf)
+{
+	return buf->recv(buf);
+}
+
+void gitno_buffer_setup_callback(
+	gitno_buffer *buf,
+	char *data,
+	size_t len,
+	int (*recv)(gitno_buffer *buf), void *cb_data)
+{
+	memset(data, 0x0, len);
+	buf->data = data;
+	buf->len = len;
+	buf->offset = 0;
+	buf->recv = recv;
+	buf->cb_data = cb_data;
+}
+
+static int recv_stream(gitno_buffer *buf)
+{
+	git_stream *io = (git_stream *) buf->cb_data;
+	int ret;
+
+	ret = git_stream_read(io, buf->data + buf->offset, buf->len - buf->offset);
+	if (ret < 0)
+		return -1;
+
+	buf->offset += ret;
+	return ret;
+}
+
+void gitno_buffer_setup_fromstream(git_stream *st, gitno_buffer *buf, char *data, size_t len)
+{
+	memset(data, 0x0, len);
+	buf->data = data;
+	buf->len = len;
+	buf->offset = 0;
+	buf->recv = recv_stream;
+	buf->cb_data = st;
+}
+
+/* Consume up to ptr and move the rest of the buffer to the beginning */
+void gitno_consume(gitno_buffer *buf, const char *ptr)
+{
+	size_t consumed;
+
+	assert(ptr - buf->data >= 0);
+	assert(ptr - buf->data <= (int) buf->len);
+
+	consumed = ptr - buf->data;
+
+	memmove(buf->data, ptr, buf->offset - consumed);
+	memset(buf->data + buf->offset, 0x0, buf->len - buf->offset);
+	buf->offset -= consumed;
+}
+
+/* Consume const bytes and move the rest of the buffer to the beginning */
+void gitno_consume_n(gitno_buffer *buf, size_t cons)
+{
+	memmove(buf->data, buf->data + cons, buf->len - buf->offset);
+	memset(buf->data + cons, 0x0, buf->len - buf->offset);
+	buf->offset -= cons;
+}
+
+/* Match host names according to RFC 2818 rules */
+int gitno__match_host(const char *pattern, const char *host)
+{
+	for (;;) {
+		char c = git__tolower(*pattern++);
+
+		if (c == '\0')
+			return *host ? -1 : 0;
+
+		if (c == '*') {
+			c = *pattern;
+			/* '*' at the end matches everything left */
+			if (c == '\0')
+				return 0;
+
+	/*
+	 * We've found a pattern, so move towards the next matching
+	 * char. The '.' is handled specially because wildcards aren't
+	 * allowed to cross subdomains.
+	 */
+
+			while(*host) {
+				char h = git__tolower(*host);
+				if (c == h)
+					return gitno__match_host(pattern, host++);
+				if (h == '.')
+					return gitno__match_host(pattern, host);
+				host++;
+			}
+			return -1;
+		}
+
+		if (c != git__tolower(*host++))
+			return -1;
+	}
+
+	return -1;
+}
+
+static const char *prefix_http = "http://";
+static const char *prefix_https = "https://";
+
+int gitno_connection_data_from_url(
+		gitno_connection_data *data,
+		const char *url,
+		const char *service_suffix)
+{
+	int error = -1;
+	const char *default_port = NULL, *path_search_start = NULL;
+	char *original_host = NULL;
+
+	/* service_suffix is optional */
+	assert(data && url);
+
+	/* Save these for comparison later */
+	original_host = data->host;
+	data->host = NULL;
+	gitno_connection_data_free_ptrs(data);
+
+	if (!git__prefixcmp(url, prefix_http)) {
+		path_search_start = url + strlen(prefix_http);
+		default_port = "80";
+
+		if (data->use_ssl) {
+			giterr_set(GITERR_NET, "Redirect from HTTPS to HTTP is not allowed");
+			goto cleanup;
+		}
+	} else if (!git__prefixcmp(url, prefix_https)) {
+		path_search_start = url + strlen(prefix_https);
+		default_port = "443";
+		data->use_ssl = true;
+	} else if (url[0] == '/')
+		default_port = data->use_ssl ? "443" : "80";
+
+	if (!default_port) {
+		giterr_set(GITERR_NET, "Unrecognized URL prefix");
+		goto cleanup;
+	}
+
+	error = gitno_extract_url_parts(
+		&data->host, &data->port, &data->path, &data->user, &data->pass,
+		url, default_port);
+
+	if (url[0] == '/') {
+		/* Relative redirect; reuse original host name and port */
+		path_search_start = url;
+		git__free(data->host);
+		data->host = original_host;
+		original_host = NULL;
+	}
+
+	if (!error) {
+		const char *path = strchr(path_search_start, '/');
+		size_t pathlen = strlen(path);
+		size_t suffixlen = service_suffix ? strlen(service_suffix) : 0;
+
+		if (suffixlen &&
+		    !memcmp(path + pathlen - suffixlen, service_suffix, suffixlen)) {
+			git__free(data->path);
+			data->path = git__strndup(path, pathlen - suffixlen);
+		} else {
+			git__free(data->path);
+			data->path = git__strdup(path);
+		}
+
+		/* Check for errors in the resulting data */
+		if (original_host && url[0] != '/' && strcmp(original_host, data->host)) {
+			giterr_set(GITERR_NET, "Cross host redirect not allowed");
+			error = -1;
+		}
+	}
+
+cleanup:
+	if (original_host) git__free(original_host);
+	return error;
+}
+
+void gitno_connection_data_free_ptrs(gitno_connection_data *d)
+{
+	git__free(d->host); d->host = NULL;
+	git__free(d->port); d->port = NULL;
+	git__free(d->path); d->path = NULL;
+	git__free(d->user); d->user = NULL;
+	git__free(d->pass); d->pass = NULL;
+}
+
+#define hex2c(c) ((c | 32) % 39 - 9)
+static char* unescape(char *str)
+{
+	int x, y;
+	int len = (int)strlen(str);
+
+	for (x=y=0; str[y]; ++x, ++y) {
+		if ((str[x] = str[y]) == '%') {
+			if (y < len-2 && isxdigit(str[y+1]) && isxdigit(str[y+2])) {
+				str[x] = (hex2c(str[y+1]) << 4) + hex2c(str[y+2]);
+				y += 2;
+			}
+		}
+	}
+	str[x] = '\0';
+	return str;
+}
+
+int gitno_extract_url_parts(
+		char **host,
+		char **port,
+		char **path,
+		char **username,
+		char **password,
+		const char *url,
+		const char *default_port)
+{
+	struct http_parser_url u = {0};
+	const char *_host, *_port, *_path, *_userinfo;
+
+	if (http_parser_parse_url(url, strlen(url), false, &u)) {
+		giterr_set(GITERR_NET, "Malformed URL '%s'", url);
+		return GIT_EINVALIDSPEC;
+	}
+
+	_host = url+u.field_data[UF_HOST].off;
+	_port = url+u.field_data[UF_PORT].off;
+	_path = url+u.field_data[UF_PATH].off;
+	_userinfo = url+u.field_data[UF_USERINFO].off;
+
+	if (u.field_set & (1 << UF_HOST)) {
+		*host = git__substrdup(_host, u.field_data[UF_HOST].len);
+		GITERR_CHECK_ALLOC(*host);
+	}
+
+	if (u.field_set & (1 << UF_PORT))
+		*port = git__substrdup(_port, u.field_data[UF_PORT].len);
+	else
+		*port = git__strdup(default_port);
+	GITERR_CHECK_ALLOC(*port);
+
+	if (u.field_set & (1 << UF_PATH)) {
+		*path = git__substrdup(_path, u.field_data[UF_PATH].len);
+		GITERR_CHECK_ALLOC(*path);
+	} else {
+		giterr_set(GITERR_NET, "invalid url, missing path");
+		return GIT_EINVALIDSPEC;
+	}
+
+	if (u.field_set & (1 << UF_USERINFO)) {
+		const char *colon = memchr(_userinfo, ':', u.field_data[UF_USERINFO].len);
+		if (colon) {
+			*username = unescape(git__substrdup(_userinfo, colon - _userinfo));
+			*password = unescape(git__substrdup(colon+1, u.field_data[UF_USERINFO].len - (colon+1-_userinfo)));
+			GITERR_CHECK_ALLOC(*password);
+		} else {
+			*username = git__substrdup(_userinfo, u.field_data[UF_USERINFO].len);
+		}
+		GITERR_CHECK_ALLOC(*username);
+
+	}
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/netops.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/netops.h
new file mode 100755
index 0000000..b7170a0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/netops.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_netops_h__
+#define INCLUDE_netops_h__
+
+#include "posix.h"
+#include "common.h"
+#include "stream.h"
+
+#ifdef GIT_OPENSSL
+# include <openssl/ssl.h>
+#endif
+
+typedef struct gitno_ssl {
+#ifdef GIT_OPENSSL
+	SSL *ssl;
+#else
+	size_t dummy;
+#endif
+} gitno_ssl;
+
+/* Represents a socket that may or may not be using SSL */
+typedef struct gitno_socket {
+	GIT_SOCKET socket;
+	gitno_ssl ssl;
+} gitno_socket;
+
+typedef struct gitno_buffer {
+	char *data;
+	size_t len;
+	size_t offset;
+	int (*recv)(struct gitno_buffer *buffer);
+	void *cb_data;
+} gitno_buffer;
+
+/* Flags to gitno_connect */
+enum {
+	/* Attempt to create an SSL connection. */
+	GITNO_CONNECT_SSL = 1,
+};
+
+/**
+ * Check if the name in a cert matches the wanted hostname
+ *
+ * Check if a pattern from a certificate matches the hostname we
+ * wanted to connect to according to RFC2818 rules (which specifies
+ * HTTP over TLS). Mainly, an asterisk matches anything, but is
+ * limited to a single url component.
+ *
+ * Note that this does not set an error message. It expects the user
+ * to provide the message for the user.
+ */
+int gitno__match_host(const char *pattern, const char *host);
+
+void gitno_buffer_setup_fromstream(git_stream *st, gitno_buffer *buf, char *data, size_t len);
+void gitno_buffer_setup_callback(gitno_buffer *buf, char *data, size_t len, int (*recv)(gitno_buffer *buf), void *cb_data);
+int gitno_recv(gitno_buffer *buf);
+
+void gitno_consume(gitno_buffer *buf, const char *ptr);
+void gitno_consume_n(gitno_buffer *buf, size_t cons);
+
+typedef struct gitno_connection_data {
+	char *host;
+	char *port;
+	char *path;
+	char *user;
+	char *pass;
+	bool use_ssl;
+} gitno_connection_data;
+
+/*
+ * This replaces all the pointers in `data` with freshly-allocated strings,
+ * that the caller is responsible for freeing.
+ * `gitno_connection_data_free_ptrs` is good for this.
+ */
+
+int gitno_connection_data_from_url(
+		gitno_connection_data *data,
+		const char *url,
+		const char *service_suffix);
+
+/* This frees all the pointers IN the struct, but not the struct itself. */
+void gitno_connection_data_free_ptrs(gitno_connection_data *data);
+
+int gitno_extract_url_parts(
+		char **host,
+		char **port,
+		char **path,
+		char **username,
+		char **password,
+		const char *url,
+		const char *default_port);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/notes.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/notes.c
new file mode 100755
index 0000000..ef4b41b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/notes.c
@@ -0,0 +1,694 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "notes.h"
+
+#include "git2.h"
+#include "refs.h"
+#include "config.h"
+#include "iterator.h"
+#include "signature.h"
+
+static int note_error_notfound(void)
+{
+	giterr_set(GITERR_INVALID, "Note could not be found");
+	return GIT_ENOTFOUND;
+}
+
+static int find_subtree_in_current_level(
+	git_tree **out,
+	git_repository *repo,
+	git_tree *parent,
+	const char *annotated_object_sha,
+	int fanout)
+{
+	size_t i;
+	const git_tree_entry *entry;
+
+	*out = NULL;
+
+	if (parent == NULL)
+		return note_error_notfound();
+
+	for (i = 0; i < git_tree_entrycount(parent); i++) {
+		entry = git_tree_entry_byindex(parent, i);
+
+		if (!git__ishex(git_tree_entry_name(entry)))
+			continue;
+
+		if (S_ISDIR(git_tree_entry_filemode(entry))
+			&& strlen(git_tree_entry_name(entry)) == 2
+			&& !strncmp(git_tree_entry_name(entry), annotated_object_sha + fanout, 2))
+			return git_tree_lookup(out, repo, git_tree_entry_id(entry));
+
+		/* Not a DIR, so do we have an already existing blob? */
+		if (!strcmp(git_tree_entry_name(entry), annotated_object_sha + fanout))
+			return GIT_EEXISTS;
+	}
+
+	return note_error_notfound();
+}
+
+static int find_subtree_r(git_tree **out, git_tree *root,
+			git_repository *repo, const char *target, int *fanout)
+{
+	int error;
+	git_tree *subtree = NULL;
+
+	*out = NULL;
+
+	error = find_subtree_in_current_level(&subtree, repo, root, target, *fanout);
+	if (error == GIT_EEXISTS)
+		return git_tree_lookup(out, repo, git_tree_id(root));
+
+	if (error < 0)
+		return error;
+
+	*fanout += 2;
+	error = find_subtree_r(out, subtree, repo, target, fanout);
+	git_tree_free(subtree);
+
+	return error;
+}
+
+static int find_blob(git_oid *blob, git_tree *tree, const char *target)
+{
+	size_t i;
+	const git_tree_entry *entry;
+
+	for (i=0; i<git_tree_entrycount(tree); i++) {
+		entry = git_tree_entry_byindex(tree, i);
+
+		if (!strcmp(git_tree_entry_name(entry), target)) {
+			/* found matching note object - return */
+
+			git_oid_cpy(blob, git_tree_entry_id(entry));
+			return 0;
+		}
+	}
+
+	return note_error_notfound();
+}
+
+static int tree_write(
+	git_tree **out,
+	git_repository *repo,
+	git_tree *source_tree,
+	const git_oid *object_oid,
+	const char *treeentry_name,
+	unsigned int attributes)
+{
+	int error;
+	git_treebuilder *tb = NULL;
+	const git_tree_entry *entry;
+	git_oid tree_oid;
+
+	if ((error = git_treebuilder_new(&tb, repo, source_tree)) < 0)
+		goto cleanup;
+
+	if (object_oid) {
+		if ((error = git_treebuilder_insert(
+				&entry, tb, treeentry_name, object_oid, attributes)) < 0)
+			goto cleanup;
+	} else {
+		if ((error = git_treebuilder_remove(tb, treeentry_name)) < 0)
+			goto cleanup;
+	}
+
+	if ((error = git_treebuilder_write(&tree_oid, tb)) < 0)
+		goto cleanup;
+
+	error = git_tree_lookup(out, repo, &tree_oid);
+
+cleanup:
+	git_treebuilder_free(tb);
+	return error;
+}
+
+static int manipulate_note_in_tree_r(
+	git_tree **out,
+	git_repository *repo,
+	git_tree *parent,
+	git_oid *note_oid,
+	const char *annotated_object_sha,
+	int fanout,
+	int (*note_exists_cb)(
+		git_tree **out,
+		git_repository *repo,
+		git_tree *parent,
+		git_oid *note_oid,
+		const char *annotated_object_sha,
+		int fanout,
+		int current_error),
+	int (*note_notfound_cb)(
+		git_tree **out,
+		git_repository *repo,
+		git_tree *parent,
+		git_oid *note_oid,
+		const char *annotated_object_sha,
+		int fanout,
+		int current_error))
+{
+	int error;
+	git_tree *subtree = NULL, *new = NULL;
+	char subtree_name[3];
+
+	error = find_subtree_in_current_level(
+		&subtree, repo, parent, annotated_object_sha, fanout);
+
+	if (error == GIT_EEXISTS) {
+		error = note_exists_cb(
+			out, repo, parent, note_oid, annotated_object_sha, fanout, error);
+		goto cleanup;
+	}
+
+	if (error == GIT_ENOTFOUND) {
+		error = note_notfound_cb(
+			out, repo, parent, note_oid, annotated_object_sha, fanout, error);
+		goto cleanup;
+	}
+
+	if (error < 0)
+		goto cleanup;
+
+	/* An existing fanout has been found, let's dig deeper */
+	error = manipulate_note_in_tree_r(
+		&new, repo, subtree, note_oid, annotated_object_sha,
+		fanout + 2, note_exists_cb, note_notfound_cb);
+
+	if (error < 0)
+		goto cleanup;
+
+	strncpy(subtree_name, annotated_object_sha + fanout, 2);
+	subtree_name[2] = '\0';
+
+	error = tree_write(out, repo, parent, git_tree_id(new),
+			   subtree_name, GIT_FILEMODE_TREE);
+
+
+cleanup:
+	git_tree_free(new);
+	git_tree_free(subtree);
+	return error;
+}
+
+static int remove_note_in_tree_eexists_cb(
+	git_tree **out,
+	git_repository *repo,
+	git_tree *parent,
+	git_oid *note_oid,
+	const char *annotated_object_sha,
+	int fanout,
+	int current_error)
+{
+	GIT_UNUSED(note_oid);
+	GIT_UNUSED(current_error);
+
+	return tree_write(out, repo, parent, NULL, annotated_object_sha + fanout, 0);
+}
+
+static int remove_note_in_tree_enotfound_cb(
+	git_tree **out,
+	git_repository *repo,
+	git_tree *parent,
+	git_oid *note_oid,
+	const char *annotated_object_sha,
+	int fanout,
+	int current_error)
+{
+	GIT_UNUSED(out);
+	GIT_UNUSED(repo);
+	GIT_UNUSED(parent);
+	GIT_UNUSED(note_oid);
+	GIT_UNUSED(fanout);
+
+	giterr_set(GITERR_REPOSITORY, "Object '%s' has no note", annotated_object_sha);
+	return current_error;
+}
+
+static int insert_note_in_tree_eexists_cb(git_tree **out,
+	git_repository *repo,
+	git_tree *parent,
+	git_oid *note_oid,
+	const char *annotated_object_sha,
+	int fanout,
+	int current_error)
+{
+	GIT_UNUSED(out);
+	GIT_UNUSED(repo);
+	GIT_UNUSED(parent);
+	GIT_UNUSED(note_oid);
+	GIT_UNUSED(fanout);
+
+	giterr_set(GITERR_REPOSITORY, "Note for '%s' exists already", annotated_object_sha);
+	return current_error;
+}
+
+static int insert_note_in_tree_enotfound_cb(git_tree **out,
+	git_repository *repo,
+	git_tree *parent,
+	git_oid *note_oid,
+	const char *annotated_object_sha,
+	int fanout,
+	int current_error)
+{
+	GIT_UNUSED(current_error);
+
+	/* No existing fanout at this level, insert in place */
+	return tree_write(
+		out,
+		repo,
+		parent,
+		note_oid,
+		annotated_object_sha + fanout,
+		GIT_FILEMODE_BLOB);
+}
+
+static int note_write(git_oid *out,
+	git_repository *repo,
+	const git_signature *author,
+	const git_signature *committer,
+	const char *notes_ref,
+	const char *note,
+	git_tree *commit_tree,
+	const char *target,
+	git_commit **parents,
+	int allow_note_overwrite)
+{
+	int error;
+	git_oid oid;
+	git_tree *tree = NULL;
+
+	// TODO: should we apply filters?
+	/* create note object */
+	if ((error = git_blob_create_frombuffer(&oid, repo, note, strlen(note))) < 0)
+		goto cleanup;
+
+	if ((error = manipulate_note_in_tree_r(
+		&tree, repo, commit_tree, &oid, target, 0,
+		allow_note_overwrite ? insert_note_in_tree_enotfound_cb : insert_note_in_tree_eexists_cb,
+		insert_note_in_tree_enotfound_cb)) < 0)
+		goto cleanup;
+
+	if (out)
+		git_oid_cpy(out, &oid);
+
+	error = git_commit_create(&oid, repo, notes_ref, author, committer,
+				  NULL, GIT_NOTES_DEFAULT_MSG_ADD,
+				  tree, *parents == NULL ? 0 : 1, (const git_commit **) parents);
+
+cleanup:
+	git_tree_free(tree);
+	return error;
+}
+
+static int note_new(
+	git_note **out,
+	git_oid *note_oid,
+	git_commit *commit,
+	git_blob *blob)
+{
+	git_note *note = NULL;
+
+	note = git__malloc(sizeof(git_note));
+	GITERR_CHECK_ALLOC(note);
+
+	git_oid_cpy(&note->id, note_oid);
+
+	if (git_signature_dup(&note->author, git_commit_author(commit)) < 0 ||
+		git_signature_dup(&note->committer, git_commit_committer(commit)) < 0)
+		return -1;
+
+	note->message = git__strndup(git_blob_rawcontent(blob), git_blob_rawsize(blob));
+	GITERR_CHECK_ALLOC(note->message);
+
+	*out = note;
+	return 0;
+}
+
+static int note_lookup(
+	git_note **out,
+	git_repository *repo,
+	git_commit *commit,
+	git_tree *tree,
+	const char *target)
+{
+	int error, fanout = 0;
+	git_oid oid;
+	git_blob *blob = NULL;
+	git_note *note = NULL;
+	git_tree *subtree = NULL;
+
+	if ((error = find_subtree_r(&subtree, tree, repo, target, &fanout)) < 0)
+		goto cleanup;
+
+	if ((error = find_blob(&oid, subtree, target + fanout)) < 0)
+		goto cleanup;
+
+	if ((error = git_blob_lookup(&blob, repo, &oid)) < 0)
+		goto cleanup;
+
+	if ((error = note_new(&note, &oid, commit, blob)) < 0)
+		goto cleanup;
+
+	*out = note;
+
+cleanup:
+	git_tree_free(subtree);
+	git_blob_free(blob);
+	return error;
+}
+
+static int note_remove(git_repository *repo,
+		const git_signature *author, const git_signature *committer,
+		const char *notes_ref, git_tree *tree,
+		const char *target, git_commit **parents)
+{
+	int error;
+	git_tree *tree_after_removal = NULL;
+	git_oid oid;
+
+	if ((error = manipulate_note_in_tree_r(
+		&tree_after_removal, repo, tree, NULL, target, 0,
+		remove_note_in_tree_eexists_cb, remove_note_in_tree_enotfound_cb)) < 0)
+		goto cleanup;
+
+	error = git_commit_create(&oid, repo, notes_ref, author, committer,
+	  NULL, GIT_NOTES_DEFAULT_MSG_RM,
+	  tree_after_removal,
+	  *parents == NULL ? 0 : 1,
+	  (const git_commit **) parents);
+
+cleanup:
+	git_tree_free(tree_after_removal);
+	return error;
+}
+
+static int note_get_default_ref(char **out, git_repository *repo)
+{
+	git_config *cfg;
+	int ret = git_repository_config__weakptr(&cfg, repo);
+
+	*out = (ret != 0) ? NULL : git_config__get_string_force(
+		cfg, "core.notesref", GIT_NOTES_DEFAULT_REF);
+
+	return ret;
+}
+
+static int normalize_namespace(char **out, git_repository *repo, const char *notes_ref)
+{
+	if (notes_ref) {
+		*out = git__strdup(notes_ref);
+		GITERR_CHECK_ALLOC(*out);
+		return 0;
+	}
+
+	return note_get_default_ref(out, repo);
+}
+
+static int retrieve_note_tree_and_commit(
+	git_tree **tree_out,
+	git_commit **commit_out,
+	char **notes_ref_out,
+	git_repository *repo,
+	const char *notes_ref)
+{
+	int error;
+	git_oid oid;
+
+	if ((error = normalize_namespace(notes_ref_out, repo, notes_ref)) < 0)
+		return error;
+
+	if ((error = git_reference_name_to_id(&oid, repo, *notes_ref_out)) < 0)
+		return error;
+
+	if (git_commit_lookup(commit_out, repo, &oid) < 0)
+		return error;
+
+	if ((error = git_commit_tree(tree_out, *commit_out)) < 0)
+		return error;
+
+	return 0;
+}
+
+int git_note_read(git_note **out, git_repository *repo,
+		  const char *notes_ref_in, const git_oid *oid)
+{
+	int error;
+	char *target = NULL, *notes_ref = NULL;
+	git_tree *tree = NULL;
+	git_commit *commit = NULL;
+
+	target = git_oid_allocfmt(oid);
+	GITERR_CHECK_ALLOC(target);
+
+	if (!(error = retrieve_note_tree_and_commit(
+		      &tree, &commit, &notes_ref, repo, notes_ref_in)))
+		error = note_lookup(out, repo, commit, tree, target);
+
+	git__free(notes_ref);
+	git__free(target);
+	git_tree_free(tree);
+	git_commit_free(commit);
+	return error;
+}
+
+int git_note_create(
+	git_oid *out,
+	git_repository *repo,
+	const char *notes_ref_in,
+	const git_signature *author,
+	const git_signature *committer,
+	const git_oid *oid,
+	const char *note,
+	int allow_note_overwrite)
+{
+	int error;
+	char *target = NULL, *notes_ref = NULL;
+	git_commit *commit = NULL;
+	git_tree *tree = NULL;
+
+	target = git_oid_allocfmt(oid);
+	GITERR_CHECK_ALLOC(target);
+
+	error = retrieve_note_tree_and_commit(&tree, &commit, &notes_ref, repo, notes_ref_in);
+
+	if (error < 0 && error != GIT_ENOTFOUND)
+		goto cleanup;
+
+	error = note_write(out, repo, author, committer, notes_ref,
+			note, tree, target, &commit, allow_note_overwrite);
+
+cleanup:
+	git__free(notes_ref);
+	git__free(target);
+	git_commit_free(commit);
+	git_tree_free(tree);
+	return error;
+}
+
+int git_note_remove(git_repository *repo, const char *notes_ref_in,
+		const git_signature *author, const git_signature *committer,
+		const git_oid *oid)
+{
+	int error;
+	char *target = NULL, *notes_ref;
+	git_commit *commit = NULL;
+	git_tree *tree = NULL;
+
+	target = git_oid_allocfmt(oid);
+	GITERR_CHECK_ALLOC(target);
+
+	if (!(error = retrieve_note_tree_and_commit(
+		      &tree, &commit, &notes_ref, repo, notes_ref_in)))
+		error = note_remove(
+			repo, author, committer, notes_ref, tree, target, &commit);
+
+	git__free(notes_ref);
+	git__free(target);
+	git_commit_free(commit);
+	git_tree_free(tree);
+	return error;
+}
+
+int git_note_default_ref(git_buf *out, git_repository *repo)
+{
+	char *default_ref;
+	int error;
+
+	assert(out && repo);
+
+	git_buf_sanitize(out);
+
+	if ((error = note_get_default_ref(&default_ref, repo)) < 0)
+		return error;
+
+	git_buf_attach(out, default_ref, strlen(default_ref));
+	return 0;
+}
+
+const git_signature *git_note_committer(const git_note *note)
+{
+	assert(note);
+	return note->committer;
+}
+
+const git_signature *git_note_author(const git_note *note)
+{
+	assert(note);
+	return note->author;
+}
+
+const char * git_note_message(const git_note *note)
+{
+	assert(note);
+	return note->message;
+}
+
+const git_oid * git_note_id(const git_note *note)
+{
+	assert(note);
+	return &note->id;
+}
+
+void git_note_free(git_note *note)
+{
+	if (note == NULL)
+		return;
+
+	git_signature_free(note->committer);
+	git_signature_free(note->author);
+	git__free(note->message);
+	git__free(note);
+}
+
+static int process_entry_path(
+	const char* entry_path,
+	git_oid *annotated_object_id)
+{
+	int error = 0;
+	size_t i = 0, j = 0, len;
+	git_buf buf = GIT_BUF_INIT;
+
+	if ((error = git_buf_puts(&buf, entry_path)) < 0)
+		goto cleanup;
+
+	len = git_buf_len(&buf);
+
+	while (i < len) {
+		if (buf.ptr[i] == '/') {
+			i++;
+			continue;
+		}
+
+		if (git__fromhex(buf.ptr[i]) < 0) {
+			/* This is not a note entry */
+			goto cleanup;
+		}
+
+		if (i != j)
+			buf.ptr[j] = buf.ptr[i];
+
+		i++;
+		j++;
+	}
+
+	buf.ptr[j] = '\0';
+	buf.size = j;
+
+	if (j != GIT_OID_HEXSZ) {
+		/* This is not a note entry */
+		goto cleanup;
+	}
+
+	error = git_oid_fromstr(annotated_object_id, buf.ptr);
+
+cleanup:
+	git_buf_free(&buf);
+	return error;
+}
+
+int git_note_foreach(
+	git_repository *repo,
+	const char *notes_ref,
+	git_note_foreach_cb note_cb,
+	void *payload)
+{
+	int error;
+	git_note_iterator *iter = NULL;
+	git_oid note_id, annotated_id;
+
+	if ((error = git_note_iterator_new(&iter, repo, notes_ref)) < 0)
+		return error;
+
+	while (!(error = git_note_next(&note_id, &annotated_id, iter))) {
+		if ((error = note_cb(&note_id, &annotated_id, payload)) != 0) {
+			giterr_set_after_callback(error);
+			break;
+		}
+	}
+
+	if (error == GIT_ITEROVER)
+		error = 0;
+
+	git_note_iterator_free(iter);
+	return error;
+}
+
+
+void git_note_iterator_free(git_note_iterator *it)
+{
+	if (it == NULL)
+		return;
+
+	git_iterator_free(it);
+}
+
+
+int git_note_iterator_new(
+	git_note_iterator **it,
+	git_repository *repo,
+	const char *notes_ref_in)
+{
+	int error;
+	git_commit *commit = NULL;
+	git_tree *tree = NULL;
+	char *notes_ref;
+
+	error = retrieve_note_tree_and_commit(&tree, &commit, &notes_ref, repo, notes_ref_in);
+	if (error < 0)
+		goto cleanup;
+
+	if ((error = git_iterator_for_tree(it, tree, 0, NULL, NULL)) < 0)
+		git_iterator_free(*it);
+
+cleanup:
+	git__free(notes_ref);
+	git_tree_free(tree);
+	git_commit_free(commit);
+
+	return error;
+}
+
+int git_note_next(
+	git_oid* note_id,
+	git_oid* annotated_id,
+	git_note_iterator *it)
+{
+	int error;
+	const git_index_entry *item;
+
+	if ((error = git_iterator_current(&item, it)) < 0)
+		return error;
+
+	git_oid_cpy(note_id, &item->id);
+
+	if (!(error = process_entry_path(item->path, annotated_id)))
+		git_iterator_advance(NULL, it);
+
+	return error;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/notes.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/notes.h
new file mode 100755
index 0000000..cfc0ca2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/notes.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_note_h__
+#define INCLUDE_note_h__
+
+#include "common.h"
+
+#include "git2/oid.h"
+#include "git2/types.h"
+
+#define GIT_NOTES_DEFAULT_REF "refs/notes/commits"
+
+#define GIT_NOTES_DEFAULT_MSG_ADD \
+	"Notes added by 'git_note_create' from libgit2"
+
+#define GIT_NOTES_DEFAULT_MSG_RM \
+	"Notes removed by 'git_note_remove' from libgit2"
+
+struct git_note {
+	git_oid id;
+
+	git_signature *author;
+	git_signature *committer;
+
+	char *message;
+};
+
+#endif /* INCLUDE_notes_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/object.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/object.c
new file mode 100755
index 0000000..1073559
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/object.c
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "git2/object.h"
+
+#include "common.h"
+#include "repository.h"
+
+#include "commit.h"
+#include "tree.h"
+#include "blob.h"
+#include "tag.h"
+
+static const int OBJECT_BASE_SIZE = 4096;
+
+typedef struct {
+	const char	*str;	/* type name string */
+	size_t		size;	/* size in bytes of the object structure */
+
+	int  (*parse)(void *self, git_odb_object *obj);
+	void (*free)(void *self);
+} git_object_def;
+
+static git_object_def git_objects_table[] = {
+	/* 0 = GIT_OBJ__EXT1 */
+	{ "", 0, NULL, NULL },
+
+	/* 1 = GIT_OBJ_COMMIT */
+	{ "commit", sizeof(git_commit), git_commit__parse, git_commit__free },
+
+	/* 2 = GIT_OBJ_TREE */
+	{ "tree", sizeof(git_tree), git_tree__parse, git_tree__free },
+
+	/* 3 = GIT_OBJ_BLOB */
+	{ "blob", sizeof(git_blob), git_blob__parse, git_blob__free },
+
+	/* 4 = GIT_OBJ_TAG */
+	{ "tag", sizeof(git_tag), git_tag__parse, git_tag__free },
+
+	/* 5 = GIT_OBJ__EXT2 */
+	{ "", 0, NULL, NULL },
+	/* 6 = GIT_OBJ_OFS_DELTA */
+	{ "OFS_DELTA", 0, NULL, NULL },
+	/* 7 = GIT_OBJ_REF_DELTA */
+	{ "REF_DELTA", 0, NULL, NULL },
+};
+
+int git_object__from_odb_object(
+	git_object **object_out,
+	git_repository *repo,
+	git_odb_object *odb_obj,
+	git_otype type)
+{
+	int error;
+	size_t object_size;
+	git_object_def *def;
+	git_object *object = NULL;
+
+	assert(object_out);
+	*object_out = NULL;
+
+	/* Validate type match */
+	if (type != GIT_OBJ_ANY && type != odb_obj->cached.type) {
+		giterr_set(GITERR_INVALID,
+			"The requested type does not match the type in the ODB");
+		return GIT_ENOTFOUND;
+	}
+
+	if ((object_size = git_object__size(odb_obj->cached.type)) == 0) {
+		giterr_set(GITERR_INVALID, "The requested type is invalid");
+		return GIT_ENOTFOUND;
+	}
+
+	/* Allocate and initialize base object */
+	object = git__calloc(1, object_size);
+	GITERR_CHECK_ALLOC(object);
+
+	git_oid_cpy(&object->cached.oid, &odb_obj->cached.oid);
+	object->cached.type = odb_obj->cached.type;
+	object->cached.size = odb_obj->cached.size;
+	object->repo = repo;
+
+	/* Parse raw object data */
+	def = &git_objects_table[odb_obj->cached.type];
+	assert(def->free && def->parse);
+
+	if ((error = def->parse(object, odb_obj)) < 0)
+		def->free(object);
+	else
+		*object_out = git_cache_store_parsed(&repo->objects, object);
+
+	return error;
+}
+
+void git_object__free(void *obj)
+{
+	git_otype type = ((git_object *)obj)->cached.type;
+
+	if (type < 0 || ((size_t)type) >= ARRAY_SIZE(git_objects_table) ||
+		!git_objects_table[type].free)
+		git__free(obj);
+	else
+		git_objects_table[type].free(obj);
+}
+
+int git_object_lookup_prefix(
+	git_object **object_out,
+	git_repository *repo,
+	const git_oid *id,
+	size_t len,
+	git_otype type)
+{
+	git_object *object = NULL;
+	git_odb *odb = NULL;
+	git_odb_object *odb_obj = NULL;
+	int error = 0;
+
+	assert(repo && object_out && id);
+
+	if (len < GIT_OID_MINPREFIXLEN) {
+		giterr_set(GITERR_OBJECT, "Ambiguous lookup - OID prefix is too short");
+		return GIT_EAMBIGUOUS;
+	}
+
+	error = git_repository_odb__weakptr(&odb, repo);
+	if (error < 0)
+		return error;
+
+	if (len > GIT_OID_HEXSZ)
+		len = GIT_OID_HEXSZ;
+
+	if (len == GIT_OID_HEXSZ) {
+		git_cached_obj *cached = NULL;
+
+		/* We want to match the full id : we can first look up in the cache,
+		 * since there is no need to check for non ambiguousity
+		 */
+		cached = git_cache_get_any(&repo->objects, id);
+		if (cached != NULL) {
+			if (cached->flags == GIT_CACHE_STORE_PARSED) {
+				object = (git_object *)cached;
+
+				if (type != GIT_OBJ_ANY && type != object->cached.type) {
+					git_object_free(object);
+					giterr_set(GITERR_INVALID,
+						"The requested type does not match the type in ODB");
+					return GIT_ENOTFOUND;
+				}
+
+				*object_out = object;
+				return 0;
+			} else if (cached->flags == GIT_CACHE_STORE_RAW) {
+				odb_obj = (git_odb_object *)cached;
+			} else {
+				assert(!"Wrong caching type in the global object cache");
+			}
+		} else {
+			/* Object was not found in the cache, let's explore the backends.
+			 * We could just use git_odb_read_unique_short_oid,
+			 * it is the same cost for packed and loose object backends,
+			 * but it may be much more costly for sqlite and hiredis.
+			 */
+			error = git_odb_read(&odb_obj, odb, id);
+		}
+	} else {
+		git_oid short_oid;
+
+		/* We copy the first len*4 bits from id and fill the remaining with 0s */
+		memcpy(short_oid.id, id->id, (len + 1) / 2);
+		if (len % 2)
+			short_oid.id[len / 2] &= 0xF0;
+		memset(short_oid.id + (len + 1) / 2, 0, (GIT_OID_HEXSZ - len) / 2);
+
+		/* If len < GIT_OID_HEXSZ (a strict short oid was given), we have
+		 * 2 options :
+		 * - We always search in the cache first. If we find that short oid is
+		 *	ambiguous, we can stop. But in all the other cases, we must then
+		 *	explore all the backends (to find an object if there was match,
+		 *	or to check that oid is not ambiguous if we have found 1 match in
+		 *	the cache)
+		 * - We never explore the cache, go right to exploring the backends
+		 * We chose the latter : we explore directly the backends.
+		 */
+		error = git_odb_read_prefix(&odb_obj, odb, &short_oid, len);
+	}
+
+	if (error < 0)
+		return error;
+
+	error = git_object__from_odb_object(object_out, repo, odb_obj, type);
+
+	git_odb_object_free(odb_obj);
+
+	return error;
+}
+
+int git_object_lookup(git_object **object_out, git_repository *repo, const git_oid *id, git_otype type) {
+	return git_object_lookup_prefix(object_out, repo, id, GIT_OID_HEXSZ, type);
+}
+
+void git_object_free(git_object *object)
+{
+	if (object == NULL)
+		return;
+
+	git_cached_obj_decref(object);
+}
+
+const git_oid *git_object_id(const git_object *obj)
+{
+	assert(obj);
+	return &obj->cached.oid;
+}
+
+git_otype git_object_type(const git_object *obj)
+{
+	assert(obj);
+	return obj->cached.type;
+}
+
+git_repository *git_object_owner(const git_object *obj)
+{
+	assert(obj);
+	return obj->repo;
+}
+
+const char *git_object_type2string(git_otype type)
+{
+	if (type < 0 || ((size_t) type) >= ARRAY_SIZE(git_objects_table))
+		return "";
+
+	return git_objects_table[type].str;
+}
+
+git_otype git_object_string2type(const char *str)
+{
+	size_t i;
+
+	if (!str || !*str)
+		return GIT_OBJ_BAD;
+
+	for (i = 0; i < ARRAY_SIZE(git_objects_table); i++)
+		if (!strcmp(str, git_objects_table[i].str))
+			return (git_otype)i;
+
+	return GIT_OBJ_BAD;
+}
+
+int git_object_typeisloose(git_otype type)
+{
+	if (type < 0 || ((size_t) type) >= ARRAY_SIZE(git_objects_table))
+		return 0;
+
+	return (git_objects_table[type].size > 0) ? 1 : 0;
+}
+
+size_t git_object__size(git_otype type)
+{
+	if (type < 0 || ((size_t) type) >= ARRAY_SIZE(git_objects_table))
+		return 0;
+
+	return git_objects_table[type].size;
+}
+
+static int dereference_object(git_object **dereferenced, git_object *obj)
+{
+	git_otype type = git_object_type(obj);
+
+	switch (type) {
+	case GIT_OBJ_COMMIT:
+		return git_commit_tree((git_tree **)dereferenced, (git_commit*)obj);
+
+	case GIT_OBJ_TAG:
+		return git_tag_target(dereferenced, (git_tag*)obj);
+
+	case GIT_OBJ_BLOB:
+	case GIT_OBJ_TREE:
+		return GIT_EPEEL;
+
+	default:
+		return GIT_EINVALIDSPEC;
+	}
+}
+
+static int peel_error(int error, const git_oid *oid, git_otype type)
+{
+	const char *type_name;
+	char hex_oid[GIT_OID_HEXSZ + 1];
+
+	type_name = git_object_type2string(type);
+
+	git_oid_fmt(hex_oid, oid);
+	hex_oid[GIT_OID_HEXSZ] = '\0';
+
+	giterr_set(GITERR_OBJECT, "The git_object of id '%s' can not be "
+		"successfully peeled into a %s (git_otype=%i).", hex_oid, type_name, type);
+
+	return error;
+}
+
+static int check_type_combination(git_otype type, git_otype target)
+{
+	if (type == target)
+		return 0;
+
+	switch (type) {
+	case GIT_OBJ_BLOB:
+	case GIT_OBJ_TREE:
+		/* a blob or tree can never be peeled to anything but themselves */
+		return GIT_EINVALIDSPEC;
+		break;
+	case GIT_OBJ_COMMIT:
+		/* a commit can only be peeled to a tree */
+		if (target != GIT_OBJ_TREE && target != GIT_OBJ_ANY)
+			return GIT_EINVALIDSPEC;
+		break;
+	case GIT_OBJ_TAG:
+		/* a tag may point to anything, so we let anything through */
+		break;
+	default:
+		return GIT_EINVALIDSPEC;
+	}
+
+	return 0;
+}
+
+int git_object_peel(
+	git_object **peeled,
+	const git_object *object,
+	git_otype target_type)
+{
+	git_object *source, *deref = NULL;
+	int error;
+
+	assert(object && peeled);
+
+	assert(target_type == GIT_OBJ_TAG ||
+		target_type == GIT_OBJ_COMMIT ||
+		target_type == GIT_OBJ_TREE ||
+		target_type == GIT_OBJ_BLOB ||
+		target_type == GIT_OBJ_ANY);
+
+	if ((error = check_type_combination(git_object_type(object), target_type)) < 0)
+		return peel_error(error, git_object_id(object), target_type);
+
+	if (git_object_type(object) == target_type)
+		return git_object_dup(peeled, (git_object *)object);
+
+	source = (git_object *)object;
+
+	while (!(error = dereference_object(&deref, source))) {
+
+		if (source != object)
+			git_object_free(source);
+
+		if (git_object_type(deref) == target_type) {
+			*peeled = deref;
+			return 0;
+		}
+
+		if (target_type == GIT_OBJ_ANY &&
+			git_object_type(deref) != git_object_type(object))
+		{
+			*peeled = deref;
+			return 0;
+		}
+
+		source = deref;
+		deref = NULL;
+	}
+
+	if (source != object)
+		git_object_free(source);
+
+	git_object_free(deref);
+
+	if (error)
+		error = peel_error(error, git_object_id(object), target_type);
+
+	return error;
+}
+
+int git_object_dup(git_object **dest, git_object *source)
+{
+	git_cached_obj_incref(source);
+	*dest = source;
+	return 0;
+}
+
+int git_object_lookup_bypath(
+		git_object **out,
+		const git_object *treeish,
+		const char *path,
+		git_otype type)
+{
+	int error = -1;
+	git_tree *tree = NULL;
+	git_tree_entry *entry = NULL;
+
+	assert(out && treeish && path);
+
+	if ((error = git_object_peel((git_object**)&tree, treeish, GIT_OBJ_TREE)) < 0 ||
+		 (error = git_tree_entry_bypath(&entry, tree, path)) < 0)
+	{
+		goto cleanup;
+	}
+
+	if (type != GIT_OBJ_ANY && git_tree_entry_type(entry) != type)
+	{
+		giterr_set(GITERR_OBJECT,
+				"object at path '%s' is not of the asked-for type %d",
+				path, type);
+		error = GIT_EINVALIDSPEC;
+		goto cleanup;
+	}
+
+	error = git_tree_entry_to_object(out, git_object_owner(treeish), entry);
+
+cleanup:
+	git_tree_entry_free(entry);
+	git_tree_free(tree);
+	return error;
+}
+
+int git_object_short_id(git_buf *out, const git_object *obj)
+{
+	git_repository *repo;
+	int len = GIT_ABBREV_DEFAULT, error;
+	git_oid id = {{0}};
+	git_odb *odb;
+
+	assert(out && obj);
+
+	git_buf_sanitize(out);
+	repo = git_object_owner(obj);
+
+	if ((error = git_repository__cvar(&len, repo, GIT_CVAR_ABBREV)) < 0)
+		return error;
+
+	if ((error = git_repository_odb(&odb, repo)) < 0)
+		return error;
+
+	while (len < GIT_OID_HEXSZ) {
+		/* set up short oid */
+		memcpy(&id.id, &obj->cached.oid.id, (len + 1) / 2);
+		if (len & 1)
+			id.id[len / 2] &= 0xf0;
+
+		error = git_odb_exists_prefix(NULL, odb, &id, len);
+		if (error != GIT_EAMBIGUOUS)
+			break;
+
+		giterr_clear();
+		len++;
+	}
+
+	if (!error && !(error = git_buf_grow(out, len + 1))) {
+		git_oid_tostr(out->ptr, len + 1, &id);
+		out->size = len;
+	}
+
+	git_odb_free(odb);
+
+	return error;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/object.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/object.h
new file mode 100755
index 0000000..d187c55
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/object.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_object_h__
+#define INCLUDE_object_h__
+
+/** Base git object for inheritance */
+struct git_object {
+	git_cached_obj cached;
+	git_repository *repo;
+};
+
+/* fully free the object; internal method, DO NOT EXPORT */
+void git_object__free(void *object);
+
+int git_object__from_odb_object(
+	git_object **object_out,
+	git_repository *repo,
+	git_odb_object *odb_obj,
+	git_otype type);
+
+int git_object__resolve_to_type(git_object **obj, git_otype type);
+
+int git_oid__parse(git_oid *oid, const char **buffer_out, const char *buffer_end, const char *header);
+
+void git_oid__writebuf(git_buf *buf, const char *header, const git_oid *oid);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/object_api.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/object_api.c
new file mode 100755
index 0000000..838bba3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/object_api.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "git2/object.h"
+
+#include "common.h"
+#include "repository.h"
+
+#include "commit.h"
+#include "tree.h"
+#include "blob.h"
+#include "tag.h"
+
+/**
+ * Blob
+ */
+int git_commit_lookup(git_commit **out, git_repository *repo, const git_oid *id)
+{
+	return git_object_lookup((git_object **)out, repo, id, GIT_OBJ_COMMIT);
+}
+
+int git_commit_lookup_prefix(git_commit **out, git_repository *repo, const git_oid *id, size_t len)
+{
+	return git_object_lookup_prefix((git_object **)out, repo, id, len, GIT_OBJ_COMMIT);
+}
+
+void git_commit_free(git_commit *obj)
+{
+	git_object_free((git_object *)obj);
+}
+
+const git_oid *git_commit_id(const git_commit *obj)
+{
+	return git_object_id((const git_object *)obj);
+}
+
+git_repository *git_commit_owner(const git_commit *obj)
+{
+	return git_object_owner((const git_object *)obj);
+}
+
+
+/**
+ * Tree
+ */
+int git_tree_lookup(git_tree **out, git_repository *repo, const git_oid *id)
+{
+	return git_object_lookup((git_object **)out, repo, id, GIT_OBJ_TREE);
+}
+
+int git_tree_lookup_prefix(git_tree **out, git_repository *repo, const git_oid *id, size_t len)
+{
+	return git_object_lookup_prefix((git_object **)out, repo, id, len, GIT_OBJ_TREE);
+}
+
+void git_tree_free(git_tree *obj)
+{
+	git_object_free((git_object *)obj);
+}
+
+const git_oid *git_tree_id(const git_tree *obj)
+{
+	return git_object_id((const git_object *)obj);
+}
+
+git_repository *git_tree_owner(const git_tree *obj)
+{
+	return git_object_owner((const git_object *)obj);
+}
+
+
+/**
+ * Tag
+ */
+int git_tag_lookup(git_tag **out, git_repository *repo, const git_oid *id)
+{
+	return git_object_lookup((git_object **)out, repo, id, GIT_OBJ_TAG);
+}
+
+int git_tag_lookup_prefix(git_tag **out, git_repository *repo, const git_oid *id, size_t len)
+{
+	return git_object_lookup_prefix((git_object **)out, repo, id, len, GIT_OBJ_TAG);
+}
+
+void git_tag_free(git_tag *obj)
+{
+	git_object_free((git_object *)obj);
+}
+
+const git_oid *git_tag_id(const git_tag *obj)
+{
+	return git_object_id((const git_object *)obj);
+}
+
+git_repository *git_tag_owner(const git_tag *obj)
+{
+	return git_object_owner((const git_object *)obj);
+}
+
+/**
+ * Blob
+ */
+int git_blob_lookup(git_blob **out, git_repository *repo, const git_oid *id)
+{
+	return git_object_lookup((git_object **)out, repo, id, GIT_OBJ_BLOB);
+}
+
+int git_blob_lookup_prefix(git_blob **out, git_repository *repo, const git_oid *id, size_t len)
+{
+	return git_object_lookup_prefix((git_object **)out, repo, id, len, GIT_OBJ_BLOB);
+}
+
+void git_blob_free(git_blob *obj)
+{
+	git_object_free((git_object *)obj);
+}
+
+const git_oid *git_blob_id(const git_blob *obj)
+{
+	return git_object_id((const git_object *)obj);
+}
+
+git_repository *git_blob_owner(const git_blob *obj)
+{
+	return git_object_owner((const git_object *)obj);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/odb.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/odb.c
new file mode 100755
index 0000000..b2d6351
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/odb.c
@@ -0,0 +1,1165 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include <zlib.h>
+#include "git2/object.h"
+#include "git2/sys/odb_backend.h"
+#include "fileops.h"
+#include "hash.h"
+#include "odb.h"
+#include "delta-apply.h"
+#include "filter.h"
+#include "repository.h"
+
+#include "git2/odb_backend.h"
+#include "git2/oid.h"
+
+#define GIT_ALTERNATES_FILE "info/alternates"
+
+/*
+ * We work under the assumption that most objects for long-running
+ * operations will be packed
+ */
+#define GIT_LOOSE_PRIORITY 1
+#define GIT_PACKED_PRIORITY 2
+
+#define GIT_ALTERNATES_MAX_DEPTH 5
+
+typedef struct
+{
+	git_odb_backend *backend;
+	int priority;
+	bool is_alternate;
+	ino_t disk_inode;
+} backend_internal;
+
+static git_cache *odb_cache(git_odb *odb)
+{
+	if (odb->rc.owner != NULL) {
+		git_repository *owner = odb->rc.owner;
+		return &owner->objects;
+	}
+
+	return &odb->own_cache;
+}
+
+static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_depth);
+
+int git_odb__format_object_header(char *hdr, size_t n, git_off_t obj_len, git_otype obj_type)
+{
+	const char *type_str = git_object_type2string(obj_type);
+	int len = p_snprintf(hdr, n, "%s %lld", type_str, (long long)obj_len);
+	assert(len > 0 && len <= (int)n);
+	return len+1;
+}
+
+int git_odb__hashobj(git_oid *id, git_rawobj *obj)
+{
+	git_buf_vec vec[2];
+	char header[64];
+	int hdrlen;
+
+	assert(id && obj);
+
+	if (!git_object_typeisloose(obj->type))
+		return -1;
+
+	if (!obj->data && obj->len != 0)
+		return -1;
+
+	hdrlen = git_odb__format_object_header(header, sizeof(header), obj->len, obj->type);
+
+	vec[0].data = header;
+	vec[0].len = hdrlen;
+	vec[1].data = obj->data;
+	vec[1].len = obj->len;
+
+	git_hash_vec(id, vec, 2);
+
+	return 0;
+}
+
+
+static git_odb_object *odb_object__alloc(const git_oid *oid, git_rawobj *source)
+{
+	git_odb_object *object = git__calloc(1, sizeof(git_odb_object));
+
+	if (object != NULL) {
+		git_oid_cpy(&object->cached.oid, oid);
+		object->cached.type = source->type;
+		object->cached.size = source->len;
+		object->buffer      = source->data;
+	}
+
+	return object;
+}
+
+void git_odb_object__free(void *object)
+{
+	if (object != NULL) {
+		git__free(((git_odb_object *)object)->buffer);
+		git__free(object);
+	}
+}
+
+const git_oid *git_odb_object_id(git_odb_object *object)
+{
+	return &object->cached.oid;
+}
+
+const void *git_odb_object_data(git_odb_object *object)
+{
+	return object->buffer;
+}
+
+size_t git_odb_object_size(git_odb_object *object)
+{
+	return object->cached.size;
+}
+
+git_otype git_odb_object_type(git_odb_object *object)
+{
+	return object->cached.type;
+}
+
+int git_odb_object_dup(git_odb_object **dest, git_odb_object *source)
+{
+	git_cached_obj_incref(source);
+	*dest = source;
+	return 0;
+}
+
+void git_odb_object_free(git_odb_object *object)
+{
+	if (object == NULL)
+		return;
+
+	git_cached_obj_decref(object);
+}
+
+int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type)
+{
+	int hdr_len;
+	char hdr[64], buffer[FILEIO_BUFSIZE];
+	git_hash_ctx ctx;
+	ssize_t read_len = 0;
+	int error = 0;
+
+	if (!git_object_typeisloose(type)) {
+		giterr_set(GITERR_INVALID, "Invalid object type for hash");
+		return -1;
+	}
+
+	if ((error = git_hash_ctx_init(&ctx)) < 0)
+		return -1;
+
+	hdr_len = git_odb__format_object_header(hdr, sizeof(hdr), size, type);
+
+	if ((error = git_hash_update(&ctx, hdr, hdr_len)) < 0)
+		goto done;
+
+	while (size > 0 && (read_len = p_read(fd, buffer, sizeof(buffer))) > 0) {
+		if ((error = git_hash_update(&ctx, buffer, read_len)) < 0)
+			goto done;
+
+		size -= read_len;
+	}
+
+	/* If p_read returned an error code, the read obviously failed.
+	 * If size is not zero, the file was truncated after we originally
+	 * stat'd it, so we consider this a read failure too */
+	if (read_len < 0 || size > 0) {
+		giterr_set(GITERR_OS, "Error reading file for hashing");
+		error = -1;
+
+		goto done;
+	}
+
+	error = git_hash_final(out, &ctx);
+
+done:
+	git_hash_ctx_cleanup(&ctx);
+	return error;
+}
+
+int git_odb__hashfd_filtered(
+	git_oid *out, git_file fd, size_t size, git_otype type, git_filter_list *fl)
+{
+	int error;
+	git_buf raw = GIT_BUF_INIT;
+
+	if (!fl)
+		return git_odb__hashfd(out, fd, size, type);
+
+	/* size of data is used in header, so we have to read the whole file
+	 * into memory to apply filters before beginning to calculate the hash
+	 */
+
+	if (!(error = git_futils_readbuffer_fd(&raw, fd, size))) {
+		git_buf post = GIT_BUF_INIT;
+
+		error = git_filter_list_apply_to_data(&post, fl, &raw);
+
+		git_buf_free(&raw);
+
+		if (!error)
+			error = git_odb_hash(out, post.ptr, post.size, type);
+
+		git_buf_free(&post);
+	}
+
+	return error;
+}
+
+int git_odb__hashlink(git_oid *out, const char *path)
+{
+	struct stat st;
+	int size;
+	int result;
+
+	if (git_path_lstat(path, &st) < 0)
+		return -1;
+
+	if (!git__is_int(st.st_size) || (int)st.st_size < 0) {
+		giterr_set(GITERR_FILESYSTEM, "File size overflow for 32-bit systems");
+		return -1;
+	}
+
+	size = (int)st.st_size;
+
+	if (S_ISLNK(st.st_mode)) {
+		char *link_data;
+		int read_len;
+		size_t alloc_size;
+
+		GITERR_CHECK_ALLOC_ADD(&alloc_size, size, 1);
+		link_data = git__malloc(alloc_size);
+		GITERR_CHECK_ALLOC(link_data);
+
+		read_len = p_readlink(path, link_data, size);
+		link_data[size] = '\0';
+		if (read_len != size) {
+			giterr_set(GITERR_OS, "Failed to read symlink data for '%s'", path);
+			git__free(link_data);
+			return -1;
+		}
+
+		result = git_odb_hash(out, link_data, size, GIT_OBJ_BLOB);
+		git__free(link_data);
+	} else {
+		int fd = git_futils_open_ro(path);
+		if (fd < 0)
+			return -1;
+		result = git_odb__hashfd(out, fd, size, GIT_OBJ_BLOB);
+		p_close(fd);
+	}
+
+	return result;
+}
+
+int git_odb_hashfile(git_oid *out, const char *path, git_otype type)
+{
+	git_off_t size;
+	int result, fd = git_futils_open_ro(path);
+	if (fd < 0)
+		return fd;
+
+	if ((size = git_futils_filesize(fd)) < 0 || !git__is_sizet(size)) {
+		giterr_set(GITERR_OS, "File size overflow for 32-bit systems");
+		p_close(fd);
+		return -1;
+	}
+
+	result = git_odb__hashfd(out, fd, (size_t)size, type);
+	p_close(fd);
+	return result;
+}
+
+int git_odb_hash(git_oid *id, const void *data, size_t len, git_otype type)
+{
+	git_rawobj raw;
+
+	assert(id);
+
+	raw.data = (void *)data;
+	raw.len = len;
+	raw.type = type;
+
+	return git_odb__hashobj(id, &raw);
+}
+
+/**
+ * FAKE WSTREAM
+ */
+
+typedef struct {
+	git_odb_stream stream;
+	char *buffer;
+	size_t size, written;
+	git_otype type;
+} fake_wstream;
+
+static int fake_wstream__fwrite(git_odb_stream *_stream, const git_oid *oid)
+{
+	fake_wstream *stream = (fake_wstream *)_stream;
+	return _stream->backend->write(_stream->backend, oid, stream->buffer, stream->size, stream->type);
+}
+
+static int fake_wstream__write(git_odb_stream *_stream, const char *data, size_t len)
+{
+	fake_wstream *stream = (fake_wstream *)_stream;
+
+	if (stream->written + len > stream->size)
+		return -1;
+
+	memcpy(stream->buffer + stream->written, data, len);
+	stream->written += len;
+	return 0;
+}
+
+static void fake_wstream__free(git_odb_stream *_stream)
+{
+	fake_wstream *stream = (fake_wstream *)_stream;
+
+	git__free(stream->buffer);
+	git__free(stream);
+}
+
+static int init_fake_wstream(git_odb_stream **stream_p, git_odb_backend *backend, git_off_t size, git_otype type)
+{
+	fake_wstream *stream;
+
+	if (!git__is_ssizet(size)) {
+		giterr_set(GITERR_ODB, "object size too large to keep in memory");
+		return -1;
+	}
+
+	stream = git__calloc(1, sizeof(fake_wstream));
+	GITERR_CHECK_ALLOC(stream);
+
+	stream->size = size;
+	stream->type = type;
+	stream->buffer = git__malloc(size);
+	if (stream->buffer == NULL) {
+		git__free(stream);
+		return -1;
+	}
+
+	stream->stream.backend = backend;
+	stream->stream.read = NULL; /* read only */
+	stream->stream.write = &fake_wstream__write;
+	stream->stream.finalize_write = &fake_wstream__fwrite;
+	stream->stream.free = &fake_wstream__free;
+	stream->stream.mode = GIT_STREAM_WRONLY;
+
+	*stream_p = (git_odb_stream *)stream;
+	return 0;
+}
+
+/***********************************************************
+ *
+ * OBJECT DATABASE PUBLIC API
+ *
+ * Public calls for the ODB functionality
+ *
+ ***********************************************************/
+
+static int backend_sort_cmp(const void *a, const void *b)
+{
+	const backend_internal *backend_a = (const backend_internal *)(a);
+	const backend_internal *backend_b = (const backend_internal *)(b);
+
+	if (backend_a->is_alternate == backend_b->is_alternate)
+		return (backend_b->priority - backend_a->priority);
+
+	return backend_a->is_alternate ? 1 : -1;
+}
+
+int git_odb_new(git_odb **out)
+{
+	git_odb *db = git__calloc(1, sizeof(*db));
+	GITERR_CHECK_ALLOC(db);
+
+	if (git_cache_init(&db->own_cache) < 0 ||
+		git_vector_init(&db->backends, 4, backend_sort_cmp) < 0) {
+		git__free(db);
+		return -1;
+	}
+
+	*out = db;
+	GIT_REFCOUNT_INC(db);
+	return 0;
+}
+
+static int add_backend_internal(
+	git_odb *odb, git_odb_backend *backend,
+	int priority, bool is_alternate, ino_t disk_inode)
+{
+	backend_internal *internal;
+
+	assert(odb && backend);
+
+	GITERR_CHECK_VERSION(backend, GIT_ODB_BACKEND_VERSION, "git_odb_backend");
+
+	/* Check if the backend is already owned by another ODB */
+	assert(!backend->odb || backend->odb == odb);
+
+	internal = git__malloc(sizeof(backend_internal));
+	GITERR_CHECK_ALLOC(internal);
+
+	internal->backend = backend;
+	internal->priority = priority;
+	internal->is_alternate = is_alternate;
+	internal->disk_inode = disk_inode;
+
+	if (git_vector_insert(&odb->backends, internal) < 0) {
+		git__free(internal);
+		return -1;
+	}
+
+	git_vector_sort(&odb->backends);
+	internal->backend->odb = odb;
+	return 0;
+}
+
+int git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority)
+{
+	return add_backend_internal(odb, backend, priority, false, 0);
+}
+
+int git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority)
+{
+	return add_backend_internal(odb, backend, priority, true, 0);
+}
+
+size_t git_odb_num_backends(git_odb *odb)
+{
+	assert(odb);
+	return odb->backends.length;
+}
+
+static int git_odb__error_unsupported_in_backend(const char *action)
+{
+	giterr_set(GITERR_ODB,
+		"Cannot %s - unsupported in the loaded odb backends", action);
+	return -1;
+}
+
+
+int git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos)
+{
+	backend_internal *internal;
+
+	assert(out && odb);
+	internal = git_vector_get(&odb->backends, pos);
+
+	if (internal && internal->backend) {
+		*out = internal->backend;
+		return 0;
+	}
+
+	giterr_set(GITERR_ODB, "No ODB backend loaded at index %" PRIuZ, pos);
+	return GIT_ENOTFOUND;
+}
+
+static int add_default_backends(
+	git_odb *db, const char *objects_dir,
+	bool as_alternates, int alternate_depth)
+{
+	size_t i;
+	struct stat st;
+	ino_t inode;
+	git_odb_backend *loose, *packed;
+
+	/* TODO: inodes are not really relevant on Win32, so we need to find
+	 * a cross-platform workaround for this */
+#ifdef GIT_WIN32
+	GIT_UNUSED(i);
+	GIT_UNUSED(st);
+
+	inode = 0;
+#else
+	if (p_stat(objects_dir, &st) < 0) {
+		if (as_alternates)
+			return 0;
+
+		giterr_set(GITERR_ODB, "Failed to load object database in '%s'", objects_dir);
+		return -1;
+	}
+
+	inode = st.st_ino;
+
+	for (i = 0; i < db->backends.length; ++i) {
+		backend_internal *backend = git_vector_get(&db->backends, i);
+		if (backend->disk_inode == inode)
+			return 0;
+	}
+#endif
+
+	/* add the loose object backend */
+	if (git_odb_backend_loose(&loose, objects_dir, -1, 0, 0, 0) < 0 ||
+		add_backend_internal(db, loose, GIT_LOOSE_PRIORITY, as_alternates, inode) < 0)
+		return -1;
+
+	/* add the packed file backend */
+	if (git_odb_backend_pack(&packed, objects_dir) < 0 ||
+		add_backend_internal(db, packed, GIT_PACKED_PRIORITY, as_alternates, inode) < 0)
+		return -1;
+
+	return load_alternates(db, objects_dir, alternate_depth);
+}
+
+static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_depth)
+{
+	git_buf alternates_path = GIT_BUF_INIT;
+	git_buf alternates_buf = GIT_BUF_INIT;
+	char *buffer;
+	const char *alternate;
+	int result = 0;
+
+	/* Git reports an error, we just ignore anything deeper */
+	if (alternate_depth > GIT_ALTERNATES_MAX_DEPTH)
+		return 0;
+
+	if (git_buf_joinpath(&alternates_path, objects_dir, GIT_ALTERNATES_FILE) < 0)
+		return -1;
+
+	if (git_path_exists(alternates_path.ptr) == false) {
+		git_buf_free(&alternates_path);
+		return 0;
+	}
+
+	if (git_futils_readbuffer(&alternates_buf, alternates_path.ptr) < 0) {
+		git_buf_free(&alternates_path);
+		return -1;
+	}
+
+	buffer = (char *)alternates_buf.ptr;
+
+	/* add each alternate as a new backend; one alternate per line */
+	while ((alternate = git__strtok(&buffer, "\r\n")) != NULL) {
+		if (*alternate == '\0' || *alternate == '#')
+			continue;
+
+		/*
+		 * Relative path: build based on the current `objects`
+		 * folder. However, relative paths are only allowed in
+		 * the current repository.
+		 */
+		if (*alternate == '.' && !alternate_depth) {
+			if ((result = git_buf_joinpath(&alternates_path, objects_dir, alternate)) < 0)
+				break;
+			alternate = git_buf_cstr(&alternates_path);
+		}
+
+		if ((result = add_default_backends(odb, alternate, true, alternate_depth + 1)) < 0)
+			break;
+	}
+
+	git_buf_free(&alternates_path);
+	git_buf_free(&alternates_buf);
+
+	return result;
+}
+
+int git_odb_add_disk_alternate(git_odb *odb, const char *path)
+{
+	return add_default_backends(odb, path, true, 0);
+}
+
+int git_odb_open(git_odb **out, const char *objects_dir)
+{
+	git_odb *db;
+
+	assert(out && objects_dir);
+
+	*out = NULL;
+
+	if (git_odb_new(&db) < 0)
+		return -1;
+
+	if (add_default_backends(db, objects_dir, 0, 0) < 0) {
+		git_odb_free(db);
+		return -1;
+	}
+
+	*out = db;
+	return 0;
+}
+
+static void odb_free(git_odb *db)
+{
+	size_t i;
+
+	for (i = 0; i < db->backends.length; ++i) {
+		backend_internal *internal = git_vector_get(&db->backends, i);
+		git_odb_backend *backend = internal->backend;
+
+		if (backend->free) backend->free(backend);
+		else git__free(backend);
+
+		git__free(internal);
+	}
+
+	git_vector_free(&db->backends);
+	git_cache_free(&db->own_cache);
+
+	git__memzero(db, sizeof(*db));
+	git__free(db);
+}
+
+void git_odb_free(git_odb *db)
+{
+	if (db == NULL)
+		return;
+
+	GIT_REFCOUNT_DEC(db, odb_free);
+}
+
+int git_odb_exists(git_odb *db, const git_oid *id)
+{
+	git_odb_object *object;
+	size_t i;
+	bool found = false;
+
+	assert(db && id);
+
+	if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) {
+		git_odb_object_free(object);
+		return (int)true;
+	}
+
+	for (i = 0; i < db->backends.length && !found; ++i) {
+		backend_internal *internal = git_vector_get(&db->backends, i);
+		git_odb_backend *b = internal->backend;
+
+		if (b->exists != NULL)
+			found = (bool)b->exists(b, id);
+	}
+
+	return (int)found;
+}
+
+int git_odb_exists_prefix(
+	git_oid *out, git_odb *db, const git_oid *short_id, size_t len)
+{
+	int error = GIT_ENOTFOUND, num_found = 0;
+	size_t i;
+	git_oid key = {{0}}, last_found = {{0}}, found;
+
+	assert(db && short_id);
+
+	if (len < GIT_OID_MINPREFIXLEN)
+		return git_odb__error_ambiguous("prefix length too short");
+	if (len > GIT_OID_HEXSZ)
+		len = GIT_OID_HEXSZ;
+
+	if (len == GIT_OID_HEXSZ) {
+		if (git_odb_exists(db, short_id)) {
+			if (out)
+				git_oid_cpy(out, short_id);
+			return 0;
+		} else {
+			return git_odb__error_notfound("no match for id prefix", short_id);
+		}
+	}
+
+	/* just copy valid part of short_id */
+	memcpy(&key.id, short_id->id, (len + 1) / 2);
+	if (len & 1)
+		key.id[len / 2] &= 0xF0;
+
+	for (i = 0; i < db->backends.length; ++i) {
+		backend_internal *internal = git_vector_get(&db->backends, i);
+		git_odb_backend *b = internal->backend;
+
+		if (!b->exists_prefix)
+			continue;
+
+		error = b->exists_prefix(&found, b, &key, len);
+		if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH)
+			continue;
+		if (error)
+			return error;
+
+		/* make sure found item doesn't introduce ambiguity */
+		if (num_found) {
+			if (git_oid__cmp(&last_found, &found))
+				return git_odb__error_ambiguous("multiple matches for prefix");
+		} else {
+			git_oid_cpy(&last_found, &found);
+			num_found++;
+		}
+	}
+
+	if (!num_found)
+		return git_odb__error_notfound("no match for id prefix", &key);
+	if (out)
+		git_oid_cpy(out, &last_found);
+
+	return 0;
+}
+
+int git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *db, const git_oid *id)
+{
+	int error;
+	git_odb_object *object;
+
+	error = git_odb__read_header_or_object(&object, len_p, type_p, db, id);
+
+	if (object)
+		git_odb_object_free(object);
+
+	return error;
+}
+
+int git_odb__read_header_or_object(
+	git_odb_object **out, size_t *len_p, git_otype *type_p,
+	git_odb *db, const git_oid *id)
+{
+	size_t i;
+	int error = GIT_ENOTFOUND;
+	git_odb_object *object;
+
+	assert(db && id && out && len_p && type_p);
+
+	if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) {
+		*len_p = object->cached.size;
+		*type_p = object->cached.type;
+		*out = object;
+		return 0;
+	}
+
+	*out = NULL;
+
+	for (i = 0; i < db->backends.length && error < 0; ++i) {
+		backend_internal *internal = git_vector_get(&db->backends, i);
+		git_odb_backend *b = internal->backend;
+
+		if (b->read_header != NULL)
+			error = b->read_header(len_p, type_p, b, id);
+	}
+
+	if (!error || error == GIT_PASSTHROUGH)
+		return 0;
+
+	/*
+	 * no backend could read only the header.
+	 * try reading the whole object and freeing the contents
+	 */
+	if ((error = git_odb_read(&object, db, id)) < 0)
+		return error; /* error already set - pass along */
+
+	*len_p = object->cached.size;
+	*type_p = object->cached.type;
+	*out = object;
+
+	return 0;
+}
+
+static git_oid empty_blob = {{ 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b,
+			       0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 }};
+static git_oid empty_tree = {{ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
+			       0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }};
+
+static int hardcoded_objects(git_rawobj *raw, const git_oid *id)
+{
+	if (!git_oid_cmp(id, &empty_blob)) {
+		raw->type = GIT_OBJ_BLOB;
+		raw->len = 0;
+		raw->data = git__calloc(1, sizeof(uint8_t));
+		return 0;
+	} else if (!git_oid_cmp(id, &empty_tree)) {
+		raw->type = GIT_OBJ_TREE;
+		raw->len = 0;
+		raw->data = git__calloc(1, sizeof(uint8_t));
+		return 0;
+	} else {
+		return GIT_ENOTFOUND;
+	}
+}
+
+int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
+{
+	size_t i, reads = 0;
+	int error;
+	git_rawobj raw;
+	git_odb_object *object;
+
+	assert(out && db && id);
+
+	*out = git_cache_get_raw(odb_cache(db), id);
+	if (*out != NULL)
+		return 0;
+
+	error = hardcoded_objects(&raw, id);
+
+	for (i = 0; i < db->backends.length && error < 0; ++i) {
+		backend_internal *internal = git_vector_get(&db->backends, i);
+		git_odb_backend *b = internal->backend;
+
+		if (b->read != NULL) {
+			++reads;
+			error = b->read(&raw.data, &raw.len, &raw.type, b, id);
+		}
+	}
+
+	if (error && error != GIT_PASSTHROUGH) {
+		if (!reads)
+			return git_odb__error_notfound("no match for id", id);
+		return error;
+	}
+
+	giterr_clear();
+	if ((object = odb_object__alloc(id, &raw)) == NULL)
+		return -1;
+
+	*out = git_cache_store_raw(odb_cache(db), object);
+	return 0;
+}
+
+int git_odb_read_prefix(
+	git_odb_object **out, git_odb *db, const git_oid *short_id, size_t len)
+{
+	size_t i;
+	int error = GIT_ENOTFOUND;
+	git_oid key = {{0}}, found_full_oid = {{0}};
+	git_rawobj raw;
+	void *data = NULL;
+	bool found = false;
+	git_odb_object *object;
+
+	assert(out && db);
+
+	if (len < GIT_OID_MINPREFIXLEN)
+		return git_odb__error_ambiguous("prefix length too short");
+	if (len > GIT_OID_HEXSZ)
+		len = GIT_OID_HEXSZ;
+
+	if (len == GIT_OID_HEXSZ) {
+		*out = git_cache_get_raw(odb_cache(db), short_id);
+		if (*out != NULL)
+			return 0;
+	}
+
+	/* just copy valid part of short_id */
+	memcpy(&key.id, short_id->id, (len + 1) / 2);
+	if (len & 1)
+		key.id[len / 2] &= 0xF0;
+
+	for (i = 0; i < db->backends.length; ++i) {
+		backend_internal *internal = git_vector_get(&db->backends, i);
+		git_odb_backend *b = internal->backend;
+
+		if (b->read_prefix != NULL) {
+			git_oid full_oid;
+			error = b->read_prefix(&full_oid, &raw.data, &raw.len, &raw.type, b, &key, len);
+			if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH)
+				continue;
+
+			if (error)
+				return error;
+
+			git__free(data);
+			data = raw.data;
+
+			if (found && git_oid__cmp(&full_oid, &found_full_oid)) {
+				git__free(raw.data);
+				return git_odb__error_ambiguous("multiple matches for prefix");
+			}
+
+			found_full_oid = full_oid;
+			found = true;
+		}
+	}
+
+	if (!found)
+		return git_odb__error_notfound("no match for prefix", &key);
+
+	if ((object = odb_object__alloc(&found_full_oid, &raw)) == NULL)
+		return -1;
+
+	*out = git_cache_store_raw(odb_cache(db), object);
+	return 0;
+}
+
+int git_odb_foreach(git_odb *db, git_odb_foreach_cb cb, void *payload)
+{
+	unsigned int i;
+	backend_internal *internal;
+
+	git_vector_foreach(&db->backends, i, internal) {
+		git_odb_backend *b = internal->backend;
+		int error = b->foreach(b, cb, payload);
+		if (error < 0)
+			return error;
+	}
+
+	return 0;
+}
+
+int git_odb_write(
+	git_oid *oid, git_odb *db, const void *data, size_t len, git_otype type)
+{
+	size_t i;
+	int error = GIT_ERROR;
+	git_odb_stream *stream;
+
+	assert(oid && db);
+
+	git_odb_hash(oid, data, len, type);
+	if (git_odb_exists(db, oid))
+		return 0;
+
+	for (i = 0; i < db->backends.length && error < 0; ++i) {
+		backend_internal *internal = git_vector_get(&db->backends, i);
+		git_odb_backend *b = internal->backend;
+
+		/* we don't write in alternates! */
+		if (internal->is_alternate)
+			continue;
+
+		if (b->write != NULL)
+			error = b->write(b, oid, data, len, type);
+	}
+
+	if (!error || error == GIT_PASSTHROUGH)
+		return 0;
+
+	/* if no backends were able to write the object directly, we try a
+	 * streaming write to the backends; just write the whole object into the
+	 * stream in one push
+	 */
+	if ((error = git_odb_open_wstream(&stream, db, len, type)) != 0)
+		return error;
+
+	stream->write(stream, data, len);
+	error = stream->finalize_write(stream, oid);
+	git_odb_stream_free(stream);
+
+	return error;
+}
+
+static void hash_header(git_hash_ctx *ctx, git_off_t size, git_otype type)
+{
+	char header[64];
+	int hdrlen;
+
+	hdrlen = git_odb__format_object_header(header, sizeof(header), size, type);
+	git_hash_update(ctx, header, hdrlen);
+}
+
+int git_odb_open_wstream(
+	git_odb_stream **stream, git_odb *db, git_off_t size, git_otype type)
+{
+	size_t i, writes = 0;
+	int error = GIT_ERROR;
+	git_hash_ctx *ctx = NULL;
+
+	assert(stream && db);
+
+	for (i = 0; i < db->backends.length && error < 0; ++i) {
+		backend_internal *internal = git_vector_get(&db->backends, i);
+		git_odb_backend *b = internal->backend;
+
+		/* we don't write in alternates! */
+		if (internal->is_alternate)
+			continue;
+
+		if (b->writestream != NULL) {
+			++writes;
+			error = b->writestream(stream, b, size, type);
+		} else if (b->write != NULL) {
+			++writes;
+			error = init_fake_wstream(stream, b, size, type);
+		}
+	}
+
+	if (error < 0) {
+		if (error == GIT_PASSTHROUGH)
+			error = 0;
+		else if (!writes)
+			error = git_odb__error_unsupported_in_backend("write object");
+
+		goto done;
+	}
+
+	ctx = git__malloc(sizeof(git_hash_ctx));
+	GITERR_CHECK_ALLOC(ctx);
+
+	if ((error = git_hash_ctx_init(ctx)) < 0)
+		goto done;
+
+	hash_header(ctx, size, type);
+	(*stream)->hash_ctx = ctx;
+
+	(*stream)->declared_size = size;
+	(*stream)->received_bytes = 0;
+
+done:
+	return error;
+}
+
+static int git_odb_stream__invalid_length(
+	const git_odb_stream *stream,
+	const char *action)
+{
+	giterr_set(GITERR_ODB,
+		"Cannot %s - "
+		"Invalid length. %"PRIuZ" was expected. The "
+		"total size of the received chunks amounts to %"PRIuZ".",
+		action, stream->declared_size, stream->received_bytes);		
+
+	return -1;
+}
+
+int git_odb_stream_write(git_odb_stream *stream, const char *buffer, size_t len)
+{
+	git_hash_update(stream->hash_ctx, buffer, len);
+
+	stream->received_bytes += len;
+
+	if (stream->received_bytes > stream->declared_size)
+		return git_odb_stream__invalid_length(stream,
+			"stream_write()");
+
+	return stream->write(stream, buffer, len);
+}
+
+int git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stream)
+{
+	if (stream->received_bytes != stream->declared_size)
+		return git_odb_stream__invalid_length(stream,
+			"stream_finalize_write()");
+
+	git_hash_final(out, stream->hash_ctx);
+
+	if (git_odb_exists(stream->backend->odb, out))
+		return 0;
+
+	return stream->finalize_write(stream, out);
+}
+
+int git_odb_stream_read(git_odb_stream *stream, char *buffer, size_t len)
+{
+	return stream->read(stream, buffer, len);
+}
+
+void git_odb_stream_free(git_odb_stream *stream)
+{
+	if (stream == NULL)
+		return;
+
+	git_hash_ctx_cleanup(stream->hash_ctx);
+	git__free(stream->hash_ctx);
+	stream->free(stream);
+}
+
+int git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oid)
+{
+	size_t i, reads = 0;
+	int error = GIT_ERROR;
+
+	assert(stream && db);
+
+	for (i = 0; i < db->backends.length && error < 0; ++i) {
+		backend_internal *internal = git_vector_get(&db->backends, i);
+		git_odb_backend *b = internal->backend;
+
+		if (b->readstream != NULL) {
+			++reads;
+			error = b->readstream(stream, b, oid);
+		}
+	}
+
+	if (error == GIT_PASSTHROUGH)
+		error = 0;
+	if (error < 0 && !reads)
+		error = git_odb__error_unsupported_in_backend("read object streamed");
+
+	return error;
+}
+
+int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_transfer_progress_cb progress_cb, void *progress_payload)
+{
+	size_t i, writes = 0;
+	int error = GIT_ERROR;
+
+	assert(out && db);
+
+	for (i = 0; i < db->backends.length && error < 0; ++i) {
+		backend_internal *internal = git_vector_get(&db->backends, i);
+		git_odb_backend *b = internal->backend;
+
+		/* we don't write in alternates! */
+		if (internal->is_alternate)
+			continue;
+
+		if (b->writepack != NULL) {
+			++writes;
+			error = b->writepack(out, b, db, progress_cb, progress_payload);
+		}
+	}
+
+	if (error == GIT_PASSTHROUGH)
+		error = 0;
+	if (error < 0 && !writes)
+		error = git_odb__error_unsupported_in_backend("write pack");
+
+	return error;
+}
+
+void *git_odb_backend_malloc(git_odb_backend *backend, size_t len)
+{
+	GIT_UNUSED(backend);
+	return git__malloc(len);
+}
+
+int git_odb_refresh(struct git_odb *db)
+{
+	size_t i;
+	assert(db);
+
+	for (i = 0; i < db->backends.length; ++i) {
+		backend_internal *internal = git_vector_get(&db->backends, i);
+		git_odb_backend *b = internal->backend;
+
+		if (b->refresh != NULL) {
+			int error = b->refresh(b);
+			if (error < 0)
+				return error;
+		}
+	}
+
+	return 0;
+}
+
+int git_odb__error_notfound(const char *message, const git_oid *oid)
+{
+	if (oid != NULL) {
+		char oid_str[GIT_OID_HEXSZ + 1];
+		git_oid_tostr(oid_str, sizeof(oid_str), oid);
+		giterr_set(GITERR_ODB, "Object not found - %s (%s)", message, oid_str);
+	} else
+		giterr_set(GITERR_ODB, "Object not found - %s", message);
+
+	return GIT_ENOTFOUND;
+}
+
+int git_odb__error_ambiguous(const char *message)
+{
+	giterr_set(GITERR_ODB, "Ambiguous SHA1 prefix - %s", message);
+	return GIT_EAMBIGUOUS;
+}
+
+int git_odb_init_backend(git_odb_backend *backend, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		backend, version, git_odb_backend, GIT_ODB_BACKEND_INIT);
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/odb.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/odb.h
new file mode 100755
index 0000000..281bd3a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/odb.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_odb_h__
+#define INCLUDE_odb_h__
+
+#include "git2/odb.h"
+#include "git2/oid.h"
+#include "git2/types.h"
+
+#include "vector.h"
+#include "cache.h"
+#include "posix.h"
+#include "filter.h"
+
+#define GIT_OBJECTS_DIR "objects/"
+#define GIT_OBJECT_DIR_MODE 0777
+#define GIT_OBJECT_FILE_MODE 0444
+
+/* DO NOT EXPORT */
+typedef struct {
+	void *data;			/**< Raw, decompressed object data. */
+	size_t len;			/**< Total number of bytes in data. */
+	git_otype type;		/**< Type of this object. */
+} git_rawobj;
+
+/* EXPORT */
+struct git_odb_object {
+	git_cached_obj cached;
+	void *buffer;
+};
+
+/* EXPORT */
+struct git_odb {
+	git_refcount rc;
+	git_vector backends;
+	git_cache own_cache;
+};
+
+/*
+ * Hash a git_rawobj internally.
+ * The `git_rawobj` is supposed to be previously initialized
+ */
+int git_odb__hashobj(git_oid *id, git_rawobj *obj);
+
+/*
+ * Format the object header such as it would appear in the on-disk object
+ */
+int git_odb__format_object_header(char *hdr, size_t n, git_off_t obj_len, git_otype obj_type);
+/*
+ * Hash an open file descriptor.
+ * This is a performance call when the contents of a fd need to be hashed,
+ * but the fd is already open and we have the size of the contents.
+ *
+ * Saves us some `stat` calls.
+ *
+ * The fd is never closed, not even on error. It must be opened and closed
+ * by the caller
+ */
+int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type);
+
+/*
+ * Hash an open file descriptor applying an array of filters
+ * Acts just like git_odb__hashfd with the addition of filters...
+ */
+int git_odb__hashfd_filtered(
+	git_oid *out, git_file fd, size_t len, git_otype type, git_filter_list *fl);
+
+/*
+ * Hash a `path`, assuming it could be a POSIX symlink: if the path is a
+ * symlink, then the raw contents of the symlink will be hashed. Otherwise,
+ * this will fallback to `git_odb__hashfd`.
+ *
+ * The hash type for this call is always `GIT_OBJ_BLOB` because symlinks may
+ * only point to blobs.
+ */
+int git_odb__hashlink(git_oid *out, const char *path);
+
+/*
+ * Generate a GIT_ENOTFOUND error for the ODB.
+ */
+int git_odb__error_notfound(const char *message, const git_oid *oid);
+
+/*
+ * Generate a GIT_EAMBIGUOUS error for the ODB.
+ */
+int git_odb__error_ambiguous(const char *message);
+
+/*
+ * Attempt to read object header or just return whole object if it could
+ * not be read.
+ */
+int git_odb__read_header_or_object(
+	git_odb_object **out, size_t *len_p, git_otype *type_p,
+	git_odb *db, const git_oid *id);
+
+/* fully free the object; internal method, DO NOT EXPORT */
+void git_odb_object__free(void *object);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/odb_loose.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/odb_loose.c
new file mode 100755
index 0000000..99b8f7c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/odb_loose.c
@@ -0,0 +1,978 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include <zlib.h>
+#include "git2/object.h"
+#include "git2/sys/odb_backend.h"
+#include "fileops.h"
+#include "hash.h"
+#include "odb.h"
+#include "delta-apply.h"
+#include "filebuf.h"
+
+#include "git2/odb_backend.h"
+#include "git2/types.h"
+
+typedef struct { /* object header data */
+	git_otype type; /* object type */
+	size_t	size; /* object size */
+} obj_hdr;
+
+typedef struct {
+	git_odb_stream stream;
+	git_filebuf fbuf;
+} loose_writestream;
+
+typedef struct loose_backend {
+	git_odb_backend parent;
+
+	int object_zlib_level; /** loose object zlib compression level. */
+	int fsync_object_files; /** loose object file fsync flag. */
+	mode_t object_file_mode;
+	mode_t object_dir_mode;
+
+	size_t objects_dirlen;
+	char objects_dir[GIT_FLEX_ARRAY];
+} loose_backend;
+
+/* State structure for exploring directories,
+ * in order to locate objects matching a short oid.
+ */
+typedef struct {
+	size_t dir_len;
+	unsigned char short_oid[GIT_OID_HEXSZ]; /* hex formatted oid to match */
+	size_t short_oid_len;
+	int found;				/* number of matching
+						 * objects already found */
+	unsigned char res_oid[GIT_OID_HEXSZ];	/* hex formatted oid of
+						 * the object found */
+} loose_locate_object_state;
+
+
+/***********************************************************
+ *
+ * MISCELLANEOUS HELPER FUNCTIONS
+ *
+ ***********************************************************/
+
+static int object_file_name(
+	git_buf *name, const loose_backend *be, const git_oid *id)
+{
+	size_t alloclen;
+
+	/* expand length for object root + 40 hex sha1 chars + 2 * '/' + '\0' */
+	GITERR_CHECK_ALLOC_ADD(&alloclen, be->objects_dirlen, GIT_OID_HEXSZ);
+	GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 3);
+	if (git_buf_grow(name, alloclen) < 0)
+		return -1;
+
+	git_buf_set(name, be->objects_dir, be->objects_dirlen);
+	git_path_to_dir(name);
+
+	/* loose object filename: aa/aaa... (41 bytes) */
+	git_oid_pathfmt(name->ptr + name->size, id);
+	name->size += GIT_OID_HEXSZ + 1;
+	name->ptr[name->size] = '\0';
+
+	return 0;
+}
+
+static int object_mkdir(const git_buf *name, const loose_backend *be)
+{
+	return git_futils_mkdir(
+		name->ptr + be->objects_dirlen, be->objects_dir, be->object_dir_mode,
+		GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST | GIT_MKDIR_VERIFY_DIR);
+}
+
+static size_t get_binary_object_header(obj_hdr *hdr, git_buf *obj)
+{
+	unsigned char c;
+	unsigned char *data = (unsigned char *)obj->ptr;
+	size_t shift, size, used = 0;
+
+	if (git_buf_len(obj) == 0)
+		return 0;
+
+	c = data[used++];
+	hdr->type = (c >> 4) & 7;
+
+	size = c & 15;
+	shift = 4;
+	while (c & 0x80) {
+		if (git_buf_len(obj) <= used)
+			return 0;
+		if (sizeof(size_t) * 8 <= shift)
+			return 0;
+		c = data[used++];
+		size += (c & 0x7f) << shift;
+		shift += 7;
+	}
+	hdr->size = size;
+
+	return used;
+}
+
+static size_t get_object_header(obj_hdr *hdr, unsigned char *data)
+{
+	char c, typename[10];
+	size_t size, used = 0;
+
+	/*
+	 * type name string followed by space.
+	 */
+	while ((c = data[used]) != ' ') {
+		typename[used++] = c;
+		if (used >= sizeof(typename))
+			return 0;
+	}
+	typename[used] = 0;
+	if (used == 0)
+		return 0;
+	hdr->type = git_object_string2type(typename);
+	used++; /* consume the space */
+
+	/*
+	 * length follows immediately in decimal (without
+	 * leading zeros).
+	 */
+	size = data[used++] - '0';
+	if (size > 9)
+		return 0;
+	if (size) {
+		while ((c = data[used]) != '\0') {
+			size_t d = c - '0';
+			if (d > 9)
+				break;
+			used++;
+			size = size * 10 + d;
+		}
+	}
+	hdr->size = size;
+
+	/*
+	 * the length must be followed by a zero byte
+	 */
+	if (data[used++] != '\0')
+		return 0;
+
+	return used;
+}
+
+
+
+/***********************************************************
+ *
+ * ZLIB RELATED FUNCTIONS
+ *
+ ***********************************************************/
+
+static void init_stream(z_stream *s, void *out, size_t len)
+{
+	memset(s, 0, sizeof(*s));
+	s->next_out = out;
+	s->avail_out = (uInt)len;
+}
+
+static void set_stream_input(z_stream *s, void *in, size_t len)
+{
+	s->next_in = in;
+	s->avail_in = (uInt)len;
+}
+
+static void set_stream_output(z_stream *s, void *out, size_t len)
+{
+	s->next_out = out;
+	s->avail_out = (uInt)len;
+}
+
+
+static int start_inflate(z_stream *s, git_buf *obj, void *out, size_t len)
+{
+	int status;
+
+	init_stream(s, out, len);
+	set_stream_input(s, obj->ptr, git_buf_len(obj));
+
+	if ((status = inflateInit(s)) < Z_OK)
+		return status;
+
+	return inflate(s, 0);
+}
+
+static int finish_inflate(z_stream *s)
+{
+	int status = Z_OK;
+
+	while (status == Z_OK)
+		status = inflate(s, Z_FINISH);
+
+	inflateEnd(s);
+
+	if ((status != Z_STREAM_END) || (s->avail_in != 0)) {
+		giterr_set(GITERR_ZLIB, "Failed to finish ZLib inflation. Stream aborted prematurely");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int is_zlib_compressed_data(unsigned char *data)
+{
+	unsigned int w;
+
+	w = ((unsigned int)(data[0]) << 8) + data[1];
+	return (data[0] & 0x8F) == 0x08 && !(w % 31);
+}
+
+static int inflate_buffer(void *in, size_t inlen, void *out, size_t outlen)
+{
+	z_stream zs;
+	int status = Z_OK;
+
+	memset(&zs, 0x0, sizeof(zs));
+
+	zs.next_out = out;
+	zs.avail_out = (uInt)outlen;
+
+	zs.next_in = in;
+	zs.avail_in = (uInt)inlen;
+
+	if (inflateInit(&zs) < Z_OK) {
+		giterr_set(GITERR_ZLIB, "Failed to inflate buffer");
+		return -1;
+	}
+
+	while (status == Z_OK)
+		status = inflate(&zs, Z_FINISH);
+
+	inflateEnd(&zs);
+
+	if (status != Z_STREAM_END /* || zs.avail_in != 0 */ ||
+		zs.total_out != outlen)
+	{
+		giterr_set(GITERR_ZLIB, "Failed to inflate buffer. Stream aborted prematurely");
+		return -1;
+	}
+
+	return 0;
+}
+
+static void *inflate_tail(z_stream *s, void *hb, size_t used, obj_hdr *hdr)
+{
+	unsigned char *buf, *head = hb;
+	size_t tail, alloc_size;
+
+	/*
+	 * allocate a buffer to hold the inflated data and copy the
+	 * initial sequence of inflated data from the tail of the
+	 * head buffer, if any.
+	 */
+	if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, hdr->size, 1) ||
+		(buf = git__malloc(alloc_size)) == NULL) {
+		inflateEnd(s);
+		return NULL;
+	}
+	tail = s->total_out - used;
+	if (used > 0 && tail > 0) {
+		if (tail > hdr->size)
+			tail = hdr->size;
+		memcpy(buf, head + used, tail);
+	}
+	used = tail;
+
+	/*
+	 * inflate the remainder of the object data, if any
+	 */
+	if (hdr->size < used)
+		inflateEnd(s);
+	else {
+		set_stream_output(s, buf + used, hdr->size - used);
+		if (finish_inflate(s)) {
+			git__free(buf);
+			return NULL;
+		}
+	}
+
+	return buf;
+}
+
+/*
+ * At one point, there was a loose object format that was intended to
+ * mimic the format used in pack-files. This was to allow easy copying
+ * of loose object data into packs. This format is no longer used, but
+ * we must still read it.
+ */
+static int inflate_packlike_loose_disk_obj(git_rawobj *out, git_buf *obj)
+{
+	unsigned char *in, *buf;
+	obj_hdr hdr;
+	size_t len, used, alloclen;
+
+	/*
+	 * read the object header, which is an (uncompressed)
+	 * binary encoding of the object type and size.
+	 */
+	if ((used = get_binary_object_header(&hdr, obj)) == 0 ||
+		!git_object_typeisloose(hdr.type)) {
+		giterr_set(GITERR_ODB, "Failed to inflate loose object.");
+		return -1;
+	}
+
+	/*
+	 * allocate a buffer and inflate the data into it
+	 */
+	GITERR_CHECK_ALLOC_ADD(&alloclen, hdr.size, 1);
+	buf = git__malloc(alloclen);
+	GITERR_CHECK_ALLOC(buf);
+
+	in = ((unsigned char *)obj->ptr) + used;
+	len = obj->size - used;
+	if (inflate_buffer(in, len, buf, hdr.size) < 0) {
+		git__free(buf);
+		return -1;
+	}
+	buf[hdr.size] = '\0';
+
+	out->data = buf;
+	out->len = hdr.size;
+	out->type = hdr.type;
+
+	return 0;
+}
+
+static int inflate_disk_obj(git_rawobj *out, git_buf *obj)
+{
+	unsigned char head[64], *buf;
+	z_stream zs;
+	obj_hdr hdr;
+	size_t used;
+
+	/*
+	 * check for a pack-like loose object
+	 */
+	if (!is_zlib_compressed_data((unsigned char *)obj->ptr))
+		return inflate_packlike_loose_disk_obj(out, obj);
+
+	/*
+	 * inflate the initial part of the io buffer in order
+	 * to parse the object header (type and size).
+	 */
+	if (start_inflate(&zs, obj, head, sizeof(head)) < Z_OK ||
+		(used = get_object_header(&hdr, head)) == 0 ||
+		!git_object_typeisloose(hdr.type))
+	{
+		giterr_set(GITERR_ODB, "Failed to inflate disk object.");
+		return -1;
+	}
+
+	/*
+	 * allocate a buffer and inflate the object data into it
+	 * (including the initial sequence in the head buffer).
+	 */
+	if ((buf = inflate_tail(&zs, head, used, &hdr)) == NULL)
+		return -1;
+	buf[hdr.size] = '\0';
+
+	out->data = buf;
+	out->len = hdr.size;
+	out->type = hdr.type;
+
+	return 0;
+}
+
+
+
+
+
+
+/***********************************************************
+ *
+ * ODB OBJECT READING & WRITING
+ *
+ * Backend for the public API; read headers and full objects
+ * from the ODB. Write raw data to the ODB.
+ *
+ ***********************************************************/
+
+static int read_loose(git_rawobj *out, git_buf *loc)
+{
+	int error;
+	git_buf obj = GIT_BUF_INIT;
+
+	assert(out && loc);
+
+	if (git_buf_oom(loc))
+		return -1;
+
+	out->data = NULL;
+	out->len = 0;
+	out->type = GIT_OBJ_BAD;
+
+	if (!(error = git_futils_readbuffer(&obj, loc->ptr)))
+		error = inflate_disk_obj(out, &obj);
+
+	git_buf_free(&obj);
+
+	return error;
+}
+
+static int read_header_loose(git_rawobj *out, git_buf *loc)
+{
+	int error = 0, z_return = Z_ERRNO, read_bytes;
+	git_file fd;
+	z_stream zs;
+	obj_hdr header_obj;
+	unsigned char raw_buffer[16], inflated_buffer[64];
+
+	assert(out && loc);
+
+	if (git_buf_oom(loc))
+		return -1;
+
+	out->data = NULL;
+
+	if ((fd = git_futils_open_ro(loc->ptr)) < 0)
+		return fd;
+
+	init_stream(&zs, inflated_buffer, sizeof(inflated_buffer));
+
+	z_return = inflateInit(&zs);
+
+	while (z_return == Z_OK) {
+		if ((read_bytes = p_read(fd, raw_buffer, sizeof(raw_buffer))) > 0) {
+			set_stream_input(&zs, raw_buffer, read_bytes);
+			z_return = inflate(&zs, 0);
+		} else
+			z_return = Z_STREAM_END;
+	}
+
+	if ((z_return != Z_STREAM_END && z_return != Z_BUF_ERROR)
+		|| get_object_header(&header_obj, inflated_buffer) == 0
+		|| git_object_typeisloose(header_obj.type) == 0)
+	{
+		giterr_set(GITERR_ZLIB, "Failed to read loose object header");
+		error = -1;
+	} else {
+		out->len = header_obj.size;
+		out->type = header_obj.type;
+	}
+
+	finish_inflate(&zs);
+	p_close(fd);
+
+	return error;
+}
+
+static int locate_object(
+	git_buf *object_location,
+	loose_backend *backend,
+	const git_oid *oid)
+{
+	int error = object_file_name(object_location, backend, oid);
+
+	if (!error && !git_path_exists(object_location->ptr))
+		return GIT_ENOTFOUND;
+
+	return error;
+}
+
+/* Explore an entry of a directory and see if it matches a short oid */
+static int fn_locate_object_short_oid(void *state, git_buf *pathbuf) {
+	loose_locate_object_state *sstate = (loose_locate_object_state *)state;
+
+	if (git_buf_len(pathbuf) - sstate->dir_len != GIT_OID_HEXSZ - 2) {
+		/* Entry cannot be an object. Continue to next entry */
+		return 0;
+	}
+
+	if (git_path_isdir(pathbuf->ptr) == false) {
+		/* We are already in the directory matching the 2 first hex characters,
+		 * compare the first ncmp characters of the oids */
+		if (!memcmp(sstate->short_oid + 2,
+			(unsigned char *)pathbuf->ptr + sstate->dir_len,
+			sstate->short_oid_len - 2)) {
+
+			if (!sstate->found) {
+				sstate->res_oid[0] = sstate->short_oid[0];
+				sstate->res_oid[1] = sstate->short_oid[1];
+				memcpy(sstate->res_oid+2, pathbuf->ptr+sstate->dir_len, GIT_OID_HEXSZ-2);
+			}
+			sstate->found++;
+		}
+	}
+
+	if (sstate->found > 1)
+		return GIT_EAMBIGUOUS;
+
+	return 0;
+}
+
+/* Locate an object matching a given short oid */
+static int locate_object_short_oid(
+	git_buf *object_location,
+	git_oid *res_oid,
+	loose_backend *backend,
+	const git_oid *short_oid,
+	size_t len)
+{
+	char *objects_dir = backend->objects_dir;
+	size_t dir_len = strlen(objects_dir), alloc_len;
+	loose_locate_object_state state;
+	int error;
+
+	/* prealloc memory for OBJ_DIR/xx/xx..38x..xx */
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, dir_len, GIT_OID_HEXSZ);
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 3);
+	if (git_buf_grow(object_location, alloc_len) < 0)
+		return -1;
+
+	git_buf_set(object_location, objects_dir, dir_len);
+	git_path_to_dir(object_location);
+
+	/* save adjusted position at end of dir so it can be restored later */
+	dir_len = git_buf_len(object_location);
+
+	/* Convert raw oid to hex formatted oid */
+	git_oid_fmt((char *)state.short_oid, short_oid);
+
+	/* Explore OBJ_DIR/xx/ where xx is the beginning of hex formatted short oid */
+	if (git_buf_put(object_location, (char *)state.short_oid, 3) < 0)
+		return -1;
+	object_location->ptr[object_location->size - 1] = '/';
+
+	/* Check that directory exists */
+	if (git_path_isdir(object_location->ptr) == false)
+		return git_odb__error_notfound("no matching loose object for prefix", short_oid);
+
+	state.dir_len = git_buf_len(object_location);
+	state.short_oid_len = len;
+	state.found = 0;
+
+	/* Explore directory to find a unique object matching short_oid */
+	error = git_path_direach(
+		object_location, 0, fn_locate_object_short_oid, &state);
+	if (error < 0 && error != GIT_EAMBIGUOUS)
+		return error;
+
+	if (!state.found)
+		return git_odb__error_notfound("no matching loose object for prefix", short_oid);
+
+	if (state.found > 1)
+		return git_odb__error_ambiguous("multiple matches in loose objects");
+
+	/* Convert obtained hex formatted oid to raw */
+	error = git_oid_fromstr(res_oid, (char *)state.res_oid);
+	if (error)
+		return error;
+
+	/* Update the location according to the oid obtained */
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, dir_len, GIT_OID_HEXSZ);
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
+
+	git_buf_truncate(object_location, dir_len);
+	if (git_buf_grow(object_location, alloc_len) < 0)
+		return -1;
+
+	git_oid_pathfmt(object_location->ptr + dir_len, res_oid);
+
+	object_location->size += GIT_OID_HEXSZ + 1;
+	object_location->ptr[object_location->size] = '\0';
+
+	return 0;
+}
+
+
+
+
+
+
+
+
+
+/***********************************************************
+ *
+ * LOOSE BACKEND PUBLIC API
+ *
+ * Implement the git_odb_backend API calls
+ *
+ ***********************************************************/
+
+static int loose_backend__read_header(size_t *len_p, git_otype *type_p, git_odb_backend *backend, const git_oid *oid)
+{
+	git_buf object_path = GIT_BUF_INIT;
+	git_rawobj raw;
+	int error;
+
+	assert(backend && oid);
+
+	raw.len = 0;
+	raw.type = GIT_OBJ_BAD;
+
+	if (locate_object(&object_path, (loose_backend *)backend, oid) < 0)
+		error = git_odb__error_notfound("no matching loose object", oid);
+	else if ((error = read_header_loose(&raw, &object_path)) == 0) {
+		*len_p = raw.len;
+		*type_p = raw.type;
+	}
+
+	git_buf_free(&object_path);
+
+	return error;
+}
+
+static int loose_backend__read(void **buffer_p, size_t *len_p, git_otype *type_p, git_odb_backend *backend, const git_oid *oid)
+{
+	git_buf object_path = GIT_BUF_INIT;
+	git_rawobj raw;
+	int error = 0;
+
+	assert(backend && oid);
+
+	if (locate_object(&object_path, (loose_backend *)backend, oid) < 0)
+		error = git_odb__error_notfound("no matching loose object", oid);
+	else if ((error = read_loose(&raw, &object_path)) == 0) {
+		*buffer_p = raw.data;
+		*len_p = raw.len;
+		*type_p = raw.type;
+	}
+
+	git_buf_free(&object_path);
+
+	return error;
+}
+
+static int loose_backend__read_prefix(
+	git_oid *out_oid,
+	void **buffer_p,
+	size_t *len_p,
+	git_otype *type_p,
+	git_odb_backend *backend,
+	const git_oid *short_oid,
+	size_t len)
+{
+	int error = 0;
+
+	assert(len >= GIT_OID_MINPREFIXLEN && len <= GIT_OID_HEXSZ);
+
+	if (len == GIT_OID_HEXSZ) {
+		/* We can fall back to regular read method */
+		error = loose_backend__read(buffer_p, len_p, type_p, backend, short_oid);
+		if (!error)
+			git_oid_cpy(out_oid, short_oid);
+	} else {
+		git_buf object_path = GIT_BUF_INIT;
+		git_rawobj raw;
+
+		assert(backend && short_oid);
+
+		if ((error = locate_object_short_oid(&object_path, out_oid,
+				(loose_backend *)backend, short_oid, len)) == 0 &&
+			(error = read_loose(&raw, &object_path)) == 0)
+		{
+			*buffer_p = raw.data;
+			*len_p = raw.len;
+			*type_p = raw.type;
+		}
+
+		git_buf_free(&object_path);
+	}
+
+	return error;
+}
+
+static int loose_backend__exists(git_odb_backend *backend, const git_oid *oid)
+{
+	git_buf object_path = GIT_BUF_INIT;
+	int error;
+
+	assert(backend && oid);
+
+	error = locate_object(&object_path, (loose_backend *)backend, oid);
+
+	git_buf_free(&object_path);
+
+	return !error;
+}
+
+static int loose_backend__exists_prefix(
+	git_oid *out, git_odb_backend *backend, const git_oid *short_id, size_t len)
+{
+	git_buf object_path = GIT_BUF_INIT;
+	int error;
+
+	assert(backend && out && short_id && len >= GIT_OID_MINPREFIXLEN);
+
+	error = locate_object_short_oid(
+		&object_path, out, (loose_backend *)backend, short_id, len);
+
+	git_buf_free(&object_path);
+
+	return error;
+}
+
+struct foreach_state {
+	size_t dir_len;
+	git_odb_foreach_cb cb;
+	void *data;
+};
+
+GIT_INLINE(int) filename_to_oid(git_oid *oid, const char *ptr)
+{
+	int v, i = 0;
+	if (strlen(ptr) != GIT_OID_HEXSZ+1)
+		return -1;
+
+	if (ptr[2] != '/') {
+		return -1;
+	}
+
+	v = (git__fromhex(ptr[i]) << 4) | git__fromhex(ptr[i+1]);
+	if (v < 0)
+		return -1;
+
+	oid->id[0] = (unsigned char) v;
+
+	ptr += 3;
+	for (i = 0; i < 38; i += 2) {
+		v = (git__fromhex(ptr[i]) << 4) | git__fromhex(ptr[i + 1]);
+		if (v < 0)
+			return -1;
+
+		oid->id[1 + i/2] = (unsigned char) v;
+	}
+
+	return 0;
+}
+
+static int foreach_object_dir_cb(void *_state, git_buf *path)
+{
+	git_oid oid;
+	struct foreach_state *state = (struct foreach_state *) _state;
+
+	if (filename_to_oid(&oid, path->ptr + state->dir_len) < 0)
+		return 0;
+
+	return giterr_set_after_callback_function(
+		state->cb(&oid, state->data), "git_odb_foreach");
+}
+
+static int foreach_cb(void *_state, git_buf *path)
+{
+	struct foreach_state *state = (struct foreach_state *) _state;
+
+	/* non-dir is some stray file, ignore it */
+	if (!git_path_isdir(git_buf_cstr(path)))
+		return 0;
+
+	return git_path_direach(path, 0, foreach_object_dir_cb, state);
+}
+
+static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb cb, void *data)
+{
+	char *objects_dir;
+	int error;
+	git_buf buf = GIT_BUF_INIT;
+	struct foreach_state state;
+	loose_backend *backend = (loose_backend *) _backend;
+
+	assert(backend && cb);
+
+	objects_dir = backend->objects_dir;
+
+	git_buf_sets(&buf, objects_dir);
+	git_path_to_dir(&buf);
+	if (git_buf_oom(&buf))
+		return -1;
+
+	memset(&state, 0, sizeof(state));
+	state.cb = cb;
+	state.data = data;
+	state.dir_len = git_buf_len(&buf);
+
+	error = git_path_direach(&buf, 0, foreach_cb, &state);
+
+	git_buf_free(&buf);
+
+	return error;
+}
+
+static int loose_backend__stream_fwrite(git_odb_stream *_stream, const git_oid *oid)
+{
+	loose_writestream *stream = (loose_writestream *)_stream;
+	loose_backend *backend = (loose_backend *)_stream->backend;
+	git_buf final_path = GIT_BUF_INIT;
+	int error = 0;
+
+	if (object_file_name(&final_path, backend, oid) < 0 ||
+		object_mkdir(&final_path, backend) < 0)
+		error = -1;
+	else
+		error = git_filebuf_commit_at(
+			&stream->fbuf, final_path.ptr);
+
+	git_buf_free(&final_path);
+
+	return error;
+}
+
+static int loose_backend__stream_write(git_odb_stream *_stream, const char *data, size_t len)
+{
+	loose_writestream *stream = (loose_writestream *)_stream;
+	return git_filebuf_write(&stream->fbuf, data, len);
+}
+
+static void loose_backend__stream_free(git_odb_stream *_stream)
+{
+	loose_writestream *stream = (loose_writestream *)_stream;
+
+	git_filebuf_cleanup(&stream->fbuf);
+	git__free(stream);
+}
+
+static int loose_backend__stream(git_odb_stream **stream_out, git_odb_backend *_backend, git_off_t length, git_otype type)
+{
+	loose_backend *backend;
+	loose_writestream *stream = NULL;
+	char hdr[64];
+	git_buf tmp_path = GIT_BUF_INIT;
+	int hdrlen;
+
+	assert(_backend && length >= 0);
+
+	backend = (loose_backend *)_backend;
+	*stream_out = NULL;
+
+	hdrlen = git_odb__format_object_header(hdr, sizeof(hdr), length, type);
+
+	stream = git__calloc(1, sizeof(loose_writestream));
+	GITERR_CHECK_ALLOC(stream);
+
+	stream->stream.backend = _backend;
+	stream->stream.read = NULL; /* read only */
+	stream->stream.write = &loose_backend__stream_write;
+	stream->stream.finalize_write = &loose_backend__stream_fwrite;
+	stream->stream.free = &loose_backend__stream_free;
+	stream->stream.mode = GIT_STREAM_WRONLY;
+
+	if (git_buf_joinpath(&tmp_path, backend->objects_dir, "tmp_object") < 0 ||
+		git_filebuf_open(&stream->fbuf, tmp_path.ptr,
+			GIT_FILEBUF_TEMPORARY |
+			(backend->object_zlib_level << GIT_FILEBUF_DEFLATE_SHIFT),
+			backend->object_file_mode) < 0 ||
+		stream->stream.write((git_odb_stream *)stream, hdr, hdrlen) < 0)
+	{
+		git_filebuf_cleanup(&stream->fbuf);
+		git__free(stream);
+		stream = NULL;
+	}
+	git_buf_free(&tmp_path);
+	*stream_out = (git_odb_stream *)stream;
+
+	return !stream ? -1 : 0;
+}
+
+static int loose_backend__write(git_odb_backend *_backend, const git_oid *oid, const void *data, size_t len, git_otype type)
+{
+	int error = 0, header_len;
+	git_buf final_path = GIT_BUF_INIT;
+	char header[64];
+	git_filebuf fbuf = GIT_FILEBUF_INIT;
+	loose_backend *backend;
+
+	backend = (loose_backend *)_backend;
+
+	/* prepare the header for the file */
+	header_len = git_odb__format_object_header(header, sizeof(header), len, type);
+
+	if (git_buf_joinpath(&final_path, backend->objects_dir, "tmp_object") < 0 ||
+		git_filebuf_open(&fbuf, final_path.ptr,
+			GIT_FILEBUF_TEMPORARY |
+			(backend->object_zlib_level << GIT_FILEBUF_DEFLATE_SHIFT),
+			backend->object_file_mode) < 0)
+	{
+		error = -1;
+		goto cleanup;
+	}
+
+	git_filebuf_write(&fbuf, header, header_len);
+	git_filebuf_write(&fbuf, data, len);
+
+	if (object_file_name(&final_path, backend, oid) < 0 ||
+		object_mkdir(&final_path, backend) < 0 ||
+		git_filebuf_commit_at(&fbuf, final_path.ptr) < 0)
+		error = -1;
+
+cleanup:
+	if (error < 0)
+		git_filebuf_cleanup(&fbuf);
+	git_buf_free(&final_path);
+	return error;
+}
+
+static void loose_backend__free(git_odb_backend *_backend)
+{
+	loose_backend *backend;
+	assert(_backend);
+	backend = (loose_backend *)_backend;
+
+	git__free(backend);
+}
+
+int git_odb_backend_loose(
+	git_odb_backend **backend_out,
+	const char *objects_dir,
+	int compression_level,
+	int do_fsync,
+	unsigned int dir_mode,
+	unsigned int file_mode)
+{
+	loose_backend *backend;
+	size_t objects_dirlen, alloclen;
+
+	assert(backend_out && objects_dir);
+
+	objects_dirlen = strlen(objects_dir);
+
+	GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(loose_backend), objects_dirlen);
+	GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 2);
+	backend = git__calloc(1, alloclen);
+	GITERR_CHECK_ALLOC(backend);
+
+	backend->parent.version = GIT_ODB_BACKEND_VERSION;
+	backend->objects_dirlen = objects_dirlen;
+	memcpy(backend->objects_dir, objects_dir, objects_dirlen);
+	if (backend->objects_dir[backend->objects_dirlen - 1] != '/')
+		backend->objects_dir[backend->objects_dirlen++] = '/';
+
+	if (compression_level < 0)
+		compression_level = Z_BEST_SPEED;
+
+	if (dir_mode == 0)
+		dir_mode = GIT_OBJECT_DIR_MODE;
+
+	if (file_mode == 0)
+		file_mode = GIT_OBJECT_FILE_MODE;
+
+	backend->object_zlib_level = compression_level;
+	backend->fsync_object_files = do_fsync;
+	backend->object_dir_mode = dir_mode;
+	backend->object_file_mode = file_mode;
+
+	backend->parent.read = &loose_backend__read;
+	backend->parent.write = &loose_backend__write;
+	backend->parent.read_prefix = &loose_backend__read_prefix;
+	backend->parent.read_header = &loose_backend__read_header;
+	backend->parent.writestream = &loose_backend__stream;
+	backend->parent.exists = &loose_backend__exists;
+	backend->parent.exists_prefix = &loose_backend__exists_prefix;
+	backend->parent.foreach = &loose_backend__foreach;
+	backend->parent.free = &loose_backend__free;
+
+	*backend_out = (git_odb_backend *)backend;
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/odb_mempack.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/odb_mempack.c
new file mode 100755
index 0000000..3435527
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/odb_mempack.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "git2/object.h"
+#include "git2/sys/odb_backend.h"
+#include "fileops.h"
+#include "hash.h"
+#include "odb.h"
+#include "array.h"
+#include "oidmap.h"
+
+#include "git2/odb_backend.h"
+#include "git2/types.h"
+#include "git2/pack.h"
+
+GIT__USE_OIDMAP
+
+struct memobject {
+	git_oid oid;
+	size_t len;
+	git_otype type;
+	char data[];
+};
+
+struct memory_packer_db {
+	git_odb_backend parent;
+	git_oidmap *objects;
+	git_array_t(struct memobject *) commits;
+};
+
+static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void *data, size_t len, git_otype type)
+{
+	struct memory_packer_db *db = (struct memory_packer_db *)_backend;
+	struct memobject *obj = NULL; 
+	khiter_t pos;
+	size_t alloc_len;
+	int rval;
+
+	pos = kh_put(oid, db->objects, oid, &rval);
+	if (rval < 0)
+		return -1;
+
+	if (rval == 0)
+		return 0;
+
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, sizeof(struct memobject), len);
+	obj = git__malloc(alloc_len);
+	GITERR_CHECK_ALLOC(obj);
+
+	memcpy(obj->data, data, len);
+	git_oid_cpy(&obj->oid, oid);
+	obj->len = len;
+	obj->type = type;
+
+	kh_key(db->objects, pos) = &obj->oid;
+	kh_val(db->objects, pos) = obj;
+
+	if (type == GIT_OBJ_COMMIT) {
+		struct memobject **store = git_array_alloc(db->commits);
+		GITERR_CHECK_ALLOC(store);
+		*store = obj;
+	}
+
+	return 0;
+}
+
+static int impl__exists(git_odb_backend *backend, const git_oid *oid)
+{
+	struct memory_packer_db *db = (struct memory_packer_db *)backend;
+	khiter_t pos;
+
+	pos = kh_get(oid, db->objects, oid);
+	if (pos != kh_end(db->objects))
+		return 1;
+
+	return 0;
+}
+
+static int impl__read(void **buffer_p, size_t *len_p, git_otype *type_p, git_odb_backend *backend, const git_oid *oid)
+{
+	struct memory_packer_db *db = (struct memory_packer_db *)backend;
+	struct memobject *obj = NULL;
+	khiter_t pos;
+
+	pos = kh_get(oid, db->objects, oid);
+	if (pos == kh_end(db->objects))
+		return GIT_ENOTFOUND;
+
+	obj = kh_val(db->objects, pos);
+
+	*len_p = obj->len;
+	*type_p = obj->type;
+	*buffer_p = git__malloc(obj->len);
+	GITERR_CHECK_ALLOC(*buffer_p);
+
+	memcpy(*buffer_p, obj->data, obj->len);
+	return 0;
+}
+
+static int impl__read_header(size_t *len_p, git_otype *type_p, git_odb_backend *backend, const git_oid *oid)
+{
+	struct memory_packer_db *db = (struct memory_packer_db *)backend;
+	struct memobject *obj = NULL;
+	khiter_t pos;
+
+	pos = kh_get(oid, db->objects, oid);
+	if (pos == kh_end(db->objects))
+		return GIT_ENOTFOUND;
+
+	obj = kh_val(db->objects, pos);
+
+	*len_p = obj->len;
+	*type_p = obj->type;
+	return 0;
+}
+
+int git_mempack_dump(git_buf *pack, git_repository *repo, git_odb_backend *_backend)
+{
+	struct memory_packer_db *db = (struct memory_packer_db *)_backend;
+	git_packbuilder *packbuilder;
+	uint32_t i;
+	int err = -1;
+
+	if (git_packbuilder_new(&packbuilder, repo) < 0)
+		return -1;
+
+	for (i = 0; i < db->commits.size; ++i) {
+		struct memobject *commit = db->commits.ptr[i];
+
+		err = git_packbuilder_insert_commit(packbuilder, &commit->oid);
+		if (err < 0)
+			goto cleanup;
+	}
+
+	err = git_packbuilder_write_buf(pack, packbuilder);
+
+cleanup:
+	git_packbuilder_free(packbuilder);
+	return err;
+}
+
+void git_mempack_reset(git_odb_backend *_backend)
+{
+	struct memory_packer_db *db = (struct memory_packer_db *)_backend;
+	struct memobject *object = NULL;
+
+	kh_foreach_value(db->objects, object, {
+		git__free(object);
+	});
+
+	git_array_clear(db->commits);
+}
+
+static void impl__free(git_odb_backend *_backend)
+{
+	git_mempack_reset(_backend);
+	git__free(_backend);
+}
+
+int git_mempack_new(git_odb_backend **out)
+{
+	struct memory_packer_db *db;
+
+	assert(out);
+
+	db = git__calloc(1, sizeof(struct memory_packer_db));
+	GITERR_CHECK_ALLOC(db);
+
+	db->objects = git_oidmap_alloc();
+
+	db->parent.read = &impl__read;
+	db->parent.write = &impl__write;
+	db->parent.read_header = &impl__read_header;
+	db->parent.exists = &impl__exists;
+	db->parent.free = &impl__free;
+
+	*out = (git_odb_backend *)db;
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/odb_pack.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/odb_pack.c
new file mode 100755
index 0000000..735158d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/odb_pack.c
@@ -0,0 +1,691 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include <zlib.h>
+#include "git2/repository.h"
+#include "git2/indexer.h"
+#include "git2/sys/odb_backend.h"
+#include "fileops.h"
+#include "hash.h"
+#include "odb.h"
+#include "delta-apply.h"
+#include "sha1_lookup.h"
+#include "mwindow.h"
+#include "pack.h"
+
+#include "git2/odb_backend.h"
+
+struct pack_backend {
+	git_odb_backend parent;
+	git_vector packs;
+	struct git_pack_file *last_found;
+	char *pack_folder;
+};
+
+struct pack_writepack {
+	struct git_odb_writepack parent;
+	git_indexer *indexer;
+};
+
+/**
+ * The wonderful tale of a Packed Object lookup query
+ * ===================================================
+ *	A riveting and epic story of epicness and ASCII
+ *			art, presented by yours truly,
+ *				Sir Vicent of Marti
+ *
+ *
+ *	Chapter 1: Once upon a time...
+ *	Initialization of the Pack Backend
+ *	--------------------------------------------------
+ *
+ *	# git_odb_backend_pack
+ *	| Creates the pack backend structure, initializes the
+ *	| callback pointers to our default read() and exist() methods,
+ *	| and tries to preload all the known packfiles in the ODB.
+ * |
+ *	|-# packfile_load_all
+ *	 | Tries to find the `pack` folder, if it exists. ODBs without
+ *	 | a pack folder are ignored altogether. If there's a `pack` folder
+ *	 | we run a `dirent` callback through every file in the pack folder
+ *	 | to find our packfiles. The packfiles are then sorted according
+ *	 | to a sorting callback.
+ * 	 |
+ *	 |-# packfile_load__cb
+ *	 | | This callback is called from `dirent` with every single file
+ *	 | | inside the pack folder. We find the packs by actually locating
+ *	 | | their index (ends in ".idx"). From that index, we verify that
+ *	 | | the corresponding packfile exists and is valid, and if so, we
+ *	| | add it to the pack list.
+ *	 | |
+ *	 | |-# packfile_check
+ *	 |		Make sure that there's a packfile to back this index, and store
+ *	 |		some very basic information regarding the packfile itself,
+ *	 |		such as the full path, the size, and the modification time.
+ *	 |		We don't actually open the packfile to check for internal consistency.
+ *	|
+ *	|-# packfile_sort__cb
+ *		Sort all the preloaded packs according to some specific criteria:
+ *		we prioritize the "newer" packs because it's more likely they
+ *		contain the objects we are looking for, and we prioritize local
+ *		packs over remote ones.
+ *
+ *
+ *
+ *	Chapter 2: To be, or not to be...
+ *	A standard packed `exist` query for an OID
+ *	--------------------------------------------------
+ *
+ * # pack_backend__exists
+ * | Check if the given SHA1 oid exists in any of the packs
+ * | that have been loaded for our ODB.
+ * |
+ * |-# pack_entry_find
+ *	| Iterate through all the packs that have been preloaded
+ *	| (starting by the pack where the latest object was found)
+ *	| to try to find the OID in one of them.
+ *	|
+ *	|-# pack_entry_find1
+ *		| Check the index of an individual pack to see if the SHA1
+ *		| OID can be found. If we can find the offset to that SHA1
+ *		| inside of the index, that means the object is contained
+ *		| inside of the packfile and we can stop searching.
+ *		| Before returning, we verify that the packfile behing the
+ *		| index we are searching still exists on disk.
+ *		|
+ *		|-# pack_entry_find_offset
+ *		| | Mmap the actual index file to disk if it hasn't been opened
+ *		| | yet, and run a binary search through it to find the OID.
+ *		| | See <http://book.git-scm.com/7_the_packfile.html> for specifics
+ *		| | on the Packfile Index format and how do we find entries in it.
+ *		| |
+ *		| |-# pack_index_open
+ *		|	| Guess the name of the index based on the full path to the
+ *		|	| packfile, open it and verify its contents. Only if the index
+ *		|	| has not been opened already.
+ *		|	|
+ *		|	|-# pack_index_check
+ *		|		Mmap the index file and do a quick run through the header
+ *		|		to guess the index version (right now we support v1 and v2),
+ *		|		and to verify that the size of the index makes sense.
+ *		|
+ *		|-# packfile_open
+ *			See `packfile_open` in Chapter 3
+ *
+ *
+ *
+ *	Chapter 3: The neverending story...
+ *	A standard packed `lookup` query for an OID
+ *	--------------------------------------------------
+ *	TODO
+ *
+ */
+
+
+/***********************************************************
+ *
+ * FORWARD DECLARATIONS
+ *
+ ***********************************************************/
+
+static int packfile_sort__cb(const void *a_, const void *b_);
+
+static int packfile_load__cb(void *_data, git_buf *path);
+
+static int pack_entry_find(struct git_pack_entry *e,
+	struct pack_backend *backend, const git_oid *oid);
+
+/* Can find the offset of an object given
+ * a prefix of an identifier.
+ * Sets GIT_EAMBIGUOUS if short oid is ambiguous.
+ * This method assumes that len is between
+ * GIT_OID_MINPREFIXLEN and GIT_OID_HEXSZ.
+ */
+static int pack_entry_find_prefix(
+	struct git_pack_entry *e,
+	struct pack_backend *backend,
+	const git_oid *short_oid,
+	size_t len);
+
+
+
+/***********************************************************
+ *
+ * PACK WINDOW MANAGEMENT
+ *
+ ***********************************************************/
+
+static int packfile_sort__cb(const void *a_, const void *b_)
+{
+	const struct git_pack_file *a = a_;
+	const struct git_pack_file *b = b_;
+	int st;
+
+	/*
+	 * Local packs tend to contain objects specific to our
+	 * variant of the project than remote ones. In addition,
+	 * remote ones could be on a network mounted filesystem.
+	 * Favor local ones for these reasons.
+	 */
+	st = a->pack_local - b->pack_local;
+	if (st)
+		return -st;
+
+	/*
+	 * Younger packs tend to contain more recent objects,
+	 * and more recent objects tend to get accessed more
+	 * often.
+	 */
+	if (a->mtime < b->mtime)
+		return 1;
+	else if (a->mtime == b->mtime)
+		return 0;
+
+	return -1;
+}
+
+
+static int packfile_load__cb(void *data, git_buf *path)
+{
+	struct pack_backend *backend = data;
+	struct git_pack_file *pack;
+	const char *path_str = git_buf_cstr(path);
+	size_t i, cmp_len = git_buf_len(path);
+	int error;
+
+	if (cmp_len <= strlen(".idx") || git__suffixcmp(path_str, ".idx") != 0)
+		return 0; /* not an index */
+
+	cmp_len -= strlen(".idx");
+
+	for (i = 0; i < backend->packs.length; ++i) {
+		struct git_pack_file *p = git_vector_get(&backend->packs, i);
+
+		if (memcmp(p->pack_name, path_str, cmp_len) == 0)
+			return 0;
+	}
+
+	error = git_mwindow_get_pack(&pack, path->ptr);
+
+	/* ignore missing .pack file as git does */
+	if (error == GIT_ENOTFOUND) {
+		giterr_clear();
+		return 0;
+	}
+
+	if (!error)
+		error = git_vector_insert(&backend->packs, pack);
+
+	return error;
+
+}
+
+static int pack_entry_find_inner(
+	struct git_pack_entry *e,
+	struct pack_backend *backend,
+	const git_oid *oid,
+	struct git_pack_file *last_found)
+{
+	size_t i;
+
+	if (last_found &&
+		git_pack_entry_find(e, last_found, oid, GIT_OID_HEXSZ) == 0)
+		return 0;
+
+	for (i = 0; i < backend->packs.length; ++i) {
+		struct git_pack_file *p;
+
+		p = git_vector_get(&backend->packs, i);
+		if (p == last_found)
+			continue;
+
+		if (git_pack_entry_find(e, p, oid, GIT_OID_HEXSZ) == 0) {
+			backend->last_found = p;
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
+static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backend, const git_oid *oid)
+{
+	struct git_pack_file *last_found = backend->last_found;
+
+	if (backend->last_found &&
+		git_pack_entry_find(e, backend->last_found, oid, GIT_OID_HEXSZ) == 0)
+		return 0;
+
+	if (!pack_entry_find_inner(e, backend, oid, last_found))
+		return 0;
+
+	return git_odb__error_notfound("failed to find pack entry", oid);
+}
+
+static int pack_entry_find_prefix(
+	struct git_pack_entry *e,
+	struct pack_backend *backend,
+	const git_oid *short_oid,
+	size_t len)
+{
+	int error;
+	size_t i;
+	git_oid found_full_oid = {{0}};
+	bool found = false;
+	struct git_pack_file *last_found = backend->last_found;
+
+	if (last_found) {
+		error = git_pack_entry_find(e, last_found, short_oid, len);
+		if (error == GIT_EAMBIGUOUS)
+			return error;
+		if (!error) {
+			git_oid_cpy(&found_full_oid, &e->sha1);
+			found = true;
+		}
+	}
+
+	for (i = 0; i < backend->packs.length; ++i) {
+		struct git_pack_file *p;
+
+		p = git_vector_get(&backend->packs, i);
+		if (p == last_found)
+			continue;
+
+		error = git_pack_entry_find(e, p, short_oid, len);
+		if (error == GIT_EAMBIGUOUS)
+			return error;
+		if (!error) {
+			if (found && git_oid_cmp(&e->sha1, &found_full_oid))
+				return git_odb__error_ambiguous("found multiple pack entries");
+			git_oid_cpy(&found_full_oid, &e->sha1);
+			found = true;
+			backend->last_found = p;
+		}
+	}
+
+	if (!found)
+		return git_odb__error_notfound("no matching pack entry for prefix", short_oid);
+	else
+		return 0;
+}
+
+
+/***********************************************************
+ *
+ * PACKED BACKEND PUBLIC API
+ *
+ * Implement the git_odb_backend API calls
+ *
+ ***********************************************************/
+static int pack_backend__refresh(git_odb_backend *backend_)
+{
+	int error;
+	struct stat st;
+	git_buf path = GIT_BUF_INIT;
+	struct pack_backend *backend = (struct pack_backend *)backend_;
+
+	if (backend->pack_folder == NULL)
+		return 0;
+
+	if (p_stat(backend->pack_folder, &st) < 0 || !S_ISDIR(st.st_mode))
+		return git_odb__error_notfound("failed to refresh packfiles", NULL);
+
+	git_buf_sets(&path, backend->pack_folder);
+
+	/* reload all packs */
+	error = git_path_direach(&path, 0, packfile_load__cb, backend);
+
+	git_buf_free(&path);
+	git_vector_sort(&backend->packs);
+
+	return error;
+}
+
+static int pack_backend__read_header_internal(
+	size_t *len_p, git_otype *type_p,
+	struct git_odb_backend *backend, const git_oid *oid)
+{
+	struct git_pack_entry e;
+	int error;
+
+	assert(len_p && type_p && backend && oid);
+
+	if ((error = pack_entry_find(&e, (struct pack_backend *)backend, oid)) < 0)
+		return error;
+
+	return git_packfile_resolve_header(len_p, type_p, e.p, e.offset);
+}
+
+static int pack_backend__read_header(
+	size_t *len_p, git_otype *type_p,
+	struct git_odb_backend *backend, const git_oid *oid)
+{
+	int error;
+
+	error = pack_backend__read_header_internal(len_p, type_p, backend, oid);
+
+	if (error != GIT_ENOTFOUND)
+		return error;
+
+	if ((error = pack_backend__refresh(backend)) < 0)
+		return error;
+
+	return pack_backend__read_header_internal(len_p, type_p, backend, oid);
+}
+
+static int pack_backend__read_internal(
+	void **buffer_p, size_t *len_p, git_otype *type_p,
+	git_odb_backend *backend, const git_oid *oid)
+{
+	struct git_pack_entry e;
+	git_rawobj raw = {NULL};
+	int error;
+
+	if ((error = pack_entry_find(&e, (struct pack_backend *)backend, oid)) < 0 ||
+		(error = git_packfile_unpack(&raw, e.p, &e.offset)) < 0)
+		return error;
+
+	*buffer_p = raw.data;
+	*len_p = raw.len;
+	*type_p = raw.type;
+
+	return 0;
+}
+
+static int pack_backend__read(
+	void **buffer_p, size_t *len_p, git_otype *type_p,
+	git_odb_backend *backend, const git_oid *oid)
+{
+	int error;
+
+	error = pack_backend__read_internal(buffer_p, len_p, type_p, backend, oid);
+
+	if (error != GIT_ENOTFOUND)
+		return error;
+
+	if ((error = pack_backend__refresh(backend)) < 0)
+		return error;
+
+	return pack_backend__read_internal(buffer_p, len_p, type_p, backend, oid);
+}
+
+static int pack_backend__read_prefix_internal(
+	git_oid *out_oid,
+	void **buffer_p,
+	size_t *len_p,
+	git_otype *type_p,
+	git_odb_backend *backend,
+	const git_oid *short_oid,
+	size_t len)
+{
+	int error = 0;
+
+	if (len < GIT_OID_MINPREFIXLEN)
+		error = git_odb__error_ambiguous("prefix length too short");
+
+	else if (len >= GIT_OID_HEXSZ) {
+		/* We can fall back to regular read method */
+		error = pack_backend__read(buffer_p, len_p, type_p, backend, short_oid);
+		if (!error)
+			git_oid_cpy(out_oid, short_oid);
+	} else {
+		struct git_pack_entry e;
+		git_rawobj raw;
+
+		if ((error = pack_entry_find_prefix(
+				&e, (struct pack_backend *)backend, short_oid, len)) == 0 &&
+			(error = git_packfile_unpack(&raw, e.p, &e.offset)) == 0)
+		{
+			*buffer_p = raw.data;
+			*len_p = raw.len;
+			*type_p = raw.type;
+			git_oid_cpy(out_oid, &e.sha1);
+		}
+	}
+
+	return error;
+}
+
+static int pack_backend__read_prefix(
+	git_oid *out_oid,
+	void **buffer_p,
+	size_t *len_p,
+	git_otype *type_p,
+	git_odb_backend *backend,
+	const git_oid *short_oid,
+	size_t len)
+{
+	int error;
+
+	error = pack_backend__read_prefix_internal(
+		out_oid, buffer_p, len_p, type_p, backend, short_oid, len);
+
+	if (error != GIT_ENOTFOUND)
+		return error;
+
+	if ((error = pack_backend__refresh(backend)) < 0)
+		return error;
+
+	return pack_backend__read_prefix_internal(
+		out_oid, buffer_p, len_p, type_p, backend, short_oid, len);
+}
+
+static int pack_backend__exists(git_odb_backend *backend, const git_oid *oid)
+{
+	struct git_pack_entry e;
+	int error;
+
+	error = pack_entry_find(&e, (struct pack_backend *)backend, oid);
+
+	if (error != GIT_ENOTFOUND)
+		return error == 0;
+
+	if ((error = pack_backend__refresh(backend)) < 0) {
+		giterr_clear();
+		return (int)false;
+	}
+
+	return pack_entry_find(&e, (struct pack_backend *)backend, oid) == 0;
+}
+
+static int pack_backend__exists_prefix(
+	git_oid *out, git_odb_backend *backend, const git_oid *short_id, size_t len)
+{
+	int error;
+	struct pack_backend *pb = (struct pack_backend *)backend;
+	struct git_pack_entry e = {0};
+
+	error = pack_entry_find_prefix(&e, pb, short_id, len);
+
+	if (error == GIT_ENOTFOUND && !(error = pack_backend__refresh(backend)))
+		error = pack_entry_find_prefix(&e, pb, short_id, len);
+
+	git_oid_cpy(out, &e.sha1);
+
+	return error;
+}
+
+static int pack_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb cb, void *data)
+{
+	int error;
+	struct git_pack_file *p;
+	struct pack_backend *backend;
+	unsigned int i;
+
+	assert(_backend && cb);
+	backend = (struct pack_backend *)_backend;
+
+	/* Make sure we know about the packfiles */
+	if ((error = pack_backend__refresh(_backend)) < 0)
+		return error;
+
+	git_vector_foreach(&backend->packs, i, p) {
+		if ((error = git_pack_foreach_entry(p, cb, data)) < 0)
+			return error;
+	}
+
+	return 0;
+}
+
+static int pack_backend__writepack_append(struct git_odb_writepack *_writepack, const void *data, size_t size, git_transfer_progress *stats)
+{
+	struct pack_writepack *writepack = (struct pack_writepack *)_writepack;
+
+	assert(writepack);
+
+	return git_indexer_append(writepack->indexer, data, size, stats);
+}
+
+static int pack_backend__writepack_commit(struct git_odb_writepack *_writepack, git_transfer_progress *stats)
+{
+	struct pack_writepack *writepack = (struct pack_writepack *)_writepack;
+
+	assert(writepack);
+
+	return git_indexer_commit(writepack->indexer, stats);
+}
+
+static void pack_backend__writepack_free(struct git_odb_writepack *_writepack)
+{
+	struct pack_writepack *writepack = (struct pack_writepack *)_writepack;
+
+	assert(writepack);
+
+	git_indexer_free(writepack->indexer);
+	git__free(writepack);
+}
+
+static int pack_backend__writepack(struct git_odb_writepack **out,
+	git_odb_backend *_backend,
+        git_odb *odb,
+	git_transfer_progress_cb progress_cb,
+	void *progress_payload)
+{
+	struct pack_backend *backend;
+	struct pack_writepack *writepack;
+
+	assert(out && _backend);
+
+	*out = NULL;
+
+	backend = (struct pack_backend *)_backend;
+
+	writepack = git__calloc(1, sizeof(struct pack_writepack));
+	GITERR_CHECK_ALLOC(writepack);
+
+	if (git_indexer_new(&writepack->indexer,
+		backend->pack_folder, 0, odb, progress_cb, progress_payload) < 0) {
+		git__free(writepack);
+		return -1;
+	}
+
+	writepack->parent.backend = _backend;
+	writepack->parent.append = pack_backend__writepack_append;
+	writepack->parent.commit = pack_backend__writepack_commit;
+	writepack->parent.free = pack_backend__writepack_free;
+
+	*out = (git_odb_writepack *)writepack;
+
+	return 0;
+}
+
+static void pack_backend__free(git_odb_backend *_backend)
+{
+	struct pack_backend *backend;
+	size_t i;
+
+	assert(_backend);
+
+	backend = (struct pack_backend *)_backend;
+
+	for (i = 0; i < backend->packs.length; ++i) {
+		struct git_pack_file *p = git_vector_get(&backend->packs, i);
+		git_mwindow_put_pack(p);
+	}
+
+	git_vector_free(&backend->packs);
+	git__free(backend->pack_folder);
+	git__free(backend);
+}
+
+static int pack_backend__alloc(struct pack_backend **out, size_t initial_size)
+{
+	struct pack_backend *backend = git__calloc(1, sizeof(struct pack_backend));
+	GITERR_CHECK_ALLOC(backend);
+
+	if (git_vector_init(&backend->packs, initial_size, packfile_sort__cb) < 0) {
+		git__free(backend);
+		return -1;
+	}
+
+	backend->parent.version = GIT_ODB_BACKEND_VERSION;
+
+	backend->parent.read = &pack_backend__read;
+	backend->parent.read_prefix = &pack_backend__read_prefix;
+	backend->parent.read_header = &pack_backend__read_header;
+	backend->parent.exists = &pack_backend__exists;
+	backend->parent.exists_prefix = &pack_backend__exists_prefix;
+	backend->parent.refresh = &pack_backend__refresh;
+	backend->parent.foreach = &pack_backend__foreach;
+	backend->parent.writepack = &pack_backend__writepack;
+	backend->parent.free = &pack_backend__free;
+
+	*out = backend;
+	return 0;
+}
+
+int git_odb_backend_one_pack(git_odb_backend **backend_out, const char *idx)
+{
+	struct pack_backend *backend = NULL;
+	struct git_pack_file *packfile = NULL;
+
+	if (pack_backend__alloc(&backend, 1) < 0)
+		return -1;
+
+	if (git_mwindow_get_pack(&packfile, idx) < 0 ||
+		git_vector_insert(&backend->packs, packfile) < 0)
+	{
+		pack_backend__free((git_odb_backend *)backend);
+		return -1;
+	}
+
+	*backend_out = (git_odb_backend *)backend;
+	return 0;
+}
+
+int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir)
+{
+	int error = 0;
+	struct pack_backend *backend = NULL;
+	git_buf path = GIT_BUF_INIT;
+
+	if (git_mwindow_files_init() < 0)
+		return -1;
+
+	if (pack_backend__alloc(&backend, 8) < 0)
+		return -1;
+
+	if (!(error = git_buf_joinpath(&path, objects_dir, "pack")) &&
+		git_path_isdir(git_buf_cstr(&path)))
+	{
+		backend->pack_folder = git_buf_detach(&path);
+
+		error = pack_backend__refresh((git_odb_backend *)backend);
+	}
+
+	if (error < 0) {
+		pack_backend__free((git_odb_backend *)backend);
+		backend = NULL;
+	}
+
+	*backend_out = (git_odb_backend *)backend;
+
+	git_buf_free(&path);
+
+	return error;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/offmap.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/offmap.h
new file mode 100755
index 0000000..0d0e512
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/offmap.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 the libgit2 contributors
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_offmap_h__
+#define INCLUDE_offmap_h__
+
+#include "common.h"
+#include "git2/types.h"
+
+#define kmalloc git__malloc
+#define kcalloc git__calloc
+#define krealloc git__realloc
+#define kreallocarray git__reallocarray
+#define kfree git__free
+#include "khash.h"
+
+__KHASH_TYPE(off, git_off_t, void *)
+typedef khash_t(off) git_offmap;
+
+#define GIT__USE_OFFMAP \
+	__KHASH_IMPL(off, static kh_inline, git_off_t, void *, 1, kh_int64_hash_func, kh_int64_hash_equal)
+
+#define git_offmap_alloc()  kh_init(off)
+#define git_offmap_free(h)  kh_destroy(off, h), h = NULL
+#define git_offmap_clear(h) kh_clear(off, h)
+
+#define git_offmap_num_entries(h) kh_size(h)
+
+#define git_offmap_lookup_index(h, k)  kh_get(off, h, k)
+#define git_offmap_valid_index(h, idx) (idx != kh_end(h))
+
+#define git_offmap_exists(h, k) (kh_get(off, h, k) != kh_end(h))
+
+#define git_offmap_value_at(h, idx)        kh_val(h, idx)
+#define git_offmap_set_value_at(h, idx, v) kh_val(h, idx) = v
+#define git_offmap_delete_at(h, idx)       kh_del(off, h, idx)
+
+#define git_offmap_insert(h, key, val, rval) do { \
+	khiter_t __pos = kh_put(off, h, key, &rval); \
+	if (rval >= 0) { \
+		if (rval == 0) kh_key(h, __pos) = key; \
+		kh_val(h, __pos) = val; \
+	} } while (0)
+
+#define git_offmap_insert2(h, key, val, oldv, rval) do { \
+	khiter_t __pos = kh_put(off, h, key, &rval); \
+	if (rval >= 0) { \
+		if (rval == 0) { \
+			oldv = kh_val(h, __pos); \
+			kh_key(h, __pos) = key; \
+		} else { oldv = NULL; } \
+		kh_val(h, __pos) = val; \
+	} } while (0)
+
+#define git_offmap_delete(h, key) do { \
+	khiter_t __pos = git_offmap_lookup_index(h, key); \
+	if (git_offmap_valid_index(h, __pos)) \
+		git_offmap_delete_at(h, __pos); } while (0)
+
+#define git_offmap_foreach		kh_foreach
+#define git_offmap_foreach_value	kh_foreach_value
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/oid.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/oid.c
new file mode 100755
index 0000000..9fe2ebb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/oid.c
@@ -0,0 +1,441 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "git2/oid.h"
+#include "repository.h"
+#include "global.h"
+#include <string.h>
+#include <limits.h>
+
+static char to_hex[] = "0123456789abcdef";
+
+static int oid_error_invalid(const char *msg)
+{
+	giterr_set(GITERR_INVALID, "Unable to parse OID - %s", msg);
+	return -1;
+}
+
+int git_oid_fromstrn(git_oid *out, const char *str, size_t length)
+{
+	size_t p;
+	int v;
+
+	assert(out && str);
+
+	if (!length)
+		return oid_error_invalid("too short");
+
+	if (length > GIT_OID_HEXSZ)
+		return oid_error_invalid("too long");
+
+	memset(out->id, 0, GIT_OID_RAWSZ);
+
+	for (p = 0; p < length; p++) {
+		v = git__fromhex(str[p]);
+		if (v < 0)
+			return oid_error_invalid("contains invalid characters");
+
+		out->id[p / 2] |= (unsigned char)(v << (p % 2 ? 0 : 4));
+	}
+
+	return 0;
+}
+
+int git_oid_fromstrp(git_oid *out, const char *str)
+{
+	return git_oid_fromstrn(out, str, strlen(str));
+}
+
+int git_oid_fromstr(git_oid *out, const char *str)
+{
+	return git_oid_fromstrn(out, str, GIT_OID_HEXSZ);
+}
+
+GIT_INLINE(char) *fmt_one(char *str, unsigned int val)
+{
+	*str++ = to_hex[val >> 4];
+	*str++ = to_hex[val & 0xf];
+	return str;
+}
+
+void git_oid_nfmt(char *str, size_t n, const git_oid *oid)
+{
+	size_t i, max_i;
+
+	if (!oid) {
+		memset(str, 0, n);
+		return;
+	}
+	if (n > GIT_OID_HEXSZ) {
+		memset(&str[GIT_OID_HEXSZ], 0, n - GIT_OID_HEXSZ);
+		n = GIT_OID_HEXSZ;
+	}
+
+	max_i = n / 2;
+
+	for (i = 0; i < max_i; i++)
+		str = fmt_one(str, oid->id[i]);
+
+	if (n & 1)
+		*str++ = to_hex[oid->id[i] >> 4];
+}
+
+void git_oid_fmt(char *str, const git_oid *oid)
+{
+	git_oid_nfmt(str, GIT_OID_HEXSZ, oid);
+}
+
+void git_oid_pathfmt(char *str, const git_oid *oid)
+{
+	size_t i;
+
+	str = fmt_one(str, oid->id[0]);
+	*str++ = '/';
+	for (i = 1; i < sizeof(oid->id); i++)
+		str = fmt_one(str, oid->id[i]);
+}
+
+char *git_oid_tostr_s(const git_oid *oid)
+{
+	char *str = GIT_GLOBAL->oid_fmt;
+	git_oid_nfmt(str, GIT_OID_HEXSZ + 1, oid);
+	return str;
+}
+
+char *git_oid_allocfmt(const git_oid *oid)
+{
+	char *str = git__malloc(GIT_OID_HEXSZ + 1);
+	if (!str)
+		return NULL;
+	git_oid_nfmt(str, GIT_OID_HEXSZ + 1, oid);
+	return str;
+}
+
+char *git_oid_tostr(char *out, size_t n, const git_oid *oid)
+{
+	if (!out || n == 0)
+		return "";
+
+	if (n > GIT_OID_HEXSZ + 1)
+		n = GIT_OID_HEXSZ + 1;
+
+	git_oid_nfmt(out, n - 1, oid); /* allow room for terminating NUL */
+	out[n - 1] = '\0';
+
+	return out;
+}
+
+int git_oid__parse(
+	git_oid *oid, const char **buffer_out,
+	const char *buffer_end, const char *header)
+{
+	const size_t sha_len = GIT_OID_HEXSZ;
+	const size_t header_len = strlen(header);
+
+	const char *buffer = *buffer_out;
+
+	if (buffer + (header_len + sha_len + 1) > buffer_end)
+		return -1;
+
+	if (memcmp(buffer, header, header_len) != 0)
+		return -1;
+
+	if (buffer[header_len + sha_len] != '\n')
+		return -1;
+
+	if (git_oid_fromstr(oid, buffer + header_len) < 0)
+		return -1;
+
+	*buffer_out = buffer + (header_len + sha_len + 1);
+
+	return 0;
+}
+
+void git_oid__writebuf(git_buf *buf, const char *header, const git_oid *oid)
+{
+	char hex_oid[GIT_OID_HEXSZ];
+
+	git_oid_fmt(hex_oid, oid);
+	git_buf_puts(buf, header);
+	git_buf_put(buf, hex_oid, GIT_OID_HEXSZ);
+	git_buf_putc(buf, '\n');
+}
+
+void git_oid_fromraw(git_oid *out, const unsigned char *raw)
+{
+	memcpy(out->id, raw, sizeof(out->id));
+}
+
+void git_oid_cpy(git_oid *out, const git_oid *src)
+{
+	memcpy(out->id, src->id, sizeof(out->id));
+}
+
+int git_oid_cmp(const git_oid *a, const git_oid *b)
+{
+	return git_oid__cmp(a, b);
+}
+
+int git_oid_equal(const git_oid *a, const git_oid *b)
+{
+	return (git_oid__cmp(a, b) == 0);
+}
+
+int git_oid_ncmp(const git_oid *oid_a, const git_oid *oid_b, size_t len)
+{
+	const unsigned char *a = oid_a->id;
+	const unsigned char *b = oid_b->id;
+
+	if (len > GIT_OID_HEXSZ)
+		len = GIT_OID_HEXSZ;
+
+	while (len > 1) {
+		if (*a != *b)
+			return 1;
+		a++;
+		b++;
+		len -= 2;
+	};
+
+	if (len)
+		if ((*a ^ *b) & 0xf0)
+			return 1;
+
+	return 0;
+}
+
+int git_oid_strcmp(const git_oid *oid_a, const char *str)
+{
+	const unsigned char *a;
+	unsigned char strval;
+	int hexval;
+
+	for (a = oid_a->id; *str && (a - oid_a->id) < GIT_OID_RAWSZ; ++a) {
+		if ((hexval = git__fromhex(*str++)) < 0)
+			return -1;
+		strval = (unsigned char)(hexval << 4);
+		if (*str) {
+			if ((hexval = git__fromhex(*str++)) < 0)
+				return -1;
+			strval |= hexval;
+		}
+		if (*a != strval)
+			return (*a - strval);
+	}
+
+	return 0;
+}
+
+int git_oid_streq(const git_oid *oid_a, const char *str)
+{
+	return git_oid_strcmp(oid_a, str) == 0 ? 0 : -1;
+}
+
+int git_oid_iszero(const git_oid *oid_a)
+{
+	const unsigned char *a = oid_a->id;
+	unsigned int i;
+	for (i = 0; i < GIT_OID_RAWSZ; ++i, ++a)
+		if (*a != 0)
+			return 0;
+	return 1;
+}
+
+typedef short node_index;
+
+typedef union {
+	const char *tail;
+	node_index children[16];
+} trie_node;
+
+struct git_oid_shorten {
+	trie_node *nodes;
+	size_t node_count, size;
+	int min_length, full;
+};
+
+static int resize_trie(git_oid_shorten *self, size_t new_size)
+{
+	self->nodes = git__reallocarray(self->nodes, new_size, sizeof(trie_node));
+	GITERR_CHECK_ALLOC(self->nodes);
+
+	if (new_size > self->size) {
+		memset(&self->nodes[self->size], 0x0, (new_size - self->size) * sizeof(trie_node));
+	}
+
+	self->size = new_size;
+	return 0;
+}
+
+static trie_node *push_leaf(git_oid_shorten *os, node_index idx, int push_at, const char *oid)
+{
+	trie_node *node, *leaf;
+	node_index idx_leaf;
+
+	if (os->node_count >= os->size) {
+		if (resize_trie(os, os->size * 2) < 0)
+			return NULL;
+	}
+
+	idx_leaf = (node_index)os->node_count++;
+
+	if (os->node_count == SHRT_MAX) {
+		os->full = 1;
+        return NULL;
+    }
+
+	node = &os->nodes[idx];
+	node->children[push_at] = -idx_leaf;
+
+	leaf = &os->nodes[idx_leaf];
+	leaf->tail = oid;
+
+	return node;
+}
+
+git_oid_shorten *git_oid_shorten_new(size_t min_length)
+{
+	git_oid_shorten *os;
+
+	assert((size_t)((int)min_length) == min_length);
+
+	os = git__calloc(1, sizeof(git_oid_shorten));
+	if (os == NULL)
+		return NULL;
+
+	if (resize_trie(os, 16) < 0) {
+		git__free(os);
+		return NULL;
+	}
+
+	os->node_count = 1;
+	os->min_length = (int)min_length;
+
+	return os;
+}
+
+void git_oid_shorten_free(git_oid_shorten *os)
+{
+	if (os == NULL)
+		return;
+
+	git__free(os->nodes);
+	git__free(os);
+}
+
+
+/*
+ * What wizardry is this?
+ *
+ * This is just a memory-optimized trie: basically a very fancy
+ * 16-ary tree, which is used to store the prefixes of the OID
+ * strings.
+ *
+ * Read more: http://en.wikipedia.org/wiki/Trie
+ *
+ * Magic that happens in this method:
+ *
+ *	- Each node in the trie is an union, so it can work both as
+ *	a normal node, or as a leaf.
+ *
+ *	- Each normal node points to 16 children (one for each possible
+ *	character in the oid). This is *not* stored in an array of
+ *	pointers, because in a 64-bit arch this would be sucking
+ *	16*sizeof(void*) = 128 bytes of memory per node, which is
+ *	insane. What we do is store Node Indexes, and use these indexes
+ *	to look up each node in the om->index array. These indexes are
+ *	signed shorts, so this limits the amount of unique OIDs that
+ *	fit in the structure to about 20000 (assuming a more or less uniform
+ *	distribution).
+ *
+ *	- All the nodes in om->index array are stored contiguously in
+ *	memory, and each of them is 32 bytes, so we fit 2x nodes per
+ *	cache line. Convenient for speed.
+ *
+ *	- To differentiate the leafs from the normal nodes, we store all
+ *	the indexes towards a leaf as a negative index (indexes to normal
+ *	nodes are positives). When we find that one of the children for
+ *	a node has a negative value, that means it's going to be a leaf.
+ *	This reduces the amount of indexes we have by two, but also reduces
+ *	the size of each node by 1-4 bytes (the amount we would need to
+ *	add a `is_leaf` field): this is good because it allows the nodes
+ *	to fit cleanly in cache lines.
+ *
+ *	- Once we reach an empty children, instead of continuing to insert
+ *	new nodes for each remaining character of the OID, we store a pointer
+ *	to the tail in the leaf; if the leaf is reached again, we turn it
+ *	into a normal node and use the tail to create a new leaf.
+ *
+ *	This is a pretty good balance between performance and memory usage.
+ */
+int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid)
+{
+	int i;
+	bool is_leaf;
+	node_index idx;
+
+	if (os->full) {
+		giterr_set(GITERR_INVALID, "Unable to shorten OID - OID set full");
+		return -1;
+	}
+
+	if (text_oid == NULL)
+		return os->min_length;
+
+	idx = 0;
+	is_leaf = false;
+
+	for (i = 0; i < GIT_OID_HEXSZ; ++i) {
+		int c = git__fromhex(text_oid[i]);
+		trie_node *node;
+
+		if (c == -1) {
+			giterr_set(GITERR_INVALID, "Unable to shorten OID - invalid hex value");
+			return -1;
+		}
+
+		node = &os->nodes[idx];
+
+		if (is_leaf) {
+			const char *tail;
+
+			tail = node->tail;
+			node->tail = NULL;
+
+			node = push_leaf(os, idx, git__fromhex(tail[0]), &tail[1]);
+			if (node == NULL) {
+				if (os->full)
+					giterr_set(GITERR_INVALID, "Unable to shorten OID - OID set full");
+				return -1;
+			}
+		}
+
+		if (node->children[c] == 0) {
+			if (push_leaf(os, idx, c, &text_oid[i + 1]) == NULL) {
+				if (os->full)
+					giterr_set(GITERR_INVALID, "Unable to shorten OID - OID set full");
+				return -1;
+			}
+			break;
+		}
+
+		idx = node->children[c];
+		is_leaf = false;
+
+		if (idx < 0) {
+			node->children[c] = idx = -idx;
+			is_leaf = true;
+		}
+	}
+
+	if (++i > os->min_length)
+		os->min_length = i;
+
+	return os->min_length;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/oid.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/oid.h
new file mode 100755
index 0000000..aa1f0bf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/oid.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_oid_h__
+#define INCLUDE_oid_h__
+
+#include "git2/oid.h"
+
+/**
+ * Format a git_oid into a newly allocated c-string.
+ *
+ * The c-string is owned by the caller and needs to be manually freed.
+ *
+ * @param id the oid structure to format
+ * @return the c-string; NULL if memory is exhausted. Caller must
+ *			deallocate the string with git__free().
+ */
+char *git_oid_allocfmt(const git_oid *id);
+
+GIT_INLINE(int) git_oid__hashcmp(const unsigned char *sha1, const unsigned char *sha2)
+{
+	int i;
+
+	for (i = 0; i < GIT_OID_RAWSZ; i++, sha1++, sha2++) {
+		if (*sha1 != *sha2)
+			return *sha1 - *sha2;
+	}
+
+	return 0;
+}
+
+/*
+ * Compare two oid structures.
+ *
+ * @param a first oid structure.
+ * @param b second oid structure.
+ * @return <0, 0, >0 if a < b, a == b, a > b.
+ */
+GIT_INLINE(int) git_oid__cmp(const git_oid *a, const git_oid *b)
+{
+	return git_oid__hashcmp(a->id, b->id);
+}
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/oidarray.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/oidarray.c
new file mode 100755
index 0000000..1d51a29
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/oidarray.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2/oidarray.h"
+#include "oidarray.h"
+#include "array.h"
+
+void git_oidarray_free(git_oidarray *arr)
+{
+	git__free(arr->ids);
+}
+
+void git_oidarray__from_array(git_oidarray *arr, git_array_oid_t *array)
+{
+	arr->count = array->size;
+	arr->ids = array->ptr;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/oidarray.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/oidarray.h
new file mode 100755
index 0000000..a7215ae
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/oidarray.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_oidarray_h__
+#define INCLUDE_oidarray_h__
+
+#include "common.h"
+#include "git2/oidarray.h"
+#include "array.h"
+
+typedef git_array_t(git_oid) git_array_oid_t;
+
+extern void git_oidarray__from_array(git_oidarray *arr, git_array_oid_t *array);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/oidmap.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/oidmap.h
new file mode 100755
index 0000000..d2c451e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/oidmap.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_oidmap_h__
+#define INCLUDE_oidmap_h__
+
+#include "common.h"
+#include "git2/oid.h"
+
+#define kmalloc git__malloc
+#define kcalloc git__calloc
+#define krealloc git__realloc
+#define kreallocarray git__reallocarray
+#define kfree git__free
+#include "khash.h"
+
+__KHASH_TYPE(oid, const git_oid *, void *)
+typedef khash_t(oid) git_oidmap;
+
+GIT_INLINE(khint_t) git_oidmap_hash(const git_oid *oid)
+{
+	khint_t h;
+	memcpy(&h, oid, sizeof(khint_t));
+	return h;
+}
+
+#define GIT__USE_OIDMAP \
+	__KHASH_IMPL(oid, static kh_inline, const git_oid *, void *, 1, git_oidmap_hash, git_oid_equal)
+
+#define git_oidmap_alloc() kh_init(oid)
+#define git_oidmap_free(h) kh_destroy(oid,h), h = NULL
+
+#define git_oidmap_lookup_index(h, k) kh_get(oid, h, k)
+#define git_oidmap_valid_index(h, idx) (idx != kh_end(h))
+
+#define git_oidmap_value_at(h, idx) kh_val(h, idx)
+
+#define git_oidmap_insert(h, key, val, rval) do { \
+	khiter_t __pos = kh_put(oid, h, key, &rval); \
+	if (rval >= 0) { \
+		if (rval == 0) kh_key(h, __pos) = key; \
+		kh_val(h, __pos) = val; \
+	} } while (0)
+
+#define git_oidmap_foreach_value kh_foreach_value
+
+#define git_oidmap_size(h) kh_size(h)
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/openssl_stream.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/openssl_stream.c
new file mode 100755
index 0000000..4df7c6b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/openssl_stream.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifdef GIT_OPENSSL
+
+#include <ctype.h>
+
+#include "global.h"
+#include "posix.h"
+#include "stream.h"
+#include "socket_stream.h"
+#include "netops.h"
+#include "git2/transport.h"
+
+#ifdef GIT_CURL
+# include "curl_stream.h"
+#endif
+
+#ifndef GIT_WIN32
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+#endif
+
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#include <openssl/bio.h>
+
+static int bio_create(BIO *b)
+{
+	b->init = 1;
+	b->num = 0;
+	b->ptr = NULL;
+	b->flags = 0;
+
+	return 1;
+}
+
+static int bio_destroy(BIO *b)
+{
+	if (!b)
+		return 0;
+
+	b->init = 0;
+	b->num = 0;
+	b->ptr = NULL;
+	b->flags = 0;
+
+	return 1;
+}
+
+static int bio_read(BIO *b, char *buf, int len)
+{
+	git_stream *io = (git_stream *) b->ptr;
+	return (int) git_stream_read(io, buf, len);
+}
+
+static int bio_write(BIO *b, const char *buf, int len)
+{
+	git_stream *io = (git_stream *) b->ptr;
+	return (int) git_stream_write(io, buf, len, 0);
+}
+
+static long bio_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	GIT_UNUSED(b);
+	GIT_UNUSED(num);
+	GIT_UNUSED(ptr);
+
+	if (cmd == BIO_CTRL_FLUSH)
+		return 1;
+
+	return 0;
+}
+
+static int bio_gets(BIO *b, char *buf, int len)
+{
+	GIT_UNUSED(b);
+	GIT_UNUSED(buf);
+	GIT_UNUSED(len);
+	return -1;
+}
+
+static int bio_puts(BIO *b, const char *str)
+{
+	return bio_write(b, str, strlen(str));
+}
+
+static BIO_METHOD git_stream_bio_method = {
+	BIO_TYPE_SOURCE_SINK,
+	"git_stream",
+	bio_write,
+	bio_read,
+	bio_puts,
+	bio_gets,
+	bio_ctrl,
+	bio_create,
+	bio_destroy
+};
+
+static int ssl_set_error(SSL *ssl, int error)
+{
+	int err;
+	unsigned long e;
+
+	err = SSL_get_error(ssl, error);
+
+	assert(err != SSL_ERROR_WANT_READ);
+	assert(err != SSL_ERROR_WANT_WRITE);
+
+	switch (err) {
+	case SSL_ERROR_WANT_CONNECT:
+	case SSL_ERROR_WANT_ACCEPT:
+		giterr_set(GITERR_NET, "SSL error: connection failure\n");
+		break;
+	case SSL_ERROR_WANT_X509_LOOKUP:
+		giterr_set(GITERR_NET, "SSL error: x509 error\n");
+		break;
+	case SSL_ERROR_SYSCALL:
+		e = ERR_get_error();
+		if (e > 0) {
+			giterr_set(GITERR_NET, "SSL error: %s",
+					ERR_error_string(e, NULL));
+			break;
+		} else if (error < 0) {
+			giterr_set(GITERR_OS, "SSL error: syscall failure");
+			break;
+		}
+		giterr_set(GITERR_NET, "SSL error: received early EOF");
+		return GIT_EEOF;
+		break;
+	case SSL_ERROR_SSL:
+		e = ERR_get_error();
+		giterr_set(GITERR_NET, "SSL error: %s",
+				ERR_error_string(e, NULL));
+		break;
+	case SSL_ERROR_NONE:
+	case SSL_ERROR_ZERO_RETURN:
+	default:
+		giterr_set(GITERR_NET, "SSL error: unknown error");
+		break;
+	}
+	return -1;
+}
+
+static int ssl_teardown(SSL *ssl)
+{
+	int ret;
+
+	ret = SSL_shutdown(ssl);
+	if (ret < 0)
+		ret = ssl_set_error(ssl, ret);
+	else
+		ret = 0;
+
+	SSL_free(ssl);
+	return ret;
+}
+
+static int check_host_name(const char *name, const char *host)
+{
+	if (!strcasecmp(name, host))
+		return 0;
+
+	if (gitno__match_host(name, host) < 0)
+		return -1;
+
+	return 0;
+}
+
+static int verify_server_cert(SSL *ssl, const char *host)
+{
+	X509 *cert;
+	X509_NAME *peer_name;
+	ASN1_STRING *str;
+	unsigned char *peer_cn = NULL;
+	int matched = -1, type = GEN_DNS;
+	GENERAL_NAMES *alts;
+	struct in6_addr addr6;
+	struct in_addr addr4;
+	void *addr;
+	int i = -1,j;
+
+	if (SSL_get_verify_result(ssl) != X509_V_OK) {
+		giterr_set(GITERR_SSL, "The SSL certificate is invalid");
+		return GIT_ECERTIFICATE;
+	}
+
+	/* Try to parse the host as an IP address to see if it is */
+	if (p_inet_pton(AF_INET, host, &addr4)) {
+		type = GEN_IPADD;
+		addr = &addr4;
+	} else {
+		if(p_inet_pton(AF_INET6, host, &addr6)) {
+			type = GEN_IPADD;
+			addr = &addr6;
+		}
+	}
+
+
+	cert = SSL_get_peer_certificate(ssl);
+	if (!cert) {
+		giterr_set(GITERR_SSL, "the server did not provide a certificate");
+		return -1;
+	}
+
+	/* Check the alternative names */
+	alts = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
+	if (alts) {
+		int num;
+
+		num = sk_GENERAL_NAME_num(alts);
+		for (i = 0; i < num && matched != 1; i++) {
+			const GENERAL_NAME *gn = sk_GENERAL_NAME_value(alts, i);
+			const char *name = (char *) ASN1_STRING_data(gn->d.ia5);
+			size_t namelen = (size_t) ASN1_STRING_length(gn->d.ia5);
+
+			/* Skip any names of a type we're not looking for */
+			if (gn->type != type)
+				continue;
+
+			if (type == GEN_DNS) {
+				/* If it contains embedded NULs, don't even try */
+				if (memchr(name, '\0', namelen))
+					continue;
+
+				if (check_host_name(name, host) < 0)
+					matched = 0;
+				else
+					matched = 1;
+			} else if (type == GEN_IPADD) {
+				/* Here name isn't so much a name but a binary representation of the IP */
+				matched = !!memcmp(name, addr, namelen);
+			}
+		}
+	}
+	GENERAL_NAMES_free(alts);
+
+	if (matched == 0)
+		goto cert_fail_name;
+
+	if (matched == 1)
+		return 0;
+
+	/* If no alternative names are available, check the common name */
+	peer_name = X509_get_subject_name(cert);
+	if (peer_name == NULL)
+		goto on_error;
+
+	if (peer_name) {
+		/* Get the index of the last CN entry */
+		while ((j = X509_NAME_get_index_by_NID(peer_name, NID_commonName, i)) >= 0)
+			i = j;
+	}
+
+	if (i < 0)
+		goto on_error;
+
+	str = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(peer_name, i));
+	if (str == NULL)
+		goto on_error;
+
+	/* Work around a bug in OpenSSL whereby ASN1_STRING_to_UTF8 fails if it's already in utf-8 */
+	if (ASN1_STRING_type(str) == V_ASN1_UTF8STRING) {
+		int size = ASN1_STRING_length(str);
+
+		if (size > 0) {
+			peer_cn = OPENSSL_malloc(size + 1);
+			GITERR_CHECK_ALLOC(peer_cn);
+			memcpy(peer_cn, ASN1_STRING_data(str), size);
+			peer_cn[size] = '\0';
+		}
+	} else {
+		int size = ASN1_STRING_to_UTF8(&peer_cn, str);
+		GITERR_CHECK_ALLOC(peer_cn);
+		if (memchr(peer_cn, '\0', size))
+			goto cert_fail_name;
+	}
+
+	if (check_host_name((char *)peer_cn, host) < 0)
+		goto cert_fail_name;
+
+	OPENSSL_free(peer_cn);
+
+	return 0;
+
+on_error:
+	OPENSSL_free(peer_cn);
+	return ssl_set_error(ssl, 0);
+
+cert_fail_name:
+	OPENSSL_free(peer_cn);
+	giterr_set(GITERR_SSL, "hostname does not match certificate");
+	return GIT_ECERTIFICATE;
+}
+
+typedef struct {
+	git_stream parent;
+	git_stream *io;
+	char *host;
+	SSL *ssl;
+	git_cert_x509 cert_info;
+} openssl_stream;
+
+int openssl_close(git_stream *stream);
+
+int openssl_connect(git_stream *stream)
+{
+	int ret;
+	BIO *bio;
+	openssl_stream *st = (openssl_stream *) stream;
+
+	if ((ret = git_stream_connect(st->io)) < 0)
+		return ret;
+
+	bio = BIO_new(&git_stream_bio_method);
+	GITERR_CHECK_ALLOC(bio);
+	bio->ptr = st->io;
+
+	SSL_set_bio(st->ssl, bio, bio);
+	/* specify the host in case SNI is needed */
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+	SSL_set_tlsext_host_name(st->ssl, st->host);
+#endif
+
+	if ((ret = SSL_connect(st->ssl)) <= 0)
+		return ssl_set_error(st->ssl, ret);
+
+	return verify_server_cert(st->ssl, st->host);
+}
+
+int openssl_certificate(git_cert **out, git_stream *stream)
+{
+	openssl_stream *st = (openssl_stream *) stream;
+	int len;
+	X509 *cert = SSL_get_peer_certificate(st->ssl);
+	unsigned char *guard, *encoded_cert;
+
+	/* Retrieve the length of the certificate first */
+	len = i2d_X509(cert, NULL);
+	if (len < 0) {
+		giterr_set(GITERR_NET, "failed to retrieve certificate information");
+		return -1;
+	}
+
+	encoded_cert = git__malloc(len);
+	GITERR_CHECK_ALLOC(encoded_cert);
+	/* i2d_X509 makes 'guard' point to just after the data */
+	guard = encoded_cert;
+
+	len = i2d_X509(cert, &guard);
+	if (len < 0) {
+		git__free(encoded_cert);
+		giterr_set(GITERR_NET, "failed to retrieve certificate information");
+		return -1;
+	}
+
+	st->cert_info.cert_type = GIT_CERT_X509;
+	st->cert_info.data = encoded_cert;
+	st->cert_info.len = len;
+
+	*out = (git_cert *)&st->cert_info;
+	return 0;
+}
+
+static int openssl_set_proxy(git_stream *stream, const char *proxy_url)
+{
+	openssl_stream *st = (openssl_stream *) stream;
+
+	return git_stream_set_proxy(st->io, proxy_url);
+}
+
+ssize_t openssl_write(git_stream *stream, const char *data, size_t len, int flags)
+{
+	openssl_stream *st = (openssl_stream *) stream;
+	int ret;
+
+	GIT_UNUSED(flags);
+
+	if ((ret = SSL_write(st->ssl, data, len)) <= 0) {
+		return ssl_set_error(st->ssl, ret);
+	}
+
+	return ret;
+}
+
+ssize_t openssl_read(git_stream *stream, void *data, size_t len)
+{
+	openssl_stream *st = (openssl_stream *) stream;
+	int ret;
+
+	if ((ret = SSL_read(st->ssl, data, len)) <= 0)
+		ssl_set_error(st->ssl, ret);
+
+	return ret;
+}
+
+int openssl_close(git_stream *stream)
+{
+	openssl_stream *st = (openssl_stream *) stream;
+	int ret;
+
+	if ((ret = ssl_teardown(st->ssl)) < 0)
+		return -1;
+
+	return git_stream_close(st->io);
+}
+
+void openssl_free(git_stream *stream)
+{
+	openssl_stream *st = (openssl_stream *) stream;
+
+	git__free(st->host);
+	git__free(st->cert_info.data);
+	git_stream_free(st->io);
+	git__free(st);
+}
+
+int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
+{
+	int error;
+	openssl_stream *st;
+
+	st = git__calloc(1, sizeof(openssl_stream));
+	GITERR_CHECK_ALLOC(st);
+
+#ifdef GIT_CURL
+	error = git_curl_stream_new(&st->io, host, port);
+#else
+	error = git_socket_stream_new(&st->io, host, port);
+#endif
+
+	if (error < 0)
+		return error;
+
+	st->ssl = SSL_new(git__ssl_ctx);
+	if (st->ssl == NULL) {
+		giterr_set(GITERR_SSL, "failed to create ssl object");
+		return -1;
+	}
+
+	st->host = git__strdup(host);
+	GITERR_CHECK_ALLOC(st->host);
+
+	st->parent.version = GIT_STREAM_VERSION;
+	st->parent.encrypted = 1;
+	st->parent.proxy_support = git_stream_supports_proxy(st->io);
+	st->parent.connect = openssl_connect;
+	st->parent.certificate = openssl_certificate;
+	st->parent.set_proxy = openssl_set_proxy;
+	st->parent.read = openssl_read;
+	st->parent.write = openssl_write;
+	st->parent.close = openssl_close;
+	st->parent.free = openssl_free;
+
+	*out = (git_stream *) st;
+	return 0;
+}
+
+#else
+
+#include "stream.h"
+
+int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
+{
+	GIT_UNUSED(out);
+	GIT_UNUSED(host);
+	GIT_UNUSED(port);
+
+	giterr_set(GITERR_SSL, "openssl is not supported in this version");
+	return -1;
+}
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/openssl_stream.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/openssl_stream.h
new file mode 100755
index 0000000..9ca0648
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/openssl_stream.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_openssl_stream_h__
+#define INCLUDE_openssl_stream_h__
+
+#include "git2/sys/stream.h"
+
+extern int git_openssl_stream_new(git_stream **out, const char *host, const char *port);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pack-objects.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pack-objects.c
new file mode 100755
index 0000000..c4c061a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pack-objects.c
@@ -0,0 +1,1750 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "pack-objects.h"
+
+#include "zstream.h"
+#include "delta.h"
+#include "iterator.h"
+#include "netops.h"
+#include "pack.h"
+#include "thread-utils.h"
+#include "tree.h"
+#include "util.h"
+#include "revwalk.h"
+#include "commit_list.h"
+
+#include "git2/pack.h"
+#include "git2/commit.h"
+#include "git2/tag.h"
+#include "git2/indexer.h"
+#include "git2/config.h"
+
+struct unpacked {
+	git_pobject *object;
+	void *data;
+	struct git_delta_index *index;
+	int depth;
+};
+
+struct tree_walk_context {
+	git_packbuilder *pb;
+	git_buf buf;
+};
+
+struct pack_write_context {
+	git_indexer *indexer;
+	git_transfer_progress *stats;
+};
+
+GIT__USE_OIDMAP
+
+#ifdef GIT_THREADS
+
+#define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) do { \
+		int result = git_mutex_##op(&(pb)->mtx); \
+		assert(!result); \
+		GIT_UNUSED(result); \
+	} while (0)
+
+#else
+
+#define GIT_PACKBUILDER__MUTEX_OP(pb,mtx,op) GIT_UNUSED(pb)
+
+#endif /* GIT_THREADS */
+
+#define git_packbuilder__cache_lock(pb) GIT_PACKBUILDER__MUTEX_OP(pb, cache_mutex, lock)
+#define git_packbuilder__cache_unlock(pb) GIT_PACKBUILDER__MUTEX_OP(pb, cache_mutex, unlock)
+#define git_packbuilder__progress_lock(pb) GIT_PACKBUILDER__MUTEX_OP(pb, progress_mutex, lock)
+#define git_packbuilder__progress_unlock(pb) GIT_PACKBUILDER__MUTEX_OP(pb, progress_mutex, unlock)
+
+/* The minimal interval between progress updates (in seconds). */
+#define MIN_PROGRESS_UPDATE_INTERVAL 0.5
+
+/* Size of the buffer to feed to zlib */
+#define COMPRESS_BUFLEN (1024 * 1024)
+
+static unsigned name_hash(const char *name)
+{
+	unsigned c, hash = 0;
+
+	if (!name)
+		return 0;
+
+	/*
+	 * This effectively just creates a sortable number from the
+	 * last sixteen non-whitespace characters. Last characters
+	 * count "most", so things that end in ".c" sort together.
+	 */
+	while ((c = *name++) != 0) {
+		if (git__isspace(c))
+			continue;
+		hash = (hash >> 2) + (c << 24);
+	}
+	return hash;
+}
+
+static int packbuilder_config(git_packbuilder *pb)
+{
+	git_config *config;
+	int ret;
+	int64_t val;
+
+	if ((ret = git_repository_config_snapshot(&config, pb->repo)) < 0)
+		return ret;
+
+#define config_get(KEY,DST,DFLT) do { \
+	ret = git_config_get_int64(&val, config, KEY); \
+	if (!ret) (DST) = val; \
+	else if (ret == GIT_ENOTFOUND) (DST) = (DFLT); \
+	else if (ret < 0) return -1; } while (0)
+
+	config_get("pack.deltaCacheSize", pb->max_delta_cache_size,
+		   GIT_PACK_DELTA_CACHE_SIZE);
+	config_get("pack.deltaCacheLimit", pb->cache_max_small_delta_size,
+		   GIT_PACK_DELTA_CACHE_LIMIT);
+	config_get("pack.deltaCacheSize", pb->big_file_threshold,
+		   GIT_PACK_BIG_FILE_THRESHOLD);
+	config_get("pack.windowMemory", pb->window_memory_limit, 0);
+
+#undef config_get
+
+	git_config_free(config);
+
+	return 0;
+}
+
+int git_packbuilder_new(git_packbuilder **out, git_repository *repo)
+{
+	git_packbuilder *pb;
+
+	*out = NULL;
+
+	pb = git__calloc(1, sizeof(*pb));
+	GITERR_CHECK_ALLOC(pb);
+
+	pb->object_ix = git_oidmap_alloc();
+	if (!pb->object_ix)
+		goto on_error;
+
+	pb->walk_objects = git_oidmap_alloc();
+	if (!pb->walk_objects)
+		goto on_error;
+
+	if (git_pool_init(&pb->object_pool, sizeof(git_walk_object), 0) < 0)
+		goto on_error;
+
+	pb->repo = repo;
+	pb->nr_threads = 1; /* do not spawn any thread by default */
+
+	if (git_hash_ctx_init(&pb->ctx) < 0 ||
+		git_zstream_init(&pb->zstream) < 0 ||
+		git_repository_odb(&pb->odb, repo) < 0 ||
+		packbuilder_config(pb) < 0)
+		goto on_error;
+
+#ifdef GIT_THREADS
+
+	if (git_mutex_init(&pb->cache_mutex) ||
+		git_mutex_init(&pb->progress_mutex) ||
+		git_cond_init(&pb->progress_cond))
+	{
+		giterr_set(GITERR_OS, "Failed to initialize packbuilder mutex");
+		goto on_error;
+	}
+
+#endif
+
+	*out = pb;
+	return 0;
+
+on_error:
+	git_packbuilder_free(pb);
+	return -1;
+}
+
+unsigned int git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n)
+{
+	assert(pb);
+
+#ifdef GIT_THREADS
+	pb->nr_threads = n;
+#else
+	GIT_UNUSED(n);
+	assert(1 == pb->nr_threads);
+#endif
+
+	return pb->nr_threads;
+}
+
+static void rehash(git_packbuilder *pb)
+{
+	git_pobject *po;
+	khiter_t pos;
+	unsigned int i;
+	int ret;
+
+	kh_clear(oid, pb->object_ix);
+	for (i = 0, po = pb->object_list; i < pb->nr_objects; i++, po++) {
+		pos = kh_put(oid, pb->object_ix, &po->id, &ret);
+		kh_value(pb->object_ix, pos) = po;
+	}
+}
+
+int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
+			   const char *name)
+{
+	git_pobject *po;
+	khiter_t pos;
+	size_t newsize;
+	int ret;
+
+	assert(pb && oid);
+
+	/* If the object already exists in the hash table, then we don't
+	 * have any work to do */
+	pos = kh_get(oid, pb->object_ix, oid);
+	if (pos != kh_end(pb->object_ix))
+		return 0;
+
+	if (pb->nr_objects >= pb->nr_alloc) {
+		GITERR_CHECK_ALLOC_ADD(&newsize, pb->nr_alloc, 1024);
+		GITERR_CHECK_ALLOC_MULTIPLY(&newsize, newsize, 3 / 2);
+
+		if (!git__is_uint32(newsize)) {
+			giterr_set(GITERR_NOMEMORY, "Packfile too large to fit in memory.");
+			return -1;
+		}
+
+		pb->nr_alloc = (uint32_t)newsize;
+
+		pb->object_list = git__reallocarray(pb->object_list,
+			pb->nr_alloc, sizeof(*po));
+		GITERR_CHECK_ALLOC(pb->object_list);
+		rehash(pb);
+	}
+
+	po = pb->object_list + pb->nr_objects;
+	memset(po, 0x0, sizeof(*po));
+
+	if ((ret = git_odb_read_header(&po->size, &po->type, pb->odb, oid)) < 0)
+		return ret;
+
+	pb->nr_objects++;
+	git_oid_cpy(&po->id, oid);
+	po->hash = name_hash(name);
+
+	pos = kh_put(oid, pb->object_ix, &po->id, &ret);
+	if (ret < 0) {
+		giterr_set_oom();
+		return ret;
+	}
+	assert(ret != 0);
+	kh_value(pb->object_ix, pos) = po;
+
+	pb->done = false;
+
+	if (pb->progress_cb) {
+		double current_time = git__timer();
+		double elapsed = current_time - pb->last_progress_report_time;
+
+		if (elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
+			pb->last_progress_report_time = current_time;
+
+			ret = pb->progress_cb(
+				GIT_PACKBUILDER_ADDING_OBJECTS,
+				pb->nr_objects, 0, pb->progress_cb_payload);
+
+			if (ret)
+				return giterr_set_after_callback(ret);
+		}
+	}
+
+	return 0;
+}
+
+static int get_delta(void **out, git_odb *odb, git_pobject *po)
+{
+	git_odb_object *src = NULL, *trg = NULL;
+	unsigned long delta_size;
+	void *delta_buf;
+
+	*out = NULL;
+
+	if (git_odb_read(&src, odb, &po->delta->id) < 0 ||
+	    git_odb_read(&trg, odb, &po->id) < 0)
+		goto on_error;
+
+	delta_buf = git_delta(
+		git_odb_object_data(src), (unsigned long)git_odb_object_size(src),
+		git_odb_object_data(trg), (unsigned long)git_odb_object_size(trg),
+		&delta_size, 0);
+
+	if (!delta_buf || delta_size != po->delta_size) {
+		giterr_set(GITERR_INVALID, "Delta size changed");
+		goto on_error;
+	}
+
+	*out = delta_buf;
+
+	git_odb_object_free(src);
+	git_odb_object_free(trg);
+	return 0;
+
+on_error:
+	git_odb_object_free(src);
+	git_odb_object_free(trg);
+	return -1;
+}
+
+static int write_object(
+	git_packbuilder *pb,
+	git_pobject *po,
+	int (*write_cb)(void *buf, size_t size, void *cb_data),
+	void *cb_data)
+{
+	git_odb_object *obj = NULL;
+	git_otype type;
+	unsigned char hdr[10], *zbuf = NULL;
+	void *data = NULL;
+	size_t hdr_len, zbuf_len = COMPRESS_BUFLEN, data_len;
+	int error;
+
+	/*
+	 * If we have a delta base, let's use the delta to save space.
+	 * Otherwise load the whole object. 'data' ends up pointing to
+	 * whatever data we want to put into the packfile.
+	 */
+	if (po->delta) {
+		if (po->delta_data)
+			data = po->delta_data;
+		else if ((error = get_delta(&data, pb->odb, po)) < 0)
+				goto done;
+
+		data_len = po->delta_size;
+		type = GIT_OBJ_REF_DELTA;
+	} else {
+		if ((error = git_odb_read(&obj, pb->odb, &po->id)) < 0)
+			goto done;
+
+		data = (void *)git_odb_object_data(obj);
+		data_len = git_odb_object_size(obj);
+		type = git_odb_object_type(obj);
+	}
+
+	/* Write header */
+	hdr_len = git_packfile__object_header(hdr, data_len, type);
+
+	if ((error = write_cb(hdr, hdr_len, cb_data)) < 0 ||
+		(error = git_hash_update(&pb->ctx, hdr, hdr_len)) < 0)
+		goto done;
+
+	if (type == GIT_OBJ_REF_DELTA) {
+		if ((error = write_cb(po->delta->id.id, GIT_OID_RAWSZ, cb_data)) < 0 ||
+			(error = git_hash_update(&pb->ctx, po->delta->id.id, GIT_OID_RAWSZ)) < 0)
+			goto done;
+	}
+
+	/* Write data */
+	if (po->z_delta_size) {
+		data_len = po->z_delta_size;
+
+		if ((error = write_cb(data, data_len, cb_data)) < 0 ||
+			(error = git_hash_update(&pb->ctx, data, data_len)) < 0)
+			goto done;
+	} else {
+		zbuf = git__malloc(zbuf_len);
+		GITERR_CHECK_ALLOC(zbuf);
+
+		git_zstream_reset(&pb->zstream);
+		git_zstream_set_input(&pb->zstream, data, data_len);
+
+		while (!git_zstream_done(&pb->zstream)) {
+			if ((error = git_zstream_get_output(zbuf, &zbuf_len, &pb->zstream)) < 0 ||
+				(error = write_cb(zbuf, zbuf_len, cb_data)) < 0 ||
+				(error = git_hash_update(&pb->ctx, zbuf, zbuf_len)) < 0)
+				goto done;
+
+			zbuf_len = COMPRESS_BUFLEN; /* reuse buffer */
+		}
+	}
+
+	/*
+	 * If po->delta is true, data is a delta and it is our
+	 * responsibility to free it (otherwise it's a git_object's
+	 * data). We set po->delta_data to NULL in case we got the
+	 * data from there instead of get_delta(). If we didn't,
+	 * there's no harm.
+	 */
+	if (po->delta) {
+		git__free(data);
+		po->delta_data = NULL;
+	}
+
+	pb->nr_written++;
+
+done:
+	git__free(zbuf);
+	git_odb_object_free(obj);
+	return error;
+}
+
+enum write_one_status {
+	WRITE_ONE_SKIP = -1, /* already written */
+	WRITE_ONE_BREAK = 0, /* writing this will bust the limit; not written */
+	WRITE_ONE_WRITTEN = 1, /* normal */
+	WRITE_ONE_RECURSIVE = 2 /* already scheduled to be written */
+};
+
+static int write_one(
+	enum write_one_status *status,
+	git_packbuilder *pb,
+	git_pobject *po,
+	int (*write_cb)(void *buf, size_t size, void *cb_data),
+	void *cb_data)
+{
+	int error;
+
+	if (po->recursing) {
+		*status = WRITE_ONE_RECURSIVE;
+		return 0;
+	} else if (po->written) {
+		*status = WRITE_ONE_SKIP;
+		return 0;
+	}
+
+	if (po->delta) {
+		po->recursing = 1;
+
+		if ((error = write_one(status, pb, po->delta, write_cb, cb_data)) < 0)
+			return error;
+
+		/* we cannot depend on this one */
+		if (*status == WRITE_ONE_RECURSIVE)
+			po->delta = NULL;
+	}
+
+	*status = WRITE_ONE_WRITTEN;
+	po->written = 1;
+	po->recursing = 0;
+
+	return write_object(pb, po, write_cb, cb_data);
+}
+
+GIT_INLINE(void) add_to_write_order(git_pobject **wo, unsigned int *endp,
+				    git_pobject *po)
+{
+	if (po->filled)
+		return;
+	wo[(*endp)++] = po;
+	po->filled = 1;
+}
+
+static void add_descendants_to_write_order(git_pobject **wo, unsigned int *endp,
+					   git_pobject *po)
+{
+	int add_to_order = 1;
+	while (po) {
+		if (add_to_order) {
+			git_pobject *s;
+			/* add this node... */
+			add_to_write_order(wo, endp, po);
+			/* all its siblings... */
+			for (s = po->delta_sibling; s; s = s->delta_sibling) {
+				add_to_write_order(wo, endp, s);
+			}
+		}
+		/* drop down a level to add left subtree nodes if possible */
+		if (po->delta_child) {
+			add_to_order = 1;
+			po = po->delta_child;
+		} else {
+			add_to_order = 0;
+			/* our sibling might have some children, it is next */
+			if (po->delta_sibling) {
+				po = po->delta_sibling;
+				continue;
+			}
+			/* go back to our parent node */
+			po = po->delta;
+			while (po && !po->delta_sibling) {
+				/* we're on the right side of a subtree, keep
+				 * going up until we can go right again */
+				po = po->delta;
+			}
+			if (!po) {
+				/* done- we hit our original root node */
+				return;
+			}
+			/* pass it off to sibling at this level */
+			po = po->delta_sibling;
+		}
+	};
+}
+
+static void add_family_to_write_order(git_pobject **wo, unsigned int *endp,
+				      git_pobject *po)
+{
+	git_pobject *root;
+
+	for (root = po; root->delta; root = root->delta)
+		; /* nothing */
+	add_descendants_to_write_order(wo, endp, root);
+}
+
+static int cb_tag_foreach(const char *name, git_oid *oid, void *data)
+{
+	git_packbuilder *pb = data;
+	git_pobject *po;
+	khiter_t pos;
+
+	GIT_UNUSED(name);
+
+	pos = kh_get(oid, pb->object_ix, oid);
+	if (pos == kh_end(pb->object_ix))
+		return 0;
+
+	po = kh_value(pb->object_ix, pos);
+	po->tagged = 1;
+
+	/* TODO: peel objects */
+
+	return 0;
+}
+
+static git_pobject **compute_write_order(git_packbuilder *pb)
+{
+	unsigned int i, wo_end, last_untagged;
+	git_pobject **wo;
+
+	if ((wo = git__mallocarray(pb->nr_objects, sizeof(*wo))) == NULL)
+		return NULL;
+
+	for (i = 0; i < pb->nr_objects; i++) {
+		git_pobject *po = pb->object_list + i;
+		po->tagged = 0;
+		po->filled = 0;
+		po->delta_child = NULL;
+		po->delta_sibling = NULL;
+	}
+
+	/*
+	 * Fully connect delta_child/delta_sibling network.
+	 * Make sure delta_sibling is sorted in the original
+	 * recency order.
+	 */
+	for (i = pb->nr_objects; i > 0;) {
+		git_pobject *po = &pb->object_list[--i];
+		if (!po->delta)
+			continue;
+		/* Mark me as the first child */
+		po->delta_sibling = po->delta->delta_child;
+		po->delta->delta_child = po;
+	}
+
+	/*
+	 * Mark objects that are at the tip of tags.
+	 */
+	if (git_tag_foreach(pb->repo, &cb_tag_foreach, pb) < 0) {
+		git__free(wo);
+		return NULL;
+	}
+
+	/*
+	 * Give the objects in the original recency order until
+	 * we see a tagged tip.
+	 */
+	for (i = wo_end = 0; i < pb->nr_objects; i++) {
+		git_pobject *po = pb->object_list + i;
+		if (po->tagged)
+			break;
+		add_to_write_order(wo, &wo_end, po);
+	}
+	last_untagged = i;
+
+	/*
+	 * Then fill all the tagged tips.
+	 */
+	for (; i < pb->nr_objects; i++) {
+		git_pobject *po = pb->object_list + i;
+		if (po->tagged)
+			add_to_write_order(wo, &wo_end, po);
+	}
+
+	/*
+	 * And then all remaining commits and tags.
+	 */
+	for (i = last_untagged; i < pb->nr_objects; i++) {
+		git_pobject *po = pb->object_list + i;
+		if (po->type != GIT_OBJ_COMMIT &&
+		    po->type != GIT_OBJ_TAG)
+			continue;
+		add_to_write_order(wo, &wo_end, po);
+	}
+
+	/*
+	 * And then all the trees.
+	 */
+	for (i = last_untagged; i < pb->nr_objects; i++) {
+		git_pobject *po = pb->object_list + i;
+		if (po->type != GIT_OBJ_TREE)
+			continue;
+		add_to_write_order(wo, &wo_end, po);
+	}
+
+	/*
+	 * Finally all the rest in really tight order
+	 */
+	for (i = last_untagged; i < pb->nr_objects; i++) {
+		git_pobject *po = pb->object_list + i;
+		if (!po->filled)
+			add_family_to_write_order(wo, &wo_end, po);
+	}
+
+	if (wo_end != pb->nr_objects) {
+		giterr_set(GITERR_INVALID, "invalid write order");
+		return NULL;
+	}
+
+	return wo;
+}
+
+static int write_pack(git_packbuilder *pb,
+	int (*write_cb)(void *buf, size_t size, void *cb_data),
+	void *cb_data)
+{
+	git_pobject **write_order;
+	git_pobject *po;
+	enum write_one_status status;
+	struct git_pack_header ph;
+	git_oid entry_oid;
+	unsigned int i = 0;
+	int error = 0;
+
+	write_order = compute_write_order(pb);
+	if (write_order == NULL) {
+		error = -1;
+		goto done;
+	}
+
+	/* Write pack header */
+	ph.hdr_signature = htonl(PACK_SIGNATURE);
+	ph.hdr_version = htonl(PACK_VERSION);
+	ph.hdr_entries = htonl(pb->nr_objects);
+
+	if ((error = write_cb(&ph, sizeof(ph), cb_data)) < 0 ||
+		(error = git_hash_update(&pb->ctx, &ph, sizeof(ph))) < 0)
+		goto done;
+
+	pb->nr_remaining = pb->nr_objects;
+	do {
+		pb->nr_written = 0;
+		for ( ; i < pb->nr_objects; ++i) {
+			po = write_order[i];
+
+			if ((error = write_one(&status, pb, po, write_cb, cb_data)) < 0)
+				goto done;
+		}
+
+		pb->nr_remaining -= pb->nr_written;
+	} while (pb->nr_remaining && i < pb->nr_objects);
+
+	if ((error = git_hash_final(&entry_oid, &pb->ctx)) < 0)
+		goto done;
+
+	error = write_cb(entry_oid.id, GIT_OID_RAWSZ, cb_data);
+
+done:
+	/* if callback cancelled writing, we must still free delta_data */
+	for ( ; i < pb->nr_objects; ++i) {
+		po = write_order[i];
+		if (po->delta_data) {
+			git__free(po->delta_data);
+			po->delta_data = NULL;
+		}
+	}
+
+	git__free(write_order);
+	return error;
+}
+
+static int write_pack_buf(void *buf, size_t size, void *data)
+{
+	git_buf *b = (git_buf *)data;
+	return git_buf_put(b, buf, size);
+}
+
+static int type_size_sort(const void *_a, const void *_b)
+{
+	const git_pobject *a = (git_pobject *)_a;
+	const git_pobject *b = (git_pobject *)_b;
+
+	if (a->type > b->type)
+		return -1;
+	if (a->type < b->type)
+		return 1;
+	if (a->hash > b->hash)
+		return -1;
+	if (a->hash < b->hash)
+		return 1;
+	/*
+	 * TODO
+	 *
+	if (a->preferred_base > b->preferred_base)
+		return -1;
+	if (a->preferred_base < b->preferred_base)
+		return 1;
+	*/
+	if (a->size > b->size)
+		return -1;
+	if (a->size < b->size)
+		return 1;
+	return a < b ? -1 : (a > b); /* newest first */
+}
+
+static int delta_cacheable(git_packbuilder *pb, unsigned long src_size,
+			   unsigned long trg_size, unsigned long delta_size)
+{
+	if (pb->max_delta_cache_size &&
+		pb->delta_cache_size + delta_size > pb->max_delta_cache_size)
+		return 0;
+
+	if (delta_size < pb->cache_max_small_delta_size)
+		return 1;
+
+	/* cache delta, if objects are large enough compared to delta size */
+	if ((src_size >> 20) + (trg_size >> 21) > (delta_size >> 10))
+		return 1;
+
+	return 0;
+}
+
+static int try_delta(git_packbuilder *pb, struct unpacked *trg,
+		     struct unpacked *src, int max_depth,
+		     unsigned long *mem_usage, int *ret)
+{
+	git_pobject *trg_object = trg->object;
+	git_pobject *src_object = src->object;
+	git_odb_object *obj;
+	unsigned long trg_size, src_size, delta_size,
+		      sizediff, max_size, sz;
+	unsigned int ref_depth;
+	void *delta_buf;
+
+	/* Don't bother doing diffs between different types */
+	if (trg_object->type != src_object->type) {
+		*ret = -1;
+		return 0;
+	}
+
+	*ret = 0;
+
+	/* TODO: support reuse-delta */
+
+	/* Let's not bust the allowed depth. */
+	if (src->depth >= max_depth)
+		return 0;
+
+	/* Now some size filtering heuristics. */
+	trg_size = (unsigned long)trg_object->size;
+	if (!trg_object->delta) {
+		max_size = trg_size/2 - 20;
+		ref_depth = 1;
+	} else {
+		max_size = trg_object->delta_size;
+		ref_depth = trg->depth;
+	}
+
+	max_size = (uint64_t)max_size * (max_depth - src->depth) /
+					(max_depth - ref_depth + 1);
+	if (max_size == 0)
+		return 0;
+
+	src_size = (unsigned long)src_object->size;
+	sizediff = src_size < trg_size ? trg_size - src_size : 0;
+	if (sizediff >= max_size)
+		return 0;
+	if (trg_size < src_size / 32)
+		return 0;
+
+	/* Load data if not already done */
+	if (!trg->data) {
+		if (git_odb_read(&obj, pb->odb, &trg_object->id) < 0)
+			return -1;
+
+		sz = (unsigned long)git_odb_object_size(obj);
+		trg->data = git__malloc(sz);
+		GITERR_CHECK_ALLOC(trg->data);
+		memcpy(trg->data, git_odb_object_data(obj), sz);
+
+		git_odb_object_free(obj);
+
+		if (sz != trg_size) {
+			giterr_set(GITERR_INVALID,
+				   "Inconsistent target object length");
+			return -1;
+		}
+
+		*mem_usage += sz;
+	}
+	if (!src->data) {
+		size_t obj_sz;
+
+		if (git_odb_read(&obj, pb->odb, &src_object->id) < 0 ||
+			!git__is_ulong(obj_sz = git_odb_object_size(obj)))
+			return -1;
+
+		sz = (unsigned long)obj_sz;
+		src->data = git__malloc(sz);
+		GITERR_CHECK_ALLOC(src->data);
+		memcpy(src->data, git_odb_object_data(obj), sz);
+
+		git_odb_object_free(obj);
+
+		if (sz != src_size) {
+			giterr_set(GITERR_INVALID,
+				   "Inconsistent source object length");
+			return -1;
+		}
+
+		*mem_usage += sz;
+	}
+	if (!src->index) {
+		src->index = git_delta_create_index(src->data, src_size);
+		if (!src->index)
+			return 0; /* suboptimal pack - out of memory */
+
+		*mem_usage += git_delta_sizeof_index(src->index);
+	}
+
+	delta_buf = git_delta_create(src->index, trg->data, trg_size,
+				     &delta_size, max_size);
+	if (!delta_buf)
+		return 0;
+
+	if (trg_object->delta) {
+		/* Prefer only shallower same-sized deltas. */
+		if (delta_size == trg_object->delta_size &&
+		    src->depth + 1 >= trg->depth) {
+			git__free(delta_buf);
+			return 0;
+		}
+	}
+
+	git_packbuilder__cache_lock(pb);
+	if (trg_object->delta_data) {
+		git__free(trg_object->delta_data);
+		pb->delta_cache_size -= trg_object->delta_size;
+		trg_object->delta_data = NULL;
+	}
+	if (delta_cacheable(pb, src_size, trg_size, delta_size)) {
+		bool overflow = git__add_uint64_overflow(
+			&pb->delta_cache_size, pb->delta_cache_size, delta_size);
+
+		git_packbuilder__cache_unlock(pb);
+
+		if (overflow ||
+			!(trg_object->delta_data = git__realloc(delta_buf, delta_size)))
+			return -1;
+	} else {
+		/* create delta when writing the pack */
+		git_packbuilder__cache_unlock(pb);
+		git__free(delta_buf);
+	}
+
+	trg_object->delta = src_object;
+	trg_object->delta_size = delta_size;
+	trg->depth = src->depth + 1;
+
+	*ret = 1;
+	return 0;
+}
+
+static unsigned int check_delta_limit(git_pobject *me, unsigned int n)
+{
+	git_pobject *child = me->delta_child;
+	unsigned int m = n;
+
+	while (child) {
+		unsigned int c = check_delta_limit(child, n + 1);
+		if (m < c)
+			m = c;
+		child = child->delta_sibling;
+	}
+	return m;
+}
+
+static unsigned long free_unpacked(struct unpacked *n)
+{
+	unsigned long freed_mem = git_delta_sizeof_index(n->index);
+	git_delta_free_index(n->index);
+	n->index = NULL;
+	if (n->data) {
+		freed_mem += (unsigned long)n->object->size;
+		git__free(n->data);
+		n->data = NULL;
+	}
+	n->object = NULL;
+	n->depth = 0;
+	return freed_mem;
+}
+
+static int report_delta_progress(git_packbuilder *pb, uint32_t count, bool force)
+{
+	int ret;
+
+	if (pb->progress_cb) {
+		double current_time = git__timer();
+		double elapsed = current_time - pb->last_progress_report_time;
+
+		if (force || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
+			pb->last_progress_report_time = current_time;
+
+			ret = pb->progress_cb(
+				GIT_PACKBUILDER_DELTAFICATION,
+				count, pb->nr_objects, pb->progress_cb_payload);
+
+			if (ret)
+				return giterr_set_after_callback(ret);
+		}
+	}
+
+	return 0;
+}
+
+static int find_deltas(git_packbuilder *pb, git_pobject **list,
+		       unsigned int *list_size, unsigned int window,
+		       int depth)
+{
+	git_pobject *po;
+	git_buf zbuf = GIT_BUF_INIT;
+	struct unpacked *array;
+	uint32_t idx = 0, count = 0;
+	unsigned long mem_usage = 0;
+	unsigned int i;
+	int error = -1;
+
+	array = git__calloc(window, sizeof(struct unpacked));
+	GITERR_CHECK_ALLOC(array);
+
+	for (;;) {
+		struct unpacked *n = array + idx;
+		int max_depth, j, best_base = -1;
+
+		git_packbuilder__progress_lock(pb);
+		if (!*list_size) {
+			git_packbuilder__progress_unlock(pb);
+			break;
+		}
+
+		pb->nr_deltified += 1;
+		report_delta_progress(pb, pb->nr_deltified, false);
+
+		po = *list++;
+		(*list_size)--;
+		git_packbuilder__progress_unlock(pb);
+
+		mem_usage -= free_unpacked(n);
+		n->object = po;
+
+		while (pb->window_memory_limit &&
+		       mem_usage > pb->window_memory_limit &&
+		       count > 1) {
+			uint32_t tail = (idx + window - count) % window;
+			mem_usage -= free_unpacked(array + tail);
+			count--;
+		}
+
+		/*
+		 * If the current object is at pack edge, take the depth the
+		 * objects that depend on the current object into account
+		 * otherwise they would become too deep.
+		 */
+		max_depth = depth;
+		if (po->delta_child) {
+			max_depth -= check_delta_limit(po, 0);
+			if (max_depth <= 0)
+				goto next;
+		}
+
+		j = window;
+		while (--j > 0) {
+			int ret;
+			uint32_t other_idx = idx + j;
+			struct unpacked *m;
+
+			if (other_idx >= window)
+				other_idx -= window;
+
+			m = array + other_idx;
+			if (!m->object)
+				break;
+
+			if (try_delta(pb, n, m, max_depth, &mem_usage, &ret) < 0)
+				goto on_error;
+			if (ret < 0)
+				break;
+			else if (ret > 0)
+				best_base = other_idx;
+		}
+
+		/*
+		 * If we decided to cache the delta data, then it is best
+		 * to compress it right away.  First because we have to do
+		 * it anyway, and doing it here while we're threaded will
+		 * save a lot of time in the non threaded write phase,
+		 * as well as allow for caching more deltas within
+		 * the same cache size limit.
+		 * ...
+		 * But only if not writing to stdout, since in that case
+		 * the network is most likely throttling writes anyway,
+		 * and therefore it is best to go to the write phase ASAP
+		 * instead, as we can afford spending more time compressing
+		 * between writes at that moment.
+		 */
+		if (po->delta_data) {
+			if (git_zstream_deflatebuf(&zbuf, po->delta_data, po->delta_size) < 0)
+				goto on_error;
+
+			git__free(po->delta_data);
+			po->delta_data = git__malloc(zbuf.size);
+			GITERR_CHECK_ALLOC(po->delta_data);
+
+			memcpy(po->delta_data, zbuf.ptr, zbuf.size);
+			po->z_delta_size = (unsigned long)zbuf.size;
+			git_buf_clear(&zbuf);
+
+			git_packbuilder__cache_lock(pb);
+			pb->delta_cache_size -= po->delta_size;
+			pb->delta_cache_size += po->z_delta_size;
+			git_packbuilder__cache_unlock(pb);
+		}
+
+		/*
+		 * If we made n a delta, and if n is already at max
+		 * depth, leaving it in the window is pointless.  we
+		 * should evict it first.
+		 */
+		if (po->delta && max_depth <= n->depth)
+			continue;
+
+		/*
+		 * Move the best delta base up in the window, after the
+		 * currently deltified object, to keep it longer.  It will
+		 * be the first base object to be attempted next.
+		 */
+		if (po->delta) {
+			struct unpacked swap = array[best_base];
+			int dist = (window + idx - best_base) % window;
+			int dst = best_base;
+			while (dist--) {
+				int src = (dst + 1) % window;
+				array[dst] = array[src];
+				dst = src;
+			}
+			array[dst] = swap;
+		}
+
+		next:
+		idx++;
+		if (count + 1 < window)
+			count++;
+		if (idx >= window)
+			idx = 0;
+	}
+	error = 0;
+
+on_error:
+	for (i = 0; i < window; ++i) {
+		git__free(array[i].index);
+		git__free(array[i].data);
+	}
+	git__free(array);
+	git_buf_free(&zbuf);
+
+	return error;
+}
+
+#ifdef GIT_THREADS
+
+struct thread_params {
+	git_thread thread;
+	git_packbuilder *pb;
+
+	git_pobject **list;
+
+	git_cond cond;
+	git_mutex mutex;
+
+	unsigned int list_size;
+	unsigned int remaining;
+
+	int window;
+	int depth;
+	int working;
+	int data_ready;
+};
+
+static void *threaded_find_deltas(void *arg)
+{
+	struct thread_params *me = arg;
+
+	while (me->remaining) {
+		if (find_deltas(me->pb, me->list, &me->remaining,
+				me->window, me->depth) < 0) {
+			; /* TODO */
+		}
+
+		git_packbuilder__progress_lock(me->pb);
+		me->working = 0;
+		git_cond_signal(&me->pb->progress_cond);
+		git_packbuilder__progress_unlock(me->pb);
+
+		if (git_mutex_lock(&me->mutex)) {
+			giterr_set(GITERR_THREAD, "unable to lock packfile condition mutex");
+			return NULL;
+		}
+
+		while (!me->data_ready)
+			git_cond_wait(&me->cond, &me->mutex);
+
+		/*
+		 * We must not set ->data_ready before we wait on the
+		 * condition because the main thread may have set it to 1
+		 * before we get here. In order to be sure that new
+		 * work is available if we see 1 in ->data_ready, it
+		 * was initialized to 0 before this thread was spawned
+		 * and we reset it to 0 right away.
+		 */
+		me->data_ready = 0;
+		git_mutex_unlock(&me->mutex);
+	}
+	/* leave ->working 1 so that this doesn't get more work assigned */
+	return NULL;
+}
+
+static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
+			  unsigned int list_size, unsigned int window,
+			  int depth)
+{
+	struct thread_params *p;
+	int i, ret, active_threads = 0;
+
+	if (!pb->nr_threads)
+		pb->nr_threads = git_online_cpus();
+
+	if (pb->nr_threads <= 1) {
+		find_deltas(pb, list, &list_size, window, depth);
+		return 0;
+	}
+
+	p = git__mallocarray(pb->nr_threads, sizeof(*p));
+	GITERR_CHECK_ALLOC(p);
+
+	/* Partition the work among the threads */
+	for (i = 0; i < pb->nr_threads; ++i) {
+		unsigned sub_size = list_size / (pb->nr_threads - i);
+
+		/* don't use too small segments or no deltas will be found */
+		if (sub_size < 2*window && i+1 < pb->nr_threads)
+			sub_size = 0;
+
+		p[i].pb = pb;
+		p[i].window = window;
+		p[i].depth = depth;
+		p[i].working = 1;
+		p[i].data_ready = 0;
+
+		/* try to split chunks on "path" boundaries */
+		while (sub_size && sub_size < list_size &&
+		       list[sub_size]->hash &&
+		       list[sub_size]->hash == list[sub_size-1]->hash)
+			sub_size++;
+
+		p[i].list = list;
+		p[i].list_size = sub_size;
+		p[i].remaining = sub_size;
+
+		list += sub_size;
+		list_size -= sub_size;
+	}
+
+	/* Start work threads */
+	for (i = 0; i < pb->nr_threads; ++i) {
+		if (!p[i].list_size)
+			continue;
+
+		git_mutex_init(&p[i].mutex);
+		git_cond_init(&p[i].cond);
+
+		ret = git_thread_create(&p[i].thread, NULL,
+					threaded_find_deltas, &p[i]);
+		if (ret) {
+			giterr_set(GITERR_THREAD, "unable to create thread");
+			return -1;
+		}
+		active_threads++;
+	}
+
+	/*
+	 * Now let's wait for work completion.  Each time a thread is done
+	 * with its work, we steal half of the remaining work from the
+	 * thread with the largest number of unprocessed objects and give
+	 * it to that newly idle thread.  This ensure good load balancing
+	 * until the remaining object list segments are simply too short
+	 * to be worth splitting anymore.
+	 */
+	while (active_threads) {
+		struct thread_params *target = NULL;
+		struct thread_params *victim = NULL;
+		unsigned sub_size = 0;
+
+		/* Start by locating a thread that has transitioned its
+		 * 'working' flag from 1 -> 0. This indicates that it is
+		 * ready to receive more work using our work-stealing
+		 * algorithm. */
+		git_packbuilder__progress_lock(pb);
+		for (;;) {
+			for (i = 0; !target && i < pb->nr_threads; i++)
+				if (!p[i].working)
+					target = &p[i];
+			if (target)
+				break;
+			git_cond_wait(&pb->progress_cond, &pb->progress_mutex);
+		}
+
+		/* At this point we hold the progress lock and have located
+		 * a thread to receive more work. We still need to locate a
+		 * thread from which to steal work (the victim). */
+		for (i = 0; i < pb->nr_threads; i++)
+			if (p[i].remaining > 2*window &&
+			    (!victim || victim->remaining < p[i].remaining))
+				victim = &p[i];
+
+		if (victim) {
+			sub_size = victim->remaining / 2;
+			list = victim->list + victim->list_size - sub_size;
+			while (sub_size && list[0]->hash &&
+			       list[0]->hash == list[-1]->hash) {
+				list++;
+				sub_size--;
+			}
+			if (!sub_size) {
+				/*
+				 * It is possible for some "paths" to have
+				 * so many objects that no hash boundary
+				 * might be found.  Let's just steal the
+				 * exact half in that case.
+				 */
+				sub_size = victim->remaining / 2;
+				list -= sub_size;
+			}
+			target->list = list;
+			victim->list_size -= sub_size;
+			victim->remaining -= sub_size;
+		}
+		target->list_size = sub_size;
+		target->remaining = sub_size;
+		target->working = 1;
+		git_packbuilder__progress_unlock(pb);
+
+		if (git_mutex_lock(&target->mutex)) {
+			giterr_set(GITERR_THREAD, "unable to lock packfile condition mutex");
+			git__free(p);
+			return -1;
+		}
+
+		target->data_ready = 1;
+		git_cond_signal(&target->cond);
+		git_mutex_unlock(&target->mutex);
+
+		if (!sub_size) {
+			git_thread_join(&target->thread, NULL);
+			git_cond_free(&target->cond);
+			git_mutex_free(&target->mutex);
+			active_threads--;
+		}
+	}
+
+	git__free(p);
+	return 0;
+}
+
+#else
+#define ll_find_deltas(pb, l, ls, w, d) find_deltas(pb, l, &ls, w, d)
+#endif
+
+static int prepare_pack(git_packbuilder *pb)
+{
+	git_pobject **delta_list;
+	unsigned int i, n = 0;
+
+	if (pb->nr_objects == 0 || pb->done)
+		return 0; /* nothing to do */
+
+	/*
+	 * Although we do not report progress during deltafication, we
+	 * at least report that we are in the deltafication stage
+	 */
+	if (pb->progress_cb)
+			pb->progress_cb(GIT_PACKBUILDER_DELTAFICATION, 0, pb->nr_objects, pb->progress_cb_payload);
+
+	delta_list = git__mallocarray(pb->nr_objects, sizeof(*delta_list));
+	GITERR_CHECK_ALLOC(delta_list);
+
+	for (i = 0; i < pb->nr_objects; ++i) {
+		git_pobject *po = pb->object_list + i;
+
+		/* Make sure the item is within our size limits */
+		if (po->size < 50 || po->size > pb->big_file_threshold)
+			continue;
+
+		delta_list[n++] = po;
+	}
+
+	if (n > 1) {
+		git__tsort((void **)delta_list, n, type_size_sort);
+		if (ll_find_deltas(pb, delta_list, n,
+				   GIT_PACK_WINDOW + 1,
+				   GIT_PACK_DEPTH) < 0) {
+			git__free(delta_list);
+			return -1;
+		}
+	}
+
+	report_delta_progress(pb, pb->nr_objects, true);
+
+	pb->done = true;
+	git__free(delta_list);
+	return 0;
+}
+
+#define PREPARE_PACK if (prepare_pack(pb) < 0) { return -1; }
+
+int git_packbuilder_foreach(git_packbuilder *pb, int (*cb)(void *buf, size_t size, void *payload), void *payload)
+{
+	PREPARE_PACK;
+	return write_pack(pb, cb, payload);
+}
+
+int git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb)
+{
+	PREPARE_PACK;
+	git_buf_sanitize(buf);
+	return write_pack(pb, &write_pack_buf, buf);
+}
+
+static int write_cb(void *buf, size_t len, void *payload)
+{
+	struct pack_write_context *ctx = payload;
+	return git_indexer_append(ctx->indexer, buf, len, ctx->stats);
+}
+
+int git_packbuilder_write(
+	git_packbuilder *pb,
+	const char *path,
+	unsigned int mode,
+	git_transfer_progress_cb progress_cb,
+	void *progress_cb_payload)
+{
+	git_indexer *indexer;
+	git_transfer_progress stats;
+	struct pack_write_context ctx;
+
+	PREPARE_PACK;
+
+	if (git_indexer_new(
+		&indexer, path, mode, pb->odb, progress_cb, progress_cb_payload) < 0)
+		return -1;
+
+	ctx.indexer = indexer;
+	ctx.stats = &stats;
+
+	if (git_packbuilder_foreach(pb, write_cb, &ctx) < 0 ||
+		git_indexer_commit(indexer, &stats) < 0) {
+		git_indexer_free(indexer);
+		return -1;
+	}
+
+	git_oid_cpy(&pb->pack_oid, git_indexer_hash(indexer));
+
+	git_indexer_free(indexer);
+	return 0;
+}
+
+#undef PREPARE_PACK
+
+const git_oid *git_packbuilder_hash(git_packbuilder *pb)
+{
+	return &pb->pack_oid;
+}
+
+
+static int cb_tree_walk(
+	const char *root, const git_tree_entry *entry, void *payload)
+{
+	int error;
+	struct tree_walk_context *ctx = payload;
+
+	/* A commit inside a tree represents a submodule commit and should be skipped. */
+	if (git_tree_entry_type(entry) == GIT_OBJ_COMMIT)
+		return 0;
+
+	if (!(error = git_buf_sets(&ctx->buf, root)) &&
+		!(error = git_buf_puts(&ctx->buf, git_tree_entry_name(entry))))
+		error = git_packbuilder_insert(
+			ctx->pb, git_tree_entry_id(entry), git_buf_cstr(&ctx->buf));
+
+	return error;
+}
+
+int git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid *oid)
+{
+	git_commit *commit;
+
+	if (git_commit_lookup(&commit, pb->repo, oid) < 0 ||
+		git_packbuilder_insert(pb, oid, NULL) < 0)
+		return -1;
+
+	if (git_packbuilder_insert_tree(pb, git_commit_tree_id(commit)) < 0)
+		return -1;
+
+	git_commit_free(commit);
+	return 0;
+}
+
+int git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid *oid)
+{
+	int error;
+	git_tree *tree = NULL;
+	struct tree_walk_context context = { pb, GIT_BUF_INIT };
+
+	if (!(error = git_tree_lookup(&tree, pb->repo, oid)) &&
+	    !(error = git_packbuilder_insert(pb, oid, NULL)))
+		error = git_tree_walk(tree, GIT_TREEWALK_PRE, cb_tree_walk, &context);
+
+	git_tree_free(tree);
+	git_buf_free(&context.buf);
+	return error;
+}
+
+int git_packbuilder_insert_recur(git_packbuilder *pb, const git_oid *id, const char *name)
+{
+	git_object *obj;
+	int error;
+
+	assert(pb && id);
+
+	if ((error = git_object_lookup(&obj, pb->repo, id, GIT_OBJ_ANY)) < 0)
+		return error;
+
+	switch (git_object_type(obj)) {
+	case GIT_OBJ_BLOB:
+		error = git_packbuilder_insert(pb, id, name);
+		break;
+	case GIT_OBJ_TREE:
+		error = git_packbuilder_insert_tree(pb, id);
+		break;
+	case GIT_OBJ_COMMIT:
+		error = git_packbuilder_insert_commit(pb, id);
+		break;
+	case GIT_OBJ_TAG:
+		if ((error = git_packbuilder_insert(pb, id, name)) < 0)
+			goto cleanup;
+		error = git_packbuilder_insert_recur(pb, git_tag_target_id((git_tag *) obj), NULL);
+		break;
+
+	default:
+		giterr_set(GITERR_INVALID, "unknown object type");
+		error = -1;
+	}
+
+cleanup:
+	git_object_free(obj);
+	return error;
+}
+
+uint32_t git_packbuilder_object_count(git_packbuilder *pb)
+{
+	return pb->nr_objects;
+}
+
+uint32_t git_packbuilder_written(git_packbuilder *pb)
+{
+	return pb->nr_written;
+}
+
+int lookup_walk_object(git_walk_object **out, git_packbuilder *pb, const git_oid *id)
+{
+	git_walk_object *obj;
+
+	obj = git_pool_mallocz(&pb->object_pool, 1);
+	if (!obj) {
+		giterr_set_oom();
+		return -1;
+	}
+
+	git_oid_cpy(&obj->id, id);
+
+	*out = obj;
+	return 0;
+}
+
+static int retrieve_object(git_walk_object **out, git_packbuilder *pb, const git_oid *id)
+{
+	int error;
+	khiter_t pos;
+	git_walk_object *obj;
+
+	pos = git_oidmap_lookup_index(pb->walk_objects, id);
+	if (git_oidmap_valid_index(pb->walk_objects, pos)) {
+		obj = git_oidmap_value_at(pb->walk_objects, pos);
+	} else {
+		if ((error = lookup_walk_object(&obj, pb, id)) < 0)
+			return error;
+
+		git_oidmap_insert(pb->walk_objects, &obj->id, obj, error);
+	}
+
+	*out = obj;
+	return 0;
+}
+
+static int mark_blob_uninteresting(git_packbuilder *pb, const git_oid *id)
+{
+	int error;
+	git_walk_object *obj;
+
+	if ((error = retrieve_object(&obj, pb, id)) < 0)
+		return error;
+
+	obj->uninteresting = 1;
+
+	return 0;
+}
+
+static int mark_tree_uninteresting(git_packbuilder *pb, const git_oid *id)
+{
+	git_walk_object *obj;
+	git_tree *tree;
+	int error;
+	size_t i;
+
+	if ((error = retrieve_object(&obj, pb, id)) < 0)
+		return error;
+
+	if (obj->uninteresting)
+		return 0;
+
+	obj->uninteresting = 1;
+
+	if ((error = git_tree_lookup(&tree, pb->repo, id)) < 0)
+		return error;
+
+	for (i = 0; i < git_tree_entrycount(tree); i++) {
+		const git_tree_entry *entry = git_tree_entry_byindex(tree, i);
+		const git_oid *entry_id = git_tree_entry_id(entry);
+		switch (git_tree_entry_type(entry)) {
+		case GIT_OBJ_TREE:
+			if ((error = mark_tree_uninteresting(pb, entry_id)) < 0)
+				goto cleanup;
+			break;
+		case GIT_OBJ_BLOB:
+			if ((error = mark_blob_uninteresting(pb, entry_id)) < 0)
+				goto cleanup;
+			break;
+		default:
+			/* it's a submodule or something unknown, we don't want it */
+			;
+		}
+	}
+
+cleanup:
+	git_tree_free(tree);
+	return error;
+}
+
+/*
+ * Mark the edges of the graph uninteresting. Since we start from a
+ * git_revwalk, the commits are already uninteresting, but we need to
+ * mark the trees and blobs.
+ */
+static int mark_edges_uninteresting(git_packbuilder *pb, git_commit_list *commits)
+{
+	int error;
+	git_commit_list *list;
+	git_commit *commit;
+
+	for (list = commits; list; list = list->next) {
+		if (!list->item->uninteresting)
+			continue;
+
+		if ((error = git_commit_lookup(&commit, pb->repo, &list->item->oid)) < 0)
+			return error;
+
+		error = mark_tree_uninteresting(pb, git_commit_tree_id(commit));
+		git_commit_free(commit);
+
+		if (error < 0)
+			return error;
+	}
+
+	return 0;
+}
+
+int insert_tree(git_packbuilder *pb, git_tree *tree)
+{
+	size_t i;
+	int error;
+	git_tree *subtree;
+	git_walk_object *obj;
+	const char *name;
+
+	if ((error = retrieve_object(&obj, pb, git_tree_id(tree))) < 0)
+		return error;
+
+	if (obj->seen)
+		return 0;
+
+	obj->seen = 1;
+
+	if ((error = git_packbuilder_insert(pb, &obj->id, NULL)))
+		return error;
+
+	for (i = 0; i < git_tree_entrycount(tree); i++) {
+		const git_tree_entry *entry = git_tree_entry_byindex(tree, i);
+		const git_oid *entry_id = git_tree_entry_id(entry);
+		switch (git_tree_entry_type(entry)) {
+		case GIT_OBJ_TREE:
+			if ((error = git_tree_lookup(&subtree, pb->repo, entry_id)) < 0)
+				return error;
+
+			error = insert_tree(pb, subtree);
+			git_tree_free(subtree);
+
+			if (error < 0)
+				return error;
+
+			break;
+		case GIT_OBJ_BLOB:
+			name = git_tree_entry_name(entry);
+			if ((error = git_packbuilder_insert(pb, entry_id, name)) < 0)
+				return error;
+			break;
+		default:
+			/* it's a submodule or something unknown, we don't want it */
+			;
+		}
+	}
+
+
+	return error;
+}
+
+int insert_commit(git_packbuilder *pb, git_walk_object *obj)
+{
+	int error;
+	git_commit *commit = NULL;
+	git_tree *tree = NULL;
+
+	obj->seen = 1;
+
+	if ((error = git_packbuilder_insert(pb, &obj->id, NULL)) < 0)
+		return error;
+
+	if ((error = git_commit_lookup(&commit, pb->repo, &obj->id)) < 0)
+		return error;
+
+	if ((error = git_tree_lookup(&tree, pb->repo, git_commit_tree_id(commit))) < 0)
+		goto cleanup;
+
+	if ((error = insert_tree(pb, tree)) < 0)
+		goto cleanup;
+
+cleanup:
+	git_commit_free(commit);
+	git_tree_free(tree);
+	return error;
+}
+
+int git_packbuilder_insert_walk(git_packbuilder *pb, git_revwalk *walk)
+{
+	int error;
+	git_oid id;
+	git_walk_object *obj;
+
+	assert(pb && walk);
+
+	if ((error = mark_edges_uninteresting(pb, walk->user_input)) < 0)
+		return error;
+
+	/*
+	 * TODO: git marks the parents of the edges
+	 * uninteresting. This may provide a speed advantage, but does
+	 * seem to assume the remote does not have a single-commit
+	 * history on the other end.
+	 */
+
+	/* walk down each tree up to the blobs and insert them, stopping when uninteresting */
+	while ((error = git_revwalk_next(&id, walk)) == 0) {
+		if ((error = retrieve_object(&obj, pb, &id)) < 0)
+			return error;
+
+		if (obj->seen || obj->uninteresting)
+			continue;
+
+		if ((error = insert_commit(pb, obj)) < 0)
+			return error;
+	}
+
+	if (error == GIT_ITEROVER)
+		error = 0;
+
+	return 0;
+}
+
+int git_packbuilder_set_callbacks(git_packbuilder *pb, git_packbuilder_progress progress_cb, void *progress_cb_payload)
+{
+	if (!pb)
+		return -1;
+
+	pb->progress_cb = progress_cb;
+	pb->progress_cb_payload = progress_cb_payload;
+
+	return 0;
+}
+
+void git_packbuilder_free(git_packbuilder *pb)
+{
+	if (pb == NULL)
+		return;
+
+#ifdef GIT_THREADS
+
+	git_mutex_free(&pb->cache_mutex);
+	git_mutex_free(&pb->progress_mutex);
+	git_cond_free(&pb->progress_cond);
+
+#endif
+
+	if (pb->odb)
+		git_odb_free(pb->odb);
+
+	if (pb->object_ix)
+		git_oidmap_free(pb->object_ix);
+
+	if (pb->object_list)
+		git__free(pb->object_list);
+
+	git_oidmap_free(pb->walk_objects);
+	git_pool_clear(&pb->object_pool);
+
+	git_hash_ctx_cleanup(&pb->ctx);
+	git_zstream_free(&pb->zstream);
+
+	git__free(pb);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pack-objects.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pack-objects.h
new file mode 100755
index 0000000..82dea81
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pack-objects.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_pack_objects_h__
+#define INCLUDE_pack_objects_h__
+
+#include "common.h"
+
+#include "buffer.h"
+#include "hash.h"
+#include "oidmap.h"
+#include "netops.h"
+#include "zstream.h"
+#include "pool.h"
+
+#include "git2/oid.h"
+#include "git2/pack.h"
+
+#define GIT_PACK_WINDOW 10 /* number of objects to possibly delta against */
+#define GIT_PACK_DEPTH 50 /* max delta depth */
+#define GIT_PACK_DELTA_CACHE_SIZE (256 * 1024 * 1024)
+#define GIT_PACK_DELTA_CACHE_LIMIT 1000
+#define GIT_PACK_BIG_FILE_THRESHOLD (512 * 1024 * 1024)
+
+typedef struct git_pobject {
+	git_oid id;
+	git_otype type;
+	git_off_t offset;
+
+	size_t size;
+
+	unsigned int hash; /* name hint hash */
+
+	struct git_pobject *delta; /* delta base object */
+	struct git_pobject *delta_child; /* deltified objects who bases me */
+	struct git_pobject *delta_sibling; /* other deltified objects
+					    * who uses the same base as
+					    * me */
+
+	void *delta_data;
+	unsigned long delta_size;
+	unsigned long z_delta_size;
+
+	int written:1,
+	    recursing:1,
+	    tagged:1,
+	    filled:1;
+} git_pobject;
+
+typedef struct {
+	git_oid id;
+	unsigned int uninteresting:1,
+		seen:1;
+} git_walk_object;
+
+struct git_packbuilder {
+	git_repository *repo; /* associated repository */
+	git_odb *odb; /* associated object database */
+
+	git_hash_ctx ctx;
+	git_zstream zstream;
+
+	uint32_t nr_objects,
+		 nr_deltified,
+		 nr_alloc,
+		 nr_written,
+		 nr_remaining;
+
+	git_pobject *object_list;
+
+	git_oidmap *object_ix;
+
+	git_oidmap *walk_objects;
+	git_pool object_pool;
+
+	git_oid pack_oid; /* hash of written pack */
+
+	/* synchronization objects */
+	git_mutex cache_mutex;
+	git_mutex progress_mutex;
+	git_cond progress_cond;
+
+	/* configs */
+	uint64_t delta_cache_size;
+	uint64_t max_delta_cache_size;
+	uint64_t cache_max_small_delta_size;
+	uint64_t big_file_threshold;
+	uint64_t window_memory_limit;
+
+	int nr_threads; /* nr of threads to use */
+
+	git_packbuilder_progress progress_cb;
+	void *progress_cb_payload;
+	double last_progress_report_time; /* the time progress was last reported */
+
+	bool done;
+};
+
+int git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb);
+
+#endif /* INCLUDE_pack_objects_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pack.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pack.c
new file mode 100755
index 0000000..45dd4d5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pack.c
@@ -0,0 +1,1389 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "odb.h"
+#include "pack.h"
+#include "delta-apply.h"
+#include "sha1_lookup.h"
+#include "mwindow.h"
+#include "fileops.h"
+#include "oid.h"
+
+#include <zlib.h>
+
+GIT__USE_OFFMAP
+GIT__USE_OIDMAP
+
+static int packfile_open(struct git_pack_file *p);
+static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n);
+int packfile_unpack_compressed(
+		git_rawobj *obj,
+		struct git_pack_file *p,
+		git_mwindow **w_curs,
+		git_off_t *curpos,
+		size_t size,
+		git_otype type);
+
+/* Can find the offset of an object given
+ * a prefix of an identifier.
+ * Throws GIT_EAMBIGUOUSOIDPREFIX if short oid
+ * is ambiguous within the pack.
+ * This method assumes that len is between
+ * GIT_OID_MINPREFIXLEN and GIT_OID_HEXSZ.
+ */
+static int pack_entry_find_offset(
+		git_off_t *offset_out,
+		git_oid *found_oid,
+		struct git_pack_file *p,
+		const git_oid *short_oid,
+		size_t len);
+
+static int packfile_error(const char *message)
+{
+	giterr_set(GITERR_ODB, "Invalid pack file - %s", message);
+	return -1;
+}
+
+/********************
+ * Delta base cache
+ ********************/
+
+static git_pack_cache_entry *new_cache_object(git_rawobj *source)
+{
+	git_pack_cache_entry *e = git__calloc(1, sizeof(git_pack_cache_entry));
+	if (!e)
+		return NULL;
+
+	git_atomic_inc(&e->refcount);
+	memcpy(&e->raw, source, sizeof(git_rawobj));
+
+	return e;
+}
+
+static void free_cache_object(void *o)
+{
+	git_pack_cache_entry *e = (git_pack_cache_entry *)o;
+
+	if (e != NULL) {
+		assert(e->refcount.val == 0);
+		git__free(e->raw.data);
+		git__free(e);
+	}
+}
+
+static void cache_free(git_pack_cache *cache)
+{
+	khiter_t k;
+
+	if (cache->entries) {
+		for (k = kh_begin(cache->entries); k != kh_end(cache->entries); k++) {
+			if (kh_exist(cache->entries, k))
+				free_cache_object(kh_value(cache->entries, k));
+		}
+
+		git_offmap_free(cache->entries);
+		cache->entries = NULL;
+	}
+}
+
+static int cache_init(git_pack_cache *cache)
+{
+	cache->entries = git_offmap_alloc();
+	GITERR_CHECK_ALLOC(cache->entries);
+
+	cache->memory_limit = GIT_PACK_CACHE_MEMORY_LIMIT;
+
+	if (git_mutex_init(&cache->lock)) {
+		giterr_set(GITERR_OS, "Failed to initialize pack cache mutex");
+
+		git__free(cache->entries);
+		cache->entries = NULL;
+
+		return -1;
+	}
+
+	return 0;
+}
+
+static git_pack_cache_entry *cache_get(git_pack_cache *cache, git_off_t offset)
+{
+	khiter_t k;
+	git_pack_cache_entry *entry = NULL;
+
+	if (git_mutex_lock(&cache->lock) < 0)
+		return NULL;
+
+	k = kh_get(off, cache->entries, offset);
+	if (k != kh_end(cache->entries)) { /* found it */
+		entry = kh_value(cache->entries, k);
+		git_atomic_inc(&entry->refcount);
+		entry->last_usage = cache->use_ctr++;
+	}
+	git_mutex_unlock(&cache->lock);
+
+	return entry;
+}
+
+/* Run with the cache lock held */
+static void free_lowest_entry(git_pack_cache *cache)
+{
+	git_pack_cache_entry *entry;
+	khiter_t k;
+
+	for (k = kh_begin(cache->entries); k != kh_end(cache->entries); k++) {
+		if (!kh_exist(cache->entries, k))
+			continue;
+
+		entry = kh_value(cache->entries, k);
+
+		if (entry && entry->refcount.val == 0) {
+			cache->memory_used -= entry->raw.len;
+			kh_del(off, cache->entries, k);
+			free_cache_object(entry);
+		}
+	}
+}
+
+static int cache_add(
+		git_pack_cache_entry **cached_out,
+		git_pack_cache *cache,
+		git_rawobj *base,
+		git_off_t offset)
+{
+	git_pack_cache_entry *entry;
+	int error, exists = 0;
+	khiter_t k;
+
+	if (base->len > GIT_PACK_CACHE_SIZE_LIMIT)
+		return -1;
+
+	entry = new_cache_object(base);
+	if (entry) {
+		if (git_mutex_lock(&cache->lock) < 0) {
+			giterr_set(GITERR_OS, "failed to lock cache");
+			git__free(entry);
+			return -1;
+		}
+		/* Add it to the cache if nobody else has */
+		exists = kh_get(off, cache->entries, offset) != kh_end(cache->entries);
+		if (!exists) {
+			while (cache->memory_used + base->len > cache->memory_limit)
+				free_lowest_entry(cache);
+
+			k = kh_put(off, cache->entries, offset, &error);
+			assert(error != 0);
+			kh_value(cache->entries, k) = entry;
+			cache->memory_used += entry->raw.len;
+
+			*cached_out = entry;
+		}
+		git_mutex_unlock(&cache->lock);
+		/* Somebody beat us to adding it into the cache */
+		if (exists) {
+			git__free(entry);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/***********************************************************
+ *
+ * PACK INDEX METHODS
+ *
+ ***********************************************************/
+
+static void pack_index_free(struct git_pack_file *p)
+{
+	if (p->oids) {
+		git__free(p->oids);
+		p->oids = NULL;
+	}
+	if (p->index_map.data) {
+		git_futils_mmap_free(&p->index_map);
+		p->index_map.data = NULL;
+	}
+}
+
+static int pack_index_check(const char *path, struct git_pack_file *p)
+{
+	struct git_pack_idx_header *hdr;
+	uint32_t version, nr, i, *index;
+	void *idx_map;
+	size_t idx_size;
+	struct stat st;
+	int error;
+	/* TODO: properly open the file without access time using O_NOATIME */
+	git_file fd = git_futils_open_ro(path);
+	if (fd < 0)
+		return fd;
+
+	if (p_fstat(fd, &st) < 0) {
+		p_close(fd);
+		giterr_set(GITERR_OS, "Unable to stat pack index '%s'", path);
+		return -1;
+	}
+
+	if (!S_ISREG(st.st_mode) ||
+		!git__is_sizet(st.st_size) ||
+		(idx_size = (size_t)st.st_size) < 4 * 256 + 20 + 20)
+	{
+		p_close(fd);
+		giterr_set(GITERR_ODB, "Invalid pack index '%s'", path);
+		return -1;
+	}
+
+	error = git_futils_mmap_ro(&p->index_map, fd, 0, idx_size);
+
+	p_close(fd);
+
+	if (error < 0)
+		return error;
+
+	hdr = idx_map = p->index_map.data;
+
+	if (hdr->idx_signature == htonl(PACK_IDX_SIGNATURE)) {
+		version = ntohl(hdr->idx_version);
+
+		if (version < 2 || version > 2) {
+			git_futils_mmap_free(&p->index_map);
+			return packfile_error("unsupported index version");
+		}
+
+	} else
+		version = 1;
+
+	nr = 0;
+	index = idx_map;
+
+	if (version > 1)
+		index += 2; /* skip index header */
+
+	for (i = 0; i < 256; i++) {
+		uint32_t n = ntohl(index[i]);
+		if (n < nr) {
+			git_futils_mmap_free(&p->index_map);
+			return packfile_error("index is non-monotonic");
+		}
+		nr = n;
+	}
+
+	if (version == 1) {
+		/*
+		 * Total size:
+		 * - 256 index entries 4 bytes each
+		 * - 24-byte entries * nr (20-byte sha1 + 4-byte offset)
+		 * - 20-byte SHA1 of the packfile
+		 * - 20-byte SHA1 file checksum
+		 */
+		if (idx_size != 4*256 + nr * 24 + 20 + 20) {
+			git_futils_mmap_free(&p->index_map);
+			return packfile_error("index is corrupted");
+		}
+	} else if (version == 2) {
+		/*
+		 * Minimum size:
+		 * - 8 bytes of header
+		 * - 256 index entries 4 bytes each
+		 * - 20-byte sha1 entry * nr
+		 * - 4-byte crc entry * nr
+		 * - 4-byte offset entry * nr
+		 * - 20-byte SHA1 of the packfile
+		 * - 20-byte SHA1 file checksum
+		 * And after the 4-byte offset table might be a
+		 * variable sized table containing 8-byte entries
+		 * for offsets larger than 2^31.
+		 */
+		unsigned long min_size = 8 + 4*256 + nr*(20 + 4 + 4) + 20 + 20;
+		unsigned long max_size = min_size;
+
+		if (nr)
+			max_size += (nr - 1)*8;
+
+		if (idx_size < min_size || idx_size > max_size) {
+			git_futils_mmap_free(&p->index_map);
+			return packfile_error("wrong index size");
+		}
+	}
+
+	p->num_objects = nr;
+	p->index_version = version;
+	return 0;
+}
+
+static int pack_index_open(struct git_pack_file *p)
+{
+	int error = 0;
+	size_t name_len;
+	git_buf idx_name = GIT_BUF_INIT;
+
+	if (p->index_version > -1)
+		return 0;
+
+	name_len = strlen(p->pack_name);
+	assert(name_len > strlen(".pack")); /* checked by git_pack_file alloc */
+
+	git_buf_grow(&idx_name, name_len);
+	git_buf_put(&idx_name, p->pack_name, name_len - strlen(".pack"));
+	git_buf_puts(&idx_name, ".idx");
+	if (git_buf_oom(&idx_name)) {
+		giterr_set_oom();
+		return -1;
+	}
+
+	if ((error = git_mutex_lock(&p->lock)) < 0) {
+		git_buf_free(&idx_name);
+		return error;
+	}
+
+	if (p->index_version == -1)
+		error = pack_index_check(idx_name.ptr, p);
+
+	git_buf_free(&idx_name);
+
+	git_mutex_unlock(&p->lock);
+
+	return error;
+}
+
+static unsigned char *pack_window_open(
+		struct git_pack_file *p,
+		git_mwindow **w_cursor,
+		git_off_t offset,
+		unsigned int *left)
+{
+	if (p->mwf.fd == -1 && packfile_open(p) < 0)
+		return NULL;
+
+	/* Since packfiles end in a hash of their content and it's
+	 * pointless to ask for an offset into the middle of that
+	 * hash, and the pack_window_contains function above wouldn't match
+	 * don't allow an offset too close to the end of the file.
+	 */
+	if (offset > (p->mwf.size - 20))
+		return NULL;
+
+	return git_mwindow_open(&p->mwf, w_cursor, offset, 20, left);
+ }
+
+/*
+ * The per-object header is a pretty dense thing, which is
+ *  - first byte: low four bits are "size",
+ *    then three bits of "type",
+ *    with the high bit being "size continues".
+ *  - each byte afterwards: low seven bits are size continuation,
+ *    with the high bit being "size continues"
+ */
+size_t git_packfile__object_header(unsigned char *hdr, size_t size, git_otype type)
+{
+	unsigned char *hdr_base;
+	unsigned char c;
+
+	assert(type >= GIT_OBJ_COMMIT && type <= GIT_OBJ_REF_DELTA);
+
+	/* TODO: add support for chunked objects; see git.git 6c0d19b1 */
+
+	c = (unsigned char)((type << 4) | (size & 15));
+	size >>= 4;
+	hdr_base = hdr;
+
+	while (size) {
+		*hdr++ = c | 0x80;
+		c = size & 0x7f;
+		size >>= 7;
+	}
+	*hdr++ = c;
+
+	return (hdr - hdr_base);
+}
+
+
+static int packfile_unpack_header1(
+		unsigned long *usedp,
+		size_t *sizep,
+		git_otype *type,
+		const unsigned char *buf,
+		unsigned long len)
+{
+	unsigned shift;
+	unsigned long size, c;
+	unsigned long used = 0;
+
+	c = buf[used++];
+	*type = (c >> 4) & 7;
+	size = c & 15;
+	shift = 4;
+	while (c & 0x80) {
+		if (len <= used) {
+			giterr_set(GITERR_ODB, "buffer too small");
+			return GIT_EBUFS;
+		}
+
+		if (bitsizeof(long) <= shift) {
+			*usedp = 0;
+			giterr_set(GITERR_ODB, "packfile corrupted");
+			return -1;
+		}
+
+		c = buf[used++];
+		size += (c & 0x7f) << shift;
+		shift += 7;
+	}
+
+	*sizep = (size_t)size;
+	*usedp = used;
+	return 0;
+}
+
+int git_packfile_unpack_header(
+		size_t *size_p,
+		git_otype *type_p,
+		git_mwindow_file *mwf,
+		git_mwindow **w_curs,
+		git_off_t *curpos)
+{
+	unsigned char *base;
+	unsigned int left;
+	unsigned long used;
+	int ret;
+
+	/* pack_window_open() assures us we have [base, base + 20) available
+	 * as a range that we can look at at. (Its actually the hash
+	 * size that is assured.) With our object header encoding
+	 * the maximum deflated object size is 2^137, which is just
+	 * insane, so we know won't exceed what we have been given.
+	 */
+/*	base = pack_window_open(p, w_curs, *curpos, &left); */
+	base = git_mwindow_open(mwf, w_curs, *curpos, 20, &left);
+	if (base == NULL)
+		return GIT_EBUFS;
+
+	ret = packfile_unpack_header1(&used, size_p, type_p, base, left);
+	git_mwindow_close(w_curs);
+	if (ret == GIT_EBUFS)
+		return ret;
+	else if (ret < 0)
+		return packfile_error("header length is zero");
+
+	*curpos += used;
+	return 0;
+}
+
+int git_packfile_resolve_header(
+		size_t *size_p,
+		git_otype *type_p,
+		struct git_pack_file *p,
+		git_off_t offset)
+{
+	git_mwindow *w_curs = NULL;
+	git_off_t curpos = offset;
+	size_t size;
+	git_otype type;
+	git_off_t base_offset;
+	int error;
+
+	error = git_packfile_unpack_header(&size, &type, &p->mwf, &w_curs, &curpos);
+	git_mwindow_close(&w_curs);
+	if (error < 0)
+		return error;
+
+	if (type == GIT_OBJ_OFS_DELTA || type == GIT_OBJ_REF_DELTA) {
+		size_t base_size;
+		git_rawobj delta;
+		base_offset = get_delta_base(p, &w_curs, &curpos, type, offset);
+		git_mwindow_close(&w_curs);
+		error = packfile_unpack_compressed(&delta, p, &w_curs, &curpos, size, type);
+		git_mwindow_close(&w_curs);
+		if (error < 0)
+			return error;
+		error = git__delta_read_header(delta.data, delta.len, &base_size, size_p);
+		git__free(delta.data);
+		if (error < 0)
+			return error;
+	} else
+		*size_p = size;
+
+	while (type == GIT_OBJ_OFS_DELTA || type == GIT_OBJ_REF_DELTA) {
+		curpos = base_offset;
+		error = git_packfile_unpack_header(&size, &type, &p->mwf, &w_curs, &curpos);
+		git_mwindow_close(&w_curs);
+		if (error < 0)
+			return error;
+		if (type != GIT_OBJ_OFS_DELTA && type != GIT_OBJ_REF_DELTA)
+			break;
+		base_offset = get_delta_base(p, &w_curs, &curpos, type, base_offset);
+		git_mwindow_close(&w_curs);
+	}
+	*type_p = type;
+
+	return error;
+}
+
+#define SMALL_STACK_SIZE 64
+
+/**
+ * Generate the chain of dependencies which we need to get to the
+ * object at `off`. `chain` is used a stack, popping gives the right
+ * order to apply deltas on. If an object is found in the pack's base
+ * cache, we stop calculating there.
+ */
+static int pack_dependency_chain(git_dependency_chain *chain_out,
+				 git_pack_cache_entry **cached_out, git_off_t *cached_off,
+				 struct pack_chain_elem *small_stack, size_t *stack_sz,
+				 struct git_pack_file *p, git_off_t obj_offset)
+{
+	git_dependency_chain chain = GIT_ARRAY_INIT;
+	git_mwindow *w_curs = NULL;
+	git_off_t curpos = obj_offset, base_offset;
+	int error = 0, use_heap = 0;
+	size_t size, elem_pos;
+	git_otype type;
+
+	elem_pos = 0;
+	while (true) {
+		struct pack_chain_elem *elem;
+		git_pack_cache_entry *cached = NULL;
+
+		/* if we have a base cached, we can stop here instead */
+		if ((cached = cache_get(&p->bases, obj_offset)) != NULL) {
+			*cached_out = cached;
+			*cached_off = obj_offset;
+			break;
+		}
+
+		/* if we run out of space on the small stack, use the array */
+		if (elem_pos == SMALL_STACK_SIZE) {
+			git_array_init_to_size(chain, elem_pos);
+			GITERR_CHECK_ARRAY(chain);
+			memcpy(chain.ptr, small_stack, elem_pos * sizeof(struct pack_chain_elem));
+			chain.size = elem_pos;
+			use_heap = 1;
+		}
+
+		curpos = obj_offset;
+		if (!use_heap) {
+			elem = &small_stack[elem_pos];
+		} else {
+			elem = git_array_alloc(chain);
+			if (!elem) {
+				error = -1;
+				goto on_error;
+			}
+		}
+
+		elem->base_key = obj_offset;
+
+		error = git_packfile_unpack_header(&size, &type, &p->mwf, &w_curs, &curpos);
+		git_mwindow_close(&w_curs);
+
+		if (error < 0)
+			goto on_error;
+
+		elem->offset = curpos;
+		elem->size = size;
+		elem->type = type;
+		elem->base_key = obj_offset;
+
+		if (type != GIT_OBJ_OFS_DELTA && type != GIT_OBJ_REF_DELTA)
+			break;
+
+		base_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset);
+		git_mwindow_close(&w_curs);
+
+		if (base_offset == 0) {
+			error = packfile_error("delta offset is zero");
+			goto on_error;
+		}
+		if (base_offset < 0) { /* must actually be an error code */
+			error = (int)base_offset;
+			goto on_error;
+		}
+
+		/* we need to pass the pos *after* the delta-base bit */
+		elem->offset = curpos;
+
+		/* go through the loop again, but with the new object */
+		obj_offset = base_offset;
+		elem_pos++;
+	}
+
+	
+	*stack_sz = elem_pos + 1;
+	*chain_out = chain;
+	return error;
+
+on_error:
+	git_array_clear(chain);
+	return error;
+}
+
+int git_packfile_unpack(
+	git_rawobj *obj,
+	struct git_pack_file *p,
+	git_off_t *obj_offset)
+{
+	git_mwindow *w_curs = NULL;
+	git_off_t curpos = *obj_offset;
+	int error, free_base = 0;
+	git_dependency_chain chain = GIT_ARRAY_INIT;
+	struct pack_chain_elem *elem = NULL, *stack;
+	git_pack_cache_entry *cached = NULL;
+	struct pack_chain_elem small_stack[SMALL_STACK_SIZE];
+	size_t stack_size = 0, elem_pos, alloclen;
+	git_otype base_type;
+
+	/*
+	 * TODO: optionally check the CRC on the packfile
+	 */
+
+	error = pack_dependency_chain(&chain, &cached, obj_offset, small_stack, &stack_size, p, *obj_offset);
+	if (error < 0)
+		return error;
+
+	obj->data = NULL;
+	obj->len = 0;
+	obj->type = GIT_OBJ_BAD;
+
+	/* let's point to the right stack */
+	stack = chain.ptr ? chain.ptr : small_stack;
+
+	elem_pos = stack_size;
+	if (cached) {
+		memcpy(obj, &cached->raw, sizeof(git_rawobj));
+		base_type = obj->type;
+		elem_pos--;	/* stack_size includes the base, which isn't actually there */
+	} else {
+		elem = &stack[--elem_pos];
+		base_type = elem->type;
+	}
+
+	switch (base_type) {
+	case GIT_OBJ_COMMIT:
+	case GIT_OBJ_TREE:
+	case GIT_OBJ_BLOB:
+	case GIT_OBJ_TAG:
+		if (!cached) {
+			curpos = elem->offset;
+			error = packfile_unpack_compressed(obj, p, &w_curs, &curpos, elem->size, elem->type);
+			git_mwindow_close(&w_curs);
+			base_type = elem->type;
+		}
+		if (error < 0)
+			goto cleanup;
+		break;
+	case GIT_OBJ_OFS_DELTA:
+	case GIT_OBJ_REF_DELTA:
+		error = packfile_error("dependency chain ends in a delta");
+		goto cleanup;
+	default:
+		error = packfile_error("invalid packfile type in header");
+		goto cleanup;
+	}
+
+	/*
+	 * Finding the object we want a cached base element is
+	 * problematic, as we need to make sure we don't accidentally
+	 * give the caller the cached object, which it would then feel
+	 * free to free, so we need to copy the data.
+	 */
+	if (cached && stack_size == 1) {
+		void *data = obj->data;
+
+		GITERR_CHECK_ALLOC_ADD(&alloclen, obj->len, 1);
+		obj->data = git__malloc(alloclen);
+		GITERR_CHECK_ALLOC(obj->data);
+
+		memcpy(obj->data, data, obj->len + 1);
+		git_atomic_dec(&cached->refcount);
+		goto cleanup;
+	}
+
+	/* we now apply each consecutive delta until we run out */
+	while (elem_pos > 0 && !error) {
+		git_rawobj base, delta;
+
+		/*
+		 * We can now try to add the base to the cache, as
+		 * long as it's not already the cached one.
+		 */
+		if (!cached)
+			free_base = !!cache_add(&cached, &p->bases, obj, elem->base_key);
+
+		elem = &stack[elem_pos - 1];
+		curpos = elem->offset;
+		error = packfile_unpack_compressed(&delta, p, &w_curs, &curpos, elem->size, elem->type);
+		git_mwindow_close(&w_curs);
+
+		if (error < 0)
+			break;
+
+		/* the current object becomes the new base, on which we apply the delta */
+		base = *obj;
+		obj->data = NULL;
+		obj->len = 0;
+		obj->type = GIT_OBJ_BAD;
+
+		error = git__delta_apply(obj, base.data, base.len, delta.data, delta.len);
+		obj->type = base_type;
+		/*
+		 * We usually don't want to free the base at this
+		 * point, as we put it into the cache in the previous
+		 * iteration. free_base lets us know that we got the
+		 * base object directly from the packfile, so we can free it.
+		 */
+		git__free(delta.data);
+		if (free_base) {
+			free_base = 0;
+			git__free(base.data);
+		}
+
+		if (cached) {
+			git_atomic_dec(&cached->refcount);
+			cached = NULL;
+		}
+
+		if (error < 0)
+			break;
+
+		elem_pos--;
+	}
+
+cleanup:
+	if (error < 0)
+		git__free(obj->data);
+
+	if (elem)
+		*obj_offset = curpos;
+
+	git_array_clear(chain);
+	return error;
+}
+
+static void *use_git_alloc(void *opaq, unsigned int count, unsigned int size)
+{
+	GIT_UNUSED(opaq);
+	return git__calloc(count, size);
+}
+
+static void use_git_free(void *opaq, void *ptr)
+{
+	GIT_UNUSED(opaq);
+	git__free(ptr);
+}
+
+int git_packfile_stream_open(git_packfile_stream *obj, struct git_pack_file *p, git_off_t curpos)
+{
+	int st;
+
+	memset(obj, 0, sizeof(git_packfile_stream));
+	obj->curpos = curpos;
+	obj->p = p;
+	obj->zstream.zalloc = use_git_alloc;
+	obj->zstream.zfree = use_git_free;
+	obj->zstream.next_in = Z_NULL;
+	obj->zstream.next_out = Z_NULL;
+	st = inflateInit(&obj->zstream);
+	if (st != Z_OK) {
+		git__free(obj);
+		giterr_set(GITERR_ZLIB, "failed to init packfile stream");
+		return -1;
+	}
+
+	return 0;
+}
+
+ssize_t git_packfile_stream_read(git_packfile_stream *obj, void *buffer, size_t len)
+{
+	unsigned char *in;
+	size_t written;
+	int st;
+
+	if (obj->done)
+		return 0;
+
+	in = pack_window_open(obj->p, &obj->mw, obj->curpos, &obj->zstream.avail_in);
+	if (in == NULL)
+		return GIT_EBUFS;
+
+	obj->zstream.next_out = buffer;
+	obj->zstream.avail_out = (unsigned int)len;
+	obj->zstream.next_in = in;
+
+	st = inflate(&obj->zstream, Z_SYNC_FLUSH);
+	git_mwindow_close(&obj->mw);
+
+	obj->curpos += obj->zstream.next_in - in;
+	written = len - obj->zstream.avail_out;
+
+	if (st != Z_OK && st != Z_STREAM_END) {
+		giterr_set(GITERR_ZLIB, "error reading from the zlib stream");
+		return -1;
+	}
+
+	if (st == Z_STREAM_END)
+		obj->done = 1;
+
+
+	/* If we didn't write anything out but we're not done, we need more data */
+	if (!written && st != Z_STREAM_END)
+		return GIT_EBUFS;
+
+	return written;
+
+}
+
+void git_packfile_stream_free(git_packfile_stream *obj)
+{
+	inflateEnd(&obj->zstream);
+}
+
+int packfile_unpack_compressed(
+	git_rawobj *obj,
+	struct git_pack_file *p,
+	git_mwindow **w_curs,
+	git_off_t *curpos,
+	size_t size,
+	git_otype type)
+{
+	size_t buf_size;
+	int st;
+	z_stream stream;
+	unsigned char *buffer, *in;
+
+	GITERR_CHECK_ALLOC_ADD(&buf_size, size, 1);
+	buffer = git__calloc(1, buf_size);
+	GITERR_CHECK_ALLOC(buffer);
+
+	memset(&stream, 0, sizeof(stream));
+	stream.next_out = buffer;
+	stream.avail_out = (uInt)buf_size;
+	stream.zalloc = use_git_alloc;
+	stream.zfree = use_git_free;
+
+	st = inflateInit(&stream);
+	if (st != Z_OK) {
+		git__free(buffer);
+		giterr_set(GITERR_ZLIB, "failed to init zlib stream on unpack");
+
+		return -1;
+	}
+
+	do {
+		in = pack_window_open(p, w_curs, *curpos, &stream.avail_in);
+		stream.next_in = in;
+		st = inflate(&stream, Z_FINISH);
+		git_mwindow_close(w_curs);
+
+		if (!stream.avail_out)
+			break; /* the payload is larger than it should be */
+
+		if (st == Z_BUF_ERROR && in == NULL) {
+			inflateEnd(&stream);
+			git__free(buffer);
+			return GIT_EBUFS;
+		}
+
+		*curpos += stream.next_in - in;
+	} while (st == Z_OK || st == Z_BUF_ERROR);
+
+	inflateEnd(&stream);
+
+	if ((st != Z_STREAM_END) || stream.total_out != size) {
+		git__free(buffer);
+		giterr_set(GITERR_ZLIB, "error inflating zlib stream");
+		return -1;
+	}
+
+	obj->type = type;
+	obj->len = size;
+	obj->data = buffer;
+	return 0;
+}
+
+/*
+ * curpos is where the data starts, delta_obj_offset is the where the
+ * header starts
+ */
+git_off_t get_delta_base(
+	struct git_pack_file *p,
+	git_mwindow **w_curs,
+	git_off_t *curpos,
+	git_otype type,
+	git_off_t delta_obj_offset)
+{
+	unsigned int left = 0;
+	unsigned char *base_info;
+	git_off_t base_offset;
+	git_oid unused;
+
+	base_info = pack_window_open(p, w_curs, *curpos, &left);
+	/* Assumption: the only reason this would fail is because the file is too small */
+	if (base_info == NULL)
+		return GIT_EBUFS;
+	/* pack_window_open() assured us we have [base_info, base_info + 20)
+	 * as a range that we can look at without walking off the
+	 * end of the mapped window. Its actually the hash size
+	 * that is assured. An OFS_DELTA longer than the hash size
+	 * is stupid, as then a REF_DELTA would be smaller to store.
+	 */
+	if (type == GIT_OBJ_OFS_DELTA) {
+		unsigned used = 0;
+		unsigned char c = base_info[used++];
+		base_offset = c & 127;
+		while (c & 128) {
+			if (left <= used)
+				return GIT_EBUFS;
+			base_offset += 1;
+			if (!base_offset || MSB(base_offset, 7))
+				return 0; /* overflow */
+			c = base_info[used++];
+			base_offset = (base_offset << 7) + (c & 127);
+		}
+		base_offset = delta_obj_offset - base_offset;
+		if (base_offset <= 0 || base_offset >= delta_obj_offset)
+			return 0; /* out of bound */
+		*curpos += used;
+	} else if (type == GIT_OBJ_REF_DELTA) {
+		/* If we have the cooperative cache, search in it first */
+		if (p->has_cache) {
+			khiter_t k;
+			git_oid oid;
+
+			git_oid_fromraw(&oid, base_info);
+			k = kh_get(oid, p->idx_cache, &oid);
+			if (k != kh_end(p->idx_cache)) {
+				*curpos += 20;
+				return ((struct git_pack_entry *)kh_value(p->idx_cache, k))->offset;
+			} else {
+				/* If we're building an index, don't try to find the pack
+				 * entry; we just haven't seen it yet.  We'll make
+				 * progress again in the next loop.
+				 */
+				return GIT_PASSTHROUGH;
+			}
+		}
+
+		/* The base entry _must_ be in the same pack */
+		if (pack_entry_find_offset(&base_offset, &unused, p, (git_oid *)base_info, GIT_OID_HEXSZ) < 0)
+			return packfile_error("base entry delta is not in the same pack");
+		*curpos += 20;
+	} else
+		return 0;
+
+	return base_offset;
+}
+
+/***********************************************************
+ *
+ * PACKFILE METHODS
+ *
+ ***********************************************************/
+
+void git_packfile_free(struct git_pack_file *p)
+{
+	if (!p)
+		return;
+
+	cache_free(&p->bases);
+
+	if (p->mwf.fd >= 0) {
+		git_mwindow_free_all_locked(&p->mwf);
+		p_close(p->mwf.fd);
+	}
+
+	pack_index_free(p);
+
+	git__free(p->bad_object_sha1);
+
+	git_mutex_free(&p->lock);
+	git_mutex_free(&p->bases.lock);
+	git__free(p);
+}
+
+static int packfile_open(struct git_pack_file *p)
+{
+	struct stat st;
+	struct git_pack_header hdr;
+	git_oid sha1;
+	unsigned char *idx_sha1;
+
+	if (p->index_version == -1 && pack_index_open(p) < 0)
+		return git_odb__error_notfound("failed to open packfile", NULL);
+
+	/* if mwf opened by another thread, return now */
+	if (git_mutex_lock(&p->lock) < 0)
+		return packfile_error("failed to get lock for open");
+
+	if (p->mwf.fd >= 0) {
+		git_mutex_unlock(&p->lock);
+		return 0;
+	}
+
+	/* TODO: open with noatime */
+	p->mwf.fd = git_futils_open_ro(p->pack_name);
+	if (p->mwf.fd < 0)
+		goto cleanup;
+
+	if (p_fstat(p->mwf.fd, &st) < 0 ||
+		git_mwindow_file_register(&p->mwf) < 0)
+		goto cleanup;
+
+	/* If we created the struct before we had the pack we lack size. */
+	if (!p->mwf.size) {
+		if (!S_ISREG(st.st_mode))
+			goto cleanup;
+		p->mwf.size = (git_off_t)st.st_size;
+	} else if (p->mwf.size != st.st_size)
+		goto cleanup;
+
+#if 0
+	/* We leave these file descriptors open with sliding mmap;
+	 * there is no point keeping them open across exec(), though.
+	 */
+	fd_flag = fcntl(p->mwf.fd, F_GETFD, 0);
+	if (fd_flag < 0)
+		goto cleanup;
+
+	fd_flag |= FD_CLOEXEC;
+	if (fcntl(p->pack_fd, F_SETFD, fd_flag) == -1)
+		goto cleanup;
+#endif
+
+	/* Verify we recognize this pack file format. */
+	if (p_read(p->mwf.fd, &hdr, sizeof(hdr)) < 0 ||
+		hdr.hdr_signature != htonl(PACK_SIGNATURE) ||
+		!pack_version_ok(hdr.hdr_version))
+		goto cleanup;
+
+	/* Verify the pack matches its index. */
+	if (p->num_objects != ntohl(hdr.hdr_entries) ||
+		p_lseek(p->mwf.fd, p->mwf.size - GIT_OID_RAWSZ, SEEK_SET) == -1 ||
+		p_read(p->mwf.fd, sha1.id, GIT_OID_RAWSZ) < 0)
+		goto cleanup;
+
+	idx_sha1 = ((unsigned char *)p->index_map.data) + p->index_map.len - 40;
+
+	if (git_oid__cmp(&sha1, (git_oid *)idx_sha1) != 0)
+		goto cleanup;
+
+	git_mutex_unlock(&p->lock);
+	return 0;
+
+cleanup:
+	giterr_set(GITERR_OS, "Invalid packfile '%s'", p->pack_name);
+
+	if (p->mwf.fd >= 0)
+		p_close(p->mwf.fd);
+	p->mwf.fd = -1;
+
+	git_mutex_unlock(&p->lock);
+
+	return -1;
+}
+
+int git_packfile__name(char **out, const char *path)
+{
+	size_t path_len;
+	git_buf buf = GIT_BUF_INIT;
+
+	path_len = strlen(path);
+
+	if (path_len < strlen(".idx"))
+		return git_odb__error_notfound("invalid packfile path", NULL);
+
+	if (git_buf_printf(&buf, "%.*s.pack", (int)(path_len - strlen(".idx")), path) < 0)
+		return -1;
+
+	*out = git_buf_detach(&buf);
+	return 0;
+}
+
+int git_packfile_alloc(struct git_pack_file **pack_out, const char *path)
+{
+	struct stat st;
+	struct git_pack_file *p;
+	size_t path_len = path ? strlen(path) : 0, alloc_len;
+
+	*pack_out = NULL;
+
+	if (path_len < strlen(".idx"))
+		return git_odb__error_notfound("invalid packfile path", NULL);
+
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, sizeof(*p), path_len);
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
+
+	p = git__calloc(1, alloc_len);
+	GITERR_CHECK_ALLOC(p);
+
+	memcpy(p->pack_name, path, path_len + 1);
+
+	/*
+	 * Make sure a corresponding .pack file exists and that
+	 * the index looks sane.
+	 */
+	if (git__suffixcmp(path, ".idx") == 0) {
+		size_t root_len = path_len - strlen(".idx");
+
+		memcpy(p->pack_name + root_len, ".keep", sizeof(".keep"));
+		if (git_path_exists(p->pack_name) == true)
+			p->pack_keep = 1;
+
+		memcpy(p->pack_name + root_len, ".pack", sizeof(".pack"));
+	}
+
+	if (p_stat(p->pack_name, &st) < 0 || !S_ISREG(st.st_mode)) {
+		git__free(p);
+		return git_odb__error_notfound("packfile not found", NULL);
+	}
+
+	/* ok, it looks sane as far as we can check without
+	 * actually mapping the pack file.
+	 */
+	p->mwf.fd = -1;
+	p->mwf.size = st.st_size;
+	p->pack_local = 1;
+	p->mtime = (git_time_t)st.st_mtime;
+	p->index_version = -1;
+
+	if (git_mutex_init(&p->lock)) {
+		giterr_set(GITERR_OS, "Failed to initialize packfile mutex");
+		git__free(p);
+		return -1;
+	}
+
+	if (cache_init(&p->bases) < 0) {
+		git__free(p);
+		return -1;
+	}
+
+	*pack_out = p;
+
+	return 0;
+}
+
+/***********************************************************
+ *
+ * PACKFILE ENTRY SEARCH INTERNALS
+ *
+ ***********************************************************/
+
+static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n)
+{
+	const unsigned char *index = p->index_map.data;
+	index += 4 * 256;
+	if (p->index_version == 1) {
+		return ntohl(*((uint32_t *)(index + 24 * n)));
+	} else {
+		uint32_t off;
+		index += 8 + p->num_objects * (20 + 4);
+		off = ntohl(*((uint32_t *)(index + 4 * n)));
+		if (!(off & 0x80000000))
+			return off;
+		index += p->num_objects * 4 + (off & 0x7fffffff) * 8;
+		return (((uint64_t)ntohl(*((uint32_t *)(index + 0)))) << 32) |
+					ntohl(*((uint32_t *)(index + 4)));
+	}
+}
+
+static int git__memcmp4(const void *a, const void *b) {
+	return memcmp(a, b, 4);
+}
+
+int git_pack_foreach_entry(
+	struct git_pack_file *p,
+	git_odb_foreach_cb cb,
+	void *data)
+{
+	const unsigned char *index = p->index_map.data, *current;
+	uint32_t i;
+	int error = 0;
+
+	if (index == NULL) {
+		if ((error = pack_index_open(p)) < 0)
+			return error;
+
+		assert(p->index_map.data);
+
+		index = p->index_map.data;
+	}
+
+	if (p->index_version > 1) {
+		index += 8;
+	}
+
+	index += 4 * 256;
+
+	if (p->oids == NULL) {
+		git_vector offsets, oids;
+
+		if ((error = git_vector_init(&oids, p->num_objects, NULL)))
+			return error;
+
+		if ((error = git_vector_init(&offsets, p->num_objects, git__memcmp4)))
+			return error;
+
+		if (p->index_version > 1) {
+			const unsigned char *off = index + 24 * p->num_objects;
+			for (i = 0; i < p->num_objects; i++)
+				git_vector_insert(&offsets, (void*)&off[4 * i]);
+			git_vector_sort(&offsets);
+			git_vector_foreach(&offsets, i, current)
+				git_vector_insert(&oids, (void*)&index[5 * (current - off)]);
+		} else {
+			for (i = 0; i < p->num_objects; i++)
+				git_vector_insert(&offsets, (void*)&index[24 * i]);
+			git_vector_sort(&offsets);
+			git_vector_foreach(&offsets, i, current)
+				git_vector_insert(&oids, (void*)&current[4]);
+		}
+
+		git_vector_free(&offsets);
+		p->oids = (git_oid **)git_vector_detach(NULL, NULL, &oids);
+	}
+
+	for (i = 0; i < p->num_objects; i++)
+		if ((error = cb(p->oids[i], data)) != 0)
+			return giterr_set_after_callback(error);
+
+	return error;
+}
+
+static int pack_entry_find_offset(
+	git_off_t *offset_out,
+	git_oid *found_oid,
+	struct git_pack_file *p,
+	const git_oid *short_oid,
+	size_t len)
+{
+	const uint32_t *level1_ofs = p->index_map.data;
+	const unsigned char *index = p->index_map.data;
+	unsigned hi, lo, stride;
+	int pos, found = 0;
+	const unsigned char *current = 0;
+
+	*offset_out = 0;
+
+	if (p->index_version == -1) {
+		int error;
+
+		if ((error = pack_index_open(p)) < 0)
+			return error;
+		assert(p->index_map.data);
+
+		index = p->index_map.data;
+		level1_ofs = p->index_map.data;
+	}
+
+	if (p->index_version > 1) {
+		level1_ofs += 2;
+		index += 8;
+	}
+
+	index += 4 * 256;
+	hi = ntohl(level1_ofs[(int)short_oid->id[0]]);
+	lo = ((short_oid->id[0] == 0x0) ? 0 : ntohl(level1_ofs[(int)short_oid->id[0] - 1]));
+
+	if (p->index_version > 1) {
+		stride = 20;
+	} else {
+		stride = 24;
+		index += 4;
+	}
+
+#ifdef INDEX_DEBUG_LOOKUP
+	printf("%02x%02x%02x... lo %u hi %u nr %d\n",
+		short_oid->id[0], short_oid->id[1], short_oid->id[2], lo, hi, p->num_objects);
+#endif
+
+#ifdef GIT_USE_LOOKUP
+	pos = sha1_entry_pos(index, stride, 0, lo, hi, p->num_objects, short_oid->id);
+#else
+	pos = sha1_position(index, stride, lo, hi, short_oid->id);
+#endif
+
+	if (pos >= 0) {
+		/* An object matching exactly the oid was found */
+		found = 1;
+		current = index + pos * stride;
+	} else {
+		/* No object was found */
+		/* pos refers to the object with the "closest" oid to short_oid */
+		pos = - 1 - pos;
+		if (pos < (int)p->num_objects) {
+			current = index + pos * stride;
+
+			if (!git_oid_ncmp(short_oid, (const git_oid *)current, len))
+				found = 1;
+		}
+	}
+
+	if (found && len != GIT_OID_HEXSZ && pos + 1 < (int)p->num_objects) {
+		/* Check for ambiguousity */
+		const unsigned char *next = current + stride;
+
+		if (!git_oid_ncmp(short_oid, (const git_oid *)next, len)) {
+			found = 2;
+		}
+	}
+
+	if (!found)
+		return git_odb__error_notfound("failed to find offset for pack entry", short_oid);
+	if (found > 1)
+		return git_odb__error_ambiguous("found multiple offsets for pack entry");
+
+	*offset_out = nth_packed_object_offset(p, pos);
+	git_oid_fromraw(found_oid, current);
+
+#ifdef INDEX_DEBUG_LOOKUP
+	{
+		unsigned char hex_sha1[GIT_OID_HEXSZ + 1];
+		git_oid_fmt(hex_sha1, found_oid);
+		hex_sha1[GIT_OID_HEXSZ] = '\0';
+		printf("found lo=%d %s\n", lo, hex_sha1);
+	}
+#endif
+
+	return 0;
+}
+
+int git_pack_entry_find(
+		struct git_pack_entry *e,
+		struct git_pack_file *p,
+		const git_oid *short_oid,
+		size_t len)
+{
+	git_off_t offset;
+	git_oid found_oid;
+	int error;
+
+	assert(p);
+
+	if (len == GIT_OID_HEXSZ && p->num_bad_objects) {
+		unsigned i;
+		for (i = 0; i < p->num_bad_objects; i++)
+			if (git_oid__cmp(short_oid, &p->bad_object_sha1[i]) == 0)
+				return packfile_error("bad object found in packfile");
+	}
+
+	error = pack_entry_find_offset(&offset, &found_oid, p, short_oid, len);
+	if (error < 0)
+		return error;
+
+	/* we found a unique entry in the index;
+	 * make sure the packfile backing the index
+	 * still exists on disk */
+	if (p->mwf.fd == -1 && (error = packfile_open(p)) < 0)
+		return error;
+
+	e->offset = offset;
+	e->p = p;
+
+	git_oid_cpy(&e->sha1, &found_oid);
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pack.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pack.h
new file mode 100755
index 0000000..b3d5b29
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pack.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_pack_h__
+#define INCLUDE_pack_h__
+
+#include <zlib.h>
+
+#include "git2/oid.h"
+
+#include "common.h"
+#include "map.h"
+#include "mwindow.h"
+#include "odb.h"
+#include "oidmap.h"
+#include "array.h"
+
+#define GIT_PACK_FILE_MODE 0444
+
+#define PACK_SIGNATURE 0x5041434b	/* "PACK" */
+#define PACK_VERSION 2
+#define pack_version_ok(v) ((v) == htonl(2) || (v) == htonl(3))
+struct git_pack_header {
+	uint32_t hdr_signature;
+	uint32_t hdr_version;
+	uint32_t hdr_entries;
+};
+
+/*
+ * The first four bytes of index formats later than version 1 should
+ * start with this signature, as all older git binaries would find this
+ * value illegal and abort reading the file.
+ *
+ * This is the case because the number of objects in a packfile
+ * cannot exceed 1,431,660,000 as every object would need at least
+ * 3 bytes of data and the overall packfile cannot exceed 4 GiB with
+ * version 1 of the index file due to the offsets limited to 32 bits.
+ * Clearly the signature exceeds this maximum.
+ *
+ * Very old git binaries will also compare the first 4 bytes to the
+ * next 4 bytes in the index and abort with a "non-monotonic index"
+ * error if the second 4 byte word is smaller than the first 4
+ * byte word. This would be true in the proposed future index
+ * format as idx_signature would be greater than idx_version.
+ */
+
+#define PACK_IDX_SIGNATURE 0xff744f63	/* "\377tOc" */
+
+struct git_pack_idx_header {
+	uint32_t idx_signature;
+	uint32_t idx_version;
+};
+
+typedef struct git_pack_cache_entry {
+	size_t last_usage; /* enough? */
+	git_atomic refcount;
+	git_rawobj raw;
+} git_pack_cache_entry;
+
+struct pack_chain_elem {
+	git_off_t base_key;
+	git_off_t offset;
+	size_t size;
+	git_otype type;
+};
+
+typedef git_array_t(struct pack_chain_elem) git_dependency_chain;
+
+#include "offmap.h"
+#include "oidmap.h"
+
+#define GIT_PACK_CACHE_MEMORY_LIMIT 16 * 1024 * 1024
+#define GIT_PACK_CACHE_SIZE_LIMIT 1024 * 1024 /* don't bother caching anything over 1MB */
+
+typedef struct {
+	size_t memory_used;
+	size_t memory_limit;
+	size_t use_ctr;
+	git_mutex lock;
+	git_offmap *entries;
+} git_pack_cache;
+
+struct git_pack_file {
+	git_mwindow_file mwf;
+	git_map index_map;
+	git_mutex lock; /* protect updates to mwf and index_map */
+	git_atomic refcount;
+
+	uint32_t num_objects;
+	uint32_t num_bad_objects;
+	git_oid *bad_object_sha1; /* array of git_oid */
+
+	int index_version;
+	git_time_t mtime;
+	unsigned pack_local:1, pack_keep:1, has_cache:1;
+	git_oidmap *idx_cache;
+	git_oid **oids;
+
+	git_pack_cache bases; /* delta base cache */
+
+	/* something like ".git/objects/pack/xxxxx.pack" */
+	char pack_name[GIT_FLEX_ARRAY]; /* more */
+};
+
+struct git_pack_entry {
+	git_off_t offset;
+	git_oid sha1;
+	struct git_pack_file *p;
+};
+
+typedef struct git_packfile_stream {
+	git_off_t curpos;
+	int done;
+	z_stream zstream;
+	struct git_pack_file *p;
+	git_mwindow *mw;
+} git_packfile_stream;
+
+size_t git_packfile__object_header(unsigned char *hdr, size_t size, git_otype type);
+
+int git_packfile__name(char **out, const char *path);
+
+int git_packfile_unpack_header(
+		size_t *size_p,
+		git_otype *type_p,
+		git_mwindow_file *mwf,
+		git_mwindow **w_curs,
+		git_off_t *curpos);
+
+int git_packfile_resolve_header(
+		size_t *size_p,
+		git_otype *type_p,
+		struct git_pack_file *p,
+		git_off_t offset);
+
+int git_packfile_unpack(git_rawobj *obj, struct git_pack_file *p, git_off_t *obj_offset);
+int packfile_unpack_compressed(
+	git_rawobj *obj,
+	struct git_pack_file *p,
+	git_mwindow **w_curs,
+	git_off_t *curpos,
+	size_t size,
+	git_otype type);
+
+int git_packfile_stream_open(git_packfile_stream *obj, struct git_pack_file *p, git_off_t curpos);
+ssize_t git_packfile_stream_read(git_packfile_stream *obj, void *buffer, size_t len);
+void git_packfile_stream_free(git_packfile_stream *obj);
+
+git_off_t get_delta_base(struct git_pack_file *p, git_mwindow **w_curs,
+		git_off_t *curpos, git_otype type,
+		git_off_t delta_obj_offset);
+
+void git_packfile_free(struct git_pack_file *p);
+int git_packfile_alloc(struct git_pack_file **pack_out, const char *path);
+
+int git_pack_entry_find(
+		struct git_pack_entry *e,
+		struct git_pack_file *p,
+		const git_oid *short_oid,
+		size_t len);
+int git_pack_foreach_entry(
+		struct git_pack_file *p,
+		git_odb_foreach_cb cb,
+		void *data);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/path.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/path.c
new file mode 100755
index 0000000..d145484
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/path.c
@@ -0,0 +1,1678 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "path.h"
+#include "posix.h"
+#include "repository.h"
+#ifdef GIT_WIN32
+#include "win32/posix.h"
+#include "win32/w32_buffer.h"
+#include "win32/w32_util.h"
+#include "win32/version.h"
+#else
+#include <dirent.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+
+#define LOOKS_LIKE_DRIVE_PREFIX(S) (git__isalpha((S)[0]) && (S)[1] == ':')
+
+#ifdef GIT_WIN32
+static bool looks_like_network_computer_name(const char *path, int pos)
+{
+	if (pos < 3)
+		return false;
+
+	if (path[0] != '/' || path[1] != '/')
+		return false;
+
+	while (pos-- > 2) {
+		if (path[pos] == '/')
+			return false;
+	}
+
+	return true;
+}
+#endif
+
+/*
+ * Based on the Android implementation, BSD licensed.
+ * http://android.git.kernel.org/
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+int git_path_basename_r(git_buf *buffer, const char *path)
+{
+	const char *endp, *startp;
+	int len, result;
+
+	/* Empty or NULL string gets treated as "." */
+	if (path == NULL || *path == '\0') {
+		startp = ".";
+		len		= 1;
+		goto Exit;
+	}
+
+	/* Strip trailing slashes */
+	endp = path + strlen(path) - 1;
+	while (endp > path && *endp == '/')
+		endp--;
+
+	/* All slashes becomes "/" */
+	if (endp == path && *endp == '/') {
+		startp = "/";
+		len	= 1;
+		goto Exit;
+	}
+
+	/* Find the start of the base */
+	startp = endp;
+	while (startp > path && *(startp - 1) != '/')
+		startp--;
+
+	/* Cast is safe because max path < max int */
+	len = (int)(endp - startp + 1);
+
+Exit:
+	result = len;
+
+	if (buffer != NULL && git_buf_set(buffer, startp, len) < 0)
+		return -1;
+
+	return result;
+}
+
+/*
+ * Based on the Android implementation, BSD licensed.
+ * Check http://android.git.kernel.org/
+ */
+int git_path_dirname_r(git_buf *buffer, const char *path)
+{
+	const char *endp;
+	int result, len;
+
+	/* Empty or NULL string gets treated as "." */
+	if (path == NULL || *path == '\0') {
+		path = ".";
+		len = 1;
+		goto Exit;
+	}
+
+	/* Strip trailing slashes */
+	endp = path + strlen(path) - 1;
+	while (endp > path && *endp == '/')
+		endp--;
+
+	/* Find the start of the dir */
+	while (endp > path && *endp != '/')
+		endp--;
+
+	/* Either the dir is "/" or there are no slashes */
+	if (endp == path) {
+		path = (*endp == '/') ? "/" : ".";
+		len = 1;
+		goto Exit;
+	}
+
+	do {
+		endp--;
+	} while (endp > path && *endp == '/');
+
+	/* Cast is safe because max path < max int */
+	len = (int)(endp - path + 1);
+
+#ifdef GIT_WIN32
+	/* Mimic unix behavior where '/.git' returns '/': 'C:/.git' will return
+		'C:/' here */
+
+	if (len == 2 && LOOKS_LIKE_DRIVE_PREFIX(path)) {
+		len = 3;
+		goto Exit;
+	}
+
+	/* Similarly checks if we're dealing with a network computer name
+		'//computername/.git' will return '//computername/' */
+
+	if (looks_like_network_computer_name(path, len)) {
+		len++;
+		goto Exit;
+	}
+
+#endif
+
+Exit:
+	result = len;
+
+	if (buffer != NULL && git_buf_set(buffer, path, len) < 0)
+		return -1;
+
+	return result;
+}
+
+
+char *git_path_dirname(const char *path)
+{
+	git_buf buf = GIT_BUF_INIT;
+	char *dirname;
+
+	git_path_dirname_r(&buf, path);
+	dirname = git_buf_detach(&buf);
+	git_buf_free(&buf); /* avoid memleak if error occurs */
+
+	return dirname;
+}
+
+char *git_path_basename(const char *path)
+{
+	git_buf buf = GIT_BUF_INIT;
+	char *basename;
+
+	git_path_basename_r(&buf, path);
+	basename = git_buf_detach(&buf);
+	git_buf_free(&buf); /* avoid memleak if error occurs */
+
+	return basename;
+}
+
+size_t git_path_basename_offset(git_buf *buffer)
+{
+	ssize_t slash;
+
+	if (!buffer || buffer->size <= 0)
+		return 0;
+
+	slash = git_buf_rfind_next(buffer, '/');
+
+	if (slash >= 0 && buffer->ptr[slash] == '/')
+		return (size_t)(slash + 1);
+
+	return 0;
+}
+
+const char *git_path_topdir(const char *path)
+{
+	size_t len;
+	ssize_t i;
+
+	assert(path);
+	len = strlen(path);
+
+	if (!len || path[len - 1] != '/')
+		return NULL;
+
+	for (i = (ssize_t)len - 2; i >= 0; --i)
+		if (path[i] == '/')
+			break;
+
+	return &path[i + 1];
+}
+
+int git_path_root(const char *path)
+{
+	int offset = 0;
+
+	/* Does the root of the path look like a windows drive ? */
+	if (LOOKS_LIKE_DRIVE_PREFIX(path))
+		offset += 2;
+
+#ifdef GIT_WIN32
+	/* Are we dealing with a windows network path? */
+	else if ((path[0] == '/' && path[1] == '/' && path[2] != '/') ||
+		(path[0] == '\\' && path[1] == '\\' && path[2] != '\\'))
+	{
+		offset += 2;
+
+		/* Skip the computer name segment */
+		while (path[offset] && path[offset] != '/' && path[offset] != '\\')
+			offset++;
+	}
+#endif
+
+	if (path[offset] == '/' || path[offset] == '\\')
+		return offset;
+
+	return -1;	/* Not a real error - signals that path is not rooted */
+}
+
+void git_path_trim_slashes(git_buf *path)
+{
+	int ceiling = git_path_root(path->ptr) + 1;
+	assert(ceiling >= 0);
+
+	while (path->size > (size_t)ceiling) {
+		if (path->ptr[path->size-1] != '/')
+			break;
+
+		path->ptr[path->size-1] = '\0';
+		path->size--;
+	}
+}
+
+int git_path_join_unrooted(
+	git_buf *path_out, const char *path, const char *base, ssize_t *root_at)
+{
+	ssize_t root;
+
+	assert(path && path_out);
+
+	root = (ssize_t)git_path_root(path);
+
+	if (base != NULL && root < 0) {
+		if (git_buf_joinpath(path_out, base, path) < 0)
+			return -1;
+
+		root = (ssize_t)strlen(base);
+	} else {
+		if (git_buf_sets(path_out, path) < 0)
+			return -1;
+
+		if (root < 0)
+			root = 0;
+		else if (base)
+			git_path_equal_or_prefixed(base, path, &root);
+	}
+
+	if (root_at)
+		*root_at = root;
+
+	return 0;
+}
+
+int git_path_prettify(git_buf *path_out, const char *path, const char *base)
+{
+	char buf[GIT_PATH_MAX];
+
+	assert(path && path_out);
+
+	/* construct path if needed */
+	if (base != NULL && git_path_root(path) < 0) {
+		if (git_buf_joinpath(path_out, base, path) < 0)
+			return -1;
+		path = path_out->ptr;
+	}
+
+	if (p_realpath(path, buf) == NULL) {
+		/* giterr_set resets the errno when dealing with a GITERR_OS kind of error */
+		int error = (errno == ENOENT || errno == ENOTDIR) ? GIT_ENOTFOUND : -1;
+		giterr_set(GITERR_OS, "Failed to resolve path '%s'", path);
+
+		git_buf_clear(path_out);
+
+		return error;
+	}
+
+	return git_buf_sets(path_out, buf);
+}
+
+int git_path_prettify_dir(git_buf *path_out, const char *path, const char *base)
+{
+	int error = git_path_prettify(path_out, path, base);
+	return (error < 0) ? error : git_path_to_dir(path_out);
+}
+
+int git_path_to_dir(git_buf *path)
+{
+	if (path->asize > 0 &&
+		git_buf_len(path) > 0 &&
+		path->ptr[git_buf_len(path) - 1] != '/')
+		git_buf_putc(path, '/');
+
+	return git_buf_oom(path) ? -1 : 0;
+}
+
+void git_path_string_to_dir(char* path, size_t size)
+{
+	size_t end = strlen(path);
+
+	if (end && path[end - 1] != '/' && end < size) {
+		path[end] = '/';
+		path[end + 1] = '\0';
+	}
+}
+
+int git__percent_decode(git_buf *decoded_out, const char *input)
+{
+	int len, hi, lo, i;
+	assert(decoded_out && input);
+
+	len = (int)strlen(input);
+	git_buf_clear(decoded_out);
+
+	for(i = 0; i < len; i++)
+	{
+		char c = input[i];
+
+		if (c != '%')
+			goto append;
+
+		if (i >= len - 2)
+			goto append;
+
+		hi = git__fromhex(input[i + 1]);
+		lo = git__fromhex(input[i + 2]);
+
+		if (hi < 0 || lo < 0)
+			goto append;
+
+		c = (char)(hi << 4 | lo);
+		i += 2;
+
+append:
+		if (git_buf_putc(decoded_out, c) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
+static int error_invalid_local_file_uri(const char *uri)
+{
+	giterr_set(GITERR_CONFIG, "'%s' is not a valid local file URI", uri);
+	return -1;
+}
+
+static int local_file_url_prefixlen(const char *file_url)
+{
+	int len = -1;
+
+	if (git__prefixcmp(file_url, "file://") == 0) {
+		if (file_url[7] == '/')
+			len = 8;
+		else if (git__prefixcmp(file_url + 7, "localhost/") == 0)
+			len = 17;
+	}
+
+	return len;
+}
+
+bool git_path_is_local_file_url(const char *file_url)
+{
+	return (local_file_url_prefixlen(file_url) > 0);
+}
+
+int git_path_fromurl(git_buf *local_path_out, const char *file_url)
+{
+	int offset;
+
+	assert(local_path_out && file_url);
+
+	if ((offset = local_file_url_prefixlen(file_url)) < 0 ||
+		file_url[offset] == '\0' || file_url[offset] == '/')
+		return error_invalid_local_file_uri(file_url);
+
+#ifndef GIT_WIN32
+	offset--;	/* A *nix absolute path starts with a forward slash */
+#endif
+
+	git_buf_clear(local_path_out);
+	return git__percent_decode(local_path_out, file_url + offset);
+}
+
+int git_path_walk_up(
+	git_buf *path,
+	const char *ceiling,
+	int (*cb)(void *data, const char *),
+	void *data)
+{
+	int error = 0;
+	git_buf iter;
+	ssize_t stop = 0, scan;
+	char oldc = '\0';
+
+	assert(path && cb);
+
+	if (ceiling != NULL) {
+		if (git__prefixcmp(path->ptr, ceiling) == 0)
+			stop = (ssize_t)strlen(ceiling);
+		else
+			stop = git_buf_len(path);
+	}
+	scan = git_buf_len(path);
+
+	/* empty path: yield only once */
+	if (!scan) {
+		error = cb(data, "");
+		if (error)
+			giterr_set_after_callback(error);
+		return error;
+	}
+
+	iter.ptr = path->ptr;
+	iter.size = git_buf_len(path);
+	iter.asize = path->asize;
+
+	while (scan >= stop) {
+		error = cb(data, iter.ptr);
+		iter.ptr[scan] = oldc;
+
+		if (error) {
+			giterr_set_after_callback(error);
+			break;
+		}
+
+		scan = git_buf_rfind_next(&iter, '/');
+		if (scan >= 0) {
+			scan++;
+			oldc = iter.ptr[scan];
+			iter.size = scan;
+			iter.ptr[scan] = '\0';
+		}
+	}
+
+	if (scan >= 0)
+		iter.ptr[scan] = oldc;
+
+	/* relative path: yield for the last component */
+	if (!error && stop == 0 && iter.ptr[0] != '/') {
+		error = cb(data, "");
+		if (error)
+			giterr_set_after_callback(error);
+	}
+
+	return error;
+}
+
+bool git_path_exists(const char *path)
+{
+	assert(path);
+	return p_access(path, F_OK) == 0;
+}
+
+bool git_path_isdir(const char *path)
+{
+	struct stat st;
+	if (p_stat(path, &st) < 0)
+		return false;
+
+	return S_ISDIR(st.st_mode) != 0;
+}
+
+bool git_path_isfile(const char *path)
+{
+	struct stat st;
+
+	assert(path);
+	if (p_stat(path, &st) < 0)
+		return false;
+
+	return S_ISREG(st.st_mode) != 0;
+}
+
+#ifdef GIT_WIN32
+
+bool git_path_is_empty_dir(const char *path)
+{
+	git_win32_path filter_w;
+	bool empty = false;
+
+	if (git_win32__findfirstfile_filter(filter_w, path)) {
+		WIN32_FIND_DATAW findData;
+		HANDLE hFind = FindFirstFileW(filter_w, &findData);
+
+		/* FindFirstFile will fail if there are no children to the given
+		 * path, which can happen if the given path is a file (and obviously
+		 * has no children) or if the given path is an empty mount point.
+		 * (Most directories have at least directory entries '.' and '..',
+		 * but ridiculously another volume mounted in another drive letter's
+		 * path space do not, and thus have nothing to enumerate.)  If
+		 * FindFirstFile fails, check if this is a directory-like thing
+		 * (a mount point).
+		 */
+		if (hFind == INVALID_HANDLE_VALUE)
+			return git_path_isdir(path);
+
+		/* If the find handle was created successfully, then it's a directory */
+		empty = true;
+
+		do {
+			/* Allow the enumeration to return . and .. and still be considered
+			 * empty. In the special case of drive roots (i.e. C:\) where . and
+			 * .. do not occur, we can still consider the path to be an empty
+			 * directory if there's nothing there. */
+			if (!git_path_is_dot_or_dotdotW(findData.cFileName)) {
+				empty = false;
+				break;
+			}
+		} while (FindNextFileW(hFind, &findData));
+
+		FindClose(hFind);
+	}
+
+	return empty;
+}
+
+#else
+
+static int path_found_entry(void *payload, git_buf *path)
+{
+	GIT_UNUSED(payload);
+	return !git_path_is_dot_or_dotdot(path->ptr);
+}
+
+bool git_path_is_empty_dir(const char *path)
+{
+	int error;
+	git_buf dir = GIT_BUF_INIT;
+
+	if (!git_path_isdir(path))
+		return false;
+
+	if ((error = git_buf_sets(&dir, path)) != 0)
+		giterr_clear();
+	else
+		error = git_path_direach(&dir, 0, path_found_entry, NULL);
+
+	git_buf_free(&dir);
+
+	return !error;
+}
+
+#endif
+
+int git_path_set_error(int errno_value, const char *path, const char *action)
+{
+	switch (errno_value) {
+	case ENOENT:
+	case ENOTDIR:
+		giterr_set(GITERR_OS, "Could not find '%s' to %s", path, action);
+		return GIT_ENOTFOUND;
+
+	case EINVAL:
+	case ENAMETOOLONG:
+		giterr_set(GITERR_OS, "Invalid path for filesystem '%s'", path);
+		return GIT_EINVALIDSPEC;
+
+	case EEXIST:
+		giterr_set(GITERR_OS, "Failed %s - '%s' already exists", action, path);
+		return GIT_EEXISTS;
+
+	default:
+		giterr_set(GITERR_OS, "Could not %s '%s'", action, path);
+		return -1;
+	}
+}
+
+int git_path_lstat(const char *path, struct stat *st)
+{
+	if (p_lstat(path, st) == 0)
+		return 0;
+
+	return git_path_set_error(errno, path, "stat");
+}
+
+static bool _check_dir_contents(
+	git_buf *dir,
+	const char *sub,
+	bool (*predicate)(const char *))
+{
+	bool result;
+	size_t dir_size = git_buf_len(dir);
+	size_t sub_size = strlen(sub);
+	size_t alloc_size;
+
+	/* leave base valid even if we could not make space for subdir */
+	if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, dir_size, sub_size) ||
+		GIT_ADD_SIZET_OVERFLOW(&alloc_size, alloc_size, 2) ||
+		git_buf_try_grow(dir, alloc_size, false) < 0)
+		return false;
+
+	/* save excursion */
+	git_buf_joinpath(dir, dir->ptr, sub);
+
+	result = predicate(dir->ptr);
+
+	/* restore path */
+	git_buf_truncate(dir, dir_size);
+	return result;
+}
+
+bool git_path_contains(git_buf *dir, const char *item)
+{
+	return _check_dir_contents(dir, item, &git_path_exists);
+}
+
+bool git_path_contains_dir(git_buf *base, const char *subdir)
+{
+	return _check_dir_contents(base, subdir, &git_path_isdir);
+}
+
+bool git_path_contains_file(git_buf *base, const char *file)
+{
+	return _check_dir_contents(base, file, &git_path_isfile);
+}
+
+int git_path_find_dir(git_buf *dir, const char *path, const char *base)
+{
+	int error = git_path_join_unrooted(dir, path, base, NULL);
+
+	if (!error) {
+		char buf[GIT_PATH_MAX];
+		if (p_realpath(dir->ptr, buf) != NULL)
+			error = git_buf_sets(dir, buf);
+	}
+
+	/* call dirname if this is not a directory */
+	if (!error) /* && git_path_isdir(dir->ptr) == false) */
+		error = (git_path_dirname_r(dir, dir->ptr) < 0) ? -1 : 0;
+
+	if (!error)
+		error = git_path_to_dir(dir);
+
+	return error;
+}
+
+int git_path_resolve_relative(git_buf *path, size_t ceiling)
+{
+	char *base, *to, *from, *next;
+	size_t len;
+
+	if (!path || git_buf_oom(path))
+		return -1;
+
+	if (ceiling > path->size)
+		ceiling = path->size;
+
+	/* recognize drive prefixes, etc. that should not be backed over */
+	if (ceiling == 0)
+		ceiling = git_path_root(path->ptr) + 1;
+
+	/* recognize URL prefixes that should not be backed over */
+	if (ceiling == 0) {
+		for (next = path->ptr; *next && git__isalpha(*next); ++next);
+		if (next[0] == ':' && next[1] == '/' && next[2] == '/')
+			ceiling = (next + 3) - path->ptr;
+	}
+
+	base = to = from = path->ptr + ceiling;
+
+	while (*from) {
+		for (next = from; *next && *next != '/'; ++next);
+
+		len = next - from;
+
+		if (len == 1 && from[0] == '.')
+			/* do nothing with singleton dot */;
+
+		else if (len == 2 && from[0] == '.' && from[1] == '.') {
+			/* error out if trying to up one from a hard base */
+			if (to == base && ceiling != 0) {
+				giterr_set(GITERR_INVALID,
+					"Cannot strip root component off url");
+				return -1;
+			}
+
+			/* no more path segments to strip,
+			 * use '../' as a new base path */
+			if (to == base) {
+				if (*next == '/')
+					len++;
+
+				if (to != from)
+					memmove(to, from, len);
+
+				to += len;
+				/* this is now the base, can't back up from a
+				 * relative prefix */
+				base = to;
+			} else {
+				/* back up a path segment */
+				while (to > base && to[-1] == '/') to--;
+				while (to > base && to[-1] != '/') to--;
+			}
+		} else {
+			if (*next == '/' && *from != '/')
+				len++;
+
+			if (to != from)
+				memmove(to, from, len);
+
+			to += len;
+		}
+
+		from += len;
+
+		while (*from == '/') from++;
+	}
+
+	*to = '\0';
+
+	path->size = to - path->ptr;
+
+	return 0;
+}
+
+int git_path_apply_relative(git_buf *target, const char *relpath)
+{
+	git_buf_joinpath(target, git_buf_cstr(target), relpath);
+	return git_path_resolve_relative(target, 0);
+}
+
+int git_path_cmp(
+	const char *name1, size_t len1, int isdir1,
+	const char *name2, size_t len2, int isdir2,
+	int (*compare)(const char *, const char *, size_t))
+{
+	unsigned char c1, c2;
+	size_t len = len1 < len2 ? len1 : len2;
+	int cmp;
+
+	cmp = compare(name1, name2, len);
+	if (cmp)
+		return cmp;
+
+	c1 = name1[len];
+	c2 = name2[len];
+
+	if (c1 == '\0' && isdir1)
+		c1 = '/';
+
+	if (c2 == '\0' && isdir2)
+		c2 = '/';
+
+	return (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0;
+}
+
+int git_path_make_relative(git_buf *path, const char *parent)
+{
+	const char *p, *q, *p_dirsep, *q_dirsep;
+	size_t plen = path->size, newlen, alloclen, depth = 1, i, offset;
+
+	for (p_dirsep = p = path->ptr, q_dirsep = q = parent; *p && *q; p++, q++) {
+		if (*p == '/' && *q == '/') {
+			p_dirsep = p;
+			q_dirsep = q;
+		}
+		else if (*p != *q)
+			break;
+	}
+
+	/* need at least 1 common path segment */
+	if ((p_dirsep == path->ptr || q_dirsep == parent) &&
+		(*p_dirsep != '/' || *q_dirsep != '/')) {
+		giterr_set(GITERR_INVALID,
+			"%s is not a parent of %s", parent, path->ptr);
+		return GIT_ENOTFOUND;
+	}
+
+	if (*p == '/' && !*q)
+		p++;
+	else if (!*p && *q == '/')
+		q++;
+	else if (!*p && !*q)
+		return git_buf_clear(path), 0;
+	else {
+		p = p_dirsep + 1;
+		q = q_dirsep + 1;
+	}
+
+	plen -= (p - path->ptr);
+
+	if (!*q)
+		return git_buf_set(path, p, plen);
+
+	for (; (q = strchr(q, '/')) && *(q + 1); q++)
+		depth++;
+
+	GITERR_CHECK_ALLOC_MULTIPLY(&newlen, depth, 3);
+	GITERR_CHECK_ALLOC_ADD(&newlen, newlen, plen);
+
+	GITERR_CHECK_ALLOC_ADD(&alloclen, newlen, 1);
+
+	/* save the offset as we might realllocate the pointer */
+	offset = p - path->ptr;
+	if (git_buf_try_grow(path, alloclen, 1) < 0)
+		return -1;
+	p = path->ptr + offset;
+
+	memmove(path->ptr + (depth * 3), p, plen + 1);
+
+	for (i = 0; i < depth; i++)
+		memcpy(path->ptr + (i * 3), "../", 3);
+
+	path->size = newlen;
+	return 0;
+}
+
+bool git_path_has_non_ascii(const char *path, size_t pathlen)
+{
+	const uint8_t *scan = (const uint8_t *)path, *end;
+
+	for (end = scan + pathlen; scan < end; ++scan)
+		if (*scan & 0x80)
+			return true;
+
+	return false;
+}
+
+#ifdef GIT_USE_ICONV
+
+int git_path_iconv_init_precompose(git_path_iconv_t *ic)
+{
+	git_buf_init(&ic->buf, 0);
+	ic->map = iconv_open(GIT_PATH_REPO_ENCODING, GIT_PATH_NATIVE_ENCODING);
+	return 0;
+}
+
+void git_path_iconv_clear(git_path_iconv_t *ic)
+{
+	if (ic) {
+		if (ic->map != (iconv_t)-1)
+			iconv_close(ic->map);
+		git_buf_free(&ic->buf);
+	}
+}
+
+int git_path_iconv(git_path_iconv_t *ic, const char **in, size_t *inlen)
+{
+	char *nfd = (char*)*in, *nfc;
+	size_t nfdlen = *inlen, nfclen, wantlen = nfdlen, alloclen, rv;
+	int retry = 1;
+
+	if (!ic || ic->map == (iconv_t)-1 ||
+		!git_path_has_non_ascii(*in, *inlen))
+		return 0;
+
+	git_buf_clear(&ic->buf);
+
+	while (1) {
+		GITERR_CHECK_ALLOC_ADD(&alloclen, wantlen, 1);
+		if (git_buf_grow(&ic->buf, alloclen) < 0)
+			return -1;
+
+		nfc    = ic->buf.ptr   + ic->buf.size;
+		nfclen = ic->buf.asize - ic->buf.size;
+
+		rv = iconv(ic->map, &nfd, &nfdlen, &nfc, &nfclen);
+
+		ic->buf.size = (nfc - ic->buf.ptr);
+
+		if (rv != (size_t)-1)
+			break;
+
+		/* if we cannot convert the data (probably because iconv thinks
+		 * it is not valid UTF-8 source data), then use original data
+		 */
+		if (errno != E2BIG)
+			return 0;
+
+		/* make space for 2x the remaining data to be converted
+		 * (with per retry overhead to avoid infinite loops)
+		 */
+		wantlen = ic->buf.size + max(nfclen, nfdlen) * 2 + (size_t)(retry * 4);
+
+		if (retry++ > 4)
+			goto fail;
+	}
+
+	ic->buf.ptr[ic->buf.size] = '\0';
+
+	*in    = ic->buf.ptr;
+	*inlen = ic->buf.size;
+
+	return 0;
+
+fail:
+	giterr_set(GITERR_OS, "Unable to convert unicode path data");
+	return -1;
+}
+
+static const char *nfc_file = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D.XXXXXX";
+static const char *nfd_file = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D.XXXXXX";
+
+/* Check if the platform is decomposing unicode data for us.  We will
+ * emulate core Git and prefer to use precomposed unicode data internally
+ * on these platforms, composing the decomposed unicode on the fly.
+ *
+ * This mainly happens on the Mac where HDFS stores filenames as
+ * decomposed unicode.  Even on VFAT and SAMBA file systems, the Mac will
+ * return decomposed unicode from readdir() even when the actual
+ * filesystem is storing precomposed unicode.
+ */
+bool git_path_does_fs_decompose_unicode(const char *root)
+{
+	git_buf path = GIT_BUF_INIT;
+	int fd;
+	bool found_decomposed = false;
+	char tmp[6];
+
+	/* Create a file using a precomposed path and then try to find it
+	 * using the decomposed name.  If the lookup fails, then we will mark
+	 * that we should precompose unicode for this repository.
+	 */
+	if (git_buf_joinpath(&path, root, nfc_file) < 0 ||
+		(fd = p_mkstemp(path.ptr)) < 0)
+		goto done;
+	p_close(fd);
+
+	/* record trailing digits generated by mkstemp */
+	memcpy(tmp, path.ptr + path.size - sizeof(tmp), sizeof(tmp));
+
+	/* try to look up as NFD path */
+	if (git_buf_joinpath(&path, root, nfd_file) < 0)
+		goto done;
+	memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp));
+
+	found_decomposed = git_path_exists(path.ptr);
+
+	/* remove temporary file (using original precomposed path) */
+	if (git_buf_joinpath(&path, root, nfc_file) < 0)
+		goto done;
+	memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp));
+
+	(void)p_unlink(path.ptr);
+
+done:
+	git_buf_free(&path);
+	return found_decomposed;
+}
+
+#else
+
+bool git_path_does_fs_decompose_unicode(const char *root)
+{
+	GIT_UNUSED(root);
+	return false;
+}
+
+#endif
+
+#if defined(__sun) || defined(__GNU__)
+typedef char path_dirent_data[sizeof(struct dirent) + FILENAME_MAX + 1];
+#else
+typedef struct dirent path_dirent_data;
+#endif
+
+int git_path_direach(
+	git_buf *path,
+	uint32_t flags,
+	int (*fn)(void *, git_buf *),
+	void *arg)
+{
+	int error = 0;
+	ssize_t wd_len;
+	DIR *dir;
+	struct dirent *de;
+
+#ifdef GIT_USE_ICONV
+	git_path_iconv_t ic = GIT_PATH_ICONV_INIT;
+#endif
+
+	GIT_UNUSED(flags);
+
+	if (git_path_to_dir(path) < 0)
+		return -1;
+
+	wd_len = git_buf_len(path);
+
+	if ((dir = opendir(path->ptr)) == NULL) {
+		giterr_set(GITERR_OS, "Failed to open directory '%s'", path->ptr);
+		if (errno == ENOENT)
+			return GIT_ENOTFOUND;
+
+		return -1;
+	}
+
+#ifdef GIT_USE_ICONV
+	if ((flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0)
+		(void)git_path_iconv_init_precompose(&ic);
+#endif
+
+	while ((de = readdir(dir)) != NULL) {
+		const char *de_path = de->d_name;
+		size_t de_len = strlen(de_path);
+
+		if (git_path_is_dot_or_dotdot(de_path))
+			continue;
+
+#ifdef GIT_USE_ICONV
+		if ((error = git_path_iconv(&ic, &de_path, &de_len)) < 0)
+			break;
+#endif
+
+		if ((error = git_buf_put(path, de_path, de_len)) < 0)
+			break;
+
+		giterr_clear();
+		error = fn(arg, path);
+
+		git_buf_truncate(path, wd_len); /* restore path */
+
+		/* Only set our own error if the callback did not set one already */
+		if (error != 0) {
+			if (!giterr_last())
+				giterr_set_after_callback(error);
+
+			break;
+		}
+	}
+
+	closedir(dir);
+
+#ifdef GIT_USE_ICONV
+	git_path_iconv_clear(&ic);
+#endif
+
+	return error;
+}
+
+#if defined(GIT_WIN32) && !defined(__MINGW32__)
+
+/* Using _FIND_FIRST_EX_LARGE_FETCH may increase performance in Windows 7
+ * and better.
+ */
+#ifndef FIND_FIRST_EX_LARGE_FETCH
+# define FIND_FIRST_EX_LARGE_FETCH 2
+#endif
+
+int git_path_diriter_init(
+	git_path_diriter *diriter,
+	const char *path,
+	unsigned int flags)
+{
+	git_win32_path path_filter;
+	git_buf hack = {0};
+
+	static int is_win7_or_later = -1;
+	if (is_win7_or_later < 0)
+		is_win7_or_later = git_has_win32_version(6, 1, 0);
+
+	assert(diriter && path);
+
+	memset(diriter, 0, sizeof(git_path_diriter));
+	diriter->handle = INVALID_HANDLE_VALUE;
+
+	if (git_buf_puts(&diriter->path_utf8, path) < 0)
+		return -1;
+
+	git_path_trim_slashes(&diriter->path_utf8);
+
+	if (diriter->path_utf8.size == 0) {
+		giterr_set(GITERR_FILESYSTEM, "Could not open directory '%s'", path);
+		return -1;
+	}
+
+	if ((diriter->parent_len = git_win32_path_from_utf8(diriter->path, diriter->path_utf8.ptr)) < 0 ||
+			!git_win32__findfirstfile_filter(path_filter, diriter->path_utf8.ptr)) {
+		giterr_set(GITERR_OS, "Could not parse the directory path '%s'", path);
+		return -1;
+	}
+
+	diriter->handle = FindFirstFileExW(
+		path_filter,
+		is_win7_or_later ? FindExInfoBasic : FindExInfoStandard,
+		&diriter->current,
+		FindExSearchNameMatch,
+		NULL,
+		is_win7_or_later ? FIND_FIRST_EX_LARGE_FETCH : 0);
+
+	if (diriter->handle == INVALID_HANDLE_VALUE) {
+		giterr_set(GITERR_OS, "Could not open directory '%s'", path);
+		return -1;
+	}
+
+	diriter->parent_utf8_len = diriter->path_utf8.size;
+	diriter->flags = flags;
+	return 0;
+}
+
+static int diriter_update_paths(git_path_diriter *diriter)
+{
+	size_t filename_len, path_len;
+
+	filename_len = wcslen(diriter->current.cFileName);
+
+	if (GIT_ADD_SIZET_OVERFLOW(&path_len, diriter->parent_len, filename_len) ||
+		GIT_ADD_SIZET_OVERFLOW(&path_len, path_len, 2))
+		return -1;
+
+	if (path_len > GIT_WIN_PATH_UTF16) {
+		giterr_set(GITERR_FILESYSTEM,
+			"invalid path '%.*ls\\%ls' (path too long)",
+			diriter->parent_len, diriter->path, diriter->current.cFileName);
+		return -1;
+	}
+
+	diriter->path[diriter->parent_len] = L'\\';
+	memcpy(&diriter->path[diriter->parent_len+1],
+		diriter->current.cFileName, filename_len * sizeof(wchar_t));
+	diriter->path[path_len-1] = L'\0';
+
+	git_buf_truncate(&diriter->path_utf8, diriter->parent_utf8_len);
+	git_buf_putc(&diriter->path_utf8, '/');
+	git_buf_put_w(&diriter->path_utf8, diriter->current.cFileName, filename_len);
+
+	if (git_buf_oom(&diriter->path_utf8))
+		return -1;
+
+	return 0;
+}
+
+int git_path_diriter_next(git_path_diriter *diriter)
+{
+	bool skip_dot = !(diriter->flags & GIT_PATH_DIR_INCLUDE_DOT_AND_DOTDOT);
+
+	do {
+		/* Our first time through, we already have the data from
+		 * FindFirstFileW.  Use it, otherwise get the next file.
+		 */
+		if (!diriter->needs_next)
+			diriter->needs_next = 1;
+		else if (!FindNextFileW(diriter->handle, &diriter->current))
+			return GIT_ITEROVER;
+	} while (skip_dot && git_path_is_dot_or_dotdotW(diriter->current.cFileName));
+
+	if (diriter_update_paths(diriter) < 0)
+		return -1;
+
+	return 0;
+}
+
+int git_path_diriter_filename(
+	const char **out,
+	size_t *out_len,
+	git_path_diriter *diriter)
+{
+	assert(out && out_len && diriter);
+
+	assert(diriter->path_utf8.size > diriter->parent_utf8_len);
+
+	*out = &diriter->path_utf8.ptr[diriter->parent_utf8_len+1];
+	*out_len = diriter->path_utf8.size - diriter->parent_utf8_len - 1;
+	return 0;
+}
+
+int git_path_diriter_fullpath(
+	const char **out,
+	size_t *out_len,
+	git_path_diriter *diriter)
+{
+	assert(out && out_len && diriter);
+
+	*out = diriter->path_utf8.ptr;
+	*out_len = diriter->path_utf8.size;
+	return 0;
+}
+
+int git_path_diriter_stat(struct stat *out, git_path_diriter *diriter)
+{
+	assert(out && diriter);
+
+	return git_win32__file_attribute_to_stat(out,
+		(WIN32_FILE_ATTRIBUTE_DATA *)&diriter->current,
+		diriter->path);
+}
+
+void git_path_diriter_free(git_path_diriter *diriter)
+{
+	if (diriter == NULL)
+		return;
+
+	git_buf_free(&diriter->path_utf8);
+
+	if (diriter->handle != INVALID_HANDLE_VALUE) {
+		FindClose(diriter->handle);
+		diriter->handle = INVALID_HANDLE_VALUE;
+	}
+}
+
+#else
+
+int git_path_diriter_init(
+	git_path_diriter *diriter,
+	const char *path,
+	unsigned int flags)
+{
+	assert(diriter && path);
+
+	memset(diriter, 0, sizeof(git_path_diriter));
+
+	if (git_buf_puts(&diriter->path, path) < 0)
+		return -1;
+
+	git_path_trim_slashes(&diriter->path);
+
+	if (diriter->path.size == 0) {
+		giterr_set(GITERR_FILESYSTEM, "Could not open directory '%s'", path);
+		return -1;
+	}
+
+	if ((diriter->dir = opendir(diriter->path.ptr)) == NULL) {
+		git_buf_free(&diriter->path);
+
+		giterr_set(GITERR_OS, "Failed to open directory '%s'", path);
+		return -1;
+	}
+
+#ifdef GIT_USE_ICONV
+	if ((flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0)
+		(void)git_path_iconv_init_precompose(&diriter->ic);
+#endif
+
+	diriter->parent_len = diriter->path.size;
+	diriter->flags = flags;
+
+	return 0;
+}
+
+int git_path_diriter_next(git_path_diriter *diriter)
+{
+	struct dirent *de;
+	const char *filename;
+	size_t filename_len;
+	bool skip_dot = !(diriter->flags & GIT_PATH_DIR_INCLUDE_DOT_AND_DOTDOT);
+	int error = 0;
+
+	assert(diriter);
+
+	errno = 0;
+
+	do {
+		if ((de = readdir(diriter->dir)) == NULL) {
+			if (!errno)
+				return GIT_ITEROVER;
+
+			giterr_set(GITERR_OS,
+				"Could not read directory '%s'", diriter->path);
+			return -1;
+		}
+	} while (skip_dot && git_path_is_dot_or_dotdot(de->d_name));
+
+	filename = de->d_name;
+	filename_len = strlen(filename);
+
+#ifdef GIT_USE_ICONV
+	if ((diriter->flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0 &&
+		(error = git_path_iconv(&diriter->ic, &filename, &filename_len)) < 0)
+		return error;
+#endif
+
+	git_buf_truncate(&diriter->path, diriter->parent_len);
+	git_buf_putc(&diriter->path, '/');
+	git_buf_put(&diriter->path, filename, filename_len);
+
+	if (git_buf_oom(&diriter->path))
+		return -1;
+
+	return error;
+}
+
+int git_path_diriter_filename(
+	const char **out,
+	size_t *out_len,
+	git_path_diriter *diriter)
+{
+	assert(out && out_len && diriter);
+
+	assert(diriter->path.size > diriter->parent_len);
+
+	*out = &diriter->path.ptr[diriter->parent_len+1];
+	*out_len = diriter->path.size - diriter->parent_len - 1;
+	return 0;
+}
+
+int git_path_diriter_fullpath(
+	const char **out,
+	size_t *out_len,
+	git_path_diriter *diriter)
+{
+	assert(out && out_len && diriter);
+
+	*out = diriter->path.ptr;
+	*out_len = diriter->path.size;
+	return 0;
+}
+
+int git_path_diriter_stat(struct stat *out, git_path_diriter *diriter)
+{
+	assert(out && diriter);
+
+	return git_path_lstat(diriter->path.ptr, out);
+}
+
+void git_path_diriter_free(git_path_diriter *diriter)
+{
+	if (diriter == NULL)
+		return;
+
+	if (diriter->dir) {
+		closedir(diriter->dir);
+		diriter->dir = NULL;
+	}
+
+#ifdef GIT_USE_ICONV
+	git_path_iconv_clear(&diriter->ic);
+#endif
+
+	git_buf_free(&diriter->path);
+}
+
+#endif
+
+int git_path_dirload(
+	git_vector *contents,
+	const char *path,
+	size_t prefix_len,
+	unsigned int flags)
+{
+	git_path_diriter iter = GIT_PATH_DIRITER_INIT;
+	const char *name;
+	size_t name_len;
+	char *dup;
+	int error;
+
+	assert(contents && path);
+
+	if ((error = git_path_diriter_init(&iter, path, flags)) < 0)
+		return error;
+
+	while ((error = git_path_diriter_next(&iter)) == 0) {
+		if ((error = git_path_diriter_fullpath(&name, &name_len, &iter)) < 0)
+			break;
+
+		assert(name_len > prefix_len);
+
+		dup = git__strndup(name + prefix_len, name_len - prefix_len);
+		GITERR_CHECK_ALLOC(dup);
+
+		if ((error = git_vector_insert(contents, dup)) < 0)
+			break;
+	}
+
+	if (error == GIT_ITEROVER)
+		error = 0;
+
+	git_path_diriter_free(&iter);
+	return error;
+}
+
+int git_path_from_url_or_path(git_buf *local_path_out, const char *url_or_path)
+{
+	if (git_path_is_local_file_url(url_or_path))
+		return git_path_fromurl(local_path_out, url_or_path);
+	else
+		return git_buf_sets(local_path_out, url_or_path);
+}
+
+/* Reject paths like AUX or COM1, or those versions that end in a dot or
+ * colon.  ("AUX." or "AUX:")
+ */
+GIT_INLINE(bool) verify_dospath(
+	const char *component,
+	size_t len,
+	const char dospath[3],
+	bool trailing_num)
+{
+	size_t last = trailing_num ? 4 : 3;
+
+	if (len < last || git__strncasecmp(component, dospath, 3) != 0)
+		return true;
+
+	if (trailing_num && (component[3] < '1' || component[3] > '9'))
+		return true;
+
+	return (len > last &&
+		component[last] != '.' &&
+		component[last] != ':');
+}
+
+static int32_t next_hfs_char(const char **in, size_t *len)
+{
+	while (*len) {
+		int32_t codepoint;
+		int cp_len = git__utf8_iterate((const uint8_t *)(*in), (int)(*len), &codepoint);
+		if (cp_len < 0)
+			return -1;
+
+		(*in) += cp_len;
+		(*len) -= cp_len;
+
+		/* these code points are ignored completely */
+		switch (codepoint) {
+		case 0x200c: /* ZERO WIDTH NON-JOINER */
+		case 0x200d: /* ZERO WIDTH JOINER */
+		case 0x200e: /* LEFT-TO-RIGHT MARK */
+		case 0x200f: /* RIGHT-TO-LEFT MARK */
+		case 0x202a: /* LEFT-TO-RIGHT EMBEDDING */
+		case 0x202b: /* RIGHT-TO-LEFT EMBEDDING */
+		case 0x202c: /* POP DIRECTIONAL FORMATTING */
+		case 0x202d: /* LEFT-TO-RIGHT OVERRIDE */
+		case 0x202e: /* RIGHT-TO-LEFT OVERRIDE */
+		case 0x206a: /* INHIBIT SYMMETRIC SWAPPING */
+		case 0x206b: /* ACTIVATE SYMMETRIC SWAPPING */
+		case 0x206c: /* INHIBIT ARABIC FORM SHAPING */
+		case 0x206d: /* ACTIVATE ARABIC FORM SHAPING */
+		case 0x206e: /* NATIONAL DIGIT SHAPES */
+		case 0x206f: /* NOMINAL DIGIT SHAPES */
+		case 0xfeff: /* ZERO WIDTH NO-BREAK SPACE */
+			continue;
+		}
+
+		/* fold into lowercase -- this will only fold characters in
+		 * the ASCII range, which is perfectly fine, because the
+		 * git folder name can only be composed of ascii characters
+		 */
+		return git__tolower(codepoint);
+	}
+	return 0; /* NULL byte -- end of string */
+}
+
+static bool verify_dotgit_hfs(const char *path, size_t len)
+{
+	if (next_hfs_char(&path, &len) != '.' ||
+		next_hfs_char(&path, &len) != 'g' ||
+		next_hfs_char(&path, &len) != 'i' ||
+		next_hfs_char(&path, &len) != 't' ||
+		next_hfs_char(&path, &len) != 0)
+		return true;
+
+	return false;
+}
+
+GIT_INLINE(bool) verify_dotgit_ntfs(git_repository *repo, const char *path, size_t len)
+{
+	git_buf *reserved = git_repository__reserved_names_win32;
+	size_t reserved_len = git_repository__reserved_names_win32_len;
+	size_t start = 0, i;
+
+	if (repo)
+		git_repository__reserved_names(&reserved, &reserved_len, repo, true);
+
+	for (i = 0; i < reserved_len; i++) {
+		git_buf *r = &reserved[i];
+
+		if (len >= r->size &&
+			strncasecmp(path, r->ptr, r->size) == 0) {
+			start = r->size;
+			break;
+		}
+	}
+
+	if (!start)
+		return true;
+
+	/* Reject paths like ".git\" */
+	if (path[start] == '\\')
+		return false;
+
+	/* Reject paths like '.git ' or '.git.' */
+	for (i = start; i < len; i++) {
+		if (path[i] != ' ' && path[i] != '.')
+			return true;
+	}
+
+	return false;
+}
+
+GIT_INLINE(bool) verify_char(unsigned char c, unsigned int flags)
+{
+	if ((flags & GIT_PATH_REJECT_BACKSLASH) && c == '\\')
+		return false;
+
+	if ((flags & GIT_PATH_REJECT_SLASH) && c == '/')
+		return false;
+
+	if (flags & GIT_PATH_REJECT_NT_CHARS) {
+		if (c < 32)
+			return false;
+
+		switch (c) {
+		case '<':
+		case '>':
+		case ':':
+		case '"':
+		case '|':
+		case '?':
+		case '*':
+			return false;
+		}
+	}
+
+	return true;
+}
+
+/*
+ * We fundamentally don't like some paths when dealing with user-inputted
+ * strings (in checkout or ref names): we don't want dot or dot-dot
+ * anywhere, we want to avoid writing weird paths on Windows that can't
+ * be handled by tools that use the non-\\?\ APIs, we don't want slashes
+ * or double slashes at the end of paths that can make them ambiguous.
+ *
+ * For checkout, we don't want to recurse into ".git" either.
+ */
+static bool verify_component(
+	git_repository *repo,
+	const char *component,
+	size_t len,
+	unsigned int flags)
+{
+	if (len == 0)
+		return false;
+
+	if ((flags & GIT_PATH_REJECT_TRAVERSAL) &&
+		len == 1 && component[0] == '.')
+		return false;
+
+	if ((flags & GIT_PATH_REJECT_TRAVERSAL) &&
+		len == 2 && component[0] == '.' && component[1] == '.')
+		return false;
+
+	if ((flags & GIT_PATH_REJECT_TRAILING_DOT) && component[len-1] == '.')
+		return false;
+
+	if ((flags & GIT_PATH_REJECT_TRAILING_SPACE) && component[len-1] == ' ')
+		return false;
+
+	if ((flags & GIT_PATH_REJECT_TRAILING_COLON) && component[len-1] == ':')
+		return false;
+
+	if (flags & GIT_PATH_REJECT_DOS_PATHS) {
+		if (!verify_dospath(component, len, "CON", false) ||
+			!verify_dospath(component, len, "PRN", false) ||
+			!verify_dospath(component, len, "AUX", false) ||
+			!verify_dospath(component, len, "NUL", false) ||
+			!verify_dospath(component, len, "COM", true)  ||
+			!verify_dospath(component, len, "LPT", true))
+			return false;
+	}
+
+	if (flags & GIT_PATH_REJECT_DOT_GIT_HFS &&
+		!verify_dotgit_hfs(component, len))
+		return false;
+
+	if (flags & GIT_PATH_REJECT_DOT_GIT_NTFS &&
+		!verify_dotgit_ntfs(repo, component, len))
+		return false;
+
+	if ((flags & GIT_PATH_REJECT_DOT_GIT_HFS) == 0 &&
+		(flags & GIT_PATH_REJECT_DOT_GIT_NTFS) == 0 &&
+		(flags & GIT_PATH_REJECT_DOT_GIT) &&
+		len == 4 &&
+		component[0] == '.' &&
+		(component[1] == 'g' || component[1] == 'G') &&
+		(component[2] == 'i' || component[2] == 'I') &&
+		(component[3] == 't' || component[3] == 'T'))
+		return false;
+
+	return true;
+}
+
+GIT_INLINE(unsigned int) dotgit_flags(
+	git_repository *repo,
+	unsigned int flags)
+{
+	int protectHFS = 0, protectNTFS = 0;
+
+#ifdef __APPLE__
+	protectHFS = 1;
+#endif
+
+#ifdef GIT_WIN32
+	protectNTFS = 1;
+#endif
+
+	if (repo && !protectHFS)
+		git_repository__cvar(&protectHFS, repo, GIT_CVAR_PROTECTHFS);
+	if (protectHFS)
+		flags |= GIT_PATH_REJECT_DOT_GIT_HFS;
+
+	if (repo && !protectNTFS)
+		git_repository__cvar(&protectNTFS, repo, GIT_CVAR_PROTECTNTFS);
+	if (protectNTFS)
+		flags |= GIT_PATH_REJECT_DOT_GIT_NTFS;
+
+	return flags;
+}
+
+bool git_path_isvalid(
+	git_repository *repo,
+	const char *path,
+	unsigned int flags)
+{
+	const char *start, *c;
+
+	/* Upgrade the ".git" checks based on platform */
+	if ((flags & GIT_PATH_REJECT_DOT_GIT))
+		flags = dotgit_flags(repo, flags);
+
+	for (start = c = path; *c; c++) {
+		if (!verify_char(*c, flags))
+			return false;
+
+		if (*c == '/') {
+			if (!verify_component(repo, start, (c - start), flags))
+				return false;
+
+			start = c+1;
+		}
+	}
+
+	return verify_component(repo, start, (c - start), flags);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/path.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/path.h
new file mode 100755
index 0000000..e6be06f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/path.h
@@ -0,0 +1,594 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_path_h__
+#define INCLUDE_path_h__
+
+#include "common.h"
+#include "posix.h"
+#include "buffer.h"
+#include "vector.h"
+
+/**
+ * Path manipulation utils
+ *
+ * These are path utilities that munge paths without actually
+ * looking at the real filesystem.
+ */
+
+/*
+ * The dirname() function shall take a pointer to a character string
+ * that contains a pathname, and return a pointer to a string that is a
+ * pathname of the parent directory of that file. Trailing '/' characters
+ * in the path are not counted as part of the path.
+ *
+ * If path does not contain a '/', then dirname() shall return a pointer to
+ * the string ".". If path is a null pointer or points to an empty string,
+ * dirname() shall return a pointer to the string "." .
+ *
+ * The `git_path_dirname` implementation is thread safe. The returned
+ * string must be manually free'd.
+ *
+ * The `git_path_dirname_r` implementation writes the dirname to a `git_buf`
+ * if the buffer pointer is not NULL.
+ * It returns an error code < 0 if there is an allocation error, otherwise
+ * the length of the dirname (which will be > 0).
+ */
+extern char *git_path_dirname(const char *path);
+extern int git_path_dirname_r(git_buf *buffer, const char *path);
+
+/*
+ * This function returns the basename of the file, which is the last
+ * part of its full name given by fname, with the drive letter and
+ * leading directories stripped off. For example, the basename of
+ * c:/foo/bar/file.ext is file.ext, and the basename of a:foo is foo.
+ *
+ * Trailing slashes and backslashes are significant: the basename of
+ * c:/foo/bar/ is an empty string after the rightmost slash.
+ *
+ * The `git_path_basename` implementation is thread safe. The returned
+ * string must be manually free'd.
+ *
+ * The `git_path_basename_r` implementation writes the basename to a `git_buf`.
+ * It returns an error code < 0 if there is an allocation error, otherwise
+ * the length of the basename (which will be >= 0).
+ */
+extern char *git_path_basename(const char *path);
+extern int git_path_basename_r(git_buf *buffer, const char *path);
+
+/* Return the offset of the start of the basename.  Unlike the other
+ * basename functions, this returns 0 if the path is empty.
+ */
+extern size_t git_path_basename_offset(git_buf *buffer);
+
+extern const char *git_path_topdir(const char *path);
+
+/**
+ * Find offset to root of path if path has one.
+ *
+ * This will return a number >= 0 which is the offset to the start of the
+ * path, if the path is rooted (i.e. "/rooted/path" returns 0 and
+ * "c:/windows/rooted/path" returns 2).  If the path is not rooted, this
+ * returns < 0.
+ */
+extern int git_path_root(const char *path);
+
+/**
+ * Ensure path has a trailing '/'.
+ */
+extern int git_path_to_dir(git_buf *path);
+
+/**
+ * Ensure string has a trailing '/' if there is space for it.
+ */
+extern void git_path_string_to_dir(char* path, size_t size);
+
+/**
+ * Taken from git.git; returns nonzero if the given path is "." or "..".
+ */
+GIT_INLINE(int) git_path_is_dot_or_dotdot(const char *name)
+{
+	return (name[0] == '.' &&
+			  (name[1] == '\0' ||
+				(name[1] == '.' && name[2] == '\0')));
+}
+
+#ifdef GIT_WIN32
+GIT_INLINE(int) git_path_is_dot_or_dotdotW(const wchar_t *name)
+{
+	return (name[0] == L'.' &&
+			  (name[1] == L'\0' ||
+				(name[1] == L'.' && name[2] == L'\0')));
+}
+
+/**
+ * Convert backslashes in path to forward slashes.
+ */
+GIT_INLINE(void) git_path_mkposix(char *path)
+{
+	while (*path) {
+		if (*path == '\\')
+			*path = '/';
+
+		path++;
+	}
+}
+#else
+#	define git_path_mkposix(p) /* blank */
+#endif
+
+/**
+ * Check if string is a relative path (i.e. starts with "./" or "../")
+ */
+GIT_INLINE(int) git_path_is_relative(const char *p)
+{
+	return (p[0] == '.' && (p[1] == '/' || (p[1] == '.' && p[2] == '/')));
+}
+
+/**
+ * Check if string is at end of path segment (i.e. looking at '/' or '\0')
+ */
+GIT_INLINE(int) git_path_at_end_of_segment(const char *p)
+{
+	return !*p || *p == '/';
+}
+
+extern int git__percent_decode(git_buf *decoded_out, const char *input);
+
+/**
+ * Extract path from file:// URL.
+ */
+extern int git_path_fromurl(git_buf *local_path_out, const char *file_url);
+
+
+/**
+ * Path filesystem utils
+ *
+ * These are path utilities that actually access the filesystem.
+ */
+
+/**
+ * Check if a file exists and can be accessed.
+ * @return true or false
+ */
+extern bool git_path_exists(const char *path);
+
+/**
+ * Check if the given path points to a directory.
+ * @return true or false
+ */
+extern bool git_path_isdir(const char *path);
+
+/**
+ * Check if the given path points to a regular file.
+ * @return true or false
+ */
+extern bool git_path_isfile(const char *path);
+
+/**
+ * Check if the given path is a directory, and is empty.
+ */
+extern bool git_path_is_empty_dir(const char *path);
+
+/**
+ * Stat a file and/or link and set error if needed.
+ */
+extern int git_path_lstat(const char *path, struct stat *st);
+
+/**
+ * Check if the parent directory contains the item.
+ *
+ * @param dir Directory to check.
+ * @param item Item that might be in the directory.
+ * @return 0 if item exists in directory, <0 otherwise.
+ */
+extern bool git_path_contains(git_buf *dir, const char *item);
+
+/**
+ * Check if the given path contains the given subdirectory.
+ *
+ * @param parent Directory path that might contain subdir
+ * @param subdir Subdirectory name to look for in parent
+ * @return true if subdirectory exists, false otherwise.
+ */
+extern bool git_path_contains_dir(git_buf *parent, const char *subdir);
+
+/**
+ * Make the path relative to the given parent path.
+ *
+ * @param path The path to make relative
+ * @param parent The parent path to make path relative to
+ * @return 0 if path was made relative, GIT_ENOTFOUND
+ *         if there was not common root between the paths,
+ *         or <0.
+ */
+extern int git_path_make_relative(git_buf *path, const char *parent);
+
+/**
+ * Check if the given path contains the given file.
+ *
+ * @param dir Directory path that might contain file
+ * @param file File name to look for in parent
+ * @return true if file exists, false otherwise.
+ */
+extern bool git_path_contains_file(git_buf *dir, const char *file);
+
+/**
+ * Prepend base to unrooted path or just copy path over.
+ *
+ * This will optionally return the index into the path where the "root"
+ * is, either the end of the base directory prefix or the path root.
+ */
+extern int git_path_join_unrooted(
+	git_buf *path_out, const char *path, const char *base, ssize_t *root_at);
+
+/**
+ * Clean up path, prepending base if it is not already rooted.
+ */
+extern int git_path_prettify(git_buf *path_out, const char *path, const char *base);
+
+/**
+ * Clean up path, prepending base if it is not already rooted and
+ * appending a slash.
+ */
+extern int git_path_prettify_dir(git_buf *path_out, const char *path, const char *base);
+
+/**
+ * Get a directory from a path.
+ *
+ * If path is a directory, this acts like `git_path_prettify_dir`
+ * (cleaning up path and appending a '/').  If path is a normal file,
+ * this prettifies it, then removed the filename a la dirname and
+ * appends the trailing '/'.  If the path does not exist, it is
+ * treated like a regular filename.
+ */
+extern int git_path_find_dir(git_buf *dir, const char *path, const char *base);
+
+/**
+ * Resolve relative references within a path.
+ *
+ * This eliminates "./" and "../" relative references inside a path,
+ * as well as condensing multiple slashes into single ones.  It will
+ * not touch the path before the "ceiling" length.
+ *
+ * Additionally, this will recognize an "c:/" drive prefix or a "xyz://" URL
+ * prefix and not touch that part of the path.
+ */
+extern int git_path_resolve_relative(git_buf *path, size_t ceiling);
+
+/**
+ * Apply a relative path to base path.
+ *
+ * Note that the base path could be a filename or a URL and this
+ * should still work.  The relative path is walked segment by segment
+ * with three rules: series of slashes will be condensed to a single
+ * slash, "." will be eaten with no change, and ".." will remove a
+ * segment from the base path.
+ */
+extern int git_path_apply_relative(git_buf *target, const char *relpath);
+
+enum {
+	GIT_PATH_DIR_IGNORE_CASE = (1u << 0),
+	GIT_PATH_DIR_PRECOMPOSE_UNICODE = (1u << 1),
+	GIT_PATH_DIR_INCLUDE_DOT_AND_DOTDOT = (1u << 2),
+};
+
+/**
+ * Walk each directory entry, except '.' and '..', calling fn(state).
+ *
+ * @param pathbuf Buffer the function reads the initial directory
+ * 		path from, and updates with each successive entry's name.
+ * @param flags Combination of GIT_PATH_DIR flags.
+ * @param callback Callback for each entry. Passed the `payload` and each
+ *		successive path inside the directory as a full path.  This may
+ *		safely append text to the pathbuf if needed.  Return non-zero to
+ *		cancel iteration (and return value will be propagated back).
+ * @param payload Passed to callback as first argument.
+ * @return 0 on success or error code from OS error or from callback
+ */
+extern int git_path_direach(
+	git_buf *pathbuf,
+	uint32_t flags,
+	int (*callback)(void *payload, git_buf *path),
+	void *payload);
+
+/**
+ * Sort function to order two paths
+ */
+extern int git_path_cmp(
+	const char *name1, size_t len1, int isdir1,
+	const char *name2, size_t len2, int isdir2,
+	int (*compare)(const char *, const char *, size_t));
+
+/**
+ * Invoke callback up path directory by directory until the ceiling is
+ * reached (inclusive of a final call at the root_path).
+ *
+ * Returning anything other than 0 from the callback function
+ * will stop the iteration and propagate the error to the caller.
+ *
+ * @param pathbuf Buffer the function reads the directory from and
+ *		and updates with each successive name.
+ * @param ceiling Prefix of path at which to stop walking up.  If NULL,
+ *		this will walk all the way up to the root.  If not a prefix of
+ *		pathbuf, the callback will be invoked a single time on the
+ *		original input path.
+ * @param callback Function to invoke on each path.  Passed the `payload`
+ *		and the buffer containing the current path.  The path should not
+ *		be modified in any way. Return non-zero to stop iteration.
+ * @param payload Passed to fn as the first ath.
+ */
+extern int git_path_walk_up(
+	git_buf *pathbuf,
+	const char *ceiling,
+	int (*callback)(void *payload, const char *path),
+	void *payload);
+
+
+enum { GIT_PATH_NOTEQUAL = 0, GIT_PATH_EQUAL = 1, GIT_PATH_PREFIX = 2 };
+
+/*
+ * Determines if a path is equal to or potentially a child of another.
+ * @param parent The possible parent
+ * @param child The possible child
+ */
+GIT_INLINE(int) git_path_equal_or_prefixed(
+	const char *parent,
+	const char *child,
+	ssize_t *prefixlen)
+{
+	const char *p = parent, *c = child;
+	int lastslash = 0;
+
+	while (*p && *c) {
+		lastslash = (*p == '/');
+
+		if (*p++ != *c++)
+			return GIT_PATH_NOTEQUAL;
+	}
+
+	if (*p != '\0')
+		return GIT_PATH_NOTEQUAL;
+
+	if (*c == '\0') {
+		if (prefixlen)
+			*prefixlen = p - parent;
+
+		return GIT_PATH_EQUAL;
+	}
+
+	if (*c == '/' || lastslash) {
+		if (prefixlen)
+			*prefixlen = (p - parent) - lastslash;
+
+		return GIT_PATH_PREFIX;
+	}
+
+	return GIT_PATH_NOTEQUAL;
+}
+
+/* translate errno to libgit2 error code and set error message */
+extern int git_path_set_error(
+	int errno_value, const char *path, const char *action);
+
+/* check if non-ascii characters are present in filename */
+extern bool git_path_has_non_ascii(const char *path, size_t pathlen);
+
+#define GIT_PATH_REPO_ENCODING "UTF-8"
+
+#ifdef __APPLE__
+#define GIT_PATH_NATIVE_ENCODING "UTF-8-MAC"
+#else
+#define GIT_PATH_NATIVE_ENCODING "UTF-8"
+#endif
+
+#ifdef GIT_USE_ICONV
+
+#include <iconv.h>
+
+typedef struct {
+	iconv_t map;
+	git_buf buf;
+} git_path_iconv_t;
+
+#define GIT_PATH_ICONV_INIT { (iconv_t)-1, GIT_BUF_INIT }
+
+/* Init iconv data for converting decomposed UTF-8 to precomposed */
+extern int git_path_iconv_init_precompose(git_path_iconv_t *ic);
+
+/* Clear allocated iconv data */
+extern void git_path_iconv_clear(git_path_iconv_t *ic);
+
+/*
+ * Rewrite `in` buffer using iconv map if necessary, replacing `in`
+ * pointer internal iconv buffer if rewrite happened.  The `in` pointer
+ * will be left unchanged if no rewrite was needed.
+ */
+extern int git_path_iconv(git_path_iconv_t *ic, const char **in, size_t *inlen);
+
+#endif /* GIT_USE_ICONV */
+
+extern bool git_path_does_fs_decompose_unicode(const char *root);
+
+
+typedef struct git_path_diriter git_path_diriter;
+
+#if defined(GIT_WIN32) && !defined(__MINGW32__)
+
+struct git_path_diriter
+{
+	git_win32_path path;
+	size_t parent_len;
+
+	git_buf path_utf8;
+	size_t parent_utf8_len;
+
+	HANDLE handle;
+
+	unsigned int flags;
+
+	WIN32_FIND_DATAW current;
+	unsigned int needs_next;
+};
+
+#define GIT_PATH_DIRITER_INIT { {0}, 0, GIT_BUF_INIT, 0, INVALID_HANDLE_VALUE }
+
+#else
+
+struct git_path_diriter
+{
+	git_buf path;
+	size_t parent_len;
+
+	unsigned int flags;
+
+	DIR *dir;
+
+#ifdef GIT_USE_ICONV
+	git_path_iconv_t ic;
+#endif
+};
+
+#define GIT_PATH_DIRITER_INIT { GIT_BUF_INIT }
+
+#endif
+
+/**
+ * Initialize a directory iterator.
+ *
+ * @param diriter Pointer to a diriter structure that will be setup.
+ * @param path The path that will be iterated over
+ * @param flags Directory reader flags
+ * @return 0 or an error code
+ */
+extern int git_path_diriter_init(
+	git_path_diriter *diriter,
+	const char *path,
+	unsigned int flags);
+
+/**
+ * Advance the directory iterator.  Will return GIT_ITEROVER when
+ * the iteration has completed successfully.
+ *
+ * @param diriter The directory iterator
+ * @return 0, GIT_ITEROVER, or an error code
+ */
+extern int git_path_diriter_next(git_path_diriter *diriter);
+
+/**
+ * Returns the file name of the current item in the iterator.
+ *
+ * @param out Pointer to store the path in
+ * @param out_len Pointer to store the length of the path in
+ * @param diriter The directory iterator
+ * @return 0 or an error code
+ */
+extern int git_path_diriter_filename(
+	const char **out,
+	size_t *out_len,
+	git_path_diriter *diriter);
+
+/**
+ * Returns the full path of the current item in the iterator; that
+ * is the current filename plus the path of the directory that the
+ * iterator was constructed with.
+ *
+ * @param out Pointer to store the path in
+ * @param out_len Pointer to store the length of the path in
+ * @param diriter The directory iterator
+ * @return 0 or an error code
+ */
+extern int git_path_diriter_fullpath(
+	const char **out,
+	size_t *out_len,
+	git_path_diriter *diriter);
+
+/**
+ * Performs an `lstat` on the current item in the iterator.
+ *
+ * @param out Pointer to store the stat data in
+ * @param diriter The directory iterator
+ * @return 0 or an error code
+ */
+extern int git_path_diriter_stat(struct stat *out, git_path_diriter *diriter);
+
+/**
+ * Closes the directory iterator.
+ *
+ * @param diriter The directory iterator
+ */
+extern void git_path_diriter_free(git_path_diriter *diriter);
+
+/**
+ * Load all directory entries (except '.' and '..') into a vector.
+ *
+ * For cases where `git_path_direach()` is not appropriate, this
+ * allows you to load the filenames in a directory into a vector
+ * of strings. That vector can then be sorted, iterated, or whatever.
+ * Remember to free alloc of the allocated strings when you are done.
+ *
+ * @param contents Vector to fill with directory entry names.
+ * @param path The directory to read from.
+ * @param prefix_len When inserting entries, the trailing part of path
+ * 		will be prefixed after this length.  I.e. given path "/a/b" and
+ * 		prefix_len 3, the entries will look like "b/e1", "b/e2", etc.
+ * @param flags Combination of GIT_PATH_DIR flags.
+ */
+extern int git_path_dirload(
+	git_vector *contents,
+	const char *path,
+	size_t prefix_len,
+	uint32_t flags);
+
+
+/* Used for paths to repositories on the filesystem */
+extern bool git_path_is_local_file_url(const char *file_url);
+extern int git_path_from_url_or_path(git_buf *local_path_out, const char *url_or_path);
+
+/* Flags to determine path validity in `git_path_isvalid` */
+#define GIT_PATH_REJECT_TRAVERSAL          (1 << 0)
+#define GIT_PATH_REJECT_DOT_GIT            (1 << 1)
+#define GIT_PATH_REJECT_SLASH              (1 << 2)
+#define GIT_PATH_REJECT_BACKSLASH          (1 << 3)
+#define GIT_PATH_REJECT_TRAILING_DOT       (1 << 4)
+#define GIT_PATH_REJECT_TRAILING_SPACE     (1 << 5)
+#define GIT_PATH_REJECT_TRAILING_COLON     (1 << 6)
+#define GIT_PATH_REJECT_DOS_PATHS          (1 << 7)
+#define GIT_PATH_REJECT_NT_CHARS           (1 << 8)
+#define GIT_PATH_REJECT_DOT_GIT_HFS        (1 << 9)
+#define GIT_PATH_REJECT_DOT_GIT_NTFS       (1 << 10)
+
+/* Default path safety for writing files to disk: since we use the
+ * Win32 "File Namespace" APIs ("\\?\") we need to protect from
+ * paths that the normal Win32 APIs would not write.
+ */
+#ifdef GIT_WIN32
+# define GIT_PATH_REJECT_DEFAULTS \
+	GIT_PATH_REJECT_TRAVERSAL | \
+	GIT_PATH_REJECT_BACKSLASH | \
+	GIT_PATH_REJECT_TRAILING_DOT | \
+	GIT_PATH_REJECT_TRAILING_SPACE | \
+	GIT_PATH_REJECT_TRAILING_COLON | \
+	GIT_PATH_REJECT_DOS_PATHS | \
+	GIT_PATH_REJECT_NT_CHARS
+#else
+# define GIT_PATH_REJECT_DEFAULTS GIT_PATH_REJECT_TRAVERSAL
+#endif
+
+/*
+ * Determine whether a path is a valid git path or not - this must not contain
+ * a '.' or '..' component, or a component that is ".git" (in any case).
+ *
+ * `repo` is optional.  If specified, it will be used to determine the short
+ * path name to reject (if `GIT_PATH_REJECT_DOS_SHORTNAME` is specified),
+ * in addition to the default of "git~1".
+ */
+extern bool git_path_isvalid(
+	git_repository *repo,
+	const char *path,
+	unsigned int flags);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pathspec.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pathspec.c
new file mode 100755
index 0000000..fab6f9a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pathspec.c
@@ -0,0 +1,725 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2/pathspec.h"
+#include "git2/diff.h"
+#include "pathspec.h"
+#include "buf_text.h"
+#include "attr_file.h"
+#include "iterator.h"
+#include "repository.h"
+#include "index.h"
+#include "bitvec.h"
+#include "diff.h"
+
+/* what is the common non-wildcard prefix for all items in the pathspec */
+char *git_pathspec_prefix(const git_strarray *pathspec)
+{
+	git_buf prefix = GIT_BUF_INIT;
+	const char *scan;
+
+	if (!pathspec || !pathspec->count ||
+		git_buf_text_common_prefix(&prefix, pathspec) < 0)
+		return NULL;
+
+	/* diff prefix will only be leading non-wildcards */
+	for (scan = prefix.ptr; *scan; ++scan) {
+		if (git__iswildcard(*scan) &&
+			(scan == prefix.ptr || (*(scan - 1) != '\\')))
+			break;
+	}
+	git_buf_truncate(&prefix, scan - prefix.ptr);
+
+	if (prefix.size <= 0) {
+		git_buf_free(&prefix);
+		return NULL;
+	}
+
+	git_buf_text_unescape(&prefix);
+
+	return git_buf_detach(&prefix);
+}
+
+/* is there anything in the spec that needs to be filtered on */
+bool git_pathspec_is_empty(const git_strarray *pathspec)
+{
+	size_t i;
+
+	if (pathspec == NULL)
+		return true;
+
+	for (i = 0; i < pathspec->count; ++i) {
+		const char *str = pathspec->strings[i];
+
+		if (str && str[0])
+			return false;
+	}
+
+	return true;
+}
+
+/* build a vector of fnmatch patterns to evaluate efficiently */
+int git_pathspec__vinit(
+	git_vector *vspec, const git_strarray *strspec, git_pool *strpool)
+{
+	size_t i;
+
+	memset(vspec, 0, sizeof(*vspec));
+
+	if (git_pathspec_is_empty(strspec))
+		return 0;
+
+	if (git_vector_init(vspec, strspec->count, NULL) < 0)
+		return -1;
+
+	for (i = 0; i < strspec->count; ++i) {
+		int ret;
+		const char *pattern = strspec->strings[i];
+		git_attr_fnmatch *match = git__calloc(1, sizeof(git_attr_fnmatch));
+		if (!match)
+			return -1;
+
+		match->flags = GIT_ATTR_FNMATCH_ALLOWSPACE |
+			GIT_ATTR_FNMATCH_ALLOWNEG | GIT_ATTR_FNMATCH_NOLEADINGDIR;
+
+		ret = git_attr_fnmatch__parse(match, strpool, NULL, &pattern);
+		if (ret == GIT_ENOTFOUND) {
+			git__free(match);
+			continue;
+		} else if (ret < 0) {
+			git__free(match);
+			return ret;
+		}
+
+		if (git_vector_insert(vspec, match) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
+/* free data from the pathspec vector */
+void git_pathspec__vfree(git_vector *vspec)
+{
+	git_vector_free_deep(vspec);
+}
+
+struct pathspec_match_context {
+	int fnmatch_flags;
+	int (*strcomp)(const char *, const char *);
+	int (*strncomp)(const char *, const char *, size_t);
+};
+
+static void pathspec_match_context_init(
+	struct pathspec_match_context *ctxt,
+	bool disable_fnmatch,
+	bool casefold)
+{
+	if (disable_fnmatch)
+		ctxt->fnmatch_flags = -1;
+	else if (casefold)
+		ctxt->fnmatch_flags = FNM_CASEFOLD;
+	else
+		ctxt->fnmatch_flags = 0;
+
+	if (casefold) {
+		ctxt->strcomp  = git__strcasecmp;
+		ctxt->strncomp = git__strncasecmp;
+	} else {
+		ctxt->strcomp  = git__strcmp;
+		ctxt->strncomp = git__strncmp;
+	}
+}
+
+static int pathspec_match_one(
+	const git_attr_fnmatch *match,
+	struct pathspec_match_context *ctxt,
+	const char *path)
+{
+	int result = (match->flags & GIT_ATTR_FNMATCH_MATCH_ALL) ? 0 : FNM_NOMATCH;
+
+	if (result == FNM_NOMATCH)
+		result = ctxt->strcomp(match->pattern, path) ? FNM_NOMATCH : 0;
+
+	if (ctxt->fnmatch_flags >= 0 && result == FNM_NOMATCH)
+		result = p_fnmatch(match->pattern, path, ctxt->fnmatch_flags);
+
+	/* if we didn't match, look for exact dirname prefix match */
+	if (result == FNM_NOMATCH &&
+		(match->flags & GIT_ATTR_FNMATCH_HASWILD) == 0 &&
+		ctxt->strncomp(path, match->pattern, match->length) == 0 &&
+		path[match->length] == '/')
+		result = 0;
+
+	/* if we didn't match and this is a negative match, check for exact
+	 * match of filename with leading '!'
+	 */
+	if (result == FNM_NOMATCH &&
+		(match->flags & GIT_ATTR_FNMATCH_NEGATIVE) != 0 &&
+		*path == '!' &&
+		ctxt->strncomp(path + 1, match->pattern, match->length) == 0 &&
+		(!path[match->length + 1] || path[match->length + 1] == '/'))
+		return 1;
+
+	if (result == 0)
+		return (match->flags & GIT_ATTR_FNMATCH_NEGATIVE) ? 0 : 1;
+	return -1;
+}
+
+static int git_pathspec__match_at(
+	size_t *matched_at,
+	const git_vector *vspec,
+	struct pathspec_match_context *ctxt,
+	const char *path0,
+	const char *path1)
+{
+	int result = GIT_ENOTFOUND;
+	size_t i = 0;
+	const git_attr_fnmatch *match;
+
+	git_vector_foreach(vspec, i, match) {
+		if (path0 && (result = pathspec_match_one(match, ctxt, path0)) >= 0)
+			break;
+		if (path1 && (result = pathspec_match_one(match, ctxt, path1)) >= 0)
+			break;
+	}
+
+	*matched_at = i;
+	return result;
+}
+
+/* match a path against the vectorized pathspec */
+bool git_pathspec__match(
+	const git_vector *vspec,
+	const char *path,
+	bool disable_fnmatch,
+	bool casefold,
+	const char **matched_pathspec,
+	size_t *matched_at)
+{
+	int result;
+	size_t pos;
+	struct pathspec_match_context ctxt;
+
+	if (matched_pathspec)
+		*matched_pathspec = NULL;
+	if (matched_at)
+		*matched_at = GIT_PATHSPEC_NOMATCH;
+
+	if (!vspec || !vspec->length)
+		return true;
+
+	pathspec_match_context_init(&ctxt, disable_fnmatch, casefold);
+
+	result = git_pathspec__match_at(&pos, vspec, &ctxt, path, NULL);
+	if (result >= 0) {
+		if (matched_pathspec) {
+			const git_attr_fnmatch *match = git_vector_get(vspec, pos);
+			*matched_pathspec = match->pattern;
+		}
+
+		if (matched_at)
+			*matched_at = pos;
+	}
+
+	return (result > 0);
+}
+
+
+int git_pathspec__init(git_pathspec *ps, const git_strarray *paths)
+{
+	int error = 0;
+
+	memset(ps, 0, sizeof(*ps));
+
+	ps->prefix = git_pathspec_prefix(paths);
+
+	if ((error = git_pool_init(&ps->pool, 1, 0)) < 0 ||
+		(error = git_pathspec__vinit(&ps->pathspec, paths, &ps->pool)) < 0)
+		git_pathspec__clear(ps);
+
+	return error;
+}
+
+void git_pathspec__clear(git_pathspec *ps)
+{
+	git__free(ps->prefix);
+	git_pathspec__vfree(&ps->pathspec);
+	git_pool_clear(&ps->pool);
+	memset(ps, 0, sizeof(*ps));
+}
+
+int git_pathspec_new(git_pathspec **out, const git_strarray *pathspec)
+{
+	int error = 0;
+	git_pathspec *ps = git__malloc(sizeof(git_pathspec));
+	GITERR_CHECK_ALLOC(ps);
+
+	if ((error = git_pathspec__init(ps, pathspec)) < 0) {
+		git__free(ps);
+		return error;
+	}
+
+	GIT_REFCOUNT_INC(ps);
+	*out = ps;
+	return 0;
+}
+
+static void pathspec_free(git_pathspec *ps)
+{
+	git_pathspec__clear(ps);
+	git__free(ps);
+}
+
+void git_pathspec_free(git_pathspec *ps)
+{
+	if (!ps)
+		return;
+	GIT_REFCOUNT_DEC(ps, pathspec_free);
+}
+
+int git_pathspec_matches_path(
+	const git_pathspec *ps, uint32_t flags, const char *path)
+{
+	bool no_fnmatch = (flags & GIT_PATHSPEC_NO_GLOB) != 0;
+	bool casefold =  (flags & GIT_PATHSPEC_IGNORE_CASE) != 0;
+
+	assert(ps && path);
+
+	return (0 != git_pathspec__match(
+		&ps->pathspec, path, no_fnmatch, casefold, NULL, NULL));
+}
+
+static void pathspec_match_free(git_pathspec_match_list *m)
+{
+	if (!m)
+		return;
+
+	git_pathspec_free(m->pathspec);
+	m->pathspec = NULL;
+
+	git_array_clear(m->matches);
+	git_array_clear(m->failures);
+	git_pool_clear(&m->pool);
+	git__free(m);
+}
+
+static git_pathspec_match_list *pathspec_match_alloc(
+	git_pathspec *ps, int datatype)
+{
+	git_pathspec_match_list *m = git__calloc(1, sizeof(git_pathspec_match_list));
+
+	if (m != NULL && git_pool_init(&m->pool, 1, 0) < 0) {
+		pathspec_match_free(m);
+		m = NULL;
+	}
+
+	if (!m)
+		return NULL;
+
+	/* need to keep reference to pathspec and increment refcount because
+	 * failures array stores pointers to the pattern strings of the
+	 * pathspec that had no matches
+	 */
+	GIT_REFCOUNT_INC(ps);
+	m->pathspec = ps;
+	m->datatype = datatype;
+
+	return m;
+}
+
+GIT_INLINE(size_t) pathspec_mark_pattern(git_bitvec *used, size_t pos)
+{
+	if (!git_bitvec_get(used, pos)) {
+		git_bitvec_set(used, pos, true);
+		return 1;
+	}
+
+	return 0;
+}
+
+static size_t pathspec_mark_remaining(
+	git_bitvec *used,
+	git_vector *patterns,
+	struct pathspec_match_context *ctxt,
+	size_t start,
+	const char *path0,
+	const char *path1)
+{
+	size_t count = 0;
+
+	if (path1 == path0)
+		path1 = NULL;
+
+	for (; start < patterns->length; ++start) {
+		const git_attr_fnmatch *pat = git_vector_get(patterns, start);
+
+		if (git_bitvec_get(used, start))
+			continue;
+
+		if (path0 && pathspec_match_one(pat, ctxt, path0) > 0)
+			count += pathspec_mark_pattern(used, start);
+		else if (path1 && pathspec_match_one(pat, ctxt, path1) > 0)
+			count += pathspec_mark_pattern(used, start);
+	}
+
+	return count;
+}
+
+static int pathspec_build_failure_array(
+	git_pathspec_string_array_t *failures,
+	git_vector *patterns,
+	git_bitvec *used,
+	git_pool *pool)
+{
+	size_t pos;
+	char **failed;
+	const git_attr_fnmatch *pat;
+
+	for (pos = 0; pos < patterns->length; ++pos) {
+		if (git_bitvec_get(used, pos))
+			continue;
+
+		if ((failed = git_array_alloc(*failures)) == NULL)
+			return -1;
+
+		pat = git_vector_get(patterns, pos);
+
+		if ((*failed = git_pool_strdup(pool, pat->pattern)) == NULL)
+			return -1;
+	}
+
+	return 0;
+}
+
+static int pathspec_match_from_iterator(
+	git_pathspec_match_list **out,
+	git_iterator *iter,
+	uint32_t flags,
+	git_pathspec *ps)
+{
+	int error = 0;
+	git_pathspec_match_list *m = NULL;
+	const git_index_entry *entry = NULL;
+	struct pathspec_match_context ctxt;
+	git_vector *patterns = &ps->pathspec;
+	bool find_failures = out && (flags & GIT_PATHSPEC_FIND_FAILURES) != 0;
+	bool failures_only = !out || (flags & GIT_PATHSPEC_FAILURES_ONLY) != 0;
+	size_t pos, used_ct = 0, found_files = 0;
+	git_index *index = NULL;
+	git_bitvec used_patterns;
+	char **file;
+
+	if (git_bitvec_init(&used_patterns, patterns->length) < 0)
+		return -1;
+
+	if (out) {
+		*out = m = pathspec_match_alloc(ps, PATHSPEC_DATATYPE_STRINGS);
+		GITERR_CHECK_ALLOC(m);
+	}
+
+	if ((error = git_iterator_reset(iter, ps->prefix, ps->prefix)) < 0)
+		goto done;
+
+	if (git_iterator_type(iter) == GIT_ITERATOR_TYPE_WORKDIR &&
+		(error = git_repository_index__weakptr(
+			&index, git_iterator_owner(iter))) < 0)
+		goto done;
+
+	pathspec_match_context_init(
+		&ctxt, (flags & GIT_PATHSPEC_NO_GLOB) != 0,
+		git_iterator_ignore_case(iter));
+
+	while (!(error = git_iterator_advance(&entry, iter))) {
+		/* search for match with entry->path */
+		int result = git_pathspec__match_at(
+			&pos, patterns, &ctxt, entry->path, NULL);
+
+		/* no matches for this path */
+		if (result < 0)
+			continue;
+
+		/* if result was a negative pattern match, then don't list file */
+		if (!result) {
+			used_ct += pathspec_mark_pattern(&used_patterns, pos);
+			continue;
+		}
+
+		/* check if path is ignored and untracked */
+		if (index != NULL &&
+			git_iterator_current_is_ignored(iter) &&
+			git_index__find_pos(NULL, index, entry->path, 0, GIT_INDEX_STAGE_ANY) < 0)
+			continue;
+
+		/* mark the matched pattern as used */
+		used_ct += pathspec_mark_pattern(&used_patterns, pos);
+		++found_files;
+
+		/* if find_failures is on, check if any later patterns also match */
+		if (find_failures && used_ct < patterns->length)
+			used_ct += pathspec_mark_remaining(
+				&used_patterns, patterns, &ctxt, pos + 1, entry->path, NULL);
+
+		/* if only looking at failures, exit early or just continue */
+		if (failures_only || !out) {
+			if (used_ct == patterns->length)
+				break;
+			continue;
+		}
+
+		/* insert matched path into matches array */
+		if ((file = (char **)git_array_alloc(m->matches)) == NULL ||
+			(*file = git_pool_strdup(&m->pool, entry->path)) == NULL) {
+			error = -1;
+			goto done;
+		}
+	}
+
+	if (error < 0 && error != GIT_ITEROVER)
+		goto done;
+	error = 0;
+
+	/* insert patterns that had no matches into failures array */
+	if (find_failures && used_ct < patterns->length &&
+		(error = pathspec_build_failure_array(
+			&m->failures, patterns, &used_patterns, &m->pool)) < 0)
+		goto done;
+
+	/* if every pattern failed to match, then we have failed */
+	if ((flags & GIT_PATHSPEC_NO_MATCH_ERROR) != 0 && !found_files) {
+		giterr_set(GITERR_INVALID, "No matching files were found");
+		error = GIT_ENOTFOUND;
+	}
+
+done:
+	git_bitvec_free(&used_patterns);
+
+	if (error < 0) {
+		pathspec_match_free(m);
+		if (out) *out = NULL;
+	}
+
+	return error;
+}
+
+static git_iterator_flag_t pathspec_match_iter_flags(uint32_t flags)
+{
+	git_iterator_flag_t f = 0;
+
+	if ((flags & GIT_PATHSPEC_IGNORE_CASE) != 0)
+		f |= GIT_ITERATOR_IGNORE_CASE;
+	else if ((flags & GIT_PATHSPEC_USE_CASE) != 0)
+		f |= GIT_ITERATOR_DONT_IGNORE_CASE;
+
+	return f;
+}
+
+int git_pathspec_match_workdir(
+	git_pathspec_match_list **out,
+	git_repository *repo,
+	uint32_t flags,
+	git_pathspec *ps)
+{
+	int error = 0;
+	git_iterator *iter;
+
+	assert(repo);
+
+	if (!(error = git_iterator_for_workdir(
+			&iter, repo, NULL, NULL, pathspec_match_iter_flags(flags), NULL, NULL))) {
+
+		error = pathspec_match_from_iterator(out, iter, flags, ps);
+
+		git_iterator_free(iter);
+	}
+
+	return error;
+}
+
+int git_pathspec_match_index(
+	git_pathspec_match_list **out,
+	git_index *index,
+	uint32_t flags,
+	git_pathspec *ps)
+{
+	int error = 0;
+	git_iterator *iter;
+
+	assert(index);
+
+	if (!(error = git_iterator_for_index(
+			&iter, index, pathspec_match_iter_flags(flags), NULL, NULL))) {
+
+		error = pathspec_match_from_iterator(out, iter, flags, ps);
+
+		git_iterator_free(iter);
+	}
+
+	return error;
+}
+
+int git_pathspec_match_tree(
+	git_pathspec_match_list **out,
+	git_tree *tree,
+	uint32_t flags,
+	git_pathspec *ps)
+{
+	int error = 0;
+	git_iterator *iter;
+
+	assert(tree);
+
+	if (!(error = git_iterator_for_tree(
+			&iter, tree, pathspec_match_iter_flags(flags), NULL, NULL))) {
+
+		error = pathspec_match_from_iterator(out, iter, flags, ps);
+
+		git_iterator_free(iter);
+	}
+
+	return error;
+}
+
+int git_pathspec_match_diff(
+	git_pathspec_match_list **out,
+	git_diff *diff,
+	uint32_t flags,
+	git_pathspec *ps)
+{
+	int error = 0;
+	git_pathspec_match_list *m = NULL;
+	struct pathspec_match_context ctxt;
+	git_vector *patterns = &ps->pathspec;
+	bool find_failures = out && (flags & GIT_PATHSPEC_FIND_FAILURES) != 0;
+	bool failures_only = !out || (flags & GIT_PATHSPEC_FAILURES_ONLY) != 0;
+	size_t i, pos, used_ct = 0, found_deltas = 0;
+	const git_diff_delta *delta, **match;
+	git_bitvec used_patterns;
+
+	assert(diff);
+
+	if (git_bitvec_init(&used_patterns, patterns->length) < 0)
+		return -1;
+
+	if (out) {
+		*out = m = pathspec_match_alloc(ps, PATHSPEC_DATATYPE_DIFF);
+		GITERR_CHECK_ALLOC(m);
+	}
+
+	pathspec_match_context_init(
+		&ctxt, (flags & GIT_PATHSPEC_NO_GLOB) != 0,
+		git_diff_is_sorted_icase(diff));
+
+	git_vector_foreach(&diff->deltas, i, delta) {
+		/* search for match with delta */
+		int result = git_pathspec__match_at(
+			&pos, patterns, &ctxt, delta->old_file.path, delta->new_file.path);
+
+		/* no matches for this path */
+		if (result < 0)
+			continue;
+
+		/* mark the matched pattern as used */
+		used_ct += pathspec_mark_pattern(&used_patterns, pos);
+
+		/* if result was a negative pattern match, then don't list file */
+		if (!result)
+			continue;
+
+		++found_deltas;
+
+		/* if find_failures is on, check if any later patterns also match */
+		if (find_failures && used_ct < patterns->length)
+			used_ct += pathspec_mark_remaining(
+				&used_patterns, patterns, &ctxt, pos + 1,
+				delta->old_file.path, delta->new_file.path);
+
+		/* if only looking at failures, exit early or just continue */
+		if (failures_only || !out) {
+			if (used_ct == patterns->length)
+				break;
+			continue;
+		}
+
+		/* insert matched delta into matches array */
+		if (!(match = (const git_diff_delta **)git_array_alloc(m->matches))) {
+			error = -1;
+			goto done;
+		} else {
+			*match = delta;
+		}
+	}
+
+	/* insert patterns that had no matches into failures array */
+	if (find_failures && used_ct < patterns->length &&
+		(error = pathspec_build_failure_array(
+			&m->failures, patterns, &used_patterns, &m->pool)) < 0)
+		goto done;
+
+	/* if every pattern failed to match, then we have failed */
+	if ((flags & GIT_PATHSPEC_NO_MATCH_ERROR) != 0 && !found_deltas) {
+		giterr_set(GITERR_INVALID, "No matching deltas were found");
+		error = GIT_ENOTFOUND;
+	}
+
+done:
+	git_bitvec_free(&used_patterns);
+
+	if (error < 0) {
+		pathspec_match_free(m);
+		if (out) *out = NULL;
+	}
+
+	return error;
+}
+
+void git_pathspec_match_list_free(git_pathspec_match_list *m)
+{
+	if (m)
+		pathspec_match_free(m);
+}
+
+size_t git_pathspec_match_list_entrycount(
+	const git_pathspec_match_list *m)
+{
+	return m ? git_array_size(m->matches) : 0;
+}
+
+const char *git_pathspec_match_list_entry(
+	const git_pathspec_match_list *m, size_t pos)
+{
+	if (!m || m->datatype != PATHSPEC_DATATYPE_STRINGS ||
+		!git_array_valid_index(m->matches, pos))
+		return NULL;
+
+	return *((const char **)git_array_get(m->matches, pos));
+}
+
+const git_diff_delta *git_pathspec_match_list_diff_entry(
+	const git_pathspec_match_list *m, size_t pos)
+{
+	if (!m || m->datatype != PATHSPEC_DATATYPE_DIFF ||
+		!git_array_valid_index(m->matches, pos))
+		return NULL;
+
+	return *((const git_diff_delta **)git_array_get(m->matches, pos));
+}
+
+size_t git_pathspec_match_list_failed_entrycount(
+	const git_pathspec_match_list *m)
+{
+	return m ? git_array_size(m->failures) : 0;
+}
+
+const char * git_pathspec_match_list_failed_entry(
+	const git_pathspec_match_list *m, size_t pos)
+{
+	char **entry = m ? git_array_get(m->failures, pos) : NULL;
+
+	return entry ? *entry : NULL;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pathspec.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pathspec.h
new file mode 100755
index 0000000..40cd21c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pathspec.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_pathspec_h__
+#define INCLUDE_pathspec_h__
+
+#include "common.h"
+#include <git2/pathspec.h>
+#include "buffer.h"
+#include "vector.h"
+#include "pool.h"
+#include "array.h"
+
+/* public compiled pathspec */
+struct git_pathspec {
+	git_refcount rc;
+	char *prefix;
+	git_vector pathspec;
+	git_pool pool;
+};
+
+enum {
+	PATHSPEC_DATATYPE_STRINGS = 0,
+	PATHSPEC_DATATYPE_DIFF = 1,
+};
+
+typedef git_array_t(char *) git_pathspec_string_array_t;
+
+/* public interface to pathspec matching */
+struct git_pathspec_match_list {
+	git_pathspec *pathspec;
+	git_array_t(void *) matches;
+	git_pathspec_string_array_t failures;
+	git_pool pool;
+	int datatype;
+};
+
+/* what is the common non-wildcard prefix for all items in the pathspec */
+extern char *git_pathspec_prefix(const git_strarray *pathspec);
+
+/* is there anything in the spec that needs to be filtered on */
+extern bool git_pathspec_is_empty(const git_strarray *pathspec);
+
+/* build a vector of fnmatch patterns to evaluate efficiently */
+extern int git_pathspec__vinit(
+	git_vector *vspec, const git_strarray *strspec, git_pool *strpool);
+
+/* free data from the pathspec vector */
+extern void git_pathspec__vfree(git_vector *vspec);
+
+#define GIT_PATHSPEC_NOMATCH ((size_t)-1)
+
+/*
+ * Match a path against the vectorized pathspec.
+ * The matched pathspec is passed back into the `matched_pathspec` parameter,
+ * unless it is passed as NULL by the caller.
+ */
+extern bool git_pathspec__match(
+	const git_vector *vspec,
+	const char *path,
+	bool disable_fnmatch,
+	bool casefold,
+	const char **matched_pathspec,
+	size_t *matched_at);
+
+/* easy pathspec setup */
+
+extern int git_pathspec__init(git_pathspec *ps, const git_strarray *paths);
+
+extern void git_pathspec__clear(git_pathspec *ps);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pool.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pool.c
new file mode 100755
index 0000000..c93d781
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pool.c
@@ -0,0 +1,325 @@
+#include "pool.h"
+#include "posix.h"
+#ifndef GIT_WIN32
+#include <unistd.h>
+#endif
+
+struct git_pool_page {
+	git_pool_page *next;
+	uint32_t size;
+	uint32_t avail;
+	GIT_ALIGN(char data[GIT_FLEX_ARRAY], 8);
+};
+
+struct pool_freelist {
+	struct pool_freelist *next;
+};
+
+#define GIT_POOL_MIN_USABLE	4
+#define GIT_POOL_MIN_PAGESZ	2 * sizeof(void*)
+
+static void *pool_alloc_page(git_pool *pool, uint32_t size);
+static void pool_insert_page(git_pool *pool, git_pool_page *page);
+
+int git_pool_init(
+	git_pool *pool, uint32_t item_size, uint32_t items_per_page)
+{
+	assert(pool);
+
+	if (!item_size)
+		item_size = 1;
+	/* round up item_size for decent object alignment */
+	if (item_size > 4)
+		item_size = (item_size + 7) & ~7;
+	else if (item_size == 3)
+		item_size = 4;
+
+	if (!items_per_page)
+		items_per_page = git_pool__suggest_items_per_page(item_size);
+	if (item_size * items_per_page < GIT_POOL_MIN_PAGESZ)
+		items_per_page = (GIT_POOL_MIN_PAGESZ + item_size - 1) / item_size;
+
+	memset(pool, 0, sizeof(git_pool));
+	pool->item_size = item_size;
+	pool->page_size = item_size * items_per_page;
+
+	return 0;
+}
+
+void git_pool_clear(git_pool *pool)
+{
+	git_pool_page *scan, *next;
+
+	for (scan = pool->open; scan != NULL; scan = next) {
+		next = scan->next;
+		git__free(scan);
+	}
+	pool->open = NULL;
+
+	for (scan = pool->full; scan != NULL; scan = next) {
+		next = scan->next;
+		git__free(scan);
+	}
+	pool->full = NULL;
+
+	pool->free_list = NULL;
+
+	pool->items = 0;
+
+	pool->has_string_alloc     = 0;
+	pool->has_multi_item_alloc = 0;
+	pool->has_large_page_alloc = 0;
+}
+
+void git_pool_swap(git_pool *a, git_pool *b)
+{
+	git_pool temp;
+
+	if (a == b)
+		return;
+
+	memcpy(&temp, a, sizeof(temp));
+	memcpy(a, b, sizeof(temp));
+	memcpy(b, &temp, sizeof(temp));
+}
+
+static void pool_insert_page(git_pool *pool, git_pool_page *page)
+{
+	git_pool_page *scan;
+
+	/* If there are no open pages or this page has the most open space,
+	 * insert it at the beginning of the list.  This is the common case.
+	 */
+	if (pool->open == NULL || pool->open->avail < page->avail) {
+		page->next = pool->open;
+		pool->open = page;
+		return;
+	}
+
+	/* Otherwise insert into sorted position. */
+	for (scan = pool->open;
+		 scan->next && scan->next->avail > page->avail;
+		 scan = scan->next);
+	page->next = scan->next;
+	scan->next = page;
+}
+
+static void *pool_alloc_page(git_pool *pool, uint32_t size)
+{
+	git_pool_page *page;
+	uint32_t new_page_size;
+	size_t alloc_size;
+
+	if (size <= pool->page_size)
+		new_page_size = pool->page_size;
+	else {
+		new_page_size = size;
+		pool->has_large_page_alloc = 1;
+	}
+
+	if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, new_page_size, sizeof(git_pool_page)) ||
+		!(page = git__calloc(1, alloc_size)))
+		return NULL;
+
+	page->size  = new_page_size;
+	page->avail = new_page_size - size;
+
+	if (page->avail > 0)
+		pool_insert_page(pool, page);
+	else {
+		page->next = pool->full;
+		pool->full = page;
+	}
+
+	pool->items++;
+
+	return page->data;
+}
+
+GIT_INLINE(void) pool_remove_page(
+	git_pool *pool, git_pool_page *page, git_pool_page *prev)
+{
+	if (prev == NULL)
+		pool->open = page->next;
+	else
+		prev->next = page->next;
+}
+
+void *git_pool_malloc(git_pool *pool, uint32_t items)
+{
+	git_pool_page *scan = pool->open, *prev;
+	uint32_t size = ((items * pool->item_size) + 7) & ~7;
+	void *ptr = NULL;
+
+	pool->has_string_alloc = 0;
+	if (items > 1)
+		pool->has_multi_item_alloc = 1;
+	else if (pool->free_list != NULL) {
+		ptr = pool->free_list;
+		pool->free_list = ((struct pool_freelist *)pool->free_list)->next;
+		return ptr;
+	}
+
+	/* just add a block if there is no open one to accommodate this */
+	if (size >= pool->page_size || !scan || scan->avail < size)
+		return pool_alloc_page(pool, size);
+
+	pool->items++;
+
+	/* find smallest block in free list with space */
+	for (scan = pool->open, prev = NULL;
+		 scan->next && scan->next->avail >= size;
+		 prev = scan, scan = scan->next);
+
+	/* allocate space from the block */
+	ptr = &scan->data[scan->size - scan->avail];
+	scan->avail -= size;
+
+	/* move to full list if there is almost no space left */
+	if (scan->avail < pool->item_size || scan->avail < GIT_POOL_MIN_USABLE) {
+		pool_remove_page(pool, scan, prev);
+		scan->next = pool->full;
+		pool->full = scan;
+	}
+	/* reorder list if block is now smaller than the one after it */
+	else if (scan->next != NULL && scan->next->avail > scan->avail) {
+		pool_remove_page(pool, scan, prev);
+		pool_insert_page(pool, scan);
+	}
+
+	return ptr;
+}
+
+char *git_pool_strndup(git_pool *pool, const char *str, size_t n)
+{
+	char *ptr = NULL;
+
+	assert(pool && str && pool->item_size == sizeof(char));
+
+	if ((uint32_t)(n + 1) < n)
+		return NULL;
+
+	if ((ptr = git_pool_malloc(pool, (uint32_t)(n + 1))) != NULL) {
+		memcpy(ptr, str, n);
+		ptr[n] = '\0';
+	}
+
+	pool->has_string_alloc = 1;
+
+	return ptr;
+}
+
+char *git_pool_strdup(git_pool *pool, const char *str)
+{
+	assert(pool && str && pool->item_size == sizeof(char));
+
+	return git_pool_strndup(pool, str, strlen(str));
+}
+
+char *git_pool_strdup_safe(git_pool *pool, const char *str)
+{
+	return str ? git_pool_strdup(pool, str) : NULL;
+}
+
+char *git_pool_strcat(git_pool *pool, const char *a, const char *b)
+{
+	void *ptr;
+	size_t len_a, len_b;
+
+	assert(pool && pool->item_size == sizeof(char));
+
+	len_a = a ? strlen(a) : 0;
+	len_b = b ? strlen(b) : 0;
+
+	if ((ptr = git_pool_malloc(pool, (uint32_t)(len_a + len_b + 1))) != NULL) {
+		if (len_a)
+			memcpy(ptr, a, len_a);
+		if (len_b)
+			memcpy(((char *)ptr) + len_a, b, len_b);
+		*(((char *)ptr) + len_a + len_b) = '\0';
+	}
+	pool->has_string_alloc = 1;
+
+	return ptr;
+}
+
+void git_pool_free(git_pool *pool, void *ptr)
+{
+	struct pool_freelist *item = ptr;
+
+	assert(pool && pool->item_size >= sizeof(void*));
+
+	if (item) {
+		item->next = pool->free_list;
+		pool->free_list = item;
+	}
+}
+
+void git_pool_free_array(git_pool *pool, size_t count, void **ptrs)
+{
+	struct pool_freelist **items = (struct pool_freelist **)ptrs;
+	size_t i;
+
+	assert(pool && ptrs && pool->item_size >= sizeof(void*));
+
+	if (!count)
+		return;
+
+	for (i = count - 1; i > 0; --i)
+		items[i]->next = items[i - 1];
+
+	items[i]->next  = pool->free_list;
+	pool->free_list = items[count - 1];
+}
+
+uint32_t git_pool__open_pages(git_pool *pool)
+{
+	uint32_t ct = 0;
+	git_pool_page *scan;
+	for (scan = pool->open; scan != NULL; scan = scan->next) ct++;
+	return ct;
+}
+
+uint32_t git_pool__full_pages(git_pool *pool)
+{
+	uint32_t ct = 0;
+	git_pool_page *scan;
+	for (scan = pool->full; scan != NULL; scan = scan->next) ct++;
+	return ct;
+}
+
+bool git_pool__ptr_in_pool(git_pool *pool, void *ptr)
+{
+	git_pool_page *scan;
+	for (scan = pool->open; scan != NULL; scan = scan->next)
+		if ((void *)scan->data <= ptr &&
+			(void *)(((char *)scan->data) + scan->size) > ptr)
+			return true;
+	for (scan = pool->full; scan != NULL; scan = scan->next)
+		if ((void *)scan->data <= ptr &&
+			(void *)(((char *)scan->data) + scan->size) > ptr)
+			return true;
+	return false;
+}
+
+uint32_t git_pool__system_page_size(void)
+{
+	static uint32_t size = 0;
+
+	if (!size) {
+		size_t page_size;
+		if (git__page_size(&page_size) < 0)
+			page_size = 4096;
+		size = page_size - 2 * sizeof(void *); /* allow space for malloc overhead */
+	}
+
+	return size;
+}
+
+uint32_t git_pool__suggest_items_per_page(uint32_t item_size)
+{
+	uint32_t page_bytes =
+		git_pool__system_page_size() - sizeof(git_pool_page);
+	return page_bytes / item_size;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pool.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pool.h
new file mode 100755
index 0000000..b0007f3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pool.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_pool_h__
+#define INCLUDE_pool_h__
+
+#include "common.h"
+
+typedef struct git_pool_page git_pool_page;
+
+/**
+ * Chunked allocator.
+ *
+ * A `git_pool` can be used when you want to cheaply allocate
+ * multiple items of the same type and are willing to free them
+ * all together with a single call.  The two most common cases
+ * are a set of fixed size items (such as lots of OIDs) or a
+ * bunch of strings.
+ *
+ * Internally, a `git_pool` allocates pages of memory and then
+ * deals out blocks from the trailing unused portion of each page.
+ * The pages guarantee that the number of actual allocations done
+ * will be much smaller than the number of items needed.
+ *
+ * For examples of how to set up a `git_pool` see `git_pool_init`.
+ */
+typedef struct {
+	git_pool_page *open; /* pages with space left */
+	git_pool_page *full; /* pages with no space left */
+	void *free_list;     /* optional: list of freed blocks */
+	uint32_t item_size;  /* size of single alloc unit in bytes */
+	uint32_t page_size;  /* size of page in bytes */
+	uint32_t items;
+	unsigned has_string_alloc : 1; /* was the strdup function used */
+	unsigned has_multi_item_alloc : 1; /* was items ever > 1 in malloc */
+	unsigned has_large_page_alloc : 1; /* are any pages > page_size */
+} git_pool;
+
+#define GIT_POOL_INIT_STRINGPOOL { 0, 0, 0, 1, 4000, 0, 0, 0, 0 }
+
+/**
+ * Initialize a pool.
+ *
+ * To allocation strings, use like this:
+ *
+ *     git_pool_init(&string_pool, 1, 0);
+ *     my_string = git_pool_strdup(&string_pool, your_string);
+ *
+ * To allocate items of fixed size, use like this:
+ *
+ *     git_pool_init(&pool, sizeof(item), 0);
+ *     my_item = git_pool_malloc(&pool, 1);
+ *
+ * Of course, you can use this in other ways, but those are the
+ * two most common patterns.
+ */
+extern int git_pool_init(
+	git_pool *pool, uint32_t item_size, uint32_t items_per_page);
+
+/**
+ * Free all items in pool
+ */
+extern void git_pool_clear(git_pool *pool);
+
+/**
+ * Swap two pools with one another
+ */
+extern void git_pool_swap(git_pool *a, git_pool *b);
+
+/**
+ * Allocate space for one or more items from a pool.
+ */
+extern void *git_pool_malloc(git_pool *pool, uint32_t items);
+
+/**
+ * Allocate space and zero it out.
+ */
+GIT_INLINE(void *) git_pool_mallocz(git_pool *pool, uint32_t items)
+{
+	void *ptr = git_pool_malloc(pool, items);
+	if (ptr)
+		memset(ptr, 0, (size_t)items * (size_t)pool->item_size);
+	return ptr;
+}
+
+/**
+ * Allocate space and duplicate string data into it.
+ *
+ * This is allowed only for pools with item_size == sizeof(char)
+ */
+extern char *git_pool_strndup(git_pool *pool, const char *str, size_t n);
+
+/**
+ * Allocate space and duplicate a string into it.
+ *
+ * This is allowed only for pools with item_size == sizeof(char)
+ */
+extern char *git_pool_strdup(git_pool *pool, const char *str);
+
+/**
+ * Allocate space and duplicate a string into it, NULL is no error.
+ *
+ * This is allowed only for pools with item_size == sizeof(char)
+ */
+extern char *git_pool_strdup_safe(git_pool *pool, const char *str);
+
+/**
+ * Allocate space for the concatenation of two strings.
+ *
+ * This is allowed only for pools with item_size == sizeof(char)
+ */
+extern char *git_pool_strcat(git_pool *pool, const char *a, const char *b);
+
+/**
+ * Push a block back onto the free list for the pool.
+ *
+ * This is allowed only if the item_size is >= sizeof(void*).
+ *
+ * In some cases, it is helpful to "release" an allocated block
+ * for reuse.  Pools don't support a general purpose free, but
+ * they will keep a simple free blocks linked list provided the
+ * native block size is large enough to hold a void pointer
+ */
+extern void git_pool_free(git_pool *pool, void *ptr);
+
+/**
+ * Push an array of pool allocated blocks efficiently onto the free list.
+ *
+ * This has the same constraints as `git_pool_free()` above.
+ */
+extern void git_pool_free_array(git_pool *pool, size_t count, void **ptrs);
+
+/*
+ * Misc utilities
+ */
+
+extern uint32_t git_pool__open_pages(git_pool *pool);
+
+extern uint32_t git_pool__full_pages(git_pool *pool);
+
+extern bool git_pool__ptr_in_pool(git_pool *pool, void *ptr);
+
+extern uint32_t git_pool__suggest_items_per_page(uint32_t item_size);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/posix.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/posix.c
new file mode 100755
index 0000000..8d86aa8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/posix.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "posix.h"
+#include "path.h"
+#include <stdio.h>
+#include <ctype.h>
+
+#ifndef GIT_WIN32
+
+#ifdef NO_ADDRINFO
+
+int p_getaddrinfo(
+	const char *host,
+	const char *port,
+	struct addrinfo *hints,
+	struct addrinfo **info)
+{
+	struct addrinfo *ainfo, *ai;
+	int p = 0;
+
+	GIT_UNUSED(hints);
+
+	if ((ainfo = malloc(sizeof(struct addrinfo))) == NULL)
+		return -1;
+
+	if ((ainfo->ai_hostent = gethostbyname(host)) == NULL) {
+		free(ainfo);
+		return -2;
+	}
+
+	ainfo->ai_servent = getservbyname(port, 0);
+
+	if (ainfo->ai_servent)
+		ainfo->ai_port = ainfo->ai_servent->s_port;
+	else
+		ainfo->ai_port = atol(port);
+
+	memcpy(&ainfo->ai_addr_in.sin_addr,
+			ainfo->ai_hostent->h_addr_list[0],
+			ainfo->ai_hostent->h_length);
+
+	ainfo->ai_protocol = 0;
+	ainfo->ai_socktype = hints->ai_socktype;
+	ainfo->ai_family = ainfo->ai_hostent->h_addrtype;
+	ainfo->ai_addr_in.sin_family = ainfo->ai_family;
+	ainfo->ai_addr_in.sin_port = ainfo->ai_port;
+	ainfo->ai_addr = (struct addrinfo *)&ainfo->ai_addr_in;
+	ainfo->ai_addrlen = sizeof(struct sockaddr_in);
+
+	*info = ainfo;
+
+	if (ainfo->ai_hostent->h_addr_list[1] == NULL) {
+		ainfo->ai_next = NULL;
+		return 0;
+	}
+
+	ai = ainfo;
+
+	for (p = 1; ainfo->ai_hostent->h_addr_list[p] != NULL; p++) {
+		ai->ai_next = malloc(sizeof(struct addrinfo));
+		memcpy(&ai->ai_next, ainfo, sizeof(struct addrinfo));
+		memcpy(&ai->ai_next->ai_addr_in.sin_addr,
+			ainfo->ai_hostent->h_addr_list[p],
+			ainfo->ai_hostent->h_length);
+		ai->ai_next->ai_addr = (struct addrinfo *)&ai->ai_next->ai_addr_in;
+		ai = ai->ai_next;
+	}
+
+	ai->ai_next = NULL;
+	return 0;
+}
+
+void p_freeaddrinfo(struct addrinfo *info)
+{
+	struct addrinfo *p, *next;
+
+	p = info;
+
+	while(p != NULL) {
+		next = p->ai_next;
+		free(p);
+		p = next;
+	}
+}
+
+const char *p_gai_strerror(int ret)
+{
+	switch(ret) {
+	case -1: return "Out of memory"; break;
+	case -2: return "Address lookup failed"; break;
+	default: return "Unknown error"; break;
+	}
+}
+
+#endif /* NO_ADDRINFO */
+
+int p_open(const char *path, volatile int flags, ...)
+{
+	mode_t mode = 0;
+
+	if (flags & O_CREAT) {
+		va_list arg_list;
+
+		va_start(arg_list, flags);
+		mode = (mode_t)va_arg(arg_list, int);
+		va_end(arg_list);
+	}
+
+	return open(path, flags | O_BINARY | O_CLOEXEC, mode);
+}
+
+int p_creat(const char *path, mode_t mode)
+{
+	return open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC, mode);
+}
+
+int p_getcwd(char *buffer_out, size_t size)
+{
+	char *cwd_buffer;
+
+	assert(buffer_out && size > 0);
+
+	cwd_buffer = getcwd(buffer_out, size);
+
+	if (cwd_buffer == NULL)
+		return -1;
+
+	git_path_mkposix(buffer_out);
+	git_path_string_to_dir(buffer_out, size); /* append trailing slash */
+
+	return 0;
+}
+
+int p_rename(const char *from, const char *to)
+{
+	if (!link(from, to)) {
+		p_unlink(from);
+		return 0;
+	}
+
+	if (!rename(from, to))
+		return 0;
+
+	return -1;
+}
+
+#endif /* GIT_WIN32 */
+
+ssize_t p_read(git_file fd, void *buf, size_t cnt)
+{
+	char *b = buf;
+
+	if (!git__is_ssizet(cnt)) {
+#ifdef GIT_WIN32
+		SetLastError(ERROR_INVALID_PARAMETER);
+#endif
+		errno = EINVAL;
+		return -1;
+	}
+
+	while (cnt) {
+		ssize_t r;
+#ifdef GIT_WIN32
+		r = read(fd, b, cnt > INT_MAX ? INT_MAX : (unsigned int)cnt);
+#else
+		r = read(fd, b, cnt);
+#endif
+		if (r < 0) {
+			if (errno == EINTR || errno == EAGAIN)
+				continue;
+			return -1;
+		}
+		if (!r)
+			break;
+		cnt -= r;
+		b += r;
+	}
+	return (b - (char *)buf);
+}
+
+int p_write(git_file fd, const void *buf, size_t cnt)
+{
+	const char *b = buf;
+
+	while (cnt) {
+		ssize_t r;
+#ifdef GIT_WIN32
+		assert((size_t)((unsigned int)cnt) == cnt);
+		r = write(fd, b, (unsigned int)cnt);
+#else
+		r = write(fd, b, cnt);
+#endif
+		if (r < 0) {
+			if (errno == EINTR || GIT_ISBLOCKED(errno))
+				continue;
+			return -1;
+		}
+		if (!r) {
+			errno = EPIPE;
+			return -1;
+		}
+		cnt -= r;
+		b += r;
+	}
+	return 0;
+}
+
+#ifdef NO_MMAP
+
+#include "map.h"
+
+int git__page_size(size_t *page_size)
+{
+	/* dummy; here we don't need any alignment anyway */
+	*page_size = 4096;
+	return 0;
+}
+
+
+int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset)
+{
+	GIT_MMAP_VALIDATE(out, len, prot, flags);
+
+	out->data = NULL;
+	out->len = 0;
+
+	if ((prot & GIT_PROT_WRITE) && ((flags & GIT_MAP_TYPE) == GIT_MAP_SHARED)) {
+		giterr_set(GITERR_OS, "Trying to map shared-writeable");
+		return -1;
+	}
+
+	out->data = malloc(len);
+	GITERR_CHECK_ALLOC(out->data);
+
+	if (!git__is_ssizet(len) ||
+		(p_lseek(fd, offset, SEEK_SET) < 0) ||
+		(p_read(fd, out->data, len) != (ssize_t)len)) {
+		giterr_set(GITERR_OS, "mmap emulation failed");
+		return -1;
+	}
+
+	out->len = len;
+	return 0;
+}
+
+int p_munmap(git_map *map)
+{
+	assert(map != NULL);
+	free(map->data);
+
+	return 0;
+}
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/posix.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/posix.h
new file mode 100755
index 0000000..8785a4c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/posix.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_posix_h__
+#define INCLUDE_posix_h__
+
+#include "common.h"
+#include <fcntl.h>
+#include <time.h>
+#include "fnmatch.h"
+
+/* stat: file mode type testing macros */
+#ifndef S_IFGITLINK
+#define S_IFGITLINK 0160000
+#define S_ISGITLINK(m) (((m) & S_IFMT) == S_IFGITLINK)
+#endif
+
+#ifndef S_IFLNK
+#define S_IFLNK 0120000
+#undef _S_IFLNK
+#define _S_IFLNK S_IFLNK
+#endif
+
+#ifndef S_IXUSR
+#define S_IXUSR 00100
+#endif
+
+#ifndef S_ISLNK
+#define S_ISLNK(m) (((m) & _S_IFMT) == _S_IFLNK)
+#endif
+
+#ifndef S_ISDIR
+#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
+#endif
+
+#ifndef S_ISREG
+#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
+#endif
+
+#ifndef S_ISFIFO
+#define S_ISFIFO(m) (((m) & _S_IFMT) == _S_IFIFO)
+#endif
+
+/* if S_ISGID is not defined, then don't try to set it */
+#ifndef S_ISGID
+#define S_ISGID 0
+#endif
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 0
+#endif
+
+/* access() mode parameter #defines	*/
+#ifndef F_OK
+#define F_OK 0 /* existence check */
+#endif
+#ifndef W_OK
+#define W_OK 2 /* write mode check */
+#endif
+#ifndef R_OK
+#define R_OK 4 /* read mode check */
+#endif
+
+/* Determine whether an errno value indicates that a read or write failed
+ * because the descriptor is blocked.
+ */
+#if defined(EWOULDBLOCK)
+#define GIT_ISBLOCKED(e) ((e) == EAGAIN || (e) == EWOULDBLOCK)
+#else
+#define GIT_ISBLOCKED(e) ((e) == EAGAIN)
+#endif
+
+/* define some standard errnos that the runtime may be missing.  for example,
+ * mingw lacks EAFNOSUPPORT. */
+#ifndef EAFNOSUPPORT
+#define EAFNOSUPPORT (INT_MAX-1)
+#endif
+
+typedef int git_file;
+
+/**
+ * Standard POSIX Methods
+ *
+ * All the methods starting with the `p_` prefix are
+ * direct ports of the standard POSIX methods.
+ *
+ * Some of the methods are slightly wrapped to provide
+ * saner defaults. Some of these methods are emulated
+ * in Windows platforms.
+ *
+ * Use your manpages to check the docs on these.
+ */
+
+extern ssize_t p_read(git_file fd, void *buf, size_t cnt);
+extern int p_write(git_file fd, const void *buf, size_t cnt);
+
+#define p_close(fd) close(fd)
+#define p_umask(m) umask(m)
+
+extern int p_open(const char *path, int flags, ...);
+extern int p_creat(const char *path, mode_t mode);
+extern int p_getcwd(char *buffer_out, size_t size);
+extern int p_rename(const char *from, const char *to);
+
+extern int git__page_size(size_t *page_size);
+
+/**
+ * Platform-dependent methods
+ */
+#ifdef GIT_WIN32
+#	include "win32/posix.h"
+#else
+#	include "unix/posix.h"
+#endif
+
+#include "strnlen.h"
+
+#ifdef NO_READDIR_R
+GIT_INLINE(int) p_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
+{
+	GIT_UNUSED(entry);
+	*result = readdir(dirp);
+	return 0;
+}
+#else /* NO_READDIR_R */
+#	define p_readdir_r(d,e,r) readdir_r(d,e,r)
+#endif
+
+#ifdef NO_ADDRINFO
+#	include <netdb.h>
+struct addrinfo {
+	struct hostent *ai_hostent;
+	struct servent *ai_servent;
+	struct sockaddr_in ai_addr_in;
+	struct sockaddr *ai_addr;
+	size_t ai_addrlen;
+	int ai_family;
+	int ai_socktype;
+	int ai_protocol;
+	long ai_port;
+	struct addrinfo *ai_next;
+};
+
+extern int p_getaddrinfo(const char *host, const char *port,
+	struct addrinfo *hints, struct addrinfo **info);
+extern void p_freeaddrinfo(struct addrinfo *info);
+extern const char *p_gai_strerror(int ret);
+#else
+#	define p_getaddrinfo(a, b, c, d) getaddrinfo(a, b, c, d)
+#	define p_freeaddrinfo(a) freeaddrinfo(a)
+#	define p_gai_strerror(c) gai_strerror(c)
+#endif /* NO_ADDRINFO */
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pqueue.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pqueue.c
new file mode 100755
index 0000000..54a60ca
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pqueue.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "pqueue.h"
+#include "util.h"
+
+#define PQUEUE_LCHILD_OF(I) (((I)<<1)+1)
+#define PQUEUE_RCHILD_OF(I) (((I)<<1)+2)
+#define PQUEUE_PARENT_OF(I) (((I)-1)>>1)
+
+int git_pqueue_init(
+	git_pqueue *pq,
+	uint32_t flags,
+	size_t init_size,
+	git_vector_cmp cmp)
+{
+	int error = git_vector_init(pq, init_size, cmp);
+
+	if (!error) {
+		/* mix in our flags */
+		pq->flags |= flags;
+
+		/* if fixed size heap, pretend vector is exactly init_size elements */
+		if ((flags & GIT_PQUEUE_FIXED_SIZE) && init_size > 0)
+			pq->_alloc_size = init_size;
+	}
+
+	return error;
+}
+
+static void pqueue_up(git_pqueue *pq, size_t el)
+{
+	size_t parent_el = PQUEUE_PARENT_OF(el);
+	void *kid = git_vector_get(pq, el);
+
+	while (el > 0) {
+		void *parent = pq->contents[parent_el];
+
+		if (pq->_cmp(parent, kid) <= 0)
+			break;
+
+		pq->contents[el] = parent;
+
+		el = parent_el;
+		parent_el = PQUEUE_PARENT_OF(el);
+	}
+
+	pq->contents[el] = kid;
+}
+
+static void pqueue_down(git_pqueue *pq, size_t el)
+{
+	void *parent = git_vector_get(pq, el), *kid, *rkid;
+
+	while (1) {
+		size_t kid_el = PQUEUE_LCHILD_OF(el);
+
+		if ((kid = git_vector_get(pq, kid_el)) == NULL)
+			break;
+
+		if ((rkid = git_vector_get(pq, kid_el + 1)) != NULL &&
+			pq->_cmp(kid, rkid) > 0) {
+			kid    = rkid;
+			kid_el += 1;
+		}
+
+		if (pq->_cmp(parent, kid) <= 0)
+			break;
+
+		pq->contents[el] = kid;
+		el = kid_el;
+	}
+
+	pq->contents[el] = parent;
+}
+
+int git_pqueue_insert(git_pqueue *pq, void *item)
+{
+	int error = 0;
+
+	/* if heap is full, pop the top element if new one should replace it */
+	if ((pq->flags & GIT_PQUEUE_FIXED_SIZE) != 0 &&
+		pq->length >= pq->_alloc_size)
+	{
+		/* skip this item if below min item in heap */
+		if (pq->_cmp(item, git_vector_get(pq, 0)) <= 0)
+			return 0;
+		/* otherwise remove the min item before inserting new */
+		(void)git_pqueue_pop(pq);
+	}
+
+	if (!(error = git_vector_insert(pq, item)))
+		pqueue_up(pq, pq->length - 1);
+
+	return error;
+}
+
+void *git_pqueue_pop(git_pqueue *pq)
+{
+	void *rval = git_pqueue_get(pq, 0);
+
+	if (git_pqueue_size(pq) > 1) {
+		/* move last item to top of heap, shrink, and push item down */
+		pq->contents[0] = git_vector_last(pq);
+		git_vector_pop(pq);
+		pqueue_down(pq, 0);
+	} else {
+		/* all we need to do is shrink the heap in this case */
+		git_vector_pop(pq);
+	}
+
+	return rval;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pqueue.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pqueue.h
new file mode 100755
index 0000000..da7b74e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/pqueue.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) the libgit2 contributors.  All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_pqueue_h__
+#define INCLUDE_pqueue_h__
+
+#include "vector.h"
+
+typedef git_vector git_pqueue;
+
+enum {
+	/* flag meaning: don't grow heap, keep highest values only */
+	GIT_PQUEUE_FIXED_SIZE = (GIT_VECTOR_FLAG_MAX << 1),
+};
+
+/**
+ * Initialize priority queue
+ *
+ * @param pq The priority queue struct to initialize
+ * @param flags Flags (see above) to control queue behavior
+ * @param init_size The initial queue size
+ * @param cmp The entry priority comparison function
+ * @return 0 on success, <0 on error
+ */
+extern int git_pqueue_init(
+	git_pqueue *pq,
+	uint32_t flags,
+	size_t init_size,
+	git_vector_cmp cmp);
+
+#define git_pqueue_free  git_vector_free
+#define git_pqueue_clear git_vector_clear
+#define git_pqueue_size  git_vector_length
+#define git_pqueue_get   git_vector_get
+
+/**
+ * Insert a new item into the queue
+ *
+ * @param pq The priority queue
+ * @param item Pointer to the item data
+ * @return 0 on success, <0 on failure
+ */
+extern int git_pqueue_insert(git_pqueue *pq, void *item);
+
+/**
+ * Remove the top item in the priority queue
+ *
+ * @param pq The priority queue
+ * @return item from heap on success, NULL if queue is empty
+ */
+extern void *git_pqueue_pop(git_pqueue *pq);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/push.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/push.c
new file mode 100755
index 0000000..a0d8a05
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/push.c
@@ -0,0 +1,717 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2.h"
+
+#include "common.h"
+#include "pack.h"
+#include "pack-objects.h"
+#include "remote.h"
+#include "vector.h"
+#include "push.h"
+#include "tree.h"
+
+static int push_spec_rref_cmp(const void *a, const void *b)
+{
+	const push_spec *push_spec_a = a, *push_spec_b = b;
+
+	return strcmp(push_spec_a->refspec.dst, push_spec_b->refspec.dst);
+}
+
+static int push_status_ref_cmp(const void *a, const void *b)
+{
+	const push_status *push_status_a = a, *push_status_b = b;
+
+	return strcmp(push_status_a->ref, push_status_b->ref);
+}
+
+int git_push_new(git_push **out, git_remote *remote)
+{
+	git_push *p;
+
+	*out = NULL;
+
+	p = git__calloc(1, sizeof(*p));
+	GITERR_CHECK_ALLOC(p);
+
+	p->repo = remote->repo;
+	p->remote = remote;
+	p->report_status = 1;
+	p->pb_parallelism = 1;
+
+	if (git_vector_init(&p->specs, 0, push_spec_rref_cmp) < 0) {
+		git__free(p);
+		return -1;
+	}
+
+	if (git_vector_init(&p->status, 0, push_status_ref_cmp) < 0) {
+		git_vector_free(&p->specs);
+		git__free(p);
+		return -1;
+	}
+
+	if (git_vector_init(&p->updates, 0, NULL) < 0) {
+		git_vector_free(&p->status);
+		git_vector_free(&p->specs);
+		git__free(p);
+		return -1;
+	}
+
+	*out = p;
+	return 0;
+}
+
+int git_push_set_options(git_push *push, const git_push_options *opts)
+{
+	if (!push || !opts)
+		return -1;
+
+	GITERR_CHECK_VERSION(opts, GIT_PUSH_OPTIONS_VERSION, "git_push_options");
+
+	push->pb_parallelism = opts->pb_parallelism;
+
+	return 0;
+}
+
+static void free_refspec(push_spec *spec)
+{
+	if (spec == NULL)
+		return;
+
+	git_refspec__free(&spec->refspec);
+	git__free(spec);
+}
+
+static int check_rref(char *ref)
+{
+	if (git__prefixcmp(ref, "refs/")) {
+		giterr_set(GITERR_INVALID, "Not a valid reference '%s'", ref);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int check_lref(git_push *push, char *ref)
+{
+	/* lref must be resolvable to an existing object */
+	git_object *obj;
+	int error = git_revparse_single(&obj, push->repo, ref);
+	git_object_free(obj);
+
+	if (!error)
+		return 0;
+
+	if (error == GIT_ENOTFOUND)
+		giterr_set(GITERR_REFERENCE,
+			"src refspec '%s' does not match any existing object", ref);
+	else
+		giterr_set(GITERR_INVALID, "Not a valid reference '%s'", ref);
+	return -1;
+}
+
+static int parse_refspec(git_push *push, push_spec **spec, const char *str)
+{
+	push_spec *s;
+
+	*spec = NULL;
+
+	s = git__calloc(1, sizeof(*s));
+	GITERR_CHECK_ALLOC(s);
+
+	if (git_refspec__parse(&s->refspec, str, false) < 0) {
+		giterr_set(GITERR_INVALID, "invalid refspec %s", str);
+		goto on_error;
+	}
+
+	if (s->refspec.src && s->refspec.src[0] != '\0' &&
+	    check_lref(push, s->refspec.src) < 0) {
+		goto on_error;
+	}
+
+	if (check_rref(s->refspec.dst) < 0)
+		goto on_error;
+
+	*spec = s;
+	return 0;
+
+on_error:
+	free_refspec(s);
+	return -1;
+}
+
+int git_push_add_refspec(git_push *push, const char *refspec)
+{
+	push_spec *spec;
+
+	if (parse_refspec(push, &spec, refspec) < 0 ||
+	    git_vector_insert(&push->specs, spec) < 0)
+		return -1;
+
+	return 0;
+}
+
+int git_push_update_tips(git_push *push, const git_remote_callbacks *callbacks)
+{
+	git_buf remote_ref_name = GIT_BUF_INIT;
+	size_t i, j;
+	git_refspec *fetch_spec;
+	push_spec *push_spec = NULL;
+	git_reference *remote_ref;
+	push_status *status;
+	int error = 0;
+
+	git_vector_foreach(&push->status, i, status) {
+		int fire_callback = 1;
+
+		/* Skip unsuccessful updates which have non-empty messages */
+		if (status->msg)
+			continue;
+
+		/* Find the corresponding remote ref */
+		fetch_spec = git_remote__matching_refspec(push->remote, status->ref);
+		if (!fetch_spec)
+			continue;
+
+		if ((error = git_refspec_transform(&remote_ref_name, fetch_spec, status->ref)) < 0)
+			goto on_error;
+
+		/* Find matching  push ref spec */
+		git_vector_foreach(&push->specs, j, push_spec) {
+			if (!strcmp(push_spec->refspec.dst, status->ref))
+				break;
+		}
+
+		/* Could not find the corresponding push ref spec for this push update */
+		if (j == push->specs.length)
+			continue;
+
+		/* Update the remote ref */
+		if (git_oid_iszero(&push_spec->loid)) {
+			error = git_reference_lookup(&remote_ref, push->remote->repo, git_buf_cstr(&remote_ref_name));
+
+			if (error >= 0) {
+				error = git_reference_delete(remote_ref);
+				git_reference_free(remote_ref);
+			}
+		} else {
+			error = git_reference_create(NULL, push->remote->repo,
+						git_buf_cstr(&remote_ref_name), &push_spec->loid, 1,
+						"update by push");
+		}
+
+		if (error < 0) {
+			if (error != GIT_ENOTFOUND)
+				goto on_error;
+
+			giterr_clear();
+			fire_callback = 0;
+		}
+
+		if (fire_callback && callbacks && callbacks->update_tips) {
+			error = callbacks->update_tips(git_buf_cstr(&remote_ref_name),
+						&push_spec->roid, &push_spec->loid, callbacks->payload);
+
+			if (error < 0)
+				goto on_error;
+		}
+	}
+
+	error = 0;
+
+on_error:
+	git_buf_free(&remote_ref_name);
+	return error;
+}
+
+/**
+ * Insert all tags until we find a non-tag object, which is returned
+ * in `out`.
+ */
+static int enqueue_tag(git_object **out, git_push *push, git_oid *id)
+{
+	git_object *obj = NULL, *target = NULL;
+	int error;
+
+	if ((error = git_object_lookup(&obj, push->repo, id, GIT_OBJ_TAG)) < 0)
+		return error;
+
+	while (git_object_type(obj) == GIT_OBJ_TAG) {
+		if ((error = git_packbuilder_insert(push->pb, git_object_id(obj), NULL)) < 0)
+			break;
+
+		if ((error = git_tag_target(&target, (git_tag *) obj)) < 0)
+			break;
+
+		git_object_free(obj);
+		obj = target;
+	}
+
+	if (error < 0)
+		git_object_free(obj);
+	else
+		*out = obj;
+
+	return error;
+}
+
+static int revwalk(git_vector *commits, git_push *push)
+{
+	git_remote_head *head;
+	push_spec *spec;
+	git_revwalk *rw;
+	git_oid oid;
+	unsigned int i;
+	int error = -1;
+
+	if (git_revwalk_new(&rw, push->repo) < 0)
+		return -1;
+
+	git_revwalk_sorting(rw, GIT_SORT_TIME);
+
+	git_vector_foreach(&push->specs, i, spec) {
+		git_otype type;
+		size_t size;
+
+		if (git_oid_iszero(&spec->loid))
+			/*
+			 * Delete reference on remote side;
+			 * nothing to do here.
+			 */
+			continue;
+
+		if (git_oid_equal(&spec->loid, &spec->roid))
+			continue; /* up-to-date */
+
+		if (git_odb_read_header(&size, &type, push->repo->_odb, &spec->loid) < 0)
+			goto on_error;
+
+		if (type == GIT_OBJ_TAG) {
+			git_object *target;
+
+			if ((error = enqueue_tag(&target, push, &spec->loid)) < 0)
+				goto on_error;
+
+			if (git_object_type(target) == GIT_OBJ_COMMIT) {
+				if (git_revwalk_push(rw, git_object_id(target)) < 0) {
+					git_object_free(target);
+					goto on_error;
+				}
+			} else {
+				if (git_packbuilder_insert(
+					push->pb, git_object_id(target), NULL) < 0) {
+					git_object_free(target);
+					goto on_error;
+				}
+			}
+			git_object_free(target);
+		} else if (git_revwalk_push(rw, &spec->loid) < 0)
+			goto on_error;
+
+		if (!spec->refspec.force) {
+			git_oid base;
+
+			if (git_oid_iszero(&spec->roid))
+				continue;
+
+			if (!git_odb_exists(push->repo->_odb, &spec->roid)) {
+				giterr_set(GITERR_REFERENCE, 
+					"Cannot push because a reference that you are trying to update on the remote contains commits that are not present locally.");
+				error = GIT_ENONFASTFORWARD;
+				goto on_error;
+			}
+
+			error = git_merge_base(&base, push->repo,
+					       &spec->loid, &spec->roid);
+
+			if (error == GIT_ENOTFOUND ||
+				(!error && !git_oid_equal(&base, &spec->roid))) {
+				giterr_set(GITERR_REFERENCE,
+					"Cannot push non-fastforwardable reference");
+				error = GIT_ENONFASTFORWARD;
+				goto on_error;
+			}
+
+			if (error < 0)
+				goto on_error;
+		}
+	}
+
+	git_vector_foreach(&push->remote->refs, i, head) {
+		if (git_oid_iszero(&head->oid))
+			continue;
+
+		/* TODO */
+		git_revwalk_hide(rw, &head->oid);
+	}
+
+	while ((error = git_revwalk_next(&oid, rw)) == 0) {
+		git_oid *o = git__malloc(GIT_OID_RAWSZ);
+		if (!o) {
+			error = -1;
+			goto on_error;
+		}
+		git_oid_cpy(o, &oid);
+		if ((error = git_vector_insert(commits, o)) < 0)
+			goto on_error;
+	}
+
+on_error:
+	git_revwalk_free(rw);
+	return error == GIT_ITEROVER ? 0 : error;
+}
+
+static int enqueue_object(
+	const git_tree_entry *entry,
+	git_packbuilder *pb)
+{
+	switch (git_tree_entry_type(entry)) {
+		case GIT_OBJ_COMMIT:
+			return 0;
+		case GIT_OBJ_TREE:
+			return git_packbuilder_insert_tree(pb, &entry->oid);
+		default:
+			return git_packbuilder_insert(pb, &entry->oid, entry->filename);
+	}
+}
+
+static int queue_differences(
+	git_tree *base,
+	git_tree *delta,
+	git_packbuilder *pb)
+{
+	git_tree *b_child = NULL, *d_child = NULL;
+	size_t b_length = git_tree_entrycount(base);
+	size_t d_length = git_tree_entrycount(delta);
+	size_t i = 0, j = 0;
+	int error;
+
+	while (i < b_length && j < d_length) {
+		const git_tree_entry *b_entry = git_tree_entry_byindex(base, i);
+		const git_tree_entry *d_entry = git_tree_entry_byindex(delta, j);
+		int cmp = 0;
+
+		if (!git_oid__cmp(&b_entry->oid, &d_entry->oid))
+			goto loop;
+
+		cmp = strcmp(b_entry->filename, d_entry->filename);
+
+		/* If the entries are both trees and they have the same name but are
+		 * different, then we'll recurse after adding the right-hand entry */
+		if (!cmp &&
+			git_tree_entry__is_tree(b_entry) &&
+			git_tree_entry__is_tree(d_entry)) {
+			/* Add the right-hand entry */
+			if ((error = git_packbuilder_insert(pb, &d_entry->oid,
+				d_entry->filename)) < 0)
+				goto on_error;
+
+			/* Acquire the subtrees and recurse */
+			if ((error = git_tree_lookup(&b_child,
+					git_tree_owner(base), &b_entry->oid)) < 0 ||
+				(error = git_tree_lookup(&d_child,
+					git_tree_owner(delta), &d_entry->oid)) < 0 ||
+				(error = queue_differences(b_child, d_child, pb)) < 0)
+				goto on_error;
+
+			git_tree_free(b_child); b_child = NULL;
+			git_tree_free(d_child); d_child = NULL;
+		}
+		/* If the object is new or different in the right-hand tree,
+		 * then enumerate it */
+		else if (cmp >= 0 &&
+			(error = enqueue_object(d_entry, pb)) < 0)
+			goto on_error;
+
+	loop:
+		if (cmp <= 0) i++;
+		if (cmp >= 0) j++;
+	}
+
+	/* Drain the right-hand tree of entries */
+	for (; j < d_length; j++)
+		if ((error = enqueue_object(git_tree_entry_byindex(delta, j), pb)) < 0)
+			goto on_error;
+
+	error = 0;
+
+on_error:
+	if (b_child)
+		git_tree_free(b_child);
+
+	if (d_child)
+		git_tree_free(d_child);
+
+	return error;
+}
+
+static int queue_objects(git_push *push)
+{
+	git_vector commits = GIT_VECTOR_INIT;
+	git_oid *oid;
+	size_t i;
+	unsigned j;
+	int error;
+
+	if ((error = revwalk(&commits, push)) < 0)
+		goto on_error;
+
+	git_vector_foreach(&commits, i, oid) {
+		git_commit *parent = NULL, *commit;
+		git_tree *tree = NULL, *ptree = NULL;
+		size_t parentcount;
+
+		if ((error = git_commit_lookup(&commit,	push->repo, oid)) < 0)
+			goto on_error;
+
+		/* Insert the commit */
+		if ((error = git_packbuilder_insert(push->pb, oid, NULL)) < 0)
+			goto loop_error;
+
+		parentcount = git_commit_parentcount(commit);
+
+		if (!parentcount) {
+			if ((error = git_packbuilder_insert_tree(push->pb,
+				git_commit_tree_id(commit))) < 0)
+				goto loop_error;
+		} else {
+			if ((error = git_tree_lookup(&tree, push->repo,
+					git_commit_tree_id(commit))) < 0 ||
+				(error = git_packbuilder_insert(push->pb,
+					git_commit_tree_id(commit), NULL)) < 0)
+				goto loop_error;
+
+			/* For each parent, add the items which are different */
+			for (j = 0; j < parentcount; j++) {
+				if ((error = git_commit_parent(&parent, commit, j)) < 0 ||
+					(error = git_commit_tree(&ptree, parent)) < 0 ||
+					(error = queue_differences(ptree, tree, push->pb)) < 0)
+					goto loop_error;
+
+				git_tree_free(ptree); ptree = NULL;
+				git_commit_free(parent); parent = NULL;
+			}
+		}
+
+		error = 0;
+
+	loop_error:
+		if (tree)
+			git_tree_free(tree);
+
+		if (ptree)
+			git_tree_free(ptree);
+
+		if (parent)
+			git_commit_free(parent);
+
+		git_commit_free(commit);
+
+		if (error < 0)
+			goto on_error;
+	}
+
+	error = 0;
+
+on_error:
+	git_vector_free_deep(&commits);
+	return error;
+}
+
+static int add_update(git_push *push, push_spec *spec)
+{
+	git_push_update *u = git__calloc(1, sizeof(git_push_update));
+	GITERR_CHECK_ALLOC(u);
+
+	u->src_refname = git__strdup(spec->refspec.src);
+	GITERR_CHECK_ALLOC(u->src_refname);
+
+	u->dst_refname = git__strdup(spec->refspec.dst);
+	GITERR_CHECK_ALLOC(u->dst_refname);
+
+	git_oid_cpy(&u->src, &spec->roid);
+	git_oid_cpy(&u->dst, &spec->loid);
+
+	return git_vector_insert(&push->updates, u);
+}
+
+static int calculate_work(git_push *push)
+{
+	git_remote_head *head;
+	push_spec *spec;
+	unsigned int i, j;
+
+	/* Update local and remote oids*/
+
+	git_vector_foreach(&push->specs, i, spec) {
+		if (spec->refspec.src && spec->refspec.src[0]!= '\0') {
+			/* This is a create or update.  Local ref must exist. */
+			if (git_reference_name_to_id(
+					&spec->loid, push->repo, spec->refspec.src) < 0) {
+				giterr_set(GITERR_REFERENCE, "No such reference '%s'", spec->refspec.src);
+				return -1;
+			}
+		}
+
+		/* Remote ref may or may not (e.g. during create) already exist. */
+		git_vector_foreach(&push->remote->refs, j, head) {
+			if (!strcmp(spec->refspec.dst, head->name)) {
+				git_oid_cpy(&spec->roid, &head->oid);
+				break;
+			}
+		}
+
+		if (add_update(push, spec) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
+static int do_push(git_push *push, const git_remote_callbacks *callbacks)
+{
+	int error = 0;
+	git_transport *transport = push->remote->transport;
+
+	if (!transport->push) {
+		giterr_set(GITERR_NET, "Remote transport doesn't support push");
+		error = -1;
+		goto on_error;
+	}
+
+	/*
+	 * A pack-file MUST be sent if either create or update command
+	 * is used, even if the server already has all the necessary
+	 * objects.  In this case the client MUST send an empty pack-file.
+	 */
+
+	if ((error = git_packbuilder_new(&push->pb, push->repo)) < 0)
+		goto on_error;
+
+	git_packbuilder_set_threads(push->pb, push->pb_parallelism);
+
+	if (callbacks && callbacks->pack_progress)
+		if ((error = git_packbuilder_set_callbacks(push->pb, callbacks->pack_progress, callbacks->payload)) < 0)
+			goto on_error;
+
+	if ((error = calculate_work(push)) < 0)
+		goto on_error;
+
+	if (callbacks && callbacks->push_negotiation &&
+	    (error = callbacks->push_negotiation((const git_push_update **) push->updates.contents,
+					  push->updates.length, callbacks->payload)) < 0)
+	    goto on_error;
+
+	if ((error = queue_objects(push)) < 0 ||
+	    (error = transport->push(transport, push, callbacks)) < 0)
+		goto on_error;
+
+on_error:
+	git_packbuilder_free(push->pb);
+	return error;
+}
+
+static int filter_refs(git_remote *remote)
+{
+	const git_remote_head **heads;
+	size_t heads_len, i;
+
+	git_vector_clear(&remote->refs);
+
+	if (git_remote_ls(&heads, &heads_len, remote) < 0)
+		return -1;
+
+	for (i = 0; i < heads_len; i++) {
+		if (git_vector_insert(&remote->refs, (void *)heads[i]) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
+int git_push_finish(git_push *push, const git_remote_callbacks *callbacks)
+{
+	int error;
+
+	if (!git_remote_connected(push->remote) &&
+	    (error = git_remote_connect(push->remote, GIT_DIRECTION_PUSH, callbacks)) < 0)
+		return error;
+
+	if ((error = filter_refs(push->remote)) < 0 ||
+	    (error = do_push(push, callbacks)) < 0)
+		return error;
+
+	if (!push->unpack_ok) {
+		error = -1;
+		giterr_set(GITERR_NET, "unpacking the sent packfile failed on the remote");
+	}
+
+	return error;
+}
+
+int git_push_status_foreach(git_push *push,
+		int (*cb)(const char *ref, const char *msg, void *data),
+		void *data)
+{
+	push_status *status;
+	unsigned int i;
+
+	git_vector_foreach(&push->status, i, status) {
+		int error = cb(status->ref, status->msg, data);
+		if (error)
+			return giterr_set_after_callback(error);
+	}
+
+	return 0;
+}
+
+void git_push_status_free(push_status *status)
+{
+	if (status == NULL)
+		return;
+
+	git__free(status->msg);
+	git__free(status->ref);
+	git__free(status);
+}
+
+void git_push_free(git_push *push)
+{
+	push_spec *spec;
+	push_status *status;
+	git_push_update *update;
+	unsigned int i;
+
+	if (push == NULL)
+		return;
+
+	git_vector_foreach(&push->specs, i, spec) {
+		free_refspec(spec);
+	}
+	git_vector_free(&push->specs);
+
+	git_vector_foreach(&push->status, i, status) {
+		git_push_status_free(status);
+	}
+	git_vector_free(&push->status);
+
+	git_vector_foreach(&push->updates, i, update) {
+		git__free(update->src_refname);
+		git__free(update->dst_refname);
+		git__free(update);
+	}
+	git_vector_free(&push->updates);
+
+	git__free(push);
+}
+
+int git_push_init_options(git_push_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_push_options, GIT_PUSH_OPTIONS_INIT);
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/push.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/push.h
new file mode 100755
index 0000000..a847ee0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/push.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_push_h__
+#define INCLUDE_push_h__
+
+#include "git2.h"
+#include "refspec.h"
+
+typedef struct push_spec {
+	struct git_refspec refspec;
+
+	git_oid loid;
+	git_oid roid;
+} push_spec;
+
+typedef struct push_status {
+	bool ok;
+
+	char *ref;
+	char *msg;
+} push_status;
+
+struct git_push {
+	git_repository *repo;
+	git_packbuilder *pb;
+	git_remote *remote;
+	git_vector specs;
+	git_vector updates;
+	bool report_status;
+
+	/* report-status */
+	bool unpack_ok;
+	git_vector status;
+
+	/* options */
+	unsigned pb_parallelism;
+};
+
+/**
+ * Free the given push status object
+ *
+ * @param status The push status object
+ */
+void git_push_status_free(push_status *status);
+
+/**
+ * Create a new push object
+ *
+ * @param out New push object
+ * @param remote Remote instance
+ *
+ * @return 0 or an error code
+ */
+int git_push_new(git_push **out, git_remote *remote);
+
+/**
+ * Set options on a push object
+ *
+ * @param push The push object
+ * @param opts The options to set on the push object
+ *
+ * @return 0 or an error code
+ */
+int git_push_set_options(
+	git_push *push,
+	const git_push_options *opts);
+
+/**
+ * Add a refspec to be pushed
+ *
+ * @param push The push object
+ * @param refspec Refspec string
+ *
+ * @return 0 or an error code
+ */
+int git_push_add_refspec(git_push *push, const char *refspec);
+
+/**
+ * Update remote tips after a push
+ *
+ * @param push The push object
+ * @param callbacks the callbacks to use for this connection
+ *
+ * @return 0 or an error code
+ */
+int git_push_update_tips(git_push *push, const git_remote_callbacks *callbacks);
+
+/**
+ * Perform the push
+ *
+ * This function will return an error in case of a protocol error or
+ * the server being unable to unpack the data we sent.
+ *
+ * The return value does not reflect whether the server accepted or
+ * refused any reference updates. Use `git_push_status_foreach()` in
+ * order to find out which updates were accepted or rejected.
+ *
+ * @param push The push object
+ * @param callbacks the callbacks to use for this connection
+ *
+ * @return 0 or an error code
+ */
+int git_push_finish(git_push *push, const git_remote_callbacks *callbacks);
+
+/**
+ * Invoke callback `cb' on each status entry
+ *
+ * For each of the updated references, we receive a status report in the
+ * form of `ok refs/heads/master` or `ng refs/heads/master <msg>`.
+ * `msg != NULL` means the reference has not been updated for the given
+ * reason.
+ *
+ * Return a non-zero value from the callback to stop the loop.
+ *
+ * @param push The push object
+ * @param cb The callback to call on each object
+ * @param data The payload passed to the callback
+ *
+ * @return 0 on success, non-zero callback return value, or error code
+ */
+int git_push_status_foreach(git_push *push,
+			int (*cb)(const char *ref, const char *msg, void *data),
+			void *data);
+
+/**
+ * Free the given push object
+ *
+ * @param push The push object
+ */
+void git_push_free(git_push *push);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/rebase.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/rebase.c
new file mode 100755
index 0000000..17536c0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/rebase.c
@@ -0,0 +1,1191 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "buffer.h"
+#include "repository.h"
+#include "posix.h"
+#include "filebuf.h"
+#include "merge.h"
+#include "array.h"
+#include "config.h"
+#include "annotated_commit.h"
+#include "index.h"
+
+#include <git2/types.h>
+#include <git2/annotated_commit.h>
+#include <git2/rebase.h>
+#include <git2/commit.h>
+#include <git2/reset.h>
+#include <git2/revwalk.h>
+#include <git2/notes.h>
+
+#define REBASE_APPLY_DIR    "rebase-apply"
+#define REBASE_MERGE_DIR    "rebase-merge"
+
+#define HEAD_NAME_FILE      "head-name"
+#define ORIG_HEAD_FILE      "orig-head"
+#define HEAD_FILE           "head"
+#define ONTO_FILE           "onto"
+#define ONTO_NAME_FILE      "onto_name"
+#define QUIET_FILE          "quiet"
+
+#define MSGNUM_FILE         "msgnum"
+#define END_FILE            "end"
+#define CMT_FILE_FMT        "cmt.%" PRIuZ
+#define CURRENT_FILE        "current"
+#define REWRITTEN_FILE      "rewritten"
+
+#define ORIG_DETACHED_HEAD  "detached HEAD"
+
+#define NOTES_DEFAULT_REF   NULL
+
+#define REBASE_DIR_MODE     0777
+#define REBASE_FILE_MODE    0666
+
+typedef enum {
+	GIT_REBASE_TYPE_NONE = 0,
+	GIT_REBASE_TYPE_APPLY = 1,
+	GIT_REBASE_TYPE_MERGE = 2,
+	GIT_REBASE_TYPE_INTERACTIVE = 3,
+} git_rebase_type_t;
+
+struct git_rebase {
+	git_repository *repo;
+
+	git_rebase_options options;
+
+	git_rebase_type_t type;
+	char *state_path;
+
+	int head_detached : 1,
+		quiet : 1,
+		started : 1;
+
+	char *orig_head_name;
+	git_oid orig_head_id;
+
+	git_oid onto_id;
+	char *onto_name;
+
+	git_array_t(git_rebase_operation) operations;
+	size_t current;
+};
+
+#define GIT_REBASE_STATE_INIT {0}
+
+static int rebase_state_type(
+	git_rebase_type_t *type_out,
+	char **path_out,
+	git_repository *repo)
+{
+	git_buf path = GIT_BUF_INIT;
+	git_rebase_type_t type = GIT_REBASE_TYPE_NONE;
+
+	if (git_buf_joinpath(&path, repo->path_repository, REBASE_APPLY_DIR) < 0)
+		return -1;
+
+	if (git_path_isdir(git_buf_cstr(&path))) {
+		type = GIT_REBASE_TYPE_APPLY;
+		goto done;
+	}
+
+	git_buf_clear(&path);
+	if (git_buf_joinpath(&path, repo->path_repository, REBASE_MERGE_DIR) < 0)
+		return -1;
+
+	if (git_path_isdir(git_buf_cstr(&path))) {
+		type = GIT_REBASE_TYPE_MERGE;
+		goto done;
+	}
+
+done:
+	*type_out = type;
+
+	if (type != GIT_REBASE_TYPE_NONE && path_out)
+		*path_out = git_buf_detach(&path);
+
+	git_buf_free(&path);
+
+	return 0;
+}
+
+GIT_INLINE(int) rebase_readfile(
+	git_buf *out,
+	git_buf *state_path,
+	const char *filename)
+{
+	size_t state_path_len = state_path->size;
+	int error;
+
+	git_buf_clear(out);
+
+	if ((error = git_buf_joinpath(state_path, state_path->ptr, filename)) < 0 ||
+		(error = git_futils_readbuffer(out, state_path->ptr)) < 0)
+		goto done;
+
+	git_buf_rtrim(out);
+
+done:
+	git_buf_truncate(state_path, state_path_len);
+	return error;
+}
+
+GIT_INLINE(int) rebase_readint(
+	size_t *out, git_buf *asc_out, git_buf *state_path, const char *filename)
+{
+	int32_t num;
+	const char *eol;
+	int error = 0;
+
+	if ((error = rebase_readfile(asc_out, state_path, filename)) < 0)
+		return error;
+
+	if (git__strtol32(&num, asc_out->ptr, &eol, 10) < 0 || num < 0 || *eol) {
+		giterr_set(GITERR_REBASE, "The file '%s' contains an invalid numeric value", filename);
+		return -1;
+	}
+
+	*out = (size_t) num;
+
+	return 0;
+}
+
+GIT_INLINE(int) rebase_readoid(
+	git_oid *out, git_buf *str_out, git_buf *state_path, const char *filename)
+{
+	int error;
+
+	if ((error = rebase_readfile(str_out, state_path, filename)) < 0)
+		return error;
+
+	if (str_out->size != GIT_OID_HEXSZ || git_oid_fromstr(out, str_out->ptr) < 0) {
+		giterr_set(GITERR_REBASE, "The file '%s' contains an invalid object ID", filename);
+		return -1;
+	}
+
+	return 0;
+}
+
+static git_rebase_operation *rebase_operation_alloc(
+	git_rebase *rebase,
+	git_rebase_operation_t type,
+	git_oid *id,
+	const char *exec)
+{
+	git_rebase_operation *operation;
+
+	assert((type == GIT_REBASE_OPERATION_EXEC) == !id);
+	assert((type == GIT_REBASE_OPERATION_EXEC) == !!exec);
+
+	if ((operation = git_array_alloc(rebase->operations)) == NULL)
+		return NULL;
+
+	operation->type = type;
+	git_oid_cpy((git_oid *)&operation->id, id);
+	operation->exec = exec;
+
+	return operation;
+}
+
+static int rebase_open_merge(git_rebase *rebase)
+{
+	git_buf state_path = GIT_BUF_INIT, buf = GIT_BUF_INIT, cmt = GIT_BUF_INIT;
+	git_oid id;
+	git_rebase_operation *operation;
+	size_t i, msgnum = 0, end;
+	int error;
+
+	if ((error = git_buf_puts(&state_path, rebase->state_path)) < 0)
+		goto done;
+
+	/* Read 'msgnum' if it exists (otherwise, let msgnum = 0) */
+	if ((error = rebase_readint(&msgnum, &buf, &state_path, MSGNUM_FILE)) < 0 &&
+		error != GIT_ENOTFOUND)
+		goto done;
+
+	if (msgnum) {
+		rebase->started = 1;
+		rebase->current = msgnum - 1;
+	}
+
+	/* Read 'end' */
+	if ((error = rebase_readint(&end, &buf, &state_path, END_FILE)) < 0)
+		goto done;
+
+	/* Read 'current' if it exists */
+	if ((error = rebase_readoid(&id, &buf, &state_path, CURRENT_FILE)) < 0 &&
+		error != GIT_ENOTFOUND)
+		goto done;
+
+	/* Read cmt.* */
+	git_array_init_to_size(rebase->operations, end);
+	GITERR_CHECK_ARRAY(rebase->operations);
+
+	for (i = 0; i < end; i++) {
+		git_buf_clear(&cmt);
+
+		if ((error = git_buf_printf(&cmt, "cmt.%" PRIuZ, (i+1))) < 0 ||
+			(error = rebase_readoid(&id, &buf, &state_path, cmt.ptr)) < 0)
+			goto done;
+
+		operation = rebase_operation_alloc(rebase, GIT_REBASE_OPERATION_PICK, &id, NULL);
+		GITERR_CHECK_ALLOC(operation);
+	}
+
+	/* Read 'onto_name' */
+	if ((error = rebase_readfile(&buf, &state_path, ONTO_NAME_FILE)) < 0)
+		goto done;
+
+	rebase->onto_name = git_buf_detach(&buf);
+
+done:
+	git_buf_free(&cmt);
+	git_buf_free(&state_path);
+	git_buf_free(&buf);
+
+	return error;
+}
+
+static git_rebase *rebase_alloc(const git_rebase_options *rebase_opts)
+{
+	git_rebase *rebase = git__calloc(1, sizeof(git_rebase));
+
+	if (!rebase)
+		return NULL;
+
+	if (rebase_opts)
+		memcpy(&rebase->options, rebase_opts, sizeof(git_rebase_options));
+	else
+		git_rebase_init_options(&rebase->options, GIT_REBASE_OPTIONS_VERSION);
+
+	if (rebase_opts && rebase_opts->rewrite_notes_ref) {
+		if ((rebase->options.rewrite_notes_ref = git__strdup(rebase_opts->rewrite_notes_ref)) == NULL)
+			return NULL;
+	}
+
+	if ((rebase->options.checkout_options.checkout_strategy & (GIT_CHECKOUT_SAFE | GIT_CHECKOUT_FORCE)) == 0)
+		rebase->options.checkout_options.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+	return rebase;
+}
+
+static int rebase_check_versions(const git_rebase_options *given_opts)
+{
+	GITERR_CHECK_VERSION(given_opts, GIT_REBASE_OPTIONS_VERSION, "git_rebase_options");
+
+	if (given_opts)
+		GITERR_CHECK_VERSION(&given_opts->checkout_options, GIT_CHECKOUT_OPTIONS_VERSION, "git_checkout_options");
+
+	return 0;
+}
+
+int git_rebase_open(
+	git_rebase **out,
+	git_repository *repo,
+	const git_rebase_options *given_opts)
+{
+	git_rebase *rebase;
+	git_buf path = GIT_BUF_INIT, orig_head_name = GIT_BUF_INIT,
+		orig_head_id = GIT_BUF_INIT, onto_id = GIT_BUF_INIT;
+	int state_path_len, error;
+
+	assert(repo);
+
+	if ((error = rebase_check_versions(given_opts)) < 0)
+		return error;
+
+	rebase = rebase_alloc(given_opts);
+	GITERR_CHECK_ALLOC(rebase);
+
+	rebase->repo = repo;
+
+	if ((error = rebase_state_type(&rebase->type, &rebase->state_path, repo)) < 0)
+		goto done;
+
+	if (rebase->type == GIT_REBASE_TYPE_NONE) {
+		giterr_set(GITERR_REBASE, "There is no rebase in progress");
+		error = GIT_ENOTFOUND;
+		goto done;
+	}
+
+	if ((error = git_buf_puts(&path, rebase->state_path)) < 0)
+		goto done;
+
+	state_path_len = git_buf_len(&path);
+
+	if ((error = git_buf_joinpath(&path, path.ptr, HEAD_NAME_FILE)) < 0 ||
+		(error = git_futils_readbuffer(&orig_head_name, path.ptr)) < 0)
+		goto done;
+
+	git_buf_rtrim(&orig_head_name);
+
+	if (strcmp(ORIG_DETACHED_HEAD, orig_head_name.ptr) == 0)
+		rebase->head_detached = 1;
+
+	git_buf_truncate(&path, state_path_len);
+
+	if ((error = git_buf_joinpath(&path, path.ptr, ORIG_HEAD_FILE)) < 0)
+		goto done;
+
+	if (!git_path_isfile(path.ptr)) {
+		/* Previous versions of git.git used 'head' here; support that. */
+		git_buf_truncate(&path, state_path_len);
+
+		if ((error = git_buf_joinpath(&path, path.ptr, HEAD_FILE)) < 0)
+			goto done;
+	}
+
+	if ((error = git_futils_readbuffer(&orig_head_id, path.ptr)) < 0)
+		goto done;
+
+	git_buf_rtrim(&orig_head_id);
+
+	if ((error = git_oid_fromstr(&rebase->orig_head_id, orig_head_id.ptr)) < 0)
+		goto done;
+
+	git_buf_truncate(&path, state_path_len);
+
+	if ((error = git_buf_joinpath(&path, path.ptr, ONTO_FILE)) < 0 ||
+		(error = git_futils_readbuffer(&onto_id, path.ptr)) < 0)
+		goto done;
+
+	git_buf_rtrim(&onto_id);
+
+	if ((error = git_oid_fromstr(&rebase->onto_id, onto_id.ptr)) < 0)
+		goto done;
+
+	if (!rebase->head_detached)
+		rebase->orig_head_name = git_buf_detach(&orig_head_name);
+
+	switch (rebase->type) {
+	case GIT_REBASE_TYPE_INTERACTIVE:
+		giterr_set(GITERR_REBASE, "Interactive rebase is not supported");
+		error = -1;
+		break;
+	case GIT_REBASE_TYPE_MERGE:
+		error = rebase_open_merge(rebase);
+		break;
+	case GIT_REBASE_TYPE_APPLY:
+		giterr_set(GITERR_REBASE, "Patch application rebase is not supported");
+		error = -1;
+		break;
+	default:
+		abort();
+	}
+
+done:
+	if (error == 0)
+		*out = rebase;
+	else
+		git_rebase_free(rebase);
+
+	git_buf_free(&path);
+	git_buf_free(&orig_head_name);
+	git_buf_free(&orig_head_id);
+	git_buf_free(&onto_id);
+	return error;
+}
+
+static int rebase_cleanup(git_rebase *rebase)
+{
+	return git_path_isdir(rebase->state_path) ?
+		git_futils_rmdir_r(rebase->state_path, NULL, GIT_RMDIR_REMOVE_FILES) :
+		0;
+}
+
+static int rebase_setupfile(git_rebase *rebase, const char *filename, int flags, const char *fmt, ...)
+{
+	git_buf path = GIT_BUF_INIT,
+		contents = GIT_BUF_INIT;
+	va_list ap;
+	int error;
+
+	va_start(ap, fmt);
+	git_buf_vprintf(&contents, fmt, ap);
+	va_end(ap);
+
+	if ((error = git_buf_joinpath(&path, rebase->state_path, filename)) == 0)
+		error = git_futils_writebuffer(&contents, path.ptr, flags, REBASE_FILE_MODE);
+
+	git_buf_free(&path);
+	git_buf_free(&contents);
+
+	return error;
+}
+
+static const char *rebase_onto_name(const git_annotated_commit *onto)
+{
+	if (onto->ref_name && git__strncmp(onto->ref_name, "refs/heads/", 11) == 0)
+		return onto->ref_name + 11;
+	else if (onto->ref_name)
+		return onto->ref_name;
+	else
+		return onto->id_str;
+}
+
+static int rebase_setupfiles_merge(git_rebase *rebase)
+{
+	git_buf commit_filename = GIT_BUF_INIT;
+	char id_str[GIT_OID_HEXSZ];
+	git_rebase_operation *operation;
+	size_t i;
+	int error = 0;
+
+	if ((error = rebase_setupfile(rebase, END_FILE, -1, "%" PRIuZ "\n", git_array_size(rebase->operations))) < 0 ||
+		(error = rebase_setupfile(rebase, ONTO_NAME_FILE, -1, "%s\n", rebase->onto_name)) < 0)
+		goto done;
+
+	for (i = 0; i < git_array_size(rebase->operations); i++) {
+		operation = git_array_get(rebase->operations, i);
+
+		git_buf_clear(&commit_filename);
+		git_buf_printf(&commit_filename, CMT_FILE_FMT, i+1);
+
+		git_oid_fmt(id_str, &operation->id);
+
+		if ((error = rebase_setupfile(rebase, commit_filename.ptr, -1,
+				"%.*s\n", GIT_OID_HEXSZ, id_str)) < 0)
+			goto done;
+	}
+
+done:
+	git_buf_free(&commit_filename);
+	return error;
+}
+
+static int rebase_setupfiles(git_rebase *rebase)
+{
+	char onto[GIT_OID_HEXSZ], orig_head[GIT_OID_HEXSZ];
+
+	git_oid_fmt(onto, &rebase->onto_id);
+	git_oid_fmt(orig_head, &rebase->orig_head_id);
+
+	if (p_mkdir(rebase->state_path, REBASE_DIR_MODE) < 0) {
+		giterr_set(GITERR_OS, "Failed to create rebase directory '%s'", rebase->state_path);
+		return -1;
+	}
+
+	if (git_repository__set_orig_head(rebase->repo, &rebase->orig_head_id) < 0 ||
+		rebase_setupfile(rebase, HEAD_NAME_FILE, -1, "%s\n", rebase->orig_head_name) < 0 ||
+		rebase_setupfile(rebase, ONTO_FILE, -1, "%.*s\n", GIT_OID_HEXSZ, onto) < 0 ||
+		rebase_setupfile(rebase, ORIG_HEAD_FILE, -1, "%.*s\n", GIT_OID_HEXSZ, orig_head) < 0 ||
+		rebase_setupfile(rebase, QUIET_FILE, -1, rebase->quiet ? "t\n" : "\n") < 0)
+		return -1;
+
+	return rebase_setupfiles_merge(rebase);
+}
+
+int git_rebase_init_options(git_rebase_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_rebase_options, GIT_REBASE_OPTIONS_INIT);
+	return 0;
+}
+
+static int rebase_ensure_not_in_progress(git_repository *repo)
+{
+	int error;
+	git_rebase_type_t type;
+
+	if ((error = rebase_state_type(&type, NULL, repo)) < 0)
+		return error;
+
+	if (type != GIT_REBASE_TYPE_NONE) {
+		giterr_set(GITERR_REBASE, "There is an existing rebase in progress");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int rebase_ensure_not_dirty(
+	git_repository *repo,
+	bool check_index,
+	bool check_workdir,
+	int fail_with)
+{
+	git_tree *head = NULL;
+	git_index *index = NULL;
+	git_diff *diff = NULL;
+	int error = 0;
+
+	if (check_index) {
+		if ((error = git_repository_head_tree(&head, repo)) < 0 ||
+			(error = git_repository_index(&index, repo)) < 0 ||
+			(error = git_diff_tree_to_index(&diff, repo, head, index, NULL)) < 0)
+			goto done;
+
+		if (git_diff_num_deltas(diff) > 0) {
+			giterr_set(GITERR_REBASE, "Uncommitted changes exist in index");
+			error = fail_with;
+			goto done;
+		}
+
+		git_diff_free(diff);
+		diff = NULL;
+	}
+
+	if (check_workdir) {
+		if ((error = git_diff_index_to_workdir(&diff, repo, index, NULL)) < 0)
+			goto done;
+
+		if (git_diff_num_deltas(diff) > 0) {
+			giterr_set(GITERR_REBASE, "Unstaged changes exist in workdir");
+			error = fail_with;
+			goto done;
+		}
+	}
+
+done:
+	git_diff_free(diff);
+	git_index_free(index);
+	git_tree_free(head);
+
+	return error;
+}
+
+static int rebase_init_operations(
+	git_rebase *rebase,
+	git_repository *repo,
+	const git_annotated_commit *branch,
+	const git_annotated_commit *upstream,
+	const git_annotated_commit *onto)
+{
+	git_revwalk *revwalk = NULL;
+	git_commit *commit;
+	git_oid id;
+	bool merge;
+	git_rebase_operation *operation;
+	int error;
+
+	if (!upstream)
+		upstream = onto;
+
+	if ((error = git_revwalk_new(&revwalk, rebase->repo)) < 0 ||
+		(error = git_revwalk_push(revwalk, git_annotated_commit_id(branch))) < 0 ||
+		(error = git_revwalk_hide(revwalk, git_annotated_commit_id(upstream))) < 0)
+		goto done;
+
+	git_revwalk_sorting(revwalk, GIT_SORT_REVERSE | GIT_SORT_TIME);
+
+	while ((error = git_revwalk_next(&id, revwalk)) == 0) {
+		if ((error = git_commit_lookup(&commit, repo, &id)) < 0)
+			goto done;
+
+		merge = (git_commit_parentcount(commit) > 1);
+		git_commit_free(commit);
+
+		if (merge)
+			continue;
+
+		operation = rebase_operation_alloc(rebase, GIT_REBASE_OPERATION_PICK, &id, NULL);
+		GITERR_CHECK_ALLOC(operation);
+	}
+
+	error = 0;
+
+done:
+	git_revwalk_free(revwalk);
+	return error;
+}
+
+static int rebase_init_merge(
+	git_rebase *rebase,
+	git_repository *repo,
+	const git_annotated_commit *branch,
+	const git_annotated_commit *upstream,
+	const git_annotated_commit *onto)
+{
+	if (rebase_init_operations(rebase, repo, branch, upstream, onto) < 0)
+		return -1;
+
+	rebase->onto_name = git__strdup(rebase_onto_name(onto));
+	GITERR_CHECK_ALLOC(rebase->onto_name);
+
+	return 0;
+}
+
+static int rebase_init(
+	git_rebase *rebase,
+	git_repository *repo,
+	const git_annotated_commit *branch,
+	const git_annotated_commit *upstream,
+	const git_annotated_commit *onto)
+{
+	git_reference *head_ref = NULL;
+	git_annotated_commit *head_branch = NULL;
+	git_buf state_path = GIT_BUF_INIT;
+	int error;
+
+	if ((error = git_buf_joinpath(&state_path, repo->path_repository, REBASE_MERGE_DIR)) < 0)
+		goto done;
+
+	if (!branch) {
+		if ((error = git_repository_head(&head_ref, repo)) < 0 ||
+			(error = git_annotated_commit_from_ref(&head_branch, repo, head_ref)) < 0)
+			goto done;
+
+		branch = head_branch;
+	}
+
+	rebase->repo = repo;
+	rebase->type = GIT_REBASE_TYPE_MERGE;
+	rebase->state_path = git_buf_detach(&state_path);
+	rebase->orig_head_name = git__strdup(branch->ref_name ? branch->ref_name : ORIG_DETACHED_HEAD);
+	rebase->quiet = rebase->options.quiet;
+
+	git_oid_cpy(&rebase->orig_head_id, git_annotated_commit_id(branch));
+	git_oid_cpy(&rebase->onto_id, git_annotated_commit_id(onto));
+
+	if (!rebase->orig_head_name || !rebase->state_path)
+		return -1;
+
+	error = rebase_init_merge(rebase, repo, branch, upstream, onto);
+
+	git_buf_free(&state_path);
+
+done:
+	git_reference_free(head_ref);
+	git_annotated_commit_free(head_branch);
+
+	return error;
+}
+
+int git_rebase_init(
+	git_rebase **out,
+	git_repository *repo,
+	const git_annotated_commit *branch,
+	const git_annotated_commit *upstream,
+	const git_annotated_commit *onto,
+	const git_rebase_options *given_opts)
+{
+	git_rebase *rebase = NULL;
+	git_buf reflog = GIT_BUF_INIT;
+	git_commit *onto_commit = NULL;
+	git_reference *head_ref = NULL;
+	int error;
+
+	assert(repo && (upstream || onto));
+
+	*out = NULL;
+
+	if (!onto)
+		onto = upstream;
+
+	if ((error = rebase_check_versions(given_opts)) < 0 ||
+		(error = git_repository__ensure_not_bare(repo, "rebase")) < 0 ||
+		(error = rebase_ensure_not_in_progress(repo)) < 0 ||
+		(error = rebase_ensure_not_dirty(repo, true, true, GIT_ERROR)) < 0 ||
+		(error = git_commit_lookup(
+			&onto_commit, repo, git_annotated_commit_id(onto))) < 0)
+		return error;
+
+	rebase = rebase_alloc(given_opts);
+
+	if ((error = rebase_init(
+			rebase, repo, branch, upstream, onto)) < 0 ||
+		(error = rebase_setupfiles(rebase)) < 0 ||
+		(error = git_buf_printf(&reflog,
+			"rebase: checkout %s", rebase_onto_name(onto))) < 0 ||
+		(error = git_checkout_tree(
+			repo, (git_object *)onto_commit, &rebase->options.checkout_options)) < 0 ||
+		(error = git_reference_create(&head_ref, repo, GIT_HEAD_FILE,
+			git_annotated_commit_id(onto), 1, reflog.ptr)) < 0)
+		goto done;
+
+	*out = rebase;
+
+done:
+	git_reference_free(head_ref);
+	if (error < 0) {
+		rebase_cleanup(rebase);
+		git_rebase_free(rebase);
+	}
+
+	git_commit_free(onto_commit);
+	git_buf_free(&reflog);
+
+	return error;
+}
+
+static void normalize_checkout_options_for_apply(
+	git_checkout_options *checkout_opts,
+	git_rebase *rebase,
+	git_commit *current_commit)
+{
+	memcpy(checkout_opts, &rebase->options.checkout_options, sizeof(git_checkout_options));
+
+	if (!checkout_opts->ancestor_label)
+		checkout_opts->ancestor_label = "ancestor";
+
+	if (rebase->type == GIT_REBASE_TYPE_MERGE) {
+		if (!checkout_opts->our_label)
+			checkout_opts->our_label = rebase->onto_name;
+
+		if (!checkout_opts->their_label)
+			checkout_opts->their_label = git_commit_summary(current_commit);
+	} else {
+		abort();
+	}
+}
+
+GIT_INLINE(int) rebase_movenext(git_rebase *rebase)
+{
+	size_t next = rebase->started ? rebase->current + 1 : 0;
+
+	if (next == git_array_size(rebase->operations))
+		return GIT_ITEROVER;
+
+	rebase->started = 1;
+	rebase->current = next;
+
+	return 0;
+}
+
+static int rebase_next_merge(
+	git_rebase_operation **out,
+	git_rebase *rebase)
+{
+	git_buf path = GIT_BUF_INIT;
+	git_commit *current_commit = NULL, *parent_commit = NULL;
+	git_tree *current_tree = NULL, *head_tree = NULL, *parent_tree = NULL;
+	git_index *index = NULL;
+	git_indexwriter indexwriter = GIT_INDEXWRITER_INIT;
+	git_rebase_operation *operation;
+	git_checkout_options checkout_opts;
+	char current_idstr[GIT_OID_HEXSZ];
+	unsigned int parent_count;
+	int error;
+
+	*out = NULL;
+
+	if ((error = rebase_movenext(rebase)) < 0)
+		goto done;
+
+	operation = git_array_get(rebase->operations, rebase->current);
+
+	if ((error = git_commit_lookup(&current_commit, rebase->repo, &operation->id)) < 0 ||
+		(error = git_commit_tree(&current_tree, current_commit)) < 0 ||
+		(error = git_repository_head_tree(&head_tree, rebase->repo)) < 0)
+		goto done;
+
+	if ((parent_count = git_commit_parentcount(current_commit)) > 1) {
+		giterr_set(GITERR_REBASE, "Cannot rebase a merge commit");
+		error = -1;
+		goto done;
+	} else if (parent_count) {
+		if ((error = git_commit_parent(&parent_commit, current_commit, 0)) < 0 ||
+			(error = git_commit_tree(&parent_tree, parent_commit)) < 0)
+			goto done;
+	}
+
+	git_oid_fmt(current_idstr, &operation->id);
+
+	normalize_checkout_options_for_apply(&checkout_opts, rebase, current_commit);
+
+	if ((error = git_indexwriter_init_for_operation(&indexwriter, rebase->repo, &checkout_opts.checkout_strategy)) < 0 ||
+		(error = rebase_setupfile(rebase, MSGNUM_FILE, -1, "%" PRIuZ "\n", rebase->current+1)) < 0 ||
+		(error = rebase_setupfile(rebase, CURRENT_FILE, -1, "%.*s\n", GIT_OID_HEXSZ, current_idstr)) < 0 ||
+		(error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, NULL)) < 0 ||
+		(error = git_merge__check_result(rebase->repo, index)) < 0 ||
+		(error = git_checkout_index(rebase->repo, index, &checkout_opts)) < 0 ||
+		(error = git_indexwriter_commit(&indexwriter)) < 0)
+		goto done;
+
+	*out = operation;
+
+done:
+	git_indexwriter_cleanup(&indexwriter);
+	git_index_free(index);
+	git_tree_free(current_tree);
+	git_tree_free(head_tree);
+	git_tree_free(parent_tree);
+	git_commit_free(parent_commit);
+	git_commit_free(current_commit);
+	git_buf_free(&path);
+
+	return error;
+}
+
+int git_rebase_next(
+	git_rebase_operation **out,
+	git_rebase *rebase)
+{
+	int error;
+
+	assert(out && rebase);
+
+	switch (rebase->type) {
+	case GIT_REBASE_TYPE_MERGE:
+		error = rebase_next_merge(out, rebase);
+		break;
+	default:
+		abort();
+	}
+
+	return error;
+}
+
+static int rebase_commit_merge(
+	git_oid *commit_id,
+	git_rebase *rebase,
+	const git_signature *author,
+	const git_signature *committer,
+	const char *message_encoding,
+	const char *message)
+{
+	git_index *index = NULL;
+	git_reference *head = NULL;
+	git_commit *current_commit = NULL, *head_commit = NULL, *commit = NULL;
+	git_rebase_operation *operation;
+	git_tree *head_tree = NULL, *tree = NULL;
+	git_diff *diff = NULL;
+	git_oid tree_id;
+	git_buf reflog_msg = GIT_BUF_INIT;
+	char old_idstr[GIT_OID_HEXSZ], new_idstr[GIT_OID_HEXSZ];
+	int error;
+
+	operation = git_array_get(rebase->operations, rebase->current);
+	assert(operation);
+
+	if ((error = git_repository_index(&index, rebase->repo)) < 0)
+		goto done;
+
+	if (git_index_has_conflicts(index)) {
+		giterr_set(GITERR_REBASE, "Conflicts have not been resolved");
+		error = GIT_EUNMERGED;
+		goto done;
+	}
+
+	if ((error = rebase_ensure_not_dirty(rebase->repo, false, true, GIT_EUNMERGED)) < 0 ||
+		(error = git_commit_lookup(&current_commit, rebase->repo, &operation->id)) < 0 ||
+		(error = git_repository_head(&head, rebase->repo)) < 0 ||
+		(error = git_reference_peel((git_object **)&head_commit, head, GIT_OBJ_COMMIT)) < 0 ||
+		(error = git_commit_tree(&head_tree, head_commit)) < 0 ||
+		(error = git_diff_tree_to_index(&diff, rebase->repo, head_tree, index, NULL)) < 0)
+		goto done;
+
+	if (git_diff_num_deltas(diff) == 0) {
+		giterr_set(GITERR_REBASE, "This patch has already been applied");
+		error = GIT_EAPPLIED;
+		goto done;
+	}
+
+	if ((error = git_index_write_tree(&tree_id, index)) < 0 ||
+		(error = git_tree_lookup(&tree, rebase->repo, &tree_id)) < 0)
+		goto done;
+
+	if (!author)
+		author = git_commit_author(current_commit);
+
+	if (!message) {
+		message_encoding = git_commit_message_encoding(current_commit);
+		message = git_commit_message(current_commit);
+	}
+
+	if ((error = git_commit_create(commit_id, rebase->repo, NULL, author,
+			committer, message_encoding, message, tree, 1,
+			(const git_commit **)&head_commit)) < 0 ||
+		(error = git_commit_lookup(&commit, rebase->repo, commit_id)) < 0 ||
+		(error = git_reference__update_for_commit(
+			rebase->repo, NULL, "HEAD", commit_id, "rebase")) < 0)
+		goto done;
+
+	git_oid_fmt(old_idstr, git_commit_id(current_commit));
+	git_oid_fmt(new_idstr, commit_id);
+
+	error = rebase_setupfile(rebase, REWRITTEN_FILE, O_CREAT|O_WRONLY|O_APPEND,
+		"%.*s %.*s\n", GIT_OID_HEXSZ, old_idstr, GIT_OID_HEXSZ, new_idstr);
+
+done:
+	git_buf_free(&reflog_msg);
+	git_commit_free(commit);
+	git_diff_free(diff);
+	git_tree_free(tree);
+	git_tree_free(head_tree);
+	git_commit_free(head_commit);
+	git_commit_free(current_commit);
+	git_reference_free(head);
+	git_index_free(index);
+
+	return error;
+}
+
+int git_rebase_commit(
+	git_oid *id,
+	git_rebase *rebase,
+	const git_signature *author,
+	const git_signature *committer,
+	const char *message_encoding,
+	const char *message)
+{
+	int error;
+
+	assert(rebase && committer);
+
+	switch (rebase->type) {
+	case GIT_REBASE_TYPE_MERGE:
+		error = rebase_commit_merge(
+			id, rebase, author, committer, message_encoding, message);
+		break;
+	default:
+		abort();
+	}
+
+	return error;
+}
+
+int git_rebase_abort(git_rebase *rebase)
+{
+	git_reference *orig_head_ref = NULL;
+	git_commit *orig_head_commit = NULL;
+	int error;
+
+	assert(rebase);
+
+	error = rebase->head_detached ?
+		git_reference_create(&orig_head_ref, rebase->repo, GIT_HEAD_FILE,
+			 &rebase->orig_head_id, 1, "rebase: aborting") :
+		git_reference_symbolic_create(
+			&orig_head_ref, rebase->repo, GIT_HEAD_FILE, rebase->orig_head_name, 1,
+			"rebase: aborting");
+
+	if (error < 0)
+		goto done;
+
+	if ((error = git_commit_lookup(
+			&orig_head_commit, rebase->repo, &rebase->orig_head_id)) < 0 ||
+		(error = git_reset(rebase->repo, (git_object *)orig_head_commit,
+			GIT_RESET_HARD, &rebase->options.checkout_options)) < 0)
+		goto done;
+
+	error = rebase_cleanup(rebase);
+
+done:
+	git_commit_free(orig_head_commit);
+	git_reference_free(orig_head_ref);
+
+	return error;
+}
+
+static int notes_ref_lookup(git_buf *out, git_rebase *rebase)
+{
+	git_config *config = NULL;
+	int do_rewrite, error;
+
+	if (rebase->options.rewrite_notes_ref) {
+		git_buf_attach_notowned(out,
+			rebase->options.rewrite_notes_ref,
+			strlen(rebase->options.rewrite_notes_ref));
+		return 0;
+	}
+
+	if ((error = git_repository_config(&config, rebase->repo)) < 0 ||
+		(error = git_config_get_bool(&do_rewrite, config, "notes.rewrite.rebase")) < 0) {
+
+		if (error != GIT_ENOTFOUND)
+			goto done;
+
+		giterr_clear();
+		do_rewrite = 1;
+	}
+
+	error = do_rewrite ?
+		git_config_get_string_buf(out, config, "notes.rewriteref") :
+		GIT_ENOTFOUND;
+
+done:
+	git_config_free(config);
+	return error;
+}
+
+static int rebase_copy_note(
+	git_rebase *rebase,
+	const char *notes_ref,
+	git_oid *from,
+	git_oid *to,
+	const git_signature *committer)
+{
+	git_note *note = NULL;
+	git_oid note_id;
+	git_signature *who = NULL;
+	int error;
+
+	if ((error = git_note_read(&note, rebase->repo, notes_ref, from)) < 0) {
+		if (error == GIT_ENOTFOUND) {
+			giterr_clear();
+			error = 0;
+		}
+
+		goto done;
+	}
+
+	if (!committer) {
+		if((error = git_signature_default(&who, rebase->repo)) < 0) {
+			if (error != GIT_ENOTFOUND ||
+				(error = git_signature_now(&who, "unknown", "unknown")) < 0)
+				goto done;
+
+			giterr_clear();
+		}
+
+		committer = who;
+	}
+
+	error = git_note_create(&note_id, rebase->repo, notes_ref,
+		git_note_author(note), committer, to, git_note_message(note), 0);
+
+done:
+	git_note_free(note);
+	git_signature_free(who);
+
+	return error;
+}
+
+static int rebase_copy_notes(
+	git_rebase *rebase,
+	const git_signature *committer)
+{
+	git_buf path = GIT_BUF_INIT, rewritten = GIT_BUF_INIT, notes_ref = GIT_BUF_INIT;
+	char *pair_list, *fromstr, *tostr, *end;
+	git_oid from, to;
+	unsigned int linenum = 1;
+	int error = 0;
+
+	if ((error = notes_ref_lookup(&notes_ref, rebase)) < 0) {
+		if (error == GIT_ENOTFOUND) {
+			giterr_clear();
+			error = 0;
+		}
+
+		goto done;
+	}
+
+	if ((error = git_buf_joinpath(&path, rebase->state_path, REWRITTEN_FILE)) < 0 ||
+		(error = git_futils_readbuffer(&rewritten, path.ptr)) < 0)
+		goto done;
+
+	pair_list = rewritten.ptr;
+
+	while (*pair_list) {
+		fromstr = pair_list;
+
+		if ((end = strchr(fromstr, '\n')) == NULL)
+			goto on_error;
+
+		pair_list = end+1;
+		*end = '\0';
+
+		if ((end = strchr(fromstr, ' ')) == NULL)
+			goto on_error;
+
+		tostr = end+1;
+		*end = '\0';
+
+		if (strlen(fromstr) != GIT_OID_HEXSZ ||
+			strlen(tostr) != GIT_OID_HEXSZ ||
+			git_oid_fromstr(&from, fromstr) < 0 ||
+			git_oid_fromstr(&to, tostr) < 0)
+			goto on_error;
+
+		if ((error = rebase_copy_note(rebase, notes_ref.ptr, &from, &to, committer)) < 0)
+			goto done;
+
+		linenum++;
+	}
+
+	goto done;
+
+on_error:
+	giterr_set(GITERR_REBASE, "Invalid rewritten file at line %d", linenum);
+	error = -1;
+
+done:
+	git_buf_free(&rewritten);
+	git_buf_free(&path);
+	git_buf_free(&notes_ref);
+
+	return error;
+}
+
+int git_rebase_finish(
+	git_rebase *rebase,
+	const git_signature *signature)
+{
+	git_reference *terminal_ref = NULL, *branch_ref = NULL, *head_ref = NULL;
+	git_commit *terminal_commit = NULL;
+	git_buf branch_msg = GIT_BUF_INIT, head_msg = GIT_BUF_INIT;
+	char onto[GIT_OID_HEXSZ];
+	int error;
+
+	assert(rebase);
+
+	git_oid_fmt(onto, &rebase->onto_id);
+
+	if ((error = git_buf_printf(&branch_msg, "rebase finished: %s onto %.*s",
+			rebase->orig_head_name, GIT_OID_HEXSZ, onto)) < 0 ||
+		(error = git_buf_printf(&head_msg, "rebase finished: returning to %s",
+			rebase->orig_head_name)) < 0 ||
+		(error = git_repository_head(&terminal_ref, rebase->repo)) < 0 ||
+		(error = git_reference_peel((git_object **)&terminal_commit,
+			terminal_ref, GIT_OBJ_COMMIT)) < 0 ||
+		(error = git_reference_create_matching(&branch_ref,
+			rebase->repo, rebase->orig_head_name, git_commit_id(terminal_commit), 1,
+			&rebase->orig_head_id, branch_msg.ptr)) < 0 ||
+		(error = git_reference_symbolic_create(&head_ref,
+			rebase->repo, GIT_HEAD_FILE, rebase->orig_head_name, 1,
+			head_msg.ptr)) < 0 ||
+		(error = rebase_copy_notes(rebase, signature)) < 0)
+		goto done;
+
+	error = rebase_cleanup(rebase);
+
+done:
+	git_buf_free(&head_msg);
+	git_buf_free(&branch_msg);
+	git_commit_free(terminal_commit);
+	git_reference_free(head_ref);
+	git_reference_free(branch_ref);
+	git_reference_free(terminal_ref);
+
+	return error;
+}
+
+size_t git_rebase_operation_entrycount(git_rebase *rebase)
+{
+	assert(rebase);
+
+	return git_array_size(rebase->operations);
+}
+
+size_t git_rebase_operation_current(git_rebase *rebase)
+{
+	assert(rebase);
+
+	return rebase->started ? rebase->current : GIT_REBASE_NO_OPERATION;
+}
+
+git_rebase_operation *git_rebase_operation_byindex(git_rebase *rebase, size_t idx)
+{
+	assert(rebase);
+
+	return git_array_get(rebase->operations, idx);
+}
+
+void git_rebase_free(git_rebase *rebase)
+{
+	if (rebase == NULL)
+		return;
+
+	git__free(rebase->onto_name);
+	git__free(rebase->orig_head_name);
+	git__free(rebase->state_path);
+	git_array_clear(rebase->operations);
+	git__free((char *)rebase->options.rewrite_notes_ref);
+	git__free(rebase);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refdb.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refdb.c
new file mode 100755
index 0000000..16fb519
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refdb.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "posix.h"
+
+#include "git2/object.h"
+#include "git2/refs.h"
+#include "git2/refdb.h"
+#include "git2/sys/refdb_backend.h"
+
+#include "hash.h"
+#include "refdb.h"
+#include "refs.h"
+#include "reflog.h"
+
+int git_refdb_new(git_refdb **out, git_repository *repo)
+{
+	git_refdb *db;
+
+	assert(out && repo);
+
+	db = git__calloc(1, sizeof(*db));
+	GITERR_CHECK_ALLOC(db);
+
+	db->repo = repo;
+
+	*out = db;
+	GIT_REFCOUNT_INC(db);
+	return 0;
+}
+
+int git_refdb_open(git_refdb **out, git_repository *repo)
+{
+	git_refdb *db;
+	git_refdb_backend *dir;
+
+	assert(out && repo);
+
+	*out = NULL;
+
+	if (git_refdb_new(&db, repo) < 0)
+		return -1;
+
+	/* Add the default (filesystem) backend */
+	if (git_refdb_backend_fs(&dir, repo) < 0) {
+		git_refdb_free(db);
+		return -1;
+	}
+
+	db->repo = repo;
+	db->backend = dir;
+
+	*out = db;
+	return 0;
+}
+
+static void refdb_free_backend(git_refdb *db)
+{
+	if (db->backend) {
+		if (db->backend->free)
+			db->backend->free(db->backend);
+		else
+			git__free(db->backend);
+	}
+}
+
+int git_refdb_set_backend(git_refdb *db, git_refdb_backend *backend)
+{
+	refdb_free_backend(db);
+	db->backend = backend;
+
+	return 0;
+}
+
+int git_refdb_compress(git_refdb *db)
+{
+	assert(db);
+
+	if (db->backend->compress)
+		return db->backend->compress(db->backend);
+
+	return 0;
+}
+
+void git_refdb__free(git_refdb *db)
+{
+	refdb_free_backend(db);
+	git__memzero(db, sizeof(*db));
+	git__free(db);
+}
+
+void git_refdb_free(git_refdb *db)
+{
+	if (db == NULL)
+		return;
+
+	GIT_REFCOUNT_DEC(db, git_refdb__free);
+}
+
+int git_refdb_exists(int *exists, git_refdb *refdb, const char *ref_name)
+{
+	assert(exists && refdb && refdb->backend);
+
+	return refdb->backend->exists(exists, refdb->backend, ref_name);
+}
+
+int git_refdb_lookup(git_reference **out, git_refdb *db, const char *ref_name)
+{
+	git_reference *ref;
+	int error;
+
+	assert(db && db->backend && out && ref_name);
+
+	error = db->backend->lookup(&ref, db->backend, ref_name);
+	if (error < 0)
+		return error;
+
+	GIT_REFCOUNT_INC(db);
+	ref->db = db;
+
+	*out = ref;
+	return 0;
+}
+
+int git_refdb_iterator(git_reference_iterator **out, git_refdb *db, const char *glob)
+{
+	if (!db->backend || !db->backend->iterator) {
+		giterr_set(GITERR_REFERENCE, "This backend doesn't support iterators");
+		return -1;
+	}
+
+	if (db->backend->iterator(out, db->backend, glob) < 0)
+		return -1;
+
+	GIT_REFCOUNT_INC(db);
+	(*out)->db = db;
+
+	return 0;
+}
+
+int git_refdb_iterator_next(git_reference **out, git_reference_iterator *iter)
+{
+	int error;
+
+	if ((error = iter->next(out, iter)) < 0)
+		return error;
+
+	GIT_REFCOUNT_INC(iter->db);
+	(*out)->db = iter->db;
+
+	return 0;
+}
+
+int git_refdb_iterator_next_name(const char **out, git_reference_iterator *iter)
+{
+	return iter->next_name(out, iter);
+}
+
+void git_refdb_iterator_free(git_reference_iterator *iter)
+{
+	GIT_REFCOUNT_DEC(iter->db, git_refdb__free);
+	iter->free(iter);
+}
+
+int git_refdb_write(git_refdb *db, git_reference *ref, int force, const git_signature *who, const char *message, const git_oid *old_id, const char *old_target)
+{
+	assert(db && db->backend);
+
+	GIT_REFCOUNT_INC(db);
+	ref->db = db;
+
+	return db->backend->write(db->backend, ref, force, who, message, old_id, old_target);
+}
+
+int git_refdb_rename(
+	git_reference **out,
+	git_refdb *db,
+	const char *old_name,
+	const char *new_name,
+	int force,
+	const git_signature *who,
+	const char *message)
+{
+	int error;
+
+	assert(db && db->backend);
+	error = db->backend->rename(out, db->backend, old_name, new_name, force, who, message);
+	if (error < 0)
+		return error;
+
+	if (out) {
+		GIT_REFCOUNT_INC(db);
+		(*out)->db = db;
+	}
+
+	return 0;
+}
+
+int git_refdb_delete(struct git_refdb *db, const char *ref_name, const git_oid *old_id, const char *old_target)
+{
+	assert(db && db->backend);
+	return db->backend->del(db->backend, ref_name, old_id, old_target);
+}
+
+int git_refdb_reflog_read(git_reflog **out, git_refdb *db,  const char *name)
+{
+	int error;
+
+	assert(db && db->backend);
+
+	if ((error = db->backend->reflog_read(out, db->backend, name)) < 0)
+		return error;
+
+	GIT_REFCOUNT_INC(db);
+	(*out)->db = db;
+
+	return 0;
+}
+
+int git_refdb_has_log(git_refdb *db, const char *refname)
+{
+	assert(db && refname);
+
+	return db->backend->has_log(db->backend, refname);
+}
+
+int git_refdb_ensure_log(git_refdb *db, const char *refname)
+{
+	assert(db && refname);
+
+	return db->backend->ensure_log(db->backend, refname);
+}
+
+int git_refdb_init_backend(git_refdb_backend *backend, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		backend, version, git_refdb_backend, GIT_REFDB_BACKEND_INIT);
+	return 0;
+}
+
+int git_refdb_lock(void **payload, git_refdb *db, const char *refname)
+{
+	assert(payload && db && refname);
+
+	if (!db->backend->lock) {
+		giterr_set(GITERR_REFERENCE, "backend does not support locking");
+		return -1;
+	}
+
+	return db->backend->lock(payload, db->backend, refname);
+}
+
+int git_refdb_unlock(git_refdb *db, void *payload, int success, int update_reflog, const git_reference *ref, const git_signature *sig, const char *message)
+{
+	assert(db);
+
+	return db->backend->unlock(db->backend, payload, success, update_reflog, ref, sig, message);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refdb.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refdb.h
new file mode 100755
index 0000000..4ee3b80
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refdb.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_refdb_h__
+#define INCLUDE_refdb_h__
+
+#include "git2/refdb.h"
+#include "repository.h"
+
+struct git_refdb {
+	git_refcount rc;
+	git_repository *repo;
+	git_refdb_backend *backend;
+};
+
+void git_refdb__free(git_refdb *db);
+
+int git_refdb_exists(
+	int *exists,
+	git_refdb *refdb,
+	const char *ref_name);
+
+int git_refdb_lookup(
+	git_reference **out,
+	git_refdb *refdb,
+	const char *ref_name);
+
+int git_refdb_rename(
+	git_reference **out,
+	git_refdb *db,
+	const char *old_name,
+	const char *new_name,
+	int force,
+	const git_signature *who,
+	const char *message);
+
+int git_refdb_iterator(git_reference_iterator **out, git_refdb *db, const char *glob);
+int git_refdb_iterator_next(git_reference **out, git_reference_iterator *iter);
+int git_refdb_iterator_next_name(const char **out, git_reference_iterator *iter);
+void git_refdb_iterator_free(git_reference_iterator *iter);
+
+int git_refdb_write(git_refdb *refdb, git_reference *ref, int force, const git_signature *who, const char *message, const git_oid *old_id, const char *old_target);
+int git_refdb_delete(git_refdb *refdb, const char *ref_name, const git_oid *old_id, const char *old_target);
+
+int git_refdb_reflog_read(git_reflog **out, git_refdb *db,  const char *name);
+int git_refdb_reflog_write(git_reflog *reflog);
+
+int git_refdb_has_log(git_refdb *db, const char *refname);
+int git_refdb_ensure_log(git_refdb *refdb, const char *refname);
+
+int git_refdb_lock(void **payload, git_refdb *db, const char *refname);
+int git_refdb_unlock(git_refdb *db, void *payload, int success, int update_reflog, const git_reference *ref, const git_signature *sig, const char *message);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refdb_fs.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refdb_fs.c
new file mode 100755
index 0000000..e1a77f3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refdb_fs.c
@@ -0,0 +1,1957 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "refs.h"
+#include "hash.h"
+#include "repository.h"
+#include "fileops.h"
+#include "filebuf.h"
+#include "pack.h"
+#include "reflog.h"
+#include "refdb.h"
+#include "refdb_fs.h"
+#include "iterator.h"
+#include "sortedcache.h"
+#include "signature.h"
+
+#include <git2/tag.h>
+#include <git2/object.h>
+#include <git2/refdb.h>
+#include <git2/branch.h>
+#include <git2/sys/refdb_backend.h>
+#include <git2/sys/refs.h>
+#include <git2/sys/reflog.h>
+
+GIT__USE_STRMAP
+
+#define DEFAULT_NESTING_LEVEL	5
+#define MAX_NESTING_LEVEL		10
+
+enum {
+	PACKREF_HAS_PEEL = 1,
+	PACKREF_WAS_LOOSE = 2,
+	PACKREF_CANNOT_PEEL = 4,
+	PACKREF_SHADOWED = 8,
+};
+
+enum {
+	PEELING_NONE = 0,
+	PEELING_STANDARD,
+	PEELING_FULL
+};
+
+struct packref {
+	git_oid oid;
+	git_oid peel;
+	char flags;
+	char name[GIT_FLEX_ARRAY];
+};
+
+typedef struct refdb_fs_backend {
+	git_refdb_backend parent;
+
+	git_repository *repo;
+	char *path;
+
+	git_sortedcache *refcache;
+	int peeling_mode;
+	git_iterator_flag_t iterator_flags;
+	uint32_t direach_flags;
+} refdb_fs_backend;
+
+static int packref_cmp(const void *a_, const void *b_)
+{
+	const struct packref *a = a_, *b = b_;
+	return strcmp(a->name, b->name);
+}
+
+static int packed_reload(refdb_fs_backend *backend)
+{
+	int error;
+	git_buf packedrefs = GIT_BUF_INIT;
+	char *scan, *eof, *eol;
+
+	if (!backend->path)
+		return 0;
+
+	error = git_sortedcache_lockandload(backend->refcache, &packedrefs);
+
+	/*
+	 * If we can't find the packed-refs, clear table and return.
+	 * Any other error just gets passed through.
+	 * If no error, and file wasn't changed, just return.
+	 * Anything else means we need to refresh the packed refs.
+	 */
+	if (error <= 0) {
+		if (error == GIT_ENOTFOUND) {
+			git_sortedcache_clear(backend->refcache, true);
+			giterr_clear();
+			error = 0;
+		}
+		return error;
+	}
+
+	/* At this point, refresh the packed refs from the loaded buffer. */
+
+	git_sortedcache_clear(backend->refcache, false);
+
+	scan = (char *)packedrefs.ptr;
+	eof  = scan + packedrefs.size;
+
+	backend->peeling_mode = PEELING_NONE;
+
+	if (*scan == '#') {
+		static const char *traits_header = "# pack-refs with: ";
+
+		if (git__prefixcmp(scan, traits_header) == 0) {
+			scan += strlen(traits_header);
+			eol = strchr(scan, '\n');
+
+			if (!eol)
+				goto parse_failed;
+			*eol = '\0';
+
+			if (strstr(scan, " fully-peeled ") != NULL) {
+				backend->peeling_mode = PEELING_FULL;
+			} else if (strstr(scan, " peeled ") != NULL) {
+				backend->peeling_mode = PEELING_STANDARD;
+			}
+
+			scan = eol + 1;
+		}
+	}
+
+	while (scan < eof && *scan == '#') {
+		if (!(eol = strchr(scan, '\n')))
+			goto parse_failed;
+		scan = eol + 1;
+	}
+
+	while (scan < eof) {
+		struct packref *ref;
+		git_oid oid;
+
+		/* parse "<OID> <refname>\n" */
+
+		if (git_oid_fromstr(&oid, scan) < 0)
+			goto parse_failed;
+		scan += GIT_OID_HEXSZ;
+
+		if (*scan++ != ' ')
+			goto parse_failed;
+		if (!(eol = strchr(scan, '\n')))
+			goto parse_failed;
+		*eol = '\0';
+		if (eol[-1] == '\r')
+			eol[-1] = '\0';
+
+		if (git_sortedcache_upsert((void **)&ref, backend->refcache, scan) < 0)
+			goto parse_failed;
+		scan = eol + 1;
+
+		git_oid_cpy(&ref->oid, &oid);
+
+		/* look for optional "^<OID>\n" */
+
+		if (*scan == '^') {
+			if (git_oid_fromstr(&oid, scan + 1) < 0)
+				goto parse_failed;
+			scan += GIT_OID_HEXSZ + 1;
+
+			if (scan < eof) {
+				if (!(eol = strchr(scan, '\n')))
+					goto parse_failed;
+				scan = eol + 1;
+			}
+
+			git_oid_cpy(&ref->peel, &oid);
+			ref->flags |= PACKREF_HAS_PEEL;
+		}
+		else if (backend->peeling_mode == PEELING_FULL ||
+				(backend->peeling_mode == PEELING_STANDARD &&
+				 git__prefixcmp(ref->name, GIT_REFS_TAGS_DIR) == 0))
+			ref->flags |= PACKREF_CANNOT_PEEL;
+	}
+
+	git_sortedcache_wunlock(backend->refcache);
+	git_buf_free(&packedrefs);
+
+	return 0;
+
+parse_failed:
+	giterr_set(GITERR_REFERENCE, "Corrupted packed references file");
+
+	git_sortedcache_clear(backend->refcache, false);
+	git_sortedcache_wunlock(backend->refcache);
+	git_buf_free(&packedrefs);
+
+	return -1;
+}
+
+static int loose_parse_oid(
+	git_oid *oid, const char *filename, git_buf *file_content)
+{
+	const char *str = git_buf_cstr(file_content);
+
+	if (git_buf_len(file_content) < GIT_OID_HEXSZ)
+		goto corrupted;
+
+	/* we need to get 40 OID characters from the file */
+	if (git_oid_fromstr(oid, str) < 0)
+		goto corrupted;
+
+	/* If the file is longer than 40 chars, the 41st must be a space */
+	str += GIT_OID_HEXSZ;
+	if (*str == '\0' || git__isspace(*str))
+		return 0;
+
+corrupted:
+	giterr_set(GITERR_REFERENCE, "Corrupted loose reference file: %s", filename);
+	return -1;
+}
+
+static int loose_readbuffer(git_buf *buf, const char *base, const char *path)
+{
+	int error;
+
+	/* build full path to file */
+	if ((error = git_buf_joinpath(buf, base, path)) < 0 ||
+		(error = git_futils_readbuffer(buf, buf->ptr)) < 0)
+		git_buf_free(buf);
+
+	return error;
+}
+
+static int loose_lookup_to_packfile(refdb_fs_backend *backend, const char *name)
+{
+	int error = 0;
+	git_buf ref_file = GIT_BUF_INIT;
+	struct packref *ref = NULL;
+	git_oid oid;
+
+	/* if we fail to load the loose reference, assume someone changed
+	 * the filesystem under us and skip it...
+	 */
+	if (loose_readbuffer(&ref_file, backend->path, name) < 0) {
+		giterr_clear();
+		goto done;
+	}
+
+	/* skip symbolic refs */
+	if (!git__prefixcmp(git_buf_cstr(&ref_file), GIT_SYMREF))
+		goto done;
+
+	/* parse OID from file */
+	if ((error = loose_parse_oid(&oid, name, &ref_file)) < 0)
+		goto done;
+
+	git_sortedcache_wlock(backend->refcache);
+
+	if (!(error = git_sortedcache_upsert(
+			(void **)&ref, backend->refcache, name))) {
+
+		git_oid_cpy(&ref->oid, &oid);
+		ref->flags = PACKREF_WAS_LOOSE;
+	}
+
+	git_sortedcache_wunlock(backend->refcache);
+
+done:
+	git_buf_free(&ref_file);
+	return error;
+}
+
+static int _dirent_loose_load(void *payload, git_buf *full_path)
+{
+	refdb_fs_backend *backend = payload;
+	const char *file_path;
+
+	if (git__suffixcmp(full_path->ptr, ".lock") == 0)
+		return 0;
+
+	if (git_path_isdir(full_path->ptr)) {
+		int error = git_path_direach(
+			full_path, backend->direach_flags, _dirent_loose_load, backend);
+		/* Race with the filesystem, ignore it */
+		if (error == GIT_ENOTFOUND) {
+			giterr_clear();
+			return 0;
+		}
+
+		return error;
+	}
+
+	file_path = full_path->ptr + strlen(backend->path);
+
+	return loose_lookup_to_packfile(backend, file_path);
+}
+
+/*
+ * Load all the loose references from the repository
+ * into the in-memory Packfile, and build a vector with
+ * all the references so it can be written back to
+ * disk.
+ */
+static int packed_loadloose(refdb_fs_backend *backend)
+{
+	int error;
+	git_buf refs_path = GIT_BUF_INIT;
+
+	if (git_buf_joinpath(&refs_path, backend->path, GIT_REFS_DIR) < 0)
+		return -1;
+
+	/*
+	 * Load all the loose files from disk into the Packfile table.
+	 * This will overwrite any old packed entries with their
+	 * updated loose versions
+	 */
+	error = git_path_direach(
+		&refs_path, backend->direach_flags, _dirent_loose_load, backend);
+
+	git_buf_free(&refs_path);
+
+	return error;
+}
+
+static int refdb_fs_backend__exists(
+	int *exists,
+	git_refdb_backend *_backend,
+	const char *ref_name)
+{
+	refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
+	git_buf ref_path = GIT_BUF_INIT;
+
+	assert(backend);
+
+	if (packed_reload(backend) < 0 ||
+		git_buf_joinpath(&ref_path, backend->path, ref_name) < 0)
+		return -1;
+
+	*exists = git_path_isfile(ref_path.ptr) ||
+		(git_sortedcache_lookup(backend->refcache, ref_name) != NULL);
+
+	git_buf_free(&ref_path);
+	return 0;
+}
+
+static const char *loose_parse_symbolic(git_buf *file_content)
+{
+	const unsigned int header_len = (unsigned int)strlen(GIT_SYMREF);
+	const char *refname_start;
+
+	refname_start = (const char *)file_content->ptr;
+
+	if (git_buf_len(file_content) < header_len + 1) {
+		giterr_set(GITERR_REFERENCE, "Corrupted loose reference file");
+		return NULL;
+	}
+
+	/*
+	 * Assume we have already checked for the header
+	 * before calling this function
+	 */
+	refname_start += header_len;
+
+	return refname_start;
+}
+
+static int loose_lookup(
+	git_reference **out,
+	refdb_fs_backend *backend,
+	const char *ref_name)
+{
+	git_buf ref_file = GIT_BUF_INIT;
+	int error = 0;
+
+	if (out)
+		*out = NULL;
+
+	if ((error = loose_readbuffer(&ref_file, backend->path, ref_name)) < 0)
+		/* cannot read loose ref file - gah */;
+	else if (git__prefixcmp(git_buf_cstr(&ref_file), GIT_SYMREF) == 0) {
+		const char *target;
+
+		git_buf_rtrim(&ref_file);
+
+		if (!(target = loose_parse_symbolic(&ref_file)))
+			error = -1;
+		else if (out != NULL)
+			*out = git_reference__alloc_symbolic(ref_name, target);
+	} else {
+		git_oid oid;
+
+		if (!(error = loose_parse_oid(&oid, ref_name, &ref_file)) &&
+			out != NULL)
+			*out = git_reference__alloc(ref_name, &oid, NULL);
+	}
+
+	git_buf_free(&ref_file);
+	return error;
+}
+
+static int ref_error_notfound(const char *name)
+{
+	giterr_set(GITERR_REFERENCE, "Reference '%s' not found", name);
+	return GIT_ENOTFOUND;
+}
+
+static int packed_lookup(
+	git_reference **out,
+	refdb_fs_backend *backend,
+	const char *ref_name)
+{
+	int error = 0;
+	struct packref *entry;
+
+	if (packed_reload(backend) < 0)
+		return -1;
+
+	if (git_sortedcache_rlock(backend->refcache) < 0)
+		return -1;
+
+	entry = git_sortedcache_lookup(backend->refcache, ref_name);
+	if (!entry) {
+		error = ref_error_notfound(ref_name);
+	} else {
+		*out = git_reference__alloc(ref_name, &entry->oid, &entry->peel);
+		if (!*out)
+			error = -1;
+	}
+
+	git_sortedcache_runlock(backend->refcache);
+
+	return error;
+}
+
+static int refdb_fs_backend__lookup(
+	git_reference **out,
+	git_refdb_backend *_backend,
+	const char *ref_name)
+{
+	refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
+	int error;
+
+	assert(backend);
+
+	if (!(error = loose_lookup(out, backend, ref_name)))
+		return 0;
+
+	/* only try to lookup this reference on the packfile if it
+	 * wasn't found on the loose refs; not if there was a critical error */
+	if (error == GIT_ENOTFOUND) {
+		giterr_clear();
+		error = packed_lookup(out, backend, ref_name);
+	}
+
+	return error;
+}
+
+typedef struct {
+	git_reference_iterator parent;
+
+	char *glob;
+
+	git_pool pool;
+	git_vector loose;
+
+	git_sortedcache *cache;
+	size_t loose_pos;
+	size_t packed_pos;
+} refdb_fs_iter;
+
+static void refdb_fs_backend__iterator_free(git_reference_iterator *_iter)
+{
+	refdb_fs_iter *iter = (refdb_fs_iter *) _iter;
+
+	git_vector_free(&iter->loose);
+	git_pool_clear(&iter->pool);
+	git_sortedcache_free(iter->cache);
+	git__free(iter);
+}
+
+static int iter_load_loose_paths(refdb_fs_backend *backend, refdb_fs_iter *iter)
+{
+	int error = 0;
+	git_buf path = GIT_BUF_INIT;
+	git_iterator *fsit = NULL;
+	const git_index_entry *entry = NULL;
+
+	if (!backend->path) /* do nothing if no path for loose refs */
+		return 0;
+
+	if ((error = git_buf_printf(&path, "%s/refs", backend->path)) < 0 ||
+		(error = git_iterator_for_filesystem(
+			&fsit, path.ptr, backend->iterator_flags, NULL, NULL)) < 0) {
+		git_buf_free(&path);
+		return error;
+	}
+
+	error = git_buf_sets(&path, GIT_REFS_DIR);
+
+	while (!error && !git_iterator_advance(&entry, fsit)) {
+		const char *ref_name;
+		struct packref *ref;
+		char *ref_dup;
+
+		git_buf_truncate(&path, strlen(GIT_REFS_DIR));
+		git_buf_puts(&path, entry->path);
+		ref_name = git_buf_cstr(&path);
+
+		if (git__suffixcmp(ref_name, ".lock") == 0 ||
+			(iter->glob && p_fnmatch(iter->glob, ref_name, 0) != 0))
+			continue;
+
+		git_sortedcache_rlock(backend->refcache);
+		ref = git_sortedcache_lookup(backend->refcache, ref_name);
+		if (ref)
+			ref->flags |= PACKREF_SHADOWED;
+		git_sortedcache_runlock(backend->refcache);
+
+		ref_dup = git_pool_strdup(&iter->pool, ref_name);
+		if (!ref_dup)
+			error = -1;
+		else
+			error = git_vector_insert(&iter->loose, ref_dup);
+	}
+
+	git_iterator_free(fsit);
+	git_buf_free(&path);
+
+	return error;
+}
+
+static int refdb_fs_backend__iterator_next(
+	git_reference **out, git_reference_iterator *_iter)
+{
+	int error = GIT_ITEROVER;
+	refdb_fs_iter *iter = (refdb_fs_iter *)_iter;
+	refdb_fs_backend *backend = (refdb_fs_backend *)iter->parent.db->backend;
+	struct packref *ref;
+
+	while (iter->loose_pos < iter->loose.length) {
+		const char *path = git_vector_get(&iter->loose, iter->loose_pos++);
+
+		if (loose_lookup(out, backend, path) == 0)
+			return 0;
+
+		giterr_clear();
+	}
+
+	if (!iter->cache) {
+		if ((error = git_sortedcache_copy(&iter->cache, backend->refcache, 1, NULL, NULL)) < 0)
+			return error;
+	}
+
+	error = GIT_ITEROVER;
+	while (iter->packed_pos < git_sortedcache_entrycount(iter->cache)) {
+		ref = git_sortedcache_entry(iter->cache, iter->packed_pos++);
+		if (!ref) /* stop now if another thread deleted refs and we past end */
+			break;
+
+		if (ref->flags & PACKREF_SHADOWED)
+			continue;
+		if (iter->glob && p_fnmatch(iter->glob, ref->name, 0) != 0)
+			continue;
+
+		*out = git_reference__alloc(ref->name, &ref->oid, &ref->peel);
+		error = (*out != NULL) ? 0 : -1;
+		break;
+	}
+
+	return error;
+}
+
+static int refdb_fs_backend__iterator_next_name(
+	const char **out, git_reference_iterator *_iter)
+{
+	int error = GIT_ITEROVER;
+	refdb_fs_iter *iter = (refdb_fs_iter *)_iter;
+	refdb_fs_backend *backend = (refdb_fs_backend *)iter->parent.db->backend;
+	struct packref *ref;
+
+	while (iter->loose_pos < iter->loose.length) {
+		const char *path = git_vector_get(&iter->loose, iter->loose_pos++);
+
+		if (loose_lookup(NULL, backend, path) == 0) {
+			*out = path;
+			return 0;
+		}
+
+		giterr_clear();
+	}
+
+	if (!iter->cache) {
+		if ((error = git_sortedcache_copy(&iter->cache, backend->refcache, 1, NULL, NULL)) < 0)
+			return error;
+	}
+
+	error = GIT_ITEROVER;
+	while (iter->packed_pos < git_sortedcache_entrycount(iter->cache)) {
+		ref = git_sortedcache_entry(iter->cache, iter->packed_pos++);
+		if (!ref) /* stop now if another thread deleted refs and we past end */
+			break;
+
+		if (ref->flags & PACKREF_SHADOWED)
+			continue;
+		if (iter->glob && p_fnmatch(iter->glob, ref->name, 0) != 0)
+			continue;
+
+		*out = ref->name;
+		error = 0;
+		break;
+	}
+
+	return error;
+}
+
+static int refdb_fs_backend__iterator(
+	git_reference_iterator **out, git_refdb_backend *_backend, const char *glob)
+{
+	refdb_fs_iter *iter;
+	refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
+
+	assert(backend);
+
+	if (packed_reload(backend) < 0)
+		return -1;
+
+	iter = git__calloc(1, sizeof(refdb_fs_iter));
+	GITERR_CHECK_ALLOC(iter);
+
+	if (git_pool_init(&iter->pool, 1, 0) < 0 ||
+		git_vector_init(&iter->loose, 8, NULL) < 0)
+		goto fail;
+
+	if (glob != NULL &&
+		(iter->glob = git_pool_strdup(&iter->pool, glob)) == NULL)
+		goto fail;
+
+	iter->parent.next = refdb_fs_backend__iterator_next;
+	iter->parent.next_name = refdb_fs_backend__iterator_next_name;
+	iter->parent.free = refdb_fs_backend__iterator_free;
+
+	if (iter_load_loose_paths(backend, iter) < 0)
+		goto fail;
+
+	*out = (git_reference_iterator *)iter;
+	return 0;
+
+fail:
+	refdb_fs_backend__iterator_free((git_reference_iterator *)iter);
+	return -1;
+}
+
+static bool ref_is_available(
+	const char *old_ref, const char *new_ref, const char *this_ref)
+{
+	if (old_ref == NULL || strcmp(old_ref, this_ref)) {
+		size_t reflen = strlen(this_ref);
+		size_t newlen = strlen(new_ref);
+		size_t cmplen = reflen < newlen ? reflen : newlen;
+		const char *lead = reflen < newlen ? new_ref : this_ref;
+
+		if (!strncmp(new_ref, this_ref, cmplen) && lead[cmplen] == '/') {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static int reference_path_available(
+	refdb_fs_backend *backend,
+	const char *new_ref,
+	const char* old_ref,
+	int force)
+{
+	size_t i;
+
+	if (packed_reload(backend) < 0)
+		return -1;
+
+	if (!force) {
+		int exists;
+
+		if (refdb_fs_backend__exists(
+				&exists, (git_refdb_backend *)backend, new_ref) < 0)
+			return -1;
+
+		if (exists) {
+			giterr_set(GITERR_REFERENCE,
+				"Failed to write reference '%s': a reference with "
+				"that name already exists.", new_ref);
+			return GIT_EEXISTS;
+		}
+	}
+
+	git_sortedcache_rlock(backend->refcache);
+
+	for (i = 0; i < git_sortedcache_entrycount(backend->refcache); ++i) {
+		struct packref *ref = git_sortedcache_entry(backend->refcache, i);
+
+		if (ref && !ref_is_available(old_ref, new_ref, ref->name)) {
+			git_sortedcache_runlock(backend->refcache);
+			giterr_set(GITERR_REFERENCE,
+				"Path to reference '%s' collides with existing one", new_ref);
+			return -1;
+		}
+	}
+
+	git_sortedcache_runlock(backend->refcache);
+	return 0;
+}
+
+static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *name)
+{
+	int error;
+	git_buf ref_path = GIT_BUF_INIT;
+
+	assert(file && backend && name);
+
+	if (!git_path_isvalid(backend->repo, name, GIT_PATH_REJECT_DEFAULTS)) {
+		giterr_set(GITERR_INVALID, "Invalid reference name '%s'.", name);
+		return GIT_EINVALIDSPEC;
+	}
+
+	/* Remove a possibly existing empty directory hierarchy
+	 * which name would collide with the reference name
+	 */
+	if (git_futils_rmdir_r(name, backend->path, GIT_RMDIR_SKIP_NONEMPTY) < 0)
+		return -1;
+
+	if (git_buf_joinpath(&ref_path, backend->path, name) < 0)
+		return -1;
+
+	error = git_filebuf_open(file, ref_path.ptr, GIT_FILEBUF_FORCE, GIT_REFS_FILE_MODE);
+
+	git_buf_free(&ref_path);
+        return error;
+}
+
+static int loose_commit(git_filebuf *file, const git_reference *ref)
+{
+	assert(file && ref);
+
+	if (ref->type == GIT_REF_OID) {
+		char oid[GIT_OID_HEXSZ + 1];
+		git_oid_nfmt(oid, sizeof(oid), &ref->target.oid);
+
+		git_filebuf_printf(file, "%s\n", oid);
+	} else if (ref->type == GIT_REF_SYMBOLIC) {
+		git_filebuf_printf(file, GIT_SYMREF "%s\n", ref->target.symbolic);
+	} else {
+		assert(0); /* don't let this happen */
+	}
+
+	return git_filebuf_commit(file);
+}
+
+static int refdb_fs_backend__lock(void **out, git_refdb_backend *_backend, const char *refname)
+{
+	int error;
+	git_filebuf *lock;
+	refdb_fs_backend *backend = (refdb_fs_backend *) _backend;
+
+	lock = git__calloc(1, sizeof(git_filebuf));
+	GITERR_CHECK_ALLOC(lock);
+
+	if ((error = loose_lock(lock, backend, refname)) < 0) {
+		git__free(lock);
+		return error;
+	}
+
+	*out = lock;
+	return 0;
+}
+
+static int refdb_fs_backend__write_tail(
+	git_refdb_backend *_backend,
+	const git_reference *ref,
+	git_filebuf *file,
+	int update_reflog,
+	const git_signature *who,
+	const char *message,
+	const git_oid *old_id,
+	const char *old_target);
+
+static int refdb_fs_backend__delete_tail(
+	git_refdb_backend *_backend,
+	git_filebuf *file,
+	const char *ref_name,
+	const git_oid *old_id, const char *old_target);
+
+static int refdb_fs_backend__unlock(git_refdb_backend *backend, void *payload, int success, int update_reflog,
+				    const git_reference *ref, const git_signature *sig, const char *message)
+{
+	git_filebuf *lock = (git_filebuf *) payload;
+	int error = 0;
+
+	if (success == 2)
+		error = refdb_fs_backend__delete_tail(backend, lock, ref->name, NULL, NULL);
+	else if (success)
+		error = refdb_fs_backend__write_tail(backend, ref, lock, update_reflog, sig, message, NULL, NULL);
+	else
+		git_filebuf_cleanup(lock);
+
+	git__free(lock);
+	return error;
+}
+
+/*
+ * Find out what object this reference resolves to.
+ *
+ * For references that point to a 'big' tag (e.g. an
+ * actual tag object on the repository), we need to
+ * cache on the packfile the OID of the object to
+ * which that 'big tag' is pointing to.
+ */
+static int packed_find_peel(refdb_fs_backend *backend, struct packref *ref)
+{
+	git_object *object;
+
+	if (ref->flags & PACKREF_HAS_PEEL || ref->flags & PACKREF_CANNOT_PEEL)
+		return 0;
+
+	/*
+	 * Find the tagged object in the repository
+	 */
+	if (git_object_lookup(&object, backend->repo, &ref->oid, GIT_OBJ_ANY) < 0)
+		return -1;
+
+	/*
+	 * If the tagged object is a Tag object, we need to resolve it;
+	 * if the ref is actually a 'weak' ref, we don't need to resolve
+	 * anything.
+	 */
+	if (git_object_type(object) == GIT_OBJ_TAG) {
+		git_tag *tag = (git_tag *)object;
+
+		/*
+		 * Find the object pointed at by this tag
+		 */
+		git_oid_cpy(&ref->peel, git_tag_target_id(tag));
+		ref->flags |= PACKREF_HAS_PEEL;
+
+		/*
+		 * The reference has now cached the resolved OID, and is
+		 * marked at such. When written to the packfile, it'll be
+		 * accompanied by this resolved oid
+		 */
+	}
+
+	git_object_free(object);
+	return 0;
+}
+
+/*
+ * Write a single reference into a packfile
+ */
+static int packed_write_ref(struct packref *ref, git_filebuf *file)
+{
+	char oid[GIT_OID_HEXSZ + 1];
+	git_oid_nfmt(oid, sizeof(oid), &ref->oid);
+
+	/*
+	 * For references that peel to an object in the repo, we must
+	 * write the resulting peel on a separate line, e.g.
+	 *
+	 *	6fa8a902cc1d18527e1355773c86721945475d37 refs/tags/libgit2-0.4
+	 *	^2ec0cb7959b0bf965d54f95453f5b4b34e8d3100
+	 *
+	 * This obviously only applies to tags.
+	 * The required peels have already been loaded into `ref->peel_target`.
+	 */
+	if (ref->flags & PACKREF_HAS_PEEL) {
+		char peel[GIT_OID_HEXSZ + 1];
+		git_oid_nfmt(peel, sizeof(peel), &ref->peel);
+
+		if (git_filebuf_printf(file, "%s %s\n^%s\n", oid, ref->name, peel) < 0)
+			return -1;
+	} else {
+		if (git_filebuf_printf(file, "%s %s\n", oid, ref->name) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Remove all loose references
+ *
+ * Once we have successfully written a packfile,
+ * all the loose references that were packed must be
+ * removed from disk.
+ *
+ * This is a dangerous method; make sure the packfile
+ * is well-written, because we are destructing references
+ * here otherwise.
+ */
+static int packed_remove_loose(refdb_fs_backend *backend)
+{
+	size_t i;
+	git_buf full_path = GIT_BUF_INIT;
+	int failed = 0;
+
+	/* backend->refcache is already locked when this is called */
+
+	for (i = 0; i < git_sortedcache_entrycount(backend->refcache); ++i) {
+		struct packref *ref = git_sortedcache_entry(backend->refcache, i);
+
+		if (!ref || !(ref->flags & PACKREF_WAS_LOOSE))
+			continue;
+
+		if (git_buf_joinpath(&full_path, backend->path, ref->name) < 0)
+			return -1; /* critical; do not try to recover on oom */
+
+		if (git_path_exists(full_path.ptr) && p_unlink(full_path.ptr) < 0) {
+			if (failed)
+				continue;
+
+			giterr_set(GITERR_REFERENCE,
+				"Failed to remove loose reference '%s' after packing: %s",
+				full_path.ptr, strerror(errno));
+			failed = 1;
+		}
+
+		/*
+		 * if we fail to remove a single file, this is *not* good,
+		 * but we should keep going and remove as many as possible.
+		 * After we've removed as many files as possible, we return
+		 * the error code anyway.
+		 */
+	}
+
+	git_buf_free(&full_path);
+	return failed ? -1 : 0;
+}
+
+/*
+ * Write all the contents in the in-memory packfile to disk.
+ */
+static int packed_write(refdb_fs_backend *backend)
+{
+	git_sortedcache *refcache = backend->refcache;
+	git_filebuf pack_file = GIT_FILEBUF_INIT;
+	size_t i;
+
+	/* lock the cache to updates while we do this */
+	if (git_sortedcache_wlock(refcache) < 0)
+		return -1;
+
+	/* Open the file! */
+	if (git_filebuf_open(&pack_file, git_sortedcache_path(refcache), 0, GIT_PACKEDREFS_FILE_MODE) < 0)
+		goto fail;
+
+	/* Packfiles have a header... apparently
+	 * This is in fact not required, but we might as well print it
+	 * just for kicks */
+	if (git_filebuf_printf(&pack_file, "%s\n", GIT_PACKEDREFS_HEADER) < 0)
+		goto fail;
+
+	for (i = 0; i < git_sortedcache_entrycount(refcache); ++i) {
+		struct packref *ref = git_sortedcache_entry(refcache, i);
+
+		if (packed_find_peel(backend, ref) < 0)
+			goto fail;
+
+		if (packed_write_ref(ref, &pack_file) < 0)
+			goto fail;
+	}
+
+	/* if we've written all the references properly, we can commit
+	 * the packfile to make the changes effective */
+	if (git_filebuf_commit(&pack_file) < 0)
+		goto fail;
+
+	/* when and only when the packfile has been properly written,
+	 * we can go ahead and remove the loose refs */
+	if (packed_remove_loose(backend) < 0)
+		goto fail;
+
+	git_sortedcache_updated(refcache);
+	git_sortedcache_wunlock(refcache);
+
+	/* we're good now */
+	return 0;
+
+fail:
+	git_filebuf_cleanup(&pack_file);
+	git_sortedcache_wunlock(refcache);
+
+	return -1;
+}
+
+static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, const git_oid *old, const git_oid *new, const git_signature *author, const char *message);
+static int has_reflog(git_repository *repo, const char *name);
+
+/* We only write if it's under heads/, remotes/ or notes/ or if it already has a log */
+static int should_write_reflog(int *write, git_repository *repo, const char *name)
+{
+	int error, logall;
+
+	error = git_repository__cvar(&logall, repo, GIT_CVAR_LOGALLREFUPDATES);
+	if (error < 0)
+		return error;
+
+	/* Defaults to the opposite of the repo being bare */
+	if (logall == GIT_LOGALLREFUPDATES_UNSET)
+		logall = !git_repository_is_bare(repo);
+
+	if (!logall) {
+		*write = 0;
+	} else if (has_reflog(repo, name)) {
+		*write = 1;
+	} else if (!git__prefixcmp(name, GIT_REFS_HEADS_DIR) ||
+		   !git__strcmp(name, GIT_HEAD_FILE) ||
+		   !git__prefixcmp(name, GIT_REFS_REMOTES_DIR) ||
+		   !git__prefixcmp(name, GIT_REFS_NOTES_DIR)) {
+		*write = 1;
+	} else {
+		*write = 0;
+	}
+
+	return 0;
+}
+
+static int cmp_old_ref(int *cmp, git_refdb_backend *backend, const char *name,
+	const git_oid *old_id, const char *old_target)
+{
+	int error = 0;
+	git_reference *old_ref = NULL;
+
+	*cmp = 0;
+	/* It "matches" if there is no old value to compare against */
+	if (!old_id && !old_target)
+		return 0;
+
+	if ((error = refdb_fs_backend__lookup(&old_ref, backend, name)) < 0)
+		goto out;
+
+	/* If the types don't match, there's no way the values do */
+	if (old_id && old_ref->type != GIT_REF_OID) {
+		*cmp = -1;
+		goto out;
+	}
+	if (old_target && old_ref->type != GIT_REF_SYMBOLIC) {
+		*cmp = 1;
+		goto out;
+	}
+
+	if (old_id && old_ref->type == GIT_REF_OID)
+		*cmp = git_oid_cmp(old_id, &old_ref->target.oid);
+
+	if (old_target && old_ref->type == GIT_REF_SYMBOLIC)
+		*cmp = git__strcmp(old_target, old_ref->target.symbolic);
+
+out:
+	git_reference_free(old_ref);
+
+	return error;
+}
+
+/*
+ * The git.git comment regarding this, for your viewing pleasure:
+ *
+ * Special hack: If a branch is updated directly and HEAD
+ * points to it (may happen on the remote side of a push
+ * for example) then logically the HEAD reflog should be
+ * updated too.
+ * A generic solution implies reverse symref information,
+ * but finding all symrefs pointing to the given branch
+ * would be rather costly for this rare event (the direct
+ * update of a branch) to be worth it.  So let's cheat and
+ * check with HEAD only which should cover 99% of all usage
+ * scenarios (even 100% of the default ones).
+ */
+static int maybe_append_head(refdb_fs_backend *backend, const git_reference *ref, const git_signature *who, const char *message)
+{
+	int error;
+	git_oid old_id = {{0}};
+	git_reference *tmp = NULL, *head = NULL, *peeled = NULL;
+	const char *name;
+
+	if (ref->type == GIT_REF_SYMBOLIC)
+		return 0;
+
+	/* if we can't resolve, we use {0}*40 as old id */
+	git_reference_name_to_id(&old_id, backend->repo, ref->name);
+
+	if ((error = git_reference_lookup(&head, backend->repo, GIT_HEAD_FILE)) < 0)
+		return error;
+
+	if (git_reference_type(head) == GIT_REF_OID)
+		goto cleanup;
+
+	if ((error = git_reference_lookup(&tmp, backend->repo, GIT_HEAD_FILE)) < 0)
+		goto cleanup;
+
+	/* Go down the symref chain until we find the branch */
+	while (git_reference_type(tmp) == GIT_REF_SYMBOLIC) {
+		error = git_reference_lookup(&peeled, backend->repo, git_reference_symbolic_target(tmp));
+		if (error < 0)
+			break;
+
+		git_reference_free(tmp);
+		tmp = peeled;
+	}
+
+	if (error == GIT_ENOTFOUND) {
+		error = 0;
+		name = git_reference_symbolic_target(tmp);
+	} else if (error < 0) {
+		goto cleanup;
+	} else {
+		name = git_reference_name(tmp);
+	}
+
+	if (strcmp(name, ref->name))
+		goto cleanup;
+
+	error = reflog_append(backend, head, &old_id, git_reference_target(ref), who, message);
+
+cleanup:
+	git_reference_free(tmp);
+	git_reference_free(head);
+	return error;
+}
+
+static int refdb_fs_backend__write(
+	git_refdb_backend *_backend,
+	const git_reference *ref,
+	int force,
+	const git_signature *who,
+	const char *message,
+	const git_oid *old_id,
+	const char *old_target)
+{
+	refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
+	git_filebuf file = GIT_FILEBUF_INIT;
+	int error = 0;
+
+	assert(backend);
+
+	error = reference_path_available(backend, ref->name, NULL, force);
+	if (error < 0)
+		return error;
+
+	/* We need to perform the reflog append and old value check under the ref's lock */
+	if ((error = loose_lock(&file, backend, ref->name)) < 0)
+		return error;
+
+	return refdb_fs_backend__write_tail(_backend, ref, &file, true, who, message, old_id, old_target);
+}
+
+static int refdb_fs_backend__write_tail(
+	git_refdb_backend *_backend,
+	const git_reference *ref,
+	git_filebuf *file,
+	int update_reflog,
+	const git_signature *who,
+	const char *message,
+	const git_oid *old_id,
+	const char *old_target)
+{
+	refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
+	int error = 0, cmp = 0, should_write;
+	const char *new_target = NULL;
+	const git_oid *new_id = NULL;
+
+	if ((error = cmp_old_ref(&cmp, _backend, ref->name, old_id, old_target)) < 0)
+		goto on_error;
+
+	if (cmp) {
+		giterr_set(GITERR_REFERENCE, "old reference value does not match");
+		error = GIT_EMODIFIED;
+		goto on_error;
+	}
+
+	if (ref->type == GIT_REF_SYMBOLIC)
+		new_target = ref->target.symbolic;
+	else
+		new_id = &ref->target.oid;
+
+	error = cmp_old_ref(&cmp, _backend, ref->name, new_id, new_target);
+	if (error < 0 && error != GIT_ENOTFOUND)
+		goto on_error;
+
+	/* Don't update if we have the same value */
+	if (!error && !cmp) {
+		error = 0;
+		goto on_error; /* not really error */
+	}
+
+	if (update_reflog) {
+		if ((error = should_write_reflog(&should_write, backend->repo, ref->name)) < 0)
+			goto on_error;
+
+		if (should_write) {
+			if ((error = reflog_append(backend, ref, NULL, NULL, who, message)) < 0)
+				goto on_error;
+			if ((error = maybe_append_head(backend, ref, who, message)) < 0)
+				goto on_error;
+		}
+	}
+
+	return loose_commit(file, ref);
+
+on_error:
+        git_filebuf_cleanup(file);
+        return error;
+}
+
+static int refdb_fs_backend__delete(
+	git_refdb_backend *_backend,
+	const char *ref_name,
+	const git_oid *old_id, const char *old_target)
+{
+	refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
+	git_filebuf file = GIT_FILEBUF_INIT;
+	int error = 0;
+
+	assert(backend && ref_name);
+
+	if ((error = loose_lock(&file, backend, ref_name)) < 0)
+		return error;
+
+	return refdb_fs_backend__delete_tail(_backend, &file, ref_name, old_id, old_target);
+}
+
+static int refdb_fs_backend__delete_tail(
+	git_refdb_backend *_backend,
+	git_filebuf *file,
+	const char *ref_name,
+	const git_oid *old_id, const char *old_target)
+{
+	refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
+	git_buf loose_path = GIT_BUF_INIT;
+	size_t pack_pos;
+	int error = 0, cmp = 0;
+	bool loose_deleted = 0;
+
+	error = cmp_old_ref(&cmp, _backend, ref_name, old_id, old_target);
+	if (error < 0)
+		goto cleanup;
+
+	if (cmp) {
+		giterr_set(GITERR_REFERENCE, "old reference value does not match");
+		error = GIT_EMODIFIED;
+		goto cleanup;
+	}
+
+	/* If a loose reference exists, remove it from the filesystem */
+	if (git_buf_joinpath(&loose_path, backend->path, ref_name) < 0)
+		return -1;
+
+	if (git_path_isfile(loose_path.ptr)) {
+		error = p_unlink(loose_path.ptr);
+		loose_deleted = 1;
+	}
+
+	git_buf_free(&loose_path);
+
+	if (error != 0)
+		goto cleanup;
+
+	if ((error = packed_reload(backend)) < 0)
+		goto cleanup;
+
+	/* If a packed reference exists, remove it from the packfile and repack */
+	if ((error = git_sortedcache_wlock(backend->refcache)) < 0)
+		goto cleanup;
+
+	if (!(error = git_sortedcache_lookup_index(
+			&pack_pos, backend->refcache, ref_name)))
+		error = git_sortedcache_remove(backend->refcache, pack_pos);
+
+	git_sortedcache_wunlock(backend->refcache);
+
+	if (error == GIT_ENOTFOUND) {
+		error = loose_deleted ? 0 : ref_error_notfound(ref_name);
+		goto cleanup;
+	}
+
+	error = packed_write(backend);
+
+cleanup:
+	git_filebuf_cleanup(file);
+
+	return error;
+}
+
+static int refdb_reflog_fs__rename(git_refdb_backend *_backend, const char *old_name, const char *new_name);
+
+static int refdb_fs_backend__rename(
+	git_reference **out,
+	git_refdb_backend *_backend,
+	const char *old_name,
+	const char *new_name,
+	int force,
+	const git_signature *who,
+	const char *message)
+{
+	refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
+	git_reference *old, *new;
+	git_filebuf file = GIT_FILEBUF_INIT;
+	int error;
+
+	assert(backend);
+
+	if ((error = reference_path_available(
+			backend, new_name, old_name, force)) < 0 ||
+		(error = refdb_fs_backend__lookup(&old, _backend, old_name)) < 0)
+		return error;
+
+	if ((error = refdb_fs_backend__delete(_backend, old_name, NULL, NULL)) < 0) {
+		git_reference_free(old);
+		return error;
+	}
+
+	new = git_reference__set_name(old, new_name);
+	if (!new) {
+		git_reference_free(old);
+		return -1;
+	}
+
+	if ((error = loose_lock(&file, backend, new->name)) < 0) {
+		git_reference_free(new);
+		return error;
+	}
+
+	/* Try to rename the refog; it's ok if the old doesn't exist */
+	error = refdb_reflog_fs__rename(_backend, old_name, new_name);
+	if (((error == 0) || (error == GIT_ENOTFOUND)) &&
+	    ((error = reflog_append(backend, new, git_reference_target(new), NULL, who, message)) < 0)) {
+		git_reference_free(new);
+		git_filebuf_cleanup(&file);
+		return error;
+	}
+
+	if (error < 0) {
+		git_reference_free(new);
+		git_filebuf_cleanup(&file);
+		return error;
+	}
+
+
+	if ((error = loose_commit(&file, new)) < 0 || out == NULL) {
+		git_reference_free(new);
+		return error;
+	}
+
+	*out = new;
+	return 0;
+}
+
+static int refdb_fs_backend__compress(git_refdb_backend *_backend)
+{
+	refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
+
+	assert(backend);
+
+	if (packed_reload(backend) < 0 || /* load the existing packfile */
+		packed_loadloose(backend) < 0 || /* add all the loose refs */
+		packed_write(backend) < 0) /* write back to disk */
+		return -1;
+
+	return 0;
+}
+
+static void refdb_fs_backend__free(git_refdb_backend *_backend)
+{
+	refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
+
+	assert(backend);
+
+	git_sortedcache_free(backend->refcache);
+	git__free(backend->path);
+	git__free(backend);
+}
+
+static int setup_namespace(git_buf *path, git_repository *repo)
+{
+	char *parts, *start, *end;
+
+	/* Not all repositories have a path */
+	if (repo->path_repository == NULL)
+		return 0;
+
+	/* Load the path to the repo first */
+	git_buf_puts(path, repo->path_repository);
+
+	/* if the repo is not namespaced, nothing else to do */
+	if (repo->namespace == NULL)
+		return 0;
+
+	parts = end = git__strdup(repo->namespace);
+	if (parts == NULL)
+		return -1;
+
+	/*
+	 * From `man gitnamespaces`:
+	 *  namespaces which include a / will expand to a hierarchy
+	 *  of namespaces; for example, GIT_NAMESPACE=foo/bar will store
+	 *  refs under refs/namespaces/foo/refs/namespaces/bar/
+	 */
+	while ((start = git__strsep(&end, "/")) != NULL) {
+		git_buf_printf(path, "refs/namespaces/%s/", start);
+	}
+
+	git_buf_printf(path, "refs/namespaces/%s/refs", end);
+	git__free(parts);
+
+	/* Make sure that the folder with the namespace exists */
+	if (git_futils_mkdir_r(git_buf_cstr(path), repo->path_repository, 0777) < 0)
+		return -1;
+
+	/* Return root of the namespaced path, i.e. without the trailing '/refs' */
+	git_buf_rtruncate_at_char(path, '/');
+	return 0;
+}
+
+static int reflog_alloc(git_reflog **reflog, const char *name)
+{
+	git_reflog *log;
+
+	*reflog = NULL;
+
+	log = git__calloc(1, sizeof(git_reflog));
+	GITERR_CHECK_ALLOC(log);
+
+	log->ref_name = git__strdup(name);
+	GITERR_CHECK_ALLOC(log->ref_name);
+
+	if (git_vector_init(&log->entries, 0, NULL) < 0) {
+		git__free(log->ref_name);
+		git__free(log);
+		return -1;
+	}
+
+	*reflog = log;
+
+	return 0;
+}
+
+static int reflog_parse(git_reflog *log, const char *buf, size_t buf_size)
+{
+	const char *ptr;
+	git_reflog_entry *entry;
+
+#define seek_forward(_increase) do { \
+	if (_increase >= buf_size) { \
+		giterr_set(GITERR_INVALID, "Ran out of data while parsing reflog"); \
+		goto fail; \
+	} \
+	buf += _increase; \
+	buf_size -= _increase; \
+	} while (0)
+
+	while (buf_size > GIT_REFLOG_SIZE_MIN) {
+		entry = git__calloc(1, sizeof(git_reflog_entry));
+		GITERR_CHECK_ALLOC(entry);
+
+		entry->committer = git__malloc(sizeof(git_signature));
+		GITERR_CHECK_ALLOC(entry->committer);
+
+		if (git_oid_fromstrn(&entry->oid_old, buf, GIT_OID_HEXSZ) < 0)
+			goto fail;
+		seek_forward(GIT_OID_HEXSZ + 1);
+
+		if (git_oid_fromstrn(&entry->oid_cur, buf, GIT_OID_HEXSZ) < 0)
+			goto fail;
+		seek_forward(GIT_OID_HEXSZ + 1);
+
+		ptr = buf;
+
+		/* Seek forward to the end of the signature. */
+		while (*buf && *buf != '\t' && *buf != '\n')
+			seek_forward(1);
+
+		if (git_signature__parse(entry->committer, &ptr, buf + 1, NULL, *buf) < 0)
+			goto fail;
+
+		if (*buf == '\t') {
+			/* We got a message. Read everything till we reach LF. */
+			seek_forward(1);
+			ptr = buf;
+
+			while (*buf && *buf != '\n')
+				seek_forward(1);
+
+			entry->msg = git__strndup(ptr, buf - ptr);
+			GITERR_CHECK_ALLOC(entry->msg);
+		} else
+			entry->msg = NULL;
+
+		while (*buf && *buf == '\n' && buf_size > 1)
+			seek_forward(1);
+
+		if (git_vector_insert(&log->entries, entry) < 0)
+			goto fail;
+	}
+
+	return 0;
+
+#undef seek_forward
+
+fail:
+	if (entry)
+		git_reflog_entry__free(entry);
+
+	return -1;
+}
+
+static int create_new_reflog_file(const char *filepath)
+{
+	int fd, error;
+
+	if ((error = git_futils_mkpath2file(filepath, GIT_REFLOG_DIR_MODE)) < 0)
+		return error;
+
+	if ((fd = p_open(filepath,
+			O_WRONLY | O_CREAT,
+			GIT_REFLOG_FILE_MODE)) < 0)
+		return -1;
+
+	return p_close(fd);
+}
+
+GIT_INLINE(int) retrieve_reflog_path(git_buf *path, git_repository *repo, const char *name)
+{
+	return git_buf_join3(path, '/', repo->path_repository, GIT_REFLOG_DIR, name);
+}
+
+static int refdb_reflog_fs__ensure_log(git_refdb_backend *_backend, const char *name)
+{
+	refdb_fs_backend *backend;
+	git_repository *repo;
+	git_buf path = GIT_BUF_INIT;
+	int error;
+
+	assert(_backend && name);
+
+	backend = (refdb_fs_backend *) _backend;
+	repo = backend->repo;
+
+	if ((error = retrieve_reflog_path(&path, repo, name)) < 0)
+		return error;
+
+	error = create_new_reflog_file(git_buf_cstr(&path));
+	git_buf_free(&path);
+
+	return error;
+}
+
+static int has_reflog(git_repository *repo, const char *name)
+{
+	int ret = 0;
+	git_buf path = GIT_BUF_INIT;
+
+	if (retrieve_reflog_path(&path, repo, name) < 0)
+		goto cleanup;
+
+	ret = git_path_isfile(git_buf_cstr(&path));
+
+cleanup:
+	git_buf_free(&path);
+	return ret;
+}
+
+static int refdb_reflog_fs__has_log(git_refdb_backend *_backend, const char *name)
+{
+	refdb_fs_backend *backend;
+
+	assert(_backend && name);
+
+	backend = (refdb_fs_backend *) _backend;
+
+	return has_reflog(backend->repo, name);
+}
+
+static int refdb_reflog_fs__read(git_reflog **out, git_refdb_backend *_backend, const char *name)
+{
+	int error = -1;
+	git_buf log_path = GIT_BUF_INIT;
+	git_buf log_file = GIT_BUF_INIT;
+	git_reflog *log = NULL;
+	git_repository *repo;
+	refdb_fs_backend *backend;
+
+	assert(out && _backend && name);
+
+	backend = (refdb_fs_backend *) _backend;
+	repo = backend->repo;
+
+	if (reflog_alloc(&log, name) < 0)
+		return -1;
+
+	if (retrieve_reflog_path(&log_path, repo, name) < 0)
+		goto cleanup;
+
+	error = git_futils_readbuffer(&log_file, git_buf_cstr(&log_path));
+	if (error < 0 && error != GIT_ENOTFOUND)
+		goto cleanup;
+
+	if ((error == GIT_ENOTFOUND) &&
+		((error = create_new_reflog_file(git_buf_cstr(&log_path))) < 0))
+		goto cleanup;
+ 
+	if ((error = reflog_parse(log,
+		git_buf_cstr(&log_file), git_buf_len(&log_file))) < 0)
+		goto cleanup;
+
+	*out = log;
+	goto success;
+
+cleanup:
+	git_reflog_free(log);
+
+success:
+	git_buf_free(&log_file);
+	git_buf_free(&log_path);
+
+	return error;
+}
+
+static int serialize_reflog_entry(
+	git_buf *buf,
+	const git_oid *oid_old,
+	const git_oid *oid_new,
+	const git_signature *committer,
+	const char *msg)
+{
+	char raw_old[GIT_OID_HEXSZ+1];
+	char raw_new[GIT_OID_HEXSZ+1];
+
+	git_oid_tostr(raw_old, GIT_OID_HEXSZ+1, oid_old);
+	git_oid_tostr(raw_new, GIT_OID_HEXSZ+1, oid_new);
+
+	git_buf_clear(buf);
+
+	git_buf_puts(buf, raw_old);
+	git_buf_putc(buf, ' ');
+	git_buf_puts(buf, raw_new);
+
+	git_signature__writebuf(buf, " ", committer);
+
+	/* drop trailing LF */
+	git_buf_rtrim(buf);
+
+	if (msg) {
+		git_buf_putc(buf, '\t');
+		git_buf_puts(buf, msg);
+	}
+
+	git_buf_putc(buf, '\n');
+
+	return git_buf_oom(buf);
+}
+
+static int lock_reflog(git_filebuf *file, refdb_fs_backend *backend, const char *refname)
+{
+	git_repository *repo;
+	git_buf log_path = GIT_BUF_INIT;
+	int error;
+
+	repo = backend->repo;
+
+	if (!git_path_isvalid(backend->repo, refname, GIT_PATH_REJECT_DEFAULTS)) {
+		giterr_set(GITERR_INVALID, "Invalid reference name '%s'.", refname);
+		return GIT_EINVALIDSPEC;
+	}
+
+	if (retrieve_reflog_path(&log_path, repo, refname) < 0)
+		return -1;
+
+	if (!git_path_isfile(git_buf_cstr(&log_path))) {
+		giterr_set(GITERR_INVALID,
+			"Log file for reference '%s' doesn't exist.", refname);
+		error = -1;
+		goto cleanup;
+	}
+
+	error = git_filebuf_open(file, git_buf_cstr(&log_path), 0, GIT_REFLOG_FILE_MODE);
+
+cleanup:
+	git_buf_free(&log_path);
+
+	return error;
+}
+
+static int refdb_reflog_fs__write(git_refdb_backend *_backend, git_reflog *reflog)
+{
+	int error = -1;
+	unsigned int i;
+	git_reflog_entry *entry;
+	refdb_fs_backend *backend;
+	git_buf log = GIT_BUF_INIT;
+	git_filebuf fbuf = GIT_FILEBUF_INIT;
+
+	assert(_backend && reflog);
+
+	backend = (refdb_fs_backend *) _backend;
+
+	if ((error = lock_reflog(&fbuf, backend, reflog->ref_name)) < 0)
+		return -1;
+
+	git_vector_foreach(&reflog->entries, i, entry) {
+		if (serialize_reflog_entry(&log, &(entry->oid_old), &(entry->oid_cur), entry->committer, entry->msg) < 0)
+			goto cleanup;
+
+		if ((error = git_filebuf_write(&fbuf, log.ptr, log.size)) < 0)
+			goto cleanup;
+	}
+
+	error = git_filebuf_commit(&fbuf);
+	goto success;
+
+cleanup:
+	git_filebuf_cleanup(&fbuf);
+
+success:
+	git_buf_free(&log);
+
+	return error;
+}
+
+/* Append to the reflog, must be called under reference lock */
+static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, const git_oid *old, const git_oid *new, const git_signature *who, const char *message)
+{
+	int error, is_symbolic;
+	git_oid old_id = {{0}}, new_id = {{0}};
+	git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT;
+	git_repository *repo = backend->repo;
+
+	is_symbolic = ref->type == GIT_REF_SYMBOLIC;
+
+	/* "normal" symbolic updates do not write */
+	if (is_symbolic &&
+	    strcmp(ref->name, GIT_HEAD_FILE) &&
+	    !(old && new))
+		return 0;
+
+	/* From here on is_symoblic also means that it's HEAD */
+
+	if (old) {
+		git_oid_cpy(&old_id, old);
+	} else {
+		error = git_reference_name_to_id(&old_id, repo, ref->name);
+		if (error < 0 && error != GIT_ENOTFOUND)
+			return error;
+	}
+
+	if (new) {
+		git_oid_cpy(&new_id, new);
+	} else {
+		if (!is_symbolic) {
+			git_oid_cpy(&new_id, git_reference_target(ref));
+		} else {
+			error = git_reference_name_to_id(&new_id, repo, git_reference_symbolic_target(ref));
+			if (error < 0 && error != GIT_ENOTFOUND)
+				return error;
+			/* detaching HEAD does not create an entry */
+			if (error == GIT_ENOTFOUND)
+				return 0;
+
+			giterr_clear();
+		}
+	}
+
+	if ((error = serialize_reflog_entry(&buf, &old_id, &new_id, who, message)) < 0)
+		goto cleanup;
+
+	if ((error = retrieve_reflog_path(&path, repo, ref->name)) < 0)
+		goto cleanup;
+
+	if (((error = git_futils_mkpath2file(git_buf_cstr(&path), 0777)) < 0) &&
+	    (error != GIT_EEXISTS)) {
+		goto cleanup;
+	}
+
+	/* If the new branch matches part of the namespace of a previously deleted branch,
+	 * there maybe an obsolete/unused directory (or directory hierarchy) in the way.
+	 */
+	if (git_path_isdir(git_buf_cstr(&path)) &&
+		(git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_RMDIR_SKIP_NONEMPTY) < 0)) {
+		error = -1;
+		goto cleanup;
+	}
+
+	error = git_futils_writebuffer(&buf, git_buf_cstr(&path), O_WRONLY|O_CREAT|O_APPEND, GIT_REFLOG_FILE_MODE);
+
+cleanup:
+	git_buf_free(&buf);
+	git_buf_free(&path);
+
+	return error;
+}
+
+static int refdb_reflog_fs__rename(git_refdb_backend *_backend, const char *old_name, const char *new_name)
+{
+	int error = 0, fd;
+	git_buf old_path = GIT_BUF_INIT;
+	git_buf new_path = GIT_BUF_INIT;
+	git_buf temp_path = GIT_BUF_INIT;
+	git_buf normalized = GIT_BUF_INIT;
+	git_repository *repo;
+	refdb_fs_backend *backend;
+
+	assert(_backend && old_name && new_name);
+
+	backend = (refdb_fs_backend *) _backend;
+	repo = backend->repo;
+
+	if ((error = git_reference__normalize_name(
+		&normalized, new_name, GIT_REF_FORMAT_ALLOW_ONELEVEL)) < 0)
+			return error;
+
+	if (git_buf_joinpath(&temp_path, repo->path_repository, GIT_REFLOG_DIR) < 0)
+		return -1;
+
+	if (git_buf_joinpath(&old_path, git_buf_cstr(&temp_path), old_name) < 0)
+		return -1;
+
+	if (git_buf_joinpath(&new_path, git_buf_cstr(&temp_path), git_buf_cstr(&normalized)) < 0)
+		return -1;
+
+	if (!git_path_exists(git_buf_cstr(&old_path))) {
+		error = GIT_ENOTFOUND;
+		goto cleanup;
+	}
+
+	/*
+	 * Move the reflog to a temporary place. This two-phase renaming is required
+	 * in order to cope with funny renaming use cases when one tries to move a reference
+	 * to a partially colliding namespace:
+	 *  - a/b -> a/b/c
+	 *  - a/b/c/d -> a/b/c
+	 */
+	if (git_buf_joinpath(&temp_path, git_buf_cstr(&temp_path), "temp_reflog") < 0)
+		return -1;
+
+	if ((fd = git_futils_mktmp(&temp_path, git_buf_cstr(&temp_path), GIT_REFLOG_FILE_MODE)) < 0) {
+		error = -1;
+		goto cleanup;
+	}
+
+	p_close(fd);
+
+	if (p_rename(git_buf_cstr(&old_path), git_buf_cstr(&temp_path)) < 0) {
+		giterr_set(GITERR_OS, "Failed to rename reflog for %s", new_name);
+		error = -1;
+		goto cleanup;
+	}
+
+	if (git_path_isdir(git_buf_cstr(&new_path)) && 
+		(git_futils_rmdir_r(git_buf_cstr(&new_path), NULL, GIT_RMDIR_SKIP_NONEMPTY) < 0)) {
+		error = -1;
+		goto cleanup;
+	}
+
+	if (git_futils_mkpath2file(git_buf_cstr(&new_path), GIT_REFLOG_DIR_MODE) < 0) {
+		error = -1;
+		goto cleanup;
+	}
+
+	if (p_rename(git_buf_cstr(&temp_path), git_buf_cstr(&new_path)) < 0) {
+		giterr_set(GITERR_OS, "Failed to rename reflog for %s", new_name);
+		error = -1;
+	}
+
+cleanup:
+	git_buf_free(&temp_path);
+	git_buf_free(&old_path);
+	git_buf_free(&new_path);
+	git_buf_free(&normalized);
+
+	return error;
+}
+
+static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name)
+{
+	int error;
+	git_buf path = GIT_BUF_INIT;
+
+	git_repository *repo;
+	refdb_fs_backend *backend;
+
+	assert(_backend && name);
+
+	backend = (refdb_fs_backend *) _backend;
+	repo = backend->repo;
+
+	error = retrieve_reflog_path(&path, repo, name);
+
+	if (!error && git_path_exists(path.ptr))
+		error = p_unlink(path.ptr);
+
+	git_buf_free(&path);
+
+	return error;
+
+}
+
+int git_refdb_backend_fs(
+	git_refdb_backend **backend_out,
+	git_repository *repository)
+{
+	int t = 0;
+	git_buf path = GIT_BUF_INIT;
+	refdb_fs_backend *backend;
+
+	backend = git__calloc(1, sizeof(refdb_fs_backend));
+	GITERR_CHECK_ALLOC(backend);
+
+	backend->repo = repository;
+
+	if (setup_namespace(&path, repository) < 0)
+		goto fail;
+
+	backend->path = git_buf_detach(&path);
+
+	if (git_buf_joinpath(&path, backend->path, GIT_PACKEDREFS_FILE) < 0 ||
+		git_sortedcache_new(
+			&backend->refcache, offsetof(struct packref, name),
+			NULL, NULL, packref_cmp, git_buf_cstr(&path)) < 0)
+		goto fail;
+
+	git_buf_free(&path);
+
+	if (!git_repository__cvar(&t, backend->repo, GIT_CVAR_IGNORECASE) && t) {
+		backend->iterator_flags |= GIT_ITERATOR_IGNORE_CASE;
+		backend->direach_flags  |= GIT_PATH_DIR_IGNORE_CASE;
+	}
+	if (!git_repository__cvar(&t, backend->repo, GIT_CVAR_PRECOMPOSE) && t) {
+		backend->iterator_flags |= GIT_ITERATOR_PRECOMPOSE_UNICODE;
+		backend->direach_flags  |= GIT_PATH_DIR_PRECOMPOSE_UNICODE;
+	}
+
+	backend->parent.exists = &refdb_fs_backend__exists;
+	backend->parent.lookup = &refdb_fs_backend__lookup;
+	backend->parent.iterator = &refdb_fs_backend__iterator;
+	backend->parent.write = &refdb_fs_backend__write;
+	backend->parent.del = &refdb_fs_backend__delete;
+	backend->parent.rename = &refdb_fs_backend__rename;
+	backend->parent.compress = &refdb_fs_backend__compress;
+	backend->parent.lock = &refdb_fs_backend__lock;
+	backend->parent.unlock = &refdb_fs_backend__unlock;
+	backend->parent.has_log = &refdb_reflog_fs__has_log;
+	backend->parent.ensure_log = &refdb_reflog_fs__ensure_log;
+	backend->parent.free = &refdb_fs_backend__free;
+	backend->parent.reflog_read = &refdb_reflog_fs__read;
+	backend->parent.reflog_write = &refdb_reflog_fs__write;
+	backend->parent.reflog_rename = &refdb_reflog_fs__rename;
+	backend->parent.reflog_delete = &refdb_reflog_fs__delete;
+
+	*backend_out = (git_refdb_backend *)backend;
+	return 0;
+
+fail:
+	git_buf_free(&path);
+	git__free(backend->path);
+	git__free(backend);
+	return -1;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refdb_fs.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refdb_fs.h
new file mode 100755
index 0000000..79e2968
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refdb_fs.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_refdb_fs_h__
+#define INCLUDE_refdb_fs_h__
+
+typedef struct {
+	git_strmap *packfile;
+	time_t packfile_time;
+} git_refcache;
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/reflog.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/reflog.c
new file mode 100755
index 0000000..9ce9aee
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/reflog.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "reflog.h"
+#include "repository.h"
+#include "filebuf.h"
+#include "signature.h"
+#include "refdb.h"
+
+#include <git2/sys/refdb_backend.h>
+
+git_reflog_entry *git_reflog_entry__alloc(void)
+{
+	return git__calloc(1, sizeof(git_reflog_entry));
+}
+
+void git_reflog_entry__free(git_reflog_entry *entry)
+{
+	git_signature_free(entry->committer);
+
+	git__free(entry->msg);
+	git__free(entry);
+}
+
+void git_reflog_free(git_reflog *reflog)
+{
+	size_t i;
+	git_reflog_entry *entry;
+
+	if (reflog == NULL)
+		return;
+
+	if (reflog->db)
+		GIT_REFCOUNT_DEC(reflog->db, git_refdb__free);
+
+	for (i=0; i < reflog->entries.length; i++) {
+		entry = git_vector_get(&reflog->entries, i);
+
+		git_reflog_entry__free(entry);
+	}
+
+	git_vector_free(&reflog->entries);
+	git__free(reflog->ref_name);
+	git__free(reflog);
+}
+
+int git_reflog_read(git_reflog **reflog, git_repository *repo,  const char *name)
+{
+	git_refdb *refdb;
+	int error;
+
+	assert(reflog && repo && name);
+
+	if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
+		return error;
+
+	return git_refdb_reflog_read(reflog, refdb, name);
+}
+
+int git_reflog_write(git_reflog *reflog)
+{
+	git_refdb *db;
+
+	assert(reflog && reflog->db);
+
+	db = reflog->db;
+	return db->backend->reflog_write(db->backend, reflog);
+}
+
+int git_reflog_append(git_reflog *reflog, const git_oid *new_oid, const git_signature *committer, const char *msg)
+{
+	git_reflog_entry *entry;
+	const git_reflog_entry *previous;
+	const char *newline;
+
+	assert(reflog && new_oid && committer);
+
+	entry = git__calloc(1, sizeof(git_reflog_entry));
+	GITERR_CHECK_ALLOC(entry);
+
+	if ((git_signature_dup(&entry->committer, committer)) < 0)
+		goto cleanup;
+
+	if (msg != NULL) {
+		if ((entry->msg = git__strdup(msg)) == NULL)
+			goto cleanup;
+
+		newline = strchr(msg, '\n');
+
+		if (newline) {
+			if (newline[1] != '\0') {
+				giterr_set(GITERR_INVALID, "Reflog message cannot contain newline");
+				goto cleanup;
+			}
+
+			entry->msg[newline - msg] = '\0';
+		}
+	}
+
+	previous = git_reflog_entry_byindex(reflog, 0);
+
+	if (previous == NULL)
+		git_oid_fromstr(&entry->oid_old, GIT_OID_HEX_ZERO);
+	else
+		git_oid_cpy(&entry->oid_old, &previous->oid_cur);
+
+	git_oid_cpy(&entry->oid_cur, new_oid);
+
+	if (git_vector_insert(&reflog->entries, entry) < 0)
+		goto cleanup;
+
+	return 0;
+
+cleanup:
+	git_reflog_entry__free(entry);
+	return -1;
+}
+
+int git_reflog_rename(git_repository *repo, const char *old_name, const char *new_name)
+{
+	git_refdb *refdb;
+	int error;
+
+	if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
+		return -1;
+
+	return refdb->backend->reflog_rename(refdb->backend, old_name, new_name);
+}
+
+int git_reflog_delete(git_repository *repo, const char *name)
+{
+	git_refdb *refdb;
+	int error;
+
+	if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
+		return -1;
+
+	return refdb->backend->reflog_delete(refdb->backend, name);
+}
+
+size_t git_reflog_entrycount(git_reflog *reflog)
+{
+	assert(reflog);
+	return reflog->entries.length;
+}
+
+const git_reflog_entry * git_reflog_entry_byindex(const git_reflog *reflog, size_t idx)
+{
+	assert(reflog);
+
+	if (idx >= reflog->entries.length)
+		return NULL;
+
+	return git_vector_get(
+		&reflog->entries, reflog_inverse_index(idx, reflog->entries.length));
+}
+
+const git_oid * git_reflog_entry_id_old(const git_reflog_entry *entry)
+{
+	assert(entry);
+	return &entry->oid_old;
+}
+
+const git_oid * git_reflog_entry_id_new(const git_reflog_entry *entry)
+{
+	assert(entry);
+	return &entry->oid_cur;
+}
+
+const git_signature * git_reflog_entry_committer(const git_reflog_entry *entry)
+{
+	assert(entry);
+	return entry->committer;
+}
+
+const char * git_reflog_entry_message(const git_reflog_entry *entry)
+{
+	assert(entry);
+	return entry->msg;
+}
+
+int git_reflog_drop(git_reflog *reflog, size_t idx, int rewrite_previous_entry)
+{
+	size_t entrycount;
+	git_reflog_entry *entry, *previous;
+
+	entrycount = git_reflog_entrycount(reflog);
+
+	entry = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx);
+
+	if (entry == NULL) {
+		giterr_set(GITERR_REFERENCE, "No reflog entry at index %"PRIuZ, idx);
+		return GIT_ENOTFOUND;
+	}
+
+	git_reflog_entry__free(entry);
+
+	if (git_vector_remove(
+			&reflog->entries, reflog_inverse_index(idx, entrycount)) < 0)
+		return -1;
+
+	if (!rewrite_previous_entry)
+		return 0;
+
+	/* No need to rewrite anything when removing the most recent entry */
+	if (idx == 0)
+		return 0;
+
+	/* Have the latest entry just been dropped? */
+	if (entrycount == 1)
+		return 0;
+
+	entry = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx - 1);
+
+	/* If the oldest entry has just been removed... */
+	if (idx == entrycount - 1) {
+		/* ...clear the oid_old member of the "new" oldest entry */
+		if (git_oid_fromstr(&entry->oid_old, GIT_OID_HEX_ZERO) < 0)
+			return -1;
+
+		return 0;
+	}
+
+	previous = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx);
+	git_oid_cpy(&entry->oid_old, &previous->oid_cur);
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/reflog.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/reflog.h
new file mode 100755
index 0000000..2d31ae4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/reflog.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_reflog_h__
+#define INCLUDE_reflog_h__
+
+#include "common.h"
+#include "git2/reflog.h"
+#include "vector.h"
+
+#define GIT_REFLOG_DIR "logs/"
+#define GIT_REFLOG_DIR_MODE 0777
+#define GIT_REFLOG_FILE_MODE 0666
+
+#define GIT_REFLOG_SIZE_MIN (2*GIT_OID_HEXSZ+2+17)
+
+struct git_reflog_entry {
+	git_oid oid_old;
+	git_oid oid_cur;
+
+	git_signature *committer;
+
+	char *msg;
+};
+
+struct git_reflog {
+	git_refdb *db;
+	char *ref_name;
+	git_vector entries;
+};
+
+GIT_INLINE(size_t) reflog_inverse_index(size_t idx, size_t total)
+{
+	return (total - 1) - idx;
+}
+
+#endif /* INCLUDE_reflog_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refs.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refs.c
new file mode 100755
index 0000000..7b53865
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refs.c
@@ -0,0 +1,1305 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "refs.h"
+#include "hash.h"
+#include "repository.h"
+#include "fileops.h"
+#include "filebuf.h"
+#include "pack.h"
+#include "reflog.h"
+#include "refdb.h"
+
+#include <git2/tag.h>
+#include <git2/object.h>
+#include <git2/oid.h>
+#include <git2/branch.h>
+#include <git2/refs.h>
+#include <git2/refdb.h>
+#include <git2/sys/refs.h>
+#include <git2/signature.h>
+#include <git2/commit.h>
+
+GIT__USE_STRMAP
+
+#define DEFAULT_NESTING_LEVEL	5
+#define MAX_NESTING_LEVEL		10
+
+enum {
+	GIT_PACKREF_HAS_PEEL = 1,
+	GIT_PACKREF_WAS_LOOSE = 2
+};
+
+static git_reference *alloc_ref(const char *name)
+{
+	git_reference *ref = NULL;
+	size_t namelen = strlen(name), reflen;
+
+	if (!GIT_ADD_SIZET_OVERFLOW(&reflen, sizeof(git_reference), namelen) &&
+		!GIT_ADD_SIZET_OVERFLOW(&reflen, reflen, 1) &&
+		(ref = git__calloc(1, reflen)) != NULL)
+		memcpy(ref->name, name, namelen + 1);
+
+	return ref;
+}
+
+git_reference *git_reference__alloc_symbolic(
+	const char *name, const char *target)
+{
+	git_reference *ref;
+
+	assert(name && target);
+
+	ref = alloc_ref(name);
+	if (!ref)
+		return NULL;
+
+	ref->type = GIT_REF_SYMBOLIC;
+
+	if ((ref->target.symbolic = git__strdup(target)) == NULL) {
+		git__free(ref);
+		return NULL;
+	}
+
+	return ref;
+}
+
+git_reference *git_reference__alloc(
+	const char *name,
+	const git_oid *oid,
+	const git_oid *peel)
+{
+	git_reference *ref;
+
+	assert(name && oid);
+
+	ref = alloc_ref(name);
+	if (!ref)
+		return NULL;
+
+	ref->type = GIT_REF_OID;
+	git_oid_cpy(&ref->target.oid, oid);
+
+	if (peel != NULL)
+		git_oid_cpy(&ref->peel, peel);
+
+	return ref;
+}
+
+git_reference *git_reference__set_name(
+	git_reference *ref, const char *name)
+{
+	size_t namelen = strlen(name);
+	size_t reflen;
+	git_reference *rewrite = NULL;
+
+	if (!GIT_ADD_SIZET_OVERFLOW(&reflen, sizeof(git_reference), namelen) &&
+		!GIT_ADD_SIZET_OVERFLOW(&reflen, reflen, 1) &&
+		(rewrite = git__realloc(ref, reflen)) != NULL)
+		memcpy(rewrite->name, name, namelen + 1);
+
+	return rewrite;
+}
+
+void git_reference_free(git_reference *reference)
+{
+	if (reference == NULL)
+		return;
+
+	if (reference->type == GIT_REF_SYMBOLIC)
+		git__free(reference->target.symbolic);
+
+	if (reference->db)
+		GIT_REFCOUNT_DEC(reference->db, git_refdb__free);
+
+	git__free(reference);
+}
+
+int git_reference_delete(git_reference *ref)
+{
+	const git_oid *old_id = NULL;
+	const char *old_target = NULL;
+
+	if (ref->type == GIT_REF_OID)
+		old_id = &ref->target.oid;
+	else
+		old_target = ref->target.symbolic;
+
+	return git_refdb_delete(ref->db, ref->name, old_id, old_target);
+}
+
+int git_reference_remove(git_repository *repo, const char *name)
+{
+	git_refdb *db;
+	int error;
+
+	if ((error = git_repository_refdb__weakptr(&db, repo)) < 0)
+		return error;
+
+	return git_refdb_delete(db, name, NULL, NULL);
+}
+
+int git_reference_lookup(git_reference **ref_out,
+	git_repository *repo, const char *name)
+{
+	return git_reference_lookup_resolved(ref_out, repo, name, 0);
+}
+
+int git_reference_name_to_id(
+	git_oid *out, git_repository *repo, const char *name)
+{
+	int error;
+	git_reference *ref;
+
+	if ((error = git_reference_lookup_resolved(&ref, repo, name, -1)) < 0)
+		return error;
+
+	git_oid_cpy(out, git_reference_target(ref));
+	git_reference_free(ref);
+	return 0;
+}
+
+static int reference_normalize_for_repo(
+	git_refname_t out,
+	git_repository *repo,
+	const char *name)
+{
+	int precompose;
+	unsigned int flags = GIT_REF_FORMAT_ALLOW_ONELEVEL;
+
+	if (!git_repository__cvar(&precompose, repo, GIT_CVAR_PRECOMPOSE) &&
+		precompose)
+		flags |= GIT_REF_FORMAT__PRECOMPOSE_UNICODE;
+
+	return git_reference_normalize_name(out, GIT_REFNAME_MAX, name, flags);
+}
+
+int git_reference_lookup_resolved(
+	git_reference **ref_out,
+	git_repository *repo,
+	const char *name,
+	int max_nesting)
+{
+	git_refname_t scan_name;
+	git_ref_t scan_type;
+	int error = 0, nesting;
+	git_reference *ref = NULL;
+	git_refdb *refdb;
+
+	assert(ref_out && repo && name);
+
+	*ref_out = NULL;
+
+	if (max_nesting > MAX_NESTING_LEVEL)
+		max_nesting = MAX_NESTING_LEVEL;
+	else if (max_nesting < 0)
+		max_nesting = DEFAULT_NESTING_LEVEL;
+
+	scan_type = GIT_REF_SYMBOLIC;
+
+	if ((error = reference_normalize_for_repo(scan_name, repo, name)) < 0)
+		return error;
+
+	if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
+		return error;
+
+	for (nesting = max_nesting;
+		 nesting >= 0 && scan_type == GIT_REF_SYMBOLIC;
+		 nesting--)
+	{
+		if (nesting != max_nesting) {
+			strncpy(scan_name, ref->target.symbolic, sizeof(scan_name));
+			git_reference_free(ref);
+		}
+
+		if ((error = git_refdb_lookup(&ref, refdb, scan_name)) < 0)
+			return error;
+
+		scan_type = ref->type;
+	}
+
+	if (scan_type != GIT_REF_OID && max_nesting != 0) {
+		giterr_set(GITERR_REFERENCE,
+			"Cannot resolve reference (>%u levels deep)", max_nesting);
+		git_reference_free(ref);
+		return -1;
+	}
+
+	*ref_out = ref;
+	return 0;
+}
+
+int git_reference_dwim(git_reference **out, git_repository *repo, const char *refname)
+{
+	int error = 0, i;
+	bool fallbackmode = true, foundvalid = false;
+	git_reference *ref;
+	git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT;
+
+	static const char* formatters[] = {
+		"%s",
+		GIT_REFS_DIR "%s",
+		GIT_REFS_TAGS_DIR "%s",
+		GIT_REFS_HEADS_DIR "%s",
+		GIT_REFS_REMOTES_DIR "%s",
+		GIT_REFS_REMOTES_DIR "%s/" GIT_HEAD_FILE,
+		NULL
+	};
+
+	if (*refname)
+		git_buf_puts(&name, refname);
+	else {
+		git_buf_puts(&name, GIT_HEAD_FILE);
+		fallbackmode = false;
+	}
+
+	for (i = 0; formatters[i] && (fallbackmode || i == 0); i++) {
+
+		git_buf_clear(&refnamebuf);
+
+		if ((error = git_buf_printf(&refnamebuf, formatters[i], git_buf_cstr(&name))) < 0)
+			goto cleanup;
+
+		if (!git_reference_is_valid_name(git_buf_cstr(&refnamebuf))) {
+			error = GIT_EINVALIDSPEC;
+			continue;
+		}
+		foundvalid = true;
+
+		error = git_reference_lookup_resolved(&ref, repo, git_buf_cstr(&refnamebuf), -1);
+
+		if (!error) {
+			*out = ref;
+			error = 0;
+			goto cleanup;
+		}
+
+		if (error != GIT_ENOTFOUND)
+			goto cleanup;
+	}
+
+cleanup:
+	if (error && !foundvalid) {
+		/* never found a valid reference name */
+		giterr_set(GITERR_REFERENCE,
+			"Could not use '%s' as valid reference name", git_buf_cstr(&name));
+	}
+
+	git_buf_free(&name);
+	git_buf_free(&refnamebuf);
+	return error;
+}
+
+/**
+ * Getters
+ */
+git_ref_t git_reference_type(const git_reference *ref)
+{
+	assert(ref);
+	return ref->type;
+}
+
+const char *git_reference_name(const git_reference *ref)
+{
+	assert(ref);
+	return ref->name;
+}
+
+git_repository *git_reference_owner(const git_reference *ref)
+{
+	assert(ref);
+	return ref->db->repo;
+}
+
+const git_oid *git_reference_target(const git_reference *ref)
+{
+	assert(ref);
+
+	if (ref->type != GIT_REF_OID)
+		return NULL;
+
+	return &ref->target.oid;
+}
+
+const git_oid *git_reference_target_peel(const git_reference *ref)
+{
+	assert(ref);
+
+	if (ref->type != GIT_REF_OID || git_oid_iszero(&ref->peel))
+		return NULL;
+
+	return &ref->peel;
+}
+
+const char *git_reference_symbolic_target(const git_reference *ref)
+{
+	assert(ref);
+
+	if (ref->type != GIT_REF_SYMBOLIC)
+		return NULL;
+
+	return ref->target.symbolic;
+}
+
+static int reference__create(
+	git_reference **ref_out,
+	git_repository *repo,
+	const char *name,
+	const git_oid *oid,
+	const char *symbolic,
+	int force,
+	const git_signature *signature,
+	const char *log_message,
+	const git_oid *old_id,
+	const char *old_target)
+{
+	git_refname_t normalized;
+	git_refdb *refdb;
+	git_reference *ref = NULL;
+	int error = 0;
+
+	assert(repo && name);
+	assert(symbolic || signature);
+
+	if (ref_out)
+		*ref_out = NULL;
+
+	error = reference_normalize_for_repo(normalized, repo, name);
+	if (error < 0)
+		return error;
+
+	error = git_repository_refdb__weakptr(&refdb, repo);
+	if (error < 0)
+		return error;
+
+	if (oid != NULL) {
+		git_odb *odb;
+
+		assert(symbolic == NULL);
+
+		/* Sanity check the reference being created - target must exist. */
+		if ((error = git_repository_odb__weakptr(&odb, repo)) < 0)
+			return error;
+
+		if (!git_odb_exists(odb, oid)) {
+			giterr_set(GITERR_REFERENCE,
+				"Target OID for the reference doesn't exist on the repository");
+			return -1;
+		}
+
+		ref = git_reference__alloc(normalized, oid, NULL);
+	} else {
+		git_refname_t normalized_target;
+
+		if ((error = reference_normalize_for_repo(normalized_target, repo, symbolic)) < 0)
+			return error;
+
+		ref = git_reference__alloc_symbolic(normalized, normalized_target);
+	}
+
+	GITERR_CHECK_ALLOC(ref);
+
+	if ((error = git_refdb_write(refdb, ref, force, signature, log_message, old_id, old_target)) < 0) {
+		git_reference_free(ref);
+		return error;
+	}
+
+	if (ref_out == NULL)
+		git_reference_free(ref);
+	else
+		*ref_out = ref;
+
+	return 0;
+}
+
+int configured_ident(git_signature **out, const git_repository *repo)
+{
+	if (repo->ident_name && repo->ident_email)
+		return git_signature_now(out, repo->ident_name, repo->ident_email);
+
+	/* if not configured let us fall-through to the next method  */
+	return -1;
+}
+
+int git_reference__log_signature(git_signature **out, git_repository *repo)
+{
+	int error;
+	git_signature *who;
+
+	if(((error = configured_ident(&who, repo)) < 0) &&
+	   ((error = git_signature_default(&who, repo)) < 0) &&
+	   ((error = git_signature_now(&who, "unknown", "unknown")) < 0))
+		return error;
+
+	*out = who;
+	return 0;
+}
+
+int git_reference_create_matching(
+	git_reference **ref_out,
+	git_repository *repo,
+	const char *name,
+	const git_oid *id,
+	int force,
+	const git_oid *old_id,
+	const char *log_message)
+
+{
+	int error;
+	git_signature *who = NULL;
+	
+	assert(id);
+
+	if ((error = git_reference__log_signature(&who, repo)) < 0)
+		return error;
+
+	error = reference__create(
+		ref_out, repo, name, id, NULL, force, who, log_message, old_id, NULL);
+
+	git_signature_free(who);
+	return error;
+}
+
+int git_reference_create(
+	git_reference **ref_out,
+	git_repository *repo,
+	const char *name,
+	const git_oid *id,
+	int force,
+	const char *log_message)
+{
+        return git_reference_create_matching(ref_out, repo, name, id, force, NULL, log_message);
+}
+
+int git_reference_symbolic_create_matching(
+	git_reference **ref_out,
+	git_repository *repo,
+	const char *name,
+	const char *target,
+	int force,
+	const char *old_target,
+	const char *log_message)
+{
+	int error;
+	git_signature *who = NULL;
+
+	assert(target);
+
+	if ((error = git_reference__log_signature(&who, repo)) < 0)
+		return error;
+
+	error = reference__create(
+		ref_out, repo, name, NULL, target, force, who, log_message, NULL, old_target);
+
+	git_signature_free(who);
+	return error;
+}
+
+int git_reference_symbolic_create(
+	git_reference **ref_out,
+	git_repository *repo,
+	const char *name,
+	const char *target,
+	int force,
+	const char *log_message)
+{
+	return git_reference_symbolic_create_matching(ref_out, repo, name, target, force, NULL, log_message);
+}
+
+static int ensure_is_an_updatable_direct_reference(git_reference *ref)
+{
+	if (ref->type == GIT_REF_OID)
+		return 0;
+
+	giterr_set(GITERR_REFERENCE, "Cannot set OID on symbolic reference");
+	return -1;
+}
+
+int git_reference_set_target(
+	git_reference **out,
+	git_reference *ref,
+	const git_oid *id,
+	const char *log_message)
+{
+	int error;
+	git_repository *repo;
+
+	assert(out && ref && id);
+
+	repo = ref->db->repo;
+
+	if ((error = ensure_is_an_updatable_direct_reference(ref)) < 0)
+		return error;
+
+	return git_reference_create_matching(out, repo, ref->name, id, 1, &ref->target.oid, log_message);
+}
+
+static int ensure_is_an_updatable_symbolic_reference(git_reference *ref)
+{
+	if (ref->type == GIT_REF_SYMBOLIC)
+		return 0;
+
+	giterr_set(GITERR_REFERENCE, "Cannot set symbolic target on a direct reference");
+	return -1;
+}
+
+int git_reference_symbolic_set_target(
+	git_reference **out,
+	git_reference *ref,
+	const char *target,
+	const char *log_message)
+{
+	int error;
+
+	assert(out && ref && target);
+
+	if ((error = ensure_is_an_updatable_symbolic_reference(ref)) < 0)
+		return error;
+
+	return git_reference_symbolic_create_matching(
+		out, ref->db->repo, ref->name, target, 1, ref->target.symbolic, log_message);
+}
+
+static int reference__rename(git_reference **out, git_reference *ref, const char *new_name, int force,
+				 const git_signature *signature, const char *message)
+{
+	git_refname_t normalized;
+	bool should_head_be_updated = false;
+	int error = 0;
+
+	assert(ref && new_name && signature);
+
+	if ((error = reference_normalize_for_repo(
+			normalized, git_reference_owner(ref), new_name)) < 0)
+		return error;
+
+
+	/* Check if we have to update HEAD. */
+	if ((error = git_branch_is_head(ref)) < 0)
+		return error;
+
+	should_head_be_updated = (error > 0);
+
+	if ((error = git_refdb_rename(out, ref->db, ref->name, normalized, force, signature, message)) < 0)
+		return error;
+
+	/* Update HEAD it was pointing to the reference being renamed */
+	if (should_head_be_updated &&
+		(error = git_repository_set_head(ref->db->repo, normalized)) < 0) {
+		giterr_set(GITERR_REFERENCE, "Failed to update HEAD after renaming reference");
+		return error;
+	}
+
+	return 0;
+}
+
+
+int git_reference_rename(
+	git_reference **out,
+	git_reference *ref,
+	const char *new_name,
+	int force,
+	const char *log_message)
+{
+	git_signature *who;
+	int error;
+
+	if ((error = git_reference__log_signature(&who, ref->db->repo)) < 0)
+		return error;
+
+	error = reference__rename(out, ref, new_name, force, who, log_message);
+	git_signature_free(who);
+
+	return error;
+}
+
+int git_reference_resolve(git_reference **ref_out, const git_reference *ref)
+{
+	switch (git_reference_type(ref)) {
+	case GIT_REF_OID:
+		return git_reference_lookup(ref_out, ref->db->repo, ref->name);
+
+	case GIT_REF_SYMBOLIC:
+		return git_reference_lookup_resolved(ref_out, ref->db->repo, ref->target.symbolic, -1);
+
+	default:
+		giterr_set(GITERR_REFERENCE, "Invalid reference");
+		return -1;
+	}
+}
+
+int git_reference_foreach(
+	git_repository *repo,
+	git_reference_foreach_cb callback,
+	void *payload)
+{
+	git_reference_iterator *iter;
+	git_reference *ref;
+	int error;
+
+	if ((error = git_reference_iterator_new(&iter, repo)) < 0)
+		return error;
+
+	while (!(error = git_reference_next(&ref, iter))) {
+		if ((error = callback(ref, payload)) != 0) {
+			giterr_set_after_callback(error);
+			break;
+		}
+	}
+
+	if (error == GIT_ITEROVER)
+		error = 0;
+
+	git_reference_iterator_free(iter);
+	return error;
+}
+
+int git_reference_foreach_name(
+	git_repository *repo,
+	git_reference_foreach_name_cb callback,
+	void *payload)
+{
+	git_reference_iterator *iter;
+	const char *refname;
+	int error;
+
+	if ((error = git_reference_iterator_new(&iter, repo)) < 0)
+		return error;
+
+	while (!(error = git_reference_next_name(&refname, iter))) {
+		if ((error = callback(refname, payload)) != 0) {
+			giterr_set_after_callback(error);
+			break;
+		}
+	}
+
+	if (error == GIT_ITEROVER)
+		error = 0;
+
+	git_reference_iterator_free(iter);
+	return error;
+}
+
+int git_reference_foreach_glob(
+	git_repository *repo,
+	const char *glob,
+	git_reference_foreach_name_cb callback,
+	void *payload)
+{
+	git_reference_iterator *iter;
+	const char *refname;
+	int error;
+
+	if ((error = git_reference_iterator_glob_new(&iter, repo, glob)) < 0)
+		return error;
+
+	while (!(error = git_reference_next_name(&refname, iter))) {
+		if ((error = callback(refname, payload)) != 0) {
+			giterr_set_after_callback(error);
+			break;
+		}
+	}
+
+	if (error == GIT_ITEROVER)
+		error = 0;
+
+	git_reference_iterator_free(iter);
+	return error;
+}
+
+int git_reference_iterator_new(git_reference_iterator **out, git_repository *repo)
+{
+	git_refdb *refdb;
+
+	if (git_repository_refdb__weakptr(&refdb, repo) < 0)
+		return -1;
+
+	return git_refdb_iterator(out, refdb, NULL);
+}
+
+int git_reference_iterator_glob_new(
+	git_reference_iterator **out, git_repository *repo, const char *glob)
+{
+	git_refdb *refdb;
+
+	if (git_repository_refdb__weakptr(&refdb, repo) < 0)
+		return -1;
+
+	return git_refdb_iterator(out, refdb, glob);
+}
+
+int git_reference_next(git_reference **out, git_reference_iterator *iter)
+{
+	return git_refdb_iterator_next(out, iter);
+}
+
+int git_reference_next_name(const char **out, git_reference_iterator *iter)
+{
+	return git_refdb_iterator_next_name(out, iter);
+}
+
+void git_reference_iterator_free(git_reference_iterator *iter)
+{
+	if (iter == NULL)
+		return;
+
+	git_refdb_iterator_free(iter);
+}
+
+static int cb__reflist_add(const char *ref, void *data)
+{
+	char *name = git__strdup(ref);
+	GITERR_CHECK_ALLOC(name);
+	return git_vector_insert((git_vector *)data, name);
+}
+
+int git_reference_list(
+	git_strarray *array,
+	git_repository *repo)
+{
+	git_vector ref_list;
+
+	assert(array && repo);
+
+	array->strings = NULL;
+	array->count = 0;
+
+	if (git_vector_init(&ref_list, 8, NULL) < 0)
+		return -1;
+
+	if (git_reference_foreach_name(
+			repo, &cb__reflist_add, (void *)&ref_list) < 0) {
+		git_vector_free(&ref_list);
+		return -1;
+	}
+
+	array->strings = (char **)git_vector_detach(&array->count, NULL, &ref_list);
+
+	return 0;
+}
+
+static int is_valid_ref_char(char ch)
+{
+	if ((unsigned) ch <= ' ')
+		return 0;
+
+	switch (ch) {
+	case '~':
+	case '^':
+	case ':':
+	case '\\':
+	case '?':
+	case '[':
+	case '*':
+		return 0;
+	default:
+		return 1;
+	}
+}
+
+static int ensure_segment_validity(const char *name)
+{
+	const char *current = name;
+	char prev = '\0';
+	const int lock_len = (int)strlen(GIT_FILELOCK_EXTENSION);
+	int segment_len;
+
+	if (*current == '.')
+		return -1; /* Refname starts with "." */
+
+	for (current = name; ; current++) {
+		if (*current == '\0' || *current == '/')
+			break;
+
+		if (!is_valid_ref_char(*current))
+			return -1; /* Illegal character in refname */
+
+		if (prev == '.' && *current == '.')
+			return -1; /* Refname contains ".." */
+
+		if (prev == '@' && *current == '{')
+			return -1; /* Refname contains "@{" */
+
+		prev = *current;
+	}
+
+	segment_len = (int)(current - name);
+
+	/* A refname component can not end with ".lock" */
+	if (segment_len >= lock_len &&
+		!memcmp(current - lock_len, GIT_FILELOCK_EXTENSION, lock_len))
+			return -1;
+
+	return segment_len;
+}
+
+static bool is_all_caps_and_underscore(const char *name, size_t len)
+{
+	size_t i;
+	char c;
+
+	assert(name && len > 0);
+
+	for (i = 0; i < len; i++)
+	{
+		c = name[i];
+		if ((c < 'A' || c > 'Z') && c != '_')
+			return false;
+	}
+
+	if (*name == '_' || name[len - 1] == '_')
+		return false;
+
+	return true;
+}
+
+/* Inspired from https://github.com/git/git/blob/f06d47e7e0d9db709ee204ed13a8a7486149f494/refs.c#L36-100 */
+int git_reference__normalize_name(
+	git_buf *buf,
+	const char *name,
+	unsigned int flags)
+{
+	const char *current;
+	int segment_len, segments_count = 0, error = GIT_EINVALIDSPEC;
+	unsigned int process_flags;
+	bool normalize = (buf != NULL);
+
+#ifdef GIT_USE_ICONV
+	git_path_iconv_t ic = GIT_PATH_ICONV_INIT;
+#endif
+
+	assert(name);
+
+	process_flags = flags;
+	current = (char *)name;
+
+	if (*current == '/')
+		goto cleanup;
+
+	if (normalize)
+		git_buf_clear(buf);
+
+#ifdef GIT_USE_ICONV
+	if ((flags & GIT_REF_FORMAT__PRECOMPOSE_UNICODE) != 0) {
+		size_t namelen = strlen(current);
+		if ((error = git_path_iconv_init_precompose(&ic)) < 0 ||
+			(error = git_path_iconv(&ic, &current, &namelen)) < 0)
+			goto cleanup;
+		error = GIT_EINVALIDSPEC;
+	}
+#endif
+
+	while (true) {
+		segment_len = ensure_segment_validity(current);
+		if (segment_len < 0) {
+			if ((process_flags & GIT_REF_FORMAT_REFSPEC_PATTERN) &&
+					current[0] == '*' &&
+					(current[1] == '\0' || current[1] == '/')) {
+				/* Accept one wildcard as a full refname component. */
+				process_flags &= ~GIT_REF_FORMAT_REFSPEC_PATTERN;
+				segment_len = 1;
+			} else
+				goto cleanup;
+		}
+
+		if (segment_len > 0) {
+			if (normalize) {
+				size_t cur_len = git_buf_len(buf);
+
+				git_buf_joinpath(buf, git_buf_cstr(buf), current);
+				git_buf_truncate(buf,
+					cur_len + segment_len + (segments_count ? 1 : 0));
+
+				if (git_buf_oom(buf)) {
+					error = -1;
+					goto cleanup;
+				}
+			}
+
+			segments_count++;
+		}
+
+		/* No empty segment is allowed when not normalizing */
+		if (segment_len == 0 && !normalize)
+			goto cleanup;
+
+		if (current[segment_len] == '\0')
+			break;
+
+		current += segment_len + 1;
+	}
+
+	/* A refname can not be empty */
+	if (segment_len == 0 && segments_count == 0)
+		goto cleanup;
+
+	/* A refname can not end with "." */
+	if (current[segment_len - 1] == '.')
+		goto cleanup;
+
+	/* A refname can not end with "/" */
+	if (current[segment_len - 1] == '/')
+		goto cleanup;
+
+	if ((segments_count == 1 ) && !(flags & GIT_REF_FORMAT_ALLOW_ONELEVEL))
+		goto cleanup;
+
+	if ((segments_count == 1 ) &&
+	    !(flags & GIT_REF_FORMAT_REFSPEC_SHORTHAND) &&
+		!(is_all_caps_and_underscore(name, (size_t)segment_len) ||
+			((flags & GIT_REF_FORMAT_REFSPEC_PATTERN) && !strcmp("*", name))))
+			goto cleanup;
+
+	if ((segments_count > 1)
+		&& (is_all_caps_and_underscore(name, strchr(name, '/') - name)))
+			goto cleanup;
+
+	error = 0;
+
+cleanup:
+	if (error == GIT_EINVALIDSPEC)
+		giterr_set(
+			GITERR_REFERENCE,
+			"The given reference name '%s' is not valid", name);
+
+	if (error && normalize)
+		git_buf_free(buf);
+
+#ifdef GIT_USE_ICONV
+	git_path_iconv_clear(&ic);
+#endif
+
+	return error;
+}
+
+int git_reference_normalize_name(
+	char *buffer_out,
+	size_t buffer_size,
+	const char *name,
+	unsigned int flags)
+{
+	git_buf buf = GIT_BUF_INIT;
+	int error;
+
+	if ((error = git_reference__normalize_name(&buf, name, flags)) < 0)
+		goto cleanup;
+
+	if (git_buf_len(&buf) > buffer_size - 1) {
+		giterr_set(
+		GITERR_REFERENCE,
+		"The provided buffer is too short to hold the normalization of '%s'", name);
+		error = GIT_EBUFS;
+		goto cleanup;
+	}
+
+	git_buf_copy_cstr(buffer_out, buffer_size, &buf);
+
+	error = 0;
+
+cleanup:
+	git_buf_free(&buf);
+	return error;
+}
+
+#define GIT_REF_TYPEMASK (GIT_REF_OID | GIT_REF_SYMBOLIC)
+
+int git_reference_cmp(
+	const git_reference *ref1,
+	const git_reference *ref2)
+{
+	git_ref_t type1, type2;
+	assert(ref1 && ref2);
+
+	type1 = git_reference_type(ref1);
+	type2 = git_reference_type(ref2);
+
+	/* let's put symbolic refs before OIDs */
+	if (type1 != type2)
+		return (type1 == GIT_REF_SYMBOLIC) ? -1 : 1;
+
+	if (type1 == GIT_REF_SYMBOLIC)
+		return strcmp(ref1->target.symbolic, ref2->target.symbolic);
+
+	return git_oid__cmp(&ref1->target.oid, &ref2->target.oid);
+}
+
+/**
+ * Get the end of a chain of references. If the final one is not
+ * found, we return the reference just before that.
+ */
+static int get_terminal(git_reference **out, git_repository *repo, const char *ref_name, int nesting)
+{
+	git_reference *ref;
+	int error = 0;
+
+	if (nesting > MAX_NESTING_LEVEL) {
+		giterr_set(GITERR_REFERENCE, "Reference chain too deep (%d)", nesting);
+		return GIT_ENOTFOUND;
+	}
+
+	/* set to NULL to let the caller know that they're at the end of the chain */
+	if ((error = git_reference_lookup(&ref, repo, ref_name)) < 0) {
+		*out = NULL;
+		return error;
+	}
+
+	if (git_reference_type(ref) == GIT_REF_OID) {
+		*out = ref;
+		error = 0;
+	} else {
+		error = get_terminal(out, repo, git_reference_symbolic_target(ref), nesting + 1);
+		if (error == GIT_ENOTFOUND && !*out)
+			*out = ref;
+		else
+			git_reference_free(ref);
+	}
+
+	return error;
+}
+
+/*
+ * Starting with the reference given by `ref_name`, follows symbolic
+ * references until a direct reference is found and updated the OID
+ * on that direct reference to `oid`.
+ */
+int git_reference__update_terminal(
+	git_repository *repo,
+	const char *ref_name,
+	const git_oid *oid,
+	const git_signature *sig,
+	const char *log_message)
+{
+	git_reference *ref = NULL, *ref2 = NULL;
+	git_signature *who = NULL;
+	const git_signature *to_use;
+	int error = 0;
+
+	if (!sig && (error = git_reference__log_signature(&who, repo)) < 0)
+		return error;
+
+	to_use = sig ? sig : who;
+	error = get_terminal(&ref, repo, ref_name, 0);
+
+	/* found a dangling symref */
+	if (error == GIT_ENOTFOUND && ref) {
+		assert(git_reference_type(ref) == GIT_REF_SYMBOLIC);
+		giterr_clear();
+		error = reference__create(&ref2, repo, ref->target.symbolic, oid, NULL, 0, to_use,
+					  log_message, NULL, NULL);
+	} else if (error == GIT_ENOTFOUND) {
+		giterr_clear();
+		error = reference__create(&ref2, repo, ref_name, oid, NULL, 0, to_use,
+					  log_message, NULL, NULL);
+	}  else if (error == 0) {
+		assert(git_reference_type(ref) == GIT_REF_OID);
+		error = reference__create(&ref2, repo, ref->name, oid, NULL, 1, to_use,
+					  log_message, &ref->target.oid, NULL);
+	}
+
+	git_reference_free(ref2);
+	git_reference_free(ref);
+	git_signature_free(who);
+	return error;
+}
+
+int git_reference__update_for_commit(
+	git_repository *repo,
+	git_reference *ref,
+	const char *ref_name,
+	const git_oid *id,
+	const char *operation)
+{
+	git_reference *ref_new = NULL;
+	git_commit *commit = NULL;
+	git_buf reflog_msg = GIT_BUF_INIT;
+	const git_signature *who;
+	int error;
+
+	if ((error = git_commit_lookup(&commit, repo, id)) < 0 ||
+		(error = git_buf_printf(&reflog_msg, "%s%s: %s",
+			operation ? operation : "commit",
+			git_commit_parentcount(commit) == 0 ? " (initial)" : "",
+			git_commit_summary(commit))) < 0)
+		goto done;
+
+	who = git_commit_committer(commit);
+
+	if (ref) {
+		if ((error = ensure_is_an_updatable_direct_reference(ref)) < 0)
+			return error;
+
+		error = reference__create(&ref_new, repo, ref->name, id, NULL, 1, who,
+					  git_buf_cstr(&reflog_msg), &ref->target.oid, NULL);
+	}
+	else
+		error = git_reference__update_terminal(
+			repo, ref_name, id, who, git_buf_cstr(&reflog_msg));
+
+done:
+	git_reference_free(ref_new);
+	git_buf_free(&reflog_msg);
+	git_commit_free(commit);
+	return error;
+}
+
+int git_reference_has_log(git_repository *repo, const char *refname)
+{
+	int error;
+	git_refdb *refdb;
+
+	assert(repo && refname);
+
+	if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
+		return error;
+
+	return git_refdb_has_log(refdb, refname);
+}
+
+int git_reference_ensure_log(git_repository *repo, const char *refname)
+{
+	int error;
+	git_refdb *refdb;
+
+	assert(repo && refname);
+
+	if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
+		return error;
+
+	return git_refdb_ensure_log(refdb, refname);
+}
+
+int git_reference__is_branch(const char *ref_name)
+{
+	return git__prefixcmp(ref_name, GIT_REFS_HEADS_DIR) == 0;
+}
+
+int git_reference_is_branch(const git_reference *ref)
+{
+	assert(ref);
+	return git_reference__is_branch(ref->name);
+}
+
+int git_reference__is_remote(const char *ref_name)
+{
+	return git__prefixcmp(ref_name, GIT_REFS_REMOTES_DIR) == 0;
+}
+
+int git_reference_is_remote(const git_reference *ref)
+{
+	assert(ref);
+	return git_reference__is_remote(ref->name);
+}
+
+int git_reference__is_tag(const char *ref_name)
+{
+	return git__prefixcmp(ref_name, GIT_REFS_TAGS_DIR) == 0;
+}
+
+int git_reference_is_tag(const git_reference *ref)
+{
+	assert(ref);
+	return git_reference__is_tag(ref->name);
+}
+
+int git_reference__is_note(const char *ref_name)
+{
+	return git__prefixcmp(ref_name, GIT_REFS_NOTES_DIR) == 0;
+}
+
+int git_reference_is_note(const git_reference *ref)
+{
+	assert(ref);
+	return git_reference__is_note(ref->name);
+}
+
+static int peel_error(int error, git_reference *ref, const char* msg)
+{
+	giterr_set(
+		GITERR_INVALID,
+		"The reference '%s' cannot be peeled - %s", git_reference_name(ref), msg);
+	return error;
+}
+
+int git_reference_peel(
+	git_object **peeled,
+	git_reference *ref,
+	git_otype target_type)
+{
+	git_reference *resolved = NULL;
+	git_object *target = NULL;
+	int error;
+
+	assert(ref);
+
+	if (ref->type == GIT_REF_OID) {
+		resolved = ref;
+	} else {
+		if ((error = git_reference_resolve(&resolved, ref)) < 0)
+			return peel_error(error, ref, "Cannot resolve reference");
+	}
+
+	if (!git_oid_iszero(&resolved->peel)) {
+		error = git_object_lookup(&target,
+			git_reference_owner(ref), &resolved->peel, GIT_OBJ_ANY);
+	} else {
+		error = git_object_lookup(&target,
+			git_reference_owner(ref), &resolved->target.oid, GIT_OBJ_ANY);
+	}
+
+	if (error < 0) {
+		peel_error(error, ref, "Cannot retrieve reference target");
+		goto cleanup;
+	}
+
+	if (target_type == GIT_OBJ_ANY && git_object_type(target) != GIT_OBJ_TAG)
+		error = git_object_dup(peeled, target);
+	else
+		error = git_object_peel(peeled, target, target_type);
+
+cleanup:
+	git_object_free(target);
+
+	if (resolved != ref)
+		git_reference_free(resolved);
+
+	return error;
+}
+
+int git_reference__is_valid_name(const char *refname, unsigned int flags)
+{
+	if (git_reference__normalize_name(NULL, refname, flags) < 0) {
+		giterr_clear();
+		return false;
+	}
+
+	return true;
+}
+
+int git_reference_is_valid_name(const char *refname)
+{
+	return git_reference__is_valid_name(refname, GIT_REF_FORMAT_ALLOW_ONELEVEL);
+}
+
+const char *git_reference__shorthand(const char *name)
+{
+	if (!git__prefixcmp(name, GIT_REFS_HEADS_DIR))
+		return name + strlen(GIT_REFS_HEADS_DIR);
+	else if (!git__prefixcmp(name, GIT_REFS_TAGS_DIR))
+		return name + strlen(GIT_REFS_TAGS_DIR);
+	else if (!git__prefixcmp(name, GIT_REFS_REMOTES_DIR))
+		return name + strlen(GIT_REFS_REMOTES_DIR);
+	else if (!git__prefixcmp(name, GIT_REFS_DIR))
+		return name + strlen(GIT_REFS_DIR);
+
+	/* No shorthands are avaiable, so just return the name */
+	return name;
+}
+
+const char *git_reference_shorthand(const git_reference *ref)
+{
+	return git_reference__shorthand(ref->name);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refs.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refs.h
new file mode 100755
index 0000000..f78ea06
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refs.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_refs_h__
+#define INCLUDE_refs_h__
+
+#include "common.h"
+#include "git2/oid.h"
+#include "git2/refs.h"
+#include "git2/refdb.h"
+#include "strmap.h"
+#include "buffer.h"
+#include "oid.h"
+
+#define GIT_REFS_DIR "refs/"
+#define GIT_REFS_HEADS_DIR GIT_REFS_DIR "heads/"
+#define GIT_REFS_TAGS_DIR GIT_REFS_DIR "tags/"
+#define GIT_REFS_REMOTES_DIR GIT_REFS_DIR "remotes/"
+#define GIT_REFS_NOTES_DIR GIT_REFS_DIR "notes/"
+#define GIT_REFS_DIR_MODE 0777
+#define GIT_REFS_FILE_MODE 0666
+
+#define GIT_RENAMED_REF_FILE GIT_REFS_DIR "RENAMED-REF"
+
+#define GIT_SYMREF "ref: "
+#define GIT_PACKEDREFS_FILE "packed-refs"
+#define GIT_PACKEDREFS_HEADER "# pack-refs with: peeled fully-peeled "
+#define GIT_PACKEDREFS_FILE_MODE 0666
+
+#define GIT_HEAD_FILE "HEAD"
+#define GIT_ORIG_HEAD_FILE "ORIG_HEAD"
+#define GIT_FETCH_HEAD_FILE "FETCH_HEAD"
+#define GIT_MERGE_HEAD_FILE "MERGE_HEAD"
+#define GIT_REVERT_HEAD_FILE "REVERT_HEAD"
+#define GIT_CHERRYPICK_HEAD_FILE "CHERRY_PICK_HEAD"
+#define GIT_BISECT_LOG_FILE "BISECT_LOG"
+#define GIT_REBASE_MERGE_DIR "rebase-merge/"
+#define GIT_REBASE_MERGE_INTERACTIVE_FILE GIT_REBASE_MERGE_DIR "interactive"
+#define GIT_REBASE_APPLY_DIR "rebase-apply/"
+#define GIT_REBASE_APPLY_REBASING_FILE GIT_REBASE_APPLY_DIR "rebasing"
+#define GIT_REBASE_APPLY_APPLYING_FILE GIT_REBASE_APPLY_DIR "applying"
+#define GIT_REFS_HEADS_MASTER_FILE GIT_REFS_HEADS_DIR "master"
+
+#define GIT_STASH_FILE "stash"
+#define GIT_REFS_STASH_FILE GIT_REFS_DIR GIT_STASH_FILE
+
+#define GIT_REF_FORMAT__PRECOMPOSE_UNICODE	(1u << 16)
+
+#define GIT_REFNAME_MAX 1024
+
+typedef char git_refname_t[GIT_REFNAME_MAX];
+
+struct git_reference {
+	git_refdb *db;
+	git_ref_t type;
+
+	union {
+		git_oid oid;
+		char *symbolic;
+	} target;
+
+	git_oid peel;
+	char name[GIT_FLEX_ARRAY];
+};
+
+git_reference *git_reference__set_name(git_reference *ref, const char *name);
+
+int git_reference__normalize_name(git_buf *buf, const char *name, unsigned int flags);
+int git_reference__update_terminal(git_repository *repo, const char *ref_name, const git_oid *oid, const git_signature *sig, const char *log_message);
+int git_reference__is_valid_name(const char *refname, unsigned int flags);
+int git_reference__is_branch(const char *ref_name);
+int git_reference__is_remote(const char *ref_name);
+int git_reference__is_tag(const char *ref_name);
+const char *git_reference__shorthand(const char *name);
+
+/**
+ * Lookup a reference by name and try to resolve to an OID.
+ *
+ * You can control how many dereferences this will attempt to resolve the
+ * reference with the `max_deref` parameter, or pass -1 to use a sane
+ * default.  If you pass 0 for `max_deref`, this will not attempt to resolve
+ * the reference.  For any value of `max_deref` other than 0, not
+ * successfully resolving the reference will be reported as an error.
+
+ * The generated reference must be freed by the user.
+ *
+ * @param reference_out Pointer to the looked-up reference
+ * @param repo The repository to look up the reference
+ * @param name The long name for the reference (e.g. HEAD, ref/heads/master, refs/tags/v0.1.0, ...)
+ * @param max_deref Maximum number of dereferences to make of symbolic refs, 0 means simple lookup, < 0 means use default reasonable value
+ * @return 0 on success or < 0 on error; not being able to resolve the reference is an error unless 0 was passed for max_deref
+ */
+int git_reference_lookup_resolved(
+	git_reference **reference_out,
+	git_repository *repo,
+	const char *name,
+	int max_deref);
+
+int git_reference__log_signature(git_signature **out, git_repository *repo);
+
+/** Update a reference after a commit. */
+int git_reference__update_for_commit(
+	git_repository *repo,
+	git_reference *ref,
+	const char *ref_name,
+	const git_oid *id,
+	const char *operation);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refspec.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refspec.c
new file mode 100755
index 0000000..f92a6d2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refspec.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2/errors.h"
+
+#include "common.h"
+#include "refspec.h"
+#include "util.h"
+#include "posix.h"
+#include "refs.h"
+#include "vector.h"
+
+int git_refspec__parse(git_refspec *refspec, const char *input, bool is_fetch)
+{
+	// Ported from https://github.com/git/git/blob/f06d47e7e0d9db709ee204ed13a8a7486149f494/remote.c#L518-636
+
+	size_t llen;
+	int is_glob = 0;
+	const char *lhs, *rhs;
+	int flags;
+
+	assert(refspec && input);
+
+	memset(refspec, 0x0, sizeof(git_refspec));
+	refspec->push = !is_fetch;
+
+	lhs = input;
+	if (*lhs == '+') {
+		refspec->force = 1;
+		lhs++;
+	}
+
+	rhs = strrchr(lhs, ':');
+
+	/*
+	 * Before going on, special case ":" (or "+:") as a refspec
+	 * for matching refs.
+	 */
+	if (!is_fetch && rhs == lhs && rhs[1] == '\0') {
+		refspec->matching = 1;
+		refspec->string = git__strdup(input);
+		GITERR_CHECK_ALLOC(refspec->string);
+		refspec->src = git__strdup("");
+		GITERR_CHECK_ALLOC(refspec->src);
+		refspec->dst = git__strdup("");
+		GITERR_CHECK_ALLOC(refspec->dst);
+		return 0;
+	}
+
+	if (rhs) {
+		size_t rlen = strlen(++rhs);
+		is_glob = (1 <= rlen && strchr(rhs, '*'));
+		refspec->dst = git__strndup(rhs, rlen);
+	}
+
+	llen = (rhs ? (size_t)(rhs - lhs - 1) : strlen(lhs));
+	if (1 <= llen && memchr(lhs, '*', llen)) {
+		if ((rhs && !is_glob) || (!rhs && is_fetch))
+			goto invalid;
+		is_glob = 1;
+	} else if (rhs && is_glob)
+		goto invalid;
+
+	refspec->pattern = is_glob;
+	refspec->src = git__strndup(lhs, llen);
+	flags = GIT_REF_FORMAT_ALLOW_ONELEVEL | GIT_REF_FORMAT_REFSPEC_SHORTHAND
+		| (is_glob ? GIT_REF_FORMAT_REFSPEC_PATTERN : 0);
+
+	if (is_fetch) {
+		/*
+			* LHS
+			* - empty is allowed; it means HEAD.
+			* - otherwise it must be a valid looking ref.
+			*/
+		if (!*refspec->src)
+			; /* empty is ok */
+		else if (!git_reference__is_valid_name(refspec->src, flags))
+			goto invalid;
+		/*
+			* RHS
+			* - missing is ok, and is same as empty.
+			* - empty is ok; it means not to store.
+			* - otherwise it must be a valid looking ref.
+			*/
+		if (!refspec->dst)
+			; /* ok */
+		else if (!*refspec->dst)
+			; /* ok */
+		else if (!git_reference__is_valid_name(refspec->dst, flags))
+			goto invalid;
+	} else {
+		/*
+			* LHS
+			* - empty is allowed; it means delete.
+			* - when wildcarded, it must be a valid looking ref.
+			* - otherwise, it must be an extended SHA-1, but
+			*   there is no existing way to validate this.
+			*/
+		if (!*refspec->src)
+			; /* empty is ok */
+		else if (is_glob) {
+			if (!git_reference__is_valid_name(refspec->src, flags))
+				goto invalid;
+		}
+		else {
+			; /* anything goes, for now */
+		}
+		/*
+			* RHS
+			* - missing is allowed, but LHS then must be a
+			*   valid looking ref.
+			* - empty is not allowed.
+			* - otherwise it must be a valid looking ref.
+			*/
+		if (!refspec->dst) {
+			if (!git_reference__is_valid_name(refspec->src, flags))
+				goto invalid;
+		} else if (!*refspec->dst) {
+			goto invalid;
+		} else {
+			if (!git_reference__is_valid_name(refspec->dst, flags))
+				goto invalid;
+		}
+
+		/* if the RHS is empty, then it's a copy of the LHS */
+		if (!refspec->dst) {
+			refspec->dst = git__strdup(refspec->src);
+			GITERR_CHECK_ALLOC(refspec->dst);
+		}
+	}
+
+	refspec->string = git__strdup(input);
+	GITERR_CHECK_ALLOC(refspec->string);
+
+	return 0;
+
+ invalid:
+        giterr_set(
+                GITERR_INVALID,
+                "'%s' is not a valid refspec.", input);
+        git_refspec__free(refspec);
+	return -1;
+}
+
+void git_refspec__free(git_refspec *refspec)
+{
+	if (refspec == NULL)
+		return;
+
+	git__free(refspec->src);
+	git__free(refspec->dst);
+	git__free(refspec->string);
+
+	memset(refspec, 0x0, sizeof(git_refspec));
+}
+
+const char *git_refspec_src(const git_refspec *refspec)
+{
+	return refspec == NULL ? NULL : refspec->src;
+}
+
+const char *git_refspec_dst(const git_refspec *refspec)
+{
+	return refspec == NULL ? NULL : refspec->dst;
+}
+
+const char *git_refspec_string(const git_refspec *refspec)
+{
+	return refspec == NULL ? NULL : refspec->string;
+}
+
+int git_refspec_force(const git_refspec *refspec)
+{
+	assert(refspec);
+
+	return refspec->force;
+}
+
+int git_refspec_src_matches(const git_refspec *refspec, const char *refname)
+{
+	if (refspec == NULL || refspec->src == NULL)
+		return false;
+
+	return (p_fnmatch(refspec->src, refname, 0) == 0);
+}
+
+int git_refspec_dst_matches(const git_refspec *refspec, const char *refname)
+{
+	if (refspec == NULL || refspec->dst == NULL)
+		return false;
+
+	return (p_fnmatch(refspec->dst, refname, 0) == 0);
+}
+
+static int refspec_transform(
+	git_buf *out, const char *from, const char *to, const char *name)
+{
+	const char *from_star, *to_star;
+	const char *name_slash, *from_slash;
+	size_t replacement_len, star_offset;
+
+	git_buf_sanitize(out);
+	git_buf_clear(out);
+
+	/*
+	 * There are two parts to each side of a refspec, the bit
+	 * before the star and the bit after it. The star can be in
+	 * the middle of the pattern, so we need to look at each bit
+	 * individually.
+	 */
+	from_star = strchr(from, '*');
+	to_star = strchr(to, '*');
+
+	assert(from_star && to_star);
+
+	/* star offset, both in 'from' and in 'name' */
+	star_offset = from_star - from;
+
+	/* the first half is copied over */
+	git_buf_put(out, to, to_star - to);
+
+	/* then we copy over the replacement, from the star's offset to the next slash in 'name' */
+	name_slash = strchr(name + star_offset, '/');
+	if (!name_slash)
+		name_slash = strrchr(name, '\0');
+
+	/* if there is no slash after the star in 'from', we want to copy everything over */
+	from_slash = strchr(from + star_offset, '/');
+	if (!from_slash)
+		name_slash = strrchr(name, '\0');
+
+	replacement_len = (name_slash - name) - star_offset;
+	git_buf_put(out, name + star_offset, replacement_len);
+
+	return git_buf_puts(out, to_star + 1);
+}
+
+int git_refspec_transform(git_buf *out, const git_refspec *spec, const char *name)
+{
+	assert(out && spec && name);
+	git_buf_sanitize(out);
+
+	if (!git_refspec_src_matches(spec, name)) {
+		giterr_set(GITERR_INVALID, "ref '%s' doesn't match the source", name);
+		return -1;
+	}
+
+	if (!spec->pattern)
+		return git_buf_puts(out, spec->dst);
+
+	return refspec_transform(out, spec->src, spec->dst, name);
+}
+
+int git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name)
+{
+	assert(out && spec && name);
+	git_buf_sanitize(out);
+
+	if (!git_refspec_dst_matches(spec, name)) {
+		giterr_set(GITERR_INVALID, "ref '%s' doesn't match the destination", name);
+		return -1;
+	}
+
+	if (!spec->pattern)
+		return git_buf_puts(out, spec->src);
+
+	return refspec_transform(out, spec->dst, spec->src, name);
+}
+
+int git_refspec__serialize(git_buf *out, const git_refspec *refspec)
+{
+	if (refspec->force)
+		git_buf_putc(out, '+');
+
+	git_buf_printf(out, "%s:%s",
+		refspec->src != NULL ? refspec->src : "",
+		refspec->dst != NULL ? refspec->dst : "");
+
+	return git_buf_oom(out) == false;
+}
+
+int git_refspec_is_wildcard(const git_refspec *spec)
+{
+	assert(spec && spec->src);
+
+	return (spec->src[strlen(spec->src) - 1] == '*');
+}
+
+git_direction git_refspec_direction(const git_refspec *spec)
+{
+	assert(spec);
+
+	return spec->push;
+}
+
+int git_refspec__dwim_one(git_vector *out, git_refspec *spec, git_vector *refs)
+{
+	git_buf buf = GIT_BUF_INIT;
+	size_t j, pos;
+	git_remote_head key;
+
+	const char* formatters[] = {
+		GIT_REFS_DIR "%s",
+		GIT_REFS_TAGS_DIR "%s",
+		GIT_REFS_HEADS_DIR "%s",
+		NULL
+	};
+
+	git_refspec *cur = git__calloc(1, sizeof(git_refspec));
+	GITERR_CHECK_ALLOC(cur);
+
+	cur->force = spec->force;
+	cur->push = spec->push;
+	cur->pattern = spec->pattern;
+	cur->matching = spec->matching;
+	cur->string = git__strdup(spec->string);
+
+	/* shorthand on the lhs */
+	if (git__prefixcmp(spec->src, GIT_REFS_DIR)) {
+		for (j = 0; formatters[j]; j++) {
+			git_buf_clear(&buf);
+			if (git_buf_printf(&buf, formatters[j], spec->src) < 0)
+				return -1;
+
+			key.name = (char *) git_buf_cstr(&buf);
+			if (!git_vector_search(&pos, refs, &key)) {
+				/* we found something to match the shorthand, set src to that */
+				cur->src = git_buf_detach(&buf);
+			}
+		}
+	}
+
+	/* No shorthands found, copy over the name */
+	if (cur->src == NULL && spec->src != NULL) {
+		cur->src = git__strdup(spec->src);
+		GITERR_CHECK_ALLOC(cur->src);
+	}
+
+	if (spec->dst && git__prefixcmp(spec->dst, GIT_REFS_DIR)) {
+		/* if it starts with "remotes" then we just prepend "refs/" */
+		if (!git__prefixcmp(spec->dst, "remotes/")) {
+			git_buf_puts(&buf, GIT_REFS_DIR);
+		} else {
+			git_buf_puts(&buf, GIT_REFS_HEADS_DIR);
+		}
+
+		if (git_buf_puts(&buf, spec->dst) < 0)
+			return -1;
+
+		cur->dst = git_buf_detach(&buf);
+	}
+
+	git_buf_free(&buf);
+
+	if (cur->dst == NULL && spec->dst != NULL) {
+		cur->dst = git__strdup(spec->dst);
+		GITERR_CHECK_ALLOC(cur->dst);
+	}
+
+	return git_vector_insert(out, cur);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refspec.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refspec.h
new file mode 100755
index 0000000..9a87c97
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/refspec.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_refspec_h__
+#define INCLUDE_refspec_h__
+
+#include "git2/refspec.h"
+#include "buffer.h"
+#include "vector.h"
+
+struct git_refspec {
+	char *string;
+	char *src;
+	char *dst;
+	unsigned int force :1,
+		push : 1,
+		pattern :1,
+		matching :1;
+};
+
+#define GIT_REFSPEC_TAGS "refs/tags/*:refs/tags/*"
+
+int git_refspec__parse(
+	struct git_refspec *refspec,
+	const char *str,
+	bool is_fetch);
+
+void git_refspec__free(git_refspec *refspec);
+
+int git_refspec__serialize(git_buf *out, const git_refspec *refspec);
+
+/**
+ * Determines if a refspec is a wildcard refspec.
+ *
+ * @param spec the refspec
+ * @return 1 if the refspec is a wildcard, 0 otherwise
+ */
+int git_refspec_is_wildcard(const git_refspec *spec);
+
+/**
+ * DWIM `spec` with `refs` existing on the remote, append the dwim'ed
+ * result in `out`.
+ */
+int git_refspec__dwim_one(git_vector *out, git_refspec *spec, git_vector *refs);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/remote.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/remote.c
new file mode 100755
index 0000000..9f82aae
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/remote.c
@@ -0,0 +1,2510 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2/config.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+#include "git2/net.h"
+
+#include "common.h"
+#include "config.h"
+#include "repository.h"
+#include "remote.h"
+#include "fetch.h"
+#include "refs.h"
+#include "refspec.h"
+#include "fetchhead.h"
+#include "push.h"
+
+#define CONFIG_URL_FMT "remote.%s.url"
+#define CONFIG_PUSHURL_FMT "remote.%s.pushurl"
+#define CONFIG_FETCH_FMT "remote.%s.fetch"
+#define CONFIG_PUSH_FMT "remote.%s.push"
+#define CONFIG_TAGOPT_FMT "remote.%s.tagopt"
+
+static int dwim_refspecs(git_vector *out, git_vector *refspecs, git_vector *refs);
+static int lookup_remote_prune_config(git_remote *remote, git_config *config, const char *name);
+char *apply_insteadof(git_config *config, const char *url, int direction);
+
+static int add_refspec_to(git_vector *vector, const char *string, bool is_fetch)
+{
+	git_refspec *spec;
+
+	spec = git__calloc(1, sizeof(git_refspec));
+	GITERR_CHECK_ALLOC(spec);
+
+	if (git_refspec__parse(spec, string, is_fetch) < 0) {
+		git__free(spec);
+		return -1;
+	}
+
+	spec->push = !is_fetch;
+	if (git_vector_insert(vector, spec) < 0) {
+		git_refspec__free(spec);
+		git__free(spec);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int add_refspec(git_remote *remote, const char *string, bool is_fetch)
+{
+	return add_refspec_to(&remote->refspecs, string, is_fetch);
+}
+
+static int download_tags_value(git_remote *remote, git_config *cfg)
+{
+	git_config_entry *ce;
+	git_buf buf = GIT_BUF_INIT;
+	int error;
+
+	if (git_buf_printf(&buf, "remote.%s.tagopt", remote->name) < 0)
+		return -1;
+
+	error = git_config__lookup_entry(&ce, cfg, git_buf_cstr(&buf), false);
+	git_buf_free(&buf);
+
+	if (!error && ce && ce->value) {
+		if (!strcmp(ce->value, "--no-tags"))
+			remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_NONE;
+		else if (!strcmp(ce->value, "--tags"))
+			remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL;
+	}
+
+	git_config_entry_free(ce);
+	return error;
+}
+
+static int ensure_remote_name_is_valid(const char *name)
+{
+	int error = 0;
+
+	if (!git_remote_is_valid_name(name)) {
+		giterr_set(
+			GITERR_CONFIG,
+			"'%s' is not a valid remote name.", name ? name : "(null)");
+		error = GIT_EINVALIDSPEC;
+	}
+
+	return error;
+}
+
+static int write_add_refspec(git_repository *repo, const char *name, const char *refspec, bool fetch)
+{
+	git_config *cfg;
+	git_buf var = GIT_BUF_INIT;
+	git_refspec spec;
+	const char *fmt;
+	int error;
+
+	if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
+	    return error;
+
+	fmt = fetch ? CONFIG_FETCH_FMT : CONFIG_PUSH_FMT;
+
+	if ((error = ensure_remote_name_is_valid(name)) < 0)
+		return error;
+
+	if ((error = git_refspec__parse(&spec, refspec, fetch)) < 0) {
+		if (giterr_last()->klass != GITERR_NOMEMORY)
+			error = GIT_EINVALIDSPEC;
+
+		return error;
+	}
+
+	git_refspec__free(&spec);
+
+	if ((error = git_buf_printf(&var, fmt, name)) < 0)
+		return error;
+
+	/*
+	 * "$^" is a unmatcheable regexp: it will not match anything at all, so
+	 * all values will be considered new and we will not replace any
+	 * present value.
+	 */
+	if ((error = git_config_set_multivar(cfg, var.ptr, "$^", refspec)) < 0) {
+		goto cleanup;
+	}
+
+cleanup:
+	git_buf_free(&var);
+	return 0;
+}
+
+#if 0
+/* We could export this as a helper */
+static int get_check_cert(int *out, git_repository *repo)
+{
+	git_config *cfg;
+	const char *val;
+	int error = 0;
+
+	assert(out && repo);
+
+	/* By default, we *DO* want to verify the certificate. */
+	*out = 1;
+
+	/* Go through the possible sources for SSL verification settings, from
+	 * most specific to least specific. */
+
+	/* GIT_SSL_NO_VERIFY environment variable */
+	if ((val = getenv("GIT_SSL_NO_VERIFY")) != NULL)
+		return git_config_parse_bool(out, val);
+
+	/* http.sslVerify config setting */
+	if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
+		return error;
+
+	*out = git_config__get_bool_force(cfg, "http.sslverify", 1);
+	return 0;
+}
+#endif
+
+static int canonicalize_url(git_buf *out, const char *in)
+{
+	if (in == NULL || strlen(in) == 0) {
+		giterr_set(GITERR_INVALID, "cannot set empty URL");
+		return GIT_EINVALIDSPEC;
+	}
+
+#ifdef GIT_WIN32
+	/* Given a UNC path like \\server\path, we need to convert this
+	 * to //server/path for compatibility with core git.
+	 */
+	if (in[0] == '\\' && in[1] == '\\' &&
+		(git__isalpha(in[2]) || git__isdigit(in[2]))) {
+		const char *c;
+		for (c = in; *c; c++)
+			git_buf_putc(out, *c == '\\' ? '/' : *c);
+
+		return git_buf_oom(out) ? -1 : 0;
+	}
+#endif
+
+	return git_buf_puts(out, in);
+}
+
+static int create_internal(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch)
+{
+	git_remote *remote;
+	git_config *config = NULL;
+	git_buf canonical_url = GIT_BUF_INIT;
+	git_buf var = GIT_BUF_INIT;
+	int error = -1;
+
+	/* name is optional */
+	assert(out && repo && url);
+
+	if ((error = git_repository_config__weakptr(&config, repo)) < 0)
+		return error;
+
+	remote = git__calloc(1, sizeof(git_remote));
+	GITERR_CHECK_ALLOC(remote);
+
+	remote->repo = repo;
+
+	if (git_vector_init(&remote->refs, 32, NULL) < 0 ||
+		canonicalize_url(&canonical_url, url) < 0)
+		goto on_error;
+
+	remote->url = apply_insteadof(repo->_config, canonical_url.ptr, GIT_DIRECTION_FETCH);
+
+	if (name != NULL) {
+		remote->name = git__strdup(name);
+		GITERR_CHECK_ALLOC(remote->name);
+
+		if ((error = git_buf_printf(&var, CONFIG_URL_FMT, name)) < 0)
+			goto on_error;
+
+		if ((error = git_config_set_string(config, var.ptr, canonical_url.ptr)) < 0)
+			goto on_error;
+	}
+
+	if (fetch != NULL) {
+		if ((error = add_refspec(remote, fetch, true)) < 0)
+			goto on_error;
+
+		/* only write for non-anonymous remotes */
+		if (name && (error = write_add_refspec(repo, name, fetch, true)) < 0)
+			goto on_error;
+
+		if ((error = git_repository_config_snapshot(&config, repo)) < 0)
+			goto on_error;
+
+		if ((error = lookup_remote_prune_config(remote, config, name)) < 0)
+			goto on_error;
+
+		/* Move the data over to where the matching functions can find them */
+		if ((error = dwim_refspecs(&remote->active_refspecs, &remote->refspecs, &remote->refs)) < 0)
+			goto on_error;
+	}
+
+	/* A remote without a name doesn't download tags */
+	if (!name)
+		remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_NONE;
+	else
+		remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO;
+
+
+	git_buf_free(&var);
+
+	*out = remote;
+	error = 0;
+
+on_error:
+	if (error)
+		git_remote_free(remote);
+
+	git_config_free(config);
+	git_buf_free(&canonical_url);
+	git_buf_free(&var);
+	return error;
+}
+
+static int ensure_remote_doesnot_exist(git_repository *repo, const char *name)
+{
+	int error;
+	git_remote *remote;
+
+	error = git_remote_lookup(&remote, repo, name);
+
+	if (error == GIT_ENOTFOUND)
+		return 0;
+
+	if (error < 0)
+		return error;
+
+	git_remote_free(remote);
+
+	giterr_set(
+		GITERR_CONFIG,
+		"Remote '%s' already exists.", name);
+
+	return GIT_EEXISTS;
+}
+
+
+int git_remote_create(git_remote **out, git_repository *repo, const char *name, const char *url)
+{
+	git_buf buf = GIT_BUF_INIT;
+	int error;
+
+	if (git_buf_printf(&buf, "+refs/heads/*:refs/remotes/%s/*", name) < 0)
+		return -1;
+
+	error = git_remote_create_with_fetchspec(out, repo, name, url, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+
+	return error;
+}
+
+int git_remote_create_with_fetchspec(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch)
+{
+	git_remote *remote = NULL;
+	int error;
+
+	if ((error = ensure_remote_name_is_valid(name)) < 0)
+		return error;
+
+	if ((error = ensure_remote_doesnot_exist(repo, name)) < 0)
+		return error;
+
+	if (create_internal(&remote, repo, name, url, fetch) < 0)
+		goto on_error;
+
+	*out = remote;
+
+	return 0;
+
+on_error:
+	git_remote_free(remote);
+	return -1;
+}
+
+int git_remote_create_anonymous(git_remote **out, git_repository *repo, const char *url)
+{
+	return create_internal(out, repo, NULL, url, NULL);
+}
+
+int git_remote_dup(git_remote **dest, git_remote *source)
+{
+	size_t i;
+	int error = 0;
+	git_refspec *spec;
+	git_remote *remote = git__calloc(1, sizeof(git_remote));
+	GITERR_CHECK_ALLOC(remote);
+
+	if (source->name != NULL) {
+		remote->name = git__strdup(source->name);
+		GITERR_CHECK_ALLOC(remote->name);
+	}
+
+	if (source->url != NULL) {
+		remote->url = git__strdup(source->url);
+		GITERR_CHECK_ALLOC(remote->url);
+	}
+
+	if (source->pushurl != NULL) {
+		remote->pushurl = git__strdup(source->pushurl);
+		GITERR_CHECK_ALLOC(remote->pushurl);
+	}
+
+	remote->repo = source->repo;
+	remote->download_tags = source->download_tags;
+	remote->prune_refs = source->prune_refs;
+
+	if (git_vector_init(&remote->refs, 32, NULL) < 0 ||
+	    git_vector_init(&remote->refspecs, 2, NULL) < 0 ||
+	    git_vector_init(&remote->active_refspecs, 2, NULL) < 0) {
+		error = -1;
+		goto cleanup;
+	}
+
+	git_vector_foreach(&source->refspecs, i, spec) {
+		if ((error = add_refspec(remote, spec->string, !spec->push)) < 0)
+			goto cleanup;
+	}
+
+	*dest = remote;
+
+cleanup:
+
+	if (error < 0)
+		git__free(remote);
+
+	return error;
+}
+
+struct refspec_cb_data {
+	git_remote *remote;
+	int fetch;
+};
+
+static int refspec_cb(const git_config_entry *entry, void *payload)
+{
+	struct refspec_cb_data *data = (struct refspec_cb_data *)payload;
+	return add_refspec(data->remote, entry->value, data->fetch);
+}
+
+static int get_optional_config(
+	bool *found, git_config *config, git_buf *buf,
+	git_config_foreach_cb cb, void *payload)
+{
+	int error = 0;
+	const char *key = git_buf_cstr(buf);
+
+	if (git_buf_oom(buf))
+		return -1;
+
+	if (cb != NULL)
+		error = git_config_get_multivar_foreach(config, key, NULL, cb, payload);
+	else
+		error = git_config_get_string(payload, config, key);
+
+	if (found)
+		*found = !error;
+
+	if (error == GIT_ENOTFOUND) {
+		giterr_clear();
+		error = 0;
+	}
+
+	return error;
+}
+
+int git_remote_lookup(git_remote **out, git_repository *repo, const char *name)
+{
+	git_remote *remote;
+	git_buf buf = GIT_BUF_INIT;
+	const char *val;
+	int error = 0;
+	git_config *config;
+	struct refspec_cb_data data = { NULL };
+	bool optional_setting_found = false, found;
+
+	assert(out && repo && name);
+
+	if ((error = ensure_remote_name_is_valid(name)) < 0)
+		return error;
+
+	if ((error = git_repository_config_snapshot(&config, repo)) < 0)
+		return error;
+
+	remote = git__calloc(1, sizeof(git_remote));
+	GITERR_CHECK_ALLOC(remote);
+
+	remote->name = git__strdup(name);
+	GITERR_CHECK_ALLOC(remote->name);
+
+	if (git_vector_init(&remote->refs, 32, NULL) < 0 ||
+	    git_vector_init(&remote->refspecs, 2, NULL) < 0 ||
+	    git_vector_init(&remote->passive_refspecs, 2, NULL) < 0 ||
+	    git_vector_init(&remote->active_refspecs, 2, NULL) < 0) {
+		error = -1;
+		goto cleanup;
+	}
+
+	if ((error = git_buf_printf(&buf, "remote.%s.url", name)) < 0)
+		goto cleanup;
+
+	if ((error = get_optional_config(&found, config, &buf, NULL, (void *)&val)) < 0)
+		goto cleanup;
+
+	optional_setting_found |= found;
+
+	remote->repo = repo;
+	remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO;
+
+	if (found && strlen(val) > 0) {
+		remote->url = apply_insteadof(config, val, GIT_DIRECTION_FETCH);
+		GITERR_CHECK_ALLOC(remote->url);
+	}
+
+	val = NULL;
+	git_buf_clear(&buf);
+	git_buf_printf(&buf, "remote.%s.pushurl", name);
+
+	if ((error = get_optional_config(&found, config, &buf, NULL, (void *)&val)) < 0)
+		goto cleanup;
+
+	optional_setting_found |= found;
+
+	if (!optional_setting_found) {
+		error = GIT_ENOTFOUND;
+		giterr_set(GITERR_CONFIG, "Remote '%s' does not exist.", name);
+		goto cleanup;
+	}
+
+	if (found && strlen(val) > 0) {
+		remote->pushurl = apply_insteadof(config, val, GIT_DIRECTION_PUSH);
+		GITERR_CHECK_ALLOC(remote->pushurl);
+	}
+
+	data.remote = remote;
+	data.fetch = true;
+
+	git_buf_clear(&buf);
+	git_buf_printf(&buf, "remote.%s.fetch", name);
+
+	if ((error = get_optional_config(NULL, config, &buf, refspec_cb, &data)) < 0)
+		goto cleanup;
+
+	data.fetch = false;
+	git_buf_clear(&buf);
+	git_buf_printf(&buf, "remote.%s.push", name);
+
+	if ((error = get_optional_config(NULL, config, &buf, refspec_cb, &data)) < 0)
+		goto cleanup;
+
+	if (download_tags_value(remote, config) < 0)
+		goto cleanup;
+
+	if ((error = lookup_remote_prune_config(remote, config, name)) < 0)
+		goto cleanup;
+
+	/* Move the data over to where the matching functions can find them */
+	if ((error = dwim_refspecs(&remote->active_refspecs, &remote->refspecs, &remote->refs)) < 0)
+		goto cleanup;
+
+	*out = remote;
+
+cleanup:
+	git_config_free(config);
+	git_buf_free(&buf);
+
+	if (error < 0)
+		git_remote_free(remote);
+
+	return error;
+}
+
+static int lookup_remote_prune_config(git_remote *remote, git_config *config, const char *name)
+{
+	git_buf buf = GIT_BUF_INIT;
+	int error = 0;
+
+	git_buf_printf(&buf, "remote.%s.prune", name);
+
+	if ((error = git_config_get_bool(&remote->prune_refs, config, git_buf_cstr(&buf))) < 0) {
+		if (error == GIT_ENOTFOUND) {
+			giterr_clear();
+
+			if ((error = git_config_get_bool(&remote->prune_refs, config, "fetch.prune")) < 0) {
+				if (error == GIT_ENOTFOUND) {
+					giterr_clear();
+					error = 0;
+				}
+			}
+		}
+	}
+
+	git_buf_free(&buf);
+	return error;
+}
+
+static int update_config_refspec(const git_remote *remote, git_config *config, int direction)
+{
+	git_buf name = GIT_BUF_INIT;
+	unsigned int push;
+	const char *dir;
+	size_t i;
+	int error = 0;
+	const char *cname;
+
+	push = direction == GIT_DIRECTION_PUSH;
+	dir = push ? "push" : "fetch";
+
+	if (git_buf_printf(&name, "remote.%s.%s", remote->name, dir) < 0)
+		return -1;
+	cname = git_buf_cstr(&name);
+
+	/* Clear out the existing config */
+	while (!error)
+		error = git_config_delete_multivar(config, cname, ".*");
+
+	if (error != GIT_ENOTFOUND)
+		return error;
+
+	for (i = 0; i < remote->refspecs.length; i++) {
+		git_refspec *spec = git_vector_get(&remote->refspecs, i);
+
+		if (spec->push != push)
+			continue;
+
+		// "$^" is a unmatcheable regexp: it will not match anything at all, so
+		// all values will be considered new and we will not replace any
+		// present value.
+		if ((error = git_config_set_multivar(
+				config, cname, "$^", spec->string)) < 0) {
+			goto cleanup;
+		}
+	}
+
+	giterr_clear();
+	error = 0;
+
+cleanup:
+	git_buf_free(&name);
+
+	return error;
+}
+
+const char *git_remote_name(const git_remote *remote)
+{
+	assert(remote);
+	return remote->name;
+}
+
+git_repository *git_remote_owner(const git_remote *remote)
+{
+	assert(remote);
+	return remote->repo;
+}
+
+const char *git_remote_url(const git_remote *remote)
+{
+	assert(remote);
+	return remote->url;
+}
+
+static int set_url(git_repository *repo, const char *remote, const char *pattern, const char *url)
+{
+	git_config *cfg;
+	git_buf buf = GIT_BUF_INIT, canonical_url = GIT_BUF_INIT;
+	int error;
+
+	assert(repo && remote);
+
+	if ((error = ensure_remote_name_is_valid(remote)) < 0)
+		return error;
+
+	if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
+		return error;
+
+	if ((error = git_buf_printf(&buf, pattern, remote)) < 0)
+		return error;
+
+	if (url) {
+		if ((error = canonicalize_url(&canonical_url, url)) < 0)
+			goto cleanup;
+
+		error = git_config_set_string(cfg, buf.ptr, url);
+	} else {
+		error = git_config_delete_entry(cfg, buf.ptr);
+	}
+
+cleanup:
+	git_buf_free(&canonical_url);
+	git_buf_free(&buf);
+
+	return error;
+}
+
+int git_remote_set_url(git_repository *repo, const char *remote, const char *url)
+{
+	return set_url(repo, remote, CONFIG_URL_FMT, url);
+}
+
+const char *git_remote_pushurl(const git_remote *remote)
+{
+	assert(remote);
+	return remote->pushurl;
+}
+
+int git_remote_set_pushurl(git_repository *repo, const char *remote, const char* url)
+{
+	return set_url(repo, remote, CONFIG_PUSHURL_FMT, url);
+}
+
+const char* git_remote__urlfordirection(git_remote *remote, int direction)
+{
+	assert(remote);
+
+	assert(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH);
+
+	if (direction == GIT_DIRECTION_FETCH) {
+		return remote->url;
+	}
+
+	if (direction == GIT_DIRECTION_PUSH) {
+		return remote->pushurl ? remote->pushurl : remote->url;
+	}
+
+	return NULL;
+}
+
+int set_transport_callbacks(git_transport *t, const git_remote_callbacks *cbs)
+{
+	if (!t->set_callbacks || !cbs)
+		return 0;
+
+	return t->set_callbacks(t, cbs->sideband_progress, NULL,
+				cbs->certificate_check, cbs->payload);
+}
+
+int git_remote_connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks)
+{
+	git_transport *t;
+	const char *url;
+	int flags = GIT_TRANSPORTFLAGS_NONE;
+	int error;
+	void *payload = NULL;
+	git_cred_acquire_cb credentials = NULL;
+	git_transport_cb transport = NULL;
+
+	assert(remote);
+
+	if (callbacks) {
+		GITERR_CHECK_VERSION(callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks");
+		credentials = callbacks->credentials;
+		transport   = callbacks->transport;
+		payload     = callbacks->payload;
+	}
+
+	t = remote->transport;
+
+	url = git_remote__urlfordirection(remote, direction);
+	if (url == NULL) {
+		giterr_set(GITERR_INVALID,
+			"Malformed remote '%s' - missing URL", remote->name);
+		return -1;
+	}
+
+	/* If we don't have a transport object yet, and the caller specified a
+	 * custom transport factory, use that */
+	if (!t && transport &&
+		(error = transport(&t, remote, payload)) < 0)
+		return error;
+
+	/* If we still don't have a transport, then use the global
+	 * transport registrations which map URI schemes to transport factories */
+	if (!t && (error = git_transport_new(&t, remote, url)) < 0)
+		return error;
+
+	if ((error = set_transport_callbacks(t, callbacks)) < 0 ||
+	    (error = t->connect(t, url, credentials, payload, direction, flags)) != 0)
+		goto on_error;
+
+	remote->transport = t;
+
+	return 0;
+
+on_error:
+	t->free(t);
+
+	if (t == remote->transport)
+		remote->transport = NULL;
+
+	return error;
+}
+
+int git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote)
+{
+	assert(remote);
+
+	if (!remote->transport) {
+		giterr_set(GITERR_NET, "this remote has never connected");
+		return -1;
+	}
+
+	return remote->transport->ls(out, size, remote->transport);
+}
+
+int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_url)
+{
+	git_config *cfg;
+	git_config_entry *ce = NULL;
+	const char *val = NULL;
+	int error;
+
+	assert(remote);
+
+	if (!proxy_url || !remote->repo)
+		return -1;
+
+	*proxy_url = NULL;
+
+	if ((error = git_repository_config__weakptr(&cfg, remote->repo)) < 0)
+		return error;
+
+	/* Go through the possible sources for proxy configuration, from most specific
+	 * to least specific. */
+
+	/* remote.<name>.proxy config setting */
+	if (remote->name && remote->name[0]) {
+		git_buf buf = GIT_BUF_INIT;
+
+		if ((error = git_buf_printf(&buf, "remote.%s.proxy", remote->name)) < 0)
+			return error;
+
+		error = git_config__lookup_entry(&ce, cfg, git_buf_cstr(&buf), false);
+		git_buf_free(&buf);
+
+		if (error < 0)
+			return error;
+
+		if (ce && ce->value) {
+			val = ce->value;
+			goto found;
+		}
+	}
+
+	/* http.proxy config setting */
+	if ((error = git_config__lookup_entry(&ce, cfg, "http.proxy", false)) < 0)
+		return error;
+	if (ce && ce->value) {
+		val = ce->value;
+		goto found;
+	}
+
+	/* HTTP_PROXY / HTTPS_PROXY environment variables */
+	val = use_ssl ? getenv("HTTPS_PROXY") : getenv("HTTP_PROXY");
+
+found:
+	if (val && val[0]) {
+		*proxy_url = git__strdup(val);
+		GITERR_CHECK_ALLOC(*proxy_url);
+	}
+	git_config_entry_free(ce);
+
+	return 0;
+}
+
+/* DWIM `refspecs` based on `refs` and append the output to `out` */
+static int dwim_refspecs(git_vector *out, git_vector *refspecs, git_vector *refs)
+{
+	size_t i;
+	git_refspec *spec;
+
+	git_vector_foreach(refspecs, i, spec) {
+		if (git_refspec__dwim_one(out, spec, refs) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
+static void free_refspecs(git_vector *vec)
+{
+	size_t i;
+	git_refspec *spec;
+
+	git_vector_foreach(vec, i, spec) {
+		git_refspec__free(spec);
+		git__free(spec);
+	}
+
+	git_vector_clear(vec);
+}
+
+static int remote_head_cmp(const void *_a, const void *_b)
+{
+	const git_remote_head *a = (git_remote_head *) _a;
+	const git_remote_head *b = (git_remote_head *) _b;
+
+	return git__strcmp_cb(a->name, b->name);
+}
+
+static int ls_to_vector(git_vector *out, git_remote *remote)
+{
+	git_remote_head **heads;
+	size_t heads_len, i;
+
+	if (git_remote_ls((const git_remote_head ***)&heads, &heads_len, remote) < 0)
+		return -1;
+
+	if (git_vector_init(out, heads_len, remote_head_cmp) < 0)
+		return -1;
+
+	for (i = 0; i < heads_len; i++) {
+		if (git_vector_insert(out, heads[i]) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
+int git_remote_download(git_remote *remote, const git_strarray *refspecs, const git_fetch_options *opts)
+{
+	int error = -1;
+	size_t i;
+	git_vector *to_active, specs = GIT_VECTOR_INIT, refs = GIT_VECTOR_INIT;
+	const git_remote_callbacks *cbs = NULL;
+
+	assert(remote);
+
+	if (opts) {
+		GITERR_CHECK_VERSION(&opts->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks");
+		cbs = &opts->callbacks;
+	}
+
+	if (!git_remote_connected(remote) &&
+	    (error = git_remote_connect(remote, GIT_DIRECTION_FETCH, cbs)) < 0)
+		goto on_error;
+
+	if (ls_to_vector(&refs, remote) < 0)
+		return -1;
+
+	if ((git_vector_init(&specs, 0, NULL)) < 0)
+		goto on_error;
+
+	remote->passed_refspecs = 0;
+	if (!refspecs || !refspecs->count) {
+		to_active = &remote->refspecs;
+	} else {
+		for (i = 0; i < refspecs->count; i++) {
+			if ((error = add_refspec_to(&specs, refspecs->strings[i], true)) < 0)
+				goto on_error;
+		}
+
+		to_active = &specs;
+		remote->passed_refspecs = 1;
+	}
+
+	free_refspecs(&remote->passive_refspecs);
+	if ((error = dwim_refspecs(&remote->passive_refspecs, &remote->refspecs, &refs)) < 0)
+		goto on_error;
+
+	free_refspecs(&remote->active_refspecs);
+	error = dwim_refspecs(&remote->active_refspecs, to_active, &refs);
+
+	git_vector_free(&refs);
+	free_refspecs(&specs);
+	git_vector_free(&specs);
+
+	if (error < 0)
+		return error;
+
+	if (remote->push) {
+		git_push_free(remote->push);
+		remote->push = NULL;
+	}
+
+	if ((error = git_fetch_negotiate(remote, opts)) < 0)
+		return error;
+
+	return git_fetch_download_pack(remote, cbs);
+
+on_error:
+	git_vector_free(&refs);
+	free_refspecs(&specs);
+	git_vector_free(&specs);
+	return error;
+}
+
+int git_remote_fetch(
+		git_remote *remote,
+		const git_strarray *refspecs,
+		const git_fetch_options *opts,
+		const char *reflog_message)
+{
+	int error, update_fetchhead = 1;
+	git_remote_autotag_option_t tagopt = remote->download_tags;
+	bool prune = false;
+	git_buf reflog_msg_buf = GIT_BUF_INIT;
+	const git_remote_callbacks *cbs = NULL;
+
+	if (opts) {
+		GITERR_CHECK_VERSION(&opts->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks");
+		cbs = &opts->callbacks;
+		update_fetchhead = opts->update_fetchhead;
+		tagopt = opts->download_tags;
+	}
+
+	/* Connect and download everything */
+	if ((error = git_remote_connect(remote, GIT_DIRECTION_FETCH, cbs)) != 0)
+		return error;
+
+	error = git_remote_download(remote, refspecs, opts);
+
+	/* We don't need to be connected anymore */
+	git_remote_disconnect(remote);
+
+	/* If the download failed, return the error */
+	if (error != 0)
+		return error;
+
+	/* Default reflog message */
+	if (reflog_message)
+		git_buf_sets(&reflog_msg_buf, reflog_message);
+	else {
+		git_buf_printf(&reflog_msg_buf, "fetch %s",
+				remote->name ? remote->name : remote->url);
+	}
+
+	/* Create "remote/foo" branches for all remote branches */
+	error = git_remote_update_tips(remote, cbs, update_fetchhead, tagopt, git_buf_cstr(&reflog_msg_buf));
+	git_buf_free(&reflog_msg_buf);
+	if (error < 0)
+		return error;
+
+	if (opts && opts->prune == GIT_FETCH_PRUNE)
+		prune = true;
+	else if (opts && opts->prune == GIT_FETCH_PRUNE_UNSPECIFIED && remote->prune_refs)
+		prune = true;
+	else if (opts && opts->prune == GIT_FETCH_NO_PRUNE)
+		prune = false;
+	else
+		prune = remote->prune_refs;
+
+	if (prune)
+		error = git_remote_prune(remote, cbs);
+
+	return error;
+}
+
+static int remote_head_for_fetchspec_src(git_remote_head **out, git_vector *update_heads, const char *fetchspec_src)
+{
+	unsigned int i;
+	git_remote_head *remote_ref;
+
+	assert(update_heads && fetchspec_src);
+
+	*out = NULL;
+
+	git_vector_foreach(update_heads, i, remote_ref) {
+		if (strcmp(remote_ref->name, fetchspec_src) == 0) {
+			*out = remote_ref;
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int ref_to_update(int *update, git_buf *remote_name, git_remote *remote, git_refspec *spec, const char *ref_name)
+{
+	int error = 0;
+	git_repository *repo;
+	git_buf upstream_remote = GIT_BUF_INIT;
+	git_buf upstream_name = GIT_BUF_INIT;
+
+	repo = git_remote_owner(remote);
+
+	if ((!git_reference__is_branch(ref_name)) ||
+	    !git_remote_name(remote) ||
+	    (error = git_branch_upstream_remote(&upstream_remote, repo, ref_name) < 0) ||
+	    git__strcmp(git_remote_name(remote), git_buf_cstr(&upstream_remote)) ||
+	    (error = git_branch_upstream_name(&upstream_name, repo, ref_name)) < 0 ||
+	    !git_refspec_dst_matches(spec, git_buf_cstr(&upstream_name)) ||
+	    (error = git_refspec_rtransform(remote_name, spec, upstream_name.ptr)) < 0) {
+		/* Not an error if there is no upstream */
+		if (error == GIT_ENOTFOUND) {
+			giterr_clear();
+			error = 0;
+		}
+
+		*update = 0;
+	} else {
+		*update = 1;
+	}
+
+	git_buf_free(&upstream_remote);
+	git_buf_free(&upstream_name);
+	return error;
+}
+
+static int remote_head_for_ref(git_remote_head **out, git_remote *remote, git_refspec *spec, git_vector *update_heads, git_reference *ref)
+{
+	git_reference *resolved_ref = NULL;
+	git_buf remote_name = GIT_BUF_INIT;
+	git_config *config = NULL;
+	const char *ref_name;
+	int error = 0, update;
+
+	assert(out && spec && ref);
+
+	*out = NULL;
+
+	error = git_reference_resolve(&resolved_ref, ref);
+
+	/* If we're in an unborn branch, let's pretend nothing happened */
+	if (error == GIT_ENOTFOUND && git_reference_type(ref) == GIT_REF_SYMBOLIC) {
+		ref_name = git_reference_symbolic_target(ref);
+		error = 0;
+	} else {
+		ref_name = git_reference_name(resolved_ref);
+	}
+
+	if ((error = ref_to_update(&update, &remote_name, remote, spec, ref_name)) < 0)
+		goto cleanup;
+
+	if (update)
+		error = remote_head_for_fetchspec_src(out, update_heads, git_buf_cstr(&remote_name));
+
+cleanup:
+	git_buf_free(&remote_name);
+	git_reference_free(resolved_ref);
+	git_config_free(config);
+	return error;
+}
+
+static int git_remote_write_fetchhead(git_remote *remote, git_refspec *spec, git_vector *update_heads)
+{
+	git_reference *head_ref = NULL;
+	git_fetchhead_ref *fetchhead_ref;
+	git_remote_head *remote_ref, *merge_remote_ref;
+	git_vector fetchhead_refs;
+	bool include_all_fetchheads;
+	unsigned int i = 0;
+	int error = 0;
+
+	assert(remote);
+
+	/* no heads, nothing to do */
+	if (update_heads->length == 0)
+		return 0;
+
+	if (git_vector_init(&fetchhead_refs, update_heads->length, git_fetchhead_ref_cmp) < 0)
+		return -1;
+
+	/* Iff refspec is * (but not subdir slash star), include tags */
+	include_all_fetchheads = (strcmp(GIT_REFS_HEADS_DIR "*", git_refspec_src(spec)) == 0);
+
+	/* Determine what to merge: if refspec was a wildcard, just use HEAD */
+	if (git_refspec_is_wildcard(spec)) {
+		if ((error = git_reference_lookup(&head_ref, remote->repo, GIT_HEAD_FILE)) < 0 ||
+			(error = remote_head_for_ref(&merge_remote_ref, remote, spec, update_heads, head_ref)) < 0)
+				goto cleanup;
+	} else {
+		/* If we're fetching a single refspec, that's the only thing that should be in FETCH_HEAD. */
+		if ((error = remote_head_for_fetchspec_src(&merge_remote_ref, update_heads, git_refspec_src(spec))) < 0)
+			goto cleanup;
+	}
+
+	/* Create the FETCH_HEAD file */
+	git_vector_foreach(update_heads, i, remote_ref) {
+		int merge_this_fetchhead = (merge_remote_ref == remote_ref);
+
+		if (!include_all_fetchheads &&
+			!git_refspec_src_matches(spec, remote_ref->name) &&
+			!merge_this_fetchhead)
+			continue;
+
+		if (git_fetchhead_ref_create(&fetchhead_ref,
+			&remote_ref->oid,
+			merge_this_fetchhead,
+			remote_ref->name,
+			git_remote_url(remote)) < 0)
+			goto cleanup;
+
+		if (git_vector_insert(&fetchhead_refs, fetchhead_ref) < 0)
+			goto cleanup;
+	}
+
+	git_fetchhead_write(remote->repo, &fetchhead_refs);
+
+cleanup:
+	for (i = 0; i < fetchhead_refs.length; ++i)
+		git_fetchhead_ref_free(fetchhead_refs.contents[i]);
+
+	git_vector_free(&fetchhead_refs);
+	git_reference_free(head_ref);
+
+	return error;
+}
+
+/**
+ * Generate a list of candidates for pruning by getting a list of
+ * references which match the rhs of an active refspec.
+ */
+static int prune_candidates(git_vector *candidates, git_remote *remote)
+{
+	git_strarray arr = { 0 };
+	size_t i;
+	int error;
+
+	if ((error = git_reference_list(&arr, remote->repo)) < 0)
+		return error;
+
+	for (i = 0; i < arr.count; i++) {
+		const char *refname = arr.strings[i];
+		char *refname_dup;
+
+		if (!git_remote__matching_dst_refspec(remote, refname))
+			continue;
+
+		refname_dup = git__strdup(refname);
+		GITERR_CHECK_ALLOC(refname_dup);
+
+		if ((error = git_vector_insert(candidates, refname_dup)) < 0)
+			goto out;
+	}
+
+out:
+	git_strarray_free(&arr);
+	return error;
+}
+
+static int find_head(const void *_a, const void *_b)
+{
+	git_remote_head *a = (git_remote_head *) _a;
+	git_remote_head *b = (git_remote_head *) _b;
+
+	return strcmp(a->name, b->name);
+}
+
+int git_remote_prune(git_remote *remote, const git_remote_callbacks *callbacks)
+{
+	size_t i, j;
+	git_vector remote_refs = GIT_VECTOR_INIT;
+	git_vector candidates = GIT_VECTOR_INIT;
+	const git_refspec *spec;
+	const char *refname;
+	int error;
+	git_oid zero_id = {{ 0 }};
+
+	if (callbacks)
+		GITERR_CHECK_VERSION(callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks");
+
+	if ((error = ls_to_vector(&remote_refs, remote)) < 0)
+		goto cleanup;
+
+	git_vector_set_cmp(&remote_refs, find_head);
+
+	if ((error = prune_candidates(&candidates, remote)) < 0)
+		goto cleanup;
+
+	/*
+	 * Remove those entries from the candidate list for which we
+	 * can find a remote reference in at least one refspec.
+	 */
+	git_vector_foreach(&candidates, i, refname) {
+		git_vector_foreach(&remote->active_refspecs, j, spec) {
+			git_buf buf = GIT_BUF_INIT;
+			size_t pos;
+			char *src_name;
+			git_remote_head key = {0};
+
+			if (!git_refspec_dst_matches(spec, refname))
+				continue;
+
+			if ((error = git_refspec_rtransform(&buf, spec, refname)) < 0)
+				goto cleanup;
+
+			key.name = (char *) git_buf_cstr(&buf);
+			error = git_vector_search(&pos, &remote_refs, &key);
+			git_buf_free(&buf);
+
+			if (error < 0 && error != GIT_ENOTFOUND)
+				goto cleanup;
+
+			if (error == GIT_ENOTFOUND)
+				continue;
+
+			/* if we did find a source, remove it from the candiates */
+			if ((error = git_vector_set((void **) &src_name, &candidates, i, NULL)) < 0)
+				goto cleanup;
+
+			git__free(src_name);
+			break;
+		}
+	}
+
+	/*
+	 * For those candidates still left in the list, we need to
+	 * remove them. We do not remove symrefs, as those are for
+	 * stuff like origin/HEAD which will never match, but we do
+	 * not want to remove them.
+	 */
+	git_vector_foreach(&candidates, i, refname) {
+		git_reference *ref;
+		git_oid id;
+
+		if (refname == NULL)
+			continue;
+
+		error = git_reference_lookup(&ref, remote->repo, refname);
+		/* as we want it gone, let's not consider this an error */
+		if (error == GIT_ENOTFOUND)
+			continue;
+
+		if (error < 0)
+			goto cleanup;
+
+		if (git_reference_type(ref) == GIT_REF_SYMBOLIC) {
+			git_reference_free(ref);
+			continue;
+		}
+
+		git_oid_cpy(&id, git_reference_target(ref));
+		error = git_reference_delete(ref);
+		git_reference_free(ref);
+		if (error < 0)
+			goto cleanup;
+
+		if (callbacks && callbacks->update_tips)
+			error = callbacks->update_tips(refname, &id, &zero_id, callbacks->payload);
+
+		if (error < 0)
+			goto cleanup;
+	}
+
+cleanup:
+	git_vector_free(&remote_refs);
+	git_vector_free_deep(&candidates);
+	return error;
+}
+
+static int update_tips_for_spec(
+		git_remote *remote,
+		const git_remote_callbacks *callbacks,
+		int update_fetchhead,
+		git_remote_autotag_option_t tagopt,
+		git_refspec *spec,
+		git_vector *refs,
+		const char *log_message)
+{
+	int error = 0, autotag;
+	unsigned int i = 0;
+	git_buf refname = GIT_BUF_INIT;
+	git_oid old;
+	git_odb *odb;
+	git_remote_head *head;
+	git_reference *ref;
+	git_refspec tagspec;
+	git_vector update_heads;
+
+	assert(remote);
+
+	if (git_repository_odb__weakptr(&odb, remote->repo) < 0)
+		return -1;
+
+	if (git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true) < 0)
+		return -1;
+
+	/* Make a copy of the transport's refs */
+	if (git_vector_init(&update_heads, 16, NULL) < 0)
+		return -1;
+
+	for (; i < refs->length; ++i) {
+		head = git_vector_get(refs, i);
+		autotag = 0;
+		git_buf_clear(&refname);
+
+		/* Ignore malformed ref names (which also saves us from tag^{} */
+		if (!git_reference_is_valid_name(head->name))
+			continue;
+
+		/* If we have a tag, see if the auto-follow rules say to update it */
+		if (git_refspec_src_matches(&tagspec, head->name)) {
+			if (tagopt != GIT_REMOTE_DOWNLOAD_TAGS_NONE) {
+
+				if (tagopt == GIT_REMOTE_DOWNLOAD_TAGS_AUTO)
+					autotag = 1;
+
+				git_buf_clear(&refname);
+				if (git_buf_puts(&refname, head->name) < 0)
+					goto on_error;
+			}
+		}
+
+		/* If we didn't want to auto-follow the tag, check if the refspec matches */
+		if (!autotag && git_refspec_src_matches(spec, head->name)) {
+			if (spec->dst) {
+				if (git_refspec_transform(&refname, spec, head->name) < 0)
+					goto on_error;
+			} else {
+				/*
+				 * no rhs mans store it in FETCH_HEAD, even if we don't
+				 update anything else.
+				 */
+				if ((error = git_vector_insert(&update_heads, head)) < 0)
+					goto on_error;
+
+				continue;
+			}
+		}
+
+		/* If we still don't have a refname, we don't want it */
+		if (git_buf_len(&refname) == 0) {
+			continue;
+		}
+
+		/* In autotag mode, only create tags for objects already in db */
+		if (autotag && !git_odb_exists(odb, &head->oid))
+			continue;
+
+		if (!autotag && git_vector_insert(&update_heads, head) < 0)
+			goto on_error;
+
+		error = git_reference_name_to_id(&old, remote->repo, refname.ptr);
+		if (error < 0 && error != GIT_ENOTFOUND)
+			goto on_error;
+
+		if (error == GIT_ENOTFOUND) {
+			memset(&old, 0, GIT_OID_RAWSZ);
+
+			if (autotag && git_vector_insert(&update_heads, head) < 0)
+				goto on_error;
+		}
+
+		if (!git_oid__cmp(&old, &head->oid))
+			continue;
+
+		/* In autotag mode, don't overwrite any locally-existing tags */
+		error = git_reference_create(&ref, remote->repo, refname.ptr, &head->oid, !autotag, 
+				log_message);
+		if (error < 0 && error != GIT_EEXISTS)
+			goto on_error;
+
+		git_reference_free(ref);
+
+		if (callbacks && callbacks->update_tips != NULL) {
+			if (callbacks->update_tips(refname.ptr, &old, &head->oid, callbacks->payload) < 0)
+				goto on_error;
+		}
+	}
+
+	if (update_fetchhead &&
+	    (error = git_remote_write_fetchhead(remote, spec, &update_heads)) < 0)
+		goto on_error;
+
+	git_vector_free(&update_heads);
+	git_refspec__free(&tagspec);
+	git_buf_free(&refname);
+	return 0;
+
+on_error:
+	git_vector_free(&update_heads);
+	git_refspec__free(&tagspec);
+	git_buf_free(&refname);
+	return -1;
+
+}
+
+/**
+ * Iteration over the three vectors, with a pause whenever we find a match
+ *
+ * On each stop, we store the iteration stat in the inout i,j,k
+ * parameters, and return the currently matching passive refspec as
+ * well as the head which we matched.
+ */
+static int next_head(const git_remote *remote, git_vector *refs,
+		     git_refspec **out_spec, git_remote_head **out_head,
+		     size_t *out_i, size_t *out_j, size_t *out_k)
+{
+	const git_vector *active, *passive;
+	git_remote_head *head;
+	git_refspec *spec, *passive_spec;
+	size_t i, j, k;
+
+	active = &remote->active_refspecs;
+	passive = &remote->passive_refspecs;
+
+	i = *out_i;
+	j = *out_j;
+	k = *out_k;
+
+	for (; i < refs->length; i++) {
+		head = git_vector_get(refs, i);
+
+		if (!git_reference_is_valid_name(head->name))
+			continue;
+
+		for (; j < active->length; j++) {
+			spec = git_vector_get(active, j);
+
+			if (!git_refspec_src_matches(spec, head->name))
+				continue;
+
+			for (; k < passive->length; k++) {
+				passive_spec = git_vector_get(passive, k);
+
+				if (!git_refspec_src_matches(passive_spec, head->name))
+				    continue;
+
+				*out_spec = passive_spec;
+				*out_head = head;
+				*out_i = i;
+				*out_j = j;
+				*out_k = k + 1;
+				return 0;
+
+			}
+			k = 0;
+		}
+		j = 0;
+	}
+
+	return GIT_ITEROVER;
+}
+
+static int opportunistic_updates(const git_remote *remote, const git_remote_callbacks *callbacks,
+				 git_vector *refs, const char *msg)
+{
+	size_t i, j, k;
+	git_refspec *spec;
+	git_remote_head *head;
+	git_reference *ref;
+	git_buf refname = GIT_BUF_INIT;
+	int error = 0;
+
+	i = j = k = 0;
+
+	while ((error = next_head(remote, refs, &spec, &head, &i, &j, &k)) == 0) {
+		git_oid old = {{ 0 }};
+		/*
+		 * If we got here, there is a refspec which was used
+		 * for fetching which matches the source of one of the
+		 * passive refspecs, so we should update that
+		 * remote-tracking branch, but not add it to
+		 * FETCH_HEAD
+		 */
+
+		git_buf_clear(&refname);
+		if ((error = git_refspec_transform(&refname, spec, head->name)) < 0)
+			goto cleanup;
+
+		error = git_reference_name_to_id(&old, remote->repo, refname.ptr);
+		if (error < 0 && error != GIT_ENOTFOUND)
+			goto cleanup;
+
+		if (!git_oid_cmp(&old, &head->oid))
+			continue;
+
+		/* If we did find a current reference, make sure we haven't lost a race */
+		if (error)
+			error = git_reference_create(&ref, remote->repo, refname.ptr, &head->oid, true, msg);
+		else
+			error = git_reference_create_matching(&ref, remote->repo, refname.ptr, &head->oid, true, &old, msg);
+		git_reference_free(ref);
+		if (error < 0)
+			goto cleanup;
+
+		if (callbacks && callbacks->update_tips != NULL) {
+			if (callbacks->update_tips(refname.ptr, &old, &head->oid, callbacks->payload) < 0)
+				goto cleanup;
+		}
+	}
+
+	if (error == GIT_ITEROVER)
+		error = 0;
+
+cleanup:
+	git_buf_free(&refname);
+	return error;
+}
+
+int git_remote_update_tips(
+		git_remote *remote,
+		const git_remote_callbacks *callbacks,
+		int update_fetchhead,
+		git_remote_autotag_option_t download_tags,
+		const char *reflog_message)
+{
+	git_refspec *spec, tagspec;
+	git_vector refs = GIT_VECTOR_INIT;
+	git_remote_autotag_option_t tagopt;
+	int error;
+	size_t i;
+
+	/* push has its own logic hidden away in the push object */
+	if (remote->push) {
+		return git_push_update_tips(remote->push, callbacks);
+	}
+
+	if (git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true) < 0)
+		return -1;
+
+
+	if ((error = ls_to_vector(&refs, remote)) < 0)
+		goto out;
+
+	if (download_tags == GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED)
+		tagopt = remote->download_tags;
+	else
+		tagopt = download_tags;
+
+	if (tagopt == GIT_REMOTE_DOWNLOAD_TAGS_ALL) {
+		if ((error = update_tips_for_spec(remote, callbacks, update_fetchhead, tagopt, &tagspec, &refs, reflog_message)) < 0)
+			goto out;
+	}
+
+	git_vector_foreach(&remote->active_refspecs, i, spec) {
+		if (spec->push)
+			continue;
+
+		if ((error = update_tips_for_spec(remote, callbacks, update_fetchhead, tagopt, spec, &refs, reflog_message)) < 0)
+			goto out;
+	}
+
+	/* only try to do opportunisitic updates if the refpec lists differ */
+	if (remote->passed_refspecs)
+		error = opportunistic_updates(remote, callbacks, &refs, reflog_message);
+
+out:
+	git_vector_free(&refs);
+	git_refspec__free(&tagspec);
+	return error;
+}
+
+int git_remote_connected(const git_remote *remote)
+{
+	assert(remote);
+
+	if (!remote->transport || !remote->transport->is_connected)
+		return 0;
+
+	/* Ask the transport if it's connected. */
+	return remote->transport->is_connected(remote->transport);
+}
+
+void git_remote_stop(git_remote *remote)
+{
+	assert(remote);
+
+	if (remote->transport && remote->transport->cancel)
+		remote->transport->cancel(remote->transport);
+}
+
+void git_remote_disconnect(git_remote *remote)
+{
+	assert(remote);
+
+	if (git_remote_connected(remote))
+		remote->transport->close(remote->transport);
+}
+
+void git_remote_free(git_remote *remote)
+{
+	if (remote == NULL)
+		return;
+
+	if (remote->transport != NULL) {
+		git_remote_disconnect(remote);
+
+		remote->transport->free(remote->transport);
+		remote->transport = NULL;
+	}
+
+	git_vector_free(&remote->refs);
+
+	free_refspecs(&remote->refspecs);
+	git_vector_free(&remote->refspecs);
+
+	free_refspecs(&remote->active_refspecs);
+	git_vector_free(&remote->active_refspecs);
+
+	free_refspecs(&remote->passive_refspecs);
+	git_vector_free(&remote->passive_refspecs);
+
+	git_push_free(remote->push);
+	git__free(remote->url);
+	git__free(remote->pushurl);
+	git__free(remote->name);
+	git__free(remote);
+}
+
+static int remote_list_cb(const git_config_entry *entry, void *payload)
+{
+	git_vector *list = payload;
+	const char *name = entry->name + strlen("remote.");
+	size_t namelen = strlen(name);
+	char *remote_name;
+
+	/* we know name matches "remote.<stuff>.(push)?url" */
+
+	if (!strcmp(&name[namelen - 4], ".url"))
+		remote_name = git__strndup(name, namelen - 4); /* strip ".url" */
+	else
+		remote_name = git__strndup(name, namelen - 8); /* strip ".pushurl" */
+	GITERR_CHECK_ALLOC(remote_name);
+
+	return git_vector_insert(list, remote_name);
+}
+
+int git_remote_list(git_strarray *remotes_list, git_repository *repo)
+{
+	int error;
+	git_config *cfg;
+	git_vector list = GIT_VECTOR_INIT;
+
+	if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
+		return error;
+
+	if ((error = git_vector_init(&list, 4, git__strcmp_cb)) < 0)
+		return error;
+
+	error = git_config_foreach_match(
+		cfg, "^remote\\..*\\.(push)?url$", remote_list_cb, &list);
+
+	if (error < 0) {
+		git_vector_free_deep(&list);
+		return error;
+	}
+
+	git_vector_uniq(&list, git__free);
+
+	remotes_list->strings =
+		(char **)git_vector_detach(&remotes_list->count, NULL, &list);
+
+	return 0;
+}
+
+const git_transfer_progress* git_remote_stats(git_remote *remote)
+{
+	assert(remote);
+	return &remote->stats;
+}
+
+git_remote_autotag_option_t git_remote_autotag(const git_remote *remote)
+{
+	return remote->download_tags;
+}
+
+int git_remote_set_autotag(git_repository *repo, const char *remote, git_remote_autotag_option_t value)
+{
+	git_buf var = GIT_BUF_INIT;
+	git_config *config;
+	int error;
+
+	assert(repo && remote);
+
+	if ((error = ensure_remote_name_is_valid(remote)) < 0)
+		return error;
+
+	if ((error = git_repository_config__weakptr(&config, repo)) < 0)
+		return error;
+
+	if ((error = git_buf_printf(&var, CONFIG_TAGOPT_FMT, remote)))
+		return error;
+
+	switch (value) {
+	case GIT_REMOTE_DOWNLOAD_TAGS_NONE:
+		error = git_config_set_string(config, var.ptr, "--no-tags");
+		break;
+	case GIT_REMOTE_DOWNLOAD_TAGS_ALL:
+		error = git_config_set_string(config, var.ptr, "--tags");
+		break;
+	case GIT_REMOTE_DOWNLOAD_TAGS_AUTO:
+		error = git_config_delete_entry(config, var.ptr);
+		if (error == GIT_ENOTFOUND)
+			error = 0;
+		break;
+	default:
+		giterr_set(GITERR_INVALID, "Invalid value for the tagopt setting");
+		error = -1;
+	}
+
+	git_buf_free(&var);
+	return error;
+}
+
+int git_remote_prune_refs(const git_remote *remote)
+{
+	return remote->prune_refs;
+}
+
+static int rename_remote_config_section(
+	git_repository *repo,
+	const char *old_name,
+	const char *new_name)
+{
+	git_buf old_section_name = GIT_BUF_INIT,
+		new_section_name = GIT_BUF_INIT;
+	int error = -1;
+
+	if (git_buf_printf(&old_section_name, "remote.%s", old_name) < 0)
+		goto cleanup;
+
+	if (new_name &&
+		(git_buf_printf(&new_section_name, "remote.%s", new_name) < 0))
+			goto cleanup;
+
+	error = git_config_rename_section(
+		repo,
+		git_buf_cstr(&old_section_name),
+		new_name ? git_buf_cstr(&new_section_name) : NULL);
+
+cleanup:
+	git_buf_free(&old_section_name);
+	git_buf_free(&new_section_name);
+
+	return error;
+}
+
+struct update_data {
+	git_config *config;
+	const char *old_remote_name;
+	const char *new_remote_name;
+};
+
+static int update_config_entries_cb(
+	const git_config_entry *entry,
+	void *payload)
+{
+	struct update_data *data = (struct update_data *)payload;
+
+	if (strcmp(entry->value, data->old_remote_name))
+		return 0;
+
+	return git_config_set_string(
+		data->config, entry->name, data->new_remote_name);
+}
+
+static int update_branch_remote_config_entry(
+	git_repository *repo,
+	const char *old_name,
+	const char *new_name)
+{
+	int error;
+	struct update_data data = { NULL };
+
+	if ((error = git_repository_config__weakptr(&data.config, repo)) < 0)
+		return error;
+
+	data.old_remote_name = old_name;
+	data.new_remote_name = new_name;
+
+	return git_config_foreach_match(
+		data.config, "branch\\..+\\.remote", update_config_entries_cb, &data);
+}
+
+static int rename_one_remote_reference(
+	git_reference *reference_in,
+	const char *old_remote_name,
+	const char *new_remote_name)
+{
+	int error;
+	git_reference *ref = NULL, *dummy = NULL;
+	git_buf namespace = GIT_BUF_INIT, old_namespace = GIT_BUF_INIT;
+	git_buf new_name = GIT_BUF_INIT;
+	git_buf log_message = GIT_BUF_INIT;
+	size_t pfx_len;
+	const char *target;
+
+	if ((error = git_buf_printf(&namespace, GIT_REFS_REMOTES_DIR "%s/", new_remote_name)) < 0)
+		return error;
+
+	pfx_len = strlen(GIT_REFS_REMOTES_DIR) + strlen(old_remote_name) + 1;
+	git_buf_puts(&new_name, namespace.ptr);
+	if ((error = git_buf_puts(&new_name, git_reference_name(reference_in) + pfx_len)) < 0)
+		goto cleanup;
+
+	if ((error = git_buf_printf(&log_message,
+					"renamed remote %s to %s",
+					old_remote_name, new_remote_name)) < 0)
+		goto cleanup;
+
+	if ((error = git_reference_rename(&ref, reference_in, git_buf_cstr(&new_name), 1,
+					  git_buf_cstr(&log_message))) < 0)
+		goto cleanup;
+
+	if (git_reference_type(ref) != GIT_REF_SYMBOLIC)
+		goto cleanup;
+
+	/* Handle refs like origin/HEAD -> origin/master */
+	target = git_reference_symbolic_target(ref);
+	if ((error = git_buf_printf(&old_namespace, GIT_REFS_REMOTES_DIR "%s/", old_remote_name)) < 0)
+		goto cleanup;
+
+	if (git__prefixcmp(target, old_namespace.ptr))
+		goto cleanup;
+
+	git_buf_clear(&new_name);
+	git_buf_puts(&new_name, namespace.ptr);
+	if ((error = git_buf_puts(&new_name, target + pfx_len)) < 0)
+		goto cleanup;
+
+	error = git_reference_symbolic_set_target(&dummy, ref, git_buf_cstr(&new_name),
+						  git_buf_cstr(&log_message));
+
+	git_reference_free(dummy);
+
+cleanup:
+	git_reference_free(reference_in);
+	git_reference_free(ref);
+	git_buf_free(&namespace);
+	git_buf_free(&old_namespace);
+	git_buf_free(&new_name);
+	git_buf_free(&log_message);
+	return error;
+}
+
+static int rename_remote_references(
+	git_repository *repo,
+	const char *old_name,
+	const char *new_name)
+{
+	int error;
+	git_buf buf = GIT_BUF_INIT;
+	git_reference *ref;
+	git_reference_iterator *iter;
+
+	if ((error = git_buf_printf(&buf, GIT_REFS_REMOTES_DIR "%s/*", old_name)) < 0)
+		return error;
+
+	error = git_reference_iterator_glob_new(&iter, repo, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+
+	if (error < 0)
+		return error;
+
+	while ((error = git_reference_next(&ref, iter)) == 0) {
+		if ((error = rename_one_remote_reference(ref, old_name, new_name)) < 0)
+			break;
+	}
+
+	git_reference_iterator_free(iter);
+
+	return (error == GIT_ITEROVER) ? 0 : error;
+}
+
+static int rename_fetch_refspecs(git_vector *problems, git_remote *remote, const char *new_name)
+{
+	git_config *config;
+	git_buf base = GIT_BUF_INIT, var = GIT_BUF_INIT, val = GIT_BUF_INIT;
+	const git_refspec *spec;
+	size_t i;
+	int error = 0;
+
+	if ((error = git_repository_config__weakptr(&config, remote->repo)) < 0)
+		return error;
+
+	if ((error = git_vector_init(problems, 1, NULL)) < 0)
+		return error;
+
+	if ((error = git_buf_printf(
+			&base, "+refs/heads/*:refs/remotes/%s/*", remote->name)) < 0)
+		return error;
+
+	git_vector_foreach(&remote->refspecs, i, spec) {
+		if (spec->push)
+			continue;
+
+		/* Does the dst part of the refspec follow the expected format? */
+		if (strcmp(git_buf_cstr(&base), spec->string)) {
+			char *dup;
+
+			dup = git__strdup(spec->string);
+			GITERR_CHECK_ALLOC(dup);
+
+			if ((error = git_vector_insert(problems, dup)) < 0)
+				break;
+
+			continue;
+		}
+
+		/* If we do want to move it to the new section */
+
+		git_buf_clear(&val);
+		git_buf_clear(&var);
+
+		if (git_buf_printf(
+				&val, "+refs/heads/*:refs/remotes/%s/*", new_name) < 0 ||
+			git_buf_printf(&var, "remote.%s.fetch", new_name) < 0)
+		{
+			error = -1;
+			break;
+		}
+
+		if ((error = git_config_set_string(
+				config, git_buf_cstr(&var), git_buf_cstr(&val))) < 0)
+			break;
+	}
+
+	git_buf_free(&base);
+	git_buf_free(&var);
+	git_buf_free(&val);
+
+	if (error < 0) {
+		char *str;
+		git_vector_foreach(problems, i, str)
+			git__free(str);
+
+		git_vector_free(problems);
+	}
+
+	return error;
+}
+
+int git_remote_rename(git_strarray *out, git_repository *repo, const char *name, const char *new_name)
+{
+	int error;
+	git_vector problem_refspecs = GIT_VECTOR_INIT;
+	git_remote *remote = NULL;
+
+	assert(out && repo && name && new_name);
+
+	if ((error = git_remote_lookup(&remote, repo, name)) < 0)
+		return error;
+
+	if ((error = ensure_remote_name_is_valid(new_name)) < 0)
+		goto cleanup;
+
+	if ((error = ensure_remote_doesnot_exist(repo, new_name)) < 0)
+		goto cleanup;
+
+	if ((error = rename_remote_config_section(repo, name, new_name)) < 0)
+		goto cleanup;
+
+	if ((error = update_branch_remote_config_entry(repo, name, new_name)) < 0)
+		goto cleanup;
+
+	if ((error = rename_remote_references(repo, name, new_name)) < 0)
+		goto cleanup;
+
+	if ((error = rename_fetch_refspecs(&problem_refspecs, remote, new_name)) < 0)
+		goto cleanup;
+
+	out->count = problem_refspecs.length;
+	out->strings = (char **) problem_refspecs.contents;
+
+cleanup:
+	if (error < 0)
+		git_vector_free(&problem_refspecs);
+
+	git_remote_free(remote);
+	return error;
+}
+
+int git_remote_is_valid_name(
+	const char *remote_name)
+{
+	git_buf buf = GIT_BUF_INIT;
+	git_refspec refspec;
+	int error = -1;
+
+	if (!remote_name || *remote_name == '\0')
+		return 0;
+
+	git_buf_printf(&buf, "refs/heads/test:refs/remotes/%s/test", remote_name);
+	error = git_refspec__parse(&refspec, git_buf_cstr(&buf), true);
+
+	git_buf_free(&buf);
+	git_refspec__free(&refspec);
+
+	giterr_clear();
+	return error == 0;
+}
+
+git_refspec *git_remote__matching_refspec(git_remote *remote, const char *refname)
+{
+	git_refspec *spec;
+	size_t i;
+
+	git_vector_foreach(&remote->active_refspecs, i, spec) {
+		if (spec->push)
+			continue;
+
+		if (git_refspec_src_matches(spec, refname))
+			return spec;
+	}
+
+	return NULL;
+}
+
+git_refspec *git_remote__matching_dst_refspec(git_remote *remote, const char *refname)
+{
+	git_refspec *spec;
+	size_t i;
+
+	git_vector_foreach(&remote->active_refspecs, i, spec) {
+		if (spec->push)
+			continue;
+
+		if (git_refspec_dst_matches(spec, refname))
+			return spec;
+	}
+
+	return NULL;
+}
+
+int git_remote_add_fetch(git_repository *repo, const char *remote, const char *refspec)
+{
+	return write_add_refspec(repo, remote, refspec, true);
+}
+
+int git_remote_add_push(git_repository *repo, const char *remote, const char *refspec)
+{
+	return write_add_refspec(repo, remote, refspec, false);
+}
+
+static int set_refspecs(git_remote *remote, git_strarray *array, int push)
+{
+	git_vector *vec = &remote->refspecs;
+	git_refspec *spec;
+	size_t i;
+
+	/* Start by removing any refspecs of the same type */
+	for (i = 0; i < vec->length; i++) {
+		spec = git_vector_get(vec, i);
+		if (spec->push != push)
+			continue;
+
+		git_refspec__free(spec);
+		git__free(spec);
+		git_vector_remove(vec, i);
+		i--;
+	}
+
+	/* And now we add the new ones */
+
+	for (i = 0; i < array->count; i++) {
+		if (add_refspec(remote, array->strings[i], !push) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
+static int copy_refspecs(git_strarray *array, const git_remote *remote, unsigned int push)
+{
+	size_t i;
+	git_vector refspecs;
+	git_refspec *spec;
+	char *dup;
+
+	if (git_vector_init(&refspecs, remote->refspecs.length, NULL) < 0)
+		return -1;
+
+	git_vector_foreach(&remote->refspecs, i, spec) {
+		if (spec->push != push)
+			continue;
+
+		if ((dup = git__strdup(spec->string)) == NULL)
+			goto on_error;
+
+		if (git_vector_insert(&refspecs, dup) < 0) {
+			git__free(dup);
+			goto on_error;
+		}
+	}
+
+	array->strings = (char **)refspecs.contents;
+	array->count = refspecs.length;
+
+	return 0;
+
+on_error:
+	git_vector_free_deep(&refspecs);
+
+	return -1;
+}
+
+int git_remote_get_fetch_refspecs(git_strarray *array, const git_remote *remote)
+{
+	return copy_refspecs(array, remote, false);
+}
+
+int git_remote_get_push_refspecs(git_strarray *array, const git_remote *remote)
+{
+	return copy_refspecs(array, remote, true);
+}
+
+size_t git_remote_refspec_count(const git_remote *remote)
+{
+	return remote->refspecs.length;
+}
+
+const git_refspec *git_remote_get_refspec(const git_remote *remote, size_t n)
+{
+	return git_vector_get(&remote->refspecs, n);
+}
+
+int git_remote_init_callbacks(git_remote_callbacks *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_remote_callbacks, GIT_REMOTE_CALLBACKS_INIT);
+	return 0;
+}
+
+/* asserts a branch.<foo>.remote format */
+static const char *name_offset(size_t *len_out, const char *name)
+{
+	size_t prefix_len;
+	const char *dot;
+
+	prefix_len = strlen("remote.");
+	dot = strchr(name + prefix_len, '.');
+
+	assert(dot);
+
+	*len_out = dot - name - prefix_len;
+	return name + prefix_len;
+}
+
+static int remove_branch_config_related_entries(
+	git_repository *repo,
+	const char *remote_name)
+{
+	int error;
+	git_config *config;
+	git_config_entry *entry;
+	git_config_iterator *iter;
+	git_buf buf = GIT_BUF_INIT;
+
+	if ((error = git_repository_config__weakptr(&config, repo)) < 0)
+		return error;
+
+	if ((error = git_config_iterator_glob_new(&iter, config, "branch\\..+\\.remote")) < 0)
+		return error;
+
+	/* find any branches with us as upstream and remove that config */
+	while ((error = git_config_next(&entry, iter)) == 0) {
+		const char *branch;
+		size_t branch_len;
+
+		if (strcmp(remote_name, entry->value))
+			continue;
+
+		branch = name_offset(&branch_len, entry->name);
+
+		git_buf_clear(&buf);
+		if (git_buf_printf(&buf, "branch.%.*s.merge", (int)branch_len, branch) < 0)
+			break;
+
+		if ((error = git_config_delete_entry(config, git_buf_cstr(&buf))) < 0)
+			break;
+
+		git_buf_clear(&buf);
+		if (git_buf_printf(&buf, "branch.%.*s.remote", (int)branch_len, branch) < 0)
+			break;
+
+		if ((error = git_config_delete_entry(config, git_buf_cstr(&buf))) < 0)
+			break;
+	}
+
+	if (error == GIT_ITEROVER)
+		error = 0;
+
+	git_buf_free(&buf);
+	git_config_iterator_free(iter);
+	return error;
+}
+
+static int remove_refs(git_repository *repo, const git_refspec *spec)
+{
+	git_reference_iterator *iter = NULL;
+	git_vector refs;
+	const char *name;
+	char *dup;
+	int error;
+	size_t i;
+
+	if ((error = git_vector_init(&refs, 8, NULL)) < 0)
+		return error;
+
+	if ((error = git_reference_iterator_new(&iter, repo)) < 0)
+		goto cleanup;
+
+	while ((error = git_reference_next_name(&name, iter)) == 0) {
+		if (!git_refspec_dst_matches(spec, name))
+			continue;
+
+		dup = git__strdup(name);
+		if (!dup) {
+			error = -1;
+			goto cleanup;
+		}
+
+		if ((error = git_vector_insert(&refs, dup)) < 0)
+			goto cleanup;
+	}
+	if (error == GIT_ITEROVER)
+		error = 0;
+	if (error < 0)
+		goto cleanup;
+
+	git_vector_foreach(&refs, i, name) {
+		if ((error = git_reference_remove(repo, name)) < 0)
+			break;
+	}
+
+cleanup:
+	git_reference_iterator_free(iter);
+	git_vector_foreach(&refs, i, dup) {
+		git__free(dup);
+	}
+	git_vector_free(&refs);
+	return error;
+}
+
+static int remove_remote_tracking(git_repository *repo, const char *remote_name)
+{
+	git_remote *remote;
+	int error;
+	size_t i, count;
+
+	/* we want to use what's on the config, regardless of changes to the instance in memory */
+	if ((error = git_remote_lookup(&remote, repo, remote_name)) < 0)
+		return error;
+
+	count = git_remote_refspec_count(remote);
+	for (i = 0; i < count; i++) {
+		const git_refspec *refspec = git_remote_get_refspec(remote, i);
+
+		/* shouldn't ever actually happen */
+		if (refspec == NULL)
+			continue;
+
+		if ((error = remove_refs(repo, refspec)) < 0)
+			break;
+	}
+
+	git_remote_free(remote);
+	return error;
+}
+
+int git_remote_delete(git_repository *repo, const char *name)
+{
+	int error;
+
+	assert(repo && name);
+
+	if ((error = remove_branch_config_related_entries(repo, name)) < 0 ||
+	    (error = remove_remote_tracking(repo, name)) < 0 ||
+	    (error = rename_remote_config_section(repo, name, NULL)) < 0)
+		return error;
+
+	return 0;
+}
+
+int git_remote_default_branch(git_buf *out, git_remote *remote)
+{
+	const git_remote_head **heads;
+	const git_remote_head *guess = NULL;
+	const git_oid *head_id;
+	size_t heads_len, i;
+	int error;
+
+	assert(out);
+
+	if ((error = git_remote_ls(&heads, &heads_len, remote)) < 0)
+		return error;
+
+	if (heads_len == 0)
+		return GIT_ENOTFOUND;
+
+	if (strcmp(heads[0]->name, GIT_HEAD_FILE))
+		return GIT_ENOTFOUND;
+
+	git_buf_sanitize(out);
+	/* the first one must be HEAD so if that has the symref info, we're done */
+	if (heads[0]->symref_target)
+		return git_buf_puts(out, heads[0]->symref_target);
+
+	/*
+	 * If there's no symref information, we have to look over them
+	 * and guess. We return the first match unless the master
+	 * branch is a candidate. Then we return the master branch.
+	 */
+	head_id = &heads[0]->oid;
+
+	for (i = 1; i < heads_len; i++) {
+		if (git_oid_cmp(head_id, &heads[i]->oid))
+			continue;
+
+		if (git__prefixcmp(heads[i]->name, GIT_REFS_HEADS_DIR))
+			continue;
+
+		if (!guess) {
+			guess = heads[i];
+			continue;
+		}
+
+		if (!git__strcmp(GIT_REFS_HEADS_MASTER_FILE, heads[i]->name)) {
+			guess = heads[i];
+			break;
+		}
+	}
+
+	if (!guess)
+		return GIT_ENOTFOUND;
+
+	return git_buf_puts(out, guess->name);
+}
+
+int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const git_push_options *opts)
+{
+	size_t i;
+	int error;
+	git_push *push;
+	git_refspec *spec;
+	const git_remote_callbacks *cbs = NULL;
+
+	assert(remote);
+
+	if (opts)
+		cbs = &opts->callbacks;
+
+	if (!git_remote_connected(remote) &&
+	    (error = git_remote_connect(remote, GIT_DIRECTION_PUSH, cbs)) < 0)
+		goto cleanup;
+
+	free_refspecs(&remote->active_refspecs);
+	if ((error = dwim_refspecs(&remote->active_refspecs, &remote->refspecs, &remote->refs)) < 0)
+		goto cleanup;
+
+	if (remote->push) {
+		git_push_free(remote->push);
+		remote->push = NULL;
+	}
+
+	if ((error = git_push_new(&remote->push, remote)) < 0)
+		return error;
+
+	push = remote->push;
+
+	if (opts && (error = git_push_set_options(push, opts)) < 0)
+		goto cleanup;
+
+	if (refspecs && refspecs->count > 0) {
+		for (i = 0; i < refspecs->count; i++) {
+			if ((error = git_push_add_refspec(push, refspecs->strings[i])) < 0)
+				goto cleanup;
+		}
+	} else {
+		git_vector_foreach(&remote->refspecs, i, spec) {
+			if (!spec->push)
+				continue;
+			if ((error = git_push_add_refspec(push, spec->string)) < 0)
+				goto cleanup;
+		}
+	}
+
+	if ((error = git_push_finish(push, cbs)) < 0)
+		goto cleanup;
+
+	if (cbs && cbs->push_update_reference &&
+	    (error = git_push_status_foreach(push, cbs->push_update_reference, cbs->payload)) < 0)
+		goto cleanup;
+
+cleanup:
+	return error;
+}
+
+int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_push_options *opts)
+{
+	int error;
+	const git_remote_callbacks *cbs = NULL;
+
+	if (opts) {
+		GITERR_CHECK_VERSION(&opts->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks");
+		cbs = &opts->callbacks;
+	}
+
+	assert(remote && refspecs);
+
+	if ((error = git_remote_connect(remote, GIT_DIRECTION_PUSH, cbs)) < 0)
+		return error;
+
+	if ((error = git_remote_upload(remote, refspecs, opts)) < 0)
+		return error;
+
+	error = git_remote_update_tips(remote, cbs, 0, 0, NULL);
+
+	git_remote_disconnect(remote);
+	return error;
+}
+
+#define PREFIX "url"
+#define SUFFIX_FETCH "insteadof"
+#define SUFFIX_PUSH "pushinsteadof"
+
+char *apply_insteadof(git_config *config, const char *url, int direction)
+{
+	size_t match_length, prefix_length, suffix_length;
+	char *replacement = NULL;
+	const char *regexp;
+
+	git_buf result = GIT_BUF_INIT;
+	git_config_entry *entry;
+	git_config_iterator *iter;
+
+	assert(config);
+	assert(url);
+	assert(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH);
+
+	/* Add 1 to prefix/suffix length due to the additional escaped dot */
+	prefix_length = strlen(PREFIX) + 1;
+	if (direction == GIT_DIRECTION_FETCH) {
+		regexp = PREFIX "\\..*\\." SUFFIX_FETCH;
+		suffix_length = strlen(SUFFIX_FETCH) + 1;
+	} else {
+		regexp = PREFIX "\\..*\\." SUFFIX_PUSH;
+		suffix_length = strlen(SUFFIX_PUSH) + 1;
+	}
+
+	if (git_config_iterator_glob_new(&iter, config, regexp) < 0)
+		return NULL;
+
+	match_length = 0;
+	while (git_config_next(&entry, iter) == 0) {
+		size_t n, replacement_length;
+
+		/* Check if entry value is a prefix of URL */
+		if (git__prefixcmp(url, entry->value))
+			continue;
+		/* Check if entry value is longer than previous
+		 * prefixes */
+		if ((n = strlen(entry->value)) <= match_length)
+			continue;
+
+		git__free(replacement);
+		match_length = n;
+
+		/* Cut off prefix and suffix of the value */
+		replacement_length =
+		    strlen(entry->name) - (prefix_length + suffix_length);
+		replacement = git__strndup(entry->name + prefix_length,
+				replacement_length);
+	}
+
+	git_config_iterator_free(iter);
+
+	if (match_length == 0)
+		return git__strdup(url);
+
+	git_buf_printf(&result, "%s%s", replacement, url + match_length);
+
+	git__free(replacement);
+
+	return result.ptr;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/remote.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/remote.h
new file mode 100755
index 0000000..e696997
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/remote.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_remote_h__
+#define INCLUDE_remote_h__
+
+#include "git2/remote.h"
+#include "git2/transport.h"
+#include "git2/sys/transport.h"
+
+#include "refspec.h"
+#include "vector.h"
+
+#define GIT_REMOTE_ORIGIN "origin"
+
+struct git_remote {
+	char *name;
+	char *url;
+	char *pushurl;
+	git_vector refs;
+	git_vector refspecs;
+	git_vector active_refspecs;
+	git_vector passive_refspecs;
+	git_transport *transport;
+	git_repository *repo;
+	git_push *push;
+	git_transfer_progress stats;
+	unsigned int need_pack;
+	git_remote_autotag_option_t download_tags;
+	int prune_refs;
+	int passed_refspecs;
+};
+
+const char* git_remote__urlfordirection(struct git_remote *remote, int direction);
+int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_url);
+
+git_refspec *git_remote__matching_refspec(git_remote *remote, const char *refname);
+git_refspec *git_remote__matching_dst_refspec(git_remote *remote, const char *refname);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/repo_template.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/repo_template.h
new file mode 100755
index 0000000..099279a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/repo_template.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_repo_template_h__
+#define INCLUDE_repo_template_h__
+
+#define GIT_OBJECTS_INFO_DIR GIT_OBJECTS_DIR "info/"
+#define GIT_OBJECTS_PACK_DIR GIT_OBJECTS_DIR "pack/"
+
+#define GIT_HOOKS_DIR "hooks/"
+#define GIT_HOOKS_DIR_MODE 0777
+
+#define GIT_HOOKS_README_FILE GIT_HOOKS_DIR "README.sample"
+#define GIT_HOOKS_README_MODE 0777
+#define GIT_HOOKS_README_CONTENT \
+"#!/bin/sh\n"\
+"#\n"\
+"# Place appropriately named executable hook scripts into this directory\n"\
+"# to intercept various actions that git takes.  See `git help hooks` for\n"\
+"# more information.\n"
+
+#define GIT_INFO_DIR "info/"
+#define GIT_INFO_DIR_MODE 0777
+
+#define GIT_INFO_EXCLUDE_FILE GIT_INFO_DIR "exclude"
+#define GIT_INFO_EXCLUDE_MODE 0666
+#define GIT_INFO_EXCLUDE_CONTENT \
+"# File patterns to ignore; see `git help ignore` for more information.\n"\
+"# Lines that start with '#' are comments.\n"
+
+#define GIT_DESC_FILE "description"
+#define GIT_DESC_MODE 0666
+#define GIT_DESC_CONTENT \
+"Unnamed repository; edit this file 'description' to name the repository.\n"
+
+typedef struct {
+	const char *path;
+	mode_t mode;
+	const char *content;
+} repo_template_item;
+
+static repo_template_item repo_template[] = {
+	{ GIT_OBJECTS_INFO_DIR, GIT_OBJECT_DIR_MODE, NULL }, /* '/objects/info/' */
+	{ GIT_OBJECTS_PACK_DIR, GIT_OBJECT_DIR_MODE, NULL }, /* '/objects/pack/' */
+	{ GIT_REFS_HEADS_DIR, GIT_REFS_DIR_MODE, NULL },     /* '/refs/heads/' */
+	{ GIT_REFS_TAGS_DIR, GIT_REFS_DIR_MODE, NULL },      /* '/refs/tags/' */
+	{ GIT_HOOKS_DIR, GIT_HOOKS_DIR_MODE, NULL },         /* '/hooks/' */
+	{ GIT_INFO_DIR, GIT_INFO_DIR_MODE, NULL },           /* '/info/' */
+	{ GIT_DESC_FILE, GIT_DESC_MODE, GIT_DESC_CONTENT },
+	{ GIT_HOOKS_README_FILE, GIT_HOOKS_README_MODE, GIT_HOOKS_README_CONTENT },
+	{ GIT_INFO_EXCLUDE_FILE, GIT_INFO_EXCLUDE_MODE, GIT_INFO_EXCLUDE_CONTENT },
+	{ NULL, 0, NULL }
+};
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/repository.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/repository.c
new file mode 100755
index 0000000..08f4baa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/repository.c
@@ -0,0 +1,2316 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include <ctype.h>
+
+#include "git2/object.h"
+#include "git2/refdb.h"
+#include "git2/sys/repository.h"
+
+#include "common.h"
+#include "repository.h"
+#include "commit.h"
+#include "tag.h"
+#include "blob.h"
+#include "fileops.h"
+#include "sysdir.h"
+#include "filebuf.h"
+#include "index.h"
+#include "config.h"
+#include "refs.h"
+#include "filter.h"
+#include "odb.h"
+#include "remote.h"
+#include "merge.h"
+#include "diff_driver.h"
+#include "annotated_commit.h"
+
+#ifdef GIT_WIN32
+# include "win32/w32_util.h"
+#endif
+
+static int check_repositoryformatversion(git_config *config);
+
+#define GIT_FILE_CONTENT_PREFIX "gitdir:"
+
+#define GIT_BRANCH_MASTER "master"
+
+#define GIT_REPO_VERSION 0
+
+git_buf git_repository__reserved_names_win32[] = {
+	{ DOT_GIT, 0, CONST_STRLEN(DOT_GIT) },
+	{ GIT_DIR_SHORTNAME, 0, CONST_STRLEN(GIT_DIR_SHORTNAME) }
+};
+size_t git_repository__reserved_names_win32_len = 2;
+
+git_buf git_repository__reserved_names_posix[] = {
+	{ DOT_GIT, 0, CONST_STRLEN(DOT_GIT) },
+};
+size_t git_repository__reserved_names_posix_len = 1;
+
+static void set_odb(git_repository *repo, git_odb *odb)
+{
+	if (odb) {
+		GIT_REFCOUNT_OWN(odb, repo);
+		GIT_REFCOUNT_INC(odb);
+	}
+
+	if ((odb = git__swap(repo->_odb, odb)) != NULL) {
+		GIT_REFCOUNT_OWN(odb, NULL);
+		git_odb_free(odb);
+	}
+}
+
+static void set_refdb(git_repository *repo, git_refdb *refdb)
+{
+	if (refdb) {
+		GIT_REFCOUNT_OWN(refdb, repo);
+		GIT_REFCOUNT_INC(refdb);
+	}
+
+	if ((refdb = git__swap(repo->_refdb, refdb)) != NULL) {
+		GIT_REFCOUNT_OWN(refdb, NULL);
+		git_refdb_free(refdb);
+	}
+}
+
+static void set_config(git_repository *repo, git_config *config)
+{
+	if (config) {
+		GIT_REFCOUNT_OWN(config, repo);
+		GIT_REFCOUNT_INC(config);
+	}
+
+	if ((config = git__swap(repo->_config, config)) != NULL) {
+		GIT_REFCOUNT_OWN(config, NULL);
+		git_config_free(config);
+	}
+
+	git_repository__cvar_cache_clear(repo);
+}
+
+static void set_index(git_repository *repo, git_index *index)
+{
+	if (index) {
+		GIT_REFCOUNT_OWN(index, repo);
+		GIT_REFCOUNT_INC(index);
+	}
+
+	if ((index = git__swap(repo->_index, index)) != NULL) {
+		GIT_REFCOUNT_OWN(index, NULL);
+		git_index_free(index);
+	}
+}
+
+void git_repository__cleanup(git_repository *repo)
+{
+	assert(repo);
+
+	git_cache_clear(&repo->objects);
+	git_attr_cache_flush(repo);
+
+	set_config(repo, NULL);
+	set_index(repo, NULL);
+	set_odb(repo, NULL);
+	set_refdb(repo, NULL);
+}
+
+void git_repository_free(git_repository *repo)
+{
+	size_t i;
+
+	if (repo == NULL)
+		return;
+
+	git_repository__cleanup(repo);
+
+	git_cache_free(&repo->objects);
+
+	git_diff_driver_registry_free(repo->diff_drivers);
+	repo->diff_drivers = NULL;
+
+	for (i = 0; i < repo->reserved_names.size; i++)
+		git_buf_free(git_array_get(repo->reserved_names, i));
+	git_array_clear(repo->reserved_names);
+
+	git__free(repo->path_gitlink);
+	git__free(repo->path_repository);
+	git__free(repo->workdir);
+	git__free(repo->namespace);
+	git__free(repo->ident_name);
+	git__free(repo->ident_email);
+
+	git__memzero(repo, sizeof(*repo));
+	git__free(repo);
+}
+
+/*
+ * Git repository open methods
+ *
+ * Open a repository object from its path
+ */
+static bool valid_repository_path(git_buf *repository_path)
+{
+	/* Check OBJECTS_DIR first, since it will generate the longest path name */
+	if (git_path_contains_dir(repository_path, GIT_OBJECTS_DIR) == false)
+		return false;
+
+	/* Ensure HEAD file exists */
+	if (git_path_contains_file(repository_path, GIT_HEAD_FILE) == false)
+		return false;
+
+	if (git_path_contains_dir(repository_path, GIT_REFS_DIR)  == false)
+		return false;
+
+	return true;
+}
+
+static git_repository *repository_alloc(void)
+{
+	git_repository *repo = git__calloc(1, sizeof(git_repository));
+
+	if (repo == NULL ||
+		git_cache_init(&repo->objects) < 0)
+		goto on_error;
+
+	git_array_init_to_size(repo->reserved_names, 4);
+	if (!repo->reserved_names.ptr)
+		goto on_error;
+
+	/* set all the entries in the cvar cache to `unset` */
+	git_repository__cvar_cache_clear(repo);
+
+	return repo;
+
+on_error:
+	if (repo)
+		git_cache_free(&repo->objects);
+
+	git__free(repo);
+	return NULL;
+}
+
+int git_repository_new(git_repository **out)
+{
+	git_repository *repo;
+
+	*out = repo = repository_alloc();
+	GITERR_CHECK_ALLOC(repo);
+
+	repo->is_bare = 1;
+
+	return 0;
+}
+
+static int load_config_data(git_repository *repo, const git_config *config)
+{
+	int is_bare;
+
+	/* Try to figure out if it's bare, default to non-bare if it's not set */
+	if (git_config_get_bool(&is_bare, config, "core.bare") < 0)
+		repo->is_bare = 0;
+	else
+		repo->is_bare = is_bare;
+
+	return 0;
+}
+
+static int load_workdir(git_repository *repo, git_config *config, git_buf *parent_path)
+{
+	int         error;
+	git_config_entry *ce;
+	git_buf     worktree = GIT_BUF_INIT;
+
+	if (repo->is_bare)
+		return 0;
+
+	if ((error = git_config__lookup_entry(
+			&ce, config, "core.worktree", false)) < 0)
+		return error;
+
+	if (ce && ce->value) {
+		if ((error = git_path_prettify_dir(
+				&worktree, ce->value, repo->path_repository)) < 0)
+			goto cleanup;
+
+		repo->workdir = git_buf_detach(&worktree);
+	}
+	else if (parent_path && git_path_isdir(parent_path->ptr))
+		repo->workdir = git_buf_detach(parent_path);
+	else {
+		if (git_path_dirname_r(&worktree, repo->path_repository) < 0 ||
+		    git_path_to_dir(&worktree) < 0) {
+			error = -1;
+			goto cleanup;
+		}
+
+		repo->workdir = git_buf_detach(&worktree);
+	}
+
+	GITERR_CHECK_ALLOC(repo->workdir);
+cleanup:
+	git_config_entry_free(ce);
+	return error;
+}
+
+/*
+ * This function returns furthest offset into path where a ceiling dir
+ * is found, so we can stop processing the path at that point.
+ *
+ * Note: converting this to use git_bufs instead of GIT_PATH_MAX buffers on
+ * the stack could remove directories name limits, but at the cost of doing
+ * repeated malloc/frees inside the loop below, so let's not do it now.
+ */
+static int find_ceiling_dir_offset(
+	const char *path,
+	const char *ceiling_directories)
+{
+	char buf[GIT_PATH_MAX + 1];
+	char buf2[GIT_PATH_MAX + 1];
+	const char *ceil, *sep;
+	size_t len, max_len = 0, min_len;
+
+	assert(path);
+
+	min_len = (size_t)(git_path_root(path) + 1);
+
+	if (ceiling_directories == NULL || min_len == 0)
+		return (int)min_len;
+
+	for (sep = ceil = ceiling_directories; *sep; ceil = sep + 1) {
+		for (sep = ceil; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++);
+		len = sep - ceil;
+
+		if (len == 0 || len >= sizeof(buf) || git_path_root(ceil) == -1)
+			continue;
+
+		strncpy(buf, ceil, len);
+		buf[len] = '\0';
+
+		if (p_realpath(buf, buf2) == NULL)
+			continue;
+
+		len = strlen(buf2);
+		if (len > 0 && buf2[len-1] == '/')
+			buf[--len] = '\0';
+
+		if (!strncmp(path, buf2, len) &&
+			(path[len] == '/' || !path[len]) &&
+			len > max_len)
+		{
+			max_len = len;
+		}
+	}
+
+	return (int)(max_len <= min_len ? min_len : max_len);
+}
+
+/*
+ * Read the contents of `file_path` and set `path_out` to the repo dir that
+ * it points to.  Before calling, set `path_out` to the base directory that
+ * should be used if the contents of `file_path` are a relative path.
+ */
+static int read_gitfile(git_buf *path_out, const char *file_path)
+{
+	int     error = 0;
+	git_buf file = GIT_BUF_INIT;
+	size_t  prefix_len = strlen(GIT_FILE_CONTENT_PREFIX);
+
+	assert(path_out && file_path);
+
+	if (git_futils_readbuffer(&file, file_path) < 0)
+		return -1;
+
+	git_buf_rtrim(&file);
+	/* apparently on Windows, some people use backslashes in paths */
+	git_path_mkposix(file.ptr);
+
+	if (git_buf_len(&file) <= prefix_len ||
+		memcmp(git_buf_cstr(&file), GIT_FILE_CONTENT_PREFIX, prefix_len) != 0)
+	{
+		giterr_set(GITERR_REPOSITORY,
+			"The `.git` file at '%s' is malformed", file_path);
+		error = -1;
+	}
+	else if ((error = git_path_dirname_r(path_out, file_path)) >= 0) {
+		const char *gitlink = git_buf_cstr(&file) + prefix_len;
+		while (*gitlink && git__isspace(*gitlink)) gitlink++;
+
+		error = git_path_prettify_dir(
+			path_out, gitlink, git_buf_cstr(path_out));
+	}
+
+	git_buf_free(&file);
+	return error;
+}
+
+static int find_repo(
+	git_buf *repo_path,
+	git_buf *parent_path,
+	git_buf *link_path,
+	const char *start_path,
+	uint32_t flags,
+	const char *ceiling_dirs)
+{
+	int error;
+	git_buf path = GIT_BUF_INIT;
+	struct stat st;
+	dev_t initial_device = 0;
+	bool try_with_dot_git = ((flags & GIT_REPOSITORY_OPEN_BARE) != 0);
+	int ceiling_offset;
+
+	git_buf_free(repo_path);
+
+	if ((error = git_path_prettify(&path, start_path, NULL)) < 0)
+		return error;
+
+	ceiling_offset = find_ceiling_dir_offset(path.ptr, ceiling_dirs);
+
+	if (!try_with_dot_git &&
+		(error = git_buf_joinpath(&path, path.ptr, DOT_GIT)) < 0)
+		return error;
+
+	while (!error && !git_buf_len(repo_path)) {
+		if (p_stat(path.ptr, &st) == 0) {
+			/* check that we have not crossed device boundaries */
+			if (initial_device == 0)
+				initial_device = st.st_dev;
+			else if (st.st_dev != initial_device &&
+				(flags & GIT_REPOSITORY_OPEN_CROSS_FS) == 0)
+				break;
+
+			if (S_ISDIR(st.st_mode)) {
+				if (valid_repository_path(&path)) {
+					git_path_to_dir(&path);
+					git_buf_set(repo_path, path.ptr, path.size);
+					break;
+				}
+			}
+			else if (S_ISREG(st.st_mode)) {
+				git_buf repo_link = GIT_BUF_INIT;
+
+				if (!(error = read_gitfile(&repo_link, path.ptr))) {
+					if (valid_repository_path(&repo_link)) {
+						git_buf_swap(repo_path, &repo_link);
+
+						if (link_path)
+							error = git_buf_put(link_path, 
+								path.ptr, path.size);
+					}
+
+					git_buf_free(&repo_link);
+					break;
+				}
+				git_buf_free(&repo_link);
+			}
+		}
+
+		/* move up one directory level */
+		if (git_path_dirname_r(&path, path.ptr) < 0) {
+			error = -1;
+			break;
+		}
+
+		if (try_with_dot_git) {
+			/* if we tried original dir with and without .git AND either hit
+			 * directory ceiling or NO_SEARCH was requested, then be done.
+			 */
+			if (path.ptr[ceiling_offset] == '\0' ||
+				(flags & GIT_REPOSITORY_OPEN_NO_SEARCH) != 0)
+				break;
+			/* otherwise look first for .git item */
+			error = git_buf_joinpath(&path, path.ptr, DOT_GIT);
+		}
+		try_with_dot_git = !try_with_dot_git;
+	}
+
+	if (!error && parent_path && !(flags & GIT_REPOSITORY_OPEN_BARE)) {
+		if (!git_buf_len(repo_path))
+			git_buf_clear(parent_path);
+		else {
+			git_path_dirname_r(parent_path, path.ptr);
+			git_path_to_dir(parent_path);
+		}
+		if (git_buf_oom(parent_path))
+			return -1;
+	}
+
+	git_buf_free(&path);
+
+	if (!git_buf_len(repo_path) && !error) {
+		giterr_set(GITERR_REPOSITORY,
+			"Could not find repository from '%s'", start_path);
+		error = GIT_ENOTFOUND;
+	}
+
+	return error;
+}
+
+int git_repository_open_bare(
+	git_repository **repo_ptr,
+	const char *bare_path)
+{
+	int error;
+	git_buf path = GIT_BUF_INIT;
+	git_repository *repo = NULL;
+
+	if ((error = git_path_prettify_dir(&path, bare_path, NULL)) < 0)
+		return error;
+
+	if (!valid_repository_path(&path)) {
+		git_buf_free(&path);
+		giterr_set(GITERR_REPOSITORY, "Path is not a repository: %s", bare_path);
+		return GIT_ENOTFOUND;
+	}
+
+	repo = repository_alloc();
+	GITERR_CHECK_ALLOC(repo);
+
+	repo->path_repository = git_buf_detach(&path);
+	GITERR_CHECK_ALLOC(repo->path_repository);
+
+	/* of course we're bare! */
+	repo->is_bare = 1;
+	repo->workdir = NULL;
+
+	*repo_ptr = repo;
+	return 0;
+}
+
+int git_repository_open_ext(
+	git_repository **repo_ptr,
+	const char *start_path,
+	unsigned int flags,
+	const char *ceiling_dirs)
+{
+	int error;
+	git_buf path = GIT_BUF_INIT, parent = GIT_BUF_INIT,
+		link_path = GIT_BUF_INIT;
+	git_repository *repo;
+	git_config *config = NULL;
+
+	if (repo_ptr)
+		*repo_ptr = NULL;
+
+	error = find_repo(
+		&path, &parent, &link_path, start_path, flags, ceiling_dirs);
+
+	if (error < 0 || !repo_ptr)
+		return error;
+
+	repo = repository_alloc();
+	GITERR_CHECK_ALLOC(repo);
+
+	repo->path_repository = git_buf_detach(&path);
+	GITERR_CHECK_ALLOC(repo->path_repository);
+
+	if (link_path.size) {
+		repo->path_gitlink = git_buf_detach(&link_path);
+		GITERR_CHECK_ALLOC(repo->path_gitlink);
+	}
+
+	/*
+	 * We'd like to have the config, but git doesn't particularly
+	 * care if it's not there, so we need to deal with that.
+	 */
+
+	error = git_repository_config_snapshot(&config, repo);
+	if (error < 0 && error != GIT_ENOTFOUND)
+		goto cleanup;
+
+	if (config && (error = check_repositoryformatversion(config)) < 0)
+		goto cleanup;
+
+	if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0)
+		repo->is_bare = 1;
+	else {
+
+		if (config &&
+		    ((error = load_config_data(repo, config)) < 0 ||
+		     (error = load_workdir(repo, config, &parent)) < 0))
+			goto cleanup;
+	}
+
+cleanup:
+	git_buf_free(&parent);
+	git_config_free(config);
+
+	if (error < 0)
+		git_repository_free(repo);
+	else
+		*repo_ptr = repo;
+
+	return error;
+}
+
+int git_repository_open(git_repository **repo_out, const char *path)
+{
+	return git_repository_open_ext(
+		repo_out, path, GIT_REPOSITORY_OPEN_NO_SEARCH, NULL);
+}
+
+int git_repository_wrap_odb(git_repository **repo_out, git_odb *odb)
+{
+	git_repository *repo;
+
+	repo = repository_alloc();
+	GITERR_CHECK_ALLOC(repo);
+
+	git_repository_set_odb(repo, odb);
+	*repo_out = repo;
+
+	return 0;
+}
+
+int git_repository_discover(
+	git_buf *out,
+	const char *start_path,
+	int across_fs,
+	const char *ceiling_dirs)
+{
+	uint32_t flags = across_fs ? GIT_REPOSITORY_OPEN_CROSS_FS : 0;
+
+	assert(start_path);
+
+	git_buf_sanitize(out);
+
+	return find_repo(out, NULL, NULL, start_path, flags, ceiling_dirs);
+}
+
+static int load_config(
+	git_config **out,
+	git_repository *repo,
+	const char *global_config_path,
+	const char *xdg_config_path,
+	const char *system_config_path)
+{
+	int error;
+	git_buf config_path = GIT_BUF_INIT;
+	git_config *cfg = NULL;
+
+	assert(repo && out);
+
+	if ((error = git_config_new(&cfg)) < 0)
+		return error;
+
+	error = git_buf_joinpath(
+		&config_path, repo->path_repository, GIT_CONFIG_FILENAME_INREPO);
+	if (error < 0)
+		goto on_error;
+
+	if ((error = git_config_add_file_ondisk(
+			cfg, config_path.ptr, GIT_CONFIG_LEVEL_LOCAL, 0)) < 0 &&
+		error != GIT_ENOTFOUND)
+		goto on_error;
+
+	git_buf_free(&config_path);
+
+	if (global_config_path != NULL &&
+		(error = git_config_add_file_ondisk(
+			cfg, global_config_path, GIT_CONFIG_LEVEL_GLOBAL, 0)) < 0 &&
+		error != GIT_ENOTFOUND)
+		goto on_error;
+
+	if (xdg_config_path != NULL &&
+		(error = git_config_add_file_ondisk(
+			cfg, xdg_config_path, GIT_CONFIG_LEVEL_XDG, 0)) < 0 &&
+		error != GIT_ENOTFOUND)
+		goto on_error;
+
+	if (system_config_path != NULL &&
+		(error = git_config_add_file_ondisk(
+			cfg, system_config_path, GIT_CONFIG_LEVEL_SYSTEM, 0)) < 0 &&
+		error != GIT_ENOTFOUND)
+		goto on_error;
+
+	giterr_clear(); /* clear any lingering ENOTFOUND errors */
+
+	*out = cfg;
+	return 0;
+
+on_error:
+	git_buf_free(&config_path);
+	git_config_free(cfg);
+	*out = NULL;
+	return error;
+}
+
+static const char *path_unless_empty(git_buf *buf)
+{
+	return git_buf_len(buf) > 0 ? git_buf_cstr(buf) : NULL;
+}
+
+int git_repository_config__weakptr(git_config **out, git_repository *repo)
+{
+	int error = 0;
+
+	if (repo->_config == NULL) {
+		git_buf global_buf = GIT_BUF_INIT;
+		git_buf xdg_buf = GIT_BUF_INIT;
+		git_buf system_buf = GIT_BUF_INIT;
+		git_config *config;
+
+		git_config_find_global(&global_buf);
+		git_config_find_xdg(&xdg_buf);
+		git_config_find_system(&system_buf);
+
+		/* If there is no global file, open a backend for it anyway */
+		if (git_buf_len(&global_buf) == 0)
+			git_config__global_location(&global_buf);
+
+		error = load_config(
+			&config, repo,
+			path_unless_empty(&global_buf),
+			path_unless_empty(&xdg_buf),
+			path_unless_empty(&system_buf));
+		if (!error) {
+			GIT_REFCOUNT_OWN(config, repo);
+
+			config = git__compare_and_swap(&repo->_config, NULL, config);
+			if (config != NULL) {
+				GIT_REFCOUNT_OWN(config, NULL);
+				git_config_free(config);
+			}
+		}
+
+		git_buf_free(&global_buf);
+		git_buf_free(&xdg_buf);
+		git_buf_free(&system_buf);
+	}
+
+	*out = repo->_config;
+	return error;
+}
+
+int git_repository_config(git_config **out, git_repository *repo)
+{
+	if (git_repository_config__weakptr(out, repo) < 0)
+		return -1;
+
+	GIT_REFCOUNT_INC(*out);
+	return 0;
+}
+
+int git_repository_config_snapshot(git_config **out, git_repository *repo)
+{
+	int error;
+	git_config *weak;
+
+	if ((error = git_repository_config__weakptr(&weak, repo)) < 0)
+		return error;
+
+	return git_config_snapshot(out, weak);
+}
+
+void git_repository_set_config(git_repository *repo, git_config *config)
+{
+	assert(repo && config);
+	set_config(repo, config);
+}
+
+int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
+{
+	int error = 0;
+
+	assert(repo && out);
+
+	if (repo->_odb == NULL) {
+		git_buf odb_path = GIT_BUF_INIT;
+		git_odb *odb;
+
+		if ((error = git_buf_joinpath(&odb_path, repo->path_repository, GIT_OBJECTS_DIR)) < 0)
+			return error;
+
+		error = git_odb_open(&odb, odb_path.ptr);
+		if (!error) {
+			GIT_REFCOUNT_OWN(odb, repo);
+
+			odb = git__compare_and_swap(&repo->_odb, NULL, odb);
+			if (odb != NULL) {
+				GIT_REFCOUNT_OWN(odb, NULL);
+				git_odb_free(odb);
+			}
+		}
+
+		git_buf_free(&odb_path);
+	}
+
+	*out = repo->_odb;
+	return error;
+}
+
+int git_repository_odb(git_odb **out, git_repository *repo)
+{
+	if (git_repository_odb__weakptr(out, repo) < 0)
+		return -1;
+
+	GIT_REFCOUNT_INC(*out);
+	return 0;
+}
+
+void git_repository_set_odb(git_repository *repo, git_odb *odb)
+{
+	assert(repo && odb);
+	set_odb(repo, odb);
+}
+
+int git_repository_refdb__weakptr(git_refdb **out, git_repository *repo)
+{
+	int error = 0;
+
+	assert(out && repo);
+
+	if (repo->_refdb == NULL) {
+		git_refdb *refdb;
+
+		error = git_refdb_open(&refdb, repo);
+		if (!error) {
+			GIT_REFCOUNT_OWN(refdb, repo);
+
+			refdb = git__compare_and_swap(&repo->_refdb, NULL, refdb);
+			if (refdb != NULL) {
+				GIT_REFCOUNT_OWN(refdb, NULL);
+				git_refdb_free(refdb);
+			}
+		}
+	}
+
+	*out = repo->_refdb;
+	return error;
+}
+
+int git_repository_refdb(git_refdb **out, git_repository *repo)
+{
+	if (git_repository_refdb__weakptr(out, repo) < 0)
+		return -1;
+
+	GIT_REFCOUNT_INC(*out);
+	return 0;
+}
+
+void git_repository_set_refdb(git_repository *repo, git_refdb *refdb)
+{
+	assert(repo && refdb);
+	set_refdb(repo, refdb);
+}
+
+int git_repository_index__weakptr(git_index **out, git_repository *repo)
+{
+	int error = 0;
+
+	assert(out && repo);
+
+	if (repo->_index == NULL) {
+		git_buf index_path = GIT_BUF_INIT;
+		git_index *index;
+
+		if ((error = git_buf_joinpath(&index_path, repo->path_repository, GIT_INDEX_FILE)) < 0)
+			return error;
+
+		error = git_index_open(&index, index_path.ptr);
+		if (!error) {
+			GIT_REFCOUNT_OWN(index, repo);
+
+			index = git__compare_and_swap(&repo->_index, NULL, index);
+			if (index != NULL) {
+				GIT_REFCOUNT_OWN(index, NULL);
+				git_index_free(index);
+			}
+
+			error = git_index_set_caps(repo->_index, GIT_INDEXCAP_FROM_OWNER);
+		}
+
+		git_buf_free(&index_path);
+	}
+
+	*out = repo->_index;
+	return error;
+}
+
+int git_repository_index(git_index **out, git_repository *repo)
+{
+	if (git_repository_index__weakptr(out, repo) < 0)
+		return -1;
+
+	GIT_REFCOUNT_INC(*out);
+	return 0;
+}
+
+void git_repository_set_index(git_repository *repo, git_index *index)
+{
+	assert(repo);
+	set_index(repo, index);
+}
+
+int git_repository_set_namespace(git_repository *repo, const char *namespace)
+{
+	git__free(repo->namespace);
+
+	if (namespace == NULL) {
+		repo->namespace = NULL;
+		return 0;
+	}
+
+	return (repo->namespace = git__strdup(namespace)) ? 0 : -1;
+}
+
+const char *git_repository_get_namespace(git_repository *repo)
+{
+	return repo->namespace;
+}
+
+#ifdef GIT_WIN32
+static int reserved_names_add8dot3(git_repository *repo, const char *path)
+{
+	char *name = git_win32_path_8dot3_name(path);
+	const char *def = GIT_DIR_SHORTNAME;
+	const char *def_dot_git = DOT_GIT;
+	size_t name_len, def_len = CONST_STRLEN(GIT_DIR_SHORTNAME);
+	size_t def_dot_git_len = CONST_STRLEN(DOT_GIT);
+	git_buf *buf;
+
+	if (!name)
+		return 0;
+
+	name_len = strlen(name);
+
+	if ((name_len == def_len && memcmp(name, def, def_len) == 0) || 
+		(name_len == def_dot_git_len && memcmp(name, def_dot_git, def_dot_git_len) == 0)) {
+		git__free(name);
+		return 0;
+	}
+
+	if ((buf = git_array_alloc(repo->reserved_names)) == NULL)
+		return -1;
+
+	git_buf_attach(buf, name, name_len);
+	return true;
+}
+
+bool git_repository__reserved_names(
+	git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs)
+{
+	GIT_UNUSED(include_ntfs);
+
+	if (repo->reserved_names.size == 0) {
+		git_buf *buf;
+		size_t i;
+
+		/* Add the static defaults */
+		for (i = 0; i < git_repository__reserved_names_win32_len; i++) {
+			if ((buf = git_array_alloc(repo->reserved_names)) == NULL)
+				goto on_error;
+
+			buf->ptr = git_repository__reserved_names_win32[i].ptr;
+			buf->size = git_repository__reserved_names_win32[i].size;
+		}
+
+		/* Try to add any repo-specific reserved names */
+		if (!repo->is_bare) {
+			const char *reserved_path = repo->path_gitlink ?
+				repo->path_gitlink : repo->path_repository;
+
+			if (reserved_names_add8dot3(repo, reserved_path) < 0)
+				goto on_error;
+		}
+	}
+
+	*out = repo->reserved_names.ptr;
+	*outlen = repo->reserved_names.size;
+
+	return true;
+
+	/* Always give good defaults, even on OOM */
+on_error:
+	*out = git_repository__reserved_names_win32;
+	*outlen = git_repository__reserved_names_win32_len;
+
+	return false;
+}
+#else
+bool git_repository__reserved_names(
+	git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs)
+{
+	GIT_UNUSED(repo);
+
+	if (include_ntfs) {
+		*out = git_repository__reserved_names_win32;
+		*outlen = git_repository__reserved_names_win32_len;
+	} else {
+		*out = git_repository__reserved_names_posix;
+		*outlen = git_repository__reserved_names_posix_len;
+	}
+
+	return true;
+}
+#endif
+
+static int check_repositoryformatversion(git_config *config)
+{
+	int version, error;
+
+	error = git_config_get_int32(&version, config, "core.repositoryformatversion");
+	/* git ignores this if the config variable isn't there */
+	if (error == GIT_ENOTFOUND)
+		return 0;
+
+	if (error < 0)
+		return -1;
+
+	if (GIT_REPO_VERSION < version) {
+		giterr_set(GITERR_REPOSITORY,
+			"Unsupported repository version %d. Only versions up to %d are supported.",
+			version, GIT_REPO_VERSION);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int repo_init_create_head(const char *git_dir, const char *ref_name)
+{
+	git_buf ref_path = GIT_BUF_INIT;
+	git_filebuf ref = GIT_FILEBUF_INIT;
+	const char *fmt;
+
+	if (git_buf_joinpath(&ref_path, git_dir, GIT_HEAD_FILE) < 0 ||
+		git_filebuf_open(&ref, ref_path.ptr, 0, GIT_REFS_FILE_MODE) < 0)
+		goto fail;
+
+	if (!ref_name)
+		ref_name = GIT_BRANCH_MASTER;
+
+	if (git__prefixcmp(ref_name, GIT_REFS_DIR) == 0)
+		fmt = "ref: %s\n";
+	else
+		fmt = "ref: " GIT_REFS_HEADS_DIR "%s\n";
+
+	if (git_filebuf_printf(&ref, fmt, ref_name) < 0 ||
+		git_filebuf_commit(&ref) < 0)
+		goto fail;
+
+	git_buf_free(&ref_path);
+	return 0;
+
+fail:
+	git_buf_free(&ref_path);
+	git_filebuf_cleanup(&ref);
+	return -1;
+}
+
+static bool is_chmod_supported(const char *file_path)
+{
+	struct stat st1, st2;
+
+	if (p_stat(file_path, &st1) < 0)
+		return false;
+
+	if (p_chmod(file_path, st1.st_mode ^ S_IXUSR) < 0)
+		return false;
+
+	if (p_stat(file_path, &st2) < 0)
+		return false;
+
+	return (st1.st_mode != st2.st_mode);
+}
+
+static bool is_filesystem_case_insensitive(const char *gitdir_path)
+{
+	git_buf path = GIT_BUF_INIT;
+	int is_insensitive = -1;
+
+	if (!git_buf_joinpath(&path, gitdir_path, "CoNfIg"))
+		is_insensitive = git_path_exists(git_buf_cstr(&path));
+
+	git_buf_free(&path);
+	return is_insensitive;
+}
+
+static bool are_symlinks_supported(const char *wd_path)
+{
+	git_buf path = GIT_BUF_INIT;
+	int fd;
+	struct stat st;
+	int symlinks_supported = -1;
+
+	if ((fd = git_futils_mktmp(&path, wd_path, 0666)) < 0 ||
+		p_close(fd) < 0 ||
+		p_unlink(path.ptr) < 0 ||
+		p_symlink("testing", path.ptr) < 0 ||
+		p_lstat(path.ptr, &st) < 0)
+		symlinks_supported = false;
+	else
+		symlinks_supported = (S_ISLNK(st.st_mode) != 0);
+
+	(void)p_unlink(path.ptr);
+	git_buf_free(&path);
+
+	return symlinks_supported;
+}
+
+static int create_empty_file(const char *path, mode_t mode)
+{
+	int fd;
+
+	if ((fd = p_creat(path, mode)) < 0) {
+		giterr_set(GITERR_OS, "Error while creating '%s'", path);
+		return -1;
+	}
+
+	if (p_close(fd) < 0) {
+		giterr_set(GITERR_OS, "Error while closing '%s'", path);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int repo_local_config(
+	git_config **out,
+	git_buf *config_dir,
+	git_repository *repo,
+	const char *repo_dir)
+{
+	int error = 0;
+	git_config *parent;
+	const char *cfg_path;
+
+	if (git_buf_joinpath(config_dir, repo_dir, GIT_CONFIG_FILENAME_INREPO) < 0)
+		return -1;
+	cfg_path = git_buf_cstr(config_dir);
+
+	/* make LOCAL config if missing */
+	if (!git_path_isfile(cfg_path) &&
+		(error = create_empty_file(cfg_path, GIT_CONFIG_FILE_MODE)) < 0)
+		return error;
+
+	/* if no repo, just open that file directly */
+	if (!repo)
+		return git_config_open_ondisk(out, cfg_path);
+
+	/* otherwise, open parent config and get that level */
+	if ((error = git_repository_config__weakptr(&parent, repo)) < 0)
+		return error;
+
+	if (git_config_open_level(out, parent, GIT_CONFIG_LEVEL_LOCAL) < 0) {
+		giterr_clear();
+
+		if (!(error = git_config_add_file_ondisk(
+				parent, cfg_path, GIT_CONFIG_LEVEL_LOCAL, false)))
+			error = git_config_open_level(out, parent, GIT_CONFIG_LEVEL_LOCAL);
+	}
+
+	git_config_free(parent);
+
+	return error;
+}
+
+static int repo_init_fs_configs(
+	git_config *cfg,
+	const char *cfg_path,
+	const char *repo_dir,
+	const char *work_dir,
+	bool update_ignorecase)
+{
+	int error = 0;
+
+	if (!work_dir)
+		work_dir = repo_dir;
+
+	if ((error = git_config_set_bool(
+			cfg, "core.filemode", is_chmod_supported(cfg_path))) < 0)
+		return error;
+
+	if (!are_symlinks_supported(work_dir)) {
+		if ((error = git_config_set_bool(cfg, "core.symlinks", false)) < 0)
+			return error;
+	} else if (git_config_delete_entry(cfg, "core.symlinks") < 0)
+		giterr_clear();
+
+	if (update_ignorecase) {
+		if (is_filesystem_case_insensitive(repo_dir)) {
+			if ((error = git_config_set_bool(cfg, "core.ignorecase", true)) < 0)
+				return error;
+		} else if (git_config_delete_entry(cfg, "core.ignorecase") < 0)
+			giterr_clear();
+	}
+
+#ifdef GIT_USE_ICONV
+	if ((error = git_config_set_bool(
+			cfg, "core.precomposeunicode",
+			git_path_does_fs_decompose_unicode(work_dir))) < 0)
+		return error;
+	/* on non-iconv platforms, don't even set core.precomposeunicode */
+#endif
+
+	return 0;
+}
+
+static int repo_init_config(
+	const char *repo_dir,
+	const char *work_dir,
+	uint32_t flags,
+	uint32_t mode)
+{
+	int error = 0;
+	git_buf cfg_path = GIT_BUF_INIT, worktree_path = GIT_BUF_INIT;
+	git_config *config = NULL;
+	bool is_bare = ((flags & GIT_REPOSITORY_INIT_BARE) != 0);
+	bool is_reinit = ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0);
+
+	if ((error = repo_local_config(&config, &cfg_path, NULL, repo_dir)) < 0)
+		goto cleanup;
+
+	if (is_reinit && (error = check_repositoryformatversion(config)) < 0)
+		goto cleanup;
+
+#define SET_REPO_CONFIG(TYPE, NAME, VAL) do { \
+	if ((error = git_config_set_##TYPE(config, NAME, VAL)) < 0) \
+		goto cleanup; } while (0)
+
+	SET_REPO_CONFIG(bool, "core.bare", is_bare);
+	SET_REPO_CONFIG(int32, "core.repositoryformatversion", GIT_REPO_VERSION);
+
+	if ((error = repo_init_fs_configs(
+			config, cfg_path.ptr, repo_dir, work_dir, !is_reinit)) < 0)
+		goto cleanup;
+
+	if (!is_bare) {
+		SET_REPO_CONFIG(bool, "core.logallrefupdates", true);
+
+		if (!(flags & GIT_REPOSITORY_INIT__NATURAL_WD)) {
+			if ((error = git_buf_sets(&worktree_path, work_dir)) < 0)
+				goto cleanup;
+
+			if ((flags & GIT_REPOSITORY_INIT_RELATIVE_GITLINK))
+				if ((error = git_path_make_relative(&worktree_path, repo_dir)) < 0)
+					goto cleanup;
+
+			SET_REPO_CONFIG(string, "core.worktree", worktree_path.ptr);
+		} else if (is_reinit) {
+			if (git_config_delete_entry(config, "core.worktree") < 0)
+				giterr_clear();
+		}
+	}
+
+	if (mode == GIT_REPOSITORY_INIT_SHARED_GROUP) {
+		SET_REPO_CONFIG(int32, "core.sharedrepository", 1);
+		SET_REPO_CONFIG(bool, "receive.denyNonFastforwards", true);
+	}
+	else if (mode == GIT_REPOSITORY_INIT_SHARED_ALL) {
+		SET_REPO_CONFIG(int32, "core.sharedrepository", 2);
+		SET_REPO_CONFIG(bool, "receive.denyNonFastforwards", true);
+	}
+
+cleanup:
+	git_buf_free(&cfg_path);
+	git_buf_free(&worktree_path);
+	git_config_free(config);
+
+	return error;
+}
+
+static int repo_reinit_submodule_fs(git_submodule *sm, const char *n, void *p)
+{
+	git_repository *smrepo = NULL;
+	GIT_UNUSED(n); GIT_UNUSED(p);
+
+	if (git_submodule_open(&smrepo, sm) < 0 ||
+		git_repository_reinit_filesystem(smrepo, true) < 0)
+		giterr_clear();
+	git_repository_free(smrepo);
+
+	return 0;
+}
+
+int git_repository_reinit_filesystem(git_repository *repo, int recurse)
+{
+	int error = 0;
+	git_buf path = GIT_BUF_INIT;
+	git_config *config = NULL;
+	const char *repo_dir = git_repository_path(repo);
+
+	if (!(error = repo_local_config(&config, &path, repo, repo_dir)))
+		error = repo_init_fs_configs(
+			config, path.ptr, repo_dir, git_repository_workdir(repo), true);
+
+	git_config_free(config);
+	git_buf_free(&path);
+
+	git_repository__cvar_cache_clear(repo);
+
+	if (!repo->is_bare && recurse)
+		(void)git_submodule_foreach(repo, repo_reinit_submodule_fs, NULL);
+
+	return error;
+}
+
+static int repo_write_template(
+	const char *git_dir,
+	bool allow_overwrite,
+	const char *file,
+	mode_t mode,
+	bool hidden,
+	const char *content)
+{
+	git_buf path = GIT_BUF_INIT;
+	int fd, error = 0, flags;
+
+	if (git_buf_joinpath(&path, git_dir, file) < 0)
+		return -1;
+
+	if (allow_overwrite)
+		flags = O_WRONLY | O_CREAT | O_TRUNC;
+	else
+		flags = O_WRONLY | O_CREAT | O_EXCL;
+
+	fd = p_open(git_buf_cstr(&path), flags, mode);
+
+	if (fd >= 0) {
+		error = p_write(fd, content, strlen(content));
+
+		p_close(fd);
+	}
+	else if (errno != EEXIST)
+		error = fd;
+
+#ifdef GIT_WIN32
+	if (!error && hidden) {
+		if (git_win32__sethidden(path.ptr) < 0)
+			error = -1;
+	}
+#else
+	GIT_UNUSED(hidden);
+#endif
+
+	git_buf_free(&path);
+
+	if (error)
+		giterr_set(GITERR_OS,
+			"Failed to initialize repository with template '%s'", file);
+
+	return error;
+}
+
+static int repo_write_gitlink(
+	const char *in_dir, const char *to_repo, bool use_relative_path)
+{
+	int error;
+	git_buf buf = GIT_BUF_INIT;
+	git_buf path_to_repo = GIT_BUF_INIT;
+	struct stat st;
+
+	git_path_dirname_r(&buf, to_repo);
+	git_path_to_dir(&buf);
+	if (git_buf_oom(&buf))
+		return -1;
+
+	/* don't write gitlink to natural workdir */
+	if (git__suffixcmp(to_repo, "/" DOT_GIT "/") == 0 &&
+		strcmp(in_dir, buf.ptr) == 0)
+	{
+		error = GIT_PASSTHROUGH;
+		goto cleanup;
+	}
+
+	if ((error = git_buf_joinpath(&buf, in_dir, DOT_GIT)) < 0)
+		goto cleanup;
+
+	if (!p_stat(buf.ptr, &st) && !S_ISREG(st.st_mode)) {
+		giterr_set(GITERR_REPOSITORY,
+			"Cannot overwrite gitlink file into path '%s'", in_dir);
+		error = GIT_EEXISTS;
+		goto cleanup;
+	}
+
+	git_buf_clear(&buf);
+
+	error = git_buf_sets(&path_to_repo, to_repo);
+
+	if (!error && use_relative_path)
+		error = git_path_make_relative(&path_to_repo, in_dir);
+
+	if (!error)
+		error = git_buf_join(&buf, ' ', GIT_FILE_CONTENT_PREFIX, path_to_repo.ptr);
+
+	if (!error)
+		error = repo_write_template(in_dir, true, DOT_GIT, 0666, true, buf.ptr);
+
+cleanup:
+	git_buf_free(&buf);
+	git_buf_free(&path_to_repo);
+	return error;
+}
+
+static mode_t pick_dir_mode(git_repository_init_options *opts)
+{
+	if (opts->mode == GIT_REPOSITORY_INIT_SHARED_UMASK)
+		return 0777;
+	if (opts->mode == GIT_REPOSITORY_INIT_SHARED_GROUP)
+		return (0775 | S_ISGID);
+	if (opts->mode == GIT_REPOSITORY_INIT_SHARED_ALL)
+		return (0777 | S_ISGID);
+	return opts->mode;
+}
+
+#include "repo_template.h"
+
+static int repo_init_structure(
+	const char *repo_dir,
+	const char *work_dir,
+	git_repository_init_options *opts)
+{
+	int error = 0;
+	repo_template_item *tpl;
+	bool external_tpl =
+		((opts->flags & GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE) != 0);
+	mode_t dmode = pick_dir_mode(opts);
+	bool chmod = opts->mode != GIT_REPOSITORY_INIT_SHARED_UMASK;
+
+	/* Hide the ".git" directory */
+#ifdef GIT_WIN32
+	if ((opts->flags & GIT_REPOSITORY_INIT__HAS_DOTGIT) != 0) {
+		if (git_win32__sethidden(repo_dir) < 0) {
+			giterr_set(GITERR_OS,
+				"Failed to mark Git repository folder as hidden");
+			return -1;
+		}
+	}
+#endif
+
+	/* Create the .git gitlink if appropriate */
+	if ((opts->flags & GIT_REPOSITORY_INIT_BARE) == 0 &&
+		(opts->flags & GIT_REPOSITORY_INIT__NATURAL_WD) == 0)
+	{
+		if (repo_write_gitlink(work_dir, repo_dir, opts->flags & GIT_REPOSITORY_INIT_RELATIVE_GITLINK) < 0)
+			return -1;
+	}
+
+	/* Copy external template if requested */
+	if (external_tpl) {
+		git_config *cfg = NULL;
+		const char *tdir = NULL;
+		bool default_template = false;
+		git_buf template_buf = GIT_BUF_INIT;
+
+		if (opts->template_path)
+			tdir = opts->template_path;
+		else if ((error = git_config_open_default(&cfg)) >= 0) {
+			if (!git_config_get_path(&template_buf, cfg, "init.templatedir"))
+				tdir = template_buf.ptr;
+			giterr_clear();
+		}
+
+		if (!tdir) {
+			if (!(error = git_sysdir_find_template_dir(&template_buf)))
+				tdir = template_buf.ptr;
+			default_template = true;
+		}
+
+		if (tdir) {
+			uint32_t cpflags = GIT_CPDIR_COPY_SYMLINKS | GIT_CPDIR_SIMPLE_TO_MODE;
+			if (opts->mode != GIT_REPOSITORY_INIT_SHARED_UMASK)
+					cpflags |= GIT_CPDIR_CHMOD_DIRS;
+			error = git_futils_cp_r(tdir, repo_dir, cpflags, dmode);
+		}
+
+		git_buf_free(&template_buf);
+		git_config_free(cfg);
+
+		if (error < 0) {
+			if (!default_template)
+				return error;
+
+			/* if template was default, ignore error and use internal */
+			giterr_clear();
+			external_tpl = false;
+			error = 0;
+		}
+	}
+
+	/* Copy internal template
+	 * - always ensure existence of dirs
+	 * - only create files if no external template was specified
+	 */
+	for (tpl = repo_template; !error && tpl->path; ++tpl) {
+		if (!tpl->content) {
+			uint32_t mkdir_flags = GIT_MKDIR_PATH;
+			if (chmod)
+				mkdir_flags |= GIT_MKDIR_CHMOD;
+
+			error = git_futils_mkdir(
+				tpl->path, repo_dir, dmode, mkdir_flags);
+		}
+		else if (!external_tpl) {
+			const char *content = tpl->content;
+
+			if (opts->description && strcmp(tpl->path, GIT_DESC_FILE) == 0)
+				content = opts->description;
+
+			error = repo_write_template(
+				repo_dir, false, tpl->path, tpl->mode, false, content);
+		}
+	}
+
+	return error;
+}
+
+static int mkdir_parent(git_buf *buf, uint32_t mode, bool skip2)
+{
+	/* When making parent directories during repository initialization
+	 * don't try to set gid or grant world write access
+	 */
+	return git_futils_mkdir(
+		buf->ptr, NULL, mode & ~(S_ISGID | 0002),
+		GIT_MKDIR_PATH | GIT_MKDIR_VERIFY_DIR |
+		(skip2 ? GIT_MKDIR_SKIP_LAST2 : GIT_MKDIR_SKIP_LAST));
+}
+
+static int repo_init_directories(
+	git_buf *repo_path,
+	git_buf *wd_path,
+	const char *given_repo,
+	git_repository_init_options *opts)
+{
+	int error = 0;
+	bool is_bare, add_dotgit, has_dotgit, natural_wd;
+	mode_t dirmode;
+
+	/* There are three possible rules for what we are allowed to create:
+	 * - MKPATH means anything we need
+	 * - MKDIR means just the .git directory and its parent and the workdir
+	 * - Neither means only the .git directory can be created
+	 *
+	 * There are 5 "segments" of path that we might need to deal with:
+	 * 1. The .git directory
+	 * 2. The parent of the .git directory
+	 * 3. Everything above the parent of the .git directory
+	 * 4. The working directory (often the same as #2)
+	 * 5. Everything above the working directory (often the same as #3)
+	 *
+	 * For all directories created, we start with the init_mode value for
+	 * permissions and then strip off bits in some cases:
+	 *
+	 * For MKPATH, we create #3 (and #5) paths without S_ISGID or S_IWOTH
+	 * For MKPATH and MKDIR, we create #2 (and #4) without S_ISGID
+	 * For all rules, we create #1 using the untouched init_mode
+	 */
+
+	/* set up repo path */
+
+	is_bare = ((opts->flags & GIT_REPOSITORY_INIT_BARE) != 0);
+
+	add_dotgit =
+		(opts->flags & GIT_REPOSITORY_INIT_NO_DOTGIT_DIR) == 0 &&
+		!is_bare &&
+		git__suffixcmp(given_repo, "/" DOT_GIT) != 0 &&
+		git__suffixcmp(given_repo, "/" GIT_DIR) != 0;
+
+	if (git_buf_joinpath(repo_path, given_repo, add_dotgit ? GIT_DIR : "") < 0)
+		return -1;
+
+	has_dotgit = (git__suffixcmp(repo_path->ptr, "/" GIT_DIR) == 0);
+	if (has_dotgit)
+		opts->flags |= GIT_REPOSITORY_INIT__HAS_DOTGIT;
+
+	/* set up workdir path */
+
+	if (!is_bare) {
+		if (opts->workdir_path) {
+			if (git_path_join_unrooted(
+					wd_path, opts->workdir_path, repo_path->ptr, NULL) < 0)
+				return -1;
+		} else if (has_dotgit) {
+			if (git_path_dirname_r(wd_path, repo_path->ptr) < 0)
+				return -1;
+		} else {
+			giterr_set(GITERR_REPOSITORY, "Cannot pick working directory"
+				" for non-bare repository that isn't a '.git' directory");
+			return -1;
+		}
+
+		if (git_path_to_dir(wd_path) < 0)
+			return -1;
+	} else {
+		git_buf_clear(wd_path);
+	}
+
+	natural_wd =
+		has_dotgit &&
+		wd_path->size > 0 &&
+		wd_path->size + strlen(GIT_DIR) == repo_path->size &&
+		memcmp(repo_path->ptr, wd_path->ptr, wd_path->size) == 0;
+	if (natural_wd)
+		opts->flags |= GIT_REPOSITORY_INIT__NATURAL_WD;
+
+	/* create directories as needed / requested */
+
+	dirmode = pick_dir_mode(opts);
+
+	if ((opts->flags & GIT_REPOSITORY_INIT_MKPATH) != 0) {
+		/* create path #5 */
+		if (wd_path->size > 0 &&
+			(error = mkdir_parent(wd_path, dirmode, false)) < 0)
+			return error;
+
+		/* create path #3 (if not the same as #5) */
+		if (!natural_wd &&
+			(error = mkdir_parent(repo_path, dirmode, has_dotgit)) < 0)
+			return error;
+	}
+
+	if ((opts->flags & GIT_REPOSITORY_INIT_MKDIR) != 0 ||
+		(opts->flags & GIT_REPOSITORY_INIT_MKPATH) != 0)
+	{
+		/* create path #4 */
+		if (wd_path->size > 0 &&
+			(error = git_futils_mkdir(
+				wd_path->ptr, NULL, dirmode & ~S_ISGID,
+				GIT_MKDIR_VERIFY_DIR)) < 0)
+			return error;
+
+		/* create path #2 (if not the same as #4) */
+		if (!natural_wd &&
+			(error = git_futils_mkdir(
+				repo_path->ptr, NULL, dirmode & ~S_ISGID,
+				GIT_MKDIR_VERIFY_DIR | GIT_MKDIR_SKIP_LAST)) < 0)
+			return error;
+	}
+
+	if ((opts->flags & GIT_REPOSITORY_INIT_MKDIR) != 0 ||
+		(opts->flags & GIT_REPOSITORY_INIT_MKPATH) != 0 ||
+		has_dotgit)
+	{
+		/* create path #1 */
+		error = git_futils_mkdir(repo_path->ptr, NULL, dirmode,
+			GIT_MKDIR_VERIFY_DIR | ((dirmode & S_ISGID) ? GIT_MKDIR_CHMOD : 0));
+	}
+
+	/* prettify both directories now that they are created */
+
+	if (!error) {
+		error = git_path_prettify_dir(repo_path, repo_path->ptr, NULL);
+
+		if (!error && wd_path->size > 0)
+			error = git_path_prettify_dir(wd_path, wd_path->ptr, NULL);
+	}
+
+	return error;
+}
+
+static int repo_init_create_origin(git_repository *repo, const char *url)
+{
+	int error;
+	git_remote *remote;
+
+	if (!(error = git_remote_create(&remote, repo, GIT_REMOTE_ORIGIN, url))) {
+		git_remote_free(remote);
+	}
+
+	return error;
+}
+
+int git_repository_init(
+	git_repository **repo_out, const char *path, unsigned is_bare)
+{
+	git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
+
+	opts.flags = GIT_REPOSITORY_INIT_MKPATH; /* don't love this default */
+	if (is_bare)
+		opts.flags |= GIT_REPOSITORY_INIT_BARE;
+
+	return git_repository_init_ext(repo_out, path, &opts);
+}
+
+int git_repository_init_ext(
+	git_repository **out,
+	const char *given_repo,
+	git_repository_init_options *opts)
+{
+	int error;
+	git_buf repo_path = GIT_BUF_INIT, wd_path = GIT_BUF_INIT;
+	const char *wd;
+
+	assert(out && given_repo && opts);
+
+	GITERR_CHECK_VERSION(opts, GIT_REPOSITORY_INIT_OPTIONS_VERSION, "git_repository_init_options");
+
+	error = repo_init_directories(&repo_path, &wd_path, given_repo, opts);
+	if (error < 0)
+		goto cleanup;
+
+	wd = (opts->flags & GIT_REPOSITORY_INIT_BARE) ? NULL : git_buf_cstr(&wd_path);
+	if (valid_repository_path(&repo_path)) {
+
+		if ((opts->flags & GIT_REPOSITORY_INIT_NO_REINIT) != 0) {
+			giterr_set(GITERR_REPOSITORY,
+				"Attempt to reinitialize '%s'", given_repo);
+			error = GIT_EEXISTS;
+			goto cleanup;
+		}
+
+		opts->flags |= GIT_REPOSITORY_INIT__IS_REINIT;
+
+		error = repo_init_config(
+			repo_path.ptr, wd, opts->flags, opts->mode);
+
+		/* TODO: reinitialize the templates */
+	}
+	else {
+		if (!(error = repo_init_structure(
+				repo_path.ptr, wd, opts)) &&
+			!(error = repo_init_config(
+				repo_path.ptr, wd, opts->flags, opts->mode)))
+			error = repo_init_create_head(
+				repo_path.ptr, opts->initial_head);
+	}
+	if (error < 0)
+		goto cleanup;
+
+	error = git_repository_open(out, repo_path.ptr);
+
+	if (!error && opts->origin_url)
+		error = repo_init_create_origin(*out, opts->origin_url);
+
+cleanup:
+	git_buf_free(&repo_path);
+	git_buf_free(&wd_path);
+
+	return error;
+}
+
+int git_repository_head_detached(git_repository *repo)
+{
+	git_reference *ref;
+	git_odb *odb = NULL;
+	int exists;
+
+	if (git_repository_odb__weakptr(&odb, repo) < 0)
+		return -1;
+
+	if (git_reference_lookup(&ref, repo, GIT_HEAD_FILE) < 0)
+		return -1;
+
+	if (git_reference_type(ref) == GIT_REF_SYMBOLIC) {
+		git_reference_free(ref);
+		return 0;
+	}
+
+	exists = git_odb_exists(odb, git_reference_target(ref));
+
+	git_reference_free(ref);
+	return exists;
+}
+
+int git_repository_head(git_reference **head_out, git_repository *repo)
+{
+	git_reference *head;
+	int error;
+
+	if ((error = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0)
+		return error;
+
+	if (git_reference_type(head) == GIT_REF_OID) {
+		*head_out = head;
+		return 0;
+	}
+
+	error = git_reference_lookup_resolved(head_out, repo, git_reference_symbolic_target(head), -1);
+	git_reference_free(head);
+
+	return error == GIT_ENOTFOUND ? GIT_EUNBORNBRANCH : error;
+}
+
+int git_repository_head_unborn(git_repository *repo)
+{
+	git_reference *ref = NULL;
+	int error;
+
+	error = git_repository_head(&ref, repo);
+	git_reference_free(ref);
+
+	if (error == GIT_EUNBORNBRANCH) {
+		giterr_clear();
+		return 1;
+	}
+
+	if (error < 0)
+		return -1;
+
+	return 0;
+}
+
+static int at_least_one_cb(const char *refname, void *payload)
+{
+	GIT_UNUSED(refname);
+	GIT_UNUSED(payload);
+	return GIT_PASSTHROUGH;
+}
+
+static int repo_contains_no_reference(git_repository *repo)
+{
+	int error = git_reference_foreach_name(repo, &at_least_one_cb, NULL);
+
+	if (error == GIT_PASSTHROUGH)
+		return 0;
+
+	if (!error)
+		return 1;
+
+	return error;
+}
+
+int git_repository_is_empty(git_repository *repo)
+{
+	git_reference *head = NULL;
+	int is_empty = 0;
+
+	if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0)
+		return -1;
+
+	if (git_reference_type(head) == GIT_REF_SYMBOLIC)
+		is_empty =
+			(strcmp(git_reference_symbolic_target(head),
+					GIT_REFS_HEADS_DIR "master") == 0) &&
+			repo_contains_no_reference(repo);
+
+	git_reference_free(head);
+
+	return is_empty;
+}
+
+const char *git_repository_path(git_repository *repo)
+{
+	assert(repo);
+	return repo->path_repository;
+}
+
+const char *git_repository_workdir(git_repository *repo)
+{
+	assert(repo);
+
+	if (repo->is_bare)
+		return NULL;
+
+	return repo->workdir;
+}
+
+int git_repository_set_workdir(
+	git_repository *repo, const char *workdir, int update_gitlink)
+{
+	int error = 0;
+	git_buf path = GIT_BUF_INIT;
+
+	assert(repo && workdir);
+
+	if (git_path_prettify_dir(&path, workdir, NULL) < 0)
+		return -1;
+
+	if (repo->workdir && strcmp(repo->workdir, path.ptr) == 0)
+		return 0;
+
+	if (update_gitlink) {
+		git_config *config;
+
+		if (git_repository_config__weakptr(&config, repo) < 0)
+			return -1;
+
+		error = repo_write_gitlink(path.ptr, git_repository_path(repo), false);
+
+		/* passthrough error means gitlink is unnecessary */
+		if (error == GIT_PASSTHROUGH)
+			error = git_config_delete_entry(config, "core.worktree");
+		else if (!error)
+			error = git_config_set_string(config, "core.worktree", path.ptr);
+
+		if (!error)
+			error = git_config_set_bool(config, "core.bare", false);
+	}
+
+	if (!error) {
+		char *old_workdir = repo->workdir;
+
+		repo->workdir = git_buf_detach(&path);
+		repo->is_bare = 0;
+
+		git__free(old_workdir);
+	}
+
+	return error;
+}
+
+int git_repository_is_bare(git_repository *repo)
+{
+	assert(repo);
+	return repo->is_bare;
+}
+
+int git_repository_set_bare(git_repository *repo)
+{
+	int error;
+	git_config *config;
+
+	assert(repo);
+
+	if (repo->is_bare)
+		return 0;
+
+	if ((error = git_repository_config__weakptr(&config, repo)) < 0)
+		return error;
+
+	if ((error = git_config_set_bool(config, "core.bare", true)) < 0)
+		return error;
+
+	if ((error = git_config__update_entry(config, "core.worktree", NULL, true, true)) < 0)
+		return error;
+
+	git__free(repo->workdir);
+	repo->workdir = NULL;
+	repo->is_bare = 1;
+
+	return 0;
+}
+
+int git_repository_head_tree(git_tree **tree, git_repository *repo)
+{
+	git_reference *head;
+	git_object *obj;
+	int error;
+
+	if ((error = git_repository_head(&head, repo)) < 0)
+		return error;
+
+	if ((error = git_reference_peel(&obj, head, GIT_OBJ_TREE)) < 0)
+		goto cleanup;
+
+	*tree = (git_tree *)obj;
+
+cleanup:
+	git_reference_free(head);
+	return error;
+}
+
+int git_repository__set_orig_head(git_repository *repo, const git_oid *orig_head)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	git_buf file_path = GIT_BUF_INIT;
+	char orig_head_str[GIT_OID_HEXSZ];
+	int error = 0;
+
+	git_oid_fmt(orig_head_str, orig_head);
+
+	if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_ORIG_HEAD_FILE)) == 0 &&
+		(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_MERGE_FILE_MODE)) == 0 &&
+		(error = git_filebuf_printf(&file, "%.*s\n", GIT_OID_HEXSZ, orig_head_str)) == 0)
+		error = git_filebuf_commit(&file);
+
+	if (error < 0)
+		git_filebuf_cleanup(&file);
+
+	git_buf_free(&file_path);
+
+	return error;
+}
+
+int git_repository_message(git_buf *out, git_repository *repo)
+{
+	git_buf path = GIT_BUF_INIT;
+	struct stat st;
+	int error;
+
+	git_buf_sanitize(out);
+
+	if (git_buf_joinpath(&path, repo->path_repository, GIT_MERGE_MSG_FILE) < 0)
+		return -1;
+
+	if ((error = p_stat(git_buf_cstr(&path), &st)) < 0) {
+		if (errno == ENOENT)
+			error = GIT_ENOTFOUND;
+		giterr_set(GITERR_OS, "Could not access message file");
+	} else {
+		error = git_futils_readbuffer(out, git_buf_cstr(&path));
+	}
+
+	git_buf_free(&path);
+
+	return error;
+}
+
+int git_repository_message_remove(git_repository *repo)
+{
+	git_buf path = GIT_BUF_INIT;
+	int error;
+
+	if (git_buf_joinpath(&path, repo->path_repository, GIT_MERGE_MSG_FILE) < 0)
+		return -1;
+
+	error = p_unlink(git_buf_cstr(&path));
+	git_buf_free(&path);
+
+	return error;
+}
+
+int git_repository_hashfile(
+	git_oid *out,
+	git_repository *repo,
+	const char *path,
+	git_otype type,
+	const char *as_path)
+{
+	int error;
+	git_filter_list *fl = NULL;
+	git_file fd = -1;
+	git_off_t len;
+	git_buf full_path = GIT_BUF_INIT;
+
+	assert(out && path && repo); /* as_path can be NULL */
+
+	/* At some point, it would be nice if repo could be NULL to just
+	 * apply filter rules defined in system and global files, but for
+	 * now that is not possible because git_filters_load() needs it.
+	 */
+
+	error = git_path_join_unrooted(
+		&full_path, path, git_repository_workdir(repo), NULL);
+	if (error < 0)
+		return error;
+
+	if (!as_path)
+		as_path = path;
+
+	/* passing empty string for "as_path" indicated --no-filters */
+	if (strlen(as_path) > 0) {
+		error = git_filter_list_load(
+			&fl, repo, NULL, as_path,
+			GIT_FILTER_TO_ODB, GIT_FILTER_DEFAULT);
+		if (error < 0)
+			return error;
+	} else {
+		error = 0;
+	}
+
+	/* at this point, error is a count of the number of loaded filters */
+
+	fd = git_futils_open_ro(full_path.ptr);
+	if (fd < 0) {
+		error = fd;
+		goto cleanup;
+	}
+
+	len = git_futils_filesize(fd);
+	if (len < 0) {
+		error = (int)len;
+		goto cleanup;
+	}
+
+	if (!git__is_sizet(len)) {
+		giterr_set(GITERR_OS, "File size overflow for 32-bit systems");
+		error = -1;
+		goto cleanup;
+	}
+
+	error = git_odb__hashfd_filtered(out, fd, (size_t)len, type, fl);
+
+cleanup:
+	if (fd >= 0)
+		p_close(fd);
+	git_filter_list_free(fl);
+	git_buf_free(&full_path);
+
+	return error;
+}
+
+static int checkout_message(git_buf *out, git_reference *old, const char *new)
+{
+	git_buf_puts(out, "checkout: moving from ");
+
+	if (git_reference_type(old) == GIT_REF_SYMBOLIC)
+		git_buf_puts(out, git_reference__shorthand(git_reference_symbolic_target(old)));
+	else
+		git_buf_puts(out, git_oid_tostr_s(git_reference_target(old)));
+
+	git_buf_puts(out, " to ");
+
+	if (git_reference__is_branch(new))
+		git_buf_puts(out, git_reference__shorthand(new));
+	else
+		git_buf_puts(out, new);
+
+	if (git_buf_oom(out))
+		return -1;
+
+	return 0;
+}
+
+int git_repository_set_head(
+	git_repository* repo,
+	const char* refname)
+{
+	git_reference *ref = NULL, *current = NULL, *new_head = NULL;
+	git_buf log_message = GIT_BUF_INIT;
+	int error;
+
+	assert(repo && refname);
+
+	if ((error = git_reference_lookup(&current, repo, GIT_HEAD_FILE)) < 0)
+		return error;
+
+	if ((error = checkout_message(&log_message, current, refname)) < 0)
+		goto cleanup;
+
+	error = git_reference_lookup(&ref, repo, refname);
+	if (error < 0 && error != GIT_ENOTFOUND)
+		goto cleanup;
+
+	if (!error) {
+		if (git_reference_is_branch(ref)) {
+			error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE,
+					git_reference_name(ref), true, git_buf_cstr(&log_message));
+		} else {
+			error = git_repository_set_head_detached(repo, git_reference_target(ref));
+		}
+	} else if (git_reference__is_branch(refname)) {
+		error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname,
+				true, git_buf_cstr(&log_message));
+	}
+
+cleanup:
+	git_buf_free(&log_message);
+	git_reference_free(current);
+	git_reference_free(ref);
+	git_reference_free(new_head);
+	return error;
+}
+
+static int detach(git_repository *repo, const git_oid *id, const char *from)
+{
+	int error;
+	git_buf log_message = GIT_BUF_INIT;
+	git_object *object = NULL, *peeled = NULL;
+	git_reference *new_head = NULL, *current = NULL;
+
+	assert(repo && id);
+
+	if ((error = git_reference_lookup(&current, repo, GIT_HEAD_FILE)) < 0)
+		return error;
+
+	if ((error = git_object_lookup(&object, repo, id, GIT_OBJ_ANY)) < 0)
+		goto cleanup;
+
+	if ((error = git_object_peel(&peeled, object, GIT_OBJ_COMMIT)) < 0)
+		goto cleanup;
+
+	if (from == NULL)
+		from = git_oid_tostr_s(git_object_id(peeled));
+
+	if ((error = checkout_message(&log_message, current, from)) < 0)
+		goto cleanup;
+
+	error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true, git_buf_cstr(&log_message));
+
+cleanup:
+	git_buf_free(&log_message);
+	git_object_free(object);
+	git_object_free(peeled);
+	git_reference_free(current);
+	git_reference_free(new_head);
+	return error;
+}
+
+int git_repository_set_head_detached(
+	git_repository* repo,
+	const git_oid* commitish)
+{
+	return detach(repo, commitish, NULL);
+}
+
+int git_repository_set_head_detached_from_annotated(
+	git_repository *repo,
+	const git_annotated_commit *commitish)
+{
+	assert(repo && commitish);
+
+	return detach(repo, git_annotated_commit_id(commitish), commitish->ref_name);
+}
+
+int git_repository_detach_head(git_repository* repo)
+{
+	git_reference *old_head = NULL,	*new_head = NULL, *current = NULL;
+	git_object *object = NULL;
+	git_buf log_message = GIT_BUF_INIT;
+	int error;
+
+	assert(repo);
+
+	if ((error = git_reference_lookup(&current, repo, GIT_HEAD_FILE)) < 0)
+		return error;
+
+	if ((error = git_repository_head(&old_head, repo)) < 0)
+		goto cleanup;
+
+	if ((error = git_object_lookup(&object, repo, git_reference_target(old_head), GIT_OBJ_COMMIT)) < 0)
+		goto cleanup;
+
+	if ((error = checkout_message(&log_message, current, git_oid_tostr_s(git_object_id(object)))) < 0)
+		goto cleanup;
+
+	error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_reference_target(old_head),
+			1, git_buf_cstr(&log_message));
+
+cleanup:
+	git_buf_free(&log_message);
+	git_object_free(object);
+	git_reference_free(old_head);
+	git_reference_free(new_head);
+	git_reference_free(current);
+	return error;
+}
+
+/**
+ * Loosely ported from git.git
+ * https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh#L198-289
+ */
+int git_repository_state(git_repository *repo)
+{
+	git_buf repo_path = GIT_BUF_INIT;
+	int state = GIT_REPOSITORY_STATE_NONE;
+
+	assert(repo);
+
+	if (git_buf_puts(&repo_path, repo->path_repository) < 0)
+		return -1;
+
+	if (git_path_contains_file(&repo_path, GIT_REBASE_MERGE_INTERACTIVE_FILE))
+		state = GIT_REPOSITORY_STATE_REBASE_INTERACTIVE;
+	else if (git_path_contains_dir(&repo_path, GIT_REBASE_MERGE_DIR))
+		state = GIT_REPOSITORY_STATE_REBASE_MERGE;
+	else if (git_path_contains_file(&repo_path, GIT_REBASE_APPLY_REBASING_FILE))
+		state = GIT_REPOSITORY_STATE_REBASE;
+	else if (git_path_contains_file(&repo_path, GIT_REBASE_APPLY_APPLYING_FILE))
+		state = GIT_REPOSITORY_STATE_APPLY_MAILBOX;
+	else if (git_path_contains_dir(&repo_path, GIT_REBASE_APPLY_DIR))
+		state = GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE;
+	else if (git_path_contains_file(&repo_path, GIT_MERGE_HEAD_FILE))
+		state = GIT_REPOSITORY_STATE_MERGE;
+	else if(git_path_contains_file(&repo_path, GIT_REVERT_HEAD_FILE))
+		state = GIT_REPOSITORY_STATE_REVERT;
+	else if(git_path_contains_file(&repo_path, GIT_CHERRYPICK_HEAD_FILE))
+		state = GIT_REPOSITORY_STATE_CHERRYPICK;
+	else if(git_path_contains_file(&repo_path, GIT_BISECT_LOG_FILE))
+		state = GIT_REPOSITORY_STATE_BISECT;
+
+	git_buf_free(&repo_path);
+	return state;
+}
+
+int git_repository__cleanup_files(
+	git_repository *repo, const char *files[], size_t files_len)
+{
+	git_buf buf = GIT_BUF_INIT;
+	size_t i;
+	int error;
+
+	for (error = 0, i = 0; !error && i < files_len; ++i) {
+		const char *path;
+
+		if (git_buf_joinpath(&buf, repo->path_repository, files[i]) < 0)
+			return -1;
+
+		path = git_buf_cstr(&buf);
+
+		if (git_path_isfile(path)) {
+			error = p_unlink(path);
+		} else if (git_path_isdir(path)) {
+			error = git_futils_rmdir_r(path, NULL,
+				GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_REMOVE_BLOCKERS);
+		}
+			
+		git_buf_clear(&buf);
+	}
+
+	git_buf_free(&buf);
+	return error;
+}
+
+static const char *state_files[] = {
+	GIT_MERGE_HEAD_FILE,
+	GIT_MERGE_MODE_FILE,
+	GIT_MERGE_MSG_FILE,
+	GIT_REVERT_HEAD_FILE,
+	GIT_CHERRYPICK_HEAD_FILE,
+	GIT_BISECT_LOG_FILE,
+	GIT_REBASE_MERGE_DIR,
+	GIT_REBASE_APPLY_DIR,
+};
+
+int git_repository_state_cleanup(git_repository *repo)
+{
+	assert(repo);
+
+	return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files));
+}
+
+int git_repository_is_shallow(git_repository *repo)
+{
+	git_buf path = GIT_BUF_INIT;
+	struct stat st;
+	int error;
+
+	if ((error = git_buf_joinpath(&path, repo->path_repository, "shallow")) < 0)
+		return error;
+
+	error = git_path_lstat(path.ptr, &st);
+	git_buf_free(&path);
+
+	if (error == GIT_ENOTFOUND) {
+		giterr_clear();
+		return 0;
+	}
+
+	if (error < 0)
+		return error;
+	return st.st_size == 0 ? 0 : 1;
+}
+
+int git_repository_init_init_options(
+	git_repository_init_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_repository_init_options,
+		GIT_REPOSITORY_INIT_OPTIONS_INIT);
+	return 0;
+}
+
+int git_repository_ident(const char **name, const char **email, const git_repository *repo)
+{
+	*name = repo->ident_name;
+	*email = repo->ident_email;
+
+	return 0;
+}
+
+int git_repository_set_ident(git_repository *repo, const char *name, const char *email)
+{
+	char *tmp_name = NULL, *tmp_email = NULL;
+
+	if (name) {
+		tmp_name = git__strdup(name);
+		GITERR_CHECK_ALLOC(tmp_name);
+	}
+
+	if (email) {
+		tmp_email = git__strdup(email);
+		GITERR_CHECK_ALLOC(tmp_email);
+	}
+
+	tmp_name = git__swap(repo->ident_name, tmp_name);
+	tmp_email = git__swap(repo->ident_email, tmp_email);
+
+	git__free(tmp_name);
+	git__free(tmp_email);
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/repository.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/repository.h
new file mode 100755
index 0000000..fd679b4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/repository.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_repository_h__
+#define INCLUDE_repository_h__
+
+#include "git2/common.h"
+#include "git2/oid.h"
+#include "git2/odb.h"
+#include "git2/repository.h"
+#include "git2/object.h"
+#include "git2/config.h"
+
+#include "array.h"
+#include "cache.h"
+#include "refs.h"
+#include "buffer.h"
+#include "object.h"
+#include "attrcache.h"
+#include "submodule.h"
+#include "diff_driver.h"
+
+#define DOT_GIT ".git"
+#define GIT_DIR DOT_GIT "/"
+#define GIT_DIR_MODE 0755
+#define GIT_BARE_DIR_MODE 0777
+
+/* Default DOS-compatible 8.3 "short name" for a git repository, "GIT~1" */
+#define GIT_DIR_SHORTNAME "GIT~1"
+
+/** Cvar cache identifiers */
+typedef enum {
+	GIT_CVAR_AUTO_CRLF = 0, /* core.autocrlf */
+	GIT_CVAR_EOL,           /* core.eol */
+	GIT_CVAR_SYMLINKS,      /* core.symlinks */
+	GIT_CVAR_IGNORECASE,    /* core.ignorecase */
+	GIT_CVAR_FILEMODE,      /* core.filemode */
+	GIT_CVAR_IGNORESTAT,    /* core.ignorestat */
+	GIT_CVAR_TRUSTCTIME,    /* core.trustctime */
+	GIT_CVAR_ABBREV,        /* core.abbrev */
+	GIT_CVAR_PRECOMPOSE,    /* core.precomposeunicode */
+	GIT_CVAR_SAFE_CRLF,		/* core.safecrlf */
+	GIT_CVAR_LOGALLREFUPDATES, /* core.logallrefupdates */
+	GIT_CVAR_PROTECTHFS,    /* core.protectHFS */
+	GIT_CVAR_PROTECTNTFS,   /* core.protectNTFS */
+	GIT_CVAR_CACHE_MAX
+} git_cvar_cached;
+
+/**
+ * CVAR value enumerations
+ *
+ * These are the values that are actually stored in the cvar cache, instead
+ * of their string equivalents. These values are internal and symbolic;
+ * make sure that none of them is set to `-1`, since that is the unique
+ * identifier for "not cached"
+ */
+typedef enum {
+	/* The value hasn't been loaded from the cache yet */
+	GIT_CVAR_NOT_CACHED = -1,
+
+	/* core.safecrlf: false, 'fail', 'warn' */
+	GIT_SAFE_CRLF_FALSE = 0,
+	GIT_SAFE_CRLF_FAIL = 1,
+	GIT_SAFE_CRLF_WARN = 2,
+
+	/* core.autocrlf: false, true, 'input; */
+	GIT_AUTO_CRLF_FALSE = 0,
+	GIT_AUTO_CRLF_TRUE = 1,
+	GIT_AUTO_CRLF_INPUT = 2,
+	GIT_AUTO_CRLF_DEFAULT = GIT_AUTO_CRLF_FALSE,
+
+	/* core.eol: unset, 'crlf', 'lf', 'native' */
+	GIT_EOL_UNSET = 0,
+	GIT_EOL_CRLF = 1,
+	GIT_EOL_LF = 2,
+#ifdef GIT_WIN32
+	GIT_EOL_NATIVE = GIT_EOL_CRLF,
+#else
+	GIT_EOL_NATIVE = GIT_EOL_LF,
+#endif
+	GIT_EOL_DEFAULT = GIT_EOL_NATIVE,
+
+	/* core.symlinks: bool */
+	GIT_SYMLINKS_DEFAULT = GIT_CVAR_TRUE,
+	/* core.ignorecase */
+	GIT_IGNORECASE_DEFAULT = GIT_CVAR_FALSE,
+	/* core.filemode */
+	GIT_FILEMODE_DEFAULT = GIT_CVAR_TRUE,
+	/* core.ignorestat */
+	GIT_IGNORESTAT_DEFAULT = GIT_CVAR_FALSE,
+	/* core.trustctime */
+	GIT_TRUSTCTIME_DEFAULT = GIT_CVAR_TRUE,
+	/* core.abbrev */
+	GIT_ABBREV_DEFAULT = 7,
+	/* core.precomposeunicode */
+	GIT_PRECOMPOSE_DEFAULT = GIT_CVAR_FALSE,
+	/* core.safecrlf */
+	GIT_SAFE_CRLF_DEFAULT = GIT_CVAR_FALSE,
+	/* core.logallrefupdates */
+	GIT_LOGALLREFUPDATES_UNSET = 2,
+	GIT_LOGALLREFUPDATES_DEFAULT = GIT_LOGALLREFUPDATES_UNSET,
+	/* core.protectHFS */
+	GIT_PROTECTHFS_DEFAULT = GIT_CVAR_FALSE,
+	/* core.protectNTFS */
+	GIT_PROTECTNTFS_DEFAULT = GIT_CVAR_FALSE,
+} git_cvar_value;
+
+/* internal repository init flags */
+enum {
+	GIT_REPOSITORY_INIT__HAS_DOTGIT = (1u << 16),
+	GIT_REPOSITORY_INIT__NATURAL_WD = (1u << 17),
+	GIT_REPOSITORY_INIT__IS_REINIT  = (1u << 18),
+};
+
+/** Internal structure for repository object */
+struct git_repository {
+	git_odb *_odb;
+	git_refdb *_refdb;
+	git_config *_config;
+	git_index *_index;
+
+	git_cache objects;
+	git_attr_cache *attrcache;
+	git_diff_driver_registry *diff_drivers;
+
+	char *path_repository;
+	char *path_gitlink;
+	char *workdir;
+	char *namespace;
+
+	char *ident_name;
+	char *ident_email;
+
+	git_array_t(git_buf) reserved_names;
+
+	unsigned is_bare:1;
+
+	unsigned int lru_counter;
+
+	git_atomic attr_session_key;
+
+	git_cvar_value cvar_cache[GIT_CVAR_CACHE_MAX];
+};
+
+GIT_INLINE(git_attr_cache *) git_repository_attr_cache(git_repository *repo)
+{
+	return repo->attrcache;
+}
+
+int git_repository_head_tree(git_tree **tree, git_repository *repo);
+
+/*
+ * Weak pointers to repository internals.
+ *
+ * The returned pointers do not need to be freed. Do not keep
+ * permanent references to these (i.e. between API calls), since they may
+ * become invalidated if the user replaces a repository internal.
+ */
+int git_repository_config__weakptr(git_config **out, git_repository *repo);
+int git_repository_odb__weakptr(git_odb **out, git_repository *repo);
+int git_repository_refdb__weakptr(git_refdb **out, git_repository *repo);
+int git_repository_index__weakptr(git_index **out, git_repository *repo);
+
+/*
+ * CVAR cache
+ *
+ * Efficient access to the most used config variables of a repository.
+ * The cache is cleared every time the config backend is replaced.
+ */
+int git_repository__cvar(int *out, git_repository *repo, git_cvar_cached cvar);
+void git_repository__cvar_cache_clear(git_repository *repo);
+
+GIT_INLINE(int) git_repository__ensure_not_bare(
+	git_repository *repo,
+	const char *operation_name)
+{
+	if (!git_repository_is_bare(repo))
+		return 0;
+
+	giterr_set(
+		GITERR_REPOSITORY,
+		"Cannot %s. This operation is not allowed against bare repositories.",
+		operation_name);
+
+	return GIT_EBAREREPO;
+}
+
+int git_repository__set_orig_head(git_repository *repo, const git_oid *orig_head);
+
+int git_repository__cleanup_files(git_repository *repo, const char *files[], size_t files_len);
+
+/* The default "reserved names" for a repository */
+extern git_buf git_repository__reserved_names_win32[];
+extern size_t git_repository__reserved_names_win32_len;
+
+extern git_buf git_repository__reserved_names_posix[];
+extern size_t git_repository__reserved_names_posix_len;
+
+/*
+ * Gets any "reserved names" in the repository.  This will return paths
+ * that should not be allowed in the repository (like ".git") to avoid
+ * conflicting with the repository path, or with alternate mechanisms to
+ * the repository path (eg, "GIT~1").  Every attempt will be made to look
+ * up all possible reserved names - if there was a conflict for the shortname
+ * GIT~1, for example, this function will try to look up the alternate
+ * shortname.  If that fails, this function returns false, but out and outlen
+ * will still be populated with good defaults.
+ */
+bool git_repository__reserved_names(
+	git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/reset.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/reset.c
new file mode 100755
index 0000000..0ffa51b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/reset.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "commit.h"
+#include "tag.h"
+#include "merge.h"
+#include "diff.h"
+#include "annotated_commit.h"
+#include "git2/reset.h"
+#include "git2/checkout.h"
+#include "git2/merge.h"
+#include "git2/refs.h"
+
+#define ERROR_MSG "Cannot perform reset"
+
+int git_reset_default(
+	git_repository *repo,
+	git_object *target,
+	git_strarray* pathspecs)
+{
+	git_object *commit = NULL;
+	git_tree *tree = NULL;
+	git_diff *diff = NULL;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	size_t i, max_i;
+	git_index_entry entry;
+	int error;
+	git_index *index = NULL;
+
+	assert(pathspecs != NULL && pathspecs->count > 0);
+
+	memset(&entry, 0, sizeof(git_index_entry));
+
+	if ((error = git_repository_index(&index, repo)) < 0)
+		goto cleanup;
+
+	if (target) {
+		if (git_object_owner(target) != repo) {
+			giterr_set(GITERR_OBJECT,
+				"%s_default - The given target does not belong to this repository.", ERROR_MSG);
+			return -1;
+		}
+
+		if ((error = git_object_peel(&commit, target, GIT_OBJ_COMMIT)) < 0 ||
+			(error = git_commit_tree(&tree, (git_commit *)commit)) < 0)
+			goto cleanup;
+	}
+
+	opts.pathspec = *pathspecs;
+	opts.flags = GIT_DIFF_REVERSE;
+
+	if ((error = git_diff_tree_to_index(
+		&diff, repo, tree, index, &opts)) < 0)
+			goto cleanup;
+
+	for (i = 0, max_i = git_diff_num_deltas(diff); i < max_i; ++i) {
+		const git_diff_delta *delta = git_diff_get_delta(diff, i);
+
+		assert(delta->status == GIT_DELTA_ADDED ||
+			delta->status == GIT_DELTA_MODIFIED ||
+			delta->status == GIT_DELTA_CONFLICTED ||
+			delta->status == GIT_DELTA_DELETED);
+
+		error = git_index_conflict_remove(index, delta->old_file.path);
+		if (error < 0) {
+			if (delta->status == GIT_DELTA_ADDED && error == GIT_ENOTFOUND)
+				giterr_clear();
+			else
+				goto cleanup;
+		}
+
+		if (delta->status == GIT_DELTA_DELETED) {
+			if ((error = git_index_remove(index, delta->old_file.path, 0)) < 0)
+				goto cleanup;
+		} else {
+			entry.mode = delta->new_file.mode;
+			git_oid_cpy(&entry.id, &delta->new_file.id);
+			entry.path = (char *)delta->new_file.path;
+
+			if ((error = git_index_add(index, &entry)) < 0)
+				goto cleanup;
+		}
+	}
+
+	error = git_index_write(index);
+
+cleanup:
+	git_object_free(commit);
+	git_tree_free(tree);
+	git_index_free(index);
+	git_diff_free(diff);
+
+	return error;
+}
+
+static int reset(
+	git_repository *repo,
+	git_object *target,
+	const char *to,
+	git_reset_t reset_type,
+	const git_checkout_options *checkout_opts)
+{
+	git_object *commit = NULL;
+	git_index *index = NULL;
+	git_tree *tree = NULL;
+	int error = 0;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_buf log_message = GIT_BUF_INIT;
+
+	assert(repo && target);
+
+	if (checkout_opts)
+		opts = *checkout_opts;
+
+	if (git_object_owner(target) != repo) {
+		giterr_set(GITERR_OBJECT,
+			"%s - The given target does not belong to this repository.", ERROR_MSG);
+		return -1;
+	}
+
+	if (reset_type != GIT_RESET_SOFT &&
+		(error = git_repository__ensure_not_bare(repo,
+			reset_type == GIT_RESET_MIXED ? "reset mixed" : "reset hard")) < 0)
+		return error;
+
+	if ((error = git_object_peel(&commit, target, GIT_OBJ_COMMIT)) < 0 ||
+		(error = git_repository_index(&index, repo)) < 0 ||
+		(error = git_commit_tree(&tree, (git_commit *)commit)) < 0)
+		goto cleanup;
+
+	if (reset_type == GIT_RESET_SOFT &&
+		(git_repository_state(repo) == GIT_REPOSITORY_STATE_MERGE ||
+		 git_index_has_conflicts(index)))
+	{
+		giterr_set(GITERR_OBJECT, "%s (soft) in the middle of a merge.", ERROR_MSG);
+		error = GIT_EUNMERGED;
+		goto cleanup;
+	}
+
+	if ((error = git_buf_printf(&log_message, "reset: moving to %s", to)) < 0)
+		return error;
+
+	/* move HEAD to the new target */
+	if ((error = git_reference__update_terminal(repo, GIT_HEAD_FILE,
+		git_object_id(commit), NULL, git_buf_cstr(&log_message))) < 0)
+		goto cleanup;
+
+	if (reset_type == GIT_RESET_HARD) {
+		/* overwrite working directory with HEAD */
+		opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+		if ((error = git_checkout_tree(repo, (git_object *)tree, &opts)) < 0)
+			goto cleanup;
+	}
+
+	if (reset_type > GIT_RESET_SOFT) {
+		/* reset index to the target content */
+
+		if ((error = git_index_read_tree(index, tree)) < 0 ||
+			(error = git_index_write(index)) < 0)
+			goto cleanup;
+
+		if ((error = git_repository_state_cleanup(repo)) < 0) {
+			giterr_set(GITERR_INDEX, "%s - failed to clean up merge data", ERROR_MSG);
+			goto cleanup;
+		}
+	}
+
+cleanup:
+	git_object_free(commit);
+	git_index_free(index);
+	git_tree_free(tree);
+	git_buf_free(&log_message);
+
+	return error;
+}
+
+int git_reset(
+	git_repository *repo,
+	git_object *target,
+	git_reset_t reset_type,
+	const git_checkout_options *checkout_opts)
+{
+	return reset(repo, target, git_oid_tostr_s(git_object_id(target)), reset_type, checkout_opts);
+}
+
+int git_reset_from_annotated(
+	git_repository *repo,
+	git_annotated_commit *commit,
+	git_reset_t reset_type,
+	const git_checkout_options *checkout_opts)
+{
+	return reset(repo, (git_object *) commit->commit, commit->ref_name, reset_type, checkout_opts);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/revert.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/revert.c
new file mode 100755
index 0000000..c481e7d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/revert.c
@@ -0,0 +1,231 @@
+/*
+* Copyright (C) the libgit2 contributors. All rights reserved.
+*
+* This file is part of libgit2, distributed under the GNU GPL v2 with
+* a Linking Exception. For full terms see the included COPYING file.
+*/
+
+#include "common.h"
+#include "repository.h"
+#include "filebuf.h"
+#include "merge.h"
+#include "index.h"
+
+#include "git2/types.h"
+#include "git2/merge.h"
+#include "git2/revert.h"
+#include "git2/commit.h"
+#include "git2/sys/commit.h"
+
+#define GIT_REVERT_FILE_MODE		0666
+
+static int write_revert_head(
+	git_repository *repo,
+	const char *commit_oidstr)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	git_buf file_path = GIT_BUF_INIT;
+	int error = 0;
+
+	if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_REVERT_HEAD_FILE)) >= 0 &&
+		(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_REVERT_FILE_MODE)) >= 0 &&
+		(error = git_filebuf_printf(&file, "%s\n", commit_oidstr)) >= 0)
+		error = git_filebuf_commit(&file);
+
+	if (error < 0)
+		git_filebuf_cleanup(&file);
+
+	git_buf_free(&file_path);
+
+	return error;
+}
+
+static int write_merge_msg(
+	git_repository *repo,
+	const char *commit_oidstr,
+	const char *commit_msgline)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	git_buf file_path = GIT_BUF_INIT;
+	int error = 0;
+
+	if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_MSG_FILE)) < 0 ||
+		(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_REVERT_FILE_MODE)) < 0 ||
+		(error = git_filebuf_printf(&file, "Revert \"%s\"\n\nThis reverts commit %s.\n",
+		commit_msgline, commit_oidstr)) < 0)
+		goto cleanup;
+
+	error = git_filebuf_commit(&file);
+
+cleanup:
+	if (error < 0)
+		git_filebuf_cleanup(&file);
+
+	git_buf_free(&file_path);
+
+	return error;
+}
+
+static int revert_normalize_opts(
+	git_repository *repo,
+	git_revert_options *opts,
+	const git_revert_options *given,
+	const char *their_label)
+{
+	int error = 0;
+	unsigned int default_checkout_strategy = GIT_CHECKOUT_SAFE |
+		GIT_CHECKOUT_ALLOW_CONFLICTS;
+
+	GIT_UNUSED(repo);
+
+	if (given != NULL)
+		memcpy(opts, given, sizeof(git_revert_options));
+	else {
+		git_revert_options default_opts = GIT_REVERT_OPTIONS_INIT;
+		memcpy(opts, &default_opts, sizeof(git_revert_options));
+	}
+
+	if (!opts->checkout_opts.checkout_strategy)
+		opts->checkout_opts.checkout_strategy = default_checkout_strategy;
+
+	if (!opts->checkout_opts.our_label)
+		opts->checkout_opts.our_label = "HEAD";
+
+	if (!opts->checkout_opts.their_label)
+		opts->checkout_opts.their_label = their_label;
+
+	return error;
+}
+
+static int revert_state_cleanup(git_repository *repo)
+{
+	const char *state_files[] = { GIT_REVERT_HEAD_FILE, GIT_MERGE_MSG_FILE };
+
+	return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files));
+}
+
+static int revert_seterr(git_commit *commit, const char *fmt)
+{
+	char commit_oidstr[GIT_OID_HEXSZ + 1];
+
+	git_oid_fmt(commit_oidstr, git_commit_id(commit));
+	commit_oidstr[GIT_OID_HEXSZ] = '\0';
+
+	giterr_set(GITERR_REVERT, fmt, commit_oidstr);
+
+	return -1;
+}
+
+int git_revert_commit(
+	git_index **out,
+	git_repository *repo,
+	git_commit *revert_commit,
+	git_commit *our_commit,
+	unsigned int mainline,
+	const git_merge_options *merge_opts)
+{
+	git_commit *parent_commit = NULL;
+	git_tree *parent_tree = NULL, *our_tree = NULL, *revert_tree = NULL;
+	int parent = 0, error = 0;
+
+	assert(out && repo && revert_commit && our_commit);
+
+	if (git_commit_parentcount(revert_commit) > 1) {
+		if (!mainline)
+			return revert_seterr(revert_commit,
+				"Mainline branch is not specified but %s is a merge commit");
+
+		parent = mainline;
+	} else {
+		if (mainline)
+			return revert_seterr(revert_commit,
+				"Mainline branch specified but %s is not a merge commit");
+
+		parent = git_commit_parentcount(revert_commit);
+	}
+
+	if (parent &&
+		((error = git_commit_parent(&parent_commit, revert_commit, (parent - 1))) < 0 ||
+		(error = git_commit_tree(&parent_tree, parent_commit)) < 0))
+		goto done;
+
+	if ((error = git_commit_tree(&revert_tree, revert_commit)) < 0 ||
+		(error = git_commit_tree(&our_tree, our_commit)) < 0)
+		goto done;
+
+	error = git_merge_trees(out, repo, revert_tree, our_tree, parent_tree, merge_opts);
+
+done:
+	git_tree_free(parent_tree);
+	git_tree_free(our_tree);
+	git_tree_free(revert_tree);
+	git_commit_free(parent_commit);
+
+	return error;
+}
+
+int git_revert(
+	git_repository *repo,
+	git_commit *commit,
+	const git_revert_options *given_opts)
+{
+	git_revert_options opts;
+	git_reference *our_ref = NULL;
+	git_commit *our_commit = NULL;
+	char commit_oidstr[GIT_OID_HEXSZ + 1];
+	const char *commit_msg;
+	git_buf their_label = GIT_BUF_INIT;
+	git_index *index = NULL;
+	git_indexwriter indexwriter = GIT_INDEXWRITER_INIT;
+	int error;
+
+	assert(repo && commit);
+
+	GITERR_CHECK_VERSION(given_opts, GIT_REVERT_OPTIONS_VERSION, "git_revert_options");
+
+	if ((error = git_repository__ensure_not_bare(repo, "revert")) < 0)
+		return error;
+
+	git_oid_fmt(commit_oidstr, git_commit_id(commit));
+	commit_oidstr[GIT_OID_HEXSZ] = '\0';
+
+	if ((commit_msg = git_commit_summary(commit)) == NULL) {
+		error = -1;
+		goto on_error;
+	}
+
+	if ((error = git_buf_printf(&their_label, "parent of %.7s... %s", commit_oidstr, commit_msg)) < 0 ||
+		(error = revert_normalize_opts(repo, &opts, given_opts, git_buf_cstr(&their_label))) < 0 ||
+		(error = git_indexwriter_init_for_operation(&indexwriter, repo, &opts.checkout_opts.checkout_strategy)) < 0 ||
+		(error = write_revert_head(repo, commit_oidstr)) < 0 ||
+		(error = write_merge_msg(repo, commit_oidstr, commit_msg)) < 0 ||
+		(error = git_repository_head(&our_ref, repo)) < 0 ||
+		(error = git_reference_peel((git_object **)&our_commit, our_ref, GIT_OBJ_COMMIT)) < 0 ||
+		(error = git_revert_commit(&index, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 ||
+		(error = git_merge__check_result(repo, index)) < 0 ||
+		(error = git_merge__append_conflicts_to_merge_msg(repo, index)) < 0 ||
+		(error = git_checkout_index(repo, index, &opts.checkout_opts)) < 0 ||
+		(error = git_indexwriter_commit(&indexwriter)) < 0)
+		goto on_error;
+
+	goto done;
+
+on_error:
+	revert_state_cleanup(repo);
+
+done:
+	git_indexwriter_cleanup(&indexwriter);
+	git_index_free(index);
+	git_commit_free(our_commit);
+	git_reference_free(our_ref);
+	git_buf_free(&their_label);
+
+	return error;
+}
+
+int git_revert_init_options(git_revert_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_revert_options, GIT_REVERT_OPTIONS_INIT);
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/revparse.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/revparse.c
new file mode 100755
index 0000000..e0ec394
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/revparse.c
@@ -0,0 +1,913 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include <assert.h>
+
+#include "common.h"
+#include "buffer.h"
+#include "tree.h"
+#include "refdb.h"
+
+#include "git2.h"
+
+static int maybe_sha_or_abbrev(git_object** out, git_repository *repo, const char *spec, size_t speclen)
+{
+	git_oid oid;
+
+	if (git_oid_fromstrn(&oid, spec, speclen) < 0)
+		return GIT_ENOTFOUND;
+
+	return git_object_lookup_prefix(out, repo, &oid, speclen, GIT_OBJ_ANY);
+}
+
+static int maybe_sha(git_object** out, git_repository *repo, const char *spec)
+{
+	size_t speclen = strlen(spec);
+
+	if (speclen != GIT_OID_HEXSZ)
+		return GIT_ENOTFOUND;
+
+	return maybe_sha_or_abbrev(out, repo, spec, speclen);
+}
+
+static int maybe_abbrev(git_object** out, git_repository *repo, const char *spec)
+{
+	size_t speclen = strlen(spec);
+
+	return maybe_sha_or_abbrev(out, repo, spec, speclen);
+}
+
+static int build_regex(regex_t *regex, const char *pattern)
+{
+	int error;
+
+	if (*pattern == '\0') {
+		giterr_set(GITERR_REGEX, "Empty pattern");
+		return GIT_EINVALIDSPEC;
+	}
+
+	error = regcomp(regex, pattern, REG_EXTENDED);
+	if (!error)
+		return 0;
+
+	error = giterr_set_regex(regex, error);
+
+	regfree(regex);
+
+	return error;
+}
+
+static int maybe_describe(git_object**out, git_repository *repo, const char *spec)
+{
+	const char *substr;
+	int error;
+	regex_t regex;
+
+	substr = strstr(spec, "-g");
+
+	if (substr == NULL)
+		return GIT_ENOTFOUND;
+
+	if (build_regex(&regex, ".+-[0-9]+-g[0-9a-fA-F]+") < 0)
+		return -1;
+
+	error = regexec(&regex, spec, 0, NULL, 0);
+	regfree(&regex);
+
+	if (error)
+		return GIT_ENOTFOUND;
+
+	return maybe_abbrev(out, repo, substr+2);
+}
+
+static int revparse_lookup_object(
+	git_object **object_out,
+	git_reference **reference_out,
+	git_repository *repo,
+	const char *spec)
+{
+	int error;
+	git_reference *ref;
+
+	if ((error = maybe_sha(object_out, repo, spec)) != GIT_ENOTFOUND)
+		return error;
+
+	error = git_reference_dwim(&ref, repo, spec);
+	if (!error) {
+
+		error = git_object_lookup(
+			object_out, repo, git_reference_target(ref), GIT_OBJ_ANY);
+
+		if (!error)
+			*reference_out = ref;
+
+		return error;
+	}
+
+	if (error != GIT_ENOTFOUND)
+		return error;
+
+	if ((strlen(spec) < GIT_OID_HEXSZ) &&
+		((error = maybe_abbrev(object_out, repo, spec)) != GIT_ENOTFOUND))
+			return error;
+
+	if ((error = maybe_describe(object_out, repo, spec)) != GIT_ENOTFOUND)
+		return error;
+
+	giterr_set(GITERR_REFERENCE, "Revspec '%s' not found.", spec);
+	return GIT_ENOTFOUND;
+}
+
+static int try_parse_numeric(int *n, const char *curly_braces_content)
+{
+	int32_t content;
+	const char *end_ptr;
+
+	if (git__strtol32(&content, curly_braces_content, &end_ptr, 10) < 0)
+		return -1;
+
+	if (*end_ptr != '\0')
+		return -1;
+
+	*n = (int)content;
+	return 0;
+}
+
+static int retrieve_previously_checked_out_branch_or_revision(git_object **out, git_reference **base_ref, git_repository *repo, const char *identifier, size_t position)
+{
+	git_reference *ref = NULL;
+	git_reflog *reflog = NULL;
+	regex_t preg;
+	int error = -1;
+	size_t i, numentries, cur;
+	const git_reflog_entry *entry;
+	const char *msg;
+	regmatch_t regexmatches[2];
+	git_buf buf = GIT_BUF_INIT;
+
+	cur = position;
+
+	if (*identifier != '\0' || *base_ref != NULL)
+		return GIT_EINVALIDSPEC;
+
+	if (build_regex(&preg, "checkout: moving from (.*) to .*") < 0)
+		return -1;
+
+	if (git_reference_lookup(&ref, repo, GIT_HEAD_FILE) < 0)
+		goto cleanup;
+
+	if (git_reflog_read(&reflog, repo, GIT_HEAD_FILE) < 0)
+		goto cleanup;
+
+	numentries  = git_reflog_entrycount(reflog);
+
+	for (i = 0; i < numentries; i++) {
+		entry = git_reflog_entry_byindex(reflog, i);
+		msg = git_reflog_entry_message(entry);
+		if (!msg)
+			continue;
+
+		if (regexec(&preg, msg, 2, regexmatches, 0))
+			continue;
+
+		cur--;
+
+		if (cur > 0)
+			continue;
+
+		git_buf_put(&buf, msg+regexmatches[1].rm_so, regexmatches[1].rm_eo - regexmatches[1].rm_so);
+
+		if ((error = git_reference_dwim(base_ref, repo, git_buf_cstr(&buf))) == 0)
+			goto cleanup;
+
+		if (error < 0 && error != GIT_ENOTFOUND)
+			goto cleanup;
+
+		error = maybe_abbrev(out, repo, git_buf_cstr(&buf));
+
+		goto cleanup;
+	}
+
+	error = GIT_ENOTFOUND;
+
+cleanup:
+	git_reference_free(ref);
+	git_buf_free(&buf);
+	regfree(&preg);
+	git_reflog_free(reflog);
+	return error;
+}
+
+static int retrieve_oid_from_reflog(git_oid *oid, git_reference *ref, size_t identifier)
+{
+	git_reflog *reflog;
+	size_t numentries;
+	const git_reflog_entry *entry;
+	bool search_by_pos = (identifier <= 100000000);
+
+	if (git_reflog_read(&reflog, git_reference_owner(ref), git_reference_name(ref)) < 0)
+		return -1;
+
+	numentries = git_reflog_entrycount(reflog);
+
+	if (search_by_pos) {
+		if (numentries < identifier + 1)
+			goto notfound;
+
+		entry = git_reflog_entry_byindex(reflog, identifier);
+		git_oid_cpy(oid, git_reflog_entry_id_new(entry));
+	} else {
+		size_t i;
+		git_time commit_time;
+
+		for (i = 0; i < numentries; i++) {
+			entry = git_reflog_entry_byindex(reflog, i);
+			commit_time = git_reflog_entry_committer(entry)->when;
+
+			if (commit_time.time > (git_time_t)identifier)
+				continue;
+
+			git_oid_cpy(oid, git_reflog_entry_id_new(entry));
+			break;
+		}
+
+		if (i == numentries)
+			goto notfound;
+	}
+
+	git_reflog_free(reflog);
+	return 0;
+
+notfound:
+	giterr_set(
+		GITERR_REFERENCE,
+		"Reflog for '%s' has only %"PRIuZ" entries, asked for %"PRIuZ,
+		git_reference_name(ref), numentries, identifier);
+
+	git_reflog_free(reflog);
+	return GIT_ENOTFOUND;
+}
+
+static int retrieve_revobject_from_reflog(git_object **out, git_reference **base_ref, git_repository *repo, const char *identifier, size_t position)
+{
+	git_reference *ref;
+	git_oid oid;
+	int error = -1;
+
+	if (*base_ref == NULL) {
+		if ((error = git_reference_dwim(&ref, repo, identifier)) < 0)
+			return error;
+	} else {
+		ref = *base_ref;
+		*base_ref = NULL;
+	}
+
+	if (position == 0) {
+		error = git_object_lookup(out, repo, git_reference_target(ref), GIT_OBJ_ANY);
+		goto cleanup;
+	}
+
+	if ((error = retrieve_oid_from_reflog(&oid, ref, position)) < 0)
+		goto cleanup;
+
+	error = git_object_lookup(out, repo, &oid, GIT_OBJ_ANY);
+
+cleanup:
+	git_reference_free(ref);
+	return error;
+}
+
+static int retrieve_remote_tracking_reference(git_reference **base_ref, const char *identifier, git_repository *repo)
+{
+	git_reference *tracking, *ref;
+	int error = -1;
+
+	if (*base_ref == NULL) {
+		if ((error = git_reference_dwim(&ref, repo, identifier)) < 0)
+			return error;
+	} else {
+		ref = *base_ref;
+		*base_ref = NULL;
+	}
+
+	if (!git_reference_is_branch(ref)) {
+		error = GIT_EINVALIDSPEC;
+		goto cleanup;
+	}
+
+	if ((error = git_branch_upstream(&tracking, ref)) < 0)
+		goto cleanup;
+
+	*base_ref = tracking;
+
+cleanup:
+	git_reference_free(ref);
+	return error;
+}
+
+static int handle_at_syntax(git_object **out, git_reference **ref, const char *spec, size_t identifier_len, git_repository* repo, const char *curly_braces_content)
+{
+	bool is_numeric;
+	int parsed = 0, error = -1;
+	git_buf identifier = GIT_BUF_INIT;
+	git_time_t timestamp;
+
+	assert(*out == NULL);
+
+	if (git_buf_put(&identifier, spec, identifier_len) < 0)
+		return -1;
+
+	is_numeric = !try_parse_numeric(&parsed, curly_braces_content);
+
+	if (*curly_braces_content == '-' && (!is_numeric || parsed == 0)) {
+		error = GIT_EINVALIDSPEC;
+		goto cleanup;
+	}
+
+	if (is_numeric) {
+		if (parsed < 0)
+			error = retrieve_previously_checked_out_branch_or_revision(out, ref, repo, git_buf_cstr(&identifier), -parsed);
+		else
+			error = retrieve_revobject_from_reflog(out, ref, repo, git_buf_cstr(&identifier), parsed);
+
+		goto cleanup;
+	}
+
+	if (!strcmp(curly_braces_content, "u") || !strcmp(curly_braces_content, "upstream")) {
+		error = retrieve_remote_tracking_reference(ref, git_buf_cstr(&identifier), repo);
+
+		goto cleanup;
+	}
+
+	if (git__date_parse(&timestamp, curly_braces_content) < 0)
+		goto cleanup;
+
+	error = retrieve_revobject_from_reflog(out, ref, repo, git_buf_cstr(&identifier), (size_t)timestamp);
+
+cleanup:
+	git_buf_free(&identifier);
+	return error;
+}
+
+static git_otype parse_obj_type(const char *str)
+{
+	if (!strcmp(str, "commit"))
+		return GIT_OBJ_COMMIT;
+
+	if (!strcmp(str, "tree"))
+		return GIT_OBJ_TREE;
+
+	if (!strcmp(str, "blob"))
+		return GIT_OBJ_BLOB;
+
+	if (!strcmp(str, "tag"))
+		return GIT_OBJ_TAG;
+
+	return GIT_OBJ_BAD;
+}
+
+static int dereference_to_non_tag(git_object **out, git_object *obj)
+{
+	if (git_object_type(obj) == GIT_OBJ_TAG)
+		return git_tag_peel(out, (git_tag *)obj);
+
+	return git_object_dup(out, obj);
+}
+
+static int handle_caret_parent_syntax(git_object **out, git_object *obj, int n)
+{
+	git_object *temp_commit = NULL;
+	int error;
+
+	if ((error = git_object_peel(&temp_commit, obj, GIT_OBJ_COMMIT)) < 0)
+		return (error == GIT_EAMBIGUOUS || error == GIT_ENOTFOUND) ?
+			GIT_EINVALIDSPEC : error;
+
+	if (n == 0) {
+		*out = temp_commit;
+		return 0;
+	}
+
+	error = git_commit_parent((git_commit **)out, (git_commit*)temp_commit, n - 1);
+
+	git_object_free(temp_commit);
+	return error;
+}
+
+static int handle_linear_syntax(git_object **out, git_object *obj, int n)
+{
+	git_object *temp_commit = NULL;
+	int error;
+
+	if ((error = git_object_peel(&temp_commit, obj, GIT_OBJ_COMMIT)) < 0)
+		return (error == GIT_EAMBIGUOUS || error == GIT_ENOTFOUND) ?
+			GIT_EINVALIDSPEC : error;
+
+	error = git_commit_nth_gen_ancestor((git_commit **)out, (git_commit*)temp_commit, n);
+
+	git_object_free(temp_commit);
+	return error;
+}
+
+static int handle_colon_syntax(
+	git_object **out,
+	git_object *obj,
+	const char *path)
+{
+	git_object *tree;
+	int error = -1;
+	git_tree_entry *entry = NULL;
+
+	if ((error = git_object_peel(&tree, obj, GIT_OBJ_TREE)) < 0)
+		return error == GIT_ENOTFOUND ? GIT_EINVALIDSPEC : error;
+
+	if (*path == '\0') {
+		*out = tree;
+		return 0;
+	}
+
+	/*
+	 * TODO: Handle the relative path syntax
+	 * (:./relative/path and :../relative/path)
+	 */
+	if ((error = git_tree_entry_bypath(&entry, (git_tree *)tree, path)) < 0)
+		goto cleanup;
+
+	error = git_tree_entry_to_object(out, git_object_owner(tree), entry);
+
+cleanup:
+	git_tree_entry_free(entry);
+	git_object_free(tree);
+
+	return error;
+}
+
+static int walk_and_search(git_object **out, git_revwalk *walk, regex_t *regex)
+{
+	int error;
+	git_oid oid;
+	git_object *obj;
+
+	while (!(error = git_revwalk_next(&oid, walk))) {
+
+		error = git_object_lookup(&obj, git_revwalk_repository(walk), &oid, GIT_OBJ_COMMIT);
+		if ((error < 0) && (error != GIT_ENOTFOUND))
+			return -1;
+
+		if (!regexec(regex, git_commit_message((git_commit*)obj), 0, NULL, 0)) {
+			*out = obj;
+			return 0;
+		}
+
+		git_object_free(obj);
+	}
+
+	if (error < 0 && error == GIT_ITEROVER)
+		error = GIT_ENOTFOUND;
+
+	return error;
+}
+
+static int handle_grep_syntax(git_object **out, git_repository *repo, const git_oid *spec_oid, const char *pattern)
+{
+	regex_t preg;
+	git_revwalk *walk = NULL;
+	int error;
+
+	if ((error = build_regex(&preg, pattern)) < 0)
+		return error;
+
+	if ((error = git_revwalk_new(&walk, repo)) < 0)
+		goto cleanup;
+
+	git_revwalk_sorting(walk, GIT_SORT_TIME);
+
+	if (spec_oid == NULL) {
+		if ((error = git_revwalk_push_glob(walk, "refs/*")) < 0)
+			goto cleanup;
+	} else if ((error = git_revwalk_push(walk, spec_oid)) < 0)
+			goto cleanup;
+
+	error = walk_and_search(out, walk, &preg);
+
+cleanup:
+	regfree(&preg);
+	git_revwalk_free(walk);
+
+	return error;
+}
+
+static int handle_caret_curly_syntax(git_object **out, git_object *obj, const char *curly_braces_content)
+{
+	git_otype expected_type;
+
+	if (*curly_braces_content == '\0')
+		return dereference_to_non_tag(out, obj);
+
+	if (*curly_braces_content == '/')
+		return handle_grep_syntax(out, git_object_owner(obj), git_object_id(obj), curly_braces_content + 1);
+
+	expected_type = parse_obj_type(curly_braces_content);
+
+	if (expected_type == GIT_OBJ_BAD)
+		return GIT_EINVALIDSPEC;
+
+	return git_object_peel(out, obj, expected_type);
+}
+
+static int extract_curly_braces_content(git_buf *buf, const char *spec, size_t *pos)
+{
+	git_buf_clear(buf);
+
+	assert(spec[*pos] == '^' || spec[*pos] == '@');
+
+	(*pos)++;
+
+	if (spec[*pos] == '\0' || spec[*pos] != '{')
+		return GIT_EINVALIDSPEC;
+
+	(*pos)++;
+
+	while (spec[*pos] != '}') {
+		if (spec[*pos] == '\0')
+			return GIT_EINVALIDSPEC;
+
+		git_buf_putc(buf, spec[(*pos)++]);
+	}
+
+	(*pos)++;
+
+	return 0;
+}
+
+static int extract_path(git_buf *buf, const char *spec, size_t *pos)
+{
+	git_buf_clear(buf);
+
+	assert(spec[*pos] == ':');
+
+	(*pos)++;
+
+	if (git_buf_puts(buf, spec + *pos) < 0)
+		return -1;
+
+	*pos += git_buf_len(buf);
+
+	return 0;
+}
+
+static int extract_how_many(int *n, const char *spec, size_t *pos)
+{
+	const char *end_ptr;
+	int parsed, accumulated;
+	char kind = spec[*pos];
+
+	assert(spec[*pos] == '^' || spec[*pos] == '~');
+
+	accumulated = 0;
+
+	do {
+		do {
+			(*pos)++;
+			accumulated++;
+		} while (spec[(*pos)] == kind && kind == '~');
+
+		if (git__isdigit(spec[*pos])) {
+			if (git__strtol32(&parsed, spec + *pos, &end_ptr, 10) < 0)
+				return GIT_EINVALIDSPEC;
+
+			accumulated += (parsed - 1);
+			*pos = end_ptr - spec;
+		}
+
+	} 	while (spec[(*pos)] == kind && kind == '~');
+
+	*n = accumulated;
+
+	return 0;
+}
+
+static int object_from_reference(git_object **object, git_reference *reference)
+{
+	git_reference *resolved = NULL;
+	int error;
+
+	if (git_reference_resolve(&resolved, reference) < 0)
+		return -1;
+
+	error = git_object_lookup(object, reference->db->repo, git_reference_target(resolved), GIT_OBJ_ANY);
+	git_reference_free(resolved);
+
+	return error;
+}
+
+static int ensure_base_rev_loaded(git_object **object, git_reference **reference, const char *spec, size_t identifier_len, git_repository *repo, bool allow_empty_identifier)
+{
+	int error;
+	git_buf identifier = GIT_BUF_INIT;
+
+	if (*object != NULL)
+		return 0;
+
+	if (*reference != NULL)
+		return object_from_reference(object, *reference);
+
+	if (!allow_empty_identifier && identifier_len == 0)
+		return GIT_EINVALIDSPEC;
+
+	if (git_buf_put(&identifier, spec, identifier_len) < 0)
+		return -1;
+
+	error = revparse_lookup_object(object, reference, repo, git_buf_cstr(&identifier));
+	git_buf_free(&identifier);
+
+	return error;
+}
+
+static int ensure_base_rev_is_not_known_yet(git_object *object)
+{
+	if (object == NULL)
+		return 0;
+
+	return GIT_EINVALIDSPEC;
+}
+
+static bool any_left_hand_identifier(git_object *object, git_reference *reference, size_t identifier_len)
+{
+	if (object != NULL)
+		return true;
+
+	if (reference != NULL)
+		return true;
+
+	if (identifier_len > 0)
+		return true;
+
+	return false;
+}
+
+static int ensure_left_hand_identifier_is_not_known_yet(git_object *object, git_reference *reference)
+{
+	if (!ensure_base_rev_is_not_known_yet(object) && reference == NULL)
+		return 0;
+
+	return GIT_EINVALIDSPEC;
+}
+
+int revparse__ext(
+	git_object **object_out,
+	git_reference **reference_out,
+	size_t *identifier_len_out,
+	git_repository *repo,
+	const char *spec)
+{
+	size_t pos = 0, identifier_len = 0;
+	int error = -1, n;
+	git_buf buf = GIT_BUF_INIT;
+
+	git_reference *reference = NULL;
+	git_object *base_rev = NULL;
+
+	bool should_return_reference = true;
+
+	assert(object_out && reference_out && repo && spec);
+
+	*object_out = NULL;
+	*reference_out = NULL;
+
+	while (spec[pos]) {
+		switch (spec[pos]) {
+		case '^':
+			should_return_reference = false;
+
+			if ((error = ensure_base_rev_loaded(&base_rev, &reference, spec, identifier_len, repo, false)) < 0)
+				goto cleanup;
+
+			if (spec[pos+1] == '{') {
+				git_object *temp_object = NULL;
+
+				if ((error = extract_curly_braces_content(&buf, spec, &pos)) < 0)
+					goto cleanup;
+
+				if ((error = handle_caret_curly_syntax(&temp_object, base_rev, git_buf_cstr(&buf))) < 0)
+					goto cleanup;
+
+				git_object_free(base_rev);
+				base_rev = temp_object;
+			} else {
+				git_object *temp_object = NULL;
+
+				if ((error = extract_how_many(&n, spec, &pos)) < 0)
+					goto cleanup;
+
+				if ((error = handle_caret_parent_syntax(&temp_object, base_rev, n)) < 0)
+					goto cleanup;
+
+				git_object_free(base_rev);
+				base_rev = temp_object;
+			}
+			break;
+
+		case '~':
+		{
+			git_object *temp_object = NULL;
+
+			should_return_reference = false;
+
+			if ((error = extract_how_many(&n, spec, &pos)) < 0)
+				goto cleanup;
+
+			if ((error = ensure_base_rev_loaded(&base_rev, &reference, spec, identifier_len, repo, false)) < 0)
+				goto cleanup;
+
+			if ((error = handle_linear_syntax(&temp_object, base_rev, n)) < 0)
+				goto cleanup;
+
+			git_object_free(base_rev);
+			base_rev = temp_object;
+			break;
+		}
+
+		case ':':
+		{
+			git_object *temp_object = NULL;
+
+			should_return_reference = false;
+
+			if ((error = extract_path(&buf, spec, &pos)) < 0)
+				goto cleanup;
+
+			if (any_left_hand_identifier(base_rev, reference, identifier_len)) {
+				if ((error = ensure_base_rev_loaded(&base_rev, &reference, spec, identifier_len, repo, true)) < 0)
+					goto cleanup;
+
+				if ((error = handle_colon_syntax(&temp_object, base_rev, git_buf_cstr(&buf))) < 0)
+					goto cleanup;
+			} else {
+				if (*git_buf_cstr(&buf) == '/') {
+					if ((error = handle_grep_syntax(&temp_object, repo, NULL, git_buf_cstr(&buf) + 1)) < 0)
+						goto cleanup;
+				} else {
+
+					/*
+					 * TODO: support merge-stage path lookup (":2:Makefile")
+					 * and plain index blob lookup (:i-am/a/blob)
+					 */
+					giterr_set(GITERR_INVALID, "Unimplemented");
+					error = GIT_ERROR;
+					goto cleanup;
+				}
+			}
+
+			git_object_free(base_rev);
+			base_rev = temp_object;
+			break;
+		}
+
+		case '@':
+		{
+			if (spec[pos+1] == '{') {
+				git_object *temp_object = NULL;
+
+				if ((error = extract_curly_braces_content(&buf, spec, &pos)) < 0)
+					goto cleanup;
+
+				if ((error = ensure_base_rev_is_not_known_yet(base_rev)) < 0)
+					goto cleanup;
+
+				if ((error = handle_at_syntax(&temp_object, &reference, spec, identifier_len, repo, git_buf_cstr(&buf))) < 0)
+					goto cleanup;
+
+				if (temp_object != NULL)
+					base_rev = temp_object;
+				break;
+			} else {
+				/* Fall through */
+			}
+		}
+
+		default:
+			if ((error = ensure_left_hand_identifier_is_not_known_yet(base_rev, reference)) < 0)
+				goto cleanup;
+
+			pos++;
+			identifier_len++;
+		}
+	}
+
+	if ((error = ensure_base_rev_loaded(&base_rev, &reference, spec, identifier_len, repo, false)) < 0)
+		goto cleanup;
+
+	if (!should_return_reference) {
+		git_reference_free(reference);
+		reference = NULL;
+	}
+
+	*object_out = base_rev;
+	*reference_out = reference;
+	*identifier_len_out = identifier_len;
+	error = 0;
+
+cleanup:
+	if (error) {
+		if (error == GIT_EINVALIDSPEC)
+			giterr_set(GITERR_INVALID,
+				"Failed to parse revision specifier - Invalid pattern '%s'", spec);
+
+		git_object_free(base_rev);
+		git_reference_free(reference);
+	}
+
+	git_buf_free(&buf);
+	return error;
+}
+
+int git_revparse_ext(
+	git_object **object_out,
+	git_reference **reference_out,
+	git_repository *repo,
+	const char *spec)
+{
+	int error;
+	size_t identifier_len;
+	git_object *obj = NULL;
+	git_reference *ref = NULL;
+
+	if ((error = revparse__ext(&obj, &ref, &identifier_len, repo, spec)) < 0)
+		goto cleanup;
+
+	*object_out = obj;
+	*reference_out = ref;
+	GIT_UNUSED(identifier_len);
+
+	return 0;
+
+cleanup:
+	git_object_free(obj);
+	git_reference_free(ref);
+	return error;
+}
+
+int git_revparse_single(git_object **out, git_repository *repo, const char *spec)
+{
+	int error;
+	git_object *obj = NULL;
+	git_reference *ref = NULL;
+
+	*out = NULL;
+
+	if ((error = git_revparse_ext(&obj, &ref, repo, spec)) < 0)
+		goto cleanup;
+
+	git_reference_free(ref);
+
+	*out = obj;
+
+	return 0;
+
+cleanup:
+	git_object_free(obj);
+	git_reference_free(ref);
+	return error;
+}
+
+int git_revparse(
+	git_revspec *revspec,
+	git_repository *repo,
+	const char *spec)
+{
+	const char *dotdot;
+	int error = 0;
+
+	assert(revspec && repo && spec);
+
+	memset(revspec, 0x0, sizeof(*revspec));
+
+	if ((dotdot = strstr(spec, "..")) != NULL) {
+		char *lstr;
+		const char *rstr;
+		revspec->flags = GIT_REVPARSE_RANGE;
+
+		lstr = git__substrdup(spec, dotdot - spec);
+		rstr = dotdot + 2;
+		if (dotdot[2] == '.') {
+			revspec->flags |= GIT_REVPARSE_MERGE_BASE;
+			rstr++;
+		}
+
+		error = git_revparse_single(&revspec->from, repo, lstr);
+		if (!error)
+			error = git_revparse_single(&revspec->to, repo, rstr);
+
+		git__free((void*)lstr);
+	} else {
+		revspec->flags = GIT_REVPARSE_SINGLE;
+		error = git_revparse_single(&revspec->from, repo, spec);
+	}
+
+	return error;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/revwalk.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/revwalk.c
new file mode 100755
index 0000000..dcdd979
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/revwalk.c
@@ -0,0 +1,672 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "commit.h"
+#include "odb.h"
+#include "pool.h"
+
+#include "revwalk.h"
+#include "git2/revparse.h"
+#include "merge.h"
+
+GIT__USE_OIDMAP
+
+git_commit_list_node *git_revwalk__commit_lookup(
+	git_revwalk *walk, const git_oid *oid)
+{
+	git_commit_list_node *commit;
+	khiter_t pos;
+	int ret;
+
+	/* lookup and reserve space if not already present */
+	pos = kh_get(oid, walk->commits, oid);
+	if (pos != kh_end(walk->commits))
+		return kh_value(walk->commits, pos);
+
+	commit = git_commit_list_alloc_node(walk);
+	if (commit == NULL)
+		return NULL;
+
+	git_oid_cpy(&commit->oid, oid);
+
+	pos = kh_put(oid, walk->commits, &commit->oid, &ret);
+	assert(ret != 0);
+	kh_value(walk->commits, pos) = commit;
+
+	return commit;
+}
+
+typedef git_array_t(git_commit_list_node*) commit_list_node_array;
+
+static bool interesting_arr(commit_list_node_array arr)
+{
+	git_commit_list_node **n;
+	size_t i = 0, size;
+
+	size = git_array_size(arr);
+	for (i = 0; i < size; i++) {
+		n = git_array_get(arr, i);
+		if (!*n)
+			break;
+
+		if (!(*n)->uninteresting)
+			return true;
+	}
+
+	return false;
+}
+
+static int mark_uninteresting(git_revwalk *walk, git_commit_list_node *commit)
+{
+	int error;
+	unsigned short i;
+	commit_list_node_array pending = GIT_ARRAY_INIT;
+	git_commit_list_node **tmp;
+
+	assert(commit);
+
+	do {
+		commit->uninteresting = 1;
+
+		if ((error = git_commit_list_parse(walk, commit)) < 0)
+			return error;
+
+		for (i = 0; i < commit->out_degree; ++i)
+			if (!commit->parents[i]->uninteresting) {
+				git_commit_list_node **node = git_array_alloc(pending);
+				GITERR_CHECK_ALLOC(node);
+				*node = commit->parents[i];
+			}
+
+		tmp = git_array_pop(pending);
+		commit = tmp ? *tmp : NULL;
+
+	} while (commit != NULL && !interesting_arr(pending));
+
+	git_array_clear(pending);
+
+	return 0;
+}
+
+static int process_commit(git_revwalk *walk, git_commit_list_node *commit, int hide)
+{
+	int error;
+
+	if (!hide && walk->hide_cb)
+		hide = walk->hide_cb(&commit->oid, walk->hide_cb_payload);
+
+	if (hide && mark_uninteresting(walk, commit) < 0)
+		return -1;
+
+	if (commit->seen)
+		return 0;
+
+	commit->seen = 1;
+
+	if ((error = git_commit_list_parse(walk, commit)) < 0)
+		return error;
+
+	if (!hide)
+		return walk->enqueue(walk, commit);
+
+	return 0;
+}
+
+static int process_commit_parents(git_revwalk *walk, git_commit_list_node *commit)
+{
+	unsigned short i, max;
+	int error = 0;
+
+	max = commit->out_degree;
+	if (walk->first_parent && commit->out_degree)
+		max = 1;
+
+	for (i = 0; i < max && !error; ++i)
+		error = process_commit(walk, commit->parents[i], commit->uninteresting);
+
+	return error;
+}
+
+static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting, int from_glob)
+{
+	git_oid commit_id;
+	int error;
+	git_object *obj, *oobj;
+	git_commit_list_node *commit;
+	git_commit_list *list;
+
+	if ((error = git_object_lookup(&oobj, walk->repo, oid, GIT_OBJ_ANY)) < 0)
+		return error;
+
+	error = git_object_peel(&obj, oobj, GIT_OBJ_COMMIT);
+	git_object_free(oobj);
+
+	if (error == GIT_ENOTFOUND || error == GIT_EINVALIDSPEC || error == GIT_EPEEL) {
+		/* If this comes from e.g. push_glob("tags"), ignore this */
+		if (from_glob)
+			return 0;
+
+		giterr_set(GITERR_INVALID, "Object is not a committish");
+		return -1;
+	}
+	if (error < 0)
+		return error;
+
+	git_oid_cpy(&commit_id, git_object_id(obj));
+	git_object_free(obj);
+
+	commit = git_revwalk__commit_lookup(walk, &commit_id);
+	if (commit == NULL)
+		return -1; /* error already reported by failed lookup */
+
+	/* A previous hide already told us we don't want this commit  */
+	if (commit->uninteresting)
+		return 0;
+
+	if (uninteresting)
+		walk->did_hide = 1;
+	else
+		walk->did_push = 1;
+
+	commit->uninteresting = uninteresting;
+	list = walk->user_input;
+	if (git_commit_list_insert(commit, &list) == NULL) {
+		giterr_set_oom();
+		return -1;
+	}
+
+	walk->user_input = list;
+
+	return 0;
+}
+
+int git_revwalk_push(git_revwalk *walk, const git_oid *oid)
+{
+	assert(walk && oid);
+	return push_commit(walk, oid, 0, false);
+}
+
+
+int git_revwalk_hide(git_revwalk *walk, const git_oid *oid)
+{
+	assert(walk && oid);
+	return push_commit(walk, oid, 1, false);
+}
+
+static int push_ref(git_revwalk *walk, const char *refname, int hide, int from_glob)
+{
+	git_oid oid;
+
+	if (git_reference_name_to_id(&oid, walk->repo, refname) < 0)
+		return -1;
+
+	return push_commit(walk, &oid, hide, from_glob);
+}
+
+static int push_glob(git_revwalk *walk, const char *glob, int hide)
+{
+	int error = 0;
+	git_buf buf = GIT_BUF_INIT;
+	git_reference *ref;
+	git_reference_iterator *iter;
+	size_t wildcard;
+
+	assert(walk && glob);
+
+	/* refs/ is implied if not given in the glob */
+	if (git__prefixcmp(glob, GIT_REFS_DIR) != 0)
+		git_buf_joinpath(&buf, GIT_REFS_DIR, glob);
+	else
+		git_buf_puts(&buf, glob);
+	if (git_buf_oom(&buf))
+		return -1;
+
+	/* If no '?', '*' or '[' exist, we append '/ *' to the glob */
+	wildcard = strcspn(glob, "?*[");
+	if (!glob[wildcard])
+		git_buf_put(&buf, "/*", 2);
+
+	if ((error = git_reference_iterator_glob_new(&iter, walk->repo, buf.ptr)) < 0)
+		goto out;
+
+	while ((error = git_reference_next(&ref, iter)) == 0) {
+		error = push_ref(walk, git_reference_name(ref), hide, true);
+		git_reference_free(ref);
+		if (error < 0)
+			break;
+	}
+	git_reference_iterator_free(iter);
+
+	if (error == GIT_ITEROVER)
+		error = 0;
+out:
+	git_buf_free(&buf);
+	return error;
+}
+
+int git_revwalk_push_glob(git_revwalk *walk, const char *glob)
+{
+	assert(walk && glob);
+	return push_glob(walk, glob, 0);
+}
+
+int git_revwalk_hide_glob(git_revwalk *walk, const char *glob)
+{
+	assert(walk && glob);
+	return push_glob(walk, glob, 1);
+}
+
+int git_revwalk_push_head(git_revwalk *walk)
+{
+	assert(walk);
+	return push_ref(walk, GIT_HEAD_FILE, 0, false);
+}
+
+int git_revwalk_hide_head(git_revwalk *walk)
+{
+	assert(walk);
+	return push_ref(walk, GIT_HEAD_FILE, 1, false);
+}
+
+int git_revwalk_push_ref(git_revwalk *walk, const char *refname)
+{
+	assert(walk && refname);
+	return push_ref(walk, refname, 0, false);
+}
+
+int git_revwalk_push_range(git_revwalk *walk, const char *range)
+{
+	git_revspec revspec;
+	int error = 0;
+
+	if ((error = git_revparse(&revspec, walk->repo, range)))
+		return error;
+
+	if (revspec.flags & GIT_REVPARSE_MERGE_BASE) {
+		/* TODO: support "<commit>...<commit>" */
+		giterr_set(GITERR_INVALID, "Symmetric differences not implemented in revwalk");
+		return GIT_EINVALIDSPEC;
+	}
+
+	if ((error = push_commit(walk, git_object_id(revspec.from), 1, false)))
+		goto out;
+
+	error = push_commit(walk, git_object_id(revspec.to), 0, false);
+
+out:
+	git_object_free(revspec.from);
+	git_object_free(revspec.to);
+	return error;
+}
+
+int git_revwalk_hide_ref(git_revwalk *walk, const char *refname)
+{
+	assert(walk && refname);
+	return push_ref(walk, refname, 1, false);
+}
+
+static int revwalk_enqueue_timesort(git_revwalk *walk, git_commit_list_node *commit)
+{
+	return git_pqueue_insert(&walk->iterator_time, commit);
+}
+
+static int revwalk_enqueue_unsorted(git_revwalk *walk, git_commit_list_node *commit)
+{
+	return git_commit_list_insert(commit, &walk->iterator_rand) ? 0 : -1;
+}
+
+static int revwalk_next_timesort(git_commit_list_node **object_out, git_revwalk *walk)
+{
+	int error;
+	git_commit_list_node *next;
+
+	while ((next = git_pqueue_pop(&walk->iterator_time)) != NULL)
+		if (!next->uninteresting) {
+			if ((error = process_commit_parents(walk, next)) < 0)
+				return error;
+
+			*object_out = next;
+			return 0;
+		}
+
+	giterr_clear();
+	return GIT_ITEROVER;
+}
+
+static int revwalk_next_unsorted(git_commit_list_node **object_out, git_revwalk *walk)
+{
+	int error;
+	git_commit_list_node *next;
+
+	while ((next = git_commit_list_pop(&walk->iterator_rand)) != NULL)
+		if (!next->uninteresting) {
+			if ((error = process_commit_parents(walk, next)) < 0)
+				return error;
+
+			*object_out = next;
+			return 0;
+		}
+
+	giterr_clear();
+	return GIT_ITEROVER;
+}
+
+static int revwalk_next_toposort(git_commit_list_node **object_out, git_revwalk *walk)
+{
+	git_commit_list_node *next;
+	unsigned short i, max;
+
+	for (;;) {
+		next = git_commit_list_pop(&walk->iterator_topo);
+		if (next == NULL) {
+			giterr_clear();
+			return GIT_ITEROVER;
+		}
+
+		if (next->in_degree > 0) {
+			next->topo_delay = 1;
+			continue;
+		}
+
+
+		max = next->out_degree;
+		if (walk->first_parent && next->out_degree)
+			max = 1;
+
+		for (i = 0; i < max; ++i) {
+			git_commit_list_node *parent = next->parents[i];
+
+			if (--parent->in_degree == 0 && parent->topo_delay) {
+				parent->topo_delay = 0;
+				if (git_commit_list_insert(parent, &walk->iterator_topo) == NULL)
+					return -1;
+			}
+		}
+
+		*object_out = next;
+		return 0;
+	}
+}
+
+static int revwalk_next_reverse(git_commit_list_node **object_out, git_revwalk *walk)
+{
+	*object_out = git_commit_list_pop(&walk->iterator_reverse);
+	return *object_out ? 0 : GIT_ITEROVER;
+}
+
+
+static int interesting(git_pqueue *list)
+{
+	size_t i;
+
+	for (i = 0; i < git_pqueue_size(list); i++) {
+		git_commit_list_node *commit = git_pqueue_get(list, i);
+		if (!commit->uninteresting)
+			return 1;
+	}
+
+	return 0;
+}
+
+static int contains(git_pqueue *list, git_commit_list_node *node)
+{
+	size_t i;
+
+	for (i = 0; i < git_pqueue_size(list); i++) {
+		git_commit_list_node *commit = git_pqueue_get(list, i);
+		if (commit == node)
+			return 1;
+	}
+
+	return 0;
+}
+
+static int premark_uninteresting(git_revwalk *walk)
+{
+	int error = 0;
+	unsigned short i;
+	git_pqueue q;
+	git_commit_list *list;
+	git_commit_list_node *commit, *parent;
+
+	if ((error = git_pqueue_init(&q, 0, 8, git_commit_list_time_cmp)) < 0)
+		return error;
+
+	for (list = walk->user_input; list; list = list->next) {
+		if ((error = git_commit_list_parse(walk, list->item)) < 0)
+			goto cleanup;
+
+		if ((error = git_pqueue_insert(&q, list->item)) < 0)
+			goto cleanup;
+	}
+
+	while (interesting(&q)) {
+		commit = git_pqueue_pop(&q);
+
+		for (i = 0; i < commit->out_degree; i++) {
+			parent = commit->parents[i];
+
+			if ((error = git_commit_list_parse(walk, parent)) < 0)
+				goto cleanup;
+
+			if (commit->uninteresting)
+				parent->uninteresting = 1;
+
+			if (contains(&q, parent))
+				continue;
+
+			if ((error = git_pqueue_insert(&q, parent)) < 0)
+				goto cleanup;
+		}
+	}
+
+cleanup:
+	git_pqueue_free(&q);
+	return error;
+}
+
+static int prepare_walk(git_revwalk *walk)
+{
+	int error;
+	git_commit_list *list;
+	git_commit_list_node *next;
+
+	/* If there were no pushes, we know that the walk is already over */
+	if (!walk->did_push) {
+		giterr_clear();
+		return GIT_ITEROVER;
+	}
+
+	if (walk->did_hide && (error = premark_uninteresting(walk)) < 0)
+		return error;
+
+	for (list = walk->user_input; list; list = list->next) {
+		if (process_commit(walk, list->item, list->item->uninteresting) < 0)
+			return -1;
+	}
+
+
+	if (walk->sorting & GIT_SORT_TOPOLOGICAL) {
+		unsigned short i;
+
+		while ((error = walk->get_next(&next, walk)) == 0) {
+			for (i = 0; i < next->out_degree; ++i) {
+				git_commit_list_node *parent = next->parents[i];
+				parent->in_degree++;
+			}
+
+			if (git_commit_list_insert(next, &walk->iterator_topo) == NULL)
+				return -1;
+		}
+
+		if (error != GIT_ITEROVER)
+			return error;
+
+		walk->get_next = &revwalk_next_toposort;
+	}
+
+	if (walk->sorting & GIT_SORT_REVERSE) {
+
+		while ((error = walk->get_next(&next, walk)) == 0)
+			if (git_commit_list_insert(next, &walk->iterator_reverse) == NULL)
+				return -1;
+
+		if (error != GIT_ITEROVER)
+			return error;
+
+		walk->get_next = &revwalk_next_reverse;
+	}
+
+	walk->walking = 1;
+	return 0;
+}
+
+
+int git_revwalk_new(git_revwalk **revwalk_out, git_repository *repo)
+{
+	git_revwalk *walk = git__calloc(1, sizeof(git_revwalk));
+	GITERR_CHECK_ALLOC(walk);
+
+	walk->commits = git_oidmap_alloc();
+	GITERR_CHECK_ALLOC(walk->commits);
+
+	if (git_pqueue_init(
+			&walk->iterator_time, 0, 8, git_commit_list_time_cmp) < 0 ||
+		git_pool_init(&walk->commit_pool, 1,
+			git_pool__suggest_items_per_page(COMMIT_ALLOC) * COMMIT_ALLOC) < 0)
+		return -1;
+
+	walk->get_next = &revwalk_next_unsorted;
+	walk->enqueue = &revwalk_enqueue_unsorted;
+
+	walk->repo = repo;
+
+	if (git_repository_odb(&walk->odb, repo) < 0) {
+		git_revwalk_free(walk);
+		return -1;
+	}
+
+	*revwalk_out = walk;
+	return 0;
+}
+
+void git_revwalk_free(git_revwalk *walk)
+{
+	if (walk == NULL)
+		return;
+
+	git_revwalk_reset(walk);
+	git_odb_free(walk->odb);
+
+	git_oidmap_free(walk->commits);
+	git_pool_clear(&walk->commit_pool);
+	git_pqueue_free(&walk->iterator_time);
+	git__free(walk);
+}
+
+git_repository *git_revwalk_repository(git_revwalk *walk)
+{
+	assert(walk);
+	return walk->repo;
+}
+
+void git_revwalk_sorting(git_revwalk *walk, unsigned int sort_mode)
+{
+	assert(walk);
+
+	if (walk->walking)
+		git_revwalk_reset(walk);
+
+	walk->sorting = sort_mode;
+
+	if (walk->sorting & GIT_SORT_TIME) {
+		walk->get_next = &revwalk_next_timesort;
+		walk->enqueue = &revwalk_enqueue_timesort;
+	} else {
+		walk->get_next = &revwalk_next_unsorted;
+		walk->enqueue = &revwalk_enqueue_unsorted;
+	}
+}
+
+void git_revwalk_simplify_first_parent(git_revwalk *walk)
+{
+	walk->first_parent = 1;
+}
+
+int git_revwalk_next(git_oid *oid, git_revwalk *walk)
+{
+	int error;
+	git_commit_list_node *next;
+
+	assert(walk && oid);
+
+	if (!walk->walking) {
+		if ((error = prepare_walk(walk)) < 0)
+			return error;
+	}
+
+	error = walk->get_next(&next, walk);
+
+	if (error == GIT_ITEROVER) {
+		git_revwalk_reset(walk);
+		giterr_clear();
+		return GIT_ITEROVER;
+	}
+
+	if (!error)
+		git_oid_cpy(oid, &next->oid);
+
+	return error;
+}
+
+void git_revwalk_reset(git_revwalk *walk)
+{
+	git_commit_list_node *commit;
+
+	assert(walk);
+
+	kh_foreach_value(walk->commits, commit, {
+		commit->seen = 0;
+		commit->in_degree = 0;
+		commit->topo_delay = 0;
+		commit->uninteresting = 0;
+		commit->flags = 0;
+		});
+
+	git_pqueue_clear(&walk->iterator_time);
+	git_commit_list_free(&walk->iterator_topo);
+	git_commit_list_free(&walk->iterator_rand);
+	git_commit_list_free(&walk->iterator_reverse);
+	git_commit_list_free(&walk->user_input);
+	walk->first_parent = 0;
+	walk->walking = 0;
+	walk->did_push = walk->did_hide = 0;
+}
+
+int git_revwalk_add_hide_cb(
+	git_revwalk *walk,
+	git_revwalk_hide_cb hide_cb,
+	void *payload)
+{
+	assert(walk);
+
+	if (walk->walking)
+		git_revwalk_reset(walk);
+
+	if (walk->hide_cb) {
+		/* There is already a callback added */
+		giterr_set(GITERR_INVALID, "There is already a callback added to hide commits in revision walker.");
+		return -1;
+	}
+
+	walk->hide_cb = hide_cb;
+	walk->hide_cb_payload = payload;
+
+	return 0;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/revwalk.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/revwalk.h
new file mode 100755
index 0000000..6b363d4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/revwalk.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_revwalk_h__
+#define INCLUDE_revwalk_h__
+
+#include "git2/revwalk.h"
+#include "oidmap.h"
+#include "commit_list.h"
+#include "pqueue.h"
+#include "pool.h"
+#include "vector.h"
+
+#include "oidmap.h"
+
+struct git_revwalk {
+	git_repository *repo;
+	git_odb *odb;
+
+	git_oidmap *commits;
+	git_pool commit_pool;
+
+	git_commit_list *iterator_topo;
+	git_commit_list *iterator_rand;
+	git_commit_list *iterator_reverse;
+	git_pqueue iterator_time;
+
+	int (*get_next)(git_commit_list_node **, git_revwalk *);
+	int (*enqueue)(git_revwalk *, git_commit_list_node *);
+
+	unsigned walking:1,
+		first_parent: 1,
+		did_hide: 1,
+		did_push: 1;
+	unsigned int sorting;
+
+	/* the pushes and hides */
+	git_commit_list *user_input;
+
+	/* hide callback */
+	git_revwalk_hide_cb hide_cb;
+	void *hide_cb_payload;
+};
+
+git_commit_list_node *git_revwalk__commit_lookup(git_revwalk *walk, const git_oid *oid);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/settings.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/settings.c
new file mode 100755
index 0000000..2097ca3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/settings.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifdef GIT_OPENSSL
+# include <openssl/err.h>
+#endif
+
+#include <git2.h>
+#include "common.h"
+#include "sysdir.h"
+#include "cache.h"
+#include "global.h"
+
+void git_libgit2_version(int *major, int *minor, int *rev)
+{
+	*major = LIBGIT2_VER_MAJOR;
+	*minor = LIBGIT2_VER_MINOR;
+	*rev = LIBGIT2_VER_REVISION;
+}
+
+int git_libgit2_features()
+{
+	return 0
+#ifdef GIT_THREADS
+		| GIT_FEATURE_THREADS
+#endif
+#if defined(GIT_OPENSSL) || defined(GIT_WINHTTP) || defined(GIT_SECURE_TRANSPORT)
+		| GIT_FEATURE_HTTPS
+#endif
+#if defined(GIT_SSH)
+		| GIT_FEATURE_SSH
+#endif
+	;
+}
+
+/* Declarations for tuneable settings */
+extern size_t git_mwindow__window_size;
+extern size_t git_mwindow__mapped_limit;
+
+static int config_level_to_sysdir(int config_level)
+{
+	int val = -1;
+
+	switch (config_level) {
+	case GIT_CONFIG_LEVEL_SYSTEM: val = GIT_SYSDIR_SYSTEM; break;
+	case GIT_CONFIG_LEVEL_XDG:    val = GIT_SYSDIR_XDG; break;
+	case GIT_CONFIG_LEVEL_GLOBAL: val = GIT_SYSDIR_GLOBAL; break;
+	default:
+		giterr_set(
+			GITERR_INVALID, "Invalid config path selector %d", config_level);
+	}
+
+	return val;
+}
+
+int git_libgit2_opts(int key, ...)
+{
+	int error = 0;
+	va_list ap;
+
+	va_start(ap, key);
+
+	switch (key) {
+	case GIT_OPT_SET_MWINDOW_SIZE:
+		git_mwindow__window_size = va_arg(ap, size_t);
+		break;
+
+	case GIT_OPT_GET_MWINDOW_SIZE:
+		*(va_arg(ap, size_t *)) = git_mwindow__window_size;
+		break;
+
+	case GIT_OPT_SET_MWINDOW_MAPPED_LIMIT:
+		git_mwindow__mapped_limit = va_arg(ap, size_t);
+		break;
+
+	case GIT_OPT_GET_MWINDOW_MAPPED_LIMIT:
+		*(va_arg(ap, size_t *)) = git_mwindow__mapped_limit;
+		break;
+
+	case GIT_OPT_GET_SEARCH_PATH:
+		if ((error = config_level_to_sysdir(va_arg(ap, int))) >= 0) {
+			git_buf *out = va_arg(ap, git_buf *);
+			const git_buf *tmp;
+
+			git_buf_sanitize(out);
+			if ((error = git_sysdir_get(&tmp, error)) < 0)
+				break;
+
+			error = git_buf_sets(out, tmp->ptr);
+		}
+		break;
+
+	case GIT_OPT_SET_SEARCH_PATH:
+		if ((error = config_level_to_sysdir(va_arg(ap, int))) >= 0)
+			error = git_sysdir_set(error, va_arg(ap, const char *));
+		break;
+
+	case GIT_OPT_SET_CACHE_OBJECT_LIMIT:
+		{
+			git_otype type = (git_otype)va_arg(ap, int);
+			size_t size = va_arg(ap, size_t);
+			error = git_cache_set_max_object_size(type, size);
+			break;
+		}
+
+	case GIT_OPT_SET_CACHE_MAX_SIZE:
+		git_cache__max_storage = va_arg(ap, ssize_t);
+		break;
+
+	case GIT_OPT_ENABLE_CACHING:
+		git_cache__enabled = (va_arg(ap, int) != 0);
+		break;
+
+	case GIT_OPT_GET_CACHED_MEMORY:
+		*(va_arg(ap, ssize_t *)) = git_cache__current_storage.val;
+		*(va_arg(ap, ssize_t *)) = git_cache__max_storage;
+		break;
+
+	case GIT_OPT_GET_TEMPLATE_PATH:
+		{
+			git_buf *out = va_arg(ap, git_buf *);
+			const git_buf *tmp;
+
+			git_buf_sanitize(out);
+			if ((error = git_sysdir_get(&tmp, GIT_SYSDIR_TEMPLATE)) < 0)
+				break;
+
+			error = git_buf_sets(out, tmp->ptr);
+		}
+		break;
+
+	case GIT_OPT_SET_TEMPLATE_PATH:
+		error = git_sysdir_set(GIT_SYSDIR_TEMPLATE, va_arg(ap, const char *));
+		break;
+
+	case GIT_OPT_SET_SSL_CERT_LOCATIONS:
+#ifdef GIT_OPENSSL
+		{
+			const char *file = va_arg(ap, const char *);
+			const char *path = va_arg(ap, const char *);
+			if (!SSL_CTX_load_verify_locations(git__ssl_ctx, file, path)) {
+				giterr_set(GITERR_NET, "SSL error: %s",
+					ERR_error_string(ERR_get_error(), NULL));
+				error = -1;
+			}
+		}
+#else
+		giterr_set(GITERR_NET, "Cannot set certificate locations: OpenSSL is not enabled");
+		error = -1;
+#endif
+		break;
+	}
+
+	va_end(ap);
+
+	return error;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sha1_lookup.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sha1_lookup.c
new file mode 100755
index 0000000..c6b5613
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sha1_lookup.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include <stdio.h>
+
+#include "sha1_lookup.h"
+#include "common.h"
+#include "oid.h"
+
+/*
+ * Conventional binary search loop looks like this:
+ *
+ *	unsigned lo, hi;
+ *		do {
+ *				unsigned mi = (lo + hi) / 2;
+ *				int cmp = "entry pointed at by mi" minus "target";
+ *				if (!cmp)
+ *						return (mi is the wanted one)
+ *				if (cmp > 0)
+ *						hi = mi; "mi is larger than target"
+ *				else
+ *						lo = mi+1; "mi is smaller than target"
+ *		} while (lo < hi);
+ *
+ * The invariants are:
+ *
+ * - When entering the loop, lo points at a slot that is never
+ *	above the target (it could be at the target), hi points at a
+ *	slot that is guaranteed to be above the target (it can never
+ *	be at the target).
+ *
+ * - We find a point 'mi' between lo and hi (mi could be the same
+ *	as lo, but never can be as same as hi), and check if it hits
+ *	the target. There are three cases:
+ *
+ *	- if it is a hit, we are happy.
+ *
+ *	- if it is strictly higher than the target, we set it to hi,
+ *		and repeat the search.
+ *
+ *	- if it is strictly lower than the target, we update lo to
+ *		one slot after it, because we allow lo to be at the target.
+ *
+ *	If the loop exits, there is no matching entry.
+ *
+ * When choosing 'mi', we do not have to take the "middle" but
+ * anywhere in between lo and hi, as long as lo <= mi < hi is
+ * satisfied. When we somehow know that the distance between the
+ * target and lo is much shorter than the target and hi, we could
+ * pick mi that is much closer to lo than the midway.
+ *
+ * Now, we can take advantage of the fact that SHA-1 is a good hash
+ * function, and as long as there are enough entries in the table, we
+ * can expect uniform distribution. An entry that begins with for
+ * example "deadbeef..." is much likely to appear much later than in
+ * the midway of the table. It can reasonably be expected to be near
+ * 87% (222/256) from the top of the table.
+ *
+ * However, we do not want to pick "mi" too precisely. If the entry at
+ * the 87% in the above example turns out to be higher than the target
+ * we are looking for, we would end up narrowing the search space down
+ * only by 13%, instead of 50% we would get if we did a simple binary
+ * search. So we would want to hedge our bets by being less aggressive.
+ *
+ * The table at "table" holds at least "nr" entries of "elem_size"
+ * bytes each. Each entry has the SHA-1 key at "key_offset". The
+ * table is sorted by the SHA-1 key of the entries. The caller wants
+ * to find the entry with "key", and knows that the entry at "lo" is
+ * not higher than the entry it is looking for, and that the entry at
+ * "hi" is higher than the entry it is looking for.
+ */
+int sha1_entry_pos(const void *table,
+			size_t elem_size,
+			size_t key_offset,
+			unsigned lo, unsigned hi, unsigned nr,
+			const unsigned char *key)
+{
+	const unsigned char *base = (const unsigned char*)table;
+	const unsigned char *hi_key, *lo_key;
+	unsigned ofs_0;
+
+	if (!nr || lo >= hi)
+		return -1;
+
+	if (nr == hi)
+		hi_key = NULL;
+	else
+		hi_key = base + elem_size * hi + key_offset;
+	lo_key = base + elem_size * lo + key_offset;
+
+	ofs_0 = 0;
+	do {
+		int cmp;
+		unsigned ofs, mi, range;
+		unsigned lov, hiv, kyv;
+		const unsigned char *mi_key;
+
+		range = hi - lo;
+		if (hi_key) {
+			for (ofs = ofs_0; ofs < 20; ofs++)
+				if (lo_key[ofs] != hi_key[ofs])
+					break;
+			ofs_0 = ofs;
+			/*
+			 * byte 0 thru (ofs-1) are the same between
+			 * lo and hi; ofs is the first byte that is
+			 * different.
+			 *
+			 * If ofs==20, then no bytes are different,
+			 * meaning we have entries with duplicate
+			 * keys. We know that we are in a solid run
+			 * of this entry (because the entries are
+			 * sorted, and our lo and hi are the same,
+			 * there can be nothing but this single key
+			 * in between). So we can stop the search.
+			 * Either one of these entries is it (and
+			 * we do not care which), or we do not have
+			 * it.
+			 *
+			 * Furthermore, we know that one of our
+			 * endpoints must be the edge of the run of
+			 * duplicates. For example, given this
+			 * sequence:
+			 *
+			 *     idx 0 1 2 3 4 5
+			 *     key A C C C C D
+			 *
+			 * If we are searching for "B", we might
+			 * hit the duplicate run at lo=1, hi=3
+			 * (e.g., by first mi=3, then mi=0). But we
+			 * can never have lo > 1, because B < C.
+			 * That is, if our key is less than the
+			 * run, we know that "lo" is the edge, but
+			 * we can say nothing of "hi". Similarly,
+			 * if our key is greater than the run, we
+			 * know that "hi" is the edge, but we can
+			 * say nothing of "lo".
+			 *
+			 * Therefore if we do not find it, we also
+			 * know where it would go if it did exist:
+			 * just on the far side of the edge that we
+			 * know about.
+			 */
+			if (ofs == 20) {
+				mi = lo;
+				mi_key = base + elem_size * mi + key_offset;
+				cmp = memcmp(mi_key, key, 20);
+				if (!cmp)
+					return mi;
+				if (cmp < 0)
+					return -1 - hi;
+				else
+					return -1 - lo;
+			}
+
+			hiv = hi_key[ofs_0];
+			if (ofs_0 < 19)
+				hiv = (hiv << 8) | hi_key[ofs_0+1];
+		} else {
+			hiv = 256;
+			if (ofs_0 < 19)
+				hiv <<= 8;
+		}
+		lov = lo_key[ofs_0];
+		kyv = key[ofs_0];
+		if (ofs_0 < 19) {
+			lov = (lov << 8) | lo_key[ofs_0+1];
+			kyv = (kyv << 8) | key[ofs_0+1];
+		}
+		assert(lov < hiv);
+
+		if (kyv < lov)
+			return -1 - lo;
+		if (hiv < kyv)
+			return -1 - hi;
+
+		/*
+		 * Even if we know the target is much closer to 'hi'
+		 * than 'lo', if we pick too precisely and overshoot
+		 * (e.g. when we know 'mi' is closer to 'hi' than to
+		 * 'lo', pick 'mi' that is higher than the target), we
+		 * end up narrowing the search space by a smaller
+		 * amount (i.e. the distance between 'mi' and 'hi')
+		 * than what we would have (i.e. about half of 'lo'
+		 * and 'hi'). Hedge our bets to pick 'mi' less
+		 * aggressively, i.e. make 'mi' a bit closer to the
+		 * middle than we would otherwise pick.
+		 */
+		kyv = (kyv * 6 + lov + hiv) / 8;
+		if (lov < hiv - 1) {
+			if (kyv == lov)
+				kyv++;
+			else if (kyv == hiv)
+				kyv--;
+		}
+		mi = (range - 1) * (kyv - lov) / (hiv - lov) + lo;
+
+#ifdef INDEX_DEBUG_LOOKUP
+		printf("lo %u hi %u rg %u mi %u ", lo, hi, range, mi);
+		printf("ofs %u lov %x, hiv %x, kyv %x\n",
+				ofs_0, lov, hiv, kyv);
+#endif
+
+		if (!(lo <= mi && mi < hi)) {
+			giterr_set(GITERR_INVALID, "Assertion failure. Binary search invariant is false");
+			return -1;
+		}
+
+		mi_key = base + elem_size * mi + key_offset;
+		cmp = memcmp(mi_key + ofs_0, key + ofs_0, 20 - ofs_0);
+		if (!cmp)
+			return mi;
+		if (cmp > 0) {
+			hi = mi;
+			hi_key = mi_key;
+		} else {
+			lo = mi + 1;
+			lo_key = mi_key + elem_size;
+		}
+	} while (lo < hi);
+	return -((int)lo)-1;
+}
+
+int sha1_position(const void *table,
+			size_t stride,
+			unsigned lo, unsigned hi,
+			const unsigned char *key)
+{
+	const unsigned char *base = table;
+
+	do {
+		unsigned mi = (lo + hi) / 2;
+		int cmp = git_oid__hashcmp(base + mi * stride, key);
+
+		if (!cmp)
+			return mi;
+
+		if (cmp > 0)
+			hi = mi;
+		else
+			lo = mi+1;
+	} while (lo < hi);
+
+	return -((int)lo)-1;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sha1_lookup.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sha1_lookup.h
new file mode 100755
index 0000000..3799620
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sha1_lookup.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sha1_lookup_h__
+#define INCLUDE_sha1_lookup_h__
+
+#include <stdlib.h>
+
+int sha1_entry_pos(const void *table,
+			size_t elem_size,
+			size_t key_offset,
+			unsigned lo, unsigned hi, unsigned nr,
+			const unsigned char *key);
+
+int sha1_position(const void *table,
+			size_t stride,
+			unsigned lo, unsigned hi,
+			const unsigned char *key);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/signature.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/signature.c
new file mode 100755
index 0000000..818cd30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/signature.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "signature.h"
+#include "repository.h"
+#include "git2/common.h"
+#include "posix.h"
+
+void git_signature_free(git_signature *sig)
+{
+	if (sig == NULL)
+		return;
+
+	git__free(sig->name);
+	sig->name = NULL;
+	git__free(sig->email);
+	sig->email = NULL;
+	git__free(sig);
+}
+
+static int signature_error(const char *msg)
+{
+	giterr_set(GITERR_INVALID, "Failed to parse signature - %s", msg);
+	return -1;
+}
+
+static bool contains_angle_brackets(const char *input)
+{
+	return strchr(input, '<') != NULL || strchr(input, '>') != NULL;
+}
+
+static char *extract_trimmed(const char *ptr, size_t len)
+{
+	while (len && git__isspace(ptr[0])) {
+		ptr++; len--;
+	}
+
+	while (len && git__isspace(ptr[len - 1])) {
+		len--;
+	}
+
+	return git__substrdup(ptr, len);
+}
+
+int git_signature_new(git_signature **sig_out, const char *name, const char *email, git_time_t time, int offset)
+{
+	git_signature *p = NULL;
+
+	assert(name && email);
+
+	*sig_out = NULL;
+
+	if (contains_angle_brackets(name) ||
+		contains_angle_brackets(email)) {
+		return signature_error(
+			"Neither `name` nor `email` should contain angle brackets chars.");
+	}
+
+	p = git__calloc(1, sizeof(git_signature));
+	GITERR_CHECK_ALLOC(p);
+
+	p->name = extract_trimmed(name, strlen(name));
+	p->email = extract_trimmed(email, strlen(email));
+
+	if (p->name == NULL || p->email == NULL)
+		return -1; /* oom */
+
+	if (p->name[0] == '\0' || p->email[0] == '\0') {
+		git_signature_free(p);
+		return signature_error("Signature cannot have an empty name or email");
+	}
+
+	p->when.time = time;
+	p->when.offset = offset;
+
+	*sig_out = p;
+	return 0;
+}
+
+int git_signature_dup(git_signature **dest, const git_signature *source)
+{
+	git_signature *signature;
+
+	if (source == NULL)
+		return 0;
+
+	signature = git__calloc(1, sizeof(git_signature));
+	GITERR_CHECK_ALLOC(signature);
+
+	signature->name = git__strdup(source->name);
+	GITERR_CHECK_ALLOC(signature->name);
+
+	signature->email = git__strdup(source->email);
+	GITERR_CHECK_ALLOC(signature->email);
+
+	signature->when.time = source->when.time;
+	signature->when.offset = source->when.offset;
+
+	*dest = signature;
+
+	return 0;
+}
+
+int git_signature__pdup(git_signature **dest, const git_signature *source, git_pool *pool)
+{
+	git_signature *signature;
+
+	if (source == NULL)
+		return 0;
+
+	signature = git_pool_mallocz(pool, sizeof(git_signature));
+	GITERR_CHECK_ALLOC(signature);
+
+	signature->name = git_pool_strdup(pool, source->name);
+	GITERR_CHECK_ALLOC(signature->name);
+
+	signature->email = git_pool_strdup(pool, source->email);
+	GITERR_CHECK_ALLOC(signature->email);
+
+	signature->when.time = source->when.time;
+	signature->when.offset = source->when.offset;
+
+	*dest = signature;
+
+	return 0;
+}
+
+int git_signature_now(git_signature **sig_out, const char *name, const char *email)
+{
+	time_t now;
+	time_t offset;
+	struct tm *utc_tm;
+	git_signature *sig;
+	struct tm _utc;
+
+	*sig_out = NULL;
+
+	/*
+	 * Get the current time as seconds since the epoch and
+	 * transform that into a tm struct containing the time at
+	 * UTC. Give that to mktime which considers it a local time
+	 * (tm_isdst = -1 asks it to take DST into account) and gives
+	 * us that time as seconds since the epoch. The difference
+	 * between its return value and 'now' is our offset to UTC.
+	 */
+	time(&now);
+	utc_tm = p_gmtime_r(&now, &_utc);
+	utc_tm->tm_isdst = -1;
+	offset = (time_t)difftime(now, mktime(utc_tm));
+	offset /= 60;
+
+	if (git_signature_new(&sig, name, email, now, (int)offset) < 0)
+		return -1;
+
+	*sig_out = sig;
+
+	return 0;
+}
+
+int git_signature_default(git_signature **out, git_repository *repo)
+{
+	int error;
+	git_config *cfg;
+	const char *user_name, *user_email;
+
+	if ((error = git_repository_config_snapshot(&cfg, repo)) < 0)
+		return error;
+
+	if (!(error = git_config_get_string(&user_name, cfg, "user.name")) &&
+		!(error = git_config_get_string(&user_email, cfg, "user.email")))
+		error = git_signature_now(out, user_name, user_email);
+
+	git_config_free(cfg);
+	return error;
+}
+
+int git_signature__parse(git_signature *sig, const char **buffer_out,
+		const char *buffer_end, const char *header, char ender)
+{
+	const char *buffer = *buffer_out;
+	const char *email_start, *email_end;
+
+	memset(sig, 0, sizeof(git_signature));
+
+	if ((buffer_end = memchr(buffer, ender, buffer_end - buffer)) == NULL)
+		return signature_error("no newline given");
+
+	if (header) {
+		const size_t header_len = strlen(header);
+
+		if (buffer + header_len >= buffer_end || memcmp(buffer, header, header_len) != 0)
+			return signature_error("expected prefix doesn't match actual");
+
+		buffer += header_len;
+	}
+
+	email_start = git__memrchr(buffer, '<', buffer_end - buffer);
+	email_end = git__memrchr(buffer, '>', buffer_end - buffer);
+
+	if (!email_start || !email_end || email_end <= email_start)
+		return signature_error("malformed e-mail");
+
+	email_start += 1;
+	sig->name = extract_trimmed(buffer, email_start - buffer - 1);
+	sig->email = extract_trimmed(email_start, email_end - email_start);
+
+	/* Do we even have a time at the end of the signature? */
+	if (email_end + 2 < buffer_end) {
+		const char *time_start = email_end + 2;
+		const char *time_end;
+
+		if (git__strtol64(&sig->when.time, time_start, &time_end, 10) < 0)
+			return signature_error("invalid Unix timestamp");
+
+		/* do we have a timezone? */
+		if (time_end + 1 < buffer_end) {
+			int offset, hours, mins;
+			const char *tz_start, *tz_end;
+
+			tz_start = time_end + 1;
+
+			if ((tz_start[0] != '-' && tz_start[0] != '+') ||
+				git__strtol32(&offset, tz_start + 1, &tz_end, 10) < 0) {
+				//malformed timezone, just assume it's zero
+				offset = 0;
+			}
+
+			hours = offset / 100;
+			mins = offset % 100;
+
+			/*
+			 * only store timezone if it's not overflowing;
+			 * see http://www.worldtimezone.com/faq.html
+			 */
+			if (hours < 14 && mins < 59) {
+				sig->when.offset = (hours * 60) + mins;
+				if (tz_start[0] == '-')
+					sig->when.offset = -sig->when.offset;
+			}
+		}
+	}
+
+	*buffer_out = buffer_end + 1;
+	return 0;
+}
+
+void git_signature__writebuf(git_buf *buf, const char *header, const git_signature *sig)
+{
+	int offset, hours, mins;
+	char sign;
+
+	assert(buf && sig);
+
+	offset = sig->when.offset;
+	sign = (sig->when.offset < 0) ? '-' : '+';
+
+	if (offset < 0)
+		offset = -offset;
+
+	hours = offset / 60;
+	mins = offset % 60;
+
+	git_buf_printf(buf, "%s%s <%s> %u %c%02d%02d\n",
+			header ? header : "", sig->name, sig->email,
+			(unsigned)sig->when.time, sign, hours, mins);
+}
+
+bool git_signature__equal(const git_signature *one, const git_signature *two)
+{
+	assert(one && two);
+
+	return
+		git__strcmp(one->name, two->name) == 0 &&
+		git__strcmp(one->email, two->email) == 0 &&
+		one->when.time == two->when.time &&
+		one->when.offset == two->when.offset;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/signature.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/signature.h
new file mode 100755
index 0000000..75265df
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/signature.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_signature_h__
+#define INCLUDE_signature_h__
+
+#include "git2/common.h"
+#include "git2/signature.h"
+#include "repository.h"
+#include <time.h>
+
+int git_signature__parse(git_signature *sig, const char **buffer_out, const char *buffer_end, const char *header, char ender);
+void git_signature__writebuf(git_buf *buf, const char *header, const git_signature *sig);
+bool git_signature__equal(const git_signature *one, const git_signature *two);
+
+int git_signature__pdup(git_signature **dest, const git_signature *source, git_pool *pool);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/socket_stream.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/socket_stream.c
new file mode 100755
index 0000000..71f4911
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/socket_stream.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "posix.h"
+#include "netops.h"
+#include "stream.h"
+#include "socket_stream.h"
+
+#ifndef _WIN32
+#	include <sys/types.h>
+#	include <sys/socket.h>
+#	include <sys/select.h>
+#	include <sys/time.h>
+#	include <netdb.h>
+#	include <netinet/in.h>
+#       include <arpa/inet.h>
+#else
+#	include <winsock2.h>
+#	include <ws2tcpip.h>
+#	ifdef _MSC_VER
+#		pragma comment(lib, "ws2_32")
+#	endif
+#endif
+
+#ifdef GIT_WIN32
+static void net_set_error(const char *str)
+{
+	int error = WSAGetLastError();
+	char * win32_error = git_win32_get_error_message(error);
+
+	if (win32_error) {
+		giterr_set(GITERR_NET, "%s: %s", str, win32_error);
+		git__free(win32_error);
+	} else {
+		giterr_set(GITERR_NET, str);
+	}
+}
+#else
+static void net_set_error(const char *str)
+{
+	giterr_set(GITERR_NET, "%s: %s", str, strerror(errno));
+}
+#endif
+
+static int close_socket(GIT_SOCKET s)
+{
+	if (s == INVALID_SOCKET)
+		return 0;
+
+#ifdef GIT_WIN32
+	if (SOCKET_ERROR == closesocket(s))
+		return -1;
+
+	if (0 != WSACleanup()) {
+		giterr_set(GITERR_OS, "Winsock cleanup failed");
+		return -1;
+	}
+
+	return 0;
+#else
+	return close(s);
+#endif
+
+}
+
+int socket_connect(git_stream *stream)
+{
+	struct addrinfo *info = NULL, *p;
+	struct addrinfo hints;
+	git_socket_stream *st = (git_socket_stream *) stream;
+	GIT_SOCKET s = INVALID_SOCKET;
+	int ret;
+
+#ifdef GIT_WIN32
+	/* on win32, the WSA context needs to be initialized
+	 * before any socket calls can be performed */
+	WSADATA wsd;
+
+	if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
+		giterr_set(GITERR_OS, "Winsock init failed");
+		return -1;
+	}
+
+	if (LOBYTE(wsd.wVersion) != 2 || HIBYTE(wsd.wVersion) != 2) {
+		WSACleanup();
+		giterr_set(GITERR_OS, "Winsock init failed");
+		return -1;
+	}
+#endif
+
+	memset(&hints, 0x0, sizeof(struct addrinfo));
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_family = AF_UNSPEC;
+
+	if ((ret = p_getaddrinfo(st->host, st->port, &hints, &info)) != 0) {
+		giterr_set(GITERR_NET,
+			   "Failed to resolve address for %s: %s", st->host, p_gai_strerror(ret));
+		return -1;
+	}
+
+	for (p = info; p != NULL; p = p->ai_next) {
+		s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
+
+		if (s == INVALID_SOCKET) {
+			net_set_error("error creating socket");
+			break;
+		}
+
+		if (connect(s, p->ai_addr, (socklen_t)p->ai_addrlen) == 0)
+			break;
+
+		/* If we can't connect, try the next one */
+		close_socket(s);
+		s = INVALID_SOCKET;
+	}
+
+	/* Oops, we couldn't connect to any address */
+	if (s == INVALID_SOCKET && p == NULL) {
+		giterr_set(GITERR_OS, "Failed to connect to %s", st->host);
+		p_freeaddrinfo(info);
+		return -1;
+	}
+
+	st->s = s;
+	p_freeaddrinfo(info);
+	return 0;
+}
+
+ssize_t socket_write(git_stream *stream, const char *data, size_t len, int flags)
+{
+	ssize_t ret;
+	size_t off = 0;
+	git_socket_stream *st = (git_socket_stream *) stream;
+
+	while (off < len) {
+		errno = 0;
+		ret = p_send(st->s, data + off, len - off, flags);
+		if (ret < 0) {
+			net_set_error("Error sending data");
+			return -1;
+		}
+
+		off += ret;
+	}
+
+	return off;
+}
+
+ssize_t socket_read(git_stream *stream, void *data, size_t len)
+{
+	ssize_t ret;
+	git_socket_stream *st = (git_socket_stream *) stream;
+
+	if ((ret = p_recv(st->s, data, len, 0)) < 0)
+		net_set_error("Error receiving socket data");
+
+	return ret;
+}
+
+int socket_close(git_stream *stream)
+{
+	git_socket_stream *st = (git_socket_stream *) stream;
+	int error;
+
+	error = close_socket(st->s);
+	st->s = INVALID_SOCKET;
+
+	return error;
+}
+
+void socket_free(git_stream *stream)
+{
+	git_socket_stream *st = (git_socket_stream *) stream;
+
+	git__free(st->host);
+	git__free(st->port);
+	git__free(st);
+}
+
+int git_socket_stream_new(git_stream **out, const char *host, const char *port)
+{
+	git_socket_stream *st;
+
+	assert(out && host);
+
+	st = git__calloc(1, sizeof(git_socket_stream));
+	GITERR_CHECK_ALLOC(st);
+
+	st->host = git__strdup(host);
+	GITERR_CHECK_ALLOC(st->host);
+
+	if (port) {
+		st->port = git__strdup(port);
+		GITERR_CHECK_ALLOC(st->port);
+	}
+
+	st->parent.version = GIT_STREAM_VERSION;
+	st->parent.connect = socket_connect;
+	st->parent.write = socket_write;
+	st->parent.read = socket_read;
+	st->parent.close = socket_close;
+	st->parent.free = socket_free;
+	st->s = INVALID_SOCKET;
+
+	*out = (git_stream *) st;
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/socket_stream.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/socket_stream.h
new file mode 100755
index 0000000..8e9949f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/socket_stream.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_socket_stream_h__
+#define INCLUDE_socket_stream_h__
+
+#include "netops.h"
+
+typedef struct {
+	git_stream parent;
+	char *host;
+	char *port;
+	GIT_SOCKET s;
+} git_socket_stream;
+
+extern int git_socket_stream_new(git_stream **out, const char *host, const char *port);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sortedcache.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sortedcache.c
new file mode 100755
index 0000000..1151757
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sortedcache.c
@@ -0,0 +1,380 @@
+#include "sortedcache.h"
+
+GIT__USE_STRMAP
+
+int git_sortedcache_new(
+	git_sortedcache **out,
+	size_t item_path_offset,
+	git_sortedcache_free_item_fn free_item,
+	void *free_item_payload,
+	git_vector_cmp item_cmp,
+	const char *path)
+{
+	git_sortedcache *sc;
+	size_t pathlen, alloclen;
+
+	pathlen = path ? strlen(path) : 0;
+
+	GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(git_sortedcache), pathlen);
+	GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
+	sc = git__calloc(1, alloclen);
+	GITERR_CHECK_ALLOC(sc);
+
+	if (git_pool_init(&sc->pool, 1, 0) < 0 ||
+		git_vector_init(&sc->items, 4, item_cmp) < 0 ||
+		git_strmap_alloc(&sc->map) < 0)
+		goto fail;
+
+	if (git_rwlock_init(&sc->lock)) {
+		giterr_set(GITERR_OS, "Failed to initialize lock");
+		goto fail;
+	}
+
+	sc->item_path_offset  = item_path_offset;
+	sc->free_item         = free_item;
+	sc->free_item_payload = free_item_payload;
+	GIT_REFCOUNT_INC(sc);
+	if (pathlen)
+		memcpy(sc->path, path, pathlen);
+
+	*out = sc;
+	return 0;
+
+fail:
+	git_strmap_free(sc->map);
+	git_vector_free(&sc->items);
+	git_pool_clear(&sc->pool);
+	git__free(sc);
+	return -1;
+}
+
+void git_sortedcache_incref(git_sortedcache *sc)
+{
+	GIT_REFCOUNT_INC(sc);
+}
+
+const char *git_sortedcache_path(git_sortedcache *sc)
+{
+	return sc->path;
+}
+
+static void sortedcache_clear(git_sortedcache *sc)
+{
+	git_strmap_clear(sc->map);
+
+	if (sc->free_item) {
+		size_t i;
+		void *item;
+
+		git_vector_foreach(&sc->items, i, item) {
+			sc->free_item(sc->free_item_payload, item);
+		}
+	}
+
+	git_vector_clear(&sc->items);
+
+	git_pool_clear(&sc->pool);
+}
+
+static void sortedcache_free(git_sortedcache *sc)
+{
+	/* acquire write lock to make sure everyone else is done */
+	if (git_sortedcache_wlock(sc) < 0)
+		return;
+
+	sortedcache_clear(sc);
+	git_vector_free(&sc->items);
+	git_strmap_free(sc->map);
+
+	git_sortedcache_wunlock(sc);
+
+	git_rwlock_free(&sc->lock);
+	git__free(sc);
+}
+
+void git_sortedcache_free(git_sortedcache *sc)
+{
+	if (!sc)
+		return;
+	GIT_REFCOUNT_DEC(sc, sortedcache_free);
+}
+
+static int sortedcache_copy_item(void *payload, void *tgt_item, void *src_item)
+{
+	git_sortedcache *sc = payload;
+	/* path will already have been copied by upsert */
+	memcpy(tgt_item, src_item, sc->item_path_offset);
+	return 0;
+}
+
+/* copy a sorted cache */
+int git_sortedcache_copy(
+	git_sortedcache **out,
+	git_sortedcache *src,
+	bool lock,
+	int (*copy_item)(void *payload, void *tgt_item, void *src_item),
+	void *payload)
+{
+	int error = 0;
+	git_sortedcache *tgt;
+	size_t i;
+	void *src_item, *tgt_item;
+
+	/* just use memcpy if no special copy fn is passed in */
+	if (!copy_item) {
+		copy_item = sortedcache_copy_item;
+		payload   = src;
+	}
+
+	if ((error = git_sortedcache_new(
+			&tgt, src->item_path_offset,
+			src->free_item, src->free_item_payload,
+			src->items._cmp, src->path)) < 0)
+		return error;
+
+	if (lock && git_sortedcache_rlock(src) < 0) {
+		git_sortedcache_free(tgt);
+		return -1;
+	}
+
+	git_vector_foreach(&src->items, i, src_item) {
+		char *path = ((char *)src_item) + src->item_path_offset;
+
+		if ((error = git_sortedcache_upsert(&tgt_item, tgt, path)) < 0 ||
+			(error = copy_item(payload, tgt_item, src_item)) < 0)
+			break;
+	}
+
+	if (lock)
+		git_sortedcache_runlock(src);
+	if (error)
+		git_sortedcache_free(tgt);
+
+	*out = !error ? tgt : NULL;
+
+	return error;
+}
+
+/* lock sortedcache while making modifications */
+int git_sortedcache_wlock(git_sortedcache *sc)
+{
+	GIT_UNUSED(sc); /* prevent warning when compiled w/o threads */
+
+	if (git_rwlock_wrlock(&sc->lock) < 0) {
+		giterr_set(GITERR_OS, "Unable to acquire write lock on cache");
+		return -1;
+	}
+	return 0;
+}
+
+/* unlock sorted cache when done with modifications */
+void git_sortedcache_wunlock(git_sortedcache *sc)
+{
+	git_vector_sort(&sc->items);
+	git_rwlock_wrunlock(&sc->lock);
+}
+
+/* lock sortedcache for read */
+int git_sortedcache_rlock(git_sortedcache *sc)
+{
+	GIT_UNUSED(sc); /* prevent warning when compiled w/o threads */
+
+	if (git_rwlock_rdlock(&sc->lock) < 0) {
+		giterr_set(GITERR_OS, "Unable to acquire read lock on cache");
+		return -1;
+	}
+	return 0;
+}
+
+/* unlock sorted cache when done reading */
+void git_sortedcache_runlock(git_sortedcache *sc)
+{
+	GIT_UNUSED(sc); /* prevent warning when compiled w/o threads */
+	git_rwlock_rdunlock(&sc->lock);
+}
+
+/* if the file has changed, lock cache and load file contents into buf;
+ * returns <0 on error, >0 if file has not changed
+ */
+int git_sortedcache_lockandload(git_sortedcache *sc, git_buf *buf)
+{
+	int error, fd;
+
+	if ((error = git_sortedcache_wlock(sc)) < 0)
+		return error;
+
+	if ((error = git_futils_filestamp_check(&sc->stamp, sc->path)) <= 0)
+		goto unlock;
+
+	if (!git__is_sizet(sc->stamp.size)) {
+		giterr_set(GITERR_INVALID, "Unable to load file larger than size_t");
+		error = -1;
+		goto unlock;
+	}
+
+	if ((fd = git_futils_open_ro(sc->path)) < 0) {
+		error = fd;
+		goto unlock;
+	}
+
+	if (buf)
+		error = git_futils_readbuffer_fd(buf, fd, (size_t)sc->stamp.size);
+
+	(void)p_close(fd);
+
+	if (error < 0)
+		goto unlock;
+
+	return 1; /* return 1 -> file needs reload and was successfully loaded */
+
+unlock:
+	git_sortedcache_wunlock(sc);
+	return error;
+}
+
+void git_sortedcache_updated(git_sortedcache *sc)
+{
+	/* update filestamp to latest value */
+	git_futils_filestamp_check(&sc->stamp, sc->path);
+}
+
+/* release all items in sorted cache */
+int git_sortedcache_clear(git_sortedcache *sc, bool wlock)
+{
+	if (wlock && git_sortedcache_wlock(sc) < 0)
+		return -1;
+
+	sortedcache_clear(sc);
+
+	if (wlock)
+		git_sortedcache_wunlock(sc);
+
+	return 0;
+}
+
+/* find and/or insert item, returning pointer to item data */
+int git_sortedcache_upsert(void **out, git_sortedcache *sc, const char *key)
+{
+	int error = 0;
+	khiter_t pos;
+	void *item;
+	size_t keylen, itemlen;
+	char *item_key;
+
+	pos = git_strmap_lookup_index(sc->map, key);
+	if (git_strmap_valid_index(sc->map, pos)) {
+		item = git_strmap_value_at(sc->map, pos);
+		goto done;
+	}
+
+	keylen  = strlen(key);
+	itemlen = sc->item_path_offset + keylen + 1;
+	itemlen = (itemlen + 7) & ~7;
+
+	if ((item = git_pool_mallocz(&sc->pool, (uint32_t)itemlen)) == NULL) {
+		/* don't use GITERR_CHECK_ALLOC b/c of lock */
+		error = -1;
+		goto done;
+	}
+
+	/* one strange thing is that even if the vector or hash table insert
+	 * fail, there is no way to free the pool item so we just abandon it
+	 */
+
+	item_key = ((char *)item) + sc->item_path_offset;
+	memcpy(item_key, key, keylen);
+
+	pos = kh_put(str, sc->map, item_key, &error);
+	if (error < 0)
+		goto done;
+
+	if (!error)
+		kh_key(sc->map, pos) = item_key;
+	kh_val(sc->map, pos) = item;
+
+	error = git_vector_insert(&sc->items, item);
+	if (error < 0)
+		git_strmap_delete_at(sc->map, pos);
+
+done:
+	if (out)
+		*out = !error ? item : NULL;
+	return error;
+}
+
+/* lookup item by key */
+void *git_sortedcache_lookup(const git_sortedcache *sc, const char *key)
+{
+	khiter_t pos = git_strmap_lookup_index(sc->map, key);
+	if (git_strmap_valid_index(sc->map, pos))
+		return git_strmap_value_at(sc->map, pos);
+	return NULL;
+}
+
+/* find out how many items are in the cache */
+size_t git_sortedcache_entrycount(const git_sortedcache *sc)
+{
+	return git_vector_length(&sc->items);
+}
+
+/* lookup item by index */
+void *git_sortedcache_entry(git_sortedcache *sc, size_t pos)
+{
+	/* make sure the items are sorted so this gets the correct item */
+	if (!git_vector_is_sorted(&sc->items))
+		git_vector_sort(&sc->items);
+
+	return git_vector_get(&sc->items, pos);
+}
+
+/* helper struct so bsearch callback can know offset + key value for cmp */
+struct sortedcache_magic_key {
+	size_t offset;
+	const char *key;
+};
+
+static int sortedcache_magic_cmp(const void *key, const void *value)
+{
+	const struct sortedcache_magic_key *magic = key;
+	const char *value_key = ((const char *)value) + magic->offset;
+	return strcmp(magic->key, value_key);
+}
+
+/* lookup index of item by key */
+int git_sortedcache_lookup_index(
+	size_t *out, git_sortedcache *sc, const char *key)
+{
+	struct sortedcache_magic_key magic;
+
+	magic.offset = sc->item_path_offset;
+	magic.key    = key;
+
+	return git_vector_bsearch2(out, &sc->items, sortedcache_magic_cmp, &magic);
+}
+
+/* remove entry from cache */
+int git_sortedcache_remove(git_sortedcache *sc, size_t pos)
+{
+	char *item;
+	khiter_t mappos;
+
+	/* because of pool allocation, this can't actually remove the item,
+	 * but we can remove it from the items vector and the hash table.
+	 */
+
+	if ((item = git_vector_get(&sc->items, pos)) == NULL) {
+		giterr_set(GITERR_INVALID, "Removing item out of range");
+		return GIT_ENOTFOUND;
+	}
+
+	(void)git_vector_remove(&sc->items, pos);
+
+	mappos = git_strmap_lookup_index(sc->map, item + sc->item_path_offset);
+	git_strmap_delete_at(sc->map, mappos);
+
+	if (sc->free_item)
+		sc->free_item(sc->free_item_payload, item);
+
+	return 0;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sortedcache.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sortedcache.h
new file mode 100755
index 0000000..4cacad6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sortedcache.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sorted_cache_h__
+#define INCLUDE_sorted_cache_h__
+
+#include "util.h"
+#include "fileops.h"
+#include "vector.h"
+#include "thread-utils.h"
+#include "pool.h"
+#include "strmap.h"
+
+#include <stddef.h>
+
+/*
+ * The purpose of this data structure is to cache the parsed contents of a
+ * file (a.k.a. the backing file) where each item in the file can be
+ * identified by a key string and you want to both look them up by name
+ * and traverse them in sorted order.  Each item is assumed to itself end
+ * in a GIT_FLEX_ARRAY.
+ */
+
+typedef void (*git_sortedcache_free_item_fn)(void *payload, void *item);
+
+typedef struct {
+	git_refcount rc;
+	git_rwlock   lock;
+	size_t       item_path_offset;
+	git_sortedcache_free_item_fn free_item;
+	void         *free_item_payload;
+	git_pool     pool;
+	git_vector   items;
+	git_strmap   *map;
+	git_futils_filestamp stamp;
+	char         path[GIT_FLEX_ARRAY];
+} git_sortedcache;
+
+/* Create a new sortedcache
+ *
+ * Even though every sortedcache stores items with a GIT_FLEX_ARRAY at
+ * the end containing their key string, you have to provide the item_cmp
+ * sorting function because the sorting function doesn't get a payload
+ * and therefore can't know the offset to the item key string. :-(
+ *
+ * @param out The allocated git_sortedcache
+ * @param item_path_offset Offset to the GIT_FLEX_ARRAY item key in the
+ *        struct - use offsetof(struct mine, key-field) to get this
+ * @param free_item Optional callback to free each item
+ * @param free_item_payload Optional payload passed to free_item callback
+ * @param item_cmp Compare the keys of two items
+ * @param path The path to the backing store file for this cache; this
+ *        may be NULL.  The cache makes it easy to load this and check
+ *        if it has been modified since the last load and/or write.
+ */
+int git_sortedcache_new(
+	git_sortedcache **out,
+	size_t item_path_offset, /* use offsetof(struct, path-field) macro */
+	git_sortedcache_free_item_fn free_item,
+	void *free_item_payload,
+	git_vector_cmp item_cmp,
+	const char *path);
+
+/* Copy a sorted cache
+ *
+ * - `copy_item` can be NULL to just use memcpy
+ * - if `lock`, grabs read lock on `src` during copy and releases after
+ */
+int git_sortedcache_copy(
+	git_sortedcache **out,
+	git_sortedcache *src,
+	bool lock,
+	int (*copy_item)(void *payload, void *tgt_item, void *src_item),
+	void *payload);
+
+/* Free sorted cache (first calling `free_item` callbacks)
+ *
+ * Don't call on a locked collection - it may acquire a write lock
+ */
+void git_sortedcache_free(git_sortedcache *sc);
+
+/* Increment reference count - balance with call to free */
+void git_sortedcache_incref(git_sortedcache *sc);
+
+/* Get the pathname associated with this cache at creation time */
+const char *git_sortedcache_path(git_sortedcache *sc);
+
+/*
+ * CACHE WRITE FUNCTIONS
+ *
+ * The following functions require you to have a writer lock to make the
+ * modification.  Some of the functions take a `wlock` parameter and
+ * will optionally lock and unlock for you if that is passed as true.
+ *
+ */
+
+/* Lock sortedcache for write */
+int git_sortedcache_wlock(git_sortedcache *sc);
+
+/* Unlock sorted cache when done with write */
+void git_sortedcache_wunlock(git_sortedcache *sc);
+
+/* Lock cache and load backing file into a buffer.
+ *
+ * This grabs a write lock on the cache then looks at the modification
+ * time and size of the file on disk.
+ *
+ * If the file appears to have changed, this loads the file contents into
+ * the buffer and returns a positive value leaving the cache locked - the
+ * caller should parse the file content, update the cache as needed, then
+ * release the lock.  NOTE: In this case, the caller MUST unlock the cache.
+ *
+ * If the file appears to be unchanged, then this automatically releases
+ * the lock on the cache, clears the buffer, and returns 0.
+ *
+ * @return 0 if up-to-date, 1 if out-of-date, <0 on error
+ */
+int git_sortedcache_lockandload(git_sortedcache *sc, git_buf *buf);
+
+/* Refresh file timestamp after write completes
+ * You should already be holding the write lock when you call this.
+ */
+void git_sortedcache_updated(git_sortedcache *sc);
+
+/* Release all items in sorted cache
+ *
+ * If `wlock` is true, grabs write lock and releases when done, otherwise
+ * you should already be holding a write lock when you call this.
+ */
+int git_sortedcache_clear(git_sortedcache *sc, bool wlock);
+
+/* Find and/or insert item, returning pointer to item data.
+ * You should already be holding the write lock when you call this.
+ */
+int git_sortedcache_upsert(
+	void **out, git_sortedcache *sc, const char *key);
+
+/* Removes entry at pos from cache
+ * You should already be holding the write lock when you call this.
+ */
+int git_sortedcache_remove(git_sortedcache *sc, size_t pos);
+
+/*
+ * CACHE READ FUNCTIONS
+ *
+ * The following functions access items in the cache.  To prevent the
+ * results from being invalidated before they can be used, you should be
+ * holding either a read lock or a write lock when using these functions.
+ *
+ */
+
+/* Lock sortedcache for read */
+int git_sortedcache_rlock(git_sortedcache *sc);
+
+/* Unlock sorted cache when done with read */
+void git_sortedcache_runlock(git_sortedcache *sc);
+
+/* Lookup item by key - returns NULL if not found */
+void *git_sortedcache_lookup(const git_sortedcache *sc, const char *key);
+
+/* Get how many items are in the cache
+ *
+ * You can call this function without holding a lock, but be aware
+ * that it may change before you use it.
+ */
+size_t git_sortedcache_entrycount(const git_sortedcache *sc);
+
+/* Lookup item by index - returns NULL if out of range */
+void *git_sortedcache_entry(git_sortedcache *sc, size_t pos);
+
+/* Lookup index of item by key - returns GIT_ENOTFOUND if not found */
+int git_sortedcache_lookup_index(
+	size_t *out, git_sortedcache *sc, const char *key);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/stash.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/stash.c
new file mode 100755
index 0000000..fcb1112
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/stash.c
@@ -0,0 +1,1074 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "repository.h"
+#include "commit.h"
+#include "message.h"
+#include "tree.h"
+#include "reflog.h"
+#include "git2/diff.h"
+#include "git2/stash.h"
+#include "git2/status.h"
+#include "git2/checkout.h"
+#include "git2/index.h"
+#include "git2/transaction.h"
+#include "git2/merge.h"
+#include "index.h"
+#include "signature.h"
+#include "iterator.h"
+#include "merge.h"
+#include "diff.h"
+
+static int create_error(int error, const char *msg)
+{
+	giterr_set(GITERR_STASH, "Cannot stash changes - %s", msg);
+	return error;
+}
+
+static int retrieve_head(git_reference **out, git_repository *repo)
+{
+	int error = git_repository_head(out, repo);
+
+	if (error == GIT_EUNBORNBRANCH)
+		return create_error(error, "You do not have the initial commit yet.");
+
+	return error;
+}
+
+static int append_abbreviated_oid(git_buf *out, const git_oid *b_commit)
+{
+	char *formatted_oid;
+
+	formatted_oid = git_oid_allocfmt(b_commit);
+	GITERR_CHECK_ALLOC(formatted_oid);
+
+	git_buf_put(out, formatted_oid, 7);
+	git__free(formatted_oid);
+
+	return git_buf_oom(out) ? -1 : 0;
+}
+
+static int append_commit_description(git_buf *out, git_commit* commit)
+{
+	const char *summary = git_commit_summary(commit);
+	GITERR_CHECK_ALLOC(summary);
+
+	if (append_abbreviated_oid(out, git_commit_id(commit)) < 0)
+		return -1;
+
+	git_buf_putc(out, ' ');
+	git_buf_puts(out, summary);
+	git_buf_putc(out, '\n');
+
+	return git_buf_oom(out) ? -1 : 0;
+}
+
+static int retrieve_base_commit_and_message(
+	git_commit **b_commit,
+	git_buf *stash_message,
+	git_repository *repo)
+{
+	git_reference *head = NULL;
+	int error;
+
+	if ((error = retrieve_head(&head, repo)) < 0)
+		return error;
+
+	if (strcmp("HEAD", git_reference_name(head)) == 0)
+		error = git_buf_puts(stash_message, "(no branch): ");
+	else
+		error = git_buf_printf(
+			stash_message,
+			"%s: ",
+			git_reference_name(head) + strlen(GIT_REFS_HEADS_DIR));
+	if (error < 0)
+		goto cleanup;
+
+	if ((error = git_commit_lookup(
+			 b_commit, repo, git_reference_target(head))) < 0)
+		goto cleanup;
+
+	if ((error = append_commit_description(stash_message, *b_commit)) < 0)
+		goto cleanup;
+
+cleanup:
+	git_reference_free(head);
+	return error;
+}
+
+static int build_tree_from_index(git_tree **out, git_index *index)
+{
+	int error;
+	git_oid i_tree_oid;
+
+	if ((error = git_index_write_tree(&i_tree_oid, index)) < 0)
+		return error;
+
+	return git_tree_lookup(out, git_index_owner(index), &i_tree_oid);
+}
+
+static int commit_index(
+	git_commit **i_commit,
+	git_index *index,
+	const git_signature *stasher,
+	const char *message,
+	const git_commit *parent)
+{
+	git_tree *i_tree = NULL;
+	git_oid i_commit_oid;
+	git_buf msg = GIT_BUF_INIT;
+	int error;
+
+	if ((error = build_tree_from_index(&i_tree, index)) < 0)
+		goto cleanup;
+
+	if ((error = git_buf_printf(&msg, "index on %s\n", message)) < 0)
+		goto cleanup;
+
+	if ((error = git_commit_create(
+		&i_commit_oid,
+		git_index_owner(index),
+		NULL,
+		stasher,
+		stasher,
+		NULL,
+		git_buf_cstr(&msg),
+		i_tree,
+		1,
+		&parent)) < 0)
+		goto cleanup;
+
+	error = git_commit_lookup(i_commit, git_index_owner(index), &i_commit_oid);
+
+cleanup:
+	git_tree_free(i_tree);
+	git_buf_free(&msg);
+	return error;
+}
+
+struct stash_update_rules {
+	bool include_changed;
+	bool include_untracked;
+	bool include_ignored;
+};
+
+static int stash_update_index_from_diff(
+	git_index *index,
+	const git_diff *diff,
+	struct stash_update_rules *data)
+{
+	int error = 0;
+	size_t d, max_d = git_diff_num_deltas(diff);
+
+	for (d = 0; !error && d < max_d; ++d) {
+		const char *add_path = NULL;
+		const git_diff_delta *delta = git_diff_get_delta(diff, d);
+
+		switch (delta->status) {
+		case GIT_DELTA_IGNORED:
+			if (data->include_ignored)
+				add_path = delta->new_file.path;
+			break;
+
+		case GIT_DELTA_UNTRACKED:
+			if (data->include_untracked &&
+				delta->new_file.mode != GIT_FILEMODE_TREE)
+				add_path = delta->new_file.path;
+			break;
+
+		case GIT_DELTA_ADDED:
+		case GIT_DELTA_MODIFIED:
+			if (data->include_changed)
+				add_path = delta->new_file.path;
+			break;
+
+		case GIT_DELTA_DELETED:
+			if (data->include_changed &&
+				!git_index_find(NULL, index, delta->old_file.path))
+				error = git_index_remove(index, delta->old_file.path, 0);
+			break;
+
+		default:
+			/* Unimplemented */
+			giterr_set(
+				GITERR_INVALID,
+				"Cannot update index. Unimplemented status (%d)",
+				delta->status);
+			return -1;
+		}
+
+		if (add_path != NULL)
+			error = git_index_add_bypath(index, add_path);
+	}
+
+	return error;
+}
+
+static int build_untracked_tree(
+	git_tree **tree_out,
+	git_index *index,
+	git_commit *i_commit,
+	uint32_t flags)
+{
+	git_tree *i_tree = NULL;
+	git_diff *diff = NULL;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	struct stash_update_rules data = {0};
+	int error;
+
+	git_index_clear(index);
+
+	if (flags & GIT_STASH_INCLUDE_UNTRACKED) {
+		opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED |
+			GIT_DIFF_RECURSE_UNTRACKED_DIRS;
+		data.include_untracked = true;
+	}
+
+	if (flags & GIT_STASH_INCLUDE_IGNORED) {
+		opts.flags |= GIT_DIFF_INCLUDE_IGNORED |
+			GIT_DIFF_RECURSE_IGNORED_DIRS;
+		data.include_ignored = true;
+	}
+
+	if ((error = git_commit_tree(&i_tree, i_commit)) < 0)
+		goto cleanup;
+
+	if ((error = git_diff_tree_to_workdir(
+			&diff, git_index_owner(index), i_tree, &opts)) < 0)
+		goto cleanup;
+
+	if ((error = stash_update_index_from_diff(index, diff, &data)) < 0)
+		goto cleanup;
+
+	error = build_tree_from_index(tree_out, index);
+
+cleanup:
+	git_diff_free(diff);
+	git_tree_free(i_tree);
+	return error;
+}
+
+static int commit_untracked(
+	git_commit **u_commit,
+	git_index *index,
+	const git_signature *stasher,
+	const char *message,
+	git_commit *i_commit,
+	uint32_t flags)
+{
+	git_tree *u_tree = NULL;
+	git_oid u_commit_oid;
+	git_buf msg = GIT_BUF_INIT;
+	int error;
+
+	if ((error = build_untracked_tree(&u_tree, index, i_commit, flags)) < 0)
+		goto cleanup;
+
+	if ((error = git_buf_printf(&msg, "untracked files on %s\n", message)) < 0)
+		goto cleanup;
+
+	if ((error = git_commit_create(
+		&u_commit_oid,
+		git_index_owner(index),
+		NULL,
+		stasher,
+		stasher,
+		NULL,
+		git_buf_cstr(&msg),
+		u_tree,
+		0,
+		NULL)) < 0)
+		goto cleanup;
+
+	error = git_commit_lookup(u_commit, git_index_owner(index), &u_commit_oid);
+
+cleanup:
+	git_tree_free(u_tree);
+	git_buf_free(&msg);
+	return error;
+}
+
+static git_diff_delta *stash_delta_merge(
+	const git_diff_delta *a,
+	const git_diff_delta *b,
+	git_pool *pool)
+{
+	/* Special case for stash: if a file is deleted in the index, but exists
+	 * in the working tree, we need to stash the workdir copy for the workdir.
+	 */
+	if (a->status == GIT_DELTA_DELETED && b->status == GIT_DELTA_UNTRACKED) {
+		git_diff_delta *dup = git_diff__delta_dup(b, pool);
+
+		if (dup)
+			dup->status = GIT_DELTA_MODIFIED;
+		return dup;
+	}
+
+	return git_diff__merge_like_cgit(a, b, pool);
+}
+
+static int build_workdir_tree(
+	git_tree **tree_out,
+	git_index *index,
+	git_commit *b_commit)
+{
+	git_repository *repo = git_index_owner(index);
+	git_tree *b_tree = NULL;
+	git_diff *diff = NULL, *idx_to_wd = NULL;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	struct stash_update_rules data = {0};
+	int error;
+
+	opts.flags = GIT_DIFF_IGNORE_SUBMODULES | GIT_DIFF_INCLUDE_UNTRACKED;
+
+	if ((error = git_commit_tree(&b_tree, b_commit)) < 0)
+		goto cleanup;
+
+	if ((error = git_diff_tree_to_index(&diff, repo, b_tree, index, &opts)) < 0 ||
+		(error = git_diff_index_to_workdir(&idx_to_wd, repo, index, &opts)) < 0 ||
+		(error = git_diff__merge(diff, idx_to_wd, stash_delta_merge)) < 0)
+		goto cleanup;
+
+	data.include_changed = true;
+
+	if ((error = stash_update_index_from_diff(index, diff, &data)) < 0)
+		goto cleanup;
+
+	error = build_tree_from_index(tree_out, index);
+
+cleanup:
+	git_diff_free(idx_to_wd);
+	git_diff_free(diff);
+	git_tree_free(b_tree);
+
+	return error;
+}
+
+static int commit_worktree(
+	git_oid *w_commit_oid,
+	git_index *index,
+	const git_signature *stasher,
+	const char *message,
+	git_commit *i_commit,
+	git_commit *b_commit,
+	git_commit *u_commit)
+{
+	int error = 0;
+	git_tree *w_tree = NULL, *i_tree = NULL;
+	const git_commit *parents[] = {	NULL, NULL,	NULL };
+
+	parents[0] = b_commit;
+	parents[1] = i_commit;
+	parents[2] = u_commit;
+
+	if ((error = git_commit_tree(&i_tree, i_commit)) < 0)
+		goto cleanup;
+
+	if ((error = git_index_read_tree(index, i_tree)) < 0)
+		goto cleanup;
+
+	if ((error = build_workdir_tree(&w_tree, index, b_commit)) < 0)
+		goto cleanup;
+
+	error = git_commit_create(
+		w_commit_oid,
+		git_index_owner(index),
+		NULL,
+		stasher,
+		stasher,
+		NULL,
+		message,
+		w_tree,
+		u_commit ? 3 : 2,
+		parents);
+
+cleanup:
+	git_tree_free(i_tree);
+	git_tree_free(w_tree);
+	return error;
+}
+
+static int prepare_worktree_commit_message(
+	git_buf* msg,
+	const char *user_message)
+{
+	git_buf buf = GIT_BUF_INIT;
+	int error;
+
+	if ((error = git_buf_set(&buf, git_buf_cstr(msg), git_buf_len(msg))) < 0)
+		return error;
+
+	git_buf_clear(msg);
+
+	if (!user_message)
+		git_buf_printf(msg, "WIP on %s", git_buf_cstr(&buf));
+	else {
+		const char *colon;
+
+		if ((colon = strchr(git_buf_cstr(&buf), ':')) == NULL)
+			goto cleanup;
+
+		git_buf_puts(msg, "On ");
+		git_buf_put(msg, git_buf_cstr(&buf), colon - buf.ptr);
+		git_buf_printf(msg, ": %s\n", user_message);
+	}
+
+	error = (git_buf_oom(msg) || git_buf_oom(&buf)) ? -1 : 0;
+
+cleanup:
+	git_buf_free(&buf);
+
+	return error;
+}
+
+static int update_reflog(
+	git_oid *w_commit_oid,
+	git_repository *repo,
+	const char *message)
+{
+	git_reference *stash;
+	int error;
+
+	if ((error = git_reference_ensure_log(repo, GIT_REFS_STASH_FILE)) < 0)
+		return error;
+
+	error = git_reference_create(&stash, repo, GIT_REFS_STASH_FILE, w_commit_oid, 1, message);
+
+	git_reference_free(stash);
+
+	return error;
+}
+
+static int is_dirty_cb(const char *path, unsigned int status, void *payload)
+{
+	GIT_UNUSED(path);
+	GIT_UNUSED(status);
+	GIT_UNUSED(payload);
+
+	return GIT_PASSTHROUGH;
+}
+
+static int ensure_there_are_changes_to_stash(
+	git_repository *repo,
+	bool include_untracked_files,
+	bool include_ignored_files)
+{
+	int error;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+
+	opts.show  = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
+	opts.flags = GIT_STATUS_OPT_EXCLUDE_SUBMODULES;
+
+	if (include_untracked_files)
+		opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+			GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
+
+	if (include_ignored_files)
+		opts.flags |= GIT_STATUS_OPT_INCLUDE_IGNORED |
+			GIT_STATUS_OPT_RECURSE_IGNORED_DIRS;
+
+	error = git_status_foreach_ext(repo, &opts, is_dirty_cb, NULL);
+
+	if (error == GIT_PASSTHROUGH)
+		return 0;
+
+	if (!error)
+		return create_error(GIT_ENOTFOUND, "There is nothing to stash.");
+
+	return error;
+}
+
+static int reset_index_and_workdir(
+	git_repository *repo,
+	git_commit *commit,
+	bool remove_untracked,
+	bool remove_ignored)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	if (remove_untracked)
+		opts.checkout_strategy |= GIT_CHECKOUT_REMOVE_UNTRACKED;
+
+	if (remove_ignored)
+		opts.checkout_strategy |= GIT_CHECKOUT_REMOVE_IGNORED;
+
+	return git_checkout_tree(repo, (git_object *)commit, &opts);
+}
+
+int git_stash_save(
+	git_oid *out,
+	git_repository *repo,
+	const git_signature *stasher,
+	const char *message,
+	uint32_t flags)
+{
+	git_index *index = NULL;
+	git_commit *b_commit = NULL, *i_commit = NULL, *u_commit = NULL;
+	git_buf msg = GIT_BUF_INIT;
+	int error;
+
+	assert(out && repo && stasher);
+
+	if ((error = git_repository__ensure_not_bare(repo, "stash save")) < 0)
+		return error;
+
+	if ((error = retrieve_base_commit_and_message(&b_commit, &msg, repo)) < 0)
+		goto cleanup;
+
+	if ((error = ensure_there_are_changes_to_stash(
+		repo,
+		(flags & GIT_STASH_INCLUDE_UNTRACKED) != 0,
+		(flags & GIT_STASH_INCLUDE_IGNORED) != 0)) < 0)
+		goto cleanup;
+
+	if ((error = git_repository_index(&index, repo)) < 0)
+		goto cleanup;
+
+	if ((error = commit_index(
+			&i_commit, index, stasher, git_buf_cstr(&msg), b_commit)) < 0)
+		goto cleanup;
+
+	if ((flags & (GIT_STASH_INCLUDE_UNTRACKED | GIT_STASH_INCLUDE_IGNORED)) &&
+		(error = commit_untracked(
+			&u_commit, index, stasher, git_buf_cstr(&msg),
+			i_commit, flags)) < 0)
+		goto cleanup;
+
+	if ((error = prepare_worktree_commit_message(&msg, message)) < 0)
+		goto cleanup;
+
+	if ((error = commit_worktree(
+			out, index, stasher, git_buf_cstr(&msg),
+			i_commit, b_commit, u_commit)) < 0)
+		goto cleanup;
+
+	git_buf_rtrim(&msg);
+
+	if ((error = update_reflog(out, repo, git_buf_cstr(&msg))) < 0)
+		goto cleanup;
+
+	if ((error = reset_index_and_workdir(
+		repo,
+		((flags & GIT_STASH_KEEP_INDEX) != 0) ? i_commit : b_commit,
+		(flags & GIT_STASH_INCLUDE_UNTRACKED) != 0,
+		(flags & GIT_STASH_INCLUDE_IGNORED) != 0)) < 0)
+		goto cleanup;
+
+cleanup:
+
+	git_buf_free(&msg);
+	git_commit_free(i_commit);
+	git_commit_free(b_commit);
+	git_commit_free(u_commit);
+	git_index_free(index);
+
+	return error;
+}
+
+static int retrieve_stash_commit(
+	git_commit **commit,
+	git_repository *repo,
+	size_t index)
+{
+	git_reference *stash = NULL;
+	git_reflog *reflog = NULL;
+	int error;
+	size_t max;
+	const git_reflog_entry *entry;
+
+	if ((error = git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE)) < 0)
+		goto cleanup;
+
+	if ((error = git_reflog_read(&reflog, repo, GIT_REFS_STASH_FILE)) < 0)
+		goto cleanup;
+
+	max = git_reflog_entrycount(reflog);
+	if (!max || index > max - 1) {
+		error = GIT_ENOTFOUND;
+		giterr_set(GITERR_STASH, "No stashed state at position %" PRIuZ, index);
+		goto cleanup;
+	}
+
+	entry = git_reflog_entry_byindex(reflog, index);
+	if ((error = git_commit_lookup(commit, repo, git_reflog_entry_id_new(entry))) < 0)
+		goto cleanup;
+
+cleanup:
+	git_reference_free(stash);
+	git_reflog_free(reflog);
+	return error;
+}
+
+static int retrieve_stash_trees(
+	git_tree **out_stash_tree,
+	git_tree **out_base_tree,
+	git_tree **out_index_tree,
+	git_tree **out_index_parent_tree,
+	git_tree **out_untracked_tree,
+	git_commit *stash_commit)
+{
+	git_tree *stash_tree = NULL;
+	git_commit *base_commit = NULL;
+	git_tree *base_tree = NULL;
+	git_commit *index_commit = NULL;
+	git_tree *index_tree = NULL;
+	git_commit *index_parent_commit = NULL;
+	git_tree *index_parent_tree = NULL;
+	git_commit *untracked_commit = NULL;
+	git_tree *untracked_tree = NULL;
+	int error;
+
+	if ((error = git_commit_tree(&stash_tree, stash_commit)) < 0)
+		goto cleanup;
+
+	if ((error = git_commit_parent(&base_commit, stash_commit, 0)) < 0)
+		goto cleanup;
+	if ((error = git_commit_tree(&base_tree, base_commit)) < 0)
+		goto cleanup;
+
+	if ((error = git_commit_parent(&index_commit, stash_commit, 1)) < 0)
+		goto cleanup;
+	if ((error = git_commit_tree(&index_tree, index_commit)) < 0)
+		goto cleanup;
+
+	if ((error = git_commit_parent(&index_parent_commit, index_commit, 0)) < 0)
+		goto cleanup;
+	if ((error = git_commit_tree(&index_parent_tree, index_parent_commit)) < 0)
+		goto cleanup;
+
+	if (git_commit_parentcount(stash_commit) == 3) {
+		if ((error = git_commit_parent(&untracked_commit, stash_commit, 2)) < 0)
+			goto cleanup;
+		if ((error = git_commit_tree(&untracked_tree, untracked_commit)) < 0)
+			goto cleanup;
+	}
+
+	*out_stash_tree = stash_tree;
+	*out_base_tree = base_tree;
+	*out_index_tree = index_tree;
+	*out_index_parent_tree = index_parent_tree;
+	*out_untracked_tree = untracked_tree;
+
+cleanup:
+	git_commit_free(untracked_commit);
+	git_commit_free(index_parent_commit);
+	git_commit_free(index_commit);
+	git_commit_free(base_commit);
+	if (error < 0) {
+		git_tree_free(stash_tree);
+		git_tree_free(base_tree);
+		git_tree_free(index_tree);
+		git_tree_free(index_parent_tree);
+		git_tree_free(untracked_tree);
+	}
+	return error;
+}
+
+static int merge_indexes(
+	git_index **out,
+	git_repository *repo,
+	git_tree *ancestor_tree,
+	git_index *ours_index,
+	git_index *theirs_index)
+{
+	git_iterator *ancestor = NULL, *ours = NULL, *theirs = NULL;
+	const git_iterator_flag_t flags = GIT_ITERATOR_DONT_IGNORE_CASE;
+	int error;
+
+	if ((error = git_iterator_for_tree(&ancestor, ancestor_tree, flags, NULL, NULL)) < 0 ||
+		(error = git_iterator_for_index(&ours, ours_index, flags, NULL, NULL)) < 0 ||
+		(error = git_iterator_for_index(&theirs, theirs_index, flags, NULL, NULL)) < 0)
+		goto done;
+
+	error = git_merge__iterators(out, repo, ancestor, ours, theirs, NULL);
+
+done:
+	git_iterator_free(ancestor);
+	git_iterator_free(ours);
+	git_iterator_free(theirs);
+	return error;
+}
+
+static int merge_index_and_tree(
+	git_index **out,
+	git_repository *repo,
+	git_tree *ancestor_tree,
+	git_index *ours_index,
+	git_tree *theirs_tree)
+{
+	git_iterator *ancestor = NULL, *ours = NULL, *theirs = NULL;
+	const git_iterator_flag_t flags = GIT_ITERATOR_DONT_IGNORE_CASE;
+	int error;
+
+	if ((error = git_iterator_for_tree(&ancestor, ancestor_tree, flags, NULL, NULL)) < 0 ||
+		(error = git_iterator_for_index(&ours, ours_index, flags, NULL, NULL)) < 0 ||
+		(error = git_iterator_for_tree(&theirs, theirs_tree, flags, NULL, NULL)) < 0)
+		goto done;
+
+	error = git_merge__iterators(out, repo, ancestor, ours, theirs, NULL);
+
+done:
+	git_iterator_free(ancestor);
+	git_iterator_free(ours);
+	git_iterator_free(theirs);
+	return error;
+}
+
+static void normalize_apply_options(
+	git_stash_apply_options *opts,
+	const git_stash_apply_options *given_apply_opts)
+{	
+	if (given_apply_opts != NULL) {
+		memcpy(opts, given_apply_opts, sizeof(git_stash_apply_options));
+	} else {
+		git_stash_apply_options default_apply_opts = GIT_STASH_APPLY_OPTIONS_INIT;
+		memcpy(opts, &default_apply_opts, sizeof(git_stash_apply_options));
+	}
+
+	if ((opts->checkout_options.checkout_strategy & (GIT_CHECKOUT_SAFE | GIT_CHECKOUT_FORCE)) == 0)
+		opts->checkout_options.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+	if (!opts->checkout_options.our_label)
+		opts->checkout_options.our_label = "Updated upstream";
+
+	if (!opts->checkout_options.their_label)
+		opts->checkout_options.their_label = "Stashed changes";
+}
+
+int git_stash_apply_init_options(git_stash_apply_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_stash_apply_options, GIT_STASH_APPLY_OPTIONS_INIT);
+	return 0;
+}
+
+#define NOTIFY_PROGRESS(opts, progress_type)				\
+	do {								\
+		if ((opts).progress_cb &&				\
+		    (error = (opts).progress_cb((progress_type), (opts).progress_payload))) { \
+			error = (error < 0) ? error : -1;		\
+			goto cleanup;					\
+		}							\
+	} while(false);
+
+static int ensure_clean_index(git_repository *repo, git_index *index)
+{
+	git_tree *head_tree = NULL;
+	git_diff *index_diff = NULL;
+	int error = 0;
+
+	if ((error = git_repository_head_tree(&head_tree, repo)) < 0 ||
+		(error = git_diff_tree_to_index(
+			&index_diff, repo, head_tree, index, NULL)) < 0)
+		goto done;
+
+	if (git_diff_num_deltas(index_diff) > 0) {
+		giterr_set(GITERR_STASH, "%" PRIuZ " uncommitted changes exist in the index",
+			git_diff_num_deltas(index_diff));
+		error = GIT_EUNCOMMITTED;
+	}
+
+done:
+	git_diff_free(index_diff);
+	git_tree_free(head_tree);
+	return error;
+}
+
+static int stage_new_file(const git_index_entry **entries, void *data)
+{
+	git_index *index = data;
+
+	if(entries[0] == NULL)
+		return git_index_add(index, entries[1]);
+	else
+		return git_index_add(index, entries[0]);
+}
+
+static int stage_new_files(
+	git_index **out,
+	git_tree *parent_tree,
+	git_tree *tree)
+{
+	git_iterator *iterators[2] = { NULL, NULL };
+	git_index *index = NULL;
+	int error;
+
+	if ((error = git_index_new(&index)) < 0 ||
+		(error = git_iterator_for_tree(&iterators[0], parent_tree,
+			GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
+		(error = git_iterator_for_tree(&iterators[1], tree,
+			GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0)
+		goto done;
+
+	error = git_iterator_walk(iterators, 2, stage_new_file, index);
+
+done:
+	if (error < 0)
+		git_index_free(index);
+	else
+		*out = index;
+
+	git_iterator_free(iterators[0]);
+	git_iterator_free(iterators[1]);
+
+	return error;
+}
+
+int git_stash_apply(
+	git_repository *repo,
+	size_t index,
+	const git_stash_apply_options *given_opts)
+{
+	git_stash_apply_options opts;
+	unsigned int checkout_strategy;
+	git_commit *stash_commit = NULL;
+	git_tree *stash_tree = NULL;
+	git_tree *stash_parent_tree = NULL;
+	git_tree *index_tree = NULL;
+	git_tree *index_parent_tree = NULL;
+	git_tree *untracked_tree = NULL;
+	git_index *stash_adds = NULL;
+	git_index *repo_index = NULL;
+	git_index *unstashed_index = NULL;
+	git_index *modified_index = NULL;
+	git_index *untracked_index = NULL;
+	int error;
+
+	GITERR_CHECK_VERSION(given_opts, GIT_STASH_APPLY_OPTIONS_VERSION, "git_stash_apply_options");
+
+	normalize_apply_options(&opts, given_opts);
+	checkout_strategy = opts.checkout_options.checkout_strategy;
+
+	NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_LOADING_STASH);
+
+	/* Retrieve commit corresponding to the given stash */
+	if ((error = retrieve_stash_commit(&stash_commit, repo, index)) < 0)
+		goto cleanup;
+
+	/* Retrieve all trees in the stash */
+	if ((error = retrieve_stash_trees(
+			&stash_tree, &stash_parent_tree, &index_tree,
+			&index_parent_tree, &untracked_tree, stash_commit)) < 0)
+		goto cleanup;
+
+	/* Load repo index */
+	if ((error = git_repository_index(&repo_index, repo)) < 0)
+		goto cleanup;
+
+	NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_ANALYZE_INDEX);
+
+	if ((error = ensure_clean_index(repo, repo_index)) < 0)
+		goto cleanup;
+
+	/* Restore index if required */
+	if ((opts.flags & GIT_STASH_APPLY_REINSTATE_INDEX) &&
+		git_oid_cmp(git_tree_id(stash_parent_tree), git_tree_id(index_tree))) {
+
+		if ((error = merge_index_and_tree(
+				&unstashed_index, repo, index_parent_tree, repo_index, index_tree)) < 0)
+			goto cleanup;
+
+		if (git_index_has_conflicts(unstashed_index)) {
+			error = GIT_ECONFLICT;
+			goto cleanup;
+		}
+
+	/* Otherwise, stage any new files in the stash tree.  (Note: their
+	 * previously unstaged contents are staged, not the previously staged.)
+	 */
+	} else if ((opts.flags & GIT_STASH_APPLY_REINSTATE_INDEX) == 0) {
+		if ((error = stage_new_files(
+				&stash_adds, stash_parent_tree, stash_tree)) < 0 ||
+			(error = merge_indexes(
+				&unstashed_index, repo, stash_parent_tree, repo_index, stash_adds)) < 0)
+			goto cleanup;
+	}
+
+	NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_ANALYZE_MODIFIED);
+
+	/* Restore modified files in workdir */
+	if ((error = merge_index_and_tree(
+			&modified_index, repo, stash_parent_tree, repo_index, stash_tree)) < 0)
+		goto cleanup;
+
+	/* If applicable, restore untracked / ignored files in workdir */
+	if (untracked_tree) {
+		NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_ANALYZE_UNTRACKED);
+
+		if ((error = merge_index_and_tree(&untracked_index, repo, NULL, repo_index, untracked_tree)) < 0)
+			goto cleanup;
+	}
+
+	if (untracked_index) {
+		opts.checkout_options.checkout_strategy |= GIT_CHECKOUT_DONT_UPDATE_INDEX;
+
+		NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_CHECKOUT_UNTRACKED);
+
+		if ((error = git_checkout_index(repo, untracked_index, &opts.checkout_options)) < 0)
+			goto cleanup;
+
+		opts.checkout_options.checkout_strategy = checkout_strategy;
+	}
+
+
+	/* If there are conflicts in the modified index, then we need to actually
+	 * check that out as the repo's index.  Otherwise, we don't update the
+	 * index.
+	 */
+
+	if (!git_index_has_conflicts(modified_index))
+		opts.checkout_options.checkout_strategy |= GIT_CHECKOUT_DONT_UPDATE_INDEX;
+
+	/* Check out the modified index using the existing repo index as baseline,
+	 * so that existing modifications in the index can be rewritten even when
+	 * checking out safely.
+	 */
+	opts.checkout_options.baseline_index = repo_index;
+
+	NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_CHECKOUT_MODIFIED);
+
+	if ((error = git_checkout_index(repo, modified_index, &opts.checkout_options)) < 0)
+		goto cleanup;
+
+	if (unstashed_index && !git_index_has_conflicts(modified_index)) {
+		if ((error = git_index_read_index(repo_index, unstashed_index)) < 0)
+			goto cleanup;
+	}
+
+	NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_DONE);
+
+	error = git_index_write(repo_index);
+
+cleanup:
+	git_index_free(untracked_index);
+	git_index_free(modified_index);
+	git_index_free(unstashed_index);
+	git_index_free(stash_adds);
+	git_index_free(repo_index);
+	git_tree_free(untracked_tree);
+	git_tree_free(index_parent_tree);
+	git_tree_free(index_tree);
+	git_tree_free(stash_parent_tree);
+	git_tree_free(stash_tree);
+	git_commit_free(stash_commit);
+	return error;
+}
+
+int git_stash_foreach(
+	git_repository *repo,
+	git_stash_cb callback,
+	void *payload)
+{
+	git_reference *stash;
+	git_reflog *reflog = NULL;
+	int error;
+	size_t i, max;
+	const git_reflog_entry *entry;
+
+	error = git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE);
+	if (error == GIT_ENOTFOUND) {
+		giterr_clear();
+		return 0;
+	}
+	if (error < 0)
+		goto cleanup;
+
+	if ((error = git_reflog_read(&reflog, repo, GIT_REFS_STASH_FILE)) < 0)
+		goto cleanup;
+
+	max = git_reflog_entrycount(reflog);
+	for (i = 0; i < max; i++) {
+		entry = git_reflog_entry_byindex(reflog, i);
+
+		error = callback(i,
+			git_reflog_entry_message(entry),
+			git_reflog_entry_id_new(entry),
+			payload);
+
+		if (error) {
+			giterr_set_after_callback(error);
+			break;
+		}
+	}
+
+cleanup:
+	git_reference_free(stash);
+	git_reflog_free(reflog);
+	return error;
+}
+
+int git_stash_drop(
+	git_repository *repo,
+	size_t index)
+{
+	git_transaction *tx;
+	git_reference *stash = NULL;
+	git_reflog *reflog = NULL;
+	size_t max;
+	int error;
+
+	if ((error = git_transaction_new(&tx, repo)) < 0)
+		return error;
+
+	if ((error = git_transaction_lock_ref(tx, GIT_REFS_STASH_FILE)) < 0)
+		goto cleanup;
+
+	if ((error = git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE)) < 0)
+		goto cleanup;
+
+	if ((error = git_reflog_read(&reflog, repo, GIT_REFS_STASH_FILE)) < 0)
+		goto cleanup;
+
+	max = git_reflog_entrycount(reflog);
+
+	if (!max || index > max - 1) {
+		error = GIT_ENOTFOUND;
+		giterr_set(GITERR_STASH, "No stashed state at position %" PRIuZ, index);
+		goto cleanup;
+	}
+
+	if ((error = git_reflog_drop(reflog, index, true)) < 0)
+		goto cleanup;
+
+	if ((error = git_transaction_set_reflog(tx, GIT_REFS_STASH_FILE, reflog)) < 0)
+		goto cleanup;
+
+	if (max == 1) {
+		if ((error = git_transaction_remove(tx, GIT_REFS_STASH_FILE)) < 0)
+			goto cleanup;
+	} else if (index == 0) {
+		const git_reflog_entry *entry;
+
+		entry = git_reflog_entry_byindex(reflog, 0);
+		if ((error = git_transaction_set_target(tx, GIT_REFS_STASH_FILE, &entry->oid_cur, NULL, NULL)) < 0)
+			goto cleanup;
+	}
+
+	error = git_transaction_commit(tx);
+
+cleanup:
+	git_reference_free(stash);
+	git_transaction_free(tx);
+	git_reflog_free(reflog);
+	return error;
+}
+
+int git_stash_pop(
+	git_repository *repo,
+	size_t index,
+	const git_stash_apply_options *options)
+{
+	int error;
+
+	if ((error = git_stash_apply(repo, index, options)) < 0)
+		return error;
+
+	return git_stash_drop(repo, index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/status.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/status.c
new file mode 100755
index 0000000..b206b0e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/status.c
@@ -0,0 +1,564 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "git2.h"
+#include "fileops.h"
+#include "hash.h"
+#include "vector.h"
+#include "tree.h"
+#include "status.h"
+#include "git2/status.h"
+#include "repository.h"
+#include "ignore.h"
+#include "index.h"
+
+#include "git2/diff.h"
+#include "diff.h"
+
+static unsigned int index_delta2status(const git_diff_delta *head2idx)
+{
+	git_status_t st = GIT_STATUS_CURRENT;
+
+	switch (head2idx->status) {
+	case GIT_DELTA_ADDED:
+	case GIT_DELTA_COPIED:
+		st = GIT_STATUS_INDEX_NEW;
+		break;
+	case GIT_DELTA_DELETED:
+		st = GIT_STATUS_INDEX_DELETED;
+		break;
+	case GIT_DELTA_MODIFIED:
+		st = GIT_STATUS_INDEX_MODIFIED;
+		break;
+	case GIT_DELTA_RENAMED:
+		st = GIT_STATUS_INDEX_RENAMED;
+
+		if (!git_oid_equal(&head2idx->old_file.id, &head2idx->new_file.id))
+			st |= GIT_STATUS_INDEX_MODIFIED;
+		break;
+	case GIT_DELTA_TYPECHANGE:
+		st = GIT_STATUS_INDEX_TYPECHANGE;
+		break;
+	case GIT_DELTA_CONFLICTED:
+		st = GIT_STATUS_CONFLICTED;
+		break;
+	default:
+		break;
+	}
+
+	return st;
+}
+
+static unsigned int workdir_delta2status(
+	git_diff *diff, git_diff_delta *idx2wd)
+{
+	git_status_t st = GIT_STATUS_CURRENT;
+
+	switch (idx2wd->status) {
+	case GIT_DELTA_ADDED:
+	case GIT_DELTA_COPIED:
+	case GIT_DELTA_UNTRACKED:
+		st = GIT_STATUS_WT_NEW;
+		break;
+	case GIT_DELTA_UNREADABLE:
+		st = GIT_STATUS_WT_UNREADABLE;
+		break;
+	case GIT_DELTA_DELETED:
+		st = GIT_STATUS_WT_DELETED;
+		break;
+	case GIT_DELTA_MODIFIED:
+		st = GIT_STATUS_WT_MODIFIED;
+		break;
+	case GIT_DELTA_IGNORED:
+		st = GIT_STATUS_IGNORED;
+		break;
+	case GIT_DELTA_RENAMED:
+		st = GIT_STATUS_WT_RENAMED;
+
+		if (!git_oid_equal(&idx2wd->old_file.id, &idx2wd->new_file.id)) {
+			/* if OIDs don't match, we might need to calculate them now to
+			 * discern between RENAMED vs RENAMED+MODIFED
+			 */
+			if (git_oid_iszero(&idx2wd->old_file.id) &&
+				diff->old_src == GIT_ITERATOR_TYPE_WORKDIR &&
+				!git_diff__oid_for_file(
+					&idx2wd->old_file.id, diff, idx2wd->old_file.path,
+					idx2wd->old_file.mode, idx2wd->old_file.size))
+			idx2wd->old_file.flags |= GIT_DIFF_FLAG_VALID_ID;
+
+			if (git_oid_iszero(&idx2wd->new_file.id) &&
+				diff->new_src == GIT_ITERATOR_TYPE_WORKDIR &&
+				!git_diff__oid_for_file(
+					&idx2wd->new_file.id, diff, idx2wd->new_file.path,
+					idx2wd->new_file.mode, idx2wd->new_file.size))
+				idx2wd->new_file.flags |= GIT_DIFF_FLAG_VALID_ID;
+
+			if (!git_oid_equal(&idx2wd->old_file.id, &idx2wd->new_file.id))
+				st |= GIT_STATUS_WT_MODIFIED;
+		}
+		break;
+	case GIT_DELTA_TYPECHANGE:
+		st = GIT_STATUS_WT_TYPECHANGE;
+		break;
+	case GIT_DELTA_CONFLICTED:
+		st = GIT_STATUS_CONFLICTED;
+		break;
+	default:
+		break;
+	}
+
+	return st;
+}
+
+static bool status_is_included(
+	git_status_list *status,
+	git_diff_delta *head2idx,
+	git_diff_delta *idx2wd)
+{
+	if (!(status->opts.flags & GIT_STATUS_OPT_EXCLUDE_SUBMODULES))
+		return 1;
+
+	/* if excluding submodules and this is a submodule everywhere */
+	if (head2idx) {
+		if (head2idx->status != GIT_DELTA_ADDED &&
+			head2idx->old_file.mode != GIT_FILEMODE_COMMIT)
+			return 1;
+		if (head2idx->status != GIT_DELTA_DELETED &&
+			head2idx->new_file.mode != GIT_FILEMODE_COMMIT)
+			return 1;
+	}
+	if (idx2wd) {
+		if (idx2wd->status != GIT_DELTA_ADDED &&
+			idx2wd->old_file.mode != GIT_FILEMODE_COMMIT)
+			return 1;
+		if (idx2wd->status != GIT_DELTA_DELETED &&
+			idx2wd->new_file.mode != GIT_FILEMODE_COMMIT)
+			return 1;
+	}
+
+	/* only get here if every valid mode is GIT_FILEMODE_COMMIT */
+	return 0;
+}
+
+static git_status_t status_compute(
+	git_status_list *status,
+	git_diff_delta *head2idx,
+	git_diff_delta *idx2wd)
+{
+	git_status_t st = GIT_STATUS_CURRENT;
+
+	if (head2idx)
+		st |= index_delta2status(head2idx);
+
+	if (idx2wd)
+		st |= workdir_delta2status(status->idx2wd, idx2wd);
+
+	return st;
+}
+
+static int status_collect(
+	git_diff_delta *head2idx,
+	git_diff_delta *idx2wd,
+	void *payload)
+{
+	git_status_list *status = payload;
+	git_status_entry *status_entry;
+
+	if (!status_is_included(status, head2idx, idx2wd))
+		return 0;
+
+	status_entry = git__malloc(sizeof(git_status_entry));
+	GITERR_CHECK_ALLOC(status_entry);
+
+	status_entry->status = status_compute(status, head2idx, idx2wd);
+	status_entry->head_to_index = head2idx;
+	status_entry->index_to_workdir = idx2wd;
+
+	return git_vector_insert(&status->paired, status_entry);
+}
+
+GIT_INLINE(int) status_entry_cmp_base(
+	const void *a,
+	const void *b,
+	int (*strcomp)(const char *a, const char *b))
+{
+	const git_status_entry *entry_a = a;
+	const git_status_entry *entry_b = b;
+	const git_diff_delta *delta_a, *delta_b;
+
+	delta_a = entry_a->index_to_workdir ? entry_a->index_to_workdir :
+		entry_a->head_to_index;
+	delta_b = entry_b->index_to_workdir ? entry_b->index_to_workdir :
+		entry_b->head_to_index;
+
+	if (!delta_a && delta_b)
+		return -1;
+	if (delta_a && !delta_b)
+		return 1;
+	if (!delta_a && !delta_b)
+		return 0;
+
+	return strcomp(delta_a->new_file.path, delta_b->new_file.path);
+}
+
+static int status_entry_icmp(const void *a, const void *b)
+{
+	return status_entry_cmp_base(a, b, git__strcasecmp);
+}
+
+static int status_entry_cmp(const void *a, const void *b)
+{
+	return status_entry_cmp_base(a, b, git__strcmp);
+}
+
+static git_status_list *git_status_list_alloc(git_index *index)
+{
+	git_status_list *status = NULL;
+	int (*entrycmp)(const void *a, const void *b);
+
+	if (!(status = git__calloc(1, sizeof(git_status_list))))
+		return NULL;
+
+	entrycmp = index->ignore_case ? status_entry_icmp : status_entry_cmp;
+
+	if (git_vector_init(&status->paired, 0, entrycmp) < 0) {
+		git__free(status);
+		return NULL;
+	}
+
+	return status;
+}
+
+static int status_validate_options(const git_status_options *opts)
+{
+	if (!opts)
+		return 0;
+
+	GITERR_CHECK_VERSION(opts, GIT_STATUS_OPTIONS_VERSION, "git_status_options");
+
+	if (opts->show > GIT_STATUS_SHOW_WORKDIR_ONLY) {
+		giterr_set(GITERR_INVALID, "Unknown status 'show' option");
+		return -1;
+	}
+
+	if ((opts->flags & GIT_STATUS_OPT_NO_REFRESH) != 0 &&
+		(opts->flags & GIT_STATUS_OPT_UPDATE_INDEX) != 0) {
+		giterr_set(GITERR_INVALID, "Updating index from status "
+			"is not allowed when index refresh is disabled");
+		return -1;
+	}
+
+	return 0;
+}
+
+int git_status_list_new(
+	git_status_list **out,
+	git_repository *repo,
+	const git_status_options *opts)
+{
+	git_index *index = NULL;
+	git_status_list *status = NULL;
+	git_diff_options diffopt = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options findopt = GIT_DIFF_FIND_OPTIONS_INIT;
+	git_tree *head = NULL;
+	git_status_show_t show =
+		opts ? opts->show : GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
+	int error = 0;
+	unsigned int flags = opts ? opts->flags : GIT_STATUS_OPT_DEFAULTS;
+
+	*out = NULL;
+
+	if (status_validate_options(opts) < 0)
+		return -1;
+
+	if ((error = git_repository__ensure_not_bare(repo, "status")) < 0 ||
+		(error = git_repository_index(&index, repo)) < 0)
+		return error;
+
+	/* if there is no HEAD, that's okay - we'll make an empty iterator */
+	if ((error = git_repository_head_tree(&head, repo)) < 0) {
+		if (error != GIT_ENOTFOUND && error != GIT_EUNBORNBRANCH)
+			goto done;
+		giterr_clear();
+	}
+
+	/* refresh index from disk unless prevented */
+	if ((flags & GIT_STATUS_OPT_NO_REFRESH) == 0 &&
+		git_index_read(index, false) < 0)
+		giterr_clear();
+
+	status = git_status_list_alloc(index);
+	GITERR_CHECK_ALLOC(status);
+
+	if (opts) {
+		memcpy(&status->opts, opts, sizeof(git_status_options));
+		memcpy(&diffopt.pathspec, &opts->pathspec, sizeof(diffopt.pathspec));
+	}
+
+	diffopt.flags = GIT_DIFF_INCLUDE_TYPECHANGE;
+	findopt.flags = GIT_DIFF_FIND_FOR_UNTRACKED;
+
+	if ((flags & GIT_STATUS_OPT_INCLUDE_UNTRACKED) != 0)
+		diffopt.flags = diffopt.flags | GIT_DIFF_INCLUDE_UNTRACKED;
+	if ((flags & GIT_STATUS_OPT_INCLUDE_IGNORED) != 0)
+		diffopt.flags = diffopt.flags | GIT_DIFF_INCLUDE_IGNORED;
+	if ((flags & GIT_STATUS_OPT_INCLUDE_UNMODIFIED) != 0)
+		diffopt.flags = diffopt.flags | GIT_DIFF_INCLUDE_UNMODIFIED;
+	if ((flags & GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS) != 0)
+		diffopt.flags = diffopt.flags | GIT_DIFF_RECURSE_UNTRACKED_DIRS;
+	if ((flags & GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH) != 0)
+		diffopt.flags = diffopt.flags | GIT_DIFF_DISABLE_PATHSPEC_MATCH;
+	if ((flags & GIT_STATUS_OPT_RECURSE_IGNORED_DIRS) != 0)
+		diffopt.flags = diffopt.flags | GIT_DIFF_RECURSE_IGNORED_DIRS;
+	if ((flags & GIT_STATUS_OPT_EXCLUDE_SUBMODULES) != 0)
+		diffopt.flags = diffopt.flags | GIT_DIFF_IGNORE_SUBMODULES;
+	if ((flags & GIT_STATUS_OPT_UPDATE_INDEX) != 0)
+		diffopt.flags = diffopt.flags | GIT_DIFF_UPDATE_INDEX;
+	if ((flags & GIT_STATUS_OPT_INCLUDE_UNREADABLE) != 0)
+		diffopt.flags = diffopt.flags | GIT_DIFF_INCLUDE_UNREADABLE;
+	if ((flags & GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED) != 0)
+		diffopt.flags = diffopt.flags | GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED;
+
+	if ((flags & GIT_STATUS_OPT_RENAMES_FROM_REWRITES) != 0)
+		findopt.flags = findopt.flags |
+			GIT_DIFF_FIND_AND_BREAK_REWRITES |
+			GIT_DIFF_FIND_RENAMES_FROM_REWRITES |
+			GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY;
+
+	if (show != GIT_STATUS_SHOW_WORKDIR_ONLY) {
+		if ((error = git_diff_tree_to_index(
+				&status->head2idx, repo, head, index, &diffopt)) < 0)
+			goto done;
+
+		if ((flags & GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX) != 0 &&
+			(error = git_diff_find_similar(status->head2idx, &findopt)) < 0)
+			goto done;
+	}
+
+	if (show != GIT_STATUS_SHOW_INDEX_ONLY) {
+		if ((error = git_diff_index_to_workdir(
+				&status->idx2wd, repo, index, &diffopt)) < 0) {
+			goto done;
+		}
+
+		if ((flags & GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR) != 0 &&
+			(error = git_diff_find_similar(status->idx2wd, &findopt)) < 0)
+			goto done;
+	}
+
+	error = git_diff__paired_foreach(
+		status->head2idx, status->idx2wd, status_collect, status);
+	if (error < 0)
+		goto done;
+
+	if (flags & GIT_STATUS_OPT_SORT_CASE_SENSITIVELY)
+		git_vector_set_cmp(&status->paired, status_entry_cmp);
+	if (flags & GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY)
+		git_vector_set_cmp(&status->paired, status_entry_icmp);
+
+	if ((flags &
+		 (GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX |
+		  GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR |
+		  GIT_STATUS_OPT_SORT_CASE_SENSITIVELY |
+		  GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY)) != 0)
+		git_vector_sort(&status->paired);
+
+done:
+	if (error < 0) {
+		git_status_list_free(status);
+		status = NULL;
+	}
+
+	*out = status;
+
+	git_tree_free(head);
+	git_index_free(index);
+
+	return error;
+}
+
+size_t git_status_list_entrycount(git_status_list *status)
+{
+	assert(status);
+
+	return status->paired.length;
+}
+
+const git_status_entry *git_status_byindex(git_status_list *status, size_t i)
+{
+	assert(status);
+
+	return git_vector_get(&status->paired, i);
+}
+
+void git_status_list_free(git_status_list *status)
+{
+	if (status == NULL)
+		return;
+
+	git_diff_free(status->head2idx);
+	git_diff_free(status->idx2wd);
+
+	git_vector_free_deep(&status->paired);
+
+	git__memzero(status, sizeof(*status));
+	git__free(status);
+}
+
+int git_status_foreach_ext(
+	git_repository *repo,
+	const git_status_options *opts,
+	git_status_cb cb,
+	void *payload)
+{
+	git_status_list *status;
+	const git_status_entry *status_entry;
+	size_t i;
+	int error = 0;
+
+	if ((error = git_status_list_new(&status, repo, opts)) < 0) {
+		return error;
+	}
+
+	git_vector_foreach(&status->paired, i, status_entry) {
+		const char *path = status_entry->head_to_index ?
+			status_entry->head_to_index->old_file.path :
+			status_entry->index_to_workdir->old_file.path;
+
+		if ((error = cb(path, status_entry->status, payload)) != 0) {
+			giterr_set_after_callback(error);
+			break;
+		}
+	}
+
+	git_status_list_free(status);
+
+	return error;
+}
+
+int git_status_foreach(git_repository *repo, git_status_cb cb, void *payload)
+{
+	return git_status_foreach_ext(repo, NULL, cb, payload);
+}
+
+struct status_file_info {
+	char *expected;
+	unsigned int count;
+	unsigned int status;
+	int fnm_flags;
+	int ambiguous;
+};
+
+static int get_one_status(const char *path, unsigned int status, void *data)
+{
+	struct status_file_info *sfi = data;
+	int (*strcomp)(const char *a, const char *b);
+
+	sfi->count++;
+	sfi->status = status;
+
+	strcomp = (sfi->fnm_flags & FNM_CASEFOLD) ? git__strcasecmp : git__strcmp;
+
+	if (sfi->count > 1 ||
+		(strcomp(sfi->expected, path) != 0 &&
+		 p_fnmatch(sfi->expected, path, sfi->fnm_flags) != 0))
+	{
+		sfi->ambiguous = true;
+		return GIT_EAMBIGUOUS; /* giterr_set will be done by caller */
+	}
+
+	return 0;
+}
+
+int git_status_file(
+	unsigned int *status_flags,
+	git_repository *repo,
+	const char *path)
+{
+	int error;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	struct status_file_info sfi = {0};
+	git_index *index;
+
+	assert(status_flags && repo && path);
+
+	if ((error = git_repository_index__weakptr(&index, repo)) < 0)
+		return error;
+
+	if ((sfi.expected = git__strdup(path)) == NULL)
+		return -1;
+	if (index->ignore_case)
+		sfi.fnm_flags = FNM_CASEFOLD;
+
+	opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
+	opts.flags = GIT_STATUS_OPT_INCLUDE_IGNORED |
+		GIT_STATUS_OPT_RECURSE_IGNORED_DIRS |
+		GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS |
+		GIT_STATUS_OPT_INCLUDE_UNMODIFIED |
+		GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH;
+	opts.pathspec.count = 1;
+	opts.pathspec.strings = &sfi.expected;
+
+	error = git_status_foreach_ext(repo, &opts, get_one_status, &sfi);
+
+	if (error < 0 && sfi.ambiguous) {
+		giterr_set(GITERR_INVALID,
+			"Ambiguous path '%s' given to git_status_file", sfi.expected);
+		error = GIT_EAMBIGUOUS;
+	}
+
+	if (!error && !sfi.count) {
+		giterr_set(GITERR_INVALID,
+			"Attempt to get status of nonexistent file '%s'", path);
+		error = GIT_ENOTFOUND;
+	}
+
+	*status_flags = sfi.status;
+
+	git__free(sfi.expected);
+
+	return error;
+}
+
+int git_status_should_ignore(
+	int *ignored,
+	git_repository *repo,
+	const char *path)
+{
+	return git_ignore_path_is_ignored(ignored, repo, path);
+}
+
+int git_status_init_options(git_status_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_status_options, GIT_STATUS_OPTIONS_INIT);
+	return 0;
+}
+
+int git_status_list_get_perfdata(
+	git_diff_perfdata *out, const git_status_list *status)
+{
+	assert(out);
+	GITERR_CHECK_VERSION(out, GIT_DIFF_PERFDATA_VERSION, "git_diff_perfdata");
+
+	out->stat_calls = 0;
+	out->oid_calculations = 0;
+
+	if (status->head2idx) {
+		out->stat_calls += status->head2idx->perf.stat_calls;
+		out->oid_calculations += status->head2idx->perf.oid_calculations;
+	}
+	if (status->idx2wd) {
+		out->stat_calls += status->idx2wd->perf.stat_calls;
+		out->oid_calculations += status->idx2wd->perf.oid_calculations;
+	}
+
+	return 0;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/status.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/status.h
new file mode 100755
index 0000000..33008b8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/status.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_status_h__
+#define INCLUDE_status_h__
+
+#include "diff.h"
+#include "git2/status.h"
+#include "git2/diff.h"
+
+struct git_status_list {
+	git_status_options opts;
+
+	git_diff *head2idx;
+	git_diff *idx2wd;
+
+	git_vector paired;
+};
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/stransport_stream.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/stransport_stream.c
new file mode 100755
index 0000000..10e1916
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/stransport_stream.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifdef GIT_SECURE_TRANSPORT
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecureTransport.h>
+#include <Security/SecCertificate.h>
+
+#include "git2/transport.h"
+
+#include "socket_stream.h"
+#include "curl_stream.h"
+
+int stransport_error(OSStatus ret)
+{
+	CFStringRef message;
+
+	if (ret == noErr || ret == errSSLClosedGraceful) {
+		giterr_clear();
+		return 0;
+	}
+
+#if !TARGET_OS_IPHONE
+	message = SecCopyErrorMessageString(ret, NULL);
+	GITERR_CHECK_ALLOC(message);
+
+	giterr_set(GITERR_NET, "SecureTransport error: %s", CFStringGetCStringPtr(message, kCFStringEncodingUTF8));
+	CFRelease(message);
+#else
+    giterr_set(GITERR_NET, "SecureTransport error: OSStatus %d", (unsigned int)ret);
+#endif
+
+	return -1;
+}
+
+typedef struct {
+	git_stream parent;
+	git_stream *io;
+	SSLContextRef ctx;
+	CFDataRef der_data;
+	git_cert_x509 cert_info;
+} stransport_stream;
+
+int stransport_connect(git_stream *stream)
+{
+	stransport_stream *st = (stransport_stream *) stream;
+	int error;
+	SecTrustRef trust = NULL;
+	SecTrustResultType sec_res;
+	OSStatus ret;
+
+	if ((error = git_stream_connect(st->io)) < 0)
+		return error;
+
+	ret = SSLHandshake(st->ctx);
+	if (ret != errSSLServerAuthCompleted) {
+		giterr_set(GITERR_SSL, "unexpected return value from ssl handshake %d", ret);
+		return -1;
+	}
+
+	if ((ret = SSLCopyPeerTrust(st->ctx, &trust)) != noErr)
+		goto on_error;
+
+	if ((ret = SecTrustEvaluate(trust, &sec_res)) != noErr)
+		goto on_error;
+
+	CFRelease(trust);
+
+	if (sec_res == kSecTrustResultInvalid || sec_res == kSecTrustResultOtherError) {
+		giterr_set(GITERR_SSL, "internal security trust error");
+		return -1;
+	}
+
+	if (sec_res == kSecTrustResultDeny || sec_res == kSecTrustResultRecoverableTrustFailure ||
+	    sec_res == kSecTrustResultFatalTrustFailure)
+		return GIT_ECERTIFICATE;
+
+	return 0;
+
+on_error:
+	if (trust)
+		CFRelease(trust);
+
+	return stransport_error(ret);
+}
+
+int stransport_certificate(git_cert **out, git_stream *stream)
+{
+	stransport_stream *st = (stransport_stream *) stream;
+	SecTrustRef trust = NULL;
+	SecCertificateRef sec_cert;
+	OSStatus ret;
+
+	if ((ret = SSLCopyPeerTrust(st->ctx, &trust)) != noErr)
+		return stransport_error(ret);
+
+	sec_cert = SecTrustGetCertificateAtIndex(trust, 0);
+	st->der_data = SecCertificateCopyData(sec_cert);
+	CFRelease(trust);
+
+	if (st->der_data == NULL) {
+		giterr_set(GITERR_SSL, "retrieved invalid certificate data");
+		return -1;
+	}
+
+	st->cert_info.cert_type = GIT_CERT_X509;
+	st->cert_info.data = (void *) CFDataGetBytePtr(st->der_data);
+	st->cert_info.len = CFDataGetLength(st->der_data);
+
+	*out = (git_cert *)&st->cert_info;
+	return 0;
+}
+
+int stransport_set_proxy(git_stream *stream, const char *proxy)
+{
+	stransport_stream *st = (stransport_stream *) stream;
+
+	return git_stream_set_proxy(st->io, proxy);
+}
+
+/*
+ * Contrary to typical network IO callbacks, Secure Transport write callback is
+ * expected to write *all* passed data, not just as much as it can, and any
+ * other case would be considered a failure.
+ *
+ * This behavior is actually not specified in the Apple documentation, but is
+ * required for things to work correctly (and incidentally, that's also how
+ * Apple implements it in its projects at opensource.apple.com).
+ *
+ * Libgit2 streams happen to already have this very behavior so this is just
+ * passthrough.
+ */
+static OSStatus write_cb(SSLConnectionRef conn, const void *data, size_t *len)
+{
+	git_stream *io = (git_stream *) conn;
+
+	if (git_stream_write(io, data, *len, 0) < 0) {
+		return -36; /* "ioErr" from MacErrors.h which is not available on iOS */
+	}
+
+	return noErr;
+}
+
+ssize_t stransport_write(git_stream *stream, const char *data, size_t len, int flags)
+{
+	stransport_stream *st = (stransport_stream *) stream;
+	size_t data_len, processed;
+	OSStatus ret;
+
+	GIT_UNUSED(flags);
+
+	data_len = len;
+	if ((ret = SSLWrite(st->ctx, data, data_len, &processed)) != noErr)
+		return stransport_error(ret);
+
+	return processed;
+}
+
+/*
+ * Contrary to typical network IO callbacks, Secure Transport read callback is
+ * expected to read *exactly* the requested number of bytes, not just as much
+ * as it can, and any other case would be considered a failure.
+ *
+ * This behavior is actually not specified in the Apple documentation, but is
+ * required for things to work correctly (and incidentally, that's also how
+ * Apple implements it in its projects at opensource.apple.com).
+ */
+static OSStatus read_cb(SSLConnectionRef conn, void *data, size_t *len)
+{
+	git_stream *io = (git_stream *) conn;
+	OSStatus error = noErr;
+	size_t off = 0;
+	ssize_t ret;
+
+	do {
+		ret = git_stream_read(io, data + off, *len - off);
+		if (ret < 0) {
+			error = -36; /* "ioErr" from MacErrors.h which is not available on iOS */
+			break;
+		}
+		if (ret == 0) {
+			error = errSSLClosedGraceful;
+			break;
+		}
+
+		off += ret;
+	} while (off < *len);
+
+	*len = off;
+	return error;
+}
+
+ssize_t stransport_read(git_stream *stream, void *data, size_t len)
+{
+	stransport_stream *st = (stransport_stream *) stream;
+	size_t processed;
+	OSStatus ret;
+
+	if ((ret = SSLRead(st->ctx, data, len, &processed)) != noErr)
+		return stransport_error(ret);
+
+	return processed;
+}
+
+int stransport_close(git_stream *stream)
+{
+	stransport_stream *st = (stransport_stream *) stream;
+	OSStatus ret;
+
+	ret = SSLClose(st->ctx);
+	if (ret != noErr && ret != errSSLClosedGraceful)
+		return stransport_error(ret);
+
+	return git_stream_close(st->io);
+}
+
+void stransport_free(git_stream *stream)
+{
+	stransport_stream *st = (stransport_stream *) stream;
+
+	git_stream_free(st->io);
+	CFRelease(st->ctx);
+	if (st->der_data)
+		CFRelease(st->der_data);
+	git__free(st);
+}
+
+int git_stransport_stream_new(git_stream **out, const char *host, const char *port)
+{
+	stransport_stream *st;
+	int error;
+	OSStatus ret;
+
+	assert(out && host);
+
+	st = git__calloc(1, sizeof(stransport_stream));
+	GITERR_CHECK_ALLOC(st);
+
+#ifdef GIT_CURL
+	error = git_curl_stream_new(&st->io, host, port);
+#else
+	error = git_socket_stream_new(&st->io, host, port);
+#endif
+
+	if (error < 0){
+		git__free(st);
+		return error;
+	}
+
+	st->ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
+	if (!st->ctx) {
+		giterr_set(GITERR_NET, "failed to create SSL context");
+		return -1;
+	}
+
+	if ((ret = SSLSetIOFuncs(st->ctx, read_cb, write_cb)) != noErr ||
+	    (ret = SSLSetConnection(st->ctx, st->io)) != noErr ||
+	    (ret = SSLSetSessionOption(st->ctx, kSSLSessionOptionBreakOnServerAuth, true)) != noErr ||
+	    (ret = SSLSetProtocolVersionMin(st->ctx, kTLSProtocol1)) != noErr ||
+	    (ret = SSLSetProtocolVersionMax(st->ctx, kTLSProtocol12)) != noErr ||
+	    (ret = SSLSetPeerDomainName(st->ctx, host, strlen(host))) != noErr) {
+		git_stream_free((git_stream *)st);
+		return stransport_error(ret);
+	}
+
+	st->parent.version = GIT_STREAM_VERSION;
+	st->parent.encrypted = 1;
+	st->parent.proxy_support = git_stream_supports_proxy(st->io);
+	st->parent.connect = stransport_connect;
+	st->parent.certificate = stransport_certificate;
+	st->parent.set_proxy = stransport_set_proxy;
+	st->parent.read = stransport_read;
+	st->parent.write = stransport_write;
+	st->parent.close = stransport_close;
+	st->parent.free = stransport_free;
+
+	*out = (git_stream *) st;
+	return 0;
+}
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/stransport_stream.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/stransport_stream.h
new file mode 100755
index 0000000..714f902
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/stransport_stream.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_stransport_stream_h__
+#define INCLUDE_stransport_stream_h__
+
+#include "git2/sys/stream.h"
+
+extern int git_stransport_stream_new(git_stream **out, const char *host, const char *port);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/stream.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/stream.h
new file mode 100755
index 0000000..43fcc30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/stream.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_stream_h__
+#define INCLUDE_stream_h__
+
+#include "common.h"
+#include "git2/sys/stream.h"
+
+GIT_INLINE(int) git_stream_connect(git_stream *st)
+{
+	return st->connect(st);
+}
+
+GIT_INLINE(int) git_stream_is_encrypted(git_stream *st)
+{
+	return st->encrypted;
+}
+
+GIT_INLINE(int) git_stream_certificate(git_cert **out, git_stream *st)
+{
+	if (!st->encrypted) {
+		giterr_set(GITERR_INVALID, "an unencrypted stream does not have a certificate");
+		return -1;
+	}
+
+	return st->certificate(out, st);
+}
+
+GIT_INLINE(int) git_stream_supports_proxy(git_stream *st)
+{
+	return st->proxy_support;
+}
+
+GIT_INLINE(int) git_stream_set_proxy(git_stream *st, const char *proxy_url)
+{
+	if (!st->proxy_support) {
+		giterr_set(GITERR_INVALID, "proxy not supported on this stream");
+		return -1;
+	}
+
+	return st->set_proxy(st, proxy_url);
+}
+
+GIT_INLINE(ssize_t) git_stream_read(git_stream *st, void *data, size_t len)
+{
+	return st->read(st, data, len);
+}
+
+GIT_INLINE(ssize_t) git_stream_write(git_stream *st, const char *data, size_t len, int flags)
+{
+	return st->write(st, data, len, flags);
+}
+
+GIT_INLINE(int) git_stream_close(git_stream *st)
+{
+	return st->close(st);
+}
+
+GIT_INLINE(void) git_stream_free(git_stream *st)
+{
+	st->free(st);
+}
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/strmap.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/strmap.c
new file mode 100755
index 0000000..b26a13d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/strmap.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "strmap.h"
+
+int git_strmap_next(
+	void **data,
+	git_strmap_iter* iter,
+	git_strmap *map)
+{
+	if (!map)
+		return GIT_ERROR;
+
+	while (*iter != git_strmap_end(map)) {
+		if (!(git_strmap_has_data(map, *iter))) {
+			++(*iter);
+			continue;
+		}
+
+		*data = git_strmap_value_at(map, *iter);
+
+		++(*iter);
+
+		return GIT_OK;
+	}
+
+	return GIT_ITEROVER;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/strmap.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/strmap.h
new file mode 100755
index 0000000..5209847
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/strmap.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_strmap_h__
+#define INCLUDE_strmap_h__
+
+#include "common.h"
+
+#define kmalloc git__malloc
+#define kcalloc git__calloc
+#define krealloc git__realloc
+#define kreallocarray git__reallocarray
+#define kfree git__free
+#include "khash.h"
+
+__KHASH_TYPE(str, const char *, void *)
+typedef khash_t(str) git_strmap;
+typedef khiter_t git_strmap_iter;
+
+#define GIT__USE_STRMAP \
+	__KHASH_IMPL(str, static kh_inline, const char *, void *, 1, kh_str_hash_func, kh_str_hash_equal)
+
+#define git_strmap_alloc(hp) \
+	((*(hp) = kh_init(str)) == NULL) ? giterr_set_oom(), -1 : 0
+
+#define git_strmap_free(h)  kh_destroy(str, h), h = NULL
+#define git_strmap_clear(h) kh_clear(str, h)
+
+#define git_strmap_num_entries(h) kh_size(h)
+
+#define git_strmap_lookup_index(h, k)  kh_get(str, h, k)
+#define git_strmap_valid_index(h, idx) (idx != kh_end(h))
+
+#define git_strmap_exists(h, k) (kh_get(str, h, k) != kh_end(h))
+#define git_strmap_has_data(h, idx) kh_exist(h, idx)
+
+#define git_strmap_key(h, idx)             kh_key(h, idx)
+#define git_strmap_value_at(h, idx)        kh_val(h, idx)
+#define git_strmap_set_value_at(h, idx, v) kh_val(h, idx) = v
+#define git_strmap_delete_at(h, idx)       kh_del(str, h, idx)
+
+#define git_strmap_insert(h, key, val, rval) do { \
+	khiter_t __pos = kh_put(str, h, key, &rval); \
+	if (rval >= 0) { \
+		if (rval == 0) kh_key(h, __pos) = key; \
+		kh_val(h, __pos) = val; \
+	} } while (0)
+
+#define git_strmap_insert2(h, key, val, oldv, rval) do { \
+	khiter_t __pos = kh_put(str, h, key, &rval); \
+	if (rval >= 0) { \
+		if (rval == 0) { \
+			oldv = kh_val(h, __pos); \
+			kh_key(h, __pos) = key; \
+		} else { oldv = NULL; } \
+		kh_val(h, __pos) = val; \
+	} } while (0)
+
+#define git_strmap_delete(h, key) do { \
+	khiter_t __pos = git_strmap_lookup_index(h, key); \
+	if (git_strmap_valid_index(h, __pos)) \
+		git_strmap_delete_at(h, __pos); } while (0)
+
+#define git_strmap_foreach		kh_foreach
+#define git_strmap_foreach_value	kh_foreach_value
+
+#define git_strmap_begin		kh_begin
+#define git_strmap_end		kh_end
+
+int git_strmap_next(
+	void **data,
+	git_strmap_iter* iter,
+	git_strmap *map);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/strnlen.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/strnlen.h
new file mode 100755
index 0000000..eecfe3c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/strnlen.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_strlen_h__
+#define INCLUDE_strlen_h__
+
+#if defined(__MINGW32__) || defined(__sun) || defined(__APPLE__) || defined(__MidnightBSD__) ||\
+	(defined(_MSC_VER) && _MSC_VER < 1500)
+#   define NO_STRNLEN
+#endif
+
+#ifdef NO_STRNLEN
+GIT_INLINE(size_t) p_strnlen(const char *s, size_t maxlen) {
+	const char *end = memchr(s, 0, maxlen);
+	return end ? (size_t)(end - s) : maxlen;
+}
+#else
+#   define p_strnlen strnlen
+#endif
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/submodule.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/submodule.c
new file mode 100755
index 0000000..3d02874
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/submodule.c
@@ -0,0 +1,2001 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "git2/config.h"
+#include "git2/sys/config.h"
+#include "git2/types.h"
+#include "git2/index.h"
+#include "buffer.h"
+#include "buf_text.h"
+#include "vector.h"
+#include "posix.h"
+#include "config_file.h"
+#include "config.h"
+#include "repository.h"
+#include "submodule.h"
+#include "tree.h"
+#include "iterator.h"
+#include "path.h"
+#include "index.h"
+
+#define GIT_MODULES_FILE ".gitmodules"
+
+static git_cvar_map _sm_update_map[] = {
+	{GIT_CVAR_STRING, "checkout", GIT_SUBMODULE_UPDATE_CHECKOUT},
+	{GIT_CVAR_STRING, "rebase", GIT_SUBMODULE_UPDATE_REBASE},
+	{GIT_CVAR_STRING, "merge", GIT_SUBMODULE_UPDATE_MERGE},
+	{GIT_CVAR_STRING, "none", GIT_SUBMODULE_UPDATE_NONE},
+	{GIT_CVAR_FALSE, NULL, GIT_SUBMODULE_UPDATE_NONE},
+	{GIT_CVAR_TRUE, NULL, GIT_SUBMODULE_UPDATE_CHECKOUT},
+};
+
+static git_cvar_map _sm_ignore_map[] = {
+	{GIT_CVAR_STRING, "none", GIT_SUBMODULE_IGNORE_NONE},
+	{GIT_CVAR_STRING, "untracked", GIT_SUBMODULE_IGNORE_UNTRACKED},
+	{GIT_CVAR_STRING, "dirty", GIT_SUBMODULE_IGNORE_DIRTY},
+	{GIT_CVAR_STRING, "all", GIT_SUBMODULE_IGNORE_ALL},
+	{GIT_CVAR_FALSE, NULL, GIT_SUBMODULE_IGNORE_NONE},
+	{GIT_CVAR_TRUE, NULL, GIT_SUBMODULE_IGNORE_ALL},
+};
+
+static git_cvar_map _sm_recurse_map[] = {
+	{GIT_CVAR_STRING, "on-demand", GIT_SUBMODULE_RECURSE_ONDEMAND},
+	{GIT_CVAR_FALSE, NULL, GIT_SUBMODULE_RECURSE_NO},
+	{GIT_CVAR_TRUE, NULL, GIT_SUBMODULE_RECURSE_YES},
+};
+
+enum {
+	CACHE_OK = 0,
+	CACHE_REFRESH = 1,
+	CACHE_FLUSH = 2
+};
+enum {
+	GITMODULES_EXISTING = 0,
+	GITMODULES_CREATE = 1,
+};
+
+static kh_inline khint_t str_hash_no_trailing_slash(const char *s)
+{
+	khint_t h;
+
+	for (h = 0; *s; ++s)
+		if (s[1] != '\0' || *s != '/')
+			h = (h << 5) - h + *s;
+
+	return h;
+}
+
+static kh_inline int str_equal_no_trailing_slash(const char *a, const char *b)
+{
+	size_t alen = a ? strlen(a) : 0;
+	size_t blen = b ? strlen(b) : 0;
+
+	if (alen > 0 && a[alen - 1] == '/')
+		alen--;
+	if (blen > 0 && b[blen - 1] == '/')
+		blen--;
+
+	return (alen == blen && strncmp(a, b, alen) == 0);
+}
+
+__KHASH_IMPL(
+	str, static kh_inline, const char *, void *, 1,
+	str_hash_no_trailing_slash, str_equal_no_trailing_slash)
+
+static int submodule_alloc(git_submodule **out, git_repository *repo, const char *name);
+static git_config_backend *open_gitmodules(git_repository *repo, int gitmod);
+static int get_url_base(git_buf *url, git_repository *repo);
+static int lookup_head_remote_key(git_buf *remote_key, git_repository *repo);
+static int submodule_load_from_config(const git_config_entry *, void *);
+static int submodule_load_from_wd_lite(git_submodule *);
+static void submodule_get_index_status(unsigned int *, git_submodule *);
+static void submodule_get_wd_status(unsigned int *, git_submodule *, git_repository *, git_submodule_ignore_t);
+static void submodule_update_from_index_entry(git_submodule *sm, const git_index_entry *ie);
+static void submodule_update_from_head_data(git_submodule *sm, mode_t mode, const git_oid *id);
+
+static int submodule_cmp(const void *a, const void *b)
+{
+	return strcmp(((git_submodule *)a)->name, ((git_submodule *)b)->name);
+}
+
+static int submodule_config_key_trunc_puts(git_buf *key, const char *suffix)
+{
+	ssize_t idx = git_buf_rfind(key, '.');
+	git_buf_truncate(key, (size_t)(idx + 1));
+	return git_buf_puts(key, suffix);
+}
+
+/*
+ * PUBLIC APIS
+ */
+
+static void submodule_set_lookup_error(int error, const char *name)
+{
+	if (!error)
+		return;
+
+	giterr_set(GITERR_SUBMODULE, (error == GIT_ENOTFOUND) ?
+		"No submodule named '%s'" :
+		"Submodule '%s' has not been added yet", name);
+}
+
+typedef struct {
+	const char *path;
+	char *name;
+} fbp_data;
+
+static int find_by_path(const git_config_entry *entry, void *payload)
+{
+	fbp_data *data = payload;
+
+	if (!strcmp(entry->value, data->path)) {
+		const char *fdot, *ldot;
+		fdot = strchr(entry->name, '.');
+		ldot = strrchr(entry->name, '.');
+		data->name = git__strndup(fdot + 1, ldot - fdot - 1);
+		GITERR_CHECK_ALLOC(data->name);
+	}
+
+	return 0;
+}
+
+int git_submodule_lookup(
+	git_submodule **out, /* NULL if user only wants to test existence */
+	git_repository *repo,
+	const char *name)    /* trailing slash is allowed */
+{
+	int error;
+	unsigned int location;
+	git_submodule *sm;
+
+	assert(repo && name);
+
+	if ((error = submodule_alloc(&sm, repo, name)) < 0)
+		return error;
+
+	if ((error = git_submodule_reload(sm, false)) < 0) {
+		git_submodule_free(sm);
+		return error;
+	}
+
+	if ((error = git_submodule_location(&location, sm)) < 0) {
+		git_submodule_free(sm);
+		return error;
+	}
+
+	/* If it's not configured or we're looking by path  */
+	if (location == 0 || location == GIT_SUBMODULE_STATUS_IN_WD) {
+		git_config_backend *mods;
+		const char *pattern = "submodule\\..*\\.path";
+		git_buf path = GIT_BUF_INIT;
+		fbp_data data = { NULL, NULL };
+
+		git_buf_puts(&path, name);
+		while (path.ptr[path.size-1] == '/') {
+			path.ptr[--path.size] = '\0';
+		}
+		data.path = path.ptr;
+
+		mods = open_gitmodules(repo, GITMODULES_EXISTING);
+
+		if (mods)
+			error = git_config_file_foreach_match(mods, pattern, find_by_path, &data);
+
+		git_config_file_free(mods);
+
+		if (error < 0) {
+			git_submodule_free(sm);
+			return error;
+		}
+
+		if (data.name) {
+			git__free(sm->name);
+			sm->name = data.name;
+			sm->path = git_buf_detach(&path);
+
+			/* Try to load again with the right name */
+			if ((error = git_submodule_reload(sm, false)) < 0) {
+				git_submodule_free(sm);
+				return error;
+			}
+		}
+
+		git_buf_free(&path);
+	}
+
+	if ((error = git_submodule_location(&location, sm)) < 0) {
+		git_submodule_free(sm);
+		return error;
+	}
+
+	/* If we still haven't found it, do the WD check */
+	if (location == 0 || location == GIT_SUBMODULE_STATUS_IN_WD) {
+		git_submodule_free(sm);
+		error = GIT_ENOTFOUND;
+
+		/* If it's not configured, we still check if there's a repo at the path */
+		if (git_repository_workdir(repo)) {
+			git_buf path = GIT_BUF_INIT;
+			if (git_buf_join3(&path,
+					  '/', git_repository_workdir(repo), name, DOT_GIT) < 0)
+				return -1;
+
+			if (git_path_exists(path.ptr))
+				error = GIT_EEXISTS;
+
+			git_buf_free(&path);
+		}
+
+		submodule_set_lookup_error(error, name);
+		return error;
+	}
+
+	if (out)
+		*out = sm;
+	else
+		git_submodule_free(sm);
+
+	return 0;
+}
+
+static void submodule_free_dup(void *sm)
+{
+	git_submodule_free(sm);
+}
+
+static int submodule_get_or_create(git_submodule **out, git_repository *repo, git_strmap *map, const char *name)
+{
+	int error = 0;
+	khiter_t pos;
+	git_submodule *sm = NULL;
+
+	pos = git_strmap_lookup_index(map, name);
+	if (git_strmap_valid_index(map, pos)) {
+		sm = git_strmap_value_at(map, pos);
+		goto done;
+	}
+
+	/* if the submodule doesn't exist yet in the map, create it */
+	if ((error = submodule_alloc(&sm, repo, name)) < 0)
+		return error;
+
+	pos = kh_put(str, map, sm->name, &error);
+	/* nobody can beat us to adding it */
+	assert(error != 0);
+	if (error < 0) {
+		git_submodule_free(sm);
+		return error;
+	}
+
+	git_strmap_set_value_at(map, pos, sm);
+
+done:
+	GIT_REFCOUNT_INC(sm);
+	*out = sm;
+	return 0;
+}
+
+static int submodules_from_index(git_strmap *map, git_index *idx)
+{
+       int error;
+       git_iterator *i;
+       const git_index_entry *entry;
+
+       if ((error = git_iterator_for_index(&i, idx, 0, NULL, NULL)) < 0)
+               return error;
+
+       while (!(error = git_iterator_advance(&entry, i))) {
+               khiter_t pos = git_strmap_lookup_index(map, entry->path);
+               git_submodule *sm;
+
+               if (git_strmap_valid_index(map, pos)) {
+                       sm = git_strmap_value_at(map, pos);
+
+                       if (S_ISGITLINK(entry->mode))
+                               submodule_update_from_index_entry(sm, entry);
+                       else
+                               sm->flags |= GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE;
+               } else if (S_ISGITLINK(entry->mode)) {
+                       if (!submodule_get_or_create(&sm, git_index_owner(idx), map, entry->path)) {
+                               submodule_update_from_index_entry(sm, entry);
+                               git_submodule_free(sm);
+                       }
+               }
+       }
+
+       if (error == GIT_ITEROVER)
+               error = 0;
+
+       git_iterator_free(i);
+
+       return error;
+}
+
+static int submodules_from_head(git_strmap *map, git_tree *head)
+{
+       int error;
+       git_iterator *i;
+       const git_index_entry *entry;
+
+       if ((error = git_iterator_for_tree(&i, head, 0, NULL, NULL)) < 0)
+               return error;
+
+       while (!(error = git_iterator_advance(&entry, i))) {
+               khiter_t pos = git_strmap_lookup_index(map, entry->path);
+               git_submodule *sm;
+
+               if (git_strmap_valid_index(map, pos)) {
+                       sm = git_strmap_value_at(map, pos);
+
+                       if (S_ISGITLINK(entry->mode))
+                               submodule_update_from_head_data(sm, entry->mode, &entry->id);
+                       else
+                               sm->flags |= GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE;
+               } else if (S_ISGITLINK(entry->mode)) {
+                       if (!submodule_get_or_create(&sm, git_tree_owner(head), map, entry->path)) {
+                               submodule_update_from_head_data(
+                                       sm, entry->mode, &entry->id);
+                               git_submodule_free(sm);
+                       }
+               }
+       }
+
+       if (error == GIT_ITEROVER)
+               error = 0;
+
+       git_iterator_free(i);
+
+       return error;
+}
+
+/* If have_sm is true, sm is populated, otherwise map an repo are. */
+typedef struct {
+	int have_sm;
+	git_submodule *sm;
+	git_strmap *map;
+	git_repository *repo;
+} lfc_data;
+
+static int all_submodules(git_repository *repo, git_strmap *map)
+{
+	int error = 0;
+	git_index *idx = NULL;
+	git_tree *head = NULL;
+	const char *wd = NULL;
+	git_buf path = GIT_BUF_INIT;
+	git_submodule *sm;
+	git_config_backend *mods = NULL;
+	uint32_t mask;
+
+	assert(repo && map);
+
+	/* get sources that we will need to check */
+	if (git_repository_index(&idx, repo) < 0)
+		giterr_clear();
+	if (git_repository_head_tree(&head, repo) < 0)
+		giterr_clear();
+
+	wd = git_repository_workdir(repo);
+	if (wd && (error = git_buf_joinpath(&path, wd, GIT_MODULES_FILE)) < 0)
+		goto cleanup;
+
+	/* clear submodule flags that are to be refreshed */
+	mask = 0;
+	mask |= GIT_SUBMODULE_STATUS_IN_INDEX |
+		GIT_SUBMODULE_STATUS__INDEX_FLAGS |
+		GIT_SUBMODULE_STATUS__INDEX_OID_VALID |
+		GIT_SUBMODULE_STATUS__INDEX_MULTIPLE_ENTRIES;
+
+	mask |= GIT_SUBMODULE_STATUS_IN_HEAD |
+		GIT_SUBMODULE_STATUS__HEAD_OID_VALID;
+	mask |= GIT_SUBMODULE_STATUS_IN_CONFIG;
+	if (mask != 0)
+		mask |= GIT_SUBMODULE_STATUS_IN_WD |
+			GIT_SUBMODULE_STATUS__WD_SCANNED |
+			GIT_SUBMODULE_STATUS__WD_FLAGS |
+			GIT_SUBMODULE_STATUS__WD_OID_VALID;
+
+	/* add back submodule information from index */
+	if (idx) {
+		if ((error = submodules_from_index(map, idx)) < 0)
+			goto cleanup;
+	}
+	/* add submodule information from HEAD */
+	if (head) {
+		if ((error = submodules_from_head(map, head)) < 0)
+			goto cleanup;
+	}
+	/* add submodule information from .gitmodules */
+	if (wd) {
+		lfc_data data = { 0 };
+		data.map = map;
+		data.repo = repo;
+		if ((mods = open_gitmodules(repo, false)) != NULL &&
+		    (error = git_config_file_foreach(
+			    mods, submodule_load_from_config, &data)) < 0)
+			goto cleanup;
+	}
+	/* shallow scan submodules in work tree as needed */
+	if (wd && mask != 0) {
+		git_strmap_foreach_value(map, sm, {
+				submodule_load_from_wd_lite(sm);
+			});
+	}
+
+cleanup:
+	git_config_file_free(mods);
+	/* TODO: if we got an error, mark submodule config as invalid? */
+	git_index_free(idx);
+	git_tree_free(head);
+	git_buf_free(&path);
+	return error;
+}
+
+int git_submodule_foreach(
+	git_repository *repo,
+	int (*callback)(git_submodule *sm, const char *name, void *payload),
+	void *payload)
+{
+	git_vector snapshot = GIT_VECTOR_INIT;
+	git_strmap *submodules;
+	git_submodule *sm;
+	int error;
+	size_t i;
+
+	if ((error = git_strmap_alloc(&submodules)) < 0)
+		return error;
+
+	if ((error = all_submodules(repo, submodules)) < 0)
+		goto done;
+
+	if (!(error = git_vector_init(
+			&snapshot, kh_size(submodules), submodule_cmp))) {
+
+		git_strmap_foreach_value(submodules, sm, {
+			if ((error = git_vector_insert(&snapshot, sm)) < 0)
+				break;
+			GIT_REFCOUNT_INC(sm);
+		});
+	}
+
+	if (error < 0)
+		goto done;
+
+	git_vector_uniq(&snapshot, submodule_free_dup);
+
+	git_vector_foreach(&snapshot, i, sm) {
+		if ((error = callback(sm, sm->name, payload)) != 0) {
+			giterr_set_after_callback(error);
+			break;
+		}
+	}
+
+done:
+	git_vector_foreach(&snapshot, i, sm)
+		git_submodule_free(sm);
+	git_vector_free(&snapshot);
+
+	git_strmap_foreach_value(submodules, sm, {
+		git_submodule_free(sm);
+	});
+	git_strmap_free(submodules);
+
+	return error;
+}
+
+static int submodule_repo_init(
+	git_repository **out,
+	git_repository *parent_repo,
+	const char *path,
+	const char *url,
+	bool use_gitlink)
+{
+	int error = 0;
+	git_buf workdir = GIT_BUF_INIT, repodir = GIT_BUF_INIT;
+	git_repository_init_options initopt = GIT_REPOSITORY_INIT_OPTIONS_INIT;
+	git_repository *subrepo = NULL;
+
+	error = git_buf_joinpath(&workdir, git_repository_workdir(parent_repo), path);
+	if (error < 0)
+		goto cleanup;
+
+	initopt.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_NO_REINIT;
+	initopt.origin_url = url;
+
+	/* init submodule repository and add origin remote as needed */
+
+	/* New style: sub-repo goes in <repo-dir>/modules/<name>/ with a
+	 * gitlink in the sub-repo workdir directory to that repository
+	 *
+	 * Old style: sub-repo goes directly into repo/<name>/.git/
+	 */
+	 if (use_gitlink) {
+		error = git_buf_join3(
+			&repodir, '/', git_repository_path(parent_repo), "modules", path);
+		if (error < 0)
+			goto cleanup;
+
+		initopt.workdir_path = workdir.ptr;
+		initopt.flags |=
+			GIT_REPOSITORY_INIT_NO_DOTGIT_DIR |
+			GIT_REPOSITORY_INIT_RELATIVE_GITLINK;
+
+		error = git_repository_init_ext(&subrepo, repodir.ptr, &initopt);
+	} else
+		error = git_repository_init_ext(&subrepo, workdir.ptr, &initopt);
+
+cleanup:
+	git_buf_free(&workdir);
+	git_buf_free(&repodir);
+
+	*out = subrepo;
+
+	return error;
+}
+
+int git_submodule_add_setup(
+	git_submodule **out,
+	git_repository *repo,
+	const char *url,
+	const char *path,
+	int use_gitlink)
+{
+	int error = 0;
+	git_config_backend *mods = NULL;
+	git_submodule *sm = NULL;
+	git_buf name = GIT_BUF_INIT, real_url = GIT_BUF_INIT;
+	git_repository *subrepo = NULL;
+
+	assert(repo && url && path);
+
+	/* see if there is already an entry for this submodule */
+
+	if (git_submodule_lookup(NULL, repo, path) < 0)
+		giterr_clear();
+	else {
+		giterr_set(GITERR_SUBMODULE,
+			"Attempt to add submodule '%s' that already exists", path);
+		return GIT_EEXISTS;
+	}
+
+	/* validate and normalize path */
+
+	if (git__prefixcmp(path, git_repository_workdir(repo)) == 0)
+		path += strlen(git_repository_workdir(repo));
+
+	if (git_path_root(path) >= 0) {
+		giterr_set(GITERR_SUBMODULE, "Submodule path must be a relative path");
+		error = -1;
+		goto cleanup;
+	}
+
+	/* update .gitmodules */
+
+	if (!(mods = open_gitmodules(repo, GITMODULES_CREATE))) {
+		giterr_set(GITERR_SUBMODULE,
+			"Adding submodules to a bare repository is not supported");
+		return -1;
+	}
+
+	if ((error = git_buf_printf(&name, "submodule.%s.path", path)) < 0 ||
+		(error = git_config_file_set_string(mods, name.ptr, path)) < 0)
+		goto cleanup;
+
+	if ((error = submodule_config_key_trunc_puts(&name, "url")) < 0 ||
+		(error = git_config_file_set_string(mods, name.ptr, url)) < 0)
+		goto cleanup;
+
+	git_buf_clear(&name);
+
+	/* init submodule repository and add origin remote as needed */
+
+	error = git_buf_joinpath(&name, git_repository_workdir(repo), path);
+	if (error < 0)
+		goto cleanup;
+
+	/* if the repo does not already exist, then init a new repo and add it.
+	 * Otherwise, just add the existing repo.
+	 */
+	if (!(git_path_exists(name.ptr) &&
+		git_path_contains(&name, DOT_GIT))) {
+
+		/* resolve the actual URL to use */
+		if ((error = git_submodule_resolve_url(&real_url, repo, url)) < 0)
+			goto cleanup;
+
+		 if ((error = submodule_repo_init(&subrepo, repo, path, real_url.ptr, use_gitlink)) < 0)
+			goto cleanup;
+	}
+
+	if ((error = git_submodule_lookup(&sm, repo, path)) < 0)
+		goto cleanup;
+
+	error = git_submodule_init(sm, false);
+
+cleanup:
+	if (error && sm) {
+		git_submodule_free(sm);
+		sm = NULL;
+	}
+	if (out != NULL)
+		*out = sm;
+
+	git_config_file_free(mods);
+	git_repository_free(subrepo);
+	git_buf_free(&real_url);
+	git_buf_free(&name);
+
+	return error;
+}
+
+int git_submodule_repo_init(
+	git_repository **out,
+	const git_submodule *sm,
+	int use_gitlink)
+{
+	int error;
+	git_repository *sub_repo = NULL;
+	const char *configured_url;
+	git_config *cfg = NULL;
+	git_buf buf = GIT_BUF_INIT;
+
+	assert(out && sm);
+
+	/* get the configured remote url of the submodule */
+	if ((error = git_buf_printf(&buf, "submodule.%s.url", sm->name)) < 0 ||
+		(error = git_repository_config_snapshot(&cfg, sm->repo)) < 0 ||
+		(error = git_config_get_string(&configured_url, cfg, buf.ptr)) < 0 ||
+		(error = submodule_repo_init(&sub_repo, sm->repo, sm->path, configured_url, use_gitlink)) < 0)
+		goto done;
+
+	*out = sub_repo;
+
+done:
+	git_config_free(cfg);
+	git_buf_free(&buf);
+	return error;
+}
+
+int git_submodule_add_finalize(git_submodule *sm)
+{
+	int error;
+	git_index *index;
+
+	assert(sm);
+
+	if ((error = git_repository_index__weakptr(&index, sm->repo)) < 0 ||
+		(error = git_index_add_bypath(index, GIT_MODULES_FILE)) < 0)
+		return error;
+
+	return git_submodule_add_to_index(sm, true);
+}
+
+int git_submodule_add_to_index(git_submodule *sm, int write_index)
+{
+	int error;
+	git_repository *sm_repo = NULL;
+	git_index *index;
+	git_buf path = GIT_BUF_INIT;
+	git_commit *head;
+	git_index_entry entry;
+	struct stat st;
+
+	assert(sm);
+
+	/* force reload of wd OID by git_submodule_open */
+	sm->flags = sm->flags & ~GIT_SUBMODULE_STATUS__WD_OID_VALID;
+
+	if ((error = git_repository_index__weakptr(&index, sm->repo)) < 0 ||
+		(error = git_buf_joinpath(
+			&path, git_repository_workdir(sm->repo), sm->path)) < 0 ||
+		(error = git_submodule_open(&sm_repo, sm)) < 0)
+		goto cleanup;
+
+	/* read stat information for submodule working directory */
+	if (p_stat(path.ptr, &st) < 0) {
+		giterr_set(GITERR_SUBMODULE,
+			"Cannot add submodule without working directory");
+		error = -1;
+		goto cleanup;
+	}
+
+	memset(&entry, 0, sizeof(entry));
+	entry.path = sm->path;
+	git_index_entry__init_from_stat(
+		&entry, &st, !(git_index_caps(index) & GIT_INDEXCAP_NO_FILEMODE));
+
+	/* calling git_submodule_open will have set sm->wd_oid if possible */
+	if ((sm->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID) == 0) {
+		giterr_set(GITERR_SUBMODULE,
+			"Cannot add submodule without HEAD to index");
+		error = -1;
+		goto cleanup;
+	}
+	git_oid_cpy(&entry.id, &sm->wd_oid);
+
+	if ((error = git_commit_lookup(&head, sm_repo, &sm->wd_oid)) < 0)
+		goto cleanup;
+
+	entry.ctime.seconds = git_commit_time(head);
+	entry.ctime.nanoseconds = 0;
+	entry.mtime.seconds = git_commit_time(head);
+	entry.mtime.nanoseconds = 0;
+
+	git_commit_free(head);
+
+	/* add it */
+	error = git_index_add(index, &entry);
+
+	/* write it, if requested */
+	if (!error && write_index) {
+		error = git_index_write(index);
+
+		if (!error)
+			git_oid_cpy(&sm->index_oid, &sm->wd_oid);
+	}
+
+cleanup:
+	git_repository_free(sm_repo);
+	git_buf_free(&path);
+	return error;
+}
+
+const char *git_submodule_update_to_str(git_submodule_update_t update)
+{
+	int i;
+	for (i = 0; i < (int)ARRAY_SIZE(_sm_update_map); ++i)
+		if (_sm_update_map[i].map_value == (int)update)
+			return _sm_update_map[i].str_match;
+	return NULL;
+}
+
+git_repository *git_submodule_owner(git_submodule *submodule)
+{
+	assert(submodule);
+	return submodule->repo;
+}
+
+const char *git_submodule_name(git_submodule *submodule)
+{
+	assert(submodule);
+	return submodule->name;
+}
+
+const char *git_submodule_path(git_submodule *submodule)
+{
+	assert(submodule);
+	return submodule->path;
+}
+
+const char *git_submodule_url(git_submodule *submodule)
+{
+	assert(submodule);
+	return submodule->url;
+}
+
+int git_submodule_resolve_url(git_buf *out, git_repository *repo, const char *url)
+{
+	int error = 0;
+	git_buf normalized = GIT_BUF_INIT;
+
+	assert(out && repo && url);
+
+	git_buf_sanitize(out);
+
+	if (strchr(url, '\\')) {
+		char *p;
+		if ((error = git_buf_puts(&normalized, url)) < 0)
+			return error;
+
+		for (p = normalized.ptr; *p; p++) {
+			if (*p == '\\')
+				*p = '/';
+		}
+
+		url = normalized.ptr;
+	}
+
+	if (git_path_is_relative(url)) {
+		if (!(error = get_url_base(out, repo)))
+			error = git_path_apply_relative(out, url);
+	} else if (strchr(url, ':') != NULL || url[0] == '/') {
+		error = git_buf_sets(out, url);
+	} else {
+		giterr_set(GITERR_SUBMODULE, "Invalid format for submodule URL");
+		error = -1;
+	}
+
+	git_buf_free(&normalized);
+	return error;
+}
+
+static int write_var(git_repository *repo, const char *name, const char *var, const char *val)
+{
+	git_buf key = GIT_BUF_INIT;
+	git_config_backend *mods;
+	int error;
+
+	mods = open_gitmodules(repo, GITMODULES_CREATE);
+	if (!mods)
+		return -1;
+
+	if ((error = git_buf_printf(&key, "submodule.%s.%s", name, var)) < 0)
+		goto cleanup;
+
+	if (val)
+		error = git_config_file_set_string(mods, key.ptr, val);
+	else
+		error = git_config_file_delete(mods, key.ptr);
+
+	git_buf_free(&key);
+
+cleanup:
+	git_config_file_free(mods);
+	return error;
+}
+
+static int write_mapped_var(git_repository *repo, const char *name, git_cvar_map *maps, size_t nmaps, const char *var, int ival)
+{
+	git_cvar_t type;
+	const char *val;
+
+	if (git_config_lookup_map_enum(&type, &val, maps, nmaps, ival) < 0) {
+		giterr_set(GITERR_SUBMODULE, "invalid value for %s", var);
+		return -1;
+	}
+
+	if (type == GIT_CVAR_TRUE)
+		val = "true";
+
+	return write_var(repo, name, var, val);
+}
+
+const char *git_submodule_branch(git_submodule *submodule)
+{
+	assert(submodule);
+	return submodule->branch;
+}
+
+int git_submodule_set_branch(git_repository *repo, const char *name, const char *branch)
+{
+
+	assert(repo && name);
+
+	return write_var(repo, name, "branch", branch);
+}
+
+int git_submodule_set_url(git_repository *repo, const char *name, const char *url)
+{
+	assert(repo && name && url);
+
+	return write_var(repo, name, "url", url);
+}
+
+const git_oid *git_submodule_index_id(git_submodule *submodule)
+{
+	assert(submodule);
+
+	if (submodule->flags & GIT_SUBMODULE_STATUS__INDEX_OID_VALID)
+		return &submodule->index_oid;
+	else
+		return NULL;
+}
+
+const git_oid *git_submodule_head_id(git_submodule *submodule)
+{
+	assert(submodule);
+
+	if (submodule->flags & GIT_SUBMODULE_STATUS__HEAD_OID_VALID)
+		return &submodule->head_oid;
+	else
+		return NULL;
+}
+
+const git_oid *git_submodule_wd_id(git_submodule *submodule)
+{
+	assert(submodule);
+
+	/* load unless we think we have a valid oid */
+	if (!(submodule->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID)) {
+		git_repository *subrepo;
+
+		/* calling submodule open grabs the HEAD OID if possible */
+		if (!git_submodule_open_bare(&subrepo, submodule))
+			git_repository_free(subrepo);
+		else
+			giterr_clear();
+	}
+
+	if (submodule->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID)
+		return &submodule->wd_oid;
+	else
+		return NULL;
+}
+
+git_submodule_ignore_t git_submodule_ignore(git_submodule *submodule)
+{
+	assert(submodule);
+	return (submodule->ignore < GIT_SUBMODULE_IGNORE_NONE) ?
+		GIT_SUBMODULE_IGNORE_NONE : submodule->ignore;
+}
+
+int git_submodule_set_ignore(git_repository *repo, const char *name, git_submodule_ignore_t ignore)
+{
+	assert(repo && name);
+
+	return write_mapped_var(repo, name, _sm_ignore_map, ARRAY_SIZE(_sm_ignore_map), "ignore", ignore);
+}
+
+git_submodule_update_t git_submodule_update_strategy(git_submodule *submodule)
+{
+	assert(submodule);
+	return (submodule->update < GIT_SUBMODULE_UPDATE_CHECKOUT) ?
+		GIT_SUBMODULE_UPDATE_CHECKOUT : submodule->update;
+}
+
+int git_submodule_set_update(git_repository *repo, const char *name, git_submodule_update_t update)
+{
+	assert(repo && name);
+
+	return write_mapped_var(repo, name, _sm_update_map, ARRAY_SIZE(_sm_update_map), "update", update);
+}
+
+git_submodule_recurse_t git_submodule_fetch_recurse_submodules(
+	git_submodule *submodule)
+{
+	assert(submodule);
+	return submodule->fetch_recurse;
+}
+
+int git_submodule_set_fetch_recurse_submodules(git_repository *repo, const char *name, git_submodule_recurse_t recurse)
+{
+	assert(repo && name);
+
+	return write_mapped_var(repo, name, _sm_recurse_map, ARRAY_SIZE(_sm_recurse_map), "fetchRecurseSubmodules", recurse);
+}
+
+static int submodule_repo_create(
+	git_repository **out,
+	git_repository *parent_repo,
+	const char *path)
+{
+	int error = 0;
+	git_buf workdir = GIT_BUF_INIT, repodir = GIT_BUF_INIT;
+	git_repository_init_options initopt = GIT_REPOSITORY_INIT_OPTIONS_INIT;
+	git_repository *subrepo = NULL;
+
+	initopt.flags =
+		GIT_REPOSITORY_INIT_MKPATH |
+		GIT_REPOSITORY_INIT_NO_REINIT |
+		GIT_REPOSITORY_INIT_NO_DOTGIT_DIR |
+		GIT_REPOSITORY_INIT_RELATIVE_GITLINK;
+
+	/* Workdir: path to sub-repo working directory */
+	error = git_buf_joinpath(&workdir, git_repository_workdir(parent_repo), path);
+	if (error < 0)
+		goto cleanup;
+
+	initopt.workdir_path = workdir.ptr;
+
+	/**
+	 * Repodir: path to the sub-repo. sub-repo goes in:
+	 * <repo-dir>/modules/<name>/ with a gitlink in the 
+	 * sub-repo workdir directory to that repository.
+	 */
+	error = git_buf_join3(
+		&repodir, '/', git_repository_path(parent_repo), "modules", path);
+	if (error < 0)
+		goto cleanup;
+
+	error = git_repository_init_ext(&subrepo, repodir.ptr, &initopt);
+
+cleanup:
+	git_buf_free(&workdir);
+	git_buf_free(&repodir);
+
+	*out = subrepo;
+
+	return error;
+}
+
+/**
+ * Callback to override sub-repository creation when
+ * cloning a sub-repository.
+ */
+static int git_submodule_update_repo_init_cb(
+	git_repository **out,
+	const char *path,
+	int bare,
+	void *payload)
+{
+	git_submodule *sm;
+
+	GIT_UNUSED(bare);
+
+	sm = payload;
+
+	return submodule_repo_create(out, sm->repo, path);
+}
+
+int git_submodule_update_init_options(git_submodule_update_options *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_submodule_update_options, GIT_SUBMODULE_UPDATE_OPTIONS_INIT);
+	return 0;
+}
+
+int git_submodule_update(git_submodule *sm, int init, git_submodule_update_options *_update_options)
+{
+	int error;
+	unsigned int submodule_status;
+	git_config *config = NULL;
+	const char *submodule_url;
+	git_repository *sub_repo = NULL;
+	git_remote *remote = NULL;
+	git_object *target_commit = NULL;
+	git_buf buf = GIT_BUF_INIT;
+	git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
+	git_clone_options clone_options = GIT_CLONE_OPTIONS_INIT;
+
+	assert(sm);
+
+	if (_update_options)
+		memcpy(&update_options, _update_options, sizeof(git_submodule_update_options));
+
+	GITERR_CHECK_VERSION(&update_options, GIT_SUBMODULE_UPDATE_OPTIONS_VERSION, "git_submodule_update_options");
+
+	/* Copy over the remote callbacks */
+	memcpy(&clone_options.fetch_opts, &update_options.fetch_opts, sizeof(git_fetch_options));
+
+	/* Get the status of the submodule to determine if it is already initialized  */
+	if ((error = git_submodule_status(&submodule_status, sm->repo, sm->name, GIT_SUBMODULE_IGNORE_UNSPECIFIED)) < 0)
+		goto done;
+
+	/*
+	 * If submodule work dir is not already initialized, check to see
+	 * what we need to do (initialize, clone, return error...)
+	 */
+	if (submodule_status & GIT_SUBMODULE_STATUS_WD_UNINITIALIZED) {
+		/*
+		 * Work dir is not initialized, check to see if the submodule
+		 * info has been copied into .git/config
+		 */
+		if ((error = git_repository_config_snapshot(&config, sm->repo)) < 0 ||
+			(error = git_buf_printf(&buf, "submodule.%s.url", git_submodule_name(sm))) < 0)
+			goto done;
+
+		if ((error = git_config_get_string(&submodule_url, config, git_buf_cstr(&buf))) < 0) {
+			/*
+			 * If the error is not "not found" or if it is "not found" and we are not
+			 * initializing the submodule, then return error.
+			 */
+			if (error != GIT_ENOTFOUND)
+				goto done;
+
+			if (error == GIT_ENOTFOUND && !init) {
+				giterr_set(GITERR_SUBMODULE, "Submodule is not initialized.");
+				error = GIT_ERROR;
+				goto done;
+			}
+
+			/* The submodule has not been initialized yet - initialize it now.*/
+			if ((error = git_submodule_init(sm, 0)) < 0)
+				goto done;
+
+			git_config_free(config);
+			config = NULL;
+
+			if ((error = git_repository_config_snapshot(&config, sm->repo)) < 0 ||
+				(error = git_config_get_string(&submodule_url, config, git_buf_cstr(&buf))) < 0)
+				goto done;
+		}
+
+		/** submodule is initialized - now clone it **/
+		/* override repo creation */
+		clone_options.repository_cb = git_submodule_update_repo_init_cb;
+		clone_options.repository_cb_payload = sm;
+
+		/*
+		 * Do not perform checkout as part of clone, instead we 
+		 * will checkout the specific commit manually.
+		 */
+		clone_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_NONE;
+		update_options.checkout_opts.checkout_strategy = update_options.clone_checkout_strategy;
+
+		if ((error = git_clone(&sub_repo, submodule_url, sm->path, &clone_options)) < 0 ||
+			(error = git_repository_set_head_detached(sub_repo, git_submodule_index_id(sm))) < 0 ||
+			(error = git_checkout_head(sub_repo, &update_options.checkout_opts)) != 0)
+			goto done;
+	} else {
+		/**
+		 * Work dir is initialized - look up the commit in the parent repository's index,
+		 * update the workdir contents of the subrepository, and set the subrepository's
+		 * head to the new commit.
+		 */
+		if ((error = git_submodule_open(&sub_repo, sm)) < 0 ||
+			(error = git_object_lookup(&target_commit, sub_repo, git_submodule_index_id(sm), GIT_OBJ_COMMIT)) < 0 ||
+			(error = git_checkout_tree(sub_repo, target_commit, &update_options.checkout_opts)) != 0 ||
+			(error = git_repository_set_head_detached(sub_repo, git_submodule_index_id(sm))) < 0)
+			goto done;
+
+		/* Invalidate the wd flags as the workdir has been updated. */
+		sm->flags = sm->flags &
+			~(GIT_SUBMODULE_STATUS_IN_WD |
+		  	GIT_SUBMODULE_STATUS__WD_OID_VALID |
+		  	GIT_SUBMODULE_STATUS__WD_SCANNED);
+	}
+
+done:
+	git_buf_free(&buf);
+	git_config_free(config);
+	git_object_free(target_commit);
+	git_remote_free(remote);
+	git_repository_free(sub_repo);
+
+	return error;
+}
+
+int git_submodule_init(git_submodule *sm, int overwrite)
+{
+	int error;
+	const char *val;
+	git_buf key = GIT_BUF_INIT, effective_submodule_url = GIT_BUF_INIT;
+	git_config *cfg = NULL;
+
+	if (!sm->url) {
+		giterr_set(GITERR_SUBMODULE,
+			"No URL configured for submodule '%s'", sm->name);
+		return -1;
+	}
+
+	if ((error = git_repository_config(&cfg, sm->repo)) < 0)
+		return error;
+
+	/* write "submodule.NAME.url" */
+
+	if ((error = git_submodule_resolve_url(&effective_submodule_url, sm->repo, sm->url)) < 0 ||
+		(error = git_buf_printf(&key, "submodule.%s.url", sm->name)) < 0 ||
+		(error = git_config__update_entry(
+			cfg, key.ptr, effective_submodule_url.ptr, overwrite != 0, false)) < 0)
+		goto cleanup;
+
+	/* write "submodule.NAME.update" if not default */
+
+	val = (sm->update == GIT_SUBMODULE_UPDATE_CHECKOUT) ?
+		NULL : git_submodule_update_to_str(sm->update);
+
+	if ((error = git_buf_printf(&key, "submodule.%s.update", sm->name)) < 0 ||
+		(error = git_config__update_entry(
+			cfg, key.ptr, val, overwrite != 0, false)) < 0)
+		goto cleanup;
+
+	/* success */
+
+cleanup:
+	git_config_free(cfg);
+	git_buf_free(&key);
+	git_buf_free(&effective_submodule_url);
+
+	return error;
+}
+
+int git_submodule_sync(git_submodule *sm)
+{
+	int error = 0;
+	git_config *cfg = NULL;
+	git_buf key = GIT_BUF_INIT;
+	git_repository *smrepo = NULL;
+
+	if (!sm->url) {
+		giterr_set(GITERR_SUBMODULE,
+			"No URL configured for submodule '%s'", sm->name);
+		return -1;
+	}
+
+	/* copy URL over to config only if it already exists */
+
+	if (!(error = git_repository_config__weakptr(&cfg, sm->repo)) &&
+		!(error = git_buf_printf(&key, "submodule.%s.url", sm->name)))
+		error = git_config__update_entry(cfg, key.ptr, sm->url, true, true);
+
+	/* if submodule exists in the working directory, update remote url */
+
+	if (!error &&
+		(sm->flags & GIT_SUBMODULE_STATUS_IN_WD) != 0 &&
+		!(error = git_submodule_open(&smrepo, sm)))
+	{
+		git_buf remote_name = GIT_BUF_INIT;
+
+		if ((error = git_repository_config__weakptr(&cfg, smrepo)) < 0)
+			/* return error from reading submodule config */;
+		else if ((error = lookup_head_remote_key(&remote_name, smrepo)) < 0) {
+			giterr_clear();
+			error = git_buf_sets(&key, "remote.origin.url");
+		} else {
+			error = git_buf_join3(
+				&key, '.', "remote", remote_name.ptr, "url");
+			git_buf_free(&remote_name);
+		}
+
+		if (!error)
+			error = git_config__update_entry(cfg, key.ptr, sm->url, true, false);
+
+		git_repository_free(smrepo);
+	}
+
+	git_buf_free(&key);
+
+	return error;
+}
+
+static int git_submodule__open(
+	git_repository **subrepo, git_submodule *sm, bool bare)
+{
+	int error;
+	git_buf path = GIT_BUF_INIT;
+	unsigned int flags = GIT_REPOSITORY_OPEN_NO_SEARCH;
+	const char *wd;
+
+	assert(sm && subrepo);
+
+	if (git_repository__ensure_not_bare(
+			sm->repo, "open submodule repository") < 0)
+		return GIT_EBAREREPO;
+
+	wd = git_repository_workdir(sm->repo);
+
+	if (git_buf_joinpath(&path, wd, sm->path) < 0 ||
+		git_buf_joinpath(&path, path.ptr, DOT_GIT) < 0)
+		return -1;
+
+	sm->flags = sm->flags &
+		~(GIT_SUBMODULE_STATUS_IN_WD |
+		  GIT_SUBMODULE_STATUS__WD_OID_VALID |
+		  GIT_SUBMODULE_STATUS__WD_SCANNED);
+
+	if (bare)
+		flags |= GIT_REPOSITORY_OPEN_BARE;
+
+	error = git_repository_open_ext(subrepo, path.ptr, flags, wd);
+
+	/* if we opened the submodule successfully, grab HEAD OID, etc. */
+	if (!error) {
+		sm->flags |= GIT_SUBMODULE_STATUS_IN_WD |
+			GIT_SUBMODULE_STATUS__WD_SCANNED;
+
+		if (!git_reference_name_to_id(&sm->wd_oid, *subrepo, GIT_HEAD_FILE))
+			sm->flags |= GIT_SUBMODULE_STATUS__WD_OID_VALID;
+		else
+			giterr_clear();
+	} else if (git_path_exists(path.ptr)) {
+		sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED |
+			GIT_SUBMODULE_STATUS_IN_WD;
+	} else {
+		git_buf_rtruncate_at_char(&path, '/'); /* remove "/.git" */
+
+		if (git_path_isdir(path.ptr))
+			sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED;
+	}
+
+	git_buf_free(&path);
+
+	return error;
+}
+
+int git_submodule_open_bare(git_repository **subrepo, git_submodule *sm)
+{
+	return git_submodule__open(subrepo, sm, true);
+}
+
+int git_submodule_open(git_repository **subrepo, git_submodule *sm)
+{
+	return git_submodule__open(subrepo, sm, false);
+}
+
+static void submodule_update_from_index_entry(
+	git_submodule *sm, const git_index_entry *ie)
+{
+	bool already_found = (sm->flags & GIT_SUBMODULE_STATUS_IN_INDEX) != 0;
+
+	if (!S_ISGITLINK(ie->mode)) {
+		if (!already_found)
+			sm->flags |= GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE;
+	} else {
+		if (already_found)
+			sm->flags |= GIT_SUBMODULE_STATUS__INDEX_MULTIPLE_ENTRIES;
+		else
+			git_oid_cpy(&sm->index_oid, &ie->id);
+
+		sm->flags |= GIT_SUBMODULE_STATUS_IN_INDEX |
+			GIT_SUBMODULE_STATUS__INDEX_OID_VALID;
+	}
+}
+
+static int submodule_update_index(git_submodule *sm)
+{
+	git_index *index;
+	const git_index_entry *ie;
+
+	if (git_repository_index__weakptr(&index, sm->repo) < 0)
+		return -1;
+
+	sm->flags = sm->flags &
+		~(GIT_SUBMODULE_STATUS_IN_INDEX |
+		  GIT_SUBMODULE_STATUS__INDEX_OID_VALID);
+
+	if (!(ie = git_index_get_bypath(index, sm->path, 0)))
+		return 0;
+
+	submodule_update_from_index_entry(sm, ie);
+
+	return 0;
+}
+
+static void submodule_update_from_head_data(
+	git_submodule *sm, mode_t mode, const git_oid *id)
+{
+	if (!S_ISGITLINK(mode))
+		sm->flags |= GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE;
+	else {
+		git_oid_cpy(&sm->head_oid, id);
+
+		sm->flags |= GIT_SUBMODULE_STATUS_IN_HEAD |
+			GIT_SUBMODULE_STATUS__HEAD_OID_VALID;
+	}
+}
+
+static int submodule_update_head(git_submodule *submodule)
+{
+	git_tree *head = NULL;
+	git_tree_entry *te = NULL;
+
+	submodule->flags = submodule->flags &
+		~(GIT_SUBMODULE_STATUS_IN_HEAD |
+		  GIT_SUBMODULE_STATUS__HEAD_OID_VALID);
+
+	/* if we can't look up file in current head, then done */
+	if (git_repository_head_tree(&head, submodule->repo) < 0 ||
+		git_tree_entry_bypath(&te, head, submodule->path) < 0)
+		giterr_clear();
+	else
+		submodule_update_from_head_data(submodule, te->attr, &te->oid);
+
+	git_tree_entry_free(te);
+	git_tree_free(head);
+	return 0;
+}
+
+
+int git_submodule_reload(git_submodule *sm, int force)
+{
+	int error = 0;
+	git_config_backend *mods;
+	lfc_data data = { 0 };
+
+	GIT_UNUSED(force);
+
+	assert(sm);
+
+	/* refresh index data */
+	if ((error = submodule_update_index(sm)) < 0)
+		return error;
+
+	/* refresh HEAD tree data */
+	if ((error = submodule_update_head(sm)) < 0)
+		return error;
+
+	/* done if bare */
+	if (git_repository_is_bare(sm->repo))
+		return error;
+
+	/* refresh config data */
+	mods = open_gitmodules(sm->repo, GITMODULES_EXISTING);
+	if (mods != NULL) {
+		git_buf path = GIT_BUF_INIT;
+
+		git_buf_sets(&path, "submodule\\.");
+		git_buf_text_puts_escape_regex(&path, sm->name);
+		git_buf_puts(&path, "\\..*");
+
+		if (git_buf_oom(&path)) {
+			error = -1;
+		} else {
+			data.have_sm = 1;
+			data.sm = sm;
+			error = git_config_file_foreach_match(
+				mods, path.ptr, submodule_load_from_config, &data);
+		}
+
+		git_buf_free(&path);
+		git_config_file_free(mods);
+
+		if (error < 0)
+			return error;
+	}
+
+	/* refresh wd data */
+	sm->flags &=
+		~(GIT_SUBMODULE_STATUS_IN_WD | GIT_SUBMODULE_STATUS__WD_OID_VALID |
+		  GIT_SUBMODULE_STATUS__WD_FLAGS);
+
+	return submodule_load_from_wd_lite(sm);
+}
+
+static void submodule_copy_oid_maybe(
+	git_oid *tgt, const git_oid *src, bool valid)
+{
+	if (tgt) {
+		if (valid)
+			memcpy(tgt, src, sizeof(*tgt));
+		else
+			memset(tgt, 0, sizeof(*tgt));
+	}
+}
+
+int git_submodule__status(
+	unsigned int *out_status,
+	git_oid *out_head_id,
+	git_oid *out_index_id,
+	git_oid *out_wd_id,
+	git_submodule *sm,
+	git_submodule_ignore_t ign)
+{
+	unsigned int status;
+	git_repository *smrepo = NULL;
+
+	if (ign == GIT_SUBMODULE_IGNORE_UNSPECIFIED)
+		ign = sm->ignore;
+
+	/* only return location info if ignore == all */
+	if (ign == GIT_SUBMODULE_IGNORE_ALL) {
+		*out_status = (sm->flags & GIT_SUBMODULE_STATUS__IN_FLAGS);
+		return 0;
+	}
+
+	/* refresh the index OID */
+	if (submodule_update_index(sm) < 0)
+		return -1;
+
+	/* refresh the HEAD OID */
+	if (submodule_update_head(sm) < 0)
+		return -1;
+
+	/* for ignore == dirty, don't scan the working directory */
+	if (ign == GIT_SUBMODULE_IGNORE_DIRTY) {
+		/* git_submodule_open_bare will load WD OID data */
+		if (git_submodule_open_bare(&smrepo, sm) < 0)
+			giterr_clear();
+		else
+			git_repository_free(smrepo);
+		smrepo = NULL;
+	} else if (git_submodule_open(&smrepo, sm) < 0) {
+		giterr_clear();
+		smrepo = NULL;
+	}
+
+	status = GIT_SUBMODULE_STATUS__CLEAR_INTERNAL(sm->flags);
+
+	submodule_get_index_status(&status, sm);
+	submodule_get_wd_status(&status, sm, smrepo, ign);
+
+	git_repository_free(smrepo);
+
+	*out_status = status;
+
+	submodule_copy_oid_maybe(out_head_id, &sm->head_oid,
+		(sm->flags & GIT_SUBMODULE_STATUS__HEAD_OID_VALID) != 0);
+	submodule_copy_oid_maybe(out_index_id, &sm->index_oid,
+		(sm->flags & GIT_SUBMODULE_STATUS__INDEX_OID_VALID) != 0);
+	submodule_copy_oid_maybe(out_wd_id, &sm->wd_oid,
+		(sm->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID) != 0);
+
+	return 0;
+}
+
+int git_submodule_status(unsigned int *status, git_repository *repo, const char *name, git_submodule_ignore_t ignore)
+{
+	git_submodule *sm;
+	int error;
+
+	assert(status && repo && name);
+
+	if ((error = git_submodule_lookup(&sm, repo, name)) < 0)
+		return error;
+
+	error = git_submodule__status(status, NULL, NULL, NULL, sm, ignore);
+	git_submodule_free(sm);
+
+	return error;
+}
+
+int git_submodule_location(unsigned int *location, git_submodule *sm)
+{
+	assert(location && sm);
+
+	return git_submodule__status(
+		location, NULL, NULL, NULL, sm, GIT_SUBMODULE_IGNORE_ALL);
+}
+
+
+/*
+ * INTERNAL FUNCTIONS
+ */
+
+static int submodule_alloc(
+	git_submodule **out, git_repository *repo, const char *name)
+{
+	size_t namelen;
+	git_submodule *sm;
+
+	if (!name || !(namelen = strlen(name))) {
+		giterr_set(GITERR_SUBMODULE, "Invalid submodule name");
+		return -1;
+	}
+
+	sm = git__calloc(1, sizeof(git_submodule));
+	GITERR_CHECK_ALLOC(sm);
+
+	sm->name = sm->path = git__strdup(name);
+	if (!sm->name) {
+		git__free(sm);
+		return -1;
+	}
+
+	GIT_REFCOUNT_INC(sm);
+	sm->ignore = sm->ignore_default = GIT_SUBMODULE_IGNORE_NONE;
+	sm->update = sm->update_default = GIT_SUBMODULE_UPDATE_CHECKOUT;
+	sm->fetch_recurse = sm->fetch_recurse_default = GIT_SUBMODULE_RECURSE_NO;
+	sm->repo   = repo;
+	sm->branch = NULL;
+
+	*out = sm;
+	return 0;
+}
+
+static void submodule_release(git_submodule *sm)
+{
+	if (!sm)
+		return;
+
+	if (sm->repo) {
+		sm->repo = NULL;
+	}
+
+	if (sm->path != sm->name)
+		git__free(sm->path);
+	git__free(sm->name);
+	git__free(sm->url);
+	git__free(sm->branch);
+	git__memzero(sm, sizeof(*sm));
+	git__free(sm);
+}
+
+void git_submodule_free(git_submodule *sm)
+{
+	if (!sm)
+		return;
+	GIT_REFCOUNT_DEC(sm, submodule_release);
+}
+
+static int submodule_config_error(const char *property, const char *value)
+{
+	giterr_set(GITERR_INVALID,
+		"Invalid value for submodule '%s' property: '%s'", property, value);
+	return -1;
+}
+
+int git_submodule_parse_ignore(git_submodule_ignore_t *out, const char *value)
+{
+	int val;
+
+	if (git_config_lookup_map_value(
+			&val, _sm_ignore_map, ARRAY_SIZE(_sm_ignore_map), value) < 0) {
+		*out = GIT_SUBMODULE_IGNORE_NONE;
+		return submodule_config_error("ignore", value);
+	}
+
+	*out = (git_submodule_ignore_t)val;
+	return 0;
+}
+
+int git_submodule_parse_update(git_submodule_update_t *out, const char *value)
+{
+	int val;
+
+	if (git_config_lookup_map_value(
+			&val, _sm_update_map, ARRAY_SIZE(_sm_update_map), value) < 0) {
+		*out = GIT_SUBMODULE_UPDATE_CHECKOUT;
+		return submodule_config_error("update", value);
+	}
+
+	*out = (git_submodule_update_t)val;
+	return 0;
+}
+
+int git_submodule_parse_recurse(git_submodule_recurse_t *out, const char *value)
+{
+	int val;
+
+	if (git_config_lookup_map_value(
+			&val, _sm_recurse_map, ARRAY_SIZE(_sm_recurse_map), value) < 0) {
+		*out = GIT_SUBMODULE_RECURSE_YES;
+		return submodule_config_error("recurse", value);
+	}
+
+	*out = (git_submodule_recurse_t)val;
+	return 0;
+}
+
+static int submodule_load_from_config(
+	const git_config_entry *entry, void *payload)
+{
+	const char *namestart, *property;
+	const char *key = entry->name, *value = entry->value, *path;
+	char *alternate = NULL, *replaced = NULL;
+	git_buf name = GIT_BUF_INIT;
+	lfc_data *data = payload;
+	git_submodule *sm;
+	int error = 0;
+
+	if (git__prefixcmp(key, "submodule.") != 0)
+		return 0;
+
+	namestart = key + strlen("submodule.");
+	property  = strrchr(namestart, '.');
+
+	if (!property || (property == namestart))
+		return 0;
+
+	property++;
+	path = !strcasecmp(property, "path") ? value : NULL;
+
+	if ((error = git_buf_set(&name, namestart, property - namestart -1)) < 0)
+		goto done;
+
+	if (data->have_sm) {
+		sm = data->sm;
+	} else {
+		khiter_t pos;
+		git_strmap *map = data->map;
+		pos = git_strmap_lookup_index(map, path ? path : name.ptr);
+		if (git_strmap_valid_index(map, pos)) {
+			sm = git_strmap_value_at(map, pos);
+		} else {
+			if ((error = submodule_alloc(&sm, data->repo, name.ptr)) < 0)
+				goto done;
+
+			git_strmap_insert(map, sm->name, sm, error);
+			assert(error != 0);
+			if (error < 0)
+				goto done;
+			error = 0;
+		}
+	}
+
+	sm->flags |= GIT_SUBMODULE_STATUS_IN_CONFIG;
+
+	/* Only from config might we get differing names & paths.  If so, then
+	 * update the submodule and insert under the alternative key.
+	 */
+
+	/* TODO: if case insensitive filesystem, then the following strcmps
+	 * should be strcasecmp
+	 */
+
+	if (strcmp(sm->name, name.ptr) != 0) { /* name changed */
+		if (sm->path && !strcmp(sm->path, name.ptr)) { /* already set as path */
+			replaced = sm->name;
+			sm->name = sm->path;
+		} else {
+			if (sm->name != sm->path)
+				replaced = sm->name;
+			alternate = sm->name = git_buf_detach(&name);
+		}
+	}
+	else if (path && strcmp(path, sm->path) != 0) { /* path changed */
+		if (!strcmp(sm->name, value)) { /* already set as name */
+			replaced = sm->path;
+			sm->path = sm->name;
+		} else {
+			if (sm->path != sm->name)
+				replaced = sm->path;
+			if ((alternate = git__strdup(value)) == NULL) {
+				error = -1;
+				goto done;
+			}
+			sm->path = alternate;
+		}
+	}
+
+	/* Deregister under name being replaced */
+	if (replaced) {
+		git__free(replaced);
+	}
+
+	/* TODO: Look up path in index and if it is present but not a GITLINK
+	 * then this should be deleted (at least to match git's behavior)
+	 */
+
+	if (path)
+		goto done;
+
+	/* copy other properties into submodule entry */
+	if (strcasecmp(property, "url") == 0) {
+		git__free(sm->url);
+		sm->url = NULL;
+
+		if (value != NULL && (sm->url = git__strdup(value)) == NULL) {
+			error = -1;
+			goto done;
+		}
+	}
+	else if (strcasecmp(property, "branch") == 0) {
+		git__free(sm->branch);
+		sm->branch = NULL;
+
+		if (value != NULL && (sm->branch = git__strdup(value)) == NULL) {
+			error = -1;
+			goto done;
+		}
+	}
+	else if (strcasecmp(property, "update") == 0) {
+		if ((error = git_submodule_parse_update(&sm->update, value)) < 0)
+			goto done;
+		sm->update_default = sm->update;
+	}
+	else if (strcasecmp(property, "fetchRecurseSubmodules") == 0) {
+		if ((error = git_submodule_parse_recurse(&sm->fetch_recurse, value)) < 0)
+			goto done;
+		sm->fetch_recurse_default = sm->fetch_recurse;
+	}
+	else if (strcasecmp(property, "ignore") == 0) {
+		if ((error = git_submodule_parse_ignore(&sm->ignore, value)) < 0)
+			goto done;
+		sm->ignore_default = sm->ignore;
+	}
+	/* ignore other unknown submodule properties */
+
+done:
+	git_buf_free(&name);
+	return error;
+}
+
+static int submodule_load_from_wd_lite(git_submodule *sm)
+{
+	git_buf path = GIT_BUF_INIT;
+
+	if (git_buf_joinpath(&path, git_repository_workdir(sm->repo), sm->path) < 0)
+		return -1;
+
+	if (git_path_isdir(path.ptr))
+		sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED;
+
+	if (git_path_contains(&path, DOT_GIT))
+		sm->flags |= GIT_SUBMODULE_STATUS_IN_WD;
+
+	git_buf_free(&path);
+	return 0;
+}
+
+static git_config_backend *open_gitmodules(
+	git_repository *repo,
+	int okay_to_create)
+{
+	const char *workdir = git_repository_workdir(repo);
+	git_buf path = GIT_BUF_INIT;
+	git_config_backend *mods = NULL;
+
+	if (workdir != NULL) {
+		if (git_buf_joinpath(&path, workdir, GIT_MODULES_FILE) != 0)
+			return NULL;
+
+		if (okay_to_create || git_path_isfile(path.ptr)) {
+			/* git_config_file__ondisk should only fail if OOM */
+			if (git_config_file__ondisk(&mods, path.ptr) < 0)
+				mods = NULL;
+			/* open should only fail here if the file is malformed */
+			else if (git_config_file_open(mods, GIT_CONFIG_LEVEL_LOCAL) < 0) {
+				git_config_file_free(mods);
+				mods = NULL;
+			}
+		}
+	}
+
+	git_buf_free(&path);
+
+	return mods;
+}
+
+/* Lookup name of remote of the local tracking branch HEAD points to */
+static int lookup_head_remote_key(git_buf *remote_name, git_repository *repo)
+{
+	int error;
+	git_reference *head = NULL;
+	git_buf upstream_name = GIT_BUF_INIT;
+
+	/* lookup and dereference HEAD */
+	if ((error = git_repository_head(&head, repo)) < 0)
+		return error;
+
+	/**
+	 * If head does not refer to a branch, then return
+	 * GIT_ENOTFOUND to indicate that we could not find
+	 * a remote key for the local tracking branch HEAD points to.
+	 **/
+	if (!git_reference_is_branch(head)) {
+		giterr_set(GITERR_INVALID,
+			"HEAD does not refer to a branch.");
+		error = GIT_ENOTFOUND;
+		goto done;
+	}
+
+	/* lookup remote tracking branch of HEAD */
+	if ((error = git_branch_upstream_name(
+		&upstream_name,
+		repo,
+		git_reference_name(head))) < 0)
+		goto done;
+
+	/* lookup remote of remote tracking branch */
+	if ((error = git_branch_remote_name(remote_name, repo, upstream_name.ptr)) < 0)
+		goto done;
+
+done:
+	git_buf_free(&upstream_name);
+	git_reference_free(head);
+
+	return error;
+}
+
+/* Lookup the remote of the local tracking branch HEAD points to */
+static int lookup_head_remote(git_remote **remote, git_repository *repo)
+{
+	int error;
+	git_buf remote_name = GIT_BUF_INIT;
+
+	/* lookup remote of remote tracking branch name */
+	if (!(error = lookup_head_remote_key(&remote_name, repo)))
+		error = git_remote_lookup(remote, repo, remote_name.ptr);
+
+	git_buf_free(&remote_name);
+
+	return error;
+}
+
+/* Lookup remote, either from HEAD or fall back on origin */
+static int lookup_default_remote(git_remote **remote, git_repository *repo)
+{
+	int error = lookup_head_remote(remote, repo);
+
+	/* if that failed, use 'origin' instead */
+	if (error == GIT_ENOTFOUND)
+		error = git_remote_lookup(remote, repo, "origin");
+
+	if (error == GIT_ENOTFOUND)
+		giterr_set(
+			GITERR_SUBMODULE,
+			"Cannot get default remote for submodule - no local tracking "
+			"branch for HEAD and origin does not exist");
+
+	return error;
+}
+
+static int get_url_base(git_buf *url, git_repository *repo)
+{
+	int error;
+	git_remote *remote = NULL;
+
+	if (!(error = lookup_default_remote(&remote, repo))) {
+		error = git_buf_sets(url, git_remote_url(remote));
+		git_remote_free(remote);
+	}
+	else if (error == GIT_ENOTFOUND) {
+		/* if repository does not have a default remote, use workdir instead */
+		giterr_clear();
+		error = git_buf_sets(url, git_repository_workdir(repo));
+	}
+
+	return error;
+}
+
+static void submodule_get_index_status(unsigned int *status, git_submodule *sm)
+{
+	const git_oid *head_oid  = git_submodule_head_id(sm);
+	const git_oid *index_oid = git_submodule_index_id(sm);
+
+	*status = *status & ~GIT_SUBMODULE_STATUS__INDEX_FLAGS;
+
+	if (!head_oid) {
+		if (index_oid)
+			*status |= GIT_SUBMODULE_STATUS_INDEX_ADDED;
+	}
+	else if (!index_oid)
+		*status |= GIT_SUBMODULE_STATUS_INDEX_DELETED;
+	else if (!git_oid_equal(head_oid, index_oid))
+		*status |= GIT_SUBMODULE_STATUS_INDEX_MODIFIED;
+}
+
+
+static void submodule_get_wd_status(
+	unsigned int *status,
+	git_submodule *sm,
+	git_repository *sm_repo,
+	git_submodule_ignore_t ign)
+{
+	const git_oid *index_oid = git_submodule_index_id(sm);
+	const git_oid *wd_oid =
+		(sm->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID) ? &sm->wd_oid : NULL;
+	git_tree *sm_head = NULL;
+	git_index *index = NULL;
+	git_diff_options opt = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff;
+
+	*status = *status & ~GIT_SUBMODULE_STATUS__WD_FLAGS;
+
+	if (!index_oid) {
+		if (wd_oid)
+			*status |= GIT_SUBMODULE_STATUS_WD_ADDED;
+	}
+	else if (!wd_oid) {
+		if ((sm->flags & GIT_SUBMODULE_STATUS__WD_SCANNED) != 0 &&
+			(sm->flags & GIT_SUBMODULE_STATUS_IN_WD) == 0)
+			*status |= GIT_SUBMODULE_STATUS_WD_UNINITIALIZED;
+		else
+			*status |= GIT_SUBMODULE_STATUS_WD_DELETED;
+	}
+	else if (!git_oid_equal(index_oid, wd_oid))
+		*status |= GIT_SUBMODULE_STATUS_WD_MODIFIED;
+
+	/* if we have no repo, then we're done */
+	if (!sm_repo)
+		return;
+
+	/* the diffs below could be optimized with an early termination
+	 * option to the git_diff functions, but for now this is sufficient
+	 * (and certainly no worse that what core git does).
+	 */
+
+	if (ign == GIT_SUBMODULE_IGNORE_NONE)
+		opt.flags |= GIT_DIFF_INCLUDE_UNTRACKED;
+
+	(void)git_repository_index__weakptr(&index, sm_repo);
+
+	/* if we don't have an unborn head, check diff with index */
+	if (git_repository_head_tree(&sm_head, sm_repo) < 0)
+		giterr_clear();
+	else {
+		/* perform head to index diff on submodule */
+		if (git_diff_tree_to_index(&diff, sm_repo, sm_head, index, &opt) < 0)
+			giterr_clear();
+		else {
+			if (git_diff_num_deltas(diff) > 0)
+				*status |= GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED;
+			git_diff_free(diff);
+			diff = NULL;
+		}
+
+		git_tree_free(sm_head);
+	}
+
+	/* perform index-to-workdir diff on submodule */
+	if (git_diff_index_to_workdir(&diff, sm_repo, index, &opt) < 0)
+		giterr_clear();
+	else {
+		size_t untracked =
+			git_diff_num_deltas_of_type(diff, GIT_DELTA_UNTRACKED);
+
+		if (untracked > 0)
+			*status |= GIT_SUBMODULE_STATUS_WD_UNTRACKED;
+
+		if (git_diff_num_deltas(diff) != untracked)
+			*status |= GIT_SUBMODULE_STATUS_WD_WD_MODIFIED;
+
+		git_diff_free(diff);
+		diff = NULL;
+	}
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/submodule.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/submodule.h
new file mode 100755
index 0000000..2ef2031
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/submodule.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_submodule_h__
+#define INCLUDE_submodule_h__
+
+#include "git2/submodule.h"
+#include "git2/repository.h"
+#include "fileops.h"
+
+/* Notes:
+ *
+ * Submodule information can be in four places: the index, the config files
+ * (both .git/config and .gitmodules), the HEAD tree, and the working
+ * directory.
+ *
+ * In the index:
+ * - submodule is found by path
+ * - may be missing, present, or of the wrong type
+ * - will have an oid if present
+ *
+ * In the HEAD tree:
+ * - submodule is found by path
+ * - may be missing, present, or of the wrong type
+ * - will have an oid if present
+ *
+ * In the config files:
+ * - submodule is found by submodule "name" which is usually the path
+ * - may be missing or present
+ * - will have a name, path, url, and other properties
+ *
+ * In the working directory:
+ * - submodule is found by path
+ * - may be missing, an empty directory, a checked out directory,
+ *   or of the wrong type
+ * - if checked out, will have a HEAD oid
+ * - if checked out, will have git history that can be used to compare oids
+ * - if checked out, may have modified files and/or untracked files
+ */
+
+/**
+ * Description of submodule
+ *
+ * This record describes a submodule found in a repository.  There should be
+ * an entry for every submodule found in the HEAD and index, and for every
+ * submodule described in .gitmodules.  The fields are as follows:
+ *
+ * - `rc` tracks the refcount of how many hash table entries in the
+ *   git_submodule_cache there are for this submodule.  It only comes into
+ *   play if the name and path of the submodule differ.
+ *
+ * - `name` is the name of the submodule from .gitmodules.
+ * - `path` is the path to the submodule from the repo root.  It is almost
+ *    always the same as `name`.
+ * - `url` is the url for the submodule.
+ * - `update` is a git_submodule_update_t value - see gitmodules(5) update.
+ * - `update_default` is the update value from the config
+ * - `ignore` is a git_submodule_ignore_t value - see gitmodules(5) ignore.
+ * - `ignore_default` is the ignore value from the config
+ * - `fetch_recurse` is a git_submodule_recurse_t value - see gitmodules(5)
+ *    fetchRecurseSubmodules.
+ * - `fetch_recurse_default` is the recurse value from the config
+ *
+ * - `repo` is the parent repository that contains this submodule.
+ * - `flags` after for internal use, tracking where this submodule has been
+ *   found (head, index, config, workdir) and known status info, etc.
+ * - `head_oid` is the SHA1 for the submodule path in the repo HEAD.
+ * - `index_oid` is the SHA1 for the submodule recorded in the index.
+ * - `wd_oid` is the SHA1 for the HEAD of the checked out submodule.
+ *
+ * If the submodule has been added to .gitmodules but not yet git added,
+ * then the `index_oid` will be zero but still marked valid.  If the
+ * submodule has been deleted, but the delete has not been committed yet,
+ * then the `index_oid` will be set, but the `url` will be NULL.
+ */
+struct git_submodule {
+	git_refcount rc;
+
+	/* information from config */
+	char *name;
+	char *path; /* important: may just point to "name" string */
+	char *url;
+	char *branch;
+	git_submodule_update_t update;
+	git_submodule_update_t update_default;
+	git_submodule_ignore_t ignore;
+	git_submodule_ignore_t ignore_default;
+	git_submodule_recurse_t fetch_recurse;
+	git_submodule_recurse_t fetch_recurse_default;
+
+	/* internal information */
+	git_repository *repo;
+	uint32_t flags;
+	git_oid head_oid;
+	git_oid index_oid;
+	git_oid wd_oid;
+};
+
+/* Force revalidation of submodule data cache (alloc as needed) */
+extern int git_submodule_cache_refresh(git_repository *repo);
+
+/* Release all submodules */
+extern void git_submodule_cache_free(git_repository *repo);
+
+/* Additional flags on top of public GIT_SUBMODULE_STATUS values */
+enum {
+	GIT_SUBMODULE_STATUS__WD_SCANNED          = (1u << 20),
+	GIT_SUBMODULE_STATUS__HEAD_OID_VALID      = (1u << 21),
+	GIT_SUBMODULE_STATUS__INDEX_OID_VALID     = (1u << 22),
+	GIT_SUBMODULE_STATUS__WD_OID_VALID        = (1u << 23),
+	GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE  = (1u << 24),
+	GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE = (1u << 25),
+	GIT_SUBMODULE_STATUS__WD_NOT_SUBMODULE    = (1u << 26),
+	GIT_SUBMODULE_STATUS__INDEX_MULTIPLE_ENTRIES = (1u << 27),
+};
+
+#define GIT_SUBMODULE_STATUS__CLEAR_INTERNAL(S) \
+	((S) & ~(0xFFFFFFFFu << 20))
+
+/* Internal lookup does not attempt to refresh cached data */
+extern int git_submodule__lookup(
+	git_submodule **out, git_repository *repo, const char *path);
+
+/* Internal status fn returns status and optionally the various OIDs */
+extern int git_submodule__status(
+	unsigned int *out_status,
+	git_oid *out_head_id,
+	git_oid *out_index_id,
+	git_oid *out_wd_id,
+	git_submodule *sm,
+	git_submodule_ignore_t ign);
+
+/* Open submodule repository as bare repo for quick HEAD check, etc. */
+extern int git_submodule_open_bare(
+	git_repository **repo,
+	git_submodule *submodule);
+
+extern int git_submodule_parse_ignore(
+	git_submodule_ignore_t *out, const char *value);
+extern int git_submodule_parse_update(
+	git_submodule_update_t *out, const char *value);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sysdir.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sysdir.c
new file mode 100755
index 0000000..cd94a8b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sysdir.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "sysdir.h"
+#include "global.h"
+#include "buffer.h"
+#include "path.h"
+#include <ctype.h>
+#if GIT_WIN32
+#include "win32/findfile.h"
+#endif
+
+static int git_sysdir_guess_system_dirs(git_buf *out)
+{
+#ifdef GIT_WIN32
+	return git_win32__find_system_dirs(out, L"etc\\");
+#else
+	return git_buf_sets(out, "/etc");
+#endif
+}
+
+static int git_sysdir_guess_global_dirs(git_buf *out)
+{
+#ifdef GIT_WIN32
+	return git_win32__find_global_dirs(out);
+#else
+	return git_buf_sets(out, getenv("HOME"));
+#endif
+}
+
+static int git_sysdir_guess_xdg_dirs(git_buf *out)
+{
+#ifdef GIT_WIN32
+	return git_win32__find_xdg_dirs(out);
+#else
+	const char *env = NULL;
+
+	if ((env = getenv("XDG_CONFIG_HOME")) != NULL)
+		return git_buf_joinpath(out, env, "git");
+	else if ((env = getenv("HOME")) != NULL)
+		return git_buf_joinpath(out, env, ".config/git");
+
+	git_buf_clear(out);
+	return 0;
+#endif
+}
+
+static int git_sysdir_guess_template_dirs(git_buf *out)
+{
+#ifdef GIT_WIN32
+	return git_win32__find_system_dirs(out, L"share\\git-core\\templates");
+#else
+	return git_buf_sets(out, "/usr/share/git-core/templates");
+#endif
+}
+
+typedef int (*git_sysdir_guess_cb)(git_buf *out);
+
+static git_buf git_sysdir__dirs[GIT_SYSDIR__MAX] =
+	{ GIT_BUF_INIT, GIT_BUF_INIT, GIT_BUF_INIT, GIT_BUF_INIT };
+
+static git_sysdir_guess_cb git_sysdir__dir_guess[GIT_SYSDIR__MAX] = {
+	git_sysdir_guess_system_dirs,
+	git_sysdir_guess_global_dirs,
+	git_sysdir_guess_xdg_dirs,
+	git_sysdir_guess_template_dirs,
+};
+
+static int git_sysdir__dirs_shutdown_set = 0;
+
+int git_sysdir_global_init(void)
+{
+	git_sysdir_t i;
+	const git_buf *path;
+	int error = 0;
+
+	for (i = 0; !error && i < GIT_SYSDIR__MAX; i++)
+		error = git_sysdir_get(&path, i);
+
+	return error;
+}
+
+void git_sysdir_global_shutdown(void)
+{
+	int i;
+	for (i = 0; i < GIT_SYSDIR__MAX; ++i)
+		git_buf_free(&git_sysdir__dirs[i]);
+
+	git_sysdir__dirs_shutdown_set = 0;
+}
+
+static int git_sysdir_check_selector(git_sysdir_t which)
+{
+	if (which < GIT_SYSDIR__MAX)
+		return 0;
+
+	giterr_set(GITERR_INVALID, "config directory selector out of range");
+	return -1;
+}
+
+
+int git_sysdir_get(const git_buf **out, git_sysdir_t which)
+{
+	assert(out);
+
+	*out = NULL;
+
+	GITERR_CHECK_ERROR(git_sysdir_check_selector(which));
+
+	if (!git_buf_len(&git_sysdir__dirs[which])) {
+		/* prepare shutdown if we're going to need it */
+		if (!git_sysdir__dirs_shutdown_set) {
+			git__on_shutdown(git_sysdir_global_shutdown);
+			git_sysdir__dirs_shutdown_set = 1;
+		}
+
+		GITERR_CHECK_ERROR(
+			git_sysdir__dir_guess[which](&git_sysdir__dirs[which]));
+	}
+
+	*out = &git_sysdir__dirs[which];
+	return 0;
+}
+
+int git_sysdir_get_str(
+	char *out,
+	size_t outlen,
+	git_sysdir_t which)
+{
+	const git_buf *path = NULL;
+
+	GITERR_CHECK_ERROR(git_sysdir_check_selector(which));
+	GITERR_CHECK_ERROR(git_sysdir_get(&path, which));
+
+	if (!out || path->size >= outlen) {
+		giterr_set(GITERR_NOMEMORY, "Buffer is too short for the path");
+		return GIT_EBUFS;
+	}
+
+	git_buf_copy_cstr(out, outlen, path);
+	return 0;
+}
+
+#define PATH_MAGIC "$PATH"
+
+int git_sysdir_set(git_sysdir_t which, const char *search_path)
+{
+	const char *expand_path = NULL;
+	git_buf merge = GIT_BUF_INIT;
+
+	GITERR_CHECK_ERROR(git_sysdir_check_selector(which));
+
+	if (search_path != NULL)
+		expand_path = strstr(search_path, PATH_MAGIC);
+
+	/* init with default if not yet done and needed (ignoring error) */
+	if ((!search_path || expand_path) &&
+		!git_buf_len(&git_sysdir__dirs[which]))
+		git_sysdir__dir_guess[which](&git_sysdir__dirs[which]);
+
+	/* if $PATH is not referenced, then just set the path */
+	if (!expand_path)
+		return git_buf_sets(&git_sysdir__dirs[which], search_path);
+
+	/* otherwise set to join(before $PATH, old value, after $PATH) */
+	if (expand_path > search_path)
+		git_buf_set(&merge, search_path, expand_path - search_path);
+
+	if (git_buf_len(&git_sysdir__dirs[which]))
+		git_buf_join(&merge, GIT_PATH_LIST_SEPARATOR,
+			merge.ptr, git_sysdir__dirs[which].ptr);
+
+	expand_path += strlen(PATH_MAGIC);
+	if (*expand_path)
+		git_buf_join(&merge, GIT_PATH_LIST_SEPARATOR, merge.ptr, expand_path);
+
+	git_buf_swap(&git_sysdir__dirs[which], &merge);
+	git_buf_free(&merge);
+
+	return git_buf_oom(&git_sysdir__dirs[which]) ? -1 : 0;
+}
+
+static int git_sysdir_find_in_dirlist(
+	git_buf *path,
+	const char *name,
+	git_sysdir_t which,
+	const char *label)
+{
+	size_t len;
+	const char *scan, *next = NULL;
+	const git_buf *syspath;
+
+	GITERR_CHECK_ERROR(git_sysdir_get(&syspath, which));
+	if (!syspath || !git_buf_len(syspath))
+		goto done;
+
+	for (scan = git_buf_cstr(syspath); scan; scan = next) {
+		/* find unescaped separator or end of string */
+		for (next = scan; *next; ++next) {
+			if (*next == GIT_PATH_LIST_SEPARATOR &&
+				(next <= scan || next[-1] != '\\'))
+				break;
+		}
+
+		len = (size_t)(next - scan);
+		next = (*next ? next + 1 : NULL);
+		if (!len)
+			continue;
+
+		GITERR_CHECK_ERROR(git_buf_set(path, scan, len));
+		if (name)
+			GITERR_CHECK_ERROR(git_buf_joinpath(path, path->ptr, name));
+
+		if (git_path_exists(path->ptr))
+			return 0;
+	}
+
+done:
+	git_buf_free(path);
+	giterr_set(GITERR_OS, "The %s file '%s' doesn't exist", label, name);
+	return GIT_ENOTFOUND;
+}
+
+int git_sysdir_find_system_file(git_buf *path, const char *filename)
+{
+	return git_sysdir_find_in_dirlist(
+		path, filename, GIT_SYSDIR_SYSTEM, "system");
+}
+
+int git_sysdir_find_global_file(git_buf *path, const char *filename)
+{
+	return git_sysdir_find_in_dirlist(
+		path, filename, GIT_SYSDIR_GLOBAL, "global");
+}
+
+int git_sysdir_find_xdg_file(git_buf *path, const char *filename)
+{
+	return git_sysdir_find_in_dirlist(
+		path, filename, GIT_SYSDIR_XDG, "global/xdg");
+}
+
+int git_sysdir_find_template_dir(git_buf *path)
+{
+	return git_sysdir_find_in_dirlist(
+		path, NULL, GIT_SYSDIR_TEMPLATE, "template");
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sysdir.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sysdir.h
new file mode 100755
index 0000000..f1bbf0b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/sysdir.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sysdir_h__
+#define INCLUDE_sysdir_h__
+
+#include "common.h"
+#include "posix.h"
+#include "buffer.h"
+
+/**
+ * Find a "global" file (i.e. one in a user's home directory).
+ *
+ * @param path buffer to write the full path into
+ * @param filename name of file to find in the home directory
+ * @return 0 if found, GIT_ENOTFOUND if not found, or -1 on other OS error
+ */
+extern int git_sysdir_find_global_file(git_buf *path, const char *filename);
+
+/**
+ * Find an "XDG" file (i.e. one in user's XDG config path).
+ *
+ * @param path buffer to write the full path into
+ * @param filename name of file to find in the home directory
+ * @return 0 if found, GIT_ENOTFOUND if not found, or -1 on other OS error
+ */
+extern int git_sysdir_find_xdg_file(git_buf *path, const char *filename);
+
+/**
+ * Find a "system" file (i.e. one shared for all users of the system).
+ *
+ * @param path buffer to write the full path into
+ * @param filename name of file to find in the home directory
+ * @return 0 if found, GIT_ENOTFOUND if not found, or -1 on other OS error
+ */
+extern int git_sysdir_find_system_file(git_buf *path, const char *filename);
+
+/**
+ * Find template directory.
+ *
+ * @param path buffer to write the full path into
+ * @return 0 if found, GIT_ENOTFOUND if not found, or -1 on other OS error
+ */
+extern int git_sysdir_find_template_dir(git_buf *path);
+
+typedef enum {
+	GIT_SYSDIR_SYSTEM = 0,
+	GIT_SYSDIR_GLOBAL = 1,
+	GIT_SYSDIR_XDG    = 2,
+	GIT_SYSDIR_TEMPLATE = 3,
+	GIT_SYSDIR__MAX   = 4,
+} git_sysdir_t;
+
+/**
+ * Configures global data for configuration file search paths.
+ *
+ * @return 0 on success, <0 on failure
+ */
+extern int git_sysdir_global_init(void);
+
+/**
+ * Get the search path for global/system/xdg files
+ *
+ * @param out pointer to git_buf containing search path
+ * @param which which list of paths to return
+ * @return 0 on success, <0 on failure
+ */
+extern int git_sysdir_get(const git_buf **out, git_sysdir_t which);
+
+/**
+ * Get search path into a preallocated buffer
+ *
+ * @param out String buffer to write into
+ * @param outlen Size of string buffer
+ * @param which Which search path to return
+ * @return 0 on success, GIT_EBUFS if out is too small, <0 on other failure
+ */
+
+extern int git_sysdir_get_str(char *out, size_t outlen, git_sysdir_t which);
+
+/**
+ * Set search paths for global/system/xdg files
+ *
+ * The first occurrence of the magic string "$PATH" in the new value will
+ * be replaced with the old value of the search path.
+ *
+ * @param which Which search path to modify
+ * @param paths New search path (separated by GIT_PATH_LIST_SEPARATOR)
+ * @return 0 on success, <0 on failure (allocation error)
+ */
+extern int git_sysdir_set(git_sysdir_t which, const char *paths);
+
+/**
+ * Free the configuration file search paths.
+ */
+extern void git_sysdir_global_shutdown(void);
+
+#endif /* INCLUDE_sysdir_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tag.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tag.c
new file mode 100755
index 0000000..6e69d76
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tag.c
@@ -0,0 +1,511 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "commit.h"
+#include "tag.h"
+#include "signature.h"
+#include "message.h"
+#include "git2/object.h"
+#include "git2/repository.h"
+#include "git2/signature.h"
+#include "git2/odb_backend.h"
+
+void git_tag__free(void *_tag)
+{
+	git_tag *tag = _tag;
+	git_signature_free(tag->tagger);
+	git__free(tag->message);
+	git__free(tag->tag_name);
+	git__free(tag);
+}
+
+int git_tag_target(git_object **target, const git_tag *t)
+{
+	assert(t);
+	return git_object_lookup(target, t->object.repo, &t->target, t->type);
+}
+
+const git_oid *git_tag_target_id(const git_tag *t)
+{
+	assert(t);
+	return &t->target;
+}
+
+git_otype git_tag_target_type(const git_tag *t)
+{
+	assert(t);
+	return t->type;
+}
+
+const char *git_tag_name(const git_tag *t)
+{
+	assert(t);
+	return t->tag_name;
+}
+
+const git_signature *git_tag_tagger(const git_tag *t)
+{
+	return t->tagger;
+}
+
+const char *git_tag_message(const git_tag *t)
+{
+	assert(t);
+	return t->message;
+}
+
+static int tag_error(const char *str)
+{
+	giterr_set(GITERR_TAG, "Failed to parse tag. %s", str);
+	return -1;
+}
+
+static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end)
+{
+	static const char *tag_types[] = {
+		NULL, "commit\n", "tree\n", "blob\n", "tag\n"
+	};
+
+	unsigned int i;
+	size_t text_len, alloc_len;
+	char *search;
+
+	if (git_oid__parse(&tag->target, &buffer, buffer_end, "object ") < 0)
+		return tag_error("Object field invalid");
+
+	if (buffer + 5 >= buffer_end)
+		return tag_error("Object too short");
+
+	if (memcmp(buffer, "type ", 5) != 0)
+		return tag_error("Type field not found");
+	buffer += 5;
+
+	tag->type = GIT_OBJ_BAD;
+
+	for (i = 1; i < ARRAY_SIZE(tag_types); ++i) {
+		size_t type_length = strlen(tag_types[i]);
+
+		if (buffer + type_length >= buffer_end)
+			return tag_error("Object too short");
+
+		if (memcmp(buffer, tag_types[i], type_length) == 0) {
+			tag->type = i;
+			buffer += type_length;
+			break;
+		}
+	}
+
+	if (tag->type == GIT_OBJ_BAD)
+		return tag_error("Invalid object type");
+
+	if (buffer + 4 >= buffer_end)
+		return tag_error("Object too short");
+
+	if (memcmp(buffer, "tag ", 4) != 0)
+		return tag_error("Tag field not found");
+
+	buffer += 4;
+
+	search = memchr(buffer, '\n', buffer_end - buffer);
+	if (search == NULL)
+		return tag_error("Object too short");
+
+	text_len = search - buffer;
+
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, text_len, 1);
+	tag->tag_name = git__malloc(alloc_len);
+	GITERR_CHECK_ALLOC(tag->tag_name);
+
+	memcpy(tag->tag_name, buffer, text_len);
+	tag->tag_name[text_len] = '\0';
+
+	buffer = search + 1;
+
+	tag->tagger = NULL;
+	if (buffer < buffer_end && *buffer != '\n') {
+		tag->tagger = git__malloc(sizeof(git_signature));
+		GITERR_CHECK_ALLOC(tag->tagger);
+
+		if (git_signature__parse(tag->tagger, &buffer, buffer_end, "tagger ", '\n') < 0)
+			return -1;
+	}
+
+	tag->message = NULL;
+	if (buffer < buffer_end) {
+		if( *buffer != '\n' )
+			return tag_error("No new line before message");
+
+		text_len = buffer_end - ++buffer;
+
+		GITERR_CHECK_ALLOC_ADD(&alloc_len, text_len, 1);
+		tag->message = git__malloc(alloc_len);
+		GITERR_CHECK_ALLOC(tag->message);
+
+		memcpy(tag->message, buffer, text_len);
+		tag->message[text_len] = '\0';
+	}
+
+	return 0;
+}
+
+int git_tag__parse(void *_tag, git_odb_object *odb_obj)
+{
+	git_tag *tag = _tag;
+	const char *buffer = git_odb_object_data(odb_obj);
+	const char *buffer_end = buffer + git_odb_object_size(odb_obj);
+
+	return tag_parse(tag, buffer, buffer_end);
+}
+
+static int retrieve_tag_reference(
+	git_reference **tag_reference_out,
+	git_buf *ref_name_out,
+	git_repository *repo,
+	const char *tag_name)
+{
+	git_reference *tag_ref;
+	int error;
+
+	*tag_reference_out = NULL;
+
+	if (git_buf_joinpath(ref_name_out, GIT_REFS_TAGS_DIR, tag_name) < 0)
+		return -1;
+
+	error = git_reference_lookup(&tag_ref, repo, ref_name_out->ptr);
+	if (error < 0)
+		return error; /* Be it not foundo or corrupted */
+
+	*tag_reference_out = tag_ref;
+
+	return 0;
+}
+
+static int retrieve_tag_reference_oid(
+	git_oid *oid,
+	git_buf *ref_name_out,
+	git_repository *repo,
+	const char *tag_name)
+{
+	if (git_buf_joinpath(ref_name_out, GIT_REFS_TAGS_DIR, tag_name) < 0)
+		return -1;
+
+	return git_reference_name_to_id(oid, repo, ref_name_out->ptr);
+}
+
+static int write_tag_annotation(
+		git_oid *oid,
+		git_repository *repo,
+		const char *tag_name,
+		const git_object *target,
+		const git_signature *tagger,
+		const char *message)
+{
+	git_buf tag = GIT_BUF_INIT;
+	git_odb *odb;
+
+	git_oid__writebuf(&tag, "object ", git_object_id(target));
+	git_buf_printf(&tag, "type %s\n", git_object_type2string(git_object_type(target)));
+	git_buf_printf(&tag, "tag %s\n", tag_name);
+	git_signature__writebuf(&tag, "tagger ", tagger);
+	git_buf_putc(&tag, '\n');
+
+	if (git_buf_puts(&tag, message) < 0)
+		goto on_error;
+
+	if (git_repository_odb__weakptr(&odb, repo) < 0)
+		goto on_error;
+
+	if (git_odb_write(oid, odb, tag.ptr, tag.size, GIT_OBJ_TAG) < 0)
+		goto on_error;
+
+	git_buf_free(&tag);
+	return 0;
+
+on_error:
+	git_buf_free(&tag);
+	giterr_set(GITERR_OBJECT, "Failed to create tag annotation.");
+	return -1;
+}
+
+static int git_tag_create__internal(
+		git_oid *oid,
+		git_repository *repo,
+		const char *tag_name,
+		const git_object *target,
+		const git_signature *tagger,
+		const char *message,
+		int allow_ref_overwrite,
+		int create_tag_annotation)
+{
+	git_reference *new_ref = NULL;
+	git_buf ref_name = GIT_BUF_INIT;
+
+	int error;
+
+	assert(repo && tag_name && target);
+	assert(!create_tag_annotation || (tagger && message));
+
+	if (git_object_owner(target) != repo) {
+		giterr_set(GITERR_INVALID, "The given target does not belong to this repository");
+		return -1;
+	}
+
+	error = retrieve_tag_reference_oid(oid, &ref_name, repo, tag_name);
+	if (error < 0 && error != GIT_ENOTFOUND)
+		goto cleanup;
+
+	/** Ensure the tag name doesn't conflict with an already existing
+	 *	reference unless overwriting has explicitly been requested **/
+	if (error == 0 && !allow_ref_overwrite) {
+		git_buf_free(&ref_name);
+		giterr_set(GITERR_TAG, "Tag already exists");
+		return GIT_EEXISTS;
+	}
+
+	if (create_tag_annotation) {
+		if (write_tag_annotation(oid, repo, tag_name, target, tagger, message) < 0)
+			return -1;
+	} else
+		git_oid_cpy(oid, git_object_id(target));
+
+	error = git_reference_create(&new_ref, repo, ref_name.ptr, oid, allow_ref_overwrite, NULL);
+
+cleanup:
+	git_reference_free(new_ref);
+	git_buf_free(&ref_name);
+	return error;
+}
+
+int git_tag_create(
+	git_oid *oid,
+	git_repository *repo,
+	const char *tag_name,
+	const git_object *target,
+	const git_signature *tagger,
+	const char *message,
+	int allow_ref_overwrite)
+{
+	return git_tag_create__internal(oid, repo, tag_name, target, tagger, message, allow_ref_overwrite, 1);
+}
+
+int git_tag_annotation_create(
+	git_oid *oid,
+	git_repository *repo,
+	const char *tag_name,
+	const git_object *target,
+	const git_signature *tagger,
+	const char *message)
+{
+	assert(oid && repo && tag_name && target && tagger && message);
+
+	return write_tag_annotation(oid, repo, tag_name, target, tagger, message);
+}
+
+int git_tag_create_lightweight(
+	git_oid *oid,
+	git_repository *repo,
+	const char *tag_name,
+	const git_object *target,
+	int allow_ref_overwrite)
+{
+	return git_tag_create__internal(oid, repo, tag_name, target, NULL, NULL, allow_ref_overwrite, 0);
+}
+
+int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *buffer, int allow_ref_overwrite)
+{
+	git_tag tag;
+	int error;
+	git_odb *odb;
+	git_odb_stream *stream;
+	git_odb_object *target_obj;
+
+	git_reference *new_ref = NULL;
+	git_buf ref_name = GIT_BUF_INIT;
+
+	assert(oid && buffer);
+
+	memset(&tag, 0, sizeof(tag));
+
+	if (git_repository_odb__weakptr(&odb, repo) < 0)
+		return -1;
+
+	/* validate the buffer */
+	if (tag_parse(&tag, buffer, buffer + strlen(buffer)) < 0)
+		return -1;
+
+	/* validate the target */
+	if (git_odb_read(&target_obj, odb, &tag.target) < 0)
+		goto on_error;
+
+	if (tag.type != target_obj->cached.type) {
+		giterr_set(GITERR_TAG, "The type for the given target is invalid");
+		goto on_error;
+	}
+
+	error = retrieve_tag_reference_oid(oid, &ref_name, repo, tag.tag_name);
+	if (error < 0 && error != GIT_ENOTFOUND)
+		goto on_error;
+
+	/* We don't need these objects after this */
+	git_signature_free(tag.tagger);
+	git__free(tag.tag_name);
+	git__free(tag.message);
+	git_odb_object_free(target_obj);
+
+	/** Ensure the tag name doesn't conflict with an already existing
+	 *	reference unless overwriting has explictly been requested **/
+	if (error == 0 && !allow_ref_overwrite) {
+		giterr_set(GITERR_TAG, "Tag already exists");
+		return GIT_EEXISTS;
+	}
+
+	/* write the buffer */
+	if ((error = git_odb_open_wstream(
+			&stream, odb, strlen(buffer), GIT_OBJ_TAG)) < 0)
+		return error;
+
+	if (!(error = git_odb_stream_write(stream, buffer, strlen(buffer))))
+		error = git_odb_stream_finalize_write(oid, stream);
+
+	git_odb_stream_free(stream);
+
+	if (error < 0) {
+		git_buf_free(&ref_name);
+		return error;
+	}
+
+	error = git_reference_create(
+		&new_ref, repo, ref_name.ptr, oid, allow_ref_overwrite, NULL);
+
+	git_reference_free(new_ref);
+	git_buf_free(&ref_name);
+
+	return error;
+
+on_error:
+	git_signature_free(tag.tagger);
+	git__free(tag.tag_name);
+	git__free(tag.message);
+	git_odb_object_free(target_obj);
+	return -1;
+}
+
+int git_tag_delete(git_repository *repo, const char *tag_name)
+{
+	git_reference *tag_ref;
+	git_buf ref_name = GIT_BUF_INIT;
+	int error;
+
+	error = retrieve_tag_reference(&tag_ref, &ref_name, repo, tag_name);
+
+	git_buf_free(&ref_name);
+
+	if (error < 0)
+		return error;
+
+	error = git_reference_delete(tag_ref);
+
+	git_reference_free(tag_ref);
+
+	return error;
+}
+
+typedef struct {
+	git_repository *repo;
+	git_tag_foreach_cb cb;
+	void *cb_data;
+} tag_cb_data;
+
+static int tags_cb(const char *ref, void *data)
+{
+	int error;
+	git_oid oid;
+	tag_cb_data *d = (tag_cb_data *)data;
+
+	if (git__prefixcmp(ref, GIT_REFS_TAGS_DIR) != 0)
+		return 0; /* no tag */
+
+	if (!(error = git_reference_name_to_id(&oid, d->repo, ref))) {
+		if ((error = d->cb(ref, &oid, d->cb_data)) != 0)
+			giterr_set_after_callback_function(error, "git_tag_foreach");
+	}
+
+	return error;
+}
+
+int git_tag_foreach(git_repository *repo, git_tag_foreach_cb cb, void *cb_data)
+{
+	tag_cb_data data;
+
+	assert(repo && cb);
+
+	data.cb = cb;
+	data.cb_data = cb_data;
+	data.repo = repo;
+
+	return git_reference_foreach_name(repo, &tags_cb, &data);
+}
+
+typedef struct {
+	git_vector *taglist;
+	const char *pattern;
+} tag_filter_data;
+
+#define GIT_REFS_TAGS_DIR_LEN strlen(GIT_REFS_TAGS_DIR)
+
+static int tag_list_cb(const char *tag_name, git_oid *oid, void *data)
+{
+	tag_filter_data *filter = (tag_filter_data *)data;
+	GIT_UNUSED(oid);
+
+	if (!*filter->pattern ||
+		p_fnmatch(filter->pattern, tag_name + GIT_REFS_TAGS_DIR_LEN, 0) == 0)
+	{
+		char *matched = git__strdup(tag_name + GIT_REFS_TAGS_DIR_LEN);
+		GITERR_CHECK_ALLOC(matched);
+
+		return git_vector_insert(filter->taglist, matched);
+	}
+
+	return 0;
+}
+
+int git_tag_list_match(git_strarray *tag_names, const char *pattern, git_repository *repo)
+{
+	int error;
+	tag_filter_data filter;
+	git_vector taglist;
+
+	assert(tag_names && repo && pattern);
+
+	if ((error = git_vector_init(&taglist, 8, NULL)) < 0)
+		return error;
+
+	filter.taglist = &taglist;
+	filter.pattern = pattern;
+
+	error = git_tag_foreach(repo, &tag_list_cb, (void *)&filter);
+
+	if (error < 0)
+		git_vector_free(&taglist);
+
+	tag_names->strings =
+		(char **)git_vector_detach(&tag_names->count, NULL, &taglist);
+
+	return 0;
+}
+
+int git_tag_list(git_strarray *tag_names, git_repository *repo)
+{
+	return git_tag_list_match(tag_names, "", repo);
+}
+
+int git_tag_peel(git_object **tag_target, const git_tag *tag)
+{
+	return git_object_peel(tag_target, (const git_object *)tag, GIT_OBJ_ANY);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tag.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tag.h
new file mode 100755
index 0000000..d0cd393
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tag.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_tag_h__
+#define INCLUDE_tag_h__
+
+#include "git2/tag.h"
+#include "repository.h"
+#include "odb.h"
+
+struct git_tag {
+	git_object object;
+
+	git_oid target;
+	git_otype type;
+
+	char *tag_name;
+	git_signature *tagger;
+	char *message;
+};
+
+void git_tag__free(void *tag);
+int git_tag__parse(void *tag, git_odb_object *obj);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/thread-utils.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/thread-utils.c
new file mode 100755
index 0000000..dc9b2f0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/thread-utils.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "thread-utils.h"
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#	define WIN32_LEAN_AND_MEAN
+#endif
+#	include <windows.h>
+#elif defined(hpux) || defined(__hpux) || defined(_hpux)
+#	include <sys/pstat.h>
+#endif
+
+/*
+ * By doing this in two steps we can at least get
+ * the function to be somewhat coherent, even
+ * with this disgusting nest of #ifdefs.
+ */
+#ifndef _SC_NPROCESSORS_ONLN
+#	ifdef _SC_NPROC_ONLN
+#		define _SC_NPROCESSORS_ONLN _SC_NPROC_ONLN
+#	elif defined _SC_CRAY_NCPU
+#		define _SC_NPROCESSORS_ONLN _SC_CRAY_NCPU
+#	endif
+#endif
+
+int git_online_cpus(void)
+{
+#ifdef _SC_NPROCESSORS_ONLN
+	long ncpus;
+#endif
+
+#ifdef _WIN32
+	SYSTEM_INFO info;
+	GetSystemInfo(&info);
+
+	if ((int)info.dwNumberOfProcessors > 0)
+		return (int)info.dwNumberOfProcessors;
+#elif defined(hpux) || defined(__hpux) || defined(_hpux)
+	struct pst_dynamic psd;
+
+	if (!pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0))
+		return (int)psd.psd_proc_cnt;
+#endif
+
+#ifdef _SC_NPROCESSORS_ONLN
+	if ((ncpus = (long)sysconf(_SC_NPROCESSORS_ONLN)) > 0)
+		return (int)ncpus;
+#endif
+
+	return 1;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/thread-utils.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/thread-utils.h
new file mode 100755
index 0000000..dd1136c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/thread-utils.h
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_thread_utils_h__
+#define INCLUDE_thread_utils_h__
+
+/* Common operations even if threading has been disabled */
+typedef struct {
+#if defined(GIT_WIN32)
+	volatile long val;
+#else
+	volatile int val;
+#endif
+} git_atomic;
+
+#ifdef GIT_ARCH_64
+
+typedef struct {
+#if defined(GIT_WIN32)
+	__int64 val;
+#else
+	int64_t val;
+#endif
+} git_atomic64;
+
+typedef git_atomic64 git_atomic_ssize;
+
+#define git_atomic_ssize_add git_atomic64_add
+
+#else
+
+typedef git_atomic git_atomic_ssize;
+
+#define git_atomic_ssize_add git_atomic_add
+
+#endif
+
+#ifdef GIT_THREADS
+
+#if !defined(GIT_WIN32)
+
+typedef struct {
+	pthread_t thread;
+} git_thread;
+
+#define git_thread_create(git_thread_ptr, attr, start_routine, arg) \
+	pthread_create(&(git_thread_ptr)->thread, attr, start_routine, arg)
+#define git_thread_join(git_thread_ptr, status) \
+	pthread_join((git_thread_ptr)->thread, status)
+
+#endif
+
+/* Pthreads Mutex */
+#define git_mutex pthread_mutex_t
+#define git_mutex_init(a)	pthread_mutex_init(a, NULL)
+#define git_mutex_lock(a)	pthread_mutex_lock(a)
+#define git_mutex_unlock(a) pthread_mutex_unlock(a)
+#define git_mutex_free(a)	pthread_mutex_destroy(a)
+
+/* Pthreads condition vars */
+#define git_cond pthread_cond_t
+#define git_cond_init(c)	pthread_cond_init(c, NULL)
+#define git_cond_free(c) 	pthread_cond_destroy(c)
+#define git_cond_wait(c, l)	pthread_cond_wait(c, l)
+#define git_cond_signal(c)	pthread_cond_signal(c)
+#define git_cond_broadcast(c)	pthread_cond_broadcast(c)
+
+/* Pthread (-ish) rwlock
+ *
+ * This differs from normal pthreads rwlocks in two ways:
+ * 1. Separate APIs for releasing read locks and write locks (as
+ *    opposed to the pure POSIX API which only has one unlock fn)
+ * 2. You should not use recursive read locks (i.e. grabbing a read
+ *    lock in a thread that already holds a read lock) because the
+ *    Windows implementation doesn't support it
+ */
+#define git_rwlock pthread_rwlock_t
+#define git_rwlock_init(a)		pthread_rwlock_init(a, NULL)
+#define git_rwlock_rdlock(a)	pthread_rwlock_rdlock(a)
+#define git_rwlock_rdunlock(a)	pthread_rwlock_rdunlock(a)
+#define git_rwlock_wrlock(a)	pthread_rwlock_wrlock(a)
+#define git_rwlock_wrunlock(a)	pthread_rwlock_wrunlock(a)
+#define git_rwlock_free(a)		pthread_rwlock_destroy(a)
+#define GIT_RWLOCK_STATIC_INIT	PTHREAD_RWLOCK_INITIALIZER
+
+#ifndef GIT_WIN32
+#define pthread_rwlock_rdunlock pthread_rwlock_unlock
+#define pthread_rwlock_wrunlock pthread_rwlock_unlock
+#endif
+
+
+GIT_INLINE(void) git_atomic_set(git_atomic *a, int val)
+{
+#if defined(GIT_WIN32)
+	InterlockedExchange(&a->val, (LONG)val);
+#elif defined(__GNUC__)
+	__sync_lock_test_and_set(&a->val, val);
+#else
+#	error "Unsupported architecture for atomic operations"
+#endif
+}
+
+GIT_INLINE(int) git_atomic_inc(git_atomic *a)
+{
+#if defined(GIT_WIN32)
+	return InterlockedIncrement(&a->val);
+#elif defined(__GNUC__)
+	return __sync_add_and_fetch(&a->val, 1);
+#else
+#	error "Unsupported architecture for atomic operations"
+#endif
+}
+
+GIT_INLINE(int) git_atomic_add(git_atomic *a, int32_t addend)
+{
+#if defined(GIT_WIN32)
+	return InterlockedExchangeAdd(&a->val, addend);
+#elif defined(__GNUC__)
+	return __sync_add_and_fetch(&a->val, addend);
+#else
+#	error "Unsupported architecture for atomic operations"
+#endif
+}
+
+GIT_INLINE(int) git_atomic_dec(git_atomic *a)
+{
+#if defined(GIT_WIN32)
+	return InterlockedDecrement(&a->val);
+#elif defined(__GNUC__)
+	return __sync_sub_and_fetch(&a->val, 1);
+#else
+#	error "Unsupported architecture for atomic operations"
+#endif
+}
+
+GIT_INLINE(void *) git___compare_and_swap(
+	void * volatile *ptr, void *oldval, void *newval)
+{
+	volatile void *foundval;
+#if defined(GIT_WIN32)
+	foundval = InterlockedCompareExchangePointer((volatile PVOID *)ptr, newval, oldval);
+#elif defined(__GNUC__)
+	foundval = __sync_val_compare_and_swap(ptr, oldval, newval);
+#else
+#	error "Unsupported architecture for atomic operations"
+#endif
+	return (foundval == oldval) ? oldval : newval;
+}
+
+GIT_INLINE(volatile void *) git___swap(
+	void * volatile *ptr, void *newval)
+{
+#if defined(GIT_WIN32)
+	return InterlockedExchangePointer(ptr, newval);
+#else
+	return __sync_lock_test_and_set(ptr, newval);
+#endif
+}
+
+#ifdef GIT_ARCH_64
+
+GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend)
+{
+#if defined(GIT_WIN32)
+	return InterlockedExchangeAdd64(&a->val, addend);
+#elif defined(__GNUC__)
+	return __sync_add_and_fetch(&a->val, addend);
+#else
+#	error "Unsupported architecture for atomic operations"
+#endif
+}
+
+#endif
+
+#else
+
+#define git_thread unsigned int
+#define git_thread_create(thread, attr, start_routine, arg) 0
+#define git_thread_join(id, status) (void)0
+
+/* Pthreads Mutex */
+#define git_mutex unsigned int
+GIT_INLINE(int) git_mutex_init(git_mutex *mutex) \
+	{ GIT_UNUSED(mutex); return 0; }
+GIT_INLINE(int) git_mutex_lock(git_mutex *mutex) \
+	{ GIT_UNUSED(mutex); return 0; }
+#define git_mutex_unlock(a) (void)0
+#define git_mutex_free(a) (void)0
+
+/* Pthreads condition vars */
+#define git_cond unsigned int
+#define git_cond_init(c, a)	(void)0
+#define git_cond_free(c) (void)0
+#define git_cond_wait(c, l)	(void)0
+#define git_cond_signal(c) (void)0
+#define git_cond_broadcast(c) (void)0
+
+/* Pthreads rwlock */
+#define git_rwlock unsigned int
+#define git_rwlock_init(a)		0
+#define git_rwlock_rdlock(a)	0
+#define git_rwlock_rdunlock(a)	(void)0
+#define git_rwlock_wrlock(a)	0
+#define git_rwlock_wrunlock(a)	(void)0
+#define git_rwlock_free(a)		(void)0
+#define GIT_RWLOCK_STATIC_INIT	0
+
+
+GIT_INLINE(void) git_atomic_set(git_atomic *a, int val)
+{
+	a->val = val;
+}
+
+GIT_INLINE(int) git_atomic_inc(git_atomic *a)
+{
+	return ++a->val;
+}
+
+GIT_INLINE(int) git_atomic_add(git_atomic *a, int32_t addend)
+{
+	a->val += addend;
+	return a->val;
+}
+
+GIT_INLINE(int) git_atomic_dec(git_atomic *a)
+{
+	return --a->val;
+}
+
+GIT_INLINE(void *) git___compare_and_swap(
+	void * volatile *ptr, void *oldval, void *newval)
+{
+	if (*ptr == oldval)
+		*ptr = newval;
+	else
+		oldval = newval;
+	return oldval;
+}
+
+GIT_INLINE(volatile void *) git___swap(
+	void * volatile *ptr, void *newval)
+{
+	volatile void *old = *ptr;
+	*ptr = newval;
+	return old;
+}
+
+#ifdef GIT_ARCH_64
+
+GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend)
+{
+	a->val += addend;
+	return a->val;
+}
+
+#endif
+
+#endif
+
+GIT_INLINE(int) git_atomic_get(git_atomic *a)
+{
+	return (int)a->val;
+}
+
+/* Atomically replace oldval with newval
+ * @return oldval if it was replaced or newval if it was not
+ */
+#define git__compare_and_swap(P,O,N) \
+	git___compare_and_swap((void * volatile *)P, O, N)
+
+#define git__swap(ptr, val) (void *)git___swap((void * volatile *)&ptr, val)
+
+extern int git_online_cpus(void);
+
+#if defined(GIT_THREADS) && defined(GIT_WIN32)
+# define GIT_MEMORY_BARRIER MemoryBarrier()
+#elif defined(GIT_THREADS)
+# define GIT_MEMORY_BARRIER __sync_synchronize()
+#else
+# define GIT_MEMORY_BARRIER /* noop */
+#endif
+
+#endif /* INCLUDE_thread_utils_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tls_stream.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tls_stream.c
new file mode 100755
index 0000000..39a8ce3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tls_stream.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2/errors.h"
+#include "common.h"
+
+#include "openssl_stream.h"
+#include "stransport_stream.h"
+
+int git_tls_stream_new(git_stream **out, const char *host, const char *port)
+{
+#ifdef GIT_SECURE_TRANSPORT
+	return git_stransport_stream_new(out, host, port);
+#elif defined(GIT_OPENSSL)
+	return git_openssl_stream_new(out, host, port);
+#else
+	GIT_UNUSED(out);
+	GIT_UNUSED(host);
+	GIT_UNUSED(port);
+
+	giterr_set(GITERR_SSL, "there is no TLS stream available");
+	return -1;
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tls_stream.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tls_stream.h
new file mode 100755
index 0000000..98a7041
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tls_stream.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_tls_stream_h__
+#define INCLUDE_tls_stream_h__
+
+#include "git2/sys/stream.h"
+
+/**
+ * Create a TLS stream with the most appropriate backend available for
+ * the current platform.
+ *
+ * This allows us to ask for a SecureTransport or OpenSSL stream
+ * according to being on general Unix vs OS X.
+ */
+extern int git_tls_stream_new(git_stream **out, const char *host, const char *port);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/trace.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/trace.c
new file mode 100755
index 0000000..ee5039f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/trace.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "buffer.h"
+#include "common.h"
+#include "global.h"
+#include "trace.h"
+#include "git2/trace.h"
+
+#ifdef GIT_TRACE
+
+struct git_trace_data git_trace__data = {0};
+
+#endif
+
+int git_trace_set(git_trace_level_t level, git_trace_callback callback)
+{
+#ifdef GIT_TRACE
+	assert(level == 0 || callback != NULL);
+
+	git_trace__data.level = level;
+	git_trace__data.callback = callback;
+	GIT_MEMORY_BARRIER;
+
+	return 0;
+#else
+	GIT_UNUSED(level);
+	GIT_UNUSED(callback);
+
+	giterr_set(GITERR_INVALID,
+		"This version of libgit2 was not built with tracing.");
+	return -1;
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/trace.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/trace.h
new file mode 100755
index 0000000..486084d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/trace.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_trace_h__
+#define INCLUDE_trace_h__
+
+#include <git2/trace.h>
+#include "buffer.h"
+
+#ifdef GIT_TRACE
+
+struct git_trace_data {
+	git_trace_level_t level;
+	git_trace_callback callback;
+};
+
+extern struct git_trace_data git_trace__data;
+
+GIT_INLINE(void) git_trace__write_fmt(
+	git_trace_level_t level,
+	const char *fmt, ...)
+{
+	git_trace_callback callback = git_trace__data.callback;
+	git_buf message = GIT_BUF_INIT;
+	va_list ap;
+
+	va_start(ap, fmt);
+	git_buf_vprintf(&message, fmt, ap);
+	va_end(ap);
+
+	callback(level, git_buf_cstr(&message));
+
+	git_buf_free(&message);
+}
+
+#define git_trace_level()		(git_trace__data.level)
+#define git_trace(l, ...)		{ \
+									if (git_trace__data.level >= l && \
+										git_trace__data.callback != NULL) { \
+										git_trace__write_fmt(l, __VA_ARGS__); \
+									} \
+								}
+
+#else
+
+GIT_INLINE(void) git_trace__null(
+	git_trace_level_t level,
+	const char *fmt, ...)
+{
+	GIT_UNUSED(level);
+	GIT_UNUSED(fmt);
+}
+
+#define git_trace_level()		((void)0)
+#define git_trace			git_trace__null
+
+#endif
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transaction.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transaction.c
new file mode 100755
index 0000000..e833189
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transaction.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "repository.h"
+#include "strmap.h"
+#include "refdb.h"
+#include "pool.h"
+#include "reflog.h"
+#include "signature.h"
+
+#include "git2/transaction.h"
+#include "git2/signature.h"
+#include "git2/sys/refs.h"
+#include "git2/sys/refdb_backend.h"
+
+GIT__USE_STRMAP
+
+typedef struct {
+	const char *name;
+	void *payload;
+
+	git_ref_t ref_type;
+	union {
+		git_oid id;
+		char *symbolic;
+	} target;
+	git_reflog *reflog;
+
+	const char *message;
+	git_signature *sig;
+
+	unsigned int committed :1,
+		remove :1;
+} transaction_node;
+
+struct git_transaction {
+	git_repository *repo;
+	git_refdb *db;
+
+	git_strmap *locks;
+	git_pool pool;
+};
+
+int git_transaction_new(git_transaction **out, git_repository *repo)
+{
+	int error;
+	git_pool pool;
+	git_transaction *tx = NULL;
+
+	assert(out && repo);
+
+	if ((error = git_pool_init(&pool, 1, 0)) < 0)
+		return error;
+
+	tx = git_pool_mallocz(&pool, sizeof(git_transaction));
+	if (!tx) {
+		error = -1;
+		goto on_error;
+	}
+
+	if ((error = git_strmap_alloc(&tx->locks)) < 0) {
+		error = -1;
+		goto on_error;
+	}
+
+	if ((error = git_repository_refdb(&tx->db, repo)) < 0)
+		goto on_error;
+
+	memcpy(&tx->pool, &pool, sizeof(git_pool));
+	tx->repo = repo;
+	*out = tx;
+	return 0;
+
+on_error:
+	git_pool_clear(&pool);
+	return error;
+}
+
+int git_transaction_lock_ref(git_transaction *tx, const char *refname)
+{
+	int error;
+	transaction_node *node;
+
+	assert(tx && refname);
+
+	node = git_pool_mallocz(&tx->pool, sizeof(transaction_node));
+	GITERR_CHECK_ALLOC(node);
+
+	node->name = git_pool_strdup(&tx->pool, refname);
+	GITERR_CHECK_ALLOC(node->name);
+
+	if ((error = git_refdb_lock(&node->payload, tx->db, refname)) < 0)
+		return error;
+
+	git_strmap_insert(tx->locks, node->name, node, error);
+	if (error < 0) 
+		goto cleanup;
+
+	return 0;
+
+cleanup:
+	git_refdb_unlock(tx->db, node->payload, false, false, NULL, NULL, NULL);
+
+	return error;
+}
+
+static int find_locked(transaction_node **out, git_transaction *tx, const char *refname)
+{
+	git_strmap_iter pos;
+	transaction_node *node;
+
+	pos = git_strmap_lookup_index(tx->locks, refname);
+	if (!git_strmap_valid_index(tx->locks, pos)) {
+		giterr_set(GITERR_REFERENCE, "the specified reference is not locked");
+		return GIT_ENOTFOUND;
+	}
+
+	node = git_strmap_value_at(tx->locks, pos);
+
+	*out = node;
+	return 0;
+}
+
+static int copy_common(transaction_node *node, git_transaction *tx, const git_signature *sig, const char *msg)
+{
+	if (sig && git_signature__pdup(&node->sig, sig, &tx->pool) < 0)
+		return -1;
+
+	if (!node->sig) {
+		git_signature *tmp;
+		int error;
+
+		if (git_reference__log_signature(&tmp, tx->repo) < 0)
+			return -1;
+
+		/* make sure the sig we use is in our pool */
+		error = git_signature__pdup(&node->sig, tmp, &tx->pool);
+		git_signature_free(tmp);
+		if (error < 0)
+			return error;
+	}
+
+	if (msg) {
+		node->message = git_pool_strdup(&tx->pool, msg);
+		GITERR_CHECK_ALLOC(node->message);
+	}
+
+	return 0;
+}
+
+int git_transaction_set_target(git_transaction *tx, const char *refname, const git_oid *target, const git_signature *sig, const char *msg)
+{
+	int error;
+	transaction_node *node;
+
+	assert(tx && refname && target);
+
+	if ((error = find_locked(&node, tx, refname)) < 0)
+		return error;
+
+	if ((error = copy_common(node, tx, sig, msg)) < 0)
+		return error;
+
+	git_oid_cpy(&node->target.id, target);
+	node->ref_type = GIT_REF_OID;
+
+	return 0;
+}
+
+int git_transaction_set_symbolic_target(git_transaction *tx, const char *refname, const char *target, const git_signature *sig, const char *msg)
+{
+	int error;
+	transaction_node *node;
+
+	assert(tx && refname && target);
+
+	if ((error = find_locked(&node, tx, refname)) < 0)
+		return error;
+
+	if ((error = copy_common(node, tx, sig, msg)) < 0)
+		return error;
+
+	node->target.symbolic = git_pool_strdup(&tx->pool, target);
+	GITERR_CHECK_ALLOC(node->target.symbolic);
+	node->ref_type = GIT_REF_SYMBOLIC;
+
+	return 0;
+}
+
+int git_transaction_remove(git_transaction *tx, const char *refname)
+{
+	int error;
+	transaction_node *node;
+
+	if ((error = find_locked(&node, tx, refname)) < 0)
+		return error;
+
+	node->remove = true;
+	node->ref_type = GIT_REF_OID; /* the id will be ignored */
+
+	return 0;
+}
+
+static int dup_reflog(git_reflog **out, const git_reflog *in, git_pool *pool)
+{
+	git_reflog *reflog;
+	git_reflog_entry *entries;
+	size_t len, i;
+
+	reflog = git_pool_mallocz(pool, sizeof(git_reflog));
+	GITERR_CHECK_ALLOC(reflog);
+
+	reflog->ref_name = git_pool_strdup(pool, in->ref_name);
+	GITERR_CHECK_ALLOC(reflog->ref_name);
+
+	len = in->entries.length;
+	reflog->entries.length = len;
+	reflog->entries.contents = git_pool_mallocz(pool, len * sizeof(void *));
+	GITERR_CHECK_ALLOC(reflog->entries.contents);
+
+	entries = git_pool_mallocz(pool, len * sizeof(git_reflog_entry));
+	GITERR_CHECK_ALLOC(entries);
+
+	for (i = 0; i < len; i++) {
+		const git_reflog_entry *src;
+		git_reflog_entry *tgt;
+
+		tgt = &entries[i];
+		reflog->entries.contents[i] = tgt;
+
+		src = git_vector_get(&in->entries, i);
+		git_oid_cpy(&tgt->oid_old, &src->oid_old);
+		git_oid_cpy(&tgt->oid_cur, &src->oid_cur);
+
+		tgt->msg = git_pool_strdup(pool, src->msg);
+		GITERR_CHECK_ALLOC(tgt->msg);
+
+		if (git_signature__pdup(&tgt->committer, src->committer, pool) < 0)
+			return -1;
+	}
+
+
+	*out = reflog;
+	return 0;
+}
+
+int git_transaction_set_reflog(git_transaction *tx, const char *refname, const git_reflog *reflog)
+{
+	int error;
+	transaction_node *node;
+
+	assert(tx && refname && reflog);
+
+	if ((error = find_locked(&node, tx, refname)) < 0)
+		return error;
+
+	if ((error = dup_reflog(&node->reflog, reflog, &tx->pool)) < 0)
+		return error;
+
+	return 0;
+}
+
+static int update_target(git_refdb *db, transaction_node *node)
+{
+	git_reference *ref;
+	int error, update_reflog;
+
+	if (node->ref_type == GIT_REF_OID) {
+		ref = git_reference__alloc(node->name, &node->target.id, NULL);
+	} else if (node->ref_type == GIT_REF_SYMBOLIC) {
+		ref = git_reference__alloc_symbolic(node->name, node->target.symbolic);
+	} else {
+		abort();
+	}
+
+	GITERR_CHECK_ALLOC(ref);
+	update_reflog = node->reflog == NULL;
+
+	if (node->remove) {
+		error =  git_refdb_unlock(db, node->payload, 2, false, ref, NULL, NULL);
+	} else if (node->ref_type == GIT_REF_OID) {
+		error = git_refdb_unlock(db, node->payload, true, update_reflog, ref, node->sig, node->message);
+	} else if (node->ref_type == GIT_REF_SYMBOLIC) {
+		error = git_refdb_unlock(db, node->payload, true, update_reflog, ref, node->sig, node->message);
+	} else {
+		abort();
+	}
+
+	git_reference_free(ref);
+	node->committed = true;
+
+	return error;
+}
+
+int git_transaction_commit(git_transaction *tx)
+{
+	transaction_node *node;
+	git_strmap_iter pos;
+	int error = 0;
+
+	assert(tx);
+
+	for (pos = kh_begin(tx->locks); pos < kh_end(tx->locks); pos++) {
+		if (!git_strmap_has_data(tx->locks, pos))
+			continue;
+
+		node = git_strmap_value_at(tx->locks, pos);
+		if (node->reflog) {
+			if ((error = tx->db->backend->reflog_write(tx->db->backend, node->reflog)) < 0)
+				return error;
+		}
+
+		if (node->ref_type != GIT_REF_INVALID) {
+			if ((error = update_target(tx->db, node)) < 0)
+				return error;
+		}
+	}
+
+	return 0;
+}
+
+void git_transaction_free(git_transaction *tx)
+{
+	transaction_node *node;
+	git_pool pool;
+	git_strmap_iter pos;
+
+	assert(tx);
+
+	/* start by unlocking the ones we've left hanging, if any */
+	for (pos = kh_begin(tx->locks); pos < kh_end(tx->locks); pos++) {
+		if (!git_strmap_has_data(tx->locks, pos))
+			continue;
+
+		node = git_strmap_value_at(tx->locks, pos);
+		if (node->committed)
+			continue;
+
+		git_refdb_unlock(tx->db, node->payload, false, false, NULL, NULL, NULL);
+	}
+
+	git_refdb_free(tx->db);
+	git_strmap_free(tx->locks);
+
+	/* tx is inside the pool, so we need to extract the data */
+	memcpy(&pool, &tx->pool, sizeof(git_pool));
+	git_pool_clear(&pool);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transport.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transport.c
new file mode 100755
index 0000000..5c65c7c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transport.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "git2/types.h"
+#include "git2/remote.h"
+#include "git2/net.h"
+#include "git2/transport.h"
+#include "git2/sys/transport.h"
+#include "path.h"
+
+typedef struct transport_definition {
+	char *prefix;
+	git_transport_cb fn;
+	void *param;
+} transport_definition;
+
+static git_smart_subtransport_definition http_subtransport_definition = { git_smart_subtransport_http, 1, NULL };
+static git_smart_subtransport_definition git_subtransport_definition = { git_smart_subtransport_git, 0, NULL };
+#ifdef GIT_SSH
+static git_smart_subtransport_definition ssh_subtransport_definition = { git_smart_subtransport_ssh, 0, NULL };
+#endif
+
+static transport_definition local_transport_definition = { "file://", git_transport_local, NULL };
+
+static transport_definition transports[] = {
+	{ "git://",   git_transport_smart, &git_subtransport_definition },
+	{ "http://",  git_transport_smart, &http_subtransport_definition },
+#if defined(GIT_OPENSSL) || defined(GIT_WINHTTP) || defined(GIT_SECURE_TRANSPORT)
+	{ "https://", git_transport_smart, &http_subtransport_definition },
+#endif
+	{ "file://",  git_transport_local, NULL },
+#ifdef GIT_SSH
+	{ "ssh://",   git_transport_smart, &ssh_subtransport_definition },
+#endif
+	{ NULL, 0, 0 }
+};
+
+static git_vector custom_transports = GIT_VECTOR_INIT;
+
+#define GIT_TRANSPORT_COUNT (sizeof(transports)/sizeof(transports[0])) - 1
+
+static transport_definition * transport_find_by_url(const char *url)
+{
+	size_t i = 0;
+	transport_definition *d;
+
+	/* Find a user transport who wants to deal with this URI */
+	git_vector_foreach(&custom_transports, i, d) {
+		if (strncasecmp(url, d->prefix, strlen(d->prefix)) == 0) {
+			return d;
+		}
+	}
+
+	/* Find a system transport for this URI */
+	for (i = 0; i < GIT_TRANSPORT_COUNT; ++i) {
+		d = &transports[i];
+
+		if (strncasecmp(url, d->prefix, strlen(d->prefix)) == 0) {
+			return d;
+		}
+	}
+
+	return NULL;
+}
+
+static int transport_find_fn(
+	git_transport_cb *out,
+	const char *url,
+	void **param)
+{
+	transport_definition *definition = transport_find_by_url(url);
+
+#ifdef GIT_WIN32
+	/* On Windows, it might not be possible to discern between absolute local
+	 * and ssh paths - first check if this is a valid local path that points
+	 * to a directory and if so assume local path, else assume SSH */
+
+	/* Check to see if the path points to a file on the local file system */
+	if (!definition && git_path_exists(url) && git_path_isdir(url))
+		definition = &local_transport_definition;
+#endif
+
+	/* For other systems, perform the SSH check first, to avoid going to the
+	 * filesystem if it is not necessary */
+
+	/* It could be a SSH remote path. Check to see if there's a :
+	 * SSH is an unsupported transport mechanism in this version of libgit2 */
+	if (!definition && strrchr(url, ':')) {
+		// re-search transports again with ssh:// as url so that we can find a third party ssh transport
+		definition = transport_find_by_url("ssh://");
+	}
+
+#ifndef GIT_WIN32
+	/* Check to see if the path points to a file on the local file system */
+	if (!definition && git_path_exists(url) && git_path_isdir(url))
+		definition = &local_transport_definition;
+#endif
+
+	if (!definition)
+		return GIT_ENOTFOUND;
+
+	*out = definition->fn;
+	*param = definition->param;
+
+	return 0;
+}
+
+/**************
+ * Public API *
+ **************/
+
+int git_transport_new(git_transport **out, git_remote *owner, const char *url)
+{
+	git_transport_cb fn;
+	git_transport *transport;
+	void *param;
+	int error;
+
+	if ((error = transport_find_fn(&fn, url, &param)) == GIT_ENOTFOUND) {
+		giterr_set(GITERR_NET, "Unsupported URL protocol");
+		return -1;
+	} else if (error < 0)
+		return error;
+
+	if ((error = fn(&transport, owner, param)) < 0)
+		return error;
+
+	GITERR_CHECK_VERSION(transport, GIT_TRANSPORT_VERSION, "git_transport");
+
+	*out = transport;
+
+	return 0;
+}
+
+int git_transport_register(
+	const char *scheme,
+	git_transport_cb cb,
+	void *param)
+{
+	git_buf prefix = GIT_BUF_INIT;
+	transport_definition *d, *definition = NULL;
+	size_t i;
+	int error = 0;
+
+	assert(scheme);
+	assert(cb);
+
+	if ((error = git_buf_printf(&prefix, "%s://", scheme)) < 0)
+		goto on_error;
+
+	git_vector_foreach(&custom_transports, i, d) {
+		if (strcasecmp(d->prefix, prefix.ptr) == 0) {
+			error = GIT_EEXISTS;
+			goto on_error;
+		}
+	}
+
+	definition = git__calloc(1, sizeof(transport_definition));
+	GITERR_CHECK_ALLOC(definition);
+
+	definition->prefix = git_buf_detach(&prefix);
+	definition->fn = cb;
+	definition->param = param;
+
+	if (git_vector_insert(&custom_transports, definition) < 0)
+		goto on_error;
+
+	return 0;
+
+on_error:
+	git_buf_free(&prefix);
+	git__free(definition);
+	return error;
+}
+
+int git_transport_unregister(const char *scheme)
+{
+	git_buf prefix = GIT_BUF_INIT;
+	transport_definition *d;
+	size_t i;
+	int error = 0;
+
+	assert(scheme);
+
+	if ((error = git_buf_printf(&prefix, "%s://", scheme)) < 0)
+		goto done;
+
+	git_vector_foreach(&custom_transports, i, d) {
+		if (strcasecmp(d->prefix, prefix.ptr) == 0) {
+			if ((error = git_vector_remove(&custom_transports, i)) < 0)
+				goto done;
+
+			git__free(d->prefix);
+			git__free(d);
+
+			if (!custom_transports.length)
+				git_vector_free(&custom_transports);
+
+			error = 0;
+			goto done;
+		}
+	}
+
+	error = GIT_ENOTFOUND;
+
+done:
+	git_buf_free(&prefix);
+	return error;
+}
+
+int git_transport_init(git_transport *opts, unsigned int version)
+{
+	GIT_INIT_STRUCTURE_FROM_TEMPLATE(
+		opts, version, git_transport, GIT_TRANSPORT_INIT);
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/auth.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/auth.c
new file mode 100755
index 0000000..c1154db
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/auth.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2.h"
+#include "buffer.h"
+#include "auth.h"
+
+static int basic_next_token(
+	git_buf *out, git_http_auth_context *ctx, git_cred *c)
+{
+	git_cred_userpass_plaintext *cred;
+	git_buf raw = GIT_BUF_INIT;
+	int error = -1;
+
+	GIT_UNUSED(ctx);
+
+	if (c->credtype != GIT_CREDTYPE_USERPASS_PLAINTEXT) {
+		giterr_set(GITERR_INVALID, "invalid credential type for basic auth");
+		goto on_error;
+	}
+
+	cred = (git_cred_userpass_plaintext *)c;
+
+	git_buf_printf(&raw, "%s:%s", cred->username, cred->password);
+
+	if (git_buf_oom(&raw) ||
+		git_buf_puts(out, "Authorization: Basic ") < 0 ||
+		git_buf_encode_base64(out, git_buf_cstr(&raw), raw.size) < 0 ||
+		git_buf_puts(out, "\r\n") < 0)
+		goto on_error;
+
+	error = 0;
+
+on_error:
+	if (raw.size)
+		git__memzero(raw.ptr, raw.size);
+
+	git_buf_free(&raw);
+	return error;
+}
+
+static git_http_auth_context basic_context = {
+	GIT_AUTHTYPE_BASIC,
+	GIT_CREDTYPE_USERPASS_PLAINTEXT,
+	NULL,
+	basic_next_token,
+	NULL
+};
+
+int git_http_auth_basic(
+	git_http_auth_context **out, const gitno_connection_data *connection_data)
+{
+	GIT_UNUSED(connection_data);
+
+	*out = &basic_context;
+	return 0;
+}
+
+int git_http_auth_dummy(
+	git_http_auth_context **out, const gitno_connection_data *connection_data)
+{
+	GIT_UNUSED(connection_data);
+
+	*out = NULL;
+	return 0;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/auth.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/auth.h
new file mode 100755
index 0000000..52138cf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/auth.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_http_auth_h__
+#define INCLUDE_http_auth_h__
+
+#include "git2.h"
+#include "netops.h"
+
+typedef enum {
+	GIT_AUTHTYPE_BASIC = 1,
+	GIT_AUTHTYPE_NEGOTIATE = 2,
+} git_http_authtype_t;
+
+typedef struct git_http_auth_context git_http_auth_context;
+
+struct git_http_auth_context {
+	/** Type of scheme */
+	git_http_authtype_t type;
+
+	/** Supported credentials */
+	git_credtype_t credtypes;
+
+	/** Sets the challenge on the authentication context */
+	int (*set_challenge)(git_http_auth_context *ctx, const char *challenge);
+
+	/** Gets the next authentication token from the context */
+	int (*next_token)(git_buf *out, git_http_auth_context *ctx, git_cred *cred);
+
+	/** Frees the authentication context */
+	void (*free)(git_http_auth_context *ctx);
+};
+
+typedef struct {
+	/** Type of scheme */
+	git_http_authtype_t type;
+
+	/** Name of the scheme (as used in the Authorization header) */
+	const char *name;
+
+	/** Credential types this scheme supports */
+	git_credtype_t credtypes;
+
+	/** Function to initialize an authentication context */
+	int (*init_context)(
+		git_http_auth_context **out,
+		const gitno_connection_data *connection_data);
+} git_http_auth_scheme;
+
+int git_http_auth_dummy(
+	git_http_auth_context **out,
+	const gitno_connection_data *connection_data);
+
+int git_http_auth_basic(
+	git_http_auth_context **out,
+	const gitno_connection_data *connection_data);
+
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/auth_negotiate.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/auth_negotiate.c
new file mode 100755
index 0000000..8b99fc7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/auth_negotiate.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifdef GIT_GSSAPI
+
+#include "git2.h"
+#include "common.h"
+#include "buffer.h"
+#include "auth.h"
+
+#include <gssapi.h>
+#include <krb5.h>
+
+static gss_OID_desc negotiate_oid_spnego =
+	{ 6, (void *) "\x2b\x06\x01\x05\x05\x02" };
+static gss_OID_desc negotiate_oid_krb5 =
+	{ 9, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" };
+
+static gss_OID negotiate_oids[] =
+	{ &negotiate_oid_spnego, &negotiate_oid_krb5, NULL };
+
+typedef struct {
+	git_http_auth_context parent;
+	unsigned configured : 1,
+		complete : 1;
+	git_buf target;
+	char *challenge;
+	gss_ctx_id_t gss_context;
+	gss_OID oid;
+} http_auth_negotiate_context;
+
+static void negotiate_err_set(
+	OM_uint32 status_major,
+	OM_uint32 status_minor,
+	const char *message)
+{
+	gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER;
+	OM_uint32 status_display, context = 0;
+
+	if (gss_display_status(&status_display, status_major, GSS_C_GSS_CODE,
+		GSS_C_NO_OID, &context, &buffer) == GSS_S_COMPLETE) {
+		giterr_set(GITERR_NET, "%s: %.*s (%d.%d)",
+			message, (int)buffer.length, (const char *)buffer.value,
+			status_major, status_minor);
+		gss_release_buffer(&status_minor, &buffer);
+	} else {
+		giterr_set(GITERR_NET, "%s: unknown negotiate error (%d.%d)",
+			message, status_major, status_minor);
+	}
+}
+
+static int negotiate_set_challenge(
+	git_http_auth_context *c,
+	const char *challenge)
+{
+	http_auth_negotiate_context *ctx = (http_auth_negotiate_context *)c;
+
+	assert(ctx && ctx->configured && challenge);
+
+	git__free(ctx->challenge);
+
+	ctx->challenge = git__strdup(challenge);
+	GITERR_CHECK_ALLOC(ctx->challenge);
+
+	return 0;
+}
+
+static int negotiate_next_token(
+	git_buf *buf,
+	git_http_auth_context *c,
+	git_cred *cred)
+{
+	http_auth_negotiate_context *ctx = (http_auth_negotiate_context *)c;
+	OM_uint32 status_major, status_minor;
+	gss_buffer_desc target_buffer = GSS_C_EMPTY_BUFFER,
+		input_token = GSS_C_EMPTY_BUFFER,
+		output_token = GSS_C_EMPTY_BUFFER;
+	gss_buffer_t input_token_ptr = GSS_C_NO_BUFFER;
+	git_buf input_buf = GIT_BUF_INIT;
+	gss_name_t server = NULL;
+	gss_OID mech;
+	size_t challenge_len;
+	int error = 0;
+
+	assert(buf && ctx && ctx->configured && cred && cred->credtype == GIT_CREDTYPE_DEFAULT);
+
+	if (ctx->complete)
+		return 0;
+
+	target_buffer.value = (void *)ctx->target.ptr;
+	target_buffer.length = ctx->target.size;
+
+	status_major = gss_import_name(&status_minor, &target_buffer,
+		GSS_C_NT_HOSTBASED_SERVICE, &server);
+
+	if (GSS_ERROR(status_major)) {
+		negotiate_err_set(status_major, status_minor,
+			"Could not parse principal");
+		error = -1;
+		goto done;
+	}
+
+	challenge_len = ctx->challenge ? strlen(ctx->challenge) : 0;
+
+	if (challenge_len < 9) {
+		giterr_set(GITERR_NET, "No negotiate challenge sent from server");
+		error = -1;
+		goto done;
+	} else if (challenge_len > 9) {
+		if (git_buf_decode_base64(&input_buf,
+				ctx->challenge + 10, challenge_len - 10) < 0) {
+			giterr_set(GITERR_NET, "Invalid negotiate challenge from server");
+			error = -1;
+			goto done;
+		}
+
+		input_token.value = input_buf.ptr;
+		input_token.length = input_buf.size;
+		input_token_ptr = &input_token;
+	} else if (ctx->gss_context != GSS_C_NO_CONTEXT) {
+		giterr_set(GITERR_NET, "Could not restart authentication");
+		error = -1;
+		goto done;
+	}
+
+	mech = &negotiate_oid_spnego;
+
+	if (GSS_ERROR(status_major = gss_init_sec_context(
+		&status_minor,
+		GSS_C_NO_CREDENTIAL,
+		&ctx->gss_context,
+		server,
+		mech,
+		GSS_C_DELEG_FLAG | GSS_C_MUTUAL_FLAG,
+		GSS_C_INDEFINITE,
+		GSS_C_NO_CHANNEL_BINDINGS,
+		input_token_ptr,
+		NULL,
+		&output_token,
+		NULL,
+		NULL))) {
+		negotiate_err_set(status_major, status_minor, "Negotiate failure");
+		error = -1;
+		goto done;
+	}
+
+	/* This message merely told us auth was complete; we do not respond. */
+	if (status_major == GSS_S_COMPLETE) {
+		ctx->complete = 1;
+		goto done;
+	}
+
+	git_buf_puts(buf, "Authorization: Negotiate ");
+	git_buf_encode_base64(buf, output_token.value, output_token.length);
+	git_buf_puts(buf, "\r\n");
+
+	if (git_buf_oom(buf))
+		error = -1;
+
+done:
+	gss_release_name(&status_minor, &server);
+	gss_release_buffer(&status_minor, (gss_buffer_t) &output_token);
+	git_buf_free(&input_buf);
+	return error;
+}
+
+static void negotiate_context_free(git_http_auth_context *c)
+{
+	http_auth_negotiate_context *ctx = (http_auth_negotiate_context *)c;
+	OM_uint32 status_minor;
+
+	if (ctx->gss_context != GSS_C_NO_CONTEXT) {
+		gss_delete_sec_context(
+			&status_minor, &ctx->gss_context, GSS_C_NO_BUFFER);
+		ctx->gss_context = GSS_C_NO_CONTEXT;
+	}
+
+	git_buf_free(&ctx->target);
+
+	git__free(ctx->challenge);
+
+	ctx->configured = 0;
+	ctx->complete = 0;
+	ctx->oid = NULL;
+
+	git__free(ctx);
+}
+
+static int negotiate_init_context(
+	http_auth_negotiate_context *ctx,
+	const gitno_connection_data *connection_data)
+{
+	OM_uint32 status_major, status_minor;
+	gss_OID item, *oid;
+	gss_OID_set mechanism_list;
+	size_t i;
+
+	/* Query supported mechanisms looking for SPNEGO) */
+	if (GSS_ERROR(status_major =
+		gss_indicate_mechs(&status_minor, &mechanism_list))) {
+		negotiate_err_set(status_major, status_minor,
+			"could not query mechanisms");
+		return -1;
+	}
+
+	if (mechanism_list) {
+		for (oid = negotiate_oids; *oid; oid++) {
+			for (i = 0; i < mechanism_list->count; i++) {
+				item = &mechanism_list->elements[i];
+
+				if (item->length == (*oid)->length &&
+					memcmp(item->elements, (*oid)->elements, item->length) == 0) {
+					ctx->oid = *oid;
+					break;
+				}
+
+			}
+
+			if (ctx->oid)
+				break;
+		}
+	}
+
+	gss_release_oid_set(&status_minor, &mechanism_list);
+
+	if (!ctx->oid) {
+		giterr_set(GITERR_NET, "Negotiate authentication is not supported");
+		return -1;
+	}
+
+	git_buf_puts(&ctx->target, "HTTP@");
+	git_buf_puts(&ctx->target, connection_data->host);
+
+	if (git_buf_oom(&ctx->target))
+		return -1;
+
+	ctx->gss_context = GSS_C_NO_CONTEXT;
+	ctx->configured = 1;
+
+	return 0;
+}
+
+int git_http_auth_negotiate(
+	git_http_auth_context **out,
+	const gitno_connection_data *connection_data)
+{
+	http_auth_negotiate_context *ctx;
+
+	*out = NULL;
+
+	ctx = git__calloc(1, sizeof(http_auth_negotiate_context));
+	GITERR_CHECK_ALLOC(ctx);
+
+	if (negotiate_init_context(ctx, connection_data) < 0) {
+		git__free(ctx);
+		return -1;
+	}
+
+	ctx->parent.type = GIT_AUTHTYPE_NEGOTIATE;
+	ctx->parent.credtypes = GIT_CREDTYPE_DEFAULT;
+	ctx->parent.set_challenge = negotiate_set_challenge;
+	ctx->parent.next_token = negotiate_next_token;
+	ctx->parent.free = negotiate_context_free;
+
+	*out = (git_http_auth_context *)ctx;
+
+	return 0;
+}
+
+#endif /* GIT_GSSAPI */
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/auth_negotiate.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/auth_negotiate.h
new file mode 100755
index 0000000..d7270b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/auth_negotiate.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_auth_negotiate_h__
+#define INCLUDE_auth_negotiate_h__
+
+#include "git2.h"
+#include "auth.h"
+
+#ifdef GIT_GSSAPI
+
+extern int git_http_auth_negotiate(
+	git_http_auth_context **out,
+	const gitno_connection_data *connection_data);
+
+#else
+
+#define git_http_auth_negotiate git_http_auth_dummy
+
+#endif /* GIT_GSSAPI */
+
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/cred.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/cred.c
new file mode 100755
index 0000000..044b2a2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/cred.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2.h"
+#include "smart.h"
+#include "git2/cred_helpers.h"
+
+static int git_cred_ssh_key_type_new(
+	git_cred **cred,
+	const char *username,
+	const char *publickey,
+	const char *privatekey,
+	const char *passphrase,
+	git_credtype_t credtype);
+
+int git_cred_has_username(git_cred *cred)
+{
+	if (cred->credtype == GIT_CREDTYPE_DEFAULT)
+		return 0;
+
+	return 1;
+}
+
+const char *git_cred__username(git_cred *cred)
+{
+	switch (cred->credtype) {
+	case GIT_CREDTYPE_USERNAME:
+	{
+		git_cred_username *c = (git_cred_username *) cred;
+		return c->username;
+	}
+	case GIT_CREDTYPE_USERPASS_PLAINTEXT:
+	{
+		git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *) cred;
+		return c->username;
+	}
+	case GIT_CREDTYPE_SSH_KEY:
+	case GIT_CREDTYPE_SSH_MEMORY:
+	{
+		git_cred_ssh_key *c = (git_cred_ssh_key *) cred;
+		return c->username;
+	}
+	case GIT_CREDTYPE_SSH_CUSTOM:
+	{
+		git_cred_ssh_custom *c = (git_cred_ssh_custom *) cred;
+		return c->username;
+	}
+	case GIT_CREDTYPE_SSH_INTERACTIVE:
+	{
+		git_cred_ssh_interactive *c = (git_cred_ssh_interactive *) cred;
+		return c->username;
+	}
+
+	default:
+		return NULL;
+	}
+}
+
+static void plaintext_free(struct git_cred *cred)
+{
+	git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
+
+	git__free(c->username);
+
+	/* Zero the memory which previously held the password */
+	if (c->password) {
+		size_t pass_len = strlen(c->password);
+		git__memzero(c->password, pass_len);
+		git__free(c->password);
+	}
+
+	git__free(c);
+}
+
+int git_cred_userpass_plaintext_new(
+	git_cred **cred,
+	const char *username,
+	const char *password)
+{
+	git_cred_userpass_plaintext *c;
+
+	assert(cred && username && password);
+
+	c = git__malloc(sizeof(git_cred_userpass_plaintext));
+	GITERR_CHECK_ALLOC(c);
+
+	c->parent.credtype = GIT_CREDTYPE_USERPASS_PLAINTEXT;
+	c->parent.free = plaintext_free;
+	c->username = git__strdup(username);
+
+	if (!c->username) {
+		git__free(c);
+		return -1;
+	}
+
+	c->password = git__strdup(password);
+
+	if (!c->password) {
+		git__free(c->username);
+		git__free(c);
+		return -1;
+	}
+
+	*cred = &c->parent;
+	return 0;
+}
+
+static void ssh_key_free(struct git_cred *cred)
+{
+	git_cred_ssh_key *c =
+		(git_cred_ssh_key *)cred;
+
+	git__free(c->username);
+
+	if (c->privatekey) {
+		/* Zero the memory which previously held the private key */
+		size_t key_len = strlen(c->privatekey);
+		git__memzero(c->privatekey, key_len);
+		git__free(c->privatekey);
+	}
+
+	if (c->passphrase) {
+		/* Zero the memory which previously held the passphrase */
+		size_t pass_len = strlen(c->passphrase);
+		git__memzero(c->passphrase, pass_len);
+		git__free(c->passphrase);
+	}
+
+	if (c->publickey) {
+		/* Zero the memory which previously held the public key */
+		size_t key_len = strlen(c->publickey);
+		git__memzero(c->publickey, key_len);
+		git__free(c->publickey);
+	}
+
+	git__free(c);
+}
+
+static void ssh_interactive_free(struct git_cred *cred)
+{
+	git_cred_ssh_interactive *c = (git_cred_ssh_interactive *)cred;
+
+	git__free(c->username);
+
+	git__free(c);
+}
+
+static void ssh_custom_free(struct git_cred *cred)
+{
+	git_cred_ssh_custom *c = (git_cred_ssh_custom *)cred;
+
+	git__free(c->username);
+
+	if (c->publickey) {
+		/* Zero the memory which previously held the publickey */
+		size_t key_len = strlen(c->publickey);
+		git__memzero(c->publickey, key_len);
+		git__free(c->publickey);
+	}
+
+	git__free(c);
+}
+
+static void default_free(struct git_cred *cred)
+{
+	git_cred_default *c = (git_cred_default *)cred;
+
+	git__free(c);
+}
+
+static void username_free(struct git_cred *cred)
+{
+	git__free(cred);
+}
+
+int git_cred_ssh_key_new(
+	git_cred **cred,
+	const char *username,
+	const char *publickey,
+	const char *privatekey,
+	const char *passphrase)
+{
+	return git_cred_ssh_key_type_new(
+		cred,
+		username,
+		publickey,
+		privatekey,
+		passphrase,
+		GIT_CREDTYPE_SSH_KEY);
+}
+
+int git_cred_ssh_key_memory_new(
+	git_cred **cred,
+	const char *username,
+	const char *publickey,
+	const char *privatekey,
+	const char *passphrase)
+{
+#ifdef GIT_SSH_MEMORY_CREDENTIALS
+	return git_cred_ssh_key_type_new(
+		cred,
+		username,
+		publickey,
+		privatekey,
+		passphrase,
+		GIT_CREDTYPE_SSH_MEMORY);
+#else
+	GIT_UNUSED(cred);
+	GIT_UNUSED(username);
+	GIT_UNUSED(publickey);
+	GIT_UNUSED(privatekey);
+	GIT_UNUSED(passphrase);
+
+	giterr_set(GITERR_INVALID,
+		"This version of libgit2 was not built with ssh memory credentials.");
+	return -1;
+#endif
+}
+
+static int git_cred_ssh_key_type_new(
+	git_cred **cred,
+	const char *username,
+	const char *publickey,
+	const char *privatekey,
+	const char *passphrase,
+	git_credtype_t credtype)
+{
+	git_cred_ssh_key *c;
+
+	assert(username && cred && privatekey);
+
+	c = git__calloc(1, sizeof(git_cred_ssh_key));
+	GITERR_CHECK_ALLOC(c);
+
+	c->parent.credtype = credtype;
+	c->parent.free = ssh_key_free;
+
+	c->username = git__strdup(username);
+	GITERR_CHECK_ALLOC(c->username);
+
+	c->privatekey = git__strdup(privatekey);
+	GITERR_CHECK_ALLOC(c->privatekey);
+
+	if (publickey) {
+		c->publickey = git__strdup(publickey);
+		GITERR_CHECK_ALLOC(c->publickey);
+	}
+
+	if (passphrase) {
+		c->passphrase = git__strdup(passphrase);
+		GITERR_CHECK_ALLOC(c->passphrase);
+	}
+
+	*cred = &c->parent;
+	return 0;
+}
+
+int git_cred_ssh_interactive_new(
+	git_cred **out,
+	const char *username,
+	git_cred_ssh_interactive_callback prompt_callback,
+	void *payload)
+{
+	git_cred_ssh_interactive *c;
+
+	assert(out && username && prompt_callback);
+
+	c = git__calloc(1, sizeof(git_cred_ssh_interactive));
+	GITERR_CHECK_ALLOC(c);
+
+	c->parent.credtype = GIT_CREDTYPE_SSH_INTERACTIVE;
+	c->parent.free = ssh_interactive_free;
+
+	c->username = git__strdup(username);
+	GITERR_CHECK_ALLOC(c->username);
+
+	c->prompt_callback = prompt_callback;
+	c->payload = payload;
+
+	*out = &c->parent;
+	return 0;
+}
+
+int git_cred_ssh_key_from_agent(git_cred **cred, const char *username) {
+	git_cred_ssh_key *c;
+
+	assert(username && cred);
+
+	c = git__calloc(1, sizeof(git_cred_ssh_key));
+	GITERR_CHECK_ALLOC(c);
+
+	c->parent.credtype = GIT_CREDTYPE_SSH_KEY;
+	c->parent.free = ssh_key_free;
+
+	c->username = git__strdup(username);
+	GITERR_CHECK_ALLOC(c->username);
+
+	c->privatekey = NULL;
+
+	*cred = &c->parent;
+	return 0;
+}
+
+int git_cred_ssh_custom_new(
+	git_cred **cred,
+	const char *username,
+	const char *publickey,
+	size_t publickey_len,
+	git_cred_sign_callback sign_callback,
+	void *payload)
+{
+	git_cred_ssh_custom *c;
+
+	assert(username && cred);
+
+	c = git__calloc(1, sizeof(git_cred_ssh_custom));
+	GITERR_CHECK_ALLOC(c);
+
+	c->parent.credtype = GIT_CREDTYPE_SSH_CUSTOM;
+	c->parent.free = ssh_custom_free;
+
+	c->username = git__strdup(username);
+	GITERR_CHECK_ALLOC(c->username);
+
+	if (publickey_len > 0) {
+		c->publickey = git__malloc(publickey_len);
+		GITERR_CHECK_ALLOC(c->publickey);
+
+		memcpy(c->publickey, publickey, publickey_len);
+	}
+
+	c->publickey_len = publickey_len;
+	c->sign_callback = sign_callback;
+	c->payload = payload;
+
+	*cred = &c->parent;
+	return 0;
+}
+
+int git_cred_default_new(git_cred **cred)
+{
+	git_cred_default *c;
+
+	assert(cred);
+
+	c = git__calloc(1, sizeof(git_cred_default));
+	GITERR_CHECK_ALLOC(c);
+
+	c->credtype = GIT_CREDTYPE_DEFAULT;
+	c->free = default_free;
+
+	*cred = c;
+	return 0;
+}
+
+int git_cred_username_new(git_cred **cred, const char *username)
+{
+	git_cred_username *c;
+	size_t len, allocsize;
+
+	assert(cred);
+
+	len = strlen(username);
+
+	GITERR_CHECK_ALLOC_ADD(&allocsize, sizeof(git_cred_username), len);
+	GITERR_CHECK_ALLOC_ADD(&allocsize, allocsize, 1);
+	c = git__malloc(allocsize);
+	GITERR_CHECK_ALLOC(c);
+
+	c->parent.credtype = GIT_CREDTYPE_USERNAME;
+	c->parent.free = username_free;
+	memcpy(c->username, username, len + 1);
+
+	*cred = (git_cred *) c;
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/cred.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/cred.h
new file mode 100755
index 0000000..2de8dee
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/cred.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_cred_h__
+#define INCLUDE_git_cred_h__
+
+#include "git2/transport.h"
+
+const char *git_cred__username(git_cred *cred);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/cred_helpers.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/cred_helpers.c
new file mode 100755
index 0000000..5cc9b08
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/cred_helpers.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "git2/cred_helpers.h"
+
+int git_cred_userpass(
+		git_cred **cred,
+		const char *url,
+		const char *user_from_url,
+		unsigned int allowed_types,
+		void *payload)
+{
+	git_cred_userpass_payload *userpass = (git_cred_userpass_payload*)payload;
+	const char *effective_username = NULL;
+
+	GIT_UNUSED(url);
+
+	if (!userpass || !userpass->password) return -1;
+
+	/* Username resolution: a username can be passed with the URL, the
+	 * credentials payload, or both. Here's what we do.  Note that if we get
+	 * this far, we know that any password the url may contain has already
+	 * failed at least once, so we ignore it.
+	 *
+	 * |  Payload    |   URL    |   Used    |
+	 * +-------------+----------+-----------+
+	 * |    yes      |   no     |  payload  |
+	 * |    yes      |   yes    |  payload  |
+	 * |    no       |   yes    |  url      |
+	 * |    no       |   no     |  FAIL     |
+	 */
+	if (userpass->username)
+		effective_username = userpass->username;
+	else if (user_from_url)
+		effective_username = user_from_url;
+	else
+		return -1;
+
+	if (GIT_CREDTYPE_USERNAME & allowed_types)
+		return git_cred_username_new(cred, effective_username);
+
+	if ((GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) == 0 ||
+			git_cred_userpass_plaintext_new(cred, effective_username, userpass->password) < 0)
+		return -1;
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/git.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/git.c
new file mode 100755
index 0000000..52de92d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/git.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "git2.h"
+#include "buffer.h"
+#include "netops.h"
+#include "git2/sys/transport.h"
+#include "stream.h"
+#include "socket_stream.h"
+
+#define OWNING_SUBTRANSPORT(s) ((git_subtransport *)(s)->parent.subtransport)
+
+static const char prefix_git[] = "git://";
+static const char cmd_uploadpack[] = "git-upload-pack";
+static const char cmd_receivepack[] = "git-receive-pack";
+
+typedef struct {
+	git_smart_subtransport_stream parent;
+	git_stream *io;
+	const char *cmd;
+	char *url;
+	unsigned sent_command : 1;
+} git_proto_stream;
+
+typedef struct {
+	git_smart_subtransport parent;
+	git_transport *owner;
+	git_proto_stream *current_stream;
+} git_subtransport;
+
+/*
+ * Create a git protocol request.
+ *
+ * For example: 0035git-upload-pack /libgit2/libgit2\0host=github.com\0
+ */
+static int gen_proto(git_buf *request, const char *cmd, const char *url)
+{
+	char *delim, *repo;
+	char host[] = "host=";
+	size_t len;
+
+	delim = strchr(url, '/');
+	if (delim == NULL) {
+		giterr_set(GITERR_NET, "Malformed URL");
+		return -1;
+	}
+
+	repo = delim;
+	if (repo[1] == '~')
+		++repo;
+
+	delim = strchr(url, ':');
+	if (delim == NULL)
+		delim = strchr(url, '/');
+
+	len = 4 + strlen(cmd) + 1 + strlen(repo) + 1 + strlen(host) + (delim - url) + 1;
+
+	git_buf_grow(request, len);
+	git_buf_printf(request, "%04x%s %s%c%s",
+		(unsigned int)(len & 0x0FFFF), cmd, repo, 0, host);
+	git_buf_put(request, url, delim - url);
+	git_buf_putc(request, '\0');
+
+	if (git_buf_oom(request))
+		return -1;
+
+	return 0;
+}
+
+static int send_command(git_proto_stream *s)
+{
+	int error;
+	git_buf request = GIT_BUF_INIT;
+
+	error = gen_proto(&request, s->cmd, s->url);
+	if (error < 0)
+		goto cleanup;
+
+	error = git_stream_write(s->io, request.ptr, request.size, 0);
+	if (error >= 0)
+		s->sent_command = 1;
+
+cleanup:
+	git_buf_free(&request);
+	return error;
+}
+
+static int git_proto_stream_read(
+	git_smart_subtransport_stream *stream,
+	char *buffer,
+	size_t buf_size,
+	size_t *bytes_read)
+{
+	int error;
+	git_proto_stream *s = (git_proto_stream *)stream;
+	gitno_buffer buf;
+
+	*bytes_read = 0;
+
+	if (!s->sent_command && (error = send_command(s)) < 0)
+		return error;
+
+	gitno_buffer_setup_fromstream(s->io, &buf, buffer, buf_size);
+
+	if ((error = gitno_recv(&buf)) < 0)
+		return error;
+
+	*bytes_read = buf.offset;
+
+	return 0;
+}
+
+static int git_proto_stream_write(
+	git_smart_subtransport_stream *stream,
+	const char *buffer,
+	size_t len)
+{
+	int error;
+	git_proto_stream *s = (git_proto_stream *)stream;
+
+	if (!s->sent_command && (error = send_command(s)) < 0)
+		return error;
+
+	return git_stream_write(s->io, buffer, len, 0);
+}
+
+static void git_proto_stream_free(git_smart_subtransport_stream *stream)
+{
+	git_proto_stream *s = (git_proto_stream *)stream;
+	git_subtransport *t = OWNING_SUBTRANSPORT(s);
+	int ret;
+
+	GIT_UNUSED(ret);
+
+	t->current_stream = NULL;
+
+	git_stream_close(s->io);
+	git_stream_free(s->io);
+	git__free(s->url);
+	git__free(s);
+}
+
+static int git_proto_stream_alloc(
+	git_subtransport *t,
+	const char *url,
+	const char *cmd,
+	const char *host,
+	const char *port,
+	git_smart_subtransport_stream **stream)
+{
+	git_proto_stream *s;
+
+	if (!stream)
+		return -1;
+
+	s = git__calloc(1, sizeof(git_proto_stream));
+	GITERR_CHECK_ALLOC(s);
+
+	s->parent.subtransport = &t->parent;
+	s->parent.read = git_proto_stream_read;
+	s->parent.write = git_proto_stream_write;
+	s->parent.free = git_proto_stream_free;
+
+	s->cmd = cmd;
+	s->url = git__strdup(url);
+
+	if (!s->url) {
+		git__free(s);
+		return -1;
+	}
+
+	if ((git_socket_stream_new(&s->io, host, port)) < 0)
+		return -1;
+
+	GITERR_CHECK_VERSION(s->io, GIT_STREAM_VERSION, "git_stream");
+
+	*stream = &s->parent;
+	return 0;
+}
+
+static int _git_uploadpack_ls(
+	git_subtransport *t,
+	const char *url,
+	git_smart_subtransport_stream **stream)
+{
+	char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL;
+	const char *stream_url = url;
+	git_proto_stream *s;
+	int error;
+
+	*stream = NULL;
+
+	if (!git__prefixcmp(url, prefix_git))
+		stream_url += strlen(prefix_git);
+
+	if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, GIT_DEFAULT_PORT)) < 0)
+		return error;
+
+	error = git_proto_stream_alloc(t, stream_url, cmd_uploadpack, host, port, stream);
+
+	git__free(host);
+	git__free(port);
+	git__free(path);
+	git__free(user);
+	git__free(pass);
+
+
+	if (error < 0) {
+		git_proto_stream_free(*stream);
+		return error;
+	}
+
+	s = (git_proto_stream *) *stream;
+	if ((error = git_stream_connect(s->io)) < 0) {
+		git_proto_stream_free(*stream);
+		return error;
+	}
+
+	t->current_stream = s;
+
+	return 0;
+}
+
+static int _git_uploadpack(
+	git_subtransport *t,
+	const char *url,
+	git_smart_subtransport_stream **stream)
+{
+	GIT_UNUSED(url);
+
+	if (t->current_stream) {
+		*stream = &t->current_stream->parent;
+		return 0;
+	}
+
+	giterr_set(GITERR_NET, "Must call UPLOADPACK_LS before UPLOADPACK");
+	return -1;
+}
+
+static int _git_receivepack_ls(
+	git_subtransport *t,
+	const char *url,
+	git_smart_subtransport_stream **stream)
+{
+	char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL;
+	const char *stream_url = url;
+	git_proto_stream *s;
+	int error;
+
+	*stream = NULL;
+	if (!git__prefixcmp(url, prefix_git))
+		stream_url += strlen(prefix_git);
+
+	if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, GIT_DEFAULT_PORT)) < 0)
+		return error;
+
+	error = git_proto_stream_alloc(t, stream_url, cmd_receivepack, host, port, stream);
+
+	git__free(host);
+	git__free(port);
+	git__free(path);
+	git__free(user);
+	git__free(pass);
+
+	if (error < 0) {
+		git_proto_stream_free(*stream);
+		return error;
+	}
+
+	s = (git_proto_stream *) *stream;
+
+	if ((error = git_stream_connect(s->io)) < 0)
+		return error;
+
+	t->current_stream = s;
+
+	return 0;
+}
+
+static int _git_receivepack(
+	git_subtransport *t,
+	const char *url,
+	git_smart_subtransport_stream **stream)
+{
+	GIT_UNUSED(url);
+
+	if (t->current_stream) {
+		*stream = &t->current_stream->parent;
+		return 0;
+	}
+
+	giterr_set(GITERR_NET, "Must call RECEIVEPACK_LS before RECEIVEPACK");
+	return -1;
+}
+
+static int _git_action(
+	git_smart_subtransport_stream **stream,
+	git_smart_subtransport *subtransport,
+	const char *url,
+	git_smart_service_t action)
+{
+	git_subtransport *t = (git_subtransport *) subtransport;
+
+	switch (action) {
+		case GIT_SERVICE_UPLOADPACK_LS:
+			return _git_uploadpack_ls(t, url, stream);
+
+		case GIT_SERVICE_UPLOADPACK:
+			return _git_uploadpack(t, url, stream);
+
+		case GIT_SERVICE_RECEIVEPACK_LS:
+			return _git_receivepack_ls(t, url, stream);
+
+		case GIT_SERVICE_RECEIVEPACK:
+			return _git_receivepack(t, url, stream);
+	}
+
+	*stream = NULL;
+	return -1;
+}
+
+static int _git_close(git_smart_subtransport *subtransport)
+{
+	git_subtransport *t = (git_subtransport *) subtransport;
+
+	assert(!t->current_stream);
+
+	GIT_UNUSED(t);
+
+	return 0;
+}
+
+static void _git_free(git_smart_subtransport *subtransport)
+{
+	git_subtransport *t = (git_subtransport *) subtransport;
+
+	assert(!t->current_stream);
+
+	git__free(t);
+}
+
+int git_smart_subtransport_git(git_smart_subtransport **out, git_transport *owner, void *param)
+{
+	git_subtransport *t;
+
+	GIT_UNUSED(param);
+
+	if (!out)
+		return -1;
+
+	t = git__calloc(1, sizeof(git_subtransport));
+	GITERR_CHECK_ALLOC(t);
+
+	t->owner = owner;
+	t->parent.action = _git_action;
+	t->parent.close = _git_close;
+	t->parent.free = _git_free;
+
+	*out = (git_smart_subtransport *) t;
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/http.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/http.c
new file mode 100755
index 0000000..87f3ee8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/http.c
@@ -0,0 +1,1065 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef GIT_WINHTTP
+
+#include "git2.h"
+#include "http_parser.h"
+#include "buffer.h"
+#include "netops.h"
+#include "remote.h"
+#include "smart.h"
+#include "auth.h"
+#include "auth_negotiate.h"
+#include "tls_stream.h"
+#include "socket_stream.h"
+#include "curl_stream.h"
+
+git_http_auth_scheme auth_schemes[] = {
+	{ GIT_AUTHTYPE_NEGOTIATE, "Negotiate", GIT_CREDTYPE_DEFAULT, git_http_auth_negotiate },
+	{ GIT_AUTHTYPE_BASIC, "Basic", GIT_CREDTYPE_USERPASS_PLAINTEXT, git_http_auth_basic },
+};
+
+static const char *upload_pack_service = "upload-pack";
+static const char *upload_pack_ls_service_url = "/info/refs?service=git-upload-pack";
+static const char *upload_pack_service_url = "/git-upload-pack";
+static const char *receive_pack_service = "receive-pack";
+static const char *receive_pack_ls_service_url = "/info/refs?service=git-receive-pack";
+static const char *receive_pack_service_url = "/git-receive-pack";
+static const char *get_verb = "GET";
+static const char *post_verb = "POST";
+
+#define OWNING_SUBTRANSPORT(s) ((http_subtransport *)(s)->parent.subtransport)
+
+#define PARSE_ERROR_GENERIC	-1
+#define PARSE_ERROR_REPLAY	-2
+/** Look at the user field */
+#define PARSE_ERROR_EXT         -3
+
+#define CHUNK_SIZE	4096
+
+enum last_cb {
+	NONE,
+	FIELD,
+	VALUE
+};
+
+typedef struct {
+	git_smart_subtransport_stream parent;
+	const char *service;
+	const char *service_url;
+	char *redirect_url;
+	const char *verb;
+	char *chunk_buffer;
+	unsigned chunk_buffer_len;
+	unsigned sent_request : 1,
+		received_response : 1,
+		chunked : 1,
+		redirect_count : 3;
+} http_stream;
+
+typedef struct {
+	git_smart_subtransport parent;
+	transport_smart *owner;
+	git_stream *io;
+	gitno_connection_data connection_data;
+	bool connected;
+
+	/* Parser structures */
+	http_parser parser;
+	http_parser_settings settings;
+	gitno_buffer parse_buffer;
+	git_buf parse_header_name;
+	git_buf parse_header_value;
+	char parse_buffer_data[NETIO_BUFSIZE];
+	char *content_type;
+	char *location;
+	git_vector www_authenticate;
+	enum last_cb last_cb;
+	int parse_error;
+	int error;
+	unsigned parse_finished : 1;
+
+	/* Authentication */
+	git_cred *cred;
+	git_cred *url_cred;
+	git_vector auth_contexts;
+} http_subtransport;
+
+typedef struct {
+	http_stream *s;
+	http_subtransport *t;
+
+	/* Target buffer details from read() */
+	char *buffer;
+	size_t buf_size;
+	size_t *bytes_read;
+} parser_context;
+
+static bool credtype_match(git_http_auth_scheme *scheme, void *data)
+{
+	unsigned int credtype = *(unsigned int *)data;
+
+	return !!(scheme->credtypes & credtype);
+}
+
+static bool challenge_match(git_http_auth_scheme *scheme, void *data)
+{
+	const char *scheme_name = scheme->name;
+	const char *challenge = (const char *)data;
+	size_t scheme_len;
+
+	scheme_len = strlen(scheme_name);
+	return (strncmp(challenge, scheme_name, scheme_len) == 0 &&
+		(challenge[scheme_len] == '\0' || challenge[scheme_len] == ' '));
+}
+
+static int auth_context_match(
+	git_http_auth_context **out,
+	http_subtransport *t,
+	bool (*scheme_match)(git_http_auth_scheme *scheme, void *data),
+	void *data)
+{
+	git_http_auth_scheme *scheme = NULL;
+	git_http_auth_context *context = NULL, *c;
+	size_t i;
+
+	*out = NULL;
+
+	for (i = 0; i < ARRAY_SIZE(auth_schemes); i++) {
+		if (scheme_match(&auth_schemes[i], data)) {
+			scheme = &auth_schemes[i];
+			break;
+		}
+	}
+
+	if (!scheme)
+		return 0;
+
+	/* See if authentication has already started for this scheme */
+	git_vector_foreach(&t->auth_contexts, i, c) {
+		if (c->type == scheme->type) {
+			context = c;
+			break;
+		}
+	}
+
+	if (!context) {
+		if (scheme->init_context(&context, &t->connection_data) < 0)
+			return -1;
+		else if (!context)
+			return 0;
+		else if (git_vector_insert(&t->auth_contexts, context) < 0)
+			return -1;
+	}
+
+	*out = context;
+
+	return 0;
+}
+
+static int apply_credentials(git_buf *buf, http_subtransport *t)
+{
+	git_cred *cred = t->cred;
+	git_http_auth_context *context;
+
+	/* Apply the credentials given to us in the URL */
+	if (!cred && t->connection_data.user && t->connection_data.pass) {
+		if (!t->url_cred &&
+			git_cred_userpass_plaintext_new(&t->url_cred,
+				t->connection_data.user, t->connection_data.pass) < 0)
+			return -1;
+
+		cred = t->url_cred;
+	}
+
+	if (!cred)
+		return 0;
+
+	/* Get or create a context for the best scheme for this cred type */
+	if (auth_context_match(&context, t, credtype_match, &cred->credtype) < 0)
+		return -1;
+
+	return context->next_token(buf, context, cred);
+}
+
+static int gen_request(
+	git_buf *buf,
+	http_stream *s,
+	size_t content_length)
+{
+	http_subtransport *t = OWNING_SUBTRANSPORT(s);
+	const char *path = t->connection_data.path ? t->connection_data.path : "/";
+
+	git_buf_printf(buf, "%s %s%s HTTP/1.1\r\n", s->verb, path, s->service_url);
+
+	git_buf_puts(buf, "User-Agent: git/1.0 (libgit2 " LIBGIT2_VERSION ")\r\n");
+	git_buf_printf(buf, "Host: %s\r\n", t->connection_data.host);
+
+	if (s->chunked || content_length > 0) {
+		git_buf_printf(buf, "Accept: application/x-git-%s-result\r\n", s->service);
+		git_buf_printf(buf, "Content-Type: application/x-git-%s-request\r\n", s->service);
+
+		if (s->chunked)
+			git_buf_puts(buf, "Transfer-Encoding: chunked\r\n");
+		else
+			git_buf_printf(buf, "Content-Length: %"PRIuZ "\r\n", content_length);
+	} else
+		git_buf_puts(buf, "Accept: */*\r\n");
+
+	/* Apply credentials to the request */
+	if (apply_credentials(buf, t) < 0)
+		return -1;
+
+	git_buf_puts(buf, "\r\n");
+
+	if (git_buf_oom(buf))
+		return -1;
+
+	return 0;
+}
+
+static int parse_authenticate_response(
+	git_vector *www_authenticate,
+	http_subtransport *t,
+	int *allowed_types)
+{
+	git_http_auth_context *context;
+	char *challenge;
+	size_t i;
+
+	git_vector_foreach(www_authenticate, i, challenge) {
+		if (auth_context_match(&context, t, challenge_match, challenge) < 0)
+			return -1;
+		else if (!context)
+			continue;
+
+		if (context->set_challenge &&
+			context->set_challenge(context, challenge) < 0)
+			return -1;
+
+		*allowed_types |= context->credtypes;
+	}
+
+	return 0;
+}
+
+static int on_header_ready(http_subtransport *t)
+{
+	git_buf *name = &t->parse_header_name;
+	git_buf *value = &t->parse_header_value;
+
+	if (!strcasecmp("Content-Type", git_buf_cstr(name))) {
+		if (!t->content_type) {
+			t->content_type = git__strdup(git_buf_cstr(value));
+			GITERR_CHECK_ALLOC(t->content_type);
+		}
+	}
+	else if (!strcasecmp("WWW-Authenticate", git_buf_cstr(name))) {
+		char *dup = git__strdup(git_buf_cstr(value));
+		GITERR_CHECK_ALLOC(dup);
+
+		git_vector_insert(&t->www_authenticate, dup);
+	}
+	else if (!strcasecmp("Location", git_buf_cstr(name))) {
+		if (!t->location) {
+			t->location = git__strdup(git_buf_cstr(value));
+			GITERR_CHECK_ALLOC(t->location);
+		}
+	}
+
+	return 0;
+}
+
+static int on_header_field(http_parser *parser, const char *str, size_t len)
+{
+	parser_context *ctx = (parser_context *) parser->data;
+	http_subtransport *t = ctx->t;
+
+	/* Both parse_header_name and parse_header_value are populated
+	 * and ready for consumption */
+	if (VALUE == t->last_cb)
+		if (on_header_ready(t) < 0)
+			return t->parse_error = PARSE_ERROR_GENERIC;
+
+	if (NONE == t->last_cb || VALUE == t->last_cb)
+		git_buf_clear(&t->parse_header_name);
+
+	if (git_buf_put(&t->parse_header_name, str, len) < 0)
+		return t->parse_error = PARSE_ERROR_GENERIC;
+
+	t->last_cb = FIELD;
+	return 0;
+}
+
+static int on_header_value(http_parser *parser, const char *str, size_t len)
+{
+	parser_context *ctx = (parser_context *) parser->data;
+	http_subtransport *t = ctx->t;
+
+	assert(NONE != t->last_cb);
+
+	if (FIELD == t->last_cb)
+		git_buf_clear(&t->parse_header_value);
+
+	if (git_buf_put(&t->parse_header_value, str, len) < 0)
+		return t->parse_error = PARSE_ERROR_GENERIC;
+
+	t->last_cb = VALUE;
+	return 0;
+}
+
+static int on_headers_complete(http_parser *parser)
+{
+	parser_context *ctx = (parser_context *) parser->data;
+	http_subtransport *t = ctx->t;
+	http_stream *s = ctx->s;
+	git_buf buf = GIT_BUF_INIT;
+	int error = 0, no_callback = 0, allowed_auth_types = 0;
+
+	/* Both parse_header_name and parse_header_value are populated
+	 * and ready for consumption. */
+	if (VALUE == t->last_cb)
+		if (on_header_ready(t) < 0)
+			return t->parse_error = PARSE_ERROR_GENERIC;
+
+	/* Capture authentication headers which may be a 401 (authentication
+	 * is not complete) or a 200 (simply informing us that auth *is*
+	 * complete.)
+	 */
+	if (parse_authenticate_response(&t->www_authenticate, t,
+			&allowed_auth_types) < 0)
+		return t->parse_error = PARSE_ERROR_GENERIC;
+
+	/* Check for an authentication failure. */
+	if (parser->status_code == 401 && get_verb == s->verb) {
+		if (!t->owner->cred_acquire_cb) {
+			no_callback = 1;
+		} else {
+			if (allowed_auth_types) {
+				if (t->cred) {
+					t->cred->free(t->cred);
+					t->cred = NULL;
+				}
+
+				error = t->owner->cred_acquire_cb(&t->cred,
+								  t->owner->url,
+								  t->connection_data.user,
+								  allowed_auth_types,
+								  t->owner->cred_acquire_payload);
+
+				if (error == GIT_PASSTHROUGH) {
+					no_callback = 1;
+				} else if (error < 0) {
+					t->error = error;
+					return t->parse_error = PARSE_ERROR_EXT;
+				} else {
+					assert(t->cred);
+
+					if (!(t->cred->credtype & allowed_auth_types)) {
+						giterr_set(GITERR_NET, "credentials callback returned an invalid cred type");
+						return t->parse_error = PARSE_ERROR_GENERIC;
+					}
+
+					/* Successfully acquired a credential. */
+					t->parse_error = PARSE_ERROR_REPLAY;
+					return 0;
+				}
+			}
+		}
+
+		if (no_callback) {
+			giterr_set(GITERR_NET, "authentication required but no callback set");
+			return t->parse_error = PARSE_ERROR_GENERIC;
+		}
+	}
+
+	/* Check for a redirect.
+	 * Right now we only permit a redirect to the same hostname. */
+	if ((parser->status_code == 301 ||
+	     parser->status_code == 302 ||
+	     (parser->status_code == 303 && get_verb == s->verb) ||
+	     parser->status_code == 307) &&
+	    t->location) {
+
+		if (s->redirect_count >= 7) {
+			giterr_set(GITERR_NET, "Too many redirects");
+			return t->parse_error = PARSE_ERROR_GENERIC;
+		}
+
+		if (gitno_connection_data_from_url(&t->connection_data, t->location, s->service_url) < 0)
+			return t->parse_error = PARSE_ERROR_GENERIC;
+
+		/* Set the redirect URL on the stream. This is a transfer of
+		 * ownership of the memory. */
+		if (s->redirect_url)
+			git__free(s->redirect_url);
+
+		s->redirect_url = t->location;
+		t->location = NULL;
+
+		t->connected = 0;
+		s->redirect_count++;
+
+		t->parse_error = PARSE_ERROR_REPLAY;
+		return 0;
+	}
+
+	/* Check for a 200 HTTP status code. */
+	if (parser->status_code != 200) {
+		giterr_set(GITERR_NET,
+			"Unexpected HTTP status code: %d",
+			parser->status_code);
+		return t->parse_error = PARSE_ERROR_GENERIC;
+	}
+
+	/* The response must contain a Content-Type header. */
+	if (!t->content_type) {
+		giterr_set(GITERR_NET, "No Content-Type header in response");
+		return t->parse_error = PARSE_ERROR_GENERIC;
+	}
+
+	/* The Content-Type header must match our expectation. */
+	if (get_verb == s->verb)
+		git_buf_printf(&buf,
+			"application/x-git-%s-advertisement",
+			ctx->s->service);
+	else
+		git_buf_printf(&buf,
+			"application/x-git-%s-result",
+			ctx->s->service);
+
+	if (git_buf_oom(&buf))
+		return t->parse_error = PARSE_ERROR_GENERIC;
+
+	if (strcmp(t->content_type, git_buf_cstr(&buf))) {
+		git_buf_free(&buf);
+		giterr_set(GITERR_NET,
+			"Invalid Content-Type: %s",
+			t->content_type);
+		return t->parse_error = PARSE_ERROR_GENERIC;
+	}
+
+	git_buf_free(&buf);
+
+	return 0;
+}
+
+static int on_message_complete(http_parser *parser)
+{
+	parser_context *ctx = (parser_context *) parser->data;
+	http_subtransport *t = ctx->t;
+
+	t->parse_finished = 1;
+
+	return 0;
+}
+
+static int on_body_fill_buffer(http_parser *parser, const char *str, size_t len)
+{
+	parser_context *ctx = (parser_context *) parser->data;
+	http_subtransport *t = ctx->t;
+
+	/* If our goal is to replay the request (either an auth failure or
+	 * a redirect) then don't bother buffering since we're ignoring the
+	 * content anyway.
+	 */
+	if (t->parse_error == PARSE_ERROR_REPLAY)
+		return 0;
+
+	if (ctx->buf_size < len) {
+		giterr_set(GITERR_NET, "Can't fit data in the buffer");
+		return t->parse_error = PARSE_ERROR_GENERIC;
+	}
+
+	memcpy(ctx->buffer, str, len);
+	*(ctx->bytes_read) += len;
+	ctx->buffer += len;
+	ctx->buf_size -= len;
+
+	return 0;
+}
+
+static void clear_parser_state(http_subtransport *t)
+{
+	http_parser_init(&t->parser, HTTP_RESPONSE);
+	gitno_buffer_setup_fromstream(t->io,
+		&t->parse_buffer,
+		t->parse_buffer_data,
+		sizeof(t->parse_buffer_data));
+
+	t->last_cb = NONE;
+	t->parse_error = 0;
+	t->parse_finished = 0;
+
+	git_buf_free(&t->parse_header_name);
+	git_buf_init(&t->parse_header_name, 0);
+
+	git_buf_free(&t->parse_header_value);
+	git_buf_init(&t->parse_header_value, 0);
+
+	git__free(t->content_type);
+	t->content_type = NULL;
+
+	git__free(t->location);
+	t->location = NULL;
+
+	git_vector_free_deep(&t->www_authenticate);
+}
+
+static int write_chunk(git_stream *io, const char *buffer, size_t len)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	/* Chunk header */
+	git_buf_printf(&buf, "%" PRIxZ "\r\n", len);
+
+	if (git_buf_oom(&buf))
+		return -1;
+
+	if (git_stream_write(io, buf.ptr, buf.size, 0) < 0) {
+		git_buf_free(&buf);
+		return -1;
+	}
+
+	git_buf_free(&buf);
+
+	/* Chunk body */
+	if (len > 0 && git_stream_write(io, buffer, len, 0) < 0)
+		return -1;
+
+	/* Chunk footer */
+	if (git_stream_write(io, "\r\n", 2, 0) < 0)
+		return -1;
+
+	return 0;
+}
+
+static int http_connect(http_subtransport *t)
+{
+	int error;
+	char *proxy_url;
+
+	if (t->connected &&
+		http_should_keep_alive(&t->parser) &&
+		t->parse_finished)
+		return 0;
+
+	if (t->io) {
+		git_stream_close(t->io);
+		git_stream_free(t->io);
+		t->io = NULL;
+	}
+
+	if (t->connection_data.use_ssl) {
+		error = git_tls_stream_new(&t->io, t->connection_data.host, t->connection_data.port);
+	} else {
+#ifdef GIT_CURL
+		error = git_curl_stream_new(&t->io, t->connection_data.host, t->connection_data.port);
+#else
+		error = git_socket_stream_new(&t->io,  t->connection_data.host, t->connection_data.port);
+#endif
+	}
+
+	if (error < 0)
+		return error;
+
+	GITERR_CHECK_VERSION(t->io, GIT_STREAM_VERSION, "git_stream");
+
+	if (git_stream_supports_proxy(t->io) &&
+	    !git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url)) {
+		error = git_stream_set_proxy(t->io, proxy_url);
+		git__free(proxy_url);
+
+		if (error < 0)
+			return error;
+	}
+
+	error = git_stream_connect(t->io);
+
+#if defined(GIT_OPENSSL) || defined(GIT_SECURE_TRANSPORT) || defined(GIT_CURL)
+	if ((!error || error == GIT_ECERTIFICATE) && t->owner->certificate_check_cb != NULL &&
+	    git_stream_is_encrypted(t->io)) {
+		git_cert *cert;
+		int is_valid;
+
+		if ((error = git_stream_certificate(&cert, t->io)) < 0)
+			return error;
+
+		giterr_clear();
+		is_valid = error != GIT_ECERTIFICATE;
+		error = t->owner->certificate_check_cb(cert, is_valid, t->connection_data.host, t->owner->message_cb_payload);
+
+		if (error < 0) {
+			if (!giterr_last())
+				giterr_set(GITERR_NET, "user cancelled certificate check");
+
+			return error;
+		}
+	}
+#endif
+	if (error < 0)
+		return error;
+
+	t->connected = 1;
+	return 0;
+}
+
+static int http_stream_read(
+	git_smart_subtransport_stream *stream,
+	char *buffer,
+	size_t buf_size,
+	size_t *bytes_read)
+{
+	http_stream *s = (http_stream *)stream;
+	http_subtransport *t = OWNING_SUBTRANSPORT(s);
+	parser_context ctx;
+	size_t bytes_parsed;
+
+replay:
+	*bytes_read = 0;
+
+	assert(t->connected);
+
+	if (!s->sent_request) {
+		git_buf request = GIT_BUF_INIT;
+
+		clear_parser_state(t);
+
+		if (gen_request(&request, s, 0) < 0)
+			return -1;
+
+		if (git_stream_write(t->io, request.ptr, request.size, 0) < 0) {
+			git_buf_free(&request);
+			return -1;
+		}
+
+		git_buf_free(&request);
+
+		s->sent_request = 1;
+	}
+
+	if (!s->received_response) {
+		if (s->chunked) {
+			assert(s->verb == post_verb);
+
+			/* Flush, if necessary */
+			if (s->chunk_buffer_len > 0 &&
+				write_chunk(t->io, s->chunk_buffer, s->chunk_buffer_len) < 0)
+				return -1;
+
+			s->chunk_buffer_len = 0;
+
+			/* Write the final chunk. */
+			if (git_stream_write(t->io, "0\r\n\r\n", 5, 0) < 0)
+				return -1;
+		}
+
+		s->received_response = 1;
+	}
+
+	while (!*bytes_read && !t->parse_finished) {
+		size_t data_offset;
+		int error;
+
+		/*
+		 * Make the parse_buffer think it's as full of data as
+		 * the buffer, so it won't try to recv more data than
+		 * we can put into it.
+		 *
+		 * data_offset is the actual data offset from which we
+		 * should tell the parser to start reading.
+		 */
+		if (buf_size >= t->parse_buffer.len) {
+			t->parse_buffer.offset = 0;
+		} else {
+			t->parse_buffer.offset = t->parse_buffer.len - buf_size;
+		}
+
+		data_offset = t->parse_buffer.offset;
+
+		if (gitno_recv(&t->parse_buffer) < 0)
+			return -1;
+
+		/* This call to http_parser_execute will result in invocations of the
+		 * on_* family of callbacks. The most interesting of these is
+		 * on_body_fill_buffer, which is called when data is ready to be copied
+		 * into the target buffer. We need to marshal the buffer, buf_size, and
+		 * bytes_read parameters to this callback. */
+		ctx.t = t;
+		ctx.s = s;
+		ctx.buffer = buffer;
+		ctx.buf_size = buf_size;
+		ctx.bytes_read = bytes_read;
+
+		/* Set the context, call the parser, then unset the context. */
+		t->parser.data = &ctx;
+
+		bytes_parsed = http_parser_execute(&t->parser,
+			&t->settings,
+			t->parse_buffer.data + data_offset,
+			t->parse_buffer.offset - data_offset);
+
+		t->parser.data = NULL;
+
+		/* If there was a handled authentication failure, then parse_error
+		 * will have signaled us that we should replay the request. */
+		if (PARSE_ERROR_REPLAY == t->parse_error) {
+			s->sent_request = 0;
+
+			if ((error = http_connect(t)) < 0)
+				return error;
+
+			goto replay;
+		}
+
+		if (t->parse_error == PARSE_ERROR_EXT) {
+			return t->error;
+		}
+
+		if (t->parse_error < 0)
+			return -1;
+
+		if (bytes_parsed != t->parse_buffer.offset - data_offset) {
+			giterr_set(GITERR_NET,
+				"HTTP parser error: %s",
+				http_errno_description((enum http_errno)t->parser.http_errno));
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int http_stream_write_chunked(
+	git_smart_subtransport_stream *stream,
+	const char *buffer,
+	size_t len)
+{
+	http_stream *s = (http_stream *)stream;
+	http_subtransport *t = OWNING_SUBTRANSPORT(s);
+
+	assert(t->connected);
+
+	/* Send the request, if necessary */
+	if (!s->sent_request) {
+		git_buf request = GIT_BUF_INIT;
+
+		clear_parser_state(t);
+
+		if (gen_request(&request, s, 0) < 0)
+			return -1;
+
+		if (git_stream_write(t->io, request.ptr, request.size, 0) < 0) {
+			git_buf_free(&request);
+			return -1;
+		}
+
+		git_buf_free(&request);
+
+		s->sent_request = 1;
+	}
+
+	if (len > CHUNK_SIZE) {
+		/* Flush, if necessary */
+		if (s->chunk_buffer_len > 0) {
+			if (write_chunk(t->io, s->chunk_buffer, s->chunk_buffer_len) < 0)
+				return -1;
+
+			s->chunk_buffer_len = 0;
+		}
+
+		/* Write chunk directly */
+		if (write_chunk(t->io, buffer, len) < 0)
+			return -1;
+	}
+	else {
+		/* Append as much to the buffer as we can */
+		int count = min(CHUNK_SIZE - s->chunk_buffer_len, len);
+
+		if (!s->chunk_buffer)
+			s->chunk_buffer = git__malloc(CHUNK_SIZE);
+
+		memcpy(s->chunk_buffer + s->chunk_buffer_len, buffer, count);
+		s->chunk_buffer_len += count;
+		buffer += count;
+		len -= count;
+
+		/* Is the buffer full? If so, then flush */
+		if (CHUNK_SIZE == s->chunk_buffer_len) {
+			if (write_chunk(t->io, s->chunk_buffer, s->chunk_buffer_len) < 0)
+				return -1;
+
+			s->chunk_buffer_len = 0;
+
+			if (len > 0) {
+				memcpy(s->chunk_buffer, buffer, len);
+				s->chunk_buffer_len = len;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int http_stream_write_single(
+	git_smart_subtransport_stream *stream,
+	const char *buffer,
+	size_t len)
+{
+	http_stream *s = (http_stream *)stream;
+	http_subtransport *t = OWNING_SUBTRANSPORT(s);
+	git_buf request = GIT_BUF_INIT;
+
+	assert(t->connected);
+
+	if (s->sent_request) {
+		giterr_set(GITERR_NET, "Subtransport configured for only one write");
+		return -1;
+	}
+
+	clear_parser_state(t);
+
+	if (gen_request(&request, s, len) < 0)
+		return -1;
+
+	if (git_stream_write(t->io, request.ptr, request.size, 0) < 0)
+		goto on_error;
+
+	if (len && git_stream_write(t->io, buffer, len, 0) < 0)
+		goto on_error;
+
+	git_buf_free(&request);
+	s->sent_request = 1;
+
+	return 0;
+
+on_error:
+	git_buf_free(&request);
+	return -1;
+}
+
+static void http_stream_free(git_smart_subtransport_stream *stream)
+{
+	http_stream *s = (http_stream *)stream;
+
+	if (s->chunk_buffer)
+		git__free(s->chunk_buffer);
+
+	if (s->redirect_url)
+		git__free(s->redirect_url);
+
+	git__free(s);
+}
+
+static int http_stream_alloc(http_subtransport *t,
+	git_smart_subtransport_stream **stream)
+{
+	http_stream *s;
+
+	if (!stream)
+		return -1;
+
+	s = git__calloc(sizeof(http_stream), 1);
+	GITERR_CHECK_ALLOC(s);
+
+	s->parent.subtransport = &t->parent;
+	s->parent.read = http_stream_read;
+	s->parent.write = http_stream_write_single;
+	s->parent.free = http_stream_free;
+
+	*stream = (git_smart_subtransport_stream *)s;
+	return 0;
+}
+
+static int http_uploadpack_ls(
+	http_subtransport *t,
+	git_smart_subtransport_stream **stream)
+{
+	http_stream *s;
+
+	if (http_stream_alloc(t, stream) < 0)
+		return -1;
+
+	s = (http_stream *)*stream;
+
+	s->service = upload_pack_service;
+	s->service_url = upload_pack_ls_service_url;
+	s->verb = get_verb;
+
+	return 0;
+}
+
+static int http_uploadpack(
+	http_subtransport *t,
+	git_smart_subtransport_stream **stream)
+{
+	http_stream *s;
+
+	if (http_stream_alloc(t, stream) < 0)
+		return -1;
+
+	s = (http_stream *)*stream;
+
+	s->service = upload_pack_service;
+	s->service_url = upload_pack_service_url;
+	s->verb = post_verb;
+
+	return 0;
+}
+
+static int http_receivepack_ls(
+	http_subtransport *t,
+	git_smart_subtransport_stream **stream)
+{
+	http_stream *s;
+
+	if (http_stream_alloc(t, stream) < 0)
+		return -1;
+
+	s = (http_stream *)*stream;
+
+	s->service = receive_pack_service;
+	s->service_url = receive_pack_ls_service_url;
+	s->verb = get_verb;
+
+	return 0;
+}
+
+static int http_receivepack(
+	http_subtransport *t,
+	git_smart_subtransport_stream **stream)
+{
+	http_stream *s;
+
+	if (http_stream_alloc(t, stream) < 0)
+		return -1;
+
+	s = (http_stream *)*stream;
+
+	/* Use Transfer-Encoding: chunked for this request */
+	s->chunked = 1;
+	s->parent.write = http_stream_write_chunked;
+
+	s->service = receive_pack_service;
+	s->service_url = receive_pack_service_url;
+	s->verb = post_verb;
+
+	return 0;
+}
+
+static int http_action(
+	git_smart_subtransport_stream **stream,
+	git_smart_subtransport *subtransport,
+	const char *url,
+	git_smart_service_t action)
+{
+	http_subtransport *t = (http_subtransport *)subtransport;
+	int ret;
+
+	if (!stream)
+		return -1;
+
+	if ((!t->connection_data.host || !t->connection_data.port || !t->connection_data.path) &&
+		 (ret = gitno_connection_data_from_url(&t->connection_data, url, NULL)) < 0)
+		return ret;
+
+	if ((ret = http_connect(t)) < 0)
+		return ret;
+
+	switch (action) {
+	case GIT_SERVICE_UPLOADPACK_LS:
+		return http_uploadpack_ls(t, stream);
+
+	case GIT_SERVICE_UPLOADPACK:
+		return http_uploadpack(t, stream);
+
+	case GIT_SERVICE_RECEIVEPACK_LS:
+		return http_receivepack_ls(t, stream);
+
+	case GIT_SERVICE_RECEIVEPACK:
+		return http_receivepack(t, stream);
+	}
+
+	*stream = NULL;
+	return -1;
+}
+
+static int http_close(git_smart_subtransport *subtransport)
+{
+	http_subtransport *t = (http_subtransport *) subtransport;
+	git_http_auth_context *context;
+	size_t i;
+
+	clear_parser_state(t);
+
+	if (t->io) {
+		git_stream_close(t->io);
+		git_stream_free(t->io);
+		t->io = NULL;
+	}
+
+	if (t->cred) {
+		t->cred->free(t->cred);
+		t->cred = NULL;
+	}
+
+	if (t->url_cred) {
+		t->url_cred->free(t->url_cred);
+		t->url_cred = NULL;
+	}
+
+	git_vector_foreach(&t->auth_contexts, i, context) {
+		if (context->free)
+			context->free(context);
+	}
+
+	git_vector_clear(&t->auth_contexts);
+
+	gitno_connection_data_free_ptrs(&t->connection_data);
+	memset(&t->connection_data, 0x0, sizeof(gitno_connection_data));
+
+	return 0;
+}
+
+static void http_free(git_smart_subtransport *subtransport)
+{
+	http_subtransport *t = (http_subtransport *) subtransport;
+
+	http_close(subtransport);
+
+	git_vector_free(&t->auth_contexts);
+	git__free(t);
+}
+
+int git_smart_subtransport_http(git_smart_subtransport **out, git_transport *owner, void *param)
+{
+	http_subtransport *t;
+
+	GIT_UNUSED(param);
+
+	if (!out)
+		return -1;
+
+	t = git__calloc(sizeof(http_subtransport), 1);
+	GITERR_CHECK_ALLOC(t);
+
+	t->owner = (transport_smart *)owner;
+	t->parent.action = http_action;
+	t->parent.close = http_close;
+	t->parent.free = http_free;
+
+	t->settings.on_header_field = on_header_field;
+	t->settings.on_header_value = on_header_value;
+	t->settings.on_headers_complete = on_headers_complete;
+	t->settings.on_body = on_body_fill_buffer;
+	t->settings.on_message_complete = on_message_complete;
+
+	*out = (git_smart_subtransport *) t;
+	return 0;
+}
+
+#endif /* !GIT_WINHTTP */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/local.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/local.c
new file mode 100755
index 0000000..1c6e5f0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/local.c
@@ -0,0 +1,718 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "common.h"
+#include "git2/types.h"
+#include "git2/net.h"
+#include "git2/repository.h"
+#include "git2/object.h"
+#include "git2/tag.h"
+#include "git2/transport.h"
+#include "git2/revwalk.h"
+#include "git2/odb_backend.h"
+#include "git2/pack.h"
+#include "git2/commit.h"
+#include "git2/revparse.h"
+#include "pack-objects.h"
+#include "refs.h"
+#include "posix.h"
+#include "path.h"
+#include "buffer.h"
+#include "repository.h"
+#include "odb.h"
+#include "push.h"
+#include "remote.h"
+
+typedef struct {
+	git_transport parent;
+	git_remote *owner;
+	char *url;
+	int direction;
+	int flags;
+	git_atomic cancelled;
+	git_repository *repo;
+	git_transport_message_cb progress_cb;
+	git_transport_message_cb error_cb;
+	void *message_cb_payload;
+	git_vector refs;
+	unsigned connected : 1,
+		have_refs : 1;
+} transport_local;
+
+static void free_head(git_remote_head *head)
+{
+	git__free(head->name);
+	git__free(head->symref_target);
+	git__free(head);
+}
+
+static void free_heads(git_vector *heads)
+{
+	git_remote_head *head;
+	size_t i;
+
+	git_vector_foreach(heads, i, head)
+		free_head(head);
+
+	git_vector_free(heads);
+}
+
+static int add_ref(transport_local *t, const char *name)
+{
+	const char peeled[] = "^{}";
+	git_reference *ref, *resolved;
+	git_remote_head *head;
+	git_oid obj_id;
+	git_object *obj = NULL, *target = NULL;
+	git_buf buf = GIT_BUF_INIT;
+	int error;
+
+	if ((error = git_reference_lookup(&ref, t->repo, name)) < 0)
+		return error;
+
+	error = git_reference_resolve(&resolved, ref);
+	if (error < 0) {
+		git_reference_free(ref);
+		if (!strcmp(name, GIT_HEAD_FILE) && error == GIT_ENOTFOUND) {
+			/* This is actually okay.  Empty repos often have a HEAD that
+			 * points to a nonexistent "refs/heads/master". */
+			giterr_clear();
+			return 0;
+		}
+		return error;
+	}
+
+	git_oid_cpy(&obj_id, git_reference_target(resolved));
+	git_reference_free(resolved);
+
+	head = git__calloc(1, sizeof(git_remote_head));
+	GITERR_CHECK_ALLOC(head);
+
+	head->name = git__strdup(name);
+	GITERR_CHECK_ALLOC(head->name);
+
+	git_oid_cpy(&head->oid, &obj_id);
+
+	if (git_reference_type(ref) == GIT_REF_SYMBOLIC) {
+		head->symref_target = git__strdup(git_reference_symbolic_target(ref));
+		GITERR_CHECK_ALLOC(head->symref_target);
+	}
+	git_reference_free(ref);
+
+	if ((error = git_vector_insert(&t->refs, head)) < 0) {
+		free_head(head);
+		return error;
+	}
+
+	/* If it's not a tag, we don't need to try to peel it */
+	if (git__prefixcmp(name, GIT_REFS_TAGS_DIR))
+		return 0;
+
+	if ((error = git_object_lookup(&obj, t->repo, &head->oid, GIT_OBJ_ANY)) < 0)
+		return error;
+
+	head = NULL;
+
+	/* If it's not an annotated tag, or if we're mocking
+	 * git-receive-pack, just get out */
+	if (git_object_type(obj) != GIT_OBJ_TAG ||
+		t->direction != GIT_DIRECTION_FETCH) {
+		git_object_free(obj);
+		return 0;
+	}
+
+	/* And if it's a tag, peel it, and add it to the list */
+	head = git__calloc(1, sizeof(git_remote_head));
+	GITERR_CHECK_ALLOC(head);
+
+	if (git_buf_join(&buf, 0, name, peeled) < 0) {
+		free_head(head);
+		return -1;
+	}
+	head->name = git_buf_detach(&buf);
+
+	if (!(error = git_tag_peel(&target, (git_tag *)obj))) {
+		git_oid_cpy(&head->oid, git_object_id(target));
+
+		if ((error = git_vector_insert(&t->refs, head)) < 0) {
+			free_head(head);
+		}
+	}
+
+	git_object_free(obj);
+	git_object_free(target);
+
+	return error;
+}
+
+static int store_refs(transport_local *t)
+{
+	size_t i;
+	git_remote_head *head;
+	git_strarray ref_names = {0};
+
+	assert(t);
+
+	if (git_reference_list(&ref_names, t->repo) < 0)
+		goto on_error;
+
+	/* Clear all heads we might have fetched in a previous connect */
+	git_vector_foreach(&t->refs, i, head) {
+		git__free(head->name);
+		git__free(head);
+	}
+
+	/* Clear the vector so we can reuse it */
+	git_vector_clear(&t->refs);
+
+	/* Sort the references first */
+	git__tsort((void **)ref_names.strings, ref_names.count, &git__strcmp_cb);
+
+	/* Add HEAD iff direction is fetch */
+	if (t->direction == GIT_DIRECTION_FETCH && add_ref(t, GIT_HEAD_FILE) < 0)
+		goto on_error;
+
+	for (i = 0; i < ref_names.count; ++i) {
+		if (add_ref(t, ref_names.strings[i]) < 0)
+			goto on_error;
+	}
+
+	t->have_refs = 1;
+	git_strarray_free(&ref_names);
+	return 0;
+
+on_error:
+	git_vector_free(&t->refs);
+	git_strarray_free(&ref_names);
+	return -1;
+}
+
+/*
+ * Try to open the url as a git directory. The direction doesn't
+ * matter in this case because we're calculating the heads ourselves.
+ */
+static int local_connect(
+	git_transport *transport,
+	const char *url,
+	git_cred_acquire_cb cred_acquire_cb,
+	void *cred_acquire_payload,
+	int direction, int flags)
+{
+	git_repository *repo;
+	int error;
+	transport_local *t = (transport_local *) transport;
+	const char *path;
+	git_buf buf = GIT_BUF_INIT;
+
+	GIT_UNUSED(cred_acquire_cb);
+	GIT_UNUSED(cred_acquire_payload);
+
+	if (t->connected)
+		return 0;
+
+	free_heads(&t->refs);
+
+	t->url = git__strdup(url);
+	GITERR_CHECK_ALLOC(t->url);
+	t->direction = direction;
+	t->flags = flags;
+
+	/* 'url' may be a url or path; convert to a path */
+	if ((error = git_path_from_url_or_path(&buf, url)) < 0) {
+		git_buf_free(&buf);
+		return error;
+	}
+	path = git_buf_cstr(&buf);
+
+	error = git_repository_open(&repo, path);
+
+	git_buf_free(&buf);
+
+	if (error < 0)
+		return -1;
+
+	t->repo = repo;
+
+	if (store_refs(t) < 0)
+		return -1;
+
+	t->connected = 1;
+
+	return 0;
+}
+
+static int local_ls(const git_remote_head ***out, size_t *size, git_transport *transport)
+{
+	transport_local *t = (transport_local *)transport;
+
+	if (!t->have_refs) {
+		giterr_set(GITERR_NET, "The transport has not yet loaded the refs");
+		return -1;
+	}
+
+	*out = (const git_remote_head **)t->refs.contents;
+	*size = t->refs.length;
+
+	return 0;
+}
+
+static int local_negotiate_fetch(
+	git_transport *transport,
+	git_repository *repo,
+	const git_remote_head * const *refs,
+	size_t count)
+{
+	transport_local *t = (transport_local*)transport;
+	git_remote_head *rhead;
+	unsigned int i;
+
+	GIT_UNUSED(refs);
+	GIT_UNUSED(count);
+
+	/* Fill in the loids */
+	git_vector_foreach(&t->refs, i, rhead) {
+		git_object *obj;
+
+		int error = git_revparse_single(&obj, repo, rhead->name);
+		if (!error)
+			git_oid_cpy(&rhead->loid, git_object_id(obj));
+		else if (error != GIT_ENOTFOUND)
+			return error;
+		else
+			giterr_clear();
+		git_object_free(obj);
+	}
+
+	return 0;
+}
+
+static int local_push_update_remote_ref(
+	git_repository *remote_repo,
+	const char *lref,
+	const char *rref,
+	git_oid *loid,
+	git_oid *roid)
+{
+	int error;
+	git_reference *remote_ref = NULL;
+
+	/* check for lhs, if it's empty it means to delete */
+	if (lref[0] != '\0') {
+		/* Create or update a ref */
+		error = git_reference_create(NULL, remote_repo, rref, loid,
+					     !git_oid_iszero(roid), NULL);
+	} else {
+		/* Delete a ref */
+		if ((error = git_reference_lookup(&remote_ref, remote_repo, rref)) < 0) {
+			if (error == GIT_ENOTFOUND)
+				error = 0;
+			return error;
+		}
+
+		error = git_reference_delete(remote_ref);
+		git_reference_free(remote_ref);
+	}
+
+	return error;
+}
+
+static int transfer_to_push_transfer(const git_transfer_progress *stats, void *payload)
+{
+	const git_remote_callbacks *cbs = payload;
+
+	if (!cbs || !cbs->push_transfer_progress)
+		return 0;
+
+	return cbs->push_transfer_progress(stats->received_objects, stats->total_objects, stats->received_bytes,
+					   cbs->payload);
+}
+
+static int local_push(
+	git_transport *transport,
+	git_push *push,
+	const git_remote_callbacks *cbs)
+{
+	transport_local *t = (transport_local *)transport;
+	git_repository *remote_repo = NULL;
+	push_spec *spec;
+	char *url = NULL;
+	const char *path;
+	git_buf buf = GIT_BUF_INIT, odb_path = GIT_BUF_INIT;
+	int error;
+	size_t j;
+
+	GIT_UNUSED(cbs);
+
+	/* 'push->remote->url' may be a url or path; convert to a path */
+	if ((error = git_path_from_url_or_path(&buf, push->remote->url)) < 0) {
+		git_buf_free(&buf);
+		return error;
+	}
+	path = git_buf_cstr(&buf);
+
+	error = git_repository_open(&remote_repo, path);
+
+	git_buf_free(&buf);
+
+	if (error < 0)
+		return error;
+
+	/* We don't currently support pushing locally to non-bare repos. Proper
+	   non-bare repo push support would require checking configs to see if
+	   we should override the default 'don't let this happen' behavior.
+
+	   Note that this is only an issue when pushing to the current branch,
+	   but we forbid all pushes just in case */
+	if (!remote_repo->is_bare) {
+		error = GIT_EBAREREPO;
+		giterr_set(GITERR_INVALID, "Local push doesn't (yet) support pushing to non-bare repos.");
+		goto on_error;
+	}
+
+	if ((error = git_buf_joinpath(&odb_path, git_repository_path(remote_repo), "objects/pack")) < 0)
+		goto on_error;
+
+	error = git_packbuilder_write(push->pb, odb_path.ptr, 0, transfer_to_push_transfer, (void *) cbs);
+	git_buf_free(&odb_path);
+
+	if (error < 0)
+		goto on_error;
+
+	push->unpack_ok = 1;
+
+	git_vector_foreach(&push->specs, j, spec) {
+		push_status *status;
+		const git_error *last;
+		char *ref = spec->refspec.dst;
+
+		status = git__calloc(1, sizeof(push_status));
+		if (!status)
+			goto on_error;
+
+		status->ref = git__strdup(ref);
+		if (!status->ref) {
+			git_push_status_free(status);
+			goto on_error;
+		}
+
+		error = local_push_update_remote_ref(remote_repo, spec->refspec.src, spec->refspec.dst,
+			&spec->loid, &spec->roid);
+
+		switch (error) {
+			case GIT_OK:
+				break;
+			case GIT_EINVALIDSPEC:
+				status->msg = git__strdup("funny refname");
+				break;
+			case GIT_ENOTFOUND:
+				status->msg = git__strdup("Remote branch not found to delete");
+				break;
+			default:
+				last = giterr_last();
+
+				if (last && last->message)
+					status->msg = git__strdup(last->message);
+				else
+					status->msg = git__strdup("Unspecified error encountered");
+				break;
+		}
+
+		/* failed to allocate memory for a status message */
+		if (error < 0 && !status->msg) {
+			git_push_status_free(status);
+			goto on_error;
+		}
+
+		/* failed to insert the ref update status */
+		if ((error = git_vector_insert(&push->status, status)) < 0) {
+			git_push_status_free(status);
+			goto on_error;
+		}
+	}
+
+	if (push->specs.length) {
+		int flags = t->flags;
+		url = git__strdup(t->url);
+
+		if (!url || t->parent.close(&t->parent) < 0 ||
+			t->parent.connect(&t->parent, url,
+			NULL, NULL, GIT_DIRECTION_PUSH, flags))
+			goto on_error;
+	}
+
+	error = 0;
+
+on_error:
+	git_repository_free(remote_repo);
+	git__free(url);
+
+	return error;
+}
+
+typedef struct foreach_data {
+	git_transfer_progress *stats;
+	git_transfer_progress_cb progress_cb;
+	void *progress_payload;
+	git_odb_writepack *writepack;
+} foreach_data;
+
+static int foreach_cb(void *buf, size_t len, void *payload)
+{
+	foreach_data *data = (foreach_data*)payload;
+
+	data->stats->received_bytes += len;
+	return data->writepack->append(data->writepack, buf, len, data->stats);
+}
+
+static const char *counting_objects_fmt = "Counting objects %d\r";
+static const char *compressing_objects_fmt = "Compressing objects: %.0f%% (%d/%d)";
+
+static int local_counting(int stage, unsigned int current, unsigned int total, void *payload)
+{
+	git_buf progress_info = GIT_BUF_INIT;
+	transport_local *t = payload;
+	int error;
+
+	if (!t->progress_cb)
+		return 0;
+
+	if (stage == GIT_PACKBUILDER_ADDING_OBJECTS) {
+		git_buf_printf(&progress_info, counting_objects_fmt, current);
+	} else if (stage == GIT_PACKBUILDER_DELTAFICATION) {
+		float perc = (((float) current) / total) * 100;
+		git_buf_printf(&progress_info, compressing_objects_fmt, perc, current, total);
+		if (current == total)
+			git_buf_printf(&progress_info, ", done\n");
+		else
+			git_buf_putc(&progress_info, '\r');
+
+	}
+
+	if (git_buf_oom(&progress_info))
+		return -1;
+
+	error = t->progress_cb(git_buf_cstr(&progress_info), git_buf_len(&progress_info), t->message_cb_payload);
+	git_buf_free(&progress_info);
+
+	return error;
+}
+
+static int local_download_pack(
+		git_transport *transport,
+		git_repository *repo,
+		git_transfer_progress *stats,
+		git_transfer_progress_cb progress_cb,
+		void *progress_payload)
+{
+	transport_local *t = (transport_local*)transport;
+	git_revwalk *walk = NULL;
+	git_remote_head *rhead;
+	unsigned int i;
+	int error = -1;
+	git_packbuilder *pack = NULL;
+	git_odb_writepack *writepack = NULL;
+	git_odb *odb = NULL;
+	git_buf progress_info = GIT_BUF_INIT;
+
+	if ((error = git_revwalk_new(&walk, t->repo)) < 0)
+		goto cleanup;
+	git_revwalk_sorting(walk, GIT_SORT_TIME);
+
+	if ((error = git_packbuilder_new(&pack, t->repo)) < 0)
+		goto cleanup;
+
+	git_packbuilder_set_callbacks(pack, local_counting, t);
+
+	stats->total_objects = 0;
+	stats->indexed_objects = 0;
+	stats->received_objects = 0;
+	stats->received_bytes = 0;
+
+	git_vector_foreach(&t->refs, i, rhead) {
+		git_object *obj;
+		if ((error = git_object_lookup(&obj, t->repo, &rhead->oid, GIT_OBJ_ANY)) < 0)
+			goto cleanup;
+
+		if (git_object_type(obj) == GIT_OBJ_COMMIT) {
+			/* Revwalker includes only wanted commits */
+			error = git_revwalk_push(walk, &rhead->oid);
+			if (!error && !git_oid_iszero(&rhead->loid)) {
+				error = git_revwalk_hide(walk, &rhead->loid);
+				if (error == GIT_ENOTFOUND)
+					error = 0;
+			}
+		} else {
+			/* Tag or some other wanted object. Add it on its own */
+			error = git_packbuilder_insert_recur(pack, &rhead->oid, rhead->name);
+		}
+		git_object_free(obj);
+		if (error < 0)
+			goto cleanup;
+	}
+
+	if ((error = git_packbuilder_insert_walk(pack, walk)))
+		goto cleanup;
+
+	if ((error = git_buf_printf(&progress_info, counting_objects_fmt, git_packbuilder_object_count(pack))) < 0)
+		goto cleanup;
+
+	if (t->progress_cb &&
+	    (error = t->progress_cb(git_buf_cstr(&progress_info), git_buf_len(&progress_info), t->message_cb_payload)) < 0)
+		goto cleanup;
+
+	/* Walk the objects, building a packfile */
+	if ((error = git_repository_odb__weakptr(&odb, repo)) < 0)
+		goto cleanup;
+
+	/* One last one with the newline */
+	git_buf_clear(&progress_info);
+	git_buf_printf(&progress_info, counting_objects_fmt, git_packbuilder_object_count(pack));
+	if ((error = git_buf_putc(&progress_info, '\n')) < 0)
+		goto cleanup;
+
+	if (t->progress_cb &&
+	    (error = t->progress_cb(git_buf_cstr(&progress_info), git_buf_len(&progress_info), t->message_cb_payload)) < 0)
+		goto cleanup;
+
+	if ((error = git_odb_write_pack(&writepack, odb, progress_cb, progress_payload)) != 0)
+		goto cleanup;
+
+	/* Write the data to the ODB */
+	{
+		foreach_data data = {0};
+		data.stats = stats;
+		data.progress_cb = progress_cb;
+		data.progress_payload = progress_payload;
+		data.writepack = writepack;
+
+		/* autodetect */
+		git_packbuilder_set_threads(pack, 0);
+
+		if ((error = git_packbuilder_foreach(pack, foreach_cb, &data)) != 0)
+			goto cleanup;
+	}
+
+	error = writepack->commit(writepack, stats);
+
+cleanup:
+	if (writepack) writepack->free(writepack);
+	git_buf_free(&progress_info);
+	git_packbuilder_free(pack);
+	git_revwalk_free(walk);
+	return error;
+}
+
+static int local_set_callbacks(
+	git_transport *transport,
+	git_transport_message_cb progress_cb,
+	git_transport_message_cb error_cb,
+	git_transport_certificate_check_cb certificate_check_cb,
+	void *message_cb_payload)
+{
+	transport_local *t = (transport_local *)transport;
+
+	GIT_UNUSED(certificate_check_cb);
+
+	t->progress_cb = progress_cb;
+	t->error_cb = error_cb;
+	t->message_cb_payload = message_cb_payload;
+
+	return 0;
+}
+
+static int local_is_connected(git_transport *transport)
+{
+	transport_local *t = (transport_local *)transport;
+
+	return t->connected;
+}
+
+static int local_read_flags(git_transport *transport, int *flags)
+{
+	transport_local *t = (transport_local *)transport;
+
+	*flags = t->flags;
+
+	return 0;
+}
+
+static void local_cancel(git_transport *transport)
+{
+	transport_local *t = (transport_local *)transport;
+
+	git_atomic_set(&t->cancelled, 1);
+}
+
+static int local_close(git_transport *transport)
+{
+	transport_local *t = (transport_local *)transport;
+
+	t->connected = 0;
+
+	if (t->repo) {
+		git_repository_free(t->repo);
+		t->repo = NULL;
+	}
+
+	if (t->url) {
+		git__free(t->url);
+		t->url = NULL;
+	}
+
+	return 0;
+}
+
+static void local_free(git_transport *transport)
+{
+	transport_local *t = (transport_local *)transport;
+
+	free_heads(&t->refs);
+
+	/* Close the transport, if it's still open. */
+	local_close(transport);
+
+	/* Free the transport */
+	git__free(t);
+}
+
+/**************
+ * Public API *
+ **************/
+
+int git_transport_local(git_transport **out, git_remote *owner, void *param)
+{
+	int error;
+	transport_local *t;
+
+	GIT_UNUSED(param);
+
+	t = git__calloc(1, sizeof(transport_local));
+	GITERR_CHECK_ALLOC(t);
+
+	t->parent.version = GIT_TRANSPORT_VERSION;
+	t->parent.set_callbacks = local_set_callbacks;
+	t->parent.connect = local_connect;
+	t->parent.negotiate_fetch = local_negotiate_fetch;
+	t->parent.download_pack = local_download_pack;
+	t->parent.push = local_push;
+	t->parent.close = local_close;
+	t->parent.free = local_free;
+	t->parent.ls = local_ls;
+	t->parent.is_connected = local_is_connected;
+	t->parent.read_flags = local_read_flags;
+	t->parent.cancel = local_cancel;
+
+	if ((error = git_vector_init(&t->refs, 0, NULL)) < 0) {
+		git__free(t);
+		return error;
+	}
+
+	t->owner = owner;
+
+	*out = (git_transport *) t;
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/smart.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/smart.c
new file mode 100755
index 0000000..85a49e5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/smart.c
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "git2.h"
+#include "smart.h"
+#include "refs.h"
+#include "refspec.h"
+
+static int git_smart__recv_cb(gitno_buffer *buf)
+{
+	transport_smart *t = (transport_smart *) buf->cb_data;
+	size_t old_len, bytes_read;
+	int error;
+
+	assert(t->current_stream);
+
+	old_len = buf->offset;
+
+	if ((error = t->current_stream->read(t->current_stream, buf->data + buf->offset, buf->len - buf->offset, &bytes_read)) < 0)
+		return error;
+
+	buf->offset += bytes_read;
+
+	if (t->packetsize_cb && !t->cancelled.val) {
+		error = t->packetsize_cb(bytes_read, t->packetsize_payload);
+		if (error) {
+			git_atomic_set(&t->cancelled, 1);
+			return GIT_EUSER;
+		}
+	}
+
+	return (int)(buf->offset - old_len);
+}
+
+GIT_INLINE(int) git_smart__reset_stream(transport_smart *t, bool close_subtransport)
+{
+	if (t->current_stream) {
+		t->current_stream->free(t->current_stream);
+		t->current_stream = NULL;
+	}
+
+	if (close_subtransport &&
+		t->wrapped->close(t->wrapped) < 0)
+		return -1;
+
+	return 0;
+}
+
+static int git_smart__set_callbacks(
+	git_transport *transport,
+	git_transport_message_cb progress_cb,
+	git_transport_message_cb error_cb,
+	git_transport_certificate_check_cb certificate_check_cb,
+	void *message_cb_payload)
+{
+	transport_smart *t = (transport_smart *)transport;
+
+	t->progress_cb = progress_cb;
+	t->error_cb = error_cb;
+	t->certificate_check_cb = certificate_check_cb;
+	t->message_cb_payload = message_cb_payload;
+
+	return 0;
+}
+
+int git_smart__update_heads(transport_smart *t, git_vector *symrefs)
+{
+	size_t i;
+	git_pkt *pkt;
+
+	git_vector_clear(&t->heads);
+	git_vector_foreach(&t->refs, i, pkt) {
+		git_pkt_ref *ref = (git_pkt_ref *) pkt;
+		if (pkt->type != GIT_PKT_REF)
+			continue;
+
+		if (symrefs) {
+			git_refspec *spec;
+			git_buf buf = GIT_BUF_INIT;
+			size_t j;
+			int error = 0;
+
+			git_vector_foreach(symrefs, j, spec) {
+				git_buf_clear(&buf);
+				if (git_refspec_src_matches(spec, ref->head.name) &&
+				    !(error = git_refspec_transform(&buf, spec, ref->head.name)))
+					ref->head.symref_target = git_buf_detach(&buf);
+			}
+
+			git_buf_free(&buf);
+
+			if (error < 0)
+				return error;
+		}
+
+		if (git_vector_insert(&t->heads, &ref->head) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
+static void free_symrefs(git_vector *symrefs)
+{
+	git_refspec *spec;
+	size_t i;
+
+	git_vector_foreach(symrefs, i, spec) {
+		git_refspec__free(spec);
+		git__free(spec);
+	}
+
+	git_vector_free(symrefs);
+}
+
+static int git_smart__connect(
+	git_transport *transport,
+	const char *url,
+	git_cred_acquire_cb cred_acquire_cb,
+	void *cred_acquire_payload,
+	int direction,
+	int flags)
+{
+	transport_smart *t = (transport_smart *)transport;
+	git_smart_subtransport_stream *stream;
+	int error;
+	git_pkt *pkt;
+	git_pkt_ref *first;
+	git_vector symrefs;
+	git_smart_service_t service;
+
+	if (git_smart__reset_stream(t, true) < 0)
+		return -1;
+
+	t->url = git__strdup(url);
+	GITERR_CHECK_ALLOC(t->url);
+
+	t->direction = direction;
+	t->flags = flags;
+	t->cred_acquire_cb = cred_acquire_cb;
+	t->cred_acquire_payload = cred_acquire_payload;
+
+	if (GIT_DIRECTION_FETCH == t->direction)
+		service = GIT_SERVICE_UPLOADPACK_LS;
+	else if (GIT_DIRECTION_PUSH == t->direction)
+		service = GIT_SERVICE_RECEIVEPACK_LS;
+	else {
+		giterr_set(GITERR_NET, "Invalid direction");
+		return -1;
+	}
+
+	if ((error = t->wrapped->action(&stream, t->wrapped, t->url, service)) < 0)
+		return error;
+
+	/* Save off the current stream (i.e. socket) that we are working with */
+	t->current_stream = stream;
+
+	gitno_buffer_setup_callback(&t->buffer, t->buffer_data, sizeof(t->buffer_data), git_smart__recv_cb, t);
+
+	/* 2 flushes for RPC; 1 for stateful */
+	if ((error = git_smart__store_refs(t, t->rpc ? 2 : 1)) < 0)
+		return error;
+
+	/* Strip the comment packet for RPC */
+	if (t->rpc) {
+		pkt = (git_pkt *)git_vector_get(&t->refs, 0);
+
+		if (!pkt || GIT_PKT_COMMENT != pkt->type) {
+			giterr_set(GITERR_NET, "Invalid response");
+			return -1;
+		} else {
+			/* Remove the comment pkt from the list */
+			git_vector_remove(&t->refs, 0);
+			git__free(pkt);
+		}
+	}
+
+	/* We now have loaded the refs. */
+	t->have_refs = 1;
+
+	first = (git_pkt_ref *)git_vector_get(&t->refs, 0);
+
+	if ((error = git_vector_init(&symrefs, 1, NULL)) < 0)
+		return error;
+
+	/* Detect capabilities */
+	if (git_smart__detect_caps(first, &t->caps, &symrefs) < 0)
+		return -1;
+
+	/* If the only ref in the list is capabilities^{} with OID_ZERO, remove it */
+	if (1 == t->refs.length && !strcmp(first->head.name, "capabilities^{}") &&
+		git_oid_iszero(&first->head.oid)) {
+		git_vector_clear(&t->refs);
+		git_pkt_free((git_pkt *)first);
+	}
+
+	/* Keep a list of heads for _ls */
+	git_smart__update_heads(t, &symrefs);
+
+	free_symrefs(&symrefs);
+
+	if (t->rpc && git_smart__reset_stream(t, false) < 0)
+		return -1;
+
+	/* We're now logically connected. */
+	t->connected = 1;
+
+	return 0;
+}
+
+static int git_smart__ls(const git_remote_head ***out, size_t *size, git_transport *transport)
+{
+	transport_smart *t = (transport_smart *)transport;
+
+	if (!t->have_refs) {
+		giterr_set(GITERR_NET, "The transport has not yet loaded the refs");
+		return -1;
+	}
+
+	*out = (const git_remote_head **) t->heads.contents;
+	*size = t->heads.length;
+
+	return 0;
+}
+
+int git_smart__negotiation_step(git_transport *transport, void *data, size_t len)
+{
+	transport_smart *t = (transport_smart *)transport;
+	git_smart_subtransport_stream *stream;
+	int error;
+
+	if (t->rpc && git_smart__reset_stream(t, false) < 0)
+		return -1;
+
+	if (GIT_DIRECTION_FETCH != t->direction) {
+		giterr_set(GITERR_NET, "This operation is only valid for fetch");
+		return -1;
+	}
+
+	if ((error = t->wrapped->action(&stream, t->wrapped, t->url, GIT_SERVICE_UPLOADPACK)) < 0)
+		return error;
+
+	/* If this is a stateful implementation, the stream we get back should be the same */
+	assert(t->rpc || t->current_stream == stream);
+
+	/* Save off the current stream (i.e. socket) that we are working with */
+	t->current_stream = stream;
+
+	if ((error = stream->write(stream, (const char *)data, len)) < 0)
+		return error;
+
+	gitno_buffer_setup_callback(&t->buffer, t->buffer_data, sizeof(t->buffer_data), git_smart__recv_cb, t);
+
+	return 0;
+}
+
+int git_smart__get_push_stream(transport_smart *t, git_smart_subtransport_stream **stream)
+{
+	int error;
+
+	if (t->rpc && git_smart__reset_stream(t, false) < 0)
+		return -1;
+
+	if (GIT_DIRECTION_PUSH != t->direction) {
+		giterr_set(GITERR_NET, "This operation is only valid for push");
+		return -1;
+	}
+
+	if ((error = t->wrapped->action(stream, t->wrapped, t->url, GIT_SERVICE_RECEIVEPACK)) < 0)
+		return error;
+
+	/* If this is a stateful implementation, the stream we get back should be the same */
+	assert(t->rpc || t->current_stream == *stream);
+
+	/* Save off the current stream (i.e. socket) that we are working with */
+	t->current_stream = *stream;
+
+	gitno_buffer_setup_callback(&t->buffer, t->buffer_data, sizeof(t->buffer_data), git_smart__recv_cb, t);
+
+	return 0;
+}
+
+static void git_smart__cancel(git_transport *transport)
+{
+	transport_smart *t = (transport_smart *)transport;
+
+	git_atomic_set(&t->cancelled, 1);
+}
+
+static int git_smart__is_connected(git_transport *transport)
+{
+	transport_smart *t = (transport_smart *)transport;
+
+	return t->connected;
+}
+
+static int git_smart__read_flags(git_transport *transport, int *flags)
+{
+	transport_smart *t = (transport_smart *)transport;
+
+	*flags = t->flags;
+
+	return 0;
+}
+
+static int git_smart__close(git_transport *transport)
+{
+	transport_smart *t = (transport_smart *)transport;
+	git_vector *common = &t->common;
+	unsigned int i;
+	git_pkt *p;
+	int ret;
+	git_smart_subtransport_stream *stream;
+	const char flush[] = "0000";
+
+	/*
+	 * If we're still connected at this point and not using RPC,
+	 * we should say goodbye by sending a flush, or git-daemon
+	 * will complain that we disconnected unexpectedly.
+	 */
+	if (t->connected && !t->rpc &&
+	    !t->wrapped->action(&stream, t->wrapped, t->url, GIT_SERVICE_UPLOADPACK)) {
+		t->current_stream->write(t->current_stream, flush, 4);
+	}
+
+	ret = git_smart__reset_stream(t, true);
+
+	git_vector_foreach(common, i, p)
+		git_pkt_free(p);
+
+	git_vector_free(common);
+
+	if (t->url) {
+		git__free(t->url);
+		t->url = NULL;
+	}
+
+	t->connected = 0;
+
+	return ret;
+}
+
+static void git_smart__free(git_transport *transport)
+{
+	transport_smart *t = (transport_smart *)transport;
+	git_vector *refs = &t->refs;
+	unsigned int i;
+	git_pkt *p;
+
+	/* Make sure that the current stream is closed, if we have one. */
+	git_smart__close(transport);
+
+	/* Free the subtransport */
+	t->wrapped->free(t->wrapped);
+
+	git_vector_free(&t->heads);
+	git_vector_foreach(refs, i, p)
+		git_pkt_free(p);
+
+	git_vector_free(refs);
+
+	git__free(t);
+}
+
+static int ref_name_cmp(const void *a, const void *b)
+{
+	const git_pkt_ref *ref_a = a, *ref_b = b;
+
+	return strcmp(ref_a->head.name, ref_b->head.name);
+}
+
+int git_transport_smart(git_transport **out, git_remote *owner, void *param)
+{
+	transport_smart *t;
+	git_smart_subtransport_definition *definition = (git_smart_subtransport_definition *)param;
+
+	if (!param)
+		return -1;
+
+	t = git__calloc(1, sizeof(transport_smart));
+	GITERR_CHECK_ALLOC(t);
+
+	t->parent.version = GIT_TRANSPORT_VERSION;
+	t->parent.set_callbacks = git_smart__set_callbacks;
+	t->parent.connect = git_smart__connect;
+	t->parent.close = git_smart__close;
+	t->parent.free = git_smart__free;
+	t->parent.negotiate_fetch = git_smart__negotiate_fetch;
+	t->parent.download_pack = git_smart__download_pack;
+	t->parent.push = git_smart__push;
+	t->parent.ls = git_smart__ls;
+	t->parent.is_connected = git_smart__is_connected;
+	t->parent.read_flags = git_smart__read_flags;
+	t->parent.cancel = git_smart__cancel;
+
+	t->owner = owner;
+	t->rpc = definition->rpc;
+
+	if (git_vector_init(&t->refs, 16, ref_name_cmp) < 0) {
+		git__free(t);
+		return -1;
+	}
+
+	if (git_vector_init(&t->heads, 16, ref_name_cmp) < 0) {
+		git__free(t);
+		return -1;
+	}
+
+	if (definition->callback(&t->wrapped, &t->parent, definition->param) < 0) {
+		git__free(t);
+		return -1;
+	}
+
+	*out = (git_transport *) t;
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/smart.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/smart.h
new file mode 100755
index 0000000..4c728c7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/smart.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "git2.h"
+#include "vector.h"
+#include "netops.h"
+#include "buffer.h"
+#include "push.h"
+#include "git2/sys/transport.h"
+
+#define GIT_SIDE_BAND_DATA     1
+#define GIT_SIDE_BAND_PROGRESS 2
+#define GIT_SIDE_BAND_ERROR    3
+
+#define GIT_CAP_OFS_DELTA "ofs-delta"
+#define GIT_CAP_MULTI_ACK "multi_ack"
+#define GIT_CAP_MULTI_ACK_DETAILED "multi_ack_detailed"
+#define GIT_CAP_SIDE_BAND "side-band"
+#define GIT_CAP_SIDE_BAND_64K "side-band-64k"
+#define GIT_CAP_INCLUDE_TAG "include-tag"
+#define GIT_CAP_DELETE_REFS "delete-refs"
+#define GIT_CAP_REPORT_STATUS "report-status"
+#define GIT_CAP_THIN_PACK "thin-pack"
+#define GIT_CAP_SYMREF "symref"
+
+enum git_pkt_type {
+	GIT_PKT_CMD,
+	GIT_PKT_FLUSH,
+	GIT_PKT_REF,
+	GIT_PKT_HAVE,
+	GIT_PKT_ACK,
+	GIT_PKT_NAK,
+	GIT_PKT_PACK,
+	GIT_PKT_COMMENT,
+	GIT_PKT_ERR,
+	GIT_PKT_DATA,
+	GIT_PKT_PROGRESS,
+	GIT_PKT_OK,
+	GIT_PKT_NG,
+	GIT_PKT_UNPACK,
+};
+
+/* Used for multi_ack and mutli_ack_detailed */
+enum git_ack_status {
+	GIT_ACK_NONE,
+	GIT_ACK_CONTINUE,
+	GIT_ACK_COMMON,
+	GIT_ACK_READY
+};
+
+/* This would be a flush pkt */
+typedef struct {
+	enum git_pkt_type type;
+} git_pkt;
+
+struct git_pkt_cmd {
+	enum git_pkt_type type;
+	char *cmd;
+	char *path;
+	char *host;
+};
+
+/* This is a pkt-line with some info in it */
+typedef struct {
+	enum git_pkt_type type;
+	git_remote_head head;
+	char *capabilities;
+} git_pkt_ref;
+
+/* Useful later */
+typedef struct {
+	enum git_pkt_type type;
+	git_oid oid;
+	enum git_ack_status status;
+} git_pkt_ack;
+
+typedef struct {
+	enum git_pkt_type type;
+	char comment[GIT_FLEX_ARRAY];
+} git_pkt_comment;
+
+typedef struct {
+	enum git_pkt_type type;
+	int len;
+	char data[GIT_FLEX_ARRAY];
+} git_pkt_data;
+
+typedef git_pkt_data git_pkt_progress;
+
+typedef struct {
+	enum git_pkt_type type;
+	int len;
+	char error[GIT_FLEX_ARRAY];
+} git_pkt_err;
+
+typedef struct {
+	enum git_pkt_type type;
+	char *ref;
+} git_pkt_ok;
+
+typedef struct {
+	enum git_pkt_type type;
+	char *ref;
+	char *msg;
+} git_pkt_ng;
+
+typedef struct {
+	enum git_pkt_type type;
+	int unpack_ok;
+} git_pkt_unpack;
+
+typedef struct transport_smart_caps {
+	int common:1,
+		ofs_delta:1,
+		multi_ack: 1,
+		multi_ack_detailed: 1,
+		side_band:1,
+		side_band_64k:1,
+		include_tag:1,
+		delete_refs:1,
+		report_status:1,
+		thin_pack:1;
+} transport_smart_caps;
+
+typedef int (*packetsize_cb)(size_t received, void *payload);
+
+typedef struct {
+	git_transport parent;
+	git_remote *owner;
+	char *url;
+	git_cred_acquire_cb cred_acquire_cb;
+	void *cred_acquire_payload;
+	int direction;
+	int flags;
+	git_transport_message_cb progress_cb;
+	git_transport_message_cb error_cb;
+	git_transport_certificate_check_cb certificate_check_cb;
+	void *message_cb_payload;
+	git_smart_subtransport *wrapped;
+	git_smart_subtransport_stream *current_stream;
+	transport_smart_caps caps;
+	git_vector refs;
+	git_vector heads;
+	git_vector common;
+	git_atomic cancelled;
+	packetsize_cb packetsize_cb;
+	void *packetsize_payload;
+	unsigned rpc : 1,
+		have_refs : 1,
+		connected : 1;
+	gitno_buffer buffer;
+	char buffer_data[65536];
+} transport_smart;
+
+/* smart_protocol.c */
+int git_smart__store_refs(transport_smart *t, int flushes);
+int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vector *symrefs);
+int git_smart__push(git_transport *transport, git_push *push, const git_remote_callbacks *cbs);
+
+int git_smart__negotiate_fetch(
+	git_transport *transport,
+	git_repository *repo,
+	const git_remote_head * const *refs,
+	size_t count);
+
+int git_smart__download_pack(
+	git_transport *transport,
+	git_repository *repo,
+	git_transfer_progress *stats,
+	git_transfer_progress_cb progress_cb,
+	void *progress_payload);
+
+/* smart.c */
+int git_smart__negotiation_step(git_transport *transport, void *data, size_t len);
+int git_smart__get_push_stream(transport_smart *t, git_smart_subtransport_stream **out);
+
+int git_smart__update_heads(transport_smart *t, git_vector *symrefs);
+
+/* smart_pkt.c */
+int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_t len);
+int git_pkt_buffer_flush(git_buf *buf);
+int git_pkt_send_flush(GIT_SOCKET s);
+int git_pkt_buffer_done(git_buf *buf);
+int git_pkt_buffer_wants(const git_remote_head * const *refs, size_t count, transport_smart_caps *caps, git_buf *buf);
+int git_pkt_buffer_have(git_oid *oid, git_buf *buf);
+void git_pkt_free(git_pkt *pkt);
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/smart_pkt.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/smart_pkt.c
new file mode 100755
index 0000000..9ccbd80
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/smart_pkt.c
@@ -0,0 +1,596 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+
+#include "git2/types.h"
+#include "git2/errors.h"
+#include "git2/refs.h"
+#include "git2/revwalk.h"
+
+#include "smart.h"
+#include "util.h"
+#include "netops.h"
+#include "posix.h"
+#include "buffer.h"
+
+#include <ctype.h>
+
+#define PKT_LEN_SIZE 4
+static const char pkt_done_str[] = "0009done\n";
+static const char pkt_flush_str[] = "0000";
+static const char pkt_have_prefix[] = "0032have ";
+static const char pkt_want_prefix[] = "0032want ";
+
+static int flush_pkt(git_pkt **out)
+{
+	git_pkt *pkt;
+
+	pkt = git__malloc(sizeof(git_pkt));
+	GITERR_CHECK_ALLOC(pkt);
+
+	pkt->type = GIT_PKT_FLUSH;
+	*out = pkt;
+
+	return 0;
+}
+
+/* the rest of the line will be useful for multi_ack and multi_ack_detailed */
+static int ack_pkt(git_pkt **out, const char *line, size_t len)
+{
+	git_pkt_ack *pkt;
+	GIT_UNUSED(line);
+	GIT_UNUSED(len);
+
+	pkt = git__calloc(1, sizeof(git_pkt_ack));
+	GITERR_CHECK_ALLOC(pkt);
+
+	pkt->type = GIT_PKT_ACK;
+	line += 3;
+	len -= 3;
+
+	if (len >= GIT_OID_HEXSZ) {
+		git_oid_fromstr(&pkt->oid, line + 1);
+		line += GIT_OID_HEXSZ + 1;
+		len -= GIT_OID_HEXSZ + 1;
+	}
+
+	if (len >= 7) {
+		if (!git__prefixcmp(line + 1, "continue"))
+			pkt->status = GIT_ACK_CONTINUE;
+		if (!git__prefixcmp(line + 1, "common"))
+			pkt->status = GIT_ACK_COMMON;
+		if (!git__prefixcmp(line + 1, "ready"))
+			pkt->status = GIT_ACK_READY;
+	}
+
+	*out = (git_pkt *) pkt;
+
+	return 0;
+}
+
+static int nak_pkt(git_pkt **out)
+{
+	git_pkt *pkt;
+
+	pkt = git__malloc(sizeof(git_pkt));
+	GITERR_CHECK_ALLOC(pkt);
+
+	pkt->type = GIT_PKT_NAK;
+	*out = pkt;
+
+	return 0;
+}
+
+static int pack_pkt(git_pkt **out)
+{
+	git_pkt *pkt;
+
+	pkt = git__malloc(sizeof(git_pkt));
+	GITERR_CHECK_ALLOC(pkt);
+
+	pkt->type = GIT_PKT_PACK;
+	*out = pkt;
+
+	return 0;
+}
+
+static int comment_pkt(git_pkt **out, const char *line, size_t len)
+{
+	git_pkt_comment *pkt;
+	size_t alloclen;
+
+	GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(git_pkt_comment), len);
+	GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
+	pkt = git__malloc(alloclen);
+	GITERR_CHECK_ALLOC(pkt);
+
+	pkt->type = GIT_PKT_COMMENT;
+	memcpy(pkt->comment, line, len);
+	pkt->comment[len] = '\0';
+
+	*out = (git_pkt *) pkt;
+
+	return 0;
+}
+
+static int err_pkt(git_pkt **out, const char *line, size_t len)
+{
+	git_pkt_err *pkt;
+	size_t alloclen;
+
+	/* Remove "ERR " from the line */
+	line += 4;
+	len -= 4;
+
+	GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(git_pkt_progress), len);
+	GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
+	pkt = git__malloc(alloclen);
+	GITERR_CHECK_ALLOC(pkt);
+
+	pkt->type = GIT_PKT_ERR;
+	pkt->len = (int)len;
+	memcpy(pkt->error, line, len);
+	pkt->error[len] = '\0';
+
+	*out = (git_pkt *) pkt;
+
+	return 0;
+}
+
+static int data_pkt(git_pkt **out, const char *line, size_t len)
+{
+	git_pkt_data *pkt;
+	size_t alloclen;
+
+	line++;
+	len--;
+
+	GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(git_pkt_progress), len);
+	pkt = git__malloc(alloclen);
+	GITERR_CHECK_ALLOC(pkt);
+
+	pkt->type = GIT_PKT_DATA;
+	pkt->len = (int) len;
+	memcpy(pkt->data, line, len);
+
+	*out = (git_pkt *) pkt;
+
+	return 0;
+}
+
+static int sideband_progress_pkt(git_pkt **out, const char *line, size_t len)
+{
+	git_pkt_progress *pkt;
+	size_t alloclen;
+
+	line++;
+	len--;
+
+	GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(git_pkt_progress), len);
+	pkt = git__malloc(alloclen);
+	GITERR_CHECK_ALLOC(pkt);
+
+	pkt->type = GIT_PKT_PROGRESS;
+	pkt->len = (int) len;
+	memcpy(pkt->data, line, len);
+
+	*out = (git_pkt *) pkt;
+
+	return 0;
+}
+
+static int sideband_error_pkt(git_pkt **out, const char *line, size_t len)
+{
+	git_pkt_err *pkt;
+	size_t alloc_len;
+
+	line++;
+	len--;
+
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, sizeof(git_pkt_err), len);
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 1);
+	pkt = git__malloc(alloc_len);
+	GITERR_CHECK_ALLOC(pkt);
+
+	pkt->type = GIT_PKT_ERR;
+	pkt->len = (int)len;
+	memcpy(pkt->error, line, len);
+	pkt->error[len] = '\0';
+
+	*out = (git_pkt *)pkt;
+
+	return 0;
+}
+
+/*
+ * Parse an other-ref line.
+ */
+static int ref_pkt(git_pkt **out, const char *line, size_t len)
+{
+	int error;
+	git_pkt_ref *pkt;
+	size_t alloclen;
+
+	pkt = git__malloc(sizeof(git_pkt_ref));
+	GITERR_CHECK_ALLOC(pkt);
+
+	memset(pkt, 0x0, sizeof(git_pkt_ref));
+	pkt->type = GIT_PKT_REF;
+	if ((error = git_oid_fromstr(&pkt->head.oid, line)) < 0)
+		goto error_out;
+
+	/* Check for a bit of consistency */
+	if (line[GIT_OID_HEXSZ] != ' ') {
+		giterr_set(GITERR_NET, "Error parsing pkt-line");
+		error = -1;
+		goto error_out;
+	}
+
+	/* Jump from the name */
+	line += GIT_OID_HEXSZ + 1;
+	len -= (GIT_OID_HEXSZ + 1);
+
+	if (line[len - 1] == '\n')
+		--len;
+
+	GITERR_CHECK_ALLOC_ADD(&alloclen, len, 1);
+	pkt->head.name = git__malloc(alloclen);
+	GITERR_CHECK_ALLOC(pkt->head.name);
+
+	memcpy(pkt->head.name, line, len);
+	pkt->head.name[len] = '\0';
+
+	if (strlen(pkt->head.name) < len) {
+		pkt->capabilities = strchr(pkt->head.name, '\0') + 1;
+	}
+
+	*out = (git_pkt *)pkt;
+	return 0;
+
+error_out:
+	git__free(pkt);
+	return error;
+}
+
+static int ok_pkt(git_pkt **out, const char *line, size_t len)
+{
+	git_pkt_ok *pkt;
+	const char *ptr;
+	size_t alloc_len;
+
+	pkt = git__malloc(sizeof(*pkt));
+	GITERR_CHECK_ALLOC(pkt);
+
+	pkt->type = GIT_PKT_OK;
+
+	line += 3; /* skip "ok " */
+	if (!(ptr = strchr(line, '\n'))) {
+		giterr_set(GITERR_NET, "Invalid packet line");
+		return -1;
+	}
+	len = ptr - line;
+
+	GITERR_CHECK_ALLOC_ADD(&alloc_len, len, 1);
+	pkt->ref = git__malloc(alloc_len);
+	GITERR_CHECK_ALLOC(pkt->ref);
+
+	memcpy(pkt->ref, line, len);
+	pkt->ref[len] = '\0';
+
+	*out = (git_pkt *)pkt;
+	return 0;
+}
+
+static int ng_pkt(git_pkt **out, const char *line, size_t len)
+{
+	git_pkt_ng *pkt;
+	const char *ptr;
+	size_t alloclen;
+
+	pkt = git__malloc(sizeof(*pkt));
+	GITERR_CHECK_ALLOC(pkt);
+
+	pkt->type = GIT_PKT_NG;
+
+	line += 3; /* skip "ng " */
+	if (!(ptr = strchr(line, ' '))) {
+		giterr_set(GITERR_NET, "Invalid packet line");
+		return -1;
+	}
+	len = ptr - line;
+
+	GITERR_CHECK_ALLOC_ADD(&alloclen, len, 1);
+	pkt->ref = git__malloc(alloclen);
+	GITERR_CHECK_ALLOC(pkt->ref);
+
+	memcpy(pkt->ref, line, len);
+	pkt->ref[len] = '\0';
+
+	line = ptr + 1;
+	if (!(ptr = strchr(line, '\n'))) {
+		giterr_set(GITERR_NET, "Invalid packet line");
+		return -1;
+	}
+	len = ptr - line;
+
+	GITERR_CHECK_ALLOC_ADD(&alloclen, len, 1);
+	pkt->msg = git__malloc(alloclen);
+	GITERR_CHECK_ALLOC(pkt->msg);
+
+	memcpy(pkt->msg, line, len);
+	pkt->msg[len] = '\0';
+
+	*out = (git_pkt *)pkt;
+	return 0;
+}
+
+static int unpack_pkt(git_pkt **out, const char *line, size_t len)
+{
+	git_pkt_unpack *pkt;
+
+	GIT_UNUSED(len);
+
+	pkt = git__malloc(sizeof(*pkt));
+	GITERR_CHECK_ALLOC(pkt);
+
+	pkt->type = GIT_PKT_UNPACK;
+	if (!git__prefixcmp(line, "unpack ok"))
+		pkt->unpack_ok = 1;
+	else
+		pkt->unpack_ok = 0;
+
+	*out = (git_pkt *)pkt;
+	return 0;
+}
+
+static int32_t parse_len(const char *line)
+{
+	char num[PKT_LEN_SIZE + 1];
+	int i, error;
+	int32_t len;
+	const char *num_end;
+
+	memcpy(num, line, PKT_LEN_SIZE);
+	num[PKT_LEN_SIZE] = '\0';
+
+	for (i = 0; i < PKT_LEN_SIZE; ++i) {
+		if (!isxdigit(num[i])) {
+			giterr_set(GITERR_NET, "Found invalid hex digit in length");
+			return -1;
+		}
+	}
+
+	if ((error = git__strtol32(&len, num, &num_end, 16)) < 0)
+		return error;
+
+	return len;
+}
+
+/*
+ * As per the documentation, the syntax is:
+ *
+ * pkt-line	= data-pkt / flush-pkt
+ * data-pkt	= pkt-len pkt-payload
+ * pkt-len		= 4*(HEXDIG)
+ * pkt-payload = (pkt-len -4)*(OCTET)
+ * flush-pkt	= "0000"
+ *
+ * Which means that the first four bytes are the length of the line,
+ * in ASCII hexadecimal (including itself)
+ */
+
+int git_pkt_parse_line(
+	git_pkt **head, const char *line, const char **out, size_t bufflen)
+{
+	int ret;
+	int32_t len;
+
+	/* Not even enough for the length */
+	if (bufflen > 0 && bufflen < PKT_LEN_SIZE)
+		return GIT_EBUFS;
+
+	len = parse_len(line);
+	if (len < 0) {
+		/*
+		 * If we fail to parse the length, it might be because the
+		 * server is trying to send us the packfile already.
+		 */
+		if (bufflen >= 4 && !git__prefixcmp(line, "PACK")) {
+			giterr_clear();
+			*out = line;
+			return pack_pkt(head);
+		}
+
+		return (int)len;
+	}
+
+	/*
+	 * If we were given a buffer length, then make sure there is
+	 * enough in the buffer to satisfy this line
+	 */
+	if (bufflen > 0 && bufflen < (size_t)len)
+		return GIT_EBUFS;
+
+	line += PKT_LEN_SIZE;
+	/*
+	 * TODO: How do we deal with empty lines? Try again? with the next
+	 * line?
+	 */
+	if (len == PKT_LEN_SIZE) {
+		*out = line;
+		return 0;
+	}
+
+	if (len == 0) { /* Flush pkt */
+		*out = line;
+		return flush_pkt(head);
+	}
+
+	len -= PKT_LEN_SIZE; /* the encoded length includes its own size */
+
+	if (*line == GIT_SIDE_BAND_DATA)
+		ret = data_pkt(head, line, len);
+	else if (*line == GIT_SIDE_BAND_PROGRESS)
+		ret = sideband_progress_pkt(head, line, len);
+	else if (*line == GIT_SIDE_BAND_ERROR)
+		ret = sideband_error_pkt(head, line, len);
+	else if (!git__prefixcmp(line, "ACK"))
+		ret = ack_pkt(head, line, len);
+	else if (!git__prefixcmp(line, "NAK"))
+		ret = nak_pkt(head);
+	else if (!git__prefixcmp(line, "ERR "))
+		ret = err_pkt(head, line, len);
+	else if (*line == '#')
+		ret = comment_pkt(head, line, len);
+	else if (!git__prefixcmp(line, "ok"))
+		ret = ok_pkt(head, line, len);
+	else if (!git__prefixcmp(line, "ng"))
+		ret = ng_pkt(head, line, len);
+	else if (!git__prefixcmp(line, "unpack"))
+		ret = unpack_pkt(head, line, len);
+	else
+		ret = ref_pkt(head, line, len);
+
+	*out = line + len;
+
+	return ret;
+}
+
+void git_pkt_free(git_pkt *pkt)
+{
+	if (pkt->type == GIT_PKT_REF) {
+		git_pkt_ref *p = (git_pkt_ref *) pkt;
+		git__free(p->head.name);
+		git__free(p->head.symref_target);
+	}
+
+	if (pkt->type == GIT_PKT_OK) {
+		git_pkt_ok *p = (git_pkt_ok *) pkt;
+		git__free(p->ref);
+	}
+
+	if (pkt->type == GIT_PKT_NG) {
+		git_pkt_ng *p = (git_pkt_ng *) pkt;
+		git__free(p->ref);
+		git__free(p->msg);
+	}
+
+	git__free(pkt);
+}
+
+int git_pkt_buffer_flush(git_buf *buf)
+{
+	return git_buf_put(buf, pkt_flush_str, strlen(pkt_flush_str));
+}
+
+static int buffer_want_with_caps(const git_remote_head *head, transport_smart_caps *caps, git_buf *buf)
+{
+	git_buf str = GIT_BUF_INIT;
+	char oid[GIT_OID_HEXSZ +1] = {0};
+	size_t len;
+
+	/* Prefer multi_ack_detailed */
+	if (caps->multi_ack_detailed)
+		git_buf_puts(&str, GIT_CAP_MULTI_ACK_DETAILED " ");
+	else if (caps->multi_ack)
+		git_buf_puts(&str, GIT_CAP_MULTI_ACK " ");
+
+	/* Prefer side-band-64k if the server supports both */
+	if (caps->side_band_64k)
+		git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND_64K);
+	else if (caps->side_band)
+		git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND);
+
+	if (caps->include_tag)
+		git_buf_puts(&str, GIT_CAP_INCLUDE_TAG " ");
+
+	if (caps->thin_pack)
+		git_buf_puts(&str, GIT_CAP_THIN_PACK " ");
+
+	if (caps->ofs_delta)
+		git_buf_puts(&str, GIT_CAP_OFS_DELTA " ");
+
+	if (git_buf_oom(&str))
+		return -1;
+
+	len = strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ +
+		 git_buf_len(&str) + 1 /* LF */;
+
+	if (len > 0xffff) {
+		giterr_set(GITERR_NET,
+			"Tried to produce packet with invalid length %" PRIuZ, len);
+		return -1;
+	}
+
+	git_buf_grow_by(buf, len);
+	git_oid_fmt(oid, &head->oid);
+	git_buf_printf(buf,
+		"%04xwant %s %s\n", (unsigned int)len, oid, git_buf_cstr(&str));
+	git_buf_free(&str);
+
+	return git_buf_oom(buf);
+}
+
+/*
+ * All "want" packets have the same length and format, so what we do
+ * is overwrite the OID each time.
+ */
+
+int git_pkt_buffer_wants(
+	const git_remote_head * const *refs,
+	size_t count,
+	transport_smart_caps *caps,
+	git_buf *buf)
+{
+	size_t i = 0;
+	const git_remote_head *head;
+
+	if (caps->common) {
+		for (; i < count; ++i) {
+			head = refs[i];
+			if (!head->local)
+				break;
+		}
+
+		if (buffer_want_with_caps(refs[i], caps, buf) < 0)
+			return -1;
+
+		i++;
+	}
+
+	for (; i < count; ++i) {
+		char oid[GIT_OID_HEXSZ];
+
+		head = refs[i];
+		if (head->local)
+			continue;
+
+		git_oid_fmt(oid, &head->oid);
+		git_buf_put(buf, pkt_want_prefix, strlen(pkt_want_prefix));
+		git_buf_put(buf, oid, GIT_OID_HEXSZ);
+		git_buf_putc(buf, '\n');
+		if (git_buf_oom(buf))
+			return -1;
+	}
+
+	return git_pkt_buffer_flush(buf);
+}
+
+int git_pkt_buffer_have(git_oid *oid, git_buf *buf)
+{
+	char oidhex[GIT_OID_HEXSZ + 1];
+
+	memset(oidhex, 0x0, sizeof(oidhex));
+	git_oid_fmt(oidhex, oid);
+	return git_buf_printf(buf, "%s%s\n", pkt_have_prefix, oidhex);
+}
+
+int git_pkt_buffer_done(git_buf *buf)
+{
+	return git_buf_puts(buf, pkt_done_str);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/smart_protocol.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/smart_protocol.c
new file mode 100755
index 0000000..1d46d4b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/smart_protocol.c
@@ -0,0 +1,1035 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "git2.h"
+#include "git2/odb_backend.h"
+
+#include "smart.h"
+#include "refs.h"
+#include "repository.h"
+#include "push.h"
+#include "pack-objects.h"
+#include "remote.h"
+#include "util.h"
+
+#define NETWORK_XFER_THRESHOLD (100*1024)
+/* The minimal interval between progress updates (in seconds). */
+#define MIN_PROGRESS_UPDATE_INTERVAL 0.5
+
+int git_smart__store_refs(transport_smart *t, int flushes)
+{
+	gitno_buffer *buf = &t->buffer;
+	git_vector *refs = &t->refs;
+	int error, flush = 0, recvd;
+	const char *line_end = NULL;
+	git_pkt *pkt = NULL;
+	size_t i;
+
+	/* Clear existing refs in case git_remote_connect() is called again
+	 * after git_remote_disconnect().
+	 */
+	git_vector_foreach(refs, i, pkt) {
+		git_pkt_free(pkt);
+	}
+	git_vector_clear(refs);
+	pkt = NULL;
+
+	do {
+		if (buf->offset > 0)
+			error = git_pkt_parse_line(&pkt, buf->data, &line_end, buf->offset);
+		else
+			error = GIT_EBUFS;
+
+		if (error < 0 && error != GIT_EBUFS)
+			return error;
+
+		if (error == GIT_EBUFS) {
+			if ((recvd = gitno_recv(buf)) < 0)
+				return recvd;
+
+			if (recvd == 0 && !flush) {
+				giterr_set(GITERR_NET, "early EOF");
+				return GIT_EEOF;
+			}
+
+			continue;
+		}
+
+		gitno_consume(buf, line_end);
+		if (pkt->type == GIT_PKT_ERR) {
+			giterr_set(GITERR_NET, "Remote error: %s", ((git_pkt_err *)pkt)->error);
+			git__free(pkt);
+			return -1;
+		}
+
+		if (pkt->type != GIT_PKT_FLUSH && git_vector_insert(refs, pkt) < 0)
+			return -1;
+
+		if (pkt->type == GIT_PKT_FLUSH) {
+			flush++;
+			git_pkt_free(pkt);
+		}
+	} while (flush < flushes);
+
+	return flush;
+}
+
+static int append_symref(const char **out, git_vector *symrefs, const char *ptr)
+{
+	int error;
+	const char *end;
+	git_buf buf = GIT_BUF_INIT;
+	git_refspec *mapping = NULL;
+
+	ptr += strlen(GIT_CAP_SYMREF);
+	if (*ptr != '=')
+		goto on_invalid;
+
+	ptr++;
+	if (!(end = strchr(ptr, ' ')) &&
+	    !(end = strchr(ptr, '\0')))
+		goto on_invalid;
+
+	if ((error = git_buf_put(&buf, ptr, end - ptr)) < 0)
+		return error;
+
+	/* symref mapping has refspec format */
+	mapping = git__calloc(1, sizeof(git_refspec));
+	GITERR_CHECK_ALLOC(mapping);
+
+	error = git_refspec__parse(mapping, git_buf_cstr(&buf), true);
+	git_buf_free(&buf);
+
+	/* if the error isn't OOM, then it's a parse error; let's use a nicer message */
+	if (error < 0) {
+		if (giterr_last()->klass != GITERR_NOMEMORY)
+			goto on_invalid;
+
+		return error;
+	}
+
+	if ((error = git_vector_insert(symrefs, mapping)) < 0)
+		return error;
+
+	*out = end;
+	return 0;
+
+on_invalid:
+	giterr_set(GITERR_NET, "remote sent invalid symref");
+	git_refspec__free(mapping);
+	return -1;
+}
+
+int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vector *symrefs)
+{
+	const char *ptr;
+
+	/* No refs or capabilites, odd but not a problem */
+	if (pkt == NULL || pkt->capabilities == NULL)
+		return 0;
+
+	ptr = pkt->capabilities;
+	while (ptr != NULL && *ptr != '\0') {
+		if (*ptr == ' ')
+			ptr++;
+
+		if (!git__prefixcmp(ptr, GIT_CAP_OFS_DELTA)) {
+			caps->common = caps->ofs_delta = 1;
+			ptr += strlen(GIT_CAP_OFS_DELTA);
+			continue;
+		}
+
+		/* Keep multi_ack_detailed before multi_ack */
+		if (!git__prefixcmp(ptr, GIT_CAP_MULTI_ACK_DETAILED)) {
+			caps->common = caps->multi_ack_detailed = 1;
+			ptr += strlen(GIT_CAP_MULTI_ACK_DETAILED);
+			continue;
+		}
+
+		if (!git__prefixcmp(ptr, GIT_CAP_MULTI_ACK)) {
+			caps->common = caps->multi_ack = 1;
+			ptr += strlen(GIT_CAP_MULTI_ACK);
+			continue;
+		}
+
+		if (!git__prefixcmp(ptr, GIT_CAP_INCLUDE_TAG)) {
+			caps->common = caps->include_tag = 1;
+			ptr += strlen(GIT_CAP_INCLUDE_TAG);
+			continue;
+		}
+
+		/* Keep side-band check after side-band-64k */
+		if (!git__prefixcmp(ptr, GIT_CAP_SIDE_BAND_64K)) {
+			caps->common = caps->side_band_64k = 1;
+			ptr += strlen(GIT_CAP_SIDE_BAND_64K);
+			continue;
+		}
+
+		if (!git__prefixcmp(ptr, GIT_CAP_SIDE_BAND)) {
+			caps->common = caps->side_band = 1;
+			ptr += strlen(GIT_CAP_SIDE_BAND);
+			continue;
+		}
+
+		if (!git__prefixcmp(ptr, GIT_CAP_DELETE_REFS)) {
+			caps->common = caps->delete_refs = 1;
+			ptr += strlen(GIT_CAP_DELETE_REFS);
+			continue;
+		}
+
+		if (!git__prefixcmp(ptr, GIT_CAP_THIN_PACK)) {
+			caps->common = caps->thin_pack = 1;
+			ptr += strlen(GIT_CAP_THIN_PACK);
+			continue;
+		}
+
+		if (!git__prefixcmp(ptr, GIT_CAP_SYMREF)) {
+			int error;
+
+			if ((error = append_symref(&ptr, symrefs, ptr)) < 0)
+				return error;
+
+			continue;
+		}
+
+		/* We don't know this capability, so skip it */
+		ptr = strchr(ptr, ' ');
+	}
+
+	return 0;
+}
+
+static int recv_pkt(git_pkt **out, gitno_buffer *buf)
+{
+	const char *ptr = buf->data, *line_end = ptr;
+	git_pkt *pkt = NULL;
+	int pkt_type, error = 0, ret;
+
+	do {
+		if (buf->offset > 0)
+			error = git_pkt_parse_line(&pkt, ptr, &line_end, buf->offset);
+		else
+			error = GIT_EBUFS;
+
+		if (error == 0)
+			break; /* return the pkt */
+
+		if (error < 0 && error != GIT_EBUFS)
+			return error;
+
+		if ((ret = gitno_recv(buf)) < 0)
+			return ret;
+	} while (error);
+
+	gitno_consume(buf, line_end);
+	pkt_type = pkt->type;
+	if (out != NULL)
+		*out = pkt;
+	else
+		git__free(pkt);
+
+	return pkt_type;
+}
+
+static int store_common(transport_smart *t)
+{
+	git_pkt *pkt = NULL;
+	gitno_buffer *buf = &t->buffer;
+	int error;
+
+	do {
+		if ((error = recv_pkt(&pkt, buf)) < 0)
+			return error;
+
+		if (pkt->type == GIT_PKT_ACK) {
+			if (git_vector_insert(&t->common, pkt) < 0)
+				return -1;
+		} else {
+			git__free(pkt);
+			return 0;
+		}
+
+	} while (1);
+
+	return 0;
+}
+
+static int fetch_setup_walk(git_revwalk **out, git_repository *repo)
+{
+	git_revwalk *walk = NULL;
+	git_strarray refs;
+	unsigned int i;
+	git_reference *ref;
+	int error;
+
+	if ((error = git_reference_list(&refs, repo)) < 0)
+		return error;
+
+	if ((error = git_revwalk_new(&walk, repo)) < 0)
+		return error;
+
+	git_revwalk_sorting(walk, GIT_SORT_TIME);
+
+	for (i = 0; i < refs.count; ++i) {
+		/* No tags */
+		if (!git__prefixcmp(refs.strings[i], GIT_REFS_TAGS_DIR))
+			continue;
+
+		if ((error = git_reference_lookup(&ref, repo, refs.strings[i])) < 0)
+			goto on_error;
+
+		if (git_reference_type(ref) == GIT_REF_SYMBOLIC)
+			continue;
+
+		if ((error = git_revwalk_push(walk, git_reference_target(ref))) < 0)
+			goto on_error;
+
+		git_reference_free(ref);
+	}
+
+	git_strarray_free(&refs);
+	*out = walk;
+	return 0;
+
+on_error:
+	git_revwalk_free(walk);
+	git_reference_free(ref);
+	git_strarray_free(&refs);
+	return error;
+}
+
+static int wait_while_ack(gitno_buffer *buf)
+{
+	int error;
+	git_pkt_ack *pkt = NULL;
+
+	while (1) {
+		git__free(pkt);
+
+		if ((error = recv_pkt((git_pkt **)&pkt, buf)) < 0)
+			return error;
+
+		if (pkt->type == GIT_PKT_NAK)
+			break;
+
+		if (pkt->type == GIT_PKT_ACK &&
+		    (pkt->status != GIT_ACK_CONTINUE &&
+		     pkt->status != GIT_ACK_COMMON)) {
+			git__free(pkt);
+			return 0;
+		}
+	}
+
+	git__free(pkt);
+	return 0;
+}
+
+int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, const git_remote_head * const *wants, size_t count)
+{
+	transport_smart *t = (transport_smart *)transport;
+	gitno_buffer *buf = &t->buffer;
+	git_buf data = GIT_BUF_INIT;
+	git_revwalk *walk = NULL;
+	int error = -1, pkt_type;
+	unsigned int i;
+	git_oid oid;
+
+	if ((error = git_pkt_buffer_wants(wants, count, &t->caps, &data)) < 0)
+		return error;
+
+	if ((error = fetch_setup_walk(&walk, repo)) < 0)
+		goto on_error;
+
+	/*
+	 * Our support for ACK extensions is simply to parse them. On
+	 * the first ACK we will accept that as enough common
+	 * objects. We give up if we haven't found an answer in the
+	 * first 256 we send.
+	 */
+	i = 0;
+	while (i < 256) {
+		error = git_revwalk_next(&oid, walk);
+
+		if (error < 0) {
+			if (GIT_ITEROVER == error)
+				break;
+
+			goto on_error;
+		}
+
+		git_pkt_buffer_have(&oid, &data);
+		i++;
+		if (i % 20 == 0) {
+			if (t->cancelled.val) {
+				giterr_set(GITERR_NET, "The fetch was cancelled by the user");
+				error = GIT_EUSER;
+				goto on_error;
+			}
+
+			git_pkt_buffer_flush(&data);
+			if (git_buf_oom(&data)) {
+				error = -1;
+				goto on_error;
+			}
+
+			if ((error = git_smart__negotiation_step(&t->parent, data.ptr, data.size)) < 0)
+				goto on_error;
+
+			git_buf_clear(&data);
+			if (t->caps.multi_ack || t->caps.multi_ack_detailed) {
+				if ((error = store_common(t)) < 0)
+					goto on_error;
+			} else {
+				pkt_type = recv_pkt(NULL, buf);
+
+				if (pkt_type == GIT_PKT_ACK) {
+					break;
+				} else if (pkt_type == GIT_PKT_NAK) {
+					continue;
+				} else if (pkt_type < 0) {
+					/* recv_pkt returned an error */
+					error = pkt_type;
+					goto on_error;
+				} else {
+					giterr_set(GITERR_NET, "Unexpected pkt type");
+					error = -1;
+					goto on_error;
+				}
+			}
+		}
+
+		if (t->common.length > 0)
+			break;
+
+		if (i % 20 == 0 && t->rpc) {
+			git_pkt_ack *pkt;
+			unsigned int i;
+
+			if ((error = git_pkt_buffer_wants(wants, count, &t->caps, &data)) < 0)
+				goto on_error;
+
+			git_vector_foreach(&t->common, i, pkt) {
+				if ((error = git_pkt_buffer_have(&pkt->oid, &data)) < 0)
+					goto on_error;
+			}
+
+			if (git_buf_oom(&data)) {
+				error = -1;
+				goto on_error;
+			}
+		}
+	}
+
+	/* Tell the other end that we're done negotiating */
+	if (t->rpc && t->common.length > 0) {
+		git_pkt_ack *pkt;
+		unsigned int i;
+
+		if ((error = git_pkt_buffer_wants(wants, count, &t->caps, &data)) < 0)
+			goto on_error;
+
+		git_vector_foreach(&t->common, i, pkt) {
+			if ((error = git_pkt_buffer_have(&pkt->oid, &data)) < 0)
+				goto on_error;
+		}
+
+		if (git_buf_oom(&data)) {
+			error = -1;
+			goto on_error;
+		}
+	}
+
+	if ((error = git_pkt_buffer_done(&data)) < 0)
+		goto on_error;
+
+	if (t->cancelled.val) {
+		giterr_set(GITERR_NET, "The fetch was cancelled by the user");
+		error = GIT_EUSER;
+		goto on_error;
+	}
+	if ((error = git_smart__negotiation_step(&t->parent, data.ptr, data.size)) < 0)
+		goto on_error;
+
+	git_buf_free(&data);
+	git_revwalk_free(walk);
+
+	/* Now let's eat up whatever the server gives us */
+	if (!t->caps.multi_ack && !t->caps.multi_ack_detailed) {
+		pkt_type = recv_pkt(NULL, buf);
+
+		if (pkt_type < 0) {
+			return pkt_type;
+		} else if (pkt_type != GIT_PKT_ACK && pkt_type != GIT_PKT_NAK) {
+			giterr_set(GITERR_NET, "Unexpected pkt type");
+			return -1;
+		}
+	} else {
+		error = wait_while_ack(buf);
+	}
+
+	return error;
+
+on_error:
+	git_revwalk_free(walk);
+	git_buf_free(&data);
+	return error;
+}
+
+static int no_sideband(transport_smart *t, struct git_odb_writepack *writepack, gitno_buffer *buf, git_transfer_progress *stats)
+{
+	int recvd;
+
+	do {
+		if (t->cancelled.val) {
+			giterr_set(GITERR_NET, "The fetch was cancelled by the user");
+			return GIT_EUSER;
+		}
+
+		if (writepack->append(writepack, buf->data, buf->offset, stats) < 0)
+			return -1;
+
+		gitno_consume_n(buf, buf->offset);
+
+		if ((recvd = gitno_recv(buf)) < 0)
+			return recvd;
+	} while(recvd > 0);
+
+	if (writepack->commit(writepack, stats) < 0)
+		return -1;
+
+	return 0;
+}
+
+struct network_packetsize_payload
+{
+	git_transfer_progress_cb callback;
+	void *payload;
+	git_transfer_progress *stats;
+	size_t last_fired_bytes;
+};
+
+static int network_packetsize(size_t received, void *payload)
+{
+	struct network_packetsize_payload *npp = (struct network_packetsize_payload*)payload;
+
+	/* Accumulate bytes */
+	npp->stats->received_bytes += received;
+
+	/* Fire notification if the threshold is reached */
+	if ((npp->stats->received_bytes - npp->last_fired_bytes) > NETWORK_XFER_THRESHOLD) {
+		npp->last_fired_bytes = npp->stats->received_bytes;
+
+		if (npp->callback(npp->stats, npp->payload))
+			return GIT_EUSER;
+	}
+
+	return 0;
+}
+
+int git_smart__download_pack(
+	git_transport *transport,
+	git_repository *repo,
+	git_transfer_progress *stats,
+	git_transfer_progress_cb transfer_progress_cb,
+	void *progress_payload)
+{
+	transport_smart *t = (transport_smart *)transport;
+	gitno_buffer *buf = &t->buffer;
+	git_odb *odb;
+	struct git_odb_writepack *writepack = NULL;
+	int error = 0;
+	struct network_packetsize_payload npp = {0};
+
+	memset(stats, 0, sizeof(git_transfer_progress));
+
+	if (transfer_progress_cb) {
+		npp.callback = transfer_progress_cb;
+		npp.payload = progress_payload;
+		npp.stats = stats;
+		t->packetsize_cb = &network_packetsize;
+		t->packetsize_payload = &npp;
+
+		/* We might have something in the buffer already from negotiate_fetch */
+		if (t->buffer.offset > 0 && !t->cancelled.val)
+			if (t->packetsize_cb(t->buffer.offset, t->packetsize_payload))
+				git_atomic_set(&t->cancelled, 1);
+	}
+
+	if ((error = git_repository_odb__weakptr(&odb, repo)) < 0 ||
+		((error = git_odb_write_pack(&writepack, odb, transfer_progress_cb, progress_payload)) != 0))
+		goto done;
+
+	/*
+	 * If the remote doesn't support the side-band, we can feed
+	 * the data directly to the pack writer. Otherwise, we need to
+	 * check which one belongs there.
+	 */
+	if (!t->caps.side_band && !t->caps.side_band_64k) {
+		error = no_sideband(t, writepack, buf, stats);
+		goto done;
+	}
+
+	do {
+		git_pkt *pkt = NULL;
+
+		/* Check cancellation before network call */
+		if (t->cancelled.val) {
+			giterr_clear();
+			error = GIT_EUSER;
+			goto done;
+		}
+
+		if ((error = recv_pkt(&pkt, buf)) >= 0) {
+			/* Check cancellation after network call */
+			if (t->cancelled.val) {
+				giterr_clear();
+				error = GIT_EUSER;
+			} else if (pkt->type == GIT_PKT_PROGRESS) {
+				if (t->progress_cb) {
+					git_pkt_progress *p = (git_pkt_progress *) pkt;
+					error = t->progress_cb(p->data, p->len, t->message_cb_payload);
+				}
+			} else if (pkt->type == GIT_PKT_DATA) {
+				git_pkt_data *p = (git_pkt_data *) pkt;
+
+				if (p->len)
+					error = writepack->append(writepack, p->data, p->len, stats);
+			} else if (pkt->type == GIT_PKT_FLUSH) {
+				/* A flush indicates the end of the packfile */
+				git__free(pkt);
+				break;
+			}
+		}
+
+		git__free(pkt);
+		if (error < 0)
+			goto done;
+
+	} while (1);
+
+	/*
+	 * Trailing execution of transfer_progress_cb, if necessary...
+	 * Only the callback through the npp datastructure currently
+	 * updates the last_fired_bytes value. It is possible that
+	 * progress has already been reported with the correct
+	 * "received_bytes" value, but until (if?) this is unified
+	 * then we will report progress again to be sure that the
+	 * correct last received_bytes value is reported.
+	 */
+	if (npp.callback && npp.stats->received_bytes > npp.last_fired_bytes) {
+		error = npp.callback(npp.stats, npp.payload);
+		if (error != 0)
+			goto done;
+	}
+
+	error = writepack->commit(writepack, stats);
+
+done:
+	if (writepack)
+		writepack->free(writepack);
+	if (transfer_progress_cb) {
+		t->packetsize_cb = NULL;
+		t->packetsize_payload = NULL;
+	}
+
+	return error;
+}
+
+static int gen_pktline(git_buf *buf, git_push *push)
+{
+	push_spec *spec;
+	size_t i, len;
+	char old_id[GIT_OID_HEXSZ+1], new_id[GIT_OID_HEXSZ+1];
+
+	old_id[GIT_OID_HEXSZ] = '\0'; new_id[GIT_OID_HEXSZ] = '\0';
+
+	git_vector_foreach(&push->specs, i, spec) {
+		len = 2*GIT_OID_HEXSZ + 7 + strlen(spec->refspec.dst);
+
+		if (i == 0) {
+			++len; /* '\0' */
+			if (push->report_status)
+				len += strlen(GIT_CAP_REPORT_STATUS) + 1;
+			len += strlen(GIT_CAP_SIDE_BAND_64K) + 1;
+		}
+
+		git_oid_fmt(old_id, &spec->roid);
+		git_oid_fmt(new_id, &spec->loid);
+
+		git_buf_printf(buf, "%04"PRIxZ"%s %s %s", len, old_id, new_id, spec->refspec.dst);
+
+		if (i == 0) {
+			git_buf_putc(buf, '\0');
+			/* Core git always starts their capabilities string with a space */
+			if (push->report_status) {
+				git_buf_putc(buf, ' ');
+				git_buf_printf(buf, GIT_CAP_REPORT_STATUS);
+			}
+			git_buf_putc(buf, ' ');
+			git_buf_printf(buf, GIT_CAP_SIDE_BAND_64K);
+		}
+
+		git_buf_putc(buf, '\n');
+	}
+
+	git_buf_puts(buf, "0000");
+	return git_buf_oom(buf) ? -1 : 0;
+}
+
+static int add_push_report_pkt(git_push *push, git_pkt *pkt)
+{
+	push_status *status;
+
+	switch (pkt->type) {
+		case GIT_PKT_OK:
+			status = git__calloc(1, sizeof(push_status));
+			GITERR_CHECK_ALLOC(status);
+			status->msg = NULL;
+			status->ref = git__strdup(((git_pkt_ok *)pkt)->ref);
+			if (!status->ref ||
+				git_vector_insert(&push->status, status) < 0) {
+				git_push_status_free(status);
+				return -1;
+			}
+			break;
+		case GIT_PKT_NG:
+			status = git__calloc(1, sizeof(push_status));
+			GITERR_CHECK_ALLOC(status);
+			status->ref = git__strdup(((git_pkt_ng *)pkt)->ref);
+			status->msg = git__strdup(((git_pkt_ng *)pkt)->msg);
+			if (!status->ref || !status->msg ||
+				git_vector_insert(&push->status, status) < 0) {
+				git_push_status_free(status);
+				return -1;
+			}
+			break;
+		case GIT_PKT_UNPACK:
+			push->unpack_ok = ((git_pkt_unpack *)pkt)->unpack_ok;
+			break;
+		case GIT_PKT_FLUSH:
+			return GIT_ITEROVER;
+		default:
+			giterr_set(GITERR_NET, "report-status: protocol error");
+			return -1;
+	}
+
+	return 0;
+}
+
+static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt)
+{
+	git_pkt *pkt;
+	const char *line = data_pkt->data, *line_end;
+	size_t line_len = data_pkt->len;
+	int error;
+
+	while (line_len > 0) {
+		error = git_pkt_parse_line(&pkt, line, &line_end, line_len);
+
+		if (error < 0)
+			return error;
+
+		/* Advance in the buffer */
+		line_len -= (line_end - line);
+		line = line_end;
+
+		error = add_push_report_pkt(push, pkt);
+
+		git_pkt_free(pkt);
+
+		if (error < 0 && error != GIT_ITEROVER)
+			return error;
+	}
+
+	return 0;
+}
+
+static int parse_report(transport_smart *transport, git_push *push)
+{
+	git_pkt *pkt = NULL;
+	const char *line_end = NULL;
+	gitno_buffer *buf = &transport->buffer;
+	int error, recvd;
+
+	for (;;) {
+		if (buf->offset > 0)
+			error = git_pkt_parse_line(&pkt, buf->data,
+						   &line_end, buf->offset);
+		else
+			error = GIT_EBUFS;
+
+		if (error < 0 && error != GIT_EBUFS)
+			return -1;
+
+		if (error == GIT_EBUFS) {
+			if ((recvd = gitno_recv(buf)) < 0)
+				return recvd;
+
+			if (recvd == 0) {
+				giterr_set(GITERR_NET, "early EOF");
+				return GIT_EEOF;
+			}
+			continue;
+		}
+
+		gitno_consume(buf, line_end);
+
+		error = 0;
+
+		switch (pkt->type) {
+			case GIT_PKT_DATA:
+				/* This is a sideband packet which contains other packets */
+				error = add_push_report_sideband_pkt(push, (git_pkt_data *)pkt);
+				break;
+			case GIT_PKT_ERR:
+				giterr_set(GITERR_NET, "report-status: Error reported: %s",
+					((git_pkt_err *)pkt)->error);
+				error = -1;
+				break;
+			case GIT_PKT_PROGRESS:
+				if (transport->progress_cb) {
+					git_pkt_progress *p = (git_pkt_progress *) pkt;
+					error = transport->progress_cb(p->data, p->len, transport->message_cb_payload);
+				}
+				break;
+			default:
+				error = add_push_report_pkt(push, pkt);
+				break;
+		}
+
+		git_pkt_free(pkt);
+
+		/* add_push_report_pkt returns GIT_ITEROVER when it receives a flush */
+		if (error == GIT_ITEROVER)
+			return 0;
+
+		if (error < 0)
+			return error;
+	}
+}
+
+static int add_ref_from_push_spec(git_vector *refs, push_spec *push_spec)
+{
+	git_pkt_ref *added = git__calloc(1, sizeof(git_pkt_ref));
+	GITERR_CHECK_ALLOC(added);
+
+	added->type = GIT_PKT_REF;
+	git_oid_cpy(&added->head.oid, &push_spec->loid);
+	added->head.name = git__strdup(push_spec->refspec.dst);
+
+	if (!added->head.name ||
+		git_vector_insert(refs, added) < 0) {
+		git_pkt_free((git_pkt *)added);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int update_refs_from_report(
+	git_vector *refs,
+	git_vector *push_specs,
+	git_vector *push_report)
+{
+	git_pkt_ref *ref;
+	push_spec *push_spec;
+	push_status *push_status;
+	size_t i, j, refs_len;
+	int cmp;
+
+	/* For each push spec we sent to the server, we should have
+	 * gotten back a status packet in the push report */
+	if (push_specs->length != push_report->length) {
+		giterr_set(GITERR_NET, "report-status: protocol error");
+		return -1;
+	}
+
+	/* We require that push_specs be sorted with push_spec_rref_cmp,
+	 * and that push_report be sorted with push_status_ref_cmp */
+	git_vector_sort(push_specs);
+	git_vector_sort(push_report);
+
+	git_vector_foreach(push_specs, i, push_spec) {
+		push_status = git_vector_get(push_report, i);
+
+		/* For each push spec we sent to the server, we should have
+		 * gotten back a status packet in the push report which matches */
+		if (strcmp(push_spec->refspec.dst, push_status->ref)) {
+			giterr_set(GITERR_NET, "report-status: protocol error");
+			return -1;
+		}
+	}
+
+	/* We require that refs be sorted with ref_name_cmp */
+	git_vector_sort(refs);
+	i = j = 0;
+	refs_len = refs->length;
+
+	/* Merge join push_specs with refs */
+	while (i < push_specs->length && j < refs_len) {
+		push_spec = git_vector_get(push_specs, i);
+		push_status = git_vector_get(push_report, i);
+		ref = git_vector_get(refs, j);
+
+		cmp = strcmp(push_spec->refspec.dst, ref->head.name);
+
+		/* Iterate appropriately */
+		if (cmp <= 0) i++;
+		if (cmp >= 0) j++;
+
+		/* Add case */
+		if (cmp < 0 &&
+			!push_status->msg &&
+			add_ref_from_push_spec(refs, push_spec) < 0)
+			return -1;
+
+		/* Update case, delete case */
+		if (cmp == 0 &&
+			!push_status->msg)
+			git_oid_cpy(&ref->head.oid, &push_spec->loid);
+	}
+
+	for (; i < push_specs->length; i++) {
+		push_spec = git_vector_get(push_specs, i);
+		push_status = git_vector_get(push_report, i);
+
+		/* Add case */
+		if (!push_status->msg &&
+			add_ref_from_push_spec(refs, push_spec) < 0)
+			return -1;
+	}
+
+	/* Remove any refs which we updated to have a zero OID. */
+	git_vector_rforeach(refs, i, ref) {
+		if (git_oid_iszero(&ref->head.oid)) {
+			git_vector_remove(refs, i);
+			git_pkt_free((git_pkt *)ref);
+		}
+	}
+
+	git_vector_sort(refs);
+
+	return 0;
+}
+
+struct push_packbuilder_payload
+{
+	git_smart_subtransport_stream *stream;
+	git_packbuilder *pb;
+	git_push_transfer_progress cb;
+	void *cb_payload;
+	size_t last_bytes;
+	double last_progress_report_time;
+};
+
+static int stream_thunk(void *buf, size_t size, void *data)
+{
+	int error = 0;
+	struct push_packbuilder_payload *payload = data;
+
+	if ((error = payload->stream->write(payload->stream, (const char *)buf, size)) < 0)
+		return error;
+
+	if (payload->cb) {
+		double current_time = git__timer();
+		payload->last_bytes += size;
+
+		if ((current_time - payload->last_progress_report_time) >= MIN_PROGRESS_UPDATE_INTERVAL) {
+			payload->last_progress_report_time = current_time;
+			error = payload->cb(payload->pb->nr_written, payload->pb->nr_objects, payload->last_bytes, payload->cb_payload);
+		}
+	}
+
+	return error;
+}
+
+int git_smart__push(git_transport *transport, git_push *push, const git_remote_callbacks *cbs)
+{
+	transport_smart *t = (transport_smart *)transport;
+	struct push_packbuilder_payload packbuilder_payload = {0};
+	git_buf pktline = GIT_BUF_INIT;
+	int error = 0, need_pack = 0;
+	push_spec *spec;
+	unsigned int i;
+
+	packbuilder_payload.pb = push->pb;
+
+	if (cbs && cbs->push_transfer_progress) {
+		packbuilder_payload.cb = cbs->push_transfer_progress;
+		packbuilder_payload.cb_payload = cbs->payload;
+	}
+
+#ifdef PUSH_DEBUG
+{
+	git_remote_head *head;
+	char hex[GIT_OID_HEXSZ+1]; hex[GIT_OID_HEXSZ] = '\0';
+
+	git_vector_foreach(&push->remote->refs, i, head) {
+		git_oid_fmt(hex, &head->oid);
+		fprintf(stderr, "%s (%s)\n", hex, head->name);
+	}
+
+	git_vector_foreach(&push->specs, i, spec) {
+		git_oid_fmt(hex, &spec->roid);
+		fprintf(stderr, "%s (%s) -> ", hex, spec->lref);
+		git_oid_fmt(hex, &spec->loid);
+		fprintf(stderr, "%s (%s)\n", hex, spec->rref ?
+			spec->rref : spec->lref);
+	}
+}
+#endif
+
+	/*
+	 * Figure out if we need to send a packfile; which is in all
+	 * cases except when we only send delete commands
+	 */
+	git_vector_foreach(&push->specs, i, spec) {
+		if (spec->refspec.src && spec->refspec.src[0] != '\0') {
+			need_pack = 1;
+			break;
+		}
+	}
+
+	if ((error = git_smart__get_push_stream(t, &packbuilder_payload.stream)) < 0 ||
+		(error = gen_pktline(&pktline, push)) < 0 ||
+		(error = packbuilder_payload.stream->write(packbuilder_payload.stream, git_buf_cstr(&pktline), git_buf_len(&pktline))) < 0)
+		goto done;
+
+	if (need_pack &&
+		(error = git_packbuilder_foreach(push->pb, &stream_thunk, &packbuilder_payload)) < 0)
+		goto done;
+
+	/* If we sent nothing or the server doesn't support report-status, then
+	 * we consider the pack to have been unpacked successfully */
+	if (!push->specs.length || !push->report_status)
+		push->unpack_ok = 1;
+	else if ((error = parse_report(t, push)) < 0)
+		goto done;
+
+	/* If progress is being reported write the final report */
+	if (cbs && cbs->push_transfer_progress) {
+		error = cbs->push_transfer_progress(
+					push->pb->nr_written,
+					push->pb->nr_objects,
+					packbuilder_payload.last_bytes,
+					cbs->payload);
+
+		if (error < 0)
+			goto done;
+	}
+
+	if (push->status.length) {
+		error = update_refs_from_report(&t->refs, &push->specs, &push->status);
+		if (error < 0)
+			goto done;
+
+		error = git_smart__update_heads(t, NULL);
+	}
+
+done:
+	git_buf_free(&pktline);
+	return error;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/ssh.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/ssh.c
new file mode 100755
index 0000000..e3792eb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/ssh.c
@@ -0,0 +1,871 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifdef GIT_SSH
+#include <libssh2.h>
+#endif
+
+#include "git2.h"
+#include "buffer.h"
+#include "netops.h"
+#include "smart.h"
+#include "cred.h"
+#include "socket_stream.h"
+
+#ifdef GIT_SSH
+
+#define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport)
+
+static const char prefix_ssh[] = "ssh://";
+static const char cmd_uploadpack[] = "git-upload-pack";
+static const char cmd_receivepack[] = "git-receive-pack";
+
+typedef struct {
+	git_smart_subtransport_stream parent;
+	git_stream *io;
+	LIBSSH2_SESSION *session;
+	LIBSSH2_CHANNEL *channel;
+	const char *cmd;
+	char *url;
+	unsigned sent_command : 1;
+} ssh_stream;
+
+typedef struct {
+	git_smart_subtransport parent;
+	transport_smart *owner;
+	ssh_stream *current_stream;
+	git_cred *cred;
+	char *cmd_uploadpack;
+	char *cmd_receivepack;
+} ssh_subtransport;
+
+static int list_auth_methods(int *out, LIBSSH2_SESSION *session, const char *username);
+
+static void ssh_error(LIBSSH2_SESSION *session, const char *errmsg)
+{
+	char *ssherr;
+	libssh2_session_last_error(session, &ssherr, NULL, 0);
+
+	giterr_set(GITERR_SSH, "%s: %s", errmsg, ssherr);
+}
+
+/*
+ * Create a git protocol request.
+ *
+ * For example: git-upload-pack '/libgit2/libgit2'
+ */
+static int gen_proto(git_buf *request, const char *cmd, const char *url)
+{
+	char *repo;
+	int len;
+
+	if (!git__prefixcmp(url, prefix_ssh)) {
+		url = url + strlen(prefix_ssh);
+		repo = strchr(url, '/');
+		if (repo && repo[1] == '~')
+			++repo;
+	} else {
+		repo = strchr(url, ':');
+		if (repo) repo++;
+	}
+
+	if (!repo) {
+		giterr_set(GITERR_NET, "Malformed git protocol URL");
+		return -1;
+	}
+
+	len = strlen(cmd) + 1 /* Space */ + 1 /* Quote */ + strlen(repo) + 1 /* Quote */ + 1;
+
+	git_buf_grow(request, len);
+	git_buf_printf(request, "%s '%s'", cmd, repo);
+	git_buf_putc(request, '\0');
+
+	if (git_buf_oom(request))
+		return -1;
+
+	return 0;
+}
+
+static int send_command(ssh_stream *s)
+{
+	int error;
+	git_buf request = GIT_BUF_INIT;
+
+	error = gen_proto(&request, s->cmd, s->url);
+	if (error < 0)
+		goto cleanup;
+
+	error = libssh2_channel_exec(s->channel, request.ptr);
+	if (error < LIBSSH2_ERROR_NONE) {
+		ssh_error(s->session, "SSH could not execute request");
+		goto cleanup;
+	}
+
+	s->sent_command = 1;
+
+cleanup:
+	git_buf_free(&request);
+	return error;
+}
+
+static int ssh_stream_read(
+	git_smart_subtransport_stream *stream,
+	char *buffer,
+	size_t buf_size,
+	size_t *bytes_read)
+{
+	int rc;
+	ssh_stream *s = (ssh_stream *)stream;
+
+	*bytes_read = 0;
+
+	if (!s->sent_command && send_command(s) < 0)
+		return -1;
+
+	if ((rc = libssh2_channel_read(s->channel, buffer, buf_size)) < LIBSSH2_ERROR_NONE) {
+		ssh_error(s->session, "SSH could not read data");
+		return -1;
+	}
+
+	/*
+	 * If we can't get anything out of stdout, it's typically a
+	 * not-found error, so read from stderr and signal EOF on
+	 * stderr.
+	 */
+	if (rc == 0 && (rc = libssh2_channel_read_stderr(s->channel, buffer, buf_size)) > 0) {
+		giterr_set(GITERR_SSH, "%*s", rc, buffer);
+		return GIT_EEOF;
+	}
+
+
+	*bytes_read = rc;
+
+	return 0;
+}
+
+static int ssh_stream_write(
+	git_smart_subtransport_stream *stream,
+	const char *buffer,
+	size_t len)
+{
+	ssh_stream *s = (ssh_stream *)stream;
+	size_t off = 0;
+	ssize_t ret = 0;
+
+	if (!s->sent_command && send_command(s) < 0)
+		return -1;
+
+	do {
+		ret = libssh2_channel_write(s->channel, buffer + off, len - off);
+		if (ret < 0)
+			break;
+
+		off += ret;
+
+	} while (off < len);
+
+	if (ret < 0) {
+		ssh_error(s->session, "SSH could not write data");
+		return -1;
+	}
+
+	return 0;
+}
+
+static void ssh_stream_free(git_smart_subtransport_stream *stream)
+{
+	ssh_stream *s = (ssh_stream *)stream;
+	ssh_subtransport *t;
+
+	if (!stream)
+		return;
+
+	t = OWNING_SUBTRANSPORT(s);
+	t->current_stream = NULL;
+
+	if (s->channel) {
+		libssh2_channel_close(s->channel);
+		libssh2_channel_free(s->channel);
+		s->channel = NULL;
+	}
+
+	if (s->session) {
+		libssh2_session_free(s->session);
+		s->session = NULL;
+	}
+
+	if (s->io) {
+		git_stream_close(s->io);
+		git_stream_free(s->io);
+		s->io = NULL;
+	}
+
+	git__free(s->url);
+	git__free(s);
+}
+
+static int ssh_stream_alloc(
+	ssh_subtransport *t,
+	const char *url,
+	const char *cmd,
+	git_smart_subtransport_stream **stream)
+{
+	ssh_stream *s;
+
+	assert(stream);
+
+	s = git__calloc(sizeof(ssh_stream), 1);
+	GITERR_CHECK_ALLOC(s);
+
+	s->parent.subtransport = &t->parent;
+	s->parent.read = ssh_stream_read;
+	s->parent.write = ssh_stream_write;
+	s->parent.free = ssh_stream_free;
+
+	s->cmd = cmd;
+
+	s->url = git__strdup(url);
+	if (!s->url) {
+		git__free(s);
+		return -1;
+	}
+
+	*stream = &s->parent;
+	return 0;
+}
+
+static int git_ssh_extract_url_parts(
+	char **host,
+	char **username,
+	const char *url)
+{
+	char *colon, *at;
+	const char *start;
+
+	colon = strchr(url, ':');
+
+
+	at = strchr(url, '@');
+	if (at) {
+		start = at + 1;
+		*username = git__substrdup(url, at - url);
+		GITERR_CHECK_ALLOC(*username);
+	} else {
+		start = url;
+		*username = NULL;
+	}
+
+	if (colon == NULL || (colon < start)) {
+		giterr_set(GITERR_NET, "Malformed URL");
+		return -1;
+	}
+
+	*host = git__substrdup(start, colon - start);
+	GITERR_CHECK_ALLOC(*host);
+
+	return 0;
+}
+
+static int ssh_agent_auth(LIBSSH2_SESSION *session, git_cred_ssh_key *c) {
+	int rc = LIBSSH2_ERROR_NONE;
+
+	struct libssh2_agent_publickey *curr, *prev = NULL;
+
+	LIBSSH2_AGENT *agent = libssh2_agent_init(session);
+
+	if (agent == NULL)
+		return -1;
+
+	rc = libssh2_agent_connect(agent);
+
+	if (rc != LIBSSH2_ERROR_NONE)
+		goto shutdown;
+
+	rc = libssh2_agent_list_identities(agent);
+
+	if (rc != LIBSSH2_ERROR_NONE)
+		goto shutdown;
+
+	while (1) {
+		rc = libssh2_agent_get_identity(agent, &curr, prev);
+
+		if (rc < 0)
+			goto shutdown;
+
+		/* rc is set to 1 whenever the ssh agent ran out of keys to check.
+		 * Set the error code to authentication failure rather than erroring
+		 * out with an untranslatable error code.
+		 */
+		if (rc == 1) {
+			rc = LIBSSH2_ERROR_AUTHENTICATION_FAILED;
+			goto shutdown;
+		}
+
+		rc = libssh2_agent_userauth(agent, c->username, curr);
+
+		if (rc == 0)
+			break;
+
+		prev = curr;
+	}
+
+shutdown:
+
+	if (rc != LIBSSH2_ERROR_NONE)
+		ssh_error(session, "error authenticating");
+
+	libssh2_agent_disconnect(agent);
+	libssh2_agent_free(agent);
+
+	return rc;
+}
+
+static int _git_ssh_authenticate_session(
+	LIBSSH2_SESSION* session,
+	git_cred* cred)
+{
+	int rc;
+
+	do {
+		giterr_clear();
+		switch (cred->credtype) {
+		case GIT_CREDTYPE_USERPASS_PLAINTEXT: {
+			git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
+			rc = libssh2_userauth_password(session, c->username, c->password);
+			break;
+		}
+		case GIT_CREDTYPE_SSH_KEY: {
+			git_cred_ssh_key *c = (git_cred_ssh_key *)cred;
+
+			if (c->privatekey)
+				rc = libssh2_userauth_publickey_fromfile(
+					session, c->username, c->publickey,
+					c->privatekey, c->passphrase);
+			else
+				rc = ssh_agent_auth(session, c);
+
+			break;
+		}
+		case GIT_CREDTYPE_SSH_CUSTOM: {
+			git_cred_ssh_custom *c = (git_cred_ssh_custom *)cred;
+
+			rc = libssh2_userauth_publickey(
+				session, c->username, (const unsigned char *)c->publickey,
+				c->publickey_len, c->sign_callback, &c->payload);
+			break;
+		}
+		case GIT_CREDTYPE_SSH_INTERACTIVE: {
+			void **abstract = libssh2_session_abstract(session);
+			git_cred_ssh_interactive *c = (git_cred_ssh_interactive *)cred;
+
+			/* ideally, we should be able to set this by calling
+			 * libssh2_session_init_ex() instead of libssh2_session_init().
+			 * libssh2's API is inconsistent here i.e. libssh2_userauth_publickey()
+			 * allows you to pass the `abstract` as part of the call, whereas
+			 * libssh2_userauth_keyboard_interactive() does not!
+			 *
+			 * The only way to set the `abstract` pointer is by calling
+			 * libssh2_session_abstract(), which will replace the existing
+			 * pointer as is done below. This is safe for now (at time of writing),
+			 * but may not be valid in future.
+			 */
+			*abstract = c->payload;
+
+			rc = libssh2_userauth_keyboard_interactive(
+				session, c->username, c->prompt_callback);
+			break;
+		}
+#ifdef GIT_SSH_MEMORY_CREDENTIALS
+		case GIT_CREDTYPE_SSH_MEMORY: {
+			git_cred_ssh_key *c = (git_cred_ssh_key *)cred;
+
+			assert(c->username);
+			assert(c->privatekey);
+
+			rc = libssh2_userauth_publickey_frommemory(
+				session,
+				c->username,
+				strlen(c->username),
+				c->publickey,
+				c->publickey ? strlen(c->publickey) : 0,
+				c->privatekey,
+				strlen(c->privatekey),
+				c->passphrase);
+			break;
+		}
+#endif
+		default:
+			rc = LIBSSH2_ERROR_AUTHENTICATION_FAILED;
+		}
+	} while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc);
+
+        if (rc == LIBSSH2_ERROR_PASSWORD_EXPIRED || rc == LIBSSH2_ERROR_AUTHENTICATION_FAILED)
+                return GIT_EAUTH;
+
+	if (rc != LIBSSH2_ERROR_NONE) {
+		if (!giterr_last())
+			ssh_error(session, "Failed to authenticate SSH session");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int request_creds(git_cred **out, ssh_subtransport *t, const char *user, int auth_methods)
+{
+	int error, no_callback = 0;
+	git_cred *cred = NULL;
+
+	if (!t->owner->cred_acquire_cb) {
+		no_callback = 1;
+	} else {
+		error = t->owner->cred_acquire_cb(&cred, t->owner->url, user, auth_methods,
+						  t->owner->cred_acquire_payload);
+
+		if (error == GIT_PASSTHROUGH)
+			no_callback = 1;
+		else if (error < 0)
+			return error;
+		else if (!cred) {
+			giterr_set(GITERR_SSH, "Callback failed to initialize SSH credentials");
+			return -1;
+		}
+	}
+
+	if (no_callback) {
+		giterr_set(GITERR_SSH, "authentication required but no callback set");
+		return -1;
+	}
+
+	if (!(cred->credtype & auth_methods)) {
+		cred->free(cred);
+		giterr_set(GITERR_SSH, "callback returned unsupported credentials type");
+		return -1;
+	}
+
+	*out = cred;
+
+	return 0;
+}
+
+static int _git_ssh_session_create(
+	LIBSSH2_SESSION** session,
+	git_stream *io)
+{
+	int rc = 0;
+	LIBSSH2_SESSION* s;
+	git_socket_stream *socket = (git_socket_stream *) io;
+
+	assert(session);
+
+	s = libssh2_session_init();
+	if (!s) {
+		giterr_set(GITERR_NET, "Failed to initialize SSH session");
+		return -1;
+	}
+
+	do {
+		rc = libssh2_session_startup(s, socket->s);
+	} while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc);
+
+	if (rc != LIBSSH2_ERROR_NONE) {
+		ssh_error(s, "Failed to start SSH session");
+		libssh2_session_free(s);
+		return -1;
+	}
+
+	libssh2_session_set_blocking(s, 1);
+
+	*session = s;
+
+	return 0;
+}
+
+static int _git_ssh_setup_conn(
+	ssh_subtransport *t,
+	const char *url,
+	const char *cmd,
+	git_smart_subtransport_stream **stream)
+{
+	char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL;
+	const char *default_port="22";
+	int auth_methods, error = 0;
+	ssh_stream *s;
+	git_cred *cred = NULL;
+	LIBSSH2_SESSION* session=NULL;
+	LIBSSH2_CHANNEL* channel=NULL;
+
+	t->current_stream = NULL;
+
+	*stream = NULL;
+	if (ssh_stream_alloc(t, url, cmd, stream) < 0)
+		return -1;
+
+	s = (ssh_stream *)*stream;
+	s->session = NULL;
+	s->channel = NULL;
+
+	if (!git__prefixcmp(url, prefix_ssh)) {
+		if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, default_port)) < 0)
+			goto done;
+	} else {
+		if ((error = git_ssh_extract_url_parts(&host, &user, url)) < 0)
+			goto done;
+		port = git__strdup(default_port);
+		GITERR_CHECK_ALLOC(port);
+	}
+
+	if ((error = git_socket_stream_new(&s->io, host, port)) < 0 ||
+	    (error = git_stream_connect(s->io)) < 0)
+		goto done;
+
+	if ((error = _git_ssh_session_create(&session, s->io)) < 0)
+		goto done;
+
+	if (t->owner->certificate_check_cb != NULL) {
+		git_cert_hostkey cert = { 0 }, *cert_ptr;
+		const char *key;
+
+		cert.cert_type = GIT_CERT_HOSTKEY_LIBSSH2;
+
+		key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
+		if (key != NULL) {
+			cert.type |= GIT_CERT_SSH_SHA1;
+			memcpy(&cert.hash_sha1, key, 20);
+		}
+
+		key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
+		if (key != NULL) {
+			cert.type |= GIT_CERT_SSH_MD5;
+			memcpy(&cert.hash_md5, key, 16);
+		}
+
+		if (cert.type == 0) {
+			giterr_set(GITERR_SSH, "unable to get the host key");
+			error = -1;
+			goto done;
+		}
+
+		/* We don't currently trust any hostkeys */
+		giterr_clear();
+
+		cert_ptr = &cert;
+
+		error = t->owner->certificate_check_cb((git_cert *) cert_ptr, 0, host, t->owner->message_cb_payload);
+		if (error < 0) {
+			if (!giterr_last())
+				giterr_set(GITERR_NET, "user cancelled hostkey check");
+
+			goto done;
+		}
+	}
+
+	/* we need the username to ask for auth methods */
+	if (!user) {
+		if ((error = request_creds(&cred, t, NULL, GIT_CREDTYPE_USERNAME)) < 0)
+			goto done;
+
+		user = git__strdup(((git_cred_username *) cred)->username);
+		cred->free(cred);
+		cred = NULL;
+		if (!user)
+			goto done;
+	} else if (user && pass) {
+		if ((error = git_cred_userpass_plaintext_new(&cred, user, pass)) < 0)
+			goto done;
+	}
+
+	if ((error = list_auth_methods(&auth_methods, session, user)) < 0)
+		goto done;
+
+	error = GIT_EAUTH;
+	/* if we already have something to try */
+	if (cred && auth_methods & cred->credtype)
+		error = _git_ssh_authenticate_session(session, cred);
+
+	while (error == GIT_EAUTH) {
+		if (cred) {
+			cred->free(cred);
+			cred = NULL;
+		}
+
+		if ((error = request_creds(&cred, t, user, auth_methods)) < 0)
+			goto done;
+
+		if (strcmp(user, git_cred__username(cred))) {
+			giterr_set(GITERR_SSH, "username does not match previous request");
+			error = -1;
+			goto done;
+		}
+
+		error = _git_ssh_authenticate_session(session, cred);
+	}
+
+	if (error < 0)
+		goto done;
+
+	channel = libssh2_channel_open_session(session);
+	if (!channel) {
+		error = -1;
+		ssh_error(session, "Failed to open SSH channel");
+		goto done;
+	}
+
+	libssh2_channel_set_blocking(channel, 1);
+
+	s->session = session;
+	s->channel = channel;
+
+	t->current_stream = s;
+
+done:
+	if (error < 0) {
+		ssh_stream_free(*stream);
+
+		if (session)
+			libssh2_session_free(session);
+	}
+
+	if (cred)
+		cred->free(cred);
+
+	git__free(host);
+	git__free(port);
+	git__free(path);
+	git__free(user);
+	git__free(pass);
+
+	return error;
+}
+
+static int ssh_uploadpack_ls(
+	ssh_subtransport *t,
+	const char *url,
+	git_smart_subtransport_stream **stream)
+{
+	const char *cmd = t->cmd_uploadpack ? t->cmd_uploadpack : cmd_uploadpack;
+
+	return _git_ssh_setup_conn(t, url, cmd, stream);
+}
+
+static int ssh_uploadpack(
+	ssh_subtransport *t,
+	const char *url,
+	git_smart_subtransport_stream **stream)
+{
+	GIT_UNUSED(url);
+
+	if (t->current_stream) {
+		*stream = &t->current_stream->parent;
+		return 0;
+	}
+
+	giterr_set(GITERR_NET, "Must call UPLOADPACK_LS before UPLOADPACK");
+	return -1;
+}
+
+static int ssh_receivepack_ls(
+	ssh_subtransport *t,
+	const char *url,
+	git_smart_subtransport_stream **stream)
+{
+	const char *cmd = t->cmd_receivepack ? t->cmd_receivepack : cmd_receivepack;
+
+
+	return _git_ssh_setup_conn(t, url, cmd, stream);
+}
+
+static int ssh_receivepack(
+	ssh_subtransport *t,
+	const char *url,
+	git_smart_subtransport_stream **stream)
+{
+	GIT_UNUSED(url);
+
+	if (t->current_stream) {
+		*stream = &t->current_stream->parent;
+		return 0;
+	}
+
+	giterr_set(GITERR_NET, "Must call RECEIVEPACK_LS before RECEIVEPACK");
+	return -1;
+}
+
+static int _ssh_action(
+	git_smart_subtransport_stream **stream,
+	git_smart_subtransport *subtransport,
+	const char *url,
+	git_smart_service_t action)
+{
+	ssh_subtransport *t = (ssh_subtransport *) subtransport;
+
+	switch (action) {
+		case GIT_SERVICE_UPLOADPACK_LS:
+			return ssh_uploadpack_ls(t, url, stream);
+
+		case GIT_SERVICE_UPLOADPACK:
+			return ssh_uploadpack(t, url, stream);
+
+		case GIT_SERVICE_RECEIVEPACK_LS:
+			return ssh_receivepack_ls(t, url, stream);
+
+		case GIT_SERVICE_RECEIVEPACK:
+			return ssh_receivepack(t, url, stream);
+	}
+
+	*stream = NULL;
+	return -1;
+}
+
+static int _ssh_close(git_smart_subtransport *subtransport)
+{
+	ssh_subtransport *t = (ssh_subtransport *) subtransport;
+
+	assert(!t->current_stream);
+
+	GIT_UNUSED(t);
+
+	return 0;
+}
+
+static void _ssh_free(git_smart_subtransport *subtransport)
+{
+	ssh_subtransport *t = (ssh_subtransport *) subtransport;
+
+	assert(!t->current_stream);
+
+	git__free(t->cmd_uploadpack);
+	git__free(t->cmd_receivepack);
+	git__free(t);
+}
+
+#define SSH_AUTH_PUBLICKEY "publickey"
+#define SSH_AUTH_PASSWORD "password"
+#define SSH_AUTH_KEYBOARD_INTERACTIVE "keyboard-interactive"
+
+static int list_auth_methods(int *out, LIBSSH2_SESSION *session, const char *username)
+{
+	const char *list, *ptr;
+
+	*out = 0;
+
+	list = libssh2_userauth_list(session, username, strlen(username));
+
+	/* either error, or the remote accepts NONE auth, which is bizarre, let's punt */
+	if (list == NULL && !libssh2_userauth_authenticated(session))
+		return -1;
+
+	ptr = list;
+	while (ptr) {
+		if (*ptr == ',')
+			ptr++;
+
+		if (!git__prefixcmp(ptr, SSH_AUTH_PUBLICKEY)) {
+			*out |= GIT_CREDTYPE_SSH_KEY;
+			*out |= GIT_CREDTYPE_SSH_CUSTOM;
+#ifdef GIT_SSH_MEMORY_CREDENTIALS
+			*out |= GIT_CREDTYPE_SSH_MEMORY;
+#endif
+			ptr += strlen(SSH_AUTH_PUBLICKEY);
+			continue;
+		}
+
+		if (!git__prefixcmp(ptr, SSH_AUTH_PASSWORD)) {
+			*out |= GIT_CREDTYPE_USERPASS_PLAINTEXT;
+			ptr += strlen(SSH_AUTH_PASSWORD);
+			continue;
+		}
+
+		if (!git__prefixcmp(ptr, SSH_AUTH_KEYBOARD_INTERACTIVE)) {
+			*out |= GIT_CREDTYPE_SSH_INTERACTIVE;
+			ptr += strlen(SSH_AUTH_KEYBOARD_INTERACTIVE);
+			continue;
+		}
+
+		/* Skipt it if we don't know it */
+		ptr = strchr(ptr, ',');
+	}
+
+	return 0;
+}
+#endif
+
+int git_smart_subtransport_ssh(
+	git_smart_subtransport **out, git_transport *owner, void *param)
+{
+#ifdef GIT_SSH
+	ssh_subtransport *t;
+
+	assert(out);
+
+	GIT_UNUSED(param);
+
+	t = git__calloc(sizeof(ssh_subtransport), 1);
+	GITERR_CHECK_ALLOC(t);
+
+	t->owner = (transport_smart *)owner;
+	t->parent.action = _ssh_action;
+	t->parent.close = _ssh_close;
+	t->parent.free = _ssh_free;
+
+	*out = (git_smart_subtransport *) t;
+	return 0;
+#else
+	GIT_UNUSED(owner);
+	GIT_UNUSED(param);
+
+	assert(out);
+	*out = NULL;
+
+	giterr_set(GITERR_INVALID, "Cannot create SSH transport. Library was built without SSH support");
+	return -1;
+#endif
+}
+
+int git_transport_ssh_with_paths(git_transport **out, git_remote *owner, void *payload)
+{
+#ifdef GIT_SSH
+	git_strarray *paths = (git_strarray *) payload;
+	git_transport *transport;
+	transport_smart *smart;
+	ssh_subtransport *t;
+	int error;
+	git_smart_subtransport_definition ssh_definition = {
+		git_smart_subtransport_ssh,
+		0, /* no RPC */
+		NULL,
+	};
+
+	if (paths->count != 2) {
+		giterr_set(GITERR_SSH, "invalid ssh paths, must be two strings");
+		return GIT_EINVALIDSPEC;
+	}
+
+	if ((error = git_transport_smart(&transport, owner, &ssh_definition)) < 0)
+		return error;
+
+	smart = (transport_smart *) transport;
+	t = (ssh_subtransport *) smart->wrapped;
+
+	t->cmd_uploadpack = git__strdup(paths->strings[0]);
+	GITERR_CHECK_ALLOC(t->cmd_uploadpack);
+	t->cmd_receivepack = git__strdup(paths->strings[1]);
+	GITERR_CHECK_ALLOC(t->cmd_receivepack);
+
+	*out = transport;
+	return 0;
+#else
+	GIT_UNUSED(owner);
+	GIT_UNUSED(payload);
+
+	assert(out);
+	*out = NULL;
+
+	giterr_set(GITERR_INVALID, "Cannot create SSH transport. Library was built without SSH support");
+	return -1;
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/winhttp.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/winhttp.c
new file mode 100755
index 0000000..da047d6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/transports/winhttp.c
@@ -0,0 +1,1350 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifdef GIT_WINHTTP
+
+#include "git2.h"
+#include "git2/transport.h"
+#include "buffer.h"
+#include "posix.h"
+#include "netops.h"
+#include "smart.h"
+#include "remote.h"
+#include "repository.h"
+
+#include <wincrypt.h>
+#include <winhttp.h>
+
+/* For IInternetSecurityManager zone check */
+#include <objbase.h>
+#include <urlmon.h>
+
+#define WIDEN2(s) L ## s
+#define WIDEN(s) WIDEN2(s)
+
+#define MAX_CONTENT_TYPE_LEN	100
+#define WINHTTP_OPTION_PEERDIST_EXTENSION_STATE	109
+#define CACHED_POST_BODY_BUF_SIZE	4096
+#define UUID_LENGTH_CCH	32
+#define TIMEOUT_INFINITE -1
+#define DEFAULT_CONNECT_TIMEOUT 60000
+#ifndef WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH
+#define WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH 0
+#endif
+
+static const char *prefix_https = "https://";
+static const char *upload_pack_service = "upload-pack";
+static const char *upload_pack_ls_service_url = "/info/refs?service=git-upload-pack";
+static const char *upload_pack_service_url = "/git-upload-pack";
+static const char *receive_pack_service = "receive-pack";
+static const char *receive_pack_ls_service_url = "/info/refs?service=git-receive-pack";
+static const char *receive_pack_service_url = "/git-receive-pack";
+static const wchar_t *get_verb = L"GET";
+static const wchar_t *post_verb = L"POST";
+static const wchar_t *pragma_nocache = L"Pragma: no-cache";
+static const wchar_t *transfer_encoding = L"Transfer-Encoding: chunked";
+static const int no_check_cert_flags = SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
+	SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |
+	SECURITY_FLAG_IGNORE_UNKNOWN_CA;
+
+#if defined(__MINGW32__)
+const CLSID CLSID_InternetSecurityManager = { 0x7B8A2D94, 0x0AC9, 0x11D1,
+	{ 0x89, 0x6C, 0x00, 0xC0, 0x4F, 0xB6, 0xBF, 0xC4 } };
+const IID IID_IInternetSecurityManager = { 0x79EAC9EE, 0xBAF9, 0x11CE,
+	{ 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B } };
+#endif
+
+#define OWNING_SUBTRANSPORT(s) ((winhttp_subtransport *)(s)->parent.subtransport)
+
+typedef enum {
+	GIT_WINHTTP_AUTH_BASIC = 1,
+	GIT_WINHTTP_AUTH_NEGOTIATE = 2,
+} winhttp_authmechanism_t;
+
+typedef struct {
+	git_smart_subtransport_stream parent;
+	const char *service;
+	const char *service_url;
+	const wchar_t *verb;
+	HINTERNET request;
+	wchar_t *request_uri;
+	char *chunk_buffer;
+	unsigned chunk_buffer_len;
+	HANDLE post_body;
+	DWORD post_body_len;
+	unsigned sent_request : 1,
+		received_response : 1,
+		chunked : 1;
+} winhttp_stream;
+
+typedef struct {
+	git_smart_subtransport parent;
+	transport_smart *owner;
+	gitno_connection_data connection_data;
+	git_cred *cred;
+	git_cred *url_cred;
+	int auth_mechanism;
+	HINTERNET session;
+	HINTERNET connection;
+} winhttp_subtransport;
+
+static int apply_basic_credential(HINTERNET request, git_cred *cred)
+{
+	git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
+	git_buf buf = GIT_BUF_INIT, raw = GIT_BUF_INIT;
+	wchar_t *wide = NULL;
+	int error = -1, wide_len;
+
+	git_buf_printf(&raw, "%s:%s", c->username, c->password);
+
+	if (git_buf_oom(&raw) ||
+		git_buf_puts(&buf, "Authorization: Basic ") < 0 ||
+		git_buf_encode_base64(&buf, git_buf_cstr(&raw), raw.size) < 0)
+		goto on_error;
+
+	if ((wide_len = git__utf8_to_16_alloc(&wide, git_buf_cstr(&buf))) < 0) {
+		giterr_set(GITERR_OS, "Failed to convert string to wide form");
+		goto on_error;
+	}
+
+	if (!WinHttpAddRequestHeaders(request, wide, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) {
+		giterr_set(GITERR_OS, "Failed to add a header to the request");
+		goto on_error;
+	}
+
+	error = 0;
+
+on_error:
+	/* We were dealing with plaintext passwords, so clean up after ourselves a bit. */
+	if (wide)
+		memset(wide, 0x0, wide_len * sizeof(wchar_t));
+
+	if (buf.size)
+		memset(buf.ptr, 0x0, buf.size);
+
+	if (raw.size)
+		memset(raw.ptr, 0x0, raw.size);
+
+	git__free(wide);
+	git_buf_free(&buf);
+	git_buf_free(&raw);
+	return error;
+}
+
+static int apply_default_credentials(HINTERNET request)
+{
+	/* Either the caller explicitly requested that default credentials be passed,
+	 * or our fallback credential callback was invoked and checked that the target
+	 * URI was in the appropriate Internet Explorer security zone. By setting this
+	 * flag, we guarantee that the credentials are delivered by WinHTTP. The default
+	 * is "medium" which applies to the intranet and sounds like it would correspond
+	 * to Internet Explorer security zones, but in fact does not. */
+	DWORD data = WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW;
+
+	if (!WinHttpSetOption(request, WINHTTP_OPTION_AUTOLOGON_POLICY, &data, sizeof(DWORD)))
+		return -1;
+
+	return 0;
+}
+
+static int fallback_cred_acquire_cb(
+	git_cred **cred,
+	const char *url,
+	const char *username_from_url,
+	unsigned int allowed_types,
+	void *payload)
+{
+	int error = 1;
+
+	GIT_UNUSED(username_from_url);
+	GIT_UNUSED(payload);
+
+	/* If the target URI supports integrated Windows authentication
+	 * as an authentication mechanism */
+	if (GIT_CREDTYPE_DEFAULT & allowed_types) {
+		wchar_t *wide_url;
+
+		/* Convert URL to wide characters */
+		if (git__utf8_to_16_alloc(&wide_url, url) < 0) {
+			giterr_set(GITERR_OS, "Failed to convert string to wide form");
+			return -1;
+		}
+
+		if (SUCCEEDED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) {
+			IInternetSecurityManager* pISM;
+
+			/* And if the target URI is in the My Computer, Intranet, or Trusted zones */
+			if (SUCCEEDED(CoCreateInstance(&CLSID_InternetSecurityManager, NULL,
+				CLSCTX_ALL, &IID_IInternetSecurityManager, (void **)&pISM))) {
+				DWORD dwZone;
+
+				if (SUCCEEDED(pISM->lpVtbl->MapUrlToZone(pISM, wide_url, &dwZone, 0)) &&
+					(URLZONE_LOCAL_MACHINE == dwZone ||
+					URLZONE_INTRANET == dwZone ||
+					URLZONE_TRUSTED == dwZone)) {
+					git_cred *existing = *cred;
+
+					if (existing)
+						existing->free(existing);
+
+					/* Then use default Windows credentials to authenticate this request */
+					error = git_cred_default_new(cred);
+				}
+
+				pISM->lpVtbl->Release(pISM);
+			}
+
+			CoUninitialize();
+		}
+
+		git__free(wide_url);
+	}
+
+	return error;
+}
+
+static int certificate_check(winhttp_stream *s, int valid)
+{
+	int error;
+	winhttp_subtransport *t = OWNING_SUBTRANSPORT(s);
+	PCERT_CONTEXT cert_ctx;
+	DWORD cert_ctx_size = sizeof(cert_ctx);
+	git_cert_x509 cert;
+
+	/* If there is no override, we should fail if WinHTTP doesn't think it's fine */
+	if (t->owner->certificate_check_cb == NULL && !valid)
+		return GIT_ECERTIFICATE;
+
+	if (t->owner->certificate_check_cb == NULL || !t->connection_data.use_ssl)
+		return 0;
+
+	if (!WinHttpQueryOption(s->request, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert_ctx, &cert_ctx_size)) {
+		giterr_set(GITERR_OS, "failed to get server certificate");
+		return -1;
+	}
+
+	giterr_clear();
+	cert.cert_type = GIT_CERT_X509;
+	cert.data = cert_ctx->pbCertEncoded;
+	cert.len = cert_ctx->cbCertEncoded;
+	error = t->owner->certificate_check_cb((git_cert *) &cert, valid, t->connection_data.host, t->owner->cred_acquire_payload);
+	CertFreeCertificateContext(cert_ctx);
+
+	if (error < 0 && !giterr_last())
+		giterr_set(GITERR_NET, "user cancelled certificate check");
+
+	return error;
+}
+
+static void winhttp_stream_close(winhttp_stream *s)
+{
+	if (s->chunk_buffer) {
+		git__free(s->chunk_buffer);
+		s->chunk_buffer = NULL;
+	}
+
+	if (s->post_body) {
+		CloseHandle(s->post_body);
+		s->post_body = NULL;
+	}
+
+	if (s->request_uri) {
+		git__free(s->request_uri);
+		s->request_uri = NULL;
+	}
+
+	if (s->request) {
+		WinHttpCloseHandle(s->request);
+		s->request = NULL;
+	}
+
+	s->sent_request = 0;
+}
+
+static int winhttp_stream_connect(winhttp_stream *s)
+{
+	winhttp_subtransport *t = OWNING_SUBTRANSPORT(s);
+	git_buf buf = GIT_BUF_INIT;
+	char *proxy_url = NULL;
+	wchar_t ct[MAX_CONTENT_TYPE_LEN];
+	LPCWSTR types[] = { L"*/*", NULL };
+	BOOL peerdist = FALSE;
+	int error = -1;
+	unsigned long disable_redirects = WINHTTP_DISABLE_REDIRECTS;
+	int default_timeout = TIMEOUT_INFINITE;
+	int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT;
+
+	/* Prepare URL */
+	git_buf_printf(&buf, "%s%s", t->connection_data.path, s->service_url);
+
+	if (git_buf_oom(&buf))
+		return -1;
+
+	/* Convert URL to wide characters */
+	if (git__utf8_to_16_alloc(&s->request_uri, git_buf_cstr(&buf)) < 0) {
+		giterr_set(GITERR_OS, "Failed to convert string to wide form");
+		goto on_error;
+	}
+
+	/* Establish request */
+	s->request = WinHttpOpenRequest(
+			t->connection,
+			s->verb,
+			s->request_uri,
+			NULL,
+			WINHTTP_NO_REFERER,
+			types,
+			t->connection_data.use_ssl ? WINHTTP_FLAG_SECURE : 0);
+
+	if (!s->request) {
+		giterr_set(GITERR_OS, "Failed to open request");
+		goto on_error;
+	}
+
+	if (!WinHttpSetTimeouts(s->request, default_timeout, default_connect_timeout, default_timeout, default_timeout)) {
+		giterr_set(GITERR_OS, "Failed to set timeouts for WinHTTP");
+		goto on_error;
+	}
+
+	/* Set proxy if necessary */
+	if (git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url) < 0)
+		goto on_error;
+
+	if (proxy_url) {
+		WINHTTP_PROXY_INFO proxy_info;
+		wchar_t *proxy_wide;
+
+		/* Convert URL to wide characters */
+		int proxy_wide_len = git__utf8_to_16_alloc(&proxy_wide, proxy_url);
+
+		if (proxy_wide_len < 0) {
+			giterr_set(GITERR_OS, "Failed to convert string to wide form");
+			goto on_error;
+		}
+
+		/* Strip any trailing forward slash on the proxy URL;
+		 * WinHTTP doesn't like it if one is present */
+		if (proxy_wide_len > 1 && L'/' == proxy_wide[proxy_wide_len - 2])
+			proxy_wide[proxy_wide_len - 2] = L'\0';
+
+		proxy_info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
+		proxy_info.lpszProxy = proxy_wide;
+		proxy_info.lpszProxyBypass = NULL;
+
+		if (!WinHttpSetOption(s->request,
+			WINHTTP_OPTION_PROXY,
+			&proxy_info,
+			sizeof(WINHTTP_PROXY_INFO))) {
+			giterr_set(GITERR_OS, "Failed to set proxy");
+			git__free(proxy_wide);
+			goto on_error;
+		}
+
+		git__free(proxy_wide);
+	}
+
+	/* Disable WinHTTP redirects so we can handle them manually. Why, you ask?
+	 * http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/b2ff8879-ab9f-4218-8f09-16d25dff87ae
+	 */
+	if (!WinHttpSetOption(s->request,
+		WINHTTP_OPTION_DISABLE_FEATURE,
+		&disable_redirects,
+		sizeof(disable_redirects))) {
+			giterr_set(GITERR_OS, "Failed to disable redirects");
+			goto on_error;
+	}
+
+	/* Strip unwanted headers (X-P2P-PeerDist, X-P2P-PeerDistEx) that WinHTTP
+	 * adds itself. This option may not be supported by the underlying
+	 * platform, so we do not error-check it */
+	WinHttpSetOption(s->request,
+		WINHTTP_OPTION_PEERDIST_EXTENSION_STATE,
+		&peerdist,
+		sizeof(peerdist));
+
+	/* Send Pragma: no-cache header */
+	if (!WinHttpAddRequestHeaders(s->request, pragma_nocache, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) {
+		giterr_set(GITERR_OS, "Failed to add a header to the request");
+		goto on_error;
+	}
+
+	if (post_verb == s->verb) {
+		/* Send Content-Type and Accept headers -- only necessary on a POST */
+		git_buf_clear(&buf);
+		if (git_buf_printf(&buf,
+			"Content-Type: application/x-git-%s-request",
+			s->service) < 0)
+			goto on_error;
+
+		if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) {
+			giterr_set(GITERR_OS, "Failed to convert content-type to wide characters");
+			goto on_error;
+		}
+
+		if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L,
+			WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) {
+			giterr_set(GITERR_OS, "Failed to add a header to the request");
+			goto on_error;
+		}
+
+		git_buf_clear(&buf);
+		if (git_buf_printf(&buf,
+			"Accept: application/x-git-%s-result",
+			s->service) < 0)
+			goto on_error;
+
+		if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) {
+			giterr_set(GITERR_OS, "Failed to convert accept header to wide characters");
+			goto on_error;
+		}
+
+		if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L,
+			WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) {
+			giterr_set(GITERR_OS, "Failed to add a header to the request");
+			goto on_error;
+		}
+	}
+
+	/* If requested, disable certificate validation */
+	if (t->connection_data.use_ssl) {
+		int flags;
+
+		if (t->owner->parent.read_flags(&t->owner->parent, &flags) < 0)
+			goto on_error;
+	}
+
+	/* If we have a credential on the subtransport, apply it to the request */
+	if (t->cred &&
+		t->cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT &&
+		t->auth_mechanism == GIT_WINHTTP_AUTH_BASIC &&
+		apply_basic_credential(s->request, t->cred) < 0)
+		goto on_error;
+	else if (t->cred &&
+		t->cred->credtype == GIT_CREDTYPE_DEFAULT &&
+		t->auth_mechanism == GIT_WINHTTP_AUTH_NEGOTIATE &&
+		apply_default_credentials(s->request) < 0)
+		goto on_error;
+
+	/* If no other credentials have been applied and the URL has username and
+	 * password, use those */
+	if (!t->cred && t->connection_data.user && t->connection_data.pass) {
+		if (!t->url_cred &&
+			git_cred_userpass_plaintext_new(&t->url_cred, t->connection_data.user, t->connection_data.pass) < 0)
+			goto on_error;
+		if (apply_basic_credential(s->request, t->url_cred) < 0)
+			goto on_error;
+	}
+
+	/* We've done everything up to calling WinHttpSendRequest. */
+
+	error = 0;
+
+on_error:
+	if (error < 0)
+		winhttp_stream_close(s);
+
+	git__free(proxy_url);
+	git_buf_free(&buf);
+	return error;
+}
+
+static int parse_unauthorized_response(
+	HINTERNET request,
+	int *allowed_types,
+	int *auth_mechanism)
+{
+	DWORD supported, first, target;
+
+	*allowed_types = 0;
+	*auth_mechanism = 0;
+
+	/* WinHttpQueryHeaders() must be called before WinHttpQueryAuthSchemes(). 
+	 * We can assume this was already done, since we know we are unauthorized. 
+	 */
+	if (!WinHttpQueryAuthSchemes(request, &supported, &first, &target)) {
+		giterr_set(GITERR_OS, "Failed to parse supported auth schemes"); 
+		return -1;
+	}
+
+	if (WINHTTP_AUTH_SCHEME_BASIC & supported) {
+		*allowed_types |= GIT_CREDTYPE_USERPASS_PLAINTEXT;
+		*auth_mechanism = GIT_WINHTTP_AUTH_BASIC;
+	}
+
+	if ((WINHTTP_AUTH_SCHEME_NTLM & supported) ||
+		(WINHTTP_AUTH_SCHEME_NEGOTIATE & supported)) {
+		*allowed_types |= GIT_CREDTYPE_DEFAULT;
+		*auth_mechanism = GIT_WINHTTP_AUTH_NEGOTIATE;
+	}
+
+	return 0;
+}
+
+static int write_chunk(HINTERNET request, const char *buffer, size_t len)
+{
+	DWORD bytes_written;
+	git_buf buf = GIT_BUF_INIT;
+
+	/* Chunk header */
+	git_buf_printf(&buf, "%X\r\n", len);
+
+	if (git_buf_oom(&buf))
+		return -1;
+
+	if (!WinHttpWriteData(request,
+		git_buf_cstr(&buf),	(DWORD)git_buf_len(&buf),
+		&bytes_written)) {
+		git_buf_free(&buf);
+		giterr_set(GITERR_OS, "Failed to write chunk header");
+		return -1;
+	}
+
+	git_buf_free(&buf);
+
+	/* Chunk body */
+	if (!WinHttpWriteData(request,
+		buffer, (DWORD)len,
+		&bytes_written)) {
+		giterr_set(GITERR_OS, "Failed to write chunk");
+		return -1;
+	}
+
+	/* Chunk footer */
+	if (!WinHttpWriteData(request,
+		"\r\n", 2,
+		&bytes_written)) {
+		giterr_set(GITERR_OS, "Failed to write chunk footer");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int winhttp_close_connection(winhttp_subtransport *t)
+{
+	int ret = 0;
+
+	if (t->connection) {
+		if (!WinHttpCloseHandle(t->connection)) {
+			giterr_set(GITERR_OS, "Unable to close connection");
+			ret = -1;
+		}
+
+		t->connection = NULL;
+	}
+
+	if (t->session) {
+		if (!WinHttpCloseHandle(t->session)) {
+			giterr_set(GITERR_OS, "Unable to close session");
+			ret = -1;
+		}
+
+		t->session = NULL;
+	}
+
+	return ret;
+}
+
+static int winhttp_connect(
+	winhttp_subtransport *t)
+{
+	wchar_t *ua = L"git/1.0 (libgit2 " WIDEN(LIBGIT2_VERSION) L")";
+	wchar_t *wide_host;
+	int32_t port;
+	int error = -1;
+	int default_timeout = TIMEOUT_INFINITE;
+	int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT;
+
+	t->session = NULL;
+	t->connection = NULL;
+
+	/* Prepare port */
+	if (git__strtol32(&port, t->connection_data.port, NULL, 10) < 0)
+		return -1;
+
+	/* Prepare host */
+	if (git__utf8_to_16_alloc(&wide_host, t->connection_data.host) < 0) {
+		giterr_set(GITERR_OS, "Unable to convert host to wide characters");
+		return -1;
+	}
+
+	/* Establish session */
+	t->session = WinHttpOpen(
+		ua,
+		WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
+		WINHTTP_NO_PROXY_NAME,
+		WINHTTP_NO_PROXY_BYPASS,
+		0);
+
+	if (!t->session) {
+		giterr_set(GITERR_OS, "Failed to init WinHTTP");
+		goto on_error;
+	}
+
+	if (!WinHttpSetTimeouts(t->session, default_timeout, default_connect_timeout, default_timeout, default_timeout)) {
+		giterr_set(GITERR_OS, "Failed to set timeouts for WinHTTP");
+		goto on_error;
+	}
+
+	
+	/* Establish connection */
+	t->connection = WinHttpConnect(
+		t->session,
+		wide_host,
+		(INTERNET_PORT) port,
+		0);
+
+	if (!t->connection) {
+		giterr_set(GITERR_OS, "Failed to connect to host");
+		goto on_error;
+	}
+
+	error = 0;
+
+on_error:
+	if (error < 0)
+		winhttp_close_connection(t);
+
+	git__free(wide_host);
+
+	return error;
+}
+
+static int do_send_request(winhttp_stream *s, size_t len, int ignore_length)
+{
+	if (ignore_length) {
+		if (!WinHttpSendRequest(s->request,
+			WINHTTP_NO_ADDITIONAL_HEADERS, 0,
+			WINHTTP_NO_REQUEST_DATA, 0,
+			WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, 0)) {
+			return -1;
+		}
+	} else {
+		if (!WinHttpSendRequest(s->request,
+			WINHTTP_NO_ADDITIONAL_HEADERS, 0,
+			WINHTTP_NO_REQUEST_DATA, 0,
+			len, 0)) {
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int send_request(winhttp_stream *s, size_t len, int ignore_length)
+{
+	int request_failed = 0, cert_valid = 1, error = 0;
+	DWORD ignore_flags;
+
+	if ((error = do_send_request(s, len, ignore_length)) < 0)
+		request_failed = 1;
+
+	if (request_failed) {
+		if (GetLastError() != ERROR_WINHTTP_SECURE_FAILURE) {
+			giterr_set(GITERR_OS, "failed to send request");
+			return -1;
+		} else {
+			cert_valid = 0;
+		}
+	}
+
+	giterr_clear();
+	if ((error = certificate_check(s, cert_valid)) < 0) {
+		if (!giterr_last())
+			giterr_set(GITERR_OS, "user cancelled certificate check");
+
+		return error;
+	}
+
+	/* if neither the request nor the certificate check returned errors, we're done */
+	if (!request_failed)
+		return 0;
+
+	ignore_flags = no_check_cert_flags;
+	
+	if (!WinHttpSetOption(s->request, WINHTTP_OPTION_SECURITY_FLAGS, &ignore_flags, sizeof(ignore_flags))) {
+		giterr_set(GITERR_OS, "failed to set security options");
+		return -1;
+	}
+
+	if ((error = do_send_request(s, len, ignore_length)) < 0)
+		giterr_set(GITERR_OS, "failed to send request");
+
+	return error;
+}
+
+static int winhttp_stream_read(
+	git_smart_subtransport_stream *stream,
+	char *buffer,
+	size_t buf_size,
+	size_t *bytes_read)
+{
+	winhttp_stream *s = (winhttp_stream *)stream;
+	winhttp_subtransport *t = OWNING_SUBTRANSPORT(s);
+	DWORD dw_bytes_read;
+	char replay_count = 0;
+	int error;
+
+replay:
+	/* Enforce a reasonable cap on the number of replays */
+	if (++replay_count >= 7) {
+		giterr_set(GITERR_NET, "Too many redirects or authentication replays");
+		return -1;
+	}
+
+	/* Connect if necessary */
+	if (!s->request && winhttp_stream_connect(s) < 0)
+		return -1;
+
+	if (!s->received_response) {
+		DWORD status_code, status_code_length, content_type_length, bytes_written;
+		char expected_content_type_8[MAX_CONTENT_TYPE_LEN];
+		wchar_t expected_content_type[MAX_CONTENT_TYPE_LEN], content_type[MAX_CONTENT_TYPE_LEN];
+
+		if (!s->sent_request) {
+
+			if ((error = send_request(s, s->post_body_len, 0)) < 0)
+				return error;
+
+			s->sent_request = 1;
+		}
+
+		if (s->chunked) {
+			assert(s->verb == post_verb);
+
+			/* Flush, if necessary */
+			if (s->chunk_buffer_len > 0 &&
+				write_chunk(s->request, s->chunk_buffer, s->chunk_buffer_len) < 0)
+				return -1;
+
+			s->chunk_buffer_len = 0;
+
+			/* Write the final chunk. */
+			if (!WinHttpWriteData(s->request,
+				"0\r\n\r\n", 5,
+				&bytes_written)) {
+				giterr_set(GITERR_OS, "Failed to write final chunk");
+				return -1;
+			}
+		}
+		else if (s->post_body) {
+			char *buffer;
+			DWORD len = s->post_body_len, bytes_read;
+
+			if (INVALID_SET_FILE_POINTER == SetFilePointer(s->post_body,
+					0, 0, FILE_BEGIN) &&
+				NO_ERROR != GetLastError()) {
+				giterr_set(GITERR_OS, "Failed to reset file pointer");
+				return -1;
+			}
+
+			buffer = git__malloc(CACHED_POST_BODY_BUF_SIZE);
+
+			while (len > 0) {
+				DWORD bytes_written;
+
+				if (!ReadFile(s->post_body, buffer,
+					min(CACHED_POST_BODY_BUF_SIZE, len),
+					&bytes_read, NULL) ||
+					!bytes_read) {
+					git__free(buffer);
+					giterr_set(GITERR_OS, "Failed to read from temp file");
+					return -1;
+				}
+
+				if (!WinHttpWriteData(s->request, buffer,
+					bytes_read, &bytes_written)) {
+					git__free(buffer);
+					giterr_set(GITERR_OS, "Failed to write data");
+					return -1;
+				}
+
+				len -= bytes_read;
+				assert(bytes_read == bytes_written);
+			}
+
+			git__free(buffer);
+
+			/* Eagerly close the temp file */
+			CloseHandle(s->post_body);
+			s->post_body = NULL;
+		}
+
+		if (!WinHttpReceiveResponse(s->request, 0)) {
+			giterr_set(GITERR_OS, "Failed to receive response");
+			return -1;
+		}
+
+		/* Verify that we got a 200 back */
+		status_code_length = sizeof(status_code);
+
+		if (!WinHttpQueryHeaders(s->request,
+			WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
+			WINHTTP_HEADER_NAME_BY_INDEX,
+			&status_code, &status_code_length,
+			WINHTTP_NO_HEADER_INDEX)) {
+				giterr_set(GITERR_OS, "Failed to retrieve status code");
+				return -1;
+		}
+
+		/* The implementation of WinHTTP prior to Windows 7 will not
+		 * redirect to an identical URI. Some Git hosters use self-redirects
+		 * as part of their DoS mitigation strategy. Check first to see if we
+		 * have a redirect status code, and that we haven't already streamed
+		 * a post body. (We can't replay a streamed POST.) */
+		if (!s->chunked &&
+			(HTTP_STATUS_MOVED == status_code ||
+			 HTTP_STATUS_REDIRECT == status_code ||
+			 (HTTP_STATUS_REDIRECT_METHOD == status_code &&
+			  get_verb == s->verb) ||
+			 HTTP_STATUS_REDIRECT_KEEP_VERB == status_code)) {
+
+			/* Check for Windows 7. This workaround is only necessary on
+			 * Windows Vista and earlier. Windows 7 is version 6.1. */
+			wchar_t *location;
+			DWORD location_length;
+			char *location8;
+
+			/* OK, fetch the Location header from the redirect. */
+			if (WinHttpQueryHeaders(s->request,
+				WINHTTP_QUERY_LOCATION,
+				WINHTTP_HEADER_NAME_BY_INDEX,
+				WINHTTP_NO_OUTPUT_BUFFER,
+				&location_length,
+				WINHTTP_NO_HEADER_INDEX) ||
+				GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+				giterr_set(GITERR_OS, "Failed to read Location header");
+				return -1;
+			}
+
+			location = git__malloc(location_length);
+			GITERR_CHECK_ALLOC(location);
+
+			if (!WinHttpQueryHeaders(s->request,
+				WINHTTP_QUERY_LOCATION,
+				WINHTTP_HEADER_NAME_BY_INDEX,
+				location,
+				&location_length,
+				WINHTTP_NO_HEADER_INDEX)) {
+				giterr_set(GITERR_OS, "Failed to read Location header");
+				git__free(location);
+				return -1;
+			}
+
+			/* Convert the Location header to UTF-8 */
+			if (git__utf16_to_8_alloc(&location8, location) < 0) {
+				giterr_set(GITERR_OS, "Failed to convert Location header to UTF-8");
+				git__free(location);
+				return -1;
+			}
+
+			git__free(location);
+
+			/* Replay the request */
+			winhttp_stream_close(s);
+
+			if (!git__prefixcmp_icase(location8, prefix_https)) {
+				/* Upgrade to secure connection; disconnect and start over */
+				if (gitno_connection_data_from_url(&t->connection_data, location8, s->service_url) < 0) {
+					git__free(location8);
+					return -1;
+				}
+
+				winhttp_close_connection(t);
+
+				if (winhttp_connect(t) < 0)
+					return -1;
+			}
+
+			git__free(location8);
+			goto replay;
+		}
+
+		/* Handle authentication failures */
+		if (HTTP_STATUS_DENIED == status_code && get_verb == s->verb) {
+			int allowed_types;
+
+			if (parse_unauthorized_response(s->request, &allowed_types, &t->auth_mechanism) < 0)
+				return -1;
+
+			if (allowed_types &&
+				(!t->cred || 0 == (t->cred->credtype & allowed_types))) {
+				int cred_error = 1;
+
+				/* Start with the user-supplied credential callback, if present */
+				if (t->owner->cred_acquire_cb) {
+					cred_error = t->owner->cred_acquire_cb(&t->cred, t->owner->url,
+						t->connection_data.user, allowed_types,	t->owner->cred_acquire_payload);
+
+					if (cred_error < 0)
+						return cred_error;
+				}
+
+				/* Invoke the fallback credentials acquisition callback if necessary */
+				if (cred_error > 0) {
+					cred_error = fallback_cred_acquire_cb(&t->cred, t->owner->url,
+						t->connection_data.user, allowed_types, NULL);
+
+					if (cred_error < 0)
+						return cred_error;
+				}
+
+				if (!cred_error) {
+					assert(t->cred);
+
+					winhttp_stream_close(s);
+
+					/* Successfully acquired a credential */
+					goto replay;
+				}
+			}
+		}
+
+		if (HTTP_STATUS_OK != status_code) {
+			giterr_set(GITERR_NET, "Request failed with status code: %d", status_code);
+			return -1;
+		}
+
+		/* Verify that we got the correct content-type back */
+		if (post_verb == s->verb)
+			p_snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-result", s->service);
+		else
+			p_snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-advertisement", s->service);
+
+		if (git__utf8_to_16(expected_content_type, MAX_CONTENT_TYPE_LEN, expected_content_type_8) < 0) {
+			giterr_set(GITERR_OS, "Failed to convert expected content-type to wide characters");
+			return -1;
+		}
+
+		content_type_length = sizeof(content_type);
+
+		if (!WinHttpQueryHeaders(s->request,
+			WINHTTP_QUERY_CONTENT_TYPE,
+			WINHTTP_HEADER_NAME_BY_INDEX,
+			&content_type, &content_type_length,
+			WINHTTP_NO_HEADER_INDEX)) {
+				giterr_set(GITERR_OS, "Failed to retrieve response content-type");
+				return -1;
+		}
+
+		if (wcscmp(expected_content_type, content_type)) {
+			giterr_set(GITERR_NET, "Received unexpected content-type");
+			return -1;
+		}
+
+		s->received_response = 1;
+	}
+
+	if (!WinHttpReadData(s->request,
+		(LPVOID)buffer,
+		(DWORD)buf_size,
+		&dw_bytes_read))
+	{
+		giterr_set(GITERR_OS, "Failed to read data");
+		return -1;
+	}
+
+	*bytes_read = dw_bytes_read;
+
+	return 0;
+}
+
+static int winhttp_stream_write_single(
+	git_smart_subtransport_stream *stream,
+	const char *buffer,
+	size_t len)
+{
+	winhttp_stream *s = (winhttp_stream *)stream;
+	DWORD bytes_written;
+	int error;
+
+	if (!s->request && winhttp_stream_connect(s) < 0)
+		return -1;
+
+	/* This implementation of write permits only a single call. */
+	if (s->sent_request) {
+		giterr_set(GITERR_NET, "Subtransport configured for only one write");
+		return -1;
+	}
+
+	if ((error = send_request(s, len, 0)) < 0)
+		return error;
+
+	s->sent_request = 1;
+
+	if (!WinHttpWriteData(s->request,
+			(LPCVOID)buffer,
+			(DWORD)len,
+			&bytes_written)) {
+		giterr_set(GITERR_OS, "Failed to write data");
+		return -1;
+	}
+
+	assert((DWORD)len == bytes_written);
+
+	return 0;
+}
+
+static int put_uuid_string(LPWSTR buffer, size_t buffer_len_cch)
+{
+	UUID uuid;
+	RPC_STATUS status = UuidCreate(&uuid);
+	int result;
+
+	if (RPC_S_OK != status &&
+		RPC_S_UUID_LOCAL_ONLY != status &&
+		RPC_S_UUID_NO_ADDRESS != status) {
+		giterr_set(GITERR_NET, "Unable to generate name for temp file");
+		return -1;
+	}
+
+	if (buffer_len_cch < UUID_LENGTH_CCH + 1) {
+		giterr_set(GITERR_NET, "Buffer too small for name of temp file");
+		return -1;
+	}
+
+#if !defined(__MINGW32__) || defined(MINGW_HAS_SECURE_API)
+	result = swprintf_s(buffer, buffer_len_cch,
+#else
+	result = wsprintfW(buffer,
+#endif
+		L"%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x",
+		uuid.Data1, uuid.Data2, uuid.Data3,
+		uuid.Data4[0], uuid.Data4[1], uuid.Data4[2], uuid.Data4[3],
+		uuid.Data4[4], uuid.Data4[5], uuid.Data4[6], uuid.Data4[7]);
+
+	if (result < UUID_LENGTH_CCH) {
+		giterr_set(GITERR_OS, "Unable to generate name for temp file");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int get_temp_file(LPWSTR buffer, DWORD buffer_len_cch)
+{
+	size_t len;
+
+	if (!GetTempPathW(buffer_len_cch, buffer)) {
+		giterr_set(GITERR_OS, "Failed to get temp path");
+		return -1;
+	}
+
+	len = wcslen(buffer);
+
+	if (buffer[len - 1] != '\\' && len < buffer_len_cch)
+		buffer[len++] = '\\';
+
+	if (put_uuid_string(&buffer[len], (size_t)buffer_len_cch - len) < 0)
+		return -1;
+
+	return 0;
+}
+
+static int winhttp_stream_write_buffered(
+	git_smart_subtransport_stream *stream,
+	const char *buffer,
+	size_t len)
+{
+	winhttp_stream *s = (winhttp_stream *)stream;
+	DWORD bytes_written;
+
+	if (!s->request && winhttp_stream_connect(s) < 0)
+		return -1;
+
+	/* Buffer the payload, using a temporary file so we delegate
+	 * memory management of the data to the operating system. */
+	if (!s->post_body) {
+		wchar_t temp_path[MAX_PATH + 1];
+
+		if (get_temp_file(temp_path, MAX_PATH + 1) < 0)
+			return -1;
+
+		s->post_body = CreateFileW(temp_path,
+			GENERIC_READ | GENERIC_WRITE,
+			FILE_SHARE_DELETE, NULL,
+			CREATE_NEW,
+			FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_SEQUENTIAL_SCAN,
+			NULL);
+
+		if (INVALID_HANDLE_VALUE == s->post_body) {
+			s->post_body = NULL;
+			giterr_set(GITERR_OS, "Failed to create temporary file");
+			return -1;
+		}
+	}
+
+	if (!WriteFile(s->post_body, buffer, (DWORD)len, &bytes_written, NULL)) {
+		giterr_set(GITERR_OS, "Failed to write to temporary file");
+		return -1;
+	}
+
+	assert((DWORD)len == bytes_written);
+
+	s->post_body_len += bytes_written;
+
+	return 0;
+}
+
+static int winhttp_stream_write_chunked(
+	git_smart_subtransport_stream *stream,
+	const char *buffer,
+	size_t len)
+{
+	winhttp_stream *s = (winhttp_stream *)stream;
+	int error;
+
+	if (!s->request && winhttp_stream_connect(s) < 0)
+		return -1;
+
+	if (!s->sent_request) {
+		/* Send Transfer-Encoding: chunked header */
+		if (!WinHttpAddRequestHeaders(s->request,
+			transfer_encoding, (ULONG) -1L,
+			WINHTTP_ADDREQ_FLAG_ADD)) {
+			giterr_set(GITERR_OS, "Failed to add a header to the request");
+			return -1;
+		}
+
+		if ((error = send_request(s, 0, 1)) < 0)
+			return error;
+
+		s->sent_request = 1;
+	}
+
+	if (len > CACHED_POST_BODY_BUF_SIZE) {
+		/* Flush, if necessary */
+		if (s->chunk_buffer_len > 0) {
+			if (write_chunk(s->request, s->chunk_buffer, s->chunk_buffer_len) < 0)
+				return -1;
+
+			s->chunk_buffer_len = 0;
+		}
+
+		/* Write chunk directly */
+		if (write_chunk(s->request, buffer, len) < 0)
+			return -1;
+	}
+	else {
+		/* Append as much to the buffer as we can */
+		int count = (int)min(CACHED_POST_BODY_BUF_SIZE - s->chunk_buffer_len, len);
+
+		if (!s->chunk_buffer)
+			s->chunk_buffer = git__malloc(CACHED_POST_BODY_BUF_SIZE);
+
+		memcpy(s->chunk_buffer + s->chunk_buffer_len, buffer, count);
+		s->chunk_buffer_len += count;
+		buffer += count;
+		len -= count;
+
+		/* Is the buffer full? If so, then flush */
+		if (CACHED_POST_BODY_BUF_SIZE == s->chunk_buffer_len) {
+			if (write_chunk(s->request, s->chunk_buffer, s->chunk_buffer_len) < 0)
+				return -1;
+
+			s->chunk_buffer_len = 0;
+
+			/* Is there any remaining data from the source? */
+			if (len > 0) {
+				memcpy(s->chunk_buffer, buffer, len);
+				s->chunk_buffer_len = (unsigned int)len;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static void winhttp_stream_free(git_smart_subtransport_stream *stream)
+{
+	winhttp_stream *s = (winhttp_stream *)stream;
+
+	winhttp_stream_close(s);
+	git__free(s);
+}
+
+static int winhttp_stream_alloc(winhttp_subtransport *t, winhttp_stream **stream)
+{
+	winhttp_stream *s;
+
+	if (!stream)
+		return -1;
+
+	s = git__calloc(1, sizeof(winhttp_stream));
+	GITERR_CHECK_ALLOC(s);
+
+	s->parent.subtransport = &t->parent;
+	s->parent.read = winhttp_stream_read;
+	s->parent.write = winhttp_stream_write_single;
+	s->parent.free = winhttp_stream_free;
+
+	*stream = s;
+
+	return 0;
+}
+
+static int winhttp_uploadpack_ls(
+	winhttp_subtransport *t,
+	winhttp_stream *s)
+{
+	GIT_UNUSED(t);
+
+	s->service = upload_pack_service;
+	s->service_url = upload_pack_ls_service_url;
+	s->verb = get_verb;
+
+	return 0;
+}
+
+static int winhttp_uploadpack(
+	winhttp_subtransport *t,
+	winhttp_stream *s)
+{
+	GIT_UNUSED(t);
+
+	s->service = upload_pack_service;
+	s->service_url = upload_pack_service_url;
+	s->verb = post_verb;
+
+	return 0;
+}
+
+static int winhttp_receivepack_ls(
+	winhttp_subtransport *t,
+	winhttp_stream *s)
+{
+	GIT_UNUSED(t);
+
+	s->service = receive_pack_service;
+	s->service_url = receive_pack_ls_service_url;
+	s->verb = get_verb;
+
+	return 0;
+}
+
+static int winhttp_receivepack(
+	winhttp_subtransport *t,
+	winhttp_stream *s)
+{
+	GIT_UNUSED(t);
+
+	/* WinHTTP only supports Transfer-Encoding: chunked
+	 * on Windows Vista (NT 6.0) and higher. */
+	s->chunked = git_has_win32_version(6, 0, 0);
+
+	if (s->chunked)
+		s->parent.write = winhttp_stream_write_chunked;
+	else
+		s->parent.write = winhttp_stream_write_buffered;
+
+	s->service = receive_pack_service;
+	s->service_url = receive_pack_service_url;
+	s->verb = post_verb;
+
+	return 0;
+}
+
+static int winhttp_action(
+	git_smart_subtransport_stream **stream,
+	git_smart_subtransport *subtransport,
+	const char *url,
+	git_smart_service_t action)
+{
+	winhttp_subtransport *t = (winhttp_subtransport *)subtransport;
+	winhttp_stream *s;
+	int ret = -1;
+
+	if (!t->connection)
+		if ((ret = gitno_connection_data_from_url(&t->connection_data, url, NULL)) < 0 ||
+			 (ret = winhttp_connect(t)) < 0)
+			return ret;
+
+	if (winhttp_stream_alloc(t, &s) < 0)
+		return -1;
+
+	if (!stream)
+		return -1;
+
+	switch (action)
+	{
+		case GIT_SERVICE_UPLOADPACK_LS:
+			ret = winhttp_uploadpack_ls(t, s);
+			break;
+
+		case GIT_SERVICE_UPLOADPACK:
+			ret = winhttp_uploadpack(t, s);
+			break;
+
+		case GIT_SERVICE_RECEIVEPACK_LS:
+			ret = winhttp_receivepack_ls(t, s);
+			break;
+
+		case GIT_SERVICE_RECEIVEPACK:
+			ret = winhttp_receivepack(t, s);
+			break;
+
+		default:
+			assert(0);
+	}
+
+	if (!ret)
+		*stream = &s->parent;
+
+	return ret;
+}
+
+static int winhttp_close(git_smart_subtransport *subtransport)
+{
+	winhttp_subtransport *t = (winhttp_subtransport *)subtransport;
+
+	gitno_connection_data_free_ptrs(&t->connection_data);
+	memset(&t->connection_data, 0x0, sizeof(gitno_connection_data));
+
+	if (t->cred) {
+		t->cred->free(t->cred);
+		t->cred = NULL;
+	}
+
+	if (t->url_cred) {
+		t->url_cred->free(t->url_cred);
+		t->url_cred = NULL;
+	}
+
+	return winhttp_close_connection(t);
+}
+
+static void winhttp_free(git_smart_subtransport *subtransport)
+{
+	winhttp_subtransport *t = (winhttp_subtransport *)subtransport;
+
+	winhttp_close(subtransport);
+
+	git__free(t);
+}
+
+int git_smart_subtransport_http(git_smart_subtransport **out, git_transport *owner, void *param)
+{
+	winhttp_subtransport *t;
+
+	GIT_UNUSED(param);
+
+	if (!out)
+		return -1;
+
+	t = git__calloc(1, sizeof(winhttp_subtransport));
+	GITERR_CHECK_ALLOC(t);
+
+	t->owner = (transport_smart *)owner;
+	t->parent.action = winhttp_action;
+	t->parent.close = winhttp_close;
+	t->parent.free = winhttp_free;
+
+	*out = (git_smart_subtransport *) t;
+	return 0;
+}
+
+#endif /* GIT_WINHTTP */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tree-cache.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tree-cache.c
new file mode 100755
index 0000000..b37be0f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tree-cache.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "tree-cache.h"
+#include "pool.h"
+#include "tree.h"
+
+static git_tree_cache *find_child(
+	const git_tree_cache *tree, const char *path, const char *end)
+{
+	size_t i, dirlen = end ? (size_t)(end - path) : strlen(path);
+
+	for (i = 0; i < tree->children_count; ++i) {
+		git_tree_cache *child = tree->children[i];
+
+		if (child->namelen == dirlen && !memcmp(path, child->name, dirlen))
+			return child;
+	}
+
+	return NULL;
+}
+
+void git_tree_cache_invalidate_path(git_tree_cache *tree, const char *path)
+{
+	const char *ptr = path, *end;
+
+	if (tree == NULL)
+		return;
+
+	tree->entry_count = -1;
+
+	while (ptr != NULL) {
+		end = strchr(ptr, '/');
+
+		if (end == NULL) /* End of path */
+			break;
+
+		tree = find_child(tree, ptr, end);
+		if (tree == NULL) /* We don't have that tree */
+			return;
+
+		tree->entry_count = -1;
+		ptr = end + 1;
+	}
+}
+
+const git_tree_cache *git_tree_cache_get(const git_tree_cache *tree, const char *path)
+{
+	const char *ptr = path, *end;
+
+	if (tree == NULL) {
+		return NULL;
+	}
+
+	while (1) {
+		end = strchr(ptr, '/');
+
+		tree = find_child(tree, ptr, end);
+		if (tree == NULL) /* Can't find it */
+			return NULL;
+
+		if (end == NULL || *end + 1 == '\0')
+			return tree;
+
+		ptr = end + 1;
+	}
+}
+
+static int read_tree_internal(git_tree_cache **out,
+			      const char **buffer_in, const char *buffer_end,
+			      git_pool *pool)
+{
+	git_tree_cache *tree = NULL;
+	const char *name_start, *buffer;
+	int count;
+
+	buffer = name_start = *buffer_in;
+
+	if ((buffer = memchr(buffer, '\0', buffer_end - buffer)) == NULL)
+		goto corrupted;
+
+	if (++buffer >= buffer_end)
+		goto corrupted;
+
+	if (git_tree_cache_new(&tree, name_start, pool) < 0)
+		return -1;
+
+	/* Blank-terminated ASCII decimal number of entries in this tree */
+	if (git__strtol32(&count, buffer, &buffer, 10) < 0)
+		goto corrupted;
+
+	tree->entry_count = count;
+
+	if (*buffer != ' ' || ++buffer >= buffer_end)
+		goto corrupted;
+
+	 /* Number of children of the tree, newline-terminated */
+	if (git__strtol32(&count, buffer, &buffer, 10) < 0 || count < 0)
+		goto corrupted;
+
+	tree->children_count = count;
+
+	if (*buffer != '\n' || ++buffer > buffer_end)
+		goto corrupted;
+
+	/* The SHA1 is only there if it's not invalidated */
+	if (tree->entry_count >= 0) {
+		/* 160-bit SHA-1 for this tree and it's children */
+		if (buffer + GIT_OID_RAWSZ > buffer_end)
+			goto corrupted;
+
+		git_oid_fromraw(&tree->oid, (const unsigned char *)buffer);
+		buffer += GIT_OID_RAWSZ;
+	}
+
+	/* Parse children: */
+	if (tree->children_count > 0) {
+		unsigned int i;
+
+		tree->children = git_pool_malloc(pool, tree->children_count * sizeof(git_tree_cache *));
+		GITERR_CHECK_ALLOC(tree->children);
+
+		memset(tree->children, 0x0, tree->children_count * sizeof(git_tree_cache *));
+
+		for (i = 0; i < tree->children_count; ++i) {
+			if (read_tree_internal(&tree->children[i], &buffer, buffer_end, pool) < 0)
+				goto corrupted;
+		}
+	}
+
+	*buffer_in = buffer;
+	*out = tree;
+	return 0;
+
+ corrupted:
+	giterr_set(GITERR_INDEX, "Corrupted TREE extension in index");
+	return -1;
+}
+
+int git_tree_cache_read(git_tree_cache **tree, const char *buffer, size_t buffer_size, git_pool *pool)
+{
+	const char *buffer_end = buffer + buffer_size;
+
+	if (read_tree_internal(tree, &buffer, buffer_end, pool) < 0)
+		return -1;
+
+	if (buffer < buffer_end) {
+		giterr_set(GITERR_INDEX, "Corrupted TREE extension in index (unexpected trailing data)");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int read_tree_recursive(git_tree_cache *cache, const git_tree *tree, git_pool *pool)
+{
+	git_repository *repo;
+	size_t i, j, nentries, ntrees;
+	int error;
+
+	repo = git_tree_owner(tree);
+
+	git_oid_cpy(&cache->oid, git_tree_id(tree));
+	nentries = git_tree_entrycount(tree);
+
+	/*
+	 * We make sure we know how many trees we need to allocate for
+	 * so we don't have to realloc and change the pointers for the
+	 * parents.
+	 */
+	ntrees = 0;
+	for (i = 0; i < nentries; i++) {
+		const git_tree_entry *entry;
+
+		entry = git_tree_entry_byindex(tree, i);
+		if (git_tree_entry_filemode(entry) == GIT_FILEMODE_TREE)
+			ntrees++;
+	}
+
+	cache->children_count = ntrees;
+	cache->children = git_pool_mallocz(pool, ntrees * sizeof(git_tree_cache *));
+	GITERR_CHECK_ALLOC(cache->children);
+
+	j = 0;
+	for (i = 0; i < nentries; i++) {
+		const git_tree_entry *entry;
+		git_tree *subtree;
+
+		entry = git_tree_entry_byindex(tree, i);
+		if (git_tree_entry_filemode(entry) != GIT_FILEMODE_TREE) {
+			cache->entry_count++;
+			continue;
+		}
+
+		if ((error = git_tree_cache_new(&cache->children[j], git_tree_entry_name(entry), pool)) < 0)
+			return error;
+
+		if ((error = git_tree_lookup(&subtree, repo, git_tree_entry_id(entry))) < 0)
+			return error;
+
+		error = read_tree_recursive(cache->children[j], subtree, pool);
+		git_tree_free(subtree);
+		cache->entry_count += cache->children[j]->entry_count;
+		j++;
+
+		if (error < 0)
+			return error;
+	}
+
+	return 0;
+}
+
+int git_tree_cache_read_tree(git_tree_cache **out, const git_tree *tree, git_pool *pool)
+{
+	int error;
+	git_tree_cache *cache;
+
+	if ((error = git_tree_cache_new(&cache, "", pool)) < 0)
+		return error;
+
+	if ((error = read_tree_recursive(cache, tree, pool)) < 0)
+		return error;
+
+	*out = cache;
+	return 0;
+}
+
+int git_tree_cache_new(git_tree_cache **out, const char *name, git_pool *pool)
+{
+	size_t name_len;
+	git_tree_cache *tree;
+
+	name_len = strlen(name);
+	tree = git_pool_malloc(pool, sizeof(git_tree_cache) + name_len + 1);
+	GITERR_CHECK_ALLOC(tree);
+
+	memset(tree, 0x0, sizeof(git_tree_cache));
+	/* NUL-terminated tree name */
+	tree->namelen = name_len;
+	memcpy(tree->name, name, name_len);
+	tree->name[name_len] = '\0';
+
+	*out = tree;
+	return 0;
+}
+
+static void write_tree(git_buf *out, git_tree_cache *tree)
+{
+	size_t i;
+
+	git_buf_printf(out, "%s%c%"PRIdZ" %"PRIuZ"\n", tree->name, 0, tree->entry_count, tree->children_count);
+
+	if (tree->entry_count != -1)
+		git_buf_put(out, (const char *) &tree->oid, GIT_OID_RAWSZ);
+
+	for (i = 0; i < tree->children_count; i++)
+		write_tree(out, tree->children[i]);
+}
+
+int git_tree_cache_write(git_buf *out, git_tree_cache *tree)
+{
+	write_tree(out, tree);
+
+	return git_buf_oom(out) ? -1 : 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tree-cache.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tree-cache.h
new file mode 100755
index 0000000..c44ca7c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tree-cache.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_tree_cache_h__
+#define INCLUDE_tree_cache_h__
+
+#include "common.h"
+#include "pool.h"
+#include "buffer.h"
+#include "git2/oid.h"
+
+typedef struct git_tree_cache {
+	struct git_tree_cache **children;
+	size_t children_count;
+
+	ssize_t entry_count;
+	git_oid oid;
+	size_t namelen;
+	char name[GIT_FLEX_ARRAY];
+} git_tree_cache;
+
+int git_tree_cache_write(git_buf *out, git_tree_cache *tree);
+int git_tree_cache_read(git_tree_cache **tree, const char *buffer, size_t buffer_size, git_pool *pool);
+void git_tree_cache_invalidate_path(git_tree_cache *tree, const char *path);
+const git_tree_cache *git_tree_cache_get(const git_tree_cache *tree, const char *path);
+int git_tree_cache_new(git_tree_cache **out, const char *name, git_pool *pool);
+/**
+ * Read a tree as the root of the tree cache (like for `git read-tree`)
+ */
+int git_tree_cache_read_tree(git_tree_cache **out, const git_tree *tree, git_pool *pool);
+void git_tree_cache_free(git_tree_cache *tree);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tree.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tree.c
new file mode 100755
index 0000000..bdd1766
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tree.c
@@ -0,0 +1,982 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "commit.h"
+#include "tree.h"
+#include "git2/repository.h"
+#include "git2/object.h"
+#include "fileops.h"
+#include "tree-cache.h"
+#include "index.h"
+
+#define DEFAULT_TREE_SIZE 16
+#define MAX_FILEMODE_BYTES 6
+
+GIT__USE_STRMAP
+
+static bool valid_filemode(const int filemode)
+{
+	return (filemode == GIT_FILEMODE_TREE
+		|| filemode == GIT_FILEMODE_BLOB
+		|| filemode == GIT_FILEMODE_BLOB_EXECUTABLE
+		|| filemode == GIT_FILEMODE_LINK
+		|| filemode == GIT_FILEMODE_COMMIT);
+}
+
+GIT_INLINE(git_filemode_t) normalize_filemode(git_filemode_t filemode)
+{
+	/* Tree bits set, but it's not a commit */
+	if (GIT_MODE_TYPE(filemode) == GIT_FILEMODE_TREE)
+		return GIT_FILEMODE_TREE;
+
+	/* If any of the x bits are set */
+	if (GIT_PERMS_IS_EXEC(filemode))
+		return GIT_FILEMODE_BLOB_EXECUTABLE;
+
+	/* 16XXXX means commit */
+	if (GIT_MODE_TYPE(filemode) == GIT_FILEMODE_COMMIT)
+		return GIT_FILEMODE_COMMIT;
+
+	/* 12XXXX means commit */
+	if (GIT_MODE_TYPE(filemode) == GIT_FILEMODE_LINK)
+		return GIT_FILEMODE_LINK;
+
+	/* Otherwise, return a blob */
+	return GIT_FILEMODE_BLOB;
+}
+
+static int valid_entry_name(git_repository *repo, const char *filename)
+{
+	return *filename != '\0' &&
+		git_path_isvalid(repo, filename,
+		GIT_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT | GIT_PATH_REJECT_SLASH);
+}
+
+static int entry_sort_cmp(const void *a, const void *b)
+{
+	const git_tree_entry *e1 = (const git_tree_entry *)a;
+	const git_tree_entry *e2 = (const git_tree_entry *)b;
+
+	return git_path_cmp(
+		e1->filename, e1->filename_len, git_tree_entry__is_tree(e1),
+		e2->filename, e2->filename_len, git_tree_entry__is_tree(e2),
+		git__strncmp);
+}
+
+int git_tree_entry_cmp(const git_tree_entry *e1, const git_tree_entry *e2)
+{
+	return entry_sort_cmp(e1, e2);
+}
+
+int git_tree_entry_icmp(const git_tree_entry *e1, const git_tree_entry *e2)
+{
+	return git_path_cmp(
+		e1->filename, e1->filename_len, git_tree_entry__is_tree(e1),
+		e2->filename, e2->filename_len, git_tree_entry__is_tree(e2),
+		git__strncasecmp);
+}
+
+static git_tree_entry *alloc_entry(const char *filename)
+{
+	git_tree_entry *entry = NULL;
+	size_t filename_len = strlen(filename), tree_len;
+
+	if (GIT_ADD_SIZET_OVERFLOW(&tree_len, sizeof(git_tree_entry), filename_len) ||
+		GIT_ADD_SIZET_OVERFLOW(&tree_len, tree_len, 1) ||
+		!(entry = git__malloc(tree_len)))
+		return NULL;
+
+	memset(entry, 0x0, sizeof(git_tree_entry));
+	memcpy(entry->filename, filename, filename_len);
+	entry->filename[filename_len] = 0;
+	entry->filename_len = filename_len;
+
+	return entry;
+}
+
+struct tree_key_search {
+	const char *filename;
+	size_t filename_len;
+};
+
+static int homing_search_cmp(const void *key, const void *array_member)
+{
+	const struct tree_key_search *ksearch = key;
+	const git_tree_entry *entry = array_member;
+
+	const size_t len1 = ksearch->filename_len;
+	const size_t len2 = entry->filename_len;
+
+	return memcmp(
+		ksearch->filename,
+		entry->filename,
+		len1 < len2 ? len1 : len2
+	);
+}
+
+/*
+ * Search for an entry in a given tree.
+ *
+ * Note that this search is performed in two steps because
+ * of the way tree entries are sorted internally in git:
+ *
+ * Entries in a tree are not sorted alphabetically; two entries
+ * with the same root prefix will have different positions
+ * depending on whether they are folders (subtrees) or normal files.
+ *
+ * Consequently, it is not possible to find an entry on the tree
+ * with a binary search if you don't know whether the filename
+ * you're looking for is a folder or a normal file.
+ *
+ * To work around this, we first perform a homing binary search
+ * on the tree, using the minimal length root prefix of our filename.
+ * Once the comparisons for this homing search start becoming
+ * ambiguous because of folder vs file sorting, we look linearly
+ * around the area for our target file.
+ */
+static int tree_key_search(
+	size_t *at_pos, git_vector *entries, const char *filename, size_t filename_len)
+{
+	struct tree_key_search ksearch;
+	const git_tree_entry *entry;
+	size_t homing, i;
+
+	ksearch.filename = filename;
+	ksearch.filename_len = filename_len;
+
+	/* Initial homing search; find an entry on the tree with
+	 * the same prefix as the filename we're looking for */
+	if (git_vector_bsearch2(&homing, entries, &homing_search_cmp, &ksearch) < 0)
+		return GIT_ENOTFOUND; /* just a signal error; not passed back to user */
+
+	/* We found a common prefix. Look forward as long as
+	 * there are entries that share the common prefix */
+	for (i = homing; i < entries->length; ++i) {
+		entry = entries->contents[i];
+
+		if (homing_search_cmp(&ksearch, entry) < 0)
+			break;
+
+		if (entry->filename_len == filename_len &&
+			memcmp(filename, entry->filename, filename_len) == 0) {
+			if (at_pos)
+				*at_pos = i;
+
+			return 0;
+		}
+	}
+
+	/* If we haven't found our filename yet, look backwards
+	 * too as long as we have entries with the same prefix */
+	if (homing > 0) {
+		i = homing - 1;
+
+		do {
+			entry = entries->contents[i];
+
+			if (homing_search_cmp(&ksearch, entry) > 0)
+				break;
+
+			if (entry->filename_len == filename_len &&
+				memcmp(filename, entry->filename, filename_len) == 0) {
+				if (at_pos)
+					*at_pos = i;
+
+				return 0;
+			}
+		} while (i-- > 0);
+	}
+
+	/* The filename doesn't exist at all */
+	return GIT_ENOTFOUND;
+}
+
+void git_tree_entry_free(git_tree_entry *entry)
+{
+	if (entry == NULL)
+		return;
+
+	git__free(entry);
+}
+
+int git_tree_entry_dup(git_tree_entry **dest, const git_tree_entry *source)
+{
+	size_t total_size;
+	git_tree_entry *copy;
+
+	assert(source);
+
+	GITERR_CHECK_ALLOC_ADD(&total_size, sizeof(git_tree_entry), source->filename_len);
+	GITERR_CHECK_ALLOC_ADD(&total_size, total_size, 1);
+
+	copy = git__malloc(total_size);
+	GITERR_CHECK_ALLOC(copy);
+
+	memcpy(copy, source, total_size);
+
+	*dest = copy;
+	return 0;
+}
+
+void git_tree__free(void *_tree)
+{
+	git_tree *tree = _tree;
+	size_t i;
+	git_tree_entry *e;
+
+	git_vector_foreach(&tree->entries, i, e)
+		git_tree_entry_free(e);
+
+	git_vector_free(&tree->entries);
+	git__free(tree);
+}
+
+git_filemode_t git_tree_entry_filemode(const git_tree_entry *entry)
+{
+	return normalize_filemode(entry->attr);
+}
+
+git_filemode_t git_tree_entry_filemode_raw(const git_tree_entry *entry)
+{
+	return entry->attr;
+}
+
+const char *git_tree_entry_name(const git_tree_entry *entry)
+{
+	assert(entry);
+	return entry->filename;
+}
+
+const git_oid *git_tree_entry_id(const git_tree_entry *entry)
+{
+	assert(entry);
+	return &entry->oid;
+}
+
+git_otype git_tree_entry_type(const git_tree_entry *entry)
+{
+	assert(entry);
+
+	if (S_ISGITLINK(entry->attr))
+		return GIT_OBJ_COMMIT;
+	else if (S_ISDIR(entry->attr))
+		return GIT_OBJ_TREE;
+	else
+		return GIT_OBJ_BLOB;
+}
+
+int git_tree_entry_to_object(
+	git_object **object_out,
+	git_repository *repo,
+	const git_tree_entry *entry)
+{
+	assert(entry && object_out);
+	return git_object_lookup(object_out, repo, &entry->oid, GIT_OBJ_ANY);
+}
+
+static const git_tree_entry *entry_fromname(
+	const git_tree *tree, const char *name, size_t name_len)
+{
+	size_t idx;
+
+	/* be safe when we cast away constness - i.e. don't trigger a sort */
+	assert(git_vector_is_sorted(&tree->entries));
+
+	if (tree_key_search(&idx, (git_vector *)&tree->entries, name, name_len) < 0)
+		return NULL;
+
+	return git_vector_get(&tree->entries, idx);
+}
+
+const git_tree_entry *git_tree_entry_byname(
+	const git_tree *tree, const char *filename)
+{
+	assert(tree && filename);
+	return entry_fromname(tree, filename, strlen(filename));
+}
+
+const git_tree_entry *git_tree_entry_byindex(
+	const git_tree *tree, size_t idx)
+{
+	assert(tree);
+	return git_vector_get(&tree->entries, idx);
+}
+
+const git_tree_entry *git_tree_entry_byid(
+	const git_tree *tree, const git_oid *id)
+{
+	size_t i;
+	const git_tree_entry *e;
+
+	assert(tree);
+
+	git_vector_foreach(&tree->entries, i, e) {
+		if (memcmp(&e->oid.id, &id->id, sizeof(id->id)) == 0)
+			return e;
+	}
+
+	return NULL;
+}
+
+int git_tree__prefix_position(const git_tree *tree, const char *path)
+{
+	const git_vector *entries = &tree->entries;
+	struct tree_key_search ksearch;
+	size_t at_pos;
+
+	if (!path)
+		return 0;
+
+	ksearch.filename = path;
+	ksearch.filename_len = strlen(path);
+
+	/* be safe when we cast away constness - i.e. don't trigger a sort */
+	assert(git_vector_is_sorted(&tree->entries));
+
+	/* Find tree entry with appropriate prefix */
+	git_vector_bsearch2(
+		&at_pos, (git_vector *)entries, &homing_search_cmp, &ksearch);
+
+	for (; at_pos < entries->length; ++at_pos) {
+		const git_tree_entry *entry = entries->contents[at_pos];
+		if (homing_search_cmp(&ksearch, entry) < 0)
+			break;
+	}
+
+	for (; at_pos > 0; --at_pos) {
+		const git_tree_entry *entry = entries->contents[at_pos - 1];
+		if (homing_search_cmp(&ksearch, entry) > 0)
+			break;
+	}
+
+	return (int)at_pos;
+}
+
+size_t git_tree_entrycount(const git_tree *tree)
+{
+	assert(tree);
+	return tree->entries.length;
+}
+
+unsigned int git_treebuilder_entrycount(git_treebuilder *bld)
+{
+	assert(bld);
+
+	return git_strmap_num_entries(bld->map);
+}
+
+static int tree_error(const char *str, const char *path)
+{
+	if (path)
+		giterr_set(GITERR_TREE, "%s - %s", str, path);
+	else
+		giterr_set(GITERR_TREE, "%s", str);
+	return -1;
+}
+
+int git_tree__parse(void *_tree, git_odb_object *odb_obj)
+{
+	git_tree *tree = _tree;
+	const char *buffer = git_odb_object_data(odb_obj);
+	const char *buffer_end = buffer + git_odb_object_size(odb_obj);
+
+	if (git_vector_init(&tree->entries, DEFAULT_TREE_SIZE, entry_sort_cmp) < 0)
+		return -1;
+
+	while (buffer < buffer_end) {
+		git_tree_entry *entry;
+		int attr;
+
+		if (git__strtol32(&attr, buffer, &buffer, 8) < 0 || !buffer)
+			return tree_error("Failed to parse tree. Can't parse filemode", NULL);
+
+		if (*buffer++ != ' ')
+			return tree_error("Failed to parse tree. Object is corrupted", NULL);
+
+		if (memchr(buffer, 0, buffer_end - buffer) == NULL)
+			return tree_error("Failed to parse tree. Object is corrupted", NULL);
+
+		/** Allocate the entry and store it in the entries vector */
+		{
+			entry = alloc_entry(buffer);
+			GITERR_CHECK_ALLOC(entry);
+
+			if (git_vector_insert(&tree->entries, entry) < 0) {
+				git__free(entry);
+				return -1;
+			}
+
+			entry->attr = attr;
+		}
+
+		while (buffer < buffer_end && *buffer != 0)
+			buffer++;
+
+		buffer++;
+
+		git_oid_fromraw(&entry->oid, (const unsigned char *)buffer);
+		buffer += GIT_OID_RAWSZ;
+	}
+
+	git_vector_sort(&tree->entries);
+
+	return 0;
+}
+
+static size_t find_next_dir(const char *dirname, git_index *index, size_t start)
+{
+	size_t dirlen, i, entries = git_index_entrycount(index);
+
+	dirlen = strlen(dirname);
+	for (i = start; i < entries; ++i) {
+		const git_index_entry *entry = git_index_get_byindex(index, i);
+		if (strlen(entry->path) < dirlen ||
+		    memcmp(entry->path, dirname, dirlen) ||
+			(dirlen > 0 && entry->path[dirlen] != '/')) {
+			break;
+		}
+	}
+
+	return i;
+}
+
+static int append_entry(
+	git_treebuilder *bld,
+	const char *filename,
+	const git_oid *id,
+	git_filemode_t filemode)
+{
+	git_tree_entry *entry;
+	int error = 0;
+
+	if (!valid_entry_name(bld->repo, filename))
+		return tree_error("Failed to insert entry. Invalid name for a tree entry", filename);
+
+	entry = alloc_entry(filename);
+	GITERR_CHECK_ALLOC(entry);
+
+	git_oid_cpy(&entry->oid, id);
+	entry->attr = (uint16_t)filemode;
+
+	git_strmap_insert(bld->map, entry->filename, entry, error);
+	if (error < 0) {
+		git_tree_entry_free(entry);
+		giterr_set(GITERR_TREE, "failed to append entry %s to the tree builder", filename);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int write_tree(
+	git_oid *oid,
+	git_repository *repo,
+	git_index *index,
+	const char *dirname,
+	size_t start)
+{
+	git_treebuilder *bld = NULL;
+	size_t i, entries = git_index_entrycount(index);
+	int error;
+	size_t dirname_len = strlen(dirname);
+	const git_tree_cache *cache;
+
+	cache = git_tree_cache_get(index->tree, dirname);
+	if (cache != NULL && cache->entry_count >= 0){
+		git_oid_cpy(oid, &cache->oid);
+		return (int)find_next_dir(dirname, index, start);
+	}
+
+	if ((error = git_treebuilder_new(&bld, repo, NULL)) < 0 || bld == NULL)
+		return -1;
+
+	/*
+	 * This loop is unfortunate, but necessary. The index doesn't have
+	 * any directores, so we need to handle that manually, and we
+	 * need to keep track of the current position.
+	 */
+	for (i = start; i < entries; ++i) {
+		const git_index_entry *entry = git_index_get_byindex(index, i);
+		const char *filename, *next_slash;
+
+	/*
+	 * If we've left our (sub)tree, exit the loop and return. The
+	 * first check is an early out (and security for the
+	 * third). The second check is a simple prefix comparison. The
+	 * third check catches situations where there is a directory
+	 * win32/sys and a file win32mmap.c. Without it, the following
+	 * code believes there is a file win32/mmap.c
+	 */
+		if (strlen(entry->path) < dirname_len ||
+		    memcmp(entry->path, dirname, dirname_len) ||
+		    (dirname_len > 0 && entry->path[dirname_len] != '/')) {
+			break;
+		}
+
+		filename = entry->path + dirname_len;
+		if (*filename == '/')
+			filename++;
+		next_slash = strchr(filename, '/');
+		if (next_slash) {
+			git_oid sub_oid;
+			int written;
+			char *subdir, *last_comp;
+
+			subdir = git__strndup(entry->path, next_slash - entry->path);
+			GITERR_CHECK_ALLOC(subdir);
+
+			/* Write out the subtree */
+			written = write_tree(&sub_oid, repo, index, subdir, i);
+			if (written < 0) {
+				git__free(subdir);
+				goto on_error;
+			} else {
+				i = written - 1; /* -1 because of the loop increment */
+			}
+
+			/*
+			 * We need to figure out what we want toinsert
+			 * into this tree. If we're traversing
+			 * deps/zlib/, then we only want to write
+			 * 'zlib' into the tree.
+			 */
+			last_comp = strrchr(subdir, '/');
+			if (last_comp) {
+				last_comp++; /* Get rid of the '/' */
+			} else {
+				last_comp = subdir;
+			}
+
+			error = append_entry(bld, last_comp, &sub_oid, S_IFDIR);
+			git__free(subdir);
+			if (error < 0)
+				goto on_error;
+		} else {
+			error = append_entry(bld, filename, &entry->id, entry->mode);
+			if (error < 0)
+				goto on_error;
+		}
+	}
+
+	if (git_treebuilder_write(oid, bld) < 0)
+		goto on_error;
+
+	git_treebuilder_free(bld);
+	return (int)i;
+
+on_error:
+	git_treebuilder_free(bld);
+	return -1;
+}
+
+int git_tree__write_index(
+	git_oid *oid, git_index *index, git_repository *repo)
+{
+	int ret;
+	git_tree *tree;
+	bool old_ignore_case = false;
+
+	assert(oid && index && repo);
+
+	if (git_index_has_conflicts(index)) {
+		giterr_set(GITERR_INDEX,
+			"Cannot create a tree from a not fully merged index.");
+		return GIT_EUNMERGED;
+	}
+
+	if (index->tree != NULL && index->tree->entry_count >= 0) {
+		git_oid_cpy(oid, &index->tree->oid);
+		return 0;
+	}
+
+	/* The tree cache didn't help us; we'll have to write
+	 * out a tree. If the index is ignore_case, we must
+	 * make it case-sensitive for the duration of the tree-write
+	 * operation. */
+
+	if (index->ignore_case) {
+		old_ignore_case = true;
+		git_index__set_ignore_case(index, false);
+	}
+
+	ret = write_tree(oid, repo, index, "", 0);
+
+	if (old_ignore_case)
+		git_index__set_ignore_case(index, true);
+
+	index->tree = NULL;
+
+	if (ret < 0)
+		return ret;
+
+	git_pool_clear(&index->tree_pool);
+
+	if ((ret = git_tree_lookup(&tree, repo, oid)) < 0)
+		return ret;
+
+	/* Read the tree cache into the index */
+	ret = git_tree_cache_read_tree(&index->tree, tree, &index->tree_pool);
+	git_tree_free(tree);
+
+	return ret;
+}
+
+int git_treebuilder_new(
+	git_treebuilder **builder_p,
+	git_repository *repo,
+	const git_tree *source)
+{
+	git_treebuilder *bld;
+	size_t i;
+
+	assert(builder_p && repo);
+
+	bld = git__calloc(1, sizeof(git_treebuilder));
+	GITERR_CHECK_ALLOC(bld);
+
+	bld->repo = repo;
+
+	if (git_strmap_alloc(&bld->map) < 0) {
+		git__free(bld);
+		return -1;
+	}
+
+	if (source != NULL) {
+		git_tree_entry *entry_src;
+
+		git_vector_foreach(&source->entries, i, entry_src) {
+			if (append_entry(
+				bld, entry_src->filename,
+				&entry_src->oid,
+				entry_src->attr) < 0)
+				goto on_error;
+		}
+	}
+
+	*builder_p = bld;
+	return 0;
+
+on_error:
+	git_treebuilder_free(bld);
+	return -1;
+}
+
+int git_treebuilder_insert(
+	const git_tree_entry **entry_out,
+	git_treebuilder *bld,
+	const char *filename,
+	const git_oid *id,
+	git_filemode_t filemode)
+{
+	git_tree_entry *entry;
+	int error;
+	git_strmap_iter pos;
+
+	assert(bld && id && filename);
+
+	if (!valid_filemode(filemode))
+		return tree_error("Failed to insert entry. Invalid filemode for file", filename);
+
+	if (!valid_entry_name(bld->repo, filename))
+		return tree_error("Failed to insert entry. Invalid name for a tree entry", filename);
+
+	pos = git_strmap_lookup_index(bld->map, filename);
+	if (git_strmap_valid_index(bld->map, pos)) {
+		entry = git_strmap_value_at(bld->map, pos);
+	} else {
+		entry = alloc_entry(filename);
+		GITERR_CHECK_ALLOC(entry);
+
+		git_strmap_insert(bld->map, entry->filename, entry, error);
+
+		if (error < 0) {
+			git_tree_entry_free(entry);
+			giterr_set(GITERR_TREE, "failed to insert %s", filename);
+			return -1;
+		}
+	}
+
+	git_oid_cpy(&entry->oid, id);
+	entry->attr = filemode;
+
+	if (entry_out)
+		*entry_out = entry;
+
+	return 0;
+}
+
+static git_tree_entry *treebuilder_get(git_treebuilder *bld, const char *filename)
+{
+	git_tree_entry *entry = NULL;
+	git_strmap_iter pos;
+
+	assert(bld && filename);
+
+	pos = git_strmap_lookup_index(bld->map, filename);
+	if (git_strmap_valid_index(bld->map, pos))
+		entry = git_strmap_value_at(bld->map, pos);
+
+	return entry;
+}
+
+const git_tree_entry *git_treebuilder_get(git_treebuilder *bld, const char *filename)
+{
+	return treebuilder_get(bld, filename);
+}
+
+int git_treebuilder_remove(git_treebuilder *bld, const char *filename)
+{
+	git_tree_entry *entry = treebuilder_get(bld, filename);
+
+	if (entry == NULL)
+		return tree_error("Failed to remove entry. File isn't in the tree", filename);
+
+	git_strmap_delete(bld->map, filename);
+	git_tree_entry_free(entry);
+
+	return 0;
+}
+
+int git_treebuilder_write(git_oid *oid, git_treebuilder *bld)
+{
+	int error = 0;
+	size_t i, entrycount;
+	git_buf tree = GIT_BUF_INIT;
+	git_odb *odb;
+	git_tree_entry *entry;
+	git_vector entries;
+
+	assert(bld);
+
+	entrycount = git_strmap_num_entries(bld->map);
+	if (git_vector_init(&entries, entrycount, entry_sort_cmp) < 0)
+		return -1;
+
+	git_strmap_foreach_value(bld->map, entry, {
+		if (git_vector_insert(&entries, entry) < 0)
+			return -1;
+	});
+
+	git_vector_sort(&entries);
+
+	/* Grow the buffer beforehand to an estimated size */
+	error = git_buf_grow(&tree, entrycount * 72);
+
+	for (i = 0; i < entries.length && !error; ++i) {
+		git_tree_entry *entry = git_vector_get(&entries, i);
+
+		git_buf_printf(&tree, "%o ", entry->attr);
+		git_buf_put(&tree, entry->filename, entry->filename_len + 1);
+		git_buf_put(&tree, (char *)entry->oid.id, GIT_OID_RAWSZ);
+
+		if (git_buf_oom(&tree))
+			error = -1;
+	}
+
+	git_vector_free(&entries);
+
+	if (!error &&
+		!(error = git_repository_odb__weakptr(&odb, bld->repo)))
+		error = git_odb_write(oid, odb, tree.ptr, tree.size, GIT_OBJ_TREE);
+
+	git_buf_free(&tree);
+	return error;
+}
+
+void git_treebuilder_filter(
+	git_treebuilder *bld,
+	git_treebuilder_filter_cb filter,
+	void *payload)
+{
+	const char *filename;
+	git_tree_entry *entry;
+
+	assert(bld && filter);
+
+	git_strmap_foreach(bld->map, filename, entry, {
+			if (filter(entry, payload)) {
+				git_strmap_delete(bld->map, filename);
+				git_tree_entry_free(entry);
+			}
+	});
+}
+
+void git_treebuilder_clear(git_treebuilder *bld)
+{
+	git_tree_entry *e;
+
+	assert(bld);
+
+	git_strmap_foreach_value(bld->map, e, git_tree_entry_free(e));
+	git_strmap_clear(bld->map);
+}
+
+void git_treebuilder_free(git_treebuilder *bld)
+{
+	if (bld == NULL)
+		return;
+
+	git_treebuilder_clear(bld);
+	git_strmap_free(bld->map);
+	git__free(bld);
+}
+
+static size_t subpath_len(const char *path)
+{
+	const char *slash_pos = strchr(path, '/');
+	if (slash_pos == NULL)
+		return strlen(path);
+
+	return slash_pos - path;
+}
+
+int git_tree_entry_bypath(
+	git_tree_entry **entry_out,
+	const git_tree *root,
+	const char *path)
+{
+	int error = 0;
+	git_tree *subtree;
+	const git_tree_entry *entry;
+	size_t filename_len;
+
+	/* Find how long is the current path component (i.e.
+	 * the filename between two slashes */
+	filename_len = subpath_len(path);
+
+	if (filename_len == 0) {
+		giterr_set(GITERR_TREE, "Invalid tree path given");
+		return GIT_ENOTFOUND;
+	}
+
+	entry = entry_fromname(root, path, filename_len);
+
+	if (entry == NULL) {
+		giterr_set(GITERR_TREE,
+			   "the path '%.*s' does not exist in the given tree", filename_len, path);
+		return GIT_ENOTFOUND;
+	}
+
+	switch (path[filename_len]) {
+	case '/':
+		/* If there are more components in the path...
+		 * then this entry *must* be a tree */
+		if (!git_tree_entry__is_tree(entry)) {
+			giterr_set(GITERR_TREE,
+				   "the path '%.*s' exists but is not a tree", filename_len, path);
+			return GIT_ENOTFOUND;
+		}
+
+		/* If there's only a slash left in the path, we 
+		 * return the current entry; otherwise, we keep
+		 * walking down the path */
+		if (path[filename_len + 1] != '\0')
+			break;
+
+	case '\0':
+		/* If there are no more components in the path, return
+		 * this entry */
+		return git_tree_entry_dup(entry_out, entry);
+	}
+
+	if (git_tree_lookup(&subtree, root->object.repo, &entry->oid) < 0)
+		return -1;
+
+	error = git_tree_entry_bypath(
+		entry_out,
+		subtree,
+		path + filename_len + 1
+	);
+
+	git_tree_free(subtree);
+	return error;
+}
+
+static int tree_walk(
+	const git_tree *tree,
+	git_treewalk_cb callback,
+	git_buf *path,
+	void *payload,
+	bool preorder)
+{
+	int error = 0;
+	size_t i;
+	const git_tree_entry *entry;
+
+	git_vector_foreach(&tree->entries, i, entry) {
+		if (preorder) {
+			error = callback(path->ptr, entry, payload);
+			if (error < 0) { /* negative value stops iteration */
+				giterr_set_after_callback_function(error, "git_tree_walk");
+				break;
+			}
+			if (error > 0) { /* positive value skips this entry */
+				error = 0;
+				continue;
+			}
+		}
+
+		if (git_tree_entry__is_tree(entry)) {
+			git_tree *subtree;
+			size_t path_len = git_buf_len(path);
+
+			error = git_tree_lookup(&subtree, tree->object.repo, &entry->oid);
+			if (error < 0)
+				break;
+
+			/* append the next entry to the path */
+			git_buf_puts(path, entry->filename);
+			git_buf_putc(path, '/');
+
+			if (git_buf_oom(path))
+				error = -1;
+			else
+				error = tree_walk(subtree, callback, path, payload, preorder);
+
+			git_tree_free(subtree);
+			if (error != 0)
+				break;
+
+			git_buf_truncate(path, path_len);
+		}
+
+		if (!preorder) {
+			error = callback(path->ptr, entry, payload);
+			if (error < 0) { /* negative value stops iteration */
+				giterr_set_after_callback_function(error, "git_tree_walk");
+				break;
+			}
+			error = 0;
+		}
+	}
+
+	return error;
+}
+
+int git_tree_walk(
+	const git_tree *tree,
+	git_treewalk_mode mode,
+	git_treewalk_cb callback,
+	void *payload)
+{
+	int error = 0;
+	git_buf root_path = GIT_BUF_INIT;
+
+	if (mode != GIT_TREEWALK_POST && mode != GIT_TREEWALK_PRE) {
+		giterr_set(GITERR_INVALID, "Invalid walking mode for tree walk");
+		return -1;
+	}
+
+	error = tree_walk(
+		tree, callback, &root_path, payload, (mode == GIT_TREEWALK_PRE));
+
+	git_buf_free(&root_path);
+
+	return error;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tree.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tree.h
new file mode 100755
index 0000000..d01b6fd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tree.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_tree_h__
+#define INCLUDE_tree_h__
+
+#include "git2/tree.h"
+#include "repository.h"
+#include "odb.h"
+#include "vector.h"
+#include "strmap.h"
+
+struct git_tree_entry {
+	uint16_t attr;
+	git_oid oid;
+	size_t filename_len;
+	char filename[1];
+};
+
+struct git_tree {
+	git_object object;
+	git_vector entries;
+};
+
+struct git_treebuilder {
+	git_repository *repo;
+	git_strmap *map;
+};
+
+GIT_INLINE(bool) git_tree_entry__is_tree(const struct git_tree_entry *e)
+{
+	return (S_ISDIR(e->attr) && !S_ISGITLINK(e->attr));
+}
+
+extern int git_tree_entry_icmp(const git_tree_entry *e1, const git_tree_entry *e2);
+
+void git_tree__free(void *tree);
+int git_tree__parse(void *tree, git_odb_object *obj);
+
+/**
+ * Lookup the first position in the tree with a given prefix.
+ *
+ * @param tree a previously loaded tree.
+ * @param prefix the beginning of a path to find in the tree.
+ * @return index of the first item at or after the given prefix.
+ */
+int git_tree__prefix_position(const git_tree *tree, const char *prefix);
+
+
+/**
+ * Write a tree to the given repository
+ */
+int git_tree__write_index(
+	git_oid *oid, git_index *index, git_repository *repo);
+
+/**
+ * Obsolete mode kept for compatibility reasons
+ */
+#define GIT_FILEMODE_BLOB_GROUP_WRITABLE 0100664
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tsort.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tsort.c
new file mode 100755
index 0000000..e598192
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/tsort.c
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+
+/**
+ * An array-of-pointers implementation of Python's Timsort
+ * Based on code by Christopher Swenson under the MIT license
+ *
+ * Copyright (c) 2010 Christopher Swenson
+ * Copyright (c) 2011 Vicent Marti
+ */
+
+#ifndef MAX
+#	define MAX(x,y) (((x) > (y) ? (x) : (y)))
+#endif
+
+#ifndef MIN
+#	define MIN(x,y) (((x) < (y) ? (x) : (y)))
+#endif
+
+static int binsearch(
+	void **dst, const void *x, size_t size, git__sort_r_cmp cmp, void *payload)
+{
+	int l, c, r;
+	void *lx, *cx;
+
+	assert(size > 0);
+
+	l = 0;
+	r = (int)size - 1;
+	c = r >> 1;
+	lx = dst[l];
+
+	/* check for beginning conditions */
+	if (cmp(x, lx, payload) < 0)
+		return 0;
+
+	else if (cmp(x, lx, payload) == 0) {
+		int i = 1;
+		while (cmp(x, dst[i], payload) == 0)
+			i++;
+		return i;
+	}
+
+	/* guaranteed not to be >= rx */
+	cx = dst[c];
+	while (1) {
+		const int val = cmp(x, cx, payload);
+		if (val < 0) {
+			if (c - l <= 1) return c;
+			r = c;
+		} else if (val > 0) {
+			if (r - c <= 1) return c + 1;
+			l = c;
+			lx = cx;
+		} else {
+			do {
+				cx = dst[++c];
+			} while (cmp(x, cx, payload) == 0);
+			return c;
+		}
+		c = l + ((r - l) >> 1);
+		cx = dst[c];
+	}
+}
+
+/* Binary insertion sort, but knowing that the first "start" entries are sorted. Used in timsort. */
+static void bisort(
+	void **dst, size_t start, size_t size, git__sort_r_cmp cmp, void *payload)
+{
+	size_t i;
+	void *x;
+	int location;
+
+	for (i = start; i < size; i++) {
+		int j;
+		/* If this entry is already correct, just move along */
+		if (cmp(dst[i - 1], dst[i], payload) <= 0)
+			continue;
+
+		/* Else we need to find the right place, shift everything over, and squeeze in */
+		x = dst[i];
+		location = binsearch(dst, x, i, cmp, payload);
+		for (j = (int)i - 1; j >= location; j--) {
+			dst[j + 1] = dst[j];
+		}
+		dst[location] = x;
+	}
+}
+
+
+/* timsort implementation, based on timsort.txt */
+struct tsort_run {
+	ssize_t start;
+	ssize_t length;
+};
+
+struct tsort_store {
+	size_t alloc;
+	git__sort_r_cmp cmp;
+	void *payload;
+	void **storage;
+};
+
+static void reverse_elements(void **dst, ssize_t start, ssize_t end)
+{
+	while (start < end) {
+		void *tmp = dst[start];
+		dst[start] = dst[end];
+		dst[end] = tmp;
+
+		start++;
+		end--;
+	}
+}
+
+static ssize_t count_run(
+	void **dst, ssize_t start, ssize_t size, struct tsort_store *store)
+{
+	ssize_t curr = start + 2;
+
+	if (size - start == 1)
+		return 1;
+
+	if (start >= size - 2) {
+		if (store->cmp(dst[size - 2], dst[size - 1], store->payload) > 0) {
+			void *tmp = dst[size - 1];
+			dst[size - 1] = dst[size - 2];
+			dst[size - 2] = tmp;
+		}
+
+		return 2;
+	}
+
+	if (store->cmp(dst[start], dst[start + 1], store->payload) <= 0) {
+		while (curr < size - 1 &&
+				store->cmp(dst[curr - 1], dst[curr], store->payload) <= 0)
+			curr++;
+
+		return curr - start;
+	} else {
+		while (curr < size - 1 &&
+				store->cmp(dst[curr - 1], dst[curr], store->payload) > 0)
+			curr++;
+
+		/* reverse in-place */
+		reverse_elements(dst, start, curr - 1);
+		return curr - start;
+	}
+}
+
+static size_t compute_minrun(size_t n)
+{
+	int r = 0;
+	while (n >= 64) {
+		r |= n & 1;
+		n >>= 1;
+	}
+	return n + r;
+}
+
+static int check_invariant(struct tsort_run *stack, ssize_t stack_curr)
+{
+	if (stack_curr < 2)
+		return 1;
+
+	else if (stack_curr == 2) {
+		const ssize_t A = stack[stack_curr - 2].length;
+		const ssize_t B = stack[stack_curr - 1].length;
+		return (A > B);
+	} else {
+		const ssize_t A = stack[stack_curr - 3].length;
+		const ssize_t B = stack[stack_curr - 2].length;
+		const ssize_t C = stack[stack_curr - 1].length;
+		return !((A <= B + C) || (B <= C));
+	}
+}
+
+static int resize(struct tsort_store *store, size_t new_size)
+{
+	if (store->alloc < new_size) {
+		void **tempstore;
+
+		tempstore = git__reallocarray(store->storage, new_size, sizeof(void *));
+
+		/**
+		 * Do not propagate on OOM; this will abort the sort and
+		 * leave the array unsorted, but no error code will be
+		 * raised
+		 */
+		if (tempstore == NULL)
+			return -1;
+
+		store->storage = tempstore;
+		store->alloc = new_size;
+	}
+
+	return 0;
+}
+
+static void merge(void **dst, const struct tsort_run *stack, ssize_t stack_curr, struct tsort_store *store)
+{
+	const ssize_t A = stack[stack_curr - 2].length;
+	const ssize_t B = stack[stack_curr - 1].length;
+	const ssize_t curr = stack[stack_curr - 2].start;
+
+	void **storage;
+	ssize_t i, j, k;
+
+	if (resize(store, MIN(A, B)) < 0)
+		return;
+
+	storage = store->storage;
+
+	/* left merge */
+	if (A < B) {
+		memcpy(storage, &dst[curr], A * sizeof(void *));
+		i = 0;
+		j = curr + A;
+
+		for (k = curr; k < curr + A + B; k++) {
+			if ((i < A) && (j < curr + A + B)) {
+				if (store->cmp(storage[i], dst[j], store->payload) <= 0)
+					dst[k] = storage[i++];
+				else
+					dst[k] = dst[j++];
+			} else if (i < A) {
+				dst[k] = storage[i++];
+			} else
+				dst[k] = dst[j++];
+		}
+	} else {
+		memcpy(storage, &dst[curr + A], B * sizeof(void *));
+		i = B - 1;
+		j = curr + A - 1;
+
+		for (k = curr + A + B - 1; k >= curr; k--) {
+			if ((i >= 0) && (j >= curr)) {
+				if (store->cmp(dst[j], storage[i], store->payload) > 0)
+					dst[k] = dst[j--];
+				else
+					dst[k] = storage[i--];
+			} else if (i >= 0)
+				dst[k] = storage[i--];
+			else
+				dst[k] = dst[j--];
+		}
+	}
+}
+
+static ssize_t collapse(void **dst, struct tsort_run *stack, ssize_t stack_curr, struct tsort_store *store, ssize_t size)
+{
+	ssize_t A, B, C;
+
+	while (1) {
+		/* if the stack only has one thing on it, we are done with the collapse */
+		if (stack_curr <= 1)
+			break;
+
+		/* if this is the last merge, just do it */
+		if ((stack_curr == 2) && (stack[0].length + stack[1].length == size)) {
+			merge(dst, stack, stack_curr, store);
+			stack[0].length += stack[1].length;
+			stack_curr--;
+			break;
+		}
+
+		/* check if the invariant is off for a stack of 2 elements */
+		else if ((stack_curr == 2) && (stack[0].length <= stack[1].length)) {
+			merge(dst, stack, stack_curr, store);
+			stack[0].length += stack[1].length;
+			stack_curr--;
+			break;
+		}
+		else if (stack_curr == 2)
+			break;
+
+		A = stack[stack_curr - 3].length;
+		B = stack[stack_curr - 2].length;
+		C = stack[stack_curr - 1].length;
+
+		/* check first invariant */
+		if (A <= B + C) {
+			if (A < C) {
+				merge(dst, stack, stack_curr - 1, store);
+				stack[stack_curr - 3].length += stack[stack_curr - 2].length;
+				stack[stack_curr - 2] = stack[stack_curr - 1];
+				stack_curr--;
+			} else {
+				merge(dst, stack, stack_curr, store);
+				stack[stack_curr - 2].length += stack[stack_curr - 1].length;
+				stack_curr--;
+			}
+		} else if (B <= C) {
+			merge(dst, stack, stack_curr, store);
+			stack[stack_curr - 2].length += stack[stack_curr - 1].length;
+			stack_curr--;
+		} else
+			break;
+	}
+
+	return stack_curr;
+}
+
+#define PUSH_NEXT() do {\
+	len = count_run(dst, curr, size, store);\
+	run = minrun;\
+	if (run < minrun) run = minrun;\
+	if (run > (ssize_t)size - curr) run = size - curr;\
+	if (run > len) {\
+		bisort(&dst[curr], len, run, cmp, payload);\
+		len = run;\
+	}\
+	run_stack[stack_curr].start = curr;\
+	run_stack[stack_curr++].length = len;\
+	curr += len;\
+	if (curr == (ssize_t)size) {\
+		/* finish up */ \
+		while (stack_curr > 1) { \
+			merge(dst, run_stack, stack_curr, store); \
+			run_stack[stack_curr - 2].length += run_stack[stack_curr - 1].length; \
+			stack_curr--; \
+		} \
+		if (store->storage != NULL) {\
+			git__free(store->storage);\
+			store->storage = NULL;\
+		}\
+		return;\
+	}\
+}\
+while (0)
+
+void git__tsort_r(
+	void **dst, size_t size, git__sort_r_cmp cmp, void *payload)
+{
+	struct tsort_store _store, *store = &_store;
+	struct tsort_run run_stack[128];
+
+	ssize_t stack_curr = 0;
+	ssize_t len, run;
+	ssize_t curr = 0;
+	ssize_t minrun;
+
+	if (size < 64) {
+		bisort(dst, 1, size, cmp, payload);
+		return;
+	}
+
+	/* compute the minimum run length */
+	minrun = (ssize_t)compute_minrun(size);
+
+	/* temporary storage for merges */
+	store->alloc = 0;
+	store->storage = NULL;
+	store->cmp = cmp;
+	store->payload = payload;
+
+	PUSH_NEXT();
+	PUSH_NEXT();
+	PUSH_NEXT();
+
+	while (1) {
+		if (!check_invariant(run_stack, stack_curr)) {
+			stack_curr = collapse(dst, run_stack, stack_curr, store, size);
+			continue;
+		}
+
+		PUSH_NEXT();
+	}
+}
+
+static int tsort_r_cmp(const void *a, const void *b, void *payload)
+{
+	return ((git__tsort_cmp)payload)(a, b);
+}
+
+void git__tsort(void **dst, size_t size, git__tsort_cmp cmp)
+{
+	git__tsort_r(dst, size, tsort_r_cmp, cmp);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/unix/map.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/unix/map.c
new file mode 100755
index 0000000..87ee659
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/unix/map.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include <git2/common.h>
+
+#if !defined(GIT_WIN32) && !defined(NO_MMAP)
+
+#include "map.h"
+#include <sys/mman.h>
+#include <unistd.h>
+#include <errno.h>
+
+int git__page_size(size_t *page_size)
+{
+	long sc_page_size = sysconf(_SC_PAGE_SIZE);
+	if (sc_page_size < 0) {
+		giterr_set_str(GITERR_OS, "Can't determine system page size");
+		return -1;
+	}
+	*page_size = (size_t) sc_page_size;
+	return 0;
+}
+
+int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset)
+{
+	int mprot = PROT_READ;
+	int mflag = 0;
+
+	GIT_MMAP_VALIDATE(out, len, prot, flags);
+
+	out->data = NULL;
+	out->len = 0;
+
+	if (prot & GIT_PROT_WRITE)
+		mprot |= PROT_WRITE;
+
+	if ((flags & GIT_MAP_TYPE) == GIT_MAP_SHARED)
+		mflag = MAP_SHARED;
+	else if ((flags & GIT_MAP_TYPE) == GIT_MAP_PRIVATE)
+		mflag = MAP_PRIVATE;
+	else
+		mflag = MAP_SHARED;
+
+	out->data = mmap(NULL, len, mprot, mflag, fd, offset);
+
+	if (!out->data || out->data == MAP_FAILED) {
+		giterr_set(GITERR_OS, "Failed to mmap. Could not write data");
+		return -1;
+	}
+
+	out->len = len;
+
+	return 0;
+}
+
+int p_munmap(git_map *map)
+{
+	assert(map != NULL);
+	munmap(map->data, map->len);
+
+	return 0;
+}
+
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/unix/posix.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/unix/posix.h
new file mode 100755
index 0000000..7773509
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/unix/posix.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_posix__unix_h__
+#define INCLUDE_posix__unix_h__
+
+#include <stdio.h>
+#include <dirent.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+typedef int GIT_SOCKET;
+#define INVALID_SOCKET -1
+
+#define p_lseek(f,n,w) lseek(f, n, w)
+#define p_fstat(f,b) fstat(f, b)
+#define p_lstat(p,b) lstat(p,b)
+#define p_stat(p,b) stat(p, b)
+
+#define p_utimes(f, t) utimes(f, t)
+#define p_futimes(f, t) futimes(f, t)
+
+#define p_readlink(a, b, c) readlink(a, b, c)
+#define p_symlink(o,n) symlink(o, n)
+#define p_link(o,n) link(o, n)
+#define p_unlink(p) unlink(p)
+#define p_mkdir(p,m) mkdir(p, m)
+#define p_fsync(fd) fsync(fd)
+extern char *p_realpath(const char *, char *);
+
+#define p_recv(s,b,l,f) recv(s,b,l,f)
+#define p_send(s,b,l,f) send(s,b,l,f)
+#define p_inet_pton(a, b, c) inet_pton(a, b, c)
+
+#define p_strcasecmp(s1, s2) strcasecmp(s1, s2)
+#define p_strncasecmp(s1, s2, c) strncasecmp(s1, s2, c)
+#define p_vsnprintf(b, c, f, a) vsnprintf(b, c, f, a)
+#define p_snprintf(b, c, f, ...) snprintf(b, c, f, __VA_ARGS__)
+#define p_mkstemp(p) mkstemp(p)
+#define p_chdir(p) chdir(p)
+#define p_chmod(p,m) chmod(p, m)
+#define p_rmdir(p) rmdir(p)
+#define p_access(p,m) access(p,m)
+#define p_ftruncate(fd, sz) ftruncate(fd, sz)
+
+/* see win32/posix.h for explanation about why this exists */
+#define p_lstat_posixly(p,b) lstat(p,b)
+
+#define p_localtime_r(c, r) localtime_r(c, r)
+#define p_gmtime_r(c, r) gmtime_r(c, r)
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/unix/realpath.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/unix/realpath.c
new file mode 100755
index 0000000..2e49150
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/unix/realpath.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include <git2/common.h>
+
+#ifndef GIT_WIN32
+
+#include <limits.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+char *p_realpath(const char *pathname, char *resolved)
+{
+	char *ret;
+	if ((ret = realpath(pathname, resolved)) == NULL)
+		return NULL;
+
+#ifdef __OpenBSD__
+	/* The OpenBSD realpath function behaves differently,
+	 * figure out if the file exists */
+	if (access(ret, F_OK) < 0)
+		ret = NULL;
+#endif
+	return ret;
+}
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/userdiff.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/userdiff.h
new file mode 100755
index 0000000..91c1f42
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/userdiff.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_userdiff_h__
+#define INCLUDE_userdiff_h__
+
+/*
+ * This file isolates the built in diff driver function name patterns.
+ * Most of these patterns are taken from Git (with permission from the
+ * original authors for relicensing to libgit2).
+ */
+
+typedef struct {
+	const char *name;
+	const char *fns;
+	const char *words;
+	int flags;
+} git_diff_driver_definition;
+
+#define WORD_DEFAULT "|[^[:space:]]|[\xc0-\xff][\x80-\xbf]+"
+
+/*
+ * These builtin driver definition macros have same signature as in core
+ * git userdiff.c so that the data can be extracted verbatim
+ */
+#define PATTERNS(NAME, FN_PATS, WORD_PAT) \
+	{ NAME, FN_PATS, WORD_PAT WORD_DEFAULT, 0 }
+#define IPATTERN(NAME, FN_PATS, WORD_PAT) \
+	{ NAME, FN_PATS, WORD_PAT WORD_DEFAULT, REG_ICASE }
+
+/*
+ * The table of diff driver patterns
+ *
+ * Function name patterns are a list of newline separated patterns that
+ * match a function declaration (i.e. the line you want in the hunk header),
+ * or a negative pattern prefixed with a '!' to reject a pattern (such as
+ * rejecting goto labels in C code).
+ *
+ * Word boundary patterns are just a simple pattern that will be OR'ed with
+ * the default value above (i.e. whitespace or non-ASCII characters).
+ */
+static git_diff_driver_definition builtin_defs[] = {
+
+IPATTERN("ada",
+	 "!^(.*[ \t])?(is[ \t]+new|renames|is[ \t]+separate)([ \t].*)?$\n"
+	 "!^[ \t]*with[ \t].*$\n"
+	 "^[ \t]*((procedure|function)[ \t]+.*)$\n"
+	 "^[ \t]*((package|protected|task)[ \t]+.*)$",
+	 /* -- */
+	 "[a-zA-Z][a-zA-Z0-9_]*"
+	 "|[-+]?[0-9][0-9#_.aAbBcCdDeEfF]*([eE][+-]?[0-9_]+)?"
+	 "|=>|\\.\\.|\\*\\*|:=|/=|>=|<=|<<|>>|<>"),
+
+IPATTERN("fortran",
+	 "!^([C*]|[ \t]*!)\n"
+	 "!^[ \t]*MODULE[ \t]+PROCEDURE[ \t]\n"
+	 "^[ \t]*((END[ \t]+)?(PROGRAM|MODULE|BLOCK[ \t]+DATA"
+		"|([^'\" \t]+[ \t]+)*(SUBROUTINE|FUNCTION))[ \t]+[A-Z].*)$",
+	 /* -- */
+	 "[a-zA-Z][a-zA-Z0-9_]*"
+	 "|\\.([Ee][Qq]|[Nn][Ee]|[Gg][TtEe]|[Ll][TtEe]|[Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee]|[Aa][Nn][Dd]|[Oo][Rr]|[Nn]?[Ee][Qq][Vv]|[Nn][Oo][Tt])\\."
+	 /* numbers and format statements like 2E14.4, or ES12.6, 9X.
+	  * Don't worry about format statements without leading digits since
+	  * they would have been matched above as a variable anyway. */
+	 "|[-+]?[0-9.]+([AaIiDdEeFfLlTtXx][Ss]?[-+]?[0-9.]*)?(_[a-zA-Z0-9][a-zA-Z0-9_]*)?"
+	 "|//|\\*\\*|::|[/<>=]="),
+
+PATTERNS("html", "^[ \t]*(<[Hh][1-6][ \t].*>.*)$",
+	 "[^<>= \t]+"),
+
+PATTERNS("java",
+	 "!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
+	 "^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$",
+	 /* -- */
+	 "[a-zA-Z_][a-zA-Z0-9_]*"
+	 "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
+	 "|[-+*/<>%&^|=!]="
+	 "|--|\\+\\+|<<=?|>>>?=?|&&|\\|\\|"),
+
+PATTERNS("matlab",
+	 "^[[:space:]]*((classdef|function)[[:space:]].*)$|^%%[[:space:]].*$",
+	 "[a-zA-Z_][a-zA-Z0-9_]*|[-+0-9.e]+|[=~<>]=|\\.[*/\\^']|\\|\\||&&"),
+
+PATTERNS("objc",
+	 /* Negate C statements that can look like functions */
+	 "!^[ \t]*(do|for|if|else|return|switch|while)\n"
+	 /* Objective-C methods */
+	 "^[ \t]*([-+][ \t]*\\([ \t]*[A-Za-z_][A-Za-z_0-9* \t]*\\)[ \t]*[A-Za-z_].*)$\n"
+	 /* C functions */
+	 "^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$\n"
+	 /* Objective-C class/protocol definitions */
+	 "^(@(implementation|interface|protocol)[ \t].*)$",
+	 /* -- */
+	 "[a-zA-Z_][a-zA-Z0-9_]*"
+	 "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
+	 "|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"),
+
+PATTERNS("pascal",
+	 "^(((class[ \t]+)?(procedure|function)|constructor|destructor|interface|"
+		"implementation|initialization|finalization)[ \t]*.*)$"
+	 "\n"
+	 "^(.*=[ \t]*(class|record).*)$",
+	 /* -- */
+	 "[a-zA-Z_][a-zA-Z0-9_]*"
+	 "|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+"
+	 "|<>|<=|>=|:=|\\.\\."),
+
+PATTERNS("perl",
+	 "^package .*\n"
+	 "^sub [[:alnum:]_':]+[ \t]*"
+		"(\\([^)]*\\)[ \t]*)?" /* prototype */
+		/*
+		 * Attributes.  A regex can't count nested parentheses,
+		 * so just slurp up whatever we see, taking care not
+		 * to accept lines like "sub foo; # defined elsewhere".
+		 *
+		 * An attribute could contain a semicolon, but at that
+		 * point it seems reasonable enough to give up.
+		 */
+		"(:[^;#]*)?"
+		"(\\{[ \t]*)?" /* brace can come here or on the next line */
+		"(#.*)?$\n" /* comment */
+	 "^(BEGIN|END|INIT|CHECK|UNITCHECK|AUTOLOAD|DESTROY)[ \t]*"
+		"(\\{[ \t]*)?" /* brace can come here or on the next line */
+		"(#.*)?$\n"
+	 "^=head[0-9] .*",	/* POD */
+	 /* -- */
+	 "[[:alpha:]_'][[:alnum:]_']*"
+	 "|0[xb]?[0-9a-fA-F_]*"
+	 /* taking care not to interpret 3..5 as (3.)(.5) */
+	 "|[0-9a-fA-F_]+(\\.[0-9a-fA-F_]+)?([eE][-+]?[0-9_]+)?"
+	 "|=>|-[rwxoRWXOezsfdlpSugkbctTBMAC>]|~~|::"
+	 "|&&=|\\|\\|=|//=|\\*\\*="
+	 "|&&|\\|\\||//|\\+\\+|--|\\*\\*|\\.\\.\\.?"
+	 "|[-+*/%.^&<>=!|]="
+	 "|=~|!~"
+	 "|<<|<>|<=>|>>"),
+
+PATTERNS("python", "^[ \t]*((class|def)[ \t].*)$",
+	 /* -- */
+	 "[a-zA-Z_][a-zA-Z0-9_]*"
+	 "|[-+0-9.e]+[jJlL]?|0[xX]?[0-9a-fA-F]+[lL]?"
+	 "|[-+*/<>%&^|=!]=|//=?|<<=?|>>=?|\\*\\*=?"),
+
+PATTERNS("ruby", "^[ \t]*((class|module|def)[ \t].*)$",
+	 /* -- */
+	 "(@|@@|\\$)?[a-zA-Z_][a-zA-Z0-9_]*"
+	 "|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+|\\?(\\\\C-)?(\\\\M-)?."
+	 "|//=?|[-+*/<>%&^|=!]=|<<=?|>>=?|===|\\.{1,3}|::|[!=]~"),
+
+PATTERNS("bibtex", "(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$",
+	 "[={}\"]|[^={}\" \t]+"),
+
+PATTERNS("tex", "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$",
+	 "\\\\[a-zA-Z@]+|\\\\.|[a-zA-Z0-9\x80-\xff]+"),
+
+PATTERNS("cpp",
+	 /* Jump targets or access declarations */
+	 "!^[ \t]*[A-Za-z_][A-Za-z_0-9]*:[[:space:]]*($|/[/*])\n"
+	 /* functions/methods, variables, and compounds at top level */
+	 "^((::[[:space:]]*)?[A-Za-z_].*)$",
+	 /* -- */
+	 "[a-zA-Z_][a-zA-Z0-9_]*"
+	 "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lLuU]*"
+	 "|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->\\*?|\\.\\*"),
+
+PATTERNS("csharp",
+	 /* Keywords */
+	 "!^[ \t]*(do|while|for|if|else|instanceof|new|return|switch|case|throw|catch|using)\n"
+	 /* Methods and constructors */
+	 "^[ \t]*(((static|public|internal|private|protected|new|virtual|sealed|override|unsafe)[ \t]+)*[][<>@.~_[:alnum:]]+[ \t]+[<>@._[:alnum:]]+[ \t]*\\(.*\\))[ \t]*$\n"
+	 /* Properties */
+	 "^[ \t]*(((static|public|internal|private|protected|new|virtual|sealed|override|unsafe)[ \t]+)*[][<>@.~_[:alnum:]]+[ \t]+[@._[:alnum:]]+)[ \t]*$\n"
+	 /* Type definitions */
+	 "^[ \t]*(((static|public|internal|private|protected|new|unsafe|sealed|abstract|partial)[ \t]+)*(class|enum|interface|struct)[ \t]+.*)$\n"
+	 /* Namespace */
+	 "^[ \t]*(namespace[ \t]+.*)$",
+	 /* -- */
+	 "[a-zA-Z_][a-zA-Z0-9_]*"
+	 "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
+	 "|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"),
+
+PATTERNS("php",
+	 "^[ \t]*(((public|private|protected|static|final)[ \t]+)*((class|function)[ \t].*))$",
+	 /* -- */
+	 "[a-zA-Z_][a-zA-Z0-9_]*"
+	 "|[-+0-9.e]+[fFlL]?|0[xX]?[0-9a-fA-F]+[lL]?"
+	 "|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"),
+
+PATTERNS("javascript",
+	 "([a-zA-Z_$][a-zA-Z0-9_$]*(\\.[a-zA-Z0-9_$]+)*[ \t]*=[ \t]*function([ \t][a-zA-Z_$][a-zA-Z0-9_$]*)?[^\\{]*)\n"
+	 "([a-zA-Z_$][a-zA-Z0-9_$]*[ \t]*:[ \t]*function([ \t][a-zA-Z_$][a-zA-Z0-9_$]*)?[^\\{]*)\n"
+	 "[^a-zA-Z0-9_\\$](function([ \t][a-zA-Z_$][a-zA-Z0-9_$]*)?[^\\{]*)",
+	 /* -- */
+	 "[a-zA-Z_][a-zA-Z0-9_]*"
+	 "|[-+0-9.e]+[fFlL]?|0[xX]?[0-9a-fA-F]+[lL]?"
+	 "|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"),
+};
+
+#undef IPATTERN
+#undef PATTERNS
+#undef WORD_DEFAULT
+
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/util.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/util.c
new file mode 100755
index 0000000..c628264
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/util.c
@@ -0,0 +1,767 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include <git2.h>
+#include "common.h"
+#include <stdio.h>
+#include <ctype.h>
+#include "posix.h"
+
+#ifdef _MSC_VER
+# include <Shlwapi.h>
+#endif
+
+void git_strarray_free(git_strarray *array)
+{
+	size_t i;
+
+	if (array == NULL)
+		return;
+
+	for (i = 0; i < array->count; ++i)
+		git__free(array->strings[i]);
+
+	git__free(array->strings);
+
+	memset(array, 0, sizeof(*array));
+}
+
+int git_strarray_copy(git_strarray *tgt, const git_strarray *src)
+{
+	size_t i;
+
+	assert(tgt && src);
+
+	memset(tgt, 0, sizeof(*tgt));
+
+	if (!src->count)
+		return 0;
+
+	tgt->strings = git__calloc(src->count, sizeof(char *));
+	GITERR_CHECK_ALLOC(tgt->strings);
+
+	for (i = 0; i < src->count; ++i) {
+		if (!src->strings[i])
+			continue;
+
+		tgt->strings[tgt->count] = git__strdup(src->strings[i]);
+		if (!tgt->strings[tgt->count]) {
+			git_strarray_free(tgt);
+			memset(tgt, 0, sizeof(*tgt));
+			return -1;
+		}
+
+		tgt->count++;
+	}
+
+	return 0;
+}
+
+int git__strtol64(int64_t *result, const char *nptr, const char **endptr, int base)
+{
+	const char *p;
+	int64_t n, nn;
+	int c, ovfl, v, neg, ndig;
+
+	p = nptr;
+	neg = 0;
+	n = 0;
+	ndig = 0;
+	ovfl = 0;
+
+	/*
+	 * White space
+	 */
+	while (git__isspace(*p))
+		p++;
+
+	/*
+	 * Sign
+	 */
+	if (*p == '-' || *p == '+')
+		if (*p++ == '-')
+			neg = 1;
+
+	/*
+	 * Base
+	 */
+	if (base == 0) {
+		if (*p != '0')
+			base = 10;
+		else {
+			base = 8;
+			if (p[1] == 'x' || p[1] == 'X') {
+				p += 2;
+				base = 16;
+			}
+		}
+	} else if (base == 16 && *p == '0') {
+		if (p[1] == 'x' || p[1] == 'X')
+			p += 2;
+	} else if (base < 0 || 36 < base)
+		goto Return;
+
+	/*
+	 * Non-empty sequence of digits
+	 */
+	for (;; p++,ndig++) {
+		c = *p;
+		v = base;
+		if ('0'<=c && c<='9')
+			v = c - '0';
+		else if ('a'<=c && c<='z')
+			v = c - 'a' + 10;
+		else if ('A'<=c && c<='Z')
+			v = c - 'A' + 10;
+		if (v >= base)
+			break;
+		nn = n*base + v;
+		if (nn < n)
+			ovfl = 1;
+		n = nn;
+	}
+
+Return:
+	if (ndig == 0) {
+		giterr_set(GITERR_INVALID, "Failed to convert string to long. Not a number");
+		return -1;
+	}
+
+	if (endptr)
+		*endptr = p;
+
+	if (ovfl) {
+		giterr_set(GITERR_INVALID, "Failed to convert string to long. Overflow error");
+		return -1;
+	}
+
+	*result = neg ? -n : n;
+	return 0;
+}
+
+int git__strtol32(int32_t *result, const char *nptr, const char **endptr, int base)
+{
+	int error;
+	int32_t tmp_int;
+	int64_t tmp_long;
+
+	if ((error = git__strtol64(&tmp_long, nptr, endptr, base)) < 0)
+		return error;
+
+	tmp_int = tmp_long & 0xFFFFFFFF;
+	if (tmp_int != tmp_long) {
+		giterr_set(GITERR_INVALID, "Failed to convert. '%s' is too large", nptr);
+		return -1;
+	}
+
+	*result = tmp_int;
+
+	return error;
+}
+
+int git__strcmp(const char *a, const char *b)
+{
+	while (*a && *b && *a == *b)
+		++a, ++b;
+	return (int)(*(const unsigned char *)a) - (int)(*(const unsigned char *)b);
+}
+
+int git__strcasecmp(const char *a, const char *b)
+{
+	while (*a && *b && git__tolower(*a) == git__tolower(*b))
+		++a, ++b;
+	return ((unsigned char)git__tolower(*a) - (unsigned char)git__tolower(*b));
+}
+
+int git__strcasesort_cmp(const char *a, const char *b)
+{
+	int cmp = 0;
+
+	while (*a && *b) {
+		if (*a != *b) {
+			if (git__tolower(*a) != git__tolower(*b))
+				break;
+			/* use case in sort order even if not in equivalence */
+			if (!cmp)
+				cmp = (int)(*(const uint8_t *)a) - (int)(*(const uint8_t *)b);
+		}
+
+		++a, ++b;
+	}
+
+	if (*a || *b)
+		return (unsigned char)git__tolower(*a) - (unsigned char)git__tolower(*b);
+
+	return cmp;
+}
+
+int git__strncmp(const char *a, const char *b, size_t sz)
+{
+	while (sz && *a && *b && *a == *b)
+		--sz, ++a, ++b;
+	if (!sz)
+		return 0;
+	return (int)(*(const unsigned char *)a) - (int)(*(const unsigned char *)b);
+}
+
+int git__strncasecmp(const char *a, const char *b, size_t sz)
+{
+	int al, bl;
+
+	do {
+		al = (unsigned char)git__tolower(*a);
+		bl = (unsigned char)git__tolower(*b);
+		++a, ++b;
+	} while (--sz && al && al == bl);
+
+	return al - bl;
+}
+
+void git__strntolower(char *str, size_t len)
+{
+	size_t i;
+
+	for (i = 0; i < len; ++i) {
+		str[i] = (char)git__tolower(str[i]);
+	}
+}
+
+void git__strtolower(char *str)
+{
+	git__strntolower(str, strlen(str));
+}
+
+int git__prefixcmp(const char *str, const char *prefix)
+{
+	for (;;) {
+		unsigned char p = *(prefix++), s;
+		if (!p)
+			return 0;
+		if ((s = *(str++)) != p)
+			return s - p;
+	}
+}
+
+int git__prefixcmp_icase(const char *str, const char *prefix)
+{
+	return strncasecmp(str, prefix, strlen(prefix));
+}
+
+int git__prefixncmp_icase(const char *str, size_t str_n, const char *prefix)
+{
+	int s, p;
+
+	while(str_n--) {
+		s = (unsigned char)git__tolower(*str++);
+		p = (unsigned char)git__tolower(*prefix++);
+
+		if (s != p)
+			return s - p;
+	}
+
+	return (0 - *prefix);
+}
+
+int git__suffixcmp(const char *str, const char *suffix)
+{
+	size_t a = strlen(str);
+	size_t b = strlen(suffix);
+	if (a < b)
+		return -1;
+	return strcmp(str + (a - b), suffix);
+}
+
+char *git__strtok(char **end, const char *sep)
+{
+	char *ptr = *end;
+
+	while (*ptr && strchr(sep, *ptr))
+		++ptr;
+
+	if (*ptr) {
+		char *start = ptr;
+		*end = start + 1;
+
+		while (**end && !strchr(sep, **end))
+			++*end;
+
+		if (**end) {
+			**end = '\0';
+			++*end;
+		}
+
+		return start;
+	}
+
+	return NULL;
+}
+
+/* Similar to strtok, but does not collapse repeated tokens. */
+char *git__strsep(char **end, const char *sep)
+{
+	char *start = *end, *ptr = *end;
+
+	while (*ptr && !strchr(sep, *ptr))
+		++ptr;
+
+	if (*ptr) {
+		*end = ptr + 1;
+		*ptr = '\0';
+
+		return start;
+	}
+
+	return NULL;
+}
+
+void git__hexdump(const char *buffer, size_t len)
+{
+	static const size_t LINE_WIDTH = 16;
+
+	size_t line_count, last_line, i, j;
+	const char *line;
+
+	line_count = (len / LINE_WIDTH);
+	last_line = (len % LINE_WIDTH);
+
+	for (i = 0; i < line_count; ++i) {
+		line = buffer + (i * LINE_WIDTH);
+		for (j = 0; j < LINE_WIDTH; ++j, ++line)
+			printf("%02X ", (unsigned char)*line & 0xFF);
+
+		printf("| ");
+
+		line = buffer + (i * LINE_WIDTH);
+		for (j = 0; j < LINE_WIDTH; ++j, ++line)
+			printf("%c", (*line >= 32 && *line <= 126) ? *line : '.');
+
+		printf("\n");
+	}
+
+	if (last_line > 0) {
+
+		line = buffer + (line_count * LINE_WIDTH);
+		for (j = 0; j < last_line; ++j, ++line)
+			printf("%02X ", (unsigned char)*line & 0xFF);
+
+		for (j = 0; j < (LINE_WIDTH - last_line); ++j)
+			printf("	");
+
+		printf("| ");
+
+		line = buffer + (line_count * LINE_WIDTH);
+		for (j = 0; j < last_line; ++j, ++line)
+			printf("%c", (*line >= 32 && *line <= 126) ? *line : '.');
+
+		printf("\n");
+	}
+
+	printf("\n");
+}
+
+#ifdef GIT_LEGACY_HASH
+uint32_t git__hash(const void *key, int len, unsigned int seed)
+{
+	const uint32_t m = 0x5bd1e995;
+	const int r = 24;
+	uint32_t h = seed ^ len;
+
+	const unsigned char *data = (const unsigned char *)key;
+
+	while(len >= 4) {
+		uint32_t k = *(uint32_t *)data;
+
+		k *= m;
+		k ^= k >> r;
+		k *= m;
+
+		h *= m;
+		h ^= k;
+
+		data += 4;
+		len -= 4;
+	}
+
+	switch(len) {
+	case 3: h ^= data[2] << 16;
+	case 2: h ^= data[1] << 8;
+	case 1: h ^= data[0];
+			h *= m;
+	};
+
+	h ^= h >> 13;
+	h *= m;
+	h ^= h >> 15;
+
+	return h;
+}
+#else
+/*
+	Cross-platform version of Murmurhash3
+	http://code.google.com/p/smhasher/wiki/MurmurHash3
+	by Austin Appleby (aappleby at gmail.com)
+
+	This code is on the public domain.
+*/
+uint32_t git__hash(const void *key, int len, uint32_t seed)
+{
+
+#define MURMUR_BLOCK() {\
+	k1 *= c1; \
+	k1 = git__rotl(k1,11);\
+	k1 *= c2;\
+	h1 ^= k1;\
+	h1 = h1*3 + 0x52dce729;\
+	c1 = c1*5 + 0x7b7d159c;\
+	c2 = c2*5 + 0x6bce6396;\
+}
+
+	const uint8_t *data = (const uint8_t*)key;
+	const int nblocks = len / 4;
+
+	const uint32_t *blocks = (const uint32_t *)(data + nblocks * 4);
+	const uint8_t *tail = (const uint8_t *)(data + nblocks * 4);
+
+	uint32_t h1 = 0x971e137b ^ seed;
+	uint32_t k1;
+
+	uint32_t c1 = 0x95543787;
+	uint32_t c2 = 0x2ad7eb25;
+
+	int i;
+
+	for (i = -nblocks; i; i++) {
+		k1 = blocks[i];
+		MURMUR_BLOCK();
+	}
+
+	k1 = 0;
+
+	switch(len & 3) {
+	case 3: k1 ^= tail[2] << 16;
+	case 2: k1 ^= tail[1] << 8;
+	case 1: k1 ^= tail[0];
+			MURMUR_BLOCK();
+	}
+
+	h1 ^= len;
+	h1 ^= h1 >> 16;
+	h1 *= 0x85ebca6b;
+	h1 ^= h1 >> 13;
+	h1 *= 0xc2b2ae35;
+	h1 ^= h1 >> 16;
+
+	return h1;
+}
+#endif
+
+/**
+ * A modified `bsearch` from the BSD glibc.
+ *
+ * Copyright (c) 1990 Regents of the University of California.
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. [rescinded 22 July 1999]
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+int git__bsearch(
+	void **array,
+	size_t array_len,
+	const void *key,
+	int (*compare)(const void *, const void *),
+	size_t *position)
+{
+	size_t lim;
+	int cmp = -1;
+	void **part, **base = array;
+
+	for (lim = array_len; lim != 0; lim >>= 1) {
+		part = base + (lim >> 1);
+		cmp = (*compare)(key, *part);
+		if (cmp == 0) {
+			base = part;
+			break;
+		}
+		if (cmp > 0) { /* key > p; take right partition */
+			base = part + 1;
+			lim--;
+		} /* else take left partition */
+	}
+
+	if (position)
+		*position = (base - array);
+
+	return (cmp == 0) ? 0 : GIT_ENOTFOUND;
+}
+
+int git__bsearch_r(
+	void **array,
+	size_t array_len,
+	const void *key,
+	int (*compare_r)(const void *, const void *, void *),
+	void *payload,
+	size_t *position)
+{
+	size_t lim;
+	int cmp = -1;
+	void **part, **base = array;
+
+	for (lim = array_len; lim != 0; lim >>= 1) {
+		part = base + (lim >> 1);
+		cmp = (*compare_r)(key, *part, payload);
+		if (cmp == 0) {
+			base = part;
+			break;
+		}
+		if (cmp > 0) { /* key > p; take right partition */
+			base = part + 1;
+			lim--;
+		} /* else take left partition */
+	}
+
+	if (position)
+		*position = (base - array);
+
+	return (cmp == 0) ? 0 : GIT_ENOTFOUND;
+}
+
+/**
+ * A strcmp wrapper
+ *
+ * We don't want direct pointers to the CRT on Windows, we may
+ * get stdcall conflicts.
+ */
+int git__strcmp_cb(const void *a, const void *b)
+{
+	return strcmp((const char *)a, (const char *)b);
+}
+
+int git__strcasecmp_cb(const void *a, const void *b)
+{
+	return strcasecmp((const char *)a, (const char *)b);
+}
+
+int git__parse_bool(int *out, const char *value)
+{
+	/* A missing value means true */
+	if (value == NULL ||
+		!strcasecmp(value, "true") ||
+		!strcasecmp(value, "yes") ||
+		!strcasecmp(value, "on")) {
+		*out = 1;
+		return 0;
+	}
+	if (!strcasecmp(value, "false") ||
+		!strcasecmp(value, "no") ||
+		!strcasecmp(value, "off") ||
+		value[0] == '\0') {
+		*out = 0;
+		return 0;
+	}
+
+	return -1;
+}
+
+size_t git__unescape(char *str)
+{
+	char *scan, *pos = str;
+
+	if (!str)
+		return 0;
+
+	for (scan = str; *scan; pos++, scan++) {
+		if (*scan == '\\' && *(scan + 1) != '\0')
+			scan++; /* skip '\' but include next char */
+		if (pos != scan)
+			*pos = *scan;
+	}
+
+	if (pos != scan) {
+		*pos = '\0';
+	}
+
+	return (pos - str);
+}
+
+#if defined(GIT_WIN32) || defined(BSD)
+typedef struct {
+	git__sort_r_cmp cmp;
+	void *payload;
+} git__qsort_r_glue;
+
+static int GIT_STDLIB_CALL git__qsort_r_glue_cmp(
+	void *payload, const void *a, const void *b)
+{
+	git__qsort_r_glue *glue = payload;
+	return glue->cmp(a, b, glue->payload);
+}
+#endif
+
+void git__qsort_r(
+	void *els, size_t nel, size_t elsize, git__sort_r_cmp cmp, void *payload)
+{
+#if defined(__MINGW32__) || defined(AMIGA) || \
+	defined(__OpenBSD__) || defined(__NetBSD__) || \
+	defined(__gnu_hurd__) || defined(__ANDROID_API__) || \
+	defined(__sun) || defined(__CYGWIN__) || \
+	(__GLIBC__ == 2 && __GLIBC_MINOR__ < 8) || \
+	(defined(_MSC_VER) && _MSC_VER < 1500)
+	git__insertsort_r(els, nel, elsize, NULL, cmp, payload);
+#elif defined(GIT_WIN32)
+	git__qsort_r_glue glue = { cmp, payload };
+	qsort_s(els, nel, elsize, git__qsort_r_glue_cmp, &glue);
+#elif defined(BSD)
+	git__qsort_r_glue glue = { cmp, payload };
+	qsort_r(els, nel, elsize, &glue, git__qsort_r_glue_cmp);
+#else
+	qsort_r(els, nel, elsize, cmp, payload);
+#endif
+}
+
+void git__insertsort_r(
+	void *els, size_t nel, size_t elsize, void *swapel,
+	git__sort_r_cmp cmp, void *payload)
+{
+	uint8_t *base = els;
+	uint8_t *end = base + nel * elsize;
+	uint8_t *i, *j;
+	bool freeswap = !swapel;
+
+	if (freeswap)
+		swapel = git__malloc(elsize);
+
+	for (i = base + elsize; i < end; i += elsize)
+		for (j = i; j > base && cmp(j, j - elsize, payload) < 0; j -= elsize) {
+			memcpy(swapel, j, elsize);
+			memcpy(j, j - elsize, elsize);
+			memcpy(j - elsize, swapel, elsize);
+		}
+
+	if (freeswap)
+		git__free(swapel);
+}
+
+/*
+ * git__utf8_iterate is taken from the utf8proc project,
+ * http://www.public-software-group.org/utf8proc
+ *
+ * Copyright (c) 2009 Public Software Group e. V., Berlin, Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the ""Software""),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+static const int8_t utf8proc_utf8class[256] = {
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+	4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+int git__utf8_charlen(const uint8_t *str, int str_len)
+{
+	int length, i;
+
+	length = utf8proc_utf8class[str[0]];
+	if (!length)
+		return -1;
+
+	if (str_len >= 0 && length > str_len)
+		return -str_len;
+
+	for (i = 1; i < length; i++) {
+		if ((str[i] & 0xC0) != 0x80)
+			return -i;
+	}
+
+	return length;
+}
+
+int git__utf8_iterate(const uint8_t *str, int str_len, int32_t *dst)
+{
+	int length;
+	int32_t uc = -1;
+
+	*dst = -1;
+	length = git__utf8_charlen(str, str_len);
+	if (length < 0)
+		return -1;
+
+	switch (length) {
+		case 1:
+			uc = str[0];
+			break;
+		case 2:
+			uc = ((str[0] & 0x1F) <<  6) + (str[1] & 0x3F);
+			if (uc < 0x80) uc = -1;
+			break;
+		case 3:
+			uc = ((str[0] & 0x0F) << 12) + ((str[1] & 0x3F) <<  6)
+				+ (str[2] & 0x3F);
+			if (uc < 0x800 || (uc >= 0xD800 && uc < 0xE000) ||
+					(uc >= 0xFDD0 && uc < 0xFDF0)) uc = -1;
+			break;
+		case 4:
+			uc = ((str[0] & 0x07) << 18) + ((str[1] & 0x3F) << 12)
+				+ ((str[2] & 0x3F) <<  6) + (str[3] & 0x3F);
+			if (uc < 0x10000 || uc >= 0x110000) uc = -1;
+			break;
+	}
+
+	if (uc < 0 || ((uc & 0xFFFF) >= 0xFFFE))
+		return -1;
+
+	*dst = uc;
+	return length;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/util.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/util.h
new file mode 100755
index 0000000..b2abbe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/util.h
@@ -0,0 +1,599 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_util_h__
+#define INCLUDE_util_h__
+
+#if defined(GIT_MSVC_CRTDBG)
+/* Enable MSVC CRTDBG memory leak reporting.
+ *
+ * We DO NOT use the "_CRTDBG_MAP_ALLOC" macro described in the MSVC
+ * documentation because all allocs/frees in libgit2 already go through
+ * the "git__" routines defined in this file.  Simply using the normal
+ * reporting mechanism causes all leaks to be attributed to a routine
+ * here in util.h (ie, the actual call to calloc()) rather than the
+ * caller of git__calloc().
+ *
+ * Therefore, we declare a set of "git__crtdbg__" routines to replace
+ * the corresponding "git__" routines and re-define the "git__" symbols
+ * as macros.  This allows us to get and report the file:line info of
+ * the real caller.
+ *
+ * We DO NOT replace the "git__free" routine because it needs to remain
+ * a function pointer because it is used as a function argument when
+ * setting up various structure "destructors".
+ *
+ * We also DO NOT use the "_CRTDBG_MAP_ALLOC" macro because it causes
+ * "free" to be remapped to "_free_dbg" and this causes problems for
+ * structures which define a field named "free".
+ *
+ * Finally, CRTDBG must be explicitly enabled and configured at program
+ * startup.  See tests/main.c for an example.
+ */
+#include <stdlib.h>
+#include <crtdbg.h>
+#endif
+
+#include "common.h"
+#include "strnlen.h"
+
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+#define bitsizeof(x) (CHAR_BIT * sizeof(x))
+#define MSB(x, bits) ((x) & (~0ULL << (bitsizeof(x) - (bits))))
+#ifndef min
+# define min(a,b) ((a) < (b) ? (a) : (b))
+#endif
+#ifndef max
+# define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+#define GIT_DATE_RFC2822_SZ  32
+
+/**
+ * Return the length of a constant string.
+ * We are aware that `strlen` performs the same task and is usually
+ * optimized away by the compiler, whilst being safer because it returns
+ * valid values when passed a pointer instead of a constant string; however
+ * this macro will transparently work with wide-char and single-char strings.
+ */
+#define CONST_STRLEN(x) ((sizeof(x)/sizeof(x[0])) - 1)
+
+#if defined(GIT_MSVC_CRTDBG)
+GIT_INLINE(void *) git__crtdbg__malloc(size_t len, const char *file, int line)
+{
+	void *ptr = _malloc_dbg(len, _NORMAL_BLOCK, file, line);
+	if (!ptr) giterr_set_oom();
+	return ptr;
+}
+
+GIT_INLINE(void *) git__crtdbg__calloc(size_t nelem, size_t elsize, const char *file, int line)
+{
+	void *ptr = _calloc_dbg(nelem, elsize, _NORMAL_BLOCK, file, line);
+	if (!ptr) giterr_set_oom();
+	return ptr;
+}
+
+GIT_INLINE(char *) git__crtdbg__strdup(const char *str, const char *file, int line)
+{
+	char *ptr = _strdup_dbg(str, _NORMAL_BLOCK, file, line);
+	if (!ptr) giterr_set_oom();
+	return ptr;
+}
+
+GIT_INLINE(char *) git__crtdbg__strndup(const char *str, size_t n, const char *file, int line)
+{
+	size_t length = 0, alloclength;
+	char *ptr;
+
+	length = p_strnlen(str, n);
+
+	if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) ||
+		!(ptr = git__crtdbg__malloc(alloclength, file, line)))
+		return NULL;
+
+	if (length)
+		memcpy(ptr, str, length);
+
+	ptr[length] = '\0';
+
+	return ptr;
+}
+
+GIT_INLINE(char *) git__crtdbg__substrdup(const char *start, size_t n, const char *file, int line)
+{
+	char *ptr;
+	size_t alloclen;
+
+	if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) ||
+		!(ptr = git__crtdbg__malloc(alloclen, file, line)))
+		return NULL;
+
+	memcpy(ptr, start, n);
+	ptr[n] = '\0';
+	return ptr;
+}
+
+GIT_INLINE(void *) git__crtdbg__realloc(void *ptr, size_t size, const char *file, int line)
+{
+	void *new_ptr = _realloc_dbg(ptr, size, _NORMAL_BLOCK, file, line);
+	if (!new_ptr) giterr_set_oom();
+	return new_ptr;
+}
+
+GIT_INLINE(void *) git__crtdbg__reallocarray(void *ptr, size_t nelem, size_t elsize, const char *file, int line)
+{
+	size_t newsize;
+	return GIT_MULTIPLY_SIZET_OVERFLOW(&newsize, nelem, elsize) ?
+		NULL : _realloc_dbg(ptr, newsize, _NORMAL_BLOCK, file, line);
+}
+
+GIT_INLINE(void *) git__crtdbg__mallocarray(size_t nelem, size_t elsize, const char *file, int line)
+{
+	return git__crtdbg__reallocarray(NULL, nelem, elsize, file, line);
+}
+
+#define git__malloc(len)                      git__crtdbg__malloc(len, __FILE__, __LINE__)
+#define git__calloc(nelem, elsize)            git__crtdbg__calloc(nelem, elsize, __FILE__, __LINE__)
+#define git__strdup(str)                      git__crtdbg__strdup(str, __FILE__, __LINE__)
+#define git__strndup(str, n)                  git__crtdbg__strndup(str, n, __FILE__, __LINE__)
+#define git__substrdup(str, n)                git__crtdbg__substrdup(str, n, __FILE__, __LINE__)
+#define git__realloc(ptr, size)               git__crtdbg__realloc(ptr, size, __FILE__, __LINE__)
+#define git__reallocarray(ptr, nelem, elsize) git__crtdbg__reallocarray(ptr, nelem, elsize, __FILE__, __LINE__)
+#define git__mallocarray(nelem, elsize)       git__crtdbg__mallocarray(nelem, elsize, __FILE__, __LINE__)
+
+#else
+
+/*
+ * Custom memory allocation wrappers
+ * that set error code and error message
+ * on allocation failure
+ */
+GIT_INLINE(void *) git__malloc(size_t len)
+{
+	void *ptr = malloc(len);
+	if (!ptr) giterr_set_oom();
+	return ptr;
+}
+
+GIT_INLINE(void *) git__calloc(size_t nelem, size_t elsize)
+{
+	void *ptr = calloc(nelem, elsize);
+	if (!ptr) giterr_set_oom();
+	return ptr;
+}
+
+GIT_INLINE(char *) git__strdup(const char *str)
+{
+	char *ptr = strdup(str);
+	if (!ptr) giterr_set_oom();
+	return ptr;
+}
+
+GIT_INLINE(char *) git__strndup(const char *str, size_t n)
+{
+	size_t length = 0, alloclength;
+	char *ptr;
+
+	length = p_strnlen(str, n);
+
+	if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) ||
+		!(ptr = git__malloc(alloclength)))
+		return NULL;
+
+	if (length)
+		memcpy(ptr, str, length);
+
+	ptr[length] = '\0';
+
+	return ptr;
+}
+
+/* NOTE: This doesn't do null or '\0' checking.  Watch those boundaries! */
+GIT_INLINE(char *) git__substrdup(const char *start, size_t n)
+{
+	char *ptr;
+	size_t alloclen;
+
+	if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) ||
+		!(ptr = git__malloc(alloclen)))
+		return NULL;
+
+	memcpy(ptr, start, n);
+	ptr[n] = '\0';
+	return ptr;
+}
+
+GIT_INLINE(void *) git__realloc(void *ptr, size_t size)
+{
+	void *new_ptr = realloc(ptr, size);
+	if (!new_ptr) giterr_set_oom();
+	return new_ptr;
+}
+
+/**
+ * Similar to `git__realloc`, except that it is suitable for reallocing an
+ * array to a new number of elements of `nelem`, each of size `elsize`.
+ * The total size calculation is checked for overflow.
+ */
+GIT_INLINE(void *) git__reallocarray(void *ptr, size_t nelem, size_t elsize)
+{
+	size_t newsize;
+	return GIT_MULTIPLY_SIZET_OVERFLOW(&newsize, nelem, elsize) ?
+		NULL : realloc(ptr, newsize);
+}
+
+/**
+ * Similar to `git__calloc`, except that it does not zero memory.
+ */
+GIT_INLINE(void *) git__mallocarray(size_t nelem, size_t elsize)
+{
+	return git__reallocarray(NULL, nelem, elsize);
+}
+
+#endif /* !MSVC_CTRDBG */
+
+GIT_INLINE(void) git__free(void *ptr)
+{
+	free(ptr);
+}
+
+#define STRCMP_CASESELECT(IGNORE_CASE, STR1, STR2) \
+	((IGNORE_CASE) ? strcasecmp((STR1), (STR2)) : strcmp((STR1), (STR2)))
+
+#define CASESELECT(IGNORE_CASE, ICASE, CASE) \
+	((IGNORE_CASE) ? (ICASE) : (CASE))
+
+extern int git__prefixcmp(const char *str, const char *prefix);
+extern int git__prefixcmp_icase(const char *str, const char *prefix);
+extern int git__prefixncmp_icase(const char *str, size_t str_n, const char *prefix);
+extern int git__suffixcmp(const char *str, const char *suffix);
+
+GIT_INLINE(int) git__signum(int val)
+{
+	return ((val > 0) - (val < 0));
+}
+
+extern int git__strtol32(int32_t *n, const char *buff, const char **end_buf, int base);
+extern int git__strtol64(int64_t *n, const char *buff, const char **end_buf, int base);
+
+extern void git__hexdump(const char *buffer, size_t n);
+extern uint32_t git__hash(const void *key, int len, uint32_t seed);
+
+/* 32-bit cross-platform rotl */
+#ifdef _MSC_VER /* use built-in method in MSVC */
+#	define git__rotl(v, s) (uint32_t)_rotl(v, s)
+#else /* use bitops in GCC; with o2 this gets optimized to a rotl instruction */
+#	define git__rotl(v, s) (uint32_t)(((uint32_t)(v) << (s)) | ((uint32_t)(v) >> (32 - (s))))
+#endif
+
+extern char *git__strtok(char **end, const char *sep);
+extern char *git__strsep(char **end, const char *sep);
+
+extern void git__strntolower(char *str, size_t len);
+extern void git__strtolower(char *str);
+
+#ifdef GIT_WIN32
+GIT_INLINE(int) git__tolower(int c)
+{
+	return (c >= 'A' && c <= 'Z') ? (c + 32) : c;
+}
+#else
+# define git__tolower(a) tolower(a)
+#endif
+
+GIT_INLINE(const char *) git__next_line(const char *s)
+{
+	while (*s && *s != '\n') s++;
+	while (*s == '\n' || *s == '\r') s++;
+	return s;
+}
+
+GIT_INLINE(const void *) git__memrchr(const void *s, int c, size_t n)
+{
+	const unsigned char *cp;
+
+	if (n != 0) {
+		cp = (unsigned char *)s + n;
+		do {
+			if (*(--cp) == (unsigned char)c)
+				return cp;
+		} while (--n != 0);
+	}
+
+	return NULL;
+}
+
+typedef int (*git__tsort_cmp)(const void *a, const void *b);
+
+extern void git__tsort(void **dst, size_t size, git__tsort_cmp cmp);
+
+typedef int (*git__sort_r_cmp)(const void *a, const void *b, void *payload);
+
+extern void git__tsort_r(
+	void **dst, size_t size, git__sort_r_cmp cmp, void *payload);
+
+extern void git__qsort_r(
+	void *els, size_t nel, size_t elsize, git__sort_r_cmp cmp, void *payload);
+
+extern void git__insertsort_r(
+	void *els, size_t nel, size_t elsize, void *swapel,
+	git__sort_r_cmp cmp, void *payload);
+
+/**
+ * @param position If non-NULL, this will be set to the position where the
+ * 		element is or would be inserted if not found.
+ * @return 0 if found; GIT_ENOTFOUND if not found
+ */
+extern int git__bsearch(
+	void **array,
+	size_t array_len,
+	const void *key,
+	int (*compare)(const void *key, const void *element),
+	size_t *position);
+
+extern int git__bsearch_r(
+	void **array,
+	size_t array_len,
+	const void *key,
+	int (*compare_r)(const void *key, const void *element, void *payload),
+	void *payload,
+	size_t *position);
+
+extern int git__strcmp_cb(const void *a, const void *b);
+extern int git__strcasecmp_cb(const void *a, const void *b);
+
+extern int git__strcmp(const char *a, const char *b);
+extern int git__strcasecmp(const char *a, const char *b);
+extern int git__strncmp(const char *a, const char *b, size_t sz);
+extern int git__strncasecmp(const char *a, const char *b, size_t sz);
+
+extern int git__strcasesort_cmp(const char *a, const char *b);
+
+#include "thread-utils.h"
+
+typedef struct {
+	git_atomic refcount;
+	void *owner;
+} git_refcount;
+
+typedef void (*git_refcount_freeptr)(void *r);
+
+#define GIT_REFCOUNT_INC(r) { \
+	git_atomic_inc(&((git_refcount *)(r))->refcount);	\
+}
+
+#define GIT_REFCOUNT_DEC(_r, do_free) { \
+	git_refcount *r = (git_refcount *)(_r); \
+	int val = git_atomic_dec(&r->refcount); \
+	if (val <= 0 && r->owner == NULL) { do_free(_r); } \
+}
+
+#define GIT_REFCOUNT_OWN(r, o) { \
+	((git_refcount *)(r))->owner = o; \
+}
+
+#define GIT_REFCOUNT_OWNER(r) (((git_refcount *)(r))->owner)
+
+#define GIT_REFCOUNT_VAL(r) git_atomic_get(&((git_refcount *)(r))->refcount)
+
+
+static signed char from_hex[] = {
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 00 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 20 */
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /* 30 */
+-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 40 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 50 */
+-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 60 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 70 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 90 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* a0 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* b0 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* c0 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* d0 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* e0 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* f0 */
+};
+
+GIT_INLINE(int) git__fromhex(char h)
+{
+	return from_hex[(unsigned char) h];
+}
+
+GIT_INLINE(int) git__ishex(const char *str)
+{
+	unsigned i;
+	for (i=0; str[i] != '\0'; i++)
+		if (git__fromhex(str[i]) < 0)
+			return 0;
+	return 1;
+}
+
+GIT_INLINE(size_t) git__size_t_bitmask(size_t v)
+{
+	v--;
+	v |= v >> 1;
+	v |= v >> 2;
+	v |= v >> 4;
+	v |= v >> 8;
+	v |= v >> 16;
+
+	return v;
+}
+
+GIT_INLINE(size_t) git__size_t_powerof2(size_t v)
+{
+	return git__size_t_bitmask(v) + 1;
+}
+
+GIT_INLINE(bool) git__isupper(int c)
+{
+	return (c >= 'A' && c <= 'Z');
+}
+
+GIT_INLINE(bool) git__isalpha(int c)
+{
+	return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
+}
+
+GIT_INLINE(bool) git__isdigit(int c)
+{
+	return (c >= '0' && c <= '9');
+}
+
+GIT_INLINE(bool) git__isspace(int c)
+{
+	return (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r' || c == '\v');
+}
+
+GIT_INLINE(bool) git__isspace_nonlf(int c)
+{
+	return (c == ' ' || c == '\t' || c == '\f' || c == '\r' || c == '\v');
+}
+
+GIT_INLINE(bool) git__iswildcard(int c)
+{
+	return (c == '*' || c == '?' || c == '[');
+}
+
+/*
+ * Parse a string value as a boolean, just like Core Git does.
+ *
+ * Valid values for true are: 'true', 'yes', 'on'
+ * Valid values for false are: 'false', 'no', 'off'
+ */
+extern int git__parse_bool(int *out, const char *value);
+
+/*
+ * Parse a string into a value as a git_time_t.
+ *
+ * Sample valid input:
+ * - "yesterday"
+ * - "July 17, 2003"
+ * - "2003-7-17 08:23"
+ */
+extern int git__date_parse(git_time_t *out, const char *date);
+
+/*
+ * Format a git_time as a RFC2822 string
+ *
+ * @param out buffer to store formatted date; a '\\0' terminator will automatically be added.
+ * @param len size of the buffer; should be atleast `GIT_DATE_RFC2822_SZ` in size;
+ * @param date the date to be formatted
+ * @return 0 if successful; -1 on error
+ */
+extern int git__date_rfc2822_fmt(char *out, size_t len, const git_time *date);
+
+/*
+ * Unescapes a string in-place.
+ *
+ * Edge cases behavior:
+ * - "jackie\" -> "jacky\"
+ * - "chan\\" -> "chan\"
+ */
+extern size_t git__unescape(char *str);
+
+/*
+ * Iterate through an UTF-8 string, yielding one
+ * codepoint at a time.
+ *
+ * @param str current position in the string
+ * @param str_len size left in the string; -1 if the string is NULL-terminated
+ * @param dst pointer where to store the current codepoint
+ * @return length in bytes of the read codepoint; -1 if the codepoint was invalid
+ */
+extern int git__utf8_iterate(const uint8_t *str, int str_len, int32_t *dst);
+
+/*
+ * Safely zero-out memory, making sure that the compiler
+ * doesn't optimize away the operation.
+ */
+GIT_INLINE(void) git__memzero(void *data, size_t size)
+{
+#ifdef _MSC_VER
+	SecureZeroMemory((PVOID)data, size);
+#else
+	volatile uint8_t *scan = (volatile uint8_t *)data;
+
+	while (size--)
+		*scan++ = 0x0;
+#endif
+}
+
+#ifdef GIT_WIN32
+
+GIT_INLINE(double) git__timer(void)
+{
+	/* We need the initial tick count to detect if the tick
+	 * count has rolled over. */
+	static DWORD initial_tick_count = 0;
+
+	/* GetTickCount returns the number of milliseconds that have
+	 * elapsed since the system was started. */
+	DWORD count = GetTickCount();
+
+	if(initial_tick_count == 0) {
+		initial_tick_count = count;
+	} else if (count < initial_tick_count) {
+		/* The tick count has rolled over - adjust for it. */
+		count = (0xFFFFFFFF - initial_tick_count) + count;
+	}
+
+	return (double) count / (double) 1000;
+}
+
+#elif __APPLE__
+
+#include <mach/mach_time.h>
+
+GIT_INLINE(double) git__timer(void)
+{
+   uint64_t time = mach_absolute_time();
+   static double scaling_factor = 0;
+
+   if (scaling_factor == 0) {
+       mach_timebase_info_data_t info;
+       (void)mach_timebase_info(&info);
+       scaling_factor = (double)info.numer / (double)info.denom;
+   }
+
+   return (double)time * scaling_factor / 1.0E9;
+}
+
+#elif defined(AMIGA)
+
+#include <proto/timer.h>
+
+GIT_INLINE(double) git__timer(void)
+{
+	struct TimeVal tv;
+	ITimer->GetUpTime(&tv);
+	return (double)tv.Seconds + (double)tv.Microseconds / 1.0E6;
+}
+
+#else
+
+#include <sys/time.h>
+
+GIT_INLINE(double) git__timer(void)
+{
+	struct timespec tp;
+
+	if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
+		return (double) tp.tv_sec + (double) tp.tv_nsec / 1.0E9;
+	} else {
+		/* Fall back to using gettimeofday */
+		struct timeval tv;
+		struct timezone tz;
+		gettimeofday(&tv, &tz);
+		return (double)tv.tv_sec + (double)tv.tv_usec / 1.0E6;
+	}
+}
+
+#endif
+
+#endif /* INCLUDE_util_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/vector.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/vector.c
new file mode 100755
index 0000000..93d09bb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/vector.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "vector.h"
+
+/* In elements, not bytes */
+#define MIN_ALLOCSIZE	8
+
+GIT_INLINE(size_t) compute_new_size(git_vector *v)
+{
+	size_t new_size = v->_alloc_size;
+
+	/* Use a resize factor of 1.5, which is quick to compute using integer
+	 * instructions and less than the golden ratio (1.618...) */
+	if (new_size < MIN_ALLOCSIZE)
+		new_size = MIN_ALLOCSIZE;
+	else if (new_size <= (SIZE_MAX / 3) * 2)
+		new_size += new_size / 2;
+	else
+		new_size = SIZE_MAX;
+
+	return new_size;
+}
+
+GIT_INLINE(int) resize_vector(git_vector *v, size_t new_size)
+{
+	void *new_contents;
+
+	new_contents = git__reallocarray(v->contents, new_size, sizeof(void *));
+	GITERR_CHECK_ALLOC(new_contents);
+
+	v->_alloc_size = new_size;
+	v->contents = new_contents;
+
+	return 0;
+}
+
+int git_vector_dup(git_vector *v, const git_vector *src, git_vector_cmp cmp)
+{
+	size_t bytes;
+
+	assert(v && src);
+
+	GITERR_CHECK_ALLOC_MULTIPLY(&bytes, src->length, sizeof(void *));
+
+	v->_alloc_size = src->length;
+	v->_cmp = cmp ? cmp : src->_cmp;
+	v->length = src->length;
+	v->flags  = src->flags;
+	if (cmp != src->_cmp)
+		git_vector_set_sorted(v, 0);
+	v->contents = git__malloc(bytes);
+	GITERR_CHECK_ALLOC(v->contents);
+
+	memcpy(v->contents, src->contents, bytes);
+
+	return 0;
+}
+
+void git_vector_free(git_vector *v)
+{
+	assert(v);
+
+	git__free(v->contents);
+	v->contents = NULL;
+
+	v->length = 0;
+	v->_alloc_size = 0;
+}
+
+void git_vector_free_deep(git_vector *v)
+{
+	size_t i;
+
+	assert(v);
+
+	for (i = 0; i < v->length; ++i) {
+		git__free(v->contents[i]);
+		v->contents[i] = NULL;
+	}
+
+	git_vector_free(v);
+}
+
+int git_vector_init(git_vector *v, size_t initial_size, git_vector_cmp cmp)
+{
+	assert(v);
+
+	v->_alloc_size = 0;
+	v->_cmp = cmp;
+	v->length = 0;
+	v->flags = GIT_VECTOR_SORTED;
+	v->contents = NULL;
+
+	return resize_vector(v, max(initial_size, MIN_ALLOCSIZE));
+}
+
+void **git_vector_detach(size_t *size, size_t *asize, git_vector *v)
+{
+	void **data = v->contents;
+
+	if (size)
+		*size = v->length;
+	if (asize)
+		*asize = v->_alloc_size;
+
+	v->_alloc_size = 0;
+	v->length   = 0;
+	v->contents = NULL;
+
+	return data;
+}
+
+int git_vector_insert(git_vector *v, void *element)
+{
+	assert(v);
+
+	if (v->length >= v->_alloc_size &&
+		resize_vector(v, compute_new_size(v)) < 0)
+		return -1;
+
+	v->contents[v->length++] = element;
+
+	git_vector_set_sorted(v, v->length <= 1);
+
+	return 0;
+}
+
+int git_vector_insert_sorted(
+	git_vector *v, void *element, int (*on_dup)(void **old, void *new))
+{
+	int result;
+	size_t pos;
+
+	assert(v && v->_cmp);
+
+	if (!git_vector_is_sorted(v))
+		git_vector_sort(v);
+
+	if (v->length >= v->_alloc_size &&
+		resize_vector(v, compute_new_size(v)) < 0)
+		return -1;
+
+	/* If we find the element and have a duplicate handler callback,
+	 * invoke it.  If it returns non-zero, then cancel insert, otherwise
+	 * proceed with normal insert.
+	 */
+	if (!git__bsearch(v->contents, v->length, element, v->_cmp, &pos) &&
+		on_dup && (result = on_dup(&v->contents[pos], element)) < 0)
+		return result;
+
+	/* shift elements to the right */
+	if (pos < v->length)
+		memmove(v->contents + pos + 1, v->contents + pos,
+		        (v->length - pos) * sizeof(void *));
+
+	v->contents[pos] = element;
+	v->length++;
+
+	return 0;
+}
+
+void git_vector_sort(git_vector *v)
+{
+	assert(v);
+
+	if (git_vector_is_sorted(v) || !v->_cmp)
+		return;
+
+	if (v->length > 1)
+		git__tsort(v->contents, v->length, v->_cmp);
+	git_vector_set_sorted(v, 1);
+}
+
+int git_vector_bsearch2(
+	size_t *at_pos,
+	git_vector *v,
+	git_vector_cmp key_lookup,
+	const void *key)
+{
+	assert(v && key && key_lookup);
+
+	/* need comparison function to sort the vector */
+	if (!v->_cmp)
+		return -1;
+
+	git_vector_sort(v);
+
+	return git__bsearch(v->contents, v->length, key, key_lookup, at_pos);
+}
+
+int git_vector_search2(
+	size_t *at_pos, const git_vector *v, git_vector_cmp key_lookup, const void *key)
+{
+	size_t i;
+
+	assert(v && key && key_lookup);
+
+	for (i = 0; i < v->length; ++i) {
+		if (key_lookup(key, v->contents[i]) == 0) {
+			if (at_pos)
+				*at_pos = i;
+
+			return 0;
+		}
+	}
+
+	return GIT_ENOTFOUND;
+}
+
+static int strict_comparison(const void *a, const void *b)
+{
+	return (a == b) ? 0 : -1;
+}
+
+int git_vector_search(size_t *at_pos, const git_vector *v, const void *entry)
+{
+	return git_vector_search2(at_pos, v, v->_cmp ? v->_cmp : strict_comparison, entry);
+}
+
+int git_vector_remove(git_vector *v, size_t idx)
+{
+	size_t shift_count;
+
+	assert(v);
+
+	if (idx >= v->length)
+		return GIT_ENOTFOUND;
+
+	shift_count = v->length - idx - 1;
+
+	if (shift_count)
+		memmove(&v->contents[idx], &v->contents[idx + 1],
+			shift_count * sizeof(void *));
+
+	v->length--;
+	return 0;
+}
+
+void git_vector_pop(git_vector *v)
+{
+	if (v->length > 0)
+		v->length--;
+}
+
+void git_vector_uniq(git_vector *v, void  (*git_free_cb)(void *))
+{
+	git_vector_cmp cmp;
+	size_t i, j;
+
+	if (v->length <= 1)
+		return;
+
+	git_vector_sort(v);
+	cmp = v->_cmp ? v->_cmp : strict_comparison;
+
+	for (i = 0, j = 1 ; j < v->length; ++j)
+		if (!cmp(v->contents[i], v->contents[j])) {
+			if (git_free_cb)
+				git_free_cb(v->contents[i]);
+
+			v->contents[i] = v->contents[j];
+		} else
+			v->contents[++i] = v->contents[j];
+
+	v->length -= j - i - 1;
+}
+
+void git_vector_remove_matching(
+	git_vector *v,
+	int (*match)(const git_vector *v, size_t idx, void *payload),
+	void *payload)
+{
+	size_t i, j;
+
+	for (i = 0, j = 0; j < v->length; ++j) {
+		v->contents[i] = v->contents[j];
+
+		if (!match(v, i, payload))
+			i++;
+	}
+
+	v->length = i;
+}
+
+void git_vector_clear(git_vector *v)
+{
+	assert(v);
+	v->length = 0;
+	git_vector_set_sorted(v, 1);
+}
+
+void git_vector_swap(git_vector *a, git_vector *b)
+{
+	git_vector t;
+
+	assert(a && b);
+
+	if (a != b) {
+		memcpy(&t, a, sizeof(t));
+		memcpy(a, b, sizeof(t));
+		memcpy(b, &t, sizeof(t));
+	}
+}
+
+int git_vector_resize_to(git_vector *v, size_t new_length)
+{
+	if (new_length > v->_alloc_size &&
+		resize_vector(v, new_length) < 0)
+		return -1;
+
+	if (new_length > v->length)
+		memset(&v->contents[v->length], 0,
+			sizeof(void *) * (new_length - v->length));
+
+	v->length = new_length;
+
+	return 0;
+}
+
+int git_vector_set(void **old, git_vector *v, size_t position, void *value)
+{
+	if (position + 1 > v->length) {
+		if (git_vector_resize_to(v, position + 1) < 0)
+			return -1;
+	}
+
+	if (old != NULL)
+		*old = v->contents[position];
+
+	v->contents[position] = value;
+
+	return 0;
+}
+
+int git_vector_verify_sorted(const git_vector *v)
+{
+	size_t i;
+
+	if (!git_vector_is_sorted(v))
+		return -1;
+
+	for (i = 1; i < v->length; ++i) {
+		if (v->_cmp(v->contents[i - 1], v->contents[i]) > 0)
+			return -1;
+	}
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/vector.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/vector.h
new file mode 100755
index 0000000..aac46c4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/vector.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_vector_h__
+#define INCLUDE_vector_h__
+
+#include "common.h"
+
+typedef int (*git_vector_cmp)(const void *, const void *);
+
+enum {
+	GIT_VECTOR_SORTED = (1u << 0),
+	GIT_VECTOR_FLAG_MAX = (1u << 1),
+};
+
+typedef struct git_vector {
+	size_t _alloc_size;
+	git_vector_cmp _cmp;
+	void **contents;
+	size_t length;
+	uint32_t flags;
+} git_vector;
+
+#define GIT_VECTOR_INIT {0}
+
+int git_vector_init(git_vector *v, size_t initial_size, git_vector_cmp cmp);
+void git_vector_free(git_vector *v);
+void git_vector_free_deep(git_vector *v); /* free each entry and self */
+void git_vector_clear(git_vector *v);
+int git_vector_dup(git_vector *v, const git_vector *src, git_vector_cmp cmp);
+void git_vector_swap(git_vector *a, git_vector *b);
+
+void **git_vector_detach(size_t *size, size_t *asize, git_vector *v);
+
+void git_vector_sort(git_vector *v);
+
+/** Linear search for matching entry using internal comparison function */
+int git_vector_search(size_t *at_pos, const git_vector *v, const void *entry);
+
+/** Linear search for matching entry using explicit comparison function */
+int git_vector_search2(size_t *at_pos, const git_vector *v, git_vector_cmp cmp, const void *key);
+
+/**
+ * Binary search for matching entry using explicit comparison function that
+ * returns position where item would go if not found.
+ */
+int git_vector_bsearch2(
+	size_t *at_pos, git_vector *v, git_vector_cmp cmp, const void *key);
+
+/** Binary search for matching entry using internal comparison function */
+GIT_INLINE(int) git_vector_bsearch(size_t *at_pos, git_vector *v, const void *key)
+{
+	return git_vector_bsearch2(at_pos, v, v->_cmp, key);
+}
+
+GIT_INLINE(void *) git_vector_get(const git_vector *v, size_t position)
+{
+	return (position < v->length) ? v->contents[position] : NULL;
+}
+
+#define GIT_VECTOR_GET(V,I) ((I) < (V)->length ? (V)->contents[(I)] : NULL)
+
+GIT_INLINE(size_t) git_vector_length(const git_vector *v)
+{
+	return v->length;
+}
+
+GIT_INLINE(void *) git_vector_last(const git_vector *v)
+{
+	return (v->length > 0) ? git_vector_get(v, v->length - 1) : NULL;
+}
+
+#define git_vector_foreach(v, iter, elem)	\
+	for ((iter) = 0; (iter) < (v)->length && ((elem) = (v)->contents[(iter)], 1); (iter)++ )
+
+#define git_vector_rforeach(v, iter, elem)	\
+	for ((iter) = (v)->length - 1; (iter) < SIZE_MAX && ((elem) = (v)->contents[(iter)], 1); (iter)-- )
+
+int git_vector_insert(git_vector *v, void *element);
+int git_vector_insert_sorted(git_vector *v, void *element,
+	int (*on_dup)(void **old, void *new));
+int git_vector_remove(git_vector *v, size_t idx);
+void git_vector_pop(git_vector *v);
+void git_vector_uniq(git_vector *v, void  (*git_free_cb)(void *));
+
+void git_vector_remove_matching(
+	git_vector *v,
+	int (*match)(const git_vector *v, size_t idx, void *payload),
+	void *payload);
+
+int git_vector_resize_to(git_vector *v, size_t new_length);
+int git_vector_set(void **old, git_vector *v, size_t position, void *value);
+
+/** Check if vector is sorted */
+#define git_vector_is_sorted(V) (((V)->flags & GIT_VECTOR_SORTED) != 0)
+
+/** Directly set sorted state of vector */
+#define git_vector_set_sorted(V,S) do { \
+	(V)->flags = (S) ? ((V)->flags | GIT_VECTOR_SORTED) : \
+		((V)->flags & ~GIT_VECTOR_SORTED); } while (0)
+
+/** Set the comparison function used for sorting the vector */
+GIT_INLINE(void) git_vector_set_cmp(git_vector *v, git_vector_cmp cmp)
+{
+	if (cmp != v->_cmp) {
+		v->_cmp = cmp;
+		git_vector_set_sorted(v, 0);
+	}
+}
+
+/* Just use this in tests, not for realz. returns -1 if not sorted */
+int git_vector_verify_sorted(const git_vector *v);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/dir.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/dir.c
new file mode 100755
index 0000000..c157570
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/dir.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#define GIT__WIN32_NO_WRAP_DIR
+#include "posix.h"
+
+git__DIR *git__opendir(const char *dir)
+{
+	git_win32_path filter_w;
+	git__DIR *new = NULL;
+	size_t dirlen, alloclen;
+
+	if (!dir || !git_win32__findfirstfile_filter(filter_w, dir))
+		return NULL;
+
+	dirlen = strlen(dir);
+
+	if (GIT_ADD_SIZET_OVERFLOW(&alloclen, sizeof(*new), dirlen) ||
+		GIT_ADD_SIZET_OVERFLOW(&alloclen, alloclen, 1) ||
+		!(new = git__calloc(1, alloclen)))
+		return NULL;
+
+	memcpy(new->dir, dir, dirlen);
+
+	new->h = FindFirstFileW(filter_w, &new->f);
+
+	if (new->h == INVALID_HANDLE_VALUE) {
+		giterr_set(GITERR_OS, "Could not open directory '%s'", dir);
+		git__free(new);
+		return NULL;
+	}
+
+	new->first = 1;
+	return new;
+}
+
+int git__readdir_ext(
+	git__DIR *d,
+	struct git__dirent *entry,
+	struct git__dirent **result,
+	int *is_dir)
+{
+	if (!d || !entry || !result || d->h == INVALID_HANDLE_VALUE)
+		return -1;
+
+	*result = NULL;
+
+	if (d->first)
+		d->first = 0;
+	else if (!FindNextFileW(d->h, &d->f)) {
+		if (GetLastError() == ERROR_NO_MORE_FILES)
+			return 0;
+		giterr_set(GITERR_OS, "Could not read from directory '%s'", d->dir);
+		return -1;
+	}
+
+	/* Convert the path to UTF-8 */
+	if (git_win32_path_to_utf8(entry->d_name, d->f.cFileName) < 0)
+		return -1;
+
+	entry->d_ino = 0;
+
+	*result = entry;
+
+	if (is_dir != NULL)
+		*is_dir = ((d->f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
+
+	return 0;
+}
+
+struct git__dirent *git__readdir(git__DIR *d)
+{
+	struct git__dirent *result;
+	if (git__readdir_ext(d, &d->entry, &result, NULL) < 0)
+		return NULL;
+	return result;
+}
+
+void git__rewinddir(git__DIR *d)
+{
+	git_win32_path filter_w;
+
+	if (!d)
+		return;
+
+	if (d->h != INVALID_HANDLE_VALUE) {
+		FindClose(d->h);
+		d->h = INVALID_HANDLE_VALUE;
+		d->first = 0;
+	}
+
+	if (!git_win32__findfirstfile_filter(filter_w, d->dir))
+		return;
+
+	d->h = FindFirstFileW(filter_w, &d->f);
+
+	if (d->h == INVALID_HANDLE_VALUE)
+		giterr_set(GITERR_OS, "Could not open directory '%s'", d->dir);
+	else
+		d->first = 1;
+}
+
+int git__closedir(git__DIR *d)
+{
+	if (!d)
+		return 0;
+
+	if (d->h != INVALID_HANDLE_VALUE) {
+		FindClose(d->h);
+		d->h = INVALID_HANDLE_VALUE;
+	}
+
+	git__free(d);
+	return 0;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/dir.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/dir.h
new file mode 100755
index 0000000..bef39d7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/dir.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_dir_h__
+#define INCLUDE_dir_h__
+
+#include "common.h"
+#include "w32_util.h"
+
+struct git__dirent {
+	int d_ino;
+	git_win32_utf8_path d_name;
+};
+
+typedef struct {
+	HANDLE h;
+	WIN32_FIND_DATAW f;
+	struct git__dirent entry;
+	int first;
+	char dir[GIT_FLEX_ARRAY];
+} git__DIR;
+
+extern git__DIR *git__opendir(const char *);
+extern struct git__dirent *git__readdir(git__DIR *);
+extern int git__readdir_ext(
+	git__DIR *, struct git__dirent *, struct git__dirent **, int *);
+extern void git__rewinddir(git__DIR *);
+extern int git__closedir(git__DIR *);
+
+# ifndef GIT__WIN32_NO_WRAP_DIR
+#	define dirent git__dirent
+#	define DIR git__DIR
+#	define opendir	git__opendir
+#	define readdir	git__readdir
+#   define readdir_r(d,e,r) git__readdir_ext((d),(e),(r),NULL)
+#	define rewinddir git__rewinddir
+#	define closedir git__closedir
+# endif
+
+#endif /* INCLUDE_dir_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/error.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/error.c
new file mode 100755
index 0000000..6b45009
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/error.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "error.h"
+#include "utf-conv.h"
+
+#ifdef GIT_WINHTTP
+# include <winhttp.h>
+#endif
+
+char *git_win32_get_error_message(DWORD error_code)
+{
+	LPWSTR lpMsgBuf = NULL;
+	HMODULE hModule = NULL;
+	char *utf8_msg = NULL;
+	DWORD dwFlags =
+		FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS;
+
+	if (!error_code)
+		return NULL;
+
+#ifdef GIT_WINHTTP
+	/* Errors raised by WinHTTP are not in the system resource table */
+	if (error_code >= WINHTTP_ERROR_BASE &&
+		error_code <= WINHTTP_ERROR_LAST)
+		hModule = GetModuleHandleW(L"winhttp");
+#endif
+
+	GIT_UNUSED(hModule);
+
+	if (hModule)
+		dwFlags |= FORMAT_MESSAGE_FROM_HMODULE;
+	else
+		dwFlags |= FORMAT_MESSAGE_FROM_SYSTEM;
+
+	if (FormatMessageW(dwFlags, hModule, error_code,
+		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+		(LPWSTR)&lpMsgBuf, 0, NULL)) {
+		/* Convert the message to UTF-8. If this fails, we will
+		 * return NULL, which is a condition expected by the caller */
+		if (git__utf16_to_8_alloc(&utf8_msg, lpMsgBuf) < 0)
+			utf8_msg = NULL;
+
+		LocalFree(lpMsgBuf);
+	}
+
+	return utf8_msg;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/error.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/error.h
new file mode 100755
index 0000000..12947a2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/error.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_git_win32_error_h__
+#define INCLUDE_git_win32_error_h__
+
+extern char *git_win32_get_error_message(DWORD error_code);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/findfile.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/findfile.c
new file mode 100755
index 0000000..de27dd0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/findfile.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "path_w32.h"
+#include "utf-conv.h"
+#include "path.h"
+#include "findfile.h"
+
+#define REG_MSYSGIT_INSTALL_LOCAL L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1"
+
+#ifndef _WIN64
+#define REG_MSYSGIT_INSTALL REG_MSYSGIT_INSTALL_LOCAL
+#else
+#define REG_MSYSGIT_INSTALL L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1"
+#endif
+
+typedef struct {
+	git_win32_path path;
+	DWORD len;
+} _findfile_path;
+
+static int git_win32__expand_path(_findfile_path *dest, const wchar_t *src)
+{
+	dest->len = ExpandEnvironmentStringsW(src, dest->path, ARRAY_SIZE(dest->path));
+
+	if (!dest->len || dest->len > ARRAY_SIZE(dest->path))
+		return -1;
+
+	return 0;
+}
+
+static int win32_path_to_8(git_buf *dest, const wchar_t *src)
+{
+	git_win32_utf8_path utf8_path;
+
+	if (git_win32_path_to_utf8(utf8_path, src) < 0) {
+		giterr_set(GITERR_OS, "Unable to convert path to UTF-8");
+		return -1;
+	}
+
+	/* Convert backslashes to forward slashes */
+	git_path_mkposix(utf8_path);
+
+	return git_buf_sets(dest, utf8_path);
+}
+
+static wchar_t* win32_walkpath(wchar_t *path, wchar_t *buf, size_t buflen)
+{
+	wchar_t term, *base = path;
+
+	assert(path && buf && buflen);
+
+	term = (*path == L'"') ? *path++ : L';';
+
+	for (buflen--; *path && *path != term && buflen; buflen--)
+		*buf++ = *path++;
+
+	*buf = L'\0'; /* reserved a byte via initial subtract */
+
+	while (*path == term || *path == L';')
+		path++;
+
+	return (path != base) ? path : NULL;
+}
+
+static int win32_find_git_in_path(git_buf *buf, const wchar_t *gitexe, const wchar_t *subdir)
+{
+	wchar_t *env = _wgetenv(L"PATH"), lastch;
+	_findfile_path root;
+	size_t gitexe_len = wcslen(gitexe);
+
+	if (!env)
+		return -1;
+
+	while ((env = win32_walkpath(env, root.path, MAX_PATH-1)) && *root.path) {
+		root.len = (DWORD)wcslen(root.path);
+		lastch = root.path[root.len - 1];
+
+		/* ensure trailing slash (MAX_PATH-1 to walkpath guarantees space) */
+		if (lastch != L'/' && lastch != L'\\') {
+			root.path[root.len++] = L'\\';
+			root.path[root.len]   = L'\0';
+		}
+
+		if (root.len + gitexe_len >= MAX_PATH)
+			continue;
+		wcscpy(&root.path[root.len], gitexe);
+
+		if (_waccess(root.path, F_OK) == 0 && root.len > 5) {
+			/* replace "bin\\" or "cmd\\" with subdir */
+			wcscpy(&root.path[root.len - 4], subdir);
+
+			win32_path_to_8(buf, root.path);
+			return 0;
+		}
+	}
+
+	return GIT_ENOTFOUND;
+}
+
+static int win32_find_git_in_registry(
+	git_buf *buf, const HKEY hive, const wchar_t *key, const wchar_t *subdir)
+{
+	HKEY hKey;
+	int error = GIT_ENOTFOUND;
+
+	assert(buf);
+
+	if (!RegOpenKeyExW(hive, key, 0, KEY_READ, &hKey)) {
+		DWORD dwType, cbData;
+		git_win32_path path;
+
+		/* Ensure that the buffer is big enough to have the suffix attached
+		 * after we receive the result. */
+		cbData = (DWORD)(sizeof(path) - wcslen(subdir) * sizeof(wchar_t));
+
+		/* InstallLocation points to the root of the git directory */
+		if (!RegQueryValueExW(hKey, L"InstallLocation", NULL, &dwType, (LPBYTE)path, &cbData) &&
+			dwType == REG_SZ) {
+
+			/* Append the suffix */
+			wcscat(path, subdir);
+
+			/* Convert to UTF-8, with forward slashes, and output the path
+			 * to the provided buffer */
+			if (!win32_path_to_8(buf, path))
+				error = 0;
+		}
+
+		RegCloseKey(hKey);
+	}
+
+	return error;
+}
+
+static int win32_find_existing_dirs(
+	git_buf *out, const wchar_t *tmpl[])
+{
+	_findfile_path path16;
+	git_buf buf = GIT_BUF_INIT;
+
+	git_buf_clear(out);
+
+	for (; *tmpl != NULL; tmpl++) {
+		if (!git_win32__expand_path(&path16, *tmpl) &&
+			path16.path[0] != L'%' &&
+			!_waccess(path16.path, F_OK))
+		{
+			win32_path_to_8(&buf, path16.path);
+
+			if (buf.size)
+				git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr);
+		}
+	}
+
+	git_buf_free(&buf);
+
+	return (git_buf_oom(out) ? -1 : 0);
+}
+
+int git_win32__find_system_dirs(git_buf *out, const wchar_t *subdir)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	/* directories where git.exe & git.cmd are found */
+	if (!win32_find_git_in_path(&buf, L"git.exe", subdir) && buf.size)
+		git_buf_set(out, buf.ptr, buf.size);
+	else
+		git_buf_clear(out);
+
+	if (!win32_find_git_in_path(&buf, L"git.cmd", subdir) && buf.size)
+		git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr);
+
+	/* directories where git is installed according to registry */
+	if (!win32_find_git_in_registry(
+			&buf, HKEY_CURRENT_USER, REG_MSYSGIT_INSTALL_LOCAL, subdir) && buf.size)
+		git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr);
+
+	if (!win32_find_git_in_registry(
+			&buf, HKEY_LOCAL_MACHINE, REG_MSYSGIT_INSTALL, subdir) && buf.size)
+		git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr);
+
+	git_buf_free(&buf);
+
+	return (git_buf_oom(out) ? -1 : 0);
+}
+
+int git_win32__find_global_dirs(git_buf *out)
+{
+	static const wchar_t *global_tmpls[4] = {
+		L"%HOME%\\",
+		L"%HOMEDRIVE%%HOMEPATH%\\",
+		L"%USERPROFILE%\\",
+		NULL,
+	};
+
+	return win32_find_existing_dirs(out, global_tmpls);
+}
+
+int git_win32__find_xdg_dirs(git_buf *out)
+{
+	static const wchar_t *global_tmpls[7] = {
+		L"%XDG_CONFIG_HOME%\\git",
+		L"%APPDATA%\\git",
+		L"%LOCALAPPDATA%\\git",
+		L"%HOME%\\.config\\git",
+		L"%HOMEDRIVE%%HOMEPATH%\\.config\\git",
+		L"%USERPROFILE%\\.config\\git",
+		NULL,
+	};
+
+	return win32_find_existing_dirs(out, global_tmpls);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/findfile.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/findfile.h
new file mode 100755
index 0000000..a50319b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/findfile.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_git_findfile_h__
+#define INCLUDE_git_findfile_h__
+
+extern int git_win32__find_system_dirs(git_buf *out, const wchar_t *subpath);
+extern int git_win32__find_global_dirs(git_buf *out);
+extern int git_win32__find_xdg_dirs(git_buf *out);
+
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/git2.rc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/git2.rc
new file mode 100755
index 0000000..3571bc6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/git2.rc
@@ -0,0 +1,44 @@
+#include <winver.h>
+#include "../../include/git2/version.h"
+
+#ifndef LIBGIT2_FILENAME
+# define LIBGIT2_FILENAME "git2"
+#endif
+
+#ifndef LIBGIT2_COMMENTS
+# define LIBGIT2_COMMENTS "For more information visit http://libgit2.github.com/"
+#endif
+
+VS_VERSION_INFO		VERSIONINFO	MOVEABLE IMPURE LOADONCALL DISCARDABLE
+  FILEVERSION		LIBGIT2_VER_MAJOR,LIBGIT2_VER_MINOR,LIBGIT2_VER_REVISION,LIBGIT2_VER_PATCH
+  PRODUCTVERSION	LIBGIT2_VER_MAJOR,LIBGIT2_VER_MINOR,LIBGIT2_VER_REVISION,LIBGIT2_VER_PATCH
+  FILEFLAGSMASK		VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+  FILEFLAGS		VS_FF_DEBUG
+#else
+  FILEFLAGS		0
+#endif
+  FILEOS		VOS_NT_WINDOWS32
+  FILETYPE		VFT_DLL
+  FILESUBTYPE	VFT2_UNKNOWN
+BEGIN
+  BLOCK "StringFileInfo"
+  BEGIN
+    BLOCK "040904E4"
+    //language ID = U.S. English, char set = Windows, Multilingual
+    BEGIN
+      VALUE "FileDescription",	"libgit2 - the Git linkable library\0"
+      VALUE "FileVersion",	LIBGIT2_VERSION "\0"
+      VALUE "InternalName",	LIBGIT2_FILENAME ".dll\0"
+      VALUE "LegalCopyright",	"Copyright (C) the libgit2 contributors. All rights reserved.\0"
+      VALUE "OriginalFilename",	LIBGIT2_FILENAME ".dll\0"
+      VALUE "ProductName",	"libgit2\0"
+      VALUE "ProductVersion",	LIBGIT2_VERSION "\0"
+      VALUE "Comments",		LIBGIT2_COMMENTS "\0"
+    END
+  END
+  BLOCK "VarFileInfo"
+  BEGIN
+    VALUE "Translation", 0x0409, 1252
+  END
+END
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/map.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/map.c
new file mode 100755
index 0000000..a99c30f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/map.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "map.h"
+#include <errno.h>
+
+#ifndef NO_MMAP
+
+static DWORD get_page_size(void)
+{
+	static DWORD page_size;
+	SYSTEM_INFO sys;
+
+	if (!page_size) {
+		GetSystemInfo(&sys);
+		page_size = sys.dwAllocationGranularity;
+	}
+
+	return page_size;
+}
+
+int git__page_size(size_t *page_size)
+{
+	*page_size = get_page_size();
+	return 0;
+}
+
+int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset)
+{
+	HANDLE fh = (HANDLE)_get_osfhandle(fd);
+	DWORD page_size = get_page_size();
+	DWORD fmap_prot = 0;
+	DWORD view_prot = 0;
+	DWORD off_low = 0;
+	DWORD off_hi = 0;
+	git_off_t page_start;
+	git_off_t page_offset;
+
+	GIT_MMAP_VALIDATE(out, len, prot, flags);
+
+	out->data = NULL;
+	out->len = 0;
+	out->fmh = NULL;
+
+	if (fh == INVALID_HANDLE_VALUE) {
+		errno = EBADF;
+		giterr_set(GITERR_OS, "Failed to mmap. Invalid handle value");
+		return -1;
+	}
+
+	if (prot & GIT_PROT_WRITE)
+		fmap_prot |= PAGE_READWRITE;
+	else if (prot & GIT_PROT_READ)
+		fmap_prot |= PAGE_READONLY;
+
+	if (prot & GIT_PROT_WRITE)
+		view_prot |= FILE_MAP_WRITE;
+	if (prot & GIT_PROT_READ)
+		view_prot |= FILE_MAP_READ;
+
+	page_start = (offset / page_size) * page_size;
+	page_offset = offset - page_start;
+
+	if (page_offset != 0) { /* offset must be multiple of page size */
+		errno = EINVAL;
+		giterr_set(GITERR_OS, "Failed to mmap. Offset must be multiple of page size");
+		return -1;
+	}
+
+	out->fmh = CreateFileMapping(fh, NULL, fmap_prot, 0, 0, NULL);
+	if (!out->fmh || out->fmh == INVALID_HANDLE_VALUE) {
+		giterr_set(GITERR_OS, "Failed to mmap. Invalid handle value");
+		out->fmh = NULL;
+		return -1;
+	}
+
+	assert(sizeof(git_off_t) == 8);
+
+	off_low = (DWORD)(page_start);
+	off_hi = (DWORD)(page_start >> 32);
+	out->data = MapViewOfFile(out->fmh, view_prot, off_hi, off_low, len);
+	if (!out->data) {
+		giterr_set(GITERR_OS, "Failed to mmap. No data written");
+		CloseHandle(out->fmh);
+		out->fmh = NULL;
+		return -1;
+	}
+	out->len = len;
+
+	return 0;
+}
+
+int p_munmap(git_map *map)
+{
+	int error = 0;
+
+	assert(map != NULL);
+
+	if (map->data) {
+		if (!UnmapViewOfFile(map->data)) {
+			giterr_set(GITERR_OS, "Failed to munmap. Could not unmap view of file");
+			error = -1;
+		}
+		map->data = NULL;
+	}
+
+	if (map->fmh) {
+		if (!CloseHandle(map->fmh)) {
+			giterr_set(GITERR_OS, "Failed to munmap. Could not close handle");
+			error = -1;
+		}
+		map->fmh = NULL;
+	}
+
+	return error;
+}
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/mingw-compat.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/mingw-compat.h
new file mode 100755
index 0000000..a4a5a31
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/mingw-compat.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_mingw_compat__
+#define INCLUDE_mingw_compat__
+
+#if defined(__MINGW32__)
+
+#undef stat
+
+#if _WIN32_WINNT >= 0x0601
+#define stat __stat64
+#else
+#define stat _stati64
+#endif
+
+#if _WIN32_WINNT < 0x0600 && !defined(__MINGW64_VERSION_MAJOR)
+#undef MemoryBarrier
+void __mingworg_MemoryBarrier(void);
+#define MemoryBarrier __mingworg_MemoryBarrier
+#define VOLUME_NAME_DOS 0x0
+#endif
+
+#endif
+
+#endif /* INCLUDE_mingw_compat__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/msvc-compat.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/msvc-compat.h
new file mode 100755
index 0000000..8004bc1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/msvc-compat.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_msvc_compat__
+#define INCLUDE_msvc_compat__
+
+#if defined(_MSC_VER)
+
+/* 64-bit stat information, regardless of USE_32BIT_TIME_T define */
+#define stat __stat64
+
+typedef unsigned short mode_t;
+typedef SSIZE_T ssize_t;
+
+#define strcasecmp(s1, s2) _stricmp(s1, s2)
+#define strncasecmp(s1, s2, c) _strnicmp(s1, s2, c)
+
+#endif
+
+#define GIT_STDLIB_CALL __cdecl
+
+#endif /* INCLUDE_msvc_compat__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/path_w32.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/path_w32.c
new file mode 100755
index 0000000..118e8bc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/path_w32.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "path.h"
+#include "path_w32.h"
+#include "utf-conv.h"
+#include "posix.h"
+#include "reparse.h"
+#include "dir.h"
+
+#define PATH__NT_NAMESPACE     L"\\\\?\\"
+#define PATH__NT_NAMESPACE_LEN 4
+
+#define PATH__ABSOLUTE_LEN     3
+
+#define path__is_dirsep(p) ((p) == '/' || (p) == '\\')
+
+#define path__is_absolute(p) \
+	(git__isalpha((p)[0]) && (p)[1] == ':' && ((p)[2] == '\\' || (p)[2] == '/'))
+
+#define path__is_nt_namespace(p) \
+	(((p)[0] == '\\' && (p)[1] == '\\' && (p)[2] == '?' && (p)[3] == '\\') || \
+	 ((p)[0] == '/' && (p)[1] == '/' && (p)[2] == '?' && (p)[3] == '/'))
+
+#define path__is_unc(p) \
+	(((p)[0] == '\\' && (p)[1] == '\\') || ((p)[0] == '/' && (p)[1] == '/'))
+
+GIT_INLINE(int) path__cwd(wchar_t *path, int size)
+{
+	int len;
+
+	if ((len = GetCurrentDirectoryW(size, path)) == 0) {
+		errno = GetLastError() == ERROR_ACCESS_DENIED ? EACCES : ENOENT;
+		return -1;
+	} else if (len > size) {
+		errno = ENAMETOOLONG;
+		return -1;
+	}
+
+	/* The Win32 APIs may return "\\?\" once you've used it first.
+	 * But it may not.  What a gloriously predictible API!
+	 */
+	if (wcsncmp(path, PATH__NT_NAMESPACE, PATH__NT_NAMESPACE_LEN))
+		return len;
+
+	len -= PATH__NT_NAMESPACE_LEN;
+
+	memmove(path, path + PATH__NT_NAMESPACE_LEN, sizeof(wchar_t) * len);
+	return len;
+}
+
+static wchar_t *path__skip_server(wchar_t *path)
+{
+	wchar_t *c;
+
+	for (c = path; *c; c++) {
+		if (path__is_dirsep(*c))
+			return c + 1;
+	}
+
+	return c;
+}
+
+static wchar_t *path__skip_prefix(wchar_t *path)
+{
+	if (path__is_nt_namespace(path)) {
+		path += PATH__NT_NAMESPACE_LEN;
+
+		if (wcsncmp(path, L"UNC\\", 4) == 0)
+			path = path__skip_server(path + 4);
+		else if (path__is_absolute(path))
+			path += PATH__ABSOLUTE_LEN;
+	} else if (path__is_absolute(path)) {
+		path += PATH__ABSOLUTE_LEN;
+	} else if (path__is_unc(path)) {
+		path = path__skip_server(path + 2);
+	}
+
+	return path;
+}
+
+int git_win32_path_canonicalize(git_win32_path path)
+{
+	wchar_t *base, *from, *to, *next;
+	size_t len;
+
+	base = to = path__skip_prefix(path);
+
+	/* Unposixify if the prefix */
+	for (from = path; from < to; from++) {
+		if (*from == L'/')
+			*from = L'\\';
+	}
+
+	while (*from) {
+		for (next = from; *next; ++next) {
+			if (*next == L'/') {
+				*next = L'\\';
+				break;
+			}
+
+			if (*next == L'\\')
+				break;
+		}
+
+		len = next - from;
+
+		if (len == 1 && from[0] == L'.')
+			/* do nothing with singleton dot */;
+
+		else if (len == 2 && from[0] == L'.' && from[1] == L'.') {
+			if (to == base) {
+				/* no more path segments to strip, eat the "../" */
+				if (*next == L'\\')
+					len++;
+
+				base = to;
+			} else {
+				/* back up a path segment */
+				while (to > base && to[-1] == L'\\') to--;
+				while (to > base && to[-1] != L'\\') to--;
+			}
+		} else {
+			if (*next == L'\\' && *from != L'\\')
+				len++;
+
+			if (to != from)
+				memmove(to, from, sizeof(wchar_t) * len);
+
+			to += len;
+		}
+
+		from += len;
+
+		while (*from == L'\\') from++;
+	}
+
+	/* Strip trailing backslashes */
+	while (to > base && to[-1] == L'\\') to--;
+
+	*to = L'\0';
+
+	return (to - path);
+}
+
+int git_win32_path__cwd(wchar_t *out, size_t len)
+{
+	int cwd_len;
+
+	if ((cwd_len = path__cwd(out, len)) < 0)
+		return -1;
+
+	/* UNC paths */
+	if (wcsncmp(L"\\\\", out, 2) == 0) {
+		/* Our buffer must be at least 5 characters larger than the
+		 * current working directory:  we swallow one of the leading
+		 * '\'s, but we we add a 'UNC' specifier to the path, plus
+		 * a trailing directory separator, plus a NUL.
+		 */
+		if (cwd_len > MAX_PATH - 4) {
+			errno = ENAMETOOLONG;
+			return -1;
+		}
+
+		memmove(out+2, out, sizeof(wchar_t) * cwd_len);
+		out[0] = L'U';
+		out[1] = L'N';
+		out[2] = L'C';
+
+		cwd_len += 2;
+	}
+
+	/* Our buffer must be at least 2 characters larger than the current
+	 * working directory.  (One character for the directory separator,
+	 * one for the null.
+	 */
+	else if (cwd_len > MAX_PATH - 2) {
+		errno = ENAMETOOLONG;
+		return -1;
+	}
+
+	return cwd_len;
+}
+
+int git_win32_path_from_utf8(git_win32_path out, const char *src)
+{
+	wchar_t *dest = out;
+
+	/* All win32 paths are in NT-prefixed format, beginning with "\\?\". */
+	memcpy(dest, PATH__NT_NAMESPACE, sizeof(wchar_t) * PATH__NT_NAMESPACE_LEN);
+	dest += PATH__NT_NAMESPACE_LEN;
+
+	/* See if this is an absolute path (beginning with a drive letter) */
+	if (path__is_absolute(src)) {
+		if (git__utf8_to_16(dest, MAX_PATH, src) < 0)
+			return -1;
+	}
+	/* File-prefixed NT-style paths beginning with \\?\ */
+	else if (path__is_nt_namespace(src)) {
+		/* Skip the NT prefix, the destination already contains it */
+		if (git__utf8_to_16(dest, MAX_PATH, src + PATH__NT_NAMESPACE_LEN) < 0)
+			return -1;
+	}
+	/* UNC paths */
+	else if (path__is_unc(src)) {
+		memcpy(dest, L"UNC\\", sizeof(wchar_t) * 4);
+		dest += 4;
+
+		/* Skip the leading "\\" */
+		if (git__utf8_to_16(dest, MAX_PATH - 2, src + 2) < 0)
+			return -1;
+	}
+	/* Absolute paths omitting the drive letter */
+	else if (src[0] == '\\' || src[0] == '/') {
+		if (path__cwd(dest, MAX_PATH) < 0)
+			return -1;
+
+		if (!path__is_absolute(dest)) {
+			errno = ENOENT;
+			return -1;
+		}
+
+		/* Skip the drive letter specification ("C:") */	
+		if (git__utf8_to_16(dest + 2, MAX_PATH - 2, src) < 0)
+			return -1;
+	}
+	/* Relative paths */
+	else {
+		int cwd_len;
+
+		if ((cwd_len = git_win32_path__cwd(dest, MAX_PATH)) < 0)
+			return -1;
+
+		dest[cwd_len++] = L'\\';
+
+		if (git__utf8_to_16(dest + cwd_len, MAX_PATH - cwd_len, src) < 0)
+			return -1;
+	}
+
+	return git_win32_path_canonicalize(out);
+}
+
+int git_win32_path_to_utf8(git_win32_utf8_path dest, const wchar_t *src)
+{
+	char *out = dest;
+	int len;
+
+	/* Strip NT namespacing "\\?\" */
+	if (path__is_nt_namespace(src)) {
+		src += 4;
+
+		/* "\\?\UNC\server\share" -> "\\server\share" */
+		if (wcsncmp(src, L"UNC\\", 4) == 0) {
+			src += 4;
+
+			memcpy(dest, "\\\\", 2);
+			out = dest + 2;
+		}
+	}
+
+	if ((len = git__utf16_to_8(out, GIT_WIN_PATH_UTF8, src)) < 0)
+		return len;
+
+	git_path_mkposix(dest);
+
+	return len;
+}
+
+char *git_win32_path_8dot3_name(const char *path)
+{
+	git_win32_path longpath, shortpath;
+	wchar_t *start;
+	char *shortname;
+	int len, namelen = 1;
+
+	if (git_win32_path_from_utf8(longpath, path) < 0)
+		return NULL;
+
+	len = GetShortPathNameW(longpath, shortpath, GIT_WIN_PATH_UTF16);
+
+	while (len && shortpath[len-1] == L'\\')
+		shortpath[--len] = L'\0';
+
+	if (len == 0 || len >= GIT_WIN_PATH_UTF16)
+		return NULL;
+
+	for (start = shortpath + (len - 1);
+		start > shortpath && *(start-1) != '/' && *(start-1) != '\\';
+		start--)
+		namelen++;
+
+	/* We may not have actually been given a short name.  But if we have,
+	 * it will be in the ASCII byte range, so we don't need to worry about
+	 * multi-byte sequences and can allocate naively.
+	 */
+	if (namelen > 12 || (shortname = git__malloc(namelen + 1)) == NULL)
+		return NULL;
+
+	if ((len = git__utf16_to_8(shortname, namelen + 1, start)) < 0)
+		return NULL;
+
+	return shortname;
+}
+
+static bool path_is_volume(wchar_t *target, size_t target_len)
+{
+	return (target_len && wcsncmp(target, L"\\??\\Volume{", 11) == 0);
+}
+
+/* On success, returns the length, in characters, of the path stored in dest.
+* On failure, returns a negative value. */
+int git_win32_path_readlink_w(git_win32_path dest, const git_win32_path path)
+{
+	BYTE buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
+	GIT_REPARSE_DATA_BUFFER *reparse_buf = (GIT_REPARSE_DATA_BUFFER *)buf;
+	HANDLE handle = NULL;
+	DWORD ioctl_ret;
+	wchar_t *target;
+	size_t target_len;
+
+	int error = -1;
+
+	handle = CreateFileW(path, GENERIC_READ,
+		FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING,
+		FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+	if (handle == INVALID_HANDLE_VALUE) {
+		errno = ENOENT;
+		return -1;
+	}
+
+	if (!DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0,
+		reparse_buf, sizeof(buf), &ioctl_ret, NULL)) {
+		errno = EINVAL;
+		goto on_error;
+	}
+
+	switch (reparse_buf->ReparseTag) {
+	case IO_REPARSE_TAG_SYMLINK:
+		target = reparse_buf->SymbolicLinkReparseBuffer.PathBuffer +
+			(reparse_buf->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR));
+		target_len = reparse_buf->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
+	break;
+	case IO_REPARSE_TAG_MOUNT_POINT:
+		target = reparse_buf->MountPointReparseBuffer.PathBuffer +
+			(reparse_buf->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR));
+		target_len = reparse_buf->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
+	break;
+	default:
+		errno = EINVAL;
+		goto on_error;
+	}
+
+	if (path_is_volume(target, target_len)) {
+		/* This path is a reparse point that represents another volume mounted
+		* at this location, it is not a symbolic link our input was canonical.
+		*/
+		errno = EINVAL;
+		error = -1;
+	} else if (target_len) {
+		/* The path may need to have a prefix removed. */
+		target_len = git_win32__canonicalize_path(target, target_len);
+
+		/* Need one additional character in the target buffer
+		* for the terminating NULL. */
+		if (GIT_WIN_PATH_UTF16 > target_len) {
+			wcscpy(dest, target);
+			error = (int)target_len;
+		}
+	}
+
+on_error:
+	CloseHandle(handle);
+	return error;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/path_w32.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/path_w32.h
new file mode 100755
index 0000000..3d9f828
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/path_w32.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_path_w32_h__
+#define INCLUDE_git_path_w32_h__
+
+#include "common.h"
+#include "vector.h"
+
+/*
+ * Provides a large enough buffer to support Windows paths:  MAX_PATH is
+ * 260, corresponding to a maximum path length of 259 characters plus a
+ * NULL terminator.  Prefixing with "\\?\" adds 4 characters, but if the
+ * original was a UNC path, then we turn "\\server\share" into
+ * "\\?\UNC\server\share".  So we replace the first two characters with
+ * 8 characters, a net gain of 6, so the maximum length is MAX_PATH+6.
+ */
+#define GIT_WIN_PATH_UTF16		MAX_PATH+6
+
+/* Maximum size of a UTF-8 Win32 path.  We remove the "\\?\" or "\\?\UNC\"
+ * prefixes for presentation, bringing us back to 259 (non-NULL)
+ * characters.  UTF-8 does have 4-byte sequences, but they are encoded in
+ * UTF-16 using surrogate pairs, which takes up the space of two characters.
+ * Two characters in the range U+0800 -> U+FFFF take up more space in UTF-8
+ * (6 bytes) than one surrogate pair (4 bytes).
+ */
+#define GIT_WIN_PATH_UTF8		(259 * 3 + 1)
+
+/*
+ * The length of a Windows "shortname", for 8.3 compatibility.
+ */
+#define GIT_WIN_PATH_SHORTNAME  13
+
+/* Win32 path types */
+typedef wchar_t git_win32_path[GIT_WIN_PATH_UTF16];
+typedef char git_win32_utf8_path[GIT_WIN_PATH_UTF8];
+
+/**
+ * Create a Win32 path (in UCS-2 format) from a UTF-8 string.
+ *
+ * @param dest The buffer to receive the wide string.
+ * @param src The UTF-8 string to convert.
+ * @return The length of the wide string, in characters (not counting the NULL terminator), or < 0 for failure
+ */
+extern int git_win32_path_from_utf8(git_win32_path dest, const char *src);
+
+/**
+ * Canonicalize a Win32 UCS-2 path so that it is suitable for delivery to the
+ * Win32 APIs: remove multiple directory separators, squashing to a single one,
+ * strip trailing directory separators, ensure directory separators are all
+ * canonical (always backslashes, never forward slashes) and process any
+ * directory entries of '.' or '..'.
+ *
+ * This processes the buffer in place.
+ *
+ * @param path The buffer to process
+ * @return The new length of the buffer, in wchar_t's (not counting the NULL terminator)
+ */
+extern int git_win32_path_canonicalize(git_win32_path path);
+
+/**
+ * Create an internal format (posix-style) UTF-8 path from a Win32 UCS-2 path.
+ *
+ * @param dest The buffer to receive the UTF-8 string.
+ * @param src The wide string to convert.
+ * @return The length of the UTF-8 string, in bytes (not counting the NULL terminator), or < 0 for failure
+ */
+extern int git_win32_path_to_utf8(git_win32_utf8_path dest, const wchar_t *src);
+
+/**
+ * Get the short name for the terminal path component in the given path.
+ * For example, given "C:\Foo\Bar\Asdf.txt", this will return the short name
+ * for the file "Asdf.txt".
+ *
+ * @param path The given path in UTF-8
+ * @return The name of the shortname for the given path
+ */
+extern char *git_win32_path_8dot3_name(const char *path);
+
+extern int git_win32_path_readlink_w(git_win32_path dest, const git_win32_path path);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/posix.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/posix.h
new file mode 100755
index 0000000..ac98fd8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/posix.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_posix__w32_h__
+#define INCLUDE_posix__w32_h__
+
+#include "common.h"
+#include "../posix.h"
+#include "path_w32.h"
+#include "utf-conv.h"
+#include "dir.h"
+
+typedef SOCKET GIT_SOCKET;
+
+#define p_lseek(f,n,w) _lseeki64(f, n, w)
+#define p_fstat(f,b) _fstat64(f, b)
+extern int p_lstat(const char *file_name, struct stat *buf);
+extern int p_stat(const char* path, struct stat* buf);
+
+extern int p_utimes(const char *filename, const struct timeval times[2]);
+extern int p_futimes(int fd, const struct timeval times[2]);
+
+extern int p_readlink(const char *path, char *buf, size_t bufsiz);
+extern int p_symlink(const char *old, const char *new);
+extern int p_link(const char *old, const char *new);
+extern int p_unlink(const char *path);
+extern int p_mkdir(const char *path, mode_t mode);
+extern int p_fsync(int fd);
+extern char *p_realpath(const char *orig_path, char *buffer);
+
+extern int p_recv(GIT_SOCKET socket, void *buffer, size_t length, int flags);
+extern int p_send(GIT_SOCKET socket, const void *buffer, size_t length, int flags);
+extern int p_inet_pton(int af, const char* src, void* dst);
+
+extern int p_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr);
+extern int p_snprintf(char *buffer, size_t count, const char *format, ...) GIT_FORMAT_PRINTF(3, 4);
+extern int p_mkstemp(char *tmp_path);
+extern int p_chdir(const char* path);
+extern int p_chmod(const char* path, mode_t mode);
+extern int p_rmdir(const char* path);
+extern int p_access(const char* path, mode_t mode);
+extern int p_ftruncate(int fd, git_off_t size);
+
+/* p_lstat is almost but not quite POSIX correct.  Specifically, the use of
+ * ENOTDIR is wrong, in that it does not mean precisely that a non-directory
+ * entry was encountered.  Making it correct is potentially expensive,
+ * however, so this is a separate version of p_lstat to use when correct
+ * POSIX ENOTDIR semantics is required.
+ */
+extern int p_lstat_posixly(const char *filename, struct stat *buf);
+
+extern struct tm * p_localtime_r(const time_t *timer, struct tm *result);
+extern struct tm * p_gmtime_r(const time_t *timer, struct tm *result);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/posix_w32.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/posix_w32.c
new file mode 100755
index 0000000..504562b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/posix_w32.c
@@ -0,0 +1,698 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#include "../posix.h"
+#include "../fileops.h"
+#include "path.h"
+#include "path_w32.h"
+#include "utf-conv.h"
+#include "repository.h"
+#include "reparse.h"
+#include <errno.h>
+#include <io.h>
+#include <fcntl.h>
+#include <ws2tcpip.h>
+
+#ifndef FILE_NAME_NORMALIZED
+# define FILE_NAME_NORMALIZED 0
+#endif
+
+#ifndef IO_REPARSE_TAG_SYMLINK
+#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
+#endif
+
+/* Options which we always provide to _wopen.
+ *
+ * _O_BINARY - Raw access; no translation of CR or LF characters
+ * _O_NOINHERIT - Do not mark the created handle as inheritable by child processes.
+ *    The Windows default is 'not inheritable', but the CRT's default (following
+ *    POSIX convention) is 'inheritable'. We have no desire for our handles to be
+ *    inheritable on Windows, so specify the flag to get default behavior back. */
+#define STANDARD_OPEN_FLAGS (_O_BINARY | _O_NOINHERIT)
+
+/* Allowable mode bits on Win32.  Using mode bits that are not supported on
+ * Win32 (eg S_IRWXU) is generally ignored, but Wine warns loudly about it
+ * so we simply remove them.
+ */
+#define WIN32_MODE_MASK (_S_IREAD | _S_IWRITE)
+
+/* GetFinalPathNameByHandleW signature */
+typedef DWORD(WINAPI *PFGetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, DWORD);
+
+/**
+ * Truncate or extend file.
+ *
+ * We now take a "git_off_t" rather than "long" because
+ * files may be longer than 2Gb.
+ */
+int p_ftruncate(int fd, git_off_t size)
+{
+	if (size < 0) {
+		errno = EINVAL;
+		return -1;
+	}
+
+#if !defined(__MINGW32__) || defined(MINGW_HAS_SECURE_API)
+	return ((_chsize_s(fd, size) == 0) ? 0 : -1);
+#else
+	/* TODO MINGW32 Find a replacement for _chsize() that handles big files. */
+	if (size > INT32_MAX) {
+		errno = EFBIG;
+		return -1;
+	}
+	return _chsize(fd, (long)size);
+#endif
+}
+
+int p_mkdir(const char *path, mode_t mode)
+{
+	git_win32_path buf;
+
+	GIT_UNUSED(mode);
+
+	if (git_win32_path_from_utf8(buf, path) < 0)
+		return -1;
+
+	return _wmkdir(buf);
+}
+
+int p_link(const char *old, const char *new)
+{
+	GIT_UNUSED(old);
+	GIT_UNUSED(new);
+	errno = ENOSYS;
+	return -1;
+}
+
+int p_unlink(const char *path)
+{
+	git_win32_path buf;
+	int error;
+
+	if (git_win32_path_from_utf8(buf, path) < 0)
+		return -1;
+
+	error = _wunlink(buf);
+
+	/* If the file could not be deleted because it was
+	 * read-only, clear the bit and try again */
+	if (error == -1 && errno == EACCES) {
+		_wchmod(buf, 0666);
+		error = _wunlink(buf);
+	}
+
+	return error;
+}
+
+int p_fsync(int fd)
+{
+	HANDLE fh = (HANDLE)_get_osfhandle(fd);
+
+	if (fh == INVALID_HANDLE_VALUE) {
+		errno = EBADF;
+		return -1;
+	}
+
+	if (!FlushFileBuffers(fh)) {
+		DWORD code = GetLastError();
+
+		if (code == ERROR_INVALID_HANDLE)
+			errno = EINVAL;
+		else
+			errno = EIO;
+
+		return -1;
+	}
+
+	return 0;
+}
+
+#define WIN32_IS_WSEP(CH) ((CH) == L'/' || (CH) == L'\\')
+
+static int lstat_w(
+	wchar_t *path,
+	struct stat *buf,
+	bool posix_enotdir)
+{
+	WIN32_FILE_ATTRIBUTE_DATA fdata;
+
+	if (GetFileAttributesExW(path, GetFileExInfoStandard, &fdata)) {
+		if (!buf)
+			return 0;
+
+		return git_win32__file_attribute_to_stat(buf, &fdata, path);
+	}
+
+	errno = ENOENT;
+
+	/* To match POSIX behavior, set ENOTDIR when any of the folders in the
+	 * file path is a regular file, otherwise set ENOENT.
+	 */
+	if (posix_enotdir) {
+		size_t path_len = wcslen(path);
+
+		/* scan up path until we find an existing item */
+		while (1) {
+			DWORD attrs;
+
+			/* remove last directory component */
+			for (path_len--; path_len > 0 && !WIN32_IS_WSEP(path[path_len]); path_len--);
+
+			if (path_len <= 0)
+				break;
+
+			path[path_len] = L'\0';
+			attrs = GetFileAttributesW(path);
+
+			if (attrs != INVALID_FILE_ATTRIBUTES) {
+				if (!(attrs & FILE_ATTRIBUTE_DIRECTORY))
+					errno = ENOTDIR;
+				break;
+			}
+		}
+	}
+
+	return -1;
+}
+
+static int do_lstat(const char *path, struct stat *buf, bool posixly_correct)
+{
+	git_win32_path path_w;
+	int len;
+
+	if ((len = git_win32_path_from_utf8(path_w, path)) < 0)
+		return -1;
+
+	git_win32__path_trim_end(path_w, len);
+
+	return lstat_w(path_w, buf, posixly_correct);
+}
+
+int p_lstat(const char *filename, struct stat *buf)
+{
+	return do_lstat(filename, buf, false);
+}
+
+int p_lstat_posixly(const char *filename, struct stat *buf)
+{
+	return do_lstat(filename, buf, true);
+}
+
+int p_utimes(const char *filename, const struct timeval times[2])
+{
+	int fd, error;
+
+	if ((fd = p_open(filename, O_RDWR)) < 0)
+		return fd;
+
+	error = p_futimes(fd, times);
+
+	close(fd);
+	return error;
+}
+
+int p_futimes(int fd, const struct timeval times[2])
+{
+	HANDLE handle;
+	FILETIME atime = {0}, mtime = {0};
+
+	if (times == NULL) {
+		SYSTEMTIME st;
+
+		GetSystemTime(&st);
+		SystemTimeToFileTime(&st, &atime);
+		SystemTimeToFileTime(&st, &mtime);
+	} else {
+		git_win32__timeval_to_filetime(&atime, times[0]);
+		git_win32__timeval_to_filetime(&mtime, times[1]);
+	}
+
+	if ((handle = (HANDLE)_get_osfhandle(fd)) == INVALID_HANDLE_VALUE)
+		return -1;
+
+	if (SetFileTime(handle, NULL, &atime, &mtime) == 0)
+		return -1;
+
+	return 0;
+}
+
+int p_readlink(const char *path, char *buf, size_t bufsiz)
+{
+	git_win32_path path_w, target_w;
+	git_win32_utf8_path target;
+	int len;
+
+	/* readlink(2) does not NULL-terminate the string written
+	 * to the target buffer. Furthermore, the target buffer need
+	 * not be large enough to hold the entire result. A truncated
+	 * result should be written in this case. Since this truncation
+	 * could occur in the middle of the encoding of a code point,
+	 * we need to buffer the result on the stack. */
+
+	if (git_win32_path_from_utf8(path_w, path) < 0 ||
+		git_win32_path_readlink_w(target_w, path_w) < 0 ||
+		(len = git_win32_path_to_utf8(target, target_w)) < 0)
+		return -1;
+
+	bufsiz = min((size_t)len, bufsiz);
+	memcpy(buf, target, bufsiz);
+
+	return (int)bufsiz;
+}
+
+int p_symlink(const char *old, const char *new)
+{
+	/* Real symlinks on NTFS require admin privileges. Until this changes,
+	 * libgit2 just creates a text file with the link target in the contents.
+	 */
+	return git_futils_fake_symlink(old, new);
+}
+
+int p_open(const char *path, int flags, ...)
+{
+	git_win32_path buf;
+	mode_t mode = 0;
+
+	if (git_win32_path_from_utf8(buf, path) < 0)
+		return -1;
+
+	if (flags & O_CREAT) {
+		va_list arg_list;
+
+		va_start(arg_list, flags);
+		mode = (mode_t)va_arg(arg_list, int);
+		va_end(arg_list);
+	}
+
+	return _wopen(buf, flags | STANDARD_OPEN_FLAGS, mode & WIN32_MODE_MASK);
+}
+
+int p_creat(const char *path, mode_t mode)
+{
+	git_win32_path buf;
+
+	if (git_win32_path_from_utf8(buf, path) < 0)
+		return -1;
+
+	return _wopen(buf,
+		_O_WRONLY | _O_CREAT | _O_TRUNC | STANDARD_OPEN_FLAGS,
+		mode & WIN32_MODE_MASK);
+}
+
+int p_getcwd(char *buffer_out, size_t size)
+{
+	git_win32_path buf;
+	wchar_t *cwd = _wgetcwd(buf, GIT_WIN_PATH_UTF16);
+
+	if (!cwd)
+		return -1;
+
+	/* Convert the working directory back to UTF-8 */
+	if (git__utf16_to_8(buffer_out, size, cwd) < 0) {
+		DWORD code = GetLastError();
+
+		if (code == ERROR_INSUFFICIENT_BUFFER)
+			errno = ERANGE;
+		else
+			errno = EINVAL;
+
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Returns the address of the GetFinalPathNameByHandleW function.
+ * This function is available on Windows Vista and higher.
+ */
+static PFGetFinalPathNameByHandleW get_fpnbyhandle(void)
+{
+	static PFGetFinalPathNameByHandleW pFunc = NULL;
+	PFGetFinalPathNameByHandleW toReturn = pFunc;
+
+	if (!toReturn) {
+		HMODULE hModule = GetModuleHandleW(L"kernel32");
+
+		if (hModule)
+			toReturn = (PFGetFinalPathNameByHandleW)GetProcAddress(hModule, "GetFinalPathNameByHandleW");
+
+		pFunc = toReturn;
+	}
+
+	assert(toReturn);
+
+	return toReturn;
+}
+
+static int getfinalpath_w(
+	git_win32_path dest,
+	const wchar_t *path)
+{
+	PFGetFinalPathNameByHandleW pgfp = get_fpnbyhandle();
+	HANDLE hFile;
+	DWORD dwChars;
+
+	if (!pgfp)
+		return -1;
+
+	/* Use FILE_FLAG_BACKUP_SEMANTICS so we can open a directory. Do not
+	* specify FILE_FLAG_OPEN_REPARSE_POINT; we want to open a handle to the
+	* target of the link. */
+	hFile = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE,
+		NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+	if (INVALID_HANDLE_VALUE == hFile)
+		return -1;
+
+	/* Call GetFinalPathNameByHandle */
+	dwChars = pgfp(hFile, dest, GIT_WIN_PATH_UTF16, FILE_NAME_NORMALIZED);
+	CloseHandle(hFile);
+
+	if (!dwChars || dwChars >= GIT_WIN_PATH_UTF16)
+		return -1;
+
+	/* The path may be delivered to us with a prefix; canonicalize */
+	return (int)git_win32__canonicalize_path(dest, dwChars);
+}
+
+static int follow_and_lstat_link(git_win32_path path, struct stat* buf)
+{
+	git_win32_path target_w;
+
+	if (getfinalpath_w(target_w, path) < 0)
+		return -1;
+
+	return lstat_w(target_w, buf, false);
+}
+
+int p_stat(const char* path, struct stat* buf)
+{
+	git_win32_path path_w;
+	int len;
+
+	if ((len = git_win32_path_from_utf8(path_w, path)) < 0 ||
+		lstat_w(path_w, buf, false) < 0)
+		return -1;
+
+	/* The item is a symbolic link or mount point. No need to iterate
+	 * to follow multiple links; use GetFinalPathNameFromHandle. */
+	if (S_ISLNK(buf->st_mode))
+		return follow_and_lstat_link(path_w, buf);
+
+	return 0;
+}
+
+int p_chdir(const char* path)
+{
+	git_win32_path buf;
+
+	if (git_win32_path_from_utf8(buf, path) < 0)
+		return -1;
+
+	return _wchdir(buf);
+}
+
+int p_chmod(const char* path, mode_t mode)
+{
+	git_win32_path buf;
+
+	if (git_win32_path_from_utf8(buf, path) < 0)
+		return -1;
+
+	return _wchmod(buf, mode);
+}
+
+int p_rmdir(const char* path)
+{
+	git_win32_path buf;
+	int error;
+
+	if (git_win32_path_from_utf8(buf, path) < 0)
+		return -1;
+
+	error = _wrmdir(buf);
+
+	if (error == -1) {
+		switch (GetLastError()) {
+			/* _wrmdir() is documented to return EACCES if "A program has an open
+			 * handle to the directory."  This sounds like what everybody else calls
+			 * EBUSY.  Let's convert appropriate error codes.
+			 */
+			case ERROR_SHARING_VIOLATION:
+				errno = EBUSY;
+				break;
+
+			/* This error can be returned when trying to rmdir an extant file. */
+			case ERROR_DIRECTORY:
+				errno = ENOTDIR;
+				break;
+		}
+	}
+
+	return error;
+}
+
+char *p_realpath(const char *orig_path, char *buffer)
+{
+	git_win32_path orig_path_w, buffer_w;
+
+	if (git_win32_path_from_utf8(orig_path_w, orig_path) < 0)
+		return NULL;
+
+	/* Note that if the path provided is a relative path, then the current directory
+	 * is used to resolve the path -- which is a concurrency issue because the current
+	 * directory is a process-wide variable. */
+	if (!GetFullPathNameW(orig_path_w, GIT_WIN_PATH_UTF16, buffer_w, NULL)) {
+		if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+			errno = ENAMETOOLONG;
+		else
+			errno = EINVAL;
+
+		return NULL;
+	}
+
+	/* The path must exist. */
+	if (GetFileAttributesW(buffer_w) == INVALID_FILE_ATTRIBUTES) {
+		errno = ENOENT;
+		return NULL;
+	}
+
+	if (!buffer && !(buffer = git__malloc(GIT_WIN_PATH_UTF8))) {
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	/* Convert the path to UTF-8. If the caller provided a buffer, then it
+	 * is assumed to be GIT_WIN_PATH_UTF8 characters in size. If it isn't,
+	 * then we may overflow. */
+	if (git_win32_path_to_utf8(buffer, buffer_w) < 0)
+		return NULL;
+
+	git_path_mkposix(buffer);
+
+	return buffer;
+}
+
+int p_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
+{
+#if defined(_MSC_VER)
+	int len;
+
+	if (count == 0)
+		return _vscprintf(format, argptr);
+
+	#if _MSC_VER >= 1500
+	len = _vsnprintf_s(buffer, count, _TRUNCATE, format, argptr);
+	#else
+	len = _vsnprintf(buffer, count, format, argptr);
+	#endif
+
+	if (len < 0)
+		return _vscprintf(format, argptr);
+
+	return len;
+#else /* MinGW */
+	return vsnprintf(buffer, count, format, argptr);
+#endif
+}
+
+int p_snprintf(char *buffer, size_t count, const char *format, ...)
+{
+	va_list va;
+	int r;
+
+	va_start(va, format);
+	r = p_vsnprintf(buffer, count, format, va);
+	va_end(va);
+
+	return r;
+}
+
+/* TODO: wut? */
+int p_mkstemp(char *tmp_path)
+{
+#if defined(_MSC_VER) && _MSC_VER >= 1500
+	if (_mktemp_s(tmp_path, strlen(tmp_path) + 1) != 0)
+		return -1;
+#else
+	if (_mktemp(tmp_path) == NULL)
+		return -1;
+#endif
+
+	return p_open(tmp_path, O_RDWR | O_CREAT | O_EXCL, 0744); //-V536
+}
+
+int p_access(const char* path, mode_t mode)
+{
+	git_win32_path buf;
+
+	if (git_win32_path_from_utf8(buf, path) < 0)
+		return -1;
+
+	return _waccess(buf, mode & WIN32_MODE_MASK);
+}
+
+static int ensure_writable(wchar_t *fpath)
+{
+	DWORD attrs;
+
+	attrs = GetFileAttributesW(fpath);
+	if (attrs == INVALID_FILE_ATTRIBUTES) {
+		if (GetLastError() == ERROR_FILE_NOT_FOUND)
+			return 0;
+
+		giterr_set(GITERR_OS, "failed to get attributes");
+		return -1;
+	}
+
+	if (!(attrs & FILE_ATTRIBUTE_READONLY))
+		return 0;
+
+	attrs &= ~FILE_ATTRIBUTE_READONLY;
+	if (!SetFileAttributesW(fpath, attrs)) {
+		giterr_set(GITERR_OS, "failed to set attributes");
+		return -1;
+	}
+
+	return 0;
+}
+
+int p_rename(const char *from, const char *to)
+{
+	git_win32_path wfrom;
+	git_win32_path wto;
+	int rename_tries;
+	int rename_succeeded;
+	int error;
+
+	if (git_win32_path_from_utf8(wfrom, from) < 0 ||
+		git_win32_path_from_utf8(wto, to) < 0)
+		return -1;
+
+	/* wait up to 50ms if file is locked by another thread or process */
+	rename_tries = 0;
+	rename_succeeded = 0;
+	while (rename_tries < 10) {
+		if (ensure_writable(wto) == 0 &&
+		    MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) != 0) {
+			rename_succeeded = 1;
+			break;
+		}
+		
+		error = GetLastError();
+		if (error == ERROR_SHARING_VIOLATION || error == ERROR_ACCESS_DENIED) {
+			Sleep(5);
+			rename_tries++;
+		} else
+			break;
+	}
+	
+	return rename_succeeded ? 0 : -1;
+}
+
+int p_recv(GIT_SOCKET socket, void *buffer, size_t length, int flags)
+{
+	if ((size_t)((int)length) != length)
+		return -1; /* giterr_set will be done by caller */
+
+	return recv(socket, buffer, (int)length, flags);
+}
+
+int p_send(GIT_SOCKET socket, const void *buffer, size_t length, int flags)
+{
+	if ((size_t)((int)length) != length)
+		return -1; /* giterr_set will be done by caller */
+
+	return send(socket, buffer, (int)length, flags);
+}
+
+/**
+ * Borrowed from http://old.nabble.com/Porting-localtime_r-and-gmtime_r-td15282276.html
+ * On Win32, `gmtime_r` doesn't exist but `gmtime` is threadsafe, so we can use that
+ */
+struct tm *
+p_localtime_r (const time_t *timer, struct tm *result)
+{
+	struct tm *local_result;
+	local_result = localtime (timer);
+
+	if (local_result == NULL || result == NULL)
+		return NULL;
+
+	memcpy (result, local_result, sizeof (struct tm));
+	return result;
+}
+struct tm *
+p_gmtime_r (const time_t *timer, struct tm *result)
+{
+	struct tm *local_result;
+	local_result = gmtime (timer);
+
+	if (local_result == NULL || result == NULL)
+		return NULL;
+
+	memcpy (result, local_result, sizeof (struct tm));
+	return result;
+}
+
+int p_inet_pton(int af, const char *src, void *dst)
+{
+	struct sockaddr_storage sin;
+	void *addr;
+	int sin_len = sizeof(struct sockaddr_storage), addr_len;
+	int error = 0;
+
+	if (af == AF_INET) {
+		addr = &((struct sockaddr_in *)&sin)->sin_addr;
+		addr_len = sizeof(struct in_addr);
+	} else if (af == AF_INET6) {
+		addr = &((struct sockaddr_in6 *)&sin)->sin6_addr;
+		addr_len = sizeof(struct in6_addr);
+	} else {
+		errno = EAFNOSUPPORT;
+		return -1;
+	}
+
+	if ((error = WSAStringToAddressA((LPSTR)src, af, NULL, (LPSOCKADDR)&sin, &sin_len)) == 0) {
+		memcpy(dst, addr, addr_len);
+		return 1;
+	}
+
+	switch(WSAGetLastError()) {
+	case WSAEINVAL:
+		return 0;
+	case WSAEFAULT:
+		errno = ENOSPC;
+		return -1;
+	case WSA_NOT_ENOUGH_MEMORY:
+		errno = ENOMEM;
+		return -1;
+	}
+
+	errno = EINVAL;
+	return -1;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/precompiled.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/precompiled.c
new file mode 100755
index 0000000..5f656a4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/precompiled.c
@@ -0,0 +1 @@
+#include "precompiled.h"
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/precompiled.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/precompiled.h
new file mode 100755
index 0000000..33ce106
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/precompiled.h
@@ -0,0 +1,23 @@
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <time.h>
+#include <stdarg.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <regex.h>
+
+#include <io.h>
+#include <direct.h>
+#ifdef GIT_THREADS
+ #include "win32/pthread.h"
+#endif
+
+#include "git2.h"
+#include "common.h"
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/pthread.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/pthread.c
new file mode 100755
index 0000000..a1cc189
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/pthread.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "pthread.h"
+#include "../global.h"
+
+#define CLEAN_THREAD_EXIT 0x6F012842
+
+/* The thread procedure stub used to invoke the caller's procedure
+ * and capture the return value for later collection. Windows will
+ * only hold a DWORD, but we need to be able to store an entire
+ * void pointer. This requires the indirection. */
+static DWORD WINAPI git_win32__threadproc(LPVOID lpParameter)
+{
+	git_win32_thread *thread = lpParameter;
+
+	thread->result = thread->proc(thread->param);
+
+	git__free_tls_data();
+
+	return CLEAN_THREAD_EXIT;
+}
+
+int git_win32__thread_create(
+	git_win32_thread *GIT_RESTRICT thread,
+	const pthread_attr_t *GIT_RESTRICT attr,
+	void *(*start_routine)(void*),
+	void *GIT_RESTRICT arg)
+{
+	GIT_UNUSED(attr);
+
+	thread->result = NULL;
+	thread->param = arg;
+	thread->proc = start_routine;
+	thread->thread = CreateThread(
+		NULL, 0, git_win32__threadproc, thread, 0, NULL);
+
+	return thread->thread ? 0 : -1;
+}
+
+int git_win32__thread_join(
+	git_win32_thread *thread,
+	void **value_ptr)
+{
+	DWORD exit;
+
+	if (WaitForSingleObject(thread->thread, INFINITE) != WAIT_OBJECT_0)
+		return -1;
+
+	if (!GetExitCodeThread(thread->thread, &exit)) {
+		CloseHandle(thread->thread);
+		return -1;
+	}
+
+	/* Check for the thread having exited uncleanly. If exit was unclean,
+	 * then we don't have a return value to give back to the caller. */
+	if (exit != CLEAN_THREAD_EXIT) {
+		assert(false);
+		thread->result = NULL;
+	}
+
+	if (value_ptr)
+		*value_ptr = thread->result;
+
+	CloseHandle(thread->thread);
+	return 0;
+}
+
+int pthread_mutex_init(
+	pthread_mutex_t *GIT_RESTRICT mutex,
+	const pthread_mutexattr_t *GIT_RESTRICT mutexattr)
+{
+	GIT_UNUSED(mutexattr);
+	InitializeCriticalSection(mutex);
+	return 0;
+}
+
+int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+	DeleteCriticalSection(mutex);
+	return 0;
+}
+
+int pthread_mutex_lock(pthread_mutex_t *mutex)
+{
+	EnterCriticalSection(mutex);
+	return 0;
+}
+
+int pthread_mutex_unlock(pthread_mutex_t *mutex)
+{
+	LeaveCriticalSection(mutex);
+	return 0;
+}
+
+int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
+{
+	/* We don't support non-default attributes. */
+	if (attr)
+		return EINVAL;
+
+	/* This is an auto-reset event. */
+	*cond = CreateEventW(NULL, FALSE, FALSE, NULL);
+	assert(*cond);
+
+	/* If we can't create the event, claim that the reason was out-of-memory.
+	 * The actual reason can be fetched with GetLastError(). */
+	return *cond ? 0 : ENOMEM;
+}
+
+int pthread_cond_destroy(pthread_cond_t *cond)
+{
+	BOOL closed;
+
+	if (!cond)
+		return EINVAL;
+
+	closed = CloseHandle(*cond);
+	assert(closed);
+	GIT_UNUSED(closed);
+
+	*cond = NULL;
+	return 0;
+}
+
+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+	int error;
+	DWORD wait_result;
+
+	if (!cond || !mutex)
+		return EINVAL;
+
+	/* The caller must be holding the mutex. */
+	error = pthread_mutex_unlock(mutex);
+
+	if (error)
+		return error;
+
+	wait_result = WaitForSingleObject(*cond, INFINITE);
+	assert(WAIT_OBJECT_0 == wait_result);
+	GIT_UNUSED(wait_result);
+
+	return pthread_mutex_lock(mutex);
+}
+
+int pthread_cond_signal(pthread_cond_t *cond)
+{
+	BOOL signaled;
+
+	if (!cond)
+		return EINVAL;
+
+	signaled = SetEvent(*cond);
+	assert(signaled);
+	GIT_UNUSED(signaled);
+
+	return 0;
+}
+
+/* pthread_cond_broadcast is not implemented because doing so with just
+ * Win32 events is quite complicated, and no caller in libgit2 uses it
+ * yet.
+ */
+int pthread_num_processors_np(void)
+{
+	DWORD_PTR p, s;
+	int n = 0;
+
+	if (GetProcessAffinityMask(GetCurrentProcess(), &p, &s))
+		for (; p; p >>= 1)
+			n += p&1;
+
+	return n ? n : 1;
+}
+
+typedef void (WINAPI *win32_srwlock_fn)(GIT_SRWLOCK *);
+
+static win32_srwlock_fn win32_srwlock_initialize;
+static win32_srwlock_fn win32_srwlock_acquire_shared;
+static win32_srwlock_fn win32_srwlock_release_shared;
+static win32_srwlock_fn win32_srwlock_acquire_exclusive;
+static win32_srwlock_fn win32_srwlock_release_exclusive;
+
+int pthread_rwlock_init(
+	pthread_rwlock_t *GIT_RESTRICT lock,
+	const pthread_rwlockattr_t *GIT_RESTRICT attr)
+{
+	GIT_UNUSED(attr);
+
+	if (win32_srwlock_initialize)
+		win32_srwlock_initialize(&lock->native.srwl);
+	else
+		InitializeCriticalSection(&lock->native.csec);
+
+	return 0;
+}
+
+int pthread_rwlock_rdlock(pthread_rwlock_t *lock)
+{
+	if (win32_srwlock_acquire_shared)
+		win32_srwlock_acquire_shared(&lock->native.srwl);
+	else
+		EnterCriticalSection(&lock->native.csec);
+
+	return 0;
+}
+
+int pthread_rwlock_rdunlock(pthread_rwlock_t *lock)
+{
+	if (win32_srwlock_release_shared)
+		win32_srwlock_release_shared(&lock->native.srwl);
+	else
+		LeaveCriticalSection(&lock->native.csec);
+
+	return 0;
+}
+
+int pthread_rwlock_wrlock(pthread_rwlock_t *lock)
+{
+	if (win32_srwlock_acquire_exclusive)
+		win32_srwlock_acquire_exclusive(&lock->native.srwl);
+	else
+		EnterCriticalSection(&lock->native.csec);
+
+	return 0;
+}
+
+int pthread_rwlock_wrunlock(pthread_rwlock_t *lock)
+{
+	if (win32_srwlock_release_exclusive)
+		win32_srwlock_release_exclusive(&lock->native.srwl);
+	else
+		LeaveCriticalSection(&lock->native.csec);
+
+	return 0;
+}
+
+int pthread_rwlock_destroy(pthread_rwlock_t *lock)
+{
+	if (!win32_srwlock_initialize)
+		DeleteCriticalSection(&lock->native.csec);
+	git__memzero(lock, sizeof(*lock));
+	return 0;
+}
+
+int win32_pthread_initialize(void)
+{
+	HMODULE hModule = GetModuleHandleW(L"kernel32");
+
+	if (hModule) {
+		win32_srwlock_initialize = (win32_srwlock_fn)
+			GetProcAddress(hModule, "InitializeSRWLock");
+		win32_srwlock_acquire_shared = (win32_srwlock_fn)
+			GetProcAddress(hModule, "AcquireSRWLockShared");
+		win32_srwlock_release_shared = (win32_srwlock_fn)
+			GetProcAddress(hModule, "ReleaseSRWLockShared");
+		win32_srwlock_acquire_exclusive = (win32_srwlock_fn)
+			GetProcAddress(hModule, "AcquireSRWLockExclusive");
+		win32_srwlock_release_exclusive = (win32_srwlock_fn)
+			GetProcAddress(hModule, "ReleaseSRWLockExclusive");
+	}
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/pthread.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/pthread.h
new file mode 100755
index 0000000..e4826ca
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/pthread.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef GIT_PTHREAD_H
+#define GIT_PTHREAD_H
+
+#include "../common.h"
+
+#if defined (_MSC_VER)
+#	define GIT_RESTRICT __restrict
+#else
+#	define GIT_RESTRICT __restrict__
+#endif
+
+typedef struct {
+	HANDLE thread;
+	void *(*proc)(void *);
+	void *param;
+	void *result;
+} git_win32_thread;
+
+typedef int pthread_mutexattr_t;
+typedef int pthread_condattr_t;
+typedef int pthread_attr_t;
+typedef int pthread_rwlockattr_t;
+
+typedef CRITICAL_SECTION pthread_mutex_t;
+typedef HANDLE pthread_cond_t;
+
+typedef struct { void *Ptr; } GIT_SRWLOCK;
+
+typedef struct {
+	union {
+		GIT_SRWLOCK srwl;
+		CRITICAL_SECTION csec;
+	} native;
+} pthread_rwlock_t;
+
+#define PTHREAD_MUTEX_INITIALIZER  {(void*)-1}
+
+int git_win32__thread_create(
+	git_win32_thread *GIT_RESTRICT,
+	const pthread_attr_t *GIT_RESTRICT,
+	void *(*) (void *),
+	void *GIT_RESTRICT);
+
+int git_win32__thread_join(
+	git_win32_thread *,
+	void **);
+
+#ifdef GIT_THREADS
+
+typedef git_win32_thread git_thread;
+
+#define git_thread_create(git_thread_ptr, attr, start_routine, arg) \
+	git_win32__thread_create(git_thread_ptr, attr, start_routine, arg)
+#define git_thread_join(git_thread_ptr, status) \
+	git_win32__thread_join(git_thread_ptr, status)
+
+#endif
+
+int pthread_mutex_init(
+	pthread_mutex_t *GIT_RESTRICT mutex,
+	const pthread_mutexattr_t *GIT_RESTRICT mutexattr);
+int pthread_mutex_destroy(pthread_mutex_t *);
+int pthread_mutex_lock(pthread_mutex_t *);
+int pthread_mutex_unlock(pthread_mutex_t *);
+
+int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *);
+int pthread_cond_destroy(pthread_cond_t *);
+int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
+int pthread_cond_signal(pthread_cond_t *);
+/* pthread_cond_broadcast is not supported on Win32 yet. */
+
+int pthread_num_processors_np(void);
+
+int pthread_rwlock_init(
+	pthread_rwlock_t *GIT_RESTRICT lock,
+	const pthread_rwlockattr_t *GIT_RESTRICT attr);
+int pthread_rwlock_rdlock(pthread_rwlock_t *);
+int pthread_rwlock_rdunlock(pthread_rwlock_t *);
+int pthread_rwlock_wrlock(pthread_rwlock_t *);
+int pthread_rwlock_wrunlock(pthread_rwlock_t *);
+int pthread_rwlock_destroy(pthread_rwlock_t *);
+
+extern int win32_pthread_initialize(void);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/reparse.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/reparse.h
new file mode 100755
index 0000000..70f9fd6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/reparse.h
@@ -0,0 +1,57 @@
+/*
+* Copyright (C) the libgit2 contributors. All rights reserved.
+*
+* This file is part of libgit2, distributed under the GNU GPL v2 with
+* a Linking Exception. For full terms see the included COPYING file.
+*/
+
+#ifndef INCLUDE_git_win32_reparse_h__
+#define INCLUDE_git_win32_reparse_h__
+
+/* This structure is defined on MSDN at
+* http://msdn.microsoft.com/en-us/library/windows/hardware/ff552012(v=vs.85).aspx
+*
+* It was formerly included in the Windows 2000 SDK and remains defined in
+* MinGW, so we must define it with a silly name to avoid conflicting.
+*/
+typedef struct _GIT_REPARSE_DATA_BUFFER {
+	ULONG  ReparseTag;
+	USHORT ReparseDataLength;
+	USHORT Reserved;
+	union {
+		struct {
+			USHORT SubstituteNameOffset;
+			USHORT SubstituteNameLength;
+			USHORT PrintNameOffset;
+			USHORT PrintNameLength;
+			ULONG  Flags;
+			WCHAR  PathBuffer[1];
+		} SymbolicLinkReparseBuffer;
+		struct {
+			USHORT SubstituteNameOffset;
+			USHORT SubstituteNameLength;
+			USHORT PrintNameOffset;
+			USHORT PrintNameLength;
+			WCHAR  PathBuffer[1];
+		} MountPointReparseBuffer;
+		struct {
+			UCHAR DataBuffer[1];
+		} GenericReparseBuffer;
+	};
+} GIT_REPARSE_DATA_BUFFER;
+
+#define REPARSE_DATA_HEADER_SIZE			8
+#define REPARSE_DATA_MOUNTPOINT_HEADER_SIZE	8
+#define REPARSE_DATA_UNION_SIZE				12
+
+/* Missing in MinGW */
+#ifndef FSCTL_GET_REPARSE_POINT
+# define FSCTL_GET_REPARSE_POINT			0x000900a8
+#endif
+
+/* Missing in MinGW */
+#ifndef FSCTL_SET_REPARSE_POINT
+# define FSCTL_SET_REPARSE_POINT			0x000900a4
+#endif
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/utf-conv.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/utf-conv.c
new file mode 100755
index 0000000..f1b674e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/utf-conv.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "utf-conv.h"
+
+GIT_INLINE(DWORD) get_wc_flags(void)
+{
+	static char inited = 0;
+	static DWORD flags;
+
+	/* Invalid code point check supported on Vista+ only */
+	if (!inited) {
+		flags = git_has_win32_version(6, 0, 0) ? WC_ERR_INVALID_CHARS : 0;
+		inited = 1;
+	}
+
+	return flags;
+}
+
+GIT_INLINE(void) git__set_errno(void)
+{
+	if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+		errno = ENAMETOOLONG;
+	else
+		errno = EINVAL;
+}
+
+/**
+ * Converts a UTF-8 string to wide characters.
+ *
+ * @param dest The buffer to receive the wide string.
+ * @param dest_size The size of the buffer, in characters.
+ * @param src The UTF-8 string to convert.
+ * @return The length of the wide string, in characters (not counting the NULL terminator), or < 0 for failure
+ */
+int git__utf8_to_16(wchar_t *dest, size_t dest_size, const char *src)
+{
+	int len;
+
+	/* Length of -1 indicates NULL termination of the input string. Subtract 1 from the result to
+	* turn 0 into -1 (an error code) and to not count the NULL terminator as part of the string's
+	* length. MultiByteToWideChar never returns int's minvalue, so underflow is not possible */
+	if ((len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, dest, (int)dest_size) - 1) < 0)
+		git__set_errno();
+
+	return len;
+}
+
+/**
+ * Converts a wide string to UTF-8.
+ *
+ * @param dest The buffer to receive the UTF-8 string.
+ * @param dest_size The size of the buffer, in bytes.
+ * @param src The wide string to convert.
+ * @return The length of the UTF-8 string, in bytes (not counting the NULL terminator), or < 0 for failure
+ */
+int git__utf16_to_8(char *dest, size_t dest_size, const wchar_t *src)
+{
+	int len;
+
+	/* Length of -1 indicates NULL termination of the input string. Subtract 1 from the result to
+	 * turn 0 into -1 (an error code) and to not count the NULL terminator as part of the string's
+	 * length. WideCharToMultiByte never returns int's minvalue, so underflow is not possible */
+	if ((len = WideCharToMultiByte(CP_UTF8, get_wc_flags(), src, -1, dest, (int)dest_size, NULL, NULL) - 1) < 0)
+		git__set_errno();
+
+	return len;
+}
+
+/**
+ * Converts a UTF-8 string to wide characters.
+ * Memory is allocated to hold the converted string.
+ * The caller is responsible for freeing the string with git__free.
+ *
+ * @param dest Receives a pointer to the wide string.
+ * @param src The UTF-8 string to convert.
+ * @return The length of the wide string, in characters (not counting the NULL terminator), or < 0 for failure
+ */
+int git__utf8_to_16_alloc(wchar_t **dest, const char *src)
+{
+	int utf16_size;
+
+	*dest = NULL;
+
+	/* Length of -1 indicates NULL termination of the input string */
+	utf16_size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, NULL, 0);
+
+	if (!utf16_size) {
+		git__set_errno();
+		return -1;
+	}
+
+	if (!(*dest = git__mallocarray(utf16_size, sizeof(wchar_t)))) {
+		errno = ENOMEM;
+		return -1;
+	}
+
+	utf16_size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, *dest, utf16_size);
+
+	if (!utf16_size) {
+		git__set_errno();
+
+		git__free(*dest);
+		*dest = NULL;
+	}
+
+	/* Subtract 1 from the result to turn 0 into -1 (an error code) and to not count the NULL
+	 * terminator as part of the string's length. MultiByteToWideChar never returns int's minvalue,
+	 * so underflow is not possible */
+	return utf16_size - 1;
+}
+
+/**
+ * Converts a wide string to UTF-8.
+ * Memory is allocated to hold the converted string.
+ * The caller is responsible for freeing the string with git__free.
+ *
+ * @param dest Receives a pointer to the UTF-8 string.
+ * @param src The wide string to convert.
+ * @return The length of the UTF-8 string, in bytes (not counting the NULL terminator), or < 0 for failure
+ */
+int git__utf16_to_8_alloc(char **dest, const wchar_t *src)
+{
+	int utf8_size;
+	DWORD dwFlags = get_wc_flags();
+
+	*dest = NULL;
+
+	/* Length of -1 indicates NULL termination of the input string */
+	utf8_size = WideCharToMultiByte(CP_UTF8, dwFlags, src, -1, NULL, 0, NULL, NULL);
+
+	if (!utf8_size) {
+		git__set_errno();
+		return -1;
+	}
+
+	*dest = git__malloc(utf8_size);
+
+	if (!*dest) {
+		errno = ENOMEM;
+		return -1;
+	}
+
+	utf8_size = WideCharToMultiByte(CP_UTF8, dwFlags, src, -1, *dest, utf8_size, NULL, NULL);
+
+	if (!utf8_size) {
+		git__set_errno();
+
+		git__free(*dest);
+		*dest = NULL;
+	}
+
+	/* Subtract 1 from the result to turn 0 into -1 (an error code) and to not count the NULL
+	 * terminator as part of the string's length. MultiByteToWideChar never returns int's minvalue,
+	 * so underflow is not possible */
+	return utf8_size - 1;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/utf-conv.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/utf-conv.h
new file mode 100755
index 0000000..33b95f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/utf-conv.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_utfconv_h__
+#define INCLUDE_git_utfconv_h__
+
+#include <wchar.h>
+#include "common.h"
+
+#ifndef WC_ERR_INVALID_CHARS
+# define WC_ERR_INVALID_CHARS	0x80
+#endif
+
+/**
+ * Converts a UTF-8 string to wide characters.
+ *
+ * @param dest The buffer to receive the wide string.
+ * @param dest_size The size of the buffer, in characters.
+ * @param src The UTF-8 string to convert.
+ * @return The length of the wide string, in characters (not counting the NULL terminator), or < 0 for failure
+ */
+int git__utf8_to_16(wchar_t *dest, size_t dest_size, const char *src);
+
+/**
+ * Converts a wide string to UTF-8.
+ *
+ * @param dest The buffer to receive the UTF-8 string.
+ * @param dest_size The size of the buffer, in bytes.
+ * @param src The wide string to convert.
+ * @return The length of the UTF-8 string, in bytes (not counting the NULL terminator), or < 0 for failure
+ */
+int git__utf16_to_8(char *dest, size_t dest_size, const wchar_t *src);
+
+/**
+ * Converts a UTF-8 string to wide characters.
+ * Memory is allocated to hold the converted string.
+ * The caller is responsible for freeing the string with git__free.
+ *
+ * @param dest Receives a pointer to the wide string.
+ * @param src The UTF-8 string to convert.
+ * @return The length of the wide string, in characters (not counting the NULL terminator), or < 0 for failure
+ */
+int git__utf8_to_16_alloc(wchar_t **dest, const char *src);
+
+/**
+ * Converts a wide string to UTF-8.
+ * Memory is allocated to hold the converted string.
+ * The caller is responsible for freeing the string with git__free.
+ *
+ * @param dest Receives a pointer to the UTF-8 string.
+ * @param src The wide string to convert.
+ * @return The length of the UTF-8 string, in bytes (not counting the NULL terminator), or < 0 for failure
+ */
+int git__utf16_to_8_alloc(char **dest, const wchar_t *src);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/version.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/version.h
new file mode 100755
index 0000000..7966769
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/version.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_win32_version_h__
+#define INCLUDE_win32_version_h__
+
+#include <windows.h>
+
+GIT_INLINE(int) git_has_win32_version(int major, int minor, int service_pack)
+{
+	OSVERSIONINFOEX version_test = {0};
+	DWORD version_test_mask;
+	DWORDLONG version_condition_mask = 0;
+	
+	version_test.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+	version_test.dwMajorVersion = major;
+	version_test.dwMinorVersion = minor;
+	version_test.wServicePackMajor = (WORD)service_pack;
+	version_test.wServicePackMinor = 0;
+
+	version_test_mask = (VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR);
+
+	VER_SET_CONDITION(version_condition_mask, VER_MAJORVERSION, VER_GREATER_EQUAL);
+	VER_SET_CONDITION(version_condition_mask, VER_MINORVERSION, VER_GREATER_EQUAL);
+	VER_SET_CONDITION(version_condition_mask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+	VER_SET_CONDITION(version_condition_mask, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
+
+	if (!VerifyVersionInfo(&version_test, version_test_mask, version_condition_mask))
+		return 0;
+
+	return 1;
+}
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/w32_buffer.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/w32_buffer.c
new file mode 100755
index 0000000..9122baa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/w32_buffer.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "common.h"
+#include "w32_buffer.h"
+#include "../buffer.h"
+#include "utf-conv.h"
+
+GIT_INLINE(int) handle_wc_error(void)
+{
+	if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+		errno = ENAMETOOLONG;
+	else
+		errno = EINVAL;
+
+	return -1;
+}
+
+int git_buf_put_w(git_buf *buf, const wchar_t *string_w, size_t len_w)
+{
+	int utf8_len, utf8_write_len;
+	size_t new_size;
+
+	if (!len_w)
+		return 0;
+
+	assert(string_w);
+
+	/* Measure the string necessary for conversion */
+	if ((utf8_len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, string_w, len_w, NULL, 0, NULL, NULL)) == 0)
+		return 0;
+
+	assert(utf8_len > 0);
+
+	GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, (size_t)utf8_len);
+	GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
+
+	if (git_buf_grow(buf, new_size) < 0)
+		return -1;
+
+	if ((utf8_write_len = WideCharToMultiByte(
+			CP_UTF8, WC_ERR_INVALID_CHARS, string_w, len_w, &buf->ptr[buf->size], utf8_len, NULL, NULL)) == 0)
+		return handle_wc_error();
+
+	assert(utf8_write_len == utf8_len);
+
+	buf->size += utf8_write_len;
+	buf->ptr[buf->size] = '\0';
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/w32_buffer.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/w32_buffer.h
new file mode 100755
index 0000000..6224398
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/w32_buffer.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_win32_buffer_h__
+#define INCLUDE_git_win32_buffer_h__
+
+#include "../buffer.h"
+
+/**
+ * Convert a wide character string to UTF-8 and append the results to the
+ * buffer.
+ */
+int git_buf_put_w(git_buf *buf, const wchar_t *string_w, size_t len_w);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/w32_util.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/w32_util.c
new file mode 100755
index 0000000..2e52525
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/w32_util.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include "w32_util.h"
+
+/**
+ * Creates a FindFirstFile(Ex) filter string from a UTF-8 path.
+ * The filter string enumerates all items in the directory.
+ *
+ * @param dest The buffer to receive the filter string.
+ * @param src The UTF-8 path of the directory to enumerate.
+ * @return True if the filter string was created successfully; false otherwise
+ */
+bool git_win32__findfirstfile_filter(git_win32_path dest, const char *src)
+{
+	static const wchar_t suffix[] = L"\\*";
+	int len = git_win32_path_from_utf8(dest, src);
+
+	/* Ensure the path was converted */
+	if (len < 0)
+		return false;
+
+	/* Ensure that the path does not end with a trailing slash,
+	 * because we're about to add one. Don't rely our trim_end
+	 * helper, because we want to remove the backslash even for
+	 * drive letter paths, in this case. */
+	if (len > 0 &&
+		(dest[len - 1] == L'/' || dest[len - 1] == L'\\')) {
+		dest[len - 1] = L'\0';
+		len--;
+	}
+
+	/* Ensure we have enough room to add the suffix */
+	if ((size_t)len >= GIT_WIN_PATH_UTF16 - CONST_STRLEN(suffix))
+		return false;
+
+	wcscat(dest, suffix);
+	return true;
+}
+
+/**
+ * Ensures the given path (file or folder) has the +H (hidden) attribute set.
+ *
+ * @param path The path which should receive the +H bit.
+ * @return 0 on success; -1 on failure
+ */
+int git_win32__sethidden(const char *path)
+{
+	git_win32_path buf;
+	DWORD attrs;
+
+	if (git_win32_path_from_utf8(buf, path) < 0)
+		return -1;
+
+	attrs = GetFileAttributesW(buf);
+
+	/* Ensure the path exists */
+	if (attrs == INVALID_FILE_ATTRIBUTES)
+		return -1;
+
+	/* If the item isn't already +H, add the bit */
+	if ((attrs & FILE_ATTRIBUTE_HIDDEN) == 0 &&
+		!SetFileAttributesW(buf, attrs | FILE_ATTRIBUTE_HIDDEN))
+		return -1;
+
+	return 0;
+}
+
+/**
+ * Removes any trailing backslashes from a path, except in the case of a drive
+ * letter path (C:\, D:\, etc.). This function cannot fail.
+ *
+ * @param path The path which should be trimmed.
+ * @return The length of the modified string (<= the input length)
+ */
+size_t git_win32__path_trim_end(wchar_t *str, size_t len)
+{
+	while (1) {
+		if (!len || str[len - 1] != L'\\')
+			break;
+
+		/* Don't trim backslashes from drive letter paths, which
+		 * are 3 characters long and of the form C:\, D:\, etc. */
+		if (len == 3 && git_win32__isalpha(str[0]) && str[1] == ':')
+			break;
+
+		len--;
+	}
+
+	str[len] = L'\0';
+
+	return len;
+}
+
+/**
+ * Removes any of the following namespace prefixes from a path,
+ * if found: "\??\", "\\?\", "\\?\UNC\". This function cannot fail.
+ *
+ * @param path The path which should be converted.
+ * @return The length of the modified string (<= the input length)
+ */
+size_t git_win32__canonicalize_path(wchar_t *str, size_t len)
+{
+	static const wchar_t dosdevices_prefix[] = L"\\\?\?\\";
+	static const wchar_t nt_prefix[] = L"\\\\?\\";
+	static const wchar_t unc_prefix[] = L"UNC\\";
+	size_t to_advance = 0;
+
+	/* "\??\" -- DOS Devices prefix */
+	if (len >= CONST_STRLEN(dosdevices_prefix) &&
+		!wcsncmp(str, dosdevices_prefix, CONST_STRLEN(dosdevices_prefix))) {
+		to_advance += CONST_STRLEN(dosdevices_prefix);
+		len -= CONST_STRLEN(dosdevices_prefix);
+	}
+	/* "\\?\" -- NT namespace prefix */
+	else if (len >= CONST_STRLEN(nt_prefix) &&
+		!wcsncmp(str, nt_prefix, CONST_STRLEN(nt_prefix))) {
+		to_advance += CONST_STRLEN(nt_prefix);
+		len -= CONST_STRLEN(nt_prefix);
+	}
+
+	/* "\??\UNC\", "\\?\UNC\" -- UNC prefix */
+	if (to_advance && len >= CONST_STRLEN(unc_prefix) &&
+		!wcsncmp(str + to_advance, unc_prefix, CONST_STRLEN(unc_prefix))) {
+		to_advance += CONST_STRLEN(unc_prefix);
+		len -= CONST_STRLEN(unc_prefix);
+	}
+
+	if (to_advance) {
+		memmove(str, str + to_advance, len * sizeof(wchar_t));
+		str[len] = L'\0';
+	}
+
+	return git_win32__path_trim_end(str, len);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/w32_util.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/w32_util.h
new file mode 100755
index 0000000..377d651
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/win32/w32_util.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_w32_util_h__
+#define INCLUDE_w32_util_h__
+
+#include "utf-conv.h"
+#include "posix.h"
+#include "path_w32.h"
+
+/*
+
+#include "common.h"
+#include "path.h"
+#include "path_w32.h"
+#include "utf-conv.h"
+#include "posix.h"
+#include "reparse.h"
+#include "dir.h"
+*/
+
+
+GIT_INLINE(bool) git_win32__isalpha(wchar_t c)
+{
+	return ((c >= L'A' && c <= L'Z') || (c >= L'a' && c <= L'z'));
+}
+
+/**
+ * Creates a FindFirstFile(Ex) filter string from a UTF-8 path.
+ * The filter string enumerates all items in the directory.
+ *
+ * @param dest The buffer to receive the filter string.
+ * @param src The UTF-8 path of the directory to enumerate.
+ * @return True if the filter string was created successfully; false otherwise
+ */
+bool git_win32__findfirstfile_filter(git_win32_path dest, const char *src);
+
+/**
+ * Ensures the given path (file or folder) has the +H (hidden) attribute set.
+ *
+ * @param path The path which should receive the +H bit.
+ * @return 0 on success; -1 on failure
+ */
+int git_win32__sethidden(const char *path);
+
+/**
+ * Removes any trailing backslashes from a path, except in the case of a drive
+ * letter path (C:\, D:\, etc.). This function cannot fail.
+ *
+ * @param path The path which should be trimmed.
+ * @return The length of the modified string (<= the input length)
+ */
+size_t git_win32__path_trim_end(wchar_t *str, size_t len);
+
+/**
+ * Removes any of the following namespace prefixes from a path,
+ * if found: "\??\", "\\?\", "\\?\UNC\". This function cannot fail.
+ *
+ * @param path The path which should be converted.
+ * @return The length of the modified string (<= the input length)
+ */
+size_t git_win32__canonicalize_path(wchar_t *str, size_t len);
+
+/**
+ * Converts a FILETIME structure to a time_t.
+ *
+ * @param FILETIME A pointer to a FILETIME
+ * @return A time_t containing the same time
+ */
+GIT_INLINE(time_t) git_win32__filetime_to_time_t(const FILETIME *ft)
+{
+	long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
+	winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */
+	winTime /= 10000000;             /* Nano to seconds resolution */
+	return (time_t)winTime;
+}
+
+GIT_INLINE(void) git_win32__timeval_to_filetime(
+	FILETIME *ft, const struct timeval tv)
+{
+	long long ticks = (tv.tv_sec * 10000000LL) +
+		(tv.tv_usec * 10LL) + 116444736000000000LL;
+
+	ft->dwHighDateTime = ((ticks >> 32) & 0xffffffffLL);
+	ft->dwLowDateTime = (ticks & 0xffffffffLL);
+}
+
+GIT_INLINE(int) git_win32__file_attribute_to_stat(
+	struct stat *st,
+	const WIN32_FILE_ATTRIBUTE_DATA *attrdata,
+	const wchar_t *path)
+{
+	mode_t mode = S_IREAD;
+
+	if (attrdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+		mode |= S_IFDIR;
+	else
+		mode |= S_IFREG;
+
+	if ((attrdata->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
+		mode |= S_IWRITE;
+
+	st->st_ino = 0;
+	st->st_gid = 0;
+	st->st_uid = 0;
+	st->st_nlink = 1;
+	st->st_mode = mode;
+	st->st_size = ((git_off_t)attrdata->nFileSizeHigh << 32) + attrdata->nFileSizeLow;
+	st->st_dev = _getdrive() - 1;
+	st->st_rdev = st->st_dev;
+	st->st_atime = git_win32__filetime_to_time_t(&(attrdata->ftLastAccessTime));
+	st->st_mtime = git_win32__filetime_to_time_t(&(attrdata->ftLastWriteTime));
+	st->st_ctime = git_win32__filetime_to_time_t(&(attrdata->ftCreationTime));
+
+	if (attrdata->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && path) {
+		git_win32_path target;
+
+		if (git_win32_path_readlink_w(target, path) >= 0) {
+			st->st_mode = (st->st_mode & ~S_IFMT) | S_IFLNK;
+
+			/* st_size gets the UTF-8 length of the target name, in bytes,
+				* not counting the NULL terminator */
+			if ((st->st_size = git__utf16_to_8(NULL, 0, target)) < 0) {
+				giterr_set(GITERR_OS, "Could not convert reparse point name for '%s'", path);
+				return -1;
+			}
+		}
+	}
+
+	return 0;
+}
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xdiff.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xdiff.h
new file mode 100755
index 0000000..db5d598
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xdiff.h
@@ -0,0 +1,141 @@
+/*
+ *  LibXDiff by Davide Libenzi ( File Differential Library )
+ *  Copyright (C) 2003  Davide Libenzi
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel at xmailserver.org>
+ *
+ */
+
+#include "util.h"
+
+#if !defined(XDIFF_H)
+#define XDIFF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* #ifdef __cplusplus */
+
+
+#define XDF_NEED_MINIMAL (1 << 1)
+#define XDF_IGNORE_WHITESPACE (1 << 2)
+#define XDF_IGNORE_WHITESPACE_CHANGE (1 << 3)
+#define XDF_IGNORE_WHITESPACE_AT_EOL (1 << 4)
+#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_WHITESPACE_AT_EOL)
+
+#define XDF_PATIENCE_DIFF (1 << 5)
+#define XDF_HISTOGRAM_DIFF (1 << 6)
+#define XDF_DIFF_ALGORITHM_MASK (XDF_PATIENCE_DIFF | XDF_HISTOGRAM_DIFF)
+#define XDF_DIFF_ALG(x) ((x) & XDF_DIFF_ALGORITHM_MASK)
+
+#define XDF_IGNORE_BLANK_LINES (1 << 7)
+
+#define XDL_EMIT_FUNCNAMES (1 << 0)
+#define XDL_EMIT_COMMON (1 << 1)
+#define XDL_EMIT_FUNCCONTEXT (1 << 2)
+
+#define XDL_MMB_READONLY (1 << 0)
+
+#define XDL_MMF_ATOMIC (1 << 0)
+
+#define XDL_BDOP_INS 1
+#define XDL_BDOP_CPY 2
+#define XDL_BDOP_INSB 3
+
+/* merge simplification levels */
+#define XDL_MERGE_MINIMAL 0
+#define XDL_MERGE_EAGER 1
+#define XDL_MERGE_ZEALOUS 2
+#define XDL_MERGE_ZEALOUS_ALNUM 3
+
+/* merge favor modes */
+#define XDL_MERGE_FAVOR_OURS 1
+#define XDL_MERGE_FAVOR_THEIRS 2
+#define XDL_MERGE_FAVOR_UNION 3
+
+/* merge output styles */
+#define XDL_MERGE_DIFF3 1
+
+typedef struct s_mmfile {
+	char *ptr;
+	size_t size;
+} mmfile_t;
+
+typedef struct s_mmbuffer {
+	char *ptr;
+	size_t size;
+} mmbuffer_t;
+
+typedef struct s_xpparam {
+	unsigned long flags;
+} xpparam_t;
+
+typedef struct s_xdemitcb {
+	void *priv;
+	int (*outf)(void *, mmbuffer_t *, int);
+} xdemitcb_t;
+
+typedef long (*find_func_t)(const char *line, long line_len, char *buffer, long buffer_size, void *priv);
+
+typedef int (*xdl_emit_hunk_consume_func_t)(long start_a, long count_a,
+					    long start_b, long count_b,
+					    void *cb_data);
+
+typedef struct s_xdemitconf {
+	long ctxlen;
+	long interhunkctxlen;
+	unsigned long flags;
+	find_func_t find_func;
+	void *find_func_priv;
+	xdl_emit_hunk_consume_func_t hunk_func;
+} xdemitconf_t;
+
+typedef struct s_bdiffparam {
+	long bsize;
+} bdiffparam_t;
+
+
+#define xdl_malloc(x) git__malloc(x)
+#define xdl_free(ptr) git__free(ptr)
+#define xdl_realloc(ptr,x) git__realloc(ptr,x)
+
+void *xdl_mmfile_first(mmfile_t *mmf, long *size);
+long xdl_mmfile_size(mmfile_t *mmf);
+
+int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+	     xdemitconf_t const *xecfg, xdemitcb_t *ecb);
+
+typedef struct s_xmparam {
+	xpparam_t xpp;
+	int marker_size;
+	int level;
+	int favor;
+	int style;
+	const char *ancestor;	/* label for orig */
+	const char *file1;	/* label for mf1 */
+	const char *file2;	/* label for mf2 */
+} xmparam_t;
+
+#define DEFAULT_CONFLICT_MARKER_SIZE 7
+
+int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2,
+		xmparam_t const *xmp, mmbuffer_t *result);
+
+#ifdef __cplusplus
+}
+#endif /* #ifdef __cplusplus */
+
+#endif /* #if !defined(XDIFF_H) */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xdiffi.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xdiffi.c
new file mode 100755
index 0000000..f4d01b4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xdiffi.c
@@ -0,0 +1,618 @@
+/*
+ *  LibXDiff by Davide Libenzi ( File Differential Library )
+ *  Copyright (C) 2003	Davide Libenzi
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel at xmailserver.org>
+ *
+ */
+
+#include "xinclude.h"
+#include "common.h"
+#include "integer.h"
+
+
+#define XDL_MAX_COST_MIN 256
+#define XDL_HEUR_MIN_COST 256
+#define XDL_LINE_MAX (long)((1UL << (CHAR_BIT * sizeof(long) - 1)) - 1)
+#define XDL_SNAKE_CNT 20
+#define XDL_K_HEUR 4
+
+
+
+typedef struct s_xdpsplit {
+	long i1, i2;
+	int min_lo, min_hi;
+} xdpsplit_t;
+
+
+
+
+static long xdl_split(unsigned long const *ha1, long off1, long lim1,
+		      unsigned long const *ha2, long off2, long lim2,
+		      long *kvdf, long *kvdb, int need_min, xdpsplit_t *spl,
+		      xdalgoenv_t *xenv);
+static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, long chg2);
+
+
+
+
+
+/*
+ * See "An O(ND) Difference Algorithm and its Variations", by Eugene Myers.
+ * Basically considers a "box" (off1, off2, lim1, lim2) and scan from both
+ * the forward diagonal starting from (off1, off2) and the backward diagonal
+ * starting from (lim1, lim2). If the K values on the same diagonal crosses
+ * returns the furthest point of reach. We might end up having to expensive
+ * cases using this algorithm is full, so a little bit of heuristic is needed
+ * to cut the search and to return a suboptimal point.
+ */
+static long xdl_split(unsigned long const *ha1, long off1, long lim1,
+		      unsigned long const *ha2, long off2, long lim2,
+		      long *kvdf, long *kvdb, int need_min, xdpsplit_t *spl,
+		      xdalgoenv_t *xenv) {
+	long dmin = off1 - lim2, dmax = lim1 - off2;
+	long fmid = off1 - off2, bmid = lim1 - lim2;
+	long odd = (fmid - bmid) & 1;
+	long fmin = fmid, fmax = fmid;
+	long bmin = bmid, bmax = bmid;
+	long ec, d, i1, i2, prev1, best, dd, v, k;
+
+	/*
+	 * Set initial diagonal values for both forward and backward path.
+	 */
+	kvdf[fmid] = off1;
+	kvdb[bmid] = lim1;
+
+	for (ec = 1;; ec++) {
+		int got_snake = 0;
+
+		/*
+		 * We need to extent the diagonal "domain" by one. If the next
+		 * values exits the box boundaries we need to change it in the
+		 * opposite direction because (max - min) must be a power of two.
+		 * Also we initialize the external K value to -1 so that we can
+		 * avoid extra conditions check inside the core loop.
+		 */
+		if (fmin > dmin)
+			kvdf[--fmin - 1] = -1;
+		else
+			++fmin;
+		if (fmax < dmax)
+			kvdf[++fmax + 1] = -1;
+		else
+			--fmax;
+
+		for (d = fmax; d >= fmin; d -= 2) {
+			if (kvdf[d - 1] >= kvdf[d + 1])
+				i1 = kvdf[d - 1] + 1;
+			else
+				i1 = kvdf[d + 1];
+			prev1 = i1;
+			i2 = i1 - d;
+			for (; i1 < lim1 && i2 < lim2 && ha1[i1] == ha2[i2]; i1++, i2++);
+			if (i1 - prev1 > xenv->snake_cnt)
+				got_snake = 1;
+			kvdf[d] = i1;
+			if (odd && bmin <= d && d <= bmax && kvdb[d] <= i1) {
+				spl->i1 = i1;
+				spl->i2 = i2;
+				spl->min_lo = spl->min_hi = 1;
+				return ec;
+			}
+		}
+
+		/*
+		 * We need to extent the diagonal "domain" by one. If the next
+		 * values exits the box boundaries we need to change it in the
+		 * opposite direction because (max - min) must be a power of two.
+		 * Also we initialize the external K value to -1 so that we can
+		 * avoid extra conditions check inside the core loop.
+		 */
+		if (bmin > dmin)
+			kvdb[--bmin - 1] = XDL_LINE_MAX;
+		else
+			++bmin;
+		if (bmax < dmax)
+			kvdb[++bmax + 1] = XDL_LINE_MAX;
+		else
+			--bmax;
+
+		for (d = bmax; d >= bmin; d -= 2) {
+			if (kvdb[d - 1] < kvdb[d + 1])
+				i1 = kvdb[d - 1];
+			else
+				i1 = kvdb[d + 1] - 1;
+			prev1 = i1;
+			i2 = i1 - d;
+			for (; i1 > off1 && i2 > off2 && ha1[i1 - 1] == ha2[i2 - 1]; i1--, i2--);
+			if (prev1 - i1 > xenv->snake_cnt)
+				got_snake = 1;
+			kvdb[d] = i1;
+			if (!odd && fmin <= d && d <= fmax && i1 <= kvdf[d]) {
+				spl->i1 = i1;
+				spl->i2 = i2;
+				spl->min_lo = spl->min_hi = 1;
+				return ec;
+			}
+		}
+
+		if (need_min)
+			continue;
+
+		/*
+		 * If the edit cost is above the heuristic trigger and if
+		 * we got a good snake, we sample current diagonals to see
+		 * if some of the, have reached an "interesting" path. Our
+		 * measure is a function of the distance from the diagonal
+		 * corner (i1 + i2) penalized with the distance from the
+		 * mid diagonal itself. If this value is above the current
+		 * edit cost times a magic factor (XDL_K_HEUR) we consider
+		 * it interesting.
+		 */
+		if (got_snake && ec > xenv->heur_min) {
+			for (best = 0, d = fmax; d >= fmin; d -= 2) {
+				dd = d > fmid ? d - fmid: fmid - d;
+				i1 = kvdf[d];
+				i2 = i1 - d;
+				v = (i1 - off1) + (i2 - off2) - dd;
+
+				if (v > XDL_K_HEUR * ec && v > best &&
+				    off1 + xenv->snake_cnt <= i1 && i1 < lim1 &&
+				    off2 + xenv->snake_cnt <= i2 && i2 < lim2) {
+					for (k = 1; ha1[i1 - k] == ha2[i2 - k]; k++)
+						if (k == xenv->snake_cnt) {
+							best = v;
+							spl->i1 = i1;
+							spl->i2 = i2;
+							break;
+						}
+				}
+			}
+			if (best > 0) {
+				spl->min_lo = 1;
+				spl->min_hi = 0;
+				return ec;
+			}
+
+			for (best = 0, d = bmax; d >= bmin; d -= 2) {
+				dd = d > bmid ? d - bmid: bmid - d;
+				i1 = kvdb[d];
+				i2 = i1 - d;
+				v = (lim1 - i1) + (lim2 - i2) - dd;
+
+				if (v > XDL_K_HEUR * ec && v > best &&
+				    off1 < i1 && i1 <= lim1 - xenv->snake_cnt &&
+				    off2 < i2 && i2 <= lim2 - xenv->snake_cnt) {
+					for (k = 0; ha1[i1 + k] == ha2[i2 + k]; k++)
+						if (k == xenv->snake_cnt - 1) {
+							best = v;
+							spl->i1 = i1;
+							spl->i2 = i2;
+							break;
+						}
+				}
+			}
+			if (best > 0) {
+				spl->min_lo = 0;
+				spl->min_hi = 1;
+				return ec;
+			}
+		}
+
+		/*
+		 * Enough is enough. We spent too much time here and now we collect
+		 * the furthest reaching path using the (i1 + i2) measure.
+		 */
+		if (ec >= xenv->mxcost) {
+			long fbest, fbest1, bbest, bbest1;
+
+			fbest = fbest1 = -1;
+			for (d = fmax; d >= fmin; d -= 2) {
+				i1 = XDL_MIN(kvdf[d], lim1);
+				i2 = i1 - d;
+				if (lim2 < i2)
+					i1 = lim2 + d, i2 = lim2;
+				if (fbest < i1 + i2) {
+					fbest = i1 + i2;
+					fbest1 = i1;
+				}
+			}
+
+			bbest = bbest1 = XDL_LINE_MAX;
+			for (d = bmax; d >= bmin; d -= 2) {
+				i1 = XDL_MAX(off1, kvdb[d]);
+				i2 = i1 - d;
+				if (i2 < off2)
+					i1 = off2 + d, i2 = off2;
+				if (i1 + i2 < bbest) {
+					bbest = i1 + i2;
+					bbest1 = i1;
+				}
+			}
+
+			if ((lim1 + lim2) - bbest < fbest - (off1 + off2)) {
+				spl->i1 = fbest1;
+				spl->i2 = fbest - fbest1;
+				spl->min_lo = 1;
+				spl->min_hi = 0;
+			} else {
+				spl->i1 = bbest1;
+				spl->i2 = bbest - bbest1;
+				spl->min_lo = 0;
+				spl->min_hi = 1;
+			}
+			return ec;
+		}
+	}
+}
+
+
+/*
+ * Rule: "Divide et Impera". Recursively split the box in sub-boxes by calling
+ * the box splitting function. Note that the real job (marking changed lines)
+ * is done in the two boundary reaching checks.
+ */
+int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1,
+		 diffdata_t *dd2, long off2, long lim2,
+		 long *kvdf, long *kvdb, int need_min, xdalgoenv_t *xenv) {
+	unsigned long const *ha1 = dd1->ha, *ha2 = dd2->ha;
+
+	/*
+	 * Shrink the box by walking through each diagonal snake (SW and NE).
+	 */
+	for (; off1 < lim1 && off2 < lim2 && ha1[off1] == ha2[off2]; off1++, off2++);
+	for (; off1 < lim1 && off2 < lim2 && ha1[lim1 - 1] == ha2[lim2 - 1]; lim1--, lim2--);
+
+	/*
+	 * If one dimension is empty, then all records on the other one must
+	 * be obviously changed.
+	 */
+	if (off1 == lim1) {
+		char *rchg2 = dd2->rchg;
+		long *rindex2 = dd2->rindex;
+
+		for (; off2 < lim2; off2++)
+			rchg2[rindex2[off2]] = 1;
+	} else if (off2 == lim2) {
+		char *rchg1 = dd1->rchg;
+		long *rindex1 = dd1->rindex;
+
+		for (; off1 < lim1; off1++)
+			rchg1[rindex1[off1]] = 1;
+	} else {
+		xdpsplit_t spl;
+		spl.i1 = spl.i2 = 0;
+
+		/*
+		 * Divide ...
+		 */
+		if (xdl_split(ha1, off1, lim1, ha2, off2, lim2, kvdf, kvdb,
+			      need_min, &spl, xenv) < 0) {
+
+			return -1;
+		}
+
+		/*
+		 * ... et Impera.
+		 */
+		if (xdl_recs_cmp(dd1, off1, spl.i1, dd2, off2, spl.i2,
+				 kvdf, kvdb, spl.min_lo, xenv) < 0 ||
+		    xdl_recs_cmp(dd1, spl.i1, lim1, dd2, spl.i2, lim2,
+				 kvdf, kvdb, spl.min_hi, xenv) < 0) {
+
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+
+int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+		xdfenv_t *xe) {
+	size_t ndiags, allocsize;
+	long *kvd, *kvdf, *kvdb;
+	xdalgoenv_t xenv;
+	diffdata_t dd1, dd2;
+
+	if (XDF_DIFF_ALG(xpp->flags) == XDF_PATIENCE_DIFF)
+		return xdl_do_patience_diff(mf1, mf2, xpp, xe);
+
+	if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
+		return xdl_do_histogram_diff(mf1, mf2, xpp, xe);
+
+	if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0) {
+
+		return -1;
+	}
+
+	/*
+	 * Allocate and setup K vectors to be used by the differential algorithm.
+	 * One is to store the forward path and one to store the backward path.
+	 */
+	GITERR_CHECK_ALLOC_ADD3(&ndiags, xe->xdf1.nreff, xe->xdf2.nreff, 3);
+	GITERR_CHECK_ALLOC_MULTIPLY(&allocsize, ndiags, 2);
+	GITERR_CHECK_ALLOC_ADD(&allocsize, allocsize, 2);
+	GITERR_CHECK_ALLOC_MULTIPLY(&allocsize, allocsize, sizeof(long));
+
+	if (!(kvd = (long *) xdl_malloc(allocsize))) {
+		xdl_free_env(xe);
+		return -1;
+	}
+	kvdf = kvd;
+	kvdb = kvdf + ndiags;
+	kvdf += xe->xdf2.nreff + 1;
+	kvdb += xe->xdf2.nreff + 1;
+
+	xenv.mxcost = xdl_bogosqrt(ndiags);
+	if (xenv.mxcost < XDL_MAX_COST_MIN)
+		xenv.mxcost = XDL_MAX_COST_MIN;
+	xenv.snake_cnt = XDL_SNAKE_CNT;
+	xenv.heur_min = XDL_HEUR_MIN_COST;
+
+	dd1.nrec = xe->xdf1.nreff;
+	dd1.ha = xe->xdf1.ha;
+	dd1.rchg = xe->xdf1.rchg;
+	dd1.rindex = xe->xdf1.rindex;
+	dd2.nrec = xe->xdf2.nreff;
+	dd2.ha = xe->xdf2.ha;
+	dd2.rchg = xe->xdf2.rchg;
+	dd2.rindex = xe->xdf2.rindex;
+
+	if (xdl_recs_cmp(&dd1, 0, dd1.nrec, &dd2, 0, dd2.nrec,
+			 kvdf, kvdb, (xpp->flags & XDF_NEED_MINIMAL) != 0, &xenv) < 0) {
+
+		xdl_free(kvd);
+		xdl_free_env(xe);
+		return -1;
+	}
+
+	xdl_free(kvd);
+
+	return 0;
+}
+
+
+static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, long chg2) {
+	xdchange_t *xch;
+
+	if (!(xch = (xdchange_t *) xdl_malloc(sizeof(xdchange_t))))
+		return NULL;
+
+	xch->next = xscr;
+	xch->i1 = i1;
+	xch->i2 = i2;
+	xch->chg1 = chg1;
+	xch->chg2 = chg2;
+	xch->ignore = 0;
+
+	return xch;
+}
+
+
+int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
+	long ix, ixo, ixs, ixref, grpsiz, nrec = xdf->nrec;
+	char *rchg = xdf->rchg, *rchgo = xdfo->rchg;
+	xrecord_t **recs = xdf->recs;
+
+	/*
+	 * This is the same of what GNU diff does. Move back and forward
+	 * change groups for a consistent and pretty diff output. This also
+	 * helps in finding joinable change groups and reduce the diff size.
+	 */
+	for (ix = ixo = 0;;) {
+		/*
+		 * Find the first changed line in the to-be-compacted file.
+		 * We need to keep track of both indexes, so if we find a
+		 * changed lines group on the other file, while scanning the
+		 * to-be-compacted file, we need to skip it properly. Note
+		 * that loops that are testing for changed lines on rchg* do
+		 * not need index bounding since the array is prepared with
+		 * a zero at position -1 and N.
+		 */
+		for (; ix < nrec && !rchg[ix]; ix++)
+			while (rchgo[ixo++]);
+		if (ix == nrec)
+			break;
+
+		/*
+		 * Record the start of a changed-group in the to-be-compacted file
+		 * and find the end of it, on both to-be-compacted and other file
+		 * indexes (ix and ixo).
+		 */
+		ixs = ix;
+		for (ix++; rchg[ix]; ix++);
+		for (; rchgo[ixo]; ixo++);
+
+		do {
+			grpsiz = ix - ixs;
+
+			/*
+			 * If the line before the current change group, is equal to
+			 * the last line of the current change group, shift backward
+			 * the group.
+			 */
+			while (ixs > 0 && recs[ixs - 1]->ha == recs[ix - 1]->ha &&
+			       xdl_recmatch(recs[ixs - 1]->ptr, recs[ixs - 1]->size, recs[ix - 1]->ptr, recs[ix - 1]->size, flags)) {
+				rchg[--ixs] = 1;
+				rchg[--ix] = 0;
+
+				/*
+				 * This change might have joined two change groups,
+				 * so we try to take this scenario in account by moving
+				 * the start index accordingly (and so the other-file
+				 * end-of-group index).
+				 */
+				for (; rchg[ixs - 1]; ixs--);
+				while (rchgo[--ixo]);
+			}
+
+			/*
+			 * Record the end-of-group position in case we are matched
+			 * with a group of changes in the other file (that is, the
+			 * change record before the end-of-group index in the other
+			 * file is set).
+			 */
+			ixref = rchgo[ixo - 1] ? ix: nrec;
+
+			/*
+			 * If the first line of the current change group, is equal to
+			 * the line next of the current change group, shift forward
+			 * the group.
+			 */
+			while (ix < nrec && recs[ixs]->ha == recs[ix]->ha &&
+			       xdl_recmatch(recs[ixs]->ptr, recs[ixs]->size, recs[ix]->ptr, recs[ix]->size, flags)) {
+				rchg[ixs++] = 0;
+				rchg[ix++] = 1;
+
+				/*
+				 * This change might have joined two change groups,
+				 * so we try to take this scenario in account by moving
+				 * the start index accordingly (and so the other-file
+				 * end-of-group index). Keep tracking the reference
+				 * index in case we are shifting together with a
+				 * corresponding group of changes in the other file.
+				 */
+				for (; rchg[ix]; ix++);
+				while (rchgo[++ixo])
+					ixref = ix;
+			}
+		} while (grpsiz != ix - ixs);
+
+		/*
+		 * Try to move back the possibly merged group of changes, to match
+		 * the recorded position in the other file.
+		 */
+		while (ixref < ix) {
+			rchg[--ixs] = 1;
+			rchg[--ix] = 0;
+			while (rchgo[--ixo]);
+		}
+	}
+
+	return 0;
+}
+
+
+int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr) {
+	xdchange_t *cscr = NULL, *xch;
+	char *rchg1 = xe->xdf1.rchg, *rchg2 = xe->xdf2.rchg;
+	long i1, i2, l1, l2;
+
+	/*
+	 * Trivial. Collects "groups" of changes and creates an edit script.
+	 */
+	for (i1 = xe->xdf1.nrec, i2 = xe->xdf2.nrec; i1 >= 0 || i2 >= 0; i1--, i2--)
+		if (rchg1[i1 - 1] || rchg2[i2 - 1]) {
+			for (l1 = i1; rchg1[i1 - 1]; i1--);
+			for (l2 = i2; rchg2[i2 - 1]; i2--);
+
+			if (!(xch = xdl_add_change(cscr, i1, i2, l1 - i1, l2 - i2))) {
+				xdl_free_script(cscr);
+				return -1;
+			}
+			cscr = xch;
+		}
+
+	*xscr = cscr;
+
+	return 0;
+}
+
+
+void xdl_free_script(xdchange_t *xscr) {
+	xdchange_t *xch;
+
+	while ((xch = xscr) != NULL) {
+		xscr = xscr->next;
+		xdl_free(xch);
+	}
+}
+
+static int xdl_call_hunk_func(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
+			      xdemitconf_t const *xecfg)
+{
+	xdchange_t *xch, *xche;
+
+	(void)xe;
+
+	for (xch = xscr; xch; xch = xche->next) {
+		xche = xdl_get_hunk(&xch, xecfg);
+		if (!xch)
+			break;
+		if (xecfg->hunk_func(xch->i1, xche->i1 + xche->chg1 - xch->i1,
+				     xch->i2, xche->i2 + xche->chg2 - xch->i2,
+				     ecb->priv) < 0)
+			return -1;
+	}
+	return 0;
+}
+
+static void xdl_mark_ignorable(xdchange_t *xscr, xdfenv_t *xe, long flags)
+{
+	xdchange_t *xch;
+
+	for (xch = xscr; xch; xch = xch->next) {
+		int ignore = 1;
+		xrecord_t **rec;
+		long i;
+
+		rec = &xe->xdf1.recs[xch->i1];
+		for (i = 0; i < xch->chg1 && ignore; i++)
+			ignore = xdl_blankline(rec[i]->ptr, rec[i]->size, flags);
+
+		rec = &xe->xdf2.recs[xch->i2];
+		for (i = 0; i < xch->chg2 && ignore; i++)
+			ignore = xdl_blankline(rec[i]->ptr, rec[i]->size, flags);
+
+		xch->ignore = ignore;
+	}
+}
+
+int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+	     xdemitconf_t const *xecfg, xdemitcb_t *ecb) {
+	xdchange_t *xscr;
+	xdfenv_t xe;
+	emit_func_t ef = xecfg->hunk_func ? xdl_call_hunk_func : xdl_emit_diff;
+
+	if (xdl_do_diff(mf1, mf2, xpp, &xe) < 0) {
+
+		return -1;
+	}
+	if (xdl_change_compact(&xe.xdf1, &xe.xdf2, xpp->flags) < 0 ||
+	    xdl_change_compact(&xe.xdf2, &xe.xdf1, xpp->flags) < 0 ||
+	    xdl_build_script(&xe, &xscr) < 0) {
+
+		xdl_free_env(&xe);
+		return -1;
+	}
+	if (xscr) {
+		if (xpp->flags & XDF_IGNORE_BLANK_LINES)
+			xdl_mark_ignorable(xscr, &xe, xpp->flags);
+
+		if (ef(&xe, xscr, ecb, xecfg) < 0) {
+
+			xdl_free_script(xscr);
+			xdl_free_env(&xe);
+			return -1;
+		}
+		xdl_free_script(xscr);
+	}
+	xdl_free_env(&xe);
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xdiffi.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xdiffi.h
new file mode 100755
index 0000000..8b81206
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xdiffi.h
@@ -0,0 +1,64 @@
+/*
+ *  LibXDiff by Davide Libenzi ( File Differential Library )
+ *  Copyright (C) 2003  Davide Libenzi
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel at xmailserver.org>
+ *
+ */
+
+#if !defined(XDIFFI_H)
+#define XDIFFI_H
+
+
+typedef struct s_diffdata {
+	long nrec;
+	unsigned long const *ha;
+	long *rindex;
+	char *rchg;
+} diffdata_t;
+
+typedef struct s_xdalgoenv {
+	long mxcost;
+	long snake_cnt;
+	long heur_min;
+} xdalgoenv_t;
+
+typedef struct s_xdchange {
+	struct s_xdchange *next;
+	long i1, i2;
+	long chg1, chg2;
+	int ignore;
+} xdchange_t;
+
+
+
+int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1,
+		 diffdata_t *dd2, long off2, long lim2,
+		 long *kvdf, long *kvdb, int need_min, xdalgoenv_t *xenv);
+int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+		xdfenv_t *xe);
+int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags);
+int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr);
+void xdl_free_script(xdchange_t *xscr);
+int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
+		  xdemitconf_t const *xecfg);
+int xdl_do_patience_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+		xdfenv_t *env);
+int xdl_do_histogram_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+		xdfenv_t *env);
+
+#endif /* #if !defined(XDIFFI_H) */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xemit.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xemit.c
new file mode 100755
index 0000000..600fd1f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xemit.c
@@ -0,0 +1,290 @@
+/*
+ *  LibXDiff by Davide Libenzi ( File Differential Library )
+ *  Copyright (C) 2003	Davide Libenzi
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel at xmailserver.org>
+ *
+ */
+
+#include "xinclude.h"
+
+
+
+
+static long xdl_get_rec(xdfile_t *xdf, long ri, char const **rec);
+static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb);
+
+
+
+
+static long xdl_get_rec(xdfile_t *xdf, long ri, char const **rec) {
+
+	*rec = xdf->recs[ri]->ptr;
+
+	return xdf->recs[ri]->size;
+}
+
+
+static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb) {
+	long size, psize = (long)strlen(pre);
+	char const *rec;
+
+	size = xdl_get_rec(xdf, ri, &rec);
+	if (xdl_emit_diffrec(rec, size, pre, psize, ecb) < 0) {
+
+		return -1;
+	}
+
+	return 0;
+}
+
+
+/*
+ * Starting at the passed change atom, find the latest change atom to be included
+ * inside the differential hunk according to the specified configuration.
+ * Also advance xscr if the first changes must be discarded.
+ */
+xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
+{
+	xdchange_t *xch, *xchp, *lxch;
+	long max_common = 2 * xecfg->ctxlen + xecfg->interhunkctxlen;
+	long max_ignorable = xecfg->ctxlen;
+	unsigned long ignored = 0; /* number of ignored blank lines */
+
+	/* remove ignorable changes that are too far before other changes */
+	for (xchp = *xscr; xchp && xchp->ignore; xchp = xchp->next) {
+		xch = xchp->next;
+
+		if (xch == NULL ||
+		    xch->i1 - (xchp->i1 + xchp->chg1) >= max_ignorable)
+			*xscr = xch;
+	}
+
+	if (*xscr == NULL)
+		return NULL;
+
+	lxch = *xscr;
+
+	for (xchp = *xscr, xch = xchp->next; xch; xchp = xch, xch = xch->next) {
+		long distance = xch->i1 - (xchp->i1 + xchp->chg1);
+		if (distance > max_common)
+			break;
+
+		if (distance < max_ignorable && (!xch->ignore || lxch == xchp)) {
+			lxch = xch;
+			ignored = 0;
+		} else if (distance < max_ignorable && xch->ignore) {
+			ignored += xch->chg2;
+		} else if (lxch != xchp &&
+			   xch->i1 + ignored - (lxch->i1 + lxch->chg1) > (unsigned long)max_common) {
+			break;
+		} else if (!xch->ignore) {
+			lxch = xch;
+			ignored = 0;
+		} else {
+			ignored += xch->chg2;
+		}
+	}
+
+	return lxch;
+}
+
+
+static long def_ff(const char *rec, long len, char *buf, long sz, void *priv)
+{
+	(void)priv;
+
+	if (len > 0 &&
+			(isalpha((unsigned char)*rec) || /* identifier? */
+			 *rec == '_' ||	/* also identifier? */
+			 *rec == '$')) { /* identifiers from VMS and other esoterico */
+		if (len > sz)
+			len = sz;
+		while (0 < len && isspace((unsigned char)rec[len - 1]))
+			len--;
+		memcpy(buf, rec, len);
+		return len;
+	}
+	return -1;
+}
+
+static int xdl_emit_common(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
+                           xdemitconf_t const *xecfg) {
+	xdfile_t *xdf = &xe->xdf2;
+	const char *rchg = xdf->rchg;
+	long ix;
+
+	(void)xscr;
+	(void)xecfg;
+
+	for (ix = 0; ix < xdf->nrec; ix++) {
+		if (rchg[ix])
+			continue;
+		if (xdl_emit_record(xdf, ix, "", ecb))
+			return -1;
+	}
+	return 0;
+}
+
+struct func_line {
+	long len;
+	char buf[80];
+};
+
+static long get_func_line(xdfenv_t *xe, xdemitconf_t const *xecfg,
+			  struct func_line *func_line, long start, long limit)
+{
+	find_func_t ff = xecfg->find_func ? xecfg->find_func : def_ff;
+	long l, size, step = (start > limit) ? -1 : 1;
+	char *buf, dummy[1];
+
+	buf = func_line ? func_line->buf : dummy;
+	size = func_line ? sizeof(func_line->buf) : sizeof(dummy);
+
+	for (l = start; l != limit && 0 <= l && l < xe->xdf1.nrec; l += step) {
+		const char *rec;
+		long reclen = xdl_get_rec(&xe->xdf1, l, &rec);
+		long len = ff(rec, reclen, buf, size, xecfg->find_func_priv);
+		if (len >= 0) {
+			if (func_line)
+				func_line->len = len;
+			return l;
+		}
+	}
+	return -1;
+}
+
+int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
+		  xdemitconf_t const *xecfg) {
+	long s1, s2, e1, e2, lctx;
+	xdchange_t *xch, *xche;
+	long funclineprev = -1;
+	struct func_line func_line = { 0 };
+
+	if (xecfg->flags & XDL_EMIT_COMMON)
+		return xdl_emit_common(xe, xscr, ecb, xecfg);
+
+	for (xch = xscr; xch; xch = xche->next) {
+		xche = xdl_get_hunk(&xch, xecfg);
+		if (!xch)
+			break;
+
+		s1 = XDL_MAX(xch->i1 - xecfg->ctxlen, 0);
+		s2 = XDL_MAX(xch->i2 - xecfg->ctxlen, 0);
+
+		if (xecfg->flags & XDL_EMIT_FUNCCONTEXT) {
+			long fs1 = get_func_line(xe, xecfg, NULL, xch->i1, -1);
+			if (fs1 < 0)
+				fs1 = 0;
+			if (fs1 < s1) {
+				s2 -= s1 - fs1;
+				s1 = fs1;
+			}
+		}
+
+ again:
+		lctx = xecfg->ctxlen;
+		lctx = XDL_MIN(lctx, xe->xdf1.nrec - (xche->i1 + xche->chg1));
+		lctx = XDL_MIN(lctx, xe->xdf2.nrec - (xche->i2 + xche->chg2));
+
+		e1 = xche->i1 + xche->chg1 + lctx;
+		e2 = xche->i2 + xche->chg2 + lctx;
+
+		if (xecfg->flags & XDL_EMIT_FUNCCONTEXT) {
+			long fe1 = get_func_line(xe, xecfg, NULL,
+						 xche->i1 + xche->chg1,
+						 xe->xdf1.nrec);
+			if (fe1 < 0)
+				fe1 = xe->xdf1.nrec;
+			if (fe1 > e1) {
+				e2 += fe1 - e1;
+				e1 = fe1;
+			}
+
+			/*
+			 * Overlap with next change?  Then include it
+			 * in the current hunk and start over to find
+			 * its new end.
+			 */
+			if (xche->next) {
+				long l = xche->next->i1;
+				if (l <= e1 ||
+				    get_func_line(xe, xecfg, NULL, l, e1) < 0) {
+					xche = xche->next;
+					goto again;
+				}
+			}
+		}
+
+		/*
+		 * Emit current hunk header.
+		 */
+
+		if (xecfg->flags & XDL_EMIT_FUNCNAMES) {
+			get_func_line(xe, xecfg, &func_line,
+				      s1 - 1, funclineprev);
+			funclineprev = s1 - 1;
+		}
+		if (xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2,
+				      func_line.buf, func_line.len, ecb) < 0)
+			return -1;
+
+		/*
+		 * Emit pre-context.
+		 */
+		for (; s2 < xch->i2; s2++)
+			if (xdl_emit_record(&xe->xdf2, s2, " ", ecb) < 0)
+				return -1;
+
+		for (s1 = xch->i1, s2 = xch->i2;; xch = xch->next) {
+			/*
+			 * Merge previous with current change atom.
+			 */
+			for (; s1 < xch->i1 && s2 < xch->i2; s1++, s2++)
+				if (xdl_emit_record(&xe->xdf2, s2, " ", ecb) < 0)
+					return -1;
+
+			/*
+			 * Removes lines from the first file.
+			 */
+			for (s1 = xch->i1; s1 < xch->i1 + xch->chg1; s1++)
+				if (xdl_emit_record(&xe->xdf1, s1, "-", ecb) < 0)
+					return -1;
+
+			/*
+			 * Adds lines from the second file.
+			 */
+			for (s2 = xch->i2; s2 < xch->i2 + xch->chg2; s2++)
+				if (xdl_emit_record(&xe->xdf2, s2, "+", ecb) < 0)
+					return -1;
+
+			if (xch == xche)
+				break;
+			s1 = xch->i1 + xch->chg1;
+			s2 = xch->i2 + xch->chg2;
+		}
+
+		/*
+		 * Emit post-context.
+		 */
+		for (s2 = xche->i2 + xche->chg2; s2 < e2; s2++)
+			if (xdl_emit_record(&xe->xdf2, s2, " ", ecb) < 0)
+				return -1;
+	}
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xemit.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xemit.h
new file mode 100755
index 0000000..d297107
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xemit.h
@@ -0,0 +1,36 @@
+/*
+ *  LibXDiff by Davide Libenzi ( File Differential Library )
+ *  Copyright (C) 2003  Davide Libenzi
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel at xmailserver.org>
+ *
+ */
+
+#if !defined(XEMIT_H)
+#define XEMIT_H
+
+
+typedef int (*emit_func_t)(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
+			   xdemitconf_t const *xecfg);
+
+xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg);
+int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
+		  xdemitconf_t const *xecfg);
+
+
+
+#endif /* #if !defined(XEMIT_H) */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xhistogram.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xhistogram.c
new file mode 100755
index 0000000..0c2edb8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xhistogram.c
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2010, Google Inc.
+ * and other copyright owners as documented in JGit's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "xinclude.h"
+#include "xtypes.h"
+#include "xdiff.h"
+#include "common.h"
+
+#define MAX_PTR	UINT_MAX
+#define MAX_CNT	UINT_MAX
+
+#define LINE_END(n) (line##n + count##n - 1)
+#define LINE_END_PTR(n) (*line##n + *count##n - 1)
+
+struct histindex {
+	struct record {
+		unsigned int ptr, cnt;
+		struct record *next;
+	} **records, /* an occurrence */
+	  **line_map; /* map of line to record chain */
+	chastore_t rcha;
+	unsigned int *next_ptrs;
+	unsigned int table_bits,
+		     records_size,
+		     line_map_size;
+
+	unsigned int max_chain_length,
+		     key_shift,
+		     ptr_shift;
+
+	unsigned int cnt,
+		     has_common;
+
+	xdfenv_t *env;
+	xpparam_t const *xpp;
+};
+
+struct region {
+	unsigned int begin1, end1;
+	unsigned int begin2, end2;
+};
+
+#define LINE_MAP(i, a) (i->line_map[(a) - i->ptr_shift])
+
+#define NEXT_PTR(index, ptr) \
+	(index->next_ptrs[(ptr) - index->ptr_shift])
+
+#define CNT(index, ptr) \
+	((LINE_MAP(index, ptr))->cnt)
+
+#define REC(env, s, l) \
+	(env->xdf##s.recs[l - 1])
+
+static int cmp_recs(xpparam_t const *xpp,
+	xrecord_t *r1, xrecord_t *r2)
+{
+	return r1->ha == r2->ha &&
+		xdl_recmatch(r1->ptr, r1->size, r2->ptr, r2->size,
+			    xpp->flags);
+}
+
+#define CMP_ENV(xpp, env, s1, l1, s2, l2) \
+	(cmp_recs(xpp, REC(env, s1, l1), REC(env, s2, l2)))
+
+#define CMP(i, s1, l1, s2, l2) \
+	(cmp_recs(i->xpp, REC(i->env, s1, l1), REC(i->env, s2, l2)))
+
+#define TABLE_HASH(index, side, line) \
+	XDL_HASHLONG((REC(index->env, side, line))->ha, index->table_bits)
+
+static int scanA(struct histindex *index, unsigned int line1, unsigned int count1)
+{
+	unsigned int ptr;
+	unsigned int tbl_idx;
+	unsigned int chain_len;
+	struct record **rec_chain, *rec;
+
+	for (ptr = LINE_END(1); line1 <= ptr; ptr--) {
+		tbl_idx = TABLE_HASH(index, 1, ptr);
+		rec_chain = index->records + tbl_idx;
+		rec = *rec_chain;
+
+		chain_len = 0;
+		while (rec) {
+			if (CMP(index, 1, rec->ptr, 1, ptr)) {
+				/*
+				 * ptr is identical to another element. Insert
+				 * it onto the front of the existing element
+				 * chain.
+				 */
+				NEXT_PTR(index, ptr) = rec->ptr;
+				rec->ptr = ptr;
+				/* cap rec->cnt at MAX_CNT */
+				rec->cnt = XDL_MIN(MAX_CNT, rec->cnt + 1);
+				LINE_MAP(index, ptr) = rec;
+				goto continue_scan;
+			}
+
+			rec = rec->next;
+			chain_len++;
+		}
+
+		if (chain_len == index->max_chain_length)
+			return -1;
+
+		/*
+		 * This is the first time we have ever seen this particular
+		 * element in the sequence. Construct a new chain for it.
+		 */
+		if (!(rec = xdl_cha_alloc(&index->rcha)))
+			return -1;
+		rec->ptr = ptr;
+		rec->cnt = 1;
+		rec->next = *rec_chain;
+		*rec_chain = rec;
+		LINE_MAP(index, ptr) = rec;
+
+continue_scan:
+		; /* no op */
+	}
+
+	return 0;
+}
+
+static int try_lcs(
+	struct histindex *index, struct region *lcs, unsigned int b_ptr,
+	unsigned int line1, unsigned int count1,
+	unsigned int line2, unsigned int count2)
+{
+	unsigned int b_next = b_ptr + 1;
+	struct record *rec = index->records[TABLE_HASH(index, 2, b_ptr)];
+	unsigned int as, ae, bs, be, np, rc;
+	int should_break;
+
+	for (; rec; rec = rec->next) {
+		if (rec->cnt > index->cnt) {
+			if (!index->has_common)
+				index->has_common = CMP(index, 1, rec->ptr, 2, b_ptr);
+			continue;
+		}
+
+		as = rec->ptr;
+		if (!CMP(index, 1, as, 2, b_ptr))
+			continue;
+
+		index->has_common = 1;
+		for (;;) {
+			should_break = 0;
+			np = NEXT_PTR(index, as);
+			bs = b_ptr;
+			ae = as;
+			be = bs;
+			rc = rec->cnt;
+
+			while (line1 < as && line2 < bs
+				&& CMP(index, 1, as - 1, 2, bs - 1)) {
+				as--;
+				bs--;
+				if (1 < rc)
+					rc = XDL_MIN(rc, CNT(index, as));
+			}
+			while (ae < LINE_END(1) && be < LINE_END(2)
+				&& CMP(index, 1, ae + 1, 2, be + 1)) {
+				ae++;
+				be++;
+				if (1 < rc)
+					rc = XDL_MIN(rc, CNT(index, ae));
+			}
+
+			if (b_next <= be)
+				b_next = be + 1;
+			if (lcs->end1 - lcs->begin1 < ae - as || rc < index->cnt) {
+				lcs->begin1 = as;
+				lcs->begin2 = bs;
+				lcs->end1 = ae;
+				lcs->end2 = be;
+				index->cnt = rc;
+			}
+
+			if (np == 0)
+				break;
+
+			while (np <= ae) {
+				np = NEXT_PTR(index, np);
+				if (np == 0) {
+					should_break = 1;
+					break;
+				}
+			}
+
+			if (should_break)
+				break;
+
+			as = np;
+		}
+	}
+	return b_next;
+}
+
+static int find_lcs(
+	struct histindex *index, struct region *lcs,
+	unsigned int line1, unsigned int count1,
+	unsigned int line2, unsigned int count2)
+{
+	unsigned int b_ptr;
+
+	if (scanA(index, line1, count1))
+		return -1;
+
+	index->cnt = index->max_chain_length + 1;
+
+	for (b_ptr = line2; b_ptr <= LINE_END(2); )
+		b_ptr = try_lcs(index, lcs, b_ptr, line1, count1, line2, count2);
+
+	return index->has_common && index->max_chain_length < index->cnt;
+}
+
+static int fall_back_to_classic_diff(struct histindex *index,
+		int line1, int count1, int line2, int count2)
+{
+	xpparam_t xpp;
+	xpp.flags = index->xpp->flags & ~XDF_DIFF_ALGORITHM_MASK;
+
+	return xdl_fall_back_diff(index->env, &xpp,
+				  line1, count1, line2, count2);
+}
+
+static int histogram_diff(
+	xpparam_t const *xpp, xdfenv_t *env,
+	unsigned int line1, unsigned int count1,
+	unsigned int line2, unsigned int count2)
+{
+	struct histindex index;
+	struct region lcs;
+	size_t sz;
+	int result = -1;
+
+	if (count1 <= 0 && count2 <= 0)
+		return 0;
+
+	if (LINE_END(1) >= MAX_PTR)
+		return -1;
+
+	if (!count1) {
+		while(count2--)
+			env->xdf2.rchg[line2++ - 1] = 1;
+		return 0;
+	} else if (!count2) {
+		while(count1--)
+			env->xdf1.rchg[line1++ - 1] = 1;
+		return 0;
+	}
+
+	memset(&index, 0, sizeof(index));
+
+	index.env = env;
+	index.xpp = xpp;
+
+	index.records = NULL;
+	index.line_map = NULL;
+	/* in case of early xdl_cha_free() */
+	index.rcha.head = NULL;
+
+	index.table_bits = xdl_hashbits(count1);
+	sz = index.records_size = 1 << index.table_bits;
+	GITERR_CHECK_ALLOC_MULTIPLY(&sz, sz, sizeof(struct record *));
+
+	if (!(index.records = (struct record **) xdl_malloc(sz)))
+		goto cleanup;
+	memset(index.records, 0, sz);
+
+	sz = index.line_map_size = count1;
+	sz *= sizeof(struct record *);
+	if (!(index.line_map = (struct record **) xdl_malloc(sz)))
+		goto cleanup;
+	memset(index.line_map, 0, sz);
+
+	sz = index.line_map_size;
+	sz *= sizeof(unsigned int);
+	if (!(index.next_ptrs = (unsigned int *) xdl_malloc(sz)))
+		goto cleanup;
+	memset(index.next_ptrs, 0, sz);
+
+	/* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */
+	if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0)
+		goto cleanup;
+
+	index.ptr_shift = line1;
+	index.max_chain_length = 64;
+
+	memset(&lcs, 0, sizeof(lcs));
+	if (find_lcs(&index, &lcs, line1, count1, line2, count2))
+		result = fall_back_to_classic_diff(&index, line1, count1, line2, count2);
+	else {
+		if (lcs.begin1 == 0 && lcs.begin2 == 0) {
+			while (count1--)
+				env->xdf1.rchg[line1++ - 1] = 1;
+			while (count2--)
+				env->xdf2.rchg[line2++ - 1] = 1;
+			result = 0;
+		} else {
+			result = histogram_diff(xpp, env,
+						line1, lcs.begin1 - line1,
+						line2, lcs.begin2 - line2);
+			if (result)
+				goto cleanup;
+			result = histogram_diff(xpp, env,
+						lcs.end1 + 1, LINE_END(1) - lcs.end1,
+						lcs.end2 + 1, LINE_END(2) - lcs.end2);
+			if (result)
+				goto cleanup;
+		}
+	}
+
+cleanup:
+	xdl_free(index.records);
+	xdl_free(index.line_map);
+	xdl_free(index.next_ptrs);
+	xdl_cha_free(&index.rcha);
+
+	return result;
+}
+
+int xdl_do_histogram_diff(mmfile_t *file1, mmfile_t *file2,
+	xpparam_t const *xpp, xdfenv_t *env)
+{
+	if (xdl_prepare_env(file1, file2, xpp, env) < 0)
+		return -1;
+
+	return histogram_diff(xpp, env,
+		env->xdf1.dstart + 1, env->xdf1.dend - env->xdf1.dstart + 1,
+		env->xdf2.dstart + 1, env->xdf2.dend - env->xdf2.dstart + 1);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xinclude.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xinclude.h
new file mode 100755
index 0000000..4a1cde9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xinclude.h
@@ -0,0 +1,46 @@
+/*
+ *  LibXDiff by Davide Libenzi ( File Differential Library )
+ *  Copyright (C) 2003  Davide Libenzi
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel at xmailserver.org>
+ *
+ */
+
+#if !defined(XINCLUDE_H)
+#define XINCLUDE_H
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#ifdef _WIN32
+#else
+#include <unistd.h>
+#endif
+
+#include "xmacros.h"
+#include "xdiff.h"
+#include "xtypes.h"
+#include "xutils.h"
+#include "xprepare.h"
+#include "xdiffi.h"
+#include "xemit.h"
+
+
+#endif /* #if !defined(XINCLUDE_H) */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xmacros.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xmacros.h
new file mode 100755
index 0000000..165a895
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xmacros.h
@@ -0,0 +1,54 @@
+/*
+ *  LibXDiff by Davide Libenzi ( File Differential Library )
+ *  Copyright (C) 2003  Davide Libenzi
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel at xmailserver.org>
+ *
+ */
+
+#if !defined(XMACROS_H)
+#define XMACROS_H
+
+
+
+
+#define XDL_MIN(a, b) ((a) < (b) ? (a): (b))
+#define XDL_MAX(a, b) ((a) > (b) ? (a): (b))
+#define XDL_ABS(v) ((v) >= 0 ? (v): -(v))
+#define XDL_ISDIGIT(c) ((c) >= '0' && (c) <= '9')
+#define XDL_ISSPACE(c) (isspace((unsigned char)(c)))
+#define XDL_ADDBITS(v,b)	((v) + ((v) >> (b)))
+#define XDL_MASKBITS(b)		((1UL << (b)) - 1)
+#define XDL_HASHLONG(v,b)	(XDL_ADDBITS((unsigned long)(v), b) & XDL_MASKBITS(b))
+#define XDL_PTRFREE(p) do { if (p) { xdl_free(p); (p) = NULL; } } while (0)
+#define XDL_LE32_PUT(p, v) \
+do { \
+	unsigned char *__p = (unsigned char *) (p); \
+	*__p++ = (unsigned char) (v); \
+	*__p++ = (unsigned char) ((v) >> 8); \
+	*__p++ = (unsigned char) ((v) >> 16); \
+	*__p = (unsigned char) ((v) >> 24); \
+} while (0)
+#define XDL_LE32_GET(p, v) \
+do { \
+	unsigned char const *__p = (unsigned char const *) (p); \
+	(v) = (unsigned long) __p[0] | ((unsigned long) __p[1]) << 8 | \
+		((unsigned long) __p[2]) << 16 | ((unsigned long) __p[3]) << 24; \
+} while (0)
+
+
+#endif /* #if !defined(XMACROS_H) */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xmerge.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xmerge.c
new file mode 100755
index 0000000..7b7e0e2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xmerge.c
@@ -0,0 +1,673 @@
+/*
+ *  LibXDiff by Davide Libenzi ( File Differential Library )
+ *  Copyright (C) 2003-2006 Davide Libenzi, Johannes E. Schindelin
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel at xmailserver.org>
+ *
+ */
+
+#include "xinclude.h"
+#include "common.h"
+
+typedef struct s_xdmerge {
+	struct s_xdmerge *next;
+	/*
+	 * 0 = conflict,
+	 * 1 = no conflict, take first,
+	 * 2 = no conflict, take second.
+	 * 3 = no conflict, take both.
+	 */
+	int mode;
+	/*
+	 * These point at the respective postimages.  E.g. <i1,chg1> is
+	 * how side #1 wants to change the common ancestor; if there is no
+	 * overlap, lines before i1 in the postimage of side #1 appear
+	 * in the merge result as a region touched by neither side.
+	 */
+	long i1, i2;
+	long chg1, chg2;
+	/*
+	 * These point at the preimage; of course there is just one
+	 * preimage, that is from the shared common ancestor.
+	 */
+	long i0;
+	long chg0;
+} xdmerge_t;
+
+static int xdl_append_merge(xdmerge_t **merge, int mode,
+			    long i0, long chg0,
+			    long i1, long chg1,
+			    long i2, long chg2)
+{
+	xdmerge_t *m = *merge;
+	if (m && (i1 <= m->i1 + m->chg1 || i2 <= m->i2 + m->chg2)) {
+		if (mode != m->mode)
+			m->mode = 0;
+		m->chg0 = i0 + chg0 - m->i0;
+		m->chg1 = i1 + chg1 - m->i1;
+		m->chg2 = i2 + chg2 - m->i2;
+	} else {
+		m = xdl_malloc(sizeof(xdmerge_t));
+		if (!m)
+			return -1;
+		m->next = NULL;
+		m->mode = mode;
+		m->i0 = i0;
+		m->chg0 = chg0;
+		m->i1 = i1;
+		m->chg1 = chg1;
+		m->i2 = i2;
+		m->chg2 = chg2;
+		if (*merge)
+			(*merge)->next = m;
+		*merge = m;
+	}
+	return 0;
+}
+
+static int xdl_cleanup_merge(xdmerge_t *c)
+{
+	int count = 0;
+	xdmerge_t *next_c;
+
+	/* were there conflicts? */
+	for (; c; c = next_c) {
+		if (c->mode == 0)
+			count++;
+		next_c = c->next;
+		free(c);
+	}
+	return count;
+}
+
+static int xdl_merge_cmp_lines(xdfenv_t *xe1, int i1, xdfenv_t *xe2, int i2,
+		int line_count, long flags)
+{
+	int i;
+	xrecord_t **rec1 = xe1->xdf2.recs + i1;
+	xrecord_t **rec2 = xe2->xdf2.recs + i2;
+
+	for (i = 0; i < line_count; i++) {
+		int result = xdl_recmatch(rec1[i]->ptr, rec1[i]->size,
+			rec2[i]->ptr, rec2[i]->size, flags);
+		if (!result)
+			return -1;
+	}
+	return 0;
+}
+
+static int xdl_recs_copy_0(size_t *out, int use_orig, xdfenv_t *xe, int i, int count, int add_nl, char *dest)
+{
+	xrecord_t **recs;
+	size_t size = 0;
+
+	*out = 0;
+
+	recs = (use_orig ? xe->xdf1.recs : xe->xdf2.recs) + i;
+
+	if (count < 1)
+		return 0;
+
+	for (i = 0; i < count; ) {
+		if (dest)
+			memcpy(dest + size, recs[i]->ptr, recs[i]->size);
+
+		GITERR_CHECK_ALLOC_ADD(&size, size, recs[i++]->size);
+	}
+
+	if (add_nl) {
+		i = recs[count - 1]->size;
+		if (i == 0 || recs[count - 1]->ptr[i - 1] != '\n') {
+			if (dest)
+				dest[size] = '\n';
+
+			GITERR_CHECK_ALLOC_ADD(&size, size, 1);
+		}
+	}
+
+	*out = size;
+	return 0;
+}
+
+static int xdl_recs_copy(size_t *out, xdfenv_t *xe, int i, int count, int add_nl, char *dest)
+{
+	return xdl_recs_copy_0(out, 0, xe, i, count, add_nl, dest);
+}
+
+static int xdl_orig_copy(size_t *out, xdfenv_t *xe, int i, int count, int add_nl, char *dest)
+{
+	return xdl_recs_copy_0(out, 1, xe, i, count, add_nl, dest);
+}
+
+static int fill_conflict_hunk(size_t *out, xdfenv_t *xe1, const char *name1,
+			      xdfenv_t *xe2, const char *name2,
+			      const char *name3,
+			      size_t size, int i, int style,
+			      xdmerge_t *m, char *dest, int marker_size)
+{
+	int marker1_size = (name1 ? (int)strlen(name1) + 1 : 0);
+	int marker2_size = (name2 ? (int)strlen(name2) + 1 : 0);
+	int marker3_size = (name3 ? (int)strlen(name3) + 1 : 0);
+	size_t copied;
+
+	*out = 0;
+
+	if (marker_size <= 0)
+		marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
+
+	/* Before conflicting part */
+	if (xdl_recs_copy(&copied, xe1, i, m->i1 - i, 0,
+			      dest ? dest + size : NULL) < 0)
+		return -1;
+
+	GITERR_CHECK_ALLOC_ADD(&size, size, copied);
+
+	if (!dest) {
+		GITERR_CHECK_ALLOC_ADD4(&size, size, marker_size, 1, marker1_size);
+	} else {
+		memset(dest + size, '<', marker_size);
+		size += marker_size;
+		if (marker1_size) {
+			dest[size] = ' ';
+			memcpy(dest + size + 1, name1, marker1_size - 1);
+			size += marker1_size;
+		}
+		dest[size++] = '\n';
+	}
+
+	/* Postimage from side #1 */
+	if (xdl_recs_copy(&copied, xe1, m->i1, m->chg1, 1,
+			      dest ? dest + size : NULL) < 0)
+		return -1;
+
+	GITERR_CHECK_ALLOC_ADD(&size, size, copied);
+
+	if (style == XDL_MERGE_DIFF3) {
+		/* Shared preimage */
+		if (!dest) {
+			GITERR_CHECK_ALLOC_ADD4(&size, size, marker_size, 1, marker3_size);
+		} else {
+			memset(dest + size, '|', marker_size);
+			size += marker_size;
+			if (marker3_size) {
+				dest[size] = ' ';
+				memcpy(dest + size + 1, name3, marker3_size - 1);
+				size += marker3_size;
+			}
+			dest[size++] = '\n';
+		}
+
+		if (xdl_orig_copy(&copied, xe1, m->i0, m->chg0, 1,
+				      dest ? dest + size : NULL) < 0)
+			return -1;
+		GITERR_CHECK_ALLOC_ADD(&size, size, copied);
+	}
+
+	if (!dest) {
+		GITERR_CHECK_ALLOC_ADD3(&size, size, marker_size, 1);
+	} else {
+		memset(dest + size, '=', marker_size);
+		size += marker_size;
+		dest[size++] = '\n';
+	}
+
+	/* Postimage from side #2 */
+
+	if (xdl_recs_copy(&copied, xe2, m->i2, m->chg2, 1,
+			      dest ? dest + size : NULL) < 0)
+		return -1;
+	GITERR_CHECK_ALLOC_ADD(&size, size, copied);
+
+	if (!dest) {
+		GITERR_CHECK_ALLOC_ADD4(&size, size, marker_size, 1, marker2_size);
+	} else {
+		memset(dest + size, '>', marker_size);
+		size += marker_size;
+		if (marker2_size) {
+			dest[size] = ' ';
+			memcpy(dest + size + 1, name2, marker2_size - 1);
+			size += marker2_size;
+		}
+		dest[size++] = '\n';
+	}
+
+	*out = size;
+	return 0;
+}
+
+static int xdl_fill_merge_buffer(size_t *out,
+				 xdfenv_t *xe1, const char *name1,
+				 xdfenv_t *xe2, const char *name2,
+				 const char *ancestor_name,
+				 int favor,
+				 xdmerge_t *m, char *dest, int style,
+				 int marker_size)
+{
+	size_t size, copied;
+	int i;
+
+	*out = 0;
+
+	for (size = i = 0; m; m = m->next) {
+		if (favor && !m->mode)
+			m->mode = favor;
+
+		if (m->mode == 0) {
+			if (fill_conflict_hunk(&size, xe1, name1, xe2, name2,
+						  ancestor_name,
+						  size, i, style, m, dest,
+						  marker_size) < 0)
+				return -1;
+		}
+		else if (m->mode & 3) {
+			/* Before conflicting part */
+			if (xdl_recs_copy(&copied, xe1, i, m->i1 - i, 0,
+					      dest ? dest + size : NULL) < 0)
+				return -1;
+			GITERR_CHECK_ALLOC_ADD(&size, size, copied);
+
+			/* Postimage from side #1 */
+			if (m->mode & 1) {
+				if (xdl_recs_copy(&copied, xe1, m->i1, m->chg1, (m->mode & 2),
+						      dest ? dest + size : NULL) < 0)
+					return -1;
+				GITERR_CHECK_ALLOC_ADD(&size, size, copied);
+			}
+
+			/* Postimage from side #2 */
+			if (m->mode & 2) {
+				if (xdl_recs_copy(&copied, xe2, m->i2, m->chg2, 0,
+						      dest ? dest + size : NULL) < 0)
+					return -1;
+				GITERR_CHECK_ALLOC_ADD(&size, size, copied);
+			}
+		} else
+			continue;
+		i = m->i1 + m->chg1;
+	}
+
+	if (xdl_recs_copy(&copied, xe1, i, xe1->xdf2.nrec - i, 0,
+			      dest ? dest + size : NULL) < 0)
+		return -1;
+	GITERR_CHECK_ALLOC_ADD(&size, size, copied);
+
+	*out = size;
+	return 0;
+}
+
+/*
+ * Sometimes, changes are not quite identical, but differ in only a few
+ * lines. Try hard to show only these few lines as conflicting.
+ */
+static int xdl_refine_conflicts(xdfenv_t *xe1, xdfenv_t *xe2, xdmerge_t *m,
+		xpparam_t const *xpp)
+{
+	for (; m; m = m->next) {
+		mmfile_t t1, t2;
+		xdfenv_t xe;
+		xdchange_t *xscr, *x;
+		int i1 = m->i1, i2 = m->i2;
+
+		/* let's handle just the conflicts */
+		if (m->mode)
+			continue;
+
+		/* no sense refining a conflict when one side is empty */
+		if (m->chg1 == 0 || m->chg2 == 0)
+			continue;
+
+		/*
+		 * This probably does not work outside git, since
+		 * we have a very simple mmfile structure.
+		 */
+		t1.ptr = (char *)xe1->xdf2.recs[m->i1]->ptr;
+		t1.size = xe1->xdf2.recs[m->i1 + m->chg1 - 1]->ptr
+			+ xe1->xdf2.recs[m->i1 + m->chg1 - 1]->size - t1.ptr;
+		t2.ptr = (char *)xe2->xdf2.recs[m->i2]->ptr;
+		t2.size = xe2->xdf2.recs[m->i2 + m->chg2 - 1]->ptr
+			+ xe2->xdf2.recs[m->i2 + m->chg2 - 1]->size - t2.ptr;
+		if (xdl_do_diff(&t1, &t2, xpp, &xe) < 0)
+			return -1;
+		if (xdl_change_compact(&xe.xdf1, &xe.xdf2, xpp->flags) < 0 ||
+		    xdl_change_compact(&xe.xdf2, &xe.xdf1, xpp->flags) < 0 ||
+		    xdl_build_script(&xe, &xscr) < 0) {
+			xdl_free_env(&xe);
+			return -1;
+		}
+		if (!xscr) {
+			/* If this happens, the changes are identical. */
+			xdl_free_env(&xe);
+			m->mode = 4;
+			continue;
+		}
+		x = xscr;
+		m->i1 = xscr->i1 + i1;
+		m->chg1 = xscr->chg1;
+		m->i2 = xscr->i2 + i2;
+		m->chg2 = xscr->chg2;
+		while (xscr->next) {
+			xdmerge_t *m2 = xdl_malloc(sizeof(xdmerge_t));
+			if (!m2) {
+				xdl_free_env(&xe);
+				xdl_free_script(x);
+				return -1;
+			}
+			xscr = xscr->next;
+			m2->next = m->next;
+			m->next = m2;
+			m = m2;
+			m->mode = 0;
+			m->i1 = xscr->i1 + i1;
+			m->chg1 = xscr->chg1;
+			m->i2 = xscr->i2 + i2;
+			m->chg2 = xscr->chg2;
+		}
+		xdl_free_env(&xe);
+		xdl_free_script(x);
+	}
+	return 0;
+}
+
+static int line_contains_alnum(const char *ptr, long size)
+{
+	while (size--)
+		if (isalnum((unsigned char)*(ptr++)))
+			return 1;
+	return 0;
+}
+
+static int lines_contain_alnum(xdfenv_t *xe, int i, int chg)
+{
+	for (; chg; chg--, i++)
+		if (line_contains_alnum(xe->xdf2.recs[i]->ptr,
+				xe->xdf2.recs[i]->size))
+			return 1;
+	return 0;
+}
+
+/*
+ * This function merges m and m->next, marking everything between those hunks
+ * as conflicting, too.
+ */
+static void xdl_merge_two_conflicts(xdmerge_t *m)
+{
+	xdmerge_t *next_m = m->next;
+	m->chg1 = next_m->i1 + next_m->chg1 - m->i1;
+	m->chg2 = next_m->i2 + next_m->chg2 - m->i2;
+	m->next = next_m->next;
+	free(next_m);
+}
+
+/*
+ * If there are less than 3 non-conflicting lines between conflicts,
+ * it appears simpler -- because it takes up less (or as many) lines --
+ * if the lines are moved into the conflicts.
+ */
+static int xdl_simplify_non_conflicts(xdfenv_t *xe1, xdmerge_t *m,
+				      int simplify_if_no_alnum)
+{
+	int result = 0;
+
+	if (!m)
+		return result;
+	for (;;) {
+		xdmerge_t *next_m = m->next;
+		int begin, end;
+
+		if (!next_m)
+			return result;
+
+		begin = m->i1 + m->chg1;
+		end = next_m->i1;
+
+		if (m->mode != 0 || next_m->mode != 0 ||
+		    (end - begin > 3 &&
+		     (!simplify_if_no_alnum ||
+		      lines_contain_alnum(xe1, begin, end - begin)))) {
+			m = next_m;
+		} else {
+			result++;
+			xdl_merge_two_conflicts(m);
+		}
+	}
+}
+
+/*
+ * level == 0: mark all overlapping changes as conflict
+ * level == 1: mark overlapping changes as conflict only if not identical
+ * level == 2: analyze non-identical changes for minimal conflict set
+ * level == 3: analyze non-identical changes for minimal conflict set, but
+ *             treat hunks not containing any letter or number as conflicting
+ *
+ * returns < 0 on error, == 0 for no conflicts, else number of conflicts
+ */
+static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1,
+		xdfenv_t *xe2, xdchange_t *xscr2,
+		xmparam_t const *xmp, mmbuffer_t *result)
+{
+	xdmerge_t *changes, *c;
+	xpparam_t const *xpp = &xmp->xpp;
+	const char *const ancestor_name = xmp->ancestor;
+	const char *const name1 = xmp->file1;
+	const char *const name2 = xmp->file2;
+	int i0, i1, i2, chg0, chg1, chg2;
+	int level = xmp->level;
+	int style = xmp->style;
+	int favor = xmp->favor;
+
+	if (style == XDL_MERGE_DIFF3) {
+		/*
+		 * "diff3 -m" output does not make sense for anything
+		 * more aggressive than XDL_MERGE_EAGER.
+		 */
+		if (XDL_MERGE_EAGER < level)
+			level = XDL_MERGE_EAGER;
+	}
+
+	c = changes = NULL;
+
+	while (xscr1 && xscr2) {
+		if (!changes)
+			changes = c;
+		if (xscr1->i1 + xscr1->chg1 < xscr2->i1) {
+			i0 = xscr1->i1;
+			i1 = xscr1->i2;
+			i2 = xscr2->i2 - xscr2->i1 + xscr1->i1;
+			chg0 = xscr1->chg1;
+			chg1 = xscr1->chg2;
+			chg2 = xscr1->chg1;
+			if (xdl_append_merge(&c, 1,
+					     i0, chg0, i1, chg1, i2, chg2)) {
+				xdl_cleanup_merge(changes);
+				return -1;
+			}
+			xscr1 = xscr1->next;
+			continue;
+		}
+		if (xscr2->i1 + xscr2->chg1 < xscr1->i1) {
+			i0 = xscr2->i1;
+			i1 = xscr1->i2 - xscr1->i1 + xscr2->i1;
+			i2 = xscr2->i2;
+			chg0 = xscr2->chg1;
+			chg1 = xscr2->chg1;
+			chg2 = xscr2->chg2;
+			if (xdl_append_merge(&c, 2,
+					     i0, chg0, i1, chg1, i2, chg2)) {
+				xdl_cleanup_merge(changes);
+				return -1;
+			}
+			xscr2 = xscr2->next;
+			continue;
+		}
+		if (level == XDL_MERGE_MINIMAL || xscr1->i1 != xscr2->i1 ||
+				xscr1->chg1 != xscr2->chg1 ||
+				xscr1->chg2 != xscr2->chg2 ||
+				xdl_merge_cmp_lines(xe1, xscr1->i2,
+					xe2, xscr2->i2,
+					xscr1->chg2, xpp->flags)) {
+			/* conflict */
+			int off = xscr1->i1 - xscr2->i1;
+			int ffo = off + xscr1->chg1 - xscr2->chg1;
+
+			i0 = xscr1->i1;
+			i1 = xscr1->i2;
+			i2 = xscr2->i2;
+			if (off > 0) {
+				i0 -= off;
+				i1 -= off;
+			}
+			else
+				i2 += off;
+			chg0 = xscr1->i1 + xscr1->chg1 - i0;
+			chg1 = xscr1->i2 + xscr1->chg2 - i1;
+			chg2 = xscr2->i2 + xscr2->chg2 - i2;
+			if (ffo < 0) {
+				chg0 -= ffo;
+				chg1 -= ffo;
+			} else
+				chg2 += ffo;
+			if (xdl_append_merge(&c, 0,
+					     i0, chg0, i1, chg1, i2, chg2)) {
+				xdl_cleanup_merge(changes);
+				return -1;
+			}
+		}
+
+		i1 = xscr1->i1 + xscr1->chg1;
+		i2 = xscr2->i1 + xscr2->chg1;
+
+		if (i1 >= i2)
+			xscr2 = xscr2->next;
+		if (i2 >= i1)
+			xscr1 = xscr1->next;
+	}
+	while (xscr1) {
+		if (!changes)
+			changes = c;
+		i0 = xscr1->i1;
+		i1 = xscr1->i2;
+		i2 = xscr1->i1 + xe2->xdf2.nrec - xe2->xdf1.nrec;
+		chg0 = xscr1->chg1;
+		chg1 = xscr1->chg2;
+		chg2 = xscr1->chg1;
+		if (xdl_append_merge(&c, 1,
+				     i0, chg0, i1, chg1, i2, chg2)) {
+			xdl_cleanup_merge(changes);
+			return -1;
+		}
+		xscr1 = xscr1->next;
+	}
+	while (xscr2) {
+		if (!changes)
+			changes = c;
+		i0 = xscr2->i1;
+		i1 = xscr2->i1 + xe1->xdf2.nrec - xe1->xdf1.nrec;
+		i2 = xscr2->i2;
+		chg0 = xscr2->chg1;
+		chg1 = xscr2->chg1;
+		chg2 = xscr2->chg2;
+		if (xdl_append_merge(&c, 2,
+				     i0, chg0, i1, chg1, i2, chg2)) {
+			xdl_cleanup_merge(changes);
+			return -1;
+		}
+		xscr2 = xscr2->next;
+	}
+	if (!changes)
+		changes = c;
+	/* refine conflicts */
+	if (XDL_MERGE_ZEALOUS <= level &&
+	    (xdl_refine_conflicts(xe1, xe2, changes, xpp) < 0 ||
+	     xdl_simplify_non_conflicts(xe1, changes,
+					XDL_MERGE_ZEALOUS < level) < 0)) {
+		xdl_cleanup_merge(changes);
+		return -1;
+	}
+	/* output */
+	if (result) {
+		int marker_size = xmp->marker_size;
+		size_t size;
+
+		if (xdl_fill_merge_buffer(&size, xe1, name1, xe2, name2,
+						 ancestor_name,
+						 favor, changes, NULL, style,
+						 marker_size) < 0)
+			return -1;
+
+		result->ptr = xdl_malloc(size);
+		if (!result->ptr) {
+			xdl_cleanup_merge(changes);
+			return -1;
+		}
+		result->size = size;
+		if (xdl_fill_merge_buffer(&size, xe1, name1, xe2, name2,
+				      ancestor_name, favor, changes,
+				      result->ptr, style, marker_size) < 0)
+			return -1;
+	}
+	return xdl_cleanup_merge(changes);
+}
+
+int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2,
+		xmparam_t const *xmp, mmbuffer_t *result)
+{
+	xdchange_t *xscr1, *xscr2;
+	xdfenv_t xe1, xe2;
+	int status;
+	xpparam_t const *xpp = &xmp->xpp;
+
+	result->ptr = NULL;
+	result->size = 0;
+
+	if (xdl_do_diff(orig, mf1, xpp, &xe1) < 0 ||
+			xdl_do_diff(orig, mf2, xpp, &xe2) < 0) {
+		return -1;
+	}
+	if (xdl_change_compact(&xe1.xdf1, &xe1.xdf2, xpp->flags) < 0 ||
+	    xdl_change_compact(&xe1.xdf2, &xe1.xdf1, xpp->flags) < 0 ||
+	    xdl_build_script(&xe1, &xscr1) < 0) {
+		xdl_free_env(&xe1);
+		return -1;
+	}
+	if (xdl_change_compact(&xe2.xdf1, &xe2.xdf2, xpp->flags) < 0 ||
+	    xdl_change_compact(&xe2.xdf2, &xe2.xdf1, xpp->flags) < 0 ||
+	    xdl_build_script(&xe2, &xscr2) < 0) {
+		xdl_free_env(&xe2);
+		return -1;
+	}
+	status = 0;
+	if (!xscr1) {
+		result->ptr = xdl_malloc(mf2->size);
+		memcpy(result->ptr, mf2->ptr, mf2->size);
+		result->size = mf2->size;
+	} else if (!xscr2) {
+		result->ptr = xdl_malloc(mf1->size);
+		memcpy(result->ptr, mf1->ptr, mf1->size);
+		result->size = mf1->size;
+	} else {
+		status = xdl_do_merge(&xe1, xscr1,
+				      &xe2, xscr2,
+				      xmp, result);
+	}
+	xdl_free_script(xscr1);
+	xdl_free_script(xscr2);
+
+	xdl_free_env(&xe1);
+	xdl_free_env(&xe2);
+
+	return status;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xpatience.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xpatience.c
new file mode 100755
index 0000000..04e1a1a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xpatience.c
@@ -0,0 +1,358 @@
+/*
+ *  LibXDiff by Davide Libenzi ( File Differential Library )
+ *  Copyright (C) 2003-2009 Davide Libenzi, Johannes E. Schindelin
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel at xmailserver.org>
+ *
+ */
+#include "xinclude.h"
+#include "xtypes.h"
+#include "xdiff.h"
+
+/*
+ * The basic idea of patience diff is to find lines that are unique in
+ * both files.  These are intuitively the ones that we want to see as
+ * common lines.
+ *
+ * The maximal ordered sequence of such line pairs (where ordered means
+ * that the order in the sequence agrees with the order of the lines in
+ * both files) naturally defines an initial set of common lines.
+ *
+ * Now, the algorithm tries to extend the set of common lines by growing
+ * the line ranges where the files have identical lines.
+ *
+ * Between those common lines, the patience diff algorithm is applied
+ * recursively, until no unique line pairs can be found; these line ranges
+ * are handled by the well-known Myers algorithm.
+ */
+
+#define NON_UNIQUE ULONG_MAX
+
+/*
+ * This is a hash mapping from line hash to line numbers in the first and
+ * second file.
+ */
+struct hashmap {
+	int nr, alloc;
+	struct entry {
+		unsigned long hash;
+		/*
+		 * 0 = unused entry, 1 = first line, 2 = second, etc.
+		 * line2 is NON_UNIQUE if the line is not unique
+		 * in either the first or the second file.
+		 */
+		unsigned long line1, line2;
+		/*
+		 * "next" & "previous" are used for the longest common
+		 * sequence;
+		 * initially, "next" reflects only the order in file1.
+		 */
+		struct entry *next, *previous;
+	} *entries, *first, *last;
+	/* were common records found? */
+	unsigned long has_matches;
+	mmfile_t *file1, *file2;
+	xdfenv_t *env;
+	xpparam_t const *xpp;
+};
+
+/* The argument "pass" is 1 for the first file, 2 for the second. */
+static void insert_record(int line, struct hashmap *map, int pass)
+{
+	xrecord_t **records = pass == 1 ?
+		map->env->xdf1.recs : map->env->xdf2.recs;
+	xrecord_t *record = records[line - 1], *other;
+	/*
+	 * After xdl_prepare_env() (or more precisely, due to
+	 * xdl_classify_record()), the "ha" member of the records (AKA lines)
+	 * is _not_ the hash anymore, but a linearized version of it.  In
+	 * other words, the "ha" member is guaranteed to start with 0 and
+	 * the second record's ha can only be 0 or 1, etc.
+	 *
+	 * So we multiply ha by 2 in the hope that the hashing was
+	 * "unique enough".
+	 */
+	int index = (int)((record->ha << 1) % map->alloc);
+
+	while (map->entries[index].line1) {
+		other = map->env->xdf1.recs[map->entries[index].line1 - 1];
+		if (map->entries[index].hash != record->ha ||
+				!xdl_recmatch(record->ptr, record->size,
+					other->ptr, other->size,
+					map->xpp->flags)) {
+			if (++index >= map->alloc)
+				index = 0;
+			continue;
+		}
+		if (pass == 2)
+			map->has_matches = 1;
+		if (pass == 1 || map->entries[index].line2)
+			map->entries[index].line2 = NON_UNIQUE;
+		else
+			map->entries[index].line2 = line;
+		return;
+	}
+	if (pass == 2)
+		return;
+	map->entries[index].line1 = line;
+	map->entries[index].hash = record->ha;
+	if (!map->first)
+		map->first = map->entries + index;
+	if (map->last) {
+		map->last->next = map->entries + index;
+		map->entries[index].previous = map->last;
+	}
+	map->last = map->entries + index;
+	map->nr++;
+}
+
+/*
+ * This function has to be called for each recursion into the inter-hunk
+ * parts, as previously non-unique lines can become unique when being
+ * restricted to a smaller part of the files.
+ *
+ * It is assumed that env has been prepared using xdl_prepare().
+ */
+static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
+		xpparam_t const *xpp, xdfenv_t *env,
+		struct hashmap *result,
+		int line1, int count1, int line2, int count2)
+{
+	result->file1 = file1;
+	result->file2 = file2;
+	result->xpp = xpp;
+	result->env = env;
+
+	/* We know exactly how large we want the hash map */
+	result->alloc = count1 * 2;
+	result->entries = (struct entry *)
+		xdl_malloc(result->alloc * sizeof(struct entry));
+	if (!result->entries)
+		return -1;
+	memset(result->entries, 0, result->alloc * sizeof(struct entry));
+
+	/* First, fill with entries from the first file */
+	while (count1--)
+		insert_record(line1++, result, 1);
+
+	/* Then search for matches in the second file */
+	while (count2--)
+		insert_record(line2++, result, 2);
+
+	return 0;
+}
+
+/*
+ * Find the longest sequence with a smaller last element (meaning a smaller
+ * line2, as we construct the sequence with entries ordered by line1).
+ */
+static int binary_search(struct entry **sequence, int longest,
+		struct entry *entry)
+{
+	int left = -1, right = longest;
+
+	while (left + 1 < right) {
+		int middle = (left + right) / 2;
+		/* by construction, no two entries can be equal */
+		if (sequence[middle]->line2 > entry->line2)
+			right = middle;
+		else
+			left = middle;
+	}
+	/* return the index in "sequence", _not_ the sequence length */
+	return left;
+}
+
+/*
+ * The idea is to start with the list of common unique lines sorted by
+ * the order in file1.  For each of these pairs, the longest (partial)
+ * sequence whose last element's line2 is smaller is determined.
+ *
+ * For efficiency, the sequences are kept in a list containing exactly one
+ * item per sequence length: the sequence with the smallest last
+ * element (in terms of line2).
+ */
+static struct entry *find_longest_common_sequence(struct hashmap *map)
+{
+	struct entry **sequence = xdl_malloc(map->nr * sizeof(struct entry *));
+	int longest = 0, i;
+	struct entry *entry;
+
+	for (entry = map->first; entry; entry = entry->next) {
+		if (!entry->line2 || entry->line2 == NON_UNIQUE)
+			continue;
+		i = binary_search(sequence, longest, entry);
+		entry->previous = i < 0 ? NULL : sequence[i];
+		sequence[++i] = entry;
+		if (i == longest)
+			longest++;
+	}
+
+	/* No common unique lines were found */
+	if (!longest) {
+		xdl_free(sequence);
+		return NULL;
+	}
+
+	/* Iterate starting at the last element, adjusting the "next" members */
+	entry = sequence[longest - 1];
+	entry->next = NULL;
+	while (entry->previous) {
+		entry->previous->next = entry;
+		entry = entry->previous;
+	}
+	xdl_free(sequence);
+	return entry;
+}
+
+static int match(struct hashmap *map, int line1, int line2)
+{
+	xrecord_t *record1 = map->env->xdf1.recs[line1 - 1];
+	xrecord_t *record2 = map->env->xdf2.recs[line2 - 1];
+	return xdl_recmatch(record1->ptr, record1->size,
+		record2->ptr, record2->size, map->xpp->flags);
+}
+
+static int patience_diff(mmfile_t *file1, mmfile_t *file2,
+		xpparam_t const *xpp, xdfenv_t *env,
+		int line1, int count1, int line2, int count2);
+
+static int walk_common_sequence(struct hashmap *map, struct entry *first,
+		int line1, int count1, int line2, int count2)
+{
+	int end1 = line1 + count1, end2 = line2 + count2;
+	int next1, next2;
+
+	for (;;) {
+		/* Try to grow the line ranges of common lines */
+		if (first) {
+			next1 = first->line1;
+			next2 = first->line2;
+			while (next1 > line1 && next2 > line2 &&
+					match(map, next1 - 1, next2 - 1)) {
+				next1--;
+				next2--;
+			}
+		} else {
+			next1 = end1;
+			next2 = end2;
+		}
+		while (line1 < next1 && line2 < next2 &&
+				match(map, line1, line2)) {
+			line1++;
+			line2++;
+		}
+
+		/* Recurse */
+		if (next1 > line1 || next2 > line2) {
+			struct hashmap submap;
+
+			memset(&submap, 0, sizeof(submap));
+			if (patience_diff(map->file1, map->file2,
+					map->xpp, map->env,
+					line1, next1 - line1,
+					line2, next2 - line2))
+				return -1;
+		}
+
+		if (!first)
+			return 0;
+
+		while (first->next &&
+				first->next->line1 == first->line1 + 1 &&
+				first->next->line2 == first->line2 + 1)
+			first = first->next;
+
+		line1 = first->line1 + 1;
+		line2 = first->line2 + 1;
+
+		first = first->next;
+	}
+}
+
+static int fall_back_to_classic_diff(struct hashmap *map,
+		int line1, int count1, int line2, int count2)
+{
+	xpparam_t xpp;
+	xpp.flags = map->xpp->flags & ~XDF_DIFF_ALGORITHM_MASK;
+
+	return xdl_fall_back_diff(map->env, &xpp,
+				  line1, count1, line2, count2);
+}
+
+/*
+ * Recursively find the longest common sequence of unique lines,
+ * and if none was found, ask xdl_do_diff() to do the job.
+ *
+ * This function assumes that env was prepared with xdl_prepare_env().
+ */
+static int patience_diff(mmfile_t *file1, mmfile_t *file2,
+		xpparam_t const *xpp, xdfenv_t *env,
+		int line1, int count1, int line2, int count2)
+{
+	struct hashmap map;
+	struct entry *first;
+	int result = 0;
+
+	/* trivial case: one side is empty */
+	if (!count1) {
+		while(count2--)
+			env->xdf2.rchg[line2++ - 1] = 1;
+		return 0;
+	} else if (!count2) {
+		while(count1--)
+			env->xdf1.rchg[line1++ - 1] = 1;
+		return 0;
+	}
+
+	memset(&map, 0, sizeof(map));
+	if (fill_hashmap(file1, file2, xpp, env, &map,
+			line1, count1, line2, count2))
+		return -1;
+
+	/* are there any matching lines at all? */
+	if (!map.has_matches) {
+		while(count1--)
+			env->xdf1.rchg[line1++ - 1] = 1;
+		while(count2--)
+			env->xdf2.rchg[line2++ - 1] = 1;
+		xdl_free(map.entries);
+		return 0;
+	}
+
+	first = find_longest_common_sequence(&map);
+	if (first)
+		result = walk_common_sequence(&map, first,
+			line1, count1, line2, count2);
+	else
+		result = fall_back_to_classic_diff(&map,
+			line1, count1, line2, count2);
+
+	xdl_free(map.entries);
+	return result;
+}
+
+int xdl_do_patience_diff(mmfile_t *file1, mmfile_t *file2,
+		xpparam_t const *xpp, xdfenv_t *env)
+{
+	if (xdl_prepare_env(file1, file2, xpp, env) < 0)
+		return -1;
+
+	/* environment is cleaned up in xdl_diff() */
+	return patience_diff(file1, file2, xpp, env,
+			1, env->xdf1.nrec, 1, env->xdf2.nrec);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xprepare.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xprepare.c
new file mode 100755
index 0000000..63a22c6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xprepare.c
@@ -0,0 +1,482 @@
+/*
+ *  LibXDiff by Davide Libenzi ( File Differential Library )
+ *  Copyright (C) 2003  Davide Libenzi
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel at xmailserver.org>
+ *
+ */
+
+#include "xinclude.h"
+
+
+#define XDL_KPDIS_RUN 4
+#define XDL_MAX_EQLIMIT 1024
+#define XDL_SIMSCAN_WINDOW 100
+#define XDL_GUESS_NLINES1 256
+#define XDL_GUESS_NLINES2 20
+
+
+typedef struct s_xdlclass {
+	struct s_xdlclass *next;
+	unsigned long ha;
+	char const *line;
+	long size;
+	long idx;
+	long len1, len2;
+} xdlclass_t;
+
+typedef struct s_xdlclassifier {
+	unsigned int hbits;
+	long hsize;
+	xdlclass_t **rchash;
+	chastore_t ncha;
+	xdlclass_t **rcrecs;
+	long alloc;
+	long count;
+	long flags;
+} xdlclassifier_t;
+
+
+
+
+static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags);
+static void xdl_free_classifier(xdlclassifier_t *cf);
+static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t **rhash,
+			       unsigned int hbits, xrecord_t *rec);
+static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_t const *xpp,
+			   xdlclassifier_t *cf, xdfile_t *xdf);
+static void xdl_free_ctx(xdfile_t *xdf);
+static int xdl_clean_mmatch(char const *dis, long i, long s, long e);
+static int xdl_cleanup_records(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2);
+static int xdl_trim_ends(xdfile_t *xdf1, xdfile_t *xdf2);
+static int xdl_optimize_ctxs(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2);
+
+
+
+
+static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {
+	cf->flags = flags;
+
+	cf->hbits = xdl_hashbits((unsigned int) size);
+	cf->hsize = 1 << cf->hbits;
+
+	if (xdl_cha_init(&cf->ncha, sizeof(xdlclass_t), size / 4 + 1) < 0) {
+
+		return -1;
+	}
+	if (!(cf->rchash = (xdlclass_t **) xdl_malloc(cf->hsize * sizeof(xdlclass_t *)))) {
+
+		xdl_cha_free(&cf->ncha);
+		return -1;
+	}
+	memset(cf->rchash, 0, cf->hsize * sizeof(xdlclass_t *));
+
+	cf->alloc = size;
+	if (!(cf->rcrecs = (xdlclass_t **) xdl_malloc(cf->alloc * sizeof(xdlclass_t *)))) {
+
+		xdl_free(cf->rchash);
+		xdl_cha_free(&cf->ncha);
+		return -1;
+	}
+
+	cf->count = 0;
+
+	return 0;
+}
+
+
+static void xdl_free_classifier(xdlclassifier_t *cf) {
+
+	xdl_free(cf->rcrecs);
+	xdl_free(cf->rchash);
+	xdl_cha_free(&cf->ncha);
+}
+
+
+static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t **rhash,
+			       unsigned int hbits, xrecord_t *rec) {
+	long hi;
+	char const *line;
+	xdlclass_t *rcrec;
+	xdlclass_t **rcrecs;
+
+	line = rec->ptr;
+	hi = (long) XDL_HASHLONG(rec->ha, cf->hbits);
+	for (rcrec = cf->rchash[hi]; rcrec; rcrec = rcrec->next)
+		if (rcrec->ha == rec->ha &&
+				xdl_recmatch(rcrec->line, rcrec->size,
+					rec->ptr, rec->size, cf->flags))
+			break;
+
+	if (!rcrec) {
+		if (!(rcrec = xdl_cha_alloc(&cf->ncha))) {
+
+			return -1;
+		}
+		rcrec->idx = cf->count++;
+		if (cf->count > cf->alloc) {
+			cf->alloc *= 2;
+			if (!(rcrecs = (xdlclass_t **) xdl_realloc(cf->rcrecs, cf->alloc * sizeof(xdlclass_t *)))) {
+
+				return -1;
+			}
+			cf->rcrecs = rcrecs;
+		}
+		cf->rcrecs[rcrec->idx] = rcrec;
+		rcrec->line = line;
+		rcrec->size = rec->size;
+		rcrec->ha = rec->ha;
+		rcrec->len1 = rcrec->len2 = 0;
+		rcrec->next = cf->rchash[hi];
+		cf->rchash[hi] = rcrec;
+	}
+
+	(pass == 1) ? rcrec->len1++ : rcrec->len2++;
+
+	rec->ha = (unsigned long) rcrec->idx;
+
+	hi = (long) XDL_HASHLONG(rec->ha, hbits);
+	rec->next = rhash[hi];
+	rhash[hi] = rec;
+
+	return 0;
+}
+
+
+static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_t const *xpp,
+			   xdlclassifier_t *cf, xdfile_t *xdf) {
+	unsigned int hbits;
+	long nrec, hsize, bsize;
+	unsigned long hav;
+	char const *blk, *cur, *top, *prev;
+	xrecord_t *crec;
+	xrecord_t **recs, **rrecs;
+	xrecord_t **rhash;
+	unsigned long *ha;
+	char *rchg;
+	long *rindex;
+
+	ha = NULL;
+	rindex = NULL;
+	rchg = NULL;
+	rhash = NULL;
+	recs = NULL;
+
+	if (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0)
+		goto abort;
+	if (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *))))
+		goto abort;
+
+	if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
+		hbits = hsize = 0;
+	else {
+		hbits = xdl_hashbits((unsigned int) narec);
+		hsize = 1 << hbits;
+		if (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *))))
+			goto abort;
+		memset(rhash, 0, hsize * sizeof(xrecord_t *));
+	}
+
+	nrec = 0;
+	if ((cur = blk = xdl_mmfile_first(mf, &bsize)) != NULL) {
+		for (top = blk + bsize; cur < top; ) {
+			prev = cur;
+			hav = xdl_hash_record(&cur, top, xpp->flags);
+			if (nrec >= narec) {
+				narec *= 2;
+				if (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *))))
+					goto abort;
+				recs = rrecs;
+			}
+			if (!(crec = xdl_cha_alloc(&xdf->rcha)))
+				goto abort;
+			crec->ptr = prev;
+			crec->size = (long) (cur - prev);
+			crec->ha = hav;
+			recs[nrec++] = crec;
+
+			if ((XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF) &&
+			    xdl_classify_record(pass, cf, rhash, hbits, crec) < 0)
+				goto abort;
+		}
+	}
+
+	if (!(rchg = (char *) xdl_malloc((nrec + 2) * sizeof(char))))
+		goto abort;
+	memset(rchg, 0, (nrec + 2) * sizeof(char));
+
+	if (!(rindex = (long *) xdl_malloc((nrec + 1) * sizeof(long))))
+		goto abort;
+	if (!(ha = (unsigned long *) xdl_malloc((nrec + 1) * sizeof(unsigned long))))
+		goto abort;
+
+	xdf->nrec = nrec;
+	xdf->recs = recs;
+	xdf->hbits = hbits;
+	xdf->rhash = rhash;
+	xdf->rchg = rchg + 1;
+	xdf->rindex = rindex;
+	xdf->nreff = 0;
+	xdf->ha = ha;
+	xdf->dstart = 0;
+	xdf->dend = nrec - 1;
+
+	return 0;
+
+abort:
+	xdl_free(ha);
+	xdl_free(rindex);
+	xdl_free(rchg);
+	xdl_free(rhash);
+	xdl_free(recs);
+	xdl_cha_free(&xdf->rcha);
+	return -1;
+}
+
+
+static void xdl_free_ctx(xdfile_t *xdf) {
+
+	xdl_free(xdf->rhash);
+	xdl_free(xdf->rindex);
+	xdl_free(xdf->rchg - 1);
+	xdl_free(xdf->ha);
+	xdl_free(xdf->recs);
+	xdl_cha_free(&xdf->rcha);
+}
+
+
+int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+		    xdfenv_t *xe) {
+	long enl1, enl2, sample;
+	xdlclassifier_t cf;
+
+	memset(&cf, 0, sizeof(cf));
+
+	/*
+	 * For histogram diff, we can afford a smaller sample size and
+	 * thus a poorer estimate of the number of lines, as the hash
+	 * table (rhash) won't be filled up/grown. The number of lines
+	 * (nrecs) will be updated correctly anyway by
+	 * xdl_prepare_ctx().
+	 */
+	sample = (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF
+		  ? XDL_GUESS_NLINES2 : XDL_GUESS_NLINES1);
+
+	enl1 = xdl_guess_lines(mf1, sample) + 1;
+	enl2 = xdl_guess_lines(mf2, sample) + 1;
+
+	if (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF &&
+	    xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0)
+		return -1;
+
+	if (xdl_prepare_ctx(1, mf1, enl1, xpp, &cf, &xe->xdf1) < 0) {
+
+		xdl_free_classifier(&cf);
+		return -1;
+	}
+	if (xdl_prepare_ctx(2, mf2, enl2, xpp, &cf, &xe->xdf2) < 0) {
+
+		xdl_free_ctx(&xe->xdf1);
+		xdl_free_classifier(&cf);
+		return -1;
+	}
+
+	if ((XDF_DIFF_ALG(xpp->flags) != XDF_PATIENCE_DIFF) &&
+	    (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF) &&
+	    xdl_optimize_ctxs(&cf, &xe->xdf1, &xe->xdf2) < 0) {
+
+		xdl_free_ctx(&xe->xdf2);
+		xdl_free_ctx(&xe->xdf1);
+		return -1;
+	}
+
+	if (!(xpp->flags & XDF_HISTOGRAM_DIFF))
+		xdl_free_classifier(&cf);
+
+	return 0;
+}
+
+
+void xdl_free_env(xdfenv_t *xe) {
+
+	xdl_free_ctx(&xe->xdf2);
+	xdl_free_ctx(&xe->xdf1);
+}
+
+
+static int xdl_clean_mmatch(char const *dis, long i, long s, long e) {
+	long r, rdis0, rpdis0, rdis1, rpdis1;
+
+	/*
+	 * Limits the window the is examined during the similar-lines
+	 * scan. The loops below stops when dis[i - r] == 1 (line that
+	 * has no match), but there are corner cases where the loop
+	 * proceed all the way to the extremities by causing huge
+	 * performance penalties in case of big files.
+	 */
+	if (i - s > XDL_SIMSCAN_WINDOW)
+		s = i - XDL_SIMSCAN_WINDOW;
+	if (e - i > XDL_SIMSCAN_WINDOW)
+		e = i + XDL_SIMSCAN_WINDOW;
+
+	/*
+	 * Scans the lines before 'i' to find a run of lines that either
+	 * have no match (dis[j] == 0) or have multiple matches (dis[j] > 1).
+	 * Note that we always call this function with dis[i] > 1, so the
+	 * current line (i) is already a multimatch line.
+	 */
+	for (r = 1, rdis0 = 0, rpdis0 = 1; (i - r) >= s; r++) {
+		if (!dis[i - r])
+			rdis0++;
+		else if (dis[i - r] == 2)
+			rpdis0++;
+		else
+			break;
+	}
+	/*
+	 * If the run before the line 'i' found only multimatch lines, we
+	 * return 0 and hence we don't make the current line (i) discarded.
+	 * We want to discard multimatch lines only when they appear in the
+	 * middle of runs with nomatch lines (dis[j] == 0).
+	 */
+	if (rdis0 == 0)
+		return 0;
+	for (r = 1, rdis1 = 0, rpdis1 = 1; (i + r) <= e; r++) {
+		if (!dis[i + r])
+			rdis1++;
+		else if (dis[i + r] == 2)
+			rpdis1++;
+		else
+			break;
+	}
+	/*
+	 * If the run after the line 'i' found only multimatch lines, we
+	 * return 0 and hence we don't make the current line (i) discarded.
+	 */
+	if (rdis1 == 0)
+		return 0;
+	rdis1 += rdis0;
+	rpdis1 += rpdis0;
+
+	return rpdis1 * XDL_KPDIS_RUN < (rpdis1 + rdis1);
+}
+
+
+/*
+ * Try to reduce the problem complexity, discard records that have no
+ * matches on the other file. Also, lines that have multiple matches
+ * might be potentially discarded if they happear in a run of discardable.
+ */
+static int xdl_cleanup_records(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2) {
+	long i, nm, nreff, mlim;
+	xrecord_t **recs;
+	xdlclass_t *rcrec;
+	char *dis, *dis1, *dis2;
+
+	if (!(dis = (char *) xdl_malloc(xdf1->nrec + xdf2->nrec + 2))) {
+
+		return -1;
+	}
+	memset(dis, 0, xdf1->nrec + xdf2->nrec + 2);
+	dis1 = dis;
+	dis2 = dis1 + xdf1->nrec + 1;
+
+	if ((mlim = xdl_bogosqrt(xdf1->nrec)) > XDL_MAX_EQLIMIT)
+		mlim = XDL_MAX_EQLIMIT;
+	for (i = xdf1->dstart, recs = &xdf1->recs[xdf1->dstart]; i <= xdf1->dend; i++, recs++) {
+		rcrec = cf->rcrecs[(*recs)->ha];
+		nm = rcrec ? rcrec->len2 : 0;
+		dis1[i] = (nm == 0) ? 0: (nm >= mlim) ? 2: 1;
+	}
+
+	if ((mlim = xdl_bogosqrt(xdf2->nrec)) > XDL_MAX_EQLIMIT)
+		mlim = XDL_MAX_EQLIMIT;
+	for (i = xdf2->dstart, recs = &xdf2->recs[xdf2->dstart]; i <= xdf2->dend; i++, recs++) {
+		rcrec = cf->rcrecs[(*recs)->ha];
+		nm = rcrec ? rcrec->len1 : 0;
+		dis2[i] = (nm == 0) ? 0: (nm >= mlim) ? 2: 1;
+	}
+
+	for (nreff = 0, i = xdf1->dstart, recs = &xdf1->recs[xdf1->dstart];
+	     i <= xdf1->dend; i++, recs++) {
+		if (dis1[i] == 1 ||
+		    (dis1[i] == 2 && !xdl_clean_mmatch(dis1, i, xdf1->dstart, xdf1->dend))) {
+			xdf1->rindex[nreff] = i;
+			xdf1->ha[nreff] = (*recs)->ha;
+			nreff++;
+		} else
+			xdf1->rchg[i] = 1;
+	}
+	xdf1->nreff = nreff;
+
+	for (nreff = 0, i = xdf2->dstart, recs = &xdf2->recs[xdf2->dstart];
+	     i <= xdf2->dend; i++, recs++) {
+		if (dis2[i] == 1 ||
+		    (dis2[i] == 2 && !xdl_clean_mmatch(dis2, i, xdf2->dstart, xdf2->dend))) {
+			xdf2->rindex[nreff] = i;
+			xdf2->ha[nreff] = (*recs)->ha;
+			nreff++;
+		} else
+			xdf2->rchg[i] = 1;
+	}
+	xdf2->nreff = nreff;
+
+	xdl_free(dis);
+
+	return 0;
+}
+
+
+/*
+ * Early trim initial and terminal matching records.
+ */
+static int xdl_trim_ends(xdfile_t *xdf1, xdfile_t *xdf2) {
+	long i, lim;
+	xrecord_t **recs1, **recs2;
+
+	recs1 = xdf1->recs;
+	recs2 = xdf2->recs;
+	for (i = 0, lim = XDL_MIN(xdf1->nrec, xdf2->nrec); i < lim;
+	     i++, recs1++, recs2++)
+		if ((*recs1)->ha != (*recs2)->ha)
+			break;
+
+	xdf1->dstart = xdf2->dstart = i;
+
+	recs1 = xdf1->recs + xdf1->nrec - 1;
+	recs2 = xdf2->recs + xdf2->nrec - 1;
+	for (lim -= i, i = 0; i < lim; i++, recs1--, recs2--)
+		if ((*recs1)->ha != (*recs2)->ha)
+			break;
+
+	xdf1->dend = xdf1->nrec - i - 1;
+	xdf2->dend = xdf2->nrec - i - 1;
+
+	return 0;
+}
+
+
+static int xdl_optimize_ctxs(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2) {
+
+	if (xdl_trim_ends(xdf1, xdf2) < 0 ||
+	    xdl_cleanup_records(cf, xdf1, xdf2) < 0) {
+
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xprepare.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xprepare.h
new file mode 100755
index 0000000..8fb06a5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xprepare.h
@@ -0,0 +1,34 @@
+/*
+ *  LibXDiff by Davide Libenzi ( File Differential Library )
+ *  Copyright (C) 2003  Davide Libenzi
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel at xmailserver.org>
+ *
+ */
+
+#if !defined(XPREPARE_H)
+#define XPREPARE_H
+
+
+
+int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+		    xdfenv_t *xe);
+void xdl_free_env(xdfenv_t *xe);
+
+
+
+#endif /* #if !defined(XPREPARE_H) */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xtypes.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xtypes.h
new file mode 100755
index 0000000..2511aef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xtypes.h
@@ -0,0 +1,67 @@
+/*
+ *  LibXDiff by Davide Libenzi ( File Differential Library )
+ *  Copyright (C) 2003  Davide Libenzi
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel at xmailserver.org>
+ *
+ */
+
+#if !defined(XTYPES_H)
+#define XTYPES_H
+
+
+
+typedef struct s_chanode {
+	struct s_chanode *next;
+	long icurr;
+} chanode_t;
+
+typedef struct s_chastore {
+	chanode_t *head, *tail;
+	long isize, nsize;
+	chanode_t *ancur;
+	chanode_t *sncur;
+	long scurr;
+} chastore_t;
+
+typedef struct s_xrecord {
+	struct s_xrecord *next;
+	char const *ptr;
+	long size;
+	unsigned long ha;
+} xrecord_t;
+
+typedef struct s_xdfile {
+	chastore_t rcha;
+	long nrec;
+	unsigned int hbits;
+	xrecord_t **rhash;
+	long dstart, dend;
+	xrecord_t **recs;
+	char *rchg;
+	long *rindex;
+	long nreff;
+	unsigned long *ha;
+} xdfile_t;
+
+typedef struct s_xdfenv {
+	xdfile_t xdf1, xdf2;
+} xdfenv_t;
+
+
+
+#endif /* #if !defined(XTYPES_H) */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xutils.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xutils.c
new file mode 100755
index 0000000..30f2a30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xutils.c
@@ -0,0 +1,403 @@
+/*
+ *  LibXDiff by Davide Libenzi ( File Differential Library )
+ *  Copyright (C) 2003	Davide Libenzi
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel at xmailserver.org>
+ *
+ */
+
+#include "xinclude.h"
+
+
+
+
+long xdl_bogosqrt(long n) {
+	long i;
+
+	/*
+	 * Classical integer square root approximation using shifts.
+	 */
+	for (i = 1; n > 0; n >>= 2)
+		i <<= 1;
+
+	return i;
+}
+
+
+int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
+		     xdemitcb_t *ecb) {
+	int i = 2;
+	mmbuffer_t mb[3];
+
+	mb[0].ptr = (char *) pre;
+	mb[0].size = psize;
+	mb[1].ptr = (char *) rec;
+	mb[1].size = size;
+	if (size > 0 && rec[size - 1] != '\n') {
+		mb[2].ptr = (char *) "\n\\ No newline at end of file\n";
+		mb[2].size = strlen(mb[2].ptr);
+		i++;
+	}
+	if (ecb->outf(ecb->priv, mb, i) < 0) {
+
+		return -1;
+	}
+
+	return 0;
+}
+
+void *xdl_mmfile_first(mmfile_t *mmf, long *size)
+{
+	*size = (long)mmf->size;
+	return mmf->ptr;
+}
+
+
+long xdl_mmfile_size(mmfile_t *mmf)
+{
+	return (long)mmf->size;
+}
+
+
+int xdl_cha_init(chastore_t *cha, long isize, long icount) {
+
+	cha->head = cha->tail = NULL;
+	cha->isize = isize;
+	cha->nsize = icount * isize;
+	cha->ancur = cha->sncur = NULL;
+	cha->scurr = 0;
+
+	return 0;
+}
+
+
+void xdl_cha_free(chastore_t *cha) {
+	chanode_t *cur, *tmp;
+
+	for (cur = cha->head; (tmp = cur) != NULL;) {
+		cur = cur->next;
+		xdl_free(tmp);
+	}
+}
+
+
+void *xdl_cha_alloc(chastore_t *cha) {
+	chanode_t *ancur;
+	void *data;
+
+	if (!(ancur = cha->ancur) || ancur->icurr == cha->nsize) {
+		if (!(ancur = (chanode_t *) xdl_malloc(sizeof(chanode_t) + cha->nsize))) {
+
+			return NULL;
+		}
+		ancur->icurr = 0;
+		ancur->next = NULL;
+		if (cha->tail)
+			cha->tail->next = ancur;
+		if (!cha->head)
+			cha->head = ancur;
+		cha->tail = ancur;
+		cha->ancur = ancur;
+	}
+
+	data = (char *) ancur + sizeof(chanode_t) + ancur->icurr;
+	ancur->icurr += cha->isize;
+
+	return data;
+}
+
+long xdl_guess_lines(mmfile_t *mf, long sample) {
+	long nl = 0, size, tsize = 0;
+	char const *data, *cur, *top;
+
+	if ((cur = data = xdl_mmfile_first(mf, &size)) != NULL) {
+		for (top = data + size; nl < sample && cur < top; ) {
+			nl++;
+			if (!(cur = memchr(cur, '\n', top - cur)))
+				cur = top;
+			else
+				cur++;
+		}
+		tsize += (long) (cur - data);
+	}
+
+	if (nl && tsize)
+		nl = xdl_mmfile_size(mf) / (tsize / nl);
+
+	return nl + 1;
+}
+
+int xdl_blankline(const char *line, long size, long flags)
+{
+	long i;
+
+	if (!(flags & XDF_WHITESPACE_FLAGS))
+		return (size <= 1);
+
+	for (i = 0; i < size && XDL_ISSPACE(line[i]); i++)
+		;
+
+	return (i == size);
+}
+
+int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
+{
+	int i1, i2;
+
+	if (s1 == s2 && !memcmp(l1, l2, s1))
+		return 1;
+	if (!(flags & XDF_WHITESPACE_FLAGS))
+		return 0;
+
+	i1 = 0;
+	i2 = 0;
+
+	/*
+	 * -w matches everything that matches with -b, and -b in turn
+	 * matches everything that matches with --ignore-space-at-eol.
+	 *
+	 * Each flavor of ignoring needs different logic to skip whitespaces
+	 * while we have both sides to compare.
+	 */
+	if (flags & XDF_IGNORE_WHITESPACE) {
+		goto skip_ws;
+		while (i1 < s1 && i2 < s2) {
+			if (l1[i1++] != l2[i2++])
+				return 0;
+		skip_ws:
+			while (i1 < s1 && XDL_ISSPACE(l1[i1]))
+				i1++;
+			while (i2 < s2 && XDL_ISSPACE(l2[i2]))
+				i2++;
+		}
+	} else if (flags & XDF_IGNORE_WHITESPACE_CHANGE) {
+		while (i1 < s1 && i2 < s2) {
+			if (XDL_ISSPACE(l1[i1]) && XDL_ISSPACE(l2[i2])) {
+				/* Skip matching spaces and try again */
+				while (i1 < s1 && XDL_ISSPACE(l1[i1]))
+					i1++;
+				while (i2 < s2 && XDL_ISSPACE(l2[i2]))
+					i2++;
+				continue;
+			}
+			if (l1[i1++] != l2[i2++])
+				return 0;
+		}
+	} else if (flags & XDF_IGNORE_WHITESPACE_AT_EOL) {
+		while (i1 < s1 && i2 < s2 && l1[i1++] == l2[i2++])
+			; /* keep going */
+	}
+
+	/*
+	 * After running out of one side, the remaining side must have
+	 * nothing but whitespace for the lines to match.  Note that
+	 * ignore-whitespace-at-eol case may break out of the loop
+	 * while there still are characters remaining on both lines.
+	 */
+	if (i1 < s1) {
+		while (i1 < s1 && XDL_ISSPACE(l1[i1]))
+			i1++;
+		if (s1 != i1)
+			return 0;
+	}
+	if (i2 < s2) {
+		while (i2 < s2 && XDL_ISSPACE(l2[i2]))
+			i2++;
+		return (s2 == i2);
+	}
+	return 1;
+}
+
+static unsigned long xdl_hash_record_with_whitespace(char const **data,
+		char const *top, long flags) {
+	unsigned long ha = 5381;
+	char const *ptr = *data;
+
+	for (; ptr < top && *ptr != '\n'; ptr++) {
+		if (XDL_ISSPACE(*ptr)) {
+			const char *ptr2 = ptr;
+			int at_eol;
+			while (ptr + 1 < top && XDL_ISSPACE(ptr[1])
+					&& ptr[1] != '\n')
+				ptr++;
+			at_eol = (top <= ptr + 1 || ptr[1] == '\n');
+			if (flags & XDF_IGNORE_WHITESPACE)
+				; /* already handled */
+			else if (flags & XDF_IGNORE_WHITESPACE_CHANGE
+				 && !at_eol) {
+				ha += (ha << 5);
+				ha ^= (unsigned long) ' ';
+			}
+			else if (flags & XDF_IGNORE_WHITESPACE_AT_EOL
+				 && !at_eol) {
+				while (ptr2 != ptr + 1) {
+					ha += (ha << 5);
+					ha ^= (unsigned long) *ptr2;
+					ptr2++;
+				}
+			}
+			continue;
+		}
+		ha += (ha << 5);
+		ha ^= (unsigned long) *ptr;
+	}
+	*data = ptr < top ? ptr + 1: ptr;
+
+	return ha;
+}
+
+
+unsigned long xdl_hash_record(char const **data, char const *top, long flags) {
+	unsigned long ha = 5381;
+	char const *ptr = *data;
+
+	if (flags & XDF_WHITESPACE_FLAGS)
+		return xdl_hash_record_with_whitespace(data, top, flags);
+
+	for (; ptr < top && *ptr != '\n'; ptr++) {
+		ha += (ha << 5);
+		ha ^= (unsigned long) *ptr;
+	}
+	*data = ptr < top ? ptr + 1: ptr;
+
+	return ha;
+}
+
+
+unsigned int xdl_hashbits(unsigned int size) {
+	unsigned int val = 1, bits = 0;
+
+	for (; val < size && bits < CHAR_BIT * sizeof(unsigned int); val <<= 1, bits++);
+	return bits ? bits: 1;
+}
+
+
+int xdl_num_out(char *out, long val) {
+	char *ptr, *str = out;
+	char buf[32];
+
+	ptr = buf + sizeof(buf) - 1;
+	*ptr = '\0';
+	if (val < 0) {
+		*--ptr = '-';
+		val = -val;
+	}
+	for (; val && ptr > buf; val /= 10)
+		*--ptr = "0123456789"[val % 10];
+	if (*ptr)
+		for (; *ptr; ptr++, str++)
+			*str = *ptr;
+	else
+		*str++ = '0';
+	*str = '\0';
+
+	return (int)(str - out);
+}
+
+
+long xdl_atol(char const *str, char const **next) {
+	long val, base;
+	char const *top;
+
+	for (top = str; XDL_ISDIGIT(*top); top++);
+	if (next)
+		*next = top;
+	for (val = 0, base = 1, top--; top >= str; top--, base *= 10)
+		val += base * (long)(*top - '0');
+	return val;
+}
+
+
+int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
+		      const char *func, long funclen, xdemitcb_t *ecb) {
+	int nb = 0;
+	mmbuffer_t mb;
+	char buf[128];
+
+	memcpy(buf, "@@ -", 4);
+	nb += 4;
+
+	nb += xdl_num_out(buf + nb, c1 ? s1: s1 - 1);
+
+	if (c1 != 1) {
+		memcpy(buf + nb, ",", 1);
+		nb += 1;
+
+		nb += xdl_num_out(buf + nb, c1);
+	}
+
+	memcpy(buf + nb, " +", 2);
+	nb += 2;
+
+	nb += xdl_num_out(buf + nb, c2 ? s2: s2 - 1);
+
+	if (c2 != 1) {
+		memcpy(buf + nb, ",", 1);
+		nb += 1;
+
+		nb += xdl_num_out(buf + nb, c2);
+	}
+
+	memcpy(buf + nb, " @@", 3);
+	nb += 3;
+	if (func && funclen) {
+		buf[nb++] = ' ';
+		if (funclen > (long)sizeof(buf) - nb - 1)
+			funclen = (long)sizeof(buf) - nb - 1;
+		memcpy(buf + nb, func, funclen);
+		nb += funclen;
+	}
+	buf[nb++] = '\n';
+
+	mb.ptr = buf;
+	mb.size = nb;
+	if (ecb->outf(ecb->priv, &mb, 1) < 0)
+		return -1;
+
+	return 0;
+}
+
+int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
+		int line1, int count1, int line2, int count2)
+{
+	/*
+	 * This probably does not work outside Git, since
+	 * we have a very simple mmfile structure.
+	 *
+	 * Note: ideally, we would reuse the prepared environment, but
+	 * the libxdiff interface does not (yet) allow for diffing only
+	 * ranges of lines instead of the whole files.
+	 */
+	mmfile_t subfile1, subfile2;
+	xdfenv_t env;
+
+	subfile1.ptr = (char *)diff_env->xdf1.recs[line1 - 1]->ptr;
+	subfile1.size = diff_env->xdf1.recs[line1 + count1 - 2]->ptr +
+		diff_env->xdf1.recs[line1 + count1 - 2]->size - subfile1.ptr;
+	subfile2.ptr = (char *)diff_env->xdf2.recs[line2 - 1]->ptr;
+	subfile2.size = diff_env->xdf2.recs[line2 + count2 - 2]->ptr +
+		diff_env->xdf2.recs[line2 + count2 - 2]->size - subfile2.ptr;
+	if (xdl_do_diff(&subfile1, &subfile2, xpp, &env) < 0)
+		return -1;
+
+	memcpy(diff_env->xdf1.rchg + line1 - 1, env.xdf1.rchg, count1);
+	memcpy(diff_env->xdf2.rchg + line2 - 1, env.xdf2.rchg, count2);
+
+	xdl_free_env(&env);
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xutils.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xutils.h
new file mode 100755
index 0000000..8f952a8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/xdiff/xutils.h
@@ -0,0 +1,50 @@
+/*
+ *  LibXDiff by Davide Libenzi ( File Differential Library )
+ *  Copyright (C) 2003  Davide Libenzi
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Davide Libenzi <davidel at xmailserver.org>
+ *
+ */
+
+#if !defined(XUTILS_H)
+#define XUTILS_H
+
+
+
+long xdl_bogosqrt(long n);
+int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
+		     xdemitcb_t *ecb);
+int xdl_cha_init(chastore_t *cha, long isize, long icount);
+void xdl_cha_free(chastore_t *cha);
+void *xdl_cha_alloc(chastore_t *cha);
+void *xdl_cha_first(chastore_t *cha);
+void *xdl_cha_next(chastore_t *cha);
+long xdl_guess_lines(mmfile_t *mf, long sample);
+int xdl_blankline(const char *line, long size, long flags);
+int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags);
+unsigned long xdl_hash_record(char const **data, char const *top, long flags);
+unsigned int xdl_hashbits(unsigned int size);
+int xdl_num_out(char *out, long val);
+long xdl_atol(char const *str, char const **next);
+int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
+		      const char *func, long funclen, xdemitcb_t *ecb);
+int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
+		       int line1, int count1, int line2, int count2);
+
+
+
+#endif /* #if !defined(XUTILS_H) */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/zstream.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/zstream.c
new file mode 100755
index 0000000..2130bc3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/zstream.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include <zlib.h>
+
+#include "zstream.h"
+#include "buffer.h"
+
+#define ZSTREAM_BUFFER_SIZE (1024 * 1024)
+#define ZSTREAM_BUFFER_MIN_EXTRA 8
+
+static int zstream_seterr(git_zstream *zs)
+{
+	if (zs->zerr == Z_OK || zs->zerr == Z_STREAM_END)
+		return 0;
+
+	if (zs->zerr == Z_MEM_ERROR)
+		giterr_set_oom();
+	else if (zs->z.msg)
+		giterr_set(GITERR_ZLIB, zs->z.msg);
+	else
+		giterr_set(GITERR_ZLIB, "Unknown compression error");
+
+	return -1;
+}
+
+int git_zstream_init(git_zstream *zstream)
+{
+	zstream->zerr = deflateInit(&zstream->z, Z_DEFAULT_COMPRESSION);
+	return zstream_seterr(zstream);
+}
+
+void git_zstream_free(git_zstream *zstream)
+{
+	deflateEnd(&zstream->z);
+}
+
+void git_zstream_reset(git_zstream *zstream)
+{
+	deflateReset(&zstream->z);
+	zstream->in = NULL;
+	zstream->in_len = 0;
+	zstream->zerr = Z_STREAM_END;
+}
+
+int git_zstream_set_input(git_zstream *zstream, const void *in, size_t in_len)
+{
+	zstream->in = in;
+	zstream->in_len = in_len;
+	zstream->zerr = Z_OK;
+	return 0;
+}
+
+bool git_zstream_done(git_zstream *zstream)
+{
+	return (!zstream->in_len && zstream->zerr == Z_STREAM_END);
+}
+
+size_t git_zstream_suggest_output_len(git_zstream *zstream)
+{
+	if (zstream->in_len > ZSTREAM_BUFFER_SIZE)
+		return ZSTREAM_BUFFER_SIZE;
+	else if (zstream->in_len > ZSTREAM_BUFFER_MIN_EXTRA)
+		return zstream->in_len;
+	else
+		return ZSTREAM_BUFFER_MIN_EXTRA;
+}
+
+int git_zstream_get_output(void *out, size_t *out_len, git_zstream *zstream)
+{
+	int zflush = Z_FINISH;
+	size_t out_remain = *out_len;
+
+	while (out_remain > 0 && zstream->zerr != Z_STREAM_END) {
+		size_t out_queued, in_queued, out_used, in_used;
+
+		/* set up in data */
+		zstream->z.next_in  = (Bytef *)zstream->in;
+		zstream->z.avail_in = (uInt)zstream->in_len;
+		if ((size_t)zstream->z.avail_in != zstream->in_len) {
+			zstream->z.avail_in = INT_MAX;
+			zflush = Z_NO_FLUSH;
+		} else {
+			zflush = Z_FINISH;
+		}
+		in_queued = (size_t)zstream->z.avail_in;
+
+		/* set up out data */
+		zstream->z.next_out = out;
+		zstream->z.avail_out = (uInt)out_remain;
+		if ((size_t)zstream->z.avail_out != out_remain)
+			zstream->z.avail_out = INT_MAX;
+		out_queued = (size_t)zstream->z.avail_out;
+
+		/* compress next chunk */
+		zstream->zerr = deflate(&zstream->z, zflush);
+
+		if (zstream->zerr == Z_STREAM_ERROR)
+			return zstream_seterr(zstream);
+
+		out_used = (out_queued - zstream->z.avail_out);
+		out_remain -= out_used;
+		out = ((char *)out) + out_used;
+
+		in_used = (in_queued - zstream->z.avail_in);
+		zstream->in_len -= in_used;
+		zstream->in += in_used;
+	}
+
+	/* either we finished the input or we did not flush the data */
+	assert(zstream->in_len > 0 || zflush == Z_FINISH);
+
+	/* set out_size to number of bytes actually written to output */
+	*out_len = *out_len - out_remain;
+
+	return 0;
+}
+
+int git_zstream_deflatebuf(git_buf *out, const void *in, size_t in_len)
+{
+	git_zstream zs = GIT_ZSTREAM_INIT;
+	int error = 0;
+
+	if ((error = git_zstream_init(&zs)) < 0)
+		return error;
+
+	if ((error = git_zstream_set_input(&zs, in, in_len)) < 0)
+		goto done;
+
+	while (!git_zstream_done(&zs)) {
+		size_t step = git_zstream_suggest_output_len(&zs), written;
+
+		if ((error = git_buf_grow_by(out, step)) < 0)
+			goto done;
+
+		written = out->asize - out->size;
+
+		if ((error = git_zstream_get_output(
+				out->ptr + out->size, &written, &zs)) < 0)
+			goto done;
+
+		out->size += written;
+	}
+
+	/* NULL terminate for consistency if possible */
+	if (out->size < out->asize)
+		out->ptr[out->size] = '\0';
+
+done:
+	git_zstream_free(&zs);
+	return error;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/zstream.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/zstream.h
new file mode 100755
index 0000000..9b5bf6a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/src/zstream.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_zstream_h__
+#define INCLUDE_zstream_h__
+
+#include <zlib.h>
+
+#include "common.h"
+#include "buffer.h"
+
+typedef struct {
+	z_stream z;
+	const char *in;
+	size_t in_len;
+	int zerr;
+} git_zstream;
+
+#define GIT_ZSTREAM_INIT {{0}}
+
+int git_zstream_init(git_zstream *zstream);
+void git_zstream_free(git_zstream *zstream);
+
+int git_zstream_set_input(git_zstream *zstream, const void *in, size_t in_len);
+
+size_t git_zstream_suggest_output_len(git_zstream *zstream);
+
+int git_zstream_get_output(void *out, size_t *out_len, git_zstream *zstream);
+
+bool git_zstream_done(git_zstream *zstream);
+
+void git_zstream_reset(git_zstream *zstream);
+
+int git_zstream_deflatebuf(git_buf *out, const void *in, size_t in_len);
+
+#endif /* INCLUDE_zstream_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/README.md b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/README.md
new file mode 100755
index 0000000..3aeaaf4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/README.md
@@ -0,0 +1,22 @@
+Writing Clar tests for libgit2
+==============================
+
+For information on the Clar testing framework and a detailed introduction
+please visit:
+
+https://github.com/vmg/clar
+
+
+* Write your modules and tests. Use good, meaningful names.
+
+* Make sure you actually build the tests by setting:
+
+        cmake -DBUILD_CLAR=ON build/
+
+* Test:
+
+        ./build/libgit2_clar
+
+* Make sure everything is fine.
+
+* Send your pull request. That's it.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/attr_expect.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/attr_expect.h
new file mode 100755
index 0000000..70f1ab4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/attr_expect.h
@@ -0,0 +1,43 @@
+#ifndef __CLAR_TEST_ATTR_EXPECT__
+#define __CLAR_TEST_ATTR_EXPECT__
+
+enum attr_expect_t {
+	EXPECT_FALSE,
+	EXPECT_TRUE,
+	EXPECT_UNDEFINED,
+	EXPECT_STRING
+};
+
+struct attr_expected {
+	const char *path;
+	const char *attr;
+	enum attr_expect_t expected;
+	const char *expected_str;
+};
+
+GIT_INLINE(void) attr_check_expected(
+	enum attr_expect_t expected,
+	const char *expected_str,
+	const char *name,
+	const char *value)
+{
+	switch (expected) {
+	case EXPECT_TRUE:
+		cl_assert_(GIT_ATTR_TRUE(value), name);
+		break;
+
+	case EXPECT_FALSE:
+		cl_assert_(GIT_ATTR_FALSE(value), name);
+		break;
+
+	case EXPECT_UNDEFINED:
+		cl_assert_(GIT_ATTR_UNSPECIFIED(value), name);
+		break;
+
+	case EXPECT_STRING:
+		cl_assert_equal_s(expected_str, value);
+		break;
+	}
+}
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/file.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/file.c
new file mode 100755
index 0000000..1f4108c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/file.c
@@ -0,0 +1,224 @@
+#include "clar_libgit2.h"
+#include "attr_file.h"
+#include "attr_expect.h"
+
+#define get_rule(X) ((git_attr_rule *)git_vector_get(&file->rules,(X)))
+#define get_assign(R,Y) ((git_attr_assignment *)git_vector_get(&(R)->assigns,(Y)))
+
+void test_attr_file__simple_read(void)
+{
+	git_attr_file *file;
+	git_attr_assignment *assign;
+	git_attr_rule *rule;
+
+	cl_git_pass(git_attr_file__load_standalone(&file, cl_fixture("attr/attr0")));
+
+	cl_assert_equal_s(cl_fixture("attr/attr0"), file->entry->path);
+	cl_assert(file->rules.length == 1);
+
+	rule = get_rule(0);
+	cl_assert(rule != NULL);
+	cl_assert_equal_s("*", rule->match.pattern);
+	cl_assert(rule->match.length == 1);
+	cl_assert((rule->match.flags & GIT_ATTR_FNMATCH_HASWILD) != 0);
+
+	cl_assert(rule->assigns.length == 1);
+	assign = get_assign(rule, 0);
+	cl_assert(assign != NULL);
+	cl_assert_equal_s("binary", assign->name);
+	cl_assert(GIT_ATTR_TRUE(assign->value));
+
+	git_attr_file__free(file);
+}
+
+void test_attr_file__match_variants(void)
+{
+	git_attr_file *file;
+	git_attr_rule *rule;
+	git_attr_assignment *assign;
+
+	cl_git_pass(git_attr_file__load_standalone(&file, cl_fixture("attr/attr1")));
+
+	cl_assert_equal_s(cl_fixture("attr/attr1"), file->entry->path);
+	cl_assert(file->rules.length == 10);
+
+	/* let's do a thorough check of this rule, then just verify
+	 * the things that are unique for the later rules
+	 */
+	rule = get_rule(0);
+	cl_assert(rule);
+	cl_assert_equal_s("pat0", rule->match.pattern);
+	cl_assert(rule->match.length == strlen("pat0"));
+	cl_assert(rule->assigns.length == 1);
+	assign = get_assign(rule,0);
+	cl_assert_equal_s("attr0", assign->name);
+	cl_assert(assign->name_hash == git_attr_file__name_hash(assign->name));
+	cl_assert(GIT_ATTR_TRUE(assign->value));
+
+	rule = get_rule(1);
+	cl_assert_equal_s("pat1", rule->match.pattern);
+	cl_assert(rule->match.length == strlen("pat1"));
+	cl_assert((rule->match.flags & GIT_ATTR_FNMATCH_NEGATIVE) != 0);
+
+	rule = get_rule(2);
+	cl_assert_equal_s("pat2", rule->match.pattern);
+	cl_assert(rule->match.length == strlen("pat2"));
+	cl_assert((rule->match.flags & GIT_ATTR_FNMATCH_DIRECTORY) != 0);
+
+	rule = get_rule(3);
+	cl_assert_equal_s("pat3dir/pat3file", rule->match.pattern);
+	cl_assert((rule->match.flags & GIT_ATTR_FNMATCH_FULLPATH) != 0);
+
+	rule = get_rule(4);
+	cl_assert_equal_s("pat4.*", rule->match.pattern);
+	cl_assert((rule->match.flags & GIT_ATTR_FNMATCH_HASWILD) != 0);
+
+	rule = get_rule(5);
+	cl_assert_equal_s("*.pat5", rule->match.pattern);
+	cl_assert((rule->match.flags & GIT_ATTR_FNMATCH_HASWILD) != 0);
+
+	rule = get_rule(7);
+	cl_assert_equal_s("pat7[a-e]??[xyz]", rule->match.pattern);
+	cl_assert(rule->assigns.length == 1);
+	cl_assert((rule->match.flags & GIT_ATTR_FNMATCH_HASWILD) != 0);
+	assign = get_assign(rule,0);
+	cl_assert_equal_s("attr7", assign->name);
+	cl_assert(GIT_ATTR_TRUE(assign->value));
+
+	rule = get_rule(8);
+	cl_assert_equal_s("pat8 with spaces", rule->match.pattern);
+	cl_assert(rule->match.length == strlen("pat8 with spaces"));
+
+	rule = get_rule(9);
+	cl_assert_equal_s("pat9", rule->match.pattern);
+
+	git_attr_file__free(file);
+}
+
+static void check_one_assign(
+	git_attr_file *file,
+	int rule_idx,
+	int assign_idx,
+	const char *pattern,
+	const char *name,
+	enum attr_expect_t expected,
+	const char *expected_str)
+{
+	git_attr_rule *rule = get_rule(rule_idx);
+	git_attr_assignment *assign = get_assign(rule, assign_idx);
+
+	cl_assert_equal_s(pattern, rule->match.pattern);
+	cl_assert(rule->assigns.length == 1);
+	cl_assert_equal_s(name, assign->name);
+	cl_assert(assign->name_hash == git_attr_file__name_hash(assign->name));
+
+	attr_check_expected(expected, expected_str, assign->name, assign->value);
+}
+
+void test_attr_file__assign_variants(void)
+{
+	git_attr_file *file;
+	git_attr_rule *rule;
+	git_attr_assignment *assign;
+
+	cl_git_pass(git_attr_file__load_standalone(&file, cl_fixture("attr/attr2")));
+
+	cl_assert_equal_s(cl_fixture("attr/attr2"), file->entry->path);
+	cl_assert(file->rules.length == 11);
+
+	check_one_assign(file, 0, 0, "pat0", "simple", EXPECT_TRUE, NULL);
+	check_one_assign(file, 1, 0, "pat1", "neg", EXPECT_FALSE, NULL);
+	check_one_assign(file, 2, 0, "*", "notundef", EXPECT_TRUE, NULL);
+	check_one_assign(file, 3, 0, "pat2", "notundef", EXPECT_UNDEFINED, NULL);
+	check_one_assign(file, 4, 0, "pat3", "assigned", EXPECT_STRING, "test-value");
+	check_one_assign(file, 5, 0, "pat4", "rule-with-more-chars", EXPECT_STRING, "value-with-more-chars");
+	check_one_assign(file, 6, 0, "pat5", "empty", EXPECT_TRUE, NULL);
+	check_one_assign(file, 7, 0, "pat6", "negempty", EXPECT_FALSE, NULL);
+
+	rule = get_rule(8);
+	cl_assert_equal_s("pat7", rule->match.pattern);
+	cl_assert(rule->assigns.length == 5);
+	/* assignments will be sorted by hash value, so we have to do
+	 * lookups by search instead of by position
+	 */
+	assign = git_attr_rule__lookup_assignment(rule, "multiple");
+	cl_assert(assign);
+	cl_assert_equal_s("multiple", assign->name);
+	cl_assert(GIT_ATTR_TRUE(assign->value));
+	assign = git_attr_rule__lookup_assignment(rule, "single");
+	cl_assert(assign);
+	cl_assert_equal_s("single", assign->name);
+	cl_assert(GIT_ATTR_FALSE(assign->value));
+	assign = git_attr_rule__lookup_assignment(rule, "values");
+	cl_assert(assign);
+	cl_assert_equal_s("values", assign->name);
+	cl_assert_equal_s("1", assign->value);
+	assign = git_attr_rule__lookup_assignment(rule, "also");
+	cl_assert(assign);
+	cl_assert_equal_s("also", assign->name);
+	cl_assert_equal_s("a-really-long-value/*", assign->value);
+	assign = git_attr_rule__lookup_assignment(rule, "happy");
+	cl_assert(assign);
+	cl_assert_equal_s("happy", assign->name);
+	cl_assert_equal_s("yes!", assign->value);
+	assign = git_attr_rule__lookup_assignment(rule, "other");
+	cl_assert(!assign);
+
+	rule = get_rule(9);
+	cl_assert_equal_s("pat8", rule->match.pattern);
+	cl_assert(rule->assigns.length == 2);
+	assign = git_attr_rule__lookup_assignment(rule, "again");
+	cl_assert(assign);
+	cl_assert_equal_s("again", assign->name);
+	cl_assert(GIT_ATTR_TRUE(assign->value));
+	assign = git_attr_rule__lookup_assignment(rule, "another");
+	cl_assert(assign);
+	cl_assert_equal_s("another", assign->name);
+	cl_assert_equal_s("12321", assign->value);
+
+	check_one_assign(file, 10, 0, "pat9", "at-eof", EXPECT_FALSE, NULL);
+
+	git_attr_file__free(file);
+}
+
+void test_attr_file__check_attr_examples(void)
+{
+	git_attr_file *file;
+	git_attr_rule *rule;
+	git_attr_assignment *assign;
+
+	cl_git_pass(git_attr_file__load_standalone(&file, cl_fixture("attr/attr3")));
+	cl_assert_equal_s(cl_fixture("attr/attr3"), file->entry->path);
+	cl_assert(file->rules.length == 3);
+
+	rule = get_rule(0);
+	cl_assert_equal_s("*.java", rule->match.pattern);
+	cl_assert(rule->assigns.length == 3);
+	assign = git_attr_rule__lookup_assignment(rule, "diff");
+	cl_assert_equal_s("diff", assign->name);
+	cl_assert_equal_s("java", assign->value);
+	assign = git_attr_rule__lookup_assignment(rule, "crlf");
+	cl_assert_equal_s("crlf", assign->name);
+	cl_assert(GIT_ATTR_FALSE(assign->value));
+	assign = git_attr_rule__lookup_assignment(rule, "myAttr");
+	cl_assert_equal_s("myAttr", assign->name);
+	cl_assert(GIT_ATTR_TRUE(assign->value));
+	assign = git_attr_rule__lookup_assignment(rule, "missing");
+	cl_assert(assign == NULL);
+
+	rule = get_rule(1);
+	cl_assert_equal_s("NoMyAttr.java", rule->match.pattern);
+	cl_assert(rule->assigns.length == 1);
+	assign = get_assign(rule, 0);
+	cl_assert_equal_s("myAttr", assign->name);
+	cl_assert(GIT_ATTR_UNSPECIFIED(assign->value));
+
+	rule = get_rule(2);
+	cl_assert_equal_s("README", rule->match.pattern);
+	cl_assert(rule->assigns.length == 1);
+	assign = get_assign(rule, 0);
+	cl_assert_equal_s("caveat", assign->name);
+	cl_assert_equal_s("unspecified", assign->value);
+
+	git_attr_file__free(file);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/flags.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/flags.c
new file mode 100755
index 0000000..80c6e11
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/flags.c
@@ -0,0 +1,108 @@
+#include "clar_libgit2.h"
+#include "git2/attr.h"
+
+void test_attr_flags__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_attr_flags__bare(void)
+{
+	git_repository *repo = cl_git_sandbox_init("testrepo.git");
+	const char *value;
+
+	cl_assert(git_repository_is_bare(repo));
+
+	cl_git_pass(git_attr_get(
+		&value, repo, GIT_ATTR_CHECK_NO_SYSTEM, "README.md", "diff"));
+	cl_assert(GIT_ATTR_UNSPECIFIED(value));
+}
+
+void test_attr_flags__index_vs_workdir(void)
+{
+	git_repository *repo = cl_git_sandbox_init("attr_index");
+	const char *value;
+
+	cl_assert(!git_repository_is_bare(repo));
+
+	/* wd then index */
+	cl_git_pass(git_attr_get(
+		&value, repo, GIT_ATTR_CHECK_NO_SYSTEM | GIT_ATTR_CHECK_FILE_THEN_INDEX,
+		"README.md", "bar"));
+	cl_assert(GIT_ATTR_FALSE(value));
+
+	cl_git_pass(git_attr_get(
+		&value, repo, GIT_ATTR_CHECK_NO_SYSTEM | GIT_ATTR_CHECK_FILE_THEN_INDEX,
+		"README.md", "blargh"));
+	cl_assert_equal_s(value, "goop");
+
+	cl_git_pass(git_attr_get(
+		&value, repo, GIT_ATTR_CHECK_NO_SYSTEM | GIT_ATTR_CHECK_FILE_THEN_INDEX,
+		"README.txt", "foo"));
+	cl_assert(GIT_ATTR_FALSE(value));
+
+	/* index then wd */
+	cl_git_pass(git_attr_get(
+		&value, repo, GIT_ATTR_CHECK_NO_SYSTEM | GIT_ATTR_CHECK_INDEX_THEN_FILE,
+		"README.md", "bar"));
+	cl_assert(GIT_ATTR_TRUE(value));
+
+	cl_git_pass(git_attr_get(
+		&value, repo, GIT_ATTR_CHECK_NO_SYSTEM | GIT_ATTR_CHECK_INDEX_THEN_FILE,
+		"README.md", "blargh"));
+	cl_assert_equal_s(value, "garble");
+
+	cl_git_pass(git_attr_get(
+		&value, repo, GIT_ATTR_CHECK_NO_SYSTEM | GIT_ATTR_CHECK_INDEX_THEN_FILE,
+		"README.txt", "foo"));
+	cl_assert(GIT_ATTR_TRUE(value));
+}
+
+void test_attr_flags__subdir(void)
+{
+	git_repository *repo = cl_git_sandbox_init("attr_index");
+	const char *value;
+
+	/* wd then index */
+	cl_git_pass(git_attr_get(
+		&value, repo, GIT_ATTR_CHECK_NO_SYSTEM | GIT_ATTR_CHECK_FILE_THEN_INDEX,
+		"sub/sub/README.md", "bar"));
+	cl_assert_equal_s(value, "1234");
+
+	cl_git_pass(git_attr_get(
+		&value, repo, GIT_ATTR_CHECK_NO_SYSTEM | GIT_ATTR_CHECK_FILE_THEN_INDEX,
+		"sub/sub/README.txt", "another"));
+	cl_assert_equal_s(value, "one");
+
+	cl_git_pass(git_attr_get(
+		&value, repo, GIT_ATTR_CHECK_NO_SYSTEM | GIT_ATTR_CHECK_FILE_THEN_INDEX,
+		"sub/sub/README.txt", "again"));
+	cl_assert(GIT_ATTR_TRUE(value));
+
+	cl_git_pass(git_attr_get(
+		&value, repo, GIT_ATTR_CHECK_NO_SYSTEM | GIT_ATTR_CHECK_FILE_THEN_INDEX,
+		"sub/sub/README.txt", "beep"));
+	cl_assert_equal_s(value, "10");
+
+	/* index then wd */
+	cl_git_pass(git_attr_get(
+		&value, repo, GIT_ATTR_CHECK_NO_SYSTEM | GIT_ATTR_CHECK_INDEX_THEN_FILE,
+		"sub/sub/README.md", "bar"));
+	cl_assert_equal_s(value, "1337");
+
+	cl_git_pass(git_attr_get(
+		&value, repo, GIT_ATTR_CHECK_NO_SYSTEM | GIT_ATTR_CHECK_INDEX_THEN_FILE,
+		"sub/sub/README.txt", "another"));
+	cl_assert_equal_s(value, "one");
+
+	cl_git_pass(git_attr_get(
+		&value, repo, GIT_ATTR_CHECK_NO_SYSTEM | GIT_ATTR_CHECK_INDEX_THEN_FILE,
+		"sub/sub/README.txt", "again"));
+	cl_assert(GIT_ATTR_TRUE(value));
+
+	cl_git_pass(git_attr_get(
+		&value, repo, GIT_ATTR_CHECK_NO_SYSTEM | GIT_ATTR_CHECK_INDEX_THEN_FILE,
+		"sub/sub/README.txt", "beep"));
+	cl_assert_equal_s(value, "5");
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/ignore.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/ignore.c
new file mode 100755
index 0000000..27fed25
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/ignore.c
@@ -0,0 +1,254 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "path.h"
+#include "fileops.h"
+
+static git_repository *g_repo = NULL;
+
+void test_attr_ignore__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("attr");
+}
+
+void test_attr_ignore__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+	g_repo = NULL;
+}
+
+static void assert_is_ignored_(
+	bool expected, const char *filepath, const char *file, int line)
+{
+	int is_ignored = 0;
+
+	cl_git_pass_(
+		git_ignore_path_is_ignored(&is_ignored, g_repo, filepath), file, line);
+
+	clar__assert_equal(
+		file, line, "expected != is_ignored", 1, "%d",
+		(int)(expected != 0), (int)(is_ignored != 0));
+}
+#define assert_is_ignored(expected, filepath) \
+	assert_is_ignored_(expected, filepath, __FILE__, __LINE__)
+
+void test_attr_ignore__honor_temporary_rules(void)
+{
+	cl_git_rewritefile("attr/.gitignore", "/NewFolder\n/NewFolder/NewFolder");
+
+	assert_is_ignored(false, "File.txt");
+	assert_is_ignored(true, "NewFolder");
+	assert_is_ignored(true, "NewFolder/NewFolder");
+	assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
+}
+
+void test_attr_ignore__allow_root(void)
+{
+	cl_git_rewritefile("attr/.gitignore", "/");
+
+	assert_is_ignored(false, "File.txt");
+	assert_is_ignored(false, "NewFolder");
+	assert_is_ignored(false, "NewFolder/NewFolder");
+	assert_is_ignored(false, "NewFolder/NewFolder/File.txt");
+}
+
+void test_attr_ignore__ignore_root(void)
+{
+	cl_git_rewritefile("attr/.gitignore", "/\n\n/NewFolder\n/NewFolder/NewFolder");
+
+	assert_is_ignored(false, "File.txt");
+	assert_is_ignored(true, "NewFolder");
+	assert_is_ignored(true, "NewFolder/NewFolder");
+	assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
+}
+
+void test_attr_ignore__full_paths(void)
+{
+	cl_git_rewritefile("attr/.gitignore", "Folder/*/Contained");
+
+	assert_is_ignored(true, "Folder/Middle/Contained");
+	assert_is_ignored(false, "Folder/Middle/More/More/Contained");
+
+	cl_git_rewritefile("attr/.gitignore", "Folder/**/Contained");
+
+	assert_is_ignored(true, "Folder/Middle/Contained");
+	assert_is_ignored(true, "Folder/Middle/More/More/Contained");
+
+	cl_git_rewritefile("attr/.gitignore", "Folder/**/Contained/*/Child");
+
+	assert_is_ignored(true, "Folder/Middle/Contained/Happy/Child");
+	assert_is_ignored(false, "Folder/Middle/Contained/Not/Happy/Child");
+	assert_is_ignored(true, "Folder/Middle/More/More/Contained/Happy/Child");
+	assert_is_ignored(false, "Folder/Middle/More/More/Contained/Not/Happy/Child");
+}
+
+void test_attr_ignore__more_starstar_cases(void)
+{
+	cl_must_pass(p_unlink("attr/.gitignore"));
+	cl_git_mkfile(
+		"attr/dir/.gitignore",
+		"sub/**/*.html\n");
+
+	assert_is_ignored(false, "aaa.html");
+	assert_is_ignored(false, "dir");
+	assert_is_ignored(false, "dir/sub");
+	assert_is_ignored(true,  "dir/sub/sub2/aaa.html");
+	assert_is_ignored(true,  "dir/sub/aaa.html");
+	assert_is_ignored(false, "dir/aaa.html");
+	assert_is_ignored(false, "sub");
+	assert_is_ignored(false, "sub/aaa.html");
+	assert_is_ignored(false, "sub/sub2/aaa.html");
+}
+
+void test_attr_ignore__leading_stars(void)
+{
+	cl_git_rewritefile(
+		"attr/.gitignore",
+		"*/onestar\n"
+		"**/twostars\n"
+		"*/parent1/kid1/*\n"
+		"**/parent2/kid2/*\n");
+
+	assert_is_ignored(true, "dir1/onestar");
+	assert_is_ignored(true, "dir1/onestar/child"); /* in ignored dir */
+	assert_is_ignored(false, "dir1/dir2/onestar");
+
+	assert_is_ignored(true, "dir1/twostars");
+	assert_is_ignored(true, "dir1/twostars/child"); /* in ignored dir */
+	assert_is_ignored(true, "dir1/dir2/twostars");
+	assert_is_ignored(true, "dir1/dir2/twostars/child"); /* in ignored dir */
+	assert_is_ignored(true, "dir1/dir2/dir3/twostars");
+
+	assert_is_ignored(true, "dir1/parent1/kid1/file");
+	assert_is_ignored(true, "dir1/parent1/kid1/file/inside/parent");
+	assert_is_ignored(false, "dir1/dir2/parent1/kid1/file");
+	assert_is_ignored(false, "dir1/parent1/file");
+	assert_is_ignored(false, "dir1/kid1/file");
+
+	assert_is_ignored(true, "dir1/parent2/kid2/file");
+	assert_is_ignored(true, "dir1/parent2/kid2/file/inside/parent");
+	assert_is_ignored(true, "dir1/dir2/parent2/kid2/file");
+	assert_is_ignored(true, "dir1/dir2/dir3/parent2/kid2/file");
+	assert_is_ignored(false, "dir1/parent2/file");
+	assert_is_ignored(false, "dir1/kid2/file");
+}
+
+void test_attr_ignore__skip_gitignore_directory(void)
+{
+	cl_git_rewritefile("attr/.git/info/exclude", "/NewFolder\n/NewFolder/NewFolder");
+	p_unlink("attr/.gitignore");
+	cl_assert(!git_path_exists("attr/.gitignore"));
+	p_mkdir("attr/.gitignore", 0777);
+	cl_git_mkfile("attr/.gitignore/garbage.txt", "new_file\n");
+
+	assert_is_ignored(false, "File.txt");
+	assert_is_ignored(true, "NewFolder");
+	assert_is_ignored(true, "NewFolder/NewFolder");
+	assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
+}
+
+void test_attr_ignore__subdirectory_gitignore(void)
+{
+	p_unlink("attr/.gitignore");
+	cl_assert(!git_path_exists("attr/.gitignore"));
+	cl_git_mkfile(
+		"attr/.gitignore",
+		"file1\n");
+	p_mkdir("attr/dir", 0777);
+	cl_git_mkfile(
+		"attr/dir/.gitignore",
+		"file2/\n");
+
+	assert_is_ignored(true, "file1");
+	assert_is_ignored(true, "dir/file1");
+	assert_is_ignored(true, "dir/file2/actual_file");  /* in ignored dir */
+	assert_is_ignored(false, "dir/file3");
+}
+
+void test_attr_ignore__expand_tilde_to_homedir(void)
+{
+	git_config *cfg;
+
+	assert_is_ignored(false, "example.global_with_tilde");
+
+	cl_fake_home();
+
+	/* construct fake home with fake global excludes */
+	cl_git_mkfile("home/globalexclude", "# found me\n*.global_with_tilde\n");
+
+	cl_git_pass(git_repository_config(&cfg, g_repo));
+	cl_git_pass(git_config_set_string(cfg, "core.excludesfile", "~/globalexclude"));
+	git_config_free(cfg);
+
+	git_attr_cache_flush(g_repo); /* must reset to pick up change */
+
+	assert_is_ignored(true, "example.global_with_tilde");
+
+	cl_git_pass(git_futils_rmdir_r("home", NULL, GIT_RMDIR_REMOVE_FILES));
+
+	cl_fake_home_cleanup(NULL);
+
+	git_attr_cache_flush(g_repo); /* must reset to pick up change */
+
+	assert_is_ignored(false, "example.global_with_tilde");
+}
+
+/* Ensure that the .gitignore in the subdirectory only affects
+ * items in the subdirectory. */
+void test_attr_ignore__gitignore_in_subdir(void)
+{
+	cl_git_rmfile("attr/.gitignore");
+
+	cl_must_pass(p_mkdir("attr/dir1", 0777));
+	cl_must_pass(p_mkdir("attr/dir1/dir2", 0777));
+	cl_must_pass(p_mkdir("attr/dir1/dir2/dir3", 0777));
+
+	cl_git_mkfile("attr/dir1/dir2/dir3/.gitignore", "dir1/\ndir1/subdir/");
+
+	assert_is_ignored(false, "dir1/file");
+	assert_is_ignored(false, "dir1/dir2/file");
+	assert_is_ignored(false, "dir1/dir2/dir3/file");
+	assert_is_ignored(true,  "dir1/dir2/dir3/dir1/file");
+	assert_is_ignored(true,  "dir1/dir2/dir3/dir1/subdir/foo");
+
+	if (cl_repo_get_bool(g_repo, "core.ignorecase")) {
+		cl_git_mkfile("attr/dir1/dir2/dir3/.gitignore", "DiR1/\nDiR1/subdir/\n");
+
+		assert_is_ignored(false, "dir1/file");
+		assert_is_ignored(false, "dir1/dir2/file");
+		assert_is_ignored(false, "dir1/dir2/dir3/file");
+		assert_is_ignored(true,  "dir1/dir2/dir3/dir1/file");
+		assert_is_ignored(true,  "dir1/dir2/dir3/dir1/subdir/foo");
+	}
+}
+
+/* Ensure that files do not match folder cases */
+void test_attr_ignore__dont_ignore_files_for_folder(void)
+{
+	cl_git_rmfile("attr/.gitignore");
+
+	cl_git_mkfile("attr/dir/.gitignore", "test/\n");
+
+	/* Create "test" as a file; ensure it is not ignored. */
+	cl_git_mkfile("attr/dir/test", "This is a file.");
+
+	assert_is_ignored(false, "dir/test");
+	if (cl_repo_get_bool(g_repo, "core.ignorecase"))
+		assert_is_ignored(false, "dir/TeSt");
+
+	/* Create "test" as a directory; ensure it is ignored. */
+	cl_git_rmfile("attr/dir/test");
+	cl_must_pass(p_mkdir("attr/dir/test", 0777));
+
+	assert_is_ignored(true, "dir/test");
+	if (cl_repo_get_bool(g_repo, "core.ignorecase"))
+		assert_is_ignored(true, "dir/TeSt");
+
+	/* Remove "test" entirely; ensure it is not ignored.
+	 * (As it doesn't exist, it is not a directory.)
+	 */
+	cl_must_pass(p_rmdir("attr/dir/test"));
+
+	assert_is_ignored(false, "dir/test");
+	if (cl_repo_get_bool(g_repo, "core.ignorecase"))
+		assert_is_ignored(false, "dir/TeSt");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/lookup.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/lookup.c
new file mode 100755
index 0000000..71e87cb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/lookup.c
@@ -0,0 +1,262 @@
+#include "clar_libgit2.h"
+#include "attr_file.h"
+
+#include "attr_expect.h"
+
+void test_attr_lookup__simple(void)
+{
+	git_attr_file *file;
+	git_attr_path path;
+	const char *value = NULL;
+
+	cl_git_pass(git_attr_file__load_standalone(&file, cl_fixture("attr/attr0")));
+	cl_assert_equal_s(cl_fixture("attr/attr0"), file->entry->path);
+	cl_assert(file->rules.length == 1);
+
+	cl_git_pass(git_attr_path__init(&path, "test", NULL, GIT_DIR_FLAG_UNKNOWN));
+	cl_assert_equal_s("test", path.path);
+	cl_assert_equal_s("test", path.basename);
+	cl_assert(!path.is_dir);
+
+	cl_git_pass(git_attr_file__lookup_one(file,&path,"binary",&value));
+	cl_assert(GIT_ATTR_TRUE(value));
+
+	cl_git_pass(git_attr_file__lookup_one(file,&path,"missing",&value));
+	cl_assert(!value);
+
+	git_attr_path__free(&path);
+	git_attr_file__free(file);
+}
+
+static void run_test_cases(git_attr_file *file, struct attr_expected *cases, int force_dir)
+{
+	git_attr_path path;
+	const char *value = NULL;
+	struct attr_expected *c;
+	int error;
+
+	for (c = cases; c->path != NULL; c++) {
+		cl_git_pass(git_attr_path__init(&path, c->path, NULL, GIT_DIR_FLAG_UNKNOWN));
+
+		if (force_dir)
+			path.is_dir = 1;
+
+		error = git_attr_file__lookup_one(file,&path,c->attr,&value);
+		cl_git_pass(error);
+
+		attr_check_expected(c->expected, c->expected_str, c->attr, value);
+
+		git_attr_path__free(&path);
+	}
+}
+
+void test_attr_lookup__match_variants(void)
+{
+	git_attr_file *file;
+	git_attr_path path;
+
+	struct attr_expected dir_cases[] = {
+		{ "pat2", "attr2", EXPECT_TRUE, NULL },
+		{ "/testing/for/pat2", "attr2", EXPECT_TRUE, NULL },
+		{ "/not/pat2/yousee", "attr2", EXPECT_UNDEFINED, NULL },
+		{ "/fun/fun/fun/pat4.dir", "attr4", EXPECT_TRUE, NULL },
+		{ "foo.pat5", "attr5", EXPECT_TRUE, NULL },
+		{ NULL, NULL, 0, NULL }
+	};
+
+	struct attr_expected cases[] = {
+		/* pat0 -> simple match */
+		{ "pat0", "attr0", EXPECT_TRUE, NULL },
+		{ "/testing/for/pat0", "attr0", EXPECT_TRUE, NULL },
+		{ "relative/to/pat0", "attr0", EXPECT_TRUE, NULL },
+		{ "this-contains-pat0-inside", "attr0", EXPECT_UNDEFINED, NULL },
+		{ "this-aint-right", "attr0", EXPECT_UNDEFINED, NULL },
+		{ "/this/pat0/dont/match", "attr0", EXPECT_UNDEFINED, NULL },
+		/* negative match */
+		{ "pat0", "attr1", EXPECT_TRUE, NULL },
+		{ "pat1", "attr1", EXPECT_UNDEFINED, NULL },
+		{ "/testing/for/pat1", "attr1", EXPECT_UNDEFINED, NULL },
+		{ "/testing/for/pat0", "attr1", EXPECT_TRUE, NULL },
+		{ "/testing/for/pat1/inside", "attr1", EXPECT_TRUE, NULL },
+		{ "misc", "attr1", EXPECT_TRUE, NULL },
+		/* dir match */
+		{ "pat2", "attr2", EXPECT_UNDEFINED, NULL },
+		{ "/testing/for/pat2", "attr2", EXPECT_UNDEFINED, NULL },
+		{ "/not/pat2/yousee", "attr2", EXPECT_UNDEFINED, NULL },
+		/* path match */
+		{ "pat3file", "attr3", EXPECT_UNDEFINED, NULL },
+		{ "/pat3dir/pat3file", "attr3", EXPECT_TRUE, NULL },
+		{ "pat3dir/pat3file", "attr3", EXPECT_TRUE, NULL },
+		/* pattern* match */
+		{ "pat4.txt", "attr4", EXPECT_TRUE, NULL },
+		{ "/fun/fun/fun/pat4.c", "attr4", EXPECT_TRUE, NULL },
+		{ "pat4.", "attr4", EXPECT_TRUE, NULL },
+		{ "pat4", "attr4", EXPECT_UNDEFINED, NULL },
+		/* *pattern match */
+		{ "foo.pat5", "attr5", EXPECT_TRUE, NULL },
+		{ "/this/is/ok.pat5", "attr5", EXPECT_TRUE, NULL },
+		{ "/this/is/bad.pat5/yousee.txt", "attr5", EXPECT_UNDEFINED, NULL },
+		{ "foo.pat5", "attr100", EXPECT_UNDEFINED, NULL },
+		/* glob match with slashes */
+		{ "foo.pat6", "attr6", EXPECT_UNDEFINED, NULL },
+		{ "pat6/pat6/foobar.pat6", "attr6", EXPECT_TRUE, NULL },
+		{ "pat6/pat6/.pat6", "attr6", EXPECT_TRUE, NULL },
+		{ "pat6/pat6/extra/foobar.pat6", "attr6", EXPECT_UNDEFINED, NULL },
+		{ "/prefix/pat6/pat6/foobar.pat6", "attr6", EXPECT_UNDEFINED, NULL },
+		{ "/pat6/pat6/foobar.pat6", "attr6", EXPECT_TRUE, NULL },
+		/* complex pattern */
+		{ "pat7a12z", "attr7", EXPECT_TRUE, NULL },
+		{ "pat7e__x", "attr7", EXPECT_TRUE, NULL },
+		{ "pat7b/1y", "attr7", EXPECT_UNDEFINED, NULL }, /* ? does not match / */
+		{ "pat7e_x", "attr7", EXPECT_UNDEFINED, NULL },
+		{ "pat7aaaa", "attr7", EXPECT_UNDEFINED, NULL },
+		{ "pat7zzzz", "attr7", EXPECT_UNDEFINED, NULL },
+		{ "/this/can/be/anything/pat7a12z", "attr7", EXPECT_TRUE, NULL },
+		{ "but/it/still/must/match/pat7aaaa", "attr7", EXPECT_UNDEFINED, NULL },
+		{ "pat7aaay.fail", "attr7", EXPECT_UNDEFINED, NULL },
+		/* pattern with spaces */
+		{ "pat8 with spaces", "attr8", EXPECT_TRUE, NULL },
+		{ "/gotta love/pat8 with spaces", "attr8", EXPECT_TRUE, NULL },
+		{ "failing pat8 with spaces", "attr8", EXPECT_UNDEFINED, NULL },
+		{ "spaces", "attr8", EXPECT_UNDEFINED, NULL },
+		/* pattern at eof */
+		{ "pat9", "attr9", EXPECT_TRUE, NULL },
+		{ "/eof/pat9", "attr9", EXPECT_TRUE, NULL },
+		{ "pat", "attr9", EXPECT_UNDEFINED, NULL },
+		{ "at9", "attr9", EXPECT_UNDEFINED, NULL },
+		{ "pat9.fail", "attr9", EXPECT_UNDEFINED, NULL },
+		/* sentinel at end */
+		{ NULL, NULL, 0, NULL }
+	};
+
+	cl_git_pass(git_attr_file__load_standalone(&file, cl_fixture("attr/attr1")));
+	cl_assert_equal_s(cl_fixture("attr/attr1"), file->entry->path);
+	cl_assert(file->rules.length == 10);
+
+	cl_git_pass(git_attr_path__init(&path, "/testing/for/pat0", NULL, GIT_DIR_FLAG_UNKNOWN));
+	cl_assert_equal_s("pat0", path.basename);
+
+	run_test_cases(file, cases, 0);
+	run_test_cases(file, dir_cases, 1);
+
+	git_attr_file__free(file);
+	git_attr_path__free(&path);
+}
+
+void test_attr_lookup__assign_variants(void)
+{
+	git_attr_file *file;
+
+	struct attr_expected cases[] = {
+		/* pat0 -> simple assign */
+		{ "pat0", "simple", EXPECT_TRUE, NULL },
+		{ "/testing/pat0", "simple", EXPECT_TRUE, NULL },
+		{ "pat0", "fail", EXPECT_UNDEFINED, NULL },
+		{ "/testing/pat0", "fail", EXPECT_UNDEFINED, NULL },
+		/* negative assign */
+		{ "pat1", "neg", EXPECT_FALSE, NULL },
+		{ "/testing/pat1", "neg", EXPECT_FALSE, NULL },
+		{ "pat1", "fail", EXPECT_UNDEFINED, NULL },
+		{ "/testing/pat1", "fail", EXPECT_UNDEFINED, NULL },
+		/* forced undef */
+		{ "pat1", "notundef", EXPECT_TRUE, NULL },
+		{ "pat2", "notundef", EXPECT_UNDEFINED, NULL },
+		{ "/lead/in/pat1", "notundef", EXPECT_TRUE, NULL },
+		{ "/lead/in/pat2", "notundef", EXPECT_UNDEFINED, NULL },
+		/* assign value */
+		{ "pat3", "assigned", EXPECT_STRING, "test-value" },
+		{ "pat3", "notassigned", EXPECT_UNDEFINED, NULL },
+		/* assign value */
+		{ "pat4", "rule-with-more-chars", EXPECT_STRING, "value-with-more-chars" },
+		{ "pat4", "notassigned-rule-with-more-chars", EXPECT_UNDEFINED, NULL },
+		/* empty assignments */
+		{ "pat5", "empty", EXPECT_TRUE, NULL },
+		{ "pat6", "negempty", EXPECT_FALSE, NULL },
+		/* multiple assignment */
+		{ "pat7", "multiple", EXPECT_TRUE, NULL },
+		{ "pat7", "single", EXPECT_FALSE, NULL },
+		{ "pat7", "values", EXPECT_STRING, "1" },
+		{ "pat7", "also", EXPECT_STRING, "a-really-long-value/*" },
+		{ "pat7", "happy", EXPECT_STRING, "yes!" },
+		{ "pat8", "again", EXPECT_TRUE, NULL },
+		{ "pat8", "another", EXPECT_STRING, "12321" },
+		/* bad assignment */
+		{ "patbad0", "simple", EXPECT_UNDEFINED, NULL },
+		{ "patbad0", "notundef", EXPECT_TRUE, NULL },
+		{ "patbad1", "simple", EXPECT_UNDEFINED, NULL },
+		/* eof assignment */
+		{ "pat9", "at-eof", EXPECT_FALSE, NULL },
+		/* sentinel at end */
+		{ NULL, NULL, 0, NULL }
+	};
+
+	cl_git_pass(git_attr_file__load_standalone(&file, cl_fixture("attr/attr2")));
+	cl_assert(file->rules.length == 11);
+
+	run_test_cases(file, cases, 0);
+
+	git_attr_file__free(file);
+}
+
+void test_attr_lookup__check_attr_examples(void)
+{
+	git_attr_file *file;
+
+	struct attr_expected cases[] = {
+		{ "foo.java", "diff", EXPECT_STRING, "java" },
+		{ "foo.java", "crlf", EXPECT_FALSE, NULL },
+		{ "foo.java", "myAttr", EXPECT_TRUE, NULL },
+		{ "foo.java", "other", EXPECT_UNDEFINED, NULL },
+		{ "/prefix/dir/foo.java", "diff", EXPECT_STRING, "java" },
+		{ "/prefix/dir/foo.java", "crlf", EXPECT_FALSE, NULL },
+		{ "/prefix/dir/foo.java", "myAttr", EXPECT_TRUE, NULL },
+		{ "/prefix/dir/foo.java", "other", EXPECT_UNDEFINED, NULL },
+		{ "NoMyAttr.java", "crlf", EXPECT_FALSE, NULL },
+		{ "NoMyAttr.java", "myAttr", EXPECT_UNDEFINED, NULL },
+		{ "NoMyAttr.java", "other", EXPECT_UNDEFINED, NULL },
+		{ "/prefix/dir/NoMyAttr.java", "crlf", EXPECT_FALSE, NULL },
+		{ "/prefix/dir/NoMyAttr.java", "myAttr", EXPECT_UNDEFINED, NULL },
+		{ "/prefix/dir/NoMyAttr.java", "other", EXPECT_UNDEFINED, NULL },
+		{ "README", "caveat", EXPECT_STRING, "unspecified" },
+		{ "/specific/path/README", "caveat", EXPECT_STRING, "unspecified" },
+		{ "README", "missing", EXPECT_UNDEFINED, NULL },
+		{ "/specific/path/README", "missing", EXPECT_UNDEFINED, NULL },
+		/* sentinel at end */
+		{ NULL, NULL, 0, NULL }
+	};
+
+	cl_git_pass(git_attr_file__load_standalone(&file, cl_fixture("attr/attr3")));
+	cl_assert(file->rules.length == 3);
+
+	run_test_cases(file, cases, 0);
+
+	git_attr_file__free(file);
+}
+
+void test_attr_lookup__from_buffer(void)
+{
+	git_attr_file *file;
+
+	struct attr_expected cases[] = {
+		{ "abc", "foo", EXPECT_TRUE, NULL },
+		{ "abc", "bar", EXPECT_TRUE, NULL },
+		{ "abc", "baz", EXPECT_TRUE, NULL },
+		{ "aaa", "foo", EXPECT_TRUE, NULL },
+		{ "aaa", "bar", EXPECT_UNDEFINED, NULL },
+		{ "aaa", "baz", EXPECT_TRUE, NULL },
+		{ "qqq", "foo", EXPECT_UNDEFINED, NULL },
+		{ "qqq", "bar", EXPECT_UNDEFINED, NULL },
+		{ "qqq", "baz", EXPECT_TRUE, NULL },
+		{ NULL, NULL, 0, NULL }
+	};
+
+	cl_git_pass(git_attr_file__new(&file, NULL, 0));
+
+	cl_git_pass(git_attr_file__parse_buffer(NULL, file, "a* foo\nabc bar\n* baz"));
+
+	cl_assert(file->rules.length == 3);
+
+	run_test_cases(file, cases, 0);
+
+	git_attr_file__free(file);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/repo.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/repo.c
new file mode 100755
index 0000000..8baf506
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/attr/repo.c
@@ -0,0 +1,378 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "git2/attr.h"
+#include "attr.h"
+
+#include "attr_expect.h"
+#include "git2/sys/repository.h"
+
+static git_repository *g_repo = NULL;
+
+void test_attr_repo__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("attr");
+}
+
+void test_attr_repo__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+	g_repo = NULL;
+}
+
+static struct attr_expected get_one_test_cases[] = {
+	{ "root_test1", "repoattr", EXPECT_TRUE, NULL },
+	{ "root_test1", "rootattr", EXPECT_TRUE, NULL },
+	{ "root_test1", "missingattr", EXPECT_UNDEFINED, NULL },
+	{ "root_test1", "subattr", EXPECT_UNDEFINED, NULL },
+	{ "root_test1", "negattr", EXPECT_UNDEFINED, NULL },
+	{ "root_test2", "repoattr", EXPECT_TRUE, NULL },
+	{ "root_test2", "rootattr", EXPECT_FALSE, NULL },
+	{ "root_test2", "missingattr", EXPECT_UNDEFINED, NULL },
+	{ "root_test2", "multiattr", EXPECT_FALSE, NULL },
+	{ "root_test3", "repoattr", EXPECT_TRUE, NULL },
+	{ "root_test3", "rootattr", EXPECT_UNDEFINED, NULL },
+	{ "root_test3", "multiattr", EXPECT_STRING, "3" },
+	{ "root_test3", "multi2", EXPECT_UNDEFINED, NULL },
+	{ "sub/subdir_test1", "repoattr", EXPECT_TRUE, NULL },
+	{ "sub/subdir_test1", "rootattr", EXPECT_TRUE, NULL },
+	{ "sub/subdir_test1", "missingattr", EXPECT_UNDEFINED, NULL },
+	{ "sub/subdir_test1", "subattr", EXPECT_STRING, "yes" },
+	{ "sub/subdir_test1", "negattr", EXPECT_FALSE, NULL },
+	{ "sub/subdir_test1", "another", EXPECT_UNDEFINED, NULL },
+	{ "sub/subdir_test2.txt", "repoattr", EXPECT_TRUE, NULL },
+	{ "sub/subdir_test2.txt", "rootattr", EXPECT_TRUE, NULL },
+	{ "sub/subdir_test2.txt", "missingattr", EXPECT_UNDEFINED, NULL },
+	{ "sub/subdir_test2.txt", "subattr", EXPECT_STRING, "yes" },
+	{ "sub/subdir_test2.txt", "negattr", EXPECT_FALSE, NULL },
+	{ "sub/subdir_test2.txt", "another", EXPECT_STRING, "zero" },
+	{ "sub/subdir_test2.txt", "reposub", EXPECT_TRUE, NULL },
+	{ "sub/sub/subdir.txt", "another", EXPECT_STRING, "one" },
+	{ "sub/sub/subdir.txt", "reposubsub", EXPECT_TRUE, NULL },
+	{ "sub/sub/subdir.txt", "reposub", EXPECT_UNDEFINED, NULL },
+	{ "does-not-exist", "foo", EXPECT_STRING, "yes" },
+	{ "sub/deep/file", "deepdeep", EXPECT_TRUE, NULL },
+	{ "sub/sub/d/no", "test", EXPECT_STRING, "a/b/d/*" },
+	{ "sub/sub/d/yes", "test", EXPECT_UNDEFINED, NULL },
+};
+
+void test_attr_repo__get_one(void)
+{
+	int i;
+
+	for (i = 0; i < (int)ARRAY_SIZE(get_one_test_cases); ++i) {
+		struct attr_expected *scan = &get_one_test_cases[i];
+		const char *value;
+
+		cl_git_pass(git_attr_get(&value, g_repo, 0, scan->path, scan->attr));
+		attr_check_expected(
+			scan->expected, scan->expected_str, scan->attr, value);
+	}
+
+	cl_assert(git_attr_cache__is_cached(
+		g_repo, GIT_ATTR_FILE__FROM_FILE, ".git/info/attributes"));
+	cl_assert(git_attr_cache__is_cached(
+		g_repo, GIT_ATTR_FILE__FROM_FILE, ".gitattributes"));
+	cl_assert(git_attr_cache__is_cached(
+		g_repo, GIT_ATTR_FILE__FROM_FILE, "sub/.gitattributes"));
+}
+
+void test_attr_repo__get_one_start_deep(void)
+{
+	int i;
+
+	for (i = (int)ARRAY_SIZE(get_one_test_cases) - 1; i >= 0; --i) {
+		struct attr_expected *scan = &get_one_test_cases[i];
+		const char *value;
+
+		cl_git_pass(git_attr_get(&value, g_repo, 0, scan->path, scan->attr));
+		attr_check_expected(
+			scan->expected, scan->expected_str, scan->attr, value);
+	}
+
+	cl_assert(git_attr_cache__is_cached(
+		g_repo, GIT_ATTR_FILE__FROM_FILE, ".git/info/attributes"));
+	cl_assert(git_attr_cache__is_cached(
+		g_repo, GIT_ATTR_FILE__FROM_FILE, ".gitattributes"));
+	cl_assert(git_attr_cache__is_cached(
+		g_repo, GIT_ATTR_FILE__FROM_FILE, "sub/.gitattributes"));
+}
+
+void test_attr_repo__get_many(void)
+{
+	const char *names[4] = { "repoattr", "rootattr", "missingattr", "subattr" };
+	const char *values[4];
+
+	cl_git_pass(git_attr_get_many(values, g_repo, 0, "root_test1", 4, names));
+
+	cl_assert(GIT_ATTR_TRUE(values[0]));
+	cl_assert(GIT_ATTR_TRUE(values[1]));
+	cl_assert(GIT_ATTR_UNSPECIFIED(values[2]));
+	cl_assert(GIT_ATTR_UNSPECIFIED(values[3]));
+
+	cl_git_pass(git_attr_get_many(values, g_repo, 0, "root_test2", 4, names));
+
+	cl_assert(GIT_ATTR_TRUE(values[0]));
+	cl_assert(GIT_ATTR_FALSE(values[1]));
+	cl_assert(GIT_ATTR_UNSPECIFIED(values[2]));
+	cl_assert(GIT_ATTR_UNSPECIFIED(values[3]));
+
+	cl_git_pass(git_attr_get_many(values, g_repo, 0, "sub/subdir_test1", 4, names));
+
+	cl_assert(GIT_ATTR_TRUE(values[0]));
+	cl_assert(GIT_ATTR_TRUE(values[1]));
+	cl_assert(GIT_ATTR_UNSPECIFIED(values[2]));
+	cl_assert_equal_s("yes", values[3]);
+}
+
+void test_attr_repo__get_many_in_place(void)
+{
+	const char *vals[4] = { "repoattr", "rootattr", "missingattr", "subattr" };
+
+	/* it should be legal to look up values into the same array that has
+	 * the attribute names, overwriting each name as the value is found.
+	 */
+
+	cl_git_pass(git_attr_get_many(vals, g_repo, 0, "sub/subdir_test1", 4, vals));
+
+	cl_assert(GIT_ATTR_TRUE(vals[0]));
+	cl_assert(GIT_ATTR_TRUE(vals[1]));
+	cl_assert(GIT_ATTR_UNSPECIFIED(vals[2]));
+	cl_assert_equal_s("yes", vals[3]);
+}
+
+static int count_attrs(
+	const char *name,
+	const char *value,
+	void *payload)
+{
+	GIT_UNUSED(name);
+	GIT_UNUSED(value);
+
+	*((int *)payload) += 1;
+
+	return 0;
+}
+
+#define CANCEL_VALUE 12345
+
+static int cancel_iteration(
+	const char *name,
+	const char *value,
+	void *payload)
+{
+	GIT_UNUSED(name);
+	GIT_UNUSED(value);
+
+	*((int *)payload) -= 1;
+
+	if (*((int *)payload) < 0)
+		return CANCEL_VALUE;
+
+	return 0;
+}
+
+void test_attr_repo__foreach(void)
+{
+	int count;
+
+	count = 0;
+	cl_git_pass(git_attr_foreach(
+		g_repo, 0, "root_test1", &count_attrs, &count));
+	cl_assert(count == 2);
+
+	count = 0;
+	cl_git_pass(git_attr_foreach(g_repo, 0, "sub/subdir_test1",
+		&count_attrs, &count));
+	cl_assert(count == 4); /* repoattr, rootattr, subattr, negattr */
+
+	count = 0;
+	cl_git_pass(git_attr_foreach(g_repo, 0, "sub/subdir_test2.txt",
+		&count_attrs, &count));
+	cl_assert(count == 6); /* repoattr, rootattr, subattr, reposub, negattr, another */
+
+	count = 2;
+	cl_assert_equal_i(
+		CANCEL_VALUE, git_attr_foreach(
+			g_repo, 0, "sub/subdir_test1", &cancel_iteration, &count)
+	);
+}
+
+void test_attr_repo__manpage_example(void)
+{
+	const char *value;
+
+	cl_git_pass(git_attr_get(&value, g_repo, 0, "sub/abc", "foo"));
+	cl_assert(GIT_ATTR_TRUE(value));
+
+	cl_git_pass(git_attr_get(&value, g_repo, 0, "sub/abc", "bar"));
+	cl_assert(GIT_ATTR_UNSPECIFIED(value));
+
+	cl_git_pass(git_attr_get(&value, g_repo, 0, "sub/abc", "baz"));
+	cl_assert(GIT_ATTR_FALSE(value));
+
+	cl_git_pass(git_attr_get(&value, g_repo, 0, "sub/abc", "merge"));
+	cl_assert_equal_s("filfre", value);
+
+	cl_git_pass(git_attr_get(&value, g_repo, 0, "sub/abc", "frotz"));
+	cl_assert(GIT_ATTR_UNSPECIFIED(value));
+}
+
+void test_attr_repo__macros(void)
+{
+	const char *names[5] = { "rootattr", "binary", "diff", "crlf", "frotz" };
+	const char *names2[5] = { "mymacro", "positive", "negative", "rootattr", "another" };
+	const char *names3[3] = { "macro2", "multi2", "multi3" };
+	const char *values[5];
+
+	cl_git_pass(git_attr_get_many(values, g_repo, 0, "binfile", 5, names));
+
+	cl_assert(GIT_ATTR_TRUE(values[0]));
+	cl_assert(GIT_ATTR_TRUE(values[1]));
+	cl_assert(GIT_ATTR_FALSE(values[2]));
+	cl_assert(GIT_ATTR_FALSE(values[3]));
+	cl_assert(GIT_ATTR_UNSPECIFIED(values[4]));
+
+	cl_git_pass(git_attr_get_many(values, g_repo, 0, "macro_test", 5, names2));
+
+	cl_assert(GIT_ATTR_TRUE(values[0]));
+	cl_assert(GIT_ATTR_TRUE(values[1]));
+	cl_assert(GIT_ATTR_FALSE(values[2]));
+	cl_assert(GIT_ATTR_UNSPECIFIED(values[3]));
+	cl_assert_equal_s("77", values[4]);
+
+	cl_git_pass(git_attr_get_many(values, g_repo, 0, "macro_test", 3, names3));
+
+	cl_assert(GIT_ATTR_TRUE(values[0]));
+	cl_assert(GIT_ATTR_FALSE(values[1]));
+	cl_assert_equal_s("answer", values[2]);
+}
+
+void test_attr_repo__bad_macros(void)
+{
+	const char *names[6] = { "rootattr", "positive", "negative",
+		"firstmacro", "secondmacro", "thirdmacro" };
+	const char *values[6];
+
+	cl_git_pass(git_attr_get_many(values, g_repo, 0, "macro_bad", 6, names));
+
+	/* these three just confirm that the "mymacro" rule ran */
+	cl_assert(GIT_ATTR_UNSPECIFIED(values[0]));
+	cl_assert(GIT_ATTR_TRUE(values[1]));
+	cl_assert(GIT_ATTR_FALSE(values[2]));
+
+	/* file contains:
+	 *     # let's try some malicious macro defs
+	 *     [attr]firstmacro -thirdmacro -secondmacro
+	 *     [attr]secondmacro firstmacro -firstmacro
+	 *     [attr]thirdmacro secondmacro=hahaha -firstmacro
+	 *     macro_bad firstmacro secondmacro thirdmacro
+	 *
+	 * firstmacro assignment list ends up with:
+	 *     -thirdmacro -secondmacro
+	 * secondmacro assignment list expands "firstmacro" and ends up with:
+	 *     -thirdmacro -secondmacro -firstmacro
+	 * thirdmacro assignment don't expand so list ends up with:
+	 *     secondmacro="hahaha"
+	 *
+	 * macro_bad assignment list ends up with:
+	 *     -thirdmacro -secondmacro firstmacro &&
+	 *     -thirdmacro -secondmacro -firstmacro secondmacro &&
+	 *     secondmacro="hahaha" thirdmacro
+	 *
+	 * so summary results should be:
+	 *     -firstmacro secondmacro="hahaha" thirdmacro
+	 */
+	cl_assert(GIT_ATTR_FALSE(values[3]));
+	cl_assert_equal_s("hahaha", values[4]);
+	cl_assert(GIT_ATTR_TRUE(values[5]));
+}
+
+#define CONTENT "I'm going to be dynamically processed\r\n" \
+	"And my line endings...\r\n" \
+	"...are going to be\n" \
+	"normalized!\r\n"
+
+#define GITATTR "* text=auto\n" \
+	"*.txt text\n" \
+	"*.data binary\n"
+
+static void add_to_workdir(const char *filename, const char *content)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_joinpath(&buf, "attr", filename));
+	cl_git_rewritefile(git_buf_cstr(&buf), content);
+
+	git_buf_free(&buf);
+}
+
+static void assert_proper_normalization(git_index *index, const char *filename, const char *expected_sha)
+{
+	size_t index_pos;
+	const git_index_entry *entry;
+
+	add_to_workdir(filename, CONTENT);
+	cl_git_pass(git_index_add_bypath(index, filename));
+
+	cl_assert(!git_index_find(&index_pos, index, filename));
+
+	entry = git_index_get_byindex(index, index_pos);
+	cl_assert_equal_i(0, git_oid_streq(&entry->id, expected_sha));
+}
+
+void test_attr_repo__staging_properly_normalizes_line_endings_according_to_gitattributes_directives(void)
+{
+	git_index* index;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	add_to_workdir(".gitattributes", GITATTR);
+
+	assert_proper_normalization(index, "text.txt", "22c74203bace3c2e950278c7ab08da0fca9f4e9b");
+	assert_proper_normalization(index, "huh.dunno", "22c74203bace3c2e950278c7ab08da0fca9f4e9b");
+	assert_proper_normalization(index, "binary.data", "66eeff1fcbacf589e6d70aa70edd3fce5be2b37c");
+
+	git_index_free(index);
+}
+
+void test_attr_repo__bare_repo_with_index(void)
+{
+	const char *names[4] = { "test1", "test2", "test3", "test4" };
+	const char *values[4];
+	git_index *index;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_mkfile(
+		"attr/.gitattributes",
+		"*.txt test1 test2=foobar -test3\n"
+		"trial.txt -test1 test2=barfoo !test3 test4\n");
+	cl_git_pass(git_index_add_bypath(index, ".gitattributes"));
+	git_index_free(index);
+
+	cl_must_pass(p_unlink("attr/.gitattributes"));
+	cl_assert(!git_path_exists("attr/.gitattributes"));
+
+	cl_git_pass(git_repository_set_bare(g_repo));
+
+	cl_git_pass(git_attr_get_many(values, g_repo, 0, "file.txt", 4, names));
+
+	cl_assert(GIT_ATTR_TRUE(values[0]));
+	cl_assert_equal_s("foobar", values[1]);
+	cl_assert(GIT_ATTR_FALSE(values[2]));
+	cl_assert(GIT_ATTR_UNSPECIFIED(values[3]));
+
+	cl_git_pass(git_attr_get_many(values, g_repo, 0, "trial.txt", 4, names));
+
+	cl_assert(GIT_ATTR_FALSE(values[0]));
+	cl_assert_equal_s("barfoo", values[1]);
+	cl_assert(GIT_ATTR_UNSPECIFIED(values[2]));
+	cl_assert(GIT_ATTR_TRUE(values[3]));
+
+	cl_git_pass(git_attr_get_many(values, g_repo, 0, "sub/sub/subdir.txt", 4, names));
+
+	cl_assert(GIT_ATTR_TRUE(values[0]));
+	cl_assert_equal_s("foobar", values[1]);
+	cl_assert(GIT_ATTR_FALSE(values[2]));
+	cl_assert(GIT_ATTR_UNSPECIFIED(values[3]));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/blame_helpers.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/blame_helpers.c
new file mode 100755
index 0000000..b305ba1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/blame_helpers.c
@@ -0,0 +1,67 @@
+#include "blame_helpers.h"
+
+void hunk_message(size_t idx, const git_blame_hunk *hunk, const char *fmt, ...)
+{
+	va_list arglist;
+
+	printf("Hunk %"PRIuZ" (line %d +%d): ", idx,
+			hunk->final_start_line_number, hunk->lines_in_hunk-1);
+
+	va_start(arglist, fmt);
+	vprintf(fmt, arglist);
+	va_end(arglist);
+
+	printf("\n");
+}
+
+void check_blame_hunk_index(git_repository *repo, git_blame *blame, int idx,
+		int start_line, int len, char boundary, const char *commit_id, const char *orig_path)
+{
+	char expected[GIT_OID_HEXSZ+1] = {0}, actual[GIT_OID_HEXSZ+1] = {0};
+	const git_blame_hunk *hunk = git_blame_get_hunk_byindex(blame, idx);
+	cl_assert(hunk);
+
+	if (!strncmp(commit_id, "0000", 4)) {
+		strcpy(expected, "0000000000000000000000000000000000000000");
+	} else {
+		git_object *obj;
+		cl_git_pass(git_revparse_single(&obj, repo, commit_id));
+		git_oid_fmt(expected, git_object_id(obj));
+		git_object_free(obj);
+	}
+
+	if (hunk->final_start_line_number != start_line) {
+		hunk_message(idx, hunk, "mismatched start line number: expected %d, got %d",
+				start_line, hunk->final_start_line_number);
+	}
+	cl_assert_equal_i(hunk->final_start_line_number, start_line);
+
+	if (hunk->lines_in_hunk != len) {
+		hunk_message(idx, hunk, "mismatched line count: expected %d, got %d",
+				len, hunk->lines_in_hunk);
+	}
+	cl_assert_equal_i(hunk->lines_in_hunk, len);
+
+	git_oid_fmt(actual, &hunk->final_commit_id);
+	if (strcmp(expected, actual)) {
+		hunk_message(idx, hunk, "has mismatched original id (got %s, expected %s)\n",
+				actual, expected);
+	}
+	cl_assert_equal_s(actual, expected);
+	cl_assert_equal_oid(&hunk->final_commit_id, &hunk->orig_commit_id);
+
+
+	if (strcmp(hunk->orig_path, orig_path)) {
+		hunk_message(idx, hunk, "has mismatched original path (got '%s', expected '%s')\n",
+				hunk->orig_path, orig_path);
+	}
+	cl_assert_equal_s(hunk->orig_path, orig_path);
+
+	if (hunk->boundary != boundary) {
+		hunk_message(idx, hunk, "doesn't match boundary flag (got %d, expected %d)\n",
+				hunk->boundary, boundary);
+	}
+	cl_assert_equal_i(boundary, hunk->boundary);
+}
+
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/blame_helpers.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/blame_helpers.h
new file mode 100755
index 0000000..94321a5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/blame_helpers.h
@@ -0,0 +1,16 @@
+#include "clar_libgit2.h"
+#include "blame.h"
+
+void hunk_message(size_t idx, const git_blame_hunk *hunk, const char *fmt, ...);
+
+void check_blame_hunk_index(
+		git_repository *repo,
+		git_blame *blame,
+		int idx,
+		int start_line,
+		int len,
+		char boundary,
+		const char *commit_id,
+		const char *orig_path);
+
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/buffer.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/buffer.c
new file mode 100755
index 0000000..340b1dc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/buffer.c
@@ -0,0 +1,166 @@
+#include "blame_helpers.h"
+
+static git_repository *g_repo;
+static git_blame *g_fileblame, *g_bufferblame;
+
+void test_blame_buffer__initialize(void)
+{
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("blametest.git")));
+	cl_git_pass(git_blame_file(&g_fileblame, g_repo, "b.txt", NULL));
+	g_bufferblame = NULL;
+}
+
+void test_blame_buffer__cleanup(void)
+{
+	git_blame_free(g_fileblame);
+	git_blame_free(g_bufferblame);
+	git_repository_free(g_repo);
+}
+
+void test_blame_buffer__added_line(void)
+{
+	const git_blame_hunk *hunk;
+
+	const char *buffer = "\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+\n\
+abcdefg\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
+
+	cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
+	cl_assert_equal_i(5, git_blame_get_hunk_count(g_bufferblame));
+	check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 1, 0, "000000", "b.txt");
+
+	hunk = git_blame_get_hunk_byline(g_bufferblame, 16);
+	cl_assert(hunk);
+	cl_assert_equal_s("Ben Straub", hunk->final_signature->name);
+}
+
+void test_blame_buffer__deleted_line(void)
+{
+	const char *buffer = "\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
+
+	cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
+	check_blame_hunk_index(g_repo, g_bufferblame, 2,  6, 3, 0, "63d671eb", "b.txt");
+	check_blame_hunk_index(g_repo, g_bufferblame, 3,  9, 1, 0, "63d671eb", "b.txt");
+	check_blame_hunk_index(g_repo, g_bufferblame, 4, 10, 5, 0, "aa06ecca", "b.txt");
+}
+
+void test_blame_buffer__add_splits_hunk(void)
+{
+	const char *buffer = "\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+abc\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
+
+	cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
+	check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 2, 0, "63d671eb", "b.txt");
+	check_blame_hunk_index(g_repo, g_bufferblame, 3, 8, 1, 0, "00000000", "b.txt");
+	check_blame_hunk_index(g_repo, g_bufferblame, 4, 9, 3, 0, "63d671eb", "b.txt");
+}
+
+void test_blame_buffer__delete_crosses_hunk_boundary(void)
+{
+	const char *buffer = "\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
+
+	cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
+	check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 1, 0, "63d671eb", "b.txt");
+	check_blame_hunk_index(g_repo, g_bufferblame, 3, 7, 2, 0, "aa06ecca", "b.txt");
+}
+
+void test_blame_buffer__replace_line(void)
+{
+	const char *buffer = "\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+abc\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
+
+	cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
+	check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 1, 0, "63d671eb", "b.txt");
+	check_blame_hunk_index(g_repo, g_bufferblame, 3, 7, 1, 0, "00000000", "b.txt");
+	check_blame_hunk_index(g_repo, g_bufferblame, 4, 8, 3, 0, "63d671eb", "b.txt");
+}
+
+void test_blame_buffer__add_lines_at_end(void)
+{
+	const char *buffer = "\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+\n\
+abc\n\
+def\n";
+	cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
+
+	cl_assert_equal_i(5, git_blame_get_hunk_count(g_bufferblame));
+	check_blame_hunk_index(g_repo, g_bufferblame, 0,  1, 4, 0, "da237394", "b.txt");
+	check_blame_hunk_index(g_repo, g_bufferblame, 1,  5, 1, 1, "b99f7ac0", "b.txt");
+	check_blame_hunk_index(g_repo, g_bufferblame, 2,  6, 5, 0, "63d671eb", "b.txt");
+	check_blame_hunk_index(g_repo, g_bufferblame, 3, 11, 5, 0, "aa06ecca", "b.txt");
+	check_blame_hunk_index(g_repo, g_bufferblame, 4, 16, 2, 0, "00000000", "b.txt");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/getters.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/getters.c
new file mode 100755
index 0000000..66eaeec
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/getters.c
@@ -0,0 +1,56 @@
+#include "clar_libgit2.h"
+
+#include "blame.h"
+
+git_blame *g_blame;
+
+void test_blame_getters__initialize(void)
+{
+	size_t i;
+	git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+
+	git_blame_hunk hunks[] = {
+		{ 3, {{0}},  1, NULL, {{0}}, "a", 0},
+		{ 3, {{0}},  4, NULL, {{0}}, "b", 0},
+		{ 3, {{0}},  7, NULL, {{0}}, "c", 0},
+		{ 3, {{0}}, 10, NULL, {{0}}, "d", 0},
+		{ 3, {{0}}, 13, NULL, {{0}}, "e", 0},
+	};
+
+	g_blame = git_blame__alloc(NULL, opts, "");
+
+	for (i=0; i<5; i++) {
+		git_blame_hunk *h = git__calloc(1, sizeof(git_blame_hunk));
+		h->final_start_line_number = hunks[i].final_start_line_number;
+		h->orig_path = git__strdup(hunks[i].orig_path);
+		h->lines_in_hunk = hunks[i].lines_in_hunk;
+
+		git_vector_insert(&g_blame->hunks, h);
+	}
+}
+
+void test_blame_getters__cleanup(void)
+{
+	git_blame_free(g_blame);
+}
+
+
+void test_blame_getters__byindex(void)
+{
+	const git_blame_hunk *h = git_blame_get_hunk_byindex(g_blame, 2);
+	cl_assert(h);
+	cl_assert_equal_s(h->orig_path, "c");
+
+	h = git_blame_get_hunk_byindex(g_blame, 95);
+	cl_assert_equal_p(h, NULL);
+}
+
+void test_blame_getters__byline(void)
+{
+	const git_blame_hunk *h = git_blame_get_hunk_byline(g_blame, 5);
+	cl_assert(h);
+	cl_assert_equal_s(h->orig_path, "b");
+
+	h = git_blame_get_hunk_byline(g_blame, 95);
+	cl_assert_equal_p(h, NULL);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/harder.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/harder.c
new file mode 100755
index 0000000..e777417
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/harder.c
@@ -0,0 +1,79 @@
+#include "clar_libgit2.h"
+
+#include "blame.h"
+
+
+/**
+ * The test repo has a history that looks like this:
+ *
+ * * (A) bc7c5ac
+ * |\
+ * | * (B) aa06ecc
+ * * | (C) 63d671e
+ * |/  
+ * * (D) da23739
+ * * (E) b99f7ac
+ *
+ */
+
+static git_repository *g_repo = NULL;
+
+void test_blame_harder__initialize(void)
+{
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("blametest.git")));
+}
+
+void test_blame_harder__cleanup(void)
+{
+	git_repository_free(g_repo);
+	g_repo = NULL;
+}
+
+
+
+void test_blame_harder__m(void)
+{
+	/* TODO */
+	git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+
+	GIT_UNUSED(opts);
+
+	opts.flags = GIT_BLAME_TRACK_COPIES_SAME_FILE;
+}
+
+
+void test_blame_harder__c(void)
+{
+	git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+
+	GIT_UNUSED(opts);
+
+	/* Attribute the first hunk in b.txt to (E), since it was cut/pasted from
+	 * a.txt in (D).
+	 */
+	opts.flags = GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES;
+}
+
+void test_blame_harder__cc(void)
+{
+	git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+
+	GIT_UNUSED(opts);
+
+	/* Attribute the second hunk in b.txt to (E), since it was copy/pasted from
+	 * a.txt in (C).
+	 */
+	opts.flags = GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES;
+}
+
+void test_blame_harder__ccc(void)
+{
+	git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+
+	GIT_UNUSED(opts);
+	
+	/* Attribute the third hunk in b.txt to (E).  This hunk was deleted from
+	 * a.txt in (D), but reintroduced in (B).
+	 */
+	opts.flags = GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/simple.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/simple.c
new file mode 100755
index 0000000..83e5e05
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/blame/simple.c
@@ -0,0 +1,324 @@
+#include "blame_helpers.h"
+
+static git_repository *g_repo;
+static git_blame *g_blame;
+
+void test_blame_simple__initialize(void)
+{
+	g_repo = NULL;
+	g_blame = NULL;
+}
+
+void test_blame_simple__cleanup(void)
+{
+	git_blame_free(g_blame);
+	git_repository_free(g_repo);
+}
+
+/*
+ * $ git blame -s branch_file.txt
+ *    orig line no                        final line no
+ * commit   V  author       timestamp                 V
+ * c47800c7 1 (Scott Chacon 2010-05-25 11:58:14 -0700 1
+ * a65fedf3 2 (Scott Chacon 2011-08-09 19:33:46 -0700 2
+ */
+void test_blame_simple__trivial_testrepo(void)
+{
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo/.gitted")));
+	cl_git_pass(git_blame_file(&g_blame, g_repo, "branch_file.txt", NULL));
+
+	cl_assert_equal_i(2, git_blame_get_hunk_count(g_blame));
+	check_blame_hunk_index(g_repo, g_blame, 0, 1, 1, 0, "c47800c7", "branch_file.txt");
+	check_blame_hunk_index(g_repo, g_blame, 1, 2, 1, 0, "a65fedf3", "branch_file.txt");
+}
+
+/*
+ * $ git blame -n b.txt
+ *    orig line no                          final line no
+ * commit    V  author     timestamp                  V
+ * da237394  1 (Ben Straub 2013-02-12 15:11:30 -0800  1
+ * da237394  2 (Ben Straub 2013-02-12 15:11:30 -0800  2
+ * da237394  3 (Ben Straub 2013-02-12 15:11:30 -0800  3
+ * da237394  4 (Ben Straub 2013-02-12 15:11:30 -0800  4
+ * ^b99f7ac  1 (Ben Straub 2013-02-12 15:10:12 -0800  5
+ * 63d671eb  6 (Ben Straub 2013-02-12 15:13:04 -0800  6
+ * 63d671eb  7 (Ben Straub 2013-02-12 15:13:04 -0800  7
+ * 63d671eb  8 (Ben Straub 2013-02-12 15:13:04 -0800  8
+ * 63d671eb  9 (Ben Straub 2013-02-12 15:13:04 -0800  9
+ * 63d671eb 10 (Ben Straub 2013-02-12 15:13:04 -0800 10
+ * aa06ecca  6 (Ben Straub 2013-02-12 15:14:46 -0800 11
+ * aa06ecca  7 (Ben Straub 2013-02-12 15:14:46 -0800 12
+ * aa06ecca  8 (Ben Straub 2013-02-12 15:14:46 -0800 13
+ * aa06ecca  9 (Ben Straub 2013-02-12 15:14:46 -0800 14
+ * aa06ecca 10 (Ben Straub 2013-02-12 15:14:46 -0800 15
+ */
+void test_blame_simple__trivial_blamerepo(void)
+{
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("blametest.git")));
+	cl_git_pass(git_blame_file(&g_blame, g_repo, "b.txt", NULL));
+
+	cl_assert_equal_i(4, git_blame_get_hunk_count(g_blame));
+	check_blame_hunk_index(g_repo, g_blame, 0,  1, 4, 0, "da237394", "b.txt");
+	check_blame_hunk_index(g_repo, g_blame, 1,  5, 1, 1, "b99f7ac0", "b.txt");
+	check_blame_hunk_index(g_repo, g_blame, 2,  6, 5, 0, "63d671eb", "b.txt");
+	check_blame_hunk_index(g_repo, g_blame, 3, 11, 5, 0, "aa06ecca", "b.txt");
+}
+
+
+/*
+ * $ git blame -n 359fc2d -- include/git2.h
+ *                     orig line no                                final line no
+ * commit   orig path       V  author              timestamp                  V
+ * d12299fe src/git.h       1 (Vicent Martí        2010-12-03 22:22:10 +0200  1
+ * 359fc2d2 include/git2.h  2 (Edward Thomson      2013-01-08 17:07:25 -0600  2
+ * d12299fe src/git.h       5 (Vicent Martí        2010-12-03 22:22:10 +0200  3
+ * bb742ede include/git2.h  4 (Vicent Martí        2011-09-19 01:54:32 +0300  4
+ * bb742ede include/git2.h  5 (Vicent Martí        2011-09-19 01:54:32 +0300  5
+ * d12299fe src/git.h      24 (Vicent Martí        2010-12-03 22:22:10 +0200  6
+ * d12299fe src/git.h      25 (Vicent Martí        2010-12-03 22:22:10 +0200  7
+ * d12299fe src/git.h      26 (Vicent Martí        2010-12-03 22:22:10 +0200  8
+ * d12299fe src/git.h      27 (Vicent Martí        2010-12-03 22:22:10 +0200  9
+ * d12299fe src/git.h      28 (Vicent Martí        2010-12-03 22:22:10 +0200 10
+ * 96fab093 include/git2.h 11 (Sven Strickroth     2011-10-09 18:37:41 +0200 11
+ * 9d1dcca2 src/git2.h     33 (Vicent Martí        2011-02-07 10:35:58 +0200 12
+ * 44908fe7 src/git2.h     29 (Vicent Martí        2010-12-06 23:03:16 +0200 13
+ * a15c550d include/git2.h 14 (Vicent Martí        2011-11-16 14:09:44 +0100 14
+ * 44908fe7 src/git2.h     30 (Vicent Martí        2010-12-06 23:03:16 +0200 15
+ * d12299fe src/git.h      32 (Vicent Martí        2010-12-03 22:22:10 +0200 16
+ * 44908fe7 src/git2.h     33 (Vicent Martí        2010-12-06 23:03:16 +0200 17
+ * d12299fe src/git.h      34 (Vicent Martí        2010-12-03 22:22:10 +0200 18
+ * 44908fe7 src/git2.h     35 (Vicent Martí        2010-12-06 23:03:16 +0200 19
+ * 638c2ca4 src/git2.h     36 (Vicent Martí        2010-12-18 02:10:25 +0200 20
+ * 44908fe7 src/git2.h     36 (Vicent Martí        2010-12-06 23:03:16 +0200 21
+ * d12299fe src/git.h      37 (Vicent Martí        2010-12-03 22:22:10 +0200 22
+ * 44908fe7 src/git2.h     38 (Vicent Martí        2010-12-06 23:03:16 +0200 23
+ * 44908fe7 src/git2.h     39 (Vicent Martí        2010-12-06 23:03:16 +0200 24
+ * bf787bd8 include/git2.h 25 (Carlos Martín Nieto 2012-04-08 18:56:50 +0200 25
+ * 0984c876 include/git2.h 26 (Scott J. Goldman    2012-11-28 18:27:43 -0800 26
+ * 2f8a8ab2 src/git2.h     41 (Vicent Martí        2011-01-29 01:56:25 +0200 27
+ * 27df4275 include/git2.h 47 (Michael Schubert    2011-06-28 14:13:12 +0200 28
+ * a346992f include/git2.h 28 (Ben Straub          2012-05-10 09:47:14 -0700 29
+ * d12299fe src/git.h      40 (Vicent Martí        2010-12-03 22:22:10 +0200 30
+ * 44908fe7 src/git2.h     41 (Vicent Martí        2010-12-06 23:03:16 +0200 31
+ * 44908fe7 src/git2.h     42 (Vicent Martí        2010-12-06 23:03:16 +0200 32
+ * 44908fe7 src/git2.h     43 (Vicent Martí        2010-12-06 23:03:16 +0200 33
+ * 44908fe7 src/git2.h     44 (Vicent Martí        2010-12-06 23:03:16 +0200 34
+ * 44908fe7 src/git2.h     45 (Vicent Martí        2010-12-06 23:03:16 +0200 35
+ * 65b09b1d include/git2.h 33 (Russell Belfer      2012-02-02 18:03:43 -0800 36
+ * d12299fe src/git.h      46 (Vicent Martí        2010-12-03 22:22:10 +0200 37
+ * 44908fe7 src/git2.h     47 (Vicent Martí        2010-12-06 23:03:16 +0200 38
+ * 5d4cd003 include/git2.h 55 (Carlos Martín Nieto 2011-03-28 17:02:45 +0200 39
+ * 41fb1ca0 include/git2.h 39 (Philip Kelley       2012-10-29 13:41:14 -0400 40
+ * 2dc31040 include/git2.h 56 (Carlos Martín Nieto 2011-06-20 18:58:57 +0200 41
+ * 764df57e include/git2.h 40 (Ben Straub          2012-06-15 13:14:43 -0700 42
+ * 5280f4e6 include/git2.h 41 (Ben Straub          2012-07-31 19:39:06 -0700 43
+ * 613d5eb9 include/git2.h 43 (Philip Kelley       2012-11-28 11:42:37 -0500 44
+ * d12299fe src/git.h      48 (Vicent Martí        2010-12-03 22:22:10 +0200 45
+ * 111ee3fe include/git2.h 41 (Vicent Martí        2012-07-11 14:37:26 +0200 46
+ * f004c4a8 include/git2.h 44 (Russell Belfer      2012-08-21 17:26:39 -0700 47
+ * 111ee3fe include/git2.h 42 (Vicent Martí        2012-07-11 14:37:26 +0200 48
+ * 9c82357b include/git2.h 58 (Carlos Martín Nieto 2011-06-17 18:13:14 +0200 49
+ * d6258deb include/git2.h 61 (Carlos Martín Nieto 2011-06-25 15:10:09 +0200 50
+ * b311e313 include/git2.h 63 (Julien Miotte       2011-07-27 18:31:13 +0200 51
+ * 3412391d include/git2.h 63 (Carlos Martín Nieto 2011-07-07 11:47:31 +0200 52
+ * bfc9ca59 include/git2.h 43 (Russell Belfer      2012-03-28 16:45:36 -0700 53
+ * bf477ed4 include/git2.h 44 (Michael Schubert    2012-02-15 00:33:38 +0100 54
+ * edebceff include/git2.h 46 (nulltoken           2012-05-01 13:57:45 +0200 55
+ * 743a4b3b include/git2.h 48 (nulltoken           2012-06-15 22:24:59 +0200 56
+ * 0a32dca5 include/git2.h 54 (Michael Schubert    2012-08-19 22:26:32 +0200 57
+ * 590fb68b include/git2.h 55 (nulltoken           2012-10-04 13:47:45 +0200 58
+ * bf477ed4 include/git2.h 45 (Michael Schubert    2012-02-15 00:33:38 +0100 59
+ * d12299fe src/git.h      49 (Vicent Martí        2010-12-03 22:22:10 +0200 60
+ */
+void test_blame_simple__trivial_libgit2(void)
+{
+	git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+	git_object *obj;
+
+	/* If we can't open the libgit2 repo or if it isn't a full repo
+	 * with proper history, just skip this test */
+	if (git_repository_open(&g_repo, cl_fixture("../..")) < 0)
+		cl_skip();
+
+	if (git_repository_is_shallow(g_repo))
+		cl_skip();
+
+	if (git_revparse_single(&obj, g_repo, "359fc2d") < 0)
+		cl_skip();
+
+	git_oid_cpy(&opts.newest_commit, git_object_id(obj));
+	git_object_free(obj);
+
+	cl_git_pass(git_blame_file(&g_blame, g_repo, "include/git2.h", &opts));
+
+	check_blame_hunk_index(g_repo, g_blame,  0,  1, 1, 0, "d12299fe", "src/git.h");
+	check_blame_hunk_index(g_repo, g_blame,  1,  2, 1, 0, "359fc2d2", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame,  2,  3, 1, 0, "d12299fe", "src/git.h");
+	check_blame_hunk_index(g_repo, g_blame,  3,  4, 2, 0, "bb742ede", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame,  4,  6, 5, 0, "d12299fe", "src/git.h");
+	check_blame_hunk_index(g_repo, g_blame,  5, 11, 1, 0, "96fab093", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame,  6, 12, 1, 0, "9d1dcca2", "src/git2.h");
+	check_blame_hunk_index(g_repo, g_blame,  7, 13, 1, 0, "44908fe7", "src/git2.h");
+	check_blame_hunk_index(g_repo, g_blame,  8, 14, 1, 0, "a15c550d", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame,  9, 15, 1, 0, "44908fe7", "src/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 10, 16, 1, 0, "d12299fe", "src/git.h");
+	check_blame_hunk_index(g_repo, g_blame, 11, 17, 1, 0, "44908fe7", "src/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 12, 18, 1, 0, "d12299fe", "src/git.h");
+	check_blame_hunk_index(g_repo, g_blame, 13, 19, 1, 0, "44908fe7", "src/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 14, 20, 1, 0, "638c2ca4", "src/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 15, 21, 1, 0, "44908fe7", "src/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 16, 22, 1, 0, "d12299fe", "src/git.h");
+	check_blame_hunk_index(g_repo, g_blame, 17, 23, 2, 0, "44908fe7", "src/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 18, 25, 1, 0, "bf787bd8", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 19, 26, 1, 0, "0984c876", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 20, 27, 1, 0, "2f8a8ab2", "src/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 21, 28, 1, 0, "27df4275", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 22, 29, 1, 0, "a346992f", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 23, 30, 1, 0, "d12299fe", "src/git.h");
+	check_blame_hunk_index(g_repo, g_blame, 24, 31, 5, 0, "44908fe7", "src/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 25, 36, 1, 0, "65b09b1d", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 26, 37, 1, 0, "d12299fe", "src/git.h");
+	check_blame_hunk_index(g_repo, g_blame, 27, 38, 1, 0, "44908fe7", "src/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 28, 39, 1, 0, "5d4cd003", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 29, 40, 1, 0, "41fb1ca0", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 30, 41, 1, 0, "2dc31040", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 31, 42, 1, 0, "764df57e", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 32, 43, 1, 0, "5280f4e6", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 33, 44, 1, 0, "613d5eb9", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 34, 45, 1, 0, "d12299fe", "src/git.h");
+	check_blame_hunk_index(g_repo, g_blame, 35, 46, 1, 0, "111ee3fe", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 36, 47, 1, 0, "f004c4a8", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 37, 48, 1, 0, "111ee3fe", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 38, 49, 1, 0, "9c82357b", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 39, 50, 1, 0, "d6258deb", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 40, 51, 1, 0, "b311e313", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 41, 52, 1, 0, "3412391d", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 42, 53, 1, 0, "bfc9ca59", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 43, 54, 1, 0, "bf477ed4", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 44, 55, 1, 0, "edebceff", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 45, 56, 1, 0, "743a4b3b", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 46, 57, 1, 0, "0a32dca5", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 47, 58, 1, 0, "590fb68b", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 48, 59, 1, 0, "bf477ed4", "include/git2.h");
+	check_blame_hunk_index(g_repo, g_blame, 49, 60, 1, 0, "d12299fe", "src/git.h");
+}
+
+
+/*
+ * $ git blame -n b.txt -L 8
+ *    orig line no                          final line no
+ * commit    V  author     timestamp                  V
+ * 63d671eb  8 (Ben Straub 2013-02-12 15:13:04 -0800  8
+ * 63d671eb  9 (Ben Straub 2013-02-12 15:13:04 -0800  9
+ * 63d671eb 10 (Ben Straub 2013-02-12 15:13:04 -0800 10
+ * aa06ecca  6 (Ben Straub 2013-02-12 15:14:46 -0800 11
+ * aa06ecca  7 (Ben Straub 2013-02-12 15:14:46 -0800 12
+ * aa06ecca  8 (Ben Straub 2013-02-12 15:14:46 -0800 13
+ * aa06ecca  9 (Ben Straub 2013-02-12 15:14:46 -0800 14
+ * aa06ecca 10 (Ben Straub 2013-02-12 15:14:46 -0800 15
+ */
+void test_blame_simple__can_restrict_lines_min(void)
+{
+	git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("blametest.git")));
+
+	opts.min_line = 8;
+	cl_git_pass(git_blame_file(&g_blame, g_repo, "b.txt", &opts));
+	cl_assert_equal_i(2, git_blame_get_hunk_count(g_blame));
+	check_blame_hunk_index(g_repo, g_blame, 0,  8, 3, 0, "63d671eb", "b.txt");
+	check_blame_hunk_index(g_repo, g_blame, 1, 11, 5, 0, "aa06ecca", "b.txt");
+}
+
+/*
+ * $ git blame -n b.txt -L ,6
+ *    orig line no                          final line no
+ * commit    V  author     timestamp                  V
+ * da237394  1 (Ben Straub 2013-02-12 15:11:30 -0800  1
+ * da237394  2 (Ben Straub 2013-02-12 15:11:30 -0800  2
+ * da237394  3 (Ben Straub 2013-02-12 15:11:30 -0800  3
+ * da237394  4 (Ben Straub 2013-02-12 15:11:30 -0800  4
+ * ^b99f7ac  1 (Ben Straub 2013-02-12 15:10:12 -0800  5
+ * 63d671eb  6 (Ben Straub 2013-02-12 15:13:04 -0800  6
+ */
+void test_blame_simple__can_restrict_lines_max(void)
+{
+	git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("blametest.git")));
+
+	opts.max_line = 6;
+	cl_git_pass(git_blame_file(&g_blame, g_repo, "b.txt", &opts));
+	cl_assert_equal_i(3, git_blame_get_hunk_count(g_blame));
+	check_blame_hunk_index(g_repo, g_blame, 0,  1, 4, 0, "da237394", "b.txt");
+	check_blame_hunk_index(g_repo, g_blame, 1,  5, 1, 1, "b99f7ac0", "b.txt");
+	check_blame_hunk_index(g_repo, g_blame, 2,  6, 1, 0, "63d671eb", "b.txt");
+}
+
+/*
+ * $ git blame -n b.txt -L 2,7
+ *    orig line no                          final line no
+ * commit   V  author     timestamp                 V
+ * da237394 2 (Ben Straub 2013-02-12 15:11:30 -0800 2
+ * da237394 3 (Ben Straub 2013-02-12 15:11:30 -0800 3
+ * da237394 4 (Ben Straub 2013-02-12 15:11:30 -0800 4
+ * ^b99f7ac 1 (Ben Straub 2013-02-12 15:10:12 -0800 5
+ * 63d671eb 6 (Ben Straub 2013-02-12 15:13:04 -0800 6
+ * 63d671eb 7 (Ben Straub 2013-02-12 15:13:04 -0800 7
+ */
+void test_blame_simple__can_restrict_lines_both(void)
+{
+	git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("blametest.git")));
+
+	opts.min_line = 2;
+	opts.max_line = 7;
+	cl_git_pass(git_blame_file(&g_blame, g_repo, "b.txt", &opts));
+	cl_assert_equal_i(3, git_blame_get_hunk_count(g_blame));
+	check_blame_hunk_index(g_repo, g_blame, 0,  2, 3, 0, "da237394", "b.txt");
+	check_blame_hunk_index(g_repo, g_blame, 1,  5, 1, 1, "b99f7ac0", "b.txt");
+	check_blame_hunk_index(g_repo, g_blame, 2,  6, 2, 0, "63d671eb", "b.txt");
+}
+
+/*
+ * $ git blame -n branch_file.txt be3563a..HEAD
+ *    orig line no                          final line no
+ * commit   V  author       timestamp                 V
+ * ^be3563a 1 (Scott Chacon 2010-05-25 11:58:27 -0700 1) hi
+ * a65fedf3 2 (Scott Chacon 2011-08-09 19:33:46 -0700 2) bye!
+ */
+void test_blame_simple__can_restrict_to_newish_commits(void)
+{
+	git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
+
+	{
+		git_object *obj;
+		cl_git_pass(git_revparse_single(&obj, g_repo, "be3563a"));
+		git_oid_cpy(&opts.oldest_commit, git_object_id(obj));
+		git_object_free(obj);
+	}
+
+	cl_git_pass(git_blame_file(&g_blame, g_repo, "branch_file.txt", &opts));
+
+	cl_assert_equal_i(2, git_blame_get_hunk_count(g_blame));
+	check_blame_hunk_index(g_repo, g_blame, 0,  1, 1, 1, "be3563a", "branch_file.txt");
+	check_blame_hunk_index(g_repo, g_blame, 1,  2, 1, 0, "a65fedf", "branch_file.txt");
+}
+
+void test_blame_simple__can_restrict_to_first_parent_commits(void)
+{
+	git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
+	opts.flags |= GIT_BLAME_FIRST_PARENT;
+
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("blametest.git")));
+
+	cl_git_pass(git_blame_file(&g_blame, g_repo, "b.txt", &opts));
+	cl_assert_equal_i(4, git_blame_get_hunk_count(g_blame));
+	check_blame_hunk_index(g_repo, g_blame, 0,  1, 4, 0, "da237394", "b.txt");
+	check_blame_hunk_index(g_repo, g_blame, 1,  5, 1, 1, "b99f7ac0", "b.txt");
+	check_blame_hunk_index(g_repo, g_blame, 2,  6, 5, 0, "63d671eb", "b.txt");
+	check_blame_hunk_index(g_repo, g_blame, 3, 11, 5, 0, "bc7c5ac2", "b.txt");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/buf/basic.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/buf/basic.c
new file mode 100755
index 0000000..14ea3e7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/buf/basic.c
@@ -0,0 +1,51 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+
+static const char *test_string = "Have you seen that? Have you seeeen that??";
+
+void test_buf_basic__resize(void)
+{
+	git_buf buf1 = GIT_BUF_INIT;
+	git_buf_puts(&buf1, test_string);
+	cl_assert(git_buf_oom(&buf1) == 0);
+	cl_assert_equal_s(git_buf_cstr(&buf1), test_string);
+
+	git_buf_puts(&buf1, test_string);
+	cl_assert(strlen(git_buf_cstr(&buf1)) == strlen(test_string) * 2);
+	git_buf_free(&buf1);
+}
+
+void test_buf_basic__resize_incremental(void)
+{
+	git_buf buf1 = GIT_BUF_INIT;
+
+	/* Presently, asking for 6 bytes will round up to 8. */
+	cl_git_pass(git_buf_puts(&buf1, "Hello"));
+	cl_assert_equal_i(5, buf1.size);
+	cl_assert_equal_i(8, buf1.asize);
+
+	/* Ensure an additional byte does not realloc. */
+	cl_git_pass(git_buf_grow_by(&buf1, 1));
+	cl_assert_equal_i(5, buf1.size);
+	cl_assert_equal_i(8, buf1.asize);
+
+	/* But requesting many does. */
+	cl_git_pass(git_buf_grow_by(&buf1, 16));
+	cl_assert_equal_i(5, buf1.size);
+	cl_assert(buf1.asize > 8);
+
+	git_buf_free(&buf1);
+}
+
+void test_buf_basic__printf(void)
+{
+	git_buf buf2 = GIT_BUF_INIT;
+	git_buf_printf(&buf2, "%s %s %d ", "shoop", "da", 23);
+	cl_assert(git_buf_oom(&buf2) == 0);
+	cl_assert_equal_s(git_buf_cstr(&buf2), "shoop da 23 ");
+
+	git_buf_printf(&buf2, "%s %d", "woop", 42);
+	cl_assert(git_buf_oom(&buf2) == 0);
+	cl_assert_equal_s(git_buf_cstr(&buf2), "shoop da 23 woop 42");
+	git_buf_free(&buf2);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/buf/oom.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/buf/oom.c
new file mode 100755
index 0000000..b9fd29c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/buf/oom.c
@@ -0,0 +1,41 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+
+#if defined(GIT_ARCH_64)
+#define TOOBIG 0xffffffffffffff00
+#else
+#define TOOBIG 0xffffff00
+#endif
+
+/**
+ * If we make a ridiculously large request the first time we
+ * actually allocate some space in the git_buf, the realloc()
+ * will fail.  And because the git_buf_grow() wrapper always
+ * sets mark_oom, the code in git_buf_try_grow() will free
+ * the internal buffer and set it to git_buf__oom.
+ * 
+ * We initialized the internal buffer to (the static variable)
+ * git_buf__initbuf.  The purpose of this test is to make sure
+ * that we don't try to free the static buffer.
+ */
+void test_buf_oom__grow(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	git_buf_clear(&buf);
+
+	cl_assert(git_buf_grow(&buf, TOOBIG) == -1);
+	cl_assert(git_buf_oom(&buf));
+
+	git_buf_free(&buf);
+}
+
+void test_buf_oom__grow_by(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	buf.size = SIZE_MAX-10;
+
+	cl_assert(git_buf_grow_by(&buf, 50) == -1);
+	cl_assert(git_buf_oom(&buf));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/buf/splice.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/buf/splice.c
new file mode 100755
index 0000000..e80c931
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/buf/splice.c
@@ -0,0 +1,93 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+
+static git_buf _buf;
+
+void test_buf_splice__initialize(void) {
+   git_buf_init(&_buf, 16);
+}
+
+void test_buf_splice__cleanup(void) {
+   git_buf_free(&_buf);
+}
+
+void test_buf_splice__preprend(void)
+{
+	git_buf_sets(&_buf, "world!");
+
+	cl_git_pass(git_buf_splice(&_buf, 0, 0, "Hello Dolly", strlen("Hello ")));
+
+	cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
+}
+
+void test_buf_splice__append(void)
+{
+	git_buf_sets(&_buf, "Hello");
+
+	cl_git_pass(git_buf_splice(&_buf, git_buf_len(&_buf), 0, " world!", strlen(" world!")));
+
+	cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
+}
+
+void test_buf_splice__insert_at(void)
+{
+	git_buf_sets(&_buf, "Hell world!");
+
+	cl_git_pass(git_buf_splice(&_buf, strlen("Hell"), 0, "o", strlen("o")));
+
+	cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
+}
+
+void test_buf_splice__remove_at(void)
+{
+	git_buf_sets(&_buf, "Hello world of warcraft!");
+
+	cl_git_pass(git_buf_splice(&_buf, strlen("Hello world"), strlen(" of warcraft"), "", 0));
+
+	cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
+}
+
+void test_buf_splice__replace(void)
+{
+	git_buf_sets(&_buf, "Hell0 w0rld!");
+
+	cl_git_pass(git_buf_splice(&_buf, strlen("Hell"), strlen("0 w0"), "o wo", strlen("o wo")));
+
+	cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
+}
+
+void test_buf_splice__replace_with_longer(void)
+{
+	git_buf_sets(&_buf, "Hello you!");
+
+	cl_git_pass(git_buf_splice(&_buf, strlen("Hello "), strlen("you"), "world", strlen("world")));
+
+	cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
+}
+
+void test_buf_splice__replace_with_shorter(void)
+{
+	git_buf_sets(&_buf, "Brave new world!");
+
+	cl_git_pass(git_buf_splice(&_buf, 0, strlen("Brave new"), "Hello", strlen("Hello")));
+
+	cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
+}
+
+void test_buf_splice__truncate(void)
+{
+	git_buf_sets(&_buf, "Hello world!!");
+
+	cl_git_pass(git_buf_splice(&_buf, strlen("Hello world!"), strlen("!"), "", 0));
+
+	cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
+}
+
+void test_buf_splice__dont_do_anything(void)
+{
+	git_buf_sets(&_buf, "Hello world!");
+
+	cl_git_pass(git_buf_splice(&_buf, 3, 0, "Hello", 0));
+
+	cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/binaryunicode.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/binaryunicode.c
new file mode 100755
index 0000000..27e70d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/binaryunicode.c
@@ -0,0 +1,58 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+#include "repo/repo_helpers.h"
+#include "path.h"
+#include "fileops.h"
+
+static git_repository *g_repo;
+
+void test_checkout_binaryunicode__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("binaryunicode");
+}
+
+void test_checkout_binaryunicode__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static void execute_test(void)
+{
+	git_oid oid, check;
+	git_commit *commit;
+	git_tree *tree;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/branch1"));
+	cl_git_pass(git_commit_lookup(&commit, g_repo, &oid));
+	cl_git_pass(git_commit_tree(&tree, commit));
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+	cl_git_pass(git_checkout_tree(g_repo, (git_object *)tree, &opts));
+
+	git_tree_free(tree);
+	git_commit_free(commit);
+
+	/* Verify that the lenna.jpg file was checked out correctly */
+	cl_git_pass(git_oid_fromstr(&check, "8ab005d890fe53f65eda14b23672f60d9f4ec5a1"));
+	cl_git_pass(git_odb_hashfile(&oid, "binaryunicode/lenna.jpg", GIT_OBJ_BLOB));
+	cl_assert_equal_oid(&oid, &check);
+
+	/* Verify that the text file was checked out correctly */
+	cl_git_pass(git_oid_fromstr(&check, "965b223880dd4249e2c66a0cc0b4cffe1dc40f5a"));
+	cl_git_pass(git_odb_hashfile(&oid, "binaryunicode/utf16_withbom_noeol_crlf.txt", GIT_OBJ_BLOB));
+	cl_assert_equal_oid(&oid, &check);
+}
+
+void test_checkout_binaryunicode__noautocrlf(void)
+{
+	cl_repo_set_bool(g_repo, "core.autocrlf", false);
+	execute_test();
+}
+
+void test_checkout_binaryunicode__autocrlf(void)
+{
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+	execute_test();
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/checkout_helpers.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/checkout_helpers.c
new file mode 100755
index 0000000..92a454d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/checkout_helpers.c
@@ -0,0 +1,151 @@
+#include "clar_libgit2.h"
+#include "checkout_helpers.h"
+#include "refs.h"
+#include "fileops.h"
+#include "index.h"
+
+void assert_on_branch(git_repository *repo, const char *branch)
+{
+	git_reference *head;
+	git_buf bname = GIT_BUF_INIT;
+
+	cl_git_pass(git_reference_lookup(&head, repo, GIT_HEAD_FILE));
+	cl_assert_(git_reference_type(head) == GIT_REF_SYMBOLIC, branch);
+
+	cl_git_pass(git_buf_joinpath(&bname, "refs/heads", branch));
+	cl_assert_equal_s(bname.ptr, git_reference_symbolic_target(head));
+
+	git_reference_free(head);
+	git_buf_free(&bname);
+}
+
+void reset_index_to_treeish(git_object *treeish)
+{
+	git_object *tree;
+	git_index *index;
+	git_repository *repo = git_object_owner(treeish);
+
+	cl_git_pass(git_object_peel(&tree, treeish, GIT_OBJ_TREE));
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_read_tree(index, (git_tree *)tree));
+	cl_git_pass(git_index_write(index));
+
+	git_object_free(tree);
+	git_index_free(index);
+}
+
+int checkout_count_callback(
+	git_checkout_notify_t why,
+	const char *path,
+	const git_diff_file *baseline,
+	const git_diff_file *target,
+	const git_diff_file *workdir,
+	void *payload)
+{
+	checkout_counts *ct = payload;
+
+	GIT_UNUSED(baseline); GIT_UNUSED(target); GIT_UNUSED(workdir);
+
+	if (why & GIT_CHECKOUT_NOTIFY_CONFLICT) {
+		ct->n_conflicts++;
+
+		if (ct->debug) {
+			if (workdir) {
+				if (baseline) {
+					if (target)
+						fprintf(stderr, "M %s (conflicts with M %s)\n",
+							workdir->path, target->path);
+					else
+						fprintf(stderr, "M %s (conflicts with D %s)\n",
+							workdir->path, baseline->path);
+				} else {
+					if (target)
+						fprintf(stderr, "Existing %s (conflicts with A %s)\n",
+							workdir->path, target->path);
+					else
+						fprintf(stderr, "How can an untracked file be a conflict (%s)\n", workdir->path);
+				}
+			} else {
+				if (baseline) {
+					if (target)
+						fprintf(stderr, "D %s (conflicts with M %s)\n",
+							target->path, baseline->path);
+					else
+						fprintf(stderr, "D %s (conflicts with D %s)\n",
+							baseline->path, baseline->path);
+				} else {
+					if (target)
+						fprintf(stderr, "How can an added file with no workdir be a conflict (%s)\n", target->path);
+					else
+						fprintf(stderr, "How can a nonexistent file be a conflict (%s)\n", path);
+				}
+			}
+		}
+	}
+
+	if (why & GIT_CHECKOUT_NOTIFY_DIRTY) {
+		ct->n_dirty++;
+
+		if (ct->debug) {
+			if (workdir)
+				fprintf(stderr, "M %s\n", workdir->path);
+			else
+				fprintf(stderr, "D %s\n", baseline->path);
+		}
+	}
+
+	if (why & GIT_CHECKOUT_NOTIFY_UPDATED) {
+		ct->n_updates++;
+
+		if (ct->debug) {
+			if (baseline) {
+				if (target)
+					fprintf(stderr, "update: M %s\n", path);
+				else
+					fprintf(stderr, "update: D %s\n", path);
+			} else {
+				if (target)
+					fprintf(stderr, "update: A %s\n", path);
+				else
+					fprintf(stderr, "update: this makes no sense %s\n", path);
+			}
+		}
+	}
+
+	if (why & GIT_CHECKOUT_NOTIFY_UNTRACKED) {
+		ct->n_untracked++;
+
+		if (ct->debug)
+			fprintf(stderr, "? %s\n", path);
+	}
+
+	if (why & GIT_CHECKOUT_NOTIFY_IGNORED) {
+		ct->n_ignored++;
+
+		if (ct->debug)
+			fprintf(stderr, "I %s\n", path);
+	}
+
+	return 0;
+}
+
+void tick_index(git_index *index)
+{
+	git_time_t ts;
+	struct timeval times[2];
+
+	cl_assert(index->on_disk);
+	cl_assert(git_index_path(index));
+
+	cl_git_pass(git_index_read(index, true));
+	ts = index->stamp.mtime;
+
+	times[0].tv_sec  = ts;
+	times[0].tv_usec = 0;
+	times[1].tv_sec  = ts + 5;
+	times[1].tv_usec = 0;
+
+	cl_git_pass(p_utimes(git_index_path(index), times));
+	cl_git_pass(git_index_read(index, true));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/checkout_helpers.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/checkout_helpers.h
new file mode 100755
index 0000000..6058a19
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/checkout_helpers.h
@@ -0,0 +1,31 @@
+#include "buffer.h"
+#include "git2/object.h"
+#include "git2/repository.h"
+
+extern void assert_on_branch(git_repository *repo, const char *branch);
+extern void reset_index_to_treeish(git_object *treeish);
+
+#define check_file_contents(PATH,EXP) \
+	cl_assert_equal_file(EXP,0,PATH)
+
+#define check_file_contents_nocr(PATH,EXP) \
+	cl_assert_equal_file_ignore_cr(EXP,0,PATH)
+
+typedef struct {
+	int n_conflicts;
+	int n_dirty;
+	int n_updates;
+	int n_untracked;
+	int n_ignored;
+	int debug;
+} checkout_counts;
+
+extern int checkout_count_callback(
+	git_checkout_notify_t why,
+	const char *path,
+	const git_diff_file *baseline,
+	const git_diff_file *target,
+	const git_diff_file *workdir,
+	void *payload);
+
+extern void tick_index(git_index *index);
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/conflict.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/conflict.c
new file mode 100755
index 0000000..dd2dd31
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/conflict.c
@@ -0,0 +1,1137 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/sys/index.h"
+#include "fileops.h"
+
+static git_repository *g_repo;
+static git_index *g_index;
+
+#define TEST_REPO_PATH "merge-resolve"
+
+#define CONFLICTING_ANCESTOR_OID   "d427e0b2e138501a3d15cc376077a3631e15bd46"
+#define CONFLICTING_OURS_OID       "4e886e602529caa9ab11d71f86634bd1b6e0de10"
+#define CONFLICTING_THEIRS_OID     "2bd0a343aeef7a2cf0d158478966a6e587ff3863"
+
+#define AUTOMERGEABLE_ANCESTOR_OID "6212c31dab5e482247d7977e4f0dd3601decf13b"
+#define AUTOMERGEABLE_OURS_OID     "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf"
+#define AUTOMERGEABLE_THEIRS_OID   "058541fc37114bfc1dddf6bd6bffc7fae5c2e6fe"
+
+#define LINK_ANCESTOR_OID          "1a010b1c0f081b2e8901d55307a15c29ff30af0e"
+#define LINK_OURS_OID              "72ea499e108df5ff0a4a913e7655bbeeb1fb69f2"
+#define LINK_THEIRS_OID            "8bfb012a6d809e499bd8d3e194a3929bc8995b93"
+
+#define LINK_ANCESTOR_TARGET       "file"
+#define LINK_OURS_TARGET           "other-file"
+#define LINK_THEIRS_TARGET         "still-another-file"
+
+#define CONFLICTING_OURS_FILE \
+	"this file is changed in master and branch\n"
+#define CONFLICTING_THEIRS_FILE \
+	"this file is changed in branch and master\n"
+#define CONFLICTING_DIFF3_FILE \
+	"<<<<<<< ours\n" \
+	"this file is changed in master and branch\n" \
+	"=======\n" \
+	"this file is changed in branch and master\n" \
+	">>>>>>> theirs\n"
+
+#define AUTOMERGEABLE_MERGED_FILE \
+	"this file is changed in master\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is changed in branch\n"
+
+struct checkout_index_entry {
+	uint16_t mode;
+	char oid_str[GIT_OID_HEXSZ+1];
+	int stage;
+	char path[128];
+};
+
+struct checkout_name_entry {
+	char ancestor[64];
+	char ours[64];
+	char theirs[64];
+};
+
+void test_checkout_conflict__initialize(void)
+{
+	git_config *cfg;
+
+	g_repo = cl_git_sandbox_init(TEST_REPO_PATH);
+	git_repository_index(&g_index, g_repo);
+
+	cl_git_rewritefile(
+		TEST_REPO_PATH "/.gitattributes",
+		"* text eol=lf\n");
+
+	/* Ensure that the user's merge.conflictstyle doesn't interfere */
+	cl_git_pass(git_repository_config(&cfg, g_repo));
+	cl_git_pass(git_config_set_string(cfg, "merge.conflictstyle", "merge"));
+	git_config_free(cfg);
+}
+
+void test_checkout_conflict__cleanup(void)
+{
+	git_index_free(g_index);
+	cl_git_sandbox_cleanup();
+}
+
+static void create_index(struct checkout_index_entry *entries, size_t entries_len)
+{
+	git_buf path = GIT_BUF_INIT;
+	size_t i;
+
+	for (i = 0; i < entries_len; i++) {
+		git_buf_joinpath(&path, TEST_REPO_PATH, entries[i].path);
+
+		if (entries[i].stage == 3 && (i == 0 || strcmp(entries[i-1].path, entries[i].path) != 0 || entries[i-1].stage != 2))
+			p_unlink(git_buf_cstr(&path));
+
+		git_index_remove_bypath(g_index, entries[i].path);
+	}
+
+	for (i = 0; i < entries_len; i++) {
+		git_index_entry entry;
+
+		memset(&entry, 0x0, sizeof(git_index_entry));
+
+		entry.mode = entries[i].mode;
+		GIT_IDXENTRY_STAGE_SET(&entry, entries[i].stage);
+		git_oid_fromstr(&entry.id, entries[i].oid_str);
+		entry.path = entries[i].path;
+
+		cl_git_pass(git_index_add(g_index, &entry));
+	}
+
+	git_buf_free(&path);
+}
+
+static void create_index_names(struct checkout_name_entry *entries, size_t entries_len)
+{
+	size_t i;
+
+	for (i = 0; i < entries_len; i++) {
+		cl_git_pass(git_index_name_add(g_index,
+			strlen(entries[i].ancestor) == 0 ? NULL : entries[i].ancestor,
+			strlen(entries[i].ours) == 0 ? NULL : entries[i].ours,
+			strlen(entries[i].theirs) == 0 ? NULL : entries[i].theirs));
+	}
+}
+
+static void create_conflicting_index(void)
+{
+	struct checkout_index_entry checkout_index_entries[] = {
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "conflicting.txt" },
+		{ 0100644, CONFLICTING_OURS_OID, 2, "conflicting.txt" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "conflicting.txt" },
+	};
+
+	create_index(checkout_index_entries, 3);
+	git_index_write(g_index);
+}
+
+static void ensure_workdir_contents(const char *path, const char *contents)
+{
+	git_buf fullpath = GIT_BUF_INIT, data_buf = GIT_BUF_INIT;
+
+	cl_git_pass(
+		git_buf_joinpath(&fullpath, git_repository_workdir(g_repo), path));
+
+	cl_git_pass(git_futils_readbuffer(&data_buf, git_buf_cstr(&fullpath)));
+	cl_assert(strcmp(git_buf_cstr(&data_buf), contents) == 0);
+
+	git_buf_free(&fullpath);
+	git_buf_free(&data_buf);
+}
+
+static void ensure_workdir_oid(const char *path, const char *oid_str)
+{
+	git_oid expected, actual;
+
+	cl_git_pass(git_oid_fromstr(&expected, oid_str));
+	cl_git_pass(git_repository_hashfile(&actual, g_repo, path, GIT_OBJ_BLOB, NULL));
+	cl_assert_equal_oid(&expected, &actual);
+}
+
+static void ensure_workdir_mode(const char *path, int mode)
+{
+#ifdef GIT_WIN32
+	GIT_UNUSED(path);
+	GIT_UNUSED(mode);
+#else
+	git_buf fullpath = GIT_BUF_INIT;
+	struct stat st;
+
+	cl_git_pass(
+		git_buf_joinpath(&fullpath, git_repository_workdir(g_repo), path));
+
+	cl_git_pass(p_stat(git_buf_cstr(&fullpath), &st));
+	cl_assert_equal_i((mode & S_IRWXU), (st.st_mode & S_IRWXU));
+
+	git_buf_free(&fullpath);
+#endif
+}
+
+static void ensure_workdir(const char *path, int mode, const char *oid_str)
+{
+	ensure_workdir_mode(path, mode);
+	ensure_workdir_oid(path, oid_str);
+}
+
+static void ensure_workdir_link(const char *path, const char *target)
+{
+#ifdef GIT_WIN32
+	ensure_workdir_contents(path, target);
+#else
+	git_buf fullpath = GIT_BUF_INIT;
+	char actual[1024];
+	struct stat st;
+	int len;
+
+	cl_git_pass(
+		git_buf_joinpath(&fullpath, git_repository_workdir(g_repo), path));
+
+	cl_git_pass(p_lstat(git_buf_cstr(&fullpath), &st));
+	cl_assert(S_ISLNK(st.st_mode));
+
+	cl_assert((len = p_readlink(git_buf_cstr(&fullpath), actual, 1024)) > 0);
+	actual[len] = '\0';
+	cl_assert(strcmp(actual, target) == 0);
+
+	git_buf_free(&fullpath);
+#endif
+}
+
+void test_checkout_conflict__ignored(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	opts.checkout_strategy |= GIT_CHECKOUT_SKIP_UNMERGED;
+
+	create_conflicting_index();
+	cl_git_pass(p_unlink(TEST_REPO_PATH "/conflicting.txt"));
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	cl_assert(!git_path_exists(TEST_REPO_PATH "/conflicting.txt"));
+}
+
+void test_checkout_conflict__ours(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	opts.checkout_strategy |= GIT_CHECKOUT_USE_OURS;
+
+	create_conflicting_index();
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	ensure_workdir_contents("conflicting.txt", CONFLICTING_OURS_FILE);
+}
+
+void test_checkout_conflict__theirs(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	opts.checkout_strategy |= GIT_CHECKOUT_USE_THEIRS;
+
+	create_conflicting_index();
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	ensure_workdir_contents("conflicting.txt", CONFLICTING_THEIRS_FILE);
+
+}
+
+void test_checkout_conflict__diff3(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	create_conflicting_index();
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	ensure_workdir_contents("conflicting.txt", CONFLICTING_DIFF3_FILE);
+}
+
+void test_checkout_conflict__automerge(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	struct checkout_index_entry checkout_index_entries[] = {
+		{ 0100644, AUTOMERGEABLE_ANCESTOR_OID, 1, "automergeable.txt" },
+		{ 0100644, AUTOMERGEABLE_OURS_OID, 2, "automergeable.txt" },
+		{ 0100644, AUTOMERGEABLE_THEIRS_OID, 3, "automergeable.txt" },
+	};
+
+	create_index(checkout_index_entries, 3);
+	git_index_write(g_index);
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	ensure_workdir_contents("automergeable.txt", AUTOMERGEABLE_MERGED_FILE);
+}
+
+void test_checkout_conflict__directory_file(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	struct checkout_index_entry checkout_index_entries[] = {
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "df-1" },
+		{ 0100644, CONFLICTING_OURS_OID, 2, "df-1" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 0, "df-1/file" },
+
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "df-2" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "df-2" },
+		{ 0100644, CONFLICTING_OURS_OID, 0, "df-2/file" },
+
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "df-3" },
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "df-3/file" },
+		{ 0100644, CONFLICTING_OURS_OID, 2, "df-3/file" },
+
+		{ 0100644, CONFLICTING_OURS_OID, 2, "df-4" },
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "df-4/file" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "df-4/file" },
+	};
+
+	opts.checkout_strategy |= GIT_CHECKOUT_SAFE;
+
+	create_index(checkout_index_entries, 12);
+	git_index_write(g_index);
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	ensure_workdir_oid("df-1/file", CONFLICTING_THEIRS_OID);
+	ensure_workdir_oid("df-1~ours", CONFLICTING_OURS_OID);
+	ensure_workdir_oid("df-2/file", CONFLICTING_OURS_OID);
+	ensure_workdir_oid("df-2~theirs", CONFLICTING_THEIRS_OID);
+	ensure_workdir_oid("df-3/file", CONFLICTING_OURS_OID);
+	ensure_workdir_oid("df-3~theirs", CONFLICTING_THEIRS_OID);
+	ensure_workdir_oid("df-4~ours", CONFLICTING_OURS_OID);
+	ensure_workdir_oid("df-4/file", CONFLICTING_THEIRS_OID);
+}
+
+void test_checkout_conflict__directory_file_with_custom_labels(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	struct checkout_index_entry checkout_index_entries[] = {
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "df-1" },
+		{ 0100644, CONFLICTING_OURS_OID, 2, "df-1" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 0, "df-1/file" },
+
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "df-2" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "df-2" },
+		{ 0100644, CONFLICTING_OURS_OID, 0, "df-2/file" },
+
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "df-3" },
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "df-3/file" },
+		{ 0100644, CONFLICTING_OURS_OID, 2, "df-3/file" },
+
+		{ 0100644, CONFLICTING_OURS_OID, 2, "df-4" },
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "df-4/file" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "df-4/file" },
+	};
+
+	opts.checkout_strategy |= GIT_CHECKOUT_SAFE;
+	opts.our_label = "HEAD";
+	opts.their_label = "branch";
+
+	create_index(checkout_index_entries, 12);
+	git_index_write(g_index);
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	ensure_workdir_oid("df-1/file", CONFLICTING_THEIRS_OID);
+	ensure_workdir_oid("df-1~HEAD", CONFLICTING_OURS_OID);
+	ensure_workdir_oid("df-2/file", CONFLICTING_OURS_OID);
+	ensure_workdir_oid("df-2~branch", CONFLICTING_THEIRS_OID);
+	ensure_workdir_oid("df-3/file", CONFLICTING_OURS_OID);
+	ensure_workdir_oid("df-3~branch", CONFLICTING_THEIRS_OID);
+	ensure_workdir_oid("df-4~HEAD", CONFLICTING_OURS_OID);
+	ensure_workdir_oid("df-4/file", CONFLICTING_THEIRS_OID);
+}
+
+void test_checkout_conflict__link_file(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	struct checkout_index_entry checkout_index_entries[] = {
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "link-1" },
+		{ 0100644, CONFLICTING_OURS_OID, 2, "link-1" },
+		{ 0120000, LINK_THEIRS_OID, 3, "link-1" },
+
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "link-2" },
+		{ 0120000, LINK_OURS_OID, 2, "link-2" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "link-2" },
+
+		{ 0120000, LINK_ANCESTOR_OID, 1, "link-3" },
+		{ 0100644, CONFLICTING_OURS_OID, 2, "link-3" },
+		{ 0120000, LINK_THEIRS_OID, 3, "link-3" },
+
+		{ 0120000, LINK_ANCESTOR_OID, 1, "link-4" },
+		{ 0120000, LINK_OURS_OID, 2, "link-4" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "link-4" },
+	};
+
+	opts.checkout_strategy |= GIT_CHECKOUT_SAFE;
+
+	create_index(checkout_index_entries, 12);
+	git_index_write(g_index);
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	/* Typechange conflicts always keep the file in the workdir */
+	ensure_workdir_oid("link-1", CONFLICTING_OURS_OID);
+	ensure_workdir_oid("link-2", CONFLICTING_THEIRS_OID);
+	ensure_workdir_oid("link-3", CONFLICTING_OURS_OID);
+	ensure_workdir_oid("link-4", CONFLICTING_THEIRS_OID);
+}
+
+void test_checkout_conflict__links(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	struct checkout_index_entry checkout_index_entries[] = {
+		{ 0120000, LINK_ANCESTOR_OID, 1, "link-1" },
+		{ 0120000, LINK_OURS_OID, 2, "link-1" },
+		{ 0120000, LINK_THEIRS_OID, 3, "link-1" },
+
+		{ 0120000, LINK_OURS_OID, 2, "link-2" },
+		{ 0120000, LINK_THEIRS_OID, 3, "link-2" },
+	};
+
+	opts.checkout_strategy |= GIT_CHECKOUT_SAFE;
+
+	create_index(checkout_index_entries, 5);
+	git_index_write(g_index);
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	/* Conflicts with links always keep the ours side (even with -Xtheirs) */
+	ensure_workdir_link("link-1", LINK_OURS_TARGET);
+	ensure_workdir_link("link-2", LINK_OURS_TARGET);
+}
+
+void test_checkout_conflict__add_add(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	struct checkout_index_entry checkout_index_entries[] = {
+		{ 0100644, CONFLICTING_OURS_OID, 2, "conflicting.txt" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "conflicting.txt" },
+	};
+
+	opts.checkout_strategy |= GIT_CHECKOUT_SAFE;
+
+	create_index(checkout_index_entries, 2);
+	git_index_write(g_index);
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	/* Add/add writes diff3 files */
+	ensure_workdir_contents("conflicting.txt", CONFLICTING_DIFF3_FILE);
+}
+
+void test_checkout_conflict__mode_change(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	struct checkout_index_entry checkout_index_entries[] = {
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "executable-1" },
+		{ 0100755, CONFLICTING_ANCESTOR_OID, 2, "executable-1" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "executable-1" },
+
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "executable-2" },
+		{ 0100644, CONFLICTING_OURS_OID, 2, "executable-2" },
+		{ 0100755, CONFLICTING_ANCESTOR_OID, 3, "executable-2" },
+
+		{ 0100755, CONFLICTING_ANCESTOR_OID, 1, "executable-3" },
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 2, "executable-3" },
+		{ 0100755, CONFLICTING_THEIRS_OID, 3, "executable-3" },
+
+		{ 0100755, CONFLICTING_ANCESTOR_OID, 1, "executable-4" },
+		{ 0100755, CONFLICTING_OURS_OID, 2, "executable-4" },
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 3, "executable-4" },
+
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "executable-5" },
+		{ 0100755, CONFLICTING_OURS_OID, 2, "executable-5" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "executable-5" },
+
+		{ 0100755, CONFLICTING_ANCESTOR_OID, 1, "executable-6" },
+		{ 0100644, CONFLICTING_OURS_OID, 2, "executable-6" },
+		{ 0100755, CONFLICTING_THEIRS_OID, 3, "executable-6" },
+	};
+
+	opts.checkout_strategy |= GIT_CHECKOUT_SAFE;
+
+	create_index(checkout_index_entries, 18);
+	git_index_write(g_index);
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	/* Keep the modified mode */
+	ensure_workdir_oid("executable-1", CONFLICTING_THEIRS_OID);
+	ensure_workdir_mode("executable-1", 0100755);
+
+	ensure_workdir_oid("executable-2", CONFLICTING_OURS_OID);
+	ensure_workdir_mode("executable-2", 0100755);
+
+	ensure_workdir_oid("executable-3", CONFLICTING_THEIRS_OID);
+	ensure_workdir_mode("executable-3", 0100644);
+
+	ensure_workdir_oid("executable-4", CONFLICTING_OURS_OID);
+	ensure_workdir_mode("executable-4", 0100644);
+
+	ensure_workdir_contents("executable-5", CONFLICTING_DIFF3_FILE);
+	ensure_workdir_mode("executable-5", 0100755);
+
+	ensure_workdir_contents("executable-6", CONFLICTING_DIFF3_FILE);
+	ensure_workdir_mode("executable-6", 0100644);
+}
+
+void test_checkout_conflict__renames(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	struct checkout_index_entry checkout_index_entries[] = {
+		{ 0100644, "68c6c84b091926c7d90aa6a79b2bc3bb6adccd8e", 0, "0a-no-change.txt" },
+		{ 0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6", 0, "0b-duplicated-in-ours.txt" },
+		{ 0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6", 1, "0b-rewritten-in-ours.txt" },
+		{ 0100644, "e376fbdd06ebf021c92724da9f26f44212734e3e", 2, "0b-rewritten-in-ours.txt" },
+		{ 0100644, "b2d399ae15224e1d58066e3c8df70ce37de7a656", 3, "0b-rewritten-in-ours.txt" },
+		{ 0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31", 0, "0c-duplicated-in-theirs.txt" },
+		{ 0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31", 1, "0c-rewritten-in-theirs.txt" },
+		{ 0100644, "efc9121fdedaf08ba180b53ebfbcf71bd488ed09", 2, "0c-rewritten-in-theirs.txt" },
+		{ 0100644, "712ebba6669ea847d9829e4f1059d6c830c8b531", 3, "0c-rewritten-in-theirs.txt" },
+		{ 0100644, "0d872f8e871a30208305978ecbf9e66d864f1638", 0, "1a-newname-in-ours-edited-in-theirs.txt" },
+		{ 0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb", 0, "1a-newname-in-ours.txt" },
+		{ 0100644, "ed9523e62e453e50dd9be1606af19399b96e397a", 0, "1b-newname-in-theirs-edited-in-ours.txt" },
+		{ 0100644, "2b5f1f181ee3b58ea751f5dd5d8f9b445520a136", 0, "1b-newname-in-theirs.txt" },
+		{ 0100644, "178940b450f238a56c0d75b7955cb57b38191982", 0, "2-newname-in-both.txt" },
+		{ 0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9", 2, "3a-newname-in-ours-deleted-in-theirs.txt" },
+		{ 0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9", 1, "3a-renamed-in-ours-deleted-in-theirs.txt" },
+		{ 0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495", 3, "3b-newname-in-theirs-deleted-in-ours.txt" },
+		{ 0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495", 1, "3b-renamed-in-theirs-deleted-in-ours.txt" },
+		{ 0100644, "227792b52aaa0b238bea00ec7e509b02623f168c", 2, "4a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "8b5b53cb2aa9ceb1139f5312fcfa3cc3c5a47c9a", 3, "4a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "227792b52aaa0b238bea00ec7e509b02623f168c", 1, "4a-renamed-in-ours-added-in-theirs.txt" },
+		{ 0100644, "de872ee3618b894992e9d1e18ba2ebe256a112f9", 2, "4b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "98d52d07c0b0bbf2b46548f6aa521295c2cb55db", 3, "4b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "98d52d07c0b0bbf2b46548f6aa521295c2cb55db", 1, "4b-renamed-in-theirs-added-in-ours.txt" },
+		{ 0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436", 2, "5a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "98ba4205fcf31f5dd93c916d35fe3f3b3d0e6714", 3, "5a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436", 1, "5a-renamed-in-ours-added-in-theirs.txt" },
+		{ 0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436", 3, "5a-renamed-in-ours-added-in-theirs.txt" },
+		{ 0100644, "385c8a0f26ddf79e9041e15e17dc352ed2c4cced", 2, "5b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "63247125386de9ec90a27ad36169307bf8a11a38", 3, "5b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "63247125386de9ec90a27ad36169307bf8a11a38", 1, "5b-renamed-in-theirs-added-in-ours.txt" },
+		{ 0100644, "63247125386de9ec90a27ad36169307bf8a11a38", 2, "5b-renamed-in-theirs-added-in-ours.txt" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 2, "6-both-renamed-1-to-2-ours.txt" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 3, "6-both-renamed-1-to-2-theirs.txt" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 1, "6-both-renamed-1-to-2.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 1, "7-both-renamed-side-1.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 3, "7-both-renamed-side-1.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 1, "7-both-renamed-side-2.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 2, "7-both-renamed-side-2.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 2, "7-both-renamed.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 3, "7-both-renamed.txt" }
+	};
+
+	struct checkout_name_entry checkout_name_entries[] = {
+		{
+			"3a-renamed-in-ours-deleted-in-theirs.txt",
+			"3a-newname-in-ours-deleted-in-theirs.txt",
+			""
+		},
+
+		{
+			"3b-renamed-in-theirs-deleted-in-ours.txt",
+			"",
+			"3b-newname-in-theirs-deleted-in-ours.txt"
+		},
+
+		{
+			"4a-renamed-in-ours-added-in-theirs.txt",
+			"4a-newname-in-ours-added-in-theirs.txt",
+			""
+		},
+
+		{
+			"4b-renamed-in-theirs-added-in-ours.txt",
+			"",
+			"4b-newname-in-theirs-added-in-ours.txt"
+		},
+
+		{
+			"5a-renamed-in-ours-added-in-theirs.txt",
+			"5a-newname-in-ours-added-in-theirs.txt",
+			"5a-renamed-in-ours-added-in-theirs.txt"
+		},
+
+		{
+			"5b-renamed-in-theirs-added-in-ours.txt",
+			"5b-renamed-in-theirs-added-in-ours.txt",
+			"5b-newname-in-theirs-added-in-ours.txt"
+		},
+
+		{
+			"6-both-renamed-1-to-2.txt",
+			"6-both-renamed-1-to-2-ours.txt",
+			"6-both-renamed-1-to-2-theirs.txt"
+		},
+
+		{
+			"7-both-renamed-side-1.txt",
+			"7-both-renamed.txt",
+			"7-both-renamed-side-1.txt"
+		},
+
+		{
+			"7-both-renamed-side-2.txt",
+			"7-both-renamed-side-2.txt",
+			"7-both-renamed.txt"
+		}
+	};
+
+	opts.checkout_strategy |= GIT_CHECKOUT_SAFE;
+
+	create_index(checkout_index_entries, 41);
+	create_index_names(checkout_name_entries, 9);
+	git_index_write(g_index);
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	ensure_workdir("0a-no-change.txt",
+		0100644, "68c6c84b091926c7d90aa6a79b2bc3bb6adccd8e");
+
+	ensure_workdir("0b-duplicated-in-ours.txt",
+		0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6");
+
+	ensure_workdir("0b-rewritten-in-ours.txt",
+		0100644, "4c7e515d6d52d820496858f2f059ece69e99e2e3");
+
+	ensure_workdir("0c-duplicated-in-theirs.txt",
+		0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31");
+
+	ensure_workdir("0c-rewritten-in-theirs.txt",
+		0100644, "4648d658682d1155c2a3db5b0c53305e26884ea5");
+
+	ensure_workdir("1a-newname-in-ours-edited-in-theirs.txt",
+		0100644, "0d872f8e871a30208305978ecbf9e66d864f1638");
+
+	ensure_workdir("1a-newname-in-ours.txt",
+		0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb");
+
+	ensure_workdir("1b-newname-in-theirs-edited-in-ours.txt",
+		0100644, "ed9523e62e453e50dd9be1606af19399b96e397a");
+
+	ensure_workdir("1b-newname-in-theirs.txt",
+		0100644, "2b5f1f181ee3b58ea751f5dd5d8f9b445520a136");
+
+	ensure_workdir("2-newname-in-both.txt",
+		0100644, "178940b450f238a56c0d75b7955cb57b38191982");
+
+	ensure_workdir("3a-newname-in-ours-deleted-in-theirs.txt",
+		0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9");
+
+	ensure_workdir("3b-newname-in-theirs-deleted-in-ours.txt",
+		0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495");
+
+	ensure_workdir("4a-newname-in-ours-added-in-theirs.txt~ours",
+		0100644, "227792b52aaa0b238bea00ec7e509b02623f168c");
+
+	ensure_workdir("4a-newname-in-ours-added-in-theirs.txt~theirs",
+		0100644, "8b5b53cb2aa9ceb1139f5312fcfa3cc3c5a47c9a");
+
+	ensure_workdir("4b-newname-in-theirs-added-in-ours.txt~ours",
+		0100644, "de872ee3618b894992e9d1e18ba2ebe256a112f9");
+
+	ensure_workdir("4b-newname-in-theirs-added-in-ours.txt~theirs",
+		0100644, "98d52d07c0b0bbf2b46548f6aa521295c2cb55db");
+
+	ensure_workdir("5a-newname-in-ours-added-in-theirs.txt~ours",
+		0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436");
+
+	ensure_workdir("5a-newname-in-ours-added-in-theirs.txt~theirs",
+		0100644, "98ba4205fcf31f5dd93c916d35fe3f3b3d0e6714");
+
+	ensure_workdir("5b-newname-in-theirs-added-in-ours.txt~ours",
+		0100644, "385c8a0f26ddf79e9041e15e17dc352ed2c4cced");
+
+	ensure_workdir("5b-newname-in-theirs-added-in-ours.txt~theirs",
+		0100644, "63247125386de9ec90a27ad36169307bf8a11a38");
+
+	ensure_workdir("6-both-renamed-1-to-2-ours.txt",
+		0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450");
+
+	ensure_workdir("6-both-renamed-1-to-2-theirs.txt",
+		0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450");
+
+	ensure_workdir("7-both-renamed.txt~ours",
+		0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11");
+
+	ensure_workdir("7-both-renamed.txt~theirs",
+		0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07");
+}
+
+void test_checkout_conflict__rename_keep_ours(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	
+	struct checkout_index_entry checkout_index_entries[] = {
+		{ 0100644, "68c6c84b091926c7d90aa6a79b2bc3bb6adccd8e", 0, "0a-no-change.txt" },
+		{ 0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6", 0, "0b-duplicated-in-ours.txt" },
+		{ 0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6", 1, "0b-rewritten-in-ours.txt" },
+		{ 0100644, "e376fbdd06ebf021c92724da9f26f44212734e3e", 2, "0b-rewritten-in-ours.txt" },
+		{ 0100644, "b2d399ae15224e1d58066e3c8df70ce37de7a656", 3, "0b-rewritten-in-ours.txt" },
+		{ 0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31", 0, "0c-duplicated-in-theirs.txt" },
+		{ 0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31", 1, "0c-rewritten-in-theirs.txt" },
+		{ 0100644, "efc9121fdedaf08ba180b53ebfbcf71bd488ed09", 2, "0c-rewritten-in-theirs.txt" },
+		{ 0100644, "712ebba6669ea847d9829e4f1059d6c830c8b531", 3, "0c-rewritten-in-theirs.txt" },
+		{ 0100644, "0d872f8e871a30208305978ecbf9e66d864f1638", 0, "1a-newname-in-ours-edited-in-theirs.txt" },
+		{ 0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb", 0, "1a-newname-in-ours.txt" },
+		{ 0100644, "ed9523e62e453e50dd9be1606af19399b96e397a", 0, "1b-newname-in-theirs-edited-in-ours.txt" },
+		{ 0100644, "2b5f1f181ee3b58ea751f5dd5d8f9b445520a136", 0, "1b-newname-in-theirs.txt" },
+		{ 0100644, "178940b450f238a56c0d75b7955cb57b38191982", 0, "2-newname-in-both.txt" },
+		{ 0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9", 2, "3a-newname-in-ours-deleted-in-theirs.txt" },
+		{ 0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9", 1, "3a-renamed-in-ours-deleted-in-theirs.txt" },
+		{ 0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495", 3, "3b-newname-in-theirs-deleted-in-ours.txt" },
+		{ 0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495", 1, "3b-renamed-in-theirs-deleted-in-ours.txt" },
+		{ 0100644, "227792b52aaa0b238bea00ec7e509b02623f168c", 2, "4a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "8b5b53cb2aa9ceb1139f5312fcfa3cc3c5a47c9a", 3, "4a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "227792b52aaa0b238bea00ec7e509b02623f168c", 1, "4a-renamed-in-ours-added-in-theirs.txt" },
+		{ 0100644, "de872ee3618b894992e9d1e18ba2ebe256a112f9", 2, "4b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "98d52d07c0b0bbf2b46548f6aa521295c2cb55db", 3, "4b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "98d52d07c0b0bbf2b46548f6aa521295c2cb55db", 1, "4b-renamed-in-theirs-added-in-ours.txt" },
+		{ 0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436", 2, "5a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "98ba4205fcf31f5dd93c916d35fe3f3b3d0e6714", 3, "5a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436", 1, "5a-renamed-in-ours-added-in-theirs.txt" },
+		{ 0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436", 3, "5a-renamed-in-ours-added-in-theirs.txt" },
+		{ 0100644, "385c8a0f26ddf79e9041e15e17dc352ed2c4cced", 2, "5b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "63247125386de9ec90a27ad36169307bf8a11a38", 3, "5b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "63247125386de9ec90a27ad36169307bf8a11a38", 1, "5b-renamed-in-theirs-added-in-ours.txt" },
+		{ 0100644, "63247125386de9ec90a27ad36169307bf8a11a38", 2, "5b-renamed-in-theirs-added-in-ours.txt" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 2, "6-both-renamed-1-to-2-ours.txt" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 3, "6-both-renamed-1-to-2-theirs.txt" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 1, "6-both-renamed-1-to-2.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 1, "7-both-renamed-side-1.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 3, "7-both-renamed-side-1.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 1, "7-both-renamed-side-2.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 2, "7-both-renamed-side-2.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 2, "7-both-renamed.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 3, "7-both-renamed.txt" }
+	};
+	
+	struct checkout_name_entry checkout_name_entries[] = {
+		{
+			"3a-renamed-in-ours-deleted-in-theirs.txt",
+			"3a-newname-in-ours-deleted-in-theirs.txt",
+			""
+		},
+		
+		{
+			"3b-renamed-in-theirs-deleted-in-ours.txt",
+			"",
+			"3b-newname-in-theirs-deleted-in-ours.txt"
+		},
+		
+		{
+			"4a-renamed-in-ours-added-in-theirs.txt",
+			"4a-newname-in-ours-added-in-theirs.txt",
+			""
+		},
+		
+		{
+			"4b-renamed-in-theirs-added-in-ours.txt",
+			"",
+			"4b-newname-in-theirs-added-in-ours.txt"
+		},
+		
+		{
+			"5a-renamed-in-ours-added-in-theirs.txt",
+			"5a-newname-in-ours-added-in-theirs.txt",
+			"5a-renamed-in-ours-added-in-theirs.txt"
+		},
+		
+		{
+			"5b-renamed-in-theirs-added-in-ours.txt",
+			"5b-renamed-in-theirs-added-in-ours.txt",
+			"5b-newname-in-theirs-added-in-ours.txt"
+		},
+		
+		{
+			"6-both-renamed-1-to-2.txt",
+			"6-both-renamed-1-to-2-ours.txt",
+			"6-both-renamed-1-to-2-theirs.txt"
+		},
+		
+		{
+			"7-both-renamed-side-1.txt",
+			"7-both-renamed.txt",
+			"7-both-renamed-side-1.txt"
+		},
+		
+		{
+			"7-both-renamed-side-2.txt",
+			"7-both-renamed-side-2.txt",
+			"7-both-renamed.txt"
+		}
+	};
+	
+	opts.checkout_strategy |= GIT_CHECKOUT_SAFE | GIT_CHECKOUT_USE_OURS;
+	
+	create_index(checkout_index_entries, 41);
+	create_index_names(checkout_name_entries, 9);
+	git_index_write(g_index);
+	
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+		
+	ensure_workdir("0a-no-change.txt",
+				   0100644, "68c6c84b091926c7d90aa6a79b2bc3bb6adccd8e");
+	
+	ensure_workdir("0b-duplicated-in-ours.txt",
+				   0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6");
+	
+	ensure_workdir("0b-rewritten-in-ours.txt",
+				   0100644, "e376fbdd06ebf021c92724da9f26f44212734e3e");
+	
+	ensure_workdir("0c-duplicated-in-theirs.txt",
+				   0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31");
+	
+	ensure_workdir("0c-rewritten-in-theirs.txt",
+				   0100644, "efc9121fdedaf08ba180b53ebfbcf71bd488ed09");
+	
+	ensure_workdir("1a-newname-in-ours-edited-in-theirs.txt",
+				   0100644, "0d872f8e871a30208305978ecbf9e66d864f1638");
+	
+	ensure_workdir("1a-newname-in-ours.txt",
+				   0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb");
+	
+	ensure_workdir("1b-newname-in-theirs-edited-in-ours.txt",
+				   0100644, "ed9523e62e453e50dd9be1606af19399b96e397a");
+	
+	ensure_workdir("1b-newname-in-theirs.txt",
+				   0100644, "2b5f1f181ee3b58ea751f5dd5d8f9b445520a136");
+	
+	ensure_workdir("2-newname-in-both.txt",
+				   0100644, "178940b450f238a56c0d75b7955cb57b38191982");
+
+	ensure_workdir("3a-newname-in-ours-deleted-in-theirs.txt",
+				   0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9");
+	
+	ensure_workdir("3b-newname-in-theirs-deleted-in-ours.txt",
+				   0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495");
+	
+	ensure_workdir("4a-newname-in-ours-added-in-theirs.txt",
+				   0100644, "227792b52aaa0b238bea00ec7e509b02623f168c");
+	
+	ensure_workdir("4b-newname-in-theirs-added-in-ours.txt",
+				   0100644, "de872ee3618b894992e9d1e18ba2ebe256a112f9");
+	
+	ensure_workdir("5a-newname-in-ours-added-in-theirs.txt",
+				   0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436");
+		
+	ensure_workdir("5b-newname-in-theirs-added-in-ours.txt",
+				   0100644, "385c8a0f26ddf79e9041e15e17dc352ed2c4cced");
+
+	ensure_workdir("6-both-renamed-1-to-2-ours.txt",
+				   0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450");
+	
+	ensure_workdir("7-both-renamed.txt",
+				   0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11");
+}
+
+void test_checkout_conflict__name_mangled_file_exists_in_workdir(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	struct checkout_index_entry checkout_index_entries[] = {
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 1, "test-one-side-one.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 3, "test-one-side-one.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 1, "test-one-side-two.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 2, "test-one-side-two.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 2, "test-one.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 3, "test-one.txt" },
+
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 1, "test-two-side-one.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 3, "test-two-side-one.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 1, "test-two-side-two.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 2, "test-two-side-two.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 2, "test-two.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 3, "test-two.txt" },
+
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 1, "test-three-side-one.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 3, "test-three-side-one.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 1, "test-three-side-two.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 2, "test-three-side-two.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 2, "test-three.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 3, "test-three.txt" },
+
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "directory_file-one" },
+		{ 0100644, CONFLICTING_OURS_OID, 2, "directory_file-one" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 0, "directory_file-one/file" },
+
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "directory_file-two" },
+		{ 0100644, CONFLICTING_OURS_OID, 0, "directory_file-two/file" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "directory_file-two" },
+	};
+
+	struct checkout_name_entry checkout_name_entries[] = {
+		{
+			"test-one-side-one.txt",
+			"test-one.txt",
+			"test-one-side-one.txt"
+		},
+		{
+			"test-one-side-two.txt",
+			"test-one-side-two.txt",
+			"test-one.txt"
+		},
+
+		{
+			"test-two-side-one.txt",
+			"test-two.txt",
+			"test-two-side-one.txt"
+		},
+		{
+			"test-two-side-two.txt",
+			"test-two-side-two.txt",
+			"test-two.txt"
+		},
+
+		{
+			"test-three-side-one.txt",
+			"test-three.txt",
+			"test-three-side-one.txt"
+		},
+		{
+			"test-three-side-two.txt",
+			"test-three-side-two.txt",
+			"test-three.txt"
+		}
+	};
+
+	opts.checkout_strategy |= GIT_CHECKOUT_SAFE;
+
+	create_index(checkout_index_entries, 24);
+	create_index_names(checkout_name_entries, 6);
+	git_index_write(g_index);
+
+	/* Add some files on disk that conflict with the names that would be chosen
+	 * for the files written for each side. */
+
+	cl_git_rewritefile("merge-resolve/test-one.txt~ours",
+		"Expect index contents to be written to ~ours_0");
+	cl_git_rewritefile("merge-resolve/test-one.txt~theirs",
+		"Expect index contents to be written to ~theirs_0");
+
+	cl_git_rewritefile("merge-resolve/test-two.txt~ours",
+		"Expect index contents to be written to ~ours_3");
+	cl_git_rewritefile("merge-resolve/test-two.txt~theirs",
+		"Expect index contents to be written to ~theirs_3");
+	cl_git_rewritefile("merge-resolve/test-two.txt~ours_0",
+		"Expect index contents to be written to ~ours_3");
+	cl_git_rewritefile("merge-resolve/test-two.txt~theirs_0",
+		"Expect index contents to be written to ~theirs_3");
+	cl_git_rewritefile("merge-resolve/test-two.txt~ours_1",
+		"Expect index contents to be written to ~ours_3");
+	cl_git_rewritefile("merge-resolve/test-two.txt~theirs_1",
+		"Expect index contents to be written to ~theirs_3");
+	cl_git_rewritefile("merge-resolve/test-two.txt~ours_2",
+		"Expect index contents to be written to ~ours_3");
+	cl_git_rewritefile("merge-resolve/test-two.txt~theirs_2",
+		"Expect index contents to be written to ~theirs_3");
+
+	cl_git_rewritefile("merge-resolve/test-three.txt~Ours",
+		"Expect case insensitive filesystems to create ~ours_0");
+	cl_git_rewritefile("merge-resolve/test-three.txt~THEIRS",
+		"Expect case insensitive filesystems to create ~theirs_0");
+
+	cl_git_rewritefile("merge-resolve/directory_file-one~ours",
+		"Index contents written to ~ours_0 in this D/F conflict");
+	cl_git_rewritefile("merge-resolve/directory_file-two~theirs",
+		"Index contents written to ~theirs_0 in this D/F conflict");
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	ensure_workdir("test-one.txt~ours_0",
+		0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11");
+	ensure_workdir("test-one.txt~theirs_0",
+		0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07");
+
+	ensure_workdir("test-two.txt~ours_3",
+		0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11");
+	ensure_workdir("test-two.txt~theirs_3",
+		0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07");
+
+	/* Name is mangled on case insensitive only */
+#if defined(GIT_WIN32) || defined(__APPLE__)
+	ensure_workdir("test-three.txt~ours_0",
+		0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11");
+	ensure_workdir("test-three.txt~theirs_0",
+		0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07");
+#else
+	ensure_workdir("test-three.txt~ours",
+		0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11");
+	ensure_workdir("test-three.txt~theirs",
+		0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07");
+#endif
+
+	ensure_workdir("directory_file-one~ours_0", 0100644, CONFLICTING_OURS_OID);
+	ensure_workdir("directory_file-two~theirs_0", 0100644, CONFLICTING_THEIRS_OID);
+}
+
+void test_checkout_conflict__update_only(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	struct checkout_index_entry checkout_index_entries[] = {
+		{ 0100644, AUTOMERGEABLE_ANCESTOR_OID, 1, "automergeable.txt" },
+		{ 0100644, AUTOMERGEABLE_OURS_OID, 2, "automergeable.txt" },
+		{ 0100644, AUTOMERGEABLE_THEIRS_OID, 3, "automergeable.txt" },
+
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "modify-delete" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "modify-delete" },
+
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "directory_file-one" },
+		{ 0100644, CONFLICTING_OURS_OID, 2, "directory_file-one" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 0, "directory_file-one/file" },
+
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "directory_file-two" },
+		{ 0100644, CONFLICTING_OURS_OID, 0, "directory_file-two/file" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "directory_file-two" },
+	};
+
+	opts.checkout_strategy |= GIT_CHECKOUT_UPDATE_ONLY;
+
+	create_index(checkout_index_entries, 3);
+	git_index_write(g_index);
+
+	cl_git_pass(p_mkdir("merge-resolve/directory_file-two", 0777));
+	cl_git_rewritefile("merge-resolve/directory_file-two/file", CONFLICTING_OURS_FILE);
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	ensure_workdir_contents("automergeable.txt", AUTOMERGEABLE_MERGED_FILE);
+	ensure_workdir("directory_file-two/file", 0100644, CONFLICTING_OURS_OID);
+
+	cl_assert(!git_path_exists("merge-resolve/modify-delete"));
+	cl_assert(!git_path_exists("merge-resolve/test-one.txt"));
+	cl_assert(!git_path_exists("merge-resolve/test-one-side-one.txt"));
+	cl_assert(!git_path_exists("merge-resolve/test-one-side-two.txt"));
+	cl_assert(!git_path_exists("merge-resolve/test-one.txt~ours"));
+	cl_assert(!git_path_exists("merge-resolve/test-one.txt~theirs"));
+	cl_assert(!git_path_exists("merge-resolve/directory_file-one/file"));
+	cl_assert(!git_path_exists("merge-resolve/directory_file-one~ours"));
+	cl_assert(!git_path_exists("merge-resolve/directory_file-two~theirs"));
+}
+
+void test_checkout_conflict__path_filters(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	char *paths[] = { "conflicting-1.txt", "conflicting-3.txt" };
+	git_strarray patharray = {0};
+
+	struct checkout_index_entry checkout_index_entries[] = {
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "conflicting-1.txt" },
+		{ 0100644, CONFLICTING_OURS_OID, 2, "conflicting-1.txt" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "conflicting-1.txt" },
+
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "conflicting-2.txt" },
+		{ 0100644, CONFLICTING_OURS_OID, 2, "conflicting-2.txt" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "conflicting-2.txt" },
+
+		{ 0100644, AUTOMERGEABLE_ANCESTOR_OID, 1, "conflicting-3.txt" },
+		{ 0100644, AUTOMERGEABLE_OURS_OID, 2, "conflicting-3.txt" },
+		{ 0100644, AUTOMERGEABLE_THEIRS_OID, 3, "conflicting-3.txt" },
+
+		{ 0100644, AUTOMERGEABLE_ANCESTOR_OID, 1, "conflicting-4.txt" },
+		{ 0100644, AUTOMERGEABLE_OURS_OID, 2, "conflicting-4.txt" },
+		{ 0100644, AUTOMERGEABLE_THEIRS_OID, 3, "conflicting-4.txt" },
+	};
+
+	patharray.count = 2;
+	patharray.strings = paths;
+
+	opts.paths = patharray;
+
+	create_index(checkout_index_entries, 12);
+	git_index_write(g_index);
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	ensure_workdir_contents("conflicting-1.txt", CONFLICTING_DIFF3_FILE);
+	cl_assert(!git_path_exists("merge-resolve/conflicting-2.txt"));
+	ensure_workdir_contents("conflicting-3.txt", AUTOMERGEABLE_MERGED_FILE);
+	cl_assert(!git_path_exists("merge-resolve/conflicting-4.txt"));
+}
+
+static void collect_progress(
+	const char *path,
+	size_t completed_steps,
+	size_t total_steps,
+	void *payload)
+{
+	git_vector *paths = payload;
+
+	GIT_UNUSED(completed_steps);
+	GIT_UNUSED(total_steps);
+
+	if (path == NULL)
+		return;
+
+	git_vector_insert(paths, strdup(path));
+}
+
+void test_checkout_conflict__report_progress(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_vector paths = GIT_VECTOR_INIT;
+	char *path;
+	size_t i;
+
+	struct checkout_index_entry checkout_index_entries[] = {
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "conflicting-1.txt" },
+		{ 0100644, CONFLICTING_OURS_OID, 2, "conflicting-1.txt" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "conflicting-1.txt" },
+
+		{ 0100644, CONFLICTING_ANCESTOR_OID, 1, "conflicting-2.txt" },
+		{ 0100644, CONFLICTING_OURS_OID, 2, "conflicting-2.txt" },
+		{ 0100644, CONFLICTING_THEIRS_OID, 3, "conflicting-2.txt" },
+
+		{ 0100644, AUTOMERGEABLE_ANCESTOR_OID, 1, "conflicting-3.txt" },
+		{ 0100644, AUTOMERGEABLE_OURS_OID, 2, "conflicting-3.txt" },
+		{ 0100644, AUTOMERGEABLE_THEIRS_OID, 3, "conflicting-3.txt" },
+
+		{ 0100644, AUTOMERGEABLE_ANCESTOR_OID, 1, "conflicting-4.txt" },
+		{ 0100644, AUTOMERGEABLE_OURS_OID, 2, "conflicting-4.txt" },
+		{ 0100644, AUTOMERGEABLE_THEIRS_OID, 3, "conflicting-4.txt" },
+	};
+
+	opts.progress_cb = collect_progress;
+	opts.progress_payload = &paths;
+
+
+	create_index(checkout_index_entries, 12);
+	git_index_write(g_index);
+
+	cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
+
+	cl_assert_equal_i(4, git_vector_length(&paths));
+	cl_assert_equal_s("conflicting-1.txt", git_vector_get(&paths, 0));
+	cl_assert_equal_s("conflicting-2.txt", git_vector_get(&paths, 1));
+	cl_assert_equal_s("conflicting-3.txt", git_vector_get(&paths, 2));
+	cl_assert_equal_s("conflicting-4.txt", git_vector_get(&paths, 3));
+
+	git_vector_foreach(&paths, i, path)
+		git__free(path);
+
+	git_vector_free(&paths);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/crlf.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/crlf.c
new file mode 100755
index 0000000..8e77d08
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/crlf.c
@@ -0,0 +1,463 @@
+#include "clar_libgit2.h"
+#include "checkout_helpers.h"
+#include "../filter/crlf.h"
+#include "fileops.h"
+
+#include "git2/checkout.h"
+#include "repository.h"
+#include "index.h"
+#include "posix.h"
+
+static git_repository *g_repo;
+
+static const char *systype;
+static git_buf expected_fixture = GIT_BUF_INIT;
+
+void test_checkout_crlf__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("crlf");
+
+	if (GIT_EOL_NATIVE == GIT_EOL_CRLF)
+		systype = "windows";
+	else
+		systype = "posix";
+}
+
+void test_checkout_crlf__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+
+	if (expected_fixture.size) {
+		cl_fixture_cleanup(expected_fixture.ptr);
+		git_buf_free(&expected_fixture);
+	}
+}
+
+struct compare_data
+{
+	const char *dirname;
+	const char *autocrlf;
+	const char *attrs;
+};
+
+static int compare_file(void *payload, git_buf *actual_path)
+{
+	git_buf expected_path = GIT_BUF_INIT;
+	git_buf actual_contents = GIT_BUF_INIT;
+	git_buf expected_contents = GIT_BUF_INIT;
+	struct compare_data *cd = payload;
+	bool failed = true;
+	int cmp_git, cmp_gitattributes;
+	char *basename;
+
+	basename = git_path_basename(actual_path->ptr);
+	cmp_git = strcmp(basename, ".git");
+	cmp_gitattributes = strcmp(basename, ".gitattributes");
+
+	if (cmp_git == 0 || cmp_gitattributes == 0) {
+		failed = false;
+		goto done;
+	}
+
+	cl_git_pass(git_buf_joinpath(&expected_path, cd->dirname, basename));
+
+	if (!git_path_isfile(expected_path.ptr) ||
+		!git_path_isfile(actual_path->ptr))
+		goto done;
+
+	if (git_futils_readbuffer(&actual_contents, actual_path->ptr) < 0 ||
+		git_futils_readbuffer(&expected_contents, expected_path.ptr) < 0)
+		goto done;
+
+	if (actual_contents.size != expected_contents.size)
+		goto done;
+
+	if (memcmp(actual_contents.ptr, expected_contents.ptr, expected_contents.size) != 0)
+		goto done;
+
+	failed = false;
+
+done:
+	if (failed) {
+		git_buf details = GIT_BUF_INIT;
+		git_buf_printf(&details, "filename=%s, system=%s, autocrlf=%s, attrs={%s}",
+			git_path_basename(actual_path->ptr), systype, cd->autocrlf, cd->attrs);
+		clar__fail(__FILE__, __LINE__,
+			"checked out contents did not match expected", details.ptr, 0);
+		git_buf_free(&details);
+	}
+
+	git__free(basename);
+	git_buf_free(&expected_contents);
+	git_buf_free(&actual_contents);
+	git_buf_free(&expected_path);
+
+	return 0;
+}
+
+static void test_checkout(const char *autocrlf, const char *attrs)
+{
+	git_buf attrbuf = GIT_BUF_INIT;
+	git_buf expected_dirname = GIT_BUF_INIT;
+	git_buf sandboxname = GIT_BUF_INIT;
+	git_buf reponame = GIT_BUF_INIT;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	struct compare_data compare_data = { NULL, autocrlf, attrs };
+	const char *c;
+
+	git_buf_puts(&reponame, "crlf");
+
+	git_buf_puts(&sandboxname, "autocrlf_");
+	git_buf_puts(&sandboxname, autocrlf);
+
+	if (*attrs) {
+		git_buf_puts(&sandboxname, ",");
+
+		for (c = attrs; *c; c++) {
+			if (*c == ' ')
+				git_buf_putc(&sandboxname, ',');
+			else if (*c == '=')
+				git_buf_putc(&sandboxname, '_');
+			else
+				git_buf_putc(&sandboxname, *c);
+		}
+
+		git_buf_printf(&attrbuf, "* %s\n", attrs);
+		cl_git_mkfile("crlf/.gitattributes", attrbuf.ptr);
+	}
+
+	cl_repo_set_string(g_repo, "core.autocrlf", autocrlf);
+
+	git_buf_joinpath(&expected_dirname, systype, sandboxname.ptr);
+	git_buf_joinpath(&expected_fixture, "crlf_data", expected_dirname.ptr);
+	cl_fixture_sandbox(expected_fixture.ptr);
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+	git_checkout_head(g_repo, &opts);
+
+	compare_data.dirname = sandboxname.ptr;
+	cl_git_pass(git_path_direach(&reponame, 0, compare_file, &compare_data));
+
+	cl_fixture_cleanup(expected_fixture.ptr);
+	git_buf_free(&expected_fixture);
+
+	git_buf_free(&attrbuf);
+	git_buf_free(&expected_fixture);
+	git_buf_free(&expected_dirname);
+	git_buf_free(&sandboxname);
+	git_buf_free(&reponame);
+}
+
+static void empty_workdir(const char *name)
+{
+	git_vector contents = GIT_VECTOR_INIT;
+	size_t i;
+	const char *fn;
+
+	git_path_dirload(&contents, name, 0, 0);
+	git_vector_foreach(&contents, i, fn) {
+		char *basename = git_path_basename(fn);
+		int cmp = strncasecmp(basename, ".git", 4);
+
+		git__free(basename);
+
+		if (cmp == 0)
+			continue;
+		p_unlink(fn);
+	}
+	git_vector_free_deep(&contents);
+}
+
+void test_checkout_crlf__matches_core_git(void)
+{
+	const char *autocrlf[] = { "true", "false", "input", NULL };
+	const char *attrs[] = { "", "-crlf", "-text", "eol=crlf", "eol=lf",
+		"text", "text eol=crlf", "text eol=lf",
+		"text=auto", "text=auto eol=crlf", "text=auto eol=lf", 
+		NULL };
+	const char **a, **b;
+
+	for (a = autocrlf; *a; a++) {
+		for (b = attrs; *b; b++) {
+			empty_workdir("crlf");
+			test_checkout(*a, *b);
+		}
+	}
+}
+
+void test_checkout_crlf__detect_crlf_autocrlf_false(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", false);
+
+	git_checkout_head(g_repo, &opts);
+
+	check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW);
+	check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW);
+}
+
+void test_checkout_crlf__autocrlf_false_index_size_is_unfiltered_size(void)
+{
+	git_index *index;
+	const git_index_entry *entry;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", false);
+
+	git_repository_index(&index, g_repo);
+	tick_index(index);
+
+	git_checkout_head(g_repo, &opts);
+
+	cl_assert((entry = git_index_get_bypath(index, "all-lf", 0)) != NULL);
+	cl_assert(entry->file_size == strlen(ALL_LF_TEXT_RAW));
+
+	cl_assert((entry = git_index_get_bypath(index, "all-crlf", 0)) != NULL);
+	cl_assert(entry->file_size == strlen(ALL_CRLF_TEXT_RAW));
+
+	git_index_free(index);
+}
+
+void test_checkout_crlf__detect_crlf_autocrlf_true(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	git_checkout_head(g_repo, &opts);
+
+	check_file_contents("./crlf/all-lf", ALL_LF_TEXT_AS_CRLF);
+	check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW);
+}
+
+void test_checkout_crlf__detect_crlf_autocrlf_true_utf8(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	git_repository_set_head(g_repo, "refs/heads/master");
+	git_checkout_head(g_repo, &opts);
+
+	check_file_contents("./crlf/few-utf8-chars-lf", FEW_UTF8_CRLF_RAW);
+	check_file_contents("./crlf/many-utf8-chars-lf", MANY_UTF8_CRLF_RAW);
+
+	check_file_contents("./crlf/few-utf8-chars-crlf", FEW_UTF8_CRLF_RAW);
+	check_file_contents("./crlf/many-utf8-chars-crlf", MANY_UTF8_CRLF_RAW);
+}
+
+void test_checkout_crlf__autocrlf_true_index_size_is_filtered_size(void)
+{
+	git_index *index;
+	const git_index_entry *entry;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	git_repository_index(&index, g_repo);
+	tick_index(index);
+
+	git_checkout_head(g_repo, &opts);
+
+	cl_assert((entry = git_index_get_bypath(index, "all-lf", 0)) != NULL);
+
+	cl_assert_equal_sz(strlen(ALL_LF_TEXT_AS_CRLF), entry->file_size);
+
+	cl_assert((entry = git_index_get_bypath(index, "all-crlf", 0)) != NULL);
+	cl_assert_equal_sz(strlen(ALL_CRLF_TEXT_RAW), entry->file_size);
+
+	git_index_free(index);
+}
+
+void test_checkout_crlf__with_ident(void)
+{
+	git_index *index;
+	git_blob *blob;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_mkfile("crlf/.gitattributes",
+		"*.txt text\n*.bin binary\n"
+		"*.crlf text eol=crlf\n"
+		"*.lf text eol=lf\n"
+		"*.ident text ident\n"
+		"*.identcrlf ident text eol=crlf\n"
+		"*.identlf ident text eol=lf\n");
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	/* add files with $Id$ */
+
+	cl_git_mkfile("crlf/lf.ident", ALL_LF_TEXT_RAW "\n$Id: initial content$\n");
+	cl_git_mkfile("crlf/crlf.ident", ALL_CRLF_TEXT_RAW "\r\n$Id$\r\n\r\n");
+	cl_git_mkfile("crlf/more1.identlf", "$Id$\n" MORE_LF_TEXT_RAW);
+	cl_git_mkfile("crlf/more2.identcrlf", "\r\n$Id: $\r\n" MORE_CRLF_TEXT_RAW);
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_add_bypath(index, "lf.ident"));
+	cl_git_pass(git_index_add_bypath(index, "crlf.ident"));
+	cl_git_pass(git_index_add_bypath(index, "more1.identlf"));
+	cl_git_pass(git_index_add_bypath(index, "more2.identcrlf"));
+	cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "Some ident files\n");
+
+	git_checkout_head(g_repo, &opts);
+
+	/* check that blobs have $Id$ */
+
+	cl_git_pass(git_blob_lookup(&blob, g_repo,
+		& git_index_get_bypath(index, "lf.ident", 0)->id));
+	cl_assert_equal_s(
+		ALL_LF_TEXT_RAW "\n$Id$\n", git_blob_rawcontent(blob));
+	git_blob_free(blob);
+
+	cl_git_pass(git_blob_lookup(&blob, g_repo,
+		& git_index_get_bypath(index, "more2.identcrlf", 0)->id));
+	cl_assert_equal_s(
+		"\n$Id$\n" MORE_CRLF_TEXT_AS_LF, git_blob_rawcontent(blob));
+	git_blob_free(blob);
+
+	/* check that filesystem is initially untouched - matching core Git */
+
+	cl_assert_equal_file(
+		ALL_LF_TEXT_RAW "\n$Id: initial content$\n", 0, "crlf/lf.ident");
+
+	/* check that forced checkout rewrites correctly */
+
+	p_unlink("crlf/lf.ident");
+	p_unlink("crlf/crlf.ident");
+	p_unlink("crlf/more1.identlf");
+	p_unlink("crlf/more2.identcrlf");
+
+	git_checkout_head(g_repo, &opts);
+
+	cl_assert_equal_file(
+		ALL_LF_TEXT_AS_CRLF
+		"\r\n$Id: fcf6d4d9c212dc66563b1171b1cd99953c756467 $\r\n",
+		0, "crlf/lf.ident");
+	cl_assert_equal_file(
+		ALL_CRLF_TEXT_RAW
+		"\r\n$Id: f2c66ad9b2b5a734d9bf00d5000cc10a62b8a857 $\r\n\r\n",
+		0, "crlf/crlf.ident");
+
+	cl_assert_equal_file(
+		"$Id: f7830382dac1f1583422be5530fdfbd26289431b $\n"
+		MORE_LF_TEXT_AS_LF, 0, "crlf/more1.identlf");
+
+	cl_assert_equal_file(
+		"\r\n$Id: 74677a68413012ce8d7e7cfc3f12603df3a3eac4 $\r\n"
+		MORE_CRLF_TEXT_AS_CRLF, 0, "crlf/more2.identcrlf");
+
+	git_index_free(index);
+}
+
+void test_checkout_crlf__autocrlf_false_no_attrs(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", false);
+
+	git_checkout_head(g_repo, &opts);
+
+	check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW);
+	check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW);
+}
+
+void test_checkout_crlf__autocrlf_true_no_attrs(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	git_checkout_head(g_repo, &opts);
+
+	check_file_contents("./crlf/all-lf", ALL_LF_TEXT_AS_CRLF);
+	check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_AS_CRLF);
+}
+
+void test_checkout_crlf__autocrlf_input_no_attrs(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_repo_set_string(g_repo, "core.autocrlf", "input");
+
+	git_checkout_head(g_repo, &opts);
+
+	check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW);
+	check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW);
+}
+
+void test_checkout_crlf__autocrlf_false_text_auto_attr(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n");
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", false);
+
+	git_checkout_head(g_repo, &opts);
+
+	if (GIT_EOL_NATIVE == GIT_EOL_CRLF) {
+		check_file_contents("./crlf/all-lf", ALL_LF_TEXT_AS_CRLF);
+		check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_AS_CRLF);
+	} else {
+		check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW);
+		check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW);
+	}
+}
+
+void test_checkout_crlf__autocrlf_true_text_auto_attr(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n");
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	git_checkout_head(g_repo, &opts);
+
+	check_file_contents("./crlf/all-lf", ALL_LF_TEXT_AS_CRLF);
+	check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_AS_CRLF);
+}
+
+void test_checkout_crlf__autocrlf_input_text_auto_attr(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n");
+
+	cl_repo_set_string(g_repo, "core.autocrlf", "input");
+
+	git_checkout_head(g_repo, &opts);
+
+	check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW);
+	check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW);
+}
+
+void test_checkout_crlf__can_write_empty_file(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	git_repository_set_head(g_repo, "refs/heads/empty-files");
+	git_checkout_head(g_repo, &opts);
+
+	check_file_contents("./crlf/test1.txt", "");
+
+	check_file_contents("./crlf/test2.txt", "test2.txt's content\r\n");
+
+	check_file_contents("./crlf/test3.txt", "");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/head.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/head.c
new file mode 100755
index 0000000..07cc1d2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/head.c
@@ -0,0 +1,62 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+#include "repo/repo_helpers.h"
+#include "path.h"
+#include "fileops.h"
+
+static git_repository *g_repo;
+
+void test_checkout_head__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_checkout_head__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_checkout_head__unborn_head_returns_GIT_EUNBORNBRANCH(void)
+{
+	make_head_unborn(g_repo, NON_EXISTING_HEAD);
+
+	cl_assert_equal_i(GIT_EUNBORNBRANCH, git_checkout_head(g_repo, NULL));
+}
+
+void test_checkout_head__with_index_only_tree(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_index *index;
+
+	/* let's start by getting things into a known state */
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+	cl_git_pass(git_checkout_head(g_repo, &opts));
+
+	/* now let's stage some new stuff including a new directory */
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	p_mkdir("testrepo/newdir", 0777);
+    cl_git_mkfile("testrepo/newdir/newfile.txt", "new file\n");
+
+	cl_git_pass(git_index_add_bypath(index, "newdir/newfile.txt"));
+	cl_git_pass(git_index_write(index));
+
+	cl_assert(git_path_isfile("testrepo/newdir/newfile.txt"));
+	cl_assert(git_index_get_bypath(index, "newdir/newfile.txt", 0) != NULL);
+
+	git_index_free(index);
+
+	/* okay, so now we have staged this new file; let's see if we can remove */
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED;
+	cl_git_pass(git_checkout_head(g_repo, &opts));
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_assert(!git_path_isfile("testrepo/newdir/newfile.txt"));
+	cl_assert(git_index_get_bypath(index, "newdir/newfile.txt", 0) == NULL);
+
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/icase.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/icase.c
new file mode 100755
index 0000000..55ab3ab
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/icase.c
@@ -0,0 +1,303 @@
+#include "clar_libgit2.h"
+
+#include "git2/checkout.h"
+#include "refs.h"
+#include "path.h"
+
+#ifdef GIT_WIN32
+# include <windows.h>
+#else
+# include <dirent.h>
+#endif
+
+static git_repository *repo;
+static git_object *obj;
+static git_checkout_options checkout_opts;
+
+void test_checkout_icase__initialize(void)
+{
+	git_oid id;
+	git_config *cfg;
+	int icase = 0;
+
+	repo = cl_git_sandbox_init("testrepo");
+
+	cl_git_pass(git_repository_config_snapshot(&cfg, repo));
+	git_config_get_bool(&icase, cfg, "core.ignorecase");
+	git_config_free(cfg);
+
+	if (!icase)
+		cl_skip();
+
+	cl_git_pass(git_reference_name_to_id(&id, repo, "refs/heads/dir"));
+	cl_git_pass(git_object_lookup(&obj, repo, &id, GIT_OBJ_ANY));
+
+	git_checkout_init_options(&checkout_opts, GIT_CHECKOUT_OPTIONS_VERSION);
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_NONE;
+}
+
+void test_checkout_icase__cleanup(void)
+{
+	git_object_free(obj);
+	cl_git_sandbox_cleanup();
+}
+
+static char *get_filename(const char *in)
+{
+#ifdef GIT_WIN32
+	HANDLE fh;
+	HMODULE kerneldll;
+	char *filename;
+
+	typedef DWORD (__stdcall *getfinalpathname)(HANDLE, LPSTR, DWORD, DWORD);
+	getfinalpathname getfinalpathfn;
+
+	cl_assert(filename = malloc(MAX_PATH));
+	cl_assert(kerneldll = LoadLibrary("kernel32.dll"));
+	cl_assert(getfinalpathfn = (getfinalpathname)GetProcAddress(kerneldll, "GetFinalPathNameByHandleA"));
+
+	cl_assert(fh = CreateFileA(in, FILE_READ_ATTRIBUTES | STANDARD_RIGHTS_READ, FILE_SHARE_READ,
+		NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL));
+
+	cl_win32_pass(getfinalpathfn(fh, filename, MAX_PATH, VOLUME_NAME_DOS));
+
+	CloseHandle(fh);
+
+	git_path_mkposix(filename);
+
+	return filename;
+#else
+	char *search_dirname, *search_filename, *filename = NULL;
+	git_buf out = GIT_BUF_INIT;
+	DIR *dir;
+	struct dirent *de;
+
+	cl_assert(search_dirname = git_path_dirname(in));
+	cl_assert(search_filename = git_path_basename(in));
+
+	cl_assert(dir = opendir(search_dirname));
+
+	while ((de = readdir(dir))) {
+		if (strcasecmp(de->d_name, search_filename) == 0) {
+			git_buf_join(&out, '/', search_dirname, de->d_name);
+			filename = git_buf_detach(&out);
+			break;
+		}
+	}
+
+	closedir(dir);
+
+	git__free(search_dirname);
+	git__free(search_filename);
+	git_buf_free(&out);
+
+	return filename;
+#endif
+}
+
+static void assert_name_is(const char *expected)
+{
+	char *actual;
+	size_t actual_len, expected_len, start;
+
+	cl_assert(actual = get_filename(expected));
+
+	expected_len = strlen(expected);
+	actual_len = strlen(actual);
+	cl_assert(actual_len >= expected_len);
+
+	start = actual_len - expected_len;
+	cl_assert_equal_s(expected, actual + start);
+
+	if (start)
+		cl_assert_equal_strn("/", actual + (start - 1), 1);
+
+	free(actual);
+}
+
+void test_checkout_icase__refuses_to_overwrite_files_for_files(void)
+{
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE|GIT_CHECKOUT_RECREATE_MISSING;
+
+	cl_git_write2file("testrepo/BRANCH_FILE.txt", "neue file\n", 10, \
+		O_WRONLY | O_CREAT | O_TRUNC, 0644);
+
+	cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
+	assert_name_is("testrepo/BRANCH_FILE.txt");
+}
+
+void test_checkout_icase__overwrites_files_for_files_when_forced(void)
+{
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_write2file("testrepo/NEW.txt", "neue file\n", 10, \
+		O_WRONLY | O_CREAT | O_TRUNC, 0644);
+
+	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
+	assert_name_is("testrepo/new.txt");
+}
+
+void test_checkout_icase__refuses_to_overwrite_links_for_files(void)
+{
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE|GIT_CHECKOUT_RECREATE_MISSING;
+
+	cl_must_pass(p_symlink("../tmp", "testrepo/BRANCH_FILE.txt"));
+
+	cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
+
+	cl_assert(!git_path_exists("tmp"));
+	assert_name_is("testrepo/BRANCH_FILE.txt");
+}
+
+void test_checkout_icase__overwrites_links_for_files_when_forced(void)
+{
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_must_pass(p_symlink("../tmp", "testrepo/NEW.txt"));
+
+	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
+
+	cl_assert(!git_path_exists("tmp"));
+	assert_name_is("testrepo/new.txt");
+}
+
+void test_checkout_icase__overwrites_empty_folders_for_files(void)
+{
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE|GIT_CHECKOUT_RECREATE_MISSING;
+
+	cl_must_pass(p_mkdir("testrepo/NEW.txt", 0777));
+
+	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
+
+	assert_name_is("testrepo/new.txt");
+	cl_assert(!git_path_isdir("testrepo/new.txt"));
+}
+
+void test_checkout_icase__refuses_to_overwrite_populated_folders_for_files(void)
+{
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE|GIT_CHECKOUT_RECREATE_MISSING;
+
+	cl_must_pass(p_mkdir("testrepo/BRANCH_FILE.txt", 0777));
+	cl_git_write2file("testrepo/BRANCH_FILE.txt/foobar", "neue file\n", 10, \
+		O_WRONLY | O_CREAT | O_TRUNC, 0644);
+
+	cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
+
+	assert_name_is("testrepo/BRANCH_FILE.txt");
+	cl_assert(git_path_isdir("testrepo/BRANCH_FILE.txt"));
+}
+
+void test_checkout_icase__overwrites_folders_for_files_when_forced(void)
+{
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_must_pass(p_mkdir("testrepo/NEW.txt", 0777));
+	cl_git_write2file("testrepo/NEW.txt/foobar", "neue file\n", 10, \
+		O_WRONLY | O_CREAT | O_TRUNC, 0644);
+
+	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
+
+	assert_name_is("testrepo/new.txt");
+	cl_assert(!git_path_isdir("testrepo/new.txt"));
+}
+
+void test_checkout_icase__refuses_to_overwrite_files_for_folders(void)
+{
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE|GIT_CHECKOUT_RECREATE_MISSING;
+
+	cl_git_write2file("testrepo/A", "neue file\n", 10, \
+		O_WRONLY | O_CREAT | O_TRUNC, 0644);
+
+	cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
+	assert_name_is("testrepo/A");
+	cl_assert(!git_path_isdir("testrepo/A"));
+}
+
+void test_checkout_icase__overwrites_files_for_folders_when_forced(void)
+{
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_write2file("testrepo/A", "neue file\n", 10, \
+		O_WRONLY | O_CREAT | O_TRUNC, 0644);
+
+	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
+	assert_name_is("testrepo/a");
+	cl_assert(git_path_isdir("testrepo/a"));
+}
+
+void test_checkout_icase__refuses_to_overwrite_links_for_folders(void)
+{
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE|GIT_CHECKOUT_RECREATE_MISSING;
+
+	cl_must_pass(p_symlink("..", "testrepo/A"));
+
+	cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
+
+	cl_assert(!git_path_exists("b.txt"));
+	assert_name_is("testrepo/A");
+}
+
+void test_checkout_icase__overwrites_links_for_folders_when_forced(void)
+{
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_must_pass(p_symlink("..", "testrepo/A"));
+
+	cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
+
+	cl_assert(!git_path_exists("b.txt"));
+	assert_name_is("testrepo/a");
+}
+
+void test_checkout_icase__ignores_unstaged_casechange(void)
+{
+	git_reference *orig_ref, *br2_ref;
+	git_commit *orig, *br2;
+	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+	cl_git_pass(git_reference_lookup_resolved(&orig_ref, repo, "HEAD", 100));
+	cl_git_pass(git_commit_lookup(&orig, repo, git_reference_target(orig_ref)));
+	cl_git_pass(git_reset(repo, (git_object *)orig, GIT_RESET_HARD, NULL));
+
+	cl_rename("testrepo/branch_file.txt", "testrepo/Branch_File.txt");
+
+	cl_git_pass(git_reference_lookup_resolved(&br2_ref, repo, "refs/heads/br2", 100));
+	cl_git_pass(git_commit_lookup(&br2, repo, git_reference_target(br2_ref)));
+
+	cl_git_pass(git_checkout_tree(repo, (const git_object *)br2, &checkout_opts));
+
+	git_commit_free(orig);
+	git_commit_free(br2);
+	git_reference_free(orig_ref);
+	git_reference_free(br2_ref);
+}
+
+void test_checkout_icase__conflicts_with_casechanged_subtrees(void)
+{
+	git_reference *orig_ref;
+	git_object *orig, *subtrees;
+	git_oid oid;
+	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+	cl_git_pass(git_reference_lookup_resolved(&orig_ref, repo, "HEAD", 100));
+	cl_git_pass(git_object_lookup(&orig, repo, git_reference_target(orig_ref), GIT_OBJ_COMMIT));
+	cl_git_pass(git_reset(repo, (git_object *)orig, GIT_RESET_HARD, NULL));
+
+	cl_must_pass(p_mkdir("testrepo/AB", 0777));
+	cl_must_pass(p_mkdir("testrepo/AB/C", 0777));
+	cl_git_write2file("testrepo/AB/C/3.txt", "Foobar!\n", 8, O_RDWR|O_CREAT, 0666);
+
+	cl_git_pass(git_reference_name_to_id(&oid, repo, "refs/heads/subtrees"));
+	cl_git_pass(git_object_lookup(&subtrees, repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_fail(git_checkout_tree(repo, subtrees, &checkout_opts));
+
+	git_object_free(orig);
+	git_object_free(subtrees);
+    git_reference_free(orig_ref);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/index.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/index.c
new file mode 100755
index 0000000..0d220e1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/index.c
@@ -0,0 +1,774 @@
+#include "clar_libgit2.h"
+#include "checkout_helpers.h"
+
+#include "git2/checkout.h"
+#include "fileops.h"
+#include "repository.h"
+#include "remote.h"
+
+static git_repository *g_repo;
+
+void test_checkout_index__initialize(void)
+{
+	git_tree *tree;
+
+	g_repo = cl_git_sandbox_init("testrepo");
+
+	cl_git_pass(git_repository_head_tree(&tree, g_repo));
+
+	reset_index_to_treeish((git_object *)tree);
+	git_tree_free(tree);
+
+	cl_git_rewritefile(
+		"./testrepo/.gitattributes",
+		"* text eol=lf\n");
+}
+
+void test_checkout_index__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+
+	/* try to remove alternative dir */
+	if (git_path_isdir("alternative"))
+		git_futils_rmdir_r("alternative", NULL, GIT_RMDIR_REMOVE_FILES);
+}
+
+void test_checkout_index__cannot_checkout_a_bare_repository(void)
+{
+	test_checkout_index__cleanup();
+
+	g_repo = cl_git_sandbox_init("testrepo.git");
+
+	cl_git_fail(git_checkout_index(g_repo, NULL, NULL));
+}
+
+void test_checkout_index__can_create_missing_files(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
+	cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt"));
+	cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	check_file_contents("./testrepo/README", "hey there\n");
+	check_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n");
+	check_file_contents("./testrepo/new.txt", "my new file\n");
+}
+
+void test_checkout_index__can_remove_untracked_files(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	git_futils_mkdir("./testrepo/dir/subdir/subsubdir", NULL, 0755, GIT_MKDIR_PATH);
+	cl_git_mkfile("./testrepo/dir/one", "one\n");
+	cl_git_mkfile("./testrepo/dir/subdir/two", "two\n");
+
+	cl_assert_equal_i(true, git_path_isdir("./testrepo/dir/subdir/subsubdir"));
+
+	opts.checkout_strategy =
+		GIT_CHECKOUT_SAFE |
+		GIT_CHECKOUT_RECREATE_MISSING |
+		GIT_CHECKOUT_REMOVE_UNTRACKED;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	cl_assert_equal_i(false, git_path_isdir("./testrepo/dir"));
+}
+
+void test_checkout_index__honor_the_specified_pathspecs(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	char *entries[] = { "*.txt" };
+
+	opts.paths.strings = entries;
+	opts.paths.count = 1;
+
+	cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
+	cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt"));
+	cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
+	check_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n");
+	check_file_contents("./testrepo/new.txt", "my new file\n");
+}
+
+void test_checkout_index__honor_the_gitattributes_directives(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	const char *attributes =
+		"branch_file.txt text eol=crlf\n"
+		"new.txt text eol=lf\n";
+
+	cl_git_mkfile("./testrepo/.gitattributes", attributes);
+	cl_repo_set_bool(g_repo, "core.autocrlf", false);
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	check_file_contents("./testrepo/README", "hey there\n");
+	check_file_contents("./testrepo/new.txt", "my new file\n");
+	check_file_contents("./testrepo/branch_file.txt", "hi\r\nbye!\r\n");
+}
+
+void test_checkout_index__honor_coreautocrlf_setting_set_to_true(void)
+{
+#ifdef GIT_WIN32
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	const char *expected_readme_text = "hey there\r\n";
+
+	cl_git_pass(p_unlink("./testrepo/.gitattributes"));
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	check_file_contents("./testrepo/README", expected_readme_text);
+#endif
+}
+
+void test_checkout_index__honor_coresymlinks_default(void)
+{
+	git_repository *repo;
+	git_remote *origin;
+	git_object *target;
+	char cwd[GIT_PATH_MAX];
+
+	const char *url = git_repository_path(g_repo);
+
+	cl_assert(getcwd(cwd, sizeof(cwd)) != NULL);
+	cl_assert_equal_i(0, p_mkdir("readonly", 0555)); // Read-only directory
+	cl_assert_equal_i(0, chdir("readonly"));
+	cl_git_pass(git_repository_init(&repo, "../symlink.git", true));
+	cl_assert_equal_i(0, chdir(cwd));
+	cl_assert_equal_i(0, p_mkdir("symlink", 0777));
+	cl_git_pass(git_repository_set_workdir(repo, "symlink", 1));
+
+	cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
+	cl_git_pass(git_remote_fetch(origin, NULL, NULL, NULL));
+	git_remote_free(origin);
+
+	cl_git_pass(git_revparse_single(&target, repo, "remotes/origin/master"));
+	cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL));
+	git_object_free(target);
+	git_repository_free(repo);
+
+#ifdef GIT_WIN32
+	check_file_contents("./symlink/link_to_new.txt", "new.txt");
+#else
+	{
+		char link_data[1024];
+		size_t link_size = 1024;
+
+		link_size = p_readlink("./symlink/link_to_new.txt", link_data, link_size);
+		link_data[link_size] = '\0';
+		cl_assert_equal_i(link_size, strlen("new.txt"));
+		cl_assert_equal_s(link_data, "new.txt");
+		check_file_contents("./symlink/link_to_new.txt", "my new file\n");
+	}
+#endif
+
+	cl_fixture_cleanup("symlink");
+}
+
+void test_checkout_index__honor_coresymlinks_setting_set_to_true(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	cl_repo_set_bool(g_repo, "core.symlinks", true);
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+#ifdef GIT_WIN32
+	check_file_contents("./testrepo/link_to_new.txt", "new.txt");
+#else
+	{
+		char link_data[1024];
+		size_t link_size = 1024;
+
+		link_size = p_readlink("./testrepo/link_to_new.txt", link_data, link_size);
+		link_data[link_size] = '\0';
+		cl_assert_equal_i(link_size, strlen("new.txt"));
+		cl_assert_equal_s(link_data, "new.txt");
+		check_file_contents("./testrepo/link_to_new.txt", "my new file\n");
+	}
+#endif
+}
+
+void test_checkout_index__honor_coresymlinks_setting_set_to_false(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	cl_repo_set_bool(g_repo, "core.symlinks", false);
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	check_file_contents("./testrepo/link_to_new.txt", "new.txt");
+}
+
+void test_checkout_index__donot_overwrite_modified_file_by_default(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	cl_git_mkfile("./testrepo/new.txt", "This isn't what's stored!");
+
+	/* set this up to not return an error code on conflicts, but it
+	 * still will not have permission to overwrite anything...
+	 */
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_ALLOW_CONFLICTS;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	check_file_contents("./testrepo/new.txt", "This isn't what's stored!");
+}
+
+void test_checkout_index__can_overwrite_modified_file(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	cl_git_mkfile("./testrepo/new.txt", "This isn't what's stored!");
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	check_file_contents("./testrepo/new.txt", "my new file\n");
+}
+
+void test_checkout_index__options_disable_filters(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	cl_git_mkfile("./testrepo/.gitattributes", "*.txt text eol=crlf\n");
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
+	opts.disable_filters = false;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	check_file_contents("./testrepo/new.txt", "my new file\r\n");
+
+	p_unlink("./testrepo/new.txt");
+
+	opts.disable_filters = true;
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	check_file_contents("./testrepo/new.txt", "my new file\n");
+}
+
+void test_checkout_index__options_dir_modes(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	struct stat st;
+	git_oid oid;
+	git_commit *commit;
+	mode_t um;
+
+	if (!cl_is_chmod_supported())
+		return;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
+	cl_git_pass(git_commit_lookup(&commit, g_repo, &oid));
+
+	reset_index_to_treeish((git_object *)commit);
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
+	opts.dir_mode = 0701;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	/* umask will influence actual directory creation mode */
+	(void)p_umask(um = p_umask(022));
+
+	cl_git_pass(p_stat("./testrepo/a", &st));
+	cl_assert_equal_i_fmt(st.st_mode, (GIT_FILEMODE_TREE | 0701) & ~um, "%07o");
+
+	/* File-mode test, since we're on the 'dir' branch */
+	cl_git_pass(p_stat("./testrepo/a/b.txt", &st));
+	cl_assert_equal_i_fmt(st.st_mode, GIT_FILEMODE_BLOB_EXECUTABLE, "%07o");
+
+	git_commit_free(commit);
+}
+
+void test_checkout_index__options_override_file_modes(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	struct stat st;
+
+	if (!cl_is_chmod_supported())
+		return;
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
+	opts.file_mode = 0700;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	cl_git_pass(p_stat("./testrepo/new.txt", &st));
+	cl_assert_equal_i_fmt(st.st_mode & GIT_MODE_PERMS_MASK, 0700, "%07o");
+}
+
+void test_checkout_index__options_open_flags(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	cl_git_mkfile("./testrepo/new.txt", "hi\n");
+
+	opts.checkout_strategy =
+		GIT_CHECKOUT_FORCE | GIT_CHECKOUT_DONT_REMOVE_EXISTING;
+	opts.file_open_flags = O_CREAT | O_RDWR | O_APPEND;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	check_file_contents("./testrepo/new.txt", "hi\nmy new file\n");
+}
+
+struct notify_data {
+	const char *file;
+	const char *sha;
+};
+
+static int test_checkout_notify_cb(
+	git_checkout_notify_t why,
+	const char *path,
+	const git_diff_file *baseline,
+	const git_diff_file *target,
+	const git_diff_file *workdir,
+	void *payload)
+{
+	struct notify_data *expectations = (struct notify_data *)payload;
+
+	GIT_UNUSED(workdir);
+
+	cl_assert_equal_i(GIT_CHECKOUT_NOTIFY_CONFLICT, why);
+	cl_assert_equal_s(expectations->file, path);
+	cl_assert_equal_i(0, git_oid_streq(&baseline->id, expectations->sha));
+	cl_assert_equal_i(0, git_oid_streq(&target->id, expectations->sha));
+
+	return 0;
+}
+
+void test_checkout_index__can_notify_of_skipped_files(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	struct notify_data data;
+
+	cl_git_mkfile("./testrepo/new.txt", "This isn't what's stored!");
+
+	/*
+	 * $ git ls-tree HEAD
+	 * 100644 blob a8233120f6ad708f843d861ce2b7228ec4e3dec6    README
+	 * 100644 blob 3697d64be941a53d4ae8f6a271e4e3fa56b022cc    branch_file.txt
+	 * 100644 blob a71586c1dfe8a71c6cbf6c129f404c5642ff31bd    new.txt
+	 */
+	data.file = "new.txt";
+	data.sha = "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd";
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE |
+		GIT_CHECKOUT_RECREATE_MISSING |
+		GIT_CHECKOUT_ALLOW_CONFLICTS;
+	opts.notify_flags = GIT_CHECKOUT_NOTIFY_CONFLICT;
+	opts.notify_cb = test_checkout_notify_cb;
+	opts.notify_payload = &data;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+}
+
+static int dont_notify_cb(
+	git_checkout_notify_t why,
+	const char *path,
+	const git_diff_file *baseline,
+	const git_diff_file *target,
+	const git_diff_file *workdir,
+	void *payload)
+{
+	GIT_UNUSED(why);
+	GIT_UNUSED(path);
+	GIT_UNUSED(baseline);
+	GIT_UNUSED(target);
+	GIT_UNUSED(workdir);
+	GIT_UNUSED(payload);
+
+	cl_assert(false);
+
+	return 0;
+}
+
+void test_checkout_index__wont_notify_of_expected_line_ending_changes(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	cl_git_pass(p_unlink("./testrepo/.gitattributes"));
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	cl_git_mkfile("./testrepo/new.txt", "my new file\r\n");
+
+	opts.checkout_strategy =
+		GIT_CHECKOUT_SAFE |
+		GIT_CHECKOUT_RECREATE_MISSING |
+		GIT_CHECKOUT_ALLOW_CONFLICTS;
+	opts.notify_flags = GIT_CHECKOUT_NOTIFY_CONFLICT;
+	opts.notify_cb = dont_notify_cb;
+	opts.notify_payload = NULL;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+}
+
+static void checkout_progress_counter(
+	const char *path, size_t cur, size_t tot, void *payload)
+{
+	GIT_UNUSED(path); GIT_UNUSED(cur); GIT_UNUSED(tot);
+	(*(int *)payload)++;
+}
+
+void test_checkout_index__calls_progress_callback(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	int calls = 0;
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
+	opts.progress_cb = checkout_progress_counter;
+	opts.progress_payload = &calls;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+	cl_assert(calls > 0);
+}
+
+void test_checkout_index__can_overcome_name_clashes(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_index *index;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	git_index_clear(index);
+
+	cl_git_mkfile("./testrepo/path0", "content\r\n");
+	cl_git_pass(p_mkdir("./testrepo/path1", 0777));
+	cl_git_mkfile("./testrepo/path1/file1", "content\r\n");
+
+	cl_git_pass(git_index_add_bypath(index, "path0"));
+	cl_git_pass(git_index_add_bypath(index, "path1/file1"));
+
+	cl_git_pass(p_unlink("./testrepo/path0"));
+	cl_git_pass(git_futils_rmdir_r(
+		"./testrepo/path1", NULL, GIT_RMDIR_REMOVE_FILES));
+
+	cl_git_mkfile("./testrepo/path1", "content\r\n");
+	cl_git_pass(p_mkdir("./testrepo/path0", 0777));
+	cl_git_mkfile("./testrepo/path0/file0", "content\r\n");
+
+	cl_assert(git_path_isfile("./testrepo/path1"));
+	cl_assert(git_path_isfile("./testrepo/path0/file0"));
+
+	opts.checkout_strategy =
+		GIT_CHECKOUT_SAFE | 
+		GIT_CHECKOUT_RECREATE_MISSING |
+		GIT_CHECKOUT_ALLOW_CONFLICTS;
+	cl_git_pass(git_checkout_index(g_repo, index, &opts));
+
+	cl_assert(git_path_isfile("./testrepo/path1"));
+	cl_assert(git_path_isfile("./testrepo/path0/file0"));
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+	cl_git_pass(git_checkout_index(g_repo, index, &opts));
+
+	cl_assert(git_path_isfile("./testrepo/path0"));
+	cl_assert(git_path_isfile("./testrepo/path1/file1"));
+
+	git_index_free(index);
+}
+
+void test_checkout_index__validates_struct_version(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	const git_error *err;
+
+	opts.version = 1024;
+	cl_git_fail(git_checkout_index(g_repo, NULL, &opts));
+
+	err = giterr_last();
+	cl_assert_equal_i(err->klass, GITERR_INVALID);
+
+	opts.version = 0;
+	giterr_clear();
+	cl_git_fail(git_checkout_index(g_repo, NULL, &opts));
+
+	err = giterr_last();
+	cl_assert_equal_i(err->klass, GITERR_INVALID);
+}
+
+void test_checkout_index__can_update_prefixed_files(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
+	cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt"));
+	cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));
+
+	cl_git_mkfile("./testrepo/READ", "content\n");
+	cl_git_mkfile("./testrepo/README.after", "content\n");
+	cl_git_pass(p_mkdir("./testrepo/branch_file", 0777));
+	cl_git_pass(p_mkdir("./testrepo/branch_file/contained_dir", 0777));
+	cl_git_mkfile("./testrepo/branch_file/contained_file", "content\n");
+	cl_git_pass(p_mkdir("./testrepo/branch_file.txt.after", 0777));
+
+	opts.checkout_strategy =
+		GIT_CHECKOUT_SAFE |
+		GIT_CHECKOUT_RECREATE_MISSING |
+		GIT_CHECKOUT_REMOVE_UNTRACKED;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	/* remove untracked will remove the .gitattributes file before the blobs
+	 * were created, so they will have had crlf filtering applied on Windows
+	 */
+	check_file_contents_nocr("./testrepo/README", "hey there\n");
+	check_file_contents_nocr("./testrepo/branch_file.txt", "hi\nbye!\n");
+	check_file_contents_nocr("./testrepo/new.txt", "my new file\n");
+
+	cl_assert(!git_path_exists("testrepo/READ"));
+	cl_assert(!git_path_exists("testrepo/README.after"));
+	cl_assert(!git_path_exists("testrepo/branch_file"));
+	cl_assert(!git_path_exists("testrepo/branch_file.txt.after"));
+}
+
+void test_checkout_index__can_checkout_a_newly_initialized_repository(void)
+{
+	test_checkout_index__cleanup();
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+	cl_git_remove_placeholders(git_repository_path(g_repo), "dummy-marker.txt");
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, NULL));
+}
+
+void test_checkout_index__issue_1397(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	test_checkout_index__cleanup();
+
+	g_repo = cl_git_sandbox_init("issue_1397");
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	check_file_contents("./issue_1397/crlf_file.txt", "first line\r\nsecond line\r\nboth with crlf");
+}
+
+void test_checkout_index__target_directory(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	checkout_counts cts;
+	memset(&cts, 0, sizeof(cts));
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE |
+		GIT_CHECKOUT_RECREATE_MISSING;
+	opts.target_directory = "alternative";
+	cl_assert(!git_path_isdir("alternative"));
+
+	opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL;
+	opts.notify_cb = checkout_count_callback;
+	opts.notify_payload = &cts;
+
+	/* create some files that *would* conflict if we were using the wd */
+	cl_git_mkfile("testrepo/README", "I'm in the way!\n");
+	cl_git_mkfile("testrepo/new.txt", "my new file\n");
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	cl_assert_equal_i(0, cts.n_untracked);
+	cl_assert_equal_i(0, cts.n_ignored);
+	cl_assert_equal_i(4, cts.n_updates);
+
+	check_file_contents("./alternative/README", "hey there\n");
+	check_file_contents("./alternative/branch_file.txt", "hi\nbye!\n");
+	check_file_contents("./alternative/new.txt", "my new file\n");
+
+	cl_git_pass(git_futils_rmdir_r(
+		"alternative", NULL, GIT_RMDIR_REMOVE_FILES));
+}
+
+void test_checkout_index__target_directory_from_bare(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_index *index;
+	git_object *head = NULL;
+	checkout_counts cts;
+	memset(&cts, 0, sizeof(cts));
+
+	test_checkout_index__cleanup();
+
+	g_repo = cl_git_sandbox_init("testrepo.git");
+	cl_assert(git_repository_is_bare(g_repo));
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_revparse_single(&head, g_repo, "HEAD^{tree}"));
+	cl_git_pass(git_index_read_tree(index, (const git_tree *)head));
+	cl_git_pass(git_index_write(index));
+	git_index_free(index);
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE |
+		GIT_CHECKOUT_RECREATE_MISSING;
+
+	opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL;
+	opts.notify_cb = checkout_count_callback;
+	opts.notify_payload = &cts;
+
+	/* fail to checkout a bare repo */
+	cl_git_fail(git_checkout_index(g_repo, NULL, &opts));
+
+	opts.target_directory = "alternative";
+	cl_assert(!git_path_isdir("alternative"));
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	cl_assert_equal_i(0, cts.n_untracked);
+	cl_assert_equal_i(0, cts.n_ignored);
+	cl_assert_equal_i(3, cts.n_updates);
+
+	/* files will have been filtered if needed, so strip CR */
+	check_file_contents_nocr("./alternative/README", "hey there\n");
+	check_file_contents_nocr("./alternative/branch_file.txt", "hi\nbye!\n");
+	check_file_contents_nocr("./alternative/new.txt", "my new file\n");
+
+	cl_git_pass(git_futils_rmdir_r(
+		"alternative", NULL, GIT_RMDIR_REMOVE_FILES));
+
+	git_object_free(head);
+}
+
+void test_checkout_index__can_get_repo_from_index(void)
+{
+	git_index *index;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
+	cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt"));
+	cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_pass(git_checkout_index(NULL, index, &opts));
+
+	check_file_contents("./testrepo/README", "hey there\n");
+	check_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n");
+	check_file_contents("./testrepo/new.txt", "my new file\n");
+
+	git_index_free(index);
+}
+
+static void add_conflict(git_index *index, const char *path)
+{
+	git_index_entry entry;
+
+	memset(&entry, 0, sizeof(git_index_entry));
+
+	entry.mode = 0100644;
+	entry.path = path;
+
+	git_oid_fromstr(&entry.id, "d427e0b2e138501a3d15cc376077a3631e15bd46");
+	GIT_IDXENTRY_STAGE_SET(&entry, 1);
+	cl_git_pass(git_index_add(index, &entry));
+
+	git_oid_fromstr(&entry.id, "4e886e602529caa9ab11d71f86634bd1b6e0de10");
+	GIT_IDXENTRY_STAGE_SET(&entry, 2);
+	cl_git_pass(git_index_add(index, &entry));
+
+	git_oid_fromstr(&entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863");
+	GIT_IDXENTRY_STAGE_SET(&entry, 3);
+	cl_git_pass(git_index_add(index, &entry));
+}
+
+void test_checkout_index__writes_conflict_file(void)
+{
+	git_index *index;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_buf conflicting_buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	add_conflict(index, "conflicting.txt");
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	cl_git_pass(git_futils_readbuffer(&conflicting_buf, "testrepo/conflicting.txt"));
+	cl_assert(strcmp(conflicting_buf.ptr,
+		"<<<<<<< ours\n"
+		"this file is changed in master and branch\n"
+		"=======\n"
+		"this file is changed in branch and master\n"
+		">>>>>>> theirs\n") == 0);
+	git_buf_free(&conflicting_buf);
+
+	git_index_free(index);
+}
+
+void test_checkout_index__adding_conflict_removes_stage_0(void)
+{
+	git_index *new_index, *index;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	cl_git_pass(git_index_new(&new_index));
+
+	add_conflict(new_index, "new.txt");
+	cl_git_pass(git_checkout_index(g_repo, new_index, &opts));
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_assert(git_index_get_bypath(index, "new.txt", 0) == NULL);
+	cl_assert(git_index_get_bypath(index, "new.txt", 1) != NULL);
+	cl_assert(git_index_get_bypath(index, "new.txt", 2) != NULL);
+	cl_assert(git_index_get_bypath(index, "new.txt", 3) != NULL);
+
+	git_index_free(index);
+	git_index_free(new_index);
+}
+
+void test_checkout_index__conflicts_honor_coreautocrlf(void)
+{
+#ifdef GIT_WIN32
+	git_index *index;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_buf conflicting_buf = GIT_BUF_INIT;
+
+	cl_git_pass(p_unlink("./testrepo/.gitattributes"));
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	add_conflict(index, "conflicting.txt");
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
+
+	cl_git_pass(git_futils_readbuffer(&conflicting_buf, "testrepo/conflicting.txt"));
+	cl_assert(strcmp(conflicting_buf.ptr,
+		"<<<<<<< ours\r\n"
+		"this file is changed in master and branch\r\n"
+		"=======\r\n"
+		"this file is changed in branch and master\r\n"
+		">>>>>>> theirs\r\n") == 0);
+	git_buf_free(&conflicting_buf);
+
+	git_index_free(index);
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/nasty.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/nasty.c
new file mode 100755
index 0000000..952a6a1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/nasty.c
@@ -0,0 +1,366 @@
+#include "clar_libgit2.h"
+#include "checkout_helpers.h"
+
+#include "git2/checkout.h"
+#include "repository.h"
+#include "buffer.h"
+#include "fileops.h"
+
+static const char *repo_name = "nasty";
+static git_repository *repo;
+static git_checkout_options checkout_opts;
+
+void test_checkout_nasty__initialize(void)
+{
+	repo = cl_git_sandbox_init(repo_name);
+
+	GIT_INIT_STRUCTURE(&checkout_opts, GIT_CHECKOUT_OPTIONS_VERSION);
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+}
+
+void test_checkout_nasty__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static void test_checkout_passes(const char *refname, const char *filename)
+{
+	git_oid commit_id;
+	git_commit *commit;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_buf path = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_joinpath(&path, repo_name, filename));
+
+	cl_git_pass(git_reference_name_to_id(&commit_id, repo, refname));
+	cl_git_pass(git_commit_lookup(&commit, repo, &commit_id));
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE |
+		GIT_CHECKOUT_DONT_UPDATE_INDEX;
+
+	cl_git_pass(git_checkout_tree(repo, (const git_object *)commit, &opts));
+	cl_assert(!git_path_exists(path.ptr));
+
+	git_commit_free(commit);
+	git_buf_free(&path);
+}
+
+static void test_checkout_fails(const char *refname, const char *filename)
+{
+	git_oid commit_id;
+	git_commit *commit;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_buf path = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_joinpath(&path, repo_name, filename));
+
+	cl_git_pass(git_reference_name_to_id(&commit_id, repo, refname));
+	cl_git_pass(git_commit_lookup(&commit, repo, &commit_id));
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_fail(git_checkout_tree(repo, (const git_object *)commit, &opts));
+	cl_assert(!git_path_exists(path.ptr));
+
+	git_commit_free(commit);
+	git_buf_free(&path);
+}
+
+/* A tree that contains ".git" as a tree, with a blob inside
+ * (".git/foobar").
+ */
+void test_checkout_nasty__dotgit_tree(void)
+{
+	test_checkout_fails("refs/heads/dotgit_tree", ".git/foobar");
+}
+
+/* A tree that contains ".GIT" as a tree, with a blob inside
+ * (".GIT/foobar").
+ */
+void test_checkout_nasty__dotcapitalgit_tree(void)
+{
+	test_checkout_fails("refs/heads/dotcapitalgit_tree", ".GIT/foobar");
+}
+
+/* A tree that contains a tree ".", with a blob inside ("./foobar").
+ */
+void test_checkout_nasty__dot_tree(void)
+{
+	test_checkout_fails("refs/heads/dot_tree", "foobar");
+}
+
+/* A tree that contains a tree ".", with a tree ".git", with a blob
+ * inside ("./.git/foobar").
+ */
+void test_checkout_nasty__dot_dotgit_tree(void)
+{
+	test_checkout_fails("refs/heads/dot_dotgit_tree", ".git/foobar");
+}
+
+/* A tree that contains a tree, with a tree "..", with a tree ".git", with a
+ * blob inside ("foo/../.git/foobar").
+ */
+void test_checkout_nasty__dotdot_dotgit_tree(void)
+{
+	test_checkout_fails("refs/heads/dotdot_dotgit_tree", ".git/foobar");
+}
+
+/* A tree that contains a tree, with a tree "..", with a blob inside
+ * ("foo/../foobar").
+ */
+void test_checkout_nasty__dotdot_tree(void)
+{
+	test_checkout_fails("refs/heads/dotdot_tree", "foobar");
+}
+
+/* A tree that contains a blob with the rogue name ".git/foobar" */
+void test_checkout_nasty__dotgit_path(void)
+{
+	test_checkout_fails("refs/heads/dotgit_path", ".git/foobar");
+}
+
+/* A tree that contains a blob with the rogue name ".GIT/foobar" */
+void test_checkout_nasty__dotcapitalgit_path(void)
+{
+	test_checkout_fails("refs/heads/dotcapitalgit_path", ".GIT/foobar");
+}
+
+/* A tree that contains a blob with the rogue name "./.git/foobar" */
+void test_checkout_nasty__dot_dotgit_path(void)
+{
+	test_checkout_fails("refs/heads/dot_dotgit_path", ".git/foobar");
+}
+
+/* A tree that contains a blob with the rogue name "./.GIT/foobar" */
+void test_checkout_nasty__dot_dotcapitalgit_path(void)
+{
+	test_checkout_fails("refs/heads/dot_dotcapitalgit_path", ".GIT/foobar");
+}
+
+/* A tree that contains a blob with the rogue name "foo/../.git/foobar" */
+void test_checkout_nasty__dotdot_dotgit_path(void)
+{
+	test_checkout_fails("refs/heads/dotdot_dotgit_path", ".git/foobar");
+}
+
+/* A tree that contains a blob with the rogue name "foo/../.GIT/foobar" */
+void test_checkout_nasty__dotdot_dotcapitalgit_path(void)
+{
+	test_checkout_fails("refs/heads/dotdot_dotcapitalgit_path", ".GIT/foobar");
+}
+
+/* A tree that contains a blob with the rogue name "foo/." */
+void test_checkout_nasty__dot_path(void)
+{
+	test_checkout_fails("refs/heads/dot_path", "./foobar");
+}
+
+/* A tree that contains a blob with the rogue name "foo/." */
+void test_checkout_nasty__dot_path_two(void)
+{
+	test_checkout_fails("refs/heads/dot_path_two", "foo/.");
+}
+
+/* A tree that contains a blob with the rogue name "foo/../foobar" */
+void test_checkout_nasty__dotdot_path(void)
+{
+	test_checkout_fails("refs/heads/dotdot_path", "foobar");
+}
+
+/* A tree that contains an entry with a backslash ".git\foobar"  */
+void test_checkout_nasty__dotgit_backslash_path(void)
+{
+#ifdef GIT_WIN32
+	test_checkout_fails("refs/heads/dotgit_backslash_path", ".git/foobar");
+#endif
+}
+
+/* A tree that contains an entry with a backslash ".GIT\foobar"  */
+void test_checkout_nasty__dotcapitalgit_backslash_path(void)
+{
+#ifdef GIT_WIN32
+	test_checkout_fails("refs/heads/dotcapitalgit_backslash_path", ".GIT/foobar");
+#endif
+}
+
+/* A tree that contains an entry with a backslash ".\.GIT\foobar"  */
+void test_checkout_nasty__dot_backslash_dotcapitalgit_path(void)
+{
+#ifdef GIT_WIN32
+	test_checkout_fails("refs/heads/dot_backslash_dotcapitalgit_path", ".GIT/foobar");
+#endif
+}
+
+/* A tree that contains an entry ".git.", because Win32 APIs will drop the
+ * trailing slash.
+ */
+void test_checkout_nasty__dot_git_dot(void)
+{
+#ifdef GIT_WIN32
+	test_checkout_fails("refs/heads/dot_git_dot", ".git/foobar");
+#endif
+}
+
+/* A tree that contains an entry "git~1", because that is typically the
+ * short name for ".git".
+ */
+void test_checkout_nasty__git_tilde1(void)
+{
+#ifdef GIT_WIN32
+	test_checkout_fails("refs/heads/git_tilde1", ".git/foobar");
+#endif
+}
+
+/* A tree that contains an entry "git~2", when we have forced the short
+ * name for ".git" into "GIT~2".
+ */
+void test_checkout_nasty__git_custom_shortname(void)
+{
+#ifdef GIT_WIN32
+	if (!cl_sandbox_supports_8dot3())
+		clar__skip();
+
+	cl_must_pass(p_rename("nasty/.git", "nasty/_temp"));
+	cl_git_write2file("nasty/git~1", "", 0, O_RDWR|O_CREAT, 0666);
+	cl_must_pass(p_rename("nasty/_temp", "nasty/.git"));
+	test_checkout_fails("refs/heads/git_tilde2", ".git/foobar");
+#endif
+}
+
+/* A tree that contains an entry "git~3", which should be allowed, since
+ * it is not the typical short name ("GIT~1") or the actual short name
+ * ("GIT~2") for ".git".
+ */
+void test_checkout_nasty__only_looks_like_a_git_shortname(void)
+{
+#ifdef GIT_WIN32
+	git_oid commit_id;
+	git_commit *commit;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	cl_must_pass(p_rename("nasty/.git", "nasty/_temp"));
+	cl_git_write2file("nasty/git~1", "", 0, O_RDWR|O_CREAT, 0666);
+	cl_must_pass(p_rename("nasty/_temp", "nasty/.git"));
+
+	cl_git_pass(git_reference_name_to_id(&commit_id, repo, "refs/heads/git_tilde3"));
+	cl_git_pass(git_commit_lookup(&commit, repo, &commit_id));
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_pass(git_checkout_tree(repo, (const git_object *)commit, &opts));
+	cl_assert(git_path_exists("nasty/git~3/foobar"));
+
+	git_commit_free(commit);
+#endif
+}
+
+/* A tree that contains an entry "git:", because Win32 APIs will reject
+ * that as looking too similar to a drive letter.
+ */
+void test_checkout_nasty__dot_git_colon(void)
+{
+#ifdef GIT_WIN32
+	test_checkout_fails("refs/heads/dot_git_colon", ".git/foobar");
+#endif
+}
+
+/* A tree that contains an entry "git:foo", because Win32 APIs will turn
+ * that into ".git".
+ */
+void test_checkout_nasty__dot_git_colon_stuff(void)
+{
+#ifdef GIT_WIN32
+	test_checkout_fails("refs/heads/dot_git_colon_stuff", ".git/foobar");
+#endif
+}
+
+/* Trees that contains entries with a tree ".git" that contain
+ * byte sequences:
+ * { 0xe2, 0x80, 0x8c }
+ * { 0xe2, 0x80, 0x8d }
+ * { 0xe2, 0x80, 0x8e }
+ * { 0xe2, 0x80, 0x8f }
+ * { 0xe2, 0x80, 0xaa }
+ * { 0xe2, 0x80, 0xab }
+ * { 0xe2, 0x80, 0xac }
+ * { 0xe2, 0x80, 0xad }
+ * { 0xe2, 0x81, 0xae }
+ * { 0xe2, 0x81, 0xaa }
+ * { 0xe2, 0x81, 0xab }
+ * { 0xe2, 0x81, 0xac }
+ * { 0xe2, 0x81, 0xad }
+ * { 0xe2, 0x81, 0xae }
+ * { 0xe2, 0x81, 0xaf }
+ * { 0xef, 0xbb, 0xbf }
+ * Because these map to characters that HFS filesystems "ignore".  Thus
+ * ".git<U+200C>" will map to ".git".
+ */
+void test_checkout_nasty__dot_git_hfs_ignorable(void)
+{
+#ifdef __APPLE__
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_1", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_2", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_3", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_4", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_5", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_6", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_7", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_8", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_9", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_10", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_11", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_12", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_13", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_14", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_15", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_16", ".git/foobar");
+#endif
+}
+
+void test_checkout_nasty__honors_core_protecthfs(void)
+{
+	cl_repo_set_bool(repo, "core.protectHFS", true);
+
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_1", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_2", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_3", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_4", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_5", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_6", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_7", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_8", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_9", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_10", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_11", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_12", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_13", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_14", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_15", ".git/foobar");
+	test_checkout_fails("refs/heads/dotgit_hfs_ignorable_16", ".git/foobar");
+}
+
+void test_checkout_nasty__honors_core_protectntfs(void)
+{
+	cl_repo_set_bool(repo, "core.protectNTFS", true);
+
+	test_checkout_fails("refs/heads/dotgit_backslash_path", ".git/foobar");
+	test_checkout_fails("refs/heads/dotcapitalgit_backslash_path", ".GIT/foobar");
+	test_checkout_fails("refs/heads/dot_git_dot", ".git/foobar");
+	test_checkout_fails("refs/heads/git_tilde1", ".git/foobar");
+}
+
+void test_checkout_nasty__symlink1(void)
+{
+	test_checkout_passes("refs/heads/symlink1", ".git/foobar");
+}
+
+void test_checkout_nasty__symlink2(void)
+{
+	test_checkout_passes("refs/heads/symlink2", ".git/foobar");
+}
+
+void test_checkout_nasty__symlink3(void)
+{
+	test_checkout_passes("refs/heads/symlink3", ".git/foobar");
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/tree.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/tree.c
new file mode 100755
index 0000000..be40198
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/tree.c
@@ -0,0 +1,1340 @@
+#include "clar_libgit2.h"
+#include "checkout_helpers.h"
+
+#include "git2/checkout.h"
+#include "repository.h"
+#include "buffer.h"
+#include "fileops.h"
+
+static git_repository *g_repo;
+static git_checkout_options g_opts;
+static git_object *g_object;
+
+void test_checkout_tree__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo");
+
+	GIT_INIT_STRUCTURE(&g_opts, GIT_CHECKOUT_OPTIONS_VERSION);
+	g_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+}
+
+void test_checkout_tree__cleanup(void)
+{
+	git_object_free(g_object);
+	g_object = NULL;
+
+	cl_git_sandbox_cleanup();
+
+	if (git_path_isdir("alternative"))
+		git_futils_rmdir_r("alternative", NULL, GIT_RMDIR_REMOVE_FILES);
+}
+
+void test_checkout_tree__cannot_checkout_a_non_treeish(void)
+{
+	/* blob */
+	cl_git_pass(git_revparse_single(&g_object, g_repo, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd"));
+	cl_git_fail(git_checkout_tree(g_repo, g_object, NULL));
+}
+
+void test_checkout_tree__can_checkout_a_subdirectory_from_a_commit(void)
+{
+	char *entries[] = { "ab/de/" };
+
+	g_opts.paths.strings = entries;
+	g_opts.paths.count = 1;
+
+	cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees"));
+
+	cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/"));
+
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
+
+	cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt"));
+	cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/fgh/1.txt"));
+}
+
+void test_checkout_tree__can_checkout_and_remove_directory(void)
+{
+	cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/"));
+
+	/* Checkout brach "subtrees" and update HEAD, so that HEAD matches the
+	 * current working tree
+	 */
+	cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees"));
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
+
+	cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees"));
+
+	cl_assert_equal_i(true, git_path_isdir("./testrepo/ab/"));
+	cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt"));
+	cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/fgh/1.txt"));
+
+	git_object_free(g_object);
+	g_object = NULL;
+
+	/* Checkout brach "master" and update HEAD, so that HEAD matches the
+	 * current working tree
+	 */
+	cl_git_pass(git_revparse_single(&g_object, g_repo, "master"));
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
+
+	cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master"));
+
+	/* This directory should no longer exist */
+	cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/"));
+}
+
+void test_checkout_tree__can_checkout_a_subdirectory_from_a_subtree(void)
+{
+	char *entries[] = { "de/" };
+
+	g_opts.paths.strings = entries;
+	g_opts.paths.count = 1;
+
+	cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees:ab"));
+
+	cl_assert_equal_i(false, git_path_isdir("./testrepo/de/"));
+
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
+
+	cl_assert_equal_i(true, git_path_isfile("./testrepo/de/2.txt"));
+	cl_assert_equal_i(true, git_path_isfile("./testrepo/de/fgh/1.txt"));
+}
+
+static void progress(const char *path, size_t cur, size_t tot, void *payload)
+{
+	bool *was_called = (bool*)payload;
+	GIT_UNUSED(path); GIT_UNUSED(cur); GIT_UNUSED(tot);
+	*was_called = true;
+}
+
+void test_checkout_tree__calls_progress_callback(void)
+{
+	bool was_called = 0;
+
+	g_opts.progress_cb = progress;
+	g_opts.progress_payload = &was_called;
+
+	cl_git_pass(git_revparse_single(&g_object, g_repo, "master"));
+
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
+
+	cl_assert_equal_i(was_called, true);
+}
+
+void test_checkout_tree__doesnt_write_unrequested_files_to_worktree(void)
+{
+	git_oid master_oid;
+	git_oid chomped_oid;
+	git_commit* p_master_commit;
+	git_commit* p_chomped_commit;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	git_oid_fromstr(&master_oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	git_oid_fromstr(&chomped_oid, "e90810b8df3e80c413d903f631643c716887138d");
+	cl_git_pass(git_commit_lookup(&p_master_commit, g_repo, &master_oid));
+	cl_git_pass(git_commit_lookup(&p_chomped_commit, g_repo, &chomped_oid));
+
+	/* GIT_CHECKOUT_NONE should not add any file to the working tree from the
+	 * index as it is supposed to be a dry run.
+	 */
+	opts.checkout_strategy = GIT_CHECKOUT_NONE;
+	git_checkout_tree(g_repo, (git_object*)p_chomped_commit, &opts);
+	cl_assert_equal_i(false, git_path_isfile("testrepo/readme.txt"));
+
+	git_commit_free(p_master_commit);
+	git_commit_free(p_chomped_commit);
+}
+
+void test_checkout_tree__can_switch_branches(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_oid oid;
+	git_object *obj = NULL;
+
+	assert_on_branch(g_repo, "master");
+
+	/* do first checkout with FORCE because we don't know if testrepo
+	 * base data is clean for a checkout or not
+	 */
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+	cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir"));
+
+	cl_assert(git_path_isfile("testrepo/README"));
+	cl_assert(git_path_isfile("testrepo/branch_file.txt"));
+	cl_assert(git_path_isfile("testrepo/new.txt"));
+	cl_assert(git_path_isfile("testrepo/a/b.txt"));
+
+	cl_assert(!git_path_isdir("testrepo/ab"));
+
+	assert_on_branch(g_repo, "dir");
+
+	git_object_free(obj);
+
+	/* do second checkout safe because we should be clean after first */
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/subtrees"));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+	cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees"));
+
+	cl_assert(git_path_isfile("testrepo/README"));
+	cl_assert(git_path_isfile("testrepo/branch_file.txt"));
+	cl_assert(git_path_isfile("testrepo/new.txt"));
+	cl_assert(git_path_isfile("testrepo/ab/4.txt"));
+	cl_assert(git_path_isfile("testrepo/ab/c/3.txt"));
+	cl_assert(git_path_isfile("testrepo/ab/de/2.txt"));
+	cl_assert(git_path_isfile("testrepo/ab/de/fgh/1.txt"));
+
+	cl_assert(!git_path_isdir("testrepo/a"));
+
+	assert_on_branch(g_repo, "subtrees");
+
+	git_object_free(obj);
+}
+
+void test_checkout_tree__can_remove_untracked(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_REMOVE_UNTRACKED;
+
+	cl_git_mkfile("testrepo/untracked_file", "as you wish");
+	cl_assert(git_path_isfile("testrepo/untracked_file"));
+
+	cl_git_pass(git_checkout_head(g_repo, &opts));
+
+	cl_assert(!git_path_isfile("testrepo/untracked_file"));
+}
+
+void test_checkout_tree__can_remove_ignored(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	int ignored = 0;
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_REMOVE_IGNORED;
+
+	cl_git_mkfile("testrepo/ignored_file", "as you wish");
+
+	cl_git_pass(git_ignore_add_rule(g_repo, "ignored_file\n"));
+
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "ignored_file"));
+	cl_assert_equal_i(1, ignored);
+
+	cl_assert(git_path_isfile("testrepo/ignored_file"));
+
+	cl_git_pass(git_checkout_head(g_repo, &opts));
+
+	cl_assert(!git_path_isfile("testrepo/ignored_file"));
+}
+
+static int checkout_tree_with_blob_ignored_in_workdir(int strategy, bool isdir)
+{
+	git_oid oid;
+	git_object *obj = NULL;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	int ignored = 0, error;
+
+	assert_on_branch(g_repo, "master");
+
+	/* do first checkout with FORCE because we don't know if testrepo
+	 * base data is clean for a checkout or not
+	 */
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+	cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir"));
+
+	cl_assert(git_path_isfile("testrepo/README"));
+	cl_assert(git_path_isfile("testrepo/branch_file.txt"));
+	cl_assert(git_path_isfile("testrepo/new.txt"));
+	cl_assert(git_path_isfile("testrepo/a/b.txt"));
+
+	cl_assert(!git_path_isdir("testrepo/ab"));
+
+	assert_on_branch(g_repo, "dir");
+
+	git_object_free(obj);
+
+	opts.checkout_strategy = strategy;
+
+	if (isdir) {
+		cl_must_pass(p_mkdir("testrepo/ab", 0777));
+		cl_must_pass(p_mkdir("testrepo/ab/4.txt", 0777));
+
+		cl_git_mkfile("testrepo/ab/4.txt/file1.txt", "as you wish");
+		cl_git_mkfile("testrepo/ab/4.txt/file2.txt", "foo bar foo");
+		cl_git_mkfile("testrepo/ab/4.txt/file3.txt", "inky blinky pinky clyde");
+
+		cl_assert(git_path_isdir("testrepo/ab/4.txt"));
+	} else {
+		cl_must_pass(p_mkdir("testrepo/ab", 0777));
+		cl_git_mkfile("testrepo/ab/4.txt", "as you wish");
+
+		cl_assert(git_path_isfile("testrepo/ab/4.txt"));
+	}
+
+	cl_git_pass(git_ignore_add_rule(g_repo, "ab/4.txt\n"));
+
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "ab/4.txt"));
+	cl_assert_equal_i(1, ignored);
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/subtrees"));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+	error = git_checkout_tree(g_repo, obj, &opts);
+
+	git_object_free(obj);
+
+	return error;
+}
+
+void test_checkout_tree__conflict_on_ignored_when_not_overwriting(void)
+{
+	int error;
+
+	cl_git_fail(error = checkout_tree_with_blob_ignored_in_workdir(
+		GIT_CHECKOUT_SAFE | GIT_CHECKOUT_DONT_OVERWRITE_IGNORED, false));
+
+	cl_assert_equal_i(GIT_ECONFLICT, error);
+}
+
+void test_checkout_tree__can_overwrite_ignored_by_default(void)
+{
+	cl_git_pass(checkout_tree_with_blob_ignored_in_workdir(GIT_CHECKOUT_SAFE, false));
+
+	cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees"));
+
+	cl_assert(git_path_isfile("testrepo/ab/4.txt"));
+
+	assert_on_branch(g_repo, "subtrees");
+}
+
+void test_checkout_tree__conflict_on_ignored_folder_when_not_overwriting(void)
+{
+	int error;
+
+	cl_git_fail(error = checkout_tree_with_blob_ignored_in_workdir(
+		GIT_CHECKOUT_SAFE | GIT_CHECKOUT_DONT_OVERWRITE_IGNORED, true));
+
+	cl_assert_equal_i(GIT_ECONFLICT, error);
+}
+
+void test_checkout_tree__can_overwrite_ignored_folder_by_default(void)
+{
+	cl_git_pass(checkout_tree_with_blob_ignored_in_workdir(GIT_CHECKOUT_SAFE, true));
+
+	cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees"));
+
+	cl_assert(git_path_isfile("testrepo/ab/4.txt"));
+
+	assert_on_branch(g_repo, "subtrees");
+
+}
+
+void test_checkout_tree__can_update_only(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_oid oid;
+	git_object *obj = NULL;
+
+	/* first let's get things into a known state - by checkout out the HEAD */
+
+	assert_on_branch(g_repo, "master");
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+	cl_git_pass(git_checkout_head(g_repo, &opts));
+
+	cl_assert(!git_path_isdir("testrepo/a"));
+
+	check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n");
+
+	/* now checkout branch but with update only */
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+	cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir"));
+
+	assert_on_branch(g_repo, "dir");
+
+	/* this normally would have been created (which was tested separately in
+	 * the test_checkout_tree__can_switch_branches test), but with
+	 * UPDATE_ONLY it will not have been created.
+	 */
+	cl_assert(!git_path_isdir("testrepo/a"));
+
+	/* but this file still should have been updated */
+	check_file_contents_nocr("testrepo/branch_file.txt", "hi\n");
+
+	git_object_free(obj);
+}
+
+void test_checkout_tree__can_checkout_with_pattern(void)
+{
+	char *entries[] = { "[l-z]*.txt" };
+
+	/* reset to beginning of history (i.e. just a README file) */
+
+	g_opts.checkout_strategy =
+		GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED;
+
+	cl_git_pass(git_revparse_single(&g_object, g_repo, "8496071c1b46c854b31185ea97743be6a8774479"));
+
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
+	cl_git_pass(
+		git_repository_set_head_detached(g_repo, git_object_id(g_object)));
+
+	git_object_free(g_object);
+	g_object = NULL;
+
+	cl_assert(git_path_exists("testrepo/README"));
+	cl_assert(!git_path_exists("testrepo/branch_file.txt"));
+	cl_assert(!git_path_exists("testrepo/link_to_new.txt"));
+	cl_assert(!git_path_exists("testrepo/new.txt"));
+
+	/* now to a narrow patterned checkout */
+
+	g_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+	g_opts.paths.strings = entries;
+	g_opts.paths.count = 1;
+
+	cl_git_pass(git_revparse_single(&g_object, g_repo, "refs/heads/master"));
+
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
+
+	cl_assert(git_path_exists("testrepo/README"));
+	cl_assert(!git_path_exists("testrepo/branch_file.txt"));
+	cl_assert(git_path_exists("testrepo/link_to_new.txt"));
+	cl_assert(git_path_exists("testrepo/new.txt"));
+}
+
+void test_checkout_tree__can_disable_pattern_match(void)
+{
+	char *entries[] = { "b*.txt" };
+
+	/* reset to beginning of history (i.e. just a README file) */
+
+	g_opts.checkout_strategy =
+		GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED;
+
+	cl_git_pass(git_revparse_single(&g_object, g_repo, "8496071c1b46c854b31185ea97743be6a8774479"));
+
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
+	cl_git_pass(
+		git_repository_set_head_detached(g_repo, git_object_id(g_object)));
+
+	git_object_free(g_object);
+	g_object = NULL;
+
+	cl_assert(!git_path_isfile("testrepo/branch_file.txt"));
+
+	/* now to a narrow patterned checkout, but disable pattern */
+
+	g_opts.checkout_strategy =
+		GIT_CHECKOUT_SAFE |
+		GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH;
+	g_opts.paths.strings = entries;
+	g_opts.paths.count = 1;
+
+	cl_git_pass(git_revparse_single(&g_object, g_repo, "refs/heads/master"));
+
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
+
+	cl_assert(!git_path_isfile("testrepo/branch_file.txt"));
+
+	/* let's try that again, but allow the pattern match */
+
+	g_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
+
+	cl_assert(git_path_isfile("testrepo/branch_file.txt"));
+}
+
+void assert_conflict(
+	const char *entry_path,
+	const char *new_content,
+	const char *parent_sha,
+	const char *commit_sha)
+{
+	git_index *index;
+	git_object *hack_tree;
+	git_reference *branch, *head;
+	git_buf file_path = GIT_BUF_INIT;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	/* Create a branch pointing at the parent */
+	cl_git_pass(git_revparse_single(&g_object, g_repo, parent_sha));
+	cl_git_pass(git_branch_create(&branch, g_repo,
+		"potential_conflict", (git_commit *)g_object, 0));
+
+	/* Make HEAD point to this branch */
+	cl_git_pass(git_reference_symbolic_create(
+		&head, g_repo, "HEAD", git_reference_name(branch), 1, NULL));
+	git_reference_free(head);
+	git_reference_free(branch);
+
+	/* Checkout the parent */
+	g_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
+
+	/* Hack-ishy workaound to ensure *all* the index entries
+	 * match the content of the tree
+	 */
+	cl_git_pass(git_object_peel(&hack_tree, g_object, GIT_OBJ_TREE));
+	cl_git_pass(git_index_read_tree(index, (git_tree *)hack_tree));
+	git_object_free(hack_tree);
+	git_object_free(g_object);
+	g_object = NULL;
+
+	/* Create a conflicting file */
+	cl_git_pass(git_buf_joinpath(&file_path, "./testrepo", entry_path));
+	cl_git_mkfile(git_buf_cstr(&file_path), new_content);
+	git_buf_free(&file_path);
+
+	/* Trying to checkout the original commit */
+	cl_git_pass(git_revparse_single(&g_object, g_repo, commit_sha));
+
+	g_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+	cl_assert_equal_i(
+		GIT_ECONFLICT, git_checkout_tree(g_repo, g_object, &g_opts));
+
+	/* Stage the conflicting change */
+	cl_git_pass(git_index_add_bypath(index, entry_path));
+	cl_git_pass(git_index_write(index));
+	git_index_free(index);
+
+	cl_assert_equal_i(
+		GIT_ECONFLICT, git_checkout_tree(g_repo, g_object, &g_opts));
+}
+
+void test_checkout_tree__checking_out_a_conflicting_type_change_returns_ECONFLICT(void)
+{
+	/*
+	 * 099faba adds a symlink named 'link_to_new.txt'
+	 * a65fedf is the parent of 099faba
+	 */
+
+	assert_conflict("link_to_new.txt", "old.txt", "a65fedf", "099faba");
+}
+
+void test_checkout_tree__checking_out_a_conflicting_type_change_returns_ECONFLICT_2(void)
+{
+	/*
+	 * cf80f8d adds a directory named 'a/'
+	 * a4a7dce is the parent of cf80f8d
+	 */
+
+	assert_conflict("a", "hello\n", "a4a7dce", "cf80f8d");
+}
+
+void test_checkout_tree__checking_out_a_conflicting_content_change_returns_ECONFLICT(void)
+{
+	/*
+	 * c47800c adds a symlink named 'branch_file.txt'
+	 * 5b5b025 is the parent of 763d71a
+	 */
+
+	assert_conflict("branch_file.txt", "hello\n", "5b5b025", "c47800c");
+}
+
+void test_checkout_tree__donot_update_deleted_file_by_default(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_oid old_id, new_id;
+	git_commit *old_commit = NULL, *new_commit = NULL;
+	git_index *index = NULL;
+	checkout_counts ct;
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+	memset(&ct, 0, sizeof(ct));
+	opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL;
+	opts.notify_cb = checkout_count_callback;
+	opts.notify_payload = &ct;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_pass(git_oid_fromstr(&old_id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"));
+	cl_git_pass(git_commit_lookup(&old_commit, g_repo, &old_id));
+	cl_git_pass(git_reset(g_repo, (git_object *)old_commit, GIT_RESET_HARD, NULL));
+
+	cl_git_pass(p_unlink("testrepo/branch_file.txt"));
+	cl_git_pass(git_index_remove_bypath(index ,"branch_file.txt"));
+	cl_git_pass(git_index_write(index));
+
+	cl_assert(!git_path_exists("testrepo/branch_file.txt"));
+
+	cl_git_pass(git_oid_fromstr(&new_id, "099fabac3a9ea935598528c27f866e34089c2eff"));
+	cl_git_pass(git_commit_lookup(&new_commit, g_repo, &new_id));
+
+
+	cl_git_fail(git_checkout_tree(g_repo, (git_object *)new_commit, &opts));
+
+	cl_assert_equal_i(1, ct.n_conflicts);
+	cl_assert_equal_i(1, ct.n_updates);
+
+	git_commit_free(old_commit);
+	git_commit_free(new_commit);
+	git_index_free(index);
+}
+
+struct checkout_cancel_at {
+	const char *filename;
+	int error;
+	int count;
+};
+
+static int checkout_cancel_cb(
+	git_checkout_notify_t why,
+	const char *path,
+	const git_diff_file *b,
+	const git_diff_file *t,
+	const git_diff_file *w,
+	void *payload)
+{
+	struct checkout_cancel_at *ca = payload;
+
+	GIT_UNUSED(why); GIT_UNUSED(b); GIT_UNUSED(t); GIT_UNUSED(w);
+
+	ca->count++;
+
+	if (!strcmp(path, ca->filename))
+		return ca->error;
+
+	return 0;
+}
+
+void test_checkout_tree__can_cancel_checkout_from_notify(void)
+{
+	struct checkout_cancel_at ca;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_oid oid;
+	git_object *obj = NULL;
+
+	assert_on_branch(g_repo, "master");
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+	ca.filename = "new.txt";
+	ca.error = -5555;
+	ca.count = 0;
+
+	opts.notify_flags = GIT_CHECKOUT_NOTIFY_UPDATED;
+	opts.notify_cb = checkout_cancel_cb;
+	opts.notify_payload = &ca;
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_assert(!git_path_exists("testrepo/new.txt"));
+
+	cl_git_fail_with(git_checkout_tree(g_repo, obj, &opts), -5555);
+
+	cl_assert(!git_path_exists("testrepo/new.txt"));
+
+	/* on case-insensitive FS = a/b.txt, branch_file.txt, new.txt */
+	/* on case-sensitive FS   = README, then above */
+
+	if (git_path_exists("testrepo/.git/CoNfIg")) /* case insensitive */
+		cl_assert_equal_i(3, ca.count);
+	else
+		cl_assert_equal_i(4, ca.count);
+
+	/* and again with a different stopping point and return code */
+	ca.filename = "README";
+	ca.error = 123;
+	ca.count = 0;
+
+	cl_git_fail_with(git_checkout_tree(g_repo, obj, &opts), 123);
+
+	cl_assert(!git_path_exists("testrepo/new.txt"));
+
+	if (git_path_exists("testrepo/.git/CoNfIg")) /* case insensitive */
+		cl_assert_equal_i(4, ca.count);
+	else
+		cl_assert_equal_i(1, ca.count);
+
+	git_object_free(obj);
+}
+
+void test_checkout_tree__can_checkout_with_last_workdir_item_missing(void)
+{
+	git_index *index = NULL;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_oid tree_id, commit_id;
+	git_tree *tree = NULL;
+	git_commit *commit = NULL;
+
+	git_repository_index(&index, g_repo);
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_pass(git_reference_name_to_id(&commit_id, g_repo, "refs/heads/master"));
+	cl_git_pass(git_commit_lookup(&commit, g_repo, &commit_id));
+
+	cl_git_pass(git_checkout_tree(g_repo, (git_object *)commit, &opts));
+	cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master"));
+
+	cl_git_pass(p_mkdir("./testrepo/this-is-dir", 0777));
+	cl_git_mkfile("./testrepo/this-is-dir/contained_file", "content\n");
+
+	cl_git_pass(git_index_add_bypath(index, "this-is-dir/contained_file"));
+	git_index_write_tree(&tree_id, index);
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
+
+	cl_git_pass(p_unlink("./testrepo/this-is-dir/contained_file"));
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+	opts.checkout_strategy = 1;
+	git_checkout_tree(g_repo, (git_object *)tree, &opts);
+
+	git_tree_free(tree);
+	git_commit_free(commit);
+	git_index_free(index);
+}
+
+void test_checkout_tree__issue_1397(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	const char *partial_oid = "8a7ef04";
+	git_object *tree = NULL;
+
+	test_checkout_tree__cleanup(); /* cleanup default checkout */
+
+	g_repo = cl_git_sandbox_init("issue_1397");
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	cl_git_pass(git_revparse_single(&tree, g_repo, partial_oid));
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_pass(git_checkout_tree(g_repo, tree, &opts));
+
+	check_file_contents("./issue_1397/crlf_file.txt", "first line\r\nsecond line\r\nboth with crlf");
+
+	git_object_free(tree);
+}
+
+void test_checkout_tree__can_write_to_empty_dirs(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_oid oid;
+	git_object *obj = NULL;
+
+	assert_on_branch(g_repo, "master");
+
+	cl_git_pass(p_mkdir("testrepo/a", 0777));
+
+	/* do first checkout with FORCE because we don't know if testrepo
+	 * base data is clean for a checkout or not
+	 */
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+
+	cl_assert(git_path_isfile("testrepo/a/b.txt"));
+
+	git_object_free(obj);
+}
+
+void test_checkout_tree__fails_when_dir_in_use(void)
+{
+#ifdef GIT_WIN32
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_oid oid;
+	git_object *obj = NULL;
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+
+	cl_assert(git_path_isfile("testrepo/a/b.txt"));
+
+	git_object_free(obj);
+
+	cl_git_pass(p_chdir("testrepo/a"));
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/master"));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_fail(git_checkout_tree(g_repo, obj, &opts));
+
+	cl_git_pass(p_chdir("../.."));
+
+	cl_assert(git_path_is_empty_dir("testrepo/a"));
+
+	git_object_free(obj);
+#endif
+}
+
+void test_checkout_tree__can_continue_when_dir_in_use(void)
+{
+#ifdef GIT_WIN32
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_oid oid;
+	git_object *obj = NULL;
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE |
+		GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+
+	cl_assert(git_path_isfile("testrepo/a/b.txt"));
+
+	git_object_free(obj);
+
+	cl_git_pass(p_chdir("testrepo/a"));
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/master"));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+
+	cl_git_pass(p_chdir("../.."));
+
+	cl_assert(git_path_is_empty_dir("testrepo/a"));
+
+	git_object_free(obj);
+#endif
+}
+
+void test_checkout_tree__target_directory_from_bare(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_oid oid;
+	checkout_counts cts;
+	memset(&cts, 0, sizeof(cts));
+
+	test_checkout_tree__cleanup(); /* cleanup default checkout */
+
+	g_repo = cl_git_sandbox_init("testrepo.git");
+	cl_assert(git_repository_is_bare(g_repo));
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE |
+		GIT_CHECKOUT_RECREATE_MISSING;
+
+	opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL;
+	opts.notify_cb = checkout_count_callback;
+	opts.notify_payload = &cts;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "HEAD"));
+	cl_git_pass(git_object_lookup(&g_object, g_repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_fail(git_checkout_tree(g_repo, g_object, &opts));
+
+	opts.target_directory = "alternative";
+	cl_assert(!git_path_isdir("alternative"));
+
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &opts));
+
+	cl_assert_equal_i(0, cts.n_untracked);
+	cl_assert_equal_i(0, cts.n_ignored);
+	cl_assert_equal_i(3, cts.n_updates);
+
+	check_file_contents_nocr("./alternative/README", "hey there\n");
+	check_file_contents_nocr("./alternative/branch_file.txt", "hi\nbye!\n");
+	check_file_contents_nocr("./alternative/new.txt", "my new file\n");
+
+	cl_git_pass(git_futils_rmdir_r(
+		"alternative", NULL, GIT_RMDIR_REMOVE_FILES));
+}
+
+void test_checkout_tree__extremely_long_file_name(void)
+{
+	// A utf-8 string with 83 characters, but 249 bytes.
+	const char *longname = "\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97";
+	char path[1024];
+
+	g_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+	cl_git_pass(git_revparse_single(&g_object, g_repo, "long-file-name"));
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
+
+	sprintf(path, "testrepo/%s.txt", longname);
+	cl_assert(git_path_exists(path));
+
+	git_object_free(g_object);
+	cl_git_pass(git_revparse_single(&g_object, g_repo, "master"));
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
+	cl_assert(!git_path_exists(path));
+}
+
+static void create_conflict(const char *path)
+{
+	git_index *index;
+	git_index_entry entry;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	memset(&entry, 0x0, sizeof(git_index_entry));
+	entry.mode = 0100644;
+	GIT_IDXENTRY_STAGE_SET(&entry, 1);
+	git_oid_fromstr(&entry.id, "d427e0b2e138501a3d15cc376077a3631e15bd46");
+	entry.path = path;
+	cl_git_pass(git_index_add(index, &entry));
+
+	GIT_IDXENTRY_STAGE_SET(&entry, 2);
+	git_oid_fromstr(&entry.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf");
+	cl_git_pass(git_index_add(index, &entry));
+
+	GIT_IDXENTRY_STAGE_SET(&entry, 3);
+	git_oid_fromstr(&entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863");
+	cl_git_pass(git_index_add(index, &entry));
+
+	git_index_write(index);
+	git_index_free(index);
+}
+
+void test_checkout_tree__fails_when_conflicts_exist_in_index(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_oid oid;
+	git_object *obj = NULL;
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "HEAD"));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+	create_conflict("conflicts.txt");
+
+	cl_git_fail(git_checkout_tree(g_repo, obj, &opts));
+
+	git_object_free(obj);
+}
+
+void test_checkout_tree__filemode_preserved_in_index(void)
+{
+	git_oid executable_oid;
+	git_commit *commit;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_index *index;
+	const git_index_entry *entry;
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	/* test a freshly added executable */
+	cl_git_pass(git_oid_fromstr(&executable_oid, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6"));
+	cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid));
+
+	cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts));
+	cl_assert(entry = git_index_get_bypath(index, "executable.txt", 0));
+	cl_assert_equal_i(0100755, entry->mode);
+
+	git_commit_free(commit);
+
+
+	/* Now start with a commit which has a text file */
+	cl_git_pass(git_oid_fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9"));
+	cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid));
+
+	cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts));
+	cl_assert(entry = git_index_get_bypath(index, "a/b.txt", 0));
+	cl_assert_equal_i(0100644, entry->mode);
+
+	git_commit_free(commit);
+
+
+	/* And then check out to a commit which converts the text file to an executable */
+	cl_git_pass(git_oid_fromstr(&executable_oid, "144344043ba4d4a405da03de3844aa829ae8be0e"));
+	cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid));
+
+	cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts));
+	cl_assert(entry = git_index_get_bypath(index, "a/b.txt", 0));
+	cl_assert_equal_i(0100755, entry->mode);
+
+	git_commit_free(commit);
+
+
+	git_index_free(index);
+}
+
+void test_checkout_tree__removes_conflicts(void)
+{
+	git_oid commit_id;
+	git_commit *commit;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_index *index;
+	
+	cl_git_pass(git_oid_fromstr(&commit_id, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6"));
+	cl_git_pass(git_commit_lookup(&commit, g_repo, &commit_id));
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts));
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_remove(index, "executable.txt", 0));
+
+	create_conflict("executable.txt");
+	cl_git_mkfile("testrepo/executable.txt", "This is the conflict file.\n");
+
+	create_conflict("other.txt");
+	cl_git_mkfile("testrepo/other.txt", "This is another conflict file.\n");
+
+	git_index_write(index);
+
+	cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts));
+
+	cl_assert_equal_p(NULL, git_index_get_bypath(index, "executable.txt", 1));
+	cl_assert_equal_p(NULL, git_index_get_bypath(index, "executable.txt", 2));
+	cl_assert_equal_p(NULL, git_index_get_bypath(index, "executable.txt", 3));
+
+	cl_assert_equal_p(NULL, git_index_get_bypath(index, "other.txt", 1));
+	cl_assert_equal_p(NULL, git_index_get_bypath(index, "other.txt", 2));
+	cl_assert_equal_p(NULL, git_index_get_bypath(index, "other.txt", 3));
+
+	cl_assert(!git_path_exists("testrepo/other.txt"));
+
+	git_commit_free(commit);
+	git_index_free(index);
+}
+
+
+void test_checkout_tree__removes_conflicts_only_by_pathscope(void)
+{
+	git_oid commit_id;
+	git_commit *commit;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_index *index;
+	const char *path = "executable.txt";
+	
+	cl_git_pass(git_oid_fromstr(&commit_id, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6"));
+	cl_git_pass(git_commit_lookup(&commit, g_repo, &commit_id));
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+	opts.paths.count = 1;
+	opts.paths.strings = (char **)&path;
+
+	cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts));
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_remove(index, "executable.txt", 0));
+
+	create_conflict("executable.txt");
+	cl_git_mkfile("testrepo/executable.txt", "This is the conflict file.\n");
+
+	create_conflict("other.txt");
+	cl_git_mkfile("testrepo/other.txt", "This is another conflict file.\n");
+
+	git_index_write(index);
+
+	cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts));
+
+	cl_assert_equal_p(NULL, git_index_get_bypath(index, "executable.txt", 1));
+	cl_assert_equal_p(NULL, git_index_get_bypath(index, "executable.txt", 2));
+	cl_assert_equal_p(NULL, git_index_get_bypath(index, "executable.txt", 3));
+
+	cl_assert(git_index_get_bypath(index, "other.txt", 1) != NULL);
+	cl_assert(git_index_get_bypath(index, "other.txt", 2) != NULL);
+	cl_assert(git_index_get_bypath(index, "other.txt", 3) != NULL);
+
+	cl_assert(git_path_exists("testrepo/other.txt"));
+
+	git_commit_free(commit);
+	git_index_free(index);
+}
+
+void test_checkout_tree__case_changing_rename(void)
+{
+	git_index *index;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_oid master_id, dir_commit_id, tree_id, commit_id;
+	git_commit *master_commit, *dir_commit;
+	git_tree *tree;
+	git_signature *signature;
+	const git_index_entry *index_entry;
+	bool case_sensitive;
+
+	assert_on_branch(g_repo, "master");
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	/* Switch branches and perform a case-changing rename */
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_pass(git_reference_name_to_id(&dir_commit_id, g_repo, "refs/heads/dir"));
+	cl_git_pass(git_commit_lookup(&dir_commit, g_repo, &dir_commit_id));
+
+	cl_git_pass(git_checkout_tree(g_repo, (git_object *)dir_commit, &opts));
+	cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir"));
+
+	cl_assert(git_path_isfile("testrepo/README"));
+	case_sensitive = !git_path_isfile("testrepo/readme");
+
+	cl_assert(index_entry = git_index_get_bypath(index, "README", 0));
+	cl_assert_equal_s("README", index_entry->path);
+
+	cl_git_pass(git_index_remove_bypath(index, "README"));
+	cl_git_pass(p_rename("testrepo/README", "testrepo/__readme__"));
+	cl_git_pass(p_rename("testrepo/__readme__", "testrepo/readme"));
+	cl_git_append2file("testrepo/readme", "An addendum...");
+	cl_git_pass(git_index_add_bypath(index, "readme"));
+
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_index_write_tree(&tree_id, index));
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
+
+	cl_git_pass(git_signature_new(&signature, "Renamer", "rename at contoso.com", time(NULL), 0));
+
+	cl_git_pass(git_commit_create(&commit_id, g_repo, "refs/heads/dir", signature, signature, NULL, "case-changing rename", tree, 1, (const git_commit **)&dir_commit));
+
+	cl_assert(git_path_isfile("testrepo/readme"));
+	if (case_sensitive)
+		cl_assert(!git_path_isfile("testrepo/README"));
+
+	cl_assert(index_entry = git_index_get_bypath(index, "readme", 0));
+	cl_assert_equal_s("readme", index_entry->path);
+
+	/* Switching back to master should rename readme -> README */
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+	cl_git_pass(git_reference_name_to_id(&master_id, g_repo, "refs/heads/master"));
+	cl_git_pass(git_commit_lookup(&master_commit, g_repo, &master_id));
+
+	cl_git_pass(git_checkout_tree(g_repo, (git_object *)master_commit, &opts));
+	cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master"));
+	
+	assert_on_branch(g_repo, "master");
+
+	cl_assert(git_path_isfile("testrepo/README"));
+	if (case_sensitive)
+		cl_assert(!git_path_isfile("testrepo/readme"));
+
+	cl_assert(index_entry = git_index_get_bypath(index, "README", 0));
+	cl_assert_equal_s("README", index_entry->path);
+
+	git_index_free(index);
+	git_signature_free(signature);
+	git_tree_free(tree);
+	git_commit_free(dir_commit);
+	git_commit_free(master_commit);
+}
+
+void perfdata_cb(const git_checkout_perfdata *in, void *payload)
+{
+	memcpy(payload, in, sizeof(git_checkout_perfdata));
+}
+
+void test_checkout_tree__can_collect_perfdata(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_oid oid;
+	git_object *obj = NULL;
+	git_checkout_perfdata perfdata = {0};
+
+	opts.perfdata_cb = perfdata_cb;
+	opts.perfdata_payload = &perfdata;
+
+	assert_on_branch(g_repo, "master");
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+
+	cl_assert(perfdata.mkdir_calls > 0);
+	cl_assert(perfdata.stat_calls > 0);
+
+	git_object_free(obj);
+}
+
+void update_attr_callback(
+	const char *path,
+	size_t completed_steps,
+	size_t total_steps,
+	void *payload)
+{
+	GIT_UNUSED(completed_steps);
+	GIT_UNUSED(total_steps);
+	GIT_UNUSED(payload);
+
+	if (path && strcmp(path, "ident1.txt") == 0)
+		cl_git_write2file("testrepo/.gitattributes",
+			"*.txt ident\n", 12, O_RDWR|O_CREAT, 0666);
+}
+
+void test_checkout_tree__caches_attributes_during_checkout(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_oid oid;
+	git_object *obj = NULL;
+	git_buf ident1 = GIT_BUF_INIT, ident2 = GIT_BUF_INIT;
+	char *ident_paths[] = { "ident1.txt", "ident2.txt" };
+
+	opts.progress_cb = update_attr_callback;
+
+	assert_on_branch(g_repo, "master");
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+	opts.paths.strings = ident_paths;
+	opts.paths.count = 2;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/ident"));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+
+	cl_git_pass(git_futils_readbuffer(&ident1, "testrepo/ident1.txt"));
+	cl_git_pass(git_futils_readbuffer(&ident2, "testrepo/ident2.txt"));
+
+	cl_assert_equal_strn(ident1.ptr, "# $Id$", 6);
+	cl_assert_equal_strn(ident2.ptr, "# $Id$", 6);
+
+	cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+
+	cl_git_pass(git_futils_readbuffer(&ident1, "testrepo/ident1.txt"));
+	cl_git_pass(git_futils_readbuffer(&ident2, "testrepo/ident2.txt"));
+
+	cl_assert_equal_strn(ident1.ptr, "# $Id: ", 7);
+	cl_assert_equal_strn(ident2.ptr, "# $Id: ", 7);
+
+	git_buf_free(&ident1);
+	git_buf_free(&ident2);
+	git_object_free(obj);
+}
+
+void test_checkout_tree__can_not_update_index(void)
+{
+	git_oid oid;
+	git_object *head;
+	unsigned int status;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_index *index;
+
+	opts.checkout_strategy |=
+		GIT_CHECKOUT_FORCE | GIT_CHECKOUT_DONT_UPDATE_INDEX;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "HEAD"));
+	cl_git_pass(git_object_lookup(&head, g_repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_pass(git_reset(g_repo, head, GIT_RESET_HARD, &g_opts));
+
+	cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/"));
+
+	cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees"));
+
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &opts));
+
+	cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt"));
+	cl_git_pass(git_status_file(&status, g_repo, "ab/de/2.txt"));
+	cl_assert_equal_i(GIT_STATUS_WT_NEW, status);
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_status_file(&status, g_repo, "ab/de/2.txt"));
+	cl_assert_equal_i(GIT_STATUS_WT_NEW, status);
+
+	git_object_free(head);
+	git_index_free(index);
+}
+
+void test_checkout_tree__can_update_but_not_write_index(void)
+{
+	git_oid oid;
+	git_object *head;
+	unsigned int status;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_index *index;
+	git_repository *other;
+
+	opts.checkout_strategy |=
+		GIT_CHECKOUT_FORCE | GIT_CHECKOUT_DONT_WRITE_INDEX;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "HEAD"));
+	cl_git_pass(git_object_lookup(&head, g_repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_pass(git_reset(g_repo, head, GIT_RESET_HARD, &g_opts));
+
+	cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/"));
+
+	cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees"));
+
+	cl_git_pass(git_checkout_tree(g_repo, g_object, &opts));
+
+	cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt"));
+	cl_git_pass(git_status_file(&status, g_repo, "ab/de/2.txt"));
+	cl_assert_equal_i(GIT_STATUS_INDEX_NEW, status);
+
+	cl_git_pass(git_repository_open(&other, "testrepo"));
+	cl_git_pass(git_status_file(&status, other, "ab/de/2.txt"));
+	cl_assert_equal_i(GIT_STATUS_WT_NEW, status);
+	git_repository_free(other);
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_repository_open(&other, "testrepo"));
+	cl_git_pass(git_status_file(&status, other, "ab/de/2.txt"));
+	cl_assert_equal_i(GIT_STATUS_INDEX_NEW, status);
+	git_repository_free(other);
+
+	git_object_free(head);
+	git_index_free(index);
+}
+
+/* Emulate checking out in a repo created by clone --no-checkout,
+ * which would not have written an index. */
+void test_checkout_tree__safe_proceeds_if_no_index(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_oid oid;
+	git_object *obj = NULL;
+
+	assert_on_branch(g_repo, "master");
+	cl_must_pass(p_unlink("testrepo/.git/index"));
+
+	/* do second checkout safe because we should be clean after first */
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/subtrees"));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+	cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+	cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees"));
+
+	cl_assert(git_path_isfile("testrepo/README"));
+	cl_assert(git_path_isfile("testrepo/branch_file.txt"));
+	cl_assert(git_path_isfile("testrepo/new.txt"));
+	cl_assert(git_path_isfile("testrepo/ab/4.txt"));
+	cl_assert(git_path_isfile("testrepo/ab/c/3.txt"));
+	cl_assert(git_path_isfile("testrepo/ab/de/2.txt"));
+	cl_assert(git_path_isfile("testrepo/ab/de/fgh/1.txt"));
+
+	cl_assert(!git_path_isdir("testrepo/a"));
+
+	assert_on_branch(g_repo, "subtrees");
+
+	git_object_free(obj);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/typechange.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/typechange.c
new file mode 100755
index 0000000..b4959a3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/checkout/typechange.c
@@ -0,0 +1,240 @@
+#include "clar_libgit2.h"
+#include "git2/checkout.h"
+#include "path.h"
+#include "posix.h"
+#include "fileops.h"
+
+static git_repository *g_repo = NULL;
+
+static const char *g_typechange_oids[] = {
+	"79b9f23e85f55ea36a472a902e875bc1121a94cb",
+	"9bdb75b73836a99e3dbeea640a81de81031fdc29",
+	"0e7ed140b514b8cae23254cb8656fe1674403aff",
+	"9d0235c7a7edc0889a18f97a42ee6db9fe688447",
+	"9b19edf33a03a0c59cdfc113bfa5c06179bf9b1a",
+	"1b63caae4a5ca96f78e8dfefc376c6a39a142475",
+	"6eae26c90e8ccc4d16208972119c40635489c6f0",
+	NULL
+};
+
+static bool g_typechange_empty[] = {
+	true, false, false, false, false, false, true, true
+};
+
+void test_checkout_typechange__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("typechanges");
+
+	cl_fixture_sandbox("submod2_target");
+	p_rename("submod2_target/.gitted", "submod2_target/.git");
+}
+
+void test_checkout_typechange__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+	cl_fixture_cleanup("submod2_target");
+}
+
+static void assert_file_exists(const char *path)
+{
+	cl_assert_(git_path_isfile(path), path);
+}
+
+static void assert_dir_exists(const char *path)
+{
+	cl_assert_(git_path_isdir(path), path);
+}
+
+static void assert_workdir_matches_tree(
+	git_repository *repo, const git_oid *id, const char *root, bool recurse)
+{
+	git_object *obj;
+	git_tree *tree;
+	size_t i, max_i;
+	git_buf path = GIT_BUF_INIT;
+
+	if (!root)
+		root = git_repository_workdir(repo);
+	cl_assert(root);
+
+	cl_git_pass(git_object_lookup(&obj, repo, id, GIT_OBJ_ANY));
+	cl_git_pass(git_object_peel((git_object **)&tree, obj, GIT_OBJ_TREE));
+	git_object_free(obj);
+
+	max_i = git_tree_entrycount(tree);
+
+	for (i = 0; i < max_i; ++i) {
+		const git_tree_entry *te = git_tree_entry_byindex(tree, i);
+		cl_assert(te);
+
+		cl_git_pass(git_buf_joinpath(&path, root, git_tree_entry_name(te)));
+
+		switch (git_tree_entry_type(te)) {
+		case GIT_OBJ_COMMIT:
+			assert_dir_exists(path.ptr);
+			break;
+		case GIT_OBJ_TREE:
+			assert_dir_exists(path.ptr);
+			if (recurse)
+				assert_workdir_matches_tree(
+					repo, git_tree_entry_id(te), path.ptr, true);
+			break;
+		case GIT_OBJ_BLOB:
+			switch (git_tree_entry_filemode(te)) {
+			case GIT_FILEMODE_BLOB:
+			case GIT_FILEMODE_BLOB_EXECUTABLE:
+				assert_file_exists(path.ptr);
+				/* because of cross-platform, don't confirm exec bit yet */
+				break;
+			case GIT_FILEMODE_LINK:
+				cl_assert_(git_path_exists(path.ptr), path.ptr);
+				/* because of cross-platform, don't confirm link yet */
+				break;
+			default:
+				cl_assert(false); /* really?! */
+			}
+			break;
+		default:
+			cl_assert(false); /* really?!! */
+		}
+	}
+
+	git_tree_free(tree);
+	git_buf_free(&path);
+}
+
+void test_checkout_typechange__checkout_typechanges_safe(void)
+{
+	int i;
+	git_object *obj;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	for (i = 0; g_typechange_oids[i] != NULL; ++i) {
+		cl_git_pass(git_revparse_single(&obj, g_repo, g_typechange_oids[i]));
+
+		opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+		/* There are bugs in some submodule->tree changes that prevent
+		 * SAFE from passing here, even though the following should work:
+		 */
+		/* !i ? GIT_CHECKOUT_FORCE : GIT_CHECKOUT_SAFE; */
+
+		cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+
+		cl_git_pass(
+			git_repository_set_head_detached(g_repo, git_object_id(obj)));
+
+		assert_workdir_matches_tree(g_repo, git_object_id(obj), NULL, true);
+
+		git_object_free(obj);
+
+		if (!g_typechange_empty[i]) {
+			cl_assert(git_path_isdir("typechanges"));
+			cl_assert(git_path_exists("typechanges/a"));
+			cl_assert(git_path_exists("typechanges/b"));
+			cl_assert(git_path_exists("typechanges/c"));
+			cl_assert(git_path_exists("typechanges/d"));
+			cl_assert(git_path_exists("typechanges/e"));
+		} else {
+			cl_assert(git_path_isdir("typechanges"));
+			cl_assert(!git_path_exists("typechanges/a"));
+			cl_assert(!git_path_exists("typechanges/b"));
+			cl_assert(!git_path_exists("typechanges/c"));
+			cl_assert(!git_path_exists("typechanges/d"));
+			cl_assert(!git_path_exists("typechanges/e"));
+		}
+	}
+}
+
+typedef struct {
+	int conflicts;
+	int dirty;
+	int updates;
+	int untracked;
+	int ignored;
+} notify_counts;
+
+static int notify_counter(
+	git_checkout_notify_t why,
+	const char *path,
+	const git_diff_file *baseline,
+	const git_diff_file *target,
+	const git_diff_file *workdir,
+	void *payload)
+{
+	notify_counts *cts = payload;
+
+	GIT_UNUSED(path);
+	GIT_UNUSED(baseline);
+	GIT_UNUSED(target);
+	GIT_UNUSED(workdir);
+
+	switch (why) {
+	case GIT_CHECKOUT_NOTIFY_CONFLICT:  cts->conflicts++; break;
+	case GIT_CHECKOUT_NOTIFY_DIRTY:     cts->dirty++;     break;
+	case GIT_CHECKOUT_NOTIFY_UPDATED:   cts->updates++;   break;
+	case GIT_CHECKOUT_NOTIFY_UNTRACKED: cts->untracked++; break;
+	case GIT_CHECKOUT_NOTIFY_IGNORED:   cts->ignored++;   break;
+	default: break;
+	}
+
+	return 0;
+}
+
+static void force_create_file(const char *file)
+{
+	int error = git_futils_rmdir_r(file, NULL,
+		GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_REMOVE_BLOCKERS);
+	cl_assert(!error || error == GIT_ENOTFOUND);
+	cl_git_pass(git_futils_mkpath2file(file, 0777));
+	cl_git_rewritefile(file, "yowza!!");
+}
+
+void test_checkout_typechange__checkout_with_conflicts(void)
+{
+	int i;
+	git_object *obj;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	notify_counts cts = {0};
+
+	opts.notify_flags =
+		GIT_CHECKOUT_NOTIFY_CONFLICT | GIT_CHECKOUT_NOTIFY_UNTRACKED;
+	opts.notify_cb = notify_counter;
+	opts.notify_payload = &cts;
+
+	for (i = 0; g_typechange_oids[i] != NULL; ++i) {
+		cl_git_pass(git_revparse_single(&obj, g_repo, g_typechange_oids[i]));
+
+		force_create_file("typechanges/a/blocker");
+		force_create_file("typechanges/b");
+		force_create_file("typechanges/c/sub/sub/file");
+		git_futils_rmdir_r("typechanges/d", NULL, GIT_RMDIR_REMOVE_FILES);
+		p_mkdir("typechanges/d", 0777); /* intentionally empty dir */
+		force_create_file("typechanges/untracked");
+
+		opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+		memset(&cts, 0, sizeof(cts));
+
+		cl_git_fail(git_checkout_tree(g_repo, obj, &opts));
+		cl_assert(cts.conflicts > 0);
+		cl_assert(cts.untracked > 0);
+
+		opts.checkout_strategy =
+			GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED;
+		memset(&cts, 0, sizeof(cts));
+
+		cl_assert(git_path_exists("typechanges/untracked"));
+
+		cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+		cl_assert_equal_i(0, cts.conflicts);
+
+		cl_assert(!git_path_exists("typechanges/untracked"));
+
+		cl_git_pass(
+			git_repository_set_head_detached(g_repo, git_object_id(obj)));
+
+		assert_workdir_matches_tree(g_repo, git_object_id(obj), NULL, true);
+
+		git_object_free(obj);
+	}
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/cherrypick/bare.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/cherrypick/bare.c
new file mode 100755
index 0000000..1353365
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/cherrypick/bare.c
@@ -0,0 +1,106 @@
+#include "clar.h"
+#include "clar_libgit2.h"
+
+#include "buffer.h"
+#include "fileops.h"
+#include "git2/cherrypick.h"
+
+#include "../merge/merge_helpers.h"
+
+#define TEST_REPO_PATH "cherrypick"
+
+static git_repository *repo;
+
+void test_cherrypick_bare__initialize(void)
+{
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+}
+
+void test_cherrypick_bare__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_cherrypick_bare__automerge(void)
+{
+	git_commit *head = NULL, *commit = NULL;
+	git_index *index = NULL;
+	git_oid head_oid, cherry_oid;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "38c05a857e831a7e759d83778bfc85d003e21c45", 0, "file1.txt" },
+		{ 0100644, "a661b5dec1004e2c62654ded3762370c27cf266b", 0, "file2.txt" },
+		{ 0100644, "df6b290e0bd6a89b01d69f66687e8abf385283ca", 0, "file3.txt" },
+	};
+
+	git_oid_fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+
+	git_oid_fromstr(&cherry_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
+	cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+
+	cl_git_pass(git_cherrypick_commit(&index, repo, commit, head, 0, NULL));
+	cl_assert(merge_test_index(index, merge_index_entries, 3));
+
+	git_index_free(index);
+	git_commit_free(head);
+	git_commit_free(commit);
+}
+
+void test_cherrypick_bare__conflicts(void)
+{
+	git_commit *head = NULL, *commit = NULL;
+	git_index *index = NULL;
+	git_oid head_oid, cherry_oid;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "242e7977ba73637822ffb265b46004b9b0e5153b", 0, "file1.txt" },
+		{ 0100644, "a58ca3fee5eb68b11adc2703e5843f968c9dad1e", 1, "file2.txt" },
+		{ 0100644, "bd6ffc8c6c41f0f85ff9e3d61c9479516bac0024", 2, "file2.txt" },
+		{ 0100644, "563f6473a3858f99b80e5f93c660512ed38e1e6f", 3, "file2.txt" },
+		{ 0100644, "28d9eb4208074ad1cc84e71ccc908b34573f05d2", 1, "file3.txt" },
+		{ 0100644, "1124c2c1ae07b26fded662d6c3f3631d9dc16f88", 2, "file3.txt" },
+		{ 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 3, "file3.txt" },
+	};
+
+	git_oid_fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+
+	git_oid_fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110");
+	cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+
+	cl_git_pass(git_cherrypick_commit(&index, repo, commit, head, 0, NULL));
+	cl_assert(merge_test_index(index, merge_index_entries, 7));
+
+	git_index_free(index);
+	git_commit_free(head);
+	git_commit_free(commit);
+}
+
+void test_cherrypick_bare__orphan(void)
+{
+	git_commit *head = NULL, *commit = NULL;
+	git_index *index = NULL;
+	git_oid head_oid, cherry_oid;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "38c05a857e831a7e759d83778bfc85d003e21c45", 0, "file1.txt" },
+		{ 0100644, "a661b5dec1004e2c62654ded3762370c27cf266b", 0, "file2.txt" },
+		{ 0100644, "85a4a1d791973644f24c72f5e89420d3064cc452", 0, "file3.txt" },
+		{ 0100644, "9ccb9bf50c011fd58dcbaa65df917bf79539717f", 0, "orphan.txt" },
+	};
+
+	git_oid_fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+
+	git_oid_fromstr(&cherry_oid, "74f06b5bfec6d33d7264f73606b57a7c0b963819");
+	cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+
+	cl_git_pass(git_cherrypick_commit(&index, repo, commit, head, 0, NULL));
+	cl_assert(merge_test_index(index, merge_index_entries, 4));
+
+	git_index_free(index);
+	git_commit_free(head);
+	git_commit_free(commit);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/cherrypick/workdir.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/cherrypick/workdir.c
new file mode 100755
index 0000000..787f1f4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/cherrypick/workdir.c
@@ -0,0 +1,470 @@
+#include "clar.h"
+#include "clar_libgit2.h"
+
+#include "buffer.h"
+#include "fileops.h"
+#include "git2/cherrypick.h"
+
+#include "../merge/merge_helpers.h"
+
+#define TEST_REPO_PATH "cherrypick"
+
+static git_repository *repo;
+static git_index *repo_index;
+
+// Fixture setup and teardown
+void test_cherrypick_workdir__initialize(void)
+{
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+	git_repository_index(&repo_index, repo);
+}
+
+void test_cherrypick_workdir__cleanup(void)
+{
+	git_index_free(repo_index);
+	cl_git_sandbox_cleanup();
+}
+
+/* git reset --hard d3d77487660ee3c0194ee01dc5eaf478782b1c7e
+ * git cherry-pick cfc4f0999a8367568e049af4f72e452d40828a15
+ * git cherry-pick 964ea3da044d9083181a88ba6701de9e35778bf4
+ * git cherry-pick a43a050c588d4e92f11a6b139680923e9728477d
+ */
+void test_cherrypick_workdir__automerge(void)
+{
+	git_oid head_oid;
+	git_signature *signature = NULL;
+	size_t i;
+
+	const char *cherrypick_oids[] = {
+		"cfc4f0999a8367568e049af4f72e452d40828a15",
+		"964ea3da044d9083181a88ba6701de9e35778bf4",
+		"a43a050c588d4e92f11a6b139680923e9728477d",
+	};
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "38c05a857e831a7e759d83778bfc85d003e21c45", 0, "file1.txt" },
+		{ 0100644, "a661b5dec1004e2c62654ded3762370c27cf266b", 0, "file2.txt" },
+		{ 0100644, "df6b290e0bd6a89b01d69f66687e8abf385283ca", 0, "file3.txt" },
+
+		{ 0100644, "38c05a857e831a7e759d83778bfc85d003e21c45", 0, "file1.txt" },
+		{ 0100644, "bd8fc3c59fb52d3c8b5907ace7defa5803f82419", 0, "file2.txt" },
+		{ 0100644, "df6b290e0bd6a89b01d69f66687e8abf385283ca", 0, "file3.txt" },
+
+		{ 0100644, "f06427bee380364bc7e0cb26a9245158e4726ce0", 0, "file1.txt" },
+		{ 0100644, "bd8fc3c59fb52d3c8b5907ace7defa5803f82419", 0, "file2.txt" },
+		{ 0100644, "df6b290e0bd6a89b01d69f66687e8abf385283ca", 0, "file3.txt" },
+	};
+
+	cl_git_pass(git_signature_new(&signature, "Picker", "picker at example.org", time(NULL), 0));
+
+	git_oid_fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e");
+
+	for (i = 0; i < 3; ++i) {
+		git_commit *head = NULL, *commit = NULL;
+		git_oid cherry_oid, cherrypicked_oid, cherrypicked_tree_oid;
+		git_tree *cherrypicked_tree = NULL;
+
+		cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+		cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+		git_oid_fromstr(&cherry_oid, cherrypick_oids[i]);
+		cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+		cl_git_pass(git_cherrypick(repo, commit, NULL));
+
+		cl_assert(git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
+		cl_assert(git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
+
+		cl_git_pass(git_index_write_tree(&cherrypicked_tree_oid, repo_index));
+		cl_git_pass(git_tree_lookup(&cherrypicked_tree, repo, &cherrypicked_tree_oid));
+		cl_git_pass(git_commit_create(&cherrypicked_oid, repo, "HEAD", signature, signature, NULL,
+			"Cherry picked!", cherrypicked_tree, 1, (const git_commit **)&head));
+
+		cl_assert(merge_test_index(repo_index, merge_index_entries + i * 3, 3));
+
+		git_oid_cpy(&head_oid, &cherrypicked_oid);
+
+		git_tree_free(cherrypicked_tree);
+		git_commit_free(head);
+		git_commit_free(commit);
+	}
+
+	git_signature_free(signature);
+}
+
+/* git reset --hard cfc4f0999a8367568e049af4f72e452d40828a15
+ * git cherry-pick a43a050c588d4e92f11a6b139680923e9728477d*/
+void test_cherrypick_workdir__empty_result(void)
+{
+	git_oid head_oid;
+	git_signature *signature = NULL;
+	git_commit *head = NULL, *commit = NULL;
+	git_oid cherry_oid;
+
+	const char *cherrypick_oid = "a43a050c588d4e92f11a6b139680923e9728477d";
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "19c5c7207054604b69c84d08a7571ef9672bb5c2", 0, "file1.txt" },
+		{ 0100644, "a58ca3fee5eb68b11adc2703e5843f968c9dad1e", 0, "file2.txt" },
+		{ 0100644, "28d9eb4208074ad1cc84e71ccc908b34573f05d2", 0, "file3.txt" },
+	};
+
+	cl_git_pass(git_signature_new(&signature, "Picker", "picker at example.org", time(NULL), 0));
+
+	git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
+
+	/* Create an untracked file that should not conflict */
+	cl_git_mkfile(TEST_REPO_PATH "/file4.txt", "");
+	cl_assert(git_path_exists(TEST_REPO_PATH "/file4.txt"));
+
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	git_oid_fromstr(&cherry_oid, cherrypick_oid);
+	cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+	cl_git_pass(git_cherrypick(repo, commit, NULL));
+
+	/* The resulting tree should not have changed, the change was already on HEAD */
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 3));
+
+	git_commit_free(head);
+	git_commit_free(commit);
+
+	git_signature_free(signature);
+}
+
+/* git reset --hard bafbf6912c09505ac60575cd43d3f2aba3bd84d8
+ * git cherry-pick e9b63f3655b2ad80c0ff587389b5a9589a3a7110
+ */
+void test_cherrypick_workdir__conflicts(void)
+{
+	git_commit *head = NULL, *commit = NULL;
+	git_oid head_oid, cherry_oid;
+	git_buf conflicting_buf = GIT_BUF_INIT, mergemsg_buf = GIT_BUF_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "242e7977ba73637822ffb265b46004b9b0e5153b", 0, "file1.txt" },
+		{ 0100644, "a58ca3fee5eb68b11adc2703e5843f968c9dad1e", 1, "file2.txt" },
+		{ 0100644, "bd6ffc8c6c41f0f85ff9e3d61c9479516bac0024", 2, "file2.txt" },
+		{ 0100644, "563f6473a3858f99b80e5f93c660512ed38e1e6f", 3, "file2.txt" },
+		{ 0100644, "28d9eb4208074ad1cc84e71ccc908b34573f05d2", 1, "file3.txt" },
+		{ 0100644, "1124c2c1ae07b26fded662d6c3f3631d9dc16f88", 2, "file3.txt" },
+		{ 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 3, "file3.txt" },
+	};
+
+	git_oid_fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8");
+
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	git_oid_fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110");
+	cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+	cl_git_pass(git_cherrypick(repo, commit, NULL));
+
+	cl_assert(git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
+	cl_assert(git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 7));
+
+	cl_git_pass(git_futils_readbuffer(&mergemsg_buf,
+		TEST_REPO_PATH "/.git/MERGE_MSG"));
+	cl_assert(strcmp(git_buf_cstr(&mergemsg_buf),
+		"Change all files\n" \
+		"\n" \
+		"Conflicts:\n" \
+		"\tfile2.txt\n" \
+		"\tfile3.txt\n") == 0);
+
+	cl_git_pass(git_futils_readbuffer(&conflicting_buf,
+		TEST_REPO_PATH "/file2.txt"));
+
+	cl_assert(strcmp(git_buf_cstr(&conflicting_buf),
+		"!File 2\n" \
+		"File 2\n" \
+		"File 2\n" \
+		"File 2\n" \
+		"File 2\n" \
+		"File 2\n" \
+		"File 2\n" \
+		"File 2\n" \
+		"File 2\n" \
+		"File 2\n" \
+		"File 2!!\n" \
+		"File 2\n" \
+		"File 2\n" \
+		"File 2\n" \
+		"<<<<<<< HEAD\n" \
+		"File 2\n" \
+		"=======\n" \
+		"File 2!\n" \
+		"File 2\n" \
+		"File 2!\n" \
+		">>>>>>> e9b63f3... Change all files\n") == 0);
+
+	cl_git_pass(git_futils_readbuffer(&conflicting_buf,
+		TEST_REPO_PATH "/file3.txt"));
+
+	cl_assert(strcmp(git_buf_cstr(&conflicting_buf),
+		"!File 3\n" \
+		"File 3\n" \
+		"File 3\n" \
+		"File 3\n" \
+		"File 3\n" \
+		"File 3\n" \
+		"File 3\n" \
+		"File 3\n" \
+		"File 3\n" \
+		"File 3\n" \
+		"File 3\n" \
+		"File 3!!\n" \
+		"File 3\n" \
+		"File 3\n" \
+		"File 3\n" \
+		"<<<<<<< HEAD\n" \
+		"=======\n" \
+		"File 3!\n" \
+		"File 3!\n" \
+		">>>>>>> e9b63f3... Change all files\n") == 0);
+
+	git_commit_free(commit);
+	git_commit_free(head);
+	git_buf_free(&mergemsg_buf);
+	git_buf_free(&conflicting_buf);
+}
+
+/* git reset --hard bafbf6912c09505ac60575cd43d3f2aba3bd84d8
+ * git cherry-pick -X ours e9b63f3655b2ad80c0ff587389b5a9589a3a7110
+ */
+void test_cherrypick_workdir__conflict_use_ours(void)
+{
+	git_commit *head = NULL, *commit = NULL;
+	git_oid head_oid, cherry_oid;
+	git_cherrypick_options opts = GIT_CHERRYPICK_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "242e7977ba73637822ffb265b46004b9b0e5153b", 0, "file1.txt" },
+		{ 0100644, "a58ca3fee5eb68b11adc2703e5843f968c9dad1e", 1, "file2.txt" },
+		{ 0100644, "bd6ffc8c6c41f0f85ff9e3d61c9479516bac0024", 2, "file2.txt" },
+		{ 0100644, "563f6473a3858f99b80e5f93c660512ed38e1e6f", 3, "file2.txt" },
+		{ 0100644, "28d9eb4208074ad1cc84e71ccc908b34573f05d2", 1, "file3.txt" },
+		{ 0100644, "1124c2c1ae07b26fded662d6c3f3631d9dc16f88", 2, "file3.txt" },
+		{ 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 3, "file3.txt" },
+	};
+
+	struct merge_index_entry merge_filesystem_entries[] = {
+		{ 0100644, "242e7977ba73637822ffb265b46004b9b0e5153b", 0, "file1.txt" },
+		{ 0100644, "bd6ffc8c6c41f0f85ff9e3d61c9479516bac0024", 0, "file2.txt" },
+		{ 0100644, "1124c2c1ae07b26fded662d6c3f3631d9dc16f88", 0, "file3.txt" },
+	};
+
+	/* leave the index in a conflicted state, but checkout "ours" to the workdir */
+	opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_USE_OURS;
+
+	git_oid_fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8");
+
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	git_oid_fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110");
+	cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+	cl_git_pass(git_cherrypick(repo, commit, &opts));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 7));
+	cl_assert(merge_test_workdir(repo, merge_filesystem_entries, 3));
+
+	/* resolve conflicts in the index by taking "ours" */
+	opts.merge_opts.file_favor = GIT_MERGE_FILE_FAVOR_OURS;
+
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+	cl_git_pass(git_cherrypick(repo, commit, &opts));
+
+	cl_assert(merge_test_index(repo_index, merge_filesystem_entries, 3));
+	cl_assert(merge_test_workdir(repo, merge_filesystem_entries, 3));
+
+	git_commit_free(commit);
+	git_commit_free(head);
+}
+
+/* git reset --hard cfc4f0999a8367568e049af4f72e452d40828a15
+ * git cherry-pick 2a26c7e88b285613b302ba76712bc998863f3cbc
+ */
+void test_cherrypick_workdir__rename(void)
+{
+	git_commit *head, *commit;
+	git_oid head_oid, cherry_oid;
+	git_cherrypick_options opts = GIT_CHERRYPICK_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "19c5c7207054604b69c84d08a7571ef9672bb5c2", 0, "file1.txt" },
+		{ 0100644, "a58ca3fee5eb68b11adc2703e5843f968c9dad1e", 0, "file2.txt" },
+		{ 0100644, "28d9eb4208074ad1cc84e71ccc908b34573f05d2", 0, "file3.txt.renamed" },
+	};
+
+	opts.merge_opts.tree_flags |= GIT_MERGE_TREE_FIND_RENAMES;
+	opts.merge_opts.rename_threshold = 50;
+
+	git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	git_oid_fromstr(&cherry_oid, "2a26c7e88b285613b302ba76712bc998863f3cbc");
+	cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+	cl_git_pass(git_cherrypick(repo, commit, &opts));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 3));
+
+	git_commit_free(commit);
+	git_commit_free(head);
+}
+
+/* git reset --hard 44cd2ed2052c9c68f9a439d208e9614dc2a55c70
+ * git cherry-pick 2a26c7e88b285613b302ba76712bc998863f3cbc
+ */
+void test_cherrypick_workdir__both_renamed(void)
+{
+	git_commit *head, *commit;
+	git_oid head_oid, cherry_oid;
+	git_buf mergemsg_buf = GIT_BUF_INIT;
+	git_cherrypick_options opts = GIT_CHERRYPICK_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "19c5c7207054604b69c84d08a7571ef9672bb5c2", 0, "file1.txt" },
+		{ 0100644, "a58ca3fee5eb68b11adc2703e5843f968c9dad1e", 0, "file2.txt" },
+		{ 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 1, "file3.txt" },
+		{ 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 3, "file3.txt.renamed" },
+		{ 0100644, "28d9eb4208074ad1cc84e71ccc908b34573f05d2", 2, "file3.txt.renamed_on_branch" },
+	};
+
+	opts.merge_opts.tree_flags |= GIT_MERGE_TREE_FIND_RENAMES;
+	opts.merge_opts.rename_threshold = 50;
+
+	git_oid_fromstr(&head_oid, "44cd2ed2052c9c68f9a439d208e9614dc2a55c70");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	git_oid_fromstr(&cherry_oid, "2a26c7e88b285613b302ba76712bc998863f3cbc");
+	cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+	cl_git_pass(git_cherrypick(repo, commit, &opts));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 5));
+
+	cl_git_pass(git_futils_readbuffer(&mergemsg_buf,
+		TEST_REPO_PATH "/.git/MERGE_MSG"));
+	cl_assert(strcmp(git_buf_cstr(&mergemsg_buf),
+		"Renamed file3.txt -> file3.txt.renamed\n" \
+		"\n" \
+		"Conflicts:\n" \
+		"\tfile3.txt\n" \
+		"\tfile3.txt.renamed\n" \
+		"\tfile3.txt.renamed_on_branch\n") == 0);
+
+	git_buf_free(&mergemsg_buf);
+	git_commit_free(commit);
+	git_commit_free(head);
+}
+
+void test_cherrypick_workdir__nonmerge_fails_mainline_specified(void)
+{
+	git_reference *head;
+	git_commit *commit;
+	git_cherrypick_options opts = GIT_CHERRYPICK_OPTIONS_INIT;
+
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_peel((git_object **)&commit, head, GIT_OBJ_COMMIT));
+
+	opts.mainline = 1;
+	cl_must_fail(git_cherrypick(repo, commit, &opts));
+	cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
+	cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
+
+	git_reference_free(head);
+	git_commit_free(commit);
+}
+
+/* git reset --hard cfc4f0999a8367568e049af4f72e452d40828a15
+ * git cherry-pick abe4603bc7cd5b8167a267e0e2418fd2348f8cff
+ */
+void test_cherrypick_workdir__merge_fails_without_mainline_specified(void)
+{
+	git_commit *head, *commit;
+	git_oid head_oid, cherry_oid;
+
+	git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	git_oid_fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff");
+	cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+
+	cl_must_fail(git_cherrypick(repo, commit, NULL));
+	cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
+	cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
+
+	git_commit_free(commit);
+	git_commit_free(head);
+}
+
+/* git reset --hard cfc4f0999a8367568e049af4f72e452d40828a15
+ * git cherry-pick -m1 abe4603bc7cd5b8167a267e0e2418fd2348f8cff
+ */
+void test_cherrypick_workdir__merge_first_parent(void)
+{
+	git_commit *head, *commit;
+	git_oid head_oid, cherry_oid;
+	git_cherrypick_options opts = GIT_CHERRYPICK_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "f90f9dcbdac2cce5cc166346160e19cb693ef4e8", 0, "file1.txt" },
+		{ 0100644, "563f6473a3858f99b80e5f93c660512ed38e1e6f", 0, "file2.txt" },
+		{ 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 0, "file3.txt" },
+	};
+
+	opts.mainline = 1;
+
+	git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	git_oid_fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff");
+	cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+
+	cl_git_pass(git_cherrypick(repo, commit, &opts));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 3));
+
+	git_commit_free(commit);
+	git_commit_free(head);
+}
+
+/* git reset --hard cfc4f0999a8367568e049af4f72e452d40828a15
+ * git cherry-pick -m2 abe4603bc7cd5b8167a267e0e2418fd2348f8cff
+ */
+void test_cherrypick_workdir__merge_second_parent(void)
+{
+	git_commit *head, *commit;
+	git_oid head_oid, cherry_oid;
+	git_cherrypick_options opts = GIT_CHERRYPICK_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "487434cace79238a7091e2220611d4f20a765690", 0, "file1.txt" },
+		{ 0100644, "e5183bfd18e3a0a691fadde2f0d5610b73282d31", 0, "file2.txt" },
+		{ 0100644, "409a1bec58bf35348e8b62b72bb9c1f45cf5a587", 0, "file3.txt" },
+	};
+
+	opts.mainline = 2;
+
+	git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	git_oid_fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff");
+	cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+
+	cl_git_pass(git_cherrypick(repo, commit, &opts));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 3));
+
+	git_commit_free(commit);
+	git_commit_free(head);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar.c
new file mode 100755
index 0000000..2caa871
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar.c
@@ -0,0 +1,642 @@
+/*
+ * Copyright (c) Vicent Marti. All rights reserved.
+ *
+ * This file is part of clar, distributed under the ISC license.
+ * For full terms see the included COPYING file.
+ */
+#include <assert.h>
+#include <setjmp.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <stdarg.h>
+#include <wchar.h>
+
+/* required for sandboxing */
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+#	include <windows.h>
+#	include <io.h>
+#	include <shellapi.h>
+#	include <direct.h>
+
+#	define _MAIN_CC __cdecl
+
+#	ifndef stat
+#		define stat(path, st) _stat(path, st)
+#	endif
+#	ifndef mkdir
+#		define mkdir(path, mode) _mkdir(path)
+#	endif
+#	ifndef chdir
+#		define chdir(path) _chdir(path)
+#	endif
+#	ifndef access
+#		define access(path, mode) _access(path, mode)
+#	endif
+#	ifndef strdup
+#		define strdup(str) _strdup(str)
+#	endif
+#	ifndef strcasecmp
+#		define strcasecmp(a,b) _stricmp(a,b)
+#	endif
+
+#	ifndef __MINGW32__
+#		pragma comment(lib, "shell32")
+#		ifndef strncpy
+#			define strncpy(to, from, to_size) strncpy_s(to, to_size, from, _TRUNCATE)
+#		endif
+#		ifndef W_OK
+#			define W_OK 02
+#		endif
+#		ifndef S_ISDIR
+#			define S_ISDIR(x) ((x & _S_IFDIR) != 0)
+#		endif
+#		define p_snprintf(buf,sz,fmt,...) _snprintf_s(buf,sz,_TRUNCATE,fmt,__VA_ARGS__)
+#	else
+#		define p_snprintf snprintf
+#	endif
+
+#	ifndef PRIuZ
+#		define PRIuZ "Iu"
+#	endif
+#	ifndef PRIxZ
+#		define PRIxZ "Ix"
+#	endif
+
+#	ifdef _MSC_VER
+	typedef struct stat STAT_T;
+#	else
+	typedef struct _stat STAT_T;
+#	endif
+#else
+#	include <sys/wait.h> /* waitpid(2) */
+#	include <unistd.h>
+#	define _MAIN_CC
+#	define p_snprintf snprintf
+#	ifndef PRIuZ
+#		define PRIuZ "zu"
+#	endif
+#	ifndef PRIxZ
+#		define PRIxZ "zx"
+#	endif
+	typedef struct stat STAT_T;
+#endif
+
+#include "clar.h"
+
+static void fs_rm(const char *_source);
+static void fs_copy(const char *_source, const char *dest);
+
+static const char *
+fixture_path(const char *base, const char *fixture_name);
+
+struct clar_error {
+	const char *test;
+	int test_number;
+	const char *suite;
+	const char *file;
+	int line_number;
+	const char *error_msg;
+	char *description;
+
+	struct clar_error *next;
+};
+
+static struct {
+	int argc;
+	char **argv;
+
+	enum cl_test_status test_status;
+	const char *active_test;
+	const char *active_suite;
+
+	int total_skipped;
+	int total_errors;
+
+	int tests_ran;
+	int suites_ran;
+
+	int report_errors_only;
+	int exit_on_error;
+	int report_suite_names;
+
+	struct clar_error *errors;
+	struct clar_error *last_error;
+
+	void (*local_cleanup)(void *);
+	void *local_cleanup_payload;
+
+	jmp_buf trampoline;
+	int trampoline_enabled;
+
+	cl_trace_cb *pfn_trace_cb;
+	void *trace_payload;
+
+} _clar;
+
+struct clar_func {
+	const char *name;
+	void (*ptr)(void);
+};
+
+struct clar_suite {
+	const char *name;
+	struct clar_func initialize;
+	struct clar_func cleanup;
+	const struct clar_func *tests;
+	size_t test_count;
+	int enabled;
+};
+
+/* From clar_print_*.c */
+static void clar_print_init(int test_count, int suite_count, const char *suite_names);
+static void clar_print_shutdown(int test_count, int suite_count, int error_count);
+static void clar_print_error(int num, const struct clar_error *error);
+static void clar_print_ontest(const char *test_name, int test_number, enum cl_test_status failed);
+static void clar_print_onsuite(const char *suite_name, int suite_index);
+static void clar_print_onabort(const char *msg, ...);
+
+/* From clar_sandbox.c */
+static void clar_unsandbox(void);
+static int clar_sandbox(void);
+
+/* Load the declarations for the test suite */
+#include "clar.suite"
+
+
+#define CL_TRACE(ev)													\
+	do {																\
+		if (_clar.pfn_trace_cb)											\
+			_clar.pfn_trace_cb(ev,										\
+							   _clar.active_suite,						\
+							   _clar.active_test,						\
+							   _clar.trace_payload);					\
+	} while (0)
+
+void cl_trace_register(cl_trace_cb *cb, void *payload)
+{
+	_clar.pfn_trace_cb = cb;
+	_clar.trace_payload = payload;
+}
+
+
+/* Core test functions */
+static void
+clar_report_errors(void)
+{
+	int i = 1;
+	struct clar_error *error, *next;
+
+	error = _clar.errors;
+	while (error != NULL) {
+		next = error->next;
+		clar_print_error(i++, error);
+		free(error->description);
+		free(error);
+		error = next;
+	}
+
+	_clar.errors = _clar.last_error = NULL;
+}
+
+static void
+clar_run_test(
+	const struct clar_func *test,
+	const struct clar_func *initialize,
+	const struct clar_func *cleanup)
+{
+	_clar.test_status = CL_TEST_OK;
+	_clar.trampoline_enabled = 1;
+
+	CL_TRACE(CL_TRACE__TEST__BEGIN);
+
+	if (setjmp(_clar.trampoline) == 0) {
+		if (initialize->ptr != NULL)
+			initialize->ptr();
+
+		CL_TRACE(CL_TRACE__TEST__RUN_BEGIN);
+		test->ptr();
+		CL_TRACE(CL_TRACE__TEST__RUN_END);
+	}
+
+	_clar.trampoline_enabled = 0;
+
+	if (_clar.local_cleanup != NULL)
+		_clar.local_cleanup(_clar.local_cleanup_payload);
+
+	if (cleanup->ptr != NULL)
+		cleanup->ptr();
+
+	CL_TRACE(CL_TRACE__TEST__END);
+
+	_clar.tests_ran++;
+
+	/* remove any local-set cleanup methods */
+	_clar.local_cleanup = NULL;
+	_clar.local_cleanup_payload = NULL;
+
+	if (_clar.report_errors_only) {
+		clar_report_errors();
+	} else {
+		clar_print_ontest(test->name, _clar.tests_ran, _clar.test_status);
+	}
+}
+
+static void
+clar_run_suite(const struct clar_suite *suite, const char *filter)
+{
+	const struct clar_func *test = suite->tests;
+	size_t i, matchlen;
+
+	if (!suite->enabled)
+		return;
+
+	if (_clar.exit_on_error && _clar.total_errors)
+		return;
+
+	if (!_clar.report_errors_only)
+		clar_print_onsuite(suite->name, ++_clar.suites_ran);
+
+	_clar.active_suite = suite->name;
+	_clar.active_test = NULL;
+	CL_TRACE(CL_TRACE__SUITE_BEGIN);
+
+	if (filter) {
+		size_t suitelen = strlen(suite->name);
+		matchlen = strlen(filter);
+		if (matchlen <= suitelen) {
+			filter = NULL;
+		} else {
+			filter += suitelen;
+			while (*filter == ':')
+				++filter;
+			matchlen = strlen(filter);
+		}
+	}
+
+	for (i = 0; i < suite->test_count; ++i) {
+		if (filter && strncmp(test[i].name, filter, matchlen))
+			continue;
+
+		_clar.active_test = test[i].name;
+		clar_run_test(&test[i], &suite->initialize, &suite->cleanup);
+
+		if (_clar.exit_on_error && _clar.total_errors)
+			return;
+	}
+
+	_clar.active_test = NULL;
+	CL_TRACE(CL_TRACE__SUITE_END);
+}
+
+static void
+clar_usage(const char *arg)
+{
+	printf("Usage: %s [options]\n\n", arg);
+	printf("Options:\n");
+	printf("  -sname\tRun only the suite with `name` (can go to individual test name)\n");
+	printf("  -iname\tInclude the suite with `name`\n");
+	printf("  -xname\tExclude the suite with `name`\n");
+	printf("  -v    \tIncrease verbosity (show suite names)\n");
+	printf("  -q    \tOnly report tests that had an error\n");
+	printf("  -Q    \tQuit as soon as a test fails\n");
+	printf("  -l    \tPrint suite names\n");
+	exit(-1);
+}
+
+static void
+clar_parse_args(int argc, char **argv)
+{
+	int i;
+
+	for (i = 1; i < argc; ++i) {
+		char *argument = argv[i];
+
+		if (argument[0] != '-')
+			clar_usage(argv[0]);
+
+		switch (argument[1]) {
+		case 's':
+		case 'i':
+		case 'x': { /* given suite name */
+			int offset = (argument[2] == '=') ? 3 : 2, found = 0;
+			char action = argument[1];
+			size_t j, arglen, suitelen, cmplen;
+
+			argument += offset;
+			arglen = strlen(argument);
+
+			if (arglen == 0)
+				clar_usage(argv[0]);
+
+			for (j = 0; j < _clar_suite_count; ++j) {
+				suitelen = strlen(_clar_suites[j].name);
+				cmplen = (arglen < suitelen) ? arglen : suitelen;
+
+				if (strncmp(argument, _clar_suites[j].name, cmplen) == 0) {
+					int exact = (arglen >= suitelen);
+
+					++found;
+
+					if (!exact)
+						_clar.report_suite_names = 1;
+
+					switch (action) {
+					case 's': _clar_suites[j].enabled = 1; clar_run_suite(&_clar_suites[j], argument); break;
+					case 'i': _clar_suites[j].enabled = 1; break;
+					case 'x': _clar_suites[j].enabled = 0; break;
+					}
+
+					if (exact)
+						break;
+				}
+			}
+
+			if (!found) {
+				clar_print_onabort("No suite matching '%s' found.\n", argument);
+				exit(-1);
+			}
+			break;
+		}
+
+		case 'q':
+			_clar.report_errors_only = 1;
+			break;
+
+		case 'Q':
+			_clar.exit_on_error = 1;
+			break;
+
+		case 'l': {
+			size_t j;
+			printf("Test suites (use -s<name> to run just one):\n");
+			for (j = 0; j < _clar_suite_count; ++j)
+				printf(" %3d: %s\n", (int)j, _clar_suites[j].name);
+
+			exit(0);
+		}
+
+		case 'v':
+			_clar.report_suite_names = 1;
+			break;
+
+		default:
+			clar_usage(argv[0]);
+		}
+	}
+}
+
+void
+clar_test_init(int argc, char **argv)
+{
+	clar_print_init(
+		(int)_clar_callback_count,
+		(int)_clar_suite_count,
+		""
+	);
+
+	if (clar_sandbox() < 0) {
+		clar_print_onabort("Failed to sandbox the test runner.\n");
+		exit(-1);
+	}
+
+	_clar.argc = argc;
+	_clar.argv = argv;
+}
+
+int
+clar_test_run()
+{
+	if (_clar.argc > 1)
+		clar_parse_args(_clar.argc, _clar.argv);
+
+	if (!_clar.suites_ran) {
+		size_t i;
+		for (i = 0; i < _clar_suite_count; ++i)
+			clar_run_suite(&_clar_suites[i], NULL);
+	}
+
+	return _clar.total_errors;
+}
+
+void
+clar_test_shutdown()
+{
+	clar_print_shutdown(
+		_clar.tests_ran,
+		(int)_clar_suite_count,
+		_clar.total_errors
+	);
+
+	clar_unsandbox();
+}
+
+int
+clar_test(int argc, char **argv)
+{
+	int errors;
+
+	clar_test_init(argc, argv);
+	errors = clar_test_run();
+	clar_test_shutdown();
+
+	return errors;
+}
+
+static void abort_test(void)
+{
+	if (!_clar.trampoline_enabled) {
+		clar_print_onabort(
+				"Fatal error: a cleanup method raised an exception.");
+		clar_report_errors();
+		exit(-1);
+	}
+
+	CL_TRACE(CL_TRACE__TEST__LONGJMP);
+	longjmp(_clar.trampoline, -1);
+}
+
+void clar__skip(void)
+{
+	_clar.test_status = CL_TEST_SKIP;
+	_clar.total_skipped++;
+	abort_test();
+}
+
+void clar__fail(
+	const char *file,
+	int line,
+	const char *error_msg,
+	const char *description,
+	int should_abort)
+{
+	struct clar_error *error = calloc(1, sizeof(struct clar_error));
+
+	if (_clar.errors == NULL)
+		_clar.errors = error;
+
+	if (_clar.last_error != NULL)
+		_clar.last_error->next = error;
+
+	_clar.last_error = error;
+
+	error->test = _clar.active_test;
+	error->test_number = _clar.tests_ran;
+	error->suite = _clar.active_suite;
+	error->file = file;
+	error->line_number = line;
+	error->error_msg = error_msg;
+
+	if (description != NULL)
+		error->description = strdup(description);
+
+	_clar.total_errors++;
+	_clar.test_status = CL_TEST_FAILURE;
+
+	if (should_abort)
+		abort_test();
+}
+
+void clar__assert(
+	int condition,
+	const char *file,
+	int line,
+	const char *error_msg,
+	const char *description,
+	int should_abort)
+{
+	if (condition)
+		return;
+
+	clar__fail(file, line, error_msg, description, should_abort);
+}
+
+void clar__assert_equal(
+	const char *file,
+	int line,
+	const char *err,
+	int should_abort,
+	const char *fmt,
+	...)
+{
+	va_list args;
+	char buf[4096];
+	int is_equal = 1;
+
+	va_start(args, fmt);
+
+	if (!strcmp("%s", fmt)) {
+		const char *s1 = va_arg(args, const char *);
+		const char *s2 = va_arg(args, const char *);
+		is_equal = (!s1 || !s2) ? (s1 == s2) : !strcmp(s1, s2);
+
+		if (!is_equal) {
+			if (s1 && s2) {
+				int pos;
+				for (pos = 0; s1[pos] == s2[pos] && s1[pos] && s2[pos]; ++pos)
+					/* find differing byte offset */;
+				p_snprintf(buf, sizeof(buf), "'%s' != '%s' (at byte %d)",
+					s1, s2, pos);
+			} else {
+				p_snprintf(buf, sizeof(buf), "'%s' != '%s'", s1, s2);
+			}
+		}
+	}
+	else if(!strcmp("%.*s", fmt)) {
+		const char *s1 = va_arg(args, const char *);
+		const char *s2 = va_arg(args, const char *);
+		int len = va_arg(args, int);
+		is_equal = (!s1 || !s2) ? (s1 == s2) : !strncmp(s1, s2, len);
+
+		if (!is_equal) {
+			if (s1 && s2) {
+				int pos;
+				for (pos = 0; s1[pos] == s2[pos] && pos < len; ++pos)
+					/* find differing byte offset */;
+				p_snprintf(buf, sizeof(buf), "'%.*s' != '%.*s' (at byte %d)",
+					len, s1, len, s2, pos);
+			} else {
+				p_snprintf(buf, sizeof(buf), "'%.*s' != '%.*s'", len, s1, len, s2);
+			}
+		}
+	}
+	else if (!strcmp("%ls", fmt)) {
+		const wchar_t *wcs1 = va_arg(args, const wchar_t *);
+		const wchar_t *wcs2 = va_arg(args, const wchar_t *);
+		is_equal = (!wcs1 || !wcs2) ? (wcs1 == wcs2) : !wcscmp(wcs1, wcs2);
+
+		if (!is_equal) {
+			if (wcs1 && wcs2) {
+				int pos;
+				for (pos = 0; wcs1[pos] == wcs2[pos] && wcs1[pos] && wcs2[pos]; ++pos)
+					/* find differing byte offset */;
+				p_snprintf(buf, sizeof(buf), "'%ls' != '%ls' (at byte %d)",
+					wcs1, wcs2, pos);
+			} else {
+				p_snprintf(buf, sizeof(buf), "'%ls' != '%ls'", wcs1, wcs2);
+			}
+		}
+	}
+	else if(!strcmp("%.*ls", fmt)) {
+		const wchar_t *wcs1 = va_arg(args, const wchar_t *);
+		const wchar_t *wcs2 = va_arg(args, const wchar_t *);
+		int len = va_arg(args, int);
+		is_equal = (!wcs1 || !wcs2) ? (wcs1 == wcs2) : !wcsncmp(wcs1, wcs2, len);
+
+		if (!is_equal) {
+			if (wcs1 && wcs2) {
+				int pos;
+				for (pos = 0; wcs1[pos] == wcs2[pos] && pos < len; ++pos)
+					/* find differing byte offset */;
+				p_snprintf(buf, sizeof(buf), "'%.*ls' != '%.*ls' (at byte %d)",
+					len, wcs1, len, wcs2, pos);
+			} else {
+				p_snprintf(buf, sizeof(buf), "'%.*ls' != '%.*ls'", len, wcs1, len, wcs2);
+			}
+		}
+	}
+	else if (!strcmp("%"PRIuZ, fmt) || !strcmp("%"PRIxZ, fmt)) {
+		size_t sz1 = va_arg(args, size_t), sz2 = va_arg(args, size_t);
+		is_equal = (sz1 == sz2);
+		if (!is_equal) {
+			int offset = p_snprintf(buf, sizeof(buf), fmt, sz1);
+			strncat(buf, " != ", sizeof(buf) - offset);
+			p_snprintf(buf + offset + 4, sizeof(buf) - offset - 4, fmt, sz2);
+		}
+	}
+	else if (!strcmp("%p", fmt)) {
+		void *p1 = va_arg(args, void *), *p2 = va_arg(args, void *);
+		is_equal = (p1 == p2);
+		if (!is_equal)
+			p_snprintf(buf, sizeof(buf), "%p != %p", p1, p2);
+	}
+	else {
+		int i1 = va_arg(args, int), i2 = va_arg(args, int);
+		is_equal = (i1 == i2);
+		if (!is_equal) {
+			int offset = p_snprintf(buf, sizeof(buf), fmt, i1);
+			strncat(buf, " != ", sizeof(buf) - offset);
+			p_snprintf(buf + offset + 4, sizeof(buf) - offset - 4, fmt, i2);
+		}
+	}
+
+	va_end(args);
+
+	if (!is_equal)
+		clar__fail(file, line, err, buf, should_abort);
+}
+
+void cl_set_cleanup(void (*cleanup)(void *), void *opaque)
+{
+	_clar.local_cleanup = cleanup;
+	_clar.local_cleanup_payload = opaque;
+}
+
+#include "clar/sandbox.h"
+#include "clar/fixtures.h"
+#include "clar/fs.h"
+#include "clar/print.h"
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar.h
new file mode 100755
index 0000000..5c674d7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) Vicent Marti. All rights reserved.
+ *
+ * This file is part of clar, distributed under the ISC license.
+ * For full terms see the included COPYING file.
+ */
+#ifndef __CLAR_TEST_H__
+#define __CLAR_TEST_H__
+
+#include <stdlib.h>
+
+enum cl_test_status {
+	CL_TEST_OK,
+	CL_TEST_FAILURE,
+	CL_TEST_SKIP
+};
+
+void clar_test_init(int argc, char *argv[]);
+int clar_test_run(void);
+void clar_test_shutdown(void);
+
+int clar_test(int argc, char *argv[]);
+
+const char *clar_sandbox_path(void);
+
+void cl_set_cleanup(void (*cleanup)(void *), void *opaque);
+void cl_fs_cleanup(void);
+
+/**
+ * cl_trace_* is a hook to provide a simple global tracing
+ * mechanism.
+ *
+ * The goal here is to let main() provide clar-proper
+ * with a callback to optionally write log info for
+ * test operations into the same stream used by their
+ * actual tests.  This would let them print test names
+ * and maybe performance data as they choose.
+ *
+ * The goal is NOT to alter the flow of control or to
+ * override test selection/skipping.  (So the callback
+ * does not return a value.)
+ *
+ * The goal is NOT to duplicate the existing
+ * pass/fail/skip reporting.  (So the callback
+ * does not accept a status/errorcode argument.)
+ *
+ */
+typedef enum cl_trace_event {
+	CL_TRACE__SUITE_BEGIN,
+	CL_TRACE__SUITE_END,
+	CL_TRACE__TEST__BEGIN,
+	CL_TRACE__TEST__END,
+	CL_TRACE__TEST__RUN_BEGIN,
+	CL_TRACE__TEST__RUN_END,
+	CL_TRACE__TEST__LONGJMP,
+} cl_trace_event;
+
+typedef void (cl_trace_cb)(
+	cl_trace_event ev,
+	const char *suite_name,
+	const char *test_name,
+	void *payload);
+
+/**
+ * Register a callback into CLAR to send global trace events.
+ * Pass NULL to disable.
+ */
+void cl_trace_register(cl_trace_cb *cb, void *payload);
+
+
+#ifdef CLAR_FIXTURE_PATH
+const char *cl_fixture(const char *fixture_name);
+void cl_fixture_sandbox(const char *fixture_name);
+void cl_fixture_cleanup(const char *fixture_name);
+#endif
+
+/**
+ * Assertion macros with explicit error message
+ */
+#define cl_must_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __LINE__, "Function call failed: " #expr, desc, 1)
+#define cl_must_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __LINE__, "Expected function call to fail: " #expr, desc, 1)
+#define cl_assert_(expr, desc) clar__assert((expr) != 0, __FILE__, __LINE__, "Expression is not true: " #expr, desc, 1)
+
+/**
+ * Check macros with explicit error message
+ */
+#define cl_check_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __LINE__, "Function call failed: " #expr, desc, 0)
+#define cl_check_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __LINE__, "Expected function call to fail: " #expr, desc, 0)
+#define cl_check_(expr, desc) clar__assert((expr) != 0, __FILE__, __LINE__, "Expression is not true: " #expr, desc, 0)
+
+/**
+ * Assertion macros with no error message
+ */
+#define cl_must_pass(expr) cl_must_pass_(expr, NULL)
+#define cl_must_fail(expr) cl_must_fail_(expr, NULL)
+#define cl_assert(expr) cl_assert_(expr, NULL)
+
+/**
+ * Check macros with no error message
+ */
+#define cl_check_pass(expr) cl_check_pass_(expr, NULL)
+#define cl_check_fail(expr) cl_check_fail_(expr, NULL)
+#define cl_check(expr) cl_check_(expr, NULL)
+
+/**
+ * Forced failure/warning
+ */
+#define cl_fail(desc) clar__fail(__FILE__, __LINE__, "Test failed.", desc, 1)
+#define cl_warning(desc) clar__fail(__FILE__, __LINE__, "Warning during test execution:", desc, 0)
+
+#define cl_skip() clar__skip()
+
+/**
+ * Typed assertion macros
+ */
+#define cl_assert_equal_s(s1,s2) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #s1 " != " #s2, 1, "%s", (s1), (s2))
+#define cl_assert_equal_s_(s1,s2,note) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #s1 " != " #s2 " (" #note ")", 1, "%s", (s1), (s2))
+
+#define cl_assert_equal_wcs(wcs1,wcs2) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2, 1, "%ls", (wcs1), (wcs2))
+#define cl_assert_equal_wcs_(wcs1,wcs2,note) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%ls", (wcs1), (wcs2))
+
+#define cl_assert_equal_strn(s1,s2,len) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #s1 " != " #s2, 1, "%.*s", (s1), (s2), (int)(len))
+#define cl_assert_equal_strn_(s1,s2,len,note) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #s1 " != " #s2 " (" #note ")", 1, "%.*s", (s1), (s2), (int)(len))
+
+#define cl_assert_equal_wcsn(wcs1,wcs2,len) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2, 1, "%.*ls", (wcs1), (wcs2), (int)(len))
+#define cl_assert_equal_wcsn_(wcs1,wcs2,len,note) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%.*ls", (wcs1), (wcs2), (int)(len))
+
+#define cl_assert_equal_i(i1,i2) clar__assert_equal(__FILE__,__LINE__,#i1 " != " #i2, 1, "%d", (int)(i1), (int)(i2))
+#define cl_assert_equal_i_(i1,i2,note) clar__assert_equal(__FILE__,__LINE__,#i1 " != " #i2 " (" #note ")", 1, "%d", (i1), (i2))
+#define cl_assert_equal_i_fmt(i1,i2,fmt) clar__assert_equal(__FILE__,__LINE__,#i1 " != " #i2, 1, (fmt), (int)(i1), (int)(i2))
+
+#define cl_assert_equal_b(b1,b2) clar__assert_equal(__FILE__,__LINE__,#b1 " != " #b2, 1, "%d", (int)((b1) != 0),(int)((b2) != 0))
+
+#define cl_assert_equal_p(p1,p2) clar__assert_equal(__FILE__,__LINE__,"Pointer mismatch: " #p1 " != " #p2, 1, "%p", (p1), (p2))
+
+void clar__skip(void);
+
+void clar__fail(
+	const char *file,
+	int line,
+	const char *error,
+	const char *description,
+	int should_abort);
+
+void clar__assert(
+	int condition,
+	const char *file,
+	int line,
+	const char *error,
+	const char *description,
+	int should_abort);
+
+void clar__assert_equal(
+	const char *file,
+	int line,
+	const char *err,
+	int should_abort,
+	const char *fmt,
+	...);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar/fixtures.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar/fixtures.h
new file mode 100755
index 0000000..f7b8d96
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar/fixtures.h
@@ -0,0 +1,51 @@
+static const char *
+fixture_path(const char *base, const char *fixture_name)
+{
+	static char _path[4096];
+	size_t root_len;
+
+	root_len = strlen(base);
+	strncpy(_path, base, sizeof(_path));
+
+	if (_path[root_len - 1] != '/')
+		_path[root_len++] = '/';
+
+	if (fixture_name[0] == '/')
+		fixture_name++;
+
+	strncpy(_path + root_len,
+		fixture_name,
+		sizeof(_path) - root_len);
+
+	return _path;
+}
+
+static const char *
+fixture_basename(const char *fixture_name)
+{
+	const char *p;
+
+	for (p = fixture_name; *p; p++) {
+		if (p[0] == '/' && p[1] && p[1] != '/')
+			fixture_name = p+1;
+	}
+
+	return fixture_name;
+}
+
+#ifdef CLAR_FIXTURE_PATH
+const char *cl_fixture(const char *fixture_name)
+{
+	return fixture_path(CLAR_FIXTURE_PATH, fixture_name);
+}
+
+void cl_fixture_sandbox(const char *fixture_name)
+{
+	fs_copy(cl_fixture(fixture_name), _clar_path);
+}
+
+void cl_fixture_cleanup(const char *fixture_name)
+{
+	fs_rm(fixture_path(_clar_path, fixture_basename(fixture_name)));
+}
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar/fs.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar/fs.h
new file mode 100755
index 0000000..7c7dde6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar/fs.h
@@ -0,0 +1,333 @@
+#ifdef _WIN32
+
+#define RM_RETRY_COUNT	5
+#define RM_RETRY_DELAY	10
+
+#ifdef __MINGW32__
+
+/* These security-enhanced functions are not available
+ * in MinGW, so just use the vanilla ones */
+#define wcscpy_s(a, b, c) wcscpy((a), (c))
+#define wcscat_s(a, b, c) wcscat((a), (c))
+
+#endif /* __MINGW32__ */
+
+static int
+fs__dotordotdot(WCHAR *_tocheck)
+{
+	return _tocheck[0] == '.' &&
+		(_tocheck[1] == '\0' ||
+		 (_tocheck[1] == '.' && _tocheck[2] == '\0'));
+}
+
+static int
+fs_rmdir_rmdir(WCHAR *_wpath)
+{
+	unsigned retries = 1;
+
+	while (!RemoveDirectoryW(_wpath)) {
+		/* Only retry when we have retries remaining, and the
+		 * error was ERROR_DIR_NOT_EMPTY. */
+		if (retries++ > RM_RETRY_COUNT ||
+			ERROR_DIR_NOT_EMPTY != GetLastError())
+			return -1;
+
+		/* Give whatever has a handle to a child item some time
+		 * to release it before trying again */
+		Sleep(RM_RETRY_DELAY * retries * retries);
+	}
+
+	return 0;
+}
+
+static void
+fs_rmdir_helper(WCHAR *_wsource)
+{
+	WCHAR buffer[MAX_PATH];
+	HANDLE find_handle;
+	WIN32_FIND_DATAW find_data;
+	size_t buffer_prefix_len;
+
+	/* Set up the buffer and capture the length */
+	wcscpy_s(buffer, MAX_PATH, _wsource);
+	wcscat_s(buffer, MAX_PATH, L"\\");
+	buffer_prefix_len = wcslen(buffer);
+
+	/* FindFirstFile needs a wildcard to match multiple items */
+	wcscat_s(buffer, MAX_PATH, L"*");
+	find_handle = FindFirstFileW(buffer, &find_data);
+	cl_assert(INVALID_HANDLE_VALUE != find_handle);
+
+	do {
+		/* FindFirstFile/FindNextFile gives back . and ..
+		 * entries at the beginning */
+		if (fs__dotordotdot(find_data.cFileName))
+			continue;
+
+		wcscpy_s(buffer + buffer_prefix_len, MAX_PATH - buffer_prefix_len, find_data.cFileName);
+
+		if (FILE_ATTRIBUTE_DIRECTORY & find_data.dwFileAttributes)
+			fs_rmdir_helper(buffer);
+		else {
+			/* If set, the +R bit must be cleared before deleting */
+			if (FILE_ATTRIBUTE_READONLY & find_data.dwFileAttributes)
+				cl_assert(SetFileAttributesW(buffer, find_data.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY));
+
+			cl_assert(DeleteFileW(buffer));
+		}
+	}
+	while (FindNextFileW(find_handle, &find_data));
+
+	/* Ensure that we successfully completed the enumeration */
+	cl_assert(ERROR_NO_MORE_FILES == GetLastError());
+
+	/* Close the find handle */
+	FindClose(find_handle);
+
+	/* Now that the directory is empty, remove it */
+	cl_assert(0 == fs_rmdir_rmdir(_wsource));
+}
+
+static int
+fs_rm_wait(WCHAR *_wpath)
+{
+	unsigned retries = 1;
+	DWORD last_error;
+
+	do {
+		if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(_wpath))
+			last_error = GetLastError();
+		else
+			last_error = ERROR_SUCCESS;
+
+		/* Is the item gone? */
+		if (ERROR_FILE_NOT_FOUND == last_error ||
+			ERROR_PATH_NOT_FOUND == last_error)
+			return 0;
+
+		Sleep(RM_RETRY_DELAY * retries * retries);	
+	}
+	while (retries++ <= RM_RETRY_COUNT);
+
+	return -1;
+}
+
+static void
+fs_rm(const char *_source)
+{
+	WCHAR wsource[MAX_PATH];
+	DWORD attrs;
+
+	/* The input path is UTF-8. Convert it to wide characters
+	 * for use with the Windows API */
+	cl_assert(MultiByteToWideChar(CP_UTF8,
+				MB_ERR_INVALID_CHARS,
+				_source,
+				-1, /* Indicates NULL termination */
+				wsource,
+				MAX_PATH));
+
+	/* Does the item exist? If not, we have no work to do */
+	attrs = GetFileAttributesW(wsource);
+
+	if (INVALID_FILE_ATTRIBUTES == attrs)
+		return;
+
+	if (FILE_ATTRIBUTE_DIRECTORY & attrs)
+		fs_rmdir_helper(wsource);
+	else {
+		/* The item is a file. Strip the +R bit */
+		if (FILE_ATTRIBUTE_READONLY & attrs)
+			cl_assert(SetFileAttributesW(wsource, attrs & ~FILE_ATTRIBUTE_READONLY));
+
+		cl_assert(DeleteFileW(wsource));
+	}
+
+	/* Wait for the DeleteFile or RemoveDirectory call to complete */
+	cl_assert(0 == fs_rm_wait(wsource));
+}
+
+static void
+fs_copydir_helper(WCHAR *_wsource, WCHAR *_wdest)
+{
+	WCHAR buf_source[MAX_PATH], buf_dest[MAX_PATH];
+	HANDLE find_handle;
+	WIN32_FIND_DATAW find_data;
+	size_t buf_source_prefix_len, buf_dest_prefix_len;
+
+	wcscpy_s(buf_source, MAX_PATH, _wsource);
+	wcscat_s(buf_source, MAX_PATH, L"\\");
+	buf_source_prefix_len = wcslen(buf_source);
+
+	wcscpy_s(buf_dest, MAX_PATH, _wdest);
+	wcscat_s(buf_dest, MAX_PATH, L"\\");
+	buf_dest_prefix_len = wcslen(buf_dest);
+
+	/* Get an enumerator for the items in the source. */
+	wcscat_s(buf_source, MAX_PATH, L"*");
+	find_handle = FindFirstFileW(buf_source, &find_data);
+	cl_assert(INVALID_HANDLE_VALUE != find_handle);
+
+	/* Create the target directory. */
+	cl_assert(CreateDirectoryW(_wdest, NULL));
+
+	do {
+		/* FindFirstFile/FindNextFile gives back . and ..
+		 * entries at the beginning */
+		if (fs__dotordotdot(find_data.cFileName))
+			continue;
+
+		wcscpy_s(buf_source + buf_source_prefix_len, MAX_PATH - buf_source_prefix_len, find_data.cFileName);
+		wcscpy_s(buf_dest + buf_dest_prefix_len, MAX_PATH - buf_dest_prefix_len, find_data.cFileName);
+
+		if (FILE_ATTRIBUTE_DIRECTORY & find_data.dwFileAttributes)
+			fs_copydir_helper(buf_source, buf_dest);
+		else
+			cl_assert(CopyFileW(buf_source, buf_dest, TRUE));
+	}
+	while (FindNextFileW(find_handle, &find_data));
+
+	/* Ensure that we successfully completed the enumeration */
+	cl_assert(ERROR_NO_MORE_FILES == GetLastError());
+
+	/* Close the find handle */
+	FindClose(find_handle);
+}
+
+static void
+fs_copy(const char *_source, const char *_dest)
+{
+	WCHAR wsource[MAX_PATH], wdest[MAX_PATH];
+	DWORD source_attrs, dest_attrs;
+	HANDLE find_handle;
+	WIN32_FIND_DATAW find_data;
+
+	/* The input paths are UTF-8. Convert them to wide characters
+	 * for use with the Windows API. */
+	cl_assert(MultiByteToWideChar(CP_UTF8,
+				MB_ERR_INVALID_CHARS,
+				_source,
+				-1,
+				wsource,
+				MAX_PATH));
+
+	cl_assert(MultiByteToWideChar(CP_UTF8,
+				MB_ERR_INVALID_CHARS,
+				_dest,
+				-1,
+				wdest,
+				MAX_PATH));
+
+	/* Check the source for existence */
+	source_attrs = GetFileAttributesW(wsource);
+	cl_assert(INVALID_FILE_ATTRIBUTES != source_attrs);
+
+	/* Check the target for existence */
+	dest_attrs = GetFileAttributesW(wdest);
+
+	if (INVALID_FILE_ATTRIBUTES != dest_attrs) {
+		/* Target exists; append last path part of source to target.
+		 * Use FindFirstFile to parse the path */
+		find_handle = FindFirstFileW(wsource, &find_data);
+		cl_assert(INVALID_HANDLE_VALUE != find_handle);
+		wcscat_s(wdest, MAX_PATH, L"\\");
+		wcscat_s(wdest, MAX_PATH, find_data.cFileName);
+		FindClose(find_handle);
+
+		/* Check the new target for existence */
+		cl_assert(INVALID_FILE_ATTRIBUTES == GetFileAttributesW(wdest));
+	}
+
+	if (FILE_ATTRIBUTE_DIRECTORY & source_attrs)
+		fs_copydir_helper(wsource, wdest);
+	else
+		cl_assert(CopyFileW(wsource, wdest, TRUE));
+}
+
+void
+cl_fs_cleanup(void)
+{
+	fs_rm(fixture_path(_clar_path, "*"));
+}
+
+#else
+
+#include <errno.h>
+#include <string.h>
+
+static int
+shell_out(char * const argv[])
+{
+	int status, piderr;
+	pid_t pid;
+
+	pid = fork();
+
+	if (pid < 0) {
+		fprintf(stderr,
+			"System error: `fork()` call failed (%d) - %s\n",
+			errno, strerror(errno));
+		exit(-1);
+	}
+
+	if (pid == 0) {
+		execv(argv[0], argv);
+	}
+
+	do {
+		piderr = waitpid(pid, &status, WUNTRACED);
+	} while (piderr < 0 && (errno == EAGAIN || errno == EINTR));
+
+	return WEXITSTATUS(status);
+}
+
+static void
+fs_copy(const char *_source, const char *dest)
+{
+	char *argv[5];
+	char *source;
+	size_t source_len;
+
+	source = strdup(_source);
+	source_len = strlen(source);
+
+	if (source[source_len - 1] == '/')
+		source[source_len - 1] = 0;
+
+	argv[0] = "/bin/cp";
+	argv[1] = "-R";
+	argv[2] = source;
+	argv[3] = (char *)dest;
+	argv[4] = NULL;
+
+	cl_must_pass_(
+		shell_out(argv),
+		"Failed to copy test fixtures to sandbox"
+	);
+
+	free(source);
+}
+
+static void
+fs_rm(const char *source)
+{
+	char *argv[4];
+
+	argv[0] = "/bin/rm";
+	argv[1] = "-Rf";
+	argv[2] = (char *)source;
+	argv[3] = NULL;
+
+	cl_must_pass_(
+		shell_out(argv),
+		"Failed to cleanup the sandbox"
+	);
+}
+
+void
+cl_fs_cleanup(void)
+{
+	clar_unsandbox();
+	clar_sandbox();
+}
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar/print.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar/print.h
new file mode 100755
index 0000000..6529b6b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar/print.h
@@ -0,0 +1,66 @@
+
+static void clar_print_init(int test_count, int suite_count, const char *suite_names)
+{
+	(void)test_count;
+	printf("Loaded %d suites: %s\n", (int)suite_count, suite_names);
+	printf("Started\n");
+}
+
+static void clar_print_shutdown(int test_count, int suite_count, int error_count)
+{
+	(void)test_count;
+	(void)suite_count;
+	(void)error_count;
+
+	printf("\n\n");
+	clar_report_errors();
+}
+
+static void clar_print_error(int num, const struct clar_error *error)
+{
+	printf("  %d) Failure:\n", num);
+
+	printf("%s::%s [%s:%d]\n",
+		error->suite,
+		error->test,
+		error->file,
+		error->line_number);
+
+	printf("  %s\n", error->error_msg);
+
+	if (error->description != NULL)
+		printf("  %s\n", error->description);
+
+	printf("\n");
+	fflush(stdout);
+}
+
+static void clar_print_ontest(const char *test_name, int test_number, enum cl_test_status status)
+{
+	(void)test_name;
+	(void)test_number;
+
+	switch(status) {
+	case CL_TEST_OK: printf("."); break;
+	case CL_TEST_FAILURE: printf("F"); break;
+	case CL_TEST_SKIP: printf("S"); break;
+	}
+
+	fflush(stdout);
+}
+
+static void clar_print_onsuite(const char *suite_name, int suite_index)
+{
+	if (_clar.report_suite_names)
+		printf("\n%s", suite_name);
+
+	(void)suite_index;
+}
+
+static void clar_print_onabort(const char *msg, ...)
+{
+	va_list argp;
+	va_start(argp, msg);
+	vfprintf(stderr, msg, argp);
+	va_end(argp);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar/sandbox.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar/sandbox.h
new file mode 100755
index 0000000..4b83bf3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar/sandbox.h
@@ -0,0 +1,139 @@
+static char _clar_path[4096];
+
+static int
+is_valid_tmp_path(const char *path)
+{
+	STAT_T st;
+
+	if (stat(path, &st) != 0)
+		return 0;
+
+	if (!S_ISDIR(st.st_mode))
+		return 0;
+
+	return (access(path, W_OK) == 0);
+}
+
+static int
+find_tmp_path(char *buffer, size_t length)
+{
+#ifndef _WIN32
+	static const size_t var_count = 5;
+	static const char *env_vars[] = {
+		"CLAR_TMP", "TMPDIR", "TMP", "TEMP", "USERPROFILE"
+ 	};
+
+ 	size_t i;
+
+	for (i = 0; i < var_count; ++i) {
+		const char *env = getenv(env_vars[i]);
+		if (!env)
+			continue;
+
+		if (is_valid_tmp_path(env)) {
+			strncpy(buffer, env, length);
+			return 0;
+		}
+	}
+
+	/* If the environment doesn't say anything, try to use /tmp */
+	if (is_valid_tmp_path("/tmp")) {
+		strncpy(buffer, "/tmp", length);
+		return 0;
+	}
+
+#else
+	DWORD env_len = GetEnvironmentVariable("CLAR_TMP", buffer, (DWORD)length);
+	if (env_len > 0 && env_len < (DWORD)length)
+		return 0;
+
+	if (GetTempPath((DWORD)length, buffer))
+		return 0;
+#endif
+
+	/* This system doesn't like us, try to use the current directory */
+	if (is_valid_tmp_path(".")) {
+		strncpy(buffer, ".", length);
+		return 0;
+	}
+
+	return -1;
+}
+
+static void clar_unsandbox(void)
+{
+	if (_clar_path[0] == '\0')
+		return;
+
+	cl_must_pass(chdir(".."));
+
+	fs_rm(_clar_path);
+}
+
+static int build_sandbox_path(void)
+{
+#ifdef CLAR_TMPDIR
+	const char path_tail[] = CLAR_TMPDIR "_XXXXXX";
+#else
+	const char path_tail[] = "clar_tmp_XXXXXX";
+#endif
+
+	size_t len;
+
+	if (find_tmp_path(_clar_path, sizeof(_clar_path)) < 0)
+		return -1;
+
+	len = strlen(_clar_path);
+
+#ifdef _WIN32
+	{ /* normalize path to POSIX forward slashes */
+		size_t i;
+		for (i = 0; i < len; ++i) {
+			if (_clar_path[i] == '\\')
+				_clar_path[i] = '/';
+		}
+	}
+#endif
+
+	if (_clar_path[len - 1] != '/') {
+		_clar_path[len++] = '/';
+	}
+
+	strncpy(_clar_path + len, path_tail, sizeof(_clar_path) - len);
+
+#if defined(__MINGW32__)
+	if (_mktemp(_clar_path) == NULL)
+		return -1;
+
+	if (mkdir(_clar_path, 0700) != 0)
+		return -1;
+#elif defined(_WIN32)
+	if (_mktemp_s(_clar_path, sizeof(_clar_path)) != 0)
+		return -1;
+
+	if (mkdir(_clar_path, 0700) != 0)
+		return -1;
+#else
+	if (mkdtemp(_clar_path) == NULL)
+		return -1;
+#endif
+
+	return 0;
+}
+
+static int clar_sandbox(void)
+{
+	if (_clar_path[0] == '\0' && build_sandbox_path() < 0)
+		return -1;
+
+	if (chdir(_clar_path) != 0)
+		return -1;
+
+	return 0;
+}
+
+const char *clar_sandbox_path(void)
+{
+	return _clar_path;
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2.c
new file mode 100755
index 0000000..b14af44
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2.c
@@ -0,0 +1,570 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "path.h"
+#include "git2/sys/repository.h"
+
+void cl_git_report_failure(
+	int error, const char *file, int line, const char *fncall)
+{
+	char msg[4096];
+	const git_error *last = giterr_last();
+	p_snprintf(msg, 4096, "error %d - %s",
+		error, last ? last->message : "<no message>");
+	clar__assert(0, file, line, fncall, msg, 1);
+}
+
+void cl_git_mkfile(const char *filename, const char *content)
+{
+	int fd;
+
+	fd = p_creat(filename, 0666);
+	cl_assert(fd != -1);
+
+	if (content) {
+		cl_must_pass(p_write(fd, content, strlen(content)));
+	} else {
+		cl_must_pass(p_write(fd, filename, strlen(filename)));
+		cl_must_pass(p_write(fd, "\n", 1));
+	}
+
+	cl_must_pass(p_close(fd));
+}
+
+void cl_git_write2file(
+	const char *path, const char *content, size_t content_len,
+	int flags, unsigned int mode)
+{
+	int fd;
+	cl_assert(path && content);
+	cl_assert((fd = p_open(path, flags, mode)) >= 0);
+	if (!content_len)
+		content_len = strlen(content);
+	cl_must_pass(p_write(fd, content, content_len));
+	cl_must_pass(p_close(fd));
+}
+
+void cl_git_append2file(const char *path, const char *content)
+{
+	cl_git_write2file(path, content, 0, O_WRONLY | O_CREAT | O_APPEND, 0644);
+}
+
+void cl_git_rewritefile(const char *path, const char *content)
+{
+	cl_git_write2file(path, content, 0, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+}
+
+void cl_git_rmfile(const char *filename)
+{
+	cl_must_pass(p_unlink(filename));
+}
+
+#ifdef GIT_WIN32
+
+#include "win32/utf-conv.h"
+
+char *cl_getenv(const char *name)
+{
+	wchar_t *wide_name, *wide_value;
+	char *utf8_value = NULL;
+	DWORD value_len;
+
+	cl_assert(git__utf8_to_16_alloc(&wide_name, name) >= 0);
+
+	value_len = GetEnvironmentVariableW(wide_name, NULL, 0);
+
+	if (value_len) {
+		cl_assert(wide_value = git__malloc(value_len * sizeof(wchar_t)));
+		cl_assert(GetEnvironmentVariableW(wide_name, wide_value, value_len));
+		cl_assert(git__utf16_to_8_alloc(&utf8_value, wide_value) >= 0);
+		git__free(wide_value);
+	}
+
+	git__free(wide_name);
+	return utf8_value;
+}
+
+int cl_setenv(const char *name, const char *value)
+{
+	wchar_t *wide_name, *wide_value = NULL;
+
+	cl_assert(git__utf8_to_16_alloc(&wide_name, name) >= 0);
+
+	if (value) {
+		cl_assert(git__utf8_to_16_alloc(&wide_value, value) >= 0);
+		cl_assert(SetEnvironmentVariableW(wide_name, wide_value));
+	} else {
+		/* Windows XP returns 0 (failed) when passing NULL for lpValue when
+		* lpName does not exist in the environment block. This behavior
+		* seems to have changed in later versions. Don't check the return value
+		* of SetEnvironmentVariable when passing NULL for lpValue. */
+		SetEnvironmentVariableW(wide_name, NULL);
+	}
+
+	git__free(wide_name);
+	git__free(wide_value);
+	return 0;
+}
+
+/* This function performs retries on calls to MoveFile in order
+ * to provide enhanced reliability in the face of antivirus
+ * agents that may be scanning the source (or in the case that
+ * the source is a directory, a child of the source). */
+int cl_rename(const char *source, const char *dest)
+{
+	git_win32_path source_utf16;
+	git_win32_path dest_utf16;
+	unsigned retries = 1;
+
+	cl_assert(git_win32_path_from_utf8(source_utf16, source) >= 0);
+	cl_assert(git_win32_path_from_utf8(dest_utf16, dest) >= 0);
+
+	while (!MoveFileW(source_utf16, dest_utf16)) {
+		/* Only retry if the error is ERROR_ACCESS_DENIED;
+		 * this may indicate that an antivirus agent is
+		 * preventing the rename from source to target */
+		if (retries > 5 ||
+			ERROR_ACCESS_DENIED != GetLastError())
+			return -1;
+
+		/* With 5 retries and a coefficient of 10ms, the maximum
+		 * delay here is 550 ms */
+		Sleep(10 * retries * retries);
+		retries++;
+	}
+
+	return 0;
+}
+
+#else
+
+#include <stdlib.h>
+char *cl_getenv(const char *name)
+{
+	return getenv(name);
+}
+
+int cl_setenv(const char *name, const char *value)
+{
+	return (value == NULL) ? unsetenv(name) : setenv(name, value, 1);
+}
+
+int cl_rename(const char *source, const char *dest)
+{
+	return p_rename(source, dest);
+}
+
+#endif
+
+static const char *_cl_sandbox = NULL;
+static git_repository *_cl_repo = NULL;
+
+git_repository *cl_git_sandbox_init(const char *sandbox)
+{
+	/* Copy the whole sandbox folder from our fixtures to our test sandbox
+	 * area.  After this it can be accessed with `./sandbox`
+	 */
+	cl_fixture_sandbox(sandbox);
+	_cl_sandbox = sandbox;
+
+	cl_git_pass(p_chdir(sandbox));
+
+	/* If this is not a bare repo, then rename `sandbox/.gitted` to
+	 * `sandbox/.git` which must be done since we cannot store a folder
+	 * named `.git` inside the fixtures folder of our libgit2 repo.
+	 */
+	if (p_access(".gitted", F_OK) == 0)
+		cl_git_pass(cl_rename(".gitted", ".git"));
+
+	/* If we have `gitattributes`, rename to `.gitattributes`.  This may
+	 * be necessary if we don't want the attributes to be applied in the
+	 * libgit2 repo, but just during testing.
+	 */
+	if (p_access("gitattributes", F_OK) == 0)
+		cl_git_pass(cl_rename("gitattributes", ".gitattributes"));
+
+	/* As with `gitattributes`, we may need `gitignore` just for testing. */
+	if (p_access("gitignore", F_OK) == 0)
+		cl_git_pass(cl_rename("gitignore", ".gitignore"));
+
+	cl_git_pass(p_chdir(".."));
+
+	/* Now open the sandbox repository and make it available for tests */
+	cl_git_pass(git_repository_open(&_cl_repo, sandbox));
+
+	/* Adjust configs after copying to new filesystem */
+	cl_git_pass(git_repository_reinit_filesystem(_cl_repo, 0));
+
+	return _cl_repo;
+}
+
+git_repository *cl_git_sandbox_init_new(const char *sandbox)
+{
+	cl_git_pass(git_repository_init(&_cl_repo, sandbox, false));
+	_cl_sandbox = sandbox;
+
+	return _cl_repo;
+}
+
+git_repository *cl_git_sandbox_reopen(void)
+{
+	if (_cl_repo) {
+		git_repository_free(_cl_repo);
+		_cl_repo = NULL;
+
+		cl_git_pass(git_repository_open(&_cl_repo, _cl_sandbox));
+	}
+
+	return _cl_repo;
+}
+
+void cl_git_sandbox_cleanup(void)
+{
+	if (_cl_repo) {
+		git_repository_free(_cl_repo);
+		_cl_repo = NULL;
+	}
+	if (_cl_sandbox) {
+		cl_fixture_cleanup(_cl_sandbox);
+		_cl_sandbox = NULL;
+	}
+}
+
+bool cl_toggle_filemode(const char *filename)
+{
+	struct stat st1, st2;
+
+	cl_must_pass(p_stat(filename, &st1));
+	cl_must_pass(p_chmod(filename, st1.st_mode ^ 0100));
+	cl_must_pass(p_stat(filename, &st2));
+
+	return (st1.st_mode != st2.st_mode);
+}
+
+bool cl_is_chmod_supported(void)
+{
+	static int _is_supported = -1;
+
+	if (_is_supported < 0) {
+		cl_git_mkfile("filemode.t", "Test if filemode can be modified");
+		_is_supported = cl_toggle_filemode("filemode.t");
+		cl_must_pass(p_unlink("filemode.t"));
+	}
+
+	return _is_supported;
+}
+
+const char* cl_git_fixture_url(const char *fixturename)
+{
+	return cl_git_path_url(cl_fixture(fixturename));
+}
+
+const char* cl_git_path_url(const char *path)
+{
+	static char url[4096];
+
+	const char *in_buf;
+	git_buf path_buf = GIT_BUF_INIT;
+	git_buf url_buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_path_prettify_dir(&path_buf, path, NULL));
+	cl_git_pass(git_buf_puts(&url_buf, "file://"));
+
+#ifdef GIT_WIN32
+	/*
+	 * A FILE uri matches the following format: file://[host]/path
+	 * where "host" can be empty and "path" is an absolute path to the resource.
+	 *
+	 * In this test, no hostname is used, but we have to ensure the leading triple slashes:
+	 *
+	 * *nix: file:///usr/home/...
+	 * Windows: file:///C:/Users/...
+	 */
+	cl_git_pass(git_buf_putc(&url_buf, '/'));
+#endif
+
+	in_buf = git_buf_cstr(&path_buf);
+
+	/*
+	 * A very hacky Url encoding that only takes care of escaping the spaces
+	 */
+	while (*in_buf) {
+		if (*in_buf == ' ')
+			cl_git_pass(git_buf_puts(&url_buf, "%20"));
+		else
+			cl_git_pass(git_buf_putc(&url_buf, *in_buf));
+
+		in_buf++;
+	}
+
+	strncpy(url, git_buf_cstr(&url_buf), 4096);
+	git_buf_free(&url_buf);
+	git_buf_free(&path_buf);
+	return url;
+}
+
+typedef struct {
+	const char *filename;
+	size_t filename_len;
+} remove_data;
+
+static int remove_placeholders_recurs(void *_data, git_buf *path)
+{
+	remove_data *data = (remove_data *)_data;
+	size_t pathlen;
+
+	if (git_path_isdir(path->ptr) == true)
+		return git_path_direach(path, 0, remove_placeholders_recurs, data);
+
+	pathlen = path->size;
+
+	if (pathlen < data->filename_len)
+		return 0;
+
+	/* if path ends in '/'+filename (or equals filename) */
+	if (!strcmp(data->filename, path->ptr + pathlen - data->filename_len) &&
+		(pathlen == data->filename_len ||
+		 path->ptr[pathlen - data->filename_len - 1] == '/'))
+		return p_unlink(path->ptr);
+
+	return 0;
+}
+
+int cl_git_remove_placeholders(const char *directory_path, const char *filename)
+{
+	int error;
+	remove_data data;
+	git_buf buffer = GIT_BUF_INIT;
+
+	if (git_path_isdir(directory_path) == false)
+		return -1;
+
+	if (git_buf_sets(&buffer, directory_path) < 0)
+		return -1;
+
+	data.filename = filename;
+	data.filename_len = strlen(filename);
+
+	error = remove_placeholders_recurs(&data, &buffer);
+
+	git_buf_free(&buffer);
+
+	return error;
+}
+
+#define CL_COMMIT_NAME "Libgit2 Tester"
+#define CL_COMMIT_EMAIL "libgit2-test at github.com"
+#define CL_COMMIT_MSG "Test commit of tree "
+
+void cl_repo_commit_from_index(
+	git_oid *out,
+	git_repository *repo,
+	git_signature *sig,
+	git_time_t time,
+	const char *msg)
+{
+	git_index *index;
+	git_oid commit_id, tree_id;
+	git_object *parent = NULL;
+	git_reference *ref = NULL;
+	git_tree *tree = NULL;
+	char buf[128];
+	int free_sig = (sig == NULL);
+
+	/* it is fine if looking up HEAD fails - we make this the first commit */
+	git_revparse_ext(&parent, &ref, repo, "HEAD");
+
+	/* write the index content as a tree */
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_write_tree(&tree_id, index));
+	cl_git_pass(git_index_write(index));
+	git_index_free(index);
+
+	cl_git_pass(git_tree_lookup(&tree, repo, &tree_id));
+
+	if (sig)
+		cl_assert(sig->name && sig->email);
+	else if (!time)
+		cl_git_pass(git_signature_now(&sig, CL_COMMIT_NAME, CL_COMMIT_EMAIL));
+	else
+		cl_git_pass(git_signature_new(
+			&sig, CL_COMMIT_NAME, CL_COMMIT_EMAIL, time, 0));
+
+	if (!msg) {
+		strcpy(buf, CL_COMMIT_MSG);
+		git_oid_tostr(buf + strlen(CL_COMMIT_MSG),
+			sizeof(buf) - strlen(CL_COMMIT_MSG), &tree_id);
+		msg = buf;
+	}
+
+	cl_git_pass(git_commit_create_v(
+		&commit_id, repo, ref ? git_reference_name(ref) : "HEAD",
+		sig, sig, NULL, msg, tree, parent ? 1 : 0, parent));
+
+	if (out)
+		git_oid_cpy(out, &commit_id);
+
+	git_object_free(parent);
+	git_reference_free(ref);
+	if (free_sig)
+		git_signature_free(sig);
+	git_tree_free(tree);
+}
+
+void cl_repo_set_bool(git_repository *repo, const char *cfg, int value)
+{
+	git_config *config;
+	cl_git_pass(git_repository_config(&config, repo));
+	cl_git_pass(git_config_set_bool(config, cfg, value != 0));
+	git_config_free(config);
+}
+
+int cl_repo_get_bool(git_repository *repo, const char *cfg)
+{
+	int val = 0;
+	git_config *config;
+	cl_git_pass(git_repository_config(&config, repo));
+	if (git_config_get_bool(&val, config, cfg) < 0)
+		giterr_clear();
+	git_config_free(config);
+	return val;
+}
+
+void cl_repo_set_string(git_repository *repo, const char *cfg, const char *value)
+{
+	git_config *config;
+	cl_git_pass(git_repository_config(&config, repo));
+	cl_git_pass(git_config_set_string(config, cfg, value));
+	git_config_free(config);
+}
+
+/* this is essentially the code from git__unescape modified slightly */
+static size_t strip_cr_from_buf(char *start, size_t len)
+{
+	char *scan, *trail, *end = start + len;
+
+	for (scan = trail = start; scan < end; trail++, scan++) {
+		while (*scan == '\r')
+			scan++; /* skip '\r' */
+
+		if (trail != scan)
+			*trail = *scan;
+	}
+
+	*trail = '\0';
+
+	return (trail - start);
+}
+
+void clar__assert_equal_file(
+	const char *expected_data,
+	size_t expected_bytes,
+	int ignore_cr,
+	const char *path,
+	const char *file,
+	int line)
+{
+	char buf[4000];
+	ssize_t bytes, total_bytes = 0;
+	int fd = p_open(path, O_RDONLY | O_BINARY);
+	cl_assert(fd >= 0);
+
+	if (expected_data && !expected_bytes)
+		expected_bytes = strlen(expected_data);
+
+	while ((bytes = p_read(fd, buf, sizeof(buf))) != 0) {
+		clar__assert(
+			bytes > 0, file, line, "error reading from file", path, 1);
+
+		if (ignore_cr)
+			bytes = strip_cr_from_buf(buf, bytes);
+
+		if (memcmp(expected_data, buf, bytes) != 0) {
+			int pos;
+			for (pos = 0; pos < bytes && expected_data[pos] == buf[pos]; ++pos)
+				/* find differing byte offset */;
+			p_snprintf(
+				buf, sizeof(buf), "file content mismatch at byte %"PRIdZ,
+				(ssize_t)(total_bytes + pos));
+			p_close(fd);
+			clar__fail(file, line, path, buf, 1);
+		}
+
+		expected_data += bytes;
+		total_bytes   += bytes;
+	}
+
+	p_close(fd);
+
+	clar__assert(!bytes, file, line, "error reading from file", path, 1);
+	clar__assert_equal(file, line, "mismatched file length", 1, "%"PRIuZ,
+		(size_t)expected_bytes, (size_t)total_bytes);
+}
+
+static char *_cl_restore_home = NULL;
+
+void cl_fake_home_cleanup(void *payload)
+{
+	char *restore = _cl_restore_home;
+	_cl_restore_home = NULL;
+
+	GIT_UNUSED(payload);
+
+	if (restore) {
+		cl_git_pass(git_libgit2_opts(
+			GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, restore));
+		git__free(restore);
+	}
+}
+
+void cl_fake_home(void)
+{
+	git_buf path = GIT_BUF_INIT;
+
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &path));
+
+	_cl_restore_home = git_buf_detach(&path);
+	cl_set_cleanup(cl_fake_home_cleanup, NULL);
+
+	if (!git_path_exists("home"))
+		cl_must_pass(p_mkdir("home", 0777));
+	cl_git_pass(git_path_prettify(&path, "home", NULL));
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
+	git_buf_free(&path);
+}
+
+void cl_sandbox_set_search_path_defaults(void)
+{
+	const char *sandbox_path = clar_sandbox_path();
+
+	git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, sandbox_path);
+	git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, sandbox_path);
+	git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, sandbox_path);
+}
+
+#ifdef GIT_WIN32
+bool cl_sandbox_supports_8dot3(void)
+{
+	git_buf longpath = GIT_BUF_INIT;
+	char *shortname;
+	bool supported;
+
+	cl_git_pass(
+		git_buf_joinpath(&longpath, clar_sandbox_path(), "longer_than_8dot3"));
+
+	cl_git_write2file(longpath.ptr, "", 0, O_RDWR|O_CREAT, 0666);
+	shortname = git_win32_path_8dot3_name(longpath.ptr);
+
+	supported = (shortname != NULL);
+
+	git__free(shortname);
+	git_buf_free(&longpath);
+
+	return supported;
+}
+#endif
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2.h
new file mode 100755
index 0000000..9ab0da4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2.h
@@ -0,0 +1,169 @@
+#ifndef __CLAR_LIBGIT2__
+#define __CLAR_LIBGIT2__
+
+#include "clar.h"
+#include <git2.h>
+#include <posix.h>
+#include "common.h"
+
+/**
+ * Replace for `clar_must_pass` that passes the last library error as the
+ * test failure message.
+ *
+ * Use this wrapper around all `git_` library calls that return error codes!
+ */
+#define cl_git_pass(expr) cl_git_pass_((expr), __FILE__, __LINE__)
+
+#define cl_git_pass_(expr, file, line) do { \
+	int _lg2_error; \
+	giterr_clear(); \
+	if ((_lg2_error = (expr)) != 0) \
+		cl_git_report_failure(_lg2_error, file, line, "Function call failed: " #expr); \
+	} while (0)
+
+/**
+ * Wrapper for `clar_must_fail` -- this one is
+ * just for consistency. Use with `git_` library
+ * calls that are supposed to fail!
+ */
+#define cl_git_fail(expr) cl_must_fail(expr)
+
+#define cl_git_fail_with(expr, error) cl_assert_equal_i(error,expr)
+
+/**
+ * Like cl_git_pass, only for Win32 error code conventions
+ */
+#define cl_win32_pass(expr) do { \
+	int _win32_res; \
+	if ((_win32_res = (expr)) == 0) { \
+		giterr_set(GITERR_OS, "Returned: %d, system error code: %d", _win32_res, GetLastError()); \
+		cl_git_report_failure(_win32_res, __FILE__, __LINE__, "System call failed: " #expr); \
+	} \
+	} while(0)
+
+void cl_git_report_failure(int, const char *, int, const char *);
+
+#define cl_assert_at_line(expr,file,line) \
+	clar__assert((expr) != 0, file, line, "Expression is not true: " #expr, NULL, 1)
+
+GIT_INLINE(void) clar__assert_in_range(
+	int lo, int val, int hi,
+	const char *file, int line, const char *err, int should_abort)
+{
+	if (lo > val || hi < val) {
+		char buf[128];
+		p_snprintf(buf, sizeof(buf), "%d not in [%d,%d]", val, lo, hi);
+		clar__fail(file, line, err, buf, should_abort);
+	}
+}
+
+#define cl_assert_equal_sz(sz1,sz2) do { \
+	size_t __sz1 = (size_t)(sz1), __sz2 = (size_t)(sz2); \
+	clar__assert_equal(__FILE__,__LINE__,#sz1 " != " #sz2, 1, "%"PRIuZ, __sz1, __sz2); \
+} while (0)
+
+#define cl_assert_in_range(L,V,H) \
+	clar__assert_in_range((L),(V),(H),__FILE__,__LINE__,"Range check: " #V " in [" #L "," #H "]", 1)
+
+#define cl_assert_equal_file(DATA,SIZE,PATH) \
+	clar__assert_equal_file(DATA,SIZE,0,PATH,__FILE__,(int)__LINE__)
+
+#define cl_assert_equal_file_ignore_cr(DATA,SIZE,PATH) \
+	clar__assert_equal_file(DATA,SIZE,1,PATH,__FILE__,(int)__LINE__)
+
+void clar__assert_equal_file(
+	const char *expected_data,
+	size_t expected_size,
+	int ignore_cr,
+	const char *path,
+	const char *file,
+	int line);
+
+GIT_INLINE(void) clar__assert_equal_oid(
+	const char *file, int line, const char *desc,
+	const git_oid *one, const git_oid *two)
+{
+	if (git_oid_cmp(one, two)) {
+		char err[] = "\"........................................\" != \"........................................\"";
+
+		git_oid_fmt(&err[1], one);
+		git_oid_fmt(&err[47], two);
+
+		clar__fail(file, line, desc, err, 1);
+	}
+}
+
+#define cl_assert_equal_oid(one, two) \
+	clar__assert_equal_oid(__FILE__, __LINE__, \
+		"OID mismatch: " #one " != " #two, (one), (two))
+
+/*
+ * Some utility macros for building long strings
+ */
+#define REP4(STR)	 STR STR STR STR
+#define REP15(STR)	 REP4(STR) REP4(STR) REP4(STR) STR STR STR
+#define REP16(STR)	 REP4(REP4(STR))
+#define REP256(STR)  REP16(REP16(STR))
+#define REP1024(STR) REP4(REP256(STR))
+
+/* Write the contents of a buffer to disk */
+void cl_git_mkfile(const char *filename, const char *content);
+void cl_git_append2file(const char *filename, const char *new_content);
+void cl_git_rewritefile(const char *filename, const char *new_content);
+void cl_git_write2file(const char *path, const char *data,
+	size_t datalen, int flags, unsigned int mode);
+void cl_git_rmfile(const char *filename);
+
+bool cl_toggle_filemode(const char *filename);
+bool cl_is_chmod_supported(void);
+
+/* Environment wrappers */
+char *cl_getenv(const char *name);
+int cl_setenv(const char *name, const char *value);
+
+/* Reliable rename */
+int cl_rename(const char *source, const char *dest);
+
+/* Git sandbox setup helpers */
+
+git_repository *cl_git_sandbox_init(const char *sandbox);
+git_repository *cl_git_sandbox_init_new(const char *name);
+void cl_git_sandbox_cleanup(void);
+git_repository *cl_git_sandbox_reopen(void);
+
+/* Local-repo url helpers */
+const char* cl_git_fixture_url(const char *fixturename);
+const char* cl_git_path_url(const char *path);
+
+/* Test repository cleaner */
+int cl_git_remove_placeholders(const char *directory_path, const char *filename);
+
+/* commit creation helpers */
+void cl_repo_commit_from_index(
+	git_oid *out,
+	git_repository *repo,
+	git_signature *sig,
+	git_time_t time,
+	const char *msg);
+
+/* config setting helpers */
+void cl_repo_set_bool(git_repository *repo, const char *cfg, int value);
+int cl_repo_get_bool(git_repository *repo, const char *cfg);
+
+void cl_repo_set_string(git_repository *repo, const char *cfg, const char *value);
+
+/* set up a fake "home" directory and set libgit2 GLOBAL search path.
+ *
+ * automatically configures cleanup function to restore the regular search
+ * path, although you can call it explicitly if you wish (with NULL).
+ */
+void cl_fake_home(void);
+void cl_fake_home_cleanup(void *);
+
+void cl_sandbox_set_search_path_defaults(void);
+
+#ifdef GIT_WIN32
+bool cl_sandbox_supports_8dot3(void);
+#endif
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2_timer.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2_timer.c
new file mode 100755
index 0000000..737506d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2_timer.c
@@ -0,0 +1,31 @@
+#include "clar_libgit2.h"
+#include "clar_libgit2_timer.h"
+#include "buffer.h"
+
+void cl_perf_timer__init(cl_perf_timer *t)
+{
+	memset(t, 0, sizeof(cl_perf_timer));
+}
+
+void cl_perf_timer__start(cl_perf_timer *t)
+{
+	t->time_started = git__timer();
+}
+
+void cl_perf_timer__stop(cl_perf_timer *t)
+{
+	double time_now = git__timer();
+
+	t->last = time_now - t->time_started;
+	t->sum += t->last;
+}
+
+double cl_perf_timer__last(const cl_perf_timer *t)
+{
+	return t->last;
+}
+
+double cl_perf_timer__sum(const cl_perf_timer *t)
+{
+	return t->sum;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2_timer.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2_timer.h
new file mode 100755
index 0000000..0d150e0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2_timer.h
@@ -0,0 +1,35 @@
+#ifndef __CLAR_LIBGIT2_TIMER__
+#define __CLAR_LIBGIT2_TIMER__
+
+struct cl_perf_timer
+{
+	/* cummulative running time across all start..stop intervals */
+	double sum;
+
+	/* value of last start..stop interval */
+	double last;
+
+	/* clock value at start */
+	double time_started;
+};
+
+#define CL_PERF_TIMER_INIT {0}
+
+typedef struct cl_perf_timer cl_perf_timer;
+
+void cl_perf_timer__init(cl_perf_timer *t);
+void cl_perf_timer__start(cl_perf_timer *t);
+void cl_perf_timer__stop(cl_perf_timer *t);
+
+/**
+ * return value of last start..stop interval in seconds.
+ */
+double cl_perf_timer__last(const cl_perf_timer *t);
+
+/**
+ * return cummulative running time across all start..stop
+ * intervals in seconds.
+ */
+double cl_perf_timer__sum(const cl_perf_timer *t);
+
+#endif /* __CLAR_LIBGIT2_TIMER__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2_trace.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2_trace.c
new file mode 100755
index 0000000..ae582d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2_trace.c
@@ -0,0 +1,229 @@
+#include "clar_libgit2.h"
+#include "clar_libgit2_trace.h"
+#include "clar_libgit2_timer.h"
+#include "trace.h"
+
+
+struct method {
+	const char *name;
+	void (*git_trace_cb)(git_trace_level_t level, const char *msg);
+	void (*close)(void);
+};
+
+
+#if defined(GIT_TRACE)
+static void _git_trace_cb__printf(git_trace_level_t level, const char *msg)
+{
+	/* TODO Use level to print a per-message prefix. */
+	GIT_UNUSED(level);
+
+	printf("%s\n", msg);
+}
+
+#if defined(GIT_WIN32)
+static void _git_trace_cb__debug(git_trace_level_t level, const char *msg)
+{
+	/* TODO Use level to print a per-message prefix. */
+	GIT_UNUSED(level);
+
+	OutputDebugString(msg);
+	OutputDebugString("\n");
+
+	printf("%s\n", msg);
+}
+#else
+#define _git_trace_cb__debug _git_trace_cb__printf
+#endif
+
+
+static void _trace_printf_close(void)
+{
+	fflush(stdout);
+}
+
+#define _trace_debug_close _trace_printf_close
+
+
+static struct method s_methods[] = {
+	{ "printf", _git_trace_cb__printf, _trace_printf_close },
+	{ "debug",  _git_trace_cb__debug,  _trace_debug_close  },
+	/* TODO add file method */
+	{0},
+};
+
+
+static int s_trace_loaded = 0;
+static int s_trace_level = GIT_TRACE_NONE;
+static struct method *s_trace_method = NULL;
+
+
+static int set_method(const char *name)
+{
+	int k;
+
+	if (!name || !*name)
+		name = "printf";
+
+	for (k=0; (s_methods[k].name); k++) {
+		if (strcmp(name, s_methods[k].name) == 0) {
+			s_trace_method = &s_methods[k];
+			return 0;
+		}
+	}
+	fprintf(stderr, "Unknown CLAR_TRACE_METHOD: '%s'\n", name);
+	return -1;
+}
+
+
+/**
+ * Lookup CLAR_TRACE_LEVEL and CLAR_TRACE_METHOD from
+ * the environment and set the above s_trace_* fields.
+ *
+ * If CLAR_TRACE_LEVEL is not set, we disable tracing.
+ *
+ * TODO If set, we assume GIT_TRACE_TRACE level, which
+ * logs everything. Later, we may want to parse the
+ * value of the environment variable and set a specific
+ * level.
+ *
+ * We assume the "printf" method.  This can be changed
+ * with the CLAR_TRACE_METHOD environment variable.
+ * Currently, this is only needed on Windows for a "debug"
+ * version which also writes to the debug output window
+ * in Visual Studio.
+ *
+ * TODO add a "file" method that would open and write
+ * to a well-known file. This would help keep trace
+ * output and clar output separate.
+ *
+ */
+static void _load_trace_params(void)
+{
+	char *sz_level;
+	char *sz_method;
+
+	s_trace_loaded = 1;
+
+	sz_level = cl_getenv("CLAR_TRACE_LEVEL");
+	if (!sz_level || !*sz_level) {
+		s_trace_level = GIT_TRACE_NONE;
+		s_trace_method = NULL;
+		return;
+	}
+
+	/* TODO Parse sz_level and set s_trace_level. */
+	s_trace_level = GIT_TRACE_TRACE;
+
+	sz_method = cl_getenv("CLAR_TRACE_METHOD");
+	if (set_method(sz_method) < 0)
+		set_method(NULL);
+}
+
+#define HR "================================================================"
+
+/**
+ * Timer to report the take spend in a test's run() method.
+ */
+static cl_perf_timer s_timer_run = CL_PERF_TIMER_INIT;
+
+/**
+ * Timer to report total time in a test (init, run, cleanup).
+ */
+static cl_perf_timer s_timer_test = CL_PERF_TIMER_INIT;
+
+void _cl_trace_cb__event_handler(
+	cl_trace_event ev,
+	const char *suite_name,
+	const char *test_name,
+	void *payload)
+{
+	GIT_UNUSED(payload);
+
+	switch (ev) {
+	case CL_TRACE__SUITE_BEGIN:
+		git_trace(GIT_TRACE_TRACE, "\n\n%s\n%s: Begin Suite", HR, suite_name);
+		break;
+
+	case CL_TRACE__SUITE_END:
+		git_trace(GIT_TRACE_TRACE, "\n\n%s: End Suite\n%s", suite_name, HR);
+		break;
+
+	case CL_TRACE__TEST__BEGIN:
+		git_trace(GIT_TRACE_TRACE, "\n%s::%s: Begin Test", suite_name, test_name);
+		cl_perf_timer__init(&s_timer_test);
+		cl_perf_timer__start(&s_timer_test);
+		break;
+
+	case CL_TRACE__TEST__END:
+		cl_perf_timer__stop(&s_timer_test);
+		git_trace(GIT_TRACE_TRACE, "%s::%s: End Test (%.3f %.3f)", suite_name, test_name,
+				  cl_perf_timer__last(&s_timer_run),
+				  cl_perf_timer__last(&s_timer_test));
+		break;
+
+	case CL_TRACE__TEST__RUN_BEGIN:
+		git_trace(GIT_TRACE_TRACE, "%s::%s: Begin Run", suite_name, test_name);
+		cl_perf_timer__init(&s_timer_run);
+		cl_perf_timer__start(&s_timer_run);
+		break;
+
+	case CL_TRACE__TEST__RUN_END:
+		cl_perf_timer__stop(&s_timer_run);
+		git_trace(GIT_TRACE_TRACE, "%s::%s: End Run", suite_name, test_name);
+		break;
+
+	case CL_TRACE__TEST__LONGJMP:
+		cl_perf_timer__stop(&s_timer_run);
+		git_trace(GIT_TRACE_TRACE, "%s::%s: Aborted", suite_name, test_name);
+		break;
+
+	default:
+		break;
+	}
+}
+
+#endif /*GIT_TRACE*/
+
+/**
+ * Setup/Enable git_trace() based upon settings user's environment.
+ *
+ */
+void cl_global_trace_register(void)
+{
+#if defined(GIT_TRACE)
+	if (!s_trace_loaded)
+		_load_trace_params();
+
+	if (s_trace_level == GIT_TRACE_NONE)
+		return;
+	if (s_trace_method == NULL)
+		return;
+	if (s_trace_method->git_trace_cb == NULL)
+		return;
+
+	git_trace_set(s_trace_level, s_trace_method->git_trace_cb);
+	cl_trace_register(_cl_trace_cb__event_handler, NULL);
+#endif
+}
+
+/**
+ * If we turned on git_trace() earlier, turn it off.
+ *
+ * This is intended to let us close/flush any buffered
+ * IO if necessary.
+ *
+ */
+void cl_global_trace_disable(void)
+{
+#if defined(GIT_TRACE)
+	cl_trace_register(NULL, NULL);
+	git_trace_set(GIT_TRACE_NONE, NULL);
+	if (s_trace_method && s_trace_method->close)
+		s_trace_method->close();
+
+	/* Leave s_trace_ vars set so they can restart tracing
+	 * since we only want to hit the environment variables
+	 * once.
+	 */
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2_trace.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2_trace.h
new file mode 100755
index 0000000..09d1e05
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clar_libgit2_trace.h
@@ -0,0 +1,7 @@
+#ifndef __CLAR_LIBGIT2_TRACE__
+#define __CLAR_LIBGIT2_TRACE__
+
+void cl_global_trace_register(void);
+void cl_global_trace_disable(void);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clone/empty.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clone/empty.c
new file mode 100755
index 0000000..2a62175
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clone/empty.c
@@ -0,0 +1,85 @@
+#include "clar_libgit2.h"
+
+#include "git2/clone.h"
+#include "repository.h"
+
+static git_clone_options g_options;
+static git_repository *g_repo;
+static git_repository *g_repo_cloned;
+
+void test_clone_empty__initialize(void)
+{
+	git_repository *sandbox = cl_git_sandbox_init("empty_bare.git");
+	git_fetch_options dummy_options = GIT_FETCH_OPTIONS_INIT;
+	cl_git_remove_placeholders(git_repository_path(sandbox), "dummy-marker.txt");
+
+	g_repo = NULL;
+
+	memset(&g_options, 0, sizeof(git_clone_options));
+	g_options.version = GIT_CLONE_OPTIONS_VERSION;
+	g_options.fetch_opts = dummy_options;
+}
+
+void test_clone_empty__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static void cleanup_repository(void *path)
+{
+	cl_fixture_cleanup((const char *)path);
+
+	git_repository_free(g_repo_cloned);
+	g_repo_cloned = NULL;
+}
+
+void test_clone_empty__can_clone_an_empty_local_repo_barely(void)
+{
+	char *local_name = "refs/heads/master";
+	const char *expected_tracked_branch_name = "refs/remotes/origin/master";
+	const char *expected_remote_name = "origin";
+	git_buf buf = GIT_BUF_INIT;
+	git_reference *ref;
+
+	cl_set_cleanup(&cleanup_repository, "./empty");
+
+	g_options.bare = true;
+	cl_git_pass(git_clone(&g_repo_cloned, "./empty_bare.git", "./empty", &g_options));
+
+	/* Although the HEAD is unborn... */
+	cl_assert_equal_i(GIT_ENOTFOUND, git_reference_lookup(&ref, g_repo_cloned, local_name));
+
+	/* ...one can still retrieve the name of the remote tracking reference */
+	cl_git_pass(git_branch_upstream_name(&buf, g_repo_cloned, local_name));
+
+	cl_assert_equal_s(expected_tracked_branch_name, buf.ptr);
+	git_buf_free(&buf);
+
+	/* ...and the name of the remote... */
+	cl_git_pass(git_branch_remote_name(&buf, g_repo_cloned, expected_tracked_branch_name));
+
+	cl_assert_equal_s(expected_remote_name, buf.ptr);
+	git_buf_free(&buf);
+
+	/* ...even when the remote HEAD is unborn as well */
+	cl_assert_equal_i(GIT_ENOTFOUND, git_reference_lookup(&ref, g_repo_cloned,
+		expected_tracked_branch_name));
+}
+
+void test_clone_empty__can_clone_an_empty_local_repo(void)
+{
+	cl_set_cleanup(&cleanup_repository, "./empty");
+
+	cl_git_pass(git_clone(&g_repo_cloned, "./empty_bare.git", "./empty", &g_options));
+}
+
+void test_clone_empty__can_clone_an_empty_standard_repo(void)
+{
+	cl_git_sandbox_cleanup();
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+	cl_git_remove_placeholders(git_repository_path(g_repo), "dummy-marker.txt");
+
+	cl_set_cleanup(&cleanup_repository, "./empty");
+
+	cl_git_pass(git_clone(&g_repo_cloned, "./empty_standard_repo", "./empty", &g_options));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clone/local.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clone/local.c
new file mode 100755
index 0000000..91a0a1c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clone/local.c
@@ -0,0 +1,211 @@
+#include "clar_libgit2.h"
+
+#include "git2/clone.h"
+#include "clone.h"
+#include "buffer.h"
+#include "path.h"
+#include "posix.h"
+#include "fileops.h"
+
+static int file_url(git_buf *buf, const char *host, const char *path)
+{
+	if (path[0] == '/')
+		path++;
+
+	git_buf_clear(buf);
+	return git_buf_printf(buf, "file://%s/%s", host, path);
+}
+
+static int git_style_unc_path(git_buf *buf, const char *host, const char *path)
+{
+	git_buf_clear(buf);
+
+	if (host)
+		git_buf_printf(buf, "//%s/", host);
+
+	if (path[0] == '/')
+		path++;
+
+	if (git__isalpha(path[0]) && path[1] == ':' && path[2] == '/') {
+		git_buf_printf(buf, "%c$/", path[0]);
+		path += 3;
+	}
+
+	git_buf_puts(buf, path);
+
+	return git_buf_oom(buf) ? -1 : 0;
+}
+
+static int unc_path(git_buf *buf, const char *host, const char *path)
+{
+	char *c;
+
+	if (git_style_unc_path(buf, host, path) < 0)
+		return -1;
+
+	for (c = buf->ptr; *c; c++)
+		if (*c == '/')
+			*c = '\\';
+
+	return 0;
+}
+
+void test_clone_local__should_clone_local(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	/* we use a fixture path because it needs to exist for us to want to clone */
+	const char *path = cl_fixture("testrepo.git");
+
+	cl_git_pass(file_url(&buf, "", path));
+	cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO));
+	cl_assert_equal_i(1,  git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL));
+	cl_assert_equal_i(1,  git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS));
+	cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_NO_LOCAL));
+
+	cl_git_pass(file_url(&buf, "localhost", path));
+	cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO));
+	cl_assert_equal_i(1,  git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL));
+	cl_assert_equal_i(1,  git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS));
+	cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_NO_LOCAL));
+
+	cl_git_pass(file_url(&buf, "other-host.mycompany.com", path));
+	cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO));
+	cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL));
+	cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS));
+	cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_NO_LOCAL));
+
+	/* Ensure that file:/// urls are percent decoded: .git == %2e%67%69%74 */
+	cl_git_pass(file_url(&buf, "", path));
+	git_buf_shorten(&buf, 4);
+	cl_git_pass(git_buf_puts(&buf, "%2e%67%69%74"));
+	cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO));
+	cl_assert_equal_i(1,  git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL));
+	cl_assert_equal_i(1,  git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS));
+	cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_NO_LOCAL));
+
+	cl_assert_equal_i(1,  git_clone__should_clone_local(path, GIT_CLONE_LOCAL_AUTO));
+	cl_assert_equal_i(1,  git_clone__should_clone_local(path, GIT_CLONE_LOCAL));
+	cl_assert_equal_i(1,  git_clone__should_clone_local(path, GIT_CLONE_LOCAL_NO_LINKS));
+	cl_assert_equal_i(0, git_clone__should_clone_local(path, GIT_CLONE_NO_LOCAL));
+
+	git_buf_free(&buf);
+}
+
+void test_clone_local__hardlinks(void)
+{
+	git_repository *repo;
+	git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
+	git_buf buf = GIT_BUF_INIT;
+	struct stat st;
+
+	/*
+	 * In this first clone, we just copy over, since the temp dir
+	 * will often be in a different filesystem, so we cannot
+	 * link. It also allows us to control the number of links
+	 */
+	opts.bare = true;
+	opts.local = GIT_CLONE_LOCAL_NO_LINKS;
+	cl_git_pass(git_clone(&repo, cl_fixture("testrepo.git"), "./clone.git", &opts));
+	git_repository_free(repo);
+
+	/* This second clone is in the same filesystem, so we can hardlink */
+
+	opts.local = GIT_CLONE_LOCAL;
+	cl_git_pass(git_clone(&repo, cl_git_path_url("clone.git"), "./clone2.git", &opts));
+
+#ifndef GIT_WIN32
+	git_buf_clear(&buf);
+	cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
+
+	cl_git_pass(p_stat(buf.ptr, &st));
+	cl_assert_equal_i(2, st.st_nlink);
+#endif
+
+	git_repository_free(repo);
+	git_buf_clear(&buf);
+
+	opts.local = GIT_CLONE_LOCAL_NO_LINKS;
+	cl_git_pass(git_clone(&repo, cl_git_path_url("clone.git"), "./clone3.git", &opts));
+
+	git_buf_clear(&buf);
+	cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
+
+	cl_git_pass(p_stat(buf.ptr, &st));
+	cl_assert_equal_i(1, st.st_nlink);
+
+	git_repository_free(repo);
+
+	/* this one should automatically use links */
+	cl_git_pass(git_clone(&repo, "./clone.git", "./clone4.git", NULL));
+
+#ifndef GIT_WIN32
+	git_buf_clear(&buf);
+	cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
+
+	cl_git_pass(p_stat(buf.ptr, &st));
+	cl_assert_equal_i(3, st.st_nlink);
+#endif
+
+	git_buf_free(&buf);
+	git_repository_free(repo);
+
+	cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES));
+	cl_git_pass(git_futils_rmdir_r("./clone2.git", NULL, GIT_RMDIR_REMOVE_FILES));
+	cl_git_pass(git_futils_rmdir_r("./clone3.git", NULL, GIT_RMDIR_REMOVE_FILES));
+	cl_git_pass(git_futils_rmdir_r("./clone4.git", NULL, GIT_RMDIR_REMOVE_FILES));
+}
+
+void test_clone_local__standard_unc_paths_are_written_git_style(void)
+{
+#ifdef GIT_WIN32
+	git_repository *repo;
+	git_remote *remote;
+	git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
+	git_buf unc = GIT_BUF_INIT, git_unc = GIT_BUF_INIT;
+
+	/* we use a fixture path because it needs to exist for us to want to clone */
+	const char *path = cl_fixture("testrepo.git");
+
+	cl_git_pass(unc_path(&unc, "localhost", path));
+	cl_git_pass(git_style_unc_path(&git_unc, "localhost", path));
+
+	cl_git_pass(git_clone(&repo, unc.ptr, "./clone.git", &opts));
+	cl_git_pass(git_remote_lookup(&remote, repo, "origin"));
+
+	cl_assert_equal_s(git_unc.ptr, git_remote_url(remote));
+
+	git_remote_free(remote);
+	git_repository_free(repo);
+	git_buf_free(&unc);
+	git_buf_free(&git_unc);
+
+	cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES));
+#endif
+}
+
+void test_clone_local__git_style_unc_paths(void)
+{
+#ifdef GIT_WIN32
+	git_repository *repo;
+	git_remote *remote;
+	git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
+	git_buf git_unc = GIT_BUF_INIT;
+
+	/* we use a fixture path because it needs to exist for us to want to clone */
+	const char *path = cl_fixture("testrepo.git");
+
+	cl_git_pass(git_style_unc_path(&git_unc, "localhost", path));
+
+	cl_git_pass(git_clone(&repo, git_unc.ptr, "./clone.git", &opts));
+	cl_git_pass(git_remote_lookup(&remote, repo, "origin"));
+
+	cl_assert_equal_s(git_unc.ptr, git_remote_url(remote));
+
+	git_remote_free(remote);
+	git_repository_free(repo);
+	git_buf_free(&git_unc);
+
+	cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES));
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clone/nonetwork.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clone/nonetwork.c
new file mode 100755
index 0000000..44a5038
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clone/nonetwork.c
@@ -0,0 +1,404 @@
+#include "clar_libgit2.h"
+
+#include "git2/clone.h"
+#include "git2/sys/commit.h"
+#include "../submodule/submodule_helpers.h"
+#include "remote.h"
+#include "fileops.h"
+#include "repository.h"
+
+#define LIVE_REPO_URL "git://github.com/libgit2/TestGitRepository"
+
+static git_clone_options g_options;
+static git_repository *g_repo;
+static git_reference* g_ref;
+static git_remote* g_remote;
+
+void test_clone_nonetwork__initialize(void)
+{
+	git_checkout_options dummy_opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_fetch_options dummy_fetch = GIT_FETCH_OPTIONS_INIT;
+
+	g_repo = NULL;
+
+	memset(&g_options, 0, sizeof(git_clone_options));
+	g_options.version = GIT_CLONE_OPTIONS_VERSION;
+	g_options.checkout_opts = dummy_opts;
+	g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+	g_options.fetch_opts = dummy_fetch;
+}
+
+void test_clone_nonetwork__cleanup(void)
+{
+	if (g_repo) {
+		git_repository_free(g_repo);
+		g_repo = NULL;
+	}
+
+	if (g_ref) {
+		git_reference_free(g_ref);
+		g_ref = NULL;
+	}
+
+	if (g_remote) {
+		git_remote_free(g_remote);
+		g_remote = NULL;
+	}
+
+	cl_fixture_cleanup("./foo");
+}
+
+void test_clone_nonetwork__bad_urls(void)
+{
+	/* Clone should clean up the mess if the URL isn't a git repository */
+	cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options));
+	cl_assert(!git_path_exists("./foo"));
+	g_options.bare = true;
+	cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options));
+	cl_assert(!git_path_exists("./foo"));
+
+	cl_git_fail(git_clone(&g_repo, "git://example.com:asdf", "./foo", &g_options));
+	cl_git_fail(git_clone(&g_repo, "https://example.com:asdf/foo", "./foo", &g_options));
+	cl_git_fail(git_clone(&g_repo, "git://github.com/git://github.com/foo/bar.git.git",
+				"./foo", &g_options));
+	cl_git_fail(git_clone(&g_repo, "arrbee:my/bad:password at github.com:1111/strange:words.git",
+				"./foo", &g_options));
+}
+
+void test_clone_nonetwork__do_not_clean_existing_directory(void)
+{
+	/* Clone should not remove the directory if it already exists, but
+	 * Should clean up entries it creates. */
+	p_mkdir("./foo", GIT_DIR_MODE);
+	cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options));
+	cl_assert(git_path_is_empty_dir("./foo"));
+
+	/* Try again with a bare repository. */
+	g_options.bare = true;
+	cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options));
+	cl_assert(git_path_is_empty_dir("./foo"));
+}
+
+void test_clone_nonetwork__local(void)
+{
+	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+}
+
+void test_clone_nonetwork__local_absolute_path(void)
+{
+	const char *local_src;
+	local_src = cl_fixture("testrepo.git");
+	cl_git_pass(git_clone(&g_repo, local_src, "./foo", &g_options));
+}
+
+void test_clone_nonetwork__local_bare(void)
+{
+	g_options.bare = true;
+	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+}
+
+void test_clone_nonetwork__fail_when_the_target_is_a_file(void)
+{
+	cl_git_mkfile("./foo", "Bar!");
+	cl_git_fail(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+}
+
+void test_clone_nonetwork__fail_with_already_existing_but_non_empty_directory(void)
+{
+	p_mkdir("./foo", GIT_DIR_MODE);
+	cl_git_mkfile("./foo/bar", "Baz!");
+	cl_git_fail(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+}
+
+int custom_origin_name_remote_create(
+	git_remote **out,
+	git_repository *repo,
+	const char *name,
+	const char *url,
+	void *payload)
+{
+	GIT_UNUSED(name);
+	GIT_UNUSED(payload);
+
+	return git_remote_create(out, repo, "my_origin", url);
+}
+
+void test_clone_nonetwork__custom_origin_name(void)
+{
+	g_options.remote_cb = custom_origin_name_remote_create;
+	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+
+	cl_git_pass(git_remote_lookup(&g_remote, g_repo, "my_origin"));
+}
+
+void test_clone_nonetwork__defaults(void)
+{
+	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", NULL));
+	cl_assert(g_repo);
+	cl_git_pass(git_remote_lookup(&g_remote, g_repo, "origin"));
+}
+
+void test_clone_nonetwork__cope_with_already_existing_directory(void)
+{
+	p_mkdir("./foo", GIT_DIR_MODE);
+	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+}
+
+void test_clone_nonetwork__can_prevent_the_checkout_of_a_standard_repo(void)
+{
+	git_buf path = GIT_BUF_INIT;
+
+	g_options.checkout_opts.checkout_strategy = 0;
+	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+
+	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "master.txt"));
+	cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&path)));
+
+	git_buf_free(&path);
+}
+
+void test_clone_nonetwork__can_checkout_given_branch(void)
+{
+	g_options.checkout_branch = "test";
+	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+
+	cl_assert_equal_i(0, git_repository_head_unborn(g_repo));
+
+	cl_git_pass(git_repository_head(&g_ref, g_repo));
+	cl_assert_equal_s(git_reference_name(g_ref), "refs/heads/test");
+
+	cl_assert(git_path_exists("foo/readme.txt"));
+}
+
+static int clone_cancel_fetch_transfer_progress_cb(
+	const git_transfer_progress *stats, void *data)
+{
+	GIT_UNUSED(stats); GIT_UNUSED(data);
+	return -54321;
+}
+
+void test_clone_nonetwork__can_cancel_clone_in_fetch(void)
+{
+	g_options.checkout_branch = "test";
+
+	g_options.fetch_opts.callbacks.transfer_progress =
+		clone_cancel_fetch_transfer_progress_cb;
+
+	cl_git_fail_with(git_clone(
+		&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options),
+		-54321);
+
+	cl_assert(!g_repo);
+	cl_assert(!git_path_exists("foo/readme.txt"));
+}
+
+static int clone_cancel_checkout_cb(
+	git_checkout_notify_t why,
+	const char *path,
+	const git_diff_file *b,
+	const git_diff_file *t,
+	const git_diff_file *w,
+	void *payload)
+{
+	const char *at_file = payload;
+	GIT_UNUSED(why); GIT_UNUSED(b); GIT_UNUSED(t); GIT_UNUSED(w);
+	if (!strcmp(path, at_file))
+		return -12345;
+	return 0;
+}
+
+void test_clone_nonetwork__can_cancel_clone_in_checkout(void)
+{
+	g_options.checkout_branch = "test";
+
+	g_options.checkout_opts.notify_flags = GIT_CHECKOUT_NOTIFY_UPDATED;
+	g_options.checkout_opts.notify_cb = clone_cancel_checkout_cb;
+	g_options.checkout_opts.notify_payload = "readme.txt";
+
+	cl_git_fail_with(git_clone(
+		&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options),
+		-12345);
+
+	cl_assert(!g_repo);
+	cl_assert(!git_path_exists("foo/readme.txt"));
+}
+
+void test_clone_nonetwork__can_detached_head(void)
+{
+	git_object *obj;
+	git_repository *cloned;
+	git_reference *cloned_head;
+
+	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+
+	cl_git_pass(git_revparse_single(&obj, g_repo, "master~1"));
+	cl_git_pass(git_repository_set_head_detached(g_repo, git_object_id(obj)));
+
+	cl_git_pass(git_clone(&cloned, "./foo", "./foo1", &g_options));
+
+	cl_assert(git_repository_head_detached(cloned));
+
+	cl_git_pass(git_repository_head(&cloned_head, cloned));
+	cl_assert_equal_oid(git_object_id(obj), git_reference_target(cloned_head));
+
+	git_object_free(obj);
+	git_reference_free(cloned_head);
+	git_repository_free(cloned);
+
+	cl_fixture_cleanup("./foo1");
+}
+
+void test_clone_nonetwork__clone_tag_to_tree(void)
+{
+	git_repository *stage;
+	git_index_entry entry;
+	git_index *index;
+	git_odb *odb;
+	git_oid tree_id;
+	git_tree *tree;
+	git_reference *tag;
+	git_tree_entry *tentry;
+	const char *file_path = "some/deep/path.txt";
+	const char *file_content = "some content\n";
+	const char *tag_name = "refs/tags/tree-tag";
+
+	stage = cl_git_sandbox_init("testrepo.git");
+	cl_git_pass(git_repository_odb(&odb, stage));
+	cl_git_pass(git_index_new(&index));
+
+	memset(&entry, 0, sizeof(git_index_entry));
+	entry.path = file_path;
+	entry.mode = GIT_FILEMODE_BLOB;
+	cl_git_pass(git_odb_write(&entry.id, odb, file_content, strlen(file_content), GIT_OBJ_BLOB));
+
+	cl_git_pass(git_index_add(index, &entry));
+	cl_git_pass(git_index_write_tree_to(&tree_id, index, stage));
+	cl_git_pass(git_reference_create(&tag, stage, tag_name, &tree_id, 0, NULL));
+	git_reference_free(tag);
+	git_odb_free(odb);
+	git_index_free(index);
+
+	g_options.local = GIT_CLONE_NO_LOCAL;
+	cl_git_pass(git_clone(&g_repo, cl_git_path_url(git_repository_path(stage)), "./foo", &g_options));
+	git_repository_free(stage);
+
+	cl_git_pass(git_reference_lookup(&tag, g_repo, tag_name));
+	cl_git_pass(git_tree_lookup(&tree, g_repo, git_reference_target(tag)));
+	git_reference_free(tag);
+
+	cl_git_pass(git_tree_entry_bypath(&tentry, tree, file_path));
+	git_tree_entry_free(tentry);
+	git_tree_free(tree);
+
+	cl_fixture_cleanup("testrepo.git");
+}
+
+static void assert_correct_reflog(const char *name)
+{
+	git_reflog *log;
+	const git_reflog_entry *entry;
+	char expected_log_message[128] = {0};
+
+	sprintf(expected_log_message, "clone: from %s", cl_git_fixture_url("testrepo.git"));
+
+	cl_git_pass(git_reflog_read(&log, g_repo, name));
+	cl_assert_equal_i(1, git_reflog_entrycount(log));
+	entry = git_reflog_entry_byindex(log, 0);
+	cl_assert_equal_s(expected_log_message, git_reflog_entry_message(entry));
+
+	git_reflog_free(log);
+}
+
+void test_clone_nonetwork__clone_updates_reflog_properly(void)
+{
+	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+	assert_correct_reflog("HEAD");
+	assert_correct_reflog("refs/heads/master");
+}
+
+static void cleanup_repository(void *path)
+{
+	if (g_repo) {
+		git_repository_free(g_repo);
+		g_repo = NULL;
+	}
+
+	cl_fixture_cleanup((const char *)path);
+}
+
+void test_clone_nonetwork__clone_from_empty_sets_upstream(void)
+{
+	git_config *config;
+	git_repository *repo;
+	const char *str;
+
+	/* Create an empty repo to clone from */
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+	cl_set_cleanup(&cleanup_repository, "./repowithunborn");
+	cl_git_pass(git_clone(&repo, "./test1", "./repowithunborn", NULL));
+
+	cl_git_pass(git_repository_config_snapshot(&config, repo));
+
+	cl_git_pass(git_config_get_string(&str, config, "branch.master.remote"));
+	cl_assert_equal_s("origin", str);
+	cl_git_pass(git_config_get_string(&str, config, "branch.master.merge"));
+	cl_assert_equal_s("refs/heads/master", str);
+
+	git_config_free(config);
+	git_repository_free(repo);
+	cl_fixture_cleanup("./repowithunborn");
+}
+
+static int just_return_origin(git_remote **out, git_repository *repo, const char *name, const char *url, void *payload)
+{
+	GIT_UNUSED(url); GIT_UNUSED(payload);
+
+	return git_remote_lookup(out, repo, name);
+}
+
+static int just_return_repo(git_repository **out, const char *path, int bare, void *payload)
+{
+	git_submodule *sm = payload;
+
+	GIT_UNUSED(path); GIT_UNUSED(bare);
+
+	return git_submodule_open(out, sm);
+}
+
+void test_clone_nonetwork__clone_submodule(void)
+{
+	git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
+	git_index *index;
+	git_oid tree_id, commit_id;
+	git_submodule *sm;
+	git_signature *sig;
+	git_repository *sm_repo;
+
+	cl_git_pass(git_repository_init(&g_repo, "willaddsubmodule", false));
+
+
+	/* Create the submodule structure, clone into it and finalize */
+	cl_git_pass(git_submodule_add_setup(&sm, g_repo, cl_fixture("testrepo.git"), "testrepo", true));
+
+	clone_opts.repository_cb = just_return_repo;
+	clone_opts.repository_cb_payload = sm;
+	clone_opts.remote_cb = just_return_origin;
+	clone_opts.remote_cb_payload = sm;
+	cl_git_pass(git_clone(&sm_repo, cl_fixture("testrepo.git"), "testrepo", &clone_opts));
+	cl_git_pass(git_submodule_add_finalize(sm));
+	git_repository_free(sm_repo);
+	git_submodule_free(sm);
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_write_tree(&tree_id, index));
+	git_index_free(index);
+
+	cl_git_pass(git_signature_now(&sig, "Submoduler", "submoduler at local"));
+	cl_git_pass(git_commit_create_from_ids(&commit_id, g_repo, "HEAD", sig, sig, NULL, "A submodule\n",
+					       &tree_id, 0, NULL));
+
+	git_signature_free(sig);
+
+	assert_submodule_exists(g_repo, "testrepo");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clone/transport.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clone/transport.c
new file mode 100755
index 0000000..cccaae2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/clone/transport.c
@@ -0,0 +1,51 @@
+#include "clar_libgit2.h"
+
+#include "git2/clone.h"
+#include "git2/transport.h"
+#include "git2/sys/transport.h"
+#include "fileops.h"
+
+static int custom_transport(
+	git_transport **out,
+	git_remote *owner,
+	void *payload)
+{
+	*((int*)payload) = 1;
+
+	return git_transport_local(out, owner, payload);
+}
+
+static int custom_transport_remote_create(
+	git_remote **out,
+	git_repository *repo,
+	const char *name,
+	const char *url,
+	void *payload)
+{
+	int error;
+
+	GIT_UNUSED(payload);
+
+	if ((error = git_remote_create(out, repo, name, url)) < 0)
+		return error;
+
+	return 0;
+}
+
+void test_clone_transport__custom_transport(void)
+{
+	git_repository *repo;
+	git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
+	int custom_transport_used = 0;
+
+	clone_opts.remote_cb = custom_transport_remote_create;
+	clone_opts.fetch_opts.callbacks.transport = custom_transport;
+	clone_opts.fetch_opts.callbacks.payload = &custom_transport_used;
+
+	cl_git_pass(git_clone(&repo, cl_fixture("testrepo.git"), "./custom_transport.git", &clone_opts));
+	git_repository_free(repo);
+
+	cl_git_pass(git_futils_rmdir_r("./custom_transport.git", NULL, GIT_RMDIR_REMOVE_FILES));
+
+	cl_assert(custom_transport_used == 1);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/commit/commit.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/commit/commit.c
new file mode 100755
index 0000000..f5461cf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/commit/commit.c
@@ -0,0 +1,83 @@
+#include "clar_libgit2.h"
+#include "commit.h"
+#include "git2/commit.h"
+
+static git_repository *_repo;
+
+void test_commit_commit__initialize(void)
+{
+	cl_fixture_sandbox("testrepo.git");
+	cl_git_pass(git_repository_open(&_repo, "testrepo.git"));
+}
+
+void test_commit_commit__cleanup(void)
+{
+	git_repository_free(_repo);
+	_repo = NULL;
+
+	cl_fixture_cleanup("testrepo.git");
+}
+
+void test_commit_commit__create_unexisting_update_ref(void)
+{
+	git_oid oid;
+	git_tree *tree;
+	git_commit *commit;
+	git_signature *s;
+	git_reference *ref;
+
+	git_oid_fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	cl_git_pass(git_commit_lookup(&commit, _repo, &oid));
+
+	git_oid_fromstr(&oid, "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162");
+	cl_git_pass(git_tree_lookup(&tree, _repo, &oid));
+
+	cl_git_pass(git_signature_now(&s, "alice", "alice at example.com"));
+
+	cl_git_fail(git_reference_lookup(&ref, _repo, "refs/heads/foo/bar"));
+	cl_git_pass(git_commit_create(&oid, _repo, "refs/heads/foo/bar", s, s,
+				      NULL, "some msg", tree, 1, (const git_commit **) &commit));
+
+	/* fail because the parent isn't the tip of the branch anymore */
+	cl_git_fail(git_commit_create(&oid, _repo, "refs/heads/foo/bar", s, s,
+				      NULL, "some msg", tree, 1, (const git_commit **) &commit));
+
+	cl_git_pass(git_reference_lookup(&ref, _repo, "refs/heads/foo/bar"));
+	cl_assert_equal_oid(&oid, git_reference_target(ref));
+
+	git_tree_free(tree);
+	git_commit_free(commit);
+	git_signature_free(s);
+	git_reference_free(ref);
+}
+
+void assert_commit_summary(const char *expected, const char *given)
+{
+	git_commit *dummy;
+
+	cl_assert(dummy = git__calloc(1, sizeof(struct git_commit)));
+
+	dummy->raw_message = git__strdup(given);
+	cl_assert_equal_s(expected, git_commit_summary(dummy));
+
+	git_commit__free(dummy);
+}
+
+void test_commit_commit__summary(void)
+{
+	assert_commit_summary("One-liner with no trailing newline", "One-liner with no trailing newline");
+	assert_commit_summary("One-liner with trailing newline", "One-liner with trailing newline\n");
+	assert_commit_summary("Trimmed leading&trailing newlines", "\n\nTrimmed leading&trailing newlines\n\n");
+	assert_commit_summary("First paragraph only", "\nFirst paragraph only\n\n(There are more!)");
+	assert_commit_summary("First paragraph with  unwrapped trailing\tlines", "\nFirst paragraph\nwith  unwrapped\ntrailing\tlines\n\n(Yes, unwrapped!)");
+	assert_commit_summary("\tLeading \ttabs", "\tLeading\n\ttabs\n\nis preserved");
+	assert_commit_summary(" Leading  Spaces", " Leading\n Spaces\n\nare preserved");
+	assert_commit_summary("Trailing tabs\tare removed", "Trailing tabs\tare removed\t\t");
+	assert_commit_summary("Trailing spaces  are removed", "Trailing spaces  are removed  ");
+	assert_commit_summary("Trailing tabs", "Trailing tabs\t\n\nare removed");
+	assert_commit_summary("Trailing spaces", "Trailing spaces \n\nare removed");
+	assert_commit_summary("", "");
+	assert_commit_summary("", " ");
+	assert_commit_summary("", "\n");
+	assert_commit_summary("", "\n \n");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/commit/parent.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/commit/parent.c
new file mode 100755
index 0000000..18ce0bb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/commit/parent.c
@@ -0,0 +1,60 @@
+#include "clar_libgit2.h"
+
+static git_repository *_repo;
+static git_commit *commit;
+
+void test_commit_parent__initialize(void)
+{
+	git_oid oid;
+
+	cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git")));
+
+	git_oid_fromstr(&oid, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	cl_git_pass(git_commit_lookup(&commit, _repo, &oid));
+}
+
+void test_commit_parent__cleanup(void)
+{
+	git_commit_free(commit);
+	commit = NULL;
+
+	git_repository_free(_repo);
+	_repo = NULL;
+}
+
+static void assert_nth_gen_parent(unsigned int gen, const char *expected_oid)
+{
+	git_commit *parent = NULL;
+	int error;
+	
+	error = git_commit_nth_gen_ancestor(&parent, commit, gen);
+
+	if (expected_oid != NULL) {
+		cl_assert_equal_i(0, error);
+		cl_assert_equal_i(0, git_oid_streq(git_commit_id(parent), expected_oid));
+	} else
+		cl_assert_equal_i(GIT_ENOTFOUND, error);
+
+	git_commit_free(parent);
+}
+
+/*
+ * $ git show be35~0
+ * commit be3563ae3f795b2b4353bcce3a527ad0a4f7f644
+ *
+ * $ git show be35~1
+ * commit 9fd738e8f7967c078dceed8190330fc8648ee56a
+ *
+ * $ git show be35~3
+ * commit 5b5b025afb0b4c913b4c338a42934a3863bf3644
+ *
+ * $ git show be35~42
+ * fatal: ambiguous argument 'be35~42': unknown revision or path not in the working tree.
+ */
+void test_commit_parent__can_retrieve_nth_generation_parent(void)
+{
+	assert_nth_gen_parent(0, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	assert_nth_gen_parent(1, "9fd738e8f7967c078dceed8190330fc8648ee56a");
+	assert_nth_gen_parent(3, "5b5b025afb0b4c913b4c338a42934a3863bf3644");
+	assert_nth_gen_parent(42, NULL);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/commit/parse.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/commit/parse.c
new file mode 100755
index 0000000..388da07
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/commit/parse.c
@@ -0,0 +1,458 @@
+#include "clar_libgit2.h"
+#include <git2/types.h>
+#include "commit.h"
+#include "signature.h"
+
+// Fixture setup
+static git_repository *g_repo;
+void test_commit_parse__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo");
+}
+void test_commit_parse__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+
+// Header parsing
+typedef struct {
+	const char *line;
+	const char *header;
+} parse_test_case;
+
+static parse_test_case passing_header_cases[] = {
+	{ "parent 05452d6349abcd67aa396dfb28660d765d8b2a36\n", "parent " },
+	{ "tree 05452d6349abcd67aa396dfb28660d765d8b2a36\n", "tree " },
+	{ "random_heading 05452d6349abcd67aa396dfb28660d765d8b2a36\n", "random_heading " },
+	{ "stuck_heading05452d6349abcd67aa396dfb28660d765d8b2a36\n", "stuck_heading" },
+	{ "tree 5F4BEFFC0759261D015AA63A3A85613FF2F235DE\n", "tree " },
+	{ "tree 1A669B8AB81B5EB7D9DB69562D34952A38A9B504\n", "tree " },
+	{ "tree 5B20DCC6110FCC75D31C6CEDEBD7F43ECA65B503\n", "tree " },
+	{ "tree 173E7BF00EA5C33447E99E6C1255954A13026BE4\n", "tree " },
+	{ NULL, NULL }
+};
+
+static parse_test_case failing_header_cases[] = {
+	{ "parent 05452d6349abcd67aa396dfb28660d765d8b2a36", "parent " },
+	{ "05452d6349abcd67aa396dfb28660d765d8b2a36\n", "tree " },
+	{ "parent05452d6349abcd67aa396dfb28660d765d8b2a6a\n", "parent " },
+	{ "parent 05452d6349abcd67aa396dfb280d765d8b2a6\n", "parent " },
+	{ "tree  05452d6349abcd67aa396dfb28660d765d8b2a36\n", "tree " },
+	{ "parent 0545xd6349abcd67aa396dfb28660d765d8b2a36\n", "parent " },
+	{ "parent 0545xd6349abcd67aa396dfb28660d765d8b2a36FF\n", "parent " },
+	{ "", "tree " },
+	{ "", "" },
+	{ NULL, NULL }
+};
+
+void test_commit_parse__header(void)
+{
+	git_oid oid;
+
+	parse_test_case *testcase;
+	for (testcase = passing_header_cases; testcase->line != NULL; testcase++)
+	{
+		const char *line = testcase->line;
+		const char *line_end = line + strlen(line);
+
+		cl_git_pass(git_oid__parse(&oid, &line, line_end, testcase->header));
+		cl_assert(line == line_end);
+	}
+
+	for (testcase = failing_header_cases; testcase->line != NULL; testcase++)
+	{
+		const char *line = testcase->line;
+		const char *line_end = line + strlen(line);
+
+		cl_git_fail(git_oid__parse(&oid, &line, line_end, testcase->header));
+	}
+}
+
+
+// Signature parsing
+typedef struct {
+	const char *string;
+	const char *header;
+	const char *name;
+	const char *email;
+	git_time_t time;
+	int offset;
+} passing_signature_test_case;
+
+passing_signature_test_case passing_signature_cases[] = {
+	{"author Vicent Marti <tanoku at gmail.com> 12345 \n", "author ", "Vicent Marti", "tanoku at gmail.com", 12345, 0},
+	{"author Vicent Marti <> 12345 \n", "author ", "Vicent Marti", "", 12345, 0},
+	{"author Vicent Marti <tanoku at gmail.com> 231301 +1020\n", "author ", "Vicent Marti", "tanoku at gmail.com", 231301, 620},
+	{"author Vicent Marti with an outrageously long name which will probably overflow the buffer <tanoku at gmail.com> 12345 \n", "author ", "Vicent Marti with an outrageously long name which will probably overflow the buffer", "tanoku at gmail.com", 12345, 0},
+	{"author Vicent Marti <tanokuwithaveryveryverylongemailwhichwillprobablyvoverflowtheemailbuffer at gmail.com> 12345 \n", "author ", "Vicent Marti", "tanokuwithaveryveryverylongemailwhichwillprobablyvoverflowtheemailbuffer at gmail.com", 12345, 0},
+	{"committer Vicent Marti <tanoku at gmail.com> 123456 +0000 \n", "committer ", "Vicent Marti", "tanoku at gmail.com", 123456, 0},
+	{"committer Vicent Marti <tanoku at gmail.com> 123456 +0100 \n", "committer ", "Vicent Marti", "tanoku at gmail.com", 123456, 60},
+	{"committer Vicent Marti <tanoku at gmail.com> 123456 -0100 \n", "committer ", "Vicent Marti", "tanoku at gmail.com", 123456, -60},
+	// Parse a signature without an author field
+	{"committer <tanoku at gmail.com> 123456 -0100 \n", "committer ", "", "tanoku at gmail.com", 123456, -60},
+	// Parse a signature without an author field
+	{"committer  <tanoku at gmail.com> 123456 -0100 \n", "committer ", "", "tanoku at gmail.com", 123456, -60},
+	// Parse a signature with an empty author field
+	{"committer   <tanoku at gmail.com> 123456 -0100 \n", "committer ", "", "tanoku at gmail.com", 123456, -60},
+	// Parse a signature with an empty email field
+	{"committer Vicent Marti <> 123456 -0100 \n", "committer ", "Vicent Marti", "", 123456, -60},
+	// Parse a signature with an empty email field
+	{"committer Vicent Marti < > 123456 -0100 \n", "committer ", "Vicent Marti", "", 123456, -60},
+	// Parse a signature with empty name and email
+	{"committer <> 123456 -0100 \n", "committer ", "", "", 123456, -60},
+	// Parse a signature with empty name and email
+	{"committer  <> 123456 -0100 \n", "committer ", "", "", 123456, -60},
+	// Parse a signature with empty name and email
+	{"committer  < > 123456 -0100 \n", "committer ", "", "", 123456, -60},
+	// Parse an obviously invalid signature
+	{"committer foo<@bar> 123456 -0100 \n", "committer ", "foo", "@bar", 123456, -60},
+	// Parse an obviously invalid signature
+	{"committer    foo<@bar> 123456 -0100 \n", "committer ", "foo", "@bar", 123456, -60},
+	// Parse an obviously invalid signature
+	{"committer <>\n", "committer ", "", "", 0, 0},
+	{"committer Vicent Marti <tanoku at gmail.com> 123456 -1500 \n", "committer ", "Vicent Marti", "tanoku at gmail.com", 123456, 0},
+	{"committer Vicent Marti <tanoku at gmail.com> 123456 +0163 \n", "committer ", "Vicent Marti", "tanoku at gmail.com", 123456, 0},
+	{"author Vicent Marti <tanoku at gmail.com>\n", "author ", "Vicent Marti", "tanoku at gmail.com", 0, 0},
+	/* a variety of dates */
+	{"author Vicent Marti <tanoku at gmail.com> 0 \n", "author ", "Vicent Marti", "tanoku at gmail.com", 0, 0},
+	{"author Vicent Marti <tanoku at gmail.com> 1234567890 \n", "author ", "Vicent Marti", "tanoku at gmail.com", 1234567890, 0},
+	{"author Vicent Marti <tanoku at gmail.com> 2147483647 \n", "author ", "Vicent Marti", "tanoku at gmail.com", 0x7fffffff, 0},
+	{"author Vicent Marti <tanoku at gmail.com> 4294967295 \n", "author ", "Vicent Marti", "tanoku at gmail.com", 0xffffffff, 0},
+	{"author Vicent Marti <tanoku at gmail.com> 4294967296 \n", "author ", "Vicent Marti", "tanoku at gmail.com", 4294967296, 0},
+	{"author Vicent Marti <tanoku at gmail.com> 8589934592 \n", "author ", "Vicent Marti", "tanoku at gmail.com", 8589934592, 0},
+
+	{NULL,NULL,NULL,NULL,0,0}
+};
+
+typedef struct {
+	const char *string;
+	const char *header;
+} failing_signature_test_case;
+
+failing_signature_test_case failing_signature_cases[] = {
+	{"committer Vicent Marti tanoku at gmail.com> 123456 -0100 \n", "committer "},
+	{"author Vicent Marti <tanoku at gmail.com> 12345 \n", "author  "},
+	{"author Vicent Marti <tanoku at gmail.com> 12345 \n", "committer "},
+	{"author Vicent Marti 12345 \n", "author "},
+	{"author Vicent Marti <broken at email 12345 \n", "author "},
+	{"committer Vicent Marti ><\n", "committer "},
+	{"author ", "author "},
+	{NULL, NULL,}
+};
+
+void test_commit_parse__signature(void)
+{
+	passing_signature_test_case *passcase;
+	failing_signature_test_case *failcase;
+
+	for (passcase = passing_signature_cases; passcase->string != NULL; passcase++)
+	{
+		const char *str = passcase->string;
+		size_t len = strlen(passcase->string);
+		struct git_signature person = {0};
+
+		cl_git_pass(git_signature__parse(&person, &str, str + len, passcase->header, '\n'));
+		cl_assert_equal_s(passcase->name, person.name);
+		cl_assert_equal_s(passcase->email, person.email);
+		cl_assert_equal_i((int)passcase->time, (int)person.when.time);
+		cl_assert_equal_i(passcase->offset, person.when.offset);
+		git__free(person.name); git__free(person.email);
+	}
+
+	for (failcase = failing_signature_cases; failcase->string != NULL; failcase++)
+	{
+		const char *str = failcase->string;
+		size_t len = strlen(failcase->string);
+		git_signature person = {0};
+		cl_git_fail(git_signature__parse(&person, &str, str + len, failcase->header, '\n'));
+		git__free(person.name); git__free(person.email);
+	}
+}
+
+
+
+static char *failing_commit_cases[] = {
+// empty commit
+"",
+// random garbage
+"asd97sa9du902e9a0jdsuusad09as9du098709aweu8987sd\n",
+// broken endlines 1
+"tree f6c0dad3c7b3481caa9d73db21f91964894a945b\r\n\
+parent 05452d6349abcd67aa396dfb28660d765d8b2a36\r\n\
+author Vicent Marti <tanoku at gmail.com> 1273848544 +0200\r\n\
+committer Vicent Marti <tanoku at gmail.com> 1273848544 +0200\r\n\
+\r\n\
+a test commit with broken endlines\r\n",
+// broken endlines 2
+"tree f6c0dad3c7b3481caa9d73db21f91964894a945b\
+parent 05452d6349abcd67aa396dfb28660d765d8b2a36\
+author Vicent Marti <tanoku at gmail.com> 1273848544 +0200\
+committer Vicent Marti <tanoku at gmail.com> 1273848544 +0200\
+\
+another test commit with broken endlines",
+// starting endlines
+"\ntree f6c0dad3c7b3481caa9d73db21f91964894a945b\n\
+parent 05452d6349abcd67aa396dfb28660d765d8b2a36\n\
+author Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+committer Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+\n\
+a test commit with a starting endline\n",
+// corrupted commit 1
+"tree f6c0dad3c7b3481caa9d73db21f91964894a945b\n\
+parent 05452d6349abcd67aa396df",
+// corrupted commit 2
+"tree f6c0dad3c7b3481caa9d73db21f91964894a945b\n\
+parent ",
+// corrupted commit 3
+"tree f6c0dad3c7b3481caa9d73db21f91964894a945b\n\
+parent ",
+// corrupted commit 4
+"tree f6c0dad3c7b3481caa9d73db21f91964894a945b\n\
+par",
+};
+
+
+static char *passing_commit_cases[] = {
+// simple commit with no message
+"tree 1810dff58d8a660512d4832e740f692884338ccd\n\
+author Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+committer Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+\n",
+// simple commit, no parent
+"tree 1810dff58d8a660512d4832e740f692884338ccd\n\
+author Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+committer Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+\n\
+a simple commit which works\n",
+// simple commit, no parent, no newline in message
+"tree 1810dff58d8a660512d4832e740f692884338ccd\n\
+author Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+committer Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+\n\
+a simple commit which works",
+// simple commit, 1 parent
+"tree 1810dff58d8a660512d4832e740f692884338ccd\n\
+parent e90810b8df3e80c413d903f631643c716887138d\n\
+author Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+committer Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+\n\
+a simple commit which works\n",
+/* simple commit with GPG signature */
+"tree 6b79e22d69bf46e289df0345a14ca059dfc9bdf6\n\
+parent 34734e478d6cf50c27c9d69026d93974d052c454\n\
+author Ben Burkert <ben at benburkert.com> 1358451456 -0800\n\
+committer Ben Burkert <ben at benburkert.com> 1358451456 -0800\n\
+gpgsig -----BEGIN PGP SIGNATURE-----\n\
+ Version: GnuPG v1.4.12 (Darwin)\n\
+ \n\
+ iQIcBAABAgAGBQJQ+FMIAAoJEH+LfPdZDSs1e3EQAJMjhqjWF+WkGLHju7pTw2al\n\
+ o6IoMAhv0Z/LHlWhzBd9e7JeCnanRt12bAU7yvYp9+Z+z+dbwqLwDoFp8LVuigl8\n\
+ JGLcnwiUW3rSvhjdCp9irdb4+bhKUnKUzSdsR2CK4/hC0N2i/HOvMYX+BRsvqweq\n\
+ AsAkA6dAWh+gAfedrBUkCTGhlNYoetjdakWqlGL1TiKAefEZrtA1TpPkGn92vbLq\n\
+ SphFRUY9hVn1ZBWrT3hEpvAIcZag3rTOiRVT1X1flj8B2vGCEr3RrcwOIZikpdaW\n\
+ who/X3xh/DGbI2RbuxmmJpxxP/8dsVchRJJzBwG+yhwU/iN3MlV2c5D69tls/Dok\n\
+ 6VbyU4lm/ae0y3yR83D9dUlkycOnmmlBAHKIZ9qUts9X7mWJf0+yy2QxJVpjaTGG\n\
+ cmnQKKPeNIhGJk2ENnnnzjEve7L7YJQF6itbx5VCOcsGh3Ocb3YR7DMdWjt7f8pu\n\
+ c6j+q1rP7EpE2afUN/geSlp5i3x8aXZPDj67jImbVCE/Q1X9voCtyzGJH7MXR0N9\n\
+ ZpRF8yzveRfMH8bwAJjSOGAFF5XkcR/RNY95o+J+QcgBLdX48h+ZdNmUf6jqlu3J\n\
+ 7KmTXXQcOVpN6dD3CmRFsbjq+x6RHwa8u1iGn+oIkX908r97ckfB/kHKH7ZdXIJc\n\
+ cpxtDQQMGYFpXK/71stq\n\
+ =ozeK\n\
+ -----END PGP SIGNATURE-----\n\
+\n\
+a simple commit which works\n",
+/* some tools create two author entries */
+"tree 1810dff58d8a660512d4832e740f692884338ccd\n\
+author Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+author Helpful Coworker <helpful at coworker> 1273848544 +0200\n\
+committer Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+\n\
+a simple commit which works",
+};
+
+static int parse_commit(git_commit **out, const char *buffer)
+{
+	git_commit *commit;
+	git_odb_object fake_odb_object;
+	int error;
+
+	commit = (git_commit*)git__malloc(sizeof(git_commit));
+	memset(commit, 0x0, sizeof(git_commit));
+	commit->object.repo = g_repo;
+
+	memset(&fake_odb_object, 0x0, sizeof(git_odb_object));
+	fake_odb_object.buffer = (char *)buffer;
+	fake_odb_object.cached.size = strlen(fake_odb_object.buffer);
+
+	error = git_commit__parse(commit, &fake_odb_object);
+
+	*out = commit;
+	return error;
+}
+
+void test_commit_parse__entire_commit(void)
+{
+	const int failing_commit_count = ARRAY_SIZE(failing_commit_cases);
+	const int passing_commit_count = ARRAY_SIZE(passing_commit_cases);
+	int i;
+	git_commit *commit;
+
+	for (i = 0; i < failing_commit_count; ++i) {
+		cl_git_fail(parse_commit(&commit, failing_commit_cases[i]));
+		git_commit__free(commit);
+	}
+
+	for (i = 0; i < passing_commit_count; ++i) {
+		cl_git_pass(parse_commit(&commit, passing_commit_cases[i]));
+
+		if (!i)
+			cl_assert_equal_s("", git_commit_message(commit));
+		else
+			cl_assert(git__prefixcmp(
+				git_commit_message(commit), "a simple commit which works") == 0);
+
+		git_commit__free(commit);
+	}
+}
+
+
+// query the details on a parsed commit
+void test_commit_parse__details0(void) {
+	static const char *commit_ids[] = {
+		"a4a7dce85cf63874e984719f4fdd239f5145052f", /* 0 */
+		"9fd738e8f7967c078dceed8190330fc8648ee56a", /* 1 */
+		"4a202b346bb0fb0db7eff3cffeb3c70babbd2045", /* 2 */
+		"c47800c7266a2be04c571c04d5a6614691ea99bd", /* 3 */
+		"8496071c1b46c854b31185ea97743be6a8774479", /* 4 */
+		"5b5b025afb0b4c913b4c338a42934a3863bf3644", /* 5 */
+		"a65fedf39aefe402d3bb6e24df4d4f5fe4547750", /* 6 */
+	};
+	const size_t commit_count = sizeof(commit_ids) / sizeof(const char *);
+	unsigned int i;
+
+	for (i = 0; i < commit_count; ++i) {
+		git_oid id;
+		git_commit *commit;
+
+		const git_signature *author, *committer;
+		const char *message;
+		git_time_t commit_time;
+		unsigned int parents, p;
+		git_commit *parent = NULL, *old_parent = NULL;
+
+		git_oid_fromstr(&id, commit_ids[i]);
+
+		cl_git_pass(git_commit_lookup(&commit, g_repo, &id));
+
+		message = git_commit_message(commit);
+		author = git_commit_author(commit);
+		committer = git_commit_committer(commit);
+		commit_time = git_commit_time(commit);
+		parents = git_commit_parentcount(commit);
+
+		cl_assert_equal_s("Scott Chacon", author->name);
+		cl_assert_equal_s("schacon at gmail.com", author->email);
+		cl_assert_equal_s("Scott Chacon", committer->name);
+		cl_assert_equal_s("schacon at gmail.com", committer->email);
+		cl_assert(message != NULL);
+		cl_assert(commit_time > 0);
+		cl_assert(parents <= 2);
+		for (p = 0;p < parents;p++) {
+			if (old_parent != NULL)
+				git_commit_free(old_parent);
+
+			old_parent = parent;
+			cl_git_pass(git_commit_parent(&parent, commit, p));
+			cl_assert(parent != NULL);
+			cl_assert(git_commit_author(parent) != NULL); // is it really a commit?
+		}
+		git_commit_free(old_parent);
+		git_commit_free(parent);
+
+		cl_git_fail(git_commit_parent(&parent, commit, parents));
+		git_commit_free(commit);
+	}
+}
+
+void test_commit_parse__leading_lf(void)
+{
+	git_commit *commit;
+	const char *buffer =
+"tree 1810dff58d8a660512d4832e740f692884338ccd\n\
+parent e90810b8df3e80c413d903f631643c716887138d\n\
+author Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+committer Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+\n\
+\n\
+\n\
+This commit has a few LF at the start of the commit message";
+	const char *message =
+"This commit has a few LF at the start of the commit message";
+	const char *raw_message =
+"\n\
+\n\
+This commit has a few LF at the start of the commit message";
+	cl_git_pass(parse_commit(&commit, buffer));
+	cl_assert_equal_s(message, git_commit_message(commit));
+	cl_assert_equal_s(raw_message, git_commit_message_raw(commit));
+	git_commit__free(commit);
+}
+
+void test_commit_parse__only_lf(void)
+{
+	git_commit *commit;
+	const char *buffer =
+"tree 1810dff58d8a660512d4832e740f692884338ccd\n\
+parent e90810b8df3e80c413d903f631643c716887138d\n\
+author Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+committer Vicent Marti <tanoku at gmail.com> 1273848544 +0200\n\
+\n\
+\n\
+\n";
+	const char *message = "";
+	const char *raw_message = "\n\n";
+
+	cl_git_pass(parse_commit(&commit, buffer));
+	cl_assert_equal_s(message, git_commit_message(commit));
+	cl_assert_equal_s(raw_message, git_commit_message_raw(commit));
+	git_commit__free(commit);
+}
+
+void test_commit_parse__arbitrary_field(void)
+{
+	git_commit *commit;
+	git_buf buf = GIT_BUF_INIT;
+	const char *gpgsig = "-----BEGIN PGP SIGNATURE-----\n\
+Version: GnuPG v1.4.12 (Darwin)\n\
+\n\
+iQIcBAABAgAGBQJQ+FMIAAoJEH+LfPdZDSs1e3EQAJMjhqjWF+WkGLHju7pTw2al\n\
+o6IoMAhv0Z/LHlWhzBd9e7JeCnanRt12bAU7yvYp9+Z+z+dbwqLwDoFp8LVuigl8\n\
+JGLcnwiUW3rSvhjdCp9irdb4+bhKUnKUzSdsR2CK4/hC0N2i/HOvMYX+BRsvqweq\n\
+AsAkA6dAWh+gAfedrBUkCTGhlNYoetjdakWqlGL1TiKAefEZrtA1TpPkGn92vbLq\n\
+SphFRUY9hVn1ZBWrT3hEpvAIcZag3rTOiRVT1X1flj8B2vGCEr3RrcwOIZikpdaW\n\
+who/X3xh/DGbI2RbuxmmJpxxP/8dsVchRJJzBwG+yhwU/iN3MlV2c5D69tls/Dok\n\
+6VbyU4lm/ae0y3yR83D9dUlkycOnmmlBAHKIZ9qUts9X7mWJf0+yy2QxJVpjaTGG\n\
+cmnQKKPeNIhGJk2ENnnnzjEve7L7YJQF6itbx5VCOcsGh3Ocb3YR7DMdWjt7f8pu\n\
+c6j+q1rP7EpE2afUN/geSlp5i3x8aXZPDj67jImbVCE/Q1X9voCtyzGJH7MXR0N9\n\
+ZpRF8yzveRfMH8bwAJjSOGAFF5XkcR/RNY95o+J+QcgBLdX48h+ZdNmUf6jqlu3J\n\
+7KmTXXQcOVpN6dD3CmRFsbjq+x6RHwa8u1iGn+oIkX908r97ckfB/kHKH7ZdXIJc\n\
+cpxtDQQMGYFpXK/71stq\n\
+=ozeK\n\
+-----END PGP SIGNATURE-----";
+
+	cl_git_pass(parse_commit(&commit, passing_commit_cases[4]));
+
+	cl_git_pass(git_commit_header_field(&buf, commit, "parent"));
+	cl_assert_equal_s("34734e478d6cf50c27c9d69026d93974d052c454", buf.ptr);
+	git_buf_clear(&buf);
+
+	cl_git_pass(git_commit_header_field(&buf, commit, "gpgsig"));
+	cl_assert_equal_s(gpgsig, buf.ptr);
+
+	cl_git_fail_with(GIT_ENOTFOUND, git_commit_header_field(&buf, commit, "awesomeness"));
+	cl_git_fail_with(GIT_ENOTFOUND, git_commit_header_field(&buf, commit, "par"));
+
+	git_buf_free(&buf);
+	git_commit__free(commit);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/commit/signature.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/commit/signature.c
new file mode 100755
index 0000000..41a74b9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/commit/signature.c
@@ -0,0 +1,81 @@
+#include "clar_libgit2.h"
+
+static int try_build_signature(const char *name, const char *email, git_time_t time, int offset)
+{
+	git_signature *sign;
+	int error = 0;
+
+	if ((error =  git_signature_new(&sign, name, email, time, offset)) < 0)
+		return error;
+
+	git_signature_free((git_signature *)sign);
+
+	return error;
+}
+
+static void assert_name_and_email(
+	const char *expected_name,
+	const char *expected_email,
+	const char *name,
+	const char *email)
+{
+	git_signature *sign;
+
+	cl_git_pass(git_signature_new(&sign, name, email, 1234567890, 60));
+	cl_assert_equal_s(expected_name, sign->name);
+	cl_assert_equal_s(expected_email, sign->email);
+
+	git_signature_free(sign);
+}
+
+void test_commit_signature__leading_and_trailing_spaces_are_trimmed(void)
+{
+	assert_name_and_email("nulltoken", "emeric.fermas at gmail.com", "  nulltoken ", "   emeric.fermas at gmail.com     ");
+	assert_name_and_email("nulltoken", "emeric.fermas at gmail.com", "  nulltoken ", "   emeric.fermas at gmail.com  \n");
+	assert_name_and_email("nulltoken", "emeric.fermas at gmail.com", " \t nulltoken \n", " \n  emeric.fermas at gmail.com  \n");
+}
+
+void test_commit_signature__angle_brackets_in_names_are_not_supported(void)
+{
+	cl_git_fail(try_build_signature("<Phil Haack", "phil at haack", 1234567890, 60));
+	cl_git_fail(try_build_signature("Phil>Haack", "phil at haack", 1234567890, 60));
+	cl_git_fail(try_build_signature("<Phil Haack>", "phil at haack", 1234567890, 60));
+}
+
+void test_commit_signature__angle_brackets_in_email_are_not_supported(void)
+{
+	cl_git_fail(try_build_signature("Phil Haack", ">phil at haack", 1234567890, 60));
+	cl_git_fail(try_build_signature("Phil Haack", "phil@>haack", 1234567890, 60));
+	cl_git_fail(try_build_signature("Phil Haack", "<phil at haack>", 1234567890, 60));
+}
+
+void test_commit_signature__create_empties(void)
+{
+   // can not create a signature with empty name or email
+	cl_git_pass(try_build_signature("nulltoken", "emeric.fermas at gmail.com", 1234567890, 60));
+
+	cl_git_fail(try_build_signature("", "emeric.fermas at gmail.com", 1234567890, 60));
+	cl_git_fail(try_build_signature("   ", "emeric.fermas at gmail.com", 1234567890, 60));
+	cl_git_fail(try_build_signature("nulltoken", "", 1234567890, 60));
+	cl_git_fail(try_build_signature("nulltoken", "  ", 1234567890, 60));
+}
+
+void test_commit_signature__create_one_char(void)
+{
+   // creating a one character signature
+	assert_name_and_email("x", "foo at bar.baz", "x", "foo at bar.baz");
+}
+
+void test_commit_signature__create_two_char(void)
+{
+   // creating a two character signature
+	assert_name_and_email("xx", "foo at bar.baz", "xx", "foo at bar.baz");
+}
+
+void test_commit_signature__create_zero_char(void)
+{
+   // creating a zero character signature
+	git_signature *sign;
+	cl_git_fail(git_signature_new(&sign, "", "x at y.z", 1234567890, 60));
+	cl_assert(sign == NULL);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/commit/write.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/commit/write.c
new file mode 100755
index 0000000..ee9eb82
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/commit/write.c
@@ -0,0 +1,160 @@
+#include "clar_libgit2.h"
+
+static const char *committer_name = "Vicent Marti";
+static const char *committer_email = "vicent at github.com";
+static const char *commit_message = "This commit has been created in memory\n\
+   This is a commit created in memory and it will be written back to disk\n";
+static const char *tree_oid = "1810dff58d8a660512d4832e740f692884338ccd";
+static const char *root_commit_message = "This is a root commit\n\
+   This is a root commit and should be the only one in this branch\n";
+static const char *root_reflog_message = "commit (initial): This is a root commit \
+   This is a root commit and should be the only one in this branch";
+static char *head_old;
+static git_reference *head, *branch;
+static git_commit *commit;
+
+// Fixture setup
+static git_repository *g_repo;
+void test_commit_write__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_commit_write__cleanup(void)
+{
+	git_reference_free(head);
+	head = NULL;
+
+	git_reference_free(branch);
+	branch = NULL;
+
+	git_commit_free(commit);
+	commit = NULL;
+
+	git__free(head_old);
+	head_old = NULL;
+
+	cl_git_sandbox_cleanup();
+}
+
+
+// write a new commit object from memory to disk
+void test_commit_write__from_memory(void)
+{
+   git_oid tree_id, parent_id, commit_id;
+   git_signature *author, *committer;
+   const git_signature *author1, *committer1;
+   git_commit *parent;
+   git_tree *tree;
+   const char *commit_id_str = "8496071c1b46c854b31185ea97743be6a8774479";
+
+   git_oid_fromstr(&tree_id, tree_oid);
+   cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
+
+   git_oid_fromstr(&parent_id, commit_id_str);
+   cl_git_pass(git_commit_lookup(&parent, g_repo, &parent_id));
+
+   /* create signatures */
+   cl_git_pass(git_signature_new(&committer, committer_name, committer_email, 123456789, 60));
+   cl_git_pass(git_signature_new(&author, committer_name, committer_email, 987654321, 90));
+
+   cl_git_pass(git_commit_create_v(
+      &commit_id, /* out id */
+      g_repo,
+      NULL, /* do not update the HEAD */
+      author,
+      committer,
+      NULL,
+      commit_message,
+      tree,
+      1, parent));
+
+   git_object_free((git_object *)parent);
+   git_object_free((git_object *)tree);
+
+   git_signature_free(committer);
+   git_signature_free(author);
+
+   cl_git_pass(git_commit_lookup(&commit, g_repo, &commit_id));
+
+   /* Check attributes were set correctly */
+   author1 = git_commit_author(commit);
+   cl_assert(author1 != NULL);
+   cl_assert_equal_s(committer_name, author1->name);
+   cl_assert_equal_s(committer_email, author1->email);
+   cl_assert(author1->when.time == 987654321);
+   cl_assert(author1->when.offset == 90);
+
+   committer1 = git_commit_committer(commit);
+   cl_assert(committer1 != NULL);
+   cl_assert_equal_s(committer_name, committer1->name);
+   cl_assert_equal_s(committer_email, committer1->email);
+   cl_assert(committer1->when.time == 123456789);
+   cl_assert(committer1->when.offset == 60);
+
+   cl_assert_equal_s(commit_message, git_commit_message(commit));
+}
+
+// create a root commit
+void test_commit_write__root(void)
+{
+	git_oid tree_id, commit_id;
+	const git_oid *branch_oid;
+	git_signature *author, *committer;
+	const char *branch_name = "refs/heads/root-commit-branch";
+	git_tree *tree;
+	git_reflog *log;
+	const git_reflog_entry *entry;
+
+	git_oid_fromstr(&tree_id, tree_oid);
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
+
+	/* create signatures */
+	cl_git_pass(git_signature_new(&committer, committer_name, committer_email, 123456789, 60));
+	cl_git_pass(git_signature_new(&author, committer_name, committer_email, 987654321, 90));
+
+	/* First we need to update HEAD so it points to our non-existant branch */
+	cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
+	cl_assert(git_reference_type(head) == GIT_REF_SYMBOLIC);
+	head_old = git__strdup(git_reference_symbolic_target(head));
+	cl_assert(head_old != NULL);
+	git_reference_free(head);
+
+	cl_git_pass(git_reference_symbolic_create(&head, g_repo, "HEAD", branch_name, 1, NULL));
+
+	cl_git_pass(git_commit_create_v(
+		&commit_id, /* out id */
+		g_repo,
+		"HEAD",
+		author,
+		committer,
+		NULL,
+		root_commit_message,
+		tree,
+		0));
+
+	git_object_free((git_object *)tree);
+	git_signature_free(author);
+
+	/*
+	 * The fact that creating a commit works has already been
+	 * tested. Here we just make sure it's our commit and that it was
+	 * written as a root commit.
+	 */
+	cl_git_pass(git_commit_lookup(&commit, g_repo, &commit_id));
+	cl_assert(git_commit_parentcount(commit) == 0);
+	cl_git_pass(git_reference_lookup(&branch, g_repo, branch_name));
+	branch_oid = git_reference_target(branch);
+	cl_assert_equal_oid(branch_oid, &commit_id);
+	cl_assert_equal_s(root_commit_message, git_commit_message(commit));
+
+	cl_git_pass(git_reflog_read(&log, g_repo, branch_name));
+	cl_assert_equal_i(1, git_reflog_entrycount(log));
+	entry = git_reflog_entry_byindex(log, 0);
+	cl_assert_equal_s(committer->email, git_reflog_entry_committer(entry)->email);
+	cl_assert_equal_s(committer->name, git_reflog_entry_committer(entry)->name);
+	cl_assert_equal_s(root_reflog_message, git_reflog_entry_message(entry));
+
+	git_signature_free(committer);
+	git_reflog_free(log);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/add.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/add.c
new file mode 100755
index 0000000..405f1e2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/add.c
@@ -0,0 +1,37 @@
+#include "clar_libgit2.h"
+
+void test_config_add__initialize(void)
+{
+	cl_fixture_sandbox("config/config10");
+}
+
+void test_config_add__cleanup(void)
+{
+	cl_fixture_cleanup("config10");
+}
+
+void test_config_add__to_existing_section(void)
+{
+	git_config *cfg;
+	int32_t i;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config10"));
+	cl_git_pass(git_config_set_int32(cfg, "empty.tmp", 5));
+	cl_git_pass(git_config_get_int32(&i, cfg, "empty.tmp"));
+	cl_assert(i == 5);
+	cl_git_pass(git_config_delete_entry(cfg, "empty.tmp"));
+	git_config_free(cfg);
+}
+
+void test_config_add__to_new_section(void)
+{
+	git_config *cfg;
+	int32_t i;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config10"));
+	cl_git_pass(git_config_set_int32(cfg, "section.tmp", 5));
+	cl_git_pass(git_config_get_int32(&i, cfg, "section.tmp"));
+	cl_assert(i == 5);
+	cl_git_pass(git_config_delete_entry(cfg, "section.tmp"));
+	git_config_free(cfg);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/backend.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/backend.c
new file mode 100755
index 0000000..3fd6eb1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/backend.c
@@ -0,0 +1,24 @@
+#include "clar_libgit2.h"
+#include "git2/sys/config.h"
+
+void test_config_backend__checks_version(void)
+{
+	git_config *cfg;
+	git_config_backend backend = GIT_CONFIG_BACKEND_INIT;
+	const git_error *err;
+
+	backend.version = 1024;
+
+	cl_git_pass(git_config_new(&cfg));
+	cl_git_fail(git_config_add_backend(cfg, &backend, 0, false));
+	err = giterr_last();
+	cl_assert_equal_i(GITERR_INVALID, err->klass);
+
+	giterr_clear();
+	backend.version = 1024;
+	cl_git_fail(git_config_add_backend(cfg, &backend, 0, false));
+	err = giterr_last();
+	cl_assert_equal_i(GITERR_INVALID, err->klass);
+
+	git_config_free(cfg);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/config_helpers.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/config_helpers.c
new file mode 100755
index 0000000..025838a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/config_helpers.c
@@ -0,0 +1,68 @@
+#include "clar_libgit2.h"
+#include "config_helpers.h"
+#include "repository.h"
+#include "buffer.h"
+
+void assert_config_entry_existence(
+	git_repository *repo,
+	const char *name,
+	bool is_supposed_to_exist)
+{
+	git_config *config;
+	git_config_entry *entry = NULL;
+	int result;
+
+	cl_git_pass(git_repository_config__weakptr(&config, repo));
+	
+	result = git_config_get_entry(&entry, config, name);
+	git_config_entry_free(entry);
+
+	if (is_supposed_to_exist)
+		cl_git_pass(result);
+	else
+		cl_assert_equal_i(GIT_ENOTFOUND, result);
+}
+
+void assert_config_entry_value(
+	git_repository *repo,
+	const char *name,
+	const char *expected_value)
+{
+	git_config *config;
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_repository_config__weakptr(&config, repo));
+
+	cl_git_pass(git_config_get_string_buf(&buf, config, name));
+
+	cl_assert_equal_s(expected_value, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
+
+static int count_config_entries_cb(
+	const git_config_entry *entry,
+	void *payload)
+{
+	int *how_many = (int *)payload;
+
+	GIT_UNUSED(entry);
+
+	(*how_many)++;
+
+	return 0;
+}
+
+int count_config_entries_match(git_repository *repo, const char *pattern)
+{
+	git_config *config;
+	int how_many = 0;
+
+	cl_git_pass(git_repository_config(&config, repo));
+
+	cl_assert_equal_i(0, git_config_foreach_match(
+		config,	pattern, count_config_entries_cb, &how_many));
+
+	git_config_free(config);
+
+	return how_many;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/config_helpers.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/config_helpers.h
new file mode 100755
index 0000000..4406457
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/config_helpers.h
@@ -0,0 +1,13 @@
+extern void assert_config_entry_existence(
+	git_repository *repo,
+	const char *name,
+	bool is_supposed_to_exist);
+
+extern void assert_config_entry_value(
+	git_repository *repo,
+	const char *name,
+	const char *expected_value);
+
+extern int count_config_entries_match(
+	git_repository *repo,
+	const char *pattern);
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/configlevel.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/configlevel.c
new file mode 100755
index 0000000..ca478b1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/configlevel.c
@@ -0,0 +1,73 @@
+#include "clar_libgit2.h"
+
+void test_config_configlevel__adding_the_same_level_twice_returns_EEXISTS(void)
+{
+	int error;
+	git_config *cfg;
+
+	cl_git_pass(git_config_new(&cfg));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
+		GIT_CONFIG_LEVEL_LOCAL, 0));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
+		GIT_CONFIG_LEVEL_GLOBAL, 0));
+	error = git_config_add_file_ondisk(cfg, cl_fixture("config/config16"),
+		GIT_CONFIG_LEVEL_GLOBAL, 0);
+
+	cl_git_fail(error);
+	cl_assert_equal_i(GIT_EEXISTS, error);
+
+	git_config_free(cfg);
+}
+
+void test_config_configlevel__can_replace_a_config_file_at_an_existing_level(void)
+{
+	git_config *cfg;
+	git_buf buf = {0};
+
+	cl_git_pass(git_config_new(&cfg));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config18"),
+		GIT_CONFIG_LEVEL_LOCAL, 1));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config19"),
+		GIT_CONFIG_LEVEL_LOCAL, 1));
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.stringglobal"));
+	cl_assert_equal_s("don't find me!", buf.ptr);
+
+	git_buf_free(&buf);
+	git_config_free(cfg);
+}
+
+void test_config_configlevel__can_read_from_a_single_level_focused_file_after_parent_config_has_been_freed(void)
+{
+	git_config *cfg;
+	git_config *single_level_cfg;
+	git_buf buf = {0};
+
+	cl_git_pass(git_config_new(&cfg));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config18"),
+		GIT_CONFIG_LEVEL_GLOBAL, 0));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config19"),
+		GIT_CONFIG_LEVEL_LOCAL, 0));
+
+	cl_git_pass(git_config_open_level(&single_level_cfg, cfg, GIT_CONFIG_LEVEL_LOCAL));
+
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_get_string_buf(&buf, single_level_cfg, "core.stringglobal"));
+	cl_assert_equal_s("don't find me!", buf.ptr);
+
+	git_buf_free(&buf);
+	git_config_free(single_level_cfg);
+}
+
+void test_config_configlevel__fetching_a_level_from_an_empty_compound_config_returns_ENOTFOUND(void)
+{
+	git_config *cfg;
+	git_config *local_cfg;
+
+	cl_git_pass(git_config_new(&cfg));
+
+	cl_assert_equal_i(GIT_ENOTFOUND, git_config_open_level(&local_cfg, cfg, GIT_CONFIG_LEVEL_LOCAL));
+
+	git_config_free(cfg);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/global.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/global.c
new file mode 100755
index 0000000..4481308
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/global.c
@@ -0,0 +1,67 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "fileops.h"
+
+void test_config_global__initialize(void)
+{
+	git_buf path = GIT_BUF_INIT;
+
+	cl_git_pass(git_futils_mkdir_r("home", NULL, 0777));
+	cl_git_pass(git_path_prettify(&path, "home", NULL));
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
+
+	cl_git_pass(git_futils_mkdir_r("xdg/git", NULL, 0777));
+	cl_git_pass(git_path_prettify(&path, "xdg/git", NULL));
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr));
+
+	cl_git_pass(git_futils_mkdir_r("etc", NULL, 0777));
+	cl_git_pass(git_path_prettify(&path, "etc", NULL));
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr));
+
+	git_buf_free(&path);
+}
+
+void test_config_global__cleanup(void)
+{
+	cl_sandbox_set_search_path_defaults();
+}
+
+void test_config_global__open_global(void)
+{
+	git_config *cfg, *global, *selected, *dummy;
+
+	cl_git_pass(git_config_open_default(&cfg));
+	cl_git_pass(git_config_open_level(&global, cfg, GIT_CONFIG_LEVEL_GLOBAL));
+	cl_git_fail(git_config_open_level(&dummy, cfg, GIT_CONFIG_LEVEL_XDG));
+	cl_git_pass(git_config_open_global(&selected, cfg));
+
+	git_config_free(selected);
+	git_config_free(global);
+	git_config_free(cfg);
+}
+
+void test_config_global__open_xdg(void)
+{
+	git_config *cfg, *xdg, *selected;
+	const char *str = "teststring";
+	const char *key = "this.variable";
+	git_buf buf = {0};
+
+	cl_git_mkfile("xdg/git/config", "# XDG config\n[core]\n  test = 1\n");
+
+	cl_git_pass(git_config_open_default(&cfg));
+	cl_git_pass(git_config_open_level(&xdg, cfg, GIT_CONFIG_LEVEL_XDG));
+	cl_git_pass(git_config_open_global(&selected, cfg));
+
+	cl_git_pass(git_config_set_string(xdg, key, str));
+	cl_git_pass(git_config_get_string_buf(&buf, selected, key));
+	cl_assert_equal_s(str, buf.ptr);
+
+	git_buf_free(&buf);
+	git_config_free(selected);
+	git_config_free(xdg);
+	git_config_free(cfg);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/include.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/include.c
new file mode 100755
index 0000000..882b89b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/include.c
@@ -0,0 +1,133 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "fileops.h"
+
+void test_config_include__relative(void)
+{
+	git_config *cfg;
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config-include")));
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar.baz"));
+	cl_assert_equal_s("huzzah", git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+	git_config_free(cfg);
+}
+
+void test_config_include__absolute(void)
+{
+	git_config *cfg;
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_printf(&buf, "[include]\npath = %s/config-included", cl_fixture("config")));
+
+	cl_git_mkfile("config-include-absolute", git_buf_cstr(&buf));
+	git_buf_free(&buf);
+	cl_git_pass(git_config_open_ondisk(&cfg, "config-include-absolute"));
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar.baz"));
+	cl_assert_equal_s("huzzah", git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+	git_config_free(cfg);
+}
+
+void test_config_include__homedir(void)
+{
+	git_config *cfg;
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, cl_fixture("config")));
+	cl_git_mkfile("config-include-homedir",  "[include]\npath = ~/config-included");
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config-include-homedir"));
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar.baz"));
+	cl_assert_equal_s("huzzah", git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+	git_config_free(cfg);
+
+	cl_sandbox_set_search_path_defaults();
+}
+
+/* We need to pretend that the variables were defined where the file was included */
+void test_config_include__ordering(void)
+{
+	git_config *cfg;
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_mkfile("included", "[foo \"bar\"]\nbaz = hurrah\nfrotz = hiya");
+	cl_git_mkfile("including",
+		      "[foo \"bar\"]\nfrotz = hello\n"
+		      "[include]\npath = included\n"
+		      "[foo \"bar\"]\nbaz = huzzah\n");
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "including"));
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar.frotz"));
+	cl_assert_equal_s("hiya", git_buf_cstr(&buf));
+	git_buf_clear(&buf);
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar.baz"));
+	cl_assert_equal_s("huzzah", git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+	git_config_free(cfg);
+}
+
+/* We need to pretend that the variables were defined where the file was included */
+void test_config_include__depth(void)
+{
+	git_config *cfg;
+
+	cl_git_mkfile("a", "[include]\npath = b");
+	cl_git_mkfile("b", "[include]\npath = a");
+
+	cl_git_fail(git_config_open_ondisk(&cfg, "a"));
+
+	p_unlink("a");
+	p_unlink("b");
+}
+
+void test_config_include__missing(void)
+{
+	git_config *cfg;
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_mkfile("including", "[include]\npath = nonexistentfile\n[foo]\nbar = baz");
+
+	giterr_clear();
+	cl_git_pass(git_config_open_ondisk(&cfg, "including"));
+	cl_assert(giterr_last() == NULL);
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar"));
+	cl_assert_equal_s("baz", git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+	git_config_free(cfg);
+}
+
+#define replicate10(s) s s s s s s s s s s
+void test_config_include__depth2(void)
+{
+	git_config *cfg;
+	git_buf buf = GIT_BUF_INIT;
+	const char *content = "[include]\n" replicate10(replicate10("path=bottom\n"));
+
+	cl_git_mkfile("top-level", "[include]\npath = middle\n[foo]\nbar = baz");
+	cl_git_mkfile("middle", content);
+	cl_git_mkfile("bottom", "[foo]\nbar2 = baz2");
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "top-level"));
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar"));
+	cl_assert_equal_s("baz", git_buf_cstr(&buf));
+
+	git_buf_clear(&buf);
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar2"));
+	cl_assert_equal_s("baz2", git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+	git_config_free(cfg);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/multivar.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/multivar.c
new file mode 100755
index 0000000..0150089
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/multivar.c
@@ -0,0 +1,288 @@
+#include "clar_libgit2.h"
+
+static const char *_name = "remote.ab.url";
+
+void test_config_multivar__initialize(void)
+{
+	cl_fixture_sandbox("config");
+}
+
+void test_config_multivar__cleanup(void)
+{
+	cl_fixture_cleanup("config");
+}
+
+static int mv_read_cb(const git_config_entry *entry, void *data)
+{
+	int *n = (int *) data;
+
+	if (!strcmp(entry->name, _name))
+		(*n)++;
+
+	return 0;
+}
+
+void test_config_multivar__foreach(void)
+{
+	git_config *cfg;
+	int n = 0;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config11")));
+
+	cl_git_pass(git_config_foreach(cfg, mv_read_cb, &n));
+	cl_assert(n == 2);
+
+	git_config_free(cfg);
+}
+
+static int cb(const git_config_entry *entry, void *data)
+{
+	int *n = (int *) data;
+
+	GIT_UNUSED(entry);
+
+	(*n)++;
+
+	return 0;
+}
+
+static void check_get_multivar_foreach(
+	git_config *cfg, int expected, int expected_patterned)
+{
+	int n = 0;
+
+	if (expected > 0) {
+		cl_git_pass(git_config_get_multivar_foreach(cfg, _name, NULL, cb, &n));
+		cl_assert_equal_i(expected, n);
+	} else {
+		cl_assert_equal_i(GIT_ENOTFOUND,
+			git_config_get_multivar_foreach(cfg, _name, NULL, cb, &n));
+	}
+
+	n = 0;
+
+	if (expected_patterned > 0) {
+		cl_git_pass(git_config_get_multivar_foreach(cfg, _name, "example", cb, &n));
+		cl_assert_equal_i(expected_patterned, n);
+	} else {
+		cl_assert_equal_i(GIT_ENOTFOUND,
+			git_config_get_multivar_foreach(cfg, _name, "example", cb, &n));
+	}
+}
+
+static void check_get_multivar(git_config *cfg, int expected)
+{
+	git_config_iterator *iter;
+	git_config_entry *entry;
+	int n = 0;
+
+	cl_git_pass(git_config_multivar_iterator_new(&iter, cfg, _name, NULL));
+
+	while (git_config_next(&entry, iter) == 0)
+		n++;
+
+	cl_assert_equal_i(expected, n);
+	git_config_iterator_free(iter);
+
+}
+
+void test_config_multivar__get(void)
+{
+	git_config *cfg;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config/config11"));
+	check_get_multivar_foreach(cfg, 2, 1);
+
+	/* add another that has the _name entry */
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config/config9", GIT_CONFIG_LEVEL_SYSTEM, 1));
+	check_get_multivar_foreach(cfg, 3, 2);
+
+	/* add another that does not have the _name entry */
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config/config0", GIT_CONFIG_LEVEL_GLOBAL, 1));
+	check_get_multivar_foreach(cfg, 3, 2);
+
+	/* add another that does not have the _name entry at the end */
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config/config1", GIT_CONFIG_LEVEL_APP, 1));
+	check_get_multivar_foreach(cfg, 3, 2);
+
+	/* drop original file */
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config/config2", GIT_CONFIG_LEVEL_LOCAL, 1));
+	check_get_multivar_foreach(cfg, 1, 1);
+
+	/* drop other file with match */
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config/config3", GIT_CONFIG_LEVEL_SYSTEM, 1));
+	check_get_multivar_foreach(cfg, 0, 0);
+
+	/* reload original file (add different place in order) */
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config/config11", GIT_CONFIG_LEVEL_SYSTEM, 1));
+	check_get_multivar_foreach(cfg, 2, 1);
+
+	check_get_multivar(cfg, 2);
+
+	git_config_free(cfg);
+}
+
+void test_config_multivar__add(void)
+{
+	git_config *cfg;
+	int n;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config/config11"));
+	cl_git_pass(git_config_set_multivar(cfg, _name, "nonexistant", "git://git.otherplace.org/libgit2"));
+
+	n = 0;
+	cl_git_pass(git_config_get_multivar_foreach(cfg, _name, NULL, cb, &n));
+	cl_assert_equal_i(n, 3);
+
+	n = 0;
+	cl_git_pass(git_config_get_multivar_foreach(cfg, _name, "otherplace", cb, &n));
+	cl_assert_equal_i(n, 1);
+
+	git_config_free(cfg);
+
+	/* We know it works in memory, let's see if the file is written correctly */
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config/config11"));
+
+	n = 0;
+	cl_git_pass(git_config_get_multivar_foreach(cfg, _name, NULL, cb, &n));
+	cl_assert_equal_i(n, 3);
+
+	n = 0;
+	cl_git_pass(git_config_get_multivar_foreach(cfg, _name, "otherplace", cb, &n));
+	cl_assert_equal_i(n, 1);
+
+	git_config_free(cfg);
+}
+
+void test_config_multivar__add_new(void)
+{
+	const char *var = "a.brand.new";
+	git_config *cfg;
+	int n;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config/config11"));
+
+	cl_git_pass(git_config_set_multivar(cfg, var, "", "variable"));
+	n = 0;
+	cl_git_pass(git_config_get_multivar_foreach(cfg, var, NULL, cb, &n));
+	cl_assert_equal_i(n, 1);
+
+	git_config_free(cfg);
+}
+
+void test_config_multivar__replace(void)
+{
+	git_config *cfg;
+	int n;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config/config11"));
+
+	n = 0;
+	cl_git_pass(git_config_get_multivar_foreach(cfg, _name, NULL, cb, &n));
+	cl_assert(n == 2);
+
+	cl_git_pass(git_config_set_multivar(cfg, _name, "github", "git://git.otherplace.org/libgit2"));
+
+	n = 0;
+	cl_git_pass(git_config_get_multivar_foreach(cfg, _name, NULL, cb, &n));
+	cl_assert(n == 2);
+
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config/config11"));
+
+	n = 0;
+	cl_git_pass(git_config_get_multivar_foreach(cfg, _name, NULL, cb, &n));
+	cl_assert(n == 2);
+
+	git_config_free(cfg);
+}
+
+void test_config_multivar__replace_multiple(void)
+{
+	git_config *cfg;
+	int n;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config/config11"));
+	cl_git_pass(git_config_set_multivar(cfg, _name, "git://", "git://git.otherplace.org/libgit2"));
+
+	n = 0;
+	cl_git_pass(git_config_get_multivar_foreach(cfg, _name, "otherplace", cb, &n));
+	cl_assert_equal_i(n, 2);
+
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config/config11"));
+
+	n = 0;
+	cl_git_pass(git_config_get_multivar_foreach(cfg, _name, "otherplace", cb, &n));
+	cl_assert_equal_i(n, 2);
+
+	git_config_free(cfg);
+}
+
+void test_config_multivar__delete(void)
+{
+	git_config *cfg;
+	int n;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config/config11"));
+
+	n = 0;
+	cl_git_pass(git_config_get_multivar_foreach(cfg, _name, NULL, cb, &n));
+	cl_assert_equal_i(2, n);
+
+	cl_git_pass(git_config_delete_multivar(cfg, _name, "github"));
+
+	n = 0;
+	cl_git_pass(git_config_get_multivar_foreach(cfg, _name, NULL, cb, &n));
+	cl_assert_equal_i(1, n);
+
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config/config11"));
+
+	n = 0;
+	cl_git_pass(git_config_get_multivar_foreach(cfg, _name, NULL, cb, &n));
+	cl_assert_equal_i(1, n);
+
+	git_config_free(cfg);
+}
+
+void test_config_multivar__delete_multiple(void)
+{
+	git_config *cfg;
+	int n;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config/config11"));
+
+	n = 0;
+	cl_git_pass(git_config_get_multivar_foreach(cfg, _name, NULL, cb, &n));
+	cl_assert(n == 2);
+
+	cl_git_pass(git_config_delete_multivar(cfg, _name, "git"));
+
+	n = 0;
+	cl_git_fail_with(git_config_get_multivar_foreach(cfg, _name, NULL, cb, &n), GIT_ENOTFOUND);
+
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config/config11"));
+
+	n = 0;
+	cl_git_fail_with(git_config_get_multivar_foreach(cfg, _name, NULL, cb, &n), GIT_ENOTFOUND);
+
+	git_config_free(cfg);
+}
+
+void test_config_multivar__delete_notfound(void)
+{
+	git_config *cfg;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config/config11"));
+
+	cl_git_fail_with(git_config_delete_multivar(cfg, "remote.ab.noturl", "git"), GIT_ENOTFOUND);
+
+	git_config_free(cfg);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/new.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/new.c
new file mode 100755
index 0000000..b39baa0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/new.c
@@ -0,0 +1,34 @@
+#include "clar_libgit2.h"
+
+#include "filebuf.h"
+#include "fileops.h"
+#include "posix.h"
+
+#define TEST_CONFIG "git-new-config"
+
+void test_config_new__write_new_config(void)
+{
+	git_config *config;
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_mkfile(TEST_CONFIG, "");
+	cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG));
+
+	cl_git_pass(git_config_set_string(config, "color.ui", "auto"));
+	cl_git_pass(git_config_set_string(config, "core.editor", "ed"));
+
+	git_config_free(config);
+
+	cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG));
+
+	cl_git_pass(git_config_get_string_buf(&buf, config, "color.ui"));
+	cl_assert_equal_s("auto", git_buf_cstr(&buf));
+	git_buf_clear(&buf);
+	cl_git_pass(git_config_get_string_buf(&buf, config, "core.editor"));
+	cl_assert_equal_s("ed", git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+	git_config_free(config);
+
+	p_unlink(TEST_CONFIG);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/read.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/read.c
new file mode 100755
index 0000000..f86b2d7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/read.c
@@ -0,0 +1,705 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "path.h"
+
+static git_buf buf = GIT_BUF_INIT;
+
+void test_config_read__cleanup(void)
+{
+	git_buf_free(&buf);
+}
+
+void test_config_read__simple_read(void)
+{
+	git_config *cfg;
+	int32_t i;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config0")));
+
+	cl_git_pass(git_config_get_int32(&i, cfg, "core.repositoryformatversion"));
+	cl_assert(i == 0);
+	cl_git_pass(git_config_get_bool(&i, cfg, "core.filemode"));
+	cl_assert(i == 1);
+	cl_git_pass(git_config_get_bool(&i, cfg, "core.bare"));
+	cl_assert(i == 0);
+	cl_git_pass(git_config_get_bool(&i, cfg, "core.logallrefupdates"));
+	cl_assert(i == 1);
+
+	git_config_free(cfg);
+}
+
+void test_config_read__case_sensitive(void)
+{
+	git_config *cfg;
+	int i;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config1")));
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "this.that.other"));
+	cl_assert_equal_s("true", git_buf_cstr(&buf));
+	git_buf_clear(&buf);
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "this.That.other"));
+	cl_assert_equal_s("yes", git_buf_cstr(&buf));
+
+	cl_git_pass(git_config_get_bool(&i, cfg, "this.that.other"));
+	cl_assert(i == 1);
+	cl_git_pass(git_config_get_bool(&i, cfg, "this.That.other"));
+	cl_assert(i == 1);
+
+	/* This one doesn't exist */
+	cl_must_fail(git_config_get_bool(&i, cfg, "this.thaT.other"));
+
+	git_config_free(cfg);
+}
+
+/*
+ * If \ is the last non-space character on the line, we read the next
+ * one, separating each line with SP.
+ */
+void test_config_read__multiline_value(void)
+{
+	git_config *cfg;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config2")));
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "this.That.and"));
+	cl_assert_equal_s("one one one two two three three", git_buf_cstr(&buf));
+
+	git_config_free(cfg);
+}
+
+static void clean_test_config(void *unused)
+{
+	GIT_UNUSED(unused);
+	cl_fixture_cleanup("./testconfig");
+}
+
+void test_config_read__multiline_value_and_eof(void)
+{
+	git_config *cfg;
+
+	cl_set_cleanup(&clean_test_config, NULL);
+	cl_git_mkfile("./testconfig", "[header]\n  key1 = foo\\\n");
+	cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "header.key1"));
+	cl_assert_equal_s("foo", git_buf_cstr(&buf));
+
+	git_config_free(cfg);
+}
+
+void test_config_read__multiline_eof(void)
+{
+	git_config *cfg;
+
+	cl_set_cleanup(&clean_test_config, NULL);
+	cl_git_mkfile("./testconfig", "[header]\n  key1 = \\\n");
+	cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "header.key1"));
+	cl_assert_equal_s("", git_buf_cstr(&buf));
+
+	git_config_free(cfg);
+}
+
+/*
+ * This kind of subsection declaration is case-insensitive
+ */
+void test_config_read__subsection_header(void)
+{
+	git_config *cfg;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config3")));
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "section.subsection.var"));
+	cl_assert_equal_s("hello", git_buf_cstr(&buf));
+
+	/* The subsection is transformed to lower-case */
+	cl_must_fail(git_config_get_string_buf(&buf, cfg, "section.subSectIon.var"));
+
+	git_config_free(cfg);
+}
+
+void test_config_read__lone_variable(void)
+{
+	git_config *cfg;
+	int i;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config4")));
+
+	cl_git_fail(git_config_get_int32(&i, cfg, "some.section.variable"));
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.section.variable"));
+	cl_assert_equal_s("", git_buf_cstr(&buf));
+	git_buf_clear(&buf);
+
+	cl_git_pass(git_config_get_bool(&i, cfg, "some.section.variable"));
+	cl_assert(i == 1);
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.section.variableeq"));
+	cl_assert_equal_s("", git_buf_cstr(&buf));
+
+	cl_git_pass(git_config_get_bool(&i, cfg, "some.section.variableeq"));
+	cl_assert(i == 0);
+
+	git_config_free(cfg);
+}
+
+void test_config_read__number_suffixes(void)
+{
+	git_config *cfg;
+	int64_t i;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config5")));
+
+	cl_git_pass(git_config_get_int64(&i, cfg, "number.simple"));
+	cl_assert(i == 1);
+
+	cl_git_pass(git_config_get_int64(&i, cfg, "number.k"));
+	cl_assert(i == 1 * 1024);
+
+	cl_git_pass(git_config_get_int64(&i, cfg, "number.kk"));
+	cl_assert(i == 1 * 1024);
+
+	cl_git_pass(git_config_get_int64(&i, cfg, "number.m"));
+	cl_assert(i == 1 * 1024 * 1024);
+
+	cl_git_pass(git_config_get_int64(&i, cfg, "number.mm"));
+	cl_assert(i == 1 * 1024 * 1024);
+
+	cl_git_pass(git_config_get_int64(&i, cfg, "number.g"));
+	cl_assert(i == 1 * 1024 * 1024 * 1024);
+
+	cl_git_pass(git_config_get_int64(&i, cfg, "number.gg"));
+	cl_assert(i == 1 * 1024 * 1024 * 1024);
+
+	git_config_free(cfg);
+}
+
+void test_config_read__blank_lines(void)
+{
+	git_config *cfg;
+	int i;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config6")));
+
+	cl_git_pass(git_config_get_bool(&i, cfg, "valid.subsection.something"));
+	cl_assert(i == 1);
+
+	cl_git_pass(git_config_get_bool(&i, cfg, "something.else.something"));
+	cl_assert(i == 0);
+
+	git_config_free(cfg);
+}
+
+void test_config_read__invalid_ext_headers(void)
+{
+	git_config *cfg;
+	cl_must_fail(git_config_open_ondisk(&cfg, cl_fixture("config/config7")));
+}
+
+void test_config_read__empty_files(void)
+{
+	git_config *cfg;
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config8")));
+	git_config_free(cfg);
+}
+
+void test_config_read__symbol_headers(void)
+{
+	git_config *cfg;
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config20")));
+	git_config_free(cfg);
+}
+
+void test_config_read__header_in_last_line(void)
+{
+	git_config *cfg;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config10")));
+	git_config_free(cfg);
+}
+
+void test_config_read__prefixes(void)
+{
+	git_config *cfg;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9")));
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "remote.ab.url"));
+	cl_assert_equal_s("http://example.com/git/ab", git_buf_cstr(&buf));
+	git_buf_clear(&buf);
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "remote.abba.url"));
+	cl_assert_equal_s("http://example.com/git/abba", git_buf_cstr(&buf));
+
+	git_config_free(cfg);
+}
+
+void test_config_read__escaping_quotes(void)
+{
+	git_config *cfg;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config13")));
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.editor"));
+	cl_assert_equal_s("\"C:/Program Files/Nonsense/bah.exe\" \"--some option\"", git_buf_cstr(&buf));
+
+	git_config_free(cfg);
+}
+
+void test_config_read__invalid_escape_sequence(void)
+{
+	git_config *cfg;
+
+	cl_set_cleanup(&clean_test_config, NULL);
+	cl_git_mkfile("./testconfig", "[header]\n  key1 = \\\\\\;\n  key2 = value2\n");
+	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));
+
+	git_config_free(cfg);
+}
+
+static int count_cfg_entries_and_compare_levels(
+	const git_config_entry *entry, void *payload)
+{
+	int *count = payload;
+
+	if (!strcmp(entry->value, "7") || !strcmp(entry->value, "17"))
+		cl_assert(entry->level == GIT_CONFIG_LEVEL_GLOBAL);
+	else
+		cl_assert(entry->level == GIT_CONFIG_LEVEL_SYSTEM);
+
+	(*count)++;
+	return 0;
+}
+
+static int cfg_callback_countdown(const git_config_entry *entry, void *payload)
+{
+	int *count = payload;
+	GIT_UNUSED(entry);
+	(*count)--;
+	if (*count == 0)
+		return -100;
+	return 0;
+}
+
+void test_config_read__foreach(void)
+{
+	git_config *cfg;
+	int count, ret;
+
+	cl_git_pass(git_config_new(&cfg));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
+		GIT_CONFIG_LEVEL_SYSTEM, 0));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
+		GIT_CONFIG_LEVEL_GLOBAL, 0));
+
+	count = 0;
+	cl_git_pass(git_config_foreach(cfg, count_cfg_entries_and_compare_levels, &count));
+	cl_assert_equal_i(7, count);
+
+	count = 3;
+	cl_git_fail(ret = git_config_foreach(cfg, cfg_callback_countdown, &count));
+	cl_assert_equal_i(-100, ret);
+
+	git_config_free(cfg);
+}
+
+void test_config_read__iterator(void)
+{
+	git_config *cfg;
+	git_config_iterator *iter;
+	git_config_entry *entry;
+	int count, ret;
+
+	cl_git_pass(git_config_new(&cfg));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
+		GIT_CONFIG_LEVEL_SYSTEM, 0));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
+		GIT_CONFIG_LEVEL_GLOBAL, 0));
+
+	count = 0;
+	cl_git_pass(git_config_iterator_new(&iter, cfg));
+
+	while ((ret = git_config_next(&entry, iter)) == 0) {
+		count++;
+	}
+
+	git_config_iterator_free(iter);
+	cl_assert_equal_i(GIT_ITEROVER, ret);
+	cl_assert_equal_i(7, count);
+
+	count = 3;
+	cl_git_pass(git_config_iterator_new(&iter, cfg));
+
+	git_config_iterator_free(iter);
+	git_config_free(cfg);
+}
+
+static int count_cfg_entries(const git_config_entry *entry, void *payload)
+{
+	int *count = payload;
+	GIT_UNUSED(entry);
+	(*count)++;
+	return 0;
+}
+
+void test_config_read__foreach_match(void)
+{
+	git_config *cfg;
+	int count;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9")));
+
+	count = 0;
+	cl_git_pass(
+		git_config_foreach_match(cfg, "core.*", count_cfg_entries, &count));
+	cl_assert_equal_i(3, count);
+
+	count = 0;
+	cl_git_pass(
+		git_config_foreach_match(cfg, "remote\\.ab.*", count_cfg_entries, &count));
+	cl_assert_equal_i(2, count);
+
+	count = 0;
+	cl_git_pass(
+		git_config_foreach_match(cfg, ".*url$", count_cfg_entries, &count));
+	cl_assert_equal_i(2, count);
+
+	count = 0;
+	cl_git_pass(
+		git_config_foreach_match(cfg, ".*dummy.*", count_cfg_entries, &count));
+	cl_assert_equal_i(2, count);
+
+	count = 0;
+	cl_git_pass(
+		git_config_foreach_match(cfg, ".*nomatch.*", count_cfg_entries, &count));
+	cl_assert_equal_i(0, count);
+
+	git_config_free(cfg);
+}
+
+static void check_glob_iter(git_config *cfg, const char *regexp, int expected)
+{
+	git_config_iterator *iter;
+	git_config_entry *entry;
+	int count, error;
+
+	cl_git_pass(git_config_iterator_glob_new(&iter, cfg, regexp));
+
+	count = 0;
+	while ((error = git_config_next(&entry, iter)) == 0)
+		count++;
+
+	cl_assert_equal_i(GIT_ITEROVER, error);
+	cl_assert_equal_i(expected, count);
+	git_config_iterator_free(iter);
+}
+
+void test_config_read__iterator_invalid_glob(void)
+{
+	git_config *cfg;
+	git_config_iterator *iter;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9")));
+
+	cl_git_fail(git_config_iterator_glob_new(&iter, cfg, "*"));
+
+	git_config_free(cfg);
+}
+
+void test_config_read__iterator_glob(void)
+{
+	git_config *cfg;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9")));
+
+	check_glob_iter(cfg, "core.*", 3);
+	check_glob_iter(cfg, "remote\\.ab.*", 2);
+	check_glob_iter(cfg, ".*url$", 2);
+	check_glob_iter(cfg, ".*dummy.*", 2);
+	check_glob_iter(cfg, ".*nomatch.*", 0);
+
+	git_config_free(cfg);
+}
+
+void test_config_read__whitespace_not_required_around_assignment(void)
+{
+	git_config *cfg;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config14")));
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "a.b"));
+	cl_assert_equal_s("c", git_buf_cstr(&buf));
+	git_buf_clear(&buf);
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "d.e"));
+	cl_assert_equal_s("f", git_buf_cstr(&buf));
+
+	git_config_free(cfg);
+}
+
+void test_config_read__read_git_config_entry(void)
+{
+	git_config *cfg;
+	git_config_entry *entry;
+
+	cl_git_pass(git_config_new(&cfg));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
+		GIT_CONFIG_LEVEL_SYSTEM, 0));
+
+	cl_git_pass(git_config_get_entry(&entry, cfg, "core.dummy2"));
+	cl_assert_equal_s("core.dummy2", entry->name);
+	cl_assert_equal_s("42", entry->value);
+	cl_assert_equal_i(GIT_CONFIG_LEVEL_SYSTEM, entry->level);
+
+	git_config_entry_free(entry);
+	git_config_free(cfg);
+}
+
+/*
+ * At the beginning of the test:
+ *  - config9 has: core.dummy2=42
+ *  - config15 has: core.dummy2=7
+ *  - config16 has: core.dummy2=28
+ */
+void test_config_read__local_config_overrides_global_config_overrides_system_config(void)
+{
+	git_config *cfg;
+	int32_t i;
+
+	cl_git_pass(git_config_new(&cfg));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
+		GIT_CONFIG_LEVEL_SYSTEM, 0));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
+		GIT_CONFIG_LEVEL_GLOBAL, 0));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config16"),
+		GIT_CONFIG_LEVEL_LOCAL, 0));
+
+	cl_git_pass(git_config_get_int32(&i, cfg, "core.dummy2"));
+	cl_assert_equal_i(28, i);
+
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_new(&cfg));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
+		GIT_CONFIG_LEVEL_SYSTEM, 0));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
+		GIT_CONFIG_LEVEL_GLOBAL, 0));
+
+	cl_git_pass(git_config_get_int32(&i, cfg, "core.dummy2"));
+	cl_assert_equal_i(7, i);
+
+	git_config_free(cfg);
+}
+
+/*
+ * At the beginning of the test:
+ *  - config9 has: core.global does not exist
+ *  - config15 has: core.global=17
+ *  - config16 has: core.global=29
+ *
+ * And also:
+ *  - config9 has: core.system does not exist
+ *  - config15 has: core.system does not exist
+ *  - config16 has: core.system=11
+ */
+void test_config_read__fallback_from_local_to_global_and_from_global_to_system(void)
+{
+	git_config *cfg;
+	int32_t i;
+
+	cl_git_pass(git_config_new(&cfg));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
+		GIT_CONFIG_LEVEL_SYSTEM, 0));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
+		GIT_CONFIG_LEVEL_GLOBAL, 0));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config16"),
+		GIT_CONFIG_LEVEL_LOCAL, 0));
+
+	cl_git_pass(git_config_get_int32(&i, cfg, "core.global"));
+	cl_assert_equal_i(17, i);
+	cl_git_pass(git_config_get_int32(&i, cfg, "core.system"));
+	cl_assert_equal_i(11, i);
+
+	git_config_free(cfg);
+}
+
+/*
+ * At the beginning of the test, config18 has:
+ *	int32global = 28
+ *	int64global = 9223372036854775803
+ *	boolglobal = true
+ *	stringglobal = I'm a global config value!
+ *
+ * And config19 has:
+ *	int32global = -1
+ *	int64global = -2
+ *	boolglobal = false
+ *	stringglobal = don't find me!
+ *
+ */
+void test_config_read__simple_read_from_specific_level(void)
+{
+	git_config *cfg, *cfg_specific;
+	int i;
+	int64_t l, expected = +9223372036854775803;
+
+	cl_git_pass(git_config_new(&cfg));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config18"),
+		GIT_CONFIG_LEVEL_GLOBAL, 0));
+	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config19"),
+		GIT_CONFIG_LEVEL_SYSTEM, 0));
+
+	cl_git_pass(git_config_open_level(&cfg_specific, cfg, GIT_CONFIG_LEVEL_GLOBAL));
+
+	cl_git_pass(git_config_get_int32(&i, cfg_specific, "core.int32global"));
+	cl_assert_equal_i(28, i);
+	cl_git_pass(git_config_get_int64(&l, cfg_specific, "core.int64global"));
+	cl_assert(l == expected);
+	cl_git_pass(git_config_get_bool(&i, cfg_specific, "core.boolglobal"));
+	cl_assert_equal_b(true, i);
+	cl_git_pass(git_config_get_string_buf(&buf, cfg_specific, "core.stringglobal"));
+	cl_assert_equal_s("I'm a global config value!", git_buf_cstr(&buf));
+
+	git_config_free(cfg_specific);
+	git_config_free(cfg);
+}
+
+void test_config_read__can_load_and_parse_an_empty_config_file(void)
+{
+	git_config *cfg;
+	int i;
+
+	cl_set_cleanup(&clean_test_config, NULL);
+	cl_git_mkfile("./testconfig", "");
+	cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_config_get_int32(&i, cfg, "nope.neither"));
+
+	git_config_free(cfg);
+}
+
+void test_config_read__corrupt_header(void)
+{
+	git_config *cfg;
+
+	cl_set_cleanup(&clean_test_config, NULL);
+	cl_git_mkfile("./testconfig", "[sneaky ] \"quoted closing quote mark\\\"");
+	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));
+
+	git_config_free(cfg);
+}
+
+void test_config_read__corrupt_header2(void)
+{
+	git_config *cfg;
+
+	cl_set_cleanup(&clean_test_config, NULL);
+	cl_git_mkfile("./testconfig", "[unclosed \"bracket\"\n    lib = git2\n");
+	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));
+
+	git_config_free(cfg);
+}
+
+void test_config_read__corrupt_header3(void)
+{
+	git_config *cfg;
+
+	cl_set_cleanup(&clean_test_config, NULL);
+	cl_git_mkfile("./testconfig", "[unclosed \"slash\\\"]\n    lib = git2\n");
+	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));
+
+	git_config_free(cfg);
+}
+
+void test_config_read__invalid_key_chars(void)
+{
+	git_config *cfg;
+
+	cl_set_cleanup(&clean_test_config, NULL);
+	cl_git_mkfile("./testconfig", "[foo]\n    has_underscore = git2\n");
+	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));
+
+	cl_git_rewritefile("./testconfig", "[foo]\n  has/slash = git2\n");
+	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));
+
+	cl_git_rewritefile("./testconfig", "[foo]\n  has+plus = git2\n");
+	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));
+
+	cl_git_rewritefile("./testconfig", "[no_key]\n  = git2\n");
+	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));
+
+	git_config_free(cfg);
+}
+
+void test_config_read__lone_variable_with_trailing_whitespace(void)
+{
+	git_config *cfg;
+	int b;
+
+	cl_set_cleanup(&clean_test_config, NULL);
+	cl_git_mkfile("./testconfig", "[foo]\n    lonevariable   \n");
+	cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));
+
+	cl_git_pass(git_config_get_bool(&b, cfg, "foo.lonevariable"));
+	cl_assert_equal_b(true, b);
+
+	git_config_free(cfg);
+}
+
+void test_config_read__override_variable(void)
+{
+	git_config *cfg;
+
+	cl_set_cleanup(&clean_test_config, NULL);
+	cl_git_mkfile("./testconfig", "[some] var = one\nvar = two");
+	cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));
+
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.var"));
+	cl_assert_equal_s("two", git_buf_cstr(&buf));
+
+	git_config_free(cfg);
+}
+
+void test_config_read__path(void)
+{
+	git_config *cfg;
+	git_buf path = GIT_BUF_INIT;
+	git_buf old_path = GIT_BUF_INIT;
+	git_buf home_path = GIT_BUF_INIT;
+	git_buf expected_path = GIT_BUF_INIT;
+
+	cl_git_pass(p_mkdir("fakehome", 0777));
+	cl_git_pass(git_path_prettify(&home_path, "fakehome", NULL));
+	cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &old_path));
+	cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, home_path.ptr));
+	cl_git_mkfile("./testconfig", "[some]\n path = ~/somefile");
+	cl_git_pass(git_path_join_unrooted(&expected_path, "somefile", home_path.ptr, NULL));
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));
+	cl_git_pass(git_config_get_path(&path, cfg, "some.path"));
+	cl_assert_equal_s(expected_path.ptr, path.ptr);
+	git_buf_free(&path);
+
+	cl_git_mkfile("./testconfig", "[some]\n path = ~/");
+	cl_git_pass(git_path_join_unrooted(&expected_path, "", home_path.ptr, NULL));
+
+	cl_git_pass(git_config_get_path(&path, cfg, "some.path"));
+	cl_assert_equal_s(expected_path.ptr, path.ptr);
+	git_buf_free(&path);
+
+	cl_git_mkfile("./testconfig", "[some]\n path = ~");
+	cl_git_pass(git_buf_sets(&expected_path, home_path.ptr));
+
+	cl_git_pass(git_config_get_path(&path, cfg, "some.path"));
+	cl_assert_equal_s(expected_path.ptr, path.ptr);
+	git_buf_free(&path);
+
+	cl_git_mkfile("./testconfig", "[some]\n path = ~user/foo");
+	cl_git_fail(git_config_get_path(&path, cfg, "some.path"));
+
+	cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, old_path.ptr));
+	git_buf_free(&old_path);
+	git_buf_free(&home_path);
+	git_buf_free(&expected_path);
+	git_config_free(cfg);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/rename.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/rename.c
new file mode 100755
index 0000000..a461415
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/rename.c
@@ -0,0 +1,89 @@
+#include "clar_libgit2.h"
+#include "config.h"
+
+static git_repository *g_repo = NULL;
+static git_config *g_config = NULL;
+
+void test_config_rename__initialize(void)
+{
+    g_repo = cl_git_sandbox_init("testrepo.git");
+	cl_git_pass(git_repository_config(&g_config, g_repo));
+}
+
+void test_config_rename__cleanup(void)
+{
+	git_config_free(g_config);
+	g_config = NULL;
+
+	cl_git_sandbox_cleanup();
+	g_repo = NULL;
+}
+
+void test_config_rename__can_rename(void)
+{
+	git_config_entry *ce;
+
+	cl_git_pass(git_config_get_entry(
+		&ce, g_config, "branch.track-local.remote"));
+	cl_assert_equal_s(".", ce->value);
+	git_config_entry_free(ce);
+
+	cl_git_fail(git_config_get_entry(
+		&ce, g_config, "branch.local-track.remote"));
+
+	cl_git_pass(git_config_rename_section(
+		g_repo, "branch.track-local", "branch.local-track"));
+
+	cl_git_pass(git_config_get_entry(
+		&ce, g_config, "branch.local-track.remote"));
+	cl_assert_equal_s(".", ce->value);
+	git_config_entry_free(ce);
+
+	cl_git_fail(git_config_get_entry(
+		&ce, g_config, "branch.track-local.remote"));
+}
+
+void test_config_rename__prevent_overwrite(void)
+{
+	git_config_entry *ce;
+
+	cl_git_pass(git_config_set_string(
+		g_config, "branch.local-track.remote", "yellow"));
+
+	cl_git_pass(git_config_get_entry(
+		&ce, g_config, "branch.local-track.remote"));
+	cl_assert_equal_s("yellow", ce->value);
+	git_config_entry_free(ce);
+
+	cl_git_pass(git_config_rename_section(
+		g_repo, "branch.track-local", "branch.local-track"));
+
+	cl_git_pass(git_config_get_entry(
+		&ce, g_config, "branch.local-track.remote"));
+	cl_assert_equal_s(".", ce->value);
+	git_config_entry_free(ce);
+
+	/* so, we don't currently prevent overwrite... */
+	/* {
+		const git_error *err;
+		cl_assert((err = giterr_last()) != NULL);
+		cl_assert(err->message != NULL);
+	} */
+}
+
+static void assert_invalid_config_section_name(
+	git_repository *repo, const char *name)
+{
+	cl_git_fail_with(
+		git_config_rename_section(repo, "branch.remoteless", name),
+		GIT_EINVALIDSPEC);
+}
+
+void test_config_rename__require_a_valid_new_name(void)
+{
+	assert_invalid_config_section_name(g_repo, "");
+	assert_invalid_config_section_name(g_repo, "bra\nch");
+	assert_invalid_config_section_name(g_repo, "branc#");
+	assert_invalid_config_section_name(g_repo, "bra\nch.duh");
+	assert_invalid_config_section_name(g_repo, "branc#.duh");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/snapshot.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/snapshot.c
new file mode 100755
index 0000000..3ea07c1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/snapshot.c
@@ -0,0 +1,78 @@
+#include "clar_libgit2.h"
+
+void test_config_snapshot__create_snapshot(void)
+{
+	int32_t tmp;
+	git_config *cfg, *snapshot, *new_snapshot;
+	const char *filename = "config-ext-change";
+
+	cl_git_mkfile(filename, "[old]\nvalue = 5\n");
+
+	cl_git_pass(git_config_open_ondisk(&cfg, filename));
+
+	cl_git_pass(git_config_get_int32(&tmp, cfg, "old.value"));
+	cl_assert_equal_i(5, tmp);
+
+	cl_git_pass(git_config_snapshot(&snapshot, cfg));
+
+	/* Change the value on the file itself (simulate external process) */
+	cl_git_mkfile(filename, "[old]\nvalue = 56\n");
+
+	cl_git_pass(git_config_get_int32(&tmp, cfg, "old.value"));
+	cl_assert_equal_i(56, tmp);
+
+	cl_git_pass(git_config_get_int32(&tmp, snapshot, "old.value"));
+	cl_assert_equal_i(5, tmp);
+
+	/* Change the value on the file itself (simulate external process) */
+	cl_git_mkfile(filename, "[old]\nvalue = 999\n");
+
+	cl_git_pass(git_config_snapshot(&new_snapshot, cfg));
+
+	/* New snapshot should see new value */
+	cl_git_pass(git_config_get_int32(&tmp, new_snapshot, "old.value"));
+	cl_assert_equal_i(999, tmp);
+
+	/* Old snapshot should still have the old value */
+	cl_git_pass(git_config_get_int32(&tmp, snapshot, "old.value"));
+	cl_assert_equal_i(5, tmp);
+	
+	git_config_free(new_snapshot);
+	git_config_free(snapshot);
+	git_config_free(cfg);
+}
+
+static int count_me(const git_config_entry *entry, void *payload)
+{
+	int *n = (int *) payload;
+
+	GIT_UNUSED(entry);
+
+	(*n)++;
+
+	return 0;
+}
+
+void test_config_snapshot__multivar(void)
+{
+	int count = 0;
+	git_config *cfg, *snapshot;
+	const char *filename = "config-file";
+
+	cl_git_mkfile(filename, "[old]\nvalue = 5\nvalue = 6\n");
+
+	cl_git_pass(git_config_open_ondisk(&cfg, filename));
+	cl_git_pass(git_config_get_multivar_foreach(cfg, "old.value", NULL, count_me, &count));
+
+	cl_assert_equal_i(2, count);
+
+	cl_git_pass(git_config_snapshot(&snapshot, cfg));
+	git_config_free(cfg);
+
+	count = 0;
+	cl_git_pass(git_config_get_multivar_foreach(snapshot, "old.value", NULL, count_me, &count));
+
+	cl_assert_equal_i(2, count);
+
+	git_config_free(snapshot);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/stress.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/stress.c
new file mode 100755
index 0000000..503f44f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/stress.c
@@ -0,0 +1,109 @@
+#include "clar_libgit2.h"
+
+#include "filebuf.h"
+#include "fileops.h"
+#include "posix.h"
+
+#define TEST_CONFIG "git-test-config"
+
+static git_buf buf = GIT_BUF_INIT;
+
+void test_config_stress__initialize(void)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+
+	cl_git_pass(git_filebuf_open(&file, TEST_CONFIG, 0, 0666));
+
+	git_filebuf_printf(&file, "[color]\n\tui = auto\n");
+	git_filebuf_printf(&file, "[core]\n\teditor = \n");
+
+	cl_git_pass(git_filebuf_commit(&file));
+}
+
+void test_config_stress__cleanup(void)
+{
+	git_buf_free(&buf);
+	p_unlink(TEST_CONFIG);
+}
+
+void test_config_stress__dont_break_on_invalid_input(void)
+{
+	git_config *config;
+
+	cl_assert(git_path_exists(TEST_CONFIG));
+	cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG));
+
+	cl_git_pass(git_config_get_string_buf(&buf, config, "color.ui"));
+	cl_git_pass(git_config_get_string_buf(&buf, config, "core.editor"));
+
+	git_config_free(config);
+}
+
+void assert_config_value(git_config *config, const char *key, const char *value)
+{
+	git_buf_clear(&buf);
+	cl_git_pass(git_config_get_string_buf(&buf, config, key));
+	cl_assert_equal_s(value, git_buf_cstr(&buf));
+}
+
+void test_config_stress__comments(void)
+{
+	git_config *config;
+
+	cl_git_pass(git_config_open_ondisk(&config, cl_fixture("config/config12")));
+
+	assert_config_value(config, "some.section.test2", "hello");
+	assert_config_value(config, "some.section.test3", "welcome");
+	assert_config_value(config, "some.section.other", "hello! \" ; ; ; ");
+	assert_config_value(config, "some.section.other2", "cool! \" # # # ");
+	assert_config_value(config, "some.section.multi", "hi, this is a ; multiline comment # with ;\n special chars and other stuff !@#");
+	assert_config_value(config, "some.section.multi2", "good, this is a ; multiline comment # with ;\n special chars and other stuff !@#");
+	assert_config_value(config, "some.section.back", "this is \ba phrase");
+
+	git_config_free(config);
+}
+
+void test_config_stress__escape_subsection_names(void)
+{
+	git_config *config;
+
+	cl_assert(git_path_exists("git-test-config"));
+	cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG));
+
+	cl_git_pass(git_config_set_string(config, "some.sec\\tion.other", "foo"));
+	git_config_free(config);
+
+	cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG));
+
+	assert_config_value(config, "some.sec\\tion.other", "foo");
+
+	git_config_free(config);
+}
+
+void test_config_stress__trailing_backslash(void)
+{
+	git_config *config;
+	const char *path =  "C:\\iam\\some\\windows\\path\\";
+
+	cl_assert(git_path_exists("git-test-config"));
+	cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG));
+	cl_git_pass(git_config_set_string(config, "windows.path", path));
+	git_config_free(config);
+
+	cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG));
+	assert_config_value(config, "windows.path", path);
+
+	git_config_free(config);
+}
+
+void test_config_stress__complex(void)
+{
+	git_config *config;
+	const char *path = "./config-immediate-multiline";
+
+	cl_git_mkfile(path, "[imm]\n multi = \"\\\nfoo\"");
+	cl_git_pass(git_config_open_ondisk(&config, path));
+	assert_config_value(config, "imm.multi", "foo");
+
+	git_config_free(config);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/validkeyname.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/validkeyname.c
new file mode 100755
index 0000000..4b36509
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/validkeyname.c
@@ -0,0 +1,49 @@
+#include "clar_libgit2.h"
+
+#include "config.h"
+
+static git_config *cfg;
+
+void test_config_validkeyname__initialize(void)
+{
+	cl_fixture_sandbox("config/config10");
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config10"));
+}
+
+void test_config_validkeyname__cleanup(void)
+{
+	git_config_free(cfg);
+	cfg = NULL;
+
+	cl_fixture_cleanup("config10");
+}
+
+static void assert_invalid_config_key_name(const char *name)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_fail_with(git_config_get_string_buf(&buf, cfg, name),
+		GIT_EINVALIDSPEC);
+	cl_git_fail_with(git_config_set_string(cfg, name, "42"),
+		GIT_EINVALIDSPEC);
+	cl_git_fail_with(git_config_delete_entry(cfg, name),
+		GIT_EINVALIDSPEC);
+	cl_git_fail_with(git_config_get_multivar_foreach(cfg, name, "*", NULL, NULL),
+		GIT_EINVALIDSPEC);
+	cl_git_fail_with(git_config_set_multivar(cfg, name, "*", "42"),
+		GIT_EINVALIDSPEC);
+}
+
+void test_config_validkeyname__accessing_requires_a_valid_name(void)
+{
+	assert_invalid_config_key_name("");
+	assert_invalid_config_key_name(".");
+	assert_invalid_config_key_name("..");
+	assert_invalid_config_key_name("core.");
+	assert_invalid_config_key_name("d#ff.dirstat.lines");
+	assert_invalid_config_key_name("diff.dirstat.lines#");
+	assert_invalid_config_key_name("dif\nf.dirstat.lines");
+	assert_invalid_config_key_name("dif.dir\nstat.lines");
+	assert_invalid_config_key_name("dif.dirstat.li\nes");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/write.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/write.c
new file mode 100755
index 0000000..2e7b818
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/config/write.c
@@ -0,0 +1,632 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "fileops.h"
+
+void test_config_write__initialize(void)
+{
+	cl_fixture_sandbox("config/config9");
+	cl_fixture_sandbox("config/config15");
+	cl_fixture_sandbox("config/config17");
+}
+
+void test_config_write__cleanup(void)
+{
+	cl_fixture_cleanup("config9");
+	cl_fixture_cleanup("config15");
+	cl_fixture_cleanup("config17");
+}
+
+void test_config_write__replace_value(void)
+{
+	git_config *cfg;
+	int i;
+	int64_t l, expected = +9223372036854775803;
+
+	/* By freeing the config, we make sure we flush the values  */
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_set_int32(cfg, "core.dummy", 5));
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_get_int32(&i, cfg, "core.dummy"));
+	cl_assert(i == 5);
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_set_int32(cfg, "core.dummy", 1));
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_set_int64(cfg, "core.verylong", expected));
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_get_int64(&l, cfg, "core.verylong"));
+	cl_assert(l == expected);
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_must_fail(git_config_get_int32(&i, cfg, "core.verylong"));
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_set_int64(cfg, "core.verylong", 1));
+	git_config_free(cfg);
+}
+
+void test_config_write__delete_value(void)
+{
+	git_config *cfg;
+	int32_t i;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_set_int32(cfg, "core.dummy", 5));
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_delete_entry(cfg, "core.dummy"));
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_assert(git_config_get_int32(&i, cfg, "core.dummy") == GIT_ENOTFOUND);
+	cl_git_pass(git_config_set_int32(cfg, "core.dummy", 1));
+	git_config_free(cfg);
+}
+
+/*
+ * At the beginning of the test:
+ *  - config9 has: core.dummy2=42
+ *  - config15 has: core.dummy2=7
+ */
+void test_config_write__delete_value_at_specific_level(void)
+{
+	git_config *cfg, *cfg_specific;
+	int32_t i;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config15"));
+	cl_git_pass(git_config_get_int32(&i, cfg, "core.dummy2"));
+	cl_assert(i == 7);
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_new(&cfg));
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config9",
+		GIT_CONFIG_LEVEL_LOCAL, 0));
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config15",
+		GIT_CONFIG_LEVEL_GLOBAL, 0));
+
+	cl_git_pass(git_config_open_level(&cfg_specific, cfg, GIT_CONFIG_LEVEL_GLOBAL));
+
+	cl_git_pass(git_config_delete_entry(cfg_specific, "core.dummy2"));
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config15"));
+	cl_assert(git_config_get_int32(&i, cfg, "core.dummy2") == GIT_ENOTFOUND);
+	cl_git_pass(git_config_set_int32(cfg, "core.dummy2", 7));
+
+	git_config_free(cfg_specific);
+	git_config_free(cfg);
+}
+
+/*
+ * This test exposes a bug where duplicate empty section headers could prevent
+ * deletion of config entries.
+ */
+void test_config_write__delete_value_with_duplicate_header(void)
+{
+	const char *file_name  = "config-duplicate-header";
+	const char *entry_name = "remote.origin.url";
+	git_config *cfg;
+	git_config_entry *entry;
+
+	/* This config can occur after removing and re-adding the origin remote */
+	const char *file_content =
+		"[remote \"origin\"]\n"		\
+		"[branch \"master\"]\n"		\
+		"	remote = \"origin\"\n"	\
+		"[remote \"origin\"]\n"		\
+		"	url = \"foo\"\n";
+
+	/* Write the test config and make sure the expected entry exists */
+	cl_git_mkfile(file_name, file_content);
+	cl_git_pass(git_config_open_ondisk(&cfg, file_name));
+	cl_git_pass(git_config_get_entry(&entry, cfg, entry_name));
+
+	/* Delete that entry */
+	cl_git_pass(git_config_delete_entry(cfg, entry_name));
+
+	/* Reopen the file and make sure the entry no longer exists */
+	git_config_entry_free(entry);
+	git_config_free(cfg);
+	cl_git_pass(git_config_open_ondisk(&cfg, file_name));
+	cl_git_fail(git_config_get_entry(&entry, cfg, entry_name));
+
+	/* Cleanup */
+	git_config_entry_free(entry);
+	git_config_free(cfg);
+}
+
+/*
+ * This test exposes a bug where duplicate section headers could cause
+ * config_write to add a new entry when one already exists.
+ */
+void test_config_write__add_value_with_duplicate_header(void)
+{
+	const char *file_name  = "config-duplicate-insert";
+	const char *entry_name = "foo.c";
+	const char *old_val    = "old";
+	const char *new_val    = "new";
+	const char *str;
+	git_config *cfg, *snapshot;
+
+	/* c = old should be replaced by c = new.
+	 * The bug causes c = new to be inserted under the first 'foo' header.
+	 */
+	const char *file_content =
+		"[foo]\n"   \
+		"  a = b\n" \
+		"[other]\n" \
+		"  a = b\n" \
+		"[foo]\n"   \
+		"  c = old\n";
+
+	/* Write the test config */
+	cl_git_mkfile(file_name, file_content);
+	cl_git_pass(git_config_open_ondisk(&cfg, file_name));
+
+	/* make sure the expected entry (foo.c) exists */
+	cl_git_pass(git_config_snapshot(&snapshot, cfg));
+	cl_git_pass(git_config_get_string(&str, snapshot, entry_name));
+	cl_assert_equal_s(old_val, str);
+	git_config_free(snapshot);
+
+	/* Try setting foo.c to something else */
+	cl_git_pass(git_config_set_string(cfg, entry_name, new_val));
+	git_config_free(cfg);
+
+	/* Reopen the file and make sure the new value was set */
+	cl_git_pass(git_config_open_ondisk(&cfg, file_name));
+	cl_git_pass(git_config_snapshot(&snapshot, cfg));
+	cl_git_pass(git_config_get_string(&str, snapshot, entry_name));
+	cl_assert_equal_s(new_val, str);
+
+	/* Cleanup */
+	git_config_free(snapshot);
+	git_config_free(cfg);
+}
+
+void test_config_write__overwrite_value_with_duplicate_header(void)
+{
+	const char *file_name  = "config-duplicate-header";
+	const char *entry_name = "remote.origin.url";
+	git_config *cfg;
+	git_config_entry *entry;
+
+	/* This config can occur after removing and re-adding the origin remote */
+	const char *file_content =
+		"[remote \"origin\"]\n"		\
+		"[branch \"master\"]\n"		\
+		"	remote = \"origin\"\n"	\
+		"[remote \"origin\"]\n"		\
+		"	url = \"foo\"\n";
+
+	/* Write the test config and make sure the expected entry exists */
+	cl_git_mkfile(file_name, file_content);
+	cl_git_pass(git_config_open_ondisk(&cfg, file_name));
+	cl_git_pass(git_config_get_entry(&entry, cfg, entry_name));
+
+	/* Update that entry */
+	cl_git_pass(git_config_set_string(cfg, entry_name, "newurl"));
+
+	/* Reopen the file and make sure the entry was updated */
+	git_config_entry_free(entry);
+	git_config_free(cfg);
+	cl_git_pass(git_config_open_ondisk(&cfg, file_name));
+	cl_git_pass(git_config_get_entry(&entry, cfg, entry_name));
+
+	cl_assert_equal_s("newurl", entry->value);
+
+	/* Cleanup */
+	git_config_entry_free(entry);
+	git_config_free(cfg);
+}
+
+static int multivar_cb(const git_config_entry *entry, void *data)
+{
+	int *n = (int *)data;
+
+	cl_assert_equal_s(entry->value, "newurl");
+
+	(*n)++;
+
+	return 0;
+}
+
+void test_config_write__overwrite_multivar_within_duplicate_header(void)
+{
+	const char *file_name  = "config-duplicate-header";
+	const char *entry_name = "remote.origin.url";
+	git_config *cfg;
+	git_config_entry *entry;
+	int n = 0;
+
+	/* This config can occur after removing and re-adding the origin remote */
+	const char *file_content =
+		"[remote \"origin\"]\n"		\
+		"	url = \"bar\"\n"		\
+		"[branch \"master\"]\n"		\
+		"	remote = \"origin\"\n"	\
+		"[remote \"origin\"]\n"		\
+		"	url = \"foo\"\n";
+
+	/* Write the test config and make sure the expected entry exists */
+	cl_git_mkfile(file_name, file_content);
+	cl_git_pass(git_config_open_ondisk(&cfg, file_name));
+	cl_git_pass(git_config_get_entry(&entry, cfg, entry_name));
+
+	/* Update that entry */
+	cl_git_pass(git_config_set_multivar(cfg, entry_name, ".*", "newurl"));
+	git_config_entry_free(entry);
+	git_config_free(cfg);
+
+	/* Reopen the file and make sure the entry was updated */
+	cl_git_pass(git_config_open_ondisk(&cfg, file_name));
+	cl_git_pass(git_config_get_multivar_foreach(cfg, entry_name, NULL, multivar_cb, &n));
+	cl_assert_equal_i(2, n);
+
+	/* Cleanup */
+	git_config_free(cfg);
+}
+
+void test_config_write__write_subsection(void)
+{
+	git_config *cfg;
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_set_string(cfg, "my.own.var", "works"));
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "my.own.var"));
+	cl_assert_equal_s("works", git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+	git_config_free(cfg);
+}
+
+void test_config_write__delete_inexistent(void)
+{
+	git_config *cfg;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_assert(git_config_delete_entry(cfg, "core.imaginary") == GIT_ENOTFOUND);
+	git_config_free(cfg);
+}
+
+void test_config_write__value_containing_quotes(void)
+{
+	git_config *cfg;
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_set_string(cfg, "core.somevar", "this \"has\" quotes"));
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar"));
+	cl_assert_equal_s("this \"has\" quotes", git_buf_cstr(&buf));
+	git_buf_clear(&buf);
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar"));
+	cl_assert_equal_s("this \"has\" quotes", git_buf_cstr(&buf));
+	git_buf_clear(&buf);
+	git_config_free(cfg);
+
+	/* The code path for values that already exist is different, check that one as well */
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_set_string(cfg, "core.somevar", "this also \"has\" quotes"));
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar"));
+	cl_assert_equal_s("this also \"has\" quotes", git_buf_cstr(&buf));
+	git_buf_clear(&buf);
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar"));
+	cl_assert_equal_s("this also \"has\" quotes", git_buf_cstr(&buf));
+	git_buf_free(&buf);
+	git_config_free(cfg);
+}
+
+void test_config_write__escape_value(void)
+{
+	git_config *cfg;
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_set_string(cfg, "core.somevar", "this \"has\" quotes and \t"));
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar"));
+	cl_assert_equal_s("this \"has\" quotes and \t", git_buf_cstr(&buf));
+	git_buf_clear(&buf);
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar"));
+	cl_assert_equal_s("this \"has\" quotes and \t", git_buf_cstr(&buf));
+	git_buf_free(&buf);
+	git_config_free(cfg);
+}
+
+void test_config_write__add_value_at_specific_level(void)
+{
+	git_config *cfg, *cfg_specific;
+	int i;
+	int64_t l, expected = +9223372036854775803;
+	git_buf buf = GIT_BUF_INIT;
+
+	// open config15 as global level config file
+	cl_git_pass(git_config_new(&cfg));
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config9",
+		GIT_CONFIG_LEVEL_LOCAL, 0));
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config15",
+		GIT_CONFIG_LEVEL_GLOBAL, 0));
+
+	cl_git_pass(git_config_open_level(&cfg_specific, cfg, GIT_CONFIG_LEVEL_GLOBAL));
+
+	cl_git_pass(git_config_set_int32(cfg_specific, "core.int32global", 28));
+	cl_git_pass(git_config_set_int64(cfg_specific, "core.int64global", expected));
+	cl_git_pass(git_config_set_bool(cfg_specific, "core.boolglobal", true));
+	cl_git_pass(git_config_set_string(cfg_specific, "core.stringglobal", "I'm a global config value!"));
+	git_config_free(cfg_specific);
+	git_config_free(cfg);
+
+	// open config15 as local level config file
+	cl_git_pass(git_config_open_ondisk(&cfg, "config15"));
+
+	cl_git_pass(git_config_get_int32(&i, cfg, "core.int32global"));
+	cl_assert_equal_i(28, i);
+	cl_git_pass(git_config_get_int64(&l, cfg, "core.int64global"));
+	cl_assert(l == expected);
+	cl_git_pass(git_config_get_bool(&i, cfg, "core.boolglobal"));
+	cl_assert_equal_b(true, i);
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.stringglobal"));
+	cl_assert_equal_s("I'm a global config value!", git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+	git_config_free(cfg);
+}
+
+void test_config_write__add_value_at_file_with_no_clrf_at_the_end(void)
+{
+	git_config *cfg;
+	int i;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config17"));
+	cl_git_pass(git_config_set_int32(cfg, "core.newline", 7));
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config17"));
+	cl_git_pass(git_config_get_int32(&i, cfg, "core.newline"));
+	cl_assert_equal_i(7, i);
+
+	git_config_free(cfg);
+}
+
+void test_config_write__add_section_at_file_with_no_clrf_at_the_end(void)
+{
+	git_config *cfg;
+	int i;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config17"));
+	cl_git_pass(git_config_set_int32(cfg, "diff.context", 10));
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config17"));
+	cl_git_pass(git_config_get_int32(&i, cfg, "diff.context"));
+	cl_assert_equal_i(10, i);
+
+	git_config_free(cfg);
+}
+
+void test_config_write__add_value_which_needs_quotes(void)
+{
+	git_config *cfg, *base;
+	const char* str1;
+	const char* str2;
+	const char* str3;
+	const char* str4;
+	const char* str5;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config17"));
+	cl_git_pass(git_config_set_string(cfg, "core.startwithspace", " Something"));
+	cl_git_pass(git_config_set_string(cfg, "core.endwithspace", "Something "));
+	cl_git_pass(git_config_set_string(cfg, "core.containscommentchar1", "some#thing"));
+	cl_git_pass(git_config_set_string(cfg, "core.containscommentchar2", "some;thing"));
+	cl_git_pass(git_config_set_string(cfg, "core.startwhithsapceandcontainsdoublequote", " some\"thing"));
+	git_config_free(cfg);
+
+	cl_git_pass(git_config_open_ondisk(&base, "config17"));
+	cl_git_pass(git_config_snapshot(&cfg, base));
+	cl_git_pass(git_config_get_string(&str1, cfg, "core.startwithspace"));
+	cl_assert_equal_s(" Something", str1);
+	cl_git_pass(git_config_get_string(&str2, cfg, "core.endwithspace"));
+	cl_assert_equal_s("Something ", str2);
+	cl_git_pass(git_config_get_string(&str3, cfg, "core.containscommentchar1"));
+	cl_assert_equal_s("some#thing", str3);
+	cl_git_pass(git_config_get_string(&str4, cfg, "core.containscommentchar2"));
+	cl_assert_equal_s("some;thing", str4);
+	cl_git_pass(git_config_get_string(&str5, cfg, "core.startwhithsapceandcontainsdoublequote"));
+	cl_assert_equal_s(" some\"thing", str5);
+	git_config_free(cfg);
+	git_config_free(base);
+}
+
+void test_config_write__can_set_a_value_to_NULL(void)
+{
+    git_repository *repository;
+    git_config *config;
+
+    repository = cl_git_sandbox_init("testrepo.git");
+
+    cl_git_pass(git_repository_config(&config, repository));
+    cl_git_fail(git_config_set_string(config, "a.b.c", NULL));
+    git_config_free(config);
+
+    cl_git_sandbox_cleanup();
+}
+
+void test_config_write__can_set_an_empty_value(void)
+{
+	git_repository *repository;
+	git_config *config;
+	git_buf buf = {0};
+
+	repository = cl_git_sandbox_init("testrepo.git");
+	cl_git_pass(git_repository_config(&config, repository));
+
+	cl_git_pass(git_config_set_string(config, "core.somevar", ""));
+	cl_git_pass(git_config_get_string_buf(&buf, config, "core.somevar"));
+	cl_assert_equal_s("", buf.ptr);
+
+	git_buf_free(&buf);
+	git_config_free(config);
+	cl_git_sandbox_cleanup();
+}
+
+void test_config_write__updating_a_locked_config_file_returns_ELOCKED(void)
+{
+	git_config *cfg;
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "config9"));
+
+	cl_git_mkfile("config9.lock", "[core]\n");
+
+	cl_git_fail_with(git_config_set_string(cfg, "core.dump", "boom"), GIT_ELOCKED);
+
+	git_config_free(cfg);
+}
+
+void test_config_write__outside_change(void)
+{
+	int32_t tmp;
+	git_config *cfg;
+	const char *filename = "config-ext-change";
+
+	cl_git_mkfile(filename, "[old]\nvalue = 5\n");
+
+	cl_git_pass(git_config_open_ondisk(&cfg, filename));
+
+	cl_git_pass(git_config_get_int32(&tmp, cfg, "old.value"));
+
+	/* Change the value on the file itself (simulate external process) */
+	cl_git_mkfile(filename, "[old]\nvalue = 6\n");
+
+	cl_git_pass(git_config_set_int32(cfg, "new.value", 7));
+
+	cl_git_pass(git_config_get_int32(&tmp, cfg, "old.value"));
+	cl_assert_equal_i(6, tmp);
+
+	git_config_free(cfg);
+}
+
+#define SECTION_FOO \
+	"\n"                     \
+	"    \n"                 \
+	" [section \"foo\"]  \n" \
+	" # here's a comment\n"  \
+	"\tname = \"value\"\n"   \
+	"  name2 = \"value2\"\n" \
+	";  another comment!\n"
+
+#define SECTION_BAR \
+	"[section \"bar\"]\t\n"  \
+	"\t  \n"                 \
+	" barname=\"value\"\n"
+
+
+void test_config_write__preserves_whitespace_and_comments(void)
+{
+	const char *file_name  = "config-duplicate-header";
+	const char *n;
+	git_config *cfg;
+	git_buf newfile = GIT_BUF_INIT;
+
+	/* This config can occur after removing and re-adding the origin remote */
+	const char *file_content = SECTION_FOO SECTION_BAR;
+
+	/* Write the test config and make sure the expected entry exists */
+	cl_git_mkfile(file_name, file_content);
+	cl_git_pass(git_config_open_ondisk(&cfg, file_name));
+	cl_git_pass(git_config_set_string(cfg, "section.foo.other", "otherval"));
+	cl_git_pass(git_config_set_string(cfg, "newsection.newname", "new_value"));
+
+	/* Ensure that we didn't needlessly mangle the config file */
+	cl_git_pass(git_futils_readbuffer(&newfile, file_name));
+	n = newfile.ptr;
+
+	cl_assert_equal_strn(SECTION_FOO, n, strlen(SECTION_FOO));
+	n += strlen(SECTION_FOO);
+
+	cl_assert_equal_strn("\tother = otherval\n", n, strlen("\tother = otherval\n"));
+	n += strlen("\tother = otherval\n");
+
+	cl_assert_equal_strn(SECTION_BAR, n, strlen(SECTION_BAR));
+	n += strlen(SECTION_BAR);
+
+	cl_assert_equal_s("[newsection]\n\tnewname = new_value\n", n);
+
+	git_buf_free(&newfile);
+	git_config_free(cfg);
+}
+
+void test_config_write__preserves_entry_with_name_only(void)
+{
+	const char *file_name  = "config-empty-value";
+	git_config *cfg;
+	git_buf newfile = GIT_BUF_INIT;
+
+	/* Write the test config and make sure the expected entry exists */
+	cl_git_mkfile(file_name, "[section \"foo\"]\n\tname\n");
+	cl_git_pass(git_config_open_ondisk(&cfg, file_name));
+	cl_git_pass(git_config_set_string(cfg, "newsection.newname", "new_value"));
+	cl_git_pass(git_config_set_string(cfg, "section.foo.other", "otherval"));
+
+	cl_git_pass(git_futils_readbuffer(&newfile, file_name));
+	cl_assert_equal_s("[section \"foo\"]\n\tname\n\tother = otherval\n[newsection]\n\tnewname = new_value\n", newfile.ptr);
+
+	git_buf_free(&newfile);
+	git_config_free(cfg);
+}
+
+void test_config_write__to_empty_file(void)
+{
+	git_config *cfg;
+	const char *filename = "config-file";
+	git_buf result = GIT_BUF_INIT;
+
+	cl_git_mkfile(filename, "");
+	cl_git_pass(git_config_open_ondisk(&cfg, filename));
+	cl_git_pass(git_config_set_string(cfg, "section.name", "value"));
+	git_config_free(cfg);
+
+	cl_git_pass(git_futils_readbuffer(&result, "config-file"));
+	cl_assert_equal_s("[section]\n\tname = value\n", result.ptr);
+
+	git_buf_free(&result);
+}
+
+void test_config_write__to_file_with_only_comment(void)
+{
+	git_config *cfg;
+	const char *filename = "config-file";
+	git_buf result = GIT_BUF_INIT;
+
+	cl_git_mkfile(filename, "\n\n");
+	cl_git_pass(git_config_open_ondisk(&cfg, filename));
+	cl_git_pass(git_config_set_string(cfg, "section.name", "value"));
+	git_config_free(cfg);
+
+	cl_git_pass(git_futils_readbuffer(&result, "config-file"));
+	cl_assert_equal_s("\n\n[section]\n\tname = value\n", result.ptr);
+
+	git_buf_free(&result);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/bitvec.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/bitvec.c
new file mode 100755
index 0000000..48d7b99
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/bitvec.c
@@ -0,0 +1,64 @@
+#include "clar_libgit2.h"
+#include "bitvec.h"
+
+#if 0
+static void print_bitvec(git_bitvec *bv)
+{
+	int b;
+
+	if (!bv->length) {
+		for (b = 63; b >= 0; --b)
+			fprintf(stderr, "%d", (bv->u.bits & (1ul << b)) ? 1 : 0);
+	} else {
+		for (b = bv->length * 8; b >= 0; --b)
+			fprintf(stderr, "%d", (bv->u.ptr[b >> 3] & (b & 0x0ff)) ? 1 : 0);
+	}
+	fprintf(stderr, "\n");
+}
+#endif
+
+static void set_some_bits(git_bitvec *bv, size_t length)
+{
+	size_t i;
+
+	for (i = 0; i < length; ++i) {
+		if (i % 3 == 0 || i % 7 == 0)
+			git_bitvec_set(bv, i, true);
+	}
+}
+
+static void check_some_bits(git_bitvec *bv, size_t length)
+{
+	size_t i;
+
+	for (i = 0; i < length; ++i)
+		cl_assert_equal_b(i % 3 == 0 || i % 7 == 0, git_bitvec_get(bv, i));
+}
+
+void test_core_bitvec__0(void)
+{
+	git_bitvec bv;
+
+	cl_git_pass(git_bitvec_init(&bv, 32));
+	set_some_bits(&bv, 16);
+	check_some_bits(&bv, 16);
+	git_bitvec_clear(&bv);
+	set_some_bits(&bv, 32);
+	check_some_bits(&bv, 32);
+	git_bitvec_clear(&bv);
+	set_some_bits(&bv, 64);
+	check_some_bits(&bv, 64);
+	git_bitvec_free(&bv);
+
+	cl_git_pass(git_bitvec_init(&bv, 128));
+	set_some_bits(&bv, 32);
+	check_some_bits(&bv, 32);
+	set_some_bits(&bv, 128);
+	check_some_bits(&bv, 128);
+	git_bitvec_free(&bv);
+
+	cl_git_pass(git_bitvec_init(&bv, 4000));
+	set_some_bits(&bv, 4000);
+	check_some_bits(&bv, 4000);
+	git_bitvec_free(&bv);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/buffer.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/buffer.c
new file mode 100755
index 0000000..0e7026a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/buffer.c
@@ -0,0 +1,1168 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "buf_text.h"
+#include "git2/sys/hashsig.h"
+#include "fileops.h"
+
+#define TESTSTR "Have you seen that? Have you seeeen that??"
+const char *test_string = TESTSTR;
+const char *test_string_x2 = TESTSTR TESTSTR;
+
+#define TESTSTR_4096 REP1024("1234")
+#define TESTSTR_8192 REP1024("12341234")
+const char *test_4096 = TESTSTR_4096;
+const char *test_8192 = TESTSTR_8192;
+
+/* test basic data concatenation */
+void test_core_buffer__0(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_assert(buf.size == 0);
+
+	git_buf_puts(&buf, test_string);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(test_string, git_buf_cstr(&buf));
+
+	git_buf_puts(&buf, test_string);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(test_string_x2, git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+}
+
+/* test git_buf_printf */
+void test_core_buffer__1(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	git_buf_printf(&buf, "%s %s %d ", "shoop", "da", 23);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s("shoop da 23 ", git_buf_cstr(&buf));
+
+	git_buf_printf(&buf, "%s %d", "woop", 42);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s("shoop da 23 woop 42", git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+}
+
+/* more thorough test of concatenation options */
+void test_core_buffer__2(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	int i;
+	char data[128];
+
+	cl_assert(buf.size == 0);
+
+	/* this must be safe to do */
+	git_buf_free(&buf);
+	cl_assert(buf.size == 0);
+	cl_assert(buf.asize == 0);
+
+	/* empty buffer should be empty string */
+	cl_assert_equal_s("", git_buf_cstr(&buf));
+	cl_assert(buf.size == 0);
+	/* cl_assert(buf.asize == 0); -- should not assume what git_buf does */
+
+	/* free should set us back to the beginning */
+	git_buf_free(&buf);
+	cl_assert(buf.size == 0);
+	cl_assert(buf.asize == 0);
+
+	/* add letter */
+	git_buf_putc(&buf, '+');
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s("+", git_buf_cstr(&buf));
+
+	/* add letter again */
+	git_buf_putc(&buf, '+');
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s("++", git_buf_cstr(&buf));
+
+	/* let's try that a few times */
+	for (i = 0; i < 16; ++i) {
+		git_buf_putc(&buf, '+');
+		cl_assert(git_buf_oom(&buf) == 0);
+	}
+	cl_assert_equal_s("++++++++++++++++++", git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+
+	/* add data */
+	git_buf_put(&buf, "xo", 2);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s("xo", git_buf_cstr(&buf));
+
+	/* add letter again */
+	git_buf_put(&buf, "xo", 2);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s("xoxo", git_buf_cstr(&buf));
+
+	/* let's try that a few times */
+	for (i = 0; i < 16; ++i) {
+		git_buf_put(&buf, "xo", 2);
+		cl_assert(git_buf_oom(&buf) == 0);
+	}
+	cl_assert_equal_s("xoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxo",
+					   git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+
+	/* set to string */
+	git_buf_sets(&buf, test_string);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(test_string, git_buf_cstr(&buf));
+
+	/* append string */
+	git_buf_puts(&buf, test_string);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(test_string_x2, git_buf_cstr(&buf));
+
+	/* set to string again (should overwrite - not append) */
+	git_buf_sets(&buf, test_string);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(test_string, git_buf_cstr(&buf));
+
+	/* test clear */
+	git_buf_clear(&buf);
+	cl_assert_equal_s("", git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+
+	/* test extracting data into buffer */
+	git_buf_puts(&buf, REP4("0123456789"));
+	cl_assert(git_buf_oom(&buf) == 0);
+
+	git_buf_copy_cstr(data, sizeof(data), &buf);
+	cl_assert_equal_s(REP4("0123456789"), data);
+	git_buf_copy_cstr(data, 11, &buf);
+	cl_assert_equal_s("0123456789", data);
+	git_buf_copy_cstr(data, 3, &buf);
+	cl_assert_equal_s("01", data);
+	git_buf_copy_cstr(data, 1, &buf);
+	cl_assert_equal_s("", data);
+
+	git_buf_copy_cstr(data, sizeof(data), &buf);
+	cl_assert_equal_s(REP4("0123456789"), data);
+
+	git_buf_sets(&buf, REP256("x"));
+	git_buf_copy_cstr(data, sizeof(data), &buf);
+	/* since sizeof(data) == 128, only 127 bytes should be copied */
+	cl_assert_equal_s(REP4(REP16("x")) REP16("x") REP16("x")
+					   REP16("x") "xxxxxxxxxxxxxxx", data);
+
+	git_buf_free(&buf);
+
+	git_buf_copy_cstr(data, sizeof(data), &buf);
+	cl_assert_equal_s("", data);
+}
+
+/* let's do some tests with larger buffers to push our limits */
+void test_core_buffer__3(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	/* set to string */
+	git_buf_set(&buf, test_4096, 4096);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(test_4096, git_buf_cstr(&buf));
+
+	/* append string */
+	git_buf_puts(&buf, test_4096);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(test_8192, git_buf_cstr(&buf));
+
+	/* set to string again (should overwrite - not append) */
+	git_buf_set(&buf, test_4096, 4096);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(test_4096, git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+}
+
+/* let's try some producer/consumer tests */
+void test_core_buffer__4(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	int i;
+
+	for (i = 0; i < 10; ++i) {
+		git_buf_puts(&buf, "1234"); /* add 4 */
+		cl_assert(git_buf_oom(&buf) == 0);
+		git_buf_consume(&buf, buf.ptr + 2); /* eat the first two */
+		cl_assert(strlen(git_buf_cstr(&buf)) == (size_t)((i + 1) * 2));
+	}
+	/* we have appended 1234 10x and removed the first 20 letters */
+	cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));
+
+	git_buf_consume(&buf, NULL);
+	cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));
+
+	git_buf_consume(&buf, "invalid pointer");
+	cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));
+
+	git_buf_consume(&buf, buf.ptr);
+	cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));
+
+	git_buf_consume(&buf, buf.ptr + 1);
+	cl_assert_equal_s("2341234123412341234", git_buf_cstr(&buf));
+
+	git_buf_consume(&buf, buf.ptr + buf.size);
+	cl_assert_equal_s("", git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+}
+
+
+static void
+check_buf_append(
+	const char* data_a,
+	const char* data_b,
+	const char* expected_data,
+	size_t expected_size,
+	size_t expected_asize)
+{
+	git_buf tgt = GIT_BUF_INIT;
+
+	git_buf_sets(&tgt, data_a);
+	cl_assert(git_buf_oom(&tgt) == 0);
+	git_buf_puts(&tgt, data_b);
+	cl_assert(git_buf_oom(&tgt) == 0);
+	cl_assert_equal_s(expected_data, git_buf_cstr(&tgt));
+	cl_assert(tgt.size == expected_size);
+	if (expected_asize > 0)
+		cl_assert(tgt.asize == expected_asize);
+
+	git_buf_free(&tgt);
+}
+
+static void
+check_buf_append_abc(
+	const char* buf_a,
+	const char* buf_b,
+	const char* buf_c,
+	const char* expected_ab,
+	const char* expected_abc,
+	const char* expected_abca,
+	const char* expected_abcab,
+	const char* expected_abcabc)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	git_buf_sets(&buf, buf_a);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(buf_a, git_buf_cstr(&buf));
+
+	git_buf_puts(&buf, buf_b);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(expected_ab, git_buf_cstr(&buf));
+
+	git_buf_puts(&buf, buf_c);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(expected_abc, git_buf_cstr(&buf));
+
+	git_buf_puts(&buf, buf_a);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(expected_abca, git_buf_cstr(&buf));
+
+	git_buf_puts(&buf, buf_b);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(expected_abcab, git_buf_cstr(&buf));
+
+	git_buf_puts(&buf, buf_c);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(expected_abcabc, git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+}
+
+/* more variations on append tests */
+void test_core_buffer__5(void)
+{
+	check_buf_append("", "", "", 0, 0);
+	check_buf_append("a", "", "a", 1, 0);
+	check_buf_append("", "a", "a", 1, 8);
+	check_buf_append("", "a", "a", 1, 8);
+	check_buf_append("a", "b", "ab", 2, 8);
+	check_buf_append("", "abcdefgh", "abcdefgh", 8, 16);
+	check_buf_append("abcdefgh", "", "abcdefgh", 8, 16);
+
+	/* buffer with starting asize will grow to:
+	 *  1 ->  2,  2 ->  3,  3 ->  5,  4 ->  6,  5 ->  8,  6 ->  9,
+	 *  7 -> 11,  8 -> 12,  9 -> 14, 10 -> 15, 11 -> 17, 12 -> 18,
+	 * 13 -> 20, 14 -> 21, 15 -> 23, 16 -> 24, 17 -> 26, 18 -> 27,
+	 * 19 -> 29, 20 -> 30, 21 -> 32, 22 -> 33, 23 -> 35, 24 -> 36,
+	 * ...
+	 * follow sequence until value > target size,
+	 * then round up to nearest multiple of 8.
+	 */
+
+	check_buf_append("abcdefgh", "/", "abcdefgh/", 9, 16);
+	check_buf_append("abcdefgh", "ijklmno", "abcdefghijklmno", 15, 16);
+	check_buf_append("abcdefgh", "ijklmnop", "abcdefghijklmnop", 16, 24);
+	check_buf_append("0123456789", "0123456789",
+					 "01234567890123456789", 20, 24);
+	check_buf_append(REP16("x"), REP16("o"),
+					 REP16("x") REP16("o"), 32, 40);
+
+	check_buf_append(test_4096, "", test_4096, 4096, 4104);
+	check_buf_append(test_4096, test_4096, test_8192, 8192, 9240);
+
+	/* check sequences of appends */
+	check_buf_append_abc("a", "b", "c",
+						 "ab", "abc", "abca", "abcab", "abcabc");
+	check_buf_append_abc("a1", "b2", "c3",
+						 "a1b2", "a1b2c3", "a1b2c3a1",
+						 "a1b2c3a1b2", "a1b2c3a1b2c3");
+	check_buf_append_abc("a1/", "b2/", "c3/",
+						 "a1/b2/", "a1/b2/c3/", "a1/b2/c3/a1/",
+						 "a1/b2/c3/a1/b2/", "a1/b2/c3/a1/b2/c3/");
+}
+
+/* test swap */
+void test_core_buffer__6(void)
+{
+	git_buf a = GIT_BUF_INIT;
+	git_buf b = GIT_BUF_INIT;
+
+	git_buf_sets(&a, "foo");
+	cl_assert(git_buf_oom(&a) == 0);
+	git_buf_sets(&b, "bar");
+	cl_assert(git_buf_oom(&b) == 0);
+
+	cl_assert_equal_s("foo", git_buf_cstr(&a));
+	cl_assert_equal_s("bar", git_buf_cstr(&b));
+
+	git_buf_swap(&a, &b);
+
+	cl_assert_equal_s("bar", git_buf_cstr(&a));
+	cl_assert_equal_s("foo", git_buf_cstr(&b));
+
+	git_buf_free(&a);
+	git_buf_free(&b);
+}
+
+
+/* test detach/attach data */
+void test_core_buffer__7(void)
+{
+	const char *fun = "This is fun";
+	git_buf a = GIT_BUF_INIT;
+	char *b = NULL;
+
+	git_buf_sets(&a, "foo");
+	cl_assert(git_buf_oom(&a) == 0);
+	cl_assert_equal_s("foo", git_buf_cstr(&a));
+
+	b = git_buf_detach(&a);
+
+	cl_assert_equal_s("foo", b);
+	cl_assert_equal_s("", a.ptr);
+	git__free(b);
+
+	b = git_buf_detach(&a);
+
+	cl_assert_equal_s(NULL, b);
+	cl_assert_equal_s("", a.ptr);
+
+	git_buf_free(&a);
+
+	b = git__strdup(fun);
+	git_buf_attach(&a, b, 0);
+
+	cl_assert_equal_s(fun, a.ptr);
+	cl_assert(a.size == strlen(fun));
+	cl_assert(a.asize == strlen(fun) + 1);
+
+	git_buf_free(&a);
+
+	b = git__strdup(fun);
+	git_buf_attach(&a, b, strlen(fun) + 1);
+
+	cl_assert_equal_s(fun, a.ptr);
+	cl_assert(a.size == strlen(fun));
+	cl_assert(a.asize == strlen(fun) + 1);
+
+	git_buf_free(&a);
+}
+
+
+static void
+check_joinbuf_2(
+	const char *a,
+	const char *b,
+	const char *expected)
+{
+	char sep = '/';
+	git_buf buf = GIT_BUF_INIT;
+
+	git_buf_join(&buf, sep, a, b);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(expected, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
+
+static void
+check_joinbuf_overlapped(
+	const char *oldval,
+	int ofs_a,
+	const char *b,
+	const char *expected)
+{
+	char sep = '/';
+	git_buf buf = GIT_BUF_INIT;
+
+	git_buf_sets(&buf, oldval);
+	git_buf_join(&buf, sep, buf.ptr + ofs_a, b);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(expected, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
+
+static void
+check_joinbuf_n_2(
+	const char *a,
+	const char *b,
+	const char *expected)
+{
+	char sep = '/';
+	git_buf buf = GIT_BUF_INIT;
+
+	git_buf_sets(&buf, a);
+	cl_assert(git_buf_oom(&buf) == 0);
+
+	git_buf_join_n(&buf, sep, 1, b);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(expected, git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+}
+
+static void
+check_joinbuf_n_4(
+	const char *a,
+	const char *b,
+	const char *c,
+	const char *d,
+	const char *expected)
+{
+	char sep = ';';
+	git_buf buf = GIT_BUF_INIT;
+	git_buf_join_n(&buf, sep, 4, a, b, c, d);
+	cl_assert(git_buf_oom(&buf) == 0);
+	cl_assert_equal_s(expected, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
+
+/* test join */
+void test_core_buffer__8(void)
+{
+	git_buf a = GIT_BUF_INIT;
+
+	git_buf_join_n(&a, '/', 1, "foo");
+	cl_assert(git_buf_oom(&a) == 0);
+	cl_assert_equal_s("foo", git_buf_cstr(&a));
+
+	git_buf_join_n(&a, '/', 1, "bar");
+	cl_assert(git_buf_oom(&a) == 0);
+	cl_assert_equal_s("foo/bar", git_buf_cstr(&a));
+
+	git_buf_join_n(&a, '/', 1, "baz");
+	cl_assert(git_buf_oom(&a) == 0);
+	cl_assert_equal_s("foo/bar/baz", git_buf_cstr(&a));
+
+	git_buf_free(&a);
+
+	check_joinbuf_2(NULL, "", "");
+	check_joinbuf_2(NULL, "a", "a");
+	check_joinbuf_2(NULL, "/a", "/a");
+	check_joinbuf_2("", "", "");
+	check_joinbuf_2("", "a", "a");
+	check_joinbuf_2("", "/a", "/a");
+	check_joinbuf_2("a", "", "a/");
+	check_joinbuf_2("a", "/", "a/");
+	check_joinbuf_2("a", "b", "a/b");
+	check_joinbuf_2("/", "a", "/a");
+	check_joinbuf_2("/", "", "/");
+	check_joinbuf_2("/a", "/b", "/a/b");
+	check_joinbuf_2("/a", "/b/", "/a/b/");
+	check_joinbuf_2("/a/", "b/", "/a/b/");
+	check_joinbuf_2("/a/", "/b/", "/a/b/");
+	check_joinbuf_2("/a/", "//b/", "/a/b/");
+	check_joinbuf_2("/abcd", "/defg", "/abcd/defg");
+	check_joinbuf_2("/abcd", "/defg/", "/abcd/defg/");
+	check_joinbuf_2("/abcd/", "defg/", "/abcd/defg/");
+	check_joinbuf_2("/abcd/", "/defg/", "/abcd/defg/");
+
+	check_joinbuf_overlapped("abcd", 0, "efg", "abcd/efg");
+	check_joinbuf_overlapped("abcd", 1, "efg", "bcd/efg");
+	check_joinbuf_overlapped("abcd", 2, "efg", "cd/efg");
+	check_joinbuf_overlapped("abcd", 3, "efg", "d/efg");
+	check_joinbuf_overlapped("abcd", 4, "efg", "efg");
+	check_joinbuf_overlapped("abc/", 2, "efg", "c/efg");
+	check_joinbuf_overlapped("abc/", 3, "efg", "/efg");
+	check_joinbuf_overlapped("abc/", 4, "efg", "efg");
+	check_joinbuf_overlapped("abcd", 3, "", "d/");
+	check_joinbuf_overlapped("abcd", 4, "", "");
+	check_joinbuf_overlapped("abc/", 2, "", "c/");
+	check_joinbuf_overlapped("abc/", 3, "", "/");
+	check_joinbuf_overlapped("abc/", 4, "", "");
+
+	check_joinbuf_n_2("", "", "");
+	check_joinbuf_n_2("", "a", "a");
+	check_joinbuf_n_2("", "/a", "/a");
+	check_joinbuf_n_2("a", "", "a/");
+	check_joinbuf_n_2("a", "/", "a/");
+	check_joinbuf_n_2("a", "b", "a/b");
+	check_joinbuf_n_2("/", "a", "/a");
+	check_joinbuf_n_2("/", "", "/");
+	check_joinbuf_n_2("/a", "/b", "/a/b");
+	check_joinbuf_n_2("/a", "/b/", "/a/b/");
+	check_joinbuf_n_2("/a/", "b/", "/a/b/");
+	check_joinbuf_n_2("/a/", "/b/", "/a/b/");
+	check_joinbuf_n_2("/abcd", "/defg", "/abcd/defg");
+	check_joinbuf_n_2("/abcd", "/defg/", "/abcd/defg/");
+	check_joinbuf_n_2("/abcd/", "defg/", "/abcd/defg/");
+	check_joinbuf_n_2("/abcd/", "/defg/", "/abcd/defg/");
+
+	check_joinbuf_n_4("", "", "", "", "");
+	check_joinbuf_n_4("", "a", "", "", "a;");
+	check_joinbuf_n_4("a", "", "", "", "a;");
+	check_joinbuf_n_4("", "", "", "a", "a");
+	check_joinbuf_n_4("a", "b", "", ";c;d;", "a;b;c;d;");
+	check_joinbuf_n_4("a", "b", "", ";c;d", "a;b;c;d");
+	check_joinbuf_n_4("abcd", "efgh", "ijkl", "mnop", "abcd;efgh;ijkl;mnop");
+	check_joinbuf_n_4("abcd;", "efgh;", "ijkl;", "mnop;", "abcd;efgh;ijkl;mnop;");
+	check_joinbuf_n_4(";abcd;", ";efgh;", ";ijkl;", ";mnop;", ";abcd;efgh;ijkl;mnop;");
+}
+
+void test_core_buffer__9(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	/* just some exhaustive tests of various separator placement */
+	char *a[] = { "", "-", "a-", "-a", "-a-" };
+	char *b[] = { "", "-", "b-", "-b", "-b-" };
+	char sep[] = { 0, '-', '/' };
+	char *expect_null[] = { "",    "-",     "a-",     "-a",     "-a-",
+							"-",   "--",    "a--",    "-a-",    "-a--",
+							"b-",  "-b-",   "a-b-",   "-ab-",   "-a-b-",
+							"-b",  "--b",   "a--b",   "-a-b",   "-a--b",
+							"-b-", "--b-",  "a--b-",  "-a-b-",  "-a--b-" };
+	char *expect_dash[] = { "",    "-",     "a-",     "-a-",    "-a-",
+							"-",   "-",     "a-",     "-a-",    "-a-",
+							"b-",  "-b-",   "a-b-",   "-a-b-",  "-a-b-",
+							"-b",  "-b",    "a-b",    "-a-b",   "-a-b",
+							"-b-", "-b-",   "a-b-",   "-a-b-",  "-a-b-" };
+	char *expect_slas[] = { "",    "-/",    "a-/",    "-a/",    "-a-/",
+							"-",   "-/-",   "a-/-",   "-a/-",   "-a-/-",
+							"b-",  "-/b-",  "a-/b-",  "-a/b-",  "-a-/b-",
+							"-b",  "-/-b",  "a-/-b",  "-a/-b",  "-a-/-b",
+							"-b-", "-/-b-", "a-/-b-", "-a/-b-", "-a-/-b-" };
+	char **expect_values[] = { expect_null, expect_dash, expect_slas };
+	char separator, **expect;
+	unsigned int s, i, j;
+
+	for (s = 0; s < sizeof(sep) / sizeof(char); ++s) {
+		separator = sep[s];
+		expect = expect_values[s];
+
+		for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {
+			for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {
+				git_buf_join(&buf, separator, a[i], b[j]);
+				cl_assert_equal_s(*expect, buf.ptr);
+				expect++;
+			}
+		}
+	}
+
+	git_buf_free(&buf);
+}
+
+void test_core_buffer__10(void)
+{
+	git_buf a = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_join_n(&a, '/', 1, "test"));
+	cl_assert_equal_s(a.ptr, "test");
+	cl_git_pass(git_buf_join_n(&a, '/', 1, "string"));
+	cl_assert_equal_s(a.ptr, "test/string");
+	git_buf_clear(&a);
+	cl_git_pass(git_buf_join_n(&a, '/', 3, "test", "string", "join"));
+	cl_assert_equal_s(a.ptr, "test/string/join");
+	cl_git_pass(git_buf_join_n(&a, '/', 2, a.ptr, "more"));
+	cl_assert_equal_s(a.ptr, "test/string/join/test/string/join/more");
+
+	git_buf_free(&a);
+}
+
+void test_core_buffer__join3(void)
+{
+	git_buf a = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_join3(&a, '/', "test", "string", "join"));
+	cl_assert_equal_s("test/string/join", a.ptr);
+	cl_git_pass(git_buf_join3(&a, '/', "test/", "string", "join"));
+	cl_assert_equal_s("test/string/join", a.ptr);
+	cl_git_pass(git_buf_join3(&a, '/', "test/", "/string", "join"));
+	cl_assert_equal_s("test/string/join", a.ptr);
+	cl_git_pass(git_buf_join3(&a, '/', "test/", "/string/", "join"));
+	cl_assert_equal_s("test/string/join", a.ptr);
+	cl_git_pass(git_buf_join3(&a, '/', "test/", "/string/", "/join"));
+	cl_assert_equal_s("test/string/join", a.ptr);
+
+	cl_git_pass(git_buf_join3(&a, '/', "", "string", "join"));
+	cl_assert_equal_s("string/join", a.ptr);
+	cl_git_pass(git_buf_join3(&a, '/', "", "string/", "join"));
+	cl_assert_equal_s("string/join", a.ptr);
+	cl_git_pass(git_buf_join3(&a, '/', "", "string/", "/join"));
+	cl_assert_equal_s("string/join", a.ptr);
+
+	cl_git_pass(git_buf_join3(&a, '/', "string", "", "join"));
+	cl_assert_equal_s("string/join", a.ptr);
+	cl_git_pass(git_buf_join3(&a, '/', "string/", "", "join"));
+	cl_assert_equal_s("string/join", a.ptr);
+	cl_git_pass(git_buf_join3(&a, '/', "string/", "", "/join"));
+	cl_assert_equal_s("string/join", a.ptr);
+
+	git_buf_free(&a);
+}
+
+void test_core_buffer__11(void)
+{
+	git_buf a = GIT_BUF_INIT;
+	git_strarray t;
+	char *t1[] = { "nothing", "in", "common" };
+	char *t2[] = { "something", "something else", "some other" };
+	char *t3[] = { "something", "some fun", "no fun" };
+	char *t4[] = { "happy", "happier", "happiest" };
+	char *t5[] = { "happiest", "happier", "happy" };
+	char *t6[] = { "no", "nope", "" };
+	char *t7[] = { "", "doesn't matter" };
+
+	t.strings = t1;
+	t.count = 3;
+	cl_git_pass(git_buf_text_common_prefix(&a, &t));
+	cl_assert_equal_s(a.ptr, "");
+
+	t.strings = t2;
+	t.count = 3;
+	cl_git_pass(git_buf_text_common_prefix(&a, &t));
+	cl_assert_equal_s(a.ptr, "some");
+
+	t.strings = t3;
+	t.count = 3;
+	cl_git_pass(git_buf_text_common_prefix(&a, &t));
+	cl_assert_equal_s(a.ptr, "");
+
+	t.strings = t4;
+	t.count = 3;
+	cl_git_pass(git_buf_text_common_prefix(&a, &t));
+	cl_assert_equal_s(a.ptr, "happ");
+
+	t.strings = t5;
+	t.count = 3;
+	cl_git_pass(git_buf_text_common_prefix(&a, &t));
+	cl_assert_equal_s(a.ptr, "happ");
+
+	t.strings = t6;
+	t.count = 3;
+	cl_git_pass(git_buf_text_common_prefix(&a, &t));
+	cl_assert_equal_s(a.ptr, "");
+
+	t.strings = t7;
+	t.count = 3;
+	cl_git_pass(git_buf_text_common_prefix(&a, &t));
+	cl_assert_equal_s(a.ptr, "");
+
+	git_buf_free(&a);
+}
+
+void test_core_buffer__rfind_variants(void)
+{
+	git_buf a = GIT_BUF_INIT;
+	ssize_t len;
+
+	cl_git_pass(git_buf_sets(&a, "/this/is/it/"));
+
+	len = (ssize_t)git_buf_len(&a);
+
+	cl_assert(git_buf_rfind(&a, '/') == len - 1);
+	cl_assert(git_buf_rfind_next(&a, '/') == len - 4);
+
+	cl_assert(git_buf_rfind(&a, 'i') == len - 3);
+	cl_assert(git_buf_rfind_next(&a, 'i') == len - 3);
+
+	cl_assert(git_buf_rfind(&a, 'h') == 2);
+	cl_assert(git_buf_rfind_next(&a, 'h') == 2);
+
+	cl_assert(git_buf_rfind(&a, 'q') == -1);
+	cl_assert(git_buf_rfind_next(&a, 'q') == -1);
+
+	git_buf_free(&a);
+}
+
+void test_core_buffer__puts_escaped(void)
+{
+	git_buf a = GIT_BUF_INIT;
+
+	git_buf_clear(&a);
+	cl_git_pass(git_buf_text_puts_escaped(&a, "this is a test", "", ""));
+	cl_assert_equal_s("this is a test", a.ptr);
+
+	git_buf_clear(&a);
+	cl_git_pass(git_buf_text_puts_escaped(&a, "this is a test", "t", "\\"));
+	cl_assert_equal_s("\\this is a \\tes\\t", a.ptr);
+
+	git_buf_clear(&a);
+	cl_git_pass(git_buf_text_puts_escaped(&a, "this is a test", "i ", "__"));
+	cl_assert_equal_s("th__is__ __is__ a__ test", a.ptr);
+
+	git_buf_clear(&a);
+	cl_git_pass(git_buf_text_puts_escape_regex(&a, "^match\\s*[A-Z]+.*"));
+	cl_assert_equal_s("\\^match\\\\s\\*\\[A-Z\\]\\+\\.\\*", a.ptr);
+
+	git_buf_free(&a);
+}
+
+static void assert_unescape(char *expected, char *to_unescape) {
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_sets(&buf, to_unescape));
+	git_buf_text_unescape(&buf);
+	cl_assert_equal_s(expected, buf.ptr);
+	cl_assert_equal_sz(strlen(expected), buf.size);
+
+	git_buf_free(&buf);
+}
+
+void test_core_buffer__unescape(void)
+{
+	assert_unescape("Escaped\\", "Es\\ca\\ped\\");
+	assert_unescape("Es\\caped\\", "Es\\\\ca\\ped\\\\");
+	assert_unescape("\\", "\\");
+	assert_unescape("\\", "\\\\");
+	assert_unescape("", "");
+}
+
+void test_core_buffer__encode_base64(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	/*     t  h  i  s
+	 * 0x 74 68 69 73
+     * 0b 01110100 01101000 01101001 01110011
+	 * 0b 011101 000110 100001 101001 011100 110000
+	 * 0x 1d 06 21 29 1c 30
+	 *     d  G  h  p  c  w
+	 */
+	cl_git_pass(git_buf_encode_base64(&buf, "this", 4));
+	cl_assert_equal_s("dGhpcw==", buf.ptr);
+
+	git_buf_clear(&buf);
+	cl_git_pass(git_buf_encode_base64(&buf, "this!", 5));
+	cl_assert_equal_s("dGhpcyE=", buf.ptr);
+
+	git_buf_clear(&buf);
+	cl_git_pass(git_buf_encode_base64(&buf, "this!\n", 6));
+	cl_assert_equal_s("dGhpcyEK", buf.ptr);
+
+	git_buf_free(&buf);
+}
+
+void test_core_buffer__decode_base64(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_decode_base64(&buf, "dGhpcw==", 8));
+	cl_assert_equal_s("this", buf.ptr);
+
+	git_buf_clear(&buf);
+	cl_git_pass(git_buf_decode_base64(&buf, "dGhpcyE=", 8));
+	cl_assert_equal_s("this!", buf.ptr);
+
+	git_buf_clear(&buf);
+	cl_git_pass(git_buf_decode_base64(&buf, "dGhpcyEK", 8));
+	cl_assert_equal_s("this!\n", buf.ptr);
+
+	cl_git_fail(git_buf_decode_base64(&buf, "This is not a valid base64 string!!!", 36));
+	cl_assert_equal_s("this!\n", buf.ptr);
+
+	git_buf_free(&buf);
+}
+
+void test_core_buffer__encode_base85(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_encode_base85(&buf, "this", 4));
+	cl_assert_equal_s("bZBXF", buf.ptr);
+	git_buf_clear(&buf);
+
+	cl_git_pass(git_buf_encode_base85(&buf, "two rnds", 8));
+	cl_assert_equal_s("ba!tca&BaE", buf.ptr);
+	git_buf_clear(&buf);
+
+	cl_git_pass(git_buf_encode_base85(&buf, "this is base 85 encoded",
+		strlen("this is base 85 encoded")));
+	cl_assert_equal_s("bZBXFAZc?TVqtS-AUHK3Wo~0{WMyOk", buf.ptr);
+	git_buf_clear(&buf);
+
+	git_buf_free(&buf);
+}
+
+void test_core_buffer__classify_with_utf8(void)
+{
+	char *data0 = "Simple text\n";
+	size_t data0len = 12;
+	char *data1 = "Is that UTF-8 data I see…\nYep!\n";
+	size_t data1len = 31;
+	char *data2 = "Internal NUL!!!\000\n\nI see you!\n";
+	size_t data2len = 29;
+	char *data3 = "\xef\xbb\xbfThis is UTF-8 with a BOM.\n";
+	size_t data3len = 20;
+	git_buf b;
+
+	b.ptr = data0; b.size = b.asize = data0len;
+	cl_assert(!git_buf_text_is_binary(&b));
+	cl_assert(!git_buf_text_contains_nul(&b));
+
+	b.ptr = data1; b.size = b.asize = data1len;
+	cl_assert(!git_buf_text_is_binary(&b));
+	cl_assert(!git_buf_text_contains_nul(&b));
+
+	b.ptr = data2; b.size = b.asize = data2len;
+	cl_assert(git_buf_text_is_binary(&b));
+	cl_assert(git_buf_text_contains_nul(&b));
+
+	b.ptr = data3; b.size = b.asize = data3len;
+	cl_assert(!git_buf_text_is_binary(&b));
+	cl_assert(!git_buf_text_contains_nul(&b));
+}
+
+#define SIMILARITY_TEST_DATA_1 \
+	"000\n001\n002\n003\n004\n005\n006\n007\n008\n009\n" \
+	"010\n011\n012\n013\n014\n015\n016\n017\n018\n019\n" \
+	"020\n021\n022\n023\n024\n025\n026\n027\n028\n029\n" \
+	"030\n031\n032\n033\n034\n035\n036\n037\n038\n039\n" \
+	"040\n041\n042\n043\n044\n045\n046\n047\n048\n049\n"
+
+void test_core_buffer__similarity_metric(void)
+{
+	git_hashsig *a, *b;
+	git_buf buf = GIT_BUF_INIT;
+	int sim;
+
+	/* in the first case, we compare data to itself and expect 100% match */
+
+	cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1));
+	cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
+	cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
+
+	cl_assert_equal_i(100, git_hashsig_compare(a, b));
+
+	git_hashsig_free(a);
+	git_hashsig_free(b);
+
+	/* if we change just a single byte, how much does that change magnify? */
+
+	cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1));
+	cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
+	cl_git_pass(git_buf_sets(&buf,
+		"000\n001\n002\n003\n004\n005\n006\n007\n008\n009\n" \
+		"010\n011\n012\n013\n014\n015\n016\n017\n018\n019\n" \
+		"x020x\n021\n022\n023\n024\n025\n026\n027\n028\n029\n" \
+		"030\n031\n032\n033\n034\n035\n036\n037\n038\n039\n" \
+		"040\n041\n042\n043\n044\n045\n046\n047\n048\n049\n"
+		));
+	cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
+
+	sim = git_hashsig_compare(a, b);
+
+	cl_assert_in_range(95, sim, 100); /* expect >95% similarity */
+
+	git_hashsig_free(a);
+	git_hashsig_free(b);
+
+	/* let's try comparing data to a superset of itself */
+
+	cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1));
+	cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
+	cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1
+		"050\n051\n052\n053\n054\n055\n056\n057\n058\n059\n"));
+	cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
+
+	sim = git_hashsig_compare(a, b);
+	/* 20% lines added ~= 10% lines changed */
+
+	cl_assert_in_range(85, sim, 95); /* expect similarity around 90% */
+
+	git_hashsig_free(a);
+	git_hashsig_free(b);
+
+	/* what if we keep about half the original data and add half new */
+
+	cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1));
+	cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
+	cl_git_pass(git_buf_sets(&buf,
+		"000\n001\n002\n003\n004\n005\n006\n007\n008\n009\n" \
+		"010\n011\n012\n013\n014\n015\n016\n017\n018\n019\n" \
+		"020x\n021\n022\n023\n024\n" \
+		"x25\nx26\nx27\nx28\nx29\n" \
+		"x30\nx31\nx32\nx33\nx34\nx35\nx36\nx37\nx38\nx39\n" \
+		"x40\nx41\nx42\nx43\nx44\nx45\nx46\nx47\nx48\nx49\n"
+		));
+	cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
+
+	sim = git_hashsig_compare(a, b);
+	/* 50% lines changed */
+
+	cl_assert_in_range(40, sim, 60); /* expect in the 40-60% similarity range */
+
+	git_hashsig_free(a);
+	git_hashsig_free(b);
+
+	/* lastly, let's check that we can hash file content as well */
+
+	cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1));
+	cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
+
+	cl_git_pass(git_futils_mkdir("scratch", NULL, 0755, GIT_MKDIR_PATH));
+	cl_git_mkfile("scratch/testdata", SIMILARITY_TEST_DATA_1);
+	cl_git_pass(git_hashsig_create_fromfile(
+		&b, "scratch/testdata", GIT_HASHSIG_NORMAL));
+
+	cl_assert_equal_i(100, git_hashsig_compare(a, b));
+
+	git_hashsig_free(a);
+	git_hashsig_free(b);
+
+	git_buf_free(&buf);
+	git_futils_rmdir_r("scratch", NULL, GIT_RMDIR_REMOVE_FILES);
+}
+
+
+void test_core_buffer__similarity_metric_whitespace(void)
+{
+	git_hashsig *a, *b;
+	git_buf buf = GIT_BUF_INIT;
+	int sim, i, j;
+	git_hashsig_option_t opt;
+	const char *tabbed =
+		"	for (s = 0; s < sizeof(sep) / sizeof(char); ++s) {\n"
+		"		separator = sep[s];\n"
+		"		expect = expect_values[s];\n"
+		"\n"
+		"		for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {\n"
+		"			for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {\n"
+		"				git_buf_join(&buf, separator, a[i], b[j]);\n"
+		"				cl_assert_equal_s(*expect, buf.ptr);\n"
+		"				expect++;\n"
+		"			}\n"
+		"		}\n"
+		"	}\n";
+	const char *spaced =
+		"   for (s = 0; s < sizeof(sep) / sizeof(char); ++s) {\n"
+		"       separator = sep[s];\n"
+		"       expect = expect_values[s];\n"
+		"\n"
+		"       for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {\n"
+		"           for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {\n"
+		"               git_buf_join(&buf, separator, a[i], b[j]);\n"
+		"               cl_assert_equal_s(*expect, buf.ptr);\n"
+		"               expect++;\n"
+		"           }\n"
+		"       }\n"
+		"   }\n";
+	const char *crlf_spaced2 =
+		"  for (s = 0; s < sizeof(sep) / sizeof(char); ++s) {\r\n"
+		"    separator = sep[s];\r\n"
+		"    expect = expect_values[s];\r\n"
+		"\r\n"
+		"    for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {\r\n"
+		"      for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {\r\n"
+		"        git_buf_join(&buf, separator, a[i], b[j]);\r\n"
+		"        cl_assert_equal_s(*expect, buf.ptr);\r\n"
+		"        expect++;\r\n"
+		"      }\r\n"
+		"    }\r\n"
+		"  }\r\n";
+	const char *text[3] = { tabbed, spaced, crlf_spaced2 };
+
+	/* let's try variations of our own code with whitespace changes */
+
+	for (opt = GIT_HASHSIG_NORMAL; opt <= GIT_HASHSIG_SMART_WHITESPACE; ++opt) {
+		for (i = 0; i < 3; ++i) {
+			for (j = 0; j < 3; ++j) {
+				cl_git_pass(git_buf_sets(&buf, text[i]));
+				cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, opt));
+
+				cl_git_pass(git_buf_sets(&buf, text[j]));
+				cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, opt));
+
+				sim = git_hashsig_compare(a, b);
+
+				if (opt == GIT_HASHSIG_NORMAL) {
+					if (i == j)
+						cl_assert_equal_i(100, sim);
+					else
+						cl_assert_in_range(0, sim, 30); /* pretty different */
+				} else {
+					cl_assert_equal_i(100, sim);
+				}
+
+				git_hashsig_free(a);
+				git_hashsig_free(b);
+			}
+		}
+	}
+
+	git_buf_free(&buf);
+}
+
+#include "../filter/crlf.h"
+
+#define check_buf(expected,buf) do { \
+	cl_assert_equal_s(expected, buf.ptr); \
+	cl_assert_equal_sz(strlen(expected), buf.size); } while (0)
+
+void test_core_buffer__lf_and_crlf_conversions(void)
+{
+	git_buf src = GIT_BUF_INIT, tgt = GIT_BUF_INIT;
+
+	/* LF source */
+
+	git_buf_sets(&src, "lf\nlf\nlf\nlf\n");
+
+	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
+	check_buf("lf\r\nlf\r\nlf\r\nlf\r\n", tgt);
+
+	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
+	check_buf(src.ptr, tgt);
+
+	git_buf_sets(&src, "\nlf\nlf\nlf\nlf\nlf");
+
+	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
+	check_buf("\r\nlf\r\nlf\r\nlf\r\nlf\r\nlf", tgt);
+
+	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
+	check_buf(src.ptr, tgt);
+
+	/* CRLF source */
+
+	git_buf_sets(&src, "crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n");
+
+	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
+	check_buf("crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n", tgt);
+
+	git_buf_sets(&src, "crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n");
+
+	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
+	check_buf("crlf\ncrlf\ncrlf\ncrlf\n", tgt);
+
+	git_buf_sets(&src, "\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf");
+
+	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
+	check_buf("\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf", tgt);
+
+	git_buf_sets(&src, "\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf");
+
+	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
+	check_buf("\ncrlf\ncrlf\ncrlf\ncrlf\ncrlf", tgt);
+
+	/* CRLF in LF text */
+
+	git_buf_sets(&src, "\nlf\nlf\ncrlf\r\nlf\nlf\ncrlf\r\n");
+
+	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
+	check_buf("\r\nlf\r\nlf\r\ncrlf\r\nlf\r\nlf\r\ncrlf\r\n", tgt);
+
+	git_buf_sets(&src, "\nlf\nlf\ncrlf\r\nlf\nlf\ncrlf\r\n");
+
+	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
+	check_buf("\nlf\nlf\ncrlf\nlf\nlf\ncrlf\n", tgt);
+
+	/* LF in CRLF text */
+
+	git_buf_sets(&src, "\ncrlf\r\ncrlf\r\nlf\ncrlf\r\ncrlf");
+
+	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
+	check_buf("\r\ncrlf\r\ncrlf\r\nlf\r\ncrlf\r\ncrlf", tgt);
+
+	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
+	check_buf("\ncrlf\ncrlf\nlf\ncrlf\ncrlf", tgt);
+
+	/* bare CR test */
+
+	git_buf_sets(&src, "\rcrlf\r\nlf\nlf\ncr\rcrlf\r\nlf\ncr\r");
+
+	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
+	check_buf("\rcrlf\r\nlf\r\nlf\r\ncr\rcrlf\r\nlf\r\ncr\r", tgt);
+
+	git_buf_sets(&src, "\rcrlf\r\nlf\nlf\ncr\rcrlf\r\nlf\ncr\r");
+
+	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
+	check_buf("\rcrlf\nlf\nlf\ncr\rcrlf\nlf\ncr\r", tgt);
+
+	git_buf_sets(&src, "\rcr\r");
+	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
+	check_buf(src.ptr, tgt);
+	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
+	check_buf("\rcr\r", tgt);
+
+	git_buf_free(&src);
+	git_buf_free(&tgt);
+
+	/* blob correspondence tests */
+
+	git_buf_sets(&src, ALL_CRLF_TEXT_RAW);
+	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
+	check_buf(ALL_CRLF_TEXT_AS_CRLF, tgt);
+	git_buf_sets(&src, ALL_CRLF_TEXT_RAW);
+	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
+	check_buf(ALL_CRLF_TEXT_AS_LF, tgt);
+	git_buf_free(&src);
+	git_buf_free(&tgt);
+
+	git_buf_sets(&src, ALL_LF_TEXT_RAW);
+	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
+	check_buf(ALL_LF_TEXT_AS_CRLF, tgt);
+	git_buf_sets(&src, ALL_LF_TEXT_RAW);
+	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
+	check_buf(ALL_LF_TEXT_AS_LF, tgt);
+	git_buf_free(&src);
+	git_buf_free(&tgt);
+
+	git_buf_sets(&src, MORE_CRLF_TEXT_RAW);
+	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
+	check_buf(MORE_CRLF_TEXT_AS_CRLF, tgt);
+	git_buf_sets(&src, MORE_CRLF_TEXT_RAW);
+	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
+	check_buf(MORE_CRLF_TEXT_AS_LF, tgt);
+	git_buf_free(&src);
+	git_buf_free(&tgt);
+
+	git_buf_sets(&src, MORE_LF_TEXT_RAW);
+	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
+	check_buf(MORE_LF_TEXT_AS_CRLF, tgt);
+	git_buf_sets(&src, MORE_LF_TEXT_RAW);
+	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
+	check_buf(MORE_LF_TEXT_AS_LF, tgt);
+	git_buf_free(&src);
+	git_buf_free(&tgt);
+}
+
+void test_core_buffer__dont_grow_borrowed(void)
+{
+	const char *somestring = "blah blah";
+	git_buf buf = GIT_BUF_INIT;
+
+	git_buf_attach_notowned(&buf, somestring, strlen(somestring) + 1);
+	cl_assert_equal_p(somestring, buf.ptr);
+	cl_assert_equal_i(0, buf.asize);
+	cl_assert_equal_i(strlen(somestring) + 1, buf.size);
+
+	cl_git_fail_with(GIT_EINVALID, git_buf_grow(&buf, 1024));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/copy.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/copy.c
new file mode 100755
index 0000000..04b2dfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/copy.c
@@ -0,0 +1,152 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "path.h"
+#include "posix.h"
+
+void test_core_copy__file(void)
+{
+	struct stat st;
+	const char *content = "This is some stuff to copy\n";
+
+	cl_git_mkfile("copy_me", content);
+
+	cl_git_pass(git_futils_cp("copy_me", "copy_me_two", 0664));
+
+	cl_git_pass(git_path_lstat("copy_me_two", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert(strlen(content) == (size_t)st.st_size);
+
+	cl_git_pass(p_unlink("copy_me_two"));
+	cl_git_pass(p_unlink("copy_me"));
+}
+
+void test_core_copy__file_in_dir(void)
+{
+	struct stat st;
+	const char *content = "This is some other stuff to copy\n";
+
+	cl_git_pass(git_futils_mkdir("an_dir/in_a_dir", NULL, 0775, GIT_MKDIR_PATH));
+	cl_git_mkfile("an_dir/in_a_dir/copy_me", content);
+	cl_assert(git_path_isdir("an_dir"));
+
+	cl_git_pass(git_futils_mkpath2file
+		("an_dir/second_dir/and_more/copy_me_two", 0775));
+
+	cl_git_pass(git_futils_cp
+		("an_dir/in_a_dir/copy_me",
+		 "an_dir/second_dir/and_more/copy_me_two",
+		 0664));
+
+	cl_git_pass(git_path_lstat("an_dir/second_dir/and_more/copy_me_two", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert(strlen(content) == (size_t)st.st_size);
+
+	cl_git_pass(git_futils_rmdir_r("an_dir", NULL, GIT_RMDIR_REMOVE_FILES));
+	cl_assert(!git_path_isdir("an_dir"));
+}
+
+void assert_hard_link(const char *path)
+{
+	/* we assert this by checking that there's more than one link to the file */
+	struct stat st;
+
+	cl_assert(git_path_isfile(path));
+	cl_git_pass(p_stat(path, &st));
+	cl_assert(st.st_nlink > 1);
+}
+
+void test_core_copy__tree(void)
+{
+	struct stat st;
+	const char *content = "File content\n";
+
+	cl_git_pass(git_futils_mkdir("src/b", NULL, 0775, GIT_MKDIR_PATH));
+	cl_git_pass(git_futils_mkdir("src/c/d", NULL, 0775, GIT_MKDIR_PATH));
+	cl_git_pass(git_futils_mkdir("src/c/e", NULL, 0775, GIT_MKDIR_PATH));
+
+	cl_git_mkfile("src/f1", content);
+	cl_git_mkfile("src/b/f2", content);
+	cl_git_mkfile("src/c/f3", content);
+	cl_git_mkfile("src/c/d/f4", content);
+	cl_git_mkfile("src/c/d/.f5", content);
+
+#ifndef GIT_WIN32
+	cl_assert(p_symlink("../../b/f2", "src/c/d/l1") == 0);
+#endif
+
+	cl_assert(git_path_isdir("src"));
+	cl_assert(git_path_isdir("src/b"));
+	cl_assert(git_path_isdir("src/c/d"));
+	cl_assert(git_path_isfile("src/c/d/f4"));
+
+	/* copy with no empty dirs, yes links, no dotfiles, no overwrite */
+
+	cl_git_pass(
+		git_futils_cp_r("src", "t1", GIT_CPDIR_COPY_SYMLINKS, 0) );
+
+	cl_assert(git_path_isdir("t1"));
+	cl_assert(git_path_isdir("t1/b"));
+	cl_assert(git_path_isdir("t1/c"));
+	cl_assert(git_path_isdir("t1/c/d"));
+	cl_assert(!git_path_isdir("t1/c/e"));
+
+	cl_assert(git_path_isfile("t1/f1"));
+	cl_assert(git_path_isfile("t1/b/f2"));
+	cl_assert(git_path_isfile("t1/c/f3"));
+	cl_assert(git_path_isfile("t1/c/d/f4"));
+	cl_assert(!git_path_isfile("t1/c/d/.f5"));
+
+	cl_git_pass(git_path_lstat("t1/c/f3", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert(strlen(content) == (size_t)st.st_size);
+
+#ifndef GIT_WIN32
+	cl_git_pass(git_path_lstat("t1/c/d/l1", &st));
+	cl_assert(S_ISLNK(st.st_mode));
+#endif
+
+	cl_git_pass(git_futils_rmdir_r("t1", NULL, GIT_RMDIR_REMOVE_FILES));
+	cl_assert(!git_path_isdir("t1"));
+
+	/* copy with empty dirs, no links, yes dotfiles, no overwrite */
+
+	cl_git_pass(
+		git_futils_cp_r("src", "t2", GIT_CPDIR_CREATE_EMPTY_DIRS | GIT_CPDIR_COPY_DOTFILES, 0) );
+
+	cl_assert(git_path_isdir("t2"));
+	cl_assert(git_path_isdir("t2/b"));
+	cl_assert(git_path_isdir("t2/c"));
+	cl_assert(git_path_isdir("t2/c/d"));
+	cl_assert(git_path_isdir("t2/c/e"));
+
+	cl_assert(git_path_isfile("t2/f1"));
+	cl_assert(git_path_isfile("t2/b/f2"));
+	cl_assert(git_path_isfile("t2/c/f3"));
+	cl_assert(git_path_isfile("t2/c/d/f4"));
+	cl_assert(git_path_isfile("t2/c/d/.f5"));
+
+#ifndef GIT_WIN32
+	cl_git_fail(git_path_lstat("t2/c/d/l1", &st));
+#endif
+
+	cl_git_pass(git_futils_rmdir_r("t2", NULL, GIT_RMDIR_REMOVE_FILES));
+	cl_assert(!git_path_isdir("t2"));
+
+#ifndef GIT_WIN32
+	cl_git_pass(git_futils_cp_r("src", "t3", GIT_CPDIR_CREATE_EMPTY_DIRS | GIT_CPDIR_LINK_FILES, 0));
+	cl_assert(git_path_isdir("t3"));
+
+	cl_assert(git_path_isdir("t3"));
+	cl_assert(git_path_isdir("t3/b"));
+	cl_assert(git_path_isdir("t3/c"));
+	cl_assert(git_path_isdir("t3/c/d"));
+	cl_assert(git_path_isdir("t3/c/e"));
+
+	assert_hard_link("t3/f1");
+	assert_hard_link("t3/b/f2");
+	assert_hard_link("t3/c/f3");
+	assert_hard_link("t3/c/d/f4");
+#endif
+
+	cl_git_pass(git_futils_rmdir_r("src", NULL, GIT_RMDIR_REMOVE_FILES));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/dirent.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/dirent.c
new file mode 100755
index 0000000..d95e441
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/dirent.c
@@ -0,0 +1,277 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+
+typedef struct name_data {
+	int count; /* return count */
+	char *name; /* filename		*/
+} name_data;
+
+typedef struct walk_data {
+	char *sub;		/* sub-directory name */
+	name_data *names; /* name state data	*/
+	git_buf path;
+} walk_data;
+
+
+static char *top_dir = "dir-walk";
+static walk_data *state_loc;
+
+static void setup(walk_data *d)
+{
+	name_data *n;
+
+	cl_must_pass(p_mkdir(top_dir, 0777));
+
+	cl_must_pass(p_chdir(top_dir));
+
+	if (strcmp(d->sub, ".") != 0)
+		cl_must_pass(p_mkdir(d->sub, 0777));
+
+	cl_git_pass(git_buf_sets(&d->path, d->sub));
+
+	state_loc = d;
+
+	for (n = d->names; n->name; n++) {
+		git_file fd = p_creat(n->name, 0666);
+		cl_assert(fd >= 0);
+		p_close(fd);
+		n->count = 0;
+	}
+}
+
+static void dirent_cleanup__cb(void *_d)
+{
+	walk_data *d = _d;
+	name_data *n;
+
+	for (n = d->names; n->name; n++) {
+		cl_must_pass(p_unlink(n->name));
+	}
+
+	if (strcmp(d->sub, ".") != 0)
+		cl_must_pass(p_rmdir(d->sub));
+
+	cl_must_pass(p_chdir(".."));
+
+	cl_must_pass(p_rmdir(top_dir));
+
+	git_buf_free(&d->path);
+}
+
+static void check_counts(walk_data *d)
+{
+	name_data *n;
+
+	for (n = d->names; n->name; n++) {
+		cl_assert(n->count == 1);
+	}
+}
+
+static int update_count(name_data *data, const char *name)
+{
+	name_data *n;
+
+	for (n = data; n->name; n++) {
+		if (!strcmp(n->name, name)) {
+			n->count++;
+			return 0;
+		}
+	}
+
+	return GIT_ERROR;
+}
+
+static int one_entry(void *state, git_buf *path)
+{
+	walk_data *d = (walk_data *) state;
+
+	if (state != state_loc)
+		return GIT_ERROR;
+
+	if (path != &d->path)
+		return GIT_ERROR;
+
+	return update_count(d->names, path->ptr);
+}
+
+
+static name_data dot_names[] = {
+	{ 0, "./a" },
+	{ 0, "./asdf" },
+	{ 0, "./pack-foo.pack" },
+	{ 0, NULL }
+};
+static walk_data dot = {
+	".",
+	dot_names,
+	GIT_BUF_INIT
+};
+
+/* make sure that the '.' folder is not traversed */
+void test_core_dirent__dont_traverse_dot(void)
+{
+	cl_set_cleanup(&dirent_cleanup__cb, &dot);
+	setup(&dot);
+
+	cl_git_pass(git_path_direach(&dot.path, 0, one_entry, &dot));
+
+	check_counts(&dot);
+}
+
+
+static name_data sub_names[] = {
+	{ 0, "sub/a" },
+	{ 0, "sub/asdf" },
+	{ 0, "sub/pack-foo.pack" },
+	{ 0, NULL }
+};
+static walk_data sub = {
+	"sub",
+	sub_names,
+	GIT_BUF_INIT
+};
+
+/* traverse a subfolder */
+void test_core_dirent__traverse_subfolder(void)
+{
+	cl_set_cleanup(&dirent_cleanup__cb, &sub);
+	setup(&sub);
+
+	cl_git_pass(git_path_direach(&sub.path, 0, one_entry, &sub));
+
+	check_counts(&sub);
+}
+
+
+static walk_data sub_slash = {
+	"sub/",
+	sub_names,
+	GIT_BUF_INIT
+};
+
+/* traverse a slash-terminated subfolder */
+void test_core_dirent__traverse_slash_terminated_folder(void)
+{
+	cl_set_cleanup(&dirent_cleanup__cb, &sub_slash);
+	setup(&sub_slash);
+
+	cl_git_pass(git_path_direach(&sub_slash.path, 0, one_entry, &sub_slash));
+
+	check_counts(&sub_slash);
+}
+
+
+static name_data empty_names[] = {
+	{ 0, NULL }
+};
+static walk_data empty = {
+	"empty",
+	empty_names,
+	GIT_BUF_INIT
+};
+
+/* make sure that empty folders are not traversed */
+void test_core_dirent__dont_traverse_empty_folders(void)
+{
+	cl_set_cleanup(&dirent_cleanup__cb, &empty);
+	setup(&empty);
+
+	cl_git_pass(git_path_direach(&empty.path, 0, one_entry, &empty));
+
+	check_counts(&empty);
+
+	/* make sure callback not called */
+	cl_assert(git_path_is_empty_dir(empty.path.ptr));
+}
+
+static name_data odd_names[] = {
+	{ 0, "odd/.a" },
+	{ 0, "odd/..c" },
+	/* the following don't work on cygwin/win32 */
+	/* { 0, "odd/.b." }, */
+	/* { 0, "odd/..d.." }, */
+	{ 0, NULL }
+};
+static walk_data odd = {
+	"odd",
+	odd_names,
+	GIT_BUF_INIT
+};
+
+/* make sure that strange looking filenames ('..c') are traversed */
+void test_core_dirent__traverse_weird_filenames(void)
+{
+	cl_set_cleanup(&dirent_cleanup__cb, &odd);
+	setup(&odd);
+
+	cl_git_pass(git_path_direach(&odd.path, 0, one_entry, &odd));
+
+	check_counts(&odd);
+}
+
+/* test filename length limits */
+void test_core_dirent__length_limits(void)
+{
+	char *big_filename = (char *)git__malloc(FILENAME_MAX + 1);
+	memset(big_filename, 'a', FILENAME_MAX + 1);
+	big_filename[FILENAME_MAX] = 0;
+
+	cl_must_fail(p_creat(big_filename, 0666));
+
+	git__free(big_filename);
+}
+
+void test_core_dirent__empty_dir(void)
+{
+	cl_must_pass(p_mkdir("empty_dir", 0777));
+	cl_assert(git_path_is_empty_dir("empty_dir"));
+
+	cl_git_mkfile("empty_dir/content", "whatever\n");
+	cl_assert(!git_path_is_empty_dir("empty_dir"));
+	cl_assert(!git_path_is_empty_dir("empty_dir/content"));
+
+	cl_must_pass(p_unlink("empty_dir/content"));
+
+	cl_must_pass(p_mkdir("empty_dir/content", 0777));
+	cl_assert(!git_path_is_empty_dir("empty_dir"));
+	cl_assert(git_path_is_empty_dir("empty_dir/content"));
+
+	cl_must_pass(p_rmdir("empty_dir/content"));
+
+	cl_must_pass(p_rmdir("empty_dir"));
+}
+
+static void handle_next(git_path_diriter *diriter, walk_data *walk)
+{
+	const char *fullpath, *filename;
+	size_t fullpath_len, filename_len;
+
+	cl_git_pass(git_path_diriter_fullpath(&fullpath, &fullpath_len, diriter));
+	cl_git_pass(git_path_diriter_filename(&filename, &filename_len, diriter));
+
+	cl_assert_equal_strn(fullpath, "sub/", 4);
+	cl_assert_equal_s(fullpath+4, filename);
+
+	update_count(walk->names, fullpath);
+}
+
+/* test directory iterator */
+void test_core_dirent__diriter_with_fullname(void)
+{
+	git_path_diriter diriter = GIT_PATH_DIRITER_INIT;
+	int error;
+
+	cl_set_cleanup(&dirent_cleanup__cb, &sub);
+	setup(&sub);
+
+	cl_git_pass(git_path_diriter_init(&diriter, sub.path.ptr, 0));
+
+	while ((error = git_path_diriter_next(&diriter)) == 0)
+		handle_next(&diriter, &sub);
+
+	cl_assert_equal_i(error, GIT_ITEROVER);
+
+	git_path_diriter_free(&diriter);
+
+	check_counts(&sub);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/env.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/env.c
new file mode 100755
index 0000000..293b786
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/env.c
@@ -0,0 +1,304 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "sysdir.h"
+#include "path.h"
+
+#ifdef GIT_WIN32
+#define NUM_VARS 5
+static const char *env_vars[NUM_VARS] = {
+	"HOME", "HOMEDRIVE", "HOMEPATH", "USERPROFILE", "PROGRAMFILES"
+};
+#else
+#define NUM_VARS 1
+static const char *env_vars[NUM_VARS] = { "HOME" };
+#endif
+
+static char *env_save[NUM_VARS];
+
+static char *home_values[] = {
+	"fake_home",
+	"f\xc3\xa1ke_h\xc3\xb5me", /* all in latin-1 supplement */
+	"f\xc4\x80ke_\xc4\xa4ome", /* latin extended */
+	"f\xce\xb1\xce\xba\xce\xb5_h\xce\xbfm\xce\xad",  /* having fun with greek */
+	"fa\xe0" "\xb8" "\x87" "e_\xe0" "\xb8" "\x99" "ome", /* thai characters */
+	"f\xe1\x9c\x80ke_\xe1\x9c\x91ome", /* tagalog characters */
+	"\xe1\xb8\x9f\xe1\xba\xa2" "ke_ho" "\xe1" "\xb9" "\x81" "e", /* latin extended additional */
+	"\xf0\x9f\x98\x98\xf0\x9f\x98\x82", /* emoticons */
+	NULL
+};
+
+void test_core_env__initialize(void)
+{
+	int i;
+	for (i = 0; i < NUM_VARS; ++i) {
+		const char *original = cl_getenv(env_vars[i]);
+#ifdef GIT_WIN32
+		env_save[i] = (char *)original;
+#else
+		env_save[i] = original ? git__strdup(original) : NULL;
+#endif
+	}
+}
+
+static void set_global_search_path_from_env(void)
+{
+	cl_git_pass(git_sysdir_set(GIT_SYSDIR_GLOBAL, NULL));
+}
+
+static void set_system_search_path_from_env(void)
+{
+	cl_git_pass(git_sysdir_set(GIT_SYSDIR_SYSTEM, NULL));
+}
+
+void test_core_env__cleanup(void)
+{
+	int i;
+	char **val;
+
+	for (i = 0; i < NUM_VARS; ++i) {
+		cl_setenv(env_vars[i], env_save[i]);
+		git__free(env_save[i]);
+		env_save[i] = NULL;
+	}
+
+	/* these will probably have already been cleaned up, but if a test
+	 * fails, then it's probably good to try and clear out these dirs
+	 */
+	for (val = home_values; *val != NULL; val++) {
+		if (**val != '\0')
+			(void)p_rmdir(*val);
+	}
+
+	cl_sandbox_set_search_path_defaults();
+}
+
+static void setenv_and_check(const char *name, const char *value)
+{
+	char *check;
+
+	cl_git_pass(cl_setenv(name, value));
+
+	check = cl_getenv(name);
+	cl_assert_equal_s(value, check);
+#ifdef GIT_WIN32
+	git__free(check);
+#endif
+}
+
+void test_core_env__0(void)
+{
+	git_buf path = GIT_BUF_INIT, found = GIT_BUF_INIT;
+	char testfile[16], tidx = '0';
+	char **val;
+	const char *testname = "testfile";
+	size_t testlen = strlen(testname);
+
+	strncpy(testfile, testname, sizeof(testfile));
+	cl_assert_equal_s(testname, testfile);
+
+	for (val = home_values; *val != NULL; val++) {
+
+		/* if we can't make the directory, let's just assume
+		 * we are on a filesystem that doesn't support the
+		 * characters in question and skip this test...
+		 */
+		if (p_mkdir(*val, 0777) != 0) {
+			*val = ""; /* mark as not created */
+			continue;
+		}
+
+		cl_git_pass(git_path_prettify(&path, *val, NULL));
+
+		/* vary testfile name in each directory so accidentally leaving
+		 * an environment variable set from a previous iteration won't
+		 * accidentally make this test pass...
+		 */
+		testfile[testlen] = tidx++;
+		cl_git_pass(git_buf_joinpath(&path, path.ptr, testfile));
+		cl_git_mkfile(path.ptr, "find me");
+		git_buf_rtruncate_at_char(&path, '/');
+
+		cl_assert_equal_i(
+			GIT_ENOTFOUND, git_sysdir_find_global_file(&found, testfile));
+
+		setenv_and_check("HOME", path.ptr);
+		set_global_search_path_from_env();
+
+		cl_git_pass(git_sysdir_find_global_file(&found, testfile));
+
+		cl_setenv("HOME", env_save[0]);
+		set_global_search_path_from_env();
+
+		cl_assert_equal_i(
+			GIT_ENOTFOUND, git_sysdir_find_global_file(&found, testfile));
+
+#ifdef GIT_WIN32
+		setenv_and_check("HOMEDRIVE", NULL);
+		setenv_and_check("HOMEPATH", NULL);
+		setenv_and_check("USERPROFILE", path.ptr);
+		set_global_search_path_from_env();
+
+		cl_git_pass(git_sysdir_find_global_file(&found, testfile));
+
+		{
+			int root = git_path_root(path.ptr);
+			char old;
+
+			if (root >= 0) {
+				setenv_and_check("USERPROFILE", NULL);
+				set_global_search_path_from_env();
+
+				cl_assert_equal_i(
+					GIT_ENOTFOUND, git_sysdir_find_global_file(&found, testfile));
+
+				old = path.ptr[root];
+				path.ptr[root] = '\0';
+				setenv_and_check("HOMEDRIVE", path.ptr);
+				path.ptr[root] = old;
+				setenv_and_check("HOMEPATH", &path.ptr[root]);
+				set_global_search_path_from_env();
+
+				cl_git_pass(git_sysdir_find_global_file(&found, testfile));
+			}
+		}
+#endif
+
+		(void)p_rmdir(*val);
+	}
+
+	git_buf_free(&path);
+	git_buf_free(&found);
+}
+
+
+void test_core_env__1(void)
+{
+	git_buf path = GIT_BUF_INIT;
+
+	cl_assert_equal_i(
+		GIT_ENOTFOUND, git_sysdir_find_global_file(&path, "nonexistentfile"));
+
+	cl_git_pass(cl_setenv("HOME", "doesnotexist"));
+#ifdef GIT_WIN32
+	cl_git_pass(cl_setenv("HOMEPATH", "doesnotexist"));
+	cl_git_pass(cl_setenv("USERPROFILE", "doesnotexist"));
+#endif
+	set_global_search_path_from_env();
+
+	cl_assert_equal_i(
+		GIT_ENOTFOUND, git_sysdir_find_global_file(&path, "nonexistentfile"));
+
+	cl_git_pass(cl_setenv("HOME", NULL));
+#ifdef GIT_WIN32
+	cl_git_pass(cl_setenv("HOMEPATH", NULL));
+	cl_git_pass(cl_setenv("USERPROFILE", NULL));
+#endif
+	set_global_search_path_from_env();
+	set_system_search_path_from_env();
+
+	cl_assert_equal_i(
+		GIT_ENOTFOUND, git_sysdir_find_global_file(&path, "nonexistentfile"));
+
+	cl_assert_equal_i(
+		GIT_ENOTFOUND, git_sysdir_find_system_file(&path, "nonexistentfile"));
+
+#ifdef GIT_WIN32
+	cl_git_pass(cl_setenv("PROGRAMFILES", NULL));
+	set_system_search_path_from_env();
+
+	cl_assert_equal_i(
+		GIT_ENOTFOUND, git_sysdir_find_system_file(&path, "nonexistentfile"));
+#endif
+
+	git_buf_free(&path);
+}
+
+static void check_global_searchpath(
+	const char *path, int position, const char *file, git_buf *temp)
+{
+	git_buf out = GIT_BUF_INIT;
+
+	/* build and set new path */
+	if (position < 0)
+		cl_git_pass(git_buf_join(temp, GIT_PATH_LIST_SEPARATOR, path, "$PATH"));
+	else if (position > 0)
+		cl_git_pass(git_buf_join(temp, GIT_PATH_LIST_SEPARATOR, "$PATH", path));
+	else
+		cl_git_pass(git_buf_sets(temp, path));
+
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, temp->ptr));
+
+	/* get path and make sure $PATH expansion worked */
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &out));
+
+	if (position < 0)
+		cl_assert(git__prefixcmp(out.ptr, path) == 0);
+	else if (position > 0)
+		cl_assert(git__suffixcmp(out.ptr, path) == 0);
+	else
+		cl_assert_equal_s(out.ptr, path);
+
+	/* find file using new path */
+	cl_git_pass(git_sysdir_find_global_file(temp, file));
+
+	/* reset path and confirm file not found */
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, NULL));
+	cl_assert_equal_i(
+		GIT_ENOTFOUND, git_sysdir_find_global_file(temp, file));
+
+	git_buf_free(&out);
+}
+
+void test_core_env__2(void)
+{
+	git_buf path = GIT_BUF_INIT, found = GIT_BUF_INIT;
+	char testfile[16], tidx = '0';
+	char **val;
+	const char *testname = "alternate";
+	size_t testlen = strlen(testname);
+
+	strncpy(testfile, testname, sizeof(testfile));
+	cl_assert_equal_s(testname, testfile);
+
+	for (val = home_values; *val != NULL; val++) {
+
+		/* if we can't make the directory, let's just assume
+		 * we are on a filesystem that doesn't support the
+		 * characters in question and skip this test...
+		 */
+		if (p_mkdir(*val, 0777) != 0 && errno != EEXIST) {
+			*val = ""; /* mark as not created */
+			continue;
+		}
+
+		cl_git_pass(git_path_prettify(&path, *val, NULL));
+
+		/* vary testfile name so any sloppiness is resetting variables or
+		 * deleting files won't accidentally make a test pass.
+		 */
+		testfile[testlen] = tidx++;
+		cl_git_pass(git_buf_joinpath(&path, path.ptr, testfile));
+		cl_git_mkfile(path.ptr, "find me");
+		git_buf_rtruncate_at_char(&path, '/');
+
+		/* default should be NOTFOUND */
+		cl_assert_equal_i(
+			GIT_ENOTFOUND, git_sysdir_find_global_file(&found, testfile));
+
+		/* try plain, append $PATH, and prepend $PATH */
+		check_global_searchpath(path.ptr,  0, testfile, &found);
+		check_global_searchpath(path.ptr, -1, testfile, &found);
+		check_global_searchpath(path.ptr,  1, testfile, &found);
+
+		/* cleanup */
+		cl_git_pass(git_buf_joinpath(&path, path.ptr, testfile));
+		(void)p_unlink(path.ptr);
+		(void)p_rmdir(*val);
+	}
+
+	git_buf_free(&path);
+	git_buf_free(&found);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/errors.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/errors.c
new file mode 100755
index 0000000..a06ec4a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/errors.c
@@ -0,0 +1,176 @@
+#include "clar_libgit2.h"
+
+void test_core_errors__public_api(void)
+{
+	char *str_in_error;
+
+	giterr_clear();
+	cl_assert(giterr_last() == NULL);
+
+	giterr_set_oom();
+
+	cl_assert(giterr_last() != NULL);
+	cl_assert(giterr_last()->klass == GITERR_NOMEMORY);
+	str_in_error = strstr(giterr_last()->message, "memory");
+	cl_assert(str_in_error != NULL);
+
+	giterr_clear();
+
+	giterr_set_str(GITERR_REPOSITORY, "This is a test");
+
+	cl_assert(giterr_last() != NULL);
+	str_in_error = strstr(giterr_last()->message, "This is a test");
+	cl_assert(str_in_error != NULL);
+
+	giterr_clear();
+	cl_assert(giterr_last() == NULL);
+}
+
+#include "common.h"
+#include "util.h"
+#include "posix.h"
+
+void test_core_errors__new_school(void)
+{
+	char *str_in_error;
+
+	giterr_clear();
+	cl_assert(giterr_last() == NULL);
+
+	giterr_set_oom(); /* internal fn */
+
+	cl_assert(giterr_last() != NULL);
+	cl_assert(giterr_last()->klass == GITERR_NOMEMORY);
+	str_in_error = strstr(giterr_last()->message, "memory");
+	cl_assert(str_in_error != NULL);
+
+	giterr_clear();
+
+	giterr_set(GITERR_REPOSITORY, "This is a test"); /* internal fn */
+
+	cl_assert(giterr_last() != NULL);
+	str_in_error = strstr(giterr_last()->message, "This is a test");
+	cl_assert(str_in_error != NULL);
+
+	giterr_clear();
+	cl_assert(giterr_last() == NULL);
+
+	do {
+		struct stat st;
+		memset(&st, 0, sizeof(st));
+		cl_assert(p_lstat("this_file_does_not_exist", &st) < 0);
+		GIT_UNUSED(st);
+	} while (false);
+	giterr_set(GITERR_OS, "stat failed"); /* internal fn */
+
+	cl_assert(giterr_last() != NULL);
+	str_in_error = strstr(giterr_last()->message, "stat failed");
+	cl_assert(str_in_error != NULL);
+	cl_assert(git__prefixcmp(str_in_error, "stat failed: ") == 0);
+	cl_assert(strlen(str_in_error) > strlen("stat failed: "));
+
+#ifdef GIT_WIN32
+	giterr_clear();
+
+	/* The MSDN docs use this to generate a sample error */
+	cl_assert(GetProcessId(NULL) == 0);
+	giterr_set(GITERR_OS, "GetProcessId failed"); /* internal fn */
+
+	cl_assert(giterr_last() != NULL);
+	str_in_error = strstr(giterr_last()->message, "GetProcessId failed");
+	cl_assert(str_in_error != NULL);
+	cl_assert(git__prefixcmp(str_in_error, "GetProcessId failed: ") == 0);
+	cl_assert(strlen(str_in_error) > strlen("GetProcessId failed: "));
+#endif
+
+	giterr_clear();
+}
+
+void test_core_errors__restore(void)
+{
+	git_error_state err_state = {0};
+
+	giterr_clear();
+	cl_assert(giterr_last() == NULL);
+
+	cl_assert_equal_i(0, giterr_capture(&err_state, 0));
+
+	memset(&err_state, 0x0, sizeof(git_error_state));
+
+	giterr_set(42, "Foo: %s", "bar");
+	cl_assert_equal_i(-1, giterr_capture(&err_state, -1));
+
+	cl_assert(giterr_last() == NULL);
+
+	giterr_set(99, "Bar: %s", "foo");
+
+	giterr_restore(&err_state);
+
+	cl_assert_equal_i(42, giterr_last()->klass);
+	cl_assert_equal_s("Foo: bar", giterr_last()->message);
+}
+
+static int test_arraysize_multiply(size_t nelem, size_t size)
+{
+	size_t out;
+	GITERR_CHECK_ALLOC_MULTIPLY(&out, nelem, size);
+	return 0;
+}
+
+void test_core_errors__integer_overflow_alloc_multiply(void)
+{
+	cl_git_pass(test_arraysize_multiply(10, 10));
+	cl_git_pass(test_arraysize_multiply(1000, 1000));
+	cl_git_pass(test_arraysize_multiply(SIZE_MAX/sizeof(void *), sizeof(void *)));
+	cl_git_pass(test_arraysize_multiply(0, 10));
+	cl_git_pass(test_arraysize_multiply(10, 0));
+
+	cl_git_fail(test_arraysize_multiply(SIZE_MAX-1, sizeof(void *)));
+	cl_git_fail(test_arraysize_multiply((SIZE_MAX/sizeof(void *))+1, sizeof(void *)));
+
+	cl_assert_equal_i(GITERR_NOMEMORY, giterr_last()->klass);
+	cl_assert_equal_s("Out of memory", giterr_last()->message);
+}
+
+static int test_arraysize_add(size_t one, size_t two)
+{
+	size_t out;
+	GITERR_CHECK_ALLOC_ADD(&out, one, two);
+	return 0;
+}
+
+void test_core_errors__integer_overflow_alloc_add(void)
+{
+	cl_git_pass(test_arraysize_add(10, 10));
+	cl_git_pass(test_arraysize_add(1000, 1000));
+	cl_git_pass(test_arraysize_add(SIZE_MAX-10, 10));
+
+	cl_git_fail(test_arraysize_multiply(SIZE_MAX-1, 2));
+	cl_git_fail(test_arraysize_multiply(SIZE_MAX, SIZE_MAX));
+
+	cl_assert_equal_i(GITERR_NOMEMORY, giterr_last()->klass);
+	cl_assert_equal_s("Out of memory", giterr_last()->message);
+}
+
+void test_core_errors__integer_overflow_sets_oom(void)
+{
+	size_t out;
+
+	giterr_clear();
+	cl_assert(!GIT_ADD_SIZET_OVERFLOW(&out, SIZE_MAX-1, 1));
+	cl_assert_equal_p(NULL, giterr_last());
+
+	giterr_clear();
+	cl_assert(!GIT_ADD_SIZET_OVERFLOW(&out, 42, 69));
+	cl_assert_equal_p(NULL, giterr_last());
+
+	giterr_clear();
+	cl_assert(GIT_ADD_SIZET_OVERFLOW(&out, SIZE_MAX, SIZE_MAX));
+	cl_assert_equal_i(GITERR_NOMEMORY, giterr_last()->klass);
+	cl_assert_equal_s("Out of memory", giterr_last()->message);
+
+	giterr_clear();
+	cl_assert(GIT_ADD_SIZET_OVERFLOW(&out, SIZE_MAX, SIZE_MAX));
+	cl_assert_equal_i(GITERR_NOMEMORY, giterr_last()->klass);
+	cl_assert_equal_s("Out of memory", giterr_last()->message);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/features.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/features.c
new file mode 100755
index 0000000..5eeb05e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/features.c
@@ -0,0 +1,31 @@
+#include "clar_libgit2.h"
+
+void test_core_features__0(void)
+{
+	int major, minor, rev, caps;
+
+	git_libgit2_version(&major, &minor, &rev);
+	cl_assert_equal_i(LIBGIT2_VER_MAJOR, major);
+	cl_assert_equal_i(LIBGIT2_VER_MINOR, minor);
+	cl_assert_equal_i(LIBGIT2_VER_REVISION, rev);
+
+	caps = git_libgit2_features();
+
+#ifdef GIT_THREADS
+	cl_assert((caps & GIT_FEATURE_THREADS) != 0);
+#else
+	cl_assert((caps & GIT_FEATURE_THREADS) == 0);
+#endif
+
+#if defined(GIT_OPENSSL) || defined(GIT_WINHTTP) || defined(GIT_SECURE_TRANSPORT)
+	cl_assert((caps & GIT_FEATURE_HTTPS) != 0);
+#else
+	cl_assert((caps & GIT_FEATURE_HTTPS) == 0);
+#endif
+
+#if defined(GIT_SSH)
+	cl_assert((caps & GIT_FEATURE_SSH) != 0);
+#else
+	cl_assert((caps & GIT_FEATURE_SSH) == 0);
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/filebuf.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/filebuf.c
new file mode 100755
index 0000000..3f7dc85
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/filebuf.c
@@ -0,0 +1,153 @@
+#include "clar_libgit2.h"
+#include "filebuf.h"
+
+/* make sure git_filebuf_open doesn't delete an existing lock */
+void test_core_filebuf__0(void)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	int fd;
+	char test[] = "test", testlock[] = "test.lock";
+
+	fd = p_creat(testlock, 0744); //-V536
+
+	cl_must_pass(fd);
+	cl_must_pass(p_close(fd));
+
+	cl_git_fail(git_filebuf_open(&file, test, 0, 0666));
+	cl_assert(git_path_exists(testlock));
+
+	cl_must_pass(p_unlink(testlock));
+}
+
+
+/* make sure GIT_FILEBUF_APPEND works as expected */
+void test_core_filebuf__1(void)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	char test[] = "test";
+
+	cl_git_mkfile(test, "libgit2 rocks\n");
+
+	cl_git_pass(git_filebuf_open(&file, test, GIT_FILEBUF_APPEND, 0666));
+	cl_git_pass(git_filebuf_printf(&file, "%s\n", "libgit2 rocks"));
+	cl_git_pass(git_filebuf_commit(&file));
+
+	cl_assert_equal_file("libgit2 rocks\nlibgit2 rocks\n", 0, test);
+
+	cl_must_pass(p_unlink(test));
+}
+
+
+/* make sure git_filebuf_write writes large buffer correctly */
+void test_core_filebuf__2(void)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	char test[] = "test";
+	unsigned char buf[4096 * 4]; /* 2 * WRITE_BUFFER_SIZE */
+
+	memset(buf, 0xfe, sizeof(buf));
+
+	cl_git_pass(git_filebuf_open(&file, test, 0, 0666));
+	cl_git_pass(git_filebuf_write(&file, buf, sizeof(buf)));
+	cl_git_pass(git_filebuf_commit(&file));
+
+	cl_assert_equal_file((char *)buf, sizeof(buf), test);
+
+	cl_must_pass(p_unlink(test));
+}
+
+/* make sure git_filebuf_cleanup clears the buffer */
+void test_core_filebuf__4(void)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	char test[] = "test";
+
+	cl_assert(file.buffer == NULL);
+
+	cl_git_pass(git_filebuf_open(&file, test, 0, 0666));
+	cl_assert(file.buffer != NULL);
+
+	git_filebuf_cleanup(&file);
+	cl_assert(file.buffer == NULL);
+}
+
+
+/* make sure git_filebuf_commit clears the buffer */
+void test_core_filebuf__5(void)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	char test[] = "test";
+
+	cl_assert(file.buffer == NULL);
+
+	cl_git_pass(git_filebuf_open(&file, test, 0, 0666));
+	cl_assert(file.buffer != NULL);
+	cl_git_pass(git_filebuf_printf(&file, "%s\n", "libgit2 rocks"));
+	cl_assert(file.buffer != NULL);
+
+	cl_git_pass(git_filebuf_commit(&file));
+	cl_assert(file.buffer == NULL);
+
+	cl_must_pass(p_unlink(test));
+}
+
+
+/* make sure git_filebuf_commit takes umask into account */
+void test_core_filebuf__umask(void)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	char test[] = "test";
+	struct stat statbuf;
+	mode_t mask, os_mask;
+
+#ifdef GIT_WIN32
+	os_mask = 0600;
+#else
+	os_mask = 0777;
+#endif
+
+	p_umask(mask = p_umask(0));
+
+	cl_assert(file.buffer == NULL);
+
+	cl_git_pass(git_filebuf_open(&file, test, 0, 0666));
+	cl_assert(file.buffer != NULL);
+	cl_git_pass(git_filebuf_printf(&file, "%s\n", "libgit2 rocks"));
+	cl_assert(file.buffer != NULL);
+
+	cl_git_pass(git_filebuf_commit(&file));
+	cl_assert(file.buffer == NULL);
+
+	cl_must_pass(p_stat("test", &statbuf));
+	cl_assert_equal_i(statbuf.st_mode & os_mask, (0666 & ~mask) & os_mask);
+
+	cl_must_pass(p_unlink(test));
+}
+
+void test_core_filebuf__rename_error(void)
+{
+	git_filebuf file = GIT_FILEBUF_INIT;
+	char *dir = "subdir",  *test = "subdir/test", *test_lock = "subdir/test.lock";
+	int fd;
+
+#ifndef GIT_WIN32
+	cl_skip();
+#endif
+
+	cl_git_pass(p_mkdir(dir, 0666));
+	cl_git_mkfile(test, "dummy content");
+	fd = p_open(test, O_RDONLY);
+	cl_assert(fd > 0);
+	cl_git_pass(git_filebuf_open(&file, test, 0, 0666));
+
+	cl_git_pass(git_filebuf_printf(&file, "%s\n", "libgit2 rocks"));
+
+	cl_assert_equal_i(true, git_path_exists(test_lock));
+
+	cl_git_fail(git_filebuf_commit(&file));
+	p_close(fd);
+
+	git_filebuf_cleanup(&file);
+
+	cl_assert_equal_i(false, git_path_exists(test_lock));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/ftruncate.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/ftruncate.c
new file mode 100755
index 0000000..21981d6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/ftruncate.c
@@ -0,0 +1,48 @@
+/**
+ * Some tests for p_ftruncate() to ensure that
+ * properly handles large (2Gb+) files.
+ */
+
+#include "clar_libgit2.h"
+
+static const char *filename = "core_ftruncate.txt";
+static int fd = -1;
+
+void test_core_ftruncate__initialize(void)
+{
+	if (!cl_getenv("GITTEST_INVASIVE_FS_SIZE"))
+		cl_skip();
+
+	cl_must_pass((fd = p_open(filename, O_CREAT | O_RDWR, 0644)));
+}
+
+void test_core_ftruncate__cleanup(void)
+{
+	if (fd < 0)
+		return;
+
+	p_close(fd);
+	fd = 0;
+
+	p_unlink(filename);
+}
+
+static void _extend(git_off_t i64len)
+{
+	struct stat st;
+	int error;
+
+	cl_assert((error = p_ftruncate(fd, i64len)) == 0);
+	cl_assert((error = p_fstat(fd, &st)) == 0);
+	cl_assert(st.st_size == i64len);
+}
+
+void test_core_ftruncate__2gb(void)
+{
+	_extend(0x80000001);
+}
+
+void test_core_ftruncate__4gb(void)
+{
+	_extend(0x100000001);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/hex.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/hex.c
new file mode 100755
index 0000000..930af16
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/hex.c
@@ -0,0 +1,22 @@
+#include "clar_libgit2.h"
+#include "util.h"
+
+void test_core_hex__fromhex(void)
+{
+	/* Passing cases */
+	cl_assert(git__fromhex('0') == 0x0);
+	cl_assert(git__fromhex('1') == 0x1);
+	cl_assert(git__fromhex('3') == 0x3);
+	cl_assert(git__fromhex('9') == 0x9);
+	cl_assert(git__fromhex('A') == 0xa);
+	cl_assert(git__fromhex('C') == 0xc);
+	cl_assert(git__fromhex('F') == 0xf);
+	cl_assert(git__fromhex('a') == 0xa);
+	cl_assert(git__fromhex('c') == 0xc);
+	cl_assert(git__fromhex('f') == 0xf);
+
+	/* Failing cases */
+	cl_assert(git__fromhex('g') == -1);
+	cl_assert(git__fromhex('z') == -1);
+	cl_assert(git__fromhex('X') == -1);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/iconv.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/iconv.c
new file mode 100755
index 0000000..498094b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/iconv.c
@@ -0,0 +1,78 @@
+#include "clar_libgit2.h"
+#include "path.h"
+
+#ifdef GIT_USE_ICONV
+static git_path_iconv_t ic;
+static char *nfc = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D";
+static char *nfd = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D";
+#endif
+
+void test_core_iconv__initialize(void)
+{
+#ifdef GIT_USE_ICONV
+	cl_git_pass(git_path_iconv_init_precompose(&ic));
+#endif
+}
+
+void test_core_iconv__cleanup(void)
+{
+#ifdef GIT_USE_ICONV
+	git_path_iconv_clear(&ic);
+#endif
+}
+
+void test_core_iconv__unchanged(void)
+{
+#ifdef GIT_USE_ICONV
+	const char *data = "Ascii data", *original = data;
+	size_t datalen = strlen(data);
+
+	cl_git_pass(git_path_iconv(&ic, &data, &datalen));
+	GIT_UNUSED(datalen);
+
+	/* There are no high bits set, so this should leave data untouched */
+	cl_assert(data == original);
+#endif
+}
+
+void test_core_iconv__decomposed_to_precomposed(void)
+{
+#ifdef GIT_USE_ICONV
+	const char *data = nfd;
+	size_t datalen, nfdlen = strlen(nfd);
+
+	datalen = nfdlen;
+	cl_git_pass(git_path_iconv(&ic, &data, &datalen));
+	GIT_UNUSED(datalen);
+
+	/* The decomposed nfd string should be transformed to the nfc form
+	 * (on platforms where iconv is enabled, of course).
+	 */
+	cl_assert_equal_s(nfc, data);
+
+	/* should be able to do it multiple times with the same git_path_iconv_t */
+	data = nfd; datalen = nfdlen;
+	cl_git_pass(git_path_iconv(&ic, &data, &datalen));
+	cl_assert_equal_s(nfc, data);
+
+	data = nfd; datalen = nfdlen;
+	cl_git_pass(git_path_iconv(&ic, &data, &datalen));
+	cl_assert_equal_s(nfc, data);
+#endif
+}
+
+void test_core_iconv__precomposed_is_unmodified(void)
+{
+#ifdef GIT_USE_ICONV
+	const char *data = nfc;
+	size_t datalen = strlen(nfc);
+
+	cl_git_pass(git_path_iconv(&ic, &data, &datalen));
+	GIT_UNUSED(datalen);
+
+	/* data is already in precomposed form, so even though some bytes have
+	 * the high-bit set, the iconv transform should result in no change.
+	 */
+	cl_assert_equal_s(nfc, data);
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/init.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/init.c
new file mode 100755
index 0000000..e17b784
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/init.c
@@ -0,0 +1,14 @@
+#include "clar_libgit2.h"
+
+void test_core_init__returns_count(void)
+{
+	/* libgit2_clar initializes us first, so we have an existing
+	 * initialization.
+	 */
+	cl_assert_equal_i(2, git_libgit2_init());
+	cl_assert_equal_i(3, git_libgit2_init());
+
+	cl_assert_equal_i(2, git_libgit2_shutdown());
+	cl_assert_equal_i(1, git_libgit2_shutdown());
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/link.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/link.c
new file mode 100755
index 0000000..ec85ec4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/link.c
@@ -0,0 +1,632 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "buffer.h"
+#include "path.h"
+
+#ifdef GIT_WIN32
+# include "win32/reparse.h"
+#endif
+
+void test_core_link__cleanup(void)
+{
+#ifdef GIT_WIN32
+	RemoveDirectory("lstat_junction");
+	RemoveDirectory("lstat_dangling");
+	RemoveDirectory("lstat_dangling_dir");
+	RemoveDirectory("lstat_dangling_junction");
+
+	RemoveDirectory("stat_junction");
+	RemoveDirectory("stat_dangling");
+	RemoveDirectory("stat_dangling_dir");
+	RemoveDirectory("stat_dangling_junction");
+#endif
+}
+
+#ifdef GIT_WIN32
+static bool should_run(void)
+{
+	static SID_IDENTIFIER_AUTHORITY authority = { SECURITY_NT_AUTHORITY };
+	PSID admin_sid;
+	BOOL is_admin;
+
+	cl_win32_pass(AllocateAndInitializeSid(&authority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &admin_sid));
+	cl_win32_pass(CheckTokenMembership(NULL, admin_sid, &is_admin));
+	FreeSid(admin_sid);
+
+	return is_admin ? true : false;
+}
+#else
+static bool should_run(void)
+{
+	return true;
+}
+#endif
+
+static void do_symlink(const char *old, const char *new, int is_dir)
+{
+#ifndef GIT_WIN32
+	GIT_UNUSED(is_dir);
+
+	cl_must_pass(symlink(old, new));
+#else
+	typedef DWORD (WINAPI *create_symlink_func)(LPCTSTR, LPCTSTR, DWORD);
+	HMODULE module;
+	create_symlink_func pCreateSymbolicLink;
+
+	cl_assert(module = GetModuleHandle("kernel32"));
+	cl_assert(pCreateSymbolicLink = (create_symlink_func)GetProcAddress(module, "CreateSymbolicLinkA"));
+
+	cl_win32_pass(pCreateSymbolicLink(new, old, is_dir));
+#endif
+}
+
+static void do_hardlink(const char *old, const char *new)
+{
+#ifndef GIT_WIN32
+	cl_must_pass(link(old, new));
+#else
+	typedef DWORD (WINAPI *create_hardlink_func)(LPCTSTR, LPCTSTR, LPSECURITY_ATTRIBUTES);
+	HMODULE module;
+	create_hardlink_func pCreateHardLink;
+
+	cl_assert(module = GetModuleHandle("kernel32"));
+	cl_assert(pCreateHardLink = (create_hardlink_func)GetProcAddress(module, "CreateHardLinkA"));
+
+	cl_win32_pass(pCreateHardLink(new, old, 0));
+#endif
+}
+
+#ifdef GIT_WIN32
+
+static void do_junction(const char *old, const char *new)
+{
+	GIT_REPARSE_DATA_BUFFER *reparse_buf;
+	HANDLE handle;
+	git_buf unparsed_buf = GIT_BUF_INIT;
+	wchar_t *subst_utf16, *print_utf16;
+	DWORD ioctl_ret;
+	int subst_utf16_len, subst_byte_len, print_utf16_len, print_byte_len, ret;
+	USHORT reparse_buflen;
+	size_t i;
+
+	/* Junction targets must be the unparsed name, starting with \??\, using
+	 * backslashes instead of forward, and end in a trailing backslash.
+	 * eg: \??\C:\Foo\
+	 */
+	git_buf_puts(&unparsed_buf, "\\??\\");
+
+	for (i = 0; i < strlen(old); i++)
+		git_buf_putc(&unparsed_buf, old[i] == '/' ? '\\' : old[i]);
+
+	git_buf_putc(&unparsed_buf, '\\');
+
+	subst_utf16_len = git__utf8_to_16(NULL, 0, git_buf_cstr(&unparsed_buf));
+	subst_byte_len = subst_utf16_len * sizeof(WCHAR);
+
+	print_utf16_len = subst_utf16_len - 4;
+	print_byte_len = subst_byte_len - (4 * sizeof(WCHAR));
+
+	/* The junction must be an empty directory before the junction attribute
+	 * can be added.
+	 */
+	cl_win32_pass(CreateDirectoryA(new, NULL));
+
+	handle = CreateFileA(new, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
+		FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
+	cl_win32_pass(handle != INVALID_HANDLE_VALUE);
+
+	reparse_buflen = (USHORT)(REPARSE_DATA_HEADER_SIZE +
+		REPARSE_DATA_MOUNTPOINT_HEADER_SIZE +
+		subst_byte_len + sizeof(WCHAR) +
+		print_byte_len + sizeof(WCHAR));
+
+	reparse_buf = LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT, reparse_buflen);
+	cl_assert(reparse_buf);
+
+	subst_utf16 = reparse_buf->MountPointReparseBuffer.PathBuffer;
+	print_utf16 = subst_utf16 + subst_utf16_len + 1;
+
+	ret = git__utf8_to_16(subst_utf16, subst_utf16_len + 1,
+		git_buf_cstr(&unparsed_buf));
+	cl_assert_equal_i(subst_utf16_len, ret);
+
+	ret = git__utf8_to_16(print_utf16,
+		print_utf16_len + 1, git_buf_cstr(&unparsed_buf) + 4);
+	cl_assert_equal_i(print_utf16_len, ret);
+
+	reparse_buf->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
+	reparse_buf->MountPointReparseBuffer.SubstituteNameOffset = 0;
+	reparse_buf->MountPointReparseBuffer.SubstituteNameLength = subst_byte_len;
+	reparse_buf->MountPointReparseBuffer.PrintNameOffset = (USHORT)(subst_byte_len + sizeof(WCHAR));
+	reparse_buf->MountPointReparseBuffer.PrintNameLength = print_byte_len;
+	reparse_buf->ReparseDataLength = reparse_buflen - REPARSE_DATA_HEADER_SIZE;
+
+	cl_win32_pass(DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT,
+		reparse_buf, reparse_buflen, NULL, 0, &ioctl_ret, NULL));
+
+	CloseHandle(handle);
+	LocalFree(reparse_buf);
+
+	git_buf_free(&unparsed_buf);
+}
+
+static void do_custom_reparse(const char *path)
+{
+	REPARSE_GUID_DATA_BUFFER *reparse_buf;
+	HANDLE handle;
+	DWORD ioctl_ret;
+
+	const char *reparse_data = "Reparse points are silly.";
+	size_t reparse_buflen = REPARSE_GUID_DATA_BUFFER_HEADER_SIZE +
+		strlen(reparse_data) + 1;
+
+	reparse_buf = LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT, reparse_buflen);
+	cl_assert(reparse_buf);
+
+	reparse_buf->ReparseTag = 42;
+	reparse_buf->ReparseDataLength = (WORD)(strlen(reparse_data) + 1);
+
+	reparse_buf->ReparseGuid.Data1 = 0xdeadbeef;
+	reparse_buf->ReparseGuid.Data2 = 0xdead;
+	reparse_buf->ReparseGuid.Data3 = 0xbeef;
+	reparse_buf->ReparseGuid.Data4[0] = 42;
+	reparse_buf->ReparseGuid.Data4[1] = 42;
+	reparse_buf->ReparseGuid.Data4[2] = 42;
+	reparse_buf->ReparseGuid.Data4[3] = 42;
+	reparse_buf->ReparseGuid.Data4[4] = 42;
+	reparse_buf->ReparseGuid.Data4[5] = 42;
+	reparse_buf->ReparseGuid.Data4[6] = 42;
+	reparse_buf->ReparseGuid.Data4[7] = 42;
+	reparse_buf->ReparseGuid.Data4[8] = 42;
+
+	memcpy(reparse_buf->GenericReparseBuffer.DataBuffer,
+		reparse_data, strlen(reparse_data) + 1);
+
+	handle = CreateFileA(path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
+		FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
+	cl_win32_pass(handle != INVALID_HANDLE_VALUE);
+
+	cl_win32_pass(DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT,
+		reparse_buf,
+		reparse_buf->ReparseDataLength + REPARSE_GUID_DATA_BUFFER_HEADER_SIZE,
+		NULL, 0, &ioctl_ret, NULL));
+
+	CloseHandle(handle);
+	LocalFree(reparse_buf);
+}
+
+#endif
+
+void test_core_link__stat_regular_file(void)
+{
+	struct stat st;
+
+	cl_git_rewritefile("stat_regfile", "This is a regular file!\n");
+
+	cl_must_pass(p_stat("stat_regfile", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert_equal_i(24, st.st_size);
+}
+
+void test_core_link__lstat_regular_file(void)
+{
+	struct stat st;
+
+	cl_git_rewritefile("lstat_regfile", "This is a regular file!\n");
+
+	cl_must_pass(p_stat("lstat_regfile", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert_equal_i(24, st.st_size);
+}
+
+void test_core_link__stat_symlink(void)
+{
+	struct stat st;
+
+	if (!should_run())
+		clar__skip();
+
+	cl_git_rewritefile("stat_target", "This is the target of a symbolic link.\n");
+	do_symlink("stat_target", "stat_symlink", 0);
+
+	cl_must_pass(p_stat("stat_target", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert_equal_i(39, st.st_size);
+
+	cl_must_pass(p_stat("stat_symlink", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert_equal_i(39, st.st_size);
+}
+
+void test_core_link__stat_symlink_directory(void)
+{
+	struct stat st;
+
+	if (!should_run())
+		clar__skip();
+
+	p_mkdir("stat_dirtarget", 0777);
+	do_symlink("stat_dirtarget", "stat_dirlink", 1);
+
+	cl_must_pass(p_stat("stat_dirtarget", &st));
+	cl_assert(S_ISDIR(st.st_mode));
+
+	cl_must_pass(p_stat("stat_dirlink", &st));
+	cl_assert(S_ISDIR(st.st_mode));
+}
+
+void test_core_link__stat_symlink_chain(void)
+{
+	struct stat st;
+
+	if (!should_run())
+		clar__skip();
+
+	cl_git_rewritefile("stat_final_target", "Final target of some symbolic links...\n");
+	do_symlink("stat_final_target", "stat_chain_3", 0);
+	do_symlink("stat_chain_3", "stat_chain_2", 0);
+	do_symlink("stat_chain_2", "stat_chain_1", 0);
+
+	cl_must_pass(p_stat("stat_chain_1", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert_equal_i(39, st.st_size);
+}
+
+void test_core_link__stat_dangling_symlink(void)
+{
+	struct stat st;
+
+	if (!should_run())
+		clar__skip();
+
+	do_symlink("stat_nonexistent", "stat_dangling", 0);
+
+	cl_must_fail(p_stat("stat_nonexistent", &st));
+	cl_must_fail(p_stat("stat_dangling", &st));
+}
+
+void test_core_link__stat_dangling_symlink_directory(void)
+{
+	struct stat st;
+
+	if (!should_run())
+		clar__skip();
+
+	do_symlink("stat_nonexistent", "stat_dangling_dir", 1);
+
+	cl_must_fail(p_stat("stat_nonexistent_dir", &st));
+	cl_must_fail(p_stat("stat_dangling", &st));
+}
+
+void test_core_link__lstat_symlink(void)
+{
+	git_buf target_path = GIT_BUF_INIT;
+	struct stat st;
+
+	if (!should_run())
+		clar__skip();
+
+	/* Windows always writes the canonical path as the link target, so
+	 * write the full path on all platforms.
+	 */
+	git_buf_join(&target_path, '/', clar_sandbox_path(), "lstat_target");
+
+	cl_git_rewritefile("lstat_target", "This is the target of a symbolic link.\n");
+	do_symlink(git_buf_cstr(&target_path), "lstat_symlink", 0);
+
+	cl_must_pass(p_lstat("lstat_target", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert_equal_i(39, st.st_size);
+
+	cl_must_pass(p_lstat("lstat_symlink", &st));
+	cl_assert(S_ISLNK(st.st_mode));
+	cl_assert_equal_i(git_buf_len(&target_path), st.st_size);
+
+	git_buf_free(&target_path);
+}
+
+void test_core_link__lstat_symlink_directory(void)
+{
+	git_buf target_path = GIT_BUF_INIT;
+	struct stat st;
+
+	if (!should_run())
+		clar__skip();
+
+	git_buf_join(&target_path, '/', clar_sandbox_path(), "lstat_dirtarget");
+
+	p_mkdir("lstat_dirtarget", 0777);
+	do_symlink(git_buf_cstr(&target_path), "lstat_dirlink", 1);
+
+	cl_must_pass(p_lstat("lstat_dirtarget", &st));
+	cl_assert(S_ISDIR(st.st_mode));
+
+	cl_must_pass(p_lstat("lstat_dirlink", &st));
+	cl_assert(S_ISLNK(st.st_mode));
+	cl_assert_equal_i(git_buf_len(&target_path), st.st_size);
+
+	git_buf_free(&target_path);
+}
+
+void test_core_link__lstat_dangling_symlink(void)
+{
+	struct stat st;
+
+	if (!should_run())
+		clar__skip();
+
+	do_symlink("lstat_nonexistent", "lstat_dangling", 0);
+
+	cl_must_fail(p_lstat("lstat_nonexistent", &st));
+
+	cl_must_pass(p_lstat("lstat_dangling", &st));
+	cl_assert(S_ISLNK(st.st_mode));
+	cl_assert_equal_i(strlen("lstat_nonexistent"), st.st_size);
+}
+
+void test_core_link__lstat_dangling_symlink_directory(void)
+{
+	struct stat st;
+
+	if (!should_run())
+		clar__skip();
+
+	do_symlink("lstat_nonexistent", "lstat_dangling_dir", 1);
+
+	cl_must_fail(p_lstat("lstat_nonexistent", &st));
+
+	cl_must_pass(p_lstat("lstat_dangling_dir", &st));
+	cl_assert(S_ISLNK(st.st_mode));
+	cl_assert_equal_i(strlen("lstat_nonexistent"), st.st_size);
+}
+
+void test_core_link__stat_junction(void)
+{
+#ifdef GIT_WIN32
+	git_buf target_path = GIT_BUF_INIT;
+	struct stat st;
+
+	git_buf_join(&target_path, '/', clar_sandbox_path(), "stat_junctarget");
+
+	p_mkdir("stat_junctarget", 0777);
+	do_junction(git_buf_cstr(&target_path), "stat_junction");
+
+	cl_must_pass(p_stat("stat_junctarget", &st));
+	cl_assert(S_ISDIR(st.st_mode));
+
+	cl_must_pass(p_stat("stat_junction", &st));
+	cl_assert(S_ISDIR(st.st_mode));
+
+	git_buf_free(&target_path);
+#endif
+}
+
+void test_core_link__stat_dangling_junction(void)
+{
+#ifdef GIT_WIN32
+	git_buf target_path = GIT_BUF_INIT;
+	struct stat st;
+
+	git_buf_join(&target_path, '/', clar_sandbox_path(), "stat_nonexistent_junctarget");
+
+	p_mkdir("stat_nonexistent_junctarget", 0777);
+	do_junction(git_buf_cstr(&target_path), "stat_dangling_junction");
+
+	RemoveDirectory("stat_nonexistent_junctarget");
+
+	cl_must_fail(p_stat("stat_nonexistent_junctarget", &st));
+	cl_must_fail(p_stat("stat_dangling_junction", &st));
+
+	git_buf_free(&target_path);
+#endif
+}
+
+void test_core_link__lstat_junction(void)
+{
+#ifdef GIT_WIN32
+	git_buf target_path = GIT_BUF_INIT;
+	struct stat st;
+
+	git_buf_join(&target_path, '/', clar_sandbox_path(), "lstat_junctarget");
+
+	p_mkdir("lstat_junctarget", 0777);
+	do_junction(git_buf_cstr(&target_path), "lstat_junction");
+
+	cl_must_pass(p_lstat("lstat_junctarget", &st));
+	cl_assert(S_ISDIR(st.st_mode));
+
+	cl_must_pass(p_lstat("lstat_junction", &st));
+	cl_assert(S_ISLNK(st.st_mode));
+
+	git_buf_free(&target_path);
+#endif
+}
+
+void test_core_link__lstat_dangling_junction(void)
+{
+#ifdef GIT_WIN32
+	git_buf target_path = GIT_BUF_INIT;
+	struct stat st;
+
+	git_buf_join(&target_path, '/', clar_sandbox_path(), "lstat_nonexistent_junctarget");
+
+	p_mkdir("lstat_nonexistent_junctarget", 0777);
+	do_junction(git_buf_cstr(&target_path), "lstat_dangling_junction");
+
+	RemoveDirectory("lstat_nonexistent_junctarget");
+
+	cl_must_fail(p_lstat("lstat_nonexistent_junctarget", &st));
+
+	cl_must_pass(p_lstat("lstat_dangling_junction", &st));
+	cl_assert(S_ISLNK(st.st_mode));
+	cl_assert_equal_i(git_buf_len(&target_path), st.st_size);
+
+	git_buf_free(&target_path);
+#endif
+}
+
+void test_core_link__stat_hardlink(void)
+{
+	struct stat st;
+
+	if (!should_run())
+		clar__skip();
+
+	cl_git_rewritefile("stat_hardlink1", "This file has many names!\n");
+	do_hardlink("stat_hardlink1", "stat_hardlink2");
+
+	cl_must_pass(p_stat("stat_hardlink1", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert_equal_i(26, st.st_size);
+
+	cl_must_pass(p_stat("stat_hardlink2", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert_equal_i(26, st.st_size);
+}
+
+void test_core_link__lstat_hardlink(void)
+{
+	struct stat st;
+
+	if (!should_run())
+		clar__skip();
+
+	cl_git_rewritefile("lstat_hardlink1", "This file has many names!\n");
+	do_hardlink("lstat_hardlink1", "lstat_hardlink2");
+
+	cl_must_pass(p_lstat("lstat_hardlink1", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert_equal_i(26, st.st_size);
+
+	cl_must_pass(p_lstat("lstat_hardlink2", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert_equal_i(26, st.st_size);
+}
+
+void test_core_link__stat_reparse_point(void)
+{
+#ifdef GIT_WIN32
+	struct stat st;
+
+	/* Generic reparse points should be treated as regular files, only
+	 * symlinks and junctions should be treated as links.
+	 */
+
+	cl_git_rewritefile("stat_reparse", "This is a reparse point!\n");
+	do_custom_reparse("stat_reparse");
+
+	cl_must_pass(p_lstat("stat_reparse", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert_equal_i(25, st.st_size);
+#endif
+}
+
+void test_core_link__lstat_reparse_point(void)
+{
+#ifdef GIT_WIN32
+	struct stat st;
+
+	cl_git_rewritefile("lstat_reparse", "This is a reparse point!\n");
+	do_custom_reparse("lstat_reparse");
+
+	cl_must_pass(p_lstat("lstat_reparse", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert_equal_i(25, st.st_size);
+#endif
+}
+
+void test_core_link__readlink_nonexistent_file(void)
+{
+	char buf[2048];
+
+	cl_must_fail(p_readlink("readlink_nonexistent", buf, 2048));
+	cl_assert_equal_i(ENOENT, errno);
+}
+
+void test_core_link__readlink_normal_file(void)
+{
+	char buf[2048];
+
+	cl_git_rewritefile("readlink_regfile", "This is a regular file!\n");
+	cl_must_fail(p_readlink("readlink_regfile", buf, 2048));
+	cl_assert_equal_i(EINVAL, errno);
+}
+
+void test_core_link__readlink_symlink(void)
+{
+	git_buf target_path = GIT_BUF_INIT;
+	int len;
+	char buf[2048];
+
+	if (!should_run())
+		clar__skip();
+
+	git_buf_join(&target_path, '/', clar_sandbox_path(), "readlink_target");
+
+	cl_git_rewritefile("readlink_target", "This is the target of a symlink\n");
+	do_symlink(git_buf_cstr(&target_path), "readlink_link", 0);
+
+	len = p_readlink("readlink_link", buf, 2048);
+	cl_must_pass(len);
+
+	buf[len] = 0;
+
+	cl_assert_equal_s(git_buf_cstr(&target_path), buf);
+
+	git_buf_free(&target_path);
+}
+
+void test_core_link__readlink_dangling(void)
+{
+	git_buf target_path = GIT_BUF_INIT;
+	int len;
+	char buf[2048];
+
+	if (!should_run())
+		clar__skip();
+
+	git_buf_join(&target_path, '/', clar_sandbox_path(), "readlink_nonexistent");
+
+	do_symlink(git_buf_cstr(&target_path), "readlink_dangling", 0);
+
+	len = p_readlink("readlink_dangling", buf, 2048);
+	cl_must_pass(len);
+
+	buf[len] = 0;
+
+	cl_assert_equal_s(git_buf_cstr(&target_path), buf);
+
+	git_buf_free(&target_path);
+}
+
+void test_core_link__readlink_multiple(void)
+{
+	git_buf target_path = GIT_BUF_INIT,
+		path3 = GIT_BUF_INIT, path2 = GIT_BUF_INIT, path1 = GIT_BUF_INIT;
+	int len;
+	char buf[2048];
+
+	if (!should_run())
+		clar__skip();
+
+	git_buf_join(&target_path, '/', clar_sandbox_path(), "readlink_final");
+	git_buf_join(&path3, '/', clar_sandbox_path(), "readlink_3");
+	git_buf_join(&path2, '/', clar_sandbox_path(), "readlink_2");
+	git_buf_join(&path1, '/', clar_sandbox_path(), "readlink_1");
+
+	do_symlink(git_buf_cstr(&target_path), git_buf_cstr(&path3), 0);
+	do_symlink(git_buf_cstr(&path3), git_buf_cstr(&path2), 0);
+	do_symlink(git_buf_cstr(&path2), git_buf_cstr(&path1), 0);
+
+	len = p_readlink("readlink_1", buf, 2048);
+	cl_must_pass(len);
+
+	buf[len] = 0;
+
+	cl_assert_equal_s(git_buf_cstr(&path2), buf);
+
+	git_buf_free(&path1);
+	git_buf_free(&path2);
+	git_buf_free(&path3);
+	git_buf_free(&target_path);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/mkdir.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/mkdir.c
new file mode 100755
index 0000000..f76fe1d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/mkdir.c
@@ -0,0 +1,219 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "path.h"
+#include "posix.h"
+
+static void cleanup_basic_dirs(void *ref)
+{
+	GIT_UNUSED(ref);
+	git_futils_rmdir_r("d0", NULL, GIT_RMDIR_EMPTY_HIERARCHY);
+	git_futils_rmdir_r("d1", NULL, GIT_RMDIR_EMPTY_HIERARCHY);
+	git_futils_rmdir_r("d2", NULL, GIT_RMDIR_EMPTY_HIERARCHY);
+	git_futils_rmdir_r("d3", NULL, GIT_RMDIR_EMPTY_HIERARCHY);
+	git_futils_rmdir_r("d4", NULL, GIT_RMDIR_EMPTY_HIERARCHY);
+}
+
+void test_core_mkdir__basic(void)
+{
+	cl_set_cleanup(cleanup_basic_dirs, NULL);
+
+	/* make a directory */
+	cl_assert(!git_path_isdir("d0"));
+	cl_git_pass(git_futils_mkdir("d0", NULL, 0755, 0));
+	cl_assert(git_path_isdir("d0"));
+
+	/* make a path */
+	cl_assert(!git_path_isdir("d1"));
+	cl_git_pass(git_futils_mkdir("d1/d1.1/d1.2", NULL, 0755, GIT_MKDIR_PATH));
+	cl_assert(git_path_isdir("d1"));
+	cl_assert(git_path_isdir("d1/d1.1"));
+	cl_assert(git_path_isdir("d1/d1.1/d1.2"));
+
+	/* make a dir exclusively */
+	cl_assert(!git_path_isdir("d2"));
+	cl_git_pass(git_futils_mkdir("d2", NULL, 0755, GIT_MKDIR_EXCL));
+	cl_assert(git_path_isdir("d2"));
+
+	/* make exclusive failure */
+	cl_git_fail(git_futils_mkdir("d2", NULL, 0755, GIT_MKDIR_EXCL));
+
+	/* make a path exclusively */
+	cl_assert(!git_path_isdir("d3"));
+	cl_git_pass(git_futils_mkdir("d3/d3.1/d3.2", NULL, 0755, GIT_MKDIR_PATH | GIT_MKDIR_EXCL));
+	cl_assert(git_path_isdir("d3"));
+	cl_assert(git_path_isdir("d3/d3.1/d3.2"));
+
+	/* make exclusive path failure */
+	cl_git_fail(git_futils_mkdir("d3/d3.1/d3.2", NULL, 0755, GIT_MKDIR_PATH | GIT_MKDIR_EXCL));
+	/* ??? Should EXCL only apply to the last item in the path? */
+
+	/* path with trailing slash? */
+	cl_assert(!git_path_isdir("d4"));
+	cl_git_pass(git_futils_mkdir("d4/d4.1/", NULL, 0755, GIT_MKDIR_PATH));
+	cl_assert(git_path_isdir("d4/d4.1"));
+}
+
+static void cleanup_basedir(void *ref)
+{
+	GIT_UNUSED(ref);
+	git_futils_rmdir_r("base", NULL, GIT_RMDIR_EMPTY_HIERARCHY);
+}
+
+void test_core_mkdir__with_base(void)
+{
+#define BASEDIR "base/dir/here"
+
+	cl_set_cleanup(cleanup_basedir, NULL);
+
+	cl_git_pass(git_futils_mkdir(BASEDIR, NULL, 0755, GIT_MKDIR_PATH));
+
+	cl_git_pass(git_futils_mkdir("a", BASEDIR, 0755, 0));
+	cl_assert(git_path_isdir(BASEDIR "/a"));
+
+	cl_git_pass(git_futils_mkdir("b/b1/b2", BASEDIR, 0755, GIT_MKDIR_PATH));
+	cl_assert(git_path_isdir(BASEDIR "/b/b1/b2"));
+
+	/* exclusive with existing base */
+	cl_git_pass(git_futils_mkdir("c/c1/c2", BASEDIR, 0755, GIT_MKDIR_PATH | GIT_MKDIR_EXCL));
+
+	/* fail: exclusive with duplicated suffix */
+	cl_git_fail(git_futils_mkdir("c/c1/c3", BASEDIR, 0755, GIT_MKDIR_PATH | GIT_MKDIR_EXCL));
+
+	/* fail: exclusive with any duplicated component */
+	cl_git_fail(git_futils_mkdir("c/cz/cz", BASEDIR, 0755, GIT_MKDIR_PATH | GIT_MKDIR_EXCL));
+
+	/* success: exclusive without path */
+	cl_git_pass(git_futils_mkdir("c/c1/c3", BASEDIR, 0755, GIT_MKDIR_EXCL));
+
+	/* path with shorter base and existing dirs */
+	cl_git_pass(git_futils_mkdir("dir/here/d/", "base", 0755, GIT_MKDIR_PATH));
+	cl_assert(git_path_isdir("base/dir/here/d"));
+
+	/* fail: path with shorter base and existing dirs */
+	cl_git_fail(git_futils_mkdir("dir/here/e/", "base", 0755, GIT_MKDIR_PATH | GIT_MKDIR_EXCL));
+
+	/* fail: base with missing components */
+	cl_git_fail(git_futils_mkdir("f/", "base/missing", 0755, GIT_MKDIR_PATH));
+
+	/* success: shift missing component to path */
+	cl_git_pass(git_futils_mkdir("missing/f/", "base/", 0755, GIT_MKDIR_PATH));
+}
+
+static void cleanup_chmod_root(void *ref)
+{
+	mode_t *mode = ref;
+
+	if (mode != NULL) {
+		(void)p_umask(*mode);
+		git__free(mode);
+	}
+
+	git_futils_rmdir_r("r", NULL, GIT_RMDIR_EMPTY_HIERARCHY);
+}
+
+#define check_mode(X,A) check_mode_at_line((X), (A), __FILE__, __LINE__)
+
+static void check_mode_at_line(
+	mode_t expected, mode_t actual, const char *file, int line)
+{
+	/* FAT filesystems don't support exec bit, nor group/world bits */
+	if (!cl_is_chmod_supported()) {
+		expected &= 0600;
+		actual &= 0600;
+	}
+
+	clar__assert_equal(
+		file, line, "expected_mode != actual_mode", 1,
+		"%07o", (int)expected, (int)(actual & 0777));
+}
+
+void test_core_mkdir__chmods(void)
+{
+	struct stat st;
+	mode_t *old = git__malloc(sizeof(mode_t));
+	*old = p_umask(022);
+
+	cl_set_cleanup(cleanup_chmod_root, old);
+
+	cl_git_pass(git_futils_mkdir("r", NULL, 0777, 0));
+
+	cl_git_pass(git_futils_mkdir("mode/is/important", "r", 0777, GIT_MKDIR_PATH));
+
+	cl_git_pass(git_path_lstat("r/mode", &st));
+	check_mode(0755, st.st_mode);
+	cl_git_pass(git_path_lstat("r/mode/is", &st));
+	check_mode(0755, st.st_mode);
+	cl_git_pass(git_path_lstat("r/mode/is/important", &st));
+	check_mode(0755, st.st_mode);
+
+	cl_git_pass(git_futils_mkdir("mode2/is2/important2", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD));
+
+	cl_git_pass(git_path_lstat("r/mode2", &st));
+	check_mode(0755, st.st_mode);
+	cl_git_pass(git_path_lstat("r/mode2/is2", &st));
+	check_mode(0755, st.st_mode);
+	cl_git_pass(git_path_lstat("r/mode2/is2/important2", &st));
+	check_mode(0777, st.st_mode);
+
+	cl_git_pass(git_futils_mkdir("mode3/is3/important3", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD_PATH));
+
+	cl_git_pass(git_path_lstat("r/mode3", &st));
+	check_mode(0777, st.st_mode);
+	cl_git_pass(git_path_lstat("r/mode3/is3", &st));
+	check_mode(0777, st.st_mode);
+	cl_git_pass(git_path_lstat("r/mode3/is3/important3", &st));
+	check_mode(0777, st.st_mode);
+
+	/* test that we chmod existing dir */
+
+	cl_git_pass(git_futils_mkdir("mode/is/important", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD));
+
+	cl_git_pass(git_path_lstat("r/mode", &st));
+	check_mode(0755, st.st_mode);
+	cl_git_pass(git_path_lstat("r/mode/is", &st));
+	check_mode(0755, st.st_mode);
+	cl_git_pass(git_path_lstat("r/mode/is/important", &st));
+	check_mode(0777, st.st_mode);
+
+	/* test that we chmod even existing dirs if CHMOD_PATH is set */
+
+	cl_git_pass(git_futils_mkdir("mode2/is2/important2.1", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD_PATH));
+
+	cl_git_pass(git_path_lstat("r/mode2", &st));
+	check_mode(0777, st.st_mode);
+	cl_git_pass(git_path_lstat("r/mode2/is2", &st));
+	check_mode(0777, st.st_mode);
+	cl_git_pass(git_path_lstat("r/mode2/is2/important2.1", &st));
+	check_mode(0777, st.st_mode);
+}
+
+void test_core_mkdir__mkdir_path_inside_unwriteable_parent(void)
+{
+	struct stat st;
+	mode_t *old;
+
+	/* FAT filesystems don't support exec bit, nor group/world bits */
+	if (!cl_is_chmod_supported())
+		return;
+
+	cl_assert((old = git__malloc(sizeof(mode_t))) != NULL);
+	*old = p_umask(022);
+	cl_set_cleanup(cleanup_chmod_root, old);
+
+	cl_git_pass(git_futils_mkdir("r", NULL, 0777, 0));
+	cl_git_pass(git_futils_mkdir("mode/is/important", "r", 0777, GIT_MKDIR_PATH));
+	cl_git_pass(git_path_lstat("r/mode", &st));
+	check_mode(0755, st.st_mode);
+
+	cl_must_pass(p_chmod("r/mode", 0111));
+	cl_git_pass(git_path_lstat("r/mode", &st));
+	check_mode(0111, st.st_mode);
+
+	cl_git_pass(
+		git_futils_mkdir("mode/is/okay/inside", "r", 0777, GIT_MKDIR_PATH));
+	cl_git_pass(git_path_lstat("r/mode/is/okay/inside", &st));
+	check_mode(0755, st.st_mode);
+
+	cl_must_pass(p_chmod("r/mode", 0777));
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/oid.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/oid.c
new file mode 100755
index 0000000..7ee6fb6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/oid.c
@@ -0,0 +1,70 @@
+#include "clar_libgit2.h"
+
+static git_oid id;
+static git_oid idp;
+static git_oid idm;
+const char *str_oid = "ae90f12eea699729ed24555e40b9fd669da12a12";
+const char *str_oid_p = "ae90f12eea699729ed";
+const char *str_oid_m = "ae90f12eea699729ed24555e40b9fd669da12a12THIS IS EXTRA TEXT THAT SHOULD GET IGNORED";
+
+void test_core_oid__initialize(void)
+{
+	cl_git_pass(git_oid_fromstr(&id, str_oid));
+	cl_git_pass(git_oid_fromstrp(&idp, str_oid_p));
+	cl_git_fail(git_oid_fromstrp(&idm, str_oid_m));
+}
+
+void test_core_oid__streq(void)
+{
+	cl_assert_equal_i(0, git_oid_streq(&id, str_oid));
+	cl_assert_equal_i(-1, git_oid_streq(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
+
+	cl_assert_equal_i(-1, git_oid_streq(&id, "deadbeef"));
+	cl_assert_equal_i(-1, git_oid_streq(&id, "I'm not an oid.... :)"));
+
+	cl_assert_equal_i(0, git_oid_streq(&idp, "ae90f12eea699729ed0000000000000000000000"));
+	cl_assert_equal_i(0, git_oid_streq(&idp, "ae90f12eea699729ed"));
+	cl_assert_equal_i(-1, git_oid_streq(&idp, "ae90f12eea699729ed1"));
+	cl_assert_equal_i(-1, git_oid_streq(&idp, "ae90f12eea699729ec"));
+	cl_assert_equal_i(-1, git_oid_streq(&idp, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
+
+	cl_assert_equal_i(-1, git_oid_streq(&idp, "deadbeef"));
+	cl_assert_equal_i(-1, git_oid_streq(&idp, "I'm not an oid.... :)"));
+}
+
+void test_core_oid__strcmp(void)
+{
+	cl_assert_equal_i(0, git_oid_strcmp(&id, str_oid));
+	cl_assert(git_oid_strcmp(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") < 0);
+
+	cl_assert(git_oid_strcmp(&id, "deadbeef") < 0);
+	cl_assert_equal_i(-1, git_oid_strcmp(&id, "I'm not an oid.... :)"));
+
+	cl_assert_equal_i(0, git_oid_strcmp(&idp, "ae90f12eea699729ed0000000000000000000000"));
+	cl_assert_equal_i(0, git_oid_strcmp(&idp, "ae90f12eea699729ed"));
+	cl_assert(git_oid_strcmp(&idp, "ae90f12eea699729ed1") < 0);
+	cl_assert(git_oid_strcmp(&idp, "ae90f12eea699729ec") > 0);
+	cl_assert(git_oid_strcmp(&idp, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") < 0);
+
+	cl_assert(git_oid_strcmp(&idp, "deadbeef") < 0);
+	cl_assert_equal_i(-1, git_oid_strcmp(&idp, "I'm not an oid.... :)"));
+}
+
+void test_core_oid__ncmp(void)
+{
+	cl_assert(!git_oid_ncmp(&id, &idp, 0));
+	cl_assert(!git_oid_ncmp(&id, &idp, 1));
+	cl_assert(!git_oid_ncmp(&id, &idp, 2));
+	cl_assert(!git_oid_ncmp(&id, &idp, 17));
+	cl_assert(!git_oid_ncmp(&id, &idp, 18));
+	cl_assert(git_oid_ncmp(&id, &idp, 19));
+	cl_assert(git_oid_ncmp(&id, &idp, 40));
+	cl_assert(git_oid_ncmp(&id, &idp, 41));
+	cl_assert(git_oid_ncmp(&id, &idp, 42));
+
+	cl_assert(!git_oid_ncmp(&id, &id, 0));
+	cl_assert(!git_oid_ncmp(&id, &id, 1));
+	cl_assert(!git_oid_ncmp(&id, &id, 39));
+	cl_assert(!git_oid_ncmp(&id, &id, 40));
+	cl_assert(!git_oid_ncmp(&id, &id, 41));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/oidmap.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/oidmap.c
new file mode 100755
index 0000000..556a6ca
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/oidmap.c
@@ -0,0 +1,110 @@
+#include "clar_libgit2.h"
+#include "oidmap.h"
+
+GIT__USE_OIDMAP
+
+typedef struct {
+	git_oid oid;
+	size_t extra;
+} oidmap_item;
+
+#define NITEMS 0x0fff
+
+void test_core_oidmap__basic(void)
+{
+	git_oidmap *map;
+	oidmap_item items[NITEMS];
+	uint32_t i, j;
+
+	for (i = 0; i < NITEMS; ++i) {
+		items[i].extra = i;
+		for (j = 0; j < GIT_OID_RAWSZ / 4; ++j) {
+			items[i].oid.id[j * 4    ] = (unsigned char)i;
+			items[i].oid.id[j * 4 + 1] = (unsigned char)(i >> 8);
+			items[i].oid.id[j * 4 + 2] = (unsigned char)(i >> 16);
+			items[i].oid.id[j * 4 + 3] = (unsigned char)(i >> 24);
+		}
+	}
+
+	map = git_oidmap_alloc();
+	cl_assert(map != NULL);
+
+	for (i = 0; i < NITEMS; ++i) {
+		khiter_t pos;
+		int ret;
+
+		pos = kh_get(oid, map, &items[i].oid);
+		cl_assert(pos == kh_end(map));
+
+		pos = kh_put(oid, map, &items[i].oid, &ret);
+		cl_assert(ret != 0);
+
+		kh_val(map, pos) = &items[i];
+	}
+
+
+	for (i = 0; i < NITEMS; ++i) {
+		khiter_t pos;
+
+		pos = kh_get(oid, map, &items[i].oid);
+		cl_assert(pos != kh_end(map));
+
+		cl_assert_equal_p(kh_val(map, pos), &items[i]);
+	}
+
+	git_oidmap_free(map);
+}
+
+void test_core_oidmap__hash_collision(void)
+{
+	git_oidmap *map;
+	oidmap_item items[NITEMS];
+	uint32_t i, j;
+
+	for (i = 0; i < NITEMS; ++i) {
+		uint32_t segment = i / 8;
+		int modi = i - (segment * 8);
+
+		items[i].extra = i;
+
+		for (j = 0; j < GIT_OID_RAWSZ / 4; ++j) {
+			items[i].oid.id[j * 4    ] = (unsigned char)modi;
+			items[i].oid.id[j * 4 + 1] = (unsigned char)(modi >> 8);
+			items[i].oid.id[j * 4 + 2] = (unsigned char)(modi >> 16);
+			items[i].oid.id[j * 4 + 3] = (unsigned char)(modi >> 24);
+		}
+
+		items[i].oid.id[ 8] = (unsigned char)i;
+		items[i].oid.id[ 9] = (unsigned char)(i >> 8);
+		items[i].oid.id[10] = (unsigned char)(i >> 16);
+		items[i].oid.id[11] = (unsigned char)(i >> 24);
+	}
+
+	map = git_oidmap_alloc();
+	cl_assert(map != NULL);
+
+	for (i = 0; i < NITEMS; ++i) {
+		khiter_t pos;
+		int ret;
+
+		pos = kh_get(oid, map, &items[i].oid);
+		cl_assert(pos == kh_end(map));
+
+		pos = kh_put(oid, map, &items[i].oid, &ret);
+		cl_assert(ret != 0);
+
+		kh_val(map, pos) = &items[i];
+	}
+
+
+	for (i = 0; i < NITEMS; ++i) {
+		khiter_t pos;
+
+		pos = kh_get(oid, map, &items[i].oid);
+		cl_assert(pos != kh_end(map));
+
+		cl_assert_equal_p(kh_val(map, pos), &items[i]);
+	}
+
+	git_oidmap_free(map);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/opts.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/opts.c
new file mode 100755
index 0000000..3173c64
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/opts.c
@@ -0,0 +1,19 @@
+#include "clar_libgit2.h"
+#include "cache.h"
+
+void test_core_opts__readwrite(void)
+{
+	size_t old_val = 0;
+	size_t new_val = 0;
+
+	git_libgit2_opts(GIT_OPT_GET_MWINDOW_SIZE, &old_val);
+	git_libgit2_opts(GIT_OPT_SET_MWINDOW_SIZE, (size_t)1234);
+	git_libgit2_opts(GIT_OPT_GET_MWINDOW_SIZE, &new_val);
+
+	cl_assert(new_val == 1234);
+
+	git_libgit2_opts(GIT_OPT_SET_MWINDOW_SIZE, old_val);
+	git_libgit2_opts(GIT_OPT_GET_MWINDOW_SIZE, &new_val);
+
+	cl_assert(new_val == old_val);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/path.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/path.c
new file mode 100755
index 0000000..c3e622f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/path.c
@@ -0,0 +1,654 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+
+static void
+check_dirname(const char *A, const char *B)
+{
+	git_buf dir = GIT_BUF_INIT;
+	char *dir2;
+
+	cl_assert(git_path_dirname_r(&dir, A) >= 0);
+	cl_assert_equal_s(B, dir.ptr);
+	git_buf_free(&dir);
+
+	cl_assert((dir2 = git_path_dirname(A)) != NULL);
+	cl_assert_equal_s(B, dir2);
+	git__free(dir2);
+}
+
+static void
+check_basename(const char *A, const char *B)
+{
+	git_buf base = GIT_BUF_INIT;
+	char *base2;
+
+	cl_assert(git_path_basename_r(&base, A) >= 0);
+	cl_assert_equal_s(B, base.ptr);
+	git_buf_free(&base);
+
+	cl_assert((base2 = git_path_basename(A)) != NULL);
+	cl_assert_equal_s(B, base2);
+	git__free(base2);
+}
+
+static void
+check_topdir(const char *A, const char *B)
+{
+	const char *dir;
+
+	cl_assert((dir = git_path_topdir(A)) != NULL);
+	cl_assert_equal_s(B, dir);
+}
+
+static void
+check_joinpath(const char *path_a, const char *path_b, const char *expected_path)
+{
+	git_buf joined_path = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_joinpath(&joined_path, path_a, path_b));
+	cl_assert_equal_s(expected_path, joined_path.ptr);
+
+	git_buf_free(&joined_path);
+}
+
+static void
+check_joinpath_n(
+	const char *path_a,
+	const char *path_b,
+	const char *path_c,
+	const char *path_d,
+	const char *expected_path)
+{
+	git_buf joined_path = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_join_n(&joined_path, '/', 4,
+							   path_a, path_b, path_c, path_d));
+	cl_assert_equal_s(expected_path, joined_path.ptr);
+
+	git_buf_free(&joined_path);
+}
+
+
+/* get the dirname of a path */
+void test_core_path__00_dirname(void)
+{
+	check_dirname(NULL, ".");
+	check_dirname("", ".");
+	check_dirname("a", ".");
+	check_dirname("/", "/");
+	check_dirname("/usr", "/");
+	check_dirname("/usr/", "/");
+	check_dirname("/usr/lib", "/usr");
+	check_dirname("/usr/lib/", "/usr");
+	check_dirname("/usr/lib//", "/usr");
+	check_dirname("usr/lib", "usr");
+	check_dirname("usr/lib/", "usr");
+	check_dirname("usr/lib//", "usr");
+	check_dirname(".git/", ".");
+
+	check_dirname(REP16("/abc"), REP15("/abc"));
+
+#ifdef GIT_WIN32
+	check_dirname("C:/path/", "C:/");
+	check_dirname("C:/path", "C:/");
+	check_dirname("//computername/path/", "//computername/");
+	check_dirname("//computername/path", "//computername/");
+	check_dirname("//computername/sub/path/", "//computername/sub");
+	check_dirname("//computername/sub/path", "//computername/sub");
+#endif
+}
+
+/* get the base name of a path */
+void test_core_path__01_basename(void)
+{
+	check_basename(NULL, ".");
+	check_basename("", ".");
+	check_basename("a", "a");
+	check_basename("/", "/");
+	check_basename("/usr", "usr");
+	check_basename("/usr/", "usr");
+	check_basename("/usr/lib", "lib");
+	check_basename("/usr/lib//", "lib");
+	check_basename("usr/lib", "lib");
+
+	check_basename(REP16("/abc"), "abc");
+	check_basename(REP1024("/abc"), "abc");
+}
+
+/* get the latest component in a path */
+void test_core_path__02_topdir(void)
+{
+	check_topdir(".git/", ".git/");
+	check_topdir("/.git/", ".git/");
+	check_topdir("usr/local/.git/", ".git/");
+	check_topdir("./.git/", ".git/");
+	check_topdir("/usr/.git/", ".git/");
+	check_topdir("/", "/");
+	check_topdir("a/", "a/");
+
+	cl_assert(git_path_topdir("/usr/.git") == NULL);
+	cl_assert(git_path_topdir(".") == NULL);
+	cl_assert(git_path_topdir("") == NULL);
+	cl_assert(git_path_topdir("a") == NULL);
+}
+
+/* properly join path components */
+void test_core_path__05_joins(void)
+{
+	check_joinpath("", "", "");
+	check_joinpath("", "a", "a");
+	check_joinpath("", "/a", "/a");
+	check_joinpath("a", "", "a/");
+	check_joinpath("a", "/", "a/");
+	check_joinpath("a", "b", "a/b");
+	check_joinpath("/", "a", "/a");
+	check_joinpath("/", "", "/");
+	check_joinpath("/a", "/b", "/a/b");
+	check_joinpath("/a", "/b/", "/a/b/");
+	check_joinpath("/a/", "b/", "/a/b/");
+	check_joinpath("/a/", "/b/", "/a/b/");
+
+	check_joinpath("/abcd", "/defg", "/abcd/defg");
+	check_joinpath("/abcd", "/defg/", "/abcd/defg/");
+	check_joinpath("/abcd/", "defg/", "/abcd/defg/");
+	check_joinpath("/abcd/", "/defg/", "/abcd/defg/");
+
+	check_joinpath("/abcdefgh", "/12345678", "/abcdefgh/12345678");
+	check_joinpath("/abcdefgh", "/12345678/", "/abcdefgh/12345678/");
+	check_joinpath("/abcdefgh/", "12345678/", "/abcdefgh/12345678/");
+
+	check_joinpath(REP1024("aaaa"), "", REP1024("aaaa") "/");
+	check_joinpath(REP1024("aaaa/"), "", REP1024("aaaa/"));
+	check_joinpath(REP1024("/aaaa"), "", REP1024("/aaaa") "/");
+
+	check_joinpath(REP1024("aaaa"), REP1024("bbbb"),
+				   REP1024("aaaa") "/" REP1024("bbbb"));
+	check_joinpath(REP1024("/aaaa"), REP1024("/bbbb"),
+				   REP1024("/aaaa") REP1024("/bbbb"));
+}
+
+/* properly join path components for more than one path */
+void test_core_path__06_long_joins(void)
+{
+	check_joinpath_n("", "", "", "", "");
+	check_joinpath_n("", "a", "", "", "a/");
+	check_joinpath_n("a", "", "", "", "a/");
+	check_joinpath_n("", "", "", "a", "a");
+	check_joinpath_n("a", "b", "", "/c/d/", "a/b/c/d/");
+	check_joinpath_n("a", "b", "", "/c/d", "a/b/c/d");
+	check_joinpath_n("abcd", "efgh", "ijkl", "mnop", "abcd/efgh/ijkl/mnop");
+	check_joinpath_n("abcd/", "efgh/", "ijkl/", "mnop/", "abcd/efgh/ijkl/mnop/");
+	check_joinpath_n("/abcd/", "/efgh/", "/ijkl/", "/mnop/", "/abcd/efgh/ijkl/mnop/");
+
+	check_joinpath_n(REP1024("a"), REP1024("b"), REP1024("c"), REP1024("d"),
+					 REP1024("a") "/" REP1024("b") "/"
+					 REP1024("c") "/" REP1024("d"));
+	check_joinpath_n(REP1024("/a"), REP1024("/b"), REP1024("/c"), REP1024("/d"),
+					 REP1024("/a") REP1024("/b")
+					 REP1024("/c") REP1024("/d"));
+}
+
+
+static void
+check_path_to_dir(
+	const char* path,
+    const char* expected)
+{
+	git_buf tgt = GIT_BUF_INIT;
+
+	git_buf_sets(&tgt, path);
+	cl_git_pass(git_path_to_dir(&tgt));
+	cl_assert_equal_s(expected, tgt.ptr);
+
+	git_buf_free(&tgt);
+}
+
+static void
+check_string_to_dir(
+	const char* path,
+	size_t      maxlen,
+    const char* expected)
+{
+	size_t len = strlen(path);
+	char *buf = git__malloc(len + 2);
+	cl_assert(buf);
+
+	strncpy(buf, path, len + 2);
+
+	git_path_string_to_dir(buf, maxlen);
+
+	cl_assert_equal_s(expected, buf);
+
+	git__free(buf);
+}
+
+/* convert paths to dirs */
+void test_core_path__07_path_to_dir(void)
+{
+	check_path_to_dir("", "");
+	check_path_to_dir(".", "./");
+	check_path_to_dir("./", "./");
+	check_path_to_dir("a/", "a/");
+	check_path_to_dir("ab", "ab/");
+	/* make sure we try just under and just over an expansion that will
+	 * require a realloc
+	 */
+	check_path_to_dir("abcdef", "abcdef/");
+	check_path_to_dir("abcdefg", "abcdefg/");
+	check_path_to_dir("abcdefgh", "abcdefgh/");
+	check_path_to_dir("abcdefghi", "abcdefghi/");
+	check_path_to_dir(REP1024("abcd") "/", REP1024("abcd") "/");
+	check_path_to_dir(REP1024("abcd"), REP1024("abcd") "/");
+
+	check_string_to_dir("", 1, "");
+	check_string_to_dir(".", 1, ".");
+	check_string_to_dir(".", 2, "./");
+	check_string_to_dir(".", 3, "./");
+	check_string_to_dir("abcd", 3, "abcd");
+	check_string_to_dir("abcd", 4, "abcd");
+	check_string_to_dir("abcd", 5, "abcd/");
+	check_string_to_dir("abcd", 6, "abcd/");
+}
+
+/* join path to itself */
+void test_core_path__08_self_join(void)
+{
+	git_buf path = GIT_BUF_INIT;
+	size_t asize = 0;
+
+	asize = path.asize;
+	cl_git_pass(git_buf_sets(&path, "/foo"));
+	cl_assert_equal_s(path.ptr, "/foo");
+	cl_assert(asize < path.asize);
+
+	asize = path.asize;
+	cl_git_pass(git_buf_joinpath(&path, path.ptr, "this is a new string"));
+	cl_assert_equal_s(path.ptr, "/foo/this is a new string");
+	cl_assert(asize < path.asize);
+
+	asize = path.asize;
+	cl_git_pass(git_buf_joinpath(&path, path.ptr, "/grow the buffer, grow the buffer, grow the buffer"));
+	cl_assert_equal_s(path.ptr, "/foo/this is a new string/grow the buffer, grow the buffer, grow the buffer");
+	cl_assert(asize < path.asize);
+
+	git_buf_free(&path);
+	cl_git_pass(git_buf_sets(&path, "/foo/bar"));
+
+	cl_git_pass(git_buf_joinpath(&path, path.ptr + 4, "baz"));
+	cl_assert_equal_s(path.ptr, "/bar/baz");
+
+	asize = path.asize;
+	cl_git_pass(git_buf_joinpath(&path, path.ptr + 4, "somethinglongenoughtorealloc"));
+	cl_assert_equal_s(path.ptr, "/baz/somethinglongenoughtorealloc");
+	cl_assert(asize < path.asize);
+	
+	git_buf_free(&path);
+}
+
+static void check_percent_decoding(const char *expected_result, const char *input)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git__percent_decode(&buf, input));
+	cl_assert_equal_s(expected_result, git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+}
+
+void test_core_path__09_percent_decode(void)
+{
+	check_percent_decoding("abcd", "abcd");
+	check_percent_decoding("a2%", "a2%");
+	check_percent_decoding("a2%3", "a2%3");
+	check_percent_decoding("a2%%3", "a2%%3");
+	check_percent_decoding("a2%3z", "a2%3z");
+	check_percent_decoding("a,", "a%2c");
+	check_percent_decoding("a21", "a2%31");
+	check_percent_decoding("a2%1", "a2%%31");
+	check_percent_decoding("a bc ", "a%20bc%20");
+	check_percent_decoding("Vicent Mart" "\355", "Vicent%20Mart%ED");
+}
+
+static void check_fromurl(const char *expected_result, const char *input, int should_fail)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	assert(should_fail || expected_result);
+
+	if (!should_fail) {
+		cl_git_pass(git_path_fromurl(&buf, input));
+		cl_assert_equal_s(expected_result, git_buf_cstr(&buf));
+	} else
+		cl_git_fail(git_path_fromurl(&buf, input));
+
+	git_buf_free(&buf);
+}
+
+#ifdef GIT_WIN32
+#define ABS_PATH_MARKER ""
+#else
+#define ABS_PATH_MARKER "/"
+#endif
+
+void test_core_path__10_fromurl(void)
+{
+	/* Failing cases */
+	check_fromurl(NULL, "a", 1);
+	check_fromurl(NULL, "http:///c:/Temp%20folder/note.txt", 1);
+	check_fromurl(NULL, "file://c:/Temp%20folder/note.txt", 1);
+	check_fromurl(NULL, "file:////c:/Temp%20folder/note.txt", 1);
+	check_fromurl(NULL, "file:///", 1);
+	check_fromurl(NULL, "file:////", 1);
+	check_fromurl(NULL, "file://servername/c:/Temp%20folder/note.txt", 1);
+
+	/* Passing cases */
+	check_fromurl(ABS_PATH_MARKER "c:/Temp folder/note.txt", "file:///c:/Temp%20folder/note.txt", 0);
+	check_fromurl(ABS_PATH_MARKER "c:/Temp folder/note.txt", "file://localhost/c:/Temp%20folder/note.txt", 0);
+	check_fromurl(ABS_PATH_MARKER "c:/Temp+folder/note.txt", "file:///c:/Temp+folder/note.txt", 0);
+	check_fromurl(ABS_PATH_MARKER "a", "file:///a", 0);
+}
+
+typedef struct {
+	int expect_idx;
+	int cancel_after;
+	char **expect;
+} check_walkup_info;
+
+#define CANCEL_VALUE 1234
+
+static int check_one_walkup_step(void *ref, const char *path)
+{
+	check_walkup_info *info = (check_walkup_info *)ref;
+
+	if (!info->cancel_after) {
+		cl_assert_equal_s(info->expect[info->expect_idx], "[CANCEL]");
+		return CANCEL_VALUE;
+	}
+	info->cancel_after--;
+
+	cl_assert(info->expect[info->expect_idx] != NULL);
+	cl_assert_equal_s(info->expect[info->expect_idx], path);
+	info->expect_idx++;
+
+	return 0;
+}
+
+void test_core_path__11_walkup(void)
+{
+	git_buf p = GIT_BUF_INIT;
+
+	char *expect[] = {
+		/*  1 */ "/a/b/c/d/e/", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
+		/*  2 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
+		/*  3 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
+		/*  4 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
+		/*  5 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", NULL,
+		/*  6 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", NULL,
+		/*  7 */ "this_is_a_path", "", NULL,
+		/*  8 */ "this_is_a_path/", "", NULL,
+		/*  9 */ "///a///b///c///d///e///", "///a///b///c///d///", "///a///b///c///", "///a///b///", "///a///", "///", NULL,
+		/* 10 */ "a/b/c/", "a/b/", "a/", "", NULL,
+		/* 11 */ "a/b/c", "a/b/", "a/", "", NULL,
+		/* 12 */ "a/b/c/", "a/b/", "a/", NULL,
+		/* 13 */ "", NULL,
+		/* 14 */ "/", NULL,
+		/* 15 */ NULL
+	};
+
+	char *root[] = {
+		/*  1 */ NULL,
+		/*  2 */ NULL,
+		/*  3 */ "/",
+		/*  4 */ "",
+		/*  5 */ "/a/b",
+		/*  6 */ "/a/b/",
+		/*  7 */ NULL,
+		/*  8 */ NULL,
+		/*  9 */ NULL,
+		/* 10 */ NULL,
+		/* 11 */ NULL,
+		/* 12 */ "a/",
+		/* 13 */ NULL,
+		/* 14 */ NULL,
+	};
+
+	int i, j;
+	check_walkup_info info;
+
+	info.expect = expect;
+	info.cancel_after = -1;
+
+	for (i = 0, j = 0; expect[i] != NULL; i++, j++) {
+
+		git_buf_sets(&p, expect[i]);
+
+		info.expect_idx = i;
+		cl_git_pass(
+			git_path_walk_up(&p, root[j], check_one_walkup_step, &info)
+		);
+
+		cl_assert_equal_s(p.ptr, expect[i]);
+		cl_assert(expect[info.expect_idx] == NULL);
+		i = info.expect_idx;
+	}
+
+	git_buf_free(&p);
+}
+
+void test_core_path__11a_walkup_cancel(void)
+{
+	git_buf p = GIT_BUF_INIT;
+	int cancel[] = { 3, 2, 1, 0 };
+	char *expect[] = {
+		"/a/b/c/d/e/", "/a/b/c/d/", "/a/b/c/", "[CANCEL]", NULL,
+		"/a/b/c/d/e", "/a/b/c/d/", "[CANCEL]", NULL,
+		"/a/b/c/d/e", "[CANCEL]", NULL,
+		"[CANCEL]", NULL,
+		NULL
+	};
+	char *root[] = { NULL, NULL, "/", "", NULL };
+	int i, j;
+	check_walkup_info info;
+
+	info.expect = expect;
+
+	for (i = 0, j = 0; expect[i] != NULL; i++, j++) {
+
+		git_buf_sets(&p, expect[i]);
+
+		info.cancel_after = cancel[j];
+		info.expect_idx = i;
+
+		cl_assert_equal_i(
+			CANCEL_VALUE,
+			git_path_walk_up(&p, root[j], check_one_walkup_step, &info)
+		);
+
+		/* skip to next run of expectations */
+		while (expect[i] != NULL) i++;
+	}
+
+	git_buf_free(&p);
+}
+
+void test_core_path__12_offset_to_path_root(void)
+{
+	cl_assert(git_path_root("non/rooted/path") == -1);
+	cl_assert(git_path_root("/rooted/path") == 0);
+
+#ifdef GIT_WIN32
+	/* Windows specific tests */
+	cl_assert(git_path_root("C:non/rooted/path") == -1);
+	cl_assert(git_path_root("C:/rooted/path") == 2);
+	cl_assert(git_path_root("//computername/sharefolder/resource") == 14);
+	cl_assert(git_path_root("//computername/sharefolder") == 14);
+	cl_assert(git_path_root("//computername") == -1);
+#endif
+}
+
+#define NON_EXISTING_FILEPATH "i_hope_i_do_not_exist"
+
+void test_core_path__13_cannot_prettify_a_non_existing_file(void)
+{
+	git_buf p = GIT_BUF_INIT;
+
+	cl_assert_equal_b(git_path_exists(NON_EXISTING_FILEPATH), false);
+	cl_assert_equal_i(GIT_ENOTFOUND, git_path_prettify(&p, NON_EXISTING_FILEPATH, NULL));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_path_prettify(&p, NON_EXISTING_FILEPATH "/so-do-i", NULL));
+
+	git_buf_free(&p);
+}
+
+void test_core_path__14_apply_relative(void)
+{
+	git_buf p = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_sets(&p, "/this/is/a/base"));
+
+	cl_git_pass(git_path_apply_relative(&p, "../test"));
+	cl_assert_equal_s("/this/is/a/test", p.ptr);
+
+	cl_git_pass(git_path_apply_relative(&p, "../../the/./end"));
+	cl_assert_equal_s("/this/is/the/end", p.ptr);
+
+	cl_git_pass(git_path_apply_relative(&p, "./of/this/../the/string"));
+	cl_assert_equal_s("/this/is/the/end/of/the/string", p.ptr);
+
+	cl_git_pass(git_path_apply_relative(&p, "../../../../../.."));
+	cl_assert_equal_s("/this/", p.ptr);
+
+	cl_git_pass(git_path_apply_relative(&p, "../"));
+	cl_assert_equal_s("/", p.ptr);
+
+	cl_git_fail(git_path_apply_relative(&p, "../../.."));
+
+
+	cl_git_pass(git_buf_sets(&p, "d:/another/test"));
+
+	cl_git_pass(git_path_apply_relative(&p, "../.."));
+	cl_assert_equal_s("d:/", p.ptr);
+
+	cl_git_pass(git_path_apply_relative(&p, "from/here/to/../and/./back/."));
+	cl_assert_equal_s("d:/from/here/and/back/", p.ptr);
+
+
+	cl_git_pass(git_buf_sets(&p, "https://my.url.com/test.git"));
+
+	cl_git_pass(git_path_apply_relative(&p, "../another.git"));
+	cl_assert_equal_s("https://my.url.com/another.git", p.ptr);
+
+	cl_git_pass(git_path_apply_relative(&p, "../full/path/url.patch"));
+	cl_assert_equal_s("https://my.url.com/full/path/url.patch", p.ptr);
+
+	cl_git_pass(git_path_apply_relative(&p, ".."));
+	cl_assert_equal_s("https://my.url.com/full/path/", p.ptr);
+
+	cl_git_pass(git_path_apply_relative(&p, "../../../"));
+	cl_assert_equal_s("https://", p.ptr);
+
+
+	cl_git_pass(git_buf_sets(&p, "../../this/is/relative"));
+
+	cl_git_pass(git_path_apply_relative(&p, "../../preserves/the/prefix"));
+	cl_assert_equal_s("../../this/preserves/the/prefix", p.ptr);
+
+	cl_git_pass(git_path_apply_relative(&p, "../../../../that"));
+	cl_assert_equal_s("../../that", p.ptr);
+
+	cl_git_pass(git_path_apply_relative(&p, "../there"));
+	cl_assert_equal_s("../../there", p.ptr);
+	git_buf_free(&p);
+}
+
+static void assert_resolve_relative(
+	git_buf *buf, const char *expected, const char *path)
+{
+	cl_git_pass(git_buf_sets(buf, path));
+	cl_git_pass(git_path_resolve_relative(buf, 0));
+	cl_assert_equal_s(expected, buf->ptr);
+}
+
+void test_core_path__15_resolve_relative(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	assert_resolve_relative(&buf, "", "");
+	assert_resolve_relative(&buf, "", ".");
+	assert_resolve_relative(&buf, "", "./");
+	assert_resolve_relative(&buf, "..", "..");
+	assert_resolve_relative(&buf, "../", "../");
+	assert_resolve_relative(&buf, "..", "./..");
+	assert_resolve_relative(&buf, "../", "./../");
+	assert_resolve_relative(&buf, "../", "../.");
+	assert_resolve_relative(&buf, "../", ".././");
+	assert_resolve_relative(&buf, "../..", "../..");
+	assert_resolve_relative(&buf, "../../", "../../");
+
+	assert_resolve_relative(&buf, "/", "/");
+	assert_resolve_relative(&buf, "/", "/.");
+
+	assert_resolve_relative(&buf, "", "a/..");
+	assert_resolve_relative(&buf, "", "a/../");
+	assert_resolve_relative(&buf, "", "a/../.");
+
+	assert_resolve_relative(&buf, "/a", "/a");
+	assert_resolve_relative(&buf, "/a/", "/a/.");
+	assert_resolve_relative(&buf, "/", "/a/../");
+	assert_resolve_relative(&buf, "/", "/a/../.");
+	assert_resolve_relative(&buf, "/", "/a/.././");
+
+	assert_resolve_relative(&buf, "a", "a");
+	assert_resolve_relative(&buf, "a/", "a/");
+	assert_resolve_relative(&buf, "a/", "a/.");
+	assert_resolve_relative(&buf, "a/", "a/./");
+
+	assert_resolve_relative(&buf, "a/b", "a//b");
+	assert_resolve_relative(&buf, "a/b/c", "a/b/c");
+	assert_resolve_relative(&buf, "b/c", "./b/c");
+	assert_resolve_relative(&buf, "a/c", "a/./c");
+	assert_resolve_relative(&buf, "a/b/", "a/b/.");
+
+	assert_resolve_relative(&buf, "/a/b/c", "///a/b/c");
+	assert_resolve_relative(&buf, "/", "////");
+	assert_resolve_relative(&buf, "/a", "///a");
+	assert_resolve_relative(&buf, "/", "///.");
+	assert_resolve_relative(&buf, "/", "///a/..");
+
+	assert_resolve_relative(&buf, "../../path", "../../test//../././path");
+	assert_resolve_relative(&buf, "../d", "a/b/../../../c/../d");
+
+	cl_git_pass(git_buf_sets(&buf, "/.."));
+	cl_git_fail(git_path_resolve_relative(&buf, 0));
+
+	cl_git_pass(git_buf_sets(&buf, "/./.."));
+	cl_git_fail(git_path_resolve_relative(&buf, 0));
+
+	cl_git_pass(git_buf_sets(&buf, "/.//.."));
+	cl_git_fail(git_path_resolve_relative(&buf, 0));
+
+	cl_git_pass(git_buf_sets(&buf, "/../."));
+	cl_git_fail(git_path_resolve_relative(&buf, 0));
+
+	cl_git_pass(git_buf_sets(&buf, "/../.././../a"));
+	cl_git_fail(git_path_resolve_relative(&buf, 0));
+
+	cl_git_pass(git_buf_sets(&buf, "////.."));
+	cl_git_fail(git_path_resolve_relative(&buf, 0));
+
+	/* things that start with Windows network paths */
+#ifdef GIT_WIN32
+	assert_resolve_relative(&buf, "//a/b/c", "//a/b/c");
+	assert_resolve_relative(&buf, "//a/", "//a/b/..");
+	assert_resolve_relative(&buf, "//a/b/c", "//a/Q/../b/x/y/../../c");
+
+	cl_git_pass(git_buf_sets(&buf, "//a/b/../.."));
+	cl_git_fail(git_path_resolve_relative(&buf, 0));
+#else
+	assert_resolve_relative(&buf, "/a/b/c", "//a/b/c");
+	assert_resolve_relative(&buf, "/a/", "//a/b/..");
+	assert_resolve_relative(&buf, "/a/b/c", "//a/Q/../b/x/y/../../c");
+	assert_resolve_relative(&buf, "/", "//a/b/../..");
+#endif
+
+	git_buf_free(&buf);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/pool.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/pool.c
new file mode 100755
index 0000000..a7ec880
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/pool.c
@@ -0,0 +1,146 @@
+#include "clar_libgit2.h"
+#include "pool.h"
+#include "git2/oid.h"
+
+void test_core_pool__0(void)
+{
+	int i;
+	git_pool p;
+	void *ptr;
+
+	cl_git_pass(git_pool_init(&p, 1, 4000));
+
+	for (i = 1; i < 10000; i *= 2) {
+		ptr = git_pool_malloc(&p, i);
+		cl_assert(ptr != NULL);
+		cl_assert(git_pool__ptr_in_pool(&p, ptr));
+		cl_assert(!git_pool__ptr_in_pool(&p, &i));
+	}
+
+	/* 1+2+4+8+16+32+64+128+256+512+1024 -> original block */
+	/* 2048 -> 1 block */
+	/* 4096 -> 1 block */
+	/* 8192 -> 1 block */
+
+	cl_assert(git_pool__open_pages(&p) + git_pool__full_pages(&p) == 4);
+
+	git_pool_clear(&p);
+}
+
+void test_core_pool__1(void)
+{
+	int i;
+	git_pool p;
+
+	cl_git_pass(git_pool_init(&p, 1, 4000));
+
+	for (i = 2010; i > 0; i--)
+		cl_assert(git_pool_malloc(&p, i) != NULL);
+
+	/* with fixed page size, allocation must end up with these values */
+	cl_assert_equal_i(1, git_pool__open_pages(&p));
+	cl_assert_equal_i(507, git_pool__full_pages(&p));
+
+	git_pool_clear(&p);
+
+	cl_git_pass(git_pool_init(&p, 1, 4120));
+
+	for (i = 2010; i > 0; i--)
+		cl_assert(git_pool_malloc(&p, i) != NULL);
+
+	/* with fixed page size, allocation must end up with these values */
+	cl_assert_equal_i(1, git_pool__open_pages(&p));
+	cl_assert_equal_i(492, git_pool__full_pages(&p));
+
+	git_pool_clear(&p);
+}
+
+static char to_hex[] = "0123456789abcdef";
+
+void test_core_pool__2(void)
+{
+	git_pool p;
+	char oid_hex[GIT_OID_HEXSZ];
+	git_oid *oid;
+	int i, j;
+
+	memset(oid_hex, '0', sizeof(oid_hex));
+
+	cl_git_pass(git_pool_init(&p, sizeof(git_oid), 100));
+
+	for (i = 1000; i < 10000; i++) {
+		oid = git_pool_malloc(&p, 1);
+		cl_assert(oid != NULL);
+
+		for (j = 0; j < 8; j++)
+			oid_hex[j] = to_hex[(i >> (4 * j)) & 0x0f];
+		cl_git_pass(git_oid_fromstr(oid, oid_hex));
+	}
+
+	/* with fixed page size, allocation must end up with these values */
+	cl_assert(git_pool__open_pages(&p) == 0);
+	cl_assert(git_pool__full_pages(&p) == 90);
+
+	git_pool_clear(&p);
+}
+
+void test_core_pool__free_list(void)
+{
+	int i;
+	git_pool p;
+	void *ptr, *ptrs[50];
+
+	cl_git_pass(git_pool_init(&p, 100, 100));
+
+	for (i = 0; i < 10; ++i) {
+		ptr = git_pool_malloc(&p, 1);
+		cl_assert(ptr != NULL);
+	}
+	cl_assert_equal_i(10, (int)p.items);
+
+	for (i = 0; i < 50; ++i) {
+		ptrs[i] = git_pool_malloc(&p, 1);
+		cl_assert(ptrs[i] != NULL);
+	}
+	cl_assert_equal_i(60, (int)p.items);
+
+	git_pool_free(&p, ptr);
+	cl_assert_equal_i(60, (int)p.items);
+
+	git_pool_free_array(&p, 50, ptrs);
+	cl_assert_equal_i(60, (int)p.items);
+
+	for (i = 0; i < 50; ++i) {
+		ptrs[i] = git_pool_malloc(&p, 1);
+		cl_assert(ptrs[i] != NULL);
+	}
+	cl_assert_equal_i(60, (int)p.items);
+
+	for (i = 0; i < 111; ++i) {
+		ptr = git_pool_malloc(&p, 1);
+		cl_assert(ptr != NULL);
+	}
+	cl_assert_equal_i(170, (int)p.items);
+
+	git_pool_free_array(&p, 50, ptrs);
+	cl_assert_equal_i(170, (int)p.items);
+
+	for (i = 0; i < 50; ++i) {
+		ptrs[i] = git_pool_malloc(&p, 1);
+		cl_assert(ptrs[i] != NULL);
+	}
+	cl_assert_equal_i(170, (int)p.items);
+
+	git_pool_clear(&p);
+}
+
+void test_core_pool__strndup_limit(void)
+{
+	git_pool p;
+
+	cl_git_pass(git_pool_init(&p, 1, 100));
+	/* ensure 64 bit doesn't overflow */
+	cl_assert(git_pool_strndup(&p, "foo", (size_t)-1) == NULL);
+	git_pool_clear(&p);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/posix.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/posix.c
new file mode 100755
index 0000000..5a9e248
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/posix.c
@@ -0,0 +1,148 @@
+#ifndef _WIN32
+# include <arpa/inet.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+#else
+# include <ws2tcpip.h>
+# ifdef _MSC_VER
+#  pragma comment(lib, "ws2_32")
+# endif
+#endif
+
+#include "clar_libgit2.h"
+#include "posix.h"
+
+void test_core_posix__initialize(void)
+{
+#ifdef GIT_WIN32
+	/* on win32, the WSA context needs to be initialized
+	 * before any socket calls can be performed */
+	WSADATA wsd;
+
+	cl_git_pass(WSAStartup(MAKEWORD(2,2), &wsd));
+	cl_assert(LOBYTE(wsd.wVersion) == 2 && HIBYTE(wsd.wVersion) == 2);
+#endif
+}
+
+static bool supports_ipv6(void)
+{
+#ifdef GIT_WIN32
+	/* IPv6 is supported on Vista and newer */
+	return git_has_win32_version(6, 0, 0);
+#else
+	return 1;
+#endif
+}
+
+void test_core_posix__inet_pton(void)
+{
+	struct in_addr addr;
+	struct in6_addr addr6;
+	size_t i;
+	
+	struct in_addr_data {
+		const char *p;
+		const uint8_t n[4];
+	};
+
+	struct in6_addr_data {
+		const char *p;
+		const uint8_t n[16];
+	};
+
+	static struct in_addr_data in_addr_data[] = {
+		{ "0.0.0.0", { 0, 0, 0, 0 } },
+		{ "10.42.101.8", { 10, 42, 101, 8 } },
+		{ "127.0.0.1", { 127, 0, 0, 1 } },
+		{ "140.177.10.12", { 140, 177, 10, 12 } },
+		{ "204.232.175.90", { 204, 232, 175, 90 } },
+		{ "255.255.255.255", { 255, 255, 255, 255 } },
+	};
+
+	static struct in6_addr_data in6_addr_data[] = {
+		{ "::", { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+		{ "::1", { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } },
+		{ "0:0:0:0:0:0:0:1", { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } },
+		{ "2001:db8:8714:3a90::12", { 0x20, 0x01, 0x0d, 0xb8, 0x87, 0x14, 0x3a, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12 } },
+		{ "fe80::f8ba:c2d6:86be:3645", { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xba, 0xc2, 0xd6, 0x86, 0xbe, 0x36, 0x45 } },
+		{ "::ffff:204.152.189.116", { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x98, 0xbd, 0x74 } },
+	};
+
+	/* Test some ipv4 addresses */
+	for (i = 0; i < 6; i++) {
+		cl_assert(p_inet_pton(AF_INET, in_addr_data[i].p, &addr) == 1);
+		cl_assert(memcmp(&addr, in_addr_data[i].n, sizeof(struct in_addr)) == 0);
+	}
+
+	/* Test some ipv6 addresses */
+	if (supports_ipv6())
+	{
+		for (i = 0; i < 6; i++) {
+			cl_assert(p_inet_pton(AF_INET6, in6_addr_data[i].p, &addr6) == 1);
+			cl_assert(memcmp(&addr6, in6_addr_data[i].n, sizeof(struct in6_addr)) == 0);
+		}
+	}
+
+	/* Test some invalid strings */
+	cl_assert(p_inet_pton(AF_INET, "", &addr) == 0);
+	cl_assert(p_inet_pton(AF_INET, "foo", &addr) == 0);
+	cl_assert(p_inet_pton(AF_INET, " 127.0.0.1", &addr) == 0);
+	cl_assert(p_inet_pton(AF_INET, "bar", &addr) == 0);
+	cl_assert(p_inet_pton(AF_INET, "10.foo.bar.1", &addr) == 0);
+
+	/* Test unsupported address families */
+	cl_git_fail(p_inet_pton(12, "52.472", NULL)); /* AF_DECnet */
+	cl_assert_equal_i(EAFNOSUPPORT, errno);
+
+	cl_git_fail(p_inet_pton(5, "315.124", NULL)); /* AF_CHAOS */
+	cl_assert_equal_i(EAFNOSUPPORT, errno);
+}
+
+void test_core_posix__utimes(void)
+{
+	struct timeval times[2];
+	struct stat st;
+	time_t curtime;
+	int fd;
+
+	/* test p_utimes */
+	times[0].tv_sec = 1234567890;
+	times[0].tv_usec = 0;
+	times[1].tv_sec = 1234567890;
+	times[1].tv_usec = 0;
+
+	cl_git_mkfile("foo", "Dummy file.");
+	cl_must_pass(p_utimes("foo", times));
+
+	p_stat("foo", &st);
+	cl_assert_equal_i(1234567890, st.st_atime);
+	cl_assert_equal_i(1234567890, st.st_mtime);
+
+
+	/* test p_futimes */
+	times[0].tv_sec = 1414141414;
+	times[0].tv_usec = 0;
+	times[1].tv_sec = 1414141414;
+	times[1].tv_usec = 0;
+
+	cl_must_pass(fd = p_open("foo", O_RDWR));
+	cl_must_pass(p_futimes(fd, times));
+	p_close(fd);
+
+	p_stat("foo", &st);
+	cl_assert_equal_i(1414141414, st.st_atime);
+	cl_assert_equal_i(1414141414, st.st_mtime);
+
+
+	/* test p_utimes with current time, assume that
+	 * it takes < 5 seconds to get the time...!
+	 */
+	cl_must_pass(p_utimes("foo", NULL));
+
+	curtime = time(NULL);
+	p_stat("foo", &st);
+	cl_assert((st.st_atime - curtime) < 5);
+	cl_assert((st.st_mtime - curtime) < 5);
+
+	p_unlink("foo");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/pqueue.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/pqueue.c
new file mode 100755
index 0000000..bcd4eea
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/pqueue.c
@@ -0,0 +1,128 @@
+#include "clar_libgit2.h"
+#include "pqueue.h"
+
+static int cmp_ints(const void *v1, const void *v2)
+{
+	int i1 = *(int *)v1, i2 = *(int *)v2;
+	return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
+}
+
+void test_core_pqueue__items_are_put_in_order(void)
+{
+	git_pqueue pq;
+	int i, vals[20];
+
+	cl_git_pass(git_pqueue_init(&pq, 0, 20, cmp_ints));
+
+	for (i = 0; i < 20; ++i) {
+		if (i < 10)
+			vals[i] = 10 - i; /* 10 down to 1 */
+		else
+			vals[i] = i + 1;  /* 11 up to 20 */
+
+		cl_git_pass(git_pqueue_insert(&pq, &vals[i]));
+	}
+
+	cl_assert_equal_i(20, git_pqueue_size(&pq));
+
+	for (i = 1; i <= 20; ++i) {
+		void *p = git_pqueue_pop(&pq);
+		cl_assert(p);
+		cl_assert_equal_i(i, *(int *)p);
+	}
+
+	cl_assert_equal_i(0, git_pqueue_size(&pq));
+
+	git_pqueue_free(&pq);
+}
+
+void test_core_pqueue__interleave_inserts_and_pops(void)
+{
+	git_pqueue pq;
+	int chunk, v, i, vals[200];
+
+	cl_git_pass(git_pqueue_init(&pq, 0, 20, cmp_ints));
+
+	for (v = 0, chunk = 20; chunk <= 200; chunk += 20) {
+		/* push the next 20 */
+		for (; v < chunk; ++v) {
+			vals[v] = (v & 1) ? 200 - v : v;
+			cl_git_pass(git_pqueue_insert(&pq, &vals[v]));
+		}
+
+		/* pop the lowest 10 */
+		for (i = 0; i < 10; ++i)
+			(void)git_pqueue_pop(&pq);
+	}
+
+	cl_assert_equal_i(100, git_pqueue_size(&pq));
+
+	/* at this point, we've popped 0-99 */
+
+	for (v = 100; v < 200; ++v) {
+		void *p = git_pqueue_pop(&pq);
+		cl_assert(p);
+		cl_assert_equal_i(v, *(int *)p);
+	}
+
+	cl_assert_equal_i(0, git_pqueue_size(&pq));
+
+	git_pqueue_free(&pq);
+}
+
+void test_core_pqueue__max_heap_size(void)
+{
+	git_pqueue pq;
+	int i, vals[100];
+
+	cl_git_pass(git_pqueue_init(&pq, GIT_PQUEUE_FIXED_SIZE, 50, cmp_ints));
+
+	for (i = 0; i < 100; ++i) {
+		vals[i] = (i & 1) ? 100 - i : i;
+		cl_git_pass(git_pqueue_insert(&pq, &vals[i]));
+	}
+
+	cl_assert_equal_i(50, git_pqueue_size(&pq));
+
+	for (i = 50; i < 100; ++i) {
+		void *p = git_pqueue_pop(&pq);
+		cl_assert(p);
+		cl_assert_equal_i(i, *(int *)p);
+	}
+
+	cl_assert_equal_i(0, git_pqueue_size(&pq));
+
+	git_pqueue_free(&pq);
+
+}
+
+static int cmp_ints_like_commit_time(const void *a, const void *b)
+{
+	return *((const int *)a) < *((const int *)b);
+}
+
+void test_core_pqueue__interleaved_pushes_and_pops(void)
+{
+	git_pqueue pq;
+	int i, j, *val;
+	static int commands[] =
+		{ 6, 9, 8, 0, 5, 0, 7, 0, 4, 3, 0, 0, 0, 4, 0, 2, 0, 1, 0, 0, -1 };
+	static int expected[] =
+		{ 9, 8, 7, 6, 5, 4, 4, 3, 2, 1, -1 };
+
+	cl_git_pass(git_pqueue_init(&pq, 0, 10, cmp_ints_like_commit_time));
+
+	for (i = 0, j = 0; commands[i] >= 0; ++i) {
+		if (!commands[i]) {
+			cl_assert((val = git_pqueue_pop(&pq)) != NULL);
+			cl_assert_equal_i(expected[j], *val);
+			++j;
+		} else {
+			cl_git_pass(git_pqueue_insert(&pq, &commands[i]));
+		}
+	}
+
+	cl_assert_equal_i(0, git_pqueue_size(&pq));
+	git_pqueue_free(&pq);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/rmdir.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/rmdir.c
new file mode 100755
index 0000000..f0b0bfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/rmdir.c
@@ -0,0 +1,98 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+
+static const char *empty_tmp_dir = "test_gitfo_rmdir_recurs_test";
+
+void test_core_rmdir__initialize(void)
+{
+	git_buf path = GIT_BUF_INIT;
+
+	cl_must_pass(p_mkdir(empty_tmp_dir, 0777));
+
+	cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/one"));
+	cl_must_pass(p_mkdir(path.ptr, 0777));
+
+	cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/one/two_one"));
+	cl_must_pass(p_mkdir(path.ptr, 0777));
+
+	cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/one/two_two"));
+	cl_must_pass(p_mkdir(path.ptr, 0777));
+
+	cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/one/two_two/three"));
+	cl_must_pass(p_mkdir(path.ptr, 0777));
+
+	cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/two"));
+	cl_must_pass(p_mkdir(path.ptr, 0777));
+
+	git_buf_free(&path);
+}
+
+/* make sure empty dir can be deleted recusively */
+void test_core_rmdir__delete_recursive(void)
+{
+	cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_EMPTY_HIERARCHY));
+}
+
+/* make sure non-empty dir cannot be deleted recusively */
+void test_core_rmdir__fail_to_delete_non_empty_dir(void)
+{
+	git_buf file = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_joinpath(&file, empty_tmp_dir, "/two/file.txt"));
+
+	cl_git_mkfile(git_buf_cstr(&file), "dummy");
+
+	cl_git_fail(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_EMPTY_HIERARCHY));
+
+	cl_must_pass(p_unlink(file.ptr));
+	cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_EMPTY_HIERARCHY));
+
+	git_buf_free(&file);
+}
+
+void test_core_rmdir__can_skip_non_empty_dir(void)
+{
+	git_buf file = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_joinpath(&file, empty_tmp_dir, "/two/file.txt"));
+
+	cl_git_mkfile(git_buf_cstr(&file), "dummy");
+
+	cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_SKIP_NONEMPTY));
+	cl_assert(git_path_exists(git_buf_cstr(&file)) == true);
+
+	cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_REMOVE_FILES));
+	cl_assert(git_path_exists(empty_tmp_dir) == false);
+
+	git_buf_free(&file);
+}
+
+void test_core_rmdir__can_remove_empty_parents(void)
+{
+	git_buf file = GIT_BUF_INIT;
+
+	cl_git_pass(
+		git_buf_joinpath(&file, empty_tmp_dir, "/one/two_two/three/file.txt"));
+	cl_git_mkfile(git_buf_cstr(&file), "dummy");
+	cl_assert(git_path_isfile(git_buf_cstr(&file)));
+
+	cl_git_pass(git_futils_rmdir_r("one/two_two/three/file.txt", empty_tmp_dir,
+		GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_EMPTY_PARENTS));
+
+	cl_assert(!git_path_exists(git_buf_cstr(&file)));
+
+	git_buf_rtruncate_at_char(&file, '/'); /* three (only contained file.txt) */
+	cl_assert(!git_path_exists(git_buf_cstr(&file)));
+
+	git_buf_rtruncate_at_char(&file, '/'); /* two_two (only contained three) */
+	cl_assert(!git_path_exists(git_buf_cstr(&file)));
+
+	git_buf_rtruncate_at_char(&file, '/'); /* one (contained two_one also) */
+	cl_assert(git_path_exists(git_buf_cstr(&file)));
+
+	cl_assert(git_path_exists(empty_tmp_dir) == true);
+
+	git_buf_free(&file);
+
+	cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_EMPTY_HIERARCHY));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/sortedcache.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/sortedcache.c
new file mode 100755
index 0000000..c1869be
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/sortedcache.c
@@ -0,0 +1,363 @@
+#include "clar_libgit2.h"
+#include "sortedcache.h"
+
+static int name_only_cmp(const void *a, const void *b)
+{
+	return strcmp(a, b);
+}
+
+void test_core_sortedcache__name_only(void)
+{
+	git_sortedcache *sc;
+	void *item;
+	size_t pos;
+
+	cl_git_pass(git_sortedcache_new(
+		&sc, 0, NULL, NULL, name_only_cmp, NULL));
+
+	cl_git_pass(git_sortedcache_wlock(sc));
+	cl_git_pass(git_sortedcache_upsert(&item, sc, "aaa"));
+	cl_git_pass(git_sortedcache_upsert(&item, sc, "bbb"));
+	cl_git_pass(git_sortedcache_upsert(&item, sc, "zzz"));
+	cl_git_pass(git_sortedcache_upsert(&item, sc, "mmm"));
+	cl_git_pass(git_sortedcache_upsert(&item, sc, "iii"));
+	git_sortedcache_wunlock(sc);
+
+	cl_assert_equal_sz(5, git_sortedcache_entrycount(sc));
+
+	cl_assert((item = git_sortedcache_lookup(sc, "aaa")) != NULL);
+	cl_assert_equal_s("aaa", item);
+	cl_assert((item = git_sortedcache_lookup(sc, "mmm")) != NULL);
+	cl_assert_equal_s("mmm", item);
+	cl_assert((item = git_sortedcache_lookup(sc, "zzz")) != NULL);
+	cl_assert_equal_s("zzz", item);
+	cl_assert(git_sortedcache_lookup(sc, "qqq") == NULL);
+
+	cl_assert((item = git_sortedcache_entry(sc, 0)) != NULL);
+	cl_assert_equal_s("aaa", item);
+	cl_assert((item = git_sortedcache_entry(sc, 1)) != NULL);
+	cl_assert_equal_s("bbb", item);
+	cl_assert((item = git_sortedcache_entry(sc, 2)) != NULL);
+	cl_assert_equal_s("iii", item);
+	cl_assert((item = git_sortedcache_entry(sc, 3)) != NULL);
+	cl_assert_equal_s("mmm", item);
+	cl_assert((item = git_sortedcache_entry(sc, 4)) != NULL);
+	cl_assert_equal_s("zzz", item);
+	cl_assert(git_sortedcache_entry(sc, 5) == NULL);
+
+	cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "aaa"));
+	cl_assert_equal_sz(0, pos);
+	cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "iii"));
+	cl_assert_equal_sz(2, pos);
+	cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "zzz"));
+	cl_assert_equal_sz(4, pos);
+	cl_assert_equal_i(
+		GIT_ENOTFOUND, git_sortedcache_lookup_index(&pos, sc, "abc"));
+
+	git_sortedcache_clear(sc, true);
+
+	cl_assert_equal_sz(0, git_sortedcache_entrycount(sc));
+	cl_assert(git_sortedcache_entry(sc, 0) == NULL);
+	cl_assert(git_sortedcache_lookup(sc, "aaa") == NULL);
+	cl_assert(git_sortedcache_entry(sc, 0) == NULL);
+
+	git_sortedcache_free(sc);
+}
+
+typedef struct {
+	int value;
+	char smaller_value;
+	char path[GIT_FLEX_ARRAY];
+} sortedcache_test_struct;
+
+static int sortedcache_test_struct_cmp(const void *a_, const void *b_)
+{
+	const sortedcache_test_struct *a = a_, *b = b_;
+	return strcmp(a->path, b->path);
+}
+
+static void sortedcache_test_struct_free(void *payload, void *item_)
+{
+	sortedcache_test_struct *item = item_;
+	int *count = payload;
+	(*count)++;
+	item->smaller_value = 0;
+}
+
+void test_core_sortedcache__in_memory(void)
+{
+	git_sortedcache *sc;
+	sortedcache_test_struct *item;
+	int free_count = 0;
+
+	cl_git_pass(git_sortedcache_new(
+		&sc, offsetof(sortedcache_test_struct, path),
+		sortedcache_test_struct_free, &free_count,
+		sortedcache_test_struct_cmp, NULL));
+
+	cl_git_pass(git_sortedcache_wlock(sc));
+	cl_git_pass(git_sortedcache_upsert((void **)&item, sc, "aaa"));
+	item->value = 10;
+	item->smaller_value = 1;
+	cl_git_pass(git_sortedcache_upsert((void **)&item, sc, "bbb"));
+	item->value = 20;
+	item->smaller_value = 2;
+	cl_git_pass(git_sortedcache_upsert((void **)&item, sc, "zzz"));
+	item->value = 30;
+	item->smaller_value = 26;
+	cl_git_pass(git_sortedcache_upsert((void **)&item, sc, "mmm"));
+	item->value = 40;
+	item->smaller_value = 14;
+	cl_git_pass(git_sortedcache_upsert((void **)&item, sc, "iii"));
+	item->value = 50;
+	item->smaller_value = 9;
+	git_sortedcache_wunlock(sc);
+
+	cl_assert_equal_sz(5, git_sortedcache_entrycount(sc));
+
+	cl_git_pass(git_sortedcache_rlock(sc));
+
+	cl_assert((item = git_sortedcache_lookup(sc, "aaa")) != NULL);
+	cl_assert_equal_s("aaa", item->path);
+	cl_assert_equal_i(10, item->value);
+	cl_assert((item = git_sortedcache_lookup(sc, "mmm")) != NULL);
+	cl_assert_equal_s("mmm", item->path);
+	cl_assert_equal_i(40, item->value);
+	cl_assert((item = git_sortedcache_lookup(sc, "zzz")) != NULL);
+	cl_assert_equal_s("zzz", item->path);
+	cl_assert_equal_i(30, item->value);
+	cl_assert(git_sortedcache_lookup(sc, "abc") == NULL);
+
+	/* not on Windows:
+	 * cl_git_pass(git_sortedcache_rlock(sc)); -- grab more than one
+	 */
+
+	cl_assert((item = git_sortedcache_entry(sc, 0)) != NULL);
+	cl_assert_equal_s("aaa", item->path);
+	cl_assert_equal_i(10, item->value);
+	cl_assert((item = git_sortedcache_entry(sc, 1)) != NULL);
+	cl_assert_equal_s("bbb", item->path);
+	cl_assert_equal_i(20, item->value);
+	cl_assert((item = git_sortedcache_entry(sc, 2)) != NULL);
+	cl_assert_equal_s("iii", item->path);
+	cl_assert_equal_i(50, item->value);
+	cl_assert((item = git_sortedcache_entry(sc, 3)) != NULL);
+	cl_assert_equal_s("mmm", item->path);
+	cl_assert_equal_i(40, item->value);
+	cl_assert((item = git_sortedcache_entry(sc, 4)) != NULL);
+	cl_assert_equal_s("zzz", item->path);
+	cl_assert_equal_i(30, item->value);
+	cl_assert(git_sortedcache_entry(sc, 5) == NULL);
+
+	git_sortedcache_runlock(sc);
+	/* git_sortedcache_runlock(sc); */
+
+	cl_assert_equal_i(0, free_count);
+
+	git_sortedcache_clear(sc, true);
+
+	cl_assert_equal_i(5, free_count);
+
+	cl_assert_equal_sz(0, git_sortedcache_entrycount(sc));
+	cl_assert(git_sortedcache_entry(sc, 0) == NULL);
+	cl_assert(git_sortedcache_lookup(sc, "aaa") == NULL);
+	cl_assert(git_sortedcache_entry(sc, 0) == NULL);
+
+	free_count = 0;
+
+	cl_git_pass(git_sortedcache_wlock(sc));
+	cl_git_pass(git_sortedcache_upsert((void **)&item, sc, "testing"));
+	item->value = 10;
+	item->smaller_value = 3;
+	cl_git_pass(git_sortedcache_upsert((void **)&item, sc, "again"));
+	item->value = 20;
+	item->smaller_value = 1;
+	cl_git_pass(git_sortedcache_upsert((void **)&item, sc, "final"));
+	item->value = 30;
+	item->smaller_value = 2;
+	git_sortedcache_wunlock(sc);
+
+	cl_assert_equal_sz(3, git_sortedcache_entrycount(sc));
+
+	cl_assert((item = git_sortedcache_lookup(sc, "testing")) != NULL);
+	cl_assert_equal_s("testing", item->path);
+	cl_assert_equal_i(10, item->value);
+	cl_assert((item = git_sortedcache_lookup(sc, "again")) != NULL);
+	cl_assert_equal_s("again", item->path);
+	cl_assert_equal_i(20, item->value);
+	cl_assert((item = git_sortedcache_lookup(sc, "final")) != NULL);
+	cl_assert_equal_s("final", item->path);
+	cl_assert_equal_i(30, item->value);
+	cl_assert(git_sortedcache_lookup(sc, "zzz") == NULL);
+
+	cl_assert((item = git_sortedcache_entry(sc, 0)) != NULL);
+	cl_assert_equal_s("again", item->path);
+	cl_assert_equal_i(20, item->value);
+	cl_assert((item = git_sortedcache_entry(sc, 1)) != NULL);
+	cl_assert_equal_s("final", item->path);
+	cl_assert_equal_i(30, item->value);
+	cl_assert((item = git_sortedcache_entry(sc, 2)) != NULL);
+	cl_assert_equal_s("testing", item->path);
+	cl_assert_equal_i(10, item->value);
+	cl_assert(git_sortedcache_entry(sc, 3) == NULL);
+
+	{
+		size_t pos;
+
+		cl_git_pass(git_sortedcache_wlock(sc));
+
+		cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "again"));
+		cl_assert_equal_sz(0, pos);
+		cl_git_pass(git_sortedcache_remove(sc, pos));
+		cl_assert_equal_i(
+			GIT_ENOTFOUND, git_sortedcache_lookup_index(&pos, sc, "again"));
+
+		cl_assert_equal_sz(2, git_sortedcache_entrycount(sc));
+
+		cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "testing"));
+		cl_assert_equal_sz(1, pos);
+		cl_git_pass(git_sortedcache_remove(sc, pos));
+		cl_assert_equal_i(
+			GIT_ENOTFOUND, git_sortedcache_lookup_index(&pos, sc, "testing"));
+
+		cl_assert_equal_sz(1, git_sortedcache_entrycount(sc));
+
+		cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "final"));
+		cl_assert_equal_sz(0, pos);
+		cl_git_pass(git_sortedcache_remove(sc, pos));
+		cl_assert_equal_i(
+			GIT_ENOTFOUND, git_sortedcache_lookup_index(&pos, sc, "final"));
+
+		cl_assert_equal_sz(0, git_sortedcache_entrycount(sc));
+
+		git_sortedcache_wunlock(sc);
+	}
+
+	git_sortedcache_free(sc);
+
+	cl_assert_equal_i(3, free_count);
+}
+
+static void sortedcache_test_reload(git_sortedcache *sc)
+{
+	int count = 0;
+	git_buf buf = GIT_BUF_INIT;
+	char *scan, *after;
+	sortedcache_test_struct *item;
+
+	cl_assert(git_sortedcache_lockandload(sc, &buf) > 0);
+
+	git_sortedcache_clear(sc, false); /* clear once we already have lock */
+
+	for (scan = buf.ptr; *scan; scan = after + 1) {
+		int val = strtol(scan, &after, 0);
+		cl_assert(after > scan);
+		scan = after;
+
+		for (scan = after; git__isspace(*scan); ++scan) /* find start */;
+		for (after = scan; *after && *after != '\n'; ++after) /* find eol */;
+		*after = '\0';
+
+		cl_git_pass(git_sortedcache_upsert((void **)&item, sc, scan));
+
+		item->value = val;
+		item->smaller_value = (char)(count++);
+	}
+
+	git_sortedcache_wunlock(sc);
+
+	git_buf_free(&buf);
+}
+
+void test_core_sortedcache__on_disk(void)
+{
+	git_sortedcache *sc;
+	sortedcache_test_struct *item;
+	int free_count = 0;
+	size_t pos;
+
+	cl_git_mkfile("cacheitems.txt", "10 abc\n20 bcd\n30 cde\n");
+
+	cl_git_pass(git_sortedcache_new(
+		&sc, offsetof(sortedcache_test_struct, path),
+		sortedcache_test_struct_free, &free_count,
+		sortedcache_test_struct_cmp, "cacheitems.txt"));
+
+	/* should need to reload the first time */
+
+	sortedcache_test_reload(sc);
+
+	/* test what we loaded */
+
+	cl_assert_equal_sz(3, git_sortedcache_entrycount(sc));
+
+	cl_assert((item = git_sortedcache_lookup(sc, "abc")) != NULL);
+	cl_assert_equal_s("abc", item->path);
+	cl_assert_equal_i(10, item->value);
+	cl_assert((item = git_sortedcache_lookup(sc, "cde")) != NULL);
+	cl_assert_equal_s("cde", item->path);
+	cl_assert_equal_i(30, item->value);
+	cl_assert(git_sortedcache_lookup(sc, "aaa") == NULL);
+
+	cl_assert((item = git_sortedcache_entry(sc, 0)) != NULL);
+	cl_assert_equal_s("abc", item->path);
+	cl_assert_equal_i(10, item->value);
+	cl_assert((item = git_sortedcache_entry(sc, 1)) != NULL);
+	cl_assert_equal_s("bcd", item->path);
+	cl_assert_equal_i(20, item->value);
+	cl_assert(git_sortedcache_entry(sc, 3) == NULL);
+
+	/* should not need to reload this time */
+
+	cl_assert_equal_i(0, git_sortedcache_lockandload(sc, NULL));
+
+	/* rewrite ondisk file and reload */
+
+	cl_assert_equal_i(0, free_count);
+
+	cl_git_rewritefile(
+		"cacheitems.txt", "100 abc\n200 zzz\n500 aaa\n10 final\n");
+	sortedcache_test_reload(sc);
+
+	cl_assert_equal_i(3, free_count);
+
+	/* test what we loaded */
+
+	cl_assert_equal_sz(4, git_sortedcache_entrycount(sc));
+
+	cl_assert((item = git_sortedcache_lookup(sc, "abc")) != NULL);
+	cl_assert_equal_s("abc", item->path);
+	cl_assert_equal_i(100, item->value);
+	cl_assert((item = git_sortedcache_lookup(sc, "final")) != NULL);
+	cl_assert_equal_s("final", item->path);
+	cl_assert_equal_i(10, item->value);
+	cl_assert(git_sortedcache_lookup(sc, "cde") == NULL);
+
+	cl_assert((item = git_sortedcache_entry(sc, 0)) != NULL);
+	cl_assert_equal_s("aaa", item->path);
+	cl_assert_equal_i(500, item->value);
+	cl_assert((item = git_sortedcache_entry(sc, 2)) != NULL);
+	cl_assert_equal_s("final", item->path);
+	cl_assert_equal_i(10, item->value);
+	cl_assert((item = git_sortedcache_entry(sc, 3)) != NULL);
+	cl_assert_equal_s("zzz", item->path);
+	cl_assert_equal_i(200, item->value);
+
+	cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "aaa"));
+	cl_assert_equal_sz(0, pos);
+	cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "abc"));
+	cl_assert_equal_sz(1, pos);
+	cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "final"));
+	cl_assert_equal_sz(2, pos);
+	cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "zzz"));
+	cl_assert_equal_sz(3, pos);
+	cl_assert_equal_i(
+		GIT_ENOTFOUND, git_sortedcache_lookup_index(&pos, sc, "missing"));
+	cl_assert_equal_i(
+		GIT_ENOTFOUND, git_sortedcache_lookup_index(&pos, sc, "cde"));
+
+	git_sortedcache_free(sc);
+
+	cl_assert_equal_i(7, free_count);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/stat.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/stat.c
new file mode 100755
index 0000000..bd9b990
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/stat.c
@@ -0,0 +1,114 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "path.h"
+#include "posix.h"
+
+void test_core_stat__initialize(void)
+{
+	cl_git_pass(git_futils_mkdir("root/d1/d2", NULL, 0755, GIT_MKDIR_PATH));
+	cl_git_mkfile("root/file", "whatever\n");
+	cl_git_mkfile("root/d1/file", "whatever\n");
+}
+
+void test_core_stat__cleanup(void)
+{
+	git_futils_rmdir_r("root", NULL, GIT_RMDIR_REMOVE_FILES);
+}
+
+#define cl_assert_error(val) \
+	do { err = errno; cl_assert_equal_i((val), err); } while (0)
+
+void test_core_stat__0(void)
+{
+	struct stat st;
+	int err;
+
+	cl_assert_equal_i(0, p_lstat("root", &st));
+	cl_assert(S_ISDIR(st.st_mode));
+	cl_assert_error(0);
+
+	cl_assert_equal_i(0, p_lstat("root/", &st));
+	cl_assert(S_ISDIR(st.st_mode));
+	cl_assert_error(0);
+
+	cl_assert_equal_i(0, p_lstat("root/file", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert_error(0);
+
+	cl_assert_equal_i(0, p_lstat("root/d1", &st));
+	cl_assert(S_ISDIR(st.st_mode));
+	cl_assert_error(0);
+
+	cl_assert_equal_i(0, p_lstat("root/d1/", &st));
+	cl_assert(S_ISDIR(st.st_mode));
+	cl_assert_error(0);
+
+	cl_assert_equal_i(0, p_lstat("root/d1/file", &st));
+	cl_assert(S_ISREG(st.st_mode));
+	cl_assert_error(0);
+
+	cl_assert(p_lstat("root/missing", &st) < 0);
+	cl_assert_error(ENOENT);
+
+	cl_assert(p_lstat("root/missing/but/could/be/created", &st) < 0);
+	cl_assert_error(ENOENT);
+
+	cl_assert(p_lstat_posixly("root/missing/but/could/be/created", &st) < 0);
+	cl_assert_error(ENOENT);
+
+	cl_assert(p_lstat("root/d1/missing", &st) < 0);
+	cl_assert_error(ENOENT);
+
+	cl_assert(p_lstat("root/d1/missing/deeper/path", &st) < 0);
+	cl_assert_error(ENOENT);
+
+	cl_assert(p_lstat_posixly("root/d1/missing/deeper/path", &st) < 0);
+	cl_assert_error(ENOENT);
+
+	cl_assert(p_lstat_posixly("root/d1/file/deeper/path", &st) < 0);
+	cl_assert_error(ENOTDIR);
+
+	cl_assert(p_lstat("root/file/invalid", &st) < 0);
+#ifdef GIT_WIN32
+	cl_assert_error(ENOENT);
+#else
+	cl_assert_error(ENOTDIR);
+#endif
+
+	cl_assert(p_lstat_posixly("root/file/invalid", &st) < 0);
+	cl_assert_error(ENOTDIR);
+
+	cl_assert(p_lstat("root/file/invalid/deeper_path", &st) < 0);
+#ifdef GIT_WIN32
+	cl_assert_error(ENOENT);
+#else
+	cl_assert_error(ENOTDIR);
+#endif
+
+	cl_assert(p_lstat_posixly("root/file/invalid/deeper_path", &st) < 0);
+	cl_assert_error(ENOTDIR);
+
+	cl_assert(p_lstat_posixly("root/d1/file/extra", &st) < 0);
+	cl_assert_error(ENOTDIR);
+
+	cl_assert(p_lstat_posixly("root/d1/file/further/invalid/items", &st) < 0);
+	cl_assert_error(ENOTDIR);
+}
+
+void test_core_stat__root(void)
+{
+	const char *sandbox = clar_sandbox_path();
+	git_buf root = GIT_BUF_INIT;
+	int root_len;
+	struct stat st;
+
+	root_len = git_path_root(sandbox);
+	cl_assert(root_len >= 0);
+
+	git_buf_set(&root, sandbox, root_len+1);
+
+	cl_must_pass(p_stat(root.ptr, &st));
+	cl_assert(S_ISDIR(st.st_mode));
+
+	git_buf_free(&root);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/string.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/string.c
new file mode 100755
index 0000000..90e8fa0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/string.c
@@ -0,0 +1,83 @@
+#include "clar_libgit2.h"
+
+/* compare prefixes */
+void test_core_string__0(void)
+{
+	cl_assert(git__prefixcmp("", "") == 0);
+	cl_assert(git__prefixcmp("a", "") == 0);
+	cl_assert(git__prefixcmp("", "a") < 0);
+	cl_assert(git__prefixcmp("a", "b") < 0);
+	cl_assert(git__prefixcmp("b", "a") > 0);
+	cl_assert(git__prefixcmp("ab", "a") == 0);
+	cl_assert(git__prefixcmp("ab", "ac") < 0);
+	cl_assert(git__prefixcmp("ab", "aa") > 0);
+}
+
+/* compare suffixes */
+void test_core_string__1(void)
+{
+	cl_assert(git__suffixcmp("", "") == 0);
+	cl_assert(git__suffixcmp("a", "") == 0);
+	cl_assert(git__suffixcmp("", "a") < 0);
+	cl_assert(git__suffixcmp("a", "b") < 0);
+	cl_assert(git__suffixcmp("b", "a") > 0);
+	cl_assert(git__suffixcmp("ba", "a") == 0);
+	cl_assert(git__suffixcmp("zaa", "ac") < 0);
+	cl_assert(git__suffixcmp("zaz", "ac") > 0);
+}
+
+/* compare icase sorting with case equality */
+void test_core_string__2(void)
+{
+	cl_assert(git__strcasesort_cmp("", "") == 0);
+	cl_assert(git__strcasesort_cmp("foo", "foo") == 0);
+	cl_assert(git__strcasesort_cmp("foo", "bar") > 0);
+	cl_assert(git__strcasesort_cmp("bar", "foo") < 0);
+	cl_assert(git__strcasesort_cmp("foo", "FOO") > 0);
+	cl_assert(git__strcasesort_cmp("FOO", "foo") < 0);
+	cl_assert(git__strcasesort_cmp("foo", "BAR") > 0);
+	cl_assert(git__strcasesort_cmp("BAR", "foo") < 0);
+	cl_assert(git__strcasesort_cmp("fooBar", "foobar") < 0);
+}
+
+void test_core_string__strcmp(void)
+{
+	cl_assert(git__strcmp("", "") == 0);
+	cl_assert(git__strcmp("foo", "foo") == 0);
+	cl_assert(git__strcmp("Foo", "foo") < 0);
+	cl_assert(git__strcmp("foo", "FOO") > 0);
+	cl_assert(git__strcmp("foo", "fOO") > 0);
+
+	cl_assert(strcmp("rt\303\202of", "rt dev\302\266h") > 0);
+	cl_assert(strcmp("e\342\202\254ghi=", "et") > 0);
+	cl_assert(strcmp("rt dev\302\266h", "rt\303\202of") < 0);
+	cl_assert(strcmp("et", "e\342\202\254ghi=") < 0);
+	cl_assert(strcmp("\303\215", "\303\255") < 0);
+
+	cl_assert(git__strcmp("rt\303\202of", "rt dev\302\266h") > 0);
+	cl_assert(git__strcmp("e\342\202\254ghi=", "et") > 0);
+	cl_assert(git__strcmp("rt dev\302\266h", "rt\303\202of") < 0);
+	cl_assert(git__strcmp("et", "e\342\202\254ghi=") < 0);
+	cl_assert(git__strcmp("\303\215", "\303\255") < 0);
+}
+
+void test_core_string__strcasecmp(void)
+{
+	cl_assert(git__strcasecmp("", "") == 0);
+	cl_assert(git__strcasecmp("foo", "foo") == 0);
+	cl_assert(git__strcasecmp("foo", "Foo") == 0);
+	cl_assert(git__strcasecmp("foo", "FOO") == 0);
+	cl_assert(git__strcasecmp("foo", "fOO") == 0);
+
+	cl_assert(strcasecmp("rt\303\202of", "rt dev\302\266h") > 0);
+	cl_assert(strcasecmp("e\342\202\254ghi=", "et") > 0);
+	cl_assert(strcasecmp("rt dev\302\266h", "rt\303\202of") < 0);
+	cl_assert(strcasecmp("et", "e\342\202\254ghi=") < 0);
+	cl_assert(strcasecmp("\303\215", "\303\255") < 0);
+
+	cl_assert(git__strcasecmp("rt\303\202of", "rt dev\302\266h") > 0);
+	cl_assert(git__strcasecmp("e\342\202\254ghi=", "et") > 0);
+	cl_assert(git__strcasecmp("rt dev\302\266h", "rt\303\202of") < 0);
+	cl_assert(git__strcasecmp("et", "e\342\202\254ghi=") < 0);
+	cl_assert(git__strcasecmp("\303\215", "\303\255") < 0);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/strmap.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/strmap.c
new file mode 100755
index 0000000..3b4276a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/strmap.c
@@ -0,0 +1,100 @@
+#include "clar_libgit2.h"
+#include "strmap.h"
+
+GIT__USE_STRMAP
+
+git_strmap *g_table;
+
+void test_core_strmap__initialize(void)
+{
+	cl_git_pass(git_strmap_alloc(&g_table));
+	cl_assert(g_table != NULL);
+}
+
+void test_core_strmap__cleanup(void)
+{
+	git_strmap_free(g_table);
+}
+
+void test_core_strmap__0(void)
+{
+	cl_assert(git_strmap_num_entries(g_table) == 0);
+}
+
+static void insert_strings(git_strmap *table, int count)
+{
+	int i, j, over, err;
+	char *str;
+
+	for (i = 0; i < count; ++i) {
+		str = malloc(10);
+		for (j = 0; j < 10; ++j)
+			str[j] = 'a' + (i % 26);
+		str[9] = '\0';
+
+		/* if > 26, then encode larger value in first letters */
+		for (j = 0, over = i / 26; over > 0; j++, over = over / 26)
+			str[j] = 'A' + (over % 26);
+
+		git_strmap_insert(table, str, str, err);
+		cl_assert(err >= 0);
+	}
+
+	cl_assert((int)git_strmap_num_entries(table) == count);
+}
+
+void test_core_strmap__1(void)
+{
+	int i;
+	char *str;
+
+	insert_strings(g_table, 20);
+
+	cl_assert(git_strmap_exists(g_table, "aaaaaaaaa"));
+	cl_assert(git_strmap_exists(g_table, "ggggggggg"));
+	cl_assert(!git_strmap_exists(g_table, "aaaaaaaab"));
+	cl_assert(!git_strmap_exists(g_table, "abcdefghi"));
+
+	i = 0;
+	git_strmap_foreach_value(g_table, str, { i++; free(str); });
+	cl_assert(i == 20);
+}
+
+void test_core_strmap__2(void)
+{
+	khiter_t pos;
+	int i;
+	char *str;
+
+	insert_strings(g_table, 20);
+
+	cl_assert(git_strmap_exists(g_table, "aaaaaaaaa"));
+	cl_assert(git_strmap_exists(g_table, "ggggggggg"));
+	cl_assert(!git_strmap_exists(g_table, "aaaaaaaab"));
+	cl_assert(!git_strmap_exists(g_table, "abcdefghi"));
+
+	cl_assert(git_strmap_exists(g_table, "bbbbbbbbb"));
+	pos = git_strmap_lookup_index(g_table, "bbbbbbbbb");
+	cl_assert(git_strmap_valid_index(g_table, pos));
+	cl_assert_equal_s(git_strmap_value_at(g_table, pos), "bbbbbbbbb");
+	free(git_strmap_value_at(g_table, pos));
+	git_strmap_delete_at(g_table, pos);
+
+	cl_assert(!git_strmap_exists(g_table, "bbbbbbbbb"));
+
+	i = 0;
+	git_strmap_foreach_value(g_table, str, { i++; free(str); });
+	cl_assert(i == 19);
+}
+
+void test_core_strmap__3(void)
+{
+	int i;
+	char *str;
+
+	insert_strings(g_table, 10000);
+
+	i = 0;
+	git_strmap_foreach_value(g_table, str, { i++; free(str); });
+	cl_assert(i == 10000);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/strtol.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/strtol.c
new file mode 100755
index 0000000..8765e04
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/strtol.c
@@ -0,0 +1,37 @@
+#include "clar_libgit2.h"
+
+void test_core_strtol__int32(void)
+{
+	int32_t i;
+
+	cl_git_pass(git__strtol32(&i, "123", NULL, 10));
+	cl_assert(i == 123);
+	cl_git_pass(git__strtol32(&i, "  +123 ", NULL, 10));
+	cl_assert(i == 123);
+	cl_git_pass(git__strtol32(&i, "  +2147483647 ", NULL, 10));
+	cl_assert(i == 2147483647);
+	cl_git_pass(git__strtol32(&i, "  -2147483648 ", NULL, 10));
+	cl_assert(i == -2147483648LL);
+	
+	cl_git_fail(git__strtol32(&i, "  2147483657 ", NULL, 10));
+	cl_git_fail(git__strtol32(&i, "  -2147483657 ", NULL, 10));
+}
+
+void test_core_strtol__int64(void)
+{
+	int64_t i;
+
+	cl_git_pass(git__strtol64(&i, "123", NULL, 10));
+	cl_assert(i == 123);
+	cl_git_pass(git__strtol64(&i, "  +123 ", NULL, 10));
+	cl_assert(i == 123);
+	cl_git_pass(git__strtol64(&i, "  +2147483647 ", NULL, 10));
+	cl_assert(i == 2147483647);
+	cl_git_pass(git__strtol64(&i, "  -2147483648 ", NULL, 10));
+	cl_assert(i == -2147483648LL);
+	cl_git_pass(git__strtol64(&i, "  2147483657 ", NULL, 10));
+	cl_assert(i == 2147483657LL);
+	cl_git_pass(git__strtol64(&i, "  -2147483657 ", NULL, 10));
+	cl_assert(i == -2147483657LL);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/structinit.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/structinit.c
new file mode 100755
index 0000000..e9f7b4a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/structinit.c
@@ -0,0 +1,168 @@
+#include "clar_libgit2.h"
+#include <git2/sys/config.h>
+#include <git2/sys/odb_backend.h>
+#include <git2/sys/refdb_backend.h>
+#include <git2/sys/transport.h>
+
+#define STRINGIFY(s) #s
+
+/* Checks two conditions for the specified structure:
+ *     1. That the initializers for the latest version produces the same
+ *        in-memory representation.
+ *     2. That the function-based initializer supports all versions from 1...n,
+ *        where n is the latest version (often represented by GIT_*_VERSION).
+ *
+ * Parameters:
+ *     structname: The name of the structure to test, e.g. git_blame_options.
+ *     structver: The latest version of the specified structure.
+ *     macroinit: The macro that initializes the latest version of the structure.
+ *     funcinitname: The function that initializes the structure. Must have the
+ *                   signature "int (structname* instance, int version)".
+ */
+#define CHECK_MACRO_FUNC_INIT_EQUAL(structname, structver, macroinit, funcinitname) \
+do { \
+	structname structname##_macro_latest = macroinit; \
+	structname structname##_func_latest; \
+	int structname##_curr_ver = structver - 1; \
+	memset(&structname##_func_latest, 0, sizeof(structname##_func_latest)); \
+	cl_git_pass(funcinitname(&structname##_func_latest, structver)); \
+	options_cmp(&structname##_macro_latest, &structname##_func_latest, \
+		sizeof(structname), STRINGIFY(structname)); \
+	\
+	while (structname##_curr_ver > 0) \
+	{ \
+		structname macro; \
+		cl_git_pass(funcinitname(&macro, structname##_curr_ver)); \
+		structname##_curr_ver--; \
+	}\
+} while(0)
+
+static void options_cmp(void *one, void *two, size_t size, const char *name)
+{
+	size_t i;
+
+	for (i = 0; i < size; i++) {
+		if (((char *)one)[i] != ((char *)two)[i]) {
+			char desc[1024];
+
+			p_snprintf(desc, 1024, "Difference in %s at byte %" PRIuZ ": macro=%u / func=%u",
+				name, i, ((char *)one)[i], ((char *)two)[i]);
+			clar__fail(__FILE__, __LINE__,
+				"Difference between macro and function options initializer",
+				desc, 0);
+			return;
+		}
+	}
+}
+
+void test_core_structinit__compare(void)
+{
+	/* These tests assume that they can memcmp() two structures that were
+	 * initialized with the same static initializer.  Eg,
+	 * git_blame_options = GIT_BLAME_OPTIONS_INIT;
+	 *
+	 * This assumption fails when there is padding between structure members,
+	 * which is not guaranteed to be initialized to anything sane at all.
+	 *
+	 * Assume most compilers, in a debug build, will clear that memory for
+	 * us or set it to sentinal markers.  Etc.
+	 */
+#if !defined(DEBUG) && !defined(_DEBUG)
+	clar__skip();
+#endif
+
+	/* blame */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_blame_options, GIT_BLAME_OPTIONS_VERSION, \
+		GIT_BLAME_OPTIONS_INIT, git_blame_init_options);
+
+	/* checkout */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_checkout_options, GIT_CHECKOUT_OPTIONS_VERSION, \
+		GIT_CHECKOUT_OPTIONS_INIT, git_checkout_init_options);
+
+	/* clone */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_clone_options, GIT_CLONE_OPTIONS_VERSION, \
+		GIT_CLONE_OPTIONS_INIT, git_clone_init_options);
+
+	/* diff */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_diff_options, GIT_DIFF_OPTIONS_VERSION, \
+		GIT_DIFF_OPTIONS_INIT, git_diff_init_options);
+
+	/* diff_find */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_diff_find_options, GIT_DIFF_FIND_OPTIONS_VERSION, \
+		GIT_DIFF_FIND_OPTIONS_INIT, git_diff_find_init_options);
+
+	/* merge_file_input */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_merge_file_input, GIT_MERGE_FILE_INPUT_VERSION, \
+		GIT_MERGE_FILE_INPUT_INIT, git_merge_file_init_input);
+
+	/* merge_file */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_merge_file_options, GIT_MERGE_FILE_OPTIONS_VERSION, \
+		GIT_MERGE_FILE_OPTIONS_INIT, git_merge_file_init_options);
+
+	/* merge_tree */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_merge_options, GIT_MERGE_OPTIONS_VERSION, \
+		GIT_MERGE_OPTIONS_INIT, git_merge_init_options);
+
+	/* push */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_push_options, GIT_PUSH_OPTIONS_VERSION, \
+		GIT_PUSH_OPTIONS_INIT, git_push_init_options);
+
+	/* remote */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_remote_callbacks, GIT_REMOTE_CALLBACKS_VERSION, \
+		GIT_REMOTE_CALLBACKS_INIT, git_remote_init_callbacks);
+
+	/* repository_init */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_repository_init_options, GIT_REPOSITORY_INIT_OPTIONS_VERSION, \
+		GIT_REPOSITORY_INIT_OPTIONS_INIT, git_repository_init_init_options);
+
+	/* revert */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_revert_options, GIT_REVERT_OPTIONS_VERSION, \
+		GIT_REVERT_OPTIONS_INIT, git_revert_init_options);
+
+	/* stash apply */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_stash_apply_options, GIT_STASH_APPLY_OPTIONS_VERSION, \
+		GIT_STASH_APPLY_OPTIONS_INIT, git_stash_apply_init_options);
+
+	/* status */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_status_options, GIT_STATUS_OPTIONS_VERSION, \
+		GIT_STATUS_OPTIONS_INIT, git_status_init_options);
+
+	/* transport */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_transport, GIT_TRANSPORT_VERSION, \
+		GIT_TRANSPORT_INIT, git_transport_init);
+
+	/* config_backend */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_config_backend, GIT_CONFIG_BACKEND_VERSION, \
+		GIT_CONFIG_BACKEND_INIT, git_config_init_backend);
+
+	/* odb_backend */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_odb_backend, GIT_ODB_BACKEND_VERSION, \
+		GIT_ODB_BACKEND_INIT, git_odb_init_backend);
+
+	/* refdb_backend */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_refdb_backend, GIT_REFDB_BACKEND_VERSION, \
+		GIT_REFDB_BACKEND_INIT, git_refdb_init_backend);
+
+	/* submodule update */
+	CHECK_MACRO_FUNC_INIT_EQUAL( \
+		git_submodule_update_options, GIT_SUBMODULE_UPDATE_OPTIONS_VERSION, \
+		GIT_SUBMODULE_UPDATE_OPTIONS_INIT, git_submodule_update_init_options);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/vector.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/vector.c
new file mode 100755
index 0000000..66f90b8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/vector.c
@@ -0,0 +1,276 @@
+#include "clar_libgit2.h"
+#include "vector.h"
+
+/* initial size of 1 would cause writing past array bounds */
+void test_core_vector__0(void)
+{
+	git_vector x;
+	int i;
+	git_vector_init(&x, 1, NULL);
+	for (i = 0; i < 10; ++i) {
+		git_vector_insert(&x, (void*) 0xabc);
+	}
+	git_vector_free(&x);
+}
+
+
+/* don't read past array bounds on remove() */
+void test_core_vector__1(void)
+{
+	git_vector x;
+	// make initial capacity exact for our insertions.
+	git_vector_init(&x, 3, NULL);
+	git_vector_insert(&x, (void*) 0xabc);
+	git_vector_insert(&x, (void*) 0xdef);
+	git_vector_insert(&x, (void*) 0x123);
+
+	git_vector_remove(&x, 0); // used to read past array bounds.
+	git_vector_free(&x);
+}
+
+
+static int test_cmp(const void *a, const void *b)
+{
+	return *(const int *)a - *(const int *)b;
+}
+
+/* remove duplicates */
+void test_core_vector__2(void)
+{
+	git_vector x;
+	int *ptrs[2];
+
+	ptrs[0] = git__malloc(sizeof(int));
+	ptrs[1] = git__malloc(sizeof(int));
+
+	*ptrs[0] = 2;
+	*ptrs[1] = 1;
+
+	cl_git_pass(git_vector_init(&x, 5, test_cmp));
+	cl_git_pass(git_vector_insert(&x, ptrs[0]));
+	cl_git_pass(git_vector_insert(&x, ptrs[1]));
+	cl_git_pass(git_vector_insert(&x, ptrs[1]));
+	cl_git_pass(git_vector_insert(&x, ptrs[0]));
+	cl_git_pass(git_vector_insert(&x, ptrs[1]));
+	cl_assert(x.length == 5);
+
+	git_vector_uniq(&x, NULL);
+	cl_assert(x.length == 2);
+
+	git_vector_free(&x);
+
+	git__free(ptrs[0]);
+	git__free(ptrs[1]);
+}
+
+
+static int compare_them(const void *a, const void *b)
+{
+	return (int)((long)a - (long)b);
+}
+
+/* insert_sorted */
+void test_core_vector__3(void)
+{
+	git_vector x;
+	long i;
+	git_vector_init(&x, 1, &compare_them);
+
+	for (i = 0; i < 10; i += 2) {
+		git_vector_insert_sorted(&x, (void*)(i + 1), NULL);
+	}
+
+	for (i = 9; i > 0; i -= 2) {
+		git_vector_insert_sorted(&x, (void*)(i + 1), NULL);
+	}
+
+	cl_assert(x.length == 10);
+	for (i = 0; i < 10; ++i) {
+		cl_assert(git_vector_get(&x, i) == (void*)(i + 1));
+	}
+
+	git_vector_free(&x);
+}
+
+/* insert_sorted with duplicates */
+void test_core_vector__4(void)
+{
+	git_vector x;
+	long i;
+	git_vector_init(&x, 1, &compare_them);
+
+	for (i = 0; i < 10; i += 2) {
+		git_vector_insert_sorted(&x, (void*)(i + 1), NULL);
+	}
+
+	for (i = 9; i > 0; i -= 2) {
+		git_vector_insert_sorted(&x, (void*)(i + 1), NULL);
+	}
+
+	for (i = 0; i < 10; i += 2) {
+		git_vector_insert_sorted(&x, (void*)(i + 1), NULL);
+	}
+
+	for (i = 9; i > 0; i -= 2) {
+		git_vector_insert_sorted(&x, (void*)(i + 1), NULL);
+	}
+
+	cl_assert(x.length == 20);
+	for (i = 0; i < 20; ++i) {
+		cl_assert(git_vector_get(&x, i) == (void*)(i / 2 + 1));
+	}
+
+	git_vector_free(&x);
+}
+
+typedef struct {
+	int content;
+	int count;
+} my_struct;
+
+static int _struct_count = 0;
+
+static int compare_structs(const void *a, const void *b)
+{
+	return ((const my_struct *)a)->content -
+		((const my_struct *)b)->content;
+}
+
+static int merge_structs(void **old_raw, void *new)
+{
+	my_struct *old = *(my_struct **)old_raw;
+	cl_assert(((my_struct *)old)->content == ((my_struct *)new)->content);
+	((my_struct *)old)->count += 1;
+	git__free(new);
+	_struct_count--;
+	return GIT_EEXISTS;
+}
+
+static my_struct *alloc_struct(int value)
+{
+	my_struct *st = git__malloc(sizeof(my_struct));
+	st->content = value;
+	st->count = 0;
+	_struct_count++;
+	return st;
+}
+
+/* insert_sorted with duplicates and special handling */
+void test_core_vector__5(void)
+{
+	git_vector x;
+	int i;
+
+	git_vector_init(&x, 1, &compare_structs);
+
+	for (i = 0; i < 10; i += 2)
+		git_vector_insert_sorted(&x, alloc_struct(i), &merge_structs);
+
+	for (i = 9; i > 0; i -= 2)
+		git_vector_insert_sorted(&x, alloc_struct(i), &merge_structs);
+
+	cl_assert(x.length == 10);
+	cl_assert(_struct_count == 10);
+
+	for (i = 0; i < 10; i += 2)
+		git_vector_insert_sorted(&x, alloc_struct(i), &merge_structs);
+
+	for (i = 9; i > 0; i -= 2)
+		git_vector_insert_sorted(&x, alloc_struct(i), &merge_structs);
+
+	cl_assert(x.length == 10);
+	cl_assert(_struct_count == 10);
+
+	for (i = 0; i < 10; ++i) {
+		cl_assert(((my_struct *)git_vector_get(&x, i))->content == i);
+		git__free(git_vector_get(&x, i));
+		_struct_count--;
+	}
+
+	git_vector_free(&x);
+}
+
+static int remove_ones(const git_vector *v, size_t idx, void *p)
+{
+	GIT_UNUSED(p);
+	return (git_vector_get(v, idx) == (void *)0x001);
+}
+
+/* Test removal based on callback */
+void test_core_vector__remove_matching(void)
+{
+	git_vector x;
+	size_t i;
+	void *compare;
+
+	git_vector_init(&x, 1, NULL);
+	git_vector_insert(&x, (void*) 0x001);
+
+	cl_assert(x.length == 1);
+	git_vector_remove_matching(&x, remove_ones, NULL);
+	cl_assert(x.length == 0);
+
+	git_vector_insert(&x, (void*) 0x001);
+	git_vector_insert(&x, (void*) 0x001);
+	git_vector_insert(&x, (void*) 0x001);
+
+	cl_assert(x.length == 3);
+	git_vector_remove_matching(&x, remove_ones, NULL);
+	cl_assert(x.length == 0);
+
+	git_vector_insert(&x, (void*) 0x002);
+	git_vector_insert(&x, (void*) 0x001);
+	git_vector_insert(&x, (void*) 0x002);
+	git_vector_insert(&x, (void*) 0x001);
+
+	cl_assert(x.length == 4);
+	git_vector_remove_matching(&x, remove_ones, NULL);
+	cl_assert(x.length == 2);
+
+	git_vector_foreach(&x, i, compare) {
+		cl_assert(compare != (void *)0x001);
+	}
+
+	git_vector_clear(&x);
+
+	git_vector_insert(&x, (void*) 0x001);
+	git_vector_insert(&x, (void*) 0x002);
+	git_vector_insert(&x, (void*) 0x002);
+	git_vector_insert(&x, (void*) 0x001);
+
+	cl_assert(x.length == 4);
+	git_vector_remove_matching(&x, remove_ones, NULL);
+	cl_assert(x.length == 2);
+
+	git_vector_foreach(&x, i, compare) {
+		cl_assert(compare != (void *)0x001);
+	}
+
+	git_vector_clear(&x);
+
+	git_vector_insert(&x, (void*) 0x002);
+	git_vector_insert(&x, (void*) 0x001);
+	git_vector_insert(&x, (void*) 0x002);
+	git_vector_insert(&x, (void*) 0x001);
+
+	cl_assert(x.length == 4);
+	git_vector_remove_matching(&x, remove_ones, NULL);
+	cl_assert(x.length == 2);
+
+	git_vector_foreach(&x, i, compare) {
+		cl_assert(compare != (void *)0x001);
+	}
+
+	git_vector_clear(&x);
+
+	git_vector_insert(&x, (void*) 0x002);
+	git_vector_insert(&x, (void*) 0x003);
+	git_vector_insert(&x, (void*) 0x002);
+	git_vector_insert(&x, (void*) 0x003);
+
+	cl_assert(x.length == 4);
+	git_vector_remove_matching(&x, remove_ones, NULL);
+	cl_assert(x.length == 4);
+
+	git_vector_free(&x);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/zstream.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/zstream.c
new file mode 100755
index 0000000..7ba9424
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/core/zstream.c
@@ -0,0 +1,143 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "zstream.h"
+
+static const char *data = "This is a test test test of This is a test";
+
+#define INFLATE_EXTRA 2
+
+static void assert_zlib_equal_(
+	const void *expected, size_t e_len,
+	const void *compressed, size_t c_len,
+	const char *msg, const char *file, int line)
+{
+	z_stream stream;
+	char *expanded = git__calloc(1, e_len + INFLATE_EXTRA);
+	cl_assert(expanded);
+
+	memset(&stream, 0, sizeof(stream));
+	stream.next_out  = (Bytef *)expanded;
+	stream.avail_out = (uInt)(e_len + INFLATE_EXTRA);
+	stream.next_in   = (Bytef *)compressed;
+	stream.avail_in  = (uInt)c_len;
+
+	cl_assert(inflateInit(&stream) == Z_OK);
+	cl_assert(inflate(&stream, Z_FINISH));
+	inflateEnd(&stream);
+
+	clar__assert_equal(
+		file, line, msg, 1,
+		"%d", (int)stream.total_out, (int)e_len);
+	clar__assert_equal(
+		file, line, "Buffer len was not exact match", 1,
+		"%d", (int)stream.avail_out, (int)INFLATE_EXTRA);
+
+	clar__assert(
+		memcmp(expanded, expected, e_len) == 0,
+		file, line, "uncompressed data did not match", NULL, 1);
+
+	git__free(expanded);
+}
+
+#define assert_zlib_equal(E,EL,C,CL) \
+	assert_zlib_equal_(E, EL, C, CL, #EL " != " #CL, __FILE__, (int)__LINE__)
+
+void test_core_zstream__basic(void)
+{
+	git_zstream z = GIT_ZSTREAM_INIT;
+	char out[128];
+	size_t outlen = sizeof(out);
+
+	cl_git_pass(git_zstream_init(&z));
+	cl_git_pass(git_zstream_set_input(&z, data, strlen(data) + 1));
+	cl_git_pass(git_zstream_get_output(out, &outlen, &z));
+	cl_assert(git_zstream_done(&z));
+	cl_assert(outlen > 0);
+	git_zstream_free(&z);
+
+	assert_zlib_equal(data, strlen(data) + 1, out, outlen);
+}
+
+void test_core_zstream__buffer(void)
+{
+	git_buf out = GIT_BUF_INIT;
+	cl_git_pass(git_zstream_deflatebuf(&out, data, strlen(data) + 1));
+	assert_zlib_equal(data, strlen(data) + 1, out.ptr, out.size);
+	git_buf_free(&out);
+}
+
+#define BIG_STRING_PART "Big Data IS Big - Long Data IS Long - We need a buffer larger than 1024 x 1024 to make sure we trigger chunked compression - Big Big Data IS Bigger than Big - Long Long Data IS Longer than Long"
+
+static void compress_input_various_ways(git_buf *input)
+{
+	git_buf out1 = GIT_BUF_INIT, out2 = GIT_BUF_INIT;
+	size_t i, fixed_size = max(input->size / 2, 256);
+	char *fixed = git__malloc(fixed_size);
+	cl_assert(fixed);
+
+	/* compress with deflatebuf */
+
+	cl_git_pass(git_zstream_deflatebuf(&out1, input->ptr, input->size));
+	assert_zlib_equal(input->ptr, input->size, out1.ptr, out1.size);
+
+	/* compress with various fixed size buffer (accumulating the output) */
+
+	for (i = 0; i < 3; ++i) {
+		git_zstream zs = GIT_ZSTREAM_INIT;
+		size_t use_fixed_size;
+
+		switch (i) {
+		case 0: use_fixed_size = 256; break;
+		case 1: use_fixed_size = fixed_size / 2; break;
+		case 2: use_fixed_size = fixed_size; break;
+		}
+		cl_assert(use_fixed_size <= fixed_size);
+
+		cl_git_pass(git_zstream_init(&zs));
+		cl_git_pass(git_zstream_set_input(&zs, input->ptr, input->size));
+
+		while (!git_zstream_done(&zs)) {
+			size_t written = use_fixed_size;
+			cl_git_pass(git_zstream_get_output(fixed, &written, &zs));
+			cl_git_pass(git_buf_put(&out2, fixed, written));
+		}
+
+		git_zstream_free(&zs);
+		assert_zlib_equal(input->ptr, input->size, out2.ptr, out2.size);
+
+		/* did both approaches give the same data? */
+		cl_assert_equal_sz(out1.size, out2.size);
+		cl_assert(!memcmp(out1.ptr, out2.ptr, out1.size));
+
+		git_buf_free(&out2);
+	}
+
+	git_buf_free(&out1);
+	git__free(fixed);
+}
+
+void test_core_zstream__big_data(void)
+{
+	git_buf in = GIT_BUF_INIT;
+	size_t scan, target;
+
+	for (target = 1024; target <= 1024 * 1024 * 4; target *= 8) {
+
+		/* make a big string that's easy to compress */
+		git_buf_clear(&in);
+		while (in.size < target)
+			cl_git_pass(
+				git_buf_put(&in, BIG_STRING_PART, strlen(BIG_STRING_PART)));
+
+		compress_input_various_ways(&in);
+
+		/* make a big string that's hard to compress */
+		srand(0xabad1dea);
+		for (scan = 0; scan < in.size; ++scan)
+			in.ptr[scan] = (char)rand();
+
+		compress_input_various_ways(&in);
+	}
+
+	git_buf_free(&in);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/date/date.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/date/date.c
new file mode 100755
index 0000000..88881d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/date/date.c
@@ -0,0 +1,15 @@
+#include "clar_libgit2.h"
+
+#include "util.h"
+
+void test_date_date__overflow(void)
+{
+#ifdef __LP64__
+   git_time_t d2038, d2039;
+
+   /* This is expected to fail on a 32-bit machine. */
+   cl_git_pass(git__date_parse(&d2038, "2038-1-1"));
+   cl_git_pass(git__date_parse(&d2039, "2039-1-1"));
+   cl_assert(d2038 < d2039);
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/date/rfc2822.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/date/rfc2822.c
new file mode 100755
index 0000000..eda475a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/date/rfc2822.c
@@ -0,0 +1,40 @@
+#include "clar_libgit2.h"
+
+#include "util.h"
+
+void test_date_rfc2822__format_rfc2822_no_offset(void)
+{
+	git_time t = {1397031663, 0};
+	char buf[GIT_DATE_RFC2822_SZ];
+
+	cl_git_pass(git__date_rfc2822_fmt(buf, sizeof(buf), &t));
+	cl_assert(strcmp(buf, "Wed, 9 Apr 2014 08:21:03 +0000") == 0);
+}
+
+void test_date_rfc2822__format_rfc2822_positive_offset(void)
+{
+	git_time t = {1397031663, 120};
+	char buf[GIT_DATE_RFC2822_SZ];
+
+	cl_git_pass(git__date_rfc2822_fmt(buf, sizeof(buf), &t));
+	cl_assert(strcmp(buf, "Wed, 9 Apr 2014 10:21:03 +0200") == 0);
+}
+
+void test_date_rfc2822__format_rfc2822_negative_offset(void)
+{
+	git_time t = {1397031663, -120};
+	char buf[GIT_DATE_RFC2822_SZ];
+
+	cl_git_pass(git__date_rfc2822_fmt(buf, sizeof(buf), &t));
+	cl_assert(strcmp(buf, "Wed, 9 Apr 2014 06:21:03 -0200") == 0);
+}
+
+void test_date_rfc2822__format_rfc2822_buffer_too_small(void)
+{
+	// "Wed, 10 Apr 2014 08:21:03 +0000"
+	git_time t = {1397031663 + 86400, 0};
+	char buf[GIT_DATE_RFC2822_SZ-1];
+
+	cl_git_fail(git__date_rfc2822_fmt(buf, sizeof(buf), &t));
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/describe/describe.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/describe/describe.c
new file mode 100755
index 0000000..a8c57d8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/describe/describe.c
@@ -0,0 +1,55 @@
+#include "clar_libgit2.h"
+#include "describe_helpers.h"
+
+void test_describe_describe__can_describe_against_a_bare_repo(void)
+{
+	git_repository *repo;
+	git_describe_options opts = GIT_DESCRIBE_OPTIONS_INIT;
+	git_describe_format_options fmt_opts = GIT_DESCRIBE_FORMAT_OPTIONS_INIT;
+
+	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+
+	assert_describe("hard_tag", "HEAD", repo, &opts, &fmt_opts);
+
+	opts.show_commit_oid_as_fallback = 1;
+
+	assert_describe("be3563a*", "HEAD^", repo, &opts, &fmt_opts);
+
+	git_repository_free(repo);
+}
+
+static int delete_cb(git_reference *ref, void *payload)
+{
+	GIT_UNUSED(payload);
+
+	cl_git_pass(git_reference_delete(ref));
+	git_reference_free(ref);
+
+	return 0;
+}
+
+void test_describe_describe__describe_a_repo_with_no_refs(void)
+{
+	git_repository *repo;
+	git_describe_options opts = GIT_DESCRIBE_OPTIONS_INIT;
+	git_buf buf = GIT_BUF_INIT;
+	git_object *object;
+	git_describe_result *result = NULL;
+
+	repo = cl_git_sandbox_init("testrepo.git");
+	cl_git_pass(git_revparse_single(&object, repo, "HEAD"));
+
+	cl_git_pass(git_reference_foreach(repo, delete_cb, NULL));
+
+	/* Impossible to describe without falling back to OIDs */
+	cl_git_fail(git_describe_commit(&result, object, &opts));
+
+	/* Try again with OID fallbacks */
+	opts.show_commit_oid_as_fallback = 1;
+	cl_git_pass(git_describe_commit(&result, object, &opts));
+
+	git_describe_result_free(result);
+	git_object_free(object);
+	git_buf_free(&buf);
+	cl_git_sandbox_cleanup();
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/describe/describe_helpers.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/describe/describe_helpers.c
new file mode 100755
index 0000000..ad9c945
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/describe/describe_helpers.c
@@ -0,0 +1,42 @@
+#include "describe_helpers.h"
+
+void assert_describe(
+	const char *expected_output,
+	const char *revparse_spec,
+	git_repository *repo,
+	git_describe_options *opts,
+	git_describe_format_options *fmt_opts)
+{
+	git_object *object;
+	git_buf label = GIT_BUF_INIT;
+	git_describe_result *result;
+
+	cl_git_pass(git_revparse_single(&object, repo, revparse_spec));
+
+	cl_git_pass(git_describe_commit(&result, object, opts));
+	cl_git_pass(git_describe_format(&label, result, fmt_opts));
+
+	cl_must_pass(p_fnmatch(expected_output, git_buf_cstr(&label), 0));
+
+	git_describe_result_free(result);
+	git_object_free(object);
+	git_buf_free(&label);
+}
+
+void assert_describe_workdir(
+	const char *expected_output,
+	git_repository *repo,
+	git_describe_options *opts,
+	git_describe_format_options *fmt_opts)
+{
+	git_buf label = GIT_BUF_INIT;
+	git_describe_result *result;
+
+	cl_git_pass(git_describe_workdir(&result, repo, opts));
+	cl_git_pass(git_describe_format(&label, result, fmt_opts));
+
+	cl_must_pass(p_fnmatch(expected_output, git_buf_cstr(&label), 0));
+
+	git_describe_result_free(result);
+	git_buf_free(&label);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/describe/describe_helpers.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/describe/describe_helpers.h
new file mode 100755
index 0000000..16a0638
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/describe/describe_helpers.h
@@ -0,0 +1,15 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+
+extern void assert_describe(
+	const char *expected_output,
+	const char *revparse_spec,
+	git_repository *repo,
+	git_describe_options *opts,
+	git_describe_format_options *fmt_opts);
+
+extern void assert_describe_workdir(
+	const char *expected_output,
+	git_repository *repo,
+	git_describe_options *opts,
+	git_describe_format_options *fmt_opts);
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/describe/t6120.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/describe/t6120.c
new file mode 100755
index 0000000..6df397e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/describe/t6120.c
@@ -0,0 +1,156 @@
+#include "clar_libgit2.h"
+#include "describe_helpers.h"
+#include "repository.h"
+
+// Ported from https://github.com/git/git/blob/adfc1857bdb090786fd9d22c1acec39371c76048/t/t6120-describe.sh
+
+static git_repository *repo;
+
+void test_describe_t6120__initialize(void)
+{
+	repo = cl_git_sandbox_init("describe");
+}
+
+void test_describe_t6120__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_describe_t6120__default(void)
+{
+	git_describe_options opts = GIT_DESCRIBE_OPTIONS_INIT;
+	git_describe_format_options fmt_opts = GIT_DESCRIBE_FORMAT_OPTIONS_INIT;
+
+	assert_describe("A-*", "HEAD", repo, &opts, &fmt_opts);
+	assert_describe("A-*", "HEAD^", repo, &opts, &fmt_opts);
+	assert_describe("R-*", "HEAD^^", repo, &opts, &fmt_opts);
+	assert_describe("A-*", "HEAD^^2", repo, &opts, &fmt_opts);
+	assert_describe("B", "HEAD^^2^", repo, &opts, &fmt_opts);
+	assert_describe("R-*", "HEAD^^^", repo, &opts, &fmt_opts);
+}
+
+void test_describe_t6120__tags(void)
+{
+	git_describe_options opts = GIT_DESCRIBE_OPTIONS_INIT;
+	git_describe_format_options fmt_opts = GIT_DESCRIBE_FORMAT_OPTIONS_INIT;
+	opts.describe_strategy = GIT_DESCRIBE_TAGS;
+
+	assert_describe("c-*", "HEAD", repo, &opts, &fmt_opts);
+	assert_describe("c-*", "HEAD^", repo, &opts, &fmt_opts);
+	assert_describe("e-*", "HEAD^^", repo, &opts, &fmt_opts);
+	assert_describe("c-*", "HEAD^^2", repo, &opts, &fmt_opts);
+	assert_describe("B", "HEAD^^2^", repo, &opts, &fmt_opts);
+	assert_describe("e", "HEAD^^^", repo, &opts, &fmt_opts);
+}
+
+void test_describe_t6120__all(void)
+{
+	git_describe_options opts = GIT_DESCRIBE_OPTIONS_INIT;
+	git_describe_format_options fmt_opts = GIT_DESCRIBE_FORMAT_OPTIONS_INIT;
+	opts.describe_strategy = GIT_DESCRIBE_ALL;
+
+	assert_describe("heads/master", "HEAD", repo, &opts, &fmt_opts);
+	assert_describe("tags/c-*", "HEAD^", repo, &opts, &fmt_opts);
+	assert_describe("tags/e", "HEAD^^^", repo, &opts, &fmt_opts);
+}
+
+void test_describe_t6120__longformat(void)
+{
+	git_describe_options opts = GIT_DESCRIBE_OPTIONS_INIT;
+	git_describe_format_options fmt_opts = GIT_DESCRIBE_FORMAT_OPTIONS_INIT;
+
+	fmt_opts.always_use_long_format = 1;
+
+	assert_describe("B-0-*", "HEAD^^2^", repo, &opts, &fmt_opts);
+	assert_describe("A-3-*", "HEAD^^2", repo, &opts, &fmt_opts);
+}
+
+void test_describe_t6120__firstparent(void)
+{
+	git_describe_options opts = GIT_DESCRIBE_OPTIONS_INIT;
+	git_describe_format_options fmt_opts = GIT_DESCRIBE_FORMAT_OPTIONS_INIT;
+	opts.describe_strategy = GIT_DESCRIBE_TAGS;
+
+	assert_describe("c-7-*", "HEAD", repo, &opts, &fmt_opts);
+
+	opts.only_follow_first_parent = 1;
+	assert_describe("e-3-*", "HEAD", repo, &opts, &fmt_opts);
+}
+
+void test_describe_t6120__workdir(void)
+{
+	git_describe_options opts = GIT_DESCRIBE_OPTIONS_INIT;
+	git_describe_format_options fmt_opts = GIT_DESCRIBE_FORMAT_OPTIONS_INIT;
+
+	assert_describe_workdir("A-*[0-9a-f]", repo, &opts, &fmt_opts);
+	cl_git_mkfile("describe/file", "something different");
+
+	fmt_opts.dirty_suffix = "-dirty";
+	assert_describe_workdir("A-*[0-9a-f]-dirty", repo, &opts, &fmt_opts);
+	fmt_opts.dirty_suffix = ".mod";
+	assert_describe_workdir("A-*[0-9a-f].mod", repo, &opts, &fmt_opts);
+}
+
+static void commit_and_tag(
+	git_time_t *time,
+	const char *commit_msg,
+	const char *tag_name)
+{
+	git_index *index;
+	git_oid commit_id;
+	git_reference *ref;
+	
+	cl_git_pass(git_repository_index__weakptr(&index, repo));
+
+	cl_git_append2file("describe/file", "\n");
+	
+	git_index_add_bypath(index, "describe/file");
+	git_index_write(index);
+
+	*time += 10;
+	cl_repo_commit_from_index(&commit_id, repo, NULL, *time, commit_msg);
+
+	if (tag_name == NULL)
+		return;
+
+	cl_git_pass(git_reference_create(&ref, repo, tag_name, &commit_id, 0, NULL));
+	git_reference_free(ref);
+}
+
+void test_describe_t6120__pattern(void)
+{
+	git_describe_options opts = GIT_DESCRIBE_OPTIONS_INIT;
+	git_describe_format_options fmt_opts = GIT_DESCRIBE_FORMAT_OPTIONS_INIT;
+	git_oid tag_id;
+	git_object *head;
+	git_signature *tagger;
+	git_time_t time;
+
+	/* set-up matching pattern tests */
+	cl_git_pass(git_revparse_single(&head, repo, "HEAD"));
+
+	time = 1380553019;
+	cl_git_pass(git_signature_new(&tagger, "tagger", "tagger at libgit2.org", time, 0));
+	cl_git_pass(git_tag_create(&tag_id, repo, "test-annotated", head, tagger, "test-annotated", 0));
+	git_signature_free(tagger);
+	git_object_free(head);
+
+	commit_and_tag(&time, "one more", "refs/tags/test1-lightweight");
+	commit_and_tag(&time, "yet another", "refs/tags/test2-lightweight");
+	commit_and_tag(&time, "even more", NULL);
+
+
+	/* Exercize */
+	opts.pattern = "test-*";
+	assert_describe("test-annotated-*", "HEAD", repo, &opts, &fmt_opts);
+
+	opts.describe_strategy = GIT_DESCRIBE_TAGS;
+	opts.pattern = "test1-*";
+	assert_describe("test1-lightweight-*", "HEAD", repo, &opts, &fmt_opts);
+
+	opts.pattern = "test2-*";
+	assert_describe("test2-lightweight-*", "HEAD", repo, &opts, &fmt_opts);
+
+	fmt_opts.always_use_long_format = 1;
+	assert_describe("test2-lightweight-*", "HEAD^", repo, &opts, &fmt_opts);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/binary.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/binary.c
new file mode 100755
index 0000000..5298e9e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/binary.c
@@ -0,0 +1,538 @@
+#include "clar_libgit2.h"
+
+#include "git2/sys/diff.h"
+
+#include "buffer.h"
+#include "filebuf.h"
+#include "repository.h"
+
+static git_repository *repo;
+
+void test_diff_binary__initialize(void)
+{
+}
+
+void test_diff_binary__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_patch(
+	const char *one,
+	const char *two,
+	const git_diff_options *opts,
+	const char *expected)
+{
+	git_oid id_one, id_two;
+	git_index *index = NULL;
+	git_commit *commit_one, *commit_two = NULL;
+	git_tree *tree_one, *tree_two;
+	git_diff *diff;
+	git_patch *patch;
+	git_buf actual = GIT_BUF_INIT;
+
+	cl_git_pass(git_oid_fromstr(&id_one, one));
+	cl_git_pass(git_commit_lookup(&commit_one, repo, &id_one));
+	cl_git_pass(git_commit_tree(&tree_one, commit_one));
+
+	if (two) {
+		cl_git_pass(git_oid_fromstr(&id_two, two));
+		cl_git_pass(git_commit_lookup(&commit_two, repo, &id_two));
+		cl_git_pass(git_commit_tree(&tree_two, commit_two));
+	} else {
+		cl_git_pass(git_repository_index(&index, repo));
+		cl_git_pass(git_index_write_tree(&id_two, index));
+		cl_git_pass(git_tree_lookup(&tree_two, repo, &id_two));
+	}
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, repo, tree_one, tree_two, opts));
+
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_git_pass(git_patch_to_buf(&actual, patch));
+
+	cl_assert_equal_s(expected, actual.ptr);
+
+	git_buf_clear(&actual);
+	cl_git_pass(git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, git_diff_print_callback__to_buf, &actual));
+
+	cl_assert_equal_s(expected, actual.ptr);
+
+	git_buf_free(&actual);
+	git_patch_free(patch);
+	git_diff_free(diff);
+	git_tree_free(tree_one);
+	git_tree_free(tree_two);
+	git_commit_free(commit_one);
+	git_commit_free(commit_two);
+	git_index_free(index);
+}
+
+void test_diff_binary__add_normal(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	const char *expected =
+		"diff --git a/binary.bin b/binary.bin\n" \
+		"new file mode 100644\n" \
+		"index 0000000..bd474b2\n" \
+		"Binary files /dev/null and b/binary.bin differ\n";
+
+	repo = cl_git_sandbox_init("diff_format_email");
+	test_patch(
+		"873806f6f27e631eb0b23e4b56bea2bfac14a373",
+		"897d3af16ca9e420cd071b1c4541bd2b91d04c8c",
+		&opts,
+		expected);
+}
+
+void test_diff_binary__add(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	const char *expected =
+		"diff --git a/binary.bin b/binary.bin\n" \
+		"new file mode 100644\n" \
+		"index 0000000000000000000000000000000000000000..bd474b2519cc15eab801ff851cc7d50f0dee49a1\n" \
+		"GIT binary patch\n" \
+		"literal 3\n" \
+		"Kc${Nk-~s>u4FC%O\n"
+		"\n" \
+		"literal 0\n" \
+		"Hc$@<O00001\n";
+
+	opts.flags = GIT_DIFF_SHOW_BINARY;
+	opts.id_abbrev = GIT_OID_HEXSZ;
+
+	repo = cl_git_sandbox_init("diff_format_email");
+	test_patch(
+		"873806f6f27e631eb0b23e4b56bea2bfac14a373",
+		"897d3af16ca9e420cd071b1c4541bd2b91d04c8c",
+		&opts,
+		expected);
+}
+
+void test_diff_binary__modify_normal(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	const char *expected =
+		"diff --git a/binary.bin b/binary.bin\n" \
+		"index bd474b2..9ac35ff 100644\n" \
+		"Binary files a/binary.bin and b/binary.bin differ\n";
+
+	repo = cl_git_sandbox_init("diff_format_email");
+	test_patch(
+		"897d3af16ca9e420cd071b1c4541bd2b91d04c8c",
+		"8d7523f6fcb2404257889abe0d96f093d9f524f9",
+		&opts,
+		expected);
+}
+
+void test_diff_binary__modify(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	const char *expected =
+		"diff --git a/binary.bin b/binary.bin\n" \
+		"index bd474b2519cc15eab801ff851cc7d50f0dee49a1..9ac35ff15cd8864aeafd889e4826a3150f0b06c4 100644\n" \
+		"GIT binary patch\n" \
+		"literal 5\n" \
+		"Mc${NkU}WL~000&M4gdfE\n" \
+		"\n" \
+		"literal 3\n" \
+		"Kc${Nk-~s>u4FC%O\n";
+
+	opts.flags = GIT_DIFF_SHOW_BINARY;
+
+	repo = cl_git_sandbox_init("diff_format_email");
+	test_patch(
+		"897d3af16ca9e420cd071b1c4541bd2b91d04c8c",
+		"8d7523f6fcb2404257889abe0d96f093d9f524f9",
+		&opts,
+		expected);
+}
+
+void test_diff_binary__delete_normal(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	const char *expected =
+		"diff --git a/binary.bin b/binary.bin\n" \
+		"deleted file mode 100644\n" \
+		"index bd474b2..0000000\n" \
+		"Binary files a/binary.bin and /dev/null differ\n";
+
+	repo = cl_git_sandbox_init("diff_format_email");
+	test_patch(
+		"897d3af16ca9e420cd071b1c4541bd2b91d04c8c",
+		"873806f6f27e631eb0b23e4b56bea2bfac14a373",
+		&opts,
+		expected);
+}
+
+void test_diff_binary__delete(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	const char *expected =
+		"diff --git a/binary.bin b/binary.bin\n" \
+		"deleted file mode 100644\n" \
+		"index bd474b2519cc15eab801ff851cc7d50f0dee49a1..0000000000000000000000000000000000000000\n" \
+		"GIT binary patch\n" \
+		"literal 0\n" \
+		"Hc$@<O00001\n" \
+		"\n" \
+		"literal 3\n" \
+		"Kc${Nk-~s>u4FC%O\n";
+
+	opts.flags = GIT_DIFF_SHOW_BINARY;
+	opts.id_abbrev = GIT_OID_HEXSZ;
+
+	repo = cl_git_sandbox_init("diff_format_email");
+	test_patch(
+		"897d3af16ca9e420cd071b1c4541bd2b91d04c8c",
+		"873806f6f27e631eb0b23e4b56bea2bfac14a373",
+		&opts,
+		expected);
+}
+
+void test_diff_binary__delta(void)
+{
+	git_index *index;
+	git_buf contents = GIT_BUF_INIT;
+	size_t i;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	const char *expected =
+		"diff --git a/songof7cities.txt b/songof7cities.txt\n" \
+		"index 4210ffd5c390b21dd5483375e75288dea9ede512..cc84ec183351c9944ed90a619ca08911924055b5 100644\n" \
+		"GIT binary patch\n" \
+		"delta 198\n" \
+		"zc$}LmI8{(0BqLQJI6p64AwNwaIJGP_Pa)Ye#M3o+qJ$<Jl;sX*mF<MGCYv&*L7AHu\n" \
+		"zGA1*^gt?gYVN82wTbPO_W)+x<&1+cP;HrPHR>PQ;Y(X&QMK*C5^Br3bjG4d=XI^5@\n" \
+		"JfH567LIG)KJdFSV\n" \
+		"\n" \
+		"delta 198\n" \
+		"zc$}LmI8{(0BqLQJI6p64AwNwaIJGP_Pr*5}Br~;mqJ$<Jl;sX*mF<MGCYv&*L7AHu\n" \
+		"zGA1*^gt?gYVN82wTbPO_W)+x<&1+cP;HrPHR>PQ;Y(X&QMK*C5^Br3bjG4d=XI^5@\n" \
+		"JfH567LIF3FM2!Fd\n";
+
+	opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY;
+	opts.id_abbrev = GIT_OID_HEXSZ;
+
+	repo = cl_git_sandbox_init("renames");
+	cl_git_pass(git_repository_index(&index, repo));
+
+	cl_git_pass(git_futils_readbuffer(&contents, "renames/songof7cities.txt"));
+
+	for (i = 0; i < contents.size - 6; i++) {
+		if (strncmp(&contents.ptr[i], "Cities", 6) == 0)
+			memcpy(&contents.ptr[i], "cITIES", 6);
+	}
+
+	cl_git_rewritefile("renames/songof7cities.txt", contents.ptr);
+	cl_git_pass(git_index_add_bypath(index, "songof7cities.txt"));
+	cl_git_pass(git_index_write(index));
+
+	test_patch(
+		"19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13",
+		NULL,
+		&opts,
+		expected);
+
+	git_index_free(index);
+	git_buf_free(&contents);
+}
+
+void test_diff_binary__delta_append(void)
+{
+	git_index *index;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	const char *expected =
+		"diff --git a/untimely.txt b/untimely.txt\n" \
+		"index 9a69d960ae94b060f56c2a8702545e2bb1abb935..1111d4f11f4b35bf6759e0fb714fe09731ef0840 100644\n" \
+		"GIT binary patch\n" \
+		"delta 32\n" \
+		"nc%1vf+QYWt3zLL at hC)e3Vu?a>QDRl4f_G*?PG(-ZA}<#J$+QbW\n" \
+		"\n" \
+		"delta 7\n" \
+		"Oc%18D`@*{63ljhg(E~C7\n";
+
+	opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY;
+	opts.id_abbrev = GIT_OID_HEXSZ;
+
+	repo = cl_git_sandbox_init("renames");
+	cl_git_pass(git_repository_index(&index, repo));
+
+	cl_git_append2file("renames/untimely.txt", "Oh that crazy Kipling!\r\n");
+	cl_git_pass(git_index_add_bypath(index, "untimely.txt"));
+	cl_git_pass(git_index_write(index));
+
+	test_patch(
+		"19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13",
+		NULL,
+		&opts,
+		expected);
+
+	git_index_free(index);
+}
+
+void test_diff_binary__empty_for_no_diff(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_oid id;
+	git_commit *commit;
+	git_tree *tree;
+	git_diff *diff;
+	git_buf actual = GIT_BUF_INIT;
+
+	opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY;
+	opts.id_abbrev = GIT_OID_HEXSZ;
+
+	repo = cl_git_sandbox_init("renames");
+
+	cl_git_pass(git_oid_fromstr(&id, "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13"));
+	cl_git_pass(git_commit_lookup(&commit, repo, &id));
+	cl_git_pass(git_commit_tree(&tree, commit));
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, repo, tree, tree, &opts));
+	cl_git_pass(git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, git_diff_print_callback__to_buf, &actual));
+
+	cl_assert_equal_s("", actual.ptr);
+
+	git_buf_free(&actual);
+	git_diff_free(diff);
+	git_commit_free(commit);
+	git_tree_free(tree);
+}
+
+void test_diff_binary__index_to_workdir(void)
+{
+	git_index *index;
+	git_diff *diff;
+	git_patch *patch;
+	git_buf actual = GIT_BUF_INIT;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	const char *expected =
+		"diff --git a/untimely.txt b/untimely.txt\n" \
+		"index 9a69d960ae94b060f56c2a8702545e2bb1abb935..1111d4f11f4b35bf6759e0fb714fe09731ef0840 100644\n" \
+		"GIT binary patch\n" \
+		"delta 32\n" \
+		"nc%1vf+QYWt3zLL at hC)e3Vu?a>QDRl4f_G*?PG(-ZA}<#J$+QbW\n" \
+		"\n" \
+		"delta 7\n" \
+		"Oc%18D`@*{63ljhg(E~C7\n";
+
+	opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY;
+	opts.id_abbrev = GIT_OID_HEXSZ;
+
+	repo = cl_git_sandbox_init("renames");
+	cl_git_pass(git_repository_index(&index, repo));
+
+	cl_git_append2file("renames/untimely.txt", "Oh that crazy Kipling!\r\n");
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, repo, index, &opts));
+
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_git_pass(git_patch_to_buf(&actual, patch));
+
+	cl_assert_equal_s(expected, actual.ptr);
+
+	cl_git_pass(git_index_add_bypath(index, "untimely.txt"));
+	cl_git_pass(git_index_write(index));
+
+	test_patch(
+		"19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13",
+		NULL,
+		&opts,
+		expected);
+
+	git_buf_free(&actual);
+	git_patch_free(patch);
+	git_diff_free(diff);
+	git_index_free(index);
+}
+
+static int print_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *payload)
+{
+	git_buf *buf = (git_buf *)payload;
+
+	GIT_UNUSED(delta);
+
+	if (hunk)
+		git_buf_put(buf, hunk->header, hunk->header_len);
+
+	if (line)
+		git_buf_put(buf, line->content, line->content_len);
+
+	return git_buf_oom(buf) ? -1 : 0;
+}
+
+void test_diff_binary__print_patch_from_diff(void)
+{
+	git_index *index;
+	git_diff *diff;
+	git_buf actual = GIT_BUF_INIT;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	const char *expected =
+		"diff --git a/untimely.txt b/untimely.txt\n" \
+		"index 9a69d960ae94b060f56c2a8702545e2bb1abb935..1111d4f11f4b35bf6759e0fb714fe09731ef0840 100644\n" \
+		"GIT binary patch\n" \
+		"delta 32\n" \
+		"nc%1vf+QYWt3zLL at hC)e3Vu?a>QDRl4f_G*?PG(-ZA}<#J$+QbW\n" \
+		"\n" \
+		"delta 7\n" \
+		"Oc%18D`@*{63ljhg(E~C7\n";
+
+	opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY;
+	opts.id_abbrev = GIT_OID_HEXSZ;
+
+	repo = cl_git_sandbox_init("renames");
+	cl_git_pass(git_repository_index(&index, repo));
+
+	cl_git_append2file("renames/untimely.txt", "Oh that crazy Kipling!\r\n");
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, repo, index, &opts));
+
+	cl_git_pass(git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, print_cb, &actual));
+
+	cl_assert_equal_s(expected, actual.ptr);
+
+	git_buf_free(&actual);
+	git_diff_free(diff);
+	git_index_free(index);
+}
+
+struct diff_data {
+	char *old_path;
+	git_oid old_id;
+	git_buf old_binary_base85;
+	size_t old_binary_inflatedlen;
+	git_diff_binary_t old_binary_type;
+
+	char *new_path;
+	git_oid new_id;
+	git_buf new_binary_base85;
+	size_t new_binary_inflatedlen;
+	git_diff_binary_t new_binary_type;
+};
+
+static int file_cb(
+	const git_diff_delta *delta,
+	float progress,
+	void *payload)
+{
+	struct diff_data *diff_data = payload;
+
+	GIT_UNUSED(progress);
+
+	if (delta->old_file.path)
+		diff_data->old_path = git__strdup(delta->old_file.path);
+
+	if (delta->new_file.path)
+		diff_data->new_path = git__strdup(delta->new_file.path);
+
+	git_oid_cpy(&diff_data->old_id, &delta->old_file.id);
+	git_oid_cpy(&diff_data->new_id, &delta->new_file.id);
+
+	return 0;
+}
+
+static int binary_cb(
+	const git_diff_delta *delta,
+	const git_diff_binary *binary,
+	void *payload)
+{
+	struct diff_data *diff_data = payload;
+
+	GIT_UNUSED(delta);
+
+	git_buf_encode_base85(&diff_data->old_binary_base85,
+		binary->old_file.data, binary->old_file.datalen);
+	diff_data->old_binary_inflatedlen = binary->old_file.inflatedlen;
+	diff_data->old_binary_type = binary->old_file.type;
+
+	git_buf_encode_base85(&diff_data->new_binary_base85,
+		binary->new_file.data, binary->new_file.datalen);
+	diff_data->new_binary_inflatedlen = binary->new_file.inflatedlen;
+	diff_data->new_binary_type = binary->new_file.type;
+
+	return 0;
+}
+
+static int hunk_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	void *payload)
+{
+	GIT_UNUSED(delta);
+	GIT_UNUSED(hunk);
+	GIT_UNUSED(payload);
+
+	cl_fail("did not expect hunk callback");
+	return 0;
+}
+
+static int line_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *payload)
+{
+	GIT_UNUSED(delta);
+	GIT_UNUSED(hunk);
+	GIT_UNUSED(line);
+	GIT_UNUSED(payload);
+
+	cl_fail("did not expect line callback");
+	return 0;
+}
+
+void test_diff_binary__blob_to_blob(void)
+{
+	git_index *index;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_blob *old_blob, *new_blob;
+	git_oid old_id, new_id;
+	struct diff_data diff_data = {0};
+
+	opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY;
+	opts.id_abbrev = GIT_OID_HEXSZ;
+
+	repo = cl_git_sandbox_init("renames");
+	cl_git_pass(git_repository_index__weakptr(&index, repo));
+
+	cl_git_append2file("renames/untimely.txt", "Oh that crazy Kipling!\r\n");
+	cl_git_pass(git_index_add_bypath(index, "untimely.txt"));
+	cl_git_pass(git_index_write(index));
+
+	git_oid_fromstr(&old_id, "9a69d960ae94b060f56c2a8702545e2bb1abb935");
+	git_oid_fromstr(&new_id, "1111d4f11f4b35bf6759e0fb714fe09731ef0840");
+
+	cl_git_pass(git_blob_lookup(&old_blob, repo, &old_id));
+	cl_git_pass(git_blob_lookup(&new_blob, repo, &new_id));
+
+	cl_git_pass(git_diff_blobs(old_blob,
+		"untimely.txt", new_blob, "untimely.txt", &opts,
+		file_cb, binary_cb, hunk_cb, line_cb, &diff_data));
+
+	cl_assert_equal_s("untimely.txt", diff_data.old_path);
+	cl_assert_equal_oid(&old_id, &diff_data.old_id);
+	cl_assert_equal_i(GIT_DIFF_BINARY_DELTA, diff_data.old_binary_type);
+	cl_assert_equal_i(7, diff_data.old_binary_inflatedlen);
+	cl_assert_equal_s("c%18D`@*{63ljhg(E~C7",
+		diff_data.old_binary_base85.ptr);
+
+	cl_assert_equal_s("untimely.txt", diff_data.new_path);
+	cl_assert_equal_oid(&new_id, &diff_data.new_id);
+	cl_assert_equal_i(GIT_DIFF_BINARY_DELTA, diff_data.new_binary_type);
+	cl_assert_equal_i(32, diff_data.new_binary_inflatedlen);
+	cl_assert_equal_s("c%1vf+QYWt3zLL at hC)e3Vu?a>QDRl4f_G*?PG(-ZA}<#J$+QbW",
+		diff_data.new_binary_base85.ptr);
+
+	git_blob_free(old_blob);
+	git_blob_free(new_blob);
+
+	git__free(diff_data.old_path);
+	git__free(diff_data.new_path);
+
+	git_buf_free(&diff_data.old_binary_base85);
+	git_buf_free(&diff_data.new_binary_base85);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/blob.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/blob.c
new file mode 100755
index 0000000..c3933c3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/blob.c
@@ -0,0 +1,1008 @@
+#include "clar_libgit2.h"
+#include "diff_helpers.h"
+
+static git_repository *g_repo = NULL;
+static diff_expects expected;
+static git_diff_options opts;
+static git_blob *d, *alien;
+
+static void quick_diff_blob_to_str(
+	const git_blob *blob, const char *blob_path,
+	const char *str, size_t len, const char *str_path)
+{
+	memset(&expected, 0, sizeof(expected));
+
+	if (str && !len)
+		len = strlen(str);
+
+	cl_git_pass(git_diff_blob_to_buffer(
+		blob, blob_path, str, len, str_path,
+		&opts, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+}
+
+void test_diff_blob__initialize(void)
+{
+	git_oid oid;
+
+	g_repo = cl_git_sandbox_init("attr");
+
+	cl_git_pass(git_diff_init_options(&opts, GIT_DIFF_OPTIONS_VERSION));
+	opts.context_lines = 1;
+
+	memset(&expected, 0, sizeof(expected));
+
+	/* tests/resources/attr/root_test4.txt */
+	cl_git_pass(git_oid_fromstrn(&oid, "a0f7217a", 8));
+	cl_git_pass(git_blob_lookup_prefix(&d, g_repo, &oid, 8));
+
+	/* alien.png */
+	cl_git_pass(git_oid_fromstrn(&oid, "edf3dcee", 8));
+	cl_git_pass(git_blob_lookup_prefix(&alien, g_repo, &oid, 8));
+}
+
+void test_diff_blob__cleanup(void)
+{
+	git_blob_free(d);
+	d = NULL;
+
+	git_blob_free(alien);
+	alien = NULL;
+
+	cl_git_sandbox_cleanup();
+}
+
+static void assert_one_modified(
+	int hunks, int lines, int ctxt, int adds, int dels, diff_expects *exp)
+{
+	cl_assert_equal_i(1, exp->files);
+	cl_assert_equal_i(1, exp->file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(0, exp->files_binary);
+
+	cl_assert_equal_i(hunks, exp->hunks);
+	cl_assert_equal_i(lines, exp->lines);
+	cl_assert_equal_i(ctxt,  exp->line_ctxt);
+	cl_assert_equal_i(adds,  exp->line_adds);
+	cl_assert_equal_i(dels,  exp->line_dels);
+}
+
+void test_diff_blob__can_compare_text_blobs(void)
+{
+	git_blob *a, *b, *c;
+	git_oid a_oid, b_oid, c_oid;
+
+	/* tests/resources/attr/root_test1 */
+	cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8));
+	cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 4));
+
+	/* tests/resources/attr/root_test2 */
+	cl_git_pass(git_oid_fromstrn(&b_oid, "4d713dc4", 8));
+	cl_git_pass(git_blob_lookup_prefix(&b, g_repo, &b_oid, 4));
+
+	/* tests/resources/attr/root_test3 */
+	cl_git_pass(git_oid_fromstrn(&c_oid, "c96bbb2c2557a832", 16));
+	cl_git_pass(git_blob_lookup_prefix(&c, g_repo, &c_oid, 16));
+
+	/* Doing the equivalent of a `git diff -U1` on these files */
+
+	/* diff on tests/resources/attr/root_test1 */
+	memset(&expected, 0, sizeof(expected));
+	cl_git_pass(git_diff_blobs(
+		a, NULL, b, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+	assert_one_modified(1, 6, 1, 5, 0, &expected);
+
+	/* same diff but use direct buffers */
+	memset(&expected, 0, sizeof(expected));
+	cl_git_pass(git_diff_buffers(
+		git_blob_rawcontent(a), (size_t)git_blob_rawsize(a), NULL,
+		git_blob_rawcontent(b), (size_t)git_blob_rawsize(b), NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+	assert_one_modified(1, 6, 1, 5, 0, &expected);
+
+	/* diff on tests/resources/attr/root_test2 */
+	memset(&expected, 0, sizeof(expected));
+	cl_git_pass(git_diff_blobs(
+		b, NULL, c, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+	assert_one_modified(1, 15, 3, 9, 3, &expected);
+
+	/* diff on tests/resources/attr/root_test3 */
+	memset(&expected, 0, sizeof(expected));
+	cl_git_pass(git_diff_blobs(
+		a, NULL, c, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+	assert_one_modified(1, 13, 0, 12, 1, &expected);
+
+	memset(&expected, 0, sizeof(expected));
+	cl_git_pass(git_diff_blobs(
+		c, NULL, d, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+	assert_one_modified(2, 14, 4, 6, 4, &expected);
+
+	git_blob_free(a);
+	git_blob_free(b);
+	git_blob_free(c);
+}
+
+static void assert_patch_matches_blobs(
+	git_patch *p, git_blob *a, git_blob *b,
+	int hunks, int l0, int l1, int ctxt, int adds, int dels)
+{
+	const git_diff_delta *delta;
+	size_t tc, ta, td;
+
+	cl_assert(p != NULL);
+
+	delta = git_patch_get_delta(p);
+	cl_assert(delta != NULL);
+
+	cl_assert_equal_i(GIT_DELTA_MODIFIED, delta->status);
+	cl_assert_equal_oid(git_blob_id(a), &delta->old_file.id);
+	cl_assert_equal_sz(git_blob_rawsize(a), delta->old_file.size);
+	cl_assert_equal_oid(git_blob_id(b), &delta->new_file.id);
+	cl_assert_equal_sz(git_blob_rawsize(b), delta->new_file.size);
+
+	cl_assert_equal_i(hunks, (int)git_patch_num_hunks(p));
+
+	if (hunks > 0)
+		cl_assert_equal_i(l0, git_patch_num_lines_in_hunk(p, 0));
+	if (hunks > 1)
+		cl_assert_equal_i(l1, git_patch_num_lines_in_hunk(p, 1));
+
+	cl_git_pass(git_patch_line_stats(&tc, &ta, &td, p));
+	cl_assert_equal_i(ctxt, (int)tc);
+	cl_assert_equal_i(adds, (int)ta);
+	cl_assert_equal_i(dels, (int)td);
+}
+
+void test_diff_blob__can_compare_text_blobs_with_patch(void)
+{
+	git_blob *a, *b, *c;
+	git_oid a_oid, b_oid, c_oid;
+	git_patch *p;
+
+	/* tests/resources/attr/root_test1 */
+	cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8));
+	cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 8));
+
+	/* tests/resources/attr/root_test2 */
+	cl_git_pass(git_oid_fromstrn(&b_oid, "4d713dc4", 8));
+	cl_git_pass(git_blob_lookup_prefix(&b, g_repo, &b_oid, 8));
+
+	/* tests/resources/attr/root_test3 */
+	cl_git_pass(git_oid_fromstrn(&c_oid, "c96bbb2c2557a832", 16));
+	cl_git_pass(git_blob_lookup_prefix(&c, g_repo, &c_oid, 16));
+
+	/* Doing the equivalent of a `git diff -U1` on these files */
+
+	/* diff on tests/resources/attr/root_test1 */
+	cl_git_pass(git_patch_from_blobs(&p, a, NULL, b, NULL, &opts));
+	assert_patch_matches_blobs(p, a, b, 1, 6, 0, 1, 5, 0);
+	git_patch_free(p);
+
+	/* diff on tests/resources/attr/root_test2 */
+	cl_git_pass(git_patch_from_blobs(&p, b, NULL, c, NULL, &opts));
+	assert_patch_matches_blobs(p, b, c, 1, 15, 0, 3, 9, 3);
+	git_patch_free(p);
+
+	/* diff on tests/resources/attr/root_test3 */
+	cl_git_pass(git_patch_from_blobs(&p, a, NULL, c, NULL, &opts));
+	assert_patch_matches_blobs(p, a, c, 1, 13, 0, 0, 12, 1);
+	git_patch_free(p);
+
+	/* one more */
+	cl_git_pass(git_patch_from_blobs(&p, c, NULL, d, NULL, &opts));
+	assert_patch_matches_blobs(p, c, d, 2, 5, 9, 4, 6, 4);
+	git_patch_free(p);
+
+	git_blob_free(a);
+	git_blob_free(b);
+	git_blob_free(c);
+}
+
+void test_diff_blob__can_compare_against_null_blobs(void)
+{
+	git_blob *e = NULL;
+
+	cl_git_pass(git_diff_blobs(
+		d, NULL, e, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+
+	cl_assert_equal_i(1, expected.files);
+	cl_assert_equal_i(1, expected.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(0, expected.files_binary);
+
+	cl_assert_equal_i(1, expected.hunks);
+	cl_assert_equal_i(14, expected.hunk_old_lines);
+	cl_assert_equal_i(14, expected.lines);
+	cl_assert_equal_i(14, expected.line_dels);
+
+	opts.flags |= GIT_DIFF_REVERSE;
+	memset(&expected, 0, sizeof(expected));
+
+	cl_git_pass(git_diff_blobs(
+		d, NULL, e, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+
+	cl_assert_equal_i(1, expected.files);
+	cl_assert_equal_i(1, expected.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(0, expected.files_binary);
+
+	cl_assert_equal_i(1, expected.hunks);
+	cl_assert_equal_i(14, expected.hunk_new_lines);
+	cl_assert_equal_i(14, expected.lines);
+	cl_assert_equal_i(14, expected.line_adds);
+
+	opts.flags ^= GIT_DIFF_REVERSE;
+	memset(&expected, 0, sizeof(expected));
+
+	cl_git_pass(git_diff_blobs(
+		alien, NULL, NULL, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+
+	cl_assert_equal_i(1, expected.files);
+	cl_assert_equal_i(1, expected.files_binary);
+	cl_assert_equal_i(1, expected.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(0, expected.hunks);
+	cl_assert_equal_i(0, expected.lines);
+
+	memset(&expected, 0, sizeof(expected));
+
+	cl_git_pass(git_diff_blobs(
+		NULL, NULL, alien, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+
+	cl_assert_equal_i(1, expected.files);
+	cl_assert_equal_i(1, expected.files_binary);
+	cl_assert_equal_i(1, expected.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(0, expected.hunks);
+	cl_assert_equal_i(0, expected.lines);
+}
+
+void test_diff_blob__can_compare_against_null_blobs_with_patch(void)
+{
+	git_blob *e = NULL;
+	git_patch *p;
+	const git_diff_delta *delta;
+	const git_diff_line *line;
+	int l, max_l;
+
+	cl_git_pass(git_patch_from_blobs(&p, d, NULL, e, NULL, &opts));
+
+	cl_assert(p != NULL);
+
+	delta = git_patch_get_delta(p);
+	cl_assert(delta != NULL);
+	cl_assert_equal_i(GIT_DELTA_DELETED, delta->status);
+	cl_assert_equal_oid(git_blob_id(d), &delta->old_file.id);
+	cl_assert_equal_sz(git_blob_rawsize(d), delta->old_file.size);
+	cl_assert(git_oid_iszero(&delta->new_file.id));
+	cl_assert_equal_sz(0, delta->new_file.size);
+
+	cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
+	cl_assert_equal_i(14, git_patch_num_lines_in_hunk(p, 0));
+
+	max_l = git_patch_num_lines_in_hunk(p, 0);
+	for (l = 0; l < max_l; ++l) {
+		cl_git_pass(git_patch_get_line_in_hunk(&line, p, 0, l));
+		cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin);
+	}
+
+	git_patch_free(p);
+
+	opts.flags |= GIT_DIFF_REVERSE;
+
+	cl_git_pass(git_patch_from_blobs(&p, d, NULL, e, NULL, &opts));
+
+	cl_assert(p != NULL);
+
+	delta = git_patch_get_delta(p);
+	cl_assert(delta != NULL);
+	cl_assert_equal_i(GIT_DELTA_ADDED, delta->status);
+	cl_assert(git_oid_iszero(&delta->old_file.id));
+	cl_assert_equal_sz(0, delta->old_file.size);
+	cl_assert_equal_oid(git_blob_id(d), &delta->new_file.id);
+	cl_assert_equal_sz(git_blob_rawsize(d), delta->new_file.size);
+
+	cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
+	cl_assert_equal_i(14, git_patch_num_lines_in_hunk(p, 0));
+
+	max_l = git_patch_num_lines_in_hunk(p, 0);
+	for (l = 0; l < max_l; ++l) {
+		cl_git_pass(git_patch_get_line_in_hunk(&line, p, 0, l));
+		cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin);
+	}
+
+	git_patch_free(p);
+
+	opts.flags ^= GIT_DIFF_REVERSE;
+
+	cl_git_pass(git_patch_from_blobs(&p, alien, NULL, NULL, NULL, &opts));
+
+	cl_assert(p != NULL);
+
+	delta = git_patch_get_delta(p);
+	cl_assert(delta != NULL);
+	cl_assert_equal_i(GIT_DELTA_DELETED, delta->status);
+	cl_assert((delta->flags & GIT_DIFF_FLAG_BINARY) != 0);
+
+	cl_assert_equal_i(0, (int)git_patch_num_hunks(p));
+
+	git_patch_free(p);
+
+	cl_git_pass(git_patch_from_blobs(&p, NULL, NULL, alien, NULL, &opts));
+
+	cl_assert(p != NULL);
+
+	delta = git_patch_get_delta(p);
+	cl_assert(delta != NULL);
+	cl_assert_equal_i(GIT_DELTA_ADDED, delta->status);
+	cl_assert((delta->flags & GIT_DIFF_FLAG_BINARY) != 0);
+
+	cl_assert_equal_i(0, (int)git_patch_num_hunks(p));
+
+	git_patch_free(p);
+}
+
+static void assert_identical_blobs_comparison(diff_expects *expected)
+{
+	cl_assert_equal_i(1, expected->files);
+	cl_assert_equal_i(1, expected->file_status[GIT_DELTA_UNMODIFIED]);
+	cl_assert_equal_i(0, expected->hunks);
+	cl_assert_equal_i(0, expected->lines);
+}
+
+void test_diff_blob__can_compare_identical_blobs(void)
+{
+	opts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
+
+	cl_git_pass(git_diff_blobs(
+		d, NULL, d, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+
+	assert_identical_blobs_comparison(&expected);
+	cl_assert_equal_i(0, expected.files_binary);
+
+	memset(&expected, 0, sizeof(expected));
+	cl_git_pass(git_diff_blobs(
+		NULL, NULL, NULL, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+
+	assert_identical_blobs_comparison(&expected);
+	cl_assert_equal_i(0, expected.files_binary);
+
+	memset(&expected, 0, sizeof(expected));
+	cl_git_pass(git_diff_blobs(
+		alien, NULL, alien, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+
+	assert_identical_blobs_comparison(&expected);
+	cl_assert(expected.files_binary > 0);
+}
+
+void test_diff_blob__can_compare_identical_blobs_with_patch(void)
+{
+	git_patch *p;
+	const git_diff_delta *delta;
+
+	cl_git_pass(git_patch_from_blobs(&p, d, NULL, d, NULL, &opts));
+	cl_assert(p != NULL);
+
+	delta = git_patch_get_delta(p);
+	cl_assert(delta != NULL);
+	cl_assert_equal_i(GIT_DELTA_UNMODIFIED, delta->status);
+	cl_assert_equal_sz(delta->old_file.size, git_blob_rawsize(d));
+	cl_assert_equal_oid(git_blob_id(d), &delta->old_file.id);
+	cl_assert_equal_sz(delta->new_file.size, git_blob_rawsize(d));
+	cl_assert_equal_oid(git_blob_id(d), &delta->new_file.id);
+
+	cl_assert_equal_i(0, (int)git_patch_num_hunks(p));
+	git_patch_free(p);
+
+	cl_git_pass(git_patch_from_blobs(&p, NULL, NULL, NULL, NULL, &opts));
+	cl_assert(p != NULL);
+
+	delta = git_patch_get_delta(p);
+	cl_assert(delta != NULL);
+	cl_assert_equal_i(GIT_DELTA_UNMODIFIED, delta->status);
+	cl_assert_equal_sz(0, delta->old_file.size);
+	cl_assert(git_oid_iszero(&delta->old_file.id));
+	cl_assert_equal_sz(0, delta->new_file.size);
+	cl_assert(git_oid_iszero(&delta->new_file.id));
+
+	cl_assert_equal_i(0, (int)git_patch_num_hunks(p));
+	git_patch_free(p);
+
+	cl_git_pass(git_patch_from_blobs(&p, alien, NULL, alien, NULL, &opts));
+	cl_assert(p != NULL);
+	cl_assert_equal_i(GIT_DELTA_UNMODIFIED, git_patch_get_delta(p)->status);
+	cl_assert_equal_i(0, (int)git_patch_num_hunks(p));
+	git_patch_free(p);
+}
+
+static void assert_binary_blobs_comparison(diff_expects *expected)
+{
+	cl_assert(expected->files_binary > 0);
+
+	cl_assert_equal_i(1, expected->files);
+	cl_assert_equal_i(1, expected->file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(0, expected->hunks);
+	cl_assert_equal_i(0, expected->lines);
+}
+
+void test_diff_blob__can_compare_two_binary_blobs(void)
+{
+	git_blob *heart;
+	git_oid h_oid;
+
+	/* heart.png */
+	cl_git_pass(git_oid_fromstrn(&h_oid, "de863bff", 8));
+	cl_git_pass(git_blob_lookup_prefix(&heart, g_repo, &h_oid, 8));
+
+	cl_git_pass(git_diff_blobs(
+		alien, NULL, heart, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+
+	assert_binary_blobs_comparison(&expected);
+
+	memset(&expected, 0, sizeof(expected));
+
+	cl_git_pass(git_diff_blobs(
+		heart, NULL, alien, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+
+	assert_binary_blobs_comparison(&expected);
+
+	git_blob_free(heart);
+}
+
+void test_diff_blob__can_compare_a_binary_blob_and_a_text_blob(void)
+{
+	cl_git_pass(git_diff_blobs(
+		alien, NULL, d, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+
+	assert_binary_blobs_comparison(&expected);
+
+	memset(&expected, 0, sizeof(expected));
+
+	cl_git_pass(git_diff_blobs(
+		d, NULL, alien, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+
+	assert_binary_blobs_comparison(&expected);
+}
+
+/*
+ * $ git diff fe773770 a0f7217
+ * diff --git a/fe773770 b/a0f7217
+ * index fe77377..a0f7217 100644
+ * --- a/fe773770
+ * +++ b/a0f7217
+ * @@ -1,6 +1,6 @@
+ *  Here is some stuff at the start
+ * 
+ * -This should go in one hunk
+ * +This should go in one hunk (first)
+ * 
+ *  Some additional lines
+ * 
+ * @@ -8,7 +8,7 @@ Down here below the other lines
+ * 
+ *  With even more at the end
+ * 
+ * -Followed by a second hunk of stuff
+ * +Followed by a second hunk of stuff (second)
+ * 
+ *  That happens down here
+ */
+void test_diff_blob__comparing_two_text_blobs_honors_interhunkcontext(void)
+{
+	git_blob *old_d;
+	git_oid old_d_oid;
+
+	opts.context_lines = 3;
+
+	/* tests/resources/attr/root_test1 from commit f5b0af1 */
+	cl_git_pass(git_oid_fromstrn(&old_d_oid, "fe773770", 8));
+	cl_git_pass(git_blob_lookup_prefix(&old_d, g_repo, &old_d_oid, 8));
+
+	/* Test with default inter-hunk-context (not set) => default is 0 */
+	cl_git_pass(git_diff_blobs(
+		old_d, NULL, d, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+
+	cl_assert_equal_i(2, expected.hunks);
+
+	/* Test with inter-hunk-context explicitly set to 0 */
+	opts.interhunk_lines = 0;
+	memset(&expected, 0, sizeof(expected));
+	cl_git_pass(git_diff_blobs(
+		old_d, NULL, d, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+
+	cl_assert_equal_i(2, expected.hunks);
+
+	/* Test with inter-hunk-context explicitly set to 1 */
+	opts.interhunk_lines = 1;
+	memset(&expected, 0, sizeof(expected));
+	cl_git_pass(git_diff_blobs(
+		old_d, NULL, d, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+
+	cl_assert_equal_i(1, expected.hunks);
+
+	git_blob_free(old_d);
+}
+
+void test_diff_blob__checks_options_version_too_low(void)
+{
+	const git_error *err;
+
+	opts.version = 0;
+	cl_git_fail(git_diff_blobs(
+		d, NULL, alien, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+	err = giterr_last();
+	cl_assert_equal_i(GITERR_INVALID, err->klass);
+}
+
+void test_diff_blob__checks_options_version_too_high(void)
+{
+	const git_error *err;
+
+	opts.version = 1024;
+	cl_git_fail(git_diff_blobs(
+		d, NULL, alien, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+	err = giterr_last();
+	cl_assert_equal_i(GITERR_INVALID, err->klass);
+}
+
+void test_diff_blob__can_correctly_detect_a_binary_blob_as_binary(void)
+{
+	/* alien.png */
+	cl_assert_equal_i(true, git_blob_is_binary(alien));
+}
+
+void test_diff_blob__can_correctly_detect_a_textual_blob_as_non_binary(void)
+{
+	/* tests/resources/attr/root_test4.txt */
+	cl_assert_equal_i(false, git_blob_is_binary(d));
+}
+
+/*
+ * git_diff_blob_to_buffer tests
+ */
+
+static void assert_changed_single_one_line_file(
+	diff_expects *expected, git_delta_t mod)
+{
+	cl_assert_equal_i(1, expected->files);
+	cl_assert_equal_i(1, expected->file_status[mod]);
+	cl_assert_equal_i(1, expected->hunks);
+	cl_assert_equal_i(1, expected->lines);
+
+	if (mod == GIT_DELTA_ADDED)
+		cl_assert_equal_i(1, expected->line_adds);
+	else if (mod == GIT_DELTA_DELETED)
+		cl_assert_equal_i(1, expected->line_dels);
+}
+
+void test_diff_blob__can_compare_blob_to_buffer(void)
+{
+	git_blob *a;
+	git_oid a_oid;
+	const char *a_content = "Hello from the root\n";
+	const char *b_content = "Hello from the root\n\nSome additional lines\n\nDown here below\n\n";
+
+	/* tests/resources/attr/root_test1 */
+	cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8));
+	cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 8));
+
+	/* diff from blob a to content of b */
+	quick_diff_blob_to_str(a, NULL, b_content, 0, NULL);
+	assert_one_modified(1, 6, 1, 5, 0, &expected);
+
+	/* diff from blob a to content of a */
+	opts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
+	quick_diff_blob_to_str(a, NULL, a_content, 0, NULL);
+	assert_identical_blobs_comparison(&expected);
+
+	/* diff from NULL blob to content of a */
+	memset(&expected, 0, sizeof(expected));
+	quick_diff_blob_to_str(NULL, NULL, a_content, 0, NULL);
+	assert_changed_single_one_line_file(&expected, GIT_DELTA_ADDED);
+
+	/* diff from blob a to NULL buffer */
+	memset(&expected, 0, sizeof(expected));
+	quick_diff_blob_to_str(a, NULL, NULL, 0, NULL);
+	assert_changed_single_one_line_file(&expected, GIT_DELTA_DELETED);
+
+	/* diff with reverse */
+	opts.flags ^= GIT_DIFF_REVERSE;
+
+	memset(&expected, 0, sizeof(expected));
+	quick_diff_blob_to_str(a, NULL, NULL, 0, NULL);
+	assert_changed_single_one_line_file(&expected, GIT_DELTA_ADDED);
+
+	git_blob_free(a);
+}
+
+void test_diff_blob__can_compare_blob_to_buffer_with_patch(void)
+{
+	git_patch *p;
+	git_blob *a;
+	git_oid a_oid;
+	const char *a_content = "Hello from the root\n";
+	const char *b_content = "Hello from the root\n\nSome additional lines\n\nDown here below\n\n";
+	size_t tc, ta, td;
+
+	/* tests/resources/attr/root_test1 */
+	cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8));
+	cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 8));
+
+	/* diff from blob a to content of b */
+	cl_git_pass(git_patch_from_blob_and_buffer(
+		&p, a, NULL, b_content, strlen(b_content), NULL, &opts));
+
+	cl_assert(p != NULL);
+	cl_assert_equal_i(GIT_DELTA_MODIFIED, git_patch_get_delta(p)->status);
+	cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
+	cl_assert_equal_i(6, git_patch_num_lines_in_hunk(p, 0));
+
+	cl_git_pass(git_patch_line_stats(&tc, &ta, &td, p));
+	cl_assert_equal_i(1, (int)tc);
+	cl_assert_equal_i(5, (int)ta);
+	cl_assert_equal_i(0, (int)td);
+
+	git_patch_free(p);
+
+	/* diff from blob a to content of a */
+	opts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
+	cl_git_pass(git_patch_from_blob_and_buffer(
+		&p, a, NULL, a_content, strlen(a_content), NULL, &opts));
+	cl_assert(p != NULL);
+	cl_assert_equal_i(GIT_DELTA_UNMODIFIED, git_patch_get_delta(p)->status);
+	cl_assert_equal_i(0, (int)git_patch_num_hunks(p));
+	git_patch_free(p);
+
+	/* diff from NULL blob to content of a */
+	cl_git_pass(git_patch_from_blob_and_buffer(
+		&p, NULL, NULL, a_content, strlen(a_content), NULL, &opts));
+	cl_assert(p != NULL);
+	cl_assert_equal_i(GIT_DELTA_ADDED, git_patch_get_delta(p)->status);
+	cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
+	cl_assert_equal_i(1, git_patch_num_lines_in_hunk(p, 0));
+	git_patch_free(p);
+
+	/* diff from blob a to NULL buffer */
+	cl_git_pass(git_patch_from_blob_and_buffer(
+		&p, a, NULL, NULL, 0, NULL, &opts));
+	cl_assert(p != NULL);
+	cl_assert_equal_i(GIT_DELTA_DELETED, git_patch_get_delta(p)->status);
+	cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
+	cl_assert_equal_i(1, git_patch_num_lines_in_hunk(p, 0));
+	git_patch_free(p);
+
+	/* diff with reverse */
+	opts.flags ^= GIT_DIFF_REVERSE;
+
+	cl_git_pass(git_patch_from_blob_and_buffer(
+		&p, a, NULL, NULL, 0, NULL, &opts));
+	cl_assert(p != NULL);
+	cl_assert_equal_i(GIT_DELTA_ADDED, git_patch_get_delta(p)->status);
+	cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
+	cl_assert_equal_i(1, git_patch_num_lines_in_hunk(p, 0));
+	git_patch_free(p);
+
+	git_blob_free(a);
+}
+
+static void assert_one_modified_with_lines(diff_expects *expected, int lines)
+{
+	cl_assert_equal_i(1, expected->files);
+	cl_assert_equal_i(1, expected->file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(0, expected->files_binary);
+	cl_assert_equal_i(lines, expected->lines);
+}
+
+void test_diff_blob__binary_data_comparisons(void)
+{
+	git_blob *bin, *nonbin;
+	git_oid oid;
+	const char *nonbin_content = "Hello from the root\n";
+	size_t nonbin_len = 20;
+	const char *bin_content = "0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\n0123456789\n";
+	size_t bin_len = 33;
+
+	opts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
+
+	cl_git_pass(git_oid_fromstrn(&oid, "45141a79", 8));
+	cl_git_pass(git_blob_lookup_prefix(&nonbin, g_repo, &oid, 8));
+
+	cl_git_pass(git_oid_fromstrn(&oid, "b435cd56", 8));
+	cl_git_pass(git_blob_lookup_prefix(&bin, g_repo, &oid, 8));
+
+	/* non-binary to reference content */
+
+	quick_diff_blob_to_str(nonbin, NULL, nonbin_content, nonbin_len, NULL);
+	assert_identical_blobs_comparison(&expected);
+	cl_assert_equal_i(0, expected.files_binary);
+
+	/* binary to reference content */
+
+	quick_diff_blob_to_str(bin, NULL, bin_content, bin_len, NULL);
+	assert_identical_blobs_comparison(&expected);
+
+	cl_assert_equal_i(1, expected.files_binary);
+
+	/* non-binary to binary content */
+
+	quick_diff_blob_to_str(nonbin, NULL, bin_content, bin_len, NULL);
+	assert_binary_blobs_comparison(&expected);
+
+	/* binary to non-binary content */
+
+	quick_diff_blob_to_str(bin, NULL, nonbin_content, nonbin_len, NULL);
+	assert_binary_blobs_comparison(&expected);
+
+	/* non-binary to binary blob */
+
+	memset(&expected, 0, sizeof(expected));
+	cl_git_pass(git_diff_blobs(
+		bin, NULL, nonbin, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+	assert_binary_blobs_comparison(&expected);
+
+	/*
+	 * repeat with FORCE_TEXT
+	 */
+
+	opts.flags |= GIT_DIFF_FORCE_TEXT;
+
+	quick_diff_blob_to_str(bin, NULL, bin_content, bin_len, NULL);
+	assert_identical_blobs_comparison(&expected);
+
+	quick_diff_blob_to_str(nonbin, NULL, bin_content, bin_len, NULL);
+	assert_one_modified_with_lines(&expected, 4);
+
+	quick_diff_blob_to_str(bin, NULL, nonbin_content, nonbin_len, NULL);
+	assert_one_modified_with_lines(&expected, 4);
+
+	memset(&expected, 0, sizeof(expected));
+	cl_git_pass(git_diff_blobs(
+		bin, NULL, nonbin, NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+	assert_one_modified_with_lines(&expected, 4);
+
+	/* cleanup */
+	git_blob_free(bin);
+	git_blob_free(nonbin);
+}
+
+void test_diff_blob__using_path_and_attributes(void)
+{
+	git_config *cfg;
+	git_blob *bin, *nonbin;
+	git_oid oid;
+	const char *nonbin_content = "Hello from the root\n";
+	const char *bin_content =
+		"0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\n0123456789\n";
+	size_t bin_len = 33;
+	const char *changed;
+	git_patch *p;
+	git_buf buf = GIT_BUF_INIT;
+
+	/* set up custom diff drivers and 'diff' attribute mappings for them */
+
+	cl_git_pass(git_repository_config(&cfg, g_repo));
+	cl_git_pass(git_config_set_bool(cfg, "diff.iam_binary.binary", 1));
+	cl_git_pass(git_config_set_bool(cfg, "diff.iam_text.binary", 0));
+	cl_git_pass(git_config_set_string(
+		cfg, "diff.iam_alphactx.xfuncname", "^[A-Za-z].*$"));
+	cl_git_pass(git_config_set_bool(cfg, "diff.iam_textalpha.binary", 0));
+	cl_git_pass(git_config_set_string(
+		cfg, "diff.iam_textalpha.xfuncname", "^[A-Za-z].*$"));
+	cl_git_pass(git_config_set_string(
+		cfg, "diff.iam_numctx.funcname", "^[0-9][0-9]*"));
+	cl_git_pass(git_config_set_bool(cfg, "diff.iam_textnum.binary", 0));
+	cl_git_pass(git_config_set_string(
+		cfg, "diff.iam_textnum.funcname", "^[0-9][0-9]*"));
+	git_config_free(cfg);
+
+	cl_git_append2file(
+		"attr/.gitattributes",
+		"\n\n# test_diff_blob__using_path_and_attributes extra\n\n"
+		"*.binary  diff=iam_binary\n"
+		"*.textary diff=iam_text\n"
+		"*.alphary diff=iam_alphactx\n"
+		"*.textalphary diff=iam_textalpha\n"
+		"*.textnumary diff=iam_textnum\n"
+		"*.numary  diff=iam_numctx\n\n");
+
+	opts.context_lines = 0;
+	opts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
+
+	cl_git_pass(git_oid_fromstrn(&oid, "45141a79", 8));
+	cl_git_pass(git_blob_lookup_prefix(&nonbin, g_repo, &oid, 8));
+	/* 20b: "Hello from the root\n" */
+
+	cl_git_pass(git_oid_fromstrn(&oid, "b435cd56", 8));
+	cl_git_pass(git_blob_lookup_prefix(&bin, g_repo, &oid, 8));
+	/* 33b: "0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\n0123456789\n" */
+
+	/* non-binary to reference content */
+
+	quick_diff_blob_to_str(nonbin, NULL, nonbin_content, 0, NULL);
+	assert_identical_blobs_comparison(&expected);
+	cl_assert_equal_i(0, expected.files_binary);
+
+	/* binary to reference content */
+
+	quick_diff_blob_to_str(bin, NULL, bin_content, bin_len, NULL);
+	assert_identical_blobs_comparison(&expected);
+	cl_assert_equal_i(1, expected.files_binary);
+
+	/* add some text */
+
+	changed = "Hello from the root\nMore lines\nAnd more\nGo here\n";
+
+	quick_diff_blob_to_str(nonbin, NULL, changed, 0, NULL);
+	assert_one_modified(1, 3, 0, 3, 0, &expected);
+
+	quick_diff_blob_to_str(nonbin, "foo/bar.binary", changed, 0, NULL);
+	cl_assert_equal_i(1, expected.files);
+	cl_assert_equal_i(1, expected.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, expected.files_binary);
+	cl_assert_equal_i(0, expected.hunks);
+	cl_assert_equal_i(0, expected.lines);
+
+	quick_diff_blob_to_str(nonbin, "foo/bar.textary", changed, 0, NULL);
+	assert_one_modified(1, 3, 0, 3, 0, &expected);
+
+	quick_diff_blob_to_str(nonbin, "foo/bar.alphary", changed, 0, NULL);
+	assert_one_modified(1, 3, 0, 3, 0, &expected);
+
+	cl_git_pass(git_patch_from_blob_and_buffer(
+		&p, nonbin, "zzz.normal", changed, strlen(changed), NULL, &opts));
+	cl_git_pass(git_patch_to_buf(&buf, p));
+	cl_assert_equal_s(
+		"diff --git a/zzz.normal b/zzz.normal\n"
+		"index 45141a7..75b0dbb 100644\n"
+		"--- a/zzz.normal\n"
+		"+++ b/zzz.normal\n"
+		"@@ -1,0 +2,3 @@ Hello from the root\n"
+		"+More lines\n"
+		"+And more\n"
+		"+Go here\n", buf.ptr);
+	git_buf_clear(&buf);
+	git_patch_free(p);
+
+	cl_git_pass(git_patch_from_blob_and_buffer(
+		&p, nonbin, "zzz.binary", changed, strlen(changed), NULL, &opts));
+	cl_git_pass(git_patch_to_buf(&buf, p));
+	cl_assert_equal_s(
+		"diff --git a/zzz.binary b/zzz.binary\n"
+		"index 45141a7..75b0dbb 100644\n"
+		"Binary files a/zzz.binary and b/zzz.binary differ\n", buf.ptr);
+	git_buf_clear(&buf);
+	git_patch_free(p);
+
+	cl_git_pass(git_patch_from_blob_and_buffer(
+		&p, nonbin, "zzz.alphary", changed, strlen(changed), NULL, &opts));
+	cl_git_pass(git_patch_to_buf(&buf, p));
+	cl_assert_equal_s(
+		"diff --git a/zzz.alphary b/zzz.alphary\n"
+		"index 45141a7..75b0dbb 100644\n"
+		"--- a/zzz.alphary\n"
+		"+++ b/zzz.alphary\n"
+		"@@ -1,0 +2,3 @@ Hello from the root\n"
+		"+More lines\n"
+		"+And more\n"
+		"+Go here\n", buf.ptr);
+	git_buf_clear(&buf);
+	git_patch_free(p);
+
+	cl_git_pass(git_patch_from_blob_and_buffer(
+		&p, nonbin, "zzz.numary", changed, strlen(changed), NULL, &opts));
+	cl_git_pass(git_patch_to_buf(&buf, p));
+	cl_assert_equal_s(
+		"diff --git a/zzz.numary b/zzz.numary\n"
+		"index 45141a7..75b0dbb 100644\n"
+		"--- a/zzz.numary\n"
+		"+++ b/zzz.numary\n"
+		"@@ -1,0 +2,3 @@\n"
+		"+More lines\n"
+		"+And more\n"
+		"+Go here\n", buf.ptr);
+	git_buf_clear(&buf);
+	git_patch_free(p);
+
+	/* "0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\n0123456789\n"
+	 * 33 bytes
+	 */
+
+	changed = "0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\nreplace a line\n";
+
+	cl_git_pass(git_patch_from_blob_and_buffer(
+		&p, bin, "zzz.normal", changed, 37, NULL, &opts));
+	cl_git_pass(git_patch_to_buf(&buf, p));
+	cl_assert_equal_s(
+		"diff --git a/zzz.normal b/zzz.normal\n"
+		"index b435cd5..1604519 100644\n"
+		"Binary files a/zzz.normal and b/zzz.normal differ\n", buf.ptr);
+	git_buf_clear(&buf);
+	git_patch_free(p);
+
+	cl_git_pass(git_patch_from_blob_and_buffer(
+		&p, bin, "zzz.textary", changed, 37, NULL, &opts));
+	cl_git_pass(git_patch_to_buf(&buf, p));
+	cl_assert_equal_s(
+		"diff --git a/zzz.textary b/zzz.textary\n"
+		"index b435cd5..1604519 100644\n"
+		"--- a/zzz.textary\n"
+		"+++ b/zzz.textary\n"
+		"@@ -3 +3 @@\n"
+		"-0123456789\n"
+		"+replace a line\n", buf.ptr);
+	git_buf_clear(&buf);
+	git_patch_free(p);
+
+	cl_git_pass(git_patch_from_blob_and_buffer(
+		&p, bin, "zzz.textalphary", changed, 37, NULL, &opts));
+	cl_git_pass(git_patch_to_buf(&buf, p));
+	cl_assert_equal_s(
+		"diff --git a/zzz.textalphary b/zzz.textalphary\n"
+		"index b435cd5..1604519 100644\n"
+		"--- a/zzz.textalphary\n"
+		"+++ b/zzz.textalphary\n"
+		"@@ -3 +3 @@\n"
+		"-0123456789\n"
+		"+replace a line\n", buf.ptr);
+	git_buf_clear(&buf);
+	git_patch_free(p);
+
+	cl_git_pass(git_patch_from_blob_and_buffer(
+		&p, bin, "zzz.textnumary", changed, 37, NULL, &opts));
+	cl_git_pass(git_patch_to_buf(&buf, p));
+	cl_assert_equal_s(
+		"diff --git a/zzz.textnumary b/zzz.textnumary\n"
+		"index b435cd5..1604519 100644\n"
+		"--- a/zzz.textnumary\n"
+		"+++ b/zzz.textnumary\n"
+		"@@ -3 +3 @@ 0123456789\n"
+		"-0123456789\n"
+		"+replace a line\n", buf.ptr);
+	git_buf_clear(&buf);
+	git_patch_free(p);
+
+	git_buf_free(&buf);
+	git_blob_free(nonbin);
+	git_blob_free(bin);
+}
+
+void test_diff_blob__can_compare_buffer_to_buffer(void)
+{
+	const char *a = "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\n";
+	const char *b = "a\nB\nc\nd\nE\nF\nh\nj\nk\n";
+
+	opts.interhunk_lines = 0;
+	opts.context_lines = 0;
+
+	memset(&expected, 0, sizeof(expected));
+
+	cl_git_pass(git_diff_buffers(
+		a, strlen(a), NULL, b, strlen(b), NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+	assert_one_modified(4, 9, 0, 4, 5, &expected);
+
+	opts.flags ^= GIT_DIFF_REVERSE;
+
+	memset(&expected, 0, sizeof(expected));
+
+	cl_git_pass(git_diff_buffers(
+		a, strlen(a), NULL, b, strlen(b), NULL, &opts,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
+	assert_one_modified(4, 9, 0, 5, 4, &expected);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/diff_helpers.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/diff_helpers.c
new file mode 100755
index 0000000..c6cdf80
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/diff_helpers.c
@@ -0,0 +1,243 @@
+#include "clar_libgit2.h"
+#include "diff_helpers.h"
+#include "git2/sys/diff.h"
+
+git_tree *resolve_commit_oid_to_tree(
+	git_repository *repo,
+	const char *partial_oid)
+{
+	size_t len = strlen(partial_oid);
+	git_oid oid;
+	git_object *obj = NULL;
+	git_tree *tree = NULL;
+
+	if (git_oid_fromstrn(&oid, partial_oid, len) == 0)
+		cl_git_pass(git_object_lookup_prefix(&obj, repo, &oid, len, GIT_OBJ_ANY));
+
+	cl_git_pass(git_object_peel((git_object **) &tree, obj, GIT_OBJ_TREE));
+	git_object_free(obj);
+	return tree;
+}
+
+static char diff_pick_suffix(int mode)
+{
+	if (S_ISDIR(mode))
+		return '/';
+	else if (GIT_PERMS_IS_EXEC(mode))
+		return '*';
+	else
+		return ' ';
+}
+
+static void fprintf_delta(FILE *fp, const git_diff_delta *delta, float progress)
+{
+	char code = git_diff_status_char(delta->status);
+	char old_suffix = diff_pick_suffix(delta->old_file.mode);
+	char new_suffix = diff_pick_suffix(delta->new_file.mode);
+
+	fprintf(fp, "%c\t%s", code, delta->old_file.path);
+
+	if ((delta->old_file.path != delta->new_file.path &&
+		 strcmp(delta->old_file.path, delta->new_file.path) != 0) ||
+		(delta->old_file.mode != delta->new_file.mode &&
+		 delta->old_file.mode != 0 && delta->new_file.mode != 0))
+		fprintf(fp, "%c %s%c", old_suffix, delta->new_file.path, new_suffix);
+	else if (old_suffix != ' ')
+		fprintf(fp, "%c", old_suffix);
+
+	fprintf(fp, "\t[%.2f]\n", progress);
+}
+
+int diff_file_cb(
+	const git_diff_delta *delta,
+	float progress,
+	void *payload)
+{
+	diff_expects *e = payload;
+
+	if (e->debug)
+		fprintf_delta(stderr, delta, progress);
+
+	if (e->names)
+		cl_assert_equal_s(e->names[e->files], delta->old_file.path);
+	if (e->statuses)
+		cl_assert_equal_i(e->statuses[e->files], (int)delta->status);
+
+	e->files++;
+
+	if ((delta->flags & GIT_DIFF_FLAG_BINARY) != 0)
+		e->files_binary++;
+
+	cl_assert(delta->status <= GIT_DELTA_CONFLICTED);
+
+	e->file_status[delta->status] += 1;
+
+	return 0;
+}
+
+int diff_print_file_cb(
+	const git_diff_delta *delta,
+	float progress,
+	void *payload)
+{
+	if (!payload) {
+		fprintf_delta(stderr, delta, progress);
+		return 0;
+	}
+
+	if (!((diff_expects *)payload)->debug)
+		fprintf_delta(stderr, delta, progress);
+
+	return diff_file_cb(delta, progress, payload);
+}
+
+int diff_binary_cb(
+	const git_diff_delta *delta,
+	const git_diff_binary *binary,
+	void *payload)
+{
+	GIT_UNUSED(delta);
+	GIT_UNUSED(binary);
+	GIT_UNUSED(payload);
+
+	return 0;
+}
+
+int diff_hunk_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	void *payload)
+{
+	diff_expects *e = payload;
+	const char *scan = hunk->header, *scan_end = scan + hunk->header_len;
+
+	GIT_UNUSED(delta);
+
+	/* confirm no NUL bytes in header text */
+	while (scan < scan_end)
+		cl_assert('\0' != *scan++);
+
+	e->hunks++;
+	e->hunk_old_lines += hunk->old_lines;
+	e->hunk_new_lines += hunk->new_lines;
+	return 0;
+}
+
+int diff_line_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *payload)
+{
+	diff_expects *e = payload;
+
+	GIT_UNUSED(delta);
+	GIT_UNUSED(hunk);
+
+	e->lines++;
+	switch (line->origin) {
+	case GIT_DIFF_LINE_CONTEXT:
+	case GIT_DIFF_LINE_CONTEXT_EOFNL: /* techically not a line */
+		e->line_ctxt++;
+		break;
+	case GIT_DIFF_LINE_ADDITION:
+	case GIT_DIFF_LINE_ADD_EOFNL: /* technically not a line add */
+		e->line_adds++;
+		break;
+	case GIT_DIFF_LINE_DELETION:
+	case GIT_DIFF_LINE_DEL_EOFNL: /* technically not a line delete */
+		e->line_dels++;
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+int diff_foreach_via_iterator(
+	git_diff *diff,
+	git_diff_file_cb file_cb,
+	git_diff_binary_cb binary_cb,
+	git_diff_hunk_cb hunk_cb,
+	git_diff_line_cb line_cb,
+	void *data)
+{
+	size_t d, num_d = git_diff_num_deltas(diff);
+
+	GIT_UNUSED(binary_cb);
+
+	for (d = 0; d < num_d; ++d) {
+		git_patch *patch;
+		const git_diff_delta *delta;
+		size_t h, num_h;
+
+		cl_git_pass(git_patch_from_diff(&patch, diff, d));
+		cl_assert((delta = git_patch_get_delta(patch)) != NULL);
+
+		/* call file_cb for this file */
+		if (file_cb != NULL && file_cb(delta, (float)d / num_d, data) != 0) {
+			git_patch_free(patch);
+			goto abort;
+		}
+
+		/* if there are no changes, then the patch will be NULL */
+		if (!patch) {
+			cl_assert(delta->status == GIT_DELTA_UNMODIFIED ||
+					  (delta->flags & GIT_DIFF_FLAG_BINARY) != 0);
+			continue;
+		}
+
+		if (!hunk_cb && !line_cb) {
+			git_patch_free(patch);
+			continue;
+		}
+
+		num_h = git_patch_num_hunks(patch);
+
+		for (h = 0; h < num_h; h++) {
+			const git_diff_hunk *hunk;
+			size_t l, num_l;
+
+			cl_git_pass(git_patch_get_hunk(&hunk, &num_l, patch, h));
+
+			if (hunk_cb && hunk_cb(delta, hunk, data) != 0) {
+				git_patch_free(patch);
+				goto abort;
+			}
+
+			for (l = 0; l < num_l; ++l) {
+				const git_diff_line *line;
+
+				cl_git_pass(git_patch_get_line_in_hunk(&line, patch, h, l));
+
+				if (line_cb &&
+					line_cb(delta, hunk, line, data) != 0) {
+					git_patch_free(patch);
+					goto abort;
+				}
+			}
+		}
+
+		git_patch_free(patch);
+	}
+
+	return 0;
+
+abort:
+	giterr_clear();
+	return GIT_EUSER;
+}
+
+void diff_print(FILE *fp, git_diff *diff)
+{
+	cl_git_pass(
+		git_diff_print(diff, GIT_DIFF_FORMAT_PATCH,
+			git_diff_print_callback__to_file_handle, fp ? fp : stderr));
+}
+
+void diff_print_raw(FILE *fp, git_diff *diff)
+{
+	cl_git_pass(
+		git_diff_print(diff, GIT_DIFF_FORMAT_RAW,
+			git_diff_print_callback__to_file_handle, fp ? fp : stderr));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/diff_helpers.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/diff_helpers.h
new file mode 100755
index 0000000..4d3cd34
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/diff_helpers.h
@@ -0,0 +1,70 @@
+#include "fileops.h"
+#include "git2/diff.h"
+
+extern git_tree *resolve_commit_oid_to_tree(
+	git_repository *repo, const char *partial_oid);
+
+typedef struct {
+	int files;
+	int files_binary;
+
+	int file_status[11]; /* indexed by git_delta_t value */
+
+	int hunks;
+	int hunk_new_lines;
+	int hunk_old_lines;
+
+	int lines;
+	int line_ctxt;
+	int line_adds;
+	int line_dels;
+
+	/* optional arrays of expected specific values */
+	const char **names;
+	int *statuses;
+
+	int debug;
+
+} diff_expects;
+
+typedef struct {
+	const char *path;
+	const char *matched_pathspec;
+} notify_expected;
+
+extern int diff_file_cb(
+	const git_diff_delta *delta,
+	float progress,
+	void *cb_data);
+
+extern int diff_print_file_cb(
+	const git_diff_delta *delta,
+	float progress,
+	void *cb_data);
+
+extern int diff_binary_cb(
+	const git_diff_delta *delta,
+	const git_diff_binary *binary,
+	void *cb_data);
+
+extern int diff_hunk_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	void *cb_data);
+
+extern int diff_line_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *cb_data);
+
+extern int diff_foreach_via_iterator(
+	git_diff *diff,
+	git_diff_file_cb file_cb,
+	git_diff_binary_cb binary_cb,
+	git_diff_hunk_cb hunk_cb,
+	git_diff_line_cb line_cb,
+	void *data);
+
+extern void diff_print(FILE *fp, git_diff *diff);
+extern void diff_print_raw(FILE *fp, git_diff *diff);
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/diffiter.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/diffiter.c
new file mode 100755
index 0000000..c976e30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/diffiter.c
@@ -0,0 +1,453 @@
+#include "clar_libgit2.h"
+#include "diff_helpers.h"
+
+void test_diff_diffiter__initialize(void)
+{
+}
+
+void test_diff_diffiter__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_diff_diffiter__create(void)
+{
+	git_repository *repo = cl_git_sandbox_init("attr");
+	git_diff *diff;
+	size_t d, num_d;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, repo, NULL, NULL));
+
+	num_d = git_diff_num_deltas(diff);
+	for (d = 0; d < num_d; ++d) {
+		const git_diff_delta *delta = git_diff_get_delta(diff, d);
+		cl_assert(delta != NULL);
+	}
+
+	cl_assert(!git_diff_get_delta(diff, num_d));
+
+	git_diff_free(diff);
+}
+
+void test_diff_diffiter__iterate_files_1(void)
+{
+	git_repository *repo = cl_git_sandbox_init("attr");
+	git_diff *diff;
+	size_t d, num_d;
+	diff_expects exp = { 0 };
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, repo, NULL, NULL));
+
+	num_d = git_diff_num_deltas(diff);
+
+	for (d = 0; d < num_d; ++d) {
+		const git_diff_delta *delta = git_diff_get_delta(diff, d);
+		cl_assert(delta != NULL);
+
+		diff_file_cb(delta, (float)d / (float)num_d, &exp);
+	}
+	cl_assert_equal_sz(6, exp.files);
+
+	git_diff_free(diff);
+}
+
+void test_diff_diffiter__iterate_files_2(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_diff *diff;
+	size_t d, num_d;
+	int count = 0;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, repo, NULL, NULL));
+
+	num_d = git_diff_num_deltas(diff);
+	cl_assert_equal_i(8, (int)num_d);
+
+	for (d = 0; d < num_d; ++d) {
+		const git_diff_delta *delta = git_diff_get_delta(diff, d);
+		cl_assert(delta != NULL);
+		count++;
+	}
+	cl_assert_equal_i(8, count);
+
+	git_diff_free(diff);
+}
+
+void test_diff_diffiter__iterate_files_and_hunks(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	size_t d, num_d;
+	int file_count = 0, hunk_count = 0;
+
+	opts.context_lines = 3;
+	opts.interhunk_lines = 1;
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, repo, NULL, &opts));
+
+	num_d = git_diff_num_deltas(diff);
+
+	for (d = 0; d < num_d; ++d) {
+		git_patch *patch;
+		size_t h, num_h;
+
+		cl_git_pass(git_patch_from_diff(&patch, diff, d));
+		cl_assert(patch);
+
+		file_count++;
+
+		num_h = git_patch_num_hunks(patch);
+
+		for (h = 0; h < num_h; h++) {
+			const git_diff_hunk *hunk;
+
+			cl_git_pass(git_patch_get_hunk(&hunk, NULL, patch, h));
+			cl_assert(hunk);
+
+			hunk_count++;
+		}
+
+		git_patch_free(patch);
+	}
+
+	cl_assert_equal_i(13, file_count);
+	cl_assert_equal_i(8, hunk_count);
+
+	git_diff_free(diff);
+}
+
+void test_diff_diffiter__max_size_threshold(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	int file_count = 0, binary_count = 0, hunk_count = 0;
+	size_t d, num_d;
+
+	opts.context_lines = 3;
+	opts.interhunk_lines = 1;
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, repo, NULL, &opts));
+	num_d = git_diff_num_deltas(diff);
+
+	for (d = 0; d < num_d; ++d) {
+		git_patch *patch;
+		const git_diff_delta *delta;
+
+		cl_git_pass(git_patch_from_diff(&patch, diff, d));
+		cl_assert(patch);
+		delta = git_patch_get_delta(patch);
+		cl_assert(delta);
+
+		file_count++;
+		hunk_count += (int)git_patch_num_hunks(patch);
+
+		assert((delta->flags & (GIT_DIFF_FLAG_BINARY|GIT_DIFF_FLAG_NOT_BINARY)) != 0);
+		binary_count += ((delta->flags & GIT_DIFF_FLAG_BINARY) != 0);
+
+		git_patch_free(patch);
+	}
+
+	cl_assert_equal_i(13, file_count);
+	cl_assert_equal_i(0, binary_count);
+	cl_assert_equal_i(8, hunk_count);
+
+	git_diff_free(diff);
+
+	/* try again with low file size threshold */
+
+	file_count = binary_count = hunk_count = 0;
+
+	opts.context_lines = 3;
+	opts.interhunk_lines = 1;
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+	opts.max_size = 50; /* treat anything over 50 bytes as binary! */
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, repo, NULL, &opts));
+	num_d = git_diff_num_deltas(diff);
+
+	for (d = 0; d < num_d; ++d) {
+		git_patch *patch;
+		const git_diff_delta *delta;
+
+		cl_git_pass(git_patch_from_diff(&patch, diff, d));
+		delta = git_patch_get_delta(patch);
+
+		file_count++;
+		hunk_count += (int)git_patch_num_hunks(patch);
+
+		assert((delta->flags & (GIT_DIFF_FLAG_BINARY|GIT_DIFF_FLAG_NOT_BINARY)) != 0);
+		binary_count += ((delta->flags & GIT_DIFF_FLAG_BINARY) != 0);
+
+		git_patch_free(patch);
+	}
+
+	cl_assert_equal_i(13, file_count);
+	/* Three files are over the 50 byte threshold:
+	 * - staged_changes_file_deleted
+	 * - staged_changes_modified_file
+	 * - staged_new_file_modified_file
+	 */
+	cl_assert_equal_i(3, binary_count);
+	cl_assert_equal_i(5, hunk_count);
+
+	git_diff_free(diff);
+}
+
+
+void test_diff_diffiter__iterate_all(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	diff_expects exp = {0};
+	size_t d, num_d;
+
+	opts.context_lines = 3;
+	opts.interhunk_lines = 1;
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, repo, NULL, &opts));
+
+	num_d = git_diff_num_deltas(diff);
+	for (d = 0; d < num_d; ++d) {
+		git_patch *patch;
+		size_t h, num_h;
+
+		cl_git_pass(git_patch_from_diff(&patch, diff, d));
+		cl_assert(patch);
+		exp.files++;
+
+		num_h = git_patch_num_hunks(patch);
+		for (h = 0; h < num_h; h++) {
+			const git_diff_hunk *range;
+			size_t l, num_l;
+
+			cl_git_pass(git_patch_get_hunk(&range, &num_l, patch, h));
+			cl_assert(range);
+			exp.hunks++;
+
+			for (l = 0; l < num_l; ++l) {
+				const git_diff_line *line;
+
+				cl_git_pass(git_patch_get_line_in_hunk(&line, patch, h, l));
+				cl_assert(line && line->content);
+				exp.lines++;
+			}
+		}
+
+		git_patch_free(patch);
+	}
+
+	cl_assert_equal_i(13, exp.files);
+	cl_assert_equal_i(8, exp.hunks);
+	cl_assert_equal_i(14, exp.lines);
+
+	git_diff_free(diff);
+}
+
+static void iterate_over_patch(git_patch *patch, diff_expects *exp)
+{
+	size_t h, num_h = git_patch_num_hunks(patch), num_l;
+
+	exp->files++;
+	exp->hunks += (int)num_h;
+
+	/* let's iterate in reverse, just because we can! */
+	for (h = 1, num_l = 0; h <= num_h; ++h)
+		num_l += git_patch_num_lines_in_hunk(patch, num_h - h);
+
+	exp->lines += (int)num_l;
+}
+
+#define PATCH_CACHE 5
+
+void test_diff_diffiter__iterate_randomly_while_saving_state(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	diff_expects exp = {0};
+	git_patch *patches[PATCH_CACHE];
+	size_t p, d, num_d;
+
+	memset(patches, 0, sizeof(patches));
+
+	opts.context_lines = 3;
+	opts.interhunk_lines = 1;
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, repo, NULL, &opts));
+
+	num_d = git_diff_num_deltas(diff);
+
+	/* To make sure that references counts work for diff and patch objects,
+	 * this generates patches and randomly caches them.  Only when the patch
+	 * is removed from the cache are hunks and lines counted.  At the end,
+	 * there are still patches in the cache, so free the diff and try to
+	 * process remaining patches after the diff is freed.
+	 */
+
+	srand(121212);
+	p = rand() % PATCH_CACHE;
+
+	for (d = 0; d < num_d; ++d) {
+		/* take old patch */
+		git_patch *patch = patches[p];
+		patches[p] = NULL;
+
+		/* cache new patch */
+		cl_git_pass(git_patch_from_diff(&patches[p], diff, d));
+		cl_assert(patches[p] != NULL);
+
+		/* process old patch if non-NULL */
+		if (patch != NULL) {
+			iterate_over_patch(patch, &exp);
+			git_patch_free(patch);
+		}
+
+		p = rand() % PATCH_CACHE;
+	}
+
+	/* free diff list now - refcounts should keep things safe */
+	git_diff_free(diff);
+
+	/* process remaining unprocessed patches */
+	for (p = 0; p < PATCH_CACHE; p++) {
+		git_patch *patch = patches[p];
+
+		if (patch != NULL) {
+			iterate_over_patch(patch, &exp);
+			git_patch_free(patch);
+		}
+	}
+
+	/* hopefully it all still added up right */
+	cl_assert_equal_i(13, exp.files);
+	cl_assert_equal_i(8, exp.hunks);
+	cl_assert_equal_i(14, exp.lines);
+}
+
+/* This output is taken directly from `git diff` on the status test data */
+static const char *expected_patch_text[8] = {
+	/* 0 */
+	"diff --git a/file_deleted b/file_deleted\n"
+	"deleted file mode 100644\n"
+	"index 5452d32..0000000\n"
+	"--- a/file_deleted\n"
+	"+++ /dev/null\n"
+	"@@ -1 +0,0 @@\n"
+	"-file_deleted\n",
+	/* 1 */
+	"diff --git a/modified_file b/modified_file\n"
+	"index 452e424..0a53963 100644\n"
+	"--- a/modified_file\n"
+	"+++ b/modified_file\n"
+	"@@ -1 +1,2 @@\n"
+	" modified_file\n"
+	"+modified_file\n",
+	/* 2 */
+	"diff --git a/staged_changes_file_deleted b/staged_changes_file_deleted\n"
+	"deleted file mode 100644\n"
+	"index a6be623..0000000\n"
+	"--- a/staged_changes_file_deleted\n"
+	"+++ /dev/null\n"
+	"@@ -1,2 +0,0 @@\n"
+	"-staged_changes_file_deleted\n"
+	"-staged_changes_file_deleted\n",
+	/* 3 */
+	"diff --git a/staged_changes_modified_file b/staged_changes_modified_file\n"
+	"index 906ee77..011c344 100644\n"
+	"--- a/staged_changes_modified_file\n"
+	"+++ b/staged_changes_modified_file\n"
+	"@@ -1,2 +1,3 @@\n"
+	" staged_changes_modified_file\n"
+	" staged_changes_modified_file\n"
+	"+staged_changes_modified_file\n",
+	/* 4 */
+	"diff --git a/staged_new_file_deleted_file b/staged_new_file_deleted_file\n"
+	"deleted file mode 100644\n"
+	"index 90b8c29..0000000\n"
+	"--- a/staged_new_file_deleted_file\n"
+	"+++ /dev/null\n"
+	"@@ -1 +0,0 @@\n"
+	"-staged_new_file_deleted_file\n",
+	/* 5 */
+	"diff --git a/staged_new_file_modified_file b/staged_new_file_modified_file\n"
+	"index ed06290..8b090c0 100644\n"
+	"--- a/staged_new_file_modified_file\n"
+	"+++ b/staged_new_file_modified_file\n"
+	"@@ -1 +1,2 @@\n"
+	" staged_new_file_modified_file\n"
+	"+staged_new_file_modified_file\n",
+	/* 6 */
+	"diff --git a/subdir/deleted_file b/subdir/deleted_file\n"
+	"deleted file mode 100644\n"
+	"index 1888c80..0000000\n"
+	"--- a/subdir/deleted_file\n"
+	"+++ /dev/null\n"
+	"@@ -1 +0,0 @@\n"
+	"-subdir/deleted_file\n",
+	/* 7 */
+	"diff --git a/subdir/modified_file b/subdir/modified_file\n"
+	"index a619198..57274b7 100644\n"
+	"--- a/subdir/modified_file\n"
+	"+++ b/subdir/modified_file\n"
+	"@@ -1 +1,2 @@\n"
+	" subdir/modified_file\n"
+	"+subdir/modified_file\n"
+};
+
+void test_diff_diffiter__iterate_and_generate_patch_text(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_diff *diff;
+	size_t d, num_d;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, repo, NULL, NULL));
+
+	num_d = git_diff_num_deltas(diff);
+	cl_assert_equal_i(8, (int)num_d);
+
+	for (d = 0; d < num_d; ++d) {
+		git_patch *patch;
+		git_buf buf = GIT_BUF_INIT;
+
+		cl_git_pass(git_patch_from_diff(&patch, diff, d));
+		cl_assert(patch != NULL);
+
+		cl_git_pass(git_patch_to_buf(&buf, patch));
+
+		cl_assert_equal_s(expected_patch_text[d], buf.ptr);
+
+		git_buf_free(&buf);
+		git_patch_free(patch);
+	}
+
+	git_diff_free(diff);
+}
+
+void test_diff_diffiter__checks_options_version(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	const git_error *err;
+
+	opts.version = 0;
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+
+	cl_git_fail(git_diff_index_to_workdir(&diff, repo, NULL, &opts));
+	err = giterr_last();
+	cl_assert_equal_i(GITERR_INVALID, err->klass);
+
+	giterr_clear();
+	opts.version = 1024;
+	cl_git_fail(git_diff_index_to_workdir(&diff, repo, NULL, &opts));
+	err = giterr_last();
+	cl_assert_equal_i(GITERR_INVALID, err->klass);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/drivers.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/drivers.c
new file mode 100755
index 0000000..42af38a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/drivers.c
@@ -0,0 +1,278 @@
+#include "clar_libgit2.h"
+#include "diff_helpers.h"
+#include "repository.h"
+#include "diff_driver.h"
+
+static git_repository *g_repo = NULL;
+
+void test_diff_drivers__initialize(void)
+{
+}
+
+void test_diff_drivers__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+	g_repo = NULL;
+}
+
+static void overwrite_filemode(const char *expected, git_buf *actual)
+{
+	size_t offset;
+	char *found;
+
+	found = strstr(expected, "100644");
+	if (!found)
+		return;
+
+	offset = ((const char *)found) - expected;
+	if (actual->size < offset + 6)
+		return;
+
+	if (memcmp(&actual->ptr[offset], "100644", 6) != 0)
+		memcpy(&actual->ptr[offset], "100644", 6);
+}
+
+void test_diff_drivers__patterns(void)
+{
+	git_config *cfg;
+	const char *one_sha = "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13";
+	git_tree *one;
+	git_diff *diff;
+	git_patch *patch;
+	git_buf actual = GIT_BUF_INIT;
+	const char *expected0 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\n--- a/untimely.txt\n+++ b/untimely.txt\n@@ -22,3 +22,5 @@ Comes through the blood of the vanguards who\n   dreamed--too soon--it had sounded.\r\n \r\n                 -- Rudyard Kipling\r\n+\r\n+Some new stuff\r\n";
+	const char *expected1 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\nBinary files a/untimely.txt and b/untimely.txt differ\n";
+	const char *expected2 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\n--- a/untimely.txt\n+++ b/untimely.txt\n@@ -22,3 +22,5 @@ Heaven delivers on earth the Hour that cannot be\n   dreamed--too soon--it had sounded.\r\n \r\n                 -- Rudyard Kipling\r\n+\r\n+Some new stuff\r\n";
+
+	g_repo = cl_git_sandbox_init("renames");
+
+	one = resolve_commit_oid_to_tree(g_repo, one_sha);
+
+	/* no diff */
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
+	cl_assert_equal_i(0, (int)git_diff_num_deltas(diff));
+	git_diff_free(diff);
+
+	/* default diff */
+
+	cl_git_append2file("renames/untimely.txt", "\r\nSome new stuff\r\n");
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
+	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
+
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_git_pass(git_patch_to_buf(&actual, patch));
+	cl_assert_equal_s(expected0, actual.ptr);
+
+	git_buf_free(&actual);
+	git_patch_free(patch);
+	git_diff_free(diff);
+
+	/* attribute diff set to false */
+
+	cl_git_rewritefile("renames/.gitattributes", "untimely.txt -diff\n");
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
+	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
+
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_git_pass(git_patch_to_buf(&actual, patch));
+	cl_assert_equal_s(expected1, actual.ptr);
+
+	git_buf_free(&actual);
+	git_patch_free(patch);
+	git_diff_free(diff);
+
+	/* attribute diff set to unconfigured value (should use default) */
+
+	cl_git_rewritefile("renames/.gitattributes", "untimely.txt diff=kipling0\n");
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
+	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
+
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_git_pass(git_patch_to_buf(&actual, patch));
+	cl_assert_equal_s(expected0, actual.ptr);
+
+	git_buf_free(&actual);
+	git_patch_free(patch);
+	git_diff_free(diff);
+
+	/* let's define that driver */
+
+	cl_git_pass(git_repository_config(&cfg, g_repo));
+	cl_git_pass(git_config_set_bool(cfg, "diff.kipling0.binary", 1));
+	git_config_free(cfg);
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
+	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
+
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_git_pass(git_patch_to_buf(&actual, patch));
+	cl_assert_equal_s(expected1, actual.ptr);
+
+	git_buf_free(&actual);
+	git_patch_free(patch);
+	git_diff_free(diff);
+
+	/* let's use a real driver with some regular expressions */
+
+	git_diff_driver_registry_free(g_repo->diff_drivers);
+	g_repo->diff_drivers = NULL;
+
+	cl_git_pass(git_repository_config(&cfg, g_repo));
+	cl_git_pass(git_config_set_bool(cfg, "diff.kipling0.binary", 0));
+	cl_git_pass(git_config_set_string(cfg, "diff.kipling0.xfuncname", "^H.*$"));
+	git_config_free(cfg);
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
+	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
+
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_git_pass(git_patch_to_buf(&actual, patch));
+	cl_assert_equal_s(expected2, actual.ptr);
+
+	git_buf_free(&actual);
+	git_patch_free(patch);
+	git_diff_free(diff);
+
+	git_tree_free(one);
+}
+
+void test_diff_drivers__long_lines(void)
+{
+	const char *base = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non nisi ligula. Ut viverra enim sed lobortis suscipit.\nPhasellus eget erat odio. Praesent at est iaculis, ultricies augue vel, dignissim risus. Suspendisse at nisi quis turpis fringilla rutrum id sit amet nulla.\nNam eget dolor fermentum, aliquet nisl at, convallis tellus. Pellentesque rhoncus erat enim, id porttitor elit euismod quis.\nMauris sollicitudin magna odio, non egestas libero vehicula ut. Etiam et quam velit. Fusce eget libero rhoncus, ultricies felis sit amet, egestas purus.\nAliquam in semper tellus. Pellentesque adipiscing rutrum velit, quis malesuada lacus consequat eget.\n";
+	git_index *idx;
+	git_diff *diff;
+	git_patch *patch;
+	git_buf actual = GIT_BUF_INIT;
+	const char *expected = "diff --git a/longlines.txt b/longlines.txt\nindex c1ce6ef..0134431 100644\n--- a/longlines.txt\n+++ b/longlines.txt\n@@ -3,3 +3,5 @@ Phasellus eget erat odio. Praesent at est iaculis, ultricies augue vel, dignissi\n Nam eget dolor fermentum, aliquet nisl at, convallis tellus. Pellentesque rhoncus erat enim, id porttitor elit euismod quis.\n Mauris sollicitudin magna odio, non egestas libero vehicula ut. Etiam et quam velit. Fusce eget libero rhoncus, ultricies felis sit amet, egestas purus.\n Aliquam in semper tellus. Pellentesque adipiscing rutrum velit, quis malesuada lacus consequat eget.\n+newline\n+newline\n";
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+	cl_git_mkfile("empty_standard_repo/longlines.txt", base);
+	cl_git_pass(git_repository_index(&idx, g_repo));
+	cl_git_pass(git_index_add_bypath(idx, "longlines.txt"));
+	cl_git_pass(git_index_write(idx));
+	git_index_free(idx);
+
+	cl_git_append2file("empty_standard_repo/longlines.txt", "newline\nnewline\n");
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, NULL));
+	cl_assert_equal_sz(1, git_diff_num_deltas(diff));
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_git_pass(git_patch_to_buf(&actual, patch));
+
+	/* if chmod not supported, overwrite mode bits since anything is possible */
+	overwrite_filemode(expected, &actual);
+
+	cl_assert_equal_s(expected, actual.ptr);
+
+	git_buf_free(&actual);
+	git_patch_free(patch);
+	git_diff_free(diff);
+}
+
+void test_diff_drivers__builtins(void)
+{
+	git_diff *diff;
+	git_patch *patch;
+	git_buf file = GIT_BUF_INIT, actual = GIT_BUF_INIT, expected = GIT_BUF_INIT;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_vector files = GIT_VECTOR_INIT;
+	size_t i;
+	char *path, *extension;
+
+	g_repo = cl_git_sandbox_init("userdiff");
+
+	cl_git_pass(git_path_dirload(&files, "userdiff/files", 9, 0));
+
+	opts.interhunk_lines = 1;
+	opts.context_lines = 1;
+	opts.pathspec.count = 1;
+
+	git_vector_foreach(&files, i, path) {
+		if (git__prefixcmp(path, "files/file."))
+			continue;
+		extension = path + strlen("files/file.");
+		opts.pathspec.strings = &path;
+
+		/* do diff with no special driver */
+
+		cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+		cl_assert_equal_sz(1, git_diff_num_deltas(diff));
+		cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+		cl_git_pass(git_patch_to_buf(&actual, patch));
+
+		git_buf_sets(&expected, "userdiff/expected/nodriver/diff.");
+		git_buf_puts(&expected, extension);
+		cl_git_pass(git_futils_readbuffer(&expected, expected.ptr));
+
+		overwrite_filemode(expected.ptr, &actual);
+
+		cl_assert_equal_s(expected.ptr, actual.ptr);
+
+		git_buf_clear(&actual);
+		git_patch_free(patch);
+		git_diff_free(diff);
+
+		/* do diff with driver */
+
+		{
+			FILE *fp = fopen("userdiff/.gitattributes", "w");
+			fprintf(fp, "*.%s diff=%s\n", extension, extension);
+			fclose(fp);
+		}
+
+		cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+		cl_assert_equal_sz(1, git_diff_num_deltas(diff));
+		cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+		cl_git_pass(git_patch_to_buf(&actual, patch));
+
+		git_buf_sets(&expected, "userdiff/expected/driver/diff.");
+		git_buf_puts(&expected, extension);
+		cl_git_pass(git_futils_readbuffer(&expected, expected.ptr));
+
+		overwrite_filemode(expected.ptr, &actual);
+
+		cl_assert_equal_s(expected.ptr, actual.ptr);
+
+		git_buf_clear(&actual);
+		git_patch_free(patch);
+		git_diff_free(diff);
+
+		git__free(path);
+	}
+
+	git_buf_free(&file);
+	git_buf_free(&actual);
+	git_buf_free(&expected);
+	git_vector_free(&files);
+}
+
+void test_diff_drivers__invalid_pattern(void)
+{
+	git_config *cfg;
+	git_index *idx;
+	git_diff *diff;
+	git_patch *patch;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+
+	g_repo = cl_git_sandbox_init("userdiff");
+	cl_git_mkfile("userdiff/.gitattributes", "*.storyboard diff=storyboard\n");
+
+	cl_git_pass(git_repository_config__weakptr(&cfg, g_repo));
+	cl_git_pass(git_config_set_string(cfg, "diff.storyboard.xfuncname", "<!--(.*?)-->"));
+
+	cl_git_mkfile("userdiff/dummy.storyboard", "");
+	cl_git_pass(git_repository_index__weakptr(&idx, g_repo));
+	cl_git_pass(git_index_add_bypath(idx, "dummy.storyboard"));
+	cl_git_mkfile("userdiff/dummy.storyboard", "some content\n");
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+
+	git_patch_free(patch);
+	git_diff_free(diff);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/format_email.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/format_email.c
new file mode 100755
index 0000000..18ad99b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/format_email.c
@@ -0,0 +1,467 @@
+#include "clar.h"
+#include "clar_libgit2.h"
+
+#include "buffer.h"
+#include "commit.h"
+#include "diff.h"
+
+static git_repository *repo;
+
+void test_diff_format_email__initialize(void)
+{
+	repo = cl_git_sandbox_init("diff_format_email");
+}
+
+void test_diff_format_email__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static void assert_email_match(
+	const char *expected,
+	const char *oidstr,
+	git_diff_format_email_options *opts)
+{
+	git_oid oid;
+	git_commit *commit = NULL;
+	git_diff *diff = NULL;
+	git_buf buf = GIT_BUF_INIT;
+
+	git_oid_fromstr(&oid, oidstr);
+
+	cl_git_pass(git_commit_lookup(&commit, repo, &oid));
+
+	opts->id = git_commit_id(commit);
+	opts->author = git_commit_author(commit);
+	if (!opts->summary)
+		opts->summary = git_commit_summary(commit);
+
+	cl_git_pass(git_diff__commit(&diff, repo, commit, NULL));
+	cl_git_pass(git_diff_format_email(&buf, diff, opts));
+
+	cl_assert_equal_s(expected, git_buf_cstr(&buf));
+	git_buf_clear(&buf);
+
+	cl_git_pass(git_diff_commit_as_email(
+		&buf, repo, commit, 1, 1, opts->flags, NULL));
+	cl_assert_equal_s(expected, git_buf_cstr(&buf));
+
+	git_diff_free(diff);
+	git_commit_free(commit);
+	git_buf_free(&buf);
+}
+
+void test_diff_format_email__simple(void)
+{
+	git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT;
+	const char *email =
+	"From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001\n" \
+	"From: Jacques Germishuys <jacquesg at striata.com>\n" \
+	"Date: Wed, 9 Apr 2014 20:57:01 +0200\n" \
+	"Subject: [PATCH] Modify some content\n" \
+	"\n" \
+	"---\n" \
+	" file1.txt | 8 +++++---\n" \
+	" 1 file changed, 5 insertions(+), 3 deletions(-)\n" \
+	"\n" \
+	"diff --git a/file1.txt b/file1.txt\n" \
+	"index 94aaae8..af8f41d 100644\n" \
+	"--- a/file1.txt\n" \
+	"+++ b/file1.txt\n" \
+	"@@ -1,15 +1,17 @@\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	"+_file1.txt_\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	"+\n" \
+	"+\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	"-file1.txt\n" \
+	"-file1.txt\n" \
+	"-file1.txt\n" \
+	"+_file1.txt_\n" \
+	"+_file1.txt_\n" \
+	" file1.txt\n" \
+	"--\n" \
+	"libgit2 " LIBGIT2_VERSION "\n" \
+	"\n";
+
+	assert_email_match(
+		email, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts);
+}
+
+void test_diff_format_email__multiple(void)
+{
+	git_oid oid;
+	git_commit *commit = NULL;
+	git_diff *diff = NULL;
+ 	git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT;
+	git_buf buf = GIT_BUF_INIT;
+
+	const char *email =
+	"From 10808fe9c9be5a190c0ba68d1a002233fb363508 Mon Sep 17 00:00:00 2001\n" \
+	"From: Jacques Germishuys <jacquesg at striata.com>\n" \
+	"Date: Thu, 10 Apr 2014 19:37:05 +0200\n" \
+	"Subject: [PATCH 1/2] Added file2.txt file3.txt\n" \
+	"\n" \
+	"---\n" \
+	" file2.txt | 5 +++++\n" \
+	" file3.txt | 5 +++++\n" \
+	" 2 files changed, 10 insertions(+), 0 deletions(-)\n" \
+	" create mode 100644 file2.txt\n" \
+	" create mode 100644 file3.txt\n" \
+	"\n" \
+	"diff --git a/file2.txt b/file2.txt\n" \
+	"new file mode 100644\n" \
+	"index 0000000..e909123\n" \
+	"--- /dev/null\n" \
+	"+++ b/file2.txt\n" \
+	"@@ -0,0 +1,5 @@\n" \
+	"+file2\n" \
+	"+file2\n" \
+	"+file2\n" \
+	"+file2\n" \
+	"+file2\n" \
+	"diff --git a/file3.txt b/file3.txt\n" \
+	"new file mode 100644\n" \
+	"index 0000000..9435022\n" \
+	"--- /dev/null\n" \
+	"+++ b/file3.txt\n" \
+	"@@ -0,0 +1,5 @@\n" \
+	"+file3\n" \
+	"+file3\n" \
+	"+file3\n" \
+	"+file3\n" \
+	"+file3\n" \
+	"--\n" \
+	"libgit2 " LIBGIT2_VERSION "\n" \
+	"\n" \
+	"From 873806f6f27e631eb0b23e4b56bea2bfac14a373 Mon Sep 17 00:00:00 2001\n" \
+	"From: Jacques Germishuys <jacquesg at striata.com>\n" \
+	"Date: Thu, 10 Apr 2014 19:37:36 +0200\n" \
+	"Subject: [PATCH 2/2] Modified file2.txt, file3.txt\n" \
+	"\n" \
+	"---\n" \
+	" file2.txt | 2 +-\n" \
+	" file3.txt | 2 +-\n" \
+	" 2 files changed, 2 insertions(+), 2 deletions(-)\n" \
+	"\n" \
+	"diff --git a/file2.txt b/file2.txt\n" \
+	"index e909123..7aff11d 100644\n" \
+	"--- a/file2.txt\n" \
+	"+++ b/file2.txt\n" \
+	"@@ -1,5 +1,5 @@\n" \
+	" file2\n" \
+	" file2\n" \
+	" file2\n" \
+	"-file2\n" \
+	"+file2!\n" \
+	" file2\n" \
+	"diff --git a/file3.txt b/file3.txt\n" \
+	"index 9435022..9a2d780 100644\n" \
+	"--- a/file3.txt\n" \
+	"+++ b/file3.txt\n" \
+	"@@ -1,5 +1,5 @@\n" \
+	" file3\n" \
+	"-file3\n" \
+	"+file3!\n" \
+	" file3\n" \
+	" file3\n" \
+	" file3\n" \
+	"--\n" \
+	"libgit2 " LIBGIT2_VERSION "\n" \
+	"\n";
+
+
+	git_oid_fromstr(&oid, "10808fe9c9be5a190c0ba68d1a002233fb363508");
+	cl_git_pass(git_commit_lookup(&commit, repo, &oid));
+
+	opts.id = git_commit_id(commit);
+	opts.author = git_commit_author(commit);
+	opts.summary = git_commit_summary(commit);
+	opts.patch_no = 1;
+	opts.total_patches = 2;
+
+	cl_git_pass(git_diff__commit(&diff, repo, commit, NULL));
+	cl_git_pass(git_diff_format_email(&buf, diff, &opts));
+
+	git_diff_free(diff);
+	git_commit_free(commit);
+	diff = NULL;
+	commit = NULL;
+
+	git_oid_fromstr(&oid, "873806f6f27e631eb0b23e4b56bea2bfac14a373");
+	cl_git_pass(git_commit_lookup(&commit, repo, &oid));
+
+	opts.id = git_commit_id(commit);
+	opts.author = git_commit_author(commit);
+	opts.summary = git_commit_summary(commit);
+	opts.patch_no = 2;
+	opts.total_patches = 2;
+
+	cl_git_pass(git_diff__commit(&diff, repo, commit, NULL));
+	cl_git_pass(git_diff_format_email(&buf, diff, &opts));
+
+	cl_assert_equal_s(email, git_buf_cstr(&buf));
+
+	git_diff_free(diff);
+	git_commit_free(commit);
+	git_buf_free(&buf);
+}
+
+void test_diff_format_email__exclude_marker(void)
+{
+	git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT;
+	const char *email =
+	"From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001\n" \
+	"From: Jacques Germishuys <jacquesg at striata.com>\n" \
+	"Date: Wed, 9 Apr 2014 20:57:01 +0200\n" \
+	"Subject: Modify some content\n" \
+	"\n" \
+	"---\n" \
+	" file1.txt | 8 +++++---\n" \
+	" 1 file changed, 5 insertions(+), 3 deletions(-)\n" \
+	"\n" \
+	"diff --git a/file1.txt b/file1.txt\n" \
+	"index 94aaae8..af8f41d 100644\n" \
+	"--- a/file1.txt\n" \
+	"+++ b/file1.txt\n" \
+	"@@ -1,15 +1,17 @@\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	"+_file1.txt_\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	"+\n" \
+	"+\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	"-file1.txt\n" \
+	"-file1.txt\n" \
+	"-file1.txt\n" \
+	"+_file1.txt_\n" \
+	"+_file1.txt_\n" \
+	" file1.txt\n" \
+	"--\n" \
+	"libgit2 " LIBGIT2_VERSION "\n" \
+	"\n";
+
+	opts.flags |= GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER;
+
+	assert_email_match(
+		email, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts);
+}
+
+void test_diff_format_email__invalid_no(void)
+{
+	git_oid oid;
+	git_commit *commit = NULL;
+	git_diff *diff = NULL;
+	git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT;
+	git_buf buf = GIT_BUF_INIT;
+
+	git_oid_fromstr(&oid, "9264b96c6d104d0e07ae33d3007b6a48246c6f92");
+
+	cl_git_pass(git_commit_lookup(&commit, repo, &oid));
+
+	opts.id = git_commit_id(commit);
+	opts.author = git_commit_author(commit);
+	opts.summary = git_commit_summary(commit);
+	opts.patch_no = 2;
+	opts.total_patches = 1;
+
+	cl_git_pass(git_diff__commit(&diff, repo, commit, NULL));
+	cl_git_fail(git_diff_format_email(&buf, diff, &opts));
+	cl_git_fail(git_diff_commit_as_email(&buf, repo, commit, 2, 1, 0, NULL));
+	cl_git_fail(git_diff_commit_as_email(&buf, repo, commit, 0, 0, 0, NULL));
+
+	git_diff_free(diff);
+	git_commit_free(commit);
+	git_buf_free(&buf);
+}
+
+void test_diff_format_email__mode_change(void)
+{
+	git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT;
+	const char *email =
+	"From 7ade76dd34bba4733cf9878079f9fd4a456a9189 Mon Sep 17 00:00:00 2001\n" \
+	"From: Jacques Germishuys <jacquesg at striata.com>\n" \
+	"Date: Thu, 10 Apr 2014 10:05:03 +0200\n" \
+	"Subject: [PATCH] Update permissions\n" \
+	"\n" \
+	"---\n" \
+	" file1.txt.renamed | 0\n" \
+	" 1 file changed, 0 insertions(+), 0 deletions(-)\n" \
+	" mode change 100644 => 100755 file1.txt.renamed\n" \
+	"\n" \
+	"diff --git a/file1.txt.renamed b/file1.txt.renamed\n" \
+	"old mode 100644\n" \
+	"new mode 100755\n" \
+	"index a97157a..a97157a\n" \
+	"--- a/file1.txt.renamed\n" \
+	"+++ b/file1.txt.renamed\n" \
+	"--\n" \
+	"libgit2 " LIBGIT2_VERSION "\n" \
+	"\n";
+
+	assert_email_match(
+		email, "7ade76dd34bba4733cf9878079f9fd4a456a9189", &opts);
+}
+
+void test_diff_format_email__rename_add_remove(void)
+{
+	git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT;
+	const char *email =
+	"From 6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d Mon Sep 17 00:00:00 2001\n" \
+	"From: Jacques Germishuys <jacquesg at striata.com>\n" \
+	"Date: Wed, 9 Apr 2014 21:15:56 +0200\n" \
+	"Subject: [PATCH] Renamed file1.txt -> file1.txt.renamed\n" \
+	"\n" \
+	"---\n" \
+	" file1.txt         | 17 -----------------\n" \
+	" file1.txt.renamed | 17 +++++++++++++++++\n" \
+	" 2 files changed, 17 insertions(+), 17 deletions(-)\n" \
+	" delete mode 100644 file1.txt\n" \
+	" create mode 100644 file1.txt.renamed\n" \
+	"\n" \
+	"diff --git a/file1.txt b/file1.txt\n" \
+	"deleted file mode 100644\n" \
+	"index af8f41d..0000000\n" \
+	"--- a/file1.txt\n" \
+	"+++ /dev/null\n" \
+	"@@ -1,17 +0,0 @@\n" \
+	"-file1.txt\n" \
+	"-file1.txt\n" \
+	"-_file1.txt_\n" \
+	"-file1.txt\n" \
+	"-file1.txt\n" \
+	"-file1.txt\n" \
+	"-file1.txt\n" \
+	"-\n" \
+	"-\n" \
+	"-file1.txt\n" \
+	"-file1.txt\n" \
+	"-file1.txt\n" \
+	"-file1.txt\n" \
+	"-file1.txt\n" \
+	"-_file1.txt_\n" \
+	"-_file1.txt_\n" \
+	"-file1.txt\n" \
+	"diff --git a/file1.txt.renamed b/file1.txt.renamed\n" \
+	"new file mode 100644\n" \
+	"index 0000000..a97157a\n" \
+	"--- /dev/null\n" \
+	"+++ b/file1.txt.renamed\n" \
+	"@@ -0,0 +1,17 @@\n" \
+	"+file1.txt\n" \
+	"+file1.txt\n" \
+	"+_file1.txt_\n" \
+	"+file1.txt\n" \
+	"+file1.txt\n" \
+	"+file1.txt_renamed\n" \
+	"+file1.txt\n" \
+	"+\n" \
+	"+\n" \
+	"+file1.txt\n" \
+	"+file1.txt\n" \
+	"+file1.txt_renamed\n" \
+	"+file1.txt\n" \
+	"+file1.txt\n" \
+	"+_file1.txt_\n" \
+	"+_file1.txt_\n" \
+	"+file1.txt\n" \
+	"--\n" \
+	"libgit2 " LIBGIT2_VERSION "\n" \
+	"\n";
+
+	assert_email_match(
+		email, "6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d", &opts);
+}
+
+void test_diff_format_email__multiline_summary(void)
+{
+	git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT;
+	const char *email =
+	"From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001\n" \
+	"From: Jacques Germishuys <jacquesg at striata.com>\n" \
+	"Date: Wed, 9 Apr 2014 20:57:01 +0200\n" \
+	"Subject: [PATCH] Modify some content\n" \
+	"\n" \
+	"---\n" \
+	" file1.txt | 8 +++++---\n" \
+	" 1 file changed, 5 insertions(+), 3 deletions(-)\n" \
+	"\n" \
+	"diff --git a/file1.txt b/file1.txt\n" \
+	"index 94aaae8..af8f41d 100644\n" \
+	"--- a/file1.txt\n" \
+	"+++ b/file1.txt\n" \
+	"@@ -1,15 +1,17 @@\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	"+_file1.txt_\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	"+\n" \
+	"+\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	" file1.txt\n" \
+	"-file1.txt\n" \
+	"-file1.txt\n" \
+	"-file1.txt\n" \
+	"+_file1.txt_\n" \
+	"+_file1.txt_\n" \
+	" file1.txt\n" \
+	"--\n" \
+	"libgit2 " LIBGIT2_VERSION "\n" \
+	"\n";
+
+	opts.summary = "Modify some content\nSome extra stuff here";
+
+	assert_email_match(
+		email, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts);
+}
+
+void test_diff_format_email__binary(void)
+{
+	git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT;
+	const char *email =
+	"From 8d7523f6fcb2404257889abe0d96f093d9f524f9 Mon Sep 17 00:00:00 2001\n" \
+	"From: Jacques Germishuys <jacquesg at striata.com>\n" \
+	"Date: Sun, 13 Apr 2014 18:10:18 +0200\n" \
+	"Subject: [PATCH] Modified binary file\n" \
+	"\n" \
+	"---\n" \
+	" binary.bin | Bin 3 -> 0 bytes\n" \
+	" 1 file changed, 0 insertions(+), 0 deletions(-)\n" \
+	"\n" \
+	"diff --git a/binary.bin b/binary.bin\n" \
+	"index bd474b2..9ac35ff 100644\n" \
+	"Binary files a/binary.bin and b/binary.bin differ\n" \
+	"--\n" \
+	"libgit2 " LIBGIT2_VERSION "\n" \
+	"\n";
+	/* TODO: Actually 0 bytes here should be 5!. Seems like we don't load the new content for binary files? */
+
+	opts.summary = "Modified binary file";
+
+	assert_email_match(
+		email, "8d7523f6fcb2404257889abe0d96f093d9f524f9", &opts);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/index.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/index.c
new file mode 100755
index 0000000..f702568
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/index.c
@@ -0,0 +1,270 @@
+#include "clar_libgit2.h"
+#include "diff_helpers.h"
+
+static git_repository *g_repo = NULL;
+
+void test_diff_index__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("status");
+}
+
+void test_diff_index__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_diff_index__0(void)
+{
+	/* grabbed a couple of commit oids from the history of the attr repo */
+	const char *a_commit = "26a125ee1bf"; /* the current HEAD */
+	const char *b_commit = "0017bd4ab1ec3"; /* the start */
+	git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit);
+	git_tree *b = resolve_commit_oid_to_tree(g_repo, b_commit);
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	diff_expects exp;
+
+	cl_assert(a);
+	cl_assert(b);
+
+	opts.context_lines = 1;
+	opts.interhunk_lines = 1;
+
+	memset(&exp, 0, sizeof(exp));
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, NULL, &opts));
+
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	/* to generate these values:
+	 * - cd to tests/resources/status,
+	 * - mv .gitted .git
+	 * - git diff --name-status --cached 26a125ee1bf
+	 * - git diff -U1 --cached 26a125ee1bf
+	 * - mv .git .gitted
+	 */
+	cl_assert_equal_i(8, exp.files);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]);
+
+	cl_assert_equal_i(8, exp.hunks);
+
+	cl_assert_equal_i(11, exp.lines);
+	cl_assert_equal_i(3, exp.line_ctxt);
+	cl_assert_equal_i(6, exp.line_adds);
+	cl_assert_equal_i(2, exp.line_dels);
+
+	git_diff_free(diff);
+	diff = NULL;
+	memset(&exp, 0, sizeof(exp));
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, b, NULL, &opts));
+
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	/* to generate these values:
+	 * - cd to tests/resources/status,
+	 * - mv .gitted .git
+	 * - git diff --name-status --cached 0017bd4ab1ec3
+	 * - git diff -U1 --cached 0017bd4ab1ec3
+	 * - mv .git .gitted
+	 */
+	cl_assert_equal_i(12, exp.files);
+	cl_assert_equal_i(7, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]);
+
+	cl_assert_equal_i(12, exp.hunks);
+
+	cl_assert_equal_i(16, exp.lines);
+	cl_assert_equal_i(3, exp.line_ctxt);
+	cl_assert_equal_i(11, exp.line_adds);
+	cl_assert_equal_i(2, exp.line_dels);
+
+	git_diff_free(diff);
+	diff = NULL;
+
+	git_tree_free(a);
+	git_tree_free(b);
+}
+
+static int diff_stop_after_2_files(
+	const git_diff_delta *delta,
+	float progress,
+	void *payload)
+{
+	diff_expects *e = payload;
+
+	GIT_UNUSED(progress);
+	GIT_UNUSED(delta);
+
+	e->files++;
+
+	return (e->files == 2);
+}
+
+void test_diff_index__1(void)
+{
+	/* grabbed a couple of commit oids from the history of the attr repo */
+	const char *a_commit = "26a125ee1bf"; /* the current HEAD */
+	const char *b_commit = "0017bd4ab1ec3"; /* the start */
+	git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit);
+	git_tree *b = resolve_commit_oid_to_tree(g_repo, b_commit);
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	diff_expects exp;
+
+	cl_assert(a);
+	cl_assert(b);
+
+	opts.context_lines = 1;
+	opts.interhunk_lines = 1;
+
+	memset(&exp, 0, sizeof(exp));
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, NULL, &opts));
+
+	cl_assert_equal_i(1, git_diff_foreach(
+		diff, diff_stop_after_2_files, NULL, NULL, NULL, &exp) );
+
+	cl_assert_equal_i(2, exp.files);
+
+	git_diff_free(diff);
+	diff = NULL;
+
+	git_tree_free(a);
+	git_tree_free(b);
+}
+
+void test_diff_index__checks_options_version(void)
+{
+	const char *a_commit = "26a125ee1bf";
+	git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit);
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	const git_error *err;
+
+	opts.version = 0;
+	cl_git_fail(git_diff_tree_to_index(&diff, g_repo, a, NULL, &opts));
+	err = giterr_last();
+	cl_assert_equal_i(GITERR_INVALID, err->klass);
+	cl_assert_equal_p(diff, NULL);
+
+	giterr_clear();
+	opts.version = 1024;
+	cl_git_fail(git_diff_tree_to_index(&diff, g_repo, a, NULL, &opts));
+	err = giterr_last();
+	cl_assert_equal_i(GITERR_INVALID, err->klass);
+	cl_assert_equal_p(diff, NULL);
+
+	git_tree_free(a);
+}
+
+static void do_conflicted_diff(diff_expects *exp, unsigned long flags)
+{
+	const char *a_commit = "26a125ee1bf"; /* the current HEAD */
+	git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit);
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_index_entry ancestor = {{0}}, ours = {{0}}, theirs = {{0}};
+	git_diff *diff = NULL;
+	git_index *index;
+
+	cl_assert(a);
+
+	opts.context_lines = 1;
+	opts.interhunk_lines = 1;
+	opts.flags |= flags;
+
+	memset(exp, 0, sizeof(diff_expects));
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	ancestor.path = ours.path = theirs.path = "staged_changes";
+	ancestor.mode = ours.mode = theirs.mode = GIT_FILEMODE_BLOB;
+
+	git_oid_fromstr(&ancestor.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
+	git_oid_fromstr(&ours.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
+	git_oid_fromstr(&theirs.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
+
+	cl_git_pass(git_index_conflict_add(index, &ancestor, &ours, &theirs));
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, index, &opts));
+
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, exp));
+
+	git_diff_free(diff);
+	git_tree_free(a);
+	git_index_free(index);
+}
+
+void test_diff_index__reports_conflicts(void)
+{
+	diff_expects exp;
+
+	do_conflicted_diff(&exp, 0);
+
+	cl_assert_equal_i(8, exp.files);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_CONFLICTED]);
+
+	cl_assert_equal_i(7, exp.hunks);
+
+	cl_assert_equal_i(9, exp.lines);
+	cl_assert_equal_i(2, exp.line_ctxt);
+	cl_assert_equal_i(5, exp.line_adds);
+	cl_assert_equal_i(2, exp.line_dels);
+}
+
+void test_diff_index__reports_conflicts_when_reversed(void)
+{
+	diff_expects exp;
+
+	do_conflicted_diff(&exp, GIT_DIFF_REVERSE);
+
+	cl_assert_equal_i(8, exp.files);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_CONFLICTED]);
+
+	cl_assert_equal_i(7, exp.hunks);
+
+	cl_assert_equal_i(9, exp.lines);
+	cl_assert_equal_i(2, exp.line_ctxt);
+	cl_assert_equal_i(2, exp.line_adds);
+	cl_assert_equal_i(5, exp.line_dels);
+}
+
+void test_diff_index__not_in_head_conflicted(void)
+{
+	const char *a_commit = "26a125ee1bf"; /* the current HEAD */
+	git_index_entry theirs = {{0}};
+	git_index *index;
+	git_diff *diff;
+	const git_diff_delta *delta;
+
+	git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit);
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_read_tree(index, a));
+
+	theirs.path = "file_not_in_head";
+	theirs.mode = GIT_FILEMODE_BLOB;
+	git_oid_fromstr(&theirs.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
+	cl_git_pass(git_index_conflict_add(index, NULL, NULL, &theirs));
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, index, NULL));
+
+	cl_assert_equal_i(git_diff_num_deltas(diff), 1);
+	delta = git_diff_get_delta(diff, 0);
+	cl_assert_equal_i(delta->status, GIT_DELTA_CONFLICTED);
+
+	git_diff_free(diff);
+	git_index_free(index);
+	git_tree_free(a);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/iterator.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/iterator.c
new file mode 100755
index 0000000..6011c6a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/iterator.c
@@ -0,0 +1,980 @@
+#include "clar_libgit2.h"
+#include "diff_helpers.h"
+#include "iterator.h"
+#include "tree.h"
+
+void test_diff_iterator__initialize(void)
+{
+	/* since we are doing tests with different sandboxes, defer setup
+	 * to the actual tests.  cleanup will still be done in the global
+	 * cleanup function so that assertion failures don't result in a
+	 * missed cleanup.
+	 */
+}
+
+void test_diff_iterator__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+
+/* -- TREE ITERATOR TESTS -- */
+
+static void tree_iterator_test(
+	const char *sandbox,
+	const char *treeish,
+	const char *start,
+	const char *end,
+	int expected_count,
+	const char **expected_values)
+{
+	git_tree *t;
+	git_iterator *i;
+	const git_index_entry *entry;
+	int error, count = 0, count_post_reset = 0;
+	git_repository *repo = cl_git_sandbox_init(sandbox);
+
+	cl_assert(t = resolve_commit_oid_to_tree(repo, treeish));
+	cl_git_pass(git_iterator_for_tree(
+		&i, t, GIT_ITERATOR_DONT_IGNORE_CASE, start, end));
+
+	/* test loop */
+	while (!(error = git_iterator_advance(&entry, i))) {
+		cl_assert(entry);
+		if (expected_values != NULL)
+			cl_assert_equal_s(expected_values[count], entry->path);
+		count++;
+	}
+	cl_assert_equal_i(GIT_ITEROVER, error);
+	cl_assert(!entry);
+	cl_assert_equal_i(expected_count, count);
+
+	/* test reset */
+	cl_git_pass(git_iterator_reset(i, NULL, NULL));
+
+	while (!(error = git_iterator_advance(&entry, i))) {
+		cl_assert(entry);
+		if (expected_values != NULL)
+			cl_assert_equal_s(expected_values[count_post_reset], entry->path);
+		count_post_reset++;
+	}
+	cl_assert_equal_i(GIT_ITEROVER, error);
+	cl_assert(!entry);
+	cl_assert_equal_i(count, count_post_reset);
+
+	git_iterator_free(i);
+	git_tree_free(t);
+}
+
+/* results of: git ls-tree -r --name-only 605812a */
+const char *expected_tree_0[] = {
+	".gitattributes",
+	"attr0",
+	"attr1",
+	"attr2",
+	"attr3",
+	"binfile",
+	"macro_test",
+	"root_test1",
+	"root_test2",
+	"root_test3",
+	"root_test4.txt",
+	"subdir/.gitattributes",
+	"subdir/abc",
+	"subdir/subdir_test1",
+	"subdir/subdir_test2.txt",
+	"subdir2/subdir2_test1",
+	NULL
+};
+
+void test_diff_iterator__tree_0(void)
+{
+	tree_iterator_test("attr", "605812a", NULL, NULL, 16, expected_tree_0);
+}
+
+/* results of: git ls-tree -r --name-only 6bab5c79 */
+const char *expected_tree_1[] = {
+	".gitattributes",
+	"attr0",
+	"attr1",
+	"attr2",
+	"attr3",
+	"root_test1",
+	"root_test2",
+	"root_test3",
+	"root_test4.txt",
+	"subdir/.gitattributes",
+	"subdir/subdir_test1",
+	"subdir/subdir_test2.txt",
+	"subdir2/subdir2_test1",
+	NULL
+};
+
+void test_diff_iterator__tree_1(void)
+{
+	tree_iterator_test("attr", "6bab5c79cd5", NULL, NULL, 13, expected_tree_1);
+}
+
+/* results of: git ls-tree -r --name-only 26a125ee1 */
+const char *expected_tree_2[] = {
+	"current_file",
+	"file_deleted",
+	"modified_file",
+	"staged_changes",
+	"staged_changes_file_deleted",
+	"staged_changes_modified_file",
+	"staged_delete_file_deleted",
+	"staged_delete_modified_file",
+	"subdir.txt",
+	"subdir/current_file",
+	"subdir/deleted_file",
+	"subdir/modified_file",
+	NULL
+};
+
+void test_diff_iterator__tree_2(void)
+{
+	tree_iterator_test("status", "26a125ee1", NULL, NULL, 12, expected_tree_2);
+}
+
+/* $ git ls-tree -r --name-only 0017bd4ab1e */
+const char *expected_tree_3[] = {
+	"current_file",
+	"file_deleted",
+	"modified_file",
+	"staged_changes",
+	"staged_changes_file_deleted",
+	"staged_changes_modified_file",
+	"staged_delete_file_deleted",
+	"staged_delete_modified_file"
+};
+
+void test_diff_iterator__tree_3(void)
+{
+	tree_iterator_test("status", "0017bd4ab1e", NULL, NULL, 8, expected_tree_3);
+}
+
+/* $ git ls-tree -r --name-only 24fa9a9fc4e202313e24b648087495441dab432b */
+const char *expected_tree_4[] = {
+	"attr0",
+	"attr1",
+	"attr2",
+	"attr3",
+	"binfile",
+	"gitattributes",
+	"macro_bad",
+	"macro_test",
+	"root_test1",
+	"root_test2",
+	"root_test3",
+	"root_test4.txt",
+	"sub/abc",
+	"sub/file",
+	"sub/sub/file",
+	"sub/sub/subsub.txt",
+	"sub/subdir_test1",
+	"sub/subdir_test2.txt",
+	"subdir/.gitattributes",
+	"subdir/abc",
+	"subdir/subdir_test1",
+	"subdir/subdir_test2.txt",
+	"subdir2/subdir2_test1",
+	NULL
+};
+
+void test_diff_iterator__tree_4(void)
+{
+	tree_iterator_test(
+		"attr", "24fa9a9fc4e202313e24b648087495441dab432b", NULL, NULL,
+		23, expected_tree_4);
+}
+
+void test_diff_iterator__tree_4_ranged(void)
+{
+	tree_iterator_test(
+		"attr", "24fa9a9fc4e202313e24b648087495441dab432b",
+		"sub", "sub",
+		11, &expected_tree_4[12]);
+}
+
+const char *expected_tree_ranged_0[] = {
+	"gitattributes",
+	"macro_bad",
+	"macro_test",
+	"root_test1",
+	"root_test2",
+	"root_test3",
+	"root_test4.txt",
+	NULL
+};
+
+void test_diff_iterator__tree_ranged_0(void)
+{
+	tree_iterator_test(
+		"attr", "24fa9a9fc4e202313e24b648087495441dab432b",
+		"git", "root",
+		7, expected_tree_ranged_0);
+}
+
+const char *expected_tree_ranged_1[] = {
+	"sub/subdir_test2.txt",
+	NULL
+};
+
+void test_diff_iterator__tree_ranged_1(void)
+{
+	tree_iterator_test(
+		"attr", "24fa9a9fc4e202313e24b648087495441dab432b",
+		"sub/subdir_test2.txt", "sub/subdir_test2.txt",
+		1, expected_tree_ranged_1);
+}
+
+void test_diff_iterator__tree_range_empty_0(void)
+{
+	tree_iterator_test(
+		"attr", "24fa9a9fc4e202313e24b648087495441dab432b",
+		"empty", "empty", 0, NULL);
+}
+
+void test_diff_iterator__tree_range_empty_1(void)
+{
+	tree_iterator_test(
+		"attr", "24fa9a9fc4e202313e24b648087495441dab432b",
+		"z_empty_after", NULL, 0, NULL);
+}
+
+void test_diff_iterator__tree_range_empty_2(void)
+{
+	tree_iterator_test(
+		"attr", "24fa9a9fc4e202313e24b648087495441dab432b",
+		NULL, ".aaa_empty_before", 0, NULL);
+}
+
+static void check_tree_entry(
+	git_iterator *i,
+	const char *oid,
+	const char *oid_p,
+	const char *oid_pp,
+	const char *oid_ppp)
+{
+	const git_index_entry *ie;
+	const git_tree_entry *te;
+	const git_tree *tree;
+	git_buf path = GIT_BUF_INIT;
+
+	cl_git_pass(git_iterator_current_tree_entry(&te, i));
+	cl_assert(te);
+	cl_assert(git_oid_streq(&te->oid, oid) == 0);
+
+	cl_git_pass(git_iterator_current(&ie, i));
+	cl_git_pass(git_buf_sets(&path, ie->path));
+
+	if (oid_p) {
+		git_buf_rtruncate_at_char(&path, '/');
+		cl_git_pass(git_iterator_current_parent_tree(&tree, i, path.ptr));
+		cl_assert(tree);
+		cl_assert(git_oid_streq(git_tree_id(tree), oid_p) == 0);
+	}
+
+	if (oid_pp) {
+		git_buf_rtruncate_at_char(&path, '/');
+		cl_git_pass(git_iterator_current_parent_tree(&tree, i, path.ptr));
+		cl_assert(tree);
+		cl_assert(git_oid_streq(git_tree_id(tree), oid_pp) == 0);
+	}
+
+	if (oid_ppp) {
+		git_buf_rtruncate_at_char(&path, '/');
+		cl_git_pass(git_iterator_current_parent_tree(&tree, i, path.ptr));
+		cl_assert(tree);
+		cl_assert(git_oid_streq(git_tree_id(tree), oid_ppp) == 0);
+	}
+
+	git_buf_free(&path);
+}
+
+void test_diff_iterator__tree_special_functions(void)
+{
+	git_tree *t;
+	git_iterator *i;
+	const git_index_entry *entry;
+	git_repository *repo = cl_git_sandbox_init("attr");
+	int error, cases = 0;
+	const char *rootoid = "ce39a97a7fb1fa90bcf5e711249c1e507476ae0e";
+
+	t = resolve_commit_oid_to_tree(
+		repo, "24fa9a9fc4e202313e24b648087495441dab432b");
+	cl_assert(t != NULL);
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, t, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL));
+
+	while (!(error = git_iterator_advance(&entry, i))) {
+		cl_assert(entry);
+
+		if (strcmp(entry->path, "sub/file") == 0) {
+			cases++;
+			check_tree_entry(
+				i, "45b983be36b73c0788dc9cbcb76cbb80fc7bb057",
+				"ecb97df2a174987475ac816e3847fc8e9f6c596b",
+				rootoid, NULL);
+		}
+		else if (strcmp(entry->path, "sub/sub/subsub.txt") == 0) {
+			cases++;
+			check_tree_entry(
+				i, "9e5bdc47d6a80f2be0ea3049ad74231b94609242",
+				"4e49ba8c5b6c32ff28cd9dcb60be34df50fcc485",
+				"ecb97df2a174987475ac816e3847fc8e9f6c596b", rootoid);
+		}
+		else if (strcmp(entry->path, "subdir/.gitattributes") == 0) {
+			cases++;
+			check_tree_entry(
+				i, "99eae476896f4907224978b88e5ecaa6c5bb67a9",
+				"9fb40b6675dde60b5697afceae91b66d908c02d9",
+				rootoid, NULL);
+		}
+		else if (strcmp(entry->path, "subdir2/subdir2_test1") == 0) {
+			cases++;
+			check_tree_entry(
+				i, "dccada462d3df8ac6de596fb8c896aba9344f941",
+				"2929de282ce999e95183aedac6451d3384559c4b",
+				rootoid, NULL);
+		}
+	}
+	cl_assert_equal_i(GIT_ITEROVER, error);
+	cl_assert(!entry);
+	cl_assert_equal_i(4, cases);
+
+	git_iterator_free(i);
+	git_tree_free(t);
+}
+
+/* -- INDEX ITERATOR TESTS -- */
+
+static void index_iterator_test(
+	const char *sandbox,
+	const char *start,
+	const char *end,
+	git_iterator_flag_t flags,
+	int expected_count,
+	const char **expected_names,
+	const char **expected_oids)
+{
+	git_index *index;
+	git_iterator *i;
+	const git_index_entry *entry;
+	int error, count = 0, caps;
+	git_repository *repo = cl_git_sandbox_init(sandbox);
+
+	cl_git_pass(git_repository_index(&index, repo));
+	caps = git_index_caps(index);
+
+	cl_git_pass(git_iterator_for_index(&i, index, flags, start, end));
+
+	while (!(error = git_iterator_advance(&entry, i))) {
+		cl_assert(entry);
+
+		if (expected_names != NULL)
+			cl_assert_equal_s(expected_names[count], entry->path);
+
+		if (expected_oids != NULL) {
+			git_oid oid;
+			cl_git_pass(git_oid_fromstr(&oid, expected_oids[count]));
+			cl_assert_equal_oid(&oid, &entry->id);
+		}
+
+		count++;
+	}
+
+	cl_assert_equal_i(GIT_ITEROVER, error);
+	cl_assert(!entry);
+	cl_assert_equal_i(expected_count, count);
+
+	git_iterator_free(i);
+
+	cl_assert(caps == git_index_caps(index));
+	git_index_free(index);
+}
+
+static const char *expected_index_0[] = {
+	"attr0",
+	"attr1",
+	"attr2",
+	"attr3",
+	"binfile",
+	"gitattributes",
+	"macro_bad",
+	"macro_test",
+	"root_test1",
+	"root_test2",
+	"root_test3",
+	"root_test4.txt",
+	"sub/abc",
+	"sub/file",
+	"sub/sub/file",
+	"sub/sub/subsub.txt",
+	"sub/subdir_test1",
+	"sub/subdir_test2.txt",
+	"subdir/.gitattributes",
+	"subdir/abc",
+	"subdir/subdir_test1",
+	"subdir/subdir_test2.txt",
+	"subdir2/subdir2_test1",
+};
+
+static const char *expected_index_oids_0[] = {
+	"556f8c827b8e4a02ad5cab77dca2bcb3e226b0b3",
+	"3b74db7ab381105dc0d28f8295a77f6a82989292",
+	"2c66e14f77196ea763fb1e41612c1aa2bc2d8ed2",
+	"c485abe35abd4aa6fd83b076a78bbea9e2e7e06c",
+	"d800886d9c86731ae5c4a62b0b77c437015e00d2",
+	"2b40c5aca159b04ea8d20ffe36cdf8b09369b14a",
+	"5819a185d77b03325aaf87cafc771db36f6ddca7",
+	"ff69f8639ce2e6010b3f33a74160aad98b48da2b",
+	"45141a79a77842c59a63229403220a4e4be74e3d",
+	"4d713dc48e6b1bd75b0d61ad078ba9ca3a56745d",
+	"108bb4e7fd7b16490dc33ff7d972151e73d7166e",
+	"a0f7217ae99f5ac3e88534f5cea267febc5fa85b",
+	"3e42ffc54a663f9401cc25843d6c0e71a33e4249",
+	"45b983be36b73c0788dc9cbcb76cbb80fc7bb057",
+	"45b983be36b73c0788dc9cbcb76cbb80fc7bb057",
+	"9e5bdc47d6a80f2be0ea3049ad74231b94609242",
+	"e563cf4758f0d646f1b14b76016aa17fa9e549a4",
+	"fb5067b1aef3ac1ada4b379dbcb7d17255df7d78",
+	"99eae476896f4907224978b88e5ecaa6c5bb67a9",
+	"3e42ffc54a663f9401cc25843d6c0e71a33e4249",
+	"e563cf4758f0d646f1b14b76016aa17fa9e549a4",
+	"fb5067b1aef3ac1ada4b379dbcb7d17255df7d78",
+	"dccada462d3df8ac6de596fb8c896aba9344f941"
+};
+
+void test_diff_iterator__index_0(void)
+{
+	index_iterator_test(
+		"attr", NULL, NULL, 0, ARRAY_SIZE(expected_index_0),
+		expected_index_0, expected_index_oids_0);
+}
+
+static const char *expected_index_range[] = {
+	"root_test1",
+	"root_test2",
+	"root_test3",
+	"root_test4.txt",
+};
+
+static const char *expected_index_oids_range[] = {
+	"45141a79a77842c59a63229403220a4e4be74e3d",
+	"4d713dc48e6b1bd75b0d61ad078ba9ca3a56745d",
+	"108bb4e7fd7b16490dc33ff7d972151e73d7166e",
+	"a0f7217ae99f5ac3e88534f5cea267febc5fa85b",
+};
+
+void test_diff_iterator__index_range(void)
+{
+	index_iterator_test(
+		"attr", "root", "root", 0, ARRAY_SIZE(expected_index_range),
+		expected_index_range, expected_index_oids_range);
+}
+
+void test_diff_iterator__index_range_empty_0(void)
+{
+	index_iterator_test(
+		"attr", "empty", "empty", 0, 0, NULL, NULL);
+}
+
+void test_diff_iterator__index_range_empty_1(void)
+{
+	index_iterator_test(
+		"attr", "z_empty_after", NULL, 0, 0, NULL, NULL);
+}
+
+void test_diff_iterator__index_range_empty_2(void)
+{
+	index_iterator_test(
+		"attr", NULL, ".aaa_empty_before", 0, 0, NULL, NULL);
+}
+
+static const char *expected_index_1[] = {
+	"current_file",
+	"file_deleted",
+	"modified_file",
+	"staged_changes",
+	"staged_changes_file_deleted",
+	"staged_changes_modified_file",
+	"staged_new_file",
+	"staged_new_file_deleted_file",
+	"staged_new_file_modified_file",
+	"subdir.txt",
+	"subdir/current_file",
+	"subdir/deleted_file",
+	"subdir/modified_file",
+};
+
+static const char* expected_index_oids_1[] = {
+	"a0de7e0ac200c489c41c59dfa910154a70264e6e",
+	"5452d32f1dd538eb0405e8a83cc185f79e25e80f",
+	"452e4244b5d083ddf0460acf1ecc74db9dcfa11a",
+	"55d316c9ba708999f1918e9677d01dfcae69c6b9",
+	"a6be623522ce87a1d862128ac42672604f7b468b",
+	"906ee7711f4f4928ddcb2a5f8fbc500deba0d2a8",
+	"529a16e8e762d4acb7b9636ff540a00831f9155a",
+	"90b8c29d8ba39434d1c63e1b093daaa26e5bd972",
+	"ed062903b8f6f3dccb2fa81117ba6590944ef9bd",
+	"e8ee89e15bbe9b20137715232387b3de5b28972e",
+	"53ace0d1cc1145a5f4fe4f78a186a60263190733",
+	"1888c805345ba265b0ee9449b8877b6064592058",
+	"a6191982709b746d5650e93c2acf34ef74e11504"
+};
+
+void test_diff_iterator__index_1(void)
+{
+	index_iterator_test(
+		"status", NULL, NULL, 0, ARRAY_SIZE(expected_index_1),
+		expected_index_1, expected_index_oids_1);
+}
+
+static const char *expected_index_cs[] = {
+	"B", "D", "F", "H", "J", "L/1", "L/B", "L/D", "L/a", "L/c",
+	"a", "c", "e", "g", "i", "k/1", "k/B", "k/D", "k/a", "k/c",
+};
+
+static const char *expected_index_ci[] = {
+	"a", "B", "c", "D", "e", "F", "g", "H", "i", "J",
+	"k/1", "k/a", "k/B", "k/c", "k/D", "L/1", "L/a", "L/B", "L/c", "L/D",
+};
+
+void test_diff_iterator__index_case_folding(void)
+{
+	git_buf path = GIT_BUF_INIT;
+	int fs_is_ci = 0;
+
+	cl_git_pass(git_buf_joinpath(&path, cl_fixture("icase"), ".gitted/CoNfIg"));
+	fs_is_ci = git_path_exists(path.ptr);
+	git_buf_free(&path);
+
+	index_iterator_test(
+		"icase", NULL, NULL, 0, ARRAY_SIZE(expected_index_cs),
+		fs_is_ci ? expected_index_ci : expected_index_cs, NULL);
+
+	cl_git_sandbox_cleanup();
+
+	index_iterator_test(
+		"icase", NULL, NULL, GIT_ITERATOR_IGNORE_CASE,
+		ARRAY_SIZE(expected_index_ci), expected_index_ci, NULL);
+
+	cl_git_sandbox_cleanup();
+
+	index_iterator_test(
+		"icase", NULL, NULL, GIT_ITERATOR_DONT_IGNORE_CASE,
+		ARRAY_SIZE(expected_index_cs), expected_index_cs, NULL);
+}
+
+/* -- WORKDIR ITERATOR TESTS -- */
+
+static void workdir_iterator_test(
+	const char *sandbox,
+	const char *start,
+	const char *end,
+	int expected_count,
+	int expected_ignores,
+	const char **expected_names,
+	const char *an_ignored_name)
+{
+	git_iterator *i;
+	const git_index_entry *entry;
+	int error, count = 0, count_all = 0, count_all_post_reset = 0;
+	git_repository *repo = cl_git_sandbox_init(sandbox);
+
+	cl_git_pass(git_iterator_for_workdir(
+		&i, repo, NULL, NULL, GIT_ITERATOR_DONT_AUTOEXPAND, start, end));
+
+	error = git_iterator_current(&entry, i);
+	cl_assert((error == 0 && entry != NULL) ||
+			  (error == GIT_ITEROVER && entry == NULL));
+
+	while (entry != NULL) {
+		int ignored = git_iterator_current_is_ignored(i);
+
+		if (S_ISDIR(entry->mode)) {
+			cl_git_pass(git_iterator_advance_into(&entry, i));
+			continue;
+		}
+
+		if (expected_names != NULL)
+			cl_assert_equal_s(expected_names[count_all], entry->path);
+
+		if (an_ignored_name && strcmp(an_ignored_name,entry->path)==0)
+			cl_assert(ignored);
+
+		if (!ignored)
+			count++;
+		count_all++;
+
+		error = git_iterator_advance(&entry, i);
+
+		cl_assert((error == 0 && entry != NULL) ||
+				  (error == GIT_ITEROVER && entry == NULL));
+	}
+
+	cl_assert_equal_i(expected_count, count);
+	cl_assert_equal_i(expected_count + expected_ignores, count_all);
+
+	cl_git_pass(git_iterator_reset(i, NULL, NULL));
+
+	error = git_iterator_current(&entry, i);
+	cl_assert((error == 0 && entry != NULL) ||
+			  (error == GIT_ITEROVER && entry == NULL));
+
+	while (entry != NULL) {
+		if (S_ISDIR(entry->mode)) {
+			cl_git_pass(git_iterator_advance_into(&entry, i));
+			continue;
+		}
+
+		if (expected_names != NULL)
+			cl_assert_equal_s(
+				expected_names[count_all_post_reset], entry->path);
+		count_all_post_reset++;
+
+		error = git_iterator_advance(&entry, i);
+		cl_assert(error == 0 || error == GIT_ITEROVER);
+	}
+
+	cl_assert_equal_i(count_all, count_all_post_reset);
+
+	git_iterator_free(i);
+}
+
+void test_diff_iterator__workdir_0(void)
+{
+	workdir_iterator_test("attr", NULL, NULL, 23, 5, NULL, "ign");
+}
+
+static const char *status_paths[] = {
+	"current_file",
+	"ignored_file",
+	"modified_file",
+	"new_file",
+	"staged_changes",
+	"staged_changes_modified_file",
+	"staged_delete_modified_file",
+	"staged_new_file",
+	"staged_new_file_modified_file",
+	"subdir.txt",
+	"subdir/current_file",
+	"subdir/modified_file",
+	"subdir/new_file",
+	"\xe8\xbf\x99",
+	NULL
+};
+
+void test_diff_iterator__workdir_1(void)
+{
+	workdir_iterator_test(
+		"status", NULL, NULL, 13, 1, status_paths, "ignored_file");
+}
+
+static const char *status_paths_range_0[] = {
+	"staged_changes",
+	"staged_changes_modified_file",
+	"staged_delete_modified_file",
+	"staged_new_file",
+	"staged_new_file_modified_file",
+	NULL
+};
+
+void test_diff_iterator__workdir_1_ranged_0(void)
+{
+	workdir_iterator_test(
+		"status", "staged", "staged", 5, 0, status_paths_range_0, NULL);
+}
+
+static const char *status_paths_range_1[] = {
+	"modified_file", NULL
+};
+
+void test_diff_iterator__workdir_1_ranged_1(void)
+{
+	workdir_iterator_test(
+		"status", "modified_file", "modified_file",
+		1, 0, status_paths_range_1, NULL);
+}
+
+static const char *status_paths_range_3[] = {
+	"subdir.txt",
+	"subdir/current_file",
+	"subdir/modified_file",
+	NULL
+};
+
+void test_diff_iterator__workdir_1_ranged_3(void)
+{
+	workdir_iterator_test(
+		"status", "subdir", "subdir/modified_file",
+		3, 0, status_paths_range_3, NULL);
+}
+
+static const char *status_paths_range_4[] = {
+	"subdir/current_file",
+	"subdir/modified_file",
+	"subdir/new_file",
+	"\xe8\xbf\x99",
+	NULL
+};
+
+void test_diff_iterator__workdir_1_ranged_4(void)
+{
+	workdir_iterator_test(
+		"status", "subdir/", NULL, 4, 0, status_paths_range_4, NULL);
+}
+
+static const char *status_paths_range_5[] = {
+	"subdir/modified_file",
+	NULL
+};
+
+void test_diff_iterator__workdir_1_ranged_5(void)
+{
+	workdir_iterator_test(
+		"status", "subdir/modified_file", "subdir/modified_file",
+		1, 0, status_paths_range_5, NULL);
+}
+
+void test_diff_iterator__workdir_1_ranged_empty_0(void)
+{
+	workdir_iterator_test(
+		"status", "\xff_does_not_exist", NULL,
+		0, 0, NULL, NULL);
+}
+
+void test_diff_iterator__workdir_1_ranged_empty_1(void)
+{
+	workdir_iterator_test(
+		"status", "empty", "empty",
+		0, 0, NULL, NULL);
+}
+
+void test_diff_iterator__workdir_1_ranged_empty_2(void)
+{
+	workdir_iterator_test(
+		"status", NULL, "aaaa_empty_before",
+		0, 0, NULL, NULL);
+}
+
+void test_diff_iterator__workdir_builtin_ignores(void)
+{
+	git_repository *repo = cl_git_sandbox_init("attr");
+	git_iterator *i;
+	const git_index_entry *entry;
+	int idx;
+	static struct {
+		const char *path;
+		bool ignored;
+	} expected[] = {
+		{ "dir/", true },
+		{ "file", false },
+		{ "ign", true },
+		{ "macro_bad", false },
+		{ "macro_test", false },
+		{ "root_test1", false },
+		{ "root_test2", false },
+		{ "root_test3", false },
+		{ "root_test4.txt", false },
+		{ "sub/", false },
+		{ "sub/.gitattributes", false },
+		{ "sub/abc", false },
+		{ "sub/dir/", true },
+		{ "sub/file", false },
+		{ "sub/ign/", true },
+		{ "sub/sub/", false },
+		{ "sub/sub/.gitattributes", false },
+		{ "sub/sub/dir", false }, /* file is not actually a dir */
+		{ "sub/sub/file", false },
+		{ NULL, false }
+	};
+
+	cl_git_pass(p_mkdir("attr/sub/sub/.git", 0777));
+	cl_git_mkfile("attr/sub/.git", "whatever");
+
+	cl_git_pass(git_iterator_for_workdir(
+		&i, repo, NULL, NULL, GIT_ITERATOR_DONT_AUTOEXPAND, "dir", "sub/sub/file"));
+	cl_git_pass(git_iterator_current(&entry, i));
+
+	for (idx = 0; entry != NULL; ++idx) {
+		int ignored = git_iterator_current_is_ignored(i);
+
+		cl_assert_equal_s(expected[idx].path, entry->path);
+		cl_assert_(ignored == expected[idx].ignored, expected[idx].path);
+
+		if (!ignored &&
+			(entry->mode == GIT_FILEMODE_TREE ||
+			 entry->mode == GIT_FILEMODE_COMMIT))
+		{
+			/* it is possible to advance "into" a submodule */
+			cl_git_pass(git_iterator_advance_into(&entry, i));
+		} else {
+			int error = git_iterator_advance(&entry, i);
+			cl_assert(!error || error == GIT_ITEROVER);
+		}
+	}
+
+	cl_assert(expected[idx].path == NULL);
+
+	git_iterator_free(i);
+}
+
+static void check_wd_first_through_third_range(
+	git_repository *repo, const char *start, const char *end)
+{
+	git_iterator *i;
+	const git_index_entry *entry;
+	int error, idx;
+	static const char *expected[] = { "FIRST", "second", "THIRD", NULL };
+
+	cl_git_pass(git_iterator_for_workdir(
+		&i, repo, NULL, NULL, GIT_ITERATOR_IGNORE_CASE, start, end));
+	cl_git_pass(git_iterator_current(&entry, i));
+
+	for (idx = 0; entry != NULL; ++idx) {
+		cl_assert_equal_s(expected[idx], entry->path);
+
+		error = git_iterator_advance(&entry, i);
+		cl_assert(!error || error == GIT_ITEROVER);
+	}
+
+	cl_assert(expected[idx] == NULL);
+
+	git_iterator_free(i);
+}
+
+void test_diff_iterator__workdir_handles_icase_range(void)
+{
+	git_repository *repo;
+
+	repo = cl_git_sandbox_init("empty_standard_repo");
+	cl_git_remove_placeholders(git_repository_path(repo), "dummy-marker.txt");
+
+	cl_git_mkfile("empty_standard_repo/before", "whatever\n");
+	cl_git_mkfile("empty_standard_repo/FIRST", "whatever\n");
+	cl_git_mkfile("empty_standard_repo/second", "whatever\n");
+	cl_git_mkfile("empty_standard_repo/THIRD", "whatever\n");
+	cl_git_mkfile("empty_standard_repo/zafter", "whatever\n");
+	cl_git_mkfile("empty_standard_repo/Zlast", "whatever\n");
+
+	check_wd_first_through_third_range(repo, "first", "third");
+	check_wd_first_through_third_range(repo, "FIRST", "THIRD");
+	check_wd_first_through_third_range(repo, "first", "THIRD");
+	check_wd_first_through_third_range(repo, "FIRST", "third");
+	check_wd_first_through_third_range(repo, "FirSt", "tHiRd");
+}
+
+static void check_tree_range(
+	git_repository *repo,
+	const char *start,
+	const char *end,
+	bool ignore_case,
+	int expected_count)
+{
+	git_tree *head;
+	git_iterator *i;
+	int error, count;
+
+	cl_git_pass(git_repository_head_tree(&head, repo));
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, head,
+		ignore_case ? GIT_ITERATOR_IGNORE_CASE : GIT_ITERATOR_DONT_IGNORE_CASE,
+		start, end));
+
+	for (count = 0; !(error = git_iterator_advance(NULL, i)); ++count)
+		/* count em up */;
+
+	cl_assert_equal_i(GIT_ITEROVER, error);
+	cl_assert_equal_i(expected_count, count);
+
+	git_iterator_free(i);
+	git_tree_free(head);
+}
+
+void test_diff_iterator__tree_handles_icase_range(void)
+{
+	git_repository *repo;
+
+	repo = cl_git_sandbox_init("testrepo");
+
+	check_tree_range(repo, "B", "C", false, 0);
+	check_tree_range(repo, "B", "C", true, 1);
+	check_tree_range(repo, "b", "c", false, 1);
+	check_tree_range(repo, "b", "c", true, 1);
+
+	check_tree_range(repo, "a", "z", false, 3);
+	check_tree_range(repo, "a", "z", true, 4);
+	check_tree_range(repo, "A", "Z", false, 1);
+	check_tree_range(repo, "A", "Z", true, 4);
+	check_tree_range(repo, "a", "Z", false, 0);
+	check_tree_range(repo, "a", "Z", true, 4);
+	check_tree_range(repo, "A", "z", false, 4);
+	check_tree_range(repo, "A", "z", true, 4);
+
+	check_tree_range(repo, "new.txt", "new.txt", true, 1);
+	check_tree_range(repo, "new.txt", "new.txt", false, 1);
+	check_tree_range(repo, "README", "README", true, 1);
+	check_tree_range(repo, "README", "README", false, 1);
+}
+
+static void check_index_range(
+	git_repository *repo,
+	const char *start,
+	const char *end,
+	bool ignore_case,
+	int expected_count)
+{
+	git_index *index;
+	git_iterator *i;
+	int error, count, caps;
+	bool is_ignoring_case;
+
+	cl_git_pass(git_repository_index(&index, repo));
+
+	caps = git_index_caps(index);
+	is_ignoring_case = ((caps & GIT_INDEXCAP_IGNORE_CASE) != 0);
+
+	if (ignore_case != is_ignoring_case)
+		cl_git_pass(git_index_set_caps(index, caps ^ GIT_INDEXCAP_IGNORE_CASE));
+
+	cl_git_pass(git_iterator_for_index(&i, index, 0, start, end));
+
+	cl_assert(git_iterator_ignore_case(i) == ignore_case);
+
+	for (count = 0; !(error = git_iterator_advance(NULL, i)); ++count)
+		/* count em up */;
+
+	cl_assert_equal_i(GIT_ITEROVER, error);
+	cl_assert_equal_i(expected_count, count);
+
+	git_iterator_free(i);
+	git_index_free(index);
+}
+
+void test_diff_iterator__index_handles_icase_range(void)
+{
+	git_repository *repo;
+	git_index *index;
+	git_tree *head;
+
+	repo = cl_git_sandbox_init("testrepo");
+
+	/* reset index to match HEAD */
+	cl_git_pass(git_repository_head_tree(&head, repo));
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_read_tree(index, head));
+	cl_git_pass(git_index_write(index));
+	git_tree_free(head);
+	git_index_free(index);
+
+	/* do some ranged iterator checks toggling case sensitivity */
+	check_index_range(repo, "B", "C", false, 0);
+	check_index_range(repo, "B", "C", true, 1);
+	check_index_range(repo, "a", "z", false, 3);
+	check_index_range(repo, "a", "z", true, 4);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/notify.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/notify.c
new file mode 100755
index 0000000..6ef4af5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/notify.c
@@ -0,0 +1,230 @@
+#include "clar_libgit2.h"
+#include "diff_helpers.h"
+
+static git_repository *g_repo = NULL;
+
+void test_diff_notify__initialize(void)
+{
+}
+
+void test_diff_notify__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static int assert_called_notifications(
+	const git_diff *diff_so_far,
+	const git_diff_delta *delta_to_add,
+	const char *matched_pathspec,
+	void *payload)
+{
+	bool found = false;
+	notify_expected *exp = (notify_expected*)payload;
+	notify_expected *e;
+
+	GIT_UNUSED(diff_so_far);
+
+	for (e = exp; e->path != NULL; e++) {
+		if (strcmp(e->path, delta_to_add->new_file.path))
+			continue;
+
+		cl_assert_equal_s(e->matched_pathspec, matched_pathspec);
+
+		found = true;
+		break;
+	}
+
+	cl_assert(found);
+	return 0;
+}
+
+static void test_notify(
+	char **searched_pathspecs,
+	int pathspecs_count,
+	notify_expected *expected_matched_pathspecs,
+	int expected_diffed_files_count)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	diff_expects exp;
+
+	g_repo = cl_git_sandbox_init("status");
+
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+	opts.notify_cb = assert_called_notifications;
+	opts.pathspec.strings = searched_pathspecs;
+	opts.pathspec.count   = pathspecs_count;
+
+	opts.notify_payload = expected_matched_pathspecs;
+	memset(&exp, 0, sizeof(exp));
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
+
+	cl_assert_equal_i(expected_diffed_files_count, exp.files);
+
+	git_diff_free(diff);
+}
+
+void test_diff_notify__notify_single_pathspec(void)
+{
+	char *searched_pathspecs[] = {
+		"*_deleted",
+	};
+	notify_expected expected_matched_pathspecs[] = {
+		{ "file_deleted", "*_deleted" },
+		{ "staged_changes_file_deleted", "*_deleted" },
+		{ NULL, NULL }
+	};
+
+	test_notify(searched_pathspecs, 1, expected_matched_pathspecs, 2);
+}
+
+void test_diff_notify__notify_multiple_pathspec(void)
+{
+	char *searched_pathspecs[] = {
+		"staged_changes_cant_find_me",
+		"subdir/modified_cant_find_me",
+		"subdir/*",
+		"staged*"
+	};
+	notify_expected expected_matched_pathspecs[] = {
+		{ "staged_changes_file_deleted", "staged*" },
+		{ "staged_changes_modified_file", "staged*" },
+		{ "staged_delete_modified_file", "staged*" },
+		{ "staged_new_file_deleted_file", "staged*" },
+		{ "staged_new_file_modified_file", "staged*" },
+		{ "subdir/deleted_file", "subdir/*" },
+		{ "subdir/modified_file", "subdir/*" },
+		{ "subdir/new_file", "subdir/*" },
+		{ NULL, NULL }
+	};
+
+	test_notify(searched_pathspecs, 4, expected_matched_pathspecs, 8);
+}
+
+void test_diff_notify__notify_catchall_with_empty_pathspecs(void)
+{
+	char *searched_pathspecs[] = {
+		"",
+		""
+	};
+	notify_expected expected_matched_pathspecs[] = {
+		{ "file_deleted", NULL },
+		{ "ignored_file", NULL },
+		{ "modified_file", NULL },
+		{ "new_file", NULL },
+		{ "\xe8\xbf\x99", NULL },
+		{ "staged_changes_file_deleted", NULL },
+		{ "staged_changes_modified_file", NULL },
+		{ "staged_delete_modified_file", NULL },
+		{ "staged_new_file_deleted_file", NULL },
+		{ "staged_new_file_modified_file", NULL },
+		{ "subdir/deleted_file", NULL },
+		{ "subdir/modified_file", NULL },
+		{ "subdir/new_file", NULL },
+		{ NULL, NULL }
+	};
+
+	test_notify(searched_pathspecs, 1, expected_matched_pathspecs, 13);
+}
+
+void test_diff_notify__notify_catchall(void)
+{
+	char *searched_pathspecs[] = {
+		"*",
+	};
+	notify_expected expected_matched_pathspecs[] = {
+		{ "file_deleted", "*" },
+		{ "ignored_file", "*" },
+		{ "modified_file", "*" },
+		{ "new_file", "*" },
+		{ "\xe8\xbf\x99", "*" },
+		{ "staged_changes_file_deleted", "*" },
+		{ "staged_changes_modified_file", "*" },
+		{ "staged_delete_modified_file", "*" },
+		{ "staged_new_file_deleted_file", "*" },
+		{ "staged_new_file_modified_file", "*" },
+		{ "subdir/deleted_file", "*" },
+		{ "subdir/modified_file", "*" },
+		{ "subdir/new_file", "*" },
+		{ NULL, NULL }
+	};
+
+	test_notify(searched_pathspecs, 1, expected_matched_pathspecs, 13);
+}
+
+static int abort_diff(
+	const git_diff *diff_so_far,
+	const git_diff_delta *delta_to_add,
+	const char *matched_pathspec,
+	void *payload)
+{
+	GIT_UNUSED(diff_so_far);
+	GIT_UNUSED(delta_to_add);
+	GIT_UNUSED(matched_pathspec);
+	GIT_UNUSED(payload);
+
+	return -42;
+}
+
+void test_diff_notify__notify_cb_can_abort_diff(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	char *pathspec = NULL;
+
+	g_repo = cl_git_sandbox_init("status");
+
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+	opts.notify_cb = abort_diff;
+	opts.pathspec.strings = &pathspec;
+	opts.pathspec.count   = 1;
+
+	pathspec = "file_deleted";
+	cl_git_fail_with(
+		git_diff_index_to_workdir(&diff, g_repo, NULL, &opts), -42);
+
+	pathspec = "staged_changes_modified_file";
+	cl_git_fail_with(
+		git_diff_index_to_workdir(&diff, g_repo, NULL, &opts), -42);
+}
+
+static int filter_all(
+	const git_diff *diff_so_far,
+	const git_diff_delta *delta_to_add,
+	const char *matched_pathspec,
+	void *payload)
+{
+	GIT_UNUSED(diff_so_far);
+	GIT_UNUSED(delta_to_add);
+	GIT_UNUSED(matched_pathspec);
+	GIT_UNUSED(payload);
+
+	return 42;
+}
+
+void test_diff_notify__notify_cb_can_be_used_as_filtering_function(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	char *pathspec = NULL;
+	diff_expects exp;
+
+	g_repo = cl_git_sandbox_init("status");
+
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+	opts.notify_cb = filter_all;
+	opts.pathspec.strings = &pathspec;
+	opts.pathspec.count   = 1;
+
+	pathspec = "*_deleted";
+	memset(&exp, 0, sizeof(exp));
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
+
+	cl_assert_equal_i(0, exp.files);
+
+	git_diff_free(diff);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/patch.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/patch.c
new file mode 100755
index 0000000..1184d19
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/patch.c
@@ -0,0 +1,612 @@
+#include "clar_libgit2.h"
+#include "git2/sys/repository.h"
+
+#include "diff_helpers.h"
+#include "diff.h"
+#include "repository.h"
+#include "buf_text.h"
+
+static git_repository *g_repo = NULL;
+
+void test_diff_patch__initialize(void)
+{
+}
+
+void test_diff_patch__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+#define EXPECTED_HEADER "diff --git a/subdir.txt b/subdir.txt\n" \
+	"deleted file mode 100644\n" \
+	"index e8ee89e..0000000\n" \
+	"--- a/subdir.txt\n" \
+	"+++ /dev/null\n"
+
+#define EXPECTED_HUNK "@@ -1,2 +0,0 @@\n"
+
+static int check_removal_cb(
+	const git_diff_delta *delta,
+	const git_diff_hunk *hunk,
+	const git_diff_line *line,
+	void *payload)
+{
+	switch (line->origin) {
+	case GIT_DIFF_LINE_FILE_HDR:
+		cl_assert_equal_s(EXPECTED_HEADER, line->content);
+		cl_assert(hunk == NULL);
+		goto check_delta;
+
+	case GIT_DIFF_LINE_HUNK_HDR:
+		cl_assert_equal_s(EXPECTED_HUNK, line->content);
+		goto check_hunk;
+
+	case GIT_DIFF_LINE_CONTEXT:
+	case GIT_DIFF_LINE_DELETION:
+		if (payload != NULL)
+			return *(int *)payload;
+		goto check_hunk;
+
+	default:
+		/* unexpected code path */
+		return -1;
+	}
+
+check_hunk:
+	cl_assert(hunk != NULL);
+	cl_assert_equal_i(1, hunk->old_start);
+	cl_assert_equal_i(2, hunk->old_lines);
+	cl_assert_equal_i(0, hunk->new_start);
+	cl_assert_equal_i(0, hunk->new_lines);
+
+check_delta:
+	cl_assert_equal_s("subdir.txt", delta->old_file.path);
+	cl_assert_equal_s("subdir.txt", delta->new_file.path);
+	cl_assert_equal_i(GIT_DELTA_DELETED, delta->status);
+
+	return 0;
+}
+
+void test_diff_patch__can_properly_display_the_removal_of_a_file(void)
+{
+	/*
+	* $ git diff 26a125e..735b6a2
+	* diff --git a/subdir.txt b/subdir.txt
+	* deleted file mode 100644
+	* index e8ee89e..0000000
+	* --- a/subdir.txt
+	* +++ /dev/null
+	* @@ -1,2 +0,0 @@
+	* -Is it a bird?
+	* -Is it a plane?
+	*/
+
+	const char *one_sha = "26a125e";
+	const char *another_sha = "735b6a2";
+	git_tree *one, *another;
+	git_diff *diff;
+
+	g_repo = cl_git_sandbox_init("status");
+
+	one = resolve_commit_oid_to_tree(g_repo, one_sha);
+	another = resolve_commit_oid_to_tree(g_repo, another_sha);
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, one, another, NULL));
+
+	cl_git_pass(git_diff_print(
+		diff, GIT_DIFF_FORMAT_PATCH, check_removal_cb, NULL));
+
+	git_diff_free(diff);
+
+	git_tree_free(another);
+	git_tree_free(one);
+}
+
+void test_diff_patch__can_cancel_diff_print(void)
+{
+	const char *one_sha = "26a125e";
+	const char *another_sha = "735b6a2";
+	git_tree *one, *another;
+	git_diff *diff;
+	int fail_with;
+
+	g_repo = cl_git_sandbox_init("status");
+
+	one = resolve_commit_oid_to_tree(g_repo, one_sha);
+	another = resolve_commit_oid_to_tree(g_repo, another_sha);
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, one, another, NULL));
+
+	fail_with = -2323;
+
+	cl_git_fail_with(git_diff_print(
+		diff, GIT_DIFF_FORMAT_PATCH, check_removal_cb, &fail_with),
+		fail_with);
+
+	fail_with = 45;
+
+	cl_git_fail_with(git_diff_print(
+		diff, GIT_DIFF_FORMAT_PATCH, check_removal_cb, &fail_with),
+		fail_with);
+
+	git_diff_free(diff);
+
+	git_tree_free(another);
+	git_tree_free(one);
+}
+
+void test_diff_patch__to_string(void)
+{
+	const char *one_sha = "26a125e";
+	const char *another_sha = "735b6a2";
+	git_tree *one, *another;
+	git_diff *diff;
+	git_patch *patch;
+	git_buf buf = GIT_BUF_INIT;
+	const char *expected = "diff --git a/subdir.txt b/subdir.txt\ndeleted file mode 100644\nindex e8ee89e..0000000\n--- a/subdir.txt\n+++ /dev/null\n@@ -1,2 +0,0 @@\n-Is it a bird?\n-Is it a plane?\n";
+
+	g_repo = cl_git_sandbox_init("status");
+
+	one = resolve_commit_oid_to_tree(g_repo, one_sha);
+	another = resolve_commit_oid_to_tree(g_repo, another_sha);
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, one, another, NULL));
+
+	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
+
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+
+	cl_git_pass(git_patch_to_buf(&buf, patch));
+
+	cl_assert_equal_s(expected, buf.ptr);
+
+	cl_assert_equal_sz(31, git_patch_size(patch, 0, 0, 0));
+	cl_assert_equal_sz(31, git_patch_size(patch, 1, 0, 0));
+	cl_assert_equal_sz(31 + 16, git_patch_size(patch, 1, 1, 0));
+	cl_assert_equal_sz(strlen(expected), git_patch_size(patch, 1, 1, 1));
+
+	git_buf_free(&buf);
+	git_patch_free(patch);
+	git_diff_free(diff);
+	git_tree_free(another);
+	git_tree_free(one);
+}
+
+void test_diff_patch__config_options(void)
+{
+	const char *one_sha = "26a125e"; /* current HEAD */
+	git_tree *one;
+	git_config *cfg;
+	git_diff *diff;
+	git_patch *patch;
+	git_buf buf = GIT_BUF_INIT;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	char *onefile = "staged_changes_modified_file";
+	const char *expected1 = "diff --git c/staged_changes_modified_file i/staged_changes_modified_file\nindex 70bd944..906ee77 100644\n--- c/staged_changes_modified_file\n+++ i/staged_changes_modified_file\n@@ -1 +1,2 @@\n staged_changes_modified_file\n+staged_changes_modified_file\n";
+	const char *expected2 = "diff --git i/staged_changes_modified_file w/staged_changes_modified_file\nindex 906ee77..011c344 100644\n--- i/staged_changes_modified_file\n+++ w/staged_changes_modified_file\n@@ -1,2 +1,3 @@\n staged_changes_modified_file\n staged_changes_modified_file\n+staged_changes_modified_file\n";
+	const char *expected3 = "diff --git staged_changes_modified_file staged_changes_modified_file\nindex 906ee77..011c344 100644\n--- staged_changes_modified_file\n+++ staged_changes_modified_file\n@@ -1,2 +1,3 @@\n staged_changes_modified_file\n staged_changes_modified_file\n+staged_changes_modified_file\n";
+	const char *expected4 = "diff --git staged_changes_modified_file staged_changes_modified_file\nindex 70bd9443ada0..906ee7711f4f 100644\n--- staged_changes_modified_file\n+++ staged_changes_modified_file\n@@ -1 +1,2 @@\n staged_changes_modified_file\n+staged_changes_modified_file\n";
+
+	g_repo = cl_git_sandbox_init("status");
+	cl_git_pass(git_repository_config(&cfg, g_repo));
+	one = resolve_commit_oid_to_tree(g_repo, one_sha);
+	opts.pathspec.count = 1;
+	opts.pathspec.strings = &onefile;
+
+
+	cl_git_pass(git_config_set_string(cfg, "diff.mnemonicprefix", "true"));
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, one, NULL, &opts));
+
+	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_git_pass(git_patch_to_buf(&buf, patch));
+	cl_assert_equal_s(expected1, buf.ptr);
+
+	git_buf_clear(&buf);
+	git_patch_free(patch);
+	git_diff_free(diff);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_git_pass(git_patch_to_buf(&buf, patch));
+	cl_assert_equal_s(expected2, buf.ptr);
+
+	git_buf_clear(&buf);
+	git_patch_free(patch);
+	git_diff_free(diff);
+
+
+	cl_git_pass(git_config_set_string(cfg, "diff.noprefix", "true"));
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_git_pass(git_patch_to_buf(&buf, patch));
+	cl_assert_equal_s(expected3, buf.ptr);
+
+	git_buf_clear(&buf);
+	git_patch_free(patch);
+	git_diff_free(diff);
+
+
+	cl_git_pass(git_config_set_int32(cfg, "core.abbrev", 12));
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, one, NULL, &opts));
+
+	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_git_pass(git_patch_to_buf(&buf, patch));
+	cl_assert_equal_s(expected4, buf.ptr);
+
+	git_buf_clear(&buf);
+	git_patch_free(patch);
+	git_diff_free(diff);
+
+	git_buf_free(&buf);
+	git_tree_free(one);
+	git_config_free(cfg);
+}
+
+void test_diff_patch__hunks_have_correct_line_numbers(void)
+{
+	git_config *cfg;
+	git_tree *head;
+	git_diff_options opt = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff;
+	git_patch *patch;
+	const git_diff_delta *delta;
+	const git_diff_hunk *hunk;
+	const git_diff_line *line;
+	size_t hunklen;
+	git_buf old_content = GIT_BUF_INIT, actual = GIT_BUF_INIT;
+	const char *new_content = "The Song of Seven Cities\n------------------------\n\nI WAS Lord of Cities very sumptuously builded.\nSeven roaring Cities paid me tribute from afar.\nIvory their outposts were--the guardrooms of them gilded,\nAnd garrisoned with Amazons invincible in war.\n\nThis is some new text;\nNot as good as the old text;\nBut here it is.\n\nSo they warred and trafficked only yesterday, my Cities.\nTo-day there is no mark or mound of where my Cities stood.\nFor the River rose at midnight and it washed away my Cities.\nThey are evened with Atlantis and the towns before the Flood.\n\nRain on rain-gorged channels raised the water-levels round them,\nFreshet backed on freshet swelled and swept their world from sight,\nTill the emboldened floods linked arms and, flashing forward, drowned them--\nDrowned my Seven Cities and their peoples in one night!\n\nLow among the alders lie their derelict foundations,\nThe beams wherein they trusted and the plinths whereon they built--\nMy rulers and their treasure and their unborn populations,\nDead, destroyed, aborted, and defiled with mud and silt!\n\nAnother replacement;\nBreaking up the poem;\nGenerating some hunks.\n\nTo the sound of trumpets shall their seed restore my Cities\nWealthy and well-weaponed, that once more may I behold\nAll the world go softly when it walks before my Cities,\nAnd the horses and the chariots fleeing from them as of old!\n\n  -- Rudyard Kipling\n";
+
+	g_repo = cl_git_sandbox_init("renames");
+
+	cl_git_pass(git_config_new(&cfg));
+	git_repository_set_config(g_repo, cfg);
+	git_config_free(cfg);
+
+	git_repository_reinit_filesystem(g_repo, false);
+
+	cl_git_pass(
+		git_futils_readbuffer(&old_content, "renames/songof7cities.txt"));
+
+	cl_git_rewritefile("renames/songof7cities.txt", new_content);
+
+	cl_git_pass(git_repository_head_tree(&head, g_repo));
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, head, &opt));
+
+	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
+
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_assert((delta = git_patch_get_delta(patch)) != NULL);
+
+	cl_assert_equal_i(GIT_DELTA_MODIFIED, (int)delta->status);
+	cl_assert_equal_i(2, (int)git_patch_num_hunks(patch));
+
+	/* check hunk 0 */
+
+	cl_git_pass(
+		git_patch_get_hunk(&hunk, &hunklen, patch, 0));
+
+	cl_assert_equal_i(18, (int)hunklen);
+
+	cl_assert_equal_i(6, (int)hunk->old_start);
+	cl_assert_equal_i(15, (int)hunk->old_lines);
+	cl_assert_equal_i(6, (int)hunk->new_start);
+	cl_assert_equal_i(9, (int)hunk->new_lines);
+
+	cl_assert_equal_i(18, (int)git_patch_num_lines_in_hunk(patch, 0));
+
+	cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 0));
+	cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)line->origin);
+	cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
+	cl_assert_equal_s("Ivory their outposts were--the guardrooms of them gilded,\n", actual.ptr);
+	cl_assert_equal_i(6, line->old_lineno);
+	cl_assert_equal_i(6, line->new_lineno);
+	cl_assert_equal_i(-1, line->content_offset);
+
+	cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 3));
+	cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin);
+	cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
+	cl_assert_equal_s("All the world went softly when it walked before my Cities--\n", actual.ptr);
+	cl_assert_equal_i(9, line->old_lineno);
+	cl_assert_equal_i(-1, line->new_lineno);
+	cl_assert_equal_i(252, line->content_offset);
+
+	cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 12));
+	cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin);
+	cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
+	cl_assert_equal_s("This is some new text;\n", actual.ptr);
+	cl_assert_equal_i(-1, line->old_lineno);
+	cl_assert_equal_i(9, line->new_lineno);
+	cl_assert_equal_i(252, line->content_offset);
+
+	/* check hunk 1 */
+
+	cl_git_pass(git_patch_get_hunk(&hunk, &hunklen, patch, 1));
+
+	cl_assert_equal_i(18, (int)hunklen);
+
+	cl_assert_equal_i(31, (int)hunk->old_start);
+	cl_assert_equal_i(15, (int)hunk->old_lines);
+	cl_assert_equal_i(25, (int)hunk->new_start);
+	cl_assert_equal_i(9, (int)hunk->new_lines);
+
+	cl_assert_equal_i(18, (int)git_patch_num_lines_in_hunk(patch, 1));
+
+	cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 1, 0));
+	cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)line->origin);
+	cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
+	cl_assert_equal_s("My rulers and their treasure and their unborn populations,\n", actual.ptr);
+	cl_assert_equal_i(31, line->old_lineno);
+	cl_assert_equal_i(25, line->new_lineno);
+	cl_assert_equal_i(-1, line->content_offset);
+
+	cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 1, 3));
+	cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin);
+	cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
+	cl_assert_equal_s("The Daughters of the Palace whom they cherished in my Cities,\n", actual.ptr);
+	cl_assert_equal_i(34, line->old_lineno);
+	cl_assert_equal_i(-1, line->new_lineno);
+	cl_assert_equal_i(1468, line->content_offset);
+
+	cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 1, 12));
+	cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin);
+	cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
+	cl_assert_equal_s("Another replacement;\n", actual.ptr);
+	cl_assert_equal_i(-1, line->old_lineno);
+	cl_assert_equal_i(28, line->new_lineno);
+	cl_assert_equal_i(1066, line->content_offset);
+
+	git_patch_free(patch);
+	git_diff_free(diff);
+
+	/* Let's check line numbers when there is no newline */
+
+	git_buf_rtrim(&old_content);
+	cl_git_rewritefile("renames/songof7cities.txt", old_content.ptr);
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, head, &opt));
+
+	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
+
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_assert((delta = git_patch_get_delta(patch)) != NULL);
+
+	cl_assert_equal_i(GIT_DELTA_MODIFIED, (int)delta->status);
+	cl_assert_equal_i(1, (int)git_patch_num_hunks(patch));
+
+	/* check hunk 0 */
+
+	cl_git_pass(git_patch_get_hunk(&hunk, &hunklen, patch, 0));
+
+	cl_assert_equal_i(6, (int)hunklen);
+
+	cl_assert_equal_i(46, (int)hunk->old_start);
+	cl_assert_equal_i(4, (int)hunk->old_lines);
+	cl_assert_equal_i(46, (int)hunk->new_start);
+	cl_assert_equal_i(4, (int)hunk->new_lines);
+
+	cl_assert_equal_i(6, (int)git_patch_num_lines_in_hunk(patch, 0));
+
+	cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 1));
+	cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)line->origin);
+	cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
+	cl_assert_equal_s("And the horses and the chariots fleeing from them as of old!\n", actual.ptr);
+	cl_assert_equal_i(47, line->old_lineno);
+	cl_assert_equal_i(47, line->new_lineno);
+
+	cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 2));
+	cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)line->origin);
+	cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
+	cl_assert_equal_s("\n", actual.ptr);
+	cl_assert_equal_i(48, line->old_lineno);
+	cl_assert_equal_i(48, line->new_lineno);
+
+	cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 3));
+	cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin);
+	cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
+	cl_assert_equal_s("  -- Rudyard Kipling\n", actual.ptr);
+	cl_assert_equal_i(49, line->old_lineno);
+	cl_assert_equal_i(-1, line->new_lineno);
+
+	cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 4));
+	cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin);
+	cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
+	cl_assert_equal_s("  -- Rudyard Kipling", actual.ptr);
+	cl_assert_equal_i(-1, line->old_lineno);
+	cl_assert_equal_i(49, line->new_lineno);
+
+	cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 5));
+	cl_assert_equal_i(GIT_DIFF_LINE_DEL_EOFNL, (int)line->origin);
+	cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
+	cl_assert_equal_s("\n\\ No newline at end of file\n", actual.ptr);
+	cl_assert_equal_i(-1, line->old_lineno);
+	cl_assert_equal_i(49, line->new_lineno);
+
+	git_patch_free(patch);
+	git_diff_free(diff);
+
+	git_buf_free(&actual);
+	git_buf_free(&old_content);
+	git_tree_free(head);
+}
+
+static void check_single_patch_stats(
+	git_repository *repo, size_t hunks,
+	size_t adds, size_t dels, size_t ctxt, size_t *sizes,
+	const char *expected)
+{
+	git_diff *diff;
+	git_patch *patch;
+	const git_diff_delta *delta;
+	size_t actual_ctxt, actual_adds, actual_dels;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, repo, NULL, NULL));
+
+	cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
+
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_assert((delta = git_patch_get_delta(patch)) != NULL);
+	cl_assert_equal_i(GIT_DELTA_MODIFIED, (int)delta->status);
+
+	cl_assert_equal_i((int)hunks, (int)git_patch_num_hunks(patch));
+
+	cl_git_pass( git_patch_line_stats(
+		&actual_ctxt, &actual_adds, &actual_dels, patch) );
+
+	cl_assert_equal_sz(ctxt, actual_ctxt);
+	cl_assert_equal_sz(adds, actual_adds);
+	cl_assert_equal_sz(dels, actual_dels);
+
+	if (expected != NULL) {
+		git_buf buf = GIT_BUF_INIT;
+		cl_git_pass(git_patch_to_buf(&buf, patch));
+		cl_assert_equal_s(expected, buf.ptr);
+		git_buf_free(&buf);
+
+		cl_assert_equal_sz(
+			strlen(expected), git_patch_size(patch, 1, 1, 1));
+	}
+
+	if (sizes) {
+		if (sizes[0])
+			cl_assert_equal_sz(sizes[0], git_patch_size(patch, 0, 0, 0));
+		if (sizes[1])
+			cl_assert_equal_sz(sizes[1], git_patch_size(patch, 1, 0, 0));
+		if (sizes[2])
+			cl_assert_equal_sz(sizes[2], git_patch_size(patch, 1, 1, 0));
+	}
+
+	/* walk lines in hunk with basic sanity checks */
+	for (; hunks > 0; --hunks) {
+		size_t i, max_i;
+		const git_diff_line *line;
+		int last_new_lineno = -1, last_old_lineno = -1;
+
+		max_i = git_patch_num_lines_in_hunk(patch, hunks - 1);
+
+		for (i = 0; i < max_i; ++i) {
+			int expected = 1;
+
+			cl_git_pass(
+				git_patch_get_line_in_hunk(&line, patch, hunks - 1, i));
+
+			if (line->origin == GIT_DIFF_LINE_ADD_EOFNL ||
+				line->origin == GIT_DIFF_LINE_DEL_EOFNL ||
+				line->origin == GIT_DIFF_LINE_CONTEXT_EOFNL)
+				expected = 0;
+
+			if (line->old_lineno >= 0) {
+				if (last_old_lineno >= 0)
+					cl_assert_equal_i(
+						expected, line->old_lineno - last_old_lineno);
+				last_old_lineno = line->old_lineno;
+			}
+
+			if (line->new_lineno >= 0) {
+				if (last_new_lineno >= 0)
+					cl_assert_equal_i(
+						expected, line->new_lineno - last_new_lineno);
+				last_new_lineno = line->new_lineno;
+			}
+		}
+	}
+
+	git_patch_free(patch);
+	git_diff_free(diff);
+}
+
+void test_diff_patch__line_counts_with_eofnl(void)
+{
+	git_config *cfg;
+	git_buf content = GIT_BUF_INIT;
+	const char *end;
+	git_index *index;
+	const char *expected =
+		/* below is pasted output of 'git diff' with fn context removed */
+		"diff --git a/songof7cities.txt b/songof7cities.txt\n"
+		"index 378a7d9..3d0154e 100644\n"
+		"--- a/songof7cities.txt\n"
+		"+++ b/songof7cities.txt\n"
+		"@@ -42,7 +42,7 @@ With peoples undefeated of the dark, enduring blood.\n"
+		" \n"
+		" To the sound of trumpets shall their seed restore my Cities\n"
+		" Wealthy and well-weaponed, that once more may I behold\n"
+		"-All the world go softly when it walks before my Cities,\n"
+		"+#All the world go softly when it walks before my Cities,\n"
+		" And the horses and the chariots fleeing from them as of old!\n"
+		" \n"
+		"   -- Rudyard Kipling\n"
+		"\\ No newline at end of file\n";
+	size_t expected_sizes[3] = { 115, 119 + 115 + 114, 119 + 115 + 114 + 71 };
+
+	g_repo = cl_git_sandbox_init("renames");
+
+	cl_git_pass(git_config_new(&cfg));
+	git_repository_set_config(g_repo, cfg);
+	git_config_free(cfg);
+
+	git_repository_reinit_filesystem(g_repo, false);
+
+	cl_git_pass(git_futils_readbuffer(&content, "renames/songof7cities.txt"));
+
+	/* remove first line */
+
+	end = git_buf_cstr(&content) + git_buf_find(&content, '\n') + 1;
+	git_buf_consume(&content, end);
+	cl_git_rewritefile("renames/songof7cities.txt", content.ptr);
+
+	check_single_patch_stats(g_repo, 1, 0, 1, 3, NULL, NULL);
+
+	/* remove trailing whitespace */
+
+	git_buf_rtrim(&content);
+	cl_git_rewritefile("renames/songof7cities.txt", content.ptr);
+
+	check_single_patch_stats(g_repo, 2, 1, 2, 6, NULL, NULL);
+
+	/* add trailing whitespace */
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_add_bypath(index, "songof7cities.txt"));
+	cl_git_pass(git_index_write(index));
+	git_index_free(index);
+
+	cl_git_pass(git_buf_putc(&content, '\n'));
+	cl_git_rewritefile("renames/songof7cities.txt", content.ptr);
+
+	check_single_patch_stats(g_repo, 1, 1, 1, 3, NULL, NULL);
+
+	/* no trailing whitespace as context line */
+
+	{
+		/* walk back a couple lines, make space and insert char */
+		char *scan = content.ptr + content.size;
+		int i;
+
+		for (i = 0; i < 5; ++i) {
+			for (--scan; scan > content.ptr && *scan != '\n'; --scan)
+				/* seek to prev \n */;
+		}
+		cl_assert(scan > content.ptr);
+
+		/* overwrite trailing \n with right-shifted content */
+		memmove(scan + 1, scan, content.size - (scan - content.ptr) - 1);
+		/* insert '#' char into space we created */
+		scan[1] = '#';
+	}
+	cl_git_rewritefile("renames/songof7cities.txt", content.ptr);
+
+	check_single_patch_stats(
+		g_repo, 1, 1, 1, 6, expected_sizes, expected);
+
+	git_buf_free(&content);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/pathspec.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/pathspec.c
new file mode 100755
index 0000000..5761d2d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/pathspec.c
@@ -0,0 +1,93 @@
+#include "clar_libgit2.h"
+#include "diff_helpers.h"
+
+static git_repository *g_repo = NULL;
+
+void test_diff_pathspec__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("status");
+}
+
+void test_diff_pathspec__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_diff_pathspec__0(void)
+{
+	const char *a_commit = "26a125ee"; /* the current HEAD */
+	const char *b_commit = "0017bd4a"; /* the start */
+	git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit);
+	git_tree *b = resolve_commit_oid_to_tree(g_repo, b_commit);
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	git_strarray paths = { NULL, 1 };
+	char *path;
+	git_pathspec *ps;
+	git_pathspec_match_list *matches;
+
+	cl_assert(a);
+	cl_assert(b);
+
+	path = "*_file";
+	paths.strings = &path;
+	cl_git_pass(git_pathspec_new(&ps, &paths));
+
+	cl_git_pass(git_pathspec_match_tree(&matches, a, GIT_PATHSPEC_DEFAULT, ps));
+	cl_assert_equal_i(7, (int)git_pathspec_match_list_entrycount(matches));
+	cl_assert_equal_s("current_file", git_pathspec_match_list_entry(matches,0));
+	cl_assert(git_pathspec_match_list_diff_entry(matches,0) == NULL);
+	git_pathspec_match_list_free(matches);
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, NULL, a, &opts));
+
+	cl_git_pass(git_pathspec_match_diff(
+		&matches, diff, GIT_PATHSPEC_DEFAULT, ps));
+	cl_assert_equal_i(7, (int)git_pathspec_match_list_entrycount(matches));
+	cl_assert(git_pathspec_match_list_diff_entry(matches, 0) != NULL);
+	cl_assert(git_pathspec_match_list_entry(matches, 0) == NULL);
+	cl_assert_equal_s("current_file",
+		git_pathspec_match_list_diff_entry(matches,0)->new_file.path);
+	cl_assert_equal_i(GIT_DELTA_ADDED,
+		(int)git_pathspec_match_list_diff_entry(matches,0)->status);
+	git_pathspec_match_list_free(matches);
+
+	git_diff_free(diff);
+	diff = NULL;
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts));
+
+	cl_git_pass(git_pathspec_match_diff(
+		&matches, diff, GIT_PATHSPEC_DEFAULT, ps));
+	cl_assert_equal_i(3, (int)git_pathspec_match_list_entrycount(matches));
+	cl_assert(git_pathspec_match_list_diff_entry(matches, 0) != NULL);
+	cl_assert(git_pathspec_match_list_entry(matches, 0) == NULL);
+	cl_assert_equal_s("subdir/current_file",
+		git_pathspec_match_list_diff_entry(matches,0)->new_file.path);
+	cl_assert_equal_i(GIT_DELTA_DELETED,
+		(int)git_pathspec_match_list_diff_entry(matches,0)->status);
+	git_pathspec_match_list_free(matches);
+
+	git_diff_free(diff);
+	diff = NULL;
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, a, &opts));
+
+	cl_git_pass(git_pathspec_match_diff(
+		&matches, diff, GIT_PATHSPEC_DEFAULT, ps));
+	cl_assert_equal_i(4, (int)git_pathspec_match_list_entrycount(matches));
+	cl_assert(git_pathspec_match_list_diff_entry(matches, 0) != NULL);
+	cl_assert(git_pathspec_match_list_entry(matches, 0) == NULL);
+	cl_assert_equal_s("modified_file",
+		git_pathspec_match_list_diff_entry(matches,0)->new_file.path);
+	cl_assert_equal_i(GIT_DELTA_MODIFIED,
+		(int)git_pathspec_match_list_diff_entry(matches,0)->status);
+	git_pathspec_match_list_free(matches);
+
+	git_diff_free(diff);
+	diff = NULL;
+
+	git_tree_free(a);
+	git_tree_free(b);
+	git_pathspec_free(ps);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/rename.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/rename.c
new file mode 100755
index 0000000..5cfd8e2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/rename.c
@@ -0,0 +1,1704 @@
+#include "clar_libgit2.h"
+#include "diff_helpers.h"
+#include "buf_text.h"
+
+static git_repository *g_repo = NULL;
+
+void test_diff_rename__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("renames");
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", false);
+}
+
+void test_diff_rename__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+/*
+ * Renames repo has:
+ *
+ * commit 31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 -
+ *   serving.txt     (25 lines)
+ *   sevencities.txt (50 lines)
+ * commit 2bc7f351d20b53f1c72c16c4b036e491c478c49a -
+ *   serving.txt     -> sixserving.txt  (rename, no change, 100% match)
+ *   sevencities.txt -> sevencities.txt (no change)
+ *   sevencities.txt -> songofseven.txt (copy, no change, 100% match)
+ * commit 1c068dee5790ef1580cfc4cd670915b48d790084
+ *   songofseven.txt -> songofseven.txt (major rewrite, <20% match - split)
+ *   sixserving.txt  -> sixserving.txt  (indentation change)
+ *   sixserving.txt  -> ikeepsix.txt    (copy, add title, >80% match)
+ *   sevencities.txt                    (no change)
+ * commit 19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13
+ *   songofseven.txt -> untimely.txt    (rename, convert to crlf)
+ *   ikeepsix.txt    -> ikeepsix.txt    (reorder sections in file)
+ *   sixserving.txt  -> sixserving.txt  (whitespace change - not just indent)
+ *   sevencities.txt -> songof7cities.txt (rename, small text changes)
+ */
+
+void test_diff_rename__match_oid(void)
+{
+	const char *old_sha = "31e47d8c1fa36d7f8d537b96158e3f024de0a9f2";
+	const char *new_sha = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
+	git_tree *old_tree, *new_tree;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	diff_expects exp;
+
+	old_tree = resolve_commit_oid_to_tree(g_repo, old_sha);
+	new_tree = resolve_commit_oid_to_tree(g_repo, new_sha);
+
+	/* Must pass GIT_DIFF_INCLUDE_UNMODIFIED if you expect to emulate
+	 * --find-copies-harder during rename transformion...
+	 */
+	diffopts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
+
+	cl_git_pass(git_diff_tree_to_tree(
+		&diff, g_repo, old_tree, new_tree, &diffopts));
+
+	/* git diff --no-renames \
+	 *          31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 \
+	 *          2bc7f351d20b53f1c72c16c4b036e491c478c49a
+	 */
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNMODIFIED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+
+	/* git diff 31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 \
+	 *          2bc7f351d20b53f1c72c16c4b036e491c478c49a
+	 * don't use NULL opts to avoid config `diff.renames` contamination
+	 */
+	opts.flags = GIT_DIFF_FIND_RENAMES;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(3, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNMODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
+
+	git_diff_free(diff);
+
+	cl_git_pass(git_diff_tree_to_tree(
+		&diff, g_repo, old_tree, new_tree, &diffopts));
+
+	/* git diff --find-copies-harder \
+	 *          31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 \
+	 *          2bc7f351d20b53f1c72c16c4b036e491c478c49a
+	 */
+	opts.flags = GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(3, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNMODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_COPIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
+
+	git_diff_free(diff);
+
+	cl_git_pass(git_diff_tree_to_tree(
+		&diff, g_repo, old_tree, new_tree, &diffopts));
+
+	/* git diff --find-copies-harder -M100 -B100 \
+	 *          31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 \
+	 *          2bc7f351d20b53f1c72c16c4b036e491c478c49a
+	 */
+	opts.flags = GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED |
+		GIT_DIFF_FIND_EXACT_MATCH_ONLY;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(3, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNMODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_COPIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
+
+	git_diff_free(diff);
+
+	git_tree_free(old_tree);
+	git_tree_free(new_tree);
+}
+
+void test_diff_rename__checks_options_version(void)
+{
+	const char *old_sha = "31e47d8c1fa36d7f8d537b96158e3f024de0a9f2";
+	const char *new_sha = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
+	git_tree *old_tree, *new_tree;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	const git_error *err;
+
+	old_tree = resolve_commit_oid_to_tree(g_repo, old_sha);
+	new_tree = resolve_commit_oid_to_tree(g_repo, new_sha);
+	diffopts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
+	cl_git_pass(git_diff_tree_to_tree(
+		&diff, g_repo, old_tree, new_tree, &diffopts));
+
+	opts.version = 0;
+	cl_git_fail(git_diff_find_similar(diff, &opts));
+	err = giterr_last();
+	cl_assert_equal_i(GITERR_INVALID, err->klass);
+
+	giterr_clear();
+	opts.version = 1024;
+	cl_git_fail(git_diff_find_similar(diff, &opts));
+	err = giterr_last();
+	cl_assert_equal_i(GITERR_INVALID, err->klass);
+
+	git_diff_free(diff);
+	git_tree_free(old_tree);
+	git_tree_free(new_tree);
+}
+
+void test_diff_rename__not_exact_match(void)
+{
+	const char *sha0 = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
+	const char *sha1 = "1c068dee5790ef1580cfc4cd670915b48d790084";
+	const char *sha2 = "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13";
+	git_tree *old_tree, *new_tree;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	diff_expects exp;
+
+	/* == Changes =====================================================
+	 * songofseven.txt -> songofseven.txt (major rewrite, <20% match - split)
+	 * sixserving.txt  -> sixserving.txt  (indentation change)
+	 * sixserving.txt  -> ikeepsix.txt    (copy, add title, >80% match)
+	 * sevencities.txt                    (no change)
+	 */
+
+	old_tree = resolve_commit_oid_to_tree(g_repo, sha0);
+	new_tree = resolve_commit_oid_to_tree(g_repo, sha1);
+
+	/* Must pass GIT_DIFF_INCLUDE_UNMODIFIED if you expect to emulate
+	 * --find-copies-harder during rename transformion...
+	 */
+	diffopts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
+
+	cl_git_pass(git_diff_tree_to_tree(
+		&diff, g_repo, old_tree, new_tree, &diffopts));
+
+	/* git diff --no-renames \
+	 *          2bc7f351d20b53f1c72c16c4b036e491c478c49a \
+	 *          1c068dee5790ef1580cfc4cd670915b48d790084
+	 */
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNMODIFIED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_ADDED]);
+
+	/* git diff -M 2bc7f351d20b53f1c72c16c4b036e491c478c49a \
+	 *          1c068dee5790ef1580cfc4cd670915b48d790084
+	 *
+	 * must not pass NULL for opts because it will pick up environment
+	 * values for "diff.renames" and test won't be consistent.
+	 */
+	opts.flags = GIT_DIFF_FIND_RENAMES;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNMODIFIED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_ADDED]);
+
+	git_diff_free(diff);
+
+	/* git diff -M -C \
+	 *          2bc7f351d20b53f1c72c16c4b036e491c478c49a \
+	 *          1c068dee5790ef1580cfc4cd670915b48d790084
+	 */
+	cl_git_pass(git_diff_tree_to_tree(
+		&diff, g_repo, old_tree, new_tree, &diffopts));
+
+	opts.flags = GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_COPIES;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNMODIFIED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_COPIED]);
+
+	git_diff_free(diff);
+
+	/* git diff -M -C --find-copies-harder --break-rewrites \
+	 *          2bc7f351d20b53f1c72c16c4b036e491c478c49a \
+	 *          1c068dee5790ef1580cfc4cd670915b48d790084
+	 */
+	cl_git_pass(git_diff_tree_to_tree(
+		&diff, g_repo, old_tree, new_tree, &diffopts));
+
+	opts.flags = GIT_DIFF_FIND_ALL;
+	opts.break_rewrite_threshold = 70;
+
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(5, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNMODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_COPIED]);
+
+	git_diff_free(diff);
+
+	/* == Changes =====================================================
+	 * songofseven.txt -> untimely.txt    (rename, convert to crlf)
+	 * ikeepsix.txt    -> ikeepsix.txt    (reorder sections in file)
+	 * sixserving.txt  -> sixserving.txt  (whitespace - not just indent)
+	 * sevencities.txt -> songof7cities.txt (rename, small text changes)
+	 */
+
+	git_tree_free(old_tree);
+	old_tree = new_tree;
+	new_tree = resolve_commit_oid_to_tree(g_repo, sha2);
+
+	cl_git_pass(git_diff_tree_to_tree(
+		&diff, g_repo, old_tree, new_tree, &diffopts));
+
+	/* git diff --no-renames \
+	 *          1c068dee5790ef1580cfc4cd670915b48d790084 \
+	 *          19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13
+	 */
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(6, exp.files);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_DELETED]);
+	git_diff_free(diff);
+
+	/* git diff -M -C \
+	 *          1c068dee5790ef1580cfc4cd670915b48d790084 \
+	 *          19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13
+	 */
+	cl_git_pass(git_diff_tree_to_tree(
+		&diff, g_repo, old_tree, new_tree, &diffopts));
+
+	opts.flags = GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_COPIES;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_RENAMED]);
+
+	git_diff_free(diff);
+
+	/* git diff -M -C --find-copies-harder --break-rewrites \
+	 *          1c068dee5790ef1580cfc4cd670915b48d790084 \
+	 *          19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13
+	 * with libgit2 default similarity comparison...
+	 */
+	cl_git_pass(git_diff_tree_to_tree(
+		&diff, g_repo, old_tree, new_tree, &diffopts));
+
+	opts.flags = GIT_DIFF_FIND_ALL;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	/* the default match algorithm is going to find the internal
+	 * whitespace differences in the lines of sixserving.txt to be
+	 * significant enough that this will decide to split it into an ADD
+	 * and a DELETE
+	 */
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(5, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_RENAMED]);
+
+	git_diff_free(diff);
+
+	/* git diff -M -C --find-copies-harder --break-rewrites \
+	 *          1c068dee5790ef1580cfc4cd670915b48d790084 \
+	 *          19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13
+	 * with ignore_space whitespace comparision
+	 */
+	cl_git_pass(git_diff_tree_to_tree(
+		&diff, g_repo, old_tree, new_tree, &diffopts));
+
+	opts.flags = GIT_DIFF_FIND_ALL | GIT_DIFF_FIND_IGNORE_WHITESPACE;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	/* Ignoring whitespace, this should no longer split sixserver.txt */
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_RENAMED]);
+
+	git_diff_free(diff);
+
+	git_tree_free(old_tree);
+	git_tree_free(new_tree);
+}
+
+void test_diff_rename__test_small_files(void)
+{
+	git_index *index;
+	git_reference *head_reference;
+	git_commit *head_commit;
+	git_tree *head_tree;
+	git_tree *commit_tree;
+	git_signature *signature;
+	git_diff *diff;
+	git_oid oid;
+	const git_diff_delta *delta;
+	git_diff_options diff_options = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options find_options = GIT_DIFF_FIND_OPTIONS_INIT;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_mkfile("renames/small.txt", "Hello World!\n");
+	cl_git_pass(git_index_add_bypath(index, "small.txt"));
+
+	cl_git_pass(git_repository_head(&head_reference, g_repo));
+	cl_git_pass(git_reference_peel((git_object**)&head_commit, head_reference, GIT_OBJ_COMMIT));
+	cl_git_pass(git_commit_tree(&head_tree, head_commit));
+	cl_git_pass(git_index_write_tree(&oid, index));
+	cl_git_pass(git_tree_lookup(&commit_tree, g_repo, &oid));
+	cl_git_pass(git_signature_new(&signature, "Rename", "rename at example.com", 1404157834, 0));
+	cl_git_pass(git_commit_create(&oid, g_repo, "HEAD", signature, signature, NULL, "Test commit", commit_tree, 1, (const git_commit**)&head_commit));
+
+	cl_git_mkfile("renames/copy.txt", "Hello World!\n");
+	cl_git_rmfile("renames/small.txt");
+
+	diff_options.flags = GIT_DIFF_INCLUDE_UNTRACKED;
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, commit_tree, &diff_options));
+	find_options.flags = GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_FOR_UNTRACKED;
+	cl_git_pass(git_diff_find_similar(diff, &find_options));
+
+	cl_assert_equal_i(git_diff_num_deltas(diff), 1);
+	delta = git_diff_get_delta(diff, 0);
+	cl_assert_equal_i(delta->status, GIT_DELTA_RENAMED);
+	cl_assert_equal_s(delta->old_file.path, "small.txt");
+	cl_assert_equal_s(delta->new_file.path, "copy.txt");
+
+	git_diff_free(diff);
+	git_signature_free(signature);
+	git_tree_free(commit_tree);
+	git_tree_free(head_tree);
+	git_commit_free(head_commit);
+	git_reference_free(head_reference);
+	git_index_free(index);
+}
+
+void test_diff_rename__working_directory_changes(void)
+{
+	const char *sha0 = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
+	const char *blobsha = "66311f5cfbe7836c27510a3ba2f43e282e2c8bba";
+	git_oid id;
+	git_tree *tree;
+	git_blob *blob;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	diff_expects exp;
+	git_buf old_content = GIT_BUF_INIT, content = GIT_BUF_INIT;;
+
+	tree = resolve_commit_oid_to_tree(g_repo, sha0);
+	diffopts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED | GIT_DIFF_INCLUDE_UNTRACKED;
+
+	/*
+	$ git cat-file -p 2bc7f351d20b53f1c72c16c4b036e491c478c49a^{tree}
+
+	100644 blob 66311f5cfbe7836c27510a3ba2f43e282e2c8bba	sevencities.txt
+	100644 blob ad0a8e55a104ac54a8a29ed4b84b49e76837a113	sixserving.txt
+	100644 blob 66311f5cfbe7836c27510a3ba2f43e282e2c8bba	songofseven.txt
+
+	$ for f in *.txt; do
+		echo `git hash-object -t blob $f` $f
+	done
+
+	eaf4a3e3bfe68585e90cada20736ace491cd100b ikeepsix.txt
+	f90d4fc20ecddf21eebe6a37e9225d244339d2b5 sixserving.txt
+	4210ffd5c390b21dd5483375e75288dea9ede512 songof7cities.txt
+	9a69d960ae94b060f56c2a8702545e2bb1abb935 untimely.txt
+	*/
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, tree, &diffopts));
+
+	/* git diff --no-renames 2bc7f351d20b53f1c72c16c4b036e491c478c49a */
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(6, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	/* git diff -M 2bc7f351d20b53f1c72c16c4b036e491c478c49a */
+	opts.flags = GIT_DIFF_FIND_ALL;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(5, exp.files);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_RENAMED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	git_diff_free(diff);
+
+	/* rewrite files in the working directory with / without CRLF changes */
+
+	cl_git_pass(
+		git_futils_readbuffer(&old_content, "renames/songof7cities.txt"));
+	cl_git_pass(
+		git_buf_text_lf_to_crlf(&content, &old_content));
+	cl_git_pass(
+		git_futils_writebuffer(&content, "renames/songof7cities.txt", 0, 0));
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, tree, &diffopts));
+
+	/* git diff -M 2bc7f351d20b53f1c72c16c4b036e491c478c49a */
+	opts.flags = GIT_DIFF_FIND_ALL;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(5, exp.files);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_RENAMED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	git_diff_free(diff);
+
+	/* try a different whitespace option */
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, tree, &diffopts));
+
+	opts.flags = GIT_DIFF_FIND_ALL | GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE;
+	opts.rename_threshold = 70;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(6, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	git_diff_free(diff);
+
+	/* try a different matching option */
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, tree, &diffopts));
+
+	opts.flags = GIT_DIFF_FIND_ALL | GIT_DIFF_FIND_EXACT_MATCH_ONLY;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(6, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_UNTRACKED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_DELETED]);
+
+	git_diff_free(diff);
+
+	/* again with exact match blob */
+
+	cl_git_pass(git_oid_fromstr(&id, blobsha));
+	cl_git_pass(git_blob_lookup(&blob, g_repo, &id));
+	cl_git_pass(git_buf_set(
+		&content, git_blob_rawcontent(blob), (size_t)git_blob_rawsize(blob)));
+	cl_git_rewritefile("renames/songof7cities.txt", content.ptr);
+	git_blob_free(blob);
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, tree, &diffopts));
+
+	opts.flags = GIT_DIFF_FIND_ALL | GIT_DIFF_FIND_EXACT_MATCH_ONLY;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	/*
+	fprintf(stderr, "\n\n");
+    diff_print_raw(stderr, diff);
+	*/
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(5, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	git_diff_free(diff);
+
+	git_tree_free(tree);
+	git_buf_free(&content);
+	git_buf_free(&old_content);
+}
+
+void test_diff_rename__patch(void)
+{
+	const char *sha0 = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
+	const char *sha1 = "1c068dee5790ef1580cfc4cd670915b48d790084";
+	git_tree *old_tree, *new_tree;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	git_patch *patch;
+	const git_diff_delta *delta;
+	git_buf buf = GIT_BUF_INIT;
+	const char *expected = "diff --git a/sixserving.txt b/ikeepsix.txt\nindex ad0a8e5..36020db 100644\n--- a/sixserving.txt\n+++ b/ikeepsix.txt\n@@ -1,3 +1,6 @@\n+I Keep Six Honest Serving-Men\n+=============================\n+\n I KEEP six honest serving-men\n  (They taught me all I knew);\n Their names are What and Why and When\n@@ -21,4 +24,4 @@ She sends'em abroad on her own affairs,\n One million Hows, two million Wheres,\n And seven million Whys!\n \n-                -- Rudyard Kipling\n+  -- Rudyard Kipling\n";
+
+	old_tree = resolve_commit_oid_to_tree(g_repo, sha0);
+	new_tree = resolve_commit_oid_to_tree(g_repo, sha1);
+
+	diffopts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
+	cl_git_pass(git_diff_tree_to_tree(
+		&diff, g_repo, old_tree, new_tree, &diffopts));
+
+	opts.flags = GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_COPIES;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	/* == Changes =====================================================
+	 * sixserving.txt  -> ikeepsix.txt    (copy, add title, >80% match)
+	 * sevencities.txt                    (no change)
+	 * sixserving.txt  -> sixserving.txt  (indentation change)
+	 * songofseven.txt -> songofseven.txt (major rewrite, <20% match - split)
+	 */
+
+	cl_assert_equal_i(4, (int)git_diff_num_deltas(diff));
+
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_assert((delta = git_patch_get_delta(patch)) != NULL);
+	cl_assert_equal_i(GIT_DELTA_COPIED, (int)delta->status);
+
+	cl_git_pass(git_patch_to_buf(&buf, patch));
+	cl_assert_equal_s(expected, buf.ptr);
+	git_buf_free(&buf);
+
+	git_patch_free(patch);
+
+	cl_assert((delta = git_diff_get_delta(diff, 1)) != NULL);
+	cl_assert_equal_i(GIT_DELTA_UNMODIFIED, (int)delta->status);
+
+	cl_assert((delta = git_diff_get_delta(diff, 2)) != NULL);
+	cl_assert_equal_i(GIT_DELTA_MODIFIED, (int)delta->status);
+
+	cl_assert((delta = git_diff_get_delta(diff, 3)) != NULL);
+	cl_assert_equal_i(GIT_DELTA_MODIFIED, (int)delta->status);
+
+	git_diff_free(diff);
+	git_tree_free(old_tree);
+	git_tree_free(new_tree);
+}
+
+void test_diff_rename__file_exchange(void)
+{
+	git_buf c1 = GIT_BUF_INIT, c2 = GIT_BUF_INIT;
+	git_index *index;
+	git_tree *tree;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	diff_expects exp;
+
+	cl_git_pass(git_futils_readbuffer(&c1, "renames/untimely.txt"));
+	cl_git_pass(git_futils_readbuffer(&c2, "renames/songof7cities.txt"));
+	cl_git_pass(git_futils_writebuffer(&c1, "renames/songof7cities.txt", 0, 0));
+	cl_git_pass(git_futils_writebuffer(&c2, "renames/untimely.txt", 0, 0));
+
+	cl_git_pass(
+		git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_read_tree(index, tree));
+	cl_git_pass(git_index_add_bypath(index, "songof7cities.txt"));
+	cl_git_pass(git_index_add_bypath(index, "untimely.txt"));
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(2, exp.files);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+
+	opts.flags = GIT_DIFF_FIND_ALL;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(2, exp.files);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_RENAMED]);
+
+	git_diff_free(diff);
+	git_tree_free(tree);
+	git_index_free(index);
+
+	git_buf_free(&c1);
+	git_buf_free(&c2);
+}
+
+void test_diff_rename__file_exchange_three(void)
+{
+	git_buf c1 = GIT_BUF_INIT, c2 = GIT_BUF_INIT, c3 = GIT_BUF_INIT;
+	git_index *index;
+	git_tree *tree;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	diff_expects exp;
+
+	cl_git_pass(git_futils_readbuffer(&c1, "renames/untimely.txt"));
+	cl_git_pass(git_futils_readbuffer(&c2, "renames/songof7cities.txt"));
+	cl_git_pass(git_futils_readbuffer(&c3, "renames/ikeepsix.txt"));
+
+	cl_git_pass(git_futils_writebuffer(&c1, "renames/ikeepsix.txt", 0, 0));
+	cl_git_pass(git_futils_writebuffer(&c2, "renames/untimely.txt", 0, 0));
+	cl_git_pass(git_futils_writebuffer(&c3, "renames/songof7cities.txt", 0, 0));
+
+	cl_git_pass(
+		git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_read_tree(index, tree));
+	cl_git_pass(git_index_add_bypath(index, "songof7cities.txt"));
+	cl_git_pass(git_index_add_bypath(index, "untimely.txt"));
+	cl_git_pass(git_index_add_bypath(index, "ikeepsix.txt"));
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(3, exp.files);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]);
+
+	opts.flags = GIT_DIFF_FIND_ALL;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(3, exp.files);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_RENAMED]);
+
+	git_diff_free(diff);
+	git_tree_free(tree);
+	git_index_free(index);
+
+	git_buf_free(&c1);
+	git_buf_free(&c2);
+	git_buf_free(&c3);
+}
+
+void test_diff_rename__file_partial_exchange(void)
+{
+	git_buf c1 = GIT_BUF_INIT, c2 = GIT_BUF_INIT;
+	git_index *index;
+	git_tree *tree;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	diff_expects exp;
+	int i;
+
+	cl_git_pass(git_futils_readbuffer(&c1, "renames/untimely.txt"));
+	cl_git_pass(git_futils_writebuffer(&c1, "renames/songof7cities.txt", 0, 0));
+	for (i = 0; i < 100; ++i)
+		cl_git_pass(git_buf_puts(&c2, "this is not the content you are looking for\n"));
+	cl_git_pass(git_futils_writebuffer(&c2, "renames/untimely.txt", 0, 0));
+
+	cl_git_pass(
+		git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_read_tree(index, tree));
+	cl_git_pass(git_index_add_bypath(index, "songof7cities.txt"));
+	cl_git_pass(git_index_add_bypath(index, "untimely.txt"));
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(2, exp.files);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+
+	opts.flags = GIT_DIFF_FIND_ALL;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(3, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+
+	git_diff_free(diff);
+	git_tree_free(tree);
+	git_index_free(index);
+
+	git_buf_free(&c1);
+	git_buf_free(&c2);
+}
+
+void test_diff_rename__rename_and_copy_from_same_source(void)
+{
+	git_buf c1 = GIT_BUF_INIT, c2 = GIT_BUF_INIT;
+	git_index *index;
+	git_tree *tree;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	diff_expects exp;
+
+	/* put the first 2/3 of file into one new place
+	 * and the second 2/3 of file into another new place
+	 */
+	cl_git_pass(git_futils_readbuffer(&c1, "renames/songof7cities.txt"));
+	cl_git_pass(git_buf_set(&c2, c1.ptr, c1.size));
+	git_buf_truncate(&c1, c1.size * 2 / 3);
+	git_buf_consume(&c2, ((char *)c2.ptr) + (c2.size / 3));
+	cl_git_pass(git_futils_writebuffer(&c1, "renames/song_a.txt", 0, 0));
+	cl_git_pass(git_futils_writebuffer(&c2, "renames/song_b.txt", 0, 0));
+
+	cl_git_pass(
+		git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_read_tree(index, tree));
+	cl_git_pass(git_index_add_bypath(index, "song_a.txt"));
+	cl_git_pass(git_index_add_bypath(index, "song_b.txt"));
+
+	diffopts.flags = GIT_DIFF_INCLUDE_UNMODIFIED;
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(6, exp.files);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(4, exp.file_status[GIT_DELTA_UNMODIFIED]);
+
+	opts.flags = GIT_DIFF_FIND_ALL;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(6, exp.files);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_COPIED]);
+	cl_assert_equal_i(4, exp.file_status[GIT_DELTA_UNMODIFIED]);
+
+	git_diff_free(diff);
+	git_tree_free(tree);
+	git_index_free(index);
+
+	git_buf_free(&c1);
+	git_buf_free(&c2);
+}
+
+void test_diff_rename__from_deleted_to_split(void)
+{
+	git_buf c1 = GIT_BUF_INIT;
+	git_index *index;
+	git_tree *tree;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	diff_expects exp;
+
+	/* old file is missing, new file is actually old file renamed */
+
+	cl_git_pass(git_futils_readbuffer(&c1, "renames/songof7cities.txt"));
+	cl_git_pass(git_futils_writebuffer(&c1, "renames/untimely.txt", 0, 0));
+
+	cl_git_pass(
+		git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_read_tree(index, tree));
+	cl_git_pass(git_index_remove_bypath(index, "songof7cities.txt"));
+	cl_git_pass(git_index_add_bypath(index, "untimely.txt"));
+
+	diffopts.flags = GIT_DIFF_INCLUDE_UNMODIFIED;
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_UNMODIFIED]);
+
+	opts.flags = GIT_DIFF_FIND_ALL;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_UNMODIFIED]);
+
+	git_diff_free(diff);
+	git_tree_free(tree);
+	git_index_free(index);
+
+	git_buf_free(&c1);
+}
+
+struct rename_expected
+{
+	size_t len;
+
+	unsigned int *status;
+	const char **sources;
+	const char **targets;
+
+	size_t idx;
+};
+
+int test_names_expected(const git_diff_delta *delta, float progress, void *p)
+{
+	struct rename_expected *expected = p;
+
+	GIT_UNUSED(progress);
+
+	cl_assert(expected->idx < expected->len);
+
+	cl_assert_equal_i(delta->status, expected->status[expected->idx]);
+
+	cl_assert(git__strcmp(expected->sources[expected->idx],
+		delta->old_file.path) == 0);
+	cl_assert(git__strcmp(expected->targets[expected->idx],
+		delta->new_file.path) == 0);
+
+	expected->idx++;
+
+	return 0;
+}
+
+void test_diff_rename__rejected_match_can_match_others(void)
+{
+	git_reference *head, *selfsimilar;
+	git_index *index;
+	git_tree *tree;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT;
+	git_buf one = GIT_BUF_INIT, two = GIT_BUF_INIT;
+	unsigned int status[] = { GIT_DELTA_RENAMED, GIT_DELTA_RENAMED };
+	const char *sources[] = { "Class1.cs", "Class2.cs" };
+	const char *targets[] = { "ClassA.cs", "ClassB.cs" };
+	struct rename_expected expect = { 2, status, sources, targets };
+	char *ptr;
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+	findopts.flags = GIT_DIFF_FIND_RENAMES;
+
+	cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
+	cl_git_pass(git_reference_symbolic_set_target(
+		&selfsimilar, head, "refs/heads/renames_similar", NULL));
+	cl_git_pass(git_checkout_head(g_repo, &opts));
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_pass(git_futils_readbuffer(&one, "renames/Class1.cs"));
+	cl_git_pass(git_futils_readbuffer(&two, "renames/Class2.cs"));
+
+	cl_git_pass(p_unlink("renames/Class1.cs"));
+	cl_git_pass(p_unlink("renames/Class2.cs"));
+
+	cl_git_pass(git_index_remove_bypath(index, "Class1.cs"));
+	cl_git_pass(git_index_remove_bypath(index, "Class2.cs"));
+
+	cl_assert(ptr = strstr(one.ptr, "Class1"));
+	ptr[5] = 'A';
+
+	cl_assert(ptr = strstr(two.ptr, "Class2"));
+	ptr[5] = 'B';
+
+	cl_git_pass(
+		git_futils_writebuffer(&one, "renames/ClassA.cs", O_RDWR|O_CREAT, 0777));
+	cl_git_pass(
+		git_futils_writebuffer(&two, "renames/ClassB.cs", O_RDWR|O_CREAT, 0777));
+
+	cl_git_pass(git_index_add_bypath(index, "ClassA.cs"));
+	cl_git_pass(git_index_add_bypath(index, "ClassB.cs"));
+
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(
+		git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(
+		git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));
+
+	cl_git_pass(git_diff_find_similar(diff, &findopts));
+
+	cl_git_pass(git_diff_foreach(
+		diff, test_names_expected, NULL, NULL, NULL, &expect));
+
+	git_diff_free(diff);
+	git_tree_free(tree);
+	git_index_free(index);
+	git_reference_free(head);
+	git_reference_free(selfsimilar);
+	git_buf_free(&one);
+	git_buf_free(&two);
+}
+
+static void write_similarity_file_two(const char *filename, size_t b_lines)
+{
+	git_buf contents = GIT_BUF_INIT;
+	size_t i;
+
+	for (i = 0; i < b_lines; i++)
+		git_buf_printf(&contents, "%02d - bbbbb\r\n", (int)(i+1));
+
+	for (i = b_lines; i < 50; i++)
+		git_buf_printf(&contents, "%02d - aaaaa%s", (int)(i+1), (i == 49 ? "" : "\r\n"));
+
+	cl_git_pass(
+		git_futils_writebuffer(&contents, filename, O_RDWR|O_CREAT, 0777));
+
+	git_buf_free(&contents);
+}
+
+void test_diff_rename__rejected_match_can_match_others_two(void)
+{
+	git_reference *head, *selfsimilar;
+	git_index *index;
+	git_tree *tree;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT;
+	unsigned int status[] = { GIT_DELTA_RENAMED, GIT_DELTA_RENAMED };
+	const char *sources[] = { "a.txt", "b.txt" };
+	const char *targets[] = { "c.txt", "d.txt" };
+	struct rename_expected expect = { 2, status, sources, targets };
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+	findopts.flags = GIT_DIFF_FIND_RENAMES;
+
+	cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
+	cl_git_pass(git_reference_symbolic_set_target(
+		&selfsimilar, head, "refs/heads/renames_similar_two", NULL));
+	cl_git_pass(git_checkout_head(g_repo, &opts));
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_pass(p_unlink("renames/a.txt"));
+	cl_git_pass(p_unlink("renames/b.txt"));
+
+	cl_git_pass(git_index_remove_bypath(index, "a.txt"));
+	cl_git_pass(git_index_remove_bypath(index, "b.txt"));
+
+	write_similarity_file_two("renames/c.txt", 7);
+	write_similarity_file_two("renames/d.txt", 8);
+
+	cl_git_pass(git_index_add_bypath(index, "c.txt"));
+	cl_git_pass(git_index_add_bypath(index, "d.txt"));
+
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(
+		git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(
+		git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));
+
+	cl_git_pass(git_diff_find_similar(diff, &findopts));
+
+	cl_git_pass(git_diff_foreach(
+		diff, test_names_expected, NULL, NULL, NULL, &expect));
+	cl_assert(expect.idx > 0);
+
+	git_diff_free(diff);
+	git_tree_free(tree);
+	git_index_free(index);
+	git_reference_free(head);
+	git_reference_free(selfsimilar);
+}
+
+void test_diff_rename__rejected_match_can_match_others_three(void)
+{
+	git_reference *head, *selfsimilar;
+	git_index *index;
+	git_tree *tree;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT;
+
+	/* Both cannot be renames from a.txt */
+	unsigned int status[] = { GIT_DELTA_ADDED, GIT_DELTA_RENAMED };
+	const char *sources[] = { "0001.txt", "a.txt" };
+	const char *targets[] = { "0001.txt", "0002.txt" };
+	struct rename_expected expect = { 2, status, sources, targets };
+
+	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+	findopts.flags = GIT_DIFF_FIND_RENAMES;
+
+	cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
+	cl_git_pass(git_reference_symbolic_set_target(
+		&selfsimilar, head, "refs/heads/renames_similar_two", NULL));
+	cl_git_pass(git_checkout_head(g_repo, &opts));
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_pass(p_unlink("renames/a.txt"));
+
+	cl_git_pass(git_index_remove_bypath(index, "a.txt"));
+
+	write_similarity_file_two("renames/0001.txt", 7);
+	write_similarity_file_two("renames/0002.txt", 0);
+
+	cl_git_pass(git_index_add_bypath(index, "0001.txt"));
+	cl_git_pass(git_index_add_bypath(index, "0002.txt"));
+
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(
+		git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(
+		git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));
+
+	cl_git_pass(git_diff_find_similar(diff, &findopts));
+
+	cl_git_pass(git_diff_foreach(
+		diff, test_names_expected, NULL, NULL, NULL, &expect));
+
+	cl_assert(expect.idx == expect.len);
+
+	git_diff_free(diff);
+	git_tree_free(tree);
+	git_index_free(index);
+	git_reference_free(head);
+	git_reference_free(selfsimilar);
+}
+
+void test_diff_rename__can_rename_from_rewrite(void)
+{
+	git_index *index;
+	git_tree *tree;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT;
+
+	unsigned int status[] = { GIT_DELTA_RENAMED, GIT_DELTA_RENAMED };
+	const char *sources[] = { "ikeepsix.txt", "songof7cities.txt" };
+	const char *targets[] = { "songof7cities.txt", "this-is-a-rename.txt" };
+	struct rename_expected expect = { 2, status, sources, targets };
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_pass(p_rename("renames/songof7cities.txt", "renames/this-is-a-rename.txt"));
+	cl_git_pass(p_rename("renames/ikeepsix.txt", "renames/songof7cities.txt"));
+
+	cl_git_pass(git_index_remove_bypath(index, "ikeepsix.txt"));
+
+	cl_git_pass(git_index_add_bypath(index, "songof7cities.txt"));
+	cl_git_pass(git_index_add_bypath(index, "this-is-a-rename.txt"));
+
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(
+		git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(
+		git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));
+
+	findopts.flags |= GIT_DIFF_FIND_AND_BREAK_REWRITES |
+		GIT_DIFF_FIND_REWRITES |
+		GIT_DIFF_FIND_RENAMES_FROM_REWRITES;
+
+	cl_git_pass(git_diff_find_similar(diff, &findopts));
+
+	cl_git_pass(git_diff_foreach(
+		diff, test_names_expected, NULL, NULL, NULL, &expect));
+
+	cl_assert(expect.idx == expect.len);
+
+	git_diff_free(diff);
+	git_tree_free(tree);
+	git_index_free(index);
+}
+
+void test_diff_rename__case_changes_are_split(void)
+{
+	git_index *index;
+	git_tree *tree;
+	git_diff *diff = NULL;
+	diff_expects exp;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_pass(
+		git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(p_rename("renames/ikeepsix.txt", "renames/IKEEPSIX.txt"));
+
+	cl_git_pass(git_index_remove_bypath(index, "ikeepsix.txt"));
+	cl_git_pass(git_index_add_bypath(index, "IKEEPSIX.txt"));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, tree, index, NULL));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(2, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_ADDED]);
+
+	opts.flags = GIT_DIFF_FIND_ALL;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(1, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
+
+	git_diff_free(diff);
+	git_index_free(index);
+	git_tree_free(tree);
+}
+
+void test_diff_rename__unmodified_can_be_renamed(void)
+{
+	git_index *index;
+	git_tree *tree;
+	git_diff *diff = NULL;
+	diff_expects exp;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(
+		git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(p_rename("renames/ikeepsix.txt", "renames/ikeepsix2.txt"));
+
+	cl_git_pass(git_index_remove_bypath(index, "ikeepsix.txt"));
+	cl_git_pass(git_index_add_bypath(index, "ikeepsix2.txt"));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(2, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_ADDED]);
+
+	opts.flags = GIT_DIFF_FIND_ALL;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(1, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(1, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
+
+	git_diff_free(diff);
+	git_index_free(index);
+	git_tree_free(tree);
+}
+
+void test_diff_rename__rewrite_on_single_file(void)
+{
+	git_index *index;
+	git_diff *diff = NULL;
+	diff_expects exp;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT;
+
+	diffopts.flags = GIT_DIFF_INCLUDE_UNTRACKED;
+
+	findopts.flags = GIT_DIFF_FIND_FOR_UNTRACKED |
+		GIT_DIFF_FIND_AND_BREAK_REWRITES |
+		GIT_DIFF_FIND_RENAMES_FROM_REWRITES;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_rewritefile("renames/ikeepsix.txt",
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n");
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, &diffopts));
+	cl_git_pass(git_diff_find_similar(diff, &findopts));
+
+	memset(&exp, 0, sizeof(exp));
+
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(2, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	git_diff_free(diff);
+	git_index_free(index);
+}
+
+void test_diff_rename__can_find_copy_to_split(void)
+{
+	git_buf c1 = GIT_BUF_INIT;
+	git_index *index;
+	git_tree *tree;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	diff_expects exp;
+
+	cl_git_pass(git_futils_readbuffer(&c1, "renames/songof7cities.txt"));
+	cl_git_pass(git_futils_writebuffer(&c1, "renames/untimely.txt", 0, 0));
+
+	cl_git_pass(
+		git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_read_tree(index, tree));
+	cl_git_pass(git_index_add_bypath(index, "untimely.txt"));
+
+	diffopts.flags = GIT_DIFF_INCLUDE_UNMODIFIED;
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_UNMODIFIED]);
+
+	opts.flags = GIT_DIFF_FIND_ALL;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(5, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_COPIED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_UNMODIFIED]);
+
+	git_diff_free(diff);
+	git_tree_free(tree);
+	git_index_free(index);
+
+	git_buf_free(&c1);
+}
+
+void test_diff_rename__can_delete_unmodified_deltas(void)
+{
+	git_buf c1 = GIT_BUF_INIT;
+	git_index *index;
+	git_tree *tree;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	diff_expects exp;
+
+	cl_git_pass(git_futils_readbuffer(&c1, "renames/songof7cities.txt"));
+	cl_git_pass(git_futils_writebuffer(&c1, "renames/untimely.txt", 0, 0));
+
+	cl_git_pass(
+		git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_read_tree(index, tree));
+	cl_git_pass(git_index_add_bypath(index, "untimely.txt"));
+
+	diffopts.flags = GIT_DIFF_INCLUDE_UNMODIFIED;
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_UNMODIFIED]);
+
+	opts.flags = GIT_DIFF_FIND_ALL | GIT_DIFF_FIND_REMOVE_UNMODIFIED;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(2, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_COPIED]);
+
+	git_diff_free(diff);
+	git_tree_free(tree);
+	git_index_free(index);
+
+	git_buf_free(&c1);
+}
+
+void test_diff_rename__matches_config_behavior(void)
+{
+	const char *sha0 = "31e47d8c1fa36d7f8d537b96158e3f024de0a9f2";
+	const char *sha1 = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
+	const char *sha2 = "1c068dee5790ef1580cfc4cd670915b48d790084";
+
+	git_tree *tree0, *tree1, *tree2;
+	git_config *cfg;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	diff_expects exp;
+
+	opts.flags = GIT_DIFF_FIND_BY_CONFIG;
+	tree0 = resolve_commit_oid_to_tree(g_repo, sha0);
+	tree1 = resolve_commit_oid_to_tree(g_repo, sha1);
+	tree2 = resolve_commit_oid_to_tree(g_repo, sha2);
+
+	diffopts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
+	cl_git_pass(git_repository_config(&cfg, g_repo));
+
+	/* diff.renames = false; no rename detection should happen */
+	cl_git_pass(git_config_set_bool(cfg, "diff.renames", false));
+	cl_git_pass(git_diff_tree_to_tree(
+				&diff, g_repo, tree0, tree1, &diffopts));
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+	cl_git_pass(git_diff_foreach(diff,
+				diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNMODIFIED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	git_diff_free(diff);
+
+	/* diff.renames = true; should act like -M */
+	cl_git_pass(git_config_set_bool(cfg, "diff.renames", true));
+	cl_git_pass(git_diff_tree_to_tree(
+				&diff, g_repo, tree0, tree1, &diffopts));
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+	cl_git_pass(git_diff_foreach(diff,
+				diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(3, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNMODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
+	git_diff_free(diff);
+
+	/* diff.renames = copies; should act like -M -C */
+	cl_git_pass(git_config_set_string(cfg, "diff.renames", "copies"));
+	cl_git_pass(git_diff_tree_to_tree(
+				&diff, g_repo, tree1, tree2, &diffopts));
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+	cl_git_pass(git_diff_foreach(diff,
+				diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNMODIFIED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_COPIED]);
+	git_diff_free(diff);
+
+	/* NULL find options is the same as GIT_DIFF_FIND_BY_CONFIG */
+	cl_git_pass(git_diff_tree_to_tree(
+				&diff, g_repo, tree1, tree2, &diffopts));
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_find_similar(diff, NULL));
+	cl_git_pass(git_diff_foreach(diff,
+				diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNMODIFIED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_COPIED]);
+	git_diff_free(diff);
+
+	/* Cleanup */
+	git_tree_free(tree0);
+	git_tree_free(tree1);
+	git_tree_free(tree2);
+	git_config_free(cfg);
+}
+
+void test_diff_rename__can_override_thresholds_when_obeying_config(void)
+{
+	const char *sha1 = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
+	const char *sha2 = "1c068dee5790ef1580cfc4cd670915b48d790084";
+
+	git_tree *tree1, *tree2;
+	git_config *cfg;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	diff_expects exp;
+
+	tree1 = resolve_commit_oid_to_tree(g_repo, sha1);
+	tree2 = resolve_commit_oid_to_tree(g_repo, sha2);
+
+	diffopts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
+	opts.flags = GIT_DIFF_FIND_BY_CONFIG;
+
+	cl_git_pass(git_repository_config(&cfg, g_repo));
+	cl_git_pass(git_config_set_string(cfg, "diff.renames", "copies"));
+	git_config_free(cfg);
+
+	/* copy threshold = 96%, should see creation of ikeepsix.txt */
+	opts.copy_threshold = 96;
+	cl_git_pass(git_diff_tree_to_tree(
+				&diff, g_repo, tree1, tree2, &diffopts));
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+	cl_git_pass(git_diff_foreach(diff,
+				diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNMODIFIED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_ADDED]);
+	git_diff_free(diff);
+
+	/* copy threshold = 20%, should see sixserving.txt => ikeepsix.txt */
+	opts.copy_threshold = 20;
+	cl_git_pass(git_diff_tree_to_tree(
+				&diff, g_repo, tree1, tree2, &diffopts));
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+	cl_git_pass(git_diff_foreach(diff,
+				diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNMODIFIED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_COPIED]);
+	git_diff_free(diff);
+
+	/* Cleanup */
+	git_tree_free(tree1);
+	git_tree_free(tree2);
+}
+
+void test_diff_rename__by_config_doesnt_mess_with_whitespace_settings(void)
+{
+	const char *sha1 = "1c068dee5790ef1580cfc4cd670915b48d790084";
+	const char *sha2 = "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13";
+
+	git_tree *tree1, *tree2;
+	git_config *cfg;
+	git_diff *diff;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+	diff_expects exp;
+
+	tree1 = resolve_commit_oid_to_tree(g_repo, sha1);
+	tree2 = resolve_commit_oid_to_tree(g_repo, sha2);
+
+	diffopts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
+	opts.flags = GIT_DIFF_FIND_BY_CONFIG;
+
+	cl_git_pass(git_repository_config(&cfg, g_repo));
+	cl_git_pass(git_config_set_string(cfg, "diff.renames", "copies"));
+	git_config_free(cfg);
+
+	/* Don't ignore whitespace; this should find a change in sixserving.txt */
+	opts.flags |= 0 | GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE;
+	cl_git_pass(git_diff_tree_to_tree(
+				&diff, g_repo, tree1, tree2, &diffopts));
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+	cl_git_pass(git_diff_foreach(diff,
+				diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(5, exp.files);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_ADDED]);
+	git_diff_free(diff);
+
+	/* Cleanup */
+	git_tree_free(tree1);
+	git_tree_free(tree2);
+}
+
+static void expect_files_renamed(const char *one, const char *two, uint32_t whitespace_flags)
+{
+	git_index *index;
+	git_diff *diff = NULL;
+	diff_expects exp;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT;
+
+	diffopts.flags = GIT_DIFF_INCLUDE_UNTRACKED;
+	findopts.flags = GIT_DIFF_FIND_FOR_UNTRACKED |
+		GIT_DIFF_FIND_AND_BREAK_REWRITES |
+		GIT_DIFF_FIND_RENAMES_FROM_REWRITES |
+		whitespace_flags;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_rewritefile("renames/ikeepsix.txt", one);
+	cl_git_pass(git_index_add_bypath(index, "ikeepsix.txt"));
+
+	cl_git_rmfile("renames/ikeepsix.txt");
+	cl_git_rewritefile("renames/ikeepsix2.txt", two);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, &diffopts));
+	cl_git_pass(git_diff_find_similar(diff, &findopts));
+
+	memset(&exp, 0, sizeof(exp));
+
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(1, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
+
+	git_diff_free(diff);
+	git_index_free(index);
+}
+
+/* test some variations on empty and blank files */
+void test_diff_rename__empty_files_renamed(void)
+{
+	/* empty files are identical when ignoring whitespace or not */
+	expect_files_renamed("", "", GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE);
+	expect_files_renamed("", "",  GIT_DIFF_FIND_IGNORE_WHITESPACE);
+}
+
+/* test that blank files are similar when ignoring whitespace */
+void test_diff_rename__blank_files_renamed_when_ignoring_whitespace(void)
+{
+	expect_files_renamed("", "\n\n",  GIT_DIFF_FIND_IGNORE_WHITESPACE);
+	expect_files_renamed("", "\r\n\r\n",  GIT_DIFF_FIND_IGNORE_WHITESPACE);
+	expect_files_renamed("\r\n\r\n", "\n\n\n",  GIT_DIFF_FIND_IGNORE_WHITESPACE);
+
+	expect_files_renamed("    ", "\n\n",  GIT_DIFF_FIND_IGNORE_WHITESPACE);
+	expect_files_renamed("   \n   \n", "\n\n",  GIT_DIFF_FIND_IGNORE_WHITESPACE);
+}
+
+/* blank files are not similar when whitespace is not ignored */
+static void expect_files_not_renamed(const char *one, const char *two, uint32_t whitespace_flags)
+{
+	git_index *index;
+	git_diff *diff = NULL;
+	diff_expects exp;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT;
+
+	diffopts.flags = GIT_DIFF_INCLUDE_UNTRACKED;
+
+	findopts.flags = GIT_DIFF_FIND_FOR_UNTRACKED |
+		whitespace_flags;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_rewritefile("renames/ikeepsix.txt", one);
+	cl_git_pass(git_index_add_bypath(index, "ikeepsix.txt"));
+
+	cl_git_rmfile("renames/ikeepsix.txt");
+	cl_git_rewritefile("renames/ikeepsix2.txt", two);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, &diffopts));
+	cl_git_pass(git_diff_find_similar(diff, &findopts));
+
+	memset(&exp, 0, sizeof(exp));
+
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(2, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	git_diff_free(diff);
+	git_index_free(index);
+}
+
+/* test that blank files are similar when ignoring renames */
+void test_diff_rename__blank_files_not_renamed_when_not_ignoring_whitespace(void)
+{
+	expect_files_not_renamed("", "\r\n\r\n\r\n",  GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE);
+	expect_files_not_renamed("", "\n\n\n\n",  GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE);
+	expect_files_not_renamed("\n\n\n\n", "\r\n\r\n\r\n",  GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/stats.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/stats.c
new file mode 100755
index 0000000..f731997
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/stats.c
@@ -0,0 +1,289 @@
+#include "clar.h"
+#include "clar_libgit2.h"
+
+#include "buffer.h"
+#include "commit.h"
+#include "diff.h"
+
+static git_repository *_repo;
+static git_diff_stats *_stats;
+
+void test_diff_stats__initialize(void)
+{
+	_repo = cl_git_sandbox_init("diff_format_email");
+}
+
+void test_diff_stats__cleanup(void)
+{
+	git_diff_stats_free(_stats); _stats = NULL;
+	cl_git_sandbox_cleanup();
+}
+
+static void diff_stats_from_commit_oid(
+	git_diff_stats **stats, const char *oidstr, bool rename)
+{
+	git_oid oid;
+	git_commit *commit;
+	git_diff *diff;
+
+	git_oid_fromstr(&oid, oidstr);
+	cl_git_pass(git_commit_lookup(&commit, _repo, &oid));
+	cl_git_pass(git_diff__commit(&diff, _repo, commit, NULL));
+	if (rename)
+		cl_git_pass(git_diff_find_similar(diff, NULL));
+	cl_git_pass(git_diff_get_stats(stats, diff));
+
+	git_diff_free(diff);
+	git_commit_free(commit);
+}
+
+void test_diff_stats__stat(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	const char *stat =
+	" file1.txt | 8 +++++---\n" \
+	" 1 file changed, 5 insertions(+), 3 deletions(-)\n";
+
+	diff_stats_from_commit_oid(
+		&_stats, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", false);
+
+	cl_assert_equal_sz(1, git_diff_stats_files_changed(_stats));
+	cl_assert_equal_sz(5, git_diff_stats_insertions(_stats));
+	cl_assert_equal_sz(3, git_diff_stats_deletions(_stats));
+
+	cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0));
+	cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0);
+	git_buf_free(&buf);
+
+	cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 80));
+	cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0);
+	git_buf_free(&buf);
+}
+
+void test_diff_stats__multiple_hunks(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	const char *stat =
+	" file2.txt | 5 +++--\n" \
+	" file3.txt | 6 ++++--\n" \
+	" 2 files changed, 7 insertions(+), 4 deletions(-)\n";
+
+	diff_stats_from_commit_oid(
+		&_stats, "cd471f0d8770371e1bc78bcbb38db4c7e4106bd2", false);
+
+	cl_assert_equal_sz(2, git_diff_stats_files_changed(_stats));
+	cl_assert_equal_sz(7, git_diff_stats_insertions(_stats));
+	cl_assert_equal_sz(4, git_diff_stats_deletions(_stats));
+
+	cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0));
+	cl_assert_equal_s(stat, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
+
+void test_diff_stats__numstat(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	const char *stat =
+	"3       2       file2.txt\n"
+	"4       2       file3.txt\n";
+
+	diff_stats_from_commit_oid(
+		&_stats, "cd471f0d8770371e1bc78bcbb38db4c7e4106bd2", false);
+
+	cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_NUMBER, 0));
+	cl_assert_equal_s(stat, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
+
+void test_diff_stats__shortstat(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	const char *stat =
+	" 1 file changed, 5 insertions(+), 3 deletions(-)\n";
+
+	diff_stats_from_commit_oid(
+		&_stats, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", false);
+
+	cl_assert_equal_sz(1, git_diff_stats_files_changed(_stats));
+	cl_assert_equal_sz(5, git_diff_stats_insertions(_stats));
+	cl_assert_equal_sz(3, git_diff_stats_deletions(_stats));
+
+	cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_SHORT, 0));
+	cl_assert_equal_s(stat, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
+
+void test_diff_stats__rename(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	const char *stat =
+	" file2.txt => file2.txt.renamed | 1 +\n"
+	" file3.txt => file3.txt.renamed | 4 +++-\n"
+	" 2 files changed, 4 insertions(+), 1 deletion(-)\n";
+
+	diff_stats_from_commit_oid(
+		&_stats, "8947a46e2097638ca6040ad4877246f4186ec3bd", true);
+
+	cl_assert_equal_sz(2, git_diff_stats_files_changed(_stats));
+	cl_assert_equal_sz(4, git_diff_stats_insertions(_stats));
+	cl_assert_equal_sz(1, git_diff_stats_deletions(_stats));
+
+	cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0));
+	cl_assert_equal_s(stat, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
+
+void test_diff_stats__rename_nochanges(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	const char *stat =
+	" file2.txt.renamed => file2.txt.renamed2 | 0\n"
+	" file3.txt.renamed => file3.txt.renamed2 | 0\n"
+	" 2 files changed, 0 insertions(+), 0 deletions(-)\n";
+
+	diff_stats_from_commit_oid(
+		&_stats, "3991dce9e71a0641ca49a6a4eea6c9e7ff402ed4", true);
+
+	cl_assert_equal_sz(2, git_diff_stats_files_changed(_stats));
+	cl_assert_equal_sz(0, git_diff_stats_insertions(_stats));
+	cl_assert_equal_sz(0, git_diff_stats_deletions(_stats));
+
+	cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0));
+	cl_assert_equal_s(stat, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
+
+void test_diff_stats__rename_and_modifiy(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	const char *stat =
+	" file2.txt.renamed2                      | 2 +-\n"
+	" file3.txt.renamed2 => file3.txt.renamed | 0\n"
+	" 2 files changed, 1 insertion(+), 1 deletion(-)\n";
+
+	diff_stats_from_commit_oid(
+		&_stats, "4ca10087e696d2ba78d07b146a118e9a7096ed4f", true);
+
+	cl_assert_equal_sz(2, git_diff_stats_files_changed(_stats));
+	cl_assert_equal_sz(1, git_diff_stats_insertions(_stats));
+	cl_assert_equal_sz(1, git_diff_stats_deletions(_stats));
+
+	cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0));
+	cl_assert_equal_s(stat, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
+
+void test_diff_stats__rename_no_find(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	const char *stat =
+	" file2.txt         | 5 -----\n"
+	" file2.txt.renamed | 6 ++++++\n"
+	" file3.txt         | 5 -----\n"
+	" file3.txt.renamed | 7 +++++++\n"
+	" 4 files changed, 13 insertions(+), 10 deletions(-)\n";
+
+	diff_stats_from_commit_oid(
+		&_stats, "8947a46e2097638ca6040ad4877246f4186ec3bd", false);
+
+	cl_assert_equal_sz(4, git_diff_stats_files_changed(_stats));
+	cl_assert_equal_sz(13, git_diff_stats_insertions(_stats));
+	cl_assert_equal_sz(10, git_diff_stats_deletions(_stats));
+
+	cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0));
+	cl_assert_equal_s(stat, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
+
+void test_diff_stats__rename_nochanges_no_find(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	const char *stat =
+	" file2.txt.renamed  | 6 ------\n"
+	" file2.txt.renamed2 | 6 ++++++\n"
+	" file3.txt.renamed  | 7 -------\n"
+	" file3.txt.renamed2 | 7 +++++++\n"
+	" 4 files changed, 13 insertions(+), 13 deletions(-)\n";
+
+	diff_stats_from_commit_oid(
+		&_stats, "3991dce9e71a0641ca49a6a4eea6c9e7ff402ed4", false);
+
+	cl_assert_equal_sz(4, git_diff_stats_files_changed(_stats));
+	cl_assert_equal_sz(13, git_diff_stats_insertions(_stats));
+	cl_assert_equal_sz(13, git_diff_stats_deletions(_stats));
+
+	cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0));
+	cl_assert_equal_s(stat, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
+
+void test_diff_stats__rename_and_modifiy_no_find(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	const char *stat =
+	" file2.txt.renamed2 | 2 +-\n"
+	" file3.txt.renamed  | 7 +++++++\n"
+	" file3.txt.renamed2 | 7 -------\n"
+	" 3 files changed, 8 insertions(+), 8 deletions(-)\n";
+
+	diff_stats_from_commit_oid(
+		&_stats, "4ca10087e696d2ba78d07b146a118e9a7096ed4f", false);
+
+	cl_assert_equal_sz(3, git_diff_stats_files_changed(_stats));
+	cl_assert_equal_sz(8, git_diff_stats_insertions(_stats));
+	cl_assert_equal_sz(8, git_diff_stats_deletions(_stats));
+
+	cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0));
+	cl_assert_equal_s(stat, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
+
+void test_diff_stats__binary(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	const char *stat =
+	" binary.bin | Bin 3 -> 0 bytes\n"
+	" 1 file changed, 0 insertions(+), 0 deletions(-)\n";
+	/* TODO: Actually 0 bytes here should be 5!. Seems like we don't load the new content for binary files? */
+
+	diff_stats_from_commit_oid(
+		&_stats, "8d7523f6fcb2404257889abe0d96f093d9f524f9", false);
+
+	cl_assert_equal_sz(1, git_diff_stats_files_changed(_stats));
+	cl_assert_equal_sz(0, git_diff_stats_insertions(_stats));
+	cl_assert_equal_sz(0, git_diff_stats_deletions(_stats));
+
+	cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0));
+	cl_assert_equal_s(stat, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
+
+void test_diff_stats__binary_numstat(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	const char *stat =
+	"-       -       binary.bin\n";
+
+	diff_stats_from_commit_oid(
+		&_stats, "8d7523f6fcb2404257889abe0d96f093d9f524f9", false);
+
+	cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_NUMBER, 0));
+	cl_assert_equal_s(stat, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
+
+void test_diff_stats__mode_change(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	const char *stat =
+	" file1.txt.renamed | 0\n" \
+	" 1 file changed, 0 insertions(+), 0 deletions(-)\n" \
+		" mode change 100644 => 100755 file1.txt.renamed\n";
+
+	diff_stats_from_commit_oid(
+		&_stats, "7ade76dd34bba4733cf9878079f9fd4a456a9189", false);
+
+	cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL | GIT_DIFF_STATS_INCLUDE_SUMMARY, 0));
+	cl_assert_equal_s(stat, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/submodules.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/submodules.c
new file mode 100755
index 0000000..08682cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/submodules.c
@@ -0,0 +1,495 @@
+#include "clar_libgit2.h"
+#include "repository.h"
+#include "posix.h"
+#include "diff_helpers.h"
+#include "../submodule/submodule_helpers.h"
+
+static git_repository *g_repo = NULL;
+
+void test_diff_submodules__initialize(void)
+{
+}
+
+void test_diff_submodules__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+#define get_buf_ptr(buf) ((buf)->asize ? (buf)->ptr : NULL)
+
+static void check_diff_patches_at_line(
+	git_diff *diff, const char **expected, const char *file, int line)
+{
+	const git_diff_delta *delta;
+	git_patch *patch = NULL;
+	size_t d, num_d = git_diff_num_deltas(diff);
+	git_buf buf = GIT_BUF_INIT;
+
+	for (d = 0; d < num_d; ++d, git_patch_free(patch)) {
+		cl_git_pass(git_patch_from_diff(&patch, diff, d));
+		cl_assert((delta = git_patch_get_delta(patch)) != NULL);
+
+		if (delta->status == GIT_DELTA_UNMODIFIED) {
+			cl_assert_at_line(expected[d] == NULL, file, line);
+			continue;
+		}
+
+		if (expected[d] && !strcmp(expected[d], "<SKIP>"))
+			continue;
+		if (expected[d] && !strcmp(expected[d], "<UNTRACKED>")) {
+			cl_assert_at_line(delta->status == GIT_DELTA_UNTRACKED, file, line);
+			continue;
+		}
+		if (expected[d] && !strcmp(expected[d], "<END>")) {
+			cl_git_pass(git_patch_to_buf(&buf, patch));
+			cl_assert_at_line(!strcmp(expected[d], "<END>"), file, line);
+		}
+
+		cl_git_pass(git_patch_to_buf(&buf, patch));
+
+		clar__assert_equal(
+			file, line, "expected diff did not match actual diff", 1,
+			"%s", expected[d], get_buf_ptr(&buf));
+		git_buf_free(&buf);
+	}
+
+	cl_assert_at_line(expected[d] && !strcmp(expected[d], "<END>"), file, line);
+}
+
+#define check_diff_patches(diff, exp) \
+	check_diff_patches_at_line(diff, exp, __FILE__, __LINE__)
+
+void test_diff_submodules__unmodified_submodule(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	static const char *expected[] = {
+		"<SKIP>", /* .gitmodules */
+		NULL, /* added */
+		NULL, /* ignored */
+		"diff --git a/modified b/modified\nindex 092bfb9..452216e 100644\n--- a/modified\n+++ b/modified\n@@ -1 +1,2 @@\n-yo\n+changed\n+\n", /* modified */
+		NULL, /* testrepo.git */
+		NULL, /* unmodified */
+		NULL, /* untracked */
+		"<END>"
+	};
+
+	g_repo = setup_fixture_submodules();
+
+	opts.flags = GIT_DIFF_INCLUDE_IGNORED |
+		GIT_DIFF_INCLUDE_UNTRACKED |
+		GIT_DIFF_INCLUDE_UNMODIFIED;
+	opts.old_prefix = "a"; opts.new_prefix = "b";
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected);
+	git_diff_free(diff);
+}
+
+void test_diff_submodules__dirty_submodule(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	static const char *expected[] = {
+		"<SKIP>", /* .gitmodules */
+		NULL, /* added */
+		NULL, /* ignored */
+		"diff --git a/modified b/modified\nindex 092bfb9..452216e 100644\n--- a/modified\n+++ b/modified\n@@ -1 +1,2 @@\n-yo\n+changed\n+\n", /* modified */
+		"diff --git a/testrepo b/testrepo\nindex a65fedf..a65fedf 160000\n--- a/testrepo\n+++ b/testrepo\n@@ -1 +1 @@\n-Subproject commit a65fedf39aefe402d3bb6e24df4d4f5fe4547750\n+Subproject commit a65fedf39aefe402d3bb6e24df4d4f5fe4547750-dirty\n", /* testrepo.git */
+		NULL, /* unmodified */
+		NULL, /* untracked */
+		"<END>"
+	};
+
+	g_repo = setup_fixture_submodules();
+
+	cl_git_rewritefile("submodules/testrepo/README", "heyheyhey");
+	cl_git_mkfile("submodules/testrepo/all_new.txt", "never seen before");
+
+	opts.flags = GIT_DIFF_INCLUDE_IGNORED |
+		GIT_DIFF_INCLUDE_UNTRACKED |
+		GIT_DIFF_INCLUDE_UNMODIFIED;
+	opts.old_prefix = "a"; opts.new_prefix = "b";
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected);
+	git_diff_free(diff);
+}
+
+void test_diff_submodules__dirty_submodule_2(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL, *diff2 = NULL;
+	char *smpath = "testrepo";
+	static const char *expected_none[] = {
+		"<END>"
+	};
+	static const char *expected_dirty[] = {
+		"diff --git a/testrepo b/testrepo\nindex a65fedf..a65fedf 160000\n--- a/testrepo\n+++ b/testrepo\n@@ -1 +1 @@\n-Subproject commit a65fedf39aefe402d3bb6e24df4d4f5fe4547750\n+Subproject commit a65fedf39aefe402d3bb6e24df4d4f5fe4547750-dirty\n", /* testrepo.git */
+		"<END>"
+	};
+
+	g_repo = setup_fixture_submodules();
+
+	opts.flags = GIT_DIFF_INCLUDE_UNTRACKED |
+		GIT_DIFF_SHOW_UNTRACKED_CONTENT |
+		GIT_DIFF_RECURSE_UNTRACKED_DIRS |
+		GIT_DIFF_DISABLE_PATHSPEC_MATCH;
+	opts.old_prefix = "a"; opts.new_prefix = "b";
+	opts.pathspec.count = 1;
+	opts.pathspec.strings = &smpath;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_none);
+	git_diff_free(diff);
+
+	cl_git_rewritefile("submodules/testrepo/README", "heyheyhey");
+	cl_git_mkfile("submodules/testrepo/all_new.txt", "never seen before");
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_dirty);
+
+	{
+		git_tree *head;
+
+		cl_git_pass(git_repository_head_tree(&head, g_repo));
+		cl_git_pass(git_diff_tree_to_index(&diff2, g_repo, head, NULL, &opts));
+		cl_git_pass(git_diff_merge(diff, diff2));
+		git_diff_free(diff2);
+		git_tree_free(head);
+
+		check_diff_patches(diff, expected_dirty);
+	}
+
+	git_diff_free(diff);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_dirty);
+	git_diff_free(diff);
+}
+
+void test_diff_submodules__submod2_index_to_wd(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	static const char *expected[] = {
+		"<SKIP>", /* .gitmodules */
+		"<UNTRACKED>", /* not-submodule */
+		"<UNTRACKED>", /* not */
+		"diff --git a/sm_changed_file b/sm_changed_file\nindex 4800958..4800958 160000\n--- a/sm_changed_file\n+++ b/sm_changed_file\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_file */
+		"diff --git a/sm_changed_head b/sm_changed_head\nindex 4800958..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n", /* sm_changed_head */
+		"<UNTRACKED>", /* sm_changed_head- */
+		"<UNTRACKED>", /* sm_changed_head_ */
+		"diff --git a/sm_changed_index b/sm_changed_index\nindex 4800958..4800958 160000\n--- a/sm_changed_index\n+++ b/sm_changed_index\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_index */
+		"diff --git a/sm_changed_untracked_file b/sm_changed_untracked_file\nindex 4800958..4800958 160000\n--- a/sm_changed_untracked_file\n+++ b/sm_changed_untracked_file\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_untracked_file */
+		"diff --git a/sm_missing_commits b/sm_missing_commits\nindex 4800958..5e49635 160000\n--- a/sm_missing_commits\n+++ b/sm_missing_commits\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 5e4963595a9774b90524d35a807169049de8ccad\n", /* sm_missing_commits */
+		"<END>"
+	};
+
+	g_repo = setup_fixture_submod2();
+
+	/* bracket existing submodule with similarly named items */
+	cl_git_mkfile("submod2/sm_changed_head-", "hello");
+	cl_git_mkfile("submod2/sm_changed_head_", "hello");
+
+	opts.flags = GIT_DIFF_INCLUDE_UNTRACKED;
+	opts.old_prefix = "a"; opts.new_prefix = "b";
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected);
+	git_diff_free(diff);
+}
+
+void test_diff_submodules__submod2_head_to_index(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_tree *head;
+	git_diff *diff = NULL;
+	static const char *expected[] = {
+		"<SKIP>", /* .gitmodules */
+		"diff --git a/sm_added_and_uncommited b/sm_added_and_uncommited\nnew file mode 160000\nindex 0000000..4800958\n--- /dev/null\n+++ b/sm_added_and_uncommited\n@@ -0,0 +1 @@\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n", /* sm_added_and_uncommited */
+		"<END>"
+	};
+
+	g_repo = setup_fixture_submod2();
+
+	cl_git_pass(git_repository_head_tree(&head, g_repo));
+
+	opts.flags = GIT_DIFF_INCLUDE_UNTRACKED;
+	opts.old_prefix = "a"; opts.new_prefix = "b";
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, head, NULL, &opts));
+	check_diff_patches(diff, expected);
+	git_diff_free(diff);
+
+	git_tree_free(head);
+}
+
+void test_diff_submodules__invalid_cache(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	git_submodule *sm;
+	char *smpath = "sm_changed_head";
+	git_repository *smrepo;
+	git_index *smindex;
+	static const char *expected_baseline[] = {
+		"diff --git a/sm_changed_head b/sm_changed_head\nindex 4800958..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n", /* sm_changed_head */
+		"<END>"
+	};
+	static const char *expected_unchanged[] = { "<END>" };
+	static const char *expected_dirty[] = {
+		"diff --git a/sm_changed_head b/sm_changed_head\nindex 3d9386c..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247-dirty\n",
+		"<END>"
+	};
+	static const char *expected_moved[] = {
+		"diff --git a/sm_changed_head b/sm_changed_head\nindex 3d9386c..7002348 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n+Subproject commit 700234833f6ccc20d744b238612646be071acaae\n",
+		"<END>"
+	};
+	static const char *expected_moved_dirty[] = {
+		"diff --git a/sm_changed_head b/sm_changed_head\nindex 3d9386c..7002348 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n+Subproject commit 700234833f6ccc20d744b238612646be071acaae-dirty\n",
+		"<END>"
+	};
+
+	g_repo = setup_fixture_submod2();
+
+	opts.flags = GIT_DIFF_INCLUDE_UNTRACKED;
+	opts.old_prefix = "a"; opts.new_prefix = "b";
+	opts.pathspec.count = 1;
+	opts.pathspec.strings = &smpath;
+
+	/* baseline */
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_baseline);
+	git_diff_free(diff);
+
+	/* update index with new HEAD */
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, smpath));
+	cl_git_pass(git_submodule_add_to_index(sm, 1));
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_unchanged);
+	git_diff_free(diff);
+
+	/* create untracked file in submodule working directory */
+	cl_git_mkfile("submod2/sm_changed_head/new_around_here", "hello");
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_NONE);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_dirty);
+	git_diff_free(diff);
+
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_UNTRACKED);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_unchanged);
+	git_diff_free(diff);
+
+	/* modify tracked file in submodule working directory */
+	cl_git_append2file(
+		"submod2/sm_changed_head/file_to_modify", "\nmore stuff\n");
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_dirty);
+	git_diff_free(diff);
+
+	git_submodule_free(sm);
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, smpath));
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_dirty);
+	git_diff_free(diff);
+
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_DIRTY);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_unchanged);
+	git_diff_free(diff);
+
+	/* add file to index in submodule */
+	cl_git_pass(git_submodule_open(&smrepo, sm));
+	cl_git_pass(git_repository_index(&smindex, smrepo));
+	cl_git_pass(git_index_add_bypath(smindex, "file_to_modify"));
+
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_UNTRACKED);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_dirty);
+	git_diff_free(diff);
+
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_DIRTY);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_unchanged);
+	git_diff_free(diff);
+
+	/* commit changed index of submodule */
+	cl_repo_commit_from_index(NULL, smrepo, NULL, 1372350000, "Move it");
+
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_DIRTY);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_moved);
+	git_diff_free(diff);
+
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_ALL);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_unchanged);
+	git_diff_free(diff);
+
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_NONE);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_moved_dirty);
+	git_diff_free(diff);
+
+	p_unlink("submod2/sm_changed_head/new_around_here");
+
+	git_submodule_free(sm);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_moved);
+	git_diff_free(diff);
+
+	git_index_free(smindex);
+	git_repository_free(smrepo);
+}
+
+void test_diff_submodules__diff_ignore_options(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	git_config *cfg;
+	static const char *expected_normal[] = {
+		"<SKIP>", /* .gitmodules */
+		"<UNTRACKED>", /* not-submodule */
+		"<UNTRACKED>", /* not */
+		"diff --git a/sm_changed_file b/sm_changed_file\nindex 4800958..4800958 160000\n--- a/sm_changed_file\n+++ b/sm_changed_file\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_file */
+		"diff --git a/sm_changed_head b/sm_changed_head\nindex 4800958..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n", /* sm_changed_head */
+		"diff --git a/sm_changed_index b/sm_changed_index\nindex 4800958..4800958 160000\n--- a/sm_changed_index\n+++ b/sm_changed_index\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_index */
+		"diff --git a/sm_changed_untracked_file b/sm_changed_untracked_file\nindex 4800958..4800958 160000\n--- a/sm_changed_untracked_file\n+++ b/sm_changed_untracked_file\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_untracked_file */
+		"diff --git a/sm_missing_commits b/sm_missing_commits\nindex 4800958..5e49635 160000\n--- a/sm_missing_commits\n+++ b/sm_missing_commits\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 5e4963595a9774b90524d35a807169049de8ccad\n", /* sm_missing_commits */
+		"<END>"
+	};
+	static const char *expected_ignore_all[] = {
+		"<SKIP>", /* .gitmodules */
+		"<UNTRACKED>", /* not-submodule */
+		"<UNTRACKED>", /* not */
+		"<END>"
+	};
+	static const char *expected_ignore_dirty[] = {
+		"<SKIP>", /* .gitmodules */
+		"<UNTRACKED>", /* not-submodule */
+		"<UNTRACKED>", /* not */
+		"diff --git a/sm_changed_head b/sm_changed_head\nindex 4800958..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n", /* sm_changed_head */
+		"diff --git a/sm_missing_commits b/sm_missing_commits\nindex 4800958..5e49635 160000\n--- a/sm_missing_commits\n+++ b/sm_missing_commits\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 5e4963595a9774b90524d35a807169049de8ccad\n", /* sm_missing_commits */
+		"<END>"
+	};
+
+	g_repo = setup_fixture_submod2();
+
+	opts.flags = GIT_DIFF_INCLUDE_UNTRACKED;
+	opts.old_prefix = "a"; opts.new_prefix = "b";
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_normal);
+	git_diff_free(diff);
+
+	opts.flags |= GIT_DIFF_IGNORE_SUBMODULES;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_ignore_all);
+	git_diff_free(diff);
+
+	opts.flags &= ~GIT_DIFF_IGNORE_SUBMODULES;
+	opts.ignore_submodules = GIT_SUBMODULE_IGNORE_ALL;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_ignore_all);
+	git_diff_free(diff);
+
+	opts.ignore_submodules = GIT_SUBMODULE_IGNORE_DIRTY;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_ignore_dirty);
+	git_diff_free(diff);
+
+	opts.ignore_submodules = 0;
+	cl_git_pass(git_repository_config(&cfg, g_repo));
+	cl_git_pass(git_config_set_bool(cfg, "diff.ignoreSubmodules", false));
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_normal);
+	git_diff_free(diff);
+
+	cl_git_pass(git_config_set_bool(cfg, "diff.ignoreSubmodules", true));
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_ignore_all);
+	git_diff_free(diff);
+
+	cl_git_pass(git_config_set_string(cfg, "diff.ignoreSubmodules", "none"));
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_normal);
+	git_diff_free(diff);
+
+	cl_git_pass(git_config_set_string(cfg, "diff.ignoreSubmodules", "dirty"));
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	check_diff_patches(diff, expected_ignore_dirty);
+	git_diff_free(diff);
+
+	git_config_free(cfg);
+}
+
+void test_diff_submodules__skips_empty_includes_used(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	diff_expects exp;
+
+	/* A side effect of of Git's handling of untracked directories and
+	 * auto-ignoring of ".git" entries is that a newly initialized Git
+	 * repo inside another repo will be skipped by diff, but one that
+	 * actually has a commit it in will show as an untracked directory.
+	 * Let's make sure that works.
+	 */
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(0, exp.files);
+	git_diff_free(diff);
+
+	{
+		git_repository *r2;
+		cl_git_pass(git_repository_init(&r2, "empty_standard_repo/subrepo", 0));
+		git_repository_free(r2);
+	}
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(1, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
+	git_diff_free(diff);
+
+	cl_git_mkfile("empty_standard_repo/subrepo/README.txt", "hello\n");
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(1, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNTRACKED]);
+	git_diff_free(diff);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/tree.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/tree.c
new file mode 100755
index 0000000..2bc9e6a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/tree.c
@@ -0,0 +1,526 @@
+#include "clar_libgit2.h"
+#include "diff_helpers.h"
+
+static git_repository *g_repo = NULL;
+static git_diff_options opts;
+static git_diff *diff;
+static git_tree *a, *b;
+static diff_expects expect;
+
+void test_diff_tree__initialize(void)
+{
+	cl_git_pass(git_diff_init_options(&opts, GIT_DIFF_OPTIONS_VERSION));
+
+	memset(&expect, 0, sizeof(expect));
+
+	diff = NULL;
+	a = NULL;
+	b = NULL;
+}
+
+void test_diff_tree__cleanup(void)
+{
+	git_diff_free(diff);
+	git_tree_free(a);
+	git_tree_free(b);
+
+	cl_git_sandbox_cleanup();
+
+}
+
+void test_diff_tree__0(void)
+{
+	/* grabbed a couple of commit oids from the history of the attr repo */
+	const char *a_commit = "605812a";
+	const char *b_commit = "370fe9ec22";
+	const char *c_commit = "f5b0af1fb4f5c";
+	git_tree *c;
+
+	g_repo = cl_git_sandbox_init("attr");
+
+	cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
+	cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);
+	cl_assert((c = resolve_commit_oid_to_tree(g_repo, c_commit)) != NULL);
+
+	opts.context_lines = 1;
+	opts.interhunk_lines = 1;
+
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts));
+
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect));
+
+	cl_assert_equal_i(5, expect.files);
+	cl_assert_equal_i(2, expect.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, expect.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(2, expect.file_status[GIT_DELTA_MODIFIED]);
+
+	cl_assert_equal_i(5, expect.hunks);
+
+	cl_assert_equal_i(7 + 24 + 1 + 6 + 6, expect.lines);
+	cl_assert_equal_i(1, expect.line_ctxt);
+	cl_assert_equal_i(24 + 1 + 5 + 5, expect.line_adds);
+	cl_assert_equal_i(7 + 1, expect.line_dels);
+
+	git_diff_free(diff);
+	diff = NULL;
+
+	memset(&expect, 0, sizeof(expect));
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, c, b, &opts));
+
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect));
+
+	cl_assert_equal_i(2, expect.files);
+	cl_assert_equal_i(0, expect.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(0, expect.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(2, expect.file_status[GIT_DELTA_MODIFIED]);
+
+	cl_assert_equal_i(2, expect.hunks);
+
+	cl_assert_equal_i(8 + 15, expect.lines);
+	cl_assert_equal_i(1, expect.line_ctxt);
+	cl_assert_equal_i(1, expect.line_adds);
+	cl_assert_equal_i(7 + 14, expect.line_dels);
+
+	git_tree_free(c);
+}
+
+#define DIFF_OPTS(FLAGS, CTXT) \
+	{GIT_DIFF_OPTIONS_VERSION, (FLAGS), GIT_SUBMODULE_IGNORE_UNSPECIFIED, \
+	{NULL,0}, NULL, NULL, (CTXT), 1}
+
+void test_diff_tree__options(void)
+{
+	/* grabbed a couple of commit oids from the history of the attr repo */
+	const char *a_commit = "6bab5c79cd5140d0";
+	const char *b_commit = "605812ab7fe421fdd";
+	const char *c_commit = "f5b0af1fb4f5";
+	const char *d_commit = "a97cc019851";
+	git_tree *c, *d;
+	diff_expects actual;
+	int test_ab_or_cd[] = { 0, 0, 0, 0, 1, 1, 1, 1, 1 };
+	git_diff_options test_options[] = {
+		/* a vs b tests */
+		DIFF_OPTS(GIT_DIFF_NORMAL, 1),
+		DIFF_OPTS(GIT_DIFF_NORMAL, 3),
+		DIFF_OPTS(GIT_DIFF_REVERSE, 2),
+		DIFF_OPTS(GIT_DIFF_FORCE_TEXT, 2),
+		/* c vs d tests */
+		DIFF_OPTS(GIT_DIFF_NORMAL, 3),
+		DIFF_OPTS(GIT_DIFF_IGNORE_WHITESPACE, 3),
+		DIFF_OPTS(GIT_DIFF_IGNORE_WHITESPACE_CHANGE, 3),
+		DIFF_OPTS(GIT_DIFF_IGNORE_WHITESPACE_EOL, 3),
+		DIFF_OPTS(GIT_DIFF_IGNORE_WHITESPACE | GIT_DIFF_REVERSE, 1),
+	};
+
+	/* to generate these values:
+	 * - cd to tests/resources/attr,
+	 * - mv .gitted .git
+	 * - git diff [options] 6bab5c79cd5140d0 605812ab7fe421fdd
+	 * - mv .git .gitted
+	 */
+#define EXPECT_STATUS_ADM(ADDS,DELS,MODS) { 0, ADDS, DELS, MODS, 0, 0, 0, 0, 0 }
+
+	diff_expects test_expects[] = {
+		/* a vs b tests */
+		{ 5, 0, EXPECT_STATUS_ADM(3, 0, 2), 4, 0, 0, 51, 2, 46, 3 },
+		{ 5, 0, EXPECT_STATUS_ADM(3, 0, 2), 4, 0, 0, 53, 4, 46, 3 },
+		{ 5, 0, EXPECT_STATUS_ADM(0, 3, 2), 4, 0, 0, 52, 3, 3, 46 },
+		{ 5, 0, EXPECT_STATUS_ADM(3, 0, 2), 5, 0, 0, 54, 3, 47, 4 },
+		/* c vs d tests */
+		{ 1, 0, EXPECT_STATUS_ADM(0, 0, 1), 1, 0, 0, 22, 9, 10, 3 },
+		{ 1, 0, EXPECT_STATUS_ADM(0, 0, 1), 1, 0, 0, 19, 12, 7, 0 },
+		{ 1, 0, EXPECT_STATUS_ADM(0, 0, 1), 1, 0, 0, 20, 11, 8, 1 },
+		{ 1, 0, EXPECT_STATUS_ADM(0, 0, 1), 1, 0, 0, 20, 11, 8, 1 },
+		{ 1, 0, EXPECT_STATUS_ADM(0, 0, 1), 1, 0, 0, 18, 11, 0, 7 },
+		{ 0 },
+	};
+	diff_expects *expected;
+	int i, j;
+
+	g_repo = cl_git_sandbox_init("attr");
+
+	cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
+	cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);
+	cl_assert((c = resolve_commit_oid_to_tree(g_repo, c_commit)) != NULL);
+	cl_assert((d = resolve_commit_oid_to_tree(g_repo, d_commit)) != NULL);
+
+	for (i = 0; test_expects[i].files > 0; i++) {
+		memset(&actual, 0, sizeof(actual)); /* clear accumulator */
+		opts = test_options[i];
+
+		if (test_ab_or_cd[i] == 0)
+			cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts));
+		else
+			cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, c, d, &opts));
+
+		cl_git_pass(git_diff_foreach(
+			diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &actual));
+
+		expected = &test_expects[i];
+		cl_assert_equal_i(actual.files,     expected->files);
+		for (j = GIT_DELTA_UNMODIFIED; j <= GIT_DELTA_TYPECHANGE; ++j)
+			cl_assert_equal_i(expected->file_status[j], actual.file_status[j]);
+		cl_assert_equal_i(actual.hunks,     expected->hunks);
+		cl_assert_equal_i(actual.lines,     expected->lines);
+		cl_assert_equal_i(actual.line_ctxt, expected->line_ctxt);
+		cl_assert_equal_i(actual.line_adds, expected->line_adds);
+		cl_assert_equal_i(actual.line_dels, expected->line_dels);
+
+		git_diff_free(diff);
+		diff = NULL;
+	}
+
+	git_tree_free(c);
+	git_tree_free(d);
+}
+
+void test_diff_tree__bare(void)
+{
+	const char *a_commit = "8496071c1b46c85";
+	const char *b_commit = "be3563ae3f79";
+
+	g_repo = cl_git_sandbox_init("testrepo.git");
+
+	cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
+	cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);
+
+	opts.context_lines = 1;
+	opts.interhunk_lines = 1;
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts));
+
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect));
+
+	cl_assert_equal_i(3, expect.files);
+	cl_assert_equal_i(2, expect.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(0, expect.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, expect.file_status[GIT_DELTA_MODIFIED]);
+
+	cl_assert_equal_i(3, expect.hunks);
+
+	cl_assert_equal_i(4, expect.lines);
+	cl_assert_equal_i(0, expect.line_ctxt);
+	cl_assert_equal_i(3, expect.line_adds);
+	cl_assert_equal_i(1, expect.line_dels);
+}
+
+void test_diff_tree__merge(void)
+{
+	/* grabbed a couple of commit oids from the history of the attr repo */
+	const char *a_commit = "605812a";
+	const char *b_commit = "370fe9ec22";
+	const char *c_commit = "f5b0af1fb4f5c";
+	git_tree *c;
+	git_diff *diff1 = NULL, *diff2 = NULL;
+
+	g_repo = cl_git_sandbox_init("attr");
+
+	cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
+	cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);
+	cl_assert((c = resolve_commit_oid_to_tree(g_repo, c_commit)) != NULL);
+
+	cl_git_pass(git_diff_tree_to_tree(&diff1, g_repo, a, b, NULL));
+
+	cl_git_pass(git_diff_tree_to_tree(&diff2, g_repo, c, b, NULL));
+
+	git_tree_free(c);
+
+	cl_git_pass(git_diff_merge(diff1, diff2));
+
+	git_diff_free(diff2);
+
+	cl_git_pass(git_diff_foreach(
+		diff1, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect));
+
+	cl_assert_equal_i(6, expect.files);
+	cl_assert_equal_i(2, expect.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, expect.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(3, expect.file_status[GIT_DELTA_MODIFIED]);
+
+	cl_assert_equal_i(6, expect.hunks);
+
+	cl_assert_equal_i(59, expect.lines);
+	cl_assert_equal_i(1, expect.line_ctxt);
+	cl_assert_equal_i(36, expect.line_adds);
+	cl_assert_equal_i(22, expect.line_dels);
+
+	git_diff_free(diff1);
+}
+
+void test_diff_tree__larger_hunks(void)
+{
+	const char *a_commit = "d70d245ed97ed2aa596dd1af6536e4bfdb047b69";
+	const char *b_commit = "7a9e0b02e63179929fed24f0a3e0f19168114d10";
+	size_t d, num_d, h, num_h, l, num_l;
+	git_patch *patch;
+	const git_diff_hunk *hunk;
+	const git_diff_line *line;
+
+	g_repo = cl_git_sandbox_init("diff");
+
+	cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
+	cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);
+
+	opts.context_lines = 1;
+	opts.interhunk_lines = 0;
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts));
+
+	num_d = git_diff_num_deltas(diff);
+	for (d = 0; d < num_d; ++d) {
+		cl_git_pass(git_patch_from_diff(&patch, diff, d));
+		cl_assert(patch);
+
+		num_h = git_patch_num_hunks(patch);
+		for (h = 0; h < num_h; h++) {
+			cl_git_pass(git_patch_get_hunk(&hunk, &num_l, patch, h));
+
+			for (l = 0; l < num_l; ++l) {
+				cl_git_pass(git_patch_get_line_in_hunk(&line, patch, h, l));
+				cl_assert(line);
+			}
+
+			cl_git_fail(git_patch_get_line_in_hunk(&line, patch, h, num_l));
+		}
+
+		cl_git_fail(git_patch_get_hunk(&hunk, &num_l, patch, num_h));
+
+		git_patch_free(patch);
+	}
+
+	cl_git_fail(git_patch_from_diff(&patch, diff, num_d));
+
+	cl_assert_equal_i(2, (int)num_d);
+}
+
+void test_diff_tree__checks_options_version(void)
+{
+	const char *a_commit = "8496071c1b46c85";
+	const char *b_commit = "be3563ae3f79";
+	const git_error *err;
+
+	g_repo = cl_git_sandbox_init("testrepo.git");
+
+	cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
+	cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);
+
+	opts.version = 0;
+	cl_git_fail(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts));
+	err = giterr_last();
+	cl_assert_equal_i(GITERR_INVALID, err->klass);
+
+	giterr_clear();
+	opts.version = 1024;
+	cl_git_fail(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts));
+	err = giterr_last();
+}
+
+void process_tree_to_tree_diffing(
+	const char *old_commit,
+	const char *new_commit)
+{
+	g_repo = cl_git_sandbox_init("unsymlinked.git");
+
+	cl_assert((a = resolve_commit_oid_to_tree(g_repo, old_commit)) != NULL);
+	cl_assert((b = resolve_commit_oid_to_tree(g_repo, new_commit)) != NULL);
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts));
+
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, NULL, NULL, NULL, &expect));
+}
+
+void test_diff_tree__symlink_blob_mode_changed_to_regular_file(void)
+{
+	/*
+	* $ git diff  7fccd7..806999
+	* diff --git a/include/Nu/Nu.h b/include/Nu/Nu.h
+	* deleted file mode 120000
+	* index 19bf568..0000000
+	* --- a/include/Nu/Nu.h
+	* +++ /dev/null
+	* @@ -1 +0,0 @@
+	* -../../objc/Nu.h
+	* \ No newline at end of file
+	* diff --git a/include/Nu/Nu.h b/include/Nu/Nu.h
+	* new file mode 100644
+	* index 0000000..f9e6561
+	* --- /dev/null
+	* +++ b/include/Nu/Nu.h
+	* @@ -0,0 +1 @@
+	* +awesome content
+	* diff --git a/objc/Nu.h b/objc/Nu.h
+	* deleted file mode 100644
+	* index f9e6561..0000000
+	* --- a/objc/Nu.h
+	* +++ /dev/null
+	* @@ -1 +0,0 @@
+	* -awesome content
+	*/
+
+	process_tree_to_tree_diffing("7fccd7", "806999");
+
+	cl_assert_equal_i(3, expect.files);
+	cl_assert_equal_i(2, expect.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(0, expect.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, expect.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(0, expect.file_status[GIT_DELTA_TYPECHANGE]);
+}
+
+void test_diff_tree__symlink_blob_mode_changed_to_regular_file_as_typechange(void)
+{
+	/*
+	 * $ git diff  7fccd7..a8595c
+	 * diff --git a/include/Nu/Nu.h b/include/Nu/Nu.h
+	 * deleted file mode 120000
+	 * index 19bf568..0000000
+	 * --- a/include/Nu/Nu.h
+	 * +++ /dev/null
+	 * @@ -1 +0,0 @@
+	 * -../../objc/Nu.h
+	 * \ No newline at end of file
+	 * diff --git a/include/Nu/Nu.h b/include/Nu/Nu.h
+	 * new file mode 100755
+	 * index 0000000..f9e6561
+	 * --- /dev/null
+	 * +++ b/include/Nu/Nu.h
+	 * @@ -0,0 +1 @@
+	 * +awesome content
+	 * diff --git a/objc/Nu.h b/objc/Nu.h
+	 * deleted file mode 100644
+	 * index f9e6561..0000000
+	 * --- a/objc/Nu.h
+	 * +++ /dev/null
+	 * @@ -1 +0,0 @@
+	 * -awesome content
+	*/
+
+	opts.flags = GIT_DIFF_INCLUDE_TYPECHANGE;
+	process_tree_to_tree_diffing("7fccd7", "a8595c");
+
+	cl_assert_equal_i(2, expect.files);
+	cl_assert_equal_i(1, expect.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(0, expect.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(0, expect.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, expect.file_status[GIT_DELTA_TYPECHANGE]);
+}
+
+void test_diff_tree__regular_blob_mode_changed_to_executable_file(void)
+{
+	/*
+	 * $ git diff 806999..a8595c
+	 * diff --git a/include/Nu/Nu.h b/include/Nu/Nu.h
+	 * old mode 100644
+	 * new mode 100755
+	 */
+
+	process_tree_to_tree_diffing("806999", "a8595c");
+
+	cl_assert_equal_i(1, expect.files);
+	cl_assert_equal_i(0, expect.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, expect.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(0, expect.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(0, expect.file_status[GIT_DELTA_TYPECHANGE]);
+}
+
+void test_diff_tree__issue_1397(void)
+{
+	/* this test shows that it is not needed */
+
+	g_repo = cl_git_sandbox_init("issue_1397");
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	cl_assert((a = resolve_commit_oid_to_tree(g_repo, "8a7ef04")) != NULL);
+	cl_assert((b = resolve_commit_oid_to_tree(g_repo, "7f483a7")) != NULL);
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts));
+
+	cl_git_pass(git_diff_foreach(diff,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect));
+
+	cl_assert_equal_i(1, expect.files);
+	cl_assert_equal_i(0, expect.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, expect.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(0, expect.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(0, expect.file_status[GIT_DELTA_TYPECHANGE]);
+}
+
+static void set_config_int(git_repository *repo, const char *name, int value)
+{
+	git_config *cfg;
+
+	cl_git_pass(git_repository_config(&cfg, repo));
+	cl_git_pass(git_config_set_int32(cfg, name, value));
+	git_config_free(cfg);
+}
+
+void test_diff_tree__diff_configs(void)
+{
+	const char *a_commit = "d70d245e";
+	const char *b_commit = "7a9e0b02";
+
+	g_repo = cl_git_sandbox_init("diff");
+
+	cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
+	cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, NULL));
+
+	cl_git_pass(git_diff_foreach(diff, 
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect));
+
+	cl_assert_equal_i(2, expect.files);
+	cl_assert_equal_i(2, expect.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(6, expect.hunks);
+	cl_assert_equal_i(55, expect.lines);
+	cl_assert_equal_i(33, expect.line_ctxt);
+	cl_assert_equal_i(7, expect.line_adds);
+	cl_assert_equal_i(15, expect.line_dels);
+
+	git_diff_free(diff);
+	diff = NULL;
+
+	set_config_int(g_repo, "diff.context", 1);
+
+	memset(&expect, 0, sizeof(expect));
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, NULL));
+
+	cl_git_pass(git_diff_foreach(diff,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect));
+
+	cl_assert_equal_i(2, expect.files);
+	cl_assert_equal_i(2, expect.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(7, expect.hunks);
+	cl_assert_equal_i(34, expect.lines);
+	cl_assert_equal_i(12, expect.line_ctxt);
+	cl_assert_equal_i(7, expect.line_adds);
+	cl_assert_equal_i(15, expect.line_dels);
+
+	git_diff_free(diff);
+	diff = NULL;
+
+	set_config_int(g_repo, "diff.context", 0);
+	set_config_int(g_repo, "diff.noprefix", 1);
+
+	memset(&expect, 0, sizeof(expect));
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, NULL));
+
+	cl_git_pass(git_diff_foreach(diff,
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect));
+
+	cl_assert_equal_i(2, expect.files);
+	cl_assert_equal_i(2, expect.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(7, expect.hunks);
+	cl_assert_equal_i(22, expect.lines);
+	cl_assert_equal_i(0, expect.line_ctxt);
+	cl_assert_equal_i(7, expect.line_adds);
+	cl_assert_equal_i(15, expect.line_dels);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/workdir.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/workdir.c
new file mode 100755
index 0000000..8a23f53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/diff/workdir.c
@@ -0,0 +1,1846 @@
+#include "clar_libgit2.h"
+#include "diff_helpers.h"
+#include "repository.h"
+#include "git2/sys/diff.h"
+#include "../checkout/checkout_helpers.h"
+
+static git_repository *g_repo = NULL;
+
+void test_diff_workdir__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_diff_workdir__to_index(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	diff_expects exp;
+	int use_iterator;
+
+	g_repo = cl_git_sandbox_init("status");
+
+	opts.context_lines = 3;
+	opts.interhunk_lines = 1;
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+		else
+			cl_git_pass(git_diff_foreach(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+		/* to generate these values:
+		 * - cd to tests/resources/status,
+		 * - mv .gitted .git
+		 * - git diff --name-status
+		 * - git diff
+		 * - mv .git .gitted
+		 */
+		cl_assert_equal_i(13, exp.files);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+		cl_assert_equal_i(4, exp.file_status[GIT_DELTA_DELETED]);
+		cl_assert_equal_i(4, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
+		cl_assert_equal_i(4, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+		cl_assert_equal_i(8, exp.hunks);
+
+		cl_assert_equal_i(14, exp.lines);
+		cl_assert_equal_i(5, exp.line_ctxt);
+		cl_assert_equal_i(4, exp.line_adds);
+		cl_assert_equal_i(5, exp.line_dels);
+	}
+
+	{
+		git_diff_perfdata perf = GIT_DIFF_PERFDATA_INIT;
+		cl_git_pass(git_diff_get_perfdata(&perf, diff));
+		cl_assert_equal_sz(
+			13 /* in root */ + 3 /* in subdir */, perf.stat_calls);
+		cl_assert_equal_sz(5, perf.oid_calculations);
+	}
+
+	git_diff_free(diff);
+}
+
+void test_diff_workdir__to_index_with_conflicts(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	git_index *index;
+	git_index_entry our_entry = {{0}}, their_entry = {{0}};
+	diff_expects exp = {0};
+
+	g_repo = cl_git_sandbox_init("status");
+
+	opts.context_lines = 3;
+	opts.interhunk_lines = 1;
+
+	/* Adding an entry that represents a rename gets two files in conflict */
+	our_entry.path = "subdir/modified_file";
+	our_entry.mode = 0100644;
+
+	their_entry.path = "subdir/rename_conflict";
+	their_entry.mode = 0100644;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_conflict_add(index, NULL, &our_entry, &their_entry));
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, &opts));
+
+	cl_git_pass(diff_foreach_via_iterator(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(9, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(4, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_CONFLICTED]);
+
+	cl_assert_equal_i(7, exp.hunks);
+
+	cl_assert_equal_i(12, exp.lines);
+	cl_assert_equal_i(4, exp.line_ctxt);
+	cl_assert_equal_i(3, exp.line_adds);
+	cl_assert_equal_i(5, exp.line_dels);
+
+	git_diff_free(diff);
+	git_index_free(index);
+}
+
+void test_diff_workdir__to_index_with_assume_unchanged(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	git_index *idx = NULL;
+	diff_expects exp;
+	const git_index_entry *iep;
+	git_index_entry ie;
+
+	g_repo = cl_git_sandbox_init("status");
+
+	/* do initial diff */
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(8, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(4, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(4, exp.file_status[GIT_DELTA_MODIFIED]);
+	git_diff_free(diff);
+
+	/* mark a couple of entries with ASSUME_UNCHANGED */
+
+	cl_git_pass(git_repository_index(&idx, g_repo));
+
+	cl_assert((iep = git_index_get_bypath(idx, "modified_file", 0)) != NULL);
+	memcpy(&ie, iep, sizeof(ie));
+	ie.flags |= GIT_IDXENTRY_VALID;
+	cl_git_pass(git_index_add(idx, &ie));
+
+	cl_assert((iep = git_index_get_bypath(idx, "file_deleted", 0)) != NULL);
+	memcpy(&ie, iep, sizeof(ie));
+	ie.flags |= GIT_IDXENTRY_VALID;
+	cl_git_pass(git_index_add(idx, &ie));
+
+	cl_git_pass(git_index_write(idx));
+	git_index_free(idx);
+
+	/* redo diff and see that entries are skipped */
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+	cl_assert_equal_i(6, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]);
+	git_diff_free(diff);
+
+}
+
+void test_diff_workdir__to_tree(void)
+{
+	/* grabbed a couple of commit oids from the history of the attr repo */
+	const char *a_commit = "26a125ee1bf"; /* the current HEAD */
+	const char *b_commit = "0017bd4ab1ec3"; /* the start */
+	git_tree *a, *b;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	git_diff *diff2 = NULL;
+	diff_expects exp;
+	int use_iterator;
+
+	g_repo = cl_git_sandbox_init("status");
+
+	a = resolve_commit_oid_to_tree(g_repo, a_commit);
+	b = resolve_commit_oid_to_tree(g_repo, b_commit);
+
+	opts.context_lines = 3;
+	opts.interhunk_lines = 1;
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+
+	/* You can't really generate the equivalent of git_diff_tree_to_workdir()
+	 * using C git.  It really wants to interpose the index into the diff.
+	 *
+	 * To validate the following results with command line git, I ran the
+	 * following:
+	 * - git ls-tree 26a125
+	 * - find . ! -path ./.git/\* -a -type f | git hash-object --stdin-paths
+	 * The results are documented at the bottom of this file in the
+	 * long comment entitled "PREPARATION OF TEST DATA".
+	 */
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, a, &opts));
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+		else
+			cl_git_pass(git_diff_foreach(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+		cl_assert_equal_i(14, exp.files);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+		cl_assert_equal_i(4, exp.file_status[GIT_DELTA_DELETED]);
+		cl_assert_equal_i(4, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
+		cl_assert_equal_i(5, exp.file_status[GIT_DELTA_UNTRACKED]);
+	}
+
+	/* Since there is no git diff equivalent, let's just assume that the
+	 * text diffs produced by git_diff_foreach are accurate here.  We will
+	 * do more apples-to-apples test comparison below.
+	 */
+
+	git_diff_free(diff);
+	diff = NULL;
+	memset(&exp, 0, sizeof(exp));
+
+	/* This is a compatible emulation of "git diff <sha>" which looks like
+	 * a workdir to tree diff (even though it is not really).  This is what
+	 * you would get from "git diff --name-status 26a125ee1bf"
+	 */
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, NULL, &opts));
+	cl_git_pass(git_diff_index_to_workdir(&diff2, g_repo, NULL, &opts));
+	cl_git_pass(git_diff_merge(diff, diff2));
+	git_diff_free(diff2);
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+		else
+			cl_git_pass(git_diff_foreach(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+		cl_assert_equal_i(15, exp.files);
+		cl_assert_equal_i(2, exp.file_status[GIT_DELTA_ADDED]);
+		cl_assert_equal_i(5, exp.file_status[GIT_DELTA_DELETED]);
+		cl_assert_equal_i(4, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
+		cl_assert_equal_i(3, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+		cl_assert_equal_i(11, exp.hunks);
+
+		cl_assert_equal_i(17, exp.lines);
+		cl_assert_equal_i(4, exp.line_ctxt);
+		cl_assert_equal_i(8, exp.line_adds);
+		cl_assert_equal_i(5, exp.line_dels);
+	}
+
+	git_diff_free(diff);
+	diff = NULL;
+	memset(&exp, 0, sizeof(exp));
+
+	/* Again, emulating "git diff <sha>" for testing purposes using
+	 * "git diff --name-status 0017bd4ab1ec3" instead.
+	 */
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, b, NULL, &opts));
+	cl_git_pass(git_diff_index_to_workdir(&diff2, g_repo, NULL, &opts));
+	cl_git_pass(git_diff_merge(diff, diff2));
+	git_diff_free(diff2);
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+		else
+			cl_git_pass(git_diff_foreach(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+		cl_assert_equal_i(16, exp.files);
+		cl_assert_equal_i(5, exp.file_status[GIT_DELTA_ADDED]);
+		cl_assert_equal_i(4, exp.file_status[GIT_DELTA_DELETED]);
+		cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
+		cl_assert_equal_i(3, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+		cl_assert_equal_i(12, exp.hunks);
+
+		cl_assert_equal_i(19, exp.lines);
+		cl_assert_equal_i(3, exp.line_ctxt);
+		cl_assert_equal_i(12, exp.line_adds);
+		cl_assert_equal_i(4, exp.line_dels);
+	}
+
+	git_diff_free(diff);
+
+	/* Let's try that once more with a reversed diff */
+
+	opts.flags |= GIT_DIFF_REVERSE;
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, b, NULL, &opts));
+	cl_git_pass(git_diff_index_to_workdir(&diff2, g_repo, NULL, &opts));
+	cl_git_pass(git_diff_merge(diff, diff2));
+	git_diff_free(diff2);
+
+	memset(&exp, 0, sizeof(exp));
+
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(16, exp.files);
+	cl_assert_equal_i(5, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(4, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	cl_assert_equal_i(12, exp.hunks);
+
+	cl_assert_equal_i(19, exp.lines);
+	cl_assert_equal_i(3, exp.line_ctxt);
+	cl_assert_equal_i(12, exp.line_dels);
+	cl_assert_equal_i(4, exp.line_adds);
+
+	git_diff_free(diff);
+
+	/* all done now */
+
+	git_tree_free(a);
+	git_tree_free(b);
+}
+
+void test_diff_workdir__to_index_with_pathspec(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	diff_expects exp;
+	char *pathspec = NULL;
+	int use_iterator;
+
+	g_repo = cl_git_sandbox_init("status");
+
+	opts.context_lines = 3;
+	opts.interhunk_lines = 1;
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+	opts.pathspec.strings = &pathspec;
+	opts.pathspec.count   = 1;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff, diff_file_cb, NULL, NULL, NULL, &exp));
+		else
+			cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
+
+		cl_assert_equal_i(13, exp.files);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+		cl_assert_equal_i(4, exp.file_status[GIT_DELTA_DELETED]);
+		cl_assert_equal_i(4, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
+		cl_assert_equal_i(4, exp.file_status[GIT_DELTA_UNTRACKED]);
+	}
+
+	git_diff_free(diff);
+
+	pathspec = "modified_file";
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff, diff_file_cb, NULL, NULL, NULL, &exp));
+		else
+			cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
+
+		cl_assert_equal_i(1, exp.files);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_DELETED]);
+		cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_IGNORED]);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_UNTRACKED]);
+	}
+
+	git_diff_free(diff);
+
+	pathspec = "subdir";
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff, diff_file_cb, NULL, NULL, NULL, &exp));
+		else
+			cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
+
+		cl_assert_equal_i(3, exp.files);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+		cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+		cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_IGNORED]);
+		cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNTRACKED]);
+	}
+
+	git_diff_free(diff);
+
+	pathspec = "*_deleted";
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff, diff_file_cb, NULL, NULL, NULL, &exp));
+		else
+			cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
+
+		cl_assert_equal_i(2, exp.files);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+		cl_assert_equal_i(2, exp.file_status[GIT_DELTA_DELETED]);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_IGNORED]);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_UNTRACKED]);
+	}
+
+	git_diff_free(diff);
+}
+
+void test_diff_workdir__filemode_changes(void)
+{
+	git_diff *diff = NULL;
+	diff_expects exp;
+	int use_iterator;
+
+	if (!cl_is_chmod_supported())
+		return;
+
+	g_repo = cl_git_sandbox_init("issue_592");
+
+	cl_repo_set_bool(g_repo, "core.filemode", true);
+
+	/* test once with no mods */
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, NULL));
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+		else
+			cl_git_pass(git_diff_foreach(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+		cl_assert_equal_i(0, exp.files);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(0, exp.hunks);
+	}
+
+	git_diff_free(diff);
+
+	/* chmod file and test again */
+
+	cl_assert(cl_toggle_filemode("issue_592/a.txt"));
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, NULL));
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+		else
+			cl_git_pass(git_diff_foreach(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+		cl_assert_equal_i(1, exp.files);
+		cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(0, exp.hunks);
+	}
+
+	git_diff_free(diff);
+
+	cl_assert(cl_toggle_filemode("issue_592/a.txt"));
+}
+
+void test_diff_workdir__filemode_changes_with_filemode_false(void)
+{
+	git_diff *diff = NULL;
+	diff_expects exp;
+
+	if (!cl_is_chmod_supported())
+		return;
+
+	g_repo = cl_git_sandbox_init("issue_592");
+
+	cl_repo_set_bool(g_repo, "core.filemode", false);
+
+	/* test once with no mods */
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, NULL));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(0, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(0, exp.hunks);
+
+	git_diff_free(diff);
+
+	/* chmod file and test again */
+
+	cl_assert(cl_toggle_filemode("issue_592/a.txt"));
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, NULL));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(diff, 
+		diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(0, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(0, exp.hunks);
+
+	git_diff_free(diff);
+
+	cl_assert(cl_toggle_filemode("issue_592/a.txt"));
+}
+
+void test_diff_workdir__head_index_and_workdir_all_differ(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff_i2t = NULL, *diff_w2i = NULL;
+	diff_expects exp;
+	char *pathspec = "staged_changes_modified_file";
+	git_tree *tree;
+	int use_iterator;
+
+	/* For this file,
+	 * - head->index diff has 1 line of context, 1 line of diff
+	 * - index->workdir diff has 2 lines of context, 1 line of diff
+	 * but
+	 * - head->workdir diff has 1 line of context, 2 lines of diff
+	 * Let's make sure the right one is returned from each fn.
+	 */
+
+	g_repo = cl_git_sandbox_init("status");
+
+	tree = resolve_commit_oid_to_tree(g_repo, "26a125ee1bfc5df1e1b2e9441bbe63c8a7ae989f");
+
+	opts.pathspec.strings = &pathspec;
+	opts.pathspec.count   = 1;
+
+	cl_git_pass(git_diff_tree_to_index(&diff_i2t, g_repo, tree, NULL, &opts));
+	cl_git_pass(git_diff_index_to_workdir(&diff_w2i, g_repo, NULL, &opts));
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff_i2t, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+		else
+			cl_git_pass(git_diff_foreach(
+				diff_i2t, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+		cl_assert_equal_i(1, exp.files);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_DELETED]);
+		cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(1, exp.hunks);
+		cl_assert_equal_i(2, exp.lines);
+		cl_assert_equal_i(1, exp.line_ctxt);
+		cl_assert_equal_i(1, exp.line_adds);
+		cl_assert_equal_i(0, exp.line_dels);
+	}
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff_w2i, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+		else
+			cl_git_pass(git_diff_foreach(
+				diff_w2i, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+		cl_assert_equal_i(1, exp.files);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_DELETED]);
+		cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(1, exp.hunks);
+		cl_assert_equal_i(3, exp.lines);
+		cl_assert_equal_i(2, exp.line_ctxt);
+		cl_assert_equal_i(1, exp.line_adds);
+		cl_assert_equal_i(0, exp.line_dels);
+	}
+
+	cl_git_pass(git_diff_merge(diff_i2t, diff_w2i));
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff_i2t, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+		else
+			cl_git_pass(git_diff_foreach(
+				diff_i2t, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+		cl_assert_equal_i(1, exp.files);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_DELETED]);
+		cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(1, exp.hunks);
+		cl_assert_equal_i(3, exp.lines);
+		cl_assert_equal_i(1, exp.line_ctxt);
+		cl_assert_equal_i(2, exp.line_adds);
+		cl_assert_equal_i(0, exp.line_dels);
+	}
+
+	git_diff_free(diff_i2t);
+	git_diff_free(diff_w2i);
+
+	git_tree_free(tree);
+}
+
+void test_diff_workdir__eof_newline_changes(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	diff_expects exp;
+	char *pathspec = "current_file";
+	int use_iterator;
+
+	g_repo = cl_git_sandbox_init("status");
+
+	opts.pathspec.strings = &pathspec;
+	opts.pathspec.count   = 1;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+		else
+			cl_git_pass(git_diff_foreach(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+		cl_assert_equal_i(0, exp.files);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_DELETED]);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(0, exp.hunks);
+		cl_assert_equal_i(0, exp.lines);
+		cl_assert_equal_i(0, exp.line_ctxt);
+		cl_assert_equal_i(0, exp.line_adds);
+		cl_assert_equal_i(0, exp.line_dels);
+	}
+
+	git_diff_free(diff);
+
+	cl_git_append2file("status/current_file", "\n");
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+		else
+			cl_git_pass(git_diff_foreach(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+		cl_assert_equal_i(1, exp.files);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_DELETED]);
+		cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(1, exp.hunks);
+		cl_assert_equal_i(2, exp.lines);
+		cl_assert_equal_i(1, exp.line_ctxt);
+		cl_assert_equal_i(1, exp.line_adds);
+		cl_assert_equal_i(0, exp.line_dels);
+	}
+
+	git_diff_free(diff);
+
+	cl_git_rewritefile("status/current_file", "current_file");
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
+		memset(&exp, 0, sizeof(exp));
+
+		if (use_iterator)
+			cl_git_pass(diff_foreach_via_iterator(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+		else
+			cl_git_pass(git_diff_foreach(
+				diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+		cl_assert_equal_i(1, exp.files);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+		cl_assert_equal_i(0, exp.file_status[GIT_DELTA_DELETED]);
+		cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+		cl_assert_equal_i(1, exp.hunks);
+		cl_assert_equal_i(3, exp.lines);
+		cl_assert_equal_i(0, exp.line_ctxt);
+		cl_assert_equal_i(1, exp.line_adds);
+		cl_assert_equal_i(2, exp.line_dels);
+	}
+
+	git_diff_free(diff);
+}
+
+/* PREPARATION OF TEST DATA
+ *
+ * Since there is no command line equivalent of git_diff_tree_to_workdir,
+ * it was a bit of a pain to confirm that I was getting the expected
+ * results in the first part of this tests.  Here is what I ended up
+ * doing to set my expectation for the file counts and results:
+ *
+ * Running "git ls-tree 26a125" and "git ls-tree aa27a6" shows:
+ *
+ *  A a0de7e0ac200c489c41c59dfa910154a70264e6e	current_file
+ *  B 5452d32f1dd538eb0405e8a83cc185f79e25e80f	file_deleted
+ *  C 452e4244b5d083ddf0460acf1ecc74db9dcfa11a	modified_file
+ *  D 32504b727382542f9f089e24fddac5e78533e96c	staged_changes
+ *  E 061d42a44cacde5726057b67558821d95db96f19	staged_changes_file_deleted
+ *  F 70bd9443ada07063e7fbf0b3ff5c13f7494d89c2	staged_changes_modified_file
+ *  G e9b9107f290627c04d097733a10055af941f6bca	staged_delete_file_deleted
+ *  H dabc8af9bd6e9f5bbe96a176f1a24baf3d1f8916	staged_delete_modified_file
+ *  I 53ace0d1cc1145a5f4fe4f78a186a60263190733	subdir/current_file
+ *  J 1888c805345ba265b0ee9449b8877b6064592058	subdir/deleted_file
+ *  K a6191982709b746d5650e93c2acf34ef74e11504	subdir/modified_file
+ *  L e8ee89e15bbe9b20137715232387b3de5b28972e	subdir.txt
+ *
+ * --------
+ *
+ * find . ! -path ./.git/\* -a -type f | git hash-object --stdin-paths
+ *
+ *  A a0de7e0ac200c489c41c59dfa910154a70264e6e current_file
+ *  M 6a79f808a9c6bc9531ac726c184bbcd9351ccf11 ignored_file
+ *  C 0a539630525aca2e7bc84975958f92f10a64c9b6 modified_file
+ *  N d4fa8600b4f37d7516bef4816ae2c64dbf029e3a new_file
+ *  D 55d316c9ba708999f1918e9677d01dfcae69c6b9 staged_changes
+ *  F 011c3440d5c596e21d836aa6d7b10eb581f68c49 staged_changes_modified_file
+ *  H dabc8af9bd6e9f5bbe96a176f1a24baf3d1f8916 staged_delete_modified_file
+ *  O 529a16e8e762d4acb7b9636ff540a00831f9155a staged_new_file
+ *  P 8b090c06d14ffa09c4e880088ebad33893f921d1 staged_new_file_modified_file
+ *  I 53ace0d1cc1145a5f4fe4f78a186a60263190733 subdir/current_file
+ *  K 57274b75eeb5f36fd55527806d567b2240a20c57 subdir/modified_file
+ *  Q 80a86a6931b91bc01c2dbf5ca55bdd24ad1ef466 subdir/new_file
+ *  L e8ee89e15bbe9b20137715232387b3de5b28972e subdir.txt
+ *
+ * --------
+ *
+ *  A - current_file (UNMODIFIED) -> not in results
+ *  B D file_deleted
+ *  M I ignored_file (IGNORED)
+ *  C M modified_file
+ *  N U new_file (UNTRACKED)
+ *  D M staged_changes
+ *  E D staged_changes_file_deleted
+ *  F M staged_changes_modified_file
+ *  G D staged_delete_file_deleted
+ *  H - staged_delete_modified_file (UNMODIFIED) -> not in results
+ *  O U staged_new_file
+ *  P U staged_new_file_modified_file
+ *  I - subdir/current_file (UNMODIFIED) -> not in results
+ *  J D subdir/deleted_file
+ *  K M subdir/modified_file
+ *  Q U subdir/new_file
+ *  L - subdir.txt (UNMODIFIED) -> not in results
+ *
+ * Expect 13 files, 0 ADD, 4 DEL, 4 MOD, 1 IGN, 4 UNTR
+ */
+
+
+void test_diff_workdir__larger_hunks(void)
+{
+	const char *a_commit = "d70d245ed97ed2aa596dd1af6536e4bfdb047b69";
+	const char *b_commit = "7a9e0b02e63179929fed24f0a3e0f19168114d10";
+	git_tree *a, *b;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	size_t i, d, num_d, h, num_h, l, num_l;
+
+	g_repo = cl_git_sandbox_init("diff");
+
+	cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
+	cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);
+
+	opts.context_lines = 1;
+	opts.interhunk_lines = 0;
+
+	for (i = 0; i <= 2; ++i) {
+		git_diff *diff = NULL;
+		git_patch *patch;
+		const git_diff_hunk *hunk;
+		const git_diff_line *line;
+
+		/* okay, this is a bit silly, but oh well */
+		switch (i) {
+		case 0:
+			cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+			break;
+		case 1:
+			cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, a, &opts));
+			break;
+		case 2:
+			cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, b, &opts));
+			break;
+		}
+
+		num_d = git_diff_num_deltas(diff);
+		cl_assert_equal_i(2, (int)num_d);
+
+		for (d = 0; d < num_d; ++d) {
+			cl_git_pass(git_patch_from_diff(&patch, diff, d));
+			cl_assert(patch);
+
+			num_h = git_patch_num_hunks(patch);
+			for (h = 0; h < num_h; h++) {
+				cl_git_pass(git_patch_get_hunk(&hunk, &num_l, patch, h));
+
+				for (l = 0; l < num_l; ++l) {
+					cl_git_pass(
+						git_patch_get_line_in_hunk(&line, patch, h, l));
+					cl_assert(line);
+				}
+
+				/* confirm fail after the last item */
+				cl_git_fail(
+					git_patch_get_line_in_hunk(&line, patch, h, num_l));
+			}
+
+			/* confirm fail after the last item */
+			cl_git_fail(git_patch_get_hunk(&hunk, &num_l, patch, num_h));
+
+			git_patch_free(patch);
+		}
+
+		git_diff_free(diff);
+	}
+
+	git_tree_free(a);
+	git_tree_free(b);
+}
+
+/* Set up a test that exercises this code. The easiest test using existing
+ * test data is probably to create a sandbox of submod2 and then run a
+ * git_diff_tree_to_workdir against tree
+ * 873585b94bdeabccea991ea5e3ec1a277895b698. As for what you should actually
+ * test, you can start by just checking that the number of lines of diff
+ * content matches the actual output of git diff. That will at least
+ * demonstrate that the submodule content is being used to generate somewhat
+ * comparable outputs. It is a test that would fail without this code and
+ * will succeed with it.
+ */
+
+#include "../submodule/submodule_helpers.h"
+
+void test_diff_workdir__submodules(void)
+{
+	const char *a_commit = "873585b94bdeabccea991ea5e3ec1a277895b698";
+	git_tree *a;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	diff_expects exp;
+
+	g_repo = setup_fixture_submod2();
+
+	a = resolve_commit_oid_to_tree(g_repo, a_commit);
+
+	opts.flags =
+		GIT_DIFF_INCLUDE_UNTRACKED |
+		GIT_DIFF_INCLUDE_IGNORED |
+		GIT_DIFF_RECURSE_UNTRACKED_DIRS |
+		GIT_DIFF_SHOW_UNTRACKED_CONTENT;
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, a, &opts));
+
+	/* diff_print(stderr, diff); */
+
+	/* essentially doing: git diff 873585b94bdeabccea991ea5e3ec1a277895b698 */
+
+	memset(&exp, 0, sizeof(exp));
+
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	/* so "git diff 873585" returns:
+	 *  M   .gitmodules
+	 *  A   just_a_dir/contents
+	 *  A   just_a_file
+	 *  A   sm_added_and_uncommited
+	 *  A   sm_changed_file
+	 *  A   sm_changed_head
+	 *  A   sm_changed_index
+	 *  A   sm_changed_untracked_file
+	 *  M   sm_missing_commits
+	 *  A   sm_unchanged
+	 * which is a little deceptive because of the difference between the
+	 * "git diff <treeish>" results from "git_diff_tree_to_workdir".  The
+	 * only significant difference is that those Added items will show up
+	 * as Untracked items in the pure libgit2 diff.
+	 *
+	 * Then add in the two extra untracked items "not" and "not-submodule"
+	 * to get the 12 files reported here.
+	 */
+
+	cl_assert_equal_i(12, exp.files);
+
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_IGNORED]);
+	cl_assert_equal_i(10, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	/* the following numbers match "git diff 873585" exactly */
+
+	cl_assert_equal_i(9, exp.hunks);
+
+	cl_assert_equal_i(33, exp.lines);
+	cl_assert_equal_i(2, exp.line_ctxt);
+	cl_assert_equal_i(30, exp.line_adds);
+	cl_assert_equal_i(1, exp.line_dels);
+
+	git_diff_free(diff);
+	git_tree_free(a);
+}
+
+void test_diff_workdir__cannot_diff_against_a_bare_repository(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	git_tree *tree;
+
+	g_repo = cl_git_sandbox_init("testrepo.git");
+
+	cl_assert_equal_i(
+		GIT_EBAREREPO, git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	cl_git_pass(git_repository_head_tree(&tree, g_repo));
+
+	cl_assert_equal_i(
+		GIT_EBAREREPO, git_diff_tree_to_workdir(&diff, g_repo, tree, &opts));
+
+	git_tree_free(tree);
+}
+
+void test_diff_workdir__to_null_tree(void)
+{
+	git_diff *diff;
+	diff_expects exp;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+
+	opts.flags = GIT_DIFF_INCLUDE_UNTRACKED |
+		GIT_DIFF_RECURSE_UNTRACKED_DIRS;
+
+	g_repo = cl_git_sandbox_init("status");
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, NULL, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(exp.files, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	git_diff_free(diff);
+}
+
+void test_diff_workdir__checks_options_version(void)
+{
+	git_diff *diff;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	const git_error *err;
+
+	g_repo = cl_git_sandbox_init("status");
+
+	opts.version = 0;
+	cl_git_fail(git_diff_tree_to_workdir(&diff, g_repo, NULL, &opts));
+	err = giterr_last();
+	cl_assert_equal_i(GITERR_INVALID, err->klass);
+
+	giterr_clear();
+	opts.version = 1024;
+	cl_git_fail(git_diff_tree_to_workdir(&diff, g_repo, NULL, &opts));
+	err = giterr_last();
+	cl_assert_equal_i(GITERR_INVALID, err->klass);
+}
+
+void test_diff_workdir__can_diff_empty_file(void)
+{
+	git_diff *diff;
+	git_tree *tree;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	struct stat st;
+	git_patch *patch;
+
+	g_repo = cl_git_sandbox_init("attr_index");
+
+	tree = resolve_commit_oid_to_tree(g_repo, "3812cfef3661"); /* HEAD */
+
+	/* baseline - make sure there are no outstanding diffs */
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, tree, &opts));
+	cl_assert_equal_i(2, (int)git_diff_num_deltas(diff));
+	git_diff_free(diff);
+
+	/* empty contents of file */
+
+	cl_git_rewritefile("attr_index/README.txt", "");
+	cl_git_pass(git_path_lstat("attr_index/README.txt", &st));
+	cl_assert_equal_i(0, (int)st.st_size);
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, tree, &opts));
+	cl_assert_equal_i(3, (int)git_diff_num_deltas(diff));
+	/* diffs are: .gitattributes, README.txt, sub/sub/.gitattributes */
+	cl_git_pass(git_patch_from_diff(&patch, diff, 1));
+	git_patch_free(patch);
+	git_diff_free(diff);
+
+	/* remove a file altogether */
+
+	cl_git_pass(p_unlink("attr_index/README.txt"));
+	cl_assert(!git_path_exists("attr_index/README.txt"));
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, tree, &opts));
+	cl_assert_equal_i(3, (int)git_diff_num_deltas(diff));
+	cl_git_pass(git_patch_from_diff(&patch, diff, 1));
+	git_patch_free(patch);
+	git_diff_free(diff);
+
+	git_tree_free(tree);
+}
+
+void test_diff_workdir__to_index_issue_1397(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	diff_expects exp;
+
+	g_repo = cl_git_sandbox_init("issue_1397");
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	opts.context_lines = 3;
+	opts.interhunk_lines = 1;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(0, exp.files);
+	cl_assert_equal_i(0, exp.hunks);
+	cl_assert_equal_i(0, exp.lines);
+
+	git_diff_free(diff);
+	diff = NULL;
+
+	cl_git_rewritefile("issue_1397/crlf_file.txt",
+		"first line\r\nsecond line modified\r\nboth with crlf");
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(1, exp.files);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+
+	cl_assert_equal_i(1, exp.hunks);
+
+	cl_assert_equal_i(5, exp.lines);
+	cl_assert_equal_i(3, exp.line_ctxt);
+	cl_assert_equal_i(1, exp.line_adds);
+	cl_assert_equal_i(1, exp.line_dels);
+
+	git_diff_free(diff);
+}
+
+void test_diff_workdir__to_tree_issue_1397(void)
+{
+	const char *a_commit = "7f483a738"; /* the current HEAD */
+	git_tree *a;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	git_diff *diff2 = NULL;
+	diff_expects exp;
+
+	g_repo = cl_git_sandbox_init("issue_1397");
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	a = resolve_commit_oid_to_tree(g_repo, a_commit);
+
+	opts.context_lines = 3;
+	opts.interhunk_lines = 1;
+
+	cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, a, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(0, exp.files);
+	cl_assert_equal_i(0, exp.hunks);
+	cl_assert_equal_i(0, exp.lines);
+
+	git_diff_free(diff);
+	diff = NULL;
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, NULL, &opts));
+	cl_git_pass(git_diff_index_to_workdir(&diff2, g_repo, NULL, &opts));
+	cl_git_pass(git_diff_merge(diff, diff2));
+	git_diff_free(diff2);
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(0, exp.files);
+	cl_assert_equal_i(0, exp.hunks);
+	cl_assert_equal_i(0, exp.lines);
+
+	git_diff_free(diff);
+	git_tree_free(a);
+}
+
+void test_diff_workdir__untracked_directory_scenarios(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	diff_expects exp;
+	char *pathspec = NULL;
+	static const char *files0[] = {
+		"subdir/deleted_file",
+		"subdir/modified_file",
+		"subdir/new_file",
+		NULL
+	};
+	static const char *files1[] = {
+		"subdir/deleted_file",
+		"subdir/directory/",
+		"subdir/modified_file",
+		"subdir/new_file",
+		NULL
+	};
+	static const char *files2[] = {
+		"subdir/deleted_file",
+		"subdir/directory/more/notignored",
+		"subdir/modified_file",
+		"subdir/new_file",
+		NULL
+	};
+
+	g_repo = cl_git_sandbox_init("status");
+	cl_git_mkfile("status/.gitignore", "ignored\n");
+
+	opts.context_lines = 3;
+	opts.interhunk_lines = 1;
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+	opts.pathspec.strings = &pathspec;
+	opts.pathspec.count   = 1;
+	pathspec = "subdir";
+
+	/* baseline for "subdir" pathspec */
+
+	memset(&exp, 0, sizeof(exp));
+	exp.names = files0;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
+
+	cl_assert_equal_i(3, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_IGNORED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	git_diff_free(diff);
+
+	/* empty directory */
+
+	cl_git_pass(p_mkdir("status/subdir/directory", 0777));
+
+	memset(&exp, 0, sizeof(exp));
+	exp.names = files1;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
+
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	git_diff_free(diff);
+
+	/* empty directory in empty directory */
+
+	cl_git_pass(p_mkdir("status/subdir/directory/empty", 0777));
+
+	memset(&exp, 0, sizeof(exp));
+	exp.names = files1;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
+
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	git_diff_free(diff);
+
+	/* directory with only ignored files */
+
+	cl_git_pass(p_mkdir("status/subdir/directory/deeper", 0777));
+	cl_git_mkfile("status/subdir/directory/deeper/ignored", "ignore me\n");
+
+	cl_git_pass(p_mkdir("status/subdir/directory/another", 0777));
+	cl_git_mkfile("status/subdir/directory/another/ignored", "ignore me\n");
+
+	memset(&exp, 0, sizeof(exp));
+	exp.names = files1;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
+
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	git_diff_free(diff);
+
+	/* directory with ignored directory (contents irrelevant) */
+
+	cl_git_pass(p_mkdir("status/subdir/directory/more", 0777));
+	cl_git_pass(p_mkdir("status/subdir/directory/more/ignored", 0777));
+	cl_git_mkfile("status/subdir/directory/more/ignored/notignored",
+		"inside ignored dir\n");
+
+	memset(&exp, 0, sizeof(exp));
+	exp.names = files1;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
+
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	git_diff_free(diff);
+
+	/* quick version avoids directory scan */
+
+	opts.flags = opts.flags | GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS;
+
+	memset(&exp, 0, sizeof(exp));
+	exp.names = files1;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
+
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_IGNORED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	git_diff_free(diff);
+
+	/* directory with nested non-ignored content */
+
+	opts.flags = opts.flags & ~GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS;
+
+	cl_git_mkfile("status/subdir/directory/more/notignored",
+		"not ignored deep under untracked\n");
+
+	memset(&exp, 0, sizeof(exp));
+	exp.names = files1;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
+
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_IGNORED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	git_diff_free(diff);
+
+	/* use RECURSE_UNTRACKED_DIRS to get actual untracked files (no ignores) */
+
+	opts.flags = opts.flags & ~GIT_DIFF_INCLUDE_IGNORED;
+	opts.flags = opts.flags | GIT_DIFF_RECURSE_UNTRACKED_DIRS;
+
+	memset(&exp, 0, sizeof(exp));
+	exp.names = files2;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
+
+	cl_assert_equal_i(4, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_IGNORED]);
+	cl_assert_equal_i(2, exp.file_status[GIT_DELTA_UNTRACKED]);
+
+	git_diff_free(diff);
+}
+
+
+void test_diff_workdir__untracked_directory_comes_last(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+
+	g_repo = cl_git_sandbox_init("renames");
+
+	cl_git_mkfile("renames/.gitignore", "*.ign\n");
+	cl_git_pass(p_mkdir("renames/zzz_untracked", 0777));
+	cl_git_mkfile("renames/zzz_untracked/an.ign", "ignore me please");
+	cl_git_mkfile("renames/zzz_untracked/skip.ign", "ignore me really");
+	cl_git_mkfile("renames/zzz_untracked/test.ign", "ignore me now");
+
+	opts.context_lines = 3;
+	opts.interhunk_lines = 1;
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	cl_assert(diff != NULL);
+
+	git_diff_free(diff);
+}
+
+void test_diff_workdir__untracked_with_bom(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	const git_diff_delta *delta;
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	cl_git_write2file("empty_standard_repo/bom.txt",
+		"\xFF\xFE\x31\x00\x32\x00\x33\x00\x34\x00", 10, O_WRONLY|O_CREAT, 0664);
+
+	opts.flags =
+		GIT_DIFF_INCLUDE_UNTRACKED | GIT_DIFF_SHOW_UNTRACKED_CONTENT;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	cl_assert_equal_i(1, git_diff_num_deltas(diff));
+	cl_assert((delta = git_diff_get_delta(diff, 0)) != NULL);
+	cl_assert_equal_i(GIT_DELTA_UNTRACKED, delta->status);
+
+	/* not known at this point
+	 * cl_assert((delta->flags & GIT_DIFF_FLAG_BINARY) != 0);
+	 */
+
+	git_diff_free(diff);
+}
+
+void test_diff_workdir__patience_diff(void)
+{
+	git_index *index;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	git_patch *patch = NULL;
+	git_buf buf = GIT_BUF_INIT;
+	const char *expected_normal = "diff --git a/test.txt b/test.txt\nindex 34a5acc..d52725f 100644\n--- a/test.txt\n+++ b/test.txt\n@@ -1,10 +1,7 @@\n When I wrote this\n I did not know\n-how to create\n-a patience diff\n I did not know\n how to create\n+a patience diff\n another problem\n-I did not know\n-how to create\n a minimal diff\n";
+	const char *expected_patience = "diff --git a/test.txt b/test.txt\nindex 34a5acc..d52725f 100644\n--- a/test.txt\n+++ b/test.txt\n@@ -1,10 +1,7 @@\n When I wrote this\n I did not know\n+I did not know\n how to create\n a patience diff\n-I did not know\n-how to create\n another problem\n-I did not know\n-how to create\n a minimal diff\n";
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_mkfile(
+		"empty_standard_repo/test.txt",
+		"When I wrote this\nI did not know\nhow to create\na patience diff\nI did not know\nhow to create\nanother problem\nI did not know\nhow to create\na minimal diff\n");
+	cl_git_pass(git_index_add_bypath(index, "test.txt"));
+	cl_repo_commit_from_index(NULL, g_repo, NULL, 1372350000, "Base");
+	git_index_free(index);
+
+	cl_git_rewritefile(
+		"empty_standard_repo/test.txt",
+		"When I wrote this\nI did not know\nI did not know\nhow to create\na patience diff\nanother problem\na minimal diff\n");
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	cl_assert_equal_i(1, git_diff_num_deltas(diff));
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_git_pass(git_patch_to_buf(&buf, patch));
+
+	cl_assert_equal_s(expected_normal, buf.ptr);
+	git_buf_clear(&buf);
+	git_patch_free(patch);
+	git_diff_free(diff);
+
+	opts.flags |= GIT_DIFF_PATIENCE;
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	cl_assert_equal_i(1, git_diff_num_deltas(diff));
+	cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+	cl_git_pass(git_patch_to_buf(&buf, patch));
+
+	cl_assert_equal_s(expected_patience, buf.ptr);
+	git_buf_clear(&buf);
+
+	git_buf_free(&buf);
+	git_patch_free(patch);
+	git_diff_free(diff);
+}
+
+void test_diff_workdir__with_stale_index(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	git_index *idx = NULL;
+	diff_expects exp;
+
+	g_repo = cl_git_sandbox_init("status");
+	cl_git_pass(git_repository_index(&idx, g_repo));
+
+	/* make the in-memory index invalid */
+	{
+		git_repository *r2;
+		git_index *idx2;
+		cl_git_pass(git_repository_open(&r2, "status"));
+		cl_git_pass(git_repository_index(&idx2, r2));
+		cl_git_pass(git_index_add_bypath(idx2, "new_file"));
+		cl_git_pass(git_index_add_bypath(idx2, "subdir/new_file"));
+		cl_git_pass(git_index_remove_bypath(idx2, "staged_new_file"));
+		cl_git_pass(git_index_remove_bypath(idx2, "staged_changes_file_deleted"));
+		cl_git_pass(git_index_write(idx2));
+		git_index_free(idx2);
+		git_repository_free(r2);
+	}
+
+	opts.context_lines = 3;
+	opts.interhunk_lines = 1;
+	opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED | GIT_DIFF_INCLUDE_UNMODIFIED;
+
+	/* first try with index pointer which should prevent reload */
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, idx, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(17, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(4, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(4, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(4, exp.file_status[GIT_DELTA_UNTRACKED]);
+	cl_assert_equal_i(5, exp.file_status[GIT_DELTA_UNMODIFIED]);
+
+	git_diff_free(diff);
+
+	/* now let's try without the index pointer which should trigger reload */
+
+	/* two files that were UNTRACKED should have become UNMODIFIED */
+	/* one file that was UNMODIFIED should now have become UNTRACKED */
+	/* one file that was DELETED should now be gone completely */
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	git_diff_free(diff);
+
+	cl_assert_equal_i(16, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(4, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(3, exp.file_status[GIT_DELTA_UNTRACKED]);
+	cl_assert_equal_i(6, exp.file_status[GIT_DELTA_UNMODIFIED]);
+
+	git_index_free(idx);
+}
+
+static int touch_file(void *payload, git_buf *path)
+{
+	struct stat st;
+	struct timeval times[2];
+
+	GIT_UNUSED(payload);
+	if (git_path_isdir(path->ptr))
+		return 0;
+
+	cl_must_pass(p_stat(path->ptr, &st));
+
+	times[0].tv_sec = st.st_mtime + 3;
+	times[0].tv_usec = 0;
+	times[1].tv_sec = st.st_mtime + 3;
+	times[1].tv_usec = 0;
+
+	cl_must_pass(p_utimes(path->ptr, times));
+	return 0;
+}
+
+static void basic_diff_status(git_diff **out, const git_diff_options *opts)
+{
+	diff_expects exp;
+
+	cl_git_pass(git_diff_index_to_workdir(out, g_repo, NULL, opts));
+
+	memset(&exp, 0, sizeof(exp));
+
+	cl_git_pass(git_diff_foreach(
+		*out, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+
+	cl_assert_equal_i(13, exp.files);
+	cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(4, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(4, exp.file_status[GIT_DELTA_MODIFIED]);
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
+	cl_assert_equal_i(4, exp.file_status[GIT_DELTA_UNTRACKED]);
+}
+
+void test_diff_workdir__can_update_index(void)
+{
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	git_diff_perfdata perf = GIT_DIFF_PERFDATA_INIT;
+	git_index *index;
+
+	g_repo = cl_git_sandbox_init("status");
+
+	/* touch all the files so stat times are different */
+	{
+		git_buf path = GIT_BUF_INIT;
+		cl_git_pass(git_buf_sets(&path, "status"));
+		cl_git_pass(git_path_direach(&path, 0, touch_file, NULL));
+		git_buf_free(&path);
+	}
+
+	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+
+	basic_diff_status(&diff, &opts);
+
+	cl_git_pass(git_diff_get_perfdata(&perf, diff));
+	cl_assert_equal_sz(13 + 3, perf.stat_calls);
+	cl_assert_equal_sz(5, perf.oid_calculations);
+
+	git_diff_free(diff);
+
+	/* now allow diff to update stat cache */
+	opts.flags |= GIT_DIFF_UPDATE_INDEX;
+
+	/* advance a tick for the index so we don't re-calculate racily-clean entries */
+	cl_git_pass(git_repository_index__weakptr(&index, g_repo));
+	tick_index(index);
+
+	basic_diff_status(&diff, &opts);
+
+	cl_git_pass(git_diff_get_perfdata(&perf, diff));
+	cl_assert_equal_sz(13 + 3, perf.stat_calls);
+	cl_assert_equal_sz(5, perf.oid_calculations);
+
+	git_diff_free(diff);
+
+	/* now if we do it again, we should see fewer OID calculations */
+
+	/* tick again as the index updating from the previous diff might have reset the timestamp */
+	tick_index(index);
+	basic_diff_status(&diff, &opts);
+
+	cl_git_pass(git_diff_get_perfdata(&perf, diff));
+	cl_assert_equal_sz(13 + 3, perf.stat_calls);
+	cl_assert_equal_sz(0, perf.oid_calculations);
+
+	git_diff_free(diff);
+}
+
+#define STR7    "0123456"
+#define STR8    "01234567"
+#define STR40   STR8   STR8   STR8   STR8   STR8
+#define STR200  STR40  STR40  STR40  STR40  STR40
+#define STR999Z STR200 STR200 STR200 STR200 STR40 STR40 STR40 STR40 \
+	            STR8 STR8 STR8 STR8 STR7 "\0"
+#define STR1000 STR200 STR200 STR200 STR200 STR200
+#define STR3999Z STR1000 STR1000 STR1000 STR999Z
+#define STR4000 STR1000 STR1000 STR1000 STR1000
+
+static void assert_delta_binary(git_diff *diff, size_t idx, int is_binary)
+{
+	git_patch *patch;
+	const git_diff_delta *delta;
+
+	cl_git_pass(git_patch_from_diff(&patch, diff, idx));
+	delta = git_patch_get_delta(patch);
+	cl_assert_equal_b((delta->flags & GIT_DIFF_FLAG_BINARY), is_binary);
+	git_patch_free(patch);
+}
+
+void test_diff_workdir__binary_detection(void)
+{
+	git_index *idx;
+	git_diff *diff = NULL;
+	git_buf b = GIT_BUF_INIT;
+	int i;
+	git_buf data[10] = {
+		{ "1234567890", 0, 0 },         /* 0 - all ascii text control */
+		{ "\xC3\x85\xC3\xBC\xE2\x80\xA0\x48\xC3\xB8\xCF\x80\xCE\xA9", 0, 0 },            /* 1 - UTF-8 multibyte text */
+		{ "\xEF\xBB\xBF\xC3\x9C\xE2\xA4\x92\xC6\x92\x38\xC2\xA3\xE2\x82\xAC", 0, 0 }, /* 2 - UTF-8 with BOM */
+		{ STR999Z, 0, 1000 },           /* 3 - ASCII with NUL at 1000 */
+		{ STR3999Z, 0, 4000 },          /* 4 - ASCII with NUL at 4000 */
+		{ STR4000 STR3999Z "x", 0, 8001 }, /* 5 - ASCII with NUL at 8000 */
+		{ STR4000 STR4000 "\0", 0, 8001 }, /* 6 - ASCII with NUL at 8001 */
+		{ "\x00\xDC\x00\x6E\x21\x39\xFE\x0E\x00\x63\x00\xF8"
+		  "\x00\x64\x00\x65\x20\x48", 0, 18 }, /* 7 - UTF-16 text */
+		{ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d"
+		  "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d",
+		  0, 26 }, /* 8 - All non-printable characters (no NUL) */
+		{ "Hello \x01\x02\x03\x04\x05\x06 World!\x01\x02\x03\x04"
+		  "\x05\x06\x07", 0, 26 }, /* 9 - 50-50 non-printable (no NUL) */
+	};
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+	cl_git_pass(git_repository_index(&idx, g_repo));
+
+	/* We start with ASCII in index and test data in workdir,
+	 * then we will try with test data in index and ASCII in workdir.
+	 */
+
+	cl_git_pass(git_buf_sets(&b, "empty_standard_repo/0"));
+	for (i = 0; i < 10; ++i) {
+		b.ptr[b.size - 1] = '0' + i;
+		cl_git_mkfile(b.ptr, "baseline");
+		cl_git_pass(git_index_add_bypath(idx, &b.ptr[b.size - 1]));
+
+		if (data[i].size == 0)
+			data[i].size = strlen(data[i].ptr);
+		cl_git_write2file(
+			b.ptr, data[i].ptr, data[i].size, O_WRONLY|O_TRUNC, 0664);
+	}
+	git_index_write(idx);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, NULL));
+
+	cl_assert_equal_i(10, git_diff_num_deltas(diff));
+
+	/* using diff binary detection (i.e. looking for NUL byte) */
+	assert_delta_binary(diff, 0, false);
+	assert_delta_binary(diff, 1, false);
+	assert_delta_binary(diff, 2, false);
+	assert_delta_binary(diff, 3, true);
+	assert_delta_binary(diff, 4, true);
+	assert_delta_binary(diff, 5, true);
+	assert_delta_binary(diff, 6, false);
+	assert_delta_binary(diff, 7, true);
+	assert_delta_binary(diff, 8, false);
+	assert_delta_binary(diff, 9, false);
+	/* The above have been checked to match command-line Git */
+
+	git_diff_free(diff);
+
+	cl_git_pass(git_buf_sets(&b, "empty_standard_repo/0"));
+	for (i = 0; i < 10; ++i) {
+		b.ptr[b.size - 1] = '0' + i;
+		cl_git_pass(git_index_add_bypath(idx, &b.ptr[b.size - 1]));
+
+		cl_git_write2file(b.ptr, "baseline\n", 9, O_WRONLY|O_TRUNC, 0664);
+	}
+	git_index_write(idx);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, NULL));
+
+	cl_assert_equal_i(10, git_diff_num_deltas(diff));
+
+	/* using diff binary detection (i.e. looking for NUL byte) */
+	assert_delta_binary(diff, 0, false);
+	assert_delta_binary(diff, 1, false);
+	assert_delta_binary(diff, 2, false);
+	assert_delta_binary(diff, 3, true);
+	assert_delta_binary(diff, 4, true);
+	assert_delta_binary(diff, 5, true);
+	assert_delta_binary(diff, 6, false);
+	assert_delta_binary(diff, 7, true);
+	assert_delta_binary(diff, 8, false);
+	assert_delta_binary(diff, 9, false);
+
+	git_diff_free(diff);
+
+	git_index_free(idx);
+	git_buf_free(&b);
+}
+
+void test_diff_workdir__to_index_conflicted(void) {
+	const char *a_commit = "26a125ee1bf"; /* the current HEAD */
+	git_index_entry ancestor = {{0}}, ours = {{0}}, theirs = {{0}};
+	git_tree *a;
+	git_index *index;
+	git_diff *diff1, *diff2;
+	const git_diff_delta *delta;
+
+	g_repo = cl_git_sandbox_init("status");
+	a = resolve_commit_oid_to_tree(g_repo, a_commit);
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	ancestor.path = ours.path = theirs.path = "_file";
+	ancestor.mode = ours.mode = theirs.mode = 0100644;
+	git_oid_fromstr(&ancestor.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
+	git_oid_fromstr(&ours.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
+	git_oid_fromstr(&theirs.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
+	cl_git_pass(git_index_conflict_add(index, &ancestor, &ours, &theirs));
+
+	cl_git_pass(git_diff_tree_to_index(&diff1, g_repo, a, index, NULL));
+	cl_git_pass(git_diff_index_to_workdir(&diff2, g_repo, index, NULL));
+	cl_git_pass(git_diff_merge(diff1, diff2));
+
+	cl_assert_equal_i(git_diff_num_deltas(diff1), 12);
+	delta = git_diff_get_delta(diff1, 0);
+	cl_assert_equal_s(delta->old_file.path, "_file");
+	cl_assert_equal_i(delta->nfiles, 1);
+	cl_assert_equal_i(delta->status, GIT_DELTA_CONFLICTED);
+
+	git_diff_free(diff2);
+	git_diff_free(diff1);
+	git_index_free(index);
+	git_tree_free(a);
+}
+
+void test_diff_workdir__only_writes_index_when_necessary(void)
+{
+	git_index *index;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	git_reference *head;
+	git_object *head_object;
+	git_oid initial, first, second;
+	git_buf path = GIT_BUF_INIT;
+	struct stat st;
+	struct timeval times[2];
+
+	opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED | GIT_DIFF_UPDATE_INDEX;
+
+	g_repo = cl_git_sandbox_init("status");
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_repository_head(&head, g_repo));
+	cl_git_pass(git_reference_peel(&head_object, head, GIT_OBJ_COMMIT));
+
+	cl_git_pass(git_reset(g_repo, head_object, GIT_RESET_HARD, NULL));
+
+	git_oid_cpy(&initial, git_index_checksum(index));
+
+	/* update the index timestamp to avoid raciness */
+	cl_must_pass(p_stat("status/.git/index", &st));
+
+	times[0].tv_sec = st.st_mtime + 5;
+	times[0].tv_usec = 0;
+	times[1].tv_sec = st.st_mtime + 5;
+	times[1].tv_usec = 0;
+
+	cl_must_pass(p_utimes("status/.git/index", times));
+
+	/* ensure diff doesn't touch the index */
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	git_diff_free(diff);
+
+	git_oid_cpy(&first, git_index_checksum(index));
+	cl_assert(!git_oid_equal(&initial, &first));
+
+	/* touch all the files so stat times are different */
+	cl_git_pass(git_buf_sets(&path, "status"));
+	cl_git_pass(git_path_direach(&path, 0, touch_file, NULL));
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+	git_diff_free(diff);
+
+	/* ensure the second diff did update the index */
+	git_oid_cpy(&second, git_index_checksum(index));
+	cl_assert(!git_oid_equal(&first, &second));
+
+	git_buf_free(&path);
+	git_object_free(head_object);
+	git_reference_free(head);
+	git_index_free(index);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/fetchhead/fetchhead_data.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/fetchhead/fetchhead_data.h
new file mode 100755
index 0000000..c75b65b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/fetchhead/fetchhead_data.h
@@ -0,0 +1,48 @@
+
+#define FETCH_HEAD_WILDCARD_DATA_LOCAL \
+	"49322bb17d3acc9146f98c97d078513228bbf3c0\t\tbranch 'master' of git://github.com/libgit2/TestGitRepository\n" \
+	"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of git://github.com/libgit2/TestGitRepository\n" \
+	"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of git://github.com/libgit2/TestGitRepository\n" \
+	"d96c4e80345534eccee5ac7b07fc7603b56124cb\tnot-for-merge\ttag 'annotated_tag' of git://github.com/libgit2/TestGitRepository\n" \
+	"55a1a760df4b86a02094a904dfa511deb5655905\tnot-for-merge\ttag 'blob' of git://github.com/libgit2/TestGitRepository\n" \
+	"8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of git://github.com/libgit2/TestGitRepository\n"
+
+#define FETCH_HEAD_WILDCARD_DATA \
+	"49322bb17d3acc9146f98c97d078513228bbf3c0\t\tbranch 'master' of git://github.com/libgit2/TestGitRepository\n" \
+	"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of git://github.com/libgit2/TestGitRepository\n" \
+	"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of git://github.com/libgit2/TestGitRepository\n" \
+	"d96c4e80345534eccee5ac7b07fc7603b56124cb\tnot-for-merge\ttag 'annotated_tag' of git://github.com/libgit2/TestGitRepository\n" \
+	"55a1a760df4b86a02094a904dfa511deb5655905\tnot-for-merge\ttag 'blob' of git://github.com/libgit2/TestGitRepository\n" \
+	"8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of git://github.com/libgit2/TestGitRepository\n" \
+	"6e0c7bdb9b4ed93212491ee778ca1c65047cab4e\tnot-for-merge\ttag 'nearly-dangling' of git://github.com/libgit2/TestGitRepository\n"
+
+#define FETCH_HEAD_WILDCARD_DATA2 \
+	"49322bb17d3acc9146f98c97d078513228bbf3c0\t\tbranch 'master' of git://github.com/libgit2/TestGitRepository\n" \
+	"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of git://github.com/libgit2/TestGitRepository\n" \
+	"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of git://github.com/libgit2/TestGitRepository\n" \
+
+#define FETCH_HEAD_NO_MERGE_DATA \
+	"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of git://github.com/libgit2/TestGitRepository\n" \
+	"49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tbranch 'master' of git://github.com/libgit2/TestGitRepository\n" \
+	"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of git://github.com/libgit2/TestGitRepository\n" \
+	"d96c4e80345534eccee5ac7b07fc7603b56124cb\tnot-for-merge\ttag 'annotated_tag' of git://github.com/libgit2/TestGitRepository\n" \
+	"55a1a760df4b86a02094a904dfa511deb5655905\tnot-for-merge\ttag 'blob' of git://github.com/libgit2/TestGitRepository\n" \
+	"8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of git://github.com/libgit2/TestGitRepository\n" \
+	"6e0c7bdb9b4ed93212491ee778ca1c65047cab4e\tnot-for-merge\ttag 'nearly-dangling' of git://github.com/libgit2/TestGitRepository\n"
+
+#define FETCH_HEAD_NO_MERGE_DATA2 \
+	"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of git://github.com/libgit2/TestGitRepository\n" \
+	"49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tbranch 'master' of git://github.com/libgit2/TestGitRepository\n" \
+	"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of git://github.com/libgit2/TestGitRepository\n" \
+
+#define FETCH_HEAD_NO_MERGE_DATA3 \
+	"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of git://github.com/libgit2/TestGitRepository\n" \
+	"49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tbranch 'master' of git://github.com/libgit2/TestGitRepository\n" \
+	"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of git://github.com/libgit2/TestGitRepository\n" \
+	"8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of git://github.com/libgit2/TestGitRepository\n" \
+
+#define FETCH_HEAD_EXPLICIT_DATA \
+	"0966a434eb1a025db6b71485ab63a3bfbea520b6\t\tbranch 'first-merge' of git://github.com/libgit2/TestGitRepository\n"
+
+#define FETCH_HEAD_QUOTE_DATA \
+	"0966a434eb1a025db6b71485ab63a3bfbea520b6\t\tbranch 'first's-merge' of git://github.com/libgit2/TestGitRepository\n"
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/fetchhead/nonetwork.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/fetchhead/nonetwork.c
new file mode 100755
index 0000000..3b750af
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/fetchhead/nonetwork.c
@@ -0,0 +1,400 @@
+#include "clar_libgit2.h"
+
+#include "fileops.h"
+#include "fetchhead.h"
+
+#include "fetchhead_data.h"
+
+#define DO_LOCAL_TEST 0
+
+static git_repository *g_repo;
+
+void test_fetchhead_nonetwork__initialize(void)
+{
+	g_repo = NULL;
+}
+
+static void cleanup_repository(void *path)
+{
+	if (g_repo) {
+		git_repository_free(g_repo);
+		g_repo = NULL;
+	}
+
+	cl_fixture_cleanup((const char *)path);
+}
+
+static void populate_fetchhead(git_vector *out, git_repository *repo)
+{
+	git_fetchhead_ref *fetchhead_ref;
+	git_oid oid;
+
+	cl_git_pass(git_oid_fromstr(&oid,
+		"49322bb17d3acc9146f98c97d078513228bbf3c0"));
+	cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 1,
+		"refs/heads/master",
+		"git://github.com/libgit2/TestGitRepository"));
+	cl_git_pass(git_vector_insert(out, fetchhead_ref));
+
+	cl_git_pass(git_oid_fromstr(&oid,
+		"0966a434eb1a025db6b71485ab63a3bfbea520b6"));
+	cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 0,
+		"refs/heads/first-merge",
+		"git://github.com/libgit2/TestGitRepository"));
+	cl_git_pass(git_vector_insert(out, fetchhead_ref));
+
+	cl_git_pass(git_oid_fromstr(&oid,
+		"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1"));
+	cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 0,
+		"refs/heads/no-parent",
+		"git://github.com/libgit2/TestGitRepository"));
+	cl_git_pass(git_vector_insert(out, fetchhead_ref));
+
+	cl_git_pass(git_oid_fromstr(&oid,
+		"d96c4e80345534eccee5ac7b07fc7603b56124cb"));
+	cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 0,
+		"refs/tags/annotated_tag",
+		"git://github.com/libgit2/TestGitRepository"));
+	cl_git_pass(git_vector_insert(out, fetchhead_ref));
+
+	cl_git_pass(git_oid_fromstr(&oid,
+		"55a1a760df4b86a02094a904dfa511deb5655905"));
+	cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 0,
+		"refs/tags/blob",
+		"git://github.com/libgit2/TestGitRepository"));
+	cl_git_pass(git_vector_insert(out, fetchhead_ref));
+
+	cl_git_pass(git_oid_fromstr(&oid,
+		"8f50ba15d49353813cc6e20298002c0d17b0a9ee"));
+	cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 0,
+		"refs/tags/commit_tree",
+		"git://github.com/libgit2/TestGitRepository"));
+	cl_git_pass(git_vector_insert(out, fetchhead_ref));
+
+	cl_git_pass(git_fetchhead_write(repo, out));
+}
+
+void test_fetchhead_nonetwork__write(void)
+{
+	git_vector fetchhead_vector = GIT_VECTOR_INIT;
+	git_fetchhead_ref *fetchhead_ref;
+	git_buf fetchhead_buf = GIT_BUF_INIT;
+	int equals = 0;
+	size_t i;
+
+	git_vector_init(&fetchhead_vector, 6, NULL);
+
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+
+	populate_fetchhead(&fetchhead_vector, g_repo);
+
+	cl_git_pass(git_futils_readbuffer(&fetchhead_buf,
+		"./test1/.git/FETCH_HEAD"));
+
+	equals = (strcmp(fetchhead_buf.ptr, FETCH_HEAD_WILDCARD_DATA_LOCAL) == 0);
+
+	git_buf_free(&fetchhead_buf);
+
+	git_vector_foreach(&fetchhead_vector, i, fetchhead_ref) {
+		git_fetchhead_ref_free(fetchhead_ref);
+	}
+
+	git_vector_free(&fetchhead_vector);
+
+	cl_assert(equals);
+}
+
+typedef struct {
+	git_vector *fetchhead_vector;
+	size_t idx;
+} fetchhead_ref_cb_data; 
+
+static int fetchhead_ref_cb(const char *name, const char *url,
+	const git_oid *oid, unsigned int is_merge, void *payload)
+{
+	fetchhead_ref_cb_data *cb_data = payload;
+	git_fetchhead_ref *expected;
+
+	cl_assert(payload);
+
+	expected = git_vector_get(cb_data->fetchhead_vector, cb_data->idx);
+
+	cl_assert_equal_oid(&expected->oid, oid);
+	cl_assert(expected->is_merge == is_merge);
+
+	if (expected->ref_name)
+		cl_assert_equal_s(expected->ref_name, name);
+	else
+		cl_assert(name == NULL);
+
+	if (expected->remote_url)
+		cl_assert_equal_s(expected->remote_url, url);
+	else
+		cl_assert(url == NULL);
+
+	cb_data->idx++;
+
+	return 0;
+}
+
+void test_fetchhead_nonetwork__read(void)
+{
+	git_vector fetchhead_vector = GIT_VECTOR_INIT;
+	git_fetchhead_ref *fetchhead_ref;
+	fetchhead_ref_cb_data cb_data;
+	size_t i;
+
+	memset(&cb_data, 0x0, sizeof(fetchhead_ref_cb_data));
+
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+
+	populate_fetchhead(&fetchhead_vector, g_repo);
+
+	cb_data.fetchhead_vector = &fetchhead_vector;
+
+	cl_git_pass(git_repository_fetchhead_foreach(g_repo, fetchhead_ref_cb, &cb_data));
+
+	git_vector_foreach(&fetchhead_vector, i, fetchhead_ref) {
+		git_fetchhead_ref_free(fetchhead_ref);
+	}
+
+	git_vector_free(&fetchhead_vector);
+}
+
+static int read_old_style_cb(const char *name, const char *url,
+	const git_oid *oid, unsigned int is_merge, void *payload)
+{
+	git_oid expected;
+
+	GIT_UNUSED(payload);
+
+	git_oid_fromstr(&expected, "49322bb17d3acc9146f98c97d078513228bbf3c0");
+
+	cl_assert(name == NULL);
+	cl_assert(url == NULL);
+	cl_assert_equal_oid(&expected, oid);
+	cl_assert(is_merge == 1);
+
+	return 0;
+}
+
+void test_fetchhead_nonetwork__read_old_style(void)
+{
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+
+	cl_git_rewritefile("./test1/.git/FETCH_HEAD", "49322bb17d3acc9146f98c97d078513228bbf3c0\n");
+
+	cl_git_pass(git_repository_fetchhead_foreach(g_repo, read_old_style_cb, NULL));
+}
+
+static int read_type_missing(const char *ref_name, const char *remote_url,
+	const git_oid *oid, unsigned int is_merge, void *payload)
+{
+	git_oid expected;
+
+	GIT_UNUSED(payload);
+
+	git_oid_fromstr(&expected, "49322bb17d3acc9146f98c97d078513228bbf3c0");
+
+	cl_assert_equal_s("name", ref_name);
+	cl_assert_equal_s("remote_url", remote_url);
+	cl_assert_equal_oid(&expected, oid);
+	cl_assert(is_merge == 0);
+
+	return 0;
+}
+
+void test_fetchhead_nonetwork__type_missing(void)
+{
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+
+	cl_git_rewritefile("./test1/.git/FETCH_HEAD", "49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\t'name' of remote_url\n");
+
+	cl_git_pass(git_repository_fetchhead_foreach(g_repo, read_type_missing, NULL));
+}
+
+static int read_name_missing(const char *ref_name, const char *remote_url,
+	const git_oid *oid, unsigned int is_merge, void *payload)
+{
+	git_oid expected;
+
+	GIT_UNUSED(payload);
+
+	git_oid_fromstr(&expected, "49322bb17d3acc9146f98c97d078513228bbf3c0");
+
+	cl_assert(ref_name == NULL);
+	cl_assert_equal_s("remote_url", remote_url);
+	cl_assert_equal_oid(&expected, oid);
+	cl_assert(is_merge == 0);
+
+	return 0;
+}
+
+void test_fetchhead_nonetwork__name_missing(void)
+{
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+
+	cl_git_rewritefile("./test1/.git/FETCH_HEAD", "49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tremote_url\n");
+
+	cl_git_pass(git_repository_fetchhead_foreach(g_repo, read_name_missing, NULL));
+}
+
+static int read_noop(const char *ref_name, const char *remote_url,
+	const git_oid *oid, unsigned int is_merge, void *payload)
+{
+	GIT_UNUSED(ref_name);
+	GIT_UNUSED(remote_url);
+	GIT_UNUSED(oid);
+	GIT_UNUSED(is_merge);
+	GIT_UNUSED(payload);
+
+	return 0;
+}
+
+void test_fetchhead_nonetwork__nonexistent(void)
+{
+	int error;
+
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+
+	cl_git_fail((error = git_repository_fetchhead_foreach(g_repo, read_noop, NULL)));
+	cl_assert(error == GIT_ENOTFOUND);
+}
+
+void test_fetchhead_nonetwork__invalid_unterminated_last_line(void)
+{
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+
+	cl_git_rewritefile("./test1/.git/FETCH_HEAD", "unterminated");
+	cl_git_fail(git_repository_fetchhead_foreach(g_repo, read_noop, NULL));
+}
+
+void test_fetchhead_nonetwork__invalid_oid(void)
+{
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+
+	cl_git_rewritefile("./test1/.git/FETCH_HEAD", "shortoid\n");
+	cl_git_fail(git_repository_fetchhead_foreach(g_repo, read_noop, NULL));
+}
+
+void test_fetchhead_nonetwork__invalid_for_merge(void)
+{
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+
+	cl_git_rewritefile("./test1/.git/FETCH_HEAD", "49322bb17d3acc9146f98c97d078513228bbf3c0\tinvalid-merge\t\n");
+	cl_git_fail(git_repository_fetchhead_foreach(g_repo, read_noop, NULL));
+
+	cl_assert(git__prefixcmp(giterr_last()->message, "Invalid for-merge") == 0);
+}
+
+void test_fetchhead_nonetwork__invalid_description(void)
+{
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+
+	cl_git_rewritefile("./test1/.git/FETCH_HEAD", "49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\n");
+	cl_git_fail(git_repository_fetchhead_foreach(g_repo, read_noop, NULL));
+
+	cl_assert(git__prefixcmp(giterr_last()->message, "Invalid description") == 0);
+}
+
+static int assert_master_for_merge(const char *ref, const char *url, const git_oid *id, unsigned int is_merge, void *data)
+{
+	GIT_UNUSED(url);
+	GIT_UNUSED(id);
+	GIT_UNUSED(data);
+
+	if (!strcmp("refs/heads/master", ref) && !is_merge)
+		return -1;
+
+	return 0;
+}
+
+void test_fetchhead_nonetwork__unborn_with_upstream(void)
+{
+	git_repository *repo;
+	git_remote *remote;
+
+	/* Create an empty repo to clone from */
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+	cl_set_cleanup(&cleanup_repository, "./repowithunborn");
+	cl_git_pass(git_clone(&repo, "./test1", "./repowithunborn", NULL));
+
+	/* Simulate someone pushing to it by changing to one that has stuff */
+	cl_git_pass(git_remote_set_url(repo, "origin", cl_fixture("testrepo.git")));
+	cl_git_pass(git_remote_lookup(&remote, repo, "origin"));
+
+	cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL));
+	git_remote_free(remote);
+
+	cl_git_pass(git_repository_fetchhead_foreach(repo, assert_master_for_merge, NULL));
+
+	git_repository_free(repo);
+	cl_fixture_cleanup("./repowithunborn");
+}
+
+void test_fetchhead_nonetwork__quote_in_branch_name(void)
+{
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+
+	cl_git_rewritefile("./test1/.git/FETCH_HEAD", FETCH_HEAD_QUOTE_DATA);
+	cl_git_pass(git_repository_fetchhead_foreach(g_repo, read_noop, NULL));
+}
+
+static bool found_master;
+static bool find_master_called;
+
+int find_master(const char *ref_name, const char *remote_url, const git_oid *oid, unsigned int is_merge, void *payload)
+{
+	GIT_UNUSED(remote_url);
+	GIT_UNUSED(oid);
+	GIT_UNUSED(payload);
+
+	find_master_called = true;
+
+	if (!strcmp("refs/heads/master", ref_name)) {
+		cl_assert(is_merge);
+		found_master = true;
+	}
+
+	return 0;
+}
+
+void test_fetchhead_nonetwork__create_when_refpecs_given(void)
+{
+	git_remote *remote;
+	git_buf path = GIT_BUF_INIT;
+	char *refspec = "refs/heads/master";
+	git_strarray specs = {
+		&refspec,
+		1,
+	};
+
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+
+	cl_git_pass(git_buf_joinpath(&path, git_repository_path(g_repo), "FETCH_HEAD"));
+	cl_git_pass(git_remote_create(&remote, g_repo, "origin", cl_fixture("testrepo.git")));
+
+	cl_assert(!git_path_exists(path.ptr));
+	cl_git_pass(git_remote_fetch(remote, &specs, NULL, NULL));
+	cl_assert(git_path_exists(path.ptr));
+
+	cl_git_pass(git_repository_fetchhead_foreach(g_repo, find_master, NULL));
+	cl_assert(find_master_called);
+	cl_assert(found_master);
+
+	git_remote_free(remote);
+	git_buf_free(&path);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/blob.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/blob.c
new file mode 100755
index 0000000..bb2528d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/blob.c
@@ -0,0 +1,117 @@
+#include "clar_libgit2.h"
+#include "crlf.h"
+
+static git_repository *g_repo = NULL;
+
+void test_filter_blob__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("crlf");
+	cl_git_mkfile("crlf/.gitattributes",
+		"*.txt text\n*.bin binary\n"
+		"*.crlf text eol=crlf\n"
+		"*.lf text eol=lf\n"
+		"*.ident text ident\n"
+		"*.identcrlf ident text eol=crlf\n"
+		"*.identlf ident text eol=lf\n");
+}
+
+void test_filter_blob__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_filter_blob__all_crlf(void)
+{
+	git_blob *blob;
+	git_buf buf = { 0 };
+
+	cl_git_pass(git_revparse_single(
+		(git_object **)&blob, g_repo, "a9a2e891")); /* all-crlf */
+
+	cl_assert_equal_s(ALL_CRLF_TEXT_RAW, git_blob_rawcontent(blob));
+
+	cl_git_pass(git_blob_filtered_content(&buf, blob, "file.bin", 1));
+
+	cl_assert_equal_s(ALL_CRLF_TEXT_RAW, buf.ptr);
+
+	cl_git_pass(git_blob_filtered_content(&buf, blob, "file.crlf", 1));
+
+	/* in this case, raw content has crlf in it already */
+	cl_assert_equal_s(ALL_CRLF_TEXT_AS_CRLF, buf.ptr);
+
+	cl_git_pass(git_blob_filtered_content(&buf, blob, "file.lf", 1));
+
+	/* we never convert CRLF -> LF on platforms that have LF */
+	cl_assert_equal_s(ALL_CRLF_TEXT_AS_CRLF, buf.ptr);
+
+	git_buf_free(&buf);
+	git_blob_free(blob);
+}
+
+void test_filter_blob__sanitizes(void)
+{
+	git_blob *blob;
+	git_buf buf;
+
+	cl_git_pass(git_revparse_single(
+		(git_object **)&blob, g_repo, "e69de29")); /* zero-byte */
+
+	cl_assert_equal_i(0, git_blob_rawsize(blob));
+	cl_assert_equal_s("", git_blob_rawcontent(blob));
+
+	memset(&buf, 0, sizeof(git_buf));
+	cl_git_pass(git_blob_filtered_content(&buf, blob, "file.bin", 1));
+	cl_assert_equal_sz(0, buf.size);
+	cl_assert_equal_s("", buf.ptr);
+	git_buf_free(&buf);
+
+	memset(&buf, 0, sizeof(git_buf));
+	cl_git_pass(git_blob_filtered_content(&buf, blob, "file.crlf", 1));
+	cl_assert_equal_sz(0, buf.size);
+	cl_assert_equal_s("", buf.ptr);
+	git_buf_free(&buf);
+
+	memset(&buf, 0, sizeof(git_buf));
+	cl_git_pass(git_blob_filtered_content(&buf, blob, "file.lf", 1));
+	cl_assert_equal_sz(0, buf.size);
+	cl_assert_equal_s("", buf.ptr);
+	git_buf_free(&buf);
+
+	git_blob_free(blob);
+}
+
+void test_filter_blob__ident(void)
+{
+	git_oid id;
+	git_blob *blob;
+	git_buf buf = { 0 };
+
+	cl_git_mkfile("crlf/test.ident", "Some text\n$Id$\nGoes there\n");
+	cl_git_pass(git_blob_create_fromworkdir(&id, g_repo, "test.ident"));
+	cl_git_pass(git_blob_lookup(&blob, g_repo, &id));
+	cl_assert_equal_s(
+		"Some text\n$Id$\nGoes there\n", git_blob_rawcontent(blob));
+	git_blob_free(blob);
+
+	cl_git_mkfile("crlf/test.ident", "Some text\n$Id: Any old just you want$\nGoes there\n");
+	cl_git_pass(git_blob_create_fromworkdir(&id, g_repo, "test.ident"));
+	cl_git_pass(git_blob_lookup(&blob, g_repo, &id));
+	cl_assert_equal_s(
+		"Some text\n$Id$\nGoes there\n", git_blob_rawcontent(blob));
+
+	cl_git_pass(git_blob_filtered_content(&buf, blob, "filter.bin", 1));
+	cl_assert_equal_s(
+		"Some text\n$Id$\nGoes there\n", buf.ptr);
+
+	cl_git_pass(git_blob_filtered_content(&buf, blob, "filter.identcrlf", 1));
+	cl_assert_equal_s(
+		"Some text\r\n$Id: 3164f585d548ac68027d22b104f2d8100b2b6845 $\r\nGoes there\r\n", buf.ptr);
+
+	cl_git_pass(git_blob_filtered_content(&buf, blob, "filter.identlf", 1));
+	cl_assert_equal_s(
+		"Some text\n$Id: 3164f585d548ac68027d22b104f2d8100b2b6845 $\nGoes there\n", buf.ptr);
+
+	git_buf_free(&buf);
+	git_blob_free(blob);
+
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/crlf.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/crlf.c
new file mode 100755
index 0000000..a8ebd94
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/crlf.c
@@ -0,0 +1,235 @@
+#include "clar_libgit2.h"
+#include "git2/sys/filter.h"
+#include "buffer.h"
+
+static git_repository *g_repo = NULL;
+
+void test_filter_crlf__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("crlf");
+
+	cl_git_mkfile("crlf/.gitattributes",
+		"*.txt text\n*.bin binary\n*.crlf text eol=crlf\n*.lf text eol=lf\n");
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+}
+
+void test_filter_crlf__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_filter_crlf__to_worktree(void)
+{
+	git_filter_list *fl;
+	git_filter *crlf;
+	git_buf in = { 0 }, out = { 0 };
+
+	cl_git_pass(git_filter_list_new(
+		&fl, g_repo, GIT_FILTER_TO_WORKTREE, 0));
+
+	crlf = git_filter_lookup(GIT_FILTER_CRLF);
+	cl_assert(crlf != NULL);
+
+	cl_git_pass(git_filter_list_push(fl, crlf, NULL));
+
+	in.ptr = "Some text\nRight here\n";
+	in.size = strlen(in.ptr);
+
+	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
+
+	cl_assert_equal_s("Some text\r\nRight here\r\n", out.ptr);
+
+	git_filter_list_free(fl);
+	git_buf_free(&out);
+}
+
+void test_filter_crlf__to_odb(void)
+{
+	git_filter_list *fl;
+	git_filter *crlf;
+	git_buf in = { 0 }, out = { 0 };
+
+	cl_git_pass(git_filter_list_new(
+		&fl, g_repo, GIT_FILTER_TO_ODB, 0));
+
+	crlf = git_filter_lookup(GIT_FILTER_CRLF);
+	cl_assert(crlf != NULL);
+
+	cl_git_pass(git_filter_list_push(fl, crlf, NULL));
+
+	in.ptr = "Some text\r\nRight here\r\n";
+	in.size = strlen(in.ptr);
+
+	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
+
+	cl_assert_equal_s("Some text\nRight here\n", out.ptr);
+
+	git_filter_list_free(fl);
+	git_buf_free(&out);
+}
+
+void test_filter_crlf__with_safecrlf(void)
+{
+	git_filter_list *fl;
+	git_filter *crlf;
+	git_buf in = {0}, out = GIT_BUF_INIT;
+
+	cl_repo_set_bool(g_repo, "core.safecrlf", true);
+
+	cl_git_pass(git_filter_list_new(
+		&fl, g_repo, GIT_FILTER_TO_ODB, 0));
+
+	crlf = git_filter_lookup(GIT_FILTER_CRLF);
+	cl_assert(crlf != NULL);
+
+	cl_git_pass(git_filter_list_push(fl, crlf, NULL));
+
+	/* Normalized \r\n succeeds with safecrlf */
+	in.ptr = "Normal\r\nCRLF\r\nline-endings.\r\n";
+	in.size = strlen(in.ptr);
+
+	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
+	cl_assert_equal_s("Normal\nCRLF\nline-endings.\n", out.ptr);
+
+	/* Mix of line endings fails with safecrlf */
+	in.ptr = "Mixed\nup\r\nLF\nand\r\nCRLF\nline-endings.\r\n";
+	in.size = strlen(in.ptr);
+
+	cl_git_fail(git_filter_list_apply_to_data(&out, fl, &in));
+	cl_assert_equal_i(giterr_last()->klass, GITERR_FILTER);
+
+	/* Normalized \n is reversible, so does not fail with safecrlf */
+	in.ptr = "Normal\nLF\nonly\nline-endings.\n";
+	in.size = strlen(in.ptr);
+
+	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
+	cl_assert_equal_s(in.ptr, out.ptr);
+
+	git_filter_list_free(fl);
+	git_buf_free(&out);
+}
+
+void test_filter_crlf__with_safecrlf_and_unsafe_allowed(void)
+{
+	git_filter_list *fl;
+	git_filter *crlf;
+	git_buf in = {0}, out = GIT_BUF_INIT;
+
+	cl_repo_set_bool(g_repo, "core.safecrlf", true);
+
+	cl_git_pass(git_filter_list_new(
+		&fl, g_repo, GIT_FILTER_TO_ODB, GIT_FILTER_ALLOW_UNSAFE));
+
+	crlf = git_filter_lookup(GIT_FILTER_CRLF);
+	cl_assert(crlf != NULL);
+
+	cl_git_pass(git_filter_list_push(fl, crlf, NULL));
+
+	/* Normalized \r\n succeeds with safecrlf */
+	in.ptr = "Normal\r\nCRLF\r\nline-endings.\r\n";
+	in.size = strlen(in.ptr);
+
+	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
+	cl_assert_equal_s("Normal\nCRLF\nline-endings.\n", out.ptr);
+
+	/* Mix of line endings fails with safecrlf, but allowed to pass */
+	in.ptr = "Mixed\nup\r\nLF\nand\r\nCRLF\nline-endings.\r\n";
+	in.size = strlen(in.ptr);
+
+	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
+	/* TODO: check for warning */
+	cl_assert_equal_s("Mixed\nup\nLF\nand\nCRLF\nline-endings.\n", out.ptr);
+
+	/* Normalized \n fails with safecrlf, but allowed to pass */
+	in.ptr = "Normal\nLF\nonly\nline-endings.\n";
+	in.size = strlen(in.ptr);
+
+	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
+	/* TODO: check for warning */
+	cl_assert_equal_s("Normal\nLF\nonly\nline-endings.\n", out.ptr);
+
+	git_filter_list_free(fl);
+	git_buf_free(&out);
+}
+
+void test_filter_crlf__no_safecrlf(void)
+{
+	git_filter_list *fl;
+	git_filter *crlf;
+	git_buf in = {0}, out = GIT_BUF_INIT;
+
+	cl_git_pass(git_filter_list_new(
+		&fl, g_repo, GIT_FILTER_TO_ODB, 0));
+
+	crlf = git_filter_lookup(GIT_FILTER_CRLF);
+	cl_assert(crlf != NULL);
+
+	cl_git_pass(git_filter_list_push(fl, crlf, NULL));
+
+	/* Normalized \r\n succeeds with safecrlf */
+	in.ptr = "Normal\r\nCRLF\r\nline-endings.\r\n";
+	in.size = strlen(in.ptr);
+
+	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
+	cl_assert_equal_s("Normal\nCRLF\nline-endings.\n", out.ptr);
+
+	/* Mix of line endings fails with safecrlf */
+	in.ptr = "Mixed\nup\r\nLF\nand\r\nCRLF\nline-endings.\r\n";
+	in.size = strlen(in.ptr);
+
+	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
+	cl_assert_equal_s("Mixed\nup\nLF\nand\nCRLF\nline-endings.\n", out.ptr);
+
+	/* Normalized \n fails with safecrlf */
+	in.ptr = "Normal\nLF\nonly\nline-endings.\n";
+	in.size = strlen(in.ptr);
+
+	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
+	cl_assert_equal_s("Normal\nLF\nonly\nline-endings.\n", out.ptr);
+
+	git_filter_list_free(fl);
+	git_buf_free(&out);
+}
+
+void test_filter_crlf__safecrlf_warn(void)
+{
+	git_filter_list *fl;
+	git_filter *crlf;
+	git_buf in = {0}, out = GIT_BUF_INIT;
+
+	cl_repo_set_string(g_repo, "core.safecrlf", "warn");
+
+	cl_git_pass(git_filter_list_new(
+		&fl, g_repo, GIT_FILTER_TO_ODB, 0));
+
+	crlf = git_filter_lookup(GIT_FILTER_CRLF);
+	cl_assert(crlf != NULL);
+
+	cl_git_pass(git_filter_list_push(fl, crlf, NULL));
+
+	/* Normalized \r\n succeeds with safecrlf=warn */
+	in.ptr = "Normal\r\nCRLF\r\nline-endings.\r\n";
+	in.size = strlen(in.ptr);
+
+	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
+	cl_assert_equal_s("Normal\nCRLF\nline-endings.\n", out.ptr);
+
+	/* Mix of line endings succeeds with safecrlf=warn */
+	in.ptr = "Mixed\nup\r\nLF\nand\r\nCRLF\nline-endings.\r\n";
+	in.size = strlen(in.ptr);
+
+	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
+	/* TODO: check for warning */
+	cl_assert_equal_s("Mixed\nup\nLF\nand\nCRLF\nline-endings.\n", out.ptr);
+
+	/* Normalized \n is reversible, so does not fail with safecrlf=warn */
+	in.ptr = "Normal\nLF\nonly\nline-endings.\n";
+	in.size = strlen(in.ptr);
+
+	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
+	cl_assert_equal_s(in.ptr, out.ptr);
+
+	git_filter_list_free(fl);
+	git_buf_free(&out);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/crlf.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/crlf.h
new file mode 100755
index 0000000..786edfc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/crlf.h
@@ -0,0 +1,30 @@
+#ifndef INCLUDE_filter_crlf_h__
+#define INCLUDE_filter_crlf_h__
+
+/*
+ * file content for files in the resources/crlf repository
+ */
+
+#define UTF8_BOM "\xEF\xBB\xBF"
+
+#define ALL_CRLF_TEXT_RAW		"crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n"
+#define ALL_LF_TEXT_RAW			"lf\nlf\nlf\nlf\nlf\n"
+#define MORE_CRLF_TEXT_RAW		"crlf\r\ncrlf\r\nlf\ncrlf\r\ncrlf\r\n"
+#define MORE_LF_TEXT_RAW		"lf\nlf\ncrlf\r\nlf\nlf\n"
+
+#define ALL_CRLF_TEXT_AS_CRLF	ALL_CRLF_TEXT_RAW
+#define ALL_LF_TEXT_AS_CRLF		"lf\r\nlf\r\nlf\r\nlf\r\nlf\r\n"
+#define MORE_CRLF_TEXT_AS_CRLF	"crlf\r\ncrlf\r\nlf\r\ncrlf\r\ncrlf\r\n"
+#define MORE_LF_TEXT_AS_CRLF	"lf\r\nlf\r\ncrlf\r\nlf\r\nlf\r\n"
+
+#define ALL_CRLF_TEXT_AS_LF		"crlf\ncrlf\ncrlf\ncrlf\n"
+#define ALL_LF_TEXT_AS_LF		ALL_LF_TEXT_RAW
+#define MORE_CRLF_TEXT_AS_LF	"crlf\ncrlf\nlf\ncrlf\ncrlf\n"
+#define MORE_LF_TEXT_AS_LF		"lf\nlf\ncrlf\nlf\nlf\n"
+
+#define FEW_UTF8_CRLF_RAW		"\xe2\x9a\xbdThe rest is ASCII01.\r\nThe rest is ASCII02.\r\nThe rest is ASCII03.\r\nThe rest is ASCII04.\r\nThe rest is ASCII05.\r\nThe rest is ASCII06.\r\nThe rest is ASCII07.\r\nThe rest is ASCII08.\r\nThe rest is ASCII09.\r\nThe rest is ASCII10.\r\nThe rest is ASCII11.\r\nThe rest is ASCII12.\r\nThe rest is ASCII13.\r\nThe rest is ASCII14.\r\nThe rest is ASCII15.\r\nThe rest is ASCII16.\r\nThe rest is ASCII17.\r\nThe rest is ASCII18.\r\nThe rest is ASCII19.\r\nThe rest is ASCII20.\r\nThe rest is ASCII21.\r\nThe rest is ASCII22.\r\n"
+#define FEW_UTF8_LF_RAW			"\xe2\x9a\xbdThe rest is ASCII01.\nThe rest is ASCII02.\nThe rest is ASCII03.\nThe rest is ASCII04.\nThe rest is ASCII05.\nThe rest is ASCII06.\nThe rest is ASCII07.\nThe rest is ASCII08.\nThe rest is ASCII09.\nThe rest is ASCII10.\nThe rest is ASCII11.\nThe rest is ASCII12.\nThe rest is ASCII13.\nThe rest is ASCII14.\nThe rest is ASCII15.\nThe rest is ASCII16.\nThe rest is ASCII17.\nThe rest is ASCII18.\nThe rest is ASCII19.\nThe rest is ASCII20.\nThe rest is ASCII21.\nThe rest is ASCII22.\n"
+#define MANY_UTF8_CRLF_RAW		"Lets sing!\r\n\xe2\x99\xab\xe2\x99\xaa\xe2\x99\xac\xe2\x99\xa9\r\nEat food\r\n\xf0\x9f\x8d\x85\xf0\x9f\x8d\x95\r\n"
+#define MANY_UTF8_LF_RAW		"Lets sing!\n\xe2\x99\xab\xe2\x99\xaa\xe2\x99\xac\xe2\x99\xa9\nEat food\n\xf0\x9f\x8d\x85\xf0\x9f\x8d\x95\n"
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/custom.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/custom.c
new file mode 100755
index 0000000..493d26c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/custom.c
@@ -0,0 +1,338 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "blob.h"
+#include "filter.h"
+#include "buf_text.h"
+#include "git2/sys/filter.h"
+#include "git2/sys/repository.h"
+
+/* going TO_WORKDIR, filters are executed low to high
+ * going TO_ODB, filters are executed high to low
+ */
+#define BITFLIP_FILTER_PRIORITY -1
+#define REVERSE_FILTER_PRIORITY -2
+
+#define VERY_SECURE_ENCRYPTION(b) ((b) ^ 0xff)
+
+#ifdef GIT_WIN32
+# define NEWLINE "\r\n"
+#else
+# define NEWLINE "\n"
+#endif
+
+static char workdir_data[] =
+	"some simple" NEWLINE
+	"data" NEWLINE
+	"that will be" NEWLINE
+	"trivially" NEWLINE
+	"scrambled." NEWLINE;
+
+/* Represents the data above scrambled (bits flipped) after \r\n -> \n
+ * conversion, then bytewise reversed
+ */
+static unsigned char bitflipped_and_reversed_data[] =
+	{ 0xf5, 0xd1, 0x9b, 0x9a, 0x93, 0x9d, 0x92, 0x9e, 0x8d, 0x9c, 0x8c,
+	  0xf5, 0x86, 0x93, 0x93, 0x9e, 0x96, 0x89, 0x96, 0x8d, 0x8b, 0xf5,
+	  0x9a, 0x9d, 0xdf, 0x93, 0x93, 0x96, 0x88, 0xdf, 0x8b, 0x9e, 0x97,
+	  0x8b, 0xf5, 0x9e, 0x8b, 0x9e, 0x9b, 0xf5, 0x9a, 0x93, 0x8f, 0x92,
+	  0x96, 0x8c, 0xdf, 0x9a, 0x92, 0x90, 0x8c };
+
+#define BITFLIPPED_AND_REVERSED_DATA_LEN 51
+
+static git_repository *g_repo = NULL;
+
+static void register_custom_filters(void);
+
+void test_filter_custom__initialize(void)
+{
+	register_custom_filters();
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+	cl_git_mkfile(
+		"empty_standard_repo/.gitattributes",
+		"hero* bitflip reverse\n"
+		"herofile text\n"
+		"heroflip -reverse binary\n"
+		"*.bin binary\n");
+}
+
+void test_filter_custom__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+	g_repo = NULL;
+}
+
+static int bitflip_filter_apply(
+	git_filter     *self,
+	void          **payload,
+	git_buf        *to,
+	const git_buf  *from,
+	const git_filter_source *source)
+{
+	const unsigned char *src = (const unsigned char *)from->ptr;
+	unsigned char *dst;
+	size_t i;
+
+	GIT_UNUSED(self); GIT_UNUSED(payload);
+
+	/* verify that attribute path match worked as expected */
+	cl_assert_equal_i(
+		0, git__strncmp("hero", git_filter_source_path(source), 4));
+
+	if (!from->size)
+		return 0;
+
+	cl_git_pass(git_buf_grow(to, from->size));
+
+	dst = (unsigned char *)to->ptr;
+
+	for (i = 0; i < from->size; i++)
+		dst[i] = VERY_SECURE_ENCRYPTION(src[i]);
+
+	to->size = from->size;
+
+	return 0;
+}
+
+static void bitflip_filter_free(git_filter *f)
+{
+	git__free(f);
+}
+
+static git_filter *create_bitflip_filter(void)
+{
+	git_filter *filter = git__calloc(1, sizeof(git_filter));
+	cl_assert(filter);
+
+	filter->version = GIT_FILTER_VERSION;
+	filter->attributes = "+bitflip";
+	filter->shutdown = bitflip_filter_free;
+	filter->apply = bitflip_filter_apply;
+
+	return filter;
+}
+
+
+static int reverse_filter_apply(
+	git_filter     *self,
+	void          **payload,
+	git_buf        *to,
+	const git_buf  *from,
+	const git_filter_source *source)
+{
+	const unsigned char *src = (const unsigned char *)from->ptr;
+	const unsigned char *end = src + from->size;
+	unsigned char *dst;
+
+	GIT_UNUSED(self); GIT_UNUSED(payload); GIT_UNUSED(source);
+
+	/* verify that attribute path match worked as expected */
+	cl_assert_equal_i(
+		0, git__strncmp("hero", git_filter_source_path(source), 4));
+
+	if (!from->size)
+		return 0;
+
+	cl_git_pass(git_buf_grow(to, from->size));
+
+	dst = (unsigned char *)to->ptr + from->size - 1;
+
+	while (src < end)
+		*dst-- = *src++;
+
+	to->size = from->size;
+
+	return 0;
+}
+
+static void reverse_filter_free(git_filter *f)
+{
+	git__free(f);
+}
+
+static git_filter *create_reverse_filter(const char *attrs)
+{
+	git_filter *filter = git__calloc(1, sizeof(git_filter));
+	cl_assert(filter);
+
+	filter->version = GIT_FILTER_VERSION;
+	filter->attributes = attrs;
+	filter->shutdown = reverse_filter_free;
+	filter->apply = reverse_filter_apply;
+
+	return filter;
+}
+
+static void register_custom_filters(void)
+{
+	static int filters_registered = 0;
+
+	if (!filters_registered) {
+		cl_git_pass(git_filter_register(
+			"bitflip", create_bitflip_filter(), BITFLIP_FILTER_PRIORITY));
+
+		cl_git_pass(git_filter_register(
+			"reverse", create_reverse_filter("+reverse"),
+			REVERSE_FILTER_PRIORITY));
+
+		/* re-register reverse filter with standard filter=xyz priority */
+		cl_git_pass(git_filter_register(
+			"pre-reverse",
+			create_reverse_filter("+prereverse"),
+			GIT_FILTER_DRIVER_PRIORITY));
+
+		filters_registered = 1;
+	}
+}
+
+
+void test_filter_custom__to_odb(void)
+{
+	git_filter_list *fl;
+	git_buf out = { 0 };
+	git_buf in = GIT_BUF_INIT_CONST(workdir_data, strlen(workdir_data));
+
+	cl_git_pass(git_filter_list_load(
+		&fl, g_repo, NULL, "herofile", GIT_FILTER_TO_ODB, 0));
+
+	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
+
+	cl_assert_equal_i(BITFLIPPED_AND_REVERSED_DATA_LEN, out.size);
+
+	cl_assert_equal_i(
+		0, memcmp(bitflipped_and_reversed_data, out.ptr, out.size));
+
+	git_filter_list_free(fl);
+	git_buf_free(&out);
+}
+
+void test_filter_custom__to_workdir(void)
+{
+	git_filter_list *fl;
+	git_buf out = { 0 };
+	git_buf in = GIT_BUF_INIT_CONST(
+		bitflipped_and_reversed_data, BITFLIPPED_AND_REVERSED_DATA_LEN);
+
+	cl_git_pass(git_filter_list_load(
+		&fl, g_repo, NULL, "herofile", GIT_FILTER_TO_WORKTREE, 0));
+
+	cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
+
+	cl_assert_equal_i(strlen(workdir_data), out.size);
+
+	cl_assert_equal_i(
+		0, memcmp(workdir_data, out.ptr, out.size));
+
+	git_filter_list_free(fl);
+	git_buf_free(&out);
+}
+
+void test_filter_custom__can_register_a_custom_filter_in_the_repository(void)
+{
+	git_filter_list *fl;
+
+	cl_git_pass(git_filter_list_load(
+		&fl, g_repo, NULL, "herofile", GIT_FILTER_TO_WORKTREE, 0));
+	/* expect: bitflip, reverse, crlf */
+	cl_assert_equal_sz(3, git_filter_list_length(fl));
+	git_filter_list_free(fl);
+
+	cl_git_pass(git_filter_list_load(
+		&fl, g_repo, NULL, "herocorp", GIT_FILTER_TO_WORKTREE, 0));
+	/* expect: bitflip, reverse - possibly crlf depending on global config */
+	{
+		size_t flen = git_filter_list_length(fl);
+		cl_assert(flen == 2 || flen == 3);
+	}
+	git_filter_list_free(fl);
+
+	cl_git_pass(git_filter_list_load(
+		&fl, g_repo, NULL, "hero.bin", GIT_FILTER_TO_WORKTREE, 0));
+	/* expect: bitflip, reverse */
+	cl_assert_equal_sz(2, git_filter_list_length(fl));
+	git_filter_list_free(fl);
+
+	cl_git_pass(git_filter_list_load(
+		&fl, g_repo, NULL, "heroflip", GIT_FILTER_TO_WORKTREE, 0));
+	/* expect: bitflip (because of -reverse) */
+	cl_assert_equal_sz(1, git_filter_list_length(fl));
+	git_filter_list_free(fl);
+
+	cl_git_pass(git_filter_list_load(
+		&fl, g_repo, NULL, "doesntapplytome.bin",
+		GIT_FILTER_TO_WORKTREE, 0));
+	/* expect: none */
+	cl_assert_equal_sz(0, git_filter_list_length(fl));
+	git_filter_list_free(fl);
+}
+
+void test_filter_custom__order_dependency(void)
+{
+	git_index *index;
+	git_blob *blob;
+	git_buf buf = { 0 };
+
+	/* so if ident and reverse are used together, an interesting thing
+	 * happens - a reversed "$Id$" string is no longer going to trigger
+	 * ident correctly.  When checking out, the filters should be applied
+	 * in order CLRF, then ident, then reverse, so ident expansion should
+	 * work correctly.  On check in, the content should be reversed, then
+	 * ident, then CRLF filtered.  Let's make sure that works...
+	 */
+
+	cl_git_mkfile(
+		"empty_standard_repo/.gitattributes",
+		"hero.*.rev-ident text ident prereverse eol=lf\n");
+
+	cl_git_mkfile(
+		"empty_standard_repo/hero.1.rev-ident",
+		"This is a test\n$Id$\nHave fun!\n");
+
+	cl_git_mkfile(
+		"empty_standard_repo/hero.2.rev-ident",
+		"Another test\n$dI$\nCrazy!\n");
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_add_bypath(index, "hero.1.rev-ident"));
+	cl_git_pass(git_index_add_bypath(index, "hero.2.rev-ident"));
+	cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "Filter chains\n");
+	git_index_free(index);
+
+	cl_git_pass(git_blob_lookup(&blob, g_repo,
+		& git_index_get_bypath(index, "hero.1.rev-ident", 0)->id));
+	cl_assert_equal_s(
+		"\n!nuf evaH\n$dI$\ntset a si sihT", git_blob_rawcontent(blob));
+	cl_git_pass(git_blob_filtered_content(&buf, blob, "hero.1.rev-ident", 0));
+	/* no expansion because id was reversed at checkin and now at ident
+	 * time, reverse is not applied yet */
+	cl_assert_equal_s(
+		"This is a test\n$Id$\nHave fun!\n", buf.ptr);
+	git_blob_free(blob);
+
+	cl_git_pass(git_blob_lookup(&blob, g_repo,
+		& git_index_get_bypath(index, "hero.2.rev-ident", 0)->id));
+	cl_assert_equal_s(
+		"\n!yzarC\n$Id$\ntset rehtonA", git_blob_rawcontent(blob));
+	cl_git_pass(git_blob_filtered_content(&buf, blob, "hero.2.rev-ident", 0));
+	/* expansion because reverse was applied at checkin and at ident time,
+	 * reverse is not applied yet */
+	cl_assert_equal_s(
+		"Another test\n$ 59001fe193103b1016b27027c0c827d036fd0ac8 :dI$\nCrazy!\n", buf.ptr);
+	cl_assert_equal_i(0, git_oid_strcmp(
+		git_blob_id(blob), "8ca0df630d728c0c72072b6101b301391ef10095"));
+	git_blob_free(blob);
+
+	git_buf_free(&buf);
+}
+
+void test_filter_custom__filter_registry_failure_cases(void)
+{
+	git_filter fake = { GIT_FILTER_VERSION, 0 };
+
+	cl_assert_equal_i(GIT_EEXISTS, git_filter_register("bitflip", &fake, 0));
+
+	cl_git_fail(git_filter_unregister(GIT_FILTER_CRLF));
+	cl_git_fail(git_filter_unregister(GIT_FILTER_IDENT));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_filter_unregister("not-a-filter"));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/file.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/file.c
new file mode 100755
index 0000000..599f4e5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/file.c
@@ -0,0 +1,99 @@
+#include "clar_libgit2.h"
+#include "git2/sys/filter.h"
+#include "crlf.h"
+#include "buffer.h"
+
+static git_repository *g_repo = NULL;
+
+void test_filter_file__initialize(void)
+{
+	git_reference *head_ref;
+	git_commit *head;
+
+	g_repo = cl_git_sandbox_init("crlf");
+
+	cl_git_mkfile("crlf/.gitattributes",
+		"*.txt text\n*.bin binary\n*.crlf text eol=crlf\n*.lf text eol=lf\n");
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	cl_git_pass(git_repository_head(&head_ref, g_repo));
+	cl_git_pass(git_reference_peel((git_object **)&head, head_ref, GIT_OBJ_COMMIT));
+	cl_git_pass(git_reset(g_repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	git_commit_free(head);
+	git_reference_free(head_ref);
+}
+
+void test_filter_file__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_filter_file__apply(void)
+{
+	git_filter_list *fl;
+	git_filter *crlf;
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_filter_list_new(
+		&fl, g_repo, GIT_FILTER_TO_ODB, 0));
+
+	crlf = git_filter_lookup(GIT_FILTER_CRLF);
+	cl_assert(crlf != NULL);
+
+	cl_git_pass(git_filter_list_push(fl, crlf, NULL));
+
+	cl_git_pass(git_filter_list_apply_to_file(&buf, fl, g_repo, "all-crlf"));
+	cl_assert_equal_s("crlf\ncrlf\ncrlf\ncrlf\n", buf.ptr);
+
+	git_buf_free(&buf);
+	git_filter_list_free(fl);
+}
+
+struct buf_writestream {
+	git_writestream base;
+	git_buf buf;
+};
+
+int buf_writestream_write(git_writestream *s, const char *buf, size_t len)
+{
+	struct buf_writestream *stream = (struct buf_writestream *)s;
+	return git_buf_put(&stream->buf, buf, len);
+}
+
+int buf_writestream_close(git_writestream *s)
+{
+	GIT_UNUSED(s);
+	return 0;
+}
+
+void buf_writestream_free(git_writestream *s)
+{
+	struct buf_writestream *stream = (struct buf_writestream *)s;
+	git_buf_free(&stream->buf);
+}
+
+void test_filter_file__apply_stream(void)
+{
+	git_filter_list *fl;
+	git_filter *crlf;
+	struct buf_writestream write_target = { {
+		buf_writestream_write,
+		buf_writestream_close,
+		buf_writestream_free } };
+
+	cl_git_pass(git_filter_list_new(
+		&fl, g_repo, GIT_FILTER_TO_ODB, 0));
+
+	crlf = git_filter_lookup(GIT_FILTER_CRLF);
+	cl_assert(crlf != NULL);
+
+	cl_git_pass(git_filter_list_push(fl, crlf, NULL));
+
+	cl_git_pass(git_filter_list_stream_file(fl, g_repo, "all-crlf", &write_target.base));
+	cl_assert_equal_s("crlf\ncrlf\ncrlf\ncrlf\n", write_target.buf.ptr);
+
+	git_filter_list_free(fl);
+	write_target.base.free(&write_target.base);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/ident.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/ident.c
new file mode 100755
index 0000000..c54b621
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/ident.c
@@ -0,0 +1,133 @@
+#include "clar_libgit2.h"
+#include "git2/sys/filter.h"
+
+static git_repository *g_repo = NULL;
+
+void test_filter_ident__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("crlf");
+}
+
+void test_filter_ident__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static void add_blob_and_filter(
+	const char *data,
+	git_filter_list *fl,
+	const char *expected)
+{
+	git_oid id;
+	git_blob *blob;
+	git_buf out = { 0 };
+
+	cl_git_mkfile("crlf/identtest", data);
+	cl_git_pass(git_blob_create_fromworkdir(&id, g_repo, "identtest"));
+	cl_git_pass(git_blob_lookup(&blob, g_repo, &id));
+
+	cl_git_pass(git_filter_list_apply_to_blob(&out, fl, blob));
+
+	cl_assert_equal_s(expected, out.ptr);
+
+	git_blob_free(blob);
+	git_buf_free(&out);
+}
+
+void test_filter_ident__to_worktree(void)
+{
+	git_filter_list *fl;
+	git_filter *ident;
+
+	cl_git_pass(git_filter_list_new(
+		&fl, g_repo, GIT_FILTER_TO_WORKTREE, 0));
+
+	ident = git_filter_lookup(GIT_FILTER_IDENT);
+	cl_assert(ident != NULL);
+
+	cl_git_pass(git_filter_list_push(fl, ident, NULL));
+
+	add_blob_and_filter(
+		"Hello\n$Id$\nFun stuff\n", fl,
+		"Hello\n$Id: b69e2387aafcaf73c4de5b9ab59abe27fdadee30 $\nFun stuff\n");
+	add_blob_and_filter(
+		"Hello\n$Id: Junky$\nFun stuff\n", fl,
+		"Hello\n$Id: 45cd107a7102911cb2a7df08404674327fa050b9 $\nFun stuff\n");
+	add_blob_and_filter(
+		"$Id$\nAt the start\n", fl,
+		"$Id: b13415c767abc196fb95bd17070e8c1113e32160 $\nAt the start\n");
+	add_blob_and_filter(
+		"At the end\n$Id$", fl,
+		"At the end\n$Id: 1344925c6bc65b34c5a7b50f86bf688e48e9a272 $");
+	add_blob_and_filter(
+		"$Id$", fl,
+		"$Id: b3f5ebfb5843bc43ceecff6d4f26bb37c615beb1 $");
+	add_blob_and_filter(
+		"$Id: Some sort of junk goes here$", fl,
+		"$Id: ab2dd3853c7c9a4bff55aca2bea077a73c32ac06 $");
+
+	add_blob_and_filter("$Id: ", fl, "$Id: ");
+	add_blob_and_filter("$Id", fl, "$Id");
+	add_blob_and_filter("$I", fl, "$I");
+	add_blob_and_filter("Id$", fl, "Id$");
+
+	git_filter_list_free(fl);
+}
+
+void test_filter_ident__to_odb(void)
+{
+	git_filter_list *fl;
+	git_filter *ident;
+
+	cl_git_pass(git_filter_list_new(
+		&fl, g_repo, GIT_FILTER_TO_ODB, 0));
+
+	ident = git_filter_lookup(GIT_FILTER_IDENT);
+	cl_assert(ident != NULL);
+
+	cl_git_pass(git_filter_list_push(fl, ident, NULL));
+
+	add_blob_and_filter(
+		"Hello\n$Id$\nFun stuff\n",
+		fl, "Hello\n$Id$\nFun stuff\n");
+	add_blob_and_filter(
+		"Hello\n$Id: b69e2387aafcaf73c4de5b9ab59abe27fdadee30$\nFun stuff\n",
+		fl, "Hello\n$Id$\nFun stuff\n");
+	add_blob_and_filter(
+		"Hello\n$Id: Any junk you may have left here$\nFun stuff\n",
+		fl, "Hello\n$Id$\nFun stuff\n");
+	add_blob_and_filter(
+		"Hello\n$Id:$\nFun stuff\n",
+		fl, "Hello\n$Id$\nFun stuff\n");
+	add_blob_and_filter(
+		"Hello\n$Id:x$\nFun stuff\n",
+		fl, "Hello\n$Id$\nFun stuff\n");
+
+	add_blob_and_filter(
+		"$Id$\nAt the start\n", fl, "$Id$\nAt the start\n");
+	add_blob_and_filter(
+		"$Id: lots of random text that should be removed from here$\nAt the start\n", fl, "$Id$\nAt the start\n");
+	add_blob_and_filter(
+		"$Id: lots of random text that should not be removed without a terminator\nAt the start\n", fl, "$Id: lots of random text that should not be removed without a terminator\nAt the start\n");
+
+	add_blob_and_filter(
+		"At the end\n$Id$", fl, "At the end\n$Id$");
+	add_blob_and_filter(
+		"At the end\n$Id:$", fl, "At the end\n$Id$");
+	add_blob_and_filter(
+		"At the end\n$Id:asdfasdf$", fl, "At the end\n$Id$");
+	add_blob_and_filter(
+		"At the end\n$Id", fl, "At the end\n$Id");
+	add_blob_and_filter(
+		"At the end\n$IddI", fl, "At the end\n$IddI");
+
+	add_blob_and_filter("$Id$", fl, "$Id$");
+	add_blob_and_filter("$Id: any$", fl, "$Id$");
+	add_blob_and_filter("$Id: any long stuff goes here you see$", fl, "$Id$");
+	add_blob_and_filter("$Id: ", fl, "$Id: ");
+	add_blob_and_filter("$Id", fl, "$Id");
+	add_blob_and_filter("$I", fl, "$I");
+	add_blob_and_filter("Id$", fl, "Id$");
+
+	git_filter_list_free(fl);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/query.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/query.c
new file mode 100755
index 0000000..6889d71
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/query.c
@@ -0,0 +1,91 @@
+#include "clar_libgit2.h"
+#include "git2/sys/filter.h"
+#include "crlf.h"
+#include "buffer.h"
+
+static git_repository *g_repo = NULL;
+
+void test_filter_query__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("crlf");
+
+	cl_git_mkfile("crlf/.gitattributes",
+		"*.txt text\n"
+		"*.bin binary\n"
+		"*.crlf text eol=crlf\n"
+		"*.lf text eol=lf\n"
+		"*.binident binary ident\n"
+		"*.ident text ident\n"
+		"*.identcrlf ident text eol=crlf\n"
+		"*.identlf ident text eol=lf\n"
+		"*.custom custom ident text\n");
+}
+
+void test_filter_query__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static int filter_for(const char *filename, const char *filter)
+{
+	git_filter_list *fl;
+	int filtered;
+
+	cl_git_pass(git_filter_list_load(
+		&fl, g_repo, NULL, filename, GIT_FILTER_TO_WORKTREE, 0));
+	filtered = git_filter_list_contains(fl, filter);
+	git_filter_list_free(fl);
+
+	return filtered;
+}
+
+void test_filter_query__filters(void)
+{
+	cl_assert_equal_i(1, filter_for("text.txt", "crlf"));
+	cl_assert_equal_i(0, filter_for("binary.bin", "crlf"));
+
+	cl_assert_equal_i(1, filter_for("foo.lf", "crlf"));
+	cl_assert_equal_i(0, filter_for("foo.lf", "ident"));
+
+	cl_assert_equal_i(1, filter_for("id.ident", "crlf"));
+	cl_assert_equal_i(1, filter_for("id.ident", "ident"));
+
+	cl_assert_equal_i(0, filter_for("id.binident", "crlf"));
+	cl_assert_equal_i(1, filter_for("id.binident", "ident"));
+}
+
+void test_filter_query__autocrlf_true_implies_crlf(void)
+{
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+	cl_assert_equal_i(1, filter_for("not_in_gitattributes", "crlf"));
+	cl_assert_equal_i(1, filter_for("foo.txt", "crlf"));
+	cl_assert_equal_i(0, filter_for("foo.bin", "crlf"));
+	cl_assert_equal_i(1, filter_for("foo.lf", "crlf"));
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", false);
+	cl_assert_equal_i(0, filter_for("not_in_gitattributes", "crlf"));
+	cl_assert_equal_i(1, filter_for("foo.txt", "crlf"));
+	cl_assert_equal_i(0, filter_for("foo.bin", "crlf"));
+	cl_assert_equal_i(1, filter_for("foo.lf", "crlf"));
+}
+
+void test_filter_query__unknown(void)
+{
+	cl_assert_equal_i(1, filter_for("foo.custom", "crlf"));
+	cl_assert_equal_i(1, filter_for("foo.custom", "ident"));
+	cl_assert_equal_i(0, filter_for("foo.custom", "custom"));
+}
+
+void test_filter_query__custom(void)
+{
+	git_filter custom = { GIT_FILTER_VERSION };
+
+	cl_git_pass(git_filter_register(
+		"custom", &custom, 42));
+
+	cl_assert_equal_i(1, filter_for("foo.custom", "crlf"));
+	cl_assert_equal_i(1, filter_for("foo.custom", "ident"));
+	cl_assert_equal_i(1, filter_for("foo.custom", "custom"));
+
+	git_filter_unregister("custom");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/stream.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/stream.c
new file mode 100755
index 0000000..6bf540c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/filter/stream.c
@@ -0,0 +1,216 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "blob.h"
+#include "filter.h"
+#include "buf_text.h"
+#include "git2/sys/filter.h"
+#include "git2/sys/repository.h"
+
+static git_repository *g_repo = NULL;
+
+static git_filter *create_compress_filter(void);
+static git_filter *compress_filter;
+
+void test_filter_stream__initialize(void)
+{
+	compress_filter = create_compress_filter();
+
+	cl_git_pass(git_filter_register("compress", compress_filter, 50));
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+}
+
+void test_filter_stream__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+	g_repo = NULL;
+
+	git_filter_unregister("compress");
+	git__free(compress_filter);
+}
+
+#define CHUNKSIZE 10240
+
+struct compress_stream {
+	git_writestream parent;
+	git_writestream *next;
+	git_filter_mode_t mode;
+	char current;
+	size_t current_chunk;
+};
+
+static int compress_stream_write__deflated(struct compress_stream *stream, const char *buffer, size_t len)
+{
+	size_t idx = 0;
+
+	while (len > 0) {
+		size_t chunkremain, chunksize;
+
+		if (stream->current_chunk == 0)
+			stream->current = buffer[idx];
+
+		chunkremain = CHUNKSIZE - stream->current_chunk;
+		chunksize = min(chunkremain, len);
+
+		stream->current_chunk += chunksize;
+		len -= chunksize;
+		idx += chunksize;
+
+		if (stream->current_chunk == CHUNKSIZE) {
+			cl_git_pass(stream->next->write(stream->next, &stream->current, 1));
+			stream->current_chunk = 0;
+		}
+	}
+
+	return 0;
+}
+
+static int compress_stream_write__inflated(struct compress_stream *stream, const char *buffer, size_t len)
+{
+	char inflated[CHUNKSIZE];
+	size_t i, j;
+
+	for (i = 0; i < len; i++) {
+		for (j = 0; j < CHUNKSIZE; j++)
+			inflated[j] = buffer[i];
+
+		cl_git_pass(stream->next->write(stream->next, inflated, CHUNKSIZE));
+	}
+
+	return 0;
+}
+
+static int compress_stream_write(git_writestream *s, const char *buffer, size_t len)
+{
+	struct compress_stream *stream = (struct compress_stream *)s;
+
+	return (stream->mode == GIT_FILTER_TO_ODB) ?
+		compress_stream_write__deflated(stream, buffer, len) :
+		compress_stream_write__inflated(stream, buffer, len);
+}
+
+static int compress_stream_close(git_writestream *s)
+{
+	struct compress_stream *stream = (struct compress_stream *)s;
+	cl_assert_equal_i(0, stream->current_chunk);
+	stream->next->close(stream->next);
+	return 0;
+}
+
+static void compress_stream_free(git_writestream *stream)
+{
+	git__free(stream);
+}
+
+static int compress_filter_stream_init(
+	git_writestream **out,
+	git_filter *self,
+	void **payload,
+	const git_filter_source *src,
+	git_writestream *next)
+{
+	struct compress_stream *stream = git__calloc(1, sizeof(struct compress_stream));
+	cl_assert(stream);
+
+	GIT_UNUSED(self);
+	GIT_UNUSED(payload);
+
+	stream->parent.write = compress_stream_write;
+	stream->parent.close = compress_stream_close;
+	stream->parent.free = compress_stream_free;
+	stream->next = next;
+	stream->mode = git_filter_source_mode(src);
+
+	*out = (git_writestream *)stream;
+	return 0;
+}
+
+git_filter *create_compress_filter(void)
+{
+	git_filter *filter = git__calloc(1, sizeof(git_filter));
+	cl_assert(filter);
+
+	filter->version = GIT_FILTER_VERSION;
+	filter->attributes = "+compress";
+	filter->stream = compress_filter_stream_init;
+
+	return filter;
+}
+
+static void writefile(const char *filename, size_t numchunks)
+{
+	git_buf path = GIT_BUF_INIT;
+	char buf[CHUNKSIZE];
+	size_t i = 0, j = 0;
+	int fd;
+
+	cl_git_pass(git_buf_joinpath(&path, "empty_standard_repo", filename));
+
+	fd = p_open(path.ptr, O_RDWR|O_CREAT, 0666);
+	cl_assert(fd >= 0);
+
+	for (i = 0; i < numchunks; i++) {
+		for (j = 0; j < CHUNKSIZE; j++) {
+			buf[j] = i % 256;
+		}
+
+		cl_git_pass(p_write(fd, buf, CHUNKSIZE));
+	}
+	p_close(fd);
+
+	git_buf_free(&path);
+}
+
+static void test_stream(size_t numchunks)
+{
+	git_index *index;
+	const git_index_entry *entry;
+	git_blob *blob;
+	struct stat st;
+	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_mkfile(
+		"empty_standard_repo/.gitattributes",
+		"* compress\n");
+
+	/* write a file to disk */
+	writefile("streamed_file", numchunks);
+
+	/* place it in the index */
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_add_bypath(index, "streamed_file"));
+	cl_git_pass(git_index_write(index));
+
+	/* ensure it was appropriately compressed */
+	cl_assert(entry = git_index_get_bypath(index, "streamed_file", 0));
+
+	cl_git_pass(git_blob_lookup(&blob, g_repo, &entry->id));
+	cl_assert_equal_i(numchunks, git_blob_rawsize(blob));
+
+	/* check the file back out */
+	cl_must_pass(p_unlink("empty_standard_repo/streamed_file"));
+	cl_git_pass(git_checkout_index(g_repo, index, &checkout_opts));
+
+	/* ensure it was decompressed */
+	cl_must_pass(p_stat("empty_standard_repo/streamed_file", &st));
+	cl_assert_equal_sz((numchunks * CHUNKSIZE), st.st_size);
+
+	git_index_free(index);
+	git_blob_free(blob);
+}
+
+/* write a 50KB file through the "compression" stream */
+void test_filter_stream__smallfile(void)
+{
+	test_stream(5);
+}
+
+/* optionally write a 500 MB file through the compression stream */
+void test_filter_stream__bigfile(void)
+{
+	if (!cl_getenv("GITTEST_INVASIVE_FS_SIZE"))
+		cl_skip();
+
+	test_stream(51200);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/generate.py b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/generate.py
new file mode 100755
index 0000000..587efb5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/generate.py
@@ -0,0 +1,244 @@
+#!/usr/bin/env python
+#
+# Copyright (c) Vicent Marti. All rights reserved.
+#
+# This file is part of clar, distributed under the ISC license.
+# For full terms see the included COPYING file.
+#
+
+from __future__ import with_statement
+from string import Template
+import re, fnmatch, os, codecs, pickle
+
+class Module(object):
+    class Template(object):
+        def __init__(self, module):
+            self.module = module
+
+        def _render_callback(self, cb):
+            if not cb:
+                return '    { NULL, NULL }'
+            return '    { "%s", &%s }' % (cb['short_name'], cb['symbol'])
+
+    class DeclarationTemplate(Template):
+        def render(self):
+            out = "\n".join("extern %s;" % cb['declaration'] for cb in self.module.callbacks) + "\n"
+
+            if self.module.initialize:
+                out += "extern %s;\n" % self.module.initialize['declaration']
+
+            if self.module.cleanup:
+                out += "extern %s;\n" % self.module.cleanup['declaration']
+
+            return out
+
+    class CallbacksTemplate(Template):
+        def render(self):
+            out = "static const struct clar_func _clar_cb_%s[] = {\n" % self.module.name
+            out += ",\n".join(self._render_callback(cb) for cb in self.module.callbacks)
+            out += "\n};\n"
+            return out
+
+    class InfoTemplate(Template):
+        def render(self):
+            return Template(
+            r"""
+    {
+        "${clean_name}",
+    ${initialize},
+    ${cleanup},
+        ${cb_ptr}, ${cb_count}, ${enabled}
+    }"""
+            ).substitute(
+                clean_name = self.module.clean_name(),
+                initialize = self._render_callback(self.module.initialize),
+                cleanup = self._render_callback(self.module.cleanup),
+                cb_ptr = "_clar_cb_%s" % self.module.name,
+                cb_count = len(self.module.callbacks),
+                enabled = int(self.module.enabled)
+            )
+
+    def __init__(self, name):
+        self.name = name
+
+        self.mtime = 0
+        self.enabled = True
+        self.modified = False
+
+    def clean_name(self):
+        return self.name.replace("_", "::")
+
+    def _skip_comments(self, text):
+        SKIP_COMMENTS_REGEX = re.compile(
+            r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
+            re.DOTALL | re.MULTILINE)
+
+        def _replacer(match):
+            s = match.group(0)
+            return "" if s.startswith('/') else s
+
+        return re.sub(SKIP_COMMENTS_REGEX, _replacer, text)
+
+    def parse(self, contents):
+        TEST_FUNC_REGEX = r"^(void\s+(test_%s__(\w+))\s*\(\s*void\s*\))\s*\{"
+
+        contents = self._skip_comments(contents)
+        regex = re.compile(TEST_FUNC_REGEX % self.name, re.MULTILINE)
+
+        self.callbacks = []
+        self.initialize = None
+        self.cleanup = None
+
+        for (declaration, symbol, short_name) in regex.findall(contents):
+            data = {
+                "short_name" : short_name,
+                "declaration" : declaration,
+                "symbol" : symbol
+            }
+
+            if short_name == 'initialize':
+                self.initialize = data
+            elif short_name == 'cleanup':
+                self.cleanup = data
+            else:
+                self.callbacks.append(data)
+
+        return self.callbacks != []
+
+    def refresh(self, path):
+        self.modified = False
+
+        try:
+            st = os.stat(path)
+
+            # Not modified
+            if st.st_mtime == self.mtime:
+                return True
+
+            self.modified = True
+            self.mtime = st.st_mtime
+
+            with codecs.open(path, encoding='utf-8') as fp:
+                raw_content = fp.read()
+
+        except IOError:
+            return False
+
+        return self.parse(raw_content)
+
+class TestSuite(object):
+
+    def __init__(self, path):
+        self.path = path
+
+    def should_generate(self, path):
+        if not os.path.isfile(path):
+            return True
+
+        if any(module.modified for module in self.modules.values()):
+            return True
+
+        return False
+
+    def find_modules(self):
+        modules = []
+        for root, _, files in os.walk(self.path):
+            module_root = root[len(self.path):]
+            module_root = [c for c in module_root.split(os.sep) if c]
+
+            tests_in_module = fnmatch.filter(files, "*.c")
+
+            for test_file in tests_in_module:
+                full_path = os.path.join(root, test_file)
+                module_name = "_".join(module_root + [test_file[:-2]]).replace("-", "_")
+
+                modules.append((full_path, module_name))
+
+        return modules
+
+    def load_cache(self):
+        path = os.path.join(self.path, '.clarcache')
+        cache = {}
+
+        try:
+            fp = open(path, 'rb')
+            cache = pickle.load(fp)
+            fp.close()
+        except (IOError, ValueError):
+            pass
+
+        return cache
+
+    def save_cache(self):
+        path = os.path.join(self.path, '.clarcache')
+        with open(path, 'wb') as cache:
+            pickle.dump(self.modules, cache)
+
+    def load(self, force = False):
+        module_data = self.find_modules()
+        self.modules = {} if force else self.load_cache()
+
+        for path, name in module_data:
+            if name not in self.modules:
+                self.modules[name] = Module(name)
+
+            if not self.modules[name].refresh(path):
+                del self.modules[name]
+
+    def disable(self, excluded):
+        for exclude in excluded:
+            for module in self.modules.values():
+                name = module.clean_name()
+                if name.startswith(exclude):
+                    module.enabled = False
+                    module.modified = True
+
+    def suite_count(self):
+        return len(self.modules)
+
+    def callback_count(self):
+        return sum(len(module.callbacks) for module in self.modules.values())
+
+    def write(self):
+        output = os.path.join(self.path, 'clar.suite')
+
+        if not self.should_generate(output):
+            return False
+
+        with open(output, 'w') as data:
+            for module in self.modules.values():
+                t = Module.DeclarationTemplate(module)
+                data.write(t.render())
+
+            for module in self.modules.values():
+                t = Module.CallbacksTemplate(module)
+                data.write(t.render())
+
+            suites = "static struct clar_suite _clar_suites[] = {" + ','.join(
+                Module.InfoTemplate(module).render() for module in sorted(self.modules.values(), key=lambda module: module.name)
+            ) + "\n};\n"
+
+            data.write(suites)
+
+            data.write("static const size_t _clar_suite_count = %d;\n" % self.suite_count())
+            data.write("static const size_t _clar_callback_count = %d;\n" % self.callback_count())
+
+        self.save_cache()
+        return True
+
+if __name__ == '__main__':
+    from optparse import OptionParser
+
+    parser = OptionParser()
+    parser.add_option('-f', '--force', action="store_true", dest='force', default=False)
+    parser.add_option('-x', '--exclude', dest='excluded', action='append', default=[])
+
+    options, args = parser.parse_args()
+
+    for path in args or ['.']:
+        suite = TestSuite(path)
+        suite.load(options.force)
+        suite.disable(options.excluded)
+        if suite.write():
+            print("Written `clar.suite` (%d tests in %d suites)" % (suite.callback_count(), suite.suite_count()))
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/generate_crlf.sh b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/generate_crlf.sh
new file mode 100755
index 0000000..d3fd1bb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/generate_crlf.sh
@@ -0,0 +1,73 @@
+#!/usr/bin/env bash
+
+set -e
+
+if [ "$1" == "" -o "$2" == "" ]; then
+	echo "usage: $0 crlfrepo directory [tempdir]"
+	exit 1
+fi
+
+input=$1
+output=$2
+tempdir=$3
+
+set -u
+
+create_repo() {
+	local input=$1
+	local output=$2
+	local tempdir=$3
+	local systype=$4
+	local autocrlf=$5
+	local attr=$6
+
+	local worktree="${output}/${systype}/autocrlf_${autocrlf}"
+
+	if [ "$attr" != "" ]; then
+		local attrdir=`echo $attr | sed -e "s/ /,/g" | sed -e "s/=/_/g"`
+		worktree="${worktree},${attrdir}"
+	fi
+
+	if [ "$tempdir" = "" ]; then
+		local gitdir="${worktree}/.git"
+	else
+		local gitdir="${tempdir}/generate_crlf_${RANDOM}"
+	fi
+
+	echo "Creating ${worktree}"
+	mkdir -p "${worktree}"
+
+	git clone --no-checkout --quiet --bare "${input}/.gitted" "${gitdir}"
+	git --work-tree="${worktree}" --git-dir="${gitdir}" config core.autocrlf ${autocrlf}
+
+	if [ "$attr" != "" ]; then
+		echo "* ${attr}" >> "${worktree}/.gitattributes"
+	fi
+
+	git --work-tree="${worktree}" --git-dir="${gitdir}" checkout HEAD
+
+	if [ "$attr" != "" ]; then
+		rm "${worktree}/.gitattributes"
+	fi
+
+	if [ "$tempdir" != "" ]; then
+		rm -rf "${gitdir}"
+	fi
+}
+
+if [[ `uname -s` == MINGW* ]]; then
+	systype="windows"
+else
+	systype="posix"
+fi
+
+for autocrlf in true false input; do
+	for attr in "" text text=auto -text crlf -crlf eol=lf eol=crlf \
+		"text eol=lf" "text eol=crlf" \
+		"text=auto eol=lf" "text=auto eol=crlf"; do
+
+		create_repo "${input}" "${output}" "${tempdir}" \
+			"${systype}" "${autocrlf}" "${attr}"
+	done
+done
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/graph/descendant_of.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/graph/descendant_of.c
new file mode 100755
index 0000000..8e9952a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/graph/descendant_of.c
@@ -0,0 +1,55 @@
+#include "clar_libgit2.h"
+
+static git_repository *_repo;
+static git_commit *commit;
+
+void test_graph_descendant_of__initialize(void)
+{
+	git_oid oid;
+
+	cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git")));
+
+	git_oid_fromstr(&oid, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	cl_git_pass(git_commit_lookup(&commit, _repo, &oid));
+}
+
+void test_graph_descendant_of__cleanup(void)
+{
+	git_commit_free(commit);
+	commit = NULL;
+
+	git_repository_free(_repo);
+	_repo = NULL;
+}
+
+void test_graph_descendant_of__returns_correct_result(void)
+{
+	git_commit *other;
+
+	cl_assert_equal_i(0, git_graph_descendant_of(_repo, git_commit_id(commit), git_commit_id(commit)));
+
+
+	cl_git_pass(git_commit_nth_gen_ancestor(&other, commit, 1));
+
+	cl_assert_equal_i(1, git_graph_descendant_of(_repo, git_commit_id(commit), git_commit_id(other)));
+	cl_assert_equal_i(0, git_graph_descendant_of(_repo, git_commit_id(other), git_commit_id(commit)));
+
+	git_commit_free(other);
+
+
+	cl_git_pass(git_commit_nth_gen_ancestor(&other, commit, 3));
+
+	cl_assert_equal_i(1, git_graph_descendant_of(_repo, git_commit_id(commit), git_commit_id(other)));
+	cl_assert_equal_i(0, git_graph_descendant_of(_repo, git_commit_id(other), git_commit_id(commit)));
+
+	git_commit_free(other);
+
+}
+
+void test_graph_descendant_of__nopath(void)
+{
+	git_oid oid;
+
+	git_oid_fromstr(&oid, "e90810b8df3e80c413d903f631643c716887138d");
+	cl_assert_equal_i(0, git_graph_descendant_of(_repo, git_commit_id(commit), &oid));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/addall.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/addall.c
new file mode 100755
index 0000000..9ddb27f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/addall.c
@@ -0,0 +1,446 @@
+#include "clar_libgit2.h"
+#include "../status/status_helpers.h"
+#include "posix.h"
+#include "fileops.h"
+
+static git_repository *g_repo = NULL;
+#define TEST_DIR "addall"
+
+void test_index_addall__initialize(void)
+{
+}
+
+void test_index_addall__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+#define STATUS_INDEX_FLAGS \
+	(GIT_STATUS_INDEX_NEW | GIT_STATUS_INDEX_MODIFIED | \
+	 GIT_STATUS_INDEX_DELETED | GIT_STATUS_INDEX_RENAMED | \
+	 GIT_STATUS_INDEX_TYPECHANGE)
+
+#define STATUS_WT_FLAGS \
+	(GIT_STATUS_WT_NEW | GIT_STATUS_WT_MODIFIED | \
+	 GIT_STATUS_WT_DELETED | GIT_STATUS_WT_TYPECHANGE | \
+	 GIT_STATUS_WT_RENAMED)
+
+typedef struct {
+	size_t index_adds;
+	size_t index_dels;
+	size_t index_mods;
+	size_t wt_adds;
+	size_t wt_dels;
+	size_t wt_mods;
+	size_t ignores;
+	size_t conflicts;
+} index_status_counts;
+
+static int index_status_cb(
+	const char *path, unsigned int status_flags, void *payload)
+{
+	index_status_counts *vals = payload;
+
+	/* cb_status__print(path, status_flags, NULL); */
+
+	GIT_UNUSED(path);
+
+	if (status_flags & GIT_STATUS_INDEX_NEW)
+		vals->index_adds++;
+	if (status_flags & GIT_STATUS_INDEX_MODIFIED)
+		vals->index_mods++;
+	if (status_flags & GIT_STATUS_INDEX_DELETED)
+		vals->index_dels++;
+	if (status_flags & GIT_STATUS_INDEX_TYPECHANGE)
+		vals->index_mods++;
+
+	if (status_flags & GIT_STATUS_WT_NEW)
+		vals->wt_adds++;
+	if (status_flags & GIT_STATUS_WT_MODIFIED)
+		vals->wt_mods++;
+	if (status_flags & GIT_STATUS_WT_DELETED)
+		vals->wt_dels++;
+	if (status_flags & GIT_STATUS_WT_TYPECHANGE)
+		vals->wt_mods++;
+
+	if (status_flags & GIT_STATUS_IGNORED)
+		vals->ignores++;
+	if (status_flags & GIT_STATUS_CONFLICTED)
+		vals->conflicts++;
+
+	return 0;
+}
+
+static void check_status_at_line(
+	git_repository *repo,
+	size_t index_adds, size_t index_dels, size_t index_mods,
+	size_t wt_adds, size_t wt_dels, size_t wt_mods, size_t ignores,
+	size_t conflicts, const char *file, int line)
+{
+	index_status_counts vals;
+
+	memset(&vals, 0, sizeof(vals));
+
+	cl_git_pass(git_status_foreach(repo, index_status_cb, &vals));
+
+	clar__assert_equal(
+		file,line,"wrong index adds", 1, "%"PRIuZ, index_adds, vals.index_adds);
+	clar__assert_equal(
+		file,line,"wrong index dels", 1, "%"PRIuZ, index_dels, vals.index_dels);
+	clar__assert_equal(
+		file,line,"wrong index mods", 1, "%"PRIuZ, index_mods, vals.index_mods);
+	clar__assert_equal(
+		file,line,"wrong workdir adds", 1, "%"PRIuZ, wt_adds, vals.wt_adds);
+	clar__assert_equal(
+		file,line,"wrong workdir dels", 1, "%"PRIuZ, wt_dels, vals.wt_dels);
+	clar__assert_equal(
+		file,line,"wrong workdir mods", 1, "%"PRIuZ, wt_mods, vals.wt_mods);
+	clar__assert_equal(
+		file,line,"wrong ignores", 1, "%"PRIuZ, ignores, vals.ignores);
+	clar__assert_equal(
+		file,line,"wrong conflicts", 1, "%"PRIuZ, conflicts, vals.conflicts);
+}
+
+#define check_status(R,IA,ID,IM,WA,WD,WM,IG,C) \
+	check_status_at_line(R,IA,ID,IM,WA,WD,WM,IG,C,__FILE__,__LINE__)
+
+static void check_stat_data(git_index *index, const char *path, bool match)
+{
+	const git_index_entry *entry;
+	struct stat st;
+
+	cl_must_pass(p_lstat(path, &st));
+
+	/* skip repo base dir name */
+	while (*path != '/')
+		++path;
+	++path;
+
+	entry = git_index_get_bypath(index, path, 0);
+	cl_assert(entry);
+
+	if (match) {
+		cl_assert(st.st_ctime == entry->ctime.seconds);
+		cl_assert(st.st_mtime == entry->mtime.seconds);
+		cl_assert(st.st_size == entry->file_size);
+		cl_assert(st.st_uid  == entry->uid);
+		cl_assert(st.st_gid  == entry->gid);
+		cl_assert_equal_i_fmt(
+			GIT_MODE_TYPE(st.st_mode), GIT_MODE_TYPE(entry->mode), "%07o");
+		if (cl_is_chmod_supported())
+			cl_assert_equal_b(
+				GIT_PERMS_IS_EXEC(st.st_mode), GIT_PERMS_IS_EXEC(entry->mode));
+	} else {
+		/* most things will still match */
+		cl_assert(st.st_size != entry->file_size);
+		/* would check mtime, but with second resolution it won't work :( */
+	}
+}
+
+static void addall_create_test_repo(bool check_every_step)
+{
+	g_repo = cl_git_sandbox_init_new(TEST_DIR);
+
+	if (check_every_step)
+		check_status(g_repo, 0, 0, 0, 0, 0, 0, 0, 0);
+
+	cl_git_mkfile(TEST_DIR "/file.foo", "a file");
+	if (check_every_step)
+		check_status(g_repo, 0, 0, 0, 1, 0, 0, 0, 0);
+
+	cl_git_mkfile(TEST_DIR "/.gitignore", "*.foo\n");
+	if (check_every_step)
+		check_status(g_repo, 0, 0, 0, 1, 0, 0, 1, 0);
+
+	cl_git_mkfile(TEST_DIR "/file.bar", "another file");
+	if (check_every_step)
+		check_status(g_repo, 0, 0, 0, 2, 0, 0, 1, 0);
+}
+
+void test_index_addall__repo_lifecycle(void)
+{
+	int error;
+	git_index *index;
+	git_strarray paths = { NULL, 0 };
+	char *strs[1];
+
+	addall_create_test_repo(true);
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	strs[0] = "file.*";
+	paths.strings = strs;
+	paths.count   = 1;
+
+	cl_git_pass(git_index_add_all(index, &paths, 0, NULL, NULL));
+	check_stat_data(index, TEST_DIR "/file.bar", true);
+	check_status(g_repo, 1, 0, 0, 1, 0, 0, 1, 0);
+
+	cl_git_rewritefile(TEST_DIR "/file.bar", "new content for file");
+	check_stat_data(index, TEST_DIR "/file.bar", false);
+	check_status(g_repo, 1, 0, 0, 1, 0, 1, 1, 0);
+
+	cl_git_mkfile(TEST_DIR "/file.zzz", "yet another one");
+	cl_git_mkfile(TEST_DIR "/other.zzz", "yet another one");
+	cl_git_mkfile(TEST_DIR "/more.zzz", "yet another one");
+	check_status(g_repo, 1, 0, 0, 4, 0, 1, 1, 0);
+
+	cl_git_pass(git_index_update_all(index, NULL, NULL, NULL));
+	check_stat_data(index, TEST_DIR "/file.bar", true);
+	check_status(g_repo, 1, 0, 0, 4, 0, 0, 1, 0);
+
+	cl_git_pass(git_index_add_all(index, &paths, 0, NULL, NULL));
+	check_stat_data(index, TEST_DIR "/file.zzz", true);
+	check_status(g_repo, 2, 0, 0, 3, 0, 0, 1, 0);
+
+	cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "first commit");
+	check_status(g_repo, 0, 0, 0, 3, 0, 0, 1, 0);
+
+	if (cl_repo_get_bool(g_repo, "core.filemode")) {
+		cl_git_pass(git_index_update_all(index, NULL, NULL, NULL));
+		cl_must_pass(p_chmod(TEST_DIR "/file.zzz", 0777));
+		cl_git_pass(git_index_update_all(index, NULL, NULL, NULL));
+		check_status(g_repo, 0, 0, 1, 3, 0, 0, 1, 0);
+
+		/* go back to what we had before */
+		cl_must_pass(p_chmod(TEST_DIR "/file.zzz", 0666));
+		cl_git_pass(git_index_update_all(index, NULL, NULL, NULL));
+		check_status(g_repo, 0, 0, 0, 3, 0, 0, 1, 0);
+	}
+
+
+	/* attempt to add an ignored file - does nothing */
+	strs[0] = "file.foo";
+	cl_git_pass(git_index_add_all(index, &paths, 0, NULL, NULL));
+	check_status(g_repo, 0, 0, 0, 3, 0, 0, 1, 0);
+
+	/* add with check - should generate error */
+	error = git_index_add_all(
+		index, &paths, GIT_INDEX_ADD_CHECK_PATHSPEC, NULL, NULL);
+	cl_assert_equal_i(GIT_EINVALIDSPEC, error);
+	check_status(g_repo, 0, 0, 0, 3, 0, 0, 1, 0);
+
+	/* add with force - should allow */
+	cl_git_pass(git_index_add_all(
+		index, &paths, GIT_INDEX_ADD_FORCE, NULL, NULL));
+	check_stat_data(index, TEST_DIR "/file.foo", true);
+	check_status(g_repo, 1, 0, 0, 3, 0, 0, 0, 0);
+
+	/* now it's in the index, so regular add should work */
+	cl_git_rewritefile(TEST_DIR "/file.foo", "new content for file");
+	check_stat_data(index, TEST_DIR "/file.foo", false);
+	check_status(g_repo, 1, 0, 0, 3, 0, 1, 0, 0);
+
+	cl_git_pass(git_index_add_all(index, &paths, 0, NULL, NULL));
+	check_stat_data(index, TEST_DIR "/file.foo", true);
+	check_status(g_repo, 1, 0, 0, 3, 0, 0, 0, 0);
+
+	cl_git_pass(git_index_add_bypath(index, "more.zzz"));
+	check_stat_data(index, TEST_DIR "/more.zzz", true);
+	check_status(g_repo, 2, 0, 0, 2, 0, 0, 0, 0);
+
+	cl_git_rewritefile(TEST_DIR "/file.zzz", "new content for file");
+	check_status(g_repo, 2, 0, 0, 2, 0, 1, 0, 0);
+
+	cl_git_pass(git_index_add_bypath(index, "file.zzz"));
+	check_stat_data(index, TEST_DIR "/file.zzz", true);
+	check_status(g_repo, 2, 0, 1, 2, 0, 0, 0, 0);
+
+	strs[0] = "*.zzz";
+	cl_git_pass(git_index_remove_all(index, &paths, NULL, NULL));
+	check_status(g_repo, 1, 1, 0, 4, 0, 0, 0, 0);
+
+	cl_git_pass(git_index_add_bypath(index, "file.zzz"));
+	check_status(g_repo, 1, 0, 1, 3, 0, 0, 0, 0);
+
+	cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "second commit");
+	check_status(g_repo, 0, 0, 0, 3, 0, 0, 0, 0);
+
+	cl_must_pass(p_unlink(TEST_DIR "/file.zzz"));
+	check_status(g_repo, 0, 0, 0, 3, 1, 0, 0, 0);
+
+	/* update_all should be able to remove entries */
+	cl_git_pass(git_index_update_all(index, NULL, NULL, NULL));
+	check_status(g_repo, 0, 1, 0, 3, 0, 0, 0, 0);
+
+	strs[0] = "*";
+	cl_git_pass(git_index_add_all(index, &paths, 0, NULL, NULL));
+	check_status(g_repo, 3, 1, 0, 0, 0, 0, 0, 0);
+
+	/* must be able to remove at any position while still updating other files */
+	cl_must_pass(p_unlink(TEST_DIR "/.gitignore"));
+	cl_git_rewritefile(TEST_DIR "/file.zzz", "reconstructed file");
+	cl_git_rewritefile(TEST_DIR "/more.zzz", "altered file reality");
+	check_status(g_repo, 3, 1, 0, 1, 1, 1, 0, 0);
+
+	cl_git_pass(git_index_update_all(index, NULL, NULL, NULL));
+	check_status(g_repo, 2, 1, 0, 1, 0, 0, 0, 0);
+	/* this behavior actually matches 'git add -u' where "file.zzz" has
+	 * been removed from the index, so when you go to update, even though
+	 * it exists in the HEAD, it is not re-added to the index, leaving it
+	 * as a DELETE when comparing HEAD to index and as an ADD comparing
+	 * index to worktree
+	 */
+
+	git_index_free(index);
+}
+
+void test_index_addall__files_in_folders(void)
+{
+	git_index *index;
+
+	addall_create_test_repo(true);
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_pass(git_index_add_all(index, NULL, 0, NULL, NULL));
+	check_stat_data(index, TEST_DIR "/file.bar", true);
+	check_status(g_repo, 2, 0, 0, 0, 0, 0, 1, 0);
+
+	cl_must_pass(p_mkdir(TEST_DIR "/subdir", 0777));
+	cl_git_mkfile(TEST_DIR "/subdir/file", "hello!\n");
+	check_status(g_repo, 2, 0, 0, 1, 0, 0, 1, 0);
+
+	cl_git_pass(git_index_add_all(index, NULL, 0, NULL, NULL));
+	check_status(g_repo, 3, 0, 0, 0, 0, 0, 1, 0);
+
+	git_index_free(index);
+}
+
+static int addall_match_prefix(
+	const char *path, const char *matched_pathspec, void *payload)
+{
+	GIT_UNUSED(matched_pathspec);
+	return !git__prefixcmp(path, payload) ? 0 : 1;
+}
+
+static int addall_match_suffix(
+	const char *path, const char *matched_pathspec, void *payload)
+{
+	GIT_UNUSED(matched_pathspec);
+	return !git__suffixcmp(path, payload) ? 0 : 1;
+}
+
+static int addall_cancel_at(
+	const char *path, const char *matched_pathspec, void *payload)
+{
+	GIT_UNUSED(matched_pathspec);
+	return !strcmp(path, payload) ? -123 : 0;
+}
+
+void test_index_addall__callback_filtering(void)
+{
+	git_index *index;
+
+	addall_create_test_repo(false);
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_pass(
+		git_index_add_all(index, NULL, 0, addall_match_prefix, "file."));
+	check_stat_data(index, TEST_DIR "/file.bar", true);
+	check_status(g_repo, 1, 0, 0, 1, 0, 0, 1, 0);
+
+	cl_git_mkfile(TEST_DIR "/file.zzz", "yet another one");
+	cl_git_mkfile(TEST_DIR "/more.zzz", "yet another one");
+	cl_git_mkfile(TEST_DIR "/other.zzz", "yet another one");
+
+	cl_git_pass(git_index_update_all(index, NULL, NULL, NULL));
+	check_stat_data(index, TEST_DIR "/file.bar", true);
+	check_status(g_repo, 1, 0, 0, 4, 0, 0, 1, 0);
+
+	cl_git_pass(
+		git_index_add_all(index, NULL, 0, addall_match_prefix, "other"));
+	check_stat_data(index, TEST_DIR "/other.zzz", true);
+	check_status(g_repo, 2, 0, 0, 3, 0, 0, 1, 0);
+
+	cl_git_pass(
+		git_index_add_all(index, NULL, 0, addall_match_suffix, ".zzz"));
+	check_status(g_repo, 4, 0, 0, 1, 0, 0, 1, 0);
+
+	cl_git_pass(
+		git_index_remove_all(index, NULL, addall_match_suffix, ".zzz"));
+	check_status(g_repo, 1, 0, 0, 4, 0, 0, 1, 0);
+
+	cl_git_fail_with(
+		git_index_add_all(index, NULL, 0, addall_cancel_at, "more.zzz"), -123);
+	check_status(g_repo, 3, 0, 0, 2, 0, 0, 1, 0);
+
+	cl_git_fail_with(
+		git_index_add_all(index, NULL, 0, addall_cancel_at, "other.zzz"), -123);
+	check_status(g_repo, 4, 0, 0, 1, 0, 0, 1, 0);
+
+	cl_git_pass(
+		git_index_add_all(index, NULL, 0, addall_match_suffix, ".zzz"));
+	check_status(g_repo, 5, 0, 0, 0, 0, 0, 1, 0);
+
+	cl_must_pass(p_unlink(TEST_DIR "/file.zzz"));
+	cl_must_pass(p_unlink(TEST_DIR "/more.zzz"));
+	cl_must_pass(p_unlink(TEST_DIR "/other.zzz"));
+
+	cl_git_fail_with(
+		git_index_update_all(index, NULL, addall_cancel_at, "more.zzz"), -123);
+	/* file.zzz removed from index (so Index Adds 5 -> 4) and
+	 * more.zzz + other.zzz removed (so Worktree Dels 0 -> 2) */
+	check_status(g_repo, 4, 0, 0, 0, 2, 0, 1, 0);
+
+	cl_git_fail_with(
+		git_index_update_all(index, NULL, addall_cancel_at, "other.zzz"), -123);
+	/* more.zzz removed from index (so Index Adds 4 -> 3) and
+	 * Just other.zzz removed (so Worktree Dels 2 -> 1) */
+	check_status(g_repo, 3, 0, 0, 0, 1, 0, 1, 0);
+
+	git_index_free(index);
+}
+
+void test_index_addall__adds_conflicts(void)
+{
+	git_index *index;
+	git_reference *ref;
+	git_annotated_commit *annotated;
+
+	g_repo = cl_git_sandbox_init("merge-resolve");
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	check_status(g_repo, 0, 0, 0, 0, 0, 0, 0, 0);
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/heads/branch"));
+	cl_git_pass(git_annotated_commit_from_ref(&annotated, g_repo, ref));
+
+	cl_git_pass(git_merge(g_repo, (const git_annotated_commit**)&annotated, 1, NULL, NULL));
+	check_status(g_repo, 0, 1, 2, 0, 0, 0, 0, 1);
+
+	cl_git_pass(git_index_add_all(index, NULL, 0, NULL, NULL));
+	check_status(g_repo, 0, 1, 3, 0, 0, 0, 0, 0);
+
+	git_annotated_commit_free(annotated);
+	git_reference_free(ref);
+	git_index_free(index);
+}
+
+void test_index_addall__removes_deleted_conflicted_files(void)
+{
+	git_index *index;
+	git_reference *ref;
+	git_annotated_commit *annotated;
+
+	g_repo = cl_git_sandbox_init("merge-resolve");
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	check_status(g_repo, 0, 0, 0, 0, 0, 0, 0, 0);
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/heads/branch"));
+	cl_git_pass(git_annotated_commit_from_ref(&annotated, g_repo, ref));
+
+	cl_git_pass(git_merge(g_repo, (const git_annotated_commit**)&annotated, 1, NULL, NULL));
+	check_status(g_repo, 0, 1, 2, 0, 0, 0, 0, 1);
+
+	cl_git_rmfile("merge-resolve/conflicting.txt");
+
+	cl_git_pass(git_index_add_all(index, NULL, 0, NULL, NULL));
+	check_status(g_repo, 0, 2, 2, 0, 0, 0, 0, 0);
+
+	git_annotated_commit_free(annotated);
+	git_reference_free(ref);
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/bypath.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/bypath.c
new file mode 100755
index 0000000..9706a88
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/bypath.c
@@ -0,0 +1,48 @@
+#include "clar_libgit2.h"
+#include "repository.h"
+#include "../submodule/submodule_helpers.h"
+
+static git_repository *g_repo;
+static git_index *g_idx;
+
+void test_index_bypath__initialize(void)
+{
+	g_repo = setup_fixture_submod2();
+	cl_git_pass(git_repository_index__weakptr(&g_idx, g_repo));
+}
+
+void test_index_bypath__cleanup(void)
+{
+	g_repo = NULL;
+	g_idx = NULL;
+}
+
+void test_index_bypath__add_directory(void)
+{
+	cl_git_fail_with(GIT_EDIRECTORY, git_index_add_bypath(g_idx, "just_a_dir"));
+}
+
+void test_index_bypath__add_submodule(void)
+{
+	unsigned int status;
+	const char *sm_name = "sm_changed_head";
+
+	cl_git_pass(git_submodule_status(&status, g_repo, sm_name, 0));
+	cl_assert_equal_i(GIT_SUBMODULE_STATUS_WD_MODIFIED, status & GIT_SUBMODULE_STATUS_WD_MODIFIED);
+	cl_git_pass(git_index_add_bypath(g_idx, sm_name));
+	cl_git_pass(git_submodule_status(&status, g_repo, sm_name, 0));
+	cl_assert_equal_i(0, status & GIT_SUBMODULE_STATUS_WD_MODIFIED);
+}
+
+void test_index_bypath__add_submodule_unregistered(void)
+{
+	const char *sm_name = "not-submodule";
+	const char *sm_head = "68e92c611b80ee1ed8f38314ff9577f0d15b2444";
+	const git_index_entry *entry;
+
+	cl_git_pass(git_index_add_bypath(g_idx, sm_name));
+
+	cl_assert(entry = git_index_get_bypath(g_idx, sm_name, 0));
+	cl_assert_equal_s(sm_head, git_oid_tostr_s(&entry->id));
+	cl_assert_equal_s(sm_name, entry->path);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/cache.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/cache.c
new file mode 100755
index 0000000..3982bf1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/cache.c
@@ -0,0 +1,238 @@
+#include "clar_libgit2.h"
+#include "git2.h"
+#include "index.h"
+#include "tree-cache.h"
+
+static git_repository *g_repo;
+
+void test_index_cache__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_index_cache__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+	g_repo = NULL;
+}
+
+void test_index_cache__write_extension_at_root(void)
+{
+	git_index *index;
+	git_tree *tree;
+	git_oid id;
+	const char *tree_id_str = "45dd856fdd4d89b884c340ba0e047752d9b085d6";
+	const char *index_file = "index-tree";
+
+	cl_git_pass(git_index_open(&index, index_file));
+	cl_assert(index->tree == NULL);
+	cl_git_pass(git_oid_fromstr(&id, tree_id_str));
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
+	cl_git_pass(git_index_read_tree(index, tree));
+	git_tree_free(tree);
+
+	cl_assert(index->tree);
+	cl_git_pass(git_index_write(index));
+	git_index_free(index);
+
+	cl_git_pass(git_index_open(&index, index_file));
+	cl_assert(index->tree);
+
+	cl_assert_equal_i(git_index_entrycount(index), index->tree->entry_count);
+	cl_assert_equal_i(0, index->tree->children_count);
+
+	cl_assert(git_oid_equal(&id, &index->tree->oid));
+
+	cl_git_pass(p_unlink(index_file));
+	git_index_free(index);
+}
+
+void test_index_cache__write_extension_invalidated_root(void)
+{
+	git_index *index;
+	git_tree *tree;
+	git_oid id;
+	const char *tree_id_str = "45dd856fdd4d89b884c340ba0e047752d9b085d6";
+	const char *index_file = "index-tree-invalidated";
+	git_index_entry entry;
+
+	cl_git_pass(git_index_open(&index, index_file));
+	cl_assert(index->tree == NULL);
+	cl_git_pass(git_oid_fromstr(&id, tree_id_str));
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
+	cl_git_pass(git_index_read_tree(index, tree));
+	git_tree_free(tree);
+
+	cl_assert(index->tree);
+
+	memset(&entry, 0x0, sizeof(git_index_entry));
+	git_oid_cpy(&entry.id, &git_index_get_byindex(index, 0)->id);
+	entry.mode = GIT_FILEMODE_BLOB;
+	entry.path = "some-new-file.txt";
+
+	cl_git_pass(git_index_add(index, &entry));
+
+	cl_assert_equal_i(-1, index->tree->entry_count);
+
+	cl_git_pass(git_index_write(index));
+	git_index_free(index);
+
+	cl_git_pass(git_index_open(&index, index_file));
+	cl_assert(index->tree);
+
+	cl_assert_equal_i(-1, index->tree->entry_count);
+	cl_assert_equal_i(0, index->tree->children_count);
+
+	cl_assert(git_oid_cmp(&id, &index->tree->oid));
+
+	cl_git_pass(p_unlink(index_file));
+	git_index_free(index);
+}
+
+void test_index_cache__read_tree_no_children(void)
+{
+	git_index *index;
+	git_index_entry entry;
+	git_tree *tree;
+	git_oid id;
+
+	cl_git_pass(git_index_new(&index));
+	cl_assert(index->tree == NULL);
+	cl_git_pass(git_oid_fromstr(&id, "45dd856fdd4d89b884c340ba0e047752d9b085d6"));
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
+	cl_git_pass(git_index_read_tree(index, tree));
+	git_tree_free(tree);
+
+	cl_assert(index->tree);
+	cl_assert(git_oid_equal(&id, &index->tree->oid));
+	cl_assert_equal_i(0, index->tree->children_count);
+	cl_assert_equal_i(git_index_entrycount(index), index->tree->entry_count);
+
+	memset(&entry, 0x0, sizeof(git_index_entry));
+	entry.path = "new.txt";
+	entry.mode = GIT_FILEMODE_BLOB;
+	git_oid_fromstr(&entry.id, "45b983be36b73c0788dc9cbcb76cbb80fc7bb057");
+
+	cl_git_pass(git_index_add(index, &entry));
+	cl_assert_equal_i(-1, index->tree->entry_count);
+
+	git_index_free(index);
+}
+
+void test_index_cache__two_levels(void)
+{
+	git_tree *tree;
+	git_oid tree_id;
+	git_index *index;
+	git_index_entry entry;
+	const git_tree_cache *tree_cache;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_clear(index));
+
+	memset(&entry, 0x0, sizeof(entry));
+	entry.mode = GIT_FILEMODE_BLOB;
+	cl_git_pass(git_oid_fromstr(&entry.id, "a8233120f6ad708f843d861ce2b7228ec4e3dec6"));
+	entry.path = "top-level.txt";
+	cl_git_pass(git_index_add(index, &entry));
+
+	entry.path = "subdir/file.txt";
+	cl_git_pass(git_index_add(index, &entry));
+
+	/* the read-tree fills the tree cache */
+	cl_git_pass(git_index_write_tree(&tree_id, index));
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
+	cl_git_pass(git_index_read_tree(index, tree));
+	git_tree_free(tree);
+	cl_git_pass(git_index_write(index));
+
+	/* we now must have cache entries for "" and "subdir" */
+	cl_assert(index->tree);
+	cl_assert(git_tree_cache_get(index->tree, "subdir"));
+
+	cl_git_pass(git_index_read(index, true));
+	/* we must still have cache entries for "" and "subdir", since we wrote it out */
+	cl_assert(index->tree);
+	cl_assert(git_tree_cache_get(index->tree, "subdir"));
+
+	entry.path = "top-level.txt";
+	cl_git_pass(git_oid_fromstr(&entry.id, "3697d64be941a53d4ae8f6a271e4e3fa56b022cc"));
+	cl_git_pass(git_index_add(index, &entry));
+
+	/* writ out the index after we invalidate the root */
+	cl_git_pass(git_index_write(index));
+	cl_git_pass(git_index_read(index, true));
+
+	/* the cache for the subtree must still be valid, even if the root isn't */
+	cl_assert(index->tree);
+	cl_assert_equal_i(-1, index->tree->entry_count);
+	cl_assert_equal_i(1, index->tree->children_count);
+	tree_cache = git_tree_cache_get(index->tree, "subdir");
+	cl_assert(tree_cache);
+	cl_assert_equal_i(1, tree_cache->entry_count);
+
+	git_index_free(index);
+}
+
+void test_index_cache__read_tree_children(void)
+{
+	git_index *index;
+	git_index_entry entry;
+	git_tree *tree;
+	const git_tree_cache *cache;
+	git_oid tree_id;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_clear(index));
+	cl_assert(index->tree == NULL);
+
+
+	/* add a bunch of entries at different levels */
+	memset(&entry, 0x0, sizeof(git_index_entry));
+	entry.path = "top-level";
+	entry.mode = GIT_FILEMODE_BLOB;
+	git_oid_fromstr(&entry.id, "45b983be36b73c0788dc9cbcb76cbb80fc7bb057");
+	cl_git_pass(git_index_add(index, &entry));
+
+
+	entry.path = "subdir/some-file";
+	cl_git_pass(git_index_add(index, &entry));
+
+	entry.path = "subdir/even-deeper/some-file";
+	cl_git_pass(git_index_add(index, &entry));
+
+	entry.path = "subdir2/some-file";
+	cl_git_pass(git_index_add(index, &entry));
+
+	cl_git_pass(git_index_write_tree(&tree_id, index));
+	cl_git_pass(git_index_clear(index));
+	cl_assert(index->tree == NULL);
+
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
+	cl_git_pass(git_index_read_tree(index, tree));
+	git_tree_free(tree);
+
+	cl_assert(index->tree);
+	cl_assert_equal_i(2, index->tree->children_count);
+
+	/* override with a slightly different id, also dummy */
+	entry.path = "subdir/some-file";
+	git_oid_fromstr(&entry.id, "45b983be36b73c0788dc9cbcb76cbb80fc7bb058");
+	cl_git_pass(git_index_add(index, &entry));
+
+	cl_assert_equal_i(-1, index->tree->entry_count);
+
+	cache = git_tree_cache_get(index->tree, "subdir");
+	cl_assert(cache);
+	cl_assert_equal_i(-1, cache->entry_count);
+
+	cache = git_tree_cache_get(index->tree, "subdir/even-deeper");
+	cl_assert(cache);
+	cl_assert_equal_i(1, cache->entry_count);
+
+	cache = git_tree_cache_get(index->tree, "subdir2");
+	cl_assert(cache);
+	cl_assert_equal_i(1, cache->entry_count);
+
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/collision.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/collision.c
new file mode 100755
index 0000000..19c1548
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/collision.c
@@ -0,0 +1,106 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/index.h"
+
+git_repository *repo = NULL;
+
+void test_index_collision__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+	repo = NULL;
+}
+
+void test_index_collision__add(void)
+{
+	git_index *index;
+	git_index_entry entry;
+	git_oid tree_id;
+	git_tree *tree;
+
+	repo = cl_git_sandbox_init("empty_standard_repo");
+	cl_git_pass(git_repository_index(&index, repo));
+
+	memset(&entry, 0, sizeof(entry));
+	entry.ctime.seconds = 12346789;
+	entry.mtime.seconds = 12346789;
+	entry.mode  = 0100644;
+	entry.file_size = 0;
+	git_oid_fromstr(&entry.id, "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391");
+
+	entry.path = "a/b";
+	cl_git_pass(git_index_add(index, &entry));
+
+	/* create a tree/blob collision */
+	entry.path = "a/b/c";
+	cl_git_fail(git_index_add(index, &entry));
+
+	cl_git_pass(git_index_write_tree(&tree_id, index));
+	cl_git_pass(git_tree_lookup(&tree, repo, &tree_id));
+
+	git_tree_free(tree);
+	git_index_free(index);
+}
+
+void test_index_collision__add_with_highstage_1(void)
+{
+	git_index *index;
+	git_index_entry entry;
+
+	repo = cl_git_sandbox_init("empty_standard_repo");
+	cl_git_pass(git_repository_index(&index, repo));
+
+	memset(&entry, 0, sizeof(entry));
+	entry.ctime.seconds = 12346789;
+	entry.mtime.seconds = 12346789;
+	entry.mode  = 0100644;
+	entry.file_size = 0;
+	git_oid_fromstr(&entry.id, "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391");
+
+	entry.path = "a/b";
+	GIT_IDXENTRY_STAGE_SET(&entry, 2);
+	cl_git_pass(git_index_add(index, &entry));
+
+	/* create a blob beneath the previous tree entry */
+	entry.path = "a/b/c";
+	entry.flags = 0;
+	cl_git_pass(git_index_add(index, &entry));
+
+	/* create another tree entry above the blob */
+	entry.path = "a/b";
+	GIT_IDXENTRY_STAGE_SET(&entry, 1);
+	cl_git_pass(git_index_add(index, &entry));
+
+	git_index_free(index);
+}
+
+void test_index_collision__add_with_highstage_2(void)
+{
+	git_index *index;
+	git_index_entry entry;
+
+	repo = cl_git_sandbox_init("empty_standard_repo");
+	cl_git_pass(git_repository_index(&index, repo));
+
+	memset(&entry, 0, sizeof(entry));
+	entry.ctime.seconds = 12346789;
+	entry.mtime.seconds = 12346789;
+	entry.mode  = 0100644;
+	entry.file_size = 0;
+	git_oid_fromstr(&entry.id, "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391");
+
+	entry.path = "a/b/c";
+	GIT_IDXENTRY_STAGE_SET(&entry, 1);
+	cl_git_pass(git_index_add(index, &entry));
+
+	/* create a blob beneath the previous tree entry */
+	entry.path = "a/b/c";
+	GIT_IDXENTRY_STAGE_SET(&entry, 2);
+	cl_git_pass(git_index_add(index, &entry));
+
+	/* create another tree entry above the blob */
+	entry.path = "a/b";
+	GIT_IDXENTRY_STAGE_SET(&entry, 3);
+	cl_git_pass(git_index_add(index, &entry));
+
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/conflicts.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/conflicts.c
new file mode 100755
index 0000000..b7a2456
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/conflicts.c
@@ -0,0 +1,344 @@
+#include "clar_libgit2.h"
+#include "index.h"
+#include "git2/repository.h"
+
+static git_repository *repo;
+static git_index *repo_index;
+
+#define TEST_REPO_PATH "mergedrepo"
+#define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index"
+
+#define CONFLICTS_ONE_ANCESTOR_OID "1f85ca51b8e0aac893a621b61a9c2661d6aa6d81"
+#define CONFLICTS_ONE_OUR_OID "6aea5f295304c36144ad6e9247a291b7f8112399"
+#define CONFLICTS_ONE_THEIR_OID "516bd85f78061e09ccc714561d7b504672cb52da"
+
+#define CONFLICTS_TWO_ANCESTOR_OID "84af62840be1b1c47b778a8a249f3ff45155038c"
+#define CONFLICTS_TWO_OUR_OID "8b3f43d2402825c200f835ca1762413e386fd0b2"
+#define CONFLICTS_TWO_THEIR_OID "220bd62631c8cf7a83ef39c6b94595f00517211e"
+
+#define TEST_STAGED_OID "beefdadafeedabedcafedeedbabedeadbeaddeaf"
+#define TEST_ANCESTOR_OID "f00ff00ff00ff00ff00ff00ff00ff00ff00ff00f"
+#define TEST_OUR_OID "b44bb44bb44bb44bb44bb44bb44bb44bb44bb44b"
+#define TEST_THEIR_OID "0123456789abcdef0123456789abcdef01234567"
+
+// Fixture setup and teardown
+void test_index_conflicts__initialize(void)
+{
+	repo = cl_git_sandbox_init("mergedrepo");
+	git_repository_index(&repo_index, repo);
+}
+
+void test_index_conflicts__cleanup(void)
+{
+	git_index_free(repo_index);
+	repo_index = NULL;
+
+	cl_git_sandbox_cleanup();
+}
+
+void test_index_conflicts__add(void)
+{
+	git_index_entry ancestor_entry, our_entry, their_entry;
+
+	cl_assert(git_index_entrycount(repo_index) == 8);
+
+	memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
+	memset(&our_entry, 0x0, sizeof(git_index_entry));
+	memset(&their_entry, 0x0, sizeof(git_index_entry));
+
+	ancestor_entry.path = "test-one.txt";
+	ancestor_entry.mode = 0100644;
+	GIT_IDXENTRY_STAGE_SET(&ancestor_entry, 1);
+	git_oid_fromstr(&ancestor_entry.id, TEST_ANCESTOR_OID);
+
+	our_entry.path = "test-one.txt";
+	our_entry.mode = 0100644;
+	GIT_IDXENTRY_STAGE_SET(&our_entry, 2);
+	git_oid_fromstr(&our_entry.id, TEST_OUR_OID);
+
+	their_entry.path = "test-one.txt";
+	their_entry.mode = 0100644;
+	GIT_IDXENTRY_STAGE_SET(&ancestor_entry, 2);
+	git_oid_fromstr(&their_entry.id, TEST_THEIR_OID);
+
+	cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, &our_entry, &their_entry));
+
+	cl_assert(git_index_entrycount(repo_index) == 11);
+}
+
+void test_index_conflicts__add_fixes_incorrect_stage(void)
+{
+	git_index_entry ancestor_entry, our_entry, their_entry;
+	const git_index_entry *conflict_entry[3];
+
+	cl_assert(git_index_entrycount(repo_index) == 8);
+
+	memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
+	memset(&our_entry, 0x0, sizeof(git_index_entry));
+	memset(&their_entry, 0x0, sizeof(git_index_entry));
+
+	ancestor_entry.path = "test-one.txt";
+	ancestor_entry.mode = 0100644;
+	GIT_IDXENTRY_STAGE_SET(&ancestor_entry, 3);
+	git_oid_fromstr(&ancestor_entry.id, TEST_ANCESTOR_OID);
+
+	our_entry.path = "test-one.txt";
+	our_entry.mode = 0100644;
+	GIT_IDXENTRY_STAGE_SET(&our_entry, 1);
+	git_oid_fromstr(&our_entry.id, TEST_OUR_OID);
+
+	their_entry.path = "test-one.txt";
+	their_entry.mode = 0100644;
+	GIT_IDXENTRY_STAGE_SET(&their_entry, 2);
+	git_oid_fromstr(&their_entry.id, TEST_THEIR_OID);
+
+	cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, &our_entry, &their_entry));
+
+	cl_assert(git_index_entrycount(repo_index) == 11);
+
+	cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], repo_index, "test-one.txt"));
+
+	cl_assert(git_index_entry_stage(conflict_entry[0]) == 1);
+	cl_assert(git_index_entry_stage(conflict_entry[1]) == 2);
+	cl_assert(git_index_entry_stage(conflict_entry[2]) == 3);
+}
+
+void test_index_conflicts__add_removes_stage_zero(void)
+{
+	git_index_entry staged, ancestor_entry, our_entry, their_entry;
+	const git_index_entry *conflict_entry[3];
+
+	cl_assert(git_index_entrycount(repo_index) == 8);
+
+	memset(&staged, 0x0, sizeof(git_index_entry));
+	memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
+	memset(&our_entry, 0x0, sizeof(git_index_entry));
+	memset(&their_entry, 0x0, sizeof(git_index_entry));
+
+	staged.path = "test-one.txt";
+	staged.mode = 0100644;
+	git_oid_fromstr(&staged.id, TEST_STAGED_OID);
+	cl_git_pass(git_index_add(repo_index, &staged));
+	cl_assert(git_index_entrycount(repo_index) == 9);
+
+	ancestor_entry.path = "test-one.txt";
+	ancestor_entry.mode = 0100644;
+	GIT_IDXENTRY_STAGE_SET(&ancestor_entry, 3);
+	git_oid_fromstr(&ancestor_entry.id, TEST_ANCESTOR_OID);
+
+	our_entry.path = "test-one.txt";
+	our_entry.mode = 0100644;
+	GIT_IDXENTRY_STAGE_SET(&our_entry, 1);
+	git_oid_fromstr(&our_entry.id, TEST_OUR_OID);
+
+	their_entry.path = "test-one.txt";
+	their_entry.mode = 0100644;
+	GIT_IDXENTRY_STAGE_SET(&their_entry, 2);
+	git_oid_fromstr(&their_entry.id, TEST_THEIR_OID);
+
+	cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, &our_entry, &their_entry));
+
+	cl_assert(git_index_entrycount(repo_index) == 11);
+
+	cl_assert_equal_p(NULL, git_index_get_bypath(repo_index, "test-one.txt", 0));
+
+	cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], repo_index, "test-one.txt"));
+
+	cl_assert_equal_oid(&ancestor_entry.id, &conflict_entry[0]->id);
+	cl_assert_equal_i(1, git_index_entry_stage(conflict_entry[0]));
+	cl_assert_equal_oid(&our_entry.id, &conflict_entry[1]->id);
+	cl_assert_equal_i(2, git_index_entry_stage(conflict_entry[1]));
+	cl_assert_equal_oid(&their_entry.id, &conflict_entry[2]->id);
+	cl_assert_equal_i(3, git_index_entry_stage(conflict_entry[2]));
+}
+
+void test_index_conflicts__get(void)
+{
+	const git_index_entry *conflict_entry[3];
+	git_oid oid;
+
+	cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1],
+		&conflict_entry[2], repo_index, "conflicts-one.txt"));
+
+	cl_assert_equal_s("conflicts-one.txt", conflict_entry[0]->path);
+
+	git_oid_fromstr(&oid, CONFLICTS_ONE_ANCESTOR_OID);
+	cl_assert_equal_oid(&oid, &conflict_entry[0]->id);
+
+	git_oid_fromstr(&oid, CONFLICTS_ONE_OUR_OID);
+	cl_assert_equal_oid(&oid, &conflict_entry[1]->id);
+
+	git_oid_fromstr(&oid, CONFLICTS_ONE_THEIR_OID);
+	cl_assert_equal_oid(&oid, &conflict_entry[2]->id);
+
+	cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1],
+		&conflict_entry[2], repo_index, "conflicts-two.txt"));
+
+	cl_assert_equal_s("conflicts-two.txt", conflict_entry[0]->path);
+
+	git_oid_fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID);
+	cl_assert_equal_oid(&oid, &conflict_entry[0]->id);
+
+	git_oid_fromstr(&oid, CONFLICTS_TWO_OUR_OID);
+	cl_assert_equal_oid(&oid, &conflict_entry[1]->id);
+
+	git_oid_fromstr(&oid, CONFLICTS_TWO_THEIR_OID);
+	cl_assert_equal_oid(&oid, &conflict_entry[2]->id);
+}
+
+void test_index_conflicts__iterate(void)
+{
+	git_index_conflict_iterator *iterator;
+	const git_index_entry *conflict_entry[3];
+	git_oid oid;
+
+	cl_git_pass(git_index_conflict_iterator_new(&iterator, repo_index));
+
+	cl_git_pass(git_index_conflict_next(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], iterator));
+
+	git_oid_fromstr(&oid, CONFLICTS_ONE_ANCESTOR_OID);
+	cl_assert_equal_oid(&oid, &conflict_entry[0]->id);
+	cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-one.txt") == 0);
+
+	git_oid_fromstr(&oid, CONFLICTS_ONE_OUR_OID);
+	cl_assert_equal_oid(&oid, &conflict_entry[1]->id);
+	cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-one.txt") == 0);
+
+	git_oid_fromstr(&oid, CONFLICTS_ONE_THEIR_OID);
+	cl_assert_equal_oid(&oid, &conflict_entry[2]->id);
+	cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-one.txt") == 0);
+
+	cl_git_pass(git_index_conflict_next(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], iterator));
+
+	git_oid_fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID);
+	cl_assert_equal_oid(&oid, &conflict_entry[0]->id);
+	cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-two.txt") == 0);
+
+	git_oid_fromstr(&oid, CONFLICTS_TWO_OUR_OID);
+	cl_assert_equal_oid(&oid, &conflict_entry[1]->id);
+	cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-two.txt") == 0);
+
+	git_oid_fromstr(&oid, CONFLICTS_TWO_THEIR_OID);
+	cl_assert_equal_oid(&oid, &conflict_entry[2]->id);
+	cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-two.txt") == 0);
+
+	cl_assert(git_index_conflict_next(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], iterator) == GIT_ITEROVER);
+
+	cl_assert(conflict_entry[0] == NULL);
+	cl_assert(conflict_entry[2] == NULL);
+	cl_assert(conflict_entry[2] == NULL);
+
+	git_index_conflict_iterator_free(iterator);
+}
+
+void test_index_conflicts__remove(void)
+{
+	const git_index_entry *entry;
+	size_t i;
+
+	cl_assert(git_index_entrycount(repo_index) == 8);
+
+	cl_git_pass(git_index_conflict_remove(repo_index, "conflicts-one.txt"));
+	cl_assert(git_index_entrycount(repo_index) == 5);
+
+	for (i = 0; i < git_index_entrycount(repo_index); i++) {
+		cl_assert(entry = git_index_get_byindex(repo_index, i));
+		cl_assert(strcmp(entry->path, "conflicts-one.txt") != 0);
+	}
+
+	cl_git_pass(git_index_conflict_remove(repo_index, "conflicts-two.txt"));
+	cl_assert(git_index_entrycount(repo_index) == 2);
+
+	for (i = 0; i < git_index_entrycount(repo_index); i++) {
+		cl_assert(entry = git_index_get_byindex(repo_index, i));
+		cl_assert(strcmp(entry->path, "conflicts-two.txt") != 0);
+	}
+}
+
+void test_index_conflicts__moved_to_reuc_on_add(void)
+{
+	const git_index_entry *entry;
+	size_t i;
+
+	cl_assert(git_index_entrycount(repo_index) == 8);
+
+	cl_git_mkfile("./mergedrepo/conflicts-one.txt", "new-file\n");
+
+	cl_git_pass(git_index_add_bypath(repo_index, "conflicts-one.txt"));
+
+	cl_assert(git_index_entrycount(repo_index) == 6);
+
+	for (i = 0; i < git_index_entrycount(repo_index); i++) {
+		cl_assert(entry = git_index_get_byindex(repo_index, i));
+
+		if (strcmp(entry->path, "conflicts-one.txt") == 0)
+			cl_assert(!git_index_entry_is_conflict(entry));
+	}
+}
+
+void test_index_conflicts__moved_to_reuc_on_remove(void)
+{
+	const git_index_entry *entry;
+	size_t i;
+
+	cl_assert(git_index_entrycount(repo_index) == 8);
+
+	cl_git_pass(p_unlink("./mergedrepo/conflicts-one.txt"));
+
+	cl_git_pass(git_index_remove_bypath(repo_index, "conflicts-one.txt"));
+
+	cl_assert(git_index_entrycount(repo_index) == 5);
+
+	for (i = 0; i < git_index_entrycount(repo_index); i++) {
+		cl_assert(entry = git_index_get_byindex(repo_index, i));
+		cl_assert(strcmp(entry->path, "conflicts-one.txt") != 0);
+	}
+}
+
+void test_index_conflicts__remove_all_conflicts(void)
+{
+	size_t i;
+	const git_index_entry *entry;
+
+	cl_assert(git_index_entrycount(repo_index) == 8);
+
+	cl_assert_equal_i(true, git_index_has_conflicts(repo_index));
+
+	git_index_conflict_cleanup(repo_index);
+
+	cl_assert_equal_i(false, git_index_has_conflicts(repo_index));
+
+	cl_assert(git_index_entrycount(repo_index) == 2);
+
+	for (i = 0; i < git_index_entrycount(repo_index); i++) {
+		cl_assert(entry = git_index_get_byindex(repo_index, i));
+		cl_assert(!git_index_entry_is_conflict(entry));
+	}
+}
+
+void test_index_conflicts__partial(void)
+{
+	git_index_entry ancestor_entry, our_entry, their_entry;
+	const git_index_entry *conflict_entry[3];
+
+	cl_assert(git_index_entrycount(repo_index) == 8);
+
+	memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
+	memset(&our_entry, 0x0, sizeof(git_index_entry));
+	memset(&their_entry, 0x0, sizeof(git_index_entry));
+
+	ancestor_entry.path = "test-one.txt";
+	ancestor_entry.mode = 0100644;
+	GIT_IDXENTRY_STAGE_SET(&ancestor_entry, 1);
+	git_oid_fromstr(&ancestor_entry.id, TEST_ANCESTOR_OID);
+
+	cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, NULL, NULL));
+	cl_assert(git_index_entrycount(repo_index) == 9);
+
+	cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1],
+		&conflict_entry[2], repo_index, "test-one.txt"));
+
+	cl_assert_equal_oid(&ancestor_entry.id, &conflict_entry[0]->id);
+	cl_assert(conflict_entry[1] == NULL);
+	cl_assert(conflict_entry[2] == NULL);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/crlf.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/crlf.c
new file mode 100755
index 0000000..23f4793
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/crlf.c
@@ -0,0 +1,154 @@
+#include "clar_libgit2.h"
+#include "../filter/crlf.h"
+
+#include "git2/checkout.h"
+#include "repository.h"
+#include "posix.h"
+
+#define FILE_CONTENTS_LF "one\ntwo\nthree\nfour\n"
+#define FILE_CONTENTS_CRLF "one\r\ntwo\r\nthree\r\nfour\r\n"
+
+#define FILE_OID_LF "f384549cbeb481e437091320de6d1f2e15e11b4a"
+#define FILE_OID_CRLF "7fbf4d847b191141d80f30c8ab03d2ad4cd543a9"
+
+static git_repository *g_repo;
+static git_index *g_index;
+
+void test_index_crlf__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("crlf");
+	cl_git_pass(git_repository_index(&g_index, g_repo));
+}
+
+void test_index_crlf__cleanup(void)
+{
+	git_index_free(g_index);
+	cl_git_sandbox_cleanup();
+}
+
+void test_index_crlf__autocrlf_false_no_attrs(void)
+{
+	const git_index_entry *entry;
+	git_oid oid;
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", false);
+
+	cl_git_mkfile("./crlf/newfile.txt",
+		(GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_CONTENTS_CRLF : FILE_CONTENTS_LF);
+
+	cl_git_pass(git_index_add_bypath(g_index, "newfile.txt"));
+	entry = git_index_get_bypath(g_index, "newfile.txt", 0);
+
+	cl_git_pass(git_oid_fromstr(&oid,
+		(GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_OID_CRLF : FILE_OID_LF));
+	cl_assert_equal_oid(&oid, &entry->id);
+}
+
+void test_index_crlf__autocrlf_true_no_attrs(void)
+{
+	const git_index_entry *entry;
+	git_oid oid;
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+
+	cl_git_mkfile("./crlf/newfile.txt",
+		(GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_CONTENTS_CRLF : FILE_CONTENTS_LF);
+
+	cl_git_pass(git_index_add_bypath(g_index, "newfile.txt"));
+	entry = git_index_get_bypath(g_index, "newfile.txt", 0);
+
+	cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF));
+	cl_assert_equal_oid(&oid, &entry->id);
+}
+
+void test_index_crlf__autocrlf_input_no_attrs(void)
+{
+	const git_index_entry *entry;
+	git_oid oid;
+
+	cl_repo_set_string(g_repo, "core.autocrlf", "input");
+
+	cl_git_mkfile("./crlf/newfile.txt",
+		(GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_CONTENTS_CRLF : FILE_CONTENTS_LF);
+
+	cl_git_pass(git_index_add_bypath(g_index, "newfile.txt"));
+	entry = git_index_get_bypath(g_index, "newfile.txt", 0);
+
+	cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF));
+	cl_assert_equal_oid(&oid, &entry->id);
+}
+
+void test_index_crlf__autocrlf_false_text_auto_attr(void)
+{
+	const git_index_entry *entry;
+	git_oid oid;
+
+	cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n");
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", false);
+
+	cl_git_mkfile("./crlf/newfile.txt",
+		(GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_CONTENTS_CRLF : FILE_CONTENTS_LF);
+
+	cl_git_pass(git_index_add_bypath(g_index, "newfile.txt"));
+	entry = git_index_get_bypath(g_index, "newfile.txt", 0);
+
+	cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF));
+	cl_assert_equal_oid(&oid, &entry->id);
+}
+
+void test_index_crlf__autocrlf_true_text_auto_attr(void)
+{
+	const git_index_entry *entry;
+	git_oid oid;
+
+	cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n");
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", false);
+
+	cl_git_mkfile("./crlf/newfile.txt",
+		(GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_CONTENTS_CRLF : FILE_CONTENTS_LF);
+
+	cl_git_pass(git_index_add_bypath(g_index, "newfile.txt"));
+	entry = git_index_get_bypath(g_index, "newfile.txt", 0);
+
+	cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF));
+	cl_assert_equal_oid(&oid, &entry->id);
+}
+
+void test_index_crlf__autocrlf_input_text_auto_attr(void)
+{
+	const git_index_entry *entry;
+	git_oid oid;
+
+	cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n");
+
+	cl_repo_set_string(g_repo, "core.autocrlf", "input");
+
+	cl_git_mkfile("./crlf/newfile.txt",
+		(GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_CONTENTS_CRLF : FILE_CONTENTS_LF);
+
+	cl_git_pass(git_index_add_bypath(g_index, "newfile.txt"));
+	entry = git_index_get_bypath(g_index, "newfile.txt", 0);
+
+	cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF));
+	cl_assert_equal_oid(&oid, &entry->id);
+}
+
+void test_index_crlf__safecrlf_true_no_attrs(void)
+{
+	cl_repo_set_bool(g_repo, "core.autocrlf", true);
+	cl_repo_set_bool(g_repo, "core.safecrlf", true);
+
+	cl_git_mkfile("crlf/newfile.txt", ALL_LF_TEXT_RAW);
+	cl_git_pass(git_index_add_bypath(g_index, "newfile.txt"));
+
+	cl_git_mkfile("crlf/newfile.txt", ALL_CRLF_TEXT_RAW);
+	cl_git_pass(git_index_add_bypath(g_index, "newfile.txt"));
+
+	cl_git_mkfile("crlf/newfile.txt", MORE_CRLF_TEXT_RAW);
+	cl_git_fail(git_index_add_bypath(g_index, "newfile.txt"));
+
+	cl_git_mkfile("crlf/newfile.txt", MORE_LF_TEXT_RAW);
+	cl_git_fail(git_index_add_bypath(g_index, "newfile.txt"));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/filemodes.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/filemodes.c
new file mode 100755
index 0000000..b390799
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/filemodes.c
@@ -0,0 +1,250 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "posix.h"
+#include "index.h"
+
+static git_repository *g_repo = NULL;
+
+void test_index_filemodes__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("filemodes");
+}
+
+void test_index_filemodes__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_index_filemodes__read(void)
+{
+	git_index *index;
+	unsigned int i;
+	static bool expected[6] = { 0, 1, 0, 1, 0, 1 };
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_assert_equal_i(6, (int)git_index_entrycount(index));
+
+	for (i = 0; i < 6; ++i) {
+		const git_index_entry *entry = git_index_get_byindex(index, i);
+		cl_assert(entry != NULL);
+		cl_assert(((entry->mode & 0100) ? 1 : 0) == expected[i]);
+	}
+
+	git_index_free(index);
+}
+
+static void replace_file_with_mode(
+	const char *filename, const char *backup, unsigned int create_mode)
+{
+	git_buf path = GIT_BUF_INIT, content = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_joinpath(&path, "filemodes", filename));
+	cl_git_pass(git_buf_printf(&content, "%s as %08u (%d)",
+		filename, create_mode, rand()));
+
+	cl_git_pass(p_rename(path.ptr, backup));
+	cl_git_write2file(
+		path.ptr, content.ptr, content.size,
+		O_WRONLY|O_CREAT|O_TRUNC, create_mode);
+
+	git_buf_free(&path);
+	git_buf_free(&content);
+}
+
+#define add_and_check_mode(I,F,X) add_and_check_mode_(I,F,X,__FILE__,__LINE__)
+
+static void add_and_check_mode_(
+	git_index *index, const char *filename, unsigned int expect_mode,
+	const char *file, int line)
+{
+	size_t pos;
+	const git_index_entry *entry;
+
+	cl_git_pass(git_index_add_bypath(index, filename));
+
+	clar__assert(!git_index_find(&pos, index, filename),
+		file, line, "Cannot find index entry", NULL, 1);
+
+	entry = git_index_get_byindex(index, pos);
+
+	clar__assert_equal(file, line, "Expected mode does not match index",
+		1, "%07o", (unsigned int)entry->mode, (unsigned int)expect_mode);
+}
+
+void test_index_filemodes__untrusted(void)
+{
+	git_index *index;
+
+	cl_repo_set_bool(g_repo, "core.filemode", false);
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_assert((git_index_caps(index) & GIT_INDEXCAP_NO_FILEMODE) != 0);
+
+	/* 1 - add 0644 over existing 0644 -> expect 0644 */
+	replace_file_with_mode("exec_off", "filemodes/exec_off.0", 0644);
+	add_and_check_mode(index, "exec_off", GIT_FILEMODE_BLOB);
+
+	/* 2 - add 0644 over existing 0755 -> expect 0755 */
+	replace_file_with_mode("exec_on", "filemodes/exec_on.0", 0644);
+	add_and_check_mode(index, "exec_on", GIT_FILEMODE_BLOB_EXECUTABLE);
+
+	/* 3 - add 0755 over existing 0644 -> expect 0644 */
+	replace_file_with_mode("exec_off", "filemodes/exec_off.1", 0755);
+	add_and_check_mode(index, "exec_off", GIT_FILEMODE_BLOB);
+
+	/* 4 - add 0755 over existing 0755 -> expect 0755 */
+	replace_file_with_mode("exec_on", "filemodes/exec_on.1", 0755);
+	add_and_check_mode(index, "exec_on", GIT_FILEMODE_BLOB_EXECUTABLE);
+
+	/*  5 - add new 0644 -> expect 0644 */
+	cl_git_write2file("filemodes/new_off", "blah", 0,
+		O_WRONLY | O_CREAT | O_TRUNC, 0644);
+	add_and_check_mode(index, "new_off", GIT_FILEMODE_BLOB);
+
+	/* 6 - add new 0755 -> expect 0644 if core.filemode == false */
+	cl_git_write2file("filemodes/new_on", "blah", 0,
+		O_WRONLY | O_CREAT | O_TRUNC, 0755);
+	add_and_check_mode(index, "new_on", GIT_FILEMODE_BLOB);
+
+	git_index_free(index);
+}
+
+void test_index_filemodes__trusted(void)
+{
+	git_index *index;
+
+	/* Only run these tests on platforms where I can actually
+	 * chmod a file and get the stat results I expect!
+	 */
+	if (!cl_is_chmod_supported())
+		return;
+
+	cl_repo_set_bool(g_repo, "core.filemode", true);
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_assert((git_index_caps(index) & GIT_INDEXCAP_NO_FILEMODE) == 0);
+
+	/* 1 - add 0644 over existing 0644 -> expect 0644 */
+	replace_file_with_mode("exec_off", "filemodes/exec_off.0", 0644);
+	add_and_check_mode(index, "exec_off", GIT_FILEMODE_BLOB);
+
+	/* 2 - add 0644 over existing 0755 -> expect 0644 */
+	replace_file_with_mode("exec_on", "filemodes/exec_on.0", 0644);
+	add_and_check_mode(index, "exec_on", GIT_FILEMODE_BLOB);
+
+	/* 3 - add 0755 over existing 0644 -> expect 0755 */
+	replace_file_with_mode("exec_off", "filemodes/exec_off.1", 0755);
+	add_and_check_mode(index, "exec_off", GIT_FILEMODE_BLOB_EXECUTABLE);
+
+	/* 4 - add 0755 over existing 0755 -> expect 0755 */
+	replace_file_with_mode("exec_on", "filemodes/exec_on.1", 0755);
+	add_and_check_mode(index, "exec_on", GIT_FILEMODE_BLOB_EXECUTABLE);
+
+	/*  5 - add new 0644 -> expect 0644 */
+	cl_git_write2file("filemodes/new_off", "blah", 0,
+		O_WRONLY | O_CREAT | O_TRUNC, 0644);
+	add_and_check_mode(index, "new_off", GIT_FILEMODE_BLOB);
+
+	/* 6 - add 0755 -> expect 0755 */
+	cl_git_write2file("filemodes/new_on", "blah", 0,
+		O_WRONLY | O_CREAT | O_TRUNC, 0755);
+	add_and_check_mode(index, "new_on", GIT_FILEMODE_BLOB_EXECUTABLE);
+
+	git_index_free(index);
+}
+
+#define add_entry_and_check_mode(I,FF,X) add_entry_and_check_mode_(I,FF,X,__FILE__,__LINE__)
+
+static void add_entry_and_check_mode_(
+	git_index *index, bool from_file, git_filemode_t mode,
+	const char *file, int line)
+{
+	size_t pos;
+	const git_index_entry* entry;
+	git_index_entry new_entry;
+
+	/* If old_filename exists, we copy that to the new file, and test
+	 * git_index_add(), otherwise create a new entry testing git_index_add_frombuffer
+	 */
+	if (from_file)
+	{
+		clar__assert(!git_index_find(&pos, index, "exec_off"),
+			file, line, "Cannot find original index entry", NULL, 1);
+
+		entry = git_index_get_byindex(index, pos);
+
+		memcpy(&new_entry, entry, sizeof(new_entry));
+	}
+	else
+		memset(&new_entry, 0x0, sizeof(git_index_entry));
+
+	new_entry.path = "filemodes/explicit_test";
+	new_entry.mode = mode;
+
+	if (from_file)
+	{
+		clar__assert(!git_index_add(index, &new_entry),
+			file, line, "Cannot add index entry", NULL, 1);
+	}
+	else
+	{
+		const char *content = "hey there\n";
+		clar__assert(!git_index_add_frombuffer(index, &new_entry, content, strlen(content)),
+			file, line, "Cannot add index entry from buffer", NULL, 1);
+	}
+
+	clar__assert(!git_index_find(&pos, index, "filemodes/explicit_test"),
+		file, line, "Cannot find new index entry", NULL, 1);
+
+	entry = git_index_get_byindex(index, pos);
+
+	clar__assert_equal(file, line, "Expected mode does not match index",
+		1, "%07o", (unsigned int)entry->mode, (unsigned int)mode);
+}
+
+void test_index_filemodes__explicit(void)
+{
+	git_index *index;
+
+	/* These tests should run and work everywhere, as the filemode is
+	 * given explicitly to git_index_add or git_index_add_frombuffer
+	 */
+	cl_repo_set_bool(g_repo, "core.filemode", false);
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	/* Each of these tests keeps overwriting the same file in the index. */
+	/* 1 - add new 0644 entry  */
+	add_entry_and_check_mode(index, true, GIT_FILEMODE_BLOB);
+
+	/* 2 - add 0755 entry over existing 0644 */
+	add_entry_and_check_mode(index, true, GIT_FILEMODE_BLOB_EXECUTABLE);
+
+	/* 3 - add 0644 entry over existing 0755 */
+	add_entry_and_check_mode(index, true, GIT_FILEMODE_BLOB);
+
+	/* 4 - add 0755 buffer entry over existing 0644  */
+	add_entry_and_check_mode(index, false, GIT_FILEMODE_BLOB_EXECUTABLE);
+
+	/* 5 - add 0644 buffer entry over existing 0755 */
+	add_entry_and_check_mode(index, false, GIT_FILEMODE_BLOB);
+
+	git_index_free(index);
+}
+
+void test_index_filemodes__invalid(void)
+{
+	git_index *index;
+	git_index_entry entry;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	entry.path = "foo";
+	entry.mode = GIT_OBJ_BLOB;
+	cl_git_fail(git_index_add(index, &entry));
+
+	entry.mode = GIT_FILEMODE_BLOB;
+	cl_git_pass(git_index_add(index, &entry));
+
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/inmemory.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/inmemory.c
new file mode 100755
index 0000000..38e91e0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/inmemory.c
@@ -0,0 +1,22 @@
+#include "clar_libgit2.h"
+
+void test_index_inmemory__can_create_an_inmemory_index(void)
+{
+	git_index *index;
+
+	cl_git_pass(git_index_new(&index));
+	cl_assert_equal_i(0, (int)git_index_entrycount(index));
+
+	git_index_free(index);
+}
+
+void test_index_inmemory__cannot_add_bypath_to_an_inmemory_index(void)
+{
+	git_index *index;
+
+	cl_git_pass(git_index_new(&index));
+
+	cl_assert_equal_i(GIT_ERROR, git_index_add_bypath(index, "test.txt"));
+
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/names.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/names.c
new file mode 100755
index 0000000..d462088
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/names.c
@@ -0,0 +1,148 @@
+#include "clar_libgit2.h"
+#include "index.h"
+#include "git2/sys/index.h"
+#include "git2/repository.h"
+#include "../reset/reset_helpers.h"
+
+static git_repository *repo;
+static git_index *repo_index;
+
+#define TEST_REPO_PATH "mergedrepo"
+#define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index"
+
+// Fixture setup and teardown
+void test_index_names__initialize(void)
+{
+	repo = cl_git_sandbox_init("mergedrepo");
+	git_repository_index(&repo_index, repo);
+}
+
+void test_index_names__cleanup(void)
+{
+	git_index_free(repo_index);
+	repo_index = NULL;
+
+	cl_git_sandbox_cleanup();
+}
+
+void test_index_names__add(void)
+{
+	const git_index_name_entry *conflict_name;
+
+	cl_git_pass(git_index_name_add(repo_index, "ancestor", "ours", "theirs"));
+	cl_git_pass(git_index_name_add(repo_index, "ancestor2", "ours2", NULL));
+	cl_git_pass(git_index_name_add(repo_index, "ancestor3", NULL, "theirs3"));
+
+	cl_assert(git_index_name_entrycount(repo_index) == 3);
+
+	conflict_name = git_index_name_get_byindex(repo_index, 0);
+	cl_assert(strcmp(conflict_name->ancestor, "ancestor") == 0);
+	cl_assert(strcmp(conflict_name->ours, "ours") == 0);
+	cl_assert(strcmp(conflict_name->theirs, "theirs") == 0);
+
+	conflict_name = git_index_name_get_byindex(repo_index, 1);
+	cl_assert(strcmp(conflict_name->ancestor, "ancestor2") == 0);
+	cl_assert(strcmp(conflict_name->ours, "ours2") == 0);
+	cl_assert(conflict_name->theirs == NULL);
+
+	conflict_name = git_index_name_get_byindex(repo_index, 2);
+	cl_assert(strcmp(conflict_name->ancestor, "ancestor3") == 0);
+	cl_assert(conflict_name->ours == NULL);
+	cl_assert(strcmp(conflict_name->theirs, "theirs3") == 0);
+}
+
+void test_index_names__roundtrip(void)
+{
+	const git_index_name_entry *conflict_name;
+
+	cl_git_pass(git_index_name_add(repo_index, "ancestor", "ours", "theirs"));
+	cl_git_pass(git_index_name_add(repo_index, "ancestor2", "ours2", NULL));
+	cl_git_pass(git_index_name_add(repo_index, "ancestor3", NULL, "theirs3"));
+
+	cl_git_pass(git_index_write(repo_index));
+	git_index_clear(repo_index);
+	cl_assert(git_index_name_entrycount(repo_index) == 0);
+
+	cl_git_pass(git_index_read(repo_index, true));
+	cl_assert(git_index_name_entrycount(repo_index) == 3);
+
+	conflict_name = git_index_name_get_byindex(repo_index, 0);
+	cl_assert(strcmp(conflict_name->ancestor, "ancestor") == 0);
+	cl_assert(strcmp(conflict_name->ours, "ours") == 0);
+	cl_assert(strcmp(conflict_name->theirs, "theirs") == 0);
+
+	conflict_name = git_index_name_get_byindex(repo_index, 1);
+	cl_assert(strcmp(conflict_name->ancestor, "ancestor2") == 0);
+	cl_assert(strcmp(conflict_name->ours, "ours2") == 0);
+	cl_assert(conflict_name->theirs == NULL);
+
+	conflict_name = git_index_name_get_byindex(repo_index, 2);
+	cl_assert(strcmp(conflict_name->ancestor, "ancestor3") == 0);
+	cl_assert(conflict_name->ours == NULL);
+	cl_assert(strcmp(conflict_name->theirs, "theirs3") == 0);
+}
+
+void test_index_names__cleaned_on_reset_hard(void)
+{
+	git_object *target;
+
+	cl_git_pass(git_revparse_single(&target, repo, "3a34580"));
+
+	test_index_names__add();
+	cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL));
+	cl_assert(git_index_name_entrycount(repo_index) == 0);
+
+	git_object_free(target);
+}
+
+void test_index_names__cleaned_on_reset_mixed(void)
+{
+	git_object *target;
+
+	cl_git_pass(git_revparse_single(&target, repo, "3a34580"));
+
+	test_index_names__add();
+	cl_git_pass(git_reset(repo, target, GIT_RESET_MIXED, NULL));
+	cl_assert(git_index_name_entrycount(repo_index) == 0);
+
+	git_object_free(target);
+}
+
+void test_index_names__cleaned_on_checkout_tree(void)
+{
+	git_oid oid;
+	git_object *obj;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
+
+	test_index_names__add();
+	git_reference_name_to_id(&oid, repo, "refs/heads/master");
+	git_object_lookup(&obj, repo, &oid, GIT_OBJ_ANY);
+	git_checkout_tree(repo, obj, &opts);
+	cl_assert_equal_sz(0, git_index_name_entrycount(repo_index));
+
+	git_object_free(obj);
+}
+
+void test_index_names__cleaned_on_checkout_head(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
+
+	test_index_names__add();
+	git_checkout_head(repo, &opts);
+	cl_assert_equal_sz(0, git_index_name_entrycount(repo_index));
+}
+
+void test_index_names__retained_on_checkout_index(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
+
+	test_index_names__add();
+	git_checkout_index(repo, repo_index, &opts);
+	cl_assert(git_index_name_entrycount(repo_index) > 0);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/racy.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/racy.c
new file mode 100755
index 0000000..3b26aab
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/racy.c
@@ -0,0 +1,147 @@
+#include "clar_libgit2.h"
+#include "../checkout/checkout_helpers.h"
+
+#include "buffer.h"
+#include "index.h"
+#include "repository.h"
+
+static git_repository *g_repo;
+
+void test_index_racy__initialize(void)
+{
+	cl_git_pass(git_repository_init(&g_repo, "diff_racy", false));
+}
+
+void test_index_racy__cleanup(void)
+{
+	git_repository_free(g_repo);
+	g_repo = NULL;
+
+	cl_fixture_cleanup("diff_racy");
+}
+
+void test_index_racy__diff(void)
+{
+	git_index *index;
+	git_diff *diff;
+	git_buf path = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "A"));
+	cl_git_mkfile(path.ptr, "A");
+
+	/* Put 'A' into the index */
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_add_bypath(index, "A"));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, NULL));
+	cl_assert_equal_i(0, git_diff_num_deltas(diff));
+	git_diff_free(diff);
+
+	/* Change its contents quickly, so we get the same timestamp */
+	cl_git_mkfile(path.ptr, "B");
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, NULL));
+	cl_assert_equal_i(1, git_diff_num_deltas(diff));
+
+	git_index_free(index);
+	git_diff_free(diff);
+	git_buf_free(&path);
+}
+
+void test_index_racy__write_index_just_after_file(void)
+{
+	git_index *index;
+	git_diff *diff;
+	git_buf path = GIT_BUF_INIT;
+	struct timeval times[2];
+
+	/* Make sure we do have a timestamp */
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "A"));
+	cl_git_mkfile(path.ptr, "A");
+	/* Force the file's timestamp to be a second after we wrote the index */
+	times[0].tv_sec = index->stamp.mtime + 1;
+	times[0].tv_usec = 0;
+	times[1].tv_sec = index->stamp.mtime + 1;
+	times[1].tv_usec = 0;
+	cl_git_pass(p_utimes(path.ptr, times));
+
+	/*
+	 * Put 'A' into the index, the size field will be filled,
+	 * because the index' on-disk timestamp does not match the
+	 * file's timestamp.
+	 */
+	cl_git_pass(git_index_add_bypath(index, "A"));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_mkfile(path.ptr, "B");
+	/*
+	 * Pretend this index' modification happend a second after the
+	 * file update, and rewrite the file in that same second.
+	 */
+	times[0].tv_sec = index->stamp.mtime + 2;
+	times[0].tv_usec = 0;
+	times[1].tv_sec = index->stamp.mtime + 2;
+	times[0].tv_usec = 0;
+
+	cl_git_pass(p_utimes(git_index_path(index), times));
+	cl_git_pass(p_utimes(path.ptr, times));
+
+	cl_git_pass(git_index_read(index, true));
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, NULL));
+	cl_assert_equal_i(1, git_diff_num_deltas(diff));
+
+	git_buf_free(&path);
+	git_diff_free(diff);
+	git_index_free(index);
+}
+
+void test_index_racy__empty_file_after_smudge(void)
+{
+	git_index *index;
+	git_diff *diff;
+	git_buf path = GIT_BUF_INIT;
+	int i, found_race = 0;
+	const git_index_entry *entry;
+
+	/* Make sure we do have a timestamp */
+	cl_git_pass(git_repository_index__weakptr(&index, g_repo));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "A"));
+
+	/* Make sure writing the file, adding and rewriting happen in the same second */
+	for (i = 0; i < 10; i++) {
+		struct stat st;
+		cl_git_mkfile(path.ptr, "A");
+
+		cl_git_pass(git_index_add_bypath(index, "A"));
+		cl_git_mkfile(path.ptr, "B");
+		cl_git_pass(git_index_write(index));
+
+		cl_git_mkfile(path.ptr, "");
+
+		cl_git_pass(p_stat(path.ptr, &st));
+		cl_assert(entry = git_index_get_bypath(index, "A", 0));
+		if (entry->mtime.seconds == (int32_t) st.st_mtime) {
+			found_race = 1;
+			break;
+		}
+
+	}
+
+	if (!found_race)
+		cl_fail("failed to find race after 10 attempts");
+
+	cl_assert_equal_i(0, entry->file_size);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, NULL));
+	cl_assert_equal_i(1, git_diff_num_deltas(diff));
+
+	git_buf_free(&path);
+	git_diff_free(diff);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/read_index.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/read_index.c
new file mode 100755
index 0000000..82a771d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/read_index.c
@@ -0,0 +1,73 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "index.h"
+
+static git_repository *_repo;
+static git_index *_index;
+
+void test_index_read_index__initialize(void)
+{
+	git_object *head;
+	git_reference *head_ref;
+
+	_repo = cl_git_sandbox_init("testrepo");
+	cl_git_pass(git_revparse_ext(&head, &head_ref, _repo, "HEAD"));
+	cl_git_pass(git_reset(_repo, head, GIT_RESET_HARD, NULL));
+	cl_git_pass(git_repository_index(&_index, _repo));
+
+	git_reference_free(head_ref);
+	git_object_free(head);
+}
+
+void test_index_read_index__cleanup(void)
+{
+	git_index_free(_index);
+	cl_git_sandbox_cleanup();
+}
+
+void test_index_read_index__maintains_stat_cache(void)
+{
+	git_index *new_index;
+	git_oid index_id;
+	git_index_entry new_entry;
+	const git_index_entry *e;
+	git_tree *tree;
+	size_t i;
+
+	cl_assert_equal_i(4, git_index_entrycount(_index));
+
+	/* write-tree */
+	cl_git_pass(git_index_write_tree(&index_id, _index));
+
+	/* read-tree, then read index */
+	git_tree_lookup(&tree, _repo, &index_id);
+	cl_git_pass(git_index_new(&new_index));
+	cl_git_pass(git_index_read_tree(new_index, tree));
+	git_tree_free(tree);
+
+	/* add a new entry that will not have stat data */
+	memset(&new_entry, 0, sizeof(git_index_entry));
+	new_entry.path = "Hello";
+	git_oid_fromstr(&new_entry.id, "0123456789012345678901234567890123456789");
+	new_entry.file_size = 1234;
+	new_entry.mode = 0100644;
+	cl_git_pass(git_index_add(new_index, &new_entry));
+	cl_assert_equal_i(5, git_index_entrycount(new_index));
+
+	cl_git_pass(git_index_read_index(_index, new_index));
+	git_index_free(new_index);
+
+	cl_assert_equal_i(5, git_index_entrycount(_index));
+
+	for (i = 0; i < git_index_entrycount(_index); i++) {
+		e = git_index_get_byindex(_index, i);
+
+		if (strcmp(e->path, "Hello") == 0) {
+			cl_assert_equal_i(0, e->ctime.seconds);
+			cl_assert_equal_i(0, e->mtime.seconds);
+		} else {
+			cl_assert(0 != e->ctime.seconds);
+			cl_assert(0 != e->mtime.seconds);
+		}
+	}
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/read_tree.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/read_tree.c
new file mode 100755
index 0000000..0e18828
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/read_tree.c
@@ -0,0 +1,46 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+
+/* Test that reading and writing a tree is a no-op */
+void test_index_read_tree__read_write_involution(void)
+{
+	git_repository *repo;
+	git_index *index;
+	git_oid tree_oid;
+	git_tree *tree;
+	git_oid expected;
+
+	p_mkdir("read_tree", 0700);
+
+	cl_git_pass(git_repository_init(&repo, "./read_tree", 0));
+	cl_git_pass(git_repository_index(&index, repo));
+
+	cl_assert(git_index_entrycount(index) == 0);
+
+	p_mkdir("./read_tree/abc", 0700);
+
+	/* Sort order: '-' < '/' < '_' */
+	cl_git_mkfile("./read_tree/abc-d", NULL);
+	cl_git_mkfile("./read_tree/abc/d", NULL);
+	cl_git_mkfile("./read_tree/abc_d", NULL);
+
+	cl_git_pass(git_index_add_bypath(index, "abc-d"));
+	cl_git_pass(git_index_add_bypath(index, "abc_d"));
+	cl_git_pass(git_index_add_bypath(index, "abc/d"));
+
+	/* write-tree */
+	cl_git_pass(git_index_write_tree(&expected, index));
+
+	/* read-tree */
+	git_tree_lookup(&tree, repo, &expected);
+	cl_git_pass(git_index_read_tree(index, tree));
+	git_tree_free(tree);
+
+	cl_git_pass(git_index_write_tree(&tree_oid, index));
+	cl_assert_equal_oid(&expected, &tree_oid);
+
+	git_index_free(index);
+	git_repository_free(repo);
+
+	cl_fixture_cleanup("read_tree");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/rename.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/rename.c
new file mode 100755
index 0000000..dd3cfa7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/rename.c
@@ -0,0 +1,50 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+
+void test_index_rename__single_file(void)
+{
+	git_repository *repo;
+	git_index *index;
+	size_t position;
+	git_oid expected;
+	const git_index_entry *entry;
+
+	p_mkdir("rename", 0700);
+
+	cl_git_pass(git_repository_init(&repo, "./rename", 0));
+	cl_git_pass(git_repository_index(&index, repo));
+
+	cl_assert(git_index_entrycount(index) == 0);
+
+	cl_git_mkfile("./rename/lame.name.txt", "new_file\n");
+
+	/* This should add a new blob to the object database in 'd4/fa8600b4f37d7516bef4816ae2c64dbf029e3a' */
+	cl_git_pass(git_index_add_bypath(index, "lame.name.txt"));
+	cl_assert(git_index_entrycount(index) == 1);
+
+	cl_git_pass(git_oid_fromstr(&expected, "d4fa8600b4f37d7516bef4816ae2c64dbf029e3a"));
+
+	cl_assert(!git_index_find(&position, index, "lame.name.txt"));
+
+	entry = git_index_get_byindex(index, position);
+	cl_assert_equal_oid(&expected, &entry->id);
+
+	/* This removes the entry from the index, but not from the object database */
+	cl_git_pass(git_index_remove(index, "lame.name.txt", 0));
+	cl_assert(git_index_entrycount(index) == 0);
+
+	p_rename("./rename/lame.name.txt", "./rename/fancy.name.txt");
+
+	cl_git_pass(git_index_add_bypath(index, "fancy.name.txt"));
+	cl_assert(git_index_entrycount(index) == 1);
+
+	cl_assert(!git_index_find(&position, index, "fancy.name.txt"));
+
+	entry = git_index_get_byindex(index, position);
+	cl_assert_equal_oid(&expected, &entry->id);
+
+	git_index_free(index);
+	git_repository_free(repo);
+
+	cl_fixture_cleanup("rename");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/reuc.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/reuc.c
new file mode 100755
index 0000000..e57facc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/reuc.c
@@ -0,0 +1,372 @@
+#include "clar_libgit2.h"
+#include "index.h"
+#include "git2/sys/index.h"
+#include "git2/repository.h"
+#include "../reset/reset_helpers.h"
+
+static git_repository *repo;
+static git_index *repo_index;
+
+#define TEST_REPO_PATH "mergedrepo"
+#define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index"
+
+#define ONE_ANCESTOR_OID "478871385b9cd03908c5383acfd568bef023c6b3"
+#define ONE_OUR_OID "4458b8bc9e72b6c8755ae456f60e9844d0538d8c"
+#define ONE_THEIR_OID "8b72416545c7e761b64cecad4f1686eae4078aa8"
+
+#define TWO_ANCESTOR_OID "9d81f82fccc7dcd7de7a1ffead1815294c2e092c"
+#define TWO_OUR_OID "8f3c06cff9a83757cec40c80bc9bf31a2582bde9"
+#define TWO_THEIR_OID "887b153b165d32409c70163e0f734c090f12f673"
+
+// Fixture setup and teardown
+void test_index_reuc__initialize(void)
+{
+	repo = cl_git_sandbox_init("mergedrepo");
+	git_repository_index(&repo_index, repo);
+}
+
+void test_index_reuc__cleanup(void)
+{
+	git_index_free(repo_index);
+	repo_index = NULL;
+
+	cl_git_sandbox_cleanup();
+}
+
+void test_index_reuc__add(void)
+{
+	git_oid ancestor_oid, our_oid, their_oid;
+	const git_index_reuc_entry *reuc;
+
+	git_oid_fromstr(&ancestor_oid, ONE_ANCESTOR_OID);
+	git_oid_fromstr(&our_oid, ONE_OUR_OID);
+	git_oid_fromstr(&their_oid, ONE_THEIR_OID);
+
+	cl_git_pass(git_index_reuc_add(repo_index, "newfile.txt",
+		0100644, &ancestor_oid,
+		0100644, &our_oid,
+		0100644, &their_oid));
+
+	cl_assert(reuc = git_index_reuc_get_bypath(repo_index, "newfile.txt"));
+
+	cl_assert_equal_s("newfile.txt", reuc->path);
+	cl_assert(reuc->mode[0] == 0100644);
+	cl_assert(reuc->mode[1] == 0100644);
+	cl_assert(reuc->mode[2] == 0100644);
+	cl_assert_equal_oid(&reuc->oid[0], &ancestor_oid);
+	cl_assert_equal_oid(&reuc->oid[1], &our_oid);
+	cl_assert_equal_oid(&reuc->oid[2], &their_oid);
+}
+
+void test_index_reuc__add_no_ancestor(void)
+{
+	git_oid ancestor_oid, our_oid, their_oid;
+	const git_index_reuc_entry *reuc;
+
+	memset(&ancestor_oid, 0x0, sizeof(git_oid));
+	git_oid_fromstr(&our_oid, ONE_OUR_OID);
+	git_oid_fromstr(&their_oid, ONE_THEIR_OID);
+
+	cl_git_pass(git_index_reuc_add(repo_index, "newfile.txt",
+		0, NULL,
+		0100644, &our_oid,
+		0100644, &their_oid));
+
+	cl_assert(reuc = git_index_reuc_get_bypath(repo_index, "newfile.txt"));
+
+	cl_assert_equal_s("newfile.txt", reuc->path);
+	cl_assert(reuc->mode[0] == 0);
+	cl_assert(reuc->mode[1] == 0100644);
+	cl_assert(reuc->mode[2] == 0100644);
+	cl_assert_equal_oid(&reuc->oid[0], &ancestor_oid);
+	cl_assert_equal_oid(&reuc->oid[1], &our_oid);
+	cl_assert_equal_oid(&reuc->oid[2], &their_oid);
+}
+
+void test_index_reuc__read_bypath(void)
+{
+	const git_index_reuc_entry *reuc;
+	git_oid oid;
+
+	cl_assert_equal_i(2, git_index_reuc_entrycount(repo_index));
+
+	cl_assert(reuc = git_index_reuc_get_bypath(repo_index, "two.txt"));
+
+	cl_assert_equal_s("two.txt", reuc->path);
+	cl_assert(reuc->mode[0] == 0100644);
+	cl_assert(reuc->mode[1] == 0100644);
+	cl_assert(reuc->mode[2] == 0100644);
+	git_oid_fromstr(&oid, TWO_ANCESTOR_OID);
+	cl_assert_equal_oid(&reuc->oid[0], &oid);
+	git_oid_fromstr(&oid, TWO_OUR_OID);
+	cl_assert_equal_oid(&reuc->oid[1], &oid);
+	git_oid_fromstr(&oid, TWO_THEIR_OID);
+	cl_assert_equal_oid(&reuc->oid[2], &oid);
+
+	cl_assert(reuc = git_index_reuc_get_bypath(repo_index, "one.txt"));
+
+	cl_assert_equal_s("one.txt", reuc->path);
+	cl_assert(reuc->mode[0] == 0100644);
+	cl_assert(reuc->mode[1] == 0100644);
+	cl_assert(reuc->mode[2] == 0100644);
+	git_oid_fromstr(&oid, ONE_ANCESTOR_OID);
+	cl_assert_equal_oid(&reuc->oid[0], &oid);
+	git_oid_fromstr(&oid, ONE_OUR_OID);
+	cl_assert_equal_oid(&reuc->oid[1], &oid);
+	git_oid_fromstr(&oid, ONE_THEIR_OID);
+	cl_assert_equal_oid(&reuc->oid[2], &oid);
+}
+
+void test_index_reuc__ignore_case(void)
+{
+	const git_index_reuc_entry *reuc;
+	git_oid oid;
+	int index_caps;
+
+	index_caps = git_index_caps(repo_index);
+
+	index_caps &= ~GIT_INDEXCAP_IGNORE_CASE;
+	cl_git_pass(git_index_set_caps(repo_index, index_caps));
+
+	cl_assert(!git_index_reuc_get_bypath(repo_index, "TWO.txt"));
+
+	index_caps |= GIT_INDEXCAP_IGNORE_CASE;
+	cl_git_pass(git_index_set_caps(repo_index, index_caps));
+
+	cl_assert_equal_i(2, git_index_reuc_entrycount(repo_index));
+
+	cl_assert(reuc = git_index_reuc_get_bypath(repo_index, "TWO.txt"));
+
+	cl_assert_equal_s("two.txt", reuc->path);
+	cl_assert(reuc->mode[0] == 0100644);
+	cl_assert(reuc->mode[1] == 0100644);
+	cl_assert(reuc->mode[2] == 0100644);
+	git_oid_fromstr(&oid, TWO_ANCESTOR_OID);
+	cl_assert_equal_oid(&reuc->oid[0], &oid);
+	git_oid_fromstr(&oid, TWO_OUR_OID);
+	cl_assert_equal_oid(&reuc->oid[1], &oid);
+	git_oid_fromstr(&oid, TWO_THEIR_OID);
+	cl_assert_equal_oid(&reuc->oid[2], &oid);
+}
+
+void test_index_reuc__read_byindex(void)
+{
+	const git_index_reuc_entry *reuc;
+	git_oid oid;
+
+	cl_assert_equal_i(2, git_index_reuc_entrycount(repo_index));
+
+	cl_assert(reuc = git_index_reuc_get_byindex(repo_index, 0));
+
+	cl_assert_equal_s("one.txt", reuc->path);
+	cl_assert(reuc->mode[0] == 0100644);
+	cl_assert(reuc->mode[1] == 0100644);
+	cl_assert(reuc->mode[2] == 0100644);
+	git_oid_fromstr(&oid, ONE_ANCESTOR_OID);
+	cl_assert_equal_oid(&reuc->oid[0], &oid);
+	git_oid_fromstr(&oid, ONE_OUR_OID);
+	cl_assert_equal_oid(&reuc->oid[1], &oid);
+	git_oid_fromstr(&oid, ONE_THEIR_OID);
+	cl_assert_equal_oid(&reuc->oid[2], &oid);
+
+	cl_assert(reuc = git_index_reuc_get_byindex(repo_index, 1));
+
+	cl_assert_equal_s("two.txt", reuc->path);
+	cl_assert(reuc->mode[0] == 0100644);
+	cl_assert(reuc->mode[1] == 0100644);
+	cl_assert(reuc->mode[2] == 0100644);
+	git_oid_fromstr(&oid, TWO_ANCESTOR_OID);
+	cl_assert_equal_oid(&reuc->oid[0], &oid);
+	git_oid_fromstr(&oid, TWO_OUR_OID);
+	cl_assert_equal_oid(&reuc->oid[1], &oid);
+	git_oid_fromstr(&oid, TWO_THEIR_OID);
+	cl_assert_equal_oid(&reuc->oid[2], &oid);
+}
+
+void test_index_reuc__updates_existing(void)
+{
+	const git_index_reuc_entry *reuc;
+	git_oid ancestor_oid, our_oid, their_oid, oid;
+	int index_caps;
+
+	git_index_clear(repo_index);
+
+	index_caps = git_index_caps(repo_index);
+
+	index_caps |= GIT_INDEXCAP_IGNORE_CASE;
+	cl_git_pass(git_index_set_caps(repo_index, index_caps));
+
+	git_oid_fromstr(&ancestor_oid, TWO_ANCESTOR_OID);
+	git_oid_fromstr(&our_oid, TWO_OUR_OID);
+	git_oid_fromstr(&their_oid, TWO_THEIR_OID);
+
+	cl_git_pass(git_index_reuc_add(repo_index, "two.txt",
+		0100644, &ancestor_oid,
+		0100644, &our_oid,
+		0100644, &their_oid));
+
+	cl_git_pass(git_index_reuc_add(repo_index, "TWO.txt",
+		0100644, &our_oid,
+		0100644, &their_oid,
+		0100644, &ancestor_oid));
+
+	cl_assert_equal_i(1, git_index_reuc_entrycount(repo_index));
+
+	cl_assert(reuc = git_index_reuc_get_byindex(repo_index, 0));
+
+	cl_assert_equal_s("TWO.txt", reuc->path);
+	git_oid_fromstr(&oid, TWO_OUR_OID);
+	cl_assert_equal_oid(&reuc->oid[0], &oid);
+	git_oid_fromstr(&oid, TWO_THEIR_OID);
+	cl_assert_equal_oid(&reuc->oid[1], &oid);
+	git_oid_fromstr(&oid, TWO_ANCESTOR_OID);
+	cl_assert_equal_oid(&reuc->oid[2], &oid);
+}
+
+void test_index_reuc__remove(void)
+{
+	git_oid oid;
+	const git_index_reuc_entry *reuc;
+
+	cl_assert_equal_i(2, git_index_reuc_entrycount(repo_index));
+
+	cl_git_pass(git_index_reuc_remove(repo_index, 0));
+	cl_git_fail(git_index_reuc_remove(repo_index, 1));
+
+	cl_assert_equal_i(1, git_index_reuc_entrycount(repo_index));
+
+	cl_assert(reuc = git_index_reuc_get_byindex(repo_index, 0));
+
+	cl_assert_equal_s("two.txt", reuc->path);
+	cl_assert(reuc->mode[0] == 0100644);
+	cl_assert(reuc->mode[1] == 0100644);
+	cl_assert(reuc->mode[2] == 0100644);
+	git_oid_fromstr(&oid, TWO_ANCESTOR_OID);
+	cl_assert_equal_oid(&reuc->oid[0], &oid);
+	git_oid_fromstr(&oid, TWO_OUR_OID);
+	cl_assert_equal_oid(&reuc->oid[1], &oid);
+	git_oid_fromstr(&oid, TWO_THEIR_OID);
+	cl_assert_equal_oid(&reuc->oid[2], &oid);
+}
+
+void test_index_reuc__write(void)
+{
+	git_oid ancestor_oid, our_oid, their_oid;
+	const git_index_reuc_entry *reuc;
+
+	git_index_clear(repo_index);
+
+	/* Write out of order to ensure sorting is correct */
+	git_oid_fromstr(&ancestor_oid, TWO_ANCESTOR_OID);
+	git_oid_fromstr(&our_oid, TWO_OUR_OID);
+	git_oid_fromstr(&their_oid, TWO_THEIR_OID);
+
+	cl_git_pass(git_index_reuc_add(repo_index, "two.txt",
+		0100644, &ancestor_oid,
+		0100644, &our_oid,
+		0100644, &their_oid));
+
+	git_oid_fromstr(&ancestor_oid, ONE_ANCESTOR_OID);
+	git_oid_fromstr(&our_oid, ONE_OUR_OID);
+	git_oid_fromstr(&their_oid, ONE_THEIR_OID);
+
+	cl_git_pass(git_index_reuc_add(repo_index, "one.txt",
+		0100644, &ancestor_oid,
+		0100644, &our_oid,
+		0100644, &their_oid));
+
+	cl_git_pass(git_index_write(repo_index));
+	cl_assert_equal_i(2, git_index_reuc_entrycount(repo_index));
+
+	/* ensure sort order was round-tripped correct */
+	cl_assert(reuc = git_index_reuc_get_byindex(repo_index, 0));
+	cl_assert_equal_s("one.txt", reuc->path);
+
+	cl_assert(reuc = git_index_reuc_get_byindex(repo_index, 1));
+	cl_assert_equal_s("two.txt", reuc->path);
+}
+
+static int reuc_entry_exists(void)
+{
+	return (git_index_reuc_get_bypath(repo_index, "newfile.txt") != NULL);
+}
+
+void test_index_reuc__cleaned_on_reset_hard(void)
+{
+	git_object *target;
+
+	cl_git_pass(git_revparse_single(&target, repo, "3a34580"));
+
+	test_index_reuc__add();
+	cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL));
+	cl_assert(reuc_entry_exists() == false);
+
+	git_object_free(target);
+}
+
+void test_index_reuc__cleaned_on_reset_mixed(void)
+{
+	git_object *target;
+
+	cl_git_pass(git_revparse_single(&target, repo, "3a34580"));
+
+	test_index_reuc__add();
+	cl_git_pass(git_reset(repo, target, GIT_RESET_MIXED, NULL));
+	cl_assert(reuc_entry_exists() == false);
+
+	git_object_free(target);
+}
+
+void test_index_reuc__retained_on_reset_soft(void)
+{
+	git_object *target;
+
+	cl_git_pass(git_revparse_single(&target, repo, "3a34580"));
+
+	cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL));
+
+	test_index_reuc__add();
+	cl_git_pass(git_reset(repo, target, GIT_RESET_SOFT, NULL));
+	cl_assert(reuc_entry_exists() == true);
+
+	git_object_free(target);
+}
+
+void test_index_reuc__cleaned_on_checkout_tree(void)
+{
+	git_oid oid;
+	git_object *obj;
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
+
+	test_index_reuc__add();
+	git_reference_name_to_id(&oid, repo, "refs/heads/master");
+	git_object_lookup(&obj, repo, &oid, GIT_OBJ_ANY);
+	git_checkout_tree(repo, obj, &opts);
+	cl_assert(reuc_entry_exists() == false);
+
+	git_object_free(obj);
+}
+
+void test_index_reuc__cleaned_on_checkout_head(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
+
+	test_index_reuc__add();
+	git_checkout_head(repo, &opts);
+	cl_assert(reuc_entry_exists() == false);
+}
+
+void test_index_reuc__retained_on_checkout_index(void)
+{
+	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
+
+	test_index_reuc__add();
+	git_checkout_index(repo, repo_index, &opts);
+	cl_assert(reuc_entry_exists() == true);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/stage.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/stage.c
new file mode 100755
index 0000000..58dc1fb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/stage.c
@@ -0,0 +1,62 @@
+#include "clar_libgit2.h"
+#include "index.h"
+#include "git2/repository.h"
+
+static git_repository *repo;
+static git_index *repo_index;
+
+#define TEST_REPO_PATH "mergedrepo"
+#define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index"
+
+// Fixture setup and teardown
+void test_index_stage__initialize(void)
+{
+	repo = cl_git_sandbox_init("mergedrepo");
+	git_repository_index(&repo_index, repo);
+}
+
+void test_index_stage__cleanup(void)
+{
+	git_index_free(repo_index);
+	repo_index = NULL;
+
+	cl_git_sandbox_cleanup();
+}
+
+
+void test_index_stage__add_always_adds_stage_0(void)
+{
+	size_t entry_idx;
+	const git_index_entry *entry;
+
+    cl_git_mkfile("./mergedrepo/new-file.txt", "new-file\n");
+
+	cl_git_pass(git_index_add_bypath(repo_index, "new-file.txt"));
+
+	cl_assert(!git_index_find(&entry_idx, repo_index, "new-file.txt"));
+	cl_assert((entry = git_index_get_byindex(repo_index, entry_idx)) != NULL);
+	cl_assert(git_index_entry_stage(entry) == 0);
+}
+
+void test_index_stage__find_gets_first_stage(void)
+{
+	size_t entry_idx;
+	const git_index_entry *entry;
+
+	cl_assert(!git_index_find(&entry_idx, repo_index, "one.txt"));
+	cl_assert((entry = git_index_get_byindex(repo_index, entry_idx)) != NULL);
+	cl_assert(git_index_entry_stage(entry) == 0);
+
+	cl_assert(!git_index_find(&entry_idx, repo_index, "two.txt"));
+	cl_assert((entry = git_index_get_byindex(repo_index, entry_idx)) != NULL);
+	cl_assert(git_index_entry_stage(entry) == 0);
+
+	cl_assert(!git_index_find(&entry_idx, repo_index, "conflicts-one.txt"));
+	cl_assert((entry = git_index_get_byindex(repo_index, entry_idx)) != NULL);
+	cl_assert(git_index_entry_stage(entry) == 1);
+
+	cl_assert(!git_index_find(&entry_idx, repo_index, "conflicts-two.txt"));
+	cl_assert((entry = git_index_get_byindex(repo_index, entry_idx)) != NULL);
+	cl_assert(git_index_entry_stage(entry) == 1);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/tests.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/tests.c
new file mode 100755
index 0000000..e1ff12a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/index/tests.c
@@ -0,0 +1,822 @@
+#include "clar_libgit2.h"
+#include "index.h"
+
+static const size_t index_entry_count = 109;
+static const size_t index_entry_count_2 = 1437;
+#define TEST_INDEX_PATH cl_fixture("testrepo.git/index")
+#define TEST_INDEX2_PATH cl_fixture("gitgit.index")
+#define TEST_INDEXBIG_PATH cl_fixture("big.index")
+#define TEST_INDEXBAD_PATH cl_fixture("bad.index")
+
+
+/* Suite data */
+struct test_entry {
+   size_t index;
+   char path[128];
+   git_off_t file_size;
+   git_time_t mtime;
+};
+
+static struct test_entry test_entries[] = {
+   {4, "Makefile", 5064, 0x4C3F7F33},
+   {62, "tests/Makefile", 2631, 0x4C3F7F33},
+   {36, "src/index.c", 10014, 0x4C43368D},
+   {6, "git.git-authors", 2709, 0x4C3F7F33},
+   {48, "src/revobject.h", 1448, 0x4C3F7FE2}
+};
+
+/* Helpers */
+static void copy_file(const char *src, const char *dst)
+{
+	git_buf source_buf = GIT_BUF_INIT;
+	git_file dst_fd;
+
+	cl_git_pass(git_futils_readbuffer(&source_buf, src));
+
+	dst_fd = git_futils_creat_withpath(dst, 0777, 0666); /* -V536 */
+	if (dst_fd < 0)
+		goto cleanup;
+
+	cl_git_pass(p_write(dst_fd, source_buf.ptr, source_buf.size));
+
+cleanup:
+	git_buf_free(&source_buf);
+	p_close(dst_fd);
+}
+
+static void files_are_equal(const char *a, const char *b)
+{
+	git_buf buf_a = GIT_BUF_INIT;
+	git_buf buf_b = GIT_BUF_INIT;
+	int pass;
+
+	if (git_futils_readbuffer(&buf_a, a) < 0)
+		cl_assert(0);
+
+	if (git_futils_readbuffer(&buf_b, b) < 0) {
+		git_buf_free(&buf_a);
+		cl_assert(0);
+	}
+
+	pass = (buf_a.size == buf_b.size && !memcmp(buf_a.ptr, buf_b.ptr, buf_a.size));
+
+	git_buf_free(&buf_a);
+	git_buf_free(&buf_b);
+
+	cl_assert(pass);
+}
+
+
+/* Fixture setup and teardown */
+void test_index_tests__initialize(void)
+{
+}
+
+void test_index_tests__empty_index(void)
+{
+   git_index *index;
+
+   cl_git_pass(git_index_open(&index, "in-memory-index"));
+   cl_assert(index->on_disk == 0);
+
+   cl_assert(git_index_entrycount(index) == 0);
+   cl_assert(git_vector_is_sorted(&index->entries));
+
+   git_index_free(index);
+}
+
+void test_index_tests__default_test_index(void)
+{
+   git_index *index;
+   unsigned int i;
+   git_index_entry **entries;
+
+   cl_git_pass(git_index_open(&index, TEST_INDEX_PATH));
+   cl_assert(index->on_disk);
+
+   cl_assert(git_index_entrycount(index) == index_entry_count);
+   cl_assert(git_vector_is_sorted(&index->entries));
+
+   entries = (git_index_entry **)index->entries.contents;
+
+   for (i = 0; i < ARRAY_SIZE(test_entries); ++i) {
+		git_index_entry *e = entries[test_entries[i].index];
+
+		cl_assert_equal_s(e->path, test_entries[i].path);
+		cl_assert_equal_i(e->mtime.seconds, test_entries[i].mtime);
+		cl_assert_equal_i(e->file_size, test_entries[i].file_size);
+   }
+
+   git_index_free(index);
+}
+
+void test_index_tests__gitgit_index(void)
+{
+   git_index *index;
+
+   cl_git_pass(git_index_open(&index, TEST_INDEX2_PATH));
+   cl_assert(index->on_disk);
+
+   cl_assert(git_index_entrycount(index) == index_entry_count_2);
+   cl_assert(git_vector_is_sorted(&index->entries));
+   cl_assert(index->tree != NULL);
+
+   git_index_free(index);
+}
+
+void test_index_tests__find_in_existing(void)
+{
+   git_index *index;
+   unsigned int i;
+
+   cl_git_pass(git_index_open(&index, TEST_INDEX_PATH));
+
+   for (i = 0; i < ARRAY_SIZE(test_entries); ++i) {
+		size_t idx;
+
+		cl_assert(!git_index_find(&idx, index, test_entries[i].path));
+		cl_assert(idx == test_entries[i].index);
+   }
+
+   git_index_free(index);
+}
+
+void test_index_tests__find_in_empty(void)
+{
+   git_index *index;
+   unsigned int i;
+
+   cl_git_pass(git_index_open(&index, "fake-index"));
+
+   for (i = 0; i < ARRAY_SIZE(test_entries); ++i) {
+		cl_assert(GIT_ENOTFOUND == git_index_find(NULL, index, test_entries[i].path));
+   }
+
+   git_index_free(index);
+}
+
+void test_index_tests__write(void)
+{
+   git_index *index;
+
+   copy_file(TEST_INDEXBIG_PATH, "index_rewrite");
+
+   cl_git_pass(git_index_open(&index, "index_rewrite"));
+   cl_assert(index->on_disk);
+
+   cl_git_pass(git_index_write(index));
+   files_are_equal(TEST_INDEXBIG_PATH, "index_rewrite");
+
+   git_index_free(index);
+
+   p_unlink("index_rewrite");
+}
+
+void test_index_tests__sort0(void)
+{
+	/* sort the entires in an index */
+
+   /*
+   * TODO: This no longer applies:
+   * index sorting in Git uses some specific changes to the way
+   * directories are sorted.
+   *
+   * We need to specificially check for this by creating a new
+   * index, adding entries in random order and then
+   * checking for consistency
+   */
+}
+
+void test_index_tests__sort1(void)
+{
+   /* sort the entires in an empty index */
+   git_index *index;
+
+   cl_git_pass(git_index_open(&index, "fake-index"));
+
+   /* FIXME: this test is slightly dumb */
+   cl_assert(git_vector_is_sorted(&index->entries));
+
+   git_index_free(index);
+}
+
+static void cleanup_myrepo(void *opaque)
+{
+	GIT_UNUSED(opaque);
+	cl_fixture_cleanup("myrepo");
+}
+
+void test_index_tests__add(void)
+{
+	git_index *index;
+	git_filebuf file = GIT_FILEBUF_INIT;
+	git_repository *repo;
+	const git_index_entry *entry;
+	git_oid id1;
+
+	cl_set_cleanup(&cleanup_myrepo, NULL);
+
+	/* Intialize a new repository */
+	cl_git_pass(git_repository_init(&repo, "./myrepo", 0));
+
+	/* Ensure we're the only guy in the room */
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_assert(git_index_entrycount(index) == 0);
+
+	/* Create a new file in the working directory */
+	cl_git_pass(git_futils_mkpath2file("myrepo/test.txt", 0777));
+	cl_git_pass(git_filebuf_open(&file, "myrepo/test.txt", 0, 0666));
+	cl_git_pass(git_filebuf_write(&file, "hey there\n", 10));
+	cl_git_pass(git_filebuf_commit(&file));
+
+	/* Store the expected hash of the file/blob
+	 * This has been generated by executing the following
+	 * $ echo "hey there" | git hash-object --stdin
+	 */
+	cl_git_pass(git_oid_fromstr(&id1, "a8233120f6ad708f843d861ce2b7228ec4e3dec6"));
+
+	/* Add the new file to the index */
+	cl_git_pass(git_index_add_bypath(index, "test.txt"));
+
+	/* Wow... it worked! */
+	cl_assert(git_index_entrycount(index) == 1);
+	entry = git_index_get_byindex(index, 0);
+
+	/* And the built-in hashing mechanism worked as expected */
+	cl_assert_equal_oid(&id1, &entry->id);
+
+	/* Test access by path instead of index */
+	cl_assert((entry = git_index_get_bypath(index, "test.txt", 0)) != NULL);
+	cl_assert_equal_oid(&id1, &entry->id);
+
+	git_index_free(index);
+	git_repository_free(repo);
+}
+
+void test_index_tests__add_frombuffer(void)
+{
+	git_index *index;
+	git_repository *repo;
+        git_index_entry entry;
+	const git_index_entry *returned_entry;
+
+	git_oid id1;
+	git_blob *blob;
+
+	const char *content = "hey there\n";
+
+	cl_set_cleanup(&cleanup_myrepo, NULL);
+
+	/* Intialize a new repository */
+	cl_git_pass(git_repository_init(&repo, "./myrepo", 0));
+
+	/* Ensure we're the only guy in the room */
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_assert(git_index_entrycount(index) == 0);
+
+	/* Store the expected hash of the file/blob
+	 * This has been generated by executing the following
+	 * $ echo "hey there" | git hash-object --stdin
+	 */
+	cl_git_pass(git_oid_fromstr(&id1, "a8233120f6ad708f843d861ce2b7228ec4e3dec6"));
+
+	/* Add the new file to the index */
+	memset(&entry, 0x0, sizeof(git_index_entry));
+	entry.mode = GIT_FILEMODE_BLOB;
+	entry.path = "test.txt";
+	cl_git_pass(git_index_add_frombuffer(index, &entry,
+		content, strlen(content)));
+
+	/* Wow... it worked! */
+	cl_assert(git_index_entrycount(index) == 1);
+	returned_entry = git_index_get_byindex(index, 0);
+
+	/* And the built-in hashing mechanism worked as expected */
+	cl_assert_equal_oid(&id1, &returned_entry->id);
+	/* And mode is the one asked */
+	cl_assert_equal_i(GIT_FILEMODE_BLOB, returned_entry->mode);
+
+	/* Test access by path instead of index */
+	cl_assert((returned_entry = git_index_get_bypath(index, "test.txt", 0)) != NULL);
+	cl_assert_equal_oid(&id1, &returned_entry->id);
+
+	/* Test the blob is in the repository */
+	cl_git_pass(git_blob_lookup(&blob, repo, &id1));
+	cl_assert_equal_s(
+		content, git_blob_rawcontent(blob));
+	git_blob_free(blob);
+
+	git_index_free(index);
+	git_repository_free(repo);
+}
+
+void test_index_tests__add_frombuffer_reset_entry(void)
+{
+	git_index *index;
+	git_repository *repo;
+        git_index_entry entry;
+	const git_index_entry *returned_entry;
+	git_filebuf file = GIT_FILEBUF_INIT;
+
+	git_oid id1;
+	git_blob *blob;
+	const char *old_content = "here\n";
+	const char *content = "hey there\n";
+
+	cl_set_cleanup(&cleanup_myrepo, NULL);
+
+	/* Intialize a new repository */
+	cl_git_pass(git_repository_init(&repo, "./myrepo", 0));
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_futils_mkpath2file("myrepo/test.txt", 0777));
+	cl_git_pass(git_filebuf_open(&file, "myrepo/test.txt", 0, 0666));
+	cl_git_pass(git_filebuf_write(&file, old_content, strlen(old_content)));
+	cl_git_pass(git_filebuf_commit(&file));
+
+	/* Store the expected hash of the file/blob
+	 * This has been generated by executing the following
+	 * $ echo "hey there" | git hash-object --stdin
+	 */
+	cl_git_pass(git_oid_fromstr(&id1, "a8233120f6ad708f843d861ce2b7228ec4e3dec6"));
+
+	cl_git_pass(git_index_add_bypath(index, "test.txt"));
+
+	/* Add the new file to the index */
+	memset(&entry, 0x0, sizeof(git_index_entry));
+	entry.mode = GIT_FILEMODE_BLOB;
+	entry.path = "test.txt";
+	cl_git_pass(git_index_add_frombuffer(index, &entry,
+		content, strlen(content)));
+
+	/* Wow... it worked! */
+	cl_assert(git_index_entrycount(index) == 1);
+	returned_entry = git_index_get_byindex(index, 0);
+
+	/* And the built-in hashing mechanism worked as expected */
+	cl_assert_equal_oid(&id1, &returned_entry->id);
+	/* And mode is the one asked */
+	cl_assert_equal_i(GIT_FILEMODE_BLOB, returned_entry->mode);
+
+	/* Test access by path instead of index */
+	cl_assert((returned_entry = git_index_get_bypath(index, "test.txt", 0)) != NULL);
+	cl_assert_equal_oid(&id1, &returned_entry->id);
+	cl_assert_equal_i(0, returned_entry->dev);
+	cl_assert_equal_i(0, returned_entry->ino);
+	cl_assert_equal_i(0, returned_entry->uid);
+	cl_assert_equal_i(0, returned_entry->uid);
+	cl_assert_equal_i(10, returned_entry->file_size);
+
+            /* Test the blob is in the repository */
+	cl_git_pass(git_blob_lookup(&blob, repo, &id1));
+	cl_assert_equal_s(content, git_blob_rawcontent(blob));
+	git_blob_free(blob);
+
+	git_index_free(index);
+	git_repository_free(repo);
+}
+
+static void cleanup_1397(void *opaque)
+{
+	GIT_UNUSED(opaque);
+	cl_git_sandbox_cleanup();
+}
+
+void test_index_tests__add_issue_1397(void)
+{
+	git_index *index;
+	git_repository *repo;
+	const git_index_entry *entry;
+	git_oid id1;
+
+	cl_set_cleanup(&cleanup_1397, NULL);
+
+	repo = cl_git_sandbox_init("issue_1397");
+
+	cl_repo_set_bool(repo, "core.autocrlf", true);
+
+	/* Ensure we're the only guy in the room */
+	cl_git_pass(git_repository_index(&index, repo));
+
+	/* Store the expected hash of the file/blob
+	 * This has been generated by executing the following
+	 * $ git hash-object crlf_file.txt
+	 */
+	cl_git_pass(git_oid_fromstr(&id1, "8312e0889a9cbab77c732b6bc39b51a683e3a318"));
+
+	/* Make sure the initial SHA-1 is correct */
+	cl_assert((entry = git_index_get_bypath(index, "crlf_file.txt", 0)) != NULL);
+	cl_assert_equal_oid(&id1, &entry->id);
+
+	/* Update the index */
+	cl_git_pass(git_index_add_bypath(index, "crlf_file.txt"));
+
+	/* Check the new SHA-1 */
+	cl_assert((entry = git_index_get_bypath(index, "crlf_file.txt", 0)) != NULL);
+	cl_assert_equal_oid(&id1, &entry->id);
+
+	git_index_free(index);
+}
+
+void test_index_tests__add_bypath_to_a_bare_repository_returns_EBAREPO(void)
+{
+	git_repository *bare_repo;
+	git_index *index;
+
+	cl_git_pass(git_repository_open(&bare_repo, cl_fixture("testrepo.git")));
+	cl_git_pass(git_repository_index(&index, bare_repo));
+
+	cl_assert_equal_i(GIT_EBAREREPO, git_index_add_bypath(index, "test.txt"));
+
+	git_index_free(index);
+	git_repository_free(bare_repo);
+}
+
+static void add_invalid_filename(git_repository *repo, const char *fn)
+{
+	git_index *index;
+	git_buf path = GIT_BUF_INIT;
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_assert(git_index_entrycount(index) == 0);
+
+	git_buf_joinpath(&path, "./invalid", fn);
+
+	cl_git_mkfile(path.ptr, NULL);
+	cl_git_fail(git_index_add_bypath(index, fn));
+	cl_must_pass(p_unlink(path.ptr));
+
+	cl_assert(git_index_entrycount(index) == 0);
+
+	git_buf_free(&path);
+	git_index_free(index);
+}
+
+/* Test that writing an invalid filename fails */
+void test_index_tests__add_invalid_filename(void)
+{
+	git_repository *repo;
+
+	p_mkdir("invalid", 0700);
+
+	cl_git_pass(git_repository_init(&repo, "./invalid", 0));
+	cl_must_pass(p_mkdir("./invalid/subdir", 0777));
+
+	/* cl_git_mkfile() needs the dir to exist */
+	if (!git_path_exists("./invalid/.GIT"))
+		cl_must_pass(p_mkdir("./invalid/.GIT", 0777));
+	if (!git_path_exists("./invalid/.GiT"))
+		cl_must_pass(p_mkdir("./invalid/.GiT", 0777));
+
+	add_invalid_filename(repo, ".git/hello");
+	add_invalid_filename(repo, ".GIT/hello");
+	add_invalid_filename(repo, ".GiT/hello");
+	add_invalid_filename(repo, "./.git/hello");
+	add_invalid_filename(repo, "./foo");
+	add_invalid_filename(repo, "./bar");
+	add_invalid_filename(repo, "subdir/../bar");
+
+	git_repository_free(repo);
+
+	cl_fixture_cleanup("invalid");
+}
+
+static void replace_char(char *str, char in, char out)
+{
+	char *c = str;
+
+	while (*c++)
+		if (*c == in)
+			*c = out;
+}
+
+static void write_invalid_filename(git_repository *repo, const char *fn_orig)
+{
+	git_index *index;
+	git_oid expected;
+	const git_index_entry *entry;
+	git_buf path = GIT_BUF_INIT;
+	char *fn;
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_assert(git_index_entrycount(index) == 0);
+
+	/*
+	 * Sneak a valid path into the index, we'll update it
+	 * to an invalid path when we try to write the index.
+	 */
+	fn = git__strdup(fn_orig);
+	replace_char(fn, '/', '_');
+
+	git_buf_joinpath(&path, "./invalid", fn);
+
+	cl_git_mkfile(path.ptr, NULL);
+
+	cl_git_pass(git_index_add_bypath(index, fn));
+
+	cl_assert(entry = git_index_get_bypath(index, fn, 0));
+
+	/* kids, don't try this at home */
+	replace_char((char *)entry->path, '_', '/');
+
+	/* write-tree */
+	cl_git_fail(git_index_write_tree(&expected, index));
+
+	p_unlink(path.ptr);
+
+	cl_git_pass(git_index_remove_all(index, NULL, NULL, NULL));
+	git_buf_free(&path);
+	git_index_free(index);
+	git__free(fn);
+}
+
+/* Test that writing an invalid filename fails */
+void test_index_tests__write_invalid_filename(void)
+{
+	git_repository *repo;
+
+	p_mkdir("invalid", 0700);
+
+	cl_git_pass(git_repository_init(&repo, "./invalid", 0));
+
+	write_invalid_filename(repo, ".git/hello");
+	write_invalid_filename(repo, ".GIT/hello");
+	write_invalid_filename(repo, ".GiT/hello");
+	write_invalid_filename(repo, "./.git/hello");
+	write_invalid_filename(repo, "./foo");
+	write_invalid_filename(repo, "./bar");
+	write_invalid_filename(repo, "foo/../bar");
+
+	git_repository_free(repo);
+
+	cl_fixture_cleanup("invalid");
+}
+
+void test_index_tests__honors_protect_filesystems(void)
+{
+	git_repository *repo;
+
+	p_mkdir("invalid", 0700);
+
+	cl_git_pass(git_repository_init(&repo, "./invalid", 0));
+
+	cl_repo_set_bool(repo, "core.protectHFS", true);
+	cl_repo_set_bool(repo, "core.protectNTFS", true);
+
+	write_invalid_filename(repo, ".git./hello");
+	write_invalid_filename(repo, ".git\xe2\x80\xad/hello");
+	write_invalid_filename(repo, "git~1/hello");
+	write_invalid_filename(repo, ".git\xe2\x81\xaf/hello");
+
+	git_repository_free(repo);
+
+	cl_fixture_cleanup("invalid");
+}
+
+void test_index_tests__remove_entry(void)
+{
+	git_repository *repo;
+	git_index *index;
+
+	p_mkdir("index_test", 0770);
+
+	cl_git_pass(git_repository_init(&repo, "index_test", 0));
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_assert(git_index_entrycount(index) == 0);
+
+	cl_git_mkfile("index_test/hello", NULL);
+	cl_git_pass(git_index_add_bypath(index, "hello"));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_index_read(index, true)); /* reload */
+	cl_assert(git_index_entrycount(index) == 1);
+	cl_assert(git_index_get_bypath(index, "hello", 0) != NULL);
+
+	cl_git_pass(git_index_remove(index, "hello", 0));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_index_read(index, true)); /* reload */
+	cl_assert(git_index_entrycount(index) == 0);
+	cl_assert(git_index_get_bypath(index, "hello", 0) == NULL);
+
+	git_index_free(index);
+	git_repository_free(repo);
+	cl_fixture_cleanup("index_test");
+}
+
+void test_index_tests__remove_directory(void)
+{
+	git_repository *repo;
+	git_index *index;
+
+	p_mkdir("index_test", 0770);
+
+	cl_git_pass(git_repository_init(&repo, "index_test", 0));
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_assert_equal_i(0, (int)git_index_entrycount(index));
+
+	p_mkdir("index_test/a", 0770);
+	cl_git_mkfile("index_test/a/1.txt", NULL);
+	cl_git_mkfile("index_test/a/2.txt", NULL);
+	cl_git_mkfile("index_test/a/3.txt", NULL);
+	cl_git_mkfile("index_test/b.txt", NULL);
+
+	cl_git_pass(git_index_add_bypath(index, "a/1.txt"));
+	cl_git_pass(git_index_add_bypath(index, "a/2.txt"));
+	cl_git_pass(git_index_add_bypath(index, "a/3.txt"));
+	cl_git_pass(git_index_add_bypath(index, "b.txt"));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_index_read(index, true)); /* reload */
+	cl_assert_equal_i(4, (int)git_index_entrycount(index));
+	cl_assert(git_index_get_bypath(index, "a/1.txt", 0) != NULL);
+	cl_assert(git_index_get_bypath(index, "a/2.txt", 0) != NULL);
+	cl_assert(git_index_get_bypath(index, "b.txt", 0) != NULL);
+
+	cl_git_pass(git_index_remove(index, "a/1.txt", 0));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_index_read(index, true)); /* reload */
+	cl_assert_equal_i(3, (int)git_index_entrycount(index));
+	cl_assert(git_index_get_bypath(index, "a/1.txt", 0) == NULL);
+	cl_assert(git_index_get_bypath(index, "a/2.txt", 0) != NULL);
+	cl_assert(git_index_get_bypath(index, "b.txt", 0) != NULL);
+
+	cl_git_pass(git_index_remove_directory(index, "a", 0));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_index_read(index, true)); /* reload */
+	cl_assert_equal_i(1, (int)git_index_entrycount(index));
+	cl_assert(git_index_get_bypath(index, "a/1.txt", 0) == NULL);
+	cl_assert(git_index_get_bypath(index, "a/2.txt", 0) == NULL);
+	cl_assert(git_index_get_bypath(index, "b.txt", 0) != NULL);
+
+	git_index_free(index);
+	git_repository_free(repo);
+	cl_fixture_cleanup("index_test");
+}
+
+void test_index_tests__preserves_case(void)
+{
+	git_repository *repo;
+	git_index *index;
+	const git_index_entry *entry;
+	int index_caps;
+
+	cl_set_cleanup(&cleanup_myrepo, NULL);
+
+	cl_git_pass(git_repository_init(&repo, "./myrepo", 0));
+	cl_git_pass(git_repository_index(&index, repo));
+
+	index_caps = git_index_caps(index);
+
+	cl_git_rewritefile("myrepo/test.txt", "hey there\n");
+	cl_git_pass(git_index_add_bypath(index, "test.txt"));
+
+	cl_git_pass(p_rename("myrepo/test.txt", "myrepo/TEST.txt"));
+	cl_git_rewritefile("myrepo/TEST.txt", "hello again\n");
+	cl_git_pass(git_index_add_bypath(index, "TEST.txt"));
+
+	if (index_caps & GIT_INDEXCAP_IGNORE_CASE)
+		cl_assert_equal_i(1, (int)git_index_entrycount(index));
+	else
+		cl_assert_equal_i(2, (int)git_index_entrycount(index));
+
+	/* Test access by path instead of index */
+	cl_assert((entry = git_index_get_bypath(index, "test.txt", 0)) != NULL);
+	/* The path should *not* have changed without an explicit remove */
+	cl_assert(git__strcmp(entry->path, "test.txt") == 0);
+
+	cl_assert((entry = git_index_get_bypath(index, "TEST.txt", 0)) != NULL);
+	if (index_caps & GIT_INDEXCAP_IGNORE_CASE)
+		/* The path should *not* have changed without an explicit remove */
+		cl_assert(git__strcmp(entry->path, "test.txt") == 0);
+	else
+		cl_assert(git__strcmp(entry->path, "TEST.txt") == 0);
+
+	git_index_free(index);
+	git_repository_free(repo);
+}
+
+void test_index_tests__elocked(void)
+{
+	git_repository *repo;
+	git_index *index;
+	git_filebuf file = GIT_FILEBUF_INIT;
+	const git_error *err;
+	int error;
+
+	cl_set_cleanup(&cleanup_myrepo, NULL);
+
+	cl_git_pass(git_repository_init(&repo, "./myrepo", 0));
+	cl_git_pass(git_repository_index(&index, repo));
+
+	/* Lock the index file so we fail to lock it */
+	cl_git_pass(git_filebuf_open(&file, index->index_file_path, 0, 0666));
+	error = git_index_write(index);
+	cl_assert_equal_i(GIT_ELOCKED, error);
+
+	err = giterr_last();
+	cl_assert_equal_i(err->klass, GITERR_INDEX);
+
+	git_filebuf_cleanup(&file);
+	git_index_free(index);
+	git_repository_free(repo);
+}
+
+void test_index_tests__reload_from_disk(void)
+{
+	git_repository *repo;
+	git_index *read_index;
+	git_index *write_index;
+
+	cl_set_cleanup(&cleanup_myrepo, NULL);
+
+	cl_git_pass(git_futils_mkdir("./myrepo", NULL, 0777, GIT_MKDIR_PATH));
+	cl_git_mkfile("./myrepo/a.txt", "a\n");
+	cl_git_mkfile("./myrepo/b.txt", "b\n");
+
+	cl_git_pass(git_repository_init(&repo, "./myrepo", 0));
+	cl_git_pass(git_repository_index(&write_index, repo));
+	cl_assert_equal_i(false, write_index->on_disk);
+
+	cl_git_pass(git_index_open(&read_index, write_index->index_file_path));
+	cl_assert_equal_i(false, read_index->on_disk);
+
+	/* Stage two new files against the write_index */
+	cl_git_pass(git_index_add_bypath(write_index, "a.txt"));
+	cl_git_pass(git_index_add_bypath(write_index, "b.txt"));
+
+	cl_assert_equal_sz(2, git_index_entrycount(write_index));
+
+	/* Persist the index changes to disk */
+	cl_git_pass(git_index_write(write_index));
+	cl_assert_equal_i(true, write_index->on_disk);
+
+	/* Sync the changes back into the read_index */
+	cl_assert_equal_sz(0, git_index_entrycount(read_index));
+
+	cl_git_pass(git_index_read(read_index, true));
+	cl_assert_equal_i(true, read_index->on_disk);
+
+	cl_assert_equal_sz(2, git_index_entrycount(read_index));
+
+	/* Remove the index file from the filesystem */
+	cl_git_pass(p_unlink(write_index->index_file_path));
+
+	/* Sync the changes back into the read_index */
+	cl_git_pass(git_index_read(read_index, true));
+	cl_assert_equal_i(false, read_index->on_disk);
+	cl_assert_equal_sz(0, git_index_entrycount(read_index));
+
+	git_index_free(read_index);
+	git_index_free(write_index);
+	git_repository_free(repo);
+}
+
+void test_index_tests__corrupted_extension(void)
+{
+	git_index *index;
+
+	cl_git_fail_with(git_index_open(&index, TEST_INDEXBAD_PATH), GIT_ERROR);
+}
+
+void test_index_tests__reload_while_ignoring_case(void)
+{
+	git_index *index;
+	unsigned int caps;
+
+	cl_git_pass(git_index_open(&index, TEST_INDEX_PATH));
+	cl_git_pass(git_vector_verify_sorted(&index->entries));
+
+	caps = git_index_caps(index);
+	cl_git_pass(git_index_set_caps(index, caps &= ~GIT_INDEXCAP_IGNORE_CASE));
+	cl_git_pass(git_index_read(index, true));
+	cl_git_pass(git_vector_verify_sorted(&index->entries));
+
+	cl_git_pass(git_index_set_caps(index, caps | GIT_INDEXCAP_IGNORE_CASE));
+	cl_git_pass(git_index_read(index, true));
+	cl_git_pass(git_vector_verify_sorted(&index->entries));
+
+	git_index_free(index);
+}
+
+void test_index_tests__can_lock_index(void)
+{
+	git_index *index;
+	git_indexwriter one = GIT_INDEXWRITER_INIT,
+		two = GIT_INDEXWRITER_INIT;
+
+	cl_git_pass(git_index_open(&index, TEST_INDEX_PATH));
+	cl_git_pass(git_indexwriter_init(&one, index));
+
+	cl_git_fail_with(GIT_ELOCKED, git_indexwriter_init(&two, index));
+	cl_git_fail_with(GIT_ELOCKED, git_index_write(index));
+
+	cl_git_pass(git_indexwriter_commit(&one));
+
+	cl_git_pass(git_index_write(index));
+
+	git_indexwriter_cleanup(&one);
+	git_indexwriter_cleanup(&two);
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/main.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/main.c
new file mode 100755
index 0000000..56326da
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/main.c
@@ -0,0 +1,46 @@
+
+#if defined(GIT_MSVC_CRTDBG)
+/* Enable MSVC CRTDBG memory leak reporting.  See src/util.h for details. */
+#include <stdlib.h>
+#include <crtdbg.h>
+#endif
+
+#include "clar_libgit2.h"
+#include "clar_libgit2_trace.h"
+
+#ifdef _WIN32
+int __cdecl main(int argc, char *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+	int res;
+
+#if defined(GIT_MSVC_CRTDBG)
+	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+
+	_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
+	_CrtSetReportMode(_CRT_ERROR,  _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
+	_CrtSetReportMode(_CRT_WARN,   _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
+
+	_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
+	_CrtSetReportFile(_CRT_ERROR,  _CRTDBG_FILE_STDERR);
+	_CrtSetReportFile(_CRT_WARN,   _CRTDBG_FILE_STDERR);
+#endif
+
+	clar_test_init(argc, argv);
+
+	git_libgit2_init();
+	cl_global_trace_register();
+	cl_sandbox_set_search_path_defaults();
+
+	/* Run the test suite */
+	res = clar_test_run();
+
+	clar_test_shutdown();
+
+	cl_global_trace_disable();
+	git_libgit2_shutdown();
+
+	return res;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/files.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/files.c
new file mode 100755
index 0000000..2d55df2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/files.c
@@ -0,0 +1,378 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/merge.h"
+#include "buffer.h"
+#include "merge.h"
+#include "merge_helpers.h"
+#include "refs.h"
+#include "fileops.h"
+#include "diff_xdiff.h"
+
+#define TEST_REPO_PATH "merge-resolve"
+#define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index"
+
+static git_repository *repo;
+static git_index *repo_index;
+
+// Fixture setup and teardown
+void test_merge_files__initialize(void)
+{
+	git_config *cfg;
+
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+	git_repository_index(&repo_index, repo);
+
+	/* Ensure that the user's merge.conflictstyle doesn't interfere */
+	cl_git_pass(git_repository_config(&cfg, repo));
+	cl_git_pass(git_config_set_string(cfg, "merge.conflictstyle", "merge"));
+	git_config_free(cfg);
+}
+
+void test_merge_files__cleanup(void)
+{
+	git_index_free(repo_index);
+	cl_git_sandbox_cleanup();
+}
+
+void test_merge_files__automerge_from_bufs(void)
+{
+	git_merge_file_input ancestor = GIT_MERGE_FILE_INPUT_INIT,
+		ours = GIT_MERGE_FILE_INPUT_INIT,
+		theirs = GIT_MERGE_FILE_INPUT_INIT;
+	git_merge_file_result result = {0};
+	const char *expected = "Zero\n1\n2\n3\n4\n5\n6\n7\n8\n9\nTen\n";
+
+	ancestor.ptr = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n";
+	ancestor.size = strlen(ancestor.ptr);
+	ancestor.path = "testfile.txt";
+	ancestor.mode = 0100755;
+
+	ours.ptr = "Zero\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n";
+	ours.size = strlen(ours.ptr);
+	ours.path = "testfile.txt";
+	ours.mode = 0100755;
+
+	theirs.ptr = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\nTen\n";
+	theirs.size = strlen(theirs.ptr);
+	theirs.path = "testfile.txt";
+	theirs.mode = 0100755;
+
+	cl_git_pass(git_merge_file(&result, &ancestor, &ours, &theirs, 0));
+
+	cl_assert_equal_i(1, result.automergeable);
+
+	cl_assert_equal_s("testfile.txt", result.path);
+	cl_assert_equal_i(0100755, result.mode);
+
+	cl_assert_equal_i(strlen(expected), result.len);
+	cl_assert_equal_strn(expected, result.ptr, result.len);
+
+	git_merge_file_result_free(&result);
+}
+
+void test_merge_files__automerge_use_best_path_and_mode(void)
+{
+	git_merge_file_input ancestor = GIT_MERGE_FILE_INPUT_INIT,
+		ours = GIT_MERGE_FILE_INPUT_INIT,
+		theirs = GIT_MERGE_FILE_INPUT_INIT;
+	git_merge_file_result result = {0};
+	const char *expected = "Zero\n1\n2\n3\n4\n5\n6\n7\n8\n9\nTen\n";
+
+	ancestor.ptr = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n";
+	ancestor.size = strlen(ancestor.ptr);
+	ancestor.path = "testfile.txt";
+	ancestor.mode = 0100755;
+
+	ours.ptr = "Zero\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n";
+	ours.size = strlen(ours.ptr);
+	ours.path = "testfile.txt";
+	ours.mode = 0100644;
+
+	theirs.ptr = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\nTen\n";
+	theirs.size = strlen(theirs.ptr);
+	theirs.path = "theirs.txt";
+	theirs.mode = 0100755;
+
+	cl_git_pass(git_merge_file(&result, &ancestor, &ours, &theirs, 0));
+
+	cl_assert_equal_i(1, result.automergeable);
+
+	cl_assert_equal_s("theirs.txt", result.path);
+	cl_assert_equal_i(0100644, result.mode);
+
+	cl_assert_equal_i(strlen(expected), result.len);
+	cl_assert_equal_strn(expected, result.ptr, result.len);
+
+	git_merge_file_result_free(&result);
+}
+
+void test_merge_files__conflict_from_bufs(void)
+{
+	git_merge_file_input ancestor = GIT_MERGE_FILE_INPUT_INIT,
+		ours = GIT_MERGE_FILE_INPUT_INIT,
+		theirs = GIT_MERGE_FILE_INPUT_INIT;
+	git_merge_file_result result = {0};
+
+	const char *expected = "<<<<<<< testfile.txt\nAloha!\nOurs.\n=======\nHi!\nTheirs.\n>>>>>>> theirs.txt\n";
+	size_t expected_len = strlen(expected);
+
+	ancestor.ptr = "Hello!\nAncestor!\n";
+	ancestor.size = strlen(ancestor.ptr);
+	ancestor.path = "testfile.txt";
+	ancestor.mode = 0100755;
+
+	ours.ptr =  "Aloha!\nOurs.\n";
+	ours.size = strlen(ours.ptr);
+	ours.path = "testfile.txt";
+	ours.mode = 0100644;
+
+	theirs.ptr = "Hi!\nTheirs.\n";
+	theirs.size = strlen(theirs.ptr);
+	theirs.path = "theirs.txt";
+	theirs.mode = 0100755;
+
+	cl_git_pass(git_merge_file(&result, &ancestor, &ours, &theirs, NULL));
+
+	cl_assert_equal_i(0, result.automergeable);
+
+	cl_assert_equal_s("theirs.txt", result.path);
+	cl_assert_equal_i(0100644, result.mode);
+
+	cl_assert_equal_i(expected_len, result.len);
+	cl_assert_equal_strn(expected, result.ptr, expected_len);
+
+	git_merge_file_result_free(&result);
+}
+
+void test_merge_files__automerge_from_index(void)
+{
+	git_merge_file_result result = {0};
+	git_index_entry ancestor, ours, theirs;
+
+	git_oid_fromstr(&ancestor.id, "6212c31dab5e482247d7977e4f0dd3601decf13b");
+	ancestor.path = "automergeable.txt";
+	ancestor.mode = 0100644;
+
+	git_oid_fromstr(&ours.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf");
+	ours.path = "automergeable.txt";
+	ours.mode = 0100755;
+
+	git_oid_fromstr(&theirs.id, "058541fc37114bfc1dddf6bd6bffc7fae5c2e6fe");
+	theirs.path = "newname.txt";
+	theirs.mode = 0100644;
+
+	cl_git_pass(git_merge_file_from_index(&result, repo,
+		&ancestor, &ours, &theirs, 0));
+
+	cl_assert_equal_i(1, result.automergeable);
+
+	cl_assert_equal_s("newname.txt", result.path);
+	cl_assert_equal_i(0100755, result.mode);
+
+	cl_assert_equal_i(strlen(AUTOMERGEABLE_MERGED_FILE), result.len);
+	cl_assert_equal_strn(AUTOMERGEABLE_MERGED_FILE, result.ptr, result.len);
+
+	git_merge_file_result_free(&result);
+}
+
+void test_merge_files__automerge_whitespace_eol(void)
+{
+	git_merge_file_input ancestor = GIT_MERGE_FILE_INPUT_INIT,
+		ours = GIT_MERGE_FILE_INPUT_INIT,
+		theirs = GIT_MERGE_FILE_INPUT_INIT;
+	git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
+	git_merge_file_result result = {0};
+	const char *expected = "Zero\n1\n2\n3\n4\n5\n6\n7\n8\n9\nTen\n";
+
+	ancestor.ptr = "0 \n1\n2\n3\n4\n5\n6\n7\n8\n9\n10 \n";
+	ancestor.size = strlen(ancestor.ptr);
+	ancestor.path = "testfile.txt";
+	ancestor.mode = 0100755;
+
+	ours.ptr = "Zero\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n";
+	ours.size = strlen(ours.ptr);
+	ours.path = "testfile.txt";
+	ours.mode = 0100755;
+
+	theirs.ptr = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\nTen\n";
+	theirs.size = strlen(theirs.ptr);
+	theirs.path = "testfile.txt";
+	theirs.mode = 0100755;
+
+	opts.flags |= GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL;
+	cl_git_pass(git_merge_file(&result, &ancestor, &ours, &theirs, &opts));
+
+	cl_assert_equal_i(1, result.automergeable);
+
+	cl_assert_equal_s("testfile.txt", result.path);
+	cl_assert_equal_i(0100755, result.mode);
+
+	cl_assert_equal_i(strlen(expected), result.len);
+	cl_assert_equal_strn(expected, result.ptr, result.len);
+
+	git_merge_file_result_free(&result);
+}
+
+void test_merge_files__automerge_whitespace_change(void)
+{
+	git_merge_file_input ancestor = GIT_MERGE_FILE_INPUT_INIT,
+		ours = GIT_MERGE_FILE_INPUT_INIT,
+		theirs = GIT_MERGE_FILE_INPUT_INIT;
+	git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
+	git_merge_file_result result = {0};
+	const char *expected = "Zero\n1\n2\n3\n4\n5 XXX\n6 YYY\n7\n8\n9\nTen\n";
+
+	ancestor.ptr = "0\n1\n2\n3\n4\n5 XXX\n6YYY\n7\n8\n9\n10\n";
+	ancestor.size = strlen(ancestor.ptr);
+	ancestor.path = "testfile.txt";
+	ancestor.mode = 0100755;
+
+	ours.ptr = "Zero\n1\n2\n3\n4\n5 XXX\n6 YYY\n7\n8\n9\n10\n";
+	ours.size = strlen(ours.ptr);
+	ours.path = "testfile.txt";
+	ours.mode = 0100755;
+
+	theirs.ptr = "0\n1\n2\n3\n4\n5 XXX\n6  YYY\n7\n8\n9\nTen\n";
+	theirs.size = strlen(theirs.ptr);
+	theirs.path = "testfile.txt";
+	theirs.mode = 0100755;
+
+	opts.flags |= GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE;
+	cl_git_pass(git_merge_file(&result, &ancestor, &ours, &theirs, &opts));
+
+	cl_assert_equal_i(1, result.automergeable);
+
+	cl_assert_equal_s("testfile.txt", result.path);
+	cl_assert_equal_i(0100755, result.mode);
+
+	cl_assert_equal_i(strlen(expected), result.len);
+	cl_assert_equal_strn(expected, result.ptr, result.len);
+
+	git_merge_file_result_free(&result);
+}
+
+void test_merge_files__doesnt_add_newline(void)
+{
+	git_merge_file_input ancestor = GIT_MERGE_FILE_INPUT_INIT,
+		ours = GIT_MERGE_FILE_INPUT_INIT,
+		theirs = GIT_MERGE_FILE_INPUT_INIT;
+	git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
+	git_merge_file_result result = {0};
+	const char *expected = "Zero\n1\n2\n3\n4\n5 XXX\n6 YYY\n7\n8\n9\nTen";
+
+	ancestor.ptr = "0\n1\n2\n3\n4\n5 XXX\n6YYY\n7\n8\n9\n10";
+	ancestor.size = strlen(ancestor.ptr);
+	ancestor.path = "testfile.txt";
+	ancestor.mode = 0100755;
+
+	ours.ptr = "Zero\n1\n2\n3\n4\n5 XXX\n6 YYY\n7\n8\n9\n10";
+	ours.size = strlen(ours.ptr);
+	ours.path = "testfile.txt";
+	ours.mode = 0100755;
+
+	theirs.ptr = "0\n1\n2\n3\n4\n5 XXX\n6  YYY\n7\n8\n9\nTen";
+	theirs.size = strlen(theirs.ptr);
+	theirs.path = "testfile.txt";
+	theirs.mode = 0100755;
+
+	opts.flags |= GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE;
+	cl_git_pass(git_merge_file(&result, &ancestor, &ours, &theirs, &opts));
+
+	cl_assert_equal_i(1, result.automergeable);
+
+	cl_assert_equal_s("testfile.txt", result.path);
+	cl_assert_equal_i(0100755, result.mode);
+
+	cl_assert_equal_i(strlen(expected), result.len);
+	cl_assert_equal_strn(expected, result.ptr, result.len);
+
+	git_merge_file_result_free(&result);
+}
+
+void test_merge_files__skips_large_files(void)
+{
+	git_merge_file_input ours = GIT_MERGE_FILE_INPUT_INIT,
+		theirs = GIT_MERGE_FILE_INPUT_INIT;
+	git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
+	git_merge_file_result result = {0};
+
+	ours.size = GIT_XDIFF_MAX_SIZE + 1;
+	ours.path = "testfile.txt";
+	ours.mode = 0100755;
+
+	theirs.size = GIT_XDIFF_MAX_SIZE + 1;
+	theirs.path = "testfile.txt";
+	theirs.mode = 0100755;
+
+	cl_git_pass(git_merge_file(&result, NULL, &ours, &theirs, &opts));
+
+	cl_assert_equal_i(0, result.automergeable);
+
+	git_merge_file_result_free(&result);
+}
+
+void test_merge_files__skips_binaries(void)
+{
+	git_merge_file_input ancestor = GIT_MERGE_FILE_INPUT_INIT,
+		ours = GIT_MERGE_FILE_INPUT_INIT,
+		theirs = GIT_MERGE_FILE_INPUT_INIT;
+	git_merge_file_result result = {0};
+
+	ancestor.ptr = "ance\0stor\0";
+	ancestor.size = 10;
+	ancestor.path = "ancestor.txt";
+	ancestor.mode = 0100755;
+
+	ours.ptr = "foo\0bar\0";
+	ours.size = 8;
+	ours.path = "ours.txt";
+	ours.mode = 0100755;
+
+	theirs.ptr = "bar\0foo\0";
+	theirs.size = 8;
+	theirs.path = "theirs.txt";
+	theirs.mode = 0100644;
+
+	cl_git_pass(git_merge_file(&result, &ancestor, &ours, &theirs, NULL));
+
+	cl_assert_equal_i(0, result.automergeable);
+
+	git_merge_file_result_free(&result);
+}
+
+void test_merge_files__handles_binaries_when_favored(void)
+{
+	git_merge_file_input ancestor = GIT_MERGE_FILE_INPUT_INIT,
+		ours = GIT_MERGE_FILE_INPUT_INIT,
+		theirs = GIT_MERGE_FILE_INPUT_INIT;
+	git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
+	git_merge_file_result result = {0};
+
+	ancestor.ptr = "ance\0stor\0";
+	ancestor.size = 10;
+	ancestor.path = "ancestor.txt";
+	ancestor.mode = 0100755;
+
+	ours.ptr = "foo\0bar\0";
+	ours.size = 8;
+	ours.path = "ours.txt";
+	ours.mode = 0100755;
+
+	theirs.ptr = "bar\0foo\0";
+	theirs.size = 8;
+	theirs.path = "theirs.txt";
+	theirs.mode = 0100644;
+
+	opts.favor = GIT_MERGE_FILE_FAVOR_OURS;
+	cl_git_pass(git_merge_file(&result, &ancestor, &ours, &theirs, &opts));
+
+	cl_assert_equal_i(1, result.automergeable);
+
+	cl_assert_equal_s("ours.txt", result.path);
+	cl_assert_equal_i(0100755, result.mode);
+
+	cl_assert_equal_i(ours.size, result.len);
+	cl_assert(memcmp(result.ptr, ours.ptr, ours.size) == 0);
+
+	git_merge_file_result_free(&result);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/merge_helpers.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/merge_helpers.c
new file mode 100755
index 0000000..f814714
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/merge_helpers.c
@@ -0,0 +1,363 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "refs.h"
+#include "tree.h"
+#include "merge_helpers.h"
+#include "merge.h"
+#include "git2/merge.h"
+#include "git2/sys/index.h"
+#include "git2/annotated_commit.h"
+
+int merge_trees_from_branches(
+	git_index **index, git_repository *repo,
+	const char *ours_name, const char *theirs_name,
+	git_merge_options *opts)
+{
+	git_commit *our_commit, *their_commit, *ancestor_commit = NULL;
+	git_tree *our_tree, *their_tree, *ancestor_tree = NULL;
+	git_oid our_oid, their_oid, ancestor_oid;
+	git_buf branch_buf = GIT_BUF_INIT;
+	int error;
+
+	git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours_name);
+	cl_git_pass(git_reference_name_to_id(&our_oid, repo, branch_buf.ptr));
+	cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid));
+
+	git_buf_clear(&branch_buf);
+	git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs_name);
+	cl_git_pass(git_reference_name_to_id(&their_oid, repo, branch_buf.ptr));
+	cl_git_pass(git_commit_lookup(&their_commit, repo, &their_oid));
+
+	error = git_merge_base(&ancestor_oid, repo, git_commit_id(our_commit), git_commit_id(their_commit));
+
+	if (error != GIT_ENOTFOUND) {
+		cl_git_pass(error);
+
+		cl_git_pass(git_commit_lookup(&ancestor_commit, repo, &ancestor_oid));
+		cl_git_pass(git_commit_tree(&ancestor_tree, ancestor_commit));
+	}
+
+	cl_git_pass(git_commit_tree(&our_tree, our_commit));
+	cl_git_pass(git_commit_tree(&their_tree, their_commit));
+
+	cl_git_pass(git_merge_trees(index, repo, ancestor_tree, our_tree, their_tree, opts));
+
+	git_buf_free(&branch_buf);
+	git_tree_free(our_tree);
+	git_tree_free(their_tree);
+	git_tree_free(ancestor_tree);
+	git_commit_free(our_commit);
+	git_commit_free(their_commit);
+	git_commit_free(ancestor_commit);
+
+	return 0;
+}
+
+int merge_commits_from_branches(
+	git_index **index, git_repository *repo,
+	const char *ours_name, const char *theirs_name,
+	git_merge_options *opts)
+{
+	git_commit *our_commit, *their_commit;
+	git_oid our_oid, their_oid;
+	git_buf branch_buf = GIT_BUF_INIT;
+
+	git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours_name);
+	cl_git_pass(git_reference_name_to_id(&our_oid, repo, branch_buf.ptr));
+	cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid));
+
+	git_buf_clear(&branch_buf);
+	git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs_name);
+	cl_git_pass(git_reference_name_to_id(&their_oid, repo, branch_buf.ptr));
+	cl_git_pass(git_commit_lookup(&their_commit, repo, &their_oid));
+
+	cl_git_pass(git_merge_commits(index, repo, our_commit, their_commit, opts));
+
+	git_buf_free(&branch_buf);
+	git_commit_free(our_commit);
+	git_commit_free(their_commit);
+
+	return 0;
+}
+
+int merge_branches(git_repository *repo,
+	const char *ours_branch, const char *theirs_branch,
+	git_merge_options *merge_opts, git_checkout_options *checkout_opts)
+{
+	git_reference *head_ref, *theirs_ref;
+	git_annotated_commit *theirs_head;
+	git_checkout_options head_checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	head_checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_git_pass(git_reference_symbolic_create(&head_ref, repo, "HEAD", ours_branch, 1, NULL));
+	cl_git_pass(git_checkout_head(repo, &head_checkout_opts));
+
+	cl_git_pass(git_reference_lookup(&theirs_ref, repo, theirs_branch));
+	cl_git_pass(git_annotated_commit_from_ref(&theirs_head, repo, theirs_ref));
+
+	cl_git_pass(git_merge(repo, (const git_annotated_commit **)&theirs_head, 1, merge_opts, checkout_opts));
+
+	git_reference_free(head_ref);
+	git_reference_free(theirs_ref);
+	git_annotated_commit_free(theirs_head);
+
+	return 0;
+}
+
+void merge__dump_index_entries(git_vector *index_entries)
+{
+	size_t i;
+	const git_index_entry *index_entry;
+
+	printf ("\nINDEX [%"PRIuZ"]:\n", index_entries->length);
+	for (i = 0; i < index_entries->length; i++) {
+		index_entry = index_entries->contents[i];
+
+		printf("%o ", index_entry->mode);
+		printf("%s ", git_oid_allocfmt(&index_entry->id));
+		printf("%d ", git_index_entry_stage(index_entry));
+		printf("%s ", index_entry->path);
+		printf("\n");
+	}
+	printf("\n");
+}
+
+void merge__dump_names(git_index *index)
+{
+	size_t i;
+	const git_index_name_entry *conflict_name;
+
+	for (i = 0; i < git_index_name_entrycount(index); i++) {
+		conflict_name = git_index_name_get_byindex(index, i);
+
+		printf("%s %s %s\n", conflict_name->ancestor, conflict_name->ours, conflict_name->theirs);
+	}
+	printf("\n");
+}
+
+void merge__dump_reuc(git_index *index)
+{
+	size_t i;
+	const git_index_reuc_entry *reuc;
+
+	printf ("\nREUC:\n");
+	for (i = 0; i < git_index_reuc_entrycount(index); i++) {
+		reuc = git_index_reuc_get_byindex(index, i);
+
+		printf("%s ", reuc->path);
+		printf("%o ", reuc->mode[0]);
+		printf("%s\n", git_oid_allocfmt(&reuc->oid[0]));
+		printf("          %o ", reuc->mode[1]);
+		printf("          %s\n", git_oid_allocfmt(&reuc->oid[1]));
+		printf("          %o ", reuc->mode[2]);
+		printf("          %s ", git_oid_allocfmt(&reuc->oid[2]));
+		printf("\n");
+	}
+	printf("\n");
+}
+
+static int index_entry_eq_merge_index_entry(const struct merge_index_entry *expected, const git_index_entry *actual)
+{
+	git_oid expected_oid;
+	bool test_oid;
+
+	if (strlen(expected->oid_str) != 0) {
+		cl_git_pass(git_oid_fromstr(&expected_oid, expected->oid_str));
+		test_oid = 1;
+	} else
+		test_oid = 0;
+
+	if (actual->mode != expected->mode ||
+		(test_oid && git_oid_cmp(&actual->id, &expected_oid) != 0) ||
+		git_index_entry_stage(actual) != expected->stage)
+		return 0;
+
+	if (actual->mode == 0 && (actual->path != NULL || strlen(expected->path) > 0))
+		return 0;
+
+	if (actual->mode != 0 && (strcmp(actual->path, expected->path) != 0))
+		return 0;
+
+	return 1;
+}
+
+static int name_entry_eq(const char *expected, const char *actual)
+{
+	if (strlen(expected) == 0)
+		return (actual == NULL) ? 1 : 0;
+
+	return (strcmp(expected, actual) == 0) ? 1 : 0;
+}
+
+static int name_entry_eq_merge_name_entry(const struct merge_name_entry *expected, const git_index_name_entry *actual)
+{
+	if (name_entry_eq(expected->ancestor_path, actual->ancestor) == 0 ||
+		name_entry_eq(expected->our_path, actual->ours) == 0 ||
+		name_entry_eq(expected->their_path, actual->theirs) == 0)
+		return 0;
+
+	return 1;
+}
+
+static int index_conflict_data_eq_merge_diff(const struct merge_index_conflict_data *expected, git_merge_diff *actual)
+{
+	if (!index_entry_eq_merge_index_entry(&expected->ancestor.entry, &actual->ancestor_entry) ||
+		!index_entry_eq_merge_index_entry(&expected->ours.entry, &actual->our_entry) ||
+		!index_entry_eq_merge_index_entry(&expected->theirs.entry, &actual->their_entry))
+		return 0;
+
+	if (expected->ours.status != actual->our_status ||
+		expected->theirs.status != actual->their_status)
+		return 0;
+
+	return 1;
+}
+
+int merge_test_merge_conflicts(git_vector *conflicts, const struct merge_index_conflict_data expected[], size_t expected_len)
+{
+	git_merge_diff *actual;
+	size_t i;
+
+	if (conflicts->length != expected_len)
+		return 0;
+
+	for (i = 0; i < expected_len; i++) {
+		actual = conflicts->contents[i];
+
+		if (!index_conflict_data_eq_merge_diff(&expected[i], actual))
+			return 0;
+	}
+
+	return 1;
+}
+
+int merge_test_index(git_index *index, const struct merge_index_entry expected[], size_t expected_len)
+{
+	size_t i;
+	const git_index_entry *index_entry;
+
+	/*
+	dump_index_entries(&index->entries);
+	*/
+
+	if (git_index_entrycount(index) != expected_len)
+		return 0;
+
+	for (i = 0; i < expected_len; i++) {
+		if ((index_entry = git_index_get_byindex(index, i)) == NULL)
+			return 0;
+
+		if (!index_entry_eq_merge_index_entry(&expected[i], index_entry))
+			return 0;
+	}
+
+	return 1;
+}
+
+int merge_test_names(git_index *index, const struct merge_name_entry expected[], size_t expected_len)
+{
+	size_t i;
+	const git_index_name_entry *name_entry;
+
+	/*
+	dump_names(index);
+	*/
+
+	if (git_index_name_entrycount(index) != expected_len)
+		return 0;
+
+	for (i = 0; i < expected_len; i++) {
+		if ((name_entry = git_index_name_get_byindex(index, i)) == NULL)
+			return 0;
+
+		if (! name_entry_eq_merge_name_entry(&expected[i], name_entry))
+			return 0;
+	}
+
+	return 1;
+}
+
+int merge_test_reuc(git_index *index, const struct merge_reuc_entry expected[], size_t expected_len)
+{
+	size_t i;
+	const git_index_reuc_entry *reuc_entry;
+	git_oid expected_oid;
+
+	/*
+	dump_reuc(index);
+	*/
+
+	if (git_index_reuc_entrycount(index) != expected_len)
+		return 0;
+
+	for (i = 0; i < expected_len; i++) {
+		if ((reuc_entry = git_index_reuc_get_byindex(index, i)) == NULL)
+			return 0;
+
+		if (strcmp(reuc_entry->path, expected[i].path) != 0 ||
+			reuc_entry->mode[0] != expected[i].ancestor_mode ||
+			reuc_entry->mode[1] != expected[i].our_mode ||
+			reuc_entry->mode[2] != expected[i].their_mode)
+			return 0;
+
+		if (expected[i].ancestor_mode > 0) {
+			cl_git_pass(git_oid_fromstr(&expected_oid, expected[i].ancestor_oid_str));
+
+			if (git_oid_cmp(&reuc_entry->oid[0], &expected_oid) != 0)
+				return 0;
+		}
+
+		if (expected[i].our_mode > 0) {
+			cl_git_pass(git_oid_fromstr(&expected_oid, expected[i].our_oid_str));
+
+			if (git_oid_cmp(&reuc_entry->oid[1], &expected_oid) != 0)
+				return 0;
+		}
+
+		if (expected[i].their_mode > 0) {
+			cl_git_pass(git_oid_fromstr(&expected_oid, expected[i].their_oid_str));
+
+			if (git_oid_cmp(&reuc_entry->oid[2], &expected_oid) != 0)
+				return 0;
+		}
+	}
+
+	return 1;
+}
+
+int dircount(void *payload, git_buf *pathbuf)
+{
+	size_t *entries = payload;
+	size_t len = git_buf_len(pathbuf);
+
+	if (len < 5 || strcmp(pathbuf->ptr + (git_buf_len(pathbuf) - 5), "/.git") != 0)
+		(*entries)++;
+
+	return 0;
+}
+
+int merge_test_workdir(git_repository *repo, const struct merge_index_entry expected[], size_t expected_len)
+{
+	size_t actual_len = 0, i;
+	git_oid actual_oid, expected_oid;
+	git_buf wd = GIT_BUF_INIT;
+
+	git_buf_puts(&wd, repo->workdir);
+	git_path_direach(&wd, 0, dircount, &actual_len);
+
+	if (actual_len != expected_len)
+		return 0;
+
+	for (i = 0; i < expected_len; i++) {
+		git_blob_create_fromworkdir(&actual_oid, repo, expected[i].path);
+		git_oid_fromstr(&expected_oid, expected[i].oid_str);
+
+		if (git_oid_cmp(&actual_oid, &expected_oid) != 0)
+			return 0;
+	}
+
+	git_buf_free(&wd);
+
+	return 1;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/merge_helpers.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/merge_helpers.h
new file mode 100755
index 0000000..554c24b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/merge_helpers.h
@@ -0,0 +1,111 @@
+#ifndef INCLUDE_cl_merge_helpers_h__
+#define INCLUDE_cl_merge_helpers_h__
+
+#include "merge.h"
+#include "git2/merge.h"
+
+#define AUTOMERGEABLE_MERGED_FILE \
+	"this file is changed in master\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is changed in branch\n"
+
+#define AUTOMERGEABLE_MERGED_FILE_CRLF \
+	"this file is changed in master\r\n" \
+	"this file is automergeable\r\n" \
+	"this file is automergeable\r\n" \
+	"this file is automergeable\r\n" \
+	"this file is automergeable\r\n" \
+	"this file is automergeable\r\n" \
+	"this file is automergeable\r\n" \
+	"this file is automergeable\r\n" \
+	"this file is changed in branch\r\n"
+
+#define CONFLICTING_MERGE_FILE \
+	"<<<<<<< HEAD\n" \
+	"this file is changed in master and branch\n" \
+	"=======\n" \
+	"this file is changed in branch and master\n" \
+	">>>>>>> 7cb63eed597130ba4abb87b3e544b85021905520\n"
+
+#define CONFLICTING_DIFF3_FILE \
+	"<<<<<<< HEAD\n" \
+	"this file is changed in master and branch\n" \
+	"||||||| initial\n" \
+	"this file is a conflict\n" \
+	"=======\n" \
+	"this file is changed in branch and master\n" \
+	">>>>>>> 7cb63eed597130ba4abb87b3e544b85021905520\n"
+
+#define CONFLICTING_UNION_FILE \
+	"this file is changed in master and branch\n" \
+	"this file is changed in branch and master\n"
+
+
+struct merge_index_entry {
+	uint16_t mode;
+	char oid_str[GIT_OID_HEXSZ+1];
+	int stage;
+	char path[128];
+};
+
+struct merge_name_entry {
+	char ancestor_path[128];
+	char our_path[128];
+	char their_path[128];
+};
+
+struct merge_index_with_status {
+	struct merge_index_entry entry;
+	unsigned int status;
+};
+
+struct merge_reuc_entry {
+	char path[128];
+	unsigned int ancestor_mode;
+	unsigned int our_mode;
+	unsigned int their_mode;
+	char ancestor_oid_str[GIT_OID_HEXSZ+1];
+	char our_oid_str[GIT_OID_HEXSZ+1];
+	char their_oid_str[GIT_OID_HEXSZ+1];
+};
+
+struct merge_index_conflict_data {
+	struct merge_index_with_status ancestor;
+	struct merge_index_with_status ours;
+	struct merge_index_with_status theirs;
+	git_merge_diff_type_t change_type;
+};
+
+int merge_trees_from_branches(
+	git_index **index, git_repository *repo,
+	const char *ours_name, const char *theirs_name,
+	git_merge_options *opts);
+
+int merge_commits_from_branches(
+	git_index **index, git_repository *repo,
+	const char *ours_name, const char *theirs_name,
+	git_merge_options *opts);
+
+int merge_branches(git_repository *repo,
+	const char *ours_branch, const char *theirs_branch,
+	git_merge_options *merge_opts, git_checkout_options *checkout_opts);
+
+int merge_test_diff_list(git_merge_diff_list *diff_list, const struct merge_index_entry expected[], size_t expected_len);
+
+int merge_test_merge_conflicts(git_vector *conflicts, const struct merge_index_conflict_data expected[], size_t expected_len);
+
+int merge_test_index(git_index *index, const struct merge_index_entry expected[], size_t expected_len);
+
+int merge_test_names(git_index *index, const struct merge_name_entry expected[], size_t expected_len);
+
+int merge_test_reuc(git_index *index, const struct merge_reuc_entry expected[], size_t expected_len);
+
+int merge_test_workdir(git_repository *repo, const struct merge_index_entry expected[], size_t expected_len);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/automerge.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/automerge.c
new file mode 100755
index 0000000..c18881d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/automerge.c
@@ -0,0 +1,195 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/merge.h"
+#include "buffer.h"
+#include "merge.h"
+#include "../merge_helpers.h"
+#include "fileops.h"
+
+static git_repository *repo;
+
+#define TEST_REPO_PATH "merge-resolve"
+#define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index"
+
+#define THEIRS_AUTOMERGE_BRANCH        "branch"
+
+#define THEIRS_UNRELATED_BRANCH		"unrelated"
+#define THEIRS_UNRELATED_OID		"55b4e4687e7a0d9ca367016ed930f385d4022e6f"
+#define THEIRS_UNRELATED_PARENT		"d6cf6c7741b3316826af1314042550c97ded1d50"
+
+#define OURS_DIRECTORY_FILE			"df_side1"
+#define THEIRS_DIRECTORY_FILE		"df_side2"
+
+/* Non-conflicting files, index entries are common to every merge operation */
+#define ADDED_IN_MASTER_INDEX_ENTRY	\
+	{ 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0,  "added-in-master.txt" }
+#define AUTOMERGEABLE_INDEX_ENTRY \
+	{ 0100644, "f2e1550a0c9e53d5811175864a29536642ae3821", 0,  "automergeable.txt" }
+#define CHANGED_IN_BRANCH_INDEX_ENTRY \
+	{ 0100644, "4eb04c9e79e88f6640d01ff5b25ca2a60764f216", 0,  "changed-in-branch.txt" }
+#define CHANGED_IN_MASTER_INDEX_ENTRY \
+	{ 0100644, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", 0,  "changed-in-master.txt" }
+#define UNCHANGED_INDEX_ENTRY \
+	{ 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0,  "unchanged.txt" }
+
+/* Expected REUC entries */
+#define AUTOMERGEABLE_REUC_ENTRY \
+	{ "automergeable.txt", 0100644, 0100644, 0100644, \
+	  "6212c31dab5e482247d7977e4f0dd3601decf13b", \
+	  "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", \
+	  "058541fc37114bfc1dddf6bd6bffc7fae5c2e6fe" }
+#define CONFLICTING_REUC_ENTRY \
+	{ "conflicting.txt", 0100644, 0100644, 0100644, \
+	  "d427e0b2e138501a3d15cc376077a3631e15bd46", \
+	  "4e886e602529caa9ab11d71f86634bd1b6e0de10", \
+	  "2bd0a343aeef7a2cf0d158478966a6e587ff3863" }
+#define REMOVED_IN_BRANCH_REUC_ENTRY \
+	{ "removed-in-branch.txt", 0100644, 0100644, 0, \
+	  "dfe3f22baa1f6fce5447901c3086bae368de6bdd", \
+	  "dfe3f22baa1f6fce5447901c3086bae368de6bdd", \
+	  "" }
+#define REMOVED_IN_MASTER_REUC_ENTRY \
+	{ "removed-in-master.txt", 0100644, 0, 0100644, \
+	  "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5", \
+	  "", \
+	  "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5" }
+
+// Fixture setup and teardown
+void test_merge_trees_automerge__initialize(void)
+{
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+}
+
+void test_merge_trees_automerge__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_merge_trees_automerge__automerge(void)
+{
+	git_index *index;
+	const git_index_entry *entry;
+	git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+	git_blob *blob;
+
+	struct merge_index_entry merge_index_entries[] = {
+		ADDED_IN_MASTER_INDEX_ENTRY,
+		AUTOMERGEABLE_INDEX_ENTRY,
+		CHANGED_IN_BRANCH_INDEX_ENTRY,
+		CHANGED_IN_MASTER_INDEX_ENTRY,
+
+		{ 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 1, "conflicting.txt" },
+		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
+		{ 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" },
+
+		UNCHANGED_INDEX_ENTRY,
+	};
+
+	struct merge_reuc_entry merge_reuc_entries[] = {
+		AUTOMERGEABLE_REUC_ENTRY,
+		REMOVED_IN_BRANCH_REUC_ENTRY,
+		REMOVED_IN_MASTER_REUC_ENTRY
+	};
+
+	cl_git_pass(merge_trees_from_branches(&index, repo, "master", THEIRS_AUTOMERGE_BRANCH, &opts));
+
+	cl_assert(merge_test_index(index, merge_index_entries, 8));
+	cl_assert(merge_test_reuc(index, merge_reuc_entries, 3));
+
+	cl_assert((entry = git_index_get_bypath(index, "automergeable.txt", 0)) != NULL);
+	cl_assert(entry->file_size == strlen(AUTOMERGEABLE_MERGED_FILE));
+
+	cl_git_pass(git_object_lookup((git_object **)&blob, repo, &entry->id, GIT_OBJ_BLOB));
+	cl_assert(memcmp(git_blob_rawcontent(blob), AUTOMERGEABLE_MERGED_FILE, (size_t)entry->file_size) == 0);
+
+	git_index_free(index);
+	git_blob_free(blob);
+}
+
+void test_merge_trees_automerge__favor_ours(void)
+{
+	git_index *index;
+	git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		ADDED_IN_MASTER_INDEX_ENTRY,
+		AUTOMERGEABLE_INDEX_ENTRY,
+		CHANGED_IN_BRANCH_INDEX_ENTRY,
+		CHANGED_IN_MASTER_INDEX_ENTRY,
+		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 0, "conflicting.txt" },
+		UNCHANGED_INDEX_ENTRY,
+	};
+
+	struct merge_reuc_entry merge_reuc_entries[] = {
+		AUTOMERGEABLE_REUC_ENTRY,
+		CONFLICTING_REUC_ENTRY,
+		REMOVED_IN_BRANCH_REUC_ENTRY,
+		REMOVED_IN_MASTER_REUC_ENTRY,
+	};
+
+	opts.file_favor = GIT_MERGE_FILE_FAVOR_OURS;
+
+	cl_git_pass(merge_trees_from_branches(&index, repo, "master", THEIRS_AUTOMERGE_BRANCH, &opts));
+
+	cl_assert(merge_test_index(index, merge_index_entries, 6));
+	cl_assert(merge_test_reuc(index, merge_reuc_entries, 4));
+
+	git_index_free(index);
+}
+
+void test_merge_trees_automerge__favor_theirs(void)
+{
+	git_index *index;
+	git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		ADDED_IN_MASTER_INDEX_ENTRY,
+		AUTOMERGEABLE_INDEX_ENTRY,
+		CHANGED_IN_BRANCH_INDEX_ENTRY,
+		CHANGED_IN_MASTER_INDEX_ENTRY,
+		{ 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 0, "conflicting.txt" },
+		UNCHANGED_INDEX_ENTRY,
+	};
+
+	struct merge_reuc_entry merge_reuc_entries[] = {
+		AUTOMERGEABLE_REUC_ENTRY,
+		CONFLICTING_REUC_ENTRY,
+		REMOVED_IN_BRANCH_REUC_ENTRY,
+		REMOVED_IN_MASTER_REUC_ENTRY,
+	};
+
+	opts.file_favor = GIT_MERGE_FILE_FAVOR_THEIRS;
+
+	cl_git_pass(merge_trees_from_branches(&index, repo, "master", THEIRS_AUTOMERGE_BRANCH, &opts));
+
+	cl_assert(merge_test_index(index, merge_index_entries, 6));
+	cl_assert(merge_test_reuc(index, merge_reuc_entries, 4));
+
+	git_index_free(index);
+}
+
+void test_merge_trees_automerge__unrelated(void)
+{
+	git_index *index;
+	git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0, "added-in-master.txt" },
+		{ 0100644, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", 2, "automergeable.txt" },
+		{ 0100644, "d07ec190c306ec690bac349e87d01c4358e49bb2", 3, "automergeable.txt" },
+		{ 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-branch.txt" },
+		{ 0100644, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", 0, "changed-in-master.txt" },
+		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
+		{ 0100644, "4b253da36a0ae8bfce63aeabd8c5b58429925594", 3, "conflicting.txt" },
+		{ 0100644, "ef58fdd8086c243bdc81f99e379acacfd21d32d6", 0, "new-in-unrelated1.txt" },
+		{ 0100644, "948ba6e701c1edab0c2d394fb7c5538334129793", 0, "new-in-unrelated2.txt" },
+		{ 0100644, "dfe3f22baa1f6fce5447901c3086bae368de6bdd", 0, "removed-in-branch.txt" },
+		{ 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0, "unchanged.txt" },
+	};
+
+	cl_git_pass(merge_trees_from_branches(&index, repo, "master", THEIRS_UNRELATED_BRANCH, &opts));
+
+	cl_assert(merge_test_index(index, merge_index_entries, 11));
+
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/commits.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/commits.c
new file mode 100755
index 0000000..c4e4709
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/commits.c
@@ -0,0 +1,131 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/merge.h"
+#include "merge.h"
+#include "../merge_helpers.h"
+
+static git_repository *repo;
+
+#define TEST_REPO_PATH "merge-resolve"
+
+void test_merge_trees_commits__initialize(void)
+{
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+}
+
+void test_merge_trees_commits__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_merge_trees_commits__automerge(void)
+{
+	git_index *index;
+	const git_index_entry *entry;
+	git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+	git_blob *blob;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0,  "added-in-master.txt" },
+		{ 0100644, "f2e1550a0c9e53d5811175864a29536642ae3821", 0,  "automergeable.txt" },
+		{ 0100644, "4eb04c9e79e88f6640d01ff5b25ca2a60764f216", 0,  "changed-in-branch.txt" },
+		{ 0100644, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", 0,  "changed-in-master.txt" },
+
+		{ 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 1, "conflicting.txt" },
+		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
+		{ 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" },
+
+		{ 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0,  "unchanged.txt" },
+	};
+
+	struct merge_reuc_entry merge_reuc_entries[] = {
+		{ "automergeable.txt", 0100644, 0100644, 0100644, \
+			"6212c31dab5e482247d7977e4f0dd3601decf13b", \
+			"ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", \
+			"058541fc37114bfc1dddf6bd6bffc7fae5c2e6fe" },
+		{ "removed-in-branch.txt", 0100644, 0100644, 0, \
+			"dfe3f22baa1f6fce5447901c3086bae368de6bdd", \
+			"dfe3f22baa1f6fce5447901c3086bae368de6bdd", \
+			"" },
+		{ "removed-in-master.txt", 0100644, 0, 0100644, \
+			"5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5", \
+			"", \
+			"5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5" },
+	};
+
+	cl_git_pass(merge_commits_from_branches(&index, repo, "master", "branch", &opts));
+
+	cl_assert(merge_test_index(index, merge_index_entries, 8));
+	cl_assert(merge_test_reuc(index, merge_reuc_entries, 3));
+
+	cl_assert((entry = git_index_get_bypath(index, "automergeable.txt", 0)) != NULL);
+	cl_assert(entry->file_size == strlen(AUTOMERGEABLE_MERGED_FILE));
+
+	cl_git_pass(git_object_lookup((git_object **)&blob, repo, &entry->id, GIT_OBJ_BLOB));
+	cl_assert(memcmp(git_blob_rawcontent(blob), AUTOMERGEABLE_MERGED_FILE, (size_t)entry->file_size) == 0);
+
+	git_index_free(index);
+	git_blob_free(blob);
+}
+
+void test_merge_trees_commits__no_ancestor(void)
+{
+	git_index *index;
+	git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0, "added-in-master.txt" },
+		{ 0100644, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", 2, "automergeable.txt" },
+		{ 0100644, "d07ec190c306ec690bac349e87d01c4358e49bb2", 3, "automergeable.txt" },
+		{ 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-branch.txt" },
+		{ 0100644, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", 0, "changed-in-master.txt" },
+		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
+		{ 0100644, "4b253da36a0ae8bfce63aeabd8c5b58429925594", 3, "conflicting.txt" },
+		{ 0100644, "ef58fdd8086c243bdc81f99e379acacfd21d32d6", 0, "new-in-unrelated1.txt" },
+		{ 0100644, "948ba6e701c1edab0c2d394fb7c5538334129793", 0, "new-in-unrelated2.txt" },
+		{ 0100644, "dfe3f22baa1f6fce5447901c3086bae368de6bdd", 0, "removed-in-branch.txt" },
+		{ 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0, "unchanged.txt" },
+	};
+
+	cl_git_pass(merge_commits_from_branches(&index, repo, "master", "unrelated", &opts));
+
+	cl_assert(merge_test_index(index, merge_index_entries, 11));
+
+	git_index_free(index);
+}
+
+
+void test_merge_trees_commits__df_conflict(void)
+{
+	git_index *index;
+	git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "49130a28ef567af9a6a6104c38773fedfa5f9742", 2, "dir-10" },
+		{ 0100644, "6c06dcd163587c2cc18be44857e0b71116382aeb", 3, "dir-10" },
+		{ 0100644, "43aafd43bea779ec74317dc361f45ae3f532a505", 0, "dir-6" },
+		{ 0100644, "a031a28ae70e33a641ce4b8a8f6317f1ab79dee4", 3, "dir-7" },
+		{ 0100644, "5012fd565b1393bdfda1805d4ec38ce6619e1fd1", 1, "dir-7/file.txt" },
+		{ 0100644, "a5563304ddf6caba25cb50323a2ea6f7dbfcadca", 2, "dir-7/file.txt" },
+		{ 0100644, "e9ad6ec3e38364a3d07feda7c4197d4d845c53b5", 0, "dir-8" },
+		{ 0100644, "3ef4d30382ca33fdeba9fda895a99e0891ba37aa", 2, "dir-9" },
+		{ 0100644, "fc4c636d6515e9e261f9260dbcf3cc6eca97ea08", 1, "dir-9/file.txt" },
+		{ 0100644, "76ab0e2868197ec158ddd6c78d8a0d2fd73d38f9", 3, "dir-9/file.txt" },
+		{ 0100644, "5c2411f8075f48a6b2fdb85ebc0d371747c4df15", 0, "file-1/new" },
+		{ 0100644, "a39a620dae5bc8b4e771cd4d251b7d080401a21e", 1, "file-2" },
+		{ 0100644, "d963979c237d08b6ba39062ee7bf64c7d34a27f8", 2, "file-2" },
+		{ 0100644, "5c341ead2ba6f2af98ce5ec3fe84f6b6d2899c0d", 0, "file-2/new" },
+		{ 0100644, "9efe7723802d4305142eee177e018fee1572c4f4", 0, "file-3/new" },
+		{ 0100644, "bacac9b3493509aa15e1730e1545fc0919d1dae0", 1, "file-4" },
+		{ 0100644, "7663fce0130db092936b137cabd693ec234eb060", 3, "file-4" },
+		{ 0100644, "e49f917b448d1340b31d76e54ba388268fd4c922", 0, "file-4/new" },
+		{ 0100644, "cab2cf23998b40f1af2d9d9a756dc9e285a8df4b", 2, "file-5/new" },
+		{ 0100644, "f5504f36e6f4eb797a56fc5bac6c6c7f32969bf2", 3, "file-5/new" },
+	};
+
+	cl_git_pass(merge_trees_from_branches(&index, repo, "df_side1", "df_side2", &opts));
+
+	cl_assert(merge_test_index(index, merge_index_entries, 20));
+
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/modeconflict.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/modeconflict.c
new file mode 100755
index 0000000..d858b8f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/modeconflict.c
@@ -0,0 +1,59 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/merge.h"
+#include "buffer.h"
+#include "merge.h"
+#include "../merge_helpers.h"
+#include "fileops.h"
+
+static git_repository *repo;
+
+#define TEST_REPO_PATH "merge-resolve"
+
+#define DF_SIDE1_BRANCH		"df_side1"
+#define DF_SIDE2_BRANCH		"df_side2"
+
+// Fixture setup and teardown
+void test_merge_trees_modeconflict__initialize(void)
+{
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+}
+
+void test_merge_trees_modeconflict__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_merge_trees_modeconflict__df_conflict(void)
+{
+	git_index *index;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "49130a28ef567af9a6a6104c38773fedfa5f9742", 2, "dir-10" },
+		{ 0100644, "6c06dcd163587c2cc18be44857e0b71116382aeb", 3, "dir-10" },
+		{ 0100644, "43aafd43bea779ec74317dc361f45ae3f532a505", 0, "dir-6" },
+		{ 0100644, "a031a28ae70e33a641ce4b8a8f6317f1ab79dee4", 3, "dir-7" },
+		{ 0100644, "5012fd565b1393bdfda1805d4ec38ce6619e1fd1", 1, "dir-7/file.txt" },
+		{ 0100644, "a5563304ddf6caba25cb50323a2ea6f7dbfcadca", 2, "dir-7/file.txt" },
+		{ 0100644, "e9ad6ec3e38364a3d07feda7c4197d4d845c53b5", 0, "dir-8" },
+		{ 0100644, "3ef4d30382ca33fdeba9fda895a99e0891ba37aa", 2, "dir-9" },
+		{ 0100644, "fc4c636d6515e9e261f9260dbcf3cc6eca97ea08", 1, "dir-9/file.txt" },
+		{ 0100644, "76ab0e2868197ec158ddd6c78d8a0d2fd73d38f9", 3, "dir-9/file.txt" },
+		{ 0100644, "5c2411f8075f48a6b2fdb85ebc0d371747c4df15", 0, "file-1/new" },
+		{ 0100644, "a39a620dae5bc8b4e771cd4d251b7d080401a21e", 1, "file-2" },
+		{ 0100644, "d963979c237d08b6ba39062ee7bf64c7d34a27f8", 2, "file-2" },
+		{ 0100644, "5c341ead2ba6f2af98ce5ec3fe84f6b6d2899c0d", 0, "file-2/new" },
+		{ 0100644, "9efe7723802d4305142eee177e018fee1572c4f4", 0, "file-3/new" },
+		{ 0100644, "bacac9b3493509aa15e1730e1545fc0919d1dae0", 1, "file-4" },
+		{ 0100644, "7663fce0130db092936b137cabd693ec234eb060", 3, "file-4" },
+		{ 0100644, "e49f917b448d1340b31d76e54ba388268fd4c922", 0, "file-4/new" },
+		{ 0100644, "cab2cf23998b40f1af2d9d9a756dc9e285a8df4b", 2, "file-5/new" },
+		{ 0100644, "f5504f36e6f4eb797a56fc5bac6c6c7f32969bf2", 3, "file-5/new" },
+	};
+
+	cl_git_pass(merge_trees_from_branches(&index, repo, DF_SIDE1_BRANCH, DF_SIDE2_BRANCH, NULL));
+
+	cl_assert(merge_test_index(index, merge_index_entries, 20));
+
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/renames.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/renames.c
new file mode 100755
index 0000000..d7721c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/renames.c
@@ -0,0 +1,252 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/merge.h"
+#include "buffer.h"
+#include "merge.h"
+#include "../merge_helpers.h"
+#include "fileops.h"
+
+static git_repository *repo;
+
+#define TEST_REPO_PATH "merge-resolve"
+
+#define BRANCH_RENAME_OURS					"rename_conflict_ours"
+#define BRANCH_RENAME_THEIRS				"rename_conflict_theirs"
+
+// Fixture setup and teardown
+void test_merge_trees_renames__initialize(void)
+{
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+}
+
+void test_merge_trees_renames__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_merge_trees_renames__index(void)
+{
+	git_index *index;
+	git_merge_options *opts = NULL;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "68c6c84b091926c7d90aa6a79b2bc3bb6adccd8e", 0, "0a-no-change.txt" },
+		{ 0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6", 0, "0b-duplicated-in-ours.txt" },
+		{ 0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6", 1, "0b-rewritten-in-ours.txt" },
+		{ 0100644, "e376fbdd06ebf021c92724da9f26f44212734e3e", 2, "0b-rewritten-in-ours.txt" },
+		{ 0100644, "b2d399ae15224e1d58066e3c8df70ce37de7a656", 3, "0b-rewritten-in-ours.txt" },
+		{ 0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31", 0, "0c-duplicated-in-theirs.txt" },
+		{ 0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31", 1, "0c-rewritten-in-theirs.txt" },
+		{ 0100644, "efc9121fdedaf08ba180b53ebfbcf71bd488ed09", 2, "0c-rewritten-in-theirs.txt" },
+		{ 0100644, "712ebba6669ea847d9829e4f1059d6c830c8b531", 3, "0c-rewritten-in-theirs.txt" },
+		{ 0100644, "0d872f8e871a30208305978ecbf9e66d864f1638", 0, "1a-newname-in-ours-edited-in-theirs.txt" },
+		{ 0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb", 0, "1a-newname-in-ours.txt" },
+		{ 0100644, "ed9523e62e453e50dd9be1606af19399b96e397a", 0, "1b-newname-in-theirs-edited-in-ours.txt" },
+		{ 0100644, "2b5f1f181ee3b58ea751f5dd5d8f9b445520a136", 0, "1b-newname-in-theirs.txt" },
+		{ 0100644, "178940b450f238a56c0d75b7955cb57b38191982", 0, "2-newname-in-both.txt" },
+		{ 0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9", 2, "3a-newname-in-ours-deleted-in-theirs.txt" },
+		{ 0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9", 1, "3a-renamed-in-ours-deleted-in-theirs.txt" },
+		{ 0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495", 3, "3b-newname-in-theirs-deleted-in-ours.txt" },
+		{ 0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495", 1, "3b-renamed-in-theirs-deleted-in-ours.txt" },
+		{ 0100644, "227792b52aaa0b238bea00ec7e509b02623f168c", 2, "4a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "8b5b53cb2aa9ceb1139f5312fcfa3cc3c5a47c9a", 3, "4a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "227792b52aaa0b238bea00ec7e509b02623f168c", 1, "4a-renamed-in-ours-added-in-theirs.txt" },
+		{ 0100644, "de872ee3618b894992e9d1e18ba2ebe256a112f9", 2, "4b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "98d52d07c0b0bbf2b46548f6aa521295c2cb55db", 3, "4b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "98d52d07c0b0bbf2b46548f6aa521295c2cb55db", 1, "4b-renamed-in-theirs-added-in-ours.txt" },
+		{ 0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436", 2, "5a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "98ba4205fcf31f5dd93c916d35fe3f3b3d0e6714", 3, "5a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436", 1, "5a-renamed-in-ours-added-in-theirs.txt" },
+		{ 0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436", 3, "5a-renamed-in-ours-added-in-theirs.txt" },
+		{ 0100644, "385c8a0f26ddf79e9041e15e17dc352ed2c4cced", 2, "5b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "63247125386de9ec90a27ad36169307bf8a11a38", 3, "5b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "63247125386de9ec90a27ad36169307bf8a11a38", 1, "5b-renamed-in-theirs-added-in-ours.txt" },
+		{ 0100644, "63247125386de9ec90a27ad36169307bf8a11a38", 2, "5b-renamed-in-theirs-added-in-ours.txt" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 2, "6-both-renamed-1-to-2-ours.txt" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 3, "6-both-renamed-1-to-2-theirs.txt" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 1, "6-both-renamed-1-to-2.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 1, "7-both-renamed-side-1.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 3, "7-both-renamed-side-1.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 1, "7-both-renamed-side-2.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 2, "7-both-renamed-side-2.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 2, "7-both-renamed.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 3, "7-both-renamed.txt" },
+	};
+
+	struct merge_name_entry merge_name_entries[] = {
+		{
+			"3a-renamed-in-ours-deleted-in-theirs.txt",
+			"3a-newname-in-ours-deleted-in-theirs.txt",
+			""
+		},
+
+		{
+			"3b-renamed-in-theirs-deleted-in-ours.txt",
+			"",
+			"3b-newname-in-theirs-deleted-in-ours.txt",
+		},
+
+		{
+			"4a-renamed-in-ours-added-in-theirs.txt",
+			"4a-newname-in-ours-added-in-theirs.txt",
+			"",
+		},
+
+		{
+			"4b-renamed-in-theirs-added-in-ours.txt",
+			"",
+			"4b-newname-in-theirs-added-in-ours.txt",
+		},
+
+		{
+			"5a-renamed-in-ours-added-in-theirs.txt",
+			"5a-newname-in-ours-added-in-theirs.txt",
+			"5a-renamed-in-ours-added-in-theirs.txt",
+		},
+
+		{
+			"5b-renamed-in-theirs-added-in-ours.txt",
+			"5b-renamed-in-theirs-added-in-ours.txt",
+			"5b-newname-in-theirs-added-in-ours.txt",
+		},
+
+		{
+			"6-both-renamed-1-to-2.txt",
+			"6-both-renamed-1-to-2-ours.txt",
+			"6-both-renamed-1-to-2-theirs.txt",
+		},
+
+		{
+			"7-both-renamed-side-1.txt",
+			"7-both-renamed.txt",
+			"7-both-renamed-side-1.txt",
+		},
+
+		{
+			"7-both-renamed-side-2.txt",
+			"7-both-renamed-side-2.txt",
+			"7-both-renamed.txt",
+		},
+	};
+
+	struct merge_reuc_entry merge_reuc_entries[] = {
+		{ "1a-newname-in-ours-edited-in-theirs.txt",
+			0, 0100644, 0,
+			"",
+			"c3d02eeef75183df7584d8d13ac03053910c1301",
+			"" },
+
+		{ "1a-newname-in-ours.txt",
+			0, 0100644, 0,
+			"",
+			"d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb",
+			"" },
+
+		{ "1a-renamed-in-ours-edited-in-theirs.txt",
+			0100644, 0, 0100644,
+			"c3d02eeef75183df7584d8d13ac03053910c1301",
+			"",
+			"0d872f8e871a30208305978ecbf9e66d864f1638" },
+
+		{ "1a-renamed-in-ours.txt",
+			0100644, 0, 0100644,
+			"d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb",
+			"",
+			"d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb" },
+
+		{ "1b-newname-in-theirs-edited-in-ours.txt",
+			0, 0, 0100644,
+			"",
+			"",
+			"241a1005cd9b980732741b74385b891142bcba28" },
+
+		{ "1b-newname-in-theirs.txt",
+			0, 0, 0100644,
+			"",
+			"",
+			"2b5f1f181ee3b58ea751f5dd5d8f9b445520a136" },
+
+		{ "1b-renamed-in-theirs-edited-in-ours.txt",
+			0100644, 0100644, 0,
+			"241a1005cd9b980732741b74385b891142bcba28",
+			"ed9523e62e453e50dd9be1606af19399b96e397a",
+			"" },
+
+		{ "1b-renamed-in-theirs.txt",
+			0100644, 0100644, 0,
+			"2b5f1f181ee3b58ea751f5dd5d8f9b445520a136",
+			"2b5f1f181ee3b58ea751f5dd5d8f9b445520a136",
+			"" },
+
+		{ "2-newname-in-both.txt",
+			0, 0100644, 0100644,
+			"",
+			"178940b450f238a56c0d75b7955cb57b38191982",
+			"178940b450f238a56c0d75b7955cb57b38191982" },
+
+		{ "2-renamed-in-both.txt",
+			0100644, 0, 0,
+			"178940b450f238a56c0d75b7955cb57b38191982",
+			"",
+			"" },
+	};
+
+	cl_git_pass(merge_trees_from_branches(&index, repo,
+		BRANCH_RENAME_OURS, BRANCH_RENAME_THEIRS,
+		opts));
+
+	cl_assert(merge_test_index(index, merge_index_entries, 41));
+	cl_assert(merge_test_names(index, merge_name_entries, 9));
+	cl_assert(merge_test_reuc(index, merge_reuc_entries, 10));
+
+	git_index_free(index);
+}
+
+void test_merge_trees_renames__no_rename_index(void)
+{
+	git_index *index;
+	git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "68c6c84b091926c7d90aa6a79b2bc3bb6adccd8e", 0, "0a-no-change.txt" },
+		{ 0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6", 0, "0b-duplicated-in-ours.txt" },
+		{ 0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6", 1, "0b-rewritten-in-ours.txt" },
+		{ 0100644, "e376fbdd06ebf021c92724da9f26f44212734e3e", 2, "0b-rewritten-in-ours.txt" },
+		{ 0100644, "b2d399ae15224e1d58066e3c8df70ce37de7a656", 3, "0b-rewritten-in-ours.txt" },
+		{ 0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31", 0, "0c-duplicated-in-theirs.txt" },
+		{ 0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31", 1, "0c-rewritten-in-theirs.txt" },
+		{ 0100644, "efc9121fdedaf08ba180b53ebfbcf71bd488ed09", 2, "0c-rewritten-in-theirs.txt" },
+		{ 0100644, "712ebba6669ea847d9829e4f1059d6c830c8b531", 3, "0c-rewritten-in-theirs.txt" },
+		{ 0100644, "c3d02eeef75183df7584d8d13ac03053910c1301", 0, "1a-newname-in-ours-edited-in-theirs.txt" },
+		{ 0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb", 0, "1a-newname-in-ours.txt" },
+		{ 0100644, "c3d02eeef75183df7584d8d13ac03053910c1301", 1, "1a-renamed-in-ours-edited-in-theirs.txt" },
+		{ 0100644, "0d872f8e871a30208305978ecbf9e66d864f1638", 3, "1a-renamed-in-ours-edited-in-theirs.txt" },
+		{ 0100644, "241a1005cd9b980732741b74385b891142bcba28", 0, "1b-newname-in-theirs-edited-in-ours.txt" },
+		{ 0100644, "2b5f1f181ee3b58ea751f5dd5d8f9b445520a136", 0, "1b-newname-in-theirs.txt" },
+		{ 0100644, "241a1005cd9b980732741b74385b891142bcba28", 1, "1b-renamed-in-theirs-edited-in-ours.txt" },
+		{ 0100644, "ed9523e62e453e50dd9be1606af19399b96e397a", 2, "1b-renamed-in-theirs-edited-in-ours.txt" },
+		{ 0100644, "178940b450f238a56c0d75b7955cb57b38191982", 0, "2-newname-in-both.txt" },
+		{ 0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9", 0, "3a-newname-in-ours-deleted-in-theirs.txt" },
+		{ 0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495", 0, "3b-newname-in-theirs-deleted-in-ours.txt" },
+		{ 0100644, "227792b52aaa0b238bea00ec7e509b02623f168c", 2, "4a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "8b5b53cb2aa9ceb1139f5312fcfa3cc3c5a47c9a", 3, "4a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "de872ee3618b894992e9d1e18ba2ebe256a112f9", 2, "4b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "98d52d07c0b0bbf2b46548f6aa521295c2cb55db", 3, "4b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436", 2, "5a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "98ba4205fcf31f5dd93c916d35fe3f3b3d0e6714", 3, "5a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "385c8a0f26ddf79e9041e15e17dc352ed2c4cced", 2, "5b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "63247125386de9ec90a27ad36169307bf8a11a38", 3, "5b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 0, "6-both-renamed-1-to-2-ours.txt" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 0, "6-both-renamed-1-to-2-theirs.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 2, "7-both-renamed.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 3, "7-both-renamed.txt" },
+	};
+
+	cl_git_pass(merge_trees_from_branches(&index, repo,
+		BRANCH_RENAME_OURS, BRANCH_RENAME_THEIRS,
+		&opts));
+
+	cl_assert(merge_test_index(index, merge_index_entries, 32));
+
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/treediff.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/treediff.c
new file mode 100755
index 0000000..b96c4c4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/treediff.c
@@ -0,0 +1,554 @@
+#include "clar_libgit2.h"
+#include "git2/tree.h"
+#include "merge.h"
+#include "../merge_helpers.h"
+#include "diff.h"
+#include "git2/sys/hashsig.h"
+
+static git_repository *repo;
+
+#define TEST_REPO_PATH "merge-resolve"
+
+#define TREE_OID_ANCESTOR		"0d52e3a556e189ba0948ae56780918011c1b167d"
+#define TREE_OID_MASTER			"1f81433e3161efbf250576c58fede7f6b836f3d3"
+#define TREE_OID_BRANCH			"eea9286df54245fea72c5b557291470eb825f38f"
+#define TREE_OID_RENAMES1		"f5f9dd5886a6ee20272be0aafc790cba43b31931"
+#define TREE_OID_RENAMES2		"5fbfbdc04b4eca46f54f4853a3c5a1dce28f5165"
+
+#define TREE_OID_DF_ANCESTOR	"b8a3a806d3950e8c0a03a34f234a92eff0e2c68d"
+#define TREE_OID_DF_SIDE1		"ee1d6f164893c1866a323f072eeed36b855656be"
+#define TREE_OID_DF_SIDE2		"6178885b38fe96e825ac0f492c0a941f288b37f6"
+
+#define TREE_OID_RENAME_CONFLICT_ANCESTOR	"476dbb3e207313d1d8aaa120c6ad204bf1295e53"
+#define TREE_OID_RENAME_CONFLICT_OURS		"c4efe31e9decccc8b2b4d3df9aac2cdfe2995618"
+#define TREE_OID_RENAME_CONFLICT_THEIRS		"9e7f4359c469f309b6057febf4c6e80742cbed5b"
+
+void test_merge_trees_treediff__initialize(void)
+{
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+}
+
+void test_merge_trees_treediff__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static void test_find_differences(
+    const char *ancestor_oidstr,
+    const char *ours_oidstr,
+    const char *theirs_oidstr,
+    struct merge_index_conflict_data *treediff_conflict_data,
+    size_t treediff_conflict_data_len)
+{
+    git_merge_diff_list *merge_diff_list = git_merge_diff_list__alloc(repo);
+    git_oid ancestor_oid, ours_oid, theirs_oid;
+    git_tree *ancestor_tree, *ours_tree, *theirs_tree;
+	git_iterator *ancestor_iter, *ours_iter, *theirs_iter;
+
+	git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+	opts.tree_flags |= GIT_MERGE_TREE_FIND_RENAMES;
+	opts.target_limit = 1000;
+	opts.rename_threshold = 50;
+
+	opts.metric = git__malloc(sizeof(git_diff_similarity_metric));
+	cl_assert(opts.metric != NULL);
+
+	opts.metric->file_signature = git_diff_find_similar__hashsig_for_file;
+	opts.metric->buffer_signature = git_diff_find_similar__hashsig_for_buf;
+	opts.metric->free_signature = git_diff_find_similar__hashsig_free;
+	opts.metric->similarity = git_diff_find_similar__calc_similarity;
+	opts.metric->payload = (void *)GIT_HASHSIG_SMART_WHITESPACE;
+
+	cl_git_pass(git_oid_fromstr(&ancestor_oid, ancestor_oidstr));
+	cl_git_pass(git_oid_fromstr(&ours_oid, ours_oidstr));
+	cl_git_pass(git_oid_fromstr(&theirs_oid, theirs_oidstr));
+
+	cl_git_pass(git_tree_lookup(&ancestor_tree, repo, &ancestor_oid));
+	cl_git_pass(git_tree_lookup(&ours_tree, repo, &ours_oid));
+	cl_git_pass(git_tree_lookup(&theirs_tree, repo, &theirs_oid));
+
+	cl_git_pass(git_iterator_for_tree(&ancestor_iter, ancestor_tree,
+			GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL));
+	cl_git_pass(git_iterator_for_tree(&ours_iter, ours_tree,
+			GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL));
+	cl_git_pass(git_iterator_for_tree(&theirs_iter, theirs_tree,
+			GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL));
+
+	cl_git_pass(git_merge_diff_list__find_differences(merge_diff_list, ancestor_iter, ours_iter, theirs_iter));
+	cl_git_pass(git_merge_diff_list__find_renames(repo, merge_diff_list, &opts));
+
+	/*
+	dump_merge_index(merge_index);
+	 */
+
+	cl_assert(treediff_conflict_data_len == merge_diff_list->conflicts.length);
+
+	cl_assert(merge_test_merge_conflicts(&merge_diff_list->conflicts, treediff_conflict_data, treediff_conflict_data_len));
+
+	git_iterator_free(ancestor_iter);
+	git_iterator_free(ours_iter);
+	git_iterator_free(theirs_iter);
+
+	git_tree_free(ancestor_tree);
+	git_tree_free(ours_tree);
+	git_tree_free(theirs_tree);
+
+	git_merge_diff_list__free(merge_diff_list);
+
+	git__free(opts.metric);
+}
+
+void test_merge_trees_treediff__simple(void)
+{
+	struct merge_index_conflict_data treediff_conflict_data[] = {
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0, "added-in-master.txt" }, GIT_DELTA_ADDED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE
+		},
+
+		{
+			{ { 0100644, "6212c31dab5e482247d7977e4f0dd3601decf13b", 0, "automergeable.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", 0, "automergeable.txt" }, GIT_DELTA_MODIFIED },
+			{ { 0100644, "058541fc37114bfc1dddf6bd6bffc7fae5c2e6fe", 0, "automergeable.txt" }, GIT_DELTA_MODIFIED },
+			GIT_MERGE_DIFF_BOTH_MODIFIED
+		},
+
+		{
+			{ { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-branch.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-branch.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "4eb04c9e79e88f6640d01ff5b25ca2a60764f216", 0, "changed-in-branch.txt" }, GIT_DELTA_MODIFIED },
+			GIT_MERGE_DIFF_NONE
+		},
+
+		{
+			{ { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", 0, "changed-in-master.txt" }, GIT_DELTA_MODIFIED },
+			{ { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE
+        },
+
+		{
+			{ { 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 0, "conflicting.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 0, "conflicting.txt" }, GIT_DELTA_MODIFIED },
+			{ { 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 0, "conflicting.txt" }, GIT_DELTA_MODIFIED },
+			GIT_MERGE_DIFF_BOTH_MODIFIED
+        },
+
+		{
+			{ { 0100644, "dfe3f22baa1f6fce5447901c3086bae368de6bdd", 0, "removed-in-branch.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "dfe3f22baa1f6fce5447901c3086bae368de6bdd", 0, "removed-in-branch.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			GIT_MERGE_DIFF_NONE
+        },
+
+		{
+			{ { 0100644, "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5", 0, "removed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			{ { 0100644, "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5", 0, "removed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE
+		},
+    };
+
+    test_find_differences(TREE_OID_ANCESTOR, TREE_OID_MASTER, TREE_OID_BRANCH, treediff_conflict_data, 7);
+}
+
+void test_merge_trees_treediff__df_conflicts(void)
+{
+	struct merge_index_conflict_data treediff_conflict_data[] = {
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "49130a28ef567af9a6a6104c38773fedfa5f9742", 0, "dir-10" }, GIT_DELTA_ADDED },
+			{ { 0100644, "6c06dcd163587c2cc18be44857e0b71116382aeb", 0, "dir-10" }, GIT_DELTA_ADDED },
+			GIT_MERGE_DIFF_BOTH_ADDED,
+		},
+
+		{
+			{ { 0100644, "242591eb280ee9eeb2ce63524b9a8b9bc4cb515d", 0, "dir-10/file.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			GIT_MERGE_DIFF_BOTH_DELETED,
+		},
+
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "43aafd43bea779ec74317dc361f45ae3f532a505", 0, "dir-6" }, GIT_DELTA_ADDED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "cf8c5cc8a85a1ff5a4ba51e0bc7cf5665669924d", 0, "dir-6/file.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "cf8c5cc8a85a1ff5a4ba51e0bc7cf5665669924d", 0, "dir-6/file.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "a031a28ae70e33a641ce4b8a8f6317f1ab79dee4", 0, "dir-7" }, GIT_DELTA_ADDED },
+			GIT_MERGE_DIFF_DIRECTORY_FILE,
+		},
+
+		{
+			{ { 0100644, "5012fd565b1393bdfda1805d4ec38ce6619e1fd1", 0, "dir-7/file.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "a5563304ddf6caba25cb50323a2ea6f7dbfcadca", 0, "dir-7/file.txt" }, GIT_DELTA_MODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			GIT_MERGE_DIFF_DF_CHILD,
+		},
+
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "e9ad6ec3e38364a3d07feda7c4197d4d845c53b5", 0, "dir-8" }, GIT_DELTA_ADDED },
+			{ {0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "f20c9063fa0bda9a397c96947a7b687305c49753", 0, "dir-8/file.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			{ { 0100644, "f20c9063fa0bda9a397c96947a7b687305c49753", 0, "dir-8/file.txt" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "3ef4d30382ca33fdeba9fda895a99e0891ba37aa", 0, "dir-9" }, GIT_DELTA_ADDED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_DIRECTORY_FILE,
+		},
+
+		{
+			{ { 0100644, "fc4c636d6515e9e261f9260dbcf3cc6eca97ea08", 0, "dir-9/file.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			{ { 0100644, "76ab0e2868197ec158ddd6c78d8a0d2fd73d38f9", 0, "dir-9/file.txt" }, GIT_DELTA_MODIFIED },
+			GIT_MERGE_DIFF_DF_CHILD,
+		},
+
+		{
+			{ { 0100644, "1e4ff029aee68d0d69ef9eb6efa6cbf1ec732f99", 0, "file-1" },  GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "1e4ff029aee68d0d69ef9eb6efa6cbf1ec732f99", 0, "file-1" },  GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "5c2411f8075f48a6b2fdb85ebc0d371747c4df15", 0, "file-1/new" }, GIT_DELTA_ADDED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "a39a620dae5bc8b4e771cd4d251b7d080401a21e", 0, "file-2" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "d963979c237d08b6ba39062ee7bf64c7d34a27f8", 0, "file-2" }, GIT_DELTA_MODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			GIT_MERGE_DIFF_DIRECTORY_FILE,
+		},
+
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "5c341ead2ba6f2af98ce5ec3fe84f6b6d2899c0d", 0, "file-2/new" }, GIT_DELTA_ADDED },
+			GIT_MERGE_DIFF_DF_CHILD,
+		},
+
+		{
+			{ { 0100644, "032ebc5ab85d9553bb187d3cd40875ff23a63ed0", 0, "file-3" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			{ { 0100644, "032ebc5ab85d9553bb187d3cd40875ff23a63ed0", 0, "file-3" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "9efe7723802d4305142eee177e018fee1572c4f4", 0, "file-3/new" }, GIT_DELTA_ADDED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "bacac9b3493509aa15e1730e1545fc0919d1dae0", 0, "file-4" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			{ { 0100644, "7663fce0130db092936b137cabd693ec234eb060", 0, "file-4" }, GIT_DELTA_MODIFIED },
+			GIT_MERGE_DIFF_DIRECTORY_FILE,
+		},
+
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "e49f917b448d1340b31d76e54ba388268fd4c922", 0, "file-4/new" }, GIT_DELTA_ADDED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_DF_CHILD,
+		},
+
+		{
+			{ { 0100644, "ac4045f965119e6998f4340ed0f411decfb3ec05", 0, "file-5" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			GIT_MERGE_DIFF_BOTH_DELETED,
+		},
+
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "cab2cf23998b40f1af2d9d9a756dc9e285a8df4b", 0, "file-5/new" }, GIT_DELTA_ADDED },
+			{ { 0100644, "f5504f36e6f4eb797a56fc5bac6c6c7f32969bf2", 0, "file-5/new" }, GIT_DELTA_ADDED },
+			GIT_MERGE_DIFF_BOTH_ADDED,
+		},
+	};
+
+	test_find_differences(TREE_OID_DF_ANCESTOR, TREE_OID_DF_SIDE1, TREE_OID_DF_SIDE2, treediff_conflict_data, 20);
+}
+
+void test_merge_trees_treediff__strict_renames(void)
+{
+	struct merge_index_conflict_data treediff_conflict_data[] = {
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0, "added-in-master.txt" }, GIT_DELTA_ADDED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "6212c31dab5e482247d7977e4f0dd3601decf13b", 0, "automergeable.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", 0, "automergeable.txt" }, GIT_DELTA_MODIFIED },
+			{ { 0100644, "6212c31dab5e482247d7977e4f0dd3601decf13b", 0, "automergeable.txt" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", 0, "changed-in-master.txt" }, GIT_DELTA_MODIFIED },
+			{ { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 0, "conflicting.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 0, "conflicting.txt" }, GIT_DELTA_MODIFIED },
+			{ { 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 0, "conflicting.txt" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "dfe3f22baa1f6fce5447901c3086bae368de6bdd", 0, "removed-in-branch.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "dfe3f22baa1f6fce5447901c3086bae368de6bdd", 0, "removed-in-branch.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "dfe3f22baa1f6fce5447901c3086bae368de6bdd", 0, "renamed-in-branch.txt" }, GIT_DELTA_RENAMED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5", 0, "removed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			{ { 0100644,  "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5", 0, "removed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0, "renamed.txt" }, GIT_DELTA_ADDED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0, "unchanged.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0, "unchanged.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0, "copied.txt" }, GIT_DELTA_RENAMED },
+			GIT_MERGE_DIFF_NONE,
+		},
+    };
+
+	test_find_differences(TREE_OID_ANCESTOR, TREE_OID_MASTER, TREE_OID_RENAMES1, treediff_conflict_data, 8);
+}
+
+void test_merge_trees_treediff__rename_conflicts(void)
+{
+	struct merge_index_conflict_data treediff_conflict_data[] = {
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6", 0, "0b-duplicated-in-ours.txt" }, GIT_DELTA_ADDED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6", 0, "0b-rewritten-in-ours.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "e376fbdd06ebf021c92724da9f26f44212734e3e", 0, "0b-rewritten-in-ours.txt" }, GIT_DELTA_MODIFIED },
+			{ { 0100644, "b2d399ae15224e1d58066e3c8df70ce37de7a656", 0, "0b-rewritten-in-ours.txt" }, GIT_DELTA_MODIFIED },
+			GIT_MERGE_DIFF_BOTH_MODIFIED,
+		},
+
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31", 0, "0c-duplicated-in-theirs.txt" }, GIT_DELTA_ADDED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31", 0, "0c-rewritten-in-theirs.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "efc9121fdedaf08ba180b53ebfbcf71bd488ed09", 0, "0c-rewritten-in-theirs.txt" }, GIT_DELTA_MODIFIED },
+			{ { 0100644, "712ebba6669ea847d9829e4f1059d6c830c8b531", 0, "0c-rewritten-in-theirs.txt" }, GIT_DELTA_MODIFIED },
+			GIT_MERGE_DIFF_BOTH_MODIFIED,
+		},
+
+		{
+			{ { 0100644, "c3d02eeef75183df7584d8d13ac03053910c1301", 0, "1a-renamed-in-ours-edited-in-theirs.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "c3d02eeef75183df7584d8d13ac03053910c1301", 0, "1a-newname-in-ours-edited-in-theirs.txt" }, GIT_DELTA_RENAMED },
+			{ { 0100644, "0d872f8e871a30208305978ecbf9e66d864f1638", 0, "1a-renamed-in-ours-edited-in-theirs.txt" }, GIT_DELTA_MODIFIED },
+			GIT_MERGE_DIFF_RENAMED_MODIFIED,
+		},
+
+		{
+			{ { 0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb", 0, "1a-renamed-in-ours.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb", 0, "1a-newname-in-ours.txt" }, GIT_DELTA_RENAMED },
+			{ { 0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb", 0, "1a-renamed-in-ours.txt" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "241a1005cd9b980732741b74385b891142bcba28", 0, "1b-renamed-in-theirs-edited-in-ours.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "ed9523e62e453e50dd9be1606af19399b96e397a", 0, "1b-renamed-in-theirs-edited-in-ours.txt" }, GIT_DELTA_MODIFIED },
+			{ { 0100644, "241a1005cd9b980732741b74385b891142bcba28", 0, "1b-newname-in-theirs-edited-in-ours.txt" }, GIT_DELTA_RENAMED },
+			GIT_MERGE_DIFF_RENAMED_MODIFIED,
+		},
+
+		{
+			{ { 0100644, "2b5f1f181ee3b58ea751f5dd5d8f9b445520a136", 0, "1b-renamed-in-theirs.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "2b5f1f181ee3b58ea751f5dd5d8f9b445520a136", 0, "1b-renamed-in-theirs.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "2b5f1f181ee3b58ea751f5dd5d8f9b445520a136", 0, "1b-newname-in-theirs.txt" }, GIT_DELTA_RENAMED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "178940b450f238a56c0d75b7955cb57b38191982", 0, "2-renamed-in-both.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "178940b450f238a56c0d75b7955cb57b38191982", 0, "2-newname-in-both.txt" }, GIT_DELTA_RENAMED },
+			{ { 0100644, "178940b450f238a56c0d75b7955cb57b38191982", 0, "2-newname-in-both.txt" }, GIT_DELTA_RENAMED },
+			GIT_MERGE_DIFF_BOTH_RENAMED,
+		},
+
+		{
+			{ { 0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9", 0, "3a-renamed-in-ours-deleted-in-theirs.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9", 0, "3a-newname-in-ours-deleted-in-theirs.txt" }, GIT_DELTA_RENAMED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			GIT_MERGE_DIFF_RENAMED_DELETED,
+		},
+
+		{
+			{ { 0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495", 0, "3b-renamed-in-theirs-deleted-in-ours.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			{ { 0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495", 0, "3b-newname-in-theirs-deleted-in-ours.txt" }, GIT_DELTA_RENAMED },
+			GIT_MERGE_DIFF_RENAMED_DELETED,
+		},
+
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "8b5b53cb2aa9ceb1139f5312fcfa3cc3c5a47c9a", 0, "4a-newname-in-ours-added-in-theirs.txt" }, GIT_DELTA_ADDED },
+			GIT_MERGE_DIFF_RENAMED_ADDED,
+		},
+
+		{
+			{ { 0100644, "227792b52aaa0b238bea00ec7e509b02623f168c", 0, "4a-renamed-in-ours-added-in-theirs.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "227792b52aaa0b238bea00ec7e509b02623f168c", 0, "4a-newname-in-ours-added-in-theirs.txt" }, GIT_DELTA_RENAMED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			GIT_MERGE_DIFF_RENAMED_ADDED,
+		},
+
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "de872ee3618b894992e9d1e18ba2ebe256a112f9", 0, "4b-newname-in-theirs-added-in-ours.txt" }, GIT_DELTA_ADDED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_RENAMED_ADDED,
+		},
+
+		{
+			{ { 0100644, "98d52d07c0b0bbf2b46548f6aa521295c2cb55db", 0, "4b-renamed-in-theirs-added-in-ours.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			{ { 0100644, "98d52d07c0b0bbf2b46548f6aa521295c2cb55db", 0, "4b-newname-in-theirs-added-in-ours.txt" }, GIT_DELTA_RENAMED },
+			GIT_MERGE_DIFF_RENAMED_ADDED,
+		},
+
+		{
+			{ { 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 0, "5-both-renamed-1-to-2.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 0, "5-both-renamed-1-to-2-ours.txt" }, GIT_DELTA_RENAMED },
+			{ { 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 0, "5-both-renamed-1-to-2-theirs.txt" }, GIT_DELTA_RENAMED },
+			GIT_MERGE_DIFF_BOTH_RENAMED_1_TO_2,
+		},
+
+		{
+			{ { 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 0, "6-both-renamed-side-1.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 0, "6-both-renamed.txt" }, GIT_DELTA_RENAMED },
+			{ { 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 0, "6-both-renamed-side-1.txt" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1,
+		},
+
+		{
+			{ { 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 0, "6-both-renamed-side-2.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 0, "6-both-renamed-side-2.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 0, "6-both-renamed.txt" }, GIT_DELTA_RENAMED },
+			GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1,
+		},
+    };
+	test_find_differences(TREE_OID_RENAME_CONFLICT_ANCESTOR,
+		TREE_OID_RENAME_CONFLICT_OURS, TREE_OID_RENAME_CONFLICT_THEIRS, treediff_conflict_data, 18);
+}
+
+void test_merge_trees_treediff__best_renames(void)
+{
+	struct merge_index_conflict_data treediff_conflict_data[] = {
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0, "added-in-master.txt" }, GIT_DELTA_ADDED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "6212c31dab5e482247d7977e4f0dd3601decf13b", 0, "automergeable.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", 0, "automergeable.txt" }, GIT_DELTA_MODIFIED },
+			{ { 0100644, "45299c1ca5e07bba1fd90843056fb559f96b1f5a", 0, "renamed-90.txt" }, GIT_DELTA_RENAMED },
+			GIT_MERGE_DIFF_RENAMED_MODIFIED,
+        },
+
+		{
+			{ { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", 0, "changed-in-master.txt" }, GIT_DELTA_MODIFIED },
+			{ { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE,
+        },
+
+		{
+			{ { 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 0, "conflicting.txt" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 0, "conflicting.txt" }, GIT_DELTA_MODIFIED },
+			{ { 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 0, "conflicting.txt" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0100644, "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5", 0, "removed-in-master.txt" },GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
+			{ { 0100644, "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5", 0, "removed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
+			GIT_MERGE_DIFF_MODIFIED_DELETED,
+        },
+
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "5843febcb23480df0b5edb22a21c59c772bb8e29", 0, "renamed-50.txt" }, GIT_DELTA_ADDED },
+			GIT_MERGE_DIFF_NONE,
+		},
+
+		{
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
+			{ { 0100644, "a77a56a49f8f3ae242e02717f18ebbc60c5cc543", 0, "renamed-75.txt" }, GIT_DELTA_ADDED },
+			GIT_MERGE_DIFF_NONE,
+		},
+    };
+
+	test_find_differences(TREE_OID_ANCESTOR, TREE_OID_MASTER, TREE_OID_RENAMES2, treediff_conflict_data, 7);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/trivial.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/trivial.c
new file mode 100755
index 0000000..2262edd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/trivial.c
@@ -0,0 +1,306 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/merge.h"
+#include "merge.h"
+#include "../merge_helpers.h"
+#include "refs.h"
+#include "fileops.h"
+#include "git2/sys/index.h"
+
+static git_repository *repo;
+
+#define TEST_REPO_PATH "merge-resolve"
+#define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index"
+
+
+// Fixture setup and teardown
+void test_merge_trees_trivial__initialize(void)
+{
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+}
+
+void test_merge_trees_trivial__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+
+static int merge_trivial(git_index **index, const char *ours, const char *theirs)
+{
+	git_commit *our_commit, *their_commit, *ancestor_commit;
+	git_tree *our_tree, *their_tree, *ancestor_tree;
+	git_oid our_oid, their_oid, ancestor_oid;
+	git_buf branch_buf = GIT_BUF_INIT;
+	git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+
+	git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours);
+	cl_git_pass(git_reference_name_to_id(&our_oid, repo, branch_buf.ptr));
+	cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid));
+
+	git_buf_clear(&branch_buf);
+	git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs);
+	cl_git_pass(git_reference_name_to_id(&their_oid, repo, branch_buf.ptr));
+	cl_git_pass(git_commit_lookup(&their_commit, repo, &their_oid));
+
+	cl_git_pass(git_merge_base(&ancestor_oid, repo, git_commit_id(our_commit), git_commit_id(their_commit)));
+	cl_git_pass(git_commit_lookup(&ancestor_commit, repo, &ancestor_oid));
+
+	cl_git_pass(git_commit_tree(&ancestor_tree, ancestor_commit));
+	cl_git_pass(git_commit_tree(&our_tree, our_commit));
+	cl_git_pass(git_commit_tree(&their_tree, their_commit));
+
+	cl_git_pass(git_merge_trees(index, repo, ancestor_tree, our_tree, their_tree, &opts));
+
+	git_buf_free(&branch_buf);
+	git_tree_free(our_tree);
+	git_tree_free(their_tree);
+	git_tree_free(ancestor_tree);
+	git_commit_free(our_commit);
+	git_commit_free(their_commit);
+	git_commit_free(ancestor_commit);
+
+	return 0;
+}
+
+static int merge_trivial_conflict_entrycount(git_index *index)
+{
+	const git_index_entry *entry;
+	int count = 0;
+	size_t i;
+
+	for (i = 0; i < git_index_entrycount(index); i++) {
+		cl_assert(entry = git_index_get_byindex(index, i));
+
+		if (git_index_entry_is_conflict(entry))
+			count++;
+	}
+
+	return count;
+}
+
+/* 2ALT: ancest:(empty)+, head:*empty*, remote:remote = result:remote */
+void test_merge_trees_trivial__2alt(void)
+{
+	git_index *result;
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial(&result, "trivial-2alt", "trivial-2alt-branch"));
+
+	cl_assert(entry = git_index_get_bypath(result, "new-in-branch.txt", 0));
+	cl_assert(git_index_reuc_entrycount(result) == 0);
+	cl_assert(merge_trivial_conflict_entrycount(result) == 0);
+
+	git_index_free(result);
+}
+
+/* 3ALT: ancest:(empty)+, head:head, remote:*empty* = result:head */
+void test_merge_trees_trivial__3alt(void)
+{
+	git_index *result;
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial(&result, "trivial-3alt", "trivial-3alt-branch"));
+
+	cl_assert(entry = git_index_get_bypath(result, "new-in-3alt.txt", 0));
+	cl_assert(git_index_reuc_entrycount(result) == 0);
+	cl_assert(merge_trivial_conflict_entrycount(result) == 0);
+
+	git_index_free(result);
+}
+
+/* 4: ancest:(empty)^, head:head, remote:remote = result:no merge */
+void test_merge_trees_trivial__4(void)
+{
+	git_index *result;
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial(&result, "trivial-4", "trivial-4-branch"));
+
+	cl_assert((entry = git_index_get_bypath(result, "new-and-different.txt", 0)) == NULL);
+	cl_assert(git_index_reuc_entrycount(result) == 0);
+
+	cl_assert(merge_trivial_conflict_entrycount(result) == 2);
+	cl_assert(entry = git_index_get_bypath(result, "new-and-different.txt", 2));
+	cl_assert(entry = git_index_get_bypath(result, "new-and-different.txt", 3));
+
+	git_index_free(result);
+}
+
+/* 5ALT: ancest:*, head:head, remote:head = result:head */
+void test_merge_trees_trivial__5alt_1(void)
+{
+	git_index *result;
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial(&result, "trivial-5alt-1", "trivial-5alt-1-branch"));
+
+	cl_assert(entry = git_index_get_bypath(result, "new-and-same.txt", 0));
+	cl_assert(git_index_reuc_entrycount(result) == 0);
+	cl_assert(merge_trivial_conflict_entrycount(result) == 0);
+
+	git_index_free(result);
+}
+
+/* 5ALT: ancest:*, head:head, remote:head = result:head */
+void test_merge_trees_trivial__5alt_2(void)
+{
+	git_index *result;
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial(&result, "trivial-5alt-2", "trivial-5alt-2-branch"));
+
+	cl_assert(entry = git_index_get_bypath(result, "modified-to-same.txt", 0));
+	cl_assert(git_index_reuc_entrycount(result) == 0);
+	cl_assert(merge_trivial_conflict_entrycount(result) == 0);
+
+	git_index_free(result);
+}
+
+/* 6: ancest:ancest+, head:(empty), remote:(empty) = result:no merge */
+void test_merge_trees_trivial__6(void)
+{
+	git_index *result;
+	const git_index_entry *entry;
+	const git_index_reuc_entry *reuc;
+
+	cl_git_pass(merge_trivial(&result, "trivial-6", "trivial-6-branch"));
+
+	cl_assert((entry = git_index_get_bypath(result, "removed-in-both.txt", 0)) == NULL);
+	cl_assert(git_index_reuc_entrycount(result) == 1);
+	cl_assert(reuc = git_index_reuc_get_bypath(result, "removed-in-both.txt"));
+
+	cl_assert(merge_trivial_conflict_entrycount(result) == 0);
+
+	git_index_free(result);
+}
+
+/* 8: ancest:ancest^, head:(empty), remote:ancest = result:no merge */
+void test_merge_trees_trivial__8(void)
+{
+	git_index *result;
+	const git_index_entry *entry;
+	const git_index_reuc_entry *reuc;
+
+	cl_git_pass(merge_trivial(&result, "trivial-8", "trivial-8-branch"));
+
+	cl_assert((entry = git_index_get_bypath(result, "removed-in-8.txt", 0)) == NULL);
+
+	cl_assert(git_index_reuc_entrycount(result) == 1);
+	cl_assert(reuc = git_index_reuc_get_bypath(result, "removed-in-8.txt"));
+
+	cl_assert(merge_trivial_conflict_entrycount(result) == 0);
+
+	git_index_free(result);
+}
+
+/* 7: ancest:ancest+, head:(empty), remote:remote = result:no merge */
+void test_merge_trees_trivial__7(void)
+{
+	git_index *result;
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial(&result, "trivial-7", "trivial-7-branch"));
+
+	cl_assert((entry = git_index_get_bypath(result, "removed-in-7.txt", 0)) == NULL);
+	cl_assert(git_index_reuc_entrycount(result) == 0);
+
+	cl_assert(merge_trivial_conflict_entrycount(result) == 2);
+	cl_assert(entry = git_index_get_bypath(result, "removed-in-7.txt", 1));
+	cl_assert(entry = git_index_get_bypath(result, "removed-in-7.txt", 3));
+
+	git_index_free(result);
+}
+
+/* 10: ancest:ancest^, head:ancest, remote:(empty) = result:no merge */
+void test_merge_trees_trivial__10(void)
+{
+	git_index *result;
+	const git_index_entry *entry;
+	const git_index_reuc_entry *reuc;
+
+	cl_git_pass(merge_trivial(&result, "trivial-10", "trivial-10-branch"));
+
+	cl_assert((entry = git_index_get_bypath(result, "removed-in-10-branch.txt", 0)) == NULL);
+
+	cl_assert(git_index_reuc_entrycount(result) == 1);
+	cl_assert(reuc = git_index_reuc_get_bypath(result, "removed-in-10-branch.txt"));
+
+	cl_assert(merge_trivial_conflict_entrycount(result) == 0);
+
+	git_index_free(result);
+}
+
+/* 9: ancest:ancest+, head:head, remote:(empty) = result:no merge */
+void test_merge_trees_trivial__9(void)
+{
+	git_index *result;
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial(&result, "trivial-9", "trivial-9-branch"));
+
+	cl_assert((entry = git_index_get_bypath(result, "removed-in-9-branch.txt", 0)) == NULL);
+	cl_assert(git_index_reuc_entrycount(result) == 0);
+
+	cl_assert(merge_trivial_conflict_entrycount(result) == 2);
+	cl_assert(entry = git_index_get_bypath(result, "removed-in-9-branch.txt", 1));
+	cl_assert(entry = git_index_get_bypath(result, "removed-in-9-branch.txt", 2));
+
+	git_index_free(result);
+}
+
+/* 13: ancest:ancest+, head:head, remote:ancest = result:head */
+void test_merge_trees_trivial__13(void)
+{
+	git_index *result;
+	const git_index_entry *entry;
+	git_oid expected_oid;
+
+	cl_git_pass(merge_trivial(&result, "trivial-13", "trivial-13-branch"));
+
+	cl_assert(entry = git_index_get_bypath(result, "modified-in-13.txt", 0));
+	cl_git_pass(git_oid_fromstr(&expected_oid, "1cff9ec6a47a537380dedfdd17c9e76d74259a2b"));
+	cl_assert_equal_oid(&expected_oid, &entry->id);
+
+	cl_assert(git_index_reuc_entrycount(result) == 0);
+	cl_assert(merge_trivial_conflict_entrycount(result) == 0);
+
+	git_index_free(result);
+}
+
+/* 14: ancest:ancest+, head:ancest, remote:remote = result:remote */
+void test_merge_trees_trivial__14(void)
+{
+	git_index *result;
+	const git_index_entry *entry;
+	git_oid expected_oid;
+
+	cl_git_pass(merge_trivial(&result, "trivial-14", "trivial-14-branch"));
+
+	cl_assert(entry = git_index_get_bypath(result, "modified-in-14-branch.txt", 0));
+	cl_git_pass(git_oid_fromstr(&expected_oid, "26153a3ff3649b6c2bb652d3f06878c6e0a172f9"));
+	cl_assert(git_oid_cmp(&entry->id, &expected_oid) == 0);
+
+	cl_assert(git_index_reuc_entrycount(result) == 0);
+	cl_assert(merge_trivial_conflict_entrycount(result) == 0);
+
+	git_index_free(result);
+}
+
+/* 11: ancest:ancest+, head:head, remote:remote = result:no merge */
+void test_merge_trees_trivial__11(void)
+{
+	git_index *result;
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial(&result, "trivial-11", "trivial-11-branch"));
+
+	cl_assert((entry = git_index_get_bypath(result, "modified-in-both.txt", 0)) == NULL);
+	cl_assert(git_index_reuc_entrycount(result) == 0);
+
+	cl_assert(merge_trivial_conflict_entrycount(result) == 3);
+	cl_assert(entry = git_index_get_bypath(result, "modified-in-both.txt", 1));
+	cl_assert(entry = git_index_get_bypath(result, "modified-in-both.txt", 2));
+	cl_assert(entry = git_index_get_bypath(result, "modified-in-both.txt", 3));
+
+	git_index_free(result);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/whitespace.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/whitespace.c
new file mode 100755
index 0000000..b99583c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/trees/whitespace.c
@@ -0,0 +1,82 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/merge.h"
+#include "buffer.h"
+#include "merge.h"
+#include "../merge_helpers.h"
+#include "fileops.h"
+
+static git_repository *repo;
+
+#define TEST_REPO_PATH "merge-whitespace"
+
+#define BRANCH_A_EOL  "branch_a_eol"
+#define BRANCH_B_EOL  "branch_b_eol"
+
+#define BRANCH_A_CHANGE  "branch_a_change"
+#define BRANCH_B_CHANGE  "branch_b_change"
+
+// Fixture setup and teardown
+void test_merge_trees_whitespace__initialize(void)
+{
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+}
+
+void test_merge_trees_whitespace__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_merge_trees_whitespace__conflict(void)
+{
+	git_index *index;
+	git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "4026a6c83f39c56881c9ac62e7582db9e3d33a4f", 1, "test.txt" },
+		{ 0100644, "c3b1fb31424c98072542cc8e42b48c92e52f494a", 2, "test.txt" },
+		{ 0100644, "262f67de0de2e535a59ae1bc3c739601e98c354d", 3, "test.txt" },
+	};
+
+	cl_git_pass(merge_trees_from_branches(&index, repo, BRANCH_A_EOL, BRANCH_B_EOL, &opts));
+
+	cl_assert(merge_test_index(index, merge_index_entries, 3));
+
+	git_index_free(index);
+}
+
+void test_merge_trees_whitespace__eol(void)
+{
+	git_index *index;
+	git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "ee3c2aac8e03224c323b58ecb1f9eef616745467", 0, "test.txt" },
+	};
+
+	opts.file_flags |= GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL;
+
+	cl_git_pass(merge_trees_from_branches(&index, repo, BRANCH_A_EOL, BRANCH_B_EOL, &opts));
+
+	cl_assert(merge_test_index(index, merge_index_entries, 1));
+
+	git_index_free(index);
+}
+
+void test_merge_trees_whitespace__change(void)
+{
+	git_index *index;
+	git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "a827eab4fd66ab37a6ebcfaa7b7e341abfd55947", 0, "test.txt" },
+	};
+
+	opts.file_flags |= GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE;
+
+	cl_git_pass(merge_trees_from_branches(&index, repo, BRANCH_A_CHANGE, BRANCH_B_CHANGE, &opts));
+
+	cl_assert(merge_test_index(index, merge_index_entries, 1));
+
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/analysis.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/analysis.c
new file mode 100755
index 0000000..351cfbd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/analysis.c
@@ -0,0 +1,141 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/merge.h"
+#include "git2/annotated_commit.h"
+#include "git2/sys/index.h"
+#include "merge.h"
+#include "../merge_helpers.h"
+#include "refs.h"
+#include "posix.h"
+
+static git_repository *repo;
+static git_index *repo_index;
+
+#define TEST_REPO_PATH "merge-resolve"
+#define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index"
+
+#define UPTODATE_BRANCH			"master"
+#define PREVIOUS_BRANCH			"previous"
+
+#define FASTFORWARD_BRANCH		"ff_branch"
+#define FASTFORWARD_ID			"fd89f8cffb663ac89095a0f9764902e93ceaca6a"
+
+#define NOFASTFORWARD_BRANCH	"branch"
+#define NOFASTFORWARD_ID		"7cb63eed597130ba4abb87b3e544b85021905520"
+
+
+// Fixture setup and teardown
+void test_merge_workdir_analysis__initialize(void)
+{
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+	git_repository_index(&repo_index, repo);
+}
+
+void test_merge_workdir_analysis__cleanup(void)
+{
+	git_index_free(repo_index);
+	cl_git_sandbox_cleanup();
+}
+
+static void analysis_from_branch(
+	git_merge_analysis_t *merge_analysis,
+	git_merge_preference_t *merge_pref,
+	const char *branchname)
+{
+	git_buf refname = GIT_BUF_INIT;
+	git_reference *their_ref;
+	git_annotated_commit *their_head;
+
+	git_buf_printf(&refname, "%s%s", GIT_REFS_HEADS_DIR, branchname);
+
+	cl_git_pass(git_reference_lookup(&their_ref, repo, git_buf_cstr(&refname)));
+	cl_git_pass(git_annotated_commit_from_ref(&their_head, repo, their_ref));
+
+	cl_git_pass(git_merge_analysis(merge_analysis, merge_pref, repo, (const git_annotated_commit **)&their_head, 1));
+
+	git_buf_free(&refname);
+	git_annotated_commit_free(their_head);
+	git_reference_free(their_ref);
+}
+
+void test_merge_workdir_analysis__fastforward(void)
+{
+	git_merge_analysis_t merge_analysis;
+	git_merge_preference_t merge_pref;
+
+	analysis_from_branch(&merge_analysis, &merge_pref, FASTFORWARD_BRANCH);
+	cl_assert_equal_i(GIT_MERGE_ANALYSIS_FASTFORWARD, (merge_analysis & GIT_MERGE_ANALYSIS_FASTFORWARD));
+	cl_assert_equal_i(GIT_MERGE_ANALYSIS_NORMAL, (merge_analysis & GIT_MERGE_ANALYSIS_NORMAL));
+}
+
+void test_merge_workdir_analysis__no_fastforward(void)
+{
+	git_merge_analysis_t merge_analysis;
+	git_merge_preference_t merge_pref;
+
+	analysis_from_branch(&merge_analysis, &merge_pref, NOFASTFORWARD_BRANCH);
+	cl_assert_equal_i(GIT_MERGE_ANALYSIS_NORMAL, merge_analysis);
+}
+
+void test_merge_workdir_analysis__uptodate(void)
+{
+	git_merge_analysis_t merge_analysis;
+	git_merge_preference_t merge_pref;
+
+	analysis_from_branch(&merge_analysis, &merge_pref, UPTODATE_BRANCH);
+	cl_assert_equal_i(GIT_MERGE_ANALYSIS_UP_TO_DATE, merge_analysis);
+}
+
+void test_merge_workdir_analysis__uptodate_merging_prev_commit(void)
+{
+	git_merge_analysis_t merge_analysis;
+	git_merge_preference_t merge_pref;
+
+	analysis_from_branch(&merge_analysis, &merge_pref, PREVIOUS_BRANCH);
+	cl_assert_equal_i(GIT_MERGE_ANALYSIS_UP_TO_DATE, merge_analysis);
+}
+
+void test_merge_workdir_analysis__unborn(void)
+{
+	git_merge_analysis_t merge_analysis;
+	git_merge_preference_t merge_pref;
+	git_buf master = GIT_BUF_INIT;
+
+	git_buf_joinpath(&master, git_repository_path(repo), "refs/heads/master");
+	p_unlink(git_buf_cstr(&master));
+
+	analysis_from_branch(&merge_analysis, &merge_pref, NOFASTFORWARD_BRANCH);
+	cl_assert_equal_i(GIT_MERGE_ANALYSIS_FASTFORWARD, (merge_analysis & GIT_MERGE_ANALYSIS_FASTFORWARD));
+	cl_assert_equal_i(GIT_MERGE_ANALYSIS_UNBORN, (merge_analysis & GIT_MERGE_ANALYSIS_UNBORN));
+
+	git_buf_free(&master);
+}
+
+void test_merge_workdir_analysis__fastforward_with_config_noff(void)
+{
+	git_config *config;
+	git_merge_analysis_t merge_analysis;
+	git_merge_preference_t merge_pref;
+
+	git_repository_config(&config, repo);
+	git_config_set_string(config, "merge.ff", "false");
+
+	analysis_from_branch(&merge_analysis, &merge_pref, FASTFORWARD_BRANCH);
+	cl_assert_equal_i(GIT_MERGE_ANALYSIS_FASTFORWARD, (merge_analysis & GIT_MERGE_ANALYSIS_FASTFORWARD));
+	cl_assert_equal_i(GIT_MERGE_ANALYSIS_NORMAL, (merge_analysis & GIT_MERGE_ANALYSIS_NORMAL));
+	cl_assert_equal_i(GIT_MERGE_PREFERENCE_NO_FASTFORWARD, (merge_pref & GIT_MERGE_PREFERENCE_NO_FASTFORWARD));
+}
+
+void test_merge_workdir_analysis__no_fastforward_with_config_ffonly(void)
+{
+	git_config *config;
+	git_merge_analysis_t merge_analysis;
+	git_merge_preference_t merge_pref;
+
+	git_repository_config(&config, repo);
+	git_config_set_string(config, "merge.ff", "only");
+
+	analysis_from_branch(&merge_analysis, &merge_pref, NOFASTFORWARD_BRANCH);
+	cl_assert_equal_i(GIT_MERGE_ANALYSIS_NORMAL, (merge_analysis & GIT_MERGE_ANALYSIS_NORMAL));
+	cl_assert_equal_i(GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY, (merge_pref & GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/dirty.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/dirty.c
new file mode 100755
index 0000000..4bf984c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/dirty.c
@@ -0,0 +1,347 @@
+#include "clar_libgit2.h"
+#include "git2/merge.h"
+#include "buffer.h"
+#include "merge.h"
+#include "index.h"
+#include "../merge_helpers.h"
+#include "posix.h"
+
+#define TEST_REPO_PATH "merge-resolve"
+#define MERGE_BRANCH_OID "7cb63eed597130ba4abb87b3e544b85021905520"
+
+#define AUTOMERGEABLE_MERGED_FILE \
+	"this file is changed in master\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is automergeable\n" \
+	"this file is changed in branch\n"
+
+#define CHANGED_IN_BRANCH_FILE \
+	"changed in branch\n"
+
+static git_repository *repo;
+static git_index *repo_index;
+
+static char *unaffected[][4] = {
+	{ "added-in-master.txt", NULL },
+	{ "changed-in-master.txt", NULL },
+	{ "unchanged.txt", NULL },
+	{ "added-in-master.txt", "changed-in-master.txt", NULL },
+	{ "added-in-master.txt", "unchanged.txt", NULL },
+	{ "changed-in-master.txt", "unchanged.txt", NULL },
+	{ "added-in-master.txt", "changed-in-master.txt", "unchanged.txt", NULL },
+	{ "new_file.txt", NULL },
+	{ "new_file.txt", "unchanged.txt", NULL },
+	{ NULL },
+};
+
+static char *affected[][5] = {
+	{ "automergeable.txt", NULL },
+	{ "changed-in-branch.txt", NULL },
+	{ "conflicting.txt", NULL },
+	{ "removed-in-branch.txt", NULL },
+	{ "automergeable.txt", "changed-in-branch.txt", NULL },
+	{ "automergeable.txt", "conflicting.txt", NULL },
+	{ "automergeable.txt", "removed-in-branch.txt", NULL },
+	{ "changed-in-branch.txt", "conflicting.txt", NULL },
+	{ "changed-in-branch.txt", "removed-in-branch.txt", NULL },
+	{ "conflicting.txt", "removed-in-branch.txt", NULL },
+	{ "automergeable.txt", "changed-in-branch.txt", "conflicting.txt", NULL },
+	{ "automergeable.txt", "changed-in-branch.txt", "removed-in-branch.txt", NULL },
+	{ "automergeable.txt", "conflicting.txt", "removed-in-branch.txt", NULL },
+	{ "changed-in-branch.txt", "conflicting.txt", "removed-in-branch.txt", NULL },
+	{ "automergeable.txt", "changed-in-branch.txt", "conflicting.txt", "removed-in-branch.txt", NULL },
+	{ NULL },
+};
+
+static char *result_contents[4][6] = {
+	{ "automergeable.txt", AUTOMERGEABLE_MERGED_FILE, NULL, NULL },
+	{ "changed-in-branch.txt", CHANGED_IN_BRANCH_FILE, NULL, NULL },
+	{ "automergeable.txt", AUTOMERGEABLE_MERGED_FILE, "changed-in-branch.txt", CHANGED_IN_BRANCH_FILE, NULL, NULL },
+	{ NULL }
+};
+
+void test_merge_workdir_dirty__initialize(void)
+{
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+	git_repository_index(&repo_index, repo);
+}
+
+void test_merge_workdir_dirty__cleanup(void)
+{
+	git_index_free(repo_index);
+	cl_git_sandbox_cleanup();
+}
+
+static void set_core_autocrlf_to(git_repository *repo, bool value)
+{
+	git_config *cfg;
+
+	cl_git_pass(git_repository_config(&cfg, repo));
+	cl_git_pass(git_config_set_bool(cfg, "core.autocrlf", value));
+
+	git_config_free(cfg);
+}
+
+static int merge_branch(void)
+{
+	git_oid their_oids[1];
+	git_annotated_commit *their_head;
+	git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT;
+	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
+	int error;
+
+	cl_git_pass(git_oid_fromstr(&their_oids[0], MERGE_BRANCH_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_head, repo, &their_oids[0]));
+
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+	error = git_merge(repo, (const git_annotated_commit **)&their_head, 1, &merge_opts, &checkout_opts);
+
+	git_annotated_commit_free(their_head);
+
+	return error;
+}
+
+static void write_files(char *files[])
+{
+	char *filename;
+	git_buf path = GIT_BUF_INIT, content = GIT_BUF_INIT;
+	size_t i;
+
+	for (i = 0, filename = files[i]; filename; filename = files[++i]) {
+		git_buf_clear(&path);
+		git_buf_clear(&content);
+
+		git_buf_printf(&path, "%s/%s", TEST_REPO_PATH, filename);
+		git_buf_printf(&content, "This is a dirty file in the working directory!\n\n"
+			"It will not be staged!  Its filename is %s.\n", filename);
+
+		cl_git_mkfile(path.ptr, content.ptr);
+	}
+
+	git_buf_free(&path);
+	git_buf_free(&content);
+}
+
+static void hack_index(char *files[])
+{
+	char *filename;
+	struct stat statbuf;
+	git_buf path = GIT_BUF_INIT;
+	git_index_entry *entry;
+	struct timeval times[2];
+	time_t now;
+	size_t i;
+
+	/* Update the index to suggest that checkout placed these files on
+	 * disk, keeping the object id but updating the cache, which will
+	 * emulate a Git implementation's different filter.
+	 *
+	 * We set the file's timestamp to before now to pretend that
+	 * it was an old checkout so we don't trigger the racy
+	 * protections would would check the content.
+	 */
+
+	now = time(NULL);
+	times[0].tv_sec  = now - 5;
+	times[0].tv_usec = 0;
+	times[1].tv_sec  = now - 5;
+	times[1].tv_usec = 0;
+
+	for (i = 0, filename = files[i]; filename; filename = files[++i]) {
+		git_buf_clear(&path);
+
+		cl_assert(entry = (git_index_entry *)
+			git_index_get_bypath(repo_index, filename, 0));
+
+		cl_git_pass(git_buf_printf(&path, "%s/%s", TEST_REPO_PATH, filename));
+		cl_git_pass(p_utimes(path.ptr, times));
+		cl_git_pass(p_stat(path.ptr, &statbuf));
+
+		entry->ctime.seconds = (git_time_t)statbuf.st_ctime;
+		entry->ctime.nanoseconds = 0;
+		entry->mtime.seconds = (git_time_t)statbuf.st_mtime;
+		entry->mtime.nanoseconds = 0;
+		entry->dev = statbuf.st_dev;
+		entry->ino = statbuf.st_ino;
+		entry->uid  = statbuf.st_uid;
+		entry->gid  = statbuf.st_gid;
+		entry->file_size = statbuf.st_size;
+	}
+
+	git_buf_free(&path);
+}
+
+static void stage_random_files(char *files[])
+{
+	char *filename;
+	size_t i;
+
+	write_files(files);
+
+	for (i = 0, filename = files[i]; filename; filename = files[++i])
+		cl_git_pass(git_index_add_bypath(repo_index, filename));
+}
+
+static void stage_content(char *content[])
+{
+	git_reference *head;
+	git_object *head_object;
+	git_buf path = GIT_BUF_INIT;
+	char *filename, *text;
+	size_t i;
+
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_peel(&head_object, head, GIT_OBJ_COMMIT));
+	cl_git_pass(git_reset(repo, head_object, GIT_RESET_HARD, NULL));
+
+	for (i = 0, filename = content[i], text = content[++i];
+		filename && text;
+		filename = content[++i], text = content[++i]) {
+
+		git_buf_clear(&path);
+
+		cl_git_pass(git_buf_printf(&path, "%s/%s", TEST_REPO_PATH, filename));
+
+		cl_git_mkfile(path.ptr, text);
+		cl_git_pass(git_index_add_bypath(repo_index, filename));
+	}
+
+	git_object_free(head_object);
+	git_reference_free(head);
+	git_buf_free(&path);
+}
+
+static int merge_dirty_files(char *dirty_files[])
+{
+	git_reference *head;
+	git_object *head_object;
+	int error;
+
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_peel(&head_object, head, GIT_OBJ_COMMIT));
+	cl_git_pass(git_reset(repo, head_object, GIT_RESET_HARD, NULL));
+
+	write_files(dirty_files);
+
+	error = merge_branch();
+
+	git_object_free(head_object);
+	git_reference_free(head);
+
+	return error;
+}
+
+static int merge_differently_filtered_files(char *files[])
+{
+	git_reference *head;
+	git_object *head_object;
+	int error;
+
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_peel(&head_object, head, GIT_OBJ_COMMIT));
+	cl_git_pass(git_reset(repo, head_object, GIT_RESET_HARD, NULL));
+
+	/* Emulate checkout with a broken or misconfigured filter:  modify some
+	 * files on-disk and then update the index with the updated file size
+	 * and time, as if some filter applied them.  These files should not be
+	 * treated as dirty since we created them.
+	 *
+	 * (Make sure to update the index stamp to defeat racy-git protections
+	 * trying to sanity check the files in the index; those would rehash the
+	 * files, showing them as dirty, the exact mechanism we're trying to avoid.)
+	 */
+
+	write_files(files);
+	hack_index(files);
+
+	cl_git_pass(git_index_write(repo_index));
+
+	error = merge_branch();
+
+	git_object_free(head_object);
+	git_reference_free(head);
+
+	return error;
+}
+
+static int merge_staged_files(char *staged_files[])
+{	
+	stage_random_files(staged_files);
+	return merge_branch();
+}
+
+void test_merge_workdir_dirty__unaffected_dirty_files_allowed(void)
+{
+	char **files;
+	size_t i;
+
+	for (i = 0, files = unaffected[i]; files[0]; files = unaffected[++i])
+		cl_git_pass(merge_dirty_files(files));
+}
+
+void test_merge_workdir_dirty__unstaged_deletes_maintained(void)
+{
+	git_reference *head;
+	git_object *head_object;
+
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_peel(&head_object, head, GIT_OBJ_COMMIT));
+	cl_git_pass(git_reset(repo, head_object, GIT_RESET_HARD, NULL));
+
+	cl_git_pass(p_unlink("merge-resolve/unchanged.txt"));
+
+	cl_git_pass(merge_branch());
+
+	git_object_free(head_object);
+	git_reference_free(head);
+}
+
+void test_merge_workdir_dirty__affected_dirty_files_disallowed(void)
+{
+	char **files;
+	size_t i;
+
+	for (i = 0, files = affected[i]; files[0]; files = affected[++i])
+		cl_git_fail(merge_dirty_files(files));
+}
+
+void test_merge_workdir_dirty__staged_files_in_index_disallowed(void)
+{
+	char **files;
+	size_t i;
+
+	for (i = 0, files = unaffected[i]; files[0]; files = unaffected[++i])
+		cl_git_fail(merge_staged_files(files));
+
+	for (i = 0, files = affected[i]; files[0]; files = affected[++i])
+		cl_git_fail(merge_staged_files(files));
+}
+
+void test_merge_workdir_dirty__identical_staged_files_allowed(void)
+{
+	char **content;
+	size_t i;
+
+	set_core_autocrlf_to(repo, false);
+	
+	for (i = 0, content = result_contents[i]; content[0]; content = result_contents[++i]) {
+		stage_content(content);
+
+		git_index_write(repo_index);
+		cl_git_pass(merge_branch());
+	}
+}
+
+void test_merge_workdir_dirty__honors_cache(void)
+{
+	char **files;
+	size_t i;
+
+	for (i = 0, files = affected[i]; files[0]; files = affected[++i])
+		cl_git_pass(merge_differently_filtered_files(files));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/renames.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/renames.c
new file mode 100755
index 0000000..83006a7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/renames.c
@@ -0,0 +1,156 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/merge.h"
+#include "buffer.h"
+#include "merge.h"
+#include "../merge_helpers.h"
+#include "fileops.h"
+#include "refs.h"
+
+static git_repository *repo;
+
+#define TEST_REPO_PATH "merge-resolve"
+
+#define BRANCH_RENAME_OURS					"rename_conflict_ours"
+#define BRANCH_RENAME_THEIRS				"rename_conflict_theirs"
+
+// Fixture setup and teardown
+void test_merge_workdir_renames__initialize(void)
+{
+	git_config *cfg;
+
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+
+	/* Ensure that the user's merge.conflictstyle doesn't interfere */
+	cl_git_pass(git_repository_config(&cfg, repo));
+	cl_git_pass(git_config_set_string(cfg, "merge.conflictstyle", "merge"));
+	git_config_free(cfg);
+}
+
+void test_merge_workdir_renames__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_merge_workdir_renames__renames(void)
+{
+	git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "68c6c84b091926c7d90aa6a79b2bc3bb6adccd8e", 0, "0a-no-change.txt" },
+		{ 0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6", 0, "0b-duplicated-in-ours.txt" },
+		{ 0100644, "8aac75de2a34b4d340bf62a6e58197269cb55797", 0, "0b-rewritten-in-ours.txt" },
+		{ 0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31", 0, "0c-duplicated-in-theirs.txt" },
+		{ 0100644, "7edc726325da726751a4195e434e4377b0f67f9a", 0, "0c-rewritten-in-theirs.txt" },
+		{ 0100644, "0d872f8e871a30208305978ecbf9e66d864f1638", 0, "1a-newname-in-ours-edited-in-theirs.txt" },
+		{ 0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb", 0, "1a-newname-in-ours.txt" },
+		{ 0100644, "ed9523e62e453e50dd9be1606af19399b96e397a", 0, "1b-newname-in-theirs-edited-in-ours.txt" },
+		{ 0100644, "2b5f1f181ee3b58ea751f5dd5d8f9b445520a136", 0, "1b-newname-in-theirs.txt" },
+		{ 0100644, "178940b450f238a56c0d75b7955cb57b38191982", 0, "2-newname-in-both.txt" },
+		{ 0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9", 0, "3a-newname-in-ours-deleted-in-theirs.txt" },
+		{ 0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495", 0, "3b-newname-in-theirs-deleted-in-ours.txt" },
+		{ 0100644, "227792b52aaa0b238bea00ec7e509b02623f168c", 0, "4a-newname-in-ours-added-in-theirs.txt~HEAD" },
+		{ 0100644, "8b5b53cb2aa9ceb1139f5312fcfa3cc3c5a47c9a", 0, "4a-newname-in-ours-added-in-theirs.txt~rename_conflict_theirs" },
+		{ 0100644, "de872ee3618b894992e9d1e18ba2ebe256a112f9", 0, "4b-newname-in-theirs-added-in-ours.txt~HEAD" },
+		{ 0100644, "98d52d07c0b0bbf2b46548f6aa521295c2cb55db", 0, "4b-newname-in-theirs-added-in-ours.txt~rename_conflict_theirs" },
+		{ 0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436", 0, "5a-newname-in-ours-added-in-theirs.txt~HEAD" },
+		{ 0100644, "98ba4205fcf31f5dd93c916d35fe3f3b3d0e6714", 0, "5a-newname-in-ours-added-in-theirs.txt~rename_conflict_theirs" },
+		{ 0100644, "385c8a0f26ddf79e9041e15e17dc352ed2c4cced", 0, "5b-newname-in-theirs-added-in-ours.txt~HEAD" },
+		{ 0100644, "63247125386de9ec90a27ad36169307bf8a11a38", 0, "5b-newname-in-theirs-added-in-ours.txt~rename_conflict_theirs" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 0, "6-both-renamed-1-to-2-ours.txt" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 0, "6-both-renamed-1-to-2-theirs.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 0, "7-both-renamed.txt~HEAD" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 0, "7-both-renamed.txt~rename_conflict_theirs" },
+	};
+
+	merge_opts.tree_flags |= GIT_MERGE_TREE_FIND_RENAMES;
+	merge_opts.rename_threshold = 50;
+
+	cl_git_pass(merge_branches(repo, GIT_REFS_HEADS_DIR BRANCH_RENAME_OURS, GIT_REFS_HEADS_DIR BRANCH_RENAME_THEIRS, &merge_opts, NULL));
+	cl_assert(merge_test_workdir(repo, merge_index_entries, 24));
+}
+
+void test_merge_workdir_renames__ours(void)
+{
+	git_index *index;
+	git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT;
+	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "68c6c84b091926c7d90aa6a79b2bc3bb6adccd8e", 0, "0a-no-change.txt" },
+		{ 0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6", 0, "0b-duplicated-in-ours.txt" },
+		{ 0100644, "e376fbdd06ebf021c92724da9f26f44212734e3e", 0, "0b-rewritten-in-ours.txt" },
+		{ 0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31", 0, "0c-duplicated-in-theirs.txt" },
+		{ 0100644, "efc9121fdedaf08ba180b53ebfbcf71bd488ed09", 0, "0c-rewritten-in-theirs.txt" },
+		{ 0100644, "0d872f8e871a30208305978ecbf9e66d864f1638", 0, "1a-newname-in-ours-edited-in-theirs.txt" },
+		{ 0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb", 0, "1a-newname-in-ours.txt" },
+		{ 0100644, "ed9523e62e453e50dd9be1606af19399b96e397a", 0, "1b-newname-in-theirs-edited-in-ours.txt" },
+		{ 0100644, "2b5f1f181ee3b58ea751f5dd5d8f9b445520a136", 0, "1b-newname-in-theirs.txt" },
+		{ 0100644, "178940b450f238a56c0d75b7955cb57b38191982", 0, "2-newname-in-both.txt" },
+		{ 0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9", 0, "3a-newname-in-ours-deleted-in-theirs.txt" },
+		{ 0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495", 0, "3b-newname-in-theirs-deleted-in-ours.txt" },
+		{ 0100644, "227792b52aaa0b238bea00ec7e509b02623f168c", 0, "4a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "de872ee3618b894992e9d1e18ba2ebe256a112f9", 0, "4b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436", 0, "5a-newname-in-ours-added-in-theirs.txt" },
+		{ 0100644, "385c8a0f26ddf79e9041e15e17dc352ed2c4cced", 0, "5b-newname-in-theirs-added-in-ours.txt" },
+		{ 0100644, "63247125386de9ec90a27ad36169307bf8a11a38", 0, "5b-renamed-in-theirs-added-in-ours.txt" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 0, "6-both-renamed-1-to-2-ours.txt" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 0, "7-both-renamed-side-2.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 0, "7-both-renamed.txt" },
+	};
+
+	merge_opts.tree_flags |= GIT_MERGE_TREE_FIND_RENAMES;
+	merge_opts.rename_threshold = 50;
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_USE_OURS;
+
+	cl_git_pass(merge_branches(repo, GIT_REFS_HEADS_DIR BRANCH_RENAME_OURS, GIT_REFS_HEADS_DIR BRANCH_RENAME_THEIRS, &merge_opts, &checkout_opts));
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_write(index));
+	cl_assert(merge_test_workdir(repo, merge_index_entries, 20));
+
+	git_index_free(index);
+}
+
+void test_merge_workdir_renames__similar(void)
+{
+	git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT;
+
+	/*
+	 * Note: this differs slightly from the core git merge result - there, 4a is
+	 * tracked as a rename/delete instead of a rename/add and the theirs side
+	 * is not placed in workdir in any form.
+	 */
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "68c6c84b091926c7d90aa6a79b2bc3bb6adccd8e", 0, "0a-no-change.txt" },
+		{ 0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6", 0, "0b-duplicated-in-ours.txt" },
+		{ 0100644, "8aac75de2a34b4d340bf62a6e58197269cb55797", 0, "0b-rewritten-in-ours.txt" },
+		{ 0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31", 0, "0c-duplicated-in-theirs.txt" },
+		{ 0100644, "7edc726325da726751a4195e434e4377b0f67f9a", 0, "0c-rewritten-in-theirs.txt" },
+		{ 0100644, "0d872f8e871a30208305978ecbf9e66d864f1638", 0, "1a-newname-in-ours-edited-in-theirs.txt" },
+		{ 0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb", 0, "1a-newname-in-ours.txt" },
+		{ 0100644, "ed9523e62e453e50dd9be1606af19399b96e397a", 0, "1b-newname-in-theirs-edited-in-ours.txt" },
+		{ 0100644, "2b5f1f181ee3b58ea751f5dd5d8f9b445520a136", 0, "1b-newname-in-theirs.txt" },
+		{ 0100644, "178940b450f238a56c0d75b7955cb57b38191982", 0, "2-newname-in-both.txt" },
+		{ 0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9", 0, "3a-newname-in-ours-deleted-in-theirs.txt" },
+		{ 0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495", 0, "3b-newname-in-theirs-deleted-in-ours.txt" },
+		{ 0100644, "227792b52aaa0b238bea00ec7e509b02623f168c", 0, "4a-newname-in-ours-added-in-theirs.txt~HEAD" },
+		{ 0100644, "8b5b53cb2aa9ceb1139f5312fcfa3cc3c5a47c9a", 0, "4a-newname-in-ours-added-in-theirs.txt~rename_conflict_theirs" },
+		{ 0100644, "de872ee3618b894992e9d1e18ba2ebe256a112f9", 0, "4b-newname-in-theirs-added-in-ours.txt~HEAD" },
+		{ 0100644, "98d52d07c0b0bbf2b46548f6aa521295c2cb55db", 0, "4b-newname-in-theirs-added-in-ours.txt~rename_conflict_theirs" },
+		{ 0100644, "d3719a5ae8e4d92276b5313ce976f6ee5af2b436", 0, "5a-newname-in-ours-added-in-theirs.txt~HEAD" },
+		{ 0100644, "98ba4205fcf31f5dd93c916d35fe3f3b3d0e6714", 0, "5a-newname-in-ours-added-in-theirs.txt~rename_conflict_theirs" },
+		{ 0100644, "385c8a0f26ddf79e9041e15e17dc352ed2c4cced", 0, "5b-newname-in-theirs-added-in-ours.txt~HEAD" },
+		{ 0100644, "63247125386de9ec90a27ad36169307bf8a11a38", 0, "5b-newname-in-theirs-added-in-ours.txt~rename_conflict_theirs" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 0, "6-both-renamed-1-to-2-ours.txt" },
+		{ 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 0, "6-both-renamed-1-to-2-theirs.txt" },
+		{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 0, "7-both-renamed.txt~HEAD" },
+		{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 0, "7-both-renamed.txt~rename_conflict_theirs" },
+	};
+
+	merge_opts.tree_flags |= GIT_MERGE_TREE_FIND_RENAMES;
+	merge_opts.rename_threshold = 50;
+
+	cl_git_pass(merge_branches(repo, GIT_REFS_HEADS_DIR BRANCH_RENAME_OURS, GIT_REFS_HEADS_DIR BRANCH_RENAME_THEIRS, &merge_opts, NULL));
+	cl_assert(merge_test_workdir(repo, merge_index_entries, 24));
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/setup.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/setup.c
new file mode 100755
index 0000000..4aebf87
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/setup.c
@@ -0,0 +1,1096 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/merge.h"
+#include "merge.h"
+#include "refs.h"
+#include "fileops.h"
+
+static git_repository *repo;
+static git_index *repo_index;
+
+#define TEST_REPO_PATH		"merge-resolve"
+#define TEST_INDEX_PATH TEST_REPO_PATH	"/.git/index"
+
+#define ORIG_HEAD			"bd593285fc7fe4ca18ccdbabf027f5d689101452"
+
+#define THEIRS_SIMPLE_BRANCH	"branch"
+#define THEIRS_SIMPLE_OID	"7cb63eed597130ba4abb87b3e544b85021905520"
+
+#define OCTO1_BRANCH		"octo1"
+#define OCTO1_OID			"16f825815cfd20a07a75c71554e82d8eede0b061"
+
+#define OCTO2_BRANCH		"octo2"
+#define OCTO2_OID			"158dc7bedb202f5b26502bf3574faa7f4238d56c"
+
+#define OCTO3_BRANCH		"octo3"
+#define OCTO3_OID			"50ce7d7d01217679e26c55939eef119e0c93e272"
+
+#define OCTO4_BRANCH		"octo4"
+#define OCTO4_OID			"54269b3f6ec3d7d4ede24dd350dd5d605495c3ae"
+
+#define OCTO5_BRANCH		"octo5"
+#define OCTO5_OID			"e4f618a2c3ed0669308735727df5ebf2447f022f"
+
+// Fixture setup and teardown
+void test_merge_workdir_setup__initialize(void)
+{
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+	git_repository_index(&repo_index, repo);
+}
+
+void test_merge_workdir_setup__cleanup(void)
+{
+	git_index_free(repo_index);
+	cl_git_sandbox_cleanup();
+}
+
+static bool test_file_contents(const char *filename, const char *expected)
+{
+	git_buf file_path_buf = GIT_BUF_INIT, file_buf = GIT_BUF_INIT;
+	bool equals;
+	
+	git_buf_printf(&file_path_buf, "%s/%s", git_repository_path(repo), filename);
+	
+	cl_git_pass(git_futils_readbuffer(&file_buf, file_path_buf.ptr));
+	equals = (strcmp(file_buf.ptr, expected) == 0);
+
+	git_buf_free(&file_path_buf);
+	git_buf_free(&file_buf);
+	
+	return equals;
+}
+
+static void write_file_contents(const char *filename, const char *output)
+{
+	git_buf file_path_buf = GIT_BUF_INIT;
+
+	git_buf_printf(&file_path_buf, "%s/%s", git_repository_path(repo),
+		filename);
+	cl_git_rewritefile(file_path_buf.ptr, output);
+
+	git_buf_free(&file_path_buf);
+}
+
+/* git merge --no-ff octo1 */
+void test_merge_workdir_setup__one_branch(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_ref;
+	git_annotated_commit *our_head, *their_heads[1];
+	
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+	
+	cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref));
+	
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 1));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO1_BRANCH "'\n"));
+
+	git_reference_free(octo1_ref);
+	
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+}
+
+/* git merge --no-ff 16f825815cfd20a07a75c71554e82d8eede0b061 */
+void test_merge_workdir_setup__one_oid(void)
+{
+	git_oid our_oid;
+	git_oid octo1_oid;
+	git_annotated_commit *our_head, *their_heads[1];
+	
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+	
+	cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_oid));
+
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 1));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge commit '" OCTO1_OID "'\n"));
+
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+}
+
+/* git merge octo1 octo2 */
+void test_merge_workdir_setup__two_branches(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_ref;
+	git_reference *octo2_ref;
+	git_annotated_commit *our_head, *their_heads[2];
+	
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+	
+	cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref));
+
+	cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref));
+
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2));
+	
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "' and '" OCTO2_BRANCH "'\n"));
+	
+	git_reference_free(octo1_ref);
+	git_reference_free(octo2_ref);
+	
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+}
+
+/* git merge octo1 octo2 octo3 */
+void test_merge_workdir_setup__three_branches(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_ref;
+	git_reference *octo2_ref;
+	git_reference *octo3_ref;
+	git_annotated_commit *our_head, *their_heads[3];
+	
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref));
+	
+	cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref));
+
+	cl_git_pass(git_reference_lookup(&octo3_ref, repo, GIT_REFS_HEADS_DIR OCTO3_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[2], repo, octo3_ref));
+
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 3));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "', '" OCTO2_BRANCH "' and '" OCTO3_BRANCH "'\n"));
+	
+	git_reference_free(octo1_ref);
+	git_reference_free(octo2_ref);
+	git_reference_free(octo3_ref);
+
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+	git_annotated_commit_free(their_heads[2]);
+}
+
+/* git merge 16f825815cfd20a07a75c71554e82d8eede0b061 158dc7bedb202f5b26502bf3574faa7f4238d56c 50ce7d7d01217679e26c55939eef119e0c93e272 */
+void test_merge_workdir_setup__three_oids(void)
+{
+	git_oid our_oid;
+	git_oid octo1_oid;
+	git_oid octo2_oid;
+	git_oid octo3_oid;
+	git_annotated_commit *our_head, *their_heads[3];
+	
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_oid));
+	
+	cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[1], repo, &octo2_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[2], repo, &octo3_oid));
+
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 3));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge commit '" OCTO1_OID "'; commit '" OCTO2_OID "'; commit '" OCTO3_OID "'\n"));
+	
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+	git_annotated_commit_free(their_heads[2]);
+}
+
+/* git merge octo1 158dc7bedb202f5b26502bf3574faa7f4238d56c */
+void test_merge_workdir_setup__branches_and_oids_1(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_ref;
+	git_oid octo2_oid;
+	git_annotated_commit *our_head, *their_heads[2];
+	
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref));
+
+	cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[1], repo, &octo2_oid));
+
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO1_BRANCH "'; commit '" OCTO2_OID "'\n"));
+	
+	git_reference_free(octo1_ref);
+
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+}
+
+/* git merge octo1 158dc7bedb202f5b26502bf3574faa7f4238d56c octo3 54269b3f6ec3d7d4ede24dd350dd5d605495c3ae */
+void test_merge_workdir_setup__branches_and_oids_2(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_ref;
+	git_oid octo2_oid;
+	git_reference *octo3_ref;
+	git_oid octo4_oid;
+	git_annotated_commit *our_head, *their_heads[4];
+
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref));
+	
+	cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[1], repo, &octo2_oid));
+
+	cl_git_pass(git_reference_lookup(&octo3_ref, repo, GIT_REFS_HEADS_DIR OCTO3_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[2], repo, octo3_ref));
+	
+	cl_git_pass(git_oid_fromstr(&octo4_oid, OCTO4_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[3], repo, &octo4_oid));
+	
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 4));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n" OCTO4_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "' and '" OCTO3_BRANCH "'; commit '" OCTO2_OID "'; commit '" OCTO4_OID "'\n"));
+	
+	git_reference_free(octo1_ref);
+	git_reference_free(octo3_ref);
+
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+	git_annotated_commit_free(their_heads[2]);
+	git_annotated_commit_free(their_heads[3]);
+}
+
+/* git merge 16f825815cfd20a07a75c71554e82d8eede0b061 octo2 50ce7d7d01217679e26c55939eef119e0c93e272 octo4 */
+void test_merge_workdir_setup__branches_and_oids_3(void)
+{
+	git_oid our_oid;
+	git_oid octo1_oid;
+	git_reference *octo2_ref;
+	git_oid octo3_oid;
+	git_reference *octo4_ref;
+	git_annotated_commit *our_head, *their_heads[4];
+	
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_oid));
+
+	cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref));
+
+	cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[2], repo, &octo3_oid));
+	
+	cl_git_pass(git_reference_lookup(&octo4_ref, repo, GIT_REFS_HEADS_DIR OCTO4_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[3], repo, octo4_ref));
+	
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 4));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n" OCTO4_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge commit '" OCTO1_OID "'; branches '" OCTO2_BRANCH "' and '" OCTO4_BRANCH "'; commit '" OCTO3_OID "'\n"));
+	
+	git_reference_free(octo2_ref);
+	git_reference_free(octo4_ref);
+
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+	git_annotated_commit_free(their_heads[2]);
+	git_annotated_commit_free(their_heads[3]);
+}
+
+/* git merge 16f825815cfd20a07a75c71554e82d8eede0b061 octo2 50ce7d7d01217679e26c55939eef119e0c93e272 octo4 octo5 */
+void test_merge_workdir_setup__branches_and_oids_4(void)
+{
+	git_oid our_oid;
+	git_oid octo1_oid;
+	git_reference *octo2_ref;
+	git_oid octo3_oid;
+	git_reference *octo4_ref;
+	git_reference *octo5_ref;
+	git_annotated_commit *our_head, *their_heads[5];
+	
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+	
+	cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_oid));
+	
+	cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref));
+	
+	cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[2], repo, &octo3_oid));
+	
+	cl_git_pass(git_reference_lookup(&octo4_ref, repo, GIT_REFS_HEADS_DIR OCTO4_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[3], repo, octo4_ref));
+
+	cl_git_pass(git_reference_lookup(&octo5_ref, repo, GIT_REFS_HEADS_DIR OCTO5_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[4], repo, octo5_ref));
+
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 5));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n" OCTO4_OID "\n" OCTO5_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge commit '" OCTO1_OID "'; branches '" OCTO2_BRANCH "', '" OCTO4_BRANCH "' and '" OCTO5_BRANCH "'; commit '" OCTO3_OID "'\n"));
+	
+	git_reference_free(octo2_ref);
+	git_reference_free(octo4_ref);
+	git_reference_free(octo5_ref);
+
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+	git_annotated_commit_free(their_heads[2]);
+	git_annotated_commit_free(their_heads[3]);
+	git_annotated_commit_free(their_heads[4]);
+}
+
+/* git merge octo1 octo1 octo1 */
+void test_merge_workdir_setup__three_same_branches(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_1_ref;
+	git_reference *octo1_2_ref;
+	git_reference *octo1_3_ref;
+	git_annotated_commit *our_head, *their_heads[3];
+	
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+	
+	cl_git_pass(git_reference_lookup(&octo1_1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_1_ref));
+	
+	cl_git_pass(git_reference_lookup(&octo1_2_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo1_2_ref));
+	
+	cl_git_pass(git_reference_lookup(&octo1_3_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[2], repo, octo1_3_ref));
+	
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 3));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO1_OID "\n" OCTO1_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "', '" OCTO1_BRANCH "' and '" OCTO1_BRANCH "'\n"));
+	
+	git_reference_free(octo1_1_ref);
+	git_reference_free(octo1_2_ref);
+	git_reference_free(octo1_3_ref);
+	
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+	git_annotated_commit_free(their_heads[2]);
+}
+
+/* git merge 16f825815cfd20a07a75c71554e82d8eede0b061 16f825815cfd20a07a75c71554e82d8eede0b061 16f825815cfd20a07a75c71554e82d8eede0b061 */
+void test_merge_workdir_setup__three_same_oids(void)
+{
+	git_oid our_oid;
+	git_oid octo1_1_oid;
+	git_oid octo1_2_oid;
+	git_oid octo1_3_oid;
+	git_annotated_commit *our_head, *their_heads[3];
+	
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+	
+	cl_git_pass(git_oid_fromstr(&octo1_1_oid, OCTO1_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_1_oid));
+	
+	cl_git_pass(git_oid_fromstr(&octo1_2_oid, OCTO1_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[1], repo, &octo1_2_oid));
+	
+	cl_git_pass(git_oid_fromstr(&octo1_3_oid, OCTO1_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[2], repo, &octo1_3_oid));
+	
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 3));
+	
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO1_OID "\n" OCTO1_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge commit '" OCTO1_OID "'; commit '" OCTO1_OID "'; commit '" OCTO1_OID "'\n"));
+	
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+	git_annotated_commit_free(their_heads[2]);
+}
+
+static int create_remote_tracking_branch(const char *branch_name, const char *oid_str)
+{
+	int error = 0;
+
+	git_buf remotes_path = GIT_BUF_INIT,
+		origin_path = GIT_BUF_INIT,
+		filename = GIT_BUF_INIT,
+		data = GIT_BUF_INIT;
+
+	if ((error = git_buf_puts(&remotes_path, git_repository_path(repo))) < 0 ||
+		(error = git_buf_puts(&remotes_path, GIT_REFS_REMOTES_DIR)) < 0)
+		goto done;
+
+	if (!git_path_exists(git_buf_cstr(&remotes_path)) &&
+		(error = p_mkdir(git_buf_cstr(&remotes_path), 0777)) < 0)
+		goto done;
+
+	if ((error = git_buf_puts(&origin_path, git_buf_cstr(&remotes_path))) < 0 ||
+		(error = git_buf_puts(&origin_path, "origin")) < 0)
+		goto done;
+
+	if (!git_path_exists(git_buf_cstr(&origin_path)) &&
+		(error = p_mkdir(git_buf_cstr(&origin_path), 0777)) < 0)
+		goto done;
+
+	if ((error = git_buf_puts(&filename, git_buf_cstr(&origin_path))) < 0 ||
+		(error = git_buf_puts(&filename, "/")) < 0 ||
+		(error = git_buf_puts(&filename, branch_name)) < 0 ||
+		(error = git_buf_puts(&data, oid_str)) < 0 ||
+		(error = git_buf_puts(&data, "\n")) < 0)
+		goto done;
+
+	cl_git_rewritefile(git_buf_cstr(&filename), git_buf_cstr(&data));
+
+done:
+	git_buf_free(&remotes_path);
+	git_buf_free(&origin_path);
+	git_buf_free(&filename);
+	git_buf_free(&data);
+
+	return error;
+}
+
+/* git merge refs/remotes/origin/octo1 */
+void test_merge_workdir_setup__remote_tracking_one_branch(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_ref;
+	git_annotated_commit *our_head, *their_heads[1];
+
+	cl_git_pass(create_remote_tracking_branch(OCTO1_BRANCH, OCTO1_OID));
+
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+	
+	cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref));
+	
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 1));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge remote-tracking branch 'refs/remotes/origin/" OCTO1_BRANCH "'\n"));
+
+	git_reference_free(octo1_ref);
+	
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+}
+
+/* git merge refs/remotes/origin/octo1 refs/remotes/origin/octo2 */
+void test_merge_workdir_setup__remote_tracking_two_branches(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_ref;
+	git_reference *octo2_ref;
+	git_annotated_commit *our_head, *their_heads[2];
+
+	cl_git_pass(create_remote_tracking_branch(OCTO1_BRANCH, OCTO1_OID));
+	cl_git_pass(create_remote_tracking_branch(OCTO2_BRANCH, OCTO2_OID));
+
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+	
+	cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref));
+
+	cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO2_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref));
+
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2));
+	
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge remote-tracking branches 'refs/remotes/origin/" OCTO1_BRANCH "' and 'refs/remotes/origin/" OCTO2_BRANCH "'\n"));
+	
+	git_reference_free(octo1_ref);
+	git_reference_free(octo2_ref);
+	
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+}
+
+/* git merge refs/remotes/origin/octo1 refs/remotes/origin/octo2 refs/remotes/origin/octo3 */
+void test_merge_workdir_setup__remote_tracking_three_branches(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_ref;
+	git_reference *octo2_ref;
+	git_reference *octo3_ref;
+	git_annotated_commit *our_head, *their_heads[3];
+
+	cl_git_pass(create_remote_tracking_branch(OCTO1_BRANCH, OCTO1_OID));
+	cl_git_pass(create_remote_tracking_branch(OCTO2_BRANCH, OCTO2_OID));
+	cl_git_pass(create_remote_tracking_branch(OCTO3_BRANCH, OCTO3_OID));
+	
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref));
+	
+	cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO2_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref));
+
+	cl_git_pass(git_reference_lookup(&octo3_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO3_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[2], repo, octo3_ref));
+
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 3));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge remote-tracking branches 'refs/remotes/origin/" OCTO1_BRANCH "', 'refs/remotes/origin/" OCTO2_BRANCH "' and 'refs/remotes/origin/" OCTO3_BRANCH "'\n"));
+	
+	git_reference_free(octo1_ref);
+	git_reference_free(octo2_ref);
+	git_reference_free(octo3_ref);
+
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+	git_annotated_commit_free(their_heads[2]);
+}
+
+/* git merge octo1 refs/remotes/origin/octo2 */
+void test_merge_workdir_setup__normal_branch_and_remote_tracking_branch(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_ref;
+	git_reference *octo2_ref;
+	git_annotated_commit *our_head, *their_heads[2];
+
+	cl_git_pass(create_remote_tracking_branch(OCTO2_BRANCH, OCTO2_OID));
+
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref));
+
+	cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO2_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref));
+
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2));
+	
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO1_BRANCH "', remote-tracking branch 'refs/remotes/origin/" OCTO2_BRANCH "'\n"));
+	
+	git_reference_free(octo1_ref);
+	git_reference_free(octo2_ref);
+	
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+}
+
+/* git merge refs/remotes/origin/octo1 octo2 */
+void test_merge_workdir_setup__remote_tracking_branch_and_normal_branch(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_ref;
+	git_reference *octo2_ref;
+	git_annotated_commit *our_head, *their_heads[2];
+
+	cl_git_pass(create_remote_tracking_branch(OCTO1_BRANCH, OCTO1_OID));
+
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+	
+	cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref));
+
+	cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref));
+
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2));
+	
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO2_BRANCH "', remote-tracking branch 'refs/remotes/origin/" OCTO1_BRANCH "'\n"));
+	
+	git_reference_free(octo1_ref);
+	git_reference_free(octo2_ref);
+	
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+}
+
+/* git merge octo1 refs/remotes/origin/octo2 octo3 refs/remotes/origin/octo4 */
+void test_merge_workdir_setup__two_remote_tracking_branch_and_two_normal_branches(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_ref;
+	git_reference *octo2_ref;
+	git_reference *octo3_ref;
+	git_reference *octo4_ref;
+	git_annotated_commit *our_head, *their_heads[4];
+
+	cl_git_pass(create_remote_tracking_branch(OCTO2_BRANCH, OCTO2_OID));
+	cl_git_pass(create_remote_tracking_branch(OCTO4_BRANCH, OCTO4_OID));
+
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+	
+	cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref));
+
+	cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO2_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref));
+
+	cl_git_pass(git_reference_lookup(&octo3_ref, repo, GIT_REFS_HEADS_DIR OCTO3_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[2], repo, octo3_ref));
+
+	cl_git_pass(git_reference_lookup(&octo4_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO4_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[3], repo, octo4_ref));
+
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 4));
+	
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n" OCTO4_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "' and '" OCTO3_BRANCH "', remote-tracking branches 'refs/remotes/origin/" OCTO2_BRANCH "' and 'refs/remotes/origin/" OCTO4_BRANCH "'\n"));
+	
+	git_reference_free(octo1_ref);
+	git_reference_free(octo2_ref);
+	git_reference_free(octo3_ref);
+	git_reference_free(octo4_ref);
+	
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+	git_annotated_commit_free(their_heads[2]);
+	git_annotated_commit_free(their_heads[3]);
+}
+
+/* git pull origin branch octo1 */
+void test_merge_workdir_setup__pull_one(void)
+{
+	git_oid our_oid;
+	git_oid octo1_1_oid;
+	git_annotated_commit *our_head, *their_heads[1];
+
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo1_1_oid, OCTO1_OID));
+	cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[0], repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH, "http://remote.url/repo.git", &octo1_1_oid));
+	
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 1));
+	
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch 'octo1' of http://remote.url/repo.git\n"));
+	
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+}
+
+/* git pull origin octo1 octo2 */
+void test_merge_workdir_setup__pull_two(void)
+{
+	git_oid our_oid;
+	git_oid octo1_oid;
+	git_oid octo2_oid;
+	git_annotated_commit *our_head, *their_heads[2];
+	
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID));
+	cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[0], repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH, "http://remote.url/repo.git", &octo1_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID));
+	cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[1], repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH, "http://remote.url/repo.git", &octo2_oid));
+
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "' and '" OCTO2_BRANCH "' of http://remote.url/repo.git\n"));
+	
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+}
+
+/* git pull origin octo1 octo2 octo3 */
+void test_merge_workdir_setup__pull_three(void)
+{
+	git_oid our_oid;
+	git_oid octo1_oid;
+	git_oid octo2_oid;
+	git_oid octo3_oid;
+	git_annotated_commit *our_head, *their_heads[3];
+	
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID));
+	cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[0], repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH, "http://remote.url/repo.git", &octo1_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID));
+	cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[1], repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH, "http://remote.url/repo.git", &octo2_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID));
+	cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[2], repo, GIT_REFS_HEADS_DIR OCTO3_BRANCH, "http://remote.url/repo.git", &octo3_oid));
+
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 3));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "', '" OCTO2_BRANCH "' and '" OCTO3_BRANCH "' of http://remote.url/repo.git\n"));
+	
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+	git_annotated_commit_free(their_heads[2]);
+}
+
+void test_merge_workdir_setup__three_remotes(void)
+{
+	git_oid our_oid;
+	git_oid octo1_oid;
+	git_oid octo2_oid;
+	git_oid octo3_oid;
+	git_annotated_commit *our_head, *their_heads[3];
+	
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID));
+	cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[0], repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH, "http://remote.first/repo.git", &octo1_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID));
+	cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[1], repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH, "http://remote.second/repo.git", &octo2_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID));
+	cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[2], repo, GIT_REFS_HEADS_DIR OCTO3_BRANCH, "http://remote.third/repo.git", &octo3_oid));
+
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 3));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO1_BRANCH "' of http://remote.first/repo.git, branch '" OCTO2_BRANCH "' of http://remote.second/repo.git, branch '" OCTO3_BRANCH "' of http://remote.third/repo.git\n"));
+	
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+	git_annotated_commit_free(their_heads[2]);
+}
+
+void test_merge_workdir_setup__two_remotes(void)
+{
+	git_oid our_oid;
+	git_oid octo1_oid;
+	git_oid octo2_oid;
+	git_oid octo3_oid;
+	git_oid octo4_oid;
+	git_annotated_commit *our_head, *their_heads[4];
+	
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID));
+	cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[0], repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH, "http://remote.first/repo.git", &octo1_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID));
+	cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[1], repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH, "http://remote.second/repo.git", &octo2_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID));
+	cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[2], repo, GIT_REFS_HEADS_DIR OCTO3_BRANCH, "http://remote.first/repo.git", &octo3_oid));
+
+	cl_git_pass(git_oid_fromstr(&octo4_oid, OCTO4_OID));
+	cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[3], repo, GIT_REFS_HEADS_DIR OCTO4_BRANCH, "http://remote.second/repo.git", &octo4_oid));
+
+	cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 4));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n" OCTO4_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "' and '" OCTO3_BRANCH "' of http://remote.first/repo.git, branches '" OCTO2_BRANCH "' and '" OCTO4_BRANCH "' of http://remote.second/repo.git\n"));
+	
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+	git_annotated_commit_free(their_heads[1]);
+	git_annotated_commit_free(their_heads[2]);
+	git_annotated_commit_free(their_heads[3]);
+}
+
+void test_merge_workdir_setup__id_from_head(void)
+{
+	git_oid expected_id;
+	const git_oid *id;
+	git_reference *ref;
+	git_annotated_commit *heads[3];
+
+	cl_git_pass(git_oid_fromstr(&expected_id, OCTO1_OID));
+	cl_git_pass(git_annotated_commit_from_fetchhead(&heads[0], repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH, "http://remote.url/repo.git", &expected_id));
+	id = git_annotated_commit_id(heads[0]);
+	cl_assert_equal_i(1, git_oid_equal(id, &expected_id));
+
+	cl_git_pass(git_annotated_commit_lookup(&heads[1], repo, &expected_id));
+	id = git_annotated_commit_id(heads[1]);
+	cl_assert_equal_i(1, git_oid_equal(id, &expected_id));
+
+	cl_git_pass(git_reference_lookup(&ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&heads[2], repo, ref));
+	id = git_annotated_commit_id(heads[2]);
+	cl_assert_equal_i(1, git_oid_equal(id, &expected_id));
+
+	git_reference_free(ref);
+	git_annotated_commit_free(heads[0]);
+	git_annotated_commit_free(heads[1]);
+	git_annotated_commit_free(heads[2]);
+}
+
+struct annotated_commit_cb_data {
+	const char **oid_str;
+	unsigned int len;
+
+	unsigned int i;
+};
+
+static int annotated_commit_foreach_cb(const git_oid *oid, void *payload)
+{
+	git_oid expected_oid;
+	struct annotated_commit_cb_data *cb_data = payload;
+
+	git_oid_fromstr(&expected_oid, cb_data->oid_str[cb_data->i]);
+	cl_assert(git_oid_cmp(&expected_oid, oid) == 0);
+	cb_data->i++;
+	return 0;
+}
+
+void test_merge_workdir_setup__head_notfound(void)
+{
+	int error;
+
+	cl_git_fail((error = git_repository_mergehead_foreach(repo,
+		annotated_commit_foreach_cb, NULL)));
+	cl_assert(error == GIT_ENOTFOUND);
+}
+
+void test_merge_workdir_setup__head_invalid_oid(void)
+{
+	int error;
+
+	write_file_contents(GIT_MERGE_HEAD_FILE, "invalid-oid\n");
+
+	cl_git_fail((error = git_repository_mergehead_foreach(repo,
+		annotated_commit_foreach_cb, NULL)));
+	cl_assert(error == -1);
+}
+
+void test_merge_workdir_setup__head_foreach_nonewline(void)
+{
+	int error;
+
+	write_file_contents(GIT_MERGE_HEAD_FILE, THEIRS_SIMPLE_OID);
+
+	cl_git_fail((error = git_repository_mergehead_foreach(repo,
+		annotated_commit_foreach_cb, NULL)));
+	cl_assert(error == -1);
+}
+
+void test_merge_workdir_setup__head_foreach_one(void)
+{
+	const char *expected = THEIRS_SIMPLE_OID;
+
+	struct annotated_commit_cb_data cb_data = { &expected, 1 };
+
+	write_file_contents(GIT_MERGE_HEAD_FILE, THEIRS_SIMPLE_OID "\n");
+
+	cl_git_pass(git_repository_mergehead_foreach(repo,
+		annotated_commit_foreach_cb, &cb_data));
+
+	cl_assert(cb_data.i == cb_data.len);
+}
+
+void test_merge_workdir_setup__head_foreach_octopus(void)
+{
+	const char *expected[] = { THEIRS_SIMPLE_OID,
+		OCTO1_OID, OCTO2_OID, OCTO3_OID, OCTO4_OID, OCTO5_OID };
+
+	struct annotated_commit_cb_data cb_data = { expected, 6 };
+
+	write_file_contents(GIT_MERGE_HEAD_FILE,
+		THEIRS_SIMPLE_OID "\n"
+		OCTO1_OID "\n"
+		OCTO2_OID "\n"
+		OCTO3_OID "\n"
+		OCTO4_OID "\n"
+		OCTO5_OID "\n");
+
+	cl_git_pass(git_repository_mergehead_foreach(repo,
+		annotated_commit_foreach_cb, &cb_data));
+
+	cl_assert(cb_data.i == cb_data.len);
+}
+
+void test_merge_workdir_setup__retained_after_success(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_ref;
+	git_annotated_commit *our_head, *their_heads[1];
+
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH));
+
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref));
+
+	cl_git_pass(git_merge(repo, (const git_annotated_commit **)&their_heads[0], 1, NULL, NULL));
+
+	cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n"));
+	cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n"));
+	cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff"));
+	cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO1_BRANCH "'\n"));
+
+	git_reference_free(octo1_ref);
+
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+}
+
+
+void test_merge_workdir_setup__removed_after_failure(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_ref;
+	git_annotated_commit *our_head, *their_heads[1];
+
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref));
+
+	cl_git_write2file("merge-resolve/.git/index.lock", "foo\n", 4, O_RDWR|O_CREAT, 0666);
+
+	cl_git_fail(git_merge(
+		repo, (const git_annotated_commit **)&their_heads[0], 1, NULL, NULL));
+
+	cl_assert(!git_path_exists("merge-resolve/.git/" GIT_MERGE_HEAD_FILE));
+	cl_assert(!git_path_exists("merge-resolve/.git/" GIT_MERGE_MODE_FILE));
+	cl_assert(!git_path_exists("merge-resolve/.git/" GIT_MERGE_MSG_FILE));
+
+	git_reference_free(octo1_ref);
+
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+}
+
+void test_merge_workdir_setup__unlocked_after_success(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_ref;
+	git_annotated_commit *our_head, *their_heads[1];
+
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref));
+
+	cl_git_pass(git_merge(
+		repo, (const git_annotated_commit **)&their_heads[0], 1, NULL, NULL));
+
+	cl_assert(!git_path_exists("merge-resolve/.git/index.lock"));
+
+	git_reference_free(octo1_ref);
+
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+}
+
+void test_merge_workdir_setup__unlocked_after_conflict(void)
+{
+	git_oid our_oid;
+	git_reference *octo1_ref;
+	git_annotated_commit *our_head, *their_heads[1];
+
+	cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD));
+	cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid));
+
+	cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref));
+
+	cl_git_rewritefile("merge-resolve/new-in-octo1.txt",
+		"Conflicting file!\n\nMerge will fail!\n");
+
+	cl_git_fail(git_merge(
+		repo, (const git_annotated_commit **)&their_heads[0], 1, NULL, NULL));
+
+	cl_assert(!git_path_exists("merge-resolve/.git/index.lock"));
+
+	git_reference_free(octo1_ref);
+
+	git_annotated_commit_free(our_head);
+	git_annotated_commit_free(their_heads[0]);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/simple.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/simple.c
new file mode 100755
index 0000000..abc0777
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/simple.c
@@ -0,0 +1,635 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/merge.h"
+#include "buffer.h"
+#include "merge.h"
+#include "../merge_helpers.h"
+#include "refs.h"
+#include "fileops.h"
+
+static git_repository *repo;
+static git_index *repo_index;
+
+#define TEST_REPO_PATH "merge-resolve"
+#define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index"
+
+#define THEIRS_SIMPLE_BRANCH		"branch"
+#define THEIRS_SIMPLE_OID			"7cb63eed597130ba4abb87b3e544b85021905520"
+
+#define THEIRS_UNRELATED_BRANCH		"unrelated"
+#define THEIRS_UNRELATED_OID		"55b4e4687e7a0d9ca367016ed930f385d4022e6f"
+#define THEIRS_UNRELATED_PARENT		"d6cf6c7741b3316826af1314042550c97ded1d50"
+
+#define OURS_DIRECTORY_FILE			"df_side1"
+#define THEIRS_DIRECTORY_FILE		"fc90237dc4891fa6c69827fc465632225e391618"
+
+
+/* Non-conflicting files, index entries are common to every merge operation */
+#define ADDED_IN_MASTER_INDEX_ENTRY	\
+	{ 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0, \
+	  "added-in-master.txt" }
+#define AUTOMERGEABLE_INDEX_ENTRY \
+	{ 0100644, "f2e1550a0c9e53d5811175864a29536642ae3821", 0, \
+	  "automergeable.txt" }
+#define CHANGED_IN_BRANCH_INDEX_ENTRY \
+	{ 0100644, "4eb04c9e79e88f6640d01ff5b25ca2a60764f216", 0, \
+	  "changed-in-branch.txt" }
+#define CHANGED_IN_MASTER_INDEX_ENTRY \
+	{ 0100644, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", 0, \
+	  "changed-in-master.txt" }
+#define UNCHANGED_INDEX_ENTRY \
+	{ 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0, \
+	  "unchanged.txt" }
+
+/* Unrelated files */
+#define UNRELATED_NEW1 \
+	{ 0100644, "ef58fdd8086c243bdc81f99e379acacfd21d32d6", 0, \
+	  "new-in-unrelated1.txt" }
+#define UNRELATED_NEW2 \
+	{ 0100644, "948ba6e701c1edab0c2d394fb7c5538334129793", 0, \
+	  "new-in-unrelated2.txt" }
+
+/* Expected REUC entries */
+#define AUTOMERGEABLE_REUC_ENTRY \
+	{ "automergeable.txt", 0100644, 0100644, 0100644, \
+	  "6212c31dab5e482247d7977e4f0dd3601decf13b", \
+	  "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", \
+	  "058541fc37114bfc1dddf6bd6bffc7fae5c2e6fe" }
+#define CONFLICTING_REUC_ENTRY \
+	{ "conflicting.txt", 0100644, 0100644, 0100644, \
+	  "d427e0b2e138501a3d15cc376077a3631e15bd46", \
+	  "4e886e602529caa9ab11d71f86634bd1b6e0de10", \
+	  "2bd0a343aeef7a2cf0d158478966a6e587ff3863" }
+#define REMOVED_IN_BRANCH_REUC_ENTRY \
+	{ "removed-in-branch.txt", 0100644, 0100644, 0, \
+	  "dfe3f22baa1f6fce5447901c3086bae368de6bdd", \
+	  "dfe3f22baa1f6fce5447901c3086bae368de6bdd", \
+	  "" }
+#define REMOVED_IN_MASTER_REUC_ENTRY \
+	{ "removed-in-master.txt", 0100644, 0, 0100644, \
+	  "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5", \
+	  "", \
+	  "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5" }
+
+
+// Fixture setup and teardown
+void test_merge_workdir_simple__initialize(void)
+{
+	git_config *cfg;
+
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+	git_repository_index(&repo_index, repo);
+
+	/* Ensure that the user's merge.conflictstyle doesn't interfere */
+	cl_git_pass(git_repository_config(&cfg, repo));
+	cl_git_pass(git_config_set_string(cfg, "merge.conflictstyle", "merge"));
+	git_config_free(cfg);
+}
+
+void test_merge_workdir_simple__cleanup(void)
+{
+	git_index_free(repo_index);
+	cl_git_sandbox_cleanup();
+}
+
+static void merge_simple_branch(int merge_file_favor, int addl_checkout_strategy)
+{
+	git_oid their_oids[1];
+	git_annotated_commit *their_heads[1];
+	git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT;
+	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	cl_git_pass(git_oid_fromstr(&their_oids[0], THEIRS_SIMPLE_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &their_oids[0]));
+
+	merge_opts.file_favor = merge_file_favor;
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_ALLOW_CONFLICTS |
+		addl_checkout_strategy;
+
+	cl_git_pass(git_merge(repo, (const git_annotated_commit **)their_heads, 1, &merge_opts, &checkout_opts));
+
+	git_annotated_commit_free(their_heads[0]);
+}
+
+static void set_core_autocrlf_to(git_repository *repo, bool value)
+{
+	git_config *cfg;
+
+	cl_git_pass(git_repository_config(&cfg, repo));
+	cl_git_pass(git_config_set_bool(cfg, "core.autocrlf", value));
+
+	git_config_free(cfg);
+}
+
+void test_merge_workdir_simple__automerge(void)
+{
+	git_index *index;
+	const git_index_entry *entry;
+	git_buf automergeable_buf = GIT_BUF_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		ADDED_IN_MASTER_INDEX_ENTRY,
+		AUTOMERGEABLE_INDEX_ENTRY,
+		CHANGED_IN_BRANCH_INDEX_ENTRY,
+		CHANGED_IN_MASTER_INDEX_ENTRY,
+
+		{ 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 1, "conflicting.txt" },
+		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
+		{ 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" },
+
+		UNCHANGED_INDEX_ENTRY,
+	};
+
+	struct merge_reuc_entry merge_reuc_entries[] = {
+		AUTOMERGEABLE_REUC_ENTRY,
+		REMOVED_IN_BRANCH_REUC_ENTRY,
+		REMOVED_IN_MASTER_REUC_ENTRY
+	};
+
+
+	set_core_autocrlf_to(repo, false);
+
+	merge_simple_branch(0, 0);
+
+	cl_git_pass(git_futils_readbuffer(&automergeable_buf,
+		TEST_REPO_PATH "/automergeable.txt"));
+	cl_assert(strcmp(automergeable_buf.ptr, AUTOMERGEABLE_MERGED_FILE) == 0);
+	git_buf_free(&automergeable_buf);
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 8));
+	cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3));
+
+	git_repository_index(&index, repo);
+
+	cl_assert((entry = git_index_get_bypath(index, "automergeable.txt", 0)) != NULL);
+	cl_assert(entry->file_size == strlen(AUTOMERGEABLE_MERGED_FILE));
+
+	git_index_free(index);
+}
+
+void test_merge_workdir_simple__automerge_crlf(void)
+{
+#ifdef GIT_WIN32
+	git_index *index;
+	const git_index_entry *entry;
+	git_buf automergeable_buf = GIT_BUF_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		ADDED_IN_MASTER_INDEX_ENTRY,
+		AUTOMERGEABLE_INDEX_ENTRY,
+		CHANGED_IN_BRANCH_INDEX_ENTRY,
+		CHANGED_IN_MASTER_INDEX_ENTRY,
+
+		{ 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 1, "conflicting.txt" },
+		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
+		{ 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" },
+
+		UNCHANGED_INDEX_ENTRY,
+	};
+
+	struct merge_reuc_entry merge_reuc_entries[] = {
+		AUTOMERGEABLE_REUC_ENTRY,
+		REMOVED_IN_BRANCH_REUC_ENTRY,
+		REMOVED_IN_MASTER_REUC_ENTRY
+	};
+
+	set_core_autocrlf_to(repo, true);
+
+	merge_simple_branch(0, 0);
+
+	cl_git_pass(git_futils_readbuffer(&automergeable_buf,
+		TEST_REPO_PATH "/automergeable.txt"));
+	cl_assert(strcmp(automergeable_buf.ptr, AUTOMERGEABLE_MERGED_FILE_CRLF) == 0);
+	git_buf_free(&automergeable_buf);
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 8));
+	cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3));
+
+	git_repository_index(&index, repo);
+
+	cl_assert((entry = git_index_get_bypath(index, "automergeable.txt", 0)) != NULL);
+	cl_assert(entry->file_size == strlen(AUTOMERGEABLE_MERGED_FILE_CRLF));
+
+	git_index_free(index);
+#endif /* GIT_WIN32 */
+}
+
+void test_merge_workdir_simple__mergefile(void)
+{
+	git_buf conflicting_buf = GIT_BUF_INIT, mergemsg_buf = GIT_BUF_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		ADDED_IN_MASTER_INDEX_ENTRY,
+		AUTOMERGEABLE_INDEX_ENTRY,
+		CHANGED_IN_BRANCH_INDEX_ENTRY,
+		CHANGED_IN_MASTER_INDEX_ENTRY,
+
+		{ 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 1, "conflicting.txt" },
+		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
+		{ 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" },
+
+		UNCHANGED_INDEX_ENTRY,
+	};
+
+	struct merge_reuc_entry merge_reuc_entries[] = {
+		AUTOMERGEABLE_REUC_ENTRY,
+		REMOVED_IN_BRANCH_REUC_ENTRY,
+		REMOVED_IN_MASTER_REUC_ENTRY
+	};
+
+	set_core_autocrlf_to(repo, false);
+
+	merge_simple_branch(0, 0);
+
+	cl_git_pass(git_futils_readbuffer(&conflicting_buf,
+		TEST_REPO_PATH "/conflicting.txt"));
+	cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_MERGE_FILE) == 0);
+	cl_git_pass(git_futils_readbuffer(&mergemsg_buf,
+		TEST_REPO_PATH "/.git/MERGE_MSG"));
+	cl_assert(strcmp(git_buf_cstr(&mergemsg_buf),
+		"Merge commit '7cb63eed597130ba4abb87b3e544b85021905520'\n" \
+		"\n" \
+		"Conflicts:\n" \
+		"\tconflicting.txt\n") == 0);
+	git_buf_free(&conflicting_buf);
+	git_buf_free(&mergemsg_buf);
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 8));
+	cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3));
+}
+
+void test_merge_workdir_simple__diff3(void)
+{
+	git_buf conflicting_buf = GIT_BUF_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		ADDED_IN_MASTER_INDEX_ENTRY,
+		AUTOMERGEABLE_INDEX_ENTRY,
+		CHANGED_IN_BRANCH_INDEX_ENTRY,
+		CHANGED_IN_MASTER_INDEX_ENTRY,
+
+		{ 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 1, "conflicting.txt" },
+		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
+		{ 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" },
+
+		UNCHANGED_INDEX_ENTRY,
+	};
+
+	struct merge_reuc_entry merge_reuc_entries[] = {
+		AUTOMERGEABLE_REUC_ENTRY,
+		REMOVED_IN_BRANCH_REUC_ENTRY,
+		REMOVED_IN_MASTER_REUC_ENTRY
+	};
+
+	set_core_autocrlf_to(repo, false);
+
+	merge_simple_branch(0, GIT_CHECKOUT_CONFLICT_STYLE_DIFF3);
+
+	cl_git_pass(git_futils_readbuffer(&conflicting_buf,
+		TEST_REPO_PATH "/conflicting.txt"));
+	cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_DIFF3_FILE) == 0);
+	git_buf_free(&conflicting_buf);
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 8));
+	cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3));
+}
+
+void test_merge_workdir_simple__union(void)
+{
+	git_buf conflicting_buf = GIT_BUF_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		ADDED_IN_MASTER_INDEX_ENTRY,
+		AUTOMERGEABLE_INDEX_ENTRY,
+		CHANGED_IN_BRANCH_INDEX_ENTRY,
+		CHANGED_IN_MASTER_INDEX_ENTRY,
+
+		{ 0100644, "72cdb057b340205164478565e91eb71647e66891", 0, "conflicting.txt" },
+
+		UNCHANGED_INDEX_ENTRY,
+	};
+
+	struct merge_reuc_entry merge_reuc_entries[] = {
+		AUTOMERGEABLE_REUC_ENTRY,
+		CONFLICTING_REUC_ENTRY,
+		REMOVED_IN_BRANCH_REUC_ENTRY,
+		REMOVED_IN_MASTER_REUC_ENTRY
+	};
+
+	set_core_autocrlf_to(repo, false);
+
+	merge_simple_branch(GIT_MERGE_FILE_FAVOR_UNION, 0);
+
+	cl_git_pass(git_futils_readbuffer(&conflicting_buf,
+		TEST_REPO_PATH "/conflicting.txt"));
+	cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_UNION_FILE) == 0);
+	git_buf_free(&conflicting_buf);
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 6));
+	cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 4));
+}
+
+void test_merge_workdir_simple__diff3_from_config(void)
+{
+	git_config *config;
+	git_buf conflicting_buf = GIT_BUF_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		ADDED_IN_MASTER_INDEX_ENTRY,
+		AUTOMERGEABLE_INDEX_ENTRY,
+		CHANGED_IN_BRANCH_INDEX_ENTRY,
+		CHANGED_IN_MASTER_INDEX_ENTRY,
+
+		{ 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 1, "conflicting.txt" },
+		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
+		{ 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" },
+
+		UNCHANGED_INDEX_ENTRY,
+	};
+
+	struct merge_reuc_entry merge_reuc_entries[] = {
+		AUTOMERGEABLE_REUC_ENTRY,
+		REMOVED_IN_BRANCH_REUC_ENTRY,
+		REMOVED_IN_MASTER_REUC_ENTRY
+	};
+
+	cl_git_pass(git_repository_config(&config, repo));
+	cl_git_pass(git_config_set_string(config, "merge.conflictstyle", "diff3"));
+
+	set_core_autocrlf_to(repo, false);
+
+	merge_simple_branch(0, 0);
+
+	cl_git_pass(git_futils_readbuffer(&conflicting_buf,
+		TEST_REPO_PATH "/conflicting.txt"));
+	cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_DIFF3_FILE) == 0);
+	git_buf_free(&conflicting_buf);
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 8));
+	cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3));
+
+	git_config_free(config);
+}
+
+void test_merge_workdir_simple__merge_overrides_config(void)
+{
+	git_config *config;
+	git_buf conflicting_buf = GIT_BUF_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		ADDED_IN_MASTER_INDEX_ENTRY,
+		AUTOMERGEABLE_INDEX_ENTRY,
+		CHANGED_IN_BRANCH_INDEX_ENTRY,
+		CHANGED_IN_MASTER_INDEX_ENTRY,
+
+		{ 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 1, "conflicting.txt" },
+		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
+		{ 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" },
+
+		UNCHANGED_INDEX_ENTRY,
+	};
+
+	struct merge_reuc_entry merge_reuc_entries[] = {
+		AUTOMERGEABLE_REUC_ENTRY,
+		REMOVED_IN_BRANCH_REUC_ENTRY,
+		REMOVED_IN_MASTER_REUC_ENTRY
+	};
+
+	cl_git_pass(git_repository_config(&config, repo));
+	cl_git_pass(git_config_set_string(config, "merge.conflictstyle", "diff3"));
+
+	set_core_autocrlf_to(repo, false);
+
+	merge_simple_branch(0, GIT_CHECKOUT_CONFLICT_STYLE_MERGE);
+
+	cl_git_pass(git_futils_readbuffer(&conflicting_buf,
+		TEST_REPO_PATH "/conflicting.txt"));
+	cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_MERGE_FILE) == 0);
+	git_buf_free(&conflicting_buf);
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 8));
+	cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3));
+
+	git_config_free(config);
+}
+
+void test_merge_workdir_simple__checkout_ours(void)
+{
+	struct merge_index_entry merge_index_entries[] = {
+		ADDED_IN_MASTER_INDEX_ENTRY,
+		AUTOMERGEABLE_INDEX_ENTRY,
+		CHANGED_IN_BRANCH_INDEX_ENTRY,
+		CHANGED_IN_MASTER_INDEX_ENTRY,
+
+		{ 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 1, "conflicting.txt" },
+		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
+		{ 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" },
+
+		UNCHANGED_INDEX_ENTRY,
+	};
+
+	struct merge_reuc_entry merge_reuc_entries[] = {
+		AUTOMERGEABLE_REUC_ENTRY,
+		REMOVED_IN_BRANCH_REUC_ENTRY,
+		REMOVED_IN_MASTER_REUC_ENTRY
+	};
+
+	merge_simple_branch(0, GIT_CHECKOUT_SAFE | GIT_CHECKOUT_USE_OURS);
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 8));
+	cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3));
+
+	cl_assert(git_path_exists(TEST_REPO_PATH "/conflicting.txt"));
+}
+
+void test_merge_workdir_simple__favor_ours(void)
+{
+	struct merge_index_entry merge_index_entries[] = {
+		ADDED_IN_MASTER_INDEX_ENTRY,
+		AUTOMERGEABLE_INDEX_ENTRY,
+		CHANGED_IN_BRANCH_INDEX_ENTRY,
+		CHANGED_IN_MASTER_INDEX_ENTRY,
+		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 0, "conflicting.txt" },
+		UNCHANGED_INDEX_ENTRY,
+	};
+
+	struct merge_reuc_entry merge_reuc_entries[] = {
+		AUTOMERGEABLE_REUC_ENTRY,
+		CONFLICTING_REUC_ENTRY,
+		REMOVED_IN_BRANCH_REUC_ENTRY,
+		REMOVED_IN_MASTER_REUC_ENTRY,
+	};
+
+	merge_simple_branch(GIT_MERGE_FILE_FAVOR_OURS, 0);
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 6));
+	cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 4));
+}
+
+void test_merge_workdir_simple__favor_theirs(void)
+{
+	struct merge_index_entry merge_index_entries[] = {
+		ADDED_IN_MASTER_INDEX_ENTRY,
+		AUTOMERGEABLE_INDEX_ENTRY,
+		CHANGED_IN_BRANCH_INDEX_ENTRY,
+		CHANGED_IN_MASTER_INDEX_ENTRY,
+		{ 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 0, "conflicting.txt" },
+		UNCHANGED_INDEX_ENTRY,
+	};
+
+	struct merge_reuc_entry merge_reuc_entries[] = {
+		AUTOMERGEABLE_REUC_ENTRY,
+		CONFLICTING_REUC_ENTRY,
+		REMOVED_IN_BRANCH_REUC_ENTRY,
+		REMOVED_IN_MASTER_REUC_ENTRY,
+	};
+
+	merge_simple_branch(GIT_MERGE_FILE_FAVOR_THEIRS, 0);
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 6));
+	cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 4));
+}
+
+void test_merge_workdir_simple__directory_file(void)
+{
+	git_reference *head;
+	git_oid their_oids[1], head_commit_id;
+	git_annotated_commit *their_heads[1];
+	git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT;
+	git_commit *head_commit;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "49130a28ef567af9a6a6104c38773fedfa5f9742", 2, "dir-10" },
+		{ 0100644, "6c06dcd163587c2cc18be44857e0b71116382aeb", 3, "dir-10" },
+		{ 0100644, "43aafd43bea779ec74317dc361f45ae3f532a505", 0, "dir-6" },
+		{ 0100644, "a031a28ae70e33a641ce4b8a8f6317f1ab79dee4", 3, "dir-7" },
+		{ 0100644, "5012fd565b1393bdfda1805d4ec38ce6619e1fd1", 1, "dir-7/file.txt" },
+		{ 0100644, "a5563304ddf6caba25cb50323a2ea6f7dbfcadca", 2, "dir-7/file.txt" },
+		{ 0100644, "e9ad6ec3e38364a3d07feda7c4197d4d845c53b5", 0, "dir-8" },
+		{ 0100644, "3ef4d30382ca33fdeba9fda895a99e0891ba37aa", 2, "dir-9" },
+		{ 0100644, "fc4c636d6515e9e261f9260dbcf3cc6eca97ea08", 1, "dir-9/file.txt" },
+		{ 0100644, "76ab0e2868197ec158ddd6c78d8a0d2fd73d38f9", 3, "dir-9/file.txt" },
+		{ 0100644, "5c2411f8075f48a6b2fdb85ebc0d371747c4df15", 0, "file-1/new" },
+		{ 0100644, "a39a620dae5bc8b4e771cd4d251b7d080401a21e", 1, "file-2" },
+		{ 0100644, "d963979c237d08b6ba39062ee7bf64c7d34a27f8", 2, "file-2" },
+		{ 0100644, "5c341ead2ba6f2af98ce5ec3fe84f6b6d2899c0d", 0, "file-2/new" },
+		{ 0100644, "9efe7723802d4305142eee177e018fee1572c4f4", 0, "file-3/new" },
+		{ 0100644, "bacac9b3493509aa15e1730e1545fc0919d1dae0", 1, "file-4" },
+		{ 0100644, "7663fce0130db092936b137cabd693ec234eb060", 3, "file-4" },
+		{ 0100644, "e49f917b448d1340b31d76e54ba388268fd4c922", 0, "file-4/new" },
+		{ 0100644, "cab2cf23998b40f1af2d9d9a756dc9e285a8df4b", 2, "file-5/new" },
+		{ 0100644, "f5504f36e6f4eb797a56fc5bac6c6c7f32969bf2", 3, "file-5/new" },
+	};
+
+	cl_git_pass(git_reference_symbolic_create(&head, repo, GIT_HEAD_FILE, GIT_REFS_HEADS_DIR OURS_DIRECTORY_FILE, 1, NULL));
+	cl_git_pass(git_reference_name_to_id(&head_commit_id, repo, GIT_HEAD_FILE));
+	cl_git_pass(git_commit_lookup(&head_commit, repo, &head_commit_id));
+	cl_git_pass(git_reset(repo, (git_object *)head_commit, GIT_RESET_HARD, NULL));
+
+	cl_git_pass(git_oid_fromstr(&their_oids[0], THEIRS_DIRECTORY_FILE));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &their_oids[0]));
+
+	merge_opts.file_favor = 0;
+	cl_git_pass(git_merge(repo, (const git_annotated_commit **)their_heads, 1, &merge_opts, NULL));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 20));
+
+	git_reference_free(head);
+	git_commit_free(head_commit);
+	git_annotated_commit_free(their_heads[0]);
+}
+
+void test_merge_workdir_simple__unrelated(void)
+{
+	git_oid their_oids[1];
+	git_annotated_commit *their_heads[1];
+	git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0, "added-in-master.txt" },
+		{ 0100644, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", 0, "automergeable.txt" },
+		{ 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-branch.txt" },
+		{ 0100644, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", 0, "changed-in-master.txt" },
+		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 0, "conflicting.txt" },
+		{ 0100644, "ef58fdd8086c243bdc81f99e379acacfd21d32d6", 0, "new-in-unrelated1.txt" },
+		{ 0100644, "948ba6e701c1edab0c2d394fb7c5538334129793", 0, "new-in-unrelated2.txt" },
+		{ 0100644, "dfe3f22baa1f6fce5447901c3086bae368de6bdd", 0, "removed-in-branch.txt" },
+		{ 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0, "unchanged.txt" },
+	};
+
+	cl_git_pass(git_oid_fromstr(&their_oids[0], THEIRS_UNRELATED_PARENT));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &their_oids[0]));
+
+	merge_opts.file_favor = 0;
+	cl_git_pass(git_merge(repo, (const git_annotated_commit **)their_heads, 1, &merge_opts, NULL));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 9));
+
+	git_annotated_commit_free(their_heads[0]);
+}
+
+void test_merge_workdir_simple__unrelated_with_conflicts(void)
+{
+	git_oid their_oids[1];
+	git_annotated_commit *their_heads[1];
+	git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0, "added-in-master.txt" },
+		{ 0100644, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", 2, "automergeable.txt" },
+		{ 0100644, "d07ec190c306ec690bac349e87d01c4358e49bb2", 3, "automergeable.txt" },
+		{ 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-branch.txt" },
+		{ 0100644, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", 0, "changed-in-master.txt" },
+		{ 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
+		{ 0100644, "4b253da36a0ae8bfce63aeabd8c5b58429925594", 3, "conflicting.txt" },
+		{ 0100644, "ef58fdd8086c243bdc81f99e379acacfd21d32d6", 0, "new-in-unrelated1.txt" },
+		{ 0100644, "948ba6e701c1edab0c2d394fb7c5538334129793", 0, "new-in-unrelated2.txt" },
+		{ 0100644, "dfe3f22baa1f6fce5447901c3086bae368de6bdd", 0, "removed-in-branch.txt" },
+		{ 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0, "unchanged.txt" },
+	};
+
+	cl_git_pass(git_oid_fromstr(&their_oids[0], THEIRS_UNRELATED_OID));
+	cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &their_oids[0]));
+
+	merge_opts.file_favor = 0;
+	cl_git_pass(git_merge(repo, (const git_annotated_commit **)their_heads, 1, &merge_opts, NULL));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 11));
+
+	git_annotated_commit_free(their_heads[0]);
+}
+
+void test_merge_workdir_simple__binary(void)
+{
+	git_oid our_oid, their_oid, our_file_oid;
+	git_commit *our_commit;
+	git_annotated_commit *their_head;
+	const git_index_entry *binary_entry;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "1c51d885170f57a0c4e8c69ff6363d91a5b51f85", 1, "binary" },
+		{ 0100644, "23ed141a6ae1e798b2f721afedbe947c119111ba", 2, "binary" },
+		{ 0100644, "836b8b82b26cab22eaaed8820877c76d6c8bca19", 3, "binary" },
+	};
+
+	cl_git_pass(git_oid_fromstr(&our_oid, "cc338e4710c9b257106b8d16d82f86458d5beaf1"));
+	cl_git_pass(git_oid_fromstr(&their_oid, "ad01aebfdf2ac13145efafe3f9fcf798882f1730"));
+
+	cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid));
+	cl_git_pass(git_reset(repo, (git_object *)our_commit, GIT_RESET_HARD, NULL));
+
+	cl_git_pass(git_annotated_commit_lookup(&their_head, repo, &their_oid));
+
+	cl_git_pass(git_merge(repo, (const git_annotated_commit **)&their_head, 1, NULL, NULL));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 3));
+
+	cl_git_pass(git_index_add_bypath(repo_index, "binary"));
+	cl_assert((binary_entry = git_index_get_bypath(repo_index, "binary", 0)) != NULL);
+
+	cl_git_pass(git_oid_fromstr(&our_file_oid, "23ed141a6ae1e798b2f721afedbe947c119111ba"));
+	cl_assert(git_oid_cmp(&binary_entry->id, &our_file_oid) == 0);
+
+	git_annotated_commit_free(their_head);
+	git_commit_free(our_commit);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/submodules.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/submodules.c
new file mode 100755
index 0000000..7c18c2f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/submodules.c
@@ -0,0 +1,95 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/merge.h"
+#include "buffer.h"
+#include "merge.h"
+#include "../merge_helpers.h"
+
+static git_repository *repo;
+
+#define TEST_REPO_PATH "merge-resolve"
+
+#define SUBMODULE_MAIN_BRANCH		"submodules"
+#define SUBMODULE_OTHER_BRANCH		"submodules-branch"
+#define SUBMODULE_OTHER2_BRANCH		"submodules-branch2"
+
+#define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index"
+
+// Fixture setup and teardown
+void test_merge_workdir_submodules__initialize(void)
+{
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+}
+
+void test_merge_workdir_submodules__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_merge_workdir_submodules__automerge(void)
+{
+	git_reference *our_ref, *their_ref;
+	git_commit *our_commit;
+	git_annotated_commit *their_head;
+	git_index *index;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "caff6b7d44973f53e3e0cf31d0d695188b19aec6", 0, ".gitmodules" },
+		{ 0100644, "950a663a6a7b2609eed1ed1ba9f41eb1a3192a9f", 0, "file1.txt" },
+		{ 0100644, "343e660b9cb4bee5f407c2e33fcb9df24d9407a4", 0, "file2.txt" },
+		{ 0160000, "d3d806a4bef96889117fd7ebac0e3cb5ec152932", 1, "submodule" },
+		{ 0160000, "297aa6cd028b3336c7802c7a6f49143da4e1602d", 2, "submodule" },
+		{ 0160000, "ae39c77c70cb6bad18bb471912460c4e1ba0f586", 3, "submodule" },
+	};
+
+	cl_git_pass(git_reference_lookup(&our_ref, repo, "refs/heads/" SUBMODULE_MAIN_BRANCH));
+	cl_git_pass(git_commit_lookup(&our_commit, repo, git_reference_target(our_ref)));
+	cl_git_pass(git_reset(repo, (git_object *)our_commit, GIT_RESET_HARD, NULL));
+
+	cl_git_pass(git_reference_lookup(&their_ref, repo, "refs/heads/" SUBMODULE_OTHER_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_head, repo, their_ref));
+
+	cl_git_pass(git_merge(repo, (const git_annotated_commit **)&their_head, 1, NULL, NULL));
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_assert(merge_test_index(index, merge_index_entries, 6));
+
+	git_index_free(index);
+	git_annotated_commit_free(their_head);
+	git_commit_free(our_commit);
+	git_reference_free(their_ref);
+	git_reference_free(our_ref);
+}
+
+void test_merge_workdir_submodules__take_changed(void)
+{
+	git_reference *our_ref, *their_ref;
+	git_commit *our_commit;
+	git_annotated_commit *their_head;
+	git_index *index;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "caff6b7d44973f53e3e0cf31d0d695188b19aec6", 0, ".gitmodules" },
+		{ 0100644, "b438ff23300b2e0f80b84a6f30140dfa91e71423", 0, "file1.txt" },
+		{ 0100644, "f27fbafdfa6693f8f7a5128506fe3e338dbfcad2", 0, "file2.txt" },
+		{ 0160000, "297aa6cd028b3336c7802c7a6f49143da4e1602d", 0, "submodule" },
+	};
+
+	cl_git_pass(git_reference_lookup(&our_ref, repo, "refs/heads/" SUBMODULE_MAIN_BRANCH));
+	cl_git_pass(git_commit_lookup(&our_commit, repo, git_reference_target(our_ref)));
+	cl_git_pass(git_reset(repo, (git_object *)our_commit, GIT_RESET_HARD, NULL));
+
+	cl_git_pass(git_reference_lookup(&their_ref, repo, "refs/heads/" SUBMODULE_OTHER2_BRANCH));
+	cl_git_pass(git_annotated_commit_from_ref(&their_head, repo, their_ref));
+
+	cl_git_pass(git_merge(repo, (const git_annotated_commit **)&their_head, 1, NULL, NULL));
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_assert(merge_test_index(index, merge_index_entries, 4));
+
+	git_index_free(index);
+	git_annotated_commit_free(their_head);
+	git_commit_free(our_commit);
+	git_reference_free(their_ref);
+	git_reference_free(our_ref);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/trivial.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/trivial.c
new file mode 100755
index 0000000..4ddaf23
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/merge/workdir/trivial.c
@@ -0,0 +1,262 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/merge.h"
+#include "git2/sys/index.h"
+#include "merge.h"
+#include "../merge_helpers.h"
+#include "refs.h"
+#include "fileops.h"
+
+static git_repository *repo;
+static git_index *repo_index;
+
+#define TEST_REPO_PATH "merge-resolve"
+#define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index"
+
+
+// Fixture setup and teardown
+void test_merge_workdir_trivial__initialize(void)
+{
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+	git_repository_index(&repo_index, repo);
+}
+
+void test_merge_workdir_trivial__cleanup(void)
+{
+	git_index_free(repo_index);
+	cl_git_sandbox_cleanup();
+}
+
+
+static int merge_trivial(const char *ours, const char *theirs)
+{
+	git_buf branch_buf = GIT_BUF_INIT;
+	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_reference *our_ref, *their_ref;
+	git_annotated_commit *their_heads[1];
+
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours);
+	cl_git_pass(git_reference_symbolic_create(&our_ref, repo, "HEAD", branch_buf.ptr, 1, NULL));
+
+	cl_git_pass(git_checkout_head(repo, &checkout_opts));
+
+	git_buf_clear(&branch_buf);
+	git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs);
+	cl_git_pass(git_reference_lookup(&their_ref, repo, branch_buf.ptr));
+	cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, their_ref));
+
+	cl_git_pass(git_merge(repo, (const git_annotated_commit **)their_heads, 1, NULL, NULL));
+
+	git_buf_free(&branch_buf);
+	git_reference_free(our_ref);
+	git_reference_free(their_ref);
+	git_annotated_commit_free(their_heads[0]);
+
+	return 0;
+}
+
+static size_t merge_trivial_conflict_entrycount(void)
+{
+	const git_index_entry *entry;
+	size_t count = 0;
+	size_t i;
+
+	for (i = 0; i < git_index_entrycount(repo_index); i++) {
+		cl_assert(entry = git_index_get_byindex(repo_index, i));
+
+		if (git_index_entry_is_conflict(entry))
+			count++;
+	}
+
+	return count;
+}
+
+/* 2ALT: ancest:(empty)+, head:*empty*, remote:remote = result:remote */
+void test_merge_workdir_trivial__2alt(void)
+{
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial("trivial-2alt", "trivial-2alt-branch"));
+
+	cl_assert(entry = git_index_get_bypath(repo_index, "new-in-branch.txt", 0));
+	cl_assert(git_index_reuc_entrycount(repo_index) == 0);
+	cl_assert(merge_trivial_conflict_entrycount() == 0);
+}
+
+/* 3ALT: ancest:(empty)+, head:head, remote:*empty* = result:head */
+void test_merge_workdir_trivial__3alt(void)
+{
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial("trivial-3alt", "trivial-3alt-branch"));
+
+	cl_assert(entry = git_index_get_bypath(repo_index, "new-in-3alt.txt", 0));
+	cl_assert(git_index_reuc_entrycount(repo_index) == 0);
+	cl_assert(merge_trivial_conflict_entrycount() == 0);
+}
+
+/* 4: ancest:(empty)^, head:head, remote:remote = result:no merge */
+void test_merge_workdir_trivial__4(void)
+{
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial("trivial-4", "trivial-4-branch"));
+
+	cl_assert((entry = git_index_get_bypath(repo_index, "new-and-different.txt", 0)) == NULL);
+	cl_assert(git_index_reuc_entrycount(repo_index) == 0);
+
+	cl_assert(merge_trivial_conflict_entrycount() == 2);
+	cl_assert(entry = git_index_get_bypath(repo_index, "new-and-different.txt", 2));
+	cl_assert(entry = git_index_get_bypath(repo_index, "new-and-different.txt", 3));
+}
+
+/* 5ALT: ancest:*, head:head, remote:head = result:head */
+void test_merge_workdir_trivial__5alt_1(void)
+{
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial("trivial-5alt-1", "trivial-5alt-1-branch"));
+
+	cl_assert(entry = git_index_get_bypath(repo_index, "new-and-same.txt", 0));
+	cl_assert(git_index_reuc_entrycount(repo_index) == 0);
+	cl_assert(merge_trivial_conflict_entrycount() == 0);
+}
+
+/* 5ALT: ancest:*, head:head, remote:head = result:head */
+void test_merge_workdir_trivial__5alt_2(void)
+{
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial("trivial-5alt-2", "trivial-5alt-2-branch"));
+
+	cl_assert(entry = git_index_get_bypath(repo_index, "modified-to-same.txt", 0));
+	cl_assert(git_index_reuc_entrycount(repo_index) == 0);
+	cl_assert(merge_trivial_conflict_entrycount() == 0);
+}
+
+/* 6: ancest:ancest+, head:(empty), remote:(empty) = result:no merge */
+void test_merge_workdir_trivial__6(void)
+{
+	const git_index_entry *entry;
+	const git_index_reuc_entry *reuc;
+
+	cl_git_pass(merge_trivial("trivial-6", "trivial-6-branch"));
+
+	cl_assert((entry = git_index_get_bypath(repo_index, "removed-in-both.txt", 0)) == NULL);
+	cl_assert(git_index_reuc_entrycount(repo_index) == 1);
+	cl_assert(reuc = git_index_reuc_get_bypath(repo_index, "removed-in-both.txt"));
+
+	cl_assert(merge_trivial_conflict_entrycount() == 0);
+}
+
+/* 8: ancest:ancest^, head:(empty), remote:ancest = result:no merge */
+void test_merge_workdir_trivial__8(void)
+{
+	const git_index_entry *entry;
+	const git_index_reuc_entry *reuc;
+
+	cl_git_pass(merge_trivial("trivial-8", "trivial-8-branch"));
+
+	cl_assert((entry = git_index_get_bypath(repo_index, "removed-in-8.txt", 0)) == NULL);
+
+	cl_assert(git_index_reuc_entrycount(repo_index) == 1);
+	cl_assert(reuc = git_index_reuc_get_bypath(repo_index, "removed-in-8.txt"));
+
+	cl_assert(merge_trivial_conflict_entrycount() == 0);
+}
+
+/* 7: ancest:ancest+, head:(empty), remote:remote = result:no merge */
+void test_merge_workdir_trivial__7(void)
+{
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial("trivial-7", "trivial-7-branch"));
+
+	cl_assert((entry = git_index_get_bypath(repo_index, "removed-in-7.txt", 0)) == NULL);
+	cl_assert(git_index_reuc_entrycount(repo_index) == 0);
+
+	cl_assert(merge_trivial_conflict_entrycount() == 2);
+	cl_assert(entry = git_index_get_bypath(repo_index, "removed-in-7.txt", 1));
+	cl_assert(entry = git_index_get_bypath(repo_index, "removed-in-7.txt", 3));
+}
+
+/* 10: ancest:ancest^, head:ancest, remote:(empty) = result:no merge */
+void test_merge_workdir_trivial__10(void)
+{
+	const git_index_entry *entry;
+	const git_index_reuc_entry *reuc;
+
+	cl_git_pass(merge_trivial("trivial-10", "trivial-10-branch"));
+
+	cl_assert((entry = git_index_get_bypath(repo_index, "removed-in-10-branch.txt", 0)) == NULL);
+
+	cl_assert(git_index_reuc_entrycount(repo_index) == 1);
+	cl_assert(reuc = git_index_reuc_get_bypath(repo_index, "removed-in-10-branch.txt"));
+
+	cl_assert(merge_trivial_conflict_entrycount() == 0);
+}
+
+/* 9: ancest:ancest+, head:head, remote:(empty) = result:no merge */
+void test_merge_workdir_trivial__9(void)
+{
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial("trivial-9", "trivial-9-branch"));
+
+	cl_assert((entry = git_index_get_bypath(repo_index, "removed-in-9-branch.txt", 0)) == NULL);
+	cl_assert(git_index_reuc_entrycount(repo_index) == 0);
+
+	cl_assert(merge_trivial_conflict_entrycount() == 2);
+	cl_assert(entry = git_index_get_bypath(repo_index, "removed-in-9-branch.txt", 1));
+	cl_assert(entry = git_index_get_bypath(repo_index, "removed-in-9-branch.txt", 2));
+}
+
+/* 13: ancest:ancest+, head:head, remote:ancest = result:head */
+void test_merge_workdir_trivial__13(void)
+{
+	const git_index_entry *entry;
+	git_oid expected_oid;
+
+	cl_git_pass(merge_trivial("trivial-13", "trivial-13-branch"));
+
+	cl_assert(entry = git_index_get_bypath(repo_index, "modified-in-13.txt", 0));
+	cl_git_pass(git_oid_fromstr(&expected_oid, "1cff9ec6a47a537380dedfdd17c9e76d74259a2b"));
+	cl_assert(git_oid_cmp(&entry->id, &expected_oid) == 0);
+
+	cl_assert(git_index_reuc_entrycount(repo_index) == 0);
+	cl_assert(merge_trivial_conflict_entrycount() == 0);
+}
+
+/* 14: ancest:ancest+, head:ancest, remote:remote = result:remote */
+void test_merge_workdir_trivial__14(void)
+{
+	const git_index_entry *entry;
+	git_oid expected_oid;
+
+	cl_git_pass(merge_trivial("trivial-14", "trivial-14-branch"));
+
+	cl_assert(entry = git_index_get_bypath(repo_index, "modified-in-14-branch.txt", 0));
+	cl_git_pass(git_oid_fromstr(&expected_oid, "26153a3ff3649b6c2bb652d3f06878c6e0a172f9"));
+	cl_assert(git_oid_cmp(&entry->id, &expected_oid) == 0);
+
+	cl_assert(git_index_reuc_entrycount(repo_index) == 0);
+	cl_assert(merge_trivial_conflict_entrycount() == 0);
+}
+
+/* 11: ancest:ancest+, head:head, remote:remote = result:no merge */
+void test_merge_workdir_trivial__11(void)
+{
+	const git_index_entry *entry;
+
+	cl_git_pass(merge_trivial("trivial-11", "trivial-11-branch"));
+
+	cl_assert((entry = git_index_get_bypath(repo_index, "modified-in-both.txt", 0)) == NULL);
+	cl_assert(git_index_reuc_entrycount(repo_index) == 0);
+
+	cl_assert(merge_trivial_conflict_entrycount() == 3);
+	cl_assert(entry = git_index_get_bypath(repo_index, "modified-in-both.txt", 1));
+	cl_assert(entry = git_index_get_bypath(repo_index, "modified-in-both.txt", 2));
+	cl_assert(entry = git_index_get_bypath(repo_index, "modified-in-both.txt", 3));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/cred.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/cred.c
new file mode 100755
index 0000000..6994cc0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/cred.c
@@ -0,0 +1,50 @@
+#include "clar_libgit2.h"
+
+#include "git2/cred_helpers.h"
+
+void test_network_cred__stock_userpass_validates_args(void)
+{
+	git_cred_userpass_payload payload = {0};
+
+	cl_git_fail(git_cred_userpass(NULL, NULL, NULL, 0, NULL));
+
+	payload.username = "user";
+	cl_git_fail(git_cred_userpass(NULL, NULL, NULL, 0, &payload));
+
+	payload.username = NULL;
+	payload.username = "pass";
+	cl_git_fail(git_cred_userpass(NULL, NULL, NULL, 0, &payload));
+}
+
+void test_network_cred__stock_userpass_validates_that_method_is_allowed(void)
+{
+	git_cred *cred;
+	git_cred_userpass_payload payload = {"user", "pass"};
+
+	cl_git_fail(git_cred_userpass(&cred, NULL, NULL, 0, &payload));
+	cl_git_pass(git_cred_userpass(&cred, NULL, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
+	cred->free(cred);
+}
+
+void test_network_cred__stock_userpass_properly_handles_username_in_url(void)
+{
+	git_cred *cred;
+	git_cred_userpass_plaintext *plain;
+	git_cred_userpass_payload payload = {"alice", "password"};
+
+	cl_git_pass(git_cred_userpass(&cred, NULL, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
+	plain = (git_cred_userpass_plaintext*)cred;
+	cl_assert_equal_s(plain->username, "alice");
+	cred->free(cred);
+
+	cl_git_pass(git_cred_userpass(&cred, NULL, "bob", GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
+	plain = (git_cred_userpass_plaintext*)cred;
+	cl_assert_equal_s(plain->username, "alice");
+	cred->free(cred);
+
+	payload.username = NULL;
+	cl_git_pass(git_cred_userpass(&cred, NULL, "bob", GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
+	plain = (git_cred_userpass_plaintext*)cred;
+	cl_assert_equal_s(plain->username, "bob");
+	cred->free(cred);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/fetchlocal.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/fetchlocal.c
new file mode 100755
index 0000000..06ee3dd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/fetchlocal.c
@@ -0,0 +1,491 @@
+#include "clar_libgit2.h"
+
+#include "buffer.h"
+#include "path.h"
+#include "remote.h"
+
+static const char* tagger_name = "Vicent Marti";
+static const char* tagger_email = "vicent at github.com";
+static const char* tagger_message = "This is my tag.\n\nThere are many tags, but this one is mine\n";
+
+static int transfer_cb(const git_transfer_progress *stats, void *payload)
+{
+	int *callcount = (int*)payload;
+	GIT_UNUSED(stats);
+	(*callcount)++;
+	return 0;
+}
+
+static void cleanup_local_repo(void *path)
+{
+	cl_fixture_cleanup((char *)path);
+}
+
+void test_network_fetchlocal__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_network_fetchlocal__complete(void)
+{
+	git_repository *repo;
+	git_remote *origin;
+	int callcount = 0;
+	git_strarray refnames = {0};
+
+	const char *url = cl_git_fixture_url("testrepo.git");
+	git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
+
+	options.callbacks.transfer_progress = transfer_cb;
+	options.callbacks.payload = &callcount;
+
+	cl_set_cleanup(&cleanup_local_repo, "foo");
+	cl_git_pass(git_repository_init(&repo, "foo", true));
+
+	cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
+	cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
+
+	cl_git_pass(git_reference_list(&refnames, repo));
+	cl_assert_equal_i(19, (int)refnames.count);
+	cl_assert(callcount > 0);
+
+	git_strarray_free(&refnames);
+	git_remote_free(origin);
+	git_repository_free(repo);
+}
+
+void test_network_fetchlocal__prune(void)
+{
+	git_repository *repo;
+	git_remote *origin;
+	int callcount = 0;
+	git_strarray refnames = {0};
+	git_reference *ref;
+	git_repository *remote_repo = cl_git_sandbox_init("testrepo.git");
+	const char *url = cl_git_path_url(git_repository_path(remote_repo));
+	git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
+
+	options.callbacks.transfer_progress = transfer_cb;
+	options.callbacks.payload = &callcount;
+
+	cl_set_cleanup(&cleanup_local_repo, "foo");
+	cl_git_pass(git_repository_init(&repo, "foo", true));
+
+	cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
+	cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
+
+	cl_git_pass(git_reference_list(&refnames, repo));
+	cl_assert_equal_i(19, (int)refnames.count);
+	cl_assert(callcount > 0);
+	git_strarray_free(&refnames);
+	git_remote_free(origin);
+
+	cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/br2"));
+	cl_git_pass(git_reference_delete(ref));
+	git_reference_free(ref);
+
+	cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
+	cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
+	cl_git_pass(git_remote_prune(origin, &options.callbacks));
+
+	cl_git_pass(git_reference_list(&refnames, repo));
+	cl_assert_equal_i(18, (int)refnames.count);
+	git_strarray_free(&refnames);
+	git_remote_free(origin);
+
+	cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/packed"));
+	cl_git_pass(git_reference_delete(ref));
+	git_reference_free(ref);
+
+	cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
+	cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
+	cl_git_pass(git_remote_prune(origin, &options.callbacks));
+
+	cl_git_pass(git_reference_list(&refnames, repo));
+	cl_assert_equal_i(17, (int)refnames.count);
+	git_strarray_free(&refnames);
+	git_remote_free(origin);
+
+	git_repository_free(repo);
+}
+
+int update_tips_fail_on_call(const char *ref, const git_oid *old, const git_oid *new, void *data)
+{
+	GIT_UNUSED(ref);
+	GIT_UNUSED(old);
+	GIT_UNUSED(new);
+	GIT_UNUSED(data);
+
+	cl_fail("update tips called");
+	return 0;
+}
+
+void assert_ref_exists(git_repository *repo, const char *name)
+{
+	git_reference *ref;
+
+	cl_git_pass(git_reference_lookup(&ref, repo, name));
+	git_reference_free(ref);
+}
+
+void test_network_fetchlocal__prune_overlapping(void)
+{
+	git_repository *repo;
+	git_remote *origin;
+	int callcount = 0;
+	git_strarray refnames = {0};
+	git_reference *ref;
+	git_config *config;
+	git_oid target;
+
+	git_repository *remote_repo = cl_git_sandbox_init("testrepo.git");
+	const char *url = cl_git_path_url(git_repository_path(remote_repo));
+
+	git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
+	options.callbacks.transfer_progress = transfer_cb;
+	options.callbacks.payload = &callcount;
+
+	cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/master"));
+	git_oid_cpy(&target, git_reference_target(ref));
+	git_reference_free(ref);
+	cl_git_pass(git_reference_create(&ref, remote_repo, "refs/pull/42/head", &target, 1, NULL));
+	git_reference_free(ref);
+
+	cl_set_cleanup(&cleanup_local_repo, "foo");
+	cl_git_pass(git_repository_init(&repo, "foo", true));
+
+	cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
+
+	cl_git_pass(git_repository_config(&config, repo));
+	cl_git_pass(git_config_set_bool(config, "remote.origin.prune", true));
+	cl_git_pass(git_config_set_multivar(config, "remote.origin.fetch", "^$", "refs/pull/*/head:refs/remotes/origin/pr/*"));
+
+	git_remote_free(origin);
+	cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
+	cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
+
+	assert_ref_exists(repo, "refs/remotes/origin/master");
+	assert_ref_exists(repo, "refs/remotes/origin/pr/42");
+	cl_git_pass(git_reference_list(&refnames, repo));
+	cl_assert_equal_i(20, (int)refnames.count);
+	git_strarray_free(&refnames);
+
+	cl_git_pass(git_config_delete_multivar(config, "remote.origin.fetch", "refs"));
+	cl_git_pass(git_config_set_multivar(config, "remote.origin.fetch", "^$", "refs/pull/*/head:refs/remotes/origin/pr/*"));
+	cl_git_pass(git_config_set_multivar(config, "remote.origin.fetch", "^$", "refs/heads/*:refs/remotes/origin/*"));
+
+	git_remote_free(origin);
+	cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
+	options.callbacks.update_tips = update_tips_fail_on_call;
+	cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
+
+	assert_ref_exists(repo, "refs/remotes/origin/master");
+	assert_ref_exists(repo, "refs/remotes/origin/pr/42");
+	cl_git_pass(git_reference_list(&refnames, repo));
+	cl_assert_equal_i(20, (int)refnames.count);
+	git_strarray_free(&refnames);
+
+	cl_git_pass(git_config_delete_multivar(config, "remote.origin.fetch", "refs"));
+	cl_git_pass(git_config_set_multivar(config, "remote.origin.fetch", "^$", "refs/heads/*:refs/remotes/origin/*"));
+	cl_git_pass(git_config_set_multivar(config, "remote.origin.fetch", "^$", "refs/pull/*/head:refs/remotes/origin/pr/*"));
+
+	git_remote_free(origin);
+	cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
+	options.callbacks.update_tips = update_tips_fail_on_call;
+	cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
+
+	git_config_free(config);
+	git_strarray_free(&refnames);
+	git_remote_free(origin);
+	git_repository_free(repo);
+}
+
+void test_network_fetchlocal__fetchprune(void)
+{
+	git_repository *repo;
+	git_remote *origin;
+	int callcount = 0;
+	git_strarray refnames = {0};
+	git_reference *ref;
+	git_config *config;
+	git_repository *remote_repo = cl_git_sandbox_init("testrepo.git");
+	const char *url = cl_git_path_url(git_repository_path(remote_repo));
+	git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
+
+	options.callbacks.transfer_progress = transfer_cb;
+	options.callbacks.payload = &callcount;
+
+	cl_set_cleanup(&cleanup_local_repo, "foo");
+	cl_git_pass(git_repository_init(&repo, "foo", true));
+
+	cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
+	cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
+
+	cl_git_pass(git_reference_list(&refnames, repo));
+	cl_assert_equal_i(19, (int)refnames.count);
+	cl_assert(callcount > 0);
+	git_strarray_free(&refnames);
+	git_remote_free(origin);
+
+	cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/br2"));
+	cl_git_pass(git_reference_delete(ref));
+	git_reference_free(ref);
+
+	cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
+	cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
+	cl_git_pass(git_remote_prune(origin, &options.callbacks));
+
+	cl_git_pass(git_reference_list(&refnames, repo));
+	cl_assert_equal_i(18, (int)refnames.count);
+	git_strarray_free(&refnames);
+	git_remote_free(origin);
+
+	cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/packed"));
+	cl_git_pass(git_reference_delete(ref));
+	git_reference_free(ref);
+
+	cl_git_pass(git_repository_config(&config, repo));
+	cl_git_pass(git_config_set_bool(config, "remote.origin.prune", 1));
+	git_config_free(config);
+	cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
+	cl_assert_equal_i(1, git_remote_prune_refs(origin));
+	cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
+
+	cl_git_pass(git_reference_list(&refnames, repo));
+	cl_assert_equal_i(17, (int)refnames.count);
+	git_strarray_free(&refnames);
+	git_remote_free(origin);
+
+	git_repository_free(repo);
+}
+
+void test_network_fetchlocal__prune_tag(void)
+{
+	git_repository *repo;
+	git_remote *origin;
+	int callcount = 0;
+	git_reference *ref;
+	git_config *config;
+	git_oid tag_id;
+	git_signature *tagger;
+	git_object *obj;
+
+	git_repository *remote_repo = cl_git_sandbox_init("testrepo.git");
+	const char *url = cl_git_path_url(git_repository_path(remote_repo));
+	git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
+
+	options.callbacks.transfer_progress = transfer_cb;
+	options.callbacks.payload = &callcount;
+
+	cl_set_cleanup(&cleanup_local_repo, "foo");
+	cl_git_pass(git_repository_init(&repo, "foo", true));
+
+	cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
+	cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
+	git_remote_free(origin);
+
+	cl_git_pass(git_revparse_single(&obj, repo, "origin/master"));
+
+	cl_git_pass(git_reference_create(&ref, repo, "refs/remotes/origin/fake-remote", git_object_id(obj), 1, NULL));
+	git_reference_free(ref);
+
+	/* create signature */
+	cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60));
+
+	cl_git_pass(
+		git_tag_create(&tag_id, repo,
+		  "some-tag", obj, tagger, tagger_message, 0)
+	);
+	git_signature_free(tagger);
+
+	cl_git_pass(git_repository_config(&config, repo));
+	cl_git_pass(git_config_set_bool(config, "remote.origin.prune", 1));
+	git_config_free(config);
+	cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
+	cl_assert_equal_i(1, git_remote_prune_refs(origin));
+	cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
+
+	assert_ref_exists(repo, "refs/tags/some-tag");
+	cl_git_fail_with(GIT_ENOTFOUND, git_reference_lookup(&ref, repo, "refs/remotes/origin/fake-remote"));
+
+	git_object_free(obj);
+	git_remote_free(origin);
+
+	git_repository_free(repo);
+}
+
+static void cleanup_sandbox(void *unused)
+{
+	GIT_UNUSED(unused);
+	cl_git_sandbox_cleanup();
+}
+
+void test_network_fetchlocal__partial(void)
+{
+	git_repository *repo = cl_git_sandbox_init("partial-testrepo");
+	git_remote *origin;
+	int callcount = 0;
+	git_strarray refnames = {0};
+	const char *url;
+	git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
+
+	options.callbacks.transfer_progress = transfer_cb;
+	options.callbacks.payload = &callcount;
+
+	cl_set_cleanup(&cleanup_sandbox, NULL);
+	cl_git_pass(git_reference_list(&refnames, repo));
+	cl_assert_equal_i(1, (int)refnames.count);
+
+	url = cl_git_fixture_url("testrepo.git");
+	cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
+	cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
+
+	git_strarray_free(&refnames);
+
+	cl_git_pass(git_reference_list(&refnames, repo));
+	cl_assert_equal_i(20, (int)refnames.count); /* 18 remote + 1 local */
+	cl_assert(callcount > 0);
+
+	git_strarray_free(&refnames);
+	git_remote_free(origin);
+}
+
+static int remote_mirror_cb(git_remote **out, git_repository *repo,
+			    const char *name, const char *url, void *payload)
+{
+	int error;
+	git_remote *remote;
+
+	GIT_UNUSED(payload);
+
+	if ((error = git_remote_create_with_fetchspec(&remote, repo, name, url, "+refs/*:refs/*")) < 0)
+		return error;
+
+	*out = remote;
+	return 0;
+}
+
+void test_network_fetchlocal__clone_into_mirror(void)
+{
+	git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
+	git_repository *repo;
+	git_reference *head;
+
+	opts.bare = true;
+	opts.remote_cb = remote_mirror_cb;
+	cl_git_pass(git_clone(&repo, cl_git_fixture_url("testrepo.git"), "./foo.git", &opts));
+
+	cl_git_pass(git_reference_lookup(&head, repo, "HEAD"));
+	cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head));
+	cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));
+
+	git_reference_free(head);
+	git_repository_free(repo);
+	cl_fixture_cleanup("./foo.git");
+}
+
+void test_network_fetchlocal__multi_remotes(void)
+{
+	git_repository *repo = cl_git_sandbox_init("testrepo.git");
+	git_remote *test, *test2;
+	git_strarray refnames = {0};
+	git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
+
+	cl_set_cleanup(&cleanup_sandbox, NULL);
+	options.callbacks.transfer_progress = transfer_cb;
+	cl_git_pass(git_remote_set_url(repo, "test", cl_git_fixture_url("testrepo.git")));
+	cl_git_pass(git_remote_lookup(&test, repo, "test"));
+	cl_git_pass(git_remote_fetch(test, NULL, &options, NULL));
+
+	cl_git_pass(git_reference_list(&refnames, repo));
+	cl_assert_equal_i(32, (int)refnames.count);
+	git_strarray_free(&refnames);
+
+	cl_git_pass(git_remote_set_url(repo, "test_with_pushurl", cl_git_fixture_url("testrepo.git")));
+	cl_git_pass(git_remote_lookup(&test2, repo, "test_with_pushurl"));
+	cl_git_pass(git_remote_fetch(test2, NULL, &options, NULL));
+
+	cl_git_pass(git_reference_list(&refnames, repo));
+	cl_assert_equal_i(44, (int)refnames.count);
+
+	git_strarray_free(&refnames);
+	git_remote_free(test);
+	git_remote_free(test2);
+}
+
+static int sideband_cb(const char *str, int len, void *payload)
+{
+	int *count = (int *) payload;
+
+	GIT_UNUSED(str);
+	GIT_UNUSED(len);
+
+	(*count)++;
+	return 0;
+}
+
+void test_network_fetchlocal__call_progress(void)
+{
+	git_repository *repo;
+	git_remote *remote;
+	git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
+	int callcount = 0;
+
+	cl_git_pass(git_repository_init(&repo, "foo.git", true));
+	cl_set_cleanup(cleanup_local_repo, "foo.git");
+
+	cl_git_pass(git_remote_create_with_fetchspec(&remote, repo, "origin", cl_git_fixture_url("testrepo.git"), "+refs/heads/*:refs/heads/*"));
+
+	options.callbacks.sideband_progress = sideband_cb;
+	options.callbacks.payload = &callcount;
+
+	cl_git_pass(git_remote_fetch(remote, NULL, &options, NULL));
+	cl_assert(callcount != 0);
+
+	git_remote_free(remote);
+	git_repository_free(repo);
+}
+
+void test_network_fetchlocal__prune_load_remote_prune_config(void)
+{
+	git_repository *repo;
+	git_remote *origin;
+	git_config *config;
+	git_repository *remote_repo = cl_git_sandbox_init("testrepo.git");
+	const char *url = cl_git_path_url(git_repository_path(remote_repo));
+
+	cl_set_cleanup(&cleanup_local_repo, "foo");
+	cl_git_pass(git_repository_init(&repo, "foo", true));
+
+	cl_git_pass(git_repository_config(&config, repo));
+	cl_git_pass(git_config_set_bool(config, "remote.origin.prune", 1));
+
+	cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
+	cl_assert_equal_i(1, git_remote_prune_refs(origin));
+
+	git_config_free(config);
+	git_remote_free(origin);
+	git_repository_free(repo);
+}
+
+void test_network_fetchlocal__prune_load_fetch_prune_config(void)
+{
+	git_repository *repo;
+	git_remote *origin;
+	git_config *config;
+	git_repository *remote_repo = cl_git_sandbox_init("testrepo.git");
+	const char *url = cl_git_path_url(git_repository_path(remote_repo));
+
+	cl_set_cleanup(&cleanup_local_repo, "foo");
+	cl_git_pass(git_repository_init(&repo, "foo", true));
+
+	cl_git_pass(git_repository_config(&config, repo));
+	cl_git_pass(git_config_set_bool(config, "fetch.prune", 1));
+
+	cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
+	cl_assert_equal_i(1, git_remote_prune_refs(origin));
+
+	git_config_free(config);
+	git_remote_free(origin);
+	git_repository_free(repo);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/matchhost.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/matchhost.c
new file mode 100755
index 0000000..3100dc2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/matchhost.c
@@ -0,0 +1,13 @@
+#include "clar_libgit2.h"
+#include "netops.h"
+
+void test_network_matchhost__match(void)
+{
+	cl_git_pass(gitno__match_host("*.example.org", "www.example.org"));
+	cl_git_pass(gitno__match_host("*.foo.example.org", "www.foo.example.org"));
+	cl_git_fail(gitno__match_host("*.foo.example.org", "foo.example.org"));
+	cl_git_fail(gitno__match_host("*.foo.example.org", "www.example.org"));
+	cl_git_fail(gitno__match_host("*.example.org", "example.org"));
+	cl_git_fail(gitno__match_host("*.example.org", "www.foo.example.org"));
+	cl_git_fail(gitno__match_host("*.example.org", "blah.www.www.example.org"));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/refspecs.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/refspecs.c
new file mode 100755
index 0000000..c47f197
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/refspecs.c
@@ -0,0 +1,160 @@
+#include "clar_libgit2.h"
+#include "refspec.h"
+#include "remote.h"
+
+static void assert_refspec(unsigned int direction, const char *input, bool is_expected_to_be_valid)
+{
+	git_refspec refspec;
+	int error;
+
+	error = git_refspec__parse(&refspec, input, direction == GIT_DIRECTION_FETCH);
+	git_refspec__free(&refspec);
+
+	if (is_expected_to_be_valid)
+		cl_assert_equal_i(0, error);
+	else
+		cl_assert_equal_i(GIT_ERROR, error);
+}
+
+void test_network_refspecs__parsing(void)
+{
+	// Ported from https://github.com/git/git/blob/abd2bde78bd994166900290434a2048e660dabed/t/t5511-refspec.sh
+
+	assert_refspec(GIT_DIRECTION_PUSH, "", false);
+	assert_refspec(GIT_DIRECTION_PUSH, ":", true);
+	assert_refspec(GIT_DIRECTION_PUSH, "::", false);
+	assert_refspec(GIT_DIRECTION_PUSH, "+:", true);
+
+	assert_refspec(GIT_DIRECTION_FETCH, "", true);
+	assert_refspec(GIT_DIRECTION_PUSH, ":", true);
+	assert_refspec(GIT_DIRECTION_FETCH, "::", false);
+
+	assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/*:refs/remotes/frotz/*", true);
+	assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/*:refs/remotes/frotz", false);
+	assert_refspec(GIT_DIRECTION_PUSH, "refs/heads:refs/remotes/frotz/*", false);
+	assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/master:refs/remotes/frotz/xyzzy", true);
+
+	/*
+	 * These have invalid LHS, but we do not have a formal "valid sha-1
+	 * expression syntax checker" so they are not checked with the current
+	 * code.  They will be caught downstream anyway, but we may want to
+	 * have tighter check later...
+	 */
+	//assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/master::refs/remotes/frotz/xyzzy", false);
+	//assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/maste :refs/remotes/frotz/xyzzy", false);
+
+	assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/*:refs/remotes/frotz/*", true);
+	assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/*:refs/remotes/frotz", false);
+	assert_refspec(GIT_DIRECTION_FETCH, "refs/heads:refs/remotes/frotz/*", false);
+	assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/master:refs/remotes/frotz/xyzzy", true);
+	assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/master::refs/remotes/frotz/xyzzy", false);
+	assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/maste :refs/remotes/frotz/xyzzy", false);
+
+	assert_refspec(GIT_DIRECTION_PUSH, "master~1:refs/remotes/frotz/backup", true);
+	assert_refspec(GIT_DIRECTION_FETCH, "master~1:refs/remotes/frotz/backup", false);
+	assert_refspec(GIT_DIRECTION_PUSH, "HEAD~4:refs/remotes/frotz/new", true);
+	assert_refspec(GIT_DIRECTION_FETCH, "HEAD~4:refs/remotes/frotz/new", false);
+
+	assert_refspec(GIT_DIRECTION_PUSH, "HEAD", true);
+	assert_refspec(GIT_DIRECTION_FETCH, "HEAD", true);
+	assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/ nitfol", false);
+	assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/ nitfol", false);
+
+	assert_refspec(GIT_DIRECTION_PUSH, "HEAD:", false);
+	assert_refspec(GIT_DIRECTION_FETCH, "HEAD:", true);
+	assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/ nitfol:", false);
+	assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/ nitfol:", false);
+
+	assert_refspec(GIT_DIRECTION_PUSH, ":refs/remotes/frotz/deleteme", true);
+	assert_refspec(GIT_DIRECTION_FETCH, ":refs/remotes/frotz/HEAD-to-me", true);
+	assert_refspec(GIT_DIRECTION_PUSH, ":refs/remotes/frotz/delete me", false);
+	assert_refspec(GIT_DIRECTION_FETCH, ":refs/remotes/frotz/HEAD to me", false);
+
+	assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/*/for-linus:refs/remotes/mine/*-blah", false);
+	assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/*/for-linus:refs/remotes/mine/*-blah", false);
+
+	assert_refspec(GIT_DIRECTION_FETCH, "refs/heads*/for-linus:refs/remotes/mine/*", false);
+	assert_refspec(GIT_DIRECTION_PUSH, "refs/heads*/for-linus:refs/remotes/mine/*", false);
+
+	assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/*/*/for-linus:refs/remotes/mine/*", false);
+	assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/*/*/for-linus:refs/remotes/mine/*", false);
+
+	assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/*/for-linus:refs/remotes/mine/*", true);
+	assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/*/for-linus:refs/remotes/mine/*", true);
+
+	assert_refspec(GIT_DIRECTION_FETCH, "master", true);
+	assert_refspec(GIT_DIRECTION_PUSH, "master", true);
+
+	assert_refspec(GIT_DIRECTION_FETCH, "refs/pull/*/head:refs/remotes/origin/pr/*", true);
+}
+
+static void assert_valid_transform(const char *refspec, const char *name, const char *result)
+{
+	git_refspec spec;
+	git_buf buf = GIT_BUF_INIT;
+
+	git_refspec__parse(&spec, refspec, true);
+	cl_git_pass(git_refspec_transform(&buf, &spec, name));
+	cl_assert_equal_s(result, buf.ptr);
+
+	git_buf_free(&buf);
+	git_refspec__free(&spec);
+}
+
+void test_network_refspecs__transform_mid_star(void)
+{
+	assert_valid_transform("refs/pull/*/head:refs/remotes/origin/pr/*", "refs/pull/23/head", "refs/remotes/origin/pr/23");
+	assert_valid_transform("refs/heads/*:refs/remotes/origin/*", "refs/heads/master", "refs/remotes/origin/master");
+	assert_valid_transform("refs/heads/*:refs/remotes/origin/*", "refs/heads/user/feature", "refs/remotes/origin/user/feature");
+	assert_valid_transform("refs/heads/*:refs/heads/*", "refs/heads/master", "refs/heads/master");
+	assert_valid_transform("refs/heads/*:refs/heads/*", "refs/heads/user/feature", "refs/heads/user/feature");
+	assert_valid_transform("refs/*:refs/*", "refs/heads/master", "refs/heads/master");
+}
+
+static void assert_invalid_transform(const char *refspec, const char *name)
+{
+	git_refspec spec;
+	git_buf buf = GIT_BUF_INIT;
+
+	git_refspec__parse(&spec, refspec, true);
+	cl_git_fail(git_refspec_transform(&buf, &spec, name));
+
+	git_buf_free(&buf);
+	git_refspec__free(&spec);
+}
+
+void test_network_refspecs__invalid(void)
+{
+	assert_invalid_transform("refs/heads/*:refs/remotes/origin/*", "master");
+	assert_invalid_transform("refs/heads/*:refs/remotes/origin/*", "refs/headz/master");
+}
+
+static void assert_invalid_rtransform(const char *refspec, const char *name)
+{
+	git_refspec spec;
+	git_buf buf = GIT_BUF_INIT;
+
+	git_refspec__parse(&spec, refspec, true);
+	cl_git_fail(git_refspec_rtransform(&buf, &spec, name));
+
+	git_buf_free(&buf);
+	git_refspec__free(&spec);
+}
+
+void test_network_refspecs__invalid_reverse(void)
+{
+	assert_invalid_rtransform("refs/heads/*:refs/remotes/origin/*", "master");
+	assert_invalid_rtransform("refs/heads/*:refs/remotes/origin/*", "refs/remotes/o/master");
+}
+
+void test_network_refspecs__matching(void)
+{
+	git_refspec spec;
+
+	cl_git_pass(git_refspec__parse(&spec, ":", false));
+	cl_assert_equal_s(":", spec.string);
+	cl_assert_equal_s("", spec.src);
+	cl_assert_equal_s("", spec.dst);
+
+	git_refspec__free(&spec);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/createthenload.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/createthenload.c
new file mode 100755
index 0000000..f811f3c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/createthenload.c
@@ -0,0 +1,37 @@
+#include "clar_libgit2.h"
+
+static git_remote *_remote;
+static git_repository *_repo;
+static git_config *_config;
+static char url[] = "http://github.com/libgit2/libgit2.git";
+
+void test_network_remote_createthenload__initialize(void)
+{
+	cl_fixture_sandbox("testrepo.git");
+
+	cl_git_pass(git_repository_open(&_repo, "testrepo.git"));
+
+	cl_git_pass(git_repository_config(&_config, _repo));
+	cl_git_pass(git_config_set_string(_config, "remote.origin.fetch", "+refs/heads/*:refs/remotes/origin/*"));
+	cl_git_pass(git_config_set_string(_config, "remote.origin.url", url));
+	git_config_free(_config);
+
+	cl_git_pass(git_remote_lookup(&_remote, _repo, "origin"));
+}
+
+void test_network_remote_createthenload__cleanup(void)
+{
+	git_remote_free(_remote);
+	_remote = NULL;
+
+	git_repository_free(_repo);
+	_repo = NULL;
+
+	cl_fixture_cleanup("testrepo.git");
+}
+
+void test_network_remote_createthenload__parsing(void)
+{
+	cl_assert_equal_s(git_remote_name(_remote), "origin");
+	cl_assert_equal_s(git_remote_url(_remote), url);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/defaultbranch.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/defaultbranch.c
new file mode 100755
index 0000000..e83755e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/defaultbranch.c
@@ -0,0 +1,108 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "refspec.h"
+#include "remote.h"
+
+static git_remote *g_remote;
+static git_repository *g_repo_a, *g_repo_b;
+
+void test_network_remote_defaultbranch__initialize(void)
+{
+	g_repo_a = cl_git_sandbox_init("testrepo.git");
+	cl_git_pass(git_repository_init(&g_repo_b, "repo-b.git", true));
+	cl_git_pass(git_remote_create(&g_remote, g_repo_b, "origin", git_repository_path(g_repo_a)));
+}
+
+void test_network_remote_defaultbranch__cleanup(void)
+{
+	git_remote_free(g_remote);
+	git_repository_free(g_repo_b);
+
+	cl_git_sandbox_cleanup();
+	cl_fixture_cleanup("repo-b.git");
+}
+
+static void assert_default_branch(const char *should)
+{
+	git_buf name = GIT_BUF_INIT;
+
+	cl_git_pass(git_remote_connect(g_remote, GIT_DIRECTION_FETCH, NULL));
+	cl_git_pass(git_remote_default_branch(&name, g_remote));
+	cl_assert_equal_s(should, name.ptr);
+	git_buf_free(&name);
+}
+
+void test_network_remote_defaultbranch__master(void)
+{
+	assert_default_branch("refs/heads/master");
+}
+
+void test_network_remote_defaultbranch__master_does_not_win(void)
+{
+	cl_git_pass(git_repository_set_head(g_repo_a, "refs/heads/not-good"));
+	assert_default_branch("refs/heads/not-good");
+}
+
+void test_network_remote_defaultbranch__master_on_detached(void)
+{
+	cl_git_pass(git_repository_detach_head(g_repo_a));
+	assert_default_branch("refs/heads/master");
+}
+
+void test_network_remote_defaultbranch__no_default_branch(void)
+{
+	git_remote *remote_b;
+	const git_remote_head **heads;
+	size_t len;
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_remote_create(&remote_b, g_repo_b, "self", git_repository_path(g_repo_b)));
+	cl_git_pass(git_remote_connect(remote_b, GIT_DIRECTION_FETCH, NULL));
+	cl_git_pass(git_remote_ls(&heads, &len, remote_b));
+	cl_assert_equal_i(0, len);
+
+	cl_git_fail_with(GIT_ENOTFOUND, git_remote_default_branch(&buf, remote_b));
+
+	git_remote_free(remote_b);
+}
+
+void test_network_remote_defaultbranch__detached_sharing_nonbranch_id(void)
+{
+	git_oid id, id_cloned;
+	git_reference *ref;
+	git_buf buf = GIT_BUF_INIT;
+	git_repository *cloned_repo;
+
+	cl_git_pass(git_reference_name_to_id(&id, g_repo_a, "HEAD"));
+	cl_git_pass(git_repository_detach_head(g_repo_a));
+	cl_git_pass(git_reference_remove(g_repo_a, "refs/heads/master"));
+	cl_git_pass(git_reference_remove(g_repo_a, "refs/heads/not-good"));
+	cl_git_pass(git_reference_create(&ref, g_repo_a, "refs/foo/bar", &id, 1, NULL));
+	git_reference_free(ref);
+
+	cl_git_pass(git_remote_connect(g_remote, GIT_DIRECTION_FETCH, NULL));
+	cl_git_fail_with(GIT_ENOTFOUND, git_remote_default_branch(&buf, g_remote));
+
+	cl_git_pass(git_clone(&cloned_repo, git_repository_path(g_repo_a), "./local-detached", NULL));
+
+	cl_assert(git_repository_head_detached(cloned_repo));
+	cl_git_pass(git_reference_name_to_id(&id_cloned, g_repo_a, "HEAD"));
+	cl_assert(git_oid_equal(&id, &id_cloned));
+
+	git_repository_free(cloned_repo);
+}
+
+void test_network_remote_defaultbranch__unborn_HEAD_with_branches(void)
+{
+	git_reference *ref;
+	git_repository *cloned_repo;
+
+	cl_git_pass(git_reference_symbolic_create(&ref, g_repo_a, "HEAD", "refs/heads/i-dont-exist", 1, NULL));
+	git_reference_free(ref);
+
+	cl_git_pass(git_clone(&cloned_repo, git_repository_path(g_repo_a), "./semi-empty", NULL));
+
+	cl_assert(git_repository_head_unborn(cloned_repo));
+
+	git_repository_free(cloned_repo);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/delete.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/delete.c
new file mode 100755
index 0000000..f23a638
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/delete.c
@@ -0,0 +1,46 @@
+#include "clar_libgit2.h"
+#include "config/config_helpers.h"
+
+#include "repository.h"
+
+static git_repository *_repo;
+
+void test_network_remote_delete__initialize(void)
+{
+	_repo = cl_git_sandbox_init("testrepo.git");
+}
+
+void test_network_remote_delete__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_network_remote_delete__remove_remote_tracking_branches(void)
+{
+	git_reference *ref;
+
+	cl_git_pass(git_remote_delete(_repo, "test"));
+	cl_git_fail_with(GIT_ENOTFOUND, git_reference_lookup(&ref, _repo, "refs/remotes/test/master"));
+}
+
+void test_network_remote_delete__remove_remote_configuration_settings(void)
+{
+	cl_assert(count_config_entries_match(_repo, "remote\\.test\\.+") > 0);
+
+	cl_git_pass(git_remote_delete(_repo, "test"));
+
+	cl_assert_equal_i(0, count_config_entries_match(_repo, "remote\\.test\\.+"));
+}
+
+void test_network_remote_delete__remove_branch_upstream_configuration_settings(void)
+{
+	assert_config_entry_existence(_repo, "branch.mergeless.remote", true);
+	assert_config_entry_existence(_repo, "branch.master.remote", true);
+
+	cl_git_pass(git_remote_delete(_repo, "test"));
+
+	assert_config_entry_existence(_repo, "branch.mergeless.remote", false);
+	assert_config_entry_existence(_repo, "branch.mergeless.merge", false);
+	assert_config_entry_existence(_repo, "branch.master.remote", false);
+	assert_config_entry_existence(_repo, "branch.master.merge", false);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/isvalidname.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/isvalidname.c
new file mode 100755
index 0000000..c26fbd0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/isvalidname.c
@@ -0,0 +1,17 @@
+#include "clar_libgit2.h"
+
+void test_network_remote_isvalidname__can_detect_invalid_formats(void)
+{
+	cl_assert_equal_i(false, git_remote_is_valid_name("/"));
+	cl_assert_equal_i(false, git_remote_is_valid_name("//"));
+	cl_assert_equal_i(false, git_remote_is_valid_name(".lock"));
+	cl_assert_equal_i(false, git_remote_is_valid_name("a.lock"));
+	cl_assert_equal_i(false, git_remote_is_valid_name("/no/leading/slash"));
+	cl_assert_equal_i(false, git_remote_is_valid_name("no/trailing/slash/"));
+}
+
+void test_network_remote_isvalidname__wont_hopefully_choke_on_valid_formats(void)
+{
+	cl_assert_equal_i(true, git_remote_is_valid_name("webmatrix"));
+	cl_assert_equal_i(true, git_remote_is_valid_name("yishaigalatzer/rules"));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/local.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/local.c
new file mode 100755
index 0000000..5d726c9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/local.c
@@ -0,0 +1,467 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "path.h"
+#include "posix.h"
+
+static git_repository *repo;
+static git_buf file_path_buf = GIT_BUF_INIT;
+static git_remote *remote;
+
+static char *push_refspec_strings[] = {
+	"refs/heads/master",
+};
+static git_strarray push_array = {
+	push_refspec_strings,
+	1,
+};
+
+void test_network_remote_local__initialize(void)
+{
+	cl_git_pass(git_repository_init(&repo, "remotelocal/", 0));
+	cl_git_pass(git_repository_set_ident(repo, "Foo Bar", "foo at example.com"));
+	cl_assert(repo != NULL);
+}
+
+void test_network_remote_local__cleanup(void)
+{
+	git_buf_free(&file_path_buf);
+
+	git_remote_free(remote);
+	remote = NULL;
+
+	git_repository_free(repo);
+	repo = NULL;
+
+	cl_fixture_cleanup("remotelocal");
+}
+
+static void connect_to_local_repository(const char *local_repository)
+{
+	git_buf_sets(&file_path_buf, cl_git_path_url(local_repository));
+
+	cl_git_pass(git_remote_create_anonymous(&remote, repo, git_buf_cstr(&file_path_buf)));
+	cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL));
+}
+
+void test_network_remote_local__connected(void)
+{
+	connect_to_local_repository(cl_fixture("testrepo.git"));
+	cl_assert(git_remote_connected(remote));
+
+	git_remote_disconnect(remote);
+	cl_assert(!git_remote_connected(remote));
+}
+
+void test_network_remote_local__retrieve_advertised_references(void)
+{
+	const git_remote_head **refs;
+	size_t refs_len;
+
+	connect_to_local_repository(cl_fixture("testrepo.git"));
+
+	cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
+
+	cl_assert_equal_i(refs_len, 28);
+}
+
+void test_network_remote_local__retrieve_advertised_before_connect(void)
+{
+	const git_remote_head **refs;
+	size_t refs_len = 0;
+
+	git_buf_sets(&file_path_buf, cl_git_path_url(cl_fixture("testrepo.git")));
+
+	cl_git_pass(git_remote_create_anonymous(&remote, repo, git_buf_cstr(&file_path_buf)));
+	cl_git_fail(git_remote_ls(&refs, &refs_len, remote));
+}
+
+void test_network_remote_local__retrieve_advertised_references_after_disconnect(void)
+{
+	const git_remote_head **refs;
+	size_t refs_len;
+
+	connect_to_local_repository(cl_fixture("testrepo.git"));
+	git_remote_disconnect(remote);
+
+	cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
+
+	cl_assert_equal_i(refs_len, 28);
+}
+
+void test_network_remote_local__retrieve_advertised_references_from_spaced_repository(void)
+{
+	const git_remote_head **refs;
+	size_t refs_len;
+
+	cl_fixture_sandbox("testrepo.git");
+	cl_git_pass(p_rename("testrepo.git", "spaced testrepo.git"));
+
+	connect_to_local_repository("spaced testrepo.git");
+
+	cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
+
+	cl_assert_equal_i(refs_len, 28);
+
+	git_remote_free(remote);	/* Disconnect from the "spaced repo" before the cleanup */
+	remote = NULL;
+
+	cl_fixture_cleanup("spaced testrepo.git");
+}
+
+void test_network_remote_local__nested_tags_are_completely_peeled(void)
+{
+	const git_remote_head **refs;
+	size_t refs_len, i;
+
+	connect_to_local_repository(cl_fixture("testrepo.git"));
+
+	cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
+
+	for (i = 0; i < refs_len; i++) {
+		if (!strcmp(refs[i]->name, "refs/tags/test^{}"))
+			cl_git_pass(git_oid_streq(&refs[i]->oid, "e90810b8df3e80c413d903f631643c716887138d"));
+	}
+}
+
+void test_network_remote_local__shorthand_fetch_refspec0(void)
+{
+	char *refspec_strings[] = {
+		"master:remotes/sloppy/master",
+		"master:boh/sloppy/master",
+	};
+	git_strarray array = {
+		refspec_strings,
+		2,
+	};
+
+	git_reference *ref;
+
+	connect_to_local_repository(cl_fixture("testrepo.git"));
+
+	cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
+
+	cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/sloppy/master"));
+	git_reference_free(ref);
+
+	cl_git_pass(git_reference_lookup(&ref, repo, "refs/heads/boh/sloppy/master"));
+	git_reference_free(ref);
+}
+
+void test_network_remote_local__shorthand_fetch_refspec1(void)
+{
+	char *refspec_strings[] = {
+		"master",
+		"hard_tag",
+	};
+	git_strarray array = {
+		refspec_strings,
+		2,
+	};
+
+	git_reference *ref;
+
+	connect_to_local_repository(cl_fixture("testrepo.git"));
+
+	cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
+
+	cl_git_fail(git_reference_lookup(&ref, repo, "refs/remotes/origin/master"));
+	cl_git_fail(git_reference_lookup(&ref, repo, "refs/tags/hard_tag"));
+}
+
+void test_network_remote_local__tagopt(void)
+{
+	git_reference *ref;
+	git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
+
+	cl_git_pass(git_remote_create(&remote, repo, "tagopt", cl_git_path_url(cl_fixture("testrepo.git"))));
+	fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL;
+	cl_git_pass(git_remote_fetch(remote, NULL, &fetch_opts, NULL));
+
+	cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/tagopt/master"));
+	git_reference_free(ref);
+	cl_git_pass(git_reference_lookup(&ref, repo, "refs/tags/hard_tag"));
+	git_reference_free(ref);
+
+	fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO;
+	cl_git_pass(git_remote_fetch(remote, NULL, &fetch_opts, NULL));
+	cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/tagopt/master"));
+	git_reference_free(ref);
+}
+
+void test_network_remote_local__push_to_bare_remote(void)
+{
+	char *refspec_strings[] = {
+		"master:master",
+	};
+	git_strarray array = {
+		refspec_strings,
+		1,
+	};
+
+	/* Should be able to push to a bare remote */
+	git_remote *localremote;
+
+	/* Get some commits */
+	connect_to_local_repository(cl_fixture("testrepo.git"));
+	cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
+
+	/* Set up an empty bare repo to push into */
+	{
+		git_repository *localbarerepo;
+		cl_git_pass(git_repository_init(&localbarerepo, "./localbare.git", 1));
+		git_repository_free(localbarerepo);
+	}
+
+	/* Connect to the bare repo */
+	cl_git_pass(git_remote_create_anonymous(&localremote, repo, "./localbare.git"));
+	cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL));
+
+	/* Try to push */
+	cl_git_pass(git_remote_upload(localremote, &push_array, NULL));
+
+	/* Clean up */
+	git_remote_free(localremote);
+	cl_fixture_cleanup("localbare.git");
+}
+
+void test_network_remote_local__push_to_bare_remote_with_file_url(void)
+{
+	char *refspec_strings[] = {
+		"master:master",
+	};
+	git_strarray array = {
+		refspec_strings,
+		1,
+	};
+	/* Should be able to push to a bare remote */
+	git_remote *localremote;
+	const char *url;
+
+	/* Get some commits */
+	connect_to_local_repository(cl_fixture("testrepo.git"));
+	cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
+
+	/* Set up an empty bare repo to push into */
+	{
+		git_repository *localbarerepo;
+		cl_git_pass(git_repository_init(&localbarerepo, "./localbare.git", 1));
+		git_repository_free(localbarerepo);
+	}
+
+	/* Create a file URL */
+	url = cl_git_path_url("./localbare.git");
+
+	/* Connect to the bare repo */
+	cl_git_pass(git_remote_create_anonymous(&localremote, repo, url));
+	cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL));
+
+	/* Try to push */
+	cl_git_pass(git_remote_upload(localremote, &push_array, NULL));
+
+	/* Clean up */
+	git_remote_free(localremote);
+	cl_fixture_cleanup("localbare.git");
+}
+
+
+void test_network_remote_local__push_to_non_bare_remote(void)
+{
+	char *refspec_strings[] = {
+		"master:master",
+	};
+	git_strarray array = {
+		refspec_strings,
+		1,
+	};
+	/* Shouldn't be able to push to a non-bare remote */
+	git_remote *localremote;
+	git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
+
+	/* Get some commits */
+	connect_to_local_repository(cl_fixture("testrepo.git"));
+	cl_git_pass(git_remote_fetch(remote, &array, &fetch_opts, NULL));
+
+	/* Set up an empty non-bare repo to push into */
+	{
+		git_repository *remoterepo = NULL;
+		cl_git_pass(git_repository_init(&remoterepo, "localnonbare", 0));
+		git_repository_free(remoterepo);
+	}
+
+	/* Connect to the bare repo */
+	cl_git_pass(git_remote_create_anonymous(&localremote, repo, "./localnonbare"));
+	cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL));
+
+	/* Try to push */
+	cl_git_fail_with(GIT_EBAREREPO, git_remote_upload(localremote, &push_array, NULL));
+
+	/* Clean up */
+	git_remote_free(localremote);
+	cl_fixture_cleanup("localbare.git");
+}
+
+void test_network_remote_local__fetch(void)
+{
+	char *refspec_strings[] = {
+		"master:remotes/sloppy/master",
+	};
+	git_strarray array = {
+		refspec_strings,
+		1,
+	};
+
+	git_reflog *log;
+	const git_reflog_entry *entry;
+	git_reference *ref;
+
+	connect_to_local_repository(cl_fixture("testrepo.git"));
+
+	cl_git_pass(git_remote_fetch(remote, &array, NULL, "UPDAAAAAATE!!"));
+
+	cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/sloppy/master"));
+	git_reference_free(ref);
+
+	cl_git_pass(git_reflog_read(&log, repo, "refs/remotes/sloppy/master"));
+	cl_assert_equal_i(1, git_reflog_entrycount(log));
+	entry = git_reflog_entry_byindex(log, 0);
+	cl_assert_equal_s("foo at example.com", git_reflog_entry_committer(entry)->email);
+	cl_assert_equal_s("UPDAAAAAATE!!", git_reflog_entry_message(entry));
+
+	git_reflog_free(log);
+}
+
+void test_network_remote_local__reflog(void)
+{
+	char *refspec_strings[] = {
+		"master:remotes/sloppy/master",
+	};
+	git_strarray array = {
+		refspec_strings,
+		1,
+	};
+
+	git_reflog *log;
+	const git_reflog_entry *entry;
+
+	connect_to_local_repository(cl_fixture("testrepo.git"));
+
+	cl_git_pass(git_remote_fetch(remote, &array, NULL, "UPDAAAAAATE!!"));
+
+	cl_git_pass(git_reflog_read(&log, repo, "refs/remotes/sloppy/master"));
+	cl_assert_equal_i(1, git_reflog_entrycount(log));
+	entry = git_reflog_entry_byindex(log, 0);
+	cl_assert_equal_s("foo at example.com", git_reflog_entry_committer(entry)->email);
+	cl_assert_equal_s("UPDAAAAAATE!!", git_reflog_entry_message(entry));
+
+	git_reflog_free(log);
+}
+
+void test_network_remote_local__fetch_default_reflog_message(void)
+{
+	char *refspec_strings[] = {
+		"master:remotes/sloppy/master",
+	};
+	git_strarray array = {
+		refspec_strings,
+		1,
+	};
+
+	git_reflog *log;
+	const git_reflog_entry *entry;
+	char expected_reflog_msg[1024];
+
+	connect_to_local_repository(cl_fixture("testrepo.git"));
+
+	cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
+
+	cl_git_pass(git_reflog_read(&log, repo, "refs/remotes/sloppy/master"));
+	cl_assert_equal_i(1, git_reflog_entrycount(log));
+	entry = git_reflog_entry_byindex(log, 0);
+	cl_assert_equal_s("foo at example.com", git_reflog_entry_committer(entry)->email);
+
+	sprintf(expected_reflog_msg, "fetch %s", git_remote_url(remote));
+	cl_assert_equal_s(expected_reflog_msg, git_reflog_entry_message(entry));
+
+	git_reflog_free(log);
+}
+
+void test_network_remote_local__opportunistic_update(void)
+{
+	git_reference *ref;
+	char *refspec_strings[] = {
+		"master",
+	};
+	git_strarray array = {
+		refspec_strings,
+		1,
+	};
+
+	/* this remote has a passive refspec of "refs/heads/<star>:refs/remotes/origin/<star>" */
+	cl_git_pass(git_remote_create(&remote, repo, "origin", cl_git_fixture_url("testrepo.git")));
+	/* and we pass the active refspec "master" */
+	cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
+
+	/* and we expect that to update our copy of origin's master */
+	cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/origin/master"));
+	git_reference_free(ref);
+}
+
+void test_network_remote_local__update_tips_for_new_remote(void) {
+	git_repository *src_repo;
+	git_repository *dst_repo;
+	git_remote *new_remote;
+	git_reference* branch;
+
+	/* Copy test repo */
+	cl_fixture_sandbox("testrepo.git");
+	cl_git_pass(git_repository_open(&src_repo, "testrepo.git"));
+
+	/* Set up an empty bare repo to push into */
+	cl_git_pass(git_repository_init(&dst_repo, "./localbare.git", 1));
+
+	/* Push to bare repo */
+	cl_git_pass(git_remote_create(&new_remote, src_repo, "bare", "./localbare.git"));
+	cl_git_pass(git_remote_push(new_remote, &push_array, NULL));
+	/* Make sure remote branch has been created */
+	cl_git_pass(git_branch_lookup(&branch, src_repo, "bare/master", GIT_BRANCH_REMOTE));
+
+	git_reference_free(branch);
+	git_remote_free(new_remote);
+	git_repository_free(dst_repo);
+	cl_fixture_cleanup("localbare.git");
+	git_repository_free(src_repo);
+	cl_fixture_cleanup("testrepo.git");
+}
+
+void test_network_remote_local__push_delete(void)
+{
+	git_repository *src_repo;
+	git_repository *dst_repo;
+	git_remote *remote;
+	git_reference *ref;
+	char *spec_push[] = { "refs/heads/master" };
+	char *spec_delete[] = { ":refs/heads/master" };
+	git_strarray specs = {
+		spec_push,
+		1,
+	};
+
+	src_repo = cl_git_sandbox_init("testrepo.git");
+	cl_git_pass(git_repository_init(&dst_repo, "target.git", 1));
+
+	cl_git_pass(git_remote_create(&remote, src_repo, "origin", "./target.git"));
+
+	/* Push the master branch and verify it's there */
+	cl_git_pass(git_remote_push(remote, &specs, NULL));
+	cl_git_pass(git_reference_lookup(&ref, dst_repo, "refs/heads/master"));
+	git_reference_free(ref);
+
+	specs.strings = spec_delete;
+	cl_git_pass(git_remote_push(remote, &specs, NULL));
+	cl_git_fail(git_reference_lookup(&ref, dst_repo, "refs/heads/master"));
+
+	git_remote_free(remote);
+	git_repository_free(dst_repo);
+	cl_fixture_cleanup("target.git");
+	cl_git_sandbox_cleanup();
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/push.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/push.c
new file mode 100755
index 0000000..3486054
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/push.c
@@ -0,0 +1,114 @@
+#include "clar_libgit2.h"
+#include "git2/sys/commit.h"
+
+static git_remote *_remote;
+static git_repository *_repo, *_dummy;
+
+void test_network_remote_push__initialize(void)
+{
+	cl_fixture_sandbox("testrepo.git");
+	git_repository_open(&_repo, "testrepo.git");
+
+	/* We need a repository to have a remote */
+	cl_git_pass(git_repository_init(&_dummy, "dummy.git", true));
+	cl_git_pass(git_remote_create(&_remote, _dummy, "origin", cl_git_path_url("testrepo.git")));
+}
+
+void test_network_remote_push__cleanup(void)
+{
+	git_remote_free(_remote);
+	_remote = NULL;
+
+	git_repository_free(_repo);
+	_repo = NULL;
+
+	git_repository_free(_dummy);
+	_dummy = NULL;
+
+	cl_fixture_cleanup("testrepo.git");
+	cl_fixture_cleanup("dummy.git");
+}
+
+int negotiation_cb(const git_push_update **updates, size_t len, void *payload)
+{
+	const git_push_update *expected = payload;
+
+	cl_assert_equal_i(1, len);
+	cl_assert_equal_s(expected->src_refname, updates[0]->src_refname);
+	cl_assert_equal_s(expected->dst_refname, updates[0]->dst_refname);
+	cl_assert_equal_oid(&expected->src, &updates[0]->src);
+	cl_assert_equal_oid(&expected->dst, &updates[0]->dst);
+
+	return 0;
+}
+
+void test_network_remote_push__delete_notification(void)
+{
+	git_push_options opts = GIT_PUSH_OPTIONS_INIT;
+	git_reference *ref;
+	git_push_update expected;
+	char *refspec = ":refs/heads/master";
+	const git_strarray refspecs = {
+		&refspec,
+		1,
+	};
+
+	cl_git_pass(git_reference_lookup(&ref, _repo, "refs/heads/master"));
+
+	expected.src_refname = "";
+	expected.dst_refname = "refs/heads/master";
+	memset(&expected.dst, 0, sizeof(git_oid));
+	git_oid_cpy(&expected.src, git_reference_target(ref));
+
+	opts.callbacks.push_negotiation = negotiation_cb;
+	opts.callbacks.payload = &expected;
+	cl_git_pass(git_remote_push(_remote, &refspecs, &opts));
+
+	git_reference_free(ref);
+	cl_git_fail_with(GIT_ENOTFOUND, git_reference_lookup(&ref, _repo, "refs/heads/master"));
+
+}
+
+void create_dummy_commit(git_reference **out, git_repository *repo)
+{
+	git_index *index;
+	git_oid tree_id, commit_id;
+	git_signature *sig;
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_write_tree(&tree_id, index));
+	git_index_free(index);
+
+	cl_git_pass(git_signature_now(&sig, "Pusher Joe", "pjoe"));
+	cl_git_pass(git_commit_create_from_ids(&commit_id, repo, NULL, sig, sig,
+					       NULL, "Empty tree\n", &tree_id, 0, NULL));
+	cl_git_pass(git_reference_create(out, repo, "refs/heads/empty-tree", &commit_id, true, "commit yo"));
+	git_signature_free(sig);
+}
+
+void test_network_remote_push__create_notification(void)
+{
+	git_push_options opts = GIT_PUSH_OPTIONS_INIT;
+	git_reference *ref;
+	git_push_update expected;
+	char *refspec = "refs/heads/empty-tree";
+	const git_strarray refspecs = {
+		&refspec,
+		1,
+	};
+
+	create_dummy_commit(&ref, _dummy);
+
+	expected.src_refname = "refs/heads/empty-tree";
+	expected.dst_refname = "refs/heads/empty-tree";
+	git_oid_cpy(&expected.dst, git_reference_target(ref));
+	memset(&expected.src, 0, sizeof(git_oid));
+
+	opts.callbacks.push_negotiation = negotiation_cb;
+	opts.callbacks.payload = &expected;
+	cl_git_pass(git_remote_push(_remote, &refspecs, &opts));
+
+	git_reference_free(ref);
+	cl_git_pass(git_reference_lookup(&ref, _repo, "refs/heads/empty-tree"));
+	git_reference_free(ref);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/remotes.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/remotes.c
new file mode 100755
index 0000000..2fa21d4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/remotes.c
@@ -0,0 +1,469 @@
+#include "clar_libgit2.h"
+#include "config/config_helpers.h"
+#include "buffer.h"
+#include "refspec.h"
+#include "remote.h"
+
+static git_remote *_remote;
+static git_repository *_repo;
+static const git_refspec *_refspec;
+
+void test_network_remote_remotes__initialize(void)
+{
+	_repo = cl_git_sandbox_init("testrepo.git");
+
+	cl_git_pass(git_remote_lookup(&_remote, _repo, "test"));
+
+	_refspec = git_remote_get_refspec(_remote, 0);
+	cl_assert(_refspec != NULL);
+}
+
+void test_network_remote_remotes__cleanup(void)
+{
+	git_remote_free(_remote);
+	_remote = NULL;
+
+	cl_git_sandbox_cleanup();
+}
+
+void test_network_remote_remotes__parsing(void)
+{
+	git_remote *_remote2 = NULL;
+
+	cl_assert_equal_s(git_remote_name(_remote), "test");
+	cl_assert_equal_s(git_remote_url(_remote), "git://github.com/libgit2/libgit2");
+	cl_assert(git_remote_pushurl(_remote) == NULL);
+
+	cl_assert_equal_s(git_remote__urlfordirection(_remote, GIT_DIRECTION_FETCH),
+					  "git://github.com/libgit2/libgit2");
+	cl_assert_equal_s(git_remote__urlfordirection(_remote, GIT_DIRECTION_PUSH),
+					  "git://github.com/libgit2/libgit2");
+
+	cl_git_pass(git_remote_lookup(&_remote2, _repo, "test_with_pushurl"));
+	cl_assert_equal_s(git_remote_name(_remote2), "test_with_pushurl");
+	cl_assert_equal_s(git_remote_url(_remote2), "git://github.com/libgit2/fetchlibgit2");
+	cl_assert_equal_s(git_remote_pushurl(_remote2), "git://github.com/libgit2/pushlibgit2");
+
+	cl_assert_equal_s(git_remote__urlfordirection(_remote2, GIT_DIRECTION_FETCH),
+					  "git://github.com/libgit2/fetchlibgit2");
+	cl_assert_equal_s(git_remote__urlfordirection(_remote2, GIT_DIRECTION_PUSH),
+					  "git://github.com/libgit2/pushlibgit2");
+
+	git_remote_free(_remote2);
+}
+
+void test_network_remote_remotes__pushurl(void)
+{
+	const char *name = git_remote_name(_remote);
+	git_remote *mod;
+
+	cl_git_pass(git_remote_set_pushurl(_repo, name, "git://github.com/libgit2/notlibgit2"));
+	cl_git_pass(git_remote_lookup(&mod, _repo, name));
+	cl_assert_equal_s(git_remote_pushurl(mod), "git://github.com/libgit2/notlibgit2");
+	git_remote_free(mod);
+
+	cl_git_pass(git_remote_set_pushurl(_repo, name, NULL));
+	cl_git_pass(git_remote_lookup(&mod, _repo, name));
+	cl_assert(git_remote_pushurl(mod) == NULL);
+	git_remote_free(mod);
+}
+
+void test_network_remote_remotes__error_when_not_found(void)
+{
+	git_remote *r;
+	cl_git_fail_with(git_remote_lookup(&r, _repo, "does-not-exist"), GIT_ENOTFOUND);
+
+	cl_assert(giterr_last() != NULL);
+	cl_assert(giterr_last()->klass == GITERR_CONFIG);
+}
+
+void test_network_remote_remotes__error_when_no_push_available(void)
+{
+	git_remote *r;
+	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
+	char *specs = {
+		"refs/heads/master",
+	};
+	git_strarray arr = {
+		&specs,
+		1,
+	};
+
+
+	cl_git_pass(git_remote_create_anonymous(&r, _repo, cl_fixture("testrepo.git")));
+
+	callbacks.transport = git_transport_local;
+	cl_git_pass(git_remote_connect(r, GIT_DIRECTION_PUSH, &callbacks));
+
+	/* Make sure that push is really not available */
+	r->transport->push = NULL;
+
+	cl_git_fail_with(-1, git_remote_upload(r, &arr, NULL));
+
+	git_remote_free(r);
+}
+
+void test_network_remote_remotes__refspec_parsing(void)
+{
+	cl_assert_equal_s(git_refspec_src(_refspec), "refs/heads/*");
+	cl_assert_equal_s(git_refspec_dst(_refspec), "refs/remotes/test/*");
+}
+
+void test_network_remote_remotes__add_fetchspec(void)
+{
+	size_t size;
+
+	size = git_remote_refspec_count(_remote);
+
+	cl_git_pass(git_remote_add_fetch(_repo, "test", "refs/*:refs/*"));
+	size++;
+
+	git_remote_free(_remote);
+	cl_git_pass(git_remote_lookup(&_remote, _repo, "test"));
+
+	cl_assert_equal_i((int)size, (int)git_remote_refspec_count(_remote));
+
+	_refspec = git_remote_get_refspec(_remote, size - 1);
+	cl_assert_equal_s(git_refspec_src(_refspec), "refs/*");
+	cl_assert_equal_s(git_refspec_dst(_refspec), "refs/*");
+	cl_assert_equal_s(git_refspec_string(_refspec), "refs/*:refs/*");
+	cl_assert_equal_b(_refspec->push, false);
+
+	cl_git_fail_with(GIT_EINVALIDSPEC, git_remote_add_fetch(_repo, "test", "refs/*/foo/*:refs/*"));
+}
+
+void test_network_remote_remotes__dup(void)
+{
+	git_strarray array;
+	git_remote *dup;
+
+	cl_git_pass(git_remote_dup(&dup, _remote));
+
+	cl_assert_equal_s(git_remote_name(dup), git_remote_name(_remote));
+	cl_assert_equal_s(git_remote_url(dup), git_remote_url(_remote));
+	cl_assert_equal_s(git_remote_pushurl(dup), git_remote_pushurl(_remote));
+
+	cl_git_pass(git_remote_get_fetch_refspecs(&array, _remote));
+	cl_assert_equal_i(1, (int)array.count);
+	cl_assert_equal_s("+refs/heads/*:refs/remotes/test/*", array.strings[0]);
+	git_strarray_free(&array);
+
+	cl_git_pass(git_remote_get_push_refspecs(&array, _remote));
+	cl_assert_equal_i(0, (int)array.count);
+	git_strarray_free(&array);
+
+	git_remote_free(dup);
+}
+
+void test_network_remote_remotes__add_pushspec(void)
+{
+	size_t size;
+
+	size = git_remote_refspec_count(_remote);
+
+	cl_git_pass(git_remote_add_push(_repo, "test", "refs/*:refs/*"));
+	size++;
+
+	git_remote_free(_remote);
+	cl_git_pass(git_remote_lookup(&_remote, _repo, "test"));
+
+	cl_assert_equal_i((int)size, (int)git_remote_refspec_count(_remote));
+
+	_refspec = git_remote_get_refspec(_remote, size - 1);
+	cl_assert_equal_s(git_refspec_src(_refspec), "refs/*");
+	cl_assert_equal_s(git_refspec_dst(_refspec), "refs/*");
+	cl_assert_equal_s(git_refspec_string(_refspec), "refs/*:refs/*");
+
+	cl_assert_equal_b(_refspec->push, true);
+}
+
+void test_network_remote_remotes__fnmatch(void)
+{
+	cl_assert(git_refspec_src_matches(_refspec, "refs/heads/master"));
+	cl_assert(git_refspec_src_matches(_refspec, "refs/heads/multi/level/branch"));
+}
+
+void test_network_remote_remotes__transform(void)
+{
+	git_buf ref = GIT_BUF_INIT;
+
+	cl_git_pass(git_refspec_transform(&ref, _refspec, "refs/heads/master"));
+	cl_assert_equal_s(ref.ptr, "refs/remotes/test/master");
+	git_buf_free(&ref);
+}
+
+void test_network_remote_remotes__transform_destination_to_source(void)
+{
+	git_buf ref = GIT_BUF_INIT;
+
+	cl_git_pass(git_refspec_rtransform(&ref, _refspec, "refs/remotes/test/master"));
+	cl_assert_equal_s(ref.ptr, "refs/heads/master");
+	git_buf_free(&ref);
+}
+
+void test_network_remote_remotes__missing_refspecs(void)
+{
+	git_config *cfg;
+
+	git_remote_free(_remote);
+	_remote = NULL;
+
+	cl_git_pass(git_repository_config(&cfg, _repo));
+	cl_git_pass(git_config_set_string(cfg, "remote.specless.url", "http://example.com"));
+	cl_git_pass(git_remote_lookup(&_remote, _repo, "specless"));
+
+	git_config_free(cfg);
+}
+
+void test_network_remote_remotes__nonmatch_upstream_refspec(void)
+{
+	git_config *config;
+	git_remote *remote;
+	char *specstr[] = {
+		"refs/tags/*:refs/tags/*",
+	};
+	git_strarray specs = {
+		specstr,
+		1,
+	};
+
+	cl_git_pass(git_remote_create(&remote, _repo, "taggy", git_repository_path(_repo)));
+
+	/*
+	 * Set the current branch's upstream remote to a dummy ref so we call into the code
+	 * which tries to check for the current branch's upstream in the refspecs
+	 */
+	cl_git_pass(git_repository_config(&config, _repo));
+	cl_git_pass(git_config_set_string(config, "branch.master.remote", "taggy"));
+	cl_git_pass(git_config_set_string(config, "branch.master.merge", "refs/heads/foo"));
+
+	cl_git_pass(git_remote_fetch(remote, &specs, NULL, NULL));
+
+	git_remote_free(remote);
+}
+
+void test_network_remote_remotes__list(void)
+{
+	git_strarray list;
+	git_config *cfg;
+
+	cl_git_pass(git_remote_list(&list, _repo));
+	cl_assert(list.count == 5);
+	git_strarray_free(&list);
+
+	cl_git_pass(git_repository_config(&cfg, _repo));
+
+	/* Create a new remote */
+	cl_git_pass(git_config_set_string(cfg, "remote.specless.url", "http://example.com"));
+
+	/* Update a remote (previously without any url/pushurl entry) */
+	cl_git_pass(git_config_set_string(cfg, "remote.no-remote-url.pushurl", "http://example.com"));
+
+	cl_git_pass(git_remote_list(&list, _repo));
+	cl_assert(list.count == 7);
+	git_strarray_free(&list);
+
+	git_config_free(cfg);
+}
+
+void test_network_remote_remotes__loading_a_missing_remote_returns_ENOTFOUND(void)
+{
+	git_remote_free(_remote);
+	_remote = NULL;
+
+	cl_assert_equal_i(GIT_ENOTFOUND, git_remote_lookup(&_remote, _repo, "just-left-few-minutes-ago"));
+}
+
+void test_network_remote_remotes__loading_with_an_invalid_name_returns_EINVALIDSPEC(void)
+{
+	git_remote_free(_remote);
+	_remote = NULL;
+
+	cl_assert_equal_i(GIT_EINVALIDSPEC, git_remote_lookup(&_remote, _repo, "Inv@{id"));
+}
+
+/*
+ * $ git remote add addtest http://github.com/libgit2/libgit2
+ *
+ * $ cat .git/config
+ * [...]
+ * [remote "addtest"]
+ *         url = http://github.com/libgit2/libgit2
+ *         fetch = +refs/heads/\*:refs/remotes/addtest/\*
+ */
+void test_network_remote_remotes__add(void)
+{
+	git_remote_free(_remote);
+	_remote = NULL;
+
+	cl_git_pass(git_remote_create(&_remote, _repo, "addtest", "http://github.com/libgit2/libgit2"));
+	cl_assert_equal_i(GIT_REMOTE_DOWNLOAD_TAGS_AUTO, git_remote_autotag(_remote));
+
+	git_remote_free(_remote);
+	_remote = NULL;
+
+	cl_git_pass(git_remote_lookup(&_remote, _repo, "addtest"));
+	cl_assert_equal_i(GIT_REMOTE_DOWNLOAD_TAGS_AUTO, git_remote_autotag(_remote));
+
+	_refspec = git_vector_get(&_remote->refspecs, 0);
+	cl_assert_equal_s("refs/heads/*", git_refspec_src(_refspec));
+	cl_assert(git_refspec_force(_refspec) == 1);
+	cl_assert_equal_s("refs/remotes/addtest/*", git_refspec_dst(_refspec));
+	cl_assert_equal_s(git_remote_url(_remote), "http://github.com/libgit2/libgit2");
+}
+
+void test_network_remote_remotes__cannot_add_a_nameless_remote(void)
+{
+	git_remote *remote;
+
+	cl_assert_equal_i(
+		GIT_EINVALIDSPEC,
+		git_remote_create(&remote, _repo, NULL, "git://github.com/libgit2/libgit2"));
+}
+
+void test_network_remote_remotes__cannot_add_a_remote_with_an_invalid_name(void)
+{
+	git_remote *remote = NULL;
+
+	cl_assert_equal_i(
+		GIT_EINVALIDSPEC,
+		git_remote_create(&remote, _repo, "Inv@{id", "git://github.com/libgit2/libgit2"));
+	cl_assert_equal_p(remote, NULL);
+
+	cl_assert_equal_i(
+		GIT_EINVALIDSPEC,
+		git_remote_create(&remote, _repo, "", "git://github.com/libgit2/libgit2"));
+	cl_assert_equal_p(remote, NULL);
+}
+
+void test_network_remote_remotes__tagopt(void)
+{
+	const char *name = git_remote_name(_remote);
+
+	git_remote_set_autotag(_repo, name, GIT_REMOTE_DOWNLOAD_TAGS_ALL);
+	assert_config_entry_value(_repo, "remote.test.tagopt", "--tags");
+
+	git_remote_set_autotag(_repo, name, GIT_REMOTE_DOWNLOAD_TAGS_NONE);
+	assert_config_entry_value(_repo, "remote.test.tagopt", "--no-tags");
+
+	git_remote_set_autotag(_repo, name, GIT_REMOTE_DOWNLOAD_TAGS_AUTO);
+	assert_config_entry_existence(_repo, "remote.test.tagopt", false);
+}
+
+void test_network_remote_remotes__can_load_with_an_empty_url(void)
+{
+	git_remote *remote = NULL;
+
+	cl_git_pass(git_remote_lookup(&remote, _repo, "empty-remote-url"));
+
+	cl_assert(remote->url == NULL);
+	cl_assert(remote->pushurl == NULL);
+
+	cl_git_fail(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL));
+
+	cl_assert(giterr_last() != NULL);
+	cl_assert(giterr_last()->klass == GITERR_INVALID);
+
+	git_remote_free(remote);
+}
+
+void test_network_remote_remotes__can_load_with_only_an_empty_pushurl(void)
+{
+	git_remote *remote = NULL;
+
+	cl_git_pass(git_remote_lookup(&remote, _repo, "empty-remote-pushurl"));
+
+	cl_assert(remote->url == NULL);
+	cl_assert(remote->pushurl == NULL);
+
+	cl_git_fail(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL));
+
+	git_remote_free(remote);
+}
+
+void test_network_remote_remotes__returns_ENOTFOUND_when_neither_url_nor_pushurl(void)
+{
+	git_remote *remote = NULL;
+
+	cl_git_fail_with(
+		git_remote_lookup(&remote, _repo, "no-remote-url"), GIT_ENOTFOUND);
+}
+
+void assert_cannot_create_remote(const char *name, int expected_error)
+{
+	git_remote *remote = NULL;
+
+	cl_git_fail_with(
+		git_remote_create(&remote, _repo, name, "git://github.com/libgit2/libgit2"),
+		expected_error);
+
+	cl_assert_equal_p(remote, NULL);
+}
+
+void test_network_remote_remotes__cannot_create_a_remote_which_name_conflicts_with_an_existing_remote(void)
+{
+	assert_cannot_create_remote("test", GIT_EEXISTS);
+}
+
+void test_network_remote_remotes__cannot_create_a_remote_which_name_is_invalid(void)
+{
+	assert_cannot_create_remote("/", GIT_EINVALIDSPEC);
+	assert_cannot_create_remote("//", GIT_EINVALIDSPEC);
+	assert_cannot_create_remote(".lock", GIT_EINVALIDSPEC);
+	assert_cannot_create_remote("a.lock", GIT_EINVALIDSPEC);
+}
+
+void test_network_remote_remote__git_remote_create_with_fetchspec(void)
+{
+	git_remote *remote;
+	git_strarray array;
+
+	cl_git_pass(git_remote_create_with_fetchspec(&remote, _repo, "test-new", "git://github.com/libgit2/libgit2", "+refs/*:refs/*"));
+	git_remote_get_fetch_refspecs(&array, remote);
+	cl_assert_equal_s("+refs/*:refs/*", array.strings[0]);
+	git_remote_free(remote);
+}
+
+static const char *fetch_refspecs[] = {
+	"+refs/heads/*:refs/remotes/origin/*",
+	"refs/tags/*:refs/tags/*",
+	"+refs/pull/*:refs/pull/*",
+};
+
+static const char *push_refspecs[] = {
+	"refs/heads/*:refs/heads/*",
+	"refs/tags/*:refs/tags/*",
+	"refs/notes/*:refs/notes/*",
+};
+
+void test_network_remote_remotes__query_refspecs(void)
+{
+	git_remote *remote;
+	git_strarray array;
+	int i;
+
+	cl_git_pass(git_remote_create_with_fetchspec(&remote, _repo, "query", "git://github.com/libgit2/libgit2", NULL));
+	git_remote_free(remote);
+
+	for (i = 0; i < 3; i++) {
+		cl_git_pass(git_remote_add_fetch(_repo, "query", fetch_refspecs[i]));
+		cl_git_pass(git_remote_add_push(_repo, "query", push_refspecs[i]));
+	}
+
+	cl_git_pass(git_remote_lookup(&remote, _repo, "query"));
+
+	cl_git_pass(git_remote_get_fetch_refspecs(&array, remote));
+	for (i = 0; i < 3; i++) {
+		cl_assert_equal_s(fetch_refspecs[i], array.strings[i]);
+	}
+	git_strarray_free(&array);
+
+	cl_git_pass(git_remote_get_push_refspecs(&array, remote));
+	for (i = 0; i < 3; i++) {
+		cl_assert_equal_s(push_refspecs[i], array.strings[i]);
+	}
+	git_strarray_free(&array);
+
+	git_remote_free(remote);
+	git_remote_delete(_repo, "test");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/rename.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/rename.c
new file mode 100755
index 0000000..b44a0ae
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/remote/rename.c
@@ -0,0 +1,255 @@
+#include "clar_libgit2.h"
+#include "config/config_helpers.h"
+
+#include "repository.h"
+
+static git_repository *_repo;
+static const char *_remote_name = "test";
+
+void test_network_remote_rename__initialize(void)
+{
+	_repo = cl_git_sandbox_init("testrepo.git");
+}
+
+void test_network_remote_rename__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static int dont_call_me_cb(const char *fetch_refspec, void *payload)
+{
+	GIT_UNUSED(fetch_refspec);
+	GIT_UNUSED(payload);
+
+	cl_assert(false);
+
+	return -1;
+}
+
+void test_network_remote_rename__renaming_a_remote_moves_related_configuration_section(void)
+{
+	git_strarray problems = {0};
+
+	assert_config_entry_existence(_repo, "remote.test.fetch", true);
+	assert_config_entry_existence(_repo, "remote.just/renamed.fetch", false);
+
+	cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just/renamed"));
+	cl_assert_equal_i(0, problems.count);
+	git_strarray_free(&problems);
+
+	assert_config_entry_existence(_repo, "remote.test.fetch", false);
+	assert_config_entry_existence(_repo, "remote.just/renamed.fetch", true);
+}
+
+void test_network_remote_rename__renaming_a_remote_updates_branch_related_configuration_entries(void)
+{
+	git_strarray problems = {0};
+
+	assert_config_entry_value(_repo, "branch.master.remote", "test");
+
+	cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just/renamed"));
+	cl_assert_equal_i(0, problems.count);
+	git_strarray_free(&problems);
+
+	assert_config_entry_value(_repo, "branch.master.remote", "just/renamed");
+}
+
+void test_network_remote_rename__renaming_a_remote_updates_default_fetchrefspec(void)
+{
+	git_strarray problems = {0};
+
+	cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just/renamed"));
+	cl_assert_equal_i(0, problems.count);
+	git_strarray_free(&problems);
+
+	assert_config_entry_value(_repo, "remote.just/renamed.fetch", "+refs/heads/*:refs/remotes/just/renamed/*");
+}
+
+void test_network_remote_rename__renaming_a_remote_without_a_fetchrefspec_doesnt_create_one(void)
+{
+	git_config *config;
+	git_remote *remote;
+	git_strarray problems = {0};
+
+	cl_git_pass(git_repository_config__weakptr(&config, _repo));
+	cl_git_pass(git_config_delete_entry(config, "remote.test.fetch"));
+
+	cl_git_pass(git_remote_lookup(&remote, _repo, "test"));
+	git_remote_free(remote);
+
+	assert_config_entry_existence(_repo, "remote.test.fetch", false);
+
+	cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just/renamed"));
+	cl_assert_equal_i(0, problems.count);
+	git_strarray_free(&problems);
+
+	assert_config_entry_existence(_repo, "remote.just/renamed.fetch", false);
+}
+
+void test_network_remote_rename__renaming_a_remote_notifies_of_non_default_fetchrefspec(void)
+{
+	git_config *config;
+	git_remote *remote;
+	git_strarray problems = {0};
+
+	cl_git_pass(git_repository_config__weakptr(&config, _repo));
+	cl_git_pass(git_config_set_string(config, "remote.test.fetch", "+refs/*:refs/*"));
+	cl_git_pass(git_remote_lookup(&remote, _repo, "test"));
+	git_remote_free(remote);
+
+	cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just/renamed"));
+	cl_assert_equal_i(1, problems.count);
+	cl_assert_equal_s("+refs/*:refs/*", problems.strings[0]);
+	git_strarray_free(&problems);
+
+	assert_config_entry_value(_repo, "remote.just/renamed.fetch", "+refs/*:refs/*");
+
+	git_strarray_free(&problems);
+}
+
+void test_network_remote_rename__new_name_can_contain_dots(void)
+{
+	git_strarray problems = {0};
+
+	cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just.renamed"));
+	cl_assert_equal_i(0, problems.count);
+	git_strarray_free(&problems);
+	assert_config_entry_existence(_repo, "remote.just.renamed.fetch", true);
+}
+
+void test_network_remote_rename__new_name_must_conform_to_reference_naming_conventions(void)
+{
+	git_strarray problems = {0};
+
+	cl_assert_equal_i(
+		GIT_EINVALIDSPEC,
+		git_remote_rename(&problems, _repo, _remote_name, "new@{name"));
+}
+
+void test_network_remote_rename__renamed_name_is_persisted(void)
+{
+	git_remote *renamed;
+	git_repository *another_repo;
+	git_strarray problems = {0};
+
+	cl_git_fail(git_remote_lookup(&renamed, _repo, "just/renamed"));
+
+	cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just/renamed"));
+	cl_assert_equal_i(0, problems.count);
+	git_strarray_free(&problems);
+
+	cl_git_pass(git_repository_open(&another_repo, "testrepo.git"));
+	cl_git_pass(git_remote_lookup(&renamed, _repo, "just/renamed"));
+
+	git_remote_free(renamed);
+	git_repository_free(another_repo);
+}
+
+void test_network_remote_rename__cannot_overwrite_an_existing_remote(void)
+{
+	git_strarray problems = {0};
+
+	cl_assert_equal_i(GIT_EEXISTS, git_remote_rename(&problems, _repo, _remote_name, "test"));
+	cl_assert_equal_i(GIT_EEXISTS, git_remote_rename(&problems, _repo, _remote_name, "test_with_pushurl"));
+}
+
+void test_network_remote_rename__renaming_a_remote_moves_the_underlying_reference(void)
+{
+	git_reference *underlying;
+	git_strarray problems = {0};
+
+	cl_assert_equal_i(GIT_ENOTFOUND, git_reference_lookup(&underlying, _repo, "refs/remotes/just/renamed"));
+	cl_git_pass(git_reference_lookup(&underlying, _repo, "refs/remotes/test/master"));
+	git_reference_free(underlying);
+
+	cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just/renamed"));
+	cl_assert_equal_i(0, problems.count);
+	git_strarray_free(&problems);
+
+	cl_assert_equal_i(GIT_ENOTFOUND, git_reference_lookup(&underlying, _repo, "refs/remotes/test/master"));
+	cl_git_pass(git_reference_lookup(&underlying, _repo, "refs/remotes/just/renamed/master"));
+	git_reference_free(underlying);
+}
+
+void test_network_remote_rename__overwrite_ref_in_target(void)
+{
+	git_oid id;
+	char idstr[GIT_OID_HEXSZ + 1] = {0};
+	git_reference *ref;
+	git_branch_t btype;
+	git_branch_iterator *iter;
+	git_strarray problems = {0};
+
+	cl_git_pass(git_oid_fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"));
+	cl_git_pass(git_reference_create(&ref, _repo, "refs/remotes/renamed/master", &id, 1, NULL));
+	git_reference_free(ref);
+
+	cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "renamed"));
+	cl_assert_equal_i(0, problems.count);
+	git_strarray_free(&problems);
+
+	/* make sure there's only one remote-tracking branch */
+	cl_git_pass(git_branch_iterator_new(&iter, _repo, GIT_BRANCH_REMOTE));
+	cl_git_pass(git_branch_next(&ref, &btype, iter));
+	cl_assert_equal_s("refs/remotes/renamed/master", git_reference_name(ref));
+	git_oid_fmt(idstr, git_reference_target(ref));
+	cl_assert_equal_s("be3563ae3f795b2b4353bcce3a527ad0a4f7f644", idstr);
+	git_reference_free(ref);
+
+	cl_git_fail_with(GIT_ITEROVER, git_branch_next(&ref, &btype, iter));
+	git_branch_iterator_free(iter);
+}
+
+void test_network_remote_rename__nonexistent_returns_enotfound(void)
+{
+	git_strarray problems = {0};
+
+	int err = git_remote_rename(&problems, _repo, "nonexistent", "renamed");
+
+	cl_assert_equal_i(GIT_ENOTFOUND, err);
+}
+
+void test_network_remote_rename__symref_head(void)
+{
+	int error;
+	git_reference *ref;
+	git_branch_t btype;
+	git_branch_iterator *iter;
+	git_strarray problems = {0};
+	char idstr[GIT_OID_HEXSZ + 1] = {0};
+	git_vector refs;
+
+	cl_git_pass(git_reference_symbolic_create(&ref, _repo, "refs/remotes/test/HEAD", "refs/remotes/test/master", 0, NULL));
+	git_reference_free(ref);
+
+	cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "renamed"));
+	cl_assert_equal_i(0, problems.count);
+	git_strarray_free(&problems);
+
+	cl_git_pass(git_vector_init(&refs, 2, (git_vector_cmp) git_reference_cmp));
+	cl_git_pass(git_branch_iterator_new(&iter, _repo, GIT_BRANCH_REMOTE));
+
+	while ((error = git_branch_next(&ref, &btype, iter)) == 0) {
+		cl_git_pass(git_vector_insert(&refs, ref));
+	}
+	cl_assert_equal_i(GIT_ITEROVER, error);
+	git_vector_sort(&refs);
+
+	cl_assert_equal_i(2, refs.length);
+
+	ref = git_vector_get(&refs, 0);
+	cl_assert_equal_s("refs/remotes/renamed/HEAD", git_reference_name(ref));
+	cl_assert_equal_s("refs/remotes/renamed/master", git_reference_symbolic_target(ref));
+	git_reference_free(ref);
+
+	ref = git_vector_get(&refs, 1);
+	cl_assert_equal_s("refs/remotes/renamed/master", git_reference_name(ref));
+	git_oid_fmt(idstr, git_reference_target(ref));
+	cl_assert_equal_s("be3563ae3f795b2b4353bcce3a527ad0a4f7f644", idstr);
+	git_reference_free(ref);
+
+	git_vector_free(&refs);
+
+	cl_git_fail_with(GIT_ITEROVER, git_branch_next(&ref, &btype, iter));
+	git_branch_iterator_free(iter);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/urlparse.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/urlparse.c
new file mode 100755
index 0000000..b3ac8ae
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/network/urlparse.c
@@ -0,0 +1,211 @@
+#include "clar_libgit2.h"
+#include "netops.h"
+
+static char *host, *port, *path, *user, *pass;
+static gitno_connection_data conndata;
+
+void test_network_urlparse__initialize(void)
+{
+	host = port = path = user = pass = NULL;
+	memset(&conndata, 0, sizeof(conndata));
+}
+
+void test_network_urlparse__cleanup(void)
+{
+#define FREE_AND_NULL(x) if (x) { git__free(x); x = NULL; }
+	FREE_AND_NULL(host);
+	FREE_AND_NULL(port);
+	FREE_AND_NULL(path);
+	FREE_AND_NULL(user);
+	FREE_AND_NULL(pass);
+
+	gitno_connection_data_free_ptrs(&conndata);
+}
+
+void test_network_urlparse__trivial(void)
+{
+	cl_git_pass(gitno_extract_url_parts(&host, &port, &path, &user, &pass,
+				"http://example.com/resource", "8080"));
+	cl_assert_equal_s(host, "example.com");
+	cl_assert_equal_s(port, "8080");
+	cl_assert_equal_s(path, "/resource");
+	cl_assert_equal_p(user, NULL);
+	cl_assert_equal_p(pass, NULL);
+}
+
+void test_network_urlparse__root(void)
+{
+	cl_git_pass(gitno_extract_url_parts(&host, &port, &path, &user, &pass,
+				"http://example.com/", "8080"));
+	cl_assert_equal_s(host, "example.com");
+	cl_assert_equal_s(port, "8080");
+	cl_assert_equal_s(path, "/");
+	cl_assert_equal_p(user, NULL);
+	cl_assert_equal_p(pass, NULL);
+}
+
+void test_network_urlparse__just_hostname(void)
+{
+	cl_git_fail_with(GIT_EINVALIDSPEC,
+			 gitno_extract_url_parts(&host, &port, &path, &user, &pass,
+						 "http://example.com", "8080"));
+}
+
+void test_network_urlparse__encoded_password(void)
+{
+	cl_git_pass(gitno_extract_url_parts(&host, &port, &path, &user, &pass,
+				"https://user:pass%2fis%40bad@hostname.com:1234/", "1"));
+	cl_assert_equal_s(host, "hostname.com");
+	cl_assert_equal_s(port, "1234");
+	cl_assert_equal_s(path, "/");
+	cl_assert_equal_s(user, "user");
+	cl_assert_equal_s(pass, "pass/is at bad");
+}
+
+void test_network_urlparse__user(void)
+{
+	cl_git_pass(gitno_extract_url_parts(&host, &port, &path, &user, &pass,
+				"https://user@example.com/resource", "8080"));
+	cl_assert_equal_s(host, "example.com");
+	cl_assert_equal_s(port, "8080");
+	cl_assert_equal_s(path, "/resource");
+	cl_assert_equal_s(user, "user");
+	cl_assert_equal_p(pass, NULL);
+}
+
+void test_network_urlparse__user_pass(void)
+{
+	/* user:pass at hostname.tld/resource */
+	cl_git_pass(gitno_extract_url_parts(&host, &port, &path, &user, &pass,
+				"https://user:pass@example.com/resource", "8080"));
+	cl_assert_equal_s(host, "example.com");
+	cl_assert_equal_s(port, "8080");
+	cl_assert_equal_s(path, "/resource");
+	cl_assert_equal_s(user, "user");
+	cl_assert_equal_s(pass, "pass");
+}
+
+void test_network_urlparse__port(void)
+{
+	/* hostname.tld:port/resource */
+	cl_git_pass(gitno_extract_url_parts(&host, &port, &path, &user, &pass,
+				"https://example.com:9191/resource", "8080"));
+	cl_assert_equal_s(host, "example.com");
+	cl_assert_equal_s(port, "9191");
+	cl_assert_equal_s(path, "/resource");
+	cl_assert_equal_p(user, NULL);
+	cl_assert_equal_p(pass, NULL);
+}
+
+void test_network_urlparse__user_port(void)
+{
+	/* user at hostname.tld:port/resource */
+	cl_git_pass(gitno_extract_url_parts(&host, &port, &path, &user, &pass,
+				"https://user@example.com:9191/resource", "8080"));
+	cl_assert_equal_s(host, "example.com");
+	cl_assert_equal_s(port, "9191");
+	cl_assert_equal_s(path, "/resource");
+	cl_assert_equal_s(user, "user");
+	cl_assert_equal_p(pass, NULL);
+}
+
+void test_network_urlparse__user_pass_port(void)
+{
+	/* user:pass at hostname.tld:port/resource */
+	cl_git_pass(gitno_extract_url_parts(&host, &port, &path, &user, &pass,
+				"https://user:pass@example.com:9191/resource", "8080"));
+	cl_assert_equal_s(host, "example.com");
+	cl_assert_equal_s(port, "9191");
+	cl_assert_equal_s(path, "/resource");
+	cl_assert_equal_s(user, "user");
+	cl_assert_equal_s(pass, "pass");
+}
+
+void test_network_urlparse__connection_data_http(void)
+{
+	cl_git_pass(gitno_connection_data_from_url(&conndata,
+				"http://example.com/foo/bar/baz", "bar/baz"));
+	cl_assert_equal_s(conndata.host, "example.com");
+	cl_assert_equal_s(conndata.port, "80");
+	cl_assert_equal_s(conndata.path, "/foo/");
+	cl_assert_equal_p(conndata.user, NULL);
+	cl_assert_equal_p(conndata.pass, NULL);
+	cl_assert_equal_i(conndata.use_ssl, false);
+}
+
+void test_network_urlparse__connection_data_ssl(void)
+{
+	cl_git_pass(gitno_connection_data_from_url(&conndata,
+				"https://example.com/foo/bar/baz", "bar/baz"));
+	cl_assert_equal_s(conndata.host, "example.com");
+	cl_assert_equal_s(conndata.port, "443");
+	cl_assert_equal_s(conndata.path, "/foo/");
+	cl_assert_equal_p(conndata.user, NULL);
+	cl_assert_equal_p(conndata.pass, NULL);
+	cl_assert_equal_i(conndata.use_ssl, true);
+}
+
+void test_network_urlparse__encoded_username_password(void)
+{
+	cl_git_pass(gitno_connection_data_from_url(&conndata,
+				"https://user%2fname:pass%40word%zyx%v@example.com/foo/bar/baz", "bar/baz"));
+	cl_assert_equal_s(conndata.host, "example.com");
+	cl_assert_equal_s(conndata.port, "443");
+	cl_assert_equal_s(conndata.path, "/foo/");
+	cl_assert_equal_s(conndata.user, "user/name");
+	cl_assert_equal_s(conndata.pass, "pass at word%zyx%v");
+	cl_assert_equal_i(conndata.use_ssl, true);
+}
+
+void test_network_urlparse__connection_data_cross_host_redirect(void)
+{
+	conndata.host = git__strdup("bar.com");
+	cl_git_fail_with(gitno_connection_data_from_url(&conndata,
+				"https://foo.com/bar/baz", NULL),
+			-1);
+}
+
+void test_network_urlparse__connection_data_http_downgrade(void)
+{
+	conndata.use_ssl = true;
+	cl_git_fail_with(gitno_connection_data_from_url(&conndata,
+				"http://foo.com/bar/baz", NULL),
+			-1);
+}
+
+void test_network_urlparse__connection_data_relative_redirect(void)
+{
+	cl_git_pass(gitno_connection_data_from_url(&conndata,
+				"http://foo.com/bar/baz/biff", NULL));
+	cl_git_pass(gitno_connection_data_from_url(&conndata,
+				"/zap/baz/biff?bam", NULL));
+	cl_assert_equal_s(conndata.host, "foo.com");
+	cl_assert_equal_s(conndata.port, "80");
+	cl_assert_equal_s(conndata.path, "/zap/baz/biff?bam");
+	cl_assert_equal_p(conndata.user, NULL);
+	cl_assert_equal_p(conndata.pass, NULL);
+	cl_assert_equal_i(conndata.use_ssl, false);
+}
+
+void test_network_urlparse__connection_data_relative_redirect_ssl(void)
+{
+	cl_git_pass(gitno_connection_data_from_url(&conndata,
+				"https://foo.com/bar/baz/biff", NULL));
+	cl_git_pass(gitno_connection_data_from_url(&conndata,
+				"/zap/baz/biff?bam", NULL));
+	cl_assert_equal_s(conndata.host, "foo.com");
+	cl_assert_equal_s(conndata.port, "443");
+	cl_assert_equal_s(conndata.path, "/zap/baz/biff?bam");
+	cl_assert_equal_p(conndata.user, NULL);
+	cl_assert_equal_p(conndata.pass, NULL);
+	cl_assert_equal_i(conndata.use_ssl, true);
+}
+
+/* Run this under valgrind */
+void test_network_urlparse__connection_data_cleanup(void)
+{
+	cl_git_pass(gitno_connection_data_from_url(&conndata,
+				"http://foo.com/bar/baz/biff", "baz/biff"));
+	cl_git_pass(gitno_connection_data_from_url(&conndata,
+				"https://foo.com/bar/baz/biff", "baz/biff"));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/notes/notes.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/notes/notes.c
new file mode 100755
index 0000000..a91bf5b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/notes/notes.c
@@ -0,0 +1,390 @@
+#include "clar_libgit2.h"
+
+#include "buffer.h"
+
+static git_repository *_repo;
+static git_signature *_sig;
+
+void test_notes_notes__initialize(void)
+{
+	_repo = cl_git_sandbox_init("testrepo.git");
+	cl_git_pass(git_signature_now(&_sig, "alice", "alice at example.com"));
+}
+
+void test_notes_notes__cleanup(void)
+{
+	git_signature_free(_sig);
+	_sig = NULL;
+
+	cl_git_sandbox_cleanup();
+}
+
+static void assert_note_equal(git_note *note, char *message, git_oid *note_oid) {
+	git_blob *blob;
+
+	cl_assert_equal_s(git_note_message(note), message);
+	cl_assert_equal_oid(git_note_id(note), note_oid);
+
+	cl_git_pass(git_blob_lookup(&blob, _repo, note_oid));
+	cl_assert_equal_s(git_note_message(note), (const char *)git_blob_rawcontent(blob));
+
+	git_blob_free(blob);
+}
+
+static void create_note(git_oid *note_oid, const char *canonical_namespace, const char *target_sha, const char *message)
+{
+	git_oid oid;
+
+	cl_git_pass(git_oid_fromstr(&oid, target_sha));
+	cl_git_pass(git_note_create(note_oid, _repo, canonical_namespace, _sig, _sig, &oid, message, 0));
+}
+
+static struct {
+	const char *note_sha;
+	const char *annotated_object_sha;
+}
+list_expectations[] = {
+	{ "1c73b1f51762155d357bcd1fd4f2c409ef80065b", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045" },
+	{ "1c73b1f51762155d357bcd1fd4f2c409ef80065b", "9fd738e8f7967c078dceed8190330fc8648ee56a" },
+	{ "257b43746b6b46caa4aa788376c647cce0a33e2b", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750" },
+	{ "1ec1c8e03f461f4f5d3f3702172483662e7223f3", "c47800c7266a2be04c571c04d5a6614691ea99bd" },
+	{ NULL, NULL }
+};
+
+#define EXPECTATIONS_COUNT (sizeof(list_expectations)/sizeof(list_expectations[0])) - 1
+
+static int note_list_cb(
+	const git_oid *blob_id, const git_oid *annotated_obj_id, void *payload)
+{
+	git_oid expected_note_oid, expected_target_oid;
+
+	unsigned int *count = (unsigned int *)payload;
+
+	cl_assert(*count < EXPECTATIONS_COUNT);
+
+	cl_git_pass(git_oid_fromstr(&expected_note_oid, list_expectations[*count].note_sha));
+	cl_assert_equal_oid(&expected_note_oid, blob_id);
+
+	cl_git_pass(git_oid_fromstr(&expected_target_oid, list_expectations[*count].annotated_object_sha));
+	cl_assert_equal_oid(&expected_target_oid, annotated_obj_id);
+
+	(*count)++;
+
+	return 0;
+}
+
+/*
+ * $ git notes --ref i-can-see-dead-notes add -m "I decorate a65f" a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+ * $ git notes --ref i-can-see-dead-notes add -m "I decorate c478" c47800c7266a2be04c571c04d5a6614691ea99bd
+ * $ git notes --ref i-can-see-dead-notes add -m "I decorate 9fd7 and 4a20" 9fd738e8f7967c078dceed8190330fc8648ee56a
+ * $ git notes --ref i-can-see-dead-notes add -m "I decorate 9fd7 and 4a20" 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ *
+ * $ git notes --ref i-can-see-dead-notes list
+ * 1c73b1f51762155d357bcd1fd4f2c409ef80065b 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ * 1c73b1f51762155d357bcd1fd4f2c409ef80065b 9fd738e8f7967c078dceed8190330fc8648ee56a
+ * 257b43746b6b46caa4aa788376c647cce0a33e2b a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+ * 1ec1c8e03f461f4f5d3f3702172483662e7223f3 c47800c7266a2be04c571c04d5a6614691ea99bd
+ *
+ * $ git ls-tree refs/notes/i-can-see-dead-notes
+ * 100644 blob 1c73b1f51762155d357bcd1fd4f2c409ef80065b    4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ * 100644 blob 1c73b1f51762155d357bcd1fd4f2c409ef80065b    9fd738e8f7967c078dceed8190330fc8648ee56a
+ * 100644 blob 257b43746b6b46caa4aa788376c647cce0a33e2b    a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+ * 100644 blob 1ec1c8e03f461f4f5d3f3702172483662e7223f3    c47800c7266a2be04c571c04d5a6614691ea99bd
+*/
+void test_notes_notes__can_retrieve_a_list_of_notes_for_a_given_namespace(void)
+{
+	git_oid note_oid1, note_oid2, note_oid3, note_oid4;
+	unsigned int retrieved_notes = 0;
+
+	create_note(&note_oid1, "refs/notes/i-can-see-dead-notes", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "I decorate a65f\n");
+	create_note(&note_oid2, "refs/notes/i-can-see-dead-notes", "c47800c7266a2be04c571c04d5a6614691ea99bd", "I decorate c478\n");
+	create_note(&note_oid3, "refs/notes/i-can-see-dead-notes", "9fd738e8f7967c078dceed8190330fc8648ee56a", "I decorate 9fd7 and 4a20\n");
+	create_note(&note_oid4, "refs/notes/i-can-see-dead-notes", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "I decorate 9fd7 and 4a20\n");
+
+	cl_git_pass(git_note_foreach
+(_repo, "refs/notes/i-can-see-dead-notes", note_list_cb, &retrieved_notes));
+
+	cl_assert_equal_i(4, retrieved_notes);
+}
+
+static int note_cancel_cb(
+	const git_oid *blob_id, const git_oid *annotated_obj_id, void *payload)
+{
+	unsigned int *count = (unsigned int *)payload;
+
+	GIT_UNUSED(blob_id);
+	GIT_UNUSED(annotated_obj_id);
+
+	(*count)++;
+
+	return (*count > 2);
+}
+
+void test_notes_notes__can_cancel_foreach(void)
+{
+	git_oid note_oid1, note_oid2, note_oid3, note_oid4;
+	unsigned int retrieved_notes = 0;
+
+	create_note(&note_oid1, "refs/notes/i-can-see-dead-notes", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "I decorate a65f\n");
+	create_note(&note_oid2, "refs/notes/i-can-see-dead-notes", "c47800c7266a2be04c571c04d5a6614691ea99bd", "I decorate c478\n");
+	create_note(&note_oid3, "refs/notes/i-can-see-dead-notes", "9fd738e8f7967c078dceed8190330fc8648ee56a", "I decorate 9fd7 and 4a20\n");
+	create_note(&note_oid4, "refs/notes/i-can-see-dead-notes", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "I decorate 9fd7 and 4a20\n");
+
+	cl_assert_equal_i(
+		1,
+		git_note_foreach(_repo, "refs/notes/i-can-see-dead-notes",
+			note_cancel_cb, &retrieved_notes));
+}
+
+void test_notes_notes__retrieving_a_list_of_notes_for_an_unknown_namespace_returns_ENOTFOUND(void)
+{
+	int error;
+	unsigned int retrieved_notes = 0;
+
+	error = git_note_foreach(_repo, "refs/notes/i-am-not", note_list_cb, &retrieved_notes);
+	cl_git_fail(error);
+	cl_assert_equal_i(GIT_ENOTFOUND, error);
+
+	cl_assert_equal_i(0, retrieved_notes);
+}
+
+void test_notes_notes__inserting_a_note_without_passing_a_namespace_uses_the_default_namespace(void)
+{
+	git_oid note_oid, target_oid;
+	git_note *note, *default_namespace_note;
+	git_buf default_ref = GIT_BUF_INIT;
+
+	cl_git_pass(git_oid_fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125"));
+	cl_git_pass(git_note_default_ref(&default_ref, _repo));
+
+	create_note(&note_oid, NULL, "08b041783f40edfe12bb406c9c9a8a040177c125", "hello world\n");
+
+	cl_git_pass(git_note_read(&note, _repo, NULL, &target_oid));
+	cl_git_pass(git_note_read(&default_namespace_note, _repo, git_buf_cstr(&default_ref), &target_oid));
+
+	assert_note_equal(note, "hello world\n", &note_oid);
+	assert_note_equal(default_namespace_note, "hello world\n", &note_oid);
+
+	git_buf_free(&default_ref);
+	git_note_free(note);
+	git_note_free(default_namespace_note);
+}
+
+void test_notes_notes__can_insert_a_note_with_a_custom_namespace(void)
+{
+	git_oid note_oid, target_oid;
+	git_note *note;
+
+	cl_git_pass(git_oid_fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125"));
+
+	create_note(&note_oid, "refs/notes/some/namespace", "08b041783f40edfe12bb406c9c9a8a040177c125", "hello world on a custom namespace\n");
+
+	cl_git_pass(git_note_read(&note, _repo, "refs/notes/some/namespace", &target_oid));
+
+	assert_note_equal(note, "hello world on a custom namespace\n", &note_oid);
+
+	git_note_free(note);
+}
+
+/*
+ * $ git notes --ref fanout list 8496071c1b46c854b31185ea97743be6a8774479
+ * 08b041783f40edfe12bb406c9c9a8a040177c125
+ */
+void test_notes_notes__creating_a_note_on_a_target_which_already_has_one_returns_EEXISTS(void)
+{
+	int error;
+	git_oid note_oid, target_oid;
+
+	cl_git_pass(git_oid_fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125"));
+
+	create_note(&note_oid, NULL, "08b041783f40edfe12bb406c9c9a8a040177c125", "hello world\n");
+	error = git_note_create(&note_oid, _repo, NULL, _sig, _sig, &target_oid, "hello world\n", 0);
+	cl_git_fail(error);
+	cl_assert_equal_i(GIT_EEXISTS, error);
+
+	create_note(&note_oid, "refs/notes/some/namespace", "08b041783f40edfe12bb406c9c9a8a040177c125", "hello world\n");
+	error = git_note_create(&note_oid, _repo, "refs/notes/some/namespace", _sig, _sig, &target_oid, "hello world\n", 0);
+	cl_git_fail(error);
+	cl_assert_equal_i(GIT_EEXISTS, error);
+}
+
+
+void test_notes_notes__creating_a_note_on_a_target_can_overwrite_existing_note(void)
+{
+	git_oid note_oid, target_oid;
+	git_note *note, *namespace_note;
+
+	cl_git_pass(git_oid_fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125"));
+
+	create_note(&note_oid, NULL, "08b041783f40edfe12bb406c9c9a8a040177c125", "hello old world\n");
+	cl_git_pass(git_note_create(&note_oid, _repo, NULL, _sig, _sig, &target_oid, "hello new world\n", 1));
+
+	cl_git_pass(git_note_read(&note, _repo, NULL, &target_oid));
+	assert_note_equal(note, "hello new world\n", &note_oid);
+
+	create_note(&note_oid, "refs/notes/some/namespace", "08b041783f40edfe12bb406c9c9a8a040177c125", "hello old world\n");
+	cl_git_pass(git_note_create(&note_oid, _repo, "refs/notes/some/namespace", _sig, _sig, &target_oid, "hello new ref world\n", 1));
+
+	cl_git_pass(git_note_read(&namespace_note, _repo, "refs/notes/some/namespace", &target_oid));
+	assert_note_equal(namespace_note, "hello new ref world\n", &note_oid);
+
+	git_note_free(note);
+	git_note_free(namespace_note);
+}
+
+static char *messages[] = {
+	"08c041783f40edfe12bb406c9c9a8a040177c125",
+	"96c45fbe09ab7445fc7c60fd8d17f32494399343",
+	"48cc7e38dcfc1ec87e70ec03e08c3e83d7a16aa1",
+	"24c3eaafb681c3df668f9df96f58e7b8c756eb04",
+	"96ca1b6ccc7858ae94684777f85ac0e7447f7040",
+	"7ac2db4378a08bb244a427c357e0082ee0d57ac6",
+	"e6cba23dbf4ef84fe35e884f017f4e24dc228572",
+	"c8cf3462c7d8feba716deeb2ebe6583bd54589e2",
+	"39c16b9834c2d665ac5f68ad91dc5b933bad8549",
+	"f3c582b1397df6a664224ebbaf9d4cc952706597",
+	"29cec67037fe8e89977474988219016ae7f342a6",
+	"36c4cd238bf8e82e27b740e0741b025f2e8c79ab",
+	"f1c45a47c02e01d5a9a326f1d9f7f756373387f8",
+	"4aca84406f5daee34ab513a60717c8d7b1763ead",
+	"84ce167da452552f63ed8407b55d5ece4901845f",
+	NULL
+};
+
+#define MESSAGES_COUNT (sizeof(messages)/sizeof(messages[0])) - 1
+
+/*
+ * $ git ls-tree refs/notes/fanout
+ * 040000 tree 4b22b35d44b5a4f589edf3dc89196399771796ea    84
+ *
+ * $ git ls-tree 4b22b35
+ * 040000 tree d71aab4f9b04b45ce09bcaa636a9be6231474759    96
+ *
+ * $ git ls-tree d71aab4
+ * 100644 blob 08b041783f40edfe12bb406c9c9a8a040177c125    071c1b46c854b31185ea97743be6a8774479
+ */
+void test_notes_notes__can_insert_a_note_in_an_existing_fanout(void)
+{
+	size_t i;
+	git_oid note_oid, target_oid;
+	git_note *_note;
+
+	cl_git_pass(git_oid_fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125"));
+	
+	for (i = 0; i <  MESSAGES_COUNT; i++) {
+		cl_git_pass(git_note_create(&note_oid, _repo, "refs/notes/fanout", _sig, _sig, &target_oid, messages[i], 0));
+		cl_git_pass(git_note_read(&_note, _repo, "refs/notes/fanout", &target_oid));
+		git_note_free(_note);
+
+		git_oid_cpy(&target_oid, &note_oid);
+	}
+}
+
+/*
+ * $ git notes --ref fanout list 8496071c1b46c854b31185ea97743be6a8774479
+ * 08b041783f40edfe12bb406c9c9a8a040177c125
+ */
+void test_notes_notes__can_read_a_note_in_an_existing_fanout(void)
+{
+	git_oid note_oid, target_oid;
+	git_note *note;
+
+	cl_git_pass(git_oid_fromstr(&target_oid, "8496071c1b46c854b31185ea97743be6a8774479"));
+	cl_git_pass(git_note_read(&note, _repo, "refs/notes/fanout", &target_oid));
+
+	cl_git_pass(git_oid_fromstr(&note_oid, "08b041783f40edfe12bb406c9c9a8a040177c125"));
+	cl_assert_equal_oid(git_note_id(note), &note_oid);
+
+	git_note_free(note);
+}
+
+void test_notes_notes__can_remove_a_note_in_an_existing_fanout(void)
+{
+	git_oid target_oid;
+	git_note *note;
+
+	cl_git_pass(git_oid_fromstr(&target_oid, "8496071c1b46c854b31185ea97743be6a8774479"));
+	cl_git_pass(git_note_remove(_repo, "refs/notes/fanout", _sig, _sig, &target_oid));
+
+	cl_git_fail(git_note_read(&note, _repo, "refs/notes/fanout", &target_oid));
+}
+
+void test_notes_notes__removing_a_note_which_doesnt_exists_returns_ENOTFOUND(void)
+{
+	int error;
+	git_oid target_oid;
+
+	cl_git_pass(git_oid_fromstr(&target_oid, "8496071c1b46c854b31185ea97743be6a8774479"));
+	cl_git_pass(git_note_remove(_repo, "refs/notes/fanout", _sig, _sig, &target_oid));
+	
+	error = git_note_remove(_repo, "refs/notes/fanout", _sig, _sig, &target_oid);
+	cl_git_fail(error);
+	cl_assert_equal_i(GIT_ENOTFOUND, error);
+}
+
+void test_notes_notes__can_iterate_default_namespace(void)
+{
+	git_note_iterator *iter;
+	git_note *note;
+	git_oid note_id, annotated_id;
+	git_oid note_created[2];
+	const char* note_message[] = {
+		"I decorate a65f\n",
+		"I decorate c478\n"
+	};
+	int i, err;
+
+	create_note(&note_created[0], "refs/notes/commits",
+		"a65fedf39aefe402d3bb6e24df4d4f5fe4547750", note_message[0]);
+	create_note(&note_created[1], "refs/notes/commits",
+		"c47800c7266a2be04c571c04d5a6614691ea99bd", note_message[1]);
+
+	cl_git_pass(git_note_iterator_new(&iter, _repo, NULL));
+
+	for (i = 0; (err = git_note_next(&note_id, &annotated_id, iter)) >= 0; ++i) {
+		cl_git_pass(git_note_read(&note, _repo, NULL, &annotated_id));
+		cl_assert_equal_s(git_note_message(note), note_message[i]);
+		git_note_free(note);
+	}
+
+	cl_assert_equal_i(GIT_ITEROVER, err);
+	cl_assert_equal_i(2, i);
+	git_note_iterator_free(iter);
+}
+
+void test_notes_notes__can_iterate_custom_namespace(void)
+{
+	git_note_iterator *iter;
+	git_note *note;
+	git_oid note_id, annotated_id;
+	git_oid note_created[2];
+	const char* note_message[] = {
+		"I decorate a65f\n",
+		"I decorate c478\n"
+	};
+	int i, err;
+
+	create_note(&note_created[0], "refs/notes/beer",
+		"a65fedf39aefe402d3bb6e24df4d4f5fe4547750", note_message[0]);
+	create_note(&note_created[1], "refs/notes/beer",
+		"c47800c7266a2be04c571c04d5a6614691ea99bd", note_message[1]);
+
+	cl_git_pass(git_note_iterator_new(&iter, _repo, "refs/notes/beer"));
+
+	for (i = 0; (err = git_note_next(&note_id, &annotated_id, iter)) >= 0; ++i) {
+		cl_git_pass(git_note_read(&note, _repo, "refs/notes/beer", &annotated_id));
+		cl_assert_equal_s(git_note_message(note), note_message[i]);
+		git_note_free(note);
+	}
+
+	cl_assert_equal_i(GIT_ITEROVER, err);
+	cl_assert_equal_i(2, i);
+	git_note_iterator_free(iter);
+}
+
+void test_notes_notes__empty_iterate(void)
+{
+	git_note_iterator *iter;
+
+	cl_git_fail(git_note_iterator_new(&iter, _repo, "refs/notes/commits"));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/notes/notesref.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/notes/notesref.c
new file mode 100755
index 0000000..4159ddc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/notes/notesref.c
@@ -0,0 +1,68 @@
+#include "clar_libgit2.h"
+
+#include "notes.h"
+#include "buffer.h"
+
+static git_repository *_repo;
+static git_note *_note;
+static git_signature *_sig;
+static git_config *_cfg;
+
+void test_notes_notesref__initialize(void)
+{
+	cl_fixture_sandbox("testrepo.git");
+	cl_git_pass(git_repository_open(&_repo, "testrepo.git"));
+}
+
+void test_notes_notesref__cleanup(void)
+{
+	git_note_free(_note);
+	_note = NULL;
+
+	git_signature_free(_sig);
+	_sig = NULL;
+
+	git_config_free(_cfg);
+	_cfg = NULL;
+
+	git_repository_free(_repo);
+	_repo = NULL;
+
+	cl_fixture_cleanup("testrepo.git");
+}
+
+void test_notes_notesref__config_corenotesref(void)
+{
+	git_oid oid, note_oid;
+	git_buf default_ref = GIT_BUF_INIT;
+
+	cl_git_pass(git_signature_now(&_sig, "alice", "alice at example.com"));
+	cl_git_pass(git_oid_fromstr(&oid, "8496071c1b46c854b31185ea97743be6a8774479"));
+
+	cl_git_pass(git_repository_config(&_cfg, _repo));
+
+	cl_git_pass(git_config_set_string(_cfg, "core.notesRef", "refs/notes/mydefaultnotesref"));
+
+	cl_git_pass(git_note_create(&note_oid, _repo, NULL, _sig, _sig, &oid, "test123test\n", 0));
+
+	cl_git_pass(git_note_read(&_note, _repo, NULL, &oid));
+	cl_assert_equal_s("test123test\n", git_note_message(_note));
+	cl_assert_equal_oid(git_note_id(_note), &note_oid);
+
+	git_note_free(_note);
+
+	cl_git_pass(git_note_read(&_note, _repo, "refs/notes/mydefaultnotesref", &oid));
+	cl_assert_equal_s("test123test\n", git_note_message(_note));
+	cl_assert_equal_oid(git_note_id(_note), &note_oid);
+
+	cl_git_pass(git_note_default_ref(&default_ref, _repo));
+	cl_assert_equal_s("refs/notes/mydefaultnotesref", default_ref.ptr);
+	git_buf_clear(&default_ref);
+
+	cl_git_pass(git_config_delete_entry(_cfg, "core.notesRef"));
+
+	cl_git_pass(git_note_default_ref(&default_ref, _repo));
+	cl_assert_equal_s(GIT_NOTES_DEFAULT_REF, default_ref.ptr);
+
+	git_buf_free(&default_ref);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/blob/filter.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/blob/filter.c
new file mode 100755
index 0000000..0aaaee6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/blob/filter.c
@@ -0,0 +1,150 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "blob.h"
+#include "buf_text.h"
+
+static git_repository *g_repo = NULL;
+
+#define CRLF_NUM_TEST_OBJECTS	9
+
+static const char *g_crlf_raw[CRLF_NUM_TEST_OBJECTS] = {
+	"",
+	"foo\nbar\n",
+	"foo\rbar\r",
+	"foo\r\nbar\r\n",
+	"foo\nbar\rboth\r\nreversed\n\ragain\nproblems\r",
+	"123\n\000\001\002\003\004abc\255\254\253\r\n",
+	"\xEF\xBB\xBFThis is UTF-8\n",
+	"\xEF\xBB\xBF\xE3\x81\xBB\xE3\x81\x92\xE3\x81\xBB\xE3\x81\x92\r\n\xE3\x81\xBB\xE3\x81\x92\xE3\x81\xBB\xE3\x81\x92\r\n",
+	"\xFE\xFF\x00T\x00h\x00i\x00s\x00!"
+};
+
+static git_off_t g_crlf_raw_len[CRLF_NUM_TEST_OBJECTS] = {
+	-1, -1, -1, -1, -1, 17, -1, -1, 12
+};
+
+static git_oid g_crlf_oids[CRLF_NUM_TEST_OBJECTS];
+
+static git_buf g_crlf_filtered[CRLF_NUM_TEST_OBJECTS] = {
+	{ "", 0, 0 },
+	{ "foo\nbar\n", 0, 8 },
+	{ "foo\rbar\r", 0, 8 },
+	{ "foo\nbar\n", 0, 8 },
+	{ "foo\nbar\rboth\nreversed\n\ragain\nproblems\r", 0, 38 },
+	{ "123\n\000\001\002\003\004abc\255\254\253\n", 0, 16 },
+	{ "\xEF\xBB\xBFThis is UTF-8\n", 0, 17 },
+	{ "\xEF\xBB\xBF\xE3\x81\xBB\xE3\x81\x92\xE3\x81\xBB\xE3\x81\x92\n\xE3\x81\xBB\xE3\x81\x92\xE3\x81\xBB\xE3\x81\x92\n", 0, 29 },
+	{ "\xFE\xFF\x00T\x00h\x00i\x00s\x00!", 0, 12 }
+};
+
+static git_buf_text_stats g_crlf_filtered_stats[CRLF_NUM_TEST_OBJECTS] = {
+	{ 0, 0, 0, 0, 0, 0, 0 },
+	{ 0, 0, 0, 2, 0, 6, 0 },
+	{ 0, 0, 2, 0, 0, 6, 0 },
+	{ 0, 0, 2, 2, 2, 6, 0 },
+	{ 0, 0, 4, 4, 1, 31, 0 },
+	{ 0, 1, 1, 2, 1, 9, 5 },
+	{ GIT_BOM_UTF8, 0, 0, 1, 0, 16, 0 },
+	{ GIT_BOM_UTF8, 0, 2, 2, 2, 27, 0 },
+	{ GIT_BOM_UTF16_BE, 5, 0, 0, 0, 7, 5 },
+};
+
+void test_object_blob_filter__initialize(void)
+{
+	int i;
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+	for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) {
+		if (g_crlf_raw_len[i] < 0)
+			g_crlf_raw_len[i] = strlen(g_crlf_raw[i]);
+
+		cl_git_pass(git_blob_create_frombuffer(
+			&g_crlf_oids[i], g_repo, g_crlf_raw[i], (size_t)g_crlf_raw_len[i]));
+	}
+}
+
+void test_object_blob_filter__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_object_blob_filter__unfiltered(void)
+{
+	int i;
+	git_blob *blob;
+
+	for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) {
+		size_t raw_len = (size_t)g_crlf_raw_len[i];
+
+		cl_git_pass(git_blob_lookup(&blob, g_repo, &g_crlf_oids[i]));
+
+		cl_assert_equal_sz(raw_len, (size_t)git_blob_rawsize(blob));
+		cl_assert_equal_i(
+			0, memcmp(g_crlf_raw[i], git_blob_rawcontent(blob), raw_len));
+
+		git_blob_free(blob);
+	}
+}
+
+void test_object_blob_filter__stats(void)
+{
+	int i;
+	git_blob *blob;
+	git_buf buf = GIT_BUF_INIT;
+	git_buf_text_stats stats;
+
+	for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) {
+		cl_git_pass(git_blob_lookup(&blob, g_repo, &g_crlf_oids[i]));
+		cl_git_pass(git_blob__getbuf(&buf, blob));
+		git_buf_text_gather_stats(&stats, &buf, false);
+		cl_assert_equal_i(
+			0, memcmp(&g_crlf_filtered_stats[i], &stats, sizeof(stats)));
+		git_blob_free(blob);
+	}
+
+	git_buf_free(&buf);
+}
+
+void test_object_blob_filter__to_odb(void)
+{
+	git_filter_list *fl = NULL;
+	git_config *cfg;
+	int i;
+	git_blob *blob;
+	git_buf out = GIT_BUF_INIT, zeroed;
+
+	cl_git_pass(git_repository_config(&cfg, g_repo));
+	cl_assert(cfg);
+
+	git_attr_cache_flush(g_repo);
+	cl_git_append2file("empty_standard_repo/.gitattributes", "*.txt text\n");
+
+	cl_git_pass(git_filter_list_load(
+		&fl, g_repo, NULL, "filename.txt", GIT_FILTER_TO_ODB, 0));
+	cl_assert(fl != NULL);
+
+	for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) {
+		cl_git_pass(git_blob_lookup(&blob, g_repo, &g_crlf_oids[i]));
+
+		/* try once with allocated blob */
+		cl_git_pass(git_filter_list_apply_to_blob(&out, fl, blob));
+		cl_assert_equal_sz(g_crlf_filtered[i].size, out.size);
+		cl_assert_equal_i(
+			0, memcmp(out.ptr, g_crlf_filtered[i].ptr, out.size));
+
+		/* try again with zeroed blob */
+		memset(&zeroed, 0, sizeof(zeroed));
+		cl_git_pass(git_filter_list_apply_to_blob(&zeroed, fl, blob));
+		cl_assert_equal_sz(g_crlf_filtered[i].size, zeroed.size);
+		cl_assert_equal_i(
+			0, memcmp(zeroed.ptr, g_crlf_filtered[i].ptr, zeroed.size));
+		git_buf_free(&zeroed);
+
+		git_blob_free(blob);
+	}
+
+	git_filter_list_free(fl);
+	git_buf_free(&out);
+	git_config_free(cfg);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/blob/fromchunks.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/blob/fromchunks.c
new file mode 100755
index 0000000..b61cabf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/blob/fromchunks.c
@@ -0,0 +1,156 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "posix.h"
+#include "path.h"
+#include "fileops.h"
+
+static git_repository *repo;
+static char textual_content[] = "libgit2\n\r\n\0";
+
+void test_object_blob_fromchunks__initialize(void)
+{
+	repo = cl_git_sandbox_init("testrepo.git");
+}
+
+void test_object_blob_fromchunks__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static int text_chunked_source_cb(char *content, size_t max_length, void *payload)
+{
+	int *count;
+
+	GIT_UNUSED(max_length);
+
+	count = (int *)payload;
+	(*count)--;
+
+	if (*count == 0)
+		return 0;
+
+	strcpy(content, textual_content);
+	return (int)strlen(textual_content);
+}
+
+void test_object_blob_fromchunks__can_create_a_blob_from_a_in_memory_chunk_provider(void)
+{
+	git_oid expected_oid, oid;
+	git_object *blob;
+	int howmany = 7;
+
+	cl_git_pass(git_oid_fromstr(&expected_oid, "321cbdf08803c744082332332838df6bd160f8f9"));
+
+	cl_git_fail_with(
+		git_object_lookup(&blob, repo, &expected_oid, GIT_OBJ_ANY),
+		GIT_ENOTFOUND);
+
+	cl_git_pass(git_blob_create_fromchunks(&oid, repo, NULL, text_chunked_source_cb, &howmany));
+
+	cl_git_pass(git_object_lookup(&blob, repo, &expected_oid, GIT_OBJ_ANY));
+	cl_assert(git_oid_cmp(&expected_oid, git_object_id(blob)) == 0);
+
+	git_object_free(blob);
+}
+
+void test_object_blob_fromchunks__doesnot_overwrite_an_already_existing_object(void)
+{
+	git_buf path = GIT_BUF_INIT;
+	git_buf content = GIT_BUF_INIT;
+	git_oid expected_oid, oid;
+	int howmany = 7;
+
+	cl_git_pass(git_oid_fromstr(&expected_oid, "321cbdf08803c744082332332838df6bd160f8f9"));
+
+	cl_git_pass(git_blob_create_fromchunks(&oid, repo, NULL, text_chunked_source_cb, &howmany));
+
+	/* Let's replace the content of the blob file storage with something else... */
+	cl_git_pass(git_buf_joinpath(&path, git_repository_path(repo), "objects/32/1cbdf08803c744082332332838df6bd160f8f9"));
+	cl_git_pass(p_unlink(git_buf_cstr(&path)));
+	cl_git_mkfile(git_buf_cstr(&path), "boom");
+
+	/* ...request a creation of the same blob... */
+	howmany = 7;
+	cl_git_pass(git_blob_create_fromchunks(&oid, repo, NULL, text_chunked_source_cb, &howmany));
+
+	/* ...and ensure the content of the faked blob file hasn't been altered */
+	cl_git_pass(git_futils_readbuffer(&content, git_buf_cstr(&path)));
+	cl_assert(!git__strcmp("boom", git_buf_cstr(&content)));
+
+	git_buf_free(&path);
+	git_buf_free(&content);
+}
+
+#define GITATTR "* text=auto\n" \
+	"*.txt text\n" \
+	"*.data binary\n"
+
+static void write_attributes(git_repository *repo)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_joinpath(&buf, git_repository_path(repo), "info"));
+	cl_git_pass(git_buf_joinpath(&buf, git_buf_cstr(&buf), "attributes"));
+
+	cl_git_pass(git_futils_mkpath2file(git_buf_cstr(&buf), 0777));
+	cl_git_rewritefile(git_buf_cstr(&buf), GITATTR);
+
+	git_buf_free(&buf);
+}
+
+static void assert_named_chunked_blob(const char *expected_sha, const char *fake_name)
+{
+	git_oid expected_oid, oid;
+	int howmany = 7;
+
+	cl_git_pass(git_oid_fromstr(&expected_oid, expected_sha));
+
+	cl_git_pass(git_blob_create_fromchunks(&oid, repo, fake_name, text_chunked_source_cb, &howmany));
+	cl_assert(git_oid_cmp(&expected_oid, &oid) == 0);
+}
+
+void test_object_blob_fromchunks__creating_a_blob_from_chunks_honors_the_attributes_directives(void)
+{
+	write_attributes(repo);
+
+	assert_named_chunked_blob("321cbdf08803c744082332332838df6bd160f8f9", "dummy.data");
+	assert_named_chunked_blob("e9671e138a780833cb689753570fd10a55be84fb", "dummy.txt");
+	assert_named_chunked_blob("e9671e138a780833cb689753570fd10a55be84fb", "dummy.dunno");
+}
+
+static int failing_chunked_source_cb(
+	char *content, size_t max_length, void *payload)
+{
+	int *count = (int *)payload;
+
+	GIT_UNUSED(max_length);
+
+	(*count)--;
+	if (*count == 0)
+		return -1234;
+
+	strcpy(content, textual_content);
+	return (int)strlen(textual_content);
+}
+
+void test_object_blob_fromchunks__can_stop_with_error(void)
+{
+	git_oid expected_oid, oid;
+	git_object *blob;
+	int howmany = 7;
+
+	cl_git_pass(git_oid_fromstr(
+		&expected_oid, "321cbdf08803c744082332332838df6bd160f8f9"));
+
+	cl_git_fail_with(
+		git_object_lookup(&blob, repo, &expected_oid, GIT_OBJ_ANY),
+		GIT_ENOTFOUND);
+
+	cl_git_fail_with(git_blob_create_fromchunks(
+		&oid, repo, NULL, failing_chunked_source_cb, &howmany), -1234);
+
+	cl_git_fail_with(
+		git_object_lookup(&blob, repo, &expected_oid, GIT_OBJ_ANY),
+		GIT_ENOTFOUND);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/blob/write.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/blob/write.c
new file mode 100755
index 0000000..203bc67
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/blob/write.c
@@ -0,0 +1,69 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "posix.h"
+#include "path.h"
+#include "fileops.h"
+
+static git_repository *repo;
+
+#define WORKDIR "empty_standard_repo"
+#define BARE_REPO "testrepo.git"
+#define ELSEWHERE "elsewhere"
+
+typedef int (*blob_creator_fn)(
+	git_oid *,
+	git_repository *,
+	const char *);
+
+void test_object_blob_write__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static void assert_blob_creation(const char *path_to_file, const char *blob_from_path, blob_creator_fn creator)
+{
+	git_oid oid;
+	cl_git_mkfile(path_to_file, "1..2...3... Can you hear me?\n");
+
+	cl_must_pass(creator(&oid, repo, blob_from_path));
+	cl_assert(git_oid_streq(&oid, "da5e4f20c91c81b44a7e298f3d3fb3fe2f178e32") == 0);
+}
+
+void test_object_blob_write__can_create_a_blob_in_a_standard_repo_from_a_file_located_in_the_working_directory(void)
+{
+	repo = cl_git_sandbox_init(WORKDIR);
+
+	assert_blob_creation(WORKDIR "/test.txt", "test.txt", &git_blob_create_fromworkdir);
+}
+
+void test_object_blob_write__can_create_a_blob_in_a_standard_repo_from_a_absolute_filepath_pointing_outside_of_the_working_directory(void)
+{
+	git_buf full_path = GIT_BUF_INIT;
+
+	repo = cl_git_sandbox_init(WORKDIR);
+
+	cl_must_pass(p_mkdir(ELSEWHERE, 0777));
+	cl_must_pass(git_path_prettify_dir(&full_path, ELSEWHERE, NULL));
+	cl_must_pass(git_buf_puts(&full_path, "test.txt"));
+
+	assert_blob_creation(ELSEWHERE "/test.txt", git_buf_cstr(&full_path), &git_blob_create_fromdisk);
+
+	git_buf_free(&full_path);
+	cl_must_pass(git_futils_rmdir_r(ELSEWHERE, NULL, GIT_RMDIR_REMOVE_FILES));
+}
+
+void test_object_blob_write__can_create_a_blob_in_a_bare_repo_from_a_absolute_filepath(void)
+{
+	git_buf full_path = GIT_BUF_INIT;
+
+	repo = cl_git_sandbox_init(BARE_REPO);
+
+	cl_must_pass(p_mkdir(ELSEWHERE, 0777));
+	cl_must_pass(git_path_prettify_dir(&full_path, ELSEWHERE, NULL));
+	cl_must_pass(git_buf_puts(&full_path, "test.txt"));
+
+	assert_blob_creation(ELSEWHERE "/test.txt", git_buf_cstr(&full_path), &git_blob_create_fromdisk);
+
+	git_buf_free(&full_path);
+	cl_must_pass(git_futils_rmdir_r(ELSEWHERE, NULL, GIT_RMDIR_REMOVE_FILES));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/cache.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/cache.c
new file mode 100755
index 0000000..bdf12da
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/cache.c
@@ -0,0 +1,287 @@
+#include "clar_libgit2.h"
+#include "repository.h"
+
+static git_repository *g_repo;
+
+void test_object_cache__initialize(void)
+{
+	g_repo = NULL;
+}
+
+void test_object_cache__cleanup(void)
+{
+	git_repository_free(g_repo);
+	g_repo = NULL;
+
+	git_libgit2_opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, (int)GIT_OBJ_BLOB, (size_t)0);
+}
+
+static struct {
+	git_otype type;
+	const char *sha;
+} g_data[] = {
+	/* HEAD */
+	{ GIT_OBJ_BLOB, "a8233120f6ad708f843d861ce2b7228ec4e3dec6" }, /* README */
+	{ GIT_OBJ_BLOB, "3697d64be941a53d4ae8f6a271e4e3fa56b022cc" }, /* branch_file.txt */
+	{ GIT_OBJ_BLOB, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd" }, /* new.txt */
+
+	/* refs/heads/subtrees */
+	{ GIT_OBJ_BLOB, "1385f264afb75a56a5bec74243be9b367ba4ca08" }, /* README */
+	{ GIT_OBJ_TREE, "f1425cef211cc08caa31e7b545ffb232acb098c3" }, /* ab */
+	{ GIT_OBJ_BLOB, "d6c93164c249c8000205dd4ec5cbca1b516d487f" }, /* ab/4.txt */
+	{ GIT_OBJ_TREE, "9a03079b8a8ee85a0bee58bf9be3da8b62414ed4" }, /* ab/c */
+	{ GIT_OBJ_BLOB, "270b8ea76056d5cad83af921837702d3e3c2924d" }, /* ab/c/3.txt */
+	{ GIT_OBJ_TREE, "b6361fc6a97178d8fc8639fdeed71c775ab52593" }, /* ab/de */
+	{ GIT_OBJ_BLOB, "e7b4ad382349ff96dd8199000580b9b1e2042eb0" }, /* ab/de/2.txt */
+	{ GIT_OBJ_TREE, "3259a6bd5b57fb9c1281bb7ed3167b50f224cb54" }, /* ab/de/fgh */
+	{ GIT_OBJ_BLOB, "1f67fc4386b2d171e0d21be1c447e12660561f9b" }, /* ab/de/fgh/1.txt */
+	{ GIT_OBJ_BLOB, "45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, /* branch_file.txt */
+	{ GIT_OBJ_BLOB, "fa49b077972391ad58037050f2a75f74e3671e92" }, /* new.txt */
+
+	/* refs/heads/chomped */
+	{ GIT_OBJ_BLOB, "0266163a49e280c4f5ed1e08facd36a2bd716bcf" }, /* readme.txt */
+
+	{ 0, NULL },
+	{ 0, NULL }
+};
+
+void test_object_cache__cache_everything(void)
+{
+	int i, start;
+	git_oid oid;
+	git_odb_object *odb_obj;
+	git_object *obj;
+	git_odb *odb;
+
+	git_libgit2_opts(
+		GIT_OPT_SET_CACHE_OBJECT_LIMIT, (int)GIT_OBJ_BLOB, (size_t)32767);
+
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
+	cl_git_pass(git_repository_odb(&odb, g_repo));
+
+	start = (int)git_cache_size(&g_repo->objects);
+
+	for (i = 0; g_data[i].sha != NULL; ++i) {
+		int count = (int)git_cache_size(&g_repo->objects);
+
+		cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
+
+		/* alternate between loading raw and parsed objects */
+		if ((i & 1) == 0) {
+			cl_git_pass(git_odb_read(&odb_obj, odb, &oid));
+			cl_assert(g_data[i].type == git_odb_object_type(odb_obj));
+			git_odb_object_free(odb_obj);
+		} else {
+			cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+			cl_assert(g_data[i].type == git_object_type(obj));
+			git_object_free(obj);
+		}
+
+		cl_assert_equal_i(count + 1, (int)git_cache_size(&g_repo->objects));
+	}
+
+	cl_assert_equal_i(i, (int)git_cache_size(&g_repo->objects) - start);
+
+	git_odb_free(odb);
+
+	for (i = 0; g_data[i].sha != NULL; ++i) {
+		int count = (int)git_cache_size(&g_repo->objects);
+
+		cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
+		cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+		cl_assert(g_data[i].type == git_object_type(obj));
+		git_object_free(obj);
+
+		cl_assert_equal_i(count, (int)git_cache_size(&g_repo->objects));
+	}
+}
+
+void test_object_cache__cache_no_blobs(void)
+{
+	int i, start, nonblobs = 0;
+	git_oid oid;
+	git_odb_object *odb_obj;
+	git_object *obj;
+	git_odb *odb;
+
+	git_libgit2_opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, (int)GIT_OBJ_BLOB, (size_t)0);
+
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
+	cl_git_pass(git_repository_odb(&odb, g_repo));
+
+	start = (int)git_cache_size(&g_repo->objects);
+
+	for (i = 0; g_data[i].sha != NULL; ++i) {
+		int count = (int)git_cache_size(&g_repo->objects);
+
+		cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
+
+		/* alternate between loading raw and parsed objects */
+		if ((i & 1) == 0) {
+			cl_git_pass(git_odb_read(&odb_obj, odb, &oid));
+			cl_assert(g_data[i].type == git_odb_object_type(odb_obj));
+			git_odb_object_free(odb_obj);
+		} else {
+			cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+			cl_assert(g_data[i].type == git_object_type(obj));
+			git_object_free(obj);
+		}
+
+		if (g_data[i].type == GIT_OBJ_BLOB)
+			cl_assert_equal_i(count, (int)git_cache_size(&g_repo->objects));
+		else {
+			cl_assert_equal_i(count + 1, (int)git_cache_size(&g_repo->objects));
+			nonblobs++;
+		}
+	}
+
+	cl_assert_equal_i(nonblobs, (int)git_cache_size(&g_repo->objects) - start);
+
+	git_odb_free(odb);
+}
+
+static void *cache_parsed(void *arg)
+{
+	int i;
+	git_oid oid;
+	git_object *obj;
+
+	for (i = ((int *)arg)[1]; g_data[i].sha != NULL; i += 2) {
+		cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
+		cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+		cl_assert(g_data[i].type == git_object_type(obj));
+		git_object_free(obj);
+	}
+
+	for (i = 0; i < ((int *)arg)[1]; i += 2) {
+		cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
+		cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+		cl_assert(g_data[i].type == git_object_type(obj));
+		git_object_free(obj);
+	}
+
+	return arg;
+}
+
+static void *cache_raw(void *arg)
+{
+	int i;
+	git_oid oid;
+	git_odb *odb;
+	git_odb_object *odb_obj;
+
+	cl_git_pass(git_repository_odb(&odb, g_repo));
+
+	for (i = ((int *)arg)[1]; g_data[i].sha != NULL; i += 2) {
+		cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
+		cl_git_pass(git_odb_read(&odb_obj, odb, &oid));
+		cl_assert(g_data[i].type == git_odb_object_type(odb_obj));
+		git_odb_object_free(odb_obj);
+	}
+
+	for (i = 0; i < ((int *)arg)[1]; i += 2) {
+		cl_git_pass(git_oid_fromstr(&oid, g_data[i].sha));
+		cl_git_pass(git_odb_read(&odb_obj, odb, &oid));
+		cl_assert(g_data[i].type == git_odb_object_type(odb_obj));
+		git_odb_object_free(odb_obj);
+	}
+
+	git_odb_free(odb);
+
+	return arg;
+}
+
+#define REPEAT 20
+#define THREADCOUNT 50
+
+void test_object_cache__threadmania(void)
+{
+	int try, th, max_i;
+	void *data;
+	void *(*fn)(void *);
+
+#ifdef GIT_THREADS
+	git_thread t[THREADCOUNT];
+#endif
+
+	for (max_i = 0; g_data[max_i].sha != NULL; ++max_i)
+		/* count up */;
+
+	for (try = 0; try < REPEAT; ++try) {
+
+		cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
+
+		for (th = 0; th < THREADCOUNT; ++th) {
+			data = git__malloc(2 * sizeof(int));
+
+			((int *)data)[0] = th;
+			((int *)data)[1] = th % max_i;
+
+			fn = (th & 1) ? cache_parsed : cache_raw;
+
+#ifdef GIT_THREADS
+			cl_git_pass(git_thread_create(&t[th], NULL, fn, data));
+#else
+			cl_assert(fn(data) == data);
+			git__free(data);
+#endif
+		}
+
+#ifdef GIT_THREADS
+		for (th = 0; th < THREADCOUNT; ++th) {
+			cl_git_pass(git_thread_join(&t[th], &data));
+			cl_assert_equal_i(th, ((int *)data)[0]);
+			git__free(data);
+		}
+#endif
+
+		git_repository_free(g_repo);
+		g_repo = NULL;
+	}
+}
+
+static void *cache_quick(void *arg)
+{
+	git_oid oid;
+	git_object *obj;
+
+	cl_git_pass(git_oid_fromstr(&oid, g_data[4].sha));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+	cl_assert(g_data[4].type == git_object_type(obj));
+	git_object_free(obj);
+
+	return arg;
+}
+
+void test_object_cache__fast_thread_rush(void)
+{
+	int try, th, data[THREADCOUNT*2];
+#ifdef GIT_THREADS
+	git_thread t[THREADCOUNT*2];
+#endif
+
+	for (try = 0; try < REPEAT; ++try) {
+		cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
+
+		for (th = 0; th < THREADCOUNT*2; ++th) {
+			data[th] = th;
+#ifdef GIT_THREADS
+			cl_git_pass(
+				git_thread_create(&t[th], NULL, cache_quick, &data[th]));
+#else
+			cl_assert(cache_quick(&data[th]) == &data[th]);
+#endif
+		}
+
+#ifdef GIT_THREADS
+		for (th = 0; th < THREADCOUNT*2; ++th) {
+			void *rval;
+			cl_git_pass(git_thread_join(&t[th], &rval));
+			cl_assert_equal_i(th, *((int *)rval));
+		}
+#endif
+
+		git_repository_free(g_repo);
+		g_repo = NULL;
+	}
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/commit/commitstagedfile.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/commit/commitstagedfile.c
new file mode 100755
index 0000000..5b48519
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/commit/commitstagedfile.c
@@ -0,0 +1,219 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+
+static git_repository *repo;
+
+void test_object_commit_commitstagedfile__initialize(void)
+{
+	cl_fixture("treebuilder");
+	cl_git_pass(git_repository_init(&repo, "treebuilder/", 0));
+	cl_assert(repo != NULL);
+}
+
+void test_object_commit_commitstagedfile__cleanup(void)
+{
+	git_repository_free(repo);
+	repo = NULL;
+
+	cl_fixture_cleanup("treebuilder");
+}
+
+void test_object_commit_commitstagedfile__generate_predictable_object_ids(void)
+{
+	git_index *index;
+	const git_index_entry *entry;
+	git_oid expected_blob_oid, tree_oid, expected_tree_oid, commit_oid, expected_commit_oid;
+	git_signature *signature;
+	git_tree *tree;
+	git_buf buffer;
+
+	/*
+	 * The test below replicates the following git scenario
+	 *
+	 * $ echo "test" > test.txt
+	 * $ git hash-object test.txt
+	 * 9daeafb9864cf43055ae93beb0afd6c7d144bfa4
+	 *
+	 * $ git add .
+	 * $ git commit -m "Initial commit"
+	 *
+	 * $ git log
+	 * commit 1fe3126578fc4eca68c193e4a3a0a14a0704624d
+	 * Author: nulltoken <emeric.fermas at gmail.com>
+	 * Date:   Wed Dec 14 08:29:03 2011 +0100
+	 *
+	 *     Initial commit
+	 *
+	 * $ git show 1fe3 --format=raw
+	 * commit 1fe3126578fc4eca68c193e4a3a0a14a0704624d
+	 * tree 2b297e643c551e76cfa1f93810c50811382f9117
+	 * author nulltoken <emeric.fermas at gmail.com> 1323847743 +0100
+	 * committer nulltoken <emeric.fermas at gmail.com> 1323847743 +0100
+	 * 
+	 *     Initial commit
+	 * 
+	 * diff --git a/test.txt b/test.txt
+	 * new file mode 100644
+	 * index 0000000..9daeafb
+	 * --- /dev/null
+	 * +++ b/test.txt
+	 * @@ -0,0 +1 @@
+	 * +test
+	 *
+	 * $ git ls-tree 2b297
+	 * 100644 blob 9daeafb9864cf43055ae93beb0afd6c7d144bfa4    test.txt
+	 */
+
+	cl_git_pass(git_oid_fromstr(&expected_commit_oid, "1fe3126578fc4eca68c193e4a3a0a14a0704624d"));
+	cl_git_pass(git_oid_fromstr(&expected_tree_oid, "2b297e643c551e76cfa1f93810c50811382f9117"));
+	cl_git_pass(git_oid_fromstr(&expected_blob_oid, "9daeafb9864cf43055ae93beb0afd6c7d144bfa4"));
+
+	/*
+	 * Add a new file to the index
+	 */
+	cl_git_mkfile("treebuilder/test.txt", "test\n");
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_add_bypath(index, "test.txt"));
+
+	entry = git_index_get_byindex(index, 0);
+
+	cl_assert(git_oid_cmp(&expected_blob_oid, &entry->id) == 0);
+
+	/*
+	 * Information about index entry should match test file
+	 */
+	{
+		struct stat st;
+		cl_must_pass(p_lstat("treebuilder/test.txt", &st));
+		cl_assert(entry->file_size == st.st_size);
+#ifndef _WIN32
+		/*
+		 * Windows doesn't populate these fields, and the signage is
+		 * wrong in the Windows version of the struct, so lets avoid
+		 * the "comparing signed and unsigned" compilation warning in
+		 * that case.
+		 */
+		cl_assert(entry->uid == st.st_uid);
+		cl_assert(entry->gid == st.st_gid);
+#endif
+	}
+
+	/*
+	 * Build the tree from the index
+	 */
+	cl_git_pass(git_index_write_tree(&tree_oid, index));
+
+	cl_assert(git_oid_cmp(&expected_tree_oid, &tree_oid) == 0);
+
+	/*
+	 * Commit the staged file
+	 */
+	cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas at gmail.com", 1323847743, 60));
+	cl_git_pass(git_tree_lookup(&tree, repo, &tree_oid));
+
+	memset(&buffer, 0, sizeof(git_buf));
+	cl_git_pass(git_message_prettify(&buffer, "Initial commit", 0, '#'));
+
+	cl_git_pass(git_commit_create_v(
+		&commit_oid,
+		repo,
+		"HEAD",
+		signature,
+		signature,
+		NULL,
+		buffer.ptr,
+		tree,
+		0));
+
+	cl_assert(git_oid_cmp(&expected_commit_oid, &commit_oid) == 0);
+
+	git_buf_free(&buffer);
+	git_signature_free(signature);
+	git_tree_free(tree);
+	git_index_free(index);
+}
+
+static void assert_commit_tree_has_n_entries(git_commit *c, int count)
+{
+	git_tree *tree;
+	cl_git_pass(git_commit_tree(&tree, c));
+	cl_assert_equal_i(count, git_tree_entrycount(tree));
+	git_tree_free(tree);
+}
+
+static void assert_commit_is_head_(git_commit *c, const char *file, int line)
+{
+	git_commit *head;
+	cl_git_pass(git_revparse_single((git_object **)&head, repo, "HEAD"));
+	clar__assert(git_oid_equal(git_commit_id(c), git_commit_id(head)), file, line, "Commit is not the HEAD", NULL, 1);
+	git_commit_free(head);
+}
+#define assert_commit_is_head(C) assert_commit_is_head_((C),__FILE__,__LINE__)
+
+void test_object_commit_commitstagedfile__amend_commit(void)
+{
+	git_index *index;
+	git_oid old_oid, new_oid, tree_oid;
+	git_commit *old_commit, *new_commit;
+	git_tree *tree;
+
+	/* make a commit */
+
+	cl_git_mkfile("treebuilder/myfile", "This is a file\n");
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_add_bypath(index, "myfile"));
+	cl_repo_commit_from_index(&old_oid, repo, NULL, 0, "first commit");
+
+	cl_git_pass(git_commit_lookup(&old_commit, repo, &old_oid));
+
+	cl_assert_equal_i(0, git_commit_parentcount(old_commit));
+	assert_commit_tree_has_n_entries(old_commit, 1);
+	assert_commit_is_head(old_commit);
+
+	/* let's amend the message of the HEAD commit */
+
+	cl_git_pass(git_commit_amend(
+		&new_oid, old_commit, "HEAD", NULL, NULL, NULL, "Initial commit", NULL));
+
+	/* fail because the commit isn't the tip of the branch anymore */
+	cl_git_fail(git_commit_amend(
+		&new_oid, old_commit, "HEAD", NULL, NULL, NULL, "Initial commit", NULL));
+
+	cl_git_pass(git_commit_lookup(&new_commit, repo, &new_oid));
+
+	cl_assert_equal_i(0, git_commit_parentcount(new_commit));
+	assert_commit_tree_has_n_entries(new_commit, 1);
+	assert_commit_is_head(new_commit);
+
+	git_commit_free(old_commit);
+
+	old_commit = new_commit;
+
+	/* let's amend the tree of that last commit */
+
+	cl_git_mkfile("treebuilder/anotherfile", "This is another file\n");
+	cl_git_pass(git_index_add_bypath(index, "anotherfile"));
+	cl_git_pass(git_index_write_tree(&tree_oid, index));
+	cl_git_pass(git_tree_lookup(&tree, repo, &tree_oid));
+	cl_assert_equal_i(2, git_tree_entrycount(tree));
+
+	/* fail to amend on a ref which does not exist */
+	cl_git_fail_with(GIT_ENOTFOUND, git_commit_amend(
+		&new_oid, old_commit, "refs/heads/nope", NULL, NULL, NULL, "Initial commit", tree));
+
+	cl_git_pass(git_commit_amend(
+		&new_oid, old_commit, "HEAD", NULL, NULL, NULL, "Initial commit", tree));
+	git_tree_free(tree);
+
+	cl_git_pass(git_commit_lookup(&new_commit, repo, &new_oid));
+
+	cl_assert_equal_i(0, git_commit_parentcount(new_commit));
+	assert_commit_tree_has_n_entries(new_commit, 2);
+	assert_commit_is_head(new_commit);
+
+	/* cleanup */
+
+	git_commit_free(old_commit);
+	git_commit_free(new_commit);
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/lookup.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/lookup.c
new file mode 100755
index 0000000..cfa6d46
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/lookup.c
@@ -0,0 +1,65 @@
+#include "clar_libgit2.h"
+
+#include "repository.h"
+
+static git_repository *g_repo;
+
+void test_object_lookup__initialize(void)
+{
+   cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
+}
+
+void test_object_lookup__cleanup(void)
+{
+	git_repository_free(g_repo);
+	g_repo = NULL;
+}
+
+void test_object_lookup__lookup_wrong_type_returns_enotfound(void)
+{
+	const char *commit = "e90810b8df3e80c413d903f631643c716887138d";
+	git_oid oid;
+	git_object *object;
+
+	cl_git_pass(git_oid_fromstr(&oid, commit));
+	cl_assert_equal_i(
+		GIT_ENOTFOUND, git_object_lookup(&object, g_repo, &oid, GIT_OBJ_TAG));
+}
+
+void test_object_lookup__lookup_nonexisting_returns_enotfound(void)
+{
+	const char *unknown = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
+	git_oid oid;
+	git_object *object;
+
+	cl_git_pass(git_oid_fromstr(&oid, unknown));
+	cl_assert_equal_i(
+		GIT_ENOTFOUND, git_object_lookup(&object, g_repo, &oid, GIT_OBJ_ANY));
+}
+
+void test_object_lookup__lookup_wrong_type_by_abbreviated_id_returns_enotfound(void)
+{
+	const char *commit = "e90810b";
+	git_oid oid;
+	git_object *object;
+
+	cl_git_pass(git_oid_fromstrn(&oid, commit, strlen(commit)));
+	cl_assert_equal_i(
+		GIT_ENOTFOUND, git_object_lookup_prefix(&object, g_repo, &oid, strlen(commit), GIT_OBJ_TAG));
+}
+
+void test_object_lookup__lookup_wrong_type_eventually_returns_enotfound(void)
+{
+	const char *commit = "e90810b8df3e80c413d903f631643c716887138d";
+	git_oid oid;
+	git_object *object;
+
+	cl_git_pass(git_oid_fromstr(&oid, commit));
+
+	cl_git_pass(git_object_lookup(&object, g_repo, &oid, GIT_OBJ_COMMIT));
+	git_object_free(object);
+
+	cl_assert_equal_i(
+		GIT_ENOTFOUND, git_object_lookup(&object, g_repo, &oid, GIT_OBJ_TAG));
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/lookupbypath.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/lookupbypath.c
new file mode 100755
index 0000000..13cd6a1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/lookupbypath.c
@@ -0,0 +1,83 @@
+#include "clar_libgit2.h"
+
+#include "repository.h"
+
+static git_repository *g_repo;
+static git_tree *g_root_tree;
+static git_commit *g_head_commit;
+static git_object *g_expectedobject,
+						*g_actualobject;
+
+void test_object_lookupbypath__initialize(void)
+{
+	git_reference *head;
+	git_tree_entry *tree_entry;
+
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("attr/.gitted")));
+
+	cl_git_pass(git_repository_head(&head, g_repo));
+	cl_git_pass(git_reference_peel((git_object**)&g_head_commit, head, GIT_OBJ_COMMIT));
+	cl_git_pass(git_commit_tree(&g_root_tree, g_head_commit));
+	cl_git_pass(git_tree_entry_bypath(&tree_entry, g_root_tree, "subdir/subdir_test2.txt"));
+	cl_git_pass(git_object_lookup(&g_expectedobject, g_repo, git_tree_entry_id(tree_entry),
+				GIT_OBJ_ANY));
+
+	git_tree_entry_free(tree_entry);
+	git_reference_free(head);
+
+	g_actualobject = NULL;
+}
+void test_object_lookupbypath__cleanup(void)
+{
+	git_object_free(g_actualobject);
+	git_object_free(g_expectedobject);
+	git_tree_free(g_root_tree);
+	git_commit_free(g_head_commit);
+	g_expectedobject = NULL;
+	git_repository_free(g_repo);
+	g_repo = NULL;
+}
+
+void test_object_lookupbypath__errors(void)
+{
+	cl_assert_equal_i(GIT_EINVALIDSPEC,
+			git_object_lookup_bypath(&g_actualobject, (git_object*)g_root_tree,
+				"subdir/subdir_test2.txt", GIT_OBJ_TREE)); // It's not a tree
+	cl_assert_equal_i(GIT_ENOTFOUND,
+			git_object_lookup_bypath(&g_actualobject, (git_object*)g_root_tree,
+				"file/doesnt/exist", GIT_OBJ_ANY));
+}
+
+void test_object_lookupbypath__from_root_tree(void)
+{
+	cl_git_pass(git_object_lookup_bypath(&g_actualobject, (git_object*)g_root_tree,
+				"subdir/subdir_test2.txt", GIT_OBJ_BLOB));
+	cl_assert_equal_oid(git_object_id(g_expectedobject),
+		git_object_id(g_actualobject));
+}
+
+void test_object_lookupbypath__from_head_commit(void)
+{
+	cl_git_pass(git_object_lookup_bypath(&g_actualobject, (git_object*)g_head_commit,
+				"subdir/subdir_test2.txt", GIT_OBJ_BLOB));
+	cl_assert_equal_oid(git_object_id(g_expectedobject),
+				git_object_id(g_actualobject));
+}
+
+void test_object_lookupbypath__from_subdir_tree(void)
+{
+	git_tree_entry *entry = NULL;
+	git_tree *tree = NULL;
+
+	cl_git_pass(git_tree_entry_bypath(&entry, g_root_tree, "subdir"));
+	cl_git_pass(git_tree_lookup(&tree, g_repo, git_tree_entry_id(entry)));
+
+	cl_git_pass(git_object_lookup_bypath(&g_actualobject, (git_object*)tree,
+				"subdir_test2.txt", GIT_OBJ_BLOB));
+	cl_assert_equal_oid(git_object_id(g_expectedobject),
+				git_object_id(g_actualobject));
+
+	git_tree_entry_free(entry);
+	git_tree_free(tree);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/message.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/message.c
new file mode 100755
index 0000000..40d8e72
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/message.c
@@ -0,0 +1,199 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "message.h"
+
+static void assert_message_prettifying(char *expected_output, char *input, int strip_comments)
+{
+	git_buf prettified_message = GIT_BUF_INIT;
+
+	git_message_prettify(&prettified_message, input, strip_comments, '#');
+	cl_assert_equal_s(expected_output, git_buf_cstr(&prettified_message));
+
+	git_buf_free(&prettified_message);
+}
+
+#define t40 "A quick brown fox jumps over the lazy do"
+#define s40 "                                        "
+#define sss s40 s40 s40 s40 s40 s40 s40 s40 s40 s40 // # 400
+#define ttt t40 t40 t40 t40 t40 t40 t40 t40 t40 t40 // # 400
+
+/* Ported from git.git */
+/* see https://github.com/git/git/blob/master/t/t0030-stripspace.sh */
+void test_object_message__long_lines_without_spaces_should_be_unchanged(void)
+{
+	assert_message_prettifying(ttt "\n", ttt, 0);
+	assert_message_prettifying(ttt ttt "\n", ttt ttt, 0);
+	assert_message_prettifying(ttt ttt ttt "\n", ttt ttt ttt, 0);
+	assert_message_prettifying(ttt ttt ttt ttt "\n", ttt ttt ttt ttt, 0);
+}
+
+void test_object_message__lines_with_spaces_at_the_beginning_should_be_unchanged(void)
+{
+	assert_message_prettifying(sss ttt "\n", sss ttt, 0);
+	assert_message_prettifying(sss sss ttt "\n", sss sss ttt, 0);
+	assert_message_prettifying(sss sss sss ttt "\n", sss sss sss ttt, 0);
+}
+
+void test_object_message__lines_with_intermediate_spaces_should_be_unchanged(void)
+{
+	assert_message_prettifying(ttt sss ttt "\n", ttt sss ttt, 0);
+	assert_message_prettifying(ttt sss sss ttt "\n", ttt sss sss ttt, 0);
+}
+
+void test_object_message__consecutive_blank_lines_should_be_unified(void)
+{
+	assert_message_prettifying(ttt "\n\n" ttt "\n", ttt "\n\n\n\n\n" ttt "\n", 0);
+	assert_message_prettifying(ttt ttt "\n\n" ttt "\n", ttt ttt "\n\n\n\n\n" ttt "\n", 0);
+	assert_message_prettifying(ttt ttt ttt "\n\n" ttt "\n", ttt ttt ttt "\n\n\n\n\n" ttt "\n", 0);
+
+	assert_message_prettifying(ttt "\n\n" ttt ttt "\n", ttt "\n\n\n\n\n" ttt ttt "\n", 0);
+	assert_message_prettifying(ttt "\n\n" ttt ttt ttt "\n", ttt "\n\n\n\n\n" ttt ttt ttt "\n", 0);
+
+	assert_message_prettifying(ttt "\n\n" ttt "\n", ttt "\n\t\n \n\n  \t\t\n" ttt "\n", 0);
+	assert_message_prettifying(ttt ttt "\n\n" ttt "\n", ttt ttt "\n\t\n \n\n  \t\t\n" ttt "\n", 0);
+	assert_message_prettifying(ttt ttt ttt "\n\n" ttt "\n", ttt ttt ttt "\n\t\n \n\n  \t\t\n" ttt "\n", 0);
+
+	assert_message_prettifying(ttt "\n\n" ttt ttt "\n", ttt "\n\t\n \n\n  \t\t\n" ttt ttt "\n", 0);
+	assert_message_prettifying(ttt "\n\n" ttt ttt ttt "\n", ttt "\n\t\n \n\n  \t\t\n" ttt ttt ttt "\n", 0);
+}
+
+void test_object_message__only_consecutive_blank_lines_should_be_completely_removed(void)
+{
+	assert_message_prettifying("", "\n", 0);
+	assert_message_prettifying("", "\n\n\n", 0);
+	assert_message_prettifying("", sss "\n" sss "\n" sss "\n", 0);
+	assert_message_prettifying("", sss sss "\n" sss "\n\n", 0);
+}
+
+void test_object_message__consecutive_blank_lines_at_the_beginning_should_be_removed(void)
+{
+	assert_message_prettifying(ttt "\n", "\n" ttt "\n", 0);
+	assert_message_prettifying(ttt "\n", "\n\n\n" ttt "\n", 0);
+	assert_message_prettifying(ttt ttt "\n", "\n\n\n" ttt ttt "\n", 0);
+	assert_message_prettifying(ttt ttt ttt "\n", "\n\n\n" ttt ttt ttt "\n", 0);
+	assert_message_prettifying(ttt ttt ttt ttt "\n", "\n\n\n" ttt ttt ttt ttt "\n", 0);
+	assert_message_prettifying(ttt "\n", sss "\n" sss "\n" sss "\n" ttt "\n", 0);
+	assert_message_prettifying(ttt "\n", "\n" sss "\n" sss sss "\n" ttt "\n", 0);
+	assert_message_prettifying(ttt "\n", sss sss "\n" sss "\n\n" ttt "\n", 0);
+	assert_message_prettifying(ttt "\n", sss sss sss "\n\n\n" ttt "\n", 0);
+	assert_message_prettifying(ttt "\n", "\n" sss sss sss "\n\n" ttt "\n", 0);
+	assert_message_prettifying(ttt "\n", "\n\n" sss sss sss "\n" ttt "\n", 0);
+}
+
+void test_object_message__consecutive_blank_lines_at_the_end_should_be_removed(void)
+{
+	assert_message_prettifying(ttt "\n", ttt "\n\n", 0);
+	assert_message_prettifying(ttt "\n", ttt "\n\n\n\n", 0);
+	assert_message_prettifying(ttt ttt "\n", ttt ttt "\n\n\n\n", 0);
+	assert_message_prettifying(ttt ttt ttt "\n", ttt ttt ttt "\n\n\n\n", 0);
+	assert_message_prettifying(ttt ttt ttt ttt "\n", ttt ttt ttt ttt "\n\n\n\n", 0);
+	assert_message_prettifying(ttt "\n", ttt "\n" sss "\n" sss "\n" sss "\n", 0);
+	assert_message_prettifying(ttt "\n", ttt "\n\n" sss "\n" sss sss "\n", 0);
+	assert_message_prettifying(ttt "\n", ttt "\n" sss sss "\n" sss "\n\n", 0);
+	assert_message_prettifying(ttt "\n", ttt "\n" sss sss sss "\n\n\n", 0);
+	assert_message_prettifying(ttt "\n", ttt "\n\n" sss sss sss "\n\n", 0);
+	assert_message_prettifying(ttt "\n", ttt "\n\n\n" sss sss sss "\n\n", 0);
+}
+
+void test_object_message__text_without_newline_at_end_should_end_with_newline(void)
+{
+	assert_message_prettifying(ttt "\n", ttt, 0);
+	assert_message_prettifying(ttt ttt "\n", ttt ttt, 0);
+	assert_message_prettifying(ttt ttt ttt "\n", ttt ttt ttt, 0);
+	assert_message_prettifying(ttt ttt ttt ttt "\n", ttt ttt ttt ttt, 0);
+}
+
+void test_object_message__text_plus_spaces_without_newline_should_not_show_spaces_and_end_with_newline(void)
+{
+	assert_message_prettifying(ttt "\n", ttt sss, 0);
+	assert_message_prettifying(ttt ttt "\n", ttt ttt sss, 0);
+	assert_message_prettifying(ttt ttt ttt "\n", ttt ttt ttt sss, 0);
+	assert_message_prettifying(ttt "\n", ttt sss sss, 0);
+	assert_message_prettifying(ttt ttt "\n", ttt ttt sss sss, 0);
+	assert_message_prettifying(ttt "\n", ttt sss sss sss, 0);
+}
+
+void test_object_message__text_plus_spaces_ending_with_newline_should_be_cleaned_and_newline_must_remain(void){
+	assert_message_prettifying(ttt "\n", ttt sss "\n", 0);
+	assert_message_prettifying(ttt "\n", ttt sss sss "\n", 0);
+	assert_message_prettifying(ttt "\n", ttt sss sss sss "\n", 0);
+	assert_message_prettifying(ttt ttt "\n", ttt ttt sss "\n", 0);
+	assert_message_prettifying(ttt ttt "\n", ttt ttt sss sss "\n", 0);
+	assert_message_prettifying(ttt ttt ttt "\n", ttt ttt ttt sss "\n", 0);
+}
+
+void test_object_message__spaces_with_newline_at_end_should_be_replaced_with_empty_string(void)
+{
+	assert_message_prettifying("", sss "\n", 0);
+	assert_message_prettifying("", sss sss "\n", 0);
+	assert_message_prettifying("", sss sss sss "\n", 0);
+	assert_message_prettifying("", sss sss sss sss "\n", 0);
+}
+
+void test_object_message__spaces_without_newline_at_end_should_be_replaced_with_empty_string(void)
+{
+	assert_message_prettifying("", "", 0);
+	assert_message_prettifying("", sss sss, 0);
+	assert_message_prettifying("", sss sss sss, 0);
+	assert_message_prettifying("", sss sss sss sss, 0);
+}
+
+void test_object_message__consecutive_text_lines_should_be_unchanged(void)
+{
+	assert_message_prettifying(ttt ttt "\n" ttt "\n", ttt ttt "\n" ttt "\n", 0);
+	assert_message_prettifying(ttt "\n" ttt ttt "\n" ttt "\n", ttt "\n" ttt ttt "\n" ttt "\n", 0);
+	assert_message_prettifying(ttt "\n" ttt "\n" ttt "\n" ttt ttt "\n", ttt "\n" ttt "\n" ttt "\n" ttt ttt "\n", 0);
+	assert_message_prettifying(ttt "\n" ttt "\n\n" ttt ttt "\n" ttt "\n", ttt "\n" ttt "\n\n" ttt ttt "\n" ttt "\n", 0);
+	assert_message_prettifying(ttt ttt "\n\n" ttt "\n" ttt ttt "\n", ttt ttt "\n\n" ttt "\n" ttt ttt "\n", 0);
+	assert_message_prettifying(ttt "\n" ttt ttt "\n\n" ttt "\n", ttt "\n" ttt ttt "\n\n" ttt "\n", 0);
+}
+
+void test_object_message__strip_comments(void)
+{
+	assert_message_prettifying("", "# comment", 1);
+	assert_message_prettifying("", "# comment\n", 1);
+	assert_message_prettifying("", "# comment    \n", 1);
+
+	assert_message_prettifying(ttt "\n", ttt "\n" "# comment\n", 1);
+	assert_message_prettifying(ttt "\n", "# comment\n" ttt "\n", 1);
+	assert_message_prettifying(ttt "\n" ttt "\n", ttt "\n" "# comment\n" ttt "\n", 1);
+}
+
+void test_object_message__keep_comments(void)
+{
+	assert_message_prettifying("# comment\n", "# comment", 0);
+	assert_message_prettifying("# comment\n", "# comment\n", 0);
+	assert_message_prettifying("# comment\n", "# comment    \n", 0);
+
+	assert_message_prettifying(ttt "\n" "# comment\n", ttt "\n" "# comment\n", 0);
+	assert_message_prettifying("# comment\n" ttt "\n", "# comment\n" ttt "\n", 0);
+	assert_message_prettifying(ttt "\n" "# comment\n" ttt "\n", ttt "\n" "# comment\n" ttt "\n", 0);
+}
+
+void test_object_message__message_prettify(void)
+{
+	git_buf buffer;
+
+	memset(&buffer, 0, sizeof(buffer));
+	cl_git_pass(git_message_prettify(&buffer, "", 0, '#'));
+	cl_assert_equal_s(buffer.ptr, "");
+	git_buf_free(&buffer);
+	cl_git_pass(git_message_prettify(&buffer, "", 1, '#'));
+	cl_assert_equal_s(buffer.ptr, "");
+	git_buf_free(&buffer);
+
+	cl_git_pass(git_message_prettify(&buffer, "Short", 0, '#'));
+	cl_assert_equal_s("Short\n", buffer.ptr);
+	git_buf_free(&buffer);
+	cl_git_pass(git_message_prettify(&buffer, "Short", 1, '#'));
+	cl_assert_equal_s("Short\n", buffer.ptr);
+	git_buf_free(&buffer);
+
+	cl_git_pass(git_message_prettify(&buffer, "This is longer\nAnd multiline\n# with some comments still in\n", 0, '#'));
+	cl_assert_equal_s(buffer.ptr, "This is longer\nAnd multiline\n# with some comments still in\n");
+	git_buf_free(&buffer);
+
+	cl_git_pass(git_message_prettify(&buffer, "This is longer\nAnd multiline\n# with some comments still in\n", 1, '#'));
+	cl_assert_equal_s(buffer.ptr, "This is longer\nAnd multiline\n");
+	git_buf_free(&buffer);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/peel.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/peel.c
new file mode 100755
index 0000000..344885f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/peel.c
@@ -0,0 +1,118 @@
+#include "clar_libgit2.h"
+
+static git_repository *g_repo;
+
+void test_object_peel__initialize(void)
+{
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
+}
+
+void test_object_peel__cleanup(void)
+{
+	git_repository_free(g_repo);
+	g_repo = NULL;
+}
+
+static void assert_peel(
+	const char *sha,
+	git_otype requested_type,
+	const char* expected_sha,
+	git_otype expected_type)
+{
+	git_oid oid, expected_oid;
+	git_object *obj;
+	git_object *peeled;
+
+	cl_git_pass(git_oid_fromstr(&oid, sha));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+	
+	cl_git_pass(git_object_peel(&peeled, obj, requested_type));
+
+	cl_git_pass(git_oid_fromstr(&expected_oid, expected_sha));
+	cl_assert_equal_oid(&expected_oid, git_object_id(peeled));
+
+	cl_assert_equal_i(expected_type, git_object_type(peeled));
+
+	git_object_free(peeled);
+	git_object_free(obj);
+}
+
+static void assert_peel_error(int error, const char *sha, git_otype requested_type)
+{
+	git_oid oid;
+	git_object *obj;
+	git_object *peeled;
+
+	cl_git_pass(git_oid_fromstr(&oid, sha));
+	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+	
+	cl_assert_equal_i(error, git_object_peel(&peeled, obj, requested_type));
+
+	git_object_free(obj);
+}
+
+void test_object_peel__peeling_an_object_into_its_own_type_returns_another_instance_of_it(void)
+{
+	assert_peel("e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_COMMIT,
+		"e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_COMMIT);
+	assert_peel("7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJ_TAG,
+		"7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJ_TAG);
+	assert_peel("53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_TREE,
+		"53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_TREE);
+	assert_peel("0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJ_BLOB,
+		"0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJ_BLOB);
+}
+
+void test_object_peel__tag(void)
+{
+	assert_peel("7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJ_COMMIT,
+		"e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_COMMIT);
+	assert_peel("7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJ_TREE,
+		"53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_TREE);
+	assert_peel_error(GIT_EPEEL, "7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJ_BLOB);
+	assert_peel("7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJ_ANY,
+		    "e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_COMMIT);
+}
+
+void test_object_peel__commit(void)
+{
+	assert_peel_error(GIT_EINVALIDSPEC, "e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_BLOB);
+	assert_peel("e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_TREE,
+		    "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_TREE);
+	assert_peel("e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_COMMIT,
+		    "e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_COMMIT);
+	assert_peel_error(GIT_EINVALIDSPEC, "e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_TAG);
+	assert_peel("e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_ANY,
+		    "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_TREE);
+}
+
+void test_object_peel__tree(void)
+{
+	assert_peel_error(GIT_EINVALIDSPEC, "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_BLOB);
+	assert_peel("53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_TREE,
+		    "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_TREE);
+	assert_peel_error(GIT_EINVALIDSPEC, "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_COMMIT);
+	assert_peel_error(GIT_EINVALIDSPEC, "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_TAG);
+	assert_peel_error(GIT_EINVALIDSPEC, "53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_ANY);
+}
+
+void test_object_peel__blob(void)
+{
+	assert_peel("0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJ_BLOB,
+		    "0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJ_BLOB);
+	assert_peel_error(GIT_EINVALIDSPEC, "0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJ_TREE);
+	assert_peel_error(GIT_EINVALIDSPEC, "0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJ_COMMIT);
+	assert_peel_error(GIT_EINVALIDSPEC, "0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJ_TAG);
+	assert_peel_error(GIT_EINVALIDSPEC, "0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJ_ANY);
+}
+
+void test_object_peel__target_any_object_for_type_change(void)
+{
+	/* tag to commit */
+	assert_peel("7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJ_ANY,
+		"e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_COMMIT);
+
+	/* commit to tree */
+	assert_peel("e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_ANY,
+		"53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_TREE);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/chars.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/chars.c
new file mode 100755
index 0000000..cde0bdb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/chars.c
@@ -0,0 +1,41 @@
+
+#include "clar_libgit2.h"
+
+#include "odb.h"
+
+void test_object_raw_chars__find_invalid_chars_in_oid(void)
+{
+	git_oid out;
+	unsigned char exp[] = {
+		0x16, 0xa6, 0x77, 0x70, 0xb7,
+		0xd8, 0xd7, 0x23, 0x17, 0xc4,
+		0xb7, 0x75, 0x21, 0x3c, 0x23,
+		0xa8, 0xbd, 0x74, 0xf5, 0xe0,
+	};
+	char in[] = "16a67770b7d8d72317c4b775213c23a8bd74f5e0";
+	unsigned int i;
+
+	for (i = 0; i < 256; i++) {
+		in[38] = (char)i;
+		if (git__fromhex(i) >= 0) {
+			exp[19] = (unsigned char)(git__fromhex(i) << 4);
+			cl_git_pass(git_oid_fromstr(&out, in));
+			cl_assert(memcmp(out.id, exp, sizeof(out.id)) == 0);
+		} else {
+			cl_git_fail(git_oid_fromstr(&out, in));
+		}
+	}
+}
+
+void test_object_raw_chars__build_valid_oid_from_raw_bytes(void)
+{
+	git_oid out;
+	unsigned char exp[] = {
+		0x16, 0xa6, 0x77, 0x70, 0xb7,
+		0xd8, 0xd7, 0x23, 0x17, 0xc4,
+		0xb7, 0x75, 0x21, 0x3c, 0x23,
+		0xa8, 0xbd, 0x74, 0xf5, 0xe0,
+	};
+	git_oid_fromraw(&out, exp);
+	cl_git_pass(memcmp(out.id, exp, sizeof(out.id)));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/compare.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/compare.c
new file mode 100755
index 0000000..56c016b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/compare.c
@@ -0,0 +1,123 @@
+
+#include "clar_libgit2.h"
+
+#include "odb.h"
+
+void test_object_raw_compare__succeed_on_copy_oid(void)
+{
+	git_oid a, b;
+	unsigned char exp[] = {
+		0x16, 0xa6, 0x77, 0x70, 0xb7,
+		0xd8, 0xd7, 0x23, 0x17, 0xc4,
+		0xb7, 0x75, 0x21, 0x3c, 0x23,
+		0xa8, 0xbd, 0x74, 0xf5, 0xe0,
+	};
+	memset(&b, 0, sizeof(b));
+	git_oid_fromraw(&a, exp);
+	git_oid_cpy(&b, &a);
+	cl_git_pass(memcmp(a.id, exp, sizeof(a.id)));
+}
+
+void test_object_raw_compare__succeed_on_oid_comparison_lesser(void)
+{
+	git_oid a, b;
+	unsigned char a_in[] = {
+		0x16, 0xa6, 0x77, 0x70, 0xb7,
+		0xd8, 0xd7, 0x23, 0x17, 0xc4,
+		0xb7, 0x75, 0x21, 0x3c, 0x23,
+		0xa8, 0xbd, 0x74, 0xf5, 0xe0,
+	};
+	unsigned char b_in[] = {
+		0x16, 0xa6, 0x77, 0x70, 0xb7,
+		0xd8, 0xd7, 0x23, 0x17, 0xc4,
+		0xb7, 0x75, 0x21, 0x3c, 0x23,
+		0xa8, 0xbd, 0x74, 0xf5, 0xf0,
+	};
+	git_oid_fromraw(&a, a_in);
+	git_oid_fromraw(&b, b_in);
+	cl_assert(git_oid_cmp(&a, &b) < 0);
+}
+
+void test_object_raw_compare__succeed_on_oid_comparison_equal(void)
+{
+	git_oid a, b;
+	unsigned char a_in[] = {
+		0x16, 0xa6, 0x77, 0x70, 0xb7,
+		0xd8, 0xd7, 0x23, 0x17, 0xc4,
+		0xb7, 0x75, 0x21, 0x3c, 0x23,
+		0xa8, 0xbd, 0x74, 0xf5, 0xe0,
+	};
+	git_oid_fromraw(&a, a_in);
+	git_oid_fromraw(&b, a_in);
+	cl_assert(git_oid_cmp(&a, &b) == 0);
+}
+
+void test_object_raw_compare__succeed_on_oid_comparison_greater(void)
+{
+	git_oid a, b;
+	unsigned char a_in[] = {
+		0x16, 0xa6, 0x77, 0x70, 0xb7,
+		0xd8, 0xd7, 0x23, 0x17, 0xc4,
+		0xb7, 0x75, 0x21, 0x3c, 0x23,
+		0xa8, 0xbd, 0x74, 0xf5, 0xe0,
+	};
+	unsigned char b_in[] = {
+		0x16, 0xa6, 0x77, 0x70, 0xb7,
+		0xd8, 0xd7, 0x23, 0x17, 0xc4,
+		0xb7, 0x75, 0x21, 0x3c, 0x23,
+		0xa8, 0xbd, 0x74, 0xf5, 0xd0,
+	};
+	git_oid_fromraw(&a, a_in);
+	git_oid_fromraw(&b, b_in);
+	cl_assert(git_oid_cmp(&a, &b) > 0);
+}
+
+void test_object_raw_compare__compare_fmt_oids(void)
+{
+	const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0";
+	git_oid in;
+	char out[GIT_OID_HEXSZ + 1];
+
+	cl_git_pass(git_oid_fromstr(&in, exp));
+
+	/* Format doesn't touch the last byte */
+	out[GIT_OID_HEXSZ] = 'Z';
+	git_oid_fmt(out, &in);
+	cl_assert(out[GIT_OID_HEXSZ] == 'Z');
+
+	/* Format produced the right result */
+	out[GIT_OID_HEXSZ] = '\0';
+	cl_assert_equal_s(exp, out);
+}
+
+void test_object_raw_compare__compare_static_oids(void)
+{
+	const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0";
+	git_oid in;
+	char *out;
+
+	cl_git_pass(git_oid_fromstr(&in, exp));
+
+	out = git_oid_tostr_s(&in);
+	cl_assert(out);
+	cl_assert_equal_s(exp, out);
+}
+
+void test_object_raw_compare__compare_pathfmt_oids(void)
+{
+	const char *exp1 = "16a0123456789abcdef4b775213c23a8bd74f5e0";
+	const char *exp2 = "16/a0123456789abcdef4b775213c23a8bd74f5e0";
+	git_oid in;
+	char out[GIT_OID_HEXSZ + 2];
+
+	cl_git_pass(git_oid_fromstr(&in, exp1));
+
+	/* Format doesn't touch the last byte */
+	out[GIT_OID_HEXSZ + 1] = 'Z';
+	git_oid_pathfmt(out, &in);
+	cl_assert(out[GIT_OID_HEXSZ + 1] == 'Z');
+
+	/* Format produced the right result */
+	out[GIT_OID_HEXSZ + 1] = '\0';
+	cl_assert_equal_s(exp2, out);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/convert.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/convert.c
new file mode 100755
index 0000000..88b1380
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/convert.c
@@ -0,0 +1,112 @@
+
+#include "clar_libgit2.h"
+
+#include "odb.h"
+
+void test_object_raw_convert__succeed_on_oid_to_string_conversion(void)
+{
+	const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0";
+	git_oid in;
+	char out[GIT_OID_HEXSZ + 1];
+	char *str;
+	int i;
+
+	cl_git_pass(git_oid_fromstr(&in, exp));
+
+	/* NULL buffer pointer, returns static empty string */
+	str = git_oid_tostr(NULL, sizeof(out), &in);
+	cl_assert(str && *str == '\0' && str != out);
+
+	/* zero buffer size, returns static empty string */
+	str = git_oid_tostr(out, 0, &in);
+	cl_assert(str && *str == '\0' && str != out);
+
+	/* NULL oid pointer, sets existing buffer to empty string */
+	str = git_oid_tostr(out, sizeof(out), NULL);
+	cl_assert(str && *str == '\0' && str == out);
+
+	/* n == 1, returns out as an empty string */
+	str = git_oid_tostr(out, 1, &in);
+	cl_assert(str && *str == '\0' && str == out);
+
+	for (i = 1; i < GIT_OID_HEXSZ; i++) {
+		out[i+1] = 'Z';
+		str = git_oid_tostr(out, i+1, &in);
+		/* returns out containing c-string */
+		cl_assert(str && str == out);
+		/* must be '\0' terminated */
+		cl_assert(*(str+i) == '\0');
+		/* must not touch bytes past end of string */
+		cl_assert(*(str+(i+1)) == 'Z');
+		/* i == n-1 charaters of string */
+		cl_git_pass(strncmp(exp, out, i));
+	}
+
+	/* returns out as hex formatted c-string */
+	str = git_oid_tostr(out, sizeof(out), &in);
+	cl_assert(str && str == out && *(str+GIT_OID_HEXSZ) == '\0');
+	cl_assert_equal_s(exp, out);
+}
+
+void test_object_raw_convert__succeed_on_oid_to_string_conversion_big(void)
+{
+	const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0";
+	git_oid in;
+	char big[GIT_OID_HEXSZ + 1 + 3]; /* note + 4 => big buffer */
+	char *str;
+
+	cl_git_pass(git_oid_fromstr(&in, exp));
+
+	/* place some tail material */
+	big[GIT_OID_HEXSZ+0] = 'W'; /* should be '\0' afterwards */
+	big[GIT_OID_HEXSZ+1] = 'X'; /* should remain untouched   */
+	big[GIT_OID_HEXSZ+2] = 'Y'; /* ditto */
+	big[GIT_OID_HEXSZ+3] = 'Z'; /* ditto */
+
+	/* returns big as hex formatted c-string */
+	str = git_oid_tostr(big, sizeof(big), &in);
+	cl_assert(str && str == big && *(str+GIT_OID_HEXSZ) == '\0');
+	cl_assert_equal_s(exp, big);
+
+	/* check tail material is untouched */
+	cl_assert(str && str == big && *(str+GIT_OID_HEXSZ+1) == 'X');
+	cl_assert(str && str == big && *(str+GIT_OID_HEXSZ+2) == 'Y');
+	cl_assert(str && str == big && *(str+GIT_OID_HEXSZ+3) == 'Z');
+}
+
+static void check_partial_oid(
+	char *buffer, size_t count, const git_oid *oid, const char *expected)
+{
+	git_oid_nfmt(buffer, count, oid);
+	buffer[count] = '\0';
+	cl_assert_equal_s(expected, buffer);
+}
+
+void test_object_raw_convert__convert_oid_partially(void)
+{
+	const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0";
+	git_oid in;
+	char big[GIT_OID_HEXSZ + 1 + 3]; /* note + 4 => big buffer */
+
+	cl_git_pass(git_oid_fromstr(&in, exp));
+
+	git_oid_nfmt(big, sizeof(big), &in);
+	cl_assert_equal_s(exp, big);
+
+	git_oid_nfmt(big, GIT_OID_HEXSZ + 1, &in);
+	cl_assert_equal_s(exp, big);
+
+	check_partial_oid(big, 1, &in, "1");
+	check_partial_oid(big, 2, &in, "16");
+	check_partial_oid(big, 3, &in, "16a");
+	check_partial_oid(big, 4, &in, "16a0");
+	check_partial_oid(big, 5, &in, "16a01");
+
+	check_partial_oid(big, GIT_OID_HEXSZ, &in, exp);
+	check_partial_oid(
+		big, GIT_OID_HEXSZ - 1, &in, "16a0123456789abcdef4b775213c23a8bd74f5e");
+	check_partial_oid(
+		big, GIT_OID_HEXSZ - 2, &in, "16a0123456789abcdef4b775213c23a8bd74f5");
+	check_partial_oid(
+		big, GIT_OID_HEXSZ - 3, &in, "16a0123456789abcdef4b775213c23a8bd74f");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/data.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/data.h
new file mode 100755
index 0000000..cf23819
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/data.h
@@ -0,0 +1,323 @@
+
+/*
+ * Raw data
+ */
+static unsigned char commit_data[] = {
+    0x74, 0x72, 0x65, 0x65, 0x20, 0x64, 0x66, 0x66,
+    0x32, 0x64, 0x61, 0x39, 0x30, 0x62, 0x32, 0x35,
+    0x34, 0x65, 0x31, 0x62, 0x65, 0x62, 0x38, 0x38,
+    0x39, 0x64, 0x31, 0x66, 0x31, 0x66, 0x31, 0x32,
+    0x38, 0x38, 0x62, 0x65, 0x31, 0x38, 0x30, 0x33,
+    0x37, 0x38, 0x32, 0x64, 0x66, 0x0a, 0x61, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x20, 0x41, 0x20, 0x55,
+    0x20, 0x54, 0x68, 0x6f, 0x72, 0x20, 0x3c, 0x61,
+    0x75, 0x74, 0x68, 0x6f, 0x72, 0x40, 0x65, 0x78,
+    0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+    0x6d, 0x3e, 0x20, 0x31, 0x32, 0x32, 0x37, 0x38,
+    0x31, 0x34, 0x32, 0x39, 0x37, 0x20, 0x2b, 0x30,
+    0x30, 0x30, 0x30, 0x0a, 0x63, 0x6f, 0x6d, 0x6d,
+    0x69, 0x74, 0x74, 0x65, 0x72, 0x20, 0x43, 0x20,
+    0x4f, 0x20, 0x4d, 0x69, 0x74, 0x74, 0x65, 0x72,
+    0x20, 0x3c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
+    0x74, 0x65, 0x72, 0x40, 0x65, 0x78, 0x61, 0x6d,
+    0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3e,
+    0x20, 0x31, 0x32, 0x32, 0x37, 0x38, 0x31, 0x34,
+    0x32, 0x39, 0x37, 0x20, 0x2b, 0x30, 0x30, 0x30,
+    0x30, 0x0a, 0x0a, 0x41, 0x20, 0x6f, 0x6e, 0x65,
+    0x2d, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x63, 0x6f,
+    0x6d, 0x6d, 0x69, 0x74, 0x20, 0x73, 0x75, 0x6d,
+    0x6d, 0x61, 0x72, 0x79, 0x0a, 0x0a, 0x54, 0x68,
+    0x65, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x6f,
+    0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f,
+    0x6d, 0x6d, 0x69, 0x74, 0x20, 0x6d, 0x65, 0x73,
+    0x73, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x63, 0x6f,
+    0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67,
+    0x20, 0x66, 0x75, 0x72, 0x74, 0x68, 0x65, 0x72,
+    0x20, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x6e, 0x61,
+    0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x6f, 0x66, 0x20,
+    0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x72, 0x70,
+    0x6f, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74,
+    0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67,
+    0x65, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x72, 0x6f,
+    0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79,
+    0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d,
+    0x6d, 0x69, 0x74, 0x2e, 0x0a, 0x0a, 0x53, 0x69,
+    0x67, 0x6e, 0x65, 0x64, 0x2d, 0x6f, 0x66, 0x2d,
+    0x62, 0x79, 0x3a, 0x20, 0x41, 0x20, 0x55, 0x20,
+    0x54, 0x68, 0x6f, 0x72, 0x20, 0x3c, 0x61, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x40, 0x65, 0x78, 0x61,
+    0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+    0x3e, 0x0a,
+};
+
+
+static unsigned char tree_data[] = {
+    0x31, 0x30, 0x30, 0x36, 0x34, 0x34, 0x20, 0x6f,
+    0x6e, 0x65, 0x00, 0x8b, 0x13, 0x78, 0x91, 0x79,
+    0x1f, 0xe9, 0x69, 0x27, 0xad, 0x78, 0xe6, 0x4b,
+    0x0a, 0xad, 0x7b, 0xde, 0xd0, 0x8b, 0xdc, 0x31,
+    0x30, 0x30, 0x36, 0x34, 0x34, 0x20, 0x73, 0x6f,
+    0x6d, 0x65, 0x00, 0xfd, 0x84, 0x30, 0xbc, 0x86,
+    0x4c, 0xfc, 0xd5, 0xf1, 0x0e, 0x55, 0x90, 0xf8,
+    0xa4, 0x47, 0xe0, 0x1b, 0x94, 0x2b, 0xfe, 0x31,
+    0x30, 0x30, 0x36, 0x34, 0x34, 0x20, 0x74, 0x77,
+    0x6f, 0x00, 0x78, 0x98, 0x19, 0x22, 0x61, 0x3b,
+    0x2a, 0xfb, 0x60, 0x25, 0x04, 0x2f, 0xf6, 0xbd,
+    0x87, 0x8a, 0xc1, 0x99, 0x4e, 0x85, 0x31, 0x30,
+    0x30, 0x36, 0x34, 0x34, 0x20, 0x7a, 0x65, 0x72,
+    0x6f, 0x00, 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1,
+    0xd6, 0x43, 0x4b, 0x8b, 0x29, 0xae, 0x77, 0x5a,
+    0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91,
+};
+
+static unsigned char tag_data[] = {
+    0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x33,
+    0x64, 0x37, 0x66, 0x38, 0x61, 0x36, 0x61, 0x66,
+    0x30, 0x37, 0x36, 0x63, 0x38, 0x63, 0x33, 0x66,
+    0x32, 0x30, 0x30, 0x37, 0x31, 0x61, 0x38, 0x39,
+    0x33, 0x35, 0x63, 0x64, 0x62, 0x65, 0x38, 0x32,
+    0x32, 0x38, 0x35, 0x39, 0x34, 0x64, 0x31, 0x0a,
+    0x74, 0x79, 0x70, 0x65, 0x20, 0x63, 0x6f, 0x6d,
+    0x6d, 0x69, 0x74, 0x0a, 0x74, 0x61, 0x67, 0x20,
+    0x76, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0a, 0x74,
+    0x61, 0x67, 0x67, 0x65, 0x72, 0x20, 0x43, 0x20,
+    0x4f, 0x20, 0x4d, 0x69, 0x74, 0x74, 0x65, 0x72,
+    0x20, 0x3c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
+    0x74, 0x65, 0x72, 0x40, 0x65, 0x78, 0x61, 0x6d,
+    0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3e,
+    0x20, 0x31, 0x32, 0x32, 0x37, 0x38, 0x31, 0x34,
+    0x32, 0x39, 0x37, 0x20, 0x2b, 0x30, 0x30, 0x30,
+    0x30, 0x0a, 0x0a, 0x54, 0x68, 0x69, 0x73, 0x20,
+    0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74,
+    0x61, 0x67, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63,
+    0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x72, 0x65,
+    0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x76, 0x30,
+    0x2e, 0x30, 0x2e, 0x31, 0x0a,
+};
+
+/*
+ * Dummy data
+ */
+static unsigned char zero_data[] = {
+    0x00,
+};
+
+static unsigned char one_data[] = {
+    0x0a,
+};
+
+static unsigned char two_data[] = {
+    0x61, 0x0a,
+};
+
+static unsigned char some_data[] = {
+    0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x54, 0x68,
+    0x69, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20,
+    0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20,
+    0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
+    0x3b, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x63, 0x61,
+    0x6e, 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74,
+    0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x69,
+    0x74, 0x20, 0x61, 0x6e, 0x64, 0x2f, 0x6f, 0x72,
+    0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0a,
+    0x20, 0x2a, 0x20, 0x69, 0x74, 0x20, 0x75, 0x6e,
+    0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20,
+    0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66,
+    0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x4e, 0x55,
+    0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
+    0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+    0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x2c,
+    0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+    0x20, 0x32, 0x2c, 0x0a, 0x20, 0x2a, 0x20, 0x61,
+    0x73, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73,
+    0x68, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
+    0x68, 0x65, 0x20, 0x46, 0x72, 0x65, 0x65, 0x20,
+    0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
+    0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x20, 0x2a, 0x0a,
+    0x20, 0x2a, 0x20, 0x49, 0x6e, 0x20, 0x61, 0x64,
+    0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74,
+    0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x65,
+    0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
+    0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
+    0x20, 0x47, 0x4e, 0x55, 0x20, 0x47, 0x65, 0x6e,
+    0x65, 0x72, 0x61, 0x6c, 0x20, 0x50, 0x75, 0x62,
+    0x6c, 0x69, 0x63, 0x20, 0x4c, 0x69, 0x63, 0x65,
+    0x6e, 0x73, 0x65, 0x2c, 0x0a, 0x20, 0x2a, 0x20,
+    0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x73, 0x20, 0x67, 0x69, 0x76, 0x65,
+    0x20, 0x79, 0x6f, 0x75, 0x20, 0x75, 0x6e, 0x6c,
+    0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x20, 0x70,
+    0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f,
+    0x6e, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x69, 0x6e,
+    0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f,
+    0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x0a, 0x20,
+    0x2a, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
+    0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69,
+    0x73, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x69,
+    0x6e, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x62,
+    0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+    0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x74,
+    0x68, 0x65, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x67,
+    0x72, 0x61, 0x6d, 0x73, 0x2c, 0x0a, 0x20, 0x2a,
+    0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x20,
+    0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75,
+    0x74, 0x65, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65,
+    0x20, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61,
+    0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x77, 0x69,
+    0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x6e,
+    0x79, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69,
+    0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x2a,
+    0x20, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x20,
+    0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65,
+    0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20,
+    0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6c,
+    0x65, 0x2e, 0x20, 0x20, 0x28, 0x54, 0x68, 0x65,
+    0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
+    0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+    0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x0a,
+    0x20, 0x2a, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72,
+    0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20,
+    0x64, 0x6f, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79,
+    0x20, 0x69, 0x6e, 0x20, 0x6f, 0x74, 0x68, 0x65,
+    0x72, 0x20, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63,
+    0x74, 0x73, 0x3b, 0x20, 0x66, 0x6f, 0x72, 0x20,
+    0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c,
+    0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x63, 0x6f,
+    0x76, 0x65, 0x72, 0x0a, 0x20, 0x2a, 0x20, 0x6d,
+    0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74,
+    0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2c,
+    0x20, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x69, 0x73,
+    0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x6e,
+    0x6f, 0x74, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x65,
+    0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x0a, 0x20,
+    0x2a, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6d, 0x62,
+    0x69, 0x6e, 0x65, 0x64, 0x20, 0x65, 0x78, 0x65,
+    0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e,
+    0x29, 0x0a, 0x20, 0x2a, 0x0a, 0x20, 0x2a, 0x20,
+    0x54, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6c,
+    0x65, 0x20, 0x69, 0x73, 0x20, 0x64, 0x69, 0x73,
+    0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64,
+    0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20,
+    0x68, 0x6f, 0x70, 0x65, 0x20, 0x74, 0x68, 0x61,
+    0x74, 0x20, 0x69, 0x74, 0x20, 0x77, 0x69, 0x6c,
+    0x6c, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65,
+    0x66, 0x75, 0x6c, 0x2c, 0x20, 0x62, 0x75, 0x74,
+    0x0a, 0x20, 0x2a, 0x20, 0x57, 0x49, 0x54, 0x48,
+    0x4f, 0x55, 0x54, 0x20, 0x41, 0x4e, 0x59, 0x20,
+    0x57, 0x41, 0x52, 0x52, 0x41, 0x4e, 0x54, 0x59,
+    0x3b, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75,
+    0x74, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x74,
+    0x68, 0x65, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x69,
+    0x65, 0x64, 0x20, 0x77, 0x61, 0x72, 0x72, 0x61,
+    0x6e, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x0a, 0x20,
+    0x2a, 0x20, 0x4d, 0x45, 0x52, 0x43, 0x48, 0x41,
+    0x4e, 0x54, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54,
+    0x59, 0x20, 0x6f, 0x72, 0x20, 0x46, 0x49, 0x54,
+    0x4e, 0x45, 0x53, 0x53, 0x20, 0x46, 0x4f, 0x52,
+    0x20, 0x41, 0x20, 0x50, 0x41, 0x52, 0x54, 0x49,
+    0x43, 0x55, 0x4c, 0x41, 0x52, 0x20, 0x50, 0x55,
+    0x52, 0x50, 0x4f, 0x53, 0x45, 0x2e, 0x20, 0x20,
+    0x53, 0x65, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
+    0x47, 0x4e, 0x55, 0x0a, 0x20, 0x2a, 0x20, 0x47,
+    0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x50,
+    0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x4c, 0x69,
+    0x63, 0x65, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6f,
+    0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64,
+    0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x0a,
+    0x20, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x59, 0x6f,
+    0x75, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64,
+    0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x72, 0x65,
+    0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x20, 0x61,
+    0x20, 0x63, 0x6f, 0x70, 0x79, 0x20, 0x6f, 0x66,
+    0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x4e, 0x55,
+    0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
+    0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+    0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x0a,
+    0x20, 0x2a, 0x20, 0x61, 0x6c, 0x6f, 0x6e, 0x67,
+    0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68,
+    0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72,
+    0x61, 0x6d, 0x3b, 0x20, 0x73, 0x65, 0x65, 0x20,
+    0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65,
+    0x20, 0x43, 0x4f, 0x50, 0x59, 0x49, 0x4e, 0x47,
+    0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x6e, 0x6f,
+    0x74, 0x2c, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65,
+    0x20, 0x74, 0x6f, 0x0a, 0x20, 0x2a, 0x20, 0x74,
+    0x68, 0x65, 0x20, 0x46, 0x72, 0x65, 0x65, 0x20,
+    0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
+    0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x35, 0x31, 0x20,
+    0x46, 0x72, 0x61, 0x6e, 0x6b, 0x6c, 0x69, 0x6e,
+    0x20, 0x53, 0x74, 0x72, 0x65, 0x65, 0x74, 0x2c,
+    0x20, 0x46, 0x69, 0x66, 0x74, 0x68, 0x20, 0x46,
+    0x6c, 0x6f, 0x6f, 0x72, 0x2c, 0x0a, 0x20, 0x2a,
+    0x20, 0x42, 0x6f, 0x73, 0x74, 0x6f, 0x6e, 0x2c,
+    0x20, 0x4d, 0x41, 0x20, 0x30, 0x32, 0x31, 0x31,
+    0x30, 0x2d, 0x31, 0x33, 0x30, 0x31, 0x2c, 0x20,
+    0x55, 0x53, 0x41, 0x2e, 0x0a, 0x20, 0x2a, 0x2f,
+    0x0a,
+};
+
+/*
+ * SHA1 Hashes
+ */
+static char *commit_id = "3d7f8a6af076c8c3f20071a8935cdbe8228594d1";
+static char *tree_id = "dff2da90b254e1beb889d1f1f1288be1803782df";
+static char *tag_id = "09d373e1dfdc16b129ceec6dd649739911541e05";
+static char *zero_id = "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391";
+static char *one_id = "8b137891791fe96927ad78e64b0aad7bded08bdc";
+static char *two_id = "78981922613b2afb6025042ff6bd878ac1994e85";
+static char *some_id = "fd8430bc864cfcd5f10e5590f8a447e01b942bfe";
+
+/*
+ * In-memory objects
+ */
+static git_rawobj tree_obj = {
+	tree_data,
+	sizeof(tree_data),
+	GIT_OBJ_TREE
+};
+
+static git_rawobj tag_obj = {
+	tag_data,
+	sizeof(tag_data),
+	GIT_OBJ_TAG
+};
+
+static git_rawobj zero_obj = {
+	zero_data,
+	0,
+	GIT_OBJ_BLOB
+};
+
+static git_rawobj one_obj = {
+	one_data,
+	sizeof(one_data),
+	GIT_OBJ_BLOB
+};
+
+static git_rawobj two_obj = {
+	two_data,
+	sizeof(two_data),
+	GIT_OBJ_BLOB
+};
+
+static git_rawobj commit_obj = {
+	commit_data,
+	sizeof(commit_data),
+	GIT_OBJ_COMMIT
+};
+
+static git_rawobj some_obj = {
+	some_data,
+	sizeof(some_data),
+	GIT_OBJ_BLOB
+};
+
+static git_rawobj junk_obj = {
+	NULL,
+	0,
+	GIT_OBJ_BAD
+};
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/fromstr.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/fromstr.c
new file mode 100755
index 0000000..8c11c10
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/fromstr.c
@@ -0,0 +1,30 @@
+
+#include "clar_libgit2.h"
+
+#include "odb.h"
+
+void test_object_raw_fromstr__fail_on_invalid_oid_string(void)
+{
+	git_oid out;
+	cl_git_fail(git_oid_fromstr(&out, ""));
+	cl_git_fail(git_oid_fromstr(&out, "moo"));
+	cl_git_fail(git_oid_fromstr(&out, "16a67770b7d8d72317c4b775213c23a8bd74f5ez"));
+}
+
+void test_object_raw_fromstr__succeed_on_valid_oid_string(void)
+{
+	git_oid out;
+	unsigned char exp[] = {
+		0x16, 0xa6, 0x77, 0x70, 0xb7,
+		0xd8, 0xd7, 0x23, 0x17, 0xc4,
+		0xb7, 0x75, 0x21, 0x3c, 0x23,
+		0xa8, 0xbd, 0x74, 0xf5, 0xe0,
+	};
+
+	cl_git_pass(git_oid_fromstr(&out, "16a67770b7d8d72317c4b775213c23a8bd74f5e0"));
+	cl_git_pass(memcmp(out.id, exp, sizeof(out.id)));
+
+	cl_git_pass(git_oid_fromstr(&out, "16A67770B7D8D72317C4b775213C23A8BD74F5E0"));
+	cl_git_pass(memcmp(out.id, exp, sizeof(out.id)));
+
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/hash.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/hash.c
new file mode 100755
index 0000000..ede31e1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/hash.c
@@ -0,0 +1,166 @@
+
+#include "clar_libgit2.h"
+
+#include "odb.h"
+#include "hash.h"
+
+#include "data.h"
+
+static void hash_object_pass(git_oid *oid, git_rawobj *obj)
+{
+	cl_git_pass(git_odb_hash(oid, obj->data, obj->len, obj->type));
+}
+static void hash_object_fail(git_oid *oid, git_rawobj *obj)
+{
+	cl_git_fail(git_odb_hash(oid, obj->data, obj->len, obj->type));
+}
+
+static char *hello_id = "22596363b3de40b06f981fb85d82312e8c0ed511";
+static char *hello_text = "hello world\n";
+
+static char *bye_id = "ce08fe4884650f067bd5703b6a59a8b3b3c99a09";
+static char *bye_text = "bye world\n";
+
+void test_object_raw_hash__hash_by_blocks(void)
+{
+	git_hash_ctx ctx;
+	git_oid id1, id2;
+
+	cl_git_pass(git_hash_ctx_init(&ctx));
+
+	/* should already be init'd */
+	cl_git_pass(git_hash_update(&ctx, hello_text, strlen(hello_text)));
+	cl_git_pass(git_hash_final(&id2, &ctx));
+	cl_git_pass(git_oid_fromstr(&id1, hello_id));
+	cl_assert(git_oid_cmp(&id1, &id2) == 0);
+
+	/* reinit should permit reuse */
+	cl_git_pass(git_hash_init(&ctx));
+	cl_git_pass(git_hash_update(&ctx, bye_text, strlen(bye_text)));
+	cl_git_pass(git_hash_final(&id2, &ctx));
+	cl_git_pass(git_oid_fromstr(&id1, bye_id));
+	cl_assert(git_oid_cmp(&id1, &id2) == 0);
+
+	git_hash_ctx_cleanup(&ctx);
+}
+
+void test_object_raw_hash__hash_buffer_in_single_call(void)
+{
+	git_oid id1, id2;
+
+	cl_git_pass(git_oid_fromstr(&id1, hello_id));
+	git_hash_buf(&id2, hello_text, strlen(hello_text));
+	cl_assert(git_oid_cmp(&id1, &id2) == 0);
+}
+
+void test_object_raw_hash__hash_vector(void)
+{
+	git_oid id1, id2;
+	git_buf_vec vec[2];
+
+	cl_git_pass(git_oid_fromstr(&id1, hello_id));
+
+	vec[0].data = hello_text;
+	vec[0].len  = 4;
+	vec[1].data = hello_text+4;
+	vec[1].len  = strlen(hello_text)-4;
+
+	git_hash_vec(&id2, vec, 2);
+
+	cl_assert(git_oid_cmp(&id1, &id2) == 0);
+}
+
+void test_object_raw_hash__hash_junk_data(void)
+{
+	git_oid id, id_zero;
+
+	cl_git_pass(git_oid_fromstr(&id_zero, zero_id));
+
+	/* invalid types: */
+	junk_obj.data = some_data;
+	hash_object_fail(&id, &junk_obj);
+
+	junk_obj.type = GIT_OBJ__EXT1;
+	hash_object_fail(&id, &junk_obj);
+
+	junk_obj.type = GIT_OBJ__EXT2;
+	hash_object_fail(&id, &junk_obj);
+
+	junk_obj.type = GIT_OBJ_OFS_DELTA;
+	hash_object_fail(&id, &junk_obj);
+
+	junk_obj.type = GIT_OBJ_REF_DELTA;
+	hash_object_fail(&id, &junk_obj);
+
+	/* data can be NULL only if len is zero: */
+	junk_obj.type = GIT_OBJ_BLOB;
+	junk_obj.data = NULL;
+	hash_object_pass(&id, &junk_obj);
+	cl_assert(git_oid_cmp(&id, &id_zero) == 0);
+
+	junk_obj.len = 1;
+	hash_object_fail(&id, &junk_obj);
+}
+
+void test_object_raw_hash__hash_commit_object(void)
+{
+	git_oid id1, id2;
+
+	cl_git_pass(git_oid_fromstr(&id1, commit_id));
+	hash_object_pass(&id2, &commit_obj);
+	cl_assert(git_oid_cmp(&id1, &id2) == 0);
+}
+
+void test_object_raw_hash__hash_tree_object(void)
+{
+	git_oid id1, id2;
+
+	cl_git_pass(git_oid_fromstr(&id1, tree_id));
+	hash_object_pass(&id2, &tree_obj);
+	cl_assert(git_oid_cmp(&id1, &id2) == 0);
+}
+
+void test_object_raw_hash__hash_tag_object(void)
+{
+	git_oid id1, id2;
+
+	cl_git_pass(git_oid_fromstr(&id1, tag_id));
+	hash_object_pass(&id2, &tag_obj);
+	cl_assert(git_oid_cmp(&id1, &id2) == 0);
+}
+
+void test_object_raw_hash__hash_zero_length_object(void)
+{
+	git_oid id1, id2;
+
+	cl_git_pass(git_oid_fromstr(&id1, zero_id));
+	hash_object_pass(&id2, &zero_obj);
+	cl_assert(git_oid_cmp(&id1, &id2) == 0);
+}
+
+void test_object_raw_hash__hash_one_byte_object(void)
+{
+	git_oid id1, id2;
+
+	cl_git_pass(git_oid_fromstr(&id1, one_id));
+	hash_object_pass(&id2, &one_obj);
+	cl_assert(git_oid_cmp(&id1, &id2) == 0);
+}
+
+void test_object_raw_hash__hash_two_byte_object(void)
+{
+	git_oid id1, id2;
+
+	cl_git_pass(git_oid_fromstr(&id1, two_id));
+	hash_object_pass(&id2, &two_obj);
+	cl_assert(git_oid_cmp(&id1, &id2) == 0);
+}
+
+void test_object_raw_hash__hash_multi_byte_object(void)
+{
+	git_oid id1, id2;
+
+	cl_git_pass(git_oid_fromstr(&id1, some_id));
+	hash_object_pass(&id2, &some_obj);
+	cl_assert(git_oid_cmp(&id1, &id2) == 0);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/short.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/short.c
new file mode 100755
index 0000000..813cd86
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/short.c
@@ -0,0 +1,137 @@
+
+#include "clar_libgit2.h"
+
+#include "odb.h"
+#include "hash.h"
+
+void test_object_raw_short__oid_shortener_no_duplicates(void)
+{
+	git_oid_shorten *os;
+	int min_len;
+
+	os = git_oid_shorten_new(0);
+	cl_assert(os != NULL);
+
+	git_oid_shorten_add(os, "22596363b3de40b06f981fb85d82312e8c0ed511");
+	git_oid_shorten_add(os, "ce08fe4884650f067bd5703b6a59a8b3b3c99a09");
+	git_oid_shorten_add(os, "16a0123456789abcdef4b775213c23a8bd74f5e0");
+	min_len = git_oid_shorten_add(os, "ce08fe4884650f067bd5703b6a59a8b3b3c99a09");
+
+	cl_assert(min_len == GIT_OID_HEXSZ + 1);
+
+	git_oid_shorten_free(os);
+}
+
+static int insert_sequential_oids(
+	char ***out, git_oid_shorten *os, int n, int fail)
+{
+	int i, min_len = 0;
+	char numbuf[16];
+	git_oid oid;
+	char **oids = git__calloc(n, sizeof(char *));
+	cl_assert(oids != NULL);
+
+	for (i = 0; i < n; ++i) {
+		p_snprintf(numbuf, sizeof(numbuf), "%u", (unsigned int)i);
+		git_hash_buf(&oid, numbuf, strlen(numbuf));
+
+		oids[i] = git__malloc(GIT_OID_HEXSZ + 1);
+		cl_assert(oids[i]);
+		git_oid_nfmt(oids[i], GIT_OID_HEXSZ + 1, &oid);
+
+		min_len = git_oid_shorten_add(os, oids[i]);
+
+		/* After "fail", we expect git_oid_shorten_add to fail */
+		if (fail >= 0 && i >= fail)
+            cl_assert(min_len < 0);
+		else
+            cl_assert(min_len >= 0);
+	}
+
+	*out = oids;
+
+	return min_len;
+}
+
+static void free_oids(int n, char **oids)
+{
+	int i;
+
+	for (i = 0; i < n; ++i) {
+		git__free(oids[i]);
+	}
+	git__free(oids);
+}
+
+void test_object_raw_short__oid_shortener_stresstest_git_oid_shorten(void)
+{
+#define MAX_OIDS 1000
+
+	git_oid_shorten *os;
+	size_t i, j;
+	int min_len = 0, found_collision;
+	char **oids;
+
+	os = git_oid_shorten_new(0);
+	cl_assert(os != NULL);
+
+	/*
+	 * Insert in the shortener 1000 unique SHA1 ids
+	 */
+	min_len = insert_sequential_oids(&oids, os, MAX_OIDS, MAX_OIDS);
+	cl_assert(min_len > 0);
+
+	/*
+	 * Compare the first `min_char - 1` characters of each
+	 * SHA1 OID. If the minimizer worked, we should find at
+	 * least one collision
+	 */
+	found_collision = 0;
+	for (i = 0; i < MAX_OIDS; ++i) {
+		for (j = i + 1; j < MAX_OIDS; ++j) {
+			if (memcmp(oids[i], oids[j], min_len - 1) == 0)
+				found_collision = 1;
+		}
+	}
+	cl_assert_equal_b(true, found_collision);
+
+	/*
+	 * Compare the first `min_char` characters of each
+	 * SHA1 OID. If the minimizer worked, every single preffix
+	 * should be unique.
+	 */
+	found_collision = 0;
+	for (i = 0; i < MAX_OIDS; ++i) {
+		for (j = i + 1; j < MAX_OIDS; ++j) {
+			if (memcmp(oids[i], oids[j], min_len) == 0)
+				found_collision = 1;
+		}
+	}
+	cl_assert_equal_b(false, found_collision);
+
+	/* cleanup */
+	free_oids(MAX_OIDS, oids);
+	git_oid_shorten_free(os);
+
+#undef MAX_OIDS
+}
+
+void test_object_raw_short__oid_shortener_too_much_oids(void)
+{
+    /* The magic number of oids at which an oid_shortener will fail.
+     * This was experimentally established. */
+#define MAX_OIDS 24556
+
+	git_oid_shorten *os;
+	char **oids;
+
+	os = git_oid_shorten_new(0);
+	cl_assert(os != NULL);
+
+	cl_assert(insert_sequential_oids(&oids, os, MAX_OIDS, MAX_OIDS - 1) < 0);
+
+	free_oids(MAX_OIDS, oids);
+	git_oid_shorten_free(os);
+
+#undef MAX_OIDS
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/size.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/size.c
new file mode 100755
index 0000000..930c6de
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/size.c
@@ -0,0 +1,13 @@
+
+#include "clar_libgit2.h"
+
+#include "odb.h"
+
+void test_object_raw_size__validate_oid_size(void)
+{
+	git_oid out;
+	cl_assert(20 == GIT_OID_RAWSZ);
+	cl_assert(40 == GIT_OID_HEXSZ);
+	cl_assert(sizeof(out) == GIT_OID_RAWSZ);
+	cl_assert(sizeof(out.id) == GIT_OID_RAWSZ);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/type2string.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/type2string.c
new file mode 100755
index 0000000..a358548
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/type2string.c
@@ -0,0 +1,54 @@
+
+#include "clar_libgit2.h"
+
+#include "odb.h"
+#include "hash.h"
+
+void test_object_raw_type2string__convert_type_to_string(void)
+{
+	cl_assert_equal_s(git_object_type2string(GIT_OBJ_BAD), "");
+	cl_assert_equal_s(git_object_type2string(GIT_OBJ__EXT1), "");
+	cl_assert_equal_s(git_object_type2string(GIT_OBJ_COMMIT), "commit");
+	cl_assert_equal_s(git_object_type2string(GIT_OBJ_TREE), "tree");
+	cl_assert_equal_s(git_object_type2string(GIT_OBJ_BLOB), "blob");
+	cl_assert_equal_s(git_object_type2string(GIT_OBJ_TAG), "tag");
+	cl_assert_equal_s(git_object_type2string(GIT_OBJ__EXT2), "");
+	cl_assert_equal_s(git_object_type2string(GIT_OBJ_OFS_DELTA), "OFS_DELTA");
+	cl_assert_equal_s(git_object_type2string(GIT_OBJ_REF_DELTA), "REF_DELTA");
+
+	cl_assert_equal_s(git_object_type2string(-2), "");
+	cl_assert_equal_s(git_object_type2string(8), "");
+	cl_assert_equal_s(git_object_type2string(1234), "");
+}
+
+void test_object_raw_type2string__convert_string_to_type(void)
+{
+	cl_assert(git_object_string2type(NULL) == GIT_OBJ_BAD);
+	cl_assert(git_object_string2type("") == GIT_OBJ_BAD);
+	cl_assert(git_object_string2type("commit") == GIT_OBJ_COMMIT);
+	cl_assert(git_object_string2type("tree") == GIT_OBJ_TREE);
+	cl_assert(git_object_string2type("blob") == GIT_OBJ_BLOB);
+	cl_assert(git_object_string2type("tag") == GIT_OBJ_TAG);
+	cl_assert(git_object_string2type("OFS_DELTA") == GIT_OBJ_OFS_DELTA);
+	cl_assert(git_object_string2type("REF_DELTA") == GIT_OBJ_REF_DELTA);
+
+	cl_assert(git_object_string2type("CoMmIt") == GIT_OBJ_BAD);
+	cl_assert(git_object_string2type("hohoho") == GIT_OBJ_BAD);
+}
+
+void test_object_raw_type2string__check_type_is_loose(void)
+{
+	cl_assert(git_object_typeisloose(GIT_OBJ_BAD) == 0);
+	cl_assert(git_object_typeisloose(GIT_OBJ__EXT1) == 0);
+	cl_assert(git_object_typeisloose(GIT_OBJ_COMMIT) == 1);
+	cl_assert(git_object_typeisloose(GIT_OBJ_TREE) == 1);
+	cl_assert(git_object_typeisloose(GIT_OBJ_BLOB) == 1);
+	cl_assert(git_object_typeisloose(GIT_OBJ_TAG) == 1);
+	cl_assert(git_object_typeisloose(GIT_OBJ__EXT2) == 0);
+	cl_assert(git_object_typeisloose(GIT_OBJ_OFS_DELTA) == 0);
+	cl_assert(git_object_typeisloose(GIT_OBJ_REF_DELTA) == 0);
+
+	cl_assert(git_object_typeisloose(-2) == 0);
+	cl_assert(git_object_typeisloose(8) == 0);
+	cl_assert(git_object_typeisloose(1234) == 0);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/write.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/write.c
new file mode 100755
index 0000000..273f08f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/raw/write.c
@@ -0,0 +1,462 @@
+#include "clar_libgit2.h"
+#include "git2/odb_backend.h"
+
+#include "fileops.h"
+#include "odb.h"
+
+typedef struct object_data {
+    char *id;     /* object id (sha1)                          */
+    char *dir;    /* object store (fan-out) directory name     */
+    char *file;   /* object store filename                     */
+} object_data;
+
+static const char *odb_dir = "test-objects";
+
+void test_body(object_data *d, git_rawobj *o);
+
+
+
+// Helpers
+static void remove_object_files(object_data *d)
+{
+   cl_git_pass(p_unlink(d->file));
+   cl_git_pass(p_rmdir(d->dir));
+   cl_assert(errno != ENOTEMPTY);
+   cl_git_pass(p_rmdir(odb_dir) < 0);
+}
+
+static void streaming_write(git_oid *oid, git_odb *odb, git_rawobj *raw)
+{
+   git_odb_stream *stream;
+   int error;
+
+   cl_git_pass(git_odb_open_wstream(&stream, odb, raw->len, raw->type));
+   git_odb_stream_write(stream, raw->data, raw->len);
+   error = git_odb_stream_finalize_write(oid, stream);
+   git_odb_stream_free(stream);
+   cl_git_pass(error);
+}
+
+static void check_object_files(object_data *d)
+{
+   cl_assert(git_path_exists(d->dir));
+   cl_assert(git_path_exists(d->file));
+}
+
+static void cmp_objects(git_rawobj *o1, git_rawobj *o2)
+{
+   cl_assert(o1->type == o2->type);
+   cl_assert(o1->len == o2->len);
+   if (o1->len > 0)
+      cl_assert(memcmp(o1->data, o2->data, o1->len) == 0);
+}
+
+static void make_odb_dir(void)
+{
+	cl_git_pass(p_mkdir(odb_dir, GIT_OBJECT_DIR_MODE));
+}
+
+
+// Standard test form
+void test_body(object_data *d, git_rawobj *o) 
+{
+   git_odb *db;
+   git_oid id1, id2;
+   git_odb_object *obj;
+   git_rawobj tmp;
+
+   make_odb_dir();
+   cl_git_pass(git_odb_open(&db, odb_dir));
+   cl_git_pass(git_oid_fromstr(&id1, d->id));
+
+   streaming_write(&id2, db, o);
+   cl_assert(git_oid_cmp(&id1, &id2) == 0);
+   check_object_files(d);
+
+   cl_git_pass(git_odb_read(&obj, db, &id1));
+
+   tmp.data = obj->buffer;
+   tmp.len = obj->cached.size;
+   tmp.type = obj->cached.type;
+
+   cmp_objects(&tmp, o);
+
+   git_odb_object_free(obj);
+   git_odb_free(db);
+   remove_object_files(d);
+}
+
+
+void test_object_raw_write__loose_object(void)
+{
+   object_data commit = {
+      "3d7f8a6af076c8c3f20071a8935cdbe8228594d1",
+      "test-objects/3d",
+      "test-objects/3d/7f8a6af076c8c3f20071a8935cdbe8228594d1",
+   };
+
+   unsigned char commit_data[] = {
+      0x74, 0x72, 0x65, 0x65, 0x20, 0x64, 0x66, 0x66,
+      0x32, 0x64, 0x61, 0x39, 0x30, 0x62, 0x32, 0x35,
+      0x34, 0x65, 0x31, 0x62, 0x65, 0x62, 0x38, 0x38,
+      0x39, 0x64, 0x31, 0x66, 0x31, 0x66, 0x31, 0x32,
+      0x38, 0x38, 0x62, 0x65, 0x31, 0x38, 0x30, 0x33,
+      0x37, 0x38, 0x32, 0x64, 0x66, 0x0a, 0x61, 0x75,
+      0x74, 0x68, 0x6f, 0x72, 0x20, 0x41, 0x20, 0x55,
+      0x20, 0x54, 0x68, 0x6f, 0x72, 0x20, 0x3c, 0x61,
+      0x75, 0x74, 0x68, 0x6f, 0x72, 0x40, 0x65, 0x78,
+      0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+      0x6d, 0x3e, 0x20, 0x31, 0x32, 0x32, 0x37, 0x38,
+      0x31, 0x34, 0x32, 0x39, 0x37, 0x20, 0x2b, 0x30,
+      0x30, 0x30, 0x30, 0x0a, 0x63, 0x6f, 0x6d, 0x6d,
+      0x69, 0x74, 0x74, 0x65, 0x72, 0x20, 0x43, 0x20,
+      0x4f, 0x20, 0x4d, 0x69, 0x74, 0x74, 0x65, 0x72,
+      0x20, 0x3c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
+      0x74, 0x65, 0x72, 0x40, 0x65, 0x78, 0x61, 0x6d,
+      0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3e,
+      0x20, 0x31, 0x32, 0x32, 0x37, 0x38, 0x31, 0x34,
+      0x32, 0x39, 0x37, 0x20, 0x2b, 0x30, 0x30, 0x30,
+      0x30, 0x0a, 0x0a, 0x41, 0x20, 0x6f, 0x6e, 0x65,
+      0x2d, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x63, 0x6f,
+      0x6d, 0x6d, 0x69, 0x74, 0x20, 0x73, 0x75, 0x6d,
+      0x6d, 0x61, 0x72, 0x79, 0x0a, 0x0a, 0x54, 0x68,
+      0x65, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x6f,
+      0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f,
+      0x6d, 0x6d, 0x69, 0x74, 0x20, 0x6d, 0x65, 0x73,
+      0x73, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x63, 0x6f,
+      0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67,
+      0x20, 0x66, 0x75, 0x72, 0x74, 0x68, 0x65, 0x72,
+      0x20, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x6e, 0x61,
+      0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x6f, 0x66, 0x20,
+      0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x72, 0x70,
+      0x6f, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74,
+      0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67,
+      0x65, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x72, 0x6f,
+      0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79,
+      0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d,
+      0x6d, 0x69, 0x74, 0x2e, 0x0a, 0x0a, 0x53, 0x69,
+      0x67, 0x6e, 0x65, 0x64, 0x2d, 0x6f, 0x66, 0x2d,
+      0x62, 0x79, 0x3a, 0x20, 0x41, 0x20, 0x55, 0x20,
+      0x54, 0x68, 0x6f, 0x72, 0x20, 0x3c, 0x61, 0x75,
+      0x74, 0x68, 0x6f, 0x72, 0x40, 0x65, 0x78, 0x61,
+      0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+      0x3e, 0x0a,
+   };
+
+   git_rawobj commit_obj = {
+      commit_data,
+      sizeof(commit_data),
+      GIT_OBJ_COMMIT
+   };
+
+   test_body(&commit, &commit_obj);
+}
+
+void test_object_raw_write__loose_tree(void)
+{
+   static object_data tree = {
+      "dff2da90b254e1beb889d1f1f1288be1803782df",
+      "test-objects/df",
+      "test-objects/df/f2da90b254e1beb889d1f1f1288be1803782df",
+   };
+
+   static unsigned char tree_data[] = {
+      0x31, 0x30, 0x30, 0x36, 0x34, 0x34, 0x20, 0x6f,
+      0x6e, 0x65, 0x00, 0x8b, 0x13, 0x78, 0x91, 0x79,
+      0x1f, 0xe9, 0x69, 0x27, 0xad, 0x78, 0xe6, 0x4b,
+      0x0a, 0xad, 0x7b, 0xde, 0xd0, 0x8b, 0xdc, 0x31,
+      0x30, 0x30, 0x36, 0x34, 0x34, 0x20, 0x73, 0x6f,
+      0x6d, 0x65, 0x00, 0xfd, 0x84, 0x30, 0xbc, 0x86,
+      0x4c, 0xfc, 0xd5, 0xf1, 0x0e, 0x55, 0x90, 0xf8,
+      0xa4, 0x47, 0xe0, 0x1b, 0x94, 0x2b, 0xfe, 0x31,
+      0x30, 0x30, 0x36, 0x34, 0x34, 0x20, 0x74, 0x77,
+      0x6f, 0x00, 0x78, 0x98, 0x19, 0x22, 0x61, 0x3b,
+      0x2a, 0xfb, 0x60, 0x25, 0x04, 0x2f, 0xf6, 0xbd,
+      0x87, 0x8a, 0xc1, 0x99, 0x4e, 0x85, 0x31, 0x30,
+      0x30, 0x36, 0x34, 0x34, 0x20, 0x7a, 0x65, 0x72,
+      0x6f, 0x00, 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1,
+      0xd6, 0x43, 0x4b, 0x8b, 0x29, 0xae, 0x77, 0x5a,
+      0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91,
+   };
+
+   static git_rawobj tree_obj = {
+      tree_data,
+      sizeof(tree_data),
+      GIT_OBJ_TREE
+   };
+
+   test_body(&tree, &tree_obj);
+}
+
+void test_object_raw_write__loose_tag(void)
+{
+   static object_data tag = {
+      "09d373e1dfdc16b129ceec6dd649739911541e05",
+      "test-objects/09",
+      "test-objects/09/d373e1dfdc16b129ceec6dd649739911541e05",
+   };
+
+   static unsigned char tag_data[] = {
+      0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x33,
+      0x64, 0x37, 0x66, 0x38, 0x61, 0x36, 0x61, 0x66,
+      0x30, 0x37, 0x36, 0x63, 0x38, 0x63, 0x33, 0x66,
+      0x32, 0x30, 0x30, 0x37, 0x31, 0x61, 0x38, 0x39,
+      0x33, 0x35, 0x63, 0x64, 0x62, 0x65, 0x38, 0x32,
+      0x32, 0x38, 0x35, 0x39, 0x34, 0x64, 0x31, 0x0a,
+      0x74, 0x79, 0x70, 0x65, 0x20, 0x63, 0x6f, 0x6d,
+      0x6d, 0x69, 0x74, 0x0a, 0x74, 0x61, 0x67, 0x20,
+      0x76, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0a, 0x74,
+      0x61, 0x67, 0x67, 0x65, 0x72, 0x20, 0x43, 0x20,
+      0x4f, 0x20, 0x4d, 0x69, 0x74, 0x74, 0x65, 0x72,
+      0x20, 0x3c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
+      0x74, 0x65, 0x72, 0x40, 0x65, 0x78, 0x61, 0x6d,
+      0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3e,
+      0x20, 0x31, 0x32, 0x32, 0x37, 0x38, 0x31, 0x34,
+      0x32, 0x39, 0x37, 0x20, 0x2b, 0x30, 0x30, 0x30,
+      0x30, 0x0a, 0x0a, 0x54, 0x68, 0x69, 0x73, 0x20,
+      0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74,
+      0x61, 0x67, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63,
+      0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x72, 0x65,
+      0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x76, 0x30,
+      0x2e, 0x30, 0x2e, 0x31, 0x0a,
+   };
+
+   static git_rawobj tag_obj = {
+      tag_data,
+      sizeof(tag_data),
+      GIT_OBJ_TAG
+   };
+
+
+   test_body(&tag, &tag_obj);
+}
+
+void test_object_raw_write__zero_length(void)
+{
+   static object_data zero = {
+      "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+      "test-objects/e6",
+      "test-objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+   };
+
+   static unsigned char zero_data[] = {
+      0x00  /* dummy data */
+   };
+
+   static git_rawobj zero_obj = {
+      zero_data,
+      0,
+      GIT_OBJ_BLOB
+   };
+
+   test_body(&zero, &zero_obj);
+}
+
+void test_object_raw_write__one_byte(void)
+{
+   static object_data one = {
+      "8b137891791fe96927ad78e64b0aad7bded08bdc",
+      "test-objects/8b",
+      "test-objects/8b/137891791fe96927ad78e64b0aad7bded08bdc",
+   };
+
+   static unsigned char one_data[] = {
+      0x0a,
+   };
+
+   static git_rawobj one_obj = {
+      one_data,
+      sizeof(one_data),
+      GIT_OBJ_BLOB
+   };
+
+   test_body(&one, &one_obj);
+}
+
+void test_object_raw_write__two_byte(void)
+{
+   static object_data two = {
+      "78981922613b2afb6025042ff6bd878ac1994e85",
+      "test-objects/78",
+      "test-objects/78/981922613b2afb6025042ff6bd878ac1994e85",
+   };
+
+   static unsigned char two_data[] = {
+      0x61, 0x0a,
+   };
+
+   static git_rawobj two_obj = {
+      two_data,
+      sizeof(two_data),
+      GIT_OBJ_BLOB
+   };
+
+   test_body(&two, &two_obj);
+}
+
+void test_object_raw_write__several_bytes(void)
+{
+   static object_data some = {
+      "fd8430bc864cfcd5f10e5590f8a447e01b942bfe",
+      "test-objects/fd",
+      "test-objects/fd/8430bc864cfcd5f10e5590f8a447e01b942bfe",
+   };
+
+   static unsigned char some_data[] = {
+      0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x54, 0x68,
+      0x69, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20,
+      0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20,
+      0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
+      0x3b, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x63, 0x61,
+      0x6e, 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74,
+      0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x69,
+      0x74, 0x20, 0x61, 0x6e, 0x64, 0x2f, 0x6f, 0x72,
+      0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0a,
+      0x20, 0x2a, 0x20, 0x69, 0x74, 0x20, 0x75, 0x6e,
+      0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20,
+      0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66,
+      0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x4e, 0x55,
+      0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
+      0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+      0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x2c,
+      0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+      0x20, 0x32, 0x2c, 0x0a, 0x20, 0x2a, 0x20, 0x61,
+      0x73, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73,
+      0x68, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
+      0x68, 0x65, 0x20, 0x46, 0x72, 0x65, 0x65, 0x20,
+      0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
+      0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74,
+      0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x20, 0x2a, 0x0a,
+      0x20, 0x2a, 0x20, 0x49, 0x6e, 0x20, 0x61, 0x64,
+      0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74,
+      0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x65,
+      0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
+      0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
+      0x20, 0x47, 0x4e, 0x55, 0x20, 0x47, 0x65, 0x6e,
+      0x65, 0x72, 0x61, 0x6c, 0x20, 0x50, 0x75, 0x62,
+      0x6c, 0x69, 0x63, 0x20, 0x4c, 0x69, 0x63, 0x65,
+      0x6e, 0x73, 0x65, 0x2c, 0x0a, 0x20, 0x2a, 0x20,
+      0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68,
+      0x6f, 0x72, 0x73, 0x20, 0x67, 0x69, 0x76, 0x65,
+      0x20, 0x79, 0x6f, 0x75, 0x20, 0x75, 0x6e, 0x6c,
+      0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x20, 0x70,
+      0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f,
+      0x6e, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x69, 0x6e,
+      0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f,
+      0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x0a, 0x20,
+      0x2a, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
+      0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69,
+      0x73, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x69,
+      0x6e, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x62,
+      0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+      0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x74,
+      0x68, 0x65, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x67,
+      0x72, 0x61, 0x6d, 0x73, 0x2c, 0x0a, 0x20, 0x2a,
+      0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x20,
+      0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75,
+      0x74, 0x65, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65,
+      0x20, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61,
+      0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x77, 0x69,
+      0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x6e,
+      0x79, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69,
+      0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x2a,
+      0x20, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x20,
+      0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65,
+      0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20,
+      0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6c,
+      0x65, 0x2e, 0x20, 0x20, 0x28, 0x54, 0x68, 0x65,
+      0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
+      0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+      0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x0a,
+      0x20, 0x2a, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72,
+      0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20,
+      0x64, 0x6f, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79,
+      0x20, 0x69, 0x6e, 0x20, 0x6f, 0x74, 0x68, 0x65,
+      0x72, 0x20, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63,
+      0x74, 0x73, 0x3b, 0x20, 0x66, 0x6f, 0x72, 0x20,
+      0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c,
+      0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x63, 0x6f,
+      0x76, 0x65, 0x72, 0x0a, 0x20, 0x2a, 0x20, 0x6d,
+      0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+      0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74,
+      0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2c,
+      0x20, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x69, 0x73,
+      0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f,
+      0x6e, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x6e,
+      0x6f, 0x74, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x65,
+      0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x0a, 0x20,
+      0x2a, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6d, 0x62,
+      0x69, 0x6e, 0x65, 0x64, 0x20, 0x65, 0x78, 0x65,
+      0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e,
+      0x29, 0x0a, 0x20, 0x2a, 0x0a, 0x20, 0x2a, 0x20,
+      0x54, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6c,
+      0x65, 0x20, 0x69, 0x73, 0x20, 0x64, 0x69, 0x73,
+      0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64,
+      0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20,
+      0x68, 0x6f, 0x70, 0x65, 0x20, 0x74, 0x68, 0x61,
+      0x74, 0x20, 0x69, 0x74, 0x20, 0x77, 0x69, 0x6c,
+      0x6c, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65,
+      0x66, 0x75, 0x6c, 0x2c, 0x20, 0x62, 0x75, 0x74,
+      0x0a, 0x20, 0x2a, 0x20, 0x57, 0x49, 0x54, 0x48,
+      0x4f, 0x55, 0x54, 0x20, 0x41, 0x4e, 0x59, 0x20,
+      0x57, 0x41, 0x52, 0x52, 0x41, 0x4e, 0x54, 0x59,
+      0x3b, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75,
+      0x74, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x74,
+      0x68, 0x65, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x69,
+      0x65, 0x64, 0x20, 0x77, 0x61, 0x72, 0x72, 0x61,
+      0x6e, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x0a, 0x20,
+      0x2a, 0x20, 0x4d, 0x45, 0x52, 0x43, 0x48, 0x41,
+      0x4e, 0x54, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54,
+      0x59, 0x20, 0x6f, 0x72, 0x20, 0x46, 0x49, 0x54,
+      0x4e, 0x45, 0x53, 0x53, 0x20, 0x46, 0x4f, 0x52,
+      0x20, 0x41, 0x20, 0x50, 0x41, 0x52, 0x54, 0x49,
+      0x43, 0x55, 0x4c, 0x41, 0x52, 0x20, 0x50, 0x55,
+      0x52, 0x50, 0x4f, 0x53, 0x45, 0x2e, 0x20, 0x20,
+      0x53, 0x65, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
+      0x47, 0x4e, 0x55, 0x0a, 0x20, 0x2a, 0x20, 0x47,
+      0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x50,
+      0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x4c, 0x69,
+      0x63, 0x65, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6f,
+      0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64,
+      0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x0a,
+      0x20, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x59, 0x6f,
+      0x75, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64,
+      0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x72, 0x65,
+      0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x20, 0x61,
+      0x20, 0x63, 0x6f, 0x70, 0x79, 0x20, 0x6f, 0x66,
+      0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x4e, 0x55,
+      0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
+      0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+      0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x0a,
+      0x20, 0x2a, 0x20, 0x61, 0x6c, 0x6f, 0x6e, 0x67,
+      0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68,
+      0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72,
+      0x61, 0x6d, 0x3b, 0x20, 0x73, 0x65, 0x65, 0x20,
+      0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65,
+      0x20, 0x43, 0x4f, 0x50, 0x59, 0x49, 0x4e, 0x47,
+      0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x6e, 0x6f,
+      0x74, 0x2c, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65,
+      0x20, 0x74, 0x6f, 0x0a, 0x20, 0x2a, 0x20, 0x74,
+      0x68, 0x65, 0x20, 0x46, 0x72, 0x65, 0x65, 0x20,
+      0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
+      0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74,
+      0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x35, 0x31, 0x20,
+      0x46, 0x72, 0x61, 0x6e, 0x6b, 0x6c, 0x69, 0x6e,
+      0x20, 0x53, 0x74, 0x72, 0x65, 0x65, 0x74, 0x2c,
+      0x20, 0x46, 0x69, 0x66, 0x74, 0x68, 0x20, 0x46,
+      0x6c, 0x6f, 0x6f, 0x72, 0x2c, 0x0a, 0x20, 0x2a,
+      0x20, 0x42, 0x6f, 0x73, 0x74, 0x6f, 0x6e, 0x2c,
+      0x20, 0x4d, 0x41, 0x20, 0x30, 0x32, 0x31, 0x31,
+      0x30, 0x2d, 0x31, 0x33, 0x30, 0x31, 0x2c, 0x20,
+      0x55, 0x53, 0x41, 0x2e, 0x0a, 0x20, 0x2a, 0x2f,
+      0x0a,
+   };
+
+   static git_rawobj some_obj = {
+      some_data,
+      sizeof(some_data),
+      GIT_OBJ_BLOB
+   };
+
+   test_body(&some, &some_obj);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/shortid.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/shortid.c
new file mode 100755
index 0000000..d854cb7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/shortid.c
@@ -0,0 +1,51 @@
+#include "clar_libgit2.h"
+
+git_repository *_repo;
+
+void test_object_shortid__initialize(void)
+{
+	cl_git_pass(git_repository_open(&_repo, cl_fixture("duplicate.git")));
+}
+
+void test_object_shortid__cleanup(void)
+{
+	git_repository_free(_repo);
+	_repo = NULL;
+}
+
+void test_object_shortid__select(void)
+{
+	git_oid full;
+	git_object *obj;
+	git_buf shorty = {0};
+
+	git_oid_fromstr(&full, "ce013625030ba8dba906f756967f9e9ca394464a");
+	cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJ_ANY));
+	cl_git_pass(git_object_short_id(&shorty, obj));
+	cl_assert_equal_i(7, shorty.size);
+	cl_assert_equal_s("ce01362", shorty.ptr);
+	git_object_free(obj);
+
+	git_oid_fromstr(&full, "038d718da6a1ebbc6a7780a96ed75a70cc2ad6e2");
+	cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJ_ANY));
+	cl_git_pass(git_object_short_id(&shorty, obj));
+	cl_assert_equal_i(7, shorty.size);
+	cl_assert_equal_s("038d718", shorty.ptr);
+	git_object_free(obj);
+
+	git_oid_fromstr(&full, "dea509d097ce692e167dfc6a48a7a280cc5e877e");
+	cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJ_ANY));
+	cl_git_pass(git_object_short_id(&shorty, obj));
+	cl_assert_equal_i(9, shorty.size);
+	cl_assert_equal_s("dea509d09", shorty.ptr);
+	git_object_free(obj);
+
+	git_oid_fromstr(&full, "dea509d0b3cb8ee0650f6ca210bc83f4678851ba");
+	cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJ_ANY));
+	cl_git_pass(git_object_short_id(&shorty, obj));
+	cl_assert_equal_i(9, shorty.size);
+	cl_assert_equal_s("dea509d0b", shorty.ptr);
+	git_object_free(obj);
+
+	git_buf_free(&shorty);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tag/list.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tag/list.c
new file mode 100755
index 0000000..6d5a243
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tag/list.c
@@ -0,0 +1,115 @@
+#include "clar_libgit2.h"
+
+#include "tag.h"
+
+static git_repository *g_repo;
+
+#define MAX_USED_TAGS 6
+
+struct pattern_match_t
+{
+	const char* pattern;
+	const size_t expected_matches;
+	const char* expected_results[MAX_USED_TAGS];
+};
+
+// Helpers
+static void ensure_tag_pattern_match(git_repository *repo,
+									 const struct pattern_match_t* data)
+{
+	int already_found[MAX_USED_TAGS] = { 0 };
+	git_strarray tag_list;
+	int error = 0;
+	size_t sucessfully_found = 0;
+	size_t i, j;
+
+	cl_assert(data->expected_matches <= MAX_USED_TAGS);
+
+	if ((error = git_tag_list_match(&tag_list, data->pattern, repo)) < 0)
+		goto exit;
+
+	if (tag_list.count != data->expected_matches)
+	{
+		error = GIT_ERROR;
+		goto exit;
+	}
+
+	// we have to be prepared that tags come in any order.
+	for (i = 0; i < tag_list.count; i++)
+	{
+		for (j = 0; j < data->expected_matches; j++)
+		{
+			if (!already_found[j] && !strcmp(data->expected_results[j], tag_list.strings[i]))
+			{
+				already_found[j] = 1;
+				sucessfully_found++;
+				break;
+			}
+		}
+	}
+	cl_assert_equal_i((int)sucessfully_found, (int)data->expected_matches);
+
+exit:
+	git_strarray_free(&tag_list);
+	cl_git_pass(error);
+}
+
+// Fixture setup and teardown
+void test_object_tag_list__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_object_tag_list__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_object_tag_list__list_all(void)
+{
+	// list all tag names from the repository
+	git_strarray tag_list;
+
+	cl_git_pass(git_tag_list(&tag_list, g_repo));
+
+	cl_assert_equal_i((int)tag_list.count, 6);
+
+	git_strarray_free(&tag_list);
+}
+
+static const struct pattern_match_t matches[] = {
+	// All tags, including a packed one and two namespaced ones.
+	{ "", 6, { "e90810b", "point_to_blob", "test", "packed-tag", "foo/bar", "foo/foo/bar" } },
+
+	// beginning with
+	{ "t*", 1, { "test" } },
+
+	// ending with
+	{ "*b", 2, { "e90810b", "point_to_blob" } },
+
+	// exact match
+	{ "e", 0 },
+	{ "e90810b", 1, { "e90810b" } },
+
+	// either or
+	{ "e90810[ab]", 1, { "e90810b" } },
+
+	// glob in the middle
+	{ "foo/*/bar", 1, { "foo/foo/bar" } },
+
+	// The matching of '*' is based on plain string matching analog to the regular expression ".*"
+	// => a '/' in the tag name has no special meaning.
+	// Compare to `git tag -l "*bar"`
+	{ "*bar", 2, { "foo/bar", "foo/foo/bar" } },
+
+	// End of list
+	{ NULL }
+};
+
+void test_object_tag_list__list_by_pattern(void)
+{
+	// list all tag names from the repository matching a specified pattern
+	size_t i = 0;
+	while (matches[i].pattern)
+		ensure_tag_pattern_match(g_repo, &matches[i++]);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tag/peel.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tag/peel.c
new file mode 100755
index 0000000..e2cd8d6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tag/peel.c
@@ -0,0 +1,61 @@
+#include "clar_libgit2.h"
+#include "tag.h"
+
+static git_repository *repo;
+static git_tag *tag;
+static git_object *target;
+
+void test_object_tag_peel__initialize(void)
+{
+	cl_fixture_sandbox("testrepo.git");
+	cl_git_pass(git_repository_open(&repo, "testrepo.git"));
+}
+
+void test_object_tag_peel__cleanup(void)
+{
+	git_tag_free(tag);
+	tag = NULL;
+
+	git_object_free(target);
+	target = NULL;
+
+	git_repository_free(repo);
+	repo = NULL;
+
+	cl_fixture_cleanup("testrepo.git");
+}
+
+static void retrieve_tag_from_oid(git_tag **tag_out, git_repository *repo, const char *sha)
+{
+	git_oid oid;
+	
+	cl_git_pass(git_oid_fromstr(&oid, sha));
+	cl_git_pass(git_tag_lookup(tag_out, repo, &oid));
+}
+
+void test_object_tag_peel__can_peel_to_a_commit(void)
+{
+	retrieve_tag_from_oid(&tag, repo, "7b4384978d2493e851f9cca7858815fac9b10980");
+
+	cl_git_pass(git_tag_peel(&target, tag));
+	cl_assert(git_object_type(target) == GIT_OBJ_COMMIT);
+	cl_git_pass(git_oid_streq(git_object_id(target), "e90810b8df3e80c413d903f631643c716887138d"));
+}
+
+void test_object_tag_peel__can_peel_several_nested_tags_to_a_commit(void)
+{
+	retrieve_tag_from_oid(&tag, repo, "b25fa35b38051e4ae45d4222e795f9df2e43f1d1");
+
+	cl_git_pass(git_tag_peel(&target, tag));
+	cl_assert(git_object_type(target) == GIT_OBJ_COMMIT);
+	cl_git_pass(git_oid_streq(git_object_id(target), "e90810b8df3e80c413d903f631643c716887138d"));
+}
+
+void test_object_tag_peel__can_peel_to_a_non_commit(void)
+{
+	retrieve_tag_from_oid(&tag, repo, "521d87c1ec3aef9824daf6d96cc0ae3710766d91");
+
+	cl_git_pass(git_tag_peel(&target, tag));
+	cl_assert(git_object_type(target) == GIT_OBJ_BLOB);
+	cl_git_pass(git_oid_streq(git_object_id(target), "1385f264afb75a56a5bec74243be9b367ba4ca08"));	
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tag/read.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tag/read.c
new file mode 100755
index 0000000..c9787a4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tag/read.c
@@ -0,0 +1,142 @@
+#include "clar_libgit2.h"
+
+#include "tag.h"
+
+static const char *tag1_id = "b25fa35b38051e4ae45d4222e795f9df2e43f1d1";
+static const char *tag2_id = "7b4384978d2493e851f9cca7858815fac9b10980";
+static const char *tagged_commit = "e90810b8df3e80c413d903f631643c716887138d";
+static const char *bad_tag_id = "eda9f45a2a98d4c17a09d681d88569fa4ea91755";
+static const char *badly_tagged_commit = "e90810b8df3e80c413d903f631643c716887138d";
+static const char *short_tag_id = "5da7760512a953e3c7c4e47e4392c7a4338fb729";
+static const char *short_tagged_commit = "4a5ed60bafcf4638b7c8356bd4ce1916bfede93c";
+static const char *taggerless = "4a23e2e65ad4e31c4c9db7dc746650bfad082679";
+
+static git_repository *g_repo;
+
+// Fixture setup and teardown
+void test_object_tag_read__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_object_tag_read__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+
+void test_object_tag_read__parse(void)
+{
+	// read and parse a tag from the repository
+	git_tag *tag1, *tag2;
+	git_commit *commit;
+	git_oid id1, id2, id_commit;
+
+	git_oid_fromstr(&id1, tag1_id);
+	git_oid_fromstr(&id2, tag2_id);
+	git_oid_fromstr(&id_commit, tagged_commit);
+
+	cl_git_pass(git_tag_lookup(&tag1, g_repo, &id1));
+
+	cl_assert_equal_s(git_tag_name(tag1), "test");
+	cl_assert(git_tag_target_type(tag1) == GIT_OBJ_TAG);
+
+	cl_git_pass(git_tag_target((git_object **)&tag2, tag1));
+	cl_assert(tag2 != NULL);
+
+	cl_assert(git_oid_cmp(&id2, git_tag_id(tag2)) == 0);
+
+	cl_git_pass(git_tag_target((git_object **)&commit, tag2));
+	cl_assert(commit != NULL);
+
+	cl_assert(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0);
+
+	git_tag_free(tag1);
+	git_tag_free(tag2);
+	git_commit_free(commit);
+}
+
+void test_object_tag_read__parse_without_tagger(void)
+{
+	// read and parse a tag without a tagger field
+	git_repository *bad_tag_repo;
+	git_tag *bad_tag;
+	git_commit *commit;
+	git_oid id, id_commit;
+
+	// TODO: This is a little messy
+	cl_git_pass(git_repository_open(&bad_tag_repo, cl_fixture("bad_tag.git")));
+
+	git_oid_fromstr(&id, bad_tag_id);
+	git_oid_fromstr(&id_commit, badly_tagged_commit);
+
+	cl_git_pass(git_tag_lookup(&bad_tag, bad_tag_repo, &id));
+	cl_assert(bad_tag != NULL);
+
+	cl_assert_equal_s(git_tag_name(bad_tag), "e90810b");
+	cl_assert(git_oid_cmp(&id, git_tag_id(bad_tag)) == 0);
+	cl_assert(bad_tag->tagger == NULL);
+
+	cl_git_pass(git_tag_target((git_object **)&commit, bad_tag));
+	cl_assert(commit != NULL);
+
+	cl_assert(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0);
+
+
+	git_tag_free(bad_tag);
+	git_commit_free(commit);
+	git_repository_free(bad_tag_repo);
+}
+
+void test_object_tag_read__parse_without_message(void)
+{
+	// read and parse a tag without a message field
+	git_repository *short_tag_repo;
+	git_tag *short_tag;
+	git_commit *commit;
+	git_oid id, id_commit;
+
+	// TODO: This is a little messy
+	cl_git_pass(git_repository_open(&short_tag_repo, cl_fixture("short_tag.git")));
+
+	git_oid_fromstr(&id, short_tag_id);
+	git_oid_fromstr(&id_commit, short_tagged_commit);
+
+	cl_git_pass(git_tag_lookup(&short_tag, short_tag_repo, &id));
+	cl_assert(short_tag != NULL);
+
+	cl_assert_equal_s(git_tag_name(short_tag), "no_description");
+	cl_assert(git_oid_cmp(&id, git_tag_id(short_tag)) == 0);
+	cl_assert(short_tag->message == NULL);
+
+	cl_git_pass(git_tag_target((git_object **)&commit, short_tag));
+	cl_assert(commit != NULL);
+
+	cl_assert(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0);
+
+	git_tag_free(short_tag);
+	git_commit_free(commit);
+	git_repository_free(short_tag_repo);
+}
+
+void test_object_tag_read__without_tagger_nor_message(void)
+{
+	git_tag *tag;
+	git_oid id;
+	git_repository *repo;
+
+	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+
+	cl_git_pass(git_oid_fromstr(&id, taggerless));
+
+	cl_git_pass(git_tag_lookup(&tag, repo, &id));
+
+	cl_assert_equal_s(git_tag_name(tag), "taggerless");
+	cl_assert(git_tag_target_type(tag) == GIT_OBJ_COMMIT);
+
+	cl_assert(tag->message == NULL);
+	cl_assert(tag->tagger == NULL);
+
+	git_tag_free(tag);
+	git_repository_free(repo);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tag/write.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tag/write.c
new file mode 100755
index 0000000..68e4b6c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tag/write.c
@@ -0,0 +1,260 @@
+#include "clar_libgit2.h"
+
+static const char* tagger_name = "Vicent Marti";
+static const char* tagger_email = "vicent at github.com";
+static const char* tagger_message = "This is my tag.\n\nThere are many tags, but this one is mine\n";
+
+static const char *tag2_id = "7b4384978d2493e851f9cca7858815fac9b10980";
+static const char *tagged_commit = "e90810b8df3e80c413d903f631643c716887138d";
+
+static git_repository *g_repo;
+
+// Fixture setup and teardown
+void test_object_tag_write__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_object_tag_write__cleanup(void)
+{
+   cl_git_sandbox_cleanup();
+}
+
+void test_object_tag_write__basic(void)
+{
+   // write a tag to the repository and read it again
+	git_tag *tag;
+	git_oid target_id, tag_id;
+	git_signature *tagger;
+	const git_signature *tagger1;
+	git_reference *ref_tag;
+	git_object *target;
+
+	git_oid_fromstr(&target_id, tagged_commit);
+	cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJ_COMMIT));
+
+	/* create signature */
+	cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60));
+
+	cl_git_pass(
+		git_tag_create(&tag_id, g_repo,
+		  "the-tag", target, tagger, tagger_message, 0)
+	);
+
+	git_object_free(target);
+	git_signature_free(tagger);
+
+	cl_git_pass(git_tag_lookup(&tag, g_repo, &tag_id));
+	cl_assert(git_oid_cmp(git_tag_target_id(tag), &target_id) == 0);
+
+	/* Check attributes were set correctly */
+	tagger1 = git_tag_tagger(tag);
+	cl_assert(tagger1 != NULL);
+	cl_assert_equal_s(tagger1->name, tagger_name);
+	cl_assert_equal_s(tagger1->email, tagger_email);
+	cl_assert(tagger1->when.time == 123456789);
+	cl_assert(tagger1->when.offset == 60);
+
+	cl_assert_equal_s(git_tag_message(tag), tagger_message);
+
+	cl_git_pass(git_reference_lookup(&ref_tag, g_repo, "refs/tags/the-tag"));
+	cl_assert(git_oid_cmp(git_reference_target(ref_tag), &tag_id) == 0);
+	cl_git_pass(git_reference_delete(ref_tag));
+	git_reference_free(ref_tag);
+
+	git_tag_free(tag);
+}
+
+void test_object_tag_write__overwrite(void)
+{
+   // Attempt to write a tag bearing the same name than an already existing tag
+	git_oid target_id, tag_id;
+	git_signature *tagger;
+	git_object *target;
+
+	git_oid_fromstr(&target_id, tagged_commit);
+	cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJ_COMMIT));
+
+	/* create signature */
+	cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60));
+
+	cl_assert_equal_i(GIT_EEXISTS, git_tag_create(
+                              &tag_id, /* out id */
+                              g_repo,
+                              "e90810b",
+                              target,
+                              tagger,
+                              tagger_message,
+                              0));
+
+	git_object_free(target);
+	git_signature_free(tagger);
+}
+
+void test_object_tag_write__replace(void)
+{
+   // Replace an already existing tag
+	git_oid target_id, tag_id, old_tag_id;
+	git_signature *tagger;
+	git_reference *ref_tag;
+	git_object *target;
+
+	git_oid_fromstr(&target_id, tagged_commit);
+	cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJ_COMMIT));
+
+	cl_git_pass(git_reference_lookup(&ref_tag, g_repo, "refs/tags/e90810b"));
+	git_oid_cpy(&old_tag_id, git_reference_target(ref_tag));
+	git_reference_free(ref_tag);
+
+	/* create signature */
+	cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60));
+
+	cl_git_pass(git_tag_create(
+                              &tag_id, /* out id */
+                              g_repo,
+                              "e90810b",
+                              target,
+                              tagger,
+                              tagger_message,
+                              1));
+
+	git_object_free(target);
+	git_signature_free(tagger);
+
+	cl_git_pass(git_reference_lookup(&ref_tag, g_repo, "refs/tags/e90810b"));
+	cl_assert(git_oid_cmp(git_reference_target(ref_tag), &tag_id) == 0);
+	cl_assert(git_oid_cmp(git_reference_target(ref_tag), &old_tag_id) != 0);
+
+	git_reference_free(ref_tag);
+}
+
+void test_object_tag_write__lightweight(void)
+{
+   // write a lightweight tag to the repository and read it again
+	git_oid target_id, object_id;
+	git_reference *ref_tag;
+	git_object *target;
+
+	git_oid_fromstr(&target_id, tagged_commit);
+	cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJ_COMMIT));
+
+	cl_git_pass(git_tag_create_lightweight(
+                                          &object_id,
+                                          g_repo,
+                                          "light-tag",
+                                          target,
+                                          0));
+
+	git_object_free(target);
+
+	cl_assert(git_oid_cmp(&object_id, &target_id) == 0);
+
+	cl_git_pass(git_reference_lookup(&ref_tag, g_repo, "refs/tags/light-tag"));
+	cl_assert(git_oid_cmp(git_reference_target(ref_tag), &target_id) == 0);
+
+	cl_git_pass(git_tag_delete(g_repo, "light-tag"));
+
+	git_reference_free(ref_tag);
+}
+
+void test_object_tag_write__lightweight_over_existing(void)
+{
+   // Attempt to write a lightweight tag bearing the same name than an already existing tag
+	git_oid target_id, object_id, existing_object_id;
+	git_object *target;
+
+	git_oid_fromstr(&target_id, tagged_commit);
+	cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJ_COMMIT));
+
+	cl_assert_equal_i(GIT_EEXISTS, git_tag_create_lightweight(
+                                          &object_id,
+                                          g_repo,
+                                          "e90810b",
+                                          target,
+                                          0));
+
+	git_oid_fromstr(&existing_object_id, tag2_id);
+	cl_assert(git_oid_cmp(&object_id, &existing_object_id) == 0);
+
+	git_object_free(target);
+}
+
+void test_object_tag_write__delete(void)
+{
+   // Delete an already existing tag
+	git_reference *ref_tag;
+
+	cl_git_pass(git_tag_delete(g_repo, "e90810b"));
+
+	cl_git_fail(git_reference_lookup(&ref_tag, g_repo, "refs/tags/e90810b"));
+
+	git_reference_free(ref_tag);
+}
+
+void test_object_tag_write__creating_with_an_invalid_name_returns_EINVALIDSPEC(void)
+{
+	git_oid target_id, tag_id;
+	git_signature *tagger;
+	git_object *target;
+
+	git_oid_fromstr(&target_id, tagged_commit);
+	cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJ_COMMIT));
+
+	cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60));
+
+	cl_assert_equal_i(GIT_EINVALIDSPEC,
+		git_tag_create(&tag_id, g_repo,
+		  "Inv@{id", target, tagger, tagger_message, 0)
+	);
+
+	cl_assert_equal_i(GIT_EINVALIDSPEC,
+		git_tag_create_lightweight(&tag_id, g_repo,
+		  "Inv@{id", target, 0)
+	);
+
+	git_object_free(target);
+	git_signature_free(tagger);
+}
+
+void test_object_tag_write__deleting_with_an_invalid_name_returns_EINVALIDSPEC(void)
+{
+	cl_assert_equal_i(GIT_EINVALIDSPEC, git_tag_delete(g_repo, "Inv@{id"));
+}
+
+void create_annotation(git_oid *tag_id, const char *name)
+{
+	git_object *target;
+	git_oid target_id;
+	git_signature *tagger;
+
+	cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60));
+
+	git_oid_fromstr(&target_id, tagged_commit);
+	cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJ_COMMIT));
+
+	cl_git_pass(git_tag_annotation_create(tag_id, g_repo, name, target, tagger, "boom!"));
+	git_object_free(target);
+	git_signature_free(tagger);
+}
+
+void test_object_tag_write__creating_an_annotation_stores_the_new_object_in_the_odb(void)
+{
+	git_oid tag_id;
+	git_tag *tag;
+
+	create_annotation(&tag_id, "new_tag");
+
+	cl_git_pass(git_tag_lookup(&tag, g_repo, &tag_id));
+	cl_assert_equal_s("new_tag", git_tag_name(tag));
+
+	git_tag_free(tag);
+}
+
+void test_object_tag_write__creating_an_annotation_does_not_create_a_reference(void)
+{
+	git_oid tag_id;
+	git_reference *tag_ref;
+
+	create_annotation(&tag_id, "new_tag");
+	cl_git_fail_with(git_reference_lookup(&tag_ref, g_repo, "refs/tags/new_tag"), GIT_ENOTFOUND);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/attributes.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/attributes.c
new file mode 100755
index 0000000..413514c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/attributes.c
@@ -0,0 +1,116 @@
+#include "clar_libgit2.h"
+#include "tree.h"
+
+static git_repository *repo;
+
+static const char *blob_oid = "3d0970ec547fc41ef8a5882dde99c6adce65b021";
+static const char *tree_oid  = "1b05fdaa881ee45b48cbaa5e9b037d667a47745e";
+
+void test_object_tree_attributes__initialize(void)
+{
+	repo = cl_git_sandbox_init("deprecated-mode.git");
+}
+
+void test_object_tree_attributes__cleanup(void)
+{
+   cl_git_sandbox_cleanup();
+}
+
+void test_object_tree_attributes__ensure_correctness_of_attributes_on_insertion(void)
+{
+	git_treebuilder *builder;
+	git_oid oid;
+
+	cl_git_pass(git_oid_fromstr(&oid, blob_oid));
+
+	cl_git_pass(git_treebuilder_new(&builder, repo, NULL));
+
+	cl_git_fail(git_treebuilder_insert(NULL, builder, "one.txt", &oid, (git_filemode_t)0777777));
+	cl_git_fail(git_treebuilder_insert(NULL, builder, "one.txt", &oid, (git_filemode_t)0100666));
+	cl_git_fail(git_treebuilder_insert(NULL, builder, "one.txt", &oid, (git_filemode_t)0000001));
+
+	git_treebuilder_free(builder);
+}
+
+void test_object_tree_attributes__group_writable_tree_entries_created_with_an_antique_git_version_can_still_be_accessed(void)
+{
+	git_oid tid;
+	git_tree *tree;
+	const git_tree_entry *entry;
+
+
+	cl_git_pass(git_oid_fromstr(&tid, tree_oid));
+	cl_git_pass(git_tree_lookup(&tree, repo, &tid));
+
+	entry = git_tree_entry_byname(tree, "old_mode.txt");
+	cl_assert_equal_i(
+		GIT_FILEMODE_BLOB,
+		git_tree_entry_filemode(entry));
+
+	git_tree_free(tree);
+}
+
+void test_object_tree_attributes__treebuilder_reject_invalid_filemode(void)
+{
+	git_treebuilder *builder;
+	git_oid bid;
+	const git_tree_entry *entry;
+
+	cl_git_pass(git_oid_fromstr(&bid, blob_oid));
+	cl_git_pass(git_treebuilder_new(&builder, repo, NULL));
+
+	cl_git_fail(git_treebuilder_insert(
+		&entry,
+		builder,
+		"normalized.txt",
+		&bid,
+		GIT_FILEMODE_BLOB_GROUP_WRITABLE));
+
+	git_treebuilder_free(builder);
+}
+
+void test_object_tree_attributes__normalize_attributes_when_creating_a_tree_from_an_existing_one(void)
+{
+	git_treebuilder *builder;
+	git_oid tid, tid2;
+	git_tree *tree;
+	const git_tree_entry *entry;
+
+	cl_git_pass(git_oid_fromstr(&tid, tree_oid));
+	cl_git_pass(git_tree_lookup(&tree, repo, &tid));
+
+	cl_git_pass(git_treebuilder_new(&builder, repo, tree));
+	
+	entry = git_treebuilder_get(builder, "old_mode.txt");
+	cl_assert_equal_i(
+		GIT_FILEMODE_BLOB,
+		git_tree_entry_filemode(entry));
+
+	cl_git_pass(git_treebuilder_write(&tid2, builder));
+	git_treebuilder_free(builder);
+	git_tree_free(tree);
+
+	cl_git_pass(git_tree_lookup(&tree, repo, &tid2));
+	entry = git_tree_entry_byname(tree, "old_mode.txt");
+	cl_assert_equal_i(
+		GIT_FILEMODE_BLOB,
+		git_tree_entry_filemode(entry));
+
+	git_tree_free(tree);
+}
+
+void test_object_tree_attributes__normalize_600(void)
+{
+	git_oid id;
+	git_tree *tree;
+	const git_tree_entry *entry;
+
+	git_oid_fromstr(&id, "0810fb7818088ff5ac41ee49199b51473b1bd6c7");
+	cl_git_pass(git_tree_lookup(&tree, repo, &id));
+
+	entry = git_tree_entry_byname(tree, "ListaTeste.xml");
+	cl_assert_equal_i(git_tree_entry_filemode(entry), GIT_FILEMODE_BLOB);
+	cl_assert_equal_i(git_tree_entry_filemode_raw(entry), 0100600);
+
+	git_tree_free(tree);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/duplicateentries.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/duplicateentries.c
new file mode 100755
index 0000000..35dd383
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/duplicateentries.c
@@ -0,0 +1,157 @@
+#include "clar_libgit2.h"
+#include "tree.h"
+
+static git_repository *_repo;
+
+void test_object_tree_duplicateentries__initialize(void) {
+   _repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_object_tree_duplicateentries__cleanup(void) {
+   cl_git_sandbox_cleanup();
+}
+
+/*
+ * $ git show --format=raw refs/heads/dir
+ * commit 144344043ba4d4a405da03de3844aa829ae8be0e
+ * tree d52a8fe84ceedf260afe4f0287bbfca04a117e83
+ * parent cf80f8de9f1185bf3a05f993f6121880dd0cfbc9
+ * author Ben Straub <bstraub at github.com> 1343755506 -0700
+ * committer Ben Straub <bstraub at github.com> 1343755506 -0700
+ * 
+ *     Change a file mode
+ * 
+ * diff --git a/a/b.txt b/a/b.txt
+ * old mode 100644
+ * new mode 100755
+ *
+ * $ git ls-tree d52a8fe84ceedf260afe4f0287bbfca04a117e83
+ * 100644 blob a8233120f6ad708f843d861ce2b7228ec4e3dec6    README
+ * 040000 tree 4e0883eeeeebc1fb1735161cea82f7cb5fab7e63    a
+ * 100644 blob 45b983be36b73c0788dc9cbcb76cbb80fc7bb057    branch_file.txt
+ * 100644 blob a71586c1dfe8a71c6cbf6c129f404c5642ff31bd    new.txt
+ */
+
+static void tree_checker(
+	git_oid *tid,
+	const char *expected_sha,
+	git_filemode_t expected_filemode)
+{
+	git_tree *tree;
+	const git_tree_entry *entry;
+	git_oid oid;
+
+	cl_git_pass(git_tree_lookup(&tree, _repo, tid));
+	cl_assert_equal_i(1, (int)git_tree_entrycount(tree));
+	entry = git_tree_entry_byindex(tree, 0);
+
+	cl_git_pass(git_oid_fromstr(&oid, expected_sha));
+
+	cl_assert_equal_i(0, git_oid_cmp(&oid, git_tree_entry_id(entry)));
+	cl_assert_equal_i(expected_filemode, git_tree_entry_filemode(entry));
+
+	git_tree_free(tree);
+}
+
+static void tree_creator(git_oid *out, void (*fn)(git_treebuilder *))
+{
+	git_treebuilder *builder;
+
+	cl_git_pass(git_treebuilder_new(&builder, _repo, NULL));
+
+	fn(builder);
+
+	cl_git_pass(git_treebuilder_write(out, builder));
+	git_treebuilder_free(builder);
+}
+
+static void two_blobs(git_treebuilder *bld)
+{
+	git_oid oid;
+	const git_tree_entry *entry;
+	
+	cl_git_pass(git_oid_fromstr(&oid,
+		"a8233120f6ad708f843d861ce2b7228ec4e3dec6"));	/* blob oid (README) */
+
+	cl_git_pass(git_treebuilder_insert(
+		&entry,	bld, "duplicate", &oid,
+		GIT_FILEMODE_BLOB));
+
+	cl_git_pass(git_oid_fromstr(&oid,
+		"a71586c1dfe8a71c6cbf6c129f404c5642ff31bd"));	/* blob oid (new.txt) */
+
+	cl_git_pass(git_treebuilder_insert(
+		&entry,	bld, "duplicate", &oid,
+		GIT_FILEMODE_BLOB));
+}
+
+static void one_blob_and_one_tree(git_treebuilder *bld)
+{
+	git_oid oid;
+	const git_tree_entry *entry;
+	
+	cl_git_pass(git_oid_fromstr(&oid,
+		"a8233120f6ad708f843d861ce2b7228ec4e3dec6"));	/* blob oid (README) */
+
+	cl_git_pass(git_treebuilder_insert(
+		&entry,	bld, "duplicate", &oid,
+		GIT_FILEMODE_BLOB));
+
+	cl_git_pass(git_oid_fromstr(&oid,
+		"4e0883eeeeebc1fb1735161cea82f7cb5fab7e63"));	/* tree oid (a) */
+
+	cl_git_pass(git_treebuilder_insert(
+		&entry,	bld, "duplicate", &oid,
+		GIT_FILEMODE_TREE));
+}
+
+void test_object_tree_duplicateentries__cannot_create_a_duplicate_entry_through_the_treebuilder(void)
+{
+	git_oid tid;
+
+	tree_creator(&tid, two_blobs);
+	tree_checker(&tid, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd", GIT_FILEMODE_BLOB);
+	
+	tree_creator(&tid, one_blob_and_one_tree);
+	tree_checker(&tid, "4e0883eeeeebc1fb1735161cea82f7cb5fab7e63", GIT_FILEMODE_TREE);
+}
+
+static void add_fake_conflicts(git_index *index)
+{
+	git_index_entry ancestor_entry, our_entry, their_entry;
+
+	memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
+	memset(&our_entry, 0x0, sizeof(git_index_entry));
+	memset(&their_entry, 0x0, sizeof(git_index_entry));
+
+	ancestor_entry.path = "duplicate";
+	ancestor_entry.mode = GIT_FILEMODE_BLOB;
+	GIT_IDXENTRY_STAGE_SET(&ancestor_entry, 1);
+	git_oid_fromstr(&ancestor_entry.id, "a8233120f6ad708f843d861ce2b7228ec4e3dec6");
+
+	our_entry.path = "duplicate";
+	our_entry.mode = GIT_FILEMODE_BLOB;
+	GIT_IDXENTRY_STAGE_SET(&our_entry, 2);
+	git_oid_fromstr(&our_entry.id, "45b983be36b73c0788dc9cbcb76cbb80fc7bb057");
+
+	their_entry.path = "duplicate";
+	their_entry.mode = GIT_FILEMODE_BLOB;
+	GIT_IDXENTRY_STAGE_SET(&their_entry, 3);
+	git_oid_fromstr(&their_entry.id, "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd");
+
+	cl_git_pass(git_index_conflict_add(index, &ancestor_entry, &our_entry, &their_entry));
+}
+
+void test_object_tree_duplicateentries__cannot_create_a_duplicate_entry_building_a_tree_from_a_index_with_conflicts(void)
+{
+	git_index *index;
+	git_oid tid;
+
+	cl_git_pass(git_repository_index(&index, _repo));
+
+	add_fake_conflicts(index); 
+
+	cl_assert_equal_i(GIT_EUNMERGED, git_index_write_tree(&tid, index));
+
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/frompath.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/frompath.c
new file mode 100755
index 0000000..86ca47e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/frompath.c
@@ -0,0 +1,68 @@
+#include "clar_libgit2.h"
+
+static git_repository *repo;
+static	git_tree *tree;
+
+void test_object_tree_frompath__initialize(void)
+{
+	git_oid id;
+	const char *tree_with_subtrees_oid = "ae90f12eea699729ed24555e40b9fd669da12a12";
+
+	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+	cl_assert(repo != NULL);
+
+	cl_git_pass(git_oid_fromstr(&id, tree_with_subtrees_oid));
+	cl_git_pass(git_tree_lookup(&tree, repo, &id));
+	cl_assert(tree != NULL);
+}
+
+void test_object_tree_frompath__cleanup(void)
+{
+	git_tree_free(tree);
+	tree = NULL;
+
+	git_repository_free(repo);
+	repo = NULL;
+}
+
+static void assert_tree_from_path(
+	git_tree *root,
+	const char *path,
+	const char *expected_entry_name)
+{
+	git_tree_entry *entry;
+
+	cl_git_pass(git_tree_entry_bypath(&entry, root, path));
+	cl_assert_equal_s(git_tree_entry_name(entry), expected_entry_name);
+	git_tree_entry_free(entry);
+}
+
+void test_object_tree_frompath__retrieve_tree_from_path_to_treeentry(void)
+{
+	git_tree_entry *e;
+
+	assert_tree_from_path(tree, "README", "README");
+	assert_tree_from_path(tree, "ab/de/fgh/1.txt", "1.txt");
+	assert_tree_from_path(tree, "ab/de/fgh", "fgh");
+	assert_tree_from_path(tree, "ab/de/fgh/", "fgh");
+	assert_tree_from_path(tree, "ab/de", "de");
+	assert_tree_from_path(tree, "ab/", "ab");
+	assert_tree_from_path(tree, "ab/de/", "de");
+
+	cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "i-do-not-exist.txt"));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "README/"));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "ab/de/fgh/i-do-not-exist.txt"));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "nope/de/fgh/1.txt"));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "ab/me-neither/fgh/2.txt"));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_tree_entry_bypath(&e, tree, "ab/me-neither/fgh/2.txt/"));
+}
+
+void test_object_tree_frompath__fail_when_processing_an_invalid_path(void)
+{
+	git_tree_entry *e;
+
+	cl_must_fail(git_tree_entry_bypath(&e, tree, "/"));
+	cl_must_fail(git_tree_entry_bypath(&e, tree, "/ab"));
+	cl_must_fail(git_tree_entry_bypath(&e, tree, "/ab/de"));
+	cl_must_fail(git_tree_entry_bypath(&e, tree, "ab//de"));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/read.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/read.c
new file mode 100755
index 0000000..59a809b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/read.c
@@ -0,0 +1,75 @@
+#include "clar_libgit2.h"
+
+#include "tree.h"
+
+static const char *tree_oid = "1810dff58d8a660512d4832e740f692884338ccd";
+
+static git_repository *g_repo;
+
+// Fixture setup and teardown
+void test_object_tree_read__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_object_tree_read__cleanup(void)
+{
+   cl_git_sandbox_cleanup();
+}
+
+
+
+void test_object_tree_read__loaded(void)
+{
+   // acces randomly the entries on a loaded tree
+	git_oid id;
+	git_tree *tree;
+
+	git_oid_fromstr(&id, tree_oid);
+
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
+
+	cl_assert(git_tree_entry_byname(tree, "README") != NULL);
+	cl_assert(git_tree_entry_byname(tree, "NOTEXISTS") == NULL);
+	cl_assert(git_tree_entry_byname(tree, "") == NULL);
+	cl_assert(git_tree_entry_byindex(tree, 0) != NULL);
+	cl_assert(git_tree_entry_byindex(tree, 2) != NULL);
+	cl_assert(git_tree_entry_byindex(tree, 3) == NULL);
+	cl_assert(git_tree_entry_byindex(tree, (unsigned int)-1) == NULL);
+
+	git_tree_free(tree);
+}
+
+void test_object_tree_read__two(void)
+{
+   // read a tree from the repository
+	git_oid id;
+	git_tree *tree;
+	const git_tree_entry *entry;
+	git_object *obj;
+
+	git_oid_fromstr(&id, tree_oid);
+
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
+
+	cl_assert(git_tree_entrycount(tree) == 3);
+
+	/* GH-86: git_object_lookup() should also check the type if the object comes from the cache */
+	cl_assert(git_object_lookup(&obj, g_repo, &id, GIT_OBJ_TREE) == 0);
+	cl_assert(obj != NULL);
+	git_object_free(obj);
+	obj = NULL;
+	cl_git_fail(git_object_lookup(&obj, g_repo, &id, GIT_OBJ_BLOB));
+	cl_assert(obj == NULL);
+
+	entry = git_tree_entry_byname(tree, "README");
+	cl_assert(entry != NULL);
+
+	cl_assert_equal_s(git_tree_entry_name(entry), "README");
+
+	cl_git_pass(git_tree_entry_to_object(&obj, g_repo, entry));
+	cl_assert(obj != NULL);
+
+	git_object_free(obj);
+	git_tree_free(tree);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/walk.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/walk.c
new file mode 100755
index 0000000..f8005e5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/walk.c
@@ -0,0 +1,177 @@
+#include "clar_libgit2.h"
+#include "tree.h"
+
+static const char *tree_oid = "1810dff58d8a660512d4832e740f692884338ccd";
+static git_repository *g_repo;
+
+void test_object_tree_walk__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_object_tree_walk__cleanup(void)
+{
+   cl_git_sandbox_cleanup();
+}
+
+static int treewalk_count_cb(
+	const char *root, const git_tree_entry *entry, void *payload)
+{
+	int *count = payload;
+
+	GIT_UNUSED(root);
+	GIT_UNUSED(entry);
+
+	(*count) += 1;
+
+	return 0;
+}
+
+void test_object_tree_walk__0(void)
+{
+	git_oid id;
+	git_tree *tree;
+	int ct;
+
+	git_oid_fromstr(&id, tree_oid);
+
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
+
+	ct = 0;
+	cl_git_pass(git_tree_walk(tree, GIT_TREEWALK_PRE, treewalk_count_cb, &ct));
+	cl_assert_equal_i(3, ct);
+
+	ct = 0;
+	cl_git_pass(git_tree_walk(tree, GIT_TREEWALK_POST, treewalk_count_cb, &ct));
+	cl_assert_equal_i(3, ct);
+
+	git_tree_free(tree);
+}
+
+
+static int treewalk_stop_cb(
+	const char *root, const git_tree_entry *entry, void *payload)
+{
+	int *count = payload;
+
+	GIT_UNUSED(root);
+	GIT_UNUSED(entry);
+
+	(*count) += 1;
+
+	return (*count == 2) ? -123 : 0;
+}
+
+static int treewalk_stop_immediately_cb(
+	const char *root, const git_tree_entry *entry, void *payload)
+{
+	GIT_UNUSED(root);
+	GIT_UNUSED(entry);
+	GIT_UNUSED(payload);
+	return -100;
+}
+
+void test_object_tree_walk__1(void)
+{
+	git_oid id;
+	git_tree *tree;
+	int ct;
+
+	git_oid_fromstr(&id, tree_oid);
+
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
+
+	ct = 0;
+	cl_assert_equal_i(
+		-123, git_tree_walk(tree, GIT_TREEWALK_PRE, treewalk_stop_cb, &ct));
+	cl_assert_equal_i(2, ct);
+
+	ct = 0;
+	cl_assert_equal_i(
+		-123, git_tree_walk(tree, GIT_TREEWALK_POST, treewalk_stop_cb, &ct));
+	cl_assert_equal_i(2, ct);
+
+	cl_assert_equal_i(
+		-100, git_tree_walk(
+			tree, GIT_TREEWALK_PRE, treewalk_stop_immediately_cb, NULL));
+
+	cl_assert_equal_i(
+		-100, git_tree_walk(
+			tree, GIT_TREEWALK_POST, treewalk_stop_immediately_cb, NULL));
+
+	git_tree_free(tree);
+}
+
+
+struct treewalk_skip_data {
+	int files;
+	int dirs;
+	const char *skip;
+	const char *stop;
+};
+
+static int treewalk_skip_de_cb(
+	const char *root, const git_tree_entry *entry, void *payload)
+{
+	struct treewalk_skip_data *data = payload;
+	const char *name = git_tree_entry_name(entry);
+
+	GIT_UNUSED(root);
+
+	if (git_tree_entry_type(entry) == GIT_OBJ_TREE)
+		data->dirs++;
+	else
+		data->files++;
+
+	if (data->skip && !strcmp(name, data->skip))
+		return 1;
+	else if (data->stop && !strcmp(name, data->stop))
+		return -1;
+	else
+		return 0;
+}
+
+void test_object_tree_walk__2(void)
+{
+	git_oid id;
+	git_tree *tree;
+	struct treewalk_skip_data data;
+
+	/* look up a deep tree */
+	git_oid_fromstr(&id, "ae90f12eea699729ed24555e40b9fd669da12a12");
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
+
+	memset(&data, 0, sizeof(data));
+	data.skip = "de";
+
+	cl_assert_equal_i(0, git_tree_walk(
+		tree, GIT_TREEWALK_PRE, treewalk_skip_de_cb, &data));
+	cl_assert_equal_i(5, data.files);
+	cl_assert_equal_i(3, data.dirs);
+
+	memset(&data, 0, sizeof(data));
+	data.stop = "3.txt";
+
+	cl_assert_equal_i(-1, git_tree_walk(
+		tree, GIT_TREEWALK_PRE, treewalk_skip_de_cb, &data));
+	cl_assert_equal_i(3, data.files);
+	cl_assert_equal_i(2, data.dirs);
+
+	memset(&data, 0, sizeof(data));
+	data.skip = "new.txt";
+
+	cl_assert_equal_i(0, git_tree_walk(
+		tree, GIT_TREEWALK_PRE, treewalk_skip_de_cb, &data));
+	cl_assert_equal_i(7, data.files);
+	cl_assert_equal_i(4, data.dirs);
+
+	memset(&data, 0, sizeof(data));
+	data.stop = "new.txt";
+
+	cl_assert_equal_i(-1, git_tree_walk(
+		tree, GIT_TREEWALK_PRE, treewalk_skip_de_cb, &data));
+	cl_assert_equal_i(7, data.files);
+	cl_assert_equal_i(4, data.dirs);
+
+	git_tree_free(tree);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/write.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/write.c
new file mode 100755
index 0000000..5433e5f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/object/tree/write.c
@@ -0,0 +1,442 @@
+#include "clar_libgit2.h"
+
+#include "tree.h"
+
+static const char *blob_oid = "fa49b077972391ad58037050f2a75f74e3671e92";
+static const char *first_tree  = "181037049a54a1eb5fab404658a3a250b44335d7";
+static const char *second_tree = "f60079018b664e4e79329a7ef9559c8d9e0378d1";
+static const char *third_tree = "eb86d8b81d6adbd5290a935d6c9976882de98488";
+
+static git_repository *g_repo;
+
+/* Fixture setup and teardown */
+void test_object_tree_write__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_object_tree_write__cleanup(void)
+{
+   cl_git_sandbox_cleanup();
+}
+
+void test_object_tree_write__from_memory(void)
+{
+	/* write a tree from a memory */
+	git_treebuilder *builder;
+	git_tree *tree;
+	git_oid id, bid, rid, id2;
+
+	git_oid_fromstr(&id, first_tree);
+	git_oid_fromstr(&id2, second_tree);
+	git_oid_fromstr(&bid, blob_oid);
+
+	/* create a second tree from first tree using `git_treebuilder_insert`
+	 * on REPOSITORY_FOLDER.
+	 */
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
+	cl_git_pass(git_treebuilder_new(&builder, g_repo, tree));
+
+	cl_git_fail(git_treebuilder_insert(NULL, builder, "",
+		&bid, GIT_FILEMODE_BLOB));
+	cl_git_fail(git_treebuilder_insert(NULL, builder, "/",
+		&bid, GIT_FILEMODE_BLOB));
+	cl_git_fail(git_treebuilder_insert(NULL, builder, ".git",
+		&bid, GIT_FILEMODE_BLOB));
+	cl_git_fail(git_treebuilder_insert(NULL, builder, "..",
+		&bid, GIT_FILEMODE_BLOB));
+	cl_git_fail(git_treebuilder_insert(NULL, builder, ".",
+		&bid, GIT_FILEMODE_BLOB));
+	cl_git_fail(git_treebuilder_insert(NULL, builder, "folder/new.txt",
+		&bid, GIT_FILEMODE_BLOB));
+
+	cl_git_pass(git_treebuilder_insert(
+		NULL, builder, "new.txt", &bid, GIT_FILEMODE_BLOB));
+
+	cl_git_pass(git_treebuilder_write(&rid, builder));
+
+	cl_assert(git_oid_cmp(&rid, &id2) == 0);
+
+	git_treebuilder_free(builder);
+	git_tree_free(tree);
+}
+
+void test_object_tree_write__subtree(void)
+{
+	/* write a hierarchical tree from a memory */
+	git_treebuilder *builder;
+	git_tree *tree;
+	git_oid id, bid, subtree_id, id2, id3;
+	git_oid id_hiearar;
+
+	git_oid_fromstr(&id, first_tree);
+	git_oid_fromstr(&id2, second_tree);
+	git_oid_fromstr(&id3, third_tree);
+	git_oid_fromstr(&bid, blob_oid);
+
+	/* create subtree */
+	cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
+	cl_git_pass(git_treebuilder_insert(
+		NULL, builder, "new.txt", &bid, GIT_FILEMODE_BLOB)); /* -V536 */
+	cl_git_pass(git_treebuilder_write(&subtree_id, builder));
+	git_treebuilder_free(builder);
+
+	/* create parent tree */
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
+	cl_git_pass(git_treebuilder_new(&builder, g_repo, tree));
+	cl_git_pass(git_treebuilder_insert(
+		NULL, builder, "new", &subtree_id, GIT_FILEMODE_TREE)); /* -V536 */
+	cl_git_pass(git_treebuilder_write(&id_hiearar, builder));
+	git_treebuilder_free(builder);
+	git_tree_free(tree);
+
+	cl_assert(git_oid_cmp(&id_hiearar, &id3) == 0);
+
+	/* check data is correct */
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &id_hiearar));
+	cl_assert(2 == git_tree_entrycount(tree));
+	git_tree_free(tree);
+}
+
+/*
+ * And the Lord said: Is this tree properly sorted?
+ */
+void test_object_tree_write__sorted_subtrees(void)
+{
+	git_treebuilder *builder;
+	git_tree *tree;
+	unsigned int i;
+	int position_c = -1, position_cake = -1, position_config = -1;
+
+	struct {
+		unsigned int attr;
+		const char *filename;
+	} entries[] = {
+		{ GIT_FILEMODE_BLOB, ".gitattributes" },
+	  	{ GIT_FILEMODE_BLOB, ".gitignore" },
+	  	{ GIT_FILEMODE_BLOB, ".htaccess" },
+	  	{ GIT_FILEMODE_BLOB, "Capfile" },
+	  	{ GIT_FILEMODE_BLOB, "Makefile"},
+	  	{ GIT_FILEMODE_BLOB, "README"},
+	  	{ GIT_FILEMODE_TREE, "app"},
+	  	{ GIT_FILEMODE_TREE, "cake"},
+	  	{ GIT_FILEMODE_TREE, "config"},
+	  	{ GIT_FILEMODE_BLOB, "c"},
+	  	{ GIT_FILEMODE_BLOB, "git_test.txt"},
+	  	{ GIT_FILEMODE_BLOB, "htaccess.htaccess"},
+	  	{ GIT_FILEMODE_BLOB, "index.php"},
+	  	{ GIT_FILEMODE_TREE, "plugins"},
+	  	{ GIT_FILEMODE_TREE, "schemas"},
+	  	{ GIT_FILEMODE_TREE, "ssl-certs"},
+	  	{ GIT_FILEMODE_TREE, "vendors"}
+	};
+
+	git_oid blank_oid, tree_oid;
+
+	memset(&blank_oid, 0x0, sizeof(blank_oid));
+
+	cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
+
+	for (i = 0; i < ARRAY_SIZE(entries); ++i) {
+		cl_git_pass(git_treebuilder_insert(NULL,
+			builder, entries[i].filename, &blank_oid, entries[i].attr));
+	}
+
+	cl_git_pass(git_treebuilder_write(&tree_oid, builder));
+
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_oid));
+	for (i = 0; i < git_tree_entrycount(tree); i++) {
+		const git_tree_entry *entry = git_tree_entry_byindex(tree, i);
+
+		if (strcmp(entry->filename, "c") == 0)
+			position_c = i;
+
+		if (strcmp(entry->filename, "cake") == 0)
+			position_cake = i;
+
+		if (strcmp(entry->filename, "config") == 0)
+			position_config = i;
+	}
+
+	git_tree_free(tree);
+
+	cl_assert(position_c != -1);
+	cl_assert(position_cake != -1);
+	cl_assert(position_config != -1);
+
+	cl_assert(position_c < position_cake);
+	cl_assert(position_cake < position_config);
+
+	git_treebuilder_free(builder);
+}
+
+static struct {
+	unsigned int attr;
+	const char *filename;
+} _entries[] = {
+	{ GIT_FILEMODE_BLOB, "aardvark" },
+	{ GIT_FILEMODE_BLOB, ".first" },
+	{ GIT_FILEMODE_BLOB, "apple" },
+	{ GIT_FILEMODE_BLOB, "last"},
+	{ GIT_FILEMODE_BLOB, "apple_after"},
+	{ GIT_FILEMODE_BLOB, "after_aardvark"},
+	{ 0, NULL },
+};
+
+void test_object_tree_write__removing_and_re_adding_in_treebuilder(void)
+{
+	git_treebuilder *builder;
+	int i, aardvark_i, apple_i, apple_after_i, apple_extra_i, last_i;
+	git_oid blank_oid, tree_oid;
+	git_tree *tree;
+
+	memset(&blank_oid, 0x0, sizeof(blank_oid));
+
+	cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
+
+	cl_assert_equal_i(0, (int)git_treebuilder_entrycount(builder));
+
+	for (i = 0; _entries[i].filename; ++i)
+		cl_git_pass(git_treebuilder_insert(NULL,
+			builder, _entries[i].filename, &blank_oid, _entries[i].attr));
+
+	cl_assert_equal_i(6, (int)git_treebuilder_entrycount(builder));
+
+	cl_git_pass(git_treebuilder_remove(builder, "apple"));
+	cl_assert_equal_i(5, (int)git_treebuilder_entrycount(builder));
+
+	cl_git_pass(git_treebuilder_remove(builder, "apple_after"));
+	cl_assert_equal_i(4, (int)git_treebuilder_entrycount(builder));
+
+	cl_git_pass(git_treebuilder_insert(
+		NULL, builder, "before_last", &blank_oid, GIT_FILEMODE_BLOB));
+	cl_assert_equal_i(5, (int)git_treebuilder_entrycount(builder));
+
+	/* reinsert apple_after */
+	cl_git_pass(git_treebuilder_insert(
+		NULL, builder, "apple_after", &blank_oid, GIT_FILEMODE_BLOB));
+	cl_assert_equal_i(6, (int)git_treebuilder_entrycount(builder));
+
+	cl_git_pass(git_treebuilder_remove(builder, "last"));
+	cl_assert_equal_i(5, (int)git_treebuilder_entrycount(builder));
+
+	/* reinsert last */
+	cl_git_pass(git_treebuilder_insert(
+		NULL, builder, "last", &blank_oid, GIT_FILEMODE_BLOB));
+	cl_assert_equal_i(6, (int)git_treebuilder_entrycount(builder));
+
+	cl_git_pass(git_treebuilder_insert(
+		NULL, builder, "apple_extra", &blank_oid, GIT_FILEMODE_BLOB));
+	cl_assert_equal_i(7, (int)git_treebuilder_entrycount(builder));
+
+	cl_git_pass(git_treebuilder_write(&tree_oid, builder));
+
+	git_treebuilder_free(builder);
+
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_oid));
+
+	cl_assert_equal_i(7, (int)git_tree_entrycount(tree));
+
+	cl_assert(git_tree_entry_byname(tree, ".first") != NULL);
+	cl_assert(git_tree_entry_byname(tree, "apple") == NULL);
+	cl_assert(git_tree_entry_byname(tree, "apple_after") != NULL);
+	cl_assert(git_tree_entry_byname(tree, "apple_extra") != NULL);
+	cl_assert(git_tree_entry_byname(tree, "last") != NULL);
+
+	aardvark_i = apple_i = apple_after_i = apple_extra_i = last_i = -1;
+
+	for (i = 0; i < 7; ++i) {
+		const git_tree_entry *entry = git_tree_entry_byindex(tree, i);
+
+		if (!strcmp(entry->filename, "aardvark"))
+			aardvark_i = i;
+		else if (!strcmp(entry->filename, "apple"))
+			apple_i = i;
+		else if (!strcmp(entry->filename, "apple_after"))
+			apple_after_i = i;
+		else if (!strcmp(entry->filename, "apple_extra"))
+			apple_extra_i = i;
+		else if (!strcmp(entry->filename, "last"))
+			last_i = i;
+	}
+
+	cl_assert_equal_i(-1, apple_i);
+	cl_assert_equal_i(6, last_i);
+	cl_assert(aardvark_i < apple_after_i);
+	cl_assert(apple_after_i < apple_extra_i);
+
+	git_tree_free(tree);
+}
+
+static int treebuilder_filter_prefixed(
+	const git_tree_entry *entry, void *payload)
+{
+	return !git__prefixcmp(git_tree_entry_name(entry), payload);
+}
+
+void test_object_tree_write__filtering(void)
+{
+	git_treebuilder *builder;
+	int i;
+	git_oid blank_oid, tree_oid;
+	git_tree *tree;
+
+	memset(&blank_oid, 0x0, sizeof(blank_oid));
+
+	cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
+
+	for (i = 0; _entries[i].filename; ++i)
+		cl_git_pass(git_treebuilder_insert(NULL,
+			builder, _entries[i].filename, &blank_oid, _entries[i].attr));
+
+	cl_assert_equal_i(6, (int)git_treebuilder_entrycount(builder));
+
+	cl_assert(git_treebuilder_get(builder, "apple") != NULL);
+	cl_assert(git_treebuilder_get(builder, "aardvark") != NULL);
+	cl_assert(git_treebuilder_get(builder, "last") != NULL);
+
+	git_treebuilder_filter(builder, treebuilder_filter_prefixed, "apple");
+
+	cl_assert_equal_i(4, (int)git_treebuilder_entrycount(builder));
+
+	cl_assert(git_treebuilder_get(builder, "apple") == NULL);
+	cl_assert(git_treebuilder_get(builder, "aardvark") != NULL);
+	cl_assert(git_treebuilder_get(builder, "last") != NULL);
+
+	git_treebuilder_filter(builder, treebuilder_filter_prefixed, "a");
+
+	cl_assert_equal_i(2, (int)git_treebuilder_entrycount(builder));
+
+	cl_assert(git_treebuilder_get(builder, "aardvark") == NULL);
+	cl_assert(git_treebuilder_get(builder, "last") != NULL);
+
+	cl_git_pass(git_treebuilder_write(&tree_oid, builder));
+
+	git_treebuilder_free(builder);
+
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_oid));
+
+	cl_assert_equal_i(2, (int)git_tree_entrycount(tree));
+
+	git_tree_free(tree);
+}
+
+void test_object_tree_write__cruel_paths(void)
+{
+	static const char *the_paths[] = {
+		"C:\\",
+		" : * ? \" \n < > |",
+		"a\\b",
+		"\\\\b\a",
+		":\\",
+		"COM1",
+		"foo.aux",
+		REP1024("1234"), /* 4096 char string */
+		REP1024("12345678"), /* 8192 char string */
+		"\xC5\xAA\x6E\xC4\xAD\x63\xC5\x8D\x64\x65\xCC\xBD", /* Ūnĭcōde̽ */
+		NULL
+	};
+	git_treebuilder *builder;
+	git_tree *tree;
+	git_oid id, bid, subid;
+	const char **scan;
+	int count = 0, i, j;
+	git_tree_entry *te;
+
+	git_oid_fromstr(&bid, blob_oid);
+
+	/* create tree */
+	cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
+	for (scan = the_paths; *scan; ++scan) {
+		cl_git_pass(git_treebuilder_insert(
+			NULL, builder, *scan, &bid, GIT_FILEMODE_BLOB));
+		count++;
+	}
+	cl_git_pass(git_treebuilder_write(&id, builder));
+	git_treebuilder_free(builder);
+
+	/* check data is correct */
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
+
+	cl_assert_equal_i(count, git_tree_entrycount(tree));
+
+	for (scan = the_paths; *scan; ++scan) {
+		const git_tree_entry *cte = git_tree_entry_byname(tree, *scan);
+		cl_assert(cte != NULL);
+		cl_assert_equal_s(*scan, git_tree_entry_name(cte));
+	}
+	for (scan = the_paths; *scan; ++scan) {
+		cl_git_pass(git_tree_entry_bypath(&te, tree, *scan));
+		cl_assert_equal_s(*scan, git_tree_entry_name(te));
+		git_tree_entry_free(te);
+	}
+
+	git_tree_free(tree);
+
+	/* let's try longer paths */
+	cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
+	for (scan = the_paths; *scan; ++scan) {
+		cl_git_pass(git_treebuilder_insert(
+			NULL, builder, *scan, &id, GIT_FILEMODE_TREE));
+	}
+	cl_git_pass(git_treebuilder_write(&subid, builder));
+	git_treebuilder_free(builder);
+
+	/* check data is correct */
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &subid));
+
+	cl_assert_equal_i(count, git_tree_entrycount(tree));
+
+	for (i = 0; i < count; ++i) {
+		for (j = 0; j < count; ++j) {
+			git_buf b = GIT_BUF_INIT;
+			cl_git_pass(git_buf_joinpath(&b, the_paths[i], the_paths[j]));
+			cl_git_pass(git_tree_entry_bypath(&te, tree, b.ptr));
+			cl_assert_equal_s(the_paths[j], git_tree_entry_name(te));
+			git_tree_entry_free(te);
+			git_buf_free(&b);
+		}
+	}
+
+	git_tree_free(tree);
+}
+
+void test_object_tree_write__protect_filesystems(void)
+{
+	git_treebuilder *builder;
+	git_oid bid;
+
+	/* Ensure that (by default) we can write objects with funny names on
+	 * platforms that are not affected.
+	 */
+	cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
+
+#ifndef GIT_WIN32
+	cl_git_pass(git_treebuilder_insert(NULL, builder, ".git.", &bid, GIT_FILEMODE_BLOB));
+	cl_git_pass(git_treebuilder_insert(NULL, builder, "git~1", &bid, GIT_FILEMODE_BLOB));
+#endif
+
+#ifndef __APPLE__
+	cl_git_pass(git_treebuilder_insert(NULL, builder, ".git\xef\xbb\xbf", &bid, GIT_FILEMODE_BLOB));
+	cl_git_pass(git_treebuilder_insert(NULL, builder, ".git\xe2\x80\xad", &bid, GIT_FILEMODE_BLOB));
+#endif
+
+	git_treebuilder_free(builder);
+
+	/* Now turn on core.protectHFS and core.protectNTFS and validate that these
+	 * paths are rejected.
+	 */
+
+	cl_repo_set_bool(g_repo, "core.protectHFS", true);
+	cl_repo_set_bool(g_repo, "core.protectNTFS", true);
+
+	cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
+
+	cl_git_fail(git_treebuilder_insert(NULL, builder, ".git.", &bid, GIT_FILEMODE_BLOB));
+	cl_git_fail(git_treebuilder_insert(NULL, builder, "git~1", &bid, GIT_FILEMODE_BLOB));
+
+	cl_git_fail(git_treebuilder_insert(NULL, builder, ".git\xef\xbb\xbf", &bid, GIT_FILEMODE_BLOB));
+	cl_git_fail(git_treebuilder_insert(NULL, builder, ".git\xe2\x80\xad", &bid, GIT_FILEMODE_BLOB));
+
+	git_treebuilder_free(builder);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/alternates.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/alternates.c
new file mode 100755
index 0000000..c75f6fe
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/alternates.c
@@ -0,0 +1,80 @@
+#include "clar_libgit2.h"
+#include "odb.h"
+#include "filebuf.h"
+
+static git_buf destpath, filepath;
+static const char *paths[] = {
+	"A.git", "B.git", "C.git", "D.git", "E.git", "F.git", "G.git"
+};
+static git_filebuf file;
+static git_repository *repo;
+
+void test_odb_alternates__cleanup(void)
+{
+	size_t i;
+
+	git_buf_free(&destpath);
+	git_buf_free(&filepath);
+
+	for (i = 0; i < ARRAY_SIZE(paths); i++)
+		cl_fixture_cleanup(paths[i]);
+}
+
+static void init_linked_repo(const char *path, const char *alternate)
+{
+	git_buf_clear(&destpath);
+	git_buf_clear(&filepath);
+
+	cl_git_pass(git_repository_init(&repo, path, 1));
+	cl_git_pass(git_path_prettify(&destpath, alternate, NULL));
+	cl_git_pass(git_buf_joinpath(&destpath, destpath.ptr, "objects"));
+	cl_git_pass(git_buf_joinpath(&filepath, git_repository_path(repo), "objects/info"));
+	cl_git_pass(git_futils_mkdir(filepath.ptr, NULL, 0755, GIT_MKDIR_PATH));
+	cl_git_pass(git_buf_joinpath(&filepath, filepath.ptr , "alternates"));
+
+	cl_git_pass(git_filebuf_open(&file, git_buf_cstr(&filepath), 0, 0666));
+	git_filebuf_printf(&file, "%s\n", git_buf_cstr(&destpath));
+	cl_git_pass(git_filebuf_commit(&file));
+
+	git_repository_free(repo);
+}
+
+void test_odb_alternates__chained(void)
+{
+	git_commit *commit;
+	git_oid oid;
+
+	/* Set the alternate A -> testrepo.git */
+	init_linked_repo(paths[0], cl_fixture("testrepo.git"));
+
+	/* Set the alternate B -> A */
+	init_linked_repo(paths[1], paths[0]);
+
+	/* Now load B and see if we can find an object from testrepo.git */
+	cl_git_pass(git_repository_open(&repo, paths[1]));
+	git_oid_fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	cl_git_pass(git_commit_lookup(&commit, repo, &oid));
+	git_commit_free(commit);
+	git_repository_free(repo);
+}
+
+void test_odb_alternates__long_chain(void)
+{
+	git_commit *commit;
+	git_oid oid;
+	size_t i;
+
+	/* Set the alternate A -> testrepo.git */
+	init_linked_repo(paths[0], cl_fixture("testrepo.git"));
+
+	/* Set up the five-element chain */
+	for (i = 1; i < ARRAY_SIZE(paths); i++) {
+		init_linked_repo(paths[i], paths[i-1]);
+	}
+
+	/* Now load the last one and see if we can find an object from testrepo.git */
+	cl_git_pass(git_repository_open(&repo, paths[ARRAY_SIZE(paths)-1]));
+	git_oid_fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	cl_git_fail(git_commit_lookup(&commit, repo, &oid));
+	git_repository_free(repo);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/backend/nobackend.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/backend/nobackend.c
new file mode 100755
index 0000000..783641e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/backend/nobackend.c
@@ -0,0 +1,46 @@
+#include "clar_libgit2.h"
+#include "repository.h"
+#include "git2/sys/repository.h"
+
+static git_repository *_repo;
+
+void test_odb_backend_nobackend__initialize(void)
+{
+	git_config *config;
+	git_odb *odb;
+	git_refdb *refdb;
+
+	cl_git_pass(git_repository_new(&_repo));
+	cl_git_pass(git_config_new(&config));
+	cl_git_pass(git_odb_new(&odb));
+	cl_git_pass(git_refdb_new(&refdb, _repo));
+
+	git_repository_set_config(_repo, config);
+	git_repository_set_odb(_repo, odb);
+	git_repository_set_refdb(_repo, refdb);
+
+	/* The set increases the refcount and we don't want them anymore */
+	git_config_free(config);
+	git_odb_free(odb);
+	git_refdb_free(refdb);
+}
+
+void test_odb_backend_nobackend__cleanup(void)
+{
+	git_repository_free(_repo);
+}
+
+void test_odb_backend_nobackend__write_fails_gracefully(void)
+{
+	git_oid id;
+	git_odb *odb;
+	const git_error *err;
+
+	git_repository_odb(&odb, _repo);
+	cl_git_fail(git_odb_write(&id, odb, "Hello world!\n", 13, GIT_OBJ_BLOB));
+
+	err = giterr_last();
+	cl_assert_equal_s(err->message, "Cannot write object - unsupported in the loaded odb backends");
+
+	git_odb_free(odb);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/backend/nonrefreshing.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/backend/nonrefreshing.c
new file mode 100755
index 0000000..b435294
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/backend/nonrefreshing.c
@@ -0,0 +1,274 @@
+#include "clar_libgit2.h"
+#include "git2/sys/odb_backend.h"
+#include "repository.h"
+
+typedef struct fake_backend {
+	git_odb_backend parent;
+
+	git_error_code error_code;
+
+	int exists_calls;
+	int read_calls;
+	int read_header_calls;
+	int read_prefix_calls;
+} fake_backend;
+
+static git_repository *_repo;
+static fake_backend *_fake;
+static git_oid _oid;
+
+static int fake_backend__exists(git_odb_backend *backend, const git_oid *oid)
+{
+	fake_backend *fake;
+
+	GIT_UNUSED(oid);
+
+	fake = (fake_backend *)backend;
+
+	fake->exists_calls++;
+
+	return (fake->error_code == GIT_OK);
+}
+
+static int fake_backend__read(
+	void **buffer_p, size_t *len_p, git_otype *type_p,
+	git_odb_backend *backend, const git_oid *oid)
+{
+	fake_backend *fake;
+
+	GIT_UNUSED(buffer_p);
+	GIT_UNUSED(len_p);
+	GIT_UNUSED(type_p);
+	GIT_UNUSED(oid);
+
+	fake = (fake_backend *)backend;
+
+	fake->read_calls++;
+
+	*len_p = 0;
+	*buffer_p = NULL;
+	*type_p = GIT_OBJ_BLOB;
+
+	return fake->error_code;
+}
+
+static int fake_backend__read_header(
+	size_t *len_p, git_otype *type_p,
+	git_odb_backend *backend, const git_oid *oid)
+{
+	fake_backend *fake;
+
+	GIT_UNUSED(len_p);
+	GIT_UNUSED(type_p);
+	GIT_UNUSED(oid);
+
+	fake = (fake_backend *)backend;
+
+	fake->read_header_calls++;
+
+	*len_p = 0;
+	*type_p = GIT_OBJ_BLOB;
+
+	return fake->error_code;
+}
+
+static int fake_backend__read_prefix(
+	git_oid *out_oid, void **buffer_p, size_t *len_p, git_otype *type_p,
+	git_odb_backend *backend, const git_oid *short_oid,	size_t len)
+{
+	fake_backend *fake;
+
+	GIT_UNUSED(out_oid);
+	GIT_UNUSED(buffer_p);
+	GIT_UNUSED(len_p);
+	GIT_UNUSED(type_p);
+	GIT_UNUSED(short_oid);
+	GIT_UNUSED(len);
+
+	fake = (fake_backend *)backend;
+
+	fake->read_prefix_calls++;
+
+	*len_p = 0;
+	*buffer_p = NULL;
+	*type_p = GIT_OBJ_BLOB;
+
+	return fake->error_code;
+}
+
+static void fake_backend__free(git_odb_backend *_backend)
+{
+	fake_backend *backend;
+
+	backend = (fake_backend *)_backend;
+
+	git__free(backend);
+}
+
+static int build_fake_backend(
+	git_odb_backend **out,
+	git_error_code error_code)
+{
+	fake_backend *backend;
+
+	backend = git__calloc(1, sizeof(fake_backend));
+	GITERR_CHECK_ALLOC(backend);
+
+	backend->parent.version = GIT_ODB_BACKEND_VERSION;
+
+	backend->parent.refresh = NULL;
+	backend->error_code = error_code;
+
+	backend->parent.read = fake_backend__read;
+	backend->parent.read_prefix = fake_backend__read_prefix;
+	backend->parent.read_header = fake_backend__read_header;
+	backend->parent.exists = fake_backend__exists;
+	backend->parent.free = &fake_backend__free;
+
+	*out = (git_odb_backend *)backend;
+
+	return 0;
+}
+
+static void setup_repository_and_backend(git_error_code error_code)
+{
+	git_odb *odb = NULL;
+	git_odb_backend *backend = NULL;
+
+	_repo = cl_git_sandbox_init("testrepo.git");
+
+	cl_git_pass(build_fake_backend(&backend, error_code));
+
+	cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
+	cl_git_pass(git_odb_add_backend(odb, backend, 10));
+
+	_fake = (fake_backend *)backend;
+
+	cl_git_pass(git_oid_fromstr(&_oid, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
+}
+
+void test_odb_backend_nonrefreshing__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_odb_backend_nonrefreshing__exists_is_invoked_once_on_failure(void)
+{
+	git_odb *odb;
+
+	setup_repository_and_backend(GIT_ENOTFOUND);
+
+	cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
+	cl_assert_equal_b(false, git_odb_exists(odb, &_oid));
+
+	cl_assert_equal_i(1, _fake->exists_calls);
+}
+
+void test_odb_backend_nonrefreshing__read_is_invoked_once_on_failure(void)
+{
+	git_object *obj;
+
+	setup_repository_and_backend(GIT_ENOTFOUND);
+
+	cl_git_fail_with(
+		git_object_lookup(&obj, _repo, &_oid, GIT_OBJ_ANY),
+		GIT_ENOTFOUND);
+
+	cl_assert_equal_i(1, _fake->read_calls);
+}
+
+void test_odb_backend_nonrefreshing__readprefix_is_invoked_once_on_failure(void)
+{
+	git_object *obj;
+
+	setup_repository_and_backend(GIT_ENOTFOUND);
+
+	cl_git_fail_with(
+		git_object_lookup_prefix(&obj, _repo, &_oid, 7, GIT_OBJ_ANY),
+		GIT_ENOTFOUND);
+
+	cl_assert_equal_i(1, _fake->read_prefix_calls);
+}
+
+void test_odb_backend_nonrefreshing__readheader_is_invoked_once_on_failure(void)
+{
+	git_odb *odb;
+	size_t len;
+	git_otype type;
+
+	setup_repository_and_backend(GIT_ENOTFOUND);
+
+	cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
+
+	cl_git_fail_with(
+		git_odb_read_header(&len, &type, odb, &_oid),
+		GIT_ENOTFOUND);
+
+	cl_assert_equal_i(1, _fake->read_header_calls);
+}
+
+void test_odb_backend_nonrefreshing__exists_is_invoked_once_on_success(void)
+{
+	git_odb *odb;
+
+	setup_repository_and_backend(GIT_OK);
+
+	cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
+	cl_assert_equal_b(true, git_odb_exists(odb, &_oid));
+
+	cl_assert_equal_i(1, _fake->exists_calls);
+}
+
+void test_odb_backend_nonrefreshing__read_is_invoked_once_on_success(void)
+{
+	git_object *obj;
+
+	setup_repository_and_backend(GIT_OK);
+
+	cl_git_pass(git_object_lookup(&obj, _repo, &_oid, GIT_OBJ_ANY));
+
+	cl_assert_equal_i(1, _fake->read_calls);
+
+	git_object_free(obj);
+}
+
+void test_odb_backend_nonrefreshing__readprefix_is_invoked_once_on_success(void)
+{
+	git_object *obj;
+
+	setup_repository_and_backend(GIT_OK);
+
+	cl_git_pass(git_object_lookup_prefix(&obj, _repo, &_oid, 7, GIT_OBJ_ANY));
+
+	cl_assert_equal_i(1, _fake->read_prefix_calls);
+
+	git_object_free(obj);
+}
+
+void test_odb_backend_nonrefreshing__readheader_is_invoked_once_on_success(void)
+{
+	git_odb *odb;
+	size_t len;
+	git_otype type;
+
+	setup_repository_and_backend(GIT_OK);
+
+	cl_git_pass(git_repository_odb__weakptr(&odb, _repo));
+
+	cl_git_pass(git_odb_read_header(&len, &type, odb, &_oid));
+
+	cl_assert_equal_i(1, _fake->read_header_calls);
+}
+
+void test_odb_backend_nonrefreshing__read_is_invoked_once_when_revparsing_a_full_oid(void)
+{
+	git_object *obj;
+
+	setup_repository_and_backend(GIT_ENOTFOUND);
+
+	cl_git_fail_with(
+		git_revparse_single(&obj, _repo, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"),
+		GIT_ENOTFOUND);
+
+	cl_assert_equal_i(1, _fake->read_calls);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/emptyobjects.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/emptyobjects.c
new file mode 100755
index 0000000..783d051
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/emptyobjects.c
@@ -0,0 +1,57 @@
+#include "clar_libgit2.h"
+#include "odb.h"
+#include "filebuf.h"
+
+git_repository *g_repo;
+
+void test_odb_emptyobjects__initialize(void)
+{
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
+}
+void test_odb_emptyobjects__cleanup(void)
+{
+	git_repository_free(g_repo);
+}
+
+void test_odb_emptyobjects__read(void)
+{
+	git_oid id;
+	git_blob *blob;
+
+	cl_git_pass(git_oid_fromstr(&id, "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"));
+	cl_git_pass(git_blob_lookup(&blob, g_repo, &id));
+	cl_assert_equal_i(GIT_OBJ_BLOB, git_object_type((git_object *) blob));
+	cl_assert(git_blob_rawcontent(blob));
+	cl_assert_equal_s("", git_blob_rawcontent(blob));
+	cl_assert_equal_i(0, git_blob_rawsize(blob));
+	git_blob_free(blob);
+}
+
+void test_odb_emptyobjects__read_tree(void)
+{
+	git_oid id;
+	git_tree *tree;
+
+	cl_git_pass(git_oid_fromstr(&id, "4b825dc642cb6eb9a060e54bf8d69288fbee4904"));
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
+	cl_assert_equal_i(GIT_OBJ_TREE, git_object_type((git_object *) tree));
+	cl_assert_equal_i(0, git_tree_entrycount(tree));
+	cl_assert_equal_p(NULL, git_tree_entry_byname(tree, "foo"));
+	git_tree_free(tree);
+}
+
+void test_odb_emptyobjects__read_tree_odb(void)
+{
+	git_oid id;
+	git_odb *odb;
+	git_odb_object *tree_odb;
+
+	cl_git_pass(git_oid_fromstr(&id, "4b825dc642cb6eb9a060e54bf8d69288fbee4904"));
+	cl_git_pass(git_repository_odb(&odb, g_repo));
+	cl_git_pass(git_odb_read(&tree_odb, odb, &id));
+	cl_assert(git_odb_object_data(tree_odb));
+	cl_assert_equal_s("", git_odb_object_data(tree_odb));
+	cl_assert_equal_i(0, git_odb_object_size(tree_odb));
+	git_odb_object_free(tree_odb);
+	git_odb_free(odb);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/foreach.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/foreach.c
new file mode 100755
index 0000000..12b81b4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/foreach.c
@@ -0,0 +1,126 @@
+#include "clar_libgit2.h"
+#include "odb.h"
+#include "git2/odb_backend.h"
+#include "pack.h"
+#include "buffer.h"
+
+static git_odb *_odb;
+static git_repository *_repo;
+
+void test_odb_foreach__cleanup(void)
+{
+	git_odb_free(_odb);
+	git_repository_free(_repo);
+
+	_odb = NULL;
+	_repo = NULL;
+}
+
+static int foreach_cb(const git_oid *oid, void *data)
+{
+	int *nobj = data;
+	(*nobj)++;
+
+	GIT_UNUSED(oid);
+
+	return 0;
+}
+
+/*
+ * $ git --git-dir tests/resources/testrepo.git count-objects --verbose
+ * count: 47
+ * size: 4
+ * in-pack: 1640
+ * packs: 3
+ * size-pack: 425
+ * prune-packable: 0
+ * garbage: 0
+ */
+void test_odb_foreach__foreach(void)
+{
+	int nobj = 0;
+
+	cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git")));
+	git_repository_odb(&_odb, _repo);
+
+	cl_git_pass(git_odb_foreach(_odb, foreach_cb, &nobj));
+	cl_assert_equal_i(47 + 1640, nobj); /* count + in-pack */
+}
+
+void test_odb_foreach__one_pack(void)
+{
+	git_odb_backend *backend = NULL;
+	int nobj = 0;
+
+	cl_git_pass(git_odb_new(&_odb));
+	cl_git_pass(git_odb_backend_one_pack(&backend, cl_fixture("testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx")));
+	cl_git_pass(git_odb_add_backend(_odb, backend, 1));
+	_repo = NULL;
+
+	cl_git_pass(git_odb_foreach(_odb, foreach_cb, &nobj));
+	cl_assert(nobj == 1628);
+}
+
+static int foreach_stop_cb(const git_oid *oid, void *data)
+{
+	int *nobj = data;
+	(*nobj)++;
+
+	GIT_UNUSED(oid);
+
+	return (*nobj == 1000) ? -321 : 0;
+}
+
+static int foreach_stop_first_cb(const git_oid *oid, void *data)
+{
+	int *nobj = data;
+	(*nobj)++;
+
+	GIT_UNUSED(oid);
+
+	return -123;
+}
+
+void test_odb_foreach__interrupt_foreach(void)
+{
+	int nobj = 0;
+	git_oid id;
+
+	cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git")));
+	git_repository_odb(&_odb, _repo);
+
+	cl_assert_equal_i(-321, git_odb_foreach(_odb, foreach_stop_cb, &nobj));
+	cl_assert(nobj == 1000);
+
+	git_odb_free(_odb);
+	git_repository_free(_repo);
+
+	cl_git_pass(git_repository_init(&_repo, "onlyloose.git", true));
+	git_repository_odb(&_odb, _repo);
+
+	cl_git_pass(git_odb_write(&id, _odb, "", 0, GIT_OBJ_BLOB));
+	cl_assert_equal_i(-123, git_odb_foreach(_odb, foreach_stop_first_cb, &nobj));
+}
+
+void test_odb_foreach__files_in_objects_dir(void)
+{
+	git_repository *repo;
+	git_odb *odb;
+	git_buf buf = GIT_BUF_INIT;
+	int nobj = 0;
+
+	cl_fixture_sandbox("testrepo.git");
+	cl_git_pass(git_repository_open(&repo, "testrepo.git"));
+
+	cl_git_pass(git_buf_printf(&buf, "%s/objects/somefile", git_repository_path(repo)));
+	cl_git_mkfile(buf.ptr, "");
+	git_buf_free(&buf);
+
+	cl_git_pass(git_repository_odb(&odb, repo));
+	cl_git_pass(git_odb_foreach(odb, foreach_cb, &nobj));
+	cl_assert_equal_i(47 + 1640, nobj); /* count + in-pack */
+
+	git_odb_free(odb);
+	git_repository_free(repo);
+	cl_fixture_cleanup("testrepo.git");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/loose.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/loose.c
new file mode 100755
index 0000000..c91927c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/loose.c
@@ -0,0 +1,152 @@
+#include "clar_libgit2.h"
+#include "odb.h"
+#include "git2/odb_backend.h"
+#include "posix.h"
+#include "loose_data.h"
+
+#ifdef __ANDROID_API__
+# define S_IREAD        S_IRUSR
+# define S_IWRITE       S_IWUSR
+#endif
+
+static void write_object_files(object_data *d)
+{
+	int fd;
+
+	if (p_mkdir(d->dir, GIT_OBJECT_DIR_MODE) < 0)
+		cl_assert(errno == EEXIST);
+
+	cl_assert((fd = p_creat(d->file, S_IREAD | S_IWRITE)) >= 0);
+	cl_must_pass(p_write(fd, d->bytes, d->blen));
+
+	p_close(fd);
+}
+
+static void cmp_objects(git_rawobj *o, object_data *d)
+{
+	cl_assert(o->type == git_object_string2type(d->type));
+	cl_assert(o->len == d->dlen);
+
+	if (o->len > 0)
+		cl_assert(memcmp(o->data, d->data, o->len) == 0);
+}
+
+static void test_read_object(object_data *data)
+{
+    git_oid id;
+    git_odb_object *obj;
+	git_odb *odb;
+	git_rawobj tmp;
+
+    write_object_files(data);
+
+    cl_git_pass(git_odb_open(&odb, "test-objects"));
+    cl_git_pass(git_oid_fromstr(&id, data->id));
+    cl_git_pass(git_odb_read(&obj, odb, &id));
+
+	tmp.data = obj->buffer;
+	tmp.len = obj->cached.size;
+	tmp.type = obj->cached.type;
+
+    cmp_objects(&tmp, data);
+
+    git_odb_object_free(obj);
+	git_odb_free(odb);
+}
+
+void test_odb_loose__initialize(void)
+{
+	cl_must_pass(p_mkdir("test-objects", GIT_OBJECT_DIR_MODE));
+}
+
+void test_odb_loose__cleanup(void)
+{
+	cl_fixture_cleanup("test-objects");
+}
+
+void test_odb_loose__exists(void)
+{
+	git_oid id, id2;
+	git_odb *odb;
+
+	write_object_files(&one);
+	cl_git_pass(git_odb_open(&odb, "test-objects"));
+
+	cl_git_pass(git_oid_fromstr(&id, one.id));
+	cl_assert(git_odb_exists(odb, &id));
+
+	cl_git_pass(git_oid_fromstrp(&id, "8b137891"));
+	cl_git_pass(git_odb_exists_prefix(&id2, odb, &id, 8));
+	cl_assert_equal_i(0, git_oid_streq(&id2, one.id));
+
+	/* Test for a missing object */
+	cl_git_pass(git_oid_fromstr(&id, "8b137891791fe96927ad78e64b0aad7bded08baa"));
+	cl_assert(!git_odb_exists(odb, &id));
+
+	cl_git_pass(git_oid_fromstrp(&id, "8b13789a"));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_odb_exists_prefix(&id2, odb, &id, 8));
+
+	git_odb_free(odb);
+}
+
+void test_odb_loose__simple_reads(void)
+{
+	test_read_object(&commit);
+	test_read_object(&tree);
+	test_read_object(&tag);
+	test_read_object(&zero);
+	test_read_object(&one);
+	test_read_object(&two);
+	test_read_object(&some);
+}
+
+void test_write_object_permission(
+	mode_t dir_mode, mode_t file_mode,
+	mode_t expected_dir_mode, mode_t expected_file_mode)
+{
+	git_odb *odb;
+	git_odb_backend *backend;
+	git_oid oid;
+	struct stat statbuf;
+	mode_t mask, os_mask;
+
+	/* Windows does not return group/user bits from stat,
+	* files are never executable.
+	*/
+#ifdef GIT_WIN32
+	os_mask = 0600;
+#else
+	os_mask = 0777;
+#endif
+
+	mask = p_umask(0);
+	p_umask(mask);
+
+	cl_git_pass(git_odb_new(&odb));
+	cl_git_pass(git_odb_backend_loose(&backend, "test-objects", -1, 0, dir_mode, file_mode));
+	cl_git_pass(git_odb_add_backend(odb, backend, 1));
+	cl_git_pass(git_odb_write(&oid, odb, "Test data\n", 10, GIT_OBJ_BLOB));
+
+	cl_git_pass(p_stat("test-objects/67", &statbuf));
+	cl_assert_equal_i(statbuf.st_mode & os_mask, (expected_dir_mode & ~mask) & os_mask);
+
+	cl_git_pass(p_stat("test-objects/67/b808feb36201507a77f85e6d898f0a2836e4a5", &statbuf));
+	cl_assert_equal_i(statbuf.st_mode & os_mask, (expected_file_mode & ~mask) & os_mask);
+
+	git_odb_free(odb);
+}
+
+void test_odb_loose__permissions_standard(void)
+{
+	test_write_object_permission(0, 0, GIT_OBJECT_DIR_MODE, GIT_OBJECT_FILE_MODE);
+}
+
+void test_odb_loose_permissions_readonly(void)
+{
+	test_write_object_permission(0777, 0444, 0777, 0444);
+}
+
+void test_odb_loose__permissions_readwrite(void)
+{
+	test_write_object_permission(0777, 0666, 0777, 0666);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/loose_data.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/loose_data.h
new file mode 100755
index 0000000..c10c9bc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/loose_data.h
@@ -0,0 +1,522 @@
+typedef struct object_data {
+    unsigned char *bytes;  /* (compressed) bytes stored in object store */
+    size_t        blen;    /* length of data in object store            */
+    char          *id;     /* object id (sha1)                          */
+    char          *type;   /* object type                               */
+    char          *dir;    /* object store (fan-out) directory name     */
+    char          *file;   /* object store filename                     */
+    unsigned char *data;   /* (uncompressed) object data                */
+    size_t        dlen;    /* length of (uncompressed) object data      */
+} object_data;
+
+/* one == 8b137891791fe96927ad78e64b0aad7bded08bdc */
+static unsigned char one_bytes[] = {
+    0x31, 0x78, 0x9c, 0xe3, 0x02, 0x00, 0x00, 0x0b,
+    0x00, 0x0b,
+};
+
+static unsigned char one_data[] = {
+    0x0a,
+};
+
+static object_data one = {
+    one_bytes,
+    sizeof(one_bytes),
+    "8b137891791fe96927ad78e64b0aad7bded08bdc",
+    "blob",
+    "test-objects/8b",
+    "test-objects/8b/137891791fe96927ad78e64b0aad7bded08bdc",
+    one_data,
+    sizeof(one_data),
+};
+
+
+/* commit == 3d7f8a6af076c8c3f20071a8935cdbe8228594d1 */
+static unsigned char commit_bytes[] = {
+    0x78, 0x01, 0x85, 0x50, 0xc1, 0x6a, 0xc3, 0x30,
+    0x0c, 0xdd, 0xd9, 0x5f, 0xa1, 0xfb, 0x96, 0x12,
+    0xbb, 0x29, 0x71, 0x46, 0x19, 0x2b, 0x3d, 0x97,
+    0x1d, 0xd6, 0x7d, 0x80, 0x1d, 0xcb, 0x89, 0x21,
+    0xb6, 0x82, 0xed, 0x40, 0xf3, 0xf7, 0xf3, 0x48,
+    0x29, 0x3b, 0x6d, 0xd2, 0xe5, 0xbd, 0x27, 0xbd,
+    0x27, 0x50, 0x4f, 0xde, 0xbb, 0x0c, 0xfb, 0x43,
+    0xf3, 0x94, 0x23, 0x22, 0x18, 0x6b, 0x85, 0x51,
+    0x5d, 0xad, 0xc5, 0xa1, 0x41, 0xae, 0x51, 0x4b,
+    0xd9, 0x19, 0x6e, 0x4b, 0x0b, 0x29, 0x35, 0x72,
+    0x59, 0xef, 0x5b, 0x29, 0x8c, 0x65, 0x6a, 0xc9,
+    0x23, 0x45, 0x38, 0xc1, 0x17, 0x5c, 0x7f, 0xc0,
+    0x71, 0x13, 0xde, 0xf1, 0xa6, 0xfc, 0x3c, 0xe1,
+    0xae, 0x27, 0xff, 0x06, 0x5c, 0x88, 0x56, 0xf2,
+    0x46, 0x74, 0x2d, 0x3c, 0xd7, 0xa5, 0x58, 0x51,
+    0xcb, 0xb9, 0x8c, 0x11, 0xce, 0xf0, 0x01, 0x97,
+    0x0d, 0x1e, 0x1f, 0xea, 0x3f, 0x6e, 0x76, 0x02,
+    0x0a, 0x58, 0x4d, 0x2e, 0x20, 0x6c, 0x1e, 0x48,
+    0x8b, 0xf7, 0x2a, 0xae, 0x8c, 0x5d, 0x47, 0x04,
+    0x4d, 0x66, 0x05, 0xb2, 0x90, 0x0b, 0xbe, 0xcf,
+    0x3d, 0xa6, 0xa4, 0x06, 0x7c, 0x29, 0x3c, 0x64,
+    0xe5, 0x82, 0x0b, 0x03, 0xd8, 0x25, 0x96, 0x8d,
+    0x08, 0x78, 0x9b, 0x27, 0x15, 0x54, 0x76, 0x14,
+    0xd8, 0xdd, 0x35, 0x2f, 0x71, 0xa6, 0x84, 0x8f,
+    0x90, 0x51, 0x85, 0x01, 0x13, 0xb8, 0x90, 0x23,
+    0x99, 0xa5, 0x47, 0x03, 0x7a, 0xfd, 0x15, 0xbf,
+    0x63, 0xec, 0xd3, 0x0d, 0x01, 0x4d, 0x45, 0xb6,
+    0xd2, 0xeb, 0xeb, 0xdf, 0xef, 0x60, 0xdf, 0xef,
+    0x1f, 0x78, 0x35,
+};
+
+static unsigned char commit_data[] = {
+    0x74, 0x72, 0x65, 0x65, 0x20, 0x64, 0x66, 0x66,
+    0x32, 0x64, 0x61, 0x39, 0x30, 0x62, 0x32, 0x35,
+    0x34, 0x65, 0x31, 0x62, 0x65, 0x62, 0x38, 0x38,
+    0x39, 0x64, 0x31, 0x66, 0x31, 0x66, 0x31, 0x32,
+    0x38, 0x38, 0x62, 0x65, 0x31, 0x38, 0x30, 0x33,
+    0x37, 0x38, 0x32, 0x64, 0x66, 0x0a, 0x61, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x20, 0x41, 0x20, 0x55,
+    0x20, 0x54, 0x68, 0x6f, 0x72, 0x20, 0x3c, 0x61,
+    0x75, 0x74, 0x68, 0x6f, 0x72, 0x40, 0x65, 0x78,
+    0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+    0x6d, 0x3e, 0x20, 0x31, 0x32, 0x32, 0x37, 0x38,
+    0x31, 0x34, 0x32, 0x39, 0x37, 0x20, 0x2b, 0x30,
+    0x30, 0x30, 0x30, 0x0a, 0x63, 0x6f, 0x6d, 0x6d,
+    0x69, 0x74, 0x74, 0x65, 0x72, 0x20, 0x43, 0x20,
+    0x4f, 0x20, 0x4d, 0x69, 0x74, 0x74, 0x65, 0x72,
+    0x20, 0x3c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
+    0x74, 0x65, 0x72, 0x40, 0x65, 0x78, 0x61, 0x6d,
+    0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3e,
+    0x20, 0x31, 0x32, 0x32, 0x37, 0x38, 0x31, 0x34,
+    0x32, 0x39, 0x37, 0x20, 0x2b, 0x30, 0x30, 0x30,
+    0x30, 0x0a, 0x0a, 0x41, 0x20, 0x6f, 0x6e, 0x65,
+    0x2d, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x63, 0x6f,
+    0x6d, 0x6d, 0x69, 0x74, 0x20, 0x73, 0x75, 0x6d,
+    0x6d, 0x61, 0x72, 0x79, 0x0a, 0x0a, 0x54, 0x68,
+    0x65, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x6f,
+    0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f,
+    0x6d, 0x6d, 0x69, 0x74, 0x20, 0x6d, 0x65, 0x73,
+    0x73, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x63, 0x6f,
+    0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67,
+    0x20, 0x66, 0x75, 0x72, 0x74, 0x68, 0x65, 0x72,
+    0x20, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x6e, 0x61,
+    0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x6f, 0x66, 0x20,
+    0x74, 0x68, 0x65, 0x20, 0x70, 0x75, 0x72, 0x70,
+    0x6f, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74,
+    0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67,
+    0x65, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x72, 0x6f,
+    0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79,
+    0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d,
+    0x6d, 0x69, 0x74, 0x2e, 0x0a, 0x0a, 0x53, 0x69,
+    0x67, 0x6e, 0x65, 0x64, 0x2d, 0x6f, 0x66, 0x2d,
+    0x62, 0x79, 0x3a, 0x20, 0x41, 0x20, 0x55, 0x20,
+    0x54, 0x68, 0x6f, 0x72, 0x20, 0x3c, 0x61, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x40, 0x65, 0x78, 0x61,
+    0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+    0x3e, 0x0a,
+};
+
+static object_data commit = {
+    commit_bytes,
+    sizeof(commit_bytes),
+    "3d7f8a6af076c8c3f20071a8935cdbe8228594d1",
+    "commit",
+    "test-objects/3d",
+    "test-objects/3d/7f8a6af076c8c3f20071a8935cdbe8228594d1",
+    commit_data,
+    sizeof(commit_data),
+};
+
+/* tree == dff2da90b254e1beb889d1f1f1288be1803782df */
+static unsigned char tree_bytes[] = {
+    0x78, 0x01, 0x2b, 0x29, 0x4a, 0x4d, 0x55, 0x30,
+    0x34, 0x32, 0x63, 0x30, 0x34, 0x30, 0x30, 0x33,
+    0x31, 0x51, 0xc8, 0xcf, 0x4b, 0x65, 0xe8, 0x16,
+    0xae, 0x98, 0x58, 0x29, 0xff, 0x32, 0x53, 0x7d,
+    0x6d, 0xc5, 0x33, 0x6f, 0xae, 0xb5, 0xd5, 0xf7,
+    0x2e, 0x74, 0xdf, 0x81, 0x4a, 0x17, 0xe7, 0xe7,
+    0xa6, 0x32, 0xfc, 0x6d, 0x31, 0xd8, 0xd3, 0xe6,
+    0xf3, 0xe7, 0xea, 0x47, 0xbe, 0xd0, 0x09, 0x3f,
+    0x96, 0xb8, 0x3f, 0x90, 0x9e, 0xa2, 0xfd, 0x0f,
+    0x2a, 0x5f, 0x52, 0x9e, 0xcf, 0x50, 0x31, 0x43,
+    0x52, 0x29, 0xd1, 0x5a, 0xeb, 0x77, 0x82, 0x2a,
+    0x8b, 0xfe, 0xb7, 0xbd, 0xed, 0x5d, 0x07, 0x67,
+    0xfa, 0xb5, 0x42, 0xa5, 0xab, 0x52, 0x8b, 0xf2,
+    0x19, 0x9e, 0xcd, 0x7d, 0x34, 0x7b, 0xd3, 0xc5,
+    0x6b, 0xce, 0xde, 0xdd, 0x9a, 0xeb, 0xca, 0xa3,
+    0x6e, 0x1c, 0x7a, 0xd2, 0x13, 0x3c, 0x11, 0x00,
+    0xe2, 0xaa, 0x38, 0x57,
+};
+
+static unsigned char tree_data[] = {
+    0x31, 0x30, 0x30, 0x36, 0x34, 0x34, 0x20, 0x6f,
+    0x6e, 0x65, 0x00, 0x8b, 0x13, 0x78, 0x91, 0x79,
+    0x1f, 0xe9, 0x69, 0x27, 0xad, 0x78, 0xe6, 0x4b,
+    0x0a, 0xad, 0x7b, 0xde, 0xd0, 0x8b, 0xdc, 0x31,
+    0x30, 0x30, 0x36, 0x34, 0x34, 0x20, 0x73, 0x6f,
+    0x6d, 0x65, 0x00, 0xfd, 0x84, 0x30, 0xbc, 0x86,
+    0x4c, 0xfc, 0xd5, 0xf1, 0x0e, 0x55, 0x90, 0xf8,
+    0xa4, 0x47, 0xe0, 0x1b, 0x94, 0x2b, 0xfe, 0x31,
+    0x30, 0x30, 0x36, 0x34, 0x34, 0x20, 0x74, 0x77,
+    0x6f, 0x00, 0x78, 0x98, 0x19, 0x22, 0x61, 0x3b,
+    0x2a, 0xfb, 0x60, 0x25, 0x04, 0x2f, 0xf6, 0xbd,
+    0x87, 0x8a, 0xc1, 0x99, 0x4e, 0x85, 0x31, 0x30,
+    0x30, 0x36, 0x34, 0x34, 0x20, 0x7a, 0x65, 0x72,
+    0x6f, 0x00, 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1,
+    0xd6, 0x43, 0x4b, 0x8b, 0x29, 0xae, 0x77, 0x5a,
+    0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91,
+};
+
+static object_data tree = {
+    tree_bytes,
+    sizeof(tree_bytes),
+    "dff2da90b254e1beb889d1f1f1288be1803782df",
+    "tree",
+    "test-objects/df",
+    "test-objects/df/f2da90b254e1beb889d1f1f1288be1803782df",
+    tree_data,
+    sizeof(tree_data),
+};
+
+/* tag == 09d373e1dfdc16b129ceec6dd649739911541e05 */
+static unsigned char tag_bytes[] = {
+    0x78, 0x01, 0x35, 0x4e, 0xcb, 0x0a, 0xc2, 0x40,
+    0x10, 0xf3, 0xbc, 0x5f, 0x31, 0x77, 0xa1, 0xec,
+    0xa3, 0xed, 0x6e, 0x41, 0x44, 0xf0, 0x2c, 0x5e,
+    0xfc, 0x81, 0xe9, 0x76, 0xb6, 0xad, 0xb4, 0xb4,
+    0x6c, 0x07, 0xd1, 0xbf, 0x77, 0x44, 0x0d, 0x39,
+    0x84, 0x10, 0x92, 0x30, 0xf6, 0x60, 0xbc, 0xdb,
+    0x2d, 0xed, 0x9d, 0x22, 0x83, 0xeb, 0x7c, 0x0a,
+    0x58, 0x63, 0xd2, 0xbe, 0x8e, 0x21, 0xba, 0x64,
+    0xb5, 0xf6, 0x06, 0x43, 0xe3, 0xaa, 0xd8, 0xb5,
+    0x14, 0xac, 0x0d, 0x55, 0x53, 0x76, 0x46, 0xf1,
+    0x6b, 0x25, 0x88, 0xcb, 0x3c, 0x8f, 0xac, 0x58,
+    0x3a, 0x1e, 0xba, 0xd0, 0x85, 0xd8, 0xd8, 0xf7,
+    0x94, 0xe1, 0x0c, 0x57, 0xb8, 0x8c, 0xcc, 0x22,
+    0x0f, 0xdf, 0x90, 0xc8, 0x13, 0x3d, 0x71, 0x5e,
+    0x27, 0x2a, 0xc4, 0x39, 0x82, 0xb1, 0xd6, 0x07,
+    0x53, 0xda, 0xc6, 0xc3, 0x5e, 0x0b, 0x94, 0xba,
+    0x0d, 0xe3, 0x06, 0x42, 0x1e, 0x08, 0x3e, 0x95,
+    0xbf, 0x4b, 0x69, 0xc9, 0x90, 0x69, 0x22, 0xdc,
+    0xe8, 0xbf, 0xf2, 0x06, 0x42, 0x9a, 0x36, 0xb1,
+};
+
+static unsigned char tag_data[] = {
+    0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x33,
+    0x64, 0x37, 0x66, 0x38, 0x61, 0x36, 0x61, 0x66,
+    0x30, 0x37, 0x36, 0x63, 0x38, 0x63, 0x33, 0x66,
+    0x32, 0x30, 0x30, 0x37, 0x31, 0x61, 0x38, 0x39,
+    0x33, 0x35, 0x63, 0x64, 0x62, 0x65, 0x38, 0x32,
+    0x32, 0x38, 0x35, 0x39, 0x34, 0x64, 0x31, 0x0a,
+    0x74, 0x79, 0x70, 0x65, 0x20, 0x63, 0x6f, 0x6d,
+    0x6d, 0x69, 0x74, 0x0a, 0x74, 0x61, 0x67, 0x20,
+    0x76, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0a, 0x74,
+    0x61, 0x67, 0x67, 0x65, 0x72, 0x20, 0x43, 0x20,
+    0x4f, 0x20, 0x4d, 0x69, 0x74, 0x74, 0x65, 0x72,
+    0x20, 0x3c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
+    0x74, 0x65, 0x72, 0x40, 0x65, 0x78, 0x61, 0x6d,
+    0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3e,
+    0x20, 0x31, 0x32, 0x32, 0x37, 0x38, 0x31, 0x34,
+    0x32, 0x39, 0x37, 0x20, 0x2b, 0x30, 0x30, 0x30,
+    0x30, 0x0a, 0x0a, 0x54, 0x68, 0x69, 0x73, 0x20,
+    0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74,
+    0x61, 0x67, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63,
+    0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x72, 0x65,
+    0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x76, 0x30,
+    0x2e, 0x30, 0x2e, 0x31, 0x0a,
+};
+
+static object_data tag = {
+    tag_bytes,
+    sizeof(tag_bytes),
+    "09d373e1dfdc16b129ceec6dd649739911541e05",
+    "tag",
+    "test-objects/09",
+    "test-objects/09/d373e1dfdc16b129ceec6dd649739911541e05",
+    tag_data,
+    sizeof(tag_data),
+};
+
+/* zero == e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 */
+static unsigned char zero_bytes[] = {
+    0x78, 0x01, 0x4b, 0xca, 0xc9, 0x4f, 0x52, 0x30,
+    0x60, 0x00, 0x00, 0x09, 0xb0, 0x01, 0xf0,
+};
+
+static unsigned char zero_data[] = {
+    0x00  /* dummy data */
+};
+
+static object_data zero = {
+    zero_bytes,
+    sizeof(zero_bytes),
+    "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+    "blob",
+    "test-objects/e6",
+    "test-objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+    zero_data,
+    0,
+};
+
+/* two == 78981922613b2afb6025042ff6bd878ac1994e85 */
+static unsigned char two_bytes[] = {
+    0x78, 0x01, 0x4b, 0xca, 0xc9, 0x4f, 0x52, 0x30,
+    0x62, 0x48, 0xe4, 0x02, 0x00, 0x0e, 0x64, 0x02,
+    0x5d,
+};
+
+static unsigned char two_data[] = {
+    0x61, 0x0a,
+};
+
+static object_data two = {
+    two_bytes,
+    sizeof(two_bytes),
+    "78981922613b2afb6025042ff6bd878ac1994e85",
+    "blob",
+    "test-objects/78",
+    "test-objects/78/981922613b2afb6025042ff6bd878ac1994e85",
+    two_data,
+    sizeof(two_data),
+};
+
+/* some == fd8430bc864cfcd5f10e5590f8a447e01b942bfe */
+static unsigned char some_bytes[] = {
+    0x78, 0x01, 0x7d, 0x54, 0xc1, 0x4e, 0xe3, 0x30,
+    0x10, 0xdd, 0x33, 0x5f, 0x31, 0xc7, 0x5d, 0x94,
+    0xa5, 0x84, 0xd5, 0x22, 0xad, 0x7a, 0x0a, 0x15,
+    0x85, 0x48, 0xd0, 0x56, 0x49, 0x2a, 0xd4, 0xa3,
+    0x13, 0x4f, 0x88, 0x85, 0x63, 0x47, 0xb6, 0x43,
+    0xc9, 0xdf, 0xef, 0x8c, 0x69, 0x17, 0x56, 0x0b,
+    0x7b, 0xaa, 0x62, 0x7b, 0xde, 0xbc, 0xf7, 0xe6,
+    0x4d, 0x6b, 0x6d, 0x6b, 0x48, 0xd3, 0xcb, 0x5f,
+    0x5f, 0x66, 0xa7, 0x27, 0x70, 0x0a, 0x55, 0xa7,
+    0x3c, 0xb4, 0x4a, 0x23, 0xf0, 0xaf, 0x43, 0x04,
+    0x6f, 0xdb, 0xb0, 0x17, 0x0e, 0xe7, 0x30, 0xd9,
+    0x11, 0x1a, 0x61, 0xc0, 0xa1, 0x54, 0x3e, 0x38,
+    0x55, 0x8f, 0x81, 0x9e, 0x05, 0x10, 0x46, 0xce,
+    0xac, 0x83, 0xde, 0x4a, 0xd5, 0x4e, 0x0c, 0x42,
+    0x67, 0xa3, 0x91, 0xe8, 0x20, 0x74, 0x08, 0x01,
+    0x5d, 0xef, 0xc1, 0xb6, 0xf1, 0xe3, 0x66, 0xb5,
+    0x85, 0x1b, 0x34, 0xe8, 0x84, 0x86, 0xcd, 0x58,
+    0x6b, 0xd5, 0xc0, 0x9d, 0x6a, 0xd0, 0x78, 0x4c,
+    0xe0, 0x19, 0x9d, 0x57, 0xd6, 0xc0, 0x45, 0xc2,
+    0x18, 0xc2, 0xc3, 0xc0, 0x0f, 0x7c, 0x87, 0x12,
+    0xea, 0x29, 0x56, 0x2f, 0x99, 0x4f, 0x79, 0xe0,
+    0x03, 0x4b, 0x4b, 0x4d, 0x44, 0xa0, 0x92, 0x33,
+    0x2a, 0xe0, 0x9a, 0xdc, 0x80, 0x90, 0x52, 0xf1,
+    0x11, 0x04, 0x1b, 0x4b, 0x06, 0xea, 0xae, 0x3c,
+    0xe3, 0x7a, 0x50, 0x74, 0x4a, 0x84, 0xfe, 0xc3,
+    0x81, 0x41, 0xf8, 0x89, 0x18, 0x43, 0x67, 0x9d,
+    0x87, 0x47, 0xf5, 0x8c, 0x51, 0xf6, 0x68, 0xb4,
+    0xea, 0x55, 0x20, 0x2a, 0x6f, 0x80, 0xdc, 0x42,
+    0x2b, 0xf3, 0x14, 0x2b, 0x1a, 0xdb, 0x0f, 0xe4,
+    0x9a, 0x64, 0x84, 0xa3, 0x90, 0xa8, 0xf9, 0x8f,
+    0x9d, 0x86, 0x9e, 0xd3, 0xab, 0x5a, 0x99, 0xc8,
+    0xd9, 0xc3, 0x5e, 0x85, 0x0e, 0x2c, 0xb5, 0x73,
+    0x30, 0x38, 0xfb, 0xe8, 0x44, 0xef, 0x5f, 0x95,
+    0x1b, 0xc9, 0xd0, 0xef, 0x3c, 0x26, 0x32, 0x1e,
+    0xff, 0x2d, 0xb6, 0x23, 0x7b, 0x3f, 0xd1, 0x3c,
+    0x78, 0x1a, 0x0d, 0xcb, 0xe6, 0xf6, 0xd4, 0x44,
+    0x99, 0x47, 0x1a, 0x9e, 0xed, 0x23, 0xb5, 0x91,
+    0x6a, 0xdf, 0x53, 0x39, 0x03, 0xf8, 0x5a, 0xb1,
+    0x0f, 0x1f, 0xce, 0x81, 0x11, 0xde, 0x01, 0x7a,
+    0x90, 0x16, 0xc4, 0x30, 0xe8, 0x89, 0xed, 0x7b,
+    0x65, 0x4b, 0xd7, 0x03, 0x36, 0xc1, 0xcf, 0xa1,
+    0xa5, 0xb1, 0xe3, 0x8b, 0xe8, 0x07, 0x4d, 0xf3,
+    0x23, 0x25, 0x13, 0x35, 0x27, 0xf5, 0x8c, 0x11,
+    0xd3, 0xa0, 0x9a, 0xa8, 0xf5, 0x38, 0x7d, 0xce,
+    0x55, 0xc2, 0x71, 0x79, 0x13, 0xc7, 0xa3, 0xda,
+    0x77, 0x68, 0xc0, 0xd8, 0x10, 0xdd, 0x24, 0x8b,
+    0x15, 0x59, 0xc5, 0x10, 0xe2, 0x20, 0x99, 0x8e,
+    0xf0, 0x05, 0x9b, 0x31, 0x88, 0x5a, 0xe3, 0xd9,
+    0x37, 0xba, 0xe2, 0xdb, 0xbf, 0x92, 0xfa, 0x66,
+    0x16, 0x97, 0x47, 0xd9, 0x9d, 0x1d, 0x28, 0x7c,
+    0x9d, 0x08, 0x1c, 0xc7, 0xbd, 0xd2, 0x1a, 0x6a,
+    0x04, 0xf2, 0xa2, 0x1d, 0x75, 0x02, 0x14, 0x5d,
+    0xc6, 0x78, 0xc8, 0xab, 0xdb, 0xf5, 0xb6, 0x82,
+    0x6c, 0xb5, 0x83, 0x87, 0xac, 0x28, 0xb2, 0x55,
+    0xb5, 0x9b, 0xc7, 0xc1, 0xb0, 0xb7, 0xf8, 0x4c,
+    0xbc, 0x38, 0x0e, 0x8a, 0x04, 0x2a, 0x62, 0x41,
+    0x6b, 0xe0, 0x84, 0x09, 0x13, 0xe9, 0xe1, 0xea,
+    0xfb, 0xeb, 0x62, 0x71, 0x4b, 0x25, 0xd9, 0x55,
+    0x7e, 0x97, 0x57, 0x3b, 0x20, 0x33, 0x96, 0x79,
+    0xb5, 0xba, 0x2e, 0x4b, 0x58, 0xae, 0x0b, 0xc8,
+    0x60, 0x93, 0x15, 0x55, 0xbe, 0xd8, 0xde, 0x65,
+    0x05, 0x6c, 0xb6, 0xc5, 0x66, 0x5d, 0x5e, 0x93,
+    0xf7, 0x25, 0x65, 0x98, 0x41, 0x29, 0x86, 0x0c,
+    0xf2, 0xf1, 0x14, 0xa2, 0xb3, 0xbd, 0x75, 0x08,
+    0x12, 0x83, 0x50, 0xda, 0x1f, 0x23, 0xbe, 0xa3,
+    0x1d, 0xf4, 0x9d, 0x1d, 0xb5, 0x84, 0x4e, 0x50,
+    0x38, 0x1d, 0x36, 0x48, 0x21, 0x95, 0xd1, 0xac,
+    0x81, 0x99, 0x1d, 0xc1, 0x3f, 0x41, 0xe6, 0x9e,
+    0x42, 0x5b, 0x0a, 0x48, 0xcc, 0x5f, 0xe0, 0x7d,
+    0x3f, 0xc4, 0x6f, 0x0e, 0xfe, 0xc0, 0x2d, 0xfe,
+    0x01, 0x2c, 0xd6, 0x9b, 0x5d, 0xbe, 0xba, 0x21,
+    0xca, 0x79, 0xcb, 0xe3, 0x49, 0x60, 0xef, 0x68,
+    0x05, 0x28, 0x9b, 0x8c, 0xc1, 0x12, 0x3e, 0xdb,
+    0xc7, 0x04, 0x7e, 0xa6, 0x74, 0x29, 0xcc, 0x13,
+    0xed, 0x07, 0x94, 0x81, 0xd6, 0x96, 0xaa, 0x97,
+    0xaa, 0xa5, 0xc0, 0x2f, 0xb5, 0xb5, 0x2e, 0xe6,
+    0xfc, 0xca, 0xfa, 0x60, 0x4d, 0x02, 0xf7, 0x19,
+    0x9c, 0x5f, 0xa4, 0xe9, 0xf9, 0xf7, 0xf4, 0xc7,
+    0x79, 0x9a, 0xc0, 0xb6, 0xcc, 0x58, 0xec, 0xec,
+    0xe4, 0x37, 0x22, 0xfa, 0x8b, 0x53,
+};
+
+static unsigned char some_data[] = {
+    0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x54, 0x68,
+    0x69, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20,
+    0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20,
+    0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
+    0x3b, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x63, 0x61,
+    0x6e, 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74,
+    0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x69,
+    0x74, 0x20, 0x61, 0x6e, 0x64, 0x2f, 0x6f, 0x72,
+    0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0a,
+    0x20, 0x2a, 0x20, 0x69, 0x74, 0x20, 0x75, 0x6e,
+    0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20,
+    0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66,
+    0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x4e, 0x55,
+    0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
+    0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+    0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x2c,
+    0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+    0x20, 0x32, 0x2c, 0x0a, 0x20, 0x2a, 0x20, 0x61,
+    0x73, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73,
+    0x68, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
+    0x68, 0x65, 0x20, 0x46, 0x72, 0x65, 0x65, 0x20,
+    0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
+    0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x20, 0x2a, 0x0a,
+    0x20, 0x2a, 0x20, 0x49, 0x6e, 0x20, 0x61, 0x64,
+    0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74,
+    0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x65,
+    0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
+    0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
+    0x20, 0x47, 0x4e, 0x55, 0x20, 0x47, 0x65, 0x6e,
+    0x65, 0x72, 0x61, 0x6c, 0x20, 0x50, 0x75, 0x62,
+    0x6c, 0x69, 0x63, 0x20, 0x4c, 0x69, 0x63, 0x65,
+    0x6e, 0x73, 0x65, 0x2c, 0x0a, 0x20, 0x2a, 0x20,
+    0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x73, 0x20, 0x67, 0x69, 0x76, 0x65,
+    0x20, 0x79, 0x6f, 0x75, 0x20, 0x75, 0x6e, 0x6c,
+    0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x20, 0x70,
+    0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f,
+    0x6e, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x69, 0x6e,
+    0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f,
+    0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x0a, 0x20,
+    0x2a, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
+    0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69,
+    0x73, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x69,
+    0x6e, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x62,
+    0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+    0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x74,
+    0x68, 0x65, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x67,
+    0x72, 0x61, 0x6d, 0x73, 0x2c, 0x0a, 0x20, 0x2a,
+    0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x20,
+    0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75,
+    0x74, 0x65, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65,
+    0x20, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61,
+    0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x77, 0x69,
+    0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x6e,
+    0x79, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69,
+    0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x2a,
+    0x20, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x20,
+    0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65,
+    0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20,
+    0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6c,
+    0x65, 0x2e, 0x20, 0x20, 0x28, 0x54, 0x68, 0x65,
+    0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
+    0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+    0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x0a,
+    0x20, 0x2a, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72,
+    0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20,
+    0x64, 0x6f, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79,
+    0x20, 0x69, 0x6e, 0x20, 0x6f, 0x74, 0x68, 0x65,
+    0x72, 0x20, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63,
+    0x74, 0x73, 0x3b, 0x20, 0x66, 0x6f, 0x72, 0x20,
+    0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c,
+    0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x63, 0x6f,
+    0x76, 0x65, 0x72, 0x0a, 0x20, 0x2a, 0x20, 0x6d,
+    0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74,
+    0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2c,
+    0x20, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x69, 0x73,
+    0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x6e,
+    0x6f, 0x74, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x65,
+    0x64, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x0a, 0x20,
+    0x2a, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6d, 0x62,
+    0x69, 0x6e, 0x65, 0x64, 0x20, 0x65, 0x78, 0x65,
+    0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e,
+    0x29, 0x0a, 0x20, 0x2a, 0x0a, 0x20, 0x2a, 0x20,
+    0x54, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6c,
+    0x65, 0x20, 0x69, 0x73, 0x20, 0x64, 0x69, 0x73,
+    0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64,
+    0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20,
+    0x68, 0x6f, 0x70, 0x65, 0x20, 0x74, 0x68, 0x61,
+    0x74, 0x20, 0x69, 0x74, 0x20, 0x77, 0x69, 0x6c,
+    0x6c, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65,
+    0x66, 0x75, 0x6c, 0x2c, 0x20, 0x62, 0x75, 0x74,
+    0x0a, 0x20, 0x2a, 0x20, 0x57, 0x49, 0x54, 0x48,
+    0x4f, 0x55, 0x54, 0x20, 0x41, 0x4e, 0x59, 0x20,
+    0x57, 0x41, 0x52, 0x52, 0x41, 0x4e, 0x54, 0x59,
+    0x3b, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75,
+    0x74, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x74,
+    0x68, 0x65, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x69,
+    0x65, 0x64, 0x20, 0x77, 0x61, 0x72, 0x72, 0x61,
+    0x6e, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x0a, 0x20,
+    0x2a, 0x20, 0x4d, 0x45, 0x52, 0x43, 0x48, 0x41,
+    0x4e, 0x54, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54,
+    0x59, 0x20, 0x6f, 0x72, 0x20, 0x46, 0x49, 0x54,
+    0x4e, 0x45, 0x53, 0x53, 0x20, 0x46, 0x4f, 0x52,
+    0x20, 0x41, 0x20, 0x50, 0x41, 0x52, 0x54, 0x49,
+    0x43, 0x55, 0x4c, 0x41, 0x52, 0x20, 0x50, 0x55,
+    0x52, 0x50, 0x4f, 0x53, 0x45, 0x2e, 0x20, 0x20,
+    0x53, 0x65, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
+    0x47, 0x4e, 0x55, 0x0a, 0x20, 0x2a, 0x20, 0x47,
+    0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x50,
+    0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x4c, 0x69,
+    0x63, 0x65, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6f,
+    0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x64,
+    0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x0a,
+    0x20, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x59, 0x6f,
+    0x75, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64,
+    0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x72, 0x65,
+    0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x20, 0x61,
+    0x20, 0x63, 0x6f, 0x70, 0x79, 0x20, 0x6f, 0x66,
+    0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x4e, 0x55,
+    0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
+    0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+    0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x0a,
+    0x20, 0x2a, 0x20, 0x61, 0x6c, 0x6f, 0x6e, 0x67,
+    0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68,
+    0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72,
+    0x61, 0x6d, 0x3b, 0x20, 0x73, 0x65, 0x65, 0x20,
+    0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65,
+    0x20, 0x43, 0x4f, 0x50, 0x59, 0x49, 0x4e, 0x47,
+    0x2e, 0x20, 0x20, 0x49, 0x66, 0x20, 0x6e, 0x6f,
+    0x74, 0x2c, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65,
+    0x20, 0x74, 0x6f, 0x0a, 0x20, 0x2a, 0x20, 0x74,
+    0x68, 0x65, 0x20, 0x46, 0x72, 0x65, 0x65, 0x20,
+    0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
+    0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x35, 0x31, 0x20,
+    0x46, 0x72, 0x61, 0x6e, 0x6b, 0x6c, 0x69, 0x6e,
+    0x20, 0x53, 0x74, 0x72, 0x65, 0x65, 0x74, 0x2c,
+    0x20, 0x46, 0x69, 0x66, 0x74, 0x68, 0x20, 0x46,
+    0x6c, 0x6f, 0x6f, 0x72, 0x2c, 0x0a, 0x20, 0x2a,
+    0x20, 0x42, 0x6f, 0x73, 0x74, 0x6f, 0x6e, 0x2c,
+    0x20, 0x4d, 0x41, 0x20, 0x30, 0x32, 0x31, 0x31,
+    0x30, 0x2d, 0x31, 0x33, 0x30, 0x31, 0x2c, 0x20,
+    0x55, 0x53, 0x41, 0x2e, 0x0a, 0x20, 0x2a, 0x2f,
+    0x0a,
+};
+
+static object_data some = {
+    some_bytes,
+    sizeof(some_bytes),
+    "fd8430bc864cfcd5f10e5590f8a447e01b942bfe",
+    "blob",
+    "test-objects/fd",
+    "test-objects/fd/8430bc864cfcd5f10e5590f8a447e01b942bfe",
+    some_data,
+    sizeof(some_data),
+};
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/mixed.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/mixed.c
new file mode 100755
index 0000000..2dad4b6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/mixed.c
@@ -0,0 +1,110 @@
+#include "clar_libgit2.h"
+#include "odb.h"
+
+static git_odb *_odb;
+
+void test_odb_mixed__initialize(void)
+{
+	cl_git_pass(git_odb_open(&_odb, cl_fixture("duplicate.git/objects")));
+}
+
+void test_odb_mixed__cleanup(void)
+{
+	git_odb_free(_odb);
+	_odb = NULL;
+}
+
+void test_odb_mixed__dup_oid(void) {
+	const char hex[] = "ce013625030ba8dba906f756967f9e9ca394464a";
+	const char short_hex[] = "ce01362";
+	git_oid oid;
+	git_odb_object *obj;
+
+	cl_git_pass(git_oid_fromstr(&oid, hex));
+	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, GIT_OID_HEXSZ));
+	git_odb_object_free(obj);
+
+	cl_git_pass(git_odb_exists_prefix(NULL, _odb, &oid, GIT_OID_HEXSZ));
+
+	cl_git_pass(git_oid_fromstrn(&oid, short_hex, sizeof(short_hex) - 1));
+	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, sizeof(short_hex) - 1));
+	git_odb_object_free(obj);
+
+	cl_git_pass(git_odb_exists_prefix(NULL, _odb, &oid, sizeof(short_hex) - 1));
+}
+
+/* some known sha collisions of file content:
+ *   'aabqhq' and 'aaazvc' with prefix 'dea509d0' (+ '9' and + 'b')
+ *   'aaeufo' and 'aaaohs' with prefix '81b5bff5' (+ 'f' and + 'b')
+ *   'aafewy' and 'aaepta' with prefix '739e3c4c'
+ *   'aahsyn' and 'aadrjg' with prefix '0ddeaded' (+ '9' and + 'e')
+ */
+
+void test_odb_mixed__dup_oid_prefix_0(void) {
+	char hex[10];
+	git_oid oid, found;
+	git_odb_object *obj;
+
+	/* ambiguous in the same pack file */
+
+	strncpy(hex, "dea509d0", sizeof(hex));
+	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
+	cl_assert_equal_i(
+		GIT_EAMBIGUOUS, git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
+	cl_assert_equal_i(
+		GIT_EAMBIGUOUS, git_odb_exists_prefix(&found, _odb, &oid, strlen(hex)));
+
+	strncpy(hex, "dea509d09", sizeof(hex));
+	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
+	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
+	cl_git_pass(git_odb_exists_prefix(&found, _odb, &oid, strlen(hex)));
+	cl_assert_equal_oid(&found, git_odb_object_id(obj));
+	git_odb_object_free(obj);
+
+	strncpy(hex, "dea509d0b", sizeof(hex));
+	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
+	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
+	git_odb_object_free(obj);
+
+	/* ambiguous in different pack files */
+
+	strncpy(hex, "81b5bff5", sizeof(hex));
+	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
+	cl_assert_equal_i(
+		GIT_EAMBIGUOUS, git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
+	cl_assert_equal_i(
+		GIT_EAMBIGUOUS, git_odb_exists_prefix(&found, _odb, &oid, strlen(hex)));
+
+	strncpy(hex, "81b5bff5b", sizeof(hex));
+	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
+	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
+	cl_git_pass(git_odb_exists_prefix(&found, _odb, &oid, strlen(hex)));
+	cl_assert_equal_oid(&found, git_odb_object_id(obj));
+	git_odb_object_free(obj);
+
+	strncpy(hex, "81b5bff5f", sizeof(hex));
+	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
+	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
+	git_odb_object_free(obj);
+
+	/* ambiguous in pack file and loose */
+
+	strncpy(hex, "0ddeaded", sizeof(hex));
+	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
+	cl_assert_equal_i(
+		GIT_EAMBIGUOUS, git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
+	cl_assert_equal_i(
+		GIT_EAMBIGUOUS, git_odb_exists_prefix(&found, _odb, &oid, strlen(hex)));
+
+	strncpy(hex, "0ddeaded9", sizeof(hex));
+	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
+	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
+	cl_git_pass(git_odb_exists_prefix(&found, _odb, &oid, strlen(hex)));
+	cl_assert_equal_oid(&found, git_odb_object_id(obj));
+	git_odb_object_free(obj);
+
+	strncpy(hex, "0ddeadede", sizeof(hex));
+	cl_git_pass(git_oid_fromstrn(&oid, hex, strlen(hex)));
+	cl_git_pass(git_odb_read_prefix(&obj, _odb, &oid, strlen(hex)));
+	git_odb_object_free(obj);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/pack_data.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/pack_data.h
new file mode 100755
index 0000000..e6371be
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/pack_data.h
@@ -0,0 +1,151 @@
+
+static const char *packed_objects[] = {
+	"0266163a49e280c4f5ed1e08facd36a2bd716bcf",
+	"53fc32d17276939fc79ed05badaef2db09990016",
+	"6336846bd5c88d32f93ae57d846683e61ab5c530",
+	"6dcf9bf7541ee10456529833502442f385010c3d",
+	"bed08a0b30b72a9d4aed7f1af8c8ca124e8d64b9",
+	"e90810b8df3e80c413d903f631643c716887138d",
+	"fc3c3a2083e9f6f89e6bd53e9420e70d1e357c9b",
+	"fc58168adf502d0c0ef614c3111a7038fc8c09c8",
+	"fd0ec0333948dfe23265ac46be0205a436a8c3a5",
+	"fd8430bc864cfcd5f10e5590f8a447e01b942bfe",
+	"fd899f45951c15c1c5f7c34b1c864e91bd6556c6",
+	"fda23b974899e7e1f938619099280bfda13bdca9",
+	"fdbec189efb657c8325962b494875987881a356b",
+	"fe1ca6bd22b5d8353ce6c2f3aba80805c438a7a5",
+	"fe3a6a42c87ff1239370c741a265f3997add87c1",
+	"deb106bfd2d36ecf9f0079224c12022201a39ad1",
+	"dec93efc79e60f2680de3e666755d335967eec30",
+	"def425bf8568b9c1e20879bf5be6f9c52b7361c4",
+	"df48000ac4f48570054e3a71a81916357997b680",
+	"dfae6ed8f6dd8acc3b40a31811ea316239223559",
+	"dff79e27d3d2cdc09790ded80fe2ea8ff5d61034",
+	"e00e46abe4c542e17c8bc83d72cf5be8018d7b0e",
+	"e01b107b4f77f8f98645adac0206a504f2d29d7c",
+	"e032d863f512c47b479bd984f8b6c8061f66b7d4",
+	"e044baa468a1c74f9f9da36805445f6888358b49",
+	"e04529998989ba8ae3419538dd57969af819b241",
+	"e0637ddfbea67c8d7f557c709e095af8906e9176",
+	"e0743ad4031231e71700abdc6fdbe94f189d20e5",
+	"cf33ac7a3d8b2b8f6bb266518aadbf59de397608",
+	"cf5f7235b9c9689b133f6ea12015720b411329bd",
+	"cf6cccf1297284833a9a03138a1f5738fa1c6c94",
+	"cf7992bde17ce7a79cab5f0c1fcbe8a0108721ed",
+	"cfe3a027ab12506d4144ee8a35669ae8fc4b7ab1",
+	"cfe96f31dfad7bab49977aa1df7302f7fafcb025",
+	"cff54d138945ef4de384e9d2759291d0c13ea90a",
+	"d01f7573ac34c2f502bd1cf18cde73480c741151",
+	"d03f567593f346a1ca96a57f8191def098d126e3",
+	"d047b47aadf88501238f36f5c17dd0a50dc62087",
+	"d0a0d63086fae3b0682af7261df21f7d0f7f066d",
+	"d0a44bd6ed0be21b725a96c0891bbc79bc1a540c",
+	"d0d7e736e536a41bcb885005f8bf258c61cad682",
+	"d0e7959d4b95ffec6198df6f5a7ae259b23a5f50",
+	"bf2fe2acca17d13356ce802ba9dc8343f710dfb7",
+	"bf55f407d6d9418e51f42ea7a3a6aadf17388349",
+	"bf92206f8b633b88a66dca4a911777630b06fbac",
+	"bfaf8c42eb8842abe206179fee864cfba87e3ca9",
+	"bfe05675d4e8f6b59d50932add8790f1a06b10ee",
+	"bff8618112330763327cfa6ce6e914db84f51ddf",
+	"bff873e9853ed99fed52c25f7ad29f78b27dcec2",
+	"c01c3fae7251098d7af1b459bcd0786e81d4616d",
+	"c0220fca67f48b8a5d4163d53b1486224be3a198",
+	"c02d0b160b82ee72469c269f13de4c26a7ea09cb",
+	"c059510ad1b45ab58390e042d7dee1ac46703854",
+	"c07204a1897aeeaa3c248d29dbfa9b033baf9755",
+	"c073337a4dd7276931b4b3fdbc3f0040e9441793",
+	"0fd7e4bfba5b3a82be88d1057757ca8b2c5e6d26",
+	"100746511cc45c9f1ad6721c4ef5be49222fee4d",
+	"1088490171d9b984d68b8b9be9ca003f4eafff59",
+	"1093c8ff4cb78fcf5f79dbbeedcb6e824bd4e253",
+	"10aa3fa72afab7ee31e116ae06442fe0f7b79df2",
+	"10b759e734e8299aa0dca08be935d95d886127b6",
+	"111d5ccf0bb010c4e8d7af3eedfa12ef4c5e265b",
+	"11261fbff21758444d426356ff6327ee01e90752",
+	"112998d425717bb922ce74e8f6f0f831d8dc4510",
+	"2ef4e5d838b6507bd61d457cf6466662b791c5c0",
+	"2ef4faa0f82efa00eeac6cae9e8b2abccc8566ee",
+	"2f06098183b0d7be350acbe39cdbaccff2df0c4a",
+	"2f1c5d509ac5bffb3c62f710a1c2c542e126dfd1",
+	"2f205b20fc16423c42b3ba51b2ea78d7b9ff3578",
+	"2f9b6b6e3d9250ba09360734aa47973a993b59d1",
+	"30c62a2d5a8d644f1311d4f7fe3f6a788e4c8188",
+	"31438e245492d85fd6da4d1406eba0fbde8332a4",
+	"3184a3abdfea231992254929ff4e275898e5bbf6",
+	"3188ffdbb3a3d52e0f78f30c484533899224436e",
+	"32581d0093429770d044a60eb0e9cc0462bedb13",
+	"32679a9544d83e5403202c4d5efb61ad02492847",
+	"4e7e9f60b7e2049b7f5697daf133161a18ef688f",
+	"4e8cda27ddc8be7db875ceb0f360c37734724c6d",
+	"4ea481c61c59ab55169b7cbaae536ad50b49d6f0",
+	"4f0adcd0e61eabe06fe32be66b16559537124b7a",
+	"4f1355c91100d12f9e7202f91b245df0c110867c",
+	"4f6eadeb08b9d0d1e8b1b3eac8a34940adf29a2d",
+	"4f9339df943c53117a5fc8e86e2f38716ff3a668",
+	"4fc3874b118752e40de556b1c3e7b4a9f1737d00",
+	"4ff1dd0992dd6baafdb5e166be6f9f23b59bdf87",
+	"5018a35e0b7e2eec7ce5050baf9c7343f3f74164",
+	"50298f44a45eda3a29dae82dbe911b5aa176ac07",
+	"502acd164fb115768d723144da2e7bb5a24891bb",
+	"50330c02bd4fd95c9db1fcf2f97f4218e42b7226",
+	"5052bf355d9f8c52446561a39733a8767bf31e37",
+	"6f2cd729ae42988c1dd43588d3a6661ba48ad7a0",
+	"6f4e2c42d9138bfbf3e0f908f1308828cc6f2178",
+	"6f6a17db05a83620cef4572761831c20a70ba9b9",
+	"6faad60901e36538634f0d8b8ff3f21f83503c71",
+	"6fc72e46de3df0c3842dab302bbacf697a63abab",
+	"6fdccd49f442a7204399ca9b418f017322dbded8",
+	"6fe7568fc3861c334cb008fd85d57d9647249ef5",
+	"700f55d91d7b55665594676a4bada1f1457a0598",
+	"702bd70595a7b19afc48a1f784a6505be68469d4",
+	"7033f9ee0e52b08cb5679cd49b7b7999eaf9eaf8",
+	"70957110ce446c4e250f865760fb3da513cdcc92",
+	"8ec696a4734f16479d091bc70574d23dd9fe7443",
+	"8ed341c55ed4d6f4cdc8bf4f0ca18a08c93f6962",
+	"8edc2805f1f11b63e44bf81f4557f8b473612b69",
+	"8ef9060a954118a698fc10e20acdc430566a100f",
+	"8f0c4b543f4bb6eb1518ecfc3d4699e43108d393",
+	"8fac94df3035405c2e60b3799153ce7c428af6b9",
+	"904c0ac12b23548de524adae712241b423d765a3",
+	"90bbaa9a809c3a768d873a9cc7d52b4f3bf3d1b9",
+	"90d4d2f0fc362beabbbf76b4ffda0828229c198d",
+	"90f9ff6755330b685feff6c3d81782ee3592ab04",
+	"91822c50ebe4f9bf5bbb8308ecf9f6557062775c",
+	"91d973263a55708fa8255867b3202d81ef9c2868",
+	"af292c99c6148d772af3315a1c74e83330e7ead7",
+	"af3b99d5be330dbbce0b9250c3a5fb05911908cc",
+	"af55d0cdeb280af2db8697e5afa506e081012719",
+	"af795e498d411142ddb073e8ca2c5447c3295a4c",
+	"afadc73a392f8cc8e2cc77dd62a7433dd3bafa8c",
+	"affd84ed8ec7ce67612fe3c12a80f8164b101f6a",
+	"b0941f9c70ffe67f0387a827b338e64ecf3190f0",
+	"b0a3077f9ef6e093f8d9869bdb0c07095bd722cb",
+	"b0a8568a7614806378a54db5706ee3b06ae58693",
+	"b0fb7372f242233d1d35ce7d8e74d3990cbc5841",
+	"b10489944b9ead17427551759d180d10203e06ba",
+	"b196a807b323f2748ffc6b1d42cd0812d04c9a40",
+	"b1bb1d888f0c5e19278536d49fa77db035fac7ae"
+};
+
+static const char *loose_objects[] = {
+	"45b983be36b73c0788dc9cbcb76cbb80fc7bb057",
+	"a8233120f6ad708f843d861ce2b7228ec4e3dec6",
+	"fd093bff70906175335656e6ce6ae05783708765",
+	"c47800c7266a2be04c571c04d5a6614691ea99bd",
+	"a71586c1dfe8a71c6cbf6c129f404c5642ff31bd",
+	"8496071c1b46c854b31185ea97743be6a8774479",
+	"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+	"814889a078c031f61ed08ab5fa863aea9314344d",
+	"5b5b025afb0b4c913b4c338a42934a3863bf3644",
+	"1385f264afb75a56a5bec74243be9b367ba4ca08",
+	"f60079018b664e4e79329a7ef9559c8d9e0378d1",
+	"be3563ae3f795b2b4353bcce3a527ad0a4f7f644",
+	"75057dd4114e74cca1d750d0aee1647c903cb60a",
+	"fa49b077972391ad58037050f2a75f74e3671e92",
+	"9fd738e8f7967c078dceed8190330fc8648ee56a",
+	"1810dff58d8a660512d4832e740f692884338ccd",
+	"181037049a54a1eb5fab404658a3a250b44335d7",
+	"a4a7dce85cf63874e984719f4fdd239f5145052f",
+	"4a202b346bb0fb0db7eff3cffeb3c70babbd2045"
+};
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/pack_data_one.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/pack_data_one.h
new file mode 100755
index 0000000..13570ba
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/pack_data_one.h
@@ -0,0 +1,19 @@
+/* Just a few to make sure it's working, the rest is tested already */
+static const char *packed_objects_one[] = {
+	"9fcf811e00fa469688943a9152c16d4ee90fb9a9",
+	"a93f42a5b5e9de40fa645a9ff1e276a021c9542b",
+	"12bf5f3e3470d90db177ccf1b5e8126409377fc6",
+	"ed1ea164cdbe3c4b200fb4fa19861ea90eaee222",
+	"dfae6ed8f6dd8acc3b40a31811ea316239223559",
+	"aefe66d192771201e369fde830530f4475beec30",
+	"775e4b4c1296e9e3104f2a36ca9cf9356a130959",
+	"412ec4e4a6a7419bc1be00561fe474e54cb499fe",
+	"236e7579fed7763be77209efb8708960982f3cb3",
+	"09fe9364461cf60dd1c46b0e9545b1e47bb1a297",
+	"d76d8a6390d1cf32138d98a91b1eb7e0275a12f5",
+	"d0fdf2dcff2f548952eec536ccc6d266550041bc",
+	"a20d733a9fa79fa5b4cbb9639864f93325ec27a6",
+	"785d3fe8e7db5ade2c2242fecd46c32a7f4dc59f",
+	"4d8d0fd9cb6045075385701c3f933ec13345e9c4",
+	"0cfd861bd547b6520d1fc2e190e8359e0a9c9b90"
+};
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/packed.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/packed.c
new file mode 100755
index 0000000..b4f549b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/packed.c
@@ -0,0 +1,79 @@
+#include "clar_libgit2.h"
+#include "odb.h"
+#include "pack_data.h"
+
+static git_odb *_odb;
+
+void test_odb_packed__initialize(void)
+{
+    cl_git_pass(git_odb_open(&_odb, cl_fixture("testrepo.git/objects")));
+}
+
+void test_odb_packed__cleanup(void)
+{
+	git_odb_free(_odb);
+	_odb = NULL;
+}
+
+void test_odb_packed__mass_read(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(packed_objects); ++i) {
+		git_oid id;
+		git_odb_object *obj;
+
+		cl_git_pass(git_oid_fromstr(&id, packed_objects[i]));
+		cl_assert(git_odb_exists(_odb, &id) == 1);
+		cl_git_pass(git_odb_read(&obj, _odb, &id));
+
+		git_odb_object_free(obj);
+	}
+}
+
+void test_odb_packed__read_header_0(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(packed_objects); ++i) {
+		git_oid id;
+		git_odb_object *obj;
+		size_t len;
+		git_otype type;
+
+		cl_git_pass(git_oid_fromstr(&id, packed_objects[i]));
+
+		cl_git_pass(git_odb_read(&obj, _odb, &id));
+		cl_git_pass(git_odb_read_header(&len, &type, _odb, &id));
+
+		cl_assert(obj->cached.size == len);
+		cl_assert(obj->cached.type == type);
+
+		git_odb_object_free(obj);
+	}
+}
+
+void test_odb_packed__read_header_1(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(loose_objects); ++i) {
+		git_oid id;
+		git_odb_object *obj;
+		size_t len;
+		git_otype type;
+
+		cl_git_pass(git_oid_fromstr(&id, loose_objects[i]));
+
+		cl_assert(git_odb_exists(_odb, &id) == 1);
+
+		cl_git_pass(git_odb_read(&obj, _odb, &id));
+		cl_git_pass(git_odb_read_header(&len, &type, _odb, &id));
+
+		cl_assert(obj->cached.size == len);
+		cl_assert(obj->cached.type == type);
+
+		git_odb_object_free(obj);
+	}
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/packed_one.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/packed_one.c
new file mode 100755
index 0000000..0c6ed38
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/packed_one.c
@@ -0,0 +1,60 @@
+#include "clar_libgit2.h"
+#include "git2/odb_backend.h"
+
+#include "pack_data_one.h"
+#include "pack.h"
+
+static git_odb *_odb;
+
+void test_odb_packed_one__initialize(void)
+{
+	git_odb_backend *backend = NULL;
+
+	cl_git_pass(git_odb_new(&_odb));
+	cl_git_pass(git_odb_backend_one_pack(&backend, cl_fixture("testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx")));
+	cl_git_pass(git_odb_add_backend(_odb, backend, 1));
+}
+
+void test_odb_packed_one__cleanup(void)
+{
+	git_odb_free(_odb);
+	_odb = NULL;
+}
+
+void test_odb_packed_one__mass_read(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(packed_objects_one); ++i) {
+		git_oid id;
+		git_odb_object *obj;
+
+		cl_git_pass(git_oid_fromstr(&id, packed_objects_one[i]));
+		cl_assert(git_odb_exists(_odb, &id) == 1);
+		cl_git_pass(git_odb_read(&obj, _odb, &id));
+
+		git_odb_object_free(obj);
+	}
+}
+
+void test_odb_packed_one__read_header_0(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(packed_objects_one); ++i) {
+		git_oid id;
+		git_odb_object *obj;
+		size_t len;
+		git_otype type;
+
+		cl_git_pass(git_oid_fromstr(&id, packed_objects_one[i]));
+
+		cl_git_pass(git_odb_read(&obj, _odb, &id));
+		cl_git_pass(git_odb_read_header(&len, &type, _odb, &id));
+
+		cl_assert(obj->cached.size == len);
+		cl_assert(obj->cached.type == type);
+
+		git_odb_object_free(obj);
+	}
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/sorting.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/sorting.c
new file mode 100755
index 0000000..147a160
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/sorting.c
@@ -0,0 +1,69 @@
+#include "clar_libgit2.h"
+#include "git2/sys/odb_backend.h"
+
+typedef struct {
+	git_odb_backend base;
+	size_t position;
+} fake_backend;
+
+static git_odb_backend *new_backend(size_t position)
+{
+	fake_backend *b;
+
+	b = git__calloc(1, sizeof(fake_backend));
+	if (b == NULL)
+		return NULL;
+
+	b->base.version = GIT_ODB_BACKEND_VERSION;
+	b->position = position;
+	return (git_odb_backend *)b;
+}
+
+static void check_backend_sorting(git_odb *odb)
+{
+	size_t i, max_i = git_odb_num_backends(odb);
+	fake_backend *internal;
+
+	for (i = 0; i < max_i; ++i) {
+		cl_git_pass(git_odb_get_backend((git_odb_backend **)&internal, odb, i));
+		cl_assert(internal != NULL);
+		cl_assert_equal_sz(i, internal->position);
+	}
+}
+
+static git_odb *_odb;
+
+void test_odb_sorting__initialize(void)
+{
+	cl_git_pass(git_odb_new(&_odb));
+}
+
+void test_odb_sorting__cleanup(void)
+{
+	git_odb_free(_odb);
+	_odb = NULL;
+}
+
+void test_odb_sorting__basic_backends_sorting(void)
+{
+	cl_git_pass(git_odb_add_backend(_odb, new_backend(0), 5));
+	cl_git_pass(git_odb_add_backend(_odb, new_backend(2), 3));
+	cl_git_pass(git_odb_add_backend(_odb, new_backend(1), 4));
+	cl_git_pass(git_odb_add_backend(_odb, new_backend(3), 1));
+
+	check_backend_sorting(_odb);
+}
+
+void test_odb_sorting__alternate_backends_sorting(void)
+{
+	cl_git_pass(git_odb_add_backend(_odb, new_backend(0), 5));
+	cl_git_pass(git_odb_add_backend(_odb, new_backend(2), 3));
+	cl_git_pass(git_odb_add_backend(_odb, new_backend(1), 4));
+	cl_git_pass(git_odb_add_backend(_odb, new_backend(3), 1));
+	cl_git_pass(git_odb_add_alternate(_odb, new_backend(4), 5));
+	cl_git_pass(git_odb_add_alternate(_odb, new_backend(6), 3));
+	cl_git_pass(git_odb_add_alternate(_odb, new_backend(5), 4));
+	cl_git_pass(git_odb_add_alternate(_odb, new_backend(7), 1));
+
+	check_backend_sorting(_odb);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/streamwrite.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/streamwrite.c
new file mode 100755
index 0000000..591a200
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/odb/streamwrite.c
@@ -0,0 +1,56 @@
+#include "clar_libgit2.h"
+#include "git2/odb_backend.h"
+
+static git_repository *repo;
+static git_odb *odb;
+static git_odb_stream *stream;
+
+void test_odb_streamwrite__initialize(void)
+{
+	repo = cl_git_sandbox_init("testrepo.git");
+	cl_git_pass(git_repository_odb(&odb, repo));
+
+	cl_git_pass(git_odb_open_wstream(&stream, odb, 14, GIT_OBJ_BLOB));
+	cl_assert_equal_sz(14, stream->declared_size);
+}
+
+void test_odb_streamwrite__cleanup(void)
+{
+	git_odb_stream_free(stream);
+	git_odb_free(odb);
+	cl_git_sandbox_cleanup();
+}
+
+void test_odb_streamwrite__can_accept_chunks(void)
+{
+	git_oid oid;
+
+	cl_git_pass(git_odb_stream_write(stream, "deadbeef", 8));
+	cl_assert_equal_sz(8, stream->received_bytes);
+
+	cl_git_pass(git_odb_stream_write(stream, "deadbeef", 6));
+	cl_assert_equal_sz(8 + 6, stream->received_bytes);
+
+	cl_git_pass(git_odb_stream_finalize_write(&oid, stream));
+}
+
+void test_odb_streamwrite__can_detect_missing_bytes(void)
+{
+	git_oid oid;
+
+	cl_git_pass(git_odb_stream_write(stream, "deadbeef", 8));
+	cl_assert_equal_sz(8, stream->received_bytes);
+
+	cl_git_pass(git_odb_stream_write(stream, "deadbeef", 4));
+	cl_assert_equal_sz(8 + 4, stream->received_bytes);
+
+	cl_git_fail(git_odb_stream_finalize_write(&oid, stream));
+}
+
+void test_odb_streamwrite__can_detect_additional_bytes(void)
+{
+	cl_git_pass(git_odb_stream_write(stream, "deadbeef", 8));
+	cl_assert_equal_sz(8, stream->received_bytes);
+
+	cl_git_fail(git_odb_stream_write(stream, "deadbeef", 7));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/clone.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/clone.c
new file mode 100755
index 0000000..e63cf55
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/clone.c
@@ -0,0 +1,625 @@
+#include "clar_libgit2.h"
+
+#include "git2/clone.h"
+#include "git2/cred_helpers.h"
+#include "remote.h"
+#include "fileops.h"
+#include "refs.h"
+
+#define LIVE_REPO_URL "http://github.com/libgit2/TestGitRepository"
+#define LIVE_EMPTYREPO_URL "http://github.com/libgit2/TestEmptyRepository"
+#define BB_REPO_URL "https://libgit3@bitbucket.org/libgit2/testgitrepository.git"
+#define BB_REPO_URL_WITH_PASS "https://libgit3:libgit3@bitbucket.org/libgit2/testgitrepository.git"
+#define BB_REPO_URL_WITH_WRONG_PASS "https://libgit3:wrong@bitbucket.org/libgit2/testgitrepository.git"
+
+#define SSH_REPO_URL "ssh://github.com/libgit2/TestGitRepository"
+
+static git_repository *g_repo;
+static git_clone_options g_options;
+
+void test_online_clone__initialize(void)
+{
+	git_checkout_options dummy_opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_fetch_options dummy_fetch = GIT_FETCH_OPTIONS_INIT;
+
+	g_repo = NULL;
+
+	memset(&g_options, 0, sizeof(git_clone_options));
+	g_options.version = GIT_CLONE_OPTIONS_VERSION;
+	g_options.checkout_opts = dummy_opts;
+	g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+	g_options.fetch_opts = dummy_fetch;
+}
+
+void test_online_clone__cleanup(void)
+{
+	if (g_repo) {
+		git_repository_free(g_repo);
+		g_repo = NULL;
+	}
+	cl_fixture_cleanup("./foo");
+}
+
+void test_online_clone__network_full(void)
+{
+	git_remote *origin;
+
+	cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options));
+	cl_assert(!git_repository_is_bare(g_repo));
+	cl_git_pass(git_remote_lookup(&origin, g_repo, "origin"));
+
+	cl_assert_equal_i(GIT_REMOTE_DOWNLOAD_TAGS_AUTO, origin->download_tags);
+
+	git_remote_free(origin);
+}
+
+void test_online_clone__network_bare(void)
+{
+	git_remote *origin;
+
+	g_options.bare = true;
+
+	cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options));
+	cl_assert(git_repository_is_bare(g_repo));
+	cl_git_pass(git_remote_lookup(&origin, g_repo, "origin"));
+
+	git_remote_free(origin);
+}
+
+void test_online_clone__empty_repository(void)
+{
+	git_reference *head;
+
+	cl_git_pass(git_clone(&g_repo, LIVE_EMPTYREPO_URL, "./foo", &g_options));
+
+	cl_assert_equal_i(true, git_repository_is_empty(g_repo));
+	cl_assert_equal_i(true, git_repository_head_unborn(g_repo));
+
+	cl_git_pass(git_reference_lookup(&head, g_repo, GIT_HEAD_FILE));
+	cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head));
+	cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));
+
+	git_reference_free(head);
+}
+
+static void checkout_progress(const char *path, size_t cur, size_t tot, void *payload)
+{
+	bool *was_called = (bool*)payload;
+	GIT_UNUSED(path); GIT_UNUSED(cur); GIT_UNUSED(tot);
+	(*was_called) = true;
+}
+
+static int fetch_progress(const git_transfer_progress *stats, void *payload)
+{
+	bool *was_called = (bool*)payload;
+	GIT_UNUSED(stats);
+	(*was_called) = true;
+	return 0;
+}
+
+void test_online_clone__can_checkout_a_cloned_repo(void)
+{
+	git_buf path = GIT_BUF_INIT;
+	git_reference *head;
+	bool checkout_progress_cb_was_called = false,
+		  fetch_progress_cb_was_called = false;
+
+	g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+	g_options.checkout_opts.progress_cb = &checkout_progress;
+	g_options.checkout_opts.progress_payload = &checkout_progress_cb_was_called;
+	g_options.fetch_opts.callbacks.transfer_progress = &fetch_progress;
+	g_options.fetch_opts.callbacks.payload = &fetch_progress_cb_was_called;
+
+	cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options));
+
+	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "master.txt"));
+	cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&path)));
+
+	cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
+	cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head));
+	cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));
+
+	cl_assert_equal_i(true, checkout_progress_cb_was_called);
+	cl_assert_equal_i(true, fetch_progress_cb_was_called);
+
+	git_reference_free(head);
+	git_buf_free(&path);
+}
+
+static int remote_mirror_cb(git_remote **out, git_repository *repo,
+			    const char *name, const char *url, void *payload)
+{
+	int error;
+	git_remote *remote;
+
+	GIT_UNUSED(payload);
+
+	if ((error = git_remote_create_with_fetchspec(&remote, repo, name, url, "+refs/*:refs/*")) < 0)
+		return error;
+
+	*out = remote;
+	return 0;
+}
+
+void test_online_clone__clone_mirror(void)
+{
+	git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
+	git_reference *head;
+
+	bool fetch_progress_cb_was_called = false;
+
+	opts.fetch_opts.callbacks.transfer_progress = &fetch_progress;
+	opts.fetch_opts.callbacks.payload = &fetch_progress_cb_was_called;
+
+	opts.bare = true;
+	opts.remote_cb = remote_mirror_cb;
+
+	cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo.git", &opts));
+
+	cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
+	cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head));
+	cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));
+
+	cl_assert_equal_i(true, fetch_progress_cb_was_called);
+
+	git_reference_free(head);
+	git_repository_free(g_repo);
+	g_repo = NULL;
+
+	cl_fixture_cleanup("./foo.git");
+}
+
+static int update_tips(const char *refname, const git_oid *a, const git_oid *b, void *payload)
+{
+	int *callcount = (int*)payload;
+	GIT_UNUSED(refname); GIT_UNUSED(a); GIT_UNUSED(b);
+	*callcount = *callcount + 1;
+	return 0;
+}
+
+void test_online_clone__custom_remote_callbacks(void)
+{
+	int callcount = 0;
+
+	g_options.fetch_opts.callbacks.update_tips = update_tips;
+	g_options.fetch_opts.callbacks.payload = &callcount;
+
+	cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options));
+	cl_assert(callcount > 0);
+}
+
+static int cred_failure_cb(
+	git_cred **cred,
+	const char *url,
+	const char *username_from_url,
+	unsigned int allowed_types,
+	void *data)
+{
+	GIT_UNUSED(cred); GIT_UNUSED(url); GIT_UNUSED(username_from_url);
+	GIT_UNUSED(allowed_types); GIT_UNUSED(data);
+	return -172;
+}
+
+void test_online_clone__cred_callback_failure_return_code_is_tunnelled(void)
+{
+	const char *remote_url = cl_getenv("GITTEST_REMOTE_URL");
+	const char *remote_user = cl_getenv("GITTEST_REMOTE_USER");
+
+	if (!remote_url || !remote_user)
+		clar__skip();
+
+	g_options.fetch_opts.callbacks.credentials = cred_failure_cb;
+
+	cl_git_fail_with(-172, git_clone(&g_repo, remote_url, "./foo", &g_options));
+}
+
+static int cred_count_calls_cb(git_cred **cred, const char *url, const char *user,
+			       unsigned int allowed_types, void *data)
+{
+	size_t *counter = (size_t *) data;
+
+	GIT_UNUSED(url); GIT_UNUSED(user); GIT_UNUSED(allowed_types);
+
+	if (allowed_types == GIT_CREDTYPE_USERNAME)
+		return git_cred_username_new(cred, "foo");
+
+	(*counter)++;
+
+	if (*counter == 3)
+		return GIT_EUSER;
+
+	return git_cred_userpass_plaintext_new(cred, "foo", "bar");
+}
+
+void test_online_clone__cred_callback_called_again_on_auth_failure(void)
+{
+	const char *remote_url = cl_getenv("GITTEST_REMOTE_URL");
+	const char *remote_user = cl_getenv("GITTEST_REMOTE_USER");
+	size_t counter = 0;
+
+	if (!remote_url || !remote_user)
+		clar__skip();
+
+	g_options.fetch_opts.callbacks.credentials = cred_count_calls_cb;
+	g_options.fetch_opts.callbacks.payload = &counter;
+
+	cl_git_fail_with(GIT_EUSER, git_clone(&g_repo, remote_url, "./foo", &g_options));
+	cl_assert_equal_i(3, counter);
+}
+
+int cred_default(
+	git_cred **cred,
+	const char *url,
+	const char *user_from_url,
+	unsigned int allowed_types,
+	void *payload)
+{
+	GIT_UNUSED(url);
+	GIT_UNUSED(user_from_url);
+	GIT_UNUSED(payload);
+
+	if (!(allowed_types & GIT_CREDTYPE_DEFAULT))
+		return 0;
+
+	return git_cred_default_new(cred);
+}
+
+void test_online_clone__credentials(void)
+{
+	/* Remote URL environment variable must be set.
+	 * User and password are optional.
+	 */
+	const char *remote_url = cl_getenv("GITTEST_REMOTE_URL");
+	git_cred_userpass_payload user_pass = {
+		cl_getenv("GITTEST_REMOTE_USER"),
+		cl_getenv("GITTEST_REMOTE_PASS")
+	};
+
+	if (!remote_url) return;
+
+	if (cl_getenv("GITTEST_REMOTE_DEFAULT")) {
+		g_options.fetch_opts.callbacks.credentials = cred_default;
+	} else {
+		g_options.fetch_opts.callbacks.credentials = git_cred_userpass;
+		g_options.fetch_opts.callbacks.payload = &user_pass;
+	}
+
+	cl_git_pass(git_clone(&g_repo, remote_url, "./foo", &g_options));
+	git_repository_free(g_repo); g_repo = NULL;
+	cl_fixture_cleanup("./foo");
+}
+
+void test_online_clone__bitbucket_style(void)
+{
+	git_cred_userpass_payload user_pass = {
+		"libgit2", "libgit2"
+	};
+
+	g_options.fetch_opts.callbacks.credentials = git_cred_userpass;
+	g_options.fetch_opts.callbacks.payload = &user_pass;
+
+	cl_git_pass(git_clone(&g_repo, BB_REPO_URL, "./foo", &g_options));
+	git_repository_free(g_repo); g_repo = NULL;
+	cl_fixture_cleanup("./foo");
+
+	/* User and pass from URL */
+	user_pass.password = "wrong";
+	cl_git_pass(git_clone(&g_repo, BB_REPO_URL_WITH_PASS, "./foo", &g_options));
+	git_repository_free(g_repo); g_repo = NULL;
+	cl_fixture_cleanup("./foo");
+
+	/* Wrong password in URL, fall back to user_pass */
+	user_pass.password = "libgit2";
+	cl_git_pass(git_clone(&g_repo, BB_REPO_URL_WITH_WRONG_PASS, "./foo", &g_options));
+	git_repository_free(g_repo); g_repo = NULL;
+	cl_fixture_cleanup("./foo");
+}
+
+static int cancel_at_half(const git_transfer_progress *stats, void *payload)
+{
+	GIT_UNUSED(payload);
+
+	if (stats->received_objects > (stats->total_objects/2))
+		return 4321;
+	return 0;
+}
+
+void test_online_clone__can_cancel(void)
+{
+	g_options.fetch_opts.callbacks.transfer_progress = cancel_at_half;
+
+	cl_git_fail_with(
+		git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options), 4321);
+}
+
+static int cred_cb(git_cred **cred, const char *url, const char *user_from_url,
+		   unsigned int allowed_types, void *payload)
+{
+	const char *remote_user = cl_getenv("GITTEST_REMOTE_USER");
+	const char *pubkey = cl_getenv("GITTEST_REMOTE_SSH_PUBKEY");
+	const char *privkey = cl_getenv("GITTEST_REMOTE_SSH_KEY");
+	const char *passphrase = cl_getenv("GITTEST_REMOTE_SSH_PASSPHRASE");
+
+	GIT_UNUSED(url); GIT_UNUSED(user_from_url); GIT_UNUSED(payload);
+
+	if (allowed_types & GIT_CREDTYPE_USERNAME)
+		return git_cred_username_new(cred, remote_user);
+
+	if (allowed_types & GIT_CREDTYPE_SSH_KEY)
+		return git_cred_ssh_key_new(cred, remote_user, pubkey, privkey, passphrase);
+
+	giterr_set(GITERR_NET, "unexpected cred type");
+	return -1;
+}
+
+static int check_ssh_auth_methods(git_cred **cred, const char *url, const char *username_from_url,
+				  unsigned int allowed_types, void *data)
+{
+	int *with_user = (int *) data;
+	GIT_UNUSED(cred); GIT_UNUSED(url); GIT_UNUSED(username_from_url); GIT_UNUSED(data);
+
+	if (!*with_user)
+		cl_assert_equal_i(GIT_CREDTYPE_USERNAME, allowed_types);
+	else
+		cl_assert(!(allowed_types & GIT_CREDTYPE_USERNAME));
+
+	return GIT_EUSER;
+}
+
+void test_online_clone__ssh_auth_methods(void)
+{
+	int with_user;
+
+#ifndef GIT_SSH
+	clar__skip();
+#endif
+	g_options.fetch_opts.callbacks.credentials = check_ssh_auth_methods;
+	g_options.fetch_opts.callbacks.payload = &with_user;
+
+	with_user = 0;
+	cl_git_fail_with(GIT_EUSER,
+		git_clone(&g_repo, SSH_REPO_URL, "./foo", &g_options));
+
+	with_user = 1;
+	cl_git_fail_with(GIT_EUSER,
+		git_clone(&g_repo, "ssh://git@github.com/libgit2/TestGitRepository", "./foo", &g_options));
+}
+
+static int custom_remote_ssh_with_paths(
+	git_remote **out,
+	git_repository *repo,
+	const char *name,
+	const char *url,
+	void *payload)
+{
+	int error;
+
+	GIT_UNUSED(payload);
+
+	if ((error = git_remote_create(out, repo, name, url)) < 0)
+		return error;
+
+	return 0;
+}
+
+void test_online_clone__ssh_with_paths(void)
+{
+	char *bad_paths[] = {
+		"/bin/yes",
+		"/bin/false",
+	};
+	char *good_paths[] = {
+		"/usr/bin/git-upload-pack",
+		"/usr/bin/git-receive-pack",
+	};
+	git_strarray arr = {
+		bad_paths,
+		2,
+	};
+
+	const char *remote_url = cl_getenv("GITTEST_REMOTE_URL");
+	const char *remote_user = cl_getenv("GITTEST_REMOTE_USER");
+
+#ifndef GIT_SSH
+	clar__skip();
+#endif
+	if (!remote_url || !remote_user || strncmp(remote_url, "ssh://", 5) != 0)
+		clar__skip();
+
+	g_options.remote_cb = custom_remote_ssh_with_paths;
+	g_options.fetch_opts.callbacks.transport = git_transport_ssh_with_paths;
+	g_options.fetch_opts.callbacks.credentials = cred_cb;
+	g_options.fetch_opts.callbacks.payload = &arr;
+
+	cl_git_fail(git_clone(&g_repo, remote_url, "./foo", &g_options));
+
+	arr.strings = good_paths;
+	cl_git_pass(git_clone(&g_repo, remote_url, "./foo", &g_options));
+}
+
+static int cred_foo_bar(git_cred **cred, const char *url, const char *username_from_url,
+				  unsigned int allowed_types, void *data)
+
+{
+	GIT_UNUSED(url); GIT_UNUSED(username_from_url); GIT_UNUSED(allowed_types); GIT_UNUSED(data);
+
+	return git_cred_userpass_plaintext_new(cred, "foo", "bar");
+}
+
+void test_online_clone__ssh_cannot_change_username(void)
+{
+#ifndef GIT_SSH
+	clar__skip();
+#endif
+	g_options.fetch_opts.callbacks.credentials = cred_foo_bar;
+
+	cl_git_fail(git_clone(&g_repo, "ssh://git@github.com/libgit2/TestGitRepository", "./foo", &g_options));
+}
+
+int ssh_certificate_check(git_cert *cert, int valid, const char *host, void *payload)
+{
+	git_cert_hostkey *key;
+	git_oid expected = {{0}}, actual = {{0}};
+	const char *expected_str;
+
+	GIT_UNUSED(valid);
+	GIT_UNUSED(payload);
+
+	expected_str = cl_getenv("GITTEST_REMOTE_SSH_FINGERPRINT");
+	cl_assert(expected_str);
+
+	cl_git_pass(git_oid_fromstrp(&expected, expected_str));
+	cl_assert_equal_i(GIT_CERT_HOSTKEY_LIBSSH2, cert->cert_type);
+	key = (git_cert_hostkey *) cert;
+
+	/*
+	 * We need to figure out how long our input was to check for
+	 * the type. Here we abuse the fact that both hashes fit into
+	 * our git_oid type.
+	 */
+	if (strlen(expected_str) == 32 && key->type & GIT_CERT_SSH_MD5) {
+		memcpy(&actual.id, key->hash_md5, 16);
+	} else 	if (strlen(expected_str) == 40 && key->type & GIT_CERT_SSH_SHA1) {
+		memcpy(&actual, key->hash_sha1, 20);
+	} else {
+		cl_fail("Cannot find a usable SSH hash");
+	}
+
+	cl_assert(!memcmp(&expected, &actual, 20));
+
+	cl_assert_equal_s("localhost", host);
+
+	return GIT_EUSER;
+}
+
+void test_online_clone__ssh_cert(void)
+{
+	g_options.fetch_opts.callbacks.certificate_check = ssh_certificate_check;
+
+	if (!cl_getenv("GITTEST_REMOTE_SSH_FINGERPRINT"))
+		cl_skip();
+
+	cl_git_fail_with(GIT_EUSER, git_clone(&g_repo, "ssh://localhost/foo", "./foo", &g_options));
+}
+
+static char *read_key_file(const char *path)
+{
+	FILE *f;
+	char *buf;
+	long key_length;
+
+	if (!path || !*path)
+		return NULL;
+
+	cl_assert((f = fopen(path, "r")) != NULL);
+	cl_assert(fseek(f, 0, SEEK_END) != -1);
+	cl_assert((key_length = ftell(f)) != -1);
+	cl_assert(fseek(f, 0, SEEK_SET) != -1);
+	cl_assert((buf = malloc(key_length)) != NULL);
+	cl_assert(fread(buf, key_length, 1, f) == 1);
+	fclose(f);
+
+	return buf;
+}
+
+static int ssh_memory_cred_cb(git_cred **cred, const char *url, const char *user_from_url,
+		   unsigned int allowed_types, void *payload)
+{
+	const char *remote_user = cl_getenv("GITTEST_REMOTE_USER");
+	const char *pubkey_path = cl_getenv("GITTEST_REMOTE_SSH_PUBKEY");
+	const char *privkey_path = cl_getenv("GITTEST_REMOTE_SSH_KEY");
+	const char *passphrase = cl_getenv("GITTEST_REMOTE_SSH_PASSPHRASE");
+
+	GIT_UNUSED(url); GIT_UNUSED(user_from_url); GIT_UNUSED(payload);
+
+	if (allowed_types & GIT_CREDTYPE_USERNAME)
+		return git_cred_username_new(cred, remote_user);
+
+	if (allowed_types & GIT_CREDTYPE_SSH_KEY)
+	{
+		char *pubkey = read_key_file(pubkey_path);
+		char *privkey = read_key_file(privkey_path);
+
+		int ret = git_cred_ssh_key_memory_new(cred, remote_user, pubkey, privkey, passphrase);
+
+		if (privkey)
+			free(privkey);
+		if (pubkey)
+			free(pubkey);
+		return ret;
+	}
+
+	giterr_set(GITERR_NET, "unexpected cred type");
+	return -1;
+}
+
+void test_online_clone__ssh_memory_auth(void)
+{
+	const char *remote_url = cl_getenv("GITTEST_REMOTE_URL");
+	const char *remote_user = cl_getenv("GITTEST_REMOTE_USER");
+	const char *privkey = cl_getenv("GITTEST_REMOTE_SSH_KEY");
+
+#ifndef GIT_SSH_MEMORY_CREDENTIALS
+	clar__skip();
+#endif
+	if (!remote_url || !remote_user || !privkey || strncmp(remote_url, "ssh://", 5) != 0)
+		clar__skip();
+
+	g_options.fetch_opts.callbacks.credentials = ssh_memory_cred_cb;
+
+	cl_git_pass(git_clone(&g_repo, remote_url, "./foo", &g_options));
+}
+
+void test_online_clone__url_with_no_path_returns_EINVALIDSPEC(void)
+{
+	cl_git_fail_with(git_clone(&g_repo, "http://github.com", "./foo", &g_options),
+		GIT_EINVALIDSPEC);
+}
+
+static int fail_certificate_check(git_cert *cert, int valid, const char *host, void *payload)
+{
+	GIT_UNUSED(cert);
+	GIT_UNUSED(valid);
+	GIT_UNUSED(host);
+	GIT_UNUSED(payload);
+
+	return GIT_ECERTIFICATE;
+}
+
+void test_online_clone__certificate_invalid(void)
+{
+	g_options.fetch_opts.callbacks.certificate_check = fail_certificate_check;
+
+	cl_git_fail_with(git_clone(&g_repo, "https://github.com/libgit2/TestGitRepository", "./foo", &g_options),
+		GIT_ECERTIFICATE);
+
+#ifdef GIT_SSH
+	cl_git_fail_with(git_clone(&g_repo, "ssh://github.com/libgit2/TestGitRepository", "./foo", &g_options),
+		GIT_ECERTIFICATE);
+#endif
+}
+
+static int succeed_certificate_check(git_cert *cert, int valid, const char *host, void *payload)
+{
+	GIT_UNUSED(cert);
+	GIT_UNUSED(valid);
+	GIT_UNUSED(payload);
+
+	cl_assert_equal_s("github.com", host);
+
+	return 0;
+}
+
+void test_online_clone__certificate_valid(void)
+{
+	g_options.fetch_opts.callbacks.certificate_check = succeed_certificate_check;
+
+	cl_git_pass(git_clone(&g_repo, "https://github.com/libgit2/TestGitRepository", "./foo", &g_options));
+}
+
+void test_online_clone__start_with_http(void)
+{
+	g_options.fetch_opts.callbacks.certificate_check = succeed_certificate_check;
+
+	cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/TestGitRepository", "./foo", &g_options));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/fetch.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/fetch.c
new file mode 100755
index 0000000..72e7c24
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/fetch.c
@@ -0,0 +1,209 @@
+#include "clar_libgit2.h"
+
+static git_repository *_repo;
+static int counter;
+
+void test_online_fetch__initialize(void)
+{
+	cl_git_pass(git_repository_init(&_repo, "./fetch", 0));
+}
+
+void test_online_fetch__cleanup(void)
+{
+	git_repository_free(_repo);
+	_repo = NULL;
+
+	cl_fixture_cleanup("./fetch");
+}
+
+static int update_tips(const char *refname, const git_oid *a, const git_oid *b, void *data)
+{
+	GIT_UNUSED(refname); GIT_UNUSED(a); GIT_UNUSED(b); GIT_UNUSED(data);
+
+	++counter;
+
+	return 0;
+}
+
+static int progress(const git_transfer_progress *stats, void *payload)
+{
+	size_t *bytes_received = (size_t *)payload;
+	*bytes_received = stats->received_bytes;
+	return 0;
+}
+
+static void do_fetch(const char *url, git_remote_autotag_option_t flag, int n)
+{
+	git_remote *remote;
+	git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
+	size_t bytes_received = 0;
+
+	options.callbacks.transfer_progress = progress;
+	options.callbacks.update_tips = update_tips;
+	options.callbacks.payload = &bytes_received;
+	options.download_tags = flag;
+	counter = 0;
+
+	cl_git_pass(git_remote_create(&remote, _repo, "test", url));
+	cl_git_pass(git_remote_fetch(remote, NULL, &options, NULL));
+	cl_assert_equal_i(counter, n);
+	cl_assert(bytes_received > 0);
+
+	git_remote_free(remote);
+}
+
+void test_online_fetch__default_git(void)
+{
+	do_fetch("git://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 6);
+}
+
+void test_online_fetch__default_http(void)
+{
+	do_fetch("http://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 6);
+}
+
+void test_online_fetch__default_https(void)
+{
+	do_fetch("https://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 6);
+}
+
+void test_online_fetch__no_tags_git(void)
+{
+	do_fetch("git://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_NONE, 3);
+}
+
+void test_online_fetch__no_tags_http(void)
+{
+	do_fetch("http://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_NONE, 3);
+}
+
+void test_online_fetch__fetch_twice(void)
+{
+	git_remote *remote;
+	cl_git_pass(git_remote_create(&remote, _repo, "test", "git://github.com/libgit2/TestGitRepository.git"));
+	cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL));
+	cl_git_pass(git_remote_download(remote, NULL, NULL));
+    	git_remote_disconnect(remote);
+    	
+	git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL);
+	cl_git_pass(git_remote_download(remote, NULL, NULL));
+	git_remote_disconnect(remote);
+	
+	git_remote_free(remote);
+}
+
+static int transferProgressCallback(const git_transfer_progress *stats, void *payload)
+{
+	bool *invoked = (bool *)payload;
+
+	GIT_UNUSED(stats);
+	*invoked = true;
+	return 0;
+}
+
+void test_online_fetch__doesnt_retrieve_a_pack_when_the_repository_is_up_to_date(void)
+{
+	git_repository *_repository;
+	bool invoked = false;
+	git_remote *remote;
+	git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
+	git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
+	opts.bare = true;
+
+	cl_git_pass(git_clone(&_repository, "https://github.com/libgit2/TestGitRepository.git",
+				"./fetch/lg2", &opts));
+	git_repository_free(_repository);
+
+	cl_git_pass(git_repository_open(&_repository, "./fetch/lg2"));
+
+	cl_git_pass(git_remote_lookup(&remote, _repository, "origin"));
+	cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL));
+
+	cl_assert_equal_i(false, invoked);
+
+	options.callbacks.transfer_progress = &transferProgressCallback;
+	options.callbacks.payload = &invoked;
+	cl_git_pass(git_remote_download(remote, NULL, &options));
+
+	cl_assert_equal_i(false, invoked);
+
+	cl_git_pass(git_remote_update_tips(remote, &options.callbacks, 1, options.download_tags, NULL));
+	git_remote_disconnect(remote);
+
+	git_remote_free(remote);
+	git_repository_free(_repository);
+}
+
+static int cancel_at_half(const git_transfer_progress *stats, void *payload)
+{
+	GIT_UNUSED(payload);
+
+	if (stats->received_objects > (stats->total_objects/2))
+		return -4321;
+	return 0;
+}
+
+void test_online_fetch__can_cancel(void)
+{
+	git_remote *remote;
+	size_t bytes_received = 0;
+	git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
+
+	cl_git_pass(git_remote_create(&remote, _repo, "test",
+				"http://github.com/libgit2/TestGitRepository.git"));
+
+	options.callbacks.transfer_progress = cancel_at_half;
+	options.callbacks.payload = &bytes_received;
+
+	cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL));
+	cl_git_fail_with(git_remote_download(remote, NULL, &options), -4321);
+	git_remote_disconnect(remote);
+	git_remote_free(remote);
+}
+
+void test_online_fetch__ls_disconnected(void)
+{
+	const git_remote_head **refs;
+	size_t refs_len_before, refs_len_after;
+	git_remote *remote;
+
+	cl_git_pass(git_remote_create(&remote, _repo, "test",
+				"http://github.com/libgit2/TestGitRepository.git"));
+	cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL));
+	cl_git_pass(git_remote_ls(&refs, &refs_len_before, remote));
+	git_remote_disconnect(remote);
+	cl_git_pass(git_remote_ls(&refs, &refs_len_after, remote));
+
+	cl_assert_equal_i(refs_len_before, refs_len_after);
+
+	git_remote_free(remote);
+}
+
+void test_online_fetch__remote_symrefs(void)
+{
+	const git_remote_head **refs;
+	size_t refs_len;
+	git_remote *remote;
+
+	cl_git_pass(git_remote_create(&remote, _repo, "test",
+				"http://github.com/libgit2/TestGitRepository.git"));
+	cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL));
+	git_remote_disconnect(remote);
+	cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
+
+	cl_assert_equal_s("HEAD", refs[0]->name);
+	cl_assert_equal_s("refs/heads/master", refs[0]->symref_target);
+
+	git_remote_free(remote);
+}
+
+void test_online_fetch__twice(void)
+{
+	git_remote *remote;
+
+	cl_git_pass(git_remote_create(&remote, _repo, "test", "http://github.com/libgit2/TestGitRepository.git"));
+	cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL));
+	cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL));
+
+	git_remote_free(remote);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/fetchhead.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/fetchhead.c
new file mode 100755
index 0000000..200edac
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/fetchhead.c
@@ -0,0 +1,103 @@
+#include "clar_libgit2.h"
+
+#include "fileops.h"
+#include "fetchhead.h"
+#include "../fetchhead/fetchhead_data.h"
+#include "git2/clone.h"
+
+#define LIVE_REPO_URL "git://github.com/libgit2/TestGitRepository"
+
+static git_repository *g_repo;
+static git_clone_options g_options;
+
+void test_online_fetchhead__initialize(void)
+{
+	git_fetch_options dummy_fetch = GIT_FETCH_OPTIONS_INIT;
+	g_repo = NULL;
+
+	memset(&g_options, 0, sizeof(git_clone_options));
+	g_options.version = GIT_CLONE_OPTIONS_VERSION;
+	g_options.fetch_opts = dummy_fetch;
+}
+
+void test_online_fetchhead__cleanup(void)
+{
+	if (g_repo) {
+		git_repository_free(g_repo);
+		g_repo = NULL;
+	}
+
+	cl_fixture_cleanup("./foo");
+}
+
+static void fetchhead_test_clone(void)
+{
+	cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options));
+}
+
+static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fetchhead)
+{
+	git_remote *remote;
+	git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
+	git_buf fetchhead_buf = GIT_BUF_INIT;
+	int equals = 0;
+	git_strarray array, *active_refs = NULL;
+
+	cl_git_pass(git_remote_lookup(&remote, g_repo, "origin"));
+	fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO;
+
+	if(fetchspec != NULL) {
+		array.count = 1;
+		array.strings = (char **) &fetchspec;
+		active_refs = &array;
+	}
+
+	cl_git_pass(git_remote_fetch(remote, active_refs, &fetch_opts, NULL));
+	git_remote_free(remote);
+
+	cl_git_pass(git_futils_readbuffer(&fetchhead_buf, "./foo/.git/FETCH_HEAD"));
+
+	equals = (strcmp(fetchhead_buf.ptr, expected_fetchhead) == 0);
+
+	git_buf_free(&fetchhead_buf);
+
+	cl_assert(equals);
+}
+
+void test_online_fetchhead__wildcard_spec(void)
+{
+	fetchhead_test_clone();
+	fetchhead_test_fetch(NULL, FETCH_HEAD_WILDCARD_DATA2);
+	cl_git_pass(git_tag_delete(g_repo, "annotated_tag"));
+	cl_git_pass(git_tag_delete(g_repo, "blob"));
+	cl_git_pass(git_tag_delete(g_repo, "commit_tree"));
+	cl_git_pass(git_tag_delete(g_repo, "nearly-dangling"));
+	fetchhead_test_fetch(NULL, FETCH_HEAD_WILDCARD_DATA);
+}
+
+void test_online_fetchhead__explicit_spec(void)
+{
+	fetchhead_test_clone();
+	fetchhead_test_fetch("refs/heads/first-merge:refs/remotes/origin/first-merge", FETCH_HEAD_EXPLICIT_DATA);
+}
+
+void test_online_fetchhead__no_merges(void)
+{
+	git_config *config;
+
+	fetchhead_test_clone();
+
+	cl_git_pass(git_repository_config(&config, g_repo));
+	cl_git_pass(git_config_delete_entry(config, "branch.master.remote"));
+	cl_git_pass(git_config_delete_entry(config, "branch.master.merge"));
+	git_config_free(config);
+
+	fetchhead_test_fetch(NULL, FETCH_HEAD_NO_MERGE_DATA2);
+	cl_git_pass(git_tag_delete(g_repo, "annotated_tag"));
+	cl_git_pass(git_tag_delete(g_repo, "blob"));
+	cl_git_pass(git_tag_delete(g_repo, "commit_tree"));
+	cl_git_pass(git_tag_delete(g_repo, "nearly-dangling"));
+	fetchhead_test_fetch(NULL, FETCH_HEAD_NO_MERGE_DATA);
+	cl_git_pass(git_tag_delete(g_repo, "commit_tree"));
+	fetchhead_test_fetch(NULL, FETCH_HEAD_NO_MERGE_DATA3);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/push.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/push.c
new file mode 100755
index 0000000..6cd4443
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/push.c
@@ -0,0 +1,898 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "posix.h"
+#include "vector.h"
+#include "../submodule/submodule_helpers.h"
+#include "push_util.h"
+#include "refspec.h"
+#include "remote.h"
+
+static git_repository *_repo;
+
+static char *_remote_url;
+
+static char *_remote_ssh_key;
+static char *_remote_ssh_pubkey;
+static char *_remote_ssh_passphrase;
+
+static char *_remote_user;
+static char *_remote_pass;
+
+static char *_remote_default;
+
+static int cred_acquire_cb(git_cred **,	const char *, const char *, unsigned int, void *);
+
+static git_remote *_remote;
+static record_callbacks_data _record_cbs_data = {{ 0 }};
+static git_remote_callbacks _record_cbs = RECORD_CALLBACKS_INIT(&_record_cbs_data);
+
+static git_oid _oid_b6;
+static git_oid _oid_b5;
+static git_oid _oid_b4;
+static git_oid _oid_b3;
+static git_oid _oid_b2;
+static git_oid _oid_b1;
+
+static git_oid _tag_commit;
+static git_oid _tag_tree;
+static git_oid _tag_blob;
+static git_oid _tag_lightweight;
+static git_oid _tag_tag;
+
+static int cred_acquire_cb(
+	git_cred **cred,
+	const char *url,
+	const char *user_from_url,
+	unsigned int allowed_types,
+	void *payload)
+{
+	GIT_UNUSED(url);
+	GIT_UNUSED(user_from_url);
+	GIT_UNUSED(payload);
+
+	if (GIT_CREDTYPE_USERNAME & allowed_types) {
+		if (!_remote_user) {
+			printf("GITTEST_REMOTE_USER must be set\n");
+			return -1;
+		}
+
+		return git_cred_username_new(cred, _remote_user);
+	}
+
+	if (GIT_CREDTYPE_DEFAULT & allowed_types) {
+		if (!_remote_default) {
+			printf("GITTEST_REMOTE_DEFAULT must be set to use NTLM/Negotiate credentials\n");
+			return -1;
+		}
+
+		return git_cred_default_new(cred);
+	}
+
+	if (GIT_CREDTYPE_SSH_KEY & allowed_types) {
+		if (!_remote_user || !_remote_ssh_pubkey || !_remote_ssh_key || !_remote_ssh_passphrase) {
+			printf("GITTEST_REMOTE_USER, GITTEST_REMOTE_SSH_PUBKEY, GITTEST_REMOTE_SSH_KEY and GITTEST_REMOTE_SSH_PASSPHRASE must be set\n");
+			return -1;
+		}
+
+		return git_cred_ssh_key_new(cred, _remote_user, _remote_ssh_pubkey, _remote_ssh_key, _remote_ssh_passphrase);
+	}
+
+	if (GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) {
+		if (!_remote_user || !_remote_pass) {
+			printf("GITTEST_REMOTE_USER and GITTEST_REMOTE_PASS must be set\n");
+			return -1;
+		}
+
+		return git_cred_userpass_plaintext_new(cred, _remote_user, _remote_pass);
+	}
+
+	return -1;
+}
+
+/**
+ * git_push_status_foreach callback that records status entries.
+ * @param data (git_vector *) of push_status instances
+ */
+static int record_push_status_cb(const char *ref, const char *msg, void *payload)
+{
+	record_callbacks_data *data = (record_callbacks_data *) payload;
+	push_status *s;
+
+	cl_assert(s = git__calloc(1, sizeof(*s)));
+	if (ref)
+		cl_assert(s->ref = git__strdup(ref));
+	s->success = (msg == NULL);
+	if (msg)
+		cl_assert(s->msg = git__strdup(msg));
+
+	git_vector_insert(&data->statuses, s);
+
+	return 0;
+}
+
+static void do_verify_push_status(record_callbacks_data *data, const push_status expected[], const size_t expected_len)
+{
+	git_vector *actual = &data->statuses;
+	push_status *iter;
+	bool failed = false;
+	size_t i;
+
+	if (expected_len != actual->length)
+		failed = true;
+	else
+		git_vector_foreach(actual, i, iter)
+			if (strcmp(expected[i].ref, iter->ref) ||
+				(expected[i].success != iter->success) ||
+				(expected[i].msg && (!iter->msg || strcmp(expected[i].msg, iter->msg)))) {
+				failed = true;
+				break;
+			}
+
+	if (failed) {
+		git_buf msg = GIT_BUF_INIT;
+
+		git_buf_puts(&msg, "Expected and actual push statuses differ:\nEXPECTED:\n");
+
+		for(i = 0; i < expected_len; i++) {
+			git_buf_printf(&msg, "%s: %s\n",
+				expected[i].ref,
+				expected[i].success ? "success" : "failed");
+		}
+
+		git_buf_puts(&msg, "\nACTUAL:\n");
+
+		git_vector_foreach(actual, i, iter) {
+			if (iter->success)
+				git_buf_printf(&msg, "%s: success\n", iter->ref);
+			else
+				git_buf_printf(&msg, "%s: failed with message: %s", iter->ref, iter->msg);
+		}
+
+		cl_fail(git_buf_cstr(&msg));
+
+		git_buf_free(&msg);
+	}
+
+	git_vector_foreach(actual, i, iter)
+		git__free(iter);
+
+	git_vector_free(actual);
+}
+
+/**
+ * Verifies that after git_push_finish(), refs on a remote have the expected
+ * names, oids, and order.
+ *
+ * @param remote remote to verify
+ * @param expected_refs expected remote refs after push
+ * @param expected_refs_len length of expected_refs
+ */
+static void verify_refs(git_remote *remote, expected_ref expected_refs[], size_t expected_refs_len)
+{
+	const git_remote_head **actual_refs;
+	size_t actual_refs_len;
+
+	git_remote_ls(&actual_refs, &actual_refs_len, remote);
+	verify_remote_refs(actual_refs, actual_refs_len, expected_refs, expected_refs_len);
+}
+
+/**
+ * Verifies that after git_push_update_tips(), remote tracking branches have the expected
+ * names and oids.
+ *
+ * @param remote remote to verify
+ * @param expected_refs expected remote refs after push
+ * @param expected_refs_len length of expected_refs
+ */
+static void verify_tracking_branches(git_remote *remote, expected_ref expected_refs[], size_t expected_refs_len)
+{
+	git_refspec *fetch_spec;
+	size_t i, j;
+	git_buf msg = GIT_BUF_INIT;
+	git_buf ref_name = GIT_BUF_INIT;
+	git_vector actual_refs = GIT_VECTOR_INIT;
+	git_branch_iterator *iter;
+	char *actual_ref;
+	git_oid oid;
+	int failed = 0, error;
+	git_branch_t branch_type;
+	git_reference *ref;
+
+	/* Get current remote-tracking branches */
+	cl_git_pass(git_branch_iterator_new(&iter, remote->repo, GIT_BRANCH_REMOTE));
+
+	while ((error = git_branch_next(&ref, &branch_type, iter)) == 0) {
+		cl_assert_equal_i(branch_type, GIT_BRANCH_REMOTE);
+
+		cl_git_pass(git_vector_insert(&actual_refs, git__strdup(git_reference_name(ref))));
+
+		git_reference_free(ref);
+	}
+
+	cl_assert_equal_i(error, GIT_ITEROVER);
+	git_branch_iterator_free(iter);
+
+	/* Loop through expected refs, make sure they exist */
+	for (i = 0; i < expected_refs_len; i++) {
+
+		/* Convert remote reference name into remote-tracking branch name.
+		 * If the spec is not under refs/heads/, then skip.
+		 */
+		fetch_spec = git_remote__matching_refspec(remote, expected_refs[i].name);
+		if (!fetch_spec)
+			continue;
+
+		cl_git_pass(git_refspec_transform(&ref_name, fetch_spec, expected_refs[i].name));
+
+		/* Find matching remote branch */
+		git_vector_foreach(&actual_refs, j, actual_ref) {
+			if (!strcmp(git_buf_cstr(&ref_name), actual_ref))
+				break;
+		}
+
+		if (j == actual_refs.length) {
+			git_buf_printf(&msg, "Did not find expected tracking branch '%s'.", git_buf_cstr(&ref_name));
+			failed = 1;
+			goto failed;
+		}
+
+		/* Make sure tracking branch is at expected commit ID */
+		cl_git_pass(git_reference_name_to_id(&oid, remote->repo, actual_ref));
+
+		if (git_oid_cmp(expected_refs[i].oid, &oid) != 0) {
+			git_buf_puts(&msg, "Tracking branch commit does not match expected ID.");
+			failed = 1;
+			goto failed;
+		}
+
+		git__free(actual_ref);
+		cl_git_pass(git_vector_remove(&actual_refs, j));
+	}
+
+	/* Make sure there are no extra branches */
+	if (actual_refs.length > 0) {
+		git_buf_puts(&msg, "Unexpected remote tracking branches exist.");
+		failed = 1;
+		goto failed;
+	}
+
+failed:
+	if (failed)
+		cl_fail(git_buf_cstr(&msg));
+
+	git_vector_foreach(&actual_refs, i, actual_ref)
+		git__free(actual_ref);
+
+	git_vector_free(&actual_refs);
+	git_buf_free(&msg);
+	git_buf_free(&ref_name);
+}
+
+static void verify_update_tips_callback(git_remote *remote, expected_ref expected_refs[], size_t expected_refs_len)
+{
+	git_refspec *fetch_spec;
+	git_buf msg = GIT_BUF_INIT;
+	git_buf ref_name = GIT_BUF_INIT;
+	updated_tip *tip = NULL;
+	size_t i, j;
+	int failed = 0;
+
+	for (i = 0; i < expected_refs_len; ++i) {
+		/* Convert remote reference name into tracking branch name.
+		 * If the spec is not under refs/heads/, then skip.
+		 */
+		fetch_spec = git_remote__matching_refspec(remote, expected_refs[i].name);
+		if (!fetch_spec)
+			continue;
+
+		cl_git_pass(git_refspec_transform(&ref_name, fetch_spec, expected_refs[i].name));
+
+		/* Find matching update_tip entry */
+		git_vector_foreach(&_record_cbs_data.updated_tips, j, tip) {
+			if (!strcmp(git_buf_cstr(&ref_name), tip->name))
+				break;
+		}
+
+		if (j == _record_cbs_data.updated_tips.length) {
+			git_buf_printf(&msg, "Did not find expected updated tip entry for branch '%s'.", git_buf_cstr(&ref_name));
+			failed = 1;
+			goto failed;
+		}
+
+		if (git_oid_cmp(expected_refs[i].oid, tip->new_oid) != 0) {
+			git_buf_printf(&msg, "Updated tip ID does not match expected ID");
+			failed = 1;
+			goto failed;
+		}
+	}
+
+failed:
+	if (failed)
+		cl_fail(git_buf_cstr(&msg));
+
+	git_buf_free(&ref_name);
+	git_buf_free(&msg);
+}
+
+void test_online_push__initialize(void)
+{
+	git_vector delete_specs = GIT_VECTOR_INIT;
+	const git_remote_head **heads;
+	size_t heads_len;
+	git_push_options push_opts = GIT_PUSH_OPTIONS_INIT;
+	git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
+
+	_repo = cl_git_sandbox_init("push_src");
+
+	cl_git_pass(git_repository_set_ident(_repo, "Random J. Hacker", "foo at example.com"));
+	cl_fixture_sandbox("testrepo.git");
+	cl_rename("push_src/submodule/.gitted", "push_src/submodule/.git");
+
+	rewrite_gitmodules(git_repository_workdir(_repo));
+
+	/* git log --format=oneline --decorate --graph
+	 * *-.   951bbbb90e2259a4c8950db78946784fb53fcbce (HEAD, b6) merge b3, b4, and b5 to b6
+	 * |\ \
+	 * | | * fa38b91f199934685819bea316186d8b008c52a2 (b5) added submodule named 'submodule' pointing to '../testrepo.git'
+	 * | * | 27b7ce66243eb1403862d05f958c002312df173d (b4) edited fold\b.txt
+	 * | |/
+	 * * | d9b63a88223d8367516f50bd131a5f7349b7f3e4 (b3) edited a.txt
+	 * |/
+	 * * a78705c3b2725f931d3ee05348d83cc26700f247 (b2, b1) added fold and fold/b.txt
+	 * * 5c0bb3d1b9449d1cc69d7519fd05166f01840915 added a.txt
+	 */
+	git_oid_fromstr(&_oid_b6, "951bbbb90e2259a4c8950db78946784fb53fcbce");
+	git_oid_fromstr(&_oid_b5, "fa38b91f199934685819bea316186d8b008c52a2");
+	git_oid_fromstr(&_oid_b4, "27b7ce66243eb1403862d05f958c002312df173d");
+	git_oid_fromstr(&_oid_b3, "d9b63a88223d8367516f50bd131a5f7349b7f3e4");
+	git_oid_fromstr(&_oid_b2, "a78705c3b2725f931d3ee05348d83cc26700f247");
+	git_oid_fromstr(&_oid_b1, "a78705c3b2725f931d3ee05348d83cc26700f247");
+
+	git_oid_fromstr(&_tag_commit, "805c54522e614f29f70d2413a0470247d8b424ac");
+	git_oid_fromstr(&_tag_tree, "ff83aa4c5e5d28e3bcba2f5c6e2adc61286a4e5e");
+	git_oid_fromstr(&_tag_blob, "b483ae7ba66decee9aee971f501221dea84b1498");
+	git_oid_fromstr(&_tag_lightweight, "951bbbb90e2259a4c8950db78946784fb53fcbce");
+	git_oid_fromstr(&_tag_tag, "eea4f2705eeec2db3813f2430829afce99cd00b5");
+
+	/* Remote URL environment variable must be set.  User and password are optional.  */
+	_remote_url = cl_getenv("GITTEST_REMOTE_URL");
+	_remote_user = cl_getenv("GITTEST_REMOTE_USER");
+	_remote_pass = cl_getenv("GITTEST_REMOTE_PASS");
+	_remote_ssh_key = cl_getenv("GITTEST_REMOTE_SSH_KEY");
+	_remote_ssh_pubkey = cl_getenv("GITTEST_REMOTE_SSH_PUBKEY");
+	_remote_ssh_passphrase = cl_getenv("GITTEST_REMOTE_SSH_PASSPHRASE");
+	_remote_default = cl_getenv("GITTEST_REMOTE_DEFAULT");
+	_remote = NULL;
+
+	/* Skip the test if we're missing the remote URL */
+	if (!_remote_url)
+		cl_skip();
+
+	cl_git_pass(git_remote_create(&_remote, _repo, "test", _remote_url));
+
+	record_callbacks_data_clear(&_record_cbs_data);
+
+	cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH, &_record_cbs));
+
+	/* Clean up previously pushed branches.  Fails if receive.denyDeletes is
+	 * set on the remote.  Also, on Git 1.7.0 and newer, you must run
+	 * 'git config receive.denyDeleteCurrent ignore' in the remote repo in
+	 * order to delete the remote branch pointed to by HEAD (usually master).
+	 * See: https://raw.github.com/git/git/master/Documentation/RelNotes/1.7.0.txt
+	 */
+	cl_git_pass(git_remote_ls(&heads, &heads_len, _remote));
+	cl_git_pass(create_deletion_refspecs(&delete_specs, heads, heads_len));
+	if (delete_specs.length) {
+		git_strarray arr = {
+			(char **) delete_specs.contents,
+			delete_specs.length,
+		};
+
+		memcpy(&push_opts.callbacks, &_record_cbs, sizeof(git_remote_callbacks));
+		cl_git_pass(git_remote_upload(_remote, &arr, &push_opts));
+	}
+
+	git_remote_disconnect(_remote);
+	git_vector_free(&delete_specs);
+
+	/* Now that we've deleted everything, fetch from the remote */
+	memcpy(&fetch_opts.callbacks, &_record_cbs, sizeof(git_remote_callbacks));
+	cl_git_pass(git_remote_fetch(_remote, NULL, &fetch_opts, NULL));
+}
+
+void test_online_push__cleanup(void)
+{
+	if (_remote)
+		git_remote_free(_remote);
+	_remote = NULL;
+
+	/* Freed by cl_git_sandbox_cleanup */
+	_repo = NULL;
+
+	record_callbacks_data_clear(&_record_cbs_data);
+
+	cl_fixture_cleanup("testrepo.git");
+	cl_git_sandbox_cleanup();
+}
+
+static int push_pack_progress_cb(
+	int stage, unsigned int current, unsigned int total, void* payload)
+{
+	record_callbacks_data *data = (record_callbacks_data *) payload;
+	GIT_UNUSED(stage); GIT_UNUSED(current); GIT_UNUSED(total);
+	if (data->pack_progress_calls < 0)
+		return data->pack_progress_calls;
+
+	data->pack_progress_calls++;
+	return 0;
+}
+
+static int push_transfer_progress_cb(
+	unsigned int current, unsigned int total, size_t bytes, void* payload)
+{
+	record_callbacks_data *data = (record_callbacks_data *) payload;
+	GIT_UNUSED(current); GIT_UNUSED(total); GIT_UNUSED(bytes);
+	if (data->transfer_progress_calls < 0)
+		return data->transfer_progress_calls;
+
+	data->transfer_progress_calls++;
+	return 0;
+}
+
+/**
+ * Calls push and relists refs on remote to verify success.
+ *
+ * @param refspecs refspecs to push
+ * @param refspecs_len length of refspecs
+ * @param expected_refs expected remote refs after push
+ * @param expected_refs_len length of expected_refs
+ * @param expected_ret expected return value from git_push_finish()
+ * @param check_progress_cb Check that the push progress callbacks are called
+ */
+static void do_push(
+	const char *refspecs[], size_t refspecs_len,
+	push_status expected_statuses[], size_t expected_statuses_len,
+	expected_ref expected_refs[], size_t expected_refs_len,
+	int expected_ret, int check_progress_cb, int check_update_tips_cb)
+{
+	git_push_options opts = GIT_PUSH_OPTIONS_INIT;
+	size_t i;
+	int error;
+	git_strarray specs = {0};
+	record_callbacks_data *data;
+
+	if (_remote) {
+		/* Auto-detect the number of threads to use */
+		opts.pb_parallelism = 0;
+
+		memcpy(&opts.callbacks, &_record_cbs, sizeof(git_remote_callbacks));
+		data = opts.callbacks.payload;
+
+		opts.callbacks.pack_progress = push_pack_progress_cb;
+		opts.callbacks.push_transfer_progress = push_transfer_progress_cb;
+		opts.callbacks.push_update_reference = record_push_status_cb;
+
+		if (refspecs_len) {
+			specs.count = refspecs_len;
+			specs.strings = git__calloc(refspecs_len, sizeof(char *));
+			cl_assert(specs.strings);
+		}
+
+		for (i = 0; i < refspecs_len; i++)
+			specs.strings[i] = (char *) refspecs[i];
+
+		/* if EUSER, then abort in transfer */
+		if (check_progress_cb && expected_ret == GIT_EUSER)
+			data->transfer_progress_calls = GIT_EUSER;
+
+		error = git_remote_push(_remote, &specs, &opts);
+		git__free(specs.strings);
+
+		if (expected_ret < 0) {
+			cl_git_fail_with(expected_ret, error);
+		} else {
+			cl_git_pass(error);
+		}
+
+		if (check_progress_cb && expected_ret == 0) {
+			cl_assert(data->pack_progress_calls > 0);
+			cl_assert(data->transfer_progress_calls > 0);
+		}
+
+		do_verify_push_status(data, expected_statuses, expected_statuses_len);
+
+		verify_refs(_remote, expected_refs, expected_refs_len);
+		verify_tracking_branches(_remote, expected_refs, expected_refs_len);
+
+		if (check_update_tips_cb)
+			verify_update_tips_callback(_remote, expected_refs, expected_refs_len);
+
+	}
+
+}
+
+/* Call push_finish() without ever calling git_push_add_refspec() */
+void test_online_push__noop(void)
+{
+	do_push(NULL, 0, NULL, 0, NULL, 0, 0, 0, 1);
+}
+
+void test_online_push__b1(void)
+{
+	const char *specs[] = { "refs/heads/b1:refs/heads/b1" };
+	push_status exp_stats[] = { { "refs/heads/b1", 1 } };
+	expected_ref exp_refs[] = { { "refs/heads/b1", &_oid_b1 } };
+	do_push(specs, ARRAY_SIZE(specs),
+		exp_stats, ARRAY_SIZE(exp_stats),
+		exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
+}
+
+void test_online_push__b2(void)
+{
+	const char *specs[] = { "refs/heads/b2:refs/heads/b2" };
+	push_status exp_stats[] = { { "refs/heads/b2", 1 } };
+	expected_ref exp_refs[] = { { "refs/heads/b2", &_oid_b2 } };
+	do_push(specs, ARRAY_SIZE(specs),
+		exp_stats, ARRAY_SIZE(exp_stats),
+		exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
+}
+
+void test_online_push__b3(void)
+{
+	const char *specs[] = { "refs/heads/b3:refs/heads/b3" };
+	push_status exp_stats[] = { { "refs/heads/b3", 1 } };
+	expected_ref exp_refs[] = { { "refs/heads/b3", &_oid_b3 } };
+	do_push(specs, ARRAY_SIZE(specs),
+		exp_stats, ARRAY_SIZE(exp_stats),
+		exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
+}
+
+void test_online_push__b4(void)
+{
+	const char *specs[] = { "refs/heads/b4:refs/heads/b4" };
+	push_status exp_stats[] = { { "refs/heads/b4", 1 } };
+	expected_ref exp_refs[] = { { "refs/heads/b4", &_oid_b4 } };
+	do_push(specs, ARRAY_SIZE(specs),
+		exp_stats, ARRAY_SIZE(exp_stats),
+		exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
+}
+
+void test_online_push__b5(void)
+{
+	const char *specs[] = { "refs/heads/b5:refs/heads/b5" };
+	push_status exp_stats[] = { { "refs/heads/b5", 1 } };
+	expected_ref exp_refs[] = { { "refs/heads/b5", &_oid_b5 } };
+	do_push(specs, ARRAY_SIZE(specs),
+		exp_stats, ARRAY_SIZE(exp_stats),
+		exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
+}
+
+void test_online_push__b5_cancel(void)
+{
+	const char *specs[] = { "refs/heads/b5:refs/heads/b5" };
+	do_push(specs, ARRAY_SIZE(specs), NULL, 0, NULL, 0, GIT_EUSER, 1, 1);
+}
+
+void test_online_push__multi(void)
+{
+	git_reflog *log;
+	const git_reflog_entry *entry;
+
+	const char *specs[] = {
+		"refs/heads/b1:refs/heads/b1",
+		"refs/heads/b2:refs/heads/b2",
+		"refs/heads/b3:refs/heads/b3",
+		"refs/heads/b4:refs/heads/b4",
+		"refs/heads/b5:refs/heads/b5"
+	};
+	push_status exp_stats[] = {
+		{ "refs/heads/b1", 1 },
+		{ "refs/heads/b2", 1 },
+		{ "refs/heads/b3", 1 },
+		{ "refs/heads/b4", 1 },
+		{ "refs/heads/b5", 1 }
+	};
+	expected_ref exp_refs[] = {
+		{ "refs/heads/b1", &_oid_b1 },
+		{ "refs/heads/b2", &_oid_b2 },
+		{ "refs/heads/b3", &_oid_b3 },
+		{ "refs/heads/b4", &_oid_b4 },
+		{ "refs/heads/b5", &_oid_b5 }
+	};
+	do_push(specs, ARRAY_SIZE(specs),
+		exp_stats, ARRAY_SIZE(exp_stats),
+		exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
+
+	cl_git_pass(git_reflog_read(&log, _repo, "refs/remotes/test/b1"));
+	entry = git_reflog_entry_byindex(log, 0);
+	if (entry) {
+		cl_assert_equal_s("update by push", git_reflog_entry_message(entry));
+		cl_assert_equal_s("foo at example.com", git_reflog_entry_committer(entry)->email);
+	}
+
+	git_reflog_free(log);
+}
+
+void test_online_push__implicit_tgt(void)
+{
+	const char *specs1[] = { "refs/heads/b1" };
+	push_status exp_stats1[] = { { "refs/heads/b1", 1 } };
+	expected_ref exp_refs1[] = { { "refs/heads/b1", &_oid_b1 } };
+
+	const char *specs2[] = { "refs/heads/b2" };
+	push_status exp_stats2[] = { { "refs/heads/b2", 1 } };
+	expected_ref exp_refs2[] = {
+	{ "refs/heads/b1", &_oid_b1 },
+	{ "refs/heads/b2", &_oid_b2 }
+	};
+
+	do_push(specs1, ARRAY_SIZE(specs1),
+		exp_stats1, ARRAY_SIZE(exp_stats1),
+		exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1);
+	do_push(specs2, ARRAY_SIZE(specs2),
+		exp_stats2, ARRAY_SIZE(exp_stats2),
+		exp_refs2, ARRAY_SIZE(exp_refs2), 0, 0, 0);
+}
+
+void test_online_push__fast_fwd(void)
+{
+	/* Fast forward b1 in tgt from _oid_b1 to _oid_b6. */
+
+	const char *specs_init[] = { "refs/heads/b1:refs/heads/b1" };
+	push_status exp_stats_init[] = { { "refs/heads/b1", 1 } };
+	expected_ref exp_refs_init[] = { { "refs/heads/b1", &_oid_b1 } };
+
+	const char *specs_ff[] = { "refs/heads/b6:refs/heads/b1" };
+	push_status exp_stats_ff[] = { { "refs/heads/b1", 1 } };
+	expected_ref exp_refs_ff[] = { { "refs/heads/b1", &_oid_b6 } };
+
+	/* Do a force push to reset b1 in target back to _oid_b1 */
+	const char *specs_reset[] = { "+refs/heads/b1:refs/heads/b1" };
+	/* Force should have no effect on a fast forward push */
+	const char *specs_ff_force[] = { "+refs/heads/b6:refs/heads/b1" };
+
+	do_push(specs_init, ARRAY_SIZE(specs_init),
+		exp_stats_init, ARRAY_SIZE(exp_stats_init),
+		exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 1, 1);
+
+	do_push(specs_ff, ARRAY_SIZE(specs_ff),
+		exp_stats_ff, ARRAY_SIZE(exp_stats_ff),
+		exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0, 0);
+
+	do_push(specs_reset, ARRAY_SIZE(specs_reset),
+		exp_stats_init, ARRAY_SIZE(exp_stats_init),
+		exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 0, 0);
+
+	do_push(specs_ff_force, ARRAY_SIZE(specs_ff_force),
+		exp_stats_ff, ARRAY_SIZE(exp_stats_ff),
+		exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0, 0);
+}
+
+void test_online_push__tag_commit(void)
+{
+	const char *specs[] = { "refs/tags/tag-commit:refs/tags/tag-commit" };
+	push_status exp_stats[] = { { "refs/tags/tag-commit", 1 } };
+	expected_ref exp_refs[] = { { "refs/tags/tag-commit", &_tag_commit } };
+	do_push(specs, ARRAY_SIZE(specs),
+		exp_stats, ARRAY_SIZE(exp_stats),
+		exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
+}
+
+void test_online_push__tag_tree(void)
+{
+	const char *specs[] = { "refs/tags/tag-tree:refs/tags/tag-tree" };
+	push_status exp_stats[] = { { "refs/tags/tag-tree", 1 } };
+	expected_ref exp_refs[] = { { "refs/tags/tag-tree", &_tag_tree } };
+	do_push(specs, ARRAY_SIZE(specs),
+		exp_stats, ARRAY_SIZE(exp_stats),
+		exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
+}
+
+void test_online_push__tag_blob(void)
+{
+	const char *specs[] = { "refs/tags/tag-blob:refs/tags/tag-blob" };
+	push_status exp_stats[] = { { "refs/tags/tag-blob", 1 } };
+	expected_ref exp_refs[] = { { "refs/tags/tag-blob", &_tag_blob } };
+	do_push(specs, ARRAY_SIZE(specs),
+		exp_stats, ARRAY_SIZE(exp_stats),
+		exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
+}
+
+void test_online_push__tag_lightweight(void)
+{
+	const char *specs[] = { "refs/tags/tag-lightweight:refs/tags/tag-lightweight" };
+	push_status exp_stats[] = { { "refs/tags/tag-lightweight", 1 } };
+	expected_ref exp_refs[] = { { "refs/tags/tag-lightweight", &_tag_lightweight } };
+	do_push(specs, ARRAY_SIZE(specs),
+		exp_stats, ARRAY_SIZE(exp_stats),
+		exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
+}
+
+void test_online_push__tag_to_tag(void)
+{
+	const char *specs[] = { "refs/tags/tag-tag:refs/tags/tag-tag" };
+	push_status exp_stats[] = { { "refs/tags/tag-tag", 1 } };
+	expected_ref exp_refs[] = { { "refs/tags/tag-tag", &_tag_tag } };
+	do_push(specs, ARRAY_SIZE(specs),
+		exp_stats, ARRAY_SIZE(exp_stats),
+		exp_refs, ARRAY_SIZE(exp_refs), 0, 0, 0);
+}
+
+void test_online_push__force(void)
+{
+	const char *specs1[] = {"refs/heads/b3:refs/heads/tgt"};
+	push_status exp_stats1[] = { { "refs/heads/tgt", 1 } };
+	expected_ref exp_refs1[] = { { "refs/heads/tgt", &_oid_b3 } };
+
+	const char *specs2[] = {"refs/heads/b4:refs/heads/tgt"};
+
+	const char *specs2_force[] = {"+refs/heads/b4:refs/heads/tgt"};
+	push_status exp_stats2_force[] = { { "refs/heads/tgt", 1 } };
+	expected_ref exp_refs2_force[] = { { "refs/heads/tgt", &_oid_b4 } };
+
+	do_push(specs1, ARRAY_SIZE(specs1),
+		exp_stats1, ARRAY_SIZE(exp_stats1),
+		exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1);
+
+	do_push(specs2, ARRAY_SIZE(specs2),
+		NULL, 0,
+		exp_refs1, ARRAY_SIZE(exp_refs1), GIT_ENONFASTFORWARD, 0, 0);
+
+	/* Non-fast-forward update with force should pass. */
+	record_callbacks_data_clear(&_record_cbs_data);
+	do_push(specs2_force, ARRAY_SIZE(specs2_force),
+		exp_stats2_force, ARRAY_SIZE(exp_stats2_force),
+		exp_refs2_force, ARRAY_SIZE(exp_refs2_force), 0, 1, 1);
+}
+
+void test_online_push__delete(void)
+{
+	const char *specs1[] = {
+		"refs/heads/b1:refs/heads/tgt1",
+		"refs/heads/b1:refs/heads/tgt2"
+	};
+	push_status exp_stats1[] = {
+		{ "refs/heads/tgt1", 1 },
+		{ "refs/heads/tgt2", 1 }
+	};
+	expected_ref exp_refs1[] = {
+		{ "refs/heads/tgt1", &_oid_b1 },
+		{ "refs/heads/tgt2", &_oid_b1 }
+	};
+
+	const char *specs_del_fake[] = { ":refs/heads/fake" };
+	/* Force has no effect for delete. */
+	const char *specs_del_fake_force[] = { "+:refs/heads/fake" };
+	push_status exp_stats_fake[] = { { "refs/heads/fake", 1 } };
+
+	const char *specs_delete[] = { ":refs/heads/tgt1" };
+	push_status exp_stats_delete[] = { { "refs/heads/tgt1", 1 } };
+	expected_ref exp_refs_delete[] = { { "refs/heads/tgt2", &_oid_b1 } };
+	/* Force has no effect for delete. */
+	const char *specs_delete_force[] = { "+:refs/heads/tgt1" };
+
+	do_push(specs1, ARRAY_SIZE(specs1),
+		exp_stats1, ARRAY_SIZE(exp_stats1),
+		exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1);
+
+	/* When deleting a non-existent branch, the git client sends zero for both
+	 * the old and new commit id.  This should succeed on the server with the
+	 * same status report as if the branch were actually deleted.  The server
+	 * returns a warning on the side-band iff the side-band is supported.
+	 *  Since libgit2 doesn't support the side-band yet, there are no warnings.
+	 */
+	do_push(specs_del_fake, ARRAY_SIZE(specs_del_fake),
+		exp_stats_fake, 1,
+		exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0);
+	do_push(specs_del_fake_force, ARRAY_SIZE(specs_del_fake_force),
+		exp_stats_fake, 1,
+		exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0);
+
+	/* Delete one of the pushed branches. */
+	do_push(specs_delete, ARRAY_SIZE(specs_delete),
+		exp_stats_delete, ARRAY_SIZE(exp_stats_delete),
+		exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0, 0);
+
+	/* Re-push branches and retry delete with force. */
+	do_push(specs1, ARRAY_SIZE(specs1),
+		exp_stats1, ARRAY_SIZE(exp_stats1),
+		exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0);
+	do_push(specs_delete_force, ARRAY_SIZE(specs_delete_force),
+		exp_stats_delete, ARRAY_SIZE(exp_stats_delete),
+		exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0, 0);
+}
+
+void test_online_push__bad_refspecs(void)
+{
+	/* All classes of refspecs that should be rejected by
+	 * git_push_add_refspec() should go in this test.
+	 */
+	char *specs = {
+		"b6:b6",
+	};
+	git_strarray arr = {
+		&specs,
+		1,
+	};
+
+	if (_remote) {
+		cl_git_fail(git_remote_upload(_remote, &arr, NULL));
+	}
+}
+
+void test_online_push__expressions(void)
+{
+	/* TODO: Expressions in refspecs doesn't actually work yet */
+	const char *specs_left_expr[] = { "refs/heads/b2~1:refs/heads/b2" };
+
+	/* TODO: Find a more precise way of checking errors than a exit code of -1. */
+	do_push(specs_left_expr, ARRAY_SIZE(specs_left_expr),
+		NULL, 0,
+		NULL, 0, -1, 0, 0);
+}
+
+void test_online_push__notes(void)
+{
+	git_oid note_oid, *target_oid, expected_oid;
+	git_signature *signature;
+	const char *specs[] = { "refs/notes/commits:refs/notes/commits" };
+	push_status exp_stats[] = { { "refs/notes/commits", 1 } };
+	expected_ref exp_refs[] = { { "refs/notes/commits", &expected_oid } };
+	const char *specs_del[] = { ":refs/notes/commits" };
+
+	git_oid_fromstr(&expected_oid, "8461a99b27b7043e58ff6e1f5d2cf07d282534fb");
+
+	target_oid = &_oid_b6;
+
+	/* Create note to push */
+	cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas at gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */
+	cl_git_pass(git_note_create(&note_oid, _repo, NULL, signature, signature, target_oid, "hello world\n", 0));
+
+	do_push(specs, ARRAY_SIZE(specs),
+		exp_stats, ARRAY_SIZE(exp_stats),
+		exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
+
+	/* And make sure to delete the note */
+
+	do_push(specs_del, ARRAY_SIZE(specs_del),
+		exp_stats, 1,
+		NULL, 0, 0, 0, 0);
+
+	git_signature_free(signature);
+}
+
+void test_online_push__configured(void)
+{
+	git_oid note_oid, *target_oid, expected_oid;
+	git_signature *signature;
+	git_remote *old_remote;
+	const char *specs[] = { "refs/notes/commits:refs/notes/commits" };
+	push_status exp_stats[] = { { "refs/notes/commits", 1 } };
+	expected_ref exp_refs[] = { { "refs/notes/commits", &expected_oid } };
+	const char *specs_del[] = { ":refs/notes/commits" };
+
+	git_oid_fromstr(&expected_oid, "8461a99b27b7043e58ff6e1f5d2cf07d282534fb");
+
+	target_oid = &_oid_b6;
+
+	cl_git_pass(git_remote_add_push(_repo, git_remote_name(_remote), specs[0]));
+	old_remote = _remote;
+	cl_git_pass(git_remote_lookup(&_remote, _repo, git_remote_name(_remote)));
+	git_remote_free(old_remote);
+
+	/* Create note to push */
+	cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas at gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */
+	cl_git_pass(git_note_create(&note_oid, _repo, NULL, signature, signature, target_oid, "hello world\n", 0));
+
+	do_push(NULL, 0,
+		exp_stats, ARRAY_SIZE(exp_stats),
+		exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
+
+	/* And make sure to delete the note */
+
+	do_push(specs_del, ARRAY_SIZE(specs_del),
+		exp_stats, 1,
+		NULL, 0, 0, 0, 0);
+
+	git_signature_free(signature);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/push_util.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/push_util.c
new file mode 100755
index 0000000..cd483c7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/push_util.c
@@ -0,0 +1,146 @@
+
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "vector.h"
+#include "push_util.h"
+
+const git_oid OID_ZERO = {{ 0 }};
+
+void updated_tip_free(updated_tip *t)
+{
+	git__free(t->name);
+	git__free(t->old_oid);
+	git__free(t->new_oid);
+	git__free(t);
+}
+
+void push_status_free(push_status *s)
+{
+	git__free(s->ref);
+	git__free(s->msg);
+	git__free(s);
+}
+
+void record_callbacks_data_clear(record_callbacks_data *data)
+{
+	size_t i;
+	updated_tip *tip;
+	push_status *status;
+
+	git_vector_foreach(&data->updated_tips, i, tip)
+		updated_tip_free(tip);
+
+	git_vector_free(&data->updated_tips);
+
+	git_vector_foreach(&data->statuses, i, status)
+		push_status_free(status);
+
+	git_vector_free(&data->statuses);
+
+	data->pack_progress_calls = 0;
+	data->transfer_progress_calls = 0;
+}
+
+int record_update_tips_cb(const char *refname, const git_oid *a, const git_oid *b, void *data)
+{
+	updated_tip *t;
+	record_callbacks_data *record_data = (record_callbacks_data *)data;
+
+	cl_assert(t = git__malloc(sizeof(*t)));
+
+	cl_assert(t->name = git__strdup(refname));
+	cl_assert(t->old_oid = git__malloc(sizeof(*t->old_oid)));
+	git_oid_cpy(t->old_oid, a);
+
+	cl_assert(t->new_oid = git__malloc(sizeof(*t->new_oid)));
+	git_oid_cpy(t->new_oid, b);
+
+	git_vector_insert(&record_data->updated_tips, t);
+
+	return 0;
+}
+
+int create_deletion_refspecs(git_vector *out, const git_remote_head **heads, size_t heads_len)
+{
+	git_buf del_spec = GIT_BUF_INIT;
+	size_t i;
+
+	for (i = 0; i < heads_len; i++) {
+		const git_remote_head *head = heads[i];
+		/* Ignore malformed ref names (which also saves us from tag^{} */
+		if (!git_reference_is_valid_name(head->name))
+			return 0;
+
+		/* Create a refspec that deletes a branch in the remote */
+		if (strcmp(head->name, "refs/heads/master")) {
+			cl_git_pass(git_buf_putc(&del_spec, ':'));
+			cl_git_pass(git_buf_puts(&del_spec, head->name));
+			cl_git_pass(git_vector_insert(out, git_buf_detach(&del_spec)));
+		}
+	}
+
+	return 0;
+}
+
+int record_ref_cb(git_remote_head *head, void *payload)
+{
+	git_vector *refs = (git_vector *) payload;
+	return git_vector_insert(refs, head);
+}
+
+void verify_remote_refs(const git_remote_head *actual_refs[], size_t actual_refs_len, const expected_ref expected_refs[], size_t expected_refs_len)
+{
+	size_t i, j = 0;
+	git_buf msg = GIT_BUF_INIT;
+	const git_remote_head *actual;
+	char *oid_str;
+	bool master_present = false;
+
+	/* We don't care whether "master" is present on the other end or not */
+	for (i = 0; i < actual_refs_len; i++) {
+		actual = actual_refs[i];
+		if (!strcmp(actual->name, "refs/heads/master")) {
+			master_present = true;
+			break;
+		}
+	}
+
+	if (expected_refs_len + (master_present ? 1 : 0) != actual_refs_len)
+		goto failed;
+
+	for (i = 0; i < actual_refs_len; i++) {
+		actual = actual_refs[i];
+		if (master_present && !strcmp(actual->name, "refs/heads/master"))
+			continue;
+
+		if (strcmp(expected_refs[j].name, actual->name) ||
+			git_oid_cmp(expected_refs[j].oid, &actual->oid))
+			goto failed;
+
+		j++;
+	}
+
+	return;
+
+failed:
+	git_buf_puts(&msg, "Expected and actual refs differ:\nEXPECTED:\n");
+
+	for(i = 0; i < expected_refs_len; i++) {
+		oid_str = git_oid_tostr_s(expected_refs[i].oid);
+		cl_git_pass(git_buf_printf(&msg, "%s = %s\n", expected_refs[i].name, oid_str));
+	}
+
+	git_buf_puts(&msg, "\nACTUAL:\n");
+	for (i = 0; i < actual_refs_len; i++) {
+		actual = actual_refs[i];
+		if (master_present && !strcmp(actual->name, "refs/heads/master"))
+			continue;
+
+		oid_str = git_oid_tostr_s(&actual->oid);
+		cl_git_pass(git_buf_printf(&msg, "%s = %s\n", actual->name, oid_str));
+	}
+
+	cl_fail(git_buf_cstr(&msg));
+
+	git_buf_free(&msg);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/push_util.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/push_util.h
new file mode 100755
index 0000000..822341b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/push_util.h
@@ -0,0 +1,83 @@
+#ifndef INCLUDE_cl_push_util_h__
+#define INCLUDE_cl_push_util_h__
+
+#include "git2/oid.h"
+
+/* Constant for zero oid */
+extern const git_oid OID_ZERO;
+
+/**
+ * Macro for initializing git_remote_callbacks to use test helpers that
+ * record data in a record_callbacks_data instance.
+ * @param data pointer to a record_callbacks_data instance
+ */
+#define RECORD_CALLBACKS_INIT(data) \
+	{ GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, cred_acquire_cb, NULL, NULL, record_update_tips_cb, NULL, NULL, NULL, NULL, NULL, data }
+
+typedef struct {
+	char *name;
+	git_oid *old_oid;
+	git_oid *new_oid;
+} updated_tip;
+
+typedef struct {
+	git_vector updated_tips;
+	git_vector statuses;
+	int pack_progress_calls;
+	int transfer_progress_calls;
+} record_callbacks_data;
+
+typedef struct {
+	const char *name;
+	const git_oid *oid;
+} expected_ref;
+
+/* the results of a push status.  when used for expected values, msg may be NULL
+ * to indicate that it should not be matched. */
+typedef struct {
+	char *ref;
+	int success;
+	char *msg;
+} push_status;
+
+
+void updated_tip_free(updated_tip *t);
+
+void record_callbacks_data_clear(record_callbacks_data *data);
+
+/**
+ * Callback for git_remote_update_tips that records updates
+ *
+ * @param data (git_vector *) of updated_tip instances
+ */
+int record_update_tips_cb(const char *refname, const git_oid *a, const git_oid *b, void *data);
+
+/**
+ * Create a set of refspecs that deletes each of the inputs
+ *
+ * @param out the vector in which to store the refspecs
+ * @param heads the remote heads
+ * @param heads_len the size of the array
+ */
+int create_deletion_refspecs(git_vector *out, const git_remote_head **heads, size_t heads_len);
+
+/**
+ * Callback for git_remote_list that adds refspecs to vector
+ *
+ * @param head a ref on the remote
+ * @param payload (git_vector *) of git_remote_head instances
+ */
+int record_ref_cb(git_remote_head *head, void *payload);
+
+/**
+ * Verifies that refs on remote stored by record_ref_cb match the expected
+ * names, oids, and order.
+ *
+ * @param actual_refs actual refs in the remote
+ * @param actual_refs_len length of actual_refs
+ * @param expected_refs expected remote refs
+ * @param expected_refs_len length of expected_refs
+ */
+void verify_remote_refs(const git_remote_head *actual_refs[], size_t actual_refs_len, const expected_ref expected_refs[], size_t expected_refs_len);
+
+#endif /* INCLUDE_cl_push_util_h__ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/remotes.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/remotes.c
new file mode 100755
index 0000000..a86f2d9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/online/remotes.c
@@ -0,0 +1,55 @@
+#include "clar_libgit2.h"
+
+static const char *refspec = "refs/heads/first-merge:refs/remotes/origin/first-merge";
+
+static int remote_single_branch(git_remote **out, git_repository *repo, const char *name, const char *url, void *payload)
+{
+	GIT_UNUSED(payload);
+
+	cl_git_pass(git_remote_create_with_fetchspec(out, repo, name, url, refspec));
+
+	return 0;
+}
+
+void test_online_remotes__single_branch(void)
+{
+	git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
+	git_repository *repo;
+	git_remote *remote;
+	git_strarray refs;
+	size_t i, count = 0;
+
+	opts.remote_cb = remote_single_branch;
+	opts.checkout_branch = "first-merge";
+
+	cl_git_pass(git_clone(&repo, "git://github.com/libgit2/TestGitRepository", "./single-branch", &opts));
+	cl_git_pass(git_reference_list(&refs, repo));
+
+	for (i = 0; i < refs.count; i++) {
+		if (!git__prefixcmp(refs.strings[i], "refs/heads/"))
+			count++;
+	}
+	cl_assert_equal_i(1, count);
+
+	git_strarray_free(&refs);
+
+	cl_git_pass(git_remote_lookup(&remote, repo, "origin"));
+	cl_git_pass(git_remote_get_fetch_refspecs(&refs, remote));
+
+	cl_assert_equal_i(1, refs.count);
+	cl_assert_equal_s(refspec, refs.strings[0]);
+
+	git_strarray_free(&refs);
+	git_remote_free(remote);
+	git_repository_free(repo);
+}
+
+void test_online_remotes__restricted_refspecs(void)
+{
+	git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
+	git_repository *repo;
+
+	opts.remote_cb = remote_single_branch;
+
+	cl_git_fail_with(GIT_EINVALIDSPEC, git_clone(&repo, "git://github.com/libgit2/TestGitRepository", "./restrict-refspec", &opts));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/pack/indexer.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/pack/indexer.c
new file mode 100755
index 0000000..49a106d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/pack/indexer.c
@@ -0,0 +1,127 @@
+#include "clar_libgit2.h"
+#include <git2.h>
+#include "fileops.h"
+#include "hash.h"
+#include "iterator.h"
+#include "vector.h"
+#include "posix.h"
+
+
+/*
+ * This is a packfile with three objects. The second is a delta which
+ * depends on the third, which is also a delta.
+ */
+static const unsigned char out_of_order_pack[] = {
+  0x50, 0x41, 0x43, 0x4b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
+  0x32, 0x78, 0x9c, 0x63, 0x67, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x76,
+  0xe6, 0x8f, 0xe8, 0x12, 0x9b, 0x54, 0x6b, 0x10, 0x1a, 0xee, 0x95, 0x10,
+  0xc5, 0x32, 0x8e, 0x7f, 0x21, 0xca, 0x1d, 0x18, 0x78, 0x9c, 0x63, 0x62,
+  0x66, 0x4e, 0xcb, 0xcf, 0x07, 0x00, 0x02, 0xac, 0x01, 0x4d, 0x75, 0x01,
+  0xd7, 0x71, 0x36, 0x66, 0xf4, 0xde, 0x82, 0x27, 0x76, 0xc7, 0x62, 0x2c,
+  0x10, 0xf1, 0xb0, 0x7d, 0xe2, 0x80, 0xdc, 0x78, 0x9c, 0x63, 0x62, 0x62,
+  0x62, 0xb7, 0x03, 0x00, 0x00, 0x69, 0x00, 0x4c, 0xde, 0x7d, 0xaa, 0xe4,
+  0x19, 0x87, 0x58, 0x80, 0x61, 0x09, 0x9a, 0x33, 0xca, 0x7a, 0x31, 0x92,
+  0x6f, 0xae, 0x66, 0x75
+};
+static const unsigned int out_of_order_pack_len = 112;
+
+/*
+ * Packfile with two objects. The second is a delta against an object
+ * which is not in the packfile
+ */
+static const unsigned char thin_pack[] = {
+  0x50, 0x41, 0x43, 0x4b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
+  0x32, 0x78, 0x9c, 0x63, 0x67, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x76,
+  0xe6, 0x8f, 0xe8, 0x12, 0x9b, 0x54, 0x6b, 0x10, 0x1a, 0xee, 0x95, 0x10,
+  0xc5, 0x32, 0x8e, 0x7f, 0x21, 0xca, 0x1d, 0x18, 0x78, 0x9c, 0x63, 0x62,
+  0x66, 0x4e, 0xcb, 0xcf, 0x07, 0x00, 0x02, 0xac, 0x01, 0x4d, 0x42, 0x52,
+  0x3a, 0x6f, 0x39, 0xd1, 0xfe, 0x66, 0x68, 0x6b, 0xa5, 0xe5, 0xe2, 0x97,
+  0xac, 0x94, 0x6c, 0x76, 0x0b, 0x04
+};
+static const unsigned int thin_pack_len = 78;
+
+static const unsigned char base_obj[] = { 07, 076 };
+static const unsigned int base_obj_len = 2;
+
+void test_pack_indexer__out_of_order(void)
+{
+	git_indexer *idx = 0;
+	git_transfer_progress stats = { 0 };
+
+	cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL, NULL));
+	cl_git_pass(git_indexer_append(
+		idx, out_of_order_pack, out_of_order_pack_len, &stats));
+	cl_git_pass(git_indexer_commit(idx, &stats));
+
+	cl_assert_equal_i(stats.total_objects, 3);
+	cl_assert_equal_i(stats.received_objects, 3);
+	cl_assert_equal_i(stats.indexed_objects, 3);
+
+	git_indexer_free(idx);
+}
+
+void test_pack_indexer__fix_thin(void)
+{
+	git_indexer *idx = NULL;
+	git_transfer_progress stats = { 0 };
+	git_repository *repo;
+	git_odb *odb;
+	git_oid id, should_id;
+
+	cl_git_pass(git_repository_init(&repo, "thin.git", true));
+	cl_git_pass(git_repository_odb(&odb, repo));
+
+	/* Store the missing base into your ODB so the indexer can fix the pack */
+	cl_git_pass(git_odb_write(&id, odb, base_obj, base_obj_len, GIT_OBJ_BLOB));
+	git_oid_fromstr(&should_id, "e68fe8129b546b101aee9510c5328e7f21ca1d18");
+	cl_assert_equal_oid(&should_id, &id);
+
+	cl_git_pass(git_indexer_new(&idx, ".", 0, odb, NULL, NULL));
+	cl_git_pass(git_indexer_append(idx, thin_pack, thin_pack_len, &stats));
+	cl_git_pass(git_indexer_commit(idx, &stats));
+
+	cl_assert_equal_i(stats.total_objects, 2);
+	cl_assert_equal_i(stats.received_objects, 2);
+	cl_assert_equal_i(stats.indexed_objects, 2);
+	cl_assert_equal_i(stats.local_objects, 1);
+
+	git_oid_fromstr(&should_id, "11f0f69b334728fdd8bc86b80499f22f29d85b15");
+	cl_assert_equal_oid(&should_id, git_indexer_hash(idx));
+
+	git_indexer_free(idx);
+	git_odb_free(odb);
+	git_repository_free(repo);
+
+	/*
+	 * The pack's name/hash only tells us what objects there are,
+	 * so we need to go through the packfile again in order to
+	 * figure out whether we calculated the trailer correctly.
+	 */
+	{
+		unsigned char buffer[128];
+		int fd;
+		ssize_t read;
+		struct stat st;
+		const char *name = "pack-11f0f69b334728fdd8bc86b80499f22f29d85b15.pack";
+
+		fd = p_open(name, O_RDONLY);
+		cl_assert(fd != -1);
+
+		cl_git_pass(p_stat(name, &st));
+
+		cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL, NULL));
+		read = p_read(fd, buffer, sizeof(buffer));
+		cl_assert(read != -1);
+		p_close(fd);
+
+		cl_git_pass(git_indexer_append(idx, buffer, read, &stats));
+		cl_git_pass(git_indexer_commit(idx, &stats));
+
+		cl_assert_equal_i(stats.total_objects, 3);
+		cl_assert_equal_i(stats.received_objects, 3);
+		cl_assert_equal_i(stats.indexed_objects, 3);
+		cl_assert_equal_i(stats.local_objects, 0);
+
+		git_indexer_free(idx);
+	}
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/pack/packbuilder.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/pack/packbuilder.c
new file mode 100755
index 0000000..29f3e2d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/pack/packbuilder.c
@@ -0,0 +1,225 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "pack.h"
+#include "hash.h"
+#include "iterator.h"
+#include "vector.h"
+#include "posix.h"
+
+static git_repository *_repo;
+static git_revwalk *_revwalker;
+static git_packbuilder *_packbuilder;
+static git_indexer *_indexer;
+static git_vector _commits;
+static int _commits_is_initialized;
+static git_transfer_progress _stats;
+
+void test_pack_packbuilder__initialize(void)
+{
+	_repo = cl_git_sandbox_init("testrepo.git");
+	cl_git_pass(p_chdir("testrepo.git"));
+	cl_git_pass(git_revwalk_new(&_revwalker, _repo));
+	cl_git_pass(git_packbuilder_new(&_packbuilder, _repo));
+	cl_git_pass(git_vector_init(&_commits, 0, NULL));
+	_commits_is_initialized = 1;
+	memset(&_stats, 0, sizeof(_stats));
+}
+
+void test_pack_packbuilder__cleanup(void)
+{
+	git_oid *o;
+	unsigned int i;
+
+	if (_commits_is_initialized) {
+		_commits_is_initialized = 0;
+		git_vector_foreach(&_commits, i, o) {
+			git__free(o);
+		}
+		git_vector_free(&_commits);
+	}
+
+	git_packbuilder_free(_packbuilder);
+	_packbuilder = NULL;
+
+	git_revwalk_free(_revwalker);
+	_revwalker = NULL;
+
+	git_indexer_free(_indexer);
+	_indexer = NULL;
+
+	cl_git_pass(p_chdir(".."));
+	cl_git_sandbox_cleanup();
+	_repo = NULL;
+}
+
+static void seed_packbuilder(void)
+{
+	git_oid oid, *o;
+	unsigned int i;
+
+	git_revwalk_sorting(_revwalker, GIT_SORT_TIME);
+	cl_git_pass(git_revwalk_push_ref(_revwalker, "HEAD"));
+
+	while (git_revwalk_next(&oid, _revwalker) == 0) {
+		o = git__malloc(GIT_OID_RAWSZ);
+		cl_assert(o != NULL);
+		git_oid_cpy(o, &oid);
+		cl_git_pass(git_vector_insert(&_commits, o));
+	}
+
+	git_vector_foreach(&_commits, i, o) {
+		cl_git_pass(git_packbuilder_insert(_packbuilder, o, NULL));
+	}
+
+	git_vector_foreach(&_commits, i, o) {
+		git_object *obj;
+		cl_git_pass(git_object_lookup(&obj, _repo, o, GIT_OBJ_COMMIT));
+		cl_git_pass(git_packbuilder_insert_tree(_packbuilder,
+					git_commit_tree_id((git_commit *)obj)));
+		git_object_free(obj);
+	}
+}
+
+static int feed_indexer(void *ptr, size_t len, void *payload)
+{
+	git_transfer_progress *stats = (git_transfer_progress *)payload;
+
+	return git_indexer_append(_indexer, ptr, len, stats);
+}
+
+void test_pack_packbuilder__create_pack(void)
+{
+	git_transfer_progress stats;
+	git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT;
+	git_hash_ctx ctx;
+	git_oid hash;
+	char hex[GIT_OID_HEXSZ+1]; hex[GIT_OID_HEXSZ] = '\0';
+
+	seed_packbuilder();
+
+	cl_git_pass(git_indexer_new(&_indexer, ".", 0, NULL, NULL, NULL));
+	cl_git_pass(git_packbuilder_foreach(_packbuilder, feed_indexer, &stats));
+	cl_git_pass(git_indexer_commit(_indexer, &stats));
+
+	git_oid_fmt(hex, git_indexer_hash(_indexer));
+	git_buf_printf(&path, "pack-%s.pack", hex);
+
+	/*
+	 * By default, packfiles are created with only one thread.
+	 * Therefore we can predict the object ordering and make sure
+	 * we create exactly the same pack as git.git does when *not*
+	 * reusing existing deltas (as libgit2).
+	 *
+	 * $ cd tests/resources/testrepo.git
+	 * $ git rev-list --objects HEAD | \
+	 * 	git pack-objects -q --no-reuse-delta --threads=1 pack
+	 * $ sha1sum git-80e61eb315239ef3c53033e37fee43b744d57122.pack
+	 * 5d410bdf97cf896f9007681b92868471d636954b
+	 *
+	 */
+
+	cl_git_pass(git_futils_readbuffer(&buf, git_buf_cstr(&path)));
+
+	cl_git_pass(git_hash_ctx_init(&ctx));
+	cl_git_pass(git_hash_update(&ctx, buf.ptr, buf.size));
+	cl_git_pass(git_hash_final(&hash, &ctx));
+	git_hash_ctx_cleanup(&ctx);
+
+	git_buf_free(&path);
+	git_buf_free(&buf);
+
+	git_oid_fmt(hex, &hash);
+
+	cl_assert_equal_s(hex, "5d410bdf97cf896f9007681b92868471d636954b");
+}
+
+void test_pack_packbuilder__get_hash(void)
+{
+	char hex[GIT_OID_HEXSZ+1]; hex[GIT_OID_HEXSZ] = '\0';
+
+	seed_packbuilder();
+
+	git_packbuilder_write(_packbuilder, ".", 0, NULL, NULL);
+	git_oid_fmt(hex, git_packbuilder_hash(_packbuilder));
+
+	cl_assert_equal_s(hex, "80e61eb315239ef3c53033e37fee43b744d57122");
+}
+
+static void test_write_pack_permission(mode_t given, mode_t expected)
+{
+	struct stat statbuf;
+	mode_t mask, os_mask;
+
+	seed_packbuilder();
+
+	git_packbuilder_write(_packbuilder, ".", given, NULL, NULL);
+
+	/* Windows does not return group/user bits from stat,
+	* files are never executable.
+	*/
+#ifdef GIT_WIN32
+	os_mask = 0600;
+#else
+	os_mask = 0777;
+#endif
+
+	mask = p_umask(0);
+	p_umask(mask);
+
+	cl_git_pass(p_stat("pack-80e61eb315239ef3c53033e37fee43b744d57122.idx", &statbuf));
+	cl_assert_equal_i(statbuf.st_mode & os_mask, (expected & ~mask) & os_mask);
+
+	cl_git_pass(p_stat("pack-80e61eb315239ef3c53033e37fee43b744d57122.pack", &statbuf));
+	cl_assert_equal_i(statbuf.st_mode & os_mask, (expected & ~mask) & os_mask);
+}
+
+void test_pack_packbuilder__permissions_standard(void)
+{
+	test_write_pack_permission(0, GIT_PACK_FILE_MODE);
+}
+
+void test_pack_packbuilder__permissions_readonly(void)
+{
+	test_write_pack_permission(0444, 0444);
+}
+
+void test_pack_packbuilder__permissions_readwrite(void)
+{
+	test_write_pack_permission(0666, 0666);
+}
+
+static int foreach_cb(void *buf, size_t len, void *payload)
+{
+	git_indexer *idx = (git_indexer *) payload;
+	cl_git_pass(git_indexer_append(idx, buf, len, &_stats));
+	return 0;
+}
+
+void test_pack_packbuilder__foreach(void)
+{
+	git_indexer *idx;
+
+	seed_packbuilder();
+	cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL, NULL));
+	cl_git_pass(git_packbuilder_foreach(_packbuilder, foreach_cb, idx));
+	cl_git_pass(git_indexer_commit(idx, &_stats));
+	git_indexer_free(idx);
+}
+
+static int foreach_cancel_cb(void *buf, size_t len, void *payload)
+{
+	git_indexer *idx = (git_indexer *)payload;
+	cl_git_pass(git_indexer_append(idx, buf, len, &_stats));
+	return (_stats.total_objects > 2) ? -1111 : 0;
+}
+
+void test_pack_packbuilder__foreach_with_cancel(void)
+{
+	git_indexer *idx;
+
+	seed_packbuilder();
+	cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL, NULL));
+	cl_git_fail_with(
+		git_packbuilder_foreach(_packbuilder, foreach_cancel_cb, idx), -1111);
+	git_indexer_free(idx);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/pack/sharing.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/pack/sharing.c
new file mode 100755
index 0000000..a67d655
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/pack/sharing.c
@@ -0,0 +1,42 @@
+#include "clar_libgit2.h"
+#include <git2.h>
+#include "strmap.h"
+#include "mwindow.h"
+#include "pack.h"
+
+extern git_strmap *git__pack_cache;
+
+void test_pack_sharing__open_two_repos(void)
+{
+	git_repository *repo1, *repo2;
+	git_object *obj1, *obj2;
+	git_oid id;
+	git_strmap_iter pos;
+	void *data;
+	int error;
+
+	cl_git_pass(git_repository_open(&repo1, cl_fixture("testrepo.git")));
+	cl_git_pass(git_repository_open(&repo2, cl_fixture("testrepo.git")));
+
+	git_oid_fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+
+	cl_git_pass(git_object_lookup(&obj1, repo1, &id, GIT_OBJ_ANY));
+	cl_git_pass(git_object_lookup(&obj2, repo2, &id, GIT_OBJ_ANY));
+
+	pos = 0;
+	while ((error = git_strmap_next(&data, &pos, git__pack_cache)) == 0) {
+		struct git_pack_file *pack = (struct git_pack_file *) data;
+
+		cl_assert_equal_i(2, pack->refcount.val);
+	}
+
+	cl_assert_equal_i(3, git_strmap_num_entries(git__pack_cache));
+
+	git_object_free(obj1);
+	git_object_free(obj2);
+	git_repository_free(repo1);
+	git_repository_free(repo2);
+
+	/* we don't want to keep the packs open after the repos go away */
+	cl_assert_equal_i(0, git_strmap_num_entries(git__pack_cache));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/path/core.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/path/core.c
new file mode 100755
index 0000000..064f149
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/path/core.c
@@ -0,0 +1,354 @@
+#include "clar_libgit2.h"
+#include "path.h"
+
+static void test_make_relative(
+	const char *expected_path,
+	const char *path,
+	const char *parent,
+	int expected_status)
+{
+	git_buf buf = GIT_BUF_INIT;
+	git_buf_puts(&buf, path);
+	cl_assert_equal_i(expected_status, git_path_make_relative(&buf, parent));
+	cl_assert_equal_s(expected_path, buf.ptr);
+	git_buf_free(&buf);
+}
+
+void test_path_core__make_relative(void)
+{
+	test_make_relative("foo.c", "/path/to/foo.c", "/path/to", 0);
+	test_make_relative("bar/foo.c", "/path/to/bar/foo.c", "/path/to", 0);
+	test_make_relative("foo.c", "/path/to/foo.c", "/path/to/", 0);
+
+	test_make_relative("", "/path/to", "/path/to", 0);
+	test_make_relative("", "/path/to", "/path/to/", 0);
+
+	test_make_relative("../", "/path/to", "/path/to/foo", 0);
+
+	test_make_relative("../foo.c", "/path/to/foo.c", "/path/to/bar", 0);
+	test_make_relative("../bar/foo.c", "/path/to/bar/foo.c", "/path/to/baz", 0);
+
+	test_make_relative("../../foo.c", "/path/to/foo.c", "/path/to/foo/bar", 0);
+	test_make_relative("../../foo/bar.c", "/path/to/foo/bar.c", "/path/to/bar/foo", 0);
+
+	test_make_relative("../../foo.c", "/foo.c", "/bar/foo", 0);
+
+	test_make_relative("foo.c", "/path/to/foo.c", "/path/to/", 0);
+	test_make_relative("../foo.c", "/path/to/foo.c", "/path/to/bar/", 0);
+
+	test_make_relative("foo.c", "d:/path/to/foo.c", "d:/path/to", 0);
+
+	test_make_relative("../foo", "/foo", "/bar", 0);
+	test_make_relative("path/to/foo.c", "/path/to/foo.c", "/", 0);
+	test_make_relative("../foo", "path/to/foo", "path/to/bar", 0);
+
+	test_make_relative("/path/to/foo.c", "/path/to/foo.c", "d:/path/to", GIT_ENOTFOUND);
+	test_make_relative("d:/path/to/foo.c", "d:/path/to/foo.c", "/path/to", GIT_ENOTFOUND);
+	
+	test_make_relative("/path/to/foo.c", "/path/to/foo.c", "not-a-rooted-path", GIT_ENOTFOUND);
+	test_make_relative("not-a-rooted-path", "not-a-rooted-path", "/path/to", GIT_ENOTFOUND);
+	
+	test_make_relative("/path", "/path", "pathtofoo", GIT_ENOTFOUND);
+	test_make_relative("path", "path", "pathtofoo", GIT_ENOTFOUND);
+}
+
+void test_path_core__isvalid_standard(void)
+{
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/file.txt", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/.file", 0));
+}
+
+void test_path_core__isvalid_empty_dir_component(void)
+{
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo//bar", 0));
+
+	/* leading slash */
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "/", 0));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "/foo", 0));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "/foo/bar", 0));
+
+	/* trailing slash */
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/", 0));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar/", 0));
+}
+
+void test_path_core__isvalid_dot_and_dotdot(void)
+{
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "./foo", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "./foo", 0));
+
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "..", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "../foo", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/..", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "../foo", 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".", GIT_PATH_REJECT_TRAVERSAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "./foo", GIT_PATH_REJECT_TRAVERSAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.", GIT_PATH_REJECT_TRAVERSAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "./foo", GIT_PATH_REJECT_TRAVERSAL));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "..", GIT_PATH_REJECT_TRAVERSAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "../foo", GIT_PATH_REJECT_TRAVERSAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/..", GIT_PATH_REJECT_TRAVERSAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "../foo", GIT_PATH_REJECT_TRAVERSAL));
+}
+
+void test_path_core__isvalid_dot_git(void)
+{
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git/foo", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.git", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.git/bar", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.GIT/bar", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/.Git", 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", GIT_PATH_REJECT_DOT_GIT));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git/foo", GIT_PATH_REJECT_DOT_GIT));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.git", GIT_PATH_REJECT_DOT_GIT));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.git/bar", GIT_PATH_REJECT_DOT_GIT));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.GIT/bar", GIT_PATH_REJECT_DOT_GIT));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar/.Git", GIT_PATH_REJECT_DOT_GIT));
+
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "!git", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/!git", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "!git/bar", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".tig", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.tig", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".tig/bar", 0));
+}
+
+void test_path_core__isvalid_backslash(void)
+{
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo\\file.txt", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar\\file.txt", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar\\", 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo\\file.txt", GIT_PATH_REJECT_BACKSLASH));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar\\file.txt", GIT_PATH_REJECT_BACKSLASH));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar\\", GIT_PATH_REJECT_BACKSLASH));
+}
+
+void test_path_core__isvalid_trailing_dot(void)
+{
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo.", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo...", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar.", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo./bar", 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo.", GIT_PATH_REJECT_TRAILING_DOT));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo...", GIT_PATH_REJECT_TRAILING_DOT));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar.", GIT_PATH_REJECT_TRAILING_DOT));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo./bar", GIT_PATH_REJECT_TRAILING_DOT));
+}
+
+void test_path_core__isvalid_trailing_space(void)
+{
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo ", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo   ", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar ", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, " ", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo /bar", 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo ", GIT_PATH_REJECT_TRAILING_SPACE));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo   ", GIT_PATH_REJECT_TRAILING_SPACE));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar ", GIT_PATH_REJECT_TRAILING_SPACE));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, " ", GIT_PATH_REJECT_TRAILING_SPACE));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo /bar", GIT_PATH_REJECT_TRAILING_SPACE));
+}
+
+void test_path_core__isvalid_trailing_colon(void)
+{
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo:", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar:", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ":", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo:/bar", 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo:", GIT_PATH_REJECT_TRAILING_COLON));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar:", GIT_PATH_REJECT_TRAILING_COLON));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ":", GIT_PATH_REJECT_TRAILING_COLON));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo:/bar", GIT_PATH_REJECT_TRAILING_COLON));
+}
+
+void test_path_core__isvalid_dotgit_ntfs(void)
+{
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git ", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git.", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git.. .", 0));
+
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1 ", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1.", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1.. .", 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", GIT_PATH_REJECT_DOT_GIT_NTFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git ", GIT_PATH_REJECT_DOT_GIT_NTFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git.", GIT_PATH_REJECT_DOT_GIT_NTFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git.. .", GIT_PATH_REJECT_DOT_GIT_NTFS));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1", GIT_PATH_REJECT_DOT_GIT_NTFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1 ", GIT_PATH_REJECT_DOT_GIT_NTFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1.", GIT_PATH_REJECT_DOT_GIT_NTFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1.. .", GIT_PATH_REJECT_DOT_GIT_NTFS));
+}
+
+void test_path_core__isvalid_dos_paths(void)
+{
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux:", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.asdf", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.asdf\\zippy", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux:asdf\\foobar", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "con", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "prn", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "nul", 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux:", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.asdf", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.asdf\\zippy", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux:asdf\\foobar", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "con", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "prn", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "nul", GIT_PATH_REJECT_DOS_PATHS));
+
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux1", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux1", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "auxn", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux\\foo", GIT_PATH_REJECT_DOS_PATHS));
+}
+
+void test_path_core__isvalid_dos_paths_withnum(void)
+{
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1:", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.asdf", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.asdf\\zippy", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1:asdf\\foobar", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1\\foo", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt1", 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1:", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.asdf", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.asdf\\zippy", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1:asdf\\foobar", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1/foo", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "lpt1", GIT_PATH_REJECT_DOS_PATHS));
+
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com0", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com0", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com10", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com10", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "comn", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1\\foo", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt0", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt10", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "lptn", GIT_PATH_REJECT_DOS_PATHS));
+}
+
+void test_path_core__isvalid_nt_chars(void)
+{
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\001foo", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\037bar", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf<bar", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf>foo", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf:foo", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\"bar", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf|foo", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf?bar", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf*bar", 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\001foo", GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\037bar", GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf<bar", GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf>foo", GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf:foo", GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\"bar", GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf|foo", GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf?bar", GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf*bar", GIT_PATH_REJECT_NT_CHARS));
+}
+
+void test_path_core__isvalid_dotgit_with_hfs_ignorables(void)
+{
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git\xe2\x80\x8c", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".gi\xe2\x80\x8dT", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".g\xe2\x80\x8eIt", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".\xe2\x80\x8fgIt", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x80\xaa.gIt", GIT_PATH_REJECT_DOT_GIT_HFS));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x80\xab.\xe2\x80\xacG\xe2\x80\xadI\xe2\x80\xaet", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x81\xab.\xe2\x80\xaaG\xe2\x81\xabI\xe2\x80\xact", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", GIT_PATH_REJECT_DOT_GIT_HFS));
+
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".g", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, " .git", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "..git\xe2\x80\x8c", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\xe2\x80\x8dT.", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".g\xe2\x80It", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".\xe2gIt", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "\xe2\x80\xaa.gi", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\x80\x8dT", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\x8dT", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".g\xe2i\x80T\x8e", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\x80\xbf", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\xab\x81", GIT_PATH_REJECT_DOT_GIT_HFS));
+}
+
+static void test_join_unrooted(
+	const char *expected_result,
+	ssize_t expected_rootlen,
+	const char *path,
+	const char *base)
+{
+	git_buf result = GIT_BUF_INIT;
+	ssize_t root_at;
+
+	cl_git_pass(git_path_join_unrooted(&result, path, base, &root_at));
+	cl_assert_equal_s(expected_result, result.ptr);
+	cl_assert_equal_i(expected_rootlen, root_at);
+
+	git_buf_free(&result);
+}
+
+void test_path_core__join_unrooted(void)
+{
+	git_buf out = GIT_BUF_INIT;
+
+	test_join_unrooted("foo", 0, "foo", NULL);
+	test_join_unrooted("foo/bar", 0, "foo/bar", NULL);
+
+	/* Relative paths have base prepended */
+	test_join_unrooted("/foo/bar", 4, "bar", "/foo");
+	test_join_unrooted("/foo/bar/foobar", 4, "bar/foobar", "/foo");
+	test_join_unrooted("c:/foo/bar/foobar", 6, "bar/foobar", "c:/foo");
+	test_join_unrooted("c:/foo/bar/foobar", 10, "foobar", "c:/foo/bar");
+
+	/* Absolute paths are not prepended with base */
+	test_join_unrooted("/foo", 0, "/foo", "/asdf");
+	test_join_unrooted("/foo/bar", 0, "/foo/bar", "/asdf");
+
+	/* Drive letter is given as root length on Windows */
+	test_join_unrooted("c:/foo", 2, "c:/foo", "c:/asdf");
+	test_join_unrooted("c:/foo/bar", 2, "c:/foo/bar", "c:/asdf");
+
+	/* Base is returned when it's provided and is the prefix */
+	test_join_unrooted("c:/foo/bar/foobar", 6, "c:/foo/bar/foobar", "c:/foo");
+	test_join_unrooted("c:/foo/bar/foobar", 10, "c:/foo/bar/foobar", "c:/foo/bar");
+
+	/* Trailing slash in the base is ignored */
+	test_join_unrooted("c:/foo/bar/foobar", 6, "c:/foo/bar/foobar", "c:/foo/");
+
+	git_buf_free(&out);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/path/win32.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/path/win32.c
new file mode 100755
index 0000000..4ff0397
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/path/win32.c
@@ -0,0 +1,217 @@
+
+#include "clar_libgit2.h"
+#include "path.h"
+
+#ifdef GIT_WIN32
+#include "win32/path_w32.h"
+#endif
+
+void test_utf8_to_utf16(const char *utf8_in, const wchar_t *utf16_expected)
+{
+#ifdef GIT_WIN32
+	git_win32_path path_utf16;
+	int path_utf16len;
+
+	cl_assert((path_utf16len = git_win32_path_from_utf8(path_utf16, utf8_in)) >= 0);
+	cl_assert_equal_wcs(utf16_expected, path_utf16);
+	cl_assert_equal_i(wcslen(utf16_expected), path_utf16len);
+#else
+	GIT_UNUSED(utf8_in);
+	GIT_UNUSED(utf16_expected);
+#endif
+}
+
+void test_path_win32__utf8_to_utf16(void)
+{
+#ifdef GIT_WIN32
+	test_utf8_to_utf16("C:\\", L"\\\\?\\C:\\");
+	test_utf8_to_utf16("c:\\", L"\\\\?\\c:\\");
+	test_utf8_to_utf16("C:/", L"\\\\?\\C:\\");
+	test_utf8_to_utf16("c:/", L"\\\\?\\c:\\");
+#endif
+}
+
+void test_path_win32__removes_trailing_slash(void)
+{
+#ifdef GIT_WIN32
+	test_utf8_to_utf16("C:\\Foo\\", L"\\\\?\\C:\\Foo");
+	test_utf8_to_utf16("C:\\Foo\\\\", L"\\\\?\\C:\\Foo");
+	test_utf8_to_utf16("C:\\Foo\\\\", L"\\\\?\\C:\\Foo");
+	test_utf8_to_utf16("C:/Foo/", L"\\\\?\\C:\\Foo");
+	test_utf8_to_utf16("C:/Foo///", L"\\\\?\\C:\\Foo");
+#endif
+}
+
+void test_path_win32__squashes_multiple_slashes(void)
+{
+#ifdef GIT_WIN32
+	test_utf8_to_utf16("C:\\\\Foo\\Bar\\\\Foobar", L"\\\\?\\C:\\Foo\\Bar\\Foobar");
+	test_utf8_to_utf16("C://Foo/Bar///Foobar", L"\\\\?\\C:\\Foo\\Bar\\Foobar");
+#endif
+}
+
+void test_path_win32__unc(void)
+{
+#ifdef GIT_WIN32
+	test_utf8_to_utf16("\\\\server\\c$\\unc\\path", L"\\\\?\\UNC\\server\\c$\\unc\\path");
+	test_utf8_to_utf16("//server/git/style/unc/path", L"\\\\?\\UNC\\server\\git\\style\\unc\\path");
+#endif
+}
+
+void test_path_win32__honors_max_path(void)
+{
+#ifdef GIT_WIN32
+	git_win32_path path_utf16;
+
+	test_utf8_to_utf16("C:\\This path is 259 chars and is the max length in windows\\0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij",
+		L"\\\\?\\C:\\This path is 259 chars and is the max length in windows\\0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij");
+	test_utf8_to_utf16("\\\\unc\\paths may also be 259 characters including the server\\123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij",
+		L"\\\\?\\UNC\\unc\\paths may also be 259 characters including the server\\123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij");
+
+	cl_check_fail(git_win32_path_from_utf8(path_utf16, "C:\\This path is 260 chars and is sadly too long for windows\\0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij"));
+	cl_check_fail(git_win32_path_from_utf8(path_utf16, "\\\\unc\\paths are also bound by 260 character restrictions\\including the server name portion\\bcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij"));
+#endif
+}
+
+void test_path_win32__dot_and_dotdot(void)
+{
+#ifdef GIT_WIN32
+	test_utf8_to_utf16("C:\\Foo\\..\\Foobar", L"\\\\?\\C:\\Foobar");
+	test_utf8_to_utf16("C:\\Foo\\Bar\\..\\Foobar", L"\\\\?\\C:\\Foo\\Foobar");
+	test_utf8_to_utf16("C:\\Foo\\Bar\\..\\Foobar\\..", L"\\\\?\\C:\\Foo");
+	test_utf8_to_utf16("C:\\Foobar\\..", L"\\\\?\\C:\\");
+	test_utf8_to_utf16("C:/Foo/Bar/../Foobar", L"\\\\?\\C:\\Foo\\Foobar");
+	test_utf8_to_utf16("C:/Foo/Bar/../Foobar/../Asdf/", L"\\\\?\\C:\\Foo\\Asdf");
+	test_utf8_to_utf16("C:/Foo/Bar/../Foobar/..", L"\\\\?\\C:\\Foo");
+	test_utf8_to_utf16("C:/Foo/..", L"\\\\?\\C:\\");
+
+	test_utf8_to_utf16("C:\\Foo\\Bar\\.\\Foobar", L"\\\\?\\C:\\Foo\\Bar\\Foobar");
+	test_utf8_to_utf16("C:\\.\\Foo\\.\\Bar\\.\\Foobar\\.\\", L"\\\\?\\C:\\Foo\\Bar\\Foobar");
+	test_utf8_to_utf16("C:/Foo/Bar/./Foobar", L"\\\\?\\C:\\Foo\\Bar\\Foobar");
+	test_utf8_to_utf16("C:/Foo/../Bar/./Foobar/../", L"\\\\?\\C:\\Bar");
+
+	test_utf8_to_utf16("C:\\Foo\\..\\..\\Bar", L"\\\\?\\C:\\Bar");
+#endif
+}
+
+void test_path_win32__absolute_from_no_drive_letter(void)
+{
+#ifdef GIT_WIN32
+	test_utf8_to_utf16("\\Foo", L"\\\\?\\C:\\Foo");
+	test_utf8_to_utf16("\\Foo\\Bar", L"\\\\?\\C:\\Foo\\Bar");
+	test_utf8_to_utf16("/Foo/Bar", L"\\\\?\\C:\\Foo\\Bar");
+#endif
+}
+
+void test_path_win32__absolute_from_relative(void)
+{
+#ifdef GIT_WIN32
+	char cwd_backup[MAX_PATH];
+
+	cl_must_pass(p_getcwd(cwd_backup, MAX_PATH));
+	cl_must_pass(p_chdir("C:/"));
+
+	test_utf8_to_utf16("Foo", L"\\\\?\\C:\\Foo");
+	test_utf8_to_utf16("..\\..\\Foo", L"\\\\?\\C:\\Foo");
+	test_utf8_to_utf16("Foo\\..", L"\\\\?\\C:\\");
+	test_utf8_to_utf16("Foo\\..\\..", L"\\\\?\\C:\\");
+	test_utf8_to_utf16("", L"\\\\?\\C:\\");
+
+	cl_must_pass(p_chdir("C:/Windows"));
+
+	test_utf8_to_utf16("Foo", L"\\\\?\\C:\\Windows\\Foo");
+	test_utf8_to_utf16("Foo\\Bar", L"\\\\?\\C:\\Windows\\Foo\\Bar");
+	test_utf8_to_utf16("..\\Foo", L"\\\\?\\C:\\Foo");
+	test_utf8_to_utf16("Foo\\..\\Bar", L"\\\\?\\C:\\Windows\\Bar");
+	test_utf8_to_utf16("", L"\\\\?\\C:\\Windows");
+
+	cl_must_pass(p_chdir(cwd_backup));
+#endif
+}
+
+void test_canonicalize(const wchar_t *in, const wchar_t *expected)
+{
+#ifdef GIT_WIN32
+	git_win32_path canonical;
+
+	cl_assert(wcslen(in) < MAX_PATH);
+	wcscpy(canonical, in);
+
+	cl_must_pass(git_win32_path_canonicalize(canonical));
+	cl_assert_equal_wcs(expected, canonical);
+#else
+	GIT_UNUSED(in);
+	GIT_UNUSED(expected);
+#endif
+}
+
+void test_path_win32__canonicalize(void)
+{
+#ifdef GIT_WIN32
+	test_canonicalize(L"C:\\Foo\\Bar", L"C:\\Foo\\Bar");
+	test_canonicalize(L"C:\\Foo\\", L"C:\\Foo");
+	test_canonicalize(L"C:\\Foo\\\\", L"C:\\Foo");
+	test_canonicalize(L"C:\\Foo\\..\\Bar", L"C:\\Bar");
+	test_canonicalize(L"C:\\Foo\\..\\..\\Bar", L"C:\\Bar");
+	test_canonicalize(L"C:\\Foo\\..\\..\\..\\..\\", L"C:\\");
+	test_canonicalize(L"C:/Foo/Bar", L"C:\\Foo\\Bar");
+	test_canonicalize(L"C:/", L"C:\\");
+
+	test_canonicalize(L"Foo\\\\Bar\\\\Asdf\\\\", L"Foo\\Bar\\Asdf");
+	test_canonicalize(L"Foo\\\\Bar\\\\..\\\\Asdf\\", L"Foo\\Asdf");
+	test_canonicalize(L"Foo\\\\Bar\\\\.\\\\Asdf\\", L"Foo\\Bar\\Asdf");
+	test_canonicalize(L"Foo\\\\..\\Bar\\\\.\\\\Asdf\\", L"Bar\\Asdf");
+	test_canonicalize(L"\\", L"");
+	test_canonicalize(L"", L"");
+	test_canonicalize(L"Foo\\..\\..\\..\\..", L"");
+	test_canonicalize(L"..\\..\\..\\..", L"");
+	test_canonicalize(L"\\..\\..\\..\\..", L"");
+
+	test_canonicalize(L"\\\\?\\C:\\Foo\\Bar", L"\\\\?\\C:\\Foo\\Bar");
+	test_canonicalize(L"\\\\?\\C:\\Foo\\Bar\\", L"\\\\?\\C:\\Foo\\Bar");
+	test_canonicalize(L"\\\\?\\C:\\\\Foo\\.\\Bar\\\\..\\", L"\\\\?\\C:\\Foo");
+	test_canonicalize(L"\\\\?\\C:\\\\", L"\\\\?\\C:\\");
+	test_canonicalize(L"//?/C:/", L"\\\\?\\C:\\");
+	test_canonicalize(L"//?/C:/../../Foo/", L"\\\\?\\C:\\Foo");
+	test_canonicalize(L"//?/C:/Foo/../../", L"\\\\?\\C:\\");
+
+	test_canonicalize(L"\\\\?\\UNC\\server\\C$\\folder", L"\\\\?\\UNC\\server\\C$\\folder");
+	test_canonicalize(L"\\\\?\\UNC\\server\\C$\\folder\\", L"\\\\?\\UNC\\server\\C$\\folder");
+	test_canonicalize(L"\\\\?\\UNC\\server\\C$\\folder\\", L"\\\\?\\UNC\\server\\C$\\folder");
+	test_canonicalize(L"\\\\?\\UNC\\server\\C$\\folder\\..\\..\\..\\..\\share\\", L"\\\\?\\UNC\\server\\share");
+
+	test_canonicalize(L"\\\\server\\share", L"\\\\server\\share");
+	test_canonicalize(L"\\\\server\\share\\", L"\\\\server\\share");
+	test_canonicalize(L"\\\\server\\share\\\\foo\\\\bar", L"\\\\server\\share\\foo\\bar");
+	test_canonicalize(L"\\\\server\\\\share\\\\foo\\\\bar", L"\\\\server\\share\\foo\\bar");
+	test_canonicalize(L"\\\\server\\share\\..\\foo", L"\\\\server\\foo");
+	test_canonicalize(L"\\\\server\\..\\..\\share\\.\\foo", L"\\\\server\\share\\foo");
+#endif
+}
+
+void test_path_win32__8dot3_name(void)
+{
+#ifdef GIT_WIN32
+	char *shortname;
+
+	if (!cl_sandbox_supports_8dot3())
+		clar__skip();
+
+	/* Some guaranteed short names */
+	cl_assert_equal_s("PROGRA~1", (shortname = git_win32_path_8dot3_name("C:\\Program Files")));
+	git__free(shortname);
+
+	cl_assert_equal_s("WINDOWS", (shortname = git_win32_path_8dot3_name("C:\\WINDOWS")));
+	git__free(shortname);
+
+	/* Create some predictible short names */
+	cl_must_pass(p_mkdir(".foo", 0777));
+	cl_assert_equal_s("FOO~1", (shortname = git_win32_path_8dot3_name(".foo")));
+	git__free(shortname);
+
+	cl_git_write2file("bar~1", "foobar\n", 7, O_RDWR|O_CREAT, 0666);
+	cl_must_pass(p_mkdir(".bar", 0777));
+	cl_assert_equal_s("BAR~2", (shortname = git_win32_path_8dot3_name(".bar")));
+	git__free(shortname);
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/perf/helper__perf__do_merge.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/perf/helper__perf__do_merge.c
new file mode 100755
index 0000000..c77b46a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/perf/helper__perf__do_merge.c
@@ -0,0 +1,75 @@
+#include "clar_libgit2.h"
+#include "helper__perf__do_merge.h"
+#include "helper__perf__timer.h"
+
+static git_repository * g_repo;
+
+void perf__do_merge(const char *fixture,
+					const char *test_name,
+					const char *id_a,
+					const char *id_b)
+{
+	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
+	git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT;
+	git_oid oid_a;
+	git_oid oid_b;
+	git_reference *ref_branch_a = NULL;
+	git_reference *ref_branch_b = NULL;
+	git_commit *commit_a = NULL;
+	git_commit *commit_b = NULL;
+	git_annotated_commit *annotated_commits[1] = { NULL };
+	perf_timer t_total = PERF_TIMER_INIT;
+	perf_timer t_clone = PERF_TIMER_INIT;
+	perf_timer t_checkout = PERF_TIMER_INIT;
+	perf_timer t_merge = PERF_TIMER_INIT;
+
+	perf__timer__start(&t_total);
+
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+	clone_opts.checkout_opts = checkout_opts;
+
+	perf__timer__start(&t_clone);
+	cl_git_pass(git_clone(&g_repo, fixture, test_name, &clone_opts));
+	perf__timer__stop(&t_clone);
+	
+	git_oid_fromstr(&oid_a, id_a);
+	cl_git_pass(git_commit_lookup(&commit_a, g_repo, &oid_a));
+	cl_git_pass(git_branch_create(&ref_branch_a, g_repo,
+								  "A", commit_a,
+								  0));
+
+	perf__timer__start(&t_checkout);
+	cl_git_pass(git_checkout_tree(g_repo, (git_object*)commit_a, &checkout_opts));
+	perf__timer__stop(&t_checkout);
+
+	cl_git_pass(git_repository_set_head(g_repo, git_reference_name(ref_branch_a)));
+
+	git_oid_fromstr(&oid_b, id_b);
+	cl_git_pass(git_commit_lookup(&commit_b, g_repo, &oid_b));
+	cl_git_pass(git_branch_create(&ref_branch_b, g_repo,
+								  "B", commit_b,
+								  0));
+
+	cl_git_pass(git_annotated_commit_lookup(&annotated_commits[0], g_repo, &oid_b));
+
+	perf__timer__start(&t_merge);
+	cl_git_pass(git_merge(g_repo,
+						  (const git_annotated_commit **)annotated_commits, 1,
+						  &merge_opts, &checkout_opts));
+	perf__timer__stop(&t_merge);
+
+	git_reference_free(ref_branch_a);
+	git_reference_free(ref_branch_b);
+	git_commit_free(commit_a);
+	git_commit_free(commit_b);
+	git_annotated_commit_free(annotated_commits[0]);
+	git_repository_free(g_repo);
+
+	perf__timer__stop(&t_total);
+
+	perf__timer__report(&t_clone, "%s: clone", test_name);
+	perf__timer__report(&t_checkout, "%s: checkout", test_name);
+	perf__timer__report(&t_merge, "%s: merge", test_name);
+	perf__timer__report(&t_total, "%s: total", test_name);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/perf/helper__perf__do_merge.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/perf/helper__perf__do_merge.h
new file mode 100755
index 0000000..4a4723d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/perf/helper__perf__do_merge.h
@@ -0,0 +1,4 @@
+void perf__do_merge(const char *fixture,
+					const char *test_name,
+					const char *id_a,
+					const char *id_b);
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/perf/helper__perf__timer.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/perf/helper__perf__timer.c
new file mode 100755
index 0000000..8a7ed09
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/perf/helper__perf__timer.c
@@ -0,0 +1,73 @@
+#include "clar_libgit2.h"
+#include "helper__perf__timer.h"
+
+#if defined(GIT_WIN32)
+
+void perf__timer__start(perf_timer *t)
+{
+	QueryPerformanceCounter(&t->time_started);
+}
+
+void perf__timer__stop(perf_timer *t)
+{
+	LARGE_INTEGER time_now;
+	QueryPerformanceCounter(&time_now);
+
+	t->sum.QuadPart += (time_now.QuadPart - t->time_started.QuadPart);
+}
+
+void perf__timer__report(perf_timer *t, const char *fmt, ...)
+{
+	va_list arglist;
+	LARGE_INTEGER freq;
+	double fraction;
+
+	QueryPerformanceFrequency(&freq);
+
+	fraction = ((double)t->sum.QuadPart) / ((double)freq.QuadPart);
+
+	printf("%10.3f: ", fraction);
+
+	va_start(arglist, fmt);
+	vprintf(fmt, arglist);
+	va_end(arglist);
+
+	printf("\n");
+}
+
+#else
+
+#include <sys/time.h>
+
+static uint32_t now_in_ms(void)
+{
+	struct timeval now;
+	gettimeofday(&now, NULL);
+	return (uint32_t)((now.tv_sec * 1000) + (now.tv_usec / 1000));
+}
+
+void perf__timer__start(perf_timer *t)
+{
+	t->time_started = now_in_ms();
+}
+
+void perf__timer__stop(perf_timer *t)
+{
+	uint32_t now = now_in_ms();
+	t->sum += (now - t->time_started);
+}
+
+void perf__timer__report(perf_timer *t, const char *fmt, ...)
+{
+	va_list arglist;
+
+	printf("%10.3f: ", ((double)t->sum) / 1000);
+
+	va_start(arglist, fmt);
+	vprintf(fmt, arglist);
+	va_end(arglist);
+
+	printf("\n");
+}
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/perf/helper__perf__timer.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/perf/helper__perf__timer.h
new file mode 100755
index 0000000..5aff4b1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/perf/helper__perf__timer.h
@@ -0,0 +1,27 @@
+#if defined(GIT_WIN32)
+
+struct perf__timer
+{
+	LARGE_INTEGER sum;
+	LARGE_INTEGER time_started;
+};
+
+#define PERF_TIMER_INIT {0}
+
+#else
+
+struct perf__timer
+{
+	uint32_t sum;
+	uint32_t time_started;
+};
+
+#define PERF_TIMER_INIT {0}
+
+#endif
+
+typedef struct perf__timer perf_timer;
+
+void perf__timer__start(perf_timer *t);
+void perf__timer__stop(perf_timer *t);
+void perf__timer__report(perf_timer *t, const char *fmt, ...);
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/perf/merge.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/perf/merge.c
new file mode 100755
index 0000000..b2ef082
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/perf/merge.c
@@ -0,0 +1,44 @@
+#include "clar_libgit2.h"
+#include "helper__perf__do_merge.h"
+
+/* This test requires a large repo with many files.
+ * It doesn't care about the contents, just the size.
+ * 
+ * For now, we use the LibGit2 repo containing the
+ * source tree because it is already here.
+ *
+ * `find . | wc -l` reports 5128.
+ * 
+ */
+#define SRC_REPO (cl_fixture("../.."))
+
+/* We need 2 arbitrary commits within that repo
+ * that have a large number of changed files.
+ * Again, we don't care about the actual contents,
+ * just the size.
+ *
+ * For now, we use these public branches:
+ * maint/v0.21 d853fb9f24e0fe63b3dce9fbc04fd9cfe17a030b Always checkout with case sensitive iterator
+ * maint/v0.22 1ce9ea3ba9b4fa666602d52a5281d41a482cc58b checkout tests: cleanup realpath impl on Win32
+ *
+ */
+#define ID_BRANCH_A "d853fb9f24e0fe63b3dce9fbc04fd9cfe17a030b"
+#define ID_BRANCH_B "1ce9ea3ba9b4fa666602d52a5281d41a482cc58b"
+
+
+void test_perf_merge__initialize(void)
+{
+}
+
+void test_perf_merge__cleanup(void)
+{
+}
+
+void test_perf_merge__m1(void)
+{
+#if 1
+	cl_skip();
+#else
+	perf__do_merge(SRC_REPO, "m1", ID_BRANCH_A, ID_BRANCH_B);
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/rebase/abort.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/rebase/abort.c
new file mode 100755
index 0000000..c4b3890
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/rebase/abort.c
@@ -0,0 +1,150 @@
+#include "clar_libgit2.h"
+#include "git2/rebase.h"
+#include "merge.h"
+#include "posix.h"
+#include "annotated_commit.h"
+
+#include <fcntl.h>
+
+static git_repository *repo;
+
+// Fixture setup and teardown
+void test_rebase_abort__initialize(void)
+{
+	repo = cl_git_sandbox_init("rebase");
+}
+
+void test_rebase_abort__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static void test_abort(git_annotated_commit *branch, git_annotated_commit *onto)
+{
+	git_rebase *rebase;
+	git_reference *head_ref, *branch_ref = NULL;
+	git_status_list *statuslist;
+	git_reflog *reflog;
+	const git_reflog_entry *reflog_entry;
+
+	cl_git_pass(git_rebase_open(&rebase, repo, NULL));
+	cl_git_pass(git_rebase_abort(rebase));
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));
+
+	/* Make sure the refs are updated appropriately */
+	cl_git_pass(git_reference_lookup(&head_ref, repo, "HEAD"));
+
+	if (branch->ref_name == NULL)
+		cl_assert_equal_oid(git_annotated_commit_id(branch), git_reference_target(head_ref));
+	else {
+		cl_assert_equal_s("refs/heads/beef", git_reference_symbolic_target(head_ref));
+		cl_git_pass(git_reference_lookup(&branch_ref, repo, git_reference_symbolic_target(head_ref)));
+		cl_assert_equal_oid(git_annotated_commit_id(branch), git_reference_target(branch_ref));
+	}
+
+	git_status_list_new(&statuslist, repo, NULL);
+	cl_assert_equal_i(0, git_status_list_entrycount(statuslist));
+	git_status_list_free(statuslist);
+
+	/* Make sure the reflogs are updated appropriately */
+	cl_git_pass(git_reflog_read(&reflog, repo, "HEAD"));
+
+	cl_assert(reflog_entry = git_reflog_entry_byindex(reflog, 0));
+	cl_assert_equal_oid(git_annotated_commit_id(onto), git_reflog_entry_id_old(reflog_entry));
+	cl_assert_equal_oid(git_annotated_commit_id(branch), git_reflog_entry_id_new(reflog_entry));
+	cl_assert_equal_s("rebase: aborting", git_reflog_entry_message(reflog_entry));
+
+	git_reflog_free(reflog);
+	git_reference_free(head_ref);
+	git_reference_free(branch_ref);
+	git_rebase_free(rebase);
+}
+
+void test_rebase_abort__merge(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *onto_ref;
+	git_annotated_commit *branch_head, *onto_head;
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
+	cl_git_pass(git_reference_lookup(&onto_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&onto_head, repo, onto_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, NULL, onto_head, NULL));
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
+
+	test_abort(branch_head, onto_head);
+
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(onto_head);
+
+	git_reference_free(branch_ref);
+	git_reference_free(onto_ref);
+	git_rebase_free(rebase);
+}
+
+void test_rebase_abort__detached_head(void)
+{
+	git_rebase *rebase;
+	git_oid branch_id;
+	git_reference *onto_ref;
+	git_signature *signature;
+	git_annotated_commit *branch_head, *onto_head;
+
+	git_oid_fromstr(&branch_id, "b146bd7608eac53d9bf9e1a6963543588b555c64");
+	cl_git_pass(git_reference_lookup(&onto_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_lookup(&branch_head, repo, &branch_id));
+	cl_git_pass(git_annotated_commit_from_ref(&onto_head, repo, onto_ref));
+
+	cl_git_pass(git_signature_new(&signature, "Rebaser", "rebaser at example.com", 1404157834, -400));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, NULL, onto_head, NULL));
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
+
+	test_abort(branch_head, onto_head);
+
+	git_signature_free(signature);
+
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(onto_head);
+
+	git_reference_free(onto_ref);
+	git_rebase_free(rebase);
+}
+
+void test_rebase_abort__old_style_head_file(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *onto_ref;
+	git_signature *signature;
+	git_annotated_commit *branch_head, *onto_head;
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
+	cl_git_pass(git_reference_lookup(&onto_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&onto_head, repo, onto_ref));
+
+	cl_git_pass(git_signature_new(&signature, "Rebaser", "rebaser at example.com", 1404157834, -400));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, NULL, onto_head, NULL));
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
+
+	p_rename("rebase-merge/.git/rebase-merge/orig-head",
+		"rebase-merge/.git/rebase-merge/head");
+
+	test_abort(branch_head, onto_head);
+
+	git_signature_free(signature);
+
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(onto_head);
+
+	git_reference_free(branch_ref);
+	git_reference_free(onto_ref);
+	git_rebase_free(rebase);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/rebase/iterator.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/rebase/iterator.c
new file mode 100755
index 0000000..acf2a92
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/rebase/iterator.c
@@ -0,0 +1,106 @@
+#include "clar_libgit2.h"
+#include "git2/rebase.h"
+#include "posix.h"
+
+#include <fcntl.h>
+
+static git_repository *repo;
+static git_index *_index;
+static git_signature *signature;
+
+// Fixture setup and teardown
+void test_rebase_iterator__initialize(void)
+{
+	repo = cl_git_sandbox_init("rebase");
+	cl_git_pass(git_repository_index(&_index, repo));
+	cl_git_pass(git_signature_now(&signature, "Rebaser", "rebaser at rebaser.rb"));
+}
+
+void test_rebase_iterator__cleanup(void)
+{
+	git_signature_free(signature);
+	git_index_free(_index);
+	cl_git_sandbox_cleanup();
+}
+
+static void test_operations(git_rebase *rebase, size_t expected_current)
+{
+	size_t i, expected_count = 5;
+	git_oid expected_oid[5];
+	git_rebase_operation *operation;
+
+	git_oid_fromstr(&expected_oid[0], "da9c51a23d02d931a486f45ad18cda05cf5d2b94");
+	git_oid_fromstr(&expected_oid[1], "8d1f13f93c4995760ac07d129246ac1ff64c0be9");
+	git_oid_fromstr(&expected_oid[2], "3069cc907e6294623e5917ef6de663928c1febfb");
+	git_oid_fromstr(&expected_oid[3], "588e5d2f04d49707fe4aab865e1deacaf7ef6787");
+	git_oid_fromstr(&expected_oid[4], "b146bd7608eac53d9bf9e1a6963543588b555c64");
+
+	cl_assert_equal_i(expected_count, git_rebase_operation_entrycount(rebase));
+	cl_assert_equal_i(expected_current, git_rebase_operation_current(rebase));
+
+	for (i = 0; i < expected_count; i++) {
+		operation = git_rebase_operation_byindex(rebase, i);
+		cl_assert_equal_i(GIT_REBASE_OPERATION_PICK, operation->type);
+		cl_assert_equal_oid(&expected_oid[i], &operation->id);
+		cl_assert_equal_p(NULL, operation->exec);
+	}
+}
+
+void test_rebase_iterator__iterates(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+	git_rebase_operation *rebase_operation;
+	git_oid commit_id;
+	int error;
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));
+	test_operations(rebase, GIT_REBASE_NO_OPERATION);
+	git_rebase_free(rebase);
+
+	cl_git_pass(git_rebase_open(&rebase, repo, NULL));
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+	test_operations(rebase, 0);
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+	test_operations(rebase, 1);
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+	test_operations(rebase, 2);
+
+	git_rebase_free(rebase);
+	cl_git_pass(git_rebase_open(&rebase, repo, NULL));
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+	test_operations(rebase, 3);
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+	test_operations(rebase, 4);
+
+	cl_git_fail(error = git_rebase_next(&rebase_operation, rebase));
+	cl_assert_equal_i(GIT_ITEROVER, error);
+	test_operations(rebase, 4);
+
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/rebase/merge.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/rebase/merge.c
new file mode 100755
index 0000000..33eadb7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/rebase/merge.c
@@ -0,0 +1,567 @@
+#include "clar_libgit2.h"
+#include "git2/rebase.h"
+#include "posix.h"
+#include "signature.h"
+
+#include <fcntl.h>
+
+static git_repository *repo;
+static git_signature *signature;
+
+static void set_core_autocrlf_to(git_repository *repo, bool value)
+{
+	git_config *cfg;
+
+	cl_git_pass(git_repository_config(&cfg, repo));
+	cl_git_pass(git_config_set_bool(cfg, "core.autocrlf", value));
+
+	git_config_free(cfg);
+}
+
+// Fixture setup and teardown
+void test_rebase_merge__initialize(void)
+{
+	repo = cl_git_sandbox_init("rebase");
+	cl_git_pass(git_signature_new(&signature,
+		"Rebaser", "rebaser at rebaser.rb", 1405694510, 0));
+
+	set_core_autocrlf_to(repo, false);
+}
+
+void test_rebase_merge__cleanup(void)
+{
+	git_signature_free(signature);
+	cl_git_sandbox_cleanup();
+}
+
+void test_rebase_merge__next(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+	git_rebase_operation *rebase_operation;
+	git_status_list *status_list;
+	const git_status_entry *status_entry;
+	git_oid pick_id, file1_id;
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+
+	git_oid_fromstr(&pick_id, "da9c51a23d02d931a486f45ad18cda05cf5d2b94");
+
+	cl_assert_equal_i(GIT_REBASE_OPERATION_PICK, rebase_operation->type);
+	cl_assert_equal_oid(&pick_id, &rebase_operation->id);
+	cl_assert_equal_file("da9c51a23d02d931a486f45ad18cda05cf5d2b94\n", 41, "rebase/.git/rebase-merge/current");
+	cl_assert_equal_file("1\n", 2, "rebase/.git/rebase-merge/msgnum");
+
+	cl_git_pass(git_status_list_new(&status_list, repo, NULL));
+	cl_assert_equal_i(1, git_status_list_entrycount(status_list));
+	cl_assert(status_entry = git_status_byindex(status_list, 0));
+
+	cl_assert_equal_s("beef.txt", status_entry->head_to_index->new_file.path);
+
+	git_oid_fromstr(&file1_id, "8d95ea62e621f1d38d230d9e7d206e41096d76af");
+	cl_assert_equal_oid(&file1_id, &status_entry->head_to_index->new_file.id);
+
+	git_status_list_free(status_list);
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
+
+void test_rebase_merge__next_with_conflicts(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+	git_rebase_operation *rebase_operation;
+	git_status_list *status_list;
+	const git_status_entry *status_entry;
+	git_oid pick_id, commit_id;
+
+	const char *expected_merge =
+"ASPARAGUS SOUP.\n"
+"\n"
+"<<<<<<< master\n"
+"TAKE FOUR LARGE BUNCHES of asparagus, scrape it nicely, cut off one inch\n"
+"OF THE TOPS, and lay them in water, chop the stalks and put them on the\n"
+"FIRE WITH A PIECE OF BACON, a large onion cut up, and pepper and salt;\n"
+"ADD TWO QUARTS OF WATER, boil them till the stalks are quite soft, then\n"
+"PULP THEM THROUGH A SIEVE, and strain the water to it, which must be put\n"
+"=======\n"
+"Take four large bunches of asparagus, scrape it nicely, CUT OFF ONE INCH\n"
+"of the tops, and lay them in water, chop the stalks and PUT THEM ON THE\n"
+"fire with a piece of bacon, a large onion cut up, and pepper and salt;\n"
+"add two quarts of water, boil them till the stalks are quite soft, then\n"
+"pulp them through a sieve, and strain the water to it, which must be put\n"
+">>>>>>> Conflicting modification 1 to asparagus\n"
+"back in the pot; put into it a chicken cut up, with the tops of\n"
+"asparagus which had been laid by, boil it until these last articles are\n"
+"sufficiently done, thicken with flour, butter and milk, and serve it up.\n";
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/asparagus"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+
+	git_oid_fromstr(&pick_id, "33f915f9e4dbd9f4b24430e48731a59b45b15500");
+
+	cl_assert_equal_i(GIT_REBASE_OPERATION_PICK, rebase_operation->type);
+	cl_assert_equal_oid(&pick_id, &rebase_operation->id);
+	cl_assert_equal_file("33f915f9e4dbd9f4b24430e48731a59b45b15500\n", 41, "rebase/.git/rebase-merge/current");
+	cl_assert_equal_file("1\n", 2, "rebase/.git/rebase-merge/msgnum");
+
+	cl_git_pass(git_status_list_new(&status_list, repo, NULL));
+	cl_assert_equal_i(1, git_status_list_entrycount(status_list));
+	cl_assert(status_entry = git_status_byindex(status_list, 0));
+
+	cl_assert_equal_s("asparagus.txt", status_entry->head_to_index->new_file.path);
+
+	cl_assert_equal_file(expected_merge, strlen(expected_merge), "rebase/asparagus.txt");
+
+	cl_git_fail_with(GIT_EUNMERGED, git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL));
+
+	git_status_list_free(status_list);
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
+
+void test_rebase_merge__next_stops_with_iterover(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+	git_rebase_operation *rebase_operation;
+	git_oid commit_id;
+	int error;
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+
+	cl_git_fail(error = git_rebase_next(&rebase_operation, rebase));
+	cl_assert_equal_i(GIT_ITEROVER, error);
+
+	cl_assert_equal_file("5\n", 2, "rebase/.git/rebase-merge/end");
+	cl_assert_equal_file("5\n", 2, "rebase/.git/rebase-merge/msgnum");
+
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
+
+void test_rebase_merge__commit(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+	git_rebase_operation *rebase_operation;
+	git_oid commit_id, tree_id, parent_id;
+	git_signature *author;
+	git_commit *commit;
+	git_reflog *reflog;
+	const git_reflog_entry *reflog_entry;
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+
+	cl_git_pass(git_commit_lookup(&commit, repo, &commit_id));
+
+	git_oid_fromstr(&parent_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
+	cl_assert_equal_i(1, git_commit_parentcount(commit));
+	cl_assert_equal_oid(&parent_id, git_commit_parent_id(commit, 0));
+
+	git_oid_fromstr(&tree_id, "4461379789c777d2a6c1f2ee0e9d6c86731b9992");
+	cl_assert_equal_oid(&tree_id, git_commit_tree_id(commit));
+
+	cl_assert_equal_s(NULL, git_commit_message_encoding(commit));
+	cl_assert_equal_s("Modification 1 to beef\n", git_commit_message(commit));
+
+	cl_git_pass(git_signature_new(&author,
+		"Edward Thomson", "ethomson at edwardthomson.com", 1405621769, 0-(4*60)));
+	cl_assert(git_signature__equal(author, git_commit_author(commit)));
+
+	cl_assert(git_signature__equal(signature, git_commit_committer(commit)));
+
+	/* Make sure the reflogs are updated appropriately */
+	cl_git_pass(git_reflog_read(&reflog, repo, "HEAD"));
+	cl_assert(reflog_entry = git_reflog_entry_byindex(reflog, 0));
+	cl_assert_equal_oid(&parent_id, git_reflog_entry_id_old(reflog_entry));
+	cl_assert_equal_oid(&commit_id, git_reflog_entry_id_new(reflog_entry));
+	cl_assert_equal_s("rebase: Modification 1 to beef", git_reflog_entry_message(reflog_entry));
+
+	git_reflog_free(reflog);
+	git_signature_free(author);
+	git_commit_free(commit);
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
+
+void test_rebase_merge__blocked_when_dirty(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+	git_rebase_operation *rebase_operation;
+	git_oid commit_id;
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));
+
+	/* Allow untracked files */
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_mkfile("rebase/untracked_file.txt", "This is untracked\n");
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+
+	/* Do not allow unstaged */
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_mkfile("rebase/veal.txt", "This is an unstaged change\n");
+	cl_git_fail_with(GIT_EUNMERGED, git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
+
+void test_rebase_merge__commit_updates_rewritten(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+	git_rebase_operation *rebase_operation;
+	git_oid commit_id;
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+
+	cl_assert_equal_file(
+		"da9c51a23d02d931a486f45ad18cda05cf5d2b94 776e4c48922799f903f03f5f6e51da8b01e4cce0\n"
+		"8d1f13f93c4995760ac07d129246ac1ff64c0be9 ba1f9b4fd5cf8151f7818be2111cc0869f1eb95a\n",
+		164, "rebase/.git/rebase-merge/rewritten");
+
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
+
+void test_rebase_merge__commit_drops_already_applied(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+	git_rebase_operation *rebase_operation;
+	git_oid commit_id;
+	int error;
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/green_pea"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_fail(error = git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+
+	cl_assert_equal_i(GIT_EAPPLIED, error);
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+
+	cl_assert_equal_file(
+		"8d1f13f93c4995760ac07d129246ac1ff64c0be9 2ac4fb7b74c1287f6c792acad759e1ec01e18dae\n",
+		82, "rebase/.git/rebase-merge/rewritten");
+
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
+
+void test_rebase_merge__finish(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref, *head_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+	git_rebase_operation *rebase_operation;
+	git_oid commit_id;
+	git_reflog *reflog;
+	const git_reflog_entry *reflog_entry;
+	int error;
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/gravy"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/veal"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+
+	cl_git_fail(error = git_rebase_next(&rebase_operation, rebase));
+	cl_assert_equal_i(GIT_ITEROVER, error);
+
+	cl_git_pass(git_rebase_finish(rebase, signature));
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));
+
+	cl_git_pass(git_reference_lookup(&head_ref, repo, "HEAD"));
+	cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head_ref));
+	cl_assert_equal_s("refs/heads/gravy", git_reference_symbolic_target(head_ref));
+
+	/* Make sure the reflogs are updated appropriately */
+	cl_git_pass(git_reflog_read(&reflog, repo, "HEAD"));
+	cl_assert(reflog_entry = git_reflog_entry_byindex(reflog, 0));
+	cl_assert_equal_oid(&commit_id, git_reflog_entry_id_old(reflog_entry));
+	cl_assert_equal_oid(&commit_id, git_reflog_entry_id_new(reflog_entry));
+	cl_assert_equal_s("rebase finished: returning to refs/heads/gravy", git_reflog_entry_message(reflog_entry));
+	git_reflog_free(reflog);
+
+	cl_git_pass(git_reflog_read(&reflog, repo, "refs/heads/gravy"));
+	cl_assert(reflog_entry = git_reflog_entry_byindex(reflog, 0));
+	cl_assert_equal_oid(git_annotated_commit_id(branch_head), git_reflog_entry_id_old(reflog_entry));
+	cl_assert_equal_oid(&commit_id, git_reflog_entry_id_new(reflog_entry));
+	cl_assert_equal_s("rebase finished: refs/heads/gravy onto f87d14a4a236582a0278a916340a793714256864", git_reflog_entry_message(reflog_entry));
+
+	git_reflog_free(reflog);
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(head_ref);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
+
+static void test_copy_note(
+	const git_rebase_options *opts,
+	bool should_exist)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+	git_commit *branch_commit;
+	git_rebase_operation *rebase_operation;
+	git_oid note_id, commit_id;
+	git_note *note = NULL;
+	int error;
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/gravy"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/veal"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	cl_git_pass(git_reference_peel((git_object **)&branch_commit,
+		branch_ref, GIT_OBJ_COMMIT));
+
+	/* Add a note to a commit */
+	cl_git_pass(git_note_create(&note_id, repo, "refs/notes/test",
+		git_commit_author(branch_commit), git_commit_committer(branch_commit),
+		git_commit_id(branch_commit),
+		"This is a commit note.", 0));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, opts));
+
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
+		NULL, NULL));
+
+	cl_git_pass(git_rebase_finish(rebase, signature));
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));
+
+	if (should_exist) {
+		cl_git_pass(git_note_read(&note, repo, "refs/notes/test", &commit_id));
+		cl_assert_equal_s("This is a commit note.", git_note_message(note));
+	} else {
+		cl_git_fail(error =
+			git_note_read(&note, repo, "refs/notes/test", &commit_id));
+		cl_assert_equal_i(GIT_ENOTFOUND, error);
+	}
+
+	git_note_free(note);
+	git_commit_free(branch_commit);
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
+
+void test_rebase_merge__copy_notes_off_by_default(void)
+{
+	test_copy_note(NULL, 0);
+}
+
+void test_rebase_merge__copy_notes_specified_in_options(void)
+{
+	git_rebase_options opts = GIT_REBASE_OPTIONS_INIT;
+	opts.rewrite_notes_ref = "refs/notes/test";
+
+	test_copy_note(&opts, 1);
+}
+
+void test_rebase_merge__copy_notes_specified_in_config(void)
+{
+	git_config *config;
+
+	cl_git_pass(git_repository_config(&config, repo));
+	cl_git_pass(git_config_set_string(config,
+		"notes.rewriteRef", "refs/notes/test"));
+
+	test_copy_note(NULL, 1);
+}
+
+void test_rebase_merge__copy_notes_disabled_in_config(void)
+{
+	git_config *config;
+
+	cl_git_pass(git_repository_config(&config, repo));
+	cl_git_pass(git_config_set_bool(config, "notes.rewrite.rebase", 0));
+	cl_git_pass(git_config_set_string(config,
+		"notes.rewriteRef", "refs/notes/test"));
+
+	test_copy_note(NULL, 0);
+}
+
+void rebase_checkout_progress_cb(
+	const char *path,
+	size_t completed_steps,
+	size_t total_steps,
+	void *payload)
+{
+	int *called = payload;
+
+	GIT_UNUSED(path);
+	GIT_UNUSED(completed_steps);
+	GIT_UNUSED(total_steps);
+
+	*called = 1;
+}
+
+void test_rebase_merge__custom_checkout_options(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+	git_rebase_options rebase_options = GIT_REBASE_OPTIONS_INIT;
+	git_checkout_options checkout_options = GIT_CHECKOUT_OPTIONS_INIT;
+	git_rebase_operation *rebase_operation;
+	int called = 0;
+
+	checkout_options.progress_cb = rebase_checkout_progress_cb;
+	checkout_options.progress_payload = &called;
+
+	memcpy(&rebase_options.checkout_options, &checkout_options,
+		sizeof(git_checkout_options));
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	called = 0;
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, &rebase_options));
+	cl_assert_equal_i(1, called);
+
+	called = 0;
+	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
+	cl_assert_equal_i(1, called);
+
+	called = 0;
+	cl_git_pass(git_rebase_abort(rebase));
+	cl_assert_equal_i(1, called);
+
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/rebase/setup.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/rebase/setup.c
new file mode 100755
index 0000000..627d3b9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/rebase/setup.c
@@ -0,0 +1,391 @@
+#include "clar_libgit2.h"
+#include "git2/rebase.h"
+#include "posix.h"
+
+#include <fcntl.h>
+
+static git_repository *repo;
+static git_index *_index;
+static git_signature *signature;
+
+// Fixture setup and teardown
+void test_rebase_setup__initialize(void)
+{
+	repo = cl_git_sandbox_init("rebase");
+	cl_git_pass(git_repository_index(&_index, repo));
+	cl_git_pass(git_signature_now(&signature, "Rebaser", "rebaser at rebaser.rb"));
+}
+
+void test_rebase_setup__cleanup(void)
+{
+	git_signature_free(signature);
+	git_index_free(_index);
+	cl_git_sandbox_cleanup();
+}
+
+/* git checkout beef ; git rebase --merge master
+ * git checkout beef ; git rebase --merge master */
+void test_rebase_setup__blocked_when_in_progress(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));
+	git_rebase_free(rebase);
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
+
+	cl_git_fail(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));
+
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+}
+
+/* git checkout beef ; git rebase --merge master */
+void test_rebase_setup__merge(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+	git_reference *head;
+	git_commit *head_commit;
+	git_oid head_id;
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
+
+	git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJ_COMMIT));
+	cl_assert_equal_oid(&head_id, git_commit_id(head_commit));
+
+	cl_assert_equal_file("b146bd7608eac53d9bf9e1a6963543588b555c64\n", 41, "rebase/.git/ORIG_HEAD");
+
+	cl_assert_equal_file("da9c51a23d02d931a486f45ad18cda05cf5d2b94\n", 41, "rebase/.git/rebase-merge/cmt.1");
+	cl_assert_equal_file("8d1f13f93c4995760ac07d129246ac1ff64c0be9\n", 41, "rebase/.git/rebase-merge/cmt.2");
+	cl_assert_equal_file("3069cc907e6294623e5917ef6de663928c1febfb\n", 41, "rebase/.git/rebase-merge/cmt.3");
+	cl_assert_equal_file("588e5d2f04d49707fe4aab865e1deacaf7ef6787\n", 41, "rebase/.git/rebase-merge/cmt.4");
+	cl_assert_equal_file("b146bd7608eac53d9bf9e1a6963543588b555c64\n", 41, "rebase/.git/rebase-merge/cmt.5");
+	cl_assert_equal_file("5\n", 2, "rebase/.git/rebase-merge/end");
+	cl_assert_equal_file("efad0b11c47cb2f0220cbd6f5b0f93bb99064b00\n", 41, "rebase/.git/rebase-merge/onto");
+	cl_assert_equal_file("master\n", 7, "rebase/.git/rebase-merge/onto_name");
+	cl_assert_equal_file("b146bd7608eac53d9bf9e1a6963543588b555c64\n", 41, "rebase/.git/rebase-merge/orig-head");
+
+	git_commit_free(head_commit);
+	git_reference_free(head);
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
+
+/* git checkout beef && git rebase --merge --root --onto master */
+void test_rebase_setup__merge_root(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *onto_ref;
+	git_annotated_commit *branch_head, *onto_head;
+	git_reference *head;
+	git_commit *head_commit;
+	git_oid head_id;
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
+	cl_git_pass(git_reference_lookup(&onto_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&onto_head, repo, onto_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, NULL, onto_head, NULL));
+
+	git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJ_COMMIT));
+	cl_assert_equal_oid(&head_id, git_commit_id(head_commit));
+
+	cl_assert_equal_file("b146bd7608eac53d9bf9e1a6963543588b555c64\n", 41, "rebase/.git/ORIG_HEAD");
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
+
+	cl_assert_equal_file("da9c51a23d02d931a486f45ad18cda05cf5d2b94\n", 41, "rebase/.git/rebase-merge/cmt.1");
+	cl_assert_equal_file("8d1f13f93c4995760ac07d129246ac1ff64c0be9\n", 41, "rebase/.git/rebase-merge/cmt.2");
+	cl_assert_equal_file("3069cc907e6294623e5917ef6de663928c1febfb\n", 41, "rebase/.git/rebase-merge/cmt.3");
+	cl_assert_equal_file("588e5d2f04d49707fe4aab865e1deacaf7ef6787\n", 41, "rebase/.git/rebase-merge/cmt.4");
+	cl_assert_equal_file("b146bd7608eac53d9bf9e1a6963543588b555c64\n", 41, "rebase/.git/rebase-merge/cmt.5");
+	cl_assert_equal_file("5\n", 2, "rebase/.git/rebase-merge/end");
+	cl_assert_equal_file("efad0b11c47cb2f0220cbd6f5b0f93bb99064b00\n", 41, "rebase/.git/rebase-merge/onto");
+	cl_assert_equal_file("master\n", 7, "rebase/.git/rebase-merge/onto_name");
+	cl_assert_equal_file("b146bd7608eac53d9bf9e1a6963543588b555c64\n", 41, "rebase/.git/rebase-merge/orig-head");
+
+	git_commit_free(head_commit);
+	git_reference_free(head);
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(onto_head);
+	git_reference_free(branch_ref);
+	git_reference_free(onto_ref);
+	git_rebase_free(rebase);
+}
+
+/* git checkout gravy && git rebase --merge --onto master veal */
+void test_rebase_setup__merge_onto_and_upstream(void)
+{
+	git_rebase *rebase;
+	git_reference *branch1_ref, *branch2_ref, *onto_ref;
+	git_annotated_commit *branch1_head, *branch2_head, *onto_head;
+	git_reference *head;
+	git_commit *head_commit;
+	git_oid head_id;
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));
+
+	cl_git_pass(git_reference_lookup(&branch1_ref, repo, "refs/heads/gravy"));
+	cl_git_pass(git_reference_lookup(&branch2_ref, repo, "refs/heads/veal"));
+	cl_git_pass(git_reference_lookup(&onto_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch1_head, repo, branch1_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&branch2_head, repo, branch2_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&onto_head, repo, onto_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch1_head, branch2_head, onto_head, NULL));
+
+	git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJ_COMMIT));
+	cl_assert_equal_oid(&head_id, git_commit_id(head_commit));
+
+	cl_assert_equal_file("d616d97082eb7bb2dc6f180a7cca940993b7a56f\n", 41, "rebase/.git/ORIG_HEAD");
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
+
+	cl_assert_equal_file("d616d97082eb7bb2dc6f180a7cca940993b7a56f\n", 41, "rebase/.git/rebase-merge/cmt.1");
+	cl_assert_equal_file("1\n", 2, "rebase/.git/rebase-merge/end");
+	cl_assert_equal_file("efad0b11c47cb2f0220cbd6f5b0f93bb99064b00\n", 41, "rebase/.git/rebase-merge/onto");
+	cl_assert_equal_file("master\n", 7, "rebase/.git/rebase-merge/onto_name");
+	cl_assert_equal_file("d616d97082eb7bb2dc6f180a7cca940993b7a56f\n", 41, "rebase/.git/rebase-merge/orig-head");
+
+	git_commit_free(head_commit);
+	git_reference_free(head);
+	git_annotated_commit_free(branch1_head);
+	git_annotated_commit_free(branch2_head);
+	git_annotated_commit_free(onto_head);
+	git_reference_free(branch1_ref);
+	git_reference_free(branch2_ref);
+	git_reference_free(onto_ref);
+	git_rebase_free(rebase);
+}
+
+/* Ensure merge commits are dropped in a rebase */
+/* git checkout veal && git rebase --merge master */
+void test_rebase_setup__branch_with_merges(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+	git_reference *head;
+	git_commit *head_commit;
+	git_oid head_id;
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/veal"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
+
+	git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJ_COMMIT));
+	cl_assert_equal_oid(&head_id, git_commit_id(head_commit));
+
+	cl_assert_equal_file("f87d14a4a236582a0278a916340a793714256864\n", 41, "rebase/.git/ORIG_HEAD");
+
+	cl_assert_equal_file("4bed71df7017283cac61bbf726197ad6a5a18b84\n", 41, "rebase/.git/rebase-merge/cmt.1");
+	cl_assert_equal_file("2aa3ce842094e08ebac152b3d6d5b0fff39f9c6e\n", 41, "rebase/.git/rebase-merge/cmt.2");
+	cl_assert_equal_file("3e8989b5a16d5258c935d998ef0e6bb139cc4757\n", 41, "rebase/.git/rebase-merge/cmt.3");
+	cl_assert_equal_file("4cacc6f6e740a5bc64faa33e04b8ef0733d8a127\n", 41, "rebase/.git/rebase-merge/cmt.4");
+	cl_assert_equal_file("f87d14a4a236582a0278a916340a793714256864\n", 41, "rebase/.git/rebase-merge/cmt.5");
+	cl_assert_equal_file("5\n", 2, "rebase/.git/rebase-merge/end");
+	cl_assert_equal_file("efad0b11c47cb2f0220cbd6f5b0f93bb99064b00\n", 41, "rebase/.git/rebase-merge/onto");
+	cl_assert_equal_file("master\n", 7, "rebase/.git/rebase-merge/onto_name");
+	cl_assert_equal_file("f87d14a4a236582a0278a916340a793714256864\n", 41, "rebase/.git/rebase-merge/orig-head");
+
+	git_commit_free(head_commit);
+	git_reference_free(head);
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
+
+/* git checkout barley && git rebase --merge master */
+void test_rebase_setup__orphan_branch(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+	git_reference *head;
+	git_commit *head_commit;
+	git_oid head_id;
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/barley"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
+
+	git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJ_COMMIT));
+	cl_assert_equal_oid(&head_id, git_commit_id(head_commit));
+
+	cl_assert_equal_file("12c084412b952396962eb420716df01022b847cc\n", 41, "rebase/.git/ORIG_HEAD");
+
+	cl_assert_equal_file("aa4c42aecdfc7cd989bbc3209934ea7cda3f4d88\n", 41, "rebase/.git/rebase-merge/cmt.1");
+	cl_assert_equal_file("e4f809f826c1a9fc929874bc0e4644dd2f2a1af4\n", 41, "rebase/.git/rebase-merge/cmt.2");
+	cl_assert_equal_file("9539b2cc291d6a6b1b266df8474d31fdd344dd79\n", 41, "rebase/.git/rebase-merge/cmt.3");
+	cl_assert_equal_file("013cc32d341bab0e6f039f50f153c18986f16c58\n", 41, "rebase/.git/rebase-merge/cmt.4");
+	cl_assert_equal_file("12c084412b952396962eb420716df01022b847cc\n", 41, "rebase/.git/rebase-merge/cmt.5");
+	cl_assert_equal_file("5\n", 2, "rebase/.git/rebase-merge/end");
+	cl_assert_equal_file("efad0b11c47cb2f0220cbd6f5b0f93bb99064b00\n", 41, "rebase/.git/rebase-merge/onto");
+	cl_assert_equal_file("master\n", 7, "rebase/.git/rebase-merge/onto_name");
+	cl_assert_equal_file("12c084412b952396962eb420716df01022b847cc\n", 41, "rebase/.git/rebase-merge/orig-head");
+
+	git_commit_free(head_commit);
+	git_reference_free(head);
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
+
+/* git checkout beef && git rebase --merge master */
+void test_rebase_setup__merge_null_branch_uses_HEAD(void)
+{
+	git_rebase *rebase;
+	git_reference *upstream_ref;
+	git_annotated_commit *upstream_head;
+	git_reference *head;
+	git_commit *head_commit;
+	git_oid head_id;
+	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
+
+	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));
+
+	cl_git_pass(git_repository_set_head(repo, "refs/heads/beef"));
+	cl_git_pass(git_checkout_head(repo, &checkout_opts));
+
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	cl_git_pass(git_rebase_init(&rebase, repo, NULL, upstream_head, NULL, NULL));
+
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
+
+	git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJ_COMMIT));
+	cl_assert_equal_oid(&head_id, git_commit_id(head_commit));
+
+	cl_assert_equal_file("b146bd7608eac53d9bf9e1a6963543588b555c64\n", 41, "rebase/.git/ORIG_HEAD");
+
+	cl_assert_equal_file("da9c51a23d02d931a486f45ad18cda05cf5d2b94\n", 41, "rebase/.git/rebase-merge/cmt.1");
+	cl_assert_equal_file("8d1f13f93c4995760ac07d129246ac1ff64c0be9\n", 41, "rebase/.git/rebase-merge/cmt.2");
+	cl_assert_equal_file("3069cc907e6294623e5917ef6de663928c1febfb\n", 41, "rebase/.git/rebase-merge/cmt.3");
+	cl_assert_equal_file("588e5d2f04d49707fe4aab865e1deacaf7ef6787\n", 41, "rebase/.git/rebase-merge/cmt.4");
+	cl_assert_equal_file("b146bd7608eac53d9bf9e1a6963543588b555c64\n", 41, "rebase/.git/rebase-merge/cmt.5");
+	cl_assert_equal_file("5\n", 2, "rebase/.git/rebase-merge/end");
+	cl_assert_equal_file("efad0b11c47cb2f0220cbd6f5b0f93bb99064b00\n", 41, "rebase/.git/rebase-merge/onto");
+	cl_assert_equal_file("master\n", 7, "rebase/.git/rebase-merge/onto_name");
+	cl_assert_equal_file("b146bd7608eac53d9bf9e1a6963543588b555c64\n", 41, "rebase/.git/rebase-merge/orig-head");
+
+	git_commit_free(head_commit);
+	git_reference_free(head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
+
+static int rebase_is_blocked(void)
+{
+	git_rebase *rebase = NULL;
+	int error;
+
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+				 
+	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));
+						  
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
+								   
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+												    
+	error = git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL);
+
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+
+	return error;
+}
+
+void test_rebase_setup__blocked_for_staged_change(void)
+{
+	cl_git_rewritefile("rebase/newfile.txt", "Stage an add");
+	git_index_add_bypath(_index, "newfile.txt");
+	cl_git_fail(rebase_is_blocked());
+}
+
+void test_rebase_setup__blocked_for_unstaged_change(void)
+{
+	cl_git_rewritefile("rebase/asparagus.txt", "Unstaged change");
+	cl_git_fail(rebase_is_blocked());
+}
+
+void test_rebase_setup__not_blocked_for_untracked_add(void)
+{
+	cl_git_rewritefile("rebase/newfile.txt", "Untracked file");
+	cl_git_pass(rebase_is_blocked());
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/create.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/create.c
new file mode 100755
index 0000000..31dec06
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/create.c
@@ -0,0 +1,300 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+#include "path.h"
+
+static git_repository *repo;
+static git_commit *target;
+static git_reference *branch;
+
+void test_refs_branches_create__initialize(void)
+{
+	repo = cl_git_sandbox_init("testrepo.git");
+	branch = NULL;
+	target = NULL;
+}
+
+void test_refs_branches_create__cleanup(void)
+{
+	git_reference_free(branch);
+	branch = NULL;
+
+	git_commit_free(target);
+	target = NULL;
+
+	cl_git_sandbox_cleanup();
+	repo = NULL;
+}
+
+static void retrieve_target_from_oid(git_commit **out, git_repository *repo, const char *sha)
+{
+	git_object *obj;
+
+	cl_git_pass(git_revparse_single(&obj, repo, sha));
+	cl_git_pass(git_commit_lookup(out, repo, git_object_id(obj)));
+	git_object_free(obj);
+}
+
+static void retrieve_known_commit(git_commit **commit, git_repository *repo)
+{
+	retrieve_target_from_oid(commit, repo, "e90810b8df3");
+}
+
+#define NEW_BRANCH_NAME "new-branch-on-the-block"
+
+void test_refs_branches_create__can_create_a_local_branch(void)
+{
+	retrieve_known_commit(&target, repo);
+
+	cl_git_pass(git_branch_create(&branch, repo, NEW_BRANCH_NAME, target, 0));
+	cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target)));
+}
+
+void test_refs_branches_create__can_not_create_a_branch_if_its_name_collide_with_an_existing_one(void)
+{
+	retrieve_known_commit(&target, repo);
+
+	cl_assert_equal_i(GIT_EEXISTS, git_branch_create(&branch, repo, "br2", target, 0));
+}
+
+void test_refs_branches_create__can_force_create_over_an_existing_branch(void)
+{
+	retrieve_known_commit(&target, repo);
+
+	cl_git_pass(git_branch_create(&branch, repo, "br2", target, 1));
+	cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target)));
+	cl_assert_equal_s("refs/heads/br2", git_reference_name(branch));
+}
+
+void test_refs_branches_create__cannot_force_create_over_current_branch(void)
+{
+	const git_oid *oid;
+	git_reference *branch2;
+	retrieve_known_commit(&target, repo);
+
+	cl_git_pass(git_branch_lookup(&branch2, repo, "master", GIT_BRANCH_LOCAL));
+	cl_assert_equal_s("refs/heads/master", git_reference_name(branch2));
+	cl_assert_equal_i(true, git_branch_is_head(branch2));
+	oid = git_reference_target(branch2);
+
+	cl_git_fail_with(-1, git_branch_create(&branch, repo, "master", target, 1));
+	branch = NULL;
+	cl_git_pass(git_branch_lookup(&branch, repo, "master", GIT_BRANCH_LOCAL));
+	cl_assert_equal_s("refs/heads/master", git_reference_name(branch));
+	cl_git_pass(git_oid_cmp(git_reference_target(branch), oid));
+	git_reference_free(branch2);
+}
+
+void test_refs_branches_create__creating_a_branch_with_an_invalid_name_returns_EINVALIDSPEC(void)
+{
+	retrieve_known_commit(&target, repo);
+
+	cl_assert_equal_i(GIT_EINVALIDSPEC,
+		git_branch_create(&branch, repo, "inv@{id", target, 0));
+}
+
+void test_refs_branches_create__default_reflog_message(void)
+{
+	git_reflog *log;
+	git_buf buf = GIT_BUF_INIT;
+	const git_reflog_entry *entry;
+	git_annotated_commit *annotated;
+	git_signature *sig;
+	git_config *cfg;
+
+	cl_git_pass(git_repository_config(&cfg, repo));
+	cl_git_pass(git_config_set_string(cfg, "user.name", "Foo Bar"));
+	cl_git_pass(git_config_set_string(cfg, "user.email", "foo at example.com"));
+	git_config_free(cfg);
+
+	cl_git_pass(git_signature_default(&sig, repo));
+
+	retrieve_known_commit(&target, repo);
+	cl_git_pass(git_branch_create(&branch, repo, NEW_BRANCH_NAME, target, false));
+	cl_git_pass(git_reflog_read(&log, repo, "refs/heads/" NEW_BRANCH_NAME));
+
+	entry = git_reflog_entry_byindex(log, 0);
+	cl_git_pass(git_buf_printf(&buf, "branch: Created from %s", git_oid_tostr_s(git_commit_id(target))));
+	cl_assert_equal_s(git_buf_cstr(&buf), git_reflog_entry_message(entry));
+	cl_assert_equal_s(sig->email, git_reflog_entry_committer(entry)->email);
+
+	cl_git_pass(git_reference_remove(repo, "refs/heads/" NEW_BRANCH_NAME));
+	git_reference_free(branch);
+	git_reflog_free(log);
+	git_buf_clear(&buf);
+
+	cl_git_pass(git_annotated_commit_from_revspec(&annotated, repo, "e90810b8df3"));
+	cl_git_pass(git_branch_create_from_annotated(&branch, repo, NEW_BRANCH_NAME, annotated, true));
+	cl_git_pass(git_reflog_read(&log, repo, "refs/heads/" NEW_BRANCH_NAME));
+
+	entry = git_reflog_entry_byindex(log, 0);
+	cl_git_pass(git_buf_printf(&buf, "branch: Created from e90810b8df3"));
+	cl_assert_equal_s(git_buf_cstr(&buf), git_reflog_entry_message(entry));
+	cl_assert_equal_s(sig->email, git_reflog_entry_committer(entry)->email);
+
+	git_annotated_commit_free(annotated);
+	git_buf_free(&buf);
+	git_reflog_free(log);
+	git_signature_free(sig);
+}
+
+static void assert_branch_matches_name(
+	const char *expected, const char *lookup_as)
+{
+	git_reference *ref;
+	git_buf b = GIT_BUF_INIT;
+
+	cl_git_pass(git_branch_lookup(&ref, repo, lookup_as, GIT_BRANCH_LOCAL));
+
+	cl_git_pass(git_buf_sets(&b, "refs/heads/"));
+	cl_git_pass(git_buf_puts(&b, expected));
+	cl_assert_equal_s(b.ptr, git_reference_name(ref));
+
+	cl_git_pass(
+		git_oid_cmp(git_reference_target(ref), git_commit_id(target)));
+
+	git_reference_free(ref);
+	git_buf_free(&b);
+}
+
+void test_refs_branches_create__can_create_branch_with_unicode(void)
+{
+	const char *nfc = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D";
+	const char *nfd = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D";
+	const char *emoji = "\xF0\x9F\x8D\xB7";
+	const char *names[] = { nfc, nfd, emoji };
+	const char *alt[] = { nfd, nfc, NULL };
+	const char *expected[] = { nfc, nfd, emoji };
+	unsigned int i;
+	bool fs_decompose_unicode =
+		git_path_does_fs_decompose_unicode(git_repository_path(repo));
+
+	retrieve_known_commit(&target, repo);
+
+	if (cl_repo_get_bool(repo, "core.precomposeunicode"))
+		expected[1] = nfc;
+	/* test decomp. because not all Mac filesystems decompose unicode */
+	else if (fs_decompose_unicode)
+		expected[0] = nfd;
+
+	for (i = 0; i < ARRAY_SIZE(names); ++i) {
+		const char *name;
+		cl_git_pass(git_branch_create(
+			&branch, repo, names[i], target, 0));
+		cl_git_pass(git_oid_cmp(
+			git_reference_target(branch), git_commit_id(target)));
+
+		cl_git_pass(git_branch_name(&name, branch));
+		cl_assert_equal_s(expected[i], name);
+		assert_branch_matches_name(expected[i], names[i]);
+		if (fs_decompose_unicode && alt[i])
+			assert_branch_matches_name(expected[i], alt[i]);
+
+		cl_git_pass(git_branch_delete(branch));
+		git_reference_free(branch);
+		branch = NULL;
+	}
+}
+
+/**
+ * Verify that we can create a branch with a name that matches the
+ * namespace of a previously delete branch.
+ *
+ * git branch level_one/level_two
+ * git branch -D level_one/level_two
+ * git branch level_one
+ *
+ * We expect the delete to have deleted the files:
+ *     ".git/refs/heads/level_one/level_two"
+ *     ".git/logs/refs/heads/level_one/level_two"
+ * It may or may not have deleted the (now empty)
+ * containing directories.  To match git.git behavior,
+ * the second create needs to implicilty delete the
+ * directories and create the new files.
+ *     "refs/heads/level_one"
+ *     "logs/refs/heads/level_one"
+ *
+ * We should not fail to create the branch or its
+ * reflog because of an obsolete namespace container
+ * directory.
+ */
+void test_refs_branches_create__name_vs_namespace(void)
+{
+	const char * name;
+	struct item {
+		const char *first;
+		const char *second;
+	};
+	static const struct item item[] = {
+		{ "level_one/level_two", "level_one" },
+		{ "a/b/c/d/e",           "a/b/c/d" },
+		{ "ss/tt/uu/vv/ww",      "ss" },
+		/* And one test case that is deeper. */
+		{ "xx1/xx2/xx3/xx4",     "xx1/xx2/xx3/xx4/xx5/xx6" },
+		{ NULL, NULL },
+	};
+	const struct item *p;
+
+	retrieve_known_commit(&target, repo);
+
+	for (p=item; p->first; p++) {
+		cl_git_pass(git_branch_create(&branch, repo, p->first, target, 0));
+		cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target)));
+		cl_git_pass(git_branch_name(&name, branch));
+		cl_assert_equal_s(name, p->first);
+
+		cl_git_pass(git_branch_delete(branch));
+		git_reference_free(branch);
+		branch = NULL;
+
+		cl_git_pass(git_branch_create(&branch, repo, p->second, target, 0));
+		git_reference_free(branch);
+		branch = NULL;
+	}
+}
+
+/**
+ * We still need to fail if part of the namespace is
+ * still in use.
+ */
+void test_refs_branches_create__name_vs_namespace_fail(void)
+{
+	const char * name;
+	struct item {
+		const char *first;
+		const char *first_alternate;
+		const char *second;
+	};
+	static const struct item item[] = {
+		{ "level_one/level_two", "level_one/alternate", "level_one" },
+		{ "a/b/c/d/e",           "a/b/c/d/alternate",   "a/b/c/d" },
+		{ "ss/tt/uu/vv/ww",      "ss/alternate",        "ss" },
+		{ NULL, NULL, NULL },
+	};
+	const struct item *p;
+
+	retrieve_known_commit(&target, repo);
+
+	for (p=item; p->first; p++) {
+		cl_git_pass(git_branch_create(&branch, repo, p->first, target, 0));
+		cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target)));
+		cl_git_pass(git_branch_name(&name, branch));
+		cl_assert_equal_s(name, p->first);
+
+		cl_git_pass(git_branch_delete(branch));
+		git_reference_free(branch);
+		branch = NULL;
+
+		cl_git_pass(git_branch_create(&branch, repo, p->first_alternate, target, 0));
+		cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target)));
+		cl_git_pass(git_branch_name(&name, branch));
+		cl_assert_equal_s(name, p->first_alternate);
+
+		/* we do not delete the alternate. */
+		git_reference_free(branch);
+		branch = NULL;
+
+		cl_git_fail(git_branch_create(&branch, repo, p->second, target, 0));
+		git_reference_free(branch);
+		branch = NULL;
+	}
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/delete.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/delete.c
new file mode 100755
index 0000000..343ff0f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/delete.c
@@ -0,0 +1,140 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+#include "repo/repo_helpers.h"
+#include "config/config_helpers.h"
+
+static git_repository *repo;
+static git_reference *fake_remote;
+
+void test_refs_branches_delete__initialize(void)
+{
+	git_oid id;
+
+	repo = cl_git_sandbox_init("testrepo.git");
+
+	cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"));
+	cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0, NULL));
+}
+
+void test_refs_branches_delete__cleanup(void)
+{
+	git_reference_free(fake_remote);
+	fake_remote = NULL;
+
+	cl_git_sandbox_cleanup();
+	repo = NULL;
+}
+
+void test_refs_branches_delete__can_not_delete_a_branch_pointed_at_by_HEAD(void)
+{
+	git_reference *head;
+	git_reference *branch;
+
+	/* Ensure HEAD targets the local master branch */
+	cl_git_pass(git_reference_lookup(&head, repo, GIT_HEAD_FILE));
+	cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));
+	git_reference_free(head);
+
+	cl_git_pass(git_branch_lookup(&branch, repo, "master", GIT_BRANCH_LOCAL));
+	cl_git_fail(git_branch_delete(branch));
+	git_reference_free(branch);
+}
+
+void test_refs_branches_delete__can_delete_a_branch_even_if_HEAD_is_missing(void)
+{
+	git_reference *head;
+	git_reference *branch;
+
+	cl_git_pass(git_reference_lookup(&head, repo, GIT_HEAD_FILE));
+	git_reference_delete(head);
+	git_reference_free(head);
+
+	cl_git_pass(git_branch_lookup(&branch, repo, "br2", GIT_BRANCH_LOCAL));
+	cl_git_pass(git_branch_delete(branch));
+	git_reference_free(branch);
+}
+
+void test_refs_branches_delete__can_delete_a_branch_when_HEAD_is_unborn(void)
+{
+	git_reference *branch;
+
+	make_head_unborn(repo, NON_EXISTING_HEAD);
+
+	cl_git_pass(git_branch_lookup(&branch, repo, "br2", GIT_BRANCH_LOCAL));
+	cl_git_pass(git_branch_delete(branch));
+	git_reference_free(branch);
+}
+
+void test_refs_branches_delete__can_delete_a_branch_pointed_at_by_detached_HEAD(void)
+{
+	git_reference *head, *branch;
+
+	cl_git_pass(git_reference_lookup(&head, repo, GIT_HEAD_FILE));
+	cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head));
+	cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));
+	git_reference_free(head);
+
+	/* Detach HEAD and make it target the commit that "master" points to */
+	git_repository_detach_head(repo);
+
+	cl_git_pass(git_branch_lookup(&branch, repo, "master", GIT_BRANCH_LOCAL));
+	cl_git_pass(git_branch_delete(branch));
+	git_reference_free(branch);
+}
+
+void test_refs_branches_delete__can_delete_a_local_branch(void)
+{
+	git_reference *branch;
+	cl_git_pass(git_branch_lookup(&branch, repo, "br2", GIT_BRANCH_LOCAL));
+	cl_git_pass(git_branch_delete(branch));
+	git_reference_free(branch);
+}
+
+void test_refs_branches_delete__can_delete_a_remote_branch(void)
+{
+	git_reference *branch;
+	cl_git_pass(git_branch_lookup(&branch, repo, "nulltoken/master", GIT_BRANCH_REMOTE));
+	cl_git_pass(git_branch_delete(branch));
+	git_reference_free(branch);
+}
+
+void test_refs_branches_delete__deleting_a_branch_removes_related_configuration_data(void)
+{
+	git_reference *branch;
+
+	assert_config_entry_existence(repo, "branch.track-local.remote", true);
+	assert_config_entry_existence(repo, "branch.track-local.merge", true);
+
+	cl_git_pass(git_branch_lookup(&branch, repo, "track-local", GIT_BRANCH_LOCAL));
+	cl_git_pass(git_branch_delete(branch));
+	git_reference_free(branch);
+
+	assert_config_entry_existence(repo, "branch.track-local.remote", false);
+	assert_config_entry_existence(repo, "branch.track-local.merge", false);
+}
+
+void test_refs_branches_delete__removes_reflog(void)
+{
+	git_reference *branch;
+	git_reflog *log;
+	git_oid oidzero = {{0}};
+	git_signature *sig;
+
+	/* Ensure the reflog has at least one entry */
+	cl_git_pass(git_signature_now(&sig, "Me", "user at example.com"));
+	cl_git_pass(git_reflog_read(&log, repo, "refs/heads/track-local"));
+	cl_git_pass(git_reflog_append(log, &oidzero, sig, "message"));
+	cl_assert(git_reflog_entrycount(log) > 0);
+	git_signature_free(sig);
+	git_reflog_free(log);
+
+	cl_git_pass(git_branch_lookup(&branch, repo, "track-local", GIT_BRANCH_LOCAL));
+	cl_git_pass(git_branch_delete(branch));
+	git_reference_free(branch);
+
+	/* Reading a nonexistant reflog creates it, but it should be empty */
+	cl_git_pass(git_reflog_read(&log, repo, "refs/heads/track-local"));
+	cl_assert_equal_i(0, git_reflog_entrycount(log));
+	git_reflog_free(log);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/ishead.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/ishead.c
new file mode 100755
index 0000000..1df70b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/ishead.c
@@ -0,0 +1,98 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+#include "repo/repo_helpers.h"
+
+static git_repository *repo;
+static git_reference *branch;
+
+void test_refs_branches_ishead__initialize(void)
+{
+	repo = cl_git_sandbox_init("testrepo.git");
+	branch = NULL;
+}
+
+void test_refs_branches_ishead__cleanup(void)
+{
+	git_reference_free(branch);
+	branch = NULL;
+
+	cl_git_sandbox_cleanup();
+	repo = NULL;
+}
+
+void test_refs_branches_ishead__can_tell_if_a_branch_is_pointed_at_by_HEAD(void)
+{
+	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master"));
+
+	cl_assert_equal_i(true, git_branch_is_head(branch));
+}
+
+void test_refs_branches_ishead__can_properly_handle_unborn_HEAD(void)
+{
+	make_head_unborn(repo, NON_EXISTING_HEAD);
+
+	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master"));
+
+	cl_assert_equal_i(false, git_branch_is_head(branch));
+}
+
+void test_refs_branches_ishead__can_properly_handle_missing_HEAD(void)
+{
+	delete_head(repo);
+
+	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master"));
+
+	cl_assert_equal_i(false, git_branch_is_head(branch));
+}
+
+void test_refs_branches_ishead__can_tell_if_a_branch_is_not_pointed_at_by_HEAD(void)
+{
+	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/br2"));
+
+	cl_assert_equal_i(false, git_branch_is_head(branch));
+}
+
+void test_refs_branches_ishead__wont_be_fooled_by_a_non_branch(void)
+{
+	cl_git_pass(git_reference_lookup(&branch, repo, "refs/tags/e90810b"));
+
+	cl_assert_equal_i(false, git_branch_is_head(branch));
+}
+
+/*
+ * $ git init .
+ * Initialized empty Git repository in d:/temp/tempee/.git/
+ * 
+ * $ touch a && git add a
+ * $ git commit -m" boom"
+ * [master (root-commit) b47b758]  boom
+ *  0 files changed
+ *  create mode 100644 a
+ * 
+ * $ echo "ref: refs/heads/master" > .git/refs/heads/linked
+ * $ echo "ref: refs/heads/linked" > .git/refs/heads/super
+ * $ echo "ref: refs/heads/super" > .git/HEAD
+ * 
+ * $ git branch
+ *   linked -> master
+ * * master
+ *   super -> master
+ */
+void test_refs_branches_ishead__only_direct_references_are_considered(void)
+{
+	git_reference *linked, *super, *head;
+
+	cl_git_pass(git_reference_symbolic_create(&linked, repo, "refs/heads/linked", "refs/heads/master", 0, NULL));
+	cl_git_pass(git_reference_symbolic_create(&super, repo, "refs/heads/super", "refs/heads/linked", 0, NULL));
+	cl_git_pass(git_reference_symbolic_create(&head, repo, GIT_HEAD_FILE, "refs/heads/super", 1, NULL));
+
+	cl_assert_equal_i(false, git_branch_is_head(linked));
+	cl_assert_equal_i(false, git_branch_is_head(super));
+
+	cl_git_pass(git_repository_head(&branch, repo));
+	cl_assert_equal_s("refs/heads/master", git_reference_name(branch));
+
+	git_reference_free(linked);
+	git_reference_free(super);
+	git_reference_free(head);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/iterator.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/iterator.c
new file mode 100755
index 0000000..ca366c9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/iterator.c
@@ -0,0 +1,151 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+
+static git_repository *repo;
+static git_reference *fake_remote;
+
+void test_refs_branches_iterator__initialize(void)
+{
+	git_oid id;
+
+	cl_fixture_sandbox("testrepo.git");
+	cl_git_pass(git_repository_open(&repo, "testrepo.git"));
+
+	cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"));
+	cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0, NULL));
+}
+
+void test_refs_branches_iterator__cleanup(void)
+{
+	git_reference_free(fake_remote);
+	fake_remote = NULL;
+
+	git_repository_free(repo);
+	repo = NULL;
+
+	cl_fixture_cleanup("testrepo.git");
+
+	cl_git_sandbox_cleanup();
+}
+
+static void assert_retrieval(unsigned int flags, unsigned int expected_count)
+{
+	git_branch_iterator *iter;
+	git_reference *ref;
+	int count = 0, error;
+	git_branch_t type;
+
+	cl_git_pass(git_branch_iterator_new(&iter, repo, flags));
+	while ((error = git_branch_next(&ref, &type, iter)) == 0) {
+		count++;
+		git_reference_free(ref);
+	}
+
+	git_branch_iterator_free(iter);
+	cl_assert_equal_i(error, GIT_ITEROVER);
+	cl_assert_equal_i(expected_count, count);
+}
+
+void test_refs_branches_iterator__retrieve_all_branches(void)
+{
+	assert_retrieval(GIT_BRANCH_ALL, 14);
+}
+
+void test_refs_branches_iterator__retrieve_remote_branches(void)
+{
+	assert_retrieval(GIT_BRANCH_REMOTE, 2);
+}
+
+void test_refs_branches_iterator__retrieve_local_branches(void)
+{
+	assert_retrieval(GIT_BRANCH_LOCAL, 12);
+}
+
+struct expectations {
+	const char *branch_name;
+	int encounters;
+};
+
+static void assert_branch_has_been_found(struct expectations *findings, const char* expected_branch_name)
+{
+	int pos = 0;
+
+	for (pos = 0; findings[pos].branch_name; ++pos) {
+		if (strcmp(expected_branch_name, findings[pos].branch_name) == 0) {
+			cl_assert_equal_i(1, findings[pos].encounters);
+			return;
+		}
+	}
+
+	cl_fail("expected branch not found in list.");
+}
+
+static void contains_branches(struct expectations exp[], git_branch_iterator *iter)
+{
+	git_reference *ref;
+	git_branch_t type;
+	int error, pos = 0;
+
+	while ((error = git_branch_next(&ref, &type, iter)) == 0) {
+		for (pos = 0; exp[pos].branch_name; ++pos) {
+			if (strcmp(git_reference_shorthand(ref), exp[pos].branch_name) == 0)
+				exp[pos].encounters++;
+		}
+
+		git_reference_free(ref);
+	}
+
+	cl_assert_equal_i(error, GIT_ITEROVER);
+}
+
+/*
+ * $ git branch -r
+ *  nulltoken/HEAD -> nulltoken/master
+ *  nulltoken/master
+ */
+void test_refs_branches_iterator__retrieve_remote_symbolic_HEAD_when_present(void)
+{
+	git_branch_iterator *iter;
+	struct expectations exp[] = {
+		{ "nulltoken/HEAD", 0 },
+		{ "nulltoken/master", 0 },
+		{ NULL, 0 }
+	};
+
+	git_reference_free(fake_remote);
+	cl_git_pass(git_reference_symbolic_create(&fake_remote, repo, "refs/remotes/nulltoken/HEAD", "refs/remotes/nulltoken/master", 0, NULL));
+
+	assert_retrieval(GIT_BRANCH_REMOTE, 3);
+
+	cl_git_pass(git_branch_iterator_new(&iter, repo, GIT_BRANCH_REMOTE));
+	contains_branches(exp, iter);
+	git_branch_iterator_free(iter);
+
+	assert_branch_has_been_found(exp, "nulltoken/HEAD");
+	assert_branch_has_been_found(exp, "nulltoken/master");
+}
+
+void test_refs_branches_iterator__mix_of_packed_and_loose(void)
+{
+	git_branch_iterator *iter;
+	struct expectations exp[] = {
+		{ "master", 0 },
+		{ "origin/HEAD", 0 },
+		{ "origin/master", 0 },
+		{ "origin/packed", 0 },
+		{ NULL, 0 }
+	};
+	git_repository *r2;
+
+	r2 = cl_git_sandbox_init("testrepo2");
+
+	cl_git_pass(git_branch_iterator_new(&iter, r2, GIT_BRANCH_ALL));
+	contains_branches(exp, iter);
+
+	git_branch_iterator_free(iter);
+
+	assert_branch_has_been_found(exp, "master");
+	assert_branch_has_been_found(exp, "origin/HEAD");
+	assert_branch_has_been_found(exp, "origin/master");
+	assert_branch_has_been_found(exp, "origin/packed");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/lookup.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/lookup.c
new file mode 100755
index 0000000..95d49a4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/lookup.c
@@ -0,0 +1,45 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+
+static git_repository *repo;
+static git_reference *branch;
+
+void test_refs_branches_lookup__initialize(void)
+{
+	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+
+	branch = NULL;
+}
+
+void test_refs_branches_lookup__cleanup(void)
+{
+	git_reference_free(branch);
+	branch = NULL;
+
+	git_repository_free(repo);
+	repo = NULL;
+}
+
+void test_refs_branches_lookup__can_retrieve_a_local_branch(void)
+{
+	cl_git_pass(git_branch_lookup(&branch, repo, "br2", GIT_BRANCH_LOCAL));
+}
+
+void test_refs_branches_lookup__can_retrieve_a_remote_tracking_branch(void)
+{
+	cl_git_pass(git_branch_lookup(&branch, repo, "test/master", GIT_BRANCH_REMOTE));
+}
+
+void test_refs_branches_lookup__trying_to_retrieve_an_unknown_branch_returns_ENOTFOUND(void)
+{
+	cl_assert_equal_i(GIT_ENOTFOUND, git_branch_lookup(&branch, repo, "where/are/you", GIT_BRANCH_LOCAL));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_branch_lookup(&branch, repo, "over/here", GIT_BRANCH_REMOTE));
+}
+
+void test_refs_branches_lookup__trying_to_retrieve_a_branch_with_an_invalid_name_returns_EINVALIDSPEC(void)
+{
+	cl_assert_equal_i(GIT_EINVALIDSPEC,
+		git_branch_lookup(&branch, repo, "are/you/inv@{id", GIT_BRANCH_LOCAL));
+	cl_assert_equal_i(GIT_EINVALIDSPEC,
+		git_branch_lookup(&branch, repo, "yes/i am", GIT_BRANCH_REMOTE));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/move.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/move.c
new file mode 100755
index 0000000..bec39e1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/move.c
@@ -0,0 +1,248 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+#include "config/config_helpers.h"
+
+static git_repository *repo;
+
+void test_refs_branches_move__initialize(void)
+{
+	repo = cl_git_sandbox_init("testrepo.git");
+}
+
+void test_refs_branches_move__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+#define NEW_BRANCH_NAME "new-branch-on-the-block"
+
+void test_refs_branches_move__can_move_a_local_branch(void)
+{
+	git_reference *original_ref, *new_ref;
+
+	cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
+
+	cl_git_pass(git_branch_move(&new_ref, original_ref, NEW_BRANCH_NAME, 0));
+	cl_assert_equal_s(GIT_REFS_HEADS_DIR NEW_BRANCH_NAME, git_reference_name(new_ref));
+
+	git_reference_free(original_ref);
+	git_reference_free(new_ref);
+}
+
+void test_refs_branches_move__can_move_a_local_branch_to_a_different_namespace(void)
+{
+	git_reference *original_ref, *new_ref, *newer_ref;
+
+	cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
+
+	/* Downward */
+	cl_git_pass(git_branch_move(&new_ref, original_ref, "somewhere/" NEW_BRANCH_NAME, 0));
+	git_reference_free(original_ref);
+
+	/* Upward */
+	cl_git_pass(git_branch_move(&newer_ref, new_ref, "br2", 0));
+	git_reference_free(new_ref);
+
+	git_reference_free(newer_ref);
+}
+
+void test_refs_branches_move__can_move_a_local_branch_to_a_partially_colliding_namespace(void)
+{
+	git_reference *original_ref, *new_ref, *newer_ref;
+
+	cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
+
+	/* Downward */
+	cl_git_pass(git_branch_move(&new_ref, original_ref, "br2/" NEW_BRANCH_NAME, 0));
+	git_reference_free(original_ref);
+
+	/* Upward */
+	cl_git_pass(git_branch_move(&newer_ref, new_ref, "br2", 0));
+	git_reference_free(new_ref);
+
+	git_reference_free(newer_ref);
+}
+
+void test_refs_branches_move__can_not_move_a_branch_if_its_destination_name_collide_with_an_existing_one(void)
+{
+	git_reference *original_ref, *new_ref;
+	git_config *config;
+	git_buf buf = GIT_BUF_INIT;
+	char *original_remote, *original_merge;
+	const char *str;
+
+	cl_git_pass(git_repository_config_snapshot(&config, repo));
+
+	cl_git_pass(git_config_get_string_buf(&buf, config, "branch.master.remote"));
+	original_remote = git_buf_detach(&buf);
+	cl_git_pass(git_config_get_string_buf(&buf, config, "branch.master.merge"));
+	original_merge  = git_buf_detach(&buf);
+	git_config_free(config);
+
+	cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
+
+	cl_assert_equal_i(GIT_EEXISTS,
+		git_branch_move(&new_ref, original_ref, "master", 0));
+
+	cl_assert(giterr_last()->message != NULL);
+
+	cl_git_pass(git_repository_config_snapshot(&config, repo));
+	cl_git_pass(git_config_get_string(&str, config, "branch.master.remote"));
+	cl_assert_equal_s(original_remote, str);
+	cl_git_pass(git_config_get_string(&str, config, "branch.master.merge"));
+	cl_assert_equal_s(original_merge,  str);
+	git_config_free(config);
+
+	cl_assert_equal_i(GIT_EEXISTS,
+		git_branch_move(&new_ref, original_ref, "cannot-fetch", 0));
+
+	cl_assert(giterr_last()->message != NULL);
+
+	cl_git_pass(git_repository_config_snapshot(&config, repo));
+	cl_git_pass(git_config_get_string(&str, config, "branch.master.remote"));
+	cl_assert_equal_s(original_remote, str);
+	cl_git_pass(git_config_get_string(&str, config, "branch.master.merge"));
+	cl_assert_equal_s(original_merge,  str);
+	git_config_free(config);
+
+	git_reference_free(original_ref);
+	cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/track-local"));
+
+	cl_assert_equal_i(GIT_EEXISTS,
+		git_branch_move(&new_ref, original_ref, "master", 0));
+
+	cl_assert(giterr_last()->message != NULL);
+
+	cl_git_pass(git_repository_config_snapshot(&config, repo));
+	cl_git_pass(git_config_get_string(&str, config, "branch.master.remote"));
+	cl_assert_equal_s(original_remote, str);
+	cl_git_pass(git_config_get_string(&str, config, "branch.master.merge"));
+	cl_assert_equal_s(original_merge,  str);
+
+	git__free(original_remote); git__free(original_merge);
+	git_reference_free(original_ref);
+	git_config_free(config);
+}
+
+void test_refs_branches_move__moving_a_branch_with_an_invalid_name_returns_EINVALIDSPEC(void)
+{
+	git_reference *original_ref, *new_ref;
+
+	cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
+
+	cl_assert_equal_i(GIT_EINVALIDSPEC, git_branch_move(&new_ref, original_ref, "Inv@{id", 0));
+
+	git_reference_free(original_ref);
+}
+
+void test_refs_branches_move__can_not_move_a_non_branch(void)
+{
+	git_reference *tag, *new_ref;
+
+	cl_git_pass(git_reference_lookup(&tag, repo, "refs/tags/e90810b"));
+	cl_git_fail(git_branch_move(&new_ref, tag, NEW_BRANCH_NAME, 0));
+
+	git_reference_free(tag);
+}
+
+void test_refs_branches_move__can_force_move_over_an_existing_branch(void)
+{
+	git_reference *original_ref, *new_ref;
+
+	cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
+
+	cl_git_pass(git_branch_move(&new_ref, original_ref, "master", 1));
+
+	git_reference_free(original_ref);
+	git_reference_free(new_ref);
+}
+
+void test_refs_branches_move__moving_a_branch_moves_related_configuration_data(void)
+{
+	git_reference *branch;
+	git_reference *new_branch;
+
+	cl_git_pass(git_branch_lookup(&branch, repo, "track-local", GIT_BRANCH_LOCAL));
+
+	assert_config_entry_existence(repo, "branch.track-local.remote", true);
+	assert_config_entry_existence(repo, "branch.track-local.merge", true);
+	assert_config_entry_existence(repo, "branch.moved.remote", false);
+	assert_config_entry_existence(repo, "branch.moved.merge", false);
+
+	cl_git_pass(git_branch_move(&new_branch, branch, "moved", 0));
+	git_reference_free(branch);
+
+	assert_config_entry_existence(repo, "branch.track-local.remote", false);
+	assert_config_entry_existence(repo, "branch.track-local.merge", false);
+	assert_config_entry_existence(repo, "branch.moved.remote", true);
+	assert_config_entry_existence(repo, "branch.moved.merge", true);
+
+	git_reference_free(new_branch);
+}
+
+void test_refs_branches_move__moving_the_branch_pointed_at_by_HEAD_updates_HEAD(void)
+{
+	git_reference *branch;
+	git_reference *new_branch;
+
+	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master"));
+	cl_git_pass(git_branch_move(&new_branch, branch, "master2", 0));
+	git_reference_free(branch);
+	git_reference_free(new_branch);
+
+	cl_git_pass(git_repository_head(&branch, repo));
+	cl_assert_equal_s("refs/heads/master2", git_reference_name(branch));
+	git_reference_free(branch);
+}
+
+void test_refs_branches_move__default_reflog_message(void)
+{
+	git_reference *branch;
+	git_reference *new_branch;
+	git_reflog *log;
+	const git_reflog_entry *entry;
+	git_signature *sig;
+	git_config *cfg;
+	git_oid id;
+
+	cl_git_pass(git_repository_config(&cfg, repo));
+	cl_git_pass(git_config_set_string(cfg, "user.name", "Foo Bar"));
+	cl_git_pass(git_config_set_string(cfg, "user.email", "foo at example.com"));
+	git_config_free(cfg);
+
+	cl_git_pass(git_signature_default(&sig, repo));
+
+	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master"));
+	git_oid_cpy(&id, git_reference_target(branch));
+	cl_git_pass(git_branch_move(&new_branch, branch, "master2", 0));
+
+	cl_git_pass(git_reflog_read(&log, repo, git_reference_name(new_branch)));
+	entry = git_reflog_entry_byindex(log, 0);
+	cl_assert_equal_s("branch: renamed refs/heads/master to refs/heads/master2",
+			git_reflog_entry_message(entry));
+	cl_assert_equal_s(sig->email, git_reflog_entry_committer(entry)->email);
+	cl_assert_equal_oid(&id, git_reflog_entry_id_old(entry));
+	cl_assert_equal_oid(&id, git_reflog_entry_id_new(entry));
+
+	git_reference_free(branch);
+	git_reference_free(new_branch);
+	git_reflog_free(log);
+	git_signature_free(sig);
+}
+
+void test_refs_branches_move__can_move_with_unicode(void)
+{
+	git_reference *original_ref, *new_ref;
+	const char *new_branch_name = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D";
+
+	cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
+	cl_git_pass(git_branch_move(&new_ref, original_ref, new_branch_name, 0));
+
+	if (cl_repo_get_bool(repo, "core.precomposeunicode"))
+		cl_assert_equal_s(GIT_REFS_HEADS_DIR "\xC3\x85\x73\x74\x72\xC3\xB6\x6D", git_reference_name(new_ref));
+	else
+		cl_assert_equal_s(GIT_REFS_HEADS_DIR "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D", git_reference_name(new_ref));
+
+	git_reference_free(original_ref);
+	git_reference_free(new_ref);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/name.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/name.c
new file mode 100755
index 0000000..176f836
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/name.c
@@ -0,0 +1,45 @@
+#include "clar_libgit2.h"
+#include "branch.h"
+
+static git_repository *repo;
+static git_reference *ref;
+
+void test_refs_branches_name__initialize(void)
+{
+	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+}
+
+void test_refs_branches_name__cleanup(void)
+{
+	git_reference_free(ref);
+	ref = NULL;
+
+	git_repository_free(repo);
+	repo = NULL;
+}
+
+void test_refs_branches_name__can_get_local_branch_name(void)
+{
+	const char *name;
+
+	cl_git_pass(git_branch_lookup(&ref,repo,"master",GIT_BRANCH_LOCAL));
+	cl_git_pass(git_branch_name(&name,ref));
+	cl_assert_equal_s("master",name);
+}
+
+void test_refs_branches_name__can_get_remote_branch_name(void)
+{
+	const char *name;
+
+	cl_git_pass(git_branch_lookup(&ref,repo,"test/master",GIT_BRANCH_REMOTE));
+	cl_git_pass(git_branch_name(&name,ref));
+	cl_assert_equal_s("test/master",name);
+}
+
+void test_refs_branches_name__error_when_ref_is_no_branch(void)
+{
+	const char *name;
+
+	cl_git_pass(git_reference_lookup(&ref,repo,"refs/notes/fanout"));
+	cl_git_fail(git_branch_name(&name,ref));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/remote.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/remote.c
new file mode 100755
index 0000000..4752671
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/remote.c
@@ -0,0 +1,68 @@
+#include "clar_libgit2.h"
+#include "branch.h"
+#include "remote.h"
+
+static git_repository *g_repo;
+static const char *remote_tracking_branch_name = "refs/remotes/test/master";
+static const char *expected_remote_name = "test";
+static int expected_remote_name_length;
+
+void test_refs_branches_remote__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo");
+
+	expected_remote_name_length = (int)strlen(expected_remote_name) + 1;
+}
+
+void test_refs_branches_remote__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_refs_branches_remote__can_get_remote_for_branch(void)
+{
+	git_buf remotename = {0};
+
+	cl_git_pass(git_branch_remote_name(&remotename, g_repo, remote_tracking_branch_name));
+
+	cl_assert_equal_s("test", remotename.ptr);
+	git_buf_free(&remotename);
+}
+
+void test_refs_branches_remote__no_matching_remote_returns_error(void)
+{
+	const char *unknown = "refs/remotes/nonexistent/master";
+	git_buf buf;
+
+	giterr_clear();
+	memset(&buf, 0, sizeof(git_buf));
+	cl_git_fail_with(git_branch_remote_name(&buf, g_repo, unknown), GIT_ENOTFOUND);
+	cl_assert(giterr_last() != NULL);
+}
+
+void test_refs_branches_remote__local_remote_returns_error(void)
+{
+	const char *local = "refs/heads/master";
+	git_buf buf;
+
+	giterr_clear();
+	memset(&buf, 0, sizeof(git_buf));
+	cl_git_fail_with(git_branch_remote_name(&buf, g_repo, local), GIT_ERROR);
+	cl_assert(giterr_last() != NULL);
+}
+
+void test_refs_branches_remote__ambiguous_remote_returns_error(void)
+{
+	git_remote *remote;
+	git_buf buf;
+
+	/* Create the remote */
+	cl_git_pass(git_remote_create_with_fetchspec(&remote, g_repo, "addtest", "http://github.com/libgit2/libgit2", "refs/heads/*:refs/remotes/test/*"));
+
+	git_remote_free(remote);
+
+	giterr_clear();
+	memset(&buf, 0, sizeof(git_buf));
+	cl_git_fail_with(git_branch_remote_name(&buf, g_repo, remote_tracking_branch_name), GIT_EAMBIGUOUS);
+	cl_assert(giterr_last() != NULL);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/upstream.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/upstream.c
new file mode 100755
index 0000000..8f2e7a2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/upstream.c
@@ -0,0 +1,193 @@
+#include "clar_libgit2.h"
+#include "config/config_helpers.h"
+#include "refs.h"
+
+static git_repository *repo;
+static git_reference *branch, *upstream;
+
+void test_refs_branches_upstream__initialize(void)
+{
+	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+
+	branch = NULL;
+	upstream = NULL;
+}
+
+void test_refs_branches_upstream__cleanup(void)
+{
+	git_reference_free(upstream);
+	git_reference_free(branch);
+	branch = NULL;
+
+	git_repository_free(repo);
+	repo = NULL;
+}
+
+void test_refs_branches_upstream__can_retrieve_the_remote_tracking_reference_of_a_local_branch(void)
+{
+	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master"));
+
+	cl_git_pass(git_branch_upstream(&upstream, branch));
+
+	cl_assert_equal_s("refs/remotes/test/master", git_reference_name(upstream));
+}
+
+void test_refs_branches_upstream__can_retrieve_the_local_upstream_reference_of_a_local_branch(void)
+{
+	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/track-local"));
+
+	cl_git_pass(git_branch_upstream(&upstream, branch));
+
+	cl_assert_equal_s("refs/heads/master", git_reference_name(upstream));
+}
+
+void test_refs_branches_upstream__cannot_retrieve_a_remote_upstream_reference_from_a_non_branch(void)
+{
+	cl_git_pass(git_reference_lookup(&branch, repo, "refs/tags/e90810b"));
+
+	cl_git_fail(git_branch_upstream(&upstream, branch));
+}
+
+void test_refs_branches_upstream__trying_to_retrieve_a_remote_tracking_reference_from_a_plain_local_branch_returns_GIT_ENOTFOUND(void)
+{
+	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/subtrees"));
+
+	cl_assert_equal_i(GIT_ENOTFOUND, git_branch_upstream(&upstream, branch));
+}
+
+void test_refs_branches_upstream__trying_to_retrieve_a_remote_tracking_reference_from_a_branch_with_no_fetchspec_returns_GIT_ENOTFOUND(void)
+{
+	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/cannot-fetch"));
+
+	cl_assert_equal_i(GIT_ENOTFOUND, git_branch_upstream(&upstream, branch));
+}
+
+void test_refs_branches_upstream__upstream_remote(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_pass(git_branch_upstream_remote(&buf, repo, "refs/heads/master"));
+	cl_assert_equal_s("test", buf.ptr);
+	git_buf_free(&buf);
+}
+
+void test_refs_branches_upstream__upstream_remote_empty_value(void)
+{
+	git_repository *repository;
+	git_config *cfg;
+	git_buf buf = GIT_BUF_INIT;
+
+	repository = cl_git_sandbox_init("testrepo.git");
+	cl_git_pass(git_repository_config(&cfg, repository));
+	cl_git_pass(git_config_set_string(cfg, "branch.master.remote", ""));
+	cl_git_fail_with(GIT_ENOTFOUND, git_branch_upstream_remote(&buf, repository, "refs/heads/master"));
+
+	cl_git_pass(git_config_delete_entry(cfg, "branch.master.remote"));
+	cl_git_fail_with(GIT_ENOTFOUND, git_branch_upstream_remote(&buf, repository, "refs/heads/master"));
+	cl_git_sandbox_cleanup();
+}
+
+static void assert_merge_and_or_remote_key_missing(git_repository *repository, const git_commit *target, const char *entry_name)
+{
+	git_reference *branch;
+
+	cl_assert_equal_i(GIT_OBJ_COMMIT, git_object_type((git_object*)target));
+	cl_git_pass(git_branch_create(&branch, repository, entry_name, (git_commit*)target, 0));
+
+	cl_assert_equal_i(GIT_ENOTFOUND, git_branch_upstream(&upstream, branch));
+
+	git_reference_free(branch);
+}
+
+void test_refs_branches_upstream__retrieve_a_remote_tracking_reference_from_a_branch_with_no_remote_returns_GIT_ENOTFOUND(void)
+{
+	git_reference *head;
+	git_repository *repository;
+	git_commit *target;
+
+	repository = cl_git_sandbox_init("testrepo.git");
+
+	cl_git_pass(git_repository_head(&head, repository));
+	cl_git_pass(git_reference_peel(((git_object **)&target), head, GIT_OBJ_COMMIT));
+	git_reference_free(head);
+
+	assert_merge_and_or_remote_key_missing(repository, target, "remoteless");
+	assert_merge_and_or_remote_key_missing(repository, target, "mergeless");
+	assert_merge_and_or_remote_key_missing(repository, target, "mergeandremoteless");
+
+	git_commit_free(target);
+
+	cl_git_sandbox_cleanup();
+}
+
+void test_refs_branches_upstream__set_unset_upstream(void)
+{
+	git_reference *branch;
+	git_repository *repository;
+
+	repository = cl_git_sandbox_init("testrepo.git");
+
+	/* remote */
+	cl_git_pass(git_reference_lookup(&branch, repository, "refs/heads/test"));
+	cl_git_pass(git_branch_set_upstream(branch, "test/master"));
+
+	assert_config_entry_value(repository, "branch.test.remote", "test");
+	assert_config_entry_value(repository, "branch.test.merge", "refs/heads/master");
+
+	git_reference_free(branch);
+
+	/* local */
+	cl_git_pass(git_reference_lookup(&branch, repository, "refs/heads/test"));
+	cl_git_pass(git_branch_set_upstream(branch, "master"));
+
+	assert_config_entry_value(repository, "branch.test.remote", ".");
+	assert_config_entry_value(repository, "branch.test.merge", "refs/heads/master");
+
+	/* unset */
+	cl_git_pass(git_branch_set_upstream(branch, NULL));
+	assert_config_entry_existence(repository, "branch.test.remote", false);
+	assert_config_entry_existence(repository, "branch.test.merge", false);
+
+	git_reference_free(branch);
+
+	cl_git_pass(git_reference_lookup(&branch, repository, "refs/heads/master"));
+	cl_git_pass(git_branch_set_upstream(branch, NULL));
+	assert_config_entry_existence(repository, "branch.test.remote", false);
+	assert_config_entry_existence(repository, "branch.test.merge", false);
+
+	git_reference_free(branch);
+
+	cl_git_sandbox_cleanup();
+}
+
+void test_refs_branches_upstream__no_fetch_refspec(void)
+{
+	git_reference *ref, *branch;
+	git_repository *repo;
+	git_remote *remote;
+	git_config *cfg;
+
+	repo = cl_git_sandbox_init("testrepo.git");
+
+	cl_git_pass(git_remote_create_with_fetchspec(&remote, repo, "matching", ".", NULL));
+	cl_git_pass(git_remote_add_push(repo, "matching", ":"));
+
+	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/test"));
+	cl_git_pass(git_reference_create(&ref, repo, "refs/remotes/matching/master", git_reference_target(branch), 1, "fetch"));
+	cl_git_fail(git_branch_set_upstream(branch, "matching/master"));
+	cl_assert_equal_s("Could not determine remote for 'refs/remotes/matching/master'",
+			  giterr_last()->message);
+
+	/* we can't set it automatically, so let's test the user setting it by hand */
+	cl_git_pass(git_repository_config(&cfg, repo));
+	cl_git_pass(git_config_set_string(cfg, "branch.test.remote", "matching"));
+	cl_git_pass(git_config_set_string(cfg, "branch.test.merge", "refs/heads/master"));
+	/* we still can't find it because there is no rule for that reference */
+	cl_git_fail_with(GIT_ENOTFOUND, git_branch_upstream(&ref, branch));
+
+	git_reference_free(ref);
+	git_reference_free(branch);
+	git_remote_free(remote);
+
+	cl_git_sandbox_cleanup();
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/upstreamname.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/upstreamname.c
new file mode 100755
index 0000000..d30002e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/branches/upstreamname.c
@@ -0,0 +1,36 @@
+#include "clar_libgit2.h"
+#include "branch.h"
+
+static git_repository *repo;
+static git_buf upstream_name;
+
+void test_refs_branches_upstreamname__initialize(void)
+{
+	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+
+	git_buf_init(&upstream_name, 0);
+}
+
+void test_refs_branches_upstreamname__cleanup(void)
+{
+	git_buf_free(&upstream_name);
+
+	git_repository_free(repo);
+	repo = NULL;
+}
+
+void test_refs_branches_upstreamname__can_retrieve_the_remote_tracking_reference_name_of_a_local_branch(void)
+{
+	cl_git_pass(git_branch_upstream_name(
+		&upstream_name, repo, "refs/heads/master"));
+
+	cl_assert_equal_s("refs/remotes/test/master", git_buf_cstr(&upstream_name));
+}
+
+void test_refs_branches_upstreamname__can_retrieve_the_local_upstream_reference_name_of_a_local_branch(void)
+{
+	cl_git_pass(git_branch_upstream_name(
+		&upstream_name, repo, "refs/heads/track-local"));
+
+	cl_assert_equal_s("refs/heads/master", git_buf_cstr(&upstream_name));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/crashes.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/crashes.c
new file mode 100755
index 0000000..7a10411
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/crashes.c
@@ -0,0 +1,20 @@
+#include "clar_libgit2.h"
+
+void test_refs_crashes__double_free(void)
+{
+	git_repository *repo;
+	git_reference *ref, *ref2;
+	const char *REFNAME = "refs/heads/xxx";
+
+	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+	cl_git_pass(git_reference_symbolic_create(&ref, repo, REFNAME, "refs/heads/master", 0, NULL));
+	cl_git_pass(git_reference_lookup(&ref2, repo, REFNAME));
+	cl_git_pass(git_reference_delete(ref));
+	git_reference_free(ref);
+	git_reference_free(ref2);
+
+	/* reference is gone from disk, so reloading it will fail */
+	cl_git_fail(git_reference_lookup(&ref2, repo, REFNAME));
+
+	git_repository_free(repo);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/create.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/create.c
new file mode 100755
index 0000000..192551d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/create.c
@@ -0,0 +1,210 @@
+#include "clar_libgit2.h"
+
+#include "repository.h"
+#include "git2/reflog.h"
+#include "reflog.h"
+#include "ref_helpers.h"
+
+static const char *current_master_tip = "099fabac3a9ea935598528c27f866e34089c2eff";
+static const char *current_head_target = "refs/heads/master";
+
+static git_repository *g_repo;
+
+void test_refs_create__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_refs_create__cleanup(void)
+{
+   cl_git_sandbox_cleanup();
+}
+
+void test_refs_create__symbolic(void)
+{
+   // create a new symbolic reference
+	git_reference *new_reference, *looked_up_ref, *resolved_ref;
+	git_repository *repo2;
+	git_oid id;
+
+	const char *new_head_tracker = "ANOTHER_HEAD_TRACKER";
+
+	git_oid_fromstr(&id, current_master_tip);
+
+	/* Create and write the new symbolic reference */
+	cl_git_pass(git_reference_symbolic_create(&new_reference, g_repo, new_head_tracker, current_head_target, 0, NULL));
+
+	/* Ensure the reference can be looked-up... */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head_tracker));
+	cl_assert(git_reference_type(looked_up_ref) & GIT_REF_SYMBOLIC);
+	cl_assert(reference_is_packed(looked_up_ref) == 0);
+	cl_assert_equal_s(looked_up_ref->name, new_head_tracker);
+
+	/* ...peeled.. */
+	cl_git_pass(git_reference_resolve(&resolved_ref, looked_up_ref));
+	cl_assert(git_reference_type(resolved_ref) == GIT_REF_OID);
+
+	/* ...and that it points to the current master tip */
+	cl_assert_equal_oid(&id, git_reference_target(resolved_ref));
+	git_reference_free(looked_up_ref);
+	git_reference_free(resolved_ref);
+
+	/* Similar test with a fresh new repository */
+	cl_git_pass(git_repository_open(&repo2, "testrepo"));
+
+	cl_git_pass(git_reference_lookup(&looked_up_ref, repo2, new_head_tracker));
+	cl_git_pass(git_reference_resolve(&resolved_ref, looked_up_ref));
+	cl_assert_equal_oid(&id, git_reference_target(resolved_ref));
+
+	git_repository_free(repo2);
+
+	git_reference_free(new_reference);
+	git_reference_free(looked_up_ref);
+	git_reference_free(resolved_ref);
+}
+
+void test_refs_create__deep_symbolic(void)
+{
+   // create a deep symbolic reference
+	git_reference *new_reference, *looked_up_ref, *resolved_ref;
+	git_oid id;
+
+	const char *new_head_tracker = "deep/rooted/tracker";
+
+	git_oid_fromstr(&id, current_master_tip);
+
+	cl_git_pass(git_reference_symbolic_create(&new_reference, g_repo, new_head_tracker, current_head_target, 0, NULL));
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head_tracker));
+	cl_git_pass(git_reference_resolve(&resolved_ref, looked_up_ref));
+	cl_assert_equal_oid(&id, git_reference_target(resolved_ref));
+
+	git_reference_free(new_reference);
+	git_reference_free(looked_up_ref);
+	git_reference_free(resolved_ref);
+}
+
+void test_refs_create__oid(void)
+{
+   // create a new OID reference
+	git_reference *new_reference, *looked_up_ref;
+	git_repository *repo2;
+	git_oid id;
+
+	const char *new_head = "refs/heads/new-head";
+
+	git_oid_fromstr(&id, current_master_tip);
+
+	/* Create and write the new object id reference */
+	cl_git_pass(git_reference_create(&new_reference, g_repo, new_head, &id, 0, NULL));
+
+	/* Ensure the reference can be looked-up... */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head));
+	cl_assert(git_reference_type(looked_up_ref) & GIT_REF_OID);
+	cl_assert(reference_is_packed(looked_up_ref) == 0);
+	cl_assert_equal_s(looked_up_ref->name, new_head);
+
+	/* ...and that it points to the current master tip */
+	cl_assert_equal_oid(&id, git_reference_target(looked_up_ref));
+	git_reference_free(looked_up_ref);
+
+	/* Similar test with a fresh new repository */
+	cl_git_pass(git_repository_open(&repo2, "testrepo"));
+
+	cl_git_pass(git_reference_lookup(&looked_up_ref, repo2, new_head));
+	cl_assert_equal_oid(&id, git_reference_target(looked_up_ref));
+
+	git_repository_free(repo2);
+
+	git_reference_free(new_reference);
+	git_reference_free(looked_up_ref);
+}
+
+void test_refs_create__oid_unknown(void)
+{
+   // Can not create a new OID reference which targets at an unknown id
+	git_reference *new_reference, *looked_up_ref;
+	git_oid id;
+
+	const char *new_head = "refs/heads/new-head";
+
+	git_oid_fromstr(&id, "deadbeef3f795b2b4353bcce3a527ad0a4f7f644");
+
+	/* Create and write the new object id reference */
+	cl_git_fail(git_reference_create(&new_reference, g_repo, new_head, &id, 0, NULL));
+
+	/* Ensure the reference can't be looked-up... */
+	cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, new_head));
+}
+
+void test_refs_create__propagate_eexists(void)
+{
+	int error;
+	git_oid oid;
+	git_reference *ref;
+
+	/* Make sure it works for oid and for symbolic both */
+	git_oid_fromstr(&oid, current_master_tip);
+	error = git_reference_create(&ref, g_repo, current_head_target, &oid, false, NULL);
+	cl_assert(error == GIT_EEXISTS);
+
+	error = git_reference_symbolic_create(&ref, g_repo, "HEAD", current_head_target, false, NULL);
+	cl_assert(error == GIT_EEXISTS);
+}
+
+static void test_invalid_name(const char *name)
+{
+	git_reference *new_reference;
+	git_oid id;
+
+	git_oid_fromstr(&id, current_master_tip);
+
+	cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_create(
+		&new_reference, g_repo, name, &id, 0, NULL));
+
+	cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_symbolic_create(
+		&new_reference, g_repo, name, current_head_target, 0, NULL));
+}
+
+void test_refs_create__creating_a_reference_with_an_invalid_name_returns_EINVALIDSPEC(void)
+{
+	test_invalid_name("refs/heads/inv@{id");
+	test_invalid_name("refs/heads/back\\slash");
+
+	test_invalid_name("refs/heads/foo ");
+	test_invalid_name("refs/heads/foo /bar");
+	test_invalid_name("refs/heads/com1:bar/foo");
+
+	test_invalid_name("refs/heads/e:");
+	test_invalid_name("refs/heads/c:/foo");
+
+	test_invalid_name("refs/heads/foo.");
+}
+
+static void test_win32_name(const char *name)
+{
+	git_reference *new_reference = NULL;
+	git_oid id;
+	int ret;
+
+	git_oid_fromstr(&id, current_master_tip);
+
+	ret = git_reference_create(&new_reference, g_repo, name, &id, 0, NULL);
+
+#ifdef GIT_WIN32
+	cl_assert_equal_i(GIT_EINVALIDSPEC, ret);
+#else
+	cl_git_pass(ret);
+#endif
+
+	git_reference_free(new_reference);
+}
+
+void test_refs_create__creating_a_loose_ref_with_invalid_windows_name(void)
+{
+	test_win32_name("refs/heads/foo./bar");
+
+	test_win32_name("refs/heads/aux");
+	test_win32_name("refs/heads/aux.foo/bar");
+
+	test_win32_name("refs/heads/com1");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/createwithlog.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/createwithlog.c
new file mode 100755
index 0000000..4f64363
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/createwithlog.c
@@ -0,0 +1,47 @@
+#include "clar_libgit2.h"
+
+#include "repository.h"
+#include "git2/reflog.h"
+#include "reflog.h"
+#include "ref_helpers.h"
+
+static const char *current_master_tip = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750";
+
+static git_repository *g_repo;
+
+void test_refs_createwithlog__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo.git");
+}
+
+void test_refs_createwithlog__cleanup(void)
+{
+   cl_git_sandbox_cleanup();
+}
+
+void test_refs_createwithlog__creating_a_direct_reference_adds_a_reflog_entry(void)
+{
+	git_reference *reference;
+	git_oid id;
+	git_reflog *reflog;
+	const git_reflog_entry *entry;
+
+	const char *name = "refs/heads/new-head";
+	const char *message = "You've been logged, mate!";
+
+	git_oid_fromstr(&id, current_master_tip);
+
+	cl_git_pass(
+		git_reference_create(&reference, g_repo, name, &id, 0, message));
+
+	cl_git_pass(git_reflog_read(&reflog, g_repo, name));
+	cl_assert_equal_sz(1, git_reflog_entrycount(reflog));
+
+	entry = git_reflog_entry_byindex(reflog, 0);
+	cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) == 0);
+	cl_assert_equal_oid(&id, &entry->oid_cur);
+	cl_assert_equal_s(message, entry->msg);
+
+	git_reflog_free(reflog);
+	git_reference_free(reference);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/delete.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/delete.c
new file mode 100755
index 0000000..a1b9e25
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/delete.c
@@ -0,0 +1,107 @@
+#include "clar_libgit2.h"
+
+#include "fileops.h"
+#include "git2/reflog.h"
+#include "git2/refdb.h"
+#include "reflog.h"
+#include "ref_helpers.h"
+
+static const char *packed_test_head_name = "refs/heads/packed-test";
+static const char *current_master_tip = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750";
+
+static git_repository *g_repo;
+
+
+
+void test_refs_delete__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_refs_delete__cleanup(void)
+{
+   cl_git_sandbox_cleanup();
+}
+
+
+
+void test_refs_delete__packed_loose(void)
+{
+   // deleting a ref which is both packed and loose should remove both tracks in the filesystem
+	git_reference *looked_up_ref, *another_looked_up_ref;
+	git_buf temp_path = GIT_BUF_INIT;
+
+	/* Ensure the loose reference exists on the file system */
+	cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), packed_test_head_name));
+	cl_assert(git_path_exists(temp_path.ptr));
+
+	/* Lookup the reference */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_test_head_name));
+
+	/* Ensure it's the loose version that has been found */
+	cl_assert(reference_is_packed(looked_up_ref) == 0);
+
+	/* Now that the reference is deleted... */
+	cl_git_pass(git_reference_delete(looked_up_ref));
+	git_reference_free(looked_up_ref);
+
+	/* Looking up the reference once again should not retrieve it */
+	cl_git_fail(git_reference_lookup(&another_looked_up_ref, g_repo, packed_test_head_name));
+
+	/* Ensure the loose reference doesn't exist any longer on the file system */
+	cl_assert(!git_path_exists(temp_path.ptr));
+
+	git_reference_free(another_looked_up_ref);
+	git_buf_free(&temp_path);
+}
+
+void test_refs_delete__packed_only(void)
+{
+   // can delete a just packed reference
+	git_reference *ref;
+	git_refdb *refdb;
+	git_oid id;
+	const char *new_ref = "refs/heads/new_ref";
+
+	git_oid_fromstr(&id, current_master_tip);
+
+	/* Create and write the new object id reference */
+	cl_git_pass(git_reference_create(&ref, g_repo, new_ref, &id, 0, NULL));
+	git_reference_free(ref);
+
+	/* Lookup the reference */
+	cl_git_pass(git_reference_lookup(&ref, g_repo, new_ref));
+
+	/* Ensure it's a loose reference */
+	cl_assert(reference_is_packed(ref) == 0);
+
+	/* Pack all existing references */
+	cl_git_pass(git_repository_refdb(&refdb, g_repo));
+	cl_git_pass(git_refdb_compress(refdb));
+
+	/* Reload the reference from disk */
+	git_reference_free(ref);
+	cl_git_pass(git_reference_lookup(&ref, g_repo, new_ref));
+
+	/* Ensure it's a packed reference */
+	cl_assert(reference_is_packed(ref) == 1);
+
+	/* This should pass */
+	cl_git_pass(git_reference_delete(ref));
+	git_reference_free(ref);
+	git_refdb_free(refdb);
+}
+
+void test_refs_delete__remove(void)
+{
+	git_reference *ref;
+
+	/* Check that passing no old values lets us delete */
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, packed_test_head_name));
+	git_reference_free(ref);
+
+	cl_git_pass(git_reference_remove(g_repo, packed_test_head_name));
+
+	cl_git_fail(git_reference_lookup(&ref, g_repo, packed_test_head_name));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/foreachglob.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/foreachglob.c
new file mode 100755
index 0000000..a09191e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/foreachglob.c
@@ -0,0 +1,95 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+
+static git_repository *repo;
+static git_reference *fake_remote;
+
+void test_refs_foreachglob__initialize(void)
+{
+	git_oid id;
+
+	cl_fixture_sandbox("testrepo.git");
+	cl_git_pass(git_repository_open(&repo, "testrepo.git"));
+
+	cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"));
+	cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0, NULL));
+}
+
+void test_refs_foreachglob__cleanup(void)
+{
+	git_reference_free(fake_remote);
+	fake_remote = NULL;
+
+	git_repository_free(repo);
+	repo = NULL;
+
+	cl_fixture_cleanup("testrepo.git");
+}
+
+static int count_cb(const char *reference_name, void *payload)
+{
+	int *count = (int *)payload;
+
+	GIT_UNUSED(reference_name);
+
+	(*count)++;
+
+	return 0;
+}
+
+static void assert_retrieval(const char *glob, int expected_count)
+{
+	int count = 0;
+
+	cl_git_pass(git_reference_foreach_glob(repo, glob, count_cb, &count));
+
+	cl_assert_equal_i(expected_count, count);
+}
+
+void test_refs_foreachglob__retrieve_all_refs(void)
+{
+	/* 12 heads (including one packed head) + 1 note + 2 remotes + 7 tags */
+	assert_retrieval("*", 22);
+}
+
+void test_refs_foreachglob__retrieve_remote_branches(void)
+{
+	assert_retrieval("refs/remotes/*", 2);
+}
+
+void test_refs_foreachglob__retrieve_local_branches(void)
+{
+	assert_retrieval("refs/heads/*", 12);
+}
+
+void test_refs_foreachglob__retrieve_partially_named_references(void)
+{
+	/*
+	 * refs/heads/packed-test, refs/heads/test
+	 * refs/remotes/test/master, refs/tags/test
+	 */
+
+	assert_retrieval("*test*", 4);
+}
+
+
+static int interrupt_cb(const char *reference_name, void *payload)
+{
+	int *count = (int *)payload;
+
+	GIT_UNUSED(reference_name);
+
+	(*count)++;
+
+	return (*count == 11) ? -1000 : 0;
+}
+
+void test_refs_foreachglob__can_cancel(void)
+{
+	int count = 0;
+
+	cl_assert_equal_i(-1000, git_reference_foreach_glob(
+		repo, "*", interrupt_cb, &count) );
+
+	cl_assert_equal_i(11, count);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/isvalidname.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/isvalidname.c
new file mode 100755
index 0000000..65c70ba
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/isvalidname.c
@@ -0,0 +1,31 @@
+#include "clar_libgit2.h"
+
+void test_refs_isvalidname__can_detect_invalid_formats(void)
+{
+	cl_assert_equal_i(false, git_reference_is_valid_name("refs/tags/0.17.0^{}"));
+	cl_assert_equal_i(false, git_reference_is_valid_name("TWO/LEVELS"));
+	cl_assert_equal_i(false, git_reference_is_valid_name("ONE.LEVEL"));
+	cl_assert_equal_i(false, git_reference_is_valid_name("HEAD/"));
+	cl_assert_equal_i(false, git_reference_is_valid_name("NO_TRAILING_UNDERSCORE_"));
+	cl_assert_equal_i(false, git_reference_is_valid_name("_NO_LEADING_UNDERSCORE"));
+	cl_assert_equal_i(false, git_reference_is_valid_name("HEAD/aa"));
+	cl_assert_equal_i(false, git_reference_is_valid_name("lower_case"));
+	cl_assert_equal_i(false, git_reference_is_valid_name("/stupid/name/master"));
+	cl_assert_equal_i(false, git_reference_is_valid_name("/"));
+	cl_assert_equal_i(false, git_reference_is_valid_name("//"));
+	cl_assert_equal_i(false, git_reference_is_valid_name(""));
+	cl_assert_equal_i(false, git_reference_is_valid_name("refs/heads/sub.lock/webmatrix"));
+}
+
+void test_refs_isvalidname__wont_hopefully_choke_on_valid_formats(void)
+{
+	cl_assert_equal_i(true, git_reference_is_valid_name("refs/tags/0.17.0"));
+	cl_assert_equal_i(true, git_reference_is_valid_name("refs/LEVELS"));
+	cl_assert_equal_i(true, git_reference_is_valid_name("HEAD"));
+	cl_assert_equal_i(true, git_reference_is_valid_name("ONE_LEVEL"));
+	cl_assert_equal_i(true, git_reference_is_valid_name("refs/stash"));
+	cl_assert_equal_i(true, git_reference_is_valid_name("refs/remotes/origin/bim_with_3d at 11296"));
+	cl_assert_equal_i(true, git_reference_is_valid_name("refs/master{yesterday"));
+	cl_assert_equal_i(true, git_reference_is_valid_name("refs/master}yesterday"));
+	cl_assert_equal_i(true, git_reference_is_valid_name("refs/master{yesterday}"));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/iterator.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/iterator.c
new file mode 100755
index 0000000..c774513
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/iterator.c
@@ -0,0 +1,221 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+#include "vector.h"
+
+static git_repository *repo;
+
+void test_refs_iterator__initialize(void)
+{
+	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+}
+
+void test_refs_iterator__cleanup(void)
+{
+	git_repository_free(repo);
+}
+
+static const char *refnames[] = {
+	"refs/heads/br2",
+	"refs/heads/cannot-fetch",
+	"refs/heads/chomped",
+	"refs/heads/haacked",
+	"refs/heads/master",
+	"refs/heads/not-good",
+	"refs/heads/packed",
+	"refs/heads/packed-test",
+	"refs/heads/subtrees",
+	"refs/heads/test",
+	"refs/heads/track-local",
+	"refs/heads/trailing",
+	"refs/notes/fanout",
+	"refs/remotes/test/master",
+	"refs/tags/annotated_tag_to_blob",
+	"refs/tags/e90810b",
+	"refs/tags/hard_tag",
+	"refs/tags/point_to_blob",
+	"refs/tags/taggerless",
+	"refs/tags/test",
+	"refs/tags/wrapped_tag",
+};
+
+static int refcmp_cb(const void *a, const void *b)
+{
+	const git_reference *refa = (const git_reference *)a;
+	const git_reference *refb = (const git_reference *)b;
+
+	return strcmp(refa->name, refb->name);
+}
+
+static void assert_all_refnames_match(git_vector *output)
+{
+	size_t i;
+	git_reference *ref;
+
+	cl_assert_equal_sz(output->length, ARRAY_SIZE(refnames));
+
+	git_vector_sort(output);
+
+	git_vector_foreach(output, i, ref) {
+		cl_assert_equal_s(ref->name, refnames[i]);
+		git_reference_free(ref);
+	}
+
+	git_vector_free(output);
+}
+
+void test_refs_iterator__list(void)
+{
+	git_reference_iterator *iter;
+	git_vector output;
+	git_reference *ref;
+
+	cl_git_pass(git_vector_init(&output, 32, &refcmp_cb));
+	cl_git_pass(git_reference_iterator_new(&iter, repo));
+
+	while (1) {
+		int error = git_reference_next(&ref, iter);
+		if (error == GIT_ITEROVER)
+			break;
+		cl_git_pass(error);
+		cl_git_pass(git_vector_insert(&output, ref));
+	}
+
+	git_reference_iterator_free(iter);
+
+	assert_all_refnames_match(&output);
+}
+
+void test_refs_iterator__empty(void)
+{
+	git_reference_iterator *iter;
+	git_odb *odb;
+	git_reference *ref;
+	git_repository *empty;
+
+	cl_git_pass(git_odb_new(&odb));
+	cl_git_pass(git_repository_wrap_odb(&empty, odb));
+
+	cl_git_pass(git_reference_iterator_new(&iter, empty));
+	cl_assert_equal_i(GIT_ITEROVER, git_reference_next(&ref, iter));
+
+	git_reference_iterator_free(iter);
+	git_odb_free(odb);
+	git_repository_free(empty);
+}
+
+static int refs_foreach_cb(git_reference *reference, void *payload)
+{
+	git_vector *output = payload;
+	cl_git_pass(git_vector_insert(output, reference));
+	return 0;
+}
+
+void test_refs_iterator__foreach(void)
+{
+	git_vector output;
+	cl_git_pass(git_vector_init(&output, 32, &refcmp_cb));
+	cl_git_pass(git_reference_foreach(repo, refs_foreach_cb, &output));
+	assert_all_refnames_match(&output);
+}
+
+static int refs_foreach_cancel_cb(git_reference *reference, void *payload)
+{
+	int *cancel_after = payload;
+
+	git_reference_free(reference);
+
+	if (!*cancel_after)
+		return -333;
+	(*cancel_after)--;
+	return 0;
+}
+
+void test_refs_iterator__foreach_can_cancel(void)
+{
+	int cancel_after = 3;
+	cl_git_fail_with(
+		git_reference_foreach(repo, refs_foreach_cancel_cb, &cancel_after),
+		-333);
+	cl_assert_equal_i(0, cancel_after);
+}
+
+static int refs_foreach_name_cb(const char *name, void *payload)
+{
+	git_vector *output = payload;
+	cl_git_pass(git_vector_insert(output, git__strdup(name)));
+	return 0;
+}
+
+void test_refs_iterator__foreach_name(void)
+{
+	git_vector output;
+	size_t i;
+	char *name;
+
+	cl_git_pass(git_vector_init(&output, 32, &git__strcmp_cb));
+	cl_git_pass(
+		git_reference_foreach_name(repo, refs_foreach_name_cb, &output));
+
+	cl_assert_equal_sz(output.length, ARRAY_SIZE(refnames));
+	git_vector_sort(&output);
+
+	git_vector_foreach(&output, i, name) {
+		cl_assert_equal_s(name, refnames[i]);
+		git__free(name);
+	}
+
+	git_vector_free(&output);
+}
+
+static int refs_foreach_name_cancel_cb(const char *name, void *payload)
+{
+	int *cancel_after = payload;
+	if (!*cancel_after)
+		return -333;
+	GIT_UNUSED(name);
+	(*cancel_after)--;
+	return 0;
+}
+
+void test_refs_iterator__foreach_name_can_cancel(void)
+{
+	int cancel_after = 5;
+	cl_git_fail_with(
+		git_reference_foreach_name(
+			repo, refs_foreach_name_cancel_cb, &cancel_after),
+		-333);
+	cl_assert_equal_i(0, cancel_after);
+}
+
+void test_refs_iterator__concurrent_delete(void)
+{
+	git_reference_iterator *iter;
+	size_t full_count = 0, concurrent_count = 0;
+	const char *name;
+	int error;
+
+	git_repository_free(repo);
+	repo = cl_git_sandbox_init("testrepo");
+
+	cl_git_pass(git_reference_iterator_new(&iter, repo));
+	while ((error = git_reference_next_name(&name, iter)) == 0) {
+		full_count++;
+	}
+
+	git_reference_iterator_free(iter);
+	cl_assert_equal_i(GIT_ITEROVER, error);
+
+	cl_git_pass(git_reference_iterator_new(&iter, repo));
+	while ((error = git_reference_next_name(&name, iter)) == 0) {
+		cl_git_pass(git_reference_remove(repo, name));
+		concurrent_count++;
+	}
+
+	git_reference_iterator_free(iter);
+	cl_assert_equal_i(GIT_ITEROVER, error);
+
+	cl_assert_equal_i(full_count, concurrent_count);
+
+	cl_git_sandbox_cleanup();
+	repo = NULL;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/list.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/list.c
new file mode 100755
index 0000000..374943b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/list.c
@@ -0,0 +1,57 @@
+#include "clar_libgit2.h"
+
+#include "repository.h"
+#include "git2/reflog.h"
+#include "reflog.h"
+
+static git_repository *g_repo;
+
+
+
+void test_refs_list__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_refs_list__cleanup(void)
+{
+   cl_git_sandbox_cleanup();
+}
+
+
+
+void test_refs_list__all(void)
+{
+   // try to list all the references in our test repo
+	git_strarray ref_list;
+
+	cl_git_pass(git_reference_list(&ref_list, g_repo));
+
+	/*{
+		unsigned short i;
+		for (i = 0; i < ref_list.count; ++i)
+			printf("# %s\n", ref_list.strings[i]);
+	}*/
+
+	/* We have exactly 12 refs in total if we include the packed ones:
+	 * there is a reference that exists both in the packfile and as
+	 * loose, but we only list it once */
+	cl_assert_equal_i((int)ref_list.count, 15);
+
+	git_strarray_free(&ref_list);
+}
+
+void test_refs_list__do_not_retrieve_references_which_name_end_with_a_lock_extension(void)
+{
+	git_strarray ref_list;
+
+	/* Create a fake locked reference */
+	cl_git_mkfile(
+		"./testrepo/.git/refs/heads/hanwen.lock",
+		"144344043ba4d4a405da03de3844aa829ae8be0e\n");
+
+	cl_git_pass(git_reference_list(&ref_list, g_repo));
+	cl_assert_equal_i((int)ref_list.count, 15);
+
+	git_strarray_free(&ref_list);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/listall.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/listall.c
new file mode 100755
index 0000000..c696fbb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/listall.c
@@ -0,0 +1,47 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+
+static git_repository *repo;
+static git_strarray ref_list;
+
+static void ensure_no_refname_starts_with_a_forward_slash(const char *path)
+{
+	size_t i;
+
+	cl_git_pass(git_repository_open(&repo, path));
+	cl_git_pass(git_reference_list(&ref_list, repo));
+
+	cl_assert(ref_list.count > 0);
+
+	for (i = 0; i < ref_list.count; i++)
+		cl_assert(git__prefixcmp(ref_list.strings[i], "/") != 0);
+
+	git_strarray_free(&ref_list);
+	git_repository_free(repo);
+}
+
+void test_refs_listall__from_repository_opened_through_workdir_path(void)
+{
+	cl_fixture_sandbox("status");
+	cl_git_pass(p_rename("status/.gitted", "status/.git"));
+
+	ensure_no_refname_starts_with_a_forward_slash("status");
+
+	cl_fixture_cleanup("status");
+}
+
+void test_refs_listall__from_repository_opened_through_gitdir_path(void)
+{
+	ensure_no_refname_starts_with_a_forward_slash(cl_fixture("testrepo.git"));
+}
+
+void test_refs_listall__from_repository_with_no_trailing_newline(void)
+{
+	cl_git_pass(git_repository_open(&repo, cl_fixture("bad_tag.git")));
+	cl_git_pass(git_reference_list(&ref_list, repo));
+
+	cl_assert(ref_list.count > 0);
+
+	git_strarray_free(&ref_list);
+	git_repository_free(repo);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/lookup.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/lookup.c
new file mode 100755
index 0000000..d076e49
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/lookup.c
@@ -0,0 +1,60 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+
+static git_repository *g_repo;
+
+void test_refs_lookup__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo.git");
+}
+
+void test_refs_lookup__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_refs_lookup__with_resolve(void)
+{
+	git_reference *a, *b, *temp;
+
+	cl_git_pass(git_reference_lookup(&temp, g_repo, "HEAD"));
+	cl_git_pass(git_reference_resolve(&a, temp));
+	git_reference_free(temp);
+
+	cl_git_pass(git_reference_lookup_resolved(&b, g_repo, "HEAD", 5));
+	cl_assert(git_reference_cmp(a, b) == 0);
+	git_reference_free(b);
+
+	cl_git_pass(git_reference_lookup_resolved(&b, g_repo, "HEAD_TRACKER", 5));
+	cl_assert(git_reference_cmp(a, b) == 0);
+	git_reference_free(b);
+
+	git_reference_free(a);
+}
+
+void test_refs_lookup__invalid_name(void)
+{
+	git_oid oid;
+	cl_git_fail(git_reference_name_to_id(&oid, g_repo, "/refs/tags/point_to_blob"));
+}
+
+void test_refs_lookup__oid(void)
+{
+	git_oid tag, expected;
+
+	cl_git_pass(git_reference_name_to_id(&tag, g_repo, "refs/tags/point_to_blob"));
+	cl_git_pass(git_oid_fromstr(&expected, "1385f264afb75a56a5bec74243be9b367ba4ca08"));
+	cl_assert_equal_oid(&expected, &tag);
+}
+
+void test_refs_lookup__namespace(void)
+{
+	int error;
+	git_reference *ref;
+
+	error = git_reference_lookup(&ref, g_repo, "refs/heads");
+	cl_assert_equal_i(error, GIT_ENOTFOUND);
+
+	error = git_reference_lookup(&ref, g_repo, "refs/heads/");
+	cl_assert_equal_i(error, GIT_EINVALIDSPEC);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/normalize.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/normalize.c
new file mode 100755
index 0000000..7f313ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/normalize.c
@@ -0,0 +1,403 @@
+#include "clar_libgit2.h"
+
+#include "repository.h"
+#include "git2/reflog.h"
+#include "reflog.h"
+
+// Helpers
+static void ensure_refname_normalized(
+	unsigned int flags,
+	const char *input_refname,
+	const char *expected_refname)
+{
+	char buffer_out[GIT_REFNAME_MAX];
+
+	cl_git_pass(git_reference_normalize_name(buffer_out, sizeof(buffer_out), input_refname, flags));
+
+	cl_assert_equal_s(expected_refname, buffer_out);
+}
+
+static void ensure_refname_invalid(unsigned int flags, const char *input_refname)
+{
+	char buffer_out[GIT_REFNAME_MAX];
+
+	cl_assert_equal_i(
+		GIT_EINVALIDSPEC,
+		git_reference_normalize_name(buffer_out, sizeof(buffer_out), input_refname, flags));
+}
+
+void test_refs_normalize__can_normalize_a_direct_reference_name(void)
+{
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_NORMAL, "refs/dummy/a", "refs/dummy/a");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_NORMAL, "refs/stash", "refs/stash");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_NORMAL, "refs/tags/a", "refs/tags/a");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_NORMAL, "refs/heads/a/b", "refs/heads/a/b");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_NORMAL, "refs/heads/a./b", "refs/heads/a./b");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_NORMAL, "refs/heads/v at ation", "refs/heads/v at ation");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_NORMAL, "refs///heads///a", "refs/heads/a");
+}
+
+void test_refs_normalize__cannot_normalize_any_direct_reference_name(void)
+{
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "a");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "/a");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "//a");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "/refs/heads/a/");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "refs/heads/a/");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "refs/heads/a.");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "refs/heads/a.lock");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "refs/heads/foo?bar");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "refs/heads\foo");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_NORMAL, "refs/heads/v at ation", "refs/heads/v at ation");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_NORMAL, "refs///heads///a", "refs/heads/a");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "refs/heads/.a/b");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "refs/heads/foo/../bar");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "refs/heads/foo..bar");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "refs/heads/./foo");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "refs/heads/v@{ation");
+}
+
+void test_refs_normalize__symbolic(void)
+{
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "heads\foo");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "/");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "///");
+
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "ALL_CAPS_AND_UNDERSCORES", "ALL_CAPS_AND_UNDERSCORES");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/MixedCasing", "refs/MixedCasing");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs///heads///a", "refs/heads/a");
+
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "HEAD", "HEAD");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "MERGE_HEAD", "MERGE_HEAD");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "FETCH_HEAD", "FETCH_HEAD");
+}
+
+/* Ported from JGit, BSD licence.
+ * See https://github.com/spearce/JGit/commit/e4bf8f6957bbb29362575d641d1e77a02d906739
+ *
+ * Copyright (C) 2009, Google Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Git Development Community nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ 
+void test_refs_normalize__jgit_suite(void)
+{
+	// tests borrowed from JGit
+
+/* EmptyString */
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "/");
+
+/* MustHaveTwoComponents */
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_NORMAL, "master");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_NORMAL, "heads/master", "heads/master");
+
+/* ValidHead */
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master", "refs/heads/master");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/pu", "refs/heads/pu");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/z", "refs/heads/z");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/FoO", "refs/heads/FoO");
+
+/* ValidTag */
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/tags/v1.0", "refs/tags/v1.0");
+
+/* NoLockSuffix */
+	ensure_refname_invalid(GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master.lock");
+
+/* NoDirectorySuffix */
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master/");
+
+/* NoSpace */
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/i haz space");
+
+/* NoAsciiControlCharacters */
+	{
+		char c;
+		char buffer[GIT_REFNAME_MAX];
+		for (c = '\1'; c < ' '; c++) {
+			strncpy(buffer, "refs/heads/mast", 15);
+			strncpy(buffer + 15, (const char *)&c, 1);
+			strncpy(buffer + 16, "er", 2);
+			buffer[18 - 1] = '\0';
+			ensure_refname_invalid(GIT_REF_FORMAT_ALLOW_ONELEVEL, buffer);
+		}
+	}
+
+/* NoBareDot */
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/.");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/..");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/./master");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/../master");
+
+/* NoLeadingOrTrailingDot */
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, ".");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/.bar");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/..bar");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/bar.");
+
+/* ContainsDot */
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/m.a.s.t.e.r", "refs/heads/m.a.s.t.e.r");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master..pu");
+
+/* NoMagicRefCharacters */
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master^");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/^master");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "^refs/heads/master");
+
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master~");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/~master");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "~refs/heads/master");
+
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master:");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/:master");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, ":refs/heads/master");
+
+/* ShellGlob */
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master?");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/?master");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "?refs/heads/master");
+
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master[");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/[master");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "[refs/heads/master");
+
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master*");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/*master");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "*refs/heads/master");
+
+/* ValidSpecialCharacters */
+	ensure_refname_normalized
+		(GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/!", "refs/heads/!");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/\"", "refs/heads/\"");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/#", "refs/heads/#");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/$", "refs/heads/$");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/%", "refs/heads/%");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/&", "refs/heads/&");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/'", "refs/heads/'");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/(", "refs/heads/(");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/)", "refs/heads/)");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/+", "refs/heads/+");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/,", "refs/heads/,");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/-", "refs/heads/-");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/;", "refs/heads/;");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/<", "refs/heads/<");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/=", "refs/heads/=");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/>", "refs/heads/>");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/@", "refs/heads/@");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/]", "refs/heads/]");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/_", "refs/heads/_");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/`", "refs/heads/`");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/{", "refs/heads/{");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/|", "refs/heads/|");
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/}", "refs/heads/}");
+
+	// This is valid on UNIX, but not on Windows
+	// hence we make in invalid due to non-portability
+	//
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/\\");
+
+/* UnicodeNames */
+	/*
+	 * Currently this fails.
+	 * ensure_refname_normalized(GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/\u00e5ngstr\u00f6m", "refs/heads/\u00e5ngstr\u00f6m");
+	 */
+
+/* RefLogQueryIsValidRef */
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master@{1}");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master@{1.hour.ago}");
+}
+
+void test_refs_normalize__buffer_has_to_be_big_enough_to_hold_the_normalized_version(void)
+{
+	char buffer_out[21];
+
+	cl_git_pass(git_reference_normalize_name(
+		buffer_out, 21, "refs//heads///long///name", GIT_REF_FORMAT_NORMAL));
+	cl_git_fail(git_reference_normalize_name(
+		buffer_out, 20, "refs//heads///long///name", GIT_REF_FORMAT_NORMAL));
+}
+
+#define ONE_LEVEL_AND_REFSPEC \
+	GIT_REF_FORMAT_ALLOW_ONELEVEL \
+	| GIT_REF_FORMAT_REFSPEC_PATTERN
+
+void test_refs_normalize__refspec_pattern(void)
+{
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_REFSPEC_PATTERN, "heads/*foo/bar");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_REFSPEC_PATTERN, "heads/foo*/bar");
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_REFSPEC_PATTERN, "heads/f*o/bar");
+
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_REFSPEC_PATTERN, "foo");
+	ensure_refname_normalized(
+		ONE_LEVEL_AND_REFSPEC, "FOO", "FOO");
+
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_REFSPEC_PATTERN, "foo/bar", "foo/bar");
+	ensure_refname_normalized(
+		ONE_LEVEL_AND_REFSPEC, "foo/bar", "foo/bar");
+
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_REFSPEC_PATTERN, "*/foo", "*/foo");
+	ensure_refname_normalized(
+		ONE_LEVEL_AND_REFSPEC, "*/foo", "*/foo");
+
+	ensure_refname_normalized(
+		GIT_REF_FORMAT_REFSPEC_PATTERN, "foo/*/bar", "foo/*/bar");
+	ensure_refname_normalized(
+		ONE_LEVEL_AND_REFSPEC, "foo/*/bar", "foo/*/bar");
+
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_REFSPEC_PATTERN, "*");
+	ensure_refname_normalized(
+		ONE_LEVEL_AND_REFSPEC, "*", "*");
+
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_REFSPEC_PATTERN, "foo/*/*");
+	ensure_refname_invalid(
+		ONE_LEVEL_AND_REFSPEC, "foo/*/*");
+
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_REFSPEC_PATTERN, "*/foo/*");
+	ensure_refname_invalid(
+		ONE_LEVEL_AND_REFSPEC, "*/foo/*");
+
+	ensure_refname_invalid(
+		GIT_REF_FORMAT_REFSPEC_PATTERN, "*/*/foo");
+	ensure_refname_invalid(
+		ONE_LEVEL_AND_REFSPEC, "*/*/foo");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/overwrite.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/overwrite.c
new file mode 100755
index 0000000..5aea2a7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/overwrite.c
@@ -0,0 +1,136 @@
+#include "clar_libgit2.h"
+
+#include "repository.h"
+#include "git2/reflog.h"
+#include "reflog.h"
+
+static const char *ref_name = "refs/heads/other";
+static const char *ref_master_name = "refs/heads/master";
+static const char *ref_branch_name = "refs/heads/branch";
+static const char *ref_test_name = "refs/heads/test";
+
+static git_repository *g_repo;
+
+void test_refs_overwrite__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_refs_overwrite__cleanup(void)
+{
+   cl_git_sandbox_cleanup();
+}
+
+void test_refs_overwrite__symbolic(void)
+{
+   // Overwrite an existing symbolic reference
+	git_reference *ref, *branch_ref;
+
+	/* The target needds to exist and we need to check the name has changed */
+	cl_git_pass(git_reference_symbolic_create(&branch_ref, g_repo, ref_branch_name, ref_master_name, 0, NULL));
+	cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_branch_name, 0, NULL));
+	git_reference_free(ref);
+
+	/* Ensure it points to the right place*/
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name));
+	cl_assert(git_reference_type(ref) & GIT_REF_SYMBOLIC);
+	cl_assert_equal_s(git_reference_symbolic_target(ref), ref_branch_name);
+	git_reference_free(ref);
+
+	/* Ensure we can't create it unless we force it to */
+	cl_git_fail(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0, NULL));
+	cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 1, NULL));
+	git_reference_free(ref);
+
+	/* Ensure it points to the right place */
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name));
+	cl_assert(git_reference_type(ref) & GIT_REF_SYMBOLIC);
+	cl_assert_equal_s(git_reference_symbolic_target(ref), ref_master_name);
+
+	git_reference_free(ref);
+	git_reference_free(branch_ref);
+}
+
+void test_refs_overwrite__object_id(void)
+{
+   // Overwrite an existing object id reference
+	git_reference *ref;
+	git_oid id;
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
+	cl_assert(git_reference_type(ref) & GIT_REF_OID);
+	git_oid_cpy(&id, git_reference_target(ref));
+	git_reference_free(ref);
+
+	/* Create it */
+	cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 0, NULL));
+	git_reference_free(ref);
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_test_name));
+	cl_assert(git_reference_type(ref) & GIT_REF_OID);
+	git_oid_cpy(&id, git_reference_target(ref));
+	git_reference_free(ref);
+
+	/* Ensure we can't overwrite unless we force it */
+	cl_git_fail(git_reference_create(&ref, g_repo, ref_name, &id, 0, NULL));
+	cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 1, NULL));
+	git_reference_free(ref);
+
+	/* Ensure it has been overwritten */
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name));
+	cl_assert_equal_oid(&id, git_reference_target(ref));
+
+	git_reference_free(ref);
+}
+
+void test_refs_overwrite__object_id_with_symbolic(void)
+{
+   // Overwrite an existing object id reference with a symbolic one
+	git_reference *ref;
+	git_oid id;
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
+	cl_assert(git_reference_type(ref) & GIT_REF_OID);
+	git_oid_cpy(&id, git_reference_target(ref));
+	git_reference_free(ref);
+
+	cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 0, NULL));
+	git_reference_free(ref);
+	cl_git_fail(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0, NULL));
+	cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 1, NULL));
+	git_reference_free(ref);
+
+	/* Ensure it points to the right place */
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name));
+	cl_assert(git_reference_type(ref) & GIT_REF_SYMBOLIC);
+	cl_assert_equal_s(git_reference_symbolic_target(ref), ref_master_name);
+
+	git_reference_free(ref);
+}
+
+void test_refs_overwrite__symbolic_with_object_id(void)
+{
+   // Overwrite an existing symbolic reference with an object id one
+	git_reference *ref;
+	git_oid id;
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
+	cl_assert(git_reference_type(ref) & GIT_REF_OID);
+	git_oid_cpy(&id, git_reference_target(ref));
+	git_reference_free(ref);
+
+	/* Create the symbolic ref */
+	cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0, NULL));
+	git_reference_free(ref);
+	/* It shouldn't overwrite unless we tell it to */
+	cl_git_fail(git_reference_create(&ref, g_repo, ref_name, &id, 0, NULL));
+	cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 1, NULL));
+	git_reference_free(ref);
+
+	/* Ensure it points to the right place */
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name));
+	cl_assert(git_reference_type(ref) & GIT_REF_OID);
+	cl_assert_equal_oid(&id, git_reference_target(ref));
+
+	git_reference_free(ref);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/pack.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/pack.c
new file mode 100755
index 0000000..7dfaf6d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/pack.c
@@ -0,0 +1,105 @@
+#include "clar_libgit2.h"
+
+#include "fileops.h"
+#include "git2/reflog.h"
+#include "git2/refdb.h"
+#include "reflog.h"
+#include "refs.h"
+#include "ref_helpers.h"
+
+static const char *loose_tag_ref_name = "refs/tags/e90810b";
+
+static git_repository *g_repo;
+
+void test_refs_pack__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_refs_pack__cleanup(void)
+{
+   cl_git_sandbox_cleanup();
+}
+
+static void packall(void)
+{
+	git_refdb *refdb;
+
+	cl_git_pass(git_repository_refdb(&refdb, g_repo));
+	cl_git_pass(git_refdb_compress(refdb));
+	git_refdb_free(refdb);
+}
+
+void test_refs_pack__empty(void)
+{
+	/* create a packfile for an empty folder */
+	git_buf temp_path = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_join_n(&temp_path, '/', 3, git_repository_path(g_repo), GIT_REFS_HEADS_DIR, "empty_dir"));
+	cl_git_pass(git_futils_mkdir_r(temp_path.ptr, NULL, GIT_REFS_DIR_MODE));
+	git_buf_free(&temp_path);
+
+	packall();
+}
+
+void test_refs_pack__loose(void)
+{
+	/* create a packfile from all the loose refs in a repo */
+	git_reference *reference;
+	git_buf temp_path = GIT_BUF_INIT;
+
+	/* Ensure a known loose ref can be looked up */
+	cl_git_pass(git_reference_lookup(&reference, g_repo, loose_tag_ref_name));
+	cl_assert(reference_is_packed(reference) == 0);
+	cl_assert_equal_s(reference->name, loose_tag_ref_name);
+	git_reference_free(reference);
+
+	/*
+	 * We are now trying to pack also a loose reference
+	 * called `points_to_blob`, to make sure we can properly
+	 * pack weak tags
+	 */
+	packall();
+
+	/* Ensure the packed-refs file exists */
+	cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), GIT_PACKEDREFS_FILE));
+	cl_assert(git_path_exists(temp_path.ptr));
+
+	/* Ensure the known ref can still be looked up but is now packed */
+	cl_git_pass(git_reference_lookup(&reference, g_repo, loose_tag_ref_name));
+	cl_assert(reference_is_packed(reference));
+	cl_assert_equal_s(reference->name, loose_tag_ref_name);
+
+	/* Ensure the known ref has been removed from the loose folder structure */
+	cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), loose_tag_ref_name));
+	cl_assert(!git_path_exists(temp_path.ptr));
+
+	git_reference_free(reference);
+	git_buf_free(&temp_path);
+}
+
+void test_refs_pack__symbolic(void)
+{
+	/* create a packfile from loose refs skipping symbolic refs */
+	int i;
+	git_oid head;
+	git_reference *ref;
+	char name[128];
+
+	cl_git_pass(git_reference_name_to_id(&head, g_repo, "HEAD"));
+
+	/* make a bunch of references */
+
+	for (i = 0; i < 100; ++i) {
+		p_snprintf(name, sizeof(name), "refs/heads/symbolic-%03d", i);
+		cl_git_pass(git_reference_symbolic_create(
+			&ref, g_repo, name, "refs/heads/master", 0, NULL));
+		git_reference_free(ref);
+
+		p_snprintf(name, sizeof(name), "refs/heads/direct-%03d", i);
+		cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0, NULL));
+		git_reference_free(ref);
+	}
+
+	packall();
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/peel.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/peel.c
new file mode 100755
index 0000000..83f6109
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/peel.c
@@ -0,0 +1,119 @@
+#include "clar_libgit2.h"
+
+static git_repository *g_repo;
+static git_repository *g_peel_repo;
+
+void test_refs_peel__initialize(void)
+{
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
+	cl_git_pass(git_repository_open(&g_peel_repo, cl_fixture("peeled.git")));
+}
+
+void test_refs_peel__cleanup(void)
+{
+	git_repository_free(g_repo);
+	g_repo = NULL;
+	git_repository_free(g_peel_repo);
+	g_peel_repo = NULL;
+}
+
+static void assert_peel_generic(
+	git_repository *repo,
+	const char *ref_name,
+	git_otype requested_type,
+	const char* expected_sha,
+	git_otype expected_type)
+{
+	git_oid expected_oid;
+	git_reference *ref;
+	git_object *peeled;
+
+	cl_git_pass(git_reference_lookup(&ref, repo, ref_name));
+	
+	cl_git_pass(git_reference_peel(&peeled, ref, requested_type));
+
+	cl_git_pass(git_oid_fromstr(&expected_oid, expected_sha));
+	cl_assert_equal_oid(&expected_oid, git_object_id(peeled));
+
+	cl_assert_equal_i(expected_type, git_object_type(peeled));
+
+	git_object_free(peeled);
+	git_reference_free(ref);
+}
+
+static void assert_peel(
+	const char *ref_name,
+	git_otype requested_type,
+	const char* expected_sha,
+	git_otype expected_type)
+{
+	assert_peel_generic(g_repo, ref_name, requested_type,
+			    expected_sha, expected_type);
+}
+
+static void assert_peel_error(int error, const char *ref_name, git_otype requested_type)
+{
+	git_reference *ref;
+	git_object *peeled;
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name));
+	
+	cl_assert_equal_i(error, git_reference_peel(&peeled, ref, requested_type));
+
+	git_reference_free(ref);
+}
+
+void test_refs_peel__can_peel_a_tag(void)
+{
+	assert_peel("refs/tags/test", GIT_OBJ_TAG,
+		"b25fa35b38051e4ae45d4222e795f9df2e43f1d1", GIT_OBJ_TAG);
+	assert_peel("refs/tags/test", GIT_OBJ_COMMIT,
+		"e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_COMMIT);
+	assert_peel("refs/tags/test", GIT_OBJ_TREE,
+		"53fc32d17276939fc79ed05badaef2db09990016", GIT_OBJ_TREE);
+	assert_peel("refs/tags/point_to_blob", GIT_OBJ_BLOB,
+		"1385f264afb75a56a5bec74243be9b367ba4ca08", GIT_OBJ_BLOB);
+}
+
+void test_refs_peel__can_peel_a_branch(void)
+{
+	assert_peel("refs/heads/master", GIT_OBJ_COMMIT,
+		"a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OBJ_COMMIT);
+	assert_peel("refs/heads/master", GIT_OBJ_TREE,
+		"944c0f6e4dfa41595e6eb3ceecdb14f50fe18162", GIT_OBJ_TREE);
+}
+
+void test_refs_peel__can_peel_a_symbolic_reference(void)
+{
+	assert_peel("HEAD", GIT_OBJ_COMMIT,
+		"a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OBJ_COMMIT);
+	assert_peel("HEAD", GIT_OBJ_TREE,
+		"944c0f6e4dfa41595e6eb3ceecdb14f50fe18162", GIT_OBJ_TREE);
+}
+
+void test_refs_peel__cannot_peel_into_a_non_existing_target(void)
+{
+	assert_peel_error(GIT_EINVALIDSPEC, "refs/tags/point_to_blob", GIT_OBJ_TAG);
+}
+
+void test_refs_peel__can_peel_into_any_non_tag_object(void)
+{
+	assert_peel("refs/heads/master", GIT_OBJ_ANY,
+		"a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OBJ_COMMIT);
+	assert_peel("refs/tags/point_to_blob", GIT_OBJ_ANY,
+		"1385f264afb75a56a5bec74243be9b367ba4ca08", GIT_OBJ_BLOB);
+	assert_peel("refs/tags/test", GIT_OBJ_ANY,
+		"e90810b8df3e80c413d903f631643c716887138d", GIT_OBJ_COMMIT);
+}
+
+void test_refs_peel__can_peel_fully_peeled_packed_refs(void)
+{
+	assert_peel_generic(g_peel_repo,
+			    "refs/tags/tag-inside-tags", GIT_OBJ_ANY,
+			    "0df1a5865c8abfc09f1f2182e6a31be550e99f07",
+			    GIT_OBJ_COMMIT);
+	assert_peel_generic(g_peel_repo,
+			    "refs/foo/tag-outside-tags", GIT_OBJ_ANY,
+			    "0df1a5865c8abfc09f1f2182e6a31be550e99f07",
+			    GIT_OBJ_COMMIT);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/races.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/races.c
new file mode 100755
index 0000000..fbecf4a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/races.c
@@ -0,0 +1,152 @@
+#include "clar_libgit2.h"
+
+#include "repository.h"
+#include "git2/reflog.h"
+#include "reflog.h"
+#include "ref_helpers.h"
+
+static const char *commit_id = "099fabac3a9ea935598528c27f866e34089c2eff";
+static const char *refname = "refs/heads/master";
+static const char *other_refname = "refs/heads/foo";
+static const char *other_commit_id = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750";
+
+static git_repository *g_repo;
+
+void test_refs_races__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_refs_races__cleanup(void)
+{
+   cl_git_sandbox_cleanup();
+}
+
+void test_refs_races__create_matching(void)
+{
+	git_reference *ref, *ref2, *ref3;
+	git_oid id, other_id;
+
+	git_oid_fromstr(&id, commit_id);
+	git_oid_fromstr(&other_id, other_commit_id);
+
+	cl_git_fail_with(GIT_EMODIFIED, git_reference_create_matching(&ref, g_repo, refname, &other_id, 1, &other_id, NULL));
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, refname));
+	cl_git_pass(git_reference_create_matching(&ref2, g_repo, refname, &other_id, 1, &id, NULL));
+	cl_git_fail_with(GIT_EMODIFIED, git_reference_set_target(&ref3, ref, &other_id, NULL));
+
+	git_reference_free(ref);
+	git_reference_free(ref2);
+	git_reference_free(ref3);
+}
+
+void test_refs_races__symbolic_create_matching(void)
+{
+	git_reference *ref, *ref2, *ref3;
+	git_oid id, other_id;
+
+	git_oid_fromstr(&id, commit_id);
+	git_oid_fromstr(&other_id, other_commit_id);
+
+	cl_git_fail_with(GIT_EMODIFIED, git_reference_symbolic_create_matching(&ref, g_repo, "HEAD", other_refname, 1, other_refname, NULL));
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD"));
+	cl_git_pass(git_reference_symbolic_create_matching(&ref2, g_repo, "HEAD", other_refname, 1, NULL, refname));
+	cl_git_fail_with(GIT_EMODIFIED, git_reference_symbolic_set_target(&ref3, ref, other_refname, NULL));
+
+	git_reference_free(ref);
+	git_reference_free(ref2);
+	git_reference_free(ref3);
+}
+
+void test_refs_races__delete(void)
+{
+	git_reference *ref, *ref2;
+	git_oid id, other_id;
+
+	git_oid_fromstr(&id, commit_id);
+	git_oid_fromstr(&other_id, other_commit_id);
+
+	/* We can delete a value that matches */
+	cl_git_pass(git_reference_lookup(&ref, g_repo, refname));
+	cl_git_pass(git_reference_delete(ref));
+	git_reference_free(ref);
+
+	/* We cannot delete a symbolic value that doesn't match */
+	cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD"));
+	cl_git_pass(git_reference_symbolic_create_matching(&ref2, g_repo, "HEAD", other_refname, 1, NULL, refname));
+	cl_git_fail_with(GIT_EMODIFIED, git_reference_delete(ref));
+
+	git_reference_free(ref);
+	git_reference_free(ref2);
+
+	cl_git_pass(git_reference_create(&ref, g_repo, refname, &id, 1, NULL));
+	git_reference_free(ref);
+
+	/* We cannot delete an oid value that doesn't match */
+	cl_git_pass(git_reference_lookup(&ref, g_repo, refname));
+	cl_git_pass(git_reference_create_matching(&ref2, g_repo, refname, &other_id, 1, &id, NULL));
+	cl_git_fail_with(GIT_EMODIFIED, git_reference_delete(ref));
+
+	git_reference_free(ref);
+	git_reference_free(ref2);
+}
+
+void test_refs_races__switch_oid_to_symbolic(void)
+{
+	git_reference *ref, *ref2, *ref3;
+	git_oid id, other_id;
+
+	git_oid_fromstr(&id, commit_id);
+	git_oid_fromstr(&other_id, other_commit_id);
+
+	/* Removing a direct ref when it's currently symbolic should fail */
+	cl_git_pass(git_reference_lookup(&ref, g_repo, refname));
+	cl_git_pass(git_reference_symbolic_create(&ref2, g_repo, refname, other_refname, 1, NULL));
+	cl_git_fail_with(GIT_EMODIFIED, git_reference_delete(ref));
+
+	git_reference_free(ref);
+	git_reference_free(ref2);
+
+	cl_git_pass(git_reference_create(&ref, g_repo, refname, &id, 1, NULL));
+	git_reference_free(ref);
+
+	/* Updating a direct ref when it's currently symbolic should fail */
+	cl_git_pass(git_reference_lookup(&ref, g_repo, refname));
+	cl_git_pass(git_reference_symbolic_create(&ref2, g_repo, refname, other_refname, 1, NULL));
+	cl_git_fail_with(GIT_EMODIFIED, git_reference_set_target(&ref3, ref, &other_id, NULL));
+
+	git_reference_free(ref);
+	git_reference_free(ref2);
+	git_reference_free(ref3);
+}
+
+void test_refs_races__switch_symbolic_to_oid(void)
+{
+	git_reference *ref, *ref2, *ref3;
+	git_oid id, other_id;
+
+	git_oid_fromstr(&id, commit_id);
+	git_oid_fromstr(&other_id, other_commit_id);
+
+	/* Removing a symbolic ref when it's currently direct should fail */
+	cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD"));
+	cl_git_pass(git_reference_create(&ref2, g_repo, "HEAD", &id, 1, NULL));
+	cl_git_fail_with(GIT_EMODIFIED, git_reference_delete(ref));
+
+	git_reference_free(ref);
+	git_reference_free(ref2);
+
+	cl_git_pass(git_reference_symbolic_create(&ref, g_repo, "HEAD", refname, 1, NULL));
+	git_reference_free(ref);
+
+	/* Updating a symbolic ref when it's currently direct should fail */
+	cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD"));
+	cl_git_pass(git_reference_create(&ref2, g_repo, "HEAD", &id, 1, NULL));
+	cl_git_fail_with(GIT_EMODIFIED, git_reference_symbolic_set_target(&ref3, ref, other_refname, NULL));
+
+	git_reference_free(ref);
+	git_reference_free(ref2);
+	git_reference_free(ref3);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/read.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/read.c
new file mode 100755
index 0000000..cb42a56
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/read.c
@@ -0,0 +1,299 @@
+#include "clar_libgit2.h"
+
+#include "repository.h"
+#include "git2/reflog.h"
+#include "reflog.h"
+#include "ref_helpers.h"
+
+static const char *loose_tag_ref_name = "refs/tags/e90810b";
+static const char *non_existing_tag_ref_name = "refs/tags/i-do-not-exist";
+static const char *head_tracker_sym_ref_name = "HEAD_TRACKER";
+static const char *current_head_target = "refs/heads/master";
+static const char *current_master_tip = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750";
+static const char *packed_head_name = "refs/heads/packed";
+static const char *packed_test_head_name = "refs/heads/packed-test";
+
+static git_repository *g_repo;
+
+void test_refs_read__initialize(void)
+{
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
+}
+
+void test_refs_read__cleanup(void)
+{
+	git_repository_free(g_repo);
+	g_repo = NULL;
+}
+
+void test_refs_read__loose_tag(void)
+{
+   // lookup a loose tag reference
+	git_reference *reference;
+	git_object *object;
+	git_buf ref_name_from_tag_name = GIT_BUF_INIT;
+
+	cl_git_pass(git_reference_lookup(&reference, g_repo, loose_tag_ref_name));
+	cl_assert(git_reference_type(reference) & GIT_REF_OID);
+	cl_assert(reference_is_packed(reference) == 0);
+	cl_assert_equal_s(reference->name, loose_tag_ref_name);
+
+	cl_git_pass(git_object_lookup(&object, g_repo, git_reference_target(reference), GIT_OBJ_ANY));
+	cl_assert(object != NULL);
+	cl_assert(git_object_type(object) == GIT_OBJ_TAG);
+
+	/* Ensure the name of the tag matches the name of the reference */
+	cl_git_pass(git_buf_joinpath(&ref_name_from_tag_name, GIT_REFS_TAGS_DIR, git_tag_name((git_tag *)object)));
+	cl_assert_equal_s(ref_name_from_tag_name.ptr, loose_tag_ref_name);
+	git_buf_free(&ref_name_from_tag_name);
+
+	git_object_free(object);
+
+	git_reference_free(reference);
+}
+
+void test_refs_read__nonexisting_tag(void)
+{
+   // lookup a loose tag reference that doesn't exist
+	git_reference *reference;
+
+	cl_git_fail(git_reference_lookup(&reference, g_repo, non_existing_tag_ref_name));
+
+	git_reference_free(reference);
+}
+
+
+void test_refs_read__symbolic(void)
+{
+   // lookup a symbolic reference
+	git_reference *reference, *resolved_ref;
+	git_object *object;
+	git_oid id;
+
+	cl_git_pass(git_reference_lookup(&reference, g_repo, GIT_HEAD_FILE));
+	cl_assert(git_reference_type(reference) & GIT_REF_SYMBOLIC);
+	cl_assert(reference_is_packed(reference) == 0);
+	cl_assert_equal_s(reference->name, GIT_HEAD_FILE);
+
+	cl_git_pass(git_reference_resolve(&resolved_ref, reference));
+	cl_assert(git_reference_type(resolved_ref) == GIT_REF_OID);
+
+	cl_git_pass(git_object_lookup(&object, g_repo, git_reference_target(resolved_ref), GIT_OBJ_ANY));
+	cl_assert(object != NULL);
+	cl_assert(git_object_type(object) == GIT_OBJ_COMMIT);
+
+	git_oid_fromstr(&id, current_master_tip);
+	cl_assert_equal_oid(&id, git_object_id(object));
+
+	git_object_free(object);
+
+	git_reference_free(reference);
+	git_reference_free(resolved_ref);
+}
+
+void test_refs_read__nested_symbolic(void)
+{
+   // lookup a nested symbolic reference
+	git_reference *reference, *resolved_ref;
+	git_object *object;
+	git_oid id;
+
+	cl_git_pass(git_reference_lookup(&reference, g_repo, head_tracker_sym_ref_name));
+	cl_assert(git_reference_type(reference) & GIT_REF_SYMBOLIC);
+	cl_assert(reference_is_packed(reference) == 0);
+	cl_assert_equal_s(reference->name, head_tracker_sym_ref_name);
+
+	cl_git_pass(git_reference_resolve(&resolved_ref, reference));
+	cl_assert(git_reference_type(resolved_ref) == GIT_REF_OID);
+
+	cl_git_pass(git_object_lookup(&object, g_repo, git_reference_target(resolved_ref), GIT_OBJ_ANY));
+	cl_assert(object != NULL);
+	cl_assert(git_object_type(object) == GIT_OBJ_COMMIT);
+
+	git_oid_fromstr(&id, current_master_tip);
+	cl_assert_equal_oid(&id, git_object_id(object));
+
+	git_object_free(object);
+
+	git_reference_free(reference);
+	git_reference_free(resolved_ref);
+}
+
+void test_refs_read__head_then_master(void)
+{
+   // lookup the HEAD and resolve the master branch
+	git_reference *reference, *resolved_ref, *comp_base_ref;
+
+	cl_git_pass(git_reference_lookup(&reference, g_repo, head_tracker_sym_ref_name));
+	cl_git_pass(git_reference_resolve(&comp_base_ref, reference));
+	git_reference_free(reference);
+
+	cl_git_pass(git_reference_lookup(&reference, g_repo, GIT_HEAD_FILE));
+	cl_git_pass(git_reference_resolve(&resolved_ref, reference));
+	cl_assert_equal_oid(git_reference_target(comp_base_ref), git_reference_target(resolved_ref));
+	git_reference_free(reference);
+	git_reference_free(resolved_ref);
+
+	cl_git_pass(git_reference_lookup(&reference, g_repo, current_head_target));
+	cl_git_pass(git_reference_resolve(&resolved_ref, reference));
+	cl_assert_equal_oid(git_reference_target(comp_base_ref), git_reference_target(resolved_ref));
+	git_reference_free(reference);
+	git_reference_free(resolved_ref);
+
+	git_reference_free(comp_base_ref);
+}
+
+void test_refs_read__master_then_head(void)
+{
+   // lookup the master branch and then the HEAD
+	git_reference *reference, *master_ref, *resolved_ref;
+
+	cl_git_pass(git_reference_lookup(&master_ref, g_repo, current_head_target));
+	cl_git_pass(git_reference_lookup(&reference, g_repo, GIT_HEAD_FILE));
+
+	cl_git_pass(git_reference_resolve(&resolved_ref, reference));
+	cl_assert_equal_oid(git_reference_target(master_ref), git_reference_target(resolved_ref));
+
+	git_reference_free(reference);
+	git_reference_free(resolved_ref);
+	git_reference_free(master_ref);
+}
+
+
+void test_refs_read__packed(void)
+{
+   // lookup a packed reference
+	git_reference *reference;
+	git_object *object;
+
+	cl_git_pass(git_reference_lookup(&reference, g_repo, packed_head_name));
+	cl_assert(git_reference_type(reference) & GIT_REF_OID);
+	cl_assert(reference_is_packed(reference));
+	cl_assert_equal_s(reference->name, packed_head_name);
+
+	cl_git_pass(git_object_lookup(&object, g_repo, git_reference_target(reference), GIT_OBJ_ANY));
+	cl_assert(object != NULL);
+	cl_assert(git_object_type(object) == GIT_OBJ_COMMIT);
+
+	git_object_free(object);
+
+	git_reference_free(reference);
+}
+
+void test_refs_read__loose_first(void)
+{
+   // assure that a loose reference is looked up before a packed reference
+	git_reference *reference;
+
+	cl_git_pass(git_reference_lookup(&reference, g_repo, packed_head_name));
+	git_reference_free(reference);
+	cl_git_pass(git_reference_lookup(&reference, g_repo, packed_test_head_name));
+	cl_assert(git_reference_type(reference) & GIT_REF_OID);
+	cl_assert(reference_is_packed(reference) == 0);
+	cl_assert_equal_s(reference->name, packed_test_head_name);
+
+	git_reference_free(reference);
+}
+
+void test_refs_read__chomped(void)
+{
+	git_reference *test, *chomped;
+
+	cl_git_pass(git_reference_lookup(&test, g_repo, "refs/heads/test"));
+	cl_git_pass(git_reference_lookup(&chomped, g_repo, "refs/heads/chomped"));
+	cl_assert_equal_oid(git_reference_target(test), git_reference_target(chomped));
+
+	git_reference_free(test);
+	git_reference_free(chomped);
+}
+
+void test_refs_read__trailing(void)
+{
+	git_reference *test, *trailing;
+
+	cl_git_pass(git_reference_lookup(&test, g_repo, "refs/heads/test"));
+	cl_git_pass(git_reference_lookup(&trailing, g_repo, "refs/heads/trailing"));
+	cl_assert_equal_oid(git_reference_target(test), git_reference_target(trailing));
+	git_reference_free(trailing);
+	cl_git_pass(git_reference_lookup(&trailing, g_repo, "FETCH_HEAD"));
+
+	git_reference_free(test);
+	git_reference_free(trailing);
+}
+
+void test_refs_read__unfound_return_ENOTFOUND(void)
+{
+	git_reference *reference;
+	git_oid id;
+
+	cl_assert_equal_i(GIT_ENOTFOUND,
+		git_reference_lookup(&reference, g_repo, "TEST_MASTER"));
+	cl_assert_equal_i(GIT_ENOTFOUND,
+		git_reference_lookup(&reference, g_repo, "refs/test/master"));
+	cl_assert_equal_i(GIT_ENOTFOUND,
+		git_reference_lookup(&reference, g_repo, "refs/tags/test/master"));
+	cl_assert_equal_i(GIT_ENOTFOUND,
+		git_reference_lookup(&reference, g_repo, "refs/tags/test/farther/master"));
+
+	cl_assert_equal_i(GIT_ENOTFOUND,
+		git_reference_name_to_id(&id, g_repo, "refs/tags/test/farther/master"));
+}
+
+static void assert_is_branch(const char *name, bool expected_branchness)
+{
+	git_reference *reference;
+	cl_git_pass(git_reference_lookup(&reference, g_repo, name));
+	cl_assert_equal_i(expected_branchness, git_reference_is_branch(reference));
+	git_reference_free(reference);
+}
+
+void test_refs_read__can_determine_if_a_reference_is_a_local_branch(void)
+{
+	assert_is_branch("refs/heads/master", true);
+	assert_is_branch("refs/heads/packed", true);
+	assert_is_branch("refs/remotes/test/master", false);
+	assert_is_branch("refs/tags/e90810b", false);
+}
+
+static void assert_is_tag(const char *name, bool expected_tagness)
+{
+	git_reference *reference;
+	cl_git_pass(git_reference_lookup(&reference, g_repo, name));
+	cl_assert_equal_i(expected_tagness, git_reference_is_tag(reference));
+	git_reference_free(reference);
+}
+
+void test_refs_read__can_determine_if_a_reference_is_a_tag(void)
+{
+	assert_is_tag("refs/tags/e90810b", true);
+	assert_is_tag("refs/tags/test", true);
+	assert_is_tag("refs/heads/packed", false);
+	assert_is_tag("refs/remotes/test/master", false);
+}
+
+static void assert_is_note(const char *name, bool expected_noteness)
+{
+	git_reference *reference;
+	cl_git_pass(git_reference_lookup(&reference, g_repo, name));
+	cl_assert_equal_i(expected_noteness, git_reference_is_note(reference));
+	git_reference_free(reference);
+}
+
+void test_refs_read__can_determine_if_a_reference_is_a_note(void)
+{
+	assert_is_note("refs/notes/fanout", true);
+	assert_is_note("refs/heads/packed", false);
+	assert_is_note("refs/remotes/test/master", false);
+}
+
+void test_refs_read__invalid_name_returns_EINVALIDSPEC(void)
+{
+	git_reference *reference;
+	git_oid id;
+
+	cl_assert_equal_i(GIT_EINVALIDSPEC,
+		git_reference_lookup(&reference, g_repo, "refs/heads/Inv@{id"));
+
+	cl_assert_equal_i(GIT_EINVALIDSPEC,
+		git_reference_name_to_id(&id, g_repo, "refs/heads/Inv@{id"));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/ref_helpers.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/ref_helpers.c
new file mode 100755
index 0000000..7676e65
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/ref_helpers.c
@@ -0,0 +1,25 @@
+#include "git2/repository.h"
+#include "git2/refs.h"
+#include "common.h"
+#include "util.h"
+#include "buffer.h"
+#include "path.h"
+
+int reference_is_packed(git_reference *ref)
+{
+	git_buf ref_path = GIT_BUF_INIT;
+	int packed;
+
+	assert(ref);
+
+	if (git_buf_joinpath(&ref_path,
+		git_repository_path(git_reference_owner(ref)),
+		git_reference_name(ref)) < 0)
+		return -1;
+
+	packed = !git_path_isfile(ref_path.ptr);
+
+	git_buf_free(&ref_path);
+
+	return packed;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/ref_helpers.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/ref_helpers.h
new file mode 100755
index 0000000..0ef55bf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/ref_helpers.h
@@ -0,0 +1 @@
+int reference_is_packed(git_reference *ref);
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/reflog/drop.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/reflog/drop.c
new file mode 100755
index 0000000..916bd99
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/reflog/drop.c
@@ -0,0 +1,115 @@
+#include "clar_libgit2.h"
+
+#include "reflog.h"
+
+static git_repository *g_repo;
+static git_reflog *g_reflog;
+static size_t entrycount;
+
+void test_refs_reflog_drop__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo.git");
+
+	git_reflog_read(&g_reflog, g_repo, "HEAD");
+	entrycount = git_reflog_entrycount(g_reflog);
+}
+
+void test_refs_reflog_drop__cleanup(void)
+{
+	git_reflog_free(g_reflog);
+	g_reflog = NULL;
+
+	cl_git_sandbox_cleanup();
+}
+
+void test_refs_reflog_drop__dropping_a_non_exisiting_entry_from_the_log_returns_ENOTFOUND(void)
+{
+	cl_assert_equal_i(GIT_ENOTFOUND, git_reflog_drop(g_reflog, entrycount, 0));
+
+	cl_assert_equal_sz(entrycount, git_reflog_entrycount(g_reflog));
+}
+
+void test_refs_reflog_drop__can_drop_an_entry(void)
+{
+	cl_assert(entrycount > 4);
+
+	cl_git_pass(git_reflog_drop(g_reflog, 2, 0));
+	cl_assert_equal_sz(entrycount - 1, git_reflog_entrycount(g_reflog));
+}
+
+void test_refs_reflog_drop__can_drop_an_entry_and_rewrite_the_log_history(void)
+{
+	const git_reflog_entry *before_current;
+	const git_reflog_entry *after_current;
+	git_oid before_current_old_oid, before_current_cur_oid;
+
+	cl_assert(entrycount > 4);
+
+	before_current = git_reflog_entry_byindex(g_reflog, 1);
+
+	git_oid_cpy(&before_current_old_oid, &before_current->oid_old);
+	git_oid_cpy(&before_current_cur_oid, &before_current->oid_cur);
+
+	cl_git_pass(git_reflog_drop(g_reflog, 1, 1));
+
+	cl_assert_equal_sz(entrycount - 1, git_reflog_entrycount(g_reflog));
+
+	after_current = git_reflog_entry_byindex(g_reflog, 0);
+
+	cl_assert_equal_i(0, git_oid_cmp(&before_current_old_oid, &after_current->oid_old));
+	cl_assert(0 != git_oid_cmp(&before_current_cur_oid, &after_current->oid_cur));
+}
+
+void test_refs_reflog_drop__can_drop_the_oldest_entry(void)
+{
+	const git_reflog_entry *entry;
+
+	cl_assert(entrycount > 2);
+
+	cl_git_pass(git_reflog_drop(g_reflog, entrycount - 1, 0));
+	cl_assert_equal_sz(entrycount - 1, git_reflog_entrycount(g_reflog));
+
+	entry = git_reflog_entry_byindex(g_reflog, entrycount - 2);
+	cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) != 0);
+}
+
+void test_refs_reflog_drop__can_drop_the_oldest_entry_and_rewrite_the_log_history(void)
+{
+	const git_reflog_entry *entry;
+
+	cl_assert(entrycount > 2);
+
+	cl_git_pass(git_reflog_drop(g_reflog, entrycount - 1, 1));
+	cl_assert_equal_sz(entrycount - 1, git_reflog_entrycount(g_reflog));
+
+	entry = git_reflog_entry_byindex(g_reflog, entrycount - 2);
+	cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) == 0);
+}
+
+void test_refs_reflog_drop__can_drop_all_the_entries(void)
+{
+	cl_assert(--entrycount > 0);
+
+	do 	{
+		cl_git_pass(git_reflog_drop(g_reflog, 0, 1));
+	} while (--entrycount > 0);
+
+	cl_git_pass(git_reflog_drop(g_reflog, 0, 1));
+
+	cl_assert_equal_i(0, (int)git_reflog_entrycount(g_reflog));
+}
+
+void test_refs_reflog_drop__can_persist_deletion_on_disk(void)
+{
+	cl_assert(entrycount > 2);
+
+	cl_git_pass(git_reflog_drop(g_reflog, 0, 1));
+	cl_assert_equal_sz(entrycount - 1, git_reflog_entrycount(g_reflog));
+	cl_git_pass(git_reflog_write(g_reflog));
+
+	git_reflog_free(g_reflog);
+
+	git_reflog_read(&g_reflog, g_repo, "HEAD");
+
+	cl_assert_equal_sz(entrycount - 1, git_reflog_entrycount(g_reflog));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/reflog/reflog.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/reflog/reflog.c
new file mode 100755
index 0000000..56ec422
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/reflog/reflog.c
@@ -0,0 +1,336 @@
+#include "clar_libgit2.h"
+
+#include "fileops.h"
+#include "git2/reflog.h"
+#include "reflog.h"
+
+
+static const char *new_ref = "refs/heads/test-reflog";
+static const char *current_master_tip = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750";
+#define commit_msg "commit: bla bla"
+
+static git_repository *g_repo;
+
+
+// helpers
+static void assert_signature(const git_signature *expected, const git_signature *actual)
+{
+	cl_assert(actual);
+	cl_assert_equal_s(expected->name, actual->name);
+	cl_assert_equal_s(expected->email, actual->email);
+	cl_assert(expected->when.offset == actual->when.offset);
+	cl_assert(expected->when.time == actual->when.time);
+}
+
+
+// Fixture setup and teardown
+void test_refs_reflog_reflog__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo.git");
+}
+
+void test_refs_reflog_reflog__cleanup(void)
+{
+   cl_git_sandbox_cleanup();
+}
+
+static void assert_appends(const git_signature *committer, const git_oid *oid)
+{
+	git_repository *repo2;
+	git_reference *lookedup_ref;
+	git_reflog *reflog;
+	const git_reflog_entry *entry;
+
+	/* Reopen a new instance of the repository */
+	cl_git_pass(git_repository_open(&repo2, "testrepo.git"));
+
+	/* Lookup the previously created branch */
+	cl_git_pass(git_reference_lookup(&lookedup_ref, repo2, new_ref));
+
+	/* Read and parse the reflog for this branch */
+	cl_git_pass(git_reflog_read(&reflog, repo2, new_ref));
+	cl_assert_equal_i(3, (int)git_reflog_entrycount(reflog));
+
+	/* The first one was the creation of the branch */
+	entry = git_reflog_entry_byindex(reflog, 2);
+	cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) == 0);
+
+	entry = git_reflog_entry_byindex(reflog, 1);
+	assert_signature(committer, entry->committer);
+	cl_assert(git_oid_cmp(oid, &entry->oid_old) == 0);
+	cl_assert(git_oid_cmp(oid, &entry->oid_cur) == 0);
+	cl_assert(entry->msg == NULL);
+
+	entry = git_reflog_entry_byindex(reflog, 0);
+	assert_signature(committer, entry->committer);
+	cl_assert(git_oid_cmp(oid, &entry->oid_cur) == 0);
+	cl_assert_equal_s(commit_msg, entry->msg);
+
+	git_reflog_free(reflog);
+	git_repository_free(repo2);
+
+	git_reference_free(lookedup_ref);
+}
+
+void test_refs_reflog_reflog__append_then_read(void)
+{
+	/* write a reflog for a given reference and ensure it can be read back */
+	git_reference *ref;
+	git_oid oid;
+	git_signature *committer;
+	git_reflog *reflog;
+
+	/* Create a new branch pointing at the HEAD */
+	git_oid_fromstr(&oid, current_master_tip);
+	cl_git_pass(git_reference_create(&ref, g_repo, new_ref, &oid, 0, NULL));
+	git_reference_free(ref);
+
+	cl_git_pass(git_signature_now(&committer, "foo", "foo at bar"));
+
+	cl_git_pass(git_reflog_read(&reflog, g_repo, new_ref));
+
+	cl_git_fail(git_reflog_append(reflog, &oid, committer, "no inner\nnewline"));
+	cl_git_pass(git_reflog_append(reflog, &oid, committer, NULL));
+	cl_git_pass(git_reflog_append(reflog, &oid, committer, commit_msg "\n"));
+	cl_git_pass(git_reflog_write(reflog));
+	git_reflog_free(reflog);
+
+	assert_appends(committer, &oid);
+
+	git_signature_free(committer);
+}
+
+void test_refs_reflog_reflog__renaming_the_reference_moves_the_reflog(void)
+{
+	git_reference *master, *new_master;
+	git_buf master_log_path = GIT_BUF_INIT, moved_log_path = GIT_BUF_INIT;
+
+	git_buf_joinpath(&master_log_path, git_repository_path(g_repo), GIT_REFLOG_DIR);
+	git_buf_puts(&moved_log_path, git_buf_cstr(&master_log_path));
+	git_buf_joinpath(&master_log_path, git_buf_cstr(&master_log_path), "refs/heads/master");
+	git_buf_joinpath(&moved_log_path, git_buf_cstr(&moved_log_path), "refs/moved");
+
+	cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&master_log_path)));
+	cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&moved_log_path)));
+
+	cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master"));
+	cl_git_pass(git_reference_rename(&new_master, master, "refs/moved", 0, NULL));
+	git_reference_free(master);
+
+	cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&master_log_path)));
+	cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&moved_log_path)));
+
+	git_reference_free(new_master);
+	git_buf_free(&moved_log_path);
+	git_buf_free(&master_log_path);
+}
+
+static void assert_has_reflog(bool expected_result, const char *name)
+{
+	cl_assert_equal_i(expected_result, git_reference_has_log(g_repo, name));
+}
+
+void test_refs_reflog_reflog__reference_has_reflog(void)
+{
+	assert_has_reflog(true, "HEAD");
+	assert_has_reflog(true, "refs/heads/master");
+	assert_has_reflog(false, "refs/heads/subtrees");
+}
+
+void test_refs_reflog_reflog__reading_the_reflog_from_a_reference_with_no_log_returns_an_empty_one(void)
+{
+	git_reflog *reflog;
+	const char *refname = "refs/heads/subtrees";
+	git_buf subtrees_log_path = GIT_BUF_INIT;
+
+	git_buf_join_n(&subtrees_log_path, '/', 3, git_repository_path(g_repo), GIT_REFLOG_DIR, refname);
+	cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&subtrees_log_path)));
+
+	cl_git_pass(git_reflog_read(&reflog, g_repo, refname));
+
+	cl_assert_equal_i(0, (int)git_reflog_entrycount(reflog));
+
+	git_reflog_free(reflog);
+	git_buf_free(&subtrees_log_path);
+}
+
+void test_refs_reflog_reflog__cannot_write_a_moved_reflog(void)
+{
+	git_reference *master, *new_master;
+	git_buf master_log_path = GIT_BUF_INIT, moved_log_path = GIT_BUF_INIT;
+	git_reflog *reflog;
+
+	cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master"));
+	cl_git_pass(git_reflog_read(&reflog, g_repo, "refs/heads/master"));
+
+	cl_git_pass(git_reflog_write(reflog));
+
+	cl_git_pass(git_reference_rename(&new_master, master, "refs/moved", 0, NULL));
+	git_reference_free(master);
+
+	cl_git_fail(git_reflog_write(reflog));
+
+	git_reflog_free(reflog);
+	git_reference_free(new_master);
+	git_buf_free(&moved_log_path);
+	git_buf_free(&master_log_path);
+}
+
+void test_refs_reflog_reflog__renaming_with_an_invalid_name_returns_EINVALIDSPEC(void)
+{
+	cl_assert_equal_i(GIT_EINVALIDSPEC,
+			  git_reflog_rename(g_repo, "refs/heads/master", "refs/heads/Inv@{id"));
+}
+
+void test_refs_reflog_reflog__write_only_std_locations(void)
+{
+	git_reference *ref;
+	git_oid id;
+
+	git_oid_fromstr(&id, current_master_tip);
+
+	cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/foo", &id, 1, NULL));
+	git_reference_free(ref);
+	cl_git_pass(git_reference_create(&ref, g_repo, "refs/tags/foo", &id, 1, NULL));
+	git_reference_free(ref);
+	cl_git_pass(git_reference_create(&ref, g_repo, "refs/notes/foo", &id, 1, NULL));
+	git_reference_free(ref);
+
+	assert_has_reflog(true, "refs/heads/foo");
+	assert_has_reflog(false, "refs/tags/foo");
+	assert_has_reflog(true, "refs/notes/foo");
+
+}
+
+void test_refs_reflog_reflog__write_when_explicitly_active(void)
+{
+	git_reference *ref;
+	git_oid id;
+
+	git_oid_fromstr(&id, current_master_tip);
+	git_reference_ensure_log(g_repo, "refs/tags/foo");
+
+	cl_git_pass(git_reference_create(&ref, g_repo, "refs/tags/foo", &id, 1, NULL));
+	git_reference_free(ref);
+	assert_has_reflog(true, "refs/tags/foo");
+}
+
+void test_refs_reflog_reflog__append_to_HEAD_when_changing_current_branch(void)
+{
+	size_t nlogs, nlogs_after;
+	git_reference *ref;
+	git_reflog *log;
+	git_oid id;
+
+	cl_git_pass(git_reflog_read(&log, g_repo, "HEAD"));
+	nlogs = git_reflog_entrycount(log);
+	git_reflog_free(log);
+
+	/* Move it back */
+	git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/master", &id, 1, NULL));
+	git_reference_free(ref);
+
+	cl_git_pass(git_reflog_read(&log, g_repo, "HEAD"));
+	nlogs_after = git_reflog_entrycount(log);
+	git_reflog_free(log);
+
+	cl_assert_equal_i(nlogs_after, nlogs + 1);
+}
+
+void test_refs_reflog_reflog__do_not_append_when_no_update(void)
+{
+	size_t nlogs, nlogs_after;
+	git_reference *ref, *ref2;
+	git_reflog *log;
+
+	cl_git_pass(git_reflog_read(&log, g_repo, "HEAD"));
+	nlogs = git_reflog_entrycount(log);
+	git_reflog_free(log);
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/heads/master"));
+	cl_git_pass(git_reference_create(&ref2, g_repo, "refs/heads/master",
+					 git_reference_target(ref), 1, NULL));
+
+	git_reference_free(ref);
+	git_reference_free(ref2);
+
+	cl_git_pass(git_reflog_read(&log, g_repo, "HEAD"));
+	nlogs_after = git_reflog_entrycount(log);
+	git_reflog_free(log);
+
+	cl_assert_equal_i(nlogs_after, nlogs);
+}
+
+static void assert_no_reflog_update(void)
+{
+	size_t nlogs, nlogs_after;
+	size_t nlogs_master, nlogs_master_after;
+	git_reference *ref;
+	git_reflog *log;
+	git_oid id;
+
+	cl_git_pass(git_reflog_read(&log, g_repo, "HEAD"));
+	nlogs = git_reflog_entrycount(log);
+	git_reflog_free(log);
+
+	cl_git_pass(git_reflog_read(&log, g_repo, "refs/heads/master"));
+	nlogs_master = git_reflog_entrycount(log);
+	git_reflog_free(log);
+
+	/* Move it back */
+	git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/master", &id, 1, NULL));
+	git_reference_free(ref);
+
+	cl_git_pass(git_reflog_read(&log, g_repo, "HEAD"));
+	nlogs_after = git_reflog_entrycount(log);
+	git_reflog_free(log);
+
+	cl_assert_equal_i(nlogs_after, nlogs);
+
+	cl_git_pass(git_reflog_read(&log, g_repo, "refs/heads/master"));
+	nlogs_master_after = git_reflog_entrycount(log);
+	git_reflog_free(log);
+
+	cl_assert_equal_i(nlogs_after, nlogs);
+	cl_assert_equal_i(nlogs_master_after, nlogs_master);
+
+}
+
+void test_refs_reflog_reflog__logallrefupdates_bare_set_false(void)
+{
+	git_config *config;
+
+	cl_git_pass(git_repository_config(&config, g_repo));
+	cl_git_pass(git_config_set_bool(config, "core.logallrefupdates", false));
+	git_config_free(config);
+
+	assert_no_reflog_update();
+}
+
+void test_refs_reflog_reflog__logallrefupdates_bare_unset(void)
+{
+	git_config *config;
+
+	cl_git_pass(git_repository_config(&config, g_repo));
+	cl_git_pass(git_config_delete_entry(config, "core.logallrefupdates"));
+	git_config_free(config);
+
+	assert_no_reflog_update();
+}
+
+void test_refs_reflog_reflog__logallrefupdates_nonbare_set_false(void)
+{
+	git_config *config;
+
+	cl_git_sandbox_cleanup();
+	g_repo = cl_git_sandbox_init("testrepo");
+
+
+	cl_git_pass(git_repository_config(&config, g_repo));
+	cl_git_pass(git_config_set_bool(config, "core.logallrefupdates", false));
+	git_config_free(config);
+
+	assert_no_reflog_update();
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/rename.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/rename.c
new file mode 100755
index 0000000..6106e6c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/rename.c
@@ -0,0 +1,387 @@
+#include "clar_libgit2.h"
+
+#include "fileops.h"
+#include "git2/reflog.h"
+#include "reflog.h"
+#include "refs.h"
+#include "ref_helpers.h"
+
+static const char *loose_tag_ref_name = "refs/tags/e90810b";
+static const char *packed_head_name = "refs/heads/packed";
+static const char *packed_test_head_name = "refs/heads/packed-test";
+static const char *ref_one_name = "refs/heads/one/branch";
+static const char *ref_one_name_new = "refs/heads/two/branch";
+static const char *ref_two_name = "refs/heads/two";
+static const char *ref_master_name = "refs/heads/master";
+static const char *ref_two_name_new = "refs/heads/two/two";
+
+static git_repository *g_repo;
+
+
+
+void test_refs_rename__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo");
+	cl_git_pass(git_repository_set_ident(g_repo, "me", "foo at example.com"));
+}
+
+void test_refs_rename__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+
+
+void test_refs_rename__loose(void)
+{
+	// rename a loose reference
+	git_reference *looked_up_ref, *new_ref, *another_looked_up_ref;
+	git_buf temp_path = GIT_BUF_INIT;
+	const char *new_name = "refs/tags/Nemo/knows/refs.kung-fu";
+
+	/* Ensure the ref doesn't exist on the file system */
+	cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), new_name));
+	cl_assert(!git_path_exists(temp_path.ptr));
+
+	/* Retrieval of the reference to rename */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, loose_tag_ref_name));
+
+	/* ... which is indeed loose */
+	cl_assert(reference_is_packed(looked_up_ref) == 0);
+
+	/* Now that the reference is renamed... */
+	cl_git_pass(git_reference_rename(&new_ref, looked_up_ref, new_name, 0, NULL));
+	cl_assert_equal_s(new_ref->name, new_name);
+	git_reference_free(looked_up_ref);
+
+	/* ...It can't be looked-up with the old name... */
+	cl_git_fail(git_reference_lookup(&another_looked_up_ref, g_repo, loose_tag_ref_name));
+
+	/* ...but the new name works ok... */
+	cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, new_name));
+	cl_assert_equal_s(new_ref->name, new_name);
+
+	/* .. the new ref is loose... */
+	cl_assert(reference_is_packed(another_looked_up_ref) == 0);
+	cl_assert(reference_is_packed(new_ref) == 0);
+
+	/* ...and the ref can be found in the file system */
+	cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), new_name));
+	cl_assert(git_path_exists(temp_path.ptr));
+
+	git_reference_free(new_ref);
+	git_reference_free(another_looked_up_ref);
+	git_buf_free(&temp_path);
+}
+
+void test_refs_rename__packed(void)
+{
+	// rename a packed reference (should make it loose)
+	git_reference *looked_up_ref, *new_ref, *another_looked_up_ref;
+	git_buf temp_path = GIT_BUF_INIT;
+	const char *brand_new_name = "refs/heads/brand_new_name";
+
+	/* Ensure the ref doesn't exist on the file system */
+	cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), packed_head_name));
+	cl_assert(!git_path_exists(temp_path.ptr));
+
+	/* The reference can however be looked-up... */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
+
+	/* .. and it's packed */
+	cl_assert(reference_is_packed(looked_up_ref) != 0);
+
+	/* Now that the reference is renamed... */
+	cl_git_pass(git_reference_rename(&new_ref, looked_up_ref, brand_new_name, 0, NULL));
+	cl_assert_equal_s(new_ref->name, brand_new_name);
+	git_reference_free(looked_up_ref);
+
+	/* ...It can't be looked-up with the old name... */
+	cl_git_fail(git_reference_lookup(&another_looked_up_ref, g_repo, packed_head_name));
+
+	/* ...but the new name works ok... */
+	cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, brand_new_name));
+	cl_assert_equal_s(another_looked_up_ref->name, brand_new_name);
+
+	/* .. the ref is no longer packed... */
+	cl_assert(reference_is_packed(another_looked_up_ref) == 0);
+	cl_assert(reference_is_packed(new_ref) == 0);
+
+	/* ...and the ref now happily lives in the file system */
+	cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), brand_new_name));
+	cl_assert(git_path_exists(temp_path.ptr));
+
+	git_reference_free(new_ref);
+	git_reference_free(another_looked_up_ref);
+	git_buf_free(&temp_path);
+}
+
+void test_refs_rename__packed_doesnt_pack_others(void)
+{
+	// renaming a packed reference does not pack another reference which happens to be in both loose and pack state
+	git_reference *looked_up_ref, *another_looked_up_ref, *renamed_ref;
+	git_buf temp_path = GIT_BUF_INIT;
+	const char *brand_new_name = "refs/heads/brand_new_name";
+
+	/* Ensure the other reference exists on the file system */
+	cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), packed_test_head_name));
+	cl_assert(git_path_exists(temp_path.ptr));
+
+	/* Lookup the other reference */
+	cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, packed_test_head_name));
+
+	/* Ensure it's loose */
+	cl_assert(reference_is_packed(another_looked_up_ref) == 0);
+	git_reference_free(another_looked_up_ref);
+
+	/* Lookup the reference to rename */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
+
+	/* Ensure it's packed */
+	cl_assert(reference_is_packed(looked_up_ref) != 0);
+
+	/* Now that the reference is renamed... */
+	cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, brand_new_name, 0, NULL));
+	git_reference_free(looked_up_ref);
+
+	/* Lookup the other reference */
+	cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, packed_test_head_name));
+
+	/* Ensure it's loose */
+	cl_assert(reference_is_packed(another_looked_up_ref) == 0);
+
+	/* Ensure the other ref still exists on the file system */
+	cl_assert(git_path_exists(temp_path.ptr));
+
+	git_reference_free(renamed_ref);
+	git_reference_free(another_looked_up_ref);
+	git_buf_free(&temp_path);
+}
+
+void test_refs_rename__name_collision(void)
+{
+	// can not rename a reference with the name of an existing reference
+	git_reference *looked_up_ref, *renamed_ref;
+
+	/* An existing reference... */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
+
+	/* Can not be renamed to the name of another existing reference. */
+	cl_git_fail(git_reference_rename(&renamed_ref, looked_up_ref, packed_test_head_name, 0, NULL));
+	git_reference_free(looked_up_ref);
+
+	/* Failure to rename it hasn't corrupted its state */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
+	cl_assert_equal_s(looked_up_ref->name, packed_head_name);
+
+	git_reference_free(looked_up_ref);
+}
+
+void test_refs_rename__invalid_name(void)
+{
+	// can not rename a reference with an invalid name
+	git_reference *looked_up_ref, *renamed_ref;
+
+	/* An existing oid reference... */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_test_head_name));
+
+	/* Can not be renamed with an invalid name. */
+	cl_assert_equal_i(
+		GIT_EINVALIDSPEC,
+		git_reference_rename(&renamed_ref, looked_up_ref, "Hello! I'm a very invalid name.", 0, NULL));
+
+	/* Can not be renamed outside of the refs hierarchy
+	 * unless it's ALL_CAPS_AND_UNDERSCORES.
+	 */
+	cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_rename(&renamed_ref, looked_up_ref, "i-will-sudo-you", 0, NULL));
+
+	/* Failure to rename it hasn't corrupted its state */
+	git_reference_free(looked_up_ref);
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_test_head_name));
+	cl_assert_equal_s(looked_up_ref->name, packed_test_head_name);
+
+	git_reference_free(looked_up_ref);
+}
+
+void test_refs_rename__force_loose_packed(void)
+{
+	// can force-rename a packed reference with the name of an existing loose and packed reference
+	git_reference *looked_up_ref, *renamed_ref;
+	git_oid oid;
+
+	/* An existing reference... */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
+	git_oid_cpy(&oid, git_reference_target(looked_up_ref));
+
+	/* Can be force-renamed to the name of another existing reference. */
+	cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, packed_test_head_name, 1, NULL));
+	git_reference_free(looked_up_ref);
+	git_reference_free(renamed_ref);
+
+	/* Check we actually renamed it */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_test_head_name));
+	cl_assert_equal_s(looked_up_ref->name, packed_test_head_name);
+	cl_assert_equal_oid(&oid, git_reference_target(looked_up_ref));
+	git_reference_free(looked_up_ref);
+
+	/* And that the previous one doesn't exist any longer */
+	cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name));
+}
+
+void test_refs_rename__force_loose(void)
+{
+	// can force-rename a loose reference with the name of an existing loose reference
+	git_reference *looked_up_ref, *renamed_ref;
+	git_oid oid;
+
+	/* An existing reference... */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, "refs/heads/br2"));
+	git_oid_cpy(&oid, git_reference_target(looked_up_ref));
+
+	/* Can be force-renamed to the name of another existing reference. */
+	cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, "refs/heads/test", 1, NULL));
+	git_reference_free(looked_up_ref);
+	git_reference_free(renamed_ref);
+
+	/* Check we actually renamed it */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, "refs/heads/test"));
+	cl_assert_equal_s(looked_up_ref->name,  "refs/heads/test");
+	cl_assert_equal_oid(&oid, git_reference_target(looked_up_ref));
+	git_reference_free(looked_up_ref);
+
+	/* And that the previous one doesn't exist any longer */
+	cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, "refs/heads/br2"));
+
+	git_reference_free(looked_up_ref);
+}
+
+
+void test_refs_rename__overwrite(void)
+{
+	// can not overwrite name of existing reference
+	git_reference *ref, *ref_one, *ref_one_new, *ref_two;
+	git_refdb *refdb;
+	git_oid id;
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
+	cl_assert(git_reference_type(ref) & GIT_REF_OID);
+
+	git_oid_cpy(&id, git_reference_target(ref));
+
+	/* Create loose references */
+	cl_git_pass(git_reference_create(&ref_one, g_repo, ref_one_name, &id, 0, NULL));
+	cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0, NULL));
+
+	/* Pack everything */
+	cl_git_pass(git_repository_refdb(&refdb, g_repo));
+	cl_git_pass(git_refdb_compress(refdb));
+
+	/* Attempt to create illegal reference */
+	cl_git_fail(git_reference_create(&ref_one_new, g_repo, ref_one_name_new, &id, 0, NULL));
+
+	/* Illegal reference couldn't be created so this is supposed to fail */
+	cl_git_fail(git_reference_lookup(&ref_one_new, g_repo, ref_one_name_new));
+
+	git_reference_free(ref);
+	git_reference_free(ref_one);
+	git_reference_free(ref_one_new);
+	git_reference_free(ref_two);
+	git_refdb_free(refdb);
+}
+
+
+void test_refs_rename__prefix(void)
+{
+	// can be renamed to a new name prefixed with the old name
+	git_reference *ref, *ref_two, *looked_up_ref, *renamed_ref;
+	git_oid id;
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
+	cl_assert(git_reference_type(ref) & GIT_REF_OID);
+
+	git_oid_cpy(&id, git_reference_target(ref));
+
+	/* Create loose references */
+	cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0, NULL));
+
+	/* An existing reference... */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name));
+
+	/* Can be rename to a new name starting with the old name. */
+	cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, ref_two_name_new, 0, NULL));
+	git_reference_free(looked_up_ref);
+	git_reference_free(renamed_ref);
+
+	/* Check we actually renamed it */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new));
+	cl_assert_equal_s(looked_up_ref->name, ref_two_name_new);
+	git_reference_free(looked_up_ref);
+	cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name));
+
+	git_reference_free(ref);
+	git_reference_free(ref_two);
+	git_reference_free(looked_up_ref);
+}
+
+void test_refs_rename__move_up(void)
+{
+	// can move a reference to a upper reference hierarchy
+	git_reference *ref, *ref_two, *looked_up_ref, *renamed_ref;
+	git_oid id;
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
+	cl_assert(git_reference_type(ref) & GIT_REF_OID);
+
+	git_oid_cpy(&id, git_reference_target(ref));
+
+	/* Create loose references */
+	cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name_new, &id, 0, NULL));
+	git_reference_free(ref_two);
+
+	/* An existing reference... */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new));
+
+	/* Can be renamed upward the reference tree. */
+	cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, ref_two_name, 0, NULL));
+	git_reference_free(looked_up_ref);
+	git_reference_free(renamed_ref);
+
+	/* Check we actually renamed it */
+	cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name));
+	cl_assert_equal_s(looked_up_ref->name, ref_two_name);
+	git_reference_free(looked_up_ref);
+
+	cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new));
+	git_reference_free(ref);
+	git_reference_free(looked_up_ref);
+}
+
+void test_refs_rename__propagate_eexists(void)
+{
+	git_reference *ref, *new_ref;
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, packed_head_name));
+
+	cl_assert_equal_i(GIT_EEXISTS, git_reference_rename(&new_ref, ref, packed_test_head_name, 0, NULL));
+
+	git_reference_free(ref);
+}
+
+void test_refs_rename__writes_to_reflog(void)
+{
+	git_reference *ref, *new_ref;
+	git_reflog *log;
+	const git_reflog_entry *entry;
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
+	cl_git_pass(git_reference_rename(&new_ref, ref, ref_one_name_new, false,
+				"message"));
+	cl_git_pass(git_reflog_read(&log, g_repo, git_reference_name(new_ref)));
+	entry = git_reflog_entry_byindex(log, 0);
+	cl_assert_equal_s("message", git_reflog_entry_message(entry));
+	cl_assert_equal_s("foo at example.com", git_reflog_entry_committer(entry)->email);
+
+	git_reflog_free(log);
+	git_reference_free(ref);
+	git_reference_free(new_ref);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/revparse.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/revparse.c
new file mode 100755
index 0000000..c22c304
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/revparse.c
@@ -0,0 +1,829 @@
+#include "clar_libgit2.h"
+
+#include "git2/revparse.h"
+#include "buffer.h"
+#include "refs.h"
+#include "path.h"
+
+static git_repository *g_repo;
+static git_object *g_obj;
+
+/* Helpers */
+static void test_object_and_ref_inrepo(
+	const char *spec,
+	const char *expected_oid,
+	const char *expected_refname,
+	git_repository *repo,
+	bool assert_reference_retrieval)
+{
+	char objstr[64] = {0};
+	git_object *obj = NULL;
+	git_reference *ref = NULL;
+	int error;
+
+	error = git_revparse_ext(&obj, &ref, repo, spec);
+
+	if (expected_oid != NULL) {
+		cl_git_pass(error);
+		git_oid_fmt(objstr, git_object_id(obj));
+		cl_assert_equal_s(objstr, expected_oid);
+	} else
+		cl_git_fail(error);
+
+	if (assert_reference_retrieval) {
+		if (expected_refname == NULL)
+			cl_assert(NULL == ref);
+		else
+			cl_assert_equal_s(expected_refname, git_reference_name(ref));
+	}
+
+	git_object_free(obj);
+	git_reference_free(ref);
+}
+
+static void test_object_inrepo(const char *spec, const char *expected_oid, git_repository *repo)
+{
+	test_object_and_ref_inrepo(spec, expected_oid, NULL, repo, false);
+}
+
+static void test_id_inrepo(
+	const char *spec,
+	const char *expected_left,
+	const char *expected_right,
+	git_revparse_mode_t expected_flags,
+	git_repository *repo)
+{
+	git_revspec revspec;
+	int error = git_revparse(&revspec, repo, spec);
+
+	if (expected_left) {
+		char str[64] = {0};
+		cl_assert_equal_i(0, error);
+		git_oid_fmt(str, git_object_id(revspec.from));
+		cl_assert_equal_s(str, expected_left);
+		git_object_free(revspec.from);
+	} else {
+		cl_assert_equal_i(GIT_ENOTFOUND, error);
+	}
+
+	if (expected_right) {
+		char str[64] = {0};
+		git_oid_fmt(str, git_object_id(revspec.to));
+		cl_assert_equal_s(str, expected_right);
+		git_object_free(revspec.to);
+	}
+
+	if (expected_flags)
+		cl_assert_equal_i(expected_flags, revspec.flags);
+}
+
+static void test_object(const char *spec, const char *expected_oid)
+{
+	test_object_inrepo(spec, expected_oid, g_repo);
+}
+
+static void test_object_and_ref(const char *spec, const char *expected_oid, const char *expected_refname)
+{
+	test_object_and_ref_inrepo(spec, expected_oid, expected_refname, g_repo, true);
+}
+
+static void test_rangelike(const char *rangelike,
+						   const char *expected_left,
+						   const char *expected_right,
+						   git_revparse_mode_t expected_revparseflags)
+{
+	char objstr[64] = {0};
+	git_revspec revspec;
+	int error;
+
+	error = git_revparse(&revspec, g_repo, rangelike);
+
+	if (expected_left != NULL) {
+		cl_assert_equal_i(0, error);
+		cl_assert_equal_i(revspec.flags, expected_revparseflags);
+		git_oid_fmt(objstr, git_object_id(revspec.from));
+		cl_assert_equal_s(objstr, expected_left);
+		git_oid_fmt(objstr, git_object_id(revspec.to));
+		cl_assert_equal_s(objstr, expected_right);
+	} else
+		cl_assert(error != 0);
+
+	git_object_free(revspec.from);
+	git_object_free(revspec.to);
+}
+
+
+static void test_id(
+	const char *spec,
+	const char *expected_left,
+	const char *expected_right,
+	git_revparse_mode_t expected_flags)
+{
+	test_id_inrepo(spec, expected_left, expected_right, expected_flags, g_repo);
+}
+
+void test_refs_revparse__initialize(void)
+{
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
+}
+
+void test_refs_revparse__cleanup(void)
+{
+	git_repository_free(g_repo);
+}
+
+void test_refs_revparse__nonexistant_object(void)
+{
+	test_object("this-does-not-exist", NULL);
+	test_object("this-does-not-exist^1", NULL);
+	test_object("this-does-not-exist~2", NULL);
+}
+
+static void assert_invalid_single_spec(const char *invalid_spec)
+{
+	cl_assert_equal_i(
+		GIT_EINVALIDSPEC, git_revparse_single(&g_obj, g_repo, invalid_spec));
+}
+
+void test_refs_revparse__invalid_reference_name(void)
+{
+	assert_invalid_single_spec("this doesn't make sense");
+	assert_invalid_single_spec("Inv@{id");
+	assert_invalid_single_spec("");
+}
+
+void test_refs_revparse__shas(void)
+{
+	test_object("c47800c7266a2be04c571c04d5a6614691ea99bd", "c47800c7266a2be04c571c04d5a6614691ea99bd");
+	test_object("c47800c", "c47800c7266a2be04c571c04d5a6614691ea99bd");
+}
+
+void test_refs_revparse__head(void)
+{
+	test_object("HEAD", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	test_object("HEAD^0", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	test_object("HEAD~0", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	test_object("master", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+}
+
+void test_refs_revparse__full_refs(void)
+{
+	test_object("refs/heads/master", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	test_object("refs/heads/test", "e90810b8df3e80c413d903f631643c716887138d");
+	test_object("refs/tags/test", "b25fa35b38051e4ae45d4222e795f9df2e43f1d1");
+}
+
+void test_refs_revparse__partial_refs(void)
+{
+	test_object("point_to_blob", "1385f264afb75a56a5bec74243be9b367ba4ca08");
+	test_object("packed-test", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045");
+	test_object("br2", "a4a7dce85cf63874e984719f4fdd239f5145052f");
+}
+
+void test_refs_revparse__describe_output(void)
+{
+	test_object("blah-7-gc47800c", "c47800c7266a2be04c571c04d5a6614691ea99bd");
+	test_object("not-good", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+}
+
+void test_refs_revparse__nth_parent(void)
+{
+	assert_invalid_single_spec("be3563a^-1");
+	assert_invalid_single_spec("^");
+	assert_invalid_single_spec("be3563a^{tree}^");
+	assert_invalid_single_spec("point_to_blob^{blob}^");
+	assert_invalid_single_spec("this doesn't make sense^1");
+
+	test_object("be3563a^1", "9fd738e8f7967c078dceed8190330fc8648ee56a");
+	test_object("be3563a^", "9fd738e8f7967c078dceed8190330fc8648ee56a");
+	test_object("be3563a^2", "c47800c7266a2be04c571c04d5a6614691ea99bd");
+	test_object("be3563a^1^1", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045");
+	test_object("be3563a^^", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045");
+	test_object("be3563a^2^1", "5b5b025afb0b4c913b4c338a42934a3863bf3644");
+	test_object("be3563a^0", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	test_object("be3563a^{commit}^", "9fd738e8f7967c078dceed8190330fc8648ee56a");
+
+	test_object("be3563a^42", NULL);
+}
+
+void test_refs_revparse__not_tag(void)
+{
+	test_object("point_to_blob^{}", "1385f264afb75a56a5bec74243be9b367ba4ca08");
+	test_object("wrapped_tag^{}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	test_object("master^{}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	test_object("master^{tree}^{}", "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162");
+	test_object("e90810b^{}", "e90810b8df3e80c413d903f631643c716887138d");
+	test_object("tags/e90810b^{}", "e90810b8df3e80c413d903f631643c716887138d");
+	test_object("e908^{}", "e90810b8df3e80c413d903f631643c716887138d");
+}
+
+void test_refs_revparse__to_type(void)
+{
+	assert_invalid_single_spec("wrapped_tag^{trip}");
+	test_object("point_to_blob^{commit}", NULL);
+	cl_assert_equal_i(
+		GIT_EPEEL, git_revparse_single(&g_obj, g_repo, "wrapped_tag^{blob}"));
+
+	test_object("wrapped_tag^{commit}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	test_object("wrapped_tag^{tree}", "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162");
+	test_object("point_to_blob^{blob}", "1385f264afb75a56a5bec74243be9b367ba4ca08");
+	test_object("master^{commit}^{commit}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+}
+
+void test_refs_revparse__linear_history(void)
+{
+	assert_invalid_single_spec("~");
+	test_object("foo~bar", NULL);
+
+	assert_invalid_single_spec("master~bar");
+	assert_invalid_single_spec("master~-1");
+	assert_invalid_single_spec("master~0bar");
+	assert_invalid_single_spec("this doesn't make sense~2");
+	assert_invalid_single_spec("be3563a^{tree}~");
+	assert_invalid_single_spec("point_to_blob^{blob}~");
+
+	test_object("master~0", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	test_object("master~1", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	test_object("master~2", "9fd738e8f7967c078dceed8190330fc8648ee56a");
+	test_object("master~1~1", "9fd738e8f7967c078dceed8190330fc8648ee56a");
+	test_object("master~~", "9fd738e8f7967c078dceed8190330fc8648ee56a");
+}
+
+void test_refs_revparse__chaining(void)
+{
+	assert_invalid_single_spec("master@{0}@{0}");
+	assert_invalid_single_spec("@{u}@{-1}");
+	assert_invalid_single_spec("@{-1}@{-1}");
+	assert_invalid_single_spec("@{-3}@{0}");
+
+	test_object("master@{0}~1^1", "9fd738e8f7967c078dceed8190330fc8648ee56a");
+	test_object("@{u}@{0}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	test_object("@{-1}@{0}", "a4a7dce85cf63874e984719f4fdd239f5145052f");
+	test_object("@{-4}@{1}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	test_object("master~1^1", "9fd738e8f7967c078dceed8190330fc8648ee56a");
+	test_object("master~1^2", "c47800c7266a2be04c571c04d5a6614691ea99bd");
+	test_object("master^1^2~1", "5b5b025afb0b4c913b4c338a42934a3863bf3644");
+	test_object("master^^2^", "5b5b025afb0b4c913b4c338a42934a3863bf3644");
+	test_object("master^1^1^1^1^1", "8496071c1b46c854b31185ea97743be6a8774479");
+	test_object("master^^1^2^1", NULL);
+}
+
+void test_refs_revparse__upstream(void)
+{
+	assert_invalid_single_spec("e90810b@{u}");
+	assert_invalid_single_spec("refs/tags/e90810b@{u}");
+	test_object("refs/heads/e90810b@{u}", NULL);
+
+	test_object("master@{upstream}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	test_object("@{u}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	test_object("master@{u}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	test_object("heads/master@{u}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	test_object("refs/heads/master@{u}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+}
+
+void test_refs_revparse__ordinal(void)
+{
+	assert_invalid_single_spec("master@{-2}");
+	
+	/* TODO: make the test below actually fail
+	 * cl_git_fail(git_revparse_single(&g_obj, g_repo, "master@{1a}"));
+	 */
+
+	test_object("nope@{0}", NULL);
+	test_object("master@{31415}", NULL);
+	test_object("@{1000}", NULL);
+	test_object("@{2}", NULL);
+
+	test_object("@{0}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	test_object("@{1}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+
+	test_object("master@{0}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	test_object("master@{1}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	test_object("heads/master@{1}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	test_object("refs/heads/master@{1}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+}
+
+void test_refs_revparse__previous_head(void)
+{
+	assert_invalid_single_spec("@{-xyz}");
+	assert_invalid_single_spec("@{-0}");
+	assert_invalid_single_spec("@{-1b}");
+
+	test_object("@{-42}", NULL);
+
+	test_object("@{-2}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	test_object("@{-1}", "a4a7dce85cf63874e984719f4fdd239f5145052f");
+}
+
+static void create_fake_stash_reference_and_reflog(git_repository *repo)
+{
+	git_reference *master, *new_master;
+	git_buf log_path = GIT_BUF_INIT;
+
+	git_buf_joinpath(&log_path, git_repository_path(repo), "logs/refs/fakestash");
+
+	cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&log_path)));
+
+	cl_git_pass(git_reference_lookup(&master, repo, "refs/heads/master"));
+	cl_git_pass(git_reference_rename(&new_master, master, "refs/fakestash", 0, NULL));
+	git_reference_free(master);
+
+	cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&log_path)));
+
+	git_buf_free(&log_path);
+	git_reference_free(new_master);
+}
+
+void test_refs_revparse__reflog_of_a_ref_under_refs(void)
+{
+	git_repository *repo = cl_git_sandbox_init("testrepo.git");
+
+	test_object_inrepo("refs/fakestash", NULL, repo);
+
+	create_fake_stash_reference_and_reflog(repo);
+
+	/*
+	 * $ git reflog -1 refs/fakestash
+	 * a65fedf refs/fakestash@{0}: commit: checking in
+	 *
+	 * $ git reflog -1 refs/fakestash@{0}
+	 * a65fedf refs/fakestash@{0}: commit: checking in
+	 *
+	 * $ git reflog -1 fakestash
+	 * a65fedf fakestash@{0}: commit: checking in
+	 *
+	 * $ git reflog -1 fakestash@{0}
+	 * a65fedf fakestash@{0}: commit: checking in
+	 */
+	test_object_inrepo("refs/fakestash", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo);
+	test_object_inrepo("refs/fakestash@{0}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo);
+	test_object_inrepo("fakestash", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo);
+	test_object_inrepo("fakestash@{0}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo);
+
+	cl_git_sandbox_cleanup();
+}
+
+void test_refs_revparse__revwalk(void)
+{
+	test_object("master^{/not found in any commit}", NULL);
+	test_object("master^{/merge}", NULL);
+	assert_invalid_single_spec("master^{/((}");
+
+	test_object("master^{/anoth}", "5b5b025afb0b4c913b4c338a42934a3863bf3644");
+	test_object("master^{/Merge}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	test_object("br2^{/Merge}", "a4a7dce85cf63874e984719f4fdd239f5145052f");
+	test_object("master^{/fo.rth}", "9fd738e8f7967c078dceed8190330fc8648ee56a");
+}
+
+void test_refs_revparse__date(void)
+{
+	/*
+	 * $ git reflog HEAD --date=iso
+	 * a65fedf HEAD@{2012-04-30 08:23:41 -0900}: checkout: moving from br2 to master
+	 * a4a7dce HEAD@{2012-04-30 08:23:37 -0900}: commit: checking in
+	 * c47800c HEAD@{2012-04-30 08:23:28 -0900}: checkout: moving from master to br2
+	 * a65fedf HEAD@{2012-04-30 08:23:23 -0900}: commit:
+	 * be3563a HEAD@{2012-04-30 10:22:43 -0700}: clone: from /Users/ben/src/libgit2/tes
+	 *
+	 * $ git reflog HEAD --date=raw
+	 * a65fedf HEAD@{1335806621 -0900}: checkout: moving from br2 to master
+	 * a4a7dce HEAD@{1335806617 -0900}: commit: checking in
+	 * c47800c HEAD@{1335806608 -0900}: checkout: moving from master to br2
+	 * a65fedf HEAD@{1335806603 -0900}: commit:
+	 * be3563a HEAD@{1335806563 -0700}: clone: from /Users/ben/src/libgit2/tests/resour
+	 */
+	test_object("HEAD@{10 years ago}", NULL);
+
+	test_object("HEAD@{1 second}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	test_object("HEAD@{1 second ago}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	test_object("HEAD@{2 days ago}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+
+	/*
+	 * $ git reflog master --date=iso
+	 * a65fedf master@{2012-04-30 09:23:23 -0800}: commit: checking in
+	 * be3563a master@{2012-04-30 09:22:43 -0800}: clone: from /Users/ben/src...
+	 *
+	 * $ git reflog master --date=raw
+	 * a65fedf master@{1335806603 -0800}: commit: checking in
+	 * be3563a master@{1335806563 -0800}: clone: from /Users/ben/src/libgit2/tests/reso
+	 */
+
+
+	/*
+	 * $ git reflog -1 "master@{2012-04-30 17:22:42 +0000}"
+	 * warning: Log for 'master' only goes back to Mon, 30 Apr 2012 09:22:43 -0800.
+	 */
+	test_object("master@{2012-04-30 17:22:42 +0000}", NULL);
+	test_object("master@{2012-04-30 09:22:42 -0800}", NULL);
+
+	/*
+	 * $ git reflog -1 "master@{2012-04-30 17:22:43 +0000}"
+	 * be3563a master@{Mon Apr 30 09:22:43 2012 -0800}: clone: from /Users/ben/src/libg
+	 */
+	test_object("master@{2012-04-30 17:22:43 +0000}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+	test_object("master@{2012-04-30 09:22:43 -0800}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+
+	/*
+	 * $ git reflog -1 "master@{2012-4-30 09:23:27 -0800}"
+	 * a65fedf master@{Mon Apr 30 09:23:23 2012 -0800}: commit: checking in
+	 */
+	test_object("master@{2012-4-30 09:23:27 -0800}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+
+	/*
+	 * $ git reflog -1 master@{2012-05-03}
+	 * a65fedf master@{Mon Apr 30 09:23:23 2012 -0800}: commit: checking in
+	 */
+	test_object("master@{2012-05-03}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+
+	/*
+	 * $ git reflog -1 "master@{1335806603}"
+	 * a65fedf
+	 *
+	 * $ git reflog -1 "master@{1335806602}"
+	 * be3563a
+	 */
+	test_object("master@{1335806603}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	test_object("master@{1335806602}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
+}
+
+void test_refs_revparse__colon(void)
+{
+	assert_invalid_single_spec(":/");
+	assert_invalid_single_spec("point_to_blob:readme.txt");
+	cl_git_fail(git_revparse_single(&g_obj, g_repo, ":2:README")); /* Not implemented  */
+
+	test_object(":/not found in any commit", NULL);
+	test_object("subtrees:ab/42.txt", NULL);
+	test_object("subtrees:ab/4.txt/nope", NULL);
+	test_object("subtrees:nope", NULL);
+	test_object("test/master^1:branch_file.txt", NULL);
+
+	/* From tags */
+	test_object("test:readme.txt", "0266163a49e280c4f5ed1e08facd36a2bd716bcf");
+	test_object("tags/test:readme.txt", "0266163a49e280c4f5ed1e08facd36a2bd716bcf");
+	test_object("e90810b:readme.txt", "0266163a49e280c4f5ed1e08facd36a2bd716bcf");
+	test_object("tags/e90810b:readme.txt", "0266163a49e280c4f5ed1e08facd36a2bd716bcf");
+
+	/* From commits */
+	test_object("a65f:branch_file.txt", "3697d64be941a53d4ae8f6a271e4e3fa56b022cc");
+
+	/* From trees */
+	test_object("a65f^{tree}:branch_file.txt", "3697d64be941a53d4ae8f6a271e4e3fa56b022cc");
+	test_object("944c:branch_file.txt", "3697d64be941a53d4ae8f6a271e4e3fa56b022cc");
+
+	/* Retrieving trees */
+	test_object("master:", "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162");
+	test_object("subtrees:", "ae90f12eea699729ed24555e40b9fd669da12a12");
+	test_object("subtrees:ab", "f1425cef211cc08caa31e7b545ffb232acb098c3");
+	test_object("subtrees:ab/", "f1425cef211cc08caa31e7b545ffb232acb098c3");
+
+	/* Retrieving blobs */
+	test_object("subtrees:ab/4.txt", "d6c93164c249c8000205dd4ec5cbca1b516d487f");
+	test_object("subtrees:ab/de/fgh/1.txt", "1f67fc4386b2d171e0d21be1c447e12660561f9b");
+	test_object("master:README", "a8233120f6ad708f843d861ce2b7228ec4e3dec6");
+	test_object("master:new.txt", "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd");
+	test_object(":/Merge", "a4a7dce85cf63874e984719f4fdd239f5145052f");
+	test_object(":/one", "c47800c7266a2be04c571c04d5a6614691ea99bd");
+	test_object(":/packed commit t", "41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9");
+	test_object("test/master^2:branch_file.txt", "45b983be36b73c0788dc9cbcb76cbb80fc7bb057");
+	test_object("test/master@{1}:branch_file.txt", "3697d64be941a53d4ae8f6a271e4e3fa56b022cc");
+}
+
+void test_refs_revparse__disambiguation(void)
+{
+	/*
+	 * $ git show e90810b
+	 * tag e90810b
+	 * Tagger: Vicent Marti <tanoku at gmail.com>
+	 * Date:   Thu Aug 12 03:59:17 2010 +0200
+	 *
+	 * This is a very simple tag.
+	 *
+	 * commit e90810b8df3e80c413d903f631643c716887138d
+	 * Author: Vicent Marti <tanoku at gmail.com>
+	 * Date:   Thu Aug 5 18:42:20 2010 +0200
+	 *
+	 *     Test commit 2
+	 *
+	 * diff --git a/readme.txt b/readme.txt
+	 * index 6336846..0266163 100644
+	 * --- a/readme.txt
+	 * +++ b/readme.txt
+	 * @@ -1 +1,2 @@
+	 *  Testing a readme.txt
+	 * +Now we add a single line here
+	 *
+	 * $ git show-ref e90810b
+	 * 7b4384978d2493e851f9cca7858815fac9b10980 refs/tags/e90810b
+	 *
+	 */
+	test_object("e90810b", "7b4384978d2493e851f9cca7858815fac9b10980");
+
+	/*
+	 * $ git show e90810
+	 * commit e90810b8df3e80c413d903f631643c716887138d
+	 * Author: Vicent Marti <tanoku at gmail.com>
+	 * Date:   Thu Aug 5 18:42:20 2010 +0200
+	 *
+	 *     Test commit 2
+	 *
+	 * diff --git a/readme.txt b/readme.txt
+	 * index 6336846..0266163 100644
+	 * --- a/readme.txt
+	 * +++ b/readme.txt
+	 * @@ -1 +1,2 @@
+	 *  Testing a readme.txt
+	 * +Now we add a single line here
+	 */
+	test_object("e90810", "e90810b8df3e80c413d903f631643c716887138d");
+}
+
+void test_refs_revparse__a_too_short_objectid_returns_EAMBIGUOUS(void)
+{
+	cl_assert_equal_i(
+		GIT_EAMBIGUOUS, git_revparse_single(&g_obj, g_repo, "e90"));
+}
+
+/*
+ * $ echo "aabqhq" | git hash-object -t blob --stdin
+ * dea509d0b3cb8ee0650f6ca210bc83f4678851ba
+ * 
+ * $ echo "aaazvc" | git hash-object -t blob --stdin
+ * dea509d097ce692e167dfc6a48a7a280cc5e877e
+ */
+void test_refs_revparse__a_not_precise_enough_objectid_returns_EAMBIGUOUS(void)
+{
+	git_repository *repo;
+	git_index *index;
+	git_object *obj;
+
+	repo = cl_git_sandbox_init("testrepo");
+
+	cl_git_mkfile("testrepo/one.txt", "aabqhq\n");
+	cl_git_mkfile("testrepo/two.txt", "aaazvc\n");
+	
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_add_bypath(index, "one.txt"));
+	cl_git_pass(git_index_add_bypath(index, "two.txt"));
+	
+	cl_git_fail_with(git_revparse_single(&obj, repo, "dea509d0"), GIT_EAMBIGUOUS);
+
+	cl_git_pass(git_revparse_single(&obj, repo, "dea509d09"));
+
+	git_object_free(obj);
+	git_index_free(index);
+	cl_git_sandbox_cleanup();
+}
+
+void test_refs_revparse__issue_994(void)
+{
+	git_repository *repo;
+	git_reference *head, *with_at;
+	git_object *target;
+	
+	repo = cl_git_sandbox_init("testrepo.git");
+
+	cl_assert_equal_i(GIT_ENOTFOUND,
+		git_revparse_single(&target, repo, "origin/bim_with_3d at 11296"));
+
+	cl_assert_equal_i(GIT_ENOTFOUND,
+		git_revparse_single(&target, repo, "refs/remotes/origin/bim_with_3d at 11296"));
+
+
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_create(
+		&with_at,
+		repo,
+		"refs/remotes/origin/bim_with_3d at 11296",
+		git_reference_target(head),
+		0,
+		NULL));
+
+	cl_git_pass(git_revparse_single(&target, repo, "origin/bim_with_3d at 11296"));
+	git_object_free(target);
+
+	cl_git_pass(git_revparse_single(&target, repo, "refs/remotes/origin/bim_with_3d at 11296"));
+	git_object_free(target);
+
+	git_reference_free(with_at);
+	git_reference_free(head);
+	cl_git_sandbox_cleanup();
+}
+
+/**
+ * $ git rev-parse blah-7-gc47800c
+ * c47800c7266a2be04c571c04d5a6614691ea99bd
+ *
+ * $ git rev-parse HEAD~3
+ * 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ *
+ * $ git branch blah-7-gc47800c HEAD~3
+ *
+ * $ git rev-parse blah-7-gc47800c
+ * 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ */
+void test_refs_revparse__try_to_retrieve_branch_before_described_tag(void)
+{
+	git_repository *repo;
+	git_reference *branch;
+	git_object *target;
+	char sha[GIT_OID_HEXSZ + 1];
+
+	repo = cl_git_sandbox_init("testrepo.git");
+
+	test_object_inrepo("blah-7-gc47800c", "c47800c7266a2be04c571c04d5a6614691ea99bd", repo);
+
+	cl_git_pass(git_revparse_single(&target, repo, "HEAD~3"));
+	cl_git_pass(git_branch_create(&branch, repo, "blah-7-gc47800c", (git_commit *)target, 0));
+
+	git_oid_tostr(sha, GIT_OID_HEXSZ + 1, git_object_id(target));
+
+	test_object_inrepo("blah-7-gc47800c", sha, repo);
+
+	git_reference_free(branch);
+	git_object_free(target);
+	cl_git_sandbox_cleanup();
+}
+
+/**
+ * $ git rev-parse a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+ * a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+ *
+ * $ git rev-parse HEAD~3
+ * 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ *
+ * $ git branch a65fedf39aefe402d3bb6e24df4d4f5fe4547750 HEAD~3
+ *
+ * $ git rev-parse a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+ * a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+ *
+ * $ git rev-parse heads/a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+ * 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ */
+void test_refs_revparse__try_to_retrieve_sha_before_branch(void)
+{
+	git_repository *repo;
+	git_reference *branch;
+	git_object *target;
+	char sha[GIT_OID_HEXSZ + 1];
+
+	repo = cl_git_sandbox_init("testrepo.git");
+
+	test_object_inrepo("a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo);
+
+	cl_git_pass(git_revparse_single(&target, repo, "HEAD~3"));
+	cl_git_pass(git_branch_create(&branch, repo, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", (git_commit *)target, 0));
+
+	git_oid_tostr(sha, GIT_OID_HEXSZ + 1, git_object_id(target));
+
+	test_object_inrepo("a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo);
+	test_object_inrepo("heads/a65fedf39aefe402d3bb6e24df4d4f5fe4547750", sha, repo);
+
+	git_reference_free(branch);
+	git_object_free(target);
+	cl_git_sandbox_cleanup();
+}
+
+/**
+ * $ git rev-parse c47800
+ * c47800c7266a2be04c571c04d5a6614691ea99bd
+ *
+ * $ git rev-parse HEAD~3
+ * 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ *
+ * $ git branch c47800 HEAD~3
+ *
+ * $ git rev-parse c47800
+ * 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ */
+void test_refs_revparse__try_to_retrieve_branch_before_abbrev_sha(void)
+{
+	git_repository *repo;
+	git_reference *branch;
+	git_object *target;
+	char sha[GIT_OID_HEXSZ + 1];
+
+	repo = cl_git_sandbox_init("testrepo.git");
+
+	test_object_inrepo("c47800", "c47800c7266a2be04c571c04d5a6614691ea99bd", repo);
+
+	cl_git_pass(git_revparse_single(&target, repo, "HEAD~3"));
+	cl_git_pass(git_branch_create(&branch, repo, "c47800", (git_commit *)target, 0));
+
+	git_oid_tostr(sha, GIT_OID_HEXSZ + 1, git_object_id(target));
+
+	test_object_inrepo("c47800", sha, repo);
+
+	git_reference_free(branch);
+	git_object_free(target);
+	cl_git_sandbox_cleanup();
+}
+
+
+void test_refs_revparse__range(void)
+{
+	assert_invalid_single_spec("be3563a^1..be3563a");
+
+	test_rangelike("be3563a^1..be3563a",
+	               "9fd738e8f7967c078dceed8190330fc8648ee56a",
+	               "be3563ae3f795b2b4353bcce3a527ad0a4f7f644",
+	               GIT_REVPARSE_RANGE);
+
+	test_rangelike("be3563a^1...be3563a",
+	               "9fd738e8f7967c078dceed8190330fc8648ee56a",
+	               "be3563ae3f795b2b4353bcce3a527ad0a4f7f644",
+	               GIT_REVPARSE_RANGE | GIT_REVPARSE_MERGE_BASE);
+
+	test_rangelike("be3563a^1.be3563a", NULL, NULL, 0);
+}
+
+void test_refs_revparse__parses_range_operator(void)
+{
+	test_id("HEAD", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", NULL, GIT_REVPARSE_SINGLE);
+	test_id("HEAD~3..HEAD",
+		"4a202b346bb0fb0db7eff3cffeb3c70babbd2045",
+		"a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+		GIT_REVPARSE_RANGE);
+
+	test_id("HEAD~3...HEAD",
+		"4a202b346bb0fb0db7eff3cffeb3c70babbd2045",
+		"a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+		GIT_REVPARSE_RANGE | GIT_REVPARSE_MERGE_BASE);
+}
+
+void test_refs_revparse__ext_retrieves_both_the_reference_and_its_target(void)
+{
+	test_object_and_ref(
+		"master@{upstream}",
+		"be3563ae3f795b2b4353bcce3a527ad0a4f7f644",
+		"refs/remotes/test/master");
+
+	test_object_and_ref(
+		"@{-1}",
+		"a4a7dce85cf63874e984719f4fdd239f5145052f",
+		"refs/heads/br2");
+}
+
+void test_refs_revparse__ext_can_expand_short_reference_names(void)
+{
+	test_object_and_ref(
+		"master",
+		"a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+		"refs/heads/master");
+
+	test_object_and_ref(
+		"HEAD",
+		"a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+		"refs/heads/master");
+
+    test_object_and_ref(
+		"tags/test",
+		"b25fa35b38051e4ae45d4222e795f9df2e43f1d1",
+        "refs/tags/test");
+}
+
+void test_refs_revparse__ext_returns_NULL_reference_when_expression_points_at_a_revision(void)
+{
+    test_object_and_ref(
+        "HEAD~3",
+        "4a202b346bb0fb0db7eff3cffeb3c70babbd2045",
+        NULL);
+
+    test_object_and_ref(
+        "HEAD~0",
+        "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+        NULL);
+
+    test_object_and_ref(
+        "HEAD^0",
+        "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+        NULL);
+
+    test_object_and_ref(
+		"@{-1}@{0}",
+		"a4a7dce85cf63874e984719f4fdd239f5145052f",
+		NULL);
+}
+
+void test_refs_revparse__ext_returns_NULL_reference_when_expression_points_at_a_tree_content(void)
+{
+    test_object_and_ref(
+		"tags/test:readme.txt",
+		"0266163a49e280c4f5ed1e08facd36a2bd716bcf",
+        NULL);
+}
+
+void test_refs_revparse__uneven_sizes(void)
+{
+	test_object("a65fedf39aefe402d3bb6e24df4d4f5fe454775",
+				"a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+
+	test_object("a65fedf39aefe402d3bb6e24df4d4f5fe45477",
+				"a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+
+	test_object("a65fedf39aefe402d3bb6e24df4d4f5fe4547",
+				"a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+
+	test_object("a65fedf39aefe402d3bb6e24df4d",
+				"a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/settargetwithlog.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/settargetwithlog.c
new file mode 100755
index 0000000..58fbb5f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/settargetwithlog.c
@@ -0,0 +1,51 @@
+#include "clar_libgit2.h"
+
+#include "repository.h"
+#include "git2/reflog.h"
+#include "reflog.h"
+#include "ref_helpers.h"
+
+static const char *br2_tip = "a4a7dce85cf63874e984719f4fdd239f5145052f";
+static const char *master_tip = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750";
+static const char *br2_name = "refs/heads/br2";
+
+static git_repository *g_repo;
+
+void test_refs_settargetwithlog__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo.git");
+}
+
+void test_refs_settargetwithlog__cleanup(void)
+{
+   cl_git_sandbox_cleanup();
+}
+
+void test_refs_settargetwithlog__updating_a_direct_reference_adds_a_reflog_entry(void)
+{
+	git_reference *reference, *reference_out;
+	git_oid current_id, target_id;
+	git_reflog *reflog;
+	const git_reflog_entry *entry;
+
+	const char *message = "You've been logged, mate!";
+
+	git_oid_fromstr(&current_id, br2_tip);
+	git_oid_fromstr(&target_id, master_tip);
+
+	cl_git_pass(git_reference_lookup(&reference, g_repo, br2_name));
+
+	cl_git_pass(git_reference_set_target(
+		&reference_out, reference, &target_id, message));
+
+	cl_git_pass(git_reflog_read(&reflog, g_repo, br2_name));
+
+	entry = git_reflog_entry_byindex(reflog, 0);
+	cl_assert_equal_oid(&current_id, &entry->oid_old);
+	cl_assert_equal_oid(&target_id, &entry->oid_cur);
+	cl_assert_equal_s(message, entry->msg);
+
+	git_reflog_free(reflog);
+	git_reference_free(reference_out);
+	git_reference_free(reference);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/setter.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/setter.c
new file mode 100755
index 0000000..2b42ff2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/setter.c
@@ -0,0 +1,99 @@
+#include "clar_libgit2.h"
+
+#include "repository.h"
+#include "git2/reflog.h"
+#include "reflog.h"
+#include "git2/refs.h"
+
+static const char *ref_name = "refs/heads/other";
+static const char *ref_master_name = "refs/heads/master";
+static const char *ref_test_name = "refs/heads/test";
+
+static git_repository *g_repo;
+
+void test_refs_setter__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_refs_setter__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_refs_setter__update_direct(void)
+{
+	git_reference *ref, *test_ref, *new_ref;
+	git_oid id;
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
+	cl_assert(git_reference_type(ref) == GIT_REF_OID);
+	git_oid_cpy(&id, git_reference_target(ref));
+	git_reference_free(ref);
+
+	cl_git_pass(git_reference_lookup(&test_ref, g_repo, ref_test_name));
+	cl_assert(git_reference_type(test_ref) == GIT_REF_OID);
+
+	cl_git_pass(git_reference_set_target(&new_ref, test_ref, &id, NULL));
+
+	git_reference_free(test_ref);
+	git_reference_free(new_ref);
+
+	cl_git_pass(git_reference_lookup(&test_ref, g_repo, ref_test_name));
+	cl_assert(git_reference_type(test_ref) == GIT_REF_OID);
+	cl_assert_equal_oid(&id, git_reference_target(test_ref));
+	git_reference_free(test_ref);
+}
+
+void test_refs_setter__update_symbolic(void)
+{
+	git_reference *head, *new_head;
+
+	cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
+	cl_assert(git_reference_type(head) == GIT_REF_SYMBOLIC);
+	cl_assert(strcmp(git_reference_symbolic_target(head), ref_master_name) == 0);
+
+	cl_git_pass(git_reference_symbolic_set_target(&new_head, head, ref_test_name, NULL));
+	git_reference_free(new_head);
+	git_reference_free(head);
+
+	cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
+	cl_assert(git_reference_type(head) == GIT_REF_SYMBOLIC);
+	cl_assert(strcmp(git_reference_symbolic_target(head), ref_test_name) == 0);
+	git_reference_free(head);
+}
+
+void test_refs_setter__cant_update_direct_with_symbolic(void)
+{
+	// Overwrite an existing object id reference with a symbolic one
+	git_reference *ref, *new;
+	git_oid id;
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
+	cl_assert(git_reference_type(ref) == GIT_REF_OID);
+	git_oid_cpy(&id, git_reference_target(ref));
+
+	cl_git_fail(git_reference_symbolic_set_target(&new, ref, ref_name, NULL));
+
+	git_reference_free(ref);
+}
+
+void test_refs_setter__cant_update_symbolic_with_direct(void)
+{
+	// Overwrite an existing symbolic reference with an object id one
+	git_reference *ref, *new;
+	git_oid id;
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
+	cl_assert(git_reference_type(ref) == GIT_REF_OID);
+	git_oid_cpy(&id, git_reference_target(ref));
+	git_reference_free(ref);
+
+	/* Create the symbolic ref */
+	cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0, NULL));
+
+	/* Can't set an OID on a direct ref */
+	cl_git_fail(git_reference_set_target(&new, ref, &id, NULL));
+
+	git_reference_free(ref);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/shorthand.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/shorthand.c
new file mode 100755
index 0000000..f995d26
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/shorthand.c
@@ -0,0 +1,27 @@
+#include "clar_libgit2.h"
+
+#include "repository.h"
+
+void assert_shorthand(git_repository *repo, const char *refname, const char *shorthand)
+{
+	git_reference *ref;
+
+	cl_git_pass(git_reference_lookup(&ref, repo, refname));
+	cl_assert_equal_s(git_reference_shorthand(ref), shorthand);
+	git_reference_free(ref);
+}
+
+void test_refs_shorthand__0(void)
+{
+	git_repository *repo;
+
+	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+
+
+	assert_shorthand(repo, "refs/heads/master", "master");
+	assert_shorthand(repo, "refs/tags/test", "test");
+	assert_shorthand(repo, "refs/remotes/test/master", "test/master");
+	assert_shorthand(repo, "refs/notes/fanout", "notes/fanout");
+
+	git_repository_free(repo);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/transactions.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/transactions.c
new file mode 100755
index 0000000..39ea1ca
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/transactions.c
@@ -0,0 +1,110 @@
+#include "clar_libgit2.h"
+#include "git2/transaction.h"
+
+static git_repository *g_repo;
+static git_transaction *g_tx;
+
+void test_refs_transactions__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo");
+   cl_git_pass(git_transaction_new(&g_tx, g_repo));
+}
+
+void test_refs_transactions__cleanup(void)
+{
+	git_transaction_free(g_tx);
+	cl_git_sandbox_cleanup();
+}
+
+void test_refs_transactions__single_ref_oid(void)
+{
+	git_reference *ref;
+	git_oid id;
+
+	git_oid_fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+
+	cl_git_pass(git_transaction_lock_ref(g_tx, "refs/heads/master"));
+	cl_git_pass(git_transaction_set_target(g_tx, "refs/heads/master", &id, NULL, NULL));
+	cl_git_pass(git_transaction_commit(g_tx));
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/heads/master"));
+
+	cl_assert(!git_oid_cmp(&id, git_reference_target(ref)));
+	git_reference_free(ref);
+}
+
+void test_refs_transactions__single_ref_symbolic(void)
+{
+	git_reference *ref;
+
+	cl_git_pass(git_transaction_lock_ref(g_tx, "HEAD"));
+	cl_git_pass(git_transaction_set_symbolic_target(g_tx, "HEAD", "refs/heads/foo", NULL, NULL));
+	cl_git_pass(git_transaction_commit(g_tx));
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD"));
+
+	cl_assert_equal_s("refs/heads/foo", git_reference_symbolic_target(ref));
+	git_reference_free(ref);
+}
+
+void test_refs_transactions__single_ref_mix_types(void)
+{
+	git_reference *ref;
+	git_oid id;
+
+	git_oid_fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+
+	cl_git_pass(git_transaction_lock_ref(g_tx, "refs/heads/master"));
+	cl_git_pass(git_transaction_lock_ref(g_tx, "HEAD"));
+	cl_git_pass(git_transaction_set_symbolic_target(g_tx, "refs/heads/master", "refs/heads/foo", NULL, NULL));
+	cl_git_pass(git_transaction_set_target(g_tx, "HEAD", &id, NULL, NULL));
+	cl_git_pass(git_transaction_commit(g_tx));
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/heads/master"));
+	cl_assert_equal_s("refs/heads/foo", git_reference_symbolic_target(ref));
+	git_reference_free(ref);
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD"));
+	cl_assert(!git_oid_cmp(&id, git_reference_target(ref)));
+	git_reference_free(ref);
+}
+
+void test_refs_transactions__single_ref_delete(void)
+{
+	git_reference *ref;
+
+	cl_git_pass(git_transaction_lock_ref(g_tx, "refs/heads/master"));
+	cl_git_pass(git_transaction_remove(g_tx, "refs/heads/master"));
+	cl_git_pass(git_transaction_commit(g_tx));
+
+	cl_git_fail_with(GIT_ENOTFOUND, git_reference_lookup(&ref, g_repo, "refs/heads/master"));
+}
+
+void test_refs_transactions__single_create(void)
+{
+	git_reference *ref;
+	const char *name = "refs/heads/new-branch";
+	git_oid id;
+
+	cl_git_fail_with(GIT_ENOTFOUND, git_reference_lookup(&ref, g_repo, name));
+
+	cl_git_pass(git_transaction_lock_ref(g_tx, name));
+
+	git_oid_fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	cl_git_pass(git_transaction_set_target(g_tx, name, &id, NULL, NULL));
+	cl_git_pass(git_transaction_commit(g_tx));
+
+	cl_git_pass(git_reference_lookup(&ref, g_repo, name));
+	cl_assert(!git_oid_cmp(&id, git_reference_target(ref)));
+	git_reference_free(ref);
+}
+
+void test_refs_transactions__unlocked_set(void)
+{
+	git_oid id;
+
+	cl_git_pass(git_transaction_lock_ref(g_tx, "refs/heads/master"));
+	git_oid_fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	cl_git_fail_with(GIT_ENOTFOUND, git_transaction_set_target(g_tx, "refs/heads/foo", &id, NULL, NULL));
+	cl_git_pass(git_transaction_commit(g_tx));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/unicode.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/unicode.c
new file mode 100755
index 0000000..a279d50
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/unicode.c
@@ -0,0 +1,54 @@
+#include "clar_libgit2.h"
+
+static git_repository *repo;
+
+void test_refs_unicode__initialize(void)
+{
+	repo = cl_git_sandbox_init("testrepo.git");
+}
+
+void test_refs_unicode__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+	repo = NULL;
+}
+
+void test_refs_unicode__create_and_lookup(void)
+{
+	git_reference *ref0, *ref1, *ref2;
+	git_repository *repo2;
+
+	const char *REFNAME = "refs/heads/" "\303\205" "ngstr" "\303\266" "m";
+	const char *master = "refs/heads/master";
+
+	/* Create the reference */
+	cl_git_pass(git_reference_lookup(&ref0, repo, master));
+	cl_git_pass(git_reference_create(
+		&ref1, repo, REFNAME, git_reference_target(ref0), 0, NULL));
+	cl_assert_equal_s(REFNAME, git_reference_name(ref1));
+	git_reference_free(ref0);
+
+	/* Lookup the reference in a different instance of the repository */
+	cl_git_pass(git_repository_open(&repo2, "testrepo.git"));
+
+	cl_git_pass(git_reference_lookup(&ref2, repo2, REFNAME));
+	cl_assert_equal_oid(git_reference_target(ref1), git_reference_target(ref2));
+	cl_assert_equal_s(REFNAME, git_reference_name(ref2));
+	git_reference_free(ref2);
+
+#if GIT_USE_ICONV
+	/* Lookup reference by decomposed unicode name */
+
+#define REFNAME_DECOMPOSED "refs/heads/" "A" "\314\212" "ngstro" "\314\210" "m"
+
+	cl_git_pass(git_reference_lookup(&ref2, repo2, REFNAME_DECOMPOSED));
+	cl_assert_equal_oid(git_reference_target(ref1), git_reference_target(ref2));
+	cl_assert_equal_s(REFNAME, git_reference_name(ref2));
+	git_reference_free(ref2);
+#endif
+
+	/* Cleanup */
+
+	git_reference_free(ref1);
+	git_repository_free(repo2);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/update.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/update.c
new file mode 100755
index 0000000..403ea75
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/refs/update.c
@@ -0,0 +1,26 @@
+#include "clar_libgit2.h"
+
+#include "refs.h"
+
+static git_repository *g_repo;
+
+void test_refs_update__initialize(void)
+{
+   g_repo = cl_git_sandbox_init("testrepo.git");
+}
+
+void test_refs_update__cleanup(void)
+{
+   cl_git_sandbox_cleanup();
+}
+
+void test_refs_update__updating_the_target_of_a_symref_with_an_invalid_name_returns_EINVALIDSPEC(void)
+{
+	git_reference *head;
+
+	cl_git_pass(git_reference_lookup(&head, g_repo, GIT_HEAD_FILE));
+	cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head));
+	git_reference_free(head);
+
+	cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_symbolic_create(&head, g_repo, GIT_HEAD_FILE, "refs/heads/inv@{id", 1, NULL));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/remote/insteadof.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/remote/insteadof.c
new file mode 100755
index 0000000..05d4757
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/remote/insteadof.c
@@ -0,0 +1,72 @@
+#include "clar_libgit2.h"
+#include "remote.h"
+#include "repository.h"
+
+#define REPO_PATH "testrepo2/.gitted"
+#define REMOTE_ORIGIN "origin"
+#define REMOTE_INSTEADOF "insteadof-test"
+
+static git_repository *g_repo;
+static git_remote *g_remote;
+
+void test_remote_insteadof__initialize(void)
+{
+	g_repo = NULL;
+	g_remote = NULL;
+}
+
+void test_remote_insteadof__cleanup(void)
+{
+	git_repository_free(g_repo);
+	git_remote_free(g_remote);
+}
+
+void test_remote_insteadof__url_insteadof_not_applicable(void)
+{
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH)));
+	cl_git_pass(git_remote_lookup(&g_remote, g_repo, REMOTE_ORIGIN));
+
+	cl_assert_equal_s(
+		git_remote_url(g_remote),
+		"https://github.com/libgit2/false.git");
+}
+
+void test_remote_insteadof__url_insteadof_applicable(void)
+{
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH)));
+	cl_git_pass(git_remote_lookup(&g_remote, g_repo, REMOTE_INSTEADOF));
+
+	cl_assert_equal_s(
+	    git_remote_url(g_remote),
+	    "http://github.com/libgit2/libgit2");
+}
+
+void test_remote_insteadof__pushurl_insteadof_not_applicable(void)
+{
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH)));
+	cl_git_pass(git_remote_lookup(&g_remote, g_repo, REMOTE_ORIGIN));
+
+	cl_assert_equal_p(git_remote_pushurl(g_remote), NULL);
+}
+
+void test_remote_insteadof__pushurl_insteadof_applicable(void)
+{
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH)));
+	cl_git_pass(git_remote_lookup(&g_remote, g_repo, REMOTE_INSTEADOF));
+
+	cl_assert_equal_s(
+	    git_remote_pushurl(g_remote),
+	    "git at github.com:libgit2/libgit2");
+}
+
+void test_remote_insteadof__anonymous_remote(void)
+{
+	cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH)));
+	cl_git_pass(git_remote_create_anonymous(&g_remote, g_repo,
+	    "http://example.com/libgit2/libgit2"));
+
+	cl_assert_equal_s(
+	    git_remote_url(g_remote),
+	    "http://github.com/libgit2/libgit2");
+	cl_assert_equal_p(git_remote_pushurl(g_remote), NULL);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/config.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/config.c
new file mode 100755
index 0000000..93dedd5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/config.c
@@ -0,0 +1,211 @@
+#include "clar_libgit2.h"
+#include "sysdir.h"
+#include "fileops.h"
+#include <ctype.h>
+
+static git_buf path = GIT_BUF_INIT;
+
+void test_repo_config__initialize(void)
+{
+	cl_fixture_sandbox("empty_standard_repo");
+	cl_git_pass(cl_rename(
+		"empty_standard_repo/.gitted", "empty_standard_repo/.git"));
+
+	git_buf_clear(&path);
+
+	cl_must_pass(p_mkdir("alternate", 0777));
+	cl_git_pass(git_path_prettify(&path, "alternate", NULL));
+}
+
+void test_repo_config__cleanup(void)
+{
+	cl_sandbox_set_search_path_defaults();
+
+	git_buf_free(&path);
+
+	cl_git_pass(
+		git_futils_rmdir_r("alternate", NULL, GIT_RMDIR_REMOVE_FILES));
+	cl_assert(!git_path_isdir("alternate"));
+
+	cl_fixture_cleanup("empty_standard_repo");
+
+}
+
+void test_repo_config__can_open_global_when_there_is_no_file(void)
+{
+	git_repository *repo;
+	git_config *config, *global;
+
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr));
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr));
+
+	cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
+	cl_git_pass(git_repository_config(&config, repo));
+	cl_git_pass(git_config_open_level(
+		&global, config, GIT_CONFIG_LEVEL_GLOBAL));
+
+	cl_git_pass(git_config_set_string(global, "test.set", "42"));
+
+	git_config_free(global);
+	git_config_free(config);
+	git_repository_free(repo);
+}
+
+void test_repo_config__can_open_missing_global_with_separators(void)
+{
+	git_repository *repo;
+	git_config *config, *global;
+
+	cl_git_pass(git_buf_printf(
+		&path, "%c%s", GIT_PATH_LIST_SEPARATOR, "dummy"));
+
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr));
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr));
+
+	git_buf_free(&path);
+
+	cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
+	cl_git_pass(git_repository_config(&config, repo));
+	cl_git_pass(git_config_open_level(
+		&global, config, GIT_CONFIG_LEVEL_GLOBAL));
+
+	cl_git_pass(git_config_set_string(global, "test.set", "42"));
+
+	git_config_free(global);
+	git_config_free(config);
+	git_repository_free(repo);
+}
+
+#include "repository.h"
+
+void test_repo_config__read_with_no_configs_at_all(void)
+{
+	git_repository *repo;
+	int val;
+
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr));
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr));
+
+	/* with none */
+
+	cl_must_pass(p_unlink("empty_standard_repo/.git/config"));
+	cl_assert(!git_path_isfile("empty_standard_repo/.git/config"));
+
+	cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
+	git_repository__cvar_cache_clear(repo);
+	val = -1;
+	cl_git_pass(git_repository__cvar(&val, repo, GIT_CVAR_ABBREV));
+	cl_assert_equal_i(GIT_ABBREV_DEFAULT, val);
+	git_repository_free(repo);
+
+	/* with no local config, just system */
+
+	cl_sandbox_set_search_path_defaults();
+
+	cl_must_pass(p_mkdir("alternate/1", 0777));
+	cl_git_pass(git_buf_joinpath(&path, path.ptr, "1"));
+	cl_git_rewritefile("alternate/1/gitconfig", "[core]\n\tabbrev = 10\n");
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr));
+
+	cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
+	git_repository__cvar_cache_clear(repo);
+	val = -1;
+	cl_git_pass(git_repository__cvar(&val, repo, GIT_CVAR_ABBREV));
+	cl_assert_equal_i(10, val);
+	git_repository_free(repo);
+
+	/* with just xdg + system */
+
+	cl_must_pass(p_mkdir("alternate/2", 0777));
+	path.ptr[path.size - 1] = '2';
+	cl_git_rewritefile("alternate/2/config", "[core]\n\tabbrev = 20\n");
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr));
+
+	cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
+	git_repository__cvar_cache_clear(repo);
+	val = -1;
+	cl_git_pass(git_repository__cvar(&val, repo, GIT_CVAR_ABBREV));
+	cl_assert_equal_i(20, val);
+	git_repository_free(repo);
+
+	/* with global + xdg + system */
+
+	cl_must_pass(p_mkdir("alternate/3", 0777));
+	path.ptr[path.size - 1] = '3';
+	cl_git_rewritefile("alternate/3/.gitconfig", "[core]\n\tabbrev = 30\n");
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
+
+	cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
+	git_repository__cvar_cache_clear(repo);
+	val = -1;
+	cl_git_pass(git_repository__cvar(&val, repo, GIT_CVAR_ABBREV));
+	cl_assert_equal_i(30, val);
+	git_repository_free(repo);
+
+	/* with all configs */
+
+	cl_git_rewritefile("empty_standard_repo/.git/config", "[core]\n\tabbrev = 40\n");
+
+	cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
+	git_repository__cvar_cache_clear(repo);
+	val = -1;
+	cl_git_pass(git_repository__cvar(&val, repo, GIT_CVAR_ABBREV));
+	cl_assert_equal_i(40, val);
+	git_repository_free(repo);
+
+	/* with all configs but delete the files ? */
+
+	cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
+	git_repository__cvar_cache_clear(repo);
+	val = -1;
+	cl_git_pass(git_repository__cvar(&val, repo, GIT_CVAR_ABBREV));
+	cl_assert_equal_i(40, val);
+
+	cl_must_pass(p_unlink("empty_standard_repo/.git/config"));
+	cl_assert(!git_path_isfile("empty_standard_repo/.git/config"));
+
+	cl_must_pass(p_unlink("alternate/1/gitconfig"));
+	cl_assert(!git_path_isfile("alternate/1/gitconfig"));
+
+	cl_must_pass(p_unlink("alternate/2/config"));
+	cl_assert(!git_path_isfile("alternate/2/config"));
+
+	cl_must_pass(p_unlink("alternate/3/.gitconfig"));
+	cl_assert(!git_path_isfile("alternate/3/.gitconfig"));
+
+	git_repository__cvar_cache_clear(repo);
+	val = -1;
+	cl_git_pass(git_repository__cvar(&val, repo, GIT_CVAR_ABBREV));
+	cl_assert_equal_i(40, val);
+	git_repository_free(repo);
+
+	/* reopen */
+
+	cl_assert(!git_path_isfile("empty_standard_repo/.git/config"));
+	cl_assert(!git_path_isfile("alternate/3/.gitconfig"));
+
+	cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
+	git_repository__cvar_cache_clear(repo);
+	val = -1;
+	cl_git_pass(git_repository__cvar(&val, repo, GIT_CVAR_ABBREV));
+	cl_assert_equal_i(7, val);
+	git_repository_free(repo);
+
+	cl_assert(!git_path_exists("empty_standard_repo/.git/config"));
+	cl_assert(!git_path_exists("alternate/3/.gitconfig"));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/discover.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/discover.c
new file mode 100755
index 0000000..7904b64
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/discover.c
@@ -0,0 +1,143 @@
+#include "clar_libgit2.h"
+
+#include "odb.h"
+#include "fileops.h"
+#include "repository.h"
+
+#define TEMP_REPO_FOLDER "temprepo/"
+#define DISCOVER_FOLDER TEMP_REPO_FOLDER "discover.git"
+
+#define SUB_REPOSITORY_FOLDER_NAME "sub_repo"
+#define SUB_REPOSITORY_FOLDER DISCOVER_FOLDER "/" SUB_REPOSITORY_FOLDER_NAME
+#define SUB_REPOSITORY_FOLDER_SUB SUB_REPOSITORY_FOLDER "/sub"
+#define SUB_REPOSITORY_FOLDER_SUB_SUB SUB_REPOSITORY_FOLDER_SUB "/subsub"
+#define SUB_REPOSITORY_FOLDER_SUB_SUB_SUB SUB_REPOSITORY_FOLDER_SUB_SUB "/subsubsub"
+
+#define REPOSITORY_ALTERNATE_FOLDER DISCOVER_FOLDER "/alternate_sub_repo"
+#define REPOSITORY_ALTERNATE_FOLDER_SUB REPOSITORY_ALTERNATE_FOLDER "/sub"
+#define REPOSITORY_ALTERNATE_FOLDER_SUB_SUB REPOSITORY_ALTERNATE_FOLDER_SUB "/subsub"
+#define REPOSITORY_ALTERNATE_FOLDER_SUB_SUB_SUB REPOSITORY_ALTERNATE_FOLDER_SUB_SUB "/subsubsub"
+
+#define ALTERNATE_MALFORMED_FOLDER1 DISCOVER_FOLDER "/alternate_malformed_repo1"
+#define ALTERNATE_MALFORMED_FOLDER2 DISCOVER_FOLDER "/alternate_malformed_repo2"
+#define ALTERNATE_MALFORMED_FOLDER3 DISCOVER_FOLDER "/alternate_malformed_repo3"
+#define ALTERNATE_NOT_FOUND_FOLDER DISCOVER_FOLDER "/alternate_not_found_repo"
+
+static void ensure_repository_discover(const char *start_path,
+                                       const char *ceiling_dirs,
+				       git_buf *expected_path)
+{
+	git_buf found_path = GIT_BUF_INIT;
+	cl_git_pass(git_repository_discover(&found_path, start_path, 0, ceiling_dirs));
+	//across_fs is always 0 as we can't automate the filesystem change tests
+	cl_assert_equal_s(found_path.ptr, expected_path->ptr);
+	git_buf_free(&found_path);
+}
+
+static void write_file(const char *path, const char *content)
+{
+	git_file file;
+   int error;
+
+	if (git_path_exists(path)) {
+		cl_git_pass(p_unlink(path));
+	}
+
+	file = git_futils_creat_withpath(path, 0777, 0666);
+	cl_assert(file >= 0);
+
+	error = p_write(file, content, strlen(content) * sizeof(char));
+	p_close(file);
+	cl_git_pass(error);
+}
+
+//no check is performed on ceiling_dirs length, so be sure it's long enough
+static void append_ceiling_dir(git_buf *ceiling_dirs, const char *path)
+{
+	git_buf pretty_path = GIT_BUF_INIT;
+	char ceiling_separator[2] = { GIT_PATH_LIST_SEPARATOR, '\0' };
+
+	cl_git_pass(git_path_prettify_dir(&pretty_path, path, NULL));
+
+	if (ceiling_dirs->size > 0)
+		git_buf_puts(ceiling_dirs, ceiling_separator);
+
+	git_buf_puts(ceiling_dirs, pretty_path.ptr);
+
+	git_buf_free(&pretty_path);
+	cl_assert(git_buf_oom(ceiling_dirs) == 0);
+}
+
+void test_repo_discover__0(void)
+{
+	// test discover
+	git_repository *repo;
+	git_buf ceiling_dirs_buf = GIT_BUF_INIT, repository_path = GIT_BUF_INIT,
+		sub_repository_path = GIT_BUF_INIT, found_path = GIT_BUF_INIT;
+	const char *ceiling_dirs;
+	const mode_t mode = 0777;
+
+	git_futils_mkdir_r(DISCOVER_FOLDER, NULL, mode);
+	append_ceiling_dir(&ceiling_dirs_buf, TEMP_REPO_FOLDER);
+	ceiling_dirs = git_buf_cstr(&ceiling_dirs_buf);
+
+	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(&repository_path, DISCOVER_FOLDER, 0, ceiling_dirs));
+
+	cl_git_pass(git_repository_init(&repo, DISCOVER_FOLDER, 1));
+	cl_git_pass(git_repository_discover(&repository_path, DISCOVER_FOLDER, 0, ceiling_dirs));
+	git_repository_free(repo);
+
+	cl_git_pass(git_repository_init(&repo, SUB_REPOSITORY_FOLDER, 0));
+	cl_git_pass(git_futils_mkdir_r(SUB_REPOSITORY_FOLDER_SUB_SUB_SUB, NULL, mode));
+	cl_git_pass(git_repository_discover(&sub_repository_path, SUB_REPOSITORY_FOLDER, 0, ceiling_dirs));
+
+	cl_git_pass(git_futils_mkdir_r(SUB_REPOSITORY_FOLDER_SUB_SUB_SUB, NULL, mode));
+	ensure_repository_discover(SUB_REPOSITORY_FOLDER_SUB, ceiling_dirs, &sub_repository_path);
+	ensure_repository_discover(SUB_REPOSITORY_FOLDER_SUB_SUB, ceiling_dirs, &sub_repository_path);
+	ensure_repository_discover(SUB_REPOSITORY_FOLDER_SUB_SUB_SUB, ceiling_dirs, &sub_repository_path);
+
+	cl_git_pass(git_futils_mkdir_r(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB_SUB, NULL, mode));
+	write_file(REPOSITORY_ALTERNATE_FOLDER "/" DOT_GIT, "gitdir: ../" SUB_REPOSITORY_FOLDER_NAME "/" DOT_GIT);
+	write_file(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB "/" DOT_GIT, "gitdir: ../../../" SUB_REPOSITORY_FOLDER_NAME "/" DOT_GIT);
+	write_file(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB_SUB "/" DOT_GIT, "gitdir: ../../../../");
+	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER, ceiling_dirs, &sub_repository_path);
+	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB, ceiling_dirs, &sub_repository_path);
+	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB, ceiling_dirs, &sub_repository_path);
+	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB_SUB, ceiling_dirs, &repository_path);
+
+	cl_git_pass(git_futils_mkdir_r(ALTERNATE_MALFORMED_FOLDER1, NULL, mode));
+	write_file(ALTERNATE_MALFORMED_FOLDER1 "/" DOT_GIT, "Anything but not gitdir:");
+	cl_git_pass(git_futils_mkdir_r(ALTERNATE_MALFORMED_FOLDER2, NULL, mode));
+	write_file(ALTERNATE_MALFORMED_FOLDER2 "/" DOT_GIT, "gitdir:");
+	cl_git_pass(git_futils_mkdir_r(ALTERNATE_MALFORMED_FOLDER3, NULL, mode));
+	write_file(ALTERNATE_MALFORMED_FOLDER3 "/" DOT_GIT, "gitdir: \n\n\n");
+	cl_git_pass(git_futils_mkdir_r(ALTERNATE_NOT_FOUND_FOLDER, NULL, mode));
+	write_file(ALTERNATE_NOT_FOUND_FOLDER "/" DOT_GIT, "gitdir: a_repository_that_surely_does_not_exist");
+	cl_git_fail(git_repository_discover(&found_path, ALTERNATE_MALFORMED_FOLDER1, 0, ceiling_dirs));
+	cl_git_fail(git_repository_discover(&found_path, ALTERNATE_MALFORMED_FOLDER2, 0, ceiling_dirs));
+	cl_git_fail(git_repository_discover(&found_path, ALTERNATE_MALFORMED_FOLDER3, 0, ceiling_dirs));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(&found_path, ALTERNATE_NOT_FOUND_FOLDER, 0, ceiling_dirs));
+
+	append_ceiling_dir(&ceiling_dirs_buf, SUB_REPOSITORY_FOLDER);
+	ceiling_dirs = git_buf_cstr(&ceiling_dirs_buf);
+
+	//this must pass as ceiling_directories cannot predent the current
+	//working directory to be checked
+	cl_git_pass(git_repository_discover(&found_path, SUB_REPOSITORY_FOLDER, 0, ceiling_dirs));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(&found_path, SUB_REPOSITORY_FOLDER_SUB, 0, ceiling_dirs));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(&found_path, SUB_REPOSITORY_FOLDER_SUB_SUB, 0, ceiling_dirs));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(&found_path, SUB_REPOSITORY_FOLDER_SUB_SUB_SUB, 0, ceiling_dirs));
+
+	//.gitfile redirection should not be affected by ceiling directories
+	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER, ceiling_dirs, &sub_repository_path);
+	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB, ceiling_dirs, &sub_repository_path);
+	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB, ceiling_dirs, &sub_repository_path);
+	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB_SUB, ceiling_dirs, &repository_path);
+
+	cl_git_pass(git_futils_rmdir_r(TEMP_REPO_FOLDER, NULL, GIT_RMDIR_REMOVE_FILES));
+	git_repository_free(repo);
+	git_buf_free(&ceiling_dirs_buf);
+	git_buf_free(&repository_path);
+	git_buf_free(&sub_repository_path);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/getters.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/getters.c
new file mode 100755
index 0000000..b8ede12
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/getters.c
@@ -0,0 +1,40 @@
+#include "clar_libgit2.h"
+
+void test_repo_getters__is_empty_correctly_deals_with_pristine_looking_repos(void)
+{
+	git_repository *repo;
+
+	repo = cl_git_sandbox_init("empty_bare.git");
+	cl_git_remove_placeholders(git_repository_path(repo), "dummy-marker.txt");
+
+	cl_assert_equal_i(true, git_repository_is_empty(repo));
+
+	cl_git_sandbox_cleanup();
+}
+
+void test_repo_getters__is_empty_can_detect_used_repositories(void)
+{
+	git_repository *repo;
+
+	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+
+	cl_assert_equal_i(false, git_repository_is_empty(repo));
+
+	git_repository_free(repo);
+}
+
+void test_repo_getters__retrieving_the_odb_honors_the_refcount(void)
+{
+	git_odb *odb;
+	git_repository *repo;
+
+	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+
+	cl_git_pass(git_repository_odb(&odb, repo));
+	cl_assert(((git_refcount *)odb)->refcount.val == 2);
+
+	git_repository_free(repo);
+	cl_assert(((git_refcount *)odb)->refcount.val == 1);
+
+	git_odb_free(odb);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/hashfile.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/hashfile.c
new file mode 100755
index 0000000..ae8e122
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/hashfile.c
@@ -0,0 +1,85 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+
+static git_repository *_repo;
+
+void test_repo_hashfile__initialize(void)
+{
+	_repo = cl_git_sandbox_init("status");
+}
+
+void test_repo_hashfile__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+	_repo = NULL;
+}
+
+void test_repo_hashfile__simple(void)
+{
+	git_oid a, b;
+	git_buf full = GIT_BUF_INIT;
+
+	/* hash with repo relative path */
+	cl_git_pass(git_odb_hashfile(&a, "status/current_file", GIT_OBJ_BLOB));
+	cl_git_pass(git_repository_hashfile(&b, _repo, "current_file", GIT_OBJ_BLOB, NULL));
+	cl_assert_equal_oid(&a, &b);
+
+	cl_git_pass(git_buf_joinpath(&full, git_repository_workdir(_repo), "current_file"));
+
+	/* hash with full path */
+	cl_git_pass(git_odb_hashfile(&a, full.ptr, GIT_OBJ_BLOB));
+	cl_git_pass(git_repository_hashfile(&b, _repo, full.ptr, GIT_OBJ_BLOB, NULL));
+	cl_assert_equal_oid(&a, &b);
+
+	/* hash with invalid type */
+	cl_git_fail(git_odb_hashfile(&a, full.ptr, GIT_OBJ_ANY));
+	cl_git_fail(git_repository_hashfile(&b, _repo, full.ptr, GIT_OBJ_OFS_DELTA, NULL));
+
+	git_buf_free(&full);
+}
+
+void test_repo_hashfile__filtered(void)
+{
+	git_oid a, b;
+
+	cl_repo_set_bool(_repo, "core.autocrlf", true);
+
+	cl_git_append2file("status/.gitattributes", "*.txt text\n*.bin binary\n\n");
+
+	/* create some sample content with CRLF in it */
+	cl_git_mkfile("status/testfile.txt", "content\r\n");
+	cl_git_mkfile("status/testfile.bin", "other\r\nstuff\r\n");
+
+	/* not equal hashes because of filtering */
+	cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJ_BLOB));
+	cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJ_BLOB, NULL));
+	cl_assert(git_oid_cmp(&a, &b));
+
+	/* equal hashes because filter is binary */
+	cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJ_BLOB));
+	cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.bin", GIT_OBJ_BLOB, NULL));
+	cl_assert_equal_oid(&a, &b);
+
+	/* equal hashes when 'as_file' points to binary filtering */
+	cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJ_BLOB));
+	cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJ_BLOB, "foo.bin"));
+	cl_assert_equal_oid(&a, &b);
+
+	/* not equal hashes when 'as_file' points to text filtering */
+	cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJ_BLOB));
+	cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.bin", GIT_OBJ_BLOB, "foo.txt"));
+	cl_assert(git_oid_cmp(&a, &b));
+
+	/* equal hashes when 'as_file' is empty and turns off filtering */
+	cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJ_BLOB));
+	cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJ_BLOB, ""));
+	cl_assert_equal_oid(&a, &b);
+
+	cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJ_BLOB));
+	cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.bin", GIT_OBJ_BLOB, ""));
+	cl_assert_equal_oid(&a, &b);
+
+	/* some hash type failures */
+	cl_git_fail(git_odb_hashfile(&a, "status/testfile.txt", 0));
+	cl_git_fail(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJ_ANY, NULL));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/head.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/head.c
new file mode 100755
index 0000000..31c2287
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/head.c
@@ -0,0 +1,461 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+#include "repo_helpers.h"
+#include "posix.h"
+#include "git2/annotated_commit.h"
+
+static const char *g_email = "foo at example.com";
+static git_repository *repo;
+
+void test_repo_head__initialize(void)
+{
+	repo = cl_git_sandbox_init("testrepo.git");
+	cl_git_pass(git_repository_set_ident(repo, "Foo Bar", g_email));
+}
+
+void test_repo_head__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static void check_last_reflog_entry(const char *email, const char *message)
+{
+	git_reflog *log;
+	const git_reflog_entry *entry;
+
+	cl_git_pass(git_reflog_read(&log, repo, GIT_HEAD_FILE));
+	cl_assert(git_reflog_entrycount(log) > 0);
+	entry = git_reflog_entry_byindex(log, 0);
+	if (email)
+		cl_assert_equal_s(email, git_reflog_entry_committer(entry)->email);
+	if (message)
+		cl_assert_equal_s(message, git_reflog_entry_message(entry));
+	git_reflog_free(log);
+}
+
+void test_repo_head__head_detached(void)
+{
+	git_reference *ref;
+
+	cl_assert_equal_i(false, git_repository_head_detached(repo));
+
+	cl_git_pass(git_repository_detach_head(repo));
+	check_last_reflog_entry(g_email, "checkout: moving from master to a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+	cl_assert_equal_i(true, git_repository_head_detached(repo));
+
+	/* take the repo back to it's original state */
+	cl_git_pass(git_reference_symbolic_create(&ref, repo, "HEAD", "refs/heads/master",
+				true, "REATTACH"));
+	git_reference_free(ref);
+
+	check_last_reflog_entry(g_email, "REATTACH");
+	cl_assert_equal_i(false, git_repository_head_detached(repo));
+}
+
+void test_repo_head__unborn_head(void)
+{
+	git_reference *ref;
+
+	cl_git_pass(git_repository_head_detached(repo));
+
+	make_head_unborn(repo, NON_EXISTING_HEAD);
+
+	cl_assert(git_repository_head_unborn(repo) == 1);
+
+
+	/* take the repo back to it's original state */
+	cl_git_pass(git_reference_symbolic_create(&ref, repo, "HEAD", "refs/heads/master", 1, NULL));
+	cl_assert(git_repository_head_unborn(repo) == 0);
+
+	git_reference_free(ref);
+}
+
+void test_repo_head__set_head_Attaches_HEAD_to_un_unborn_branch_when_the_branch_doesnt_exist(void)
+{
+	git_reference *head;
+
+	cl_git_pass(git_repository_set_head(repo, "refs/heads/doesnt/exist/yet"));
+
+	cl_assert_equal_i(false, git_repository_head_detached(repo));
+
+	cl_assert_equal_i(GIT_EUNBORNBRANCH, git_repository_head(&head, repo));
+}
+
+void test_repo_head__set_head_Returns_ENOTFOUND_when_the_reference_doesnt_exist(void)
+{
+	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_set_head(repo, "refs/tags/doesnt/exist/yet"));
+}
+
+void test_repo_head__set_head_Fails_when_the_reference_points_to_a_non_commitish(void)
+{
+	cl_git_fail(git_repository_set_head(repo, "refs/tags/point_to_blob"));
+}
+
+void test_repo_head__set_head_Attaches_HEAD_when_the_reference_points_to_a_branch(void)
+{
+	git_reference *head;
+
+	cl_git_pass(git_repository_set_head(repo, "refs/heads/br2"));
+
+	cl_assert_equal_i(false, git_repository_head_detached(repo));
+
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_assert_equal_s("refs/heads/br2", git_reference_name(head));
+
+	git_reference_free(head);
+}
+
+static void assert_head_is_correctly_detached(void)
+{
+	git_reference *head;
+	git_object *commit;
+
+	cl_assert_equal_i(true, git_repository_head_detached(repo));
+
+	cl_git_pass(git_repository_head(&head, repo));
+
+	cl_git_pass(git_object_lookup(&commit, repo, git_reference_target(head), GIT_OBJ_COMMIT));
+
+	git_object_free(commit);
+	git_reference_free(head);
+}
+
+void test_repo_head__set_head_Detaches_HEAD_when_the_reference_doesnt_point_to_a_branch(void)
+{
+	cl_git_pass(git_repository_set_head(repo, "refs/tags/test"));
+
+	cl_assert_equal_i(true, git_repository_head_detached(repo));
+
+	assert_head_is_correctly_detached();
+}
+
+void test_repo_head__set_head_detached_Return_ENOTFOUND_when_the_object_doesnt_exist(void)
+{
+	git_oid oid;
+
+	cl_git_pass(git_oid_fromstr(&oid, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
+
+	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_set_head_detached(repo, &oid));
+}
+
+void test_repo_head__set_head_detached_Fails_when_the_object_isnt_a_commitish(void)
+{
+	git_object *blob;
+
+	cl_git_pass(git_revparse_single(&blob, repo, "point_to_blob"));
+
+	cl_git_fail(git_repository_set_head_detached(repo, git_object_id(blob)));
+
+	git_object_free(blob);
+}
+
+void test_repo_head__set_head_detached_Detaches_HEAD_and_make_it_point_to_the_peeled_commit(void)
+{
+	git_object *tag;
+
+	cl_git_pass(git_revparse_single(&tag, repo, "tags/test"));
+	cl_assert_equal_i(GIT_OBJ_TAG, git_object_type(tag));
+
+	cl_git_pass(git_repository_set_head_detached(repo, git_object_id(tag)));
+
+	assert_head_is_correctly_detached();
+
+	git_object_free(tag);
+}
+
+void test_repo_head__detach_head_Detaches_HEAD_and_make_it_point_to_the_peeled_commit(void)
+{
+	cl_assert_equal_i(false, git_repository_head_detached(repo));
+
+	cl_git_pass(git_repository_detach_head(repo));
+
+	assert_head_is_correctly_detached();
+}
+
+void test_repo_head__detach_head_Fails_if_HEAD_and_point_to_a_non_commitish(void)
+{
+	git_reference *head;
+
+	cl_git_pass(git_reference_symbolic_create(&head, repo, GIT_HEAD_FILE, "refs/tags/point_to_blob", 1, NULL));
+
+	cl_git_fail(git_repository_detach_head(repo));
+
+	git_reference_free(head);
+}
+
+void test_repo_head__detaching_an_unborn_branch_returns_GIT_EUNBORNBRANCH(void)
+{
+	make_head_unborn(repo, NON_EXISTING_HEAD);
+
+	cl_assert_equal_i(GIT_EUNBORNBRANCH, git_repository_detach_head(repo));
+}
+
+void test_repo_head__retrieving_an_unborn_branch_returns_GIT_EUNBORNBRANCH(void)
+{
+	git_reference *head;
+
+	make_head_unborn(repo, NON_EXISTING_HEAD);
+
+	cl_assert_equal_i(GIT_EUNBORNBRANCH, git_repository_head(&head, repo));
+}
+
+void test_repo_head__retrieving_a_missing_head_returns_GIT_ENOTFOUND(void)
+{
+	git_reference *head;
+
+	delete_head(repo);
+
+	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_head(&head, repo));
+}
+
+void test_repo_head__can_tell_if_an_unborn_head_is_detached(void)
+{
+	make_head_unborn(repo, NON_EXISTING_HEAD);
+
+	cl_assert_equal_i(false, git_repository_head_detached(repo));
+}
+
+static void test_reflog(git_repository *repo, size_t idx,
+		const char *old_spec, const char *new_spec,
+		const char *email, const char *message)
+{
+	git_reflog *log;
+	const git_reflog_entry *entry;
+
+	cl_git_pass(git_reflog_read(&log, repo, "HEAD"));
+	entry = git_reflog_entry_byindex(log, idx);
+
+	if (old_spec) {
+		git_object *obj;
+		cl_git_pass(git_revparse_single(&obj, repo, old_spec));
+		cl_assert_equal_oid(git_object_id(obj), git_reflog_entry_id_old(entry));
+		git_object_free(obj);
+	}
+	if (new_spec) {
+		git_object *obj;
+		cl_git_pass(git_revparse_single(&obj, repo, new_spec));
+		cl_assert_equal_oid(git_object_id(obj), git_reflog_entry_id_new(entry));
+		git_object_free(obj);
+	}
+
+	if (email) {
+		cl_assert_equal_s(email, git_reflog_entry_committer(entry)->email);
+	}
+	if (message) {
+		cl_assert_equal_s(message, git_reflog_entry_message(entry));
+	}
+
+	git_reflog_free(log);
+}
+
+void test_repo_head__setting_head_updates_reflog(void)
+{
+	git_object *tag;
+	git_signature *sig;
+	git_annotated_commit *annotated;
+
+	cl_git_pass(git_signature_now(&sig, "me", "foo at example.com"));
+
+	cl_git_pass(git_repository_set_head(repo, "refs/heads/haacked"));
+	cl_git_pass(git_repository_set_head(repo, "refs/heads/unborn"));
+	cl_git_pass(git_revparse_single(&tag, repo, "tags/test"));
+	cl_git_pass(git_repository_set_head_detached(repo, git_object_id(tag)));
+	cl_git_pass(git_repository_set_head(repo, "refs/heads/haacked"));
+
+	test_reflog(repo, 2, NULL, "refs/heads/haacked", "foo at example.com", "checkout: moving from master to haacked");
+	test_reflog(repo, 1, NULL, "tags/test^{commit}", "foo at example.com", "checkout: moving from unborn to e90810b8df3e80c413d903f631643c716887138d");
+	test_reflog(repo, 0, "tags/test^{commit}", "refs/heads/haacked", "foo at example.com", "checkout: moving from e90810b8df3e80c413d903f631643c716887138d to haacked");
+
+	cl_git_pass(git_annotated_commit_from_revspec(&annotated, repo, "haacked~0"));
+	cl_git_pass(git_repository_set_head_detached_from_annotated(repo, annotated));
+
+	test_reflog(repo, 0, NULL, "refs/heads/haacked", "foo at example.com", "checkout: moving from haacked to haacked~0");
+
+	git_annotated_commit_free(annotated);
+	git_object_free(tag);
+	git_signature_free(sig);
+}
+
+static void assert_head_reflog(git_repository *repo, size_t idx,
+			       const char *old_id, const char *new_id, const char *message)
+{
+	git_reflog *log;
+	const git_reflog_entry *entry;
+	char id_str[GIT_OID_HEXSZ + 1] = {0};
+
+	cl_git_pass(git_reflog_read(&log, repo, GIT_HEAD_FILE));
+	entry = git_reflog_entry_byindex(log, idx);
+
+	git_oid_fmt(id_str, git_reflog_entry_id_old(entry));
+	cl_assert_equal_s(old_id, id_str);
+
+	git_oid_fmt(id_str, git_reflog_entry_id_new(entry));
+	cl_assert_equal_s(new_id, id_str);
+
+	cl_assert_equal_s(message, git_reflog_entry_message(entry));
+
+	git_reflog_free(log);
+}
+
+void test_repo_head__detaching_writes_reflog(void)
+{
+	git_signature *sig;
+	git_oid id;
+	const char *msg;
+
+	cl_git_pass(git_signature_now(&sig, "me", "foo at example.com"));
+
+	msg = "checkout: moving from master to e90810b8df3e80c413d903f631643c716887138d";
+	git_oid_fromstr(&id, "e90810b8df3e80c413d903f631643c716887138d");
+	cl_git_pass(git_repository_set_head_detached(repo, &id));
+	assert_head_reflog(repo, 0, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+			   "e90810b8df3e80c413d903f631643c716887138d", msg);
+
+	msg = "checkout: moving from e90810b8df3e80c413d903f631643c716887138d to haacked";
+	cl_git_pass(git_repository_set_head(repo, "refs/heads/haacked"));
+	assert_head_reflog(repo, 0, "e90810b8df3e80c413d903f631643c716887138d",
+			   "258f0e2a959a364e40ed6603d5d44fbb24765b10", msg);
+
+	git_signature_free(sig);
+}
+
+void test_repo_head__orphan_branch_does_not_count(void)
+{
+	git_oid id;
+	const char *msg;
+
+	/* Have something known */
+	msg = "checkout: moving from master to e90810b8df3e80c413d903f631643c716887138d";
+	git_oid_fromstr(&id, "e90810b8df3e80c413d903f631643c716887138d");
+	cl_git_pass(git_repository_set_head_detached(repo, &id));
+	assert_head_reflog(repo, 0, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+			   "e90810b8df3e80c413d903f631643c716887138d", msg);
+
+	/* Switching to an orphan branch does not write tot he reflog */
+	cl_git_pass(git_repository_set_head(repo, "refs/heads/orphan"));
+	assert_head_reflog(repo, 0, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+			   "e90810b8df3e80c413d903f631643c716887138d", msg);
+
+	/* And coming back, we set the source to zero */
+	msg = "checkout: moving from orphan to haacked";
+	cl_git_pass(git_repository_set_head(repo, "refs/heads/haacked"));
+	assert_head_reflog(repo, 0, "0000000000000000000000000000000000000000",
+			   "258f0e2a959a364e40ed6603d5d44fbb24765b10", msg);
+}
+
+void test_repo_head__set_to_current_target(void)
+{
+	git_reflog *log;
+	size_t nentries, nentries_after;
+
+	cl_git_pass(git_reflog_read(&log, repo, GIT_HEAD_FILE));
+	nentries = git_reflog_entrycount(log);
+	git_reflog_free(log);
+
+	cl_git_pass(git_repository_set_head(repo, "refs/heads/haacked"));
+	cl_git_pass(git_repository_set_head(repo, "refs/heads/haacked"));
+
+	cl_git_pass(git_reflog_read(&log, repo, GIT_HEAD_FILE));
+	nentries_after = git_reflog_entrycount(log);
+	git_reflog_free(log);
+
+	cl_assert_equal_i(nentries + 1, nentries_after);
+}
+
+void test_repo_head__branch_birth(void)
+{
+	git_signature *sig;
+	git_oid id;
+	git_tree *tree;
+	git_reference *ref;
+	const char *msg;
+	git_reflog *log;
+	size_t nentries, nentries_after;
+
+	cl_git_pass(git_reflog_read(&log, repo, GIT_HEAD_FILE));
+	nentries = git_reflog_entrycount(log);
+	git_reflog_free(log);
+
+	cl_git_pass(git_signature_now(&sig, "me", "foo at example.com"));
+
+	cl_git_pass(git_repository_head(&ref, repo));
+	cl_git_pass(git_reference_peel((git_object **) &tree, ref, GIT_OBJ_TREE));
+	git_reference_free(ref);
+
+	cl_git_pass(git_repository_set_head(repo, "refs/heads/orphan"));
+
+	cl_git_pass(git_reflog_read(&log, repo, GIT_HEAD_FILE));
+	nentries_after = git_reflog_entrycount(log);
+	git_reflog_free(log);
+
+	cl_assert_equal_i(nentries, nentries_after);
+
+	msg = "message 2";
+	cl_git_pass(git_commit_create(&id, repo, "HEAD", sig, sig, NULL, msg, tree, 0, NULL));
+
+	git_tree_free(tree);
+
+	cl_git_pass(git_reflog_read(&log, repo, "refs/heads/orphan"));
+	cl_assert_equal_i(1, git_reflog_entrycount(log));
+	git_reflog_free(log);
+
+	cl_git_pass(git_reflog_read(&log, repo, GIT_HEAD_FILE));
+	nentries_after = git_reflog_entrycount(log);
+	git_reflog_free(log);
+
+	cl_assert_equal_i(nentries + 1, nentries_after);
+
+	git_signature_free(sig);
+
+}
+
+static size_t entrycount(git_repository *repo, const char *name)
+{
+	git_reflog *log;
+	size_t ret;
+
+	cl_git_pass(git_reflog_read(&log, repo, name));
+	ret = git_reflog_entrycount(log);
+	git_reflog_free(log);
+
+	return ret;
+}
+
+void test_repo_head__symref_chain(void)
+{
+	git_signature *sig;
+	git_oid id;
+	git_tree *tree;
+	git_reference *ref;
+	const char *msg;
+	size_t nentries, nentries_master;
+
+	nentries = entrycount(repo, GIT_HEAD_FILE);
+
+	cl_git_pass(git_signature_now(&sig, "me", "foo at example.com"));
+
+	cl_git_pass(git_repository_head(&ref, repo));
+	cl_git_pass(git_reference_peel((git_object **) &tree, ref, GIT_OBJ_TREE));
+	git_reference_free(ref);
+
+	nentries_master = entrycount(repo, "refs/heads/master");
+
+	msg = "message 1";
+	cl_git_pass(git_reference_symbolic_create(&ref, repo, "refs/heads/master", "refs/heads/foo", 1, msg));
+	git_reference_free(ref);
+
+	cl_assert_equal_i(0, entrycount(repo, "refs/heads/foo"));
+	cl_assert_equal_i(nentries, entrycount(repo, GIT_HEAD_FILE));
+	cl_assert_equal_i(nentries_master, entrycount(repo, "refs/heads/master"));
+
+	msg = "message 2";
+	cl_git_pass(git_commit_create(&id, repo, "HEAD", sig, sig, NULL, msg, tree, 0, NULL));
+	git_tree_free(tree);
+
+	cl_assert_equal_i(1, entrycount(repo, "refs/heads/foo"));
+	cl_assert_equal_i(nentries +1, entrycount(repo, GIT_HEAD_FILE));
+	cl_assert_equal_i(nentries_master, entrycount(repo, "refs/heads/master"));
+
+	git_signature_free(sig);
+
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/headtree.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/headtree.c
new file mode 100755
index 0000000..e899ac3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/headtree.c
@@ -0,0 +1,53 @@
+#include "clar_libgit2.h"
+#include "repository.h"
+#include "repo_helpers.h"
+#include "posix.h"
+
+static git_repository *repo;
+static git_tree *tree;
+
+void test_repo_headtree__initialize(void)
+{
+	repo = cl_git_sandbox_init("testrepo.git");
+	tree = NULL;
+}
+
+void test_repo_headtree__cleanup(void)
+{
+	git_tree_free(tree);
+	cl_git_sandbox_cleanup();
+}
+
+void test_repo_headtree__can_retrieve_the_root_tree_from_a_detached_head(void)
+{
+	cl_git_pass(git_repository_detach_head(repo));
+
+	cl_git_pass(git_repository_head_tree(&tree, repo));
+
+	cl_assert(git_oid_streq(git_tree_id(tree), "az"));
+}
+
+void test_repo_headtree__can_retrieve_the_root_tree_from_a_non_detached_head(void)
+{
+	cl_assert_equal_i(false, git_repository_head_detached(repo));
+
+	cl_git_pass(git_repository_head_tree(&tree, repo));
+
+	cl_assert(git_oid_streq(git_tree_id(tree), "az"));
+}
+
+void test_repo_headtree__when_head_is_unborn_returns_EUNBORNBRANCH(void)
+{
+	make_head_unborn(repo, NON_EXISTING_HEAD);
+
+	cl_assert_equal_i(true, git_repository_head_unborn(repo));
+
+	cl_assert_equal_i(GIT_EUNBORNBRANCH, git_repository_head_tree(&tree, repo));
+}
+
+void test_repo_headtree__when_head_is_missing_returns_ENOTFOUND(void)
+{
+	delete_head(repo);
+
+	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_head_tree(&tree, repo));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/init.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/init.c
new file mode 100755
index 0000000..525020f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/init.c
@@ -0,0 +1,733 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "repository.h"
+#include "config.h"
+#include "path.h"
+#include "config/config_helpers.h"
+
+enum repo_mode {
+	STANDARD_REPOSITORY = 0,
+	BARE_REPOSITORY = 1
+};
+
+static git_repository *_repo = NULL;
+static mode_t g_umask = 0;
+
+void test_repo_init__initialize(void)
+{
+	_repo = NULL;
+
+	/* load umask if not already loaded */
+	if (!g_umask) {
+		g_umask = p_umask(022);
+		(void)p_umask(g_umask);
+	}
+}
+
+static void cleanup_repository(void *path)
+{
+	git_repository_free(_repo);
+	_repo = NULL;
+
+	cl_fixture_cleanup((const char *)path);
+}
+
+static void ensure_repository_init(
+	const char *working_directory,
+	int is_bare,
+	const char *expected_path_repository,
+	const char *expected_working_directory)
+{
+	const char *workdir;
+
+	cl_assert(!git_path_isdir(working_directory));
+
+	cl_git_pass(git_repository_init(&_repo, working_directory, is_bare));
+
+	workdir = git_repository_workdir(_repo);
+	if (workdir != NULL || expected_working_directory != NULL) {
+		cl_assert(
+			git__suffixcmp(workdir, expected_working_directory) == 0
+		);
+	}
+
+	cl_assert(
+		git__suffixcmp(git_repository_path(_repo), expected_path_repository) == 0
+	);
+
+	cl_assert(git_repository_is_bare(_repo) == is_bare);
+
+#ifdef GIT_WIN32
+	if (!is_bare) {
+		DWORD fattrs = GetFileAttributes(git_repository_path(_repo));
+		cl_assert((fattrs & FILE_ATTRIBUTE_HIDDEN) != 0);
+	}
+#endif
+
+	cl_assert(git_repository_is_empty(_repo));
+}
+
+void test_repo_init__standard_repo(void)
+{
+	cl_set_cleanup(&cleanup_repository, "testrepo");
+	ensure_repository_init("testrepo/", 0, "testrepo/.git/", "testrepo/");
+}
+
+void test_repo_init__standard_repo_noslash(void)
+{
+	cl_set_cleanup(&cleanup_repository, "testrepo");
+	ensure_repository_init("testrepo", 0, "testrepo/.git/", "testrepo/");
+}
+
+void test_repo_init__bare_repo(void)
+{
+	cl_set_cleanup(&cleanup_repository, "testrepo.git");
+	ensure_repository_init("testrepo.git/", 1, "testrepo.git/", NULL);
+}
+
+void test_repo_init__bare_repo_noslash(void)
+{
+	cl_set_cleanup(&cleanup_repository, "testrepo.git");
+	ensure_repository_init("testrepo.git", 1, "testrepo.git/", NULL);
+}
+
+void test_repo_init__bare_repo_escaping_current_workdir(void)
+{
+	git_buf path_repository = GIT_BUF_INIT;
+	git_buf path_current_workdir = GIT_BUF_INIT;
+
+	cl_git_pass(git_path_prettify_dir(&path_current_workdir, ".", NULL));
+
+	cl_git_pass(git_buf_joinpath(&path_repository, git_buf_cstr(&path_current_workdir), "a/b/c"));
+	cl_git_pass(git_futils_mkdir_r(git_buf_cstr(&path_repository), NULL, GIT_DIR_MODE));
+
+	/* Change the current working directory */
+	cl_git_pass(chdir(git_buf_cstr(&path_repository)));
+
+	/* Initialize a bare repo with a relative path escaping out of the current working directory */
+	cl_git_pass(git_repository_init(&_repo, "../d/e.git", 1));
+	cl_git_pass(git__suffixcmp(git_repository_path(_repo), "/a/b/d/e.git/"));
+
+	git_repository_free(_repo);
+
+	/* Open a bare repo with a relative path escaping out of the current working directory */
+	cl_git_pass(git_repository_open(&_repo, "../d/e.git"));
+
+	cl_git_pass(chdir(git_buf_cstr(&path_current_workdir)));
+
+	git_buf_free(&path_current_workdir);
+	git_buf_free(&path_repository);
+
+	cleanup_repository("a");
+}
+
+void test_repo_init__reinit_bare_repo(void)
+{
+	cl_set_cleanup(&cleanup_repository, "reinit.git");
+
+	/* Initialize the repository */
+	cl_git_pass(git_repository_init(&_repo, "reinit.git", 1));
+	git_repository_free(_repo);
+
+	/* Reinitialize the repository */
+	cl_git_pass(git_repository_init(&_repo, "reinit.git", 1));
+}
+
+void test_repo_init__reinit_too_recent_bare_repo(void)
+{
+	git_config *config;
+
+	/* Initialize the repository */
+	cl_git_pass(git_repository_init(&_repo, "reinit.git", 1));
+	git_repository_config(&config, _repo);
+
+	/*
+	 * Hack the config of the repository to make it look like it has
+	 * been created by a recenter version of git/libgit2
+	 */
+	cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 42));
+
+	git_config_free(config);
+	git_repository_free(_repo);
+
+	/* Try to reinitialize the repository */
+	cl_git_fail(git_repository_init(&_repo, "reinit.git", 1));
+
+	cl_fixture_cleanup("reinit.git");
+}
+
+void test_repo_init__additional_templates(void)
+{
+	git_buf path = GIT_BUF_INIT;
+
+	cl_set_cleanup(&cleanup_repository, "tester");
+
+	ensure_repository_init("tester", 0, "tester/.git/", "tester/");
+
+	cl_git_pass(
+		git_buf_joinpath(&path, git_repository_path(_repo), "description"));
+	cl_assert(git_path_isfile(git_buf_cstr(&path)));
+
+	cl_git_pass(
+		git_buf_joinpath(&path, git_repository_path(_repo), "info/exclude"));
+	cl_assert(git_path_isfile(git_buf_cstr(&path)));
+
+	cl_git_pass(
+		git_buf_joinpath(&path, git_repository_path(_repo), "hooks"));
+	cl_assert(git_path_isdir(git_buf_cstr(&path)));
+	/* won't confirm specific contents of hooks dir since it may vary */
+
+	git_buf_free(&path);
+}
+
+static void assert_config_entry_on_init_bytype(
+	const char *config_key, int expected_value, bool is_bare)
+{
+	git_config *config;
+	int error, current_value;
+	const char *repo_path = is_bare ?
+		"config_entry/test.bare.git" : "config_entry/test.non.bare.git";
+
+	cl_set_cleanup(&cleanup_repository, "config_entry");
+
+	cl_git_pass(git_repository_init(&_repo, repo_path, is_bare));
+
+	cl_git_pass(git_repository_config(&config, _repo));
+	error = git_config_get_bool(&current_value, config, config_key);
+	git_config_free(config);
+
+	if (expected_value >= 0) {
+		cl_assert_equal_i(0, error);
+		cl_assert_equal_i(expected_value, current_value);
+	} else {
+		cl_assert_equal_i(expected_value, error);
+	}
+}
+
+static void assert_config_entry_on_init(
+	const char *config_key, int expected_value)
+{
+	assert_config_entry_on_init_bytype(config_key, expected_value, true);
+	git_repository_free(_repo);
+
+	assert_config_entry_on_init_bytype(config_key, expected_value, false);
+}
+
+void test_repo_init__detect_filemode(void)
+{
+	assert_config_entry_on_init("core.filemode", cl_is_chmod_supported());
+}
+
+void test_repo_init__detect_ignorecase(void)
+{
+	struct stat st;
+	bool found_without_match;
+
+	cl_git_write2file("testCAPS", "whatever\n", 0, O_CREAT | O_WRONLY, 0666);
+	found_without_match = (p_stat("Testcaps", &st) == 0);
+	cl_must_pass(p_unlink("testCAPS"));
+
+	assert_config_entry_on_init(
+		"core.ignorecase", found_without_match ? true : GIT_ENOTFOUND);
+}
+
+void test_repo_init__detect_precompose_unicode_required(void)
+{
+#ifdef GIT_USE_ICONV
+	char *composed = "ḱṷṓn", *decomposed = "ḱṷṓn";
+	struct stat st;
+	bool found_with_nfd;
+
+	cl_git_write2file(composed, "whatever\n", 0, O_CREAT | O_WRONLY, 0666);
+	found_with_nfd = (p_stat(decomposed, &st) == 0);
+	cl_must_pass(p_unlink(composed));
+
+	assert_config_entry_on_init("core.precomposeunicode", found_with_nfd);
+#else
+	assert_config_entry_on_init("core.precomposeunicode", GIT_ENOTFOUND);
+#endif
+}
+
+void test_repo_init__reinit_doesnot_overwrite_ignorecase(void)
+{
+	git_config *config;
+	int current_value;
+
+	/* Init a new repo */
+	cl_set_cleanup(&cleanup_repository, "not.overwrite.git");
+	cl_git_pass(git_repository_init(&_repo, "not.overwrite.git", 1));
+
+	/* Change the "core.ignorecase" config value to something unlikely */
+	git_repository_config(&config, _repo);
+	git_config_set_int32(config, "core.ignorecase", 42);
+	git_config_free(config);
+	git_repository_free(_repo);
+	_repo = NULL;
+
+	/* Reinit the repository */
+	cl_git_pass(git_repository_init(&_repo, "not.overwrite.git", 1));
+	git_repository_config(&config, _repo);
+
+	/* Ensure the "core.ignorecase" config value hasn't been updated */
+	cl_git_pass(git_config_get_int32(&current_value, config, "core.ignorecase"));
+	cl_assert_equal_i(42, current_value);
+
+	git_config_free(config);
+}
+
+void test_repo_init__reinit_overwrites_filemode(void)
+{
+	int expected = cl_is_chmod_supported(), current_value;
+
+	/* Init a new repo */
+	cl_set_cleanup(&cleanup_repository, "overwrite.git");
+	cl_git_pass(git_repository_init(&_repo, "overwrite.git", 1));
+
+	/* Change the "core.filemode" config value to something unlikely */
+	cl_repo_set_bool(_repo, "core.filemode", !expected);
+
+	git_repository_free(_repo);
+	_repo = NULL;
+
+	/* Reinit the repository */
+	cl_git_pass(git_repository_init(&_repo, "overwrite.git", 1));
+
+	/* Ensure the "core.filemode" config value has been reset */
+	current_value = cl_repo_get_bool(_repo, "core.filemode");
+	cl_assert_equal_i(expected, current_value);
+}
+
+void test_repo_init__sets_logAllRefUpdates_according_to_type_of_repository(void)
+{
+	assert_config_entry_on_init_bytype("core.logallrefupdates", GIT_ENOTFOUND, true);
+	git_repository_free(_repo);
+	assert_config_entry_on_init_bytype("core.logallrefupdates", true, false);
+}
+
+void test_repo_init__extended_0(void)
+{
+	git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
+
+	/* without MKDIR this should fail */
+	cl_git_fail(git_repository_init_ext(&_repo, "extended", &opts));
+
+	/* make the directory first, then it should succeed */
+	cl_git_pass(git_futils_mkdir("extended", NULL, 0775, 0));
+	cl_git_pass(git_repository_init_ext(&_repo, "extended", &opts));
+
+	cl_assert(!git__suffixcmp(git_repository_workdir(_repo), "/extended/"));
+	cl_assert(!git__suffixcmp(git_repository_path(_repo), "/extended/.git/"));
+	cl_assert(!git_repository_is_bare(_repo));
+	cl_assert(git_repository_is_empty(_repo));
+
+	cleanup_repository("extended");
+}
+
+void test_repo_init__extended_1(void)
+{
+	git_reference *ref;
+	git_remote *remote;
+	struct stat st;
+	git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
+
+	opts.flags = GIT_REPOSITORY_INIT_MKPATH |
+		GIT_REPOSITORY_INIT_NO_DOTGIT_DIR;
+	opts.mode = GIT_REPOSITORY_INIT_SHARED_GROUP;
+	opts.workdir_path = "../c_wd";
+	opts.description = "Awesomest test repository evah";
+	opts.initial_head = "development";
+	opts.origin_url = "https://github.com/libgit2/libgit2.git";
+
+	cl_git_pass(git_repository_init_ext(&_repo, "root/b/c.git", &opts));
+
+	cl_assert(!git__suffixcmp(git_repository_workdir(_repo), "/c_wd/"));
+	cl_assert(!git__suffixcmp(git_repository_path(_repo), "/c.git/"));
+	cl_assert(git_path_isfile("root/b/c_wd/.git"));
+	cl_assert(!git_repository_is_bare(_repo));
+	/* repo will not be counted as empty because we set head to "development" */
+	cl_assert(!git_repository_is_empty(_repo));
+
+	cl_git_pass(git_path_lstat(git_repository_path(_repo), &st));
+	cl_assert(S_ISDIR(st.st_mode));
+	if (cl_is_chmod_supported())
+		cl_assert((S_ISGID & st.st_mode) == S_ISGID);
+	else
+		cl_assert((S_ISGID & st.st_mode) == 0);
+
+	cl_git_pass(git_reference_lookup(&ref, _repo, "HEAD"));
+	cl_assert(git_reference_type(ref) == GIT_REF_SYMBOLIC);
+	cl_assert_equal_s("refs/heads/development", git_reference_symbolic_target(ref));
+	git_reference_free(ref);
+
+	cl_git_pass(git_remote_lookup(&remote, _repo, "origin"));
+	cl_assert_equal_s("origin", git_remote_name(remote));
+	cl_assert_equal_s(opts.origin_url, git_remote_url(remote));
+	git_remote_free(remote);
+
+	git_repository_free(_repo);
+	cl_fixture_cleanup("root");
+}
+
+void test_repo_init__relative_gitdir(void)
+{
+	git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
+	git_buf dot_git_content = GIT_BUF_INIT;
+
+	opts.workdir_path = "../c_wd";
+	opts.flags =
+		GIT_REPOSITORY_INIT_MKPATH |
+		GIT_REPOSITORY_INIT_RELATIVE_GITLINK |
+		GIT_REPOSITORY_INIT_NO_DOTGIT_DIR;
+
+	/* make the directory first, then it should succeed */
+	cl_git_pass(git_repository_init_ext(&_repo, "root/b/my_repository", &opts));
+
+	cl_assert(!git__suffixcmp(git_repository_workdir(_repo), "root/b/c_wd/"));
+	cl_assert(!git__suffixcmp(git_repository_path(_repo), "root/b/my_repository/"));
+	cl_assert(!git_repository_is_bare(_repo));
+	cl_assert(git_repository_is_empty(_repo));
+
+	/* Verify that the gitlink and worktree entries are relative */
+
+	/* Verify worktree */
+	assert_config_entry_value(_repo, "core.worktree", "../c_wd/");
+
+	/* Verify gitlink */
+	cl_git_pass(git_futils_readbuffer(&dot_git_content, "root/b/c_wd/.git"));
+	cl_assert_equal_s("gitdir: ../my_repository/", dot_git_content.ptr);
+
+	git_buf_free(&dot_git_content);
+	cleanup_repository("root");
+}
+
+void test_repo_init__relative_gitdir_2(void)
+{
+	git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
+	git_buf dot_git_content = GIT_BUF_INIT;
+	git_buf full_path = GIT_BUF_INIT;
+
+	cl_git_pass(git_path_prettify(&full_path, ".", NULL));
+	cl_git_pass(git_buf_joinpath(&full_path, full_path.ptr, "root/b/c_wd"));
+
+	opts.workdir_path = full_path.ptr;
+	opts.flags =
+		GIT_REPOSITORY_INIT_MKPATH |
+		GIT_REPOSITORY_INIT_RELATIVE_GITLINK |
+		GIT_REPOSITORY_INIT_NO_DOTGIT_DIR;
+
+	/* make the directory first, then it should succeed */
+	cl_git_pass(git_repository_init_ext(&_repo, "root/b/my_repository", &opts));
+	git_buf_free(&full_path);
+
+	cl_assert(!git__suffixcmp(git_repository_workdir(_repo), "root/b/c_wd/"));
+	cl_assert(!git__suffixcmp(git_repository_path(_repo), "root/b/my_repository/"));
+	cl_assert(!git_repository_is_bare(_repo));
+	cl_assert(git_repository_is_empty(_repo));
+
+	/* Verify that the gitlink and worktree entries are relative */
+
+	/* Verify worktree */
+	assert_config_entry_value(_repo, "core.worktree", "../c_wd/");
+
+	/* Verify gitlink */
+	cl_git_pass(git_futils_readbuffer(&dot_git_content, "root/b/c_wd/.git"));
+	cl_assert_equal_s("gitdir: ../my_repository/", dot_git_content.ptr);
+
+	git_buf_free(&dot_git_content);
+	cleanup_repository("root");
+}
+
+#define CLEAR_FOR_CORE_FILEMODE(M) ((M) &= ~0177)
+
+static void assert_hooks_match(
+	const char *template_dir,
+	const char *repo_dir,
+	const char *hook_path,
+	bool core_filemode)
+{
+	git_buf expected = GIT_BUF_INIT;
+	git_buf actual = GIT_BUF_INIT;
+	struct stat expected_st, st;
+
+	cl_git_pass(git_buf_joinpath(&expected, template_dir, hook_path));
+	cl_git_pass(git_path_lstat(expected.ptr, &expected_st));
+
+	cl_git_pass(git_buf_joinpath(&actual, repo_dir, hook_path));
+	cl_git_pass(git_path_lstat(actual.ptr, &st));
+
+	cl_assert(expected_st.st_size == st.st_size);
+
+	if (GIT_MODE_TYPE(expected_st.st_mode) != GIT_FILEMODE_LINK) {
+		mode_t expected_mode =
+			GIT_MODE_TYPE(expected_st.st_mode) |
+			(GIT_PERMS_FOR_WRITE(expected_st.st_mode) & ~g_umask);
+
+		if (!core_filemode) {
+			CLEAR_FOR_CORE_FILEMODE(expected_mode);
+			CLEAR_FOR_CORE_FILEMODE(st.st_mode);
+		}
+
+		cl_assert_equal_i_fmt(expected_mode, st.st_mode, "%07o");
+	}
+
+	git_buf_free(&expected);
+	git_buf_free(&actual);
+}
+
+static void assert_mode_seems_okay(
+	const char *base, const char *path,
+	git_filemode_t expect_mode, bool expect_setgid, bool core_filemode)
+{
+	git_buf full = GIT_BUF_INIT;
+	struct stat st;
+
+	cl_git_pass(git_buf_joinpath(&full, base, path));
+	cl_git_pass(git_path_lstat(full.ptr, &st));
+	git_buf_free(&full);
+
+	if (!core_filemode) {
+		CLEAR_FOR_CORE_FILEMODE(expect_mode);
+		CLEAR_FOR_CORE_FILEMODE(st.st_mode);
+		expect_setgid = false;
+	}
+
+	if (S_ISGID != 0)
+		cl_assert_equal_b(expect_setgid, (st.st_mode & S_ISGID) != 0);
+
+	cl_assert_equal_b(
+		GIT_PERMS_IS_EXEC(expect_mode), GIT_PERMS_IS_EXEC(st.st_mode));
+
+	cl_assert_equal_i_fmt(
+		GIT_MODE_TYPE(expect_mode), GIT_MODE_TYPE(st.st_mode), "%07o");
+}
+
+static const char *template_sandbox(const char *name)
+{
+	git_buf hooks_path = GIT_BUF_INIT, link_path = GIT_BUF_INIT;
+	const char *path = cl_fixture(name);
+
+	cl_fixture_sandbox(name);
+
+	/* create a symlink from link.sample to update.sample if the filesystem
+	 * supports it.
+	 */
+
+	cl_git_pass(git_buf_joinpath(&hooks_path, name, "hooks"));
+	cl_git_pass(git_buf_joinpath(&link_path, hooks_path.ptr, "link.sample"));
+
+#ifdef GIT_WIN32
+	cl_git_mkfile(link_path.ptr, "#!/bin/sh\necho hello, world\n");
+#else
+	cl_must_pass(symlink("update.sample", link_path.ptr));
+#endif
+
+	git_buf_free(&link_path);
+	git_buf_free(&hooks_path);
+
+	return path;
+}
+
+void test_repo_init__extended_with_template(void)
+{
+	git_buf expected = GIT_BUF_INIT;
+	git_buf actual = GIT_BUF_INIT;
+	git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
+	int filemode;
+
+	cl_set_cleanup(&cleanup_repository, "templated.git");
+	template_sandbox("template");
+
+	opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_BARE |
+		GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE;
+	opts.template_path = "template";
+
+	cl_git_pass(git_repository_init_ext(&_repo, "templated.git", &opts));
+
+	cl_assert(git_repository_is_bare(_repo));
+
+	cl_assert(!git__suffixcmp(git_repository_path(_repo), "/templated.git/"));
+
+	cl_git_pass(git_futils_readbuffer(&expected, "template/description"));
+	cl_git_pass(git_futils_readbuffer(
+		&actual, "templated.git/description"));
+
+	cl_assert_equal_s(expected.ptr, actual.ptr);
+
+	git_buf_free(&expected);
+	git_buf_free(&actual);
+
+	filemode = cl_repo_get_bool(_repo, "core.filemode");
+
+	assert_hooks_match(
+		"template", git_repository_path(_repo),
+		"hooks/update.sample", filemode);
+
+	assert_hooks_match(
+		"template", git_repository_path(_repo),
+		"hooks/link.sample", filemode);
+
+	cl_fixture_cleanup("template");
+}
+
+void test_repo_init__extended_with_template_and_shared_mode(void)
+{
+	git_buf expected = GIT_BUF_INIT;
+	git_buf actual = GIT_BUF_INIT;
+	git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
+	int filemode = true;
+	const char *repo_path = NULL;
+
+	cl_set_cleanup(&cleanup_repository, "init_shared_from_tpl");
+	template_sandbox("template");
+
+	opts.flags = GIT_REPOSITORY_INIT_MKPATH |
+		GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE;
+	opts.template_path = "template";
+	opts.mode = GIT_REPOSITORY_INIT_SHARED_GROUP;
+
+	cl_git_pass(git_repository_init_ext(&_repo, "init_shared_from_tpl", &opts));
+
+	cl_assert(!git_repository_is_bare(_repo));
+	cl_assert(!git__suffixcmp(git_repository_path(_repo), "/init_shared_from_tpl/.git/"));
+
+	filemode = cl_repo_get_bool(_repo, "core.filemode");
+
+	cl_git_pass(git_futils_readbuffer(
+		&expected, "template/description"));
+	cl_git_pass(git_futils_readbuffer(
+		&actual, "init_shared_from_tpl/.git/description"));
+
+	cl_assert_equal_s(expected.ptr, actual.ptr);
+
+	git_buf_free(&expected);
+	git_buf_free(&actual);
+
+	repo_path = git_repository_path(_repo);
+	assert_mode_seems_okay(repo_path, "hooks",
+		GIT_FILEMODE_TREE | GIT_REPOSITORY_INIT_SHARED_GROUP, true, filemode);
+	assert_mode_seems_okay(repo_path, "info",
+		GIT_FILEMODE_TREE | GIT_REPOSITORY_INIT_SHARED_GROUP, true, filemode);
+	assert_mode_seems_okay(repo_path, "description",
+		GIT_FILEMODE_BLOB, false, filemode);
+
+	/* for a non-symlinked hook, it should have shared permissions now */
+	assert_hooks_match(
+		"template", git_repository_path(_repo),
+		"hooks/update.sample", filemode);
+
+	/* for a symlinked hook, the permissions still should match the
+	 * source link, not the GIT_REPOSITORY_INIT_SHARED_GROUP value
+	 */
+	assert_hooks_match(
+		"template", git_repository_path(_repo),
+		"hooks/link.sample", filemode);
+
+	cl_fixture_cleanup("template");
+}
+
+void test_repo_init__can_reinit_an_initialized_repository(void)
+{
+	git_repository *reinit;
+
+	cl_set_cleanup(&cleanup_repository, "extended");
+
+	cl_git_pass(git_futils_mkdir("extended", NULL, 0775, 0));
+	cl_git_pass(git_repository_init(&_repo, "extended", false));
+
+	cl_git_pass(git_repository_init(&reinit, "extended", false));
+
+	cl_assert_equal_s(git_repository_path(_repo), git_repository_path(reinit));
+
+	git_repository_free(reinit);
+}
+
+void test_repo_init__init_with_initial_commit(void)
+{
+	git_index *index;
+
+	cl_set_cleanup(&cleanup_repository, "committed");
+
+	/* Initialize the repository */
+	cl_git_pass(git_repository_init(&_repo, "committed", 0));
+
+	/* Init will be automatically created when requested for a new repo */
+	cl_git_pass(git_repository_index(&index, _repo));
+
+	/* Create a file so we can commit it
+	 *
+	 * If you are writing code outside the test suite, you can create this
+	 * file any way that you like, such as:
+	 *      FILE *fp = fopen("committed/file.txt", "w");
+	 *      fputs("some stuff\n", fp);
+	 *      fclose(fp);
+	 * We like to use the help functions because they do error detection
+	 * in a way that's easily compatible with our test suite.
+	 */
+	cl_git_mkfile("committed/file.txt", "some stuff\n");
+
+	/* Add file to the index */
+	cl_git_pass(git_index_add_bypath(index, "file.txt"));
+	cl_git_pass(git_index_write(index));
+
+	/* Intentionally not using cl_repo_commit_from_index here so this code
+	 * can be used as an example of how an initial commit is typically
+	 * made to a repository...
+	 */
+
+	/* Make sure we're ready to use git_signature_default :-) */
+	{
+		git_config *cfg, *local;
+		cl_git_pass(git_repository_config(&cfg, _repo));
+		cl_git_pass(git_config_open_level(&local, cfg, GIT_CONFIG_LEVEL_LOCAL));
+		cl_git_pass(git_config_set_string(local, "user.name", "Test User"));
+		cl_git_pass(git_config_set_string(local, "user.email", "t at example.com"));
+		git_config_free(local);
+		git_config_free(cfg);
+	}
+
+	/* Create a commit with the new contents of the index */
+	{
+		git_signature *sig;
+		git_oid tree_id, commit_id;
+		git_tree *tree;
+
+		cl_git_pass(git_signature_default(&sig, _repo));
+		cl_git_pass(git_index_write_tree(&tree_id, index));
+		cl_git_pass(git_tree_lookup(&tree, _repo, &tree_id));
+
+		cl_git_pass(git_commit_create_v(
+			&commit_id, _repo, "HEAD", sig, sig,
+			NULL, "First", tree, 0));
+
+		git_tree_free(tree);
+		git_signature_free(sig);
+	}
+
+	git_index_free(index);
+}
+
+void test_repo_init__at_filesystem_root(void)
+{
+	git_repository *repo;
+	const char *sandbox = clar_sandbox_path();
+	git_buf root = GIT_BUF_INIT;
+	int root_len;
+
+	if (!cl_getenv("GITTEST_INVASIVE_FS_STRUCTURE"))
+		cl_skip();
+
+	root_len = git_path_root(sandbox);
+	cl_assert(root_len >= 0);
+
+	git_buf_put(&root, sandbox, root_len+1);
+	git_buf_joinpath(&root, root.ptr, "libgit2_test_dir");
+
+	cl_assert(!git_path_exists(root.ptr));
+
+	cl_git_pass(git_repository_init(&repo, root.ptr, 0));
+	cl_assert(git_path_isdir(root.ptr));
+	cl_git_pass(git_futils_rmdir_r(root.ptr, NULL, GIT_RMDIR_REMOVE_FILES));
+
+	git_buf_free(&root);
+	git_repository_free(repo);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/iterator.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/iterator.c
new file mode 100755
index 0000000..bb2d3a1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/iterator.c
@@ -0,0 +1,991 @@
+#include "clar_libgit2.h"
+#include "iterator.h"
+#include "repository.h"
+#include "fileops.h"
+#include <stdarg.h>
+
+static git_repository *g_repo;
+
+void test_repo_iterator__initialize(void)
+{
+}
+
+void test_repo_iterator__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+	g_repo = NULL;
+}
+
+static void expect_iterator_items(
+	git_iterator *i,
+	int expected_flat,
+	const char **expected_flat_paths,
+	int expected_total,
+	const char **expected_total_paths)
+{
+	const git_index_entry *entry;
+	int count, error;
+	int no_trees = !(git_iterator_flags(i) & GIT_ITERATOR_INCLUDE_TREES);
+	bool v = false;
+
+	if (expected_flat < 0) { v = true; expected_flat = -expected_flat; }
+	if (expected_total < 0) { v = true; expected_total = -expected_total; }
+
+	if (v) fprintf(stderr, "== %s ==\n", no_trees ? "notrees" : "trees");
+
+	count = 0;
+
+	while (!git_iterator_advance(&entry, i)) {
+		if (v) fprintf(stderr, "  %s %07o\n", entry->path, (int)entry->mode);
+
+		if (no_trees)
+			cl_assert(entry->mode != GIT_FILEMODE_TREE);
+
+		if (expected_flat_paths) {
+			const char *expect_path = expected_flat_paths[count];
+			size_t expect_len = strlen(expect_path);
+
+			cl_assert_equal_s(expect_path, entry->path);
+
+			if (expect_path[expect_len - 1] == '/')
+				cl_assert_equal_i(GIT_FILEMODE_TREE, entry->mode);
+			else
+				cl_assert(entry->mode != GIT_FILEMODE_TREE);
+		}
+
+		if (++count > expected_flat)
+			break;
+	}
+
+	cl_assert_equal_i(expected_flat, count);
+
+	cl_git_pass(git_iterator_reset(i, NULL, NULL));
+
+	count = 0;
+	cl_git_pass(git_iterator_current(&entry, i));
+
+	if (v) fprintf(stderr, "-- %s --\n", no_trees ? "notrees" : "trees");
+
+	while (entry != NULL) {
+		if (v) fprintf(stderr, "  %s %07o\n", entry->path, (int)entry->mode);
+
+		if (no_trees)
+			cl_assert(entry->mode != GIT_FILEMODE_TREE);
+
+		if (expected_total_paths) {
+			const char *expect_path = expected_total_paths[count];
+			size_t expect_len = strlen(expect_path);
+
+			cl_assert_equal_s(expect_path, entry->path);
+
+			if (expect_path[expect_len - 1] == '/')
+				cl_assert_equal_i(GIT_FILEMODE_TREE, entry->mode);
+			else
+				cl_assert(entry->mode != GIT_FILEMODE_TREE);
+		}
+
+		if (entry->mode == GIT_FILEMODE_TREE) {
+			error = git_iterator_advance_into(&entry, i);
+
+			/* could return NOTFOUND if directory is empty */
+			cl_assert(!error || error == GIT_ENOTFOUND);
+
+			if (error == GIT_ENOTFOUND) {
+				error = git_iterator_advance(&entry, i);
+				cl_assert(!error || error == GIT_ITEROVER);
+			}
+		} else {
+			error = git_iterator_advance(&entry, i);
+			cl_assert(!error || error == GIT_ITEROVER);
+		}
+
+		if (++count > expected_total)
+			break;
+	}
+
+	cl_assert_equal_i(expected_total, count);
+}
+
+/* Index contents (including pseudotrees):
+ *
+ * 0: a     5: F     10: k/      16: L/
+ * 1: B     6: g     11: k/1     17: L/1
+ * 2: c     7: H     12: k/a     18: L/a
+ * 3: D     8: i     13: k/B     19: L/B
+ * 4: e     9: J     14: k/c     20: L/c
+ *                   15: k/D     21: L/D
+ *
+ * 0: B     5: L/    11: a       16: k/
+ * 1: D     6: L/1   12: c       17: k/1
+ * 2: F     7: L/B   13: e       18: k/B
+ * 3: H     8: L/D   14: g       19: k/D
+ * 4: J     9: L/a   15: i       20: k/a
+ *         10: L/c               21: k/c
+ */
+
+void test_repo_iterator__index(void)
+{
+	git_iterator *i;
+	git_index *index;
+
+	g_repo = cl_git_sandbox_init("icase");
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	/* autoexpand with no tree entries for index */
+	cl_git_pass(git_iterator_for_index(&i, index, 0, NULL, NULL));
+	expect_iterator_items(i, 20, NULL, 20, NULL);
+	git_iterator_free(i);
+
+	/* auto expand with tree entries */
+	cl_git_pass(git_iterator_for_index(
+		&i, index, GIT_ITERATOR_INCLUDE_TREES, NULL, NULL));
+	expect_iterator_items(i, 22, NULL, 22, NULL);
+	git_iterator_free(i);
+
+	/* no auto expand (implies trees included) */
+	cl_git_pass(git_iterator_for_index(
+		&i, index, GIT_ITERATOR_DONT_AUTOEXPAND, NULL, NULL));
+	expect_iterator_items(i, 12, NULL, 22, NULL);
+	git_iterator_free(i);
+
+	git_index_free(index);
+}
+
+void test_repo_iterator__index_icase(void)
+{
+	git_iterator *i;
+	git_index *index;
+	int caps;
+
+	g_repo = cl_git_sandbox_init("icase");
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	caps = git_index_caps(index);
+
+	/* force case sensitivity */
+	cl_git_pass(git_index_set_caps(index, caps & ~GIT_INDEXCAP_IGNORE_CASE));
+
+	/* autoexpand with no tree entries over range */
+	cl_git_pass(git_iterator_for_index(&i, index, 0, "c", "k/D"));
+	expect_iterator_items(i, 7, NULL, 7, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_index(&i, index, 0, "k", "k/Z"));
+	expect_iterator_items(i, 3, NULL, 3, NULL);
+	git_iterator_free(i);
+
+	/* auto expand with tree entries */
+	cl_git_pass(git_iterator_for_index(
+		&i, index, GIT_ITERATOR_INCLUDE_TREES, "c", "k/D"));
+	expect_iterator_items(i, 8, NULL, 8, NULL);
+	git_iterator_free(i);
+	cl_git_pass(git_iterator_for_index(
+		&i, index, GIT_ITERATOR_INCLUDE_TREES, "k", "k/Z"));
+	expect_iterator_items(i, 4, NULL, 4, NULL);
+	git_iterator_free(i);
+
+	/* no auto expand (implies trees included) */
+	cl_git_pass(git_iterator_for_index(
+		&i, index, GIT_ITERATOR_DONT_AUTOEXPAND, "c", "k/D"));
+	expect_iterator_items(i, 5, NULL, 8, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_index(
+		&i, index, GIT_ITERATOR_DONT_AUTOEXPAND, "k", "k/Z"));
+	expect_iterator_items(i, 1, NULL, 4, NULL);
+	git_iterator_free(i);
+
+	/* force case insensitivity */
+	cl_git_pass(git_index_set_caps(index, caps | GIT_INDEXCAP_IGNORE_CASE));
+
+	/* autoexpand with no tree entries over range */
+	cl_git_pass(git_iterator_for_index(&i, index, 0, "c", "k/D"));
+	expect_iterator_items(i, 13, NULL, 13, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_index(&i, index, 0, "k", "k/Z"));
+	expect_iterator_items(i, 5, NULL, 5, NULL);
+	git_iterator_free(i);
+
+	/* auto expand with tree entries */
+	cl_git_pass(git_iterator_for_index(
+		&i, index, GIT_ITERATOR_INCLUDE_TREES, "c", "k/D"));
+	expect_iterator_items(i, 14, NULL, 14, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_index(
+		&i, index, GIT_ITERATOR_INCLUDE_TREES, "k", "k/Z"));
+	expect_iterator_items(i, 6, NULL, 6, NULL);
+	git_iterator_free(i);
+
+	/* no auto expand (implies trees included) */
+	cl_git_pass(git_iterator_for_index(
+		&i, index, GIT_ITERATOR_DONT_AUTOEXPAND, "c", "k/D"));
+	expect_iterator_items(i, 9, NULL, 14, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_index(
+		&i, index, GIT_ITERATOR_DONT_AUTOEXPAND, "k", "k/Z"));
+	expect_iterator_items(i, 1, NULL, 6, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_index_set_caps(index, caps));
+	git_index_free(index);
+}
+
+void test_repo_iterator__tree(void)
+{
+	git_iterator *i;
+	git_tree *head;
+
+	g_repo = cl_git_sandbox_init("icase");
+
+	cl_git_pass(git_repository_head_tree(&head, g_repo));
+
+	/* auto expand with no tree entries */
+	cl_git_pass(git_iterator_for_tree(&i, head, 0, NULL, NULL));
+	expect_iterator_items(i, 20, NULL, 20, NULL);
+	git_iterator_free(i);
+
+	/* auto expand with tree entries */
+	cl_git_pass(git_iterator_for_tree(
+		&i, head, GIT_ITERATOR_INCLUDE_TREES, NULL, NULL));
+	expect_iterator_items(i, 22, NULL, 22, NULL);
+	git_iterator_free(i);
+
+	/* no auto expand (implies trees included) */
+	cl_git_pass(git_iterator_for_tree(
+		&i, head, GIT_ITERATOR_DONT_AUTOEXPAND, NULL, NULL));
+	expect_iterator_items(i, 12, NULL, 22, NULL);
+	git_iterator_free(i);
+
+	git_tree_free(head);
+}
+
+void test_repo_iterator__tree_icase(void)
+{
+	git_iterator *i;
+	git_tree *head;
+	git_iterator_flag_t flag;
+
+	g_repo = cl_git_sandbox_init("icase");
+
+	cl_git_pass(git_repository_head_tree(&head, g_repo));
+
+	flag = GIT_ITERATOR_DONT_IGNORE_CASE;
+
+	/* auto expand with no tree entries */
+	cl_git_pass(git_iterator_for_tree(&i, head, flag, "c", "k/D"));
+	expect_iterator_items(i, 7, NULL, 7, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_tree(&i, head, flag, "k", "k/Z"));
+	expect_iterator_items(i, 3, NULL, 3, NULL);
+	git_iterator_free(i);
+
+	/* auto expand with tree entries */
+	cl_git_pass(git_iterator_for_tree(
+		&i, head, flag | GIT_ITERATOR_INCLUDE_TREES, "c", "k/D"));
+	expect_iterator_items(i, 8, NULL, 8, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, head, flag | GIT_ITERATOR_INCLUDE_TREES, "k", "k/Z"));
+	expect_iterator_items(i, 4, NULL, 4, NULL);
+	git_iterator_free(i);
+
+	/* no auto expand (implies trees included) */
+	cl_git_pass(git_iterator_for_tree(
+		&i, head, flag | GIT_ITERATOR_DONT_AUTOEXPAND, "c", "k/D"));
+	expect_iterator_items(i, 5, NULL, 8, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, head, flag | GIT_ITERATOR_DONT_AUTOEXPAND, "k", "k/Z"));
+	expect_iterator_items(i, 1, NULL, 4, NULL);
+	git_iterator_free(i);
+
+	flag = GIT_ITERATOR_IGNORE_CASE;
+
+	/* auto expand with no tree entries */
+	cl_git_pass(git_iterator_for_tree(&i, head, flag, "c", "k/D"));
+	expect_iterator_items(i, 13, NULL, 13, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_tree(&i, head, flag, "k", "k/Z"));
+	expect_iterator_items(i, 5, NULL, 5, NULL);
+	git_iterator_free(i);
+
+	/* auto expand with tree entries */
+	cl_git_pass(git_iterator_for_tree(
+		&i, head, flag | GIT_ITERATOR_INCLUDE_TREES, "c", "k/D"));
+	expect_iterator_items(i, 14, NULL, 14, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, head, flag | GIT_ITERATOR_INCLUDE_TREES, "k", "k/Z"));
+	expect_iterator_items(i, 6, NULL, 6, NULL);
+	git_iterator_free(i);
+
+	/* no auto expand (implies trees included) */
+	cl_git_pass(git_iterator_for_tree(
+		&i, head, flag | GIT_ITERATOR_DONT_AUTOEXPAND, "c", "k/D"));
+	expect_iterator_items(i, 9, NULL, 14, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, head, flag | GIT_ITERATOR_DONT_AUTOEXPAND, "k", "k/Z"));
+	expect_iterator_items(i, 1, NULL, 6, NULL);
+	git_iterator_free(i);
+
+	git_tree_free(head);
+}
+
+void test_repo_iterator__tree_more(void)
+{
+	git_iterator *i;
+	git_tree *head;
+	static const char *expect_basic[] = {
+		"current_file",
+		"file_deleted",
+		"modified_file",
+		"staged_changes",
+		"staged_changes_file_deleted",
+		"staged_changes_modified_file",
+		"staged_delete_file_deleted",
+		"staged_delete_modified_file",
+		"subdir.txt",
+		"subdir/current_file",
+		"subdir/deleted_file",
+		"subdir/modified_file",
+		NULL,
+	};
+	static const char *expect_trees[] = {
+		"current_file",
+		"file_deleted",
+		"modified_file",
+		"staged_changes",
+		"staged_changes_file_deleted",
+		"staged_changes_modified_file",
+		"staged_delete_file_deleted",
+		"staged_delete_modified_file",
+		"subdir.txt",
+		"subdir/",
+		"subdir/current_file",
+		"subdir/deleted_file",
+		"subdir/modified_file",
+		NULL,
+	};
+	static const char *expect_noauto[] = {
+		"current_file",
+		"file_deleted",
+		"modified_file",
+		"staged_changes",
+		"staged_changes_file_deleted",
+		"staged_changes_modified_file",
+		"staged_delete_file_deleted",
+		"staged_delete_modified_file",
+		"subdir.txt",
+		"subdir/",
+		NULL
+	};
+
+	g_repo = cl_git_sandbox_init("status");
+
+	cl_git_pass(git_repository_head_tree(&head, g_repo));
+
+	/* auto expand with no tree entries */
+	cl_git_pass(git_iterator_for_tree(&i, head, 0, NULL, NULL));
+	expect_iterator_items(i, 12, expect_basic, 12, expect_basic);
+	git_iterator_free(i);
+
+	/* auto expand with tree entries */
+	cl_git_pass(git_iterator_for_tree(
+		&i, head, GIT_ITERATOR_INCLUDE_TREES, NULL, NULL));
+	expect_iterator_items(i, 13, expect_trees, 13, expect_trees);
+	git_iterator_free(i);
+
+	/* no auto expand (implies trees included) */
+	cl_git_pass(git_iterator_for_tree(
+		&i, head, GIT_ITERATOR_DONT_AUTOEXPAND, NULL, NULL));
+	expect_iterator_items(i, 10, expect_noauto, 13, expect_trees);
+	git_iterator_free(i);
+
+	git_tree_free(head);
+}
+
+/* "b=name,t=name", blob_id, tree_id */
+static void build_test_tree(
+	git_oid *out, git_repository *repo, const char *fmt, ...)
+{
+	git_oid *id;
+	git_treebuilder *builder;
+	const char *scan = fmt, *next;
+	char type, delimiter;
+	git_filemode_t mode = GIT_FILEMODE_BLOB;
+	git_buf name = GIT_BUF_INIT;
+	va_list arglist;
+
+	cl_git_pass(git_treebuilder_new(&builder, repo, NULL)); /* start builder */
+
+	va_start(arglist, fmt);
+	while (*scan) {
+		switch (type = *scan++) {
+		case 't': case 'T': mode = GIT_FILEMODE_TREE; break;
+		case 'b': case 'B': mode = GIT_FILEMODE_BLOB; break;
+		default:
+			cl_assert(type == 't' || type == 'T' || type == 'b' || type == 'B');
+		}
+
+		delimiter = *scan++; /* read and skip delimiter */
+		for (next = scan; *next && *next != delimiter; ++next)
+			/* seek end */;
+		cl_git_pass(git_buf_set(&name, scan, (size_t)(next - scan)));
+		for (scan = next; *scan && (*scan == delimiter || *scan == ','); ++scan)
+			/* skip delimiter and optional comma */;
+
+		id = va_arg(arglist, git_oid *);
+
+		cl_git_pass(git_treebuilder_insert(NULL, builder, name.ptr, id, mode));
+	}
+	va_end(arglist);
+
+	cl_git_pass(git_treebuilder_write(out, builder));
+
+	git_treebuilder_free(builder);
+	git_buf_free(&name);
+}
+
+void test_repo_iterator__tree_case_conflicts_0(void)
+{
+	const char *blob_sha = "d44e18fb93b7107b5cd1b95d601591d77869a1b6";
+	git_tree *tree;
+	git_oid blob_id, biga_id, littlea_id, tree_id;
+	git_iterator *i;
+	const char *expect_cs[] = {
+		"A/1.file", "A/3.file", "a/2.file", "a/4.file" };
+	const char *expect_ci[] = {
+		"A/1.file", "a/2.file", "A/3.file", "a/4.file" };
+	const char *expect_cs_trees[] = {
+		"A/", "A/1.file", "A/3.file", "a/", "a/2.file", "a/4.file" };
+	const char *expect_ci_trees[] = {
+		"A/", "A/1.file", "a/2.file", "A/3.file", "a/4.file" };
+
+	g_repo = cl_git_sandbox_init("icase");
+
+	cl_git_pass(git_oid_fromstr(&blob_id, blob_sha)); /* lookup blob */
+
+	/* create tree with: A/1.file, A/3.file, a/2.file, a/4.file */
+	build_test_tree(
+		&biga_id, g_repo, "b|1.file|,b|3.file|", &blob_id, &blob_id);
+	build_test_tree(
+		&littlea_id, g_repo, "b|2.file|,b|4.file|", &blob_id, &blob_id);
+	build_test_tree(
+		&tree_id, g_repo, "t|A|,t|a|", &biga_id, &littlea_id);
+
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL));
+	expect_iterator_items(i, 4, expect_cs, 4, expect_cs);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, tree, GIT_ITERATOR_IGNORE_CASE, NULL, NULL));
+	expect_iterator_items(i, 4, expect_ci, 4, expect_ci);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, tree, GIT_ITERATOR_DONT_IGNORE_CASE |
+		GIT_ITERATOR_INCLUDE_TREES, NULL, NULL));
+	expect_iterator_items(i, 6, expect_cs_trees, 6, expect_cs_trees);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, tree, GIT_ITERATOR_IGNORE_CASE |
+		GIT_ITERATOR_INCLUDE_TREES, NULL, NULL));
+	expect_iterator_items(i, 5, expect_ci_trees, 5, expect_ci_trees);
+	git_iterator_free(i);
+
+	git_tree_free(tree);
+}
+
+void test_repo_iterator__tree_case_conflicts_1(void)
+{
+	const char *blob_sha = "d44e18fb93b7107b5cd1b95d601591d77869a1b6";
+	git_tree *tree;
+	git_oid blob_id, Ab_id, biga_id, littlea_id, tree_id;
+	git_iterator *i;
+	const char *expect_cs[] = {
+		"A/a", "A/b/1", "A/c", "a/C", "a/a", "a/b" };
+	const char *expect_ci[] = {
+		"A/a", "a/b", "A/b/1", "A/c" };
+	const char *expect_cs_trees[] = {
+		"A/", "A/a", "A/b/", "A/b/1", "A/c", "a/", "a/C", "a/a", "a/b" };
+	const char *expect_ci_trees[] = {
+		"A/", "A/a", "a/b", "A/b/", "A/b/1", "A/c" };
+
+	g_repo = cl_git_sandbox_init("icase");
+
+	cl_git_pass(git_oid_fromstr(&blob_id, blob_sha)); /* lookup blob */
+
+	/* create: A/a A/b/1 A/c a/a a/b a/C */
+	build_test_tree(&Ab_id, g_repo, "b|1|", &blob_id);
+	build_test_tree(
+		&biga_id, g_repo, "b|a|,t|b|,b|c|", &blob_id, &Ab_id, &blob_id);
+	build_test_tree(
+		&littlea_id, g_repo, "b|a|,b|b|,b|C|", &blob_id, &blob_id, &blob_id);
+	build_test_tree(
+		&tree_id, g_repo, "t|A|,t|a|", &biga_id, &littlea_id);
+
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL));
+	expect_iterator_items(i, 6, expect_cs, 6, expect_cs);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, tree, GIT_ITERATOR_IGNORE_CASE, NULL, NULL));
+	expect_iterator_items(i, 4, expect_ci, 4, expect_ci);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, tree, GIT_ITERATOR_DONT_IGNORE_CASE |
+		GIT_ITERATOR_INCLUDE_TREES, NULL, NULL));
+	expect_iterator_items(i, 9, expect_cs_trees, 9, expect_cs_trees);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, tree, GIT_ITERATOR_IGNORE_CASE |
+		GIT_ITERATOR_INCLUDE_TREES, NULL, NULL));
+	expect_iterator_items(i, 6, expect_ci_trees, 6, expect_ci_trees);
+	git_iterator_free(i);
+
+	git_tree_free(tree);
+}
+
+void test_repo_iterator__tree_case_conflicts_2(void)
+{
+	const char *blob_sha = "d44e18fb93b7107b5cd1b95d601591d77869a1b6";
+	git_tree *tree;
+	git_oid blob_id, d1, d2, c1, c2, b1, b2, a1, a2, tree_id;
+	git_iterator *i;
+	const char *expect_cs[] = {
+		"A/B/C/D/16", "A/B/C/D/foo", "A/B/C/d/15",  "A/B/C/d/FOO",
+		"A/B/c/D/14", "A/B/c/D/foo", "A/B/c/d/13",  "A/B/c/d/FOO",
+		"A/b/C/D/12", "A/b/C/D/foo", "A/b/C/d/11",  "A/b/C/d/FOO",
+		"A/b/c/D/10", "A/b/c/D/foo", "A/b/c/d/09",  "A/b/c/d/FOO",
+		"a/B/C/D/08", "a/B/C/D/foo", "a/B/C/d/07", "a/B/C/d/FOO",
+		"a/B/c/D/06", "a/B/c/D/foo", "a/B/c/d/05", "a/B/c/d/FOO",
+		"a/b/C/D/04", "a/b/C/D/foo", "a/b/C/d/03", "a/b/C/d/FOO",
+		"a/b/c/D/02", "a/b/c/D/foo", "a/b/c/d/01", "a/b/c/d/FOO", };
+	const char *expect_ci[] = {
+		"a/b/c/d/01", "a/b/c/D/02", "a/b/C/d/03", "a/b/C/D/04",
+		"a/B/c/d/05", "a/B/c/D/06", "a/B/C/d/07", "a/B/C/D/08",
+		"A/b/c/d/09", "A/b/c/D/10", "A/b/C/d/11", "A/b/C/D/12",
+		"A/B/c/d/13", "A/B/c/D/14", "A/B/C/d/15", "A/B/C/D/16",
+		"A/B/C/D/foo", };
+	const char *expect_ci_trees[] = {
+		"A/", "A/B/", "A/B/C/", "A/B/C/D/",
+		"a/b/c/d/01", "a/b/c/D/02", "a/b/C/d/03", "a/b/C/D/04",
+		"a/B/c/d/05", "a/B/c/D/06", "a/B/C/d/07", "a/B/C/D/08",
+		"A/b/c/d/09", "A/b/c/D/10", "A/b/C/d/11", "A/b/C/D/12",
+		"A/B/c/d/13", "A/B/c/D/14", "A/B/C/d/15", "A/B/C/D/16",
+		"A/B/C/D/foo", };
+
+	g_repo = cl_git_sandbox_init("icase");
+
+	cl_git_pass(git_oid_fromstr(&blob_id, blob_sha)); /* lookup blob */
+
+	build_test_tree(&d1, g_repo, "b|16|,b|foo|", &blob_id, &blob_id);
+	build_test_tree(&d2, g_repo, "b|15|,b|FOO|", &blob_id, &blob_id);
+	build_test_tree(&c1, g_repo, "t|D|,t|d|", &d1, &d2);
+	build_test_tree(&d1, g_repo, "b|14|,b|foo|", &blob_id, &blob_id);
+	build_test_tree(&d2, g_repo, "b|13|,b|FOO|", &blob_id, &blob_id);
+	build_test_tree(&c2, g_repo, "t|D|,t|d|", &d1, &d2);
+	build_test_tree(&b1, g_repo, "t|C|,t|c|", &c1, &c2);
+
+	build_test_tree(&d1, g_repo, "b|12|,b|foo|", &blob_id, &blob_id);
+	build_test_tree(&d2, g_repo, "b|11|,b|FOO|", &blob_id, &blob_id);
+	build_test_tree(&c1, g_repo, "t|D|,t|d|", &d1, &d2);
+	build_test_tree(&d1, g_repo, "b|10|,b|foo|", &blob_id, &blob_id);
+	build_test_tree(&d2, g_repo, "b|09|,b|FOO|", &blob_id, &blob_id);
+	build_test_tree(&c2, g_repo, "t|D|,t|d|", &d1, &d2);
+	build_test_tree(&b2, g_repo, "t|C|,t|c|", &c1, &c2);
+
+	build_test_tree(&a1, g_repo, "t|B|,t|b|", &b1, &b2);
+
+	build_test_tree(&d1, g_repo, "b|08|,b|foo|", &blob_id, &blob_id);
+	build_test_tree(&d2, g_repo, "b|07|,b|FOO|", &blob_id, &blob_id);
+	build_test_tree(&c1, g_repo, "t|D|,t|d|", &d1, &d2);
+	build_test_tree(&d1, g_repo, "b|06|,b|foo|", &blob_id, &blob_id);
+	build_test_tree(&d2, g_repo, "b|05|,b|FOO|", &blob_id, &blob_id);
+	build_test_tree(&c2, g_repo, "t|D|,t|d|", &d1, &d2);
+	build_test_tree(&b1, g_repo, "t|C|,t|c|", &c1, &c2);
+
+	build_test_tree(&d1, g_repo, "b|04|,b|foo|", &blob_id, &blob_id);
+	build_test_tree(&d2, g_repo, "b|03|,b|FOO|", &blob_id, &blob_id);
+	build_test_tree(&c1, g_repo, "t|D|,t|d|", &d1, &d2);
+	build_test_tree(&d1, g_repo, "b|02|,b|foo|", &blob_id, &blob_id);
+	build_test_tree(&d2, g_repo, "b|01|,b|FOO|", &blob_id, &blob_id);
+	build_test_tree(&c2, g_repo, "t|D|,t|d|", &d1, &d2);
+	build_test_tree(&b2, g_repo, "t|C|,t|c|", &c1, &c2);
+
+	build_test_tree(&a2, g_repo, "t|B|,t|b|", &b1, &b2);
+
+	build_test_tree(&tree_id, g_repo, "t/A/,t/a/", &a1, &a2);
+
+	cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL));
+	expect_iterator_items(i, 32, expect_cs, 32, expect_cs);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, tree, GIT_ITERATOR_IGNORE_CASE, NULL, NULL));
+	expect_iterator_items(i, 17, expect_ci, 17, expect_ci);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_tree(
+		&i, tree, GIT_ITERATOR_IGNORE_CASE |
+		GIT_ITERATOR_INCLUDE_TREES, NULL, NULL));
+	expect_iterator_items(i, 21, expect_ci_trees, 21, expect_ci_trees);
+	git_iterator_free(i);
+
+	git_tree_free(tree);
+}
+
+void test_repo_iterator__workdir(void)
+{
+	git_iterator *i;
+
+	g_repo = cl_git_sandbox_init("icase");
+
+	/* auto expand with no tree entries */
+	cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, 0, NULL, NULL));
+	expect_iterator_items(i, 20, NULL, 20, NULL);
+	git_iterator_free(i);
+
+	/* auto expand with tree entries */
+	cl_git_pass(git_iterator_for_workdir(
+		&i, g_repo, NULL, NULL, GIT_ITERATOR_INCLUDE_TREES, NULL, NULL));
+	expect_iterator_items(i, 22, NULL, 22, NULL);
+	git_iterator_free(i);
+
+	/* no auto expand (implies trees included) */
+	cl_git_pass(git_iterator_for_workdir(
+		&i, g_repo, NULL, NULL, GIT_ITERATOR_DONT_AUTOEXPAND, NULL, NULL));
+	expect_iterator_items(i, 12, NULL, 22, NULL);
+	git_iterator_free(i);
+}
+
+void test_repo_iterator__workdir_icase(void)
+{
+	git_iterator *i;
+	git_iterator_flag_t flag;
+
+	g_repo = cl_git_sandbox_init("icase");
+
+	flag = GIT_ITERATOR_DONT_IGNORE_CASE;
+
+	/* auto expand with no tree entries */
+	cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, flag, "c", "k/D"));
+	expect_iterator_items(i, 7, NULL, 7, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, flag, "k", "k/Z"));
+	expect_iterator_items(i, 3, NULL, 3, NULL);
+	git_iterator_free(i);
+
+	/* auto expand with tree entries */
+	cl_git_pass(git_iterator_for_workdir(
+		&i, g_repo, NULL, NULL, flag | GIT_ITERATOR_INCLUDE_TREES, "c", "k/D"));
+	expect_iterator_items(i, 8, NULL, 8, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_workdir(
+		&i, g_repo, NULL, NULL, flag | GIT_ITERATOR_INCLUDE_TREES, "k", "k/Z"));
+	expect_iterator_items(i, 4, NULL, 4, NULL);
+	git_iterator_free(i);
+
+	/* no auto expand (implies trees included) */
+	cl_git_pass(git_iterator_for_workdir(
+		&i, g_repo, NULL, NULL, flag | GIT_ITERATOR_DONT_AUTOEXPAND, "c", "k/D"));
+	expect_iterator_items(i, 5, NULL, 8, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_workdir(
+		&i, g_repo, NULL, NULL, flag | GIT_ITERATOR_DONT_AUTOEXPAND, "k", "k/Z"));
+	expect_iterator_items(i, 1, NULL, 4, NULL);
+	git_iterator_free(i);
+
+	flag = GIT_ITERATOR_IGNORE_CASE;
+
+	/* auto expand with no tree entries */
+	cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, flag, "c", "k/D"));
+	expect_iterator_items(i, 13, NULL, 13, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_workdir(&i, g_repo, NULL, NULL, flag, "k", "k/Z"));
+	expect_iterator_items(i, 5, NULL, 5, NULL);
+	git_iterator_free(i);
+
+	/* auto expand with tree entries */
+	cl_git_pass(git_iterator_for_workdir(
+		&i, g_repo, NULL, NULL, flag | GIT_ITERATOR_INCLUDE_TREES, "c", "k/D"));
+	expect_iterator_items(i, 14, NULL, 14, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_workdir(
+		&i, g_repo, NULL, NULL, flag | GIT_ITERATOR_INCLUDE_TREES, "k", "k/Z"));
+	expect_iterator_items(i, 6, NULL, 6, NULL);
+	git_iterator_free(i);
+
+	/* no auto expand (implies trees included) */
+	cl_git_pass(git_iterator_for_workdir(
+		&i, g_repo, NULL, NULL, flag | GIT_ITERATOR_DONT_AUTOEXPAND, "c", "k/D"));
+	expect_iterator_items(i, 9, NULL, 14, NULL);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_workdir(
+		&i, g_repo, NULL, NULL, flag | GIT_ITERATOR_DONT_AUTOEXPAND, "k", "k/Z"));
+	expect_iterator_items(i, 1, NULL, 6, NULL);
+	git_iterator_free(i);
+}
+
+static void build_workdir_tree(const char *root, int dirs, int subs)
+{
+	int i, j;
+	char buf[64], sub[64];
+
+	for (i = 0; i < dirs; ++i) {
+		if (i % 2 == 0) {
+			p_snprintf(buf, sizeof(buf), "%s/dir%02d", root, i);
+			cl_git_pass(git_futils_mkdir(buf, NULL, 0775, GIT_MKDIR_PATH));
+
+			p_snprintf(buf, sizeof(buf), "%s/dir%02d/file", root, i);
+			cl_git_mkfile(buf, buf);
+			buf[strlen(buf) - 5] = '\0';
+		} else {
+			p_snprintf(buf, sizeof(buf), "%s/DIR%02d", root, i);
+			cl_git_pass(git_futils_mkdir(buf, NULL, 0775, GIT_MKDIR_PATH));
+		}
+
+		for (j = 0; j < subs; ++j) {
+			switch (j % 4) {
+			case 0: p_snprintf(sub, sizeof(sub), "%s/sub%02d", buf, j); break;
+			case 1: p_snprintf(sub, sizeof(sub), "%s/sUB%02d", buf, j); break;
+			case 2: p_snprintf(sub, sizeof(sub), "%s/Sub%02d", buf, j); break;
+			case 3: p_snprintf(sub, sizeof(sub), "%s/SUB%02d", buf, j); break;
+			}
+			cl_git_pass(git_futils_mkdir(sub, NULL, 0775, GIT_MKDIR_PATH));
+
+			if (j % 2 == 0) {
+				size_t sublen = strlen(sub);
+				memcpy(&sub[sublen], "/file", sizeof("/file"));
+				cl_git_mkfile(sub, sub);
+				sub[sublen] = '\0';
+			}
+		}
+	}
+}
+
+void test_repo_iterator__workdir_depth(void)
+{
+	git_iterator *iter;
+
+	g_repo = cl_git_sandbox_init("icase");
+
+	build_workdir_tree("icase", 10, 10);
+	build_workdir_tree("icase/DIR01/sUB01", 50, 0);
+	build_workdir_tree("icase/dir02/sUB01", 50, 0);
+
+	/* auto expand with no tree entries */
+	cl_git_pass(git_iterator_for_workdir(&iter, g_repo, NULL, NULL, 0, NULL, NULL));
+	expect_iterator_items(iter, 125, NULL, 125, NULL);
+	git_iterator_free(iter);
+
+	/* auto expand with tree entries (empty dirs silently skipped) */
+	cl_git_pass(git_iterator_for_workdir(
+		&iter, g_repo, NULL, NULL, GIT_ITERATOR_INCLUDE_TREES, NULL, NULL));
+	expect_iterator_items(iter, 337, NULL, 337, NULL);
+	git_iterator_free(iter);
+}
+
+void test_repo_iterator__fs(void)
+{
+	git_iterator *i;
+	static const char *expect_base[] = {
+		"DIR01/Sub02/file",
+		"DIR01/sub00/file",
+		"current_file",
+		"dir00/Sub02/file",
+		"dir00/file",
+		"dir00/sub00/file",
+		"modified_file",
+		"new_file",
+		NULL,
+	};
+	static const char *expect_trees[] = {
+		"DIR01/",
+		"DIR01/SUB03/",
+		"DIR01/Sub02/",
+		"DIR01/Sub02/file",
+		"DIR01/sUB01/",
+		"DIR01/sub00/",
+		"DIR01/sub00/file",
+		"current_file",
+		"dir00/",
+		"dir00/SUB03/",
+		"dir00/Sub02/",
+		"dir00/Sub02/file",
+		"dir00/file",
+		"dir00/sUB01/",
+		"dir00/sub00/",
+		"dir00/sub00/file",
+		"modified_file",
+		"new_file",
+		NULL,
+	};
+	static const char *expect_noauto[] = {
+		"DIR01/",
+		"current_file",
+		"dir00/",
+		"modified_file",
+		"new_file",
+		NULL,
+	};
+
+	g_repo = cl_git_sandbox_init("status");
+
+	build_workdir_tree("status/subdir", 2, 4);
+
+	cl_git_pass(git_iterator_for_filesystem(
+		&i, "status/subdir", 0, NULL, NULL));
+	expect_iterator_items(i, 8, expect_base, 8, expect_base);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_filesystem(
+		&i, "status/subdir", GIT_ITERATOR_INCLUDE_TREES, NULL, NULL));
+	expect_iterator_items(i, 18, expect_trees, 18, expect_trees);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_filesystem(
+		&i, "status/subdir", GIT_ITERATOR_DONT_AUTOEXPAND, NULL, NULL));
+	expect_iterator_items(i, 5, expect_noauto, 18, expect_trees);
+	git_iterator_free(i);
+
+	git__tsort((void **)expect_base, 8, (git__tsort_cmp)git__strcasecmp);
+	git__tsort((void **)expect_trees, 18, (git__tsort_cmp)git__strcasecmp);
+	git__tsort((void **)expect_noauto, 5, (git__tsort_cmp)git__strcasecmp);
+
+	cl_git_pass(git_iterator_for_filesystem(
+		&i, "status/subdir", GIT_ITERATOR_IGNORE_CASE, NULL, NULL));
+	expect_iterator_items(i, 8, expect_base, 8, expect_base);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_filesystem(
+		&i, "status/subdir", GIT_ITERATOR_IGNORE_CASE |
+		GIT_ITERATOR_INCLUDE_TREES, NULL, NULL));
+	expect_iterator_items(i, 18, expect_trees, 18, expect_trees);
+	git_iterator_free(i);
+
+	cl_git_pass(git_iterator_for_filesystem(
+		&i, "status/subdir", GIT_ITERATOR_IGNORE_CASE |
+		GIT_ITERATOR_DONT_AUTOEXPAND, NULL, NULL));
+	expect_iterator_items(i, 5, expect_noauto, 18, expect_trees);
+	git_iterator_free(i);
+}
+
+void test_repo_iterator__fs2(void)
+{
+	git_iterator *i;
+	static const char *expect_base[] = {
+		"heads/br2",
+		"heads/dir",
+		"heads/ident",
+		"heads/long-file-name",
+		"heads/master",
+		"heads/packed-test",
+		"heads/subtrees",
+		"heads/test",
+		"tags/e90810b",
+		"tags/foo/bar",
+		"tags/foo/foo/bar",
+		"tags/point_to_blob",
+		"tags/test",
+		NULL,
+	};
+
+	g_repo = cl_git_sandbox_init("testrepo");
+
+	cl_git_pass(git_iterator_for_filesystem(
+		&i, "testrepo/.git/refs", 0, NULL, NULL));
+	expect_iterator_items(i, 13, expect_base, 13, expect_base);
+	git_iterator_free(i);
+}
+
+void test_repo_iterator__unreadable_dir(void)
+{
+	git_iterator *i;
+	const git_index_entry *e;
+
+	if (!cl_is_chmod_supported())
+		return;
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+	cl_must_pass(p_mkdir("empty_standard_repo/r", 0777));
+	cl_git_mkfile("empty_standard_repo/r/a", "hello");
+	cl_must_pass(p_mkdir("empty_standard_repo/r/b", 0777));
+	cl_git_mkfile("empty_standard_repo/r/b/problem", "not me");
+	cl_must_pass(p_chmod("empty_standard_repo/r/b", 0000));
+	cl_must_pass(p_mkdir("empty_standard_repo/r/c", 0777));
+	cl_git_mkfile("empty_standard_repo/r/d", "final");
+
+	cl_git_pass(git_iterator_for_filesystem(
+		&i, "empty_standard_repo/r", 0, NULL, NULL));
+
+	cl_git_pass(git_iterator_advance(&e, i)); /* a */
+	cl_git_fail(git_iterator_advance(&e, i)); /* b */
+	cl_assert_equal_i(GIT_ITEROVER, git_iterator_advance(&e, i));
+
+	cl_must_pass(p_chmod("empty_standard_repo/r/b", 0777));
+
+	git_iterator_free(i);
+}
+
+void test_repo_iterator__skips_fifos_and_such(void)
+{
+#ifndef GIT_WIN32
+	git_iterator *i;
+	const git_index_entry *e;
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+	cl_must_pass(p_mkdir("empty_standard_repo/dir", 0777));
+	cl_git_mkfile("empty_standard_repo/file", "not me");
+
+	cl_assert(!mkfifo("empty_standard_repo/fifo", 0777));
+	cl_assert(!access("empty_standard_repo/fifo", F_OK));
+
+	cl_git_pass(git_iterator_for_filesystem(
+		&i, "empty_standard_repo", GIT_ITERATOR_INCLUDE_TREES |
+		GIT_ITERATOR_DONT_AUTOEXPAND, NULL, NULL));
+
+	cl_git_pass(git_iterator_advance(&e, i)); /* .git */
+	cl_assert(S_ISDIR(e->mode));
+	cl_git_pass(git_iterator_advance(&e, i)); /* dir */
+	cl_assert(S_ISDIR(e->mode));
+	/* skips fifo */
+	cl_git_pass(git_iterator_advance(&e, i)); /* file */
+	cl_assert(S_ISREG(e->mode));
+
+	cl_assert_equal_i(GIT_ITEROVER, git_iterator_advance(&e, i));
+
+	git_iterator_free(i);
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/message.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/message.c
new file mode 100755
index 0000000..8757459
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/message.c
@@ -0,0 +1,39 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "refs.h"
+#include "posix.h"
+
+static git_repository *_repo;
+
+void test_repo_message__initialize(void)
+{
+	_repo = cl_git_sandbox_init("testrepo.git");
+}
+
+void test_repo_message__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_repo_message__none(void)
+{
+	git_buf actual = GIT_BUF_INIT;
+	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_message(&actual, _repo));
+}
+
+void test_repo_message__message(void)
+{
+	git_buf path = GIT_BUF_INIT, actual = GIT_BUF_INIT;
+	const char expected[] = "Test\n\nThis is a test of the emergency broadcast system\n";
+
+	cl_git_pass(git_buf_joinpath(&path, git_repository_path(_repo), "MERGE_MSG"));
+	cl_git_mkfile(git_buf_cstr(&path), expected);
+
+	cl_git_pass(git_repository_message(&actual, _repo));
+	cl_assert_equal_s(expected, git_buf_cstr(&actual));
+	git_buf_free(&actual);
+
+	cl_git_pass(p_unlink(git_buf_cstr(&path)));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_message(&actual, _repo));
+	git_buf_free(&path);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/new.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/new.c
new file mode 100755
index 0000000..d77e903
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/new.c
@@ -0,0 +1,27 @@
+#include "clar_libgit2.h"
+#include "git2/sys/repository.h"
+
+void test_repo_new__has_nothing(void)
+{
+	git_repository *repo;
+
+	cl_git_pass(git_repository_new(&repo));
+	cl_assert_equal_b(true, git_repository_is_bare(repo));
+	cl_assert_equal_p(NULL, git_repository_path(repo));
+	cl_assert_equal_p(NULL, git_repository_workdir(repo));
+	git_repository_free(repo);
+}
+
+void test_repo_new__is_bare_until_workdir_set(void)
+{
+	git_repository *repo;
+
+	cl_git_pass(git_repository_new(&repo));
+	cl_assert_equal_b(true, git_repository_is_bare(repo));
+
+	cl_git_pass(git_repository_set_workdir(repo, clar_sandbox_path(), 0));
+	cl_assert_equal_b(false, git_repository_is_bare(repo));
+
+	git_repository_free(repo);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/open.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/open.c
new file mode 100755
index 0000000..eb459e5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/open.c
@@ -0,0 +1,396 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "sysdir.h"
+#include <ctype.h>
+
+void test_repo_open__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+
+	if (git_path_isdir("alternate"))
+		git_futils_rmdir_r("alternate", NULL, GIT_RMDIR_REMOVE_FILES);
+}
+
+void test_repo_open__bare_empty_repo(void)
+{
+	git_repository *repo = cl_git_sandbox_init("empty_bare.git");
+
+	cl_assert(git_repository_path(repo) != NULL);
+	cl_assert(git__suffixcmp(git_repository_path(repo), "/") == 0);
+	cl_assert(git_repository_workdir(repo) == NULL);
+}
+
+void test_repo_open__format_version_1(void)
+{
+	git_repository *repo;
+	git_config *config;
+
+	repo = cl_git_sandbox_init("empty_bare.git");
+
+	cl_git_pass(git_repository_open(&repo, "empty_bare.git"));
+	cl_git_pass(git_repository_config(&config, repo));
+
+	cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 1));
+
+	git_config_free(config);
+	git_repository_free(repo);
+	cl_git_fail(git_repository_open(&repo, "empty_bare.git"));
+}
+
+void test_repo_open__standard_empty_repo_through_gitdir(void)
+{
+	git_repository *repo;
+
+	cl_git_pass(git_repository_open(&repo, cl_fixture("empty_standard_repo/.gitted")));
+
+	cl_assert(git_repository_path(repo) != NULL);
+	cl_assert(git__suffixcmp(git_repository_path(repo), "/") == 0);
+
+	cl_assert(git_repository_workdir(repo) != NULL);
+	cl_assert(git__suffixcmp(git_repository_workdir(repo), "/") == 0);
+
+	git_repository_free(repo);
+}
+
+void test_repo_open__standard_empty_repo_through_workdir(void)
+{
+	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
+
+	cl_assert(git_repository_path(repo) != NULL);
+	cl_assert(git__suffixcmp(git_repository_path(repo), "/") == 0);
+
+	cl_assert(git_repository_workdir(repo) != NULL);
+	cl_assert(git__suffixcmp(git_repository_workdir(repo), "/") == 0);
+}
+
+
+void test_repo_open__open_with_discover(void)
+{
+	static const char *variants[] = {
+		"attr", "attr/", "attr/.git", "attr/.git/",
+		"attr/sub", "attr/sub/", "attr/sub/sub", "attr/sub/sub/",
+		NULL
+	};
+	git_repository *repo;
+	const char **scan;
+
+	cl_fixture_sandbox("attr");
+	cl_git_pass(p_rename("attr/.gitted", "attr/.git"));
+
+	for (scan = variants; *scan != NULL; scan++) {
+		cl_git_pass(git_repository_open_ext(&repo, *scan, 0, NULL));
+		cl_assert(git__suffixcmp(git_repository_path(repo), "attr/.git/") == 0);
+		cl_assert(git__suffixcmp(git_repository_workdir(repo), "attr/") == 0);
+		git_repository_free(repo);
+	}
+
+	cl_fixture_cleanup("attr");
+}
+
+static void make_gitlink_dir(const char *dir, const char *linktext)
+{
+	git_buf path = GIT_BUF_INIT;
+
+	cl_git_pass(git_futils_mkdir(dir, NULL, 0777, GIT_MKDIR_VERIFY_DIR));
+	cl_git_pass(git_buf_joinpath(&path, dir, ".git"));
+	cl_git_rewritefile(path.ptr, linktext);
+	git_buf_free(&path);
+}
+
+void test_repo_open__gitlinked(void)
+{
+	/* need to have both repo dir and workdir set up correctly */
+	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
+	git_repository *repo2;
+
+	make_gitlink_dir("alternate", "gitdir: ../empty_standard_repo/.git");
+
+	cl_git_pass(git_repository_open(&repo2, "alternate"));
+
+	cl_assert(git_repository_path(repo2) != NULL);
+	cl_assert_(git__suffixcmp(git_repository_path(repo2), "empty_standard_repo/.git/") == 0, git_repository_path(repo2));
+	cl_assert_equal_s(git_repository_path(repo), git_repository_path(repo2));
+
+	cl_assert(git_repository_workdir(repo2) != NULL);
+	cl_assert_(git__suffixcmp(git_repository_workdir(repo2), "alternate/") == 0, git_repository_workdir(repo2));
+
+	git_repository_free(repo2);
+}
+
+void test_repo_open__from_git_new_workdir(void)
+{
+#ifndef GIT_WIN32
+	/* The git-new-workdir script that ships with git sets up a bunch of
+	 * symlinks to create a second workdir that shares the object db with
+	 * another checkout.  Libgit2 can open a repo that has been configured
+	 * this way.
+	 */
+
+	git_repository *repo2;
+	git_buf link_tgt = GIT_BUF_INIT, link = GIT_BUF_INIT, body = GIT_BUF_INIT;
+	const char **scan;
+	int link_fd;
+	static const char *links[] = {
+		"config", "refs", "logs/refs", "objects", "info", "hooks",
+		"packed-refs", "remotes", "rr-cache", "svn", NULL
+	};
+	static const char *copies[] = {
+		"HEAD", NULL
+	};
+
+	cl_git_sandbox_init("empty_standard_repo");
+
+	cl_git_pass(p_mkdir("alternate", 0777));
+	cl_git_pass(p_mkdir("alternate/.git", 0777));
+
+	for (scan = links; *scan != NULL; scan++) {
+		git_buf_joinpath(&link_tgt, "empty_standard_repo/.git", *scan);
+		if (git_path_exists(link_tgt.ptr)) {
+			git_buf_joinpath(&link_tgt, "../../empty_standard_repo/.git", *scan);
+			git_buf_joinpath(&link, "alternate/.git", *scan);
+			if (strchr(*scan, '/'))
+				git_futils_mkpath2file(link.ptr, 0777);
+			cl_assert_(symlink(link_tgt.ptr, link.ptr) == 0, strerror(errno));
+		}
+	}
+	for (scan = copies; *scan != NULL; scan++) {
+		git_buf_joinpath(&link_tgt, "empty_standard_repo/.git", *scan);
+		if (git_path_exists(link_tgt.ptr)) {
+			git_buf_joinpath(&link, "alternate/.git", *scan);
+			cl_git_pass(git_futils_readbuffer(&body, link_tgt.ptr));
+
+			cl_assert((link_fd = git_futils_creat_withpath(link.ptr, 0777, 0666)) >= 0);
+			cl_must_pass(p_write(link_fd, body.ptr, body.size));
+			p_close(link_fd);
+		}
+	}
+
+	git_buf_free(&link_tgt);
+	git_buf_free(&link);
+	git_buf_free(&body);
+
+
+	cl_git_pass(git_repository_open(&repo2, "alternate"));
+
+	cl_assert(git_repository_path(repo2) != NULL);
+	cl_assert_(git__suffixcmp(git_repository_path(repo2), "alternate/.git/") == 0, git_repository_path(repo2));
+
+	cl_assert(git_repository_workdir(repo2) != NULL);
+	cl_assert_(git__suffixcmp(git_repository_workdir(repo2), "alternate/") == 0, git_repository_workdir(repo2));
+
+	git_repository_free(repo2);
+#endif
+}
+
+void test_repo_open__failures(void)
+{
+	git_repository *base, *repo;
+	git_buf ceiling = GIT_BUF_INIT;
+
+	base = cl_git_sandbox_init("attr");
+	cl_git_pass(git_buf_sets(&ceiling, git_repository_workdir(base)));
+
+	/* fail with no searching */
+	cl_git_fail(git_repository_open(&repo, "attr/sub"));
+	cl_git_fail(git_repository_open_ext(
+		&repo, "attr/sub", GIT_REPOSITORY_OPEN_NO_SEARCH, NULL));
+
+	/* fail with ceiling too low */
+	cl_git_pass(git_buf_joinpath(&ceiling, ceiling.ptr, "sub"));
+	cl_git_fail(git_repository_open_ext(&repo, "attr/sub", 0, ceiling.ptr));
+
+	/* fail with no repo */
+	cl_git_pass(p_mkdir("alternate", 0777));
+	cl_git_pass(p_mkdir("alternate/.git", 0777));
+	cl_git_fail(git_repository_open_ext(&repo, "alternate", 0, NULL));
+	cl_git_fail(git_repository_open_ext(&repo, "alternate/.git", 0, NULL));
+
+	git_buf_free(&ceiling);
+}
+
+void test_repo_open__bad_gitlinks(void)
+{
+	git_repository *repo;
+	static const char *bad_links[] = {
+		"garbage\n", "gitdir", "gitdir:\n", "gitdir: foobar",
+		"gitdir: ../invalid", "gitdir: ../invalid2",
+		"gitdir: ../attr/.git with extra stuff",
+		NULL
+	};
+	const char **scan;
+
+	cl_git_sandbox_init("attr");
+
+	cl_git_pass(p_mkdir("invalid", 0777));
+	cl_git_pass(git_futils_mkdir_r("invalid2/.git", NULL, 0777));
+
+	for (scan = bad_links; *scan != NULL; scan++) {
+		make_gitlink_dir("alternate", *scan);
+		cl_git_fail(git_repository_open_ext(&repo, "alternate", 0, NULL));
+	}
+
+	git_futils_rmdir_r("invalid", NULL, GIT_RMDIR_REMOVE_FILES);
+	git_futils_rmdir_r("invalid2", NULL, GIT_RMDIR_REMOVE_FILES);
+}
+
+#ifdef GIT_WIN32
+static void unposix_path(git_buf *path)
+{
+	char *src, *tgt;
+
+	src = tgt = path->ptr;
+
+	/* convert "/d/..." to "d:\..." */
+	if (src[0] == '/' && isalpha(src[1]) && src[2] == '/') {
+		*tgt++ = src[1];
+		*tgt++ = ':';
+		*tgt++ = '\\';
+		src += 3;
+	}
+
+	while (*src) {
+		*tgt++ = (*src == '/') ? '\\' : *src;
+		src++;
+	}
+
+	*tgt = '\0';
+}
+#endif
+
+void test_repo_open__win32_path(void)
+{
+#ifdef GIT_WIN32
+	git_repository *repo = cl_git_sandbox_init("empty_standard_repo"), *repo2;
+	git_buf winpath = GIT_BUF_INIT;
+	static const char *repo_path = "empty_standard_repo/.git/";
+	static const char *repo_wd   = "empty_standard_repo/";
+
+	cl_assert(git__suffixcmp(git_repository_path(repo), repo_path) == 0);
+	cl_assert(git__suffixcmp(git_repository_workdir(repo), repo_wd) == 0);
+
+	cl_git_pass(git_buf_sets(&winpath, git_repository_path(repo)));
+	unposix_path(&winpath);
+	cl_git_pass(git_repository_open(&repo2, winpath.ptr));
+	cl_assert(git__suffixcmp(git_repository_path(repo2), repo_path) == 0);
+	cl_assert(git__suffixcmp(git_repository_workdir(repo2), repo_wd) == 0);
+	git_repository_free(repo2);
+
+	cl_git_pass(git_buf_sets(&winpath, git_repository_path(repo)));
+	git_buf_truncate(&winpath, winpath.size - 1); /* remove trailing '/' */
+	unposix_path(&winpath);
+	cl_git_pass(git_repository_open(&repo2, winpath.ptr));
+	cl_assert(git__suffixcmp(git_repository_path(repo2), repo_path) == 0);
+	cl_assert(git__suffixcmp(git_repository_workdir(repo2), repo_wd) == 0);
+	git_repository_free(repo2);
+
+	cl_git_pass(git_buf_sets(&winpath, git_repository_workdir(repo)));
+	unposix_path(&winpath);
+	cl_git_pass(git_repository_open(&repo2, winpath.ptr));
+	cl_assert(git__suffixcmp(git_repository_path(repo2), repo_path) == 0);
+	cl_assert(git__suffixcmp(git_repository_workdir(repo2), repo_wd) == 0);
+	git_repository_free(repo2);
+
+	cl_git_pass(git_buf_sets(&winpath, git_repository_workdir(repo)));
+	git_buf_truncate(&winpath, winpath.size - 1); /* remove trailing '/' */
+	unposix_path(&winpath);
+	cl_git_pass(git_repository_open(&repo2, winpath.ptr));
+	cl_assert(git__suffixcmp(git_repository_path(repo2), repo_path) == 0);
+	cl_assert(git__suffixcmp(git_repository_workdir(repo2), repo_wd) == 0);
+	git_repository_free(repo2);
+
+	git_buf_free(&winpath);
+#endif
+}
+
+void test_repo_open__opening_a_non_existing_repository_returns_ENOTFOUND(void)
+{
+	git_repository *repo;
+	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_open(&repo, "i-do-not/exist"));
+}
+
+void test_repo_open__no_config(void)
+{
+	git_buf path = GIT_BUF_INIT;
+	git_repository *repo;
+	git_config *config;
+
+	cl_fixture_sandbox("empty_standard_repo");
+	cl_git_pass(cl_rename(
+		"empty_standard_repo/.gitted", "empty_standard_repo/.git"));
+
+	/* remove local config */
+	cl_git_pass(git_futils_rmdir_r(
+		"empty_standard_repo/.git/config", NULL, GIT_RMDIR_REMOVE_FILES));
+
+	/* isolate from system level configs */
+	cl_must_pass(p_mkdir("alternate", 0777));
+	cl_git_pass(git_path_prettify(&path, "alternate", NULL));
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr));
+	cl_git_pass(git_libgit2_opts(
+		GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr));
+
+	git_buf_free(&path);
+
+	cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
+	cl_git_pass(git_repository_config(&config, repo));
+
+	cl_git_pass(git_config_set_string(config, "test.set", "42"));
+
+	git_config_free(config);
+	git_repository_free(repo);
+	cl_fixture_cleanup("empty_standard_repo");
+
+	cl_sandbox_set_search_path_defaults();
+}
+
+void test_repo_open__force_bare(void)
+{
+	/* need to have both repo dir and workdir set up correctly */
+	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
+	git_repository *barerepo;
+
+	make_gitlink_dir("alternate", "gitdir: ../empty_standard_repo/.git");
+
+	cl_assert(!git_repository_is_bare(repo));
+
+	cl_git_pass(git_repository_open(&barerepo, "alternate"));
+	cl_assert(!git_repository_is_bare(barerepo));
+	git_repository_free(barerepo);
+
+	cl_git_pass(git_repository_open_bare(
+		&barerepo, "empty_standard_repo/.git"));
+	cl_assert(git_repository_is_bare(barerepo));
+	git_repository_free(barerepo);
+
+	cl_git_fail(git_repository_open_bare(&barerepo, "alternate/.git"));
+
+	cl_git_pass(git_repository_open_ext(
+		&barerepo, "alternate/.git", GIT_REPOSITORY_OPEN_BARE, NULL));
+	cl_assert(git_repository_is_bare(barerepo));
+	git_repository_free(barerepo);
+
+	cl_git_pass(p_mkdir("empty_standard_repo/subdir", 0777));
+	cl_git_mkfile("empty_standard_repo/subdir/something.txt", "something");
+
+	cl_git_fail(git_repository_open_bare(
+		&barerepo, "empty_standard_repo/subdir"));
+
+	cl_git_pass(git_repository_open_ext(
+		&barerepo, "empty_standard_repo/subdir", GIT_REPOSITORY_OPEN_BARE, NULL));
+	cl_assert(git_repository_is_bare(barerepo));
+	git_repository_free(barerepo);
+
+	cl_git_pass(p_mkdir("alternate/subdir", 0777));
+	cl_git_pass(p_mkdir("alternate/subdir/sub2", 0777));
+	cl_git_mkfile("alternate/subdir/sub2/something.txt", "something");
+
+	cl_git_fail(git_repository_open_bare(&barerepo, "alternate/subdir/sub2"));
+
+	cl_git_pass(git_repository_open_ext(
+		&barerepo, "alternate/subdir/sub2", GIT_REPOSITORY_OPEN_BARE, NULL));
+	cl_assert(git_repository_is_bare(barerepo));
+	git_repository_free(barerepo);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/pathspec.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/pathspec.c
new file mode 100755
index 0000000..5b86662
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/pathspec.c
@@ -0,0 +1,385 @@
+#include "clar_libgit2.h"
+#include "git2/pathspec.h"
+
+static git_repository *g_repo;
+
+void test_repo_pathspec__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("status");
+}
+
+void test_repo_pathspec__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+	g_repo = NULL;
+}
+
+static char *str0[] = { "*_file", "new_file", "garbage" };
+static char *str1[] = { "*_FILE", "NEW_FILE", "GARBAGE" };
+static char *str2[] = { "staged_*" };
+static char *str3[] = { "!subdir", "*_file", "new_file" };
+static char *str4[] = { "*" };
+static char *str5[] = { "S*" };
+
+void test_repo_pathspec__workdir0(void)
+{
+	git_strarray s;
+	git_pathspec *ps;
+	git_pathspec_match_list *m;
+
+	/* { "*_file", "new_file", "garbage" } */
+	s.strings = str0; s.count = ARRAY_SIZE(str0);
+	cl_git_pass(git_pathspec_new(&ps, &s));
+
+	cl_git_pass(git_pathspec_match_workdir(&m, g_repo, 0, ps));
+	cl_assert_equal_sz(10, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_sz(0, git_pathspec_match_list_failed_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	cl_git_pass(git_pathspec_match_workdir(&m, g_repo,
+		GIT_PATHSPEC_FIND_FAILURES, ps));
+	cl_assert_equal_sz(10, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_sz(1, git_pathspec_match_list_failed_entrycount(m));
+	cl_assert_equal_s("garbage", git_pathspec_match_list_failed_entry(m, 0));
+	git_pathspec_match_list_free(m);
+
+	cl_git_pass(git_pathspec_match_workdir(&m, g_repo,
+		GIT_PATHSPEC_FIND_FAILURES | GIT_PATHSPEC_FAILURES_ONLY, ps));
+	cl_assert_equal_sz(0, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_sz(1, git_pathspec_match_list_failed_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	git_pathspec_free(ps);
+}
+
+void test_repo_pathspec__workdir1(void)
+{
+	git_strarray s;
+	git_pathspec *ps;
+	git_pathspec_match_list *m;
+
+	/* { "*_FILE", "NEW_FILE", "GARBAGE" } */
+	s.strings = str1; s.count = ARRAY_SIZE(str1);
+	cl_git_pass(git_pathspec_new(&ps, &s));
+
+	cl_git_pass(git_pathspec_match_workdir(&m, g_repo,
+		GIT_PATHSPEC_IGNORE_CASE, ps));
+	cl_assert_equal_sz(10, git_pathspec_match_list_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	cl_git_pass(git_pathspec_match_workdir(&m, g_repo,
+		GIT_PATHSPEC_USE_CASE, ps));
+	cl_assert_equal_sz(0, git_pathspec_match_list_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	cl_git_fail(git_pathspec_match_workdir(&m, g_repo,
+		GIT_PATHSPEC_USE_CASE | GIT_PATHSPEC_NO_MATCH_ERROR, ps));
+
+	cl_git_pass(git_pathspec_match_workdir(&m, g_repo,
+		GIT_PATHSPEC_IGNORE_CASE | GIT_PATHSPEC_FIND_FAILURES, ps));
+	cl_assert_equal_sz(10, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_sz(1, git_pathspec_match_list_failed_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	cl_git_pass(git_pathspec_match_workdir(&m, g_repo,
+		GIT_PATHSPEC_USE_CASE | GIT_PATHSPEC_FIND_FAILURES, ps));
+	cl_assert_equal_sz(0, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_sz(3, git_pathspec_match_list_failed_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	git_pathspec_free(ps);
+}
+
+void test_repo_pathspec__workdir2(void)
+{
+	git_strarray s;
+	git_pathspec *ps;
+	git_pathspec_match_list *m;
+
+	/* { "staged_*" } */
+	s.strings = str2; s.count = ARRAY_SIZE(str2);
+	cl_git_pass(git_pathspec_new(&ps, &s));
+
+	cl_git_pass(git_pathspec_match_workdir(&m, g_repo, 0, ps));
+	cl_assert_equal_sz(5, git_pathspec_match_list_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	cl_git_pass(git_pathspec_match_workdir(&m, g_repo,
+		GIT_PATHSPEC_FIND_FAILURES, ps));
+	cl_assert_equal_sz(5, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_sz(0, git_pathspec_match_list_failed_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	cl_git_fail(git_pathspec_match_workdir(&m, g_repo,
+		GIT_PATHSPEC_NO_GLOB | GIT_PATHSPEC_NO_MATCH_ERROR, ps));
+
+	cl_git_pass(git_pathspec_match_workdir(&m, g_repo,
+		GIT_PATHSPEC_NO_GLOB | GIT_PATHSPEC_FIND_FAILURES, ps));
+	cl_assert_equal_sz(0, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_sz(1, git_pathspec_match_list_failed_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	git_pathspec_free(ps);
+}
+
+void test_repo_pathspec__workdir3(void)
+{
+	git_strarray s;
+	git_pathspec *ps;
+	git_pathspec_match_list *m;
+
+	/* { "!subdir", "*_file", "new_file" } */
+	s.strings = str3; s.count = ARRAY_SIZE(str3);
+	cl_git_pass(git_pathspec_new(&ps, &s));
+
+	cl_git_pass(git_pathspec_match_workdir(&m, g_repo, 0, ps));
+	cl_assert_equal_sz(7, git_pathspec_match_list_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	cl_git_pass(git_pathspec_match_workdir(&m, g_repo,
+		GIT_PATHSPEC_FIND_FAILURES, ps));
+	cl_assert_equal_sz(7, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_sz(0, git_pathspec_match_list_failed_entrycount(m));
+
+	cl_assert_equal_s("current_file", git_pathspec_match_list_entry(m, 0));
+	cl_assert_equal_s("modified_file", git_pathspec_match_list_entry(m, 1));
+	cl_assert_equal_s("new_file", git_pathspec_match_list_entry(m, 2));
+	cl_assert_equal_s("staged_changes_modified_file", git_pathspec_match_list_entry(m, 3));
+	cl_assert_equal_s("staged_delete_modified_file", git_pathspec_match_list_entry(m, 4));
+	cl_assert_equal_s("staged_new_file", git_pathspec_match_list_entry(m, 5));
+	cl_assert_equal_s("staged_new_file_modified_file", git_pathspec_match_list_entry(m, 6));
+	cl_assert_equal_s(NULL, git_pathspec_match_list_entry(m, 7));
+
+	git_pathspec_match_list_free(m);
+
+	git_pathspec_free(ps);
+}
+
+void test_repo_pathspec__workdir4(void)
+{
+	git_strarray s;
+	git_pathspec *ps;
+	git_pathspec_match_list *m;
+
+	/* { "*" } */
+	s.strings = str4; s.count = ARRAY_SIZE(str4);
+	cl_git_pass(git_pathspec_new(&ps, &s));
+
+	cl_git_pass(git_pathspec_match_workdir(&m, g_repo, 0, ps));
+	cl_assert_equal_sz(13, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_s("\xE8\xBF\x99", git_pathspec_match_list_entry(m, 12));
+	git_pathspec_match_list_free(m);
+
+	git_pathspec_free(ps);
+}
+
+
+void test_repo_pathspec__index0(void)
+{
+	git_index *idx;
+	git_strarray s;
+	git_pathspec *ps;
+	git_pathspec_match_list *m;
+
+	cl_git_pass(git_repository_index(&idx, g_repo));
+
+	/* { "*_file", "new_file", "garbage" } */
+	s.strings = str0; s.count = ARRAY_SIZE(str0);
+	cl_git_pass(git_pathspec_new(&ps, &s));
+
+	cl_git_pass(git_pathspec_match_index(&m, idx, 0, ps));
+	cl_assert_equal_sz(9, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_sz(0, git_pathspec_match_list_failed_entrycount(m));
+	cl_assert_equal_s("current_file", git_pathspec_match_list_entry(m, 0));
+	cl_assert_equal_s("modified_file", git_pathspec_match_list_entry(m, 1));
+	cl_assert_equal_s("staged_changes_modified_file", git_pathspec_match_list_entry(m, 2));
+	cl_assert_equal_s("staged_new_file", git_pathspec_match_list_entry(m, 3));
+	cl_assert_equal_s("staged_new_file_deleted_file", git_pathspec_match_list_entry(m, 4));
+	cl_assert_equal_s("staged_new_file_modified_file", git_pathspec_match_list_entry(m, 5));
+	cl_assert_equal_s("subdir/current_file", git_pathspec_match_list_entry(m, 6));
+	cl_assert_equal_s("subdir/deleted_file", git_pathspec_match_list_entry(m, 7));
+	cl_assert_equal_s("subdir/modified_file", git_pathspec_match_list_entry(m, 8));
+	cl_assert_equal_s(NULL, git_pathspec_match_list_entry(m, 9));
+	git_pathspec_match_list_free(m);
+
+	cl_git_pass(git_pathspec_match_index(&m, idx,
+		GIT_PATHSPEC_FIND_FAILURES, ps));
+	cl_assert_equal_sz(9, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_sz(2, git_pathspec_match_list_failed_entrycount(m));
+	cl_assert_equal_s("new_file", git_pathspec_match_list_failed_entry(m, 0));
+	cl_assert_equal_s("garbage", git_pathspec_match_list_failed_entry(m, 1));
+	cl_assert_equal_s(NULL, git_pathspec_match_list_failed_entry(m, 2));
+	git_pathspec_match_list_free(m);
+
+	git_pathspec_free(ps);
+	git_index_free(idx);
+}
+
+void test_repo_pathspec__index1(void)
+{
+	/* Currently the USE_CASE and IGNORE_CASE flags don't work on the
+	 * index because the index sort order for the index iterator is
+	 * set by the index itself.  I think the correct fix is for the
+	 * index not to embed a global sort order but to support traversal
+	 * in either case sensitive or insensitive order in a stateless
+	 * manner.
+	 *
+	 * Anyhow, as it is, there is no point in doing this test.
+	 */
+#if 0
+	git_index *idx;
+	git_strarray s;
+	git_pathspec *ps;
+	git_pathspec_match_list *m;
+
+	cl_git_pass(git_repository_index(&idx, g_repo));
+
+	/* { "*_FILE", "NEW_FILE", "GARBAGE" } */
+	s.strings = str1; s.count = ARRAY_SIZE(str1);
+	cl_git_pass(git_pathspec_new(&ps, &s));
+
+	cl_git_pass(git_pathspec_match_index(&m, idx,
+		GIT_PATHSPEC_USE_CASE, ps));
+	cl_assert_equal_sz(0, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_sz(0, git_pathspec_match_list_failed_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	cl_git_pass(git_pathspec_match_index(&m, idx,
+		GIT_PATHSPEC_USE_CASE | GIT_PATHSPEC_FIND_FAILURES, ps));
+	cl_assert_equal_sz(0, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_sz(3, git_pathspec_match_list_failed_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	cl_git_pass(git_pathspec_match_index(&m, idx,
+		GIT_PATHSPEC_IGNORE_CASE | GIT_PATHSPEC_FIND_FAILURES, ps));
+	cl_assert_equal_sz(10, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_sz(2, git_pathspec_match_list_failed_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	git_pathspec_free(ps);
+	git_index_free(idx);
+#endif
+}
+
+void test_repo_pathspec__tree0(void)
+{
+	git_object *tree;
+	git_strarray s;
+	git_pathspec *ps;
+	git_pathspec_match_list *m;
+
+	/* { "*_file", "new_file", "garbage" } */
+	s.strings = str0; s.count = ARRAY_SIZE(str0);
+	cl_git_pass(git_pathspec_new(&ps, &s));
+
+	cl_git_pass(git_revparse_single(&tree, g_repo, "HEAD~2^{tree}"));
+
+	cl_git_pass(git_pathspec_match_tree(&m, (git_tree *)tree,
+		GIT_PATHSPEC_FIND_FAILURES, ps));
+	cl_assert_equal_sz(4, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_s("current_file", git_pathspec_match_list_entry(m, 0));
+	cl_assert_equal_s("modified_file", git_pathspec_match_list_entry(m, 1));
+	cl_assert_equal_s("staged_changes_modified_file", git_pathspec_match_list_entry(m, 2));
+	cl_assert_equal_s("staged_delete_modified_file", git_pathspec_match_list_entry(m, 3));
+	cl_assert_equal_s(NULL, git_pathspec_match_list_entry(m, 4));
+	cl_assert_equal_sz(2, git_pathspec_match_list_failed_entrycount(m));
+	cl_assert_equal_s("new_file", git_pathspec_match_list_failed_entry(m, 0));
+	cl_assert_equal_s("garbage", git_pathspec_match_list_failed_entry(m, 1));
+	cl_assert_equal_s(NULL, git_pathspec_match_list_failed_entry(m, 2));
+	git_pathspec_match_list_free(m);
+
+	git_object_free(tree);
+
+	cl_git_pass(git_revparse_single(&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(git_pathspec_match_tree(&m, (git_tree *)tree,
+		GIT_PATHSPEC_FIND_FAILURES, ps));
+	cl_assert_equal_sz(7, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_s("current_file", git_pathspec_match_list_entry(m, 0));
+	cl_assert_equal_s("modified_file", git_pathspec_match_list_entry(m, 1));
+	cl_assert_equal_s("staged_changes_modified_file", git_pathspec_match_list_entry(m, 2));
+	cl_assert_equal_s("staged_delete_modified_file", git_pathspec_match_list_entry(m, 3));
+	cl_assert_equal_s("subdir/current_file", git_pathspec_match_list_entry(m, 4));
+	cl_assert_equal_s("subdir/deleted_file", git_pathspec_match_list_entry(m, 5));
+	cl_assert_equal_s("subdir/modified_file", git_pathspec_match_list_entry(m, 6));
+	cl_assert_equal_s(NULL, git_pathspec_match_list_entry(m, 7));
+	cl_assert_equal_sz(2, git_pathspec_match_list_failed_entrycount(m));
+	cl_assert_equal_s("new_file", git_pathspec_match_list_failed_entry(m, 0));
+	cl_assert_equal_s("garbage", git_pathspec_match_list_failed_entry(m, 1));
+	cl_assert_equal_s(NULL, git_pathspec_match_list_failed_entry(m, 2));
+	git_pathspec_match_list_free(m);
+
+	git_object_free(tree);
+
+	git_pathspec_free(ps);
+}
+
+void test_repo_pathspec__tree5(void)
+{
+	git_object *tree;
+	git_strarray s;
+	git_pathspec *ps;
+	git_pathspec_match_list *m;
+
+	/* { "S*" } */
+	s.strings = str5; s.count = ARRAY_SIZE(str5);
+	cl_git_pass(git_pathspec_new(&ps, &s));
+
+	cl_git_pass(git_revparse_single(&tree, g_repo, "HEAD~2^{tree}"));
+
+	cl_git_pass(git_pathspec_match_tree(&m, (git_tree *)tree,
+		GIT_PATHSPEC_USE_CASE | GIT_PATHSPEC_FIND_FAILURES, ps));
+	cl_assert_equal_sz(0, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_sz(1, git_pathspec_match_list_failed_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	cl_git_pass(git_pathspec_match_tree(&m, (git_tree *)tree,
+		GIT_PATHSPEC_IGNORE_CASE | GIT_PATHSPEC_FIND_FAILURES, ps));
+	cl_assert_equal_sz(5, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_s("staged_changes", git_pathspec_match_list_entry(m, 0));
+	cl_assert_equal_s("staged_delete_modified_file", git_pathspec_match_list_entry(m, 4));
+	cl_assert_equal_sz(0, git_pathspec_match_list_failed_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	git_object_free(tree);
+
+	cl_git_pass(git_revparse_single(&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(git_pathspec_match_tree(&m, (git_tree *)tree,
+		GIT_PATHSPEC_IGNORE_CASE | GIT_PATHSPEC_FIND_FAILURES, ps));
+	cl_assert_equal_sz(9, git_pathspec_match_list_entrycount(m));
+	cl_assert_equal_s("staged_changes", git_pathspec_match_list_entry(m, 0));
+	cl_assert_equal_s("subdir.txt", git_pathspec_match_list_entry(m, 5));
+	cl_assert_equal_s("subdir/current_file", git_pathspec_match_list_entry(m, 6));
+	cl_assert_equal_sz(0, git_pathspec_match_list_failed_entrycount(m));
+	git_pathspec_match_list_free(m);
+
+	git_object_free(tree);
+
+	git_pathspec_free(ps);
+}
+
+void test_repo_pathspec__in_memory(void)
+{
+	static char *strings[] = { "one", "two*", "!three*", "*four" };
+	git_strarray s = { strings, ARRAY_SIZE(strings) };
+	git_pathspec *ps;
+
+	cl_git_pass(git_pathspec_new(&ps, &s));
+
+	cl_assert(git_pathspec_matches_path(ps, 0, "one"));
+	cl_assert(!git_pathspec_matches_path(ps, 0, "ONE"));
+	cl_assert(git_pathspec_matches_path(ps, GIT_PATHSPEC_IGNORE_CASE, "ONE"));
+	cl_assert(git_pathspec_matches_path(ps, 0, "two"));
+	cl_assert(git_pathspec_matches_path(ps, 0, "two.txt"));
+	cl_assert(!git_pathspec_matches_path(ps, 0, "three.txt"));
+	cl_assert(git_pathspec_matches_path(ps, 0, "anything.four"));
+	cl_assert(!git_pathspec_matches_path(ps, 0, "three.four"));
+	cl_assert(!git_pathspec_matches_path(ps, 0, "nomatch"));
+	cl_assert(!git_pathspec_matches_path(ps, GIT_PATHSPEC_NO_GLOB, "two"));
+	cl_assert(git_pathspec_matches_path(ps, GIT_PATHSPEC_NO_GLOB, "two*"));
+	cl_assert(!git_pathspec_matches_path(ps, GIT_PATHSPEC_NO_GLOB, "anyfour"));
+	cl_assert(git_pathspec_matches_path(ps, GIT_PATHSPEC_NO_GLOB, "*four"));
+
+	git_pathspec_free(ps);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/repo_helpers.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/repo_helpers.c
new file mode 100755
index 0000000..61f6968
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/repo_helpers.c
@@ -0,0 +1,22 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+#include "repo_helpers.h"
+#include "posix.h"
+
+void make_head_unborn(git_repository* repo, const char *target)
+{
+	git_reference *head;
+
+	cl_git_pass(git_reference_symbolic_create(&head, repo, GIT_HEAD_FILE, target, 1, NULL));
+	git_reference_free(head);
+}
+
+void delete_head(git_repository* repo)
+{
+	git_buf head_path = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_joinpath(&head_path, git_repository_path(repo), GIT_HEAD_FILE));
+	cl_git_pass(p_unlink(git_buf_cstr(&head_path)));
+
+	git_buf_free(&head_path);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/repo_helpers.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/repo_helpers.h
new file mode 100755
index 0000000..6783d57
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/repo_helpers.h
@@ -0,0 +1,6 @@
+#include "common.h"
+
+#define NON_EXISTING_HEAD "refs/heads/hide/and/seek"
+
+extern void make_head_unborn(git_repository* repo, const char *target);
+extern void delete_head(git_repository* repo);
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/reservedname.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/reservedname.c
new file mode 100755
index 0000000..faea0cc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/reservedname.c
@@ -0,0 +1,108 @@
+#include "clar_libgit2.h"
+#include "../submodule/submodule_helpers.h"
+#include "repository.h"
+
+void test_repo_reservedname__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_repo_reservedname__includes_shortname_on_win32(void)
+{
+	git_repository *repo;
+	git_buf *reserved;
+	size_t reserved_len;
+
+	repo = cl_git_sandbox_init("nasty");
+	cl_assert(git_repository__reserved_names(&reserved, &reserved_len, repo, false));
+
+#ifdef GIT_WIN32
+	cl_assert_equal_i(2, reserved_len);
+	cl_assert_equal_s(".git", reserved[0].ptr);
+	cl_assert_equal_s("GIT~1", reserved[1].ptr);
+#else
+	cl_assert_equal_i(1, reserved_len);
+	cl_assert_equal_s(".git", reserved[0].ptr);
+#endif
+}
+
+void test_repo_reservedname__includes_shortname_when_requested(void)
+{
+	git_repository *repo;
+	git_buf *reserved;
+	size_t reserved_len;
+
+	repo = cl_git_sandbox_init("nasty");
+	cl_assert(git_repository__reserved_names(&reserved, &reserved_len, repo, true));
+
+	cl_assert_equal_i(2, reserved_len);
+	cl_assert_equal_s(".git", reserved[0].ptr);
+	cl_assert_equal_s("GIT~1", reserved[1].ptr);
+}
+
+/* Ensures that custom shortnames are included: creates a GIT~1 so that the
+ * .git folder itself will have to be named GIT~2
+ */
+void test_repo_reservedname__custom_shortname_recognized(void)
+{
+#ifdef GIT_WIN32
+	git_repository *repo;
+	git_buf *reserved;
+	size_t reserved_len;
+
+	if (!cl_sandbox_supports_8dot3())
+		clar__skip();
+
+	repo = cl_git_sandbox_init("nasty");
+
+	cl_must_pass(p_rename("nasty/.git", "nasty/_temp"));
+	cl_git_write2file("nasty/git~1", "", 0, O_RDWR|O_CREAT, 0666);
+	cl_must_pass(p_rename("nasty/_temp", "nasty/.git"));
+
+	cl_assert(git_repository__reserved_names(&reserved, &reserved_len, repo, true));
+
+	cl_assert_equal_i(3, reserved_len);
+	cl_assert_equal_s(".git", reserved[0].ptr);
+	cl_assert_equal_s("GIT~1", reserved[1].ptr);
+	cl_assert_equal_s("GIT~2", reserved[2].ptr);
+#endif
+}
+
+/* When looking at the short name for a submodule, we need to prevent
+ * people from overwriting the `.git` file in the submodule working
+ * directory itself.  We don't want to look at the actual repository
+ * path, since it will be in the super's repository above us, and
+ * typically named with the name of our subrepository.  Consequently,
+ * preventing access to the short name of the actual repository path
+ * would prevent us from creating files with the same name as the
+ * subrepo.  (Eg, a submodule named "libgit2" could not contain a file
+ * named "libgit2", which would be unfortunate.)
+ */
+void test_repo_reservedname__submodule_pointer(void)
+{
+#ifdef GIT_WIN32
+	git_repository *super_repo, *sub_repo;
+	git_submodule *sub;
+	git_buf *sub_reserved;
+	size_t sub_reserved_len;
+
+	if (!cl_sandbox_supports_8dot3())
+		clar__skip();
+
+	super_repo = setup_fixture_submod2();
+
+	assert_submodule_exists(super_repo, "sm_unchanged");
+
+	cl_git_pass(git_submodule_lookup(&sub, super_repo, "sm_unchanged"));
+	cl_git_pass(git_submodule_open(&sub_repo, sub));
+
+	cl_assert(git_repository__reserved_names(&sub_reserved, &sub_reserved_len, sub_repo, true));
+
+	cl_assert_equal_i(2, sub_reserved_len);
+	cl_assert_equal_s(".git", sub_reserved[0].ptr);
+	cl_assert_equal_s("GIT~1", sub_reserved[1].ptr);
+
+	git_submodule_free(sub);
+	git_repository_free(sub_repo);
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/setters.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/setters.c
new file mode 100755
index 0000000..5a83fdb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/setters.c
@@ -0,0 +1,109 @@
+#include "clar_libgit2.h"
+#include "git2/sys/repository.h"
+
+#include "buffer.h"
+#include "posix.h"
+#include "util.h"
+#include "path.h"
+#include "fileops.h"
+
+static git_repository *repo;
+
+void test_repo_setters__initialize(void)
+{
+	cl_fixture_sandbox("testrepo.git");
+	cl_git_pass(git_repository_open(&repo, "testrepo.git"));
+	cl_must_pass(p_mkdir("new_workdir", 0777));
+}
+
+void test_repo_setters__cleanup(void)
+{
+	git_repository_free(repo);
+	repo = NULL;
+
+	cl_fixture_cleanup("testrepo.git");
+	cl_fixture_cleanup("new_workdir");
+}
+
+void test_repo_setters__setting_a_workdir_turns_a_bare_repository_into_a_standard_one(void)
+{
+	cl_assert(git_repository_is_bare(repo) == 1);
+
+	cl_assert(git_repository_workdir(repo) == NULL);
+	cl_git_pass(git_repository_set_workdir(repo, "./new_workdir", false));
+
+	cl_assert(git_repository_workdir(repo) != NULL);
+	cl_assert(git_repository_is_bare(repo) == 0);
+}
+
+void test_repo_setters__setting_a_workdir_prettifies_its_path(void)
+{
+	cl_git_pass(git_repository_set_workdir(repo, "./new_workdir", false));
+
+	cl_assert(git__suffixcmp(git_repository_workdir(repo), "new_workdir/") == 0);
+}
+
+void test_repo_setters__setting_a_workdir_creates_a_gitlink(void)
+{
+	git_config *cfg;
+	git_buf buf = GIT_BUF_INIT;
+	git_buf content = GIT_BUF_INIT;
+
+	cl_git_pass(git_repository_set_workdir(repo, "./new_workdir", true));
+
+	cl_assert(git_path_isfile("./new_workdir/.git"));
+
+	cl_git_pass(git_futils_readbuffer(&content, "./new_workdir/.git"));
+	cl_assert(git__prefixcmp(git_buf_cstr(&content), "gitdir: ") == 0);
+	cl_assert(git__suffixcmp(git_buf_cstr(&content), "testrepo.git/") == 0);
+	git_buf_free(&content);
+
+	cl_git_pass(git_repository_config(&cfg, repo));
+	cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.worktree"));
+	cl_assert(git__suffixcmp(git_buf_cstr(&buf), "new_workdir/") == 0);
+
+	git_buf_free(&buf);
+	git_config_free(cfg);
+}
+
+void test_repo_setters__setting_a_new_index_on_a_repo_which_has_already_loaded_one_properly_honors_the_refcount(void)
+{
+	git_index *new_index;
+
+	cl_git_pass(git_index_open(&new_index, "./my-index"));
+	cl_assert(((git_refcount *)new_index)->refcount.val == 1);
+
+	git_repository_set_index(repo, new_index);
+	cl_assert(((git_refcount *)new_index)->refcount.val == 2);
+
+	git_repository_free(repo);
+	cl_assert(((git_refcount *)new_index)->refcount.val == 1);
+
+	git_index_free(new_index);
+
+	/* 
+	 * Ensure the cleanup method won't try to free the repo as it's already been taken care of
+	 */
+	repo = NULL;
+}
+
+void test_repo_setters__setting_a_new_odb_on_a_repo_which_already_loaded_one_properly_honors_the_refcount(void)
+{
+	git_odb *new_odb;
+
+	cl_git_pass(git_odb_open(&new_odb, "./testrepo.git/objects"));
+	cl_assert(((git_refcount *)new_odb)->refcount.val == 1);
+
+	git_repository_set_odb(repo, new_odb);
+	cl_assert(((git_refcount *)new_odb)->refcount.val == 2);
+
+	git_repository_free(repo);
+	cl_assert(((git_refcount *)new_odb)->refcount.val == 1);
+
+	git_odb_free(new_odb);
+
+	/* 
+	 * Ensure the cleanup method won't try to free the repo as it's already been taken care of
+	 */
+	repo = NULL;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/shallow.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/shallow.c
new file mode 100755
index 0000000..5aeaf2d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/shallow.c
@@ -0,0 +1,39 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+
+static git_repository *g_repo;
+
+void test_repo_shallow__initialize(void)
+{
+}
+
+void test_repo_shallow__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_repo_shallow__no_shallow_file(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo.git");
+	cl_assert_equal_i(0, git_repository_is_shallow(g_repo));
+}
+
+void test_repo_shallow__empty_shallow_file(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo.git");
+	cl_git_mkfile("testrepo.git/shallow", "");
+	cl_assert_equal_i(0, git_repository_is_shallow(g_repo));
+}
+
+void test_repo_shallow__shallow_repo(void)
+{
+	g_repo = cl_git_sandbox_init("shallow.git");
+	cl_assert_equal_i(1, git_repository_is_shallow(g_repo));
+}
+
+void test_repo_shallow__clears_errors(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo.git");
+	cl_assert_equal_i(0, git_repository_is_shallow(g_repo));
+	cl_assert_equal_p(NULL, giterr_last());
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/state.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/state.c
new file mode 100755
index 0000000..bf2633c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/repo/state.c
@@ -0,0 +1,114 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "refs.h"
+#include "posix.h"
+#include "fileops.h"
+
+static git_repository *_repo;
+static git_buf _path;
+
+void test_repo_state__initialize(void)
+{
+	_repo = cl_git_sandbox_init("testrepo.git");
+}
+
+void test_repo_state__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+	git_buf_free(&_path);
+}
+
+static void setup_simple_state(const char *filename)
+{
+	cl_git_pass(git_buf_joinpath(&_path, git_repository_path(_repo), filename));
+	git_futils_mkpath2file(git_buf_cstr(&_path), 0777);
+	cl_git_mkfile(git_buf_cstr(&_path), "dummy");
+}
+
+static void assert_repo_state(git_repository_state_t state)
+{
+	cl_assert_equal_i(state, git_repository_state(_repo));
+}
+
+void test_repo_state__none_with_HEAD_attached(void)
+{
+	assert_repo_state(GIT_REPOSITORY_STATE_NONE);
+}
+
+void test_repo_state__none_with_HEAD_detached(void)
+{
+	cl_git_pass(git_repository_detach_head(_repo));
+	assert_repo_state(GIT_REPOSITORY_STATE_NONE);
+}
+
+void test_repo_state__merge(void)
+{
+	setup_simple_state(GIT_MERGE_HEAD_FILE);
+	assert_repo_state(GIT_REPOSITORY_STATE_MERGE);
+	cl_git_pass(git_repository_state_cleanup(_repo));
+	assert_repo_state(GIT_REPOSITORY_STATE_NONE);
+}
+
+void test_repo_state__revert(void)
+{
+	setup_simple_state(GIT_REVERT_HEAD_FILE);
+	assert_repo_state(GIT_REPOSITORY_STATE_REVERT);
+	cl_git_pass(git_repository_state_cleanup(_repo));
+	assert_repo_state(GIT_REPOSITORY_STATE_NONE);
+}
+
+void test_repo_state__cherry_pick(void)
+{
+	setup_simple_state(GIT_CHERRYPICK_HEAD_FILE);
+	assert_repo_state(GIT_REPOSITORY_STATE_CHERRYPICK);
+	cl_git_pass(git_repository_state_cleanup(_repo));
+	assert_repo_state(GIT_REPOSITORY_STATE_NONE);
+}
+
+void test_repo_state__bisect(void)
+{
+	setup_simple_state(GIT_BISECT_LOG_FILE);
+	assert_repo_state(GIT_REPOSITORY_STATE_BISECT);
+	cl_git_pass(git_repository_state_cleanup(_repo));
+	assert_repo_state(GIT_REPOSITORY_STATE_NONE);
+}
+
+void test_repo_state__rebase_interactive(void)
+{
+	setup_simple_state(GIT_REBASE_MERGE_INTERACTIVE_FILE);
+	assert_repo_state(GIT_REPOSITORY_STATE_REBASE_INTERACTIVE);
+	cl_git_pass(git_repository_state_cleanup(_repo));
+	assert_repo_state(GIT_REPOSITORY_STATE_NONE);
+}
+
+void test_repo_state__rebase_merge(void)
+{
+	setup_simple_state(GIT_REBASE_MERGE_DIR "whatever");
+	assert_repo_state(GIT_REPOSITORY_STATE_REBASE_MERGE);
+	cl_git_pass(git_repository_state_cleanup(_repo));
+	assert_repo_state(GIT_REPOSITORY_STATE_NONE);
+}
+
+void test_repo_state__rebase(void)
+{
+	setup_simple_state(GIT_REBASE_APPLY_REBASING_FILE);
+	assert_repo_state(GIT_REPOSITORY_STATE_REBASE);
+	cl_git_pass(git_repository_state_cleanup(_repo));
+	assert_repo_state(GIT_REPOSITORY_STATE_NONE);
+}
+
+void test_repo_state__apply_mailbox(void)
+{
+	setup_simple_state(GIT_REBASE_APPLY_APPLYING_FILE);
+	assert_repo_state(GIT_REPOSITORY_STATE_APPLY_MAILBOX);
+	cl_git_pass(git_repository_state_cleanup(_repo));
+	assert_repo_state(GIT_REPOSITORY_STATE_NONE);
+}
+
+void test_repo_state__apply_mailbox_or_rebase(void)
+{
+	setup_simple_state(GIT_REBASE_APPLY_DIR "whatever");
+	assert_repo_state(GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE);
+	cl_git_pass(git_repository_state_cleanup(_repo));
+	assert_repo_state(GIT_REPOSITORY_STATE_NONE);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/default.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/default.c
new file mode 100755
index 0000000..c76f148
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/default.c
@@ -0,0 +1,212 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "reset_helpers.h"
+#include "path.h"
+
+static git_repository *_repo;
+static git_object *_target;
+static git_strarray _pathspecs;
+static git_index *_index;
+
+static void initialize(const char *repo_name)
+{
+	_repo = cl_git_sandbox_init(repo_name);
+	cl_git_pass(git_repository_index(&_index, _repo));
+
+	_target = NULL;
+
+	_pathspecs.strings = NULL;
+	_pathspecs.count = 0;
+}
+
+void test_reset_default__initialize(void)
+{
+}
+
+void test_reset_default__cleanup(void)
+{
+	git_object_free(_target);
+	_target = NULL;
+
+	git_index_free(_index);
+	_index = NULL;
+
+	cl_git_sandbox_cleanup();
+}
+
+static void assert_content_in_index(
+	git_strarray *pathspecs,
+	bool should_exist,
+	git_strarray *expected_shas)
+{
+	size_t i, pos;
+	int error;
+
+	for (i = 0; i < pathspecs->count; i++) {
+		error = git_index_find(&pos, _index, pathspecs->strings[i]);
+
+		if (should_exist) {
+			const git_index_entry *entry;
+
+			cl_assert(error != GIT_ENOTFOUND);
+
+			entry = git_index_get_byindex(_index, pos);
+			cl_assert(entry != NULL);
+
+			if (!expected_shas)
+				continue;
+
+			cl_git_pass(git_oid_streq(&entry->id, expected_shas->strings[i]));
+		} else
+			cl_assert_equal_i(should_exist, error != GIT_ENOTFOUND);
+	}
+}
+
+void test_reset_default__resetting_filepaths_against_a_null_target_removes_them_from_the_index(void)
+{
+	char *paths[] = { "staged_changes", "staged_new_file" };
+
+	initialize("status");
+
+	_pathspecs.strings = paths;
+	_pathspecs.count = 2;
+
+	assert_content_in_index(&_pathspecs, true, NULL);
+
+	cl_git_pass(git_reset_default(_repo, NULL, &_pathspecs));
+
+	assert_content_in_index(&_pathspecs, false, NULL);
+}
+
+/*
+ * $ git ls-files --cached -s --abbrev=7 -- "staged*"
+ * 100644 55d316c 0        staged_changes
+ * 100644 a6be623 0        staged_changes_file_deleted
+ * ...
+ *
+ * $ git reset 0017bd4 -- staged_changes staged_changes_file_deleted
+ * Unstaged changes after reset:
+ * ...
+ *
+ * $ git ls-files --cached -s --abbrev=7 -- "staged*"
+ * 100644 32504b7 0        staged_changes
+ * 100644 061d42a 0        staged_changes_file_deleted
+ * ...
+ */
+void test_reset_default__resetting_filepaths_replaces_their_corresponding_index_entries(void)
+{
+	git_strarray before, after;
+
+	char *paths[] = { "staged_changes", "staged_changes_file_deleted" };
+	char *before_shas[] = { "55d316c9ba708999f1918e9677d01dfcae69c6b9",
+		"a6be623522ce87a1d862128ac42672604f7b468b" };
+	char *after_shas[] = { "32504b727382542f9f089e24fddac5e78533e96c",
+		"061d42a44cacde5726057b67558821d95db96f19" };
+
+	initialize("status");
+
+	_pathspecs.strings = paths;
+	_pathspecs.count = 2;
+	before.strings = before_shas;
+	before.count = 2;
+	after.strings = after_shas;
+	after.count = 2;
+
+	cl_git_pass(git_revparse_single(&_target, _repo, "0017bd4"));
+	assert_content_in_index(&_pathspecs, true, &before);
+
+	cl_git_pass(git_reset_default(_repo, _target, &_pathspecs));
+
+	assert_content_in_index(&_pathspecs, true, &after);
+}
+
+/*
+ * $ git ls-files --cached -s --abbrev=7 -- conflicts-one.txt
+ * 100644 1f85ca5 1        conflicts-one.txt
+ * 100644 6aea5f2 2        conflicts-one.txt
+ * 100644 516bd85 3        conflicts-one.txt
+ *
+ * $  git reset 9a05ccb -- conflicts-one.txt
+ * Unstaged changes after reset:
+ * ...
+ *
+ * $ git ls-files --cached -s --abbrev=7 -- conflicts-one.txt
+ * 100644 1f85ca5 0        conflicts-one.txt
+ *
+ */
+void test_reset_default__resetting_filepaths_clears_previous_conflicts(void)
+{
+	const git_index_entry *conflict_entry[3];
+	git_strarray after;
+
+	char *paths[] = { "conflicts-one.txt" };
+	char *after_shas[] = { "1f85ca51b8e0aac893a621b61a9c2661d6aa6d81" };
+
+	initialize("mergedrepo");
+
+	_pathspecs.strings = paths;
+	_pathspecs.count = 1;
+	after.strings = after_shas;
+	after.count = 1;
+
+	cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1],
+		&conflict_entry[2], _index, "conflicts-one.txt"));
+
+	cl_git_pass(git_revparse_single(&_target, _repo, "9a05ccb"));
+	cl_git_pass(git_reset_default(_repo, _target, &_pathspecs));
+
+	assert_content_in_index(&_pathspecs, true, &after);
+
+	cl_assert_equal_i(GIT_ENOTFOUND, git_index_conflict_get(&conflict_entry[0],
+		&conflict_entry[1], &conflict_entry[2], _index, "conflicts-one.txt"));
+}
+
+/*
+$  git reset HEAD -- "I_am_not_there.txt" "me_neither.txt"
+Unstaged changes after reset:
+...
+*/
+void test_reset_default__resetting_unknown_filepaths_does_not_fail(void)
+{
+	char *paths[] = { "I_am_not_there.txt", "me_neither.txt" };
+
+	initialize("status");
+
+	_pathspecs.strings = paths;
+	_pathspecs.count = 2;
+
+	assert_content_in_index(&_pathspecs, false, NULL);
+
+	cl_git_pass(git_revparse_single(&_target, _repo, "HEAD"));
+	cl_git_pass(git_reset_default(_repo, _target, &_pathspecs));
+
+	assert_content_in_index(&_pathspecs, false, NULL);
+}
+
+void test_reset_default__staged_rename_reset_delete(void)
+{
+	git_index_entry entry;
+	const git_index_entry *existing;
+	char *paths[] = { "new.txt" };
+
+	initialize("testrepo2");
+
+	existing = git_index_get_bypath(_index, "new.txt", 0);
+	cl_assert(existing);
+	memcpy(&entry, existing, sizeof(entry));
+
+	cl_git_pass(git_index_remove_bypath(_index, "new.txt"));
+
+	entry.path = "renamed.txt";
+	cl_git_pass(git_index_add(_index, &entry));
+
+	_pathspecs.strings = paths;
+	_pathspecs.count = 1;
+
+	assert_content_in_index(&_pathspecs, false, NULL);
+
+	cl_git_pass(git_revparse_single(&_target, _repo, "HEAD"));
+	cl_git_pass(git_reset_default(_repo, _target, &_pathspecs));
+
+	assert_content_in_index(&_pathspecs, true, NULL);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/hard.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/hard.c
new file mode 100755
index 0000000..88055ad
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/hard.c
@@ -0,0 +1,237 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "reset_helpers.h"
+#include "path.h"
+#include "fileops.h"
+
+static git_repository *repo;
+static git_object *target;
+
+void test_reset_hard__initialize(void)
+{
+	repo = cl_git_sandbox_init("status");
+	target = NULL;
+}
+
+void test_reset_hard__cleanup(void)
+{
+	if (target != NULL) {
+		git_object_free(target);
+		target = NULL;
+	}
+
+	cl_git_sandbox_cleanup();
+}
+
+static int strequal_ignore_eol(const char *exp, const char *str)
+{
+	while (*exp && *str) {
+		if (*exp != *str) {
+			while (*exp == '\r' || *exp == '\n') ++exp;
+			while (*str == '\r' || *str == '\n') ++str;
+			if (*exp != *str)
+				return false;
+		} else {
+			exp++; str++;
+		}
+	}
+	return (!*exp && !*str);
+}
+
+void test_reset_hard__resetting_reverts_modified_files(void)
+{
+	git_buf path = GIT_BUF_INIT, content = GIT_BUF_INIT;
+	int i;
+	static const char *files[4] = {
+		"current_file",
+		"modified_file",
+		"staged_new_file",
+		"staged_changes_modified_file" };
+	static const char *before[4] = {
+		"current_file\n",
+		"modified_file\nmodified_file\n",
+		"staged_new_file\n",
+		"staged_changes_modified_file\nstaged_changes_modified_file\nstaged_changes_modified_file\n"
+	};
+	static const char *after[4] = {
+		"current_file\n",
+		"modified_file\n",
+		NULL,
+		"staged_changes_modified_file\n"
+	};
+	const char *wd = git_repository_workdir(repo);
+
+	cl_assert(wd);
+
+	for (i = 0; i < 4; ++i) {
+		cl_git_pass(git_buf_joinpath(&path, wd, files[i]));
+		cl_git_pass(git_futils_readbuffer(&content, path.ptr));
+		cl_assert_equal_s(before[i], content.ptr);
+	}
+
+	cl_git_pass(git_revparse_single(&target, repo, "26a125e"));
+
+	cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL));
+
+	for (i = 0; i < 4; ++i) {
+		cl_git_pass(git_buf_joinpath(&path, wd, files[i]));
+		if (after[i]) {
+			cl_git_pass(git_futils_readbuffer(&content, path.ptr));
+			cl_assert(strequal_ignore_eol(after[i], content.ptr));
+		} else {
+			cl_assert(!git_path_exists(path.ptr));
+		}
+	}
+
+	git_buf_free(&content);
+	git_buf_free(&path);
+}
+
+void test_reset_hard__cannot_reset_in_a_bare_repository(void)
+{
+	git_repository *bare;
+
+	cl_git_pass(git_repository_open(&bare, cl_fixture("testrepo.git")));
+	cl_assert(git_repository_is_bare(bare) == true);
+
+	cl_git_pass(git_revparse_single(&target, bare, KNOWN_COMMIT_IN_BARE_REPO));
+
+	cl_assert_equal_i(GIT_EBAREREPO, git_reset(bare, target, GIT_RESET_HARD, NULL));
+
+	git_repository_free(bare);
+}
+
+static void index_entry_init(git_index *index, int side, git_oid *oid)
+{
+	git_index_entry entry;
+
+	memset(&entry, 0x0, sizeof(git_index_entry));
+
+	entry.path = "conflicting_file";
+	GIT_IDXENTRY_STAGE_SET(&entry, side);
+	entry.mode = 0100644;
+	git_oid_cpy(&entry.id, oid);
+
+	cl_git_pass(git_index_add(index, &entry));
+}
+
+static void unmerged_index_init(git_index *index, int entries)
+{
+	int write_ancestor = 1;
+	int write_ours = 2;
+	int write_theirs = 4;
+	git_oid ancestor, ours, theirs;
+
+	git_oid_fromstr(&ancestor, "6bb0d9f700543ba3d318ba7075fc3bd696b4287b");
+	git_oid_fromstr(&ours, "b19a1e93bec1317dc6097229e12afaffbfa74dc2");
+	git_oid_fromstr(&theirs, "950b81b7eee953d050aa05a641f8e056c85dd1bd");
+
+	cl_git_rewritefile("status/conflicting_file", "conflicting file\n");
+
+	if (entries & write_ancestor)
+		index_entry_init(index, 1, &ancestor);
+
+	if (entries & write_ours)
+		index_entry_init(index, 2, &ours);
+
+	if (entries & write_theirs)
+		index_entry_init(index, 3, &theirs);
+}
+
+void test_reset_hard__resetting_reverts_unmerged(void)
+{
+	git_index *index;
+	int entries;
+
+	/* Ensure every permutation of non-zero stage entries results in the
+	 * path being cleaned up. */
+	for (entries = 1; entries < 8; entries++) {
+		cl_git_pass(git_repository_index(&index, repo));
+
+		unmerged_index_init(index, entries);
+		cl_git_pass(git_index_write(index));
+
+		cl_git_pass(git_revparse_single(&target, repo, "26a125e"));
+		cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL));
+
+		cl_assert(git_path_exists("status/conflicting_file") == 0);
+
+		git_object_free(target);
+		target = NULL;
+
+		git_index_free(index);
+	}
+}
+
+void test_reset_hard__cleans_up_merge(void)
+{
+	git_buf merge_head_path = GIT_BUF_INIT,
+		merge_msg_path = GIT_BUF_INIT,
+		merge_mode_path = GIT_BUF_INIT,
+		orig_head_path = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_joinpath(&merge_head_path, git_repository_path(repo), "MERGE_HEAD"));
+	cl_git_mkfile(git_buf_cstr(&merge_head_path), "beefbeefbeefbeefbeefbeefbeefbeefbeefbeef\n");
+
+	cl_git_pass(git_buf_joinpath(&merge_msg_path, git_repository_path(repo), "MERGE_MSG"));
+	cl_git_mkfile(git_buf_cstr(&merge_msg_path), "Merge commit 0017bd4ab1ec30440b17bae1680cff124ab5f1f6\n");
+
+	cl_git_pass(git_buf_joinpath(&merge_mode_path, git_repository_path(repo), "MERGE_MODE"));
+	cl_git_mkfile(git_buf_cstr(&merge_mode_path), "");
+
+	cl_git_pass(git_buf_joinpath(&orig_head_path, git_repository_path(repo), "ORIG_HEAD"));
+	cl_git_mkfile(git_buf_cstr(&orig_head_path), "0017bd4ab1ec30440b17bae1680cff124ab5f1f6");
+
+	cl_git_pass(git_revparse_single(&target, repo, "0017bd4"));
+	cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL));
+
+	cl_assert(!git_path_exists(git_buf_cstr(&merge_head_path)));
+	cl_assert(!git_path_exists(git_buf_cstr(&merge_msg_path)));
+	cl_assert(!git_path_exists(git_buf_cstr(&merge_mode_path)));
+
+	cl_assert(git_path_exists(git_buf_cstr(&orig_head_path)));
+	cl_git_pass(p_unlink(git_buf_cstr(&orig_head_path)));
+
+	git_buf_free(&merge_head_path);
+	git_buf_free(&merge_msg_path);
+	git_buf_free(&merge_mode_path);
+	git_buf_free(&orig_head_path);
+}
+
+void test_reset_hard__reflog_is_correct(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	git_annotated_commit *annotated;
+	const char *exp_msg = "commit: Add a file which name should appear before the "
+		"\"subdir/\" folder while being dealt with by the treewalker";
+
+	reflog_check(repo, "HEAD", 3, "emeric.fermas at gmail.com", exp_msg);
+	reflog_check(repo, "refs/heads/master", 3, "emeric.fermas at gmail.com", exp_msg);
+
+	/* Branch not moving, no reflog entry */
+	cl_git_pass(git_revparse_single(&target, repo, "HEAD^{commit}"));
+	cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL));
+	reflog_check(repo, "HEAD", 3, "emeric.fermas at gmail.com", exp_msg);
+	reflog_check(repo, "refs/heads/master", 3, "emeric.fermas at gmail.com", exp_msg);
+
+	git_object_free(target);
+
+	/* Moved branch, expect id in message */
+	cl_git_pass(git_revparse_single(&target, repo, "HEAD~^{commit}"));
+	cl_git_pass(git_buf_printf(&buf, "reset: moving to %s", git_oid_tostr_s(git_object_id(target))));
+	cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL));
+	reflog_check(repo, "HEAD", 4, NULL, git_buf_cstr(&buf));
+	reflog_check(repo, "refs/heads/master", 4, NULL, git_buf_cstr(&buf));
+
+	git_buf_free(&buf);
+
+	/* Moved branch, expect revspec in message */
+	exp_msg = "reset: moving to HEAD~^{commit}";
+	cl_git_pass(git_annotated_commit_from_revspec(&annotated, repo, "HEAD~^{commit}"));
+	cl_git_pass(git_reset_from_annotated(repo, annotated, GIT_RESET_HARD, NULL));
+	reflog_check(repo, "HEAD", 5, NULL, exp_msg);
+	reflog_check(repo, "refs/heads/master", 5, NULL, exp_msg);
+
+	git_annotated_commit_free(annotated);
+
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/mixed.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/mixed.c
new file mode 100755
index 0000000..97eac74
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/mixed.c
@@ -0,0 +1,85 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "reset_helpers.h"
+#include "path.h"
+
+static git_repository *repo;
+static git_object *target;
+
+void test_reset_mixed__initialize(void)
+{
+	repo = cl_git_sandbox_init("attr");
+	target = NULL;
+}
+
+void test_reset_mixed__cleanup(void)
+{
+	git_object_free(target);
+	target = NULL;
+
+	cl_git_sandbox_cleanup();
+}
+
+void test_reset_mixed__cannot_reset_in_a_bare_repository(void)
+{
+	git_repository *bare;
+
+	cl_git_pass(git_repository_open(&bare, cl_fixture("testrepo.git")));
+	cl_assert(git_repository_is_bare(bare) == true);
+
+	cl_git_pass(git_revparse_single(&target, bare, KNOWN_COMMIT_IN_BARE_REPO));
+
+	cl_assert_equal_i(GIT_EBAREREPO, git_reset(bare, target, GIT_RESET_MIXED, NULL));
+
+	git_repository_free(bare);
+}
+
+void test_reset_mixed__resetting_refreshes_the_index_to_the_commit_tree(void)
+{
+	unsigned int status;
+
+	cl_git_pass(git_status_file(&status, repo, "macro_bad"));
+	cl_assert(status == GIT_STATUS_CURRENT);
+	cl_git_pass(git_revparse_single(&target, repo, "605812a"));
+
+	cl_git_pass(git_reset(repo, target, GIT_RESET_MIXED, NULL));
+
+	cl_git_pass(git_status_file(&status, repo, "macro_bad"));
+	cl_assert(status == GIT_STATUS_WT_NEW);
+}
+
+void test_reset_mixed__reflog_is_correct(void)
+{
+	git_buf buf = GIT_BUF_INIT;
+	git_annotated_commit *annotated;
+	const char *exp_msg = "commit: Updating test data so we can test inter-hunk-context";
+
+	reflog_check(repo, "HEAD", 9, "yoram.harmelin at gmail.com", exp_msg);
+	reflog_check(repo, "refs/heads/master", 9, "yoram.harmelin at gmail.com", exp_msg);
+
+	/* Branch not moving, no reflog entry */
+	cl_git_pass(git_revparse_single(&target, repo, "HEAD^{commit}"));
+	cl_git_pass(git_reset(repo, target, GIT_RESET_MIXED, NULL));
+	reflog_check(repo, "HEAD", 9, "yoram.harmelin at gmail.com", exp_msg);
+	reflog_check(repo, "refs/heads/master", 9, "yoram.harmelin at gmail.com", exp_msg);
+
+	git_object_free(target);
+	target = NULL;
+
+	/* Moved branch, expect id in message */
+	cl_git_pass(git_revparse_single(&target, repo, "HEAD~^{commit}"));
+	git_buf_clear(&buf);
+	cl_git_pass(git_buf_printf(&buf, "reset: moving to %s", git_oid_tostr_s(git_object_id(target))));
+	cl_git_pass(git_reset(repo, target, GIT_RESET_MIXED, NULL));
+	reflog_check(repo, "HEAD", 10, NULL, git_buf_cstr(&buf));
+	reflog_check(repo, "refs/heads/master", 10, NULL, git_buf_cstr(&buf));
+	git_buf_free(&buf);
+
+	/* Moved branch, expect revspec in message */
+	exp_msg = "reset: moving to HEAD~^{commit}";
+	cl_git_pass(git_annotated_commit_from_revspec(&annotated, repo, "HEAD~^{commit}"));
+	cl_git_pass(git_reset_from_annotated(repo, annotated, GIT_RESET_MIXED, NULL));
+	reflog_check(repo, "HEAD", 11, NULL, exp_msg);
+	reflog_check(repo, "refs/heads/master", 11, NULL, exp_msg);
+	git_annotated_commit_free(annotated);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/reset_helpers.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/reset_helpers.c
new file mode 100755
index 0000000..e6acec9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/reset_helpers.c
@@ -0,0 +1,20 @@
+#include "clar_libgit2.h"
+#include "reset_helpers.h"
+
+void reflog_check(git_repository *repo, const char *refname,
+		size_t exp_count, const char *exp_email, const char *exp_msg)
+{
+	git_reflog *log;
+	const git_reflog_entry *entry;
+
+	GIT_UNUSED(exp_email);
+
+	cl_git_pass(git_reflog_read(&log, repo, refname));
+	cl_assert_equal_i(exp_count, git_reflog_entrycount(log));
+	entry = git_reflog_entry_byindex(log, 0);
+
+	if (exp_msg)
+		cl_assert_equal_s(exp_msg, git_reflog_entry_message(entry));
+
+	git_reflog_free(log);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/reset_helpers.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/reset_helpers.h
new file mode 100755
index 0000000..e7e0485
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/reset_helpers.h
@@ -0,0 +1,7 @@
+#include "common.h"
+
+#define KNOWN_COMMIT_IN_BARE_REPO "e90810b8df3e80c413d903f631643c716887138d"
+#define KNOWN_COMMIT_IN_ATTR_REPO "217878ab49e1314388ea2e32dc6fdb58a1b969e0"
+
+void reflog_check(git_repository *repo, const char *refname,
+		size_t exp_count, const char *exp_email, const char *exp_msg);
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/soft.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/soft.c
new file mode 100755
index 0000000..506deca
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/reset/soft.c
@@ -0,0 +1,189 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "reset_helpers.h"
+#include "path.h"
+#include "repo/repo_helpers.h"
+
+static git_repository *repo;
+static git_object *target;
+
+void test_reset_soft__initialize(void)
+{
+	repo = cl_git_sandbox_init("testrepo.git");
+}
+
+void test_reset_soft__cleanup(void)
+{
+	git_object_free(target);
+	target = NULL;
+
+	cl_git_sandbox_cleanup();
+}
+
+static void assert_reset_soft(bool should_be_detached)
+{
+	git_oid oid;
+
+	cl_git_pass(git_reference_name_to_id(&oid, repo, "HEAD"));
+	cl_git_fail(git_oid_streq(&oid, KNOWN_COMMIT_IN_BARE_REPO));
+	cl_git_pass(git_revparse_single(&target, repo, KNOWN_COMMIT_IN_BARE_REPO));
+
+	cl_assert(git_repository_head_detached(repo) == should_be_detached);
+
+	cl_git_pass(git_reset(repo, target, GIT_RESET_SOFT, NULL));
+
+	cl_assert(git_repository_head_detached(repo) == should_be_detached);
+
+	cl_git_pass(git_reference_name_to_id(&oid, repo, "HEAD"));
+	cl_git_pass(git_oid_streq(&oid, KNOWN_COMMIT_IN_BARE_REPO));
+}
+
+void test_reset_soft__can_reset_the_non_detached_Head_to_the_specified_commit(void)
+{
+	assert_reset_soft(false);
+}
+
+void test_reset_soft__can_reset_the_detached_Head_to_the_specified_commit(void)
+{
+	git_repository_detach_head(repo);
+
+	assert_reset_soft(true);
+}
+
+void test_reset_soft__resetting_to_the_commit_pointed_at_by_the_Head_does_not_change_the_target_of_the_Head(void)
+{
+	git_oid oid;
+	char raw_head_oid[GIT_OID_HEXSZ + 1];
+
+	cl_git_pass(git_reference_name_to_id(&oid, repo, "HEAD"));
+	git_oid_fmt(raw_head_oid, &oid);
+	raw_head_oid[GIT_OID_HEXSZ] = '\0';
+
+	cl_git_pass(git_revparse_single(&target, repo, raw_head_oid));
+
+	cl_git_pass(git_reset(repo, target, GIT_RESET_SOFT, NULL));
+
+	cl_git_pass(git_reference_name_to_id(&oid, repo, "HEAD"));
+	cl_git_pass(git_oid_streq(&oid, raw_head_oid));
+}
+
+void test_reset_soft__resetting_to_a_tag_sets_the_Head_to_the_peeled_commit(void)
+{
+	git_oid oid;
+
+	/* b25fa35 is a tag, pointing to another tag which points to commit e90810b */
+	cl_git_pass(git_revparse_single(&target, repo, "b25fa35"));
+
+	cl_git_pass(git_reset(repo, target, GIT_RESET_SOFT, NULL));
+
+	cl_assert(git_repository_head_detached(repo) == false);
+	cl_git_pass(git_reference_name_to_id(&oid, repo, "HEAD"));
+	cl_git_pass(git_oid_streq(&oid, KNOWN_COMMIT_IN_BARE_REPO));
+}
+
+void test_reset_soft__cannot_reset_to_a_tag_not_pointing_at_a_commit(void)
+{
+	/* 53fc32d is the tree of commit e90810b */
+	cl_git_pass(git_revparse_single(&target, repo, "53fc32d"));
+
+	cl_git_fail(git_reset(repo, target, GIT_RESET_SOFT, NULL));
+	git_object_free(target);
+
+	/* 521d87c is an annotated tag pointing to a blob */
+	cl_git_pass(git_revparse_single(&target, repo, "521d87c"));
+	cl_git_fail(git_reset(repo, target, GIT_RESET_SOFT, NULL));
+}
+
+void test_reset_soft__resetting_against_an_unborn_head_repo_makes_the_head_no_longer_unborn(void)
+{
+	git_reference *head;
+
+	cl_git_pass(git_revparse_single(&target, repo, KNOWN_COMMIT_IN_BARE_REPO));
+
+	make_head_unborn(repo, NON_EXISTING_HEAD);
+
+	cl_assert_equal_i(true, git_repository_head_unborn(repo));
+
+	cl_git_pass(git_reset(repo, target, GIT_RESET_SOFT, NULL));
+
+	cl_assert_equal_i(false, git_repository_head_unborn(repo));
+
+	cl_git_pass(git_reference_lookup(&head, repo, NON_EXISTING_HEAD));
+	cl_assert_equal_i(0, git_oid_streq(git_reference_target(head), KNOWN_COMMIT_IN_BARE_REPO));
+
+	git_reference_free(head);
+}
+
+void test_reset_soft__fails_when_merging(void)
+{
+	git_buf merge_head_path = GIT_BUF_INIT;
+
+	cl_git_pass(git_repository_detach_head(repo));
+	cl_git_pass(git_buf_joinpath(&merge_head_path, git_repository_path(repo), "MERGE_HEAD"));
+	cl_git_mkfile(git_buf_cstr(&merge_head_path), "beefbeefbeefbeefbeefbeefbeefbeefbeefbeef\n");
+
+	cl_git_pass(git_revparse_single(&target, repo, KNOWN_COMMIT_IN_BARE_REPO));
+
+	cl_assert_equal_i(GIT_EUNMERGED, git_reset(repo, target, GIT_RESET_SOFT, NULL));
+	cl_git_pass(p_unlink(git_buf_cstr(&merge_head_path)));
+
+	git_buf_free(&merge_head_path);
+}
+
+void test_reset_soft__fails_when_index_contains_conflicts_independently_of_MERGE_HEAD_file_existence(void)
+{
+	git_index *index;
+	git_reference *head;
+	git_buf merge_head_path = GIT_BUF_INIT;
+
+	cl_git_sandbox_cleanup();
+
+	repo = cl_git_sandbox_init("mergedrepo");
+
+	cl_git_pass(git_buf_joinpath(&merge_head_path, git_repository_path(repo), "MERGE_HEAD"));
+	cl_git_pass(p_unlink(git_buf_cstr(&merge_head_path)));
+	git_buf_free(&merge_head_path);
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_assert_equal_i(true, git_index_has_conflicts(index));
+	git_index_free(index);
+
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_peel(&target, head, GIT_OBJ_COMMIT));
+	git_reference_free(head);
+
+	cl_assert_equal_i(GIT_EUNMERGED, git_reset(repo, target, GIT_RESET_SOFT, NULL));
+}
+
+void test_reset_soft__reflog_is_correct(void)
+{
+	git_annotated_commit *annotated;
+	const char *exp_msg = "checkout: moving from br2 to master";
+	const char *master_msg = "commit: checking in";
+
+	reflog_check(repo, "HEAD", 7, "yoram.harmelin at gmail.com", exp_msg);
+	reflog_check(repo, "refs/heads/master", 2, "yoram.harmelin at gmail.com", master_msg);
+
+	/* Branch not moving, no reflog entry */
+	cl_git_pass(git_revparse_single(&target, repo, "HEAD^{commit}"));
+	cl_git_pass(git_reset(repo, target, GIT_RESET_SOFT, NULL));
+	reflog_check(repo, "HEAD", 7, "yoram.harmelin at gmail.com", exp_msg);
+	reflog_check(repo, "refs/heads/master", 2, "yoram.harmelin at gmail.com", master_msg);
+	git_object_free(target);
+
+	/* Moved branch, expect id in message */
+	exp_msg = "reset: moving to be3563ae3f795b2b4353bcce3a527ad0a4f7f644";
+	cl_git_pass(git_revparse_single(&target, repo, "HEAD~^{commit}"));
+	cl_git_pass(git_reset(repo, target, GIT_RESET_SOFT, NULL));
+	reflog_check(repo, "HEAD", 8, "yoram.harmelin at gmail.com", exp_msg);
+	reflog_check(repo, "refs/heads/master", 3, NULL, exp_msg);
+
+	/* Moved branch, expect message with annotated string */
+	exp_msg = "reset: moving to HEAD~^{commit}";
+	cl_git_pass(git_annotated_commit_from_revspec(&annotated, repo, "HEAD~^{commit}"));
+	cl_git_pass(git_reset_from_annotated(repo, annotated, GIT_RESET_SOFT, NULL));
+	reflog_check(repo, "HEAD", 9, "yoram.harmelin at gmail.com", exp_msg);
+	reflog_check(repo, "refs/heads/master", 4, NULL, exp_msg);
+
+	git_annotated_commit_free(annotated);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/.gitattributes b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/.gitattributes
new file mode 100755
index 0000000..556f8c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/.gitattributes
@@ -0,0 +1 @@
+* binary
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/.gitignore b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/.gitignore
new file mode 100755
index 0000000..43a19cc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/.gitignore
@@ -0,0 +1 @@
+discover.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/config
new file mode 100755
index 0000000..af10792
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/config
@@ -0,0 +1,6 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/index
new file mode 100755
index 0000000..439ffb1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/info/attributes b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/info/attributes
new file mode 100755
index 0000000..5fe62a3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/info/attributes
@@ -0,0 +1,4 @@
+* repoattr
+a*	foo !bar -baz
+sub/*.txt reposub
+sub/sub/*.txt reposubsub
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/logs/HEAD
new file mode 100755
index 0000000..8ece39f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/logs/HEAD
@@ -0,0 +1,9 @@
+0000000000000000000000000000000000000000 6bab5c79cd5140d0f800917f550eb2a3dc32b0da Russell Belfer <arrbee at arrbee.com> 1324416995 -0800	commit (initial): initial test data
+6bab5c79cd5140d0f800917f550eb2a3dc32b0da 605812ab7fe421fdd325a935d35cb06a9234a7d7 Russell Belfer <arrbee at arrbee.com> 1325143098 -0800	commit: latest test updates
+605812ab7fe421fdd325a935d35cb06a9234a7d7 a5d76cad53f66f1312bd995909a5bab3c0820770 Russell Belfer <arrbee at arrbee.com> 1325281762 -0800	commit: more macro tests
+a5d76cad53f66f1312bd995909a5bab3c0820770 370fe9ec224ce33e71f9e5ec2bd1142ce9937a6a Russell Belfer <arrbee at arrbee.com> 1327611749 -0800	commit: Updating files so we can do diffs
+370fe9ec224ce33e71f9e5ec2bd1142ce9937a6a f5b0af1fb4f5c0cd7aad880711d368a07333c307 Russell Belfer <arrbee at arrbee.com> 1327621027 -0800	commit: Updating test data
+f5b0af1fb4f5c0cd7aad880711d368a07333c307 a97cc019851d401a4f1d091cb91a15890a0dd1ba Russell Belfer <arrbee at arrbee.com> 1328653313 -0800	commit: Some whitespace only changes for testing purposes
+a97cc019851d401a4f1d091cb91a15890a0dd1ba 217878ab49e1314388ea2e32dc6fdb58a1b969e0 Russell Belfer <arrbee at arrbee.com> 1332734901 -0700	commit: added files in sub/sub
+217878ab49e1314388ea2e32dc6fdb58a1b969e0 24fa9a9fc4e202313e24b648087495441dab432b Russell Belfer <arrbee at arrbee.com> 1332735555 -0700	commit: adding more files in sub for tree status
+24fa9a9fc4e202313e24b648087495441dab432b 8d0b9df9bd30be7910ddda60548d485bc302b911 yorah <yoram.harmelin at gmail.com> 1341230701 +0200	commit: Updating test data so we can test inter-hunk-context
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..8ece39f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/logs/refs/heads/master
@@ -0,0 +1,9 @@
+0000000000000000000000000000000000000000 6bab5c79cd5140d0f800917f550eb2a3dc32b0da Russell Belfer <arrbee at arrbee.com> 1324416995 -0800	commit (initial): initial test data
+6bab5c79cd5140d0f800917f550eb2a3dc32b0da 605812ab7fe421fdd325a935d35cb06a9234a7d7 Russell Belfer <arrbee at arrbee.com> 1325143098 -0800	commit: latest test updates
+605812ab7fe421fdd325a935d35cb06a9234a7d7 a5d76cad53f66f1312bd995909a5bab3c0820770 Russell Belfer <arrbee at arrbee.com> 1325281762 -0800	commit: more macro tests
+a5d76cad53f66f1312bd995909a5bab3c0820770 370fe9ec224ce33e71f9e5ec2bd1142ce9937a6a Russell Belfer <arrbee at arrbee.com> 1327611749 -0800	commit: Updating files so we can do diffs
+370fe9ec224ce33e71f9e5ec2bd1142ce9937a6a f5b0af1fb4f5c0cd7aad880711d368a07333c307 Russell Belfer <arrbee at arrbee.com> 1327621027 -0800	commit: Updating test data
+f5b0af1fb4f5c0cd7aad880711d368a07333c307 a97cc019851d401a4f1d091cb91a15890a0dd1ba Russell Belfer <arrbee at arrbee.com> 1328653313 -0800	commit: Some whitespace only changes for testing purposes
+a97cc019851d401a4f1d091cb91a15890a0dd1ba 217878ab49e1314388ea2e32dc6fdb58a1b969e0 Russell Belfer <arrbee at arrbee.com> 1332734901 -0700	commit: added files in sub/sub
+217878ab49e1314388ea2e32dc6fdb58a1b969e0 24fa9a9fc4e202313e24b648087495441dab432b Russell Belfer <arrbee at arrbee.com> 1332735555 -0700	commit: adding more files in sub for tree status
+24fa9a9fc4e202313e24b648087495441dab432b 8d0b9df9bd30be7910ddda60548d485bc302b911 yorah <yoram.harmelin at gmail.com> 1341230701 +0200	commit: Updating test data so we can test inter-hunk-context
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/10/8bb4e7fd7b16490dc33ff7d972151e73d7166e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/10/8bb4e7fd7b16490dc33ff7d972151e73d7166e
new file mode 100755
index 0000000..edcf752
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/10/8bb4e7fd7b16490dc33ff7d972151e73d7166e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/16/983da6643656bb44c43965ecb6855c6d574512 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/16/983da6643656bb44c43965ecb6855c6d574512
new file mode 100755
index 0000000..e49c94a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/16/983da6643656bb44c43965ecb6855c6d574512 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/21/7878ab49e1314388ea2e32dc6fdb58a1b969e0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/21/7878ab49e1314388ea2e32dc6fdb58a1b969e0
new file mode 100755
index 0000000..b537899
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/21/7878ab49e1314388ea2e32dc6fdb58a1b969e0
@@ -0,0 +1,4 @@
+xŽQ
+Â0DýÎ)öên“ØDÄ#xƒmvƒ…ÖJ’Þ߀7ðcx0¼IÛºÎ
­¨‚óž-¹ÌÁñ+e"¼vù‚Á‡œâ˜ùpÑwŽcJH1x‡Ô%Œ”¦HL>Dd¡‰
ïíµxîµê²ÀC—¬®\ʤzÿᔶõdí0Z‘àˆ#¢émÿغþÏÚ°ˆ
+äyÑ
+óê>{Ì–qK²
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/24/fa9a9fc4e202313e24b648087495441dab432b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/24/fa9a9fc4e202313e24b648087495441dab432b
new file mode 100755
index 0000000..e7099bb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/24/fa9a9fc4e202313e24b648087495441dab432b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/29/29de282ce999e95183aedac6451d3384559c4b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/29/29de282ce999e95183aedac6451d3384559c4b
new file mode 100755
index 0000000..ad84f08
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/29/29de282ce999e95183aedac6451d3384559c4b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/2b/40c5aca159b04ea8d20ffe36cdf8b09369b14a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/2b/40c5aca159b04ea8d20ffe36cdf8b09369b14a
new file mode 100755
index 0000000..0e23680
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/2b/40c5aca159b04ea8d20ffe36cdf8b09369b14a
@@ -0,0 +1 @@
+xmPÑj„0ì«ùŠ=úP8Z…ÞS¾¤”c£ñhR6{=¼¯obâ™Ò"šÙafvŒšœ‚÷×æéä#3‰ά=7Pÿ%[8<Heì`&]@?aFZª®ªç@!…÷.ÊÈù:±ù½§…•ldðÚLG­|K’7~XÃN8¤˜·IÏdìê}¿øˆqŸó2cG¾œ7l¾5ÔV_pEûŸ®’#lZ´ŽGMòt[JÌÈͽ¥&©h¸±uÌ][‰Öß4‰-3;ËCˆg˜4¿x`ZÀ»YÃŒ“錻ú€bÝ^>ïyNlÍ£¡>c¯;gӐ•¥kÇYXÄ9b|Dª~VØ—)…v¿øñÎÜ•
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/2c/66e14f77196ea763fb1e41612c1aa2bc2d8ed2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/2c/66e14f77196ea763fb1e41612c1aa2bc2d8ed2
new file mode 100755
index 0000000..4b75d50
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/2c/66e14f77196ea763fb1e41612c1aa2bc2d8ed2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/2d/e7dfe3588f3c7e9ad59e7d50ba90e3329df9d9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/2d/e7dfe3588f3c7e9ad59e7d50ba90e3329df9d9
new file mode 100755
index 0000000..e0fd046
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/2d/e7dfe3588f3c7e9ad59e7d50ba90e3329df9d9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/37/0fe9ec224ce33e71f9e5ec2bd1142ce9937a6a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/37/0fe9ec224ce33e71f9e5ec2bd1142ce9937a6a
new file mode 100755
index 0000000..9c37c59
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/37/0fe9ec224ce33e71f9e5ec2bd1142ce9937a6a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/3a/6df026462ebafe455af9867d27eda20a9e0974 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/3a/6df026462ebafe455af9867d27eda20a9e0974
new file mode 100755
index 0000000..c74add8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/3a/6df026462ebafe455af9867d27eda20a9e0974 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/3b/74db7ab381105dc0d28f8295a77f6a82989292 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/3b/74db7ab381105dc0d28f8295a77f6a82989292
new file mode 100755
index 0000000..e5cef35
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/3b/74db7ab381105dc0d28f8295a77f6a82989292 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/3e/42ffc54a663f9401cc25843d6c0e71a33e4249 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/3e/42ffc54a663f9401cc25843d6c0e71a33e4249
new file mode 100755
index 0000000..091d79b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/3e/42ffc54a663f9401cc25843d6c0e71a33e4249 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/45/141a79a77842c59a63229403220a4e4be74e3d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/45/141a79a77842c59a63229403220a4e4be74e3d
new file mode 100755
index 0000000..5b58ef0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/45/141a79a77842c59a63229403220a4e4be74e3d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/45/5a314fa848d52ae1f11d254da4f60858fc97f4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/45/5a314fa848d52ae1f11d254da4f60858fc97f4
new file mode 100755
index 0000000..f90f0d7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/45/5a314fa848d52ae1f11d254da4f60858fc97f4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057
new file mode 100755
index 0000000..7ca4cee
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/4d/713dc48e6b1bd75b0d61ad078ba9ca3a56745d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/4d/713dc48e6b1bd75b0d61ad078ba9ca3a56745d
new file mode 100755
index 0000000..eb1e8d0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/4d/713dc48e6b1bd75b0d61ad078ba9ca3a56745d
@@ -0,0 +1,2 @@
+xÁÁ
€ @ßWŶàÇ
+|ø§k 9n$¡}gŠ«à:‡îÂ;5°1¥e–4ˆ\k_]‘ÞƒŸÙ­hœD¡k›ý'~
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/4e/49ba8c5b6c32ff28cd9dcb60be34df50fcc485 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/4e/49ba8c5b6c32ff28cd9dcb60be34df50fcc485
new file mode 100755
index 0000000..6fcc549
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/4e/49ba8c5b6c32ff28cd9dcb60be34df50fcc485 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/55/6f8c827b8e4a02ad5cab77dca2bcb3e226b0b3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/55/6f8c827b8e4a02ad5cab77dca2bcb3e226b0b3
new file mode 100755
index 0000000..4bcff1f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/55/6f8c827b8e4a02ad5cab77dca2bcb3e226b0b3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/58/19a185d77b03325aaf87cafc771db36f6ddca7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/58/19a185d77b03325aaf87cafc771db36f6ddca7
new file mode 100755
index 0000000..fe34eb6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/58/19a185d77b03325aaf87cafc771db36f6ddca7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/60/5812ab7fe421fdd325a935d35cb06a9234a7d7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/60/5812ab7fe421fdd325a935d35cb06a9234a7d7
new file mode 100755
index 0000000..b0cc51e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/60/5812ab7fe421fdd325a935d35cb06a9234a7d7
@@ -0,0 +1,2 @@
+xNÛ
Â0ã;SÜ Ë»•BŒÀ—ËU ¥´JÓý	°?¶lÙ–y™çgcáU RbaâÙcG;¸l²ã DqÖ Z©Ê«AH”<Ç‘³×3Nâ¨ãä=J2d3[“0“¢½=–
+÷}Û¤¸I™¤Â™jM"םx™/ ­é[ÇŽØçTwûÇÖãÿ´U¡&[ƒ/ìkþ(õtJL
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/6b/ab5c79cd5140d0f800917f550eb2a3dc32b0da b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/6b/ab5c79cd5140d0f800917f550eb2a3dc32b0da
new file mode 100755
index 0000000..f51e11c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/6b/ab5c79cd5140d0f800917f550eb2a3dc32b0da
@@ -0,0 +1,3 @@
+xÛ	Ã0Eûí)´@‹d'~@(¥#tÅQ¨ÁiÀQö¯¡ôëÂánÞ·­(Pôm"Ř2æh°sL+d{—"{Zœ“`øÔ÷Þàu‡Ô
+O©«4˜¸µYäñ›[Þ·;³Ã@>¥®M§ýS»þOmʧhá
+*‡ÂÂÊæ¿<-
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/6d/968d62c89c7d9ea23a4c9a7b665d017c3d8ffd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/6d/968d62c89c7d9ea23a4c9a7b665d017c3d8ffd
new file mode 100755
index 0000000..e832241
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/6d/968d62c89c7d9ea23a4c9a7b665d017c3d8ffd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/71/7fc31f6b84f9d6fc3a4edbca259d7fc92beee2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/71/7fc31f6b84f9d6fc3a4edbca259d7fc92beee2
new file mode 100755
index 0000000..a80265c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/71/7fc31f6b84f9d6fc3a4edbca259d7fc92beee2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/8d/0b9df9bd30be7910ddda60548d485bc302b911 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/8d/0b9df9bd30be7910ddda60548d485bc302b911
new file mode 100755
index 0000000..3dcf088
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/8d/0b9df9bd30be7910ddda60548d485bc302b911
@@ -0,0 +1 @@
+xŽKj1D³Ö)zolôiõŒ _"hiÚK2²L’ÛG!7Ȫ¯¨ÔJÉ,ù—ÑEÀPXÝÆDèÈSŒˆ	] /)Òê}¢Í/èUwîR§ˆ.	Åj댋‘pÕë‚Á#š#:?ÇÞ:|·Î;¼þF9íÜ‹Ür=_çÛ)µòÆ¡±N/ÚÀA[­ÕlçÃ!ÿqÕû}ã‘ë†<Lfx4øH\ÿº\çôq֏cj“¿†úƒTè
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/93/61f40bb97239cf55811892e14de2e344168ba1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/93/61f40bb97239cf55811892e14de2e344168ba1
new file mode 100755
index 0000000..4b57836
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/93/61f40bb97239cf55811892e14de2e344168ba1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/94/da4faa0a6bfb8ee6ccf7153801a69202b31857 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/94/da4faa0a6bfb8ee6ccf7153801a69202b31857
new file mode 100755
index 0000000..a9ddf5d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/94/da4faa0a6bfb8ee6ccf7153801a69202b31857 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/96/089fd31ce1d3ee2afb0ba09ba063066932f027 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/96/089fd31ce1d3ee2afb0ba09ba063066932f027
new file mode 100755
index 0000000..efa62f9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/96/089fd31ce1d3ee2afb0ba09ba063066932f027 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/99/eae476896f4907224978b88e5ecaa6c5bb67a9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/99/eae476896f4907224978b88e5ecaa6c5bb67a9
new file mode 100755
index 0000000..8f5acc7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/99/eae476896f4907224978b88e5ecaa6c5bb67a9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/9e/5bdc47d6a80f2be0ea3049ad74231b94609242 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/9e/5bdc47d6a80f2be0ea3049ad74231b94609242
new file mode 100755
index 0000000..d6385ec
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/9e/5bdc47d6a80f2be0ea3049ad74231b94609242 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/9f/b40b6675dde60b5697afceae91b66d908c02d9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/9f/b40b6675dde60b5697afceae91b66d908c02d9
new file mode 100755
index 0000000..7663ad0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/9f/b40b6675dde60b5697afceae91b66d908c02d9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/a0/f7217ae99f5ac3e88534f5cea267febc5fa85b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/a0/f7217ae99f5ac3e88534f5cea267febc5fa85b
new file mode 100755
index 0000000..985c2e2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/a0/f7217ae99f5ac3e88534f5cea267febc5fa85b
@@ -0,0 +1 @@
+x5Ž1Â0E™}Š?–΀;•˜S␈Ԯ’”ŠÛ“Ðv´ýߢ8ŸO‡'FÈÈ:2r™ƒ)(¾
&¢Þ·«×9Z¼A Âð³¼Ñ¹r9Ýl¬
%¨˜ˆ„3ÑEo‚£.ÿV­Õi<BñàF­©MÌb‰®+ÂÙŸ*vµªÛþìÖmõ÷¾¢ÞLK†Ý­D?+­N
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/a5/6bbcecaeac760cc26239384d2d4c614e7e4320 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/a5/6bbcecaeac760cc26239384d2d4c614e7e4320
new file mode 100755
index 0000000..d898ae9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/a5/6bbcecaeac760cc26239384d2d4c614e7e4320 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/a5/d76cad53f66f1312bd995909a5bab3c0820770 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/a5/d76cad53f66f1312bd995909a5bab3c0820770
new file mode 100755
index 0000000..cd6a389
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/a5/d76cad53f66f1312bd995909a5bab3c0820770
@@ -0,0 +1,4 @@
+xŽ]
+‚!E{v³B>!"ZB;u¤à3Cmÿ	í §‡{.7µZŸ4âavfÈÖgBLÊEeP;NQÚ¬BŒLAnŲIÆç ÞÔù5ÁI»)MÑ6Z•œQ[
+h3Úe:
+
ùì}æ£u¸Æà}‡ï…;œ©÷È|ýÅ)µzµ&ô¦¼Óp”›”bÑõq®ú?¶¨­3TJ½Áä1‡ø3ÙJX
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/a9/7cc019851d401a4f1d091cb91a15890a0dd1ba b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/a9/7cc019851d401a4f1d091cb91a15890a0dd1ba
new file mode 100755
index 0000000..1a7ec0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/a9/7cc019851d401a4f1d091cb91a15890a0dd1ba
@@ -0,0 +1,2 @@
+xŽQjÄ0DûíSè[ähc;PJéÚ(²¼	$q°–Þ¾†Þ _3oàIÞ÷µÁàÜK+ªàâäBtƒ„I|œ”â»LìgçƈÖŐR4'=¤qFN6Í÷4
+JôÌ1ôÖFrÑ‘zÃW[r¯«VÝ6øÔ-i7.eVýø‹WÉû;X‚‰,Á
¢émwlÿÏÛ|ç]ṬMëÉ¢ídáã¡RwêC[œW9sÕj~’Wy
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/b4/35cd5689a0fb54afbeda4ac20368aa480e8f04 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/b4/35cd5689a0fb54afbeda4ac20368aa480e8f04
new file mode 100755
index 0000000..ffe3473
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/b4/35cd5689a0fb54afbeda4ac20368aa480e8f04 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/c0/091889c0c77142b87a1fa5123a6398a61d33e7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/c0/091889c0c77142b87a1fa5123a6398a61d33e7
new file mode 100755
index 0000000..11dc63c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/c0/091889c0c77142b87a1fa5123a6398a61d33e7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/c4/85abe35abd4aa6fd83b076a78bbea9e2e7e06c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/c4/85abe35abd4aa6fd83b076a78bbea9e2e7e06c
new file mode 100755
index 0000000..58569ca
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/c4/85abe35abd4aa6fd83b076a78bbea9e2e7e06c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/c7/aadd770d5907a8475c29e9ee21a27b88bf675d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/c7/aadd770d5907a8475c29e9ee21a27b88bf675d
new file mode 100755
index 0000000..39aedb7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/c7/aadd770d5907a8475c29e9ee21a27b88bf675d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/c9/6bbb2c2557a8325ae1559e3ba79cdcecb23076 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/c9/6bbb2c2557a8325ae1559e3ba79cdcecb23076
new file mode 100755
index 0000000..589f9ad
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/c9/6bbb2c2557a8325ae1559e3ba79cdcecb23076
@@ -0,0 +1,2 @@
+x5A
+Â0D]ÿSÌεèoàÂuJ~L0ýͯ¡··)¸xÃcfªœp¹]OOΊcñBµ˜6‘»!뢘´²Ã³‚{,áU<C¿j˜¹[ÁE-ŠÜ-¢Ò˜ð&#š¯)~ëÇäÆ=˜;;{.öùe"3A
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/ce/39a97a7fb1fa90bcf5e711249c1e507476ae0e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/ce/39a97a7fb1fa90bcf5e711249c1e507476ae0e
new file mode 100755
index 0000000..1005f94
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/ce/39a97a7fb1fa90bcf5e711249c1e507476ae0e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/d5/7da33c16b14326ecb05d19bbea908f5e4c47d9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/d5/7da33c16b14326ecb05d19bbea908f5e4c47d9
new file mode 100755
index 0000000..b96d40c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/d5/7da33c16b14326ecb05d19bbea908f5e4c47d9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/d8/00886d9c86731ae5c4a62b0b77c437015e00d2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/d8/00886d9c86731ae5c4a62b0b77c437015e00d2
new file mode 100755
index 0000000..83f3b72
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/d8/00886d9c86731ae5c4a62b0b77c437015e00d2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/dc/cada462d3df8ac6de596fb8c896aba9344f941 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/dc/cada462d3df8ac6de596fb8c896aba9344f941
new file mode 100755
index 0000000..ef62f8b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/dc/cada462d3df8ac6de596fb8c896aba9344f941 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/de/863bff4976c9ed7e17a4da0fd524908dc84049 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/de/863bff4976c9ed7e17a4da0fd524908dc84049
new file mode 100755
index 0000000..7d9b855
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/de/863bff4976c9ed7e17a4da0fd524908dc84049 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/e5/63cf4758f0d646f1b14b76016aa17fa9e549a4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/e5/63cf4758f0d646f1b14b76016aa17fa9e549a4
new file mode 100755
index 0000000..1bc1f0f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/e5/63cf4758f0d646f1b14b76016aa17fa9e549a4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/ec/b97df2a174987475ac816e3847fc8e9f6c596b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/ec/b97df2a174987475ac816e3847fc8e9f6c596b
new file mode 100755
index 0000000..44d703b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/ec/b97df2a174987475ac816e3847fc8e9f6c596b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/ed/f3dcee4003d71f139777898882ccd097e34c53 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/ed/f3dcee4003d71f139777898882ccd097e34c53
new file mode 100755
index 0000000..d281846
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/ed/f3dcee4003d71f139777898882ccd097e34c53 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/f2/c6d717cf4a5a3e6b02684155ab07b766982165 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/f2/c6d717cf4a5a3e6b02684155ab07b766982165
new file mode 100755
index 0000000..27a25dc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/f2/c6d717cf4a5a3e6b02684155ab07b766982165 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/f5/b0af1fb4f5c0cd7aad880711d368a07333c307 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/f5/b0af1fb4f5c0cd7aad880711d368a07333c307
new file mode 100755
index 0000000..21faeb8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/f5/b0af1fb4f5c0cd7aad880711d368a07333c307
@@ -0,0 +1,2 @@
+xN[j1Ì·O¡4ÈRbÇPJÈ
+=€Ö;NûÂë½
½A?†y 1“×y~7½žZ(¾¥2ªÏð£beàÁ8uå’Ja‰n³Š¥‘F.HÈ"—UD_®Ý£÷ÉHI£sv´×ZéûØwL=0Tú´ZàþGç¼Î_äUbßKèƒoÌ®§}cëçÿùv?Ûhí½<©aoÔµ¹_áEK
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/fb/5067b1aef3ac1ada4b379dbcb7d17255df7d78 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/fb/5067b1aef3ac1ada4b379dbcb7d17255df7d78
new file mode 100755
index 0000000..6c8ff83
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/fb/5067b1aef3ac1ada4b379dbcb7d17255df7d78 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/fe/773770c5a6cc7185580c9204b1ff18a33ff3fc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/fe/773770c5a6cc7185580c9204b1ff18a33ff3fc
new file mode 100755
index 0000000..e6fcbc0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/fe/773770c5a6cc7185580c9204b1ff18a33ff3fc
@@ -0,0 +1 @@
+x5ŽAÂ09ûû„xBÜAâœG¤vÕ¤Tüž¤Ð£åõÙ<ûãîÂ#¥Î1ÂUT釛*ÑMúWlÎOCR˜2dÖѵC.„T“©ËÈI¹lQH/öœmYÛ¬UN[àžª€ß¬¬¥þBÖ@t¶Üð8~˜†Õ‹¿}}R#č#kAØdD_=-H–
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/ff/69f8639ce2e6010b3f33a74160aad98b48da2b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/ff/69f8639ce2e6010b3f33a74160aad98b48da2b
new file mode 100755
index 0000000..b736c0b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/objects/ff/69f8639ce2e6010b3f33a74160aad98b48da2b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/refs/heads/master
new file mode 100755
index 0000000..b3abfff
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/.gitted/refs/heads/master
@@ -0,0 +1 @@
+8d0b9df9bd30be7910ddda60548d485bc302b911
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/attr0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/attr0
new file mode 100755
index 0000000..556f8c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/attr0
@@ -0,0 +1 @@
+* binary
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/attr1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/attr1
new file mode 100755
index 0000000..3b74db7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/attr1
@@ -0,0 +1,29 @@
+# a comment followed by some blank lines
+
+
+
+      # another comment that is indented
+
+# variations on fnmatch
+
+pat0 attr0
+!pat1 attr1
+pat2/ attr2
+pat3dir/pat3file attr3
+pat4.* attr4
+       *.pat5 attr5
+pat6/pat6/*.pat6 attr6
+
+pat7[a-e]??[xyz] attr7 # with a comment on the line
+
+pat8\ with\ spaces attr8
+
+   invalid # attr with no assignments doesn't count
+
+also/invalid              
+
+invalid.again/
+
+# next attr is at eof
+
+   pat9 attr9
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/attr2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/attr2
new file mode 100755
index 0000000..2c66e14
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/attr2
@@ -0,0 +1,21 @@
+
+# variations on assignments
+
+pat0 simple
+pat1 -neg
+* notundef
+pat2 !notundef
+pat3 assigned=test-value
+pat4 rule-with-more-chars=value-with-more-chars
+pat5 empty=
+pat6 -negempty=
+pat7 multiple -single values=1 also=a-really-long-value/* happy=yes!
+# the next line has trailing spaces
+pat8 again= another=12321                        
+patbad0 # empty assignment does not count
+# next line will be another simple empty assign that should not count
+            patbad1    
+
+# BTW I think there are 11 valid rules and two "invalid" empty ones
+
+pat9 -at-eof
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/attr3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/attr3
new file mode 100755
index 0000000..c485abe
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/attr3
@@ -0,0 +1,4 @@
+# These are examples from the git-check-attr.1 man page
+*.java diff=java -crlf myAttr
+NoMyAttr.java !myAttr
+README caveat=unspecified
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/binfile b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/binfile
new file mode 100755
index 0000000..d800886
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/binfile
@@ -0,0 +1 @@
+123
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/dir/file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/dir/file
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/file
new file mode 100755
index 0000000..45b983b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/file
@@ -0,0 +1 @@
+hi
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/gitattributes b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/gitattributes
new file mode 100755
index 0000000..e038983
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/gitattributes
@@ -0,0 +1,29 @@
+* rootattr
+root_test2 -rootattr
+root_test3 !rootattr
+binfile	   		   binary
+abc		foo bar baz
+does-not-exist foo=yes
+
+root_test2 multiattr
+root_test3 multi2=foo
+
+root_test3 multiattr=1 multiattr=2 multiattr=3 multi2=abc !multi2
+root_test2 multiattr=string -multiattr
+
+[attr]mymacro positive -negative !rootattr
+macro* mymacro another=77
+
+[attr]macro2 multi2 -multi2 multi3 !multi3 multi3=answer
+macro* macro2 macro2 macro2
+
+# let's try some malicious macro defs
+[attr]firstmacro -thirdmacro -secondmacro
+[attr]secondmacro firstmacro -firstmacro
+[attr]thirdmacro secondmacro=hahaha
+
+macro_bad firstmacro secondmacro thirdmacro
+
+# another test that Peff found was failing
+[attr]notest !test
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/gitignore b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/gitignore
new file mode 100755
index 0000000..1929670
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/gitignore
@@ -0,0 +1,2 @@
+ign
+dir/
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/ign b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/ign
new file mode 100755
index 0000000..592fd25
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/ign
@@ -0,0 +1 @@
+ignore me
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/macro_bad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/macro_bad
new file mode 100755
index 0000000..5819a18
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/macro_bad
@@ -0,0 +1 @@
+boo
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/macro_test b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/macro_test
new file mode 100755
index 0000000..ff69f86
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/macro_test
@@ -0,0 +1 @@
+Yo
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/root_test1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/root_test1
new file mode 100755
index 0000000..45141a7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/root_test1
@@ -0,0 +1 @@
+Hello from the root
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/root_test2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/root_test2
new file mode 100755
index 0000000..4d713dc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/root_test2
@@ -0,0 +1,6 @@
+Hello from the root
+
+Some additional lines
+
+Down here below
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/root_test3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/root_test3
new file mode 100755
index 0000000..108bb4e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/root_test3
@@ -0,0 +1,19 @@
+Some additional lines
+
+
+  Down here below the other lines  
+
+
+With even more at the end
+
+
+And lots of good stuff  
+
+
+Anywhere you want  
+
+
+Don't you think
+
+
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/root_test4.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/root_test4.txt
new file mode 100755
index 0000000..a0f7217
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/root_test4.txt
@@ -0,0 +1,14 @@
+Here is some stuff at the start
+
+This should go in one hunk (first)
+
+Some additional lines
+
+Down here below the other lines
+
+With even more at the end
+
+Followed by a second hunk of stuff (second)
+
+That happens down here
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/.gitattributes b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/.gitattributes
new file mode 100755
index 0000000..329c1c5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/.gitattributes
@@ -0,0 +1,7 @@
+* subattr=yes -negattr
+*.txt     another=zero
+sub/*.txt another=one
+ab*			 merge=filfre
+abc			 -foo -bar
+*.c			 frotz
+deep/file	 deepdeep
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/abc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/abc
new file mode 100755
index 0000000..3e42ffc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/abc
@@ -0,0 +1,37 @@
+# Test file from gitattributes(5) example:
+
+If you have these three gitattributes file:
+
+   (in $GIT_DIR/info/attributes)
+
+	a*      foo !bar -baz
+
+	(in .gitattributes)
+	abc     foo bar baz
+
+	(in t/.gitattributes)
+	ab*     merge=filfre
+	abc     -foo -bar
+	*.c     frotz
+
+the attributes given to path t/abc are computed as follows:
+
+1. By examining t/.gitattributes (which is in the same directory as the path
+   in question), git finds that the first line matches. merge attribute is
+   set. It also finds that the second line matches, and attributes foo and
+   bar are unset.
+2. Then it examines .gitattributes (which is in the parent directory), and
+   finds that the first line matches, but t/.gitattributes file already
+   decided how merge, foo and bar attributes should be given to this path,
+   so it leaves foo and bar unset. Attribute baz is set.
+3. Finally it examines $GIT_DIR/info/attributes. This file is used to
+   override the in-tree settings. The first line is a match, and foo is set,
+   bar is reverted to unspecified state, and baz is unset.
+
+As the result, the attributes assignment to t/abc becomes:
+
+	foo     set to true
+	bar     unspecified
+	baz     set to false
+	merge   set to string value "filfre"
+	frotz   unspecified
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/dir/file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/dir/file
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/file
new file mode 100755
index 0000000..45b983b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/file
@@ -0,0 +1 @@
+hi
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/ign/file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/ign/file
new file mode 100755
index 0000000..4dcd992
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/ign/file
@@ -0,0 +1 @@
+in ignored dir
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/ign/sub/file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/ign/sub/file
new file mode 100755
index 0000000..88aca01
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/ign/sub/file
@@ -0,0 +1 @@
+below ignored dir
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/sub/.gitattributes b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/sub/.gitattributes
new file mode 100755
index 0000000..55225e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/sub/.gitattributes
@@ -0,0 +1,3 @@
+d/*   test=a/b/d/*
+d/yes notest
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/sub/dir b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/sub/dir
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/sub/file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/sub/file
new file mode 100755
index 0000000..45b983b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/sub/file
@@ -0,0 +1 @@
+hi
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/sub/subsub.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/sub/subsub.txt
new file mode 100755
index 0000000..9e5bdc4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/sub/subsub.txt
@@ -0,0 +1 @@
+subsub
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/subdir_test1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/subdir_test1
new file mode 100755
index 0000000..e563cf4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/subdir_test1
@@ -0,0 +1,2 @@
+Hello from the subdir
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/subdir_test2.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/subdir_test2.txt
new file mode 100755
index 0000000..fb5067b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr/sub/subdir_test2.txt
@@ -0,0 +1 @@
+Hello again
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/config
new file mode 100755
index 0000000..af10792
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/config
@@ -0,0 +1,6 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/index
new file mode 100755
index 0000000..d874803
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/info/refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/info/refs
new file mode 100755
index 0000000..60feca2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/info/refs
@@ -0,0 +1 @@
+58f7cf825b553ef7c26e5b9f8a23599c1a9ca296	refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/logs/HEAD
new file mode 100755
index 0000000..ffd298c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/logs/HEAD
@@ -0,0 +1,4 @@
+0000000000000000000000000000000000000000 67c1640e91ccbaf0793591be09bf572cf40c9a53 Russell Belfer <rb at github.com> 1335817070 -0700	commit (initial): Initial commit
+67c1640e91ccbaf0793591be09bf572cf40c9a53 d441d7d88f52c28c2b23940ce4c33756748425f9 Russell Belfer <rb at github.com> 1335817296 -0700	commit: Adding some files in subtrees
+d441d7d88f52c28c2b23940ce4c33756748425f9 67c1640e91ccbaf0793591be09bf572cf40c9a53 Russell Belfer <rb at github.com> 1335817353 -0700	HEAD^: updating HEAD
+67c1640e91ccbaf0793591be09bf572cf40c9a53 58f7cf825b553ef7c26e5b9f8a23599c1a9ca296 Russell Belfer <rb at github.com> 1335817372 -0700	commit: Adding subtree data
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..ffd298c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/logs/refs/heads/master
@@ -0,0 +1,4 @@
+0000000000000000000000000000000000000000 67c1640e91ccbaf0793591be09bf572cf40c9a53 Russell Belfer <rb at github.com> 1335817070 -0700	commit (initial): Initial commit
+67c1640e91ccbaf0793591be09bf572cf40c9a53 d441d7d88f52c28c2b23940ce4c33756748425f9 Russell Belfer <rb at github.com> 1335817296 -0700	commit: Adding some files in subtrees
+d441d7d88f52c28c2b23940ce4c33756748425f9 67c1640e91ccbaf0793591be09bf572cf40c9a53 Russell Belfer <rb at github.com> 1335817353 -0700	HEAD^: updating HEAD
+67c1640e91ccbaf0793591be09bf572cf40c9a53 58f7cf825b553ef7c26e5b9f8a23599c1a9ca296 Russell Belfer <rb at github.com> 1335817372 -0700	commit: Adding subtree data
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/38/12cfef36615db1788d4e63f90028007e17a348 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/38/12cfef36615db1788d4e63f90028007e17a348
new file mode 100755
index 0000000..ee29915
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/38/12cfef36615db1788d4e63f90028007e17a348
@@ -0,0 +1,3 @@
+x•Ž[
+Ã Eûí*Ü@‹ŽPJé
+]€š™&“`Ìþëúw¸œ'o¥ÌM¸K«D’ ‚q•4¤ÊËì5DFË#šä!!ˆ=VZ›DÏ.³Lˆ†:ƒ%L}ƒ!dCŽ¬ˆg›¶*ßçqвÈ-LUÞkz~ç6é–·òÚ«íàWå”}í}­«ÿ>ÅgË¾Õ{fžâú%ñ¡Gò
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/59/d942b8be2784bc96db9b22202c10815c9a077b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/59/d942b8be2784bc96db9b22202c10815c9a077b
new file mode 100755
index 0000000..ff33737
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/59/d942b8be2784bc96db9b22202c10815c9a077b
@@ -0,0 +1 @@
+x
ÃÑ	€0@¿âÍà‡“¸@kR”’@ßÂ]½ã<¶K4±ÜnÕÔÅY‰á)l(a¨hF˜Hcƒcÿ^ԏ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/cd/f17ea3fe625ef812f4dce7f423f4f299287505 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/cd/f17ea3fe625ef812f4dce7f423f4f299287505
new file mode 100755
index 0000000..2a41005
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/cd/f17ea3fe625ef812f4dce7f423f4f299287505 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/f7/2502ddd01412bb20796ff812af56fd53b82b52 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/f7/2502ddd01412bb20796ff812af56fd53b82b52
new file mode 100755
index 0000000..0489280
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/f7/2502ddd01412bb20796ff812af56fd53b82b52 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/info/packs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/info/packs
new file mode 100755
index 0000000..559dc74
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/info/packs
@@ -0,0 +1,2 @@
+P pack-4e6438607204ce78827e3885594b2c0bb4f13895.pack
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/pack/pack-4e6438607204ce78827e3885594b2c0bb4f13895.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/pack/pack-4e6438607204ce78827e3885594b2c0bb4f13895.idx
new file mode 100755
index 0000000..fbef4aa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/pack/pack-4e6438607204ce78827e3885594b2c0bb4f13895.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/pack/pack-4e6438607204ce78827e3885594b2c0bb4f13895.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/pack/pack-4e6438607204ce78827e3885594b2c0bb4f13895.pack
new file mode 100755
index 0000000..09c9e06
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/objects/pack/pack-4e6438607204ce78827e3885594b2c0bb4f13895.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/packed-refs
new file mode 100755
index 0000000..6b3e4de
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+58f7cf825b553ef7c26e5b9f8a23599c1a9ca296 refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/refs/heads/master
new file mode 100755
index 0000000..9b75629
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/.gitted/refs/heads/master
@@ -0,0 +1 @@
+3812cfef36615db1788d4e63f90028007e17a348
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/README.md b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/README.md
new file mode 100755
index 0000000..59d942b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/README.md
@@ -0,0 +1 @@
+This is contains tests for when the index and work dir differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/README.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/README.txt
new file mode 100755
index 0000000..874c12b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/README.txt
@@ -0,0 +1 @@
+This contains files for testing when the index and the workdir differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/gitattributes b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/gitattributes
new file mode 100755
index 0000000..cdf17ea
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/gitattributes
@@ -0,0 +1,4 @@
+* bar
+*.txt -foo beep=10
+*.md blargh=goop -bar
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/sub/sub/.gitattributes b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/sub/sub/.gitattributes
new file mode 100755
index 0000000..060c9a2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/sub/sub/.gitattributes
@@ -0,0 +1,3 @@
+*.txt another=one again
+*.md bar=1234
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/sub/sub/README.md b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/sub/sub/README.md
new file mode 100755
index 0000000..59652e3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/sub/sub/README.md
@@ -0,0 +1 @@
+More testing
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/sub/sub/README.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/sub/sub/README.txt
new file mode 100755
index 0000000..59652e3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/attr_index/sub/sub/README.txt
@@ -0,0 +1 @@
+More testing
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad.index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad.index
new file mode 100755
index 0000000..5374654
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad.index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/config
new file mode 100755
index 0000000..2f89580
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/config
@@ -0,0 +1,5 @@
+[core]
+        repositoryformatversion = 0
+        filemode = true
+        bare = true
+        logallrefupdates = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/objects/pack/pack-7a28f4e000a17f49a41d7a79fc2f762a8a7d9164.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/objects/pack/pack-7a28f4e000a17f49a41d7a79fc2f762a8a7d9164.idx
new file mode 100755
index 0000000..c404aa1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/objects/pack/pack-7a28f4e000a17f49a41d7a79fc2f762a8a7d9164.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/objects/pack/pack-7a28f4e000a17f49a41d7a79fc2f762a8a7d9164.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/objects/pack/pack-7a28f4e000a17f49a41d7a79fc2f762a8a7d9164.pack
new file mode 100755
index 0000000..90eac50
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/objects/pack/pack-7a28f4e000a17f49a41d7a79fc2f762a8a7d9164.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/packed-refs
new file mode 100755
index 0000000..9da1645
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/packed-refs
@@ -0,0 +1,5 @@
+# pack-refs with: peeled 
+eda9f45a2a98d4c17a09d681d88569fa4ea91755 refs/tags/e90810b
+^e90810b8df3e80c413d903f631643c716887138d
+d3bacb8d3ff25876a961b1963b6515170d0151ab refs/tags/hello
+^6dcf9bf7541ee10456529833502442f385010c3d
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/refs/dummy-marker.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/bad_tag.git/refs/dummy-marker.txt
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/big.index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/big.index
new file mode 100755
index 0000000..66932f1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/big.index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/config
new file mode 100755
index 0000000..f9845fe
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/config
@@ -0,0 +1,6 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	autocrlf = true
+	logallrefupdates = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/index
new file mode 100755
index 0000000..a216d22
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/info/refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/info/refs
new file mode 100755
index 0000000..128eea7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/info/refs
@@ -0,0 +1,3 @@
+39e046d1416a208265b754124d0d197b4c9c0c47	refs/heads/branch1
+9e7d8bcd4d24dd57e3f1179aaf7afe648ff50e80	refs/heads/branch2
+d2a291469f4c11f387600d189313b927ddfe891c	refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/objects/info/packs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/objects/info/packs
new file mode 100755
index 0000000..c2de8f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/objects/info/packs
@@ -0,0 +1,2 @@
+P pack-c5bfca875b4995d7aba6e5abf36241f3c397327d.pack
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/objects/pack/pack-c5bfca875b4995d7aba6e5abf36241f3c397327d.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/objects/pack/pack-c5bfca875b4995d7aba6e5abf36241f3c397327d.idx
new file mode 100755
index 0000000..8a05b2b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/objects/pack/pack-c5bfca875b4995d7aba6e5abf36241f3c397327d.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/objects/pack/pack-c5bfca875b4995d7aba6e5abf36241f3c397327d.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/objects/pack/pack-c5bfca875b4995d7aba6e5abf36241f3c397327d.pack
new file mode 100755
index 0000000..6b5ddc4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/objects/pack/pack-c5bfca875b4995d7aba6e5abf36241f3c397327d.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/refs/heads/branch1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/refs/heads/branch1
new file mode 100755
index 0000000..0595fbd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/refs/heads/branch1
@@ -0,0 +1 @@
+39e046d1416a208265b754124d0d197b4c9c0c47
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/refs/heads/branch2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/refs/heads/branch2
new file mode 100755
index 0000000..d868566
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/refs/heads/branch2
@@ -0,0 +1 @@
+9e7d8bcd4d24dd57e3f1179aaf7afe648ff50e80
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/refs/heads/master
new file mode 100755
index 0000000..552d166
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/.gitted/refs/heads/master
@@ -0,0 +1 @@
+d2a291469f4c11f387600d189313b927ddfe891c
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/file.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/file.txt
new file mode 100755
index 0000000..2255035
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/binaryunicode/file.txt
@@ -0,0 +1 @@
+Master branch.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/config
new file mode 100755
index 0000000..c53d818
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/config
@@ -0,0 +1,5 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = true
+	ignorecase = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/0c/bab4d45fd61e55a1c9697f9f9cb07a12e15448 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/0c/bab4d45fd61e55a1c9697f9f9cb07a12e15448
new file mode 100755
index 0000000..90331ce
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/0c/bab4d45fd61e55a1c9697f9f9cb07a12e15448 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/1a/ac69ae5d96461afc4d81d0066cb12f5b05a35b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/1a/ac69ae5d96461afc4d81d0066cb12f5b05a35b
new file mode 100755
index 0000000..7189027
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/1a/ac69ae5d96461afc4d81d0066cb12f5b05a35b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/1b/5f0775af166331c854bd8d1bca3450eaf2532a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/1b/5f0775af166331c854bd8d1bca3450eaf2532a
new file mode 100755
index 0000000..e664306
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/1b/5f0775af166331c854bd8d1bca3450eaf2532a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/48/2f2c370e35c2c314fc1f96db2beb33f955a26a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/48/2f2c370e35c2c314fc1f96db2beb33f955a26a
new file mode 100755
index 0000000..7da4cf5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/48/2f2c370e35c2c314fc1f96db2beb33f955a26a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/63/d671eb32d250e4a83766ebbc60e818c1e1e93a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/63/d671eb32d250e4a83766ebbc60e818c1e1e93a
new file mode 100755
index 0000000..5f41f29
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/63/d671eb32d250e4a83766ebbc60e818c1e1e93a
@@ -0,0 +1,3 @@
+x•A E]sŠÙu¥Ê@bŒ±GðÀP뢭Azk<ù’—¼Ÿ×y~60­–I³“1S´’=“-6÷FfC.†ìcp½õŠµ,
$b
+¶8MF
+ᨹO!1eïȏò]TqkÓZáV¸··çô¾>žmÚÒ)¯ó49dì-Ñ#ªîm­üg©áw©ºTK@Î
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/63/eb57322e363e18d460da5ea8284f3cd2340b36 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/63/eb57322e363e18d460da5ea8284f3cd2340b36
new file mode 100755
index 0000000..c6c285e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/63/eb57322e363e18d460da5ea8284f3cd2340b36 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/8b/137891791fe96927ad78e64b0aad7bded08bdc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/8b/137891791fe96927ad78e64b0aad7bded08bdc
new file mode 100755
index 0000000..9d8f605
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/8b/137891791fe96927ad78e64b0aad7bded08bdc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/96/679d59cf9f74d69b3c920f258559b5e8c9a18a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/96/679d59cf9f74d69b3c920f258559b5e8c9a18a
new file mode 100755
index 0000000..d716e3b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/96/679d59cf9f74d69b3c920f258559b5e8c9a18a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/98/89d6e5557761aa8e3607e80c874a6dc51ada7c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/98/89d6e5557761aa8e3607e80c874a6dc51ada7c
new file mode 100755
index 0000000..12407f6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/98/89d6e5557761aa8e3607e80c874a6dc51ada7c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/aa/06ecca6c4ad6432ab9313e556ca92ba4bcf9e9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/aa/06ecca6c4ad6432ab9313e556ca92ba4bcf9e9
new file mode 100755
index 0000000..bc13bad
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/aa/06ecca6c4ad6432ab9313e556ca92ba4bcf9e9
@@ -0,0 +1 @@
+x•KÂ0DYçÞu²ã6I%„P9'ÈÇ¡]ô£ÞŸ"NÀÌîI#½‰ë<O4ᩈYPè(O.SÛçÔÚÜ	yÉÉ­
FV›/²TH^³å¾C¬“ÆĘÉv¡–£3ìrúÆ+¿×q-0ÈÏZüàÞ÷×TÇ=\â:߀ؠ%tÎÀ¢:èáVå¿•zü.5CóªŠA@
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/b1/76dfc3a4dc8734e4c579f77236a9c8d0a965d2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/b1/76dfc3a4dc8734e4c579f77236a9c8d0a965d2
new file mode 100755
index 0000000..caf5cc1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/b1/76dfc3a4dc8734e4c579f77236a9c8d0a965d2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/b9/0bb887b7c03750ae6b352ffe76ab9d2e86ee7d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/b9/0bb887b7c03750ae6b352ffe76ab9d2e86ee7d
new file mode 100755
index 0000000..d4f9cca
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/b9/0bb887b7c03750ae6b352ffe76ab9d2e86ee7d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/b9/9f7ac0b88909253d829554c14af488c3b0f3a5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/b9/9f7ac0b88909253d829554c14af488c3b0f3a5
new file mode 100755
index 0000000..a428fd6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/b9/9f7ac0b88909253d829554c14af488c3b0f3a5
@@ -0,0 +1,2 @@
+x•ŽK
+1]ç½›•ÒIg2Yˆˆâ	<A>­3‹L vîoÀ¸{õR-eÐΤ1ƒ#ŽóBÆ0©}¶s˜9xãí‹R6d1’S¡ËZÜx‡§´Ð#œãçúÞdíñ”j¹€&‡‹F§
Ñ#ªAGKø?KݧÇôgõ2r
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/bc/7c5ac2bafe828a68e9d1d460343718d6fbe136 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/bc/7c5ac2bafe828a68e9d1d460343718d6fbe136
new file mode 100755
index 0000000..4e6ad15
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/bc/7c5ac2bafe828a68e9d1d460343718d6fbe136
@@ -0,0 +1,3 @@
+x•AnÃ0{Ö+tË))J´AÛ<!/ eºÉÁqàÊÿ¯¢Èu±³Àl[æùÞc*òÖW÷èÅ26t-DS¨V5C2ÀŠN#§Lá©«?zdy at 7Jc*àY+
ÌnÖ¼bݧЅô¿¯
+ì­)·¬#gJjBH^
+7•dš­Mâtë·e_þˆ×¾êfñd?ß÷~Ûì½-ó9"1BPžî.Ý_£Âåï‚Ãç!ü&íO
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/cf/e0e1e1e3ba18f149fd47f5e1aef6016b2260c3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/cf/e0e1e1e3ba18f149fd47f5e1aef6016b2260c3
new file mode 100755
index 0000000..2048e81
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/cf/e0e1e1e3ba18f149fd47f5e1aef6016b2260c3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/d0/67729932057cdb7527a833d6799c4ddc520640 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/d0/67729932057cdb7527a833d6799c4ddc520640
new file mode 100755
index 0000000..926c4bb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/d0/67729932057cdb7527a833d6799c4ddc520640
@@ -0,0 +1 @@
+x+)JMU03c040031QHÔ+©(a˜Ñyíihyâª>3ö<í^¹G¥nÕ@$H­É\;ÍMêo㶜úѬ‹£Ƥ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/da/237394e6132d20d30f175b9b73c8638fddddda b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/da/237394e6132d20d30f175b9b73c8638fddddda
new file mode 100755
index 0000000..e9e1383
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/da/237394e6132d20d30f175b9b73c8638fddddda
@@ -0,0 +1,4 @@
+x•K
+Â0@]÷³ëJ™|'"¢ÞÀ$“ÔvÑVbzžÀíƒïÉ:ÏS­ðÐj)Ñif£Ñ‘äDNSÆdOÌbs§Ñ[ìÞ±–¥Ab(
+¦Y;“ƒfç¬(‚˜„ƒ‰®‹[×
+·²À³Õ¸%8§Ïõ5µqK'Yç(ã‘zF8b@ìvº·µòŸÕÝKý£ÿc–?S
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/e5/b41c1ea533f87388ab69b13baf0b5a562d6243 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/e5/b41c1ea533f87388ab69b13baf0b5a562d6243
new file mode 100755
index 0000000..7e5586c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/e5/b41c1ea533f87388ab69b13baf0b5a562d6243 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/ef/32df4d259143933715c74951f932d9892364d1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/ef/32df4d259143933715c74951f932d9892364d1
new file mode 100755
index 0000000..d021ccf
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/objects/ef/32df4d259143933715c74951f932d9892364d1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/refs/heads/master
new file mode 100755
index 0000000..b763025
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/blametest.git/refs/heads/master
@@ -0,0 +1 @@
+bc7c5ac2bafe828a68e9d1d460343718d6fbe136
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/HEAD
new file mode 100755
index 0000000..656ac0e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/automerge-branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/config
new file mode 100755
index 0000000..6c9406b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/config
@@ -0,0 +1,7 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
+	precomposeunicode = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/index
new file mode 100755
index 0000000..7291006
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/01/a2b453c2647c71ccfefc285f2266d1f00b8253 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/01/a2b453c2647c71ccfefc285f2266d1f00b8253
new file mode 100755
index 0000000..736a7f5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/01/a2b453c2647c71ccfefc285f2266d1f00b8253 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/02/67838e09bbc5969bba035be2d27c8a6de694d8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/02/67838e09bbc5969bba035be2d27c8a6de694d8
new file mode 100755
index 0000000..4eacb26
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/02/67838e09bbc5969bba035be2d27c8a6de694d8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/06/3fc9f01e6e9ec2a8d8f749885e931875e50d37 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/06/3fc9f01e6e9ec2a8d8f749885e931875e50d37
new file mode 100755
index 0000000..48fa6ef
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/06/3fc9f01e6e9ec2a8d8f749885e931875e50d37 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/08/9ac03f76058b5ba0b44bb268f317f9242481e9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/08/9ac03f76058b5ba0b44bb268f317f9242481e9
new file mode 100755
index 0000000..06d1c69
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/08/9ac03f76058b5ba0b44bb268f317f9242481e9
@@ -0,0 +1,3 @@
+x¥ÎA
+Â0@Q×9Å왤“i"î—Þ`L§µB¬MÓ…··àܾÅç§)籂#ÞÕ¢
+^CNØä™”Îb+˜%¸˜¬Š÷¨bÞRôU!õ‰zŒ1Jh¸õ)JO}딼ëƒb½‘µ>¦WIóª\´äqy¬ŸŽÏŸ
祖QªÒ”O`›ÈDÍ6{tˆfÓmµê_sÓy‹‚@Ö2¨ù("O-
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/0d/447a6c2528b06616cde3b209a4b4ea3dcb8d65 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/0d/447a6c2528b06616cde3b209a4b4ea3dcb8d65
new file mode 100755
index 0000000..9a3ea32
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/0d/447a6c2528b06616cde3b209a4b4ea3dcb8d65 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/11/24c2c1ae07b26fded662d6c3f3631d9dc16f88 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/11/24c2c1ae07b26fded662d6c3f3631d9dc16f88
new file mode 100755
index 0000000..62abc3c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/11/24c2c1ae07b26fded662d6c3f3631d9dc16f88 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/12/905f4ea5b76f9d3fdcfe73e462201c06ae632a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/12/905f4ea5b76f9d3fdcfe73e462201c06ae632a
new file mode 100755
index 0000000..162844a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/12/905f4ea5b76f9d3fdcfe73e462201c06ae632a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/19/c5c7207054604b69c84d08a7571ef9672bb5c2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/19/c5c7207054604b69c84d08a7571ef9672bb5c2
new file mode 100755
index 0000000..d5cd6d3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/19/c5c7207054604b69c84d08a7571ef9672bb5c2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/1c/2116845780455ecf916538c1cc27c4222452af b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/1c/2116845780455ecf916538c1cc27c4222452af
new file mode 100755
index 0000000..f9a841d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/1c/2116845780455ecf916538c1cc27c4222452af differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/1c/c85eb4ff0a8438fde1b14274c6f87f891b36a0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/1c/c85eb4ff0a8438fde1b14274c6f87f891b36a0
new file mode 100755
index 0000000..98b792b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/1c/c85eb4ff0a8438fde1b14274c6f87f891b36a0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/1e/1cb7391d25dcd8daba88f1f627f3045982286c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/1e/1cb7391d25dcd8daba88f1f627f3045982286c
new file mode 100755
index 0000000..10a5be6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/1e/1cb7391d25dcd8daba88f1f627f3045982286c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/20/fc1a4c9d994021f43d33ab75e4252e27ca661d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/20/fc1a4c9d994021f43d33ab75e4252e27ca661d
new file mode 100755
index 0000000..c8b26cd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/20/fc1a4c9d994021f43d33ab75e4252e27ca661d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/28/d9eb4208074ad1cc84e71ccc908b34573f05d2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/28/d9eb4208074ad1cc84e71ccc908b34573f05d2
new file mode 100755
index 0000000..80363b0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/28/d9eb4208074ad1cc84e71ccc908b34573f05d2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/2a/26c7e88b285613b302ba76712bc998863f3cbc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/2a/26c7e88b285613b302ba76712bc998863f3cbc
new file mode 100755
index 0000000..2831139
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/2a/26c7e88b285613b302ba76712bc998863f3cbc
@@ -0,0 +1 @@
+x¥MjÃ0…»Ö)f_jô]¡ËÜ`$—*Nä1´·¯C=@—ï{ðñ^YZ›lLOÒ™Á”‚³¯Uz‡ub“·£/±âX1™ì"iu£ÎWN9ºêbÙÒ„ºèZŽS”&r4£mrY:¼Q¹o¼Â+÷6¯—í{…ÃÇ/{?­ÒgÊÒŽ`\ŠÞk-<k«µÚé>Uø_uæ+5ž ÎŸìùx9þ…a?õ¨Õ7˜W…
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/2a/c3b376093de405b0a951bff578655b1c2b7fa1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/2a/c3b376093de405b0a951bff578655b1c2b7fa1
new file mode 100755
index 0000000..a3294d7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/2a/c3b376093de405b0a951bff578655b1c2b7fa1
@@ -0,0 +1 @@
+x•ÁJÅ0E]ç+f÷¢¤“Išw‚àGLÒÉk…´š¦ÿÞÊóÜž‡{óVëÒG{×›*¤ˆA9¹ ˆÊÄšcô:ÊPÜ”ˆCJ’Bž¬ù”¦k‡\2ËÌ]}ˆj‰¥PQÉãD6b”Á9ú¼5x“üuè¯Úê²ÏÇ÷O7v}Ù{[¤ËcÞê3Ž‘‹žàÞ¢µæ¤çÔ®ÿ#þEÌ»¶ëy³Éšg¸TÙÏà–µoPÕÃM™Í/X˜
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/2c/acbcaabf785f1ac231e8519849d4ad38692f2c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/2c/acbcaabf785f1ac231e8519849d4ad38692f2c
new file mode 100755
index 0000000..74b48dd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/2c/acbcaabf785f1ac231e8519849d4ad38692f2c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/35/cb210149022c7379b0a67b0dec13cc628ff87d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/35/cb210149022c7379b0a67b0dec13cc628ff87d
new file mode 100755
index 0000000..c0466f4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/35/cb210149022c7379b0a67b0dec13cc628ff87d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/38/c05a857e831a7e759d83778bfc85d003e21c45 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/38/c05a857e831a7e759d83778bfc85d003e21c45
new file mode 100755
index 0000000..d4f1cf8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/38/c05a857e831a7e759d83778bfc85d003e21c45 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/3f/9eed8946df9e2c737d3b8dc0b8e78959aacd92 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/3f/9eed8946df9e2c737d3b8dc0b8e78959aacd92
new file mode 100755
index 0000000..8c4d6d9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/3f/9eed8946df9e2c737d3b8dc0b8e78959aacd92
@@ -0,0 +1,5 @@
+xMjÃ0…»Ö)fj¤ñH– „ì]æÃdÔ¸Dq#ËÐÞ¾
+-tßåûáã=YJ™`HO­ª‚t.DòS´ä½JN.ø1ŠÁIÉ#góÁUo
$e›Râ8†É‡¨–gÊj/žÉFŒì¼á­]–
+¯,÷MW8j-ózÙ¾VxyÿñÞk«37d){pc
+Ôˆ°³h­énŸÚô
+îbNzã¢gÈóUÇ¡}6xÞÿ‰¡ŸzÄæï*V8
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/40/9a1bec58bf35348e8b62b72bb9c1f45cf5a587 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/40/9a1bec58bf35348e8b62b72bb9c1f45cf5a587
new file mode 100755
index 0000000..60d5dca
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/40/9a1bec58bf35348e8b62b72bb9c1f45cf5a587 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/44/cd2ed2052c9c68f9a439d208e9614dc2a55c70 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/44/cd2ed2052c9c68f9a439d208e9614dc2a55c70
new file mode 100755
index 0000000..8697c4e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/44/cd2ed2052c9c68f9a439d208e9614dc2a55c70
@@ -0,0 +1 @@
+x¥ÁNÄ0C9ç+推’É$M$´â†Ä‘XÍ&Úi!M%ø{ºð	ÜìgɲÓZëÜÇp×› .É0¥˜c$¦ÍÖòetBèPpLì½Éꃛ,RITtŒ‘ƒõ£óA4E.TFr˜Ilœâ½OkƒNŸ»lð,­ÎÛ´oðxýcoO[o3wÒZO`lôD.÷µV=¦vùW‰z•…«d(ó»Ø¡ux8ýš›ŽO·ô¼.çKã%MêÖ?ZØ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/48/7434cace79238a7091e2220611d4f20a765690 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/48/7434cace79238a7091e2220611d4f20a765690
new file mode 100755
index 0000000..a1fa599
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/48/7434cace79238a7091e2220611d4f20a765690 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/49/20ad2f17162dcc8823ad491444dcb87f5899c9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/49/20ad2f17162dcc8823ad491444dcb87f5899c9
new file mode 100755
index 0000000..bf96fcc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/49/20ad2f17162dcc8823ad491444dcb87f5899c9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904
new file mode 100755
index 0000000..adf6411
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/4c/532774cc1fea37f6efc2256763a64d38c8cdde b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/4c/532774cc1fea37f6efc2256763a64d38c8cdde
new file mode 100755
index 0000000..2e56d74
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/4c/532774cc1fea37f6efc2256763a64d38c8cdde differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/51/145af30d411a50195b66517d825e69bf57ed22 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/51/145af30d411a50195b66517d825e69bf57ed22
new file mode 100755
index 0000000..3e01376
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/51/145af30d411a50195b66517d825e69bf57ed22 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/54/61de53ffadbf15be4dd6345997c15689573209 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/54/61de53ffadbf15be4dd6345997c15689573209
new file mode 100755
index 0000000..7d2b233
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/54/61de53ffadbf15be4dd6345997c15689573209
@@ -0,0 +1,4 @@
+xMjÃ0…»Ö)fj¤ñH– „ì]æÃdÔ¸Dq#ËÐÞ¾
+-tßåûáã=YJ™`HO­ª‚t.DòS´ä½JN.ø1ŠÁIÉ#góÁUo
$e›Râ8†É‡¨–gÊj/žÉFŒì¼á­]–
+¯,÷MW8j-ózÙ¾VxyÿñÞk«37d){pc
+Ôˆ°³h­énŸÚô?J¿sÒ=Cž¯:í³ÁóþOýÔ#6ßïäV<
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/54/784f10955e92ab27e4fa832e40cb2baf1edbdc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/54/784f10955e92ab27e4fa832e40cb2baf1edbdc
new file mode 100755
index 0000000..2a5bcec
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/54/784f10955e92ab27e4fa832e40cb2baf1edbdc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/56/3f6473a3858f99b80e5f93c660512ed38e1e6f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/56/3f6473a3858f99b80e5f93c660512ed38e1e6f
new file mode 100755
index 0000000..8847ed6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/56/3f6473a3858f99b80e5f93c660512ed38e1e6f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/58/a957ef0061c1a8ef995c855dfab4f5da8d6617 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/58/a957ef0061c1a8ef995c855dfab4f5da8d6617
new file mode 100755
index 0000000..f161a19
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/58/a957ef0061c1a8ef995c855dfab4f5da8d6617 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/5d/c7e1f440ce74d5503a0dfbc6c30e091475f774 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/5d/c7e1f440ce74d5503a0dfbc6c30e091475f774
new file mode 100755
index 0000000..77deeaf
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/5d/c7e1f440ce74d5503a0dfbc6c30e091475f774 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/5e/2206cda1c56430ad107a6866a829c159e0b9ea b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/5e/2206cda1c56430ad107a6866a829c159e0b9ea
new file mode 100755
index 0000000..aa30f50
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/5e/2206cda1c56430ad107a6866a829c159e0b9ea
@@ -0,0 +1 @@
+x+)JMU044d040031QHËÌI5Ô+©(aøô¦§çãÊßUÜE9sì‘ \uI‘X‘œÌvKYÕ;7níêøøMý3Kd“F’"c°¢ˆ•áï®x?3¦5ö×–¯·zÓÄѨ1*
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/5f/77a2a13935ac62a629553f8944ad57b1ed8b4a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/5f/77a2a13935ac62a629553f8944ad57b1ed8b4a
new file mode 100755
index 0000000..5e622a1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/5f/77a2a13935ac62a629553f8944ad57b1ed8b4a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/63/c0d92b95253c4a40d3883f423a54be47d2c4c8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/63/c0d92b95253c4a40d3883f423a54be47d2c4c8
new file mode 100755
index 0000000..eafe2c3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/63/c0d92b95253c4a40d3883f423a54be47d2c4c8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/6c/e83eb5f0fd34a10c3d25c6b36d2ed7ec0d6ce7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/6c/e83eb5f0fd34a10c3d25c6b36d2ed7ec0d6ce7
new file mode 100755
index 0000000..1c1f503
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/6c/e83eb5f0fd34a10c3d25c6b36d2ed7ec0d6ce7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/6d/1c2afe5eeb9e497528e2780ac468a5465cbc96 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/6d/1c2afe5eeb9e497528e2780ac468a5465cbc96
new file mode 100755
index 0000000..a98378a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/6d/1c2afe5eeb9e497528e2780ac468a5465cbc96
@@ -0,0 +1 @@
+x¥Î=jÃ@@áÔ{Šé
fvöLpgp“3ÌŽF–²œÕªðímðÒ¾âãɺ,sòþ«7Uàì$Ž	©¤š1:HðEcÈ.d*1ŽQ«p5nzïà‚T²h}A"I.•ŠSÅAÅ:‘Hysï}Z\YþvÝà¢m™·inpúý´ÛyëmæÎGY—o°®Ä`É$Dó®ïÕ®ÿBÌO{L|‡f^äðOA
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/74/f06b5bfec6d33d7264f73606b57a7c0b963819 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/74/f06b5bfec6d33d7264f73606b57a7c0b963819
new file mode 100755
index 0000000..732011f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/74/f06b5bfec6d33d7264f73606b57a7c0b963819 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/82/8b08c52d2cba30952e0e008f60b25b5ba0d41a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/82/8b08c52d2cba30952e0e008f60b25b5ba0d41a
new file mode 100755
index 0000000..302014b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/82/8b08c52d2cba30952e0e008f60b25b5ba0d41a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/85/36dd6f0ec3ddecb9f9b6c8c64c6d322cd01211 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/85/36dd6f0ec3ddecb9f9b6c8c64c6d322cd01211
new file mode 100755
index 0000000..db6faa9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/85/36dd6f0ec3ddecb9f9b6c8c64c6d322cd01211 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/85/a4a1d791973644f24c72f5e89420d3064cc452 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/85/a4a1d791973644f24c72f5e89420d3064cc452
new file mode 100755
index 0000000..7fe69b6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/85/a4a1d791973644f24c72f5e89420d3064cc452 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/8b/5c30499a71001189b647f4d5b57fa8f04897ce b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/8b/5c30499a71001189b647f4d5b57fa8f04897ce
new file mode 100755
index 0000000..8b1638f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/8b/5c30499a71001189b647f4d5b57fa8f04897ce differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/96/4ea3da044d9083181a88ba6701de9e35778bf4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/96/4ea3da044d9083181a88ba6701de9e35778bf4
new file mode 100755
index 0000000..2dec33f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/96/4ea3da044d9083181a88ba6701de9e35778bf4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/9c/c39fca3765a2facbe31157f7d60c2602193f36 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/9c/c39fca3765a2facbe31157f7d60c2602193f36
new file mode 100755
index 0000000..0031445
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/9c/c39fca3765a2facbe31157f7d60c2602193f36 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/9c/cb9bf50c011fd58dcbaa65df917bf79539717f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/9c/cb9bf50c011fd58dcbaa65df917bf79539717f
new file mode 100755
index 0000000..1266aff
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/9c/cb9bf50c011fd58dcbaa65df917bf79539717f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a1/0b59f4280491afe6e430c30654a7acc67d4a33 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a1/0b59f4280491afe6e430c30654a7acc67d4a33
new file mode 100755
index 0000000..7aa0a5d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a1/0b59f4280491afe6e430c30654a7acc67d4a33 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a2/1b4bfe7a04ab18024fb57f4ae9a52a1acef394 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a2/1b4bfe7a04ab18024fb57f4ae9a52a1acef394
new file mode 100755
index 0000000..07b7195
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a2/1b4bfe7a04ab18024fb57f4ae9a52a1acef394 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a4/3a050c588d4e92f11a6b139680923e9728477d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a4/3a050c588d4e92f11a6b139680923e9728477d
new file mode 100755
index 0000000..4713fb2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a4/3a050c588d4e92f11a6b139680923e9728477d
@@ -0,0 +1 @@
+x¥ÎMjÃ0†á®uŠÙÂHŠþ ”BÜb4Ç.‘ÝJ2´· Gèöáãåã½”µƒqñ¥WÈ9¼ãl=#»`5GÎsDD5ê(ꋪlìXš!—„Æp°!e$2NÂÚ2{ç9†IÑÑ—½ÂøûW©emËñÛàõóÏîï­×•:y/o mò“‚7pBƒ¨†Ž«]þQmw™`^¢Ïý§Ã¾A¡6ºê	mT
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a5/8ca3fee5eb68b11adc2703e5843f968c9dad1e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a5/8ca3fee5eb68b11adc2703e5843f968c9dad1e
new file mode 100755
index 0000000..1c3f2fb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a5/8ca3fee5eb68b11adc2703e5843f968c9dad1e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a6/61b5dec1004e2c62654ded3762370c27cf266b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a6/61b5dec1004e2c62654ded3762370c27cf266b
new file mode 100755
index 0000000..d94a954
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a6/61b5dec1004e2c62654ded3762370c27cf266b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a6/9ef8fcbb9a2c509a7dbf4f23d257eb551d5610 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a6/9ef8fcbb9a2c509a7dbf4f23d257eb551d5610
new file mode 100755
index 0000000..69feba2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a6/9ef8fcbb9a2c509a7dbf4f23d257eb551d5610
@@ -0,0 +1 @@
+x¥Î1ŠÃ0@Ñ­uŠéA¤,!] åÞ`,/hÈr‘ÛÇ°GHûŠÏÏK­s¤ðÕ›*heæ”Éæ§8ªÅèýèJ*(&ó¦rÉTlJIØ…è«¥$…JD%YF–ÁÙú}ip•üÜt…‹¶:¯÷íµÂ÷ï¿ÝÎko³t9楞`p)9ö­5»î«]?Š˜}nsS¨ÚnjÞGPOL
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a8/3c6f70297b805dedc549e6583582966f6ebcab b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a8/3c6f70297b805dedc549e6583582966f6ebcab
new file mode 100755
index 0000000..5a6db50
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a8/3c6f70297b805dedc549e6583582966f6ebcab differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a9/020cd240774e4d672732bcb82d516d9685da76 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a9/020cd240774e4d672732bcb82d516d9685da76
new file mode 100755
index 0000000..61741af
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/a9/020cd240774e4d672732bcb82d516d9685da76 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/ab/4115f808bc585b60f822da7020af86d20f62c8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/ab/4115f808bc585b60f822da7020af86d20f62c8
new file mode 100755
index 0000000..08c4bef
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/ab/4115f808bc585b60f822da7020af86d20f62c8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/ab/e4603bc7cd5b8167a267e0e2418fd2348f8cff b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/ab/e4603bc7cd5b8167a267e0e2418fd2348f8cff
new file mode 100755
index 0000000..4e4fe6f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/ab/e4603bc7cd5b8167a267e0e2418fd2348f8cff
@@ -0,0 +1,4 @@
+x¥KNÄ0DYç½›Ùî´?B쐐8D»ÓžÉHNÀqÜžŒFœ€í«ª'•¬µÎÐƇÞT!‰`*Â<±+,YÑZ
+%LÞˆóÆÙ„ýðÅM—ì“–X$çÄNÈ$S.cq89
+š‰ìDÞš¿¾¦ìo{¢ìxŠFL)Æ”‰ÅÄÈÁ}ÞûemðÁò½ëïÚê¼]öŸ
^®wv~Ûz›¹ó³¬õ,&?Ži„GãŒz\ëú/Éð©í¬/rSåíž`^ú
+õ=Ý£áX¾fZ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/b8/26e9b36e22e949ec885e7a1f3db496bbab6cd0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/b8/26e9b36e22e949ec885e7a1f3db496bbab6cd0
new file mode 100755
index 0000000..e3bf3a0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/b8/26e9b36e22e949ec885e7a1f3db496bbab6cd0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/ba/fbf6912c09505ac60575cd43d3f2aba3bd84d8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/ba/fbf6912c09505ac60575cd43d3f2aba3bd84d8
new file mode 100755
index 0000000..956da8b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/ba/fbf6912c09505ac60575cd43d3f2aba3bd84d8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/bb/14296ffa9dfbf935ec9ce2f9ed7808d952226b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/bb/14296ffa9dfbf935ec9ce2f9ed7808d952226b
new file mode 100755
index 0000000..b558368
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/bb/14296ffa9dfbf935ec9ce2f9ed7808d952226b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/bc/4dd0744364d1db380a9811bd264c101065231e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/bc/4dd0744364d1db380a9811bd264c101065231e
new file mode 100755
index 0000000..01d88a2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/bc/4dd0744364d1db380a9811bd264c101065231e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/bd/65d4083845ed5ed4e1fe5feb85ac395d0760c8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/bd/65d4083845ed5ed4e1fe5feb85ac395d0760c8
new file mode 100755
index 0000000..6a0eccb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/bd/65d4083845ed5ed4e1fe5feb85ac395d0760c8
@@ -0,0 +1,2 @@
+x¥ÍA
+B!€áÖžböAŒ6ŠBD» [¨o^Ï@$ݾ¡í·øÿÜj-Ú›ƒtf ä]²#““ã":dKiõ‹Æû51S at RqÊÖ:<b~Opç^ËØægÀåõ³çmH/Qâ)·z}ÎjCˆpDƒ¨vÝ×ÂEÔK»<È
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/bd/6ffc8c6c41f0f85ff9e3d61c9479516bac0024 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/bd/6ffc8c6c41f0f85ff9e3d61c9479516bac0024
new file mode 100755
index 0000000..56f8367
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/bd/6ffc8c6c41f0f85ff9e3d61c9479516bac0024 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/bd/a51965cb36c0c5731c8cb50b80a36cac81018e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/bd/a51965cb36c0c5731c8cb50b80a36cac81018e
new file mode 100755
index 0000000..1187a70
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/bd/a51965cb36c0c5731c8cb50b80a36cac81018e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/ce/d8fb81b6ec534d5deaf2a48b4b96c799712507 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/ce/d8fb81b6ec534d5deaf2a48b4b96c799712507
new file mode 100755
index 0000000..569ee0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/ce/d8fb81b6ec534d5deaf2a48b4b96c799712507
@@ -0,0 +1 @@
+x¥ÎÍJÅ0@a×yŠì…Ëä?]	¾Åd2i+7¦)èÛ[ðÜ~‹Ã¡ÞÚ6¥öîafY–’ÏÕH1„ì¼K%¢+E!…(>qð>¥q”µehMÁ„”}ÈP˜”!ò:ÖCxεùŽôuò!ßx´íXÏŸC>}üÙòṟáÄõö,•IÞç‚“ Ä¥×êäEÄë9{ã±0æ;KZq_®¾ËºÝYÝæ÷¿t3V
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/cf/c4f0999a8367568e049af4f72e452d40828a15 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/cf/c4f0999a8367568e049af4f72e452d40828a15
new file mode 100755
index 0000000..d7deb0b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/cf/c4f0999a8367568e049af4f72e452d40828a15 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/d0/f21e17beb5b9d953b1d8349049818a4f2edd1e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/d0/f21e17beb5b9d953b1d8349049818a4f2edd1e
new file mode 100755
index 0000000..65c846f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/d0/f21e17beb5b9d953b1d8349049818a4f2edd1e
@@ -0,0 +1 @@
+x¥ŽAjÃ0E»Ö)f_¶¤‘,¡]z‹‘<²]"«•ÇÐÞ¾‚!Ëÿø<^ª¥lÚá‹4fÀì=iM0HÉir: š<kiFGž§hI}Sã] õ™ã4FÇ	qfÊšlÿÄà’Á¯è”µ6ø¤ôsòÜÊv¬çßׯ[Þi	]R-7è	ÎÄ	áuÐà:í©ÂOIÔû)µp[˜â!­´/=§î·;ë‹üŠú&éWY
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/d3/d77487660ee3c0194ee01dc5eaf478782b1c7e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/d3/d77487660ee3c0194ee01dc5eaf478782b1c7e
new file mode 100755
index 0000000..b42df7e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/d3/d77487660ee3c0194ee01dc5eaf478782b1c7e
@@ -0,0 +1 @@
+x¥ÎKJ1€a×9Eí…!ïI at df%x‹ª¤ú!“Ž¦«AooƒGpû-~þÒ[[lO2˜AW﯋
6‘ŽÑÄRÙ‘Õ=yFW¥ƒúÄÁ›@Õ“5l®Ä(×™šœÏÚçdúÉr­†²ôïX¾ÞáG[÷åøÙáåãÏæÛ.cEÁKéíŒËÑ»²…gmµV§ž«ÂÿŠ¨û!½ñ˜éÁPÜæs§o0­vùõ*Wd
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/e2/33b9ed408a95e9d4b65fec7fc34943a556deb2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/e2/33b9ed408a95e9d4b65fec7fc34943a556deb2
new file mode 100755
index 0000000..b344c9c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/e2/33b9ed408a95e9d4b65fec7fc34943a556deb2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/e5/183bfd18e3a0a691fadde2f0d5610b73282d31 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/e5/183bfd18e3a0a691fadde2f0d5610b73282d31
new file mode 100755
index 0000000..fdc0571
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/e5/183bfd18e3a0a691fadde2f0d5610b73282d31 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/e6/ae8889c40c77d7be02758235b5b3f7a4f2a129 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/e6/ae8889c40c77d7be02758235b5b3f7a4f2a129
new file mode 100755
index 0000000..3345907
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/e6/ae8889c40c77d7be02758235b5b3f7a4f2a129 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/e7/811a2bc55635f182750f0420da5ad232c1af91 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/e7/811a2bc55635f182750f0420da5ad232c1af91
new file mode 100755
index 0000000..2388730
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/e7/811a2bc55635f182750f0420da5ad232c1af91 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/e9/b63f3655b2ad80c0ff587389b5a9589a3a7110 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/e9/b63f3655b2ad80c0ff587389b5a9589a3a7110
new file mode 100755
index 0000000..ab0a27f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/e9/b63f3655b2ad80c0ff587389b5a9589a3a7110
@@ -0,0 +1,2 @@
+x¥ÎMjÃ0@á®uŠÙŠ<Ë!E¡·É£ØÅ?‰$/rûz„n¿Åã¥}]çHÃG+ªzåè¼"*k
+¡×AºìÆHìc”èÓhÍ]Šn
RN”-3Kp~è}PK,™ò€J=Ždéz#G›ö?’‡VøÖ²Îu:žN¿v»ÔVfiò•öõcOÎ;‹ðiÑZóÖ÷jÓEÌu’í¦ Ëy^´š-˜P@
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/eb/da71fe44dcb60c53b8fbd53208a1204d32e959 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/eb/da71fe44dcb60c53b8fbd53208a1204d32e959
new file mode 100755
index 0000000..19d0c52
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/eb/da71fe44dcb60c53b8fbd53208a1204d32e959 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/f0/5ed049854c1596a7cc0e957fab34961077f3ae b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/f0/5ed049854c1596a7cc0e957fab34961077f3ae
new file mode 100755
index 0000000..ab45439
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/f0/5ed049854c1596a7cc0e957fab34961077f3ae differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/f0/a4e1c66bb548cd2b22eebefda703872e969775 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/f0/a4e1c66bb548cd2b22eebefda703872e969775
new file mode 100755
index 0000000..558dd0a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/f0/a4e1c66bb548cd2b22eebefda703872e969775 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/f2/ec8c8cf1a9fb7aa047a25a4308bfe860237ad4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/f2/ec8c8cf1a9fb7aa047a25a4308bfe860237ad4
new file mode 100755
index 0000000..a011751
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/f2/ec8c8cf1a9fb7aa047a25a4308bfe860237ad4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/f5/684c96bf40c709877b56404cd8a5dd2d2a7978 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/f5/684c96bf40c709877b56404cd8a5dd2d2a7978
new file mode 100755
index 0000000..83bb5a0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/f5/684c96bf40c709877b56404cd8a5dd2d2a7978 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/f9/0f9dcbdac2cce5cc166346160e19cb693ef4e8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/f9/0f9dcbdac2cce5cc166346160e19cb693ef4e8
new file mode 100755
index 0000000..71be9f8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/objects/f9/0f9dcbdac2cce5cc166346160e19cb693ef4e8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/automerge-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/automerge-branch
new file mode 100755
index 0000000..9330ef3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/automerge-branch
@@ -0,0 +1 @@
+d3d77487660ee3c0194ee01dc5eaf478782b1c7e
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/master
new file mode 100755
index 0000000..aa8913b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/master
@@ -0,0 +1 @@
+2a26c7e88b285613b302ba76712bc998863f3cbc
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/merge-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/merge-branch
new file mode 100755
index 0000000..ea5b277
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/merge-branch
@@ -0,0 +1 @@
+abe4603bc7cd5b8167a267e0e2418fd2348f8cff
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/merge-conflicts b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/merge-conflicts
new file mode 100755
index 0000000..f63f17e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/merge-conflicts
@@ -0,0 +1 @@
+bafbf6912c09505ac60575cd43d3f2aba3bd84d8
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/merge-mainline b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/merge-mainline
new file mode 100755
index 0000000..0ec5e45
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/merge-mainline
@@ -0,0 +1 @@
+cfc4f0999a8367568e049af4f72e452d40828a15
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/orphan b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/orphan
new file mode 100755
index 0000000..f4d6a74
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/orphan
@@ -0,0 +1 @@
+74f06b5bfec6d33d7264f73606b57a7c0b963819
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/renames b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/renames
new file mode 100755
index 0000000..df55871
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/.gitted/refs/heads/renames
@@ -0,0 +1 @@
+44cd2ed2052c9c68f9a439d208e9614dc2a55c70
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/file1.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/file1.txt
new file mode 100755
index 0000000..38c05a8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/file1.txt
@@ -0,0 +1,15 @@
+!File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/file2.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/file2.txt
new file mode 100755
index 0000000..a661b5d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/file2.txt
@@ -0,0 +1,15 @@
+!File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/file3.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/file3.txt
new file mode 100755
index 0000000..85a4a1d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/cherrypick/file3.txt
@@ -0,0 +1,15 @@
+!File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/.gitconfig b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/.gitconfig
new file mode 100755
index 0000000..fa72bdd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/.gitconfig
@@ -0,0 +1,3 @@
+[core]
+	repositoryformatversion = 5
+	something = 2
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config-include b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config-include
new file mode 100755
index 0000000..6b5e79d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config-include
@@ -0,0 +1,2 @@
+[include]
+	path = config-included
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config-included b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config-included
new file mode 100755
index 0000000..089ca08
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config-included
@@ -0,0 +1,2 @@
+[foo "bar"]
+     baz = huzzah
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config0
new file mode 100755
index 0000000..85235c5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config0
@@ -0,0 +1,7 @@
+# This is a test                                                                                                                                                       
+; of different comments
+[core]
+    repositoryformatversion = 0
+    filemode = true
+    bare = false
+    logallrefupdates = true
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config1
new file mode 100755
index 0000000..211dc9e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config1
@@ -0,0 +1,5 @@
+# This one checks for case sensitivity
+[this "that"]
+	  other = true
+[this "That"]
+	  other = yes
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config10 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config10
new file mode 100755
index 0000000..dde1791
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config10
@@ -0,0 +1 @@
+[empty]
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config11 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config11
new file mode 100755
index 0000000..1d8a744
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config11
@@ -0,0 +1,5 @@
+[remote "ab"]
+    url = git://github.com/libgit2/libgit2
+    url = git://git.example.com/libgit2
+
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config12 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config12
new file mode 100755
index 0000000..6917880
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config12
@@ -0,0 +1,13 @@
+[some "section"]
+      test = hi ; comment
+      test2 = hello    ; comment
+      test3 = welcome  #comment
+      other = "hello! \" ; ; ; " ; more test
+      other2 = "cool! \" # # # "  # more test
+      multi = "hi, this is a ; \
+multiline comment # with ;\n special chars \
+and other stuff !@#"
+      multi2 = "good, this is a ; \
+multiline comment # with ;\n special chars \
+and other stuff !@#"  #^^^
+      back = "this is \ba phrase"
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config13 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config13
new file mode 100755
index 0000000..c1e0c56
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config13
@@ -0,0 +1,2 @@
+[core]
+	editor = \"C:/Program Files/Nonsense/bah.exe\" \"--some option\"
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config14 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config14
new file mode 100755
index 0000000..ef2198c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config14
@@ -0,0 +1,4 @@
+[a]
+    b=c
+[d]
+    e = f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config15 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config15
new file mode 100755
index 0000000..6d34f81
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config15
@@ -0,0 +1,3 @@
+[core]
+	dummy2 = 7
+	global = 17
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config16 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config16
new file mode 100755
index 0000000..f25cdb7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config16
@@ -0,0 +1,3 @@
+[core]
+	dummy2 = 28
+	system = 11
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config17 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config17
new file mode 100755
index 0000000..ca25a86
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config17
@@ -0,0 +1,3 @@
+[core]
+	dummy2 = 7
+	global = 17
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config18 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config18
new file mode 100755
index 0000000..cb6fd5e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config18
@@ -0,0 +1,5 @@
+[core]
+	int32global = 28
+	int64global = 9223372036854775803
+	boolglobal = true
+	stringglobal = I'm a global config value!
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config19 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config19
new file mode 100755
index 0000000..f3ae5a6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config19
@@ -0,0 +1,5 @@
+[core]
+	int32global = -1
+	int64global = -2
+	boolglobal = false
+	stringglobal = don't find me!
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config2
new file mode 100755
index 0000000..60a3898
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config2
@@ -0,0 +1,5 @@
+; This one tests for multiline values
+[this "That"]
+	  and = one one one \
+two two \
+three three
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config20 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config20
new file mode 100755
index 0000000..8f0f12c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config20
@@ -0,0 +1,11 @@
+[valid "[subsection]"]
+    something = a
+; we don't allow anything after closing "
+[sec "[subsec]/child"]
+    parent = grand
+[sec2 "[subsec2]/child2"]
+    type = dvcs
+[sec3 "escape\"quote"]
+    vcs = git
+[sec4 "escaping\\slash"]
+    lib = git2
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config3
new file mode 100755
index 0000000..44a5e50
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config3
@@ -0,0 +1,3 @@
+# A [section.subsection] header is case-insensitive
+[section.SuBsection]
+		var = hello
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config4
new file mode 100755
index 0000000..9dd4041
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config4
@@ -0,0 +1,5 @@
+# A variable name on its own is valid
+[some.section]
+		variable
+# A variable and '=' is accepted, but it's not considered true
+		variableeq =
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config5
new file mode 100755
index 0000000..8ab60cc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config5
@@ -0,0 +1,9 @@
+# Test for number suffixes
+[number]
+		simple = 1
+		k = 1k
+		kk = 1K
+		m = 1m
+		mm = 1M
+		g = 1g
+		gg = 1G
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config6
new file mode 100755
index 0000000..0f8f90a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config6
@@ -0,0 +1,5 @@
+[valid "subsection"]
+    something = true
+
+[something "else"]
+    something = false
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config7
new file mode 100755
index 0000000..6af6fcf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config7
@@ -0,0 +1,5 @@
+[valid "subsection"]
+    something = a
+; we don't allow anything after closing "
+[sec "subsec"x]
+    bleh = blah
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config8
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config9
new file mode 100755
index 0000000..fcaac42
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/config/config9
@@ -0,0 +1,9 @@
+[core]
+	dummy2 = 42
+	verylong = 1
+	dummy = 1
+
+[remote "ab"]
+	url = http://example.com/git/ab
+[remote "abba"]
+	url = http://example.com/git/abba
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/config
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/index
new file mode 100755
index 0000000..e8d43e9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/04/4bcd5c9bf5ebdd51e514a9a36457018f06f6e1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/04/4bcd5c9bf5ebdd51e514a9a36457018f06f6e1
new file mode 100755
index 0000000..a32a9b2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/04/4bcd5c9bf5ebdd51e514a9a36457018f06f6e1
@@ -0,0 +1 @@
+x-ŽÁjÃ0D{ÖWì½4H+Ù+C(É¡·þ„¤]aÓØJU…|}•˜Ã̃“ʺ.
к·VE@²æÄv™ÑÈ”²ËvB½x=%‰êªl
ÈsDÒÉx÷H¦!x3E9ÅA‡hPÆdU¸´¹Tøâk¨{éký+ÛAžàµv©¬Ÿ`¬ŸŒC2|h¯µê´ŸlRá{Ù~/Ë]`zµÃ-Ì¥<ÄÝüÓ]×MÄ5¼?]ud†»ÔñÖòrõÄ&K!
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/04/de00b358f13389948756732158eaaaefa1448c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/04/de00b358f13389948756732158eaaaefa1448c
new file mode 100755
index 0000000..c3b7598
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/04/de00b358f13389948756732158eaaaefa1448c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/09/7722be9b67b48dfe3b19396d02fd535300ee46 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/09/7722be9b67b48dfe3b19396d02fd535300ee46
new file mode 100755
index 0000000..5c5c24c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/09/7722be9b67b48dfe3b19396d02fd535300ee46 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/0a/a76e474d259bd7c13eb726a1396c381db55c88 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/0a/a76e474d259bd7c13eb726a1396c381db55c88
new file mode 100755
index 0000000..e118d66
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/0a/a76e474d259bd7c13eb726a1396c381db55c88 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/0d/06894e14df22e066763ae906e0ed3eb79c205f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/0d/06894e14df22e066763ae906e0ed3eb79c205f
new file mode 100755
index 0000000..b7a1f32
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/0d/06894e14df22e066763ae906e0ed3eb79c205f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/0e/052888828a954ca17e5882638e3c6a083e75c0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/0e/052888828a954ca17e5882638e3c6a083e75c0
new file mode 100755
index 0000000..746143f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/0e/052888828a954ca17e5882638e3c6a083e75c0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/0f/f5a53f19bfd2b5eea1ba550295c47515678987 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/0f/f5a53f19bfd2b5eea1ba550295c47515678987
new file mode 100755
index 0000000..5366acd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/0f/f5a53f19bfd2b5eea1ba550295c47515678987 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/16/78031ee023a23bd3515e4e1693b661a69f0a73 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/16/78031ee023a23bd3515e4e1693b661a69f0a73
new file mode 100755
index 0000000..4aa4ffb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/16/78031ee023a23bd3515e4e1693b661a69f0a73 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/16/c72b67861f8524a5bebc05cd20472d3fca00da b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/16/c72b67861f8524a5bebc05cd20472d3fca00da
new file mode 100755
index 0000000..e2b1994
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/16/c72b67861f8524a5bebc05cd20472d3fca00da differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/18/c637c5d9aba6eed226ee1840cd1ca2e6c4e4c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/18/c637c5d9aba6eed226ee1840cd1ca2e6c4e4c5
new file mode 100755
index 0000000..790eb13
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/18/c637c5d9aba6eed226ee1840cd1ca2e6c4e4c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/20/3555c5676d75cd80d69b50beb1f4b588c59ceb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/20/3555c5676d75cd80d69b50beb1f4b588c59ceb
new file mode 100755
index 0000000..8038a9b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/20/3555c5676d75cd80d69b50beb1f4b588c59ceb differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/23/f4582779e60bfa7f14750ad507399a58876611 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/23/f4582779e60bfa7f14750ad507399a58876611
new file mode 100755
index 0000000..4a4e4dc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/23/f4582779e60bfa7f14750ad507399a58876611 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/2a/d3df895f68f4dda6a0a815c620b909bdd27c05 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/2a/d3df895f68f4dda6a0a815c620b909bdd27c05
new file mode 100755
index 0000000..f5421cf
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/2a/d3df895f68f4dda6a0a815c620b909bdd27c05 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/2b/55b4b94f655c857635b6a9005c056aa7de3532 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/2b/55b4b94f655c857635b6a9005c056aa7de3532
new file mode 100755
index 0000000..031fd66
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/2b/55b4b94f655c857635b6a9005c056aa7de3532
@@ -0,0 +1,2 @@
+x-ŽKjÄ0D³Ö)z2tëcµa³™].¡O›ÄV¢È„Éé£	µ¨zð RݶµƒÖøÔ›AvyIfLiò.²Ï…œPɘL0dÑõšì<ç¨=&b{Oñ.09o4Åœ¢ÃIË”Œ
+G_jƒkþ	-ÃYÆÚ¾ë~‘ðX§T·W ãØ°çÙÂNˆjÐq²Kƒ·uÿ:Ö_óÇ£]na©õ.ž–÷áZ²Zk7!<#W½°ú²F
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/2b/d9d81b51a867352bab307b89cbb5b4a69adfe1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/2b/d9d81b51a867352bab307b89cbb5b4a69adfe1
new file mode 100755
index 0000000..96d952e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/2b/d9d81b51a867352bab307b89cbb5b4a69adfe1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/2c/03f9f407b576eae80327864bab572e282a33ea b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/2c/03f9f407b576eae80327864bab572e282a33ea
new file mode 100755
index 0000000..0e4afbb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/2c/03f9f407b576eae80327864bab572e282a33ea differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/33/cdead44e1c3ec178e39a4a69085280dbacf01b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/33/cdead44e1c3ec178e39a4a69085280dbacf01b
new file mode 100755
index 0000000..72dc780
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/33/cdead44e1c3ec178e39a4a69085280dbacf01b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/38/1cfe630df902bc29271a202d3277981180e4a6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/38/1cfe630df902bc29271a202d3277981180e4a6
new file mode 100755
index 0000000..0cf7072
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/38/1cfe630df902bc29271a202d3277981180e4a6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/3f/96bdca0e37616026afaa325c148cec4aa62d04 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/3f/96bdca0e37616026afaa325c148cec4aa62d04
new file mode 100755
index 0000000..a204fc9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/3f/96bdca0e37616026afaa325c148cec4aa62d04 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/41/7786fc35b3c71aa546e3f95eb5da3c8dad8c41 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/41/7786fc35b3c71aa546e3f95eb5da3c8dad8c41
new file mode 100755
index 0000000..ec57bde
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/41/7786fc35b3c71aa546e3f95eb5da3c8dad8c41 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/47/fbc2c28a18df0dc773276a253eb85c7516ca50 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/47/fbc2c28a18df0dc773276a253eb85c7516ca50
new file mode 100755
index 0000000..d16db96
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/47/fbc2c28a18df0dc773276a253eb85c7516ca50 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904
new file mode 100755
index 0000000..adf6411
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/5a/fb6a14a864e30787857dd92af837e8cdd2cb1b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/5a/fb6a14a864e30787857dd92af837e8cdd2cb1b
new file mode 100755
index 0000000..11a25c5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/5a/fb6a14a864e30787857dd92af837e8cdd2cb1b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/68/03c385642cebc8103fddd526ef395d75678a7e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/68/03c385642cebc8103fddd526ef395d75678a7e
new file mode 100755
index 0000000..f8d489f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/68/03c385642cebc8103fddd526ef395d75678a7e
@@ -0,0 +1,2 @@
+x¥ÎKjÄ0ЬuŠ¾À},µ!dÉ	&h·ZØ0²‚¬ÁäöQvÙgW¼‚¢¸–²u°ŸzËÚå9OAH¢v£ÓB¬ØhÉ9!õEMö}œÑcžfÔ˜52vÙ%ëmä`/¬èÑ×Úà=ÔÜÖZŽºÃ‹ýMoeãVšû3×ò
+fr1ƒpÑ“Öjè8Úåêšäí.œ[_¡Ðþ
Ÿ·K^©@ûèåükêÑ¡Yj
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/69/597764abeaa1a403ebf589d2ea579c6a8f877e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/69/597764abeaa1a403ebf589d2ea579c6a8f877e
new file mode 100755
index 0000000..ee4f427
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/69/597764abeaa1a403ebf589d2ea579c6a8f877e
@@ -0,0 +1 @@
+xÎэÂ0€až3…ßOwr“&­%„`†NàÄŽˆ -JÃ!¶1|¿þ´Îsi`ݸkUÈ¢r.*{z¤‘Ägr>ɱcòbn\ui êcæ.x"’‚DÎ,–ÞN“Ã,†ïí¼V˜þu©Õ’.umgØëÌåzLÛïãü=@×[kðƒ¢IŸÇ¦ßismbY¸>!—«næJ“LÅ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/6a/e3e9c11a51f0aabebcffcbd5c00f4beed143c9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/6a/e3e9c11a51f0aabebcffcbd5c00f4beed143c9
new file mode 100755
index 0000000..6c18a3a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/6a/e3e9c11a51f0aabebcffcbd5c00f4beed143c9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/6c/589757f65a970a6cc07c71c3f3d2528c611cbc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/6c/589757f65a970a6cc07c71c3f3d2528c611cbc
new file mode 100755
index 0000000..fe4da8c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/6c/589757f65a970a6cc07c71c3f3d2528c611cbc
@@ -0,0 +1,2 @@
+x-ŽKNÃ0„Yçÿµò;Ž„PYp‚rÿ5j#Ç€¸=nÅnF3ói¸¬ëÒÀ…ñ©UUp$“dKÑbN£Ž¼)OL)`šPfµÃ'VÝpCV‰‘Y$ÏSÊÕ³³cÔqVIÑÎ:àW»”
+çoÝàÜêÂ×ZÚ^tÅåvâýðӁGÑW°Á9gLš2<kÌÀM+¼Ko	|\ʺ—­;ó®Núþݱîï£õ>$8˜Ð1ÛìeU eÃúórÓ}ø.Q¯
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/77/afe26d93c49279ca90604c125496920753fede b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/77/afe26d93c49279ca90604c125496920753fede
new file mode 100755
index 0000000..a377cb0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/77/afe26d93c49279ca90604c125496920753fede differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/78/db270c1841841f75a8157321bdcb50ab12e6c3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/78/db270c1841841f75a8157321bdcb50ab12e6c3
new file mode 100755
index 0000000..8a55bb0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/78/db270c1841841f75a8157321bdcb50ab12e6c3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/79/9770d1cff46753a57db7a066159b5610da6e3a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/79/9770d1cff46753a57db7a066159b5610da6e3a
new file mode 100755
index 0000000..5c701b8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/79/9770d1cff46753a57db7a066159b5610da6e3a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/7c/ce67e58173e2b01f7db124ceaabe3183d19c49 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/7c/ce67e58173e2b01f7db124ceaabe3183d19c49
new file mode 100755
index 0000000..8e836ab
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/7c/ce67e58173e2b01f7db124ceaabe3183d19c49 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/85/340755cfe5e28c2835781978bb1cece91b3d0f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/85/340755cfe5e28c2835781978bb1cece91b3d0f
new file mode 100755
index 0000000..e83fbc2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/85/340755cfe5e28c2835781978bb1cece91b3d0f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/92/0e90a663bea5d740989d5f935f6dfb473a0c5d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/92/0e90a663bea5d740989d5f935f6dfb473a0c5d
new file mode 100755
index 0000000..f872be6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/92/0e90a663bea5d740989d5f935f6dfb473a0c5d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/96/87e444bcbb85645cb496080434c292f1b57182 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/96/87e444bcbb85645cb496080434c292f1b57182
new file mode 100755
index 0000000..5df64d8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/96/87e444bcbb85645cb496080434c292f1b57182
@@ -0,0 +1 @@
+x¥ÎAJ1@Q×9Eí…!©T:™Y	Þ¢ºRí´ÐMªAoïˆGpûŸ/mß7LùÁº*L¬Q‹„À)¬žyÑEÖU–šÄû•Õ(JqÜõfP2Q©Œ1¥”%¥™‰âL•æ¬Ó$QS	Ž»¶¯,Ÿ‡xѾoãz|xzÿ³·ó°¾±ñIÚþ0{ŠS at xôè½»ë}Õô_w©U+H»Ùï¾50†'û2÷ÿ=T‰
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/97/449da2d225557c558ac244384d487e66c3e591 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/97/449da2d225557c558ac244384d487e66c3e591
new file mode 100755
index 0000000..d3917a4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/97/449da2d225557c558ac244384d487e66c3e591 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/9a/6c3533fef19abd6eec8e61206b5c51982b80d9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/9a/6c3533fef19abd6eec8e61206b5c51982b80d9
new file mode 100755
index 0000000..78fc8ae
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/9a/6c3533fef19abd6eec8e61206b5c51982b80d9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/9d/29b5bb165bf65637ffcb5ededb82ddd7c3fd13 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/9d/29b5bb165bf65637ffcb5ededb82ddd7c3fd13
new file mode 100755
index 0000000..106332d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/9d/29b5bb165bf65637ffcb5ededb82ddd7c3fd13 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/a2/34455d62297f1856c4603686150c59fcb0aafe b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/a2/34455d62297f1856c4603686150c59fcb0aafe
new file mode 100755
index 0000000..7d204f4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/a2/34455d62297f1856c4603686150c59fcb0aafe differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/a9/a2e8913c1dbe2812fac5e6b4e0a4bd5d0d5966 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/a9/a2e8913c1dbe2812fac5e6b4e0a4bd5d0d5966
new file mode 100755
index 0000000..33d59f1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/a9/a2e8913c1dbe2812fac5e6b4e0a4bd5d0d5966
@@ -0,0 +1 @@
+xKÊÉOR02aH.ÊIãåÂ$œž	
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/aa/f083a9cb53dac3669dcfa0e48921580d629ec7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/aa/f083a9cb53dac3669dcfa0e48921580d629ec7
new file mode 100755
index 0000000..38775d0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/aa/f083a9cb53dac3669dcfa0e48921580d629ec7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/af/6fcf6da196f615d7cda269b55b5c4ecfb4a5b3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/af/6fcf6da196f615d7cda269b55b5c4ecfb4a5b3
new file mode 100755
index 0000000..0acc974
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/af/6fcf6da196f615d7cda269b55b5c4ecfb4a5b3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/bb/29a7b46b5d4ba3ea17b238ae561b81d59dc818 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/bb/29a7b46b5d4ba3ea17b238ae561b81d59dc818
new file mode 100755
index 0000000..a08789b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/bb/29a7b46b5d4ba3ea17b238ae561b81d59dc818 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/c3/e11722855ff260bd27418988ac1467c4e9e73a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/c3/e11722855ff260bd27418988ac1467c4e9e73a
new file mode 100755
index 0000000..5f96dc7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/c3/e11722855ff260bd27418988ac1467c4e9e73a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/c8/d0b1ebcaccdd8f968c4aae3c2175e7fed651fe b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/c8/d0b1ebcaccdd8f968c4aae3c2175e7fed651fe
new file mode 100755
index 0000000..21e2ce0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/c8/d0b1ebcaccdd8f968c4aae3c2175e7fed651fe
@@ -0,0 +1,2 @@
+x-ŽKnÃ0C»Ö)f8Ðod(‚tѤ4#؈e²ú9~• ;$˜öR–õK«ÌàIûˆ1*‡1;tfÌ9EdbŠ“&¢1™LʈÏPyk ­‰0ù˜‘#*FeƒÆY¥š²tÙ±á«Í{…Û7opkuI÷º·^¹„e½¦cøéÀ3ñ”ÕZ?™	NRI)Òócã
+ïÔ[ó^Ž}ëãÎ|¨+?ƒwîƒÆTÆX
ƒ´#Þˆ ,¿Lê°æ!Õ5C^V>Ä=ßR~
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/cd/574f5a2baa4c79504f8837b730fa0b11defe99 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/cd/574f5a2baa4c79504f8837b730fa0b11defe99
new file mode 100755
index 0000000..e8d0202
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/cd/574f5a2baa4c79504f8837b730fa0b11defe99 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/cd/d3dacc5c0501d5ea57bbdf90e3d80176606139 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/cd/d3dacc5c0501d5ea57bbdf90e3d80176606139
new file mode 100755
index 0000000..72cf3b0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/cd/d3dacc5c0501d5ea57bbdf90e3d80176606139 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/d1/1e7ef63ba7db1db3b1b99cdbafc57a8549f8a4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/d1/1e7ef63ba7db1db3b1b99cdbafc57a8549f8a4
new file mode 100755
index 0000000..05d88fc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/d1/1e7ef63ba7db1db3b1b99cdbafc57a8549f8a4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/dc/88e3b917de821e25962bea7ec1f55c4ce2112c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/dc/88e3b917de821e25962bea7ec1f55c4ce2112c
new file mode 100755
index 0000000..3db13aa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/dc/88e3b917de821e25962bea7ec1f55c4ce2112c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/de/5bfa165999d9d6c6dbafad2a7e709f93ec30fd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/de/5bfa165999d9d6c6dbafad2a7e709f93ec30fd
new file mode 100755
index 0000000..e288b97
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/de/5bfa165999d9d6c6dbafad2a7e709f93ec30fd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/e5/062da7d7802cf492975eda580f09ac4876bd88 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/e5/062da7d7802cf492975eda580f09ac4876bd88
new file mode 100755
index 0000000..62835b9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/e5/062da7d7802cf492975eda580f09ac4876bd88
@@ -0,0 +1 @@
+x¥QŠ1DýÎ)új'd2"‹û)þxNÒÃÆ,3¯ï¸xÿª^AQ•j)×ÆÛU›D`ŽÔiJÖ»>Fc:D´&Rr.†ì1#÷ÎDõÇ“Ü¥,œ­H’î‚PÏ–}Á™€9rPGŏ6Ö	~ó“§—±–¹Þa/}«ƒü·Iµü€¶DÎx$k´ˆj¡ËØ&_Ö¨GÂæZ–¿×›ÌðÜ›Áñ|šÕǸUë
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100755
index 0000000..7112238
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/ea/030d3c6cec212069eca698cabaa5b4550f1511 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/ea/030d3c6cec212069eca698cabaa5b4550f1511
new file mode 100755
index 0000000..117dc72
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/ea/030d3c6cec212069eca698cabaa5b4550f1511 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/ef/0dcd356d77221e9c27f4f3928ad28e80b87ceb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/ef/0dcd356d77221e9c27f4f3928ad28e80b87ceb
new file mode 100755
index 0000000..33aceda
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/ef/0dcd356d77221e9c27f4f3928ad28e80b87ceb differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/f2/b745d7f47d114a3a6b31a7b628e61e804d1a58 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/f2/b745d7f47d114a3a6b31a7b628e61e804d1a58
new file mode 100755
index 0000000..7b2e7a1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/f2/b745d7f47d114a3a6b31a7b628e61e804d1a58 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/f4/d25b796d86387205a5498175d66e91d1e5006a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/f4/d25b796d86387205a5498175d66e91d1e5006a
new file mode 100755
index 0000000..792b165
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/f4/d25b796d86387205a5498175d66e91d1e5006a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/fe/085d9ace90cc675b87df15e1aeed0c3a31407f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/fe/085d9ace90cc675b87df15e1aeed0c3a31407f
new file mode 100755
index 0000000..2e8d10b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/fe/085d9ace90cc675b87df15e1aeed0c3a31407f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/fe/ab3713c4659bb22700042b3c55b8d60d0a952b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/fe/ab3713c4659bb22700042b3c55b8d60d0a952b
new file mode 100755
index 0000000..8552c7b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/objects/fe/ab3713c4659bb22700042b3c55b8d60d0a952b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/refs/heads/empty-files b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/refs/heads/empty-files
new file mode 100755
index 0000000..8f1fe61
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/refs/heads/empty-files
@@ -0,0 +1 @@
+9687e444bcbb85645cb496080434c292f1b57182
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/refs/heads/master
new file mode 100755
index 0000000..fe1d0aa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf/.gitted/refs/heads/master
@@ -0,0 +1 @@
+5afb6a14a864e30787857dd92af837e8cdd2cb1b
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/.gitattributes b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/.gitattributes
new file mode 100755
index 0000000..23d9bdb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/.gitattributes
@@ -0,0 +1 @@
+* binary
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,-text/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false,text_auto/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_false/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,-text/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input,text_auto/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_input/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,-text/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true,text_auto/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/posix/autocrlf_true/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,-text/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false,text_auto/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_false/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,-text/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input,text_auto/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_input/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,-text/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/binary-all-lf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/binary-mixed-lf-cr
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..fd2abfa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/mixed-lf-cr
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..df8c0f6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_crlf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/all-lf
new file mode 100755
index 0000000..799770d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/all-lf-utf8bom
new file mode 100755
index 0000000..7cce67e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/few-utf8-chars-lf
new file mode 100755
index 0000000..f4d25b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/many-utf8-chars-lf
new file mode 100755
index 0000000..9a6c353
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto,eol_lf/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/more-crlf
new file mode 100755
index 0000000..e682c30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/more-crlf-utf8bom
new file mode 100755
index 0000000..2e1220c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/more-lf
new file mode 100755
index 0000000..6da5b0c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/more-lf-utf8bom
new file mode 100755
index 0000000..3fa59c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true,text_auto/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/all-crlf
new file mode 100755
index 0000000..a9a2e89
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/all-crlf
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/all-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/all-crlf-utf8bom
new file mode 100755
index 0000000..0aa76e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/all-crlf-utf8bom
@@ -0,0 +1,4 @@
+crlf
+crlf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/all-lf
new file mode 100755
index 0000000..f557a02
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/all-lf
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/all-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/all-lf-utf8bom
new file mode 100755
index 0000000..381cfe6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/all-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+lf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/binary-all-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/binary-all-crlf
new file mode 100755
index 0000000..8534075
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/binary-all-crlf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/binary-all-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/binary-all-lf
new file mode 100755
index 0000000..af6fcf6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/binary-all-lf
@@ -0,0 +1,4 @@
+one
+two
+three
+four
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/binary-mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/binary-mixed-lf-cr
new file mode 100755
index 0000000..203555c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/binary-mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/binary-mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/binary-mixed-lf-cr-crlf
new file mode 100755
index 0000000..aaf083a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/binary-mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/few-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/few-utf8-chars-crlf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/few-utf8-chars-crlf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/few-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/few-utf8-chars-lf
new file mode 100755
index 0000000..0e05288
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/few-utf8-chars-lf
@@ -0,0 +1,22 @@
+âš½The rest is ASCII01.
+The rest is ASCII02.
+The rest is ASCII03.
+The rest is ASCII04.
+The rest is ASCII05.
+The rest is ASCII06.
+The rest is ASCII07.
+The rest is ASCII08.
+The rest is ASCII09.
+The rest is ASCII10.
+The rest is ASCII11.
+The rest is ASCII12.
+The rest is ASCII13.
+The rest is ASCII14.
+The rest is ASCII15.
+The rest is ASCII16.
+The rest is ASCII17.
+The rest is ASCII18.
+The rest is ASCII19.
+The rest is ASCII20.
+The rest is ASCII21.
+The rest is ASCII22.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/many-utf8-chars-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/many-utf8-chars-crlf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/many-utf8-chars-crlf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/many-utf8-chars-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/many-utf8-chars-lf
new file mode 100755
index 0000000..cd574f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/many-utf8-chars-lf
@@ -0,0 +1,4 @@
+Lets sing!
+♫♪♬♩
+Eat food
+🍅🍕
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/mixed-lf-cr b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/mixed-lf-cr
new file mode 100755
index 0000000..d11e7ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/mixed-lf-cr
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/mixed-lf-cr-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/mixed-lf-cr-crlf
new file mode 100755
index 0000000..417786f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/mixed-lf-cr-crlf
@@ -0,0 +1,3 @@
+one
+two
three
+four
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/more-crlf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/more-crlf
new file mode 100755
index 0000000..0ff5a53
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/more-crlf
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/more-crlf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/more-crlf-utf8bom
new file mode 100755
index 0000000..ea030d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/more-crlf-utf8bom
@@ -0,0 +1,5 @@
+crlf
+crlf
+lf
+crlf
+crlf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/more-lf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/more-lf
new file mode 100755
index 0000000..04de00b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/more-lf
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/more-lf-utf8bom b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/more-lf-utf8bom
new file mode 100755
index 0000000..dc88e3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/more-lf-utf8bom
@@ -0,0 +1,5 @@
+lf
+lf
+crlf
+lf
+lf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/zero-byte b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/crlf_data/windows/autocrlf_true/zero-byte
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/config
new file mode 100755
index 0000000..f57351f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/config
@@ -0,0 +1,6 @@
+[core]
+	bare = true
+	repositoryformatversion = 0
+	filemode = false
+	logallrefupdates = true
+	ignorecase = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/index
new file mode 100755
index 0000000..6827406
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/info/exclude
new file mode 100755
index 0000000..6d05881
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/info/exclude
@@ -0,0 +1,2 @@
+# File patterns to ignore; see `git help ignore` for more information.
+# Lines that start with '#' are comments.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/objects/06/262edc257418e9987caf999f9a7a3e1547adff b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/objects/06/262edc257418e9987caf999f9a7a3e1547adff
new file mode 100755
index 0000000..a030cf7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/objects/06/262edc257418e9987caf999f9a7a3e1547adff differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/objects/08/10fb7818088ff5ac41ee49199b51473b1bd6c7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/objects/08/10fb7818088ff5ac41ee49199b51473b1bd6c7
new file mode 100755
index 0000000..52d5693
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/objects/08/10fb7818088ff5ac41ee49199b51473b1bd6c7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/objects/1b/05fdaa881ee45b48cbaa5e9b037d667a47745e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/objects/1b/05fdaa881ee45b48cbaa5e9b037d667a47745e
new file mode 100755
index 0000000..ae7765a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/objects/1b/05fdaa881ee45b48cbaa5e9b037d667a47745e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/objects/3d/0970ec547fc41ef8a5882dde99c6adce65b021 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/objects/3d/0970ec547fc41ef8a5882dde99c6adce65b021
new file mode 100755
index 0000000..595283e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/objects/3d/0970ec547fc41ef8a5882dde99c6adce65b021 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/refs/heads/master
new file mode 100755
index 0000000..1e106df
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/deprecated-mode.git/refs/heads/master
@@ -0,0 +1 @@
+06262edc257418e9987caf999f9a7a3e1547adff
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/HEAD
new file mode 100755
index 0000000..cb43805
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/config
new file mode 100755
index 0000000..454e576
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/config
@@ -0,0 +1,8 @@
+[core]
+	repositoryformatversion = 0
+	filemode = false
+	bare = false
+	logallrefupdates = true
+	symlinks = false
+	ignorecase = true
+	hideDotFiles = dotGitOnly
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/index
new file mode 100755
index 0000000..f5f35e2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/logs/HEAD
new file mode 100755
index 0000000..fc49c6f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/logs/HEAD
@@ -0,0 +1,14 @@
+0000000000000000000000000000000000000000 108b485d8268ea595df8ffea74f0f4b186577d32 nulltoken <emeric.fermas at gmail.com> 1380209394 +0200	commit (initial): initial
+108b485d8268ea595df8ffea74f0f4b186577d32 4d6558b8fa764baeb0f19c1e857df91e0eda5a0f nulltoken <emeric.fermas at gmail.com> 1380209404 +0200	commit: second
+4d6558b8fa764baeb0f19c1e857df91e0eda5a0f b240c0fb88c5a629e00ebc1275fa1f33e364a705 nulltoken <emeric.fermas at gmail.com> 1380209414 +0200	commit: third
+b240c0fb88c5a629e00ebc1275fa1f33e364a705 81f4b1aac643e6983fab370eae8aefccecbf3a4c nulltoken <emeric.fermas at gmail.com> 1380209425 +0200	commit: A
+81f4b1aac643e6983fab370eae8aefccecbf3a4c 6126a5f9c57ebc81e64370ec3095184ad92dab1c nulltoken <emeric.fermas at gmail.com> 1380209445 +0200	commit: c
+6126a5f9c57ebc81e64370ec3095184ad92dab1c 4d6558b8fa764baeb0f19c1e857df91e0eda5a0f nulltoken <emeric.fermas at gmail.com> 1380209455 +0200	reset: moving to 4d6558b8fa764baeb0f19c1e857df91e0eda5a0f
+4d6558b8fa764baeb0f19c1e857df91e0eda5a0f 31fc9136820b507e938a9c6b88bf2c567a9f6f4b nulltoken <emeric.fermas at gmail.com> 1380209465 +0200	commit: B
+31fc9136820b507e938a9c6b88bf2c567a9f6f4b ce1c4f8b6120122e23d4442925d98c56c41917d8 nulltoken <emeric.fermas at gmail.com> 1380209486 +0200	merge c: Merge made by the 'recursive' strategy.
+ce1c4f8b6120122e23d4442925d98c56c41917d8 4d6558b8fa764baeb0f19c1e857df91e0eda5a0f nulltoken <emeric.fermas at gmail.com> 1380209486 +0200	reset: moving to 4d6558b8fa764baeb0f19c1e857df91e0eda5a0f
+4d6558b8fa764baeb0f19c1e857df91e0eda5a0f 6a12b56088706aa6c39ccd23b7c7ce60f3a0b9a1 nulltoken <emeric.fermas at gmail.com> 1380209496 +0200	commit: D
+6a12b56088706aa6c39ccd23b7c7ce60f3a0b9a1 1e016431ec7b22dd3e23f3e6f5f68f358f9227cf nulltoken <emeric.fermas at gmail.com> 1380209527 +0200	commit: another
+1e016431ec7b22dd3e23f3e6f5f68f358f9227cf a9eb02af13df030159e39f70330d5c8a47655691 nulltoken <emeric.fermas at gmail.com> 1380209547 +0200	commit: yet another
+a9eb02af13df030159e39f70330d5c8a47655691 949b98e208015bfc0e2f573debc34ae2f97a7f0e nulltoken <emeric.fermas at gmail.com> 1380209557 +0200	merge ce1c4f8b6120122e23d4442925d98c56c41917d8: Merge made by the 'recursive' strategy.
+949b98e208015bfc0e2f573debc34ae2f97a7f0e a6095f816e81f64651595d488badc42399837d6a nulltoken <emeric.fermas at gmail.com> 1380209567 +0200	commit: x
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..fc49c6f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/logs/refs/heads/master
@@ -0,0 +1,14 @@
+0000000000000000000000000000000000000000 108b485d8268ea595df8ffea74f0f4b186577d32 nulltoken <emeric.fermas at gmail.com> 1380209394 +0200	commit (initial): initial
+108b485d8268ea595df8ffea74f0f4b186577d32 4d6558b8fa764baeb0f19c1e857df91e0eda5a0f nulltoken <emeric.fermas at gmail.com> 1380209404 +0200	commit: second
+4d6558b8fa764baeb0f19c1e857df91e0eda5a0f b240c0fb88c5a629e00ebc1275fa1f33e364a705 nulltoken <emeric.fermas at gmail.com> 1380209414 +0200	commit: third
+b240c0fb88c5a629e00ebc1275fa1f33e364a705 81f4b1aac643e6983fab370eae8aefccecbf3a4c nulltoken <emeric.fermas at gmail.com> 1380209425 +0200	commit: A
+81f4b1aac643e6983fab370eae8aefccecbf3a4c 6126a5f9c57ebc81e64370ec3095184ad92dab1c nulltoken <emeric.fermas at gmail.com> 1380209445 +0200	commit: c
+6126a5f9c57ebc81e64370ec3095184ad92dab1c 4d6558b8fa764baeb0f19c1e857df91e0eda5a0f nulltoken <emeric.fermas at gmail.com> 1380209455 +0200	reset: moving to 4d6558b8fa764baeb0f19c1e857df91e0eda5a0f
+4d6558b8fa764baeb0f19c1e857df91e0eda5a0f 31fc9136820b507e938a9c6b88bf2c567a9f6f4b nulltoken <emeric.fermas at gmail.com> 1380209465 +0200	commit: B
+31fc9136820b507e938a9c6b88bf2c567a9f6f4b ce1c4f8b6120122e23d4442925d98c56c41917d8 nulltoken <emeric.fermas at gmail.com> 1380209486 +0200	merge c: Merge made by the 'recursive' strategy.
+ce1c4f8b6120122e23d4442925d98c56c41917d8 4d6558b8fa764baeb0f19c1e857df91e0eda5a0f nulltoken <emeric.fermas at gmail.com> 1380209486 +0200	reset: moving to 4d6558b8fa764baeb0f19c1e857df91e0eda5a0f
+4d6558b8fa764baeb0f19c1e857df91e0eda5a0f 6a12b56088706aa6c39ccd23b7c7ce60f3a0b9a1 nulltoken <emeric.fermas at gmail.com> 1380209496 +0200	commit: D
+6a12b56088706aa6c39ccd23b7c7ce60f3a0b9a1 1e016431ec7b22dd3e23f3e6f5f68f358f9227cf nulltoken <emeric.fermas at gmail.com> 1380209527 +0200	commit: another
+1e016431ec7b22dd3e23f3e6f5f68f358f9227cf a9eb02af13df030159e39f70330d5c8a47655691 nulltoken <emeric.fermas at gmail.com> 1380209547 +0200	commit: yet another
+a9eb02af13df030159e39f70330d5c8a47655691 949b98e208015bfc0e2f573debc34ae2f97a7f0e nulltoken <emeric.fermas at gmail.com> 1380209557 +0200	merge ce1c4f8b6120122e23d4442925d98c56c41917d8: Merge made by the 'recursive' strategy.
+949b98e208015bfc0e2f573debc34ae2f97a7f0e a6095f816e81f64651595d488badc42399837d6a nulltoken <emeric.fermas at gmail.com> 1380209567 +0200	commit: x
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/03/00021985931292d0611b9232e757035fefc04d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/03/00021985931292d0611b9232e757035fefc04d
new file mode 100755
index 0000000..4b98de8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/03/00021985931292d0611b9232e757035fefc04d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/10/8b485d8268ea595df8ffea74f0f4b186577d32 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/10/8b485d8268ea595df8ffea74f0f4b186577d32
new file mode 100755
index 0000000..0d6187b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/10/8b485d8268ea595df8ffea74f0f4b186577d32 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/10/bd08b099ecb79184c60183f5c94ca915f427ad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/10/bd08b099ecb79184c60183f5c94ca915f427ad
new file mode 100755
index 0000000..3540cfa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/10/bd08b099ecb79184c60183f5c94ca915f427ad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/17/8481050188cf00d7d9cd5a11e43ab8fab9294f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/17/8481050188cf00d7d9cd5a11e43ab8fab9294f
new file mode 100755
index 0000000..f2eaf83
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/17/8481050188cf00d7d9cd5a11e43ab8fab9294f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/19/1faf88a5826a99f475baaf8b13652c4e40bfe6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/19/1faf88a5826a99f475baaf8b13652c4e40bfe6
new file mode 100755
index 0000000..e44246b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/19/1faf88a5826a99f475baaf8b13652c4e40bfe6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/1e/016431ec7b22dd3e23f3e6f5f68f358f9227cf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/1e/016431ec7b22dd3e23f3e6f5f68f358f9227cf
new file mode 100755
index 0000000..a876981
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/1e/016431ec7b22dd3e23f3e6f5f68f358f9227cf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/22/3b7836fb19fdf64ba2d3cd6173c6a283141f78 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/22/3b7836fb19fdf64ba2d3cd6173c6a283141f78
new file mode 100755
index 0000000..faf1fbe
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/22/3b7836fb19fdf64ba2d3cd6173c6a283141f78 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/25/d5edf8c0ef17e8a13b8da75913dcec4ea7afc1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/25/d5edf8c0ef17e8a13b8da75913dcec4ea7afc1
new file mode 100755
index 0000000..3353bf9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/25/d5edf8c0ef17e8a13b8da75913dcec4ea7afc1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/2b/df67abb163a4ffb2d7f3f0880c9fe5068ce782 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/2b/df67abb163a4ffb2d7f3f0880c9fe5068ce782
new file mode 100755
index 0000000..d0398e6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/2b/df67abb163a4ffb2d7f3f0880c9fe5068ce782 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/31/fc9136820b507e938a9c6b88bf2c567a9f6f4b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/31/fc9136820b507e938a9c6b88bf2c567a9f6f4b
new file mode 100755
index 0000000..7752a95
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/31/fc9136820b507e938a9c6b88bf2c567a9f6f4b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/42/8f9554a2eec22de29898819b579466af7c1583 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/42/8f9554a2eec22de29898819b579466af7c1583
new file mode 100755
index 0000000..f27d552
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/42/8f9554a2eec22de29898819b579466af7c1583 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/4d/6558b8fa764baeb0f19c1e857df91e0eda5a0f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/4d/6558b8fa764baeb0f19c1e857df91e0eda5a0f
new file mode 100755
index 0000000..311ee2f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/4d/6558b8fa764baeb0f19c1e857df91e0eda5a0f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/4f/2d9ce01ad5249cabdc6565366af8aff85b1525 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/4f/2d9ce01ad5249cabdc6565366af8aff85b1525
new file mode 100755
index 0000000..f04379f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/4f/2d9ce01ad5249cabdc6565366af8aff85b1525 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/52/912fbab0715dec53d43053966e78ad213ba359 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/52/912fbab0715dec53d43053966e78ad213ba359
new file mode 100755
index 0000000..5deb7ec
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/52/912fbab0715dec53d43053966e78ad213ba359 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/56/26abf0f72e58d7a153368ba57db4c673c0e171 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/56/26abf0f72e58d7a153368ba57db4c673c0e171
new file mode 100755
index 0000000..4d54474
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/56/26abf0f72e58d7a153368ba57db4c673c0e171 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/61/26a5f9c57ebc81e64370ec3095184ad92dab1c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/61/26a5f9c57ebc81e64370ec3095184ad92dab1c
new file mode 100755
index 0000000..e71707f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/61/26a5f9c57ebc81e64370ec3095184ad92dab1c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/62/d8fe9f6db631bd3a19140699101c9e281c9f9d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/62/d8fe9f6db631bd3a19140699101c9e281c9f9d
new file mode 100755
index 0000000..734f7dc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/62/d8fe9f6db631bd3a19140699101c9e281c9f9d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/65/a91bc2262480dce4c5979519aae6668368eb4e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/65/a91bc2262480dce4c5979519aae6668368eb4e
new file mode 100755
index 0000000..ef9f53a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/65/a91bc2262480dce4c5979519aae6668368eb4e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/68/0166b6cd31f76354fee2572618e6b0142d05e6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/68/0166b6cd31f76354fee2572618e6b0142d05e6
new file mode 100755
index 0000000..36f1986
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/68/0166b6cd31f76354fee2572618e6b0142d05e6
@@ -0,0 +1,2 @@
+xŒK @]sŠÙ›4¤|c<Co0ŒS‚–Ö .¼½¸yy›÷:eÐ&žŽôîàH›4;Á£#rl#óÝØäÙ³8\-aŠ¤Uÿ¾ø¨µtÕÇcù3Kƒý³mýxÊ©Ò
+O«´Jï[®T¶i$WÐ6 Á8kç!¨Ô¢~U<)a
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/69/3a3de402bb23897ed5c931273e53c78eff0495 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/69/3a3de402bb23897ed5c931273e53c78eff0495
new file mode 100755
index 0000000..80a08fc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/69/3a3de402bb23897ed5c931273e53c78eff0495 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/6a/12b56088706aa6c39ccd23b7c7ce60f3a0b9a1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/6a/12b56088706aa6c39ccd23b7c7ce60f3a0b9a1
new file mode 100755
index 0000000..9c773e4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/6a/12b56088706aa6c39ccd23b7c7ce60f3a0b9a1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/6d/218e42592043041c4da016ff298cf241b86c3c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/6d/218e42592043041c4da016ff298cf241b86c3c
new file mode 100755
index 0000000..59fc709
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/6d/218e42592043041c4da016ff298cf241b86c3c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/75/bb152c600647586c226d98411b1d2f9861af5a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/75/bb152c600647586c226d98411b1d2f9861af5a
new file mode 100755
index 0000000..a2016f4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/75/bb152c600647586c226d98411b1d2f9861af5a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/81/f4b1aac643e6983fab370eae8aefccecbf3a4c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/81/f4b1aac643e6983fab370eae8aefccecbf3a4c
new file mode 100755
index 0000000..e47f3fb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/81/f4b1aac643e6983fab370eae8aefccecbf3a4c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/8e/c1d96451ff05451720e4e8968812c46b35e5e4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/8e/c1d96451ff05451720e4e8968812c46b35e5e4
new file mode 100755
index 0000000..432b2c1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/8e/c1d96451ff05451720e4e8968812c46b35e5e4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/94/9b98e208015bfc0e2f573debc34ae2f97a7f0e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/94/9b98e208015bfc0e2f573debc34ae2f97a7f0e
new file mode 100755
index 0000000..2c7aafa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/94/9b98e208015bfc0e2f573debc34ae2f97a7f0e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/9c/06d71b8406ab97537e3acdc39a2c4ade7a9411 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/9c/06d71b8406ab97537e3acdc39a2c4ade7a9411
new file mode 100755
index 0000000..5fff6fa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/9c/06d71b8406ab97537e3acdc39a2c4ade7a9411 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/a6/095f816e81f64651595d488badc42399837d6a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/a6/095f816e81f64651595d488badc42399837d6a
new file mode 100755
index 0000000..eb9ab14
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/a6/095f816e81f64651595d488badc42399837d6a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/a9/e3325a07117aa5381e044a8d96c26eb30d729d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/a9/e3325a07117aa5381e044a8d96c26eb30d729d
new file mode 100755
index 0000000..ee45b76
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/a9/e3325a07117aa5381e044a8d96c26eb30d729d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/a9/eb02af13df030159e39f70330d5c8a47655691 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/a9/eb02af13df030159e39f70330d5c8a47655691
new file mode 100755
index 0000000..320161a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/a9/eb02af13df030159e39f70330d5c8a47655691
@@ -0,0 +1,2 @@
+xŽA
+à »öîAý&1PJ¯òÕgc±fÑÛ×3t÷˜aà…’óÖ¤!uiqdöF/촍ÑÃzbFLŠBÛEwé¬xsÅѤ†Ò“%0{cb$J„)ir‰F—c搟m-Uç¾·òÂ!oȨ[jæÏã™yÛ‡Pò]jrʨe´³¼ö¡D§ýdß¹ø¢I>J[QÅhK%
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/aa/d8d5cef3915ab78b3227abaaac99b62db9eb54 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/aa/d8d5cef3915ab78b3227abaaac99b62db9eb54
new file mode 100755
index 0000000..4cbaff1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/aa/d8d5cef3915ab78b3227abaaac99b62db9eb54 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/aa/ddd4f14847e0e323924ec262c2343249a84f8b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/aa/ddd4f14847e0e323924ec262c2343249a84f8b
new file mode 100755
index 0000000..651ec78
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/aa/ddd4f14847e0e323924ec262c2343249a84f8b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/b2/40c0fb88c5a629e00ebc1275fa1f33e364a705 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/b2/40c0fb88c5a629e00ebc1275fa1f33e364a705
new file mode 100755
index 0000000..fe86e7c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/b2/40c0fb88c5a629e00ebc1275fa1f33e364a705
@@ -0,0 +1,3 @@
+xŽM
+à »öîAͧQ(¥WñçÙJc,ÖÜ¿ž¡«7¼Øj-ƒ+E—Ñner†´ÌYè9› Xg¬•*’	«†±ï8§d´¶Áf¿
+Ad预Õ[ÊNB yíEfþ¯Öùqîûhoü†Š^â’Ñ«ÿ>žÕ—}‰­Þ¹\­P‘$~ Ø´óäÀŸ9¯ÒûµGG¬
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/ce/1c4f8b6120122e23d4442925d98c56c41917d8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/ce/1c4f8b6120122e23d4442925d98c56c41917d8
new file mode 100755
index 0000000..408c5da
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/ce/1c4f8b6120122e23d4442925d98c56c41917d8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/d5/aab219a814ddbe4b3aaedf03cdea491b218ec4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/d5/aab219a814ddbe4b3aaedf03cdea491b218ec4
new file mode 100755
index 0000000..4512d16
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/d5/aab219a814ddbe4b3aaedf03cdea491b218ec4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/f2/ad6c76f0115a6ba5b00456a849810e7ec0af20 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/f2/ad6c76f0115a6ba5b00456a849810e7ec0af20
new file mode 100755
index 0000000..a364631
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/f2/ad6c76f0115a6ba5b00456a849810e7ec0af20 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/f7/0f10e4db19068f79bc43844b49f3eece45c4e8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/f7/0f10e4db19068f79bc43844b49f3eece45c4e8
new file mode 100755
index 0000000..2e15b4f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/f7/0f10e4db19068f79bc43844b49f3eece45c4e8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/f7/19efd430d52bcfc8566a43b2eb655688d38871 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/f7/19efd430d52bcfc8566a43b2eb655688d38871
new file mode 100755
index 0000000..b2d51d9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/objects/f7/19efd430d52bcfc8566a43b2eb655688d38871 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/heads/master
new file mode 100755
index 0000000..0b2a541
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/heads/master
@@ -0,0 +1 @@
+a6095f816e81f64651595d488badc42399837d6a
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/A b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/A
new file mode 100755
index 0000000..aced4fd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/A
@@ -0,0 +1 @@
+aaddd4f14847e0e323924ec262c2343249a84f8b
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/B b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/B
new file mode 100755
index 0000000..ab1a5e6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/B
@@ -0,0 +1 @@
+52912fbab0715dec53d43053966e78ad213ba359
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/D b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/D
new file mode 100755
index 0000000..90f4208
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/D
@@ -0,0 +1 @@
+10bd08b099ecb79184c60183f5c94ca915f427ad
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/R b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/R
new file mode 100755
index 0000000..ef04b7c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/R
@@ -0,0 +1 @@
+680166b6cd31f76354fee2572618e6b0142d05e6
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/c
new file mode 100755
index 0000000..650d82f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/c
@@ -0,0 +1 @@
+6126a5f9c57ebc81e64370ec3095184ad92dab1c
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/e
new file mode 100755
index 0000000..5e88d6f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/.gitted/refs/tags/e
@@ -0,0 +1 @@
+1e016431ec7b22dd3e23f3e6f5f68f358f9227cf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/another b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/another
new file mode 100755
index 0000000..a3d00fa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/another
@@ -0,0 +1 @@
+DDD
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/file
new file mode 100755
index 0000000..fd66be0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/file
@@ -0,0 +1 @@
+X
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/side b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/side
new file mode 100755
index 0000000..fd66be0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/describe/side
@@ -0,0 +1 @@
+X
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/config
new file mode 100755
index 0000000..77a27ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/config
@@ -0,0 +1,6 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = false
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/index
new file mode 100755
index 0000000..e107187
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/logs/HEAD
new file mode 100755
index 0000000..8c6f6fd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/logs/HEAD
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 d70d245ed97ed2aa596dd1af6536e4bfdb047b69 Russell Belfer <rb at github.com> 1347559804 -0700	commit (initial): initial commit
+d70d245ed97ed2aa596dd1af6536e4bfdb047b69 7a9e0b02e63179929fed24f0a3e0f19168114d10 Russell Belfer <rb at github.com> 1347560491 -0700	commit: some changes
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..8c6f6fd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/logs/refs/heads/master
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 d70d245ed97ed2aa596dd1af6536e4bfdb047b69 Russell Belfer <rb at github.com> 1347559804 -0700	commit (initial): initial commit
+d70d245ed97ed2aa596dd1af6536e4bfdb047b69 7a9e0b02e63179929fed24f0a3e0f19168114d10 Russell Belfer <rb at github.com> 1347560491 -0700	commit: some changes
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/29/ab7053bb4dde0298e03e2c179e890b7dd465a7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/29/ab7053bb4dde0298e03e2c179e890b7dd465a7
new file mode 100755
index 0000000..94f9a67
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/29/ab7053bb4dde0298e03e2c179e890b7dd465a7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/3e/5bcbad2a68e5bc60a53b8388eea53a1a7ab847 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/3e/5bcbad2a68e5bc60a53b8388eea53a1a7ab847
new file mode 100755
index 0000000..9fed523
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/3e/5bcbad2a68e5bc60a53b8388eea53a1a7ab847 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/54/6c735f16a3b44d9784075c2c0dab2ac9bf1989 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/54/6c735f16a3b44d9784075c2c0dab2ac9bf1989
new file mode 100755
index 0000000..d7df4d6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/54/6c735f16a3b44d9784075c2c0dab2ac9bf1989 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/7a/9e0b02e63179929fed24f0a3e0f19168114d10 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/7a/9e0b02e63179929fed24f0a3e0f19168114d10
new file mode 100755
index 0000000..9bc25eb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/7a/9e0b02e63179929fed24f0a3e0f19168114d10 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/7b/808f723a8ca90df319682c221187235af76693 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/7b/808f723a8ca90df319682c221187235af76693
new file mode 100755
index 0000000..2fd266b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/7b/808f723a8ca90df319682c221187235af76693 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/88/789109439c1e1c3cd45224001edee5304ed53c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/88/789109439c1e1c3cd45224001edee5304ed53c
new file mode 100755
index 0000000..7598b59
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/88/789109439c1e1c3cd45224001edee5304ed53c
@@ -0,0 +1 @@
+x+)JMU07g040031QHÌË/ÉH-Ò+©(aÉ)Ž[¼Åwz{Œïj­“û%;¡ÊŠRSrSÁª4Wïö½Ç4そŽø¼NîÚ+©Ë¶a
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/cb/8294e696339863df760b2ff5d1e275bee72455 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/cb/8294e696339863df760b2ff5d1e275bee72455
new file mode 100755
index 0000000..86ebe04
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/cb/8294e696339863df760b2ff5d1e275bee72455 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/d7/0d245ed97ed2aa596dd1af6536e4bfdb047b69 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/d7/0d245ed97ed2aa596dd1af6536e4bfdb047b69
new file mode 100755
index 0000000..99304c4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/objects/d7/0d245ed97ed2aa596dd1af6536e4bfdb047b69
@@ -0,0 +1 @@
+x•Û	!óm·_ׄRB:XÝkVpWpµÿ© ¿‡™9±î{î ,^z#‚œôšŒ7JygÔš¬áA¦„« i1Y©Ù2úV¼ÇyR)𢒨Á½…ç'÷m„[¬û„ÒÑ;®áÊ-çl®ó¯Oô_“å#÷¼ø%Øœv8¤
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/refs/heads/master
new file mode 100755
index 0000000..a83afc3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/.gitted/refs/heads/master
@@ -0,0 +1 @@
+7a9e0b02e63179929fed24f0a3e0f19168114d10
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/another.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/another.txt
new file mode 100755
index 0000000..d0e0bae
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/another.txt
@@ -0,0 +1,38 @@
+Git is fast. With Git, nearly all operations are performed locally, giving
+it an huge speed advantage on centralized systems that constantly have to
+communicate with a server somewh3r3.
+
+For testing, large AWS instances were set up in the same availability
+zone. Git and SVN were installed on both machines, the Ruby repository was
+copied to both Git and SVN servers, and common operations were performed on
+both.
+
+In some cases the commands don't match up exactly. Here, matching on the
+lowest common denominator was attempted. For example, the 'commit' tests
+also include the time to push for Git, though most of the time you would not
+actually be pushing to the server immediately after a commit where the two
+commands cannot be separated in SVN.
+
+Note that this is the best case scenario for SVN - a server with no load
+with an 80MB/s bandwidth connection to the client machine. Nearly all of
+these times would be even worse for SVN if that connection was slower, while
+many of the Git times would not be affected.
+
+Clearly, in many of these common version control operations, Git is one or
+two orders of magnitude faster than SVN, even under ideal conditions for
+SVN.
+
+Let's see how common operations stack up against Subversion, a common
+centralized version control system that is similar to CVS or
+Perforce. Smaller is faster.
+
+One place where Git is slower is in the initial clone operation. Here, Git
+One place where Git is slower is in the initial clone operation. Here, Git
+One place where Git is slower is in the initial clone operation. Here, Git
+seen in the above charts, it's not considerably slower for an operation that
+is only performed once.
+
+It's also interesting to note that the size of the data on the client side
+is very similar even though Git also has every version of every file for the
+entire history of the project. This illustrates how efficient it is at
+compressing and storing data on the client side.
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/readme.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/readme.txt
new file mode 100755
index 0000000..beedf28
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff/readme.txt
@@ -0,0 +1,36 @@
+The Git feature that r3ally mak3s it stand apart from n3arly 3v3ry other SCM
+out there is its branching model.
+
+Git allows and encourages you to have multiple local branches that can be
+entirely independent of each other. The creation, merging, and deletion of
+those lines of development takes seconds.
+
+Git allows and encourages you to have multiple local branches that can be
+entirely independent of each other. The creation, merging, and deletion of
+those lines of development takes seconds.
+
+This means that you can do things like:
+
+Role-Bas3d Codelin3s. Have a branch that always contains only what goes to
+production, another that you merge work into for testing, and several
+smaller ones for day to day work.
+
+Feature Based Workflow. Create new branches for each new feature you're
+working on so you can seamlessly switch back and forth between them, then
+delete each branch when that feature gets merged into your main line.
+
+Disposable Experimentation. Create a branch to experiment in, realize it's
+not going to work, and just delete it - abandoning the work—with nobody else
+ever seeing it (even if you've pushed other branches in the meantime).
+
+Notably, when you push to a remote repository, you do not have to push all
+share it with others.
+
+Git allows and encourages you to have multiple local branches that can be
+entirely independent of each other. The creation, merging, and deletion of
+those lines of development takes seconds.
+
+There are ways to accomplish some of this with other systems, but the work
+involved is much more difficult and error-prone. Git makes this process
+incredibly easy and it changes the way most developers work when they learn
+it.!
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/config
new file mode 100755
index 0000000..6c9406b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/config
@@ -0,0 +1,7 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
+	precomposeunicode = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/index
new file mode 100755
index 0000000..f73027e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/0a/37045ca6d8503e9bcf06a12abbbc8e92664cce b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/0a/37045ca6d8503e9bcf06a12abbbc8e92664cce
new file mode 100755
index 0000000..1ece99c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/0a/37045ca6d8503e9bcf06a12abbbc8e92664cce differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/10/808fe9c9be5a190c0ba68d1a002233fb363508 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/10/808fe9c9be5a190c0ba68d1a002233fb363508
new file mode 100755
index 0000000..90313fe
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/10/808fe9c9be5a190c0ba68d1a002233fb363508 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/13/ecf3d572dbc5e5b32c8ba067d1d1e0939572e8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/13/ecf3d572dbc5e5b32c8ba067d1d1e0939572e8
new file mode 100755
index 0000000..360dc3b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/13/ecf3d572dbc5e5b32c8ba067d1d1e0939572e8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/17/cfad36e93db7706b16bef5ef842ba1e5ca06ab b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/17/cfad36e93db7706b16bef5ef842ba1e5ca06ab
new file mode 100755
index 0000000..603aa49
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/17/cfad36e93db7706b16bef5ef842ba1e5ca06ab differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/1a/9932083f96b0db42552103d40076f62fa8235e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/1a/9932083f96b0db42552103d40076f62fa8235e
new file mode 100755
index 0000000..b6f0453
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/1a/9932083f96b0db42552103d40076f62fa8235e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/1a/e3be57f869687d983066a0f5d2aaea1b82ddc5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/1a/e3be57f869687d983066a0f5d2aaea1b82ddc5
new file mode 100755
index 0000000..be85c78
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/1a/e3be57f869687d983066a0f5d2aaea1b82ddc5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/1b/525b0a6c5218b069b601ce91fce8eaf0a54e20 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/1b/525b0a6c5218b069b601ce91fce8eaf0a54e20
new file mode 100755
index 0000000..e8145ed
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/1b/525b0a6c5218b069b601ce91fce8eaf0a54e20 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/1e/82c3b234e37da82e5b23e0e2a70bca68ee12c6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/1e/82c3b234e37da82e5b23e0e2a70bca68ee12c6
new file mode 100755
index 0000000..3ae87cf
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/1e/82c3b234e37da82e5b23e0e2a70bca68ee12c6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/1e/875da9b1e67f853b2eec3e202c21c867097234 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/1e/875da9b1e67f853b2eec3e202c21c867097234
new file mode 100755
index 0000000..f80b361
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/1e/875da9b1e67f853b2eec3e202c21c867097234 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/20/609dbbc32bbfc827528eec3fcea2d024e6dd8a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/20/609dbbc32bbfc827528eec3fcea2d024e6dd8a
new file mode 100755
index 0000000..190c3f2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/20/609dbbc32bbfc827528eec3fcea2d024e6dd8a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/23/f92946d3f38bd090f700d3e8e7b728ffc58264 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/23/f92946d3f38bd090f700d3e8e7b728ffc58264
new file mode 100755
index 0000000..42f49ae
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/23/f92946d3f38bd090f700d3e8e7b728ffc58264 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/24/97c5249408494e66e25070a8c74e49eaeeb6c3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/24/97c5249408494e66e25070a8c74e49eaeeb6c3
new file mode 100755
index 0000000..e1ede9a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/24/97c5249408494e66e25070a8c74e49eaeeb6c3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/24/9a4263be23b4d1c02484cb840b6eca4c6cf74d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/24/9a4263be23b4d1c02484cb840b6eca4c6cf74d
new file mode 100755
index 0000000..1b8d689
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/24/9a4263be23b4d1c02484cb840b6eca4c6cf74d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/25/2a3e19fd2c6fb7b20c111142c5bd5fb9ea6b8e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/25/2a3e19fd2c6fb7b20c111142c5bd5fb9ea6b8e
new file mode 100755
index 0000000..10c3400
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/25/2a3e19fd2c6fb7b20c111142c5bd5fb9ea6b8e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/27/93544db9060bab4f9169e5b89c82f9fa7c7fa6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/27/93544db9060bab4f9169e5b89c82f9fa7c7fa6
new file mode 100755
index 0000000..689f5b9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/27/93544db9060bab4f9169e5b89c82f9fa7c7fa6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/29/1f1ff3cbb9a6f153678d9657679e3d4bf257df b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/29/1f1ff3cbb9a6f153678d9657679e3d4bf257df
new file mode 100755
index 0000000..6af5dda
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/29/1f1ff3cbb9a6f153678d9657679e3d4bf257df differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/2f/f7b811eee62a73959350b1f7349f6f4d0c882d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/2f/f7b811eee62a73959350b1f7349f6f4d0c882d
new file mode 100755
index 0000000..d2b911d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/2f/f7b811eee62a73959350b1f7349f6f4d0c882d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/39/91dce9e71a0641ca49a6a4eea6c9e7ff402ed4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/39/91dce9e71a0641ca49a6a4eea6c9e7ff402ed4
new file mode 100755
index 0000000..69d213d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/39/91dce9e71a0641ca49a6a4eea6c9e7ff402ed4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/45/eef2a9317e179984649de247269e38cd5d99cf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/45/eef2a9317e179984649de247269e38cd5d99cf
new file mode 100755
index 0000000..e501456
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/45/eef2a9317e179984649de247269e38cd5d99cf
@@ -0,0 +1,2 @@
+x¥ÎÁJÅ0…a×yŠÙ_I›IqwÁ¥o0Lo+$¹&©àÛ[õÜþŸ””öƒŸzU…à&ÒÁFY„,ñ:¯ÞYš¼CT·8B¥Õ	ŽæÎUs¯H,BL‘Â)ËÈ(‚ër.cŒažÃ
}+^Y>mpÕšö¶_
žÞÿÚí¥õºsçG)éì&k}˜G¸à€hÎzR»þëļi*Ÿ
+RrÿñsŽ ç›Âý—Ôö’›ùÐXã
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/4a/076277b884c519a932be67e346db2ac80a98fa b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/4a/076277b884c519a932be67e346db2ac80a98fa
new file mode 100755
index 0000000..b855408
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/4a/076277b884c519a932be67e346db2ac80a98fa differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/4c/3bd7182ad66ea7aa20ba47ae82812b710d169c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/4c/3bd7182ad66ea7aa20ba47ae82812b710d169c
new file mode 100755
index 0000000..65740b4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/4c/3bd7182ad66ea7aa20ba47ae82812b710d169c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/4c/a10087e696d2ba78d07b146a118e9a7096ed4f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/4c/a10087e696d2ba78d07b146a118e9a7096ed4f
new file mode 100755
index 0000000..b05e7d6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/4c/a10087e696d2ba78d07b146a118e9a7096ed4f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/4d/de2b17d1c982cd988f21d24350a214401e4a1e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/4d/de2b17d1c982cd988f21d24350a214401e4a1e
new file mode 100755
index 0000000..57a8dfe
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/4d/de2b17d1c982cd988f21d24350a214401e4a1e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/4f/31e0248ac800a1edc78b74f74e86f5eba90e87 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/4f/31e0248ac800a1edc78b74f74e86f5eba90e87
new file mode 100755
index 0000000..0f31b97
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/4f/31e0248ac800a1edc78b74f74e86f5eba90e87 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/50/17c9456d013b2c7712d29aab73b681c880f509 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/50/17c9456d013b2c7712d29aab73b681c880f509
new file mode 100755
index 0000000..5b96aa5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/50/17c9456d013b2c7712d29aab73b681c880f509 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/50/438cfa585c1d15cf3650ed1bf641da937cc261 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/50/438cfa585c1d15cf3650ed1bf641da937cc261
new file mode 100755
index 0000000..8db9090
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/50/438cfa585c1d15cf3650ed1bf641da937cc261 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/52/c3cd1ff6234b95fecbaf9ef13624da17697b8d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/52/c3cd1ff6234b95fecbaf9ef13624da17697b8d
new file mode 100755
index 0000000..4bbc0ea
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/52/c3cd1ff6234b95fecbaf9ef13624da17697b8d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/55/0d730ba1b8c4937ea170b37c7ba91d792c0aaa b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/55/0d730ba1b8c4937ea170b37c7ba91d792c0aaa
new file mode 100755
index 0000000..680e487
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/55/0d730ba1b8c4937ea170b37c7ba91d792c0aaa differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/66/81f1844dc677e5ff07ffd993461f5c441e6af5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/66/81f1844dc677e5ff07ffd993461f5c441e6af5
new file mode 100755
index 0000000..86a3828
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/66/81f1844dc677e5ff07ffd993461f5c441e6af5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/69/ddefb5c245e2f9ee62bd4cabd8ebe60a01e448 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/69/ddefb5c245e2f9ee62bd4cabd8ebe60a01e448
new file mode 100755
index 0000000..81b606f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/69/ddefb5c245e2f9ee62bd4cabd8ebe60a01e448 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/6b/6c2067c6d968f9bddb9b900ee1ab7e5b067430 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/6b/6c2067c6d968f9bddb9b900ee1ab7e5b067430
new file mode 100755
index 0000000..aa9d7b0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/6b/6c2067c6d968f9bddb9b900ee1ab7e5b067430
@@ -0,0 +1,2 @@
+x¥Î;
+1…aë¬âö‚ä	ˆX)¸‹$sãDˆ3æº{.Áö+þsšsjÀ…Þµ‚'£fg=Cm⤄çˆA §<p&m¨5\H²¹‚Ï:0¥•
ThaŒC…—J[;̱¨<Î^)‰ëmYÜ\xu¬pÅ’S]ú§Âññ³û¹¶’\s‡°æ01†¸dTžrJÉÐqµá_rIム/P¿Ký
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/6b/ef49b206b29d9c46456e075722cd1a48b41e4c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/6b/ef49b206b29d9c46456e075722cd1a48b41e4c
new file mode 100755
index 0000000..49e9d65
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/6b/ef49b206b29d9c46456e075722cd1a48b41e4c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/6c/15659c036377aebf3b4569959ca1f5bedb551f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/6c/15659c036377aebf3b4569959ca1f5bedb551f
new file mode 100755
index 0000000..e32471b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/6c/15659c036377aebf3b4569959ca1f5bedb551f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/6e/05acc5a5dab507d91a0a0cc0fb05a3dd98892d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/6e/05acc5a5dab507d91a0a0cc0fb05a3dd98892d
new file mode 100755
index 0000000..26ee224
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/6e/05acc5a5dab507d91a0a0cc0fb05a3dd98892d
@@ -0,0 +1,2 @@
+x¥ANÄ0EYçޏ¨œ8“`	f‡Ä’¸‰ËtD¦ºÜž"€åOúú¿,­Í!ñuUÈ1Õ£*Š…Cò•2G,2‰pžt+“{—®7)ŽœJªcEÅ,JT	1IâCˆ»›88Ùì²tx–ò±é
+OÚÛ¼^¶¯¯¿ìõ¼ZŸÅd(K;'Θ‘	ÝN÷©¦ÿ*q/z“¦¦ùMý`Ÿ÷§¿0ì§~´ûàW@
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/74/6d514eae0c330261d37940cab33aa97fefbd93 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/74/6d514eae0c330261d37940cab33aa97fefbd93
new file mode 100755
index 0000000..ee55d64
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/74/6d514eae0c330261d37940cab33aa97fefbd93
@@ -0,0 +1 @@
+x+)JMU01e040031QHËÌI5Ô+©(Ñ+JÍKÌMMaXY¾àB¸ØŒ¢î|ý²Ò-a'{"ÌŠw
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/74/a4d5394ebcfa7e9f445680897dfbc96586bc86 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/74/a4d5394ebcfa7e9f445680897dfbc96586bc86
new file mode 100755
index 0000000..1bae4a6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/74/a4d5394ebcfa7e9f445680897dfbc96586bc86 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/77/d0a3ed37236a7941d564f08d68d3b36462d231 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/77/d0a3ed37236a7941d564f08d68d3b36462d231
new file mode 100755
index 0000000..db037ca
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/77/d0a3ed37236a7941d564f08d68d3b36462d231
@@ -0,0 +1,2 @@
+x¥Aj1E³ö)´/ìØ„®
+¹…$ËÍ<N<žEoŸ¡ÛÇçñŸ´ZçèãatU@ì)3‹Cæ"	㓪¸"J˜-z
9'2OêºHÑ%J(5¸IÙ2:õ|¼ï¹Lž\t†¶qon$¯MWøÖ^çõ¾ý®p~ü±Ÿë:úLƒ>¥ÕLîqŠÞGø°h­Ùé~uè¿$æ+g¨­+H[Æ^`ÞȏQW
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/7a/de76dd34bba4733cf9878079f9fd4a456a9189 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/7a/de76dd34bba4733cf9878079f9fd4a456a9189
new file mode 100755
index 0000000..cf9bdaa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/7a/de76dd34bba4733cf9878079f9fd4a456a9189
@@ -0,0 +1,3 @@
+x¥ŽA
+Â0E]ç³d’4M"î÷`šm…´5IÞÞ¢Gpû>¼ÿâœÒXÁ4aW³°nˆŒ3âyŒ–,[F­í½ôH­oD-”eªÐ
+:ŠÑ‘cêzš0F¼÷Ûb™C×ÊÖ:Ì®_«¸HNcÖwãóÇçRóH•qN'Ð6x­½F{4ˆj£[j•¿$ê¶0Uåû_Æy*ê&R
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/7a/ff11da95ca2be0bfb74b06e7cc1c480559dbe7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/7a/ff11da95ca2be0bfb74b06e7cc1c480559dbe7
new file mode 100755
index 0000000..d8c9934
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/7a/ff11da95ca2be0bfb74b06e7cc1c480559dbe7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/7f/854619451620f7fbcec7ea171675e615ce92b6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/7f/854619451620f7fbcec7ea171675e615ce92b6
new file mode 100755
index 0000000..df4cbb3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/7f/854619451620f7fbcec7ea171675e615ce92b6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/87/3806f6f27e631eb0b23e4b56bea2bfac14a373 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/87/3806f6f27e631eb0b23e4b56bea2bfac14a373
new file mode 100755
index 0000000..890abcd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/87/3806f6f27e631eb0b23e4b56bea2bfac14a373 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/89/47a46e2097638ca6040ad4877246f4186ec3bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/89/47a46e2097638ca6040ad4877246f4186ec3bd
new file mode 100755
index 0000000..d4018bf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/89/47a46e2097638ca6040ad4877246f4186ec3bd
@@ -0,0 +1,2 @@
+x•ŽAjÃ0E³Ö)´/„ÑŒ,ÉJw….{ƒ‘ò8 ;•åEo_C{nßâ½WÖZçnYÒ©7À:¤8\uÌ!NiÌ@0qaWRˆ4FožÚ°t›¢$
+S˜8"ˆC¦ÌŸ‡¡œ'-ΫD1º÷ûÚ쇖¯›}G«óvß¿7{yü²ÛÛÖÛ¬]Ïe­¯ÖÉ¢‘¼Øb"sÐcµãßöÎñŸÄ|bÑŠ«ùþûLÊ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/89/7d3af16ca9e420cd071b1c4541bd2b91d04c8c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/89/7d3af16ca9e420cd071b1c4541bd2b91d04c8c
new file mode 100755
index 0000000..1dce143
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/89/7d3af16ca9e420cd071b1c4541bd2b91d04c8c
@@ -0,0 +1 @@
+x¥ÎANÄ0@QÖ9…÷HȵÓ$•šY!q'±™ éÒt1·g$ŽÀö-¾~ÙÖµ
 ŸžFWb[hñ¡²qÊ´ˆXY“Æ)™•9Qðî[ºÞ¤È	ƒ£¨'͘‰Õç9dÊ&eò‘ã²uøòsèïÚ׶_Žû¯_öyÚGo2ä¥lëL¼D3§ÏHˆî¡Õ¡ÿŠ¸s­Z!·›ô;X»ªû"Pq
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/8d/7523f6fcb2404257889abe0d96f093d9f524f9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/8d/7523f6fcb2404257889abe0d96f093d9f524f9
new file mode 100755
index 0000000..903ec75
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/8d/7523f6fcb2404257889abe0d96f093d9f524f9
@@ -0,0 +1 @@
+x¥ÎAJÅ0€a×9Åì™IÓ¤w‚à!f&_äõUÓtñnoÁ#¸ý¿nëÚø™F7JZ¹LÑòT$%ŒBQ¬ÎV—à…ÉfeŒ,î›»Ý,9•‰+EålÁ£L$¤a$ÅK¦‚Au|ŒËÖáõç°Þ¬¯m¿÷ž¿þÚçë>zãÁOº­/@SNOfGôˆî¬çê°!îc+­6+ íÆýµ]ÍýERÚ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/8d/fa038554d5b682a51bda8ee3038cee6c63be76 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/8d/fa038554d5b682a51bda8ee3038cee6c63be76
new file mode 100755
index 0000000..b5e08f9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/8d/fa038554d5b682a51bda8ee3038cee6c63be76 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/92/64b96c6d104d0e07ae33d3007b6a48246c6f92 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/92/64b96c6d104d0e07ae33d3007b6a48246c6f92
new file mode 100755
index 0000000..75b047a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/92/64b96c6d104d0e07ae33d3007b6a48246c6f92 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/94/350226b3aa14efac831c803a51f7a09f3fc31a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/94/350226b3aa14efac831c803a51f7a09f3fc31a
new file mode 100755
index 0000000..a5286bc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/94/350226b3aa14efac831c803a51f7a09f3fc31a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/94/75e21dcbc515af8f641576400e4b450e5f4c03 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/94/75e21dcbc515af8f641576400e4b450e5f4c03
new file mode 100755
index 0000000..9e26e34
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/94/75e21dcbc515af8f641576400e4b450e5f4c03 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/94/aaae8954e8bb613de636071da663a621695911 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/94/aaae8954e8bb613de636071da663a621695911
new file mode 100755
index 0000000..5fc167e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/94/aaae8954e8bb613de636071da663a621695911 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/9a/2d780ac2ea0aeabdb9d2a876e6bbfff17b2c44 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/9a/2d780ac2ea0aeabdb9d2a876e6bbfff17b2c44
new file mode 100755
index 0000000..be48c27
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/9a/2d780ac2ea0aeabdb9d2a876e6bbfff17b2c44 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/9a/c0329b8b7a4046210d8b8b02ac02055667de63 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/9a/c0329b8b7a4046210d8b8b02ac02055667de63
new file mode 100755
index 0000000..f322a7c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/9a/c0329b8b7a4046210d8b8b02ac02055667de63 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/9a/c35ff15cd8864aeafd889e4826a3150f0b06c4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/9a/c35ff15cd8864aeafd889e4826a3150f0b06c4
new file mode 100755
index 0000000..75cd714
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/9a/c35ff15cd8864aeafd889e4826a3150f0b06c4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/9b/997daca2a0beb5cc44b32c64f100a9a26d4d4b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/9b/997daca2a0beb5cc44b32c64f100a9a26d4d4b
new file mode 100755
index 0000000..d84ab8d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/9b/997daca2a0beb5cc44b32c64f100a9a26d4d4b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/a3/ac918e3a6604294b239cb956363e83d71abb3b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/a3/ac918e3a6604294b239cb956363e83d71abb3b
new file mode 100755
index 0000000..a693df5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/a3/ac918e3a6604294b239cb956363e83d71abb3b
@@ -0,0 +1 @@
+x¥ÎMJ1@a×9Eí©TçDf7 xˆJRåD¦§5^Ìíðn¿ÅãÕm]ûòöih±çbSK5pâÂ)RDô.‘²V­¥Ù|óÛ„Ô¢§EƒÖBù˜Ræ"ØrPÌKËêÉi6|ÌË6àëÏ!;œe¬}¿÷^¿þìó´ÏÑyòKÝÖ7°KŽC ÏHˆæ¡Õ)ÿŠ˜­uíÒ ô;h¿ŠùÜüQK
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/a5/ac978d4f2a1784f847f41223a34c3e78934238 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/a5/ac978d4f2a1784f847f41223a34c3e78934238
new file mode 100755
index 0000000..f048394
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/a5/ac978d4f2a1784f847f41223a34c3e78934238 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/a7/29eab45c84563135e8631d4010230bc0479f1f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/a7/29eab45c84563135e8631d4010230bc0479f1f
new file mode 100755
index 0000000..5c1faf0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/a7/29eab45c84563135e8631d4010230bc0479f1f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/a9/7157a0d0571698728b6f2f7675b456c98c5961 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/a9/7157a0d0571698728b6f2f7675b456c98c5961
new file mode 100755
index 0000000..3baf494
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/a9/7157a0d0571698728b6f2f7675b456c98c5961 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/af/8f41d0cb7a3079a8f8e231ea2ab8b97837ce13 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/af/8f41d0cb7a3079a8f8e231ea2ab8b97837ce13
new file mode 100755
index 0000000..f0dcaa9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/af/8f41d0cb7a3079a8f8e231ea2ab8b97837ce13 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/b0/5cecf1949d192b6df852b3f71853ef820ee235 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/b0/5cecf1949d192b6df852b3f71853ef820ee235
new file mode 100755
index 0000000..28e148f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/b0/5cecf1949d192b6df852b3f71853ef820ee235 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/b4/f457c219dbb3517be908d4e70f0ada2fd8b8f9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/b4/f457c219dbb3517be908d4e70f0ada2fd8b8f9
new file mode 100755
index 0000000..0c74e76
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/b4/f457c219dbb3517be908d4e70f0ada2fd8b8f9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/bd/474b2519cc15eab801ff851cc7d50f0dee49a1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/bd/474b2519cc15eab801ff851cc7d50f0dee49a1
new file mode 100755
index 0000000..2dc8208
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/bd/474b2519cc15eab801ff851cc7d50f0dee49a1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/bd/f7ba6bc5c4e57ca6595928dcbe6753c8a663ff b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/bd/f7ba6bc5c4e57ca6595928dcbe6753c8a663ff
new file mode 100755
index 0000000..af0232a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/bd/f7ba6bc5c4e57ca6595928dcbe6753c8a663ff differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/cb/a89408dc016f4caddb6dc886fcb58f587a78df b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/cb/a89408dc016f4caddb6dc886fcb58f587a78df
new file mode 100755
index 0000000..e03c749
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/cb/a89408dc016f4caddb6dc886fcb58f587a78df
@@ -0,0 +1,3 @@
+x¥ÎK
+Â0FaÇYE悤¹ÍCq&8t7É[!­¦éÀÝ[p	N¿ÁáĹ”±IM~×* }ʬÈÓ'¬×lºØ´il´à¬xqÅÔ¤wä•Í6kK‚
+šÐcX‡Ì±ë™	^Û0Wyãø^±È+j—aý,òôüÙã²´:rãCœËYvttZUOr¯´RbÓmµá¯ˆ¸câ‚$¾’ÏM‘
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/cd/471f0d8770371e1bc78bcbb38db4c7e4106bd2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/cd/471f0d8770371e1bc78bcbb38db4c7e4106bd2
new file mode 100755
index 0000000..155b452
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/cd/471f0d8770371e1bc78bcbb38db4c7e4106bd2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/cd/ed722d05305c6b181f188c118d2d9810f39bb8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/cd/ed722d05305c6b181f188c118d2d9810f39bb8
new file mode 100755
index 0000000..fd93636
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/cd/ed722d05305c6b181f188c118d2d9810f39bb8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/ce/2792fcae8d704a56901754a0583a7418a21d8a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/ce/2792fcae8d704a56901754a0583a7418a21d8a
new file mode 100755
index 0000000..5863cec
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/ce/2792fcae8d704a56901754a0583a7418a21d8a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/d1/4aa252e52a709d03a3d3d0d965e177eb0a674e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/d1/4aa252e52a709d03a3d3d0d965e177eb0a674e
new file mode 100755
index 0000000..a5d4d78
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/d1/4aa252e52a709d03a3d3d0d965e177eb0a674e
@@ -0,0 +1 @@
+x+)JMU01e040075UHËÌI5Ô+©(Ñ+JÍKÌMMaXY¾àB¸ØŒ¢î|ý²Ò-a'{"Íz
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/d7/bb447df12c6a8aba8727005482fb211f11297a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/d7/bb447df12c6a8aba8727005482fb211f11297a
new file mode 100755
index 0000000..85eb814
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/d7/bb447df12c6a8aba8727005482fb211f11297a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/db/e8727e4806ae88ccc3f0755cae8f8cb7efa2cc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/db/e8727e4806ae88ccc3f0755cae8f8cb7efa2cc
new file mode 100755
index 0000000..8e250ec
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/db/e8727e4806ae88ccc3f0755cae8f8cb7efa2cc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/e1/2af77c510e8ce4c261a3758736109c2c2dd1f0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/e1/2af77c510e8ce4c261a3758736109c2c2dd1f0
new file mode 100755
index 0000000..92a89a2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/e1/2af77c510e8ce4c261a3758736109c2c2dd1f0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100755
index 0000000..7112238
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/e9/091231467304a5ef112de02361d795ef051ee1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/e9/091231467304a5ef112de02361d795ef051ee1
new file mode 100755
index 0000000..43a0062
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/e9/091231467304a5ef112de02361d795ef051ee1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/ee/251372f131d82e575f16fe51c778406d88f8c2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/ee/251372f131d82e575f16fe51c778406d88f8c2
new file mode 100755
index 0000000..ee1edad
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/ee/251372f131d82e575f16fe51c778406d88f8c2
@@ -0,0 +1,2 @@
+x¥ÎM
+Â0@a×9Eö‚dò3“€ˆ+o‘¦¡¶¦)èí-x·ßâñÒ4Ž¥Imp×*³Ô9Sç˜u$\0NuÉؐ1Û^%ïu/æXùÙ$eï,B°P«L¹Kœˆ# 9Fp‰ƒîPĵ
S•·˜^+/òÊu,Ë°~y|üì~^Z-±ÅCšÆ“H‘²hå^i¥Ä¦Ûjã¿"âRÞë,¾HrKï
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/f3/d35bd592fefd8280fc0c302fa9f27dbdd721a3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/f3/d35bd592fefd8280fc0c302fa9f27dbdd721a3
new file mode 100755
index 0000000..62d747c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/f3/d35bd592fefd8280fc0c302fa9f27dbdd721a3
@@ -0,0 +1 @@
+x¥ÍA @Qלbö&fhi)‰1îŒÞb€A1b#LÞÞ&=‚Û¿x?Ì¥díìN*3x“Ì`C§]ô¾´õìpŠ†-&¤H]Š“Ÿ’S´Èc®p£ðY¸Á…kÉí±|Ÿ[»Ÿ›ÔLB‡0—èÞYûq4°ÇQ­u]ÿ…¨ë;K¦lšúH°B¿
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/f4/07be01334e07bfb8f57cd2078f0ee3eb61e085 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/f4/07be01334e07bfb8f57cd2078f0ee3eb61e085
new file mode 100755
index 0000000..d858a87
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/f4/07be01334e07bfb8f57cd2078f0ee3eb61e085
@@ -0,0 +1 @@
+x¥ÎMNÄ0@aÖ9…÷”8®ÓH±CBâNâ™v íL~Üž‘8Ûoñôò±mk¤øЫ*pÒÅ„–Æ31M¬6L1'4'rJÙ\¥êÞ!„bÅkñ=KˆäÊÄt²sá¹øä™zgdôå¨ð!ù6´Á»ÖmmËøiðrù³ó[ëu•.ÏùØ^ÁùК<Z´ÖÜõ¾Úõ_ó9¾ûú´Œýò"ûY›ùû÷PR
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/f9/e215d309644e24fa50d6bd6e6eedba166e56bc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/f9/e215d309644e24fa50d6bd6e6eedba166e56bc
new file mode 100755
index 0000000..b9919c2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/f9/e215d309644e24fa50d6bd6e6eedba166e56bc
@@ -0,0 +1,2 @@
+x¥ÎM
+Â0@a×9Eö‚ÌLÚL"®¼ÅäG­[Óôö<‚Ûoñxq,ehšŒÝ´š³î9ú®·	ЊÌH‰¼H`¬Ãè\{ðj’šŸMwÑ„ÄèH’µYX„ HÇ’9¤À	­J–v«¾H|-yÖç\Ë0ߗϬ÷ŸÝŽs«ƒ4Ùű4ÏÀÐé-€Zu]mù¯ˆ:
ïeR_K§
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/fc/a0c10eb9f1af6494a448d5733d283f5232a514 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/fc/a0c10eb9f1af6494a448d5733d283f5232a514
new file mode 100755
index 0000000..776221d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/fc/a0c10eb9f1af6494a448d5733d283f5232a514 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/ff/8d35b41494f7f0dc92f95d67f54fff274d3fcb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/ff/8d35b41494f7f0dc92f95d67f54fff274d3fcb
new file mode 100755
index 0000000..9296425
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/objects/ff/8d35b41494f7f0dc92f95d67f54fff274d3fcb differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/refs/heads/binary b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/refs/heads/binary
new file mode 100755
index 0000000..7e563c9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/refs/heads/binary
@@ -0,0 +1 @@
+a3ac918e3a6604294b239cb956363e83d71abb3b
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/refs/heads/master
new file mode 100755
index 0000000..f0f3f93
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/refs/heads/master
@@ -0,0 +1 @@
+873806f6f27e631eb0b23e4b56bea2bfac14a373
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/refs/heads/multihunk b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/refs/heads/multihunk
new file mode 100755
index 0000000..41bd37f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/refs/heads/multihunk
@@ -0,0 +1 @@
+cd471f0d8770371e1bc78bcbb38db4c7e4106bd2
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/refs/heads/rename b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/refs/heads/rename
new file mode 100755
index 0000000..3025fbc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/.gitted/refs/heads/rename
@@ -0,0 +1 @@
+4ca10087e696d2ba78d07b146a118e9a7096ed4f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/file1.txt.renamed b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/file1.txt.renamed
new file mode 100755
index 0000000..a97157a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/file1.txt.renamed
@@ -0,0 +1,17 @@
+file1.txt
+file1.txt
+_file1.txt_
+file1.txt
+file1.txt
+file1.txt_renamed
+file1.txt
+
+
+file1.txt
+file1.txt
+file1.txt_renamed
+file1.txt
+file1.txt
+_file1.txt_
+_file1.txt_
+file1.txt
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/file2.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/file2.txt
new file mode 100755
index 0000000..7aff11d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/file2.txt
@@ -0,0 +1,5 @@
+file2
+file2
+file2
+file2!
+file2
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/file3.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/file3.txt
new file mode 100755
index 0000000..9a2d780
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/diff_format_email/file3.txt
@@ -0,0 +1,5 @@
+file3
+file3!
+file3
+file3
+file3
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/COMMIT_EDITMSG b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/COMMIT_EDITMSG
new file mode 100755
index 0000000..01f9a2a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/COMMIT_EDITMSG
@@ -0,0 +1 @@
+commit
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/config
new file mode 100755
index 0000000..a4ef456
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/config
@@ -0,0 +1,5 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = true
+	logallrefupdates = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/index
new file mode 100755
index 0000000..a61e1c5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/info/refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/info/refs
new file mode 100755
index 0000000..3b5bb03
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/info/refs
@@ -0,0 +1 @@
+8d2f05c97ef29a4697b37c30fe81c248ef411a23	refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/logs/HEAD
new file mode 100755
index 0000000..be9b4c6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 8d2f05c97ef29a4697b37c30fe81c248ef411a23 Han-Wen Nienhuys <hanwen at xs4all.nl> 1336844322 -0300	commit (initial): commit
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/logs/refs/heads/master
new file mode 100755
index 0000000..be9b4c6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 8d2f05c97ef29a4697b37c30fe81c248ef411a23 Han-Wen Nienhuys <hanwen at xs4all.nl> 1336844322 -0300	commit (initial): commit
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/03/8d718da6a1ebbc6a7780a96ed75a70cc2ad6e2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/03/8d718da6a1ebbc6a7780a96ed75a70cc2ad6e2
new file mode 100755
index 0000000..7350d98
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/03/8d718da6a1ebbc6a7780a96ed75a70cc2ad6e2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/0d/deadede9e6d6ccddce0ee1e5749eed0485e5ea b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/0d/deadede9e6d6ccddce0ee1e5749eed0485e5ea
new file mode 100755
index 0000000..47c2a63
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/0d/deadede9e6d6ccddce0ee1e5749eed0485e5ea differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/ce/013625030ba8dba906f756967f9e9ca394464a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/ce/013625030ba8dba906f756967f9e9ca394464a
new file mode 100755
index 0000000..6802d49
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/ce/013625030ba8dba906f756967f9e9ca394464a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/info/packs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/info/packs
new file mode 100755
index 0000000..d0fdf90
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/info/packs
@@ -0,0 +1,3 @@
+P pack-e87994ad581c9af946de0eb890175c08cd005f38.pack
+P pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.pack
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-29a4896f0a0b9c9947b0927c57a5c03dcae052e3.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-29a4896f0a0b9c9947b0927c57a5c03dcae052e3.idx
new file mode 100755
index 0000000..acbed82
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-29a4896f0a0b9c9947b0927c57a5c03dcae052e3.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-29a4896f0a0b9c9947b0927c57a5c03dcae052e3.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-29a4896f0a0b9c9947b0927c57a5c03dcae052e3.pack
new file mode 100755
index 0000000..652b0c9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-29a4896f0a0b9c9947b0927c57a5c03dcae052e3.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-b18eeacbd65cbd30a365d7564b45a468e8bd43d6.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-b18eeacbd65cbd30a365d7564b45a468e8bd43d6.idx
new file mode 100755
index 0000000..fff6855
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-b18eeacbd65cbd30a365d7564b45a468e8bd43d6.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-b18eeacbd65cbd30a365d7564b45a468e8bd43d6.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-b18eeacbd65cbd30a365d7564b45a468e8bd43d6.pack
new file mode 100755
index 0000000..e3e5f0e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-b18eeacbd65cbd30a365d7564b45a468e8bd43d6.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-e87994ad581c9af946de0eb890175c08cd005f38.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-e87994ad581c9af946de0eb890175c08cd005f38.idx
new file mode 100755
index 0000000..fd8abee
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-e87994ad581c9af946de0eb890175c08cd005f38.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-e87994ad581c9af946de0eb890175c08cd005f38.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-e87994ad581c9af946de0eb890175c08cd005f38.pack
new file mode 100755
index 0000000..9879e08
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-e87994ad581c9af946de0eb890175c08cd005f38.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.idx
new file mode 100755
index 0000000..9f78f6e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.pack
new file mode 100755
index 0000000..d1dd3b6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/objects/pack/pack-f4ef1aa326265de7d05018ee51acc0a8717fe1ea.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/packed-refs
new file mode 100755
index 0000000..9f0d4e4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+8d2f05c97ef29a4697b37c30fe81c248ef411a23 refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/refs/heads/dummy-marker.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/refs/heads/dummy-marker.txt
new file mode 100755
index 0000000..421376d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/duplicate.git/refs/heads/dummy-marker.txt
@@ -0,0 +1 @@
+dummy
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/config
new file mode 100755
index 0000000..90e1647
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/config
@@ -0,0 +1,7 @@
+[core]
+	repositoryformatversion = 0
+	filemode = false
+	bare = true
+	symlinks = false
+	ignorecase = true
+	hideDotFiles = dotGitOnly
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/objects/info/dummy-marker.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/objects/info/dummy-marker.txt
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/objects/pack/dummy-marker.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/objects/pack/dummy-marker.txt
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/refs/heads/dummy-marker.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/refs/heads/dummy-marker.txt
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/refs/tags/dummy-marker.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_bare.git/refs/tags/dummy-marker.txt
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/config
new file mode 100755
index 0000000..78387c5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/config
@@ -0,0 +1,8 @@
+[core]
+	repositoryformatversion = 0
+	filemode = false
+	bare = false
+	logallrefupdates = true
+	symlinks = false
+	ignorecase = true
+	hideDotFiles = dotGitOnly
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/objects/info/dummy-marker.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/objects/info/dummy-marker.txt
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/objects/pack/dummy-marker.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/objects/pack/dummy-marker.txt
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/refs/heads/dummy-marker.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/refs/heads/dummy-marker.txt
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/refs/tags/dummy-marker.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/empty_standard_repo/.gitted/refs/tags/dummy-marker.txt
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/config
new file mode 100755
index 0000000..af10792
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/config
@@ -0,0 +1,6 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/index
new file mode 100755
index 0000000..b1b175a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/logs/HEAD
new file mode 100755
index 0000000..1cb6a84
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 9962c8453ba6f0cf8dac7c5dcc2fa2897fa9964a Russell Belfer <rb at github.com> 1338847682 -0700	commit (initial): Initial commit of test data
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..1cb6a84
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 9962c8453ba6f0cf8dac7c5dcc2fa2897fa9964a Russell Belfer <rb at github.com> 1338847682 -0700	commit (initial): Initial commit of test data
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/objects/99/62c8453ba6f0cf8dac7c5dcc2fa2897fa9964a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/objects/99/62c8453ba6f0cf8dac7c5dcc2fa2897fa9964a
new file mode 100755
index 0000000..cbd2b55
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/objects/99/62c8453ba6f0cf8dac7c5dcc2fa2897fa9964a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/objects/a5/c5dd0fc6c313159a69b1d19d7f61a9f978e8f1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/objects/a5/c5dd0fc6c313159a69b1d19d7f61a9f978e8f1
new file mode 100755
index 0000000..a9eaf2c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/objects/a5/c5dd0fc6c313159a69b1d19d7f61a9f978e8f1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/objects/e7/48d196331bcb20267eaaee4ff3326cb73b8182 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/objects/e7/48d196331bcb20267eaaee4ff3326cb73b8182
new file mode 100755
index 0000000..9806602
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/objects/e7/48d196331bcb20267eaaee4ff3326cb73b8182 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/refs/heads/master
new file mode 100755
index 0000000..9822d2d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/.gitted/refs/heads/master
@@ -0,0 +1 @@
+9962c8453ba6f0cf8dac7c5dcc2fa2897fa9964a
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_off b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_off
new file mode 100755
index 0000000..a5c5dd0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_off
@@ -0,0 +1 @@
+Howdy
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_off2on_staged b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_off2on_staged
new file mode 100755
index 0000000..a5c5dd0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_off2on_staged
@@ -0,0 +1 @@
+Howdy
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_off2on_workdir b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_off2on_workdir
new file mode 100755
index 0000000..a5c5dd0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_off2on_workdir
@@ -0,0 +1 @@
+Howdy
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_off_untracked b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_off_untracked
new file mode 100755
index 0000000..a5c5dd0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_off_untracked
@@ -0,0 +1 @@
+Howdy
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_on b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_on
new file mode 100755
index 0000000..a5c5dd0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_on
@@ -0,0 +1 @@
+Howdy
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_on2off_staged b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_on2off_staged
new file mode 100755
index 0000000..a5c5dd0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_on2off_staged
@@ -0,0 +1 @@
+Howdy
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_on2off_workdir b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_on2off_workdir
new file mode 100755
index 0000000..a5c5dd0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_on2off_workdir
@@ -0,0 +1 @@
+Howdy
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_on_untracked b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_on_untracked
new file mode 100755
index 0000000..a5c5dd0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/filemodes/exec_on_untracked
@@ -0,0 +1 @@
+Howdy
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/gitgit.index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/gitgit.index
new file mode 100755
index 0000000..215da64
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/gitgit.index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/config
new file mode 100755
index 0000000..bb4d11c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/config
@@ -0,0 +1,7 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
+	precomposeunicode = false
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/index
new file mode 100755
index 0000000..f8288ec
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/logs/HEAD
new file mode 100755
index 0000000..3b16bd1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 76d6e1d231b1085fcce151427e9899335de74be6 Russell Belfer <rb at github.com> 1359157123 -0800	commit (initial): initial commit
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..3b16bd1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 76d6e1d231b1085fcce151427e9899335de74be6 Russell Belfer <rb at github.com> 1359157123 -0800	commit (initial): initial commit
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/objects/3e/257c57f136a1cb8f2b8e9a2e5bc8ec0258bdce b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/objects/3e/257c57f136a1cb8f2b8e9a2e5bc8ec0258bdce
new file mode 100755
index 0000000..10691c7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/objects/3e/257c57f136a1cb8f2b8e9a2e5bc8ec0258bdce differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/objects/4d/d6027d083575c7431396dc2a3174afeb393c93 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/objects/4d/d6027d083575c7431396dc2a3174afeb393c93
new file mode 100755
index 0000000..8ca70df
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/objects/4d/d6027d083575c7431396dc2a3174afeb393c93 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/objects/62/e0af52c199ec731fe4ad230041cd3286192d49 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/objects/62/e0af52c199ec731fe4ad230041cd3286192d49
new file mode 100755
index 0000000..e264aea
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/objects/62/e0af52c199ec731fe4ad230041cd3286192d49 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/objects/76/d6e1d231b1085fcce151427e9899335de74be6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/objects/76/d6e1d231b1085fcce151427e9899335de74be6
new file mode 100755
index 0000000..24a4b3e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/objects/76/d6e1d231b1085fcce151427e9899335de74be6
@@ -0,0 +1,3 @@
+x•Û	1EýNÓ€’c² ‹X‚dƉÈÈ&ý°/çœËußsãñÔ›8±è}2î
SH–‚,Ñ
+am1ЋEÅÑ·Úà9ŽCJ‡”$
nîïÜ·A®û
+ÆábÐëଃÖj®ó¯Oô_SåOî9ø%Ô)Œ9š
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/objects/d4/4e18fb93b7107b5cd1b95d601591d77869a1b6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/objects/d4/4e18fb93b7107b5cd1b95d601591d77869a1b6
new file mode 100755
index 0000000..32d8c49
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/objects/d4/4e18fb93b7107b5cd1b95d601591d77869a1b6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/refs/heads/master
new file mode 100755
index 0000000..37410ec
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/.gitted/refs/heads/master
@@ -0,0 +1 @@
+76d6e1d231b1085fcce151427e9899335de74be6
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/B b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/B
new file mode 100755
index 0000000..d44e18f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/B
@@ -0,0 +1 @@
+start
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/D b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/D
new file mode 100755
index 0000000..d44e18f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/D
@@ -0,0 +1 @@
+start
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/F b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/F
new file mode 100755
index 0000000..d44e18f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/F
@@ -0,0 +1 @@
+start
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/H b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/H
new file mode 100755
index 0000000..d44e18f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/H
@@ -0,0 +1 @@
+start
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/J b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/J
new file mode 100755
index 0000000..d44e18f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/J
@@ -0,0 +1 @@
+start
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/L/1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/L/1
new file mode 100755
index 0000000..62e0af5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/L/1
@@ -0,0 +1 @@
+sub
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/L/B b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/L/B
new file mode 100755
index 0000000..62e0af5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/L/B
@@ -0,0 +1 @@
+sub
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/L/D b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/L/D
new file mode 100755
index 0000000..62e0af5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/L/D
@@ -0,0 +1 @@
+sub
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/L/a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/L/a
new file mode 100755
index 0000000..62e0af5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/L/a
@@ -0,0 +1 @@
+sub
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/L/c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/L/c
new file mode 100755
index 0000000..62e0af5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/L/c
@@ -0,0 +1 @@
+sub
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/a
new file mode 100755
index 0000000..d44e18f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/a
@@ -0,0 +1 @@
+start
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/c
new file mode 100755
index 0000000..d44e18f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/c
@@ -0,0 +1 @@
+start
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/e
new file mode 100755
index 0000000..d44e18f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/e
@@ -0,0 +1 @@
+start
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/g b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/g
new file mode 100755
index 0000000..d44e18f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/g
@@ -0,0 +1 @@
+start
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/i b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/i
new file mode 100755
index 0000000..d44e18f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/i
@@ -0,0 +1 @@
+start
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/k/1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/k/1
new file mode 100755
index 0000000..62e0af5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/k/1
@@ -0,0 +1 @@
+sub
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/k/B b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/k/B
new file mode 100755
index 0000000..62e0af5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/k/B
@@ -0,0 +1 @@
+sub
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/k/D b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/k/D
new file mode 100755
index 0000000..62e0af5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/k/D
@@ -0,0 +1 @@
+sub
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/k/a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/k/a
new file mode 100755
index 0000000..62e0af5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/k/a
@@ -0,0 +1 @@
+sub
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/k/c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/k/c
new file mode 100755
index 0000000..62e0af5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/icase/k/c
@@ -0,0 +1 @@
+sub
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/config
new file mode 100755
index 0000000..ba5bbde
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/config
@@ -0,0 +1,6 @@
+[core]
+	bare = false
+	repositoryformatversion = 0
+	filemode = false
+	logallrefupdates = true
+	ignorecase = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/index
new file mode 100755
index 0000000..fa0f541
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/7f/483a738f867e5b21c8f377d70311f011eb48b5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/7f/483a738f867e5b21c8f377d70311f011eb48b5
new file mode 100755
index 0000000..63bcb5d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/7f/483a738f867e5b21c8f377d70311f011eb48b5
@@ -0,0 +1,3 @@
+xÎQNÃ0€ažs
+¿£!'nâTBÓî°¸ŽC+Öe\Äv€ÿӯǾoÑËèfPƒ¦PL8FΆ‘ÒÌ%ª_Ä‹b4æIÜ—tk²°Uœ¸êLdeIÁòd<3/˜|0¥šjÈää1Ö£ÃõÛ\Gßô³c…wÛe»]ô~úùߊÁS
+)ÏGxEèôÿqØsµÓUÚ‡8šÁmkæ~yIæ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/83/12e0889a9cbab77c732b6bc39b51a683e3a318 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/83/12e0889a9cbab77c732b6bc39b51a683e3a318
new file mode 100755
index 0000000..06b59fe
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/83/12e0889a9cbab77c732b6bc39b51a683e3a318 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/8a/7ef047fc933edb62e84e7977b0612ec3f6f283 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/8a/7ef047fc933edb62e84e7977b0612ec3f6f283
new file mode 100755
index 0000000..19cfbea
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/8a/7ef047fc933edb62e84e7977b0612ec3f6f283 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/8e/8f80088a9274fd23584992f587083ca1bcbbac b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/8e/8f80088a9274fd23584992f587083ca1bcbbac
new file mode 100755
index 0000000..f5c776b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/8e/8f80088a9274fd23584992f587083ca1bcbbac differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/f2/c62dea0372a0578e053697d5c1ba1ac05e774a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/f2/c62dea0372a0578e053697d5c1ba1ac05e774a
new file mode 100755
index 0000000..f932f36
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/f2/c62dea0372a0578e053697d5c1ba1ac05e774a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/ff/3578d64d199d5b48d92bbb569e0a273e411741 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/ff/3578d64d199d5b48d92bbb569e0a273e411741
new file mode 100755
index 0000000..fbd7317
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/objects/ff/3578d64d199d5b48d92bbb569e0a273e411741 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/refs/heads/master
new file mode 100755
index 0000000..285bc08
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/.gitted/refs/heads/master
@@ -0,0 +1 @@
+7f483a738f867e5b21c8f377d70311f011eb48b5
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/crlf_file.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/crlf_file.txt
new file mode 100755
index 0000000..8312e08
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/crlf_file.txt
@@ -0,0 +1,3 @@
+first line
+second line
+both with crlf
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/some_other_crlf_file.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/some_other_crlf_file.txt
new file mode 100755
index 0000000..8e8f800
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_1397/some_other_crlf_file.txt
@@ -0,0 +1,3 @@
+first line
+second line with some change
+both with crlf
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/COMMIT_EDITMSG b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/COMMIT_EDITMSG
new file mode 100755
index 0000000..5852f44
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/COMMIT_EDITMSG
@@ -0,0 +1 @@
+Initial commit
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/config
new file mode 100755
index 0000000..78387c5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/config
@@ -0,0 +1,8 @@
+[core]
+	repositoryformatversion = 0
+	filemode = false
+	bare = false
+	logallrefupdates = true
+	symlinks = false
+	ignorecase = true
+	hideDotFiles = dotGitOnly
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/index
new file mode 100755
index 0000000..be7a29d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/logs/HEAD
new file mode 100755
index 0000000..f19fe35
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/logs/HEAD
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 4d383e87f0371ba8fa353f3912db6862b2625e85 nulltoken <emeric.fermas at gmail.com> 1331989635 +0100	commit (initial): Initial commit
+4d383e87f0371ba8fa353f3912db6862b2625e85 e38fcc7a6060f5eb5b876e836b52ae4769363f21 nulltoken <emeric.fermas at gmail.com> 1332227062 +0100	commit (amend): Initial commit
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..f19fe35
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/logs/refs/heads/master
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 4d383e87f0371ba8fa353f3912db6862b2625e85 nulltoken <emeric.fermas at gmail.com> 1331989635 +0100	commit (initial): Initial commit
+4d383e87f0371ba8fa353f3912db6862b2625e85 e38fcc7a6060f5eb5b876e836b52ae4769363f21 nulltoken <emeric.fermas at gmail.com> 1332227062 +0100	commit (amend): Initial commit
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/06/07ee9d4ccce8e4c4fa13c2c7d727e7faba4e0e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/06/07ee9d4ccce8e4c4fa13c2c7d727e7faba4e0e
new file mode 100755
index 0000000..05dec10
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/06/07ee9d4ccce8e4c4fa13c2c7d727e7faba4e0e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/49/363a72a90d9424240258cd3759f23788ecf1d8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/49/363a72a90d9424240258cd3759f23788ecf1d8
new file mode 100755
index 0000000..e997e1b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/49/363a72a90d9424240258cd3759f23788ecf1d8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/4d/383e87f0371ba8fa353f3912db6862b2625e85 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/4d/383e87f0371ba8fa353f3912db6862b2625e85
new file mode 100755
index 0000000..c49a8be
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/4d/383e87f0371ba8fa353f3912db6862b2625e85
@@ -0,0 +1,2 @@
+xM
+Â0]ço/”¤I›DÜzŒçë
æbzÞÀíÀÌHÍ9v2Ëtê
 =k¬›,pâ+£ø͏>ðƒ4ïýU•=¥^ß(tAF‹2´ÌŸÛ3sLƒÔ|%c­Y—u¶µÑZô˜vü©«{‰=r¢_G}KÈ>ˆ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/71/44be264b61825fbff68046fe999bdfe96a1792 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/71/44be264b61825fbff68046fe999bdfe96a1792
new file mode 100755
index 0000000..25d44d9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/71/44be264b61825fbff68046fe999bdfe96a1792 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/be/de83ee10b5b3f00239660b00acec2d55fd0b84 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/be/de83ee10b5b3f00239660b00acec2d55fd0b84
new file mode 100755
index 0000000..1d6e38d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/be/de83ee10b5b3f00239660b00acec2d55fd0b84 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/e3/8fcc7a6060f5eb5b876e836b52ae4769363f21 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/e3/8fcc7a6060f5eb5b876e836b52ae4769363f21
new file mode 100755
index 0000000..36c5b9a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/e3/8fcc7a6060f5eb5b876e836b52ae4769363f21 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/f1/adef63cb08891a0942b76fc4b9c50c6c494bc7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/f1/adef63cb08891a0942b76fc4b9c50c6c494bc7
new file mode 100755
index 0000000..c08ecd5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/objects/f1/adef63cb08891a0942b76fc4b9c50c6c494bc7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/refs/heads/master
new file mode 100755
index 0000000..1f66696
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/.gitted/refs/heads/master
@@ -0,0 +1 @@
+e38fcc7a6060f5eb5b876e836b52ae4769363f21
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/a.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/a.txt
new file mode 100755
index 0000000..f1adef6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/a.txt
@@ -0,0 +1 @@
+nothing here
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/c/a.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/c/a.txt
new file mode 100755
index 0000000..f1adef6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/c/a.txt
@@ -0,0 +1 @@
+nothing here
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/l.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/l.txt
new file mode 100755
index 0000000..f1adef6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/l.txt
@@ -0,0 +1 @@
+nothing here
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/t/a.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/t/a.txt
new file mode 100755
index 0000000..f1adef6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/t/a.txt
@@ -0,0 +1 @@
+nothing here
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/t/b.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/t/b.txt
new file mode 100755
index 0000000..f1adef6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592/t/b.txt
@@ -0,0 +1 @@
+nothing here
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/config
new file mode 100755
index 0000000..af10792
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/config
@@ -0,0 +1,6 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/index
new file mode 100755
index 0000000..5964382
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/logs/HEAD
new file mode 100755
index 0000000..6f3ba90
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 3fbf1852f72fd268e36457b13a18cdd9a4c9ea35 Russell Belfer <rb at github.com> 1337205933 -0700	commit (initial): Initial commit
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..6f3ba90
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 3fbf1852f72fd268e36457b13a18cdd9a4c9ea35 Russell Belfer <rb at github.com> 1337205933 -0700	commit (initial): Initial commit
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/3f/bf1852f72fd268e36457b13a18cdd9a4c9ea35 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/3f/bf1852f72fd268e36457b13a18cdd9a4c9ea35
new file mode 100755
index 0000000..6eaf64b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/3f/bf1852f72fd268e36457b13a18cdd9a4c9ea35
@@ -0,0 +1,2 @@
+x•K
+1]ç}%Bwn½A§íq‰™Îý
x·ªz¼µVƃv É‚còžÑ&”%9¦@˜9x¤dÝëŒìÙÐÐuëðû.µÂ]ê".=ßÞEבO¼µ+¸ÐÛ˜B€£EkÍ\çŸNô_Ó<>EUø%Ìû•9
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/6f/a891d3e578c83e1c03bdb9e0fdd8e6e934157f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/6f/a891d3e578c83e1c03bdb9e0fdd8e6e934157f
new file mode 100755
index 0000000..c4becfe
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/6f/a891d3e578c83e1c03bdb9e0fdd8e6e934157f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/80/07d41d5794e6ce4d4d2c97e370d5a9aa6d5213 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/80/07d41d5794e6ce4d4d2c97e370d5a9aa6d5213
new file mode 100755
index 0000000..aea14f2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/80/07d41d5794e6ce4d4d2c97e370d5a9aa6d5213 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/a6/5fb6583a7c425284142f285bc359a2d6565513 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/a6/5fb6583a7c425284142f285bc359a2d6565513
new file mode 100755
index 0000000..9b74072
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/a6/5fb6583a7c425284142f285bc359a2d6565513 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/ae/be7a55922c7097ef91ca3a7bc327a901d87c2c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/ae/be7a55922c7097ef91ca3a7bc327a901d87c2c
new file mode 100755
index 0000000..1494ed8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/ae/be7a55922c7097ef91ca3a7bc327a901d87c2c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/b3/44b055867fcdc1f01eaa75056a43e868eb4fbc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/b3/44b055867fcdc1f01eaa75056a43e868eb4fbc
new file mode 100755
index 0000000..7a66266
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/b3/44b055867fcdc1f01eaa75056a43e868eb4fbc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/f7/d75fbfad8b1d2e307ced287ea78aad403cdce3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/f7/d75fbfad8b1d2e307ced287ea78aad403cdce3
new file mode 100755
index 0000000..65a1fd0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/objects/f7/d75fbfad8b1d2e307ced287ea78aad403cdce3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/refs/heads/master
new file mode 100755
index 0000000..c0a9ab4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/.gitted/refs/heads/master
@@ -0,0 +1 @@
+3fbf1852f72fd268e36457b13a18cdd9a4c9ea35
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/gitignore b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/gitignore
new file mode 100755
index 0000000..8007d41
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/gitignore
@@ -0,0 +1 @@
+ignored/
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/ignored/contained/ignored3.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/ignored/contained/ignored3.txt
new file mode 100755
index 0000000..b5dc7b0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/ignored/contained/ignored3.txt
@@ -0,0 +1 @@
+I'm ignored
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/ignored/contained/tracked3.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/ignored/contained/tracked3.txt
new file mode 100755
index 0000000..b344b05
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/ignored/contained/tracked3.txt
@@ -0,0 +1 @@
+You added me anyhow
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/ignored/ignored2.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/ignored/ignored2.txt
new file mode 100755
index 0000000..b5dc7b0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/ignored/ignored2.txt
@@ -0,0 +1 @@
+I'm ignored
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/ignored/tracked2.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/ignored/tracked2.txt
new file mode 100755
index 0000000..6fa891d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/ignored/tracked2.txt
@@ -0,0 +1 @@
+You like me
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/ignored1.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/ignored1.txt
new file mode 100755
index 0000000..b5dc7b0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/ignored1.txt
@@ -0,0 +1 @@
+I'm ignored
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/tracked1.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/tracked1.txt
new file mode 100755
index 0000000..6fa891d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/issue_592b/tracked1.txt
@@ -0,0 +1 @@
+You like me
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/COMMIT_EDITMSG b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/COMMIT_EDITMSG
new file mode 100755
index 0000000..245b18a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/COMMIT_EDITMSG
@@ -0,0 +1 @@
+rename conflict theirs
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/ORIG_HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/ORIG_HEAD
new file mode 100755
index 0000000..4092d42
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/ORIG_HEAD
@@ -0,0 +1 @@
+2392a2dacc9efb562b8635d6579fb458751c7c5b
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/config
new file mode 100755
index 0000000..26c4842
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/config
@@ -0,0 +1,8 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
+[submodule "submodule"]
+	url = ../submodule
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/index
new file mode 100755
index 0000000..230eba9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/HEAD
new file mode 100755
index 0000000..96cdb33
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/HEAD
@@ -0,0 +1,236 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1351563869 -0500	commit (initial): initial
+c607fc30883e335def28cd686b51f6cfa02b06ec c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1351563886 -0500	checkout: moving from master to branch
+c607fc30883e335def28cd686b51f6cfa02b06ec 7cb63eed597130ba4abb87b3e544b85021905520 Edward Thomson <ethomson at edwardthomson.com> 1351563965 -0500	commit: branch
+7cb63eed597130ba4abb87b3e544b85021905520 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1351563968 -0500	checkout: moving from branch to master
+c607fc30883e335def28cd686b51f6cfa02b06ec 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351564033 -0500	commit: master
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351605785 -0500	checkout: moving from master to ff_branch
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 33d500f588fbbe65901d82b4e6b008e549064be0 Edward Thomson <ethomson at edwardthomson.com> 1351605830 -0500	commit: fastforward
+33d500f588fbbe65901d82b4e6b008e549064be0 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351605889 -0500	checkout: moving from ff_branch to master
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351874933 -0500	checkout: moving from master to octo1
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 16f825815cfd20a07a75c71554e82d8eede0b061 Edward Thomson <ethomson at edwardthomson.com> 1351874954 -0500	commit: octo1
+16f825815cfd20a07a75c71554e82d8eede0b061 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351874957 -0500	checkout: moving from octo1 to master
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351874960 -0500	checkout: moving from master to octo2
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 158dc7bedb202f5b26502bf3574faa7f4238d56c Edward Thomson <ethomson at edwardthomson.com> 1351874974 -0500	commit: octo2
+158dc7bedb202f5b26502bf3574faa7f4238d56c 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351874976 -0500	checkout: moving from octo2 to master
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351874980 -0500	checkout: moving from master to octo3
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 50ce7d7d01217679e26c55939eef119e0c93e272 Edward Thomson <ethomson at edwardthomson.com> 1351874998 -0500	commit: octo3
+50ce7d7d01217679e26c55939eef119e0c93e272 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351875006 -0500	checkout: moving from octo3 to master
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351875010 -0500	checkout: moving from master to octo4
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 54269b3f6ec3d7d4ede24dd350dd5d605495c3ae Edward Thomson <ethomson at edwardthomson.com> 1351875023 -0500	commit: octo4
+54269b3f6ec3d7d4ede24dd350dd5d605495c3ae 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351875031 -0500	checkout: moving from octo4 to master
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351875031 -0500	checkout: moving from master to octo5
+977c696519c5a3004c5f1d15d60c89dbeb8f235f e4f618a2c3ed0669308735727df5ebf2447f022f Edward Thomson <ethomson at edwardthomson.com> 1351875041 -0500	commit: octo5
+e4f618a2c3ed0669308735727df5ebf2447f022f 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351875046 -0500	checkout: moving from octo5 to master
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351875046 -0500	checkout: moving from master to octo6
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 4ca408a8c88655f7586a1b580be6fad138121e98 Edward Thomson <ethomson at edwardthomson.com> 1351875057 -0500	commit: octo5
+4ca408a8c88655f7586a1b580be6fad138121e98 b6f610aef53bd343e6c96227de874c66f00ee8e8 Edward Thomson <ethomson at edwardthomson.com> 1351875065 -0500	commit (amend): octo6
+b6f610aef53bd343e6c96227de874c66f00ee8e8 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351875071 -0500	checkout: moving from octo6 to master
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 4e0d9401aee78eb345a8685a859d37c8c3c0bbed Edward Thomson <ethomson at edwardthomson.com> 1351875091 -0500	merge octo1 octo2 octo3 octo4: Merge made by the 'octopus' strategy.
+4e0d9401aee78eb345a8685a859d37c8c3c0bbed 54269b3f6ec3d7d4ede24dd350dd5d605495c3ae Edward Thomson <ethomson at edwardthomson.com> 1351875108 -0500	reset: moving to 54269b3f6ec3d7d4ede24dd350dd5d605495c3ae
+54269b3f6ec3d7d4ede24dd350dd5d605495c3ae 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351875584 -0500	reset: moving to 977c696519c5a3004c5f1d15d60c89dbeb8f235f
+bd593285fc7fe4ca18ccdbabf027f5d689101452 33d500f588fbbe65901d82b4e6b008e549064be0 Edward Thomson <ethomson at edwardthomson.com> 1351990193 -0500	checkout: moving from master to ff_branch
+33d500f588fbbe65901d82b4e6b008e549064be0 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1351990202 -0500	reset: moving to c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1351990205 -0500	merge master: Fast-forward
+bd593285fc7fe4ca18ccdbabf027f5d689101452 fd89f8cffb663ac89095a0f9764902e93ceaca6a Edward Thomson <ethomson at edwardthomson.com> 1351990229 -0500	commit: fastforward
+fd89f8cffb663ac89095a0f9764902e93ceaca6a bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1351990233 -0500	checkout: moving from ff_branch to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352091703 -0600	checkout: moving from master to trivial-2alt
+c607fc30883e335def28cd686b51f6cfa02b06ec c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352092411 -0600	checkout: moving from trivial-2alt to trivial-2alt-branch
+c607fc30883e335def28cd686b51f6cfa02b06ec c9174cef549ec94ecbc43ef03cdc775b4950becb Edward Thomson <ethomson at edwardthomson.com> 1352092434 -0600	commit: 2alt-branch
+c9174cef549ec94ecbc43ef03cdc775b4950becb c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352092440 -0600	checkout: moving from trivial-2alt-branch to trivial-2alt
+c607fc30883e335def28cd686b51f6cfa02b06ec 566ab53c220a2eafc1212af1a024513230280ab9 Edward Thomson <ethomson at edwardthomson.com> 1352092452 -0600	commit: 2alt
+bd593285fc7fe4ca18ccdbabf027f5d689101452 566ab53c220a2eafc1212af1a024513230280ab9 Edward Thomson <ethomson at edwardthomson.com> 1352094476 -0600	checkout: moving from master to trivial-3alt
+566ab53c220a2eafc1212af1a024513230280ab9 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352094547 -0600	reset: moving to c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec 5459c89aa0026d543ce8343bd89871bce543f9c2 Edward Thomson <ethomson at edwardthomson.com> 1352094580 -0600	commit: 3alt
+5459c89aa0026d543ce8343bd89871bce543f9c2 4c9fac0707f8d4195037ae5a681aa48626491541 Edward Thomson <ethomson at edwardthomson.com> 1352094610 -0600	commit: 3alt-branch
+4c9fac0707f8d4195037ae5a681aa48626491541 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1352094620 -0600	checkout: moving from trivial-3alt to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 566ab53c220a2eafc1212af1a024513230280ab9 Edward Thomson <ethomson at edwardthomson.com> 1352094752 -0600	checkout: moving from master to trivial-4
+566ab53c220a2eafc1212af1a024513230280ab9 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352094764 -0600	reset: moving to c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec cc3e3009134cb88014129fc8858d1101359e5e2f Edward Thomson <ethomson at edwardthomson.com> 1352094815 -0600	commit: trivial-4
+cc3e3009134cb88014129fc8858d1101359e5e2f c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352094843 -0600	checkout: moving from trivial-4 to trivial-4-branch
+c607fc30883e335def28cd686b51f6cfa02b06ec 183310e30fb1499af8c619108ffea4d300b5e778 Edward Thomson <ethomson at edwardthomson.com> 1352094856 -0600	commit: trivial-4-branch
+183310e30fb1499af8c619108ffea4d300b5e778 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1352094860 -0600	checkout: moving from trivial-4-branch to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 cc3e3009134cb88014129fc8858d1101359e5e2f Edward Thomson <ethomson at edwardthomson.com> 1352096588 -0600	checkout: moving from master to trivial-4
+cc3e3009134cb88014129fc8858d1101359e5e2f c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352096612 -0600	checkout: moving from trivial-4 to trivial-5alt-1
+c607fc30883e335def28cd686b51f6cfa02b06ec 4fe93c0ec83eb6305cbace3dace88ecee1b63cb6 Edward Thomson <ethomson at edwardthomson.com> 1352096643 -0600	commit: 5alt-1
+4fe93c0ec83eb6305cbace3dace88ecee1b63cb6 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352096661 -0600	checkout: moving from trivial-5alt-1 to trivial-5alt-1-branch
+c607fc30883e335def28cd686b51f6cfa02b06ec 4fe93c0ec83eb6305cbace3dace88ecee1b63cb6 Edward Thomson <ethomson at edwardthomson.com> 1352096671 -0600	checkout: moving from trivial-5alt-1-branch to trivial-5alt-1
+4fe93c0ec83eb6305cbace3dace88ecee1b63cb6 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352096678 -0600	checkout: moving from trivial-5alt-1 to trivial-5alt-1-branch
+c607fc30883e335def28cd686b51f6cfa02b06ec 478172cb2f5ff9b514bc9d04d3bd5ef5840cb3b2 Edward Thomson <ethomson at edwardthomson.com> 1352096689 -0600	commit: 5alt-1-branch
+478172cb2f5ff9b514bc9d04d3bd5ef5840cb3b2 4fe93c0ec83eb6305cbace3dace88ecee1b63cb6 Edward Thomson <ethomson at edwardthomson.com> 1352096701 -0600	checkout: moving from trivial-5alt-1-branch to trivial-5alt-1
+4fe93c0ec83eb6305cbace3dace88ecee1b63cb6 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352096715 -0600	checkout: moving from trivial-5alt-1 to trivial-5alt-2
+c607fc30883e335def28cd686b51f6cfa02b06ec ebc09d0137cfb0c26697aed0109fb943ad906f3f Edward Thomson <ethomson at edwardthomson.com> 1352096764 -0600	commit: existing file
+ebc09d0137cfb0c26697aed0109fb943ad906f3f 3b47b031b3e55ae11e14a05260b1c3ffd6838d55 Edward Thomson <ethomson at edwardthomson.com> 1352096815 -0600	commit: 5alt-2
+3b47b031b3e55ae11e14a05260b1c3ffd6838d55 ebc09d0137cfb0c26697aed0109fb943ad906f3f Edward Thomson <ethomson at edwardthomson.com> 1352096840 -0600	checkout: moving from trivial-5alt-2 to trivial-5alt-2-branch
+ebc09d0137cfb0c26697aed0109fb943ad906f3f f48097eb340dc5a7cae55aabcf1faf4548aa821f Edward Thomson <ethomson at edwardthomson.com> 1352096855 -0600	commit: 5alt-2-branch
+f48097eb340dc5a7cae55aabcf1faf4548aa821f bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1352096858 -0600	checkout: moving from trivial-5alt-2-branch to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352097377 -0600	checkout: moving from master to trivial-6
+c607fc30883e335def28cd686b51f6cfa02b06ec f7c332bd4d4d4b777366cae4d24d1687477576bf Edward Thomson <ethomson at edwardthomson.com> 1352097389 -0600	commit: 6
+f7c332bd4d4d4b777366cae4d24d1687477576bf 99b4f7e4f24470fa06b980bc21f1095c2a9425c0 Edward Thomson <ethomson at edwardthomson.com> 1352097404 -0600	commit: trivial-6
+99b4f7e4f24470fa06b980bc21f1095c2a9425c0 f7c332bd4d4d4b777366cae4d24d1687477576bf Edward Thomson <ethomson at edwardthomson.com> 1352097420 -0600	checkout: moving from trivial-6 to trivial-6-branch
+f7c332bd4d4d4b777366cae4d24d1687477576bf a43150a738849c59376cf30bb2a68348a83c8f48 Edward Thomson <ethomson at edwardthomson.com> 1352097431 -0600	commit: 6-branch
+a43150a738849c59376cf30bb2a68348a83c8f48 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1352097442 -0600	checkout: moving from trivial-6-branch to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 99b4f7e4f24470fa06b980bc21f1095c2a9425c0 Edward Thomson <ethomson at edwardthomson.com> 1352098040 -0600	checkout: moving from master to trivial-6
+99b4f7e4f24470fa06b980bc21f1095c2a9425c0 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1352098057 -0600	checkout: moving from trivial-6 to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 cc3e3009134cb88014129fc8858d1101359e5e2f Edward Thomson <ethomson at edwardthomson.com> 1352098792 -0600	checkout: moving from master to trivial-4
+cc3e3009134cb88014129fc8858d1101359e5e2f c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352098818 -0600	checkout: moving from trivial-4 to trivial-8
+c607fc30883e335def28cd686b51f6cfa02b06ec 75a811bf6bc57694adb3fe604786f3a4efd1cd1b Edward Thomson <ethomson at edwardthomson.com> 1352098884 -0600	commit: trivial-8
+75a811bf6bc57694adb3fe604786f3a4efd1cd1b 75a811bf6bc57694adb3fe604786f3a4efd1cd1b Edward Thomson <ethomson at edwardthomson.com> 1352098947 -0600	checkout: moving from trivial-8 to trivial-8-branch
+75a811bf6bc57694adb3fe604786f3a4efd1cd1b 52d8bc572af2b6d4ee0d5e62ed5d1fbad92210a9 Edward Thomson <ethomson at edwardthomson.com> 1352098979 -0600	commit: trivial-8-branch
+52d8bc572af2b6d4ee0d5e62ed5d1fbad92210a9 75a811bf6bc57694adb3fe604786f3a4efd1cd1b Edward Thomson <ethomson at edwardthomson.com> 1352098982 -0600	checkout: moving from trivial-8-branch to trivial-8
+75a811bf6bc57694adb3fe604786f3a4efd1cd1b 3575826c96a975031d2c14368529cc5c4353a8fd Edward Thomson <ethomson at edwardthomson.com> 1352099000 -0600	commit: trivial-8
+3575826c96a975031d2c14368529cc5c4353a8fd bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1352099008 -0600	checkout: moving from trivial-8 to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352099776 -0600	checkout: moving from master to trivial-7
+c607fc30883e335def28cd686b51f6cfa02b06ec 092ce8682d7f3a2a3a769a6daca58950168ba5c4 Edward Thomson <ethomson at edwardthomson.com> 1352099790 -0600	commit: trivial-7
+092ce8682d7f3a2a3a769a6daca58950168ba5c4 092ce8682d7f3a2a3a769a6daca58950168ba5c4 Edward Thomson <ethomson at edwardthomson.com> 1352099799 -0600	checkout: moving from trivial-7 to trivial-7-branch
+092ce8682d7f3a2a3a769a6daca58950168ba5c4 73cbfdc4fe843169e5b2af8dcad03cbf3acf306c Edward Thomson <ethomson at edwardthomson.com> 1352099812 -0600	commit: trivial-7-branch
+73cbfdc4fe843169e5b2af8dcad03cbf3acf306c 092ce8682d7f3a2a3a769a6daca58950168ba5c4 Edward Thomson <ethomson at edwardthomson.com> 1352099815 -0600	checkout: moving from trivial-7-branch to trivial-7
+092ce8682d7f3a2a3a769a6daca58950168ba5c4 73cbfdc4fe843169e5b2af8dcad03cbf3acf306c Edward Thomson <ethomson at edwardthomson.com> 1352099838 -0600	checkout: moving from trivial-7 to trivial-7-branch
+73cbfdc4fe843169e5b2af8dcad03cbf3acf306c 092ce8682d7f3a2a3a769a6daca58950168ba5c4 Edward Thomson <ethomson at edwardthomson.com> 1352099874 -0600	reset: moving to 092ce8682d7f3a2a3a769a6daca58950168ba5c4
+092ce8682d7f3a2a3a769a6daca58950168ba5c4 009b9cab6fdac02915a88ecd078b7a792ed802d8 Edward Thomson <ethomson at edwardthomson.com> 1352099921 -0600	commit: removed in 7
+009b9cab6fdac02915a88ecd078b7a792ed802d8 5195a1b480f66691b667f10a9e41e70115a78351 Edward Thomson <ethomson at edwardthomson.com> 1352099927 -0600	commit (amend): trivial-7-branch
+5195a1b480f66691b667f10a9e41e70115a78351 092ce8682d7f3a2a3a769a6daca58950168ba5c4 Edward Thomson <ethomson at edwardthomson.com> 1352099937 -0600	checkout: moving from trivial-7-branch to trivial-7
+092ce8682d7f3a2a3a769a6daca58950168ba5c4 d874671ef5b20184836cb983bb273e5280384d0b Edward Thomson <ethomson at edwardthomson.com> 1352099947 -0600	commit: trivial-7
+d874671ef5b20184836cb983bb273e5280384d0b bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1352099949 -0600	checkout: moving from trivial-7 to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352100174 -0600	checkout: moving from master to trivial-10
+c607fc30883e335def28cd686b51f6cfa02b06ec 53825f41ac8d640612f9423a2f03a69f3d96809a Edward Thomson <ethomson at edwardthomson.com> 1352100193 -0600	commit: trivial-10
+53825f41ac8d640612f9423a2f03a69f3d96809a 53825f41ac8d640612f9423a2f03a69f3d96809a Edward Thomson <ethomson at edwardthomson.com> 1352100200 -0600	checkout: moving from trivial-10 to trivial-10-branch
+53825f41ac8d640612f9423a2f03a69f3d96809a 11f4f3c08b737f5fd896cbefa1425ee63b21b2fa Edward Thomson <ethomson at edwardthomson.com> 1352100211 -0600	commit: trivial-10-branch
+11f4f3c08b737f5fd896cbefa1425ee63b21b2fa 53825f41ac8d640612f9423a2f03a69f3d96809a Edward Thomson <ethomson at edwardthomson.com> 1352100214 -0600	checkout: moving from trivial-10-branch to trivial-10
+53825f41ac8d640612f9423a2f03a69f3d96809a 0ec5f433959cd46177f745903353efb5be08d151 Edward Thomson <ethomson at edwardthomson.com> 1352100223 -0600	commit: trivial-10
+0ec5f433959cd46177f745903353efb5be08d151 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1352100225 -0600	checkout: moving from trivial-10 to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352100270 -0600	checkout: moving from master to trivial-9
+c607fc30883e335def28cd686b51f6cfa02b06ec f0053b8060bb3f0be5cbcc3147a07ece26bf097e Edward Thomson <ethomson at edwardthomson.com> 1352100304 -0600	commit: trivial-9
+f0053b8060bb3f0be5cbcc3147a07ece26bf097e f0053b8060bb3f0be5cbcc3147a07ece26bf097e Edward Thomson <ethomson at edwardthomson.com> 1352100310 -0600	checkout: moving from trivial-9 to trivial-9-branch
+f0053b8060bb3f0be5cbcc3147a07ece26bf097e 13d1be4ea52a6ced1d7a1d832f0ee3c399348e5e Edward Thomson <ethomson at edwardthomson.com> 1352100317 -0600	commit: trivial-9-branch
+13d1be4ea52a6ced1d7a1d832f0ee3c399348e5e f0053b8060bb3f0be5cbcc3147a07ece26bf097e Edward Thomson <ethomson at edwardthomson.com> 1352100319 -0600	checkout: moving from trivial-9-branch to trivial-9
+f0053b8060bb3f0be5cbcc3147a07ece26bf097e c35dee9bcc0e989f3b0c40f68372a9a51b6c4e6a Edward Thomson <ethomson at edwardthomson.com> 1352100333 -0600	commit: trivial-9
+c35dee9bcc0e989f3b0c40f68372a9a51b6c4e6a bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1352100335 -0600	checkout: moving from trivial-9 to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352100576 -0600	checkout: moving from master to trivial-13
+c607fc30883e335def28cd686b51f6cfa02b06ec 8f4433f8593ddd65b7dd43dd4564d841f4d9c8aa Edward Thomson <ethomson at edwardthomson.com> 1352100589 -0600	commit: trivial-13
+8f4433f8593ddd65b7dd43dd4564d841f4d9c8aa 8f4433f8593ddd65b7dd43dd4564d841f4d9c8aa Edward Thomson <ethomson at edwardthomson.com> 1352100604 -0600	checkout: moving from trivial-13 to trivial-13-branch
+8f4433f8593ddd65b7dd43dd4564d841f4d9c8aa 05f3c1a2a56ca95c3d2ef28dc9ddf32b5cd6c91c Edward Thomson <ethomson at edwardthomson.com> 1352100610 -0600	commit: trivial-13-branch
+05f3c1a2a56ca95c3d2ef28dc9ddf32b5cd6c91c 8f4433f8593ddd65b7dd43dd4564d841f4d9c8aa Edward Thomson <ethomson at edwardthomson.com> 1352100612 -0600	checkout: moving from trivial-13-branch to trivial-13
+8f4433f8593ddd65b7dd43dd4564d841f4d9c8aa a3fabece9eb8748da810e1e08266fef9b7136ad4 Edward Thomson <ethomson at edwardthomson.com> 1352100625 -0600	commit: trivial-13
+a3fabece9eb8748da810e1e08266fef9b7136ad4 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1352100627 -0600	checkout: moving from trivial-13 to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352100936 -0600	checkout: moving from master to trivial-11
+c607fc30883e335def28cd686b51f6cfa02b06ec 35632e43612c06a3ea924bfbacd48333da874c29 Edward Thomson <ethomson at edwardthomson.com> 1352100958 -0600	commit: trivial-11
+35632e43612c06a3ea924bfbacd48333da874c29 35632e43612c06a3ea924bfbacd48333da874c29 Edward Thomson <ethomson at edwardthomson.com> 1352100964 -0600	checkout: moving from trivial-11 to trivial-11-branch
+35632e43612c06a3ea924bfbacd48333da874c29 6718a45909532d1fcf5600d0877f7fe7e78f0b86 Edward Thomson <ethomson at edwardthomson.com> 1352100978 -0600	commit: trivial-11-branch
+6718a45909532d1fcf5600d0877f7fe7e78f0b86 35632e43612c06a3ea924bfbacd48333da874c29 Edward Thomson <ethomson at edwardthomson.com> 1352100981 -0600	checkout: moving from trivial-11-branch to trivial-11
+35632e43612c06a3ea924bfbacd48333da874c29 3168dca1a561889b045a6441909f4c56145e666d Edward Thomson <ethomson at edwardthomson.com> 1352100992 -0600	commit: trivial-11
+3168dca1a561889b045a6441909f4c56145e666d bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1352100996 -0600	checkout: moving from trivial-11 to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352101098 -0600	checkout: moving from master to trivial-14
+c607fc30883e335def28cd686b51f6cfa02b06ec 596803b523203a4851c824c07366906f8353f4ad Edward Thomson <ethomson at edwardthomson.com> 1352101113 -0600	commit: trivial-14
+596803b523203a4851c824c07366906f8353f4ad 596803b523203a4851c824c07366906f8353f4ad Edward Thomson <ethomson at edwardthomson.com> 1352101117 -0600	checkout: moving from trivial-14 to trivial-14-branch
+596803b523203a4851c824c07366906f8353f4ad 8187117062b750eed4f93fd7e899f17b52ce554d Edward Thomson <ethomson at edwardthomson.com> 1352101132 -0600	commit: trivial-14-branch
+8187117062b750eed4f93fd7e899f17b52ce554d 596803b523203a4851c824c07366906f8353f4ad Edward Thomson <ethomson at edwardthomson.com> 1352101135 -0600	checkout: moving from trivial-14-branch to trivial-14
+596803b523203a4851c824c07366906f8353f4ad 7e2d058d5fedf8329db44db4fac610d6b1a89159 Edward Thomson <ethomson at edwardthomson.com> 1352101141 -0600	commit: trivial-14
+7e2d058d5fedf8329db44db4fac610d6b1a89159 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1352101145 -0600	checkout: moving from trivial-14 to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1353177749 -0600	checkout: moving from master to renames1
+c607fc30883e335def28cd686b51f6cfa02b06ec 412b32fb66137366147f1801ecc962452757d48a Edward Thomson <ethomson at edwardthomson.com> 1353177886 -0600	commit: renames
+412b32fb66137366147f1801ecc962452757d48a bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1353794607 -0600	checkout: moving from renames1 to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1353794647 -0600	checkout: moving from master to renames2
+bd593285fc7fe4ca18ccdbabf027f5d689101452 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1353794677 -0600	reset: moving to c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec ab40af3cb8a3ed2e2843e96d9aa7871336b94573 Edward Thomson <ethomson at edwardthomson.com> 1353794852 -0600	commit: renames2
+ab40af3cb8a3ed2e2843e96d9aa7871336b94573 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1353794883 -0600	checkout: moving from renames2 to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1354574697 -0600	checkout: moving from master to df_side1
+bd593285fc7fe4ca18ccdbabf027f5d689101452 d4207f77243500bec335ab477f9227fcdb1e271a Edward Thomson <ethomson at edwardthomson.com> 1354574962 -0600	commit: df_ancestor
+d4207f77243500bec335ab477f9227fcdb1e271a c94b27e41064c521120627e07e2035cca1d24ffa Edward Thomson <ethomson at edwardthomson.com> 1354575027 -0600	commit: df_side1
+c94b27e41064c521120627e07e2035cca1d24ffa d4207f77243500bec335ab477f9227fcdb1e271a Edward Thomson <ethomson at edwardthomson.com> 1354575070 -0600	checkout: moving from df_side1 to df_side2
+d4207f77243500bec335ab477f9227fcdb1e271a f8958bdf4d365a84a9a178b1f5f35ff1dacbd884 Edward Thomson <ethomson at edwardthomson.com> 1354575206 -0600	commit: df_side2
+f8958bdf4d365a84a9a178b1f5f35ff1dacbd884 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1354575381 -0600	checkout: moving from df_side2 to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 c94b27e41064c521120627e07e2035cca1d24ffa Edward Thomson <ethomson at edwardthomson.com> 1355017614 -0600	checkout: moving from master to df_side1
+c94b27e41064c521120627e07e2035cca1d24ffa a90bc3fb6f15181972a2959a921429efbd81a473 Edward Thomson <ethomson at edwardthomson.com> 1355017650 -0600	commit: df_added
+a90bc3fb6f15181972a2959a921429efbd81a473 c94b27e41064c521120627e07e2035cca1d24ffa Edward Thomson <ethomson at edwardthomson.com> 1355017673 -0600	checkout: moving from df_side1 to c94b27e
+c94b27e41064c521120627e07e2035cca1d24ffa d4207f77243500bec335ab477f9227fcdb1e271a Edward Thomson <ethomson at edwardthomson.com> 1355017673 -0600	rebase -i (squash): updating HEAD
+d4207f77243500bec335ab477f9227fcdb1e271a 005b6fcc8fec71d2550bef8462d169b3c26aa14b Edward Thomson <ethomson at edwardthomson.com> 1355017673 -0600	rebase -i (squash): df_side1
+005b6fcc8fec71d2550bef8462d169b3c26aa14b 005b6fcc8fec71d2550bef8462d169b3c26aa14b Edward Thomson <ethomson at edwardthomson.com> 1355017676 -0600	rebase -i (finish): returning to refs/heads/df_side1
+005b6fcc8fec71d2550bef8462d169b3c26aa14b f8958bdf4d365a84a9a178b1f5f35ff1dacbd884 Edward Thomson <ethomson at edwardthomson.com> 1355017715 -0600	reset: moving to df_side2
+f8958bdf4d365a84a9a178b1f5f35ff1dacbd884 8c749d9968d4b10dcfb06c9f97d0e5d92d337071 Edward Thomson <ethomson at edwardthomson.com> 1355017744 -0600	commit: df_added
+8c749d9968d4b10dcfb06c9f97d0e5d92d337071 f8958bdf4d365a84a9a178b1f5f35ff1dacbd884 Edward Thomson <ethomson at edwardthomson.com> 1355017754 -0600	checkout: moving from df_side1 to f8958bd
+f8958bdf4d365a84a9a178b1f5f35ff1dacbd884 d4207f77243500bec335ab477f9227fcdb1e271a Edward Thomson <ethomson at edwardthomson.com> 1355017754 -0600	rebase -i (squash): updating HEAD
+d4207f77243500bec335ab477f9227fcdb1e271a 0204a84f822acbf6386b36d33f1f6bc68bbbf858 Edward Thomson <ethomson at edwardthomson.com> 1355017754 -0600	rebase -i (squash): df_side2
+0204a84f822acbf6386b36d33f1f6bc68bbbf858 0204a84f822acbf6386b36d33f1f6bc68bbbf858 Edward Thomson <ethomson at edwardthomson.com> 1355017756 -0600	rebase -i (finish): returning to refs/heads/df_side1
+0204a84f822acbf6386b36d33f1f6bc68bbbf858 005b6fcc8fec71d2550bef8462d169b3c26aa14b Edward Thomson <ethomson at edwardthomson.com> 1355017793 -0600	reset: moving to 005b6fcc8fec71d2550bef8462d169b3c26aa14b
+005b6fcc8fec71d2550bef8462d169b3c26aa14b 0204a84f822acbf6386b36d33f1f6bc68bbbf858 Edward Thomson <ethomson at edwardthomson.com> 1355017826 -0600	reset: moving to 0204a84
+0204a84f822acbf6386b36d33f1f6bc68bbbf858 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1355017847 -0600	checkout: moving from df_side1 to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 0204a84f822acbf6386b36d33f1f6bc68bbbf858 Edward Thomson <ethomson at edwardthomson.com> 1355168677 -0600	checkout: moving from master to df_side1
+005b6fcc8fec71d2550bef8462d169b3c26aa14b 005b6fcc8fec71d2550bef8462d169b3c26aa14b Edward Thomson <ethomson at edwardthomson.com> 1355168829 -0600	checkout: moving from df_side1 to df_side1
+005b6fcc8fec71d2550bef8462d169b3c26aa14b 005b6fcc8fec71d2550bef8462d169b3c26aa14b Edward Thomson <ethomson at edwardthomson.com> 1355168838 -0600	checkout: moving from df_side1 to df_side1
+005b6fcc8fec71d2550bef8462d169b3c26aa14b e8107f24196736b870a318a0e28f048e29f6feff Edward Thomson <ethomson at edwardthomson.com> 1355169065 -0600	commit: df_side1
+e8107f24196736b870a318a0e28f048e29f6feff 005b6fcc8fec71d2550bef8462d169b3c26aa14b Edward Thomson <ethomson at edwardthomson.com> 1355169081 -0600	checkout: moving from df_side1 to 005b6fc
+005b6fcc8fec71d2550bef8462d169b3c26aa14b d4207f77243500bec335ab477f9227fcdb1e271a Edward Thomson <ethomson at edwardthomson.com> 1355169081 -0600	rebase -i (squash): updating HEAD
+d4207f77243500bec335ab477f9227fcdb1e271a 80a8fbb3abb1ba423d554e9630b8fc2e5698f86b Edward Thomson <ethomson at edwardthomson.com> 1355169081 -0600	rebase -i (squash): df_side1
+80a8fbb3abb1ba423d554e9630b8fc2e5698f86b 80a8fbb3abb1ba423d554e9630b8fc2e5698f86b Edward Thomson <ethomson at edwardthomson.com> 1355169084 -0600	rebase -i (finish): returning to refs/heads/df_side1
+80a8fbb3abb1ba423d554e9630b8fc2e5698f86b 0204a84f822acbf6386b36d33f1f6bc68bbbf858 Edward Thomson <ethomson at edwardthomson.com> 1355169141 -0600	checkout: moving from df_side1 to df_side2
+0204a84f822acbf6386b36d33f1f6bc68bbbf858 944f5dd1a867cab4c2bbcb896493435cae1dcc1a Edward Thomson <ethomson at edwardthomson.com> 1355169174 -0600	commit: both
+944f5dd1a867cab4c2bbcb896493435cae1dcc1a 0204a84f822acbf6386b36d33f1f6bc68bbbf858 Edward Thomson <ethomson at edwardthomson.com> 1355169182 -0600	checkout: moving from df_side2 to 0204a84
+0204a84f822acbf6386b36d33f1f6bc68bbbf858 d4207f77243500bec335ab477f9227fcdb1e271a Edward Thomson <ethomson at edwardthomson.com> 1355169182 -0600	rebase -i (squash): updating HEAD
+d4207f77243500bec335ab477f9227fcdb1e271a 57079a46233ae2b6df62e9ade71c4948512abefb Edward Thomson <ethomson at edwardthomson.com> 1355169182 -0600	rebase -i (squash): df_side2
+57079a46233ae2b6df62e9ade71c4948512abefb 57079a46233ae2b6df62e9ade71c4948512abefb Edward Thomson <ethomson at edwardthomson.com> 1355169185 -0600	rebase -i (finish): returning to refs/heads/df_side2
+57079a46233ae2b6df62e9ade71c4948512abefb 80a8fbb3abb1ba423d554e9630b8fc2e5698f86b Edward Thomson <ethomson at edwardthomson.com> 1355169241 -0600	checkout: moving from df_side2 to df_side1
+80a8fbb3abb1ba423d554e9630b8fc2e5698f86b e65a9bb2af9f4c2d1c375dd0f8f8a46cf9c68812 Edward Thomson <ethomson at edwardthomson.com> 1355169419 -0600	commit: side1
+e65a9bb2af9f4c2d1c375dd0f8f8a46cf9c68812 80a8fbb3abb1ba423d554e9630b8fc2e5698f86b Edward Thomson <ethomson at edwardthomson.com> 1355169431 -0600	checkout: moving from df_side1 to 80a8fbb
+80a8fbb3abb1ba423d554e9630b8fc2e5698f86b d4207f77243500bec335ab477f9227fcdb1e271a Edward Thomson <ethomson at edwardthomson.com> 1355169431 -0600	rebase -i (squash): updating HEAD
+d4207f77243500bec335ab477f9227fcdb1e271a 5dc1018e90b19654bee986b7a0c268804d39659d Edward Thomson <ethomson at edwardthomson.com> 1355169431 -0600	rebase -i (squash): df_side1
+5dc1018e90b19654bee986b7a0c268804d39659d 5dc1018e90b19654bee986b7a0c268804d39659d Edward Thomson <ethomson at edwardthomson.com> 1355169435 -0600	rebase -i (finish): returning to refs/heads/df_side1
+5dc1018e90b19654bee986b7a0c268804d39659d 57079a46233ae2b6df62e9ade71c4948512abefb Edward Thomson <ethomson at edwardthomson.com> 1355169439 -0600	checkout: moving from df_side1 to df_side2
+57079a46233ae2b6df62e9ade71c4948512abefb 58e853f66699fd02629fd50bde08082bc005933a Edward Thomson <ethomson at edwardthomson.com> 1355169460 -0600	commit: side2
+58e853f66699fd02629fd50bde08082bc005933a 57079a46233ae2b6df62e9ade71c4948512abefb Edward Thomson <ethomson at edwardthomson.com> 1355169469 -0600	checkout: moving from df_side2 to 57079a4
+57079a46233ae2b6df62e9ade71c4948512abefb d4207f77243500bec335ab477f9227fcdb1e271a Edward Thomson <ethomson at edwardthomson.com> 1355169469 -0600	rebase -i (squash): updating HEAD
+d4207f77243500bec335ab477f9227fcdb1e271a fada9356aa3f74622327a3038ae9c6f92e1c5c1d Edward Thomson <ethomson at edwardthomson.com> 1355169469 -0600	rebase -i (squash): df_side2
+fada9356aa3f74622327a3038ae9c6f92e1c5c1d fada9356aa3f74622327a3038ae9c6f92e1c5c1d Edward Thomson <ethomson at edwardthomson.com> 1355169471 -0600	rebase -i (finish): returning to refs/heads/df_side2
+fada9356aa3f74622327a3038ae9c6f92e1c5c1d 5dc1018e90b19654bee986b7a0c268804d39659d Edward Thomson <ethomson at edwardthomson.com> 1355169494 -0600	checkout: moving from df_side2 to df_side1
+5dc1018e90b19654bee986b7a0c268804d39659d d4207f77243500bec335ab477f9227fcdb1e271a Edward Thomson <ethomson at edwardthomson.com> 1355169663 -0600	checkout: moving from df_side1 to d4207f77243500bec335ab477f9227fcdb1e271a
+d4207f77243500bec335ab477f9227fcdb1e271a 849619b03ae540acee4d1edec96b86993da6b497 Edward Thomson <ethomson at edwardthomson.com> 1355169683 -0600	commit: both_dirs
+849619b03ae540acee4d1edec96b86993da6b497 d4207f77243500bec335ab477f9227fcdb1e271a Edward Thomson <ethomson at edwardthomson.com> 1355169691 -0600	checkout: moving from 849619b03ae540acee4d1edec96b86993da6b497 to d4207f7
+d4207f77243500bec335ab477f9227fcdb1e271a bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1355169691 -0600	rebase -i (squash): updating HEAD
+bd593285fc7fe4ca18ccdbabf027f5d689101452 a765fb87eb2f7a1920b73b2d5a057f8f8476a42b Edward Thomson <ethomson at edwardthomson.com> 1355169691 -0600	rebase -i (squash): df_ancestor
+a765fb87eb2f7a1920b73b2d5a057f8f8476a42b 5dc1018e90b19654bee986b7a0c268804d39659d Edward Thomson <ethomson at edwardthomson.com> 1355169706 -0600	checkout: moving from a765fb87eb2f7a1920b73b2d5a057f8f8476a42b to df_side1
+5dc1018e90b19654bee986b7a0c268804d39659d a765fb87eb2f7a1920b73b2d5a057f8f8476a42b Edward Thomson <ethomson at edwardthomson.com> 1355169715 -0600	checkout: moving from df_side1 to a765fb87eb2f7a1920b73b2d5a057f8f8476a42b^0
+a765fb87eb2f7a1920b73b2d5a057f8f8476a42b bc744705e1d8a019993cf88f62bc4020f1b80919 Edward Thomson <ethomson at edwardthomson.com> 1355169801 -0600	commit: df_side1
+bc744705e1d8a019993cf88f62bc4020f1b80919 bc744705e1d8a019993cf88f62bc4020f1b80919 Edward Thomson <ethomson at edwardthomson.com> 1355169822 -0600	checkout: moving from bc744705e1d8a019993cf88f62bc4020f1b80919 to df_side1
+bc744705e1d8a019993cf88f62bc4020f1b80919 fada9356aa3f74622327a3038ae9c6f92e1c5c1d Edward Thomson <ethomson at edwardthomson.com> 1355169826 -0600	checkout: moving from df_side1 to df_side2
+fada9356aa3f74622327a3038ae9c6f92e1c5c1d a765fb87eb2f7a1920b73b2d5a057f8f8476a42b Edward Thomson <ethomson at edwardthomson.com> 1355169866 -0600	checkout: moving from df_side2 to a765fb87eb2f7a1920b73b2d5a057f8f8476a42b^0
+a765fb87eb2f7a1920b73b2d5a057f8f8476a42b 95646149ab6b6ba6edc83cff678582538b457b2b Edward Thomson <ethomson at edwardthomson.com> 1355169897 -0600	rebase: df_side2
+95646149ab6b6ba6edc83cff678582538b457b2b 95646149ab6b6ba6edc83cff678582538b457b2b Edward Thomson <ethomson at edwardthomson.com> 1355169897 -0600	rebase finished: returning to refs/heads/df_side2
+95646149ab6b6ba6edc83cff678582538b457b2b bc744705e1d8a019993cf88f62bc4020f1b80919 Edward Thomson <ethomson at edwardthomson.com> 1355169949 -0600	checkout: moving from df_side2 to df_side1
+bc744705e1d8a019993cf88f62bc4020f1b80919 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1355170046 -0600	checkout: moving from df_side1 to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1355181639 -0600	checkout: moving from master to df_ancestor
+bd593285fc7fe4ca18ccdbabf027f5d689101452 2da538570bc1e5b2c3e855bf702f35248ad0735f Edward Thomson <ethomson at edwardthomson.com> 1355181673 -0600	commit: df_ancestor
+2da538570bc1e5b2c3e855bf702f35248ad0735f a7dbfcbfc1a60709cb80b5ca24539008456531d0 Edward Thomson <ethomson at edwardthomson.com> 1355181715 -0600	commit: df_side1
+a7dbfcbfc1a60709cb80b5ca24539008456531d0 a7dbfcbfc1a60709cb80b5ca24539008456531d0 Edward Thomson <ethomson at edwardthomson.com> 1355181743 -0600	checkout: moving from df_ancestor to df_ancestor
+a7dbfcbfc1a60709cb80b5ca24539008456531d0 9a301fbe6fada7dcb74fcd7c20269b5c743459a7 Edward Thomson <ethomson at edwardthomson.com> 1355181775 -0600	commit: df_side2
+9a301fbe6fada7dcb74fcd7c20269b5c743459a7 a7dbfcbfc1a60709cb80b5ca24539008456531d0 Edward Thomson <ethomson at edwardthomson.com> 1355181793 -0600	checkout: moving from df_ancestor to df_side1
+a7dbfcbfc1a60709cb80b5ca24539008456531d0 9a301fbe6fada7dcb74fcd7c20269b5c743459a7 Edward Thomson <ethomson at edwardthomson.com> 1355181797 -0600	checkout: moving from df_side1 to df_side2
+9a301fbe6fada7dcb74fcd7c20269b5c743459a7 9a301fbe6fada7dcb74fcd7c20269b5c743459a7 Edward Thomson <ethomson at edwardthomson.com> 1355182062 -0600	checkout: moving from df_side2 to df_ancestor
+9a301fbe6fada7dcb74fcd7c20269b5c743459a7 2da538570bc1e5b2c3e855bf702f35248ad0735f Edward Thomson <ethomson at edwardthomson.com> 1355182067 -0600	reset: moving to 2da538570bc1e5b2c3e855bf702f35248ad0735f
+2da538570bc1e5b2c3e855bf702f35248ad0735f 2da538570bc1e5b2c3e855bf702f35248ad0735f Edward Thomson <ethomson at edwardthomson.com> 1355182087 -0600	checkout: moving from df_ancestor to df_side2
+2da538570bc1e5b2c3e855bf702f35248ad0735f fc90237dc4891fa6c69827fc465632225e391618 Edward Thomson <ethomson at edwardthomson.com> 1355182104 -0600	commit: df_side2
+fc90237dc4891fa6c69827fc465632225e391618 a7dbfcbfc1a60709cb80b5ca24539008456531d0 Edward Thomson <ethomson at edwardthomson.com> 1355182111 -0600	checkout: moving from df_side2 to df_side1
+a7dbfcbfc1a60709cb80b5ca24539008456531d0 fc90237dc4891fa6c69827fc465632225e391618 Edward Thomson <ethomson at edwardthomson.com> 1355182115 -0600	checkout: moving from df_side1 to df_side2
+fc90237dc4891fa6c69827fc465632225e391618 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1355182122 -0600	checkout: moving from df_side2 to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 d6cf6c7741b3316826af1314042550c97ded1d50 Edward Thomson <ethomson at edwardthomson.com> 1358997543 -0600	checkout: moving from master to unrelated
+d6cf6c7741b3316826af1314042550c97ded1d50 55b4e4687e7a0d9ca367016ed930f385d4022e6f Edward Thomson <ethomson at edwardthomson.com> 1358997664 -0600	commit: conflicting changes
+55b4e4687e7a0d9ca367016ed930f385d4022e6f bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1358997675 -0600	checkout: moving from unrelated to master
+bd593285fc7fe4ca18ccdbabf027f5d689101452 88e185910a15cd13bdf44854ad037f4842b03b29 Edward Thomson <ethomson at microsoft.com> 1365714471 -0500	checkout: moving from master to rename_conflict_ours
+88e185910a15cd13bdf44854ad037f4842b03b29 bef6e37b3ee632ba74159168836f382fed21d77d Edward Thomson <ethomson at microsoft.com> 1365714516 -0500	checkout: moving from rename_conflict_ours to bef6e37b3ee632ba74159168836f382fed21d77d
+bef6e37b3ee632ba74159168836f382fed21d77d 01f149e1b8f84bd8896aaff6d6b22af88459ded0 Edward Thomson <ethomson at microsoft.com> 1365714831 -0500	commit: rename ancestor
+0000000000000000000000000000000000000000 2392a2dacc9efb562b8635d6579fb458751c7c5b Edward Thomson <ethomson at microsoft.com> 1365714958 -0500	commit (initial): rename conflict ancestor
+2392a2dacc9efb562b8635d6579fb458751c7c5b 88e185910a15cd13bdf44854ad037f4842b03b29 Edward Thomson <ethomson at microsoft.com> 1365714980 -0500	checkout: moving from rename_conflict_ancestor to rename_conflict_ours
+88e185910a15cd13bdf44854ad037f4842b03b29 7c2c5228c9e90170d4a35e6558e47163daf092e5 Edward Thomson <ethomson at microsoft.com> 1365715250 -0500	commit: rename conflict ours
+7c2c5228c9e90170d4a35e6558e47163daf092e5 2f4024ce528d36d8670c289cce5a7963e625bb0c Edward Thomson <ethomson at microsoft.com> 1365715274 -0500	checkout: moving from rename_conflict_ours to rename_conflict_theirs
+2f4024ce528d36d8670c289cce5a7963e625bb0c 56a638b76b75e068590ac999c2f8621e7f3e264c Edward Thomson <ethomson at microsoft.com> 1365715362 -0500	commit: rename conflict theirs
+56a638b76b75e068590ac999c2f8621e7f3e264c 2392a2dacc9efb562b8635d6579fb458751c7c5b Edward Thomson <ethomson at microsoft.com> 1365715368 -0500	checkout: moving from rename_conflict_theirs to rename_conflict_ancestor
+2392a2dacc9efb562b8635d6579fb458751c7c5b 56a638b76b75e068590ac999c2f8621e7f3e264c Edward Thomson <ethomson at microsoft.com> 1365715371 -0500	checkout: moving from rename_conflict_ancestor to rename_conflict_theirs
+56a638b76b75e068590ac999c2f8621e7f3e264c 2392a2dacc9efb562b8635d6579fb458751c7c5b Edward Thomson <ethomson at microsoft.com> 1365715404 -0500	checkout: moving from rename_conflict_theirs to rename_conflict_ancestor
+2392a2dacc9efb562b8635d6579fb458751c7c5b 2392a2dacc9efb562b8635d6579fb458751c7c5b Edward Thomson <ethomson at microsoft.com> 1365715438 -0500	checkout: moving from rename_conflict_ancestor to rename_conflict_ours
+2392a2dacc9efb562b8635d6579fb458751c7c5b 2392a2dacc9efb562b8635d6579fb458751c7c5b Edward Thomson <ethomson at microsoft.com> 1365715480 -0500	checkout: moving from rename_conflict_ours to rename_conflict_ancestor
+2392a2dacc9efb562b8635d6579fb458751c7c5b 2392a2dacc9efb562b8635d6579fb458751c7c5b Edward Thomson <ethomson at microsoft.com> 1365715486 -0500	checkout: moving from rename_conflict_ancestor to rename_conflict_ours
+2392a2dacc9efb562b8635d6579fb458751c7c5b f3293571dcd708b6a3faf03818cd2844d000e198 Edward Thomson <ethomson at microsoft.com> 1365715538 -0500	commit: rename conflict ours
+f3293571dcd708b6a3faf03818cd2844d000e198 2392a2dacc9efb562b8635d6579fb458751c7c5b Edward Thomson <ethomson at microsoft.com> 1365715546 -0500	checkout: moving from rename_conflict_ours to rename_conflict_ancestor
+2392a2dacc9efb562b8635d6579fb458751c7c5b 2392a2dacc9efb562b8635d6579fb458751c7c5b Edward Thomson <ethomson at microsoft.com> 1365715550 -0500	checkout: moving from rename_conflict_ancestor to rename_conflict_thiers
+2392a2dacc9efb562b8635d6579fb458751c7c5b 2392a2dacc9efb562b8635d6579fb458751c7c5b Edward Thomson <ethomson at microsoft.com> 1365715554 -0500	checkout: moving from rename_conflict_thiers to rename_conflict_ancestor
+2392a2dacc9efb562b8635d6579fb458751c7c5b 2392a2dacc9efb562b8635d6579fb458751c7c5b Edward Thomson <ethomson at microsoft.com> 1365715557 -0500	checkout: moving from rename_conflict_ancestor to rename_conflict_theirs
+2392a2dacc9efb562b8635d6579fb458751c7c5b a802e06f1782a9645b9851bc7202cee74a8a4972 Edward Thomson <ethomson at microsoft.com> 1365715572 -0500	commit: rename conflict theirs
+a802e06f1782a9645b9851bc7202cee74a8a4972 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at microsoft.com> 1365715620 -0500	checkout: moving from rename_conflict_theirs to master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/branch
new file mode 100755
index 0000000..8b0acb7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/branch
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1351563886 -0500	branch: Created from HEAD
+c607fc30883e335def28cd686b51f6cfa02b06ec 7cb63eed597130ba4abb87b3e544b85021905520 Edward Thomson <ethomson at edwardthomson.com> 1351563965 -0500	commit: branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/df_ancestor b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/df_ancestor
new file mode 100755
index 0000000..df7695a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/df_ancestor
@@ -0,0 +1,5 @@
+0000000000000000000000000000000000000000 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1355181639 -0600	branch: Created from HEAD
+bd593285fc7fe4ca18ccdbabf027f5d689101452 2da538570bc1e5b2c3e855bf702f35248ad0735f Edward Thomson <ethomson at edwardthomson.com> 1355181673 -0600	commit: df_ancestor
+2da538570bc1e5b2c3e855bf702f35248ad0735f a7dbfcbfc1a60709cb80b5ca24539008456531d0 Edward Thomson <ethomson at edwardthomson.com> 1355181715 -0600	commit: df_side1
+a7dbfcbfc1a60709cb80b5ca24539008456531d0 9a301fbe6fada7dcb74fcd7c20269b5c743459a7 Edward Thomson <ethomson at edwardthomson.com> 1355181775 -0600	commit: df_side2
+9a301fbe6fada7dcb74fcd7c20269b5c743459a7 2da538570bc1e5b2c3e855bf702f35248ad0735f Edward Thomson <ethomson at edwardthomson.com> 1355182067 -0600	reset: moving to 2da538570bc1e5b2c3e855bf702f35248ad0735f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/df_side1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/df_side1
new file mode 100755
index 0000000..a504ad6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/df_side1
@@ -0,0 +1,14 @@
+0000000000000000000000000000000000000000 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1354574697 -0600	branch: Created from HEAD
+bd593285fc7fe4ca18ccdbabf027f5d689101452 d4207f77243500bec335ab477f9227fcdb1e271a Edward Thomson <ethomson at edwardthomson.com> 1354574962 -0600	commit: df_ancestor
+d4207f77243500bec335ab477f9227fcdb1e271a c94b27e41064c521120627e07e2035cca1d24ffa Edward Thomson <ethomson at edwardthomson.com> 1354575027 -0600	commit: df_side1
+c94b27e41064c521120627e07e2035cca1d24ffa a90bc3fb6f15181972a2959a921429efbd81a473 Edward Thomson <ethomson at edwardthomson.com> 1355017650 -0600	commit: df_added
+a90bc3fb6f15181972a2959a921429efbd81a473 005b6fcc8fec71d2550bef8462d169b3c26aa14b Edward Thomson <ethomson at edwardthomson.com> 1355017676 -0600	rebase -i (finish): refs/heads/df_side1 onto c94b27e
+005b6fcc8fec71d2550bef8462d169b3c26aa14b f8958bdf4d365a84a9a178b1f5f35ff1dacbd884 Edward Thomson <ethomson at edwardthomson.com> 1355017715 -0600	reset: moving to df_side2
+f8958bdf4d365a84a9a178b1f5f35ff1dacbd884 8c749d9968d4b10dcfb06c9f97d0e5d92d337071 Edward Thomson <ethomson at edwardthomson.com> 1355017744 -0600	commit: df_added
+8c749d9968d4b10dcfb06c9f97d0e5d92d337071 0204a84f822acbf6386b36d33f1f6bc68bbbf858 Edward Thomson <ethomson at edwardthomson.com> 1355017756 -0600	rebase -i (finish): refs/heads/df_side1 onto f8958bd
+0204a84f822acbf6386b36d33f1f6bc68bbbf858 005b6fcc8fec71d2550bef8462d169b3c26aa14b Edward Thomson <ethomson at edwardthomson.com> 1355017793 -0600	reset: moving to 005b6fcc8fec71d2550bef8462d169b3c26aa14b
+005b6fcc8fec71d2550bef8462d169b3c26aa14b 0204a84f822acbf6386b36d33f1f6bc68bbbf858 Edward Thomson <ethomson at edwardthomson.com> 1355017826 -0600	reset: moving to 0204a84
+005b6fcc8fec71d2550bef8462d169b3c26aa14b e8107f24196736b870a318a0e28f048e29f6feff Edward Thomson <ethomson at edwardthomson.com> 1355169065 -0600	commit: df_side1
+e8107f24196736b870a318a0e28f048e29f6feff 80a8fbb3abb1ba423d554e9630b8fc2e5698f86b Edward Thomson <ethomson at edwardthomson.com> 1355169084 -0600	rebase -i (finish): refs/heads/df_side1 onto 005b6fc
+80a8fbb3abb1ba423d554e9630b8fc2e5698f86b e65a9bb2af9f4c2d1c375dd0f8f8a46cf9c68812 Edward Thomson <ethomson at edwardthomson.com> 1355169419 -0600	commit: side1
+e65a9bb2af9f4c2d1c375dd0f8f8a46cf9c68812 5dc1018e90b19654bee986b7a0c268804d39659d Edward Thomson <ethomson at edwardthomson.com> 1355169435 -0600	rebase -i (finish): refs/heads/df_side1 onto 80a8fbb
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/df_side2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/df_side2
new file mode 100755
index 0000000..27d833e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/df_side2
@@ -0,0 +1,9 @@
+0000000000000000000000000000000000000000 d4207f77243500bec335ab477f9227fcdb1e271a Edward Thomson <ethomson at edwardthomson.com> 1354575051 -0600	branch: Created from d4207f77243500bec335ab477f9227fcdb1e271a
+d4207f77243500bec335ab477f9227fcdb1e271a f8958bdf4d365a84a9a178b1f5f35ff1dacbd884 Edward Thomson <ethomson at edwardthomson.com> 1354575206 -0600	commit: df_side2
+0204a84f822acbf6386b36d33f1f6bc68bbbf858 944f5dd1a867cab4c2bbcb896493435cae1dcc1a Edward Thomson <ethomson at edwardthomson.com> 1355169174 -0600	commit: both
+944f5dd1a867cab4c2bbcb896493435cae1dcc1a 57079a46233ae2b6df62e9ade71c4948512abefb Edward Thomson <ethomson at edwardthomson.com> 1355169185 -0600	rebase -i (finish): refs/heads/df_side2 onto 0204a84
+57079a46233ae2b6df62e9ade71c4948512abefb 58e853f66699fd02629fd50bde08082bc005933a Edward Thomson <ethomson at edwardthomson.com> 1355169460 -0600	commit: side2
+58e853f66699fd02629fd50bde08082bc005933a fada9356aa3f74622327a3038ae9c6f92e1c5c1d Edward Thomson <ethomson at edwardthomson.com> 1355169471 -0600	rebase -i (finish): refs/heads/df_side2 onto 57079a4
+fada9356aa3f74622327a3038ae9c6f92e1c5c1d 95646149ab6b6ba6edc83cff678582538b457b2b Edward Thomson <ethomson at edwardthomson.com> 1355169897 -0600	rebase finished: refs/heads/df_side2 onto a765fb87eb2f7a1920b73b2d5a057f8f8476a42b
+0000000000000000000000000000000000000000 2da538570bc1e5b2c3e855bf702f35248ad0735f Edward Thomson <ethomson at edwardthomson.com> 1355182087 -0600	branch: Created from HEAD
+2da538570bc1e5b2c3e855bf702f35248ad0735f fc90237dc4891fa6c69827fc465632225e391618 Edward Thomson <ethomson at edwardthomson.com> 1355182104 -0600	commit: df_side2
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/ff_branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/ff_branch
new file mode 100755
index 0000000..c470617
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/ff_branch
@@ -0,0 +1,5 @@
+0000000000000000000000000000000000000000 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351605785 -0500	branch: Created from HEAD
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 33d500f588fbbe65901d82b4e6b008e549064be0 Edward Thomson <ethomson at edwardthomson.com> 1351605830 -0500	commit: fastforward
+33d500f588fbbe65901d82b4e6b008e549064be0 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1351990202 -0500	reset: moving to c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1351990205 -0500	merge master: Fast-forward
+bd593285fc7fe4ca18ccdbabf027f5d689101452 fd89f8cffb663ac89095a0f9764902e93ceaca6a Edward Thomson <ethomson at edwardthomson.com> 1351990229 -0500	commit: fastforward
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..6047599
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/master
@@ -0,0 +1,5 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1351563869 -0500	commit (initial): initial
+c607fc30883e335def28cd686b51f6cfa02b06ec 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351564033 -0500	commit: master
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 4e0d9401aee78eb345a8685a859d37c8c3c0bbed Edward Thomson <ethomson at edwardthomson.com> 1351875091 -0500	merge octo1 octo2 octo3 octo4: Merge made by the 'octopus' strategy.
+4e0d9401aee78eb345a8685a859d37c8c3c0bbed 54269b3f6ec3d7d4ede24dd350dd5d605495c3ae Edward Thomson <ethomson at edwardthomson.com> 1351875108 -0500	reset: moving to 54269b3f6ec3d7d4ede24dd350dd5d605495c3ae
+54269b3f6ec3d7d4ede24dd350dd5d605495c3ae 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351875584 -0500	reset: moving to 977c696519c5a3004c5f1d15d60c89dbeb8f235f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo1
new file mode 100755
index 0000000..0b6c921
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo1
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351874933 -0500	branch: Created from HEAD
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 16f825815cfd20a07a75c71554e82d8eede0b061 Edward Thomson <ethomson at edwardthomson.com> 1351874954 -0500	commit: octo1
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo2
new file mode 100755
index 0000000..5392a4f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo2
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351874960 -0500	branch: Created from HEAD
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 158dc7bedb202f5b26502bf3574faa7f4238d56c Edward Thomson <ethomson at edwardthomson.com> 1351874974 -0500	commit: octo2
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo3
new file mode 100755
index 0000000..7db5617
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo3
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351874980 -0500	branch: Created from HEAD
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 50ce7d7d01217679e26c55939eef119e0c93e272 Edward Thomson <ethomson at edwardthomson.com> 1351874998 -0500	commit: octo3
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo4
new file mode 100755
index 0000000..b0f9e42
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo4
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351875010 -0500	branch: Created from HEAD
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 54269b3f6ec3d7d4ede24dd350dd5d605495c3ae Edward Thomson <ethomson at edwardthomson.com> 1351875023 -0500	commit: octo4
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo5
new file mode 100755
index 0000000..614563e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo5
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351875031 -0500	branch: Created from HEAD
+977c696519c5a3004c5f1d15d60c89dbeb8f235f e4f618a2c3ed0669308735727df5ebf2447f022f Edward Thomson <ethomson at edwardthomson.com> 1351875041 -0500	commit: octo5
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo6
new file mode 100755
index 0000000..4c812ea
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/octo6
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 977c696519c5a3004c5f1d15d60c89dbeb8f235f Edward Thomson <ethomson at edwardthomson.com> 1351875046 -0500	branch: Created from HEAD
+977c696519c5a3004c5f1d15d60c89dbeb8f235f 4ca408a8c88655f7586a1b580be6fad138121e98 Edward Thomson <ethomson at edwardthomson.com> 1351875057 -0500	commit: octo5
+4ca408a8c88655f7586a1b580be6fad138121e98 b6f610aef53bd343e6c96227de874c66f00ee8e8 Edward Thomson <ethomson at edwardthomson.com> 1351875065 -0500	commit (amend): octo6
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/renames1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/renames1
new file mode 100755
index 0000000..58a7e05
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/renames1
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1353177745 -0600	branch: Created from c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec 412b32fb66137366147f1801ecc962452757d48a Edward Thomson <ethomson at edwardthomson.com> 1353177886 -0600	commit: renames
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/renames2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/renames2
new file mode 100755
index 0000000..5645ece
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/renames2
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 bd593285fc7fe4ca18ccdbabf027f5d689101452 Edward Thomson <ethomson at edwardthomson.com> 1353794647 -0600	branch: Created from HEAD
+bd593285fc7fe4ca18ccdbabf027f5d689101452 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1353794677 -0600	reset: moving to c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec ab40af3cb8a3ed2e2843e96d9aa7871336b94573 Edward Thomson <ethomson at edwardthomson.com> 1353794852 -0600	commit: renames2
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-10 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-10
new file mode 100755
index 0000000..b6bd247
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-10
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352100171 -0600	branch: Created from c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec 53825f41ac8d640612f9423a2f03a69f3d96809a Edward Thomson <ethomson at edwardthomson.com> 1352100193 -0600	commit: trivial-10
+53825f41ac8d640612f9423a2f03a69f3d96809a 0ec5f433959cd46177f745903353efb5be08d151 Edward Thomson <ethomson at edwardthomson.com> 1352100223 -0600	commit: trivial-10
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-10-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-10-branch
new file mode 100755
index 0000000..14ce9e5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-10-branch
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 53825f41ac8d640612f9423a2f03a69f3d96809a Edward Thomson <ethomson at edwardthomson.com> 1352100200 -0600	branch: Created from HEAD
+53825f41ac8d640612f9423a2f03a69f3d96809a 11f4f3c08b737f5fd896cbefa1425ee63b21b2fa Edward Thomson <ethomson at edwardthomson.com> 1352100211 -0600	commit: trivial-10-branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-11 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-11
new file mode 100755
index 0000000..3e6b774
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-11
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352100930 -0600	branch: Created from c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec 35632e43612c06a3ea924bfbacd48333da874c29 Edward Thomson <ethomson at edwardthomson.com> 1352100958 -0600	commit: trivial-11
+35632e43612c06a3ea924bfbacd48333da874c29 3168dca1a561889b045a6441909f4c56145e666d Edward Thomson <ethomson at edwardthomson.com> 1352100992 -0600	commit: trivial-11
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-11-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-11-branch
new file mode 100755
index 0000000..30d5ec7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-11-branch
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 35632e43612c06a3ea924bfbacd48333da874c29 Edward Thomson <ethomson at edwardthomson.com> 1352100964 -0600	branch: Created from HEAD
+35632e43612c06a3ea924bfbacd48333da874c29 6718a45909532d1fcf5600d0877f7fe7e78f0b86 Edward Thomson <ethomson at edwardthomson.com> 1352100978 -0600	commit: trivial-11-branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-13 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-13
new file mode 100755
index 0000000..3a7302d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-13
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352100559 -0600	branch: Created from c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec 8f4433f8593ddd65b7dd43dd4564d841f4d9c8aa Edward Thomson <ethomson at edwardthomson.com> 1352100589 -0600	commit: trivial-13
+8f4433f8593ddd65b7dd43dd4564d841f4d9c8aa a3fabece9eb8748da810e1e08266fef9b7136ad4 Edward Thomson <ethomson at edwardthomson.com> 1352100625 -0600	commit: trivial-13
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-13-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-13-branch
new file mode 100755
index 0000000..bb26042
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-13-branch
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 8f4433f8593ddd65b7dd43dd4564d841f4d9c8aa Edward Thomson <ethomson at edwardthomson.com> 1352100604 -0600	branch: Created from HEAD
+8f4433f8593ddd65b7dd43dd4564d841f4d9c8aa 05f3c1a2a56ca95c3d2ef28dc9ddf32b5cd6c91c Edward Thomson <ethomson at edwardthomson.com> 1352100610 -0600	commit: trivial-13-branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-14 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-14
new file mode 100755
index 0000000..4b70d28
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-14
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352101083 -0600	branch: Created from c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec 596803b523203a4851c824c07366906f8353f4ad Edward Thomson <ethomson at edwardthomson.com> 1352101113 -0600	commit: trivial-14
+596803b523203a4851c824c07366906f8353f4ad 7e2d058d5fedf8329db44db4fac610d6b1a89159 Edward Thomson <ethomson at edwardthomson.com> 1352101141 -0600	commit: trivial-14
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-14-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-14-branch
new file mode 100755
index 0000000..8e491ca
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-14-branch
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 596803b523203a4851c824c07366906f8353f4ad Edward Thomson <ethomson at edwardthomson.com> 1352101117 -0600	branch: Created from HEAD
+596803b523203a4851c824c07366906f8353f4ad 8187117062b750eed4f93fd7e899f17b52ce554d Edward Thomson <ethomson at edwardthomson.com> 1352101132 -0600	commit: trivial-14-branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-2alt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-2alt
new file mode 100755
index 0000000..a2a28d4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-2alt
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352091695 -0600	branch: Created from c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec 566ab53c220a2eafc1212af1a024513230280ab9 Edward Thomson <ethomson at edwardthomson.com> 1352092452 -0600	commit: 2alt
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-2alt-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-2alt-branch
new file mode 100755
index 0000000..a0a48ae
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-2alt-branch
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352092411 -0600	branch: Created from HEAD
+c607fc30883e335def28cd686b51f6cfa02b06ec c9174cef549ec94ecbc43ef03cdc775b4950becb Edward Thomson <ethomson at edwardthomson.com> 1352092434 -0600	commit: 2alt-branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-3alt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-3alt
new file mode 100755
index 0000000..4374d38
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-3alt
@@ -0,0 +1,3 @@
+566ab53c220a2eafc1212af1a024513230280ab9 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352094547 -0600	reset: moving to c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec 5459c89aa0026d543ce8343bd89871bce543f9c2 Edward Thomson <ethomson at edwardthomson.com> 1352094580 -0600	commit: 3alt
+5459c89aa0026d543ce8343bd89871bce543f9c2 4c9fac0707f8d4195037ae5a681aa48626491541 Edward Thomson <ethomson at edwardthomson.com> 1352094610 -0600	commit: 3alt-branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-3alt-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-3alt-branch
new file mode 100755
index 0000000..7a2e6f8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-3alt-branch
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352094594 -0600	branch: Created from c607fc30883e335def28cd686b51f6cfa02b06ec
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-4
new file mode 100755
index 0000000..3ee6d25
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-4
@@ -0,0 +1,2 @@
+566ab53c220a2eafc1212af1a024513230280ab9 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352094764 -0600	reset: moving to c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec cc3e3009134cb88014129fc8858d1101359e5e2f Edward Thomson <ethomson at edwardthomson.com> 1352094815 -0600	commit: trivial-4
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-4-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-4-branch
new file mode 100755
index 0000000..51f8a92
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-4-branch
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352094830 -0600	branch: Created from c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec 183310e30fb1499af8c619108ffea4d300b5e778 Edward Thomson <ethomson at edwardthomson.com> 1352094856 -0600	commit: trivial-4-branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-5alt-1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-5alt-1
new file mode 100755
index 0000000..1449702
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-5alt-1
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352096606 -0600	branch: Created from c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec 4fe93c0ec83eb6305cbace3dace88ecee1b63cb6 Edward Thomson <ethomson at edwardthomson.com> 1352096643 -0600	commit: 5alt-1
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-5alt-1-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-5alt-1-branch
new file mode 100755
index 0000000..4cff835
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-5alt-1-branch
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352096657 -0600	branch: Created from c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec 478172cb2f5ff9b514bc9d04d3bd5ef5840cb3b2 Edward Thomson <ethomson at edwardthomson.com> 1352096689 -0600	commit: 5alt-1-branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-5alt-2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-5alt-2
new file mode 100755
index 0000000..3ca077b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-5alt-2
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352096711 -0600	branch: Created from c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec ebc09d0137cfb0c26697aed0109fb943ad906f3f Edward Thomson <ethomson at edwardthomson.com> 1352096764 -0600	commit: existing file
+ebc09d0137cfb0c26697aed0109fb943ad906f3f 3b47b031b3e55ae11e14a05260b1c3ffd6838d55 Edward Thomson <ethomson at edwardthomson.com> 1352096815 -0600	commit: 5alt-2
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-5alt-2-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-5alt-2-branch
new file mode 100755
index 0000000..e7bb901
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-5alt-2-branch
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 ebc09d0137cfb0c26697aed0109fb943ad906f3f Edward Thomson <ethomson at edwardthomson.com> 1352096833 -0600	branch: Created from ebc09d0
+ebc09d0137cfb0c26697aed0109fb943ad906f3f f48097eb340dc5a7cae55aabcf1faf4548aa821f Edward Thomson <ethomson at edwardthomson.com> 1352096855 -0600	commit: 5alt-2-branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-6
new file mode 100755
index 0000000..7c717a2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-6
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352097371 -0600	branch: Created from c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec f7c332bd4d4d4b777366cae4d24d1687477576bf Edward Thomson <ethomson at edwardthomson.com> 1352097389 -0600	commit: 6
+f7c332bd4d4d4b777366cae4d24d1687477576bf 99b4f7e4f24470fa06b980bc21f1095c2a9425c0 Edward Thomson <ethomson at edwardthomson.com> 1352097404 -0600	commit: trivial-6
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-6-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-6-branch
new file mode 100755
index 0000000..715f3ae
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-6-branch
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 f7c332bd4d4d4b777366cae4d24d1687477576bf Edward Thomson <ethomson at edwardthomson.com> 1352097414 -0600	branch: Created from f7c332bd4d4d4b777366cae4d24d1687477576bf
+f7c332bd4d4d4b777366cae4d24d1687477576bf a43150a738849c59376cf30bb2a68348a83c8f48 Edward Thomson <ethomson at edwardthomson.com> 1352097431 -0600	commit: 6-branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-7
new file mode 100755
index 0000000..a014f17
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-7
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352099765 -0600	branch: Created from c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec 092ce8682d7f3a2a3a769a6daca58950168ba5c4 Edward Thomson <ethomson at edwardthomson.com> 1352099790 -0600	commit: trivial-7
+092ce8682d7f3a2a3a769a6daca58950168ba5c4 d874671ef5b20184836cb983bb273e5280384d0b Edward Thomson <ethomson at edwardthomson.com> 1352099947 -0600	commit: trivial-7
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-7-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-7-branch
new file mode 100755
index 0000000..22331d7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-7-branch
@@ -0,0 +1,5 @@
+0000000000000000000000000000000000000000 092ce8682d7f3a2a3a769a6daca58950168ba5c4 Edward Thomson <ethomson at edwardthomson.com> 1352099799 -0600	branch: Created from HEAD
+092ce8682d7f3a2a3a769a6daca58950168ba5c4 73cbfdc4fe843169e5b2af8dcad03cbf3acf306c Edward Thomson <ethomson at edwardthomson.com> 1352099812 -0600	commit: trivial-7-branch
+73cbfdc4fe843169e5b2af8dcad03cbf3acf306c 092ce8682d7f3a2a3a769a6daca58950168ba5c4 Edward Thomson <ethomson at edwardthomson.com> 1352099874 -0600	reset: moving to 092ce8682d7f3a2a3a769a6daca58950168ba5c4
+092ce8682d7f3a2a3a769a6daca58950168ba5c4 009b9cab6fdac02915a88ecd078b7a792ed802d8 Edward Thomson <ethomson at edwardthomson.com> 1352099921 -0600	commit: removed in 7
+009b9cab6fdac02915a88ecd078b7a792ed802d8 5195a1b480f66691b667f10a9e41e70115a78351 Edward Thomson <ethomson at edwardthomson.com> 1352099927 -0600	commit (amend): trivial-7-branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-8
new file mode 100755
index 0000000..7670c35
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-8
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352098816 -0600	branch: Created from c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec 75a811bf6bc57694adb3fe604786f3a4efd1cd1b Edward Thomson <ethomson at edwardthomson.com> 1352098884 -0600	commit: trivial-8
+75a811bf6bc57694adb3fe604786f3a4efd1cd1b 3575826c96a975031d2c14368529cc5c4353a8fd Edward Thomson <ethomson at edwardthomson.com> 1352099000 -0600	commit: trivial-8
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-8-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-8-branch
new file mode 100755
index 0000000..c4d68ed
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-8-branch
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 75a811bf6bc57694adb3fe604786f3a4efd1cd1b Edward Thomson <ethomson at edwardthomson.com> 1352098947 -0600	branch: Created from HEAD
+75a811bf6bc57694adb3fe604786f3a4efd1cd1b 52d8bc572af2b6d4ee0d5e62ed5d1fbad92210a9 Edward Thomson <ethomson at edwardthomson.com> 1352098979 -0600	commit: trivial-8-branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-9
new file mode 100755
index 0000000..09a343b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-9
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 c607fc30883e335def28cd686b51f6cfa02b06ec Edward Thomson <ethomson at edwardthomson.com> 1352100268 -0600	branch: Created from c607fc30883e335def28cd686b51f6cfa02b06ec
+c607fc30883e335def28cd686b51f6cfa02b06ec f0053b8060bb3f0be5cbcc3147a07ece26bf097e Edward Thomson <ethomson at edwardthomson.com> 1352100304 -0600	commit: trivial-9
+f0053b8060bb3f0be5cbcc3147a07ece26bf097e c35dee9bcc0e989f3b0c40f68372a9a51b6c4e6a Edward Thomson <ethomson at edwardthomson.com> 1352100333 -0600	commit: trivial-9
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-9-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-9-branch
new file mode 100755
index 0000000..1b126fb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/trivial-9-branch
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 f0053b8060bb3f0be5cbcc3147a07ece26bf097e Edward Thomson <ethomson at edwardthomson.com> 1352100310 -0600	branch: Created from HEAD
+f0053b8060bb3f0be5cbcc3147a07ece26bf097e 13d1be4ea52a6ced1d7a1d832f0ee3c399348e5e Edward Thomson <ethomson at edwardthomson.com> 1352100317 -0600	commit: trivial-9-branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/unrelated b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/unrelated
new file mode 100755
index 0000000..a83ffc2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/logs/refs/heads/unrelated
@@ -0,0 +1 @@
+d6cf6c7741b3316826af1314042550c97ded1d50 55b4e4687e7a0d9ca367016ed930f385d4022e6f Edward Thomson <ethomson at edwardthomson.com> 1358997664 -0600	commit: conflicting changes
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/ORIG_HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/ORIG_HEAD
new file mode 100755
index 0000000..d1bfcf0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/ORIG_HEAD
@@ -0,0 +1 @@
+ae39c77c70cb6bad18bb471912460c4e1ba0f586
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/config
new file mode 100755
index 0000000..575cc85
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/config
@@ -0,0 +1,15 @@
+[core]
+	repositoryformatversion = 0
+	filemode = false
+	bare = false
+	logallrefupdates = true
+	worktree = ../../../submodule
+	symlinks = false
+	ignorecase = true
+	hideDotFiles = dotGitOnly
+[remote "origin"]
+	url = c:/Temp/TestRepos/submodule
+	fetch = +refs/heads/*:refs/remotes/origin/*
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/index
new file mode 100755
index 0000000..e948afb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/18/fae1354bba0a5f1e6a531f9988369142c24a9e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/18/fae1354bba0a5f1e6a531f9988369142c24a9e
new file mode 100755
index 0000000..fcf1c63
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/18/fae1354bba0a5f1e6a531f9988369142c24a9e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/29/7aa6cd028b3336c7802c7a6f49143da4e1602d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/29/7aa6cd028b3336c7802c7a6f49143da4e1602d
new file mode 100755
index 0000000..aa9fc50
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/29/7aa6cd028b3336c7802c7a6f49143da4e1602d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/38/6c80dc813b89d719797668f40c1be0a6efa996 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/38/6c80dc813b89d719797668f40c1be0a6efa996
new file mode 100755
index 0000000..bc9a32e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/38/6c80dc813b89d719797668f40c1be0a6efa996 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/ab/435a147bae6d5906ecfd0916a570c4ab3eeea8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/ab/435a147bae6d5906ecfd0916a570c4ab3eeea8
new file mode 100755
index 0000000..65a8d75
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/ab/435a147bae6d5906ecfd0916a570c4ab3eeea8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/ad/16e0a7684ea95bf892980a2ee412293ae979cc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/ad/16e0a7684ea95bf892980a2ee412293ae979cc
new file mode 100755
index 0000000..49e1aaf
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/ad/16e0a7684ea95bf892980a2ee412293ae979cc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/ae/39c77c70cb6bad18bb471912460c4e1ba0f586 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/ae/39c77c70cb6bad18bb471912460c4e1ba0f586
new file mode 100755
index 0000000..6ceffdd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/ae/39c77c70cb6bad18bb471912460c4e1ba0f586
@@ -0,0 +1,2 @@
+x¥ŽË
!@=S
hfù%Æx±†!ëÅ Æö]kðöò/{k©-âa]
xW«s	=,lÄP…‰
+Šë#g0KÈêIC¶©–ž–,5ù“1¡– ™9;aãlB«è=×>ô­|h}_{{õMŸe·?º¶þêuž¸·‹6˜Àšˆô"€Úí>:叄ʃ6^Õ¤±Kd
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/c2/0765f6e24e8bbb63a648d0d11d84da63170190 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/c2/0765f6e24e8bbb63a648d0d11d84da63170190
new file mode 100755
index 0000000..1478103
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/c2/0765f6e24e8bbb63a648d0d11d84da63170190 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/d3/d806a4bef96889117fd7ebac0e3cb5ec152932 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/d3/d806a4bef96889117fd7ebac0e3cb5ec152932
new file mode 100755
index 0000000..8df72a4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/d3/d806a4bef96889117fd7ebac0e3cb5ec152932
@@ -0,0 +1,3 @@
+x¥A
+Â0E]çse¦mÚDÜx½À$™Ò‚é@šâõgpóø¼ÅQs^+·§ZD€ÃÐ[¦a
+,c²G‰sBO#Û	ãÀ¡v†ºhGúpIðZ4ïºÁUšý­{^cÑ]çz‰šo@½ÇŽ\çÎèM³-\åó<BÖt¼流Ì·ÈA›
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/f1/065ff5593604072837fecaad3e2e268cb0147b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/f1/065ff5593604072837fecaad3e2e268cb0147b
new file mode 100755
index 0000000..e0d73e1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/objects/f1/065ff5593604072837fecaad3e2e268cb0147b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/packed-refs
new file mode 100755
index 0000000..992c4ee
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/packed-refs
@@ -0,0 +1,3 @@
+# pack-refs with: peeled 
+297aa6cd028b3336c7802c7a6f49143da4e1602d refs/remotes/origin/master
+ae39c77c70cb6bad18bb471912460c4e1ba0f586 refs/remotes/origin/submodule-branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/refs/heads/master
new file mode 100755
index 0000000..fe28256
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/refs/heads/master
@@ -0,0 +1 @@
+297aa6cd028b3336c7802c7a6f49143da4e1602d
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..6efe28f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/modules/submodule/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/00/5b6fcc8fec71d2550bef8462d169b3c26aa14b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/00/5b6fcc8fec71d2550bef8462d169b3c26aa14b
new file mode 100755
index 0000000..82a8da5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/00/5b6fcc8fec71d2550bef8462d169b3c26aa14b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/00/9b9cab6fdac02915a88ecd078b7a792ed802d8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/00/9b9cab6fdac02915a88ecd078b7a792ed802d8
new file mode 100755
index 0000000..f663a3c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/00/9b9cab6fdac02915a88ecd078b7a792ed802d8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/00/c7d33f1ffa79d19c2272b370fcaeaadba49c08 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/00/c7d33f1ffa79d19c2272b370fcaeaadba49c08
new file mode 100755
index 0000000..72698dc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/00/c7d33f1ffa79d19c2272b370fcaeaadba49c08 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/01/f149e1b8f84bd8896aaff6d6b22af88459ded0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/01/f149e1b8f84bd8896aaff6d6b22af88459ded0
new file mode 100755
index 0000000..aa6336d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/01/f149e1b8f84bd8896aaff6d6b22af88459ded0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/02/04a84f822acbf6386b36d33f1f6bc68bbbf858 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/02/04a84f822acbf6386b36d33f1f6bc68bbbf858
new file mode 100755
index 0000000..2f0a0e1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/02/04a84f822acbf6386b36d33f1f6bc68bbbf858 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/02/251f990ca8e92e7ae61d3426163fa821c64001 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/02/251f990ca8e92e7ae61d3426163fa821c64001
new file mode 100755
index 0000000..d623117
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/02/251f990ca8e92e7ae61d3426163fa821c64001 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/03/21415405cb906c46869919af56d51dbbe5e85c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/03/21415405cb906c46869919af56d51dbbe5e85c
new file mode 100755
index 0000000..277bdcf
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/03/21415405cb906c46869919af56d51dbbe5e85c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/03/2ebc5ab85d9553bb187d3cd40875ff23a63ed0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/03/2ebc5ab85d9553bb187d3cd40875ff23a63ed0
new file mode 100755
index 0000000..e5404d8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/03/2ebc5ab85d9553bb187d3cd40875ff23a63ed0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/03/b87706555accbf874ccd410dbda01e8e70a67f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/03/b87706555accbf874ccd410dbda01e8e70a67f
new file mode 100755
index 0000000..0befcd7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/03/b87706555accbf874ccd410dbda01e8e70a67f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/03/dad1005e5d06d418f50b12e0bcd48ff2306a03 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/03/dad1005e5d06d418f50b12e0bcd48ff2306a03
new file mode 100755
index 0000000..04011a2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/03/dad1005e5d06d418f50b12e0bcd48ff2306a03 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/05/1ffd7901a442faf56b226161649074f15c7c47 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/05/1ffd7901a442faf56b226161649074f15c7c47
new file mode 100755
index 0000000..65fa689
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/05/1ffd7901a442faf56b226161649074f15c7c47
@@ -0,0 +1 @@
+x+)JMU06·`040031QH,-ÉÏM-JOMLÊIÕ+©(aH:,»:ÎCÉýúô:ÞË	²o>ZC'g$楧¦èfæé&%æ%g€5¬ÎqYôÂeÒZoÇÝÙkÚMíæ2­éÆԐ›X\’ZDPC~^ZNfrIf^:Xéõ›ZHÙŠž1O(_œ,'º×
jvn~JfZ&Ä5†&ȚؽùÁ„	+gÆz¬Ÿ¥•4íú3Ž^¨¦¢ÔÜü2ÜüI{•|þ¹÷	2m»gÜ˾‹©É1ÖËåüŠ5Ó¿Ü,\“µ})TC)0XÀ¡vÿ‰ùzÖ›¦9–¤×Mü°úÕ…'6óbó#—
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/05/8541fc37114bfc1dddf6bd6bffc7fae5c2e6fe b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/05/8541fc37114bfc1dddf6bd6bffc7fae5c2e6fe
new file mode 100755
index 0000000..d79dc30
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/05/8541fc37114bfc1dddf6bd6bffc7fae5c2e6fe differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/05/f3c1a2a56ca95c3d2ef28dc9ddf32b5cd6c91c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/05/f3c1a2a56ca95c3d2ef28dc9ddf32b5cd6c91c
new file mode 100755
index 0000000..7b4b152
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/05/f3c1a2a56ca95c3d2ef28dc9ddf32b5cd6c91c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/07/a759da919f737221791d542f176ab49c88837f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/07/a759da919f737221791d542f176ab49c88837f
new file mode 100755
index 0000000..a34b6c2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/07/a759da919f737221791d542f176ab49c88837f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/07/c514b04698e068892b31c8d352b85813b99c6e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/07/c514b04698e068892b31c8d352b85813b99c6e
new file mode 100755
index 0000000..23ab921
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/07/c514b04698e068892b31c8d352b85813b99c6e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/09/055301463b7f2f8ee5d368f8ed5c0a40ad8515 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/09/055301463b7f2f8ee5d368f8ed5c0a40ad8515
new file mode 100755
index 0000000..bf5b0fc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/09/055301463b7f2f8ee5d368f8ed5c0a40ad8515 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/09/17bb159596aea4d295f4857da77e8f96b3c7dc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/09/17bb159596aea4d295f4857da77e8f96b3c7dc
new file mode 100755
index 0000000..9fb640d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/09/17bb159596aea4d295f4857da77e8f96b3c7dc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/09/2ce8682d7f3a2a3a769a6daca58950168ba5c4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/09/2ce8682d7f3a2a3a769a6daca58950168ba5c4
new file mode 100755
index 0000000..b709cf4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/09/2ce8682d7f3a2a3a769a6daca58950168ba5c4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/09/3bebf072dd4bbba88833667d6ffe454df199e1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/09/3bebf072dd4bbba88833667d6ffe454df199e1
new file mode 100755
index 0000000..ae13207
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/09/3bebf072dd4bbba88833667d6ffe454df199e1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/09/768bed22680cdb0859683fa9677ccc8d5a25c1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/09/768bed22680cdb0859683fa9677ccc8d5a25c1
new file mode 100755
index 0000000..5f4b4da
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/09/768bed22680cdb0859683fa9677ccc8d5a25c1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0a/75d9aac1dc84fb5aa51f7325c0ab53242ddef7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0a/75d9aac1dc84fb5aa51f7325c0ab53242ddef7
new file mode 100755
index 0000000..d537734
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0a/75d9aac1dc84fb5aa51f7325c0ab53242ddef7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0c/fd6c54ef6532d862408f562309dc9c74a401e8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0c/fd6c54ef6532d862408f562309dc9c74a401e8
new file mode 100755
index 0000000..40f628f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0c/fd6c54ef6532d862408f562309dc9c74a401e8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0d/52e3a556e189ba0948ae56780918011c1b167d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0d/52e3a556e189ba0948ae56780918011c1b167d
new file mode 100755
index 0000000..4b633e5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0d/52e3a556e189ba0948ae56780918011c1b167d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0d/872f8e871a30208305978ecbf9e66d864f1638 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0d/872f8e871a30208305978ecbf9e66d864f1638
new file mode 100755
index 0000000..4cbc18e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0d/872f8e871a30208305978ecbf9e66d864f1638 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0e/c5f433959cd46177f745903353efb5be08d151 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0e/c5f433959cd46177f745903353efb5be08d151
new file mode 100755
index 0000000..1bee56c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0e/c5f433959cd46177f745903353efb5be08d151 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0f/3fc5dddc8964b9ac1040d0e957f9eb02d9efb3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0f/3fc5dddc8964b9ac1040d0e957f9eb02d9efb3
new file mode 100755
index 0000000..d0ca42d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/0f/3fc5dddc8964b9ac1040d0e957f9eb02d9efb3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/11/aeee27ac45a8402c2fd5b875d66dd844e5df00 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/11/aeee27ac45a8402c2fd5b875d66dd844e5df00
new file mode 100755
index 0000000..90e729f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/11/aeee27ac45a8402c2fd5b875d66dd844e5df00 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/11/deab00b2d3a6f5a3073988ac050c2d7b6655e2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/11/deab00b2d3a6f5a3073988ac050c2d7b6655e2
new file mode 100755
index 0000000..857b236
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/11/deab00b2d3a6f5a3073988ac050c2d7b6655e2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/11/f4f3c08b737f5fd896cbefa1425ee63b21b2fa b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/11/f4f3c08b737f5fd896cbefa1425ee63b21b2fa
new file mode 100755
index 0000000..6555194
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/11/f4f3c08b737f5fd896cbefa1425ee63b21b2fa
@@ -0,0 +1 @@
+x¥ŽQ Dýæ\ fw)cüñ^`Û´‰-Q¯/oàßÌ›Ìdb^×¥j²´«EDC²$†­u‚>Œ¡÷,Ö
z@Œ8¢’ºq‘­jk<Ù©GŽ>¹Òz2Lva2)¸Veŏ:ç¢ÏéÅ%éËœ×{ÞôAý¨“|ƒŸÛǼ5K@ˆº mg«ü9£jYž_;„n,¼ÅY½y²P”
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/13/d1be4ea52a6ced1d7a1d832f0ee3c399348e5e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/13/d1be4ea52a6ced1d7a1d832f0ee3c399348e5e
new file mode 100755
index 0000000..4e4e175
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/13/d1be4ea52a6ced1d7a1d832f0ee3c399348e5e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/14/39088f509b79b1535b64193137d3ce4b240734 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/14/39088f509b79b1535b64193137d3ce4b240734
new file mode 100755
index 0000000..51ddf6d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/14/39088f509b79b1535b64193137d3ce4b240734 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/15/8dc7bedb202f5b26502bf3574faa7f4238d56c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/15/8dc7bedb202f5b26502bf3574faa7f4238d56c
new file mode 100755
index 0000000..064423d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/15/8dc7bedb202f5b26502bf3574faa7f4238d56c
@@ -0,0 +1,2 @@
+x¥ŽK!D]sŠ¾€¦ùCbŒoà i2.b¼¾£ñîªÞK*E½µÛep73UƒÓ¾*NYYôI²Ô”)–j¼ŠL:8§<‹{¼NˆÞ“‹ÎÊH6iDC¶Ê"mqH!–Ì9T¥mé9—>àR^i¸.½=ú
+GÞè'ù+~í@½@j+ƒ7ÑØ£EÝÎNþsFtš]‰7bN)
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/16/f825815cfd20a07a75c71554e82d8eede0b061 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/16/f825815cfd20a07a75c71554e82d8eede0b061
new file mode 100755
index 0000000..82d6525
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/16/f825815cfd20a07a75c71554e82d8eede0b061
@@ -0,0 +1 @@
+x¥ŽK!D]sŠ¾€†šObŒoࠁŒƒ¯ïh¼»ª÷’Jqoí6A¹›£°JÙ€ˆ¬“T1h¢3§£·Î'LÕ ó.‰{eœc,a`ŠZJÃT1#e+Ù‡œJòUiª">çÒ\ò+Ž×¥·G_áX6úIçò¿vàÞN€šÐ;ÈÀ^’”b£ÛÙYþœgGñ—MMµ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/17/8940b450f238a56c0d75b7955cb57b38191982 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/17/8940b450f238a56c0d75b7955cb57b38191982
new file mode 100755
index 0000000..94e571e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/17/8940b450f238a56c0d75b7955cb57b38191982 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/18/3310e30fb1499af8c619108ffea4d300b5e778 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/18/3310e30fb1499af8c619108ffea4d300b5e778
new file mode 100755
index 0000000..1c4010d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/18/3310e30fb1499af8c619108ffea4d300b5e778 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/18/cb316b1cefa0f8a6946f0e201a8e1a6f845ab9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/18/cb316b1cefa0f8a6946f0e201a8e1a6f845ab9
new file mode 100755
index 0000000..30f3110
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/18/cb316b1cefa0f8a6946f0e201a8e1a6f845ab9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/19/b7ac485269b672a101060894de3ba9c2a24dd1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/19/b7ac485269b672a101060894de3ba9c2a24dd1
new file mode 100755
index 0000000..e34ccb8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/19/b7ac485269b672a101060894de3ba9c2a24dd1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/1a/010b1c0f081b2e8901d55307a15c29ff30af0e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/1a/010b1c0f081b2e8901d55307a15c29ff30af0e
new file mode 100755
index 0000000..6039df0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/1a/010b1c0f081b2e8901d55307a15c29ff30af0e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/1c/51d885170f57a0c4e8c69ff6363d91a5b51f85 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/1c/51d885170f57a0c4e8c69ff6363d91a5b51f85
new file mode 100755
index 0000000..9a21e26
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/1c/51d885170f57a0c4e8c69ff6363d91a5b51f85 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/1c/ff9ec6a47a537380dedfdd17c9e76d74259a2b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/1c/ff9ec6a47a537380dedfdd17c9e76d74259a2b
new file mode 100755
index 0000000..30802bc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/1c/ff9ec6a47a537380dedfdd17c9e76d74259a2b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/1e/4ff029aee68d0d69ef9eb6efa6cbf1ec732f99 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/1e/4ff029aee68d0d69ef9eb6efa6cbf1ec732f99
new file mode 100755
index 0000000..5183b83
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/1e/4ff029aee68d0d69ef9eb6efa6cbf1ec732f99 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/1f/81433e3161efbf250576c58fede7f6b836f3d3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/1f/81433e3161efbf250576c58fede7f6b836f3d3
new file mode 100755
index 0000000..9708556
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/1f/81433e3161efbf250576c58fede7f6b836f3d3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/20/91d94c8bd3eb0835dc5220de5e8bb310fa1513 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/20/91d94c8bd3eb0835dc5220de5e8bb310fa1513
new file mode 100755
index 0000000..a843890
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/20/91d94c8bd3eb0835dc5220de5e8bb310fa1513 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/21/671e290278286fb2ce4c63d01699b67adce331 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/21/671e290278286fb2ce4c63d01699b67adce331
new file mode 100755
index 0000000..b656d00
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/21/671e290278286fb2ce4c63d01699b67adce331 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/22/7792b52aaa0b238bea00ec7e509b02623f168c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/22/7792b52aaa0b238bea00ec7e509b02623f168c
new file mode 100755
index 0000000..3bb19bb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/22/7792b52aaa0b238bea00ec7e509b02623f168c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/23/3c0919c998ed110a4b6ff36f353aec8b713487 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/23/3c0919c998ed110a4b6ff36f353aec8b713487
new file mode 100755
index 0000000..d0c8c9e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/23/3c0919c998ed110a4b6ff36f353aec8b713487 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/23/92a2dacc9efb562b8635d6579fb458751c7c5b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/23/92a2dacc9efb562b8635d6579fb458751c7c5b
new file mode 100755
index 0000000..86127a3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/23/92a2dacc9efb562b8635d6579fb458751c7c5b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/23/ed141a6ae1e798b2f721afedbe947c119111ba b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/23/ed141a6ae1e798b2f721afedbe947c119111ba
new file mode 100755
index 0000000..06dee3b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/23/ed141a6ae1e798b2f721afedbe947c119111ba differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/24/1a1005cd9b980732741b74385b891142bcba28 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/24/1a1005cd9b980732741b74385b891142bcba28
new file mode 100755
index 0000000..9b65f66
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/24/1a1005cd9b980732741b74385b891142bcba28 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/24/2591eb280ee9eeb2ce63524b9a8b9bc4cb515d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/24/2591eb280ee9eeb2ce63524b9a8b9bc4cb515d
new file mode 100755
index 0000000..74a0137
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/24/2591eb280ee9eeb2ce63524b9a8b9bc4cb515d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/24/90b9f1a079420870027deefb49f51d6656cf74 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/24/90b9f1a079420870027deefb49f51d6656cf74
new file mode 100755
index 0000000..60497ca
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/24/90b9f1a079420870027deefb49f51d6656cf74 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/25/9d08ca43af9200e9ea9a098e44a5a350ebd9b3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/25/9d08ca43af9200e9ea9a098e44a5a350ebd9b3
new file mode 100755
index 0000000..2bae669
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/25/9d08ca43af9200e9ea9a098e44a5a350ebd9b3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/25/c40b7660c08c8fb581f770312f41b9b03119d1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/25/c40b7660c08c8fb581f770312f41b9b03119d1
new file mode 100755
index 0000000..1852147
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/25/c40b7660c08c8fb581f770312f41b9b03119d1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/26/153a3ff3649b6c2bb652d3f06878c6e0a172f9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/26/153a3ff3649b6c2bb652d3f06878c6e0a172f9
new file mode 100755
index 0000000..4fcaa07
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/26/153a3ff3649b6c2bb652d3f06878c6e0a172f9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/27/133da702ba3c60af2a01e96c2555ff4045d692 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/27/133da702ba3c60af2a01e96c2555ff4045d692
new file mode 100755
index 0000000..08e61f8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/27/133da702ba3c60af2a01e96c2555ff4045d692 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/27/4bbe983022fb4c02f8a2bf2ebe8da4fe130054 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/27/4bbe983022fb4c02f8a2bf2ebe8da4fe130054
new file mode 100755
index 0000000..c7afad2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/27/4bbe983022fb4c02f8a2bf2ebe8da4fe130054 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2b/0de5dc27505dcdd83a75c8bf1fcd9462cd7add b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2b/0de5dc27505dcdd83a75c8bf1fcd9462cd7add
new file mode 100755
index 0000000..a95f926
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2b/0de5dc27505dcdd83a75c8bf1fcd9462cd7add differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2b/5f1f181ee3b58ea751f5dd5d8f9b445520a136 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2b/5f1f181ee3b58ea751f5dd5d8f9b445520a136
new file mode 100755
index 0000000..d24231e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2b/5f1f181ee3b58ea751f5dd5d8f9b445520a136 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2b/d0a343aeef7a2cf0d158478966a6e587ff3863 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2b/d0a343aeef7a2cf0d158478966a6e587ff3863
new file mode 100755
index 0000000..d10ca63
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2b/d0a343aeef7a2cf0d158478966a6e587ff3863 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2b/fdd7e1b6c6ae993f23dfe8e84a8e06a772fa2a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2b/fdd7e1b6c6ae993f23dfe8e84a8e06a772fa2a
new file mode 100755
index 0000000..c86edfb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2b/fdd7e1b6c6ae993f23dfe8e84a8e06a772fa2a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2d/a538570bc1e5b2c3e855bf702f35248ad0735f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2d/a538570bc1e5b2c3e855bf702f35248ad0735f
new file mode 100755
index 0000000..83253f8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2d/a538570bc1e5b2c3e855bf702f35248ad0735f
@@ -0,0 +1,2 @@
+x¥ŽK
+1D]ç¹€ÒùN"n¼{ét:Œ‹L$ñúŽâ
ÜU½EQ«õ>¤¶~7:³L
ðÙD[´±5—¬É‡,Øy2e®ÐTت@”¦z*.û(ë´Àç˜[——üžåunum‹<òF?éÌ_ñkjõ$•qNå'#÷àÄF·³ƒÿœ¹Üp!^Gëâ
9+Q.
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2f/2e37b7ebbae467978610896ca3aafcdad2ee67 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2f/2e37b7ebbae467978610896ca3aafcdad2ee67
new file mode 100755
index 0000000..7adffb1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2f/2e37b7ebbae467978610896ca3aafcdad2ee67 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2f/4024ce528d36d8670c289cce5a7963e625bb0c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2f/4024ce528d36d8670c289cce5a7963e625bb0c
new file mode 100755
index 0000000..0100fd7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2f/4024ce528d36d8670c289cce5a7963e625bb0c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2f/56120107d680129a5d9791b521cb1e73a2ed31 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2f/56120107d680129a5d9791b521cb1e73a2ed31
new file mode 100755
index 0000000..1f5f597
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2f/56120107d680129a5d9791b521cb1e73a2ed31
@@ -0,0 +1,3 @@
+xí[
+Â@EýžUdR臸žy¤öBÌ”LJ·oÔnBð/pî#Ü"½Ðí>_|Å Ât@„
+“ñapg%hò•aãJYÁÕ®Aâ8Õ©í› fçà²ûN©ì¦¯4À;œ”h[º%cÍO¦ÆÎÕÑuJÑ÷çWÖyΏ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2f/598248eeccfc27e5ca44d9d96383f6dfea7b16 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2f/598248eeccfc27e5ca44d9d96383f6dfea7b16
new file mode 100755
index 0000000..1d9f226
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/2f/598248eeccfc27e5ca44d9d96383f6dfea7b16
@@ -0,0 +1 @@
+x+)JMU067c040031QH,-ÉÏM-JOMLÊIÕ+©(aH:,»:ÎCÉýúô:ÞË	²o>ZC'g$楧¦èfæé&%æ%g€5¬ÎqYôÂeÒZoÇÝÙkÚMíæ2­éÆԐ›X\’ZDPC~^ZNfrIf^:Xéõ›ZHÙŠž1O(_œ,'º×
jvQjn~Ä1–ÈÎÑ×3ßþzדôém9‹Wý¹ué]:¦$÷ßüI{•|þ¹÷	2m»gÜ˾‹©Éý1ÖËåüŠ5Ó¿Ü,\“µ})TC)0PÀavý‰ùzÖ›¦9–¤×Mü°úÕ…'6óbˆ—¢
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/31/68dca1a561889b045a6441909f4c56145e666d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/31/68dca1a561889b045a6441909f4c56145e666d
new file mode 100755
index 0000000..2de1c5a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/31/68dca1a561889b045a6441909f4c56145e666d
@@ -0,0 +1,2 @@
+x¥ŽQ
+Â0DýÎ)rJ²›MñÇxM²¥ÛHŒz}«xÿfÞƒaRY–¹ip´kUD$Ï1f¢Q2qê-Ó=Y£ëÁ3R7®²6äÄ¡·Œgàâ9e7 bæ¡w	‚âG›JÕçüâšõe*˽¬ú ý¤“|ůíSYŽÚ"5&Нñƨng›ü9£ZŸ3_;kÕ¬dO¼
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/31/d5472536041a83d986829240bbbdc897c6f8a6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/31/d5472536041a83d986829240bbbdc897c6f8a6
new file mode 100755
index 0000000..5ec5acb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/31/d5472536041a83d986829240bbbdc897c6f8a6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/32/21dd512b7e2dc4b5bd03046df6c81b2ab2070b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/32/21dd512b7e2dc4b5bd03046df6c81b2ab2070b
new file mode 100755
index 0000000..d36138d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/32/21dd512b7e2dc4b5bd03046df6c81b2ab2070b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/33/46d64325b39e5323733492cd55f808994a2475 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/33/46d64325b39e5323733492cd55f808994a2475
new file mode 100755
index 0000000..11546ce
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/33/46d64325b39e5323733492cd55f808994a2475 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/33/d500f588fbbe65901d82b4e6b008e549064be0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/33/d500f588fbbe65901d82b4e6b008e549064be0
new file mode 100755
index 0000000..061a031
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/33/d500f588fbbe65901d82b4e6b008e549064be0
@@ -0,0 +1,2 @@
+x¥ŽA E]s
+. hbŒoত.ZÅx}[ã
Üýÿ~òó¤Îó£këü¡·œµCAŒž<:km`d”„Ì‘d,!:𦐳¤žÜòÒõ‚øÁ“„œP1ÉPò qHcc±HEñ«Oµé[zsKú>Õy­‹>çî隿ÎmŒŠú 6ºÉöüç*¼öRÛn¢>úåOÇ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/34/8dcd41e2b467991578e92bedd16971b877ef1e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/34/8dcd41e2b467991578e92bedd16971b877ef1e
new file mode 100755
index 0000000..fd61b6c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/34/8dcd41e2b467991578e92bedd16971b877ef1e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/34/bfafff88eaf118402b44e6f3e2dbbf1a582b05 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/34/bfafff88eaf118402b44e6f3e2dbbf1a582b05
new file mode 100755
index 0000000..c653cec
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/34/bfafff88eaf118402b44e6f3e2dbbf1a582b05
@@ -0,0 +1 @@
+x•ŽKj1D½Ö)ú	úµ>`Œ7¾A. µ$<`MŒ¯orlŠ¢ ¸÷m‚¶þ4G­›·&údVdƒ[j2ÖµËJÉâ›C«ÑŠgu_GuÒ%ÅÚ2:ƒ3XúزÅàQ‘'Ì"½æÜÊ;?wîïp®kým×¾ÑàƒÛü&îPf!¢	ð%QJ±Ö%:ëûCˆeœzâ½=6šÀ¯qˆ;iOè
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/35/0c6eb3010efc403a6bed682332635314e9ed58 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/35/0c6eb3010efc403a6bed682332635314e9ed58
new file mode 100755
index 0000000..2eee602
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/35/0c6eb3010efc403a6bed682332635314e9ed58 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/35/411bfb77cd2cc431f3a03a2b4976ed94b5d241 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/35/411bfb77cd2cc431f3a03a2b4976ed94b5d241
new file mode 100755
index 0000000..ea024cc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/35/411bfb77cd2cc431f3a03a2b4976ed94b5d241 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/35/4704d3613ad4228e4786fc76656b11e98236c4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/35/4704d3613ad4228e4786fc76656b11e98236c4
new file mode 100755
index 0000000..1dd13c4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/35/4704d3613ad4228e4786fc76656b11e98236c4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/35/632e43612c06a3ea924bfbacd48333da874c29 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/35/632e43612c06a3ea924bfbacd48333da874c29
new file mode 100755
index 0000000..be7684f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/35/632e43612c06a3ea924bfbacd48333da874c29
@@ -0,0 +1 @@
+x¥NË
!õLÓÀšd–MŒñb60ÀÝă¨í‹Æ¼½^,ëº40;·iUFf+)›³ˆ1vòBÁ939fG–(ôDIݸʵA$s´è½k]’l|Lä{IgŠ™Ñ$‰Šm.NéÅ5Áy.ë½\a/]ý £|ÛƲ@[g4âä<Hˆª«ýl“?gT«ËsáË µzCøP˜
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/35/75826c96a975031d2c14368529cc5c4353a8fd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/35/75826c96a975031d2c14368529cc5c4353a8fd
new file mode 100755
index 0000000..24e33bc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/35/75826c96a975031d2c14368529cc5c4353a8fd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/36/219b49367146cb2e6a1555b5a9ebd4d0328495 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/36/219b49367146cb2e6a1555b5a9ebd4d0328495
new file mode 100755
index 0000000..7f80443
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/36/219b49367146cb2e6a1555b5a9ebd4d0328495 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/36/4bbe4ce80c7bd31e6307dce77d46e3e1759fb3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/36/4bbe4ce80c7bd31e6307dce77d46e3e1759fb3
new file mode 100755
index 0000000..90fd965
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/36/4bbe4ce80c7bd31e6307dce77d46e3e1759fb3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/37/48859b001c6e627e712a07951aee40afd19b41 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/37/48859b001c6e627e712a07951aee40afd19b41
new file mode 100755
index 0000000..6a0c389
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/37/48859b001c6e627e712a07951aee40afd19b41 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/38/5c8a0f26ddf79e9041e15e17dc352ed2c4cced b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/38/5c8a0f26ddf79e9041e15e17dc352ed2c4cced
new file mode 100755
index 0000000..e95ff3a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/38/5c8a0f26ddf79e9041e15e17dc352ed2c4cced
@@ -0,0 +1,2 @@
+x-MK
+1uS¼YÍRÄ…ñ™6C±…6Ò뛪ð¼okn÷ÇåYt àEpª	iÅDûØCd§Éœ³dLõB+8ø%¨q‚±ƒkµÿú+Þe™Þ6¢ï‡©fHüBü·¯1J©ÕÓ4ùFà1l
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/3b/47b031b3e55ae11e14a05260b1c3ffd6838d55 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/3b/47b031b3e55ae11e14a05260b1c3ffd6838d55
new file mode 100755
index 0000000..8208646
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/3b/47b031b3e55ae11e14a05260b1c3ffd6838d55 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/3b/bf0bf59b20df5d5fc58b9fc1dc07be637c301f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/3b/bf0bf59b20df5d5fc58b9fc1dc07be637c301f
new file mode 100755
index 0000000..723a9ae
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/3b/bf0bf59b20df5d5fc58b9fc1dc07be637c301f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/3e/f4d30382ca33fdeba9fda895a99e0891ba37aa b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/3e/f4d30382ca33fdeba9fda895a99e0891ba37aa
new file mode 100755
index 0000000..49ee152
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/3e/f4d30382ca33fdeba9fda895a99e0891ba37aa differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/3e/f9bfe82f9635518ae89152322f3b46fd4ba25b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/3e/f9bfe82f9635518ae89152322f3b46fd4ba25b
new file mode 100755
index 0000000..3b5998c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/3e/f9bfe82f9635518ae89152322f3b46fd4ba25b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/40/2784a46a4a3982294231594cbeb431f506d22c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/40/2784a46a4a3982294231594cbeb431f506d22c
new file mode 100755
index 0000000..a17e05d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/40/2784a46a4a3982294231594cbeb431f506d22c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/41/2b32fb66137366147f1801ecc962452757d48a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/41/2b32fb66137366147f1801ecc962452757d48a
new file mode 100755
index 0000000..b183dd7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/41/2b32fb66137366147f1801ecc962452757d48a
@@ -0,0 +1,2 @@
+x¥ŽK
+1D]ç¹€ÒIO>"n¼èt:Œ‹™‰x}£xwU¯ xÜj½um'»ë«ˆ.®Ì9»=y6Ø$@T8ÌÀ‰&Lhf4êA«Ü»f¡0BŒ(ˆ.K±‘³>9S<›À+zö¥­ú’_´f}]ZÝÚ]eÐO:Ëwøµ·zÒš†‹ÞƒPƒÙ.Þ¨aNU6õÎOÖ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/42/18670ab81cc219a9f94befb5c5dad90ec52648 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/42/18670ab81cc219a9f94befb5c5dad90ec52648
new file mode 100755
index 0000000..33ead61
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/42/18670ab81cc219a9f94befb5c5dad90ec52648 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/43/aafd43bea779ec74317dc361f45ae3f532a505 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/43/aafd43bea779ec74317dc361f45ae3f532a505
new file mode 100755
index 0000000..ac86823
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/43/aafd43bea779ec74317dc361f45ae3f532a505 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/43/c338656342227a3a3cd3aa85cbf784061f5425 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/43/c338656342227a3a3cd3aa85cbf784061f5425
new file mode 100755
index 0000000..d977311
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/43/c338656342227a3a3cd3aa85cbf784061f5425 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/45/299c1ca5e07bba1fd90843056fb559f96b1f5a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/45/299c1ca5e07bba1fd90843056fb559f96b1f5a
new file mode 100755
index 0000000..2093b44
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/45/299c1ca5e07bba1fd90843056fb559f96b1f5a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/46/6daf8552b891e5c22bc58c9d7fc1a2eb8f0289 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/46/6daf8552b891e5c22bc58c9d7fc1a2eb8f0289
new file mode 100755
index 0000000..c39b53a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/46/6daf8552b891e5c22bc58c9d7fc1a2eb8f0289 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/47/6dbb3e207313d1d8aaa120c6ad204bf1295e53 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/47/6dbb3e207313d1d8aaa120c6ad204bf1295e53
new file mode 100755
index 0000000..3e5f66e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/47/6dbb3e207313d1d8aaa120c6ad204bf1295e53 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/47/8172cb2f5ff9b514bc9d04d3bd5ef5840cb3b2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/47/8172cb2f5ff9b514bc9d04d3bd5ef5840cb3b2
new file mode 100755
index 0000000..d9e250e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/47/8172cb2f5ff9b514bc9d04d3bd5ef5840cb3b2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/49/130a28ef567af9a6a6104c38773fedfa5f9742 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/49/130a28ef567af9a6a6104c38773fedfa5f9742
new file mode 100755
index 0000000..e2c49f5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/49/130a28ef567af9a6a6104c38773fedfa5f9742 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/49/9df817155e4bdd3c6ee192a72c52f481818230 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/49/9df817155e4bdd3c6ee192a72c52f481818230
new file mode 100755
index 0000000..9c7e471
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/49/9df817155e4bdd3c6ee192a72c52f481818230 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/49/fd9edac79d15c8fbfca2d481cbb900beba22a6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/49/fd9edac79d15c8fbfca2d481cbb900beba22a6
new file mode 100755
index 0000000..d808d9f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/49/fd9edac79d15c8fbfca2d481cbb900beba22a6
@@ -0,0 +1,3 @@
+xUÁ
+Â0D=ç+æ¼èÅ
+‚…þÆf»5dIŽ~¼ÑEhße3Ìó©xœ¯—ÓÍÀ2?ž®‡Ø°Å$Ɂô%+¢"SëRAºÂWRîm Kýn¸ä\tXZ/µŸhôº¥ÈÝMƱߙìþg2©»ñj>#
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4a/9550ebcc97ce22b22f45af7b829bb030d003f5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4a/9550ebcc97ce22b22f45af7b829bb030d003f5
new file mode 100755
index 0000000..6ec674a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4a/9550ebcc97ce22b22f45af7b829bb030d003f5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4b/253da36a0ae8bfce63aeabd8c5b58429925594 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4b/253da36a0ae8bfce63aeabd8c5b58429925594
new file mode 100755
index 0000000..1a40727
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4b/253da36a0ae8bfce63aeabd8c5b58429925594
@@ -0,0 +1,2 @@
+x
ÅA
+€0@ÏûŠ¾AðAILm l¡¦ÿ×¹ŒæÔvGxÑ#ÿ6Ù3¬‚tWBØ6—§”ßÐ%´h”
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4b/48deed3a433909bfd6b6ab3d4b91348b6af464 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4b/48deed3a433909bfd6b6ab3d4b91348b6af464
new file mode 100755
index 0000000..328c850
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4b/48deed3a433909bfd6b6ab3d4b91348b6af464 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904
new file mode 100755
index 0000000..adf6411
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4c/9fac0707f8d4195037ae5a681aa48626491541 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4c/9fac0707f8d4195037ae5a681aa48626491541
new file mode 100755
index 0000000..6b8c85e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4c/9fac0707f8d4195037ae5a681aa48626491541 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4c/a408a8c88655f7586a1b580be6fad138121e98 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4c/a408a8c88655f7586a1b580be6fad138121e98
new file mode 100755
index 0000000..15cb7f2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4c/a408a8c88655f7586a1b580be6fad138121e98 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4e/0d9401aee78eb345a8685a859d37c8c3c0bbed b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4e/0d9401aee78eb345a8685a859d37c8c3c0bbed
new file mode 100755
index 0000000..57f7eb6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4e/0d9401aee78eb345a8685a859d37c8c3c0bbed differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4e/886e602529caa9ab11d71f86634bd1b6e0de10 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4e/886e602529caa9ab11d71f86634bd1b6e0de10
new file mode 100755
index 0000000..53168a0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4e/886e602529caa9ab11d71f86634bd1b6e0de10 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4e/b04c9e79e88f6640d01ff5b25ca2a60764f216 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4e/b04c9e79e88f6640d01ff5b25ca2a60764f216
new file mode 100755
index 0000000..f4ec0ef
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4e/b04c9e79e88f6640d01ff5b25ca2a60764f216 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4f/e93c0ec83eb6305cbace3dace88ecee1b63cb6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4f/e93c0ec83eb6305cbace3dace88ecee1b63cb6
new file mode 100755
index 0000000..67dc684
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/4f/e93c0ec83eb6305cbace3dace88ecee1b63cb6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/50/12fd565b1393bdfda1805d4ec38ce6619e1fd1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/50/12fd565b1393bdfda1805d4ec38ce6619e1fd1
new file mode 100755
index 0000000..d629a23
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/50/12fd565b1393bdfda1805d4ec38ce6619e1fd1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/50/4f75ac95a71ef98051817618576a68505b92f9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/50/4f75ac95a71ef98051817618576a68505b92f9
new file mode 100755
index 0000000..1b24c72
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/50/4f75ac95a71ef98051817618576a68505b92f9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/50/84fc2a88b6bdba8db93bd3953a8f4fdb470238 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/50/84fc2a88b6bdba8db93bd3953a8f4fdb470238
new file mode 100755
index 0000000..84c9987
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/50/84fc2a88b6bdba8db93bd3953a8f4fdb470238 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/50/ce7d7d01217679e26c55939eef119e0c93e272 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/50/ce7d7d01217679e26c55939eef119e0c93e272
new file mode 100755
index 0000000..e2f9f67
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/50/ce7d7d01217679e26c55939eef119e0c93e272 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/51/95a1b480f66691b667f10a9e41e70115a78351 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/51/95a1b480f66691b667f10a9e41e70115a78351
new file mode 100755
index 0000000..088ee54
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/51/95a1b480f66691b667f10a9e41e70115a78351 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/52/d8bc572af2b6d4ee0d5e62ed5d1fbad92210a9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/52/d8bc572af2b6d4ee0d5e62ed5d1fbad92210a9
new file mode 100755
index 0000000..6522209
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/52/d8bc572af2b6d4ee0d5e62ed5d1fbad92210a9
@@ -0,0 +1,3 @@
+x¥Ž]
+Â0„}Î)rÊnóÓD|ñ^`“ÝЂm$F½¾U¼o3ßä²,sÓ½Ã]«"#€ÇàÙbÈ"ö1±
9÷<Q7ª²6=8
+ˆ1û˜ÜàGKMv>²’cTôhS©úÌ/ª¬/SYîeÕÙè'ä+~mŸÊrÔh\c‡QwàÔF·³MþœQ­ÎÏ™®]èb¥5Mê
¨ÚRŸ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/53/825f41ac8d640612f9423a2f03a69f3d96809a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/53/825f41ac8d640612f9423a2f03a69f3d96809a
new file mode 100755
index 0000000..08cb0b6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/53/825f41ac8d640612f9423a2f03a69f3d96809a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/54/269b3f6ec3d7d4ede24dd350dd5d605495c3ae b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/54/269b3f6ec3d7d4ede24dd350dd5d605495c3ae
new file mode 100755
index 0000000..4a24153
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/54/269b3f6ec3d7d4ede24dd350dd5d605495c3ae
@@ -0,0 +1,2 @@
+x¥ŽK
+1D]ç¹€ÒI¦ó7ÞÀLºÓŒ‹L$F¼¾£xwUïAQÔj½
m'؍^Šv9dÁ”-° £Æœ„„\¼äÀˆºÏ½¬C§È'&Î`"ÃÙÅĹä(Ö¡¨ù9–Öõ…_sg}]Z}´UËF?é\¾â×ÔêI‡&ëô@mt;;ÊŸ3ªÑh“z“ÎNÀ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/54/59c89aa0026d543ce8343bd89871bce543f9c2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/54/59c89aa0026d543ce8343bd89871bce543f9c2
new file mode 100755
index 0000000..178b833
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/54/59c89aa0026d543ce8343bd89871bce543f9c2
@@ -0,0 +1,3 @@
+x¥ŽÑ
!Dý¦
+Ð,,,ãØÀ,9OblßÓ؁3ï%“ÉmY.C[L›ÑEtd–`\
%aBH%TƒvB G%QphÐqªêÎ]nCg‚P3BŒ(ˆ¾Hµ1Š4yS)W;IVüsëúT^Ü‹>Ïmy´›ÞËJ?é(_ñk»Ü–ƒ6è-$ç#è-€ZézvÈŸ3
+ù:ÔNqMB
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/54/7607c690372fe81fab8e3bb44c530e129118fd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/54/7607c690372fe81fab8e3bb44c530e129118fd
new file mode 100755
index 0000000..dccd220
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/54/7607c690372fe81fab8e3bb44c530e129118fd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/55/b4e4687e7a0d9ca367016ed930f385d4022e6f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/55/b4e4687e7a0d9ca367016ed930f385d4022e6f
new file mode 100755
index 0000000..fb157a2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/55/b4e4687e7a0d9ca367016ed930f385d4022e6f
@@ -0,0 +1 @@
+x¥ŽQjÃ0DûíSìZv¥ÕJ‚ú“ä²´Š
µ•\¿Né
ú7ó“û¶­Œã·±«‚Ôd-{á¹LìXçÀÖ'ÅŒ
ÊçéžvmŠä*Ù{¦ÙZ’`$U²ÄÈÆ9ÌÑ-TNé{,}‡Ky¦½ÀuéÛ£78éA_éS‡¿ö‘ûv².ÄèEÞQ§ƒg‡þSsxZýZóXÛ
ò’ÚMÓNRi
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/56/6ab53c220a2eafc1212af1a024513230280ab9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/56/6ab53c220a2eafc1212af1a024513230280ab9
new file mode 100755
index 0000000..a8855ae
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/56/6ab53c220a2eafc1212af1a024513230280ab9
@@ -0,0 +1,3 @@
+x¥ŽÑ
!Dý¦
+Ð,˱‰1þ؁
,°äLDblßÓ؁3ï%“I­ÖËÐhÃft
Ù¡XvŽÄøÂäYÍ‚ñ`L2ÑМ՝»Ü†NsI¼·b­ËRЧLž¢3…RaÀ$Iñs,­ëS~qÏú¼´úh7½—•~ÒQ¾â×v©Õƒ6Ö!œê-€ZézvÈŸ3
+ù:Ô9âM&
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/56/a638b76b75e068590ac999c2f8621e7f3e264c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/56/a638b76b75e068590ac999c2f8621e7f3e264c
new file mode 100755
index 0000000..36289bf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/56/a638b76b75e068590ac999c2f8621e7f3e264c
@@ -0,0 +1 @@
+x¥ŽAj!E³öu	vuW©B6sƒ¹€–%ÝÛÁ6äúqΐÝçÁ<iµpo£«BNŒ¼D'LâJfç	­„”¸ lŽ<Æ4“yÆ®ç<–Íâ&JèóÊÙ³³‚>È$Ñ^•‘R²bâÏØ[‡{þ=Ãcoõj'|褯õUéíje¼K«Ÿ°¬Ln¡•n–¬5“ÎСÿP˜Y«‚´³|2`ìzôËü—zQ{
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/57/079a46233ae2b6df62e9ade71c4948512abefb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/57/079a46233ae2b6df62e9ade71c4948512abefb
new file mode 100755
index 0000000..c7eabc4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/57/079a46233ae2b6df62e9ade71c4948512abefb differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/58/43febcb23480df0b5edb22a21c59c772bb8e29 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/58/43febcb23480df0b5edb22a21c59c772bb8e29
new file mode 100755
index 0000000..f6b2a2b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/58/43febcb23480df0b5edb22a21c59c772bb8e29 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/58/87a5e516c53bd58efb0f02ec6aa031b6fe9ad7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/58/87a5e516c53bd58efb0f02ec6aa031b6fe9ad7
new file mode 100755
index 0000000..550d288
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/58/87a5e516c53bd58efb0f02ec6aa031b6fe9ad7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/58/e853f66699fd02629fd50bde08082bc005933a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/58/e853f66699fd02629fd50bde08082bc005933a
new file mode 100755
index 0000000..cf6db63
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/58/e853f66699fd02629fd50bde08082bc005933a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/59/6803b523203a4851c824c07366906f8353f4ad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/59/6803b523203a4851c824c07366906f8353f4ad
new file mode 100755
index 0000000..cbc8cbe
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/59/6803b523203a4851c824c07366906f8353f4ad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5c/2411f8075f48a6b2fdb85ebc0d371747c4df15 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5c/2411f8075f48a6b2fdb85ebc0d371747c4df15
new file mode 100755
index 0000000..7b41413
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5c/2411f8075f48a6b2fdb85ebc0d371747c4df15 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5c/341ead2ba6f2af98ce5ec3fe84f6b6d2899c0d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5c/341ead2ba6f2af98ce5ec3fe84f6b6d2899c0d
new file mode 100755
index 0000000..63c86bd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5c/341ead2ba6f2af98ce5ec3fe84f6b6d2899c0d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5c/3b68a71fc4fa5d362fd3875e53137c6a5ab7a5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5c/3b68a71fc4fa5d362fd3875e53137c6a5ab7a5
new file mode 100755
index 0000000..5410014
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5c/3b68a71fc4fa5d362fd3875e53137c6a5ab7a5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5d/c1018e90b19654bee986b7a0c268804d39659d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5d/c1018e90b19654bee986b7a0c268804d39659d
new file mode 100755
index 0000000..7500b99
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5d/c1018e90b19654bee986b7a0c268804d39659d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5d/dd0fe66f990dc0e5cf9fec6d9b465240e9537f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5d/dd0fe66f990dc0e5cf9fec6d9b465240e9537f
new file mode 100755
index 0000000..9d8691e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5d/dd0fe66f990dc0e5cf9fec6d9b465240e9537f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5e/b7bb6a146eb3c7fd3990b240a2308eceb1cf8d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5e/b7bb6a146eb3c7fd3990b240a2308eceb1cf8d
new file mode 100755
index 0000000..aca2666
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5e/b7bb6a146eb3c7fd3990b240a2308eceb1cf8d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5f/bfbdc04b4eca46f54f4853a3c5a1dce28f5165 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5f/bfbdc04b4eca46f54f4853a3c5a1dce28f5165
new file mode 100755
index 0000000..aec3867
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/5f/bfbdc04b4eca46f54f4853a3c5a1dce28f5165 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/60/61fe116ecba0800c26113ea1a7dfac2e16eeaf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/60/61fe116ecba0800c26113ea1a7dfac2e16eeaf
new file mode 100755
index 0000000..3f266f6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/60/61fe116ecba0800c26113ea1a7dfac2e16eeaf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/60/91fc2c036a382a69489e3f518ee5aae9a4e567 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/60/91fc2c036a382a69489e3f518ee5aae9a4e567
new file mode 100755
index 0000000..fa63afb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/60/91fc2c036a382a69489e3f518ee5aae9a4e567 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/61/340eeed7340fa6a8792def9a5938bb5d4434bb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/61/340eeed7340fa6a8792def9a5938bb5d4434bb
new file mode 100755
index 0000000..e830caf
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/61/340eeed7340fa6a8792def9a5938bb5d4434bb differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/61/78885b38fe96e825ac0f492c0a941f288b37f6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/61/78885b38fe96e825ac0f492c0a941f288b37f6
new file mode 100755
index 0000000..bedc5f2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/61/78885b38fe96e825ac0f492c0a941f288b37f6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/62/12c31dab5e482247d7977e4f0dd3601decf13b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/62/12c31dab5e482247d7977e4f0dd3601decf13b
new file mode 100755
index 0000000..b6f0607
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/62/12c31dab5e482247d7977e4f0dd3601decf13b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/62/269111c3b02a9355badcb9da8678b1bf41787b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/62/269111c3b02a9355badcb9da8678b1bf41787b
new file mode 100755
index 0000000..0edf659
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/62/269111c3b02a9355badcb9da8678b1bf41787b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/62/33c6a0670228627f93c01cef32485a30403670 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/62/33c6a0670228627f93c01cef32485a30403670
new file mode 100755
index 0000000..81428dd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/62/33c6a0670228627f93c01cef32485a30403670 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/62/c4f6533c9a3894191fdcb96a3be935ade63f1a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/62/c4f6533c9a3894191fdcb96a3be935ade63f1a
new file mode 100755
index 0000000..c0f822d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/62/c4f6533c9a3894191fdcb96a3be935ade63f1a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/63/247125386de9ec90a27ad36169307bf8a11a38 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/63/247125386de9ec90a27ad36169307bf8a11a38
new file mode 100755
index 0000000..bc2d738
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/63/247125386de9ec90a27ad36169307bf8a11a38
@@ -0,0 +1 @@
+xݏ;1D©}Šé¶A‹Vâô\ÀÙ8¬¥àHIVp|²?‰‚ÐLãyO“ÃuN7C]Í¥ƒËlãt¦:iAÐ(xiŒp‚,ÆOñÄæ¡;•æo†7 …UYZB‡½ß÷ý]ÆdUmÔyk©ô[…½Úc©ñþÍ¥)©ñ!êX{¢¿Zó±ö
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/67/110d77886b2af6309b9212961e72b8583e5fa9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/67/110d77886b2af6309b9212961e72b8583e5fa9
new file mode 100755
index 0000000..877bad7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/67/110d77886b2af6309b9212961e72b8583e5fa9
@@ -0,0 +1 @@
+x¥=N1„©÷î^rœ	!J:.`'ûŠlP^×gâT3ú43Ò”Ñûuåp·¦*´Z£	%°ælÙÚ4irœÇH‰·žz,ê³¥ä[‰M]a“J©ÂҐbó5¤lÐ8OùX$XÕ³EaÇ")ŠUïœ$d2zO¸ñçÚÇ„—úųÂÛ>úmð¨'ýqÏýZ渍¶ÊèO`lF“³Oî1!n'=-ýÇÄöªó]A&e‡Ë¯^¶o––^Ý
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/67/18a45909532d1fcf5600d0877f7fe7e78f0b86 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/67/18a45909532d1fcf5600d0877f7fe7e78f0b86
new file mode 100755
index 0000000..ffda698
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/67/18a45909532d1fcf5600d0877f7fe7e78f0b86
@@ -0,0 +1 @@
+x¥ŽÑM1DùNi`‘ǹDBè~è€ǧ]‰Ý ƒöYð7óž4íû¾M8<ÌaæF䬵@Ò˜r*‹Ü85ÆV«±eV÷.Î鉋”0($!“b½UÑ35É—¨¡8¹ÏµÿÒ¾d4ÿºöý£þÉNú“®ö+þÚ£öýÙ#q@€rÉ~àNzžöÏ7Çö¹ÉÛ‚¸Ô!‡®î÷uQu
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/68/c6c84b091926c7d90aa6a79b2bc3bb6adccd8e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/68/c6c84b091926c7d90aa6a79b2bc3bb6adccd8e
new file mode 100755
index 0000000..1e4b075
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/68/c6c84b091926c7d90aa6a79b2bc3bb6adccd8e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/69/f570c57b24ea7c086e94c5e574964798321435 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/69/f570c57b24ea7c086e94c5e574964798321435
new file mode 100755
index 0000000..6975f0b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/69/f570c57b24ea7c086e94c5e574964798321435 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6a/e1a3967031a42cf955d9d5c2395211ac82f6cf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6a/e1a3967031a42cf955d9d5c2395211ac82f6cf
new file mode 100755
index 0000000..3b5713c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6a/e1a3967031a42cf955d9d5c2395211ac82f6cf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6b/7e37be8ce0b897093f2878a9dcd8f396beda2c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6b/7e37be8ce0b897093f2878a9dcd8f396beda2c
new file mode 100755
index 0000000..c393186
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6b/7e37be8ce0b897093f2878a9dcd8f396beda2c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6c/06dcd163587c2cc18be44857e0b71116382aeb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6c/06dcd163587c2cc18be44857e0b71116382aeb
new file mode 100755
index 0000000..2f54be8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6c/06dcd163587c2cc18be44857e0b71116382aeb differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6e/3b9eb35214d4e31ed5789afc7d520ac798ce55 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6e/3b9eb35214d4e31ed5789afc7d520ac798ce55
new file mode 100755
index 0000000..c6100cb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6e/3b9eb35214d4e31ed5789afc7d520ac798ce55 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6f/32739c3724d1d5f855299309f388606f407468 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6f/32739c3724d1d5f855299309f388606f407468
new file mode 100755
index 0000000..6741aa4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6f/32739c3724d1d5f855299309f388606f407468 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6f/a33014764bf1120a454eb8437ae098238e409b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6f/a33014764bf1120a454eb8437ae098238e409b
new file mode 100755
index 0000000..973a4f6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6f/a33014764bf1120a454eb8437ae098238e409b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6f/be9fb85c86d7d1435f728da418bdff52c640a9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6f/be9fb85c86d7d1435f728da418bdff52c640a9
new file mode 100755
index 0000000..a2c8d93
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/6f/be9fb85c86d7d1435f728da418bdff52c640a9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/71/17467b18605a660ebe5586df69e2311ed5609f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/71/17467b18605a660ebe5586df69e2311ed5609f
new file mode 100755
index 0000000..02e1831
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/71/17467b18605a660ebe5586df69e2311ed5609f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/71/2ebba6669ea847d9829e4f1059d6c830c8b531 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/71/2ebba6669ea847d9829e4f1059d6c830c8b531
new file mode 100755
index 0000000..dd7d58f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/71/2ebba6669ea847d9829e4f1059d6c830c8b531 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/71/add2d7b93d55bf3600f8a1582beceebbd050c8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/71/add2d7b93d55bf3600f8a1582beceebbd050c8
new file mode 100755
index 0000000..221afa3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/71/add2d7b93d55bf3600f8a1582beceebbd050c8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/72/cdb057b340205164478565e91eb71647e66891 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/72/cdb057b340205164478565e91eb71647e66891
new file mode 100755
index 0000000..84aa833
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/72/cdb057b340205164478565e91eb71647e66891 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/72/ea499e108df5ff0a4a913e7655bbeeb1fb69f2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/72/ea499e108df5ff0a4a913e7655bbeeb1fb69f2
new file mode 100755
index 0000000..4886e49
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/72/ea499e108df5ff0a4a913e7655bbeeb1fb69f2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/74/df13f0793afdaa972150bba976f7de8284914e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/74/df13f0793afdaa972150bba976f7de8284914e
new file mode 100755
index 0000000..cb50e67
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/74/df13f0793afdaa972150bba976f7de8284914e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/75/a811bf6bc57694adb3fe604786f3a4efd1cd1b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/75/a811bf6bc57694adb3fe604786f3a4efd1cd1b
new file mode 100755
index 0000000..477fd87
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/75/a811bf6bc57694adb3fe604786f3a4efd1cd1b
@@ -0,0 +1,2 @@
+x¥ŽK
+1D]ç¹ÀHçk"n¼Hº;Ì€3‘õúŽâ
ÜU½EQç©këý¦7
Ž€ !²7Xdc2±ÇR¬ƒ˜À©[j²tMv… :q.°‹Äc¦D*	l†(¤Ò£µé3¿Rc}ë|¯‹>ÈJ?é$_ñk[ªóQ,ìÑë"€Zéz¶ËŸ3ª·é9¥ë€ê
LŽOÊ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/76/63fce0130db092936b137cabd693ec234eb060 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/76/63fce0130db092936b137cabd693ec234eb060
new file mode 100755
index 0000000..f578a4a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/76/63fce0130db092936b137cabd693ec234eb060 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/76/ab0e2868197ec158ddd6c78d8a0d2fd73d38f9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/76/ab0e2868197ec158ddd6c78d8a0d2fd73d38f9
new file mode 100755
index 0000000..4d41ad8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/76/ab0e2868197ec158ddd6c78d8a0d2fd73d38f9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7a/a3edf2bcfee22398e6b55295aa56366b7aaf76 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7a/a3edf2bcfee22398e6b55295aa56366b7aaf76
new file mode 100755
index 0000000..09f1e4d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7a/a3edf2bcfee22398e6b55295aa56366b7aaf76 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7a/f14d9c679baaef35555095f4f5d33e9a569ab9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7a/f14d9c679baaef35555095f4f5d33e9a569ab9
new file mode 100755
index 0000000..b4c4ef7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7a/f14d9c679baaef35555095f4f5d33e9a569ab9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7c/04ca611203ed320c5f495b9813054dd23be3be b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7c/04ca611203ed320c5f495b9813054dd23be3be
new file mode 100755
index 0000000..e3ba605
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7c/04ca611203ed320c5f495b9813054dd23be3be
@@ -0,0 +1,2 @@
+x¥ŽQ Dýæ{
-,tcüñ^`%õƒb(ÆëKÏà|ͼd&k)¯³±§ÞDÀsžl¢è<fɇ4a¶“1BŒŽ8zs“­CvƒÅ˜„ºEëQüd¡˜ÅO>åEñ§¯µÁ#}¹%x®µìuƒ«z¸{yÅV÷šû%ÖrƒÉžÇ†·pÖ¨µtíòÇ„
+·¸ÎêUrL
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7c/2c5228c9e90170d4a35e6558e47163daf092e5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7c/2c5228c9e90170d4a35e6558e47163daf092e5
new file mode 100755
index 0000000..52fde92
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7c/2c5228c9e90170d4a35e6558e47163daf092e5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7c/b63eed597130ba4abb87b3e544b85021905520 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7c/b63eed597130ba4abb87b3e544b85021905520
new file mode 100755
index 0000000..769f29c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7c/b63eed597130ba4abb87b3e544b85021905520
@@ -0,0 +1,3 @@
+x¥ŽK
+1D]ç¹€Òùt'"n¼H:ÆÅL$F¼¾£xwUïAQÜ–å6´õf7ºˆI“T*zë±J
+–1#;@r´X]¬êžº¬C3A¨ì F'Îa‘j#Š”ÑTâšÀf a•žcn]_Ê+õ¢¯s[mÕGÙè'å+~íÀm9iãÐ ¹‰PïÔF·³CþœQ¹§•gõe"NÕ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7e/2d058d5fedf8329db44db4fac610d6b1a89159 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7e/2d058d5fedf8329db44db4fac610d6b1a89159
new file mode 100755
index 0000000..d12d7b4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7e/2d058d5fedf8329db44db4fac610d6b1a89159 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7f/7a2da58126226986d71c6ddfab4afba693280d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7f/7a2da58126226986d71c6ddfab4afba693280d
new file mode 100755
index 0000000..2f833c2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/7f/7a2da58126226986d71c6ddfab4afba693280d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/80/a8fbb3abb1ba423d554e9630b8fc2e5698f86b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/80/a8fbb3abb1ba423d554e9630b8fc2e5698f86b
new file mode 100755
index 0000000..3daf6c3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/80/a8fbb3abb1ba423d554e9630b8fc2e5698f86b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/81/1c70fcb6d5bbd022d04cc31836d30b436f9551 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/81/1c70fcb6d5bbd022d04cc31836d30b436f9551
new file mode 100755
index 0000000..6d87024
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/81/1c70fcb6d5bbd022d04cc31836d30b436f9551 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/81/87117062b750eed4f93fd7e899f17b52ce554d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/81/87117062b750eed4f93fd7e899f17b52ce554d
new file mode 100755
index 0000000..19cac9f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/81/87117062b750eed4f93fd7e899f17b52ce554d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/83/07d93a155903a5c49576583f0ce1f6ff897c0e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/83/07d93a155903a5c49576583f0ce1f6ff897c0e
new file mode 100755
index 0000000..5a96a4e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/83/07d93a155903a5c49576583f0ce1f6ff897c0e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/83/6b8b82b26cab22eaaed8820877c76d6c8bca19 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/83/6b8b82b26cab22eaaed8820877c76d6c8bca19
new file mode 100755
index 0000000..99f8286
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/83/6b8b82b26cab22eaaed8820877c76d6c8bca19 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/83/824a8c6658768e2013905219cc8c64cc3d9a2e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/83/824a8c6658768e2013905219cc8c64cc3d9a2e
new file mode 100755
index 0000000..066190f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/83/824a8c6658768e2013905219cc8c64cc3d9a2e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/84/9619b03ae540acee4d1edec96b86993da6b497 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/84/9619b03ae540acee4d1edec96b86993da6b497
new file mode 100755
index 0000000..67271ac
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/84/9619b03ae540acee4d1edec96b86993da6b497
@@ -0,0 +1,3 @@
+x¥ŽK
+1D]ç¹€Òùv7ÞÀ½t’3‹L$ñúŽâ
ÜU½E¥Vë<¤¶v7:³"xç¥K@›R¶
+rÌŠ#Ç"Ôy2[
Xµ5 r2ÆQ´ˆå¨5–”£bŠ=ÇÔº¼æõ,oS«k[ä‰7úIþŠ_;¤VÏRç”?ú`ä<€ØèvvðŸ3"¶1ÝóÜWñEÇP
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/84/de84f8f3a6d63e636ee9ad81f4b80512fa9bbe b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/84/de84f8f3a6d63e636ee9ad81f4b80512fa9bbe
new file mode 100755
index 0000000..32f1461
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/84/de84f8f3a6d63e636ee9ad81f4b80512fa9bbe differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/86/088dae8bade454995b21a1c88107b0e1accdab b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/86/088dae8bade454995b21a1c88107b0e1accdab
new file mode 100755
index 0000000..623a747
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/86/088dae8bade454995b21a1c88107b0e1accdab differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/87/b4926260d77a3b851e71ecce06839bd650b231 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/87/b4926260d77a3b851e71ecce06839bd650b231
new file mode 100755
index 0000000..91944ff
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/87/b4926260d77a3b851e71ecce06839bd650b231 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/88/e185910a15cd13bdf44854ad037f4842b03b29 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/88/e185910a15cd13bdf44854ad037f4842b03b29
new file mode 100755
index 0000000..ae1c5e2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/88/e185910a15cd13bdf44854ad037f4842b03b29 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8a/ad9d0ea334951da47b621a475b39cc6ed759bf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8a/ad9d0ea334951da47b621a475b39cc6ed759bf
new file mode 100755
index 0000000..5e2c943
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8a/ad9d0ea334951da47b621a475b39cc6ed759bf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8a/ae714f7d939309d7f132b30646d96743134a9f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8a/ae714f7d939309d7f132b30646d96743134a9f
new file mode 100755
index 0000000..34ff560
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8a/ae714f7d939309d7f132b30646d96743134a9f
@@ -0,0 +1 @@
+x+)JMU06³`040031QH,-ÉÏM-JOMLÊIÕ+©(aH:,»:ÎCÉýúô:ÞË	²o>ZC'g$楧¦èfæé&%æ%g€5¬ÎqYôÂeÒZoÇÝÙkÚMíæ2­éÆԐ›X\’ZDPC~^ZNfrIf^:Xéõ›ZHÙŠž1O(_œ,'º×
jv^j9È!Ɖ9%`¥<sBÞ§ÝHrèSæ¼3§d	ã¨Ò¢ÔÜü2wßüI{•|þ¹÷	2m»gÜ˾‹©ÉÝ1ÖËåüŠ5Ó¿Ü,\“µ})TC)00ÀavʉùzÖ›¦9–¤×Mü°úÕ…'6óbÊå’G
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8b/095d8fd01594f4d14454d073e3ac57b9ce485f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8b/095d8fd01594f4d14454d073e3ac57b9ce485f
new file mode 100755
index 0000000..4ec0138
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8b/095d8fd01594f4d14454d073e3ac57b9ce485f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8b/5b53cb2aa9ceb1139f5312fcfa3cc3c5a47c9a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8b/5b53cb2aa9ceb1139f5312fcfa3cc3c5a47c9a
new file mode 100755
index 0000000..f4249c2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8b/5b53cb2aa9ceb1139f5312fcfa3cc3c5a47c9a
@@ -0,0 +1 @@
+x퐱	À0S{Š"2ŽŒd,0²‘^?&S¤HóÕÝŸ[Ï8ï눪E›`Ñ„ËrƒZŠ*êdŒ¥­ÆrlŒ,©±ÙcbF/ ·“¶÷'¿ûågв
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8b/7cd60d49ce3a1a770ece43b7d29b5cf462a33a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8b/7cd60d49ce3a1a770ece43b7d29b5cf462a33a
new file mode 100755
index 0000000..790750c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8b/7cd60d49ce3a1a770ece43b7d29b5cf462a33a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8b/fb012a6d809e499bd8d3e194a3929bc8995b93 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8b/fb012a6d809e499bd8d3e194a3929bc8995b93
new file mode 100755
index 0000000..a90ee08
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8b/fb012a6d809e499bd8d3e194a3929bc8995b93 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8c/749d9968d4b10dcfb06c9f97d0e5d92d337071 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8c/749d9968d4b10dcfb06c9f97d0e5d92d337071
new file mode 100755
index 0000000..e42393c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8c/749d9968d4b10dcfb06c9f97d0e5d92d337071
@@ -0,0 +1,2 @@
+x¥ŽAB!C]s
+. a€ùcÜx÷f`†|_b¼¾h¼»ö5mšëº^»¶ÞmzÑÙL“`ð”}$26#"8°ÅÆ`s.`ԝšÜº.!bH\<»	i´"Á,K¦œ8¯èÙ—Úô‰_ÔXŸ—º>êMïeЏ:Ê7ø¹]®ëAƒC40ÏÞë­™ŒQƒŽ³]þœQ\.Ä,¬ÞVO 
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8f/4433f8593ddd65b7dd43dd4564d841f4d9c8aa b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8f/4433f8593ddd65b7dd43dd4564d841f4d9c8aa
new file mode 100755
index 0000000..d2de777
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/8f/4433f8593ddd65b7dd43dd4564d841f4d9c8aa differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/90/a336c7dacbe295159413559b0043b8bdc60d57 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/90/a336c7dacbe295159413559b0043b8bdc60d57
new file mode 100755
index 0000000..35453eb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/90/a336c7dacbe295159413559b0043b8bdc60d57 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/91/2b2d7819cf9c1029e414883857ed61d597a1a5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/91/2b2d7819cf9c1029e414883857ed61d597a1a5
new file mode 100755
index 0000000..d5df393
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/91/2b2d7819cf9c1029e414883857ed61d597a1a5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/91/8bb3e09090a9995d48af9a2a6296d7e6088d1c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/91/8bb3e09090a9995d48af9a2a6296d7e6088d1c
new file mode 100755
index 0000000..c214ab2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/91/8bb3e09090a9995d48af9a2a6296d7e6088d1c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/91/f44111cb1cb1358ac6944ad356ca1738813ea1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/91/f44111cb1cb1358ac6944ad356ca1738813ea1
new file mode 100755
index 0000000..51a456f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/91/f44111cb1cb1358ac6944ad356ca1738813ea1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/92/7d4943cdbdc9a667db8e62cfd0a41870235c51 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/92/7d4943cdbdc9a667db8e62cfd0a41870235c51
new file mode 100755
index 0000000..b6b92c8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/92/7d4943cdbdc9a667db8e62cfd0a41870235c51 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/93/77fccdb210540b8c0520cc6e80eb632c20bd25 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/93/77fccdb210540b8c0520cc6e80eb632c20bd25
new file mode 100755
index 0000000..4b2d93b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/93/77fccdb210540b8c0520cc6e80eb632c20bd25 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/94/4f5dd1a867cab4c2bbcb896493435cae1dcc1a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/94/4f5dd1a867cab4c2bbcb896493435cae1dcc1a
new file mode 100755
index 0000000..1430938
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/94/4f5dd1a867cab4c2bbcb896493435cae1dcc1a
@@ -0,0 +1,2 @@
+x¥ŽK!D]s
+. zšÄ7ÞÀÐ|2.b¼¾h¼»ªWÉKÅVëmH0~7zÎÒ"¦PÈ9`ò:»ÀÑQôi)QÈLEyq=oC*P6-"4„l0StAŽHÌ<u$Âs¬­ËKz…žäumõÑ6yÌ“~Ò9‡_;ÄVORç4z½X¹W¨”˜tžùOà6Vññ4NF
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/94/8ba6e701c1edab0c2d394fb7c5538334129793 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/94/8ba6e701c1edab0c2d394fb7c5538334129793
new file mode 100755
index 0000000..b3e3ef9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/94/8ba6e701c1edab0c2d394fb7c5538334129793 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/95/646149ab6b6ba6edc83cff678582538b457b2b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/95/646149ab6b6ba6edc83cff678582538b457b2b
new file mode 100755
index 0000000..de9ba28
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/95/646149ab6b6ba6edc83cff678582538b457b2b
@@ -0,0 +1,3 @@
+x•ŽMÂ …]s
+. ™ÃObŒoàÞeH»h1ãõEÓ¸{?y_ÞX–enR}h•Y*	üHFS
+€S ž!$À1…¨Å“*¯M’³˜£wUv4ôIt:ª„è²ÏÞ8KFEA¯6•*oéM5ÉûT–­¬òÌ=ýª+ÿŠÝÆ²\ä Ñ CVÁˆžö³ÿÆà`ƒnLj”ÛœX‰iO\
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/95/9de65e568274120fdf9e3af9f77b1550122149 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/95/9de65e568274120fdf9e3af9f77b1550122149
new file mode 100755
index 0000000..e998de8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/95/9de65e568274120fdf9e3af9f77b1550122149 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/96/8ca794a4597f7f6abbb2b8d940b4078a0f3fd4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/96/8ca794a4597f7f6abbb2b8d940b4078a0f3fd4
new file mode 100755
index 0000000..359e43a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/96/8ca794a4597f7f6abbb2b8d940b4078a0f3fd4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/96/bca8d4f05cc4c5e33e4389f80a1309e86fe054 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/96/bca8d4f05cc4c5e33e4389f80a1309e86fe054
new file mode 100755
index 0000000..8938d3e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/96/bca8d4f05cc4c5e33e4389f80a1309e86fe054 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/97/7c696519c5a3004c5f1d15d60c89dbeb8f235f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/97/7c696519c5a3004c5f1d15d60c89dbeb8f235f
new file mode 100755
index 0000000..e561b47
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/97/7c696519c5a3004c5f1d15d60c89dbeb8f235f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/98/ba4205fcf31f5dd93c916d35fe3f3b3d0e6714 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/98/ba4205fcf31f5dd93c916d35fe3f3b3d0e6714
new file mode 100755
index 0000000..6f5e979
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/98/ba4205fcf31f5dd93c916d35fe3f3b3d0e6714
@@ -0,0 +1 @@
+x-ŒÁ
Ã0ûÖ ÐþºG% È…­"ë×Mú!@yÉjÂýñ¼½Šv¬j‚¢:ïAÜÁ‹ÂAÇèM~dú¹­ãА{.3Ñ);ÔlÂç]vi›ú6Á„D%þ«¯¦9fú|.z
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/98/d52d07c0b0bbf2b46548f6aa521295c2cb55db b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/98/d52d07c0b0bbf2b46548f6aa521295c2cb55db
new file mode 100755
index 0000000..c8d636e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/98/d52d07c0b0bbf2b46548f6aa521295c2cb55db
@@ -0,0 +1,3 @@
+xíA
+€0=÷y„}NË®taÝJ[ï
+ú/^r“’´$ŒÓ<ô,
‡¨"1*[\™ †žYjÑ‹(;Ôóm£9ƒoNŒxcëz"1ï(»7„áy÷Û—.øõ®þ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/99/b4f7e4f24470fa06b980bc21f1095c2a9425c0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/99/b4f7e4f24470fa06b980bc21f1095c2a9425c0
new file mode 100755
index 0000000..01ad66e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/99/b4f7e4f24470fa06b980bc21f1095c2a9425c0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9a/301fbe6fada7dcb74fcd7c20269b5c743459a7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9a/301fbe6fada7dcb74fcd7c20269b5c743459a7
new file mode 100755
index 0000000..f413cc5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9a/301fbe6fada7dcb74fcd7c20269b5c743459a7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9a/f731fa116d1eb9a6c0109562472cfee6f5a979 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9a/f731fa116d1eb9a6c0109562472cfee6f5a979
new file mode 100755
index 0000000..53233c4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9a/f731fa116d1eb9a6c0109562472cfee6f5a979 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9c/0b6c34ef379a42d858f03fef38630f476b9102 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9c/0b6c34ef379a42d858f03fef38630f476b9102
new file mode 100755
index 0000000..e6f8500
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9c/0b6c34ef379a42d858f03fef38630f476b9102 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9e/7f4359c469f309b6057febf4c6e80742cbed5b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9e/7f4359c469f309b6057febf4c6e80742cbed5b
new file mode 100755
index 0000000..72b7c49
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9e/7f4359c469f309b6057febf4c6e80742cbed5b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9e/fe7723802d4305142eee177e018fee1572c4f4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9e/fe7723802d4305142eee177e018fee1572c4f4
new file mode 100755
index 0000000..c63fc2c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9e/fe7723802d4305142eee177e018fee1572c4f4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9f/74397a3397b3585faf09e9926b110d7f654254 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9f/74397a3397b3585faf09e9926b110d7f654254
new file mode 100755
index 0000000..e7ec397
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/9f/74397a3397b3585faf09e9926b110d7f654254 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a0/31a28ae70e33a641ce4b8a8f6317f1ab79dee4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a0/31a28ae70e33a641ce4b8a8f6317f1ab79dee4
new file mode 100755
index 0000000..a6c05d1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a0/31a28ae70e33a641ce4b8a8f6317f1ab79dee4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a3/9a620dae5bc8b4e771cd4d251b7d080401a21e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a3/9a620dae5bc8b4e771cd4d251b7d080401a21e
new file mode 100755
index 0000000..4d22586
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a3/9a620dae5bc8b4e771cd4d251b7d080401a21e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a3/fabece9eb8748da810e1e08266fef9b7136ad4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a3/fabece9eb8748da810e1e08266fef9b7136ad4
new file mode 100755
index 0000000..24d7dbc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a3/fabece9eb8748da810e1e08266fef9b7136ad4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a4/1b1bb6d0be3c22fb654234c33b428e15c8cc27 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a4/1b1bb6d0be3c22fb654234c33b428e15c8cc27
new file mode 100755
index 0000000..60789ee
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a4/1b1bb6d0be3c22fb654234c33b428e15c8cc27 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a4/3150a738849c59376cf30bb2a68348a83c8f48 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a4/3150a738849c59376cf30bb2a68348a83c8f48
new file mode 100755
index 0000000..06ae09e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a4/3150a738849c59376cf30bb2a68348a83c8f48 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a5/563304ddf6caba25cb50323a2ea6f7dbfcadca b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a5/563304ddf6caba25cb50323a2ea6f7dbfcadca
new file mode 100755
index 0000000..a831878
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a5/563304ddf6caba25cb50323a2ea6f7dbfcadca differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a7/08b253bd507417ec42d1467a7fd2d7519c4956 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a7/08b253bd507417ec42d1467a7fd2d7519c4956
new file mode 100755
index 0000000..bae752a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a7/08b253bd507417ec42d1467a7fd2d7519c4956 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a7/65fb87eb2f7a1920b73b2d5a057f8f8476a42b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a7/65fb87eb2f7a1920b73b2d5a057f8f8476a42b
new file mode 100755
index 0000000..30abd8b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a7/65fb87eb2f7a1920b73b2d5a057f8f8476a42b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a7/7a56a49f8f3ae242e02717f18ebbc60c5cc543 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a7/7a56a49f8f3ae242e02717f18ebbc60c5cc543
new file mode 100755
index 0000000..76dd5f9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a7/7a56a49f8f3ae242e02717f18ebbc60c5cc543 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a7/dbfcbfc1a60709cb80b5ca24539008456531d0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a7/dbfcbfc1a60709cb80b5ca24539008456531d0
new file mode 100755
index 0000000..67126c9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a7/dbfcbfc1a60709cb80b5ca24539008456531d0
@@ -0,0 +1 @@
+x¥NË
!õL4 a˜ÀÄ/vàÝð²{`1,ÆöEcÞÞ?/ÖR–.õ„»Þ˜%3$“ÁL15fe53'4Á2ÅÃ7^G1yBGV…LAGä	Ù*‘ôä|R)ÿìsmòš^¾%y›kÙê*O<Ôºð×ø±C¬å,‰À’{e”Cg;ÿ9#R¾oKboœ³NÀ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a8/02e06f1782a9645b9851bc7202cee74a8a4972 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a8/02e06f1782a9645b9851bc7202cee74a8a4972
new file mode 100755
index 0000000..d39034b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a8/02e06f1782a9645b9851bc7202cee74a8a4972 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a8/87dd39ad3edd610fc9083dcb61e40ab50673d1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a8/87dd39ad3edd610fc9083dcb61e40ab50673d1
new file mode 100755
index 0000000..968c42a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a8/87dd39ad3edd610fc9083dcb61e40ab50673d1
@@ -0,0 +1 @@
+x+)JMU067a040031QH,-ÉÏM-JOMLÊIÕ+©(aH:,»:ÎCÉýúô:ÞË	²o>ZC'g$楧¦èfæé&%æ%g€5¬ÎqYôÂeÒZoÇÝÙkÚMíæ2­éÆԐ›X\’ZDPC~^ZNfrIf^:Xéõ›ZHÙŠž1O(_œ,'º×
jv^j¹nb^ŠnJfZZjQj^	XÃû#3ƒ|>²^Uó:þ'äAÝÔ2¿†R¨†¢ÔÜü2×ßüI{•|þ¹÷	2m»gÜ˾‹©Éõ1ÖËåüŠ5Ó¿Ü,\“µ})TC)0HÀ!vʉùzÖ›¦9–¤×Mü°úÕ…'6óbG–x
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a9/0bc3fb6f15181972a2959a921429efbd81a473 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a9/0bc3fb6f15181972a2959a921429efbd81a473
new file mode 100755
index 0000000..91113ee
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/a9/0bc3fb6f15181972a2959a921429efbd81a473
@@ -0,0 +1,2 @@
+x¥ŽK
+1D]ç}¥;ÿ7ÞÀ½dÒ=Œ‹‰¯ooà®^UQT®¥\;hk6½‰@¦™Â‰gŒ	§5r’èƒÑ“–Œ]uOMnòdgÄz›&ÒècÆ圈õ¨'•ž}­
NüJá¼Öò¨7ØËp?ê(ßàG»\ËÈ8‡¼CØ¢GTÃg»ü9£x¹$faõxN"
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ab/40af3cb8a3ed2e2843e96d9aa7871336b94573 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ab/40af3cb8a3ed2e2843e96d9aa7871336b94573
new file mode 100755
index 0000000..7da1da6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ab/40af3cb8a3ed2e2843e96d9aa7871336b94573 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ab/6c44a2e84492ad4b41bb6bac87353e9d02ac8b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ab/6c44a2e84492ad4b41bb6bac87353e9d02ac8b
new file mode 100755
index 0000000..d840c1a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ab/6c44a2e84492ad4b41bb6bac87353e9d02ac8b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ab/929391ac42572f92110f3deeb4f0844a951e22 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ab/929391ac42572f92110f3deeb4f0844a951e22
new file mode 100755
index 0000000..8840d00
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ab/929391ac42572f92110f3deeb4f0844a951e22 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ac/4045f965119e6998f4340ed0f411decfb3ec05 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ac/4045f965119e6998f4340ed0f411decfb3ec05
new file mode 100755
index 0000000..4c32d63
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ac/4045f965119e6998f4340ed0f411decfb3ec05 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ad/01aebfdf2ac13145efafe3f9fcf798882f1730 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ad/01aebfdf2ac13145efafe3f9fcf798882f1730
new file mode 100755
index 0000000..ae3ef8c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ad/01aebfdf2ac13145efafe3f9fcf798882f1730 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ad/26b598134264fd284292cb233fc0b2f25851da b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ad/26b598134264fd284292cb233fc0b2f25851da
new file mode 100755
index 0000000..5819a2e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ad/26b598134264fd284292cb233fc0b2f25851da differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ad/a14492498136771f69dd451866cabcb0e9ef9a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ad/a14492498136771f69dd451866cabcb0e9ef9a
new file mode 100755
index 0000000..71023de
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ad/a14492498136771f69dd451866cabcb0e9ef9a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ad/a55a45d14527dc3dfc714ea1c65d2e1e6fbe87 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ad/a55a45d14527dc3dfc714ea1c65d2e1e6fbe87
new file mode 100755
index 0000000..3091b8f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ad/a55a45d14527dc3dfc714ea1c65d2e1e6fbe87
@@ -0,0 +1 @@
+x+)JMU067d040031QH,-ÉÏM-JOMLÊIÕ+©(aH:,»:ÎCÉýúô:ÞË	²o>ZC'g$楧¦èfæé&%æ%g€5¬ÎqYôÂeÒZoÇÝÙkÚMíæ2­éÆԐ›X\’ZDPC~^ZNfrIf^:Xéõ›ZHÙŠž1O(_œ,'º×
jvn~JfZ&Ä5†Æ`ÕÆnלU7ÏV.6™t6ôÇL/•R¨ê¢ÔÜü2§ßüI{•|þ¹÷	2m»gÜ˾‹©Éé1ÖËåüŠ5Ó¿Ü,\“µ})TC)0<ÀÁvʉùzÖ›¦9–¤×Mü°úÕ…'6ób±N’*
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b2/d399ae15224e1d58066e3c8df70ce37de7a656 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b2/d399ae15224e1d58066e3c8df70ce37de7a656
new file mode 100755
index 0000000..20fa838
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b2/d399ae15224e1d58066e3c8df70ce37de7a656
@@ -0,0 +1,2 @@
+xíQA1ôÌ+x€ÙÄ‹‰Ï¡-kI*5”f¿/»zõîÁ	af˜!¤Ö^/·“W¸Jcܤ5LŒÆ›‰;+ŠBŸ6ÎHZP|`îóh>\(óÙ$“sà´î•íX·@š¢75€}57¹K
+¯µ+=;g—®@нÒ!¬4Úè!Œ,\$\ \Âb/±ÉHsø©#þa¾¼÷QÄß
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b4/2712cfe99a1a500b2a51fe984e0b8a7702ba11 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b4/2712cfe99a1a500b2a51fe984e0b8a7702ba11
new file mode 100755
index 0000000..2820b46
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b4/2712cfe99a1a500b2a51fe984e0b8a7702ba11
@@ -0,0 +1,5 @@
+xíA
+À {öû†Bé{M1 	¨¥ß¯>£PØËË–‹3ŽýÜFÖŽ7Á¥E02
<Z
+XÐĨJ
+ÃAˆ^«Ú
+ündim=p#‹Yz¿÷“?¼\»š
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b6/9fe837e4cecfd4c9a40cdca7c138468687df07 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b6/9fe837e4cecfd4c9a40cdca7c138468687df07
new file mode 100755
index 0000000..6dbcb05
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b6/9fe837e4cecfd4c9a40cdca7c138468687df07
@@ -0,0 +1,2 @@
+xí’A
+1E»Î)þf7í}ÌŒ!‚QHzýZºí\|üOùU½âµ?Ñe!‹pJk<ÙM”oQ-¤ËQéÑàáI>†Ûý¶‹XŽ0üš¹Ì’ê,)ë$;:¯‚­Ü·îþÍÆ(óä:
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b6/f610aef53bd343e6c96227de874c66f00ee8e8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b6/f610aef53bd343e6c96227de874c66f00ee8e8
new file mode 100755
index 0000000..fb102f1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b6/f610aef53bd343e6c96227de874c66f00ee8e8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b7/a2576f9fc20024ac9ef17cb134acbd1ac73127 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b7/a2576f9fc20024ac9ef17cb134acbd1ac73127
new file mode 100755
index 0000000..22f2d13
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b7/a2576f9fc20024ac9ef17cb134acbd1ac73127 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b8/a3a806d3950e8c0a03a34f234a92eff0e2c68d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b8/a3a806d3950e8c0a03a34f234a92eff0e2c68d
new file mode 100755
index 0000000..24f0299
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/b8/a3a806d3950e8c0a03a34f234a92eff0e2c68d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ba/cac9b3493509aa15e1730e1545fc0919d1dae0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ba/cac9b3493509aa15e1730e1545fc0919d1dae0
new file mode 100755
index 0000000..f35586f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ba/cac9b3493509aa15e1730e1545fc0919d1dae0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/bc/744705e1d8a019993cf88f62bc4020f1b80919 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/bc/744705e1d8a019993cf88f62bc4020f1b80919
new file mode 100755
index 0000000..0d4bdb3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/bc/744705e1d8a019993cf88f62bc4020f1b80919
@@ -0,0 +1,2 @@
+x¥ŽK
+1D]ç}%ÿˆ¸ñî%t˜YÄH&âõâ
ÜU½¢ŠJ­Öu€Ôj7:P(Ú#¥”¬ÌF§Ì„Ä£1”°Ù+kÙ#vºˆÎš‚ÞÊ⢒£S8«‘W|ñÚÙ¨%²øKëpɯØ3\—V·v‡#MúQgú?wH­ž@(c„
žØsË9›tžôçË嶭™{ŸkOó
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/bc/95c75d59386147d1e79a87c33068d8dbfd71f2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/bc/95c75d59386147d1e79a87c33068d8dbfd71f2
new file mode 100755
index 0000000..436d5a0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/bc/95c75d59386147d1e79a87c33068d8dbfd71f2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/bd/593285fc7fe4ca18ccdbabf027f5d689101452 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/bd/593285fc7fe4ca18ccdbabf027f5d689101452
new file mode 100755
index 0000000..75ab1f0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/bd/593285fc7fe4ca18ccdbabf027f5d689101452 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/bd/867fbae2faa80b920b002b80b1c91bcade7784 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/bd/867fbae2faa80b920b002b80b1c91bcade7784
new file mode 100755
index 0000000..0f74219
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/bd/867fbae2faa80b920b002b80b1c91bcade7784 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/bd/9cb4cd0a770cb9adcb5fce212142ef40ea1c35 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/bd/9cb4cd0a770cb9adcb5fce212142ef40ea1c35
new file mode 100755
index 0000000..2aafdc6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/bd/9cb4cd0a770cb9adcb5fce212142ef40ea1c35 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/be/f6e37b3ee632ba74159168836f382fed21d77d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/be/f6e37b3ee632ba74159168836f382fed21d77d
new file mode 100755
index 0000000..6c24315
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/be/f6e37b3ee632ba74159168836f382fed21d77d
@@ -0,0 +1,2 @@
+x¥K
+1D]ç}¥»3?Ač7p?ô$=Œ`Ґ‰x}GñîªÞƒª`)Ý+0Ñ®Uhú.N“WÆÞ“!ÆÐIdl¦™øØjë<ëb®ñ%%Âm±´Z†“nô“.ú¿v–Î@¾Cdjy€=ˆn£ÛyÕ?g\Ñ,IÇ`y~ÜC%]«÷½¿H&
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c0/6a9be584ac49aa02c5551312d9e2982c91df10 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c0/6a9be584ac49aa02c5551312d9e2982c91df10
new file mode 100755
index 0000000..963ef23
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c0/6a9be584ac49aa02c5551312d9e2982c91df10 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c1/b17981db0840109a820dae8674ee29684134ff b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c1/b17981db0840109a820dae8674ee29684134ff
new file mode 100755
index 0000000..fdcf28c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c1/b17981db0840109a820dae8674ee29684134ff differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c1/b6a51bbb87c2f82b161412c3d20b59fc69b090 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c1/b6a51bbb87c2f82b161412c3d20b59fc69b090
new file mode 100755
index 0000000..3b369f8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c1/b6a51bbb87c2f82b161412c3d20b59fc69b090 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c3/5dee9bcc0e989f3b0c40f68372a9a51b6c4e6a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c3/5dee9bcc0e989f3b0c40f68372a9a51b6c4e6a
new file mode 100755
index 0000000..d22b3b2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c3/5dee9bcc0e989f3b0c40f68372a9a51b6c4e6a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c3/d02eeef75183df7584d8d13ac03053910c1301 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c3/d02eeef75183df7584d8d13ac03053910c1301
new file mode 100755
index 0000000..2294f01
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c3/d02eeef75183df7584d8d13ac03053910c1301 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c4/efe31e9decccc8b2b4d3df9aac2cdfe2995618 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c4/efe31e9decccc8b2b4d3df9aac2cdfe2995618
new file mode 100755
index 0000000..c7572d5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c4/efe31e9decccc8b2b4d3df9aac2cdfe2995618 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c5/0d0f1cb60b8b0fe1615ad20ace557e9d68d7bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c5/0d0f1cb60b8b0fe1615ad20ace557e9d68d7bd
new file mode 100755
index 0000000..a1d5321
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c5/0d0f1cb60b8b0fe1615ad20ace557e9d68d7bd
@@ -0,0 +1 @@
+x¥ŽKj1D³Ö)t˜–4ê–À˜l|ï>-f ‚¯9äÞU½‚â¥Vë6¤¶ô1:³Ì¸èè‰ !ÆüÀå>Z.¼P…0“x„Îû‘²¡h˜ÑèhQÖ+tÎ`1NÎZe¢,ÂÏX[—×ü=ËÛÚêÑvyæI_é‹ÿ†ÿvJ­^¤2 í$?ÁˆI§ìà7oÄ4•ï©íå{Kã>VÞú!~|”U=
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c5/bbe550b9f09444bdddd3ecf3d97c0b42aa786c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c5/bbe550b9f09444bdddd3ecf3d97c0b42aa786c
new file mode 100755
index 0000000..2f2ada7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c5/bbe550b9f09444bdddd3ecf3d97c0b42aa786c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c6/07fc30883e335def28cd686b51f6cfa02b06ec b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c6/07fc30883e335def28cd686b51f6cfa02b06ec
new file mode 100755
index 0000000..475b87e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c6/07fc30883e335def28cd686b51f6cfa02b06ec
@@ -0,0 +1,2 @@
+x¥Q
+1Dýî)r%±›n"þx/m[°[¨¯ooàßÌ{0k)¹…i×›*`â£ZavJ>,‚aò¢ìf<EZÈÍÉȳ¯µÁ5½¤%¸­µ<ê'ô“.ú¿vˆµœ,;ë]€=2¢tœwýsÆä-÷,wóÊ8@°
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c6/92ecf62007c0ac9fb26e2aa884de2933de15ed b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c6/92ecf62007c0ac9fb26e2aa884de2933de15ed
new file mode 100755
index 0000000..ae430bd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c6/92ecf62007c0ac9fb26e2aa884de2933de15ed differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c8/f06f2e3bb2964174677e91f0abead0e43c9e5d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c8/f06f2e3bb2964174677e91f0abead0e43c9e5d
new file mode 100755
index 0000000..5dae4c3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c8/f06f2e3bb2964174677e91f0abead0e43c9e5d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c9/174cef549ec94ecbc43ef03cdc775b4950becb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c9/174cef549ec94ecbc43ef03cdc775b4950becb
new file mode 100755
index 0000000..da8dba2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c9/174cef549ec94ecbc43ef03cdc775b4950becb
@@ -0,0 +1,2 @@
+x¥ŽQ
+Â0DýÎ)rÊf“nSñÇxífCÛHŒx}«xÿfÞÀc¤,˵Y´kUÕbïò8‚pÔu`%—|@rä3GtBÀ™;W]›‚!‹‡½zß'Í%Q¤iӐdœ€T?Û\ª=§×d/sYeµÝè'ô;üÚ^Êr´Î÷#l`6ºmú§Æ ßZ7U^e6oVòO´
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c9/4b27e41064c521120627e07e2035cca1d24ffa b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c9/4b27e41064c521120627e07e2035cca1d24ffa
new file mode 100755
index 0000000..fd1ec9f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/c9/4b27e41064c521120627e07e2035cca1d24ffa differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ca/b2cf23998b40f1af2d9d9a756dc9e285a8df4b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ca/b2cf23998b40f1af2d9d9a756dc9e285a8df4b
new file mode 100755
index 0000000..32ba2aa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ca/b2cf23998b40f1af2d9d9a756dc9e285a8df4b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ca/ff6b7d44973f53e3e0cf31d0d695188b19aec6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ca/ff6b7d44973f53e3e0cf31d0d695188b19aec6
new file mode 100755
index 0000000..6d0f600
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ca/ff6b7d44973f53e3e0cf31d0d695188b19aec6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/cb/491780d82e46dc88a065b965ab307a038f2bc2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/cb/491780d82e46dc88a065b965ab307a038f2bc2
new file mode 100755
index 0000000..cf9cd7d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/cb/491780d82e46dc88a065b965ab307a038f2bc2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/cb/6693a788715b82440a54e0eacd19ba9f6ec559 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/cb/6693a788715b82440a54e0eacd19ba9f6ec559
new file mode 100755
index 0000000..e11181a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/cb/6693a788715b82440a54e0eacd19ba9f6ec559 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/cc/338e4710c9b257106b8d16d82f86458d5beaf1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/cc/338e4710c9b257106b8d16d82f86458d5beaf1
new file mode 100755
index 0000000..85b3b81
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/cc/338e4710c9b257106b8d16d82f86458d5beaf1
@@ -0,0 +1,2 @@
+x¥ŽK!]sŠ¾€†æ3`bŒoà »ÉÌ1Æë‹gpW©E½G­Öm€±x]“ˆ˜Èù6d
+ûƒçeaŽÎ‰ç¢µz¥.ϬŽDv	Ù[êhŽ¥äD³[´Jﱶwþ¤ÎðX[ÝÛ.2ínu£ÞöVƉZ½Ú³F´!x8ê8÷¦G‡ü‘PÂÛP_’?KN
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/cc/3e3009134cb88014129fc8858d1101359e5e2f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/cc/3e3009134cb88014129fc8858d1101359e5e2f
new file mode 100755
index 0000000..9a0cb7a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/cc/3e3009134cb88014129fc8858d1101359e5e2f
@@ -0,0 +1,2 @@
+x¥Ž]
+Â0„}Î)ö•Íß&_¼H“
-ØFbÔë[Åø6ó}0LªË2wPÆìzc†’­Ë*“sXbö‚
Rt”®#Gë$‰[l¼vH„®$ÞkÖÚf.ʧLžF+¥QHœD|ô©68çWl.S]îu…oô“Nü¿¶Ou9‚ÔVa0^ZÅF·³ÿœ½ÍÏ9^#Þ
ØOd
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ce/8860d49e3bea6fd745874a01b7c3e46da8cbc3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ce/8860d49e3bea6fd745874a01b7c3e46da8cbc3
new file mode 100755
index 0000000..860f995
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ce/8860d49e3bea6fd745874a01b7c3e46da8cbc3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ce/e656c392ad0557b3aae0fb411475c206e2926f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ce/e656c392ad0557b3aae0fb411475c206e2926f
new file mode 100755
index 0000000..ff0624c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ce/e656c392ad0557b3aae0fb411475c206e2926f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/cf/8c5cc8a85a1ff5a4ba51e0bc7cf5665669924d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/cf/8c5cc8a85a1ff5a4ba51e0bc7cf5665669924d
new file mode 100755
index 0000000..36b0289
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/cf/8c5cc8a85a1ff5a4ba51e0bc7cf5665669924d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d0/7ec190c306ec690bac349e87d01c4358e49bb2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d0/7ec190c306ec690bac349e87d01c4358e49bb2
new file mode 100755
index 0000000..d52a56f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d0/7ec190c306ec690bac349e87d01c4358e49bb2
@@ -0,0 +1,2 @@
+xՏ±
€0©™Â3¤ažObˆ%Ç‘S°=HTŒ@u:]uYG¦´¥%šLÚE™–;¸’uÌ`_?gŒÎ~0²òßÒ”.
+׋Pëû£ÓœñxvXië
Ó­f!
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d0/d4594e16f2e19107e3fa7ea63e7aaaff305ffb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d0/d4594e16f2e19107e3fa7ea63e7aaaff305ffb
new file mode 100755
index 0000000..5f7e286
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d0/d4594e16f2e19107e3fa7ea63e7aaaff305ffb differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d2/f8637f2eab2507a1e13cbc9df4729ec386627e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d2/f8637f2eab2507a1e13cbc9df4729ec386627e
new file mode 100755
index 0000000..558a851
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d2/f8637f2eab2507a1e13cbc9df4729ec386627e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d3/3cedf513c059e0515653fa2c2e386631387a05 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d3/3cedf513c059e0515653fa2c2e386631387a05
new file mode 100755
index 0000000..d6d4c2b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d3/3cedf513c059e0515653fa2c2e386631387a05 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d3/719a5ae8e4d92276b5313ce976f6ee5af2b436 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d3/719a5ae8e4d92276b5313ce976f6ee5af2b436
new file mode 100755
index 0000000..930bf5a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d3/719a5ae8e4d92276b5313ce976f6ee5af2b436
@@ -0,0 +1,2 @@
+x=1Â0E™}Š¿uAH…بÄ
z‡¸ÔRHPÔŸ´T–¿÷ìBrh/ç]?ªaÐ ˜48¡,‘_â¡MúdköÄуTPF!«÷›TïZµQ?
+RÖ§F«Në™ÕÊÒ_J͆ÃÔØh’ª{Ÿßò(kÒËLKV1p–+Q‹êÑÕÝÑ®A×
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d3/7aa3bbfe1c0c49b909781251b956dbabe85f96 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d3/7aa3bbfe1c0c49b909781251b956dbabe85f96
new file mode 100755
index 0000000..5902e0f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d3/7aa3bbfe1c0c49b909781251b956dbabe85f96 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d3/7ad72a2052685fc6201c2af90103ad42d2079b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d3/7ad72a2052685fc6201c2af90103ad42d2079b
new file mode 100755
index 0000000..b2f39bf
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d3/7ad72a2052685fc6201c2af90103ad42d2079b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d4/207f77243500bec335ab477f9227fcdb1e271a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d4/207f77243500bec335ab477f9227fcdb1e271a
new file mode 100755
index 0000000..862e4e5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d4/207f77243500bec335ab477f9227fcdb1e271a
@@ -0,0 +1,2 @@
+x¥ŽK
+1D]ç¹€’O'™7ÞÀ½t:ÝŒ‹™H&âõŸ«zŠ¢:Ï÷®Ä]oÌZÀBñBXlô(ƒƒ“昭+d<"«6^ºÎ%ŒÞ
A(	¡ˆJÆ,Æ%	%£5‚SøìSmúR^ØŠ¾Nu^뢏¼ÑO:óWüځê|ÒÖ	ÆèôÞDcÔF·³ÿœQEn¸¯½6õÔ#Qç
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d4/27e0b2e138501a3d15cc376077a3631e15bd46 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d4/27e0b2e138501a3d15cc376077a3631e15bd46
new file mode 100755
index 0000000..0b3611a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d4/27e0b2e138501a3d15cc376077a3631e15bd46 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d5/093787ef302b941b6aab081b99fb4880038bd8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d5/093787ef302b941b6aab081b99fb4880038bd8
new file mode 100755
index 0000000..7d73449
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d5/093787ef302b941b6aab081b99fb4880038bd8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d5/a61b0b4992a4f0caa887fa08b52431e727bb6f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d5/a61b0b4992a4f0caa887fa08b52431e727bb6f
new file mode 100755
index 0000000..a7921de
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d5/a61b0b4992a4f0caa887fa08b52431e727bb6f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d5/b6fc965c926a1bfc9ee456042b94088b5c5d21 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d5/b6fc965c926a1bfc9ee456042b94088b5c5d21
new file mode 100755
index 0000000..924bdbb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d5/b6fc965c926a1bfc9ee456042b94088b5c5d21 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d5/ec1152fe25e9fec00189eb00b3db71db24c218 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d5/ec1152fe25e9fec00189eb00b3db71db24c218
new file mode 100755
index 0000000..0d2534b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d5/ec1152fe25e9fec00189eb00b3db71db24c218 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d6/42b9770c66bba94a08df09b5efb095001f76d7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d6/42b9770c66bba94a08df09b5efb095001f76d7
new file mode 100755
index 0000000..1671f9f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d6/42b9770c66bba94a08df09b5efb095001f76d7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d6/462fa3f5292857db599c54aea2bf91616230c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d6/462fa3f5292857db599c54aea2bf91616230c5
new file mode 100755
index 0000000..baae3f0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d6/462fa3f5292857db599c54aea2bf91616230c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d6/cf6c7741b3316826af1314042550c97ded1d50 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d6/cf6c7741b3316826af1314042550c97ded1d50
new file mode 100755
index 0000000..8f9ae1f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d6/cf6c7741b3316826af1314042550c97ded1d50
@@ -0,0 +1,2 @@
+x¥Q
+1Dýî)r%µ¦i@Äoàj›e»…ÚÅë[Åø7ó̤Zʽƒ¿éMSLB‘­Nl°ìm öÑBºÉ~×>×—üŠ-Ãu®åY8ê ŸtÖ¯øµ]ªåÖQaǶèÍ ã¼ëŸ3f]š>b×lÞ(„A]
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d7/308cc367b2cc23f710834ec1fd8ffbacf1b460 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d7/308cc367b2cc23f710834ec1fd8ffbacf1b460
new file mode 100755
index 0000000..b02cda4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d7/308cc367b2cc23f710834ec1fd8ffbacf1b460
@@ -0,0 +1 @@
+x¥K @]sŠ¹€†)ЁÄ7ÞÀð™¦]ÐI(Æx{ñî^Þâ½,µnлSoÌ`¬/¹Xä)Ù™B at GžÃ”¸œaòD¼ «øê«4x”wlž«ÔCv¸ò°?º×-79dé—,õh‚F4Žœµ×Z
;ƝÿH¨´í±}Ô·š= 
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d8/74671ef5b20184836cb983bb273e5280384d0b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d8/74671ef5b20184836cb983bb273e5280384d0b
new file mode 100755
index 0000000..1d80378
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d8/74671ef5b20184836cb983bb273e5280384d0b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d8/dec75ff2f8b41d1c5bfef0cd57b7300c834f66 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d8/dec75ff2f8b41d1c5bfef0cd57b7300c834f66
new file mode 100755
index 0000000..74f807e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d8/dec75ff2f8b41d1c5bfef0cd57b7300c834f66 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d8/fa77b6833082c1ea36b7828a582d4c43882450 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d8/fa77b6833082c1ea36b7828a582d4c43882450
new file mode 100755
index 0000000..9881453
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d8/fa77b6833082c1ea36b7828a582d4c43882450
@@ -0,0 +1 @@
+xíÐ1€ DQkN1¥–&6‡•%l²BkŒ·naa1Åk¦ø¤…°íëdI¢(ãU£rö'7‰‘»LŸ’AÅ,±+Wmð9ŒI'UŸÄ͹ÿñ£_ÛÜ°N
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d9/63979c237d08b6ba39062ee7bf64c7d34a27f8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d9/63979c237d08b6ba39062ee7bf64c7d34a27f8
new file mode 100755
index 0000000..5fa1040
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/d9/63979c237d08b6ba39062ee7bf64c7d34a27f8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/da/178208145ef585a1bd5ca5f4c9785d738df2cf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/da/178208145ef585a1bd5ca5f4c9785d738df2cf
new file mode 100755
index 0000000..6292118
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/da/178208145ef585a1bd5ca5f4c9785d738df2cf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/db/6261a7c65c7fd678520c9bb6f2c47582ab9ed5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/db/6261a7c65c7fd678520c9bb6f2c47582ab9ed5
new file mode 100755
index 0000000..b82e7fc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/db/6261a7c65c7fd678520c9bb6f2c47582ab9ed5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/dd/2ae5ab264e5592aa754235d5ad5eac8f0ecdfd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/dd/2ae5ab264e5592aa754235d5ad5eac8f0ecdfd
new file mode 100755
index 0000000..55626a5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/dd/2ae5ab264e5592aa754235d5ad5eac8f0ecdfd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/dd/9a570c3400e6e07bc4d7651d6e20b08926b3d9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/dd/9a570c3400e6e07bc4d7651d6e20b08926b3d9
new file mode 100755
index 0000000..8fd60cb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/dd/9a570c3400e6e07bc4d7651d6e20b08926b3d9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/de/872ee3618b894992e9d1e18ba2ebe256a112f9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/de/872ee3618b894992e9d1e18ba2ebe256a112f9
new file mode 100755
index 0000000..04dda4a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/de/872ee3618b894992e9d1e18ba2ebe256a112f9
@@ -0,0 +1 @@
+x퐱
À S3ŏ‚…ŒlK–A†ˆõƒ²BÚ4W®¸b­ Ÿù˜—T5Á¢:§8ÔS»c€œ±ÔÔ»P`KäI¥Ë†O3Z½•”þàç‡&ؐÝ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/df/e3f22baa1f6fce5447901c3086bae368de6bdd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/df/e3f22baa1f6fce5447901c3086bae368de6bdd
new file mode 100755
index 0000000..e135694
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/df/e3f22baa1f6fce5447901c3086bae368de6bdd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e0/67f9361140f19391472df8a82d6610813c73b7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e0/67f9361140f19391472df8a82d6610813c73b7
new file mode 100755
index 0000000..955431d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e0/67f9361140f19391472df8a82d6610813c73b7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e1/129b3cfb5898e0fbd606e0cb80b2755e50d161 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e1/129b3cfb5898e0fbd606e0cb80b2755e50d161
new file mode 100755
index 0000000..751f1dd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e1/129b3cfb5898e0fbd606e0cb80b2755e50d161 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e1/7ace1492648c9dc5701bad5c47af9d1b60c4e9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e1/7ace1492648c9dc5701bad5c47af9d1b60c4e9
new file mode 100755
index 0000000..4a812e5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e1/7ace1492648c9dc5701bad5c47af9d1b60c4e9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e2/c6abbd55fed5ac71a5f2751e29b4a34726a595 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e2/c6abbd55fed5ac71a5f2751e29b4a34726a595
new file mode 100755
index 0000000..7b84ce9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e2/c6abbd55fed5ac71a5f2751e29b4a34726a595
@@ -0,0 +1 @@
+x+)JMU067f040031QH,-ÉÏM-JOMLÊIÕ+©(aH:,»:ÎCÉýúô:ÞË	²o>ZC'g$楧¦èfæé&%æ%g€5¬ÎqYôÂeÒZoÇÝÙkÚMíæ2­éÆԐ›X\’ZDPC~^ZNfrIf^:Xéõ›ZHÙŠž1O(_œ,'º×
jvn~JfZ&Ô5ù%·˜º³\N´º¢ÔçÞö§,5[ðe“Ù¨ú¢ÔÜü2ÇßüI{•|þ¹÷	2m»gÜ˾‹©Éñ1ÖËåüŠ5Ó¿Ü,\“µ})TC)0DÀvú‰ùzÖ›¦9–¤×Mü°úÕ…'6ób‹”
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e3/1e7ad3ed298f24e383c4950f4671993ec078e4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e3/1e7ad3ed298f24e383c4950f4671993ec078e4
new file mode 100755
index 0000000..a28ded3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e3/1e7ad3ed298f24e383c4950f4671993ec078e4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e3/76fbdd06ebf021c92724da9f26f44212734e3e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e3/76fbdd06ebf021c92724da9f26f44212734e3e
new file mode 100755
index 0000000..8da2341
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e3/76fbdd06ebf021c92724da9f26f44212734e3e
@@ -0,0 +1,3 @@
+xíAÂ@E]s
+`ö@ÌuHš)M=¾Scô®Üþü’zÂé:¢ÊŠ³(ãN+6Þ›D°¡Feð­­˜Y®g$+GˆÞä&F
+Ÿ½ì‹p‡þâG—4”mQÉ\±á85Æ#FìCð¥ï~QEóÀÄÀÚR—š½u)£;cáàâ6ü­öë'ÍjÄÇ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e4/9f917b448d1340b31d76e54ba388268fd4c922 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e4/9f917b448d1340b31d76e54ba388268fd4c922
new file mode 100755
index 0000000..870c3e7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e4/9f917b448d1340b31d76e54ba388268fd4c922 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e4/f618a2c3ed0669308735727df5ebf2447f022f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e4/f618a2c3ed0669308735727df5ebf2447f022f
new file mode 100755
index 0000000..c7e1ee9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e4/f618a2c3ed0669308735727df5ebf2447f022f
@@ -0,0 +1,2 @@
+x¥ŽK!D]s
+. išObŒoà i2.b¼¾h¼»ª÷’JQ«õ6äb`7:³DN.%•±œ4¹’u¦‹ÏÄIQñYÜcçmÈàÙ`Q¨aQYa¶@>äÄÉ—Ecñ9ÖÖå%¿bÏòº¶úh›<ò¤Ÿtæ¯øµµz’J£òÁ(¹“γƒÿœFCñ_‹NŒ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e5/060729746ca9888239cba08fdcf4bee907b406 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e5/060729746ca9888239cba08fdcf4bee907b406
new file mode 100755
index 0000000..33299c2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e5/060729746ca9888239cba08fdcf4bee907b406 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e6/5a9bb2af9f4c2d1c375dd0f8f8a46cf9c68812 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e6/5a9bb2af9f4c2d1c375dd0f8f8a46cf9c68812
new file mode 100755
index 0000000..72f1cbc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e6/5a9bb2af9f4c2d1c375dd0f8f8a46cf9c68812 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e8/107f24196736b870a318a0e28f048e29f6feff b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e8/107f24196736b870a318a0e28f048e29f6feff
new file mode 100755
index 0000000..ffcf843
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e8/107f24196736b870a318a0e28f048e29f6feff
@@ -0,0 +1,3 @@
+x¥ŽK!D]s
+. i~=LbŒoàÞ@ÓdfãõEã
ÜU½—TŠj)k—Úš]oÌÒ¯mð„èü„ž5(3ƒÓj&Ô™4Íâß»póp™iRI;‘³·¨“Â9Ò‚²Q„g_j“—ô
+-ÉëRËVïòȃ~Ò™¿â×TËI*ãÜtr g;ÿ9#R¾mkb%ÞrLNÁ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e9/2cdb7017dc6c5aed25cb4202c5b0104b872246 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e9/2cdb7017dc6c5aed25cb4202c5b0104b872246
new file mode 100755
index 0000000..cb1260e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e9/2cdb7017dc6c5aed25cb4202c5b0104b872246 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e9/ad6ec3e38364a3d07feda7c4197d4d845c53b5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e9/ad6ec3e38364a3d07feda7c4197d4d845c53b5
new file mode 100755
index 0000000..da4a5ed
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e9/ad6ec3e38364a3d07feda7c4197d4d845c53b5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e9/f48beccc62d535739bfbdebe0a55ed716d8366 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e9/f48beccc62d535739bfbdebe0a55ed716d8366
new file mode 100755
index 0000000..23c59e4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/e9/f48beccc62d535739bfbdebe0a55ed716d8366 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/eb/c09d0137cfb0c26697aed0109fb943ad906f3f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/eb/c09d0137cfb0c26697aed0109fb943ad906f3f
new file mode 100755
index 0000000..83b489d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/eb/c09d0137cfb0c26697aed0109fb943ad906f3f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ec/67e5a86adff465359f1c8f995e12dbdfa08d8a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ec/67e5a86adff465359f1c8f995e12dbdfa08d8a
new file mode 100755
index 0000000..8490346
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ec/67e5a86adff465359f1c8f995e12dbdfa08d8a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ed/9523e62e453e50dd9be1606af19399b96e397a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ed/9523e62e453e50dd9be1606af19399b96e397a
new file mode 100755
index 0000000..7853e23
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ed/9523e62e453e50dd9be1606af19399b96e397a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ee/1d6f164893c1866a323f072eeed36b855656be b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ee/1d6f164893c1866a323f072eeed36b855656be
new file mode 100755
index 0000000..87d8080
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ee/1d6f164893c1866a323f072eeed36b855656be differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ee/3fa1b8c00aff7fe02065fdb50864bb0d932ccf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ee/3fa1b8c00aff7fe02065fdb50864bb0d932ccf
new file mode 100755
index 0000000..974b72d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ee/3fa1b8c00aff7fe02065fdb50864bb0d932ccf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ee/a9286df54245fea72c5b557291470eb825f38f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ee/a9286df54245fea72c5b557291470eb825f38f
new file mode 100755
index 0000000..ead0b2c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ee/a9286df54245fea72c5b557291470eb825f38f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ef/58fdd8086c243bdc81f99e379acacfd21d32d6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ef/58fdd8086c243bdc81f99e379acacfd21d32d6
new file mode 100755
index 0000000..55f79e0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ef/58fdd8086c243bdc81f99e379acacfd21d32d6
@@ -0,0 +1,2 @@
+x
ÉÁ	À0Оâï:JŠB¢ÝŸæôOV
+Þñ´yáó5éê†5jã†q!’4÷Î{¡³:ýp;¼
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ef/c499524cf105d5264ac7fc54e07e95764e8075 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ef/c499524cf105d5264ac7fc54e07e95764e8075
new file mode 100755
index 0000000..bc9350b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ef/c499524cf105d5264ac7fc54e07e95764e8075 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ef/c9121fdedaf08ba180b53ebfbcf71bd488ed09 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ef/c9121fdedaf08ba180b53ebfbcf71bd488ed09
new file mode 100755
index 0000000..5f9cd30
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ef/c9121fdedaf08ba180b53ebfbcf71bd488ed09 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f0/053b8060bb3f0be5cbcc3147a07ece26bf097e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f0/053b8060bb3f0be5cbcc3147a07ece26bf097e
new file mode 100755
index 0000000..c63d37f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f0/053b8060bb3f0be5cbcc3147a07ece26bf097e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f0/ce2b8e4986084d9b308fb72709e414c23eb5e6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f0/ce2b8e4986084d9b308fb72709e414c23eb5e6
new file mode 100755
index 0000000..e78c19f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f0/ce2b8e4986084d9b308fb72709e414c23eb5e6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f2/0c9063fa0bda9a397c96947a7b687305c49753 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f2/0c9063fa0bda9a397c96947a7b687305c49753
new file mode 100755
index 0000000..34d9aed
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f2/0c9063fa0bda9a397c96947a7b687305c49753 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f2/9e7fb590551095230c6149cbe72f2e9104a796 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f2/9e7fb590551095230c6149cbe72f2e9104a796
new file mode 100755
index 0000000..663f6ae
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f2/9e7fb590551095230c6149cbe72f2e9104a796 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f2/e1550a0c9e53d5811175864a29536642ae3821 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f2/e1550a0c9e53d5811175864a29536642ae3821
new file mode 100755
index 0000000..1fdcbe2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f2/e1550a0c9e53d5811175864a29536642ae3821 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f3/293571dcd708b6a3faf03818cd2844d000e198 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f3/293571dcd708b6a3faf03818cd2844d000e198
new file mode 100755
index 0000000..f748743
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f3/293571dcd708b6a3faf03818cd2844d000e198
@@ -0,0 +1 @@
+x¥ŽKjÄ0³Ö)údµZ!›¹Á\@nIعƒ,3×Ͳ{¼¢XZÛë?F/\Eã12zcó’©"#êX1§]µÚ[Ô_êå˜GŒ&™œ˜c©+9³‡”ùXWKÁÓžiUé›t¸çgê›´Sø*“¾×OÛ¹Ë)u|²´oXp*"pÓ¤µšt†Žò…šÅ©`9êïÎäê§zÅKO\
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f3/f1164b68b57b1995b658a828320e6df3081fae b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f3/f1164b68b57b1995b658a828320e6df3081fae
new file mode 100755
index 0000000..5f0b4e4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f3/f1164b68b57b1995b658a828320e6df3081fae differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f4/15caf3fcad16304cb424b67f0ee6b12dc03aae b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f4/15caf3fcad16304cb424b67f0ee6b12dc03aae
new file mode 100755
index 0000000..21ce1a0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f4/15caf3fcad16304cb424b67f0ee6b12dc03aae differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f4/8097eb340dc5a7cae55aabcf1faf4548aa821f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f4/8097eb340dc5a7cae55aabcf1faf4548aa821f
new file mode 100755
index 0000000..5a4a9a5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f4/8097eb340dc5a7cae55aabcf1faf4548aa821f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f5/504f36e6f4eb797a56fc5bac6c6c7f32969bf2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f5/504f36e6f4eb797a56fc5bac6c6c7f32969bf2
new file mode 100755
index 0000000..2aa0c3b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f5/504f36e6f4eb797a56fc5bac6c6c7f32969bf2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f5/b50c85a87cac64d7eb3254cdd1aec9564c0293 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f5/b50c85a87cac64d7eb3254cdd1aec9564c0293
new file mode 100755
index 0000000..c1885cb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f5/b50c85a87cac64d7eb3254cdd1aec9564c0293 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f5/f9dd5886a6ee20272be0aafc790cba43b31931 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f5/f9dd5886a6ee20272be0aafc790cba43b31931
new file mode 100755
index 0000000..17ad506
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f5/f9dd5886a6ee20272be0aafc790cba43b31931 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f6/65b45cde9b568009c6e6b7b568e89cfe717df8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f6/65b45cde9b568009c6e6b7b568e89cfe717df8
new file mode 100755
index 0000000..7af50d7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f6/65b45cde9b568009c6e6b7b568e89cfe717df8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f6/be049e284c0f9dcbbc745543885be3502ea521 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f6/be049e284c0f9dcbbc745543885be3502ea521
new file mode 100755
index 0000000..12d3c25
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f6/be049e284c0f9dcbbc745543885be3502ea521 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f7/c332bd4d4d4b777366cae4d24d1687477576bf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f7/c332bd4d4d4b777366cae4d24d1687477576bf
new file mode 100755
index 0000000..b36bcea
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f7/c332bd4d4d4b777366cae4d24d1687477576bf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f8/958bdf4d365a84a9a178b1f5f35ff1dacbd884 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f8/958bdf4d365a84a9a178b1f5f35ff1dacbd884
new file mode 100755
index 0000000..5dbbef2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/f8/958bdf4d365a84a9a178b1f5f35ff1dacbd884
@@ -0,0 +1,2 @@
+x¥ŽK
+1D]ç}¥ÓI¦qã
ÜK>f1’‰x}£xwU¯àQ±–²v kv½‰@`OŽ§<çHˆd}œ%kŽA›‘CÒ>²ÑÄêá›Ü;$KÈ™ybhŒóÁ2癈sLA±öÊ?ûR\ÒË·×¥–­Þá(ƒ~ÒY¾Ã¯b-'ÐÆYÇŽp‚=NˆjÐq¶ËŸ•òm[“zí O+
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fa/c03f2c5139618d87d53614c153823bf1f31396 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fa/c03f2c5139618d87d53614c153823bf1f31396
new file mode 100755
index 0000000..30e07e5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fa/c03f2c5139618d87d53614c153823bf1f31396 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fa/da9356aa3f74622327a3038ae9c6f92e1c5c1d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fa/da9356aa3f74622327a3038ae9c6f92e1c5c1d
new file mode 100755
index 0000000..16ce49a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fa/da9356aa3f74622327a3038ae9c6f92e1c5c1d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fb/738a106cfd097a4acb96ce132ecb1ad6c46b03 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fb/738a106cfd097a4acb96ce132ecb1ad6c46b03
new file mode 100755
index 0000000..4f1e726
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fb/738a106cfd097a4acb96ce132ecb1ad6c46b03 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fc/4c636d6515e9e261f9260dbcf3cc6eca97ea08 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fc/4c636d6515e9e261f9260dbcf3cc6eca97ea08
new file mode 100755
index 0000000..be8a810
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fc/4c636d6515e9e261f9260dbcf3cc6eca97ea08 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fc/7d7b805f7a9428574f4f802b2e34cd20ab9d99 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fc/7d7b805f7a9428574f4f802b2e34cd20ab9d99
new file mode 100755
index 0000000..20493e6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fc/7d7b805f7a9428574f4f802b2e34cd20ab9d99 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fc/90237dc4891fa6c69827fc465632225e391618 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fc/90237dc4891fa6c69827fc465632225e391618
new file mode 100755
index 0000000..961814b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fc/90237dc4891fa6c69827fc465632225e391618 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fd/57d2d6770fad8e9959124793a17f441b571e66 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fd/57d2d6770fad8e9959124793a17f441b571e66
new file mode 100755
index 0000000..21e6b2c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fd/57d2d6770fad8e9959124793a17f441b571e66 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fd/89f8cffb663ac89095a0f9764902e93ceaca6a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fd/89f8cffb663ac89095a0f9764902e93ceaca6a
new file mode 100755
index 0000000..2f9d83b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fd/89f8cffb663ac89095a0f9764902e93ceaca6a
@@ -0,0 +1,2 @@
+x¥ŽK!D]s
+. ¡{` cÜx/À§É¸`0ÆëËoà®êURy±–òèõ|èY`ÀdPÌA!±íÜäŒå4C2d=x#ž¾ñÚe`Bgr´™uôàbLÁ‡¬Ðf“fG @þÕ—Úä-½}Kò¾Ô²ÕUžyÐ=]ù;üÚ)Ör‘0 Rˆ$Ê(%²ÿ¼Ùo=׶›ˆ‡OPw
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fe/5407fc50a53aecb41d1a6e9ea7b612e581af87 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fe/5407fc50a53aecb41d1a6e9ea7b612e581af87
new file mode 100755
index 0000000..4ce7d22
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/fe/5407fc50a53aecb41d1a6e9ea7b612e581af87 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ff/49d07869831ad761bbdaea026086f8789bcb00 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ff/49d07869831ad761bbdaea026086f8789bcb00
new file mode 100755
index 0000000..eada39b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ff/49d07869831ad761bbdaea026086f8789bcb00 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ff/b312248d607284c290023f9502eea010d34efd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ff/b312248d607284c290023f9502eea010d34efd
new file mode 100755
index 0000000..7e46c4f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/objects/ff/b312248d607284c290023f9502eea010d34efd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/branch
new file mode 100755
index 0000000..03f79a3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/branch
@@ -0,0 +1 @@
+7cb63eed597130ba4abb87b3e544b85021905520
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/df_ancestor b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/df_ancestor
new file mode 100755
index 0000000..4bc37ac
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/df_ancestor
@@ -0,0 +1 @@
+2da538570bc1e5b2c3e855bf702f35248ad0735f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/df_side1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/df_side1
new file mode 100755
index 0000000..ca6dd67
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/df_side1
@@ -0,0 +1 @@
+a7dbfcbfc1a60709cb80b5ca24539008456531d0
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/df_side2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/df_side2
new file mode 100755
index 0000000..b8160f8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/df_side2
@@ -0,0 +1 @@
+fc90237dc4891fa6c69827fc465632225e391618
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/ff_branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/ff_branch
new file mode 100755
index 0000000..e9e9051
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/ff_branch
@@ -0,0 +1 @@
+fd89f8cffb663ac89095a0f9764902e93ceaca6a
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/master
new file mode 100755
index 0000000..8a329ae
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/master
@@ -0,0 +1 @@
+bd593285fc7fe4ca18ccdbabf027f5d689101452
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo1
new file mode 100755
index 0000000..4d2c669
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo1
@@ -0,0 +1 @@
+16f825815cfd20a07a75c71554e82d8eede0b061
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo2
new file mode 100755
index 0000000..f503977
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo2
@@ -0,0 +1 @@
+158dc7bedb202f5b26502bf3574faa7f4238d56c
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo3
new file mode 100755
index 0000000..b92994f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo3
@@ -0,0 +1 @@
+50ce7d7d01217679e26c55939eef119e0c93e272
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo4
new file mode 100755
index 0000000..f33d57c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo4
@@ -0,0 +1 @@
+54269b3f6ec3d7d4ede24dd350dd5d605495c3ae
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo5
new file mode 100755
index 0000000..e9f9433
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo5
@@ -0,0 +1 @@
+e4f618a2c3ed0669308735727df5ebf2447f022f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo6
new file mode 100755
index 0000000..4c5a98a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/octo6
@@ -0,0 +1 @@
+b6f610aef53bd343e6c96227de874c66f00ee8e8
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/previous b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/previous
new file mode 100755
index 0000000..7bc1a8d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/previous
@@ -0,0 +1 @@
+c607fc30883e335def28cd686b51f6cfa02b06ec
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/rename_conflict_ancestor b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/rename_conflict_ancestor
new file mode 100755
index 0000000..4092d42
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/rename_conflict_ancestor
@@ -0,0 +1 @@
+2392a2dacc9efb562b8635d6579fb458751c7c5b
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/rename_conflict_ours b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/rename_conflict_ours
new file mode 100755
index 0000000..a1c50dc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/rename_conflict_ours
@@ -0,0 +1 @@
+34bfafff88eaf118402b44e6f3e2dbbf1a582b05
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/rename_conflict_theirs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/rename_conflict_theirs
new file mode 100755
index 0000000..1309893
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/rename_conflict_theirs
@@ -0,0 +1 @@
+a802e06f1782a9645b9851bc7202cee74a8a4972
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/renames1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/renames1
new file mode 100755
index 0000000..3d24810
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/renames1
@@ -0,0 +1 @@
+412b32fb66137366147f1801ecc962452757d48a
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/renames2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/renames2
new file mode 100755
index 0000000..d226215
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/renames2
@@ -0,0 +1 @@
+ab40af3cb8a3ed2e2843e96d9aa7871336b94573
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/submodules b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/submodules
new file mode 100755
index 0000000..e5511ec
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/submodules
@@ -0,0 +1 @@
+d8dec75ff2f8b41d1c5bfef0cd57b7300c834f66
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/submodules-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/submodules-branch
new file mode 100755
index 0000000..7d47e07
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/submodules-branch
@@ -0,0 +1 @@
+811c70fcb6d5bbd022d04cc31836d30b436f9551
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/submodules-branch2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/submodules-branch2
new file mode 100755
index 0000000..ced60d8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/submodules-branch2
@@ -0,0 +1 @@
+7c04ca611203ed320c5f495b9813054dd23be3be
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-10 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-10
new file mode 100755
index 0000000..5b378cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-10
@@ -0,0 +1 @@
+0ec5f433959cd46177f745903353efb5be08d151
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-10-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-10-branch
new file mode 100755
index 0000000..b3db6c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-10-branch
@@ -0,0 +1 @@
+11f4f3c08b737f5fd896cbefa1425ee63b21b2fa
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-11 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-11
new file mode 100755
index 0000000..154de9a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-11
@@ -0,0 +1 @@
+3168dca1a561889b045a6441909f4c56145e666d
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-11-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-11-branch
new file mode 100755
index 0000000..2e41180
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-11-branch
@@ -0,0 +1 @@
+6718a45909532d1fcf5600d0877f7fe7e78f0b86
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-13 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-13
new file mode 100755
index 0000000..297573a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-13
@@ -0,0 +1 @@
+a3fabece9eb8748da810e1e08266fef9b7136ad4
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-13-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-13-branch
new file mode 100755
index 0000000..22e429a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-13-branch
@@ -0,0 +1 @@
+05f3c1a2a56ca95c3d2ef28dc9ddf32b5cd6c91c
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-14 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-14
new file mode 100755
index 0000000..8905185
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-14
@@ -0,0 +1 @@
+7e2d058d5fedf8329db44db4fac610d6b1a89159
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-14-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-14-branch
new file mode 100755
index 0000000..0158f95
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-14-branch
@@ -0,0 +1 @@
+8187117062b750eed4f93fd7e899f17b52ce554d
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-2alt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-2alt
new file mode 100755
index 0000000..4740741
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-2alt
@@ -0,0 +1 @@
+566ab53c220a2eafc1212af1a024513230280ab9
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-2alt-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-2alt-branch
new file mode 100755
index 0000000..2f5f1a4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-2alt-branch
@@ -0,0 +1 @@
+c9174cef549ec94ecbc43ef03cdc775b4950becb
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-3alt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-3alt
new file mode 100755
index 0000000..18e50ae
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-3alt
@@ -0,0 +1 @@
+4c9fac0707f8d4195037ae5a681aa48626491541
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-3alt-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-3alt-branch
new file mode 100755
index 0000000..7bc1a8d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-3alt-branch
@@ -0,0 +1 @@
+c607fc30883e335def28cd686b51f6cfa02b06ec
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-4
new file mode 100755
index 0000000..f49bbf9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-4
@@ -0,0 +1 @@
+cc3e3009134cb88014129fc8858d1101359e5e2f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-4-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-4-branch
new file mode 100755
index 0000000..bff519e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-4-branch
@@ -0,0 +1 @@
+183310e30fb1499af8c619108ffea4d300b5e778
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-5alt-1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-5alt-1
new file mode 100755
index 0000000..963a7b3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-5alt-1
@@ -0,0 +1 @@
+4fe93c0ec83eb6305cbace3dace88ecee1b63cb6
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-5alt-1-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-5alt-1-branch
new file mode 100755
index 0000000..4a22138
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-5alt-1-branch
@@ -0,0 +1 @@
+478172cb2f5ff9b514bc9d04d3bd5ef5840cb3b2
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-5alt-2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-5alt-2
new file mode 100755
index 0000000..aa4ada1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-5alt-2
@@ -0,0 +1 @@
+3b47b031b3e55ae11e14a05260b1c3ffd6838d55
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-5alt-2-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-5alt-2-branch
new file mode 100755
index 0000000..5553cdb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-5alt-2-branch
@@ -0,0 +1 @@
+f48097eb340dc5a7cae55aabcf1faf4548aa821f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-6
new file mode 100755
index 0000000..fb685bb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-6
@@ -0,0 +1 @@
+99b4f7e4f24470fa06b980bc21f1095c2a9425c0
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-6-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-6-branch
new file mode 100755
index 0000000..efc4c55
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-6-branch
@@ -0,0 +1 @@
+a43150a738849c59376cf30bb2a68348a83c8f48
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-7
new file mode 100755
index 0000000..9c94243
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-7
@@ -0,0 +1 @@
+d874671ef5b20184836cb983bb273e5280384d0b
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-7-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-7-branch
new file mode 100755
index 0000000..1762bb5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-7-branch
@@ -0,0 +1 @@
+5195a1b480f66691b667f10a9e41e70115a78351
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-8
new file mode 100755
index 0000000..837c491
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-8
@@ -0,0 +1 @@
+3575826c96a975031d2c14368529cc5c4353a8fd
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-8-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-8-branch
new file mode 100755
index 0000000..874230e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-8-branch
@@ -0,0 +1 @@
+52d8bc572af2b6d4ee0d5e62ed5d1fbad92210a9
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-9
new file mode 100755
index 0000000..b968a3e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-9
@@ -0,0 +1 @@
+c35dee9bcc0e989f3b0c40f68372a9a51b6c4e6a
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-9-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-9-branch
new file mode 100755
index 0000000..7f3097b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/trivial-9-branch
@@ -0,0 +1 @@
+13d1be4ea52a6ced1d7a1d832f0ee3c399348e5e
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/unrelated b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/unrelated
new file mode 100755
index 0000000..bb877be
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/.gitted/refs/heads/unrelated
@@ -0,0 +1 @@
+55b4e4687e7a0d9ca367016ed930f385d4022e6f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/added-in-master.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/added-in-master.txt
new file mode 100755
index 0000000..233c091
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/added-in-master.txt
@@ -0,0 +1 @@
+this file is added in master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/automergeable.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/automergeable.txt
new file mode 100755
index 0000000..ee3fa1b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/automergeable.txt
@@ -0,0 +1,9 @@
+this file is changed in master
+this file is automergeable
+this file is automergeable
+this file is automergeable
+this file is automergeable
+this file is automergeable
+this file is automergeable
+this file is automergeable
+this file is automergeable
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/changed-in-branch.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/changed-in-branch.txt
new file mode 100755
index 0000000..ab6c44a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/changed-in-branch.txt
@@ -0,0 +1 @@
+initial revision
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/changed-in-master.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/changed-in-master.txt
new file mode 100755
index 0000000..11deab0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/changed-in-master.txt
@@ -0,0 +1 @@
+changed in master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/conflicting.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/conflicting.txt
new file mode 100755
index 0000000..4e886e6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/conflicting.txt
@@ -0,0 +1 @@
+this file is changed in master and branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/removed-in-branch.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/removed-in-branch.txt
new file mode 100755
index 0000000..dfe3f22
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/removed-in-branch.txt
@@ -0,0 +1 @@
+this is removed in branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/unchanged.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/unchanged.txt
new file mode 100755
index 0000000..c8f06f2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-resolve/unchanged.txt
@@ -0,0 +1 @@
+this file is unchanged in both
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/config
new file mode 100755
index 0000000..6c9406b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/config
@@ -0,0 +1,7 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
+	precomposeunicode = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/index
new file mode 100755
index 0000000..534804a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/01/bd650462136a4f0a266dfc91ab93b3fef0f7cb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/01/bd650462136a4f0a266dfc91ab93b3fef0f7cb
new file mode 100755
index 0000000..074a77a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/01/bd650462136a4f0a266dfc91ab93b3fef0f7cb differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/08/3f868fb4324e32a4999173b2437b31d7a1ef25 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/08/3f868fb4324e32a4999173b2437b31d7a1ef25
new file mode 100755
index 0000000..ec6ed4d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/08/3f868fb4324e32a4999173b2437b31d7a1ef25 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/0a/a2acaa63cacc7a99fab0c2ce3d56572911df19 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/0a/a2acaa63cacc7a99fab0c2ce3d56572911df19
new file mode 100755
index 0000000..a2178ce
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/0a/a2acaa63cacc7a99fab0c2ce3d56572911df19
@@ -0,0 +1 @@
+xÍA @Qלbö&f€R!1ƝÑ[Lq°˜b#LÞÞ&z·ñ~œKÉ:àF*3gºžâ€¨½ó)qJZ&Bº™ˆ¤{;xk-2ή_78s-¹Ë»Ááñm÷S“šIhçrݼ·ÎÃ
¢Zëºþq{ûCÔå™%Ó¤>4ÿ?«
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/11/89e10a62aadf2fea8cd018afb52c1980f40b4f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/11/89e10a62aadf2fea8cd018afb52c1980f40b4f
new file mode 100755
index 0000000..f9f5984
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/11/89e10a62aadf2fea8cd018afb52c1980f40b4f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/24/2c8f6cf388e96e2c12b6e49cb7ae60167cba1e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/24/2c8f6cf388e96e2c12b6e49cb7ae60167cba1e
new file mode 100755
index 0000000..7cfc318
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/24/2c8f6cf388e96e2c12b6e49cb7ae60167cba1e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/25/246acb001858ffeffb03ea399fd2c0a163b832 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/25/246acb001858ffeffb03ea399fd2c0a163b832
new file mode 100755
index 0000000..f7160ce
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/25/246acb001858ffeffb03ea399fd2c0a163b832 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/26/2f67de0de2e535a59ae1bc3c739601e98c354d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/26/2f67de0de2e535a59ae1bc3c739601e98c354d
new file mode 100755
index 0000000..c5a33b4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/26/2f67de0de2e535a59ae1bc3c739601e98c354d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/2f/6727d2e570bf962d9dd926423cf6fe5072071a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/2f/6727d2e570bf962d9dd926423cf6fe5072071a
new file mode 100755
index 0000000..02bb788
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/2f/6727d2e570bf962d9dd926423cf6fe5072071a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/3c/43e7fc2a56fc825c31dfee65abd6dda8d16dca b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/3c/43e7fc2a56fc825c31dfee65abd6dda8d16dca
new file mode 100755
index 0000000..0ec95b5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/3c/43e7fc2a56fc825c31dfee65abd6dda8d16dca differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/40/26a6c83f39c56881c9ac62e7582db9e3d33a4f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/40/26a6c83f39c56881c9ac62e7582db9e3d33a4f
new file mode 100755
index 0000000..50bdfc5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/40/26a6c83f39c56881c9ac62e7582db9e3d33a4f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/42/dabb8d5dba2de103815a77e4369bb3966e64ef b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/42/dabb8d5dba2de103815a77e4369bb3966e64ef
new file mode 100755
index 0000000..ae6dab7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/42/dabb8d5dba2de103815a77e4369bb3966e64ef differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/43/9230587f2eb38e9540a5c99e9831f65641eab9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/43/9230587f2eb38e9540a5c99e9831f65641eab9
new file mode 100755
index 0000000..1b6354d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/43/9230587f2eb38e9540a5c99e9831f65641eab9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/43/ad73e75e15f03bb0b4398a48a57ecfc20788e2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/43/ad73e75e15f03bb0b4398a48a57ecfc20788e2
new file mode 100755
index 0000000..1936bc3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/43/ad73e75e15f03bb0b4398a48a57ecfc20788e2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904
new file mode 100755
index 0000000..adf6411
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/54/74989173042512ab630191ad71cdcedb646b9a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/54/74989173042512ab630191ad71cdcedb646b9a
new file mode 100755
index 0000000..cf12d4d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/54/74989173042512ab630191ad71cdcedb646b9a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/5e/fb9bc29c482e023e40e0a2b3b7e49cec842034 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/5e/fb9bc29c482e023e40e0a2b3b7e49cec842034
new file mode 100755
index 0000000..d615c02
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/5e/fb9bc29c482e023e40e0a2b3b7e49cec842034 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/70/d3d2e7d51a18fcc6f035a67e5c3f33069be04d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/70/d3d2e7d51a18fcc6f035a67e5c3f33069be04d
new file mode 100755
index 0000000..1718878
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/70/d3d2e7d51a18fcc6f035a67e5c3f33069be04d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/74/e83b6c5df14f1fba7c4ea1f99c6d007b591002 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/74/e83b6c5df14f1fba7c4ea1f99c6d007b591002
new file mode 100755
index 0000000..779e1bc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/74/e83b6c5df14f1fba7c4ea1f99c6d007b591002 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/77/f40c621ceae77ad8d756ef507bdbafe2713aa7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/77/f40c621ceae77ad8d756ef507bdbafe2713aa7
new file mode 100755
index 0000000..f2efa93
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/77/f40c621ceae77ad8d756ef507bdbafe2713aa7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/9c/5362069759fb37ae036cef6e4b2f95c6c5eaab b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/9c/5362069759fb37ae036cef6e4b2f95c6c5eaab
new file mode 100755
index 0000000..cc6ad10
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/9c/5362069759fb37ae036cef6e4b2f95c6c5eaab differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/a2/9e7dabd68dfb38a717e6b1648713cd5c7adee2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/a2/9e7dabd68dfb38a717e6b1648713cd5c7adee2
new file mode 100755
index 0000000..6e03437
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/a2/9e7dabd68dfb38a717e6b1648713cd5c7adee2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/a4/e6a86e07ef5afe036e26602fbbaa27496d00a9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/a4/e6a86e07ef5afe036e26602fbbaa27496d00a9
new file mode 100755
index 0000000..95e0d71
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/a4/e6a86e07ef5afe036e26602fbbaa27496d00a9
@@ -0,0 +1,2 @@
+x¥MJÄ@…]÷)j7A:Ý]ý"îÁ3U5Õ“I´ÓYx{#£'põà㽞¬ó<uðC¼ëM‚§KòšP¬Ö3[¾d
+™0©Tq6å¬Î|PÓ¥CôÑÙX–Ê>‘ZEkÔÀ®”(¨Dü×çªA	³EªÎòP‚Êkô!äXsí}\¼’|îºÁ‹¶yÚÆýkƒÇ÷»>o½MÔéAÖù	†ϱLî­³Öô¸Öõ_ó¦íªÀátË3Ÿ`Zúú‹Ïd¾“AeÏ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/a8/27eab4fd66ab37a6ebcfaa7b7e341abfd55947 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/a8/27eab4fd66ab37a6ebcfaa7b7e341abfd55947
new file mode 100755
index 0000000..fe2bdf4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/a8/27eab4fd66ab37a6ebcfaa7b7e341abfd55947 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/a9/66acc271e50b5d4595911752a77def0a5e5d40 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/a9/66acc271e50b5d4595911752a77def0a5e5d40
new file mode 100755
index 0000000..cd6f64d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/a9/66acc271e50b5d4595911752a77def0a5e5d40 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/b2/a69114f4897109fedf1aafea363cb2d2557029 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/b2/a69114f4897109fedf1aafea363cb2d2557029
new file mode 100755
index 0000000..b95a7be
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/b2/a69114f4897109fedf1aafea363cb2d2557029 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/bc/83ac0422ba1082c80e406234910377984cfbb6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/bc/83ac0422ba1082c80e406234910377984cfbb6
new file mode 100755
index 0000000..0ea77e8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/bc/83ac0422ba1082c80e406234910377984cfbb6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/bf/e4ea5805af22a5b194259bda6f5f634486f891 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/bf/e4ea5805af22a5b194259bda6f5f634486f891
new file mode 100755
index 0000000..a27169e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/bf/e4ea5805af22a5b194259bda6f5f634486f891
@@ -0,0 +1 @@
+x¥MjÃ0F»Ö)f’lýA)%›B/Ðõx4®°•Jcho_‡!Û÷àã}T×µX?¾Hc´‰CÆ)û˜çiˆL`??Æ`ÊŽff«nØxЈ	Ñ„t¸”fœ4Yâ!;ï‚MÆäÙ$…»,µÁ'ÒÏÎ>¸­¥/û_‡×ëƒ}¿wiÏT×70£u)FïF8i«µ:è‘*üÔˆúZŠp¿!1Ìå÷(Á-ÕMîoêõzX 
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/c3/b1fb31424c98072542cc8e42b48c92e52f494a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/c3/b1fb31424c98072542cc8e42b48c92e52f494a
new file mode 100755
index 0000000..4006460
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/c3/b1fb31424c98072542cc8e42b48c92e52f494a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/c7/e2f386736445936f5ba181269a0e0967e280e8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/c7/e2f386736445936f5ba181269a0e0967e280e8
new file mode 100755
index 0000000..821336f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/c7/e2f386736445936f5ba181269a0e0967e280e8
@@ -0,0 +1,2 @@
+x¥AjÃ0E»Ö)f—E¡È’FA)Ù
+=C˜QF±¶Y^ôöMI{‚®><>^Yçyêà‡øЛ*Ïçä5¡X­±|&Ę´Ôâl"Rg>¹éÒ!ôÑÙ˜æ*>±Z‹Ö¨A\ÍXbAe–¿¿T
ÊH¹:Ç(C³œ9V¬Ñ‡@±Rï}\¼q¹îºÁ«¶yÚÆýkƒç;»·Þ&îüTÖù†¡…Gë¬57zKëú/‰y×vQÆKápß“`Zúú‹Ol¾$eÅ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/d9/5182053c31f8aa09df4fa225f4e668c5320b59 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/d9/5182053c31f8aa09df4fa225f4e668c5320b59
new file mode 100755
index 0000000..6b9483a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/d9/5182053c31f8aa09df4fa225f4e668c5320b59
@@ -0,0 +1,5 @@
+x¥ÎM
+Â0@a×9Åì™$M›€ˆ®/àz:™Ø
+ý1IÞ^Á#¸ýÇË4Œ³»šE Ãh£‘.:MÚ'æ6¡uÔvâØ&k±
½`ÕJYæ
+Zû ©5D1™$ä9¢ö”zgX©Á¾IŠ¶:,nįM
+\%Oc¶wãógs©y¤J^¦èƸàCç,ìÑ ª¯~W«üQ÷a¬RVbh~,3\ÔgäRý
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100755
index 0000000..7112238
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/ec/5a35c75b8d3ee29bed37996b14e909d04fdcee b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/ec/5a35c75b8d3ee29bed37996b14e909d04fdcee
new file mode 100755
index 0000000..d7fc301
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/ec/5a35c75b8d3ee29bed37996b14e909d04fdcee differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/ee/3c2aac8e03224c323b58ecb1f9eef616745467 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/ee/3c2aac8e03224c323b58ecb1f9eef616745467
new file mode 100755
index 0000000..1acec06
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/ee/3c2aac8e03224c323b58ecb1f9eef616745467 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/ef/e94a4bf4e697f7f0270f0d1b8a93af784a19d0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/ef/e94a4bf4e697f7f0270f0d1b8a93af784a19d0
new file mode 100755
index 0000000..ca5af40
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/ef/e94a4bf4e697f7f0270f0d1b8a93af784a19d0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/f0/0c965d8307308469e537302baa73048488f162 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/f0/0c965d8307308469e537302baa73048488f162
new file mode 100755
index 0000000..343037e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/f0/0c965d8307308469e537302baa73048488f162 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/f1/90a0d111ca1688778657798743ddfb4ed4bd64 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/f1/90a0d111ca1688778657798743ddfb4ed4bd64
new file mode 100755
index 0000000..4e22912
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/f1/90a0d111ca1688778657798743ddfb4ed4bd64
@@ -0,0 +1,2 @@
+x¥ÎM
+Â0@a×9Eö‚äošˆ.o1I¦Z!¦éÂÛ[ðn¿Åã¥ZÊÔ¥±a׳äd!yˆ![fƒ‘³õˆCÔŽQaVn̉Y¼¨ñÜ%á0PJÆk!;@@­=ò>ó¨xS%híÚäÒ{åE^¹•iy¬ŸEŸ?»Ÿ—Þ&êtHµœ¤v0g¬Ü+£”Øt[íüWD\êÜ·qñÃMØ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/f4/9b2c244e9d3b0647fdfb95954c38fbfeecf3ad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/f4/9b2c244e9d3b0647fdfb95954c38fbfeecf3ad
new file mode 100755
index 0000000..437f667
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/f4/9b2c244e9d3b0647fdfb95954c38fbfeecf3ad
@@ -0,0 +1,2 @@
+x¥Í=
+1@aëœbzAf‡Iœ€ˆà-’ì¬!,æ§ðö.xÛ¯x/m¥ä“СWUà(dçä˜Rt}@‡j9.2;O"KTelÂèëVáÒ{hƒ»Ö’Û:>
.¯Ÿ=o­×z8¥­\ab²^ÄžŽHˆf×}Ýõ¯ˆùR<ì
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/f8/7905f99f0e66d179a8379d8ca4d8cbbd32c231 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/f8/7905f99f0e66d179a8379d8ca4d8cbbd32c231
new file mode 100755
index 0000000..d568dc1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/objects/f8/7905f99f0e66d179a8379d8ca4d8cbbd32c231
@@ -0,0 +1 @@
+x¥KjÄ0D³ö)´›E tëg5„0»@ g0-©e;`;#Ë‹Ü>†™œ «‚WEQ•¶e™›2žZQÎö–aoÀj‡š£7€„œ{L9IŽÞúHÜ}s•µ©Lƒg’Á˜r±…µvÅŠ÷!9£!:úËGÍžm±z*’2aãMŠ:kçzÐÔñѦ­ªN·Cvõ.u™÷éøÙÕëם×½Õ™¿¤mySxî=—ãÕ3h€î¤çµ&ÿ*é>¥Ž¢bå5Mêr×!iâu”‹š×¶=܁´û´Äià
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/refs/heads/branch_a_change b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/refs/heads/branch_a_change
new file mode 100755
index 0000000..3a46eff
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/refs/heads/branch_a_change
@@ -0,0 +1 @@
+d95182053c31f8aa09df4fa225f4e668c5320b59
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/refs/heads/branch_a_eol b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/refs/heads/branch_a_eol
new file mode 100755
index 0000000..a59d5b5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/refs/heads/branch_a_eol
@@ -0,0 +1 @@
+9c5362069759fb37ae036cef6e4b2f95c6c5eaab
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/refs/heads/branch_b_change b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/refs/heads/branch_b_change
new file mode 100755
index 0000000..c14ced3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/refs/heads/branch_b_change
@@ -0,0 +1 @@
+b2a69114f4897109fedf1aafea363cb2d2557029
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/refs/heads/branch_b_eol b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/refs/heads/branch_b_eol
new file mode 100755
index 0000000..9e25c6e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/refs/heads/branch_b_eol
@@ -0,0 +1 @@
+bfe4ea5805af22a5b194259bda6f5f634486f891
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/refs/heads/master
new file mode 100755
index 0000000..61e8ae7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/.gitted/refs/heads/master
@@ -0,0 +1 @@
+1189e10a62aadf2fea8cd018afb52c1980f40b4f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/test.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/test.txt
new file mode 100755
index 0000000..74e83b6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/merge-whitespace/test.txt
@@ -0,0 +1,11 @@
+0
+1
+2
+3
+4
+5 XXX
+6
+7
+8
+9
+10
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/COMMIT_EDITMSG b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/COMMIT_EDITMSG
new file mode 100755
index 0000000..1f7391f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/COMMIT_EDITMSG
@@ -0,0 +1 @@
+master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/MERGE_HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/MERGE_HEAD
new file mode 100755
index 0000000..a5bdf6e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/MERGE_HEAD
@@ -0,0 +1 @@
+e2809157a7766f272e4cfe26e61ef2678a5357ff
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/MERGE_MODE b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/MERGE_MODE
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/MERGE_MSG b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/MERGE_MSG
new file mode 100755
index 0000000..7c4d1f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/MERGE_MSG
@@ -0,0 +1,5 @@
+Merge branch 'branch'
+
+Conflicts:
+	conflicts-one.txt
+	conflicts-two.txt
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/ORIG_HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/ORIG_HEAD
new file mode 100755
index 0000000..13d4d67
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/ORIG_HEAD
@@ -0,0 +1 @@
+3a34580a35add43a4cf361e8e9a30060a905c876
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/config
new file mode 100755
index 0000000..af10792
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/config
@@ -0,0 +1,6 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/index
new file mode 100755
index 0000000..3d29f78
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/logs/HEAD
new file mode 100755
index 0000000..a385da6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/logs/HEAD
@@ -0,0 +1,5 @@
+0000000000000000000000000000000000000000 9a05ccb4e0f948de03128e095f39dae6976751c5 Edward Thomson <ethomson at edwardthomson.com> 1351371828 -0500	commit (initial): initial
+9a05ccb4e0f948de03128e095f39dae6976751c5 9a05ccb4e0f948de03128e095f39dae6976751c5 Edward Thomson <ethomson at edwardthomson.com> 1351371835 -0500	checkout: moving from master to branch
+9a05ccb4e0f948de03128e095f39dae6976751c5 e2809157a7766f272e4cfe26e61ef2678a5357ff Edward Thomson <ethomson at edwardthomson.com> 1351371872 -0500	commit: branch
+e2809157a7766f272e4cfe26e61ef2678a5357ff 9a05ccb4e0f948de03128e095f39dae6976751c5 Edward Thomson <ethomson at edwardthomson.com> 1351371873 -0500	checkout: moving from branch to master
+9a05ccb4e0f948de03128e095f39dae6976751c5 3a34580a35add43a4cf361e8e9a30060a905c876 Edward Thomson <ethomson at edwardthomson.com> 1351372106 -0500	commit: master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/logs/refs/heads/branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/logs/refs/heads/branch
new file mode 100755
index 0000000..26a5e8d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/logs/refs/heads/branch
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 9a05ccb4e0f948de03128e095f39dae6976751c5 Edward Thomson <ethomson at edwardthomson.com> 1351371835 -0500	branch: Created from HEAD
+9a05ccb4e0f948de03128e095f39dae6976751c5 e2809157a7766f272e4cfe26e61ef2678a5357ff Edward Thomson <ethomson at edwardthomson.com> 1351371872 -0500	commit: branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..425f7bd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/logs/refs/heads/master
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 9a05ccb4e0f948de03128e095f39dae6976751c5 Edward Thomson <ethomson at edwardthomson.com> 1351371828 -0500	commit (initial): initial
+9a05ccb4e0f948de03128e095f39dae6976751c5 3a34580a35add43a4cf361e8e9a30060a905c876 Edward Thomson <ethomson at edwardthomson.com> 1351372106 -0500	commit: master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/03/db1d37504ca0c4f7c26d7776b0e28bdea08712 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/03/db1d37504ca0c4f7c26d7776b0e28bdea08712
new file mode 100755
index 0000000..9232f79
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/03/db1d37504ca0c4f7c26d7776b0e28bdea08712 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/17/0efc1023e0ed2390150bb4469c8456b63e8f91 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/17/0efc1023e0ed2390150bb4469c8456b63e8f91
new file mode 100755
index 0000000..3e124d9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/17/0efc1023e0ed2390150bb4469c8456b63e8f91 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/1f/85ca51b8e0aac893a621b61a9c2661d6aa6d81 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/1f/85ca51b8e0aac893a621b61a9c2661d6aa6d81
new file mode 100755
index 0000000..7bb19c8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/1f/85ca51b8e0aac893a621b61a9c2661d6aa6d81 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/22/0bd62631c8cf7a83ef39c6b94595f00517211e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/22/0bd62631c8cf7a83ef39c6b94595f00517211e
new file mode 100755
index 0000000..487bcff
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/22/0bd62631c8cf7a83ef39c6b94595f00517211e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/32/d55d59265db86dd690f0a7fc563db43e2bc6a6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/32/d55d59265db86dd690f0a7fc563db43e2bc6a6
new file mode 100755
index 0000000..2eb3954
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/32/d55d59265db86dd690f0a7fc563db43e2bc6a6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/38/e2d82b9065a237904af4b780b4d68da6950534 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/38/e2d82b9065a237904af4b780b4d68da6950534
new file mode 100755
index 0000000..ebe83cc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/38/e2d82b9065a237904af4b780b4d68da6950534 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/3a/34580a35add43a4cf361e8e9a30060a905c876 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/3a/34580a35add43a4cf361e8e9a30060a905c876
new file mode 100755
index 0000000..0d4095f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/3a/34580a35add43a4cf361e8e9a30060a905c876
@@ -0,0 +1,2 @@
+x¥ŽK
+1D]ç}¥óíDÜx/Oã"F2¯ooà®ê<*·Zo”‘»Ñ™uI²h²hrÄlÊÊ"r	YùT8¢'©Ä#v¾mÎÉ0.Áø¨¥òŒÁ.:”È.#+³ñ9ÖÖáR^±¸®­níGžô“Îü~í[=ÔVjRìÑ"ŠIçÙÁjDÛ”ˆ7|N`
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/44/58b8bc9e72b6c8755ae456f60e9844d0538d8c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/44/58b8bc9e72b6c8755ae456f60e9844d0538d8c
new file mode 100755
index 0000000..33389c3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/44/58b8bc9e72b6c8755ae456f60e9844d0538d8c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/47/8871385b9cd03908c5383acfd568bef023c6b3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/47/8871385b9cd03908c5383acfd568bef023c6b3
new file mode 100755
index 0000000..5361ea6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/47/8871385b9cd03908c5383acfd568bef023c6b3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/51/6bd85f78061e09ccc714561d7b504672cb52da b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/51/6bd85f78061e09ccc714561d7b504672cb52da
new file mode 100755
index 0000000..a60da87
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/51/6bd85f78061e09ccc714561d7b504672cb52da differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/53/c1d95a01f4514b162066fc98564500c96c46ad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/53/c1d95a01f4514b162066fc98564500c96c46ad
new file mode 100755
index 0000000..85e84d7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/53/c1d95a01f4514b162066fc98564500c96c46ad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/6a/ea5f295304c36144ad6e9247a291b7f8112399 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/6a/ea5f295304c36144ad6e9247a291b7f8112399
new file mode 100755
index 0000000..b16b521
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/6a/ea5f295304c36144ad6e9247a291b7f8112399 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/70/68e30a7f0090ae32db35dfa1e4189d8780fcb8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/70/68e30a7f0090ae32db35dfa1e4189d8780fcb8
new file mode 100755
index 0000000..7c4e85f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/70/68e30a7f0090ae32db35dfa1e4189d8780fcb8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/75/938de1e367098b3e9a7b1ec3c4ac4548afffe4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/75/938de1e367098b3e9a7b1ec3c4ac4548afffe4
new file mode 100755
index 0000000..65173fc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/75/938de1e367098b3e9a7b1ec3c4ac4548afffe4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/7b/26923aaf452b1977eb08617c59475fb3f74b71 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/7b/26923aaf452b1977eb08617c59475fb3f74b71
new file mode 100755
index 0000000..162fa44
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/7b/26923aaf452b1977eb08617c59475fb3f74b71 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/84/af62840be1b1c47b778a8a249f3ff45155038c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/84/af62840be1b1c47b778a8a249f3ff45155038c
new file mode 100755
index 0000000..77a519f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/84/af62840be1b1c47b778a8a249f3ff45155038c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/88/71f7a2ee3addfc4ba39fbd0783c8e738d04cda b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/88/71f7a2ee3addfc4ba39fbd0783c8e738d04cda
new file mode 100755
index 0000000..f624cd4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/88/71f7a2ee3addfc4ba39fbd0783c8e738d04cda differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/88/7b153b165d32409c70163e0f734c090f12f673 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/88/7b153b165d32409c70163e0f734c090f12f673
new file mode 100755
index 0000000..096474c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/88/7b153b165d32409c70163e0f734c090f12f673 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/8a/ad34cc83733590e74b93d0f7cf00375e2a735a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/8a/ad34cc83733590e74b93d0f7cf00375e2a735a
new file mode 100755
index 0000000..a413bc6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/8a/ad34cc83733590e74b93d0f7cf00375e2a735a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/8b/3f43d2402825c200f835ca1762413e386fd0b2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/8b/3f43d2402825c200f835ca1762413e386fd0b2
new file mode 100755
index 0000000..3ac8f60
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/8b/3f43d2402825c200f835ca1762413e386fd0b2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/8b/72416545c7e761b64cecad4f1686eae4078aa8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/8b/72416545c7e761b64cecad4f1686eae4078aa8
new file mode 100755
index 0000000..589a5ae
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/8b/72416545c7e761b64cecad4f1686eae4078aa8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/8f/3c06cff9a83757cec40c80bc9bf31a2582bde9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/8f/3c06cff9a83757cec40c80bc9bf31a2582bde9
new file mode 100755
index 0000000..6503985
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/8f/3c06cff9a83757cec40c80bc9bf31a2582bde9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/8f/fcc405925511824a2240a6d3686aa7f8c7ac50 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/8f/fcc405925511824a2240a6d3686aa7f8c7ac50
new file mode 100755
index 0000000..2eaa808
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/8f/fcc405925511824a2240a6d3686aa7f8c7ac50 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/9a/05ccb4e0f948de03128e095f39dae6976751c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/9a/05ccb4e0f948de03128e095f39dae6976751c5
new file mode 100755
index 0000000..7373a80
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/9a/05ccb4e0f948de03128e095f39dae6976751c5
@@ -0,0 +1 @@
+x¥Ñ
!Dý¦Šm@³ËÉÅøc6Àq#‘#AŒí‹Æü›y/™	µ”܁œ:ô#$–l•tH:é—„*D³XÖh¬VœáŸ}«
®ëË·n[-ºÃý¤KüŠ_;…ZÎ@“¦‰ÉJGÔˆbÐqÞãŸ3"ï¹goŒ«@I
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/9d/81f82fccc7dcd7de7a1ffead1815294c2e092c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/9d/81f82fccc7dcd7de7a1ffead1815294c2e092c
new file mode 100755
index 0000000..c5a651f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/9d/81f82fccc7dcd7de7a1ffead1815294c2e092c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/b7/cedb8ad4cbb22b6363f9578cbd749797f7ef0d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/b7/cedb8ad4cbb22b6363f9578cbd749797f7ef0d
new file mode 100755
index 0000000..3e14b5d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/b7/cedb8ad4cbb22b6363f9578cbd749797f7ef0d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/d0/1885ea594926eae9ba5b54ad76692af5969f51 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/d0/1885ea594926eae9ba5b54ad76692af5969f51
new file mode 100755
index 0000000..a641adc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/d0/1885ea594926eae9ba5b54ad76692af5969f51 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/e2/809157a7766f272e4cfe26e61ef2678a5357ff b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/e2/809157a7766f272e4cfe26e61ef2678a5357ff
new file mode 100755
index 0000000..fa86662
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/e2/809157a7766f272e4cfe26e61ef2678a5357ff
@@ -0,0 +1,3 @@
+x¥ŽK
+1D]ç¹€Òùt> âÆxžN‡q1‰¯ï(ÞÀ]Õ{P·e¹
m½Ù.¢S­Ì0[Dc’õd­
+Å…ˆbM‰ԝº¬Cgdž¼@Í>glÈX].$!ÇÑ0*zŽ¹u})/êE_ç¶<Úª²ÑO:ËWüځÛrÒÆ¡qѤhõ@mt;;äÏ5uZyVoÓ\Mÿ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/e6/2cac5c88b9928f2695b934c70efa4285324478 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/e6/2cac5c88b9928f2695b934c70efa4285324478
new file mode 100755
index 0000000..c9841c6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/e6/2cac5c88b9928f2695b934c70efa4285324478 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/f7/2784290c151092abf04ce6b875068547f70406 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/f7/2784290c151092abf04ce6b875068547f70406
new file mode 100755
index 0000000..cd587db
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/objects/f7/2784290c151092abf04ce6b875068547f70406 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/refs/heads/branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/refs/heads/branch
new file mode 100755
index 0000000..a5bdf6e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/refs/heads/branch
@@ -0,0 +1 @@
+e2809157a7766f272e4cfe26e61ef2678a5357ff
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/refs/heads/master
new file mode 100755
index 0000000..13d4d67
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/.gitted/refs/heads/master
@@ -0,0 +1 @@
+3a34580a35add43a4cf361e8e9a30060a905c876
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/conflicts-one.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/conflicts-one.txt
new file mode 100755
index 0000000..8aad34c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/conflicts-one.txt
@@ -0,0 +1,5 @@
+<<<<<<< HEAD
+This is most certainly a conflict!
+=======
+This is a conflict!!!
+>>>>>>> branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/conflicts-two.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/conflicts-two.txt
new file mode 100755
index 0000000..e62cac5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/conflicts-two.txt
@@ -0,0 +1,5 @@
+<<<<<<< HEAD
+This is without question another conflict!
+=======
+This is another conflict!!!
+>>>>>>> branch
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/one.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/one.txt
new file mode 100755
index 0000000..75938de
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/one.txt
@@ -0,0 +1,10 @@
+This is file one!
+This is file one.
+This is file one.
+This is file one.
+This is file one.
+This is file one.
+This is file one.
+This is file one.
+This is file one.
+This is file one!
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/two.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/two.txt
new file mode 100755
index 0000000..7b26923
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/mergedrepo/two.txt
@@ -0,0 +1,12 @@
+This is file two!
+This is file two.
+This is file two.
+This is file two.
+This is file two.
+This is file two.
+This is file two.
+This is file two.
+This is file two.
+This is file two.
+This is file two.
+This is file two!
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/index
new file mode 100755
index 0000000..782a50d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/02/28b21d477f67b9f7720565da9e760b84c8b85b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/02/28b21d477f67b9f7720565da9e760b84c8b85b
new file mode 100755
index 0000000..e7cd63a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/02/28b21d477f67b9f7720565da9e760b84c8b85b
@@ -0,0 +1,3 @@
+x¥]
+!…{vw
^Gˆè¥Ô½b#8F´û,ÚAoç|œj)·èä®7"ˆAÚ ji±&ôÁ.(q¶ÉIg¼vBYæ=×çøô-Â5ײÕ4è'è+~m
+µ§Älì¹æœ
:Î;ý9Ã.w¿å×ôõ’@õ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/04/18f28a75dc0c4951c01842e0d794843a88178a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/04/18f28a75dc0c4951c01842e0d794843a88178a
new file mode 100755
index 0000000..7f8722e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/04/18f28a75dc0c4951c01842e0d794843a88178a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/04/fab819d8388295cbe3496310e4e53ef8f4a115 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/04/fab819d8388295cbe3496310e4e53ef8f4a115
new file mode 100755
index 0000000..688b970
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/04/fab819d8388295cbe3496310e4e53ef8f4a115 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/05/1229bf9d30ec923052ff42db8069ccdc17159d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/05/1229bf9d30ec923052ff42db8069ccdc17159d
new file mode 100755
index 0000000..4321601
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/05/1229bf9d30ec923052ff42db8069ccdc17159d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/09/9ed86cb8501ae483b1855c351fe1a506ac9631 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/09/9ed86cb8501ae483b1855c351fe1a506ac9631
new file mode 100755
index 0000000..7738fc8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/09/9ed86cb8501ae483b1855c351fe1a506ac9631 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/0a/78e40e54cc471c0415ca0680550f242e7843e2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/0a/78e40e54cc471c0415ca0680550f242e7843e2
new file mode 100755
index 0000000..d59836e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/0a/78e40e54cc471c0415ca0680550f242e7843e2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/0b/8206dd72a3b3b932fb562f92d29199b9398390 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/0b/8206dd72a3b3b932fb562f92d29199b9398390
new file mode 100755
index 0000000..b063615
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/0b/8206dd72a3b3b932fb562f92d29199b9398390 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/0d/45fb57852c2229346a800bd3fc58e32527a21c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/0d/45fb57852c2229346a800bd3fc58e32527a21c
new file mode 100755
index 0000000..d0433a0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/0d/45fb57852c2229346a800bd3fc58e32527a21c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/10/cb44a89d1a9e8bf74de3f11a2a61ee833f13b1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/10/cb44a89d1a9e8bf74de3f11a2a61ee833f13b1
new file mode 100755
index 0000000..9d14298
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/10/cb44a89d1a9e8bf74de3f11a2a61ee833f13b1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/11/9f6cd3535de0e2a15654947a7b1a5affbf1406 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/11/9f6cd3535de0e2a15654947a7b1a5affbf1406
new file mode 100755
index 0000000..fb03b26
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/11/9f6cd3535de0e2a15654947a7b1a5affbf1406 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/12/12c12915820e1ad523b6305c0dcdefea8b7e97 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/12/12c12915820e1ad523b6305c0dcdefea8b7e97
new file mode 100755
index 0000000..95bc4c8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/12/12c12915820e1ad523b6305c0dcdefea8b7e97
@@ -0,0 +1 @@
+x¥Q Dýæ{¶P ‰1þx½ÀÛ`"%¡ãíEã
ü›y/™	%ç[œÕ®Uf°Q³r£v–Æ-Þ)oó„„ÁXM‹£ GK¥Â9>©F¸¦’·²Â;ý¤ů
¡ä# F3+«q„½œ¤öóÆΈ˝¶ôÞVAž
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/13/e5f8be09e8b7db074fb39b96e08215cc4a36f1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/13/e5f8be09e8b7db074fb39b96e08215cc4a36f1
new file mode 100755
index 0000000..ea54830
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/13/e5f8be09e8b7db074fb39b96e08215cc4a36f1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/14/e70ab559b4c6a8a6fc9b6f538bd1f3934be725 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/14/e70ab559b4c6a8a6fc9b6f538bd1f3934be725
new file mode 100755
index 0000000..371951a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/14/e70ab559b4c6a8a6fc9b6f538bd1f3934be725 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/15/f7d9f9514eeb65b9588c49b10b1da145a729a2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/15/f7d9f9514eeb65b9588c49b10b1da145a729a2
new file mode 100755
index 0000000..a7f3683
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/15/f7d9f9514eeb65b9588c49b10b1da145a729a2
@@ -0,0 +1,2 @@
+x1Â0E™s
+ïH(iÚº‘baeâ&q”Á(5BÜžpÞôõ†ÿ¢Ôº*¸`wÚ˜Ñ“3ºìÝC”‡œ1øepB²>»™
½´HƒKzSKp+R7yÀ‘»ý­s]c“M²¢Ô¸ÁÓŒK€½í˜.{Wùÿs¥M?P)“´|?ó
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/16/35c47d80914f0abfa43dd4234a948db5bdb107 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/16/35c47d80914f0abfa43dd4234a948db5bdb107
new file mode 100755
index 0000000..f82b82b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/16/35c47d80914f0abfa43dd4234a948db5bdb107
@@ -0,0 +1,2 @@
+x=!…­9Åô&–Ÿ…Ä[+/ÀÝgcŒ·¯àkÞËW|/Q­ƒ
+òÀ
¼œŒ±gD’±®d?*k† ÝRœÒ‹ñÅ+5¸åwl+ÕNO8ã ¿u­[jÔ©ð)Q½€šôÍ>ÀQŽˆÇ/ãÿq?Pc‚=òú¼Õ?q
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/16/a701796bc3670e5c2fdaeccb7f1280c60b373f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/16/a701796bc3670e5c2fdaeccb7f1280c60b373f
new file mode 100755
index 0000000..46ed5c1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/16/a701796bc3670e5c2fdaeccb7f1280c60b373f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/19/1381ee74dec49c89f99a62d055cb1058ba0de9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/19/1381ee74dec49c89f99a62d055cb1058ba0de9
new file mode 100755
index 0000000..f1619a2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/19/1381ee74dec49c89f99a62d055cb1058ba0de9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/1e/3c845808fa5883aa4bcf2f882172edb72a7a32 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/1e/3c845808fa5883aa4bcf2f882172edb72a7a32
new file mode 100755
index 0000000..e25f153
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/1e/3c845808fa5883aa4bcf2f882172edb72a7a32
@@ -0,0 +1,2 @@
+x¥Q Dýæ{›eaiIŒñÇè(Ð`"%¡ãíEã
ü›y/™ñ%ç[iÕ®ÕƒæeæqbòDd•6nBœƒZ<OQÓèHzá-•
+çðt5À5•¼•±ÓO:ůøµÁ—|©¥±Z‹°GFöóÿœ—»ÛÒkx›\@|
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/24/676d5e93f9fa7b568f38d7bce01772908e982b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/24/676d5e93f9fa7b568f38d7bce01772908e982b
new file mode 100755
index 0000000..fc11c20
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/24/676d5e93f9fa7b568f38d7bce01772908e982b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/26/b665c162f67acae67779445f3c7b9782b0a6d7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/26/b665c162f67acae67779445f3c7b9782b0a6d7
new file mode 100755
index 0000000..6e1a85c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/26/b665c162f67acae67779445f3c7b9782b0a6d7
@@ -0,0 +1 @@
+x¥Q Dýæ{›…‰1þx½À–Ò`"%¡ãíEã
ü›y/™	%ç[éÇ]«1-^éÀ#YB^m ÖN²ÒŽ&RnR¥3,øÑR©pžŸ\g¸¦’·²Â!vúI§ø¿6„’ µ$Th½=DÑi?oñÏq¹ó–^ÿx@¢
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/27/db66b046536a0e4f64c4f8c3a490641c3fa5e5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/27/db66b046536a0e4f64c4f8c3a490641c3fa5e5
new file mode 100755
index 0000000..10b555b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/27/db66b046536a0e4f64c4f8c3a490641c3fa5e5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/2b/4b774d8c5441b22786531f34ffc77800cda8cf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/2b/4b774d8c5441b22786531f34ffc77800cda8cf
new file mode 100755
index 0000000..b286daa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/2b/4b774d8c5441b22786531f34ffc77800cda8cf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/2d/23d51590ec2f53fe4b5bb3e5ca62e35e4ef85a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/2d/23d51590ec2f53fe4b5bb3e5ca62e35e4ef85a
new file mode 100755
index 0000000..5d47d82
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/2d/23d51590ec2f53fe4b5bb3e5ca62e35e4ef85a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/35/ae236308929a536fb4e852278a9b98c42babb3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/35/ae236308929a536fb4e852278a9b98c42babb3
new file mode 100755
index 0000000..b8633de
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/35/ae236308929a536fb4e852278a9b98c42babb3
@@ -0,0 +1 @@
+x;Â0©}Ší‘q	!Z*.àÏZIa6²!n¹S=Mñ&Q­ƒZä"x…:zë-ÊaÌÚOÑØ £B?cŒV›´‘"¼x¥·ü-Ãc¥Úé	gö·®uK:>%ªPÚØÉÍ~£ˆ!G—ñÿq?PC‚=ðúª?Ü
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/38/0b9e58872ccf1d858be4b0fc612514a080bc40 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/38/0b9e58872ccf1d858be4b0fc612514a080bc40
new file mode 100755
index 0000000..a911c3c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/38/0b9e58872ccf1d858be4b0fc612514a080bc40 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/39/fb3af508440cf970b92767f6d081c811574d2a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/39/fb3af508440cf970b92767f6d081c811574d2a
new file mode 100755
index 0000000..3854748
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/39/fb3af508440cf970b92767f6d081c811574d2a
@@ -0,0 +1,2 @@
+x¥=
+B1„­sŠíÉÏ&® b#bÿ.³ûxq!F¼¾Q¼SÍ|3Ek½up;\õ&‘Î甸pò9X‰8²˜bºz»
&?û¢
NüʍaZ´>ô{ôãŽò-~iS´À¡KDÖ¢‡µ2ƒŽó.ÎÖçËdÞΤ?ï
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/3b/24e5c751ee9c7c89df32a0d959748aa3d0112c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/3b/24e5c751ee9c7c89df32a0d959748aa3d0112c
new file mode 100755
index 0000000..5adcd14
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/3b/24e5c751ee9c7c89df32a0d959748aa3d0112c
@@ -0,0 +1,2 @@
+x1Â0E™s
+ïHÈmš&•baeâ&‰ÕÁ(1BÜžpþôô†÷£”²)î´æ!ÌÙ±Ðù¦¹£#tœ˜)Y;Þ#z4ôÒU*\Ò›j‚Û*¥ÉŽ¹ÛË«4a=D)'F;¹Ù‡öØgºì¿šÿ/˜+5ý@¡OÒõc?ä
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/44/14ac920acabc3eb00e3cf9375eeb0cb6859c15 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/44/14ac920acabc3eb00e3cf9375eeb0cb6859c15
new file mode 100755
index 0000000..4eaaa0c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/44/14ac920acabc3eb00e3cf9375eeb0cb6859c15 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/44/2894787eddb1e84a952f17a027590e2c6c02cd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/44/2894787eddb1e84a952f17a027590e2c6c02cd
new file mode 100755
index 0000000..c81b0e6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/44/2894787eddb1e84a952f17a027590e2c6c02cd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/46/fe10fa23259b089ab050788b06df979cd7d054 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/46/fe10fa23259b089ab050788b06df979cd7d054
new file mode 100755
index 0000000..6d1f52d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/46/fe10fa23259b089ab050788b06df979cd7d054 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/4a/a347c8bb0456230f43f34833c97b9f52c40f62 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/4a/a347c8bb0456230f43f34833c97b9f52c40f62
new file mode 100755
index 0000000..2a54fe2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/4a/a347c8bb0456230f43f34833c97b9f52c40f62
@@ -0,0 +1,3 @@
+x¥]
+Â0„}Î)ö–Ý6?
ˆøâ	ôi²!‚i ˆ·7Š7ðmæû`Æ—œo
ÈN»V™ÁE©œ#^‡8£ä@
r\¬ŽÌ¬FãÉxá-•
+çðt5À5•¼•Üé'ø+~mð%$i;i‰#ìQ!ŠNûyã?gÄåî¶ôÞŠ½AÍ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/4d/83272d0d372e1232ddc4ff3260d76fdfa2015a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/4d/83272d0d372e1232ddc4ff3260d76fdfa2015a
new file mode 100755
index 0000000..d362f1d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/4d/83272d0d372e1232ddc4ff3260d76fdfa2015a
@@ -0,0 +1,2 @@
+x¥K
+1D]ç}¥“ÉDÜx/OÃNH"2·woà®ê=¨Š5çe€@}L<%´AD“Ì„VºI:%Ir§IDPÇüs̵Á-½|KpŸkîµÀ™vúIWúŠ_;Åš/À¥@Ç-WGTˆl§ûù ?gXñ}lзêºDX—ò`oÔ™Dù
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/53/41a7b545d71198b076b8ba3374a75c9a290640 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/53/41a7b545d71198b076b8ba3374a75c9a290640
new file mode 100755
index 0000000..fdfe6eb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/53/41a7b545d71198b076b8ba3374a75c9a290640
@@ -0,0 +1,3 @@
+x¥]
+Â0„}Î)ö–ݤiñÅèò³%‚i ˆ·7Š7ðmæø&”œo
Ȫ]«Ìàš­öÄÈ^‹”ËŒz"²Ñ“’1bˆµp–J…s|ºášJÞÊ
+îô“Nü~m%Fš¬ÒFØcW‰Nûyã?5ârw[z
o·f@©
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/5d/1ee4f24f66dcd62a30248588d33804656b2073 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/5d/1ee4f24f66dcd62a30248588d33804656b2073
new file mode 100755
index 0000000..ffd9bfd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/5d/1ee4f24f66dcd62a30248588d33804656b2073 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/65/94bdbad86bbc8d3ed0806a23827203fbab56c6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/65/94bdbad86bbc8d3ed0806a23827203fbab56c6
new file mode 100755
index 0000000..fa990d4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/65/94bdbad86bbc8d3ed0806a23827203fbab56c6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/68/e8bce48725490c376d57ebc60f0170605951a5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/68/e8bce48725490c376d57ebc60f0170605951a5
new file mode 100755
index 0000000..c23f815
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/68/e8bce48725490c376d57ebc60f0170605951a5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/69/7dc3d723a018538eb819d5db2035c15109af73 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/69/7dc3d723a018538eb819d5db2035c15109af73
new file mode 100755
index 0000000..6d7d9f5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/69/7dc3d723a018538eb819d5db2035c15109af73 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/6b/7d8a5a48a3c753b75a8fe5196f9c8704ac64ad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/6b/7d8a5a48a3c753b75a8fe5196f9c8704ac64ad
new file mode 100755
index 0000000..121277f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/6b/7d8a5a48a3c753b75a8fe5196f9c8704ac64ad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/6c/1f5f6fec515d33036b44c596bfae28fc460cba b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/6c/1f5f6fec515d33036b44c596bfae28fc460cba
new file mode 100755
index 0000000..8172b7f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/6c/1f5f6fec515d33036b44c596bfae28fc460cba differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/71/2ceb8eb3e57072447715bc4057c57aa50f629a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/71/2ceb8eb3e57072447715bc4057c57aa50f629a
new file mode 100755
index 0000000..9ed35d7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/71/2ceb8eb3e57072447715bc4057c57aa50f629a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/7a/0538bc4e20aecb36ef221f2077eb30ebe0bcb2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/7a/0538bc4e20aecb36ef221f2077eb30ebe0bcb2
new file mode 100755
index 0000000..0c3ea26
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/7a/0538bc4e20aecb36ef221f2077eb30ebe0bcb2
@@ -0,0 +1,2 @@
+x1!E­9Åô&X!1ÆÆÖÊ̐ÝÇÀãíÅ+øªŸWü—¸ÖMÀD½“FÚ\‚‰9ئèÓBÖÅÙMŽ¼¥ŠCc¼Â—¬ÜàšßØ2ÜW®p¢aëR·Ô¸s‘Câz3Yççcˆ°×5äè
+ýÿ nØå<QÖ/Òä?
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/7a/e174dda8f105a582c593b52d74545a3565819d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/7a/e174dda8f105a582c593b52d74545a3565819d
new file mode 100755
index 0000000..17dec59
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/7a/e174dda8f105a582c593b52d74545a3565819d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/7b/b1dd08b2c7d73084934954e4196e67004b0279 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/7b/b1dd08b2c7d73084934954e4196e67004b0279
new file mode 100755
index 0000000..e6640e6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/7b/b1dd08b2c7d73084934954e4196e67004b0279 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/7d/4e382485ace068fb83b768ba1a1c674afbdc1d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/7d/4e382485ace068fb83b768ba1a1c674afbdc1d
new file mode 100755
index 0000000..f7be9ab
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/7d/4e382485ace068fb83b768ba1a1c674afbdc1d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/7f/924ca37670afa06c7a481a2487b728b2c0185a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/7f/924ca37670afa06c7a481a2487b728b2c0185a
new file mode 100755
index 0000000..5964a27
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/7f/924ca37670afa06c7a481a2487b728b2c0185a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/80/24458e7ee49c456fd8c45d3591e9936bf613b3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/80/24458e7ee49c456fd8c45d3591e9936bf613b3
new file mode 100755
index 0000000..d2074aa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/80/24458e7ee49c456fd8c45d3591e9936bf613b3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/80/a8fe4f10626c50b3a4fd065a4604bafc9f30fa b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/80/a8fe4f10626c50b3a4fd065a4604bafc9f30fa
new file mode 100755
index 0000000..ad27251
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/80/a8fe4f10626c50b3a4fd065a4604bafc9f30fa differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/81/e2b84864f16ebd285b34a2b1e87ebb41f4c230 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/81/e2b84864f16ebd285b34a2b1e87ebb41f4c230
new file mode 100755
index 0000000..c28ad0a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/81/e2b84864f16ebd285b34a2b1e87ebb41f4c230 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/82/482ad2e683edfc14f7de359e4f9a5e88909c51 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/82/482ad2e683edfc14f7de359e4f9a5e88909c51
new file mode 100755
index 0000000..16ea98e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/82/482ad2e683edfc14f7de359e4f9a5e88909c51 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/88/6c0f5f71057d846f71f05a05fdffad332bc070 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/88/6c0f5f71057d846f71f05a05fdffad332bc070
new file mode 100755
index 0000000..432eea2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/88/6c0f5f71057d846f71f05a05fdffad332bc070 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/89/9ff28744bed5bece69c78ba752c7dc3e954629 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/89/9ff28744bed5bece69c78ba752c7dc3e954629
new file mode 100755
index 0000000..6f552e5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/89/9ff28744bed5bece69c78ba752c7dc3e954629 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/8b/cbb6e0c0f9554efd5401e1ec14a4b2595eb3bf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/8b/cbb6e0c0f9554efd5401e1ec14a4b2595eb3bf
new file mode 100755
index 0000000..bba2035
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/8b/cbb6e0c0f9554efd5401e1ec14a4b2595eb3bf
@@ -0,0 +1,2 @@
+x¥]
+!…{vw
^F…ˆ^ZAmÀÑ+9‚cD»Ï¢ôvÎ÷Á9¡–rë€Nîz#‚—&:ÎˆÙÖ„)ðTVz‹z‰Æ-–ùGϵÁ9>}‹p͵lu…
úI'úŠ_›B-G@…³SR*{®9gƒŽóNΰËÝoù5½ƒA)
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/8c/e7a3ef59c3d602a0296321eb964218f3d52fae b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/8c/e7a3ef59c3d602a0296321eb964218f3d52fae
new file mode 100755
index 0000000..6f3484c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/8c/e7a3ef59c3d602a0296321eb964218f3d52fae differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/8f/1dcd43aa0164eb6ec319c3ec8879ca5cf62c1e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/8f/1dcd43aa0164eb6ec319c3ec8879ca5cf62c1e
new file mode 100755
index 0000000..f802e5a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/8f/1dcd43aa0164eb6ec319c3ec8879ca5cf62c1e
@@ -0,0 +1,2 @@
+x¥K
+1D]ç}‡|:c7ˆ¸ñztˆ`ÌDÄÛŸ«zªb«õÚÁ°ÛôEÈ"ِ¬Ìä$åh0ï’8Ï‚™ƒ"Ö½QáÑK[à”žaIp)­®í{ô“Žò¿6ÅV`ÐÌŒHÚÂV{­Õ ã¼ËŸ3ê|kyMoA/
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/91/602c85bb50dd834205edd30435b77d5bb9ccf0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/91/602c85bb50dd834205edd30435b77d5bb9ccf0
new file mode 100755
index 0000000..d7147fb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/91/602c85bb50dd834205edd30435b77d5bb9ccf0
@@ -0,0 +1,3 @@
+x¥Q
+1Dýî)r—d»ÛZñÇèB“¥‚µÐ­ˆ··Š7ðoÞ˜‰%çk
+vÓª*ÄiÔ£Š“°8kÉw`‰½šy¢(!~´T*œäÉUà’J^ËöÚí'õ[ühˆ%€&òH“ö8#šnûyÓ?gÌùÆkz
o!çA2
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/91/cd2c95af92883550b45fcc838013ae7e2954df b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/91/cd2c95af92883550b45fcc838013ae7e2954df
new file mode 100755
index 0000000..da9d5c4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/91/cd2c95af92883550b45fcc838013ae7e2954df differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/94/f37c29173c8fa45a232b17e745c82132b2fafd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/94/f37c29173c8fa45a232b17e745c82132b2fafd
new file mode 100755
index 0000000..475d26b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/94/f37c29173c8fa45a232b17e745c82132b2fafd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/96/156716851c0afb4702b0d2c4ac8c496a730e29 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/96/156716851c0afb4702b0d2c4ac8c496a730e29
new file mode 100755
index 0000000..57419bc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/96/156716851c0afb4702b0d2c4ac8c496a730e29
@@ -0,0 +1 @@
+x;Â0©sŠí‘PüÙKÑÐRqµ½VR˜EÎ"Äí1W`ª§)Þ$©uU0aÜic›­Ëh0ŒœlAWØGŒÑ1&š,;dÏeF襋4¸æ7µ÷Eê&8q·¿u©kj²IÑC’zcÇé8؏¡ËÞUþÿa¸Ñ¦¨”àIº|\ä@o
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/96/3fdf003bf7261b9155c5748dc0945349b69e68 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/96/3fdf003bf7261b9155c5748dc0945349b69e68
new file mode 100755
index 0000000..ff1d33e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/96/3fdf003bf7261b9155c5748dc0945349b69e68 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/9a/b85e507899c19dca57778c9b6e5f1ec799b911 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/9a/b85e507899c19dca57778c9b6e5f1ec799b911
new file mode 100755
index 0000000..aa24a8f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/9a/b85e507899c19dca57778c9b6e5f1ec799b911
@@ -0,0 +1,3 @@
+x=
+1F­sŠéÙ5ÿ bckåf'	»EIFÄÛ¯à«>^ñ=âZ79N;i9ƒ[|
+hÑÔä­^¼ÅP²£+‘‚Ÿ’3˜¾då×ôÆ–à¾ríü€Sö·.u£Æ‹ˆëæ£6Öùa?
Ԑ£+ùÿuÃ.¨HðDY¿2Ù@%
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/9d/5898503adc01d763e279ac8fcefbe865b19031 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/9d/5898503adc01d763e279ac8fcefbe865b19031
new file mode 100755
index 0000000..7cb3106
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/9d/5898503adc01d763e279ac8fcefbe865b19031
@@ -0,0 +1,4 @@
+x¥O[Â ô›Sì4R
+Icüñz
+Û´±t
bÔÛK7ðk^ÉL&pJS%qS2ôTô=5­1vo•4Ñ5ƒt®‚÷zˆºu­þQFÎpŠOŸ#\FNw^ £ê®ìHßà§vÓ¤V袶°ÅQT·Žú³Fœß©çy
+0OËèu›yý$>›…Fû
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/9e/24726d64589ba02430da8cebb5712dad35593d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/9e/24726d64589ba02430da8cebb5712dad35593d
new file mode 100755
index 0000000..2cf9535
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/9e/24726d64589ba02430da8cebb5712dad35593d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/9e/683cdaf9ea2727c891b4cf8f7f11e9e28a67ca b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/9e/683cdaf9ea2727c891b4cf8f7f11e9e28a67ca
new file mode 100755
index 0000000..2e36dca
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/9e/683cdaf9ea2727c891b4cf8f7f11e9e28a67ca differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/a0/d89aa95628fcd6b64fd5b23dd56b906b06bfe2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/a0/d89aa95628fcd6b64fd5b23dd56b906b06bfe2
new file mode 100755
index 0000000..c1de43b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/a0/d89aa95628fcd6b64fd5b23dd56b906b06bfe2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/a5/76a98d3279989226992610372035b76a01a3e9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/a5/76a98d3279989226992610372035b76a01a3e9
new file mode 100755
index 0000000..75fa458
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/a5/76a98d3279989226992610372035b76a01a3e9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/a7/8dde970cffbb71d67bef2a74aa72c6621d9819 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/a7/8dde970cffbb71d67bef2a74aa72c6621d9819
new file mode 100755
index 0000000..78c2fe4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/a7/8dde970cffbb71d67bef2a74aa72c6621d9819 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/ac/84d85a425b2a21fd0ffccacac6c48823fc98c8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/ac/84d85a425b2a21fd0ffccacac6c48823fc98c8
new file mode 100755
index 0000000..b08e247
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/ac/84d85a425b2a21fd0ffccacac6c48823fc98c8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/af/45aa1eb7edf804ed10f70efb96fd178527c17c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/af/45aa1eb7edf804ed10f70efb96fd178527c17c
new file mode 100755
index 0000000..9e270bf
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/af/45aa1eb7edf804ed10f70efb96fd178527c17c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/b1/1df9aee97a65817e8904a74f5e6a1c62c7a275 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/b1/1df9aee97a65817e8904a74f5e6a1c62c7a275
new file mode 100755
index 0000000..b2e0eda
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/b1/1df9aee97a65817e8904a74f5e6a1c62c7a275 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/b8/3795b1e0eb54f22f7056119db132500d0cdc05 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/b8/3795b1e0eb54f22f7056119db132500d0cdc05
new file mode 100755
index 0000000..6cee4f9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/b8/3795b1e0eb54f22f7056119db132500d0cdc05 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/bb/29ec85546d29b0bcc314242660d7772b0a3803 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/bb/29ec85546d29b0bcc314242660d7772b0a3803
new file mode 100755
index 0000000..00ab02c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/bb/29ec85546d29b0bcc314242660d7772b0a3803 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/bc/e2dabe5766838216d95f199d95aa4fd479a084 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/bc/e2dabe5766838216d95f199d95aa4fd479a084
new file mode 100755
index 0000000..b1eab10
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/bc/e2dabe5766838216d95f199d95aa4fd479a084 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/bf/7ab4723fcc57ecc7fceccf591d6c4773491569 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/bf/7ab4723fcc57ecc7fceccf591d6c4773491569
new file mode 100755
index 0000000..af02c6b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/bf/7ab4723fcc57ecc7fceccf591d6c4773491569
@@ -0,0 +1,2 @@
+x¥K
+1D]ç}‡î|"n<^`¦;!‚™@&"ÞÞ(ÞÀ]Õ{PÅ%ç[òfÓj€Ž´ösôb0°×ŽÑj™÷¸óÌÂ4’ó¢¦GK¥ÂYžS¸¦’ײÀ!túI§ð¿6pÉG K#’ÓÆ¢괟·ð猺ܧ5½†7Õw@Ç
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/c2/a2ddd339574e5cbfd9228be840eb1bf496de4e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/c2/a2ddd339574e5cbfd9228be840eb1bf496de4e
new file mode 100755
index 0000000..939cf55
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/c2/a2ddd339574e5cbfd9228be840eb1bf496de4e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/c3/a70f8a376f17adccfb52b48e2831bfef2a2172 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/c3/a70f8a376f17adccfb52b48e2831bfef2a2172
new file mode 100755
index 0000000..b43d3f1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/c3/a70f8a376f17adccfb52b48e2831bfef2a2172
@@ -0,0 +1,2 @@
+xÍ=
+1`ë=Åô‚d'n6"6¶V^ ¿d‹8’Œˆ·7^ÁW=¾â½Àµn3©´”@y‹Êĸ¢Ó^{Ò˜ýb0F¤™hYMjr/)Üàß®E¸®pJCíR·Ð¸s–Càz†õq1«%Ø«‘iàø•ôÿÂts]>P]€§“ò?1
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/c4/89e70ed6d9f6331770eae21a77d15afd11cd99 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/c4/89e70ed6d9f6331770eae21a77d15afd11cd99
new file mode 100755
index 0000000..1d76348
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/c4/89e70ed6d9f6331770eae21a77d15afd11cd99 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/c6/72414d4d08111145ef8202f21c95fa7e688aee b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/c6/72414d4d08111145ef8202f21c95fa7e688aee
new file mode 100755
index 0000000..1b79b34
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/c6/72414d4d08111145ef8202f21c95fa7e688aee differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/c8/f98a1762ec016c30f0d73512df399dedefc3fd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/c8/f98a1762ec016c30f0d73512df399dedefc3fd
new file mode 100755
index 0000000..85ddc7f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/c8/f98a1762ec016c30f0d73512df399dedefc3fd
@@ -0,0 +1,3 @@
+x=
+1F­sŠéÙÄ͈ØØZy1™%[ÄY’ñöÆ+øªW|/q­«€ŽÓN<´ÎKD¢èÑÙ =…8ÍèçÅ’CœI·
+_R¸Á5¿±e¸®Ÿp¢aëR×Ô¸ó"‡ÄõÚgë|ˆ°ŸjÈÑúÿAÝ°Ë*&ØPÊ+?ò
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/cc/bbfdb796f9b03298f5c7225e8f830784e1a3b1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/cc/bbfdb796f9b03298f5c7225e8f830784e1a3b1
new file mode 100755
index 0000000..732474a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/cc/bbfdb796f9b03298f5c7225e8f830784e1a3b1
@@ -0,0 +1,2 @@
+x¥OI
+1ôœWô]²tŒ#"^üè$­3‡LC&â÷͈?°Nµ@•¤”¹Õ~×*30rŽî`Ø›ÑÙèSê:f4³#´Ç‘8±¢W›¤Â-¿©f¸ORVYàÌÝÝØ•¿ÁO
IÊš0X°×ª»}¼ñŸ5jxÎíôZ`û¡>Þ›E®
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/cd/44b4ea1066b3fa1d4b3baad8dc1531aec287a6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/cd/44b4ea1066b3fa1d4b3baad8dc1531aec287a6
new file mode 100755
index 0000000..51ad388
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/cd/44b4ea1066b3fa1d4b3baad8dc1531aec287a6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/ce/22b3cd9a01efafc370879c1938e0c32fb6f195 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/ce/22b3cd9a01efafc370879c1938e0c32fb6f195
new file mode 100755
index 0000000..eb5acc3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/ce/22b3cd9a01efafc370879c1938e0c32fb6f195
@@ -0,0 +1,3 @@
+x;
+B1E­ß*¦$ÿˆØØZ¹dÉ+âHÞˆ¸{ã<Õå÷ õ¾2È(v<j…œU¬¬5®¨˜EFÔÒ(£œÅ{¯²H:½¤7p)ï4
+Üõp¬ÓþÖ¹¯8h£;ú	¤ÒÆ:"ìÅd™rv¹þÿ°\ÓÆè	ᙸ}®?F
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/cf/6fcf8cdf7e8d4cda3b11b0ba02d0d5125fbbd7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/cf/6fcf8cdf7e8d4cda3b11b0ba02d0d5125fbbd7
new file mode 100755
index 0000000..f65e8ff
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/cf/6fcf8cdf7e8d4cda3b11b0ba02d0d5125fbbd7
@@ -0,0 +1,2 @@
+x¥]
+Â0„}Î)öJ²m“Šøâ	ôùÙÐ`Ó•QoooàÛÌ70ÃxÎ9@%7e%kúh0ÒÇèœQAG­i­5èµF†^
ÂÞËÄ+ÃîÎç/0R¥u oðs;ÏyªE…ºÃ¶­ì¤•ÖñBÖˆÓ+;ž“‡9- çuæú©oG‚
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/d2/eb26d4938550487de59a017a7bfee8ca46b5f4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/d2/eb26d4938550487de59a017a7bfee8ca46b5f4
new file mode 100755
index 0000000..e458bf4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/d2/eb26d4938550487de59a017a7bfee8ca46b5f4
@@ -0,0 +1,2 @@
+x¥Q
+B!Eûv³ã35!¢ŸVPÐqÄ Ÿà3¢ÝgÑú»÷¸—j)·Ò©MoÌ ·(­3”±Èšæ=›ä¼G2”UIøGϵÁ9>}‹p͵¬uúI'þŠ_›¨–#ȝ4NYm¶¨Å ã¼óŸ3âr÷k~Mo"A<
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/dc/37c5f1521fb76fe1c1ac7b13187f9396a59247 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/dc/37c5f1521fb76fe1c1ac7b13187f9396a59247
new file mode 100755
index 0000000..57329de
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/dc/37c5f1521fb76fe1c1ac7b13187f9396a59247 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/de/bdc4a004fda6141a17d9c297617be70d40248f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/de/bdc4a004fda6141a17d9c297617be70d40248f
new file mode 100755
index 0000000..de34bd4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/de/bdc4a004fda6141a17d9c297617be70d40248f
@@ -0,0 +1,2 @@
+x¥K
+1D]ç}‡tf&qã	ôm§ÃÆ@&"ÞÞ(ÞÀ]Õ{PÅ%çkã¦UbýÈ‘R2Î8ö/'Ÿ\B” Æ“uLŠm)ŽñI5Ây)y-wØI§Ÿt¯øµKÞNè4ζzÖZuÚÏ›ü9£N7Z—×ðmÐA¤
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e2/377bdbc93b30a34ed5deefedded89b947ff8f4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e2/377bdbc93b30a34ed5deefedded89b947ff8f4
new file mode 100755
index 0000000..f365908
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e2/377bdbc93b30a34ed5deefedded89b947ff8f4
@@ -0,0 +1,2 @@
+x¥K
+1D]ç}‡îÉDÜx½@&i‰`d"âíâ
ÜU½U±–rí@^nzcãØ-‘•³³V£´&iËK4xA²hP{MA‹ðè¹68¦gh	ι–µÞaǃ~ҁ¿âצXËH‘ñÒÎ$a‹Q:Î;ÿ9#N·°æ×ôÑ@W
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e3/99c4fc4c07cb7947d2f3d966bc374df6ccc691 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e3/99c4fc4c07cb7947d2f3d966bc374df6ccc691
new file mode 100755
index 0000000..d8c2379
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e3/99c4fc4c07cb7947d2f3d966bc374df6ccc691
@@ -0,0 +1,2 @@
+x¥Q
+1Dýî)r—¤›Ú.,â'Дl¤‚µÐ­ˆ··Š7ðoæ=˜‘’óµMã¦UUÀèƒ2ªcö$Èä$â. sx±lÕÕšøh©T8.ÏX8§’×r‡Y;ý¤ƒ~ů
RòˆÉ#…	¶èM§ý¼éŸ3æt‹kz
o{˜@8
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e4/edb361e51932b5ccedbc7ee41b4d3a4289aece b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e4/edb361e51932b5ccedbc7ee41b4d3a4289aece
new file mode 100755
index 0000000..a9b1818
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e4/edb361e51932b5ccedbc7ee41b4d3a4289aece differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e5/1c3fa44fe981ec290c8f47fea736f3ff2af2a6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e5/1c3fa44fe981ec290c8f47fea736f3ff2af2a6
new file mode 100755
index 0000000..3d12f3a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e5/1c3fa44fe981ec290c8f47fea736f3ff2af2a6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e7/3a04f71f11ab9d7dde72ff793882757a03f16e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e7/3a04f71f11ab9d7dde72ff793882757a03f16e
new file mode 100755
index 0000000..14144d7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e7/3a04f71f11ab9d7dde72ff793882757a03f16e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e8/68b1d6833710021785581a9e11dba8468f3a55 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e8/68b1d6833710021785581a9e11dba8468f3a55
new file mode 100755
index 0000000..8311ad3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e8/68b1d6833710021785581a9e11dba8468f3a55 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e8/7caf56c91ab8d14e4ee8eb56308533503d1885 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e8/7caf56c91ab8d14e4ee8eb56308533503d1885
new file mode 100755
index 0000000..6e61c06
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/e8/7caf56c91ab8d14e4ee8eb56308533503d1885
@@ -0,0 +1,2 @@
+x¥K
+1D]ç}‡nó™	ˆ¸ñz|:D02ñöFñîªÞƒªPK¹v +7½1IÖiñŒ–?G³J^Zo
ã²#‚rÒ$îÑsmpŠO×"\r-k½Ãžý¤#ůM¡–"c¥A©a‹Q:Î;ÿ9#Î7·æ×ô(ŸAD
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/eb/82bf596b66f90e25f881ce9b92cb55bab4fdf5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/eb/82bf596b66f90e25f881ce9b92cb55bab4fdf5
new file mode 100755
index 0000000..b886096
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/eb/82bf596b66f90e25f881ce9b92cb55bab4fdf5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/ed/4bc023f61dc345ff0084b922b229d24de206e7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/ed/4bc023f61dc345ff0084b922b229d24de206e7
new file mode 100755
index 0000000..d128a94
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/ed/4bc023f61dc345ff0084b922b229d24de206e7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/ef/6ed8a2b15f95795aed82a974b995cace02dbfe b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/ef/6ed8a2b15f95795aed82a974b995cace02dbfe
new file mode 100755
index 0000000..7357306
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/ef/6ed8a2b15f95795aed82a974b995cace02dbfe differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/f2/c059dab35f6534b3f16d90b2f1de308615320c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/f2/c059dab35f6534b3f16d90b2f1de308615320c
new file mode 100755
index 0000000..c3580d3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/f2/c059dab35f6534b3f16d90b2f1de308615320c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/fa/9cfdbeaaf3a91ff4b84d74412cd59d9b16a615 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/fa/9cfdbeaaf3a91ff4b84d74412cd59d9b16a615
new file mode 100755
index 0000000..890324e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/fa/9cfdbeaaf3a91ff4b84d74412cd59d9b16a615 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/fd/7a37d92197267e55e1fc0cc4f283a815bd79b8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/fd/7a37d92197267e55e1fc0cc4f283a815bd79b8
new file mode 100755
index 0000000..c8d38ca
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/objects/fd/7a37d92197267e55e1fc0cc4f283a815bd79b8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_backslash_dotcapitalgit_path b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_backslash_dotcapitalgit_path
new file mode 100755
index 0000000..06132bc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_backslash_dotcapitalgit_path
@@ -0,0 +1 @@
+0228b21d477f67b9f7720565da9e760b84c8b85b
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_dotcapitalgit_path b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_dotcapitalgit_path
new file mode 100755
index 0000000..fd12c3e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_dotcapitalgit_path
@@ -0,0 +1 @@
+e2377bdbc93b30a34ed5deefedded89b947ff8f4
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_dotgit_path b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_dotgit_path
new file mode 100755
index 0000000..1f9b2d4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_dotgit_path
@@ -0,0 +1 @@
+4aa347c8bb0456230f43f34833c97b9f52c40f62
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_dotgit_tree b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_dotgit_tree
new file mode 100755
index 0000000..dd9a6c0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_dotgit_tree
@@ -0,0 +1 @@
+8bcbb6e0c0f9554efd5401e1ec14a4b2595eb3bf
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_git_colon b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_git_colon
new file mode 100755
index 0000000..39052d9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_git_colon
@@ -0,0 +1 @@
+4414ac920acabc3eb00e3cf9375eeb0cb6859c15
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_git_colon_stuff b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_git_colon_stuff
new file mode 100755
index 0000000..a3bc39f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_git_colon_stuff
@@ -0,0 +1 @@
+ccbbfdb796f9b03298f5c7225e8f830784e1a3b1
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_git_dot b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_git_dot
new file mode 100755
index 0000000..b20a1e0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_git_dot
@@ -0,0 +1 @@
+26b665c162f67acae67779445f3c7b9782b0a6d7
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_path b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_path
new file mode 100755
index 0000000..b3c7ab6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_path
@@ -0,0 +1 @@
+bf7ab4723fcc57ecc7fceccf591d6c4773491569
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_path_two b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_path_two
new file mode 100755
index 0000000..515e983
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_path_two
@@ -0,0 +1 @@
+debdc4a004fda6141a17d9c297617be70d40248f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_tree b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_tree
new file mode 100755
index 0000000..cf95837
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dot_tree
@@ -0,0 +1 @@
+697dc3d723a018538eb819d5db2035c15109af73
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotcapitalgit_backslash_path b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotcapitalgit_backslash_path
new file mode 100755
index 0000000..6e4344d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotcapitalgit_backslash_path
@@ -0,0 +1 @@
+099ed86cb8501ae483b1855c351fe1a506ac9631
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotcapitalgit_path b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotcapitalgit_path
new file mode 100755
index 0000000..5822791
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotcapitalgit_path
@@ -0,0 +1 @@
+e87caf56c91ab8d14e4ee8eb56308533503d1885
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotcapitalgit_tree b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotcapitalgit_tree
new file mode 100755
index 0000000..dfb7a1a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotcapitalgit_tree
@@ -0,0 +1 @@
+39fb3af508440cf970b92767f6d081c811574d2a
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotdot_dotcapitalgit_path b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotdot_dotcapitalgit_path
new file mode 100755
index 0000000..6a24cd7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotdot_dotcapitalgit_path
@@ -0,0 +1 @@
+d2eb26d4938550487de59a017a7bfee8ca46b5f4
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotdot_dotgit_path b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotdot_dotgit_path
new file mode 100755
index 0000000..4d79b3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotdot_dotgit_path
@@ -0,0 +1 @@
+1212c12915820e1ad523b6305c0dcdefea8b7e97
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotdot_dotgit_tree b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotdot_dotgit_tree
new file mode 100755
index 0000000..6ae117e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotdot_dotgit_tree
@@ -0,0 +1 @@
+1e3c845808fa5883aa4bcf2f882172edb72a7a32
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotdot_path b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotdot_path
new file mode 100755
index 0000000..185e13b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotdot_path
@@ -0,0 +1 @@
+91602c85bb50dd834205edd30435b77d5bb9ccf0
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotdot_tree b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotdot_tree
new file mode 100755
index 0000000..d30a7b5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotdot_tree
@@ -0,0 +1 @@
+8f1dcd43aa0164eb6ec319c3ec8879ca5cf62c1e
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_backslash_path b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_backslash_path
new file mode 100755
index 0000000..6e4344d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_backslash_path
@@ -0,0 +1 @@
+099ed86cb8501ae483b1855c351fe1a506ac9631
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_1
new file mode 100755
index 0000000..dc48bd6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_1
@@ -0,0 +1 @@
+46fe10fa23259b089ab050788b06df979cd7d054
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_10 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_10
new file mode 100755
index 0000000..b3a9726
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_10
@@ -0,0 +1 @@
+9ab85e507899c19dca57778c9b6e5f1ec799b911
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_11 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_11
new file mode 100755
index 0000000..edf2798
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_11
@@ -0,0 +1 @@
+15f7d9f9514eeb65b9588c49b10b1da145a729a2
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_12 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_12
new file mode 100755
index 0000000..c4e682e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_12
@@ -0,0 +1 @@
+c3a70f8a376f17adccfb52b48e2831bfef2a2172
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_13 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_13
new file mode 100755
index 0000000..76a155c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_13
@@ -0,0 +1 @@
+c2a2ddd339574e5cbfd9228be840eb1bf496de4e
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_14 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_14
new file mode 100755
index 0000000..be2f835
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_14
@@ -0,0 +1 @@
+712ceb8eb3e57072447715bc4057c57aa50f629a
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_15 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_15
new file mode 100755
index 0000000..3fdeece
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_15
@@ -0,0 +1 @@
+3b24e5c751ee9c7c89df32a0d959748aa3d0112c
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_16 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_16
new file mode 100755
index 0000000..2739555
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_16
@@ -0,0 +1 @@
+c8f98a1762ec016c30f0d73512df399dedefc3fd
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_2
new file mode 100755
index 0000000..480832e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_2
@@ -0,0 +1 @@
+35ae236308929a536fb4e852278a9b98c42babb3
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_3
new file mode 100755
index 0000000..8510ece
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_3
@@ -0,0 +1 @@
+96156716851c0afb4702b0d2c4ac8c496a730e29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_4
new file mode 100755
index 0000000..754b55e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_4
@@ -0,0 +1 @@
+7a0538bc4e20aecb36ef221f2077eb30ebe0bcb2
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_5
new file mode 100755
index 0000000..161ebc4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_5
@@ -0,0 +1 @@
+1635c47d80914f0abfa43dd4234a948db5bdb107
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_6
new file mode 100755
index 0000000..f8a5fa3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_6
@@ -0,0 +1 @@
+9e24726d64589ba02430da8cebb5712dad35593d
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_7
new file mode 100755
index 0000000..ad5ad1d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_7
@@ -0,0 +1 @@
+ce22b3cd9a01efafc370879c1938e0c32fb6f195
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_8
new file mode 100755
index 0000000..4d10c40
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_8
@@ -0,0 +1 @@
+a576a98d3279989226992610372035b76a01a3e9
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_9
new file mode 100755
index 0000000..a935018
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_hfs_ignorable_9
@@ -0,0 +1 @@
+442894787eddb1e84a952f17a027590e2c6c02cd
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_path b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_path
new file mode 100755
index 0000000..dd71efa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_path
@@ -0,0 +1 @@
+5341a7b545d71198b076b8ba3374a75c9a290640
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_tree b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_tree
new file mode 100755
index 0000000..3b7a08d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/dotgit_tree
@@ -0,0 +1 @@
+6594bdbad86bbc8d3ed0806a23827203fbab56c6
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/git_tilde1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/git_tilde1
new file mode 100755
index 0000000..d48a185
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/git_tilde1
@@ -0,0 +1 @@
+94f37c29173c8fa45a232b17e745c82132b2fafd
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/git_tilde2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/git_tilde2
new file mode 100755
index 0000000..77082e1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/git_tilde2
@@ -0,0 +1 @@
+899ff28744bed5bece69c78ba752c7dc3e954629
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/git_tilde3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/git_tilde3
new file mode 100755
index 0000000..73022aa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/git_tilde3
@@ -0,0 +1 @@
+fa9cfdbeaaf3a91ff4b84d74412cd59d9b16a615
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/master
new file mode 100755
index 0000000..b193433
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/master
@@ -0,0 +1 @@
+e399c4fc4c07cb7947d2f3d966bc374df6ccc691
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/symlink1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/symlink1
new file mode 100755
index 0000000..efa2e88
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/symlink1
@@ -0,0 +1 @@
+4d83272d0d372e1232ddc4ff3260d76fdfa2015a
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/symlink2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/symlink2
new file mode 100755
index 0000000..e4f3d60
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/symlink2
@@ -0,0 +1 @@
+9d5898503adc01d763e279ac8fcefbe865b19031
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/symlink3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/symlink3
new file mode 100755
index 0000000..2b33e4f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/nasty/.gitted/refs/heads/symlink3
@@ -0,0 +1 @@
+cf6fcf8cdf7e8d4cda3b11b0ba02d0d5125fbbd7
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/HEAD
new file mode 100755
index 0000000..4bfb9c9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/dir
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/config
new file mode 100755
index 0000000..99abaab
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/config
@@ -0,0 +1,7 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
+[branch "dir"]
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/index
new file mode 100755
index 0000000..4f241f9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08
new file mode 100755
index 0000000..cedb2a2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/14/4344043ba4d4a405da03de3844aa829ae8be0e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/14/4344043ba4d4a405da03de3844aa829ae8be0e
new file mode 100755
index 0000000..b7d944f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/14/4344043ba4d4a405da03de3844aa829ae8be0e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/16/8e4ebd1c667499548ae12403b19b22a5c5e925 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/16/8e4ebd1c667499548ae12403b19b22a5c5e925
new file mode 100755
index 0000000..d37b93e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/16/8e4ebd1c667499548ae12403b19b22a5c5e925 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7
new file mode 100755
index 0000000..93a16f1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd
new file mode 100755
index 0000000..ba0bfb3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057
new file mode 100755
index 0000000..7ca4cee
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
new file mode 100755
index 0000000..8953b6c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
@@ -0,0 +1,2 @@
+xŽQ
+Â0DýÎ)öÊ6›Í¦ "xO°‰‰-ØFb¼¿EoàÏ0¼Ç¤º,ske×[ÎPn8R,EpD?±gŸ}Ê^3²âÙ<µåµGŽhYKÄèÒ8ЖDAÉ)¿ÉÈ;gôݧÚàšjïp™4ÕŽ¯ô-çû¢óãêr‚ÁŠ;°s°GA4Ûº=ìùÖ(ôin7øIÌKÍFE
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/4e/0883eeeeebc1fb1735161cea82f7cb5fab7e63 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/4e/0883eeeeebc1fb1735161cea82f7cb5fab7e63
new file mode 100755
index 0000000..e915021
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/4e/0883eeeeebc1fb1735161cea82f7cb5fab7e63 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
new file mode 100755
index 0000000..c1f22c5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
@@ -0,0 +1,2 @@
+xŽÛ	1EýNi@™Ék2 "X‚$ÙYW0YcÿíÀ¿Ã…s¸¥ÕzïÚÚõMDÏ€0æœ8!¶†ÉÌÞs‰XŠªgÚdí::@X0»P¢wÙ"F/‰‰œÍRàˆUz÷¥múZZïú²¤ÒV}|•/œo5݇ÒêI£!¬1z Æ:vùÇUim}ê/¢>
+öF-
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/62/eb56dabb4b9929bc15dd9263c2c733b13d2dcc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/62/eb56dabb4b9929bc15dd9263c2c733b13d2dcc
new file mode 100755
index 0000000..b669961
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/62/eb56dabb4b9929bc15dd9263c2c733b13d2dcc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/66/3adb09143767984f7be83a91effa47e128c735 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/66/3adb09143767984f7be83a91effa47e128c735
new file mode 100755
index 0000000..9ff5eb2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/66/3adb09143767984f7be83a91effa47e128c735 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a
new file mode 100755
index 0000000..2ef4faa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d
new file mode 100755
index 0000000..2f9b6b6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479
new file mode 100755
index 0000000..5df58dd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
new file mode 100755
index 0000000..a796124
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
@@ -0,0 +1,3 @@
+xŽ[
+Â0EýÎ*fÊäÕ¤ "¸W0“‡-ØFâtÿ݁—çpS[–YÀ˜x^
+Díb	CLhutɉ}¥8X*4Zí¬sY½¨—UÀ‘AÃÖ
ÌX3‡R«Mµ¶) s6è¼¢M¦ÖážšÜ&Jm…ó;}Çõ±Ðü<¥¶\@›à‚ÑޏpÄ€¨vº?”ò«jÛºLð«¨Ø?Hå
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
new file mode 100755
index 0000000..f858869
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
@@ -0,0 +1,2 @@
+x;j1DëmdÓú·À˜ÇŽ|M«µ3`ŒV{>€³âQ¯ ¸·vL0I?Í!š4–Z=Ê! ×¦8²F¢Ã’!rÖsQßyÈ9]$DŽ&„l6AÇ>jFWüÒµIKNiûë§Z¢%¡SˆŒ‘
+‹Ò	­ÅʉøU~̽øä>'¼ï™û	¯wþ
×[ËÇ×÷öÚDGÚ¡±ðŒQ-ºMù«>dܶ‘OÞáÒò}í\à8g_ШÂoYr
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd
new file mode 100755
index 0000000..d0d7e73
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6
new file mode 100755
index 0000000..18a7f61
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
new file mode 100755
index 0000000..75f541f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
@@ -0,0 +1,3 @@
+xŽQ
+Â0DýÎ)öʦ»I<‚'ØlR+˜Fj¼¿EoàÏ0<xÃh«õÞa Üõµ]È™­åXUlÞPF)Åz‘4yó”µ,\r	'SÂÄ-mI4
+‘Xhô”&òÌFÞ}n+\µõ—Y´-p|é·œoU¶z;-‘aÑlt{ØË?®I«,:ÃoÚR̳cHK
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/cf/80f8de9f1185bf3a05f993f6121880dd0cfbc9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/cf/80f8de9f1185bf3a05f993f6121880dd0cfbc9
new file mode 100755
index 0000000..7620c51
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/cf/80f8de9f1185bf3a05f993f6121880dd0cfbc9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/d5/2a8fe84ceedf260afe4f0287bbfca04a117e83 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/d5/2a8fe84ceedf260afe4f0287bbfca04a117e83
new file mode 100755
index 0000000..00940f0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/d5/2a8fe84ceedf260afe4f0287bbfca04a117e83 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1
new file mode 100755
index 0000000..0377096
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92
new file mode 100755
index 0000000..112998d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765
new file mode 100755
index 0000000..12bf5f3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/pack/.gitkeep b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/objects/pack/.gitkeep
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/refs/heads/dir b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/refs/heads/dir
new file mode 100755
index 0000000..4567d37
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/partial-testrepo/.gitted/refs/heads/dir
@@ -0,0 +1 @@
+144344043ba4d4a405da03de3844aa829ae8be0e
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/config
new file mode 100755
index 0000000..8830052
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/config
@@ -0,0 +1,8 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = true
+[remote "origin"]
+	url = /home/peff/compile/libgit2/tests-clar/resources/peeled
+	fetch = +refs/*:refs/*
+	mirror = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/objects/info/packs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/objects/info/packs
new file mode 100755
index 0000000..0d88b32
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/objects/info/packs
@@ -0,0 +1,2 @@
+P pack-e84773eaf3fce1774755580e3dbb8d9f3a1adc45.pack
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/objects/pack/pack-e84773eaf3fce1774755580e3dbb8d9f3a1adc45.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/objects/pack/pack-e84773eaf3fce1774755580e3dbb8d9f3a1adc45.idx
new file mode 100755
index 0000000..9b79e9b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/objects/pack/pack-e84773eaf3fce1774755580e3dbb8d9f3a1adc45.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/objects/pack/pack-e84773eaf3fce1774755580e3dbb8d9f3a1adc45.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/objects/pack/pack-e84773eaf3fce1774755580e3dbb8d9f3a1adc45.pack
new file mode 100755
index 0000000..2459ca2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/objects/pack/pack-e84773eaf3fce1774755580e3dbb8d9f3a1adc45.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/packed-refs
new file mode 100755
index 0000000..ad053d5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/packed-refs
@@ -0,0 +1,6 @@
+# pack-refs with: peeled fully-peeled 
+c2596aa0151888587ec5c0187f261e63412d9e11 refs/foo/tag-outside-tags
+^0df1a5865c8abfc09f1f2182e6a31be550e99f07
+0df1a5865c8abfc09f1f2182e6a31be550e99f07 refs/heads/master
+c2596aa0151888587ec5c0187f261e63412d9e11 refs/tags/tag-inside-tags
+^0df1a5865c8abfc09f1f2182e6a31be550e99f07
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/refs/heads/master
new file mode 100755
index 0000000..76c15e2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/peeled.git/refs/heads/master
@@ -0,0 +1 @@
+0df1a5865c8abfc09f1f2182e6a31be550e99f07
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push.sh b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push.sh
new file mode 100755
index 0000000..6071176
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+#creates push_src repo for libgit2 push tests.
+set -eu
+
+#Create src repo for push
+mkdir push_src
+pushd push_src
+  git init
+  
+  echo a > a.txt
+  git add .
+  git commit -m 'added a.txt'
+  
+  mkdir fold
+  echo b > fold/b.txt
+  git add .
+  git commit -m 'added fold and fold/b.txt'
+  
+  git branch b1 #b1 and b2 are the same
+  git branch b2
+  
+  git checkout -b b3
+  echo edit >> a.txt
+  git add .
+  git commit -m 'edited a.txt'
+
+  git checkout -b b4 master
+  echo edit >> fold\b.txt
+  git add .
+  git commit -m 'edited fold\b.txt'
+  
+  git checkout -b b5 master
+  git submodule add ../testrepo.git submodule
+  git commit -m "added submodule named 'submodule' pointing to '../testrepo.git'"
+  
+  git checkout master
+  git merge -m "merge b3, b4, and b5 to master" b3 b4 b5
+
+  #Log commits to include in testcase
+  git log --format=oneline --decorate --graph
+  #*-.   951bbbb90e2259a4c8950db78946784fb53fcbce (HEAD, master) merge b3, b4, and b5 to master
+  #|\ \
+  #| | * fa38b91f199934685819bea316186d8b008c52a2 (b5) added submodule named 'submodule' pointing to '../testrepo.git'
+  #| * | 27b7ce66243eb1403862d05f958c002312df173d (b4) edited fold\b.txt
+  #| |/
+  #* | d9b63a88223d8367516f50bd131a5f7349b7f3e4 (b3) edited a.txt
+  #|/
+  #* a78705c3b2725f931d3ee05348d83cc26700f247 (b2, b1) added fold and fold/b.txt
+  #* 5c0bb3d1b9449d1cc69d7519fd05166f01840915 added a.txt
+
+  #fix paths so that we can add repo folders under libgit2 repo
+  #rename .git to .gitted
+  find . -name .git -exec mv -i '{}' '{}ted' \;
+  mv -i .gitmodules gitmodules
+popd
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/COMMIT_EDITMSG b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/COMMIT_EDITMSG
new file mode 100755
index 0000000..b129508
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/COMMIT_EDITMSG
@@ -0,0 +1 @@
+added submodule named 'submodule' pointing to '../testrepo.git'
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/ORIG_HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/ORIG_HEAD
new file mode 100755
index 0000000..afadf9d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/ORIG_HEAD
@@ -0,0 +1 @@
+a78705c3b2725f931d3ee05348d83cc26700f247
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/config
new file mode 100755
index 0000000..51de031
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/config
@@ -0,0 +1,10 @@
+[core]
+	repositoryformatversion = 0
+	filemode = false
+	bare = false
+	logallrefupdates = true
+	symlinks = false
+	ignorecase = true
+	hideDotFiles = dotGitOnly
+[submodule "submodule"]
+	url = m:/dd/libgit2/tests-clar/resources/testrepo.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/index
new file mode 100755
index 0000000..0ef6594
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/HEAD
new file mode 100755
index 0000000..4ef336f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/HEAD
@@ -0,0 +1,10 @@
+0000000000000000000000000000000000000000 5c0bb3d1b9449d1cc69d7519fd05166f01840915 Congyi Wu <congyiwu at gmail.com> 1352923200 -0500	commit (initial): added a.txt
+5c0bb3d1b9449d1cc69d7519fd05166f01840915 a78705c3b2725f931d3ee05348d83cc26700f247 Congyi Wu <congyiwu at gmail.com> 1352923200 -0500	commit: added fold and fold/b.txt
+a78705c3b2725f931d3ee05348d83cc26700f247 a78705c3b2725f931d3ee05348d83cc26700f247 Congyi Wu <congyiwu at gmail.com> 1352923201 -0500	checkout: moving from master to b3
+a78705c3b2725f931d3ee05348d83cc26700f247 d9b63a88223d8367516f50bd131a5f7349b7f3e4 Congyi Wu <congyiwu at gmail.com> 1352923201 -0500	commit: edited a.txt
+d9b63a88223d8367516f50bd131a5f7349b7f3e4 a78705c3b2725f931d3ee05348d83cc26700f247 Congyi Wu <congyiwu at gmail.com> 1352923201 -0500	checkout: moving from b3 to b4
+a78705c3b2725f931d3ee05348d83cc26700f247 27b7ce66243eb1403862d05f958c002312df173d Congyi Wu <congyiwu at gmail.com> 1352923201 -0500	commit: edited fold\b.txt
+27b7ce66243eb1403862d05f958c002312df173d a78705c3b2725f931d3ee05348d83cc26700f247 Congyi Wu <congyiwu at gmail.com> 1352923201 -0500	checkout: moving from b4 to b5
+a78705c3b2725f931d3ee05348d83cc26700f247 fa38b91f199934685819bea316186d8b008c52a2 Congyi Wu <congyiwu at gmail.com> 1352923206 -0500	commit: added submodule named 'submodule' pointing to '../testrepo.git'
+fa38b91f199934685819bea316186d8b008c52a2 a78705c3b2725f931d3ee05348d83cc26700f247 Congyi Wu <congyiwu at gmail.com> 1352923207 -0500	checkout: moving from b5 to master
+a78705c3b2725f931d3ee05348d83cc26700f247 951bbbb90e2259a4c8950db78946784fb53fcbce Congyi Wu <congyiwu at gmail.com> 1352923207 -0500	merge b3 b4 b5: Merge made by the 'octopus' strategy.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/b1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/b1
new file mode 100755
index 0000000..390a03d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/b1
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 a78705c3b2725f931d3ee05348d83cc26700f247 Congyi Wu <congyiwu at gmail.com> 1352923200 -0500	branch: Created from master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/b2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/b2
new file mode 100755
index 0000000..390a03d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/b2
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 a78705c3b2725f931d3ee05348d83cc26700f247 Congyi Wu <congyiwu at gmail.com> 1352923200 -0500	branch: Created from master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/b3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/b3
new file mode 100755
index 0000000..01e302c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/b3
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 a78705c3b2725f931d3ee05348d83cc26700f247 Congyi Wu <congyiwu at gmail.com> 1352923201 -0500	branch: Created from HEAD
+a78705c3b2725f931d3ee05348d83cc26700f247 d9b63a88223d8367516f50bd131a5f7349b7f3e4 Congyi Wu <congyiwu at gmail.com> 1352923201 -0500	commit: edited a.txt
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/b4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/b4
new file mode 100755
index 0000000..7afddc5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/b4
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 a78705c3b2725f931d3ee05348d83cc26700f247 Congyi Wu <congyiwu at gmail.com> 1352923201 -0500	branch: Created from master
+a78705c3b2725f931d3ee05348d83cc26700f247 27b7ce66243eb1403862d05f958c002312df173d Congyi Wu <congyiwu at gmail.com> 1352923201 -0500	commit: edited fold\b.txt
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/b5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/b5
new file mode 100755
index 0000000..bc22567
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/b5
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 a78705c3b2725f931d3ee05348d83cc26700f247 Congyi Wu <congyiwu at gmail.com> 1352923201 -0500	branch: Created from master
+a78705c3b2725f931d3ee05348d83cc26700f247 fa38b91f199934685819bea316186d8b008c52a2 Congyi Wu <congyiwu at gmail.com> 1352923206 -0500	commit: added submodule named 'submodule' pointing to '../testrepo.git'
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..8aafa9c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/logs/refs/heads/master
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 5c0bb3d1b9449d1cc69d7519fd05166f01840915 Congyi Wu <congyiwu at gmail.com> 1352923200 -0500	commit (initial): added a.txt
+5c0bb3d1b9449d1cc69d7519fd05166f01840915 a78705c3b2725f931d3ee05348d83cc26700f247 Congyi Wu <congyiwu at gmail.com> 1352923200 -0500	commit: added fold and fold/b.txt
+a78705c3b2725f931d3ee05348d83cc26700f247 951bbbb90e2259a4c8950db78946784fb53fcbce Congyi Wu <congyiwu at gmail.com> 1352923207 -0500	merge b3 b4 b5: Merge made by the 'octopus' strategy.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/config
new file mode 100755
index 0000000..5981007
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/config
@@ -0,0 +1,15 @@
+[core]
+	repositoryformatversion = 0
+	filemode = false
+	bare = false
+	logallrefupdates = true
+	worktree = ../../../submodule
+	symlinks = false
+	ignorecase = true
+	hideDotFiles = dotGitOnly
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = m:/dd/libgit2/tests-clar/resources/testrepo.git
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/index
new file mode 100755
index 0000000..8e44080
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/logs/HEAD
new file mode 100755
index 0000000..aedcdf2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 a65fedf39aefe402d3bb6e24df4d4f5fe4547750 Congyi Wu <congyiwu at gmail.com> 1352923205 -0500	clone: from m:/dd/libgit2/tests-clar/resources/testrepo.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/logs/refs/heads/master
new file mode 100755
index 0000000..aedcdf2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 a65fedf39aefe402d3bb6e24df4d4f5fe4547750 Congyi Wu <congyiwu at gmail.com> 1352923205 -0500	clone: from m:/dd/libgit2/tests-clar/resources/testrepo.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/logs/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/logs/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..aedcdf2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/logs/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 a65fedf39aefe402d3bb6e24df4d4f5fe4547750 Congyi Wu <congyiwu at gmail.com> 1352923205 -0500	clone: from m:/dd/libgit2/tests-clar/resources/testrepo.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/08/b041783f40edfe12bb406c9c9a8a040177c125 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/08/b041783f40edfe12bb406c9c9a8a040177c125
new file mode 100755
index 0000000..d1c032f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/08/b041783f40edfe12bb406c9c9a8a040177c125 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08
new file mode 100755
index 0000000..cedb2a2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/18/1037049a54a1eb5fab404658a3a250b44335d7
new file mode 100755
index 0000000..93a16f1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/18/10dff58d8a660512d4832e740f692884338ccd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/18/10dff58d8a660512d4832e740f692884338ccd
new file mode 100755
index 0000000..ba0bfb3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/18/10dff58d8a660512d4832e740f692884338ccd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/1a/443023183e3f2bfbef8ac923cd81c1018a18fd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/1a/443023183e3f2bfbef8ac923cd81c1018a18fd
new file mode 100755
index 0000000..3ec5412
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/1a/443023183e3f2bfbef8ac923cd81c1018a18fd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/1b/8cbad43e867676df601306689fe7c3def5e689 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/1b/8cbad43e867676df601306689fe7c3def5e689
new file mode 100755
index 0000000..6048d4b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/1b/8cbad43e867676df601306689fe7c3def5e689 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b
new file mode 100755
index 0000000..225c457
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/25/8f0e2a959a364e40ed6603d5d44fbb24765b10 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/25/8f0e2a959a364e40ed6603d5d44fbb24765b10
new file mode 100755
index 0000000..cb1ed57
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/25/8f0e2a959a364e40ed6603d5d44fbb24765b10 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d
new file mode 100755
index 0000000..df40d99
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/2d/59075e0681f540482d4f6223a68e0fef790bc7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/2d/59075e0681f540482d4f6223a68e0fef790bc7
new file mode 100755
index 0000000..0a1500a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/2d/59075e0681f540482d4f6223a68e0fef790bc7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54
new file mode 100755
index 0000000..321eaa8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc
new file mode 100755
index 0000000..9bb5b62
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057
new file mode 100755
index 0000000..7ca4cee
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
new file mode 100755
index 0000000..8953b6c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
@@ -0,0 +1,2 @@
+xŽQ
+Â0DýÎ)öÊ6›Í¦ "xO°‰‰-ØFb¼¿EoàÏ0¼Ç¤º,ske×[ÎPn8R,EpD?±gŸ}Ê^3²âÙ<µåµGŽhYKÄèÒ8ЖDAÉ)¿ÉÈ;gôݧÚàšjïp™4ÕŽ¯ô-çû¢óãêr‚ÁŠ;°s°GA4Ûº=ìùÖ(ôin7øIÌKÍFE
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/4b/22b35d44b5a4f589edf3dc89196399771796ea b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/4b/22b35d44b5a4f589edf3dc89196399771796ea
new file mode 100755
index 0000000..b4e5aa1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/4b/22b35d44b5a4f589edf3dc89196399771796ea differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/52/1d87c1ec3aef9824daf6d96cc0ae3710766d91 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/52/1d87c1ec3aef9824daf6d96cc0ae3710766d91
new file mode 100755
index 0000000..351cff8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/52/1d87c1ec3aef9824daf6d96cc0ae3710766d91 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
new file mode 100755
index 0000000..c1f22c5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
@@ -0,0 +1,2 @@
+xŽÛ	1EýNi@™Ék2 "X‚$ÙYW0YcÿíÀ¿Ã…s¸¥ÕzïÚÚõMDÏ€0æœ8!¶†ÉÌÞs‰XŠªgÚdí::@X0»P¢wÙ"F/‰‰œÍRàˆUz÷¥múZZïú²¤ÒV}|•/œo5݇ÒêI£!¬1z Æ:vùÇUim}ê/¢>
+öF-
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a
new file mode 100755
index 0000000..2ef4faa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af
new file mode 100755
index 0000000..716b0c6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af
@@ -0,0 +1 @@
+xŽAj!³ö?0¨£ßÂ09Êo}HÚ6¨}ÿôjUPP©ÕZ&Yÿø˜ AÔ›±€pŒÁFdë¼÷pz[fŽYŒ½PÒqLJ.,Z§`™Å®Ð.ù`’vÙ³q
$Æ5+9çOëtœû>Û/úDE/龡W¯ï*e¿§VŸdf1>ð覭Öê²×äÄ›¹úÊ™F« ­ìTŽÙhœk.i¶^0Ô?P¼R,
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/7b/4384978d2493e851f9cca7858815fac9b10980 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/7b/4384978d2493e851f9cca7858815fac9b10980
new file mode 100755
index 0000000..23c462f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/7b/4384978d2493e851f9cca7858815fac9b10980 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/81/4889a078c031f61ed08ab5fa863aea9314344d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/81/4889a078c031f61ed08ab5fa863aea9314344d
new file mode 100755
index 0000000..2f9b6b6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/81/4889a078c031f61ed08ab5fa863aea9314344d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/84/96071c1b46c854b31185ea97743be6a8774479 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/84/96071c1b46c854b31185ea97743be6a8774479
new file mode 100755
index 0000000..5df58dd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/84/96071c1b46c854b31185ea97743be6a8774479 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/84/9a5e34a26815e821f865b8479f5815a47af0fe b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/84/9a5e34a26815e821f865b8479f5815a47af0fe
new file mode 100755
index 0000000..71019a6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/84/9a5e34a26815e821f865b8479f5815a47af0fe
@@ -0,0 +1,2 @@
+xŒM F]sŠ¹€†Ÿ41ÆxÝ(­I‹ÁéÂÛKݽ/_ÞãP@¡ÚÕø¢!8›)es
+”	¥N&FGSÆ„¹hÑ{+ßCç‰÷ÆZzvØF¡7ZàÎ-¬Îñó‡k™x\ã¡[PÆ8ï´ôGØK/¥^©lÊ>.4
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162
new file mode 100755
index 0000000..4cc3f4d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162
@@ -0,0 +1 @@
+x+)JMU044b040031QrutñueX¡l¨ðmmA‹m›Ì£íJ}Gß;U‘T”˜—œŸ–™“ªWRQÂ`6ýš÷KÇ¥¶^/¾-*|òøWØ¥3P¥y©å`%ËEÛÞ±\&gŽÐ|Ÿ0§ÿ†{Ӎ1X
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4
new file mode 100755
index 0000000..bf7b2bb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/9f/13f7d0a9402c681f91dc590cf7b5470e6a77d2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/9f/13f7d0a9402c681f91dc590cf7b5470e6a77d2
new file mode 100755
index 0000000..7f1cfb2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/9f/13f7d0a9402c681f91dc590cf7b5470e6a77d2
@@ -0,0 +1,2 @@
+xŽM
+Â0F]ç³d2¤ñ®<A~&´`­ÄôþVàæãmïËë²ÌÈÒ¡7Uà$äJöL9yM!¢GuœªH¤&UÈæ›>;ÔÂÁ…¬£³X†ÂEÈŽ5R±£ ÛAÑE&n}ZÜæ<E}À=O[ÒÖáüÞéúÓ¼^À,ã^†#¢É¿ƒ]ÿPÍ`>™A¹
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
new file mode 100755
index 0000000..a796124
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
@@ -0,0 +1,3 @@
+xŽ[
+Â0EýÎ*fÊäÕ¤ "¸W0“‡-ØFâtÿ݁—çpS[–YÀ˜x^
+Díb	CLhutɉ}¥8X*4Zí¬sY½¨—UÀ‘AÃÖ
ÌX3‡R«Mµ¶) s6è¼¢M¦ÖážšÜ&Jm…ó;}Çõ±Ðü<¥¶\@›à‚ÑޏpÄ€¨vº?”ò«jÛºLð«¨Ø?Hå
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
new file mode 100755
index 0000000..f858869
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
@@ -0,0 +1,2 @@
+x;j1DëmdÓú·À˜ÇŽ|M«µ3`ŒV{>€³âQ¯ ¸·vL0I?Í!š4–Z=Ê! ×¦8²F¢Ã’!rÖsQßyÈ9]$DŽ&„l6AÇ>jFWüÒµIKNiûë§Z¢%¡SˆŒ‘
+‹Ò	­ÅʉøU~̽øä>'¼ï™û	¯wþ
×[ËÇ×÷öÚDGÚ¡±ðŒQ-ºMù«>dܶ‘OÞáÒò}í\à8g_ШÂoYr
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750
new file mode 100755
index 0000000..29c8e82
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750
@@ -0,0 +1,3 @@
+xŽQ
+!@ûösBQ"‚ŽÐ	ÆÙ±
rÍîßÒú{<xð¤·öàîƪ
+™HlJSer!ZPTe*Žj°UÝÑEo^¼ê2 (†ˆ¬XSÅ€ED‘ƒO<Y¦šj$2üs_á&}¸Î,}Ó[~p¹7~<ÒÛ:Ÿ	£°·ÉZ³Ùípè?­1_ûåC0
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd
new file mode 100755
index 0000000..d0d7e73
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6
new file mode 100755
index 0000000..18a7f61
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/ae/90f12eea699729ed24555e40b9fd669da12a12 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/ae/90f12eea699729ed24555e40b9fd669da12a12
new file mode 100755
index 0000000..d952546
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/ae/90f12eea699729ed24555e40b9fd669da12a12 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/b2/5fa35b38051e4ae45d4222e795f9df2e43f1d1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/b2/5fa35b38051e4ae45d4222e795f9df2e43f1d1
new file mode 100755
index 0000000..f460f25
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/b2/5fa35b38051e4ae45d4222e795f9df2e43f1d1
@@ -0,0 +1,2 @@
+xÌA
+Â0…a×9ÅìIÒ	™€ˆp'î§1Ñ¶‘v\x{cáýðVŸpƒvWûgŠ¾ÇŽ0xº[]"g†#{rDÆ
Cot ­äûN œU$­ò?9-p+1Í^¤ÀQx®¯Ï9O\ÆC¬Ó	Œm'D
{mµVêú(+´ñælè¶,Þ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593
new file mode 100755
index 0000000..f613670
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644
new file mode 100755
index 0000000..0817229
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644
@@ -0,0 +1,3 @@
+xKj1D³Ö)zçUBëÛ-0ÁuV9¦Õò<#£È÷ÏȲ+ŠW<Jú¶Ý&8Ê/s¨‚e‹µµÈ•KJ­«½S
+ØRvÌÁ{©æQ†îr«äY¹QN$H\Eµ²Íè=6áX5¦òÇK Fr)·(‰dC‡Î†”­–œ—jÊs®}À—ô9ác-Òw8Ëo¸\·r»¿IßÞÁ:
+l}F‚W$Ds´Ç£©ÿÙšOW…e”]V8-ÝÌÈ"U
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
new file mode 100755
index 0000000..75f541f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
@@ -0,0 +1,3 @@
+xŽQ
+Â0DýÎ)öʦ»I<‚'ØlR+˜Fj¼¿EoàÏ0<xÃh«õÞa Üõµ]È™­åXUlÞPF)Åz‘4yó”µ,\r	'SÂÄ-mI4
+‘Xhô”&òÌFÞ}n+\µõ—Y´-p|é·œoU¶z;-‘aÑlt{ØË?®I«,:ÃoÚR̳cHK
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/d0/7b0f9a8c89f1d9e74dc4fce6421dec5ef8a659 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/d0/7b0f9a8c89f1d9e74dc4fce6421dec5ef8a659
new file mode 100755
index 0000000..f3b46b3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/d0/7b0f9a8c89f1d9e74dc4fce6421dec5ef8a659 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f
new file mode 100755
index 0000000..a67d6e6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/d7/1aab4f9b04b45ce09bcaa636a9be6231474759 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/d7/1aab4f9b04b45ce09bcaa636a9be6231474759
new file mode 100755
index 0000000..2d47e6f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/d7/1aab4f9b04b45ce09bcaa636a9be6231474759 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100755
index 0000000..7112238
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0
new file mode 100755
index 0000000..b135ecc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3
new file mode 100755
index 0000000..82e2790
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1
new file mode 100755
index 0000000..697c94c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/fa/49b077972391ad58037050f2a75f74e3671e92 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/fa/49b077972391ad58037050f2a75f74e3671e92
new file mode 100755
index 0000000..112998d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/fa/49b077972391ad58037050f2a75f74e3671e92 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/fd/093bff70906175335656e6ce6ae05783708765 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/fd/093bff70906175335656e6ce6ae05783708765
new file mode 100755
index 0000000..12bf5f3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/fd/093bff70906175335656e6ce6ae05783708765 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/fd/4959ce7510db09d4d8217fa2d1780413e05a09 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/fd/4959ce7510db09d4d8217fa2d1780413e05a09
new file mode 100755
index 0000000..158aef2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/fd/4959ce7510db09d4d8217fa2d1780413e05a09 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx
new file mode 100755
index 0000000..5068f28
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack
new file mode 100755
index 0000000..a6a1f30
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx
new file mode 100755
index 0000000..94c3c71
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack
new file mode 100755
index 0000000..74c7fe4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx
new file mode 100755
index 0000000..555cfa9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.pack
new file mode 100755
index 0000000..4d539ed
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/packed-refs
new file mode 100755
index 0000000..506a860
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/packed-refs
@@ -0,0 +1,24 @@
+# pack-refs with: peeled 
+a4a7dce85cf63874e984719f4fdd239f5145052f refs/remotes/origin/br2
+a4a7dce85cf63874e984719f4fdd239f5145052f refs/remotes/origin/cannot-fetch
+e90810b8df3e80c413d903f631643c716887138d refs/remotes/origin/chomped
+258f0e2a959a364e40ed6603d5d44fbb24765b10 refs/remotes/origin/haacked
+a65fedf39aefe402d3bb6e24df4d4f5fe4547750 refs/remotes/origin/master
+a65fedf39aefe402d3bb6e24df4d4f5fe4547750 refs/remotes/origin/not-good
+41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9 refs/remotes/origin/packed
+4a202b346bb0fb0db7eff3cffeb3c70babbd2045 refs/remotes/origin/packed-test
+763d71aadf09a7951596c9746c024e7eece7c7af refs/remotes/origin/subtrees
+e90810b8df3e80c413d903f631643c716887138d refs/remotes/origin/test
+9fd738e8f7967c078dceed8190330fc8648ee56a refs/remotes/origin/track-local
+e90810b8df3e80c413d903f631643c716887138d refs/remotes/origin/trailing
+521d87c1ec3aef9824daf6d96cc0ae3710766d91 refs/tags/annotated_tag_to_blob
+^1385f264afb75a56a5bec74243be9b367ba4ca08
+7b4384978d2493e851f9cca7858815fac9b10980 refs/tags/e90810b
+^e90810b8df3e80c413d903f631643c716887138d
+849a5e34a26815e821f865b8479f5815a47af0fe refs/tags/hard_tag
+^a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+1385f264afb75a56a5bec74243be9b367ba4ca08 refs/tags/point_to_blob
+b25fa35b38051e4ae45d4222e795f9df2e43f1d1 refs/tags/test
+^e90810b8df3e80c413d903f631643c716887138d
+849a5e34a26815e821f865b8479f5815a47af0fe refs/tags/wrapped_tag
+^a65fedf39aefe402d3bb6e24df4d4f5fe4547750
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/refs/heads/master
new file mode 100755
index 0000000..3d8f0a4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/refs/heads/master
@@ -0,0 +1 @@
+a65fedf39aefe402d3bb6e24df4d4f5fe4547750
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..6efe28f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/modules/submodule/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/08/585692ce06452da6f82ae66b90d98b55536fca b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/08/585692ce06452da6f82ae66b90d98b55536fca
new file mode 100755
index 0000000..39d126b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/08/585692ce06452da6f82ae66b90d98b55536fca
@@ -0,0 +1 @@
+x+)JMU06f040031QHÔ+©(a¨˜!©”h­õ;A•EÿÛÞö®ƒ3ýZüÝ*
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/27/b7ce66243eb1403862d05f958c002312df173d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/27/b7ce66243eb1403862d05f958c002312df173d
new file mode 100755
index 0000000..01d63b5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/27/b7ce66243eb1403862d05f958c002312df173d
@@ -0,0 +1,4 @@
+x•ŽM
+Â0F]çsËt¦i<„7ù™Ñ‚m¤¤¨··xw÷àKešÆ
+Dý®." ªâmrš1°Ó@’’ê9Ú>RëûÈž¬y†Eæ
+Á
mâHŽì&µ™EÐr7äS¢Þ!*u΄µÞËç2ß>#\V8¤ß|­§ÛÆG“Êt„–-ybÂöhÍF·Uþ/ä±J-|M}Wóã+GK
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/28/905c54ea45a4bed8d7b90f51bd8bd81eec8840 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/28/905c54ea45a4bed8d7b90f51bd8bd81eec8840
new file mode 100755
index 0000000..dc10f68
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/28/905c54ea45a4bed8d7b90f51bd8bd81eec8840 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/36/6226fb970ac0caa9d3f55967ab01334a548f60 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/36/6226fb970ac0caa9d3f55967ab01334a548f60
new file mode 100755
index 0000000..45c4d92
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/36/6226fb970ac0caa9d3f55967ab01334a548f60 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/36/f79b2846017d3761e0a02d0bccd573e0f90c57 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/36/f79b2846017d3761e0a02d0bccd573e0f90c57
new file mode 100755
index 0000000..0bc57f2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/36/f79b2846017d3761e0a02d0bccd573e0f90c57
@@ -0,0 +1,2 @@
+x%Œ]
+ƒ0„ûœSì”Ä͏B)}é
¼@bµnÑéíf`f`>ö3(§nÞibˆC°èû¾ë0öhQ6¢BåMv¨‡à2&-ø÷M0Q)+®Œêæª
tNsÚà¿E*;}àžøJϲN픹­§(th­ÔÖ@#”BŒËºC•?ÉÀTÃ…oÅyk7ÿ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/5c/0bb3d1b9449d1cc69d7519fd05166f01840915 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/5c/0bb3d1b9449d1cc69d7519fd05166f01840915
new file mode 100755
index 0000000..8831821
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/5c/0bb3d1b9449d1cc69d7519fd05166f01840915 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/61/780798228d17af2d34fce4cfbdf35556832472 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/61/780798228d17af2d34fce4cfbdf35556832472
new file mode 100755
index 0000000..586bf17
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/61/780798228d17af2d34fce4cfbdf35556832472 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/64/fd55f9b6390202db5e5666fd1fb339089fba4d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/64/fd55f9b6390202db5e5666fd1fb339089fba4d
new file mode 100755
index 0000000..bcaaa91
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/64/fd55f9b6390202db5e5666fd1fb339089fba4d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/78/981922613b2afb6025042ff6bd878ac1994e85 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/78/981922613b2afb6025042ff6bd878ac1994e85
new file mode 100755
index 0000000..e814d07
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/78/981922613b2afb6025042ff6bd878ac1994e85 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/80/5c54522e614f29f70d2413a0470247d8b424ac b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/80/5c54522e614f29f70d2413a0470247d8b424ac
new file mode 100755
index 0000000..552670c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/80/5c54522e614f29f70d2413a0470247d8b424ac differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/95/1bbbb90e2259a4c8950db78946784fb53fcbce b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/95/1bbbb90e2259a4c8950db78946784fb53fcbce
new file mode 100755
index 0000000..596cd43
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/95/1bbbb90e2259a4c8950db78946784fb53fcbce
@@ -0,0 +1,2 @@
+x•[JÆ0…}î*f¿2—Ì$ÁEøœi’úƒm¥¶ˆ»·
+úîÛáã\8ã:Ï×DôfßZ½ªöì&¹º65³^©»œ,åî%Ôá­lmÙ¡~;KJÌR“XT²®è•„Šö(!{ìÒ¯Ÿ£Ç±™qæP’qÅsPÓˆÈB\;EùëïE’gê”s–`IeoEÈ(YMŽ˜FåÂC9ö—uƒ§u™>¯ð|Àýø#?ŽÇi.××»q€D9³0F¸EENzþßÛÿ“Ãܶ©Ë<\ ,\a_a.ïgßðëd
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/a7/8705c3b2725f931d3ee05348d83cc26700f247 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/a7/8705c3b2725f931d3ee05348d83cc26700f247
new file mode 100755
index 0000000..6ad835e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/a7/8705c3b2725f931d3ee05348d83cc26700f247 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/b4/83ae7ba66decee9aee971f501221dea84b1498 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/b4/83ae7ba66decee9aee971f501221dea84b1498
new file mode 100755
index 0000000..1e0bd3b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/b4/83ae7ba66decee9aee971f501221dea84b1498
@@ -0,0 +1,3 @@
+x5K
+1D]ç½¥;1i"^À•'èÎô|d`dŒooqQE½Í«*PàÝ¢+
+á	3…$,
}ì%¢Rßw¬É+sç9»úy輨«ÍÐrøÃ`+ܦ2ŠÍp/ã[m­p~µuÝê8-—öSˆ™r„=¢Û,?ÃZ+g
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/b4/e1f2b375a64c1ccd40c5ff6aa8bc96839ba4fd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/b4/e1f2b375a64c1ccd40c5ff6aa8bc96839ba4fd
new file mode 100755
index 0000000..4e650aa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/b4/e1f2b375a64c1ccd40c5ff6aa8bc96839ba4fd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/c1/0409136a7a75e025fa502a1b2fd7b62b77d279 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/c1/0409136a7a75e025fa502a1b2fd7b62b77d279
new file mode 100755
index 0000000..fcb2b32
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/c1/0409136a7a75e025fa502a1b2fd7b62b77d279 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/cd/881f90f2933db2e4cc26b8c71fe6037ac7fe4c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/cd/881f90f2933db2e4cc26b8c71fe6037ac7fe4c
new file mode 100755
index 0000000..ad42726
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/cd/881f90f2933db2e4cc26b8c71fe6037ac7fe4c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/d9/b63a88223d8367516f50bd131a5f7349b7f3e4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/d9/b63a88223d8367516f50bd131a5f7349b7f3e4
new file mode 100755
index 0000000..b471e21
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/d9/b63a88223d8367516f50bd131a5f7349b7f3e4
@@ -0,0 +1,2 @@
+x•ŽA
+Â0E]çsËd¦Ó$ "x×i2Õ‚m¤¤¨··zwŸ÷S™¦±‘ÝÕErŠ½gjÃÐ
![ÍŽ%wbY(z˜C/ÁšG\t®w(‰{r$C`›Y…[Ÿ=§DC¨u&®õV8—ùúá²Â!ýæs=]§8Þ›T¦#|;˜ÐÂÑltûWõÓh«fˆM}Uó¼QDM
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/dc/ab83249f6f9d1ed735d651352a80519339b591 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/dc/ab83249f6f9d1ed735d651352a80519339b591
new file mode 100755
index 0000000..9f6b150
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/dc/ab83249f6f9d1ed735d651352a80519339b591 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/ee/a4f2705eeec2db3813f2430829afce99cd00b5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/ee/a4f2705eeec2db3813f2430829afce99cd00b5
new file mode 100755
index 0000000..b7b81d5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/ee/a4f2705eeec2db3813f2430829afce99cd00b5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/f7/8a3106c85fb549c65198b2a2086276c6174928 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/f7/8a3106c85fb549c65198b2a2086276c6174928
new file mode 100755
index 0000000..b981357
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/f7/8a3106c85fb549c65198b2a2086276c6174928 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/f8/f7aefc2900a3d737cea9eee45729fd55761e1a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/f8/f7aefc2900a3d737cea9eee45729fd55761e1a
new file mode 100755
index 0000000..888354f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/f8/f7aefc2900a3d737cea9eee45729fd55761e1a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/fa/38b91f199934685819bea316186d8b008c52a2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/fa/38b91f199934685819bea316186d8b008c52a2
new file mode 100755
index 0000000..13d9bca
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/fa/38b91f199934685819bea316186d8b008c52a2
@@ -0,0 +1,2 @@
+x•½J1„­ó§ÛÊ5›ÿ…‹>„urr²n’eo‚øö{»™f[)¹ƒ°â©_DmIiµ7
+7Ĩ8ꔌ÷.ànœÜƒW)²Ó_T;xë,×(ÃlÐi—[”D\K墓ˆÂXΓP–ùÑ?Ûï­ß>ÜðW~·£ø|_±•Wؤ»‚xæšs6éÜ×éÿIæc¤J‹ãNP}™~ùœ-מë½Á²®/ó„³­Gîû§X
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/ff/83aa4c5e5d28e3bcba2f5c6e2adc61286a4e5e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/ff/83aa4c5e5d28e3bcba2f5c6e2adc61286a4e5e
new file mode 100755
index 0000000..10f25eb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/ff/83aa4c5e5d28e3bcba2f5c6e2adc61286a4e5e
@@ -0,0 +1,4 @@
+x5ÍM
+1`×=Eö¢4ÓNAĸòýÉüÈÀHooq‘Ç{›/G@ò»5=$+”SOÝ)n¥xâ≻Ø[Æ@4úy
+h1Ú„v‡ÿ¥ÂmÎS”îyz'©
+çWk×-ŽóziÙQc<ÃÞ¢µfS~Âpv+…
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/ff/fe95c7fd0a37fa2ed702f8f93b56b2196b3925 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/ff/fe95c7fd0a37fa2ed702f8f93b56b2196b3925
new file mode 100755
index 0000000..1cdc048
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/ff/fe95c7fd0a37fa2ed702f8f93b56b2196b3925 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/pack/dummy b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/objects/pack/dummy
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b1
new file mode 100755
index 0000000..afadf9d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b1
@@ -0,0 +1 @@
+a78705c3b2725f931d3ee05348d83cc26700f247
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b2
new file mode 100755
index 0000000..afadf9d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b2
@@ -0,0 +1 @@
+a78705c3b2725f931d3ee05348d83cc26700f247
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b3
new file mode 100755
index 0000000..3056bb4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b3
@@ -0,0 +1 @@
+d9b63a88223d8367516f50bd131a5f7349b7f3e4
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b4
new file mode 100755
index 0000000..efed6f0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b4
@@ -0,0 +1 @@
+27b7ce66243eb1403862d05f958c002312df173d
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b5
new file mode 100755
index 0000000..cf313ad
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b5
@@ -0,0 +1 @@
+fa38b91f199934685819bea316186d8b008c52a2
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b6
new file mode 100755
index 0000000..711e466
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/heads/b6
@@ -0,0 +1 @@
+951bbbb90e2259a4c8950db78946784fb53fcbce
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-blob b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-blob
new file mode 100755
index 0000000..abfebf2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-blob
@@ -0,0 +1 @@
+b483ae7ba66decee9aee971f501221dea84b1498
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-commit b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-commit
new file mode 100755
index 0000000..c023b84
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-commit
@@ -0,0 +1 @@
+805c54522e614f29f70d2413a0470247d8b424ac
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-commit-two b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-commit-two
new file mode 100755
index 0000000..abb3650
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-commit-two
@@ -0,0 +1 @@
+36f79b2846017d3761e0a02d0bccd573e0f90c57
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-lightweight b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-lightweight
new file mode 100755
index 0000000..711e466
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-lightweight
@@ -0,0 +1 @@
+951bbbb90e2259a4c8950db78946784fb53fcbce
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-tag b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-tag
new file mode 100755
index 0000000..d6cd748
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-tag
@@ -0,0 +1 @@
+eea4f2705eeec2db3813f2430829afce99cd00b5
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-tree b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-tree
new file mode 100755
index 0000000..7a530d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/.gitted/refs/tags/tag-tree
@@ -0,0 +1 @@
+ff83aa4c5e5d28e3bcba2f5c6e2adc61286a4e5e
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/a.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/a.txt
new file mode 100755
index 0000000..f7eac1c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/a.txt
@@ -0,0 +1,2 @@
+a
+edit
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/fold/b.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/fold/b.txt
new file mode 100755
index 0000000..6178079
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/fold/b.txt
@@ -0,0 +1 @@
+b
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/foldb.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/foldb.txt
new file mode 100755
index 0000000..5b38718
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/foldb.txt
@@ -0,0 +1 @@
+edit
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/gitmodules b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/gitmodules
new file mode 100755
index 0000000..f1734df
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/gitmodules
@@ -0,0 +1,3 @@
+[submodule "submodule"]
+	path = submodule
+	url = ../testrepo.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/submodule/.gitted b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/submodule/.gitted
new file mode 100755
index 0000000..3ffcf96
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/submodule/.gitted
@@ -0,0 +1 @@
+gitdir: ../.git/modules/submodule
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/submodule/README b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/submodule/README
new file mode 100755
index 0000000..ca8c647
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/submodule/README
@@ -0,0 +1 @@
+hey there
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/submodule/branch_file.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/submodule/branch_file.txt
new file mode 100755
index 0000000..a269025
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/submodule/branch_file.txt
@@ -0,0 +1,2 @@
+hi
+bye!
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/submodule/new.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/submodule/new.txt
new file mode 100755
index 0000000..8e0884e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/push_src/submodule/new.txt
@@ -0,0 +1 @@
+my new file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/config
new file mode 100755
index 0000000..17e58b1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/config
@@ -0,0 +1,4 @@
+[core]
+	repositoryformatversion = 0
+	bare = false
+	logallrefupdates = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/index
new file mode 100755
index 0000000..0f53a21
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/logs/HEAD
new file mode 100755
index 0000000..62d3b16
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/logs/HEAD
@@ -0,0 +1 @@
+efad0b11c47cb2f0220cbd6f5b0f93bb99064b00 efad0b11c47cb2f0220cbd6f5b0f93bb99064b00 Edward Thomson <ethomson at edwardthomson.com> 1405623541 -0400	checkout: moving from master to master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/00/66204dd469ee930e551fbcf123f98e211c99ce b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/00/66204dd469ee930e551fbcf123f98e211c99ce
new file mode 100755
index 0000000..e6f72ce
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/00/66204dd469ee930e551fbcf123f98e211c99ce differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/00/f1b9a0948a7d5d14405eba6030efcdfbb8ff4a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/00/f1b9a0948a7d5d14405eba6030efcdfbb8ff4a
new file mode 100755
index 0000000..a23f526
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/00/f1b9a0948a7d5d14405eba6030efcdfbb8ff4a
@@ -0,0 +1,3 @@
+x¥ŽAnC!D»æ¾@*À𑪪YäÙGå/~ˆ(U¯ZåÙͼ‘f¦´}ßX
+o£«B%
+BU«#DGa‘‚9øì"R”H~±.-HæÎ]o˜}ñ–µH-±HZSÎÅYLÉyåIØU/ëjøg\[‡“ür8_ÛþÝnð¡“þ©/ýžî½´ýì¼fá€ÑL:Ï}±ÆE¶±ÍùVAú¦r¹+›øT
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/01/3cc32d341bab0e6f039f50f153c18986f16c58 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/01/3cc32d341bab0e6f039f50f153c18986f16c58
new file mode 100755
index 0000000..2e32bd3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/01/3cc32d341bab0e6f039f50f153c18986f16c58 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/01/a17f7d154ab5bf9f8bfede3d82dd00ddf7e7dc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/01/a17f7d154ab5bf9f8bfede3d82dd00ddf7e7dc
new file mode 100755
index 0000000..c21329f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/01/a17f7d154ab5bf9f8bfede3d82dd00ddf7e7dc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/02/2d3b6bbd0bfbdf147319476fb8bf405691cb0d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/02/2d3b6bbd0bfbdf147319476fb8bf405691cb0d
new file mode 100755
index 0000000..b1f7468
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/02/2d3b6bbd0bfbdf147319476fb8bf405691cb0d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/05/3808a709cf91385985369159b296cf61a177ac b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/05/3808a709cf91385985369159b296cf61a177ac
new file mode 100755
index 0000000..c38c5b2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/05/3808a709cf91385985369159b296cf61a177ac differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/0e/f2e2b2a2b8d6e1f8dff5e621e0eca21b693d0c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/0e/f2e2b2a2b8d6e1f8dff5e621e0eca21b693d0c
new file mode 100755
index 0000000..d8ef47c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/0e/f2e2b2a2b8d6e1f8dff5e621e0eca21b693d0c
@@ -0,0 +1,3 @@
+x¥P»N1¤öWl—
+´g¯í³„"J:~`½^ç"åÎÈ1Aü=‚/ ›—Fš‘¶®çnrw£«B‘Y9g/U­
+¦ä“ÄJ“÷ÌÑ‘Mµ$óÆ]·$,jÐHÈ>K Êìœ"åY+FçÊÌ“y»»¢3YL¤8kf™¼Í®„â3ÖZ]ªI‚~Këð\>¸x]Úzm<ê®~£'ý1~Ùƒ´õ¡Ö:"¸GB4»ºúÏó¢ý´_Óy“§Î·Ïœ·Ñà¦|1_"fi
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/0f/5f6d3353be1a9966fa5767b7d604b051798224 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/0f/5f6d3353be1a9966fa5767b7d604b051798224
new file mode 100755
index 0000000..739aca3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/0f/5f6d3353be1a9966fa5767b7d604b051798224 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/11/fac10ca1b9318ce361a0be0c3d889d777e299c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/11/fac10ca1b9318ce361a0be0c3d889d777e299c
new file mode 100755
index 0000000..5af5474
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/11/fac10ca1b9318ce361a0be0c3d889d777e299c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/12/c084412b952396962eb420716df01022b847cc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/12/c084412b952396962eb420716df01022b847cc
new file mode 100755
index 0000000..5244e46
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/12/c084412b952396962eb420716df01022b847cc
@@ -0,0 +1,2 @@
+x¥ŽKjC1³Ö)æúÌèIB6^z—Œ¤äYAQ0¾½ãd×Õ
Må¾ïm‚¥ø2‡¸Â8³)!–m“JÄ¡È"Œ‰ML¨¾yÈe‚6.gg‹C“8iñU»XIWC.›ƒ¯Æg
+Šç¹8–+Ÿç¾ÿô¼ÉjÿÒ‡<†'½æ¾¿ƒAMÞZô4j­V»d§üóFziµežm) ̉ǗÜÔK€U
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/12/f28ed978639d331269d9dc2b74e87db58e1057 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/12/f28ed978639d331269d9dc2b74e87db58e1057
new file mode 100755
index 0000000..b0dbc3e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/12/f28ed978639d331269d9dc2b74e87db58e1057
@@ -0,0 +1,3 @@
+x¥O9nÃ0tÍWìbp)‰KF&e:`¹\Ú*$…|?´á¸›3˜‘º,sçÝ©mª€XXÐ
+cŠÑÁ#Û¤V†BÌD¤.F1¿¼éÚ€„R	“F
+sØÉûBÖe'‰Èû%ä±>Ú½nðÿxËp½×e¯+\´«ô¥OãÅÎR—OÀ±—9ôãv´Ötµmúfù©y.³p›û„V÷þ‡oÇnþB#Vj
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/19/14d57ddf6c5c997664521cc94f190df46dc1c2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/19/14d57ddf6c5c997664521cc94f190df46dc1c2
new file mode 100755
index 0000000..921f2cd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/19/14d57ddf6c5c997664521cc94f190df46dc1c2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/1b/1d19799fcc89fa3cb821581fcf7f2e8fd2cc4d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/1b/1d19799fcc89fa3cb821581fcf7f2e8fd2cc4d
new file mode 100755
index 0000000..3d206b0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/1b/1d19799fcc89fa3cb821581fcf7f2e8fd2cc4d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/1f/2214c1b13b134d5508f41f6a3b77cc6a8f5182 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/1f/2214c1b13b134d5508f41f6a3b77cc6a8f5182
new file mode 100755
index 0000000..84b875c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/1f/2214c1b13b134d5508f41f6a3b77cc6a8f5182 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/20/db906c85e78c6dde82eb2ec6d3231c4b96fce8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/20/db906c85e78c6dde82eb2ec6d3231c4b96fce8
new file mode 100755
index 0000000..2a908da
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/20/db906c85e78c6dde82eb2ec6d3231c4b96fce8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/22/adb22bef75a0371e85ff6d82e5e60e4b425501 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/22/adb22bef75a0371e85ff6d82e5e60e4b425501
new file mode 100755
index 0000000..7f17ef0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/22/adb22bef75a0371e85ff6d82e5e60e4b425501 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/2a/a3ce842094e08ebac152b3d6d5b0fff39f9c6e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/2a/a3ce842094e08ebac152b3d6d5b0fff39f9c6e
new file mode 100755
index 0000000..38eca43
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/2a/a3ce842094e08ebac152b3d6d5b0fff39f9c6e
@@ -0,0 +1 @@
+x¥ŽMn!F³æ¾@#8RTeÓew¹€!™Å„ˆ’V½}hÕt÷ýHO/·m[¸…v£—Ñg$©H$ÄÈb…•Œ¨ÙW	>*jU̝{¹
R4¡Öd19ò™sD‘š\ÄCb¼ðäQ0ü×ÖáM¿¸+œ¯mûh78–¹þ¤Sù=þÚ>·í0Ø%:ç-‹
Öš¹NÙQþ‰1ïM׺fëTp0\:~›'fÐUN
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/2b/4ebffd3111546d278bb5df62e5630930b605fb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/2b/4ebffd3111546d278bb5df62e5630930b605fb
new file mode 100755
index 0000000..5bdfc1e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/2b/4ebffd3111546d278bb5df62e5630930b605fb differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/30/69cc907e6294623e5917ef6de663928c1febfb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/30/69cc907e6294623e5917ef6de663928c1febfb
new file mode 100755
index 0000000..edd86f7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/30/69cc907e6294623e5917ef6de663928c1febfb
@@ -0,0 +1 @@
+x¥Ž;n1DSë¼€RŸ]	07.ÓåEÂ[¬eldøúÞ¾Aº™7ÀàI_×e€OóÇØT!&Ɛ[ËÅUö5´¹R¬L–ÑP±¸oz+Ab)ižçF¾ø8±Ù«Ç÷qéœÛƒ·?—¾þö+u§餯áÝ>¥¯_@Óä)§Œˆn§»ìÐÞ¸ïÞ[„Dz+ªª¹'TG
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/32/52a0692ace4c4c709f22011227d9dc4845f289 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/32/52a0692ace4c4c709f22011227d9dc4845f289
new file mode 100755
index 0000000..2b2434f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/32/52a0692ace4c4c709f22011227d9dc4845f289 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/33/f915f9e4dbd9f4b24430e48731a59b45b15500 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/33/f915f9e4dbd9f4b24430e48731a59b45b15500
new file mode 100755
index 0000000..c33f179
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/33/f915f9e4dbd9f4b24430e48731a59b45b15500
@@ -0,0 +1 @@
+x¥Ûi1Eó­*¦iViÁ„@Hi@[­Â®Lڏb܁ÿî.çæÞZ€Þ¾Œ0YN"e1Æ8K}HÉ!dG‹^H;Iê'î¼
ðÙ'	ŽWIJvDâ5ÌÉ{¢´æP¬¨x×¾Ãgù{¯koGßàÌ3ýWï|/î”{{cç¢F‚WmµV3°ƒŸœQ}“ïšGÝ.Ðz©Rsuââ1¿ÅËíPH¾ZÞ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/34/86a9d4cdf0b7b4a702c199eed541dc3af13a03 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/34/86a9d4cdf0b7b4a702c199eed541dc3af13a03
new file mode 100755
index 0000000..fdbe16d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/34/86a9d4cdf0b7b4a702c199eed541dc3af13a03
@@ -0,0 +1 @@
+xM½nÃ0„;ë)îŒ,‚L-Э@ƒþe›Ž…Ò¢*Quüö¥…è"Ç#ï#{–÷ÇãÝãÃëóÓ'Þ^>ÎçÎU!:g"\sLè}fÚº?ù»ú¬M_½Rî0ÑjMAbÁ`ý5u®„+Ÿ³˜±Ù'áãØê!ª`u&lÞ¨A·=MkŽ!µY®,žù„^#(.•7è*˜¥æ²#QD²Ô1™ɘÂ!Ic£4‹Ë~øÚK‘öÂRU%@ƒ/l4ÍËdH³_:¬Ag$J‰r#/žõän …eý–x¹9)[¾ÑÖtÀ»,^¥Àg²1Ž®1ÛðãÔn;†ÎÁÎ$æw¿/Š
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/3c/33b080bf75724c8899d8e703614cb59bfbd047 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/3c/33b080bf75724c8899d8e703614cb59bfbd047
new file mode 100755
index 0000000..8716898
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/3c/33b080bf75724c8899d8e703614cb59bfbd047 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/3d/a85aca38a95b44d77ef55a8deb445e49ba19b4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/3d/a85aca38a95b44d77ef55a8deb445e49ba19b4
new file mode 100755
index 0000000..fa6d946
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/3d/a85aca38a95b44d77ef55a8deb445e49ba19b4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/3e/8989b5a16d5258c935d998ef0e6bb139cc4757 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/3e/8989b5a16d5258c935d998ef0e6bb139cc4757
new file mode 100755
index 0000000..1bbf138
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/3e/8989b5a16d5258c935d998ef0e6bb139cc4757
@@ -0,0 +1,2 @@
+x¥ŽKj1†»ö)tù1¶Jé&Ëìz%C'.®›\?nÈ
ºûðñå¶ïu€[ÒËèªPŠ¦ÕÓŠ™"åÀ›%¬Cñ¢0+›oîzrÚ
+-º&*V,e\b,	¸¼¥ã¶f’PÿŽsëp”wÏsÛÚÞt®éCdz½æ¶¿ƒ
æœwÓÍ\§ìÐbÌ©I-5ó¨SÁÂhpUþ2w_ÎT
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/3f/05a038dd89f51ba2b3d7b14ba1f8c00f0e31ac b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/3f/05a038dd89f51ba2b3d7b14ba1f8c00f0e31ac
new file mode 100755
index 0000000..26bd353
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/3f/05a038dd89f51ba2b3d7b14ba1f8c00f0e31ac differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/3f/d8d53cf02de539b9a25a5941030451f76a152f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/3f/d8d53cf02de539b9a25a5941030451f76a152f
new file mode 100755
index 0000000..91c4d95
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/3f/d8d53cf02de539b9a25a5941030451f76a152f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/40/0d89e8ee6cd91b67b1f45de1ca190e1c580c6f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/40/0d89e8ee6cd91b67b1f45de1ca190e1c580c6f
new file mode 100755
index 0000000..f674753
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/40/0d89e8ee6cd91b67b1f45de1ca190e1c580c6f
@@ -0,0 +1 @@
+x¥O;Â0eÎ)|P·•badãqC‡6¨
âúÄ
ØÞGzŸT¦i¬àÉoê’3XŲ²¨º!t¤Ü³»§Á%¶bqÉsQAñ{OÔ$†>ŠïI1aPTb´ƒëM|Ö{Yà,¯¸\ïeZË‡ÜÔ:å¯ñc»T¦#¸OwÔ!lm°Ö4µ­ùÏs)2ê˜bÛ„Z ®íO¼=Wó>{VT
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/41/4dfc71ead79c07acd4ea47fecf91f289afc4b9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/41/4dfc71ead79c07acd4ea47fecf91f289afc4b9
new file mode 100755
index 0000000..546815e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/41/4dfc71ead79c07acd4ea47fecf91f289afc4b9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/41/c5a0a761bb4a7670924c1af0800b30fe9a21be b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/41/c5a0a761bb4a7670924c1af0800b30fe9a21be
new file mode 100755
index 0000000..ecb3992
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/41/c5a0a761bb4a7670924c1af0800b30fe9a21be differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/42/cdad903aef3e7b614675e6584a8be417941911 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/42/cdad903aef3e7b614675e6584a8be417941911
new file mode 100755
index 0000000..99b5e6d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/42/cdad903aef3e7b614675e6584a8be417941911 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/44/c801fe026abbc141b52a4dec5df15fa98249c6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/44/c801fe026abbc141b52a4dec5df15fa98249c6
new file mode 100755
index 0000000..eaf24ae
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/44/c801fe026abbc141b52a4dec5df15fa98249c6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/4b/21eb6eeeec7f8fc89a1d334faff9bd5f5f8c34 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/4b/21eb6eeeec7f8fc89a1d334faff9bd5f5f8c34
new file mode 100755
index 0000000..0c9f4b9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/4b/21eb6eeeec7f8fc89a1d334faff9bd5f5f8c34
@@ -0,0 +1,2 @@
+x¥]J1„}Î)úJOÒ™L`A¼èt:»3‘™,^ß(ÞÀ·úâ+é­Õ6ÐÃ8TÁ‰s	7L%ø`I¶-Ƽi@·.$ÉÇTRF
+æ“Ýl¾8ÂQ±8—i¡•‹J”¤ží:g<"¾[?à-ñ‘áýÖÛÙw¸èLÔ‹þîIz{†…ЯÖbpðˆ„hf:a‡þsƼö½|Tu¿Bë¹–*<êÄ!øœßøz?Í72ZÝ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/4b/7c5650008b2e747fe1809eeb5a1dde0e80850a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/4b/7c5650008b2e747fe1809eeb5a1dde0e80850a
new file mode 100755
index 0000000..0163985
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/4b/7c5650008b2e747fe1809eeb5a1dde0e80850a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/4b/ed71df7017283cac61bbf726197ad6a5a18b84 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/4b/ed71df7017283cac61bbf726197ad6a5a18b84
new file mode 100755
index 0000000..f206618
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/4b/ed71df7017283cac61bbf726197ad6a5a18b84
@@ -0,0 +1,2 @@
+x¥Ž;nB1ES{³ Ûø3–PD“’.ÇáGÆ€Ø=bt÷#nëº°?FAdÖ’IO‰ÅÎh$ÛœI¶[
+Ϋ?êr9æŠ^RÄjŠAÖ>„µ-–sŒ!äÄX\UtÇÖá»Ü¨ø9¶õÜN°“¹þ§½<WÛp[¿À¸	³Ö&
ŸÚi­æ:e‡¼‰Q‡V–º0e*
~;]ïêMÿU9
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/4c/acc6f6e740a5bc64faa33e04b8ef0733d8a127 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/4c/acc6f6e740a5bc64faa33e04b8ef0733d8a127
new file mode 100755
index 0000000..36a6b31
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/4c/acc6f6e740a5bc64faa33e04b8ef0733d8a127 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/4f/b698bde45d7d2833e3f2aacfbfe8a7e7f60a65 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/4f/b698bde45d7d2833e3f2aacfbfe8a7e7f60a65
new file mode 100755
index 0000000..8bb69d0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/4f/b698bde45d7d2833e3f2aacfbfe8a7e7f60a65 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/50/8be4ff49d38465ad3de58f66d38f70e59f881f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/50/8be4ff49d38465ad3de58f66d38f70e59f881f
new file mode 100755
index 0000000..7ce4452
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/50/8be4ff49d38465ad3de58f66d38f70e59f881f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/53/f75e45a463033854e52fa8d39dc858e45537d0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/53/f75e45a463033854e52fa8d39dc858e45537d0
new file mode 100755
index 0000000..f25ef1f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/53/f75e45a463033854e52fa8d39dc858e45537d0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/58/8e5d2f04d49707fe4aab865e1deacaf7ef6787 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/58/8e5d2f04d49707fe4aab865e1deacaf7ef6787
new file mode 100755
index 0000000..766adc1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/58/8e5d2f04d49707fe4aab865e1deacaf7ef6787
@@ -0,0 +1 @@
+x¥ŽK!D]sŠ¾€†o‰1n\ºóÐ4™YÌ`FŒ×7pWõ*©<jË2wÐÎïúÆÙ“3˜\†B*‰³±Å±Š\2%çB(Cvâž6^;‰‘(JϨ£EmØEå¹baDu U9×,Ò³OmƒKy¥­ÀmjË£­päA?éÌßá×Ô–(+j¼„½´RŠA‡lç?oĵ•¹Î”ú<,ô™¹Š7è_T
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/5b/1e8bccf7787e942aecf61912f94a2c274f85a5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/5b/1e8bccf7787e942aecf61912f94a2c274f85a5
new file mode 100755
index 0000000..d4776d8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/5b/1e8bccf7787e942aecf61912f94a2c274f85a5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/60/29cb003b59f710f9a8ebd9da9ece2d73070b69 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/60/29cb003b59f710f9a8ebd9da9ece2d73070b69
new file mode 100755
index 0000000..a48e023
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/60/29cb003b59f710f9a8ebd9da9ece2d73070b69 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/61/139b9b40a3e489f4abbc6af14e10ae14006e47 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/61/139b9b40a3e489f4abbc6af14e10ae14006e47
new file mode 100755
index 0000000..b096a96
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/61/139b9b40a3e489f4abbc6af14e10ae14006e47 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/61/30e5fcbdce2aa8b3cfd84706c58a892e7d8dd0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/61/30e5fcbdce2aa8b3cfd84706c58a892e7d8dd0
new file mode 100755
index 0000000..116da7c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/61/30e5fcbdce2aa8b3cfd84706c58a892e7d8dd0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/63/c18bf188b8a1ab0bad85161dc3fb43c48ed0db b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/63/c18bf188b8a1ab0bad85161dc3fb43c48ed0db
new file mode 100755
index 0000000..297c432
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/63/c18bf188b8a1ab0bad85161dc3fb43c48ed0db differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/67/ed7afb256807556f9b74fa4f7c9284aaec1120 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/67/ed7afb256807556f9b74fa4f7c9284aaec1120
new file mode 100755
index 0000000..82da206
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/67/ed7afb256807556f9b74fa4f7c9284aaec1120 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/68/af1fc7407fd9addf1701a87eb1c95c7494c598 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/68/af1fc7407fd9addf1701a87eb1c95c7494c598
new file mode 100755
index 0000000..6aaf79f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/68/af1fc7407fd9addf1701a87eb1c95c7494c598 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/68/f6182f4c85d39e1309d97c7e456156dc9c0096 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/68/f6182f4c85d39e1309d97c7e456156dc9c0096
new file mode 100755
index 0000000..ed1de3a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/68/f6182f4c85d39e1309d97c7e456156dc9c0096 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/6c/8e16469b6ca09a07e00f0e07a5143c31dcfb64 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/6c/8e16469b6ca09a07e00f0e07a5143c31dcfb64
new file mode 100755
index 0000000..2b8d569
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/6c/8e16469b6ca09a07e00f0e07a5143c31dcfb64
@@ -0,0 +1 @@
+xERKnÛ0횧x²+Z +5U’-Dò(jd¢I†Ÿ¾}‡´Ú®Dˆ3ïËɸ	_¿ûÒ}ûÞ¾œÇSÿ Ä(7Ââr€‘áL˜²U+E¸2zä9ÇQé	:ÁjEæÖàé4âøüŒã¡Ã¯ÃÓ«à…´’ó</íÌx·òçmq•‰Bµ:_§b’f‹u¬g ñµ{c¤ò‹„«N+$¼&EEÊ$•³»‹tV;•²¿“õ]ßwïh?1´¿ÇG!çéêð‘eHÕήarÚÜu%mê	Õ0ñG։ݒš¢æ |6Uò…w‚Ëç"+jú¤;oLA²¿â¼â³N©ÁuÕjÅÛiñ£{la+Q”QïÒ#<Ë׶Î3¦â…þ›ª	°ŒÇ~à¤Å¿6vìUΘˆ7ŒÔ|âJª3®([vVx"ñeLà´2\ª$b^­4Ùdn˜e#i箜‹áÇÀ`9qeµ¡‹6Ûî–Âg}Ù?ˆ?QÂȃ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/6d/77ce8fa2cd93c6489236e33e45e35203ca748c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/6d/77ce8fa2cd93c6489236e33e45e35203ca748c
new file mode 100755
index 0000000..5c3f686
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/6d/77ce8fa2cd93c6489236e33e45e35203ca748c
@@ -0,0 +1 @@
+x+)JMU0¶`040031QHJ,ÊI­Ô+©(ahÞùóÞÿš‚z
>þÔœ†rS57jÜÀ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/6d/fb87d20f3dbca02da4a39890114fd9ba6a51e7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/6d/fb87d20f3dbca02da4a39890114fd9ba6a51e7
new file mode 100755
index 0000000..039c669
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/6d/fb87d20f3dbca02da4a39890114fd9ba6a51e7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/73/f346c88d965227a03c0af8d555870b8c5021d4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/73/f346c88d965227a03c0af8d555870b8c5021d4
new file mode 100755
index 0000000..215df59
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/73/f346c88d965227a03c0af8d555870b8c5021d4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/74/0a804e8963759c98e5b8cb912e15ae74a7a4a6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/74/0a804e8963759c98e5b8cb912e15ae74a7a4a6
new file mode 100755
index 0000000..b817182
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/74/0a804e8963759c98e5b8cb912e15ae74a7a4a6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/78/c320b06544e23d786a9ec84ee93861f2933094 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/78/c320b06544e23d786a9ec84ee93861f2933094
new file mode 100755
index 0000000..afa39fb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/78/c320b06544e23d786a9ec84ee93861f2933094 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/79/e28694aae0d3064b06f96a5207b943a2357f07 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/79/e28694aae0d3064b06f96a5207b943a2357f07
new file mode 100755
index 0000000..17ff306
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/79/e28694aae0d3064b06f96a5207b943a2357f07 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/7a/05900f340af0252aaa4e34941f040c5d2fe7f7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/7a/05900f340af0252aaa4e34941f040c5d2fe7f7
new file mode 100755
index 0000000..43201f8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/7a/05900f340af0252aaa4e34941f040c5d2fe7f7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/7a/677f6201c8f9d46bdfe1f4b08cb504e360a34e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/7a/677f6201c8f9d46bdfe1f4b08cb504e360a34e
new file mode 100755
index 0000000..dc2fd5a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/7a/677f6201c8f9d46bdfe1f4b08cb504e360a34e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/7c/7bf85e978f1d18c0566f702d2cb7766b9c8d4f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/7c/7bf85e978f1d18c0566f702d2cb7766b9c8d4f
new file mode 100755
index 0000000..fe8b157
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/7c/7bf85e978f1d18c0566f702d2cb7766b9c8d4f
@@ -0,0 +1 @@
+x¥±NÄ0D©ý««ádç'‘‚	úýÆÞ\VŠ½‘í\~Ÿ€øº™÷¤/1r…¦w5m|À0èÒt¡ntƺ®%×öû‘¬ékcnu–ïaÇà:K,’à™ú“^éWüµ³—øÆêÖ5¦í5<i«µ:èq^éŸ3ê3qe\ ӝKRê
&ڡȶÐóJ¦,N×™à‹ó#|ÈVhç‰N€wäÇ…€Ô™Ôº{‘ÓY}RYa)
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/7f/37fe2d7320360f8a9118b1ed8fba6f38481679 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/7f/37fe2d7320360f8a9118b1ed8fba6f38481679
new file mode 100755
index 0000000..400df28
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/7f/37fe2d7320360f8a9118b1ed8fba6f38481679
@@ -0,0 +1 @@
+x¥Ž½n1„©ýû óâ;{%„hR¦KùöG¸8ŒŒQ^?å
¢if¾‘FÃuÛJ\p×›*$¢ÇäW2#V1‰FCˆAcFqÅ™Ü=7½uð«O‘ȘY>òšÐÏÉ[4Ôd‚ÌA\~ökmð!?¹	|]ëö¨78é /wÑwñ—\·3ø0Íââì§0MnÐq¶ë?gÜg•b…s/ãB€j ­¨|ß5»_X$W‡
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/80/32d630f37266bace093e353f7b97d7f8b20950 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/80/32d630f37266bace093e353f7b97d7f8b20950
new file mode 100755
index 0000000..07050df
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/80/32d630f37266bace093e353f7b97d7f8b20950 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/80/dce0e74f0534811db734a68c23b49f98584d7a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/80/dce0e74f0534811db734a68c23b49f98584d7a
new file mode 100755
index 0000000..1b98b0a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/80/dce0e74f0534811db734a68c23b49f98584d7a
@@ -0,0 +1,2 @@
+xERÍNÃ0朧ðTÜHœ*	¶Šm¦îj5KBâ0ííq²§¦©ýý¶·¾‡»‡û›v×µŸíëa»í¡»Uj¯g„ÑçVÇ#BŸ™0A§ £>æÔ@2QbpdÐ^x:ìaûòÛÍ
+Þ6Ok%<!°2¯Ý x—rsrpÖŒ±3ùP§k;§:Ö	Ð~½ú¤òT#E„3ñ¡Á"¥×Æ;]DzGށÉ9\ɺU×­>¡Ý<î}ß?*=Àg_YG®v
½'{ÕÅdë	~ÕñW&FH~䦨٨m•|’èó±ÈJ„ßxåMµø+Î+¾ø—”8Od&8åÄÐ#„ÌJ,Ì%Š2<?–Ky¯ó‚idaÆS5ß@%õ×Æ‚=éA eÃj’“TRIEÙ‰³Â“P>ŠI€Œ•RuD•ò8’!tl/0x'Fxᮜ£•ŸAÀ2Keµ¡Ùyq‹ñ»þ9ܪðÊÃ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/83/53b9f9deff7c707f280e0f656c80772cca7cd9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/83/53b9f9deff7c707f280e0f656c80772cca7cd9
new file mode 100755
index 0000000..a4a7e3a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/83/53b9f9deff7c707f280e0f656c80772cca7cd9
@@ -0,0 +1,2 @@
+xMAjÃ0E»Ö)þL6]…¬ÒÚBh‚í@»”íq,*kTi\7·ïØèJðçóæiÏ
·Û‡§}y<|¢:]ÎcΗ§wÔ¯åဗ·ã±÷hlòt+ C"Â÷d“ä%Ÿ­P*ÐÓŽCF;	¦X˜êíÏû²<Õr›l¤6tëÜat®¥B#âüÂâä¶PeJÁÅ•eòh½ß¡açáW
+âo™1ð”ò¢DQ·º€^#pBï~‘§Ð­–Z1ɶ_Ë(Ðòö'*°Êg¯6kד*
v,0;)FJ«y¶^væ.’=ÏÿEà9\ïMJº_m§¸AÍ£ΰ‰cè·%ïõ°]çDo=†.#³öÍóŒŠ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/85/258e426a341cc1aa035ac7f6d18f84fed2ab38 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/85/258e426a341cc1aa035ac7f6d18f84fed2ab38
new file mode 100755
index 0000000..af1106d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/85/258e426a341cc1aa035ac7f6d18f84fed2ab38 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/85/f34ce9ca9e0f33d4146afec9cbe5a26757500a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/85/f34ce9ca9e0f33d4146afec9cbe5a26757500a
new file mode 100755
index 0000000..03e7516
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/85/f34ce9ca9e0f33d4146afec9cbe5a26757500a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/86/a5415741ed3754ccb0cac1fc19fd82587840a4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/86/a5415741ed3754ccb0cac1fc19fd82587840a4
new file mode 100755
index 0000000..fe00a22
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/86/a5415741ed3754ccb0cac1fc19fd82587840a4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/8d/1f13f93c4995760ac07d129246ac1ff64c0be9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/8d/1f13f93c4995760ac07d129246ac1ff64c0be9
new file mode 100755
index 0000000..a66cfcc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/8d/1f13f93c4995760ac07d129246ac1ff64c0be9
@@ -0,0 +1,2 @@
+x¥ŽAnÃ0{Ö+øMÙ¹ôØ[>@“⃣ÀQïÇ-úƒÜvgÅh[×¥¥é£oî0P"Á±¨³²NX*ÆH4Y1åÌ©R.á&›_;˜MQh0$+CÎcå$³š`ÒšŒæÂAýÒ6ø¶§lçK[ïí
+ßéo:ùßðß¾´­GˆŒi¤˜™á1ìt—íþæMøi¶ÔE¥/»Ao0»×ðâ›S€
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/8d/95ea62e621f1d38d230d9e7d206e41096d76af b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/8d/95ea62e621f1d38d230d9e7d206e41096d76af
new file mode 100755
index 0000000..464de7c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/8d/95ea62e621f1d38d230d9e7d206e41096d76af differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/8f/4de6c781b9ff9cedfd7f9f9f224e744f97b259 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/8f/4de6c781b9ff9cedfd7f9f9f224e744f97b259
new file mode 100755
index 0000000..faa9389
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/8f/4de6c781b9ff9cedfd7f9f9f224e744f97b259
@@ -0,0 +1 @@
+x+)JMU0·d040031QHJ,ÊI­Ô+©(a¨|Ô6eÕƒËlÞl?³‚Øw:/2­g‡ªJ)ÊLM‰/HM+tôýSøêúö5W^¹ÿ;?ñSçú#;a9$j
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/92/54a37fde7e97f9a28dee2967fdb2c5d1ed94e9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/92/54a37fde7e97f9a28dee2967fdb2c5d1ed94e9
new file mode 100755
index 0000000..10d6c13
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/92/54a37fde7e97f9a28dee2967fdb2c5d1ed94e9
@@ -0,0 +1 @@
+xERËnã0ìY_Á0z+Z '5uè¢Îúœe…Ž…(–V¢äï—RŠöd‰Îp8­áéåùAv{ÙÊÍÐA×ûG!zùQúZø#ÛM
oÃçj[wà&PÑ« N)VuPÁ,F£½U 1f·pyѳhÖÐokè›}WZŽ`Õ
hÆ?ÃUnšÏ5ˆ¤ì9˜g¢sKþŠõ®­á°ë· a¿«W50ó›\5ŸLˤá„,jGHþ.æÑ{…0*K¯B¾¿Chàï Û¾ËÙ×m£3ö.HÆ–ÓÏ4á_2Ä㹉ªZ„O¶Œ|ákpé4óÑàÞu#Åþ²§âÈñ–*¸ÎFÏpI‘`D`bTúœW‘¡ÞÑk.ò½à™SsÃM]
ÍKÎGÞ´øIã›{VG¦æ«Ÿ8’âŒ#J;˽ù‘'PŒ¶Èû(bš&£
.dopäø²Ñ»vÑœ¬KÕ˜ˆ#+½{þv‹á«üÉ?ŠÿÐwǃ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/95/39b2cc291d6a6b1b266df8474d31fdd344dd79 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/95/39b2cc291d6a6b1b266df8474d31fdd344dd79
new file mode 100755
index 0000000..9649434
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/95/39b2cc291d6a6b1b266df8474d31fdd344dd79 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/9a/8535dfcaf7554c728d874f047c5461fb2c71d1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/9a/8535dfcaf7554c728d874f047c5461fb2c71d1
new file mode 100755
index 0000000..d997426
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/9a/8535dfcaf7554c728d874f047c5461fb2c71d1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/9c/d483e7da23819d7f71d24e9843812337886753 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/9c/d483e7da23819d7f71d24e9843812337886753
new file mode 100755
index 0000000..d168455
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/9c/d483e7da23819d7f71d24e9843812337886753
@@ -0,0 +1 @@
+xMAjÃ0E»Ö)þL6]…¬ÒÚ€Ûہv)ÛãXTѨҨ®o_ÙèJðçóæiZË-·Û‡§}U>QŸ.çRçKƒÓ;š×êpÀ˱,kð€VKs¾“—|ÒB¡À@Øv]$_¨úøç}Uš±ÚSíúunœ0zÓQ‘#PÆÙ…éÄȼP%güÊRõÛ¾,whÙXÁ•œØ21FN!.JäàóVã0ä0˜‚çäúÕ2WTÐÝ×2r´¼nI„]Xå£Í6k×RVõ­Àdd„'ï)¬æQ[Ù©»H´<ýew½7)äýÙ6ù
¾iá(cývdmþtßÉ7C>†Œ&"rî«?v„‹ê
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/a0/1a6ee390f65d834375e072952deaee0c5e92f7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/a0/1a6ee390f65d834375e072952deaee0c5e92f7
new file mode 100755
index 0000000..eb98c9d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/a0/1a6ee390f65d834375e072952deaee0c5e92f7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/a0/fa65f96c1e3bdc7287e334229279dcc1248fa4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/a0/fa65f96c1e3bdc7287e334229279dcc1248fa4
new file mode 100755
index 0000000..fd43545
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/a0/fa65f96c1e3bdc7287e334229279dcc1248fa4
@@ -0,0 +1,3 @@
+xERÍnà Þ™§ðD½M›ÔS6µ«´i©šöqL£¾ý­ºSÀ|þ~ìtÆuðúþöR·ûúPZh›Ó~%ıþÞÀ¶9à§>|màãôû¹Û´àÑË Ï)VUAX­ÐÜ*P‰3€³\¶jÍŽ»
›}[´=yqægX$aà¦Ñù\ƒHÒL±À<˜³ù+M#Hðf+TÎ2-“†3W¬ft¶ü]Ì£÷
+a”†ÖBö=Ðâà’d ˜9:§Í]´)§§¾$MlÏ
Te>™byækpéœmEW¼ëF
+’óåL…Èñ”*XF­F˜S$è8£àSE†zGë\ä{Á3§â†	ÿC•	d,9Ÿí‹ç6ܣ왚;ŒÔ|â•”d¼¢d9Y։ȏì€' •Ažw@Ó0h¥Ñ’¹AÏëËAïÚEs0.ñªºD¼²2ÐY›é‘õüɯÄ9Ï̃
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/a1/25b9b655932711abceaf8962948e6b601d67b6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/a1/25b9b655932711abceaf8962948e6b601d67b6
new file mode 100755
index 0000000..50bcee1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/a1/25b9b655932711abceaf8962948e6b601d67b6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/a7/00acc970eccccc73be53cd269462176544e6d1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/a7/00acc970eccccc73be53cd269462176544e6d1
new file mode 100755
index 0000000..e5c62db
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/a7/00acc970eccccc73be53cd269462176544e6d1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/a7/b066537e6be7109abfe4ff97b675d4e077da20 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/a7/b066537e6be7109abfe4ff97b675d4e077da20
new file mode 100755
index 0000000..54f9b66
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/a7/b066537e6be7109abfe4ff97b675d4e077da20 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/aa/4c42aecdfc7cd989bbc3209934ea7cda3f4d88 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/aa/4c42aecdfc7cd989bbc3209934ea7cda3f4d88
new file mode 100755
index 0000000..628c2d3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/aa/4c42aecdfc7cd989bbc3209934ea7cda3f4d88
@@ -0,0 +1 @@
+x¥Á	B1D=§Šm@Ùý=؁
l²~À¸#b÷F±o3o`^ÒZK‹~Õ›ˆdfñL“Ï6ìØ1GÏ9¦)̘1 5ôè‹68ó“ÃeÑz×ìeÐO:ÊwøµMÒz€É¡ßZë¦ÖèÍ CÞåÏsb.½½fˆÔ®ò2o!Fw
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ab/25a53ef5622d443ecb0492b7516725f0deac8f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ab/25a53ef5622d443ecb0492b7516725f0deac8f
new file mode 100755
index 0000000..83ef51e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ab/25a53ef5622d443ecb0492b7516725f0deac8f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ad/c97cfb874cdfb9d5ab17b54f3771dea6e02ccf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ad/c97cfb874cdfb9d5ab17b54f3771dea6e02ccf
new file mode 100755
index 0000000..cc7ccd0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ad/c97cfb874cdfb9d5ab17b54f3771dea6e02ccf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ae/87cae12879a3c37d7cc994afc6395bcb0eaf99 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ae/87cae12879a3c37d7cc994afc6395bcb0eaf99
new file mode 100755
index 0000000..5c8469e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ae/87cae12879a3c37d7cc994afc6395bcb0eaf99 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/b1/46bd7608eac53d9bf9e1a6963543588b555c64 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/b1/46bd7608eac53d9bf9e1a6963543588b555c64
new file mode 100755
index 0000000..3e4b975
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/b1/46bd7608eac53d9bf9e1a6963543588b555c64
@@ -0,0 +1 @@
+x¥ŽÁj1D{öWè,¯e«B.=æÖÐÚ»‡ÃÆ!¿_7ôs˜yÔ¶mk‡@ù£ïª€Æ‚3NC±y¶ˆ–dšs.%	!w“]¯ˆY©ó±Æ¯ì³i™9‘bU)bY-eÎN}i;|קì~–¶ÝÛŽ:èŸ;ë«øO‡Ò¶`ô”2#|úè½tœíú挻´ºÚZ¤¯ãAo0«šûcJT/
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/b1/b94ec02f8ed87d0efa4c65fb38d5d6da7e8b32 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/b1/b94ec02f8ed87d0efa4c65fb38d5d6da7e8b32
new file mode 100755
index 0000000..d15c022
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/b1/b94ec02f8ed87d0efa4c65fb38d5d6da7e8b32 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/b6/72b141d48c369fee6c4deeb32a904387594365 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/b6/72b141d48c369fee6c4deeb32a904387594365
new file mode 100755
index 0000000..d8cdb71
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/b6/72b141d48c369fee6c4deeb32a904387594365 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/b7/c536a5883c8adaeb34d5e198c5a3dbbdc608b5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/b7/c536a5883c8adaeb34d5e198c5a3dbbdc608b5
new file mode 100755
index 0000000..b594984
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/b7/c536a5883c8adaeb34d5e198c5a3dbbdc608b5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/b9/f72b9158fa8c49fb4e4c10b26817ed867be803 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/b9/f72b9158fa8c49fb4e4c10b26817ed867be803
new file mode 100755
index 0000000..9701667
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/b9/f72b9158fa8c49fb4e4c10b26817ed867be803
@@ -0,0 +1,3 @@
+x¥O;N1¥žS¸Û
+d;Nf"!´
%=ÊÇaFb&«âö' {_[/Õ}ß:ò7½©‚)yÉÖ¤‚œÕ}`¬Bƒb©Ì.å2]BÓ£Ct3Gʲ$ã|QuI²j4<ŠYæÑ5Îþå‰."ÄÑ[6ÞyÇ…q&—2ÇE攦píkmð˜?BËð¼Öý½p¯CýFgý1~Ù]ªû uÌã!Ü¢ NCãºþóÌô¤íU!¶p¤N1´7ý<Ávô
+¹mš_.¦/ÚÚdÛ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/bc/cc8eabb5cfe2ec09959c7f4155aa73429fd604 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/bc/cc8eabb5cfe2ec09959c7f4155aa73429fd604
new file mode 100755
index 0000000..de778eb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/bc/cc8eabb5cfe2ec09959c7f4155aa73429fd604 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/c4/e6cca3ec6ae0148ed231f97257df8c311e015f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/c4/e6cca3ec6ae0148ed231f97257df8c311e015f
new file mode 100755
index 0000000..2bbf28f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/c4/e6cca3ec6ae0148ed231f97257df8c311e015f
@@ -0,0 +1 @@
+x%P1nÄ0ëìWð¹CNE§N7¶è¡:*‰’p¬Ô’/¸ßWÎmI‘”ú$=^^ŸŸ._ï?¿¸~|žC¸°ã¼6©yTÈ„A¨(#1eôÌÓé´“.ˆ†áÀ(Hto@̸K-aë°Õ°…¡´²“sá1r6)&)8¸Å·TêÖa¶<0ׇ¿JÙ¢Ý[‡ŒK‡5IJ²²­ÈÀªcáÁ¸q͓쌫r_ÍÛ‡"u^@ÐÈ7~X)—›÷2¸ Ýâ	G…,æ¥f¬R¸ùå`BÚúÂ4¶3£½ÁvQŸø¤›HÖ©¦Öu­êa²b SwÞcJ q…)fÆ”èæO‚ùvû×;‡í«ŒŸ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/c5/17380440ed78865ffe3fa130b9738615c76618 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/c5/17380440ed78865ffe3fa130b9738615c76618
new file mode 100755
index 0000000..b9a52a3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/c5/17380440ed78865ffe3fa130b9738615c76618 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/cb/20a10406172afd6ca3138ce36ecaf8b1269e8e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/cb/20a10406172afd6ca3138ce36ecaf8b1269e8e
new file mode 100755
index 0000000..acd6bdc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/cb/20a10406172afd6ca3138ce36ecaf8b1269e8e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/d4/82e77aecb8e07da43e4cad6e0dcb59219e12af b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/d4/82e77aecb8e07da43e4cad6e0dcb59219e12af
new file mode 100755
index 0000000..af3bd17
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/d4/82e77aecb8e07da43e4cad6e0dcb59219e12af differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/d6/16d97082eb7bb2dc6f180a7cca940993b7a56f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/d6/16d97082eb7bb2dc6f180a7cca940993b7a56f
new file mode 100755
index 0000000..fa2e8d9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/d6/16d97082eb7bb2dc6f180a7cca940993b7a56f
@@ -0,0 +1 @@
+x¥NK uÍ)æš)0-MŒqãҝ`Ð.Z¢ÆۋƸ{ÿ¼çyª É­jßùÑJ@œD7D”Ä6ô”¼q‘byçVW.²´"³	â¬ÆVC'žCGÚ›–$)%3¦1ô¢ø^/¹À!>¹D8]ò|Ël¥©´—¯ñc›çt©×„D°F‹¨šÚÎVùsFsœÒ¸N킁šá\øñRoV<
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/d6/b9ec0dfb972a6815ace42545cde5f2631cd776 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/d6/b9ec0dfb972a6815ace42545cde5f2631cd776
new file mode 100755
index 0000000..1239704
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/d6/b9ec0dfb972a6815ace42545cde5f2631cd776 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/da/82b3a60c50cf5ac524ec3000d743447329465d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/da/82b3a60c50cf5ac524ec3000d743447329465d
new file mode 100755
index 0000000..352a13a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/da/82b3a60c50cf5ac524ec3000d743447329465d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/da/9c51a23d02d931a486f45ad18cda05cf5d2b94 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/da/9c51a23d02d931a486f45ad18cda05cf5d2b94
new file mode 100755
index 0000000..85b78ee
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/da/9c51a23d02d931a486f45ad18cda05cf5d2b94
@@ -0,0 +1,2 @@
+x¥Ž;!†­9Å\@3ÀÂ@bŒ¥à1·X1+Æë‹ÆØýäËWڲ̌£M_™! 5Õ[KÆûœ
+c´lÊ‘*IÈ£CuO+ß:P¡,Áq¤ ºêPÐy/„¦š’‰"–P'QéÙ¯m…S}¥µÂåÚ–G»ÁžÇúIGþ¿¶+m9€žÌhò¶8!ª±ÙÎbÔ¹ÕYæ’ú<4ô™YÔõ¯S•
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/dc/12ac1e10f2be70e8ecd52132a08da98a309c3a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/dc/12ac1e10f2be70e8ecd52132a08da98a309c3a
new file mode 100755
index 0000000..9907248
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/dc/12ac1e10f2be70e8ecd52132a08da98a309c3a
@@ -0,0 +1 @@
+x¥ŽMJ1…]çÅì•ÊϤ¦Ad@\ºóUIÅCw†LD¼½Q¼»÷ޏ/µm«…»ÑUAI1eq‹U<ùhKfO‘¼gë$Ø#2/æÊ]÷š‰/%«.¤ˆÙå(–-.Ÿâä
ŒµuxÉŸÜ3¼­m»µu®?鬿à¯=¤¶=
x$ŒDÜc at 4s²CÿycžWíý®5]êþ‡×–k©‰GJFQ-ó
ºZy
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/df/d3d25264693fcd7348ad286f3c34f3f6b30918 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/df/d3d25264693fcd7348ad286f3c34f3f6b30918
new file mode 100755
index 0000000..3de3fda
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/df/d3d25264693fcd7348ad286f3c34f3f6b30918 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e4/f809f826c1a9fc929874bc0e4644dd2f2a1af4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e4/f809f826c1a9fc929874bc0e4644dd2f2a1af4
new file mode 100755
index 0000000..e475019
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e4/f809f826c1a9fc929874bc0e4644dd2f2a1af4
@@ -0,0 +1,3 @@
+x¥ŽMŠ1„]çïùym'0ˆ—î¼@%yÁÛ1"ÞÞ8Ì
fWõ_ªëºt²SØô&Beç
+Ü,ÖO15æȾ`òÖÁxÃpÈP?hrëpbI¹¤9åàCŒÉY‚cÁ p…³÷
+~©Žù‰–é|©ë½Þè[ý¤ƒüí+ÕuO†õ´³–YÓV³ÖjÐ!ÛåŸ7êTóR–„¾C½RD»ÊK½ÿXV
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e5/2ff405da5b7e1e9b0929939fa8405d81fe8a45 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e5/2ff405da5b7e1e9b0929939fa8405d81fe8a45
new file mode 100755
index 0000000..30c1987
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e5/2ff405da5b7e1e9b0929939fa8405d81fe8a45
@@ -0,0 +1,3 @@
+x¥Ž;j1†]ës˜‘V“&eºôaV3ƒUìÊ(
+¹~d“¤ûðñ•¶ïu€‹î4ºZŠ"KF×Å/)&—ƒc!,A²ÓdîÔ倨vË„Ù¯”8°õƒlqAѺm«ª'CßãÖ:¼ñu†[Û¿Ú™ë#½ÊóøkçÒö+؉ŠÎ…äá=¢™ë”òOŒyo\µu*Xh
+Ü«ðç]ÈüxV¢
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e7/bb00c4eab291e08361fda376733a12b4150aa9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e7/bb00c4eab291e08361fda376733a12b4150aa9
new file mode 100755
index 0000000..da96e9d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e7/bb00c4eab291e08361fda376733a12b4150aa9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e8/8cc0a6919a74599ce8e1dcb81eb2bbae33a645 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e8/8cc0a6919a74599ce8e1dcb81eb2bbae33a645
new file mode 100755
index 0000000..e8ce172
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e8/8cc0a6919a74599ce8e1dcb81eb2bbae33a645 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e9/5f47e016dcc70b0b888df8e40e97b8aabafd4c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e9/5f47e016dcc70b0b888df8e40e97b8aabafd4c
new file mode 100755
index 0000000..cc3312a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e9/5f47e016dcc70b0b888df8e40e97b8aabafd4c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e9/f22c10ffb378446c0bbcab7ee3d9d5a0040672 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e9/f22c10ffb378446c0bbcab7ee3d9d5a0040672
new file mode 100755
index 0000000..3446b2f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/e9/f22c10ffb378446c0bbcab7ee3d9d5a0040672
@@ -0,0 +1,2 @@
+xMÍjÃ0„{ÖS̘\z
+9µ`Ú‚iB~=Êö:•µª´ª“·ïÚèiav˜ývZÏ-ž·Û§×—cSá´¿6Æ.gì?q~?Ö5Þ>šæÐÚäé^AÆD„Ÿb“äEŸ­Pª0ÐŽCFW%V&»:›«1wÉFêaC¿î]Fï:ªTiœ_2ƒ8¹/©RRpqÍ2y²Þïвóp‚+ñwÈ̹¤¼ Q@Ô«.`P	œ0¸_Bäú•R-&Ùî{YZ怩ˆpP€>{¥Y½ži´S…ÙɈH1RZɳõ²3ìyþÏáúpRÒûJ[âgž¬p†M¤1†ny¯_Àö½íZ†ŒNkbõ›?ŒÂÊ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ec/725f5639730640f91cd0be5f2d6d7ac5d69c79 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ec/725f5639730640f91cd0be5f2d6d7ac5d69c79
new file mode 100755
index 0000000..0fb3334
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ec/725f5639730640f91cd0be5f2d6d7ac5d69c79 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ed/f7b3ffde1624c60d2d6b1a2bb792d86de172e0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ed/f7b3ffde1624c60d2d6b1a2bb792d86de172e0
new file mode 100755
index 0000000..e2e98d6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ed/f7b3ffde1624c60d2d6b1a2bb792d86de172e0
@@ -0,0 +1,3 @@
+x¥OKN!uÍ)êh¡
+ctá
f?ú8½èfÒb¼¾8™¸{Ÿä}¸oÛ:`Iø0U¨Â…ØZ¦Èb­Hª-PKÑž‰‚hEõ³¹k=t@LÍrÒBÙ‚„Ì>!ùEnDˆ­p–h®~K?àC~ê!pºôí«ïð¢SýCoz3îì‰ûö
+!úD± <úè½›ê;ôŸ1î]dë¬ïŸóõ~¾ju¿Z’U„
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ee/23c5eeedadf8595c0ff60a366d970a165e373d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ee/23c5eeedadf8595c0ff60a366d970a165e373d
new file mode 100755
index 0000000..b32600f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ee/23c5eeedadf8595c0ff60a366d970a165e373d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ee/f0edde5daa94da5f297d4ddb5dfbc1980f0902 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ee/f0edde5daa94da5f297d4ddb5dfbc1980f0902
new file mode 100755
index 0000000..e9b3f58
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ee/f0edde5daa94da5f297d4ddb5dfbc1980f0902 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ef/ad0b11c47cb2f0220cbd6f5b0f93bb99064b00 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ef/ad0b11c47cb2f0220cbd6f5b0f93bb99064b00
new file mode 100755
index 0000000..285e140
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ef/ad0b11c47cb2f0220cbd6f5b0f93bb99064b00
@@ -0,0 +1 @@
+x¥=nÃ0…3ë¼@Š¢dŠ.»å¬D&l¶‚^¿jÐt{?ÀÃ÷J[×¥%:õ]r¤˜•)I`_ŠÁ¥L–ªÏ–Ù´’|…ìî²ëÖaŒ3¢F1¤H"ÂxfoÈXb%ÓÉ&'~k;|ÔoÙ+\nm=Úgé¯z×gñç^K[ßÀ3ÆD>Í	^ƺ‘Ø®ÿœqŸ­.¶éË@ˆÐÈ1þÈõq¸æ©V
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/f5/56d5fef35003561dc0b64b37057d7541239105 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/f5/56d5fef35003561dc0b64b37057d7541239105
new file mode 100755
index 0000000..f4143e1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/f5/56d5fef35003561dc0b64b37057d7541239105 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/f6/3fa37e285bd11b0a7b48fa584a4091814a3ada b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/f6/3fa37e285bd11b0a7b48fa584a4091814a3ada
new file mode 100755
index 0000000..e650383
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/f6/3fa37e285bd11b0a7b48fa584a4091814a3ada differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/f7/5c193a1df47186727179f24867bc4d27a8991f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/f7/5c193a1df47186727179f24867bc4d27a8991f
new file mode 100755
index 0000000..618cb68
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/f7/5c193a1df47186727179f24867bc4d27a8991f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/f8/7d14a4a236582a0278a916340a793714256864 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/f8/7d14a4a236582a0278a916340a793714256864
new file mode 100755
index 0000000..1d29712
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/f8/7d14a4a236582a0278a916340a793714256864
@@ -0,0 +1,2 @@
+x¥ŽKŠAD]×)òUÙõqãҝÈÎ6ØÖЖz}Ûan0»ˆ<nó<uÀT6}Q…Õ4$1&+)E.X¥–h>N1‘Kà~hÑ[¯†Š#ŽU²«b–4cP¯LƼij£G¿´Žò¢Eà|ió½Ýà[WúIýþÚ·y!ú”‡œaë£÷n¥«l×Þ¸S“É&¦>­
+ôO¥«{äƒTÈ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/fc/e0584b379f535e50e036db587db71884ea6b36 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/fc/e0584b379f535e50e036db587db71884ea6b36
new file mode 100755
index 0000000..ce8b2fb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/fc/e0584b379f535e50e036db587db71884ea6b36 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ff/b36e513f5fdf8a6ba850a20142676a2ac4807d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ff/b36e513f5fdf8a6ba850a20142676a2ac4807d
new file mode 100755
index 0000000..f655d12
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ff/b36e513f5fdf8a6ba850a20142676a2ac4807d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ff/dfa89389040a87008c4ab1834120d3046daaea b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ff/dfa89389040a87008c4ab1834120d3046daaea
new file mode 100755
index 0000000..54c938e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/objects/ff/dfa89389040a87008c4ab1834120d3046daaea differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/asparagus b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/asparagus
new file mode 100755
index 0000000..a3c9d67
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/asparagus
@@ -0,0 +1 @@
+4b21eb6eeeec7f8fc89a1d334faff9bd5f5f8c34
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/barley b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/barley
new file mode 100755
index 0000000..feab944
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/barley
@@ -0,0 +1 @@
+12c084412b952396962eb420716df01022b847cc
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/beef b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/beef
new file mode 100755
index 0000000..1c69e6a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/beef
@@ -0,0 +1 @@
+b146bd7608eac53d9bf9e1a6963543588b555c64
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/dried_pea b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/dried_pea
new file mode 100755
index 0000000..9ede602
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/dried_pea
@@ -0,0 +1 @@
+7f37fe2d7320360f8a9118b1ed8fba6f38481679
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/gravy b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/gravy
new file mode 100755
index 0000000..3753b73
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/gravy
@@ -0,0 +1 @@
+d616d97082eb7bb2dc6f180a7cca940993b7a56f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/green_pea b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/green_pea
new file mode 100755
index 0000000..3bffe27
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/green_pea
@@ -0,0 +1 @@
+d482e77aecb8e07da43e4cad6e0dcb59219e12af
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/master
new file mode 100755
index 0000000..abbe9cc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/master
@@ -0,0 +1 @@
+efad0b11c47cb2f0220cbd6f5b0f93bb99064b00
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/veal b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/veal
new file mode 100755
index 0000000..484f489
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/.gitted/refs/heads/veal
@@ -0,0 +1 @@
+f87d14a4a236582a0278a916340a793714256864
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/asparagus.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/asparagus.txt
new file mode 100755
index 0000000..67ed7af
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/asparagus.txt
@@ -0,0 +1,10 @@
+ASPARAGUS SOUP.
+
+TAKE FOUR LARGE BUNCHES of asparagus, scrape it nicely, cut off one inch
+OF THE TOPS, and lay them in water, chop the stalks and put them on the
+FIRE WITH A PIECE OF BACON, a large onion cut up, and pepper and salt;
+ADD TWO QUARTS OF WATER, boil them till the stalks are quite soft, then
+PULP THEM THROUGH A SIEVE, and strain the water to it, which must be put
+back in the pot; put into it a chicken cut up, with the tops of
+asparagus which had been laid by, boil it until these last articles are
+sufficiently done, thicken with flour, butter and milk, and serve it up.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/beef.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/beef.txt
new file mode 100755
index 0000000..68f6182
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/beef.txt
@@ -0,0 +1,22 @@
+BEEF SOUP.
+
+Take the hind shin of beef, cut off all the flesh off the leg-bone,
+which must be taken away entirely, or the soup will be greasy. Wash the
+meat clean and lay it in a pot, sprinkle over it one small
+table-spoonful of pounded black pepper, and two of salt; three onions
+the size of a hen's egg, cut small, six small carrots scraped and cut
+up, two small turnips pared and cut into dice; pour on three quarts of
+water, cover the pot close, and keep it gently and steadily boiling five
+hours, which will leave about three pints of clear soup; do not let the
+pot boil over, but take off the scum carefully, as it rises. When it has
+boiled four hours, put in a small bundle of thyme and parsley, and a
+pint of celery cut small, or a tea-spoonful of celery seed pounded.
+These latter ingredients would lose their delicate flavour if boiled too
+much. Just before you take it up, brown it in the following manner: put
+a small table-spoonful of nice brown sugar into an iron skillet, set it
+on the fire and stir it till it melts and looks very dark, pour into it
+a ladle full of the soup, a little at a time; stirring it all the while.
+Strain this browning and mix it well with the soup; take out the bundle
+of thyme and parsley, put the nicest pieces of meat in your tureen, and
+pour on the soup and vegetables; put in some toasted bread cut in dice,
+and serve it up.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/bouilli.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/bouilli.txt
new file mode 100755
index 0000000..4b7c565
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/bouilli.txt
@@ -0,0 +1,18 @@
+SOUP WITH BOUILLI.
+
+Take the nicest part of the thick brisket of beef, about eight pounds,
+put it into a pot with every thing directed for the other soup; make it
+exactly in the same way, only put it on an hour sooner, that you may
+have time to prepare the bouilli; after it has boiled five hours, take
+out the beef, cover up the soup and set it near the fire that it may
+keep hot. Take the skin off the beef, have the yelk of an egg well
+beaten, dip a feather in it and wash the top of your beef, sprinkle over
+it the crumb of stale bread finely grated, put it in a Dutch oven
+previously heated, put the top on with coals enough to brown, but not
+burn the beef; let it stand nearly an hour, and prepare your gravy
+thus:--Take a sufficient quantity of soup and the vegetables boiled in
+it; add to it a table-spoonful of red wine, and two of mushroom catsup,
+thicken with a little bit of butter and a little brown flour; make it
+very hot, pour it in your dish, and put the beef on it. Garnish it with
+green pickle, cut in thin slices, serve up the soup in a tureen with
+bits of toasted bread.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/gravy.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/gravy.txt
new file mode 100755
index 0000000..c4e6cca
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/gravy.txt
@@ -0,0 +1,8 @@
+GRAVY SOUP.
+
+Get eight pounds of coarse lean beef--wash it clean and lay it in your
+pot, put in the same ingredients as for the shin soup, with the same
+quantity of water, and follow the process directed for that. Strain the
+soup through a sieve, and serve it up clear, with nothing more than
+toasted bread in it; two table-spoonsful of mushroom catsup will add a
+fine flavour to the soup.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/oyster.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/oyster.txt
new file mode 100755
index 0000000..68af1fc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/oyster.txt
@@ -0,0 +1,13 @@
+OYSTER SOUP.
+
+Wash and drain two quarts of oysters, put them on with three quarts of
+water, three onions chopped up, two or three slices of lean ham, pepper
+and salt; boil it till reduced one-half, strain it through a sieve,
+return the liquid into the pot, put in one quart of fresh oysters, boil
+it till they are sufficiently done, and thicken the soup with four
+spoonsful of flour, two gills of rich cream, and the yelks of six new
+laid eggs beaten well; boil it a few minutes after the thickening is put
+in. Take care that it does not curdle, and that the flour is not in
+lumps; serve it up with the last oysters that were put in. If the
+flavour of thyme be agreeable, you may put in a little, but take care
+that it does not boil in it long enough to discolour the soup.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/veal.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/veal.txt
new file mode 100755
index 0000000..a7b0665
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/rebase/veal.txt
@@ -0,0 +1,18 @@
+VEAL SOUP.
+
+Put into a pot three quarts of water, three onions cut small, one
+spoonful of black pepper pounded, and two of salt, with two or three
+slices of lean ham; let it boil steadily two hours; skim it
+occasionally, then put into it a shin of veal, let it boil two hours
+longer; take out the slices of ham, and skim off the grease if any
+should rise, take a gill of good cream, mix with it two table-spoonsful
+of flour very nicely, and the yelks of two eggs beaten well, strain this
+mixture, and add some chopped parsley; pour some soup on by degrees,
+stir it well, and pour it into the pot, continuing to stir until it has
+boiled two or three minutes to take off the raw taste of the eggs. If
+the cream be not perfectly sweet, and the eggs quite new, the thickening
+will curdle in the soup. For a change you may put a dozen ripe tomatos
+in, first taking off their skins, by letting them stand a few minutes in
+hot water, when they may be easily peeled. When made in this way you
+must thicken it with the flour only. Any part of the veal may be used,
+but the shin or knuckle is the nicest.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/config
new file mode 100755
index 0000000..bb4d11c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/config
@@ -0,0 +1,7 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
+	precomposeunicode = false
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/index
new file mode 100755
index 0000000..72363c0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/logs/HEAD
new file mode 100755
index 0000000..e697922
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/logs/HEAD
@@ -0,0 +1,4 @@
+0000000000000000000000000000000000000000 31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 Russell Belfer <rb at github.com> 1351024687 -0700	commit (initial): Initial commit
+31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 2bc7f351d20b53f1c72c16c4b036e491c478c49a Russell Belfer <rb at github.com> 1351024817 -0700	commit: copy and rename with no change
+2bc7f351d20b53f1c72c16c4b036e491c478c49a 1c068dee5790ef1580cfc4cd670915b48d790084 Russell Belfer <rb at github.com> 1361485758 -0800	commit: rewrites, copies with changes, etc.
+1c068dee5790ef1580cfc4cd670915b48d790084 19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13 Russell Belfer <rb at github.com> 1361486360 -0800	commit: more renames and smallish modifications
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..e697922
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/logs/refs/heads/master
@@ -0,0 +1,4 @@
+0000000000000000000000000000000000000000 31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 Russell Belfer <rb at github.com> 1351024687 -0700	commit (initial): Initial commit
+31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 2bc7f351d20b53f1c72c16c4b036e491c478c49a Russell Belfer <rb at github.com> 1351024817 -0700	commit: copy and rename with no change
+2bc7f351d20b53f1c72c16c4b036e491c478c49a 1c068dee5790ef1580cfc4cd670915b48d790084 Russell Belfer <rb at github.com> 1361485758 -0800	commit: rewrites, copies with changes, etc.
+1c068dee5790ef1580cfc4cd670915b48d790084 19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13 Russell Belfer <rb at github.com> 1361486360 -0800	commit: more renames and smallish modifications
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/03/da7ad872536bd448da8d88eb7165338bf923a7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/03/da7ad872536bd448da8d88eb7165338bf923a7
new file mode 100755
index 0000000..2ee8644
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/03/da7ad872536bd448da8d88eb7165338bf923a7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/17/58bdd7c16a72ff7c17d8de0c957ced3ccad645 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/17/58bdd7c16a72ff7c17d8de0c957ced3ccad645
new file mode 100755
index 0000000..01801ed
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/17/58bdd7c16a72ff7c17d8de0c957ced3ccad645
@@ -0,0 +1,5 @@
+xEͱ
Â@QbWq
 ÿ®—ÃÅHôŸ¡_ž‰&{ëó]ãðy›û¸•¶Y¬X³û`Ÿì‹=¯Ý'흶=Zo´Þh½Ñz£õFëÖí¿­­Ð
+­Ð
+­Ð
+­Ð
+MhBšÐ„&4¡	MhB3šÑŒf4£ÍhF3šÑŽKûxŒŒ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/19/dd32dfb1520a64e5bbaae8dce6ef423dfa2f13 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/19/dd32dfb1520a64e5bbaae8dce6ef423dfa2f13
new file mode 100755
index 0000000..4be4c69
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/19/dd32dfb1520a64e5bbaae8dce6ef423dfa2f13
@@ -0,0 +1 @@
+x•ŽÑM!Eý¦Ši at 3¼ސc,Á\X°ýKþÞ{Nrbo­,xzYC¬<‡h[&“È?=fcvÎyƒèC£W¿<äZ #:J"vs’µ%Œ9š˜Ü½¶ÁPÚ’Q|¯³ø¾ç”ZáKj–ï#|þ”uÞá-ööúpڐ;Â+¢Úëî[ý¯©Z;’›Là+Ál\k™'´žJ.‘Wé×T¯;O
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/1c/068dee5790ef1580cfc4cd670915b48d790084 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/1c/068dee5790ef1580cfc4cd670915b48d790084
new file mode 100755
index 0000000..d65ab0a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/1c/068dee5790ef1580cfc4cd670915b48d790084 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/2b/c7f351d20b53f1c72c16c4b036e491c478c49a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/2b/c7f351d20b53f1c72c16c4b036e491c478c49a
new file mode 100755
index 0000000..93f1ccb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/2b/c7f351d20b53f1c72c16c4b036e491c478c49a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/31/e47d8c1fa36d7f8d537b96158e3f024de0a9f2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/31/e47d8c1fa36d7f8d537b96158e3f024de0a9f2
new file mode 100755
index 0000000..00ce532
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/31/e47d8c1fa36d7f8d537b96158e3f024de0a9f2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/35/92953ff3ea5e8ba700c429f3aefe33c8806754 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/35/92953ff3ea5e8ba700c429f3aefe33c8806754
new file mode 100755
index 0000000..886271d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/35/92953ff3ea5e8ba700c429f3aefe33c8806754 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/36/020db6cdacaa93497f31edcd8f242ff9bc366d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/36/020db6cdacaa93497f31edcd8f242ff9bc366d
new file mode 100755
index 0000000..f4f9303
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/36/020db6cdacaa93497f31edcd8f242ff9bc366d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/3c/04741dd4b96c4ae4b00ec0f6e10c816a30aad2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/3c/04741dd4b96c4ae4b00ec0f6e10c816a30aad2
new file mode 100755
index 0000000..c236022
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/3c/04741dd4b96c4ae4b00ec0f6e10c816a30aad2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/42/10ffd5c390b21dd5483375e75288dea9ede512 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/42/10ffd5c390b21dd5483375e75288dea9ede512
new file mode 100755
index 0000000..d351a6d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/42/10ffd5c390b21dd5483375e75288dea9ede512 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/44/4a76ed3e45b183753f49376af30da8c3fe276a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/44/4a76ed3e45b183753f49376af30da8c3fe276a
new file mode 100755
index 0000000..5ce12a3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/44/4a76ed3e45b183753f49376af30da8c3fe276a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/47/184c1e7eb22abcbed2bf4ee87d4e38096f7951 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/47/184c1e7eb22abcbed2bf4ee87d4e38096f7951
new file mode 100755
index 0000000..aa91926
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/47/184c1e7eb22abcbed2bf4ee87d4e38096f7951 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/4e/4cae3e7dd56ed74bff39526d0469e554432953 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/4e/4cae3e7dd56ed74bff39526d0469e554432953
new file mode 100755
index 0000000..5e6ebd5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/4e/4cae3e7dd56ed74bff39526d0469e554432953 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/50/e90273af7d826ff0a95865bcd3ba8412c447d9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/50/e90273af7d826ff0a95865bcd3ba8412c447d9
new file mode 100755
index 0000000..a98d14e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/50/e90273af7d826ff0a95865bcd3ba8412c447d9
@@ -0,0 +1,3 @@
+xmÍM
+Â0`×9Å\@ÉOÛd ˆîE¼@š&4hLI"âíî]Ícà}Ïå”bÉÕ®ïaBÙORvΡ5çÂ"¢
+“óbÀ0[kLo³ï¶ä·èpÍ­U˺ÝSŠ®äšC;¸œŽ ”æ8ÜhØóŽsF_šl¾ÀeþØ2Ã}ɩ挞È-ý!Dg4*IDO;Ûê!Ð~)>m‰íä®”¨Ï~*ùD‰
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/5e/26abc56a5a84d89790f45416648899cbe13109 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/5e/26abc56a5a84d89790f45416648899cbe13109
new file mode 100755
index 0000000..2acd3d5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/5e/26abc56a5a84d89790f45416648899cbe13109 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/61/8c6f2f8740bd6049b2fb9eb93fc15726462745 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/61/8c6f2f8740bd6049b2fb9eb93fc15726462745
new file mode 100755
index 0000000..24eac54
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/61/8c6f2f8740bd6049b2fb9eb93fc15726462745 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/66/311f5cfbe7836c27510a3ba2f43e282e2c8bba b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/66/311f5cfbe7836c27510a3ba2f43e282e2c8bba
new file mode 100755
index 0000000..5ee28a7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/66/311f5cfbe7836c27510a3ba2f43e282e2c8bba differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/93/f538c45a57a87eb4c1e86f91c6ee41d66c7ba7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/93/f538c45a57a87eb4c1e86f91c6ee41d66c7ba7
new file mode 100755
index 0000000..39105f9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/93/f538c45a57a87eb4c1e86f91c6ee41d66c7ba7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/9a/69d960ae94b060f56c2a8702545e2bb1abb935 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/9a/69d960ae94b060f56c2a8702545e2bb1abb935
new file mode 100755
index 0000000..f75178c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/9a/69d960ae94b060f56c2a8702545e2bb1abb935 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/ad/0a8e55a104ac54a8a29ed4b84b49e76837a113 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/ad/0a8e55a104ac54a8a29ed4b84b49e76837a113
new file mode 100755
index 0000000..440b7be
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/ad/0a8e55a104ac54a8a29ed4b84b49e76837a113 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/b9/25b224cc91f897001a9993fbce169fdaa8858f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/b9/25b224cc91f897001a9993fbce169fdaa8858f
new file mode 100755
index 0000000..90e107f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/b9/25b224cc91f897001a9993fbce169fdaa8858f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/d7/9b202de198fa61b02424b9e25e840dc75e1323 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/d7/9b202de198fa61b02424b9e25e840dc75e1323
new file mode 100755
index 0000000..daa2b39
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/d7/9b202de198fa61b02424b9e25e840dc75e1323 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/ea/c43f5195a2cee53b7458d8dad16aedde10711b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/ea/c43f5195a2cee53b7458d8dad16aedde10711b
new file mode 100755
index 0000000..2fb0250
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/ea/c43f5195a2cee53b7458d8dad16aedde10711b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/ea/f4a3e3bfe68585e90cada20736ace491cd100b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/ea/f4a3e3bfe68585e90cada20736ace491cd100b
new file mode 100755
index 0000000..f72df8d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/ea/f4a3e3bfe68585e90cada20736ace491cd100b
@@ -0,0 +1,5 @@
+x}RÁªÔ@ô<_QžTÈ.¼“ÂâAáÉ[–‡â
+{ž¼t2C’žez’˜›áú%öLžº'!aº»ª«jê!Ôx{÷îÅ'¢+Îþ;“$œ)Ξ»Ý#±yÿ¿Ç˜³#q#¯h„­c°
ÃQDX¶m­R|ŠaD*ÝOˆþ†+±”^ZI~ýøi>3aôÃàã!,R!-áïÉEaIÁ>äyš‰o*«¼4戁Rf¡	m&e¯ IAÑú™ò*!â;¢ždÍݬ‚…´Å
+êH¶o­¤
+ÃÄO®‚U¾DöyTVØHpwqÅH¼7§„Æ·­.ÈʆÎÎts6{Zä +öX\)Šª”ÑC–žì5QªÂä9
+%©ÌÅt*Ã&Ï&è°êv;|šÕÆ'4½ìÆéþþDƒu[°7h¯¿e!ÉNK*"C©-=Óòæ`´æ#ØŽ$EëÅe2õáâT|ùêå@NBsús¢¦lµ°Wö|/¶0¬÷aÈ¥üJ±ò¶Nêv)-šÚ¡˜iÛ¤3ÅëbäbO:uWMâˆNÓÜàóæ¶X²7¿Tóº
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/f9/0d4fc20ecddf21eebe6a37e9225d244339d2b5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/f9/0d4fc20ecddf21eebe6a37e9225d244339d2b5
new file mode 100755
index 0000000..f6d933b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/objects/f9/0d4fc20ecddf21eebe6a37e9225d244339d2b5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/refs/heads/master
new file mode 100755
index 0000000..642c319
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/refs/heads/master
@@ -0,0 +1 @@
+19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/refs/heads/renames_similar b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/refs/heads/renames_similar
new file mode 100755
index 0000000..8ffb6d9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/refs/heads/renames_similar
@@ -0,0 +1 @@
+444a76ed3e45b183753f49376af30da8c3fe276a
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/refs/heads/renames_similar_two b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/refs/heads/renames_similar_two
new file mode 100755
index 0000000..4ee5d04
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/.gitted/refs/heads/renames_similar_two
@@ -0,0 +1 @@
+50e90273af7d826ff0a95865bcd3ba8412c447d9
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/ikeepsix.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/ikeepsix.txt
new file mode 100755
index 0000000..eaf4a3e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/ikeepsix.txt
@@ -0,0 +1,27 @@
+I Keep Six Honest Serving-Men
+=============================
+
+She sends'em abroad on her own affairs,
+ From the second she opens her eyes—
+One million Hows, two million Wheres,
+And seven million Whys!
+
+I let them rest from nine till five,
+ For I am busy then,
+As well as breakfast, lunch, and tea,
+ For they are hungry men.
+But different folk have different views;
+I know a person small—
+She keeps ten million serving-men,
+Who get no rest at all!
+
+  -- Rudyard Kipling
+
+I KEEP six honest serving-men
+ (They taught me all I knew);
+Their names are What and Why and When
+ And How and Where and Who.
+I send them over land and sea,
+ I send them east and west;
+But after they have worked for me,
+ I give them all a rest.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/sixserving.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/sixserving.txt
new file mode 100755
index 0000000..f90d4fc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/sixserving.txt
@@ -0,0 +1,25 @@
+I  KEEP  six  honest  serving-men
+  (They  taught  me  all  I  knew);
+Their  names  are  What  and  Why  and  When
+  And  How  and  Where  and  Who.
+I  send  them  over  land  and  sea,
+  I  send  them  east  and  west;
+But  after  they  have  worked  for  me,
+  I  give  them  all  a  rest.
+
+I  let  them  rest  from  nine  till  five,
+  For  I  am  busy  then,
+As  well  as  breakfast,  lunch,  and  tea,
+  For  they  are  hungry  men.
+But  different  folk  have  different  views;
+I  know  a  person  small—
+She  keeps  ten  million  serving-men,
+Who  get  no  rest  at  all!
+
+She  sends'em  abroad  on  her  own  affairs,
+  From  the  second  she  opens  her  eyes—
+One  million  Hows,  two  million  Wheres,
+And  seven  million  Whys!
+
+    --  Rudyard  Kipling
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/songof7cities.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/songof7cities.txt
new file mode 100755
index 0000000..4210ffd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/songof7cities.txt
@@ -0,0 +1,49 @@
+The Song of Seven Cities
+------------------------
+
+I WAS Lord of Cities very sumptuously builded.
+Seven roaring Cities paid me tribute from afar.
+Ivory their outposts were--the guardrooms of them gilded,
+And garrisoned with Amazons invincible in war.
+
+All the world went softly when it walked before my Cities--
+Neither King nor Army vexed my peoples at their toil,
+Never horse nor chariot irked or overbore my Cities,
+Never Mob nor Ruler questioned whence they drew their spoil.
+
+Banded, mailed and arrogant from sunrise unto sunset;
+Singing while they sacked it, they possessed the land at large.
+Yet when men would rob them, they resisted, they made onset
+And pierced the smoke of battle with a thousand-sabred charge.
+
+So they warred and trafficked only yesterday, my Cities.
+To-day there is no mark or mound of where my Cities stood.
+For the River rose at midnight and it washed away my Cities.
+They are evened with Atlantis and the towns before the Flood.
+
+Rain on rain-gorged channels raised the water-levels round them,
+Freshet backed on freshet swelled and swept their world from sight,
+Till the emboldened floods linked arms and, flashing forward, drowned them--
+Drowned my Seven Cities and their peoples in one night!
+
+Low among the alders lie their derelict foundations,
+The beams wherein they trusted and the plinths whereon they built--
+My rulers and their treasure and their unborn populations,
+Dead, destroyed, aborted, and defiled with mud and silt!
+
+The Daughters of the Palace whom they cherished in my Cities,
+My silver-tongued Princesses, and the promise of their May--
+Their bridegrooms of the June-tide--all have perished in my Cities,
+With the harsh envenomed virgins that can neither love nor play.
+
+I was Lord of Cities--I will build anew my Cities,
+Seven, set on rocks, above the wrath of any flood.
+Nor will I rest from search till I have filled anew my Cities
+With peoples undefeated of the dark, enduring blood.
+
+To the sound of trumpets shall their seed restore my Cities
+Wealthy and well-weaponed, that once more may I behold
+All the world go softly when it walks before my Cities,
+And the horses and the chariots fleeing from them as of old!
+
+  -- Rudyard Kipling
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/untimely.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/untimely.txt
new file mode 100755
index 0000000..9a69d96
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/renames/untimely.txt
@@ -0,0 +1,24 @@
+Untimely
+========
+
+Nothing in life has been made by man for man's using
+But it was shown long since to man in ages
+Lost as the name of the maker of it,
+Who received oppression and shame for his wages--
+Hate, avoidance, and scorn in his daily dealings--
+Until he perished, wholly confounded
+
+More to be pitied than he are the wise
+Souls which foresaw the evil of loosing
+Knowledge or Art before time, and aborted
+Noble devices and deep-wrought healings,
+Lest offense should arise.
+
+Heaven delivers on earth the Hour that cannot be
+  thwarted,
+Neither advanced, at the price of a world nor a soul,
+  and its Prophet
+Comes through the blood of the vanguards who
+  dreamed--too soon--it had sounded.
+
+                -- Rudyard Kipling
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/HEAD
new file mode 100755
index 0000000..cb43805
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/config
new file mode 100755
index 0000000..454e576
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/config
@@ -0,0 +1,8 @@
+[core]
+	repositoryformatversion = 0
+	filemode = false
+	bare = false
+	logallrefupdates = true
+	symlinks = false
+	ignorecase = true
+	hideDotFiles = dotGitOnly
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/index
new file mode 100755
index 0000000..3513c04
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/info/exclude
new file mode 100755
index 0000000..f006809
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/00/c97c9299419874a7bfc4d853d462c568e1be2d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/00/c97c9299419874a7bfc4d853d462c568e1be2d
new file mode 100755
index 0000000..b4e9635
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/00/c97c9299419874a7bfc4d853d462c568e1be2d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/0a/a8c7e40d342fff78d60b29a4ba8e993ed79c51 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/0a/a8c7e40d342fff78d60b29a4ba8e993ed79c51
new file mode 100755
index 0000000..5c811ef
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/0a/a8c7e40d342fff78d60b29a4ba8e993ed79c51
@@ -0,0 +1,2 @@
+x¥K
+Â0@]çs%Ó4?qã
¼@2Ð€é@ñúÖ3¸{¼Å{$­ÕÜitf@ë¸ÄL9º°1…ÙOI—‰K™cÁäÑdrY¥÷X¥Ãcù¤¾Às•¶ËW>ìî­R—]ʸ´ 	GଭÖê°Çxð	U·:jz©/¤’?
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/0a/b09ea6d4c3634bdf6c221626d8b6f7dd890767 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/0a/b09ea6d4c3634bdf6c221626d8b6f7dd890767
new file mode 100755
index 0000000..c050e5a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/0a/b09ea6d4c3634bdf6c221626d8b6f7dd890767 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/0a/d19525be6d8cae5e5deb2770fc244b65255057 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/0a/d19525be6d8cae5e5deb2770fc244b65255057
new file mode 100755
index 0000000..4aa0459
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/0a/d19525be6d8cae5e5deb2770fc244b65255057 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/0c/db66192ee192f70f891f05a47636057420e871 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/0c/db66192ee192f70f891f05a47636057420e871
new file mode 100755
index 0000000..31c107f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/0c/db66192ee192f70f891f05a47636057420e871 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/0f/5bfcf58c558d865da6be0281d7795993646cee b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/0f/5bfcf58c558d865da6be0281d7795993646cee
new file mode 100755
index 0000000..fb4fc76
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/0f/5bfcf58c558d865da6be0281d7795993646cee differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/10/10c8f4711d60d04bad16197a0f4b0d4d19c542 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/10/10c8f4711d60d04bad16197a0f4b0d4d19c542
new file mode 100755
index 0000000..083f746
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/10/10c8f4711d60d04bad16197a0f4b0d4d19c542 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/13/a6fdfd10bd74b1f258fb58801215985dd2e797 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/13/a6fdfd10bd74b1f258fb58801215985dd2e797
new file mode 100755
index 0000000..3c54aab
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/13/a6fdfd10bd74b1f258fb58801215985dd2e797 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/13/ee9cd5d8e1023c218e0e1ea684ec0c582b5050 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/13/ee9cd5d8e1023c218e0e1ea684ec0c582b5050
new file mode 100755
index 0000000..aed4647
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/13/ee9cd5d8e1023c218e0e1ea684ec0c582b5050 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/15/6ef9bcb968dccec8472a0f2eff49f1a713bc6b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/15/6ef9bcb968dccec8472a0f2eff49f1a713bc6b
new file mode 100755
index 0000000..3ee2a18
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/15/6ef9bcb968dccec8472a0f2eff49f1a713bc6b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/18/1aab27ddb37b40d9a284fb4733497006d57091 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/18/1aab27ddb37b40d9a284fb4733497006d57091
new file mode 100755
index 0000000..6b422b8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/18/1aab27ddb37b40d9a284fb4733497006d57091 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/1b/c915c5cb7185a9438de28a7b1a7dfe8c01ee7f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/1b/c915c5cb7185a9438de28a7b1a7dfe8c01ee7f
new file mode 100755
index 0000000..0a6955b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/1b/c915c5cb7185a9438de28a7b1a7dfe8c01ee7f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/1f/a4e069a641f10f5fb7588138b2d147fcd22c36 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/1f/a4e069a641f10f5fb7588138b2d147fcd22c36
new file mode 100755
index 0000000..3df134a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/1f/a4e069a641f10f5fb7588138b2d147fcd22c36 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/1f/f0c423042b46cb1d617b81efb715defbe8054d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/1f/f0c423042b46cb1d617b81efb715defbe8054d
new file mode 100755
index 0000000..2ed1a22
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/1f/f0c423042b46cb1d617b81efb715defbe8054d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/21/a96a98ed84d45866e1de6e266fd3a61a4ae9dc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/21/a96a98ed84d45866e1de6e266fd3a61a4ae9dc
new file mode 100755
index 0000000..95842db
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/21/a96a98ed84d45866e1de6e266fd3a61a4ae9dc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/29/6a6d3be1dff05c5d1f631d2459389fa7b619eb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/29/6a6d3be1dff05c5d1f631d2459389fa7b619eb
new file mode 100755
index 0000000..5555268
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/29/6a6d3be1dff05c5d1f631d2459389fa7b619eb differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/2d/440f2b3147d3dc7ad1085813478d6d869d5a4d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/2d/440f2b3147d3dc7ad1085813478d6d869d5a4d
new file mode 100755
index 0000000..c06cc94
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/2d/440f2b3147d3dc7ad1085813478d6d869d5a4d
@@ -0,0 +1,2 @@
+x¥ŽK
+1D]ç}%Iç3"n¼Èt:΀I$ñúÆ3¸)ŠWð(ª9o´q‡Þ˜aaQ9ËRyífž"É]’JÍv Ym¯Ð¸tð“ñÑð„N9‡2%\F°!™/DHÆŠðîkmp‹ŸÐ"Üך÷Zà̃þÚ5oÔê^S?QÍP8Y…~ÖŽÒJ)G;ÿ¡Ž’žõ­<€ÖP¼‹/ælPÞ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/33/c6fd981c49a2abf2971482089350bfc5cda8ea b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/33/c6fd981c49a2abf2971482089350bfc5cda8ea
new file mode 100755
index 0000000..683f27f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/33/c6fd981c49a2abf2971482089350bfc5cda8ea differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/39/467716290f6df775a91cdb9a4eb39295018145 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/39/467716290f6df775a91cdb9a4eb39295018145
new file mode 100755
index 0000000..7c1e01d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/39/467716290f6df775a91cdb9a4eb39295018145 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/39/9fb3aba3d9d13f7d40a9254ce4402067ef3149 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/39/9fb3aba3d9d13f7d40a9254ce4402067ef3149
new file mode 100755
index 0000000..6cb6839
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/39/9fb3aba3d9d13f7d40a9254ce4402067ef3149
@@ -0,0 +1,2 @@
+x¥ŽK!]s
+. á;@bŒoàzºA\0mŒ×Ïàª<äÖžC§£ç,3Ød@û ¢_ÑDò	@§K6Å—5Tâ=oS$çT1«Õ.%@zªQ["-—D	xÊ]Þèä½rÛy“ç<éo]Û;ï\Æ	¹]¤¶1YüåQE¥Ä¤óèÈ$l<ê,`…í‘ÅaGNÅ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/3a/3ef367eaf3fe79effbfb0a56b269c04c2b59fe b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/3a/3ef367eaf3fe79effbfb0a56b269c04c2b59fe
new file mode 100755
index 0000000..b83806e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/3a/3ef367eaf3fe79effbfb0a56b269c04c2b59fe differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/46/ff0854663aeb2182b9838c8da68e33ac23bc1e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/46/ff0854663aeb2182b9838c8da68e33ac23bc1e
new file mode 100755
index 0000000..7064dab
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/46/ff0854663aeb2182b9838c8da68e33ac23bc1e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/4b/8fcff56437e60f58e9a6bc630dd242ebf6ea2c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/4b/8fcff56437e60f58e9a6bc630dd242ebf6ea2c
new file mode 100755
index 0000000..c0bd3db
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/4b/8fcff56437e60f58e9a6bc630dd242ebf6ea2c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/52/c95c4264245469a0617e289a7d737f156826b4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/52/c95c4264245469a0617e289a7d737f156826b4
new file mode 100755
index 0000000..7cc9e96
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/52/c95c4264245469a0617e289a7d737f156826b4
@@ -0,0 +1,2 @@
+x¥=N1…©s
+k›mØU~Ç	!J´È8ÎÎIP&ÀõÉ2@¢°ä÷¤Ïï™jÎk+ñ¡7fð˜ŒCË^'…FF3¹4{–’”dCN")JìÅGh\:¸@‘І¤Q¡f²^E­³™ˆò`“vèEøìKmð¿C‹p]jÞj'î}{É+µºÕÔÏTó3(sqcŒ“p’NJ1ÜQ´ó?NˆwþâÖáðÆíÆ0·Phc¾«í´Ë#¬¥Wؽƒ×eÝ ýrìþüóãnk¹	ZB)CdÆÛ	QMÚË4Å„è‚Wg,ÏÆk鷺(ëÎâçہä
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/55/568c8de5322ff9a95d72747a239cdb64a19965 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/55/568c8de5322ff9a95d72747a239cdb64a19965
new file mode 100755
index 0000000..4dae50b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/55/568c8de5322ff9a95d72747a239cdb64a19965
@@ -0,0 +1 @@
+x¥ŽK!]sŠ¾€¦ù
ãÆx莓ˆÄx}ñî^jñªr«u`œÝÎZÈ1.‰§E£xYƒQÛ¸š¢]\ŒÉvQOêü€D1vX¬3"bYp5‰ÜJ‘S²\BÊ^+z[ëp)ê®·V_íGžô·Îu˽½šŒCnõSèµ
ìÑ#ªIgèà?.Ô,¦Ê°•Y¾eº«/»ZOH
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/55/acf326a69f0aab7a974ec53ffa55a50bcac14e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/55/acf326a69f0aab7a974ec53ffa55a50bcac14e
new file mode 100755
index 0000000..e9cdfc5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/55/acf326a69f0aab7a974ec53ffa55a50bcac14e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/5a/cdc74af27172ec491d213ee36cea7eb9ef2579 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/5a/cdc74af27172ec491d213ee36cea7eb9ef2579
new file mode 100755
index 0000000..61055ea
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/5a/cdc74af27172ec491d213ee36cea7eb9ef2579
@@ -0,0 +1,3 @@
+x¥=N1…©s
+w[-Š“8?B4”t\ ?3E&«L×'«' °ä÷é=?9÷Öö	éifˆ6Tg¸æDhµIÞ³4=*·<>zRäªAq‹ƒÆ:‡VYm©ÎQ˜K
+ÑpÒA’èÑП5sÈ…Šg”Jg…«€‘£õ†³ÌäU"IRÄï¹õïå'ŽŸ[og?à…½oomÏ£Ÿ½ÎçÜÛ+ ö´fõÁuÅ¥Xt=6ù'ď/†4â‘7¸´»:¯yý˜Lü:øc’
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/6b/ccd0dc58cea5ccff86014f3d64b31bd8c02a37 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/6b/ccd0dc58cea5ccff86014f3d64b31bd8c02a37
new file mode 100755
index 0000000..2664da4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/6b/ccd0dc58cea5ccff86014f3d64b31bd8c02a37 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/71/eb9c2b53dbbf3c45fb28b27c850db4b7fb8011 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/71/eb9c2b53dbbf3c45fb28b27c850db4b7fb8011
new file mode 100755
index 0000000..995a1e6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/71/eb9c2b53dbbf3c45fb28b27c850db4b7fb8011 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/72/333f47d4e83616630ff3b0ffe4c0faebcc3c45 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/72/333f47d4e83616630ff3b0ffe4c0faebcc3c45
new file mode 100755
index 0000000..1f69787
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/72/333f47d4e83616630ff3b0ffe4c0faebcc3c45 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/73/ec36fa120f8066963a0bc9105bb273dbd903d7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/73/ec36fa120f8066963a0bc9105bb273dbd903d7
new file mode 100755
index 0000000..3c8d2c2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/73/ec36fa120f8066963a0bc9105bb273dbd903d7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/74/7726e021bc5f44b86de60e3032fd6f9f1b8383 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/74/7726e021bc5f44b86de60e3032fd6f9f1b8383
new file mode 100755
index 0000000..e4d1477
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/74/7726e021bc5f44b86de60e3032fd6f9f1b8383 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/75/ec9929465623f17ff3ad68c0438ea56faba815 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/75/ec9929465623f17ff3ad68c0438ea56faba815
new file mode 100755
index 0000000..a3609c7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/75/ec9929465623f17ff3ad68c0438ea56faba815 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/77/31926a337c4eaba1e2187d90ebfa0a93659382 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/77/31926a337c4eaba1e2187d90ebfa0a93659382
new file mode 100755
index 0000000..b87fa15
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/77/31926a337c4eaba1e2187d90ebfa0a93659382 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/83/f65df4606c4f8dbf8da43de25de1b7e4c03238 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/83/f65df4606c4f8dbf8da43de25de1b7e4c03238
new file mode 100755
index 0000000..152ed5f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/83/f65df4606c4f8dbf8da43de25de1b7e4c03238 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/87/59ad453cf01cf7daf14e2a668f8218f9a678eb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/87/59ad453cf01cf7daf14e2a668f8218f9a678eb
new file mode 100755
index 0000000..ab19acf
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/87/59ad453cf01cf7daf14e2a668f8218f9a678eb differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/8b/e77695228eadd004606af0508462457961ca4a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/8b/e77695228eadd004606af0508462457961ca4a
new file mode 100755
index 0000000..951917c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/8b/e77695228eadd004606af0508462457961ca4a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/8f/d40e13fff575b63e86af87175e70fa7fb92f80 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/8f/d40e13fff575b63e86af87175e70fa7fb92f80
new file mode 100755
index 0000000..9ff8617
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/8f/d40e13fff575b63e86af87175e70fa7fb92f80 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/97/e52d5e81f541080cd6b92829fb85bc4d81d90b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/97/e52d5e81f541080cd6b92829fb85bc4d81d90b
new file mode 100755
index 0000000..416ae0f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/97/e52d5e81f541080cd6b92829fb85bc4d81d90b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/97/f3574e92f1730d365fb9e00c10e3c507c1cfe9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/97/f3574e92f1730d365fb9e00c10e3c507c1cfe9
new file mode 100755
index 0000000..12ebc58
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/97/f3574e92f1730d365fb9e00c10e3c507c1cfe9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/9a/95fd974e03c5b93828ceedd28755965b5d5c60 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/9a/95fd974e03c5b93828ceedd28755965b5d5c60
new file mode 100755
index 0000000..bb93a34
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/9a/95fd974e03c5b93828ceedd28755965b5d5c60 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/a6/9f74efcb51634b88e04ea81273158a85257f41 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/a6/9f74efcb51634b88e04ea81273158a85257f41
new file mode 100755
index 0000000..b96831f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/a6/9f74efcb51634b88e04ea81273158a85257f41 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/a8/c86221b400b836010567cc3593db6e96c1a83a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/a8/c86221b400b836010567cc3593db6e96c1a83a
new file mode 100755
index 0000000..2965461
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/a8/c86221b400b836010567cc3593db6e96c1a83a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/aa/7e281435d1fe6740d712f4bcc6fe89c425bedc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/aa/7e281435d1fe6740d712f4bcc6fe89c425bedc
new file mode 100755
index 0000000..f0dd67d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/aa/7e281435d1fe6740d712f4bcc6fe89c425bedc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/ac/c4d33902092efeb3b714aa0b1007c329e2f2e6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/ac/c4d33902092efeb3b714aa0b1007c329e2f2e6
new file mode 100755
index 0000000..91bb68b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/ac/c4d33902092efeb3b714aa0b1007c329e2f2e6
@@ -0,0 +1,2 @@
+xÍ[
+1@QßJW‘
étÒ6 F,LâþWàßý8peé½ø1llU.LÊiTB‡<dQ­uȉˆ#MTI"ºò¶ç²Âv·?OçË7ঽ´ù>dN0z¸"!:ùMLÿ䮽š¹õ$Î
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/b7/a55408832174c54708906a372a9be2ffe3649b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/b7/a55408832174c54708906a372a9be2ffe3649b
new file mode 100755
index 0000000..77d4e20
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/b7/a55408832174c54708906a372a9be2ffe3649b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/be/ead165e017269e8dc0dd6f01195726a2e1e01b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/be/ead165e017269e8dc0dd6f01195726a2e1e01b
new file mode 100755
index 0000000..57de3f2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/be/ead165e017269e8dc0dd6f01195726a2e1e01b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/ce/f56612d71a6af8d8015691e4865f7fece905b5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/ce/f56612d71a6af8d8015691e4865f7fece905b5
new file mode 100755
index 0000000..5645885
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/ce/f56612d71a6af8d8015691e4865f7fece905b5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/d1/d403d22cbe24592d725f442835cf46fe60c8ac b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/d1/d403d22cbe24592d725f442835cf46fe60c8ac
new file mode 100755
index 0000000..2190bb4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/d1/d403d22cbe24592d725f442835cf46fe60c8ac differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/dd/9a159c89509e73fd37d6af99619994cf7dfc06 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/dd/9a159c89509e73fd37d6af99619994cf7dfc06
new file mode 100755
index 0000000..ed80d0a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/dd/9a159c89509e73fd37d6af99619994cf7dfc06 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/e3/4ef1afe54eb526fd92eec66084125f340f1d65 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/e3/4ef1afe54eb526fd92eec66084125f340f1d65
new file mode 100755
index 0000000..fc19ebd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/e3/4ef1afe54eb526fd92eec66084125f340f1d65 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/e5/f831f064adf9224d8c3ce556959d9d61b3c0a9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/e5/f831f064adf9224d8c3ce556959d9d61b3c0a9
new file mode 100755
index 0000000..665f1a1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/e5/f831f064adf9224d8c3ce556959d9d61b3c0a9
@@ -0,0 +1 @@
+x¥OIj1ôY¯h|é–[3„K>`üIÝbæ +h”äû™8y@À§*ª –Üj]œÑFWBÂìÏD2¡ §(4Q˜#N(,²ckÞc×Û€0«³âÔSqLè1Ë”‚õ6”ä]Ê,ž$`2ñc,­Ã›|Å.p]ZÝÚ
žuWØk]so[+ã”[}bbf´|†'dD³«ûСD˜‹~jpüêGc®ËºA¿ü–üûÔÉ|ki`ö
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/ea/392a157085bc32daccd59aa1998fe2f5fb9fc0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/ea/392a157085bc32daccd59aa1998fe2f5fb9fc0
new file mode 100755
index 0000000..1451a6a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/ea/392a157085bc32daccd59aa1998fe2f5fb9fc0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/eb/b03002cee5d66c7732dd06241119fe72ab96a5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/eb/b03002cee5d66c7732dd06241119fe72ab96a5
new file mode 100755
index 0000000..802125e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/eb/b03002cee5d66c7732dd06241119fe72ab96a5
@@ -0,0 +1,2 @@
+x¥Á	1E=§Ši at I6&AÄ‹Ø@6;ÃÌdGlßXƒ‡Ÿwø¯HkUÁa<h'äålÉyf)ÌÑÆ̘\
+”,çÄóeb´&¿u•å“ûÏUÚ.\iØߺ·ZºìÂz*Ònà<†Áä#m°Ö;ÂJ\˜ºU­ùe¾8[>`
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/ee/c6adcb2f3ceca0cadeccfe01b19382252ece9b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/ee/c6adcb2f3ceca0cadeccfe01b19382252ece9b
new file mode 100755
index 0000000..f59f3d4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/ee/c6adcb2f3ceca0cadeccfe01b19382252ece9b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/f4/e107c230d08a60fb419d19869f1f282b272d9c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/f4/e107c230d08a60fb419d19869f1f282b272d9c
new file mode 100755
index 0000000..029da1b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/objects/f4/e107c230d08a60fb419d19869f1f282b272d9c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/refs/heads/master
new file mode 100755
index 0000000..180f407
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/refs/heads/master
@@ -0,0 +1 @@
+2d440f2b3147d3dc7ad1085813478d6d869d5a4d
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/refs/heads/merges b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/refs/heads/merges
new file mode 100755
index 0000000..6533a94
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/refs/heads/merges
@@ -0,0 +1 @@
+5acdc74af27172ec491d213ee36cea7eb9ef2579
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/refs/heads/merges-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/refs/heads/merges-branch
new file mode 100755
index 0000000..febb29c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/refs/heads/merges-branch
@@ -0,0 +1 @@
+13ee9cd5d8e1023c218e0e1ea684ec0c582b5050
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/refs/heads/reverted-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/refs/heads/reverted-branch
new file mode 100755
index 0000000..16bb7a2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/refs/heads/reverted-branch
@@ -0,0 +1 @@
+52c95c4264245469a0617e289a7d737f156826b4
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/refs/heads/two b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/refs/heads/two
new file mode 100755
index 0000000..69d76cf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/.gitted/refs/heads/two
@@ -0,0 +1 @@
+75ec9929465623f17ff3ad68c0438ea56faba815
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/file1.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/file1.txt
new file mode 100755
index 0000000..84b2259
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/file1.txt
@@ -0,0 +1,14 @@
+!File one!
+!File one!
+File one!
+File one
+File one
+File one
+File one
+File one
+File one
+File one
+File one!
+!File one!
+!File one!
+!File one!
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/file2.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/file2.txt
new file mode 100755
index 0000000..acb5747
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/file2.txt
@@ -0,0 +1,16 @@
+File two
+File two
+File two
+File two
+File two
+File two
+File two
+File two
+File two
+File two
+File two
+File two
+File two
+File two
+File two
+File two
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/file3.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/file3.txt
new file mode 100755
index 0000000..b033059
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/file3.txt
@@ -0,0 +1,16 @@
+File three
+File three
+File three
+File three
+File three
+File three
+File three
+File three
+File three
+File three
+File three
+File three
+File three
+File three
+File three
+File three
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/file6.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/file6.txt
new file mode 100755
index 0000000..5c0cd5d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/revert/file6.txt
@@ -0,0 +1,14 @@
+File six, actually!
+File four!
+File four!
+File four!
+File four!
+File four!
+File four!
+File four!
+File four!
+File four!
+File four!
+File four!
+File four!
+File four!
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/config
new file mode 100755
index 0000000..a88b74b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/config
@@ -0,0 +1,8 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = true
+	ignorecase = true
+	precomposeunicode = false
+[remote "origin"]
+	url = file://testrepo.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/objects/pack/pack-706e49b161700946489570d96153e5be4dc31ad4.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/objects/pack/pack-706e49b161700946489570d96153e5be4dc31ad4.idx
new file mode 100755
index 0000000..bfc7d24
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/objects/pack/pack-706e49b161700946489570d96153e5be4dc31ad4.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/objects/pack/pack-706e49b161700946489570d96153e5be4dc31ad4.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/objects/pack/pack-706e49b161700946489570d96153e5be4dc31ad4.pack
new file mode 100755
index 0000000..ccc6932
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/objects/pack/pack-706e49b161700946489570d96153e5be4dc31ad4.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/packed-refs
new file mode 100755
index 0000000..97eed74
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+a65fedf39aefe402d3bb6e24df4d4f5fe4547750 refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/refs/.gitkeep b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/refs/.gitkeep
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/shallow b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/shallow
new file mode 100755
index 0000000..9536ad8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/shallow.git/shallow
@@ -0,0 +1 @@
+be3563ae3f795b2b4353bcce3a527ad0a4f7f644
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/config
new file mode 100755
index 0000000..a4ef456
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/config
@@ -0,0 +1,5 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = true
+	logallrefupdates = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/index
new file mode 100755
index 0000000..87fef78
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/objects/4a/5ed60bafcf4638b7c8356bd4ce1916bfede93c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/objects/4a/5ed60bafcf4638b7c8356bd4ce1916bfede93c
new file mode 100755
index 0000000..aeb4e4b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/objects/4a/5ed60bafcf4638b7c8356bd4ce1916bfede93c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/objects/4d/5fcadc293a348e88f777dc0920f11e7d71441c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/objects/4d/5fcadc293a348e88f777dc0920f11e7d71441c
new file mode 100755
index 0000000..806ce71
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/objects/4d/5fcadc293a348e88f777dc0920f11e7d71441c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/objects/5d/a7760512a953e3c7c4e47e4392c7a4338fb729 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/objects/5d/a7760512a953e3c7c4e47e4392c7a4338fb729
new file mode 100755
index 0000000..1192707
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/objects/5d/a7760512a953e3c7c4e47e4392c7a4338fb729
@@ -0,0 +1 @@
+xÌM‚0@aלb. ií%1ƍ—pcÚé@Š”˜˜èé-Ëï-û¤6§&Bí
E+‚pÐV¹Ð¡SƆ¨‘d/m(R¯°áïJ€%çÄ
×ÇR^‘vÜÒÊ©,GiƒÇ–Þðñ<Ó´3\©º­n‡ïcöinëåRé„SögÑ	Ñüëu1
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100755
index 0000000..7112238
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/packed-refs
new file mode 100755
index 0000000..ca5197e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/packed-refs
@@ -0,0 +1 @@
+5da7760512a953e3c7c4e47e4392c7a4338fb729 refs/tags/no_description
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/refs/heads/master
new file mode 100755
index 0000000..fcefd1e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/short_tag.git/refs/heads/master
@@ -0,0 +1 @@
+4a5ed60bafcf4638b7c8356bd4ce1916bfede93c
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/COMMIT_EDITMSG b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/COMMIT_EDITMSG
new file mode 100755
index 0000000..1a25cd4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/COMMIT_EDITMSG
@@ -0,0 +1 @@
+Add a file which name should appear before the "subdir/" folder while being dealt with by the treewalker
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/ORIG_HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/ORIG_HEAD
new file mode 100755
index 0000000..b46871f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/ORIG_HEAD
@@ -0,0 +1 @@
+735b6a258cd196a8f7c9428419b02c1dca93fd75
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/config
new file mode 100755
index 0000000..af10792
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/config
@@ -0,0 +1,6 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/index
new file mode 100755
index 0000000..2af99a1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/info/exclude
new file mode 100755
index 0000000..0c4042a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/info/exclude
@@ -0,0 +1,8 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
+ignored*
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/logs/HEAD
new file mode 100755
index 0000000..7b95b3c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/logs/HEAD
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 0017bd4ab1ec30440b17bae1680cff124ab5f1f6 Jason Penny <jasonpenny4 at gmail.com> 1308050070 -0400	commit (initial): initial
+0017bd4ab1ec30440b17bae1680cff124ab5f1f6 735b6a258cd196a8f7c9428419b02c1dca93fd75 Jason Penny <jasonpenny4 at gmail.com> 1308954538 -0400	commit: add subdir
+735b6a258cd196a8f7c9428419b02c1dca93fd75 26a125ee1bfc5df1e1b2e9441bbe63c8a7ae989f nulltoken <emeric.fermas at gmail.com> 1319911544 +0200	commit: Add a file which name should appear before the "subdir/" folder while being dealt with by the treewalker
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..7b95b3c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/logs/refs/heads/master
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 0017bd4ab1ec30440b17bae1680cff124ab5f1f6 Jason Penny <jasonpenny4 at gmail.com> 1308050070 -0400	commit (initial): initial
+0017bd4ab1ec30440b17bae1680cff124ab5f1f6 735b6a258cd196a8f7c9428419b02c1dca93fd75 Jason Penny <jasonpenny4 at gmail.com> 1308954538 -0400	commit: add subdir
+735b6a258cd196a8f7c9428419b02c1dca93fd75 26a125ee1bfc5df1e1b2e9441bbe63c8a7ae989f nulltoken <emeric.fermas at gmail.com> 1319911544 +0200	commit: Add a file which name should appear before the "subdir/" folder while being dealt with by the treewalker
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/00/17bd4ab1ec30440b17bae1680cff124ab5f1f6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/00/17bd4ab1ec30440b17bae1680cff124ab5f1f6
new file mode 100755
index 0000000..b256d95
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/00/17bd4ab1ec30440b17bae1680cff124ab5f1f6
@@ -0,0 +1,2 @@
+xA E]sŠ¹€fh)‰1]»ò
+#SÀTºðö¶Wp÷ßK^~¨9§šÜ¡-"àC'Ø…)FvõbƒvÉÞ"¶wŽŽ¼EÅk{Ö®ü©nRÊίÞû6ã#sšO¡æ舄pDƒ¨6»6ù3W©¤–xV?¨Å9é
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/06/1d42a44cacde5726057b67558821d95db96f19 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/06/1d42a44cacde5726057b67558821d95db96f19
new file mode 100755
index 0000000..82e02cb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/06/1d42a44cacde5726057b67558821d95db96f19 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/18/88c805345ba265b0ee9449b8877b6064592058 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/18/88c805345ba265b0ee9449b8877b6064592058
new file mode 100755
index 0000000..e3cad2f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/18/88c805345ba265b0ee9449b8877b6064592058 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/19/d9cc8584ac2c7dcf57d2680375e80f099dc481 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/19/d9cc8584ac2c7dcf57d2680375e80f099dc481
new file mode 100755
index 0000000..2d5e711
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/19/d9cc8584ac2c7dcf57d2680375e80f099dc481 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/26/a125ee1bfc5df1e1b2e9441bbe63c8a7ae989f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/26/a125ee1bfc5df1e1b2e9441bbe63c8a7ae989f
new file mode 100755
index 0000000..f7dddc4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/26/a125ee1bfc5df1e1b2e9441bbe63c8a7ae989f
@@ -0,0 +1,2 @@
+xMnÄ …»Î)¬ÙVšò† ªö(Ì€BDˆ¢Þ¾LÐöûüžž«¥¤RÈ·Þˆ@êà,Î9Ž‹òÜÌœtàìæ•ðNj6f`žM6Z;h©ì
…ZÜÐÞp	Ú™Y,37¯/Ü;42x­&<z¬
Ö#ç^Ÿ´Â
+µä®ZÁýëQ0å««å¸äÆp®æÞ™`lÛ²Ó?ñéÛ{@)œ1¹+‚=Ö#Ã¶6°j#è‘à²Ö§öqP³®¨¥´>ÀægêìÏŸüÕÛ‰ùImú|½jñ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/32/504b727382542f9f089e24fddac5e78533e96c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/32/504b727382542f9f089e24fddac5e78533e96c
new file mode 100755
index 0000000..7fca67b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/32/504b727382542f9f089e24fddac5e78533e96c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/37/fcb02ccc1a85d1941e7f106d52dc3702dcf0d0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/37/fcb02ccc1a85d1941e7f106d52dc3702dcf0d0
new file mode 100755
index 0000000..b75481b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/37/fcb02ccc1a85d1941e7f106d52dc3702dcf0d0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/45/2e4244b5d083ddf0460acf1ecc74db9dcfa11a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/45/2e4244b5d083ddf0460acf1ecc74db9dcfa11a
new file mode 100755
index 0000000..5b47461
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/45/2e4244b5d083ddf0460acf1ecc74db9dcfa11a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/52/9a16e8e762d4acb7b9636ff540a00831f9155a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/52/9a16e8e762d4acb7b9636ff540a00831f9155a
new file mode 100755
index 0000000..615009a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/52/9a16e8e762d4acb7b9636ff540a00831f9155a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/53/ace0d1cc1145a5f4fe4f78a186a60263190733 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/53/ace0d1cc1145a5f4fe4f78a186a60263190733
new file mode 100755
index 0000000..cdb7e96
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/53/ace0d1cc1145a5f4fe4f78a186a60263190733 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/54/52d32f1dd538eb0405e8a83cc185f79e25e80f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/54/52d32f1dd538eb0405e8a83cc185f79e25e80f
new file mode 100755
index 0000000..a72dff6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/54/52d32f1dd538eb0405e8a83cc185f79e25e80f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/55/d316c9ba708999f1918e9677d01dfcae69c6b9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/55/d316c9ba708999f1918e9677d01dfcae69c6b9
new file mode 100755
index 0000000..72807f3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/55/d316c9ba708999f1918e9677d01dfcae69c6b9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/70/bd9443ada07063e7fbf0b3ff5c13f7494d89c2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/70/bd9443ada07063e7fbf0b3ff5c13f7494d89c2
new file mode 100755
index 0000000..3665a8f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/70/bd9443ada07063e7fbf0b3ff5c13f7494d89c2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/73/5b6a258cd196a8f7c9428419b02c1dca93fd75 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/73/5b6a258cd196a8f7c9428419b02c1dca93fd75
new file mode 100755
index 0000000..08e6fd2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/73/5b6a258cd196a8f7c9428419b02c1dca93fd75 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/75/6e27627e67bfbc048d01ece5819c6de733d7ea b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/75/6e27627e67bfbc048d01ece5819c6de733d7ea
new file mode 100755
index 0000000..8f3fa89
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/75/6e27627e67bfbc048d01ece5819c6de733d7ea differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/90/6ee7711f4f4928ddcb2a5f8fbc500deba0d2a8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/90/6ee7711f4f4928ddcb2a5f8fbc500deba0d2a8
new file mode 100755
index 0000000..bb732b0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/90/6ee7711f4f4928ddcb2a5f8fbc500deba0d2a8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/90/b8c29d8ba39434d1c63e1b093daaa26e5bd972 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/90/b8c29d8ba39434d1c63e1b093daaa26e5bd972
new file mode 100755
index 0000000..7a96618
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/90/b8c29d8ba39434d1c63e1b093daaa26e5bd972 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/9c/2e02cdffa8d73e6c189074594477a6baf87960 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/9c/2e02cdffa8d73e6c189074594477a6baf87960
new file mode 100755
index 0000000..20a3c49
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/9c/2e02cdffa8d73e6c189074594477a6baf87960 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/a0/de7e0ac200c489c41c59dfa910154a70264e6e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/a0/de7e0ac200c489c41c59dfa910154a70264e6e
new file mode 100755
index 0000000..a1789c9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/a0/de7e0ac200c489c41c59dfa910154a70264e6e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/a6/191982709b746d5650e93c2acf34ef74e11504 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/a6/191982709b746d5650e93c2acf34ef74e11504
new file mode 100755
index 0000000..cc1f377
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/a6/191982709b746d5650e93c2acf34ef74e11504 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/a6/be623522ce87a1d862128ac42672604f7b468b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/a6/be623522ce87a1d862128ac42672604f7b468b
new file mode 100755
index 0000000..c472983
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/a6/be623522ce87a1d862128ac42672604f7b468b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/aa/27a641456848200fdb7f7c99ba36f8a0952877 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/aa/27a641456848200fdb7f7c99ba36f8a0952877
new file mode 100755
index 0000000..a4669cc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/aa/27a641456848200fdb7f7c99ba36f8a0952877 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/da/bc8af9bd6e9f5bbe96a176f1a24baf3d1f8916 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/da/bc8af9bd6e9f5bbe96a176f1a24baf3d1f8916
new file mode 100755
index 0000000..3e3c03c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/da/bc8af9bd6e9f5bbe96a176f1a24baf3d1f8916 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/e8/ee89e15bbe9b20137715232387b3de5b28972e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/e8/ee89e15bbe9b20137715232387b3de5b28972e
new file mode 100755
index 0000000..cfc2413
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/e8/ee89e15bbe9b20137715232387b3de5b28972e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/e9/b9107f290627c04d097733a10055af941f6bca b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/e9/b9107f290627c04d097733a10055af941f6bca
new file mode 100755
index 0000000..1266d3e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/e9/b9107f290627c04d097733a10055af941f6bca differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/ed/062903b8f6f3dccb2fa81117ba6590944ef9bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/ed/062903b8f6f3dccb2fa81117ba6590944ef9bd
new file mode 100755
index 0000000..8fa8c17
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/objects/ed/062903b8f6f3dccb2fa81117ba6590944ef9bd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/refs/heads/master
new file mode 100755
index 0000000..3e2e2a0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/.gitted/refs/heads/master
@@ -0,0 +1 @@
+26a125ee1bfc5df1e1b2e9441bbe63c8a7ae989f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/current_file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/current_file
new file mode 100755
index 0000000..a0de7e0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/current_file
@@ -0,0 +1 @@
+current_file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/ignored_file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/ignored_file
new file mode 100755
index 0000000..6a79f80
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/ignored_file
@@ -0,0 +1 @@
+ignored_file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/modified_file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/modified_file
new file mode 100755
index 0000000..0a53963
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/modified_file
@@ -0,0 +1,2 @@
+modified_file
+modified_file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/new_file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/new_file
new file mode 100755
index 0000000..d4fa860
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/new_file
@@ -0,0 +1 @@
+new_file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/staged_changes b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/staged_changes
new file mode 100755
index 0000000..55d316c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/staged_changes
@@ -0,0 +1,2 @@
+staged_changes
+staged_changes
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/staged_changes_modified_file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/staged_changes_modified_file
new file mode 100755
index 0000000..011c344
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/staged_changes_modified_file
@@ -0,0 +1,3 @@
+staged_changes_modified_file
+staged_changes_modified_file
+staged_changes_modified_file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/staged_delete_modified_file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/staged_delete_modified_file
new file mode 100755
index 0000000..dabc8af
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/staged_delete_modified_file
@@ -0,0 +1 @@
+staged_delete_modified_file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/staged_new_file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/staged_new_file
new file mode 100755
index 0000000..529a16e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/staged_new_file
@@ -0,0 +1 @@
+staged_new_file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/staged_new_file_modified_file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/staged_new_file_modified_file
new file mode 100755
index 0000000..8b090c0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/staged_new_file_modified_file
@@ -0,0 +1,2 @@
+staged_new_file_modified_file
+staged_new_file_modified_file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/subdir.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/subdir.txt
new file mode 100755
index 0000000..e8ee89e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/subdir.txt
@@ -0,0 +1,2 @@
+Is it a bird?
+Is it a plane?
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/subdir/current_file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/subdir/current_file
new file mode 100755
index 0000000..53ace0d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/subdir/current_file
@@ -0,0 +1 @@
+subdir/current_file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/subdir/modified_file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/subdir/modified_file
new file mode 100755
index 0000000..57274b7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/subdir/modified_file
@@ -0,0 +1,2 @@
+subdir/modified_file
+subdir/modified_file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/subdir/new_file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/subdir/new_file
new file mode 100755
index 0000000..80a86a6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/subdir/new_file
@@ -0,0 +1 @@
+subdir/new_file
diff --git "a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/\350\277\231" "b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/\350\277\231"
new file mode 100755
index 0000000..f0ff9a1
--- /dev/null
+++ "b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/status/\350\277\231"
@@ -0,0 +1 @@
+This
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/config
new file mode 100755
index 0000000..abc4207
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/config
@@ -0,0 +1,20 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
+[submodule "sm_missing_commits"]
+	url = ../submod2_target
+[submodule "sm_unchanged"]
+	url = ../submod2_target
+[submodule "sm_changed_file"]
+	url = ../submod2_target
+[submodule "sm_changed_index"]
+	url = ../submod2_target
+[submodule "sm_changed_head"]
+	url = ../submod2_target
+[submodule "sm_changed_untracked_file"]
+	url = ../submod2_target
+[submodule "sm_added_and_uncommited"]
+	url = ../submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/index
new file mode 100755
index 0000000..0c17e86
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/logs/HEAD
new file mode 100755
index 0000000..2cf2ca7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/logs/HEAD
@@ -0,0 +1,4 @@
+0000000000000000000000000000000000000000 14fe9ccf104058df25e0a08361c4494e167ef243 Russell Belfer <rb at github.com> 1342559771 -0700	commit (initial): Initial commit
+14fe9ccf104058df25e0a08361c4494e167ef243 a9104bf89e911387244ef499413960ba472066d9 Russell Belfer <rb at github.com> 1342559831 -0700	commit: Adding a submodule
+a9104bf89e911387244ef499413960ba472066d9 5901da4f1c67756eeadc5121d206bec2431f253b Russell Belfer <rb at github.com> 1342560036 -0700	commit: Updating submodule
+5901da4f1c67756eeadc5121d206bec2431f253b 7484482eb8db738cafa696993664607500a3f2b9 Russell Belfer <rb at github.com> 1342560288 -0700	commit: Adding a bunch more test content
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..2cf2ca7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/logs/refs/heads/master
@@ -0,0 +1,4 @@
+0000000000000000000000000000000000000000 14fe9ccf104058df25e0a08361c4494e167ef243 Russell Belfer <rb at github.com> 1342559771 -0700	commit (initial): Initial commit
+14fe9ccf104058df25e0a08361c4494e167ef243 a9104bf89e911387244ef499413960ba472066d9 Russell Belfer <rb at github.com> 1342559831 -0700	commit: Adding a submodule
+a9104bf89e911387244ef499413960ba472066d9 5901da4f1c67756eeadc5121d206bec2431f253b Russell Belfer <rb at github.com> 1342560036 -0700	commit: Updating submodule
+5901da4f1c67756eeadc5121d206bec2431f253b 7484482eb8db738cafa696993664607500a3f2b9 Russell Belfer <rb at github.com> 1342560288 -0700	commit: Adding a bunch more test content
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/config
new file mode 100755
index 0000000..2d0583e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/config
@@ -0,0 +1,13 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	worktree = ../../../sm_added_and_uncommited
+	ignorecase = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = /Users/rb/src/libgit2/tests-clar/resources/submod2_target
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/index
new file mode 100755
index 0000000..65140a5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/logs/HEAD
new file mode 100755
index 0000000..53753e7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560316 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/logs/refs/heads/master
new file mode 100755
index 0000000..53753e7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560316 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/logs/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/logs/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..53753e7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/logs/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560316 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1
new file mode 100755
index 0000000..f4b7094
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484
new file mode 100755
index 0000000..56c845e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5
new file mode 100755
index 0000000..bd179b5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/41/bd4bc3df978de695f67ace64c560913da11653 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/41/bd4bc3df978de695f67ace64c560913da11653
new file mode 100755
index 0000000..ccf49bd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/41/bd4bc3df978de695f67ace64c560913da11653 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/48/0095882d281ed676fe5b863569520e54a7d5c0
new file mode 100755
index 0000000..5302906
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/5e/4963595a9774b90524d35a807169049de8ccad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/5e/4963595a9774b90524d35a807169049de8ccad
new file mode 100755
index 0000000..38c791e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/5e/4963595a9774b90524d35a807169049de8ccad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/6b/31c659545507c381e9cd34ec508f16c04e149e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
new file mode 100755
index 0000000..a26d299
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
@@ -0,0 +1,2 @@
+x•Q
+!EûvoÅÓy*Ñ_¿í@Çg#h‚£ûOhý^Î9w«¥¤ÒêSoÌ€f1*²ŠÁ[”‰¬§èIc Ô¤ìê¤p£ïµÁkçΑ\›¿¿S߇¿lµÜ@.¤´^QpF‹(æ:ÿúDÿ5Åó“zr~	ñen8
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/73/ba924a80437097795ae839e66e187c55d3babf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/73/ba924a80437097795ae839e66e187c55d3babf
new file mode 100755
index 0000000..83d1ba4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/73/ba924a80437097795ae839e66e187c55d3babf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
new file mode 100755
index 0000000..6d27af8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
@@ -0,0 +1,2 @@
+x-Ë1Â0FaæžâßØ0pŽÀìÄÐ(N-ÅöÐÛÓ¡Ò“¾é±ãq]>ksÅ*š?	|m“‡Õçiª@ÛÖý¶¼m»¨V£…£'©î`)”.Ø-1¨x
+u„xãòt(+
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/78/9efbdadaa4a582778d4584385495559ea0994b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/78/9efbdadaa4a582778d4584385495559ea0994b
new file mode 100755
index 0000000..1745884
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/78/9efbdadaa4a582778d4584385495559ea0994b
@@ -0,0 +1,2 @@
+x
α
…0)ÞŠ?=
¥ÉÄNŠlO¤k®¸‹jÛúÿ¹8&„«¨ ãr
”
+ïqJWñ°7¾B<ÉáöfÙìK8­#Q1C-‘"eª·Ì«£Š°ð>¼'@
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e
new file mode 100755
index 0000000..83cc29f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5
new file mode 100755
index 0000000..55bda40
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/packed-refs
new file mode 100755
index 0000000..5a4ebc4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+480095882d281ed676fe5b863569520e54a7d5c0 refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/refs/heads/master
new file mode 100755
index 0000000..e12c44d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/refs/heads/master
@@ -0,0 +1 @@
+480095882d281ed676fe5b863569520e54a7d5c0
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..6efe28f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_added_and_uncommited/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/config
new file mode 100755
index 0000000..10cc250
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/config
@@ -0,0 +1,13 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	worktree = ../../../sm_changed_file
+	ignorecase = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = /Users/rb/src/libgit2/tests-clar/resources/submod2_target
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/index
new file mode 100755
index 0000000..6914a3b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/logs/HEAD
new file mode 100755
index 0000000..e5cb63f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560173 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/logs/refs/heads/master
new file mode 100755
index 0000000..e5cb63f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560173 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/logs/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/logs/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..e5cb63f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/logs/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560173 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1
new file mode 100755
index 0000000..f4b7094
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484
new file mode 100755
index 0000000..56c845e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5
new file mode 100755
index 0000000..bd179b5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/41/bd4bc3df978de695f67ace64c560913da11653 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/41/bd4bc3df978de695f67ace64c560913da11653
new file mode 100755
index 0000000..ccf49bd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/41/bd4bc3df978de695f67ace64c560913da11653 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/48/0095882d281ed676fe5b863569520e54a7d5c0
new file mode 100755
index 0000000..5302906
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/5e/4963595a9774b90524d35a807169049de8ccad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/5e/4963595a9774b90524d35a807169049de8ccad
new file mode 100755
index 0000000..38c791e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/5e/4963595a9774b90524d35a807169049de8ccad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/6b/31c659545507c381e9cd34ec508f16c04e149e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
new file mode 100755
index 0000000..a26d299
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
@@ -0,0 +1,2 @@
+x•Q
+!EûvoÅÓy*Ñ_¿í@Çg#h‚£ûOhý^Î9w«¥¤ÒêSoÌ€f1*²ŠÁ[”‰¬§èIc Ô¤ìê¤p£ïµÁkçΑ\›¿¿S߇¿lµÜ@.¤´^QpF‹(æ:ÿúDÿ5Åó“zr~	ñen8
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/73/ba924a80437097795ae839e66e187c55d3babf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/73/ba924a80437097795ae839e66e187c55d3babf
new file mode 100755
index 0000000..83d1ba4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/73/ba924a80437097795ae839e66e187c55d3babf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
new file mode 100755
index 0000000..6d27af8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
@@ -0,0 +1,2 @@
+x-Ë1Â0FaæžâßØ0pŽÀìÄÐ(N-ÅöÐÛÓ¡Ò“¾é±ãq]>ksÅ*š?	|m“‡Õçiª@ÛÖý¶¼m»¨V£…£'©î`)”.Ø-1¨x
+u„xãòt(+
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/78/9efbdadaa4a582778d4584385495559ea0994b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/78/9efbdadaa4a582778d4584385495559ea0994b
new file mode 100755
index 0000000..1745884
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/78/9efbdadaa4a582778d4584385495559ea0994b
@@ -0,0 +1,2 @@
+x
α
…0)ÞŠ?=
¥ÉÄNŠlO¤k®¸‹jÛúÿ¹8&„«¨ ãr
”
+ïqJWñ°7¾B<ÉáöfÙìK8­#Q1C-‘"eª·Ì«£Š°ð>¼'@
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e
new file mode 100755
index 0000000..83cc29f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5
new file mode 100755
index 0000000..55bda40
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/packed-refs
new file mode 100755
index 0000000..5a4ebc4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+480095882d281ed676fe5b863569520e54a7d5c0 refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/refs/heads/master
new file mode 100755
index 0000000..e12c44d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/refs/heads/master
@@ -0,0 +1 @@
+480095882d281ed676fe5b863569520e54a7d5c0
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..6efe28f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_file/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/COMMIT_EDITMSG b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/COMMIT_EDITMSG
new file mode 100755
index 0000000..6b8d1e3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/COMMIT_EDITMSG
@@ -0,0 +1 @@
+Making a change in a submodule
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/config
new file mode 100755
index 0000000..7d00253
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/config
@@ -0,0 +1,13 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	worktree = ../../../sm_changed_head
+	ignorecase = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = /Users/rb/src/libgit2/tests-clar/resources/submod2_target
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/index
new file mode 100755
index 0000000..728fa29
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/logs/HEAD
new file mode 100755
index 0000000..cabdeb2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/logs/HEAD
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560179 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
+480095882d281ed676fe5b863569520e54a7d5c0 3d9386c507f6b093471a3e324085657a3c2b4247 Russell Belfer <rb at github.com> 1342560431 -0700	commit: Making a change in a submodule
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/logs/refs/heads/master
new file mode 100755
index 0000000..cabdeb2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/logs/refs/heads/master
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560179 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
+480095882d281ed676fe5b863569520e54a7d5c0 3d9386c507f6b093471a3e324085657a3c2b4247 Russell Belfer <rb at github.com> 1342560431 -0700	commit: Making a change in a submodule
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/logs/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/logs/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..257ca21
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/logs/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560179 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1
new file mode 100755
index 0000000..f4b7094
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484
new file mode 100755
index 0000000..56c845e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5
new file mode 100755
index 0000000..bd179b5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/3d/9386c507f6b093471a3e324085657a3c2b4247 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/3d/9386c507f6b093471a3e324085657a3c2b4247
new file mode 100755
index 0000000..a2c3716
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/3d/9386c507f6b093471a3e324085657a3c2b4247
@@ -0,0 +1,3 @@
+x•ŽKj!E3vµ„jµüÀ#<Þ<“ì@­êéO°uÿq™.çÂ)×ql
´‰o­Š€÷sFa#Èv‰ÓÅ)g#{':ªßTål`b¤4ë0	;ïf¡ár‘4
+Ùä™
+ªÔÛzUøî÷-û/Ùg©ð¨ù¹lmíù£\Ç'LÆjrhÍïèÕXG_êŸê+ýlç	ÊšÎE`;ß=÷]ÔÞJç
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/41/bd4bc3df978de695f67ace64c560913da11653 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/41/bd4bc3df978de695f67ace64c560913da11653
new file mode 100755
index 0000000..ccf49bd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/41/bd4bc3df978de695f67ace64c560913da11653 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/48/0095882d281ed676fe5b863569520e54a7d5c0
new file mode 100755
index 0000000..5302906
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/5e/4963595a9774b90524d35a807169049de8ccad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/5e/4963595a9774b90524d35a807169049de8ccad
new file mode 100755
index 0000000..38c791e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/5e/4963595a9774b90524d35a807169049de8ccad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/6b/31c659545507c381e9cd34ec508f16c04e149e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
new file mode 100755
index 0000000..a26d299
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
@@ -0,0 +1,2 @@
+x•Q
+!EûvoÅÓy*Ñ_¿í@Çg#h‚£ûOhý^Î9w«¥¤ÒêSoÌ€f1*²ŠÁ[”‰¬§èIc Ô¤ìê¤p£ïµÁkçΑ\›¿¿S߇¿lµÜ@.¤´^QpF‹(æ:ÿúDÿ5Åó“zr~	ñen8
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/73/ba924a80437097795ae839e66e187c55d3babf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/73/ba924a80437097795ae839e66e187c55d3babf
new file mode 100755
index 0000000..83d1ba4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/73/ba924a80437097795ae839e66e187c55d3babf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/77/fb0ed3e58568d6ad362c78de08ab8649d76e29 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/77/fb0ed3e58568d6ad362c78de08ab8649d76e29
new file mode 100755
index 0000000..f8a236f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/77/fb0ed3e58568d6ad362c78de08ab8649d76e29 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
new file mode 100755
index 0000000..6d27af8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
@@ -0,0 +1,2 @@
+x-Ë1Â0FaæžâßØ0pŽÀìÄÐ(N-ÅöÐÛÓ¡Ò“¾é±ãq]>ksÅ*š?	|m“‡Õçiª@ÛÖý¶¼m»¨V£…£'©î`)”.Ø-1¨x
+u„xãòt(+
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/78/9efbdadaa4a582778d4584385495559ea0994b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/78/9efbdadaa4a582778d4584385495559ea0994b
new file mode 100755
index 0000000..1745884
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/78/9efbdadaa4a582778d4584385495559ea0994b
@@ -0,0 +1,2 @@
+x
α
…0)ÞŠ?=
¥ÉÄNŠlO¤k®¸‹jÛúÿ¹8&„«¨ ãr
”
+ïqJWñ°7¾B<ÉáöfÙìK8­#Q1C-‘"eª·Ì«£Š°ð>¼'@
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e
new file mode 100755
index 0000000..83cc29f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/8e/b1e637ed9fc8e5454fa20d38f809091f9395f4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/8e/b1e637ed9fc8e5454fa20d38f809091f9395f4
new file mode 100755
index 0000000..8155b3e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/8e/b1e637ed9fc8e5454fa20d38f809091f9395f4
@@ -0,0 +1,2 @@
+xMM;
+1µÎ)Þ	ÁZPÐÞÆr²3kÉl²En¿ƒl!¼æýc±ˆóõrz§Üà ,¹º¡çe +ڝlEZxuPY…x QC³*ðf·uLácfR3ŠÍT0'Ò¯øjƒŠ°ð~G¦^s1Šèb2z’ƒÿùVkî]Ü5<·ûv¨'>ã
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5
new file mode 100755
index 0000000..55bda40
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/packed-refs
new file mode 100755
index 0000000..5a4ebc4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+480095882d281ed676fe5b863569520e54a7d5c0 refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/refs/heads/master
new file mode 100755
index 0000000..ae079bd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/refs/heads/master
@@ -0,0 +1 @@
+3d9386c507f6b093471a3e324085657a3c2b4247
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..6efe28f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_head/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/config
new file mode 100755
index 0000000..0274ff7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/config
@@ -0,0 +1,13 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	worktree = ../../../sm_changed_index
+	ignorecase = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = /Users/rb/src/libgit2/tests-clar/resources/submod2_target
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/index
new file mode 100755
index 0000000..6fad3b4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/logs/HEAD
new file mode 100755
index 0000000..80eb541
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560175 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/logs/refs/heads/master
new file mode 100755
index 0000000..80eb541
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560175 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/logs/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/logs/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..80eb541
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/logs/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560175 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1
new file mode 100755
index 0000000..f4b7094
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484
new file mode 100755
index 0000000..56c845e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5
new file mode 100755
index 0000000..bd179b5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/41/bd4bc3df978de695f67ace64c560913da11653 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/41/bd4bc3df978de695f67ace64c560913da11653
new file mode 100755
index 0000000..ccf49bd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/41/bd4bc3df978de695f67ace64c560913da11653 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/48/0095882d281ed676fe5b863569520e54a7d5c0
new file mode 100755
index 0000000..5302906
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/5e/4963595a9774b90524d35a807169049de8ccad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/5e/4963595a9774b90524d35a807169049de8ccad
new file mode 100755
index 0000000..38c791e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/5e/4963595a9774b90524d35a807169049de8ccad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/6b/31c659545507c381e9cd34ec508f16c04e149e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
new file mode 100755
index 0000000..a26d299
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
@@ -0,0 +1,2 @@
+x•Q
+!EûvoÅÓy*Ñ_¿í@Çg#h‚£ûOhý^Î9w«¥¤ÒêSoÌ€f1*²ŠÁ[”‰¬§èIc Ô¤ìê¤p£ïµÁkçΑ\›¿¿S߇¿lµÜ@.¤´^QpF‹(æ:ÿúDÿ5Åó“zr~	ñen8
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/73/ba924a80437097795ae839e66e187c55d3babf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/73/ba924a80437097795ae839e66e187c55d3babf
new file mode 100755
index 0000000..83d1ba4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/73/ba924a80437097795ae839e66e187c55d3babf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
new file mode 100755
index 0000000..6d27af8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
@@ -0,0 +1,2 @@
+x-Ë1Â0FaæžâßØ0pŽÀìÄÐ(N-ÅöÐÛÓ¡Ò“¾é±ãq]>ksÅ*š?	|m“‡Õçiª@ÛÖý¶¼m»¨V£…£'©î`)”.Ø-1¨x
+u„xãòt(+
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/78/9efbdadaa4a582778d4584385495559ea0994b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/78/9efbdadaa4a582778d4584385495559ea0994b
new file mode 100755
index 0000000..1745884
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/78/9efbdadaa4a582778d4584385495559ea0994b
@@ -0,0 +1,2 @@
+x
α
…0)ÞŠ?=
¥ÉÄNŠlO¤k®¸‹jÛúÿ¹8&„«¨ ãr
”
+ïqJWñ°7¾B<ÉáöfÙìK8­#Q1C-‘"eª·Ì«£Š°ð>¼'@
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e
new file mode 100755
index 0000000..83cc29f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/a0/2d31770687965547ab7a04cee199b29ee458d6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/a0/2d31770687965547ab7a04cee199b29ee458d6
new file mode 100755
index 0000000..cb3f5a0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/a0/2d31770687965547ab7a04cee199b29ee458d6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5
new file mode 100755
index 0000000..55bda40
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/packed-refs
new file mode 100755
index 0000000..5a4ebc4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+480095882d281ed676fe5b863569520e54a7d5c0 refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/refs/heads/master
new file mode 100755
index 0000000..e12c44d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/refs/heads/master
@@ -0,0 +1 @@
+480095882d281ed676fe5b863569520e54a7d5c0
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..6efe28f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_index/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/config
new file mode 100755
index 0000000..7f25844
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/config
@@ -0,0 +1,13 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	worktree = ../../../sm_changed_untracked_file
+	ignorecase = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = /Users/rb/src/libgit2/tests-clar/resources/submod2_target
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/index
new file mode 100755
index 0000000..598e30a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/logs/HEAD
new file mode 100755
index 0000000..d1beafb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560186 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/logs/refs/heads/master
new file mode 100755
index 0000000..d1beafb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560186 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/logs/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/logs/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..d1beafb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/logs/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560186 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1
new file mode 100755
index 0000000..f4b7094
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484
new file mode 100755
index 0000000..56c845e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5
new file mode 100755
index 0000000..bd179b5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/41/bd4bc3df978de695f67ace64c560913da11653 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/41/bd4bc3df978de695f67ace64c560913da11653
new file mode 100755
index 0000000..ccf49bd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/41/bd4bc3df978de695f67ace64c560913da11653 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/48/0095882d281ed676fe5b863569520e54a7d5c0
new file mode 100755
index 0000000..5302906
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/5e/4963595a9774b90524d35a807169049de8ccad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/5e/4963595a9774b90524d35a807169049de8ccad
new file mode 100755
index 0000000..38c791e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/5e/4963595a9774b90524d35a807169049de8ccad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/6b/31c659545507c381e9cd34ec508f16c04e149e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
new file mode 100755
index 0000000..a26d299
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
@@ -0,0 +1,2 @@
+x•Q
+!EûvoÅÓy*Ñ_¿í@Çg#h‚£ûOhý^Î9w«¥¤ÒêSoÌ€f1*²ŠÁ[”‰¬§èIc Ô¤ìê¤p£ïµÁkçΑ\›¿¿S߇¿lµÜ@.¤´^QpF‹(æ:ÿúDÿ5Åó“zr~	ñen8
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/73/ba924a80437097795ae839e66e187c55d3babf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/73/ba924a80437097795ae839e66e187c55d3babf
new file mode 100755
index 0000000..83d1ba4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/73/ba924a80437097795ae839e66e187c55d3babf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
new file mode 100755
index 0000000..6d27af8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
@@ -0,0 +1,2 @@
+x-Ë1Â0FaæžâßØ0pŽÀìÄÐ(N-ÅöÐÛÓ¡Ò“¾é±ãq]>ksÅ*š?	|m“‡Õçiª@ÛÖý¶¼m»¨V£…£'©î`)”.Ø-1¨x
+u„xãòt(+
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/78/9efbdadaa4a582778d4584385495559ea0994b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/78/9efbdadaa4a582778d4584385495559ea0994b
new file mode 100755
index 0000000..1745884
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/78/9efbdadaa4a582778d4584385495559ea0994b
@@ -0,0 +1,2 @@
+x
α
…0)ÞŠ?=
¥ÉÄNŠlO¤k®¸‹jÛúÿ¹8&„«¨ ãr
”
+ïqJWñ°7¾B<ÉáöfÙìK8­#Q1C-‘"eª·Ì«£Š°ð>¼'@
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e
new file mode 100755
index 0000000..83cc29f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5
new file mode 100755
index 0000000..55bda40
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/packed-refs
new file mode 100755
index 0000000..5a4ebc4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+480095882d281ed676fe5b863569520e54a7d5c0 refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/refs/heads/master
new file mode 100755
index 0000000..e12c44d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/refs/heads/master
@@ -0,0 +1 @@
+480095882d281ed676fe5b863569520e54a7d5c0
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..6efe28f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_changed_untracked_file/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/config
new file mode 100755
index 0000000..45fbb30
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/config
@@ -0,0 +1,13 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	worktree = ../../../sm_missing_commits
+	ignorecase = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = /Users/rb/src/libgit2/tests-clar/resources/submod2_target
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/index
new file mode 100755
index 0000000..4903565
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/logs/HEAD
new file mode 100755
index 0000000..ee08c97
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 5e4963595a9774b90524d35a807169049de8ccad Russell Belfer <rb at github.com> 1342559796 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/logs/refs/heads/master
new file mode 100755
index 0000000..ee08c97
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 5e4963595a9774b90524d35a807169049de8ccad Russell Belfer <rb at github.com> 1342559796 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/logs/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/logs/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..ee08c97
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/logs/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 5e4963595a9774b90524d35a807169049de8ccad Russell Belfer <rb at github.com> 1342559796 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1
new file mode 100755
index 0000000..f4b7094
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484
new file mode 100755
index 0000000..56c845e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5
new file mode 100755
index 0000000..bd179b5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/41/bd4bc3df978de695f67ace64c560913da11653 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/41/bd4bc3df978de695f67ace64c560913da11653
new file mode 100755
index 0000000..ccf49bd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/41/bd4bc3df978de695f67ace64c560913da11653 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/5e/4963595a9774b90524d35a807169049de8ccad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/5e/4963595a9774b90524d35a807169049de8ccad
new file mode 100755
index 0000000..38c791e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/5e/4963595a9774b90524d35a807169049de8ccad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/6b/31c659545507c381e9cd34ec508f16c04e149e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
new file mode 100755
index 0000000..a26d299
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
@@ -0,0 +1,2 @@
+x•Q
+!EûvoÅÓy*Ñ_¿í@Çg#h‚£ûOhý^Î9w«¥¤ÒêSoÌ€f1*²ŠÁ[”‰¬§èIc Ô¤ìê¤p£ïµÁkçΑ\›¿¿S߇¿lµÜ@.¤´^QpF‹(æ:ÿúDÿ5Åó“zr~	ñen8
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
new file mode 100755
index 0000000..6d27af8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
@@ -0,0 +1,2 @@
+x-Ë1Â0FaæžâßØ0pŽÀìÄÐ(N-ÅöÐÛÓ¡Ò“¾é±ãq]>ksÅ*š?	|m“‡Õçiª@ÛÖý¶¼m»¨V£…£'©î`)”.Ø-1¨x
+u„xãòt(+
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e
new file mode 100755
index 0000000..83cc29f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5
new file mode 100755
index 0000000..55bda40
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/packed-refs
new file mode 100755
index 0000000..66fbf5d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+5e4963595a9774b90524d35a807169049de8ccad refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/refs/heads/master
new file mode 100755
index 0000000..3913aca
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/refs/heads/master
@@ -0,0 +1 @@
+5e4963595a9774b90524d35a807169049de8ccad
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..6efe28f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_missing_commits/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/config
new file mode 100755
index 0000000..fc706c9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/config
@@ -0,0 +1,13 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	worktree = ../../../sm_unchanged
+	ignorecase = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = /Users/rb/src/libgit2/tests-clar/resources/submod2_target
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/index
new file mode 100755
index 0000000..629c849
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/logs/HEAD
new file mode 100755
index 0000000..7265328
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560169 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/logs/refs/heads/master
new file mode 100755
index 0000000..7265328
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560169 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/logs/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/logs/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..7265328
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/logs/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342560169 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1
new file mode 100755
index 0000000..f4b7094
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484
new file mode 100755
index 0000000..56c845e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5
new file mode 100755
index 0000000..bd179b5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/41/bd4bc3df978de695f67ace64c560913da11653 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/41/bd4bc3df978de695f67ace64c560913da11653
new file mode 100755
index 0000000..ccf49bd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/41/bd4bc3df978de695f67ace64c560913da11653 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/48/0095882d281ed676fe5b863569520e54a7d5c0
new file mode 100755
index 0000000..5302906
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/5e/4963595a9774b90524d35a807169049de8ccad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/5e/4963595a9774b90524d35a807169049de8ccad
new file mode 100755
index 0000000..38c791e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/5e/4963595a9774b90524d35a807169049de8ccad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/6b/31c659545507c381e9cd34ec508f16c04e149e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
new file mode 100755
index 0000000..a26d299
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
@@ -0,0 +1,2 @@
+x•Q
+!EûvoÅÓy*Ñ_¿í@Çg#h‚£ûOhý^Î9w«¥¤ÒêSoÌ€f1*²ŠÁ[”‰¬§èIc Ô¤ìê¤p£ïµÁkçΑ\›¿¿S߇¿lµÜ@.¤´^QpF‹(æ:ÿúDÿ5Åó“zr~	ñen8
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/73/ba924a80437097795ae839e66e187c55d3babf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/73/ba924a80437097795ae839e66e187c55d3babf
new file mode 100755
index 0000000..83d1ba4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/73/ba924a80437097795ae839e66e187c55d3babf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
new file mode 100755
index 0000000..6d27af8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
@@ -0,0 +1,2 @@
+x-Ë1Â0FaæžâßØ0pŽÀìÄÐ(N-ÅöÐÛÓ¡Ò“¾é±ãq]>ksÅ*š?	|m“‡Õçiª@ÛÖý¶¼m»¨V£…£'©î`)”.Ø-1¨x
+u„xãòt(+
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/78/9efbdadaa4a582778d4584385495559ea0994b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/78/9efbdadaa4a582778d4584385495559ea0994b
new file mode 100755
index 0000000..1745884
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/78/9efbdadaa4a582778d4584385495559ea0994b
@@ -0,0 +1,2 @@
+x
α
…0)ÞŠ?=
¥ÉÄNŠlO¤k®¸‹jÛúÿ¹8&„«¨ ãr
”
+ïqJWñ°7¾B<ÉáöfÙìK8­#Q1C-‘"eª·Ì«£Š°ð>¼'@
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e
new file mode 100755
index 0000000..83cc29f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5
new file mode 100755
index 0000000..55bda40
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/packed-refs
new file mode 100755
index 0000000..5a4ebc4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+480095882d281ed676fe5b863569520e54a7d5c0 refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/refs/heads/master
new file mode 100755
index 0000000..e12c44d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/refs/heads/master
@@ -0,0 +1 @@
+480095882d281ed676fe5b863569520e54a7d5c0
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..6efe28f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/modules/sm_unchanged/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/09/460e5b6cbcb05a3e404593c32a3aa7221eca0e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/09/460e5b6cbcb05a3e404593c32a3aa7221eca0e
new file mode 100755
index 0000000..f1ea5f4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/09/460e5b6cbcb05a3e404593c32a3aa7221eca0e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/14/fe9ccf104058df25e0a08361c4494e167ef243 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/14/fe9ccf104058df25e0a08361c4494e167ef243
new file mode 100755
index 0000000..d3c8582
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/14/fe9ccf104058df25e0a08361c4494e167ef243
@@ -0,0 +1 @@
+x•M F]sŠ¹€fh¡ccŒ;·Þ€ŸÁ’@I(Ü_OàöË{ïs%çØ@’>µÊ^!¹²F'½‘!諲l£_¼q4Íä´ÇE˜Þ¶RáݏƒS‚'§ÀnÕ>>±mÝ^\Éw³š´^‰$œ‘ÅXÇ_迦xí±E“à—_.à9}
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/22/ce3e0311dda73a5992d54a4a595518d3876ea7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/22/ce3e0311dda73a5992d54a4a595518d3876ea7
new file mode 100755
index 0000000..fce6a94
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/22/ce3e0311dda73a5992d54a4a595518d3876ea7
@@ -0,0 +1,4 @@
+xµË
+Â0Eݶ_Qº·.
+.üW"!1
æ!3	øù>+¶Š.¤Û9Ã=3Wº(«nÕ-¶”¥:;¨jòÜ["WÑ{›¨Þ•ÅQ¤¾ZWï°,2ºiviyh •“ÐT/‚=Ž{Ž‡ ¶!@b(¡bÎJcSËP¢¥rÅŒ
+è‡ð¡ã{ë`ì|%³imÐpú콡ÙÄ=ˆIÇÿW2›6‡„B@)|¼óÿ)g£ý™
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/25/5546424b0efb847b1bfc91dbf7348b277f8970 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/25/5546424b0efb847b1bfc91dbf7348b277f8970
new file mode 100755
index 0000000..2965bec
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/25/5546424b0efb847b1bfc91dbf7348b277f8970 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/2a/30f1e6f94b20917005a21273f65b406d0f8bad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/2a/30f1e6f94b20917005a21273f65b406d0f8bad
new file mode 100755
index 0000000..08faf0f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/2a/30f1e6f94b20917005a21273f65b406d0f8bad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/42/cfb95cd01bf9225b659b5ee3edcc78e8eeb478 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/42/cfb95cd01bf9225b659b5ee3edcc78e8eeb478
new file mode 100755
index 0000000..ee7848a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/42/cfb95cd01bf9225b659b5ee3edcc78e8eeb478 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/57/958699c2dc394f81cfc76950e9c3ac3025c398 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/57/958699c2dc394f81cfc76950e9c3ac3025c398
new file mode 100755
index 0000000..ca9203a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/57/958699c2dc394f81cfc76950e9c3ac3025c398 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/59/01da4f1c67756eeadc5121d206bec2431f253b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/59/01da4f1c67756eeadc5121d206bec2431f253b
new file mode 100755
index 0000000..9f88f6b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/59/01da4f1c67756eeadc5121d206bec2431f253b
@@ -0,0 +1,2 @@
+x•ŽÛ	1EýNÓ€2yg at D,A°€$;YöE6éßmÁß{΁›·e™(å/­2ƒõdƒ#ÊjÈšL	2—ìYdÊ:fÊž ˆ=V^D’hR	Ä$¥^ÃÅ©ÉaŠÆ+tn {ûnÞý8xžáÅsá
+÷šžãÔ¾=Ýò¶<@j£¬CÔ®èŹžÿÚ©þ[ŠÏ>Ä6­#=-ÛÐg?,¯FŒ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/60/7d96653d4d0a4f733107f7890c2e67b55b620d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/60/7d96653d4d0a4f733107f7890c2e67b55b620d
new file mode 100755
index 0000000..30bee40
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/60/7d96653d4d0a4f733107f7890c2e67b55b620d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/74/84482eb8db738cafa696993664607500a3f2b9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/74/84482eb8db738cafa696993664607500a3f2b9
new file mode 100755
index 0000000..7901804
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/74/84482eb8db738cafa696993664607500a3f2b9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/7b/a4c5c3561daa5ab1a86215cfb0587e96d404d6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/7b/a4c5c3561daa5ab1a86215cfb0587e96d404d6
new file mode 100755
index 0000000..cde89e5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/7b/a4c5c3561daa5ab1a86215cfb0587e96d404d6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/87/3585b94bdeabccea991ea5e3ec1a277895b698 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/87/3585b94bdeabccea991ea5e3ec1a277895b698
new file mode 100755
index 0000000..41af98a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/87/3585b94bdeabccea991ea5e3ec1a277895b698 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/97/4cf7c73de336b0c4e019f918f3cee367d72e84 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/97/4cf7c73de336b0c4e019f918f3cee367d72e84
new file mode 100755
index 0000000..160f1ca
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/97/4cf7c73de336b0c4e019f918f3cee367d72e84
@@ -0,0 +1,2 @@
+xµË
+Â0Eݶ_º·Bqåg¸	yŒi ™IÀÏ÷Y±Up!Ý΁s¸£|R¬ï7«=’)XCAGä¢:…à25‡º:É<°-û„uUÐ_IÛò‡¤Y¢…\Ϥ%êAFfª{Gß qTœPsï”u¹ã(ÓZ{‰RA
ô#ø̉£ó0m¾“Ų.8ïÞÑbáäìÇãÞù?{vÊŒ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/9d/bc299bc013ea253583b40bf327b5a6e4037b89 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/9d/bc299bc013ea253583b40bf327b5a6e4037b89
new file mode 100755
index 0000000..1ee5221
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/9d/bc299bc013ea253583b40bf327b5a6e4037b89 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/a9/104bf89e911387244ef499413960ba472066d9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/a9/104bf89e911387244ef499413960ba472066d9
new file mode 100755
index 0000000..2239e14
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/a9/104bf89e911387244ef499413960ba472066d9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/b6/14088620bbdc1d29549d223ceba0f4419fd4cb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/b6/14088620bbdc1d29549d223ceba0f4419fd4cb
new file mode 100755
index 0000000..a03ea66
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/b6/14088620bbdc1d29549d223ceba0f4419fd4cb differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/d4/07f19e50c1da1ff584beafe0d6dac7237c5d06 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/d4/07f19e50c1da1ff584beafe0d6dac7237c5d06
new file mode 100755
index 0000000..292303e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/d4/07f19e50c1da1ff584beafe0d6dac7237c5d06 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/d9/3e95571d92cceb5de28c205f1d5f3cc8b88bc8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/d9/3e95571d92cceb5de28c205f1d5f3cc8b88bc8
new file mode 100755
index 0000000..b92c7ee
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/d9/3e95571d92cceb5de28c205f1d5f3cc8b88bc8
@@ -0,0 +1,2 @@
+x•ÏÛ
+!€ánק}€
"‚.z’uRÉCx€}üΑہ¼øt¸
œ.׫Ù6î‚,iŸs&%ãÁ9“S¿#ݲ¦úIW¢=—a˜ßËf2A‹¼BYsÏñßНa{c±¶^K3g¼Äñ³wMÍ F˜Üúøߥ4sÅçâ€òÇáõÎ÷'Nê°I
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/e3/b83bf274ee065eee48734cf8c6dfaf5e81471c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/e3/b83bf274ee065eee48734cf8c6dfaf5e81471c
new file mode 100755
index 0000000..3c7750b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/e3/b83bf274ee065eee48734cf8c6dfaf5e81471c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/f5/4414c25e6d24fe39f5c3f128d7c8a17bc23833 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/f5/4414c25e6d24fe39f5c3f128d7c8a17bc23833
new file mode 100755
index 0000000..219620b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/f5/4414c25e6d24fe39f5c3f128d7c8a17bc23833
@@ -0,0 +1,2 @@
+xeÍÁ
+Â0„a¯íS„ÞíbOzð1<I	Iº¤¤‘Íû+ˆ‚õ:?|ãsõæt9îh¾Ô¥e6Š-	H[´¡–’ÃÜw§«¹šÿØwMò«Œ#½‘ɪ“ÈÚïж…Õm‘—_î; º$ž rò1éDÊPCvB¨Mcø‡ýI^
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/f9/90a25a74d1a8281ce2ab018ea8df66795cd60b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/f9/90a25a74d1a8281ce2ab018ea8df66795cd60b
new file mode 100755
index 0000000..883a40b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/objects/f9/90a25a74d1a8281ce2ab018ea8df66795cd60b
@@ -0,0 +1 @@
+xEŒA€ =óŠý„ÿáZ)¤RE¿/ñb2·É«1¶uÙsé˜xôÁ§Å¡—îˆä>ßä2<E™nG=2,ýÉœTÄ’’4©Žî4!¼N¬$`
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/refs/heads/master
new file mode 100755
index 0000000..d1d38aa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/.gitted/refs/heads/master
@@ -0,0 +1 @@
+7484482eb8db738cafa696993664607500a3f2b9
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/README.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/README.txt
new file mode 100755
index 0000000..f990a25
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/README.txt
@@ -0,0 +1,3 @@
+This is the submodule test data
+This repo will have a bunch of submodules in different states
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/gitmodules b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/gitmodules
new file mode 100755
index 0000000..4c31108
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/gitmodules
@@ -0,0 +1,24 @@
+[submodule "sm_missing_commits"]
+	path = sm_missing_commits
+	url = ../submod2_target
+[submodule "sm_unchanged"]
+	path = sm_unchanged
+	url = ../submod2_target
+[submodule "sm_changed_file"]
+	path = sm_changed_file
+	url = ../submod2_target
+[submodule "sm_changed_index"]
+	path = sm_changed_index
+	url = ../submod2_target
+[submodule "sm_changed_head"]
+	path = sm_changed_head
+	url = ../submod2_target
+[submodule "sm_changed_untracked_file"]
+	path = sm_changed_untracked_file
+	url = ../submod2_target
+[submodule "sm_added_and_uncommited"]
+	path = sm_added_and_uncommited
+	url = ../submod2_target
+[submodule "sm_gitmodules_only"]
+	path = sm_gitmodules_only
+	url = ../submod2_target
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/just_a_dir/contents b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/just_a_dir/contents
new file mode 100755
index 0000000..7ba4c5c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/just_a_dir/contents
@@ -0,0 +1 @@
+This is a file in a plain directory
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/just_a_file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/just_a_file
new file mode 100755
index 0000000..42cfb95
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/just_a_file
@@ -0,0 +1 @@
+This is just a plain file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/config
new file mode 100755
index 0000000..af10792
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/config
@@ -0,0 +1,6 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/index
new file mode 100755
index 0000000..f3fafa5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/logs/HEAD
new file mode 100755
index 0000000..1749e7d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 68e92c611b80ee1ed8f38314ff9577f0d15b2444 Russell Belfer <rb at github.com> 1342560358 -0700	commit (initial): Initial commit
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..1749e7d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 68e92c611b80ee1ed8f38314ff9577f0d15b2444 Russell Belfer <rb at github.com> 1342560358 -0700	commit (initial): Initial commit
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/objects/68/e92c611b80ee1ed8f38314ff9577f0d15b2444 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/objects/68/e92c611b80ee1ed8f38314ff9577f0d15b2444
new file mode 100755
index 0000000..8892531
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/objects/68/e92c611b80ee1ed8f38314ff9577f0d15b2444 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/objects/71/ff9927d7c8a5639e062c38a7d35c433c424627 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/objects/71/ff9927d7c8a5639e062c38a7d35c433c424627
new file mode 100755
index 0000000..c4e1a77
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/objects/71/ff9927d7c8a5639e062c38a7d35c433c424627 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/objects/f0/1d56b18efd353ef2bb93a4585d590a0847195e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/objects/f0/1d56b18efd353ef2bb93a4585d590a0847195e
new file mode 100755
index 0000000..e9f1942
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/objects/f0/1d56b18efd353ef2bb93a4585d590a0847195e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/refs/heads/master
new file mode 100755
index 0000000..0bd8514
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/.gitted/refs/heads/master
@@ -0,0 +1 @@
+68e92c611b80ee1ed8f38314ff9577f0d15b2444
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/README.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/README.txt
new file mode 100755
index 0000000..71ff992
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not-submodule/README.txt
@@ -0,0 +1 @@
+This is a git repo but not a submodule
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not/.gitted/notempty b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not/.gitted/notempty
new file mode 100755
index 0000000..9b33ac4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not/.gitted/notempty
@@ -0,0 +1 @@
+fooled you
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not/README.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not/README.txt
new file mode 100755
index 0000000..4f6935b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/not/README.txt
@@ -0,0 +1 @@
+what am I really
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_added_and_uncommited/.gitted b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_added_and_uncommited/.gitted
new file mode 100755
index 0000000..2b2a4cf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_added_and_uncommited/.gitted
@@ -0,0 +1 @@
+gitdir: ../.git/modules/sm_added_and_uncommited
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_added_and_uncommited/README.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_added_and_uncommited/README.txt
new file mode 100755
index 0000000..780d739
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_added_and_uncommited/README.txt
@@ -0,0 +1,3 @@
+This is the target for submod2 submodule links.
+Don't add commits casually because you make break tests.
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_added_and_uncommited/file_to_modify b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_added_and_uncommited/file_to_modify
new file mode 100755
index 0000000..789efbd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_added_and_uncommited/file_to_modify
@@ -0,0 +1,3 @@
+This is a file to modify in submodules
+It already has some history.
+You can add local changes as needed.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_file/.gitted b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_file/.gitted
new file mode 100755
index 0000000..dc98b16
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_file/.gitted
@@ -0,0 +1 @@
+gitdir: ../.git/modules/sm_changed_file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_file/README.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_file/README.txt
new file mode 100755
index 0000000..780d739
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_file/README.txt
@@ -0,0 +1,3 @@
+This is the target for submod2 submodule links.
+Don't add commits casually because you make break tests.
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_file/file_to_modify b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_file/file_to_modify
new file mode 100755
index 0000000..e5ba671
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_file/file_to_modify
@@ -0,0 +1,4 @@
+This is a file to modify in submodules
+It already has some history.
+You can add local changes as needed.
+In this case, the file is changed in the workdir
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_head/.gitted b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_head/.gitted
new file mode 100755
index 0000000..d5419b6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_head/.gitted
@@ -0,0 +1 @@
+gitdir: ../.git/modules/sm_changed_head
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_head/README.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_head/README.txt
new file mode 100755
index 0000000..780d739
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_head/README.txt
@@ -0,0 +1,3 @@
+This is the target for submod2 submodule links.
+Don't add commits casually because you make break tests.
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_head/file_to_modify b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_head/file_to_modify
new file mode 100755
index 0000000..8eb1e63
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_head/file_to_modify
@@ -0,0 +1,4 @@
+This is a file to modify in submodules
+It already has some history.
+You can add local changes as needed.
+This one has been changed and the change has been committed to HEAD.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_index/.gitted b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_index/.gitted
new file mode 100755
index 0000000..2c7a5b2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_index/.gitted
@@ -0,0 +1 @@
+gitdir: ../.git/modules/sm_changed_index
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_index/README.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_index/README.txt
new file mode 100755
index 0000000..780d739
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_index/README.txt
@@ -0,0 +1,3 @@
+This is the target for submod2 submodule links.
+Don't add commits casually because you make break tests.
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_index/file_to_modify b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_index/file_to_modify
new file mode 100755
index 0000000..a02d317
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_index/file_to_modify
@@ -0,0 +1,4 @@
+This is a file to modify in submodules
+It already has some history.
+You can add local changes as needed.
+Here the file is changed in the index and the workdir
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_untracked_file/.gitted b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_untracked_file/.gitted
new file mode 100755
index 0000000..9a10706
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_untracked_file/.gitted
@@ -0,0 +1 @@
+gitdir: ../.git/modules/sm_changed_untracked_file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_untracked_file/README.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_untracked_file/README.txt
new file mode 100755
index 0000000..780d739
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_untracked_file/README.txt
@@ -0,0 +1,3 @@
+This is the target for submod2 submodule links.
+Don't add commits casually because you make break tests.
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_untracked_file/file_to_modify b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_untracked_file/file_to_modify
new file mode 100755
index 0000000..789efbd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_untracked_file/file_to_modify
@@ -0,0 +1,3 @@
+This is a file to modify in submodules
+It already has some history.
+You can add local changes as needed.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_untracked_file/i_am_untracked b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_untracked_file/i_am_untracked
new file mode 100755
index 0000000..d2bae61
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_changed_untracked_file/i_am_untracked
@@ -0,0 +1 @@
+This file is untracked, but in a submodule
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_missing_commits/.gitted b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_missing_commits/.gitted
new file mode 100755
index 0000000..70193be
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_missing_commits/.gitted
@@ -0,0 +1 @@
+gitdir: ../.git/modules/sm_missing_commits
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_missing_commits/README.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_missing_commits/README.txt
new file mode 100755
index 0000000..780d739
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_missing_commits/README.txt
@@ -0,0 +1,3 @@
+This is the target for submod2 submodule links.
+Don't add commits casually because you make break tests.
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_missing_commits/file_to_modify b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_missing_commits/file_to_modify
new file mode 100755
index 0000000..8834b63
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_missing_commits/file_to_modify
@@ -0,0 +1,3 @@
+This is a file to modify in submodules
+It already has some history.
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_unchanged/.gitted b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_unchanged/.gitted
new file mode 100755
index 0000000..51a679c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_unchanged/.gitted
@@ -0,0 +1 @@
+gitdir: ../.git/modules/sm_unchanged
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_unchanged/README.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_unchanged/README.txt
new file mode 100755
index 0000000..780d739
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_unchanged/README.txt
@@ -0,0 +1,3 @@
+This is the target for submod2 submodule links.
+Don't add commits casually because you make break tests.
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_unchanged/file_to_modify b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_unchanged/file_to_modify
new file mode 100755
index 0000000..789efbd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2/sm_unchanged/file_to_modify
@@ -0,0 +1,3 @@
+This is a file to modify in submodules
+It already has some history.
+You can add local changes as needed.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/config
new file mode 100755
index 0000000..af10792
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/config
@@ -0,0 +1,6 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/index
new file mode 100755
index 0000000..eb3ff8c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/logs/HEAD
new file mode 100755
index 0000000..0ecd111
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/logs/HEAD
@@ -0,0 +1,4 @@
+0000000000000000000000000000000000000000 6b31c659545507c381e9cd34ec508f16c04e149e Russell Belfer <rb at github.com> 1342559662 -0700	commit (initial): Initial commit
+6b31c659545507c381e9cd34ec508f16c04e149e 41bd4bc3df978de695f67ace64c560913da11653 Russell Belfer <rb at github.com> 1342559709 -0700	commit: Adding test file
+41bd4bc3df978de695f67ace64c560913da11653 5e4963595a9774b90524d35a807169049de8ccad Russell Belfer <rb at github.com> 1342559726 -0700	commit: Updating test file
+5e4963595a9774b90524d35a807169049de8ccad 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342559925 -0700	commit: One more update
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..0ecd111
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/logs/refs/heads/master
@@ -0,0 +1,4 @@
+0000000000000000000000000000000000000000 6b31c659545507c381e9cd34ec508f16c04e149e Russell Belfer <rb at github.com> 1342559662 -0700	commit (initial): Initial commit
+6b31c659545507c381e9cd34ec508f16c04e149e 41bd4bc3df978de695f67ace64c560913da11653 Russell Belfer <rb at github.com> 1342559709 -0700	commit: Adding test file
+41bd4bc3df978de695f67ace64c560913da11653 5e4963595a9774b90524d35a807169049de8ccad Russell Belfer <rb at github.com> 1342559726 -0700	commit: Updating test file
+5e4963595a9774b90524d35a807169049de8ccad 480095882d281ed676fe5b863569520e54a7d5c0 Russell Belfer <rb at github.com> 1342559925 -0700	commit: One more update
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1
new file mode 100755
index 0000000..f4b7094
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484
new file mode 100755
index 0000000..56c845e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5
new file mode 100755
index 0000000..bd179b5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/41/bd4bc3df978de695f67ace64c560913da11653 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/41/bd4bc3df978de695f67ace64c560913da11653
new file mode 100755
index 0000000..ccf49bd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/41/bd4bc3df978de695f67ace64c560913da11653 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/48/0095882d281ed676fe5b863569520e54a7d5c0
new file mode 100755
index 0000000..5302906
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/5e/4963595a9774b90524d35a807169049de8ccad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/5e/4963595a9774b90524d35a807169049de8ccad
new file mode 100755
index 0000000..38c791e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/5e/4963595a9774b90524d35a807169049de8ccad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/6b/31c659545507c381e9cd34ec508f16c04e149e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
new file mode 100755
index 0000000..a26d299
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
@@ -0,0 +1,2 @@
+x•Q
+!EûvoÅÓy*Ñ_¿í@Çg#h‚£ûOhý^Î9w«¥¤ÒêSoÌ€f1*²ŠÁ[”‰¬§èIc Ô¤ìê¤p£ïµÁkçΑ\›¿¿S߇¿lµÜ@.¤´^QpF‹(æ:ÿúDÿ5Åó“zr~	ñen8
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/73/ba924a80437097795ae839e66e187c55d3babf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/73/ba924a80437097795ae839e66e187c55d3babf
new file mode 100755
index 0000000..83d1ba4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/73/ba924a80437097795ae839e66e187c55d3babf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
new file mode 100755
index 0000000..6d27af8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
@@ -0,0 +1,2 @@
+x-Ë1Â0FaæžâßØ0pŽÀìÄÐ(N-ÅöÐÛÓ¡Ò“¾é±ãq]>ksÅ*š?	|m“‡Õçiª@ÛÖý¶¼m»¨V£…£'©î`)”.Ø-1¨x
+u„xãòt(+
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/78/9efbdadaa4a582778d4584385495559ea0994b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/78/9efbdadaa4a582778d4584385495559ea0994b
new file mode 100755
index 0000000..1745884
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/78/9efbdadaa4a582778d4584385495559ea0994b
@@ -0,0 +1,2 @@
+x
α
…0)ÞŠ?=
¥ÉÄNŠlO¤k®¸‹jÛúÿ¹8&„«¨ ãr
”
+ïqJWñ°7¾B<ÉáöfÙìK8­#Q1C-‘"eª·Ì«£Š°ð>¼'@
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e
new file mode 100755
index 0000000..83cc29f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5
new file mode 100755
index 0000000..55bda40
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/refs/heads/master
new file mode 100755
index 0000000..e12c44d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/.gitted/refs/heads/master
@@ -0,0 +1 @@
+480095882d281ed676fe5b863569520e54a7d5c0
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/README.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/README.txt
new file mode 100755
index 0000000..780d739
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/README.txt
@@ -0,0 +1,3 @@
+This is the target for submod2 submodule links.
+Don't add commits casually because you make break tests.
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/file_to_modify b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/file_to_modify
new file mode 100755
index 0000000..789efbd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submod2_target/file_to_modify
@@ -0,0 +1,3 @@
+This is a file to modify in submodules
+It already has some history.
+You can add local changes as needed.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitmodules b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitmodules
new file mode 100755
index 0000000..03150b4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "testrepo"]
+	path = testrepo
+	url = ../testrepo.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/config
new file mode 100755
index 0000000..78387c5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/config
@@ -0,0 +1,8 @@
+[core]
+	repositoryformatversion = 0
+	filemode = false
+	bare = false
+	logallrefupdates = true
+	symlinks = false
+	ignorecase = true
+	hideDotFiles = dotGitOnly
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/index
new file mode 100755
index 0000000..6e22d7f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/objects/22/9cea838964f435d4fc2c11561ddb7447003609 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/objects/22/9cea838964f435d4fc2c11561ddb7447003609
new file mode 100755
index 0000000..9f0800d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/objects/22/9cea838964f435d4fc2c11561ddb7447003609 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/objects/5b/19f7523fbf55c96153ff5a94875583f1115a36 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/objects/5b/19f7523fbf55c96153ff5a94875583f1115a36
new file mode 100755
index 0000000..d0681ac
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/objects/5b/19f7523fbf55c96153ff5a94875583f1115a36 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/objects/a8/575e6aaececba78823993e4f11abbc6172aabd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/objects/a8/575e6aaececba78823993e4f11abbc6172aabd
new file mode 100755
index 0000000..b8961b0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/objects/a8/575e6aaececba78823993e4f11abbc6172aabd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/objects/b4/f28943fad380f4ee3a9c6b95259b28204cc25a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/objects/b4/f28943fad380f4ee3a9c6b95259b28204cc25a
new file mode 100755
index 0000000..653238c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/objects/b4/f28943fad380f4ee3a9c6b95259b28204cc25a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/objects/d6/9ff504a3ba631f2fdb35bff93cc8cb8e85f4f8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/objects/d6/9ff504a3ba631f2fdb35bff93cc8cb8e85f4f8
new file mode 100755
index 0000000..dabf65b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/objects/d6/9ff504a3ba631f2fdb35bff93cc8cb8e85f4f8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/packed-refs
new file mode 100755
index 0000000..0400126
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/packed-refs
@@ -0,0 +1,3 @@
+# pack-refs with: peeled fully-peeled 
+229cea838964f435d4fc2c11561ddb7447003609 refs/remotes/origin/alternate_1
+a8575e6aaececba78823993e4f11abbc6172aabd refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/refs/heads/alternate_1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/refs/heads/alternate_1
new file mode 100755
index 0000000..6f51966
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/refs/heads/alternate_1
@@ -0,0 +1 @@
+229cea838964f435d4fc2c11561ddb7447003609
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/refs/heads/master
new file mode 100755
index 0000000..f01cfb2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodule_simple/.gitted/refs/heads/master
@@ -0,0 +1 @@
+a8575e6aaececba78823993e4f11abbc6172aabd
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/config
new file mode 100755
index 0000000..af10792
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/config
@@ -0,0 +1,6 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/index
new file mode 100755
index 0000000..97bf8ef
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/info/exclude
new file mode 100755
index 0000000..dfc4115
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/info/exclude
@@ -0,0 +1,8 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
+ignored
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/info/refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/info/refs
new file mode 100755
index 0000000..ba17abd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/info/refs
@@ -0,0 +1 @@
+09176a980273d801a3e37cc45c84af1366501ed9	refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/logs/HEAD
new file mode 100755
index 0000000..87a7bda
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/logs/HEAD
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 09176a980273d801a3e37cc45c84af1366501ed9 Russell Belfer <arrbee at arrbee.com> 1332365253 -0700	commit (initial): initial commit
+09176a980273d801a3e37cc45c84af1366501ed9 97896810b3210244a62a82458b8e0819ecfc6850 Russell Belfer <arrbee at arrbee.com> 1332780781 -0700	commit: Setting up gitmodules
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..87a7bda
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/logs/refs/heads/master
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 09176a980273d801a3e37cc45c84af1366501ed9 Russell Belfer <arrbee at arrbee.com> 1332365253 -0700	commit (initial): initial commit
+09176a980273d801a3e37cc45c84af1366501ed9 97896810b3210244a62a82458b8e0819ecfc6850 Russell Belfer <arrbee at arrbee.com> 1332780781 -0700	commit: Setting up gitmodules
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/26/a3b32a9b7d97486c5557f5902e8ac94638145e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/26/a3b32a9b7d97486c5557f5902e8ac94638145e
new file mode 100755
index 0000000..2c3c2cb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/26/a3b32a9b7d97486c5557f5902e8ac94638145e
@@ -0,0 +1,2 @@
+x%‰=
+€0F]í)Š0à"ÃIŒ*•|Éý-t{?œ2ÇilV8¿ùô$±«Øm¡ýv»ãk­k*FDAÊ=(=|=6	¬DAv=ÛÍA}™&'…Oò$=
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/78/308c9251cf4eee8b25a76c7d2790c73d797357 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/78/308c9251cf4eee8b25a76c7d2790c73d797357
new file mode 100755
index 0000000..c85fb55
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/78/308c9251cf4eee8b25a76c7d2790c73d797357 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/97/896810b3210244a62a82458b8e0819ecfc6850 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/97/896810b3210244a62a82458b8e0819ecfc6850
new file mode 100755
index 0000000..1c8dbdf
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/97/896810b3210244a62a82458b8e0819ecfc6850
@@ -0,0 +1,3 @@
+xŽ[
+Â0EýÎ*fʤS“	ˆˆKФéú4Ý¿wà×…Ã9pÓ2MC¥FôP@ãÜu.„.¶pÚ!²OYáƒdiYUÍ'Ì•8XïbPn¼ôÊ6
+ħԞ“¶1[qîÌ}0q«ï¥Ðc[WŒ#Ý1fºÄR:àö›SZ¦+Y‘Æ+{µtdÏlvº¬»þOmž¨u˜_´}è5Ôié·«ù`	Kæ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/b6/0fd986699ba4e9e68bea07cf8e793f323ef888 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/b6/0fd986699ba4e9e68bea07cf8e793f323ef888
new file mode 100755
index 0000000..3d78bd6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/b6/0fd986699ba4e9e68bea07cf8e793f323ef888 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/d5/f7fc3f74f7dec08280f370a975b112e8f60818 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/d5/f7fc3f74f7dec08280f370a975b112e8f60818
new file mode 100755
index 0000000..6e0b49e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/d5/f7fc3f74f7dec08280f370a975b112e8f60818 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/e3/50052cc767cd1fcb37e84e9a89e701925be4ae b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/e3/50052cc767cd1fcb37e84e9a89e701925be4ae
new file mode 100755
index 0000000..082a589
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/e3/50052cc767cd1fcb37e84e9a89e701925be4ae differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/info/packs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/info/packs
new file mode 100755
index 0000000..0785ef6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/info/packs
@@ -0,0 +1,2 @@
+P pack-b69d04bb39ac274669e2184e45bd90015d02ef5b.pack
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/pack/pack-b69d04bb39ac274669e2184e45bd90015d02ef5b.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/pack/pack-b69d04bb39ac274669e2184e45bd90015d02ef5b.idx
new file mode 100755
index 0000000..810fc31
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/pack/pack-b69d04bb39ac274669e2184e45bd90015d02ef5b.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/pack/pack-b69d04bb39ac274669e2184e45bd90015d02ef5b.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/pack/pack-b69d04bb39ac274669e2184e45bd90015d02ef5b.pack
new file mode 100755
index 0000000..c25c4a7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/objects/pack/pack-b69d04bb39ac274669e2184e45bd90015d02ef5b.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/packed-refs
new file mode 100755
index 0000000..a645069
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+09176a980273d801a3e37cc45c84af1366501ed9 refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/refs/heads/master
new file mode 100755
index 0000000..32b9358
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/.gitted/refs/heads/master
@@ -0,0 +1 @@
+97896810b3210244a62a82458b8e0819ecfc6850
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/added b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/added
new file mode 100755
index 0000000..d5f7fc3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/added
@@ -0,0 +1 @@
+added
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/gitmodules b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/gitmodules
new file mode 100755
index 0000000..2798b69
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/gitmodules
@@ -0,0 +1,6 @@
+[submodule "testrepo"]
+	path = testrepo
+	url = 
+[submodule ""]
+	path = testrepo
+	url = 
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/ignored b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/ignored
new file mode 100755
index 0000000..092bfb9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/ignored
@@ -0,0 +1 @@
+yo
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/modified b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/modified
new file mode 100755
index 0000000..452216e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/modified
@@ -0,0 +1,2 @@
+changed
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/config
new file mode 100755
index 0000000..d6dcad1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/config
@@ -0,0 +1,12 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = /Users/rb/src/libgit2/tests/resources/testrepo.git
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/index
new file mode 100755
index 0000000..3eb8d84
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/logs/HEAD
new file mode 100755
index 0000000..147643a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 a65fedf39aefe402d3bb6e24df4d4f5fe4547750 Russell Belfer <arrbee at arrbee.com> 1332366307 -0700	clone: from /Users/rb/src/libgit2/tests/resources/testrepo.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..147643a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 a65fedf39aefe402d3bb6e24df4d4f5fe4547750 Russell Belfer <arrbee at arrbee.com> 1332366307 -0700	clone: from /Users/rb/src/libgit2/tests/resources/testrepo.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08
new file mode 100755
index 0000000..cedb2a2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7
new file mode 100755
index 0000000..93a16f1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd
new file mode 100755
index 0000000..ba0bfb3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b
new file mode 100755
index 0000000..225c457
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d
new file mode 100755
index 0000000..df40d99
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54
new file mode 100755
index 0000000..321eaa8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc
new file mode 100755
index 0000000..9bb5b62
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057
new file mode 100755
index 0000000..7ca4cee
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
new file mode 100755
index 0000000..8953b6c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
@@ -0,0 +1,2 @@
+xŽQ
+Â0DýÎ)öÊ6›Í¦ "xO°‰‰-ØFb¼¿EoàÏ0¼Ç¤º,ske×[ÎPn8R,EpD?±gŸ}Ê^3²âÙ<µåµGŽhYKÄèÒ8ЖDAÉ)¿ÉÈ;gôݧÚàšjïp™4ÕŽ¯ô-çû¢óãêr‚ÁŠ;°s°GA4Ûº=ìùÖ(ôin7øIÌKÍFE
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
new file mode 100755
index 0000000..c1f22c5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
@@ -0,0 +1,2 @@
+xŽÛ	1EýNi@™Ék2 "X‚$ÙYW0YcÿíÀ¿Ã…s¸¥ÕzïÚÚõMDÏ€0æœ8!¶†ÉÌÞs‰XŠªgÚdí::@X0»P¢wÙ"F/‰‰œÍRàˆUz÷¥múZZïú²¤ÒV}|•/œo5݇ÒêI£!¬1z Æ:vùÇUim}ê/¢>
+öF-
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a
new file mode 100755
index 0000000..2ef4faa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af
new file mode 100755
index 0000000..716b0c6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af
@@ -0,0 +1 @@
+xŽAj!³ö?0¨£ßÂ09Êo}HÚ6¨}ÿôjUPP©ÕZ&Yÿø˜ AÔ›±€pŒÁFdë¼÷pz[fŽYŒ½PÒqLJ.,Z§`™Å®Ð.ù`’vÙ³q
$Æ5+9çOëtœû>Û/úDE/龡W¯ï*e¿§VŸdf1>ð覭Öê²×äÄ›¹úÊ™F« ­ìTŽÙhœk.i¶^0Ô?P¼R,
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/7b/4384978d2493e851f9cca7858815fac9b10980 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/7b/4384978d2493e851f9cca7858815fac9b10980
new file mode 100755
index 0000000..23c462f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/7b/4384978d2493e851f9cca7858815fac9b10980 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d
new file mode 100755
index 0000000..2f9b6b6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479
new file mode 100755
index 0000000..5df58dd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162
new file mode 100755
index 0000000..4cc3f4d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162
@@ -0,0 +1 @@
+x+)JMU044b040031QrutñueX¡l¨ðmmA‹m›Ì£íJ}Gß;U‘T”˜—œŸ–™“ªWRQÂ`6ýš÷KÇ¥¶^/¾-*|òøWØ¥3P¥y©å`%ËEÛÞ±\&gŽÐ|Ÿ0§ÿ†{Ӎ1X
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4
new file mode 100755
index 0000000..bf7b2bb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
new file mode 100755
index 0000000..a796124
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
@@ -0,0 +1,3 @@
+xŽ[
+Â0EýÎ*fÊäÕ¤ "¸W0“‡-ØFâtÿ݁—çpS[–YÀ˜x^
+Díb	CLhutɉ}¥8X*4Zí¬sY½¨—UÀ‘AÃÖ
ÌX3‡R«Mµ¶) s6è¼¢M¦ÖážšÜ&Jm…ó;}Çõ±Ðü<¥¶\@›à‚ÑޏpÄ€¨vº?”ò«jÛºLð«¨Ø?Hå
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
new file mode 100755
index 0000000..f858869
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
@@ -0,0 +1,2 @@
+x;j1DëmdÓú·À˜ÇŽ|M«µ3`ŒV{>€³âQ¯ ¸·vL0I?Í!š4–Z=Ê! ×¦8²F¢Ã’!rÖsQßyÈ9]$DŽ&„l6AÇ>jFWüÒµIKNiûë§Z¢%¡SˆŒ‘
+‹Ò	­ÅʉøU~̽øä>'¼ï™û	¯wþ
×[ËÇ×÷öÚDGÚ¡±ðŒQ-ºMù«>dܶ‘OÞáÒò}í\à8g_ШÂoYr
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750
new file mode 100755
index 0000000..29c8e82
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750
@@ -0,0 +1,3 @@
+xŽQ
+!@ûösBQ"‚ŽÐ	ÆÙ±
rÍîßÒú{<xð¤·öàîƪ
+™HlJSer!ZPTe*Žj°UÝÑEo^¼ê2 (†ˆ¬XSÅ€ED‘ƒO<Y¦šj$2üs_á&}¸Î,}Ó[~p¹7~<ÒÛ:Ÿ	£°·ÉZ³Ùípè?­1_ûåC0
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd
new file mode 100755
index 0000000..d0d7e73
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6
new file mode 100755
index 0000000..18a7f61
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/ae/90f12eea699729ed24555e40b9fd669da12a12 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/ae/90f12eea699729ed24555e40b9fd669da12a12
new file mode 100755
index 0000000..d952546
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/ae/90f12eea699729ed24555e40b9fd669da12a12 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/b2/5fa35b38051e4ae45d4222e795f9df2e43f1d1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/b2/5fa35b38051e4ae45d4222e795f9df2e43f1d1
new file mode 100755
index 0000000..f460f25
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/b2/5fa35b38051e4ae45d4222e795f9df2e43f1d1
@@ -0,0 +1,2 @@
+xÌA
+Â0…a×9ÅìIÒ	™€ˆp'î§1Ñ¶‘v\x{cáýðVŸpƒvWûgŠ¾ÇŽ0xº[]"g†#{rDÆ
Cot ­äûN œU$­ò?9-p+1Í^¤ÀQx®¯Ï9O\ÆC¬Ó	Œm'D
{mµVêú(+´ñælè¶,Þ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593
new file mode 100755
index 0000000..f613670
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644
new file mode 100755
index 0000000..0817229
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644
@@ -0,0 +1,3 @@
+xKj1D³Ö)zçUBëÛ-0ÁuV9¦Õò<#£È÷ÏȲ+ŠW<Jú¶Ý&8Ê/s¨‚e‹µµÈ•KJ­«½S
+ØRvÌÁ{©æQ†îr«äY¹QN$H\Eµ²Íè=6áX5¦òÇK Fr)·(‰dC‡Î†”­–œ—jÊs®}À—ô9ác-Òw8Ëo¸\·r»¿IßÞÁ:
+l}F‚W$Ds´Ç£©ÿÙšOW…e”]V8-ÝÌÈ"U
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
new file mode 100755
index 0000000..75f541f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
@@ -0,0 +1,3 @@
+xŽQ
+Â0DýÎ)öʦ»I<‚'ØlR+˜Fj¼¿EoàÏ0<xÃh«õÞa Üõµ]È™­åXUlÞPF)Åz‘4yó”µ,\r	'SÂÄ-mI4
+‘Xhô”&òÌFÞ}n+\µõ—Y´-p|é·œoU¶z;-‘aÑlt{ØË?®I«,:ÃoÚR̳cHK
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f
new file mode 100755
index 0000000..a67d6e6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100755
index 0000000..7112238
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0
new file mode 100755
index 0000000..b135ecc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3
new file mode 100755
index 0000000..82e2790
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1
new file mode 100755
index 0000000..697c94c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92
new file mode 100755
index 0000000..112998d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765
new file mode 100755
index 0000000..12bf5f3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx
new file mode 100755
index 0000000..5068f28
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack
new file mode 100755
index 0000000..a6a1f30
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx
new file mode 100755
index 0000000..94c3c71
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack
new file mode 100755
index 0000000..74c7fe4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx
new file mode 100755
index 0000000..555cfa9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.pack
new file mode 100755
index 0000000..4d539ed
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/packed-refs
new file mode 100755
index 0000000..9c0433e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/packed-refs
@@ -0,0 +1,12 @@
+# pack-refs with: peeled 
+b25fa35b38051e4ae45d4222e795f9df2e43f1d1 refs/tags/test
+^e90810b8df3e80c413d903f631643c716887138d
+1385f264afb75a56a5bec74243be9b367ba4ca08 refs/tags/point_to_blob
+7b4384978d2493e851f9cca7858815fac9b10980 refs/tags/e90810b
+^e90810b8df3e80c413d903f631643c716887138d
+e90810b8df3e80c413d903f631643c716887138d refs/remotes/origin/test
+763d71aadf09a7951596c9746c024e7eece7c7af refs/remotes/origin/subtrees
+4a202b346bb0fb0db7eff3cffeb3c70babbd2045 refs/remotes/origin/packed-test
+41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9 refs/remotes/origin/packed
+a65fedf39aefe402d3bb6e24df4d4f5fe4547750 refs/remotes/origin/master
+a4a7dce85cf63874e984719f4fdd239f5145052f refs/remotes/origin/br2
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/refs/heads/master
new file mode 100755
index 0000000..3d8f0a4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/refs/heads/master
@@ -0,0 +1 @@
+a65fedf39aefe402d3bb6e24df4d4f5fe4547750
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..6efe28f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/.gitted/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/README b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/README
new file mode 100755
index 0000000..a823312
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/README
@@ -0,0 +1 @@
+hey there
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/branch_file.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/branch_file.txt
new file mode 100755
index 0000000..3697d64
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/branch_file.txt
@@ -0,0 +1,2 @@
+hi
+bye!
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/new.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/new.txt
new file mode 100755
index 0000000..a71586c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/testrepo/new.txt
@@ -0,0 +1 @@
+my new file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/unmodified b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/unmodified
new file mode 100755
index 0000000..092bfb9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/unmodified
@@ -0,0 +1 @@
+yo
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/untracked b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/untracked
new file mode 100755
index 0000000..092bfb9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/submodules/untracked
@@ -0,0 +1 @@
+yo
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/template/branches/.gitignore b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/template/branches/.gitignore
new file mode 100755
index 0000000..16868ce
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/template/branches/.gitignore
@@ -0,0 +1,2 @@
+# This file should not be copied, nor should the
+# containing directory, since it is effectively "empty"
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/template/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/template/description
new file mode 100755
index 0000000..ff04c4c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/template/description
@@ -0,0 +1 @@
+Edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/template/hooks/update.sample b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/template/hooks/update.sample
new file mode 100755
index 0000000..3b5f412
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/template/hooks/update.sample
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# A sample hook to make sure that the `git_repository_init_ext()` function
+# can correctly copy a hook over and set it up with the correct permissions.
+#
+# To enable a hook, you copy the file and remove the ".sample" suffix, but
+# in this case, we're just making sure it gets copied correctly.
+
+echo "$GIT_DIR"
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/template/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/template/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/template/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/FETCH_HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/FETCH_HEAD
new file mode 100755
index 0000000..4844626
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/FETCH_HEAD
@@ -0,0 +1,2 @@
+a65fedf39aefe402d3bb6e24df4d4f5fe4547750		branch 'master' of git://example.com/git/testrepo.git
+258f0e2a959a364e40ed6603d5d44fbb24765b10	not-for-merge  branch 'haacked' of git://example.com/git/testrepo.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/HEAD_TRACKER b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/HEAD_TRACKER
new file mode 100755
index 0000000..40d876b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/HEAD_TRACKER
@@ -0,0 +1 @@
+ref: HEAD
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/config
new file mode 100755
index 0000000..dfab4ee
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/config
@@ -0,0 +1,40 @@
+[core]
+        repositoryformatversion = 0
+        filemode = true
+        bare = true
+        logallrefupdates = true
+[remote "test"]
+	url = git://github.com/libgit2/libgit2
+	fetch = +refs/heads/*:refs/remotes/test/*
+[remote "joshaber"]
+	url = git://github.com/libgit2/libgit2
+[remote "empty-remote-url"]
+	url = 
+	pushurl =
+[remote "empty-remote-pushurl"]
+	pushurl =
+[remote "no-remote-url"]
+	fetch =
+[remote "test_with_pushurl"]
+	url = git://github.com/libgit2/fetchlibgit2
+	pushurl = git://github.com/libgit2/pushlibgit2
+	fetch = +refs/heads/*:refs/remotes/test_with_pushurl/*
+
+[branch "master"]
+   remote = test
+   merge = refs/heads/master
+[branch "track-local"]
+   remote = .
+   merge = refs/heads/master
+[branch "cannot-fetch"]
+   remote = joshaber
+   merge = refs/heads/cannot-fetch
+[branch "remoteless"]
+   remote =
+   merge = refs/heads/master
+[branch "mergeless"]
+   remote = test
+   merge = 
+[branch "mergeandremoteless"]
+   remote = 
+   merge = 
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/index
new file mode 100755
index 0000000..a27fb9c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/HEAD
new file mode 100755
index 0000000..9413b72
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/HEAD
@@ -0,0 +1,7 @@
+0000000000000000000000000000000000000000 be3563ae3f795b2b4353bcce3a527ad0a4f7f644 Ben Straub <bstraub at github.com> 1335806563 -0700	clone: from /Users/ben/src/libgit2/tests/resources/testrepo.git
+be3563ae3f795b2b4353bcce3a527ad0a4f7f644 a65fedf39aefe402d3bb6e24df4d4f5fe4547750 Ben Straub <bstraub at github.com> 1335806603 -0900	commit: 
+a65fedf39aefe402d3bb6e24df4d4f5fe4547750 5b5b025afb0b4c913b4c338a42934a3863bf3644 Ben Straub <bstraub at github.com> 1335806604 -0900	checkout: moving from master to 5b5b025
+5b5b025afb0b4c913b4c338a42934a3863bf3644 a65fedf39aefe402d3bb6e24df4d4f5fe4547750 Ben Straub <bstraub at github.com> 1335806605 -0900	checkout: moving from 5b5b025 to master
+a65fedf39aefe402d3bb6e24df4d4f5fe4547750 c47800c7266a2be04c571c04d5a6614691ea99bd Ben Straub <bstraub at github.com> 1335806608 -0900	checkout: moving from master to br2
+c47800c7266a2be04c571c04d5a6614691ea99bd a4a7dce85cf63874e984719f4fdd239f5145052f Ben Straub <bstraub at github.com> 1335806617 -0900	commit: checking in
+a4a7dce85cf63874e984719f4fdd239f5145052f a65fedf39aefe402d3bb6e24df4d4f5fe4547750 Ben Straub <bstraub at github.com> 1335806621 -0900	checkout: moving from br2 to master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/refs/heads/br2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/refs/heads/br2
new file mode 100755
index 0000000..4e27f6b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/refs/heads/br2
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 c47800c7266a2be04c571c04d5a6614691ea99bd Ben Straub <bstraub at github.com> 1335806608 -0700	branch: Created from refs/remotes/origin/br2
+a4a7dce85cf63874e984719f4fdd239f5145052f a4a7dce85cf63874e984719f4fdd239f5145052f Ben Straub <bstraub at github.com> 1335806617 -0700	commit: checking in
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/refs/heads/master
new file mode 100755
index 0000000..e1c729a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/refs/heads/master
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 be3563ae3f795b2b4353bcce3a527ad0a4f7f644 Ben Straub <bstraub at github.com> 1335806563 -0800	clone: from /Users/ben/src/libgit2/tests/resources/testrepo.git
+be3563ae3f795b2b4353bcce3a527ad0a4f7f644 a65fedf39aefe402d3bb6e24df4d4f5fe4547750 Ben Straub <bstraub at github.com> 1335806603 -0800	commit: checking in
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/refs/heads/not-good b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/refs/heads/not-good
new file mode 100755
index 0000000..bfbeacb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/refs/heads/not-good
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 a65fedf39aefe402d3bb6e24df4d4f5fe4547750 Ben Straub <bstraub at github.com> 1336761944 -0700	branch: Created from master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..f1aac6d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 be3563ae3f795b2b4353bcce3a527ad0a4f7f644 Ben Straub <bstraub at github.com> 1335806563 -0700	clone: from /Users/ben/src/libgit2/tests/resources/testrepo.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/refs/remotes/test/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/refs/remotes/test/master
new file mode 100755
index 0000000..8d49ba3
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/logs/refs/remotes/test/master
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 a65fedf39aefe402d3bb6e24df4d4f5fe4547750 Ben Straub <bstraub at github.com> 1335806565 -0800	update by push
+a65fedf39aefe402d3bb6e24df4d4f5fe4547750 be3563ae3f795b2b4353bcce3a527ad0a4f7f644 Ben Straub <bstraub at github.com> 1335806688 -0800	update by push
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/08/b041783f40edfe12bb406c9c9a8a040177c125 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/08/b041783f40edfe12bb406c9c9a8a040177c125
new file mode 100755
index 0000000..d1c032f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/08/b041783f40edfe12bb406c9c9a8a040177c125 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08
new file mode 100755
index 0000000..cedb2a2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/18/1037049a54a1eb5fab404658a3a250b44335d7
new file mode 100755
index 0000000..93a16f1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/18/10dff58d8a660512d4832e740f692884338ccd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/18/10dff58d8a660512d4832e740f692884338ccd
new file mode 100755
index 0000000..ba0bfb3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/18/10dff58d8a660512d4832e740f692884338ccd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/1a/443023183e3f2bfbef8ac923cd81c1018a18fd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/1a/443023183e3f2bfbef8ac923cd81c1018a18fd
new file mode 100755
index 0000000..3ec5412
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/1a/443023183e3f2bfbef8ac923cd81c1018a18fd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/1b/8cbad43e867676df601306689fe7c3def5e689 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/1b/8cbad43e867676df601306689fe7c3def5e689
new file mode 100755
index 0000000..6048d4b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/1b/8cbad43e867676df601306689fe7c3def5e689 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b
new file mode 100755
index 0000000..225c457
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/25/8f0e2a959a364e40ed6603d5d44fbb24765b10 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/25/8f0e2a959a364e40ed6603d5d44fbb24765b10
new file mode 100755
index 0000000..cb1ed57
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/25/8f0e2a959a364e40ed6603d5d44fbb24765b10 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d
new file mode 100755
index 0000000..df40d99
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/2d/59075e0681f540482d4f6223a68e0fef790bc7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/2d/59075e0681f540482d4f6223a68e0fef790bc7
new file mode 100755
index 0000000..0a1500a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/2d/59075e0681f540482d4f6223a68e0fef790bc7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54
new file mode 100755
index 0000000..321eaa8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc
new file mode 100755
index 0000000..9bb5b62
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057
new file mode 100755
index 0000000..7ca4cee
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
new file mode 100755
index 0000000..8953b6c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
@@ -0,0 +1,2 @@
+xŽQ
+Â0DýÎ)öÊ6›Í¦ "xO°‰‰-ØFb¼¿EoàÏ0¼Ç¤º,ske×[ÎPn8R,EpD?±gŸ}Ê^3²âÙ<µåµGŽhYKÄèÒ8ЖDAÉ)¿ÉÈ;gôݧÚàšjïp™4ÕŽ¯ô-çû¢óãêr‚ÁŠ;°s°GA4Ûº=ìùÖ(ôin7øIÌKÍFE
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/4a/23e2e65ad4e31c4c9db7dc746650bfad082679 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/4a/23e2e65ad4e31c4c9db7dc746650bfad082679
new file mode 100755
index 0000000..18e3964
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/4a/23e2e65ad4e31c4c9db7dc746650bfad082679 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/4b/22b35d44b5a4f589edf3dc89196399771796ea b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/4b/22b35d44b5a4f589edf3dc89196399771796ea
new file mode 100755
index 0000000..b4e5aa1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/4b/22b35d44b5a4f589edf3dc89196399771796ea differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/52/1d87c1ec3aef9824daf6d96cc0ae3710766d91 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/52/1d87c1ec3aef9824daf6d96cc0ae3710766d91
new file mode 100755
index 0000000..351cff8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/52/1d87c1ec3aef9824daf6d96cc0ae3710766d91 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
new file mode 100755
index 0000000..c1f22c5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
@@ -0,0 +1,2 @@
+xŽÛ	1EýNi@™Ék2 "X‚$ÙYW0YcÿíÀ¿Ã…s¸¥ÕzïÚÚõMDÏ€0æœ8!¶†ÉÌÞs‰XŠªgÚdí::@X0»P¢wÙ"F/‰‰œÍRàˆUz÷¥múZZïú²¤ÒV}|•/œo5݇ÒêI£!¬1z Æ:vùÇUim}ê/¢>
+öF-
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a
new file mode 100755
index 0000000..2ef4faa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af
new file mode 100755
index 0000000..716b0c6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af
@@ -0,0 +1 @@
+xŽAj!³ö?0¨£ßÂ09Êo}HÚ6¨}ÿôjUPP©ÕZ&Yÿø˜ AÔ›±€pŒÁFdë¼÷pz[fŽYŒ½PÒqLJ.,Z§`™Å®Ð.ù`’vÙ³q
$Æ5+9çOëtœû>Û/úDE/龡W¯ï*e¿§VŸdf1>ð覭Öê²×äÄ›¹úÊ™F« ­ìTŽÙhœk.i¶^0Ô?P¼R,
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/7b/4384978d2493e851f9cca7858815fac9b10980 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/7b/4384978d2493e851f9cca7858815fac9b10980
new file mode 100755
index 0000000..23c462f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/7b/4384978d2493e851f9cca7858815fac9b10980 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/81/4889a078c031f61ed08ab5fa863aea9314344d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/81/4889a078c031f61ed08ab5fa863aea9314344d
new file mode 100755
index 0000000..2f9b6b6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/81/4889a078c031f61ed08ab5fa863aea9314344d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/84/96071c1b46c854b31185ea97743be6a8774479 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/84/96071c1b46c854b31185ea97743be6a8774479
new file mode 100755
index 0000000..5df58dd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/84/96071c1b46c854b31185ea97743be6a8774479 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/84/9a5e34a26815e821f865b8479f5815a47af0fe b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/84/9a5e34a26815e821f865b8479f5815a47af0fe
new file mode 100755
index 0000000..71019a6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/84/9a5e34a26815e821f865b8479f5815a47af0fe
@@ -0,0 +1,2 @@
+xŒM F]sŠ¹€†Ÿ41ÆxÝ(­I‹ÁéÂÛKݽ/_ÞãP@¡ÚÕø¢!8›)es
+”	¥N&FGSÆ„¹hÑ{+ßCç‰÷ÆZzvØF¡7ZàÎ-¬Îñó‡k™x\ã¡[PÆ8ï´ôGØK/¥^©lÊ>.4
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162
new file mode 100755
index 0000000..4cc3f4d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162
@@ -0,0 +1 @@
+x+)JMU044b040031QrutñueX¡l¨ðmmA‹m›Ì£íJ}Gß;U‘T”˜—œŸ–™“ªWRQÂ`6ýš÷KÇ¥¶^/¾-*|òøWØ¥3P¥y©å`%ËEÛÞ±\&gŽÐ|Ÿ0§ÿ†{Ӎ1X
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4
new file mode 100755
index 0000000..bf7b2bb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/9f/13f7d0a9402c681f91dc590cf7b5470e6a77d2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/9f/13f7d0a9402c681f91dc590cf7b5470e6a77d2
new file mode 100755
index 0000000..7f1cfb2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/9f/13f7d0a9402c681f91dc590cf7b5470e6a77d2
@@ -0,0 +1,2 @@
+xŽM
+Â0F]ç³d2¤ñ®<A~&´`­ÄôþVàæãmïËë²ÌÈÒ¡7Uà$äJöL9yM!¢GuœªH¤&UÈæ›>;ÔÂÁ…¬£³X†ÂEÈŽ5R±£ ÛAÑE&n}ZÜæ<E}À=O[ÒÖáüÞéúÓ¼^À,ã^†#¢É¿ƒ]ÿPÍ`>™A¹
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
new file mode 100755
index 0000000..a796124
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
@@ -0,0 +1,3 @@
+xŽ[
+Â0EýÎ*fÊäÕ¤ "¸W0“‡-ØFâtÿ݁—çpS[–YÀ˜x^
+Díb	CLhutɉ}¥8X*4Zí¬sY½¨—UÀ‘AÃÖ
ÌX3‡R«Mµ¶) s6è¼¢M¦ÖážšÜ&Jm…ó;}Çõ±Ðü<¥¶\@›à‚ÑޏpÄ€¨vº?”ò«jÛºLð«¨Ø?Hå
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
new file mode 100755
index 0000000..f858869
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
@@ -0,0 +1,2 @@
+x;j1DëmdÓú·À˜ÇŽ|M«µ3`ŒV{>€³âQ¯ ¸·vL0I?Í!š4–Z=Ê! ×¦8²F¢Ã’!rÖsQßyÈ9]$DŽ&„l6AÇ>jFWüÒµIKNiûë§Z¢%¡SˆŒ‘
+‹Ò	­ÅʉøU~̽øä>'¼ï™û	¯wþ
×[ËÇ×÷öÚDGÚ¡±ðŒQ-ºMù«>dܶ‘OÞáÒò}í\à8g_ШÂoYr
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750
new file mode 100755
index 0000000..29c8e82
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750
@@ -0,0 +1,3 @@
+xŽQ
+!@ûösBQ"‚ŽÐ	ÆÙ±
rÍîßÒú{<xð¤·öàîƪ
+™HlJSer!ZPTe*Žj°UÝÑEo^¼ê2 (†ˆ¬XSÅ€ED‘ƒO<Y¦šj$2üs_á&}¸Î,}Ó[~p¹7~<ÒÛ:Ÿ	£°·ÉZ³Ùípè?­1_ûåC0
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd
new file mode 100755
index 0000000..d0d7e73
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6
new file mode 100755
index 0000000..18a7f61
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/ae/90f12eea699729ed24555e40b9fd669da12a12 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/ae/90f12eea699729ed24555e40b9fd669da12a12
new file mode 100755
index 0000000..d952546
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/ae/90f12eea699729ed24555e40b9fd669da12a12 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/b2/5fa35b38051e4ae45d4222e795f9df2e43f1d1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/b2/5fa35b38051e4ae45d4222e795f9df2e43f1d1
new file mode 100755
index 0000000..f460f25
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/b2/5fa35b38051e4ae45d4222e795f9df2e43f1d1
@@ -0,0 +1,2 @@
+xÌA
+Â0…a×9ÅìIÒ	™€ˆp'î§1Ñ¶‘v\x{cáýðVŸpƒvWûgŠ¾ÇŽ0xº[]"g†#{rDÆ
Cot ­äûN œU$­ò?9-p+1Í^¤ÀQx®¯Ï9O\ÆC¬Ó	Œm'D
{mµVêú(+´ñælè¶,Þ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593
new file mode 100755
index 0000000..f613670
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644
new file mode 100755
index 0000000..0817229
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644
@@ -0,0 +1,3 @@
+xKj1D³Ö)zçUBëÛ-0ÁuV9¦Õò<#£È÷ÏȲ+ŠW<Jú¶Ý&8Ê/s¨‚e‹µµÈ•KJ­«½S
+ØRvÌÁ{©æQ†îr«äY¹QN$H\Eµ²Íè=6áX5¦òÇK Fr)·(‰dC‡Î†”­–œ—jÊs®}À—ô9ác-Òw8Ëo¸\·r»¿IßÞÁ:
+l}F‚W$Ds´Ç£©ÿÙšOW…e”]V8-ÝÌÈ"U
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
new file mode 100755
index 0000000..75f541f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
@@ -0,0 +1,3 @@
+xŽQ
+Â0DýÎ)öʦ»I<‚'ØlR+˜Fj¼¿EoàÏ0<xÃh«õÞa Üõµ]È™­åXUlÞPF)Åz‘4yó”µ,\r	'SÂÄ-mI4
+‘Xhô”&òÌFÞ}n+\µõ—Y´-p|é·œoU¶z;-‘aÑlt{ØË?®I«,:ÃoÚR̳cHK
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/d0/7b0f9a8c89f1d9e74dc4fce6421dec5ef8a659 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/d0/7b0f9a8c89f1d9e74dc4fce6421dec5ef8a659
new file mode 100755
index 0000000..f3b46b3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/d0/7b0f9a8c89f1d9e74dc4fce6421dec5ef8a659 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f
new file mode 100755
index 0000000..a67d6e6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/d7/1aab4f9b04b45ce09bcaa636a9be6231474759 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/d7/1aab4f9b04b45ce09bcaa636a9be6231474759
new file mode 100755
index 0000000..2d47e6f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/d7/1aab4f9b04b45ce09bcaa636a9be6231474759 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100755
index 0000000..7112238
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0
new file mode 100755
index 0000000..b135ecc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3
new file mode 100755
index 0000000..82e2790
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1
new file mode 100755
index 0000000..697c94c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/fa/49b077972391ad58037050f2a75f74e3671e92
new file mode 100755
index 0000000..112998d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/fd/093bff70906175335656e6ce6ae05783708765 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/fd/093bff70906175335656e6ce6ae05783708765
new file mode 100755
index 0000000..12bf5f3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/fd/093bff70906175335656e6ce6ae05783708765 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/fd/4959ce7510db09d4d8217fa2d1780413e05a09 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/fd/4959ce7510db09d4d8217fa2d1780413e05a09
new file mode 100755
index 0000000..158aef2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/fd/4959ce7510db09d4d8217fa2d1780413e05a09 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx
new file mode 100755
index 0000000..5068f28
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack
new file mode 100755
index 0000000..a6a1f30
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx
new file mode 100755
index 0000000..94c3c71
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack
new file mode 100755
index 0000000..74c7fe4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx
new file mode 100755
index 0000000..555cfa9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.pack
new file mode 100755
index 0000000..4d539ed
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/packed-refs
new file mode 100755
index 0000000..52f5e87
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/packed-refs
@@ -0,0 +1,3 @@
+# pack-refs with: peeled 
+41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9 refs/heads/packed
+5b5b025afb0b4c913b4c338a42934a3863bf3644 refs/heads/packed-test
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/br2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/br2
new file mode 100755
index 0000000..aab87e5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/br2
@@ -0,0 +1 @@
+a4a7dce85cf63874e984719f4fdd239f5145052f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/cannot-fetch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/cannot-fetch
new file mode 100755
index 0000000..aab87e5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/cannot-fetch
@@ -0,0 +1 @@
+a4a7dce85cf63874e984719f4fdd239f5145052f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/chomped b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/chomped
new file mode 100755
index 0000000..0166a7f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/chomped
@@ -0,0 +1 @@
+e90810b8df3e80c413d903f631643c716887138d
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/haacked b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/haacked
new file mode 100755
index 0000000..17f5912
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/haacked
@@ -0,0 +1 @@
+258f0e2a959a364e40ed6603d5d44fbb24765b10
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/master
new file mode 100755
index 0000000..3d8f0a4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/master
@@ -0,0 +1 @@
+a65fedf39aefe402d3bb6e24df4d4f5fe4547750
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/not-good b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/not-good
new file mode 100755
index 0000000..3d8f0a4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/not-good
@@ -0,0 +1 @@
+a65fedf39aefe402d3bb6e24df4d4f5fe4547750
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/packed-test b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/packed-test
new file mode 100755
index 0000000..f2c14ad
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/packed-test
@@ -0,0 +1 @@
+4a202b346bb0fb0db7eff3cffeb3c70babbd2045
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/subtrees b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/subtrees
new file mode 100755
index 0000000..ad27e0b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/subtrees
@@ -0,0 +1 @@
+763d71aadf09a7951596c9746c024e7eece7c7af
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/test b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/test
new file mode 100755
index 0000000..399c4c7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/test
@@ -0,0 +1 @@
+e90810b8df3e80c413d903f631643c716887138d
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/track-local b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/track-local
new file mode 100755
index 0000000..f37febb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/track-local
@@ -0,0 +1 @@
+9fd738e8f7967c078dceed8190330fc8648ee56a
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/trailing b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/trailing
new file mode 100755
index 0000000..2a4a6e6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/heads/trailing
@@ -0,0 +1 @@
+e90810b8df3e80c413d903f631643c716887138d 
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/notes/fanout b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/notes/fanout
new file mode 100755
index 0000000..1f17036
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/notes/fanout
@@ -0,0 +1 @@
+d07b0f9a8c89f1d9e74dc4fce6421dec5ef8a659
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/remotes/test/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/remotes/test/master
new file mode 100755
index 0000000..9536ad8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/remotes/test/master
@@ -0,0 +1 @@
+be3563ae3f795b2b4353bcce3a527ad0a4f7f644
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/annotated_tag_to_blob b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/annotated_tag_to_blob
new file mode 100755
index 0000000..6c146d6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/annotated_tag_to_blob
@@ -0,0 +1 @@
+521d87c1ec3aef9824daf6d96cc0ae3710766d91
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/e90810b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/e90810b
new file mode 100755
index 0000000..584495d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/e90810b
@@ -0,0 +1 @@
+7b4384978d2493e851f9cca7858815fac9b10980
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/hard_tag b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/hard_tag
new file mode 100755
index 0000000..59ce656
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/hard_tag
@@ -0,0 +1 @@
+849a5e34a26815e821f865b8479f5815a47af0fe
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/point_to_blob b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/point_to_blob
new file mode 100755
index 0000000..f874a3f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/point_to_blob
@@ -0,0 +1 @@
+1385f264afb75a56a5bec74243be9b367ba4ca08
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/taggerless b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/taggerless
new file mode 100755
index 0000000..f960c7d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/taggerless
@@ -0,0 +1 @@
+4a23e2e65ad4e31c4c9db7dc746650bfad082679
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/test b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/test
new file mode 100755
index 0000000..6ee952a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/test
@@ -0,0 +1 @@
+b25fa35b38051e4ae45d4222e795f9df2e43f1d1
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/wrapped_tag b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/wrapped_tag
new file mode 100755
index 0000000..59ce656
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo.git/refs/tags/wrapped_tag
@@ -0,0 +1 @@
+849a5e34a26815e821f865b8479f5815a47af0fe
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/HEAD_TRACKER b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/HEAD_TRACKER
new file mode 100755
index 0000000..40d876b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/HEAD_TRACKER
@@ -0,0 +1 @@
+ref: HEAD
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/config
new file mode 100755
index 0000000..d011401
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/config
@@ -0,0 +1,8 @@
+[core]
+        repositoryformatversion = 0
+        filemode = true
+        bare = false
+        logallrefupdates = true
+[remote "test"]
+	url = git://github.com/libgit2/libgit2
+	fetch = +refs/heads/*:refs/remotes/test/*
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/index
new file mode 100755
index 0000000..a27fb9c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/09/9fabac3a9ea935598528c27f866e34089c2eff b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/09/9fabac3a9ea935598528c27f866e34089c2eff
new file mode 100755
index 0000000..c60c78f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/09/9fabac3a9ea935598528c27f866e34089c2eff
@@ -0,0 +1 @@
+xÎQ P¿9Å^@³ÂB!1F½‚'€î¢ÒJ?¼½Õ#ø7™ÉK¦ŸJhM›VE€,³·.3û¼§Þ¦ˆ‚ÔuVsHè-;õŠUÆÑÙ,œMˆ’…P³Iɉ&ÎĔ׍ìסŠK»O.2µո$8¤ùN·¡Ý—´ë§r„½!½l±CTk»lòUgfˆ0¿ËsêÓG(
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08
new file mode 100755
index 0000000..cedb2a2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/14/4344043ba4d4a405da03de3844aa829ae8be0e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/14/4344043ba4d4a405da03de3844aa829ae8be0e
new file mode 100755
index 0000000..b7d944f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/14/4344043ba4d4a405da03de3844aa829ae8be0e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/16/8e4ebd1c667499548ae12403b19b22a5c5e925 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/16/8e4ebd1c667499548ae12403b19b22a5c5e925
new file mode 100755
index 0000000..d37b93e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/16/8e4ebd1c667499548ae12403b19b22a5c5e925 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7
new file mode 100755
index 0000000..93a16f1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd
new file mode 100755
index 0000000..ba0bfb3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/1d/d0968be3ff95fcaecb6fa4245662db9fdc4568 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/1d/d0968be3ff95fcaecb6fa4245662db9fdc4568
new file mode 100755
index 0000000..97c6b2c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/1d/d0968be3ff95fcaecb6fa4245662db9fdc4568 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b
new file mode 100755
index 0000000..225c457
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d
new file mode 100755
index 0000000..df40d99
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/2b/d0a343aeef7a2cf0d158478966a6e587ff3863 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/2b/d0a343aeef7a2cf0d158478966a6e587ff3863
new file mode 100755
index 0000000..d10ca63
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/2b/d0a343aeef7a2cf0d158478966a6e587ff3863 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54
new file mode 100755
index 0000000..321eaa8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc
new file mode 100755
index 0000000..9bb5b62
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057
new file mode 100755
index 0000000..7ca4cee
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/45/dd856fdd4d89b884c340ba0e047752d9b085d6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/45/dd856fdd4d89b884c340ba0e047752d9b085d6
new file mode 100755
index 0000000..a83ed97
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/45/dd856fdd4d89b884c340ba0e047752d9b085d6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
new file mode 100755
index 0000000..8953b6c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
@@ -0,0 +1,2 @@
+xŽQ
+Â0DýÎ)öÊ6›Í¦ "xO°‰‰-ØFb¼¿EoàÏ0¼Ç¤º,ske×[ÎPn8R,EpD?±gŸ}Ê^3²âÙ<µåµGŽhYKÄèÒ8ЖDAÉ)¿ÉÈ;gôݧÚàšjïp™4ÕŽ¯ô-çû¢óãêr‚ÁŠ;°s°GA4Ûº=ìùÖ(ôin7øIÌKÍFE
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/4e/0883eeeeebc1fb1735161cea82f7cb5fab7e63 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/4e/0883eeeeebc1fb1735161cea82f7cb5fab7e63
new file mode 100755
index 0000000..e915021
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/4e/0883eeeeebc1fb1735161cea82f7cb5fab7e63 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/4e/886e602529caa9ab11d71f86634bd1b6e0de10 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/4e/886e602529caa9ab11d71f86634bd1b6e0de10
new file mode 100755
index 0000000..53168a0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/4e/886e602529caa9ab11d71f86634bd1b6e0de10 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
new file mode 100755
index 0000000..c1f22c5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
@@ -0,0 +1,2 @@
+xŽÛ	1EýNi@™Ék2 "X‚$ÙYW0YcÿíÀ¿Ã…s¸¥ÕzïÚÚõMDÏ€0æœ8!¶†ÉÌÞs‰XŠªgÚdí::@X0»P¢wÙ"F/‰‰œÍRàˆUz÷¥múZZïú²¤ÒV}|•/œo5݇ÒêI£!¬1z Æ:vùÇUim}ê/¢>
+öF-
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/62/eb56dabb4b9929bc15dd9263c2c733b13d2dcc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/62/eb56dabb4b9929bc15dd9263c2c733b13d2dcc
new file mode 100755
index 0000000..b669961
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/62/eb56dabb4b9929bc15dd9263c2c733b13d2dcc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/66/3adb09143767984f7be83a91effa47e128c735 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/66/3adb09143767984f7be83a91effa47e128c735
new file mode 100755
index 0000000..9ff5eb2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/66/3adb09143767984f7be83a91effa47e128c735 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/6b/377958d8c6a4906e8573b53672a1a23a4e8ce6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/6b/377958d8c6a4906e8573b53672a1a23a4e8ce6
new file mode 100755
index 0000000..ee7c781
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/6b/377958d8c6a4906e8573b53672a1a23a4e8ce6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/6b/9b767af9992b4abad5e24ffb1ba2d688ca602e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/6b/9b767af9992b4abad5e24ffb1ba2d688ca602e
new file mode 100755
index 0000000..197685b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/6b/9b767af9992b4abad5e24ffb1ba2d688ca602e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/6f/d5c7dd2ab27b48c493023f794be09861e9045f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/6f/d5c7dd2ab27b48c493023f794be09861e9045f
new file mode 100755
index 0000000..7f0c6fe
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/6f/d5c7dd2ab27b48c493023f794be09861e9045f
@@ -0,0 +1 @@
+x¥Aª!D³ö}GãŒ
á“Mr‚\ m[FãÇ1äú1gÈ¢ (¨G×Rr3ëCo"ÀvŽ^hq‘<7éÄAóY{žâ"Î&$ÄDýS“g˜([B!´Î¡wƳY’Ÿg±£ˆl$%E¯¾Ö·ø¦á±Ö²×'\d¤_w-™[Ýkê'®å¦³1hüµÓZtíòBÝó&;ô•:¼ó¶AÈñû"åm%ªþV
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a
new file mode 100755
index 0000000..2ef4faa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af
new file mode 100755
index 0000000..716b0c6
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af
@@ -0,0 +1 @@
+xŽAj!³ö?0¨£ßÂ09Êo}HÚ6¨}ÿôjUPP©ÕZ&Yÿø˜ AÔ›±€pŒÁFdë¼÷pz[fŽYŒ½PÒqLJ.,Z§`™Å®Ð.ù`’vÙ³q
$Æ5+9çOëtœû>Û/úDE/龡W¯ï*e¿§VŸdf1>ð覭Öê²×äÄ›¹úÊ™F« ­ìTŽÙhœk.i¶^0Ô?P¼R,
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/7b/2417a23b63e1fdde88c80e14b33247c6e5785a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/7b/2417a23b63e1fdde88c80e14b33247c6e5785a
new file mode 100755
index 0000000..db778aa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/7b/2417a23b63e1fdde88c80e14b33247c6e5785a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/7b/4384978d2493e851f9cca7858815fac9b10980 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/7b/4384978d2493e851f9cca7858815fac9b10980
new file mode 100755
index 0000000..23c462f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/7b/4384978d2493e851f9cca7858815fac9b10980 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d
new file mode 100755
index 0000000..2f9b6b6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479
new file mode 100755
index 0000000..5df58dd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/87/380ae84009e9c503506c2f6143a4fc6c60bf80 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/87/380ae84009e9c503506c2f6143a4fc6c60bf80
new file mode 100755
index 0000000..3042f57
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/87/380ae84009e9c503506c2f6143a4fc6c60bf80 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162
new file mode 100755
index 0000000..4cc3f4d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162
@@ -0,0 +1 @@
+x+)JMU044b040031QrutñueX¡l¨ðmmA‹m›Ì£íJ}Gß;U‘T”˜—œŸ–™“ªWRQÂ`6ýš÷KÇ¥¶^/¾-*|òøWØ¥3P¥y©å`%ËEÛÞ±\&gŽÐ|Ÿ0§ÿ†{Ӎ1X
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4
new file mode 100755
index 0000000..bf7b2bb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
new file mode 100755
index 0000000..a796124
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
@@ -0,0 +1,3 @@
+xŽ[
+Â0EýÎ*fÊäÕ¤ "¸W0“‡-ØFâtÿ݁—çpS[–YÀ˜x^
+Díb	CLhutɉ}¥8X*4Zí¬sY½¨—UÀ‘AÃÖ
ÌX3‡R«Mµ¶) s6è¼¢M¦ÖážšÜ&Jm…ó;}Çõ±Ðü<¥¶\@›à‚ÑޏpÄ€¨vº?”ò«jÛºLð«¨Ø?Hå
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
new file mode 100755
index 0000000..f858869
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
@@ -0,0 +1,2 @@
+x;j1DëmdÓú·À˜ÇŽ|M«µ3`ŒV{>€³âQ¯ ¸·vL0I?Í!š4–Z=Ê! ×¦8²F¢Ã’!rÖsQßyÈ9]$DŽ&„l6AÇ>jFWüÒµIKNiûë§Z¢%¡SˆŒ‘
+‹Ò	­ÅʉøU~̽øä>'¼ï™û	¯wþ
×[ËÇ×÷öÚDGÚ¡±ðŒQ-ºMù«>dܶ‘OÞáÒò}í\à8g_ШÂoYr
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750
new file mode 100755
index 0000000..29c8e82
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750
@@ -0,0 +1,3 @@
+xŽQ
+!@ûösBQ"‚ŽÐ	ÆÙ±
rÍîßÒú{<xð¤·öàîƪ
+™HlJSer!ZPTe*Žj°UÝÑEo^¼ê2 (†ˆ¬XSÅ€ED‘ƒO<Y¦šj$2üs_á&}¸Î,}Ó[~p¹7~<ÒÛ:Ÿ	£°·ÉZ³Ùípè?­1_ûåC0
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd
new file mode 100755
index 0000000..d0d7e73
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6
new file mode 100755
index 0000000..18a7f61
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/ae/90f12eea699729ed24555e40b9fd669da12a12 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/ae/90f12eea699729ed24555e40b9fd669da12a12
new file mode 100755
index 0000000..d952546
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/ae/90f12eea699729ed24555e40b9fd669da12a12 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/af/e4393b2b2a965f06acf2ca9658eaa01e0cd6b6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/af/e4393b2b2a965f06acf2ca9658eaa01e0cd6b6
new file mode 100755
index 0000000..6948f1b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/af/e4393b2b2a965f06acf2ca9658eaa01e0cd6b6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/b2/5fa35b38051e4ae45d4222e795f9df2e43f1d1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/b2/5fa35b38051e4ae45d4222e795f9df2e43f1d1
new file mode 100755
index 0000000..f460f25
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/b2/5fa35b38051e4ae45d4222e795f9df2e43f1d1
@@ -0,0 +1,2 @@
+xÌA
+Â0…a×9ÅìIÒ	™€ˆp'î§1Ñ¶‘v\x{cáýðVŸpƒvWûgŠ¾ÇŽ0xº[]"g†#{rDÆ
Cot ­äûN œU$­ò?9-p+1Í^¤ÀQx®¯Ï9O\ÆC¬Ó	Œm'D
{mµVêú(+´ñælè¶,Þ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593
new file mode 100755
index 0000000..f613670
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644
new file mode 100755
index 0000000..0817229
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644
@@ -0,0 +1,3 @@
+xKj1D³Ö)zçUBëÛ-0ÁuV9¦Õò<#£È÷ÏȲ+ŠW<Jú¶Ý&8Ê/s¨‚e‹µµÈ•KJ­«½S
+ØRvÌÁ{©æQ†îr«äY¹QN$H\Eµ²Íè=6áX5¦òÇK Fr)·(‰dC‡Î†”­–œ—jÊs®}À—ô9ác-Òw8Ëo¸\·r»¿IßÞÁ:
+l}F‚W$Ds´Ç£©ÿÙšOW…e”]V8-ÝÌÈ"U
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/c0/528fd6cc988c0a40ce0be11bc192fc8dc5346e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/c0/528fd6cc988c0a40ce0be11bc192fc8dc5346e
new file mode 100755
index 0000000..0401ab4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/c0/528fd6cc988c0a40ce0be11bc192fc8dc5346e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/c3/6d8ea75da8cb510fcb0c408c1d7e53f9a99dbe b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/c3/6d8ea75da8cb510fcb0c408c1d7e53f9a99dbe
new file mode 100755
index 0000000..0975f7f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/c3/6d8ea75da8cb510fcb0c408c1d7e53f9a99dbe differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
new file mode 100755
index 0000000..75f541f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
@@ -0,0 +1,3 @@
+xŽQ
+Â0DýÎ)öʦ»I<‚'ØlR+˜Fj¼¿EoàÏ0<xÃh«õÞa Üõµ]È™­åXUlÞPF)Åz‘4yó”µ,\r	'SÂÄ-mI4
+‘Xhô”&òÌFÞ}n+\µõ—Y´-p|é·œoU¶z;-‘aÑlt{ØË?®I«,:ÃoÚR̳cHK
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/ce/054d4c5e3c83522aed8bc061987b46b7ede3be b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/ce/054d4c5e3c83522aed8bc061987b46b7ede3be
new file mode 100755
index 0000000..4910e4c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/ce/054d4c5e3c83522aed8bc061987b46b7ede3be differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/cf/80f8de9f1185bf3a05f993f6121880dd0cfbc9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/cf/80f8de9f1185bf3a05f993f6121880dd0cfbc9
new file mode 100755
index 0000000..7620c51
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/cf/80f8de9f1185bf3a05f993f6121880dd0cfbc9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/d4/27e0b2e138501a3d15cc376077a3631e15bd46 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/d4/27e0b2e138501a3d15cc376077a3631e15bd46
new file mode 100755
index 0000000..0b3611a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/d4/27e0b2e138501a3d15cc376077a3631e15bd46 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/d5/2a8fe84ceedf260afe4f0287bbfca04a117e83 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/d5/2a8fe84ceedf260afe4f0287bbfca04a117e83
new file mode 100755
index 0000000..00940f0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/d5/2a8fe84ceedf260afe4f0287bbfca04a117e83 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f
new file mode 100755
index 0000000..a67d6e6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/e3/6900c3224db4adf4c7f7a09d4ac80247978a13 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/e3/6900c3224db4adf4c7f7a09d4ac80247978a13
new file mode 100755
index 0000000..e74291f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/e3/6900c3224db4adf4c7f7a09d4ac80247978a13 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100755
index 0000000..7112238
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0
new file mode 100755
index 0000000..b135ecc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3
new file mode 100755
index 0000000..82e2790
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1
new file mode 100755
index 0000000..697c94c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92
new file mode 100755
index 0000000..112998d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765
new file mode 100755
index 0000000..12bf5f3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx
new file mode 100755
index 0000000..5068f28
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack
new file mode 100755
index 0000000..a6a1f30
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx
new file mode 100755
index 0000000..94c3c71
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack
new file mode 100755
index 0000000..74c7fe4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx
new file mode 100755
index 0000000..555cfa9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.pack
new file mode 100755
index 0000000..4d539ed
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/objects/pack/pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/packed-refs
new file mode 100755
index 0000000..6018a19
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/packed-refs
@@ -0,0 +1,4 @@
+# pack-refs with: peeled 
+41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9 refs/heads/packed
+5b5b025afb0b4c913b4c338a42934a3863bf3644 refs/heads/packed-test
+b25fa35b38051e4ae45d4222e795f9df2e43f1d1 refs/tags/packed-tag
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/br2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/br2
new file mode 100755
index 0000000..aab87e5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/br2
@@ -0,0 +1 @@
+a4a7dce85cf63874e984719f4fdd239f5145052f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/dir b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/dir
new file mode 100755
index 0000000..4567d37
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/dir
@@ -0,0 +1 @@
+144344043ba4d4a405da03de3844aa829ae8be0e
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/ident b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/ident
new file mode 100755
index 0000000..2cfd880
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/ident
@@ -0,0 +1 @@
+6fd5c7dd2ab27b48c493023f794be09861e9045f
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/long-file-name b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/long-file-name
new file mode 100755
index 0000000..1f942a7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/long-file-name
@@ -0,0 +1 @@
+6b377958d8c6a4906e8573b53672a1a23a4e8ce6
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/master
new file mode 100755
index 0000000..f31fe78
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/master
@@ -0,0 +1 @@
+099fabac3a9ea935598528c27f866e34089c2eff
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/packed-test b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/packed-test
new file mode 100755
index 0000000..f2c14ad
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/packed-test
@@ -0,0 +1 @@
+4a202b346bb0fb0db7eff3cffeb3c70babbd2045
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/subtrees b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/subtrees
new file mode 100755
index 0000000..ad27e0b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/subtrees
@@ -0,0 +1 @@
+763d71aadf09a7951596c9746c024e7eece7c7af
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/test b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/test
new file mode 100755
index 0000000..399c4c7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/heads/test
@@ -0,0 +1 @@
+e90810b8df3e80c413d903f631643c716887138d
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/tags/e90810b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/tags/e90810b
new file mode 100755
index 0000000..584495d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/tags/e90810b
@@ -0,0 +1 @@
+7b4384978d2493e851f9cca7858815fac9b10980
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/tags/foo/bar b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/tags/foo/bar
new file mode 100755
index 0000000..6ee952a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/tags/foo/bar
@@ -0,0 +1 @@
+b25fa35b38051e4ae45d4222e795f9df2e43f1d1
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/tags/foo/foo/bar b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/tags/foo/foo/bar
new file mode 100755
index 0000000..6ee952a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/tags/foo/foo/bar
@@ -0,0 +1 @@
+b25fa35b38051e4ae45d4222e795f9df2e43f1d1
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/tags/point_to_blob b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/tags/point_to_blob
new file mode 100755
index 0000000..f874a3f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/tags/point_to_blob
@@ -0,0 +1 @@
+1385f264afb75a56a5bec74243be9b367ba4ca08
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/tags/test b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/tags/test
new file mode 100755
index 0000000..6ee952a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo/.gitted/refs/tags/test
@@ -0,0 +1 @@
+b25fa35b38051e4ae45d4222e795f9df2e43f1d1
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/config
new file mode 100755
index 0000000..4af067f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/config
@@ -0,0 +1,26 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
+	precomposeunicode = false
+[remote "origin"]
+	url = https://github.com/libgit2/false.git
+	fetch = +refs/heads/*:refs/remotes/origin/*
+[remote "insteadof-test"]
+	url = http://example.com/libgit2/libgit2
+	pushurl = http://github.com/libgit2/libgit2
+	fetch = +refs/heads/*:refs/remotes/test/*
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
+	rebase = true
+[url "longer-non-prefix-match"]
+	insteadOf = ttp://example.com/li
+[url "shorter-prefix"]
+	insteadOf = http://example.co
+[url "http://github.com"]
+	insteadOf = http://example.com
+[url "git at github.com:"]
+	pushInsteadOf = http://github.com/
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/index
new file mode 100755
index 0000000..b614d07
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/logs/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/logs/HEAD
new file mode 100755
index 0000000..4e80c69
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 36060c58702ed4c2a40832c51758d5344201d89a Russell Belfer <rb at github.com> 1368278260 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/../../../rugged/test/fixtures/testrepo.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/logs/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/logs/refs/heads/master
new file mode 100755
index 0000000..4e80c69
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 36060c58702ed4c2a40832c51758d5344201d89a Russell Belfer <rb at github.com> 1368278260 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/../../../rugged/test/fixtures/testrepo.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/logs/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/logs/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..4e80c69
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/logs/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 36060c58702ed4c2a40832c51758d5344201d89a Russell Belfer <rb at github.com> 1368278260 -0700	clone: from /Users/rb/src/libgit2/tests-clar/resources/../../../rugged/test/fixtures/testrepo.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/0c/37a5391bbff43c37f0d0371823a5509eed5b1d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/0c/37a5391bbff43c37f0d0371823a5509eed5b1d
new file mode 100755
index 0000000..bfe146a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/0c/37a5391bbff43c37f0d0371823a5509eed5b1d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08
new file mode 100755
index 0000000..cedb2a2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7
new file mode 100755
index 0000000..93a16f1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd
new file mode 100755
index 0000000..ba0bfb3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2
new file mode 100755
index 0000000..3cd240d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/36/060c58702ed4c2a40832c51758d5344201d89a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/36/060c58702ed4c2a40832c51758d5344201d89a
new file mode 100755
index 0000000..0c62460
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/36/060c58702ed4c2a40832c51758d5344201d89a
@@ -0,0 +1,2 @@
+xŽQ
+Â0ýÎ)re“Ý´
ˆÁ$Û­-˜FÒíý-ÁŸÇ00𸖲¨õ¾?i±L#»‚ÐHSŽŒS×#qÏ2²DÈæ“š¬jC|HS†L‹8$ò)áÐaž°#2i×¹6ûäªjsâºÚëÆ?¸¿JZÞ®åfçtΞÁ˜ÃUþiͶçqiÂZÛ"›ù_/H6
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057
new file mode 100755
index 0000000..7ca4cee
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
new file mode 100755
index 0000000..8953b6c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
@@ -0,0 +1,2 @@
+xŽQ
+Â0DýÎ)öÊ6›Í¦ "xO°‰‰-ØFb¼¿EoàÏ0¼Ç¤º,ske×[ÎPn8R,EpD?±gŸ}Ê^3²âÙ<µåµGŽhYKÄèÒ8ЖDAÉ)¿ÉÈ;gôݧÚàšjïp™4ÕŽ¯ô-çû¢óãêr‚ÁŠ;°s°GA4Ûº=ìùÖ(ôin7øIÌKÍFE
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
new file mode 100755
index 0000000..c1f22c5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
@@ -0,0 +1,2 @@
+xŽÛ	1EýNi@™Ék2 "X‚$ÙYW0YcÿíÀ¿Ã…s¸¥ÕzïÚÚõMDÏ€0æœ8!¶†ÉÌÞs‰XŠªgÚdí::@X0»P¢wÙ"F/‰‰œÍRàˆUz÷¥múZZïú²¤ÒV}|•/œo5݇ÒêI£!¬1z Æ:vùÇUim}ê/¢>
+öF-
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/61/9f9935957e010c419cb9d15621916ddfcc0b96 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/61/9f9935957e010c419cb9d15621916ddfcc0b96
new file mode 100755
index 0000000..1fd79b4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/61/9f9935957e010c419cb9d15621916ddfcc0b96 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a
new file mode 100755
index 0000000..2ef4faa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0
new file mode 100755
index 0000000..3d1016d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d
new file mode 100755
index 0000000..2f9b6b6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479
new file mode 100755
index 0000000..5df58dd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
new file mode 100755
index 0000000..a796124
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
@@ -0,0 +1,3 @@
+xŽ[
+Â0EýÎ*fÊäÕ¤ "¸W0“‡-ØFâtÿ݁—çpS[–YÀ˜x^
+Díb	CLhutɉ}¥8X*4Zí¬sY½¨—UÀ‘AÃÖ
ÌX3‡R«Mµ¶) s6è¼¢M¦ÖážšÜ&Jm…ó;}Çõ±Ðü<¥¶\@›à‚ÑޏpÄ€¨vº?”ò«jÛºLð«¨Ø?Hå
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
new file mode 100755
index 0000000..f858869
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
@@ -0,0 +1,2 @@
+x;j1DëmdÓú·À˜ÇŽ|M«µ3`ŒV{>€³âQ¯ ¸·vL0I?Í!š4–Z=Ê! ×¦8²F¢Ã’!rÖsQßyÈ9]$DŽ&„l6AÇ>jFWüÒµIKNiûë§Z¢%¡SˆŒ‘
+‹Ò	­ÅʉøU~̽øä>'¼ï™û	¯wþ
×[ËÇ×÷öÚDGÚ¡±ðŒQ-ºMù«>dܶ‘OÞáÒò}í\à8g_ШÂoYr
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd
new file mode 100755
index 0000000..d0d7e73
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6
new file mode 100755
index 0000000..18a7f61
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644
new file mode 100755
index 0000000..0817229
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644
@@ -0,0 +1,3 @@
+xKj1D³Ö)zçUBëÛ-0ÁuV9¦Õò<#£È÷ÏȲ+ŠW<Jú¶Ý&8Ê/s¨‚e‹µµÈ•KJ­«½S
+ØRvÌÁ{©æQ†îr«äY¹QN$H\Eµ²Íè=6áX5¦òÇK Fr)·(‰dC‡Î†”­–œ—jÊs®}À—ô9ác-Òw8Ëo¸\·r»¿IßÞÁ:
+l}F‚W$Ds´Ç£©ÿÙšOW…e”]V8-ÝÌÈ"U
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
new file mode 100755
index 0000000..75f541f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
@@ -0,0 +1,3 @@
+xŽQ
+Â0DýÎ)öʦ»I<‚'ØlR+˜Fj¼¿EoàÏ0<xÃh«õÞa Üõµ]È™­åXUlÞPF)Åz‘4yó”µ,\r	'SÂÄ-mI4
+‘Xhô”&òÌFÞ}n+\µõ—Y´-p|é·œoU¶z;-‘aÑlt{ØË?®I«,:ÃoÚR̳cHK
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/c4/dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/c4/dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b
new file mode 100755
index 0000000..599e160
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/c4/dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100755
index 0000000..7112238
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1
new file mode 100755
index 0000000..0377096
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92
new file mode 100755
index 0000000..112998d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765
new file mode 100755
index 0000000..12bf5f3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx
new file mode 100755
index 0000000..94c3c71
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack
new file mode 100755
index 0000000..74c7fe4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/packed-refs
new file mode 100755
index 0000000..97ea6a8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/packed-refs
@@ -0,0 +1,6 @@
+# pack-refs with: peeled fully-peeled 
+36060c58702ed4c2a40832c51758d5344201d89a refs/remotes/origin/master
+41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9 refs/remotes/origin/packed
+5b5b025afb0b4c913b4c338a42934a3863bf3644 refs/tags/v0.9
+0c37a5391bbff43c37f0d0371823a5509eed5b1d refs/tags/v1.0
+^5b5b025afb0b4c913b4c338a42934a3863bf3644
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/refs/heads/master
new file mode 100755
index 0000000..a7eafce
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/refs/heads/master
@@ -0,0 +1 @@
+36060c58702ed4c2a40832c51758d5344201d89a
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..6efe28f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/.gitted/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/README b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/README
new file mode 100755
index 0000000..1385f26
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/README
@@ -0,0 +1 @@
+hey
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/new.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/new.txt
new file mode 100755
index 0000000..fa49b07
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/new.txt
@@ -0,0 +1 @@
+new file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/subdir/README b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/subdir/README
new file mode 100755
index 0000000..1385f26
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/subdir/README
@@ -0,0 +1 @@
+hey
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/subdir/new.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/subdir/new.txt
new file mode 100755
index 0000000..fa49b07
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/subdir/new.txt
@@ -0,0 +1 @@
+new file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/subdir/subdir2/README b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/subdir/subdir2/README
new file mode 100755
index 0000000..1385f26
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/subdir/subdir2/README
@@ -0,0 +1 @@
+hey
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/subdir/subdir2/new.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/subdir/subdir2/new.txt
new file mode 100755
index 0000000..fa49b07
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/testrepo2/subdir/subdir2/new.txt
@@ -0,0 +1 @@
+new file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/config
new file mode 100755
index 0000000..c53d818
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/config
@@ -0,0 +1,5 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = true
+	ignorecase = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/0c/8a3f1f3d5f421cf83048c7c73ee3b55a5e0f29 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/0c/8a3f1f3d5f421cf83048c7c73ee3b55a5e0f29
new file mode 100755
index 0000000..12698af
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/0c/8a3f1f3d5f421cf83048c7c73ee3b55a5e0f29 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/10/2dce8e3081f398e4bdd9fd894dc85ac3ca6a67 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/10/2dce8e3081f398e4bdd9fd894dc85ac3ca6a67
new file mode 100755
index 0000000..3806ee7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/10/2dce8e3081f398e4bdd9fd894dc85ac3ca6a67 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/17/7d8634a28e26ec7819284752757ebe01a479d5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/17/7d8634a28e26ec7819284752757ebe01a479d5
new file mode 100755
index 0000000..e91e06d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/17/7d8634a28e26ec7819284752757ebe01a479d5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/1c/30b88f5f3ee66d78df6520a7de9e89b890818b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/1c/30b88f5f3ee66d78df6520a7de9e89b890818b
new file mode 100755
index 0000000..57d1a0f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/1c/30b88f5f3ee66d78df6520a7de9e89b890818b
@@ -0,0 +1,3 @@
+xŽM
+Â0F]çsËÌä§	ˆ¸Üz‚Iš¶Ši¤¦÷·^Áå{<>¾TKy4`6‡¶æš,y’9j§GJì8ÁÇÞb¢‘\Œfõ–5/
Ç^‰8v¹'ö‚ÙËœì`SƝ%[›ë
+÷T[ƒ[×úŠ,púüÌsºL6o±Kµœ´5Ø;ŽèÕn÷›-ÿ= ²úÿDÃ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/1f/4c0311a24b63f6fc209a59a1e404942d4a5006 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/1f/4c0311a24b63f6fc209a59a1e404942d4a5006
new file mode 100755
index 0000000..99288fd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/1f/4c0311a24b63f6fc209a59a1e404942d4a5006
@@ -0,0 +1,2 @@
+xÍ=Â0@aæœÂ ²Mê6BlH¬œ ¿m!RqïO¹ë7¼[­‹
rÐ5g°N’Xƒ‹Å±)Eg]ÏDY2c	R8xã7Û
+ØTáÞÁ­½Rõo8~òœ®Ó¢óºØêèÔ[”™àˆ#¢Ùußjþ;`¼ùÔÙ7ó
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/22/24e191514cb4bd8c566d80dac22dfcb1e9bb83 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/22/24e191514cb4bd8c566d80dac22dfcb1e9bb83
new file mode 100755
index 0000000..48466ea
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/22/24e191514cb4bd8c566d80dac22dfcb1e9bb83
@@ -0,0 +1,3 @@
+xŽK
+Â0@]çsK&¤	ˆ¸Üz‚™4éÛHMïo½‚Û÷àñbY–©‚1tª[JàbŽlɈµâ¥í4vÉ¡±Lâ³
ì'—Õ›·´V`B¦û .
+ëÎIöm ï1õZ¨Ç x¯cÙàK­ðhà^^ýÂ+\>?2·aªã.M,Ë°µtTB‹pÖ^kuÐc³¦¿jV_«sFh
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/29/6e56023cdc034d2735fee8c0d85a659d1b07f4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/29/6e56023cdc034d2735fee8c0d85a659d1b07f4
new file mode 100755
index 0000000..aa3fccd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/29/6e56023cdc034d2735fee8c0d85a659d1b07f4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/31/51880ae2b363f1c262cf98b750c1f169a0d432 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/31/51880ae2b363f1c262cf98b750c1f169a0d432
new file mode 100755
index 0000000..235d42b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/31/51880ae2b363f1c262cf98b750c1f169a0d432 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/3b/287f8730c81d0b763c2d294618a5e32b67b4f8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/3b/287f8730c81d0b763c2d294618a5e32b67b4f8
new file mode 100755
index 0000000..56ddac5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/3b/287f8730c81d0b763c2d294618a5e32b67b4f8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/42/b7311aa626e712891940c1ec5d5cba201946a4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/42/b7311aa626e712891940c1ec5d5cba201946a4
new file mode 100755
index 0000000..a8e6581
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/42/b7311aa626e712891940c1ec5d5cba201946a4
@@ -0,0 +1,3 @@
+xÎ½
Â0@ajOqcßù"!D‡DËþKÂ1
+Îþ„h_ñéÅZÊ£AßÛC[s†aÌÈžp´I³±‰#‹„lB…œqÈêí×¼4ðZ"¡Ç(œyGF¢¢ød#y«ò[›ë
+÷X[ƒ[×úJÅ/púüÊsºL6o¡‹µœA²èX„ሂ¨öºo¶ü7 ’úÔ¸Ec
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/49/6d6428b9cf92981dc9495211e6e1120fb6f2ba b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/49/6d6428b9cf92981dc9495211e6e1120fb6f2ba
new file mode 100755
index 0000000..978bc34
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/49/6d6428b9cf92981dc9495211e6e1120fb6f2ba differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/59/b0cf7d74659e1cdb13305319d6d4ce2733c118 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/59/b0cf7d74659e1cdb13305319d6d4ce2733c118
new file mode 100755
index 0000000..30b507c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/59/b0cf7d74659e1cdb13305319d6d4ce2733c118 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/6a/b5d28acbf3c3bdff276f7ccfdf29c1520e542f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/6a/b5d28acbf3c3bdff276f7ccfdf29c1520e542f
new file mode 100755
index 0000000..ff6a386
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/6a/b5d28acbf3c3bdff276f7ccfdf29c1520e542f
@@ -0,0 +1 @@
+xÎM‚0@a×=Å\@2ýcÜ™¸õeÚ†Rƒåþâܾŗǵ”¹RæÔ¶”@¢Šœ(i$™uOÉ1ö9Ro"“
¬9¸à¼x‡-­
ü@¬µcc3;ê-KvHÊ+‡9ÙèÁFe¼{›êO®­Á£ƒ{]b	+\>¿òoãܦ}踖+Hm
zšàŒ„(Žzl¶ô7 ñ•œF-
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/6c/fca542b55b8b37017e6125a4b8f59a6eae6f11 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/6c/fca542b55b8b37017e6125a4b8f59a6eae6f11
new file mode 100755
index 0000000..9a969a2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/6c/fca542b55b8b37017e6125a4b8f59a6eae6f11 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/76/5b32c65d38f04c4f287abda055818ec0f26912 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/76/5b32c65d38f04c4f287abda055818ec0f26912
new file mode 100755
index 0000000..493bbc0
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/76/5b32c65d38f04c4f287abda055818ec0f26912 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/7b/8c336c45fc6895c1c60827260fe5d798e5d247 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/7b/8c336c45fc6895c1c60827260fe5d798e5d247
new file mode 100755
index 0000000..19e7ef4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/7b/8c336c45fc6895c1c60827260fe5d798e5d247
@@ -0,0 +1,3 @@
+xÎA @Qלb.`3S(‰1îLÜz‚B[µÅTzëܾÅϏež§
+D|¨kJCß3f‰´íȵœ‚uÙ	›L>YGMÌV½eMK9¢ÑZˆƒ5ÙæHè¥õ¢#{¦ž¥E´J¶:–î±Ô
+·®åÕϲÀéó“Çp¦:n¡‰e>ƒ6-£sHGìÕ®ûfMÔS}ZE²
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/82/bf9a1a10a4b25c1f14c9607b60970705e92545 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/82/bf9a1a10a4b25c1f14c9607b60970705e92545
new file mode 100755
index 0000000..89b0b9f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/82/bf9a1a10a4b25c1f14c9607b60970705e92545
@@ -0,0 +1 @@
+xŽË
Â09»Šm€hã_ÖBܐ¸R×Ÿ„cœþ1-p§yšPKy4RÚ–D›GŒF»ÀJvÉFE>‡1#q²Ž
j§ÅÛoimbvSŽŠYSbEr²Š¸»Q"eÓÑ{+üÞ–ºÁ=ÔÖà6Àµ¾bñ+œ>?òœ/ó£-;¡–3ŒÊhœ¬C‚#¢è´g¶ô÷XÄÌyF¤
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/8b/82fb1794cb1c8c7f172ec730a4c2db0ae3e650 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/8b/82fb1794cb1c8c7f172ec730a4c2db0ae3e650
new file mode 100755
index 0000000..8e9b758
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/8b/82fb1794cb1c8c7f172ec730a4c2db0ae3e650
@@ -0,0 +1,3 @@
+xÎ½
Â0@ajOqù7BtH´Lp¾ó%A8FÁÙŸ°íW<=ª¥Ì
¬õ‡¶æx"ÊŽØ$—%1†dÄcÏDNLˆ:Yv=©7®yiÐc
+l¤$Ž\b{‰DÂbOd‚Õ9x+
+·6ÕT[ƒ{·úâ‚œ??yŽ×qnÓ–:ªåƯcÔÞÁQZ«]÷Í–ÿ¨¢¾7 H†
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/9a/40a2f11c191f180c47e54b11567cb3c1e89b30 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/9a/40a2f11c191f180c47e54b11567cb3c1e89b30
new file mode 100755
index 0000000..1de1224
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/9a/40a2f11c191f180c47e54b11567cb3c1e89b30 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/9b/219343610c88a1187c996d0dc58330b55cee28 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/9b/219343610c88a1187c996d0dc58330b55cee28
new file mode 100755
index 0000000..8b64b43
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/9b/219343610c88a1187c996d0dc58330b55cee28
@@ -0,0 +1,2 @@
+xÏKj1Ьç½óÊFj}Z‚¼3²Ê	¤VÏÇdFA#ß?’\ ËzÅu]—FÓSo" ‰JðÆ&‚^˜‚Ž,9$G’Eéd)7|¦&[6”(FU"&Žh<¯FÉc4AÆ¿>"ZÑQ;m9Û\;ïKP%1b9k‰93¤GŸkƒw®½Ãënõ£¬iƒçý[îÓuZúüÈ®ëhã¬"RÞÂY¥†C[]þ=0¼I›rKÏp—¶÷óO:Á²õ
+»pÝʯ
_¾(c‡
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/9f/e06a50f4d1634d6c6879854d01d80857388706 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/9f/e06a50f4d1634d6c6879854d01d80857388706
new file mode 100755
index 0000000..055de01
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/9f/e06a50f4d1634d6c6879854d01d80857388706 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/a4/1a49f8f5cd9b6cb14a076bf8394881ed0b4d19 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/a4/1a49f8f5cd9b6cb14a076bf8394881ed0b4d19
new file mode 100755
index 0000000..cb4d34e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/a4/1a49f8f5cd9b6cb14a076bf8394881ed0b4d19
@@ -0,0 +1,3 @@
+xÎ½
Â0@ajOqÝù7'!D‡DËöÙ	A$FÁÙŸ°íW<=©ó<5ÐÚÚZ
+8N(CÈÁzÇ…$'2!Î>[):#D½zǵ,
zŽ	£MÚ	
d…=†ä‘t…µ³NÅ­=ê
+w©­Á­ƒk}å9.púüä9^Æ©=¶ÔIÏ@ÆYž‰áˆ=¢ÚußlåÔ°Dâ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/a9/53a018c5b10b20c86e69fef55ebc8ad4c5a417 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/a9/53a018c5b10b20c86e69fef55ebc8ad4c5a417
new file mode 100755
index 0000000..8235f18
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/a9/53a018c5b10b20c86e69fef55ebc8ad4c5a417
@@ -0,0 +1 @@
+xÍJÄ0…]÷)înV3$¹is"îÁ•Oû“NŶ’ɼ¿ñ\žï|8²¯ëÒ!dzèÍªÔdXG/ޫϹp*‰¢C³X³ˆº@ZÂ8|•f[VŸ0HD™H“E]6¯”g¶I#g«*ñÏ­9UEæHÆH!MḦÕñh‚ºR¦¡Üûuoð.{ïðz—ýSײÁãí‡|ÌÏóÒ¯w¾È¾>Ç1º4‘C8;rn8èq«Û¿†7k³·²ÉNui·~þM§áÜ^­
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/a9/cce3cd1b3efbda5b1f4a6dcc3f1570b2d3d74c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/a9/cce3cd1b3efbda5b1f4a6dcc3f1570b2d3d74c
new file mode 100755
index 0000000..4da7e82
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/a9/cce3cd1b3efbda5b1f4a6dcc3f1570b2d3d74c
@@ -0,0 +1 @@
+x+)JMU044c040031QHdx6÷ÑìM¯9{wk®+ºqèIOðD¨d6>É|’¹X%>½9j
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/bd/1732c43c68d712ad09e1d872b9be6d4b9efdc4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/bd/1732c43c68d712ad09e1d872b9be6d4b9efdc4
new file mode 100755
index 0000000..b9b6012
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/bd/1732c43c68d712ad09e1d872b9be6d4b9efdc4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/c3/7a783c20d92ac92362a78a32860f7eebf938ef b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/c3/7a783c20d92ac92362a78a32860f7eebf938ef
new file mode 100755
index 0000000..041e890
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/c3/7a783c20d92ac92362a78a32860f7eebf938ef differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/cb/dd40facab1682754eb67f7a43f29e672903cf6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/cb/dd40facab1682754eb67f7a43f29e672903cf6
new file mode 100755
index 0000000..ccb156d
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/cb/dd40facab1682754eb67f7a43f29e672903cf6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/cd/f97fd3bb48eb3827638bb33d208f5fd32d0aa6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/cd/f97fd3bb48eb3827638bb33d208f5fd32d0aa6
new file mode 100755
index 0000000..0e028dc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/cd/f97fd3bb48eb3827638bb33d208f5fd32d0aa6 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/d6/f10d549cb335b9e6d38afc1f0088be69b50494 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/d6/f10d549cb335b9e6d38afc1f0088be69b50494
new file mode 100755
index 0000000..b298c52
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/d6/f10d549cb335b9e6d38afc1f0088be69b50494 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/d9/acdc7ae7632adfeec67fa73c1e343cf4d1f47e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/d9/acdc7ae7632adfeec67fa73c1e343cf4d1f47e
new file mode 100755
index 0000000..de94528
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/d9/acdc7ae7632adfeec67fa73c1e343cf4d1f47e
@@ -0,0 +1 @@
+x+)JMU044c040031QHdx6÷ÑìM¯9{wk®+ºqèIOðD¨d>É4|’éX%:79U
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100755
index 0000000..7112238
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/ef/0488f0b722f0be8bcb90a7730ac7efafd1d694 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/ef/0488f0b722f0be8bcb90a7730ac7efafd1d694
new file mode 100755
index 0000000..00f7d36
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/ef/0488f0b722f0be8bcb90a7730ac7efafd1d694
@@ -0,0 +1 @@
+xŽM F]sŠ¹€Í0Ã_cÜ™¸õ@¡ÕH1•Þ_¼‚Û—ï}y±–òh@¤mK	8³ÙYÆèä„ÁŽ4ѨŒt^'¦`lPÙ‰·ßÒÚ Ï<g™yÒY‘ŒÙ1*m´œ­»„™Fá÷¶Ô
·®õ5¿Âéó#Ïù2?Ú²‡!ÖrÉZ¡5ÆŽpD‡(:í™-ý} ²ø#E¸
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/fc/f7e3f51c11d199ab7a78403ee4f9ccd028da25 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/fc/f7e3f51c11d199ab7a78403ee4f9ccd028da25
new file mode 100755
index 0000000..54989ea
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/objects/fc/f7e3f51c11d199ab7a78403ee4f9ccd028da25 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/refs/heads/first-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/refs/heads/first-branch
new file mode 100755
index 0000000..ef0dead
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/refs/heads/first-branch
@@ -0,0 +1 @@
+2224e191514cb4bd8c566d80dac22dfcb1e9bb83
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/refs/heads/master
new file mode 100755
index 0000000..ebf18f5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/refs/heads/master
@@ -0,0 +1 @@
+1c30b88f5f3ee66d78df6520a7de9e89b890818b
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/refs/heads/second-branch b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/refs/heads/second-branch
new file mode 100755
index 0000000..586a14a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/twowaymerge.git/refs/heads/second-branch
@@ -0,0 +1 @@
+9b219343610c88a1187c996d0dc58330b55cee28
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/config
new file mode 100755
index 0000000..4cc6e1d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/config
@@ -0,0 +1,12 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
+[submodule "e"]
+	url = /Users/rb/src/libgit2/tests-clar/resources/submod2_target/.git
+[submodule "d"]
+	url = /Users/rb/src/libgit2/tests-clar/resources/submod2_target/.git
+[submodule "b"]
+	url = /Users/rb/src/libgit2/tests-clar/resources/submod2_target/.git
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/index
new file mode 100755
index 0000000..4f6d12a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/config
new file mode 100755
index 0000000..f57cd4a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/config
@@ -0,0 +1,13 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	worktree = ../../../b
+	ignorecase = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = /Users/rb/src/libgit2/tests-clar/resources/submod2_target/.git
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/index
new file mode 100755
index 0000000..c16a026
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1
new file mode 100755
index 0000000..f4b7094
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484
new file mode 100755
index 0000000..56c845e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5
new file mode 100755
index 0000000..bd179b5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/41/bd4bc3df978de695f67ace64c560913da11653 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/41/bd4bc3df978de695f67ace64c560913da11653
new file mode 100755
index 0000000..ccf49bd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/41/bd4bc3df978de695f67ace64c560913da11653 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/48/0095882d281ed676fe5b863569520e54a7d5c0
new file mode 100755
index 0000000..5302906
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/5e/4963595a9774b90524d35a807169049de8ccad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/5e/4963595a9774b90524d35a807169049de8ccad
new file mode 100755
index 0000000..38c791e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/5e/4963595a9774b90524d35a807169049de8ccad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/6b/31c659545507c381e9cd34ec508f16c04e149e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
new file mode 100755
index 0000000..a26d299
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
@@ -0,0 +1,2 @@
+x•Q
+!EûvoÅÓy*Ñ_¿í@Çg#h‚£ûOhý^Î9w«¥¤ÒêSoÌ€f1*²ŠÁ[”‰¬§èIc Ô¤ìê¤p£ïµÁkçΑ\›¿¿S߇¿lµÜ@.¤´^QpF‹(æ:ÿúDÿ5Åó“zr~	ñen8
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/73/ba924a80437097795ae839e66e187c55d3babf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/73/ba924a80437097795ae839e66e187c55d3babf
new file mode 100755
index 0000000..83d1ba4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/73/ba924a80437097795ae839e66e187c55d3babf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
new file mode 100755
index 0000000..6d27af8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
@@ -0,0 +1,2 @@
+x-Ë1Â0FaæžâßØ0pŽÀìÄÐ(N-ÅöÐÛÓ¡Ò“¾é±ãq]>ksÅ*š?	|m“‡Õçiª@ÛÖý¶¼m»¨V£…£'©î`)”.Ø-1¨x
+u„xãòt(+
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/78/9efbdadaa4a582778d4584385495559ea0994b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/78/9efbdadaa4a582778d4584385495559ea0994b
new file mode 100755
index 0000000..1745884
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/78/9efbdadaa4a582778d4584385495559ea0994b
@@ -0,0 +1,2 @@
+x
α
…0)ÞŠ?=
¥ÉÄNŠlO¤k®¸‹jÛúÿ¹8&„«¨ ãr
”
+ïqJWñ°7¾B<ÉáöfÙìK8­#Q1C-‘"eª·Ì«£Š°ð>¼'@
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e
new file mode 100755
index 0000000..83cc29f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5
new file mode 100755
index 0000000..55bda40
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/packed-refs
new file mode 100755
index 0000000..5a4ebc4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+480095882d281ed676fe5b863569520e54a7d5c0 refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/refs/heads/master
new file mode 100755
index 0000000..e12c44d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/refs/heads/master
@@ -0,0 +1 @@
+480095882d281ed676fe5b863569520e54a7d5c0
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..6efe28f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/b/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/config
new file mode 100755
index 0000000..42e1bdd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/config
@@ -0,0 +1,13 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	worktree = ../../../d
+	ignorecase = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = /Users/rb/src/libgit2/tests-clar/resources/submod2_target/.git
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/index
new file mode 100755
index 0000000..86d0266
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1
new file mode 100755
index 0000000..f4b7094
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484
new file mode 100755
index 0000000..56c845e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5
new file mode 100755
index 0000000..bd179b5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/41/bd4bc3df978de695f67ace64c560913da11653 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/41/bd4bc3df978de695f67ace64c560913da11653
new file mode 100755
index 0000000..ccf49bd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/41/bd4bc3df978de695f67ace64c560913da11653 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/48/0095882d281ed676fe5b863569520e54a7d5c0
new file mode 100755
index 0000000..5302906
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/5e/4963595a9774b90524d35a807169049de8ccad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/5e/4963595a9774b90524d35a807169049de8ccad
new file mode 100755
index 0000000..38c791e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/5e/4963595a9774b90524d35a807169049de8ccad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/6b/31c659545507c381e9cd34ec508f16c04e149e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
new file mode 100755
index 0000000..a26d299
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
@@ -0,0 +1,2 @@
+x•Q
+!EûvoÅÓy*Ñ_¿í@Çg#h‚£ûOhý^Î9w«¥¤ÒêSoÌ€f1*²ŠÁ[”‰¬§èIc Ô¤ìê¤p£ïµÁkçΑ\›¿¿S߇¿lµÜ@.¤´^QpF‹(æ:ÿúDÿ5Åó“zr~	ñen8
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/73/ba924a80437097795ae839e66e187c55d3babf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/73/ba924a80437097795ae839e66e187c55d3babf
new file mode 100755
index 0000000..83d1ba4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/73/ba924a80437097795ae839e66e187c55d3babf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
new file mode 100755
index 0000000..6d27af8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
@@ -0,0 +1,2 @@
+x-Ë1Â0FaæžâßØ0pŽÀìÄÐ(N-ÅöÐÛÓ¡Ò“¾é±ãq]>ksÅ*š?	|m“‡Õçiª@ÛÖý¶¼m»¨V£…£'©î`)”.Ø-1¨x
+u„xãòt(+
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/78/9efbdadaa4a582778d4584385495559ea0994b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/78/9efbdadaa4a582778d4584385495559ea0994b
new file mode 100755
index 0000000..1745884
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/78/9efbdadaa4a582778d4584385495559ea0994b
@@ -0,0 +1,2 @@
+x
α
…0)ÞŠ?=
¥ÉÄNŠlO¤k®¸‹jÛúÿ¹8&„«¨ ãr
”
+ïqJWñ°7¾B<ÉáöfÙìK8­#Q1C-‘"eª·Ì«£Š°ð>¼'@
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e
new file mode 100755
index 0000000..83cc29f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5
new file mode 100755
index 0000000..55bda40
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/packed-refs
new file mode 100755
index 0000000..5a4ebc4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+480095882d281ed676fe5b863569520e54a7d5c0 refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/refs/heads/master
new file mode 100755
index 0000000..e12c44d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/refs/heads/master
@@ -0,0 +1 @@
+480095882d281ed676fe5b863569520e54a7d5c0
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..6efe28f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/d/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/config
new file mode 100755
index 0000000..89b3b9b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/config
@@ -0,0 +1,13 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	worktree = ../../../e
+	ignorecase = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = /Users/rb/src/libgit2/tests-clar/resources/submod2_target/.git
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/index
new file mode 100755
index 0000000..cd6e2da
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/info/exclude
new file mode 100755
index 0000000..a5196d1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1
new file mode 100755
index 0000000..f4b7094
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/06/362fe2fdb7010d0e447b4fb450d405420479a1 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484
new file mode 100755
index 0000000..56c845e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/0e/6a3ca48bd47cfe67681acf39aa0b10a0b92484 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5
new file mode 100755
index 0000000..bd179b5
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/17/d0ece6e96460a06592d9d9d000de37ba4232c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/41/bd4bc3df978de695f67ace64c560913da11653 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/41/bd4bc3df978de695f67ace64c560913da11653
new file mode 100755
index 0000000..ccf49bd
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/41/bd4bc3df978de695f67ace64c560913da11653 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/48/0095882d281ed676fe5b863569520e54a7d5c0
new file mode 100755
index 0000000..5302906
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/48/0095882d281ed676fe5b863569520e54a7d5c0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/5e/4963595a9774b90524d35a807169049de8ccad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/5e/4963595a9774b90524d35a807169049de8ccad
new file mode 100755
index 0000000..38c791e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/5e/4963595a9774b90524d35a807169049de8ccad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/6b/31c659545507c381e9cd34ec508f16c04e149e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
new file mode 100755
index 0000000..a26d299
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/6b/31c659545507c381e9cd34ec508f16c04e149e
@@ -0,0 +1,2 @@
+x•Q
+!EûvoÅÓy*Ñ_¿í@Çg#h‚£ûOhý^Î9w«¥¤ÒêSoÌ€f1*²ŠÁ[”‰¬§èIc Ô¤ìê¤p£ïµÁkçΑ\›¿¿S߇¿lµÜ@.¤´^QpF‹(æ:ÿúDÿ5Åó“zr~	ñen8
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/73/ba924a80437097795ae839e66e187c55d3babf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/73/ba924a80437097795ae839e66e187c55d3babf
new file mode 100755
index 0000000..83d1ba4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/73/ba924a80437097795ae839e66e187c55d3babf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
new file mode 100755
index 0000000..6d27af8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/78/0d7397f5e8f8f477fb55b7af3accc2154b2d4a
@@ -0,0 +1,2 @@
+x-Ë1Â0FaæžâßØ0pŽÀìÄÐ(N-ÅöÐÛÓ¡Ò“¾é±ãq]>ksÅ*š?	|m“‡Õçiª@ÛÖý¶¼m»¨V£…£'©î`)”.Ø-1¨x
+u„xãòt(+
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/78/9efbdadaa4a582778d4584385495559ea0994b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/78/9efbdadaa4a582778d4584385495559ea0994b
new file mode 100755
index 0000000..1745884
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/78/9efbdadaa4a582778d4584385495559ea0994b
@@ -0,0 +1,2 @@
+x
α
…0)ÞŠ?=
¥ÉÄNŠlO¤k®¸‹jÛúÿ¹8&„«¨ ãr
”
+ïqJWñ°7¾B<ÉáöfÙìK8­#Q1C-‘"eª·Ì«£Š°ð>¼'@
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e
new file mode 100755
index 0000000..83cc29f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/88/34b635dd468a83cb012f6feace968c1c9f5d6e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5
new file mode 100755
index 0000000..55bda40
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/objects/d0/5f2cd5cc77addf68ed6f50d622c9a4f732e6c5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/packed-refs
new file mode 100755
index 0000000..5a4ebc4
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+480095882d281ed676fe5b863569520e54a7d5c0 refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/refs/heads/master
new file mode 100755
index 0000000..e12c44d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/refs/heads/master
@@ -0,0 +1 @@
+480095882d281ed676fe5b863569520e54a7d5c0
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/refs/remotes/origin/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/refs/remotes/origin/HEAD
new file mode 100755
index 0000000..6efe28f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/modules/e/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/0d/78578795b7ca49fd8df6c4b6d27c5c02d991d8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/0d/78578795b7ca49fd8df6c4b6d27c5c02d991d8
new file mode 100755
index 0000000..f2d02f4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/0d/78578795b7ca49fd8df6c4b6d27c5c02d991d8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/0e/7ed140b514b8cae23254cb8656fe1674403aff b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/0e/7ed140b514b8cae23254cb8656fe1674403aff
new file mode 100755
index 0000000..527964c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/0e/7ed140b514b8cae23254cb8656fe1674403aff differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/0f/f461da9689266f482d8f6654a4400b4e33c586 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/0f/f461da9689266f482d8f6654a4400b4e33c586
new file mode 100755
index 0000000..2694e4f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/0f/f461da9689266f482d8f6654a4400b4e33c586 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/18/aa7e45bbe4c3cc24a0b079696c59d36675af97 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/18/aa7e45bbe4c3cc24a0b079696c59d36675af97
new file mode 100755
index 0000000..032a960
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/18/aa7e45bbe4c3cc24a0b079696c59d36675af97 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/1b/63caae4a5ca96f78e8dfefc376c6a39a142475 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/1b/63caae4a5ca96f78e8dfefc376c6a39a142475
new file mode 100755
index 0000000..d32622e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/1b/63caae4a5ca96f78e8dfefc376c6a39a142475 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/1e/abe82aa3b2365a394f6108f24435df6e193d02 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/1e/abe82aa3b2365a394f6108f24435df6e193d02
new file mode 100755
index 0000000..42d5f92
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/1e/abe82aa3b2365a394f6108f24435df6e193d02 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/42/061c01a1c70097d1e4579f29a5adf40abdec95 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/42/061c01a1c70097d1e4579f29a5adf40abdec95
new file mode 100755
index 0000000..0a8f32e
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/42/061c01a1c70097d1e4579f29a5adf40abdec95 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/46/2838cee476a87e7cff32196b66fa18ed756592 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/46/2838cee476a87e7cff32196b66fa18ed756592
new file mode 100755
index 0000000..52af51f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/46/2838cee476a87e7cff32196b66fa18ed756592 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/63/499e4ea8e096b831515ceb1d5a7593e4d87ae5 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/63/499e4ea8e096b831515ceb1d5a7593e4d87ae5
new file mode 100755
index 0000000..afafa89
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/63/499e4ea8e096b831515ceb1d5a7593e4d87ae5 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/68/1af94e10eaf262f3ab7cb9b8fd5f4158ba4d3e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/68/1af94e10eaf262f3ab7cb9b8fd5f4158ba4d3e
new file mode 100755
index 0000000..9e518fc
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/68/1af94e10eaf262f3ab7cb9b8fd5f4158ba4d3e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/6a/9008602b811e69a9b7a2d83496f39a794fdeeb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/6a/9008602b811e69a9b7a2d83496f39a794fdeeb
new file mode 100755
index 0000000..a245727
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/6a/9008602b811e69a9b7a2d83496f39a794fdeeb differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/6e/ae26c90e8ccc4d16208972119c40635489c6f0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/6e/ae26c90e8ccc4d16208972119c40635489c6f0
new file mode 100755
index 0000000..ea35cd3
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/6e/ae26c90e8ccc4d16208972119c40635489c6f0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/6f/39eabbb8a7541515e0d35971078bccb502e7e0 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/6f/39eabbb8a7541515e0d35971078bccb502e7e0
new file mode 100755
index 0000000..c548175
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/6f/39eabbb8a7541515e0d35971078bccb502e7e0 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/71/54d3083461536dfc71ad5542f3e65e723a06c4 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/71/54d3083461536dfc71ad5542f3e65e723a06c4
new file mode 100755
index 0000000..9fdd8f2
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/71/54d3083461536dfc71ad5542f3e65e723a06c4 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/75/56c1d893a4c0ca85ac8ac51de47ff399758729 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/75/56c1d893a4c0ca85ac8ac51de47ff399758729
new file mode 100755
index 0000000..d43630f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/75/56c1d893a4c0ca85ac8ac51de47ff399758729 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/76/fef844064c26d5e06c2508240dae661e7231b2 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/76/fef844064c26d5e06c2508240dae661e7231b2
new file mode 100755
index 0000000..355ce4b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/76/fef844064c26d5e06c2508240dae661e7231b2 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/79/b9f23e85f55ea36a472a902e875bc1121a94cb b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/79/b9f23e85f55ea36a472a902e875bc1121a94cb
new file mode 100755
index 0000000..2b07ad2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/79/b9f23e85f55ea36a472a902e875bc1121a94cb
@@ -0,0 +1,2 @@
+x•A E]sŠ¹€f€JbŒqçÖí`I@
+÷—ĸýyïýµäH;ŸZeBrž6L˜P«Yº%8½²&v‹4JmÖ¢ÔÛ^*¼úqpJðà¸Âµúû;¶½ûËZò
¤žœ’Æ 3ZD1Öñ×ú¯)žŸØ"%ø%Ä–38_
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/85/28da0ea65eacf1f74f9ed6696adbac547963ad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/85/28da0ea65eacf1f74f9ed6696adbac547963ad
new file mode 100755
index 0000000..6d2da6c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/85/28da0ea65eacf1f74f9ed6696adbac547963ad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/8b/3726b365824ad5a07c537247f4bc73ed7d37ea b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/8b/3726b365824ad5a07c537247f4bc73ed7d37ea
new file mode 100755
index 0000000..3dc333b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/8b/3726b365824ad5a07c537247f4bc73ed7d37ea differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/93/3e28c1c8a68838a763d250bdf0b2c6068289c3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/93/3e28c1c8a68838a763d250bdf0b2c6068289c3
new file mode 100755
index 0000000..02ad0e9
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/93/3e28c1c8a68838a763d250bdf0b2c6068289c3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/96/2710fe5b4e453e9e827945b3487c525968ec4a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/96/2710fe5b4e453e9e827945b3487c525968ec4a
new file mode 100755
index 0000000..d06b06a
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/96/2710fe5b4e453e9e827945b3487c525968ec4a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/96/6cf1b3598e195b31b2cde3784f9a19f0728a6f b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/96/6cf1b3598e195b31b2cde3784f9a19f0728a6f
new file mode 100755
index 0000000..5f9ffd4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/96/6cf1b3598e195b31b2cde3784f9a19f0728a6f differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/99/e8bab9ece009f0fba7eb41f850f4c12bedb9b7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/99/e8bab9ece009f0fba7eb41f850f4c12bedb9b7
new file mode 100755
index 0000000..ac17def
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/99/e8bab9ece009f0fba7eb41f850f4c12bedb9b7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/9b/19edf33a03a0c59cdfc113bfa5c06179bf9b1a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/9b/19edf33a03a0c59cdfc113bfa5c06179bf9b1a
new file mode 100755
index 0000000..7ab83ae
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/9b/19edf33a03a0c59cdfc113bfa5c06179bf9b1a
@@ -0,0 +1,5 @@
+x•ŽI
+1E]箕LTˆè
¼A†J·Ðƒ¤Ó÷7WpûyïñÓ¶,ŸZÑ©Uf cXcR	ƒC4¼3Y2æ"£NN:ÔHɈo¨¼6 ,µ’žs’ˆòÁjf—#îk½G›¶
+ïcßyžáÉsá
+·ã§MG¼¦m¹ƒ2–´Bò
+.ÒK)úÚÿµŽþkŠ×Ö‘w8ñžCCÃ
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/9b/db75b73836a99e3dbeea640a81de81031fdc29 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/9b/db75b73836a99e3dbeea640a81de81031fdc29
new file mode 100755
index 0000000..aed4d81
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/9b/db75b73836a99e3dbeea640a81de81031fdc29 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/9d/0235c7a7edc0889a18f97a42ee6db9fe688447 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/9d/0235c7a7edc0889a18f97a42ee6db9fe688447
new file mode 100755
index 0000000..3e02a41
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/9d/0235c7a7edc0889a18f97a42ee6db9fe688447 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/9e/ffc457877f109b2a4319e14bee613a15f2a00d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/9e/ffc457877f109b2a4319e14bee613a15f2a00d
new file mode 100755
index 0000000..fb24100
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/9e/ffc457877f109b2a4319e14bee613a15f2a00d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/a0/a9bad6f6f40325198f938a0e3ae981622d7707 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/a0/a9bad6f6f40325198f938a0e3ae981622d7707
new file mode 100755
index 0000000..b6b7db7
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/a0/a9bad6f6f40325198f938a0e3ae981622d7707 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/b1/977dc4e573b812d4619754c98138c56999dc0d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/b1/977dc4e573b812d4619754c98138c56999dc0d
new file mode 100755
index 0000000..e133405
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/b1/977dc4e573b812d4619754c98138c56999dc0d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/d7/5992dd02391e128dac332dcc78d649dd9ab095 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/d7/5992dd02391e128dac332dcc78d649dd9ab095
new file mode 100755
index 0000000..65f1f53
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/d7/5992dd02391e128dac332dcc78d649dd9ab095 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/da/e2709d638df52212b1f43ff61797ebfedfcc7c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/da/e2709d638df52212b1f43ff61797ebfedfcc7c
new file mode 100755
index 0000000..355faa6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/da/e2709d638df52212b1f43ff61797ebfedfcc7c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/e1/152adcb9adf37ec551ada9ba377ab53aec3bad b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/e1/152adcb9adf37ec551ada9ba377ab53aec3bad
new file mode 100755
index 0000000..c68fdcf
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/e1/152adcb9adf37ec551ada9ba377ab53aec3bad differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/e4/ed436a9eb0f198cda722886a5f8d6d6c836b7b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/e4/ed436a9eb0f198cda722886a5f8d6d6c836b7b
new file mode 100755
index 0000000..c9229ba
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/e4/ed436a9eb0f198cda722886a5f8d6d6c836b7b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100755
index 0000000..7112238
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/f2/0b79342712e0b2315647cd8227a573fd3bc46e b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/f2/0b79342712e0b2315647cd8227a573fd3bc46e
new file mode 100755
index 0000000..3962ba6
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/f2/0b79342712e0b2315647cd8227a573fd3bc46e differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/fd/e0147e3b59f381635a3b016e3fe6dacb70779d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/fd/e0147e3b59f381635a3b016e3fe6dacb70779d
new file mode 100755
index 0000000..e3663da
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/objects/fd/e0147e3b59f381635a3b016e3fe6dacb70779d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/refs/heads/master
new file mode 100755
index 0000000..546481a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/.gitted/refs/heads/master
@@ -0,0 +1 @@
+6eae26c90e8ccc4d16208972119c40635489c6f0
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/README.md b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/README.md
new file mode 100755
index 0000000..1f5a95a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/README.md
@@ -0,0 +1,43 @@
+This is a test repo for libgit2 where tree entries have type changes
+
+Types
+-----
+
+The key types that could be found in tree entries are:
+
+1. GIT_FILEMODE_NEW             = 0000000 (i.e. file does not exist)
+2. GIT_FILEMODE_TREE            = 0040000
+3. GIT_FILEMODE_BLOB            = 0100644
+4. GIT_FILEMODE_BLOB_EXECUTABLE = 0100755
+5. GIT_FILEMODE_LINK            = 0120000
+6. GIT_FILEMODE_COMMIT          = 0160000
+
+I will try to have every type of transition somewhere in the history
+of this repo.
+
+Commits
+-------
+
+* `a(1--1) b(1--1) c(1--1) d(1--1) e(1--1)`
+  **Initial commit**<br>
+  `79b9f23e85f55ea36a472a902e875bc1121a94cb`
+* `a(1->2) b(1->3) c(1->4) d(1->5) e(1->6)`
+  **Create content**<br>
+  `9bdb75b73836a99e3dbeea640a81de81031fdc29`
+* `a(2->3) b(3->4) c(4->5) d(5->6) e(6->2)`
+  **Changes #1**<br>
+  `0e7ed140b514b8cae23254cb8656fe1674403aff`
+* `a(3->5) b(4->6) c(5->2) d(6->3) e(2->4)`
+  **Changes #2**<br>
+  `9d0235c7a7edc0889a18f97a42ee6db9fe688447`
+* `a(5->3) b(6->4) c(2->5) d(3->6) e(4->2)`
+  **Changes #3**<br>
+  `9b19edf33a03a0c59cdfc113bfa5c06179bf9b1a`
+* `a(3->2) b(4->3) c(5->4) d(6->5) e(2->6)`
+  **Changes #4**<br>
+  `1b63caae4a5ca96f78e8dfefc376c6a39a142475`<br>
+  Matches **Changes #1** except README.md
+* `a(2->1) b(3->1) c(4->1) d(5->1) e(6->1)`
+  **Changes #5**<br>
+  `6eae26c90e8ccc4d16208972119c40635489c6f0`<br>
+  Matches **Initial commit** except README.md and .gitmodules
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/gitmodules b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/typechanges/gitmodules
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/config
new file mode 100755
index 0000000..f57351f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/config
@@ -0,0 +1,6 @@
+[core]
+	bare = true
+	repositoryformatversion = 0
+	filemode = false
+	logallrefupdates = true
+	ignorecase = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/info/exclude b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/info/exclude
new file mode 100755
index 0000000..6d05881
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/info/exclude
@@ -0,0 +1,2 @@
+# File patterns to ignore; see `git help ignore` for more information.
+# Lines that start with '#' are comments.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/08/8b64704e0d6b8bd061dea879418cb5442a3fbf b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/08/8b64704e0d6b8bd061dea879418cb5442a3fbf
new file mode 100755
index 0000000..953262f
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/08/8b64704e0d6b8bd061dea879418cb5442a3fbf differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/13/a5e939bca25940c069fd2169d993dba328e30b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/13/a5e939bca25940c069fd2169d993dba328e30b
new file mode 100755
index 0000000..91ec8fa
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/13/a5e939bca25940c069fd2169d993dba328e30b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/19/bf568e59e3a0b363cafb4106226e62d4a4c41c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/19/bf568e59e3a0b363cafb4106226e62d4a4c41c
new file mode 100755
index 0000000..94afd01
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/19/bf568e59e3a0b363cafb4106226e62d4a4c41c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/58/1fadd35b4cf320d102a152f918729011604773 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/58/1fadd35b4cf320d102a152f918729011604773
new file mode 100755
index 0000000..5b33d02
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/58/1fadd35b4cf320d102a152f918729011604773 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/5c/87b6791e8b13da658a14d1ef7e09b5dc3bac8c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/5c/87b6791e8b13da658a14d1ef7e09b5dc3bac8c
new file mode 100755
index 0000000..67eb149
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/5c/87b6791e8b13da658a14d1ef7e09b5dc3bac8c differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/6f/e5f5398af85fb3de8a6aba0339b6d3bfa26a27 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/6f/e5f5398af85fb3de8a6aba0339b6d3bfa26a27
new file mode 100755
index 0000000..c1ea0de
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/6f/e5f5398af85fb3de8a6aba0339b6d3bfa26a27 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/7f/ccd75616ec188b8f1b23d67506a334cc34a49d b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/7f/ccd75616ec188b8f1b23d67506a334cc34a49d
new file mode 100755
index 0000000..0285055
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/7f/ccd75616ec188b8f1b23d67506a334cc34a49d differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/80/6999882bf91d24241e4077906b9017605eb1f3 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/80/6999882bf91d24241e4077906b9017605eb1f3
new file mode 100755
index 0000000..e866a75
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/80/6999882bf91d24241e4077906b9017605eb1f3 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/83/7d176303c5005505ec1e4a30231c40930c0230 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/83/7d176303c5005505ec1e4a30231c40930c0230
new file mode 100755
index 0000000..189ab04
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/83/7d176303c5005505ec1e4a30231c40930c0230 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/a8/595ccca04f40818ae0155c8f9c77a230e597b6 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/a8/595ccca04f40818ae0155c8f9c77a230e597b6
new file mode 100755
index 0000000..a2ef6be
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/a8/595ccca04f40818ae0155c8f9c77a230e597b6
@@ -0,0 +1,2 @@
+x•Ž[
+Â0EýÎ*æ_“¤yˆÝ€{˜4ShZ))¸|®À¯ÎáN[ks=èKß™Á¶Åš¨[’ÉÈQ"4&&—M*¤i/Þ´óÚ! ‹1† S‰*Ÿ™Añ€ÞGt)¢ò-'UŒ £×m‡ñ7O	cc¸Õ¹=zåå´µ;(ãPY«‡+*DqÒó^ç¿E!¥œ*­/Î0¯}Z?<ÒÂPæ…¥øšÈJp
\ No newline at end of file
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/cf/8f1cf5cce859c438d6cc067284cb5e161206e7 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/cf/8f1cf5cce859c438d6cc067284cb5e161206e7
new file mode 100755
index 0000000..ec274cb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/cf/8f1cf5cce859c438d6cc067284cb5e161206e7 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/d5/278d05c8607ec420bfee4cf219fbc0eeebfd6a b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/d5/278d05c8607ec420bfee4cf219fbc0eeebfd6a
new file mode 100755
index 0000000..c1b6a51
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/d5/278d05c8607ec420bfee4cf219fbc0eeebfd6a differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/f4/e16fb76536591a41454194058d048d8e4dd2e9 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/f4/e16fb76536591a41454194058d048d8e4dd2e9
new file mode 100755
index 0000000..ad751ad
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/f4/e16fb76536591a41454194058d048d8e4dd2e9 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/f9/e65619d93fdf2673882e0a261c5e93b1a84006 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/f9/e65619d93fdf2673882e0a261c5e93b1a84006
new file mode 100755
index 0000000..f87cd42
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/objects/f9/e65619d93fdf2673882e0a261c5e93b1a84006 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/refs/heads/exe-file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/refs/heads/exe-file
new file mode 100755
index 0000000..b96ef46
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/refs/heads/exe-file
@@ -0,0 +1 @@
+a8595ccca04f40818ae0155c8f9c77a230e597b6
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/refs/heads/master b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/refs/heads/master
new file mode 100755
index 0000000..96c17ab
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/refs/heads/master
@@ -0,0 +1 @@
+7fccd75616ec188b8f1b23d67506a334cc34a49d
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/refs/heads/reg-file b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/refs/heads/reg-file
new file mode 100755
index 0000000..b428c00
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/unsymlinked.git/refs/heads/reg-file
@@ -0,0 +1 @@
+806999882bf91d24241e4077906b9017605eb1f3
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/HEAD b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/HEAD
new file mode 100755
index 0000000..cb089cd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/config b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/config
new file mode 100755
index 0000000..6c9406b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/config
@@ -0,0 +1,7 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
+	precomposeunicode = true
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/description b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/description
new file mode 100755
index 0000000..498b267
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/index b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/index
new file mode 100755
index 0000000..548dc7b
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/index differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/info/refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/info/refs
new file mode 100755
index 0000000..b074314
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/info/refs
@@ -0,0 +1 @@
+60e3f7b244a5305e2c9fa4ef0e897f3b14f3b8dd	refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/09/65b377c214bbe5e0d18fcdaf556df7fa7ed7c8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/09/65b377c214bbe5e0d18fcdaf556df7fa7ed7c8
new file mode 100755
index 0000000..cbaf4c1
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/09/65b377c214bbe5e0d18fcdaf556df7fa7ed7c8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/0c/20ef1409ae1df4d5a76cdbd98d5c33ccdb6bcc b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/0c/20ef1409ae1df4d5a76cdbd98d5c33ccdb6bcc
new file mode 100755
index 0000000..fa149da
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/0c/20ef1409ae1df4d5a76cdbd98d5c33ccdb6bcc differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/39/ea75107a09091ba54ff86fcc780b59477e42cd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/39/ea75107a09091ba54ff86fcc780b59477e42cd
new file mode 100755
index 0000000..7483736
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/39/ea75107a09091ba54ff86fcc780b59477e42cd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/3c/c08384deae5957247bc36776ab626cc9e0582b b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/3c/c08384deae5957247bc36776ab626cc9e0582b
new file mode 100755
index 0000000..29b72fb
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/3c/c08384deae5957247bc36776ab626cc9e0582b differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/46/8d6f2afc940e14c76347fa9af26e429a3c9044 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/46/8d6f2afc940e14c76347fa9af26e429a3c9044
new file mode 100755
index 0000000..5fc8391
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/46/8d6f2afc940e14c76347fa9af26e429a3c9044 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/53/917973acfe0111f93c2cfaacf854be245880e8 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/53/917973acfe0111f93c2cfaacf854be245880e8
new file mode 100755
index 0000000..debf7e4
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/53/917973acfe0111f93c2cfaacf854be245880e8 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/63/1d44e0c72e8cd1b594fa11d7d1ee8a6d67ff67 b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/63/1d44e0c72e8cd1b594fa11d7d1ee8a6d67ff67
new file mode 100755
index 0000000..e8b884c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/63/1d44e0c72e8cd1b594fa11d7d1ee8a6d67ff67 differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/f3/be389d351e4bcc6dcc4b5fe22134ef0f63f8bd b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/f3/be389d351e4bcc6dcc4b5fe22134ef0f63f8bd
new file mode 100755
index 0000000..cfbef99
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/f3/be389d351e4bcc6dcc4b5fe22134ef0f63f8bd differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/info/packs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/info/packs
new file mode 100755
index 0000000..0c5fc2a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/info/packs
@@ -0,0 +1,2 @@
+P pack-1652578900ac63564f2a24b9714529821276ceb9.pack
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/pack/pack-1652578900ac63564f2a24b9714529821276ceb9.idx b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/pack/pack-1652578900ac63564f2a24b9714529821276ceb9.idx
new file mode 100755
index 0000000..6f4381c
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/pack/pack-1652578900ac63564f2a24b9714529821276ceb9.idx differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/pack/pack-1652578900ac63564f2a24b9714529821276ceb9.pack b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/pack/pack-1652578900ac63564f2a24b9714529821276ceb9.pack
new file mode 100755
index 0000000..39bd1d8
Binary files /dev/null and b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/objects/pack/pack-1652578900ac63564f2a24b9714529821276ceb9.pack differ
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/packed-refs b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/packed-refs
new file mode 100755
index 0000000..802f67c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled fully-peeled 
+60e3f7b244a5305e2c9fa4ef0e897f3b14f3b8dd refs/heads/master
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/refs/dummy-marker.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/.gitted/refs/dummy-marker.txt
new file mode 100755
index 0000000..e69de29
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/after/file.html b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/after/file.html
new file mode 100755
index 0000000..2320e2f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/after/file.html
@@ -0,0 +1,41 @@
+<html>
+<body>
+  <h1 id="first section">
+  <ol>
+    <li>item 1.1</li>
+    <li>item 1.2 changed</li>
+    <li>item 1.3 changed</li>
+    <li>item 1.4</li>
+    <li>item 1.5</li>
+    <li>item 1.6</li>
+    <li>item 1.7</li>
+    <li>item 1.8</li>
+    <li>item 1.9</li>
+  <li>item 1.10 added</li>
+  </ol>
+  </h1>
+  <h1 id="second section">
+  <ol>
+    <li>item 2.1</li>
+    <li>item 2.2</li>
+    <li>item 2.3</li>
+    <li>item 2.4</li>
+    <li>item 2.5</li>
+    <li>item 2.6</li>
+    <li>item 2.7 changed</li>
+    <li>item 2.7.1 added</li>
+    <li>item 2.8</li>
+  </ol>
+  </h1>
+  <h1 id="third section">
+  <ol>
+    <li>item 3.1</li>
+    <li>item 3.2</li>
+    <li>item 3.3</li>
+    <li>item 3.4</li>
+    <li>item 3.5</li>
+    <li>item 3.6</li>
+  </ol>
+  </h1>
+</body>
+</html>
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/after/file.javascript b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/after/file.javascript
new file mode 100755
index 0000000..5391797
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/after/file.javascript
@@ -0,0 +1,108 @@
+define(function(require, exports, module) {
+  module.exports = Player;
+
+  var Key = require("./key")
+    , Direction = require("./direction");
+
+  function Player(game) {
+    this.game = game;
+
+    this.image = new Image("./assets/fighter.png");
+    this.game.resources.add(this.image);
+
+    this.x = 0;
+    this.y = 0;
+
+    this.pixelX = 10;
+    this.pixelY = 10;
+
+    this.animationStep = 0;
+  }
+
+  Player.prototype.update = function() {
+    if (!this.isWalking()) {
+      this.handleInput();
+    }
+
+    if (this.isWalking()) {
+      // Increase the animation step.
+      this.animationStep = ++this.animationStep % 60;
+
+      if (this.x * 32 > this.pixelX) {
+        this.pixelX++;
+      } else if (this.x * 32 < this.pixelX) {
+        this.pixelX--;
+      }
+
+      if (this.y * 32 > this.pixelY) {
+        this.pixelY++;
+      } else if (this.y * 32 < this.pixelY) {
+        this.pixelY--;
+      }
+    } else {
+      // Reset the animation step.
+      this.animationStep = 0;
+    }
+  };
+
+  Player.prototype.handleInput = function() {
+    var keyboard = this.game.keyboard, finalAction, action, inputs = {
+      'moveDown': keyboard.isDown(Key.DOWN),
+      'moveUp': keyboard.isDown(Key.UP),
+      'moveLeft': keyboard.isDown(Key.LEFT),
+      'moveRight': keyboard.isDown(Key.RIGHT)
+    };
+
+    for (action in inputs) {
+      if (inputs[action]) {
+        if (!finalAction || inputs[finalAction] < inputs[action]) {
+          finalAction = action;
+        }
+      }
+    }
+
+    this[finalAction] && this[finalAction]();
+  };
+
+  Player.prototype.isWalking = function() {
+    return this.x * 32 != this.pixelX || this.y * 32 != this.pixelY;
+  };
+
+  Player.prototype.moveDown = function() {
+    this.y += 1;
+    this.direction = Direction.DOWN;
+  };
+
+  Player.prototype.moveUp = function() {
+    this.y -= 1;
+    this.direction = Direction.UP;
+  };
+
+  Player.prototype.moveLeft = function() {
+    this.x -= 5;
+    this.direction = Direction.LEFT;
+  };
+
+  Player.prototype.moveRight = function() {
+    this.x += 1;
+    this.direction = Direction.RIGHT;
+  };
+
+  Player.prototype.draw = function(context) {
+    var offsetX = Math.floor(this.animationStep / 15) * 32, offsetY = 0;
+
+    switch(this.direction) {
+      case Direction.UP:
+        offsetY = 48 * 3;
+        break;
+      case Direction.RIGHT:
+        offsetY = 48 * 2;
+        break;
+      case Direction.LEFT:
+        offsetY = 48;
+        break;
+    }
+
+    context.drawImage(this.image.data, offsetX, offsetY, 32, 48, this.pixelX, this.pixelY, 32, 48);
+  };
+});
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/after/file.php b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/after/file.php
new file mode 100755
index 0000000..967d646
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/after/file.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Faker;
+
+/**
+ * Proxy for other generators, to return only unique values. Works with
+ * Faker\Generator\Base->unique()
+ */
+class UniqueGenerator
+{
+    protected $generator;
+    protected $maxRetries;
+	protected $moreStuff;
+    protected $uniques = array();
+
+    public function __construct(Generator $generator, $maxRetries)
+    {
+        $this->generator = $generator;
+        $this->maxRetries = $maxRetries + 1;
+    }
+
+    /**
+     * Catch and proxy all generator calls but return only unique values
+     */
+    public function __get($attribute)
+    {
+        return $this->__call($attribute, array());
+    }
+
+    /**
+     * Catch and proxy all generator calls with arguments but return only unique values
+     */
+    public function __call($name, $arguments)
+    {
+        $i = 0;
+        if (!isset($this->uniques[$name])) {
+            $this->uniques[$name] = array();
+        }
+        do {
+            $res = call_user_func_array(array($this->generator, $name), $arguments);
+            $i++;
+            if ($i >= $this->maxRetries) {
+                throw new \OverflowException(sprintf('Maximum retries of %d reached without finding a unique value', $this->maxRetries));
+            }
+        } while (in_array($res, $this->uniques[$name]));
+        $this->uniques[$name][]= $res;
+
+        return $res;
+    }
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/before/file.html b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/before/file.html
new file mode 100755
index 0000000..872d196
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/before/file.html
@@ -0,0 +1,41 @@
+<html>
+<body>
+  <h1 id="first section">
+  <ol>
+    <li>item 1.1</li>
+    <li>item 1.2</li>
+    <li>item 1.3</li>
+    <li>item 1.4</li>
+    <li>item 1.5</li>
+    <li>item 1.6</li>
+    <li>item 1.7</li>
+    <li>item 1.8</li>
+    <li>item 1.9</li>
+  </ol>
+  </h1>
+  <h1 id="second section">
+  <ol>
+    <li>item 2.1</li>
+    <li>item 2.2</li>
+    <li>item 2.3</li>
+    <li>item 2.4</li>
+    <li>item 2.5</li>
+    <li>item 2.6</li>
+    <li>item 2.7</li>
+    <li>item 2.8</li>
+  </ol>
+  </h1>
+  <h1 id="third section">
+  <ol>
+    <li>item 3.1</li>
+    <li>item 3.2</li>
+    <li>item 3.3</li>
+    <li>item 3.4</li>
+    <li>item 3.5</li>
+    <li>item 3.6</li>
+    <li>item 3.7</li>
+    <li>item 3.8</li>
+  </ol>
+  </h1>
+</body>
+</html>
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/before/file.javascript b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/before/file.javascript
new file mode 100755
index 0000000..0965b37
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/before/file.javascript
@@ -0,0 +1,109 @@
+define(function(require, exports, module) {
+  module.exports = Player;
+
+  var Key = require("./key")
+    , Direction = require("./direction")
+    , Image = require("./image");
+
+  function Player(game) {
+    this.game = game;
+
+    this.image = new Image("./assets/fighter.png");
+    this.game.resources.add(this.image);
+
+    this.x = 0;
+    this.y = 0;
+
+    this.pixelX = 0;
+    this.pixelY = 0;
+
+    this.animationStep = 0;
+  }
+
+  Player.prototype.update = function() {
+    if (!this.isWalking()) {
+      this.handleInput();
+    }
+
+    if (this.isWalking()) {
+      // Increase the animation step.
+      this.animationStep = ++this.animationStep % 60;
+
+      if (this.x * 32 > this.pixelX) {
+        this.pixelX++;
+      } else if (this.x * 32 < this.pixelX) {
+        this.pixelX--;
+      }
+
+      if (this.y * 32 > this.pixelY) {
+        this.pixelY++;
+      } else if (this.y * 32 < this.pixelY) {
+        this.pixelY--;
+      }
+    } else {
+      // Reset the animation step.
+      this.animationStep = 0;
+    }
+  };
+
+  Player.prototype.handleInput = function() {
+    var keyboard = this.game.keyboard, finalAction, action, inputs = {
+      'moveDown': keyboard.isDown(Key.DOWN),
+      'moveUp': keyboard.isDown(Key.UP),
+      'moveLeft': keyboard.isDown(Key.LEFT),
+      'moveRight': keyboard.isDown(Key.RIGHT)
+    };
+
+    for (action in inputs) {
+      if (inputs[action]) {
+        if (!finalAction || inputs[finalAction] < inputs[action]) {
+          finalAction = action;
+        }
+      }
+    }
+
+    this[finalAction] && this[finalAction]();
+  };
+
+  Player.prototype.isWalking = function() {
+    return this.x * 32 != this.pixelX || this.y * 32 != this.pixelY;
+  };
+
+  Player.prototype.moveDown = function() {
+    this.y += 1;
+    this.direction = Direction.DOWN;
+  };
+
+  Player.prototype.moveUp = function() {
+    this.y -= 1;
+    this.direction = Direction.UP;
+  };
+
+  Player.prototype.moveLeft = function() {
+    this.x -= 1;
+    this.direction = Direction.LEFT;
+  };
+
+  Player.prototype.moveRight = function() {
+    this.x += 1;
+    this.direction = Direction.RIGHT;
+  };
+
+  Player.prototype.draw = function(context) {
+    var offsetX = Math.floor(this.animationStep / 15) * 32, offsetY = 0;
+
+    switch(this.direction) {
+      case Direction.UP:
+        offsetY = 48 * 3;
+        break;
+      case Direction.RIGHT:
+        offsetY = 48 * 2;
+        break;
+      case Direction.LEFT:
+        offsetY = 48;
+        break;
+    }
+
+    context.drawImage(this.image.data, offsetX, offsetY, 32, 48, this.pixelX, this.pixelY - 16, 32, 48);
+  };
+});
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/before/file.php b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/before/file.php
new file mode 100755
index 0000000..63250ad
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/before/file.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Faker;
+
+/**
+ * Proxy for other generators, to return only unique values. Works with
+ * Faker\Generator\Base->unique()
+ */
+class UniqueGenerator
+{
+    protected $generator;
+    protected $maxRetries;
+    protected $uniques = array();
+
+    public function __construct(Generator $generator, $maxRetries)
+    {
+        $this->generator = $generator;
+        $this->maxRetries = $maxRetries;
+    }
+
+    /**
+     * Catch and proxy all generator calls but return only unique values
+     */
+    public function __get($attribute)
+    {
+        return $this->__call($attribute, array());
+    }
+
+    /**
+     * Catch and proxy all generator calls with arguments but return only unique values
+     */
+    public function __call($name, $arguments)
+    {
+        if (!isset($this->uniques[$name])) {
+            $this->uniques[$name] = array();
+        }
+        $i = 0;
+        do {
+            $res = call_user_func_array(array($this->generator, $name), $arguments);
+            $i++;
+            if ($i > $this->maxRetries) {
+                throw new \OverflowException(sprintf('Maximum retries of %d reached without finding a unique value', $this->maxRetries));
+            }
+        } while (in_array($res, $this->uniques[$name]));
+        $this->uniques[$name][]= $res;
+
+        return $res;
+    }
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/driver/diff.html b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/driver/diff.html
new file mode 100755
index 0000000..5a428e7
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/driver/diff.html
@@ -0,0 +1,26 @@
+diff --git a/files/file.html b/files/file.html
+index 872d196..2320e2f 100644
+--- a/files/file.html
++++ b/files/file.html
+@@ -5,4 +5,4 @@ <h1 id="first section">
+     <li>item 1.1</li>
+-    <li>item 1.2</li>
+-    <li>item 1.3</li>
++    <li>item 1.2 changed</li>
++    <li>item 1.3 changed</li>
+     <li>item 1.4</li>
+@@ -13,2 +13,3 @@ <h1 id="first section">
+     <li>item 1.9</li>
++  <li>item 1.10 added</li>
+   </ol>
+@@ -23,3 +24,4 @@ <h1 id="second section">
+     <li>item 2.6</li>
+-    <li>item 2.7</li>
++    <li>item 2.7 changed</li>
++    <li>item 2.7.1 added</li>
+     <li>item 2.8</li>
+@@ -35,4 +37,2 @@ <h1 id="third section">
+     <li>item 3.6</li>
+-    <li>item 3.7</li>
+-    <li>item 3.8</li>
+   </ol>
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/driver/diff.javascript b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/driver/diff.javascript
new file mode 100755
index 0000000..4cefe5c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/driver/diff.javascript
@@ -0,0 +1,27 @@
+diff --git a/files/file.javascript b/files/file.javascript
+index 0965b37..5391797 100644
+--- a/files/file.javascript
++++ b/files/file.javascript
+@@ -4,4 +4,3 @@ function(require, exports, module)
+   var Key = require("./key")
+-    , Direction = require("./direction")
+-    , Image = require("./image");
++    , Direction = require("./direction");
+ 
+@@ -16,4 +15,4 @@ function Player(game)
+ 
+-    this.pixelX = 0;
+-    this.pixelY = 0;
++    this.pixelX = 10;
++    this.pixelY = 10;
+ 
+@@ -82,3 +81,3 @@ Player.prototype.moveUp = function()
+   Player.prototype.moveLeft = function() {
+-    this.x -= 1;
++    this.x -= 5;
+     this.direction = Direction.LEFT;
+@@ -106,3 +105,3 @@ Player.prototype.draw = function(context)
+ 
+-    context.drawImage(this.image.data, offsetX, offsetY, 32, 48, this.pixelX, this.pixelY - 16, 32, 48);
++    context.drawImage(this.image.data, offsetX, offsetY, 32, 48, this.pixelX, this.pixelY, 32, 48);
+   };
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/driver/diff.php b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/driver/diff.php
new file mode 100755
index 0000000..9711b5b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/driver/diff.php
@@ -0,0 +1,26 @@
+diff --git a/files/file.php b/files/file.php
+index 63250ad..967d646 100644
+--- a/files/file.php
++++ b/files/file.php
+@@ -12,2 +12,3 @@ class UniqueGenerator
+     protected $maxRetries;
++	protected $moreStuff;
+     protected $uniques = array();
+@@ -17,3 +18,3 @@ public function __construct(Generator $generator, $maxRetries)
+         $this->generator = $generator;
+-        $this->maxRetries = $maxRetries;
++        $this->maxRetries = $maxRetries + 1;
+     }
+@@ -33,10 +34,10 @@ public function __call($name, $arguments)
+     {
++        $i = 0;
+         if (!isset($this->uniques[$name])) {
+             $this->uniques[$name] = array();
+         }
+-        $i = 0;
+         do {
+             $res = call_user_func_array(array($this->generator, $name), $arguments);
+             $i++;
+-            if ($i > $this->maxRetries) {
++            if ($i >= $this->maxRetries) {
+                 throw new \OverflowException(sprintf('Maximum retries of %d reached without finding a unique value', $this->maxRetries));
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/nodriver/diff.html b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/nodriver/diff.html
new file mode 100755
index 0000000..2ea4b8a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/nodriver/diff.html
@@ -0,0 +1,26 @@
+diff --git a/files/file.html b/files/file.html
+index 872d196..2320e2f 100644
+--- a/files/file.html
++++ b/files/file.html
+@@ -5,4 +5,4 @@
+     <li>item 1.1</li>
+-    <li>item 1.2</li>
+-    <li>item 1.3</li>
++    <li>item 1.2 changed</li>
++    <li>item 1.3 changed</li>
+     <li>item 1.4</li>
+@@ -13,2 +13,3 @@
+     <li>item 1.9</li>
++  <li>item 1.10 added</li>
+   </ol>
+@@ -23,3 +24,4 @@
+     <li>item 2.6</li>
+-    <li>item 2.7</li>
++    <li>item 2.7 changed</li>
++    <li>item 2.7.1 added</li>
+     <li>item 2.8</li>
+@@ -35,4 +37,2 @@
+     <li>item 3.6</li>
+-    <li>item 3.7</li>
+-    <li>item 3.8</li>
+   </ol>
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/nodriver/diff.javascript b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/nodriver/diff.javascript
new file mode 100755
index 0000000..4bbd547
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/nodriver/diff.javascript
@@ -0,0 +1,27 @@
+diff --git a/files/file.javascript b/files/file.javascript
+index 0965b37..5391797 100644
+--- a/files/file.javascript
++++ b/files/file.javascript
+@@ -4,4 +4,3 @@ define(function(require, exports, module) {
+   var Key = require("./key")
+-    , Direction = require("./direction")
+-    , Image = require("./image");
++    , Direction = require("./direction");
+ 
+@@ -16,4 +15,4 @@ define(function(require, exports, module) {
+ 
+-    this.pixelX = 0;
+-    this.pixelY = 0;
++    this.pixelX = 10;
++    this.pixelY = 10;
+ 
+@@ -82,3 +81,3 @@ define(function(require, exports, module) {
+   Player.prototype.moveLeft = function() {
+-    this.x -= 1;
++    this.x -= 5;
+     this.direction = Direction.LEFT;
+@@ -106,3 +105,3 @@ define(function(require, exports, module) {
+ 
+-    context.drawImage(this.image.data, offsetX, offsetY, 32, 48, this.pixelX, this.pixelY - 16, 32, 48);
++    context.drawImage(this.image.data, offsetX, offsetY, 32, 48, this.pixelX, this.pixelY, 32, 48);
+   };
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/nodriver/diff.php b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/nodriver/diff.php
new file mode 100755
index 0000000..e77c094
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/expected/nodriver/diff.php
@@ -0,0 +1,26 @@
+diff --git a/files/file.php b/files/file.php
+index 63250ad..967d646 100644
+--- a/files/file.php
++++ b/files/file.php
+@@ -12,2 +12,3 @@ class UniqueGenerator
+     protected $maxRetries;
++	protected $moreStuff;
+     protected $uniques = array();
+@@ -17,3 +18,3 @@ class UniqueGenerator
+         $this->generator = $generator;
+-        $this->maxRetries = $maxRetries;
++        $this->maxRetries = $maxRetries + 1;
+     }
+@@ -33,10 +34,10 @@ class UniqueGenerator
+     {
++        $i = 0;
+         if (!isset($this->uniques[$name])) {
+             $this->uniques[$name] = array();
+         }
+-        $i = 0;
+         do {
+             $res = call_user_func_array(array($this->generator, $name), $arguments);
+             $i++;
+-            if ($i > $this->maxRetries) {
++            if ($i >= $this->maxRetries) {
+                 throw new \OverflowException(sprintf('Maximum retries of %d reached without finding a unique value', $this->maxRetries));
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/files/file.html b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/files/file.html
new file mode 100755
index 0000000..2320e2f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/files/file.html
@@ -0,0 +1,41 @@
+<html>
+<body>
+  <h1 id="first section">
+  <ol>
+    <li>item 1.1</li>
+    <li>item 1.2 changed</li>
+    <li>item 1.3 changed</li>
+    <li>item 1.4</li>
+    <li>item 1.5</li>
+    <li>item 1.6</li>
+    <li>item 1.7</li>
+    <li>item 1.8</li>
+    <li>item 1.9</li>
+  <li>item 1.10 added</li>
+  </ol>
+  </h1>
+  <h1 id="second section">
+  <ol>
+    <li>item 2.1</li>
+    <li>item 2.2</li>
+    <li>item 2.3</li>
+    <li>item 2.4</li>
+    <li>item 2.5</li>
+    <li>item 2.6</li>
+    <li>item 2.7 changed</li>
+    <li>item 2.7.1 added</li>
+    <li>item 2.8</li>
+  </ol>
+  </h1>
+  <h1 id="third section">
+  <ol>
+    <li>item 3.1</li>
+    <li>item 3.2</li>
+    <li>item 3.3</li>
+    <li>item 3.4</li>
+    <li>item 3.5</li>
+    <li>item 3.6</li>
+  </ol>
+  </h1>
+</body>
+</html>
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/files/file.javascript b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/files/file.javascript
new file mode 100755
index 0000000..5391797
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/files/file.javascript
@@ -0,0 +1,108 @@
+define(function(require, exports, module) {
+  module.exports = Player;
+
+  var Key = require("./key")
+    , Direction = require("./direction");
+
+  function Player(game) {
+    this.game = game;
+
+    this.image = new Image("./assets/fighter.png");
+    this.game.resources.add(this.image);
+
+    this.x = 0;
+    this.y = 0;
+
+    this.pixelX = 10;
+    this.pixelY = 10;
+
+    this.animationStep = 0;
+  }
+
+  Player.prototype.update = function() {
+    if (!this.isWalking()) {
+      this.handleInput();
+    }
+
+    if (this.isWalking()) {
+      // Increase the animation step.
+      this.animationStep = ++this.animationStep % 60;
+
+      if (this.x * 32 > this.pixelX) {
+        this.pixelX++;
+      } else if (this.x * 32 < this.pixelX) {
+        this.pixelX--;
+      }
+
+      if (this.y * 32 > this.pixelY) {
+        this.pixelY++;
+      } else if (this.y * 32 < this.pixelY) {
+        this.pixelY--;
+      }
+    } else {
+      // Reset the animation step.
+      this.animationStep = 0;
+    }
+  };
+
+  Player.prototype.handleInput = function() {
+    var keyboard = this.game.keyboard, finalAction, action, inputs = {
+      'moveDown': keyboard.isDown(Key.DOWN),
+      'moveUp': keyboard.isDown(Key.UP),
+      'moveLeft': keyboard.isDown(Key.LEFT),
+      'moveRight': keyboard.isDown(Key.RIGHT)
+    };
+
+    for (action in inputs) {
+      if (inputs[action]) {
+        if (!finalAction || inputs[finalAction] < inputs[action]) {
+          finalAction = action;
+        }
+      }
+    }
+
+    this[finalAction] && this[finalAction]();
+  };
+
+  Player.prototype.isWalking = function() {
+    return this.x * 32 != this.pixelX || this.y * 32 != this.pixelY;
+  };
+
+  Player.prototype.moveDown = function() {
+    this.y += 1;
+    this.direction = Direction.DOWN;
+  };
+
+  Player.prototype.moveUp = function() {
+    this.y -= 1;
+    this.direction = Direction.UP;
+  };
+
+  Player.prototype.moveLeft = function() {
+    this.x -= 5;
+    this.direction = Direction.LEFT;
+  };
+
+  Player.prototype.moveRight = function() {
+    this.x += 1;
+    this.direction = Direction.RIGHT;
+  };
+
+  Player.prototype.draw = function(context) {
+    var offsetX = Math.floor(this.animationStep / 15) * 32, offsetY = 0;
+
+    switch(this.direction) {
+      case Direction.UP:
+        offsetY = 48 * 3;
+        break;
+      case Direction.RIGHT:
+        offsetY = 48 * 2;
+        break;
+      case Direction.LEFT:
+        offsetY = 48;
+        break;
+    }
+
+    context.drawImage(this.image.data, offsetX, offsetY, 32, 48, this.pixelX, this.pixelY, 32, 48);
+  };
+});
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/files/file.php b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/files/file.php
new file mode 100755
index 0000000..967d646
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/resources/userdiff/files/file.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Faker;
+
+/**
+ * Proxy for other generators, to return only unique values. Works with
+ * Faker\Generator\Base->unique()
+ */
+class UniqueGenerator
+{
+    protected $generator;
+    protected $maxRetries;
+	protected $moreStuff;
+    protected $uniques = array();
+
+    public function __construct(Generator $generator, $maxRetries)
+    {
+        $this->generator = $generator;
+        $this->maxRetries = $maxRetries + 1;
+    }
+
+    /**
+     * Catch and proxy all generator calls but return only unique values
+     */
+    public function __get($attribute)
+    {
+        return $this->__call($attribute, array());
+    }
+
+    /**
+     * Catch and proxy all generator calls with arguments but return only unique values
+     */
+    public function __call($name, $arguments)
+    {
+        $i = 0;
+        if (!isset($this->uniques[$name])) {
+            $this->uniques[$name] = array();
+        }
+        do {
+            $res = call_user_func_array(array($this->generator, $name), $arguments);
+            $i++;
+            if ($i >= $this->maxRetries) {
+                throw new \OverflowException(sprintf('Maximum retries of %d reached without finding a unique value', $this->maxRetries));
+            }
+        } while (in_array($res, $this->uniques[$name]));
+        $this->uniques[$name][]= $res;
+
+        return $res;
+    }
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revert/bare.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revert/bare.c
new file mode 100755
index 0000000..206c86d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revert/bare.c
@@ -0,0 +1,107 @@
+#include "clar.h"
+#include "clar_libgit2.h"
+
+#include "buffer.h"
+#include "fileops.h"
+#include "git2/revert.h"
+
+#include "../merge/merge_helpers.h"
+
+#define TEST_REPO_PATH "revert"
+
+static git_repository *repo;
+
+// Fixture setup and teardown
+void test_revert_bare__initialize(void)
+{
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+}
+
+void test_revert_bare__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_revert_bare__automerge(void)
+{
+	git_commit *head_commit, *revert_commit;
+	git_oid head_oid, revert_oid;
+	git_index *index;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "caf99de3a49827117bb66721010eac461b06a80c", 0, "file1.txt" },
+		{ 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
+		{ 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
+		{ 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
+	};
+
+	git_oid_fromstr(&head_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45");
+	cl_git_pass(git_commit_lookup(&head_commit, repo, &head_oid));
+
+	git_oid_fromstr(&revert_oid, "d1d403d22cbe24592d725f442835cf46fe60c8ac");
+	cl_git_pass(git_commit_lookup(&revert_commit, repo, &revert_oid));
+
+	cl_git_pass(git_revert_commit(&index, repo, revert_commit, head_commit, 0, NULL));
+	cl_assert(merge_test_index(index, merge_index_entries, 4));
+
+	git_commit_free(revert_commit);
+	git_commit_free(head_commit);
+	git_index_free(index);
+}
+
+void test_revert_bare__conflicts(void)
+{
+	git_reference *head_ref;
+	git_commit *head_commit, *revert_commit;
+	git_oid revert_oid;
+	git_index *index;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "7731926a337c4eaba1e2187d90ebfa0a93659382", 1, "file1.txt" },
+		{ 0100644, "4b8fcff56437e60f58e9a6bc630dd242ebf6ea2c", 2, "file1.txt" },
+		{ 0100644, "3a3ef367eaf3fe79effbfb0a56b269c04c2b59fe", 3, "file1.txt" },
+		{ 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
+		{ 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
+		{ 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
+	};
+
+	git_oid_fromstr(&revert_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45");
+
+	cl_git_pass(git_repository_head(&head_ref, repo));
+	cl_git_pass(git_reference_peel((git_object **)&head_commit, head_ref, GIT_OBJ_COMMIT));
+
+	cl_git_pass(git_commit_lookup(&revert_commit, repo, &revert_oid));
+	cl_git_pass(git_revert_commit(&index, repo, revert_commit, head_commit, 0, NULL));
+
+	cl_assert(git_index_has_conflicts(index));
+	cl_assert(merge_test_index(index, merge_index_entries, 6));
+
+	git_commit_free(revert_commit);
+	git_commit_free(head_commit);
+	git_reference_free(head_ref);
+	git_index_free(index);
+}
+
+void test_revert_bare__orphan(void)
+{
+	git_commit *head_commit, *revert_commit;
+	git_oid head_oid, revert_oid;
+	git_index *index;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "296a6d3be1dff05c5d1f631d2459389fa7b619eb", 0, "file-mainline.txt" },
+	};
+
+	git_oid_fromstr(&head_oid, "39467716290f6df775a91cdb9a4eb39295018145");
+	cl_git_pass(git_commit_lookup(&head_commit, repo, &head_oid));
+
+	git_oid_fromstr(&revert_oid, "ebb03002cee5d66c7732dd06241119fe72ab96a5");
+	cl_git_pass(git_commit_lookup(&revert_commit, repo, &revert_oid));
+
+	cl_git_pass(git_revert_commit(&index, repo, revert_commit, head_commit, 0, NULL));
+	cl_assert(merge_test_index(index, merge_index_entries, 1));
+
+	git_commit_free(revert_commit);
+	git_commit_free(head_commit);
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revert/workdir.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revert/workdir.c
new file mode 100755
index 0000000..9f83bd8
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revert/workdir.c
@@ -0,0 +1,577 @@
+#include "clar.h"
+#include "clar_libgit2.h"
+
+#include "buffer.h"
+#include "fileops.h"
+#include "git2/revert.h"
+
+#include "../merge/merge_helpers.h"
+
+#define TEST_REPO_PATH "revert"
+
+static git_repository *repo;
+static git_index *repo_index;
+
+// Fixture setup and teardown
+void test_revert_workdir__initialize(void)
+{
+	git_config *cfg;
+
+	repo = cl_git_sandbox_init(TEST_REPO_PATH);
+	git_repository_index(&repo_index, repo);
+
+	/* Ensure that the user's merge.conflictstyle doesn't interfere */
+	cl_git_pass(git_repository_config(&cfg, repo));
+	cl_git_pass(git_config_set_string(cfg, "merge.conflictstyle", "merge"));
+	git_config_free(cfg);
+}
+
+void test_revert_workdir__cleanup(void)
+{
+	git_index_free(repo_index);
+	cl_git_sandbox_cleanup();
+}
+
+/* git reset --hard 72333f47d4e83616630ff3b0ffe4c0faebcc3c45
+ * git revert --no-commit d1d403d22cbe24592d725f442835cf46fe60c8ac */
+void test_revert_workdir__automerge(void)
+{
+	git_commit *head, *commit;
+	git_oid head_oid, revert_oid;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "caf99de3a49827117bb66721010eac461b06a80c", 0, "file1.txt" },
+		{ 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
+		{ 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
+		{ 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
+	};
+
+	git_oid_fromstr(&head_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	git_oid_fromstr(&revert_oid, "d1d403d22cbe24592d725f442835cf46fe60c8ac");
+	cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid));
+	cl_git_pass(git_revert(repo, commit, NULL));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 4));
+
+	git_commit_free(commit);
+	git_commit_free(head);
+}
+
+/* git revert --no-commit 72333f47d4e83616630ff3b0ffe4c0faebcc3c45 */
+void test_revert_workdir__conflicts(void)
+{
+	git_reference *head_ref;
+	git_commit *head, *commit;
+	git_oid revert_oid;
+	git_buf conflicting_buf = GIT_BUF_INIT, mergemsg_buf = GIT_BUF_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "7731926a337c4eaba1e2187d90ebfa0a93659382", 1, "file1.txt" },
+		{ 0100644, "4b8fcff56437e60f58e9a6bc630dd242ebf6ea2c", 2, "file1.txt" },
+		{ 0100644, "3a3ef367eaf3fe79effbfb0a56b269c04c2b59fe", 3, "file1.txt" },
+		{ 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
+		{ 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
+		{ 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
+	};
+
+	git_oid_fromstr(&revert_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45");
+
+	cl_git_pass(git_repository_head(&head_ref, repo));
+	cl_git_pass(git_reference_peel((git_object **)&head, head_ref, GIT_OBJ_COMMIT));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid));
+	cl_git_pass(git_revert(repo, commit, NULL));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 6));
+
+	cl_git_pass(git_futils_readbuffer(&conflicting_buf,
+		TEST_REPO_PATH "/file1.txt"));
+	cl_assert(strcmp(conflicting_buf.ptr, "!File one!\n" \
+		"!File one!\n" \
+		"File one!\n" \
+		"File one\n" \
+		"File one\n" \
+		"File one\n" \
+		"File one\n" \
+		"File one\n" \
+		"File one\n" \
+		"File one\n" \
+		"<<<<<<< HEAD\n" \
+		"File one!\n" \
+		"!File one!\n" \
+		"!File one!\n" \
+		"!File one!\n" \
+		"=======\n" \
+		"File one\n" \
+		"File one\n" \
+		"File one\n" \
+		"File one\n" \
+		">>>>>>> parent of 72333f4... automergeable changes\n") == 0);
+
+	cl_assert(git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
+	cl_git_pass(git_futils_readbuffer(&mergemsg_buf,
+		TEST_REPO_PATH "/.git/MERGE_MSG"));
+	cl_assert(strcmp(mergemsg_buf.ptr,
+		"Revert \"automergeable changes\"\n" \
+		"\n" \
+		"This reverts commit 72333f47d4e83616630ff3b0ffe4c0faebcc3c45.\n"
+		"\n" \
+		"Conflicts:\n" \
+		"\tfile1.txt\n") == 0);
+
+	git_commit_free(commit);
+	git_commit_free(head);
+	git_reference_free(head_ref);
+	git_buf_free(&mergemsg_buf);
+	git_buf_free(&conflicting_buf);
+}
+
+/* git reset --hard 39467716290f6df775a91cdb9a4eb39295018145
+ * git revert --no-commit ebb03002cee5d66c7732dd06241119fe72ab96a5
+*/
+void test_revert_workdir__orphan(void)
+{
+	git_commit *head, *commit;
+	git_oid head_oid, revert_oid;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "296a6d3be1dff05c5d1f631d2459389fa7b619eb", 0, "file-mainline.txt" },
+	};
+
+	git_oid_fromstr(&head_oid, "39467716290f6df775a91cdb9a4eb39295018145");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	git_oid_fromstr(&revert_oid, "ebb03002cee5d66c7732dd06241119fe72ab96a5");
+	cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid));
+	cl_git_pass(git_revert(repo, commit, NULL));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 1));
+
+	git_commit_free(commit);
+	git_commit_free(head);
+}
+
+/*
+ * revert the same commit twice (when the first reverts cleanly):
+ *
+ * git revert 2d440f2
+ * git revert 2d440f2
+ */
+void test_revert_workdir__again(void)
+{
+	git_reference *head_ref;
+	git_commit *orig_head;
+	git_tree *reverted_tree;
+	git_oid reverted_tree_oid, reverted_commit_oid;
+	git_signature *signature;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "7731926a337c4eaba1e2187d90ebfa0a93659382", 0, "file1.txt" },
+		{ 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
+		{ 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
+		{ 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
+	};
+
+	cl_git_pass(git_repository_head(&head_ref, repo));
+	cl_git_pass(git_reference_peel((git_object **)&orig_head, head_ref, GIT_OBJ_COMMIT));
+	cl_git_pass(git_reset(repo, (git_object *)orig_head, GIT_RESET_HARD, NULL));
+
+	cl_git_pass(git_revert(repo, orig_head, NULL));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 4));
+
+	cl_git_pass(git_index_write_tree(&reverted_tree_oid, repo_index));
+	cl_git_pass(git_tree_lookup(&reverted_tree, repo, &reverted_tree_oid));
+
+	cl_git_pass(git_signature_new(&signature, "Reverter", "reverter at example.org", time(NULL), 0));
+	cl_git_pass(git_commit_create(&reverted_commit_oid, repo, "HEAD", signature, signature, NULL, "Reverted!", reverted_tree, 1, (const git_commit **)&orig_head));
+
+	cl_git_pass(git_revert(repo, orig_head, NULL));
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 4));
+
+	git_signature_free(signature);
+	git_tree_free(reverted_tree);
+	git_commit_free(orig_head);
+	git_reference_free(head_ref);
+}
+
+/* git reset --hard 72333f47d4e83616630ff3b0ffe4c0faebcc3c45
+ * git revert --no-commit d1d403d22cbe24592d725f442835cf46fe60c8ac */
+void test_revert_workdir__again_after_automerge(void)
+{
+	git_commit *head, *commit;
+	git_tree *reverted_tree;
+	git_oid head_oid, revert_oid, reverted_tree_oid, reverted_commit_oid;
+	git_signature *signature;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "caf99de3a49827117bb66721010eac461b06a80c", 0, "file1.txt" },
+		{ 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
+		{ 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
+		{ 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
+	};
+
+	struct merge_index_entry second_revert_entries[] = {
+		{ 0100644, "3a3ef367eaf3fe79effbfb0a56b269c04c2b59fe", 1, "file1.txt" },
+		{ 0100644, "caf99de3a49827117bb66721010eac461b06a80c", 2, "file1.txt" },
+		{ 0100644, "747726e021bc5f44b86de60e3032fd6f9f1b8383", 3, "file1.txt" },
+		{ 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
+		{ 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
+		{ 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
+	};
+
+	git_oid_fromstr(&head_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	git_oid_fromstr(&revert_oid, "d1d403d22cbe24592d725f442835cf46fe60c8ac");
+	cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid));
+	cl_git_pass(git_revert(repo, commit, NULL));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 4));
+
+	cl_git_pass(git_index_write_tree(&reverted_tree_oid, repo_index));
+	cl_git_pass(git_tree_lookup(&reverted_tree, repo, &reverted_tree_oid));
+
+	cl_git_pass(git_signature_new(&signature, "Reverter", "reverter at example.org", time(NULL), 0));
+	cl_git_pass(git_commit_create(&reverted_commit_oid, repo, "HEAD", signature, signature, NULL, "Reverted!", reverted_tree, 1, (const git_commit **)&head));
+
+	cl_git_pass(git_revert(repo, commit, NULL));
+	cl_assert(merge_test_index(repo_index, second_revert_entries, 6));
+
+	git_signature_free(signature);
+	git_tree_free(reverted_tree);
+	git_commit_free(commit);
+	git_commit_free(head);
+}
+
+/*
+ * revert the same commit twice (when the first reverts cleanly):
+ *
+ * git revert 2d440f2
+ * git revert 2d440f2
+ */
+void test_revert_workdir__again_after_edit(void)
+{
+	git_reference *head_ref;
+	git_commit *orig_head, *commit;
+	git_tree *reverted_tree;
+	git_oid orig_head_oid, revert_oid, reverted_tree_oid, reverted_commit_oid;
+	git_signature *signature;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "3721552e06c4bdc7d478e0674e6304888545d5fd", 0, "file1.txt" },
+		{ 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
+		{ 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
+		{ 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
+	};
+
+	cl_git_pass(git_repository_head(&head_ref, repo));
+
+	cl_git_pass(git_oid_fromstr(&orig_head_oid, "399fb3aba3d9d13f7d40a9254ce4402067ef3149"));
+	cl_git_pass(git_commit_lookup(&orig_head, repo, &orig_head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)orig_head, GIT_RESET_HARD, NULL));
+
+	cl_git_pass(git_oid_fromstr(&revert_oid, "2d440f2b3147d3dc7ad1085813478d6d869d5a4d"));
+	cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid));
+
+	cl_git_pass(git_revert(repo, commit, NULL));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 4));
+
+	cl_git_pass(git_index_write_tree(&reverted_tree_oid, repo_index));
+	cl_git_pass(git_tree_lookup(&reverted_tree, repo, &reverted_tree_oid));
+
+	cl_git_pass(git_signature_new(&signature, "Reverter", "reverter at example.org", time(NULL), 0));
+	cl_git_pass(git_commit_create(&reverted_commit_oid, repo, "HEAD", signature, signature, NULL, "Reverted!", reverted_tree, 1, (const git_commit **)&orig_head));
+
+	cl_git_pass(git_revert(repo, commit, NULL));
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 4));
+
+	git_signature_free(signature);
+	git_tree_free(reverted_tree);
+	git_commit_free(commit);
+	git_commit_free(orig_head);
+	git_reference_free(head_ref);
+}
+
+/*
+ * revert the same commit twice (when the first reverts cleanly):
+ *
+ * git reset --hard 75ec9929465623f17ff3ad68c0438ea56faba815
+ * git revert 97e52d5e81f541080cd6b92829fb85bc4d81d90b
+ */
+void test_revert_workdir__again_after_edit_two(void)
+{
+	git_buf diff_buf = GIT_BUF_INIT;
+	git_config *config;
+	git_oid head_commit_oid, revert_commit_oid;
+	git_commit *head_commit, *revert_commit;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "a8c86221b400b836010567cc3593db6e96c1a83a", 1, "file.txt" },
+		{ 0100644, "46ff0854663aeb2182b9838c8da68e33ac23bc1e", 2, "file.txt" },
+		{ 0100644, "21a96a98ed84d45866e1de6e266fd3a61a4ae9dc", 3, "file.txt" },
+	};
+
+	cl_git_pass(git_repository_config(&config, repo));
+	cl_git_pass(git_config_set_bool(config, "core.autocrlf", 0));
+
+	cl_git_pass(git_oid_fromstr(&head_commit_oid, "75ec9929465623f17ff3ad68c0438ea56faba815"));
+	cl_git_pass(git_commit_lookup(&head_commit, repo, &head_commit_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head_commit, GIT_RESET_HARD, NULL));
+
+	cl_git_pass(git_oid_fromstr(&revert_commit_oid, "97e52d5e81f541080cd6b92829fb85bc4d81d90b"));
+	cl_git_pass(git_commit_lookup(&revert_commit, repo, &revert_commit_oid));
+
+	cl_git_pass(git_revert(repo, revert_commit, NULL));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 3));
+
+	cl_git_pass(git_futils_readbuffer(&diff_buf, "revert/file.txt"));
+	cl_assert_equal_s(
+			"a\n" \
+			"<<<<<<< HEAD\n" \
+			"=======\n" \
+			"a\n" \
+			">>>>>>> parent of 97e52d5... Revert me\n" \
+			"a\n" \
+			"a\n" \
+			"a\n" \
+			"a\n" \
+			"ab",
+		diff_buf.ptr);
+
+	git_commit_free(revert_commit);
+	git_commit_free(head_commit);
+	git_config_free(config);
+	git_buf_free(&diff_buf);
+}
+
+/* git reset --hard 72333f47d4e83616630ff3b0ffe4c0faebcc3c45
+ * git revert --no-commit d1d403d22cbe24592d725f442835cf46fe60c8ac */
+void test_revert_workdir__conflict_use_ours(void)
+{
+	git_commit *head, *commit;
+	git_oid head_oid, revert_oid;
+	git_revert_options opts = GIT_REVERT_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "caf99de3a49827117bb66721010eac461b06a80c", 0, "file1.txt" },
+		{ 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
+		{ 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
+		{ 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
+	};
+
+	struct merge_index_entry merge_filesystem_entries[] = {
+		{ 0100644, "caf99de3a49827117bb66721010eac461b06a80c", 0, "file1.txt" },
+		{ 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
+		{ 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
+		{ 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
+	};
+
+	opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_USE_OURS;
+
+	git_oid_fromstr(&head_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	git_oid_fromstr(&revert_oid, "d1d403d22cbe24592d725f442835cf46fe60c8ac");
+	cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid));
+	cl_git_pass(git_revert(repo, commit, &opts));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 4));
+	cl_assert(merge_test_workdir(repo, merge_filesystem_entries, 4));
+
+	git_commit_free(commit);
+	git_commit_free(head);
+}
+
+/* git reset --hard cef56612d71a6af8d8015691e4865f7fece905b5
+ * git revert --no-commit 55568c8de5322ff9a95d72747a239cdb64a19965
+ */
+void test_revert_workdir__rename_1_of_2(void)
+{
+	git_commit *head, *commit;
+	git_oid head_oid, revert_oid;
+	git_revert_options opts = GIT_REVERT_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "747726e021bc5f44b86de60e3032fd6f9f1b8383", 0, "file1.txt" },
+		{ 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
+		{ 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
+		{ 0100644, "55acf326a69f0aab7a974ec53ffa55a50bcac14e", 3, "file4.txt" },
+		{ 0100644, "55acf326a69f0aab7a974ec53ffa55a50bcac14e", 1, "file5.txt" },
+		{ 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 2, "file6.txt" },
+	};
+
+	opts.merge_opts.tree_flags |= GIT_MERGE_TREE_FIND_RENAMES;
+	opts.merge_opts.rename_threshold = 50;
+
+	git_oid_fromstr(&head_oid, "cef56612d71a6af8d8015691e4865f7fece905b5");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	git_oid_fromstr(&revert_oid, "55568c8de5322ff9a95d72747a239cdb64a19965");
+	cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid));
+	cl_git_pass(git_revert(repo, commit, &opts));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 6));
+
+	git_commit_free(commit);
+	git_commit_free(head);
+}
+
+/* git reset --hard 55568c8de5322ff9a95d72747a239cdb64a19965
+ * git revert --no-commit HEAD~1 */
+void test_revert_workdir__rename(void)
+{
+	git_commit *head, *commit;
+	git_oid head_oid, revert_oid;
+	git_revert_options opts = GIT_REVERT_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "55acf326a69f0aab7a974ec53ffa55a50bcac14e", 1, "file4.txt" },
+		{ 0100644, "55acf326a69f0aab7a974ec53ffa55a50bcac14e", 2, "file5.txt" },
+	};
+
+	struct merge_name_entry merge_name_entries[] = {
+		{ "file4.txt", "file5.txt", "" },
+	};
+
+	opts.merge_opts.tree_flags |= GIT_MERGE_TREE_FIND_RENAMES;
+	opts.merge_opts.rename_threshold = 50;
+
+	git_oid_fromstr(&head_oid, "55568c8de5322ff9a95d72747a239cdb64a19965");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	git_oid_fromstr(&revert_oid, "0aa8c7e40d342fff78d60b29a4ba8e993ed79c51");
+	cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid));
+	cl_git_pass(git_revert(repo, commit, &opts));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 2));
+	cl_assert(merge_test_names(repo_index, merge_name_entries, 1));
+
+	git_commit_free(commit);
+	git_commit_free(head);
+}
+
+/* git revert --no-commit HEAD */
+void test_revert_workdir__head(void)
+{
+	git_reference *head;
+	git_commit *commit;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "7731926a337c4eaba1e2187d90ebfa0a93659382", 0, "file1.txt" },
+		{ 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
+		{ 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
+		{ 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
+	};
+
+	/* HEAD is 2d440f2b3147d3dc7ad1085813478d6d869d5a4d */
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_peel((git_object **)&commit, head, GIT_OBJ_COMMIT));
+	cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL));
+	cl_git_pass(git_revert(repo, commit, NULL));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 4));
+	cl_assert(merge_test_workdir(repo, merge_index_entries, 4));
+
+	git_reference_free(head);
+	git_commit_free(commit);
+}
+
+void test_revert_workdir__nonmerge_fails_mainline_specified(void)
+{
+	git_reference *head;
+	git_commit *commit;
+	git_revert_options opts = GIT_REVERT_OPTIONS_INIT;
+
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_peel((git_object **)&commit, head, GIT_OBJ_COMMIT));
+
+	opts.mainline = 1;
+	cl_must_fail(git_revert(repo, commit, &opts));
+	cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
+	cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/REVERT_HEAD"));
+
+	git_reference_free(head);
+	git_commit_free(commit);
+}
+
+/* git reset --hard 5acdc74af27172ec491d213ee36cea7eb9ef2579
+ * git revert HEAD */
+void test_revert_workdir__merge_fails_without_mainline_specified(void)
+{
+	git_commit *head;
+	git_oid head_oid;
+
+	git_oid_fromstr(&head_oid, "5acdc74af27172ec491d213ee36cea7eb9ef2579");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	cl_must_fail(git_revert(repo, head, NULL));
+	cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
+	cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/REVERT_HEAD"));
+
+	git_commit_free(head);
+}
+
+/* git reset --hard 5acdc74af27172ec491d213ee36cea7eb9ef2579
+ * git revert HEAD -m1 --no-commit */
+void test_revert_workdir__merge_first_parent(void)
+{
+	git_commit *head;
+	git_oid head_oid;
+	git_revert_options opts = GIT_REVERT_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "296a6d3be1dff05c5d1f631d2459389fa7b619eb", 0, "file-mainline.txt" },
+		{ 0100644, "0cdb66192ee192f70f891f05a47636057420e871", 0, "file1.txt" },
+		{ 0100644, "73ec36fa120f8066963a0bc9105bb273dbd903d7", 0, "file2.txt" },
+	};
+
+	opts.mainline = 1;
+
+	git_oid_fromstr(&head_oid, "5acdc74af27172ec491d213ee36cea7eb9ef2579");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	cl_git_pass(git_revert(repo, head, &opts));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 3));
+
+	git_commit_free(head);
+}
+
+void test_revert_workdir__merge_second_parent(void)
+{
+	git_commit *head;
+	git_oid head_oid;
+	git_revert_options opts = GIT_REVERT_OPTIONS_INIT;
+
+	struct merge_index_entry merge_index_entries[] = {
+		{ 0100644, "33c6fd981c49a2abf2971482089350bfc5cda8ea", 0, "file-branch.txt" },
+		{ 0100644, "0cdb66192ee192f70f891f05a47636057420e871", 0, "file1.txt" },
+		{ 0100644, "73ec36fa120f8066963a0bc9105bb273dbd903d7", 0, "file2.txt" },
+	};
+
+	opts.mainline = 2;
+
+	git_oid_fromstr(&head_oid, "5acdc74af27172ec491d213ee36cea7eb9ef2579");
+	cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+	cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
+
+	cl_git_pass(git_revert(repo, head, &opts));
+
+	cl_assert(merge_test_index(repo_index, merge_index_entries, 3));
+
+	git_commit_free(head);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revwalk/basic.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revwalk/basic.c
new file mode 100755
index 0000000..7e50452
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revwalk/basic.c
@@ -0,0 +1,439 @@
+#include "clar_libgit2.h"
+
+/*
+	*   a4a7dce [0] Merge branch 'master' into br2
+	|\
+	| * 9fd738e [1] a fourth commit
+	| * 4a202b3 [2] a third commit
+	* | c47800c [3] branch commit one
+	|/
+	* 5b5b025 [5] another commit
+	* 8496071 [4] testing
+*/
+static const char *commit_head = "a4a7dce85cf63874e984719f4fdd239f5145052f";
+
+static const char *commit_ids[] = {
+	"a4a7dce85cf63874e984719f4fdd239f5145052f", /* 0 */
+	"9fd738e8f7967c078dceed8190330fc8648ee56a", /* 1 */
+	"4a202b346bb0fb0db7eff3cffeb3c70babbd2045", /* 2 */
+	"c47800c7266a2be04c571c04d5a6614691ea99bd", /* 3 */
+	"8496071c1b46c854b31185ea97743be6a8774479", /* 4 */
+	"5b5b025afb0b4c913b4c338a42934a3863bf3644", /* 5 */
+};
+
+/* Careful: there are two possible topological sorts */
+static const int commit_sorting_topo[][6] = {
+	{0, 1, 2, 3, 5, 4}, {0, 3, 1, 2, 5, 4}
+};
+
+static const int commit_sorting_time[][6] = {
+	{0, 3, 1, 2, 5, 4}
+};
+
+static const int commit_sorting_topo_reverse[][6] = {
+	{4, 5, 3, 2, 1, 0}, {4, 5, 2, 1, 3, 0}
+};
+
+static const int commit_sorting_time_reverse[][6] = {
+	{4, 5, 2, 1, 3, 0}
+};
+
+static const int commit_sorting_segment[][6] = {
+	{1, 2, -1, -1, -1, -1}
+};
+
+#define commit_count 6
+static const int result_bytes = 24;
+
+
+static int get_commit_index(git_oid *raw_oid)
+{
+	int i;
+	char oid[GIT_OID_HEXSZ];
+
+	git_oid_fmt(oid, raw_oid);
+
+	for (i = 0; i < commit_count; ++i)
+		if (memcmp(oid, commit_ids[i], GIT_OID_HEXSZ) == 0)
+			return i;
+
+	return -1;
+}
+
+static int test_walk_only(git_revwalk *walk,
+		const int possible_results[][commit_count], int results_count)
+{
+	git_oid oid;
+	int i;
+	int result_array[commit_count];
+
+	for (i = 0; i < commit_count; ++i)
+		result_array[i] = -1;
+
+	i = 0;
+	while (git_revwalk_next(&oid, walk) == 0) {
+		result_array[i++] = get_commit_index(&oid);
+		/*{
+			char str[GIT_OID_HEXSZ+1];
+			git_oid_fmt(str, &oid);
+			str[GIT_OID_HEXSZ] = 0;
+			printf("  %d) %s\n", i, str);
+		}*/
+	}
+
+	for (i = 0; i < results_count; ++i)
+		if (memcmp(possible_results[i],
+				result_array, result_bytes) == 0)
+			return 0;
+
+	return GIT_ERROR;
+}
+
+static int test_walk(git_revwalk *walk, const git_oid *root,
+		int flags, const int possible_results[][6], int results_count)
+{
+	git_revwalk_sorting(walk, flags);
+	git_revwalk_push(walk, root);
+
+	return test_walk_only(walk, possible_results, results_count);
+}
+
+static git_repository *_repo = NULL;
+static git_revwalk *_walk = NULL;
+static const char *_fixture = NULL;
+
+void test_revwalk_basic__initialize(void)
+{
+}
+
+void test_revwalk_basic__cleanup(void)
+{
+	git_revwalk_free(_walk);
+
+	if (_fixture)
+		cl_git_sandbox_cleanup();
+	else
+		git_repository_free(_repo);
+
+	_fixture = NULL;
+	_repo = NULL;
+	_walk = NULL;
+}
+
+static void revwalk_basic_setup_walk(const char *fixture)
+{
+	if (fixture) {
+		_fixture = fixture;
+		_repo = cl_git_sandbox_init(fixture);
+	} else {
+		cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git")));
+	}
+
+	cl_git_pass(git_revwalk_new(&_walk, _repo));
+}
+
+void test_revwalk_basic__sorting_modes(void)
+{
+	git_oid id;
+
+	revwalk_basic_setup_walk(NULL);
+
+	git_oid_fromstr(&id, commit_head);
+
+	cl_git_pass(test_walk(_walk, &id, GIT_SORT_TIME, commit_sorting_time, 1));
+	cl_git_pass(test_walk(_walk, &id, GIT_SORT_TOPOLOGICAL, commit_sorting_topo, 2));
+	cl_git_pass(test_walk(_walk, &id, GIT_SORT_TIME | GIT_SORT_REVERSE, commit_sorting_time_reverse, 1));
+	cl_git_pass(test_walk(_walk, &id, GIT_SORT_TOPOLOGICAL | GIT_SORT_REVERSE, commit_sorting_topo_reverse, 2));
+}
+
+void test_revwalk_basic__glob_heads(void)
+{
+	int i = 0;
+	git_oid oid;
+
+	revwalk_basic_setup_walk(NULL);
+
+	cl_git_pass(git_revwalk_push_glob(_walk, "heads"));
+
+	while (git_revwalk_next(&oid, _walk) == 0) {
+		i++;
+	}
+
+	/* git log --branches --oneline | wc -l => 14 */
+	cl_assert_equal_i(i, 14);
+}
+
+void test_revwalk_basic__glob_heads_with_invalid(void)
+{
+	int i;
+	git_oid oid;
+
+	revwalk_basic_setup_walk("testrepo");
+
+	cl_git_mkfile("testrepo/.git/refs/heads/garbage", "not-a-ref");
+	cl_git_pass(git_revwalk_push_glob(_walk, "heads"));
+
+	for (i = 0; !git_revwalk_next(&oid, _walk); ++i)
+		/* walking */;
+
+	/* git log --branches --oneline | wc -l => 16 */
+	cl_assert_equal_i(18, i);
+}
+
+void test_revwalk_basic__push_head(void)
+{
+	int i = 0;
+	git_oid oid;
+
+	revwalk_basic_setup_walk(NULL);
+
+	cl_git_pass(git_revwalk_push_head(_walk));
+
+	while (git_revwalk_next(&oid, _walk) == 0) {
+		i++;
+	}
+
+	/* git log HEAD --oneline | wc -l => 7 */
+	cl_assert_equal_i(i, 7);
+}
+
+void test_revwalk_basic__push_head_hide_ref(void)
+{
+	int i = 0;
+	git_oid oid;
+
+	revwalk_basic_setup_walk(NULL);
+
+	cl_git_pass(git_revwalk_push_head(_walk));
+	cl_git_pass(git_revwalk_hide_ref(_walk, "refs/heads/packed-test"));
+
+	while (git_revwalk_next(&oid, _walk) == 0) {
+		i++;
+	}
+
+	/* git log HEAD --oneline --not refs/heads/packed-test | wc -l => 4 */
+	cl_assert_equal_i(i, 4);
+}
+
+void test_revwalk_basic__push_head_hide_ref_nobase(void)
+{
+	int i = 0;
+	git_oid oid;
+
+	revwalk_basic_setup_walk(NULL);
+
+	cl_git_pass(git_revwalk_push_head(_walk));
+	cl_git_pass(git_revwalk_hide_ref(_walk, "refs/heads/packed"));
+
+	while (git_revwalk_next(&oid, _walk) == 0) {
+		i++;
+	}
+
+	/* git log HEAD --oneline --not refs/heads/packed | wc -l => 7 */
+	cl_assert_equal_i(i, 7);
+}
+
+/*
+* $ git rev-list HEAD 5b5b02 ^refs/heads/packed-test
+* a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+* be3563ae3f795b2b4353bcce3a527ad0a4f7f644
+* c47800c7266a2be04c571c04d5a6614691ea99bd
+* 9fd738e8f7967c078dceed8190330fc8648ee56a
+
+* $ git log HEAD 5b5b02 --oneline --not refs/heads/packed-test | wc -l => 4
+* a65fedf
+* be3563a Merge branch 'br2'
+* c47800c branch commit one
+* 9fd738e a fourth commit
+*/
+void test_revwalk_basic__multiple_push_1(void)
+{
+	int i = 0;
+	git_oid oid;
+
+	revwalk_basic_setup_walk(NULL);
+
+	cl_git_pass(git_revwalk_push_head(_walk));
+
+	cl_git_pass(git_revwalk_hide_ref(_walk, "refs/heads/packed-test"));
+
+	cl_git_pass(git_oid_fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644"));
+	cl_git_pass(git_revwalk_push(_walk, &oid));
+
+	while (git_revwalk_next(&oid, _walk) == 0)
+		i++;
+
+	cl_assert_equal_i(i, 4);
+}
+
+/*
+* Difference between test_revwalk_basic__multiple_push_1 and 
+* test_revwalk_basic__multiple_push_2 is in the order reference
+* refs/heads/packed-test and commit 5b5b02 are pushed. 
+* revwalk should return same commits in both the tests.
+
+* $ git rev-list 5b5b02 HEAD ^refs/heads/packed-test
+* a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+* be3563ae3f795b2b4353bcce3a527ad0a4f7f644
+* c47800c7266a2be04c571c04d5a6614691ea99bd
+* 9fd738e8f7967c078dceed8190330fc8648ee56a
+
+* $ git log 5b5b02 HEAD --oneline --not refs/heads/packed-test | wc -l => 4
+* a65fedf
+* be3563a Merge branch 'br2'
+* c47800c branch commit one
+* 9fd738e a fourth commit
+*/
+void test_revwalk_basic__multiple_push_2(void)
+{
+	int i = 0;
+	git_oid oid;
+
+	revwalk_basic_setup_walk(NULL);
+
+	cl_git_pass(git_oid_fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644"));
+	cl_git_pass(git_revwalk_push(_walk, &oid));
+
+	cl_git_pass(git_revwalk_hide_ref(_walk, "refs/heads/packed-test"));
+
+	cl_git_pass(git_revwalk_push_head(_walk));
+
+	while (git_revwalk_next(&oid, _walk) == 0)
+		i++;
+
+	cl_assert_equal_i(i, 4);
+}
+
+void test_revwalk_basic__disallow_non_commit(void)
+{
+	git_oid oid;
+
+	revwalk_basic_setup_walk(NULL);
+
+	cl_git_pass(git_oid_fromstr(&oid, "521d87c1ec3aef9824daf6d96cc0ae3710766d91"));
+	cl_git_fail(git_revwalk_push(_walk, &oid));
+}
+
+void test_revwalk_basic__hide_then_push(void)
+{
+	git_oid oid;
+	int i = 0;
+
+	revwalk_basic_setup_walk(NULL);
+	cl_git_pass(git_oid_fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644"));
+
+	cl_git_pass(git_revwalk_hide(_walk, &oid));
+	cl_git_pass(git_revwalk_push(_walk, &oid));
+
+	while (git_revwalk_next(&oid, _walk) == 0)
+		i++;
+
+	cl_assert_equal_i(i, 0);
+}
+
+void test_revwalk_basic__push_range(void)
+{
+	revwalk_basic_setup_walk(NULL);
+
+	git_revwalk_reset(_walk);
+	git_revwalk_sorting(_walk, 0);
+	cl_git_pass(git_revwalk_push_range(_walk, "9fd738e~2..9fd738e"));
+	cl_git_pass(test_walk_only(_walk, commit_sorting_segment, 1));
+}
+
+void test_revwalk_basic__push_mixed(void)
+{
+	git_oid oid;
+	int i = 0;
+
+	revwalk_basic_setup_walk(NULL);
+
+	git_revwalk_reset(_walk);
+	git_revwalk_sorting(_walk, 0);
+	cl_git_pass(git_revwalk_push_glob(_walk, "tags"));
+
+	while (git_revwalk_next(&oid, _walk) == 0) {
+		i++;
+	}
+
+	/* git rev-list --count --glob=tags #=> 9 */
+	cl_assert_equal_i(9, i);
+}
+
+void test_revwalk_basic__push_all(void)
+{
+	git_oid oid;
+	int i = 0;
+
+	revwalk_basic_setup_walk(NULL);
+
+	git_revwalk_reset(_walk);
+	git_revwalk_sorting(_walk, 0);
+	cl_git_pass(git_revwalk_push_glob(_walk, "*"));
+
+	while (git_revwalk_next(&oid, _walk) == 0) {
+		i++;
+	}
+
+	/* git rev-list --count --all #=> 15 */
+	cl_assert_equal_i(15, i);
+}
+
+/*
+* $ git rev-list br2 master e908
+* a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+* e90810b8df3e80c413d903f631643c716887138d
+* 6dcf9bf7541ee10456529833502442f385010c3d
+* a4a7dce85cf63874e984719f4fdd239f5145052f
+* be3563ae3f795b2b4353bcce3a527ad0a4f7f644
+* c47800c7266a2be04c571c04d5a6614691ea99bd
+* 9fd738e8f7967c078dceed8190330fc8648ee56a
+* 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+* 5b5b025afb0b4c913b4c338a42934a3863bf3644
+* 8496071c1b46c854b31185ea97743be6a8774479
+*/
+
+void test_revwalk_basic__mimic_git_rev_list(void)
+{
+   git_oid oid;
+
+   revwalk_basic_setup_walk(NULL);
+   git_revwalk_sorting(_walk, GIT_SORT_TIME);
+
+   cl_git_pass(git_revwalk_push_ref(_walk, "refs/heads/br2"));
+   cl_git_pass(git_revwalk_push_ref(_walk, "refs/heads/master"));
+   cl_git_pass(git_oid_fromstr(&oid, "e90810b8df3e80c413d903f631643c716887138d"));
+   cl_git_pass(git_revwalk_push(_walk, &oid));
+
+   cl_git_pass(git_revwalk_next(&oid, _walk));
+   cl_assert(!git_oid_streq(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"));
+
+   cl_git_pass(git_revwalk_next(&oid, _walk));
+   cl_assert(!git_oid_streq(&oid, "e90810b8df3e80c413d903f631643c716887138d"));
+
+   cl_git_pass(git_revwalk_next(&oid, _walk));
+   cl_assert(!git_oid_streq(&oid, "6dcf9bf7541ee10456529833502442f385010c3d"));
+
+   cl_git_pass(git_revwalk_next(&oid, _walk));
+   cl_assert(!git_oid_streq(&oid, "a4a7dce85cf63874e984719f4fdd239f5145052f"));
+
+   cl_git_pass(git_revwalk_next(&oid, _walk));
+   cl_assert(!git_oid_streq(&oid, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"));
+
+   cl_git_pass(git_revwalk_next(&oid, _walk));
+   cl_assert(!git_oid_streq(&oid, "c47800c7266a2be04c571c04d5a6614691ea99bd"));
+
+   cl_git_pass(git_revwalk_next(&oid, _walk));
+   cl_assert(!git_oid_streq(&oid, "9fd738e8f7967c078dceed8190330fc8648ee56a"));
+
+   cl_git_pass(git_revwalk_next(&oid, _walk));
+   cl_assert(!git_oid_streq(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045"));
+
+   cl_git_pass(git_revwalk_next(&oid, _walk));
+   cl_assert(!git_oid_streq(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644"));
+
+   cl_git_pass(git_revwalk_next(&oid, _walk));
+   cl_assert(!git_oid_streq(&oid, "8496071c1b46c854b31185ea97743be6a8774479"));
+
+   cl_git_fail_with(git_revwalk_next(&oid, _walk), GIT_ITEROVER);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revwalk/hidecb.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revwalk/hidecb.c
new file mode 100755
index 0000000..14cf39a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revwalk/hidecb.c
@@ -0,0 +1,201 @@
+#include "clar_libgit2.h"
+/*
+*   a4a7dce [0] Merge branch 'master' into br2
+|\
+| * 9fd738e [1] a fourth commit
+| * 4a202b3 [2] a third commit
+* | c47800c [3] branch commit one
+|/
+* 5b5b025 [5] another commit
+* 8496071 [4] testing
+*/
+static const char *commit_head = "a4a7dce85cf63874e984719f4fdd239f5145052f";
+
+static const char *commit_strs[] = {
+	"a4a7dce85cf63874e984719f4fdd239f5145052f", /* 0 */
+	"9fd738e8f7967c078dceed8190330fc8648ee56a", /* 1 */
+	"4a202b346bb0fb0db7eff3cffeb3c70babbd2045", /* 2 */
+	"c47800c7266a2be04c571c04d5a6614691ea99bd", /* 3 */
+	"8496071c1b46c854b31185ea97743be6a8774479", /* 4 */
+	"5b5b025afb0b4c913b4c338a42934a3863bf3644", /* 5 */
+};
+
+#define commit_count 6
+
+static git_oid commit_ids[commit_count];
+static git_oid _head_id;
+static git_repository *_repo;
+
+
+void test_revwalk_hidecb__initialize(void)
+{
+	int i;
+
+	cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git")));
+	cl_git_pass(git_oid_fromstr(&_head_id, commit_head));
+
+	for (i = 0; i < commit_count; i++)
+		cl_git_pass(git_oid_fromstr(&commit_ids[i], commit_strs[i]));
+
+}
+
+void test_revwalk_hidecb__cleanup(void)
+{
+	git_repository_free(_repo);
+	_repo = NULL;
+}
+
+/* Hide all commits */
+static int hide_every_commit_cb(const git_oid *commit_id, void *data)
+{
+	GIT_UNUSED(commit_id);
+	GIT_UNUSED(data);
+
+	return 1;
+}
+
+/* Do not hide anything */
+static int hide_none_cb(const git_oid *commit_id, void *data)
+{
+	GIT_UNUSED(commit_id);
+	GIT_UNUSED(data);
+
+	return 0;
+}
+
+/* Hide some commits */
+static int hide_commit_cb(const git_oid *commit_id, void *data)
+{
+	GIT_UNUSED(commit_id);
+	GIT_UNUSED(data);
+
+	return (git_oid_cmp(commit_id, &commit_ids[5]) == 0);
+}
+
+/* In payload data, pointer to a commit id is passed */
+static int hide_commit_use_payload_cb(const git_oid *commit_id, void *data)
+{
+	git_oid *hide_commit_id = data;
+
+	return (git_oid_cmp(commit_id, hide_commit_id) == 0);
+}
+
+void test_revwalk_hidecb__hide_all_cb(void)
+{
+	git_revwalk *walk;
+	git_oid id;
+
+	cl_git_pass(git_revwalk_new(&walk, _repo));
+	cl_git_pass(git_revwalk_add_hide_cb(walk, hide_every_commit_cb, NULL));
+	cl_git_pass(git_revwalk_push(walk, &_head_id));
+
+	/* First call to git_revwalk_next should return GIT_ITEROVER */
+	cl_assert_equal_i(GIT_ITEROVER, git_revwalk_next(&id, walk));
+
+	git_revwalk_free(walk);
+}
+
+
+void test_revwalk_hidecb__hide_none_cb(void)
+{
+	git_revwalk *walk;
+	int i, error;
+	git_oid id;
+
+	cl_git_pass(git_revwalk_new(&walk, _repo));
+	cl_git_pass(git_revwalk_add_hide_cb(walk, hide_none_cb, NULL));
+	cl_git_pass(git_revwalk_push(walk, &_head_id));
+
+	/* It should return all 6 commits */
+	i = 0;
+	while ((error = git_revwalk_next(&id, walk)) == 0)
+		i++;
+
+	cl_assert_equal_i(i, 6);
+	cl_assert_equal_i(error, GIT_ITEROVER);
+
+	git_revwalk_free(walk);
+}
+
+void test_revwalk_hidecb__add_hide_cb_multiple_times(void)
+{
+	git_revwalk *walk;
+
+	cl_git_pass(git_revwalk_new(&walk, _repo));
+	cl_git_pass(git_revwalk_add_hide_cb(walk, hide_every_commit_cb, NULL));
+	cl_git_fail(git_revwalk_add_hide_cb(walk, hide_every_commit_cb, NULL));
+
+	git_revwalk_free(walk);
+}
+
+void test_revwalk_hidecb__add_hide_cb_during_walking(void)
+{
+	git_revwalk *walk;
+	git_oid id;
+	int error;
+
+	cl_git_pass(git_revwalk_new(&walk, _repo));
+	cl_git_pass(git_revwalk_push(walk, &_head_id));
+
+	/* Start walking without adding hide callback */
+	cl_git_pass(git_revwalk_next(&id, walk));
+
+	/* Now add hide callback */
+	cl_git_pass(git_revwalk_add_hide_cb(walk, hide_none_cb, NULL));
+
+	/* walk should be reset */
+	error = git_revwalk_next(&id, walk);
+	cl_assert_equal_i(error, GIT_ITEROVER);
+
+	git_revwalk_free(walk);
+}
+
+void test_revwalk_hidecb__hide_some_commits(void)
+{
+	git_revwalk *walk;
+	git_oid id;
+	int i, error;
+
+	cl_git_pass(git_revwalk_new(&walk, _repo));
+	cl_git_pass(git_revwalk_push(walk, &_head_id));
+
+	/* Add hide callback */
+	cl_git_pass(git_revwalk_add_hide_cb(walk, hide_commit_cb, NULL));
+
+	i = 0;
+	while ((error = git_revwalk_next(&id, walk)) == 0) {
+		cl_assert_equal_oid(&commit_ids[i], &id);
+		i++;
+	}
+
+	cl_assert_equal_i(i, 4);
+	cl_assert_equal_i(error, GIT_ITEROVER);
+
+	git_revwalk_free(walk);
+}
+
+void test_revwalk_hidecb__test_payload(void)
+{
+	git_revwalk *walk;
+	git_oid id;
+	int i, error;
+
+	cl_git_pass(git_revwalk_new(&walk, _repo));
+	cl_git_pass(git_revwalk_push(walk, &_head_id));
+
+	/* Add hide callback, pass id of parent of initial commit as payload data */
+	cl_git_pass(git_revwalk_add_hide_cb(walk, hide_commit_use_payload_cb, &commit_ids[5]));
+
+	i = 0;
+	while ((error = git_revwalk_next(&id, walk)) == 0) {
+		cl_assert_equal_oid(&commit_ids[i], &id);
+		i++;
+	}
+
+	/* walker should return four commits */
+	cl_assert_equal_i(i, 4);
+	cl_assert_equal_i(error, GIT_ITEROVER);
+
+	git_revwalk_free(walk);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revwalk/mergebase.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revwalk/mergebase.c
new file mode 100755
index 0000000..aafe97d
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revwalk/mergebase.c
@@ -0,0 +1,494 @@
+#include "clar_libgit2.h"
+#include "vector.h"
+#include <stdarg.h>
+
+static git_repository *_repo;
+static git_repository *_repo2;
+
+void test_revwalk_mergebase__initialize(void)
+{
+	cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git")));
+	cl_git_pass(git_repository_open(&_repo2, cl_fixture("twowaymerge.git")));
+}
+
+void test_revwalk_mergebase__cleanup(void)
+{
+	git_repository_free(_repo);
+	_repo = NULL;
+
+	git_repository_free(_repo2);
+	_repo2 = NULL;
+}
+
+void test_revwalk_mergebase__single1(void)
+{
+	git_oid result, one, two, expected;
+	size_t ahead, behind;
+
+	cl_git_pass(git_oid_fromstr(&one, "c47800c7266a2be04c571c04d5a6614691ea99bd "));
+	cl_git_pass(git_oid_fromstr(&two, "9fd738e8f7967c078dceed8190330fc8648ee56a"));
+	cl_git_pass(git_oid_fromstr(&expected, "5b5b025afb0b4c913b4c338a42934a3863bf3644"));
+
+	cl_git_pass(git_merge_base(&result, _repo, &one, &two));
+	cl_assert_equal_oid(&expected, &result);
+
+	cl_git_pass(git_graph_ahead_behind(&ahead, &behind, _repo, &one, &two));
+	cl_assert_equal_sz(ahead, 1);
+	cl_assert_equal_sz(behind, 2);
+
+	cl_git_pass(git_graph_ahead_behind(&ahead, &behind, _repo, &two, &one));
+	cl_assert_equal_sz(ahead,  2);
+	cl_assert_equal_sz(behind,  1);
+}
+
+void test_revwalk_mergebase__single2(void)
+{
+	git_oid result, one, two, expected;
+	size_t ahead, behind;
+
+	cl_git_pass(git_oid_fromstr(&one, "763d71aadf09a7951596c9746c024e7eece7c7af"));
+	cl_git_pass(git_oid_fromstr(&two, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"));
+	cl_git_pass(git_oid_fromstr(&expected, "c47800c7266a2be04c571c04d5a6614691ea99bd"));
+
+	cl_git_pass(git_merge_base(&result, _repo, &one, &two));
+	cl_assert_equal_oid(&expected, &result);
+
+	cl_git_pass(git_graph_ahead_behind( &ahead, &behind, _repo, &one, &two));
+	cl_assert_equal_sz(ahead,  1);
+	cl_assert_equal_sz(behind,  4);
+
+	cl_git_pass(git_graph_ahead_behind( &ahead, &behind, _repo, &two, &one));
+	cl_assert_equal_sz(ahead,  4);
+	cl_assert_equal_sz(behind,  1);
+}
+
+void test_revwalk_mergebase__merged_branch(void)
+{
+	git_oid result, one, two, expected;
+	size_t ahead, behind;
+
+	cl_git_pass(git_oid_fromstr(&one, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"));
+	cl_git_pass(git_oid_fromstr(&two, "9fd738e8f7967c078dceed8190330fc8648ee56a"));
+	cl_git_pass(git_oid_fromstr(&expected, "9fd738e8f7967c078dceed8190330fc8648ee56a"));
+
+	cl_git_pass(git_merge_base(&result, _repo, &one, &two));
+	cl_assert_equal_oid(&expected, &result);
+
+	cl_git_pass(git_merge_base(&result, _repo, &two, &one));
+	cl_assert_equal_oid(&expected, &result);
+
+	cl_git_pass(git_graph_ahead_behind(&ahead, &behind, _repo, &one, &two));
+	cl_assert_equal_sz(ahead,  3);
+	cl_assert_equal_sz(behind,  0);
+
+	cl_git_pass(git_graph_ahead_behind(&ahead, &behind, _repo, &two, &one));
+	cl_assert_equal_sz(ahead,  0);
+	cl_assert_equal_sz(behind,  3);
+}
+
+void test_revwalk_mergebase__two_way_merge(void)
+{
+	git_oid one, two;
+	size_t ahead, behind;
+
+	cl_git_pass(git_oid_fromstr(&one, "9b219343610c88a1187c996d0dc58330b55cee28"));
+	cl_git_pass(git_oid_fromstr(&two, "a953a018c5b10b20c86e69fef55ebc8ad4c5a417"));
+	cl_git_pass(git_graph_ahead_behind(&ahead, &behind, _repo2, &one, &two));
+
+	cl_assert_equal_sz(ahead,  8);
+	cl_assert_equal_sz(behind,  2);
+
+	cl_git_pass(git_graph_ahead_behind(&ahead, &behind, _repo2, &two, &one));
+
+	cl_assert_equal_sz(ahead,  2);
+	cl_assert_equal_sz(behind,  8);
+}
+
+void test_revwalk_mergebase__no_common_ancestor_returns_ENOTFOUND(void)
+{
+	git_oid result, one, two;
+	size_t ahead, behind;
+	int error;
+
+	cl_git_pass(git_oid_fromstr(&one, "763d71aadf09a7951596c9746c024e7eece7c7af"));
+	cl_git_pass(git_oid_fromstr(&two, "e90810b8df3e80c413d903f631643c716887138d"));
+
+	error = git_merge_base(&result, _repo, &one, &two);
+	cl_git_fail(error);
+
+	cl_assert_equal_i(GIT_ENOTFOUND, error);
+
+	cl_git_pass(git_graph_ahead_behind(&ahead, &behind, _repo, &one, &two));
+	cl_assert_equal_sz(4, ahead);
+	cl_assert_equal_sz(2, behind);
+}
+
+void test_revwalk_mergebase__prefer_youngest_merge_base(void)
+{
+	git_oid result, one, two, expected;
+
+	cl_git_pass(git_oid_fromstr(&one, "a4a7dce85cf63874e984719f4fdd239f5145052f"));
+	cl_git_pass(git_oid_fromstr(&two, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"));
+	cl_git_pass(git_oid_fromstr(&expected, "c47800c7266a2be04c571c04d5a6614691ea99bd"));
+
+	cl_git_pass(git_merge_base(&result, _repo, &one, &two));
+	cl_assert_equal_oid(&expected, &result);
+}
+
+void test_revwalk_mergebase__multiple_merge_bases(void)
+{
+	git_oid one, two, expected1, expected2;
+	git_oidarray result = {NULL, 0};
+
+	cl_git_pass(git_oid_fromstr(&one, "a4a7dce85cf63874e984719f4fdd239f5145052f"));
+	cl_git_pass(git_oid_fromstr(&two, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"));
+	cl_git_pass(git_oid_fromstr(&expected1, "c47800c7266a2be04c571c04d5a6614691ea99bd"));
+	cl_git_pass(git_oid_fromstr(&expected2, "9fd738e8f7967c078dceed8190330fc8648ee56a"));
+
+	cl_git_pass(git_merge_bases(&result, _repo, &one, &two));
+	cl_assert_equal_i(2, result.count);
+	cl_assert_equal_oid(&expected1, &result.ids[0]);
+	cl_assert_equal_oid(&expected2, &result.ids[1]);
+
+	git_oidarray_free(&result);
+}
+
+void test_revwalk_mergebase__multiple_merge_bases_many_commits(void)
+{
+	git_oid expected1, expected2;
+	git_oidarray result = {NULL, 0};
+
+	git_oid *input = git__malloc(sizeof(git_oid) * 2);
+
+	cl_git_pass(git_oid_fromstr(&input[0], "a4a7dce85cf63874e984719f4fdd239f5145052f"));
+	cl_git_pass(git_oid_fromstr(&input[1], "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"));
+	cl_git_pass(git_oid_fromstr(&expected1, "c47800c7266a2be04c571c04d5a6614691ea99bd"));
+	cl_git_pass(git_oid_fromstr(&expected2, "9fd738e8f7967c078dceed8190330fc8648ee56a"));
+
+	cl_git_pass(git_merge_bases_many(&result, _repo, 2, input));
+	cl_assert_equal_i(2, result.count);
+	cl_assert_equal_oid(&expected1, &result.ids[0]);
+	cl_assert_equal_oid(&expected2, &result.ids[1]);
+
+	git_oidarray_free(&result);
+	git__free(input);
+}
+
+void test_revwalk_mergebase__no_off_by_one_missing(void)
+{
+	git_oid result, one, two;
+
+	cl_git_pass(git_oid_fromstr(&one, "1a443023183e3f2bfbef8ac923cd81c1018a18fd"));
+	cl_git_pass(git_oid_fromstr(&two, "9f13f7d0a9402c681f91dc590cf7b5470e6a77d2"));
+	cl_git_pass(git_merge_base(&result, _repo, &one, &two));
+}
+
+static void assert_mergebase_many(const char *expected_sha, int count, ...)
+{
+	va_list ap;
+	int i; 
+	git_oid *oids;
+	git_oid oid, expected;
+	char *partial_oid;
+	git_object *object;
+
+	oids = git__malloc(count * sizeof(git_oid));
+	cl_assert(oids != NULL);
+
+	memset(oids, 0x0, count * sizeof(git_oid));
+
+	va_start(ap, count);
+	
+	for (i = 0; i < count; ++i) {
+		partial_oid = va_arg(ap, char *);
+		cl_git_pass(git_oid_fromstrn(&oid, partial_oid, strlen(partial_oid)));
+
+		cl_git_pass(git_object_lookup_prefix(&object, _repo, &oid, strlen(partial_oid), GIT_OBJ_COMMIT));
+		git_oid_cpy(&oids[i], git_object_id(object));
+		git_object_free(object);
+	}
+
+	va_end(ap);
+
+	if (expected_sha == NULL)
+		cl_assert_equal_i(GIT_ENOTFOUND, git_merge_base_many(&oid, _repo, count, oids));
+	else {
+		cl_git_pass(git_merge_base_many(&oid, _repo, count, oids));
+		cl_git_pass(git_oid_fromstr(&expected, expected_sha));
+
+		cl_assert_equal_oid(&expected, &oid);
+	}
+
+	git__free(oids);
+}
+
+void test_revwalk_mergebase__many_no_common_ancestor_returns_ENOTFOUND(void)
+{
+	assert_mergebase_many(NULL, 3, "41bc8c", "e90810", "a65fed");
+	assert_mergebase_many(NULL, 3, "e90810", "41bc8c", "a65fed");
+	assert_mergebase_many(NULL, 3, "e90810", "a65fed", "41bc8c");
+	assert_mergebase_many(NULL, 3, "a65fed", "e90810", "41bc8c");
+	assert_mergebase_many(NULL, 3, "a65fed", "41bc8c", "e90810");
+
+	assert_mergebase_many(NULL, 3, "e90810", "763d71", "a65fed");
+}
+
+void test_revwalk_mergebase__many_merge_branch(void)
+{
+	assert_mergebase_many("c47800c7266a2be04c571c04d5a6614691ea99bd", 3, "a65fed", "763d71", "849607");
+
+	assert_mergebase_many("c47800c7266a2be04c571c04d5a6614691ea99bd", 3, "763d71", "e90810", "a65fed");
+	assert_mergebase_many("c47800c7266a2be04c571c04d5a6614691ea99bd", 3, "763d71", "a65fed", "e90810");
+
+	assert_mergebase_many("c47800c7266a2be04c571c04d5a6614691ea99bd", 3, "a65fed", "763d71", "849607");
+	assert_mergebase_many("c47800c7266a2be04c571c04d5a6614691ea99bd", 3, "a65fed", "849607", "763d71");
+	assert_mergebase_many("8496071c1b46c854b31185ea97743be6a8774479", 3, "849607", "a65fed", "763d71");
+
+	assert_mergebase_many("5b5b025afb0b4c913b4c338a42934a3863bf3644", 5, "5b5b02", "763d71", "a4a7dc", "a65fed", "41bc8c");
+}
+
+static void assert_mergebase_octopus(const char *expected_sha, int count, ...)
+{
+	va_list ap;
+	int i;
+	git_oid *oids;
+	git_oid oid, expected;
+	char *partial_oid;
+	git_object *object;
+
+	oids = git__malloc(count * sizeof(git_oid));
+	cl_assert(oids != NULL);
+
+	memset(oids, 0x0, count * sizeof(git_oid));
+
+	va_start(ap, count);
+
+	for (i = 0; i < count; ++i) {
+		partial_oid = va_arg(ap, char *);
+		cl_git_pass(git_oid_fromstrn(&oid, partial_oid, strlen(partial_oid)));
+
+		cl_git_pass(git_object_lookup_prefix(&object, _repo, &oid, strlen(partial_oid), GIT_OBJ_COMMIT));
+		git_oid_cpy(&oids[i], git_object_id(object));
+		git_object_free(object);
+	}
+
+	va_end(ap);
+
+	if (expected_sha == NULL)
+		cl_assert_equal_i(GIT_ENOTFOUND, git_merge_base_octopus(&oid, _repo, count, oids));
+	else {
+		cl_git_pass(git_merge_base_octopus(&oid, _repo, count, oids));
+		cl_git_pass(git_oid_fromstr(&expected, expected_sha));
+
+		cl_assert_equal_oid(&expected, &oid);
+	}
+
+	git__free(oids);
+}
+
+void test_revwalk_mergebase__octopus_no_common_ancestor_returns_ENOTFOUND(void)
+{
+	assert_mergebase_octopus(NULL, 3, "41bc8c", "e90810", "a65fed");
+	assert_mergebase_octopus(NULL, 3, "e90810", "41bc8c", "a65fed");
+	assert_mergebase_octopus(NULL, 3, "e90810", "a65fed", "41bc8c");
+	assert_mergebase_octopus(NULL, 3, "a65fed", "e90810", "41bc8c");
+	assert_mergebase_octopus(NULL, 3, "a65fed", "41bc8c", "e90810");
+
+	assert_mergebase_octopus(NULL, 3, "e90810", "763d71", "a65fed");
+
+	assert_mergebase_octopus(NULL, 3, "763d71", "e90810", "a65fed");
+	assert_mergebase_octopus(NULL, 3, "763d71", "a65fed", "e90810");
+
+	assert_mergebase_octopus(NULL, 5, "5b5b02", "763d71", "a4a7dc", "a65fed", "41bc8c");
+}
+
+void test_revwalk_mergebase__octopus_merge_branch(void)
+{
+	assert_mergebase_octopus("8496071c1b46c854b31185ea97743be6a8774479", 3, "a65fed", "763d71", "849607");
+
+	assert_mergebase_octopus("8496071c1b46c854b31185ea97743be6a8774479", 3, "a65fed", "763d71", "849607");
+	assert_mergebase_octopus("8496071c1b46c854b31185ea97743be6a8774479", 3, "a65fed", "849607", "763d71");
+	assert_mergebase_octopus("8496071c1b46c854b31185ea97743be6a8774479", 3, "849607", "a65fed", "763d71");
+}
+
+/*
+ * testrepo.git $ git log --graph --all
+ * * commit 763d71aadf09a7951596c9746c024e7eece7c7af
+ * | Author: nulltoken <emeric.fermas at gmail.com>
+ * | Date:   Sun Oct 9 12:54:47 2011 +0200
+ * |
+ * |     Add some files into subdirectories
+ * |
+ * | * commit a65fedf39aefe402d3bb6e24df4d4f5fe4547750
+ * | | Author: Scott Chacon <schacon at gmail.com>
+ * | | Date:   Tue Aug 9 19:33:46 2011 -0700
+ * | |
+ * | *   commit be3563ae3f795b2b4353bcce3a527ad0a4f7f644
+ * | |\  Merge: 9fd738e c47800c
+ * | |/  Author: Scott Chacon <schacon at gmail.com>
+ * |/|   Date:   Tue May 25 11:58:27 2010 -0700
+ * | |
+ * | |       Merge branch 'br2'
+ * | |
+ * | | * commit e90810b8df3e80c413d903f631643c716887138d
+ * | | | Author: Vicent Marti <tanoku at gmail.com>
+ * | | | Date:   Thu Aug 5 18:42:20 2010 +0200
+ * | | |
+ * | | |     Test commit 2
+ * | | |
+ * | | * commit 6dcf9bf7541ee10456529833502442f385010c3d
+ * | |   Author: Vicent Marti <tanoku at gmail.com>
+ * | |   Date:   Thu Aug 5 18:41:33 2010 +0200
+ * | |
+ * | |       Test commit 1
+ * | |
+ * | | *   commit a4a7dce85cf63874e984719f4fdd239f5145052f
+ * | | |\  Merge: c47800c 9fd738e
+ * | |/ /  Author: Scott Chacon <schacon at gmail.com>
+ * |/| /   Date:   Tue May 25 12:00:23 2010 -0700
+ * | |/
+ * | |         Merge branch 'master' into br2
+ * | |
+ * | * commit 9fd738e8f7967c078dceed8190330fc8648ee56a
+ * | | Author: Scott Chacon <schacon at gmail.com>
+ * | | Date:   Mon May 24 10:19:19 2010 -0700
+ * | |
+ * | |     a fourth commit
+ * | |
+ * | * commit 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
+ * | | Author: Scott Chacon <schacon at gmail.com>
+ * | | Date:   Mon May 24 10:19:04 2010 -0700
+ * | |
+ * | |     a third commit
+ * | |
+ * * | commit c47800c7266a2be04c571c04d5a6614691ea99bd
+ * |/  Author: Scott Chacon <schacon at gmail.com>
+ * |   Date:   Tue May 25 11:58:14 2010 -0700
+ * |
+ * |       branch commit one
+ * |
+ * * commit 5b5b025afb0b4c913b4c338a42934a3863bf3644
+ * | Author: Scott Chacon <schacon at gmail.com>
+ * | Date:   Tue May 11 13:38:42 2010 -0700
+ * |
+ * |     another commit
+ * |
+ * * commit 8496071c1b46c854b31185ea97743be6a8774479
+ *   Author: Scott Chacon <schacon at gmail.com>
+ *   Date:   Sat May 8 16:13:06 2010 -0700
+ * 
+ *       testing
+ * 
+ * * commit 41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9
+ * | Author: Scott Chacon <schacon at gmail.com>
+ * | Date:   Tue May 11 13:40:41 2010 -0700
+ * |
+ * |     packed commit two
+ * |
+ * * commit 5001298e0c09ad9c34e4249bc5801c75e9754fa5
+ *   Author: Scott Chacon <schacon at gmail.com>
+ *   Date:   Tue May 11 13:40:23 2010 -0700
+ * 
+ *       packed commit one
+ */
+
+/*
+ * twowaymerge.git $ git log --graph --all
+ * *   commit 9b219343610c88a1187c996d0dc58330b55cee28
+ * |\  Merge: c37a783 2224e19
+ * | | Author: Scott J. Goldman <scottjg at github.com>
+ * | | Date:   Tue Nov 27 20:31:04 2012 -0800
+ * | | 
+ * | |     Merge branch 'first-branch' into second-branch
+ * | |   
+ * | * commit 2224e191514cb4bd8c566d80dac22dfcb1e9bb83
+ * | | Author: Scott J. Goldman <scottjg at github.com>
+ * | | Date:   Tue Nov 27 20:28:51 2012 -0800
+ * | | 
+ * | |     j
+ * | |   
+ * | * commit a41a49f8f5cd9b6cb14a076bf8394881ed0b4d19
+ * | | Author: Scott J. Goldman <scottjg at github.com>
+ * | | Date:   Tue Nov 27 20:28:39 2012 -0800
+ * | | 
+ * | |     i
+ * | |   
+ * | * commit 82bf9a1a10a4b25c1f14c9607b60970705e92545
+ * | | Author: Scott J. Goldman <scottjg at github.com>
+ * | | Date:   Tue Nov 27 20:28:28 2012 -0800
+ * | | 
+ * | |     h
+ * | |   
+ * * | commit c37a783c20d92ac92362a78a32860f7eebf938ef
+ * | | Author: Scott J. Goldman <scottjg at github.com>
+ * | | Date:   Tue Nov 27 20:30:57 2012 -0800
+ * | | 
+ * | |     n
+ * | |   
+ * * | commit 8b82fb1794cb1c8c7f172ec730a4c2db0ae3e650
+ * | | Author: Scott J. Goldman <scottjg at github.com>
+ * | | Date:   Tue Nov 27 20:30:43 2012 -0800
+ * | | 
+ * | |     m
+ * | |   
+ * * | commit 6ab5d28acbf3c3bdff276f7ccfdf29c1520e542f
+ * | | Author: Scott J. Goldman <scottjg at github.com>
+ * | | Date:   Tue Nov 27 20:30:38 2012 -0800
+ * | | 
+ * | |     l
+ * | |   
+ * * | commit 7b8c336c45fc6895c1c60827260fe5d798e5d247
+ * | | Author: Scott J. Goldman <scottjg at github.com>
+ * | | Date:   Tue Nov 27 20:30:24 2012 -0800
+ * | | 
+ * | |     k
+ * | |     
+ * | | * commit 1c30b88f5f3ee66d78df6520a7de9e89b890818b
+ * | | | Author: Scott J. Goldman <scottjg at github.com>
+ * | | | Date:   Tue Nov 27 20:28:10 2012 -0800
+ * | | | 
+ * | | |     e
+ * | | |    
+ * | | * commit 42b7311aa626e712891940c1ec5d5cba201946a4
+ * | | | Author: Scott J. Goldman <scottjg at github.com>
+ * | | | Date:   Tue Nov 27 20:28:06 2012 -0800
+ * | | | 
+ * | | |     d
+ * | | |      
+ * | | *   commit a953a018c5b10b20c86e69fef55ebc8ad4c5a417
+ * | | |\  Merge: bd1732c cdf97fd
+ * | | |/  Author: Scott J. Goldman <scottjg at github.com>
+ * | |/|   Date:   Tue Nov 27 20:26:43 2012 -0800
+ * | | |   
+ * | | |       Merge branch 'first-branch'
+ * | | |    
+ * | * | commit cdf97fd3bb48eb3827638bb33d208f5fd32d0aa6
+ * | | | Author: Scott J. Goldman <scottjg at github.com>
+ * | | | Date:   Tue Nov 27 20:24:46 2012 -0800
+ * | | | 
+ * | | |     g
+ * | | |    
+ * | * | commit ef0488f0b722f0be8bcb90a7730ac7efafd1d694
+ * | | | Author: Scott J. Goldman <scottjg at github.com>
+ * | | | Date:   Tue Nov 27 20:24:39 2012 -0800
+ * | | | 
+ * | | |     f
+ * | | |    
+ * | | * commit bd1732c43c68d712ad09e1d872b9be6d4b9efdc4
+ * | |/  Author: Scott J. Goldman <scottjg at github.com>
+ * | |   Date:   Tue Nov 27 17:43:58 2012 -0800
+ * | |   
+ * | |       c
+ * | |   
+ * | * commit 0c8a3f1f3d5f421cf83048c7c73ee3b55a5e0f29
+ * |/  Author: Scott J. Goldman <scottjg at github.com>
+ * |   Date:   Tue Nov 27 17:43:48 2012 -0800
+ * |   
+ * |       b
+ * |  
+ * * commit 1f4c0311a24b63f6fc209a59a1e404942d4a5006
+ *   Author: Scott J. Goldman <scottjg at github.com>
+ *   Date:   Tue Nov 27 17:43:41 2012 -0800
+ *
+ *       a
+ */
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revwalk/signatureparsing.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revwalk/signatureparsing.c
new file mode 100755
index 0000000..5c7d881
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revwalk/signatureparsing.c
@@ -0,0 +1,47 @@
+#include "clar_libgit2.h"
+
+static git_repository *_repo;
+static git_revwalk *_walk;
+
+void test_revwalk_signatureparsing__initialize(void)
+{
+	cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git")));
+	cl_git_pass(git_revwalk_new(&_walk, _repo));
+}
+
+void test_revwalk_signatureparsing__cleanup(void)
+{
+	git_revwalk_free(_walk);
+	_walk = NULL;
+
+	git_repository_free(_repo);
+	_repo = NULL;
+}
+
+void test_revwalk_signatureparsing__do_not_choke_when_name_contains_angle_brackets(void)
+{
+	git_reference *ref;
+	git_oid commit_oid;
+	git_commit *commit;
+	const git_signature *signature;
+
+	/*
+	 * The branch below points at a commit with angle brackets in the committer/author name
+	 * committer <Yu V. Bin Haacked> <foo at example.com> 1323847743 +0100
+	 */
+	cl_git_pass(git_reference_lookup(&ref, _repo, "refs/heads/haacked"));
+
+	git_revwalk_push(_walk, git_reference_target(ref));
+	cl_git_pass(git_revwalk_next(&commit_oid, _walk));
+
+	cl_git_pass(git_commit_lookup(&commit, _repo, git_reference_target(ref)));
+
+	signature = git_commit_committer(commit);
+	cl_assert_equal_s("foo at example.com", signature->email);
+	cl_assert_equal_s("<Yu V. Bin Haacked>", signature->name);
+	cl_assert_equal_i(1323847743, (int)signature->when.time);
+	cl_assert_equal_i(60, signature->when.offset);
+
+	git_commit_free(commit);
+	git_reference_free(ref);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revwalk/simplify.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revwalk/simplify.c
new file mode 100755
index 0000000..f65ce6c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/revwalk/simplify.c
@@ -0,0 +1,55 @@
+#include "clar_libgit2.h"
+
+void test_revwalk_simplify__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+/*
+	*   a4a7dce [0] Merge branch 'master' into br2
+	|\
+	| * 9fd738e [1] a fourth commit
+	| * 4a202b3 [2] a third commit
+	* | c47800c [3] branch commit one
+	|/
+	* 5b5b025 [5] another commit
+	* 8496071 [4] testing
+*/
+static const char *commit_head = "a4a7dce85cf63874e984719f4fdd239f5145052f";
+
+static const char *expected_str[] = {
+	"a4a7dce85cf63874e984719f4fdd239f5145052f", /* 0 */
+	"c47800c7266a2be04c571c04d5a6614691ea99bd", /* 3 */
+	"5b5b025afb0b4c913b4c338a42934a3863bf3644", /* 4 */
+	"8496071c1b46c854b31185ea97743be6a8774479", /* 5 */
+};
+
+void test_revwalk_simplify__first_parent(void)
+{
+	git_repository *repo;
+	git_revwalk *walk;
+	git_oid id, expected[4];
+	int i, error;
+
+	for (i = 0; i < 4; i++) {
+		git_oid_fromstr(&expected[i], expected_str[i]);
+	}
+
+	repo = cl_git_sandbox_init("testrepo.git");
+	cl_git_pass(git_revwalk_new(&walk, repo));
+
+	git_oid_fromstr(&id, commit_head);
+	cl_git_pass(git_revwalk_push(walk, &id));
+	git_revwalk_simplify_first_parent(walk);
+
+	i = 0;
+	while ((error = git_revwalk_next(&id, walk)) == 0) {
+		cl_assert_equal_oid(&expected[i], &id);
+		i++;
+	}
+
+	cl_assert_equal_i(i, 4);
+	cl_assert_equal_i(error, GIT_ITEROVER);
+
+	git_revwalk_free(walk);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/apply.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/apply.c
new file mode 100755
index 0000000..f26b73b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/apply.c
@@ -0,0 +1,449 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "stash_helpers.h"
+
+static git_signature *signature;
+static git_repository *repo;
+static git_index *repo_index;
+
+void test_stash_apply__initialize(void)
+{
+	git_oid oid;
+
+	repo = cl_git_sandbox_init_new("stash");
+	cl_git_pass(git_repository_index(&repo_index, repo));
+	cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas at gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */
+
+	cl_git_mkfile("stash/what", "hello\n");
+	cl_git_mkfile("stash/how", "small\n");
+	cl_git_mkfile("stash/who", "world\n");
+	cl_git_mkfile("stash/where", "meh\n");
+
+	cl_git_pass(git_index_add_bypath(repo_index, "what"));
+	cl_git_pass(git_index_add_bypath(repo_index, "how"));
+	cl_git_pass(git_index_add_bypath(repo_index, "who"));
+
+	cl_repo_commit_from_index(NULL, repo, signature, 0, "Initial commit");
+
+	cl_git_rewritefile("stash/what", "goodbye\n");
+	cl_git_rewritefile("stash/who", "funky world\n");
+	cl_git_mkfile("stash/when", "tomorrow\n");
+	cl_git_mkfile("stash/why", "would anybody use stash?\n");
+	cl_git_mkfile("stash/where", "????\n");
+
+	cl_git_pass(git_index_add_bypath(repo_index, "who"));
+	cl_git_pass(git_index_add_bypath(repo_index, "why"));
+	cl_git_pass(git_index_add_bypath(repo_index, "where"));
+	git_index_write(repo_index);
+
+	cl_git_rewritefile("stash/where", "....\n");
+
+	/* Pre-stash state */
+	assert_status(repo, "what", GIT_STATUS_WT_MODIFIED);
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_INDEX_MODIFIED);
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "why", GIT_STATUS_INDEX_NEW);
+	assert_status(repo, "where", GIT_STATUS_INDEX_NEW|GIT_STATUS_WT_MODIFIED);
+
+	cl_git_pass(git_stash_save(&oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED));
+
+	/* Post-stash state */
+	assert_status(repo, "what", GIT_STATUS_CURRENT);
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_CURRENT);
+	assert_status(repo, "when", GIT_ENOTFOUND);
+	assert_status(repo, "why", GIT_ENOTFOUND);
+	assert_status(repo, "where", GIT_ENOTFOUND);
+}
+
+void test_stash_apply__cleanup(void)
+{
+	git_signature_free(signature);
+	signature = NULL;
+
+	git_index_free(repo_index);
+	repo_index = NULL;
+
+	cl_git_sandbox_cleanup();
+}
+
+void test_stash_apply__with_default(void)
+{
+	git_buf where = GIT_BUF_INIT;
+
+	cl_git_pass(git_stash_apply(repo, 0, NULL));
+
+	cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
+	assert_status(repo, "what", GIT_STATUS_WT_MODIFIED);
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_WT_MODIFIED);
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "why", GIT_STATUS_INDEX_NEW);
+	assert_status(repo, "where", GIT_STATUS_INDEX_NEW);
+
+	cl_git_pass(git_futils_readbuffer(&where, "stash/where"));
+	cl_assert_equal_s("....\n", where.ptr);
+
+	git_buf_free(&where);
+}
+
+void test_stash_apply__with_existing_file(void)
+{
+	cl_git_mkfile("stash/where", "oops!\n");
+	cl_git_fail(git_stash_apply(repo, 0, NULL));
+}
+
+void test_stash_apply__merges_new_file(void)
+{
+	const git_index_entry *ancestor, *our, *their;
+
+	cl_git_mkfile("stash/where", "committed before stash\n");
+	cl_git_pass(git_index_add_bypath(repo_index, "where"));
+	cl_repo_commit_from_index(NULL, repo, signature, 0, "Other commit");
+
+	cl_git_pass(git_stash_apply(repo, 0, NULL));
+
+	cl_assert_equal_i(1, git_index_has_conflicts(repo_index));
+	assert_status(repo, "what", GIT_STATUS_INDEX_MODIFIED);
+	cl_git_pass(git_index_conflict_get(&ancestor, &our, &their, repo_index, "where")); /* unmerged */
+	assert_status(repo, "who", GIT_STATUS_INDEX_MODIFIED);
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "why", GIT_STATUS_INDEX_NEW);
+}
+
+void test_stash_apply__with_reinstate_index(void)
+{
+	git_buf where = GIT_BUF_INIT;
+	git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
+
+	opts.flags = GIT_STASH_APPLY_REINSTATE_INDEX;
+
+	cl_git_pass(git_stash_apply(repo, 0, &opts));
+
+	cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
+	assert_status(repo, "what", GIT_STATUS_WT_MODIFIED);
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_INDEX_MODIFIED);
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "why", GIT_STATUS_INDEX_NEW);
+	assert_status(repo, "where", GIT_STATUS_INDEX_NEW | GIT_STATUS_WT_MODIFIED);
+
+	cl_git_pass(git_futils_readbuffer(&where, "stash/where"));
+	cl_assert_equal_s("....\n", where.ptr);
+
+	git_buf_free(&where);
+}
+
+void test_stash_apply__conflict_index_with_default(void)
+{
+	const git_index_entry *ancestor;
+	const git_index_entry *our;
+	const git_index_entry *their;
+
+	cl_git_rewritefile("stash/who", "nothing\n");
+	cl_git_pass(git_index_add_bypath(repo_index, "who"));
+	cl_git_pass(git_index_write(repo_index));
+	cl_repo_commit_from_index(NULL, repo, signature, 0, "Other commit");
+
+	cl_git_pass(git_stash_apply(repo, 0, NULL));
+
+	cl_assert_equal_i(git_index_has_conflicts(repo_index), 1);
+	assert_status(repo, "what", GIT_STATUS_INDEX_MODIFIED);
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	cl_git_pass(git_index_conflict_get(&ancestor, &our, &their, repo_index, "who")); /* unmerged */
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "why", GIT_STATUS_INDEX_NEW);
+}
+
+void test_stash_apply__conflict_index_with_reinstate_index(void)
+{
+	git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
+
+	opts.flags = GIT_STASH_APPLY_REINSTATE_INDEX;
+
+	cl_git_rewritefile("stash/who", "nothing\n");
+	cl_git_pass(git_index_add_bypath(repo_index, "who"));
+	cl_git_pass(git_index_write(repo_index));
+	cl_repo_commit_from_index(NULL, repo, signature, 0, "Other commit");
+
+	cl_git_fail_with(git_stash_apply(repo, 0, &opts), GIT_ECONFLICT);
+
+	cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
+	assert_status(repo, "what", GIT_STATUS_CURRENT);
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_CURRENT);
+	assert_status(repo, "when", GIT_ENOTFOUND);
+	assert_status(repo, "why", GIT_ENOTFOUND);
+}
+
+void test_stash_apply__conflict_untracked_with_default(void)
+{
+	git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
+
+	cl_git_mkfile("stash/when", "nothing\n");
+
+	cl_git_fail_with(git_stash_apply(repo, 0, &opts), GIT_ECONFLICT);
+
+	cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
+	assert_status(repo, "what", GIT_STATUS_CURRENT);
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_CURRENT);
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "why", GIT_ENOTFOUND);
+}
+
+void test_stash_apply__conflict_untracked_with_reinstate_index(void)
+{
+	git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
+
+	opts.flags = GIT_STASH_APPLY_REINSTATE_INDEX;
+
+	cl_git_mkfile("stash/when", "nothing\n");
+
+	cl_git_fail_with(git_stash_apply(repo, 0, &opts), GIT_ECONFLICT);
+
+	cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
+	assert_status(repo, "what", GIT_STATUS_CURRENT);
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_CURRENT);
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "why", GIT_ENOTFOUND);
+}
+
+void test_stash_apply__conflict_workdir_with_default(void)
+{
+	cl_git_rewritefile("stash/what", "ciao\n");
+
+	cl_git_fail_with(git_stash_apply(repo, 0, NULL), GIT_ECONFLICT);
+
+	cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
+	assert_status(repo, "what", GIT_STATUS_WT_MODIFIED);
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_CURRENT);
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "why", GIT_ENOTFOUND);
+}
+
+void test_stash_apply__conflict_workdir_with_reinstate_index(void)
+{
+	git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
+
+	opts.flags = GIT_STASH_APPLY_REINSTATE_INDEX;
+
+	cl_git_rewritefile("stash/what", "ciao\n");
+
+	cl_git_fail_with(git_stash_apply(repo, 0, &opts), GIT_ECONFLICT);
+
+	cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
+	assert_status(repo, "what", GIT_STATUS_WT_MODIFIED);
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_CURRENT);
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "why", GIT_ENOTFOUND);
+}
+
+void test_stash_apply__conflict_commit_with_default(void)
+{
+	const git_index_entry *ancestor;
+	const git_index_entry *our;
+	const git_index_entry *their;
+
+	cl_git_rewritefile("stash/what", "ciao\n");
+	cl_git_pass(git_index_add_bypath(repo_index, "what"));
+	cl_repo_commit_from_index(NULL, repo, signature, 0, "Other commit");
+
+	cl_git_pass(git_stash_apply(repo, 0, NULL));
+
+	cl_assert_equal_i(git_index_has_conflicts(repo_index), 1);
+	cl_git_pass(git_index_conflict_get(&ancestor, &our, &their, repo_index, "what")); /* unmerged */
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_INDEX_MODIFIED);
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "why", GIT_STATUS_INDEX_NEW);
+}
+
+void test_stash_apply__conflict_commit_with_reinstate_index(void)
+{
+	git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
+	const git_index_entry *ancestor;
+	const git_index_entry *our;
+	const git_index_entry *their;
+
+	opts.flags = GIT_STASH_APPLY_REINSTATE_INDEX;
+
+	cl_git_rewritefile("stash/what", "ciao\n");
+	cl_git_pass(git_index_add_bypath(repo_index, "what"));
+	cl_repo_commit_from_index(NULL, repo, signature, 0, "Other commit");
+
+	cl_git_pass(git_stash_apply(repo, 0, &opts));
+
+	cl_assert_equal_i(git_index_has_conflicts(repo_index), 1);
+	cl_git_pass(git_index_conflict_get(&ancestor, &our, &their, repo_index, "what")); /* unmerged */
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_INDEX_MODIFIED);
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "why", GIT_STATUS_INDEX_NEW);
+}
+
+void test_stash_apply__fails_with_uncommitted_changes_in_index(void)
+{
+	cl_git_rewritefile("stash/who", "nothing\n");
+	cl_git_pass(git_index_add_bypath(repo_index, "who"));
+	cl_git_pass(git_index_write(repo_index));
+
+	cl_git_fail_with(git_stash_apply(repo, 0, NULL), GIT_EUNCOMMITTED);
+
+	cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
+	assert_status(repo, "what", GIT_STATUS_CURRENT);
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_INDEX_MODIFIED);
+	assert_status(repo, "when", GIT_ENOTFOUND);
+	assert_status(repo, "why", GIT_ENOTFOUND);
+}
+
+void test_stash_apply__pop(void)
+{
+	cl_git_pass(git_stash_pop(repo, 0, NULL));
+
+	cl_git_fail_with(git_stash_pop(repo, 0, NULL), GIT_ENOTFOUND);
+}
+
+struct seen_paths {
+	bool what;
+	bool how;
+	bool who;
+	bool when;
+};
+
+int checkout_notify(
+	git_checkout_notify_t why,
+	const char *path,
+	const git_diff_file *baseline,
+	const git_diff_file *target,
+	const git_diff_file *workdir,
+	void *payload)
+{
+	struct seen_paths *seen_paths = (struct seen_paths *)payload;
+
+	GIT_UNUSED(why);
+	GIT_UNUSED(baseline);
+	GIT_UNUSED(target);
+	GIT_UNUSED(workdir);
+
+	if (strcmp(path, "what") == 0)
+		seen_paths->what = 1;
+	else if (strcmp(path, "how") == 0)
+		seen_paths->how = 1;
+	else if (strcmp(path, "who") == 0)
+		seen_paths->who = 1;
+	else if (strcmp(path, "when") == 0)
+		seen_paths->when = 1;
+
+	return 0;
+}
+
+void test_stash_apply__executes_notify_cb(void)
+{
+	git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
+	struct seen_paths seen_paths = {0};
+
+	opts.checkout_options.notify_cb = checkout_notify;
+	opts.checkout_options.notify_flags = GIT_CHECKOUT_NOTIFY_ALL;
+	opts.checkout_options.notify_payload = &seen_paths;
+
+	cl_git_pass(git_stash_apply(repo, 0, &opts));
+
+	cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
+	assert_status(repo, "what", GIT_STATUS_WT_MODIFIED);
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_WT_MODIFIED);
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "why", GIT_STATUS_INDEX_NEW);
+	assert_status(repo, "where", GIT_STATUS_INDEX_NEW);
+
+	cl_assert_equal_b(true, seen_paths.what);
+	cl_assert_equal_b(false, seen_paths.how);
+	cl_assert_equal_b(true, seen_paths.who);
+	cl_assert_equal_b(true, seen_paths.when);
+}
+
+int progress_cb(
+	git_stash_apply_progress_t progress,
+	void *payload)
+{
+	git_stash_apply_progress_t *p = (git_stash_apply_progress_t *)payload;
+
+	cl_assert_equal_i((*p)+1, progress);
+
+	*p = progress;
+
+	return 0;
+}
+
+void test_stash_apply__calls_progress_cb(void)
+{
+	git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
+	git_stash_apply_progress_t progress = GIT_STASH_APPLY_PROGRESS_NONE;
+
+	opts.progress_cb = progress_cb;
+	opts.progress_payload = &progress;
+
+	cl_git_pass(git_stash_apply(repo, 0, &opts));
+	cl_assert_equal_i(progress, GIT_STASH_APPLY_PROGRESS_DONE);
+}
+
+int aborting_progress_cb(
+	git_stash_apply_progress_t progress,
+	void *payload)
+{
+	GIT_UNUSED(payload);
+
+	if (progress == GIT_STASH_APPLY_PROGRESS_ANALYZE_MODIFIED)
+		return -44;
+
+	return 0;
+}
+
+void test_stash_apply__progress_cb_can_abort(void)
+{
+	git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
+
+	opts.progress_cb = aborting_progress_cb;
+
+	cl_git_fail_with(-44, git_stash_apply(repo, 0, &opts));
+}
+
+void test_stash_apply__uses_reflog_like_indices_1(void)
+{
+	git_oid oid;
+
+	cl_git_mkfile("stash/untracked", "untracked\n");
+	cl_git_pass(git_stash_save(&oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED));
+	assert_status(repo, "untracked", GIT_ENOTFOUND);
+
+	// stash@{1} is the oldest (first) stash we made
+	cl_git_pass(git_stash_apply(repo, 1, NULL));
+	cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
+	assert_status(repo, "what", GIT_STATUS_WT_MODIFIED);
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_WT_MODIFIED);
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "why", GIT_STATUS_INDEX_NEW);
+	assert_status(repo, "where", GIT_STATUS_INDEX_NEW);
+}
+
+void test_stash_apply__uses_reflog_like_indices_2(void)
+{
+	git_oid oid;
+
+	cl_git_mkfile("stash/untracked", "untracked\n");
+	cl_git_pass(git_stash_save(&oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED));
+	assert_status(repo, "untracked", GIT_ENOTFOUND);
+
+	// stash@{0} is the newest stash we made immediately above
+	cl_git_pass(git_stash_apply(repo, 0, NULL));
+
+	cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
+	assert_status(repo, "untracked", GIT_STATUS_WT_NEW);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/drop.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/drop.c
new file mode 100755
index 0000000..89a0ade
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/drop.c
@@ -0,0 +1,174 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "stash_helpers.h"
+#include "refs.h"
+
+static git_repository *repo;
+static git_signature *signature;
+
+void test_stash_drop__initialize(void)
+{
+	cl_git_pass(git_repository_init(&repo, "stash", 0));
+	cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas at gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */
+}
+
+void test_stash_drop__cleanup(void)
+{
+	git_signature_free(signature);
+	signature = NULL;
+
+	git_repository_free(repo);
+	repo = NULL;
+
+	cl_git_pass(git_futils_rmdir_r("stash", NULL, GIT_RMDIR_REMOVE_FILES));
+}
+
+void test_stash_drop__cannot_drop_from_an_empty_stash(void)
+{
+	cl_git_fail_with(git_stash_drop(repo, 0), GIT_ENOTFOUND);
+}
+
+static void push_three_states(void)
+{
+	git_oid oid;
+	git_index *index;
+
+	cl_git_mkfile("stash/zero.txt", "content\n");
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_add_bypath(index, "zero.txt"));
+	cl_repo_commit_from_index(NULL, repo, signature, 0, "Initial commit");
+	cl_assert(git_path_exists("stash/zero.txt"));
+	git_index_free(index);
+
+	cl_git_mkfile("stash/one.txt", "content\n");
+	cl_git_pass(git_stash_save(
+		&oid, repo, signature, "First", GIT_STASH_INCLUDE_UNTRACKED));
+	cl_assert(!git_path_exists("stash/one.txt"));
+	cl_assert(git_path_exists("stash/zero.txt"));
+
+	cl_git_mkfile("stash/two.txt", "content\n");
+	cl_git_pass(git_stash_save(
+		&oid, repo, signature, "Second", GIT_STASH_INCLUDE_UNTRACKED));
+	cl_assert(!git_path_exists("stash/two.txt"));
+	cl_assert(git_path_exists("stash/zero.txt"));
+
+	cl_git_mkfile("stash/three.txt", "content\n");
+	cl_git_pass(git_stash_save(
+		&oid, repo, signature, "Third", GIT_STASH_INCLUDE_UNTRACKED));
+	cl_assert(!git_path_exists("stash/three.txt"));
+	cl_assert(git_path_exists("stash/zero.txt"));
+}
+
+void test_stash_drop__cannot_drop_a_non_existing_stashed_state(void)
+{
+	push_three_states();
+
+	cl_git_fail_with(git_stash_drop(repo, 666), GIT_ENOTFOUND);
+	cl_git_fail_with(git_stash_drop(repo, 42), GIT_ENOTFOUND);
+	cl_git_fail_with(git_stash_drop(repo, 3), GIT_ENOTFOUND);
+}
+
+void test_stash_drop__can_purge_the_stash_from_the_top(void)
+{
+	push_three_states();
+
+	cl_git_pass(git_stash_drop(repo, 0));
+	cl_git_pass(git_stash_drop(repo, 0));
+	cl_git_pass(git_stash_drop(repo, 0));
+
+	cl_git_fail_with(git_stash_drop(repo, 0), GIT_ENOTFOUND);
+}
+
+void test_stash_drop__can_purge_the_stash_from_the_bottom(void)
+{
+	push_three_states();
+
+	cl_git_pass(git_stash_drop(repo, 2));
+	cl_git_pass(git_stash_drop(repo, 1));
+	cl_git_pass(git_stash_drop(repo, 0));
+
+	cl_git_fail_with(git_stash_drop(repo, 0), GIT_ENOTFOUND);
+}
+
+void test_stash_drop__dropping_an_entry_rewrites_reflog_history(void)
+{
+	git_reference *stash;
+	git_reflog *reflog;
+	const git_reflog_entry *entry;
+	git_oid oid;
+	size_t count;
+
+	push_three_states();
+
+	cl_git_pass(git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE));
+
+	cl_git_pass(git_reflog_read(&reflog, repo, GIT_REFS_STASH_FILE));
+	entry = git_reflog_entry_byindex(reflog, 1);
+
+	git_oid_cpy(&oid, git_reflog_entry_id_old(entry));
+	count = git_reflog_entrycount(reflog);
+
+	git_reflog_free(reflog);
+
+	cl_git_pass(git_stash_drop(repo, 1));
+
+	cl_git_pass(git_reflog_read(&reflog, repo, GIT_REFS_STASH_FILE));
+	entry = git_reflog_entry_byindex(reflog, 0);
+
+	cl_assert_equal_oid(&oid, git_reflog_entry_id_old(entry));
+	cl_assert_equal_sz(count - 1, git_reflog_entrycount(reflog));
+
+	git_reflog_free(reflog);
+
+	git_reference_free(stash);
+}
+
+void test_stash_drop__dropping_the_last_entry_removes_the_stash(void)
+{
+	git_reference *stash;
+
+	push_three_states();
+
+	cl_git_pass(git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE));
+	git_reference_free(stash);
+
+	cl_git_pass(git_stash_drop(repo, 0));
+	cl_git_pass(git_stash_drop(repo, 0));
+	cl_git_pass(git_stash_drop(repo, 0));
+
+	cl_git_fail_with(
+		git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE), GIT_ENOTFOUND);
+}
+
+void retrieve_top_stash_id(git_oid *out)
+{
+	git_object *top_stash;
+
+	cl_git_pass(git_revparse_single(&top_stash, repo, "stash@{0}"));
+	cl_git_pass(git_reference_name_to_id(out, repo, GIT_REFS_STASH_FILE));
+
+	cl_assert_equal_oid(out, git_object_id(top_stash));
+
+	git_object_free(top_stash);
+}
+
+void test_stash_drop__dropping_the_top_stash_updates_the_stash_reference(void)
+{
+	git_object *next_top_stash;
+	git_oid oid;
+
+	push_three_states();
+
+	retrieve_top_stash_id(&oid);
+
+	cl_git_pass(git_revparse_single(&next_top_stash, repo, "stash@{1}"));
+	cl_assert(git_oid_cmp(&oid, git_object_id(next_top_stash)));
+
+	cl_git_pass(git_stash_drop(repo, 0));
+
+	retrieve_top_stash_id(&oid);
+
+	cl_assert_equal_oid(&oid, git_object_id(next_top_stash));
+
+	git_object_free(next_top_stash);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/foreach.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/foreach.c
new file mode 100755
index 0000000..57dc8ee
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/foreach.c
@@ -0,0 +1,126 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "stash_helpers.h"
+
+struct callback_data
+{
+	char **oids;
+	int invokes;
+};
+
+static git_repository *repo;
+static git_signature *signature;
+static git_oid stash_tip_oid;
+struct callback_data data;
+
+#define REPO_NAME "stash"
+
+void test_stash_foreach__initialize(void)
+{
+	cl_git_pass(git_signature_new(
+		&signature,
+		"nulltoken",
+		"emeric.fermas at gmail.com",
+		1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */
+
+	memset(&data, 0, sizeof(struct callback_data));
+}
+
+void test_stash_foreach__cleanup(void)
+{
+	git_signature_free(signature);
+	signature = NULL;
+
+	git_repository_free(repo);
+	repo = NULL;
+
+	cl_git_pass(git_futils_rmdir_r(REPO_NAME, NULL, GIT_RMDIR_REMOVE_FILES));
+}
+
+static int callback_cb(
+	size_t index,
+	const char* message,
+	const git_oid *stash_oid,
+	void *payload)
+{
+	struct callback_data *data = (struct callback_data *)payload;
+
+	GIT_UNUSED(index);
+	GIT_UNUSED(message);
+
+	cl_assert_equal_i(0, git_oid_streq(stash_oid, data->oids[data->invokes++]));
+
+	return 0;
+}
+
+void test_stash_foreach__enumerating_a_empty_repository_doesnt_fail(void)
+{
+	char *oids[] = { NULL };
+
+	data.oids = oids;
+
+	cl_git_pass(git_repository_init(&repo, REPO_NAME, 0));
+
+	cl_git_pass(git_stash_foreach(repo, callback_cb, &data));
+
+	cl_assert_equal_i(0, data.invokes);
+}
+
+void test_stash_foreach__can_enumerate_a_repository(void)
+{
+	char *oids_default[] = {
+		"493568b7a2681187aaac8a58d3f1eab1527cba84", NULL };
+
+	char *oids_untracked[] = {
+		"7f89a8b15c878809c5c54d1ff8f8c9674154017b",
+		"493568b7a2681187aaac8a58d3f1eab1527cba84", NULL };
+
+	char *oids_ignored[] = {
+		"c95599a8fef20a7e57582c6727b1a0d02e0a5828",
+		"7f89a8b15c878809c5c54d1ff8f8c9674154017b",
+		"493568b7a2681187aaac8a58d3f1eab1527cba84", NULL };
+
+	cl_git_pass(git_repository_init(&repo, REPO_NAME, 0));
+
+	setup_stash(repo, signature);
+
+	cl_git_pass(git_stash_save(
+		&stash_tip_oid,
+		repo,
+		signature,
+		NULL,
+		GIT_STASH_DEFAULT));
+
+	data.oids = oids_default;
+
+	cl_git_pass(git_stash_foreach(repo, callback_cb, &data));
+	cl_assert_equal_i(1, data.invokes);
+
+	/* ensure stash_foreach operates with INCLUDE_UNTRACKED */
+	cl_git_pass(git_stash_save(
+		&stash_tip_oid,
+		repo,
+		signature,
+		NULL,
+		GIT_STASH_INCLUDE_UNTRACKED));
+
+	data.oids = oids_untracked;
+	data.invokes = 0;
+
+	cl_git_pass(git_stash_foreach(repo, callback_cb, &data));
+	cl_assert_equal_i(2, data.invokes);
+
+	/* ensure stash_foreach operates with INCLUDE_IGNORED */
+	cl_git_pass(git_stash_save(
+		&stash_tip_oid,
+		repo,
+		signature,
+		NULL,
+		GIT_STASH_INCLUDE_IGNORED));
+
+	data.oids = oids_ignored;
+	data.invokes = 0;
+
+	cl_git_pass(git_stash_foreach(repo, callback_cb, &data));
+	cl_assert_equal_i(3, data.invokes);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/save.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/save.c
new file mode 100755
index 0000000..edcee82
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/save.c
@@ -0,0 +1,428 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "stash_helpers.h"
+
+static git_repository *repo;
+static git_signature *signature;
+static git_oid stash_tip_oid;
+
+/*
+ * Friendly reminder, in order to ease the reading of the following tests:
+ *
+ * "stash"		points to the worktree commit 
+ * "stash^1"	points to the base commit (HEAD when the stash was created)
+ * "stash^2"	points to the index commit
+ * "stash^3"	points to the untracked commit
+ */
+
+void test_stash_save__initialize(void)
+{
+	cl_git_pass(git_repository_init(&repo, "stash", 0));
+	cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas at gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */
+
+	setup_stash(repo, signature);
+}
+
+void test_stash_save__cleanup(void)
+{
+	git_signature_free(signature);
+	signature = NULL;
+
+	git_repository_free(repo);
+	repo = NULL;
+
+	cl_git_pass(git_futils_rmdir_r("stash", NULL, GIT_RMDIR_REMOVE_FILES));
+	cl_fixture_cleanup("sorry-it-is-a-non-bare-only-party");
+}
+
+static void assert_object_oid(const char* revision, const char* expected_oid, git_otype type)
+{
+	int result;
+	git_object *obj;
+
+	result = git_revparse_single(&obj, repo, revision);
+
+	if (!expected_oid) {
+		cl_assert_equal_i(GIT_ENOTFOUND, result);
+		return;
+	} else
+		cl_assert_equal_i(0, result);
+
+	cl_git_pass(git_oid_streq(git_object_id(obj), expected_oid));
+	cl_assert_equal_i(type, git_object_type(obj));
+	git_object_free(obj);
+}
+
+static void assert_blob_oid(const char* revision, const char* expected_oid)
+{
+	assert_object_oid(revision, expected_oid, GIT_OBJ_BLOB);
+}
+
+void test_stash_save__does_not_keep_index_by_default(void)
+{
+/*
+$ git stash
+
+$ git show refs/stash:what
+see you later
+
+$ git show refs/stash:how
+not so small and
+
+$ git show refs/stash:who
+funky world
+
+$ git show refs/stash:when
+fatal: Path 'when' exists on disk, but not in 'stash'.
+
+$ git show refs/stash^2:what
+goodbye
+
+$ git show refs/stash^2:how
+not so small and
+
+$ git show refs/stash^2:who
+world
+
+$ git show refs/stash^2:when
+fatal: Path 'when' exists on disk, but not in 'stash^2'.
+
+$ git status --short
+?? when
+
+*/
+	unsigned int status;
+
+	cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT));
+	cl_git_pass(git_status_file(&status, repo, "when"));
+
+	assert_blob_oid("refs/stash:what", "bc99dc98b3eba0e9157e94769cd4d49cb49de449");	/* see you later */
+	assert_blob_oid("refs/stash:how", "e6d64adb2c7f3eb8feb493b556cc8070dca379a3");	/* not so small and */
+	assert_blob_oid("refs/stash:who", "a0400d4954659306a976567af43125a0b1aa8595");	/* funky world */
+	assert_blob_oid("refs/stash:when", NULL);
+	assert_blob_oid("refs/stash:why", "88c2533e21f098b89c91a431d8075cbdbe422a51"); /* would anybody use stash? */
+	assert_blob_oid("refs/stash:where", "e3d6434ec12eb76af8dfa843a64ba6ab91014a0b"); /* .... */
+	assert_blob_oid("refs/stash:.gitignore", "ac4d88de61733173d9959e4b77c69b9f17a00980");
+	assert_blob_oid("refs/stash:just.ignore", NULL);
+
+	assert_blob_oid("refs/stash^2:what", "dd7e1c6f0fefe118f0b63d9f10908c460aa317a6");	/* goodbye */
+	assert_blob_oid("refs/stash^2:how", "e6d64adb2c7f3eb8feb493b556cc8070dca379a3");	/* not so small and */
+	assert_blob_oid("refs/stash^2:who", "cc628ccd10742baea8241c5924df992b5c019f71");	/* world */
+	assert_blob_oid("refs/stash^2:when", NULL);
+	assert_blob_oid("refs/stash^2:why", "88c2533e21f098b89c91a431d8075cbdbe422a51"); /* would anybody use stash? */
+	assert_blob_oid("refs/stash^2:where", "e08f7fbb9a42a0c5367cf8b349f1f08c3d56bd72"); /* ???? */
+	assert_blob_oid("refs/stash^2:.gitignore", "ac4d88de61733173d9959e4b77c69b9f17a00980");
+	assert_blob_oid("refs/stash^2:just.ignore", NULL);
+
+	assert_blob_oid("refs/stash^3", NULL);
+
+	cl_assert_equal_i(GIT_STATUS_WT_NEW, status);
+}
+
+void test_stash_save__can_keep_index(void)
+{
+	cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_KEEP_INDEX));
+
+	assert_status(repo, "what", GIT_STATUS_INDEX_MODIFIED);
+	assert_status(repo, "how", GIT_STATUS_INDEX_MODIFIED);
+	assert_status(repo, "who", GIT_STATUS_CURRENT);
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "just.ignore", GIT_STATUS_IGNORED);
+}
+
+static void assert_commit_message_contains(const char *revision, const char *fragment)
+{
+	git_commit *commit;
+
+	cl_git_pass(git_revparse_single((git_object**)&commit, repo, revision));
+
+	cl_assert(strstr(git_commit_message(commit), fragment) != NULL);
+
+	git_commit_free(commit);
+}
+
+void test_stash_save__can_include_untracked_files(void)
+{
+	cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED));
+
+	assert_commit_message_contains("refs/stash^3", "untracked files on master: ");
+
+	assert_blob_oid("refs/stash^3:what", NULL);
+	assert_blob_oid("refs/stash^3:how", NULL);
+	assert_blob_oid("refs/stash^3:who", NULL);
+	assert_blob_oid("refs/stash^3:when", "b6ed15e81e2593d7bb6265eb4a991d29dc3e628b");
+	assert_blob_oid("refs/stash^3:just.ignore", NULL);
+}
+
+void test_stash_save__untracked_skips_ignored(void)
+{
+	cl_git_append2file("stash/.gitignore", "bundle/vendor/\n");
+	cl_must_pass(p_mkdir("stash/bundle", 0777));
+	cl_must_pass(p_mkdir("stash/bundle/vendor", 0777));
+	cl_git_mkfile("stash/bundle/vendor/blah", "contents\n");
+
+	cl_assert(git_path_exists("stash/when")); /* untracked */
+	cl_assert(git_path_exists("stash/just.ignore")); /* ignored */
+	cl_assert(git_path_exists("stash/bundle/vendor/blah")); /* ignored */
+
+	cl_git_pass(git_stash_save(
+		&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED));
+
+	cl_assert(!git_path_exists("stash/when"));
+	cl_assert(git_path_exists("stash/bundle/vendor/blah"));
+	cl_assert(git_path_exists("stash/just.ignore"));
+}
+
+void test_stash_save__can_include_untracked_and_ignored_files(void)
+{
+	cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED | GIT_STASH_INCLUDE_IGNORED));
+
+	assert_commit_message_contains("refs/stash^3", "untracked files on master: ");
+
+	assert_blob_oid("refs/stash^3:what", NULL);
+	assert_blob_oid("refs/stash^3:how", NULL);
+	assert_blob_oid("refs/stash^3:who", NULL);
+	assert_blob_oid("refs/stash^3:when", "b6ed15e81e2593d7bb6265eb4a991d29dc3e628b");
+	assert_blob_oid("refs/stash^3:just.ignore", "78925fb1236b98b37a35e9723033e627f97aa88b");
+
+	cl_assert(!git_path_exists("stash/just.ignore"));
+}
+
+#define MESSAGE "Look Ma! I'm on TV!"
+void test_stash_save__can_accept_a_message(void)
+{
+	cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, MESSAGE, GIT_STASH_DEFAULT));
+
+	assert_commit_message_contains("refs/stash^2", "index on master: ");
+	assert_commit_message_contains("refs/stash", "On master: " MESSAGE);
+}
+
+void test_stash_save__cannot_stash_against_an_unborn_branch(void)
+{
+	git_reference *head;
+
+	cl_git_pass(git_reference_symbolic_create(&head, repo, "HEAD", "refs/heads/unborn", 1, NULL));
+
+	cl_assert_equal_i(GIT_EUNBORNBRANCH,
+		git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT));
+
+	git_reference_free(head);
+}
+
+void test_stash_save__cannot_stash_against_a_bare_repository(void)
+{
+	git_repository *local;
+
+	cl_git_pass(git_repository_init(&local, "sorry-it-is-a-non-bare-only-party", 1));
+
+	cl_assert_equal_i(GIT_EBAREREPO,
+		git_stash_save(&stash_tip_oid, local, signature, NULL, GIT_STASH_DEFAULT));
+
+	git_repository_free(local);
+}
+
+void test_stash_save__can_stash_against_a_detached_head(void)
+{
+	git_repository_detach_head(repo);
+
+	cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT));
+
+	assert_commit_message_contains("refs/stash^2", "index on (no branch): ");
+	assert_commit_message_contains("refs/stash", "WIP on (no branch): ");
+}
+
+void test_stash_save__stashing_updates_the_reflog(void)
+{
+	assert_object_oid("refs/stash@{0}", NULL, GIT_OBJ_COMMIT);
+
+	cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT));
+
+	assert_object_oid("refs/stash@{0}", git_oid_tostr_s(&stash_tip_oid), GIT_OBJ_COMMIT);
+	assert_object_oid("refs/stash@{1}", NULL, GIT_OBJ_COMMIT);
+}
+
+void test_stash_save__cannot_stash_when_there_are_no_local_change(void)
+{
+	git_index *index;
+	git_oid stash_tip_oid;
+
+	cl_git_pass(git_repository_index(&index, repo));
+
+	/*
+	 * 'what', 'where' and 'who' are being committed.
+	 * 'when' remains untracked.
+	 */
+	cl_git_pass(git_index_add_bypath(index, "what"));
+	cl_git_pass(git_index_add_bypath(index, "where"));
+	cl_git_pass(git_index_add_bypath(index, "who"));
+
+	cl_repo_commit_from_index(NULL, repo, signature, 0, "Initial commit");
+	git_index_free(index);
+
+	cl_assert_equal_i(GIT_ENOTFOUND,
+		git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT));
+
+	p_unlink("stash/when");
+	cl_assert_equal_i(GIT_ENOTFOUND,
+		git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED));
+}
+
+void test_stash_save__can_stage_normal_then_stage_untracked(void)
+{
+	/*
+	 * $ git ls-tree stash@{1}^0
+	 * 100644 blob ac4d88de61733173d9959e4b77c69b9f17a00980    .gitignore
+	 * 100644 blob e6d64adb2c7f3eb8feb493b556cc8070dca379a3    how
+	 * 100644 blob bc99dc98b3eba0e9157e94769cd4d49cb49de449    what
+	 * 100644 blob a0400d4954659306a976567af43125a0b1aa8595    who
+	 *
+	 * $ git ls-tree stash@{1}^1
+	 * 100644 blob ac4d88de61733173d9959e4b77c69b9f17a00980    .gitignore
+	 * 100644 blob ac790413e2d7a26c3767e78c57bb28716686eebc    how
+	 * 100644 blob ce013625030ba8dba906f756967f9e9ca394464a    what
+	 * 100644 blob cc628ccd10742baea8241c5924df992b5c019f71    who
+	 *
+	 * $ git ls-tree stash@{1}^2
+	 * 100644 blob ac4d88de61733173d9959e4b77c69b9f17a00980    .gitignore
+	 * 100644 blob e6d64adb2c7f3eb8feb493b556cc8070dca379a3    how
+	 * 100644 blob dd7e1c6f0fefe118f0b63d9f10908c460aa317a6    what
+	 * 100644 blob cc628ccd10742baea8241c5924df992b5c019f71    who
+	 *
+	 * $ git ls-tree stash@{1}^3
+	 * fatal: Not a valid object name stash@{1}^3
+	 *
+	 * $ git ls-tree stash@{0}^0
+	 * 100644 blob ac4d88de61733173d9959e4b77c69b9f17a00980    .gitignore
+	 * 100644 blob ac790413e2d7a26c3767e78c57bb28716686eebc    how
+	 * 100644 blob ce013625030ba8dba906f756967f9e9ca394464a    what
+	 * 100644 blob cc628ccd10742baea8241c5924df992b5c019f71    who
+	 *
+	 * $ git ls-tree stash@{0}^1
+	 * 100644 blob ac4d88de61733173d9959e4b77c69b9f17a00980    .gitignore
+	 * 100644 blob ac790413e2d7a26c3767e78c57bb28716686eebc    how
+	 * 100644 blob ce013625030ba8dba906f756967f9e9ca394464a    what
+	 * 100644 blob cc628ccd10742baea8241c5924df992b5c019f71    who
+	 *
+	 * $ git ls-tree stash@{0}^2
+	 * 100644 blob ac4d88de61733173d9959e4b77c69b9f17a00980    .gitignore
+	 * 100644 blob ac790413e2d7a26c3767e78c57bb28716686eebc    how
+	 * 100644 blob ce013625030ba8dba906f756967f9e9ca394464a    what
+	 * 100644 blob cc628ccd10742baea8241c5924df992b5c019f71    who
+	 *
+	 * $ git ls-tree stash@{0}^3
+	 * 100644 blob b6ed15e81e2593d7bb6265eb4a991d29dc3e628b    when
+	*/
+
+	assert_status(repo, "what", GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_MODIFIED);
+	assert_status(repo, "how", GIT_STATUS_INDEX_MODIFIED);
+	assert_status(repo, "who", GIT_STATUS_WT_MODIFIED);
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "just.ignore", GIT_STATUS_IGNORED);
+
+	cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT));
+	assert_status(repo, "what", GIT_STATUS_CURRENT);
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_CURRENT);
+	assert_status(repo, "when", GIT_STATUS_WT_NEW);
+	assert_status(repo, "just.ignore", GIT_STATUS_IGNORED);
+
+	cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED));
+	assert_status(repo, "what", GIT_STATUS_CURRENT);
+	assert_status(repo, "how", GIT_STATUS_CURRENT);
+	assert_status(repo, "who", GIT_STATUS_CURRENT);
+	assert_status(repo, "when", GIT_ENOTFOUND);
+	assert_status(repo, "just.ignore", GIT_STATUS_IGNORED);
+
+
+	assert_blob_oid("stash@{1}^0:what", "bc99dc98b3eba0e9157e94769cd4d49cb49de449");	/* see you later */
+	assert_blob_oid("stash@{1}^0:how", "e6d64adb2c7f3eb8feb493b556cc8070dca379a3");		/* not so small and */
+	assert_blob_oid("stash@{1}^0:who", "a0400d4954659306a976567af43125a0b1aa8595");		/* funky world */
+	assert_blob_oid("stash@{1}^0:when", NULL);
+
+	assert_blob_oid("stash@{1}^2:what", "dd7e1c6f0fefe118f0b63d9f10908c460aa317a6");	/* goodbye */
+	assert_blob_oid("stash@{1}^2:how", "e6d64adb2c7f3eb8feb493b556cc8070dca379a3");		/* not so small and */
+	assert_blob_oid("stash@{1}^2:who", "cc628ccd10742baea8241c5924df992b5c019f71");		/* world */
+	assert_blob_oid("stash@{1}^2:when", NULL);
+
+	assert_object_oid("stash@{1}^3", NULL, GIT_OBJ_COMMIT);
+
+	assert_blob_oid("stash@{0}^0:what", "ce013625030ba8dba906f756967f9e9ca394464a");	/* hello */
+	assert_blob_oid("stash@{0}^0:how", "ac790413e2d7a26c3767e78c57bb28716686eebc");		/* small */
+	assert_blob_oid("stash@{0}^0:who", "cc628ccd10742baea8241c5924df992b5c019f71");		/* world */
+	assert_blob_oid("stash@{0}^0:when", NULL);
+
+	assert_blob_oid("stash@{0}^2:what", "ce013625030ba8dba906f756967f9e9ca394464a");	/* hello */
+	assert_blob_oid("stash@{0}^2:how", "ac790413e2d7a26c3767e78c57bb28716686eebc");		/* small */
+	assert_blob_oid("stash@{0}^2:who", "cc628ccd10742baea8241c5924df992b5c019f71");		/* world */
+	assert_blob_oid("stash@{0}^2:when", NULL);
+
+	assert_blob_oid("stash@{0}^3:when", "b6ed15e81e2593d7bb6265eb4a991d29dc3e628b");	/* now */
+}
+
+#define EMPTY_TREE "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
+
+void test_stash_save__including_untracked_without_any_untracked_file_creates_an_empty_tree(void)
+{
+	cl_must_pass(p_unlink("stash/when"));
+
+	assert_status(repo, "what", GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_MODIFIED);
+	assert_status(repo, "how", GIT_STATUS_INDEX_MODIFIED);
+	assert_status(repo, "who", GIT_STATUS_WT_MODIFIED);
+	assert_status(repo, "when", GIT_ENOTFOUND);
+	assert_status(repo, "just.ignore", GIT_STATUS_IGNORED);
+
+	cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED));
+
+	assert_object_oid("stash^3^{tree}", EMPTY_TREE, GIT_OBJ_TREE);
+}
+
+void test_stash_save__ignored_directory(void)
+{
+	cl_git_pass(p_mkdir("stash/ignored_directory", 0777));
+	cl_git_pass(p_mkdir("stash/ignored_directory/sub", 0777));
+	cl_git_mkfile("stash/ignored_directory/sub/some_file", "stuff");
+
+	assert_status(repo, "ignored_directory/sub/some_file", GIT_STATUS_WT_NEW);
+	cl_git_pass(git_ignore_add_rule(repo, "ignored_directory/"));
+	assert_status(repo, "ignored_directory/sub/some_file", GIT_STATUS_IGNORED);
+
+	cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED | GIT_STASH_INCLUDE_IGNORED));
+
+	cl_assert(!git_path_exists("stash/ignored_directory/sub/some_file"));
+	cl_assert(!git_path_exists("stash/ignored_directory/sub"));
+	cl_assert(!git_path_exists("stash/ignored_directory"));
+}
+
+void test_stash_save__skip_submodules(void)
+{
+	git_repository *untracked_repo;
+	cl_git_pass(git_repository_init(&untracked_repo, "stash/untracked_repo", false));
+	cl_git_mkfile("stash/untracked_repo/content", "stuff");
+	git_repository_free(untracked_repo);
+
+	assert_status(repo, "untracked_repo/", GIT_STATUS_WT_NEW);
+
+	cl_git_pass(git_stash_save(
+		&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED));
+
+	assert_status(repo, "untracked_repo/", GIT_STATUS_WT_NEW);
+}
+
+void test_stash_save__deleted_in_index_modified_in_workdir(void)
+{
+	git_index *index;
+
+	git_repository_index(&index, repo);
+
+	cl_git_pass(git_index_remove_bypath(index, "who"));
+	cl_git_pass(git_index_write(index));
+
+	assert_status(repo, "who", GIT_STATUS_WT_NEW | GIT_STATUS_INDEX_DELETED);
+
+	cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT));
+
+	assert_blob_oid("stash@{0}^0:who", "a0400d4954659306a976567af43125a0b1aa8595");
+	assert_blob_oid("stash@{0}^2:who", NULL);
+
+	git_index_free(index);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/stash_helpers.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/stash_helpers.c
new file mode 100755
index 0000000..0398757
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/stash_helpers.c
@@ -0,0 +1,57 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "stash_helpers.h"
+
+void setup_stash(git_repository *repo, git_signature *signature)
+{
+	git_index *index;
+
+	cl_git_pass(git_repository_index(&index, repo));
+
+	cl_git_mkfile("stash/what", "hello\n");		/* ce013625030ba8dba906f756967f9e9ca394464a */
+	cl_git_mkfile("stash/how", "small\n");		/* ac790413e2d7a26c3767e78c57bb28716686eebc */
+	cl_git_mkfile("stash/who", "world\n");		/* cc628ccd10742baea8241c5924df992b5c019f71 */
+	cl_git_mkfile("stash/when", "now\n");		/* b6ed15e81e2593d7bb6265eb4a991d29dc3e628b */
+	cl_git_mkfile("stash/just.ignore", "me\n");	/* 78925fb1236b98b37a35e9723033e627f97aa88b */
+
+	cl_git_mkfile("stash/.gitignore", "*.ignore\n");
+
+	cl_git_pass(git_index_add_bypath(index, "what"));
+	cl_git_pass(git_index_add_bypath(index, "how"));
+	cl_git_pass(git_index_add_bypath(index, "who"));
+	cl_git_pass(git_index_add_bypath(index, ".gitignore"));
+
+	cl_repo_commit_from_index(NULL, repo, signature, 0, "Initial commit");
+
+	cl_git_rewritefile("stash/what", "goodbye\n");			/* dd7e1c6f0fefe118f0b63d9f10908c460aa317a6 */
+	cl_git_rewritefile("stash/how", "not so small and\n");	/* e6d64adb2c7f3eb8feb493b556cc8070dca379a3 */
+	cl_git_rewritefile("stash/who", "funky world\n");		/* a0400d4954659306a976567af43125a0b1aa8595 */
+	cl_git_mkfile("stash/why", "would anybody use stash?\n"); /* 88c2533e21f098b89c91a431d8075cbde422a51 */
+	cl_git_mkfile("stash/where", "????\n");					/* e08f7fbb9a42a0c5367cf8b349f1f08c3d56bd72 */
+
+	cl_git_pass(git_index_add_bypath(index, "what"));
+	cl_git_pass(git_index_add_bypath(index, "how"));
+	cl_git_pass(git_index_add_bypath(index, "why"));
+	cl_git_pass(git_index_add_bypath(index, "where"));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_rewritefile("stash/what", "see you later\n");	/* bc99dc98b3eba0e9157e94769cd4d49cb49de449 */
+	cl_git_mkfile("stash/where", "....\n");					/* e3d6434ec12eb76af8dfa843a64ba6ab91014a0b */
+
+	git_index_free(index);
+}
+
+void assert_status(
+	git_repository *repo,
+	const char *path,
+	int status_flags)
+{
+	unsigned int status;
+
+	if (status_flags < 0)
+		cl_assert_equal_i(status_flags, git_status_file(&status, repo, path));
+	else {
+		cl_git_pass(git_status_file(&status, repo, path));
+		cl_assert_equal_i((unsigned int)status_flags, status);
+	}
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/stash_helpers.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/stash_helpers.h
new file mode 100755
index 0000000..66d758f
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/stash_helpers.h
@@ -0,0 +1,8 @@
+void setup_stash(
+	git_repository *repo,
+	git_signature *signature);
+
+void assert_status(
+	git_repository *repo,
+	const char *path,
+	int status_flags);
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/submodules.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/submodules.c
new file mode 100755
index 0000000..8cadca0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stash/submodules.c
@@ -0,0 +1,83 @@
+#include "clar_libgit2.h"
+#include "stash_helpers.h"
+#include "../submodule/submodule_helpers.h"
+
+static git_repository *repo;
+static git_signature *signature;
+static git_oid stash_tip_oid;
+
+static git_submodule *sm;
+
+void test_stash_submodules__initialize(void)
+{
+	cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas at gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */
+
+	repo = setup_fixture_submodules();
+
+	cl_git_pass(git_submodule_lookup(&sm, repo, "testrepo"));
+}
+
+void test_stash_submodules__cleanup(void)
+{
+	git_submodule_free(sm);
+	sm = NULL;
+
+	git_signature_free(signature);
+	signature = NULL;
+}
+
+void test_stash_submodules__does_not_stash_modified_submodules(void)
+{
+	static git_index *smindex;
+	static git_repository *smrepo;
+
+	assert_status(repo, "modified", GIT_STATUS_WT_MODIFIED);
+
+	/* modify file in submodule */
+	cl_git_rewritefile("submodules/testrepo/README", "heyheyhey");
+	assert_status(repo, "testrepo", GIT_STATUS_WT_MODIFIED);
+
+	/* add file to index in submodule */
+	cl_git_pass(git_submodule_open(&smrepo, sm));
+	cl_git_pass(git_repository_index(&smindex, smrepo));
+	cl_git_pass(git_index_add_bypath(smindex, "README"));
+
+	/* commit changed index of submodule */
+	cl_repo_commit_from_index(NULL, smrepo, NULL, 1372350000, "Modify it");
+	assert_status(repo, "testrepo", GIT_STATUS_WT_MODIFIED);
+
+	cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT));
+
+	assert_status(repo, "testrepo", GIT_STATUS_WT_MODIFIED);
+	assert_status(repo, "modified", GIT_STATUS_CURRENT);
+
+	git_index_free(smindex);
+	git_repository_free(smrepo);
+}
+
+void test_stash_submodules__stash_is_empty_with_modified_submodules(void)
+{
+	static git_index *smindex;
+	static git_repository *smrepo;
+
+	cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT));
+	assert_status(repo, "modified", GIT_STATUS_CURRENT);
+
+	/* modify file in submodule */
+	cl_git_rewritefile("submodules/testrepo/README", "heyheyhey");
+	assert_status(repo, "testrepo", GIT_STATUS_WT_MODIFIED);
+
+	/* add file to index in submodule */
+	cl_git_pass(git_submodule_open(&smrepo, sm));
+	cl_git_pass(git_repository_index(&smindex, smrepo));
+	cl_git_pass(git_index_add_bypath(smindex, "README"));
+
+	/* commit changed index of submodule */
+	cl_repo_commit_from_index(NULL, smrepo, NULL, 1372350000, "Modify it");
+	assert_status(repo, "testrepo", GIT_STATUS_WT_MODIFIED);
+
+	cl_git_fail_with(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT), GIT_ENOTFOUND);
+
+	git_index_free(smindex);
+	git_repository_free(smrepo);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/ignore.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/ignore.c
new file mode 100755
index 0000000..ba1d69a
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/ignore.c
@@ -0,0 +1,1024 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "git2/attr.h"
+#include "ignore.h"
+#include "attr.h"
+#include "status_helpers.h"
+
+static git_repository *g_repo = NULL;
+
+void test_status_ignore__initialize(void)
+{
+}
+
+void test_status_ignore__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static void assert_ignored_(
+	bool expected, const char *filepath, const char *file, int line)
+{
+	int is_ignored = 0;
+	cl_git_pass_(
+		git_status_should_ignore(&is_ignored, g_repo, filepath), file, line);
+	clar__assert(
+		(expected != 0) == (is_ignored != 0),
+		file, line, "expected != is_ignored", filepath, 1);
+}
+#define assert_ignored(expected, filepath) \
+	assert_ignored_(expected, filepath, __FILE__, __LINE__)
+#define assert_is_ignored(filepath) \
+	assert_ignored_(true, filepath, __FILE__, __LINE__)
+#define refute_is_ignored(filepath) \
+	assert_ignored_(false, filepath, __FILE__, __LINE__)
+
+void test_status_ignore__0(void)
+{
+	struct {
+		const char *path;
+		int expected;
+	} test_cases[] = {
+		/* pattern "ign" from .gitignore */
+		{ "file", 0 },
+		{ "ign", 1 },
+		{ "sub", 0 },
+		{ "sub/file", 0 },
+		{ "sub/ign", 1 },
+		{ "sub/ign/file", 1 },
+		{ "sub/ign/sub", 1 },
+		{ "sub/ign/sub/file", 1 },
+		{ "sub/sub", 0 },
+		{ "sub/sub/file", 0 },
+		{ "sub/sub/ign", 1 },
+		{ "sub/sub/sub", 0 },
+		/* pattern "dir/" from .gitignore */
+		{ "dir", 1 },
+		{ "dir/", 1 },
+		{ "sub/dir", 1 },
+		{ "sub/dir/", 1 },
+		{ "sub/dir/file", 1 }, /* contained in ignored parent */
+		{ "sub/sub/dir", 0 }, /* dir is not actually a dir, but a file */
+		{ NULL, 0 }
+	}, *one_test;
+
+	g_repo = cl_git_sandbox_init("attr");
+
+	for (one_test = test_cases; one_test->path != NULL; one_test++)
+		assert_ignored(one_test->expected, one_test->path);
+
+	/* confirm that ignore files were cached */
+	cl_assert(git_attr_cache__is_cached(
+		g_repo, GIT_ATTR_FILE__FROM_FILE, ".git/info/exclude"));
+	cl_assert(git_attr_cache__is_cached(
+		g_repo, GIT_ATTR_FILE__FROM_FILE, ".gitignore"));
+}
+
+
+void test_status_ignore__1(void)
+{
+	g_repo = cl_git_sandbox_init("attr");
+
+	cl_git_rewritefile("attr/.gitignore", "/*.txt\n/dir/\n");
+	git_attr_cache_flush(g_repo);
+
+	assert_is_ignored("root_test4.txt");
+	refute_is_ignored("sub/subdir_test2.txt");
+	assert_is_ignored("dir");
+	assert_is_ignored("dir/");
+	refute_is_ignored("sub/dir");
+	refute_is_ignored("sub/dir/");
+}
+
+void test_status_ignore__empty_repo_with_gitignore_rewrite(void)
+{
+	status_entry_single st;
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+	cl_git_mkfile(
+		"empty_standard_repo/look-ma.txt", "I'm going to be ignored!");
+
+	memset(&st, 0, sizeof(st));
+	cl_git_pass(git_status_foreach(g_repo, cb_status__single, &st));
+	cl_assert(st.count == 1);
+	cl_assert(st.status == GIT_STATUS_WT_NEW);
+
+	cl_git_pass(git_status_file(&st.status, g_repo, "look-ma.txt"));
+	cl_assert(st.status == GIT_STATUS_WT_NEW);
+
+	refute_is_ignored("look-ma.txt");
+
+	cl_git_rewritefile("empty_standard_repo/.gitignore", "*.nomatch\n");
+
+	memset(&st, 0, sizeof(st));
+	cl_git_pass(git_status_foreach(g_repo, cb_status__single, &st));
+	cl_assert(st.count == 2);
+	cl_assert(st.status == GIT_STATUS_WT_NEW);
+
+	cl_git_pass(git_status_file(&st.status, g_repo, "look-ma.txt"));
+	cl_assert(st.status == GIT_STATUS_WT_NEW);
+
+	refute_is_ignored("look-ma.txt");
+
+	cl_git_rewritefile("empty_standard_repo/.gitignore", "*.txt\n");
+
+	memset(&st, 0, sizeof(st));
+	cl_git_pass(git_status_foreach(g_repo, cb_status__single, &st));
+	cl_assert(st.count == 2);
+	cl_assert(st.status == GIT_STATUS_IGNORED);
+
+	cl_git_pass(git_status_file(&st.status, g_repo, "look-ma.txt"));
+	cl_assert(st.status == GIT_STATUS_IGNORED);
+
+	assert_is_ignored("look-ma.txt");
+}
+
+void test_status_ignore__ignore_pattern_contains_space(void)
+{
+	unsigned int flags;
+	const mode_t mode = 0777;
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+	cl_git_rewritefile("empty_standard_repo/.gitignore", "foo bar.txt\n");
+
+	cl_git_mkfile(
+		"empty_standard_repo/foo bar.txt", "I'm going to be ignored!");
+
+	cl_git_pass(git_status_file(&flags, g_repo, "foo bar.txt"));
+	cl_assert(flags == GIT_STATUS_IGNORED);
+
+	cl_git_pass(git_futils_mkdir_r("empty_standard_repo/foo", NULL, mode));
+	cl_git_mkfile("empty_standard_repo/foo/look-ma.txt", "I'm not going to be ignored!");
+
+	cl_git_pass(git_status_file(&flags, g_repo, "foo/look-ma.txt"));
+	cl_assert(flags == GIT_STATUS_WT_NEW);
+}
+
+void test_status_ignore__ignore_pattern_ignorecase(void)
+{
+	unsigned int flags;
+	bool ignore_case;
+	git_index *index;
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+	cl_git_rewritefile("empty_standard_repo/.gitignore", "a.txt\n");
+
+	cl_git_mkfile("empty_standard_repo/A.txt", "Differs in case");
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	ignore_case = (git_index_caps(index) & GIT_INDEXCAP_IGNORE_CASE) != 0;
+	git_index_free(index);
+
+	cl_git_pass(git_status_file(&flags, g_repo, "A.txt"));
+	cl_assert(flags == ignore_case ? GIT_STATUS_IGNORED : GIT_STATUS_WT_NEW);
+}
+
+void test_status_ignore__subdirectories(void)
+{
+	status_entry_single st;
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+	cl_git_mkfile(
+		"empty_standard_repo/ignore_me", "I'm going to be ignored!");
+
+	cl_git_rewritefile("empty_standard_repo/.gitignore", "ignore_me\n");
+
+	memset(&st, 0, sizeof(st));
+	cl_git_pass(git_status_foreach(g_repo, cb_status__single, &st));
+	cl_assert_equal_i(2, st.count);
+	cl_assert(st.status == GIT_STATUS_IGNORED);
+
+	cl_git_pass(git_status_file(&st.status, g_repo, "ignore_me"));
+	cl_assert(st.status == GIT_STATUS_IGNORED);
+
+	assert_is_ignored("ignore_me");
+
+	/* I've changed libgit2 so that the behavior here now differs from
+	 * core git but seems to make more sense.  In core git, the following
+	 * items are skipped completed, even if --ignored is passed to status.
+	 * It you mirror these steps and run "git status -uall --ignored" then
+	 * you will not see "test/ignore_me/" in the results.
+	 *
+	 * However, we had a couple reports of this as a bug, plus there is a
+	 * similar circumstance where we were differing for core git when you
+	 * used a rooted path for an ignore, so I changed this behavior.
+	 */
+	cl_git_pass(git_futils_mkdir_r(
+		"empty_standard_repo/test/ignore_me", NULL, 0775));
+	cl_git_mkfile(
+		"empty_standard_repo/test/ignore_me/file", "I'm going to be ignored!");
+	cl_git_mkfile(
+		"empty_standard_repo/test/ignore_me/file2", "Me, too!");
+
+	memset(&st, 0, sizeof(st));
+	cl_git_pass(git_status_foreach(g_repo, cb_status__single, &st));
+	cl_assert_equal_i(3, st.count);
+
+	cl_git_pass(git_status_file(&st.status, g_repo, "test/ignore_me/file"));
+	cl_assert(st.status == GIT_STATUS_IGNORED);
+
+	assert_is_ignored("test/ignore_me/file");
+}
+
+static void make_test_data(const char *reponame, const char **files)
+{
+	const char **scan;
+	size_t repolen = strlen(reponame) + 1;
+
+	g_repo = cl_git_sandbox_init(reponame);
+
+	for (scan = files; *scan != NULL; ++scan) {
+		cl_git_pass(git_futils_mkdir(
+			*scan + repolen, reponame,
+			0777, GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST));
+		cl_git_mkfile(*scan, "contents");
+	}
+}
+
+static const char *test_repo_1 = "empty_standard_repo";
+static const char *test_files_1[] = {
+	"empty_standard_repo/dir/a/ignore_me",
+	"empty_standard_repo/dir/b/ignore_me",
+	"empty_standard_repo/dir/ignore_me",
+	"empty_standard_repo/ignore_also/file",
+	"empty_standard_repo/ignore_me",
+	"empty_standard_repo/test/ignore_me/file",
+	"empty_standard_repo/test/ignore_me/file2",
+	"empty_standard_repo/test/ignore_me/and_me/file",
+	NULL
+};
+
+void test_status_ignore__subdirectories_recursion(void)
+{
+	/* Let's try again with recursing into ignored dirs turned on */
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	status_entry_counts counts;
+	static const char *paths_r[] = {
+		".gitignore",
+		"dir/a/ignore_me",
+		"dir/b/ignore_me",
+		"dir/ignore_me",
+		"ignore_also/file",
+		"ignore_me",
+		"test/ignore_me/and_me/file",
+		"test/ignore_me/file",
+		"test/ignore_me/file2",
+	};
+	static const unsigned int statuses_r[] = {
+		GIT_STATUS_WT_NEW,  GIT_STATUS_IGNORED, GIT_STATUS_IGNORED,
+		GIT_STATUS_IGNORED, GIT_STATUS_IGNORED, GIT_STATUS_IGNORED,
+		GIT_STATUS_IGNORED, GIT_STATUS_IGNORED, GIT_STATUS_IGNORED,
+	};
+	static const char *paths_nr[] = {
+		".gitignore",
+		"dir/a/ignore_me",
+		"dir/b/ignore_me",
+		"dir/ignore_me",
+		"ignore_also/",
+		"ignore_me",
+		"test/ignore_me/",
+	};
+	static const unsigned int statuses_nr[] = {
+		GIT_STATUS_WT_NEW,
+		GIT_STATUS_IGNORED, GIT_STATUS_IGNORED, GIT_STATUS_IGNORED,
+		GIT_STATUS_IGNORED, GIT_STATUS_IGNORED, GIT_STATUS_IGNORED,
+	};
+
+	make_test_data(test_repo_1, test_files_1);
+	cl_git_rewritefile("empty_standard_repo/.gitignore", "ignore_me\n/ignore_also\n");
+
+	memset(&counts, 0x0, sizeof(status_entry_counts));
+	counts.expected_entry_count = 9;
+	counts.expected_paths = paths_r;
+	counts.expected_statuses = statuses_r;
+
+	opts.flags = GIT_STATUS_OPT_DEFAULTS | GIT_STATUS_OPT_RECURSE_IGNORED_DIRS;
+
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__normal, &counts));
+
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+
+
+	memset(&counts, 0x0, sizeof(status_entry_counts));
+	counts.expected_entry_count = 7;
+	counts.expected_paths = paths_nr;
+	counts.expected_statuses = statuses_nr;
+
+	opts.flags = GIT_STATUS_OPT_DEFAULTS;
+
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__normal, &counts));
+
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+}
+
+void test_status_ignore__subdirectories_not_at_root(void)
+{
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	status_entry_counts counts;
+	static const char *paths_1[] = {
+		"dir/.gitignore",
+		"dir/a/ignore_me",
+		"dir/b/ignore_me",
+		"dir/ignore_me",
+		"ignore_also/file",
+		"ignore_me",
+		"test/.gitignore",
+		"test/ignore_me/and_me/file",
+		"test/ignore_me/file",
+		"test/ignore_me/file2",
+	};
+	static const unsigned int statuses_1[] = {
+		GIT_STATUS_WT_NEW,  GIT_STATUS_IGNORED, GIT_STATUS_IGNORED,
+		GIT_STATUS_IGNORED, GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW,
+		GIT_STATUS_WT_NEW, GIT_STATUS_IGNORED, GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW,
+	};
+
+	make_test_data(test_repo_1, test_files_1);
+	cl_git_rewritefile("empty_standard_repo/dir/.gitignore", "ignore_me\n/ignore_also\n");
+	cl_git_rewritefile("empty_standard_repo/test/.gitignore", "and_me\n");
+
+	memset(&counts, 0x0, sizeof(status_entry_counts));
+	counts.expected_entry_count = 10;
+	counts.expected_paths = paths_1;
+	counts.expected_statuses = statuses_1;
+
+	opts.flags = GIT_STATUS_OPT_DEFAULTS | GIT_STATUS_OPT_RECURSE_IGNORED_DIRS;
+
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__normal, &counts));
+
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+}
+
+void test_status_ignore__leading_slash_ignores(void)
+{
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	status_entry_counts counts;
+	static const char *paths_2[] = {
+		"dir/.gitignore",
+		"dir/a/ignore_me",
+		"dir/b/ignore_me",
+		"dir/ignore_me",
+		"ignore_also/file",
+		"ignore_me",
+		"test/.gitignore",
+		"test/ignore_me/and_me/file",
+		"test/ignore_me/file",
+		"test/ignore_me/file2",
+	};
+	static const unsigned int statuses_2[] = {
+		GIT_STATUS_WT_NEW,  GIT_STATUS_WT_NEW,  GIT_STATUS_WT_NEW,
+		GIT_STATUS_IGNORED, GIT_STATUS_IGNORED, GIT_STATUS_IGNORED,
+		GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW,
+	};
+
+	make_test_data(test_repo_1, test_files_1);
+
+	cl_fake_home();
+	cl_git_mkfile("home/.gitignore", "/ignore_me\n");
+	{
+		git_config *cfg;
+		cl_git_pass(git_repository_config(&cfg, g_repo));
+		cl_git_pass(git_config_set_string(
+			cfg, "core.excludesfile", "~/.gitignore"));
+		git_config_free(cfg);
+	}
+
+	cl_git_rewritefile("empty_standard_repo/.git/info/exclude", "/ignore_also\n");
+	cl_git_rewritefile("empty_standard_repo/dir/.gitignore", "/ignore_me\n");
+	cl_git_rewritefile("empty_standard_repo/test/.gitignore", "/and_me\n");
+
+	memset(&counts, 0x0, sizeof(status_entry_counts));
+	counts.expected_entry_count = 10;
+	counts.expected_paths = paths_2;
+	counts.expected_statuses = statuses_2;
+
+	opts.flags = GIT_STATUS_OPT_DEFAULTS | GIT_STATUS_OPT_RECURSE_IGNORED_DIRS;
+
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__normal, &counts));
+
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+}
+
+void test_status_ignore__contained_dir_with_matching_name(void)
+{
+	static const char *test_files[] = {
+		"empty_standard_repo/subdir_match/aaa/subdir_match/file",
+		"empty_standard_repo/subdir_match/zzz_ignoreme",
+		NULL
+	};
+	static const char *expected_paths[] = {
+		"subdir_match/.gitignore",
+		"subdir_match/aaa/subdir_match/file",
+		"subdir_match/zzz_ignoreme",
+	};
+	static const unsigned int expected_statuses[] = {
+		GIT_STATUS_WT_NEW,  GIT_STATUS_WT_NEW,  GIT_STATUS_IGNORED
+	};
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	status_entry_counts counts;
+
+	make_test_data("empty_standard_repo", test_files);
+	cl_git_mkfile(
+		"empty_standard_repo/subdir_match/.gitignore", "*_ignoreme\n");
+
+	refute_is_ignored("subdir_match/aaa/subdir_match/file");
+	assert_is_ignored("subdir_match/zzz_ignoreme");
+
+	memset(&counts, 0x0, sizeof(status_entry_counts));
+	counts.expected_entry_count = 3;
+	counts.expected_paths = expected_paths;
+	counts.expected_statuses = expected_statuses;
+
+	opts.flags = GIT_STATUS_OPT_DEFAULTS | GIT_STATUS_OPT_RECURSE_IGNORED_DIRS;
+
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__normal, &counts));
+
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+}
+
+void test_status_ignore__trailing_slash_star(void)
+{
+	static const char *test_files[] = {
+		"empty_standard_repo/file",
+		"empty_standard_repo/subdir/file",
+		"empty_standard_repo/subdir/sub2/sub3/file",
+		NULL
+	};
+
+	make_test_data("empty_standard_repo", test_files);
+	cl_git_mkfile(
+		"empty_standard_repo/subdir/.gitignore", "/**/*\n");
+
+	refute_is_ignored("file");
+	assert_is_ignored("subdir/sub2/sub3/file");
+	assert_is_ignored("subdir/file");
+}
+
+void test_status_ignore__adding_internal_ignores(void)
+{
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+	refute_is_ignored("one.txt");
+	refute_is_ignored("two.bar");
+
+	cl_git_pass(git_ignore_add_rule(g_repo, "*.nomatch\n"));
+
+	refute_is_ignored("one.txt");
+	refute_is_ignored("two.bar");
+
+	cl_git_pass(git_ignore_add_rule(g_repo, "*.txt\n"));
+
+	assert_is_ignored("one.txt");
+	refute_is_ignored("two.bar");
+
+	cl_git_pass(git_ignore_add_rule(g_repo, "*.bar\n"));
+
+	assert_is_ignored("one.txt");
+	assert_is_ignored("two.bar");
+
+	cl_git_pass(git_ignore_clear_internal_rules(g_repo));
+
+	refute_is_ignored("one.txt");
+	refute_is_ignored("two.bar");
+
+	cl_git_pass(git_ignore_add_rule(
+		g_repo, "multiple\n*.rules\n# comment line\n*.bar\n"));
+
+	refute_is_ignored("one.txt");
+	assert_is_ignored("two.bar");
+}
+
+void test_status_ignore__add_internal_as_first_thing(void)
+{
+	const char *add_me = "\n#################\n## Eclipse\n#################\n\n*.pydevproject\n.project\n.metadata\nbin/\ntmp/\n*.tmp\n\n";
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+	cl_git_pass(git_ignore_add_rule(g_repo, add_me));
+
+	assert_is_ignored("one.tmp");
+	refute_is_ignored("two.bar");
+}
+
+void test_status_ignore__internal_ignores_inside_deep_paths(void)
+{
+	const char *add_me = "Debug\nthis/is/deep\npatterned*/dir\n";
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+	cl_git_pass(git_ignore_add_rule(g_repo, add_me));
+
+	assert_is_ignored("Debug");
+	assert_is_ignored("and/Debug");
+	assert_is_ignored("really/Debug/this/file");
+	assert_is_ignored("Debug/what/I/say");
+
+	refute_is_ignored("and/NoDebug");
+	refute_is_ignored("NoDebug/this");
+	refute_is_ignored("please/NoDebug/this");
+
+	assert_is_ignored("this/is/deep");
+	/* pattern containing slash gets FNM_PATHNAME so all slashes must match */
+	refute_is_ignored("and/this/is/deep");
+	assert_is_ignored("this/is/deep/too");
+	/* pattern containing slash gets FNM_PATHNAME so all slashes must match */
+	refute_is_ignored("but/this/is/deep/and/ignored");
+
+	refute_is_ignored("this/is/not/deep");
+	refute_is_ignored("is/this/not/as/deep");
+	refute_is_ignored("this/is/deepish");
+	refute_is_ignored("xthis/is/deep");
+}
+
+void test_status_ignore__automatically_ignore_bad_files(void)
+{
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+	assert_is_ignored(".git");
+	assert_is_ignored("this/file/.");
+	assert_is_ignored("path/../funky");
+	refute_is_ignored("path/whatever.c");
+
+	cl_git_pass(git_ignore_add_rule(g_repo, "*.c\n"));
+
+	assert_is_ignored(".git");
+	assert_is_ignored("this/file/.");
+	assert_is_ignored("path/../funky");
+	assert_is_ignored("path/whatever.c");
+
+	cl_git_pass(git_ignore_clear_internal_rules(g_repo));
+
+	assert_is_ignored(".git");
+	assert_is_ignored("this/file/.");
+	assert_is_ignored("path/../funky");
+	refute_is_ignored("path/whatever.c");
+}
+
+void test_status_ignore__filenames_with_special_prefixes_do_not_interfere_with_status_retrieval(void)
+{
+	status_entry_single st;
+	char *test_cases[] = {
+		"!file",
+		"#blah",
+		"[blah]",
+		"[attr]",
+		"[attr]blah",
+		NULL
+	};
+	int i;
+
+	for (i = 0; *(test_cases + i) != NULL; i++) {
+		git_buf file = GIT_BUF_INIT;
+		char *file_name = *(test_cases + i);
+		git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
+
+		cl_git_pass(git_buf_joinpath(&file, "empty_standard_repo", file_name));
+		cl_git_mkfile(git_buf_cstr(&file), "Please don't ignore me!");
+
+		memset(&st, 0, sizeof(st));
+		cl_git_pass(git_status_foreach(repo, cb_status__single, &st));
+		cl_assert(st.count == 1);
+		cl_assert(st.status == GIT_STATUS_WT_NEW);
+
+		cl_git_pass(git_status_file(&st.status, repo, file_name));
+		cl_assert(st.status == GIT_STATUS_WT_NEW);
+
+		cl_git_sandbox_cleanup();
+		git_buf_free(&file);
+	}
+}
+
+void test_status_ignore__issue_1766_negated_ignores(void)
+{
+	unsigned int status;
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+	cl_git_pass(git_futils_mkdir_r(
+		"empty_standard_repo/a", NULL, 0775));
+	cl_git_mkfile(
+		"empty_standard_repo/a/.gitignore", "*\n!.gitignore\n");
+	cl_git_mkfile(
+		"empty_standard_repo/a/ignoreme", "I should be ignored\n");
+
+	refute_is_ignored("a/.gitignore");
+	assert_is_ignored("a/ignoreme");
+
+	cl_git_pass(git_futils_mkdir_r(
+		"empty_standard_repo/b", NULL, 0775));
+	cl_git_mkfile(
+		"empty_standard_repo/b/.gitignore", "*\n!.gitignore\n");
+	cl_git_mkfile(
+		"empty_standard_repo/b/ignoreme", "I should be ignored\n");
+
+	refute_is_ignored("b/.gitignore");
+	assert_is_ignored("b/ignoreme");
+
+	/* shouldn't have changed results from first couple either */
+	refute_is_ignored("a/.gitignore");
+	assert_is_ignored("a/ignoreme");
+
+	/* status should find the two ignore files and nothing else */
+
+	cl_git_pass(git_status_file(&status, g_repo, "a/.gitignore"));
+	cl_assert_equal_i(GIT_STATUS_WT_NEW, (int)status);
+
+	cl_git_pass(git_status_file(&status, g_repo, "a/ignoreme"));
+	cl_assert_equal_i(GIT_STATUS_IGNORED, (int)status);
+
+	cl_git_pass(git_status_file(&status, g_repo, "b/.gitignore"));
+	cl_assert_equal_i(GIT_STATUS_WT_NEW, (int)status);
+
+	cl_git_pass(git_status_file(&status, g_repo, "b/ignoreme"));
+	cl_assert_equal_i(GIT_STATUS_IGNORED, (int)status);
+
+	{
+		git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+		status_entry_counts counts;
+		static const char *paths[] = {
+			"a/.gitignore",
+			"a/ignoreme",
+			"b/.gitignore",
+			"b/ignoreme",
+		};
+		static const unsigned int statuses[] = {
+			GIT_STATUS_WT_NEW,
+			GIT_STATUS_IGNORED,
+			GIT_STATUS_WT_NEW,
+			GIT_STATUS_IGNORED,
+		};
+
+		memset(&counts, 0x0, sizeof(status_entry_counts));
+		counts.expected_entry_count = 4;
+		counts.expected_paths = paths;
+		counts.expected_statuses = statuses;
+
+		opts.flags = GIT_STATUS_OPT_DEFAULTS;
+
+		cl_git_pass(git_status_foreach_ext(
+			g_repo, &opts, cb_status__normal, &counts));
+
+		cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+		cl_assert_equal_i(0, counts.wrong_status_flags_count);
+		cl_assert_equal_i(0, counts.wrong_sorted_path);
+	}
+}
+
+static void add_one_to_index(const char *file)
+{
+	git_index *index;
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_index_add_bypath(index, file));
+	git_index_free(index);
+}
+
+/* Some further broken scenarios that have been reported */
+void test_status_ignore__more_breakage(void)
+{
+	static const char *test_files[] = {
+		"empty_standard_repo/d1/pfx-d2/d3/d4/d5/tracked",
+		"empty_standard_repo/d1/pfx-d2/d3/d4/d5/untracked",
+		"empty_standard_repo/d1/pfx-d2/d3/d4/untracked",
+		NULL
+	};
+
+	make_test_data("empty_standard_repo", test_files);
+	cl_git_mkfile(
+		"empty_standard_repo/.gitignore",
+		"/d1/pfx-*\n"
+		"!/d1/pfx-d2/\n"
+		"/d1/pfx-d2/*\n"
+		"!/d1/pfx-d2/d3/\n"
+		"/d1/pfx-d2/d3/*\n"
+		"!/d1/pfx-d2/d3/d4/\n");
+	add_one_to_index("d1/pfx-d2/d3/d4/d5/tracked");
+
+	{
+		git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+		status_entry_counts counts;
+		static const char *files[] = {
+			".gitignore",
+			"d1/pfx-d2/d3/d4/d5/tracked",
+			"d1/pfx-d2/d3/d4/d5/untracked",
+			"d1/pfx-d2/d3/d4/untracked",
+		};
+		static const unsigned int statuses[] = {
+			GIT_STATUS_WT_NEW,
+			GIT_STATUS_INDEX_NEW,
+			GIT_STATUS_WT_NEW,
+			GIT_STATUS_WT_NEW,
+		};
+
+		memset(&counts, 0x0, sizeof(status_entry_counts));
+		counts.expected_entry_count = 4;
+		counts.expected_paths = files;
+		counts.expected_statuses = statuses;
+		opts.flags = GIT_STATUS_OPT_DEFAULTS |
+			GIT_STATUS_OPT_INCLUDE_IGNORED |
+			GIT_STATUS_OPT_RECURSE_IGNORED_DIRS;
+		cl_git_pass(git_status_foreach_ext(
+			g_repo, &opts, cb_status__normal, &counts));
+
+		cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+		cl_assert_equal_i(0, counts.wrong_status_flags_count);
+		cl_assert_equal_i(0, counts.wrong_sorted_path);
+	}
+
+	refute_is_ignored("d1/pfx-d2/d3/d4/d5/tracked");
+	refute_is_ignored("d1/pfx-d2/d3/d4/d5/untracked");
+	refute_is_ignored("d1/pfx-d2/d3/d4/untracked");
+}
+
+void test_status_ignore__negative_ignores_inside_ignores(void)
+{
+	static const char *test_files[] = {
+		"empty_standard_repo/top/mid/btm/tracked",
+		"empty_standard_repo/top/mid/btm/untracked",
+		"empty_standard_repo/zoo/bar",
+		"empty_standard_repo/zoo/foo/bar",
+		NULL
+	};
+
+	make_test_data("empty_standard_repo", test_files);
+	cl_git_mkfile(
+		"empty_standard_repo/.gitignore",
+		"top\n"
+		"!top/mid/btm\n"
+		"zoo/*\n"
+		"!zoo/bar\n"
+		"!zoo/foo/bar\n");
+	add_one_to_index("top/mid/btm/tracked");
+
+	{
+		git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+		status_entry_counts counts;
+		static const char *files[] = {
+			".gitignore", "top/mid/btm/tracked", "top/mid/btm/untracked",
+			"zoo/bar", "zoo/foo/bar",
+		};
+		static const unsigned int statuses[] = {
+			GIT_STATUS_WT_NEW, GIT_STATUS_INDEX_NEW, GIT_STATUS_IGNORED,
+			GIT_STATUS_WT_NEW, GIT_STATUS_IGNORED,
+		};
+
+		memset(&counts, 0x0, sizeof(status_entry_counts));
+		counts.expected_entry_count = 5;
+		counts.expected_paths = files;
+		counts.expected_statuses = statuses;
+		opts.flags = GIT_STATUS_OPT_DEFAULTS |
+			GIT_STATUS_OPT_INCLUDE_IGNORED |
+			GIT_STATUS_OPT_RECURSE_IGNORED_DIRS;
+		cl_git_pass(git_status_foreach_ext(
+			g_repo, &opts, cb_status__normal, &counts));
+
+		cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+		cl_assert_equal_i(0, counts.wrong_status_flags_count);
+		cl_assert_equal_i(0, counts.wrong_sorted_path);
+	}
+
+	assert_is_ignored("top/mid/btm/tracked");
+	assert_is_ignored("top/mid/btm/untracked");
+	refute_is_ignored("foo/bar");
+}
+
+void test_status_ignore__negative_ignores_in_slash_star(void)
+{
+	git_status_options status_opts = GIT_STATUS_OPTIONS_INIT;
+	git_status_list *list;
+	int found_look_ma = 0, found_what_about = 0;
+	size_t i;
+	static const char *test_files[] = {
+		"empty_standard_repo/bin/look-ma.txt",
+		"empty_standard_repo/bin/what-about-me.txt",
+		NULL
+	};
+
+	make_test_data("empty_standard_repo", test_files);
+	cl_git_mkfile(
+		"empty_standard_repo/.gitignore",
+		"bin/*\n"
+		"!bin/w*\n");
+
+	assert_is_ignored("bin/look-ma.txt");
+	refute_is_ignored("bin/what-about-me.txt");
+
+	status_opts.flags = GIT_STATUS_OPT_DEFAULTS;
+	cl_git_pass(git_status_list_new(&list, g_repo, &status_opts));
+	for (i = 0; i < git_status_list_entrycount(list); i++) {
+		const git_status_entry *entry = git_status_byindex(list, i);
+
+		if (!strcmp("bin/look-ma.txt", entry->index_to_workdir->new_file.path))
+			found_look_ma = 1;
+
+		if (!strcmp("bin/what-about-me.txt", entry->index_to_workdir->new_file.path))
+			found_what_about = 1;
+	}
+	git_status_list_free(list);
+
+	cl_assert(found_look_ma);
+	cl_assert(found_what_about);
+}
+
+void test_status_ignore__negative_ignores_without_trailing_slash_inside_ignores(void)
+{
+	git_status_options status_opts = GIT_STATUS_OPTIONS_INIT;
+	git_status_list *list;
+	int found_parent_file = 0, found_parent_child1_file = 0, found_parent_child2_file = 0;
+	size_t i;
+	static const char *test_files[] = {
+		"empty_standard_repo/parent/file.txt",
+		"empty_standard_repo/parent/force.txt",
+		"empty_standard_repo/parent/child1/file.txt",
+		"empty_standard_repo/parent/child2/file.txt",
+		NULL
+	};
+
+	make_test_data("empty_standard_repo", test_files);
+	cl_git_mkfile(
+		"empty_standard_repo/.gitignore",
+		"parent/*\n"
+		"!parent/force.txt\n"
+		"!parent/child1\n"
+		"!parent/child2/\n");
+
+	add_one_to_index("parent/force.txt");
+
+	assert_is_ignored("parent/file.txt");
+	refute_is_ignored("parent/force.txt");
+	refute_is_ignored("parent/child1/file.txt");
+	refute_is_ignored("parent/child2/file.txt");
+
+	status_opts.flags = GIT_STATUS_OPT_DEFAULTS;
+	cl_git_pass(git_status_list_new(&list, g_repo, &status_opts));
+	for (i = 0; i < git_status_list_entrycount(list); i++) {
+		const git_status_entry *entry = git_status_byindex(list, i);
+
+		if (!entry->index_to_workdir)
+			continue;
+
+		if (!strcmp("parent/file.txt", entry->index_to_workdir->new_file.path))
+			found_parent_file = 1;
+
+		if (!strcmp("parent/force.txt", entry->index_to_workdir->new_file.path))
+			found_parent_file = 1;
+
+		if (!strcmp("parent/child1/file.txt", entry->index_to_workdir->new_file.path))
+			found_parent_child1_file = 1;
+
+		if (!strcmp("parent/child2/file.txt", entry->index_to_workdir->new_file.path))
+			found_parent_child2_file = 1;
+	}
+	git_status_list_free(list);
+
+	cl_assert(found_parent_file);
+	cl_assert(found_parent_child1_file);
+	cl_assert(found_parent_child2_file);
+}
+
+void test_status_ignore__negative_directory_ignores(void)
+{
+	static const char *test_files[] = {
+		"empty_standard_repo/parent/child1/bar.txt",
+		"empty_standard_repo/parent/child2/bar.txt",
+		"empty_standard_repo/parent/child3/foo.txt",
+		"empty_standard_repo/parent/child4/bar.txt",
+		"empty_standard_repo/parent/nested/child5/bar.txt",
+		"empty_standard_repo/parent/nested/child6/bar.txt",
+		"empty_standard_repo/parent/nested/child7/bar.txt",
+		"empty_standard_repo/padded_parent/child8/bar.txt",
+		NULL
+	};
+
+	make_test_data("empty_standard_repo", test_files);
+	cl_git_mkfile(
+		"empty_standard_repo/.gitignore",
+		"foo.txt\n"
+		"parent/child1\n"
+		"parent/child2\n"
+		"parent/child4\n"
+		"parent/nested/child5\n"
+		"nested/child6\n"
+		"nested/child7\n"
+		"padded_parent/child8\n"
+		/* test simple exact match */
+		"!parent/child1\n"
+		/* test negating file without negating dir */
+		"!parent/child2/bar.txt\n"
+		/* test negative pattern on dir with its content
+		 * being ignored */
+		"!parent/child3\n"
+		/* test with partial match at end */
+		"!child4\n"
+		/* test with partial match with '/' at end */
+		"!nested/child5\n"
+		/* test with complete match */
+		"!nested/child6\n"
+		/* test with trailing '/' */
+		"!child7/\n"
+		/* test with partial dir match */
+		"!_parent/child8\n");
+
+	refute_is_ignored("parent/child1/bar.txt");
+	assert_is_ignored("parent/child2/bar.txt");
+	assert_is_ignored("parent/child3/foo.txt");
+	refute_is_ignored("parent/child4/bar.txt");
+	assert_is_ignored("parent/nested/child5/bar.txt");
+	refute_is_ignored("parent/nested/child6/bar.txt");
+	refute_is_ignored("parent/nested/child7/bar.txt");
+	assert_is_ignored("padded_parent/child8/bar.txt");
+}
+
+void test_status_ignore__filename_with_cr(void)
+{
+	int ignored;
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+	cl_git_mkfile("empty_standard_repo/.gitignore", "Icon\r\r\n");
+
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "Icon\r"));
+	cl_assert_equal_i(1, ignored);
+
+	cl_git_mkfile("empty_standard_repo/.gitignore", "Ico\rn\n");
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "Ico\rn"));
+	cl_assert_equal_i(1, ignored);
+
+	cl_git_mkfile("empty_standard_repo/.gitignore", "Ico\rn\r\n");
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "Ico\rn"));
+	cl_assert_equal_i(1, ignored);
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "Ico\rn\r"));
+	cl_assert_equal_i(0, ignored);
+
+	cl_git_mkfile("empty_standard_repo/.gitignore", "Ico\rn\r\r\n");
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "Ico\rn\r"));
+	cl_assert_equal_i(1, ignored);
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "Icon\r"));
+	cl_assert_equal_i(0, ignored);
+
+	cl_git_mkfile("empty_standard_repo/.gitignore", "Icon\r\n");
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "Icon\r"));
+	cl_assert_equal_i(0, ignored);
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "Icon"));
+	cl_assert_equal_i(1, ignored);
+}
+
+void test_status_ignore__subdir_doesnt_match_above(void)
+{
+	int ignored, icase = 0, error;
+	git_config *cfg;
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+	cl_git_pass(git_repository_config_snapshot(&cfg, g_repo));
+	error = git_config_get_bool(&icase, cfg, "core.ignorecase");
+	git_config_free(cfg);
+	if (error == GIT_ENOTFOUND)
+		error = 0;
+
+	cl_git_pass(error);
+
+	cl_git_pass(p_mkdir("empty_standard_repo/src", 0777));
+	cl_git_pass(p_mkdir("empty_standard_repo/src/src", 0777));
+	cl_git_mkfile("empty_standard_repo/src/.gitignore", "src\n");
+	cl_git_mkfile("empty_standard_repo/.gitignore", "");
+
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "src/test.txt"));
+	cl_assert_equal_i(0, ignored);
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "src/src/test.txt"));
+	cl_assert_equal_i(1, ignored);
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "src/foo/test.txt"));
+	cl_assert_equal_i(0, ignored);
+
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "SRC/src/test.txt"));
+	cl_assert_equal_i(icase, ignored);
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "src/SRC/test.txt"));
+	cl_assert_equal_i(icase, ignored);
+}
+
+void test_status_ignore__negate_exact_previous(void)
+{
+	int ignored;
+
+	g_repo = cl_git_sandbox_init("empty_standard_repo");
+
+	cl_git_mkfile("empty_standard_repo/.gitignore", "*.com\ntags\n!tags/\n.buildpath");
+	cl_git_mkfile("empty_standard_repo/.buildpath", "");
+	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, ".buildpath"));
+	cl_assert_equal_i(1, ignored);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/renames.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/renames.c
new file mode 100755
index 0000000..f482d69
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/renames.c
@@ -0,0 +1,715 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "path.h"
+#include "posix.h"
+#include "status_helpers.h"
+#include "util.h"
+#include "status.h"
+
+static git_repository *g_repo = NULL;
+
+void test_status_renames__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("renames");
+
+	cl_repo_set_bool(g_repo, "core.autocrlf", false);
+}
+
+void test_status_renames__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static void _rename_helper(
+	git_repository *repo, const char *from, const char *to, const char *extra)
+{
+	git_buf oldpath = GIT_BUF_INIT, newpath = GIT_BUF_INIT;
+
+	cl_git_pass(git_buf_joinpath(
+		&oldpath, git_repository_workdir(repo), from));
+	cl_git_pass(git_buf_joinpath(
+		&newpath, git_repository_workdir(repo), to));
+
+	cl_git_pass(p_rename(oldpath.ptr, newpath.ptr));
+
+	if (extra)
+		cl_git_append2file(newpath.ptr, extra);
+
+	git_buf_free(&oldpath);
+	git_buf_free(&newpath);
+}
+
+#define rename_file(R,O,N) _rename_helper((R), (O), (N), NULL)
+#define rename_and_edit_file(R,O,N) \
+	_rename_helper((R), (O), (N), "Added at the end to keep similarity!")
+
+struct status_entry {
+	git_status_t status;
+	const char *oldname;
+	const char *newname;
+};
+
+static void check_status(
+	git_status_list *status_list,
+	struct status_entry *expected_list,
+	size_t expected_len)
+{
+	const git_status_entry *actual;
+	const struct status_entry *expected;
+	const char *oldname, *newname;
+	size_t i, files_in_status = git_status_list_entrycount(status_list);
+
+	cl_assert_equal_sz(expected_len, files_in_status);
+
+	for (i = 0; i < expected_len; i++) {
+		actual = git_status_byindex(status_list, i);
+		expected = &expected_list[i];
+
+		oldname = actual->head_to_index ? actual->head_to_index->old_file.path :
+			actual->index_to_workdir ? actual->index_to_workdir->old_file.path : NULL;
+
+		newname = actual->index_to_workdir ? actual->index_to_workdir->new_file.path :
+			actual->head_to_index ? actual->head_to_index->new_file.path : NULL;
+
+		cl_assert_equal_i_fmt(expected->status, actual->status, "%04x");
+
+		if (expected->oldname) {
+			cl_assert(oldname != NULL);
+			cl_assert_equal_s(oldname, expected->oldname);
+		} else {
+			cl_assert(oldname == NULL);
+		}
+
+		if (actual->status & (GIT_STATUS_INDEX_RENAMED|GIT_STATUS_WT_RENAMED)) {
+			if (expected->newname) {
+				cl_assert(newname != NULL);
+				cl_assert_equal_s(newname, expected->newname);
+			} else {
+				cl_assert(newname == NULL);
+			}
+		}
+	}
+}
+
+void test_status_renames__head2index_one(void)
+{
+	git_index *index;
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	struct status_entry expected[] = {
+		{ GIT_STATUS_INDEX_RENAMED, "ikeepsix.txt", "newname.txt" },
+	};
+
+	opts.flags |= GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	rename_file(g_repo, "ikeepsix.txt", "newname.txt");
+
+	cl_git_pass(git_index_remove_bypath(index, "ikeepsix.txt"));
+	cl_git_pass(git_index_add_bypath(index, "newname.txt"));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected, 1);
+	git_status_list_free(statuslist);
+
+	git_index_free(index);
+}
+
+void test_status_renames__head2index_two(void)
+{
+	git_index *index;
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	struct status_entry expected[] = {
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_INDEX_MODIFIED,
+		  "sixserving.txt", "aaa.txt" },
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_INDEX_MODIFIED,
+		  "untimely.txt", "bbb.txt" },
+		{ GIT_STATUS_INDEX_RENAMED, "songof7cities.txt", "ccc.txt" },
+		{ GIT_STATUS_INDEX_RENAMED, "ikeepsix.txt", "ddd.txt" },
+	};
+
+	opts.flags |= GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	rename_file(g_repo, "ikeepsix.txt", "ddd.txt");
+	rename_and_edit_file(g_repo, "sixserving.txt", "aaa.txt");
+	rename_file(g_repo, "songof7cities.txt", "ccc.txt");
+	rename_and_edit_file(g_repo, "untimely.txt", "bbb.txt");
+
+	cl_git_pass(git_index_remove_bypath(index, "ikeepsix.txt"));
+	cl_git_pass(git_index_remove_bypath(index, "sixserving.txt"));
+	cl_git_pass(git_index_remove_bypath(index, "songof7cities.txt"));
+	cl_git_pass(git_index_remove_bypath(index, "untimely.txt"));
+	cl_git_pass(git_index_add_bypath(index, "ddd.txt"));
+	cl_git_pass(git_index_add_bypath(index, "aaa.txt"));
+	cl_git_pass(git_index_add_bypath(index, "ccc.txt"));
+	cl_git_pass(git_index_add_bypath(index, "bbb.txt"));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected, 4);
+	git_status_list_free(statuslist);
+
+	git_index_free(index);
+}
+
+void test_status_renames__head2index_no_rename_from_rewrite(void)
+{
+	git_index *index;
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	struct status_entry expected[] = {
+		{ GIT_STATUS_INDEX_MODIFIED, "ikeepsix.txt", "ikeepsix.txt" },
+		{ GIT_STATUS_INDEX_MODIFIED, "sixserving.txt", "sixserving.txt" },
+	};
+
+	opts.flags |= GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	rename_file(g_repo, "ikeepsix.txt", "_temp_.txt");
+	rename_file(g_repo, "sixserving.txt", "ikeepsix.txt");
+	rename_file(g_repo, "_temp_.txt", "sixserving.txt");
+
+	cl_git_pass(git_index_add_bypath(index, "ikeepsix.txt"));
+	cl_git_pass(git_index_add_bypath(index, "sixserving.txt"));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected, 2);
+	git_status_list_free(statuslist);
+
+	git_index_free(index);
+}
+
+void test_status_renames__head2index_rename_from_rewrite(void)
+{
+	git_index *index;
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	struct status_entry expected[] = {
+		{ GIT_STATUS_INDEX_RENAMED, "sixserving.txt", "ikeepsix.txt" },
+		{ GIT_STATUS_INDEX_RENAMED, "ikeepsix.txt", "sixserving.txt" },
+	};
+
+	opts.flags |= GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_FROM_REWRITES;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	rename_file(g_repo, "ikeepsix.txt", "_temp_.txt");
+	rename_file(g_repo, "sixserving.txt", "ikeepsix.txt");
+	rename_file(g_repo, "_temp_.txt", "sixserving.txt");
+
+	cl_git_pass(git_index_add_bypath(index, "ikeepsix.txt"));
+	cl_git_pass(git_index_add_bypath(index, "sixserving.txt"));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected, 2);
+	git_status_list_free(statuslist);
+
+	git_index_free(index);
+}
+
+void test_status_renames__index2workdir_one(void)
+{
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	struct status_entry expected[] = {
+		{ GIT_STATUS_WT_RENAMED, "ikeepsix.txt", "newname.txt" },
+	};
+
+	opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;
+
+	rename_file(g_repo, "ikeepsix.txt", "newname.txt");
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected, 1);
+	git_status_list_free(statuslist);
+}
+
+void test_status_renames__index2workdir_two(void)
+{
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	struct status_entry expected[] = {
+		{ GIT_STATUS_WT_RENAMED | GIT_STATUS_WT_MODIFIED,
+		  "sixserving.txt", "aaa.txt" },
+		{ GIT_STATUS_WT_RENAMED | GIT_STATUS_WT_MODIFIED,
+		  "untimely.txt", "bbb.txt" },
+		{ GIT_STATUS_WT_RENAMED, "songof7cities.txt", "ccc.txt" },
+		{ GIT_STATUS_WT_RENAMED, "ikeepsix.txt", "ddd.txt" },
+	};
+
+	opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;
+
+	rename_file(g_repo, "ikeepsix.txt", "ddd.txt");
+	rename_and_edit_file(g_repo, "sixserving.txt", "aaa.txt");
+	rename_file(g_repo, "songof7cities.txt", "ccc.txt");
+	rename_and_edit_file(g_repo, "untimely.txt", "bbb.txt");
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected, 4);
+	git_status_list_free(statuslist);
+}
+
+void test_status_renames__index2workdir_rename_from_rewrite(void)
+{
+	git_index *index;
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	struct status_entry expected[] = {
+		{ GIT_STATUS_WT_RENAMED, "sixserving.txt", "ikeepsix.txt" },
+		{ GIT_STATUS_WT_RENAMED, "ikeepsix.txt", "sixserving.txt" },
+	};
+
+	opts.flags |= GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_FROM_REWRITES;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	rename_file(g_repo, "ikeepsix.txt", "_temp_.txt");
+	rename_file(g_repo, "sixserving.txt", "ikeepsix.txt");
+	rename_file(g_repo, "_temp_.txt", "sixserving.txt");
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected, 2);
+	git_status_list_free(statuslist);
+
+	git_index_free(index);
+}
+
+void test_status_renames__both_one(void)
+{
+	git_index *index;
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	struct status_entry expected[] = {
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_WT_RENAMED,
+		  "ikeepsix.txt", "newname-workdir.txt" },
+	};
+
+	opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	rename_file(g_repo, "ikeepsix.txt", "newname-index.txt");
+
+	cl_git_pass(git_index_remove_bypath(index, "ikeepsix.txt"));
+	cl_git_pass(git_index_add_bypath(index, "newname-index.txt"));
+	cl_git_pass(git_index_write(index));
+
+	rename_file(g_repo, "newname-index.txt", "newname-workdir.txt");
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected, 1);
+	git_status_list_free(statuslist);
+
+	git_index_free(index);
+}
+
+void test_status_renames__both_two(void)
+{
+	git_index *index;
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	struct status_entry expected[] = {
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_INDEX_MODIFIED |
+		  GIT_STATUS_WT_RENAMED | GIT_STATUS_WT_MODIFIED,
+		  "ikeepsix.txt", "ikeepsix-both.txt" },
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_INDEX_MODIFIED,
+		  "sixserving.txt", "sixserving-index.txt" },
+		{ GIT_STATUS_WT_RENAMED | GIT_STATUS_WT_MODIFIED,
+		  "songof7cities.txt", "songof7cities-workdir.txt" },
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_WT_RENAMED,
+		  "untimely.txt", "untimely-both.txt" },
+	};
+
+	opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	rename_and_edit_file(g_repo, "ikeepsix.txt", "ikeepsix-index.txt");
+	rename_and_edit_file(g_repo, "sixserving.txt", "sixserving-index.txt");
+	rename_file(g_repo, "untimely.txt", "untimely-index.txt");
+
+	cl_git_pass(git_index_remove_bypath(index, "ikeepsix.txt"));
+	cl_git_pass(git_index_remove_bypath(index, "sixserving.txt"));
+	cl_git_pass(git_index_remove_bypath(index, "untimely.txt"));
+	cl_git_pass(git_index_add_bypath(index, "ikeepsix-index.txt"));
+	cl_git_pass(git_index_add_bypath(index, "sixserving-index.txt"));
+	cl_git_pass(git_index_add_bypath(index, "untimely-index.txt"));
+	cl_git_pass(git_index_write(index));
+
+	rename_and_edit_file(g_repo, "ikeepsix-index.txt", "ikeepsix-both.txt");
+	rename_and_edit_file(g_repo, "songof7cities.txt", "songof7cities-workdir.txt");
+	rename_file(g_repo, "untimely-index.txt", "untimely-both.txt");
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected, 4);
+	git_status_list_free(statuslist);
+
+	git_index_free(index);
+}
+
+
+void test_status_renames__both_rename_from_rewrite(void)
+{
+	git_index *index;
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	struct status_entry expected[] = {
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_WT_RENAMED,
+		  "songof7cities.txt", "ikeepsix.txt" },
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_WT_RENAMED,
+		  "ikeepsix.txt", "sixserving.txt" },
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_WT_RENAMED,
+		  "sixserving.txt", "songof7cities.txt" },
+	};
+
+	opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_FROM_REWRITES;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	rename_file(g_repo, "ikeepsix.txt", "_temp_.txt");
+	rename_file(g_repo, "sixserving.txt", "ikeepsix.txt");
+	rename_file(g_repo, "songof7cities.txt", "sixserving.txt");
+	rename_file(g_repo, "_temp_.txt", "songof7cities.txt");
+
+	cl_git_pass(git_index_add_bypath(index, "ikeepsix.txt"));
+	cl_git_pass(git_index_add_bypath(index, "sixserving.txt"));
+	cl_git_pass(git_index_add_bypath(index, "songof7cities.txt"));
+	cl_git_pass(git_index_write(index));
+
+	rename_file(g_repo, "songof7cities.txt", "_temp_.txt");
+	rename_file(g_repo, "ikeepsix.txt", "songof7cities.txt");
+	rename_file(g_repo, "sixserving.txt", "ikeepsix.txt");
+	rename_file(g_repo, "_temp_.txt", "sixserving.txt");
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected, 3);
+	git_status_list_free(statuslist);
+
+	git_index_free(index);
+}
+
+void test_status_renames__rewrites_only_for_renames(void)
+{
+	git_index *index;
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	struct status_entry expected[] = {
+		{ GIT_STATUS_WT_MODIFIED, "ikeepsix.txt", "ikeepsix.txt" },
+	};
+
+	opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_FROM_REWRITES;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	cl_git_rewritefile("renames/ikeepsix.txt",
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n" \
+		"This is enough content for the file to be rewritten.\n");
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected, 1);
+	git_status_list_free(statuslist);
+
+	git_index_free(index);
+}
+
+void test_status_renames__both_casechange_one(void)
+{
+	git_index *index;
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	int index_caps;
+	struct status_entry expected_icase[] = {
+		{ GIT_STATUS_INDEX_RENAMED,
+		  "ikeepsix.txt", "IKeepSix.txt" },
+	};
+	struct status_entry expected_case[] = {
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_WT_RENAMED,
+		  "ikeepsix.txt", "IKEEPSIX.txt" },
+	};
+
+	opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	index_caps = git_index_caps(index);
+
+	rename_file(g_repo, "ikeepsix.txt", "IKeepSix.txt");
+
+	cl_git_pass(git_index_remove_bypath(index, "ikeepsix.txt"));
+	cl_git_pass(git_index_add_bypath(index, "IKeepSix.txt"));
+	cl_git_pass(git_index_write(index));
+
+	/* on a case-insensitive file system, this change won't matter.
+	 * on a case-sensitive one, it will.
+	 */
+	rename_file(g_repo, "IKeepSix.txt", "IKEEPSIX.txt");
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+
+	check_status(statuslist, (index_caps & GIT_INDEXCAP_IGNORE_CASE) ?
+		expected_icase : expected_case, 1);
+
+	git_status_list_free(statuslist);
+
+	git_index_free(index);
+}
+
+void test_status_renames__both_casechange_two(void)
+{
+	git_index *index;
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	int index_caps;
+	struct status_entry expected_icase[] = {
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_INDEX_MODIFIED |
+		  GIT_STATUS_WT_MODIFIED,
+		  "ikeepsix.txt", "IKeepSix.txt" },
+		{ GIT_STATUS_INDEX_MODIFIED,
+		  "sixserving.txt", "sixserving.txt" },
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_WT_MODIFIED,
+		  "songof7cities.txt", "songof7.txt" },
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_WT_RENAMED,
+		  "untimely.txt", "untimeliest.txt" }
+	};
+	struct status_entry expected_case[] = {
+		{ GIT_STATUS_INDEX_RENAMED |
+		  GIT_STATUS_WT_MODIFIED | GIT_STATUS_WT_RENAMED,
+		  "songof7cities.txt", "SONGOF7.txt" },
+		{ GIT_STATUS_INDEX_MODIFIED | GIT_STATUS_WT_RENAMED,
+		  "sixserving.txt", "SixServing.txt" },
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_INDEX_MODIFIED |
+		  GIT_STATUS_WT_RENAMED | GIT_STATUS_WT_MODIFIED,
+		  "ikeepsix.txt", "ikeepsix.txt" },
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_WT_RENAMED,
+		  "untimely.txt", "untimeliest.txt" }
+	};
+
+	opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX;
+	opts.flags |= GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	index_caps = git_index_caps(index);
+
+	rename_and_edit_file(g_repo, "ikeepsix.txt", "IKeepSix.txt");
+	rename_and_edit_file(g_repo, "sixserving.txt", "sixserving.txt");
+	rename_file(g_repo, "songof7cities.txt", "songof7.txt");
+	rename_file(g_repo, "untimely.txt", "untimelier.txt");
+
+	cl_git_pass(git_index_remove_bypath(index, "ikeepsix.txt"));
+	cl_git_pass(git_index_remove_bypath(index, "sixserving.txt"));
+	cl_git_pass(git_index_remove_bypath(index, "songof7cities.txt"));
+	cl_git_pass(git_index_remove_bypath(index, "untimely.txt"));
+	cl_git_pass(git_index_add_bypath(index, "IKeepSix.txt"));
+	cl_git_pass(git_index_add_bypath(index, "sixserving.txt"));
+	cl_git_pass(git_index_add_bypath(index, "songof7.txt"));
+	cl_git_pass(git_index_add_bypath(index, "untimelier.txt"));
+	cl_git_pass(git_index_write(index));
+
+	rename_and_edit_file(g_repo, "IKeepSix.txt", "ikeepsix.txt");
+	rename_file(g_repo, "sixserving.txt", "SixServing.txt");
+	rename_and_edit_file(g_repo, "songof7.txt", "SONGOF7.txt");
+	rename_file(g_repo, "untimelier.txt", "untimeliest.txt");
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+
+	check_status(statuslist, (index_caps & GIT_INDEXCAP_IGNORE_CASE) ?
+		expected_icase : expected_case, 4);
+
+	git_status_list_free(statuslist);
+
+	git_index_free(index);
+}
+
+void test_status_renames__zero_byte_file_does_not_fail(void)
+{
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+
+	struct status_entry expected[] = {
+		{ GIT_STATUS_WT_DELETED, "ikeepsix.txt", "ikeepsix.txt" },
+		{ GIT_STATUS_WT_NEW, "zerobyte.txt", "zerobyte.txt" },
+	};
+
+	opts.flags |= GIT_STATUS_OPT_RENAMES_FROM_REWRITES |
+		GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX |
+		GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR |
+		GIT_STATUS_OPT_INCLUDE_IGNORED |
+		GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS |
+		GIT_STATUS_SHOW_INDEX_AND_WORKDIR |
+		GIT_STATUS_OPT_RECURSE_IGNORED_DIRS;
+
+	p_unlink("renames/ikeepsix.txt");
+	cl_git_mkfile("renames/zerobyte.txt", "");
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected, 2);
+	git_status_list_free(statuslist);
+}
+
+#ifdef GIT_USE_ICONV
+static char *nfc = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D";
+static char *nfd = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D";
+#endif
+
+void test_status_renames__precomposed_unicode_rename(void)
+{
+#ifdef GIT_USE_ICONV
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	struct status_entry expected0[] = {
+		{ GIT_STATUS_WT_NEW, nfd, NULL },
+		{ GIT_STATUS_WT_DELETED, "sixserving.txt", NULL },
+	};
+	struct status_entry expected1[] = {
+		{ GIT_STATUS_WT_RENAMED, "sixserving.txt", nfd },
+	};
+	struct status_entry expected2[] = {
+		{ GIT_STATUS_WT_DELETED, "sixserving.txt", NULL },
+		{ GIT_STATUS_WT_NEW, nfc, NULL },
+	};
+	struct status_entry expected3[] = {
+		{ GIT_STATUS_WT_RENAMED, "sixserving.txt", nfc },
+	};
+
+	rename_file(g_repo, "sixserving.txt", nfc);
+
+	opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED;
+
+	cl_repo_set_bool(g_repo, "core.precomposeunicode", false);
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected0, ARRAY_SIZE(expected0));
+	git_status_list_free(statuslist);
+
+	opts.flags |= GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected1, ARRAY_SIZE(expected1));
+	git_status_list_free(statuslist);
+
+	cl_repo_set_bool(g_repo, "core.precomposeunicode", true);
+
+	opts.flags &= ~GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected2, ARRAY_SIZE(expected2));
+	git_status_list_free(statuslist);
+
+	opts.flags |= GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected3, ARRAY_SIZE(expected3));
+	git_status_list_free(statuslist);
+#endif
+}
+
+void test_status_renames__precomposed_unicode_toggle_is_rename(void)
+{
+#ifdef GIT_USE_ICONV
+	git_status_list *statuslist;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	struct status_entry expected0[] = {
+		{ GIT_STATUS_INDEX_RENAMED, "ikeepsix.txt", nfd },
+	};
+	struct status_entry expected1[] = {
+		{ GIT_STATUS_WT_RENAMED, nfd, nfc },
+	};
+	struct status_entry expected2[] = {
+		{ GIT_STATUS_INDEX_RENAMED, nfd, nfc },
+	};
+	struct status_entry expected3[] = {
+		{ GIT_STATUS_INDEX_RENAMED | GIT_STATUS_WT_RENAMED, nfd, nfd },
+	};
+
+	cl_repo_set_bool(g_repo, "core.precomposeunicode", false);
+	rename_file(g_repo, "ikeepsix.txt", nfd);
+
+	{
+		git_index *index;
+		cl_git_pass(git_repository_index(&index, g_repo));
+		cl_git_pass(git_index_remove_bypath(index, "ikeepsix.txt"));
+		cl_git_pass(git_index_add_bypath(index, nfd));
+		cl_git_pass(git_index_write(index));
+		git_index_free(index);
+	}
+
+	opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX |
+		GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected0, ARRAY_SIZE(expected0));
+	git_status_list_free(statuslist);
+
+	cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "commit nfd");
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	cl_assert_equal_sz(0, git_status_list_entrycount(statuslist));
+	git_status_list_free(statuslist);
+
+	cl_repo_set_bool(g_repo, "core.precomposeunicode", true);
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected1, ARRAY_SIZE(expected1));
+	git_status_list_free(statuslist);
+
+	{
+		git_index *index;
+		cl_git_pass(git_repository_index(&index, g_repo));
+		cl_git_pass(git_index_remove_bypath(index, nfd));
+		cl_git_pass(git_index_add_bypath(index, nfc));
+		cl_git_pass(git_index_write(index));
+		git_index_free(index);
+	}
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected2, ARRAY_SIZE(expected2));
+	git_status_list_free(statuslist);
+
+	cl_repo_set_bool(g_repo, "core.precomposeunicode", false);
+
+	cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
+	check_status(statuslist, expected3, ARRAY_SIZE(expected3));
+	git_status_list_free(statuslist);
+#endif
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/single.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/single.c
new file mode 100755
index 0000000..6efaab2
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/single.c
@@ -0,0 +1,45 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+
+static void
+cleanup__remove_file(void *_file)
+{
+	cl_must_pass(p_unlink((char *)_file));
+}
+
+/* test retrieving OID from a file apart from the ODB */
+void test_status_single__hash_single_file(void)
+{
+	static const char file_name[] = "new_file";
+	static const char file_contents[] = "new_file\n";
+	static const char file_hash[] = "d4fa8600b4f37d7516bef4816ae2c64dbf029e3a";
+
+	git_oid expected_id, actual_id;
+
+	/* initialization */
+	git_oid_fromstr(&expected_id, file_hash);
+	cl_git_mkfile(file_name, file_contents);
+	cl_set_cleanup(&cleanup__remove_file, (void *)file_name);
+
+	cl_git_pass(git_odb_hashfile(&actual_id, file_name, GIT_OBJ_BLOB));
+	cl_assert_equal_oid(&expected_id, &actual_id);
+}
+
+/* test retrieving OID from an empty file apart from the ODB */
+void test_status_single__hash_single_empty_file(void)
+{
+	static const char file_name[] = "new_empty_file";
+	static const char file_contents[] = "";
+	static const char file_hash[] = "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391";
+
+	git_oid expected_id, actual_id;
+
+	/* initialization */
+	git_oid_fromstr(&expected_id, file_hash);
+	cl_git_mkfile(file_name, file_contents);
+	cl_set_cleanup(&cleanup__remove_file, (void *)file_name);
+
+	cl_git_pass(git_odb_hashfile(&actual_id, file_name, GIT_OBJ_BLOB));
+	cl_assert_equal_oid(&expected_id, &actual_id);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/status_data.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/status_data.h
new file mode 100755
index 0000000..8ad4235
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/status_data.h
@@ -0,0 +1,326 @@
+#include "status_helpers.h"
+
+// A utf-8 string with 83 characters, but 249 bytes.
+static const char *longname = "\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97";
+
+
+/* entries for a plain copy of tests/resources/status */
+
+static const char *entry_paths0[] = {
+	"file_deleted",
+	"ignored_file",
+	"modified_file",
+	"new_file",
+	"staged_changes",
+	"staged_changes_file_deleted",
+	"staged_changes_modified_file",
+	"staged_delete_file_deleted",
+	"staged_delete_modified_file",
+	"staged_new_file",
+	"staged_new_file_deleted_file",
+	"staged_new_file_modified_file",
+
+	"subdir/deleted_file",
+	"subdir/modified_file",
+	"subdir/new_file",
+
+	"\xe8\xbf\x99",
+};
+
+static const unsigned int entry_statuses0[] = {
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_IGNORED,
+	GIT_STATUS_WT_MODIFIED,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_INDEX_MODIFIED | GIT_STATUS_WT_DELETED,
+	GIT_STATUS_INDEX_MODIFIED | GIT_STATUS_WT_MODIFIED,
+	GIT_STATUS_INDEX_DELETED,
+	GIT_STATUS_INDEX_DELETED | GIT_STATUS_WT_NEW,
+	GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_INDEX_NEW | GIT_STATUS_WT_DELETED,
+	GIT_STATUS_INDEX_NEW | GIT_STATUS_WT_MODIFIED,
+
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_MODIFIED,
+	GIT_STATUS_WT_NEW,
+
+	GIT_STATUS_WT_NEW,
+};
+
+static const int entry_count0 = 16;
+
+/* entries for a copy of tests/resources/status with all content
+ * deleted from the working directory
+ */
+
+static const char *entry_paths2[] = {
+	"current_file",
+	"file_deleted",
+	"modified_file",
+	"staged_changes",
+	"staged_changes_file_deleted",
+	"staged_changes_modified_file",
+	"staged_delete_file_deleted",
+	"staged_delete_modified_file",
+	"staged_new_file",
+	"staged_new_file_deleted_file",
+	"staged_new_file_modified_file",
+	"subdir.txt",
+	"subdir/current_file",
+	"subdir/deleted_file",
+	"subdir/modified_file",
+};
+
+static const unsigned int entry_statuses2[] = {
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_DELETED | GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_WT_DELETED | GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_WT_DELETED | GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_INDEX_DELETED,
+	GIT_STATUS_INDEX_DELETED,
+	GIT_STATUS_WT_DELETED | GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_WT_DELETED | GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_WT_DELETED | GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_DELETED,
+};
+
+static const int entry_count2 = 15;
+
+/* entries for a copy of tests/resources/status with some mods */
+
+static const char *entry_paths3_icase[] = {
+	".HEADER",
+	"42-is-not-prime.sigh",
+	"current_file",
+	"current_file/",
+	"file_deleted",
+	"ignored_file",
+	"modified_file",
+	"new_file",
+	"README.md",
+	"staged_changes",
+	"staged_changes_file_deleted",
+	"staged_changes_modified_file",
+	"staged_delete_file_deleted",
+	"staged_delete_modified_file",
+	"staged_new_file",
+	"staged_new_file_deleted_file",
+	"staged_new_file_modified_file",
+	"subdir",
+	"subdir/current_file",
+	"subdir/deleted_file",
+	"subdir/modified_file",
+	"\xe8\xbf\x99",
+};
+
+static const unsigned int entry_statuses3_icase[] = {
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_IGNORED,
+	GIT_STATUS_WT_MODIFIED,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_WT_DELETED | GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_INDEX_DELETED,
+	GIT_STATUS_WT_NEW | GIT_STATUS_INDEX_DELETED,
+	GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_WT_DELETED | GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_NEW,
+};
+
+static const char *entry_paths3[] = {
+	".HEADER",
+	"42-is-not-prime.sigh",
+	"README.md",
+	"current_file",
+	"current_file/",
+	"file_deleted",
+	"ignored_file",
+	"modified_file",
+	"new_file",
+	"staged_changes",
+	"staged_changes_file_deleted",
+	"staged_changes_modified_file",
+	"staged_delete_file_deleted",
+	"staged_delete_modified_file",
+	"staged_new_file",
+	"staged_new_file_deleted_file",
+	"staged_new_file_modified_file",
+	"subdir",
+	"subdir/current_file",
+	"subdir/deleted_file",
+	"subdir/modified_file",
+	"\xe8\xbf\x99",
+};
+
+static const unsigned int entry_statuses3[] = {
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_IGNORED,
+	GIT_STATUS_WT_MODIFIED,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_WT_DELETED | GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_INDEX_DELETED,
+	GIT_STATUS_WT_NEW | GIT_STATUS_INDEX_DELETED,
+	GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_WT_DELETED | GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_NEW,
+};
+
+static const int entry_count3 = 22;
+
+
+/* entries for a copy of tests/resources/status with some mods
+ * and different options to the status call
+ */
+
+static const char *entry_paths4[] = {
+	".new_file",
+	"current_file",
+	"current_file/current_file",
+	"current_file/modified_file",
+	"current_file/new_file",
+	"file_deleted",
+	"modified_file",
+	"new_file",
+	"staged_changes",
+	"staged_changes_file_deleted",
+	"staged_changes_modified_file",
+	"staged_delete_file_deleted",
+	"staged_delete_modified_file",
+	"staged_new_file",
+	"staged_new_file_deleted_file",
+	"staged_new_file_modified_file",
+	"subdir",
+	"subdir/current_file",
+	"subdir/deleted_file",
+	"subdir/modified_file",
+	"zzz_new_dir/new_file",
+	"zzz_new_file",
+	"\xe8\xbf\x99",
+};
+
+static const unsigned int entry_statuses4[] = {
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_MODIFIED,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_WT_DELETED | GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_INDEX_DELETED,
+	GIT_STATUS_WT_NEW | GIT_STATUS_INDEX_DELETED,
+	GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_WT_DELETED | GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_NEW,
+};
+
+static const int entry_count4 = 23;
+
+
+/* entries for a copy of tests/resources/status with options
+ * passed to the status call in order to only get the differences
+ * between the HEAD and the index (changes to be committed)
+ */
+
+static const char *entry_paths5[] = {
+	"staged_changes",
+	"staged_changes_file_deleted",
+	"staged_changes_modified_file",
+	"staged_delete_file_deleted",
+	"staged_delete_modified_file",
+	"staged_new_file",
+	"staged_new_file_deleted_file",
+	"staged_new_file_modified_file",
+};
+
+static const unsigned int entry_statuses5[] = {
+	GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_INDEX_DELETED,
+	GIT_STATUS_INDEX_DELETED,
+	GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_INDEX_NEW,
+};
+
+static const int entry_count5 = 8;
+
+
+/* entries for a copy of tests/resources/status with options
+ * passed to the status call in order to only get the differences
+ * between the workdir and the index (changes not staged, untracked files)
+ */
+
+static const char *entry_paths6[] = {
+	"file_deleted",
+	"ignored_file",
+	"modified_file",
+	"new_file",
+	"staged_changes_file_deleted",
+	"staged_changes_modified_file",
+	"staged_delete_modified_file",
+	"staged_new_file_deleted_file",
+	"staged_new_file_modified_file",
+	"subdir/deleted_file",
+	"subdir/modified_file",
+	"subdir/new_file",
+	"\xe8\xbf\x99",
+};
+
+static const unsigned int entry_statuses6[] = {
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_IGNORED,
+	GIT_STATUS_WT_MODIFIED,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_MODIFIED,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_MODIFIED,
+	GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_MODIFIED,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_WT_NEW,
+};
+
+static const int entry_count6 = 13;
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/status_helpers.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/status_helpers.c
new file mode 100755
index 0000000..5d13caa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/status_helpers.c
@@ -0,0 +1,97 @@
+#include "clar_libgit2.h"
+#include "status_helpers.h"
+
+int cb_status__normal(
+	const char *path, unsigned int status_flags, void *payload)
+{
+	status_entry_counts *counts = payload;
+
+	if (counts->debug)
+		cb_status__print(path, status_flags, NULL);
+
+	if (counts->entry_count >= counts->expected_entry_count)
+		counts->wrong_status_flags_count++;
+	else if (strcmp(path, counts->expected_paths[counts->entry_count]))
+		counts->wrong_sorted_path++;
+	else if (status_flags != counts->expected_statuses[counts->entry_count])
+		counts->wrong_status_flags_count++;
+
+	counts->entry_count++;
+	return 0;
+}
+
+int cb_status__count(const char *p, unsigned int s, void *payload)
+{
+	volatile int *count = (int *)payload;
+
+	GIT_UNUSED(p);
+	GIT_UNUSED(s);
+
+	(*count)++;
+
+	return 0;
+}
+
+int cb_status__single(const char *p, unsigned int s, void *payload)
+{
+	status_entry_single *data = (status_entry_single *)payload;
+
+	if (data->debug)
+		fprintf(stderr, "%02d: %s (%04x)\n", data->count, p, s);
+
+	data->count++;
+	data->status = s;
+
+	return 0;
+}
+
+int cb_status__print(
+	const char *path, unsigned int status_flags, void *payload)
+{
+	char istatus = ' ', wstatus = ' ';
+	int icount = 0, wcount = 0;
+
+	if (status_flags & GIT_STATUS_INDEX_NEW) {
+		istatus = 'A'; icount++;
+	}
+	if (status_flags & GIT_STATUS_INDEX_MODIFIED) {
+		istatus = 'M'; icount++;
+	}
+	if (status_flags & GIT_STATUS_INDEX_DELETED) {
+		istatus = 'D'; icount++;
+	}
+	if (status_flags & GIT_STATUS_INDEX_RENAMED) {
+		istatus = 'R'; icount++;
+	}
+	if (status_flags & GIT_STATUS_INDEX_TYPECHANGE) {
+		istatus = 'T'; icount++;
+	}
+
+	if (status_flags & GIT_STATUS_WT_NEW) {
+		wstatus = 'A'; wcount++;
+	}
+	if (status_flags & GIT_STATUS_WT_MODIFIED) {
+		wstatus = 'M'; wcount++;
+	}
+	if (status_flags & GIT_STATUS_WT_DELETED) {
+		wstatus = 'D'; wcount++;
+	}
+	if (status_flags & GIT_STATUS_WT_TYPECHANGE) {
+		wstatus = 'T'; wcount++;
+	}
+	if (status_flags & GIT_STATUS_IGNORED) {
+		wstatus = 'I'; wcount++;
+	}
+	if (status_flags & GIT_STATUS_WT_UNREADABLE) {
+		wstatus = 'X'; wcount++;
+	}
+
+	fprintf(stderr, "%c%c %s (%d/%d%s)\n",
+			istatus, wstatus, path, icount, wcount,
+			(icount > 1 || wcount > 1) ? " INVALID COMBO" : "");
+
+	if (payload)
+		*((int *)payload) += 1;
+
+	return 0;
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/status_helpers.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/status_helpers.h
new file mode 100755
index 0000000..242076c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/status_helpers.h
@@ -0,0 +1,49 @@
+#ifndef INCLUDE_cl_status_helpers_h__
+#define INCLUDE_cl_status_helpers_h__
+
+typedef struct {
+	int wrong_status_flags_count;
+	int wrong_sorted_path;
+	int entry_count;
+	const unsigned int* expected_statuses;
+	const char** expected_paths;
+	int expected_entry_count;
+	const char *file;
+	int line;
+	bool debug;
+} status_entry_counts;
+
+#define status_counts_init(counts, paths, statuses) do { \
+	memset(&(counts), 0, sizeof(counts)); \
+	(counts).expected_statuses = (statuses); \
+	(counts).expected_paths = (paths); \
+	(counts).file = __FILE__; \
+	(counts).line = __LINE__; \
+	} while (0)
+
+/* cb_status__normal takes payload of "status_entry_counts *" */
+
+extern int cb_status__normal(
+	const char *path, unsigned int status_flags, void *payload);
+
+
+/* cb_status__count takes payload of "int *" */
+
+extern int cb_status__count(const char *p, unsigned int s, void *payload);
+
+
+typedef struct {
+	int count;
+	unsigned int status;
+	bool debug;
+} status_entry_single;
+
+/* cb_status__single takes payload of "status_entry_single *" */
+
+extern int cb_status__single(const char *p, unsigned int s, void *payload);
+
+/* cb_status__print takes optional payload of "int *" */
+
+extern int cb_status__print(const char *p, unsigned int s, void *payload);
+
+#endif
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/submodules.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/submodules.c
new file mode 100755
index 0000000..e6de600
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/submodules.c
@@ -0,0 +1,526 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "status_helpers.h"
+#include "../submodule/submodule_helpers.h"
+
+static git_repository *g_repo = NULL;
+
+void test_status_submodules__initialize(void)
+{
+}
+
+void test_status_submodules__cleanup(void)
+{
+}
+
+void test_status_submodules__api(void)
+{
+	git_submodule *sm;
+
+	g_repo = setup_fixture_submodules();
+
+	cl_assert(git_submodule_lookup(NULL, g_repo, "nonexistent") == GIT_ENOTFOUND);
+
+	cl_assert(git_submodule_lookup(NULL, g_repo, "modified") == GIT_ENOTFOUND);
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+	cl_assert(sm != NULL);
+	cl_assert_equal_s("testrepo", git_submodule_name(sm));
+	cl_assert_equal_s("testrepo", git_submodule_path(sm));
+	git_submodule_free(sm);
+}
+
+void test_status_submodules__0(void)
+{
+	int counts = 0;
+
+	g_repo = setup_fixture_submodules();
+
+	cl_assert(git_path_isdir("submodules/.git"));
+	cl_assert(git_path_isdir("submodules/testrepo/.git"));
+	cl_assert(git_path_isfile("submodules/.gitmodules"));
+
+	cl_git_pass(
+		git_status_foreach(g_repo, cb_status__count, &counts)
+	);
+
+	cl_assert_equal_i(6, counts);
+}
+
+static const char *expected_files[] = {
+	".gitmodules",
+	"added",
+	"deleted",
+	"ignored",
+	"modified",
+	"untracked"
+};
+
+static unsigned int expected_status[] = {
+	GIT_STATUS_WT_MODIFIED,
+	GIT_STATUS_INDEX_NEW,
+	GIT_STATUS_INDEX_DELETED,
+	GIT_STATUS_IGNORED,
+	GIT_STATUS_WT_MODIFIED,
+	GIT_STATUS_WT_NEW
+};
+
+static int cb_status__match(const char *p, unsigned int s, void *payload)
+{
+	status_entry_counts *counts = payload;
+	int idx = counts->entry_count++;
+
+	clar__assert_equal(
+		counts->file, counts->line,
+		"Status path mismatch", 1,
+		"%s", counts->expected_paths[idx], p);
+
+	clar__assert_equal(
+		counts->file, counts->line,
+		"Status code mismatch", 1,
+		"%o", counts->expected_statuses[idx], s);
+
+	return 0;
+}
+
+void test_status_submodules__1(void)
+{
+	status_entry_counts counts;
+
+	g_repo = setup_fixture_submodules();
+
+	cl_assert(git_path_isdir("submodules/.git"));
+	cl_assert(git_path_isdir("submodules/testrepo/.git"));
+	cl_assert(git_path_isfile("submodules/.gitmodules"));
+
+	status_counts_init(counts, expected_files, expected_status);
+
+	cl_git_pass( git_status_foreach(g_repo, cb_status__match, &counts) );
+
+	cl_assert_equal_i(6, counts.entry_count);
+}
+
+void test_status_submodules__single_file(void)
+{
+	unsigned int status = 0;
+	g_repo = setup_fixture_submodules();
+	cl_git_pass( git_status_file(&status, g_repo, "testrepo") );
+	cl_assert(!status);
+}
+
+void test_status_submodules__moved_head(void)
+{
+	git_submodule *sm;
+	git_repository *smrepo;
+	git_oid oid;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	status_entry_counts counts;
+	static const char *expected_files_with_sub[] = {
+		".gitmodules",
+		"added",
+		"deleted",
+		"ignored",
+		"modified",
+		"testrepo",
+		"untracked"
+	};
+	static unsigned int expected_status_with_sub[] = {
+		GIT_STATUS_WT_MODIFIED,
+		GIT_STATUS_INDEX_NEW,
+		GIT_STATUS_INDEX_DELETED,
+		GIT_STATUS_IGNORED,
+		GIT_STATUS_WT_MODIFIED,
+		GIT_STATUS_WT_MODIFIED,
+		GIT_STATUS_WT_NEW
+	};
+
+	g_repo = setup_fixture_submodules();
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+	cl_git_pass(git_submodule_open(&smrepo, sm));
+	git_submodule_free(sm);
+
+	/* move submodule HEAD to c47800c7266a2be04c571c04d5a6614691ea99bd */
+	cl_git_pass(
+		git_oid_fromstr(&oid, "c47800c7266a2be04c571c04d5a6614691ea99bd"));
+	cl_git_pass(git_repository_set_head_detached(smrepo, &oid));
+
+	/* first do a normal status, which should now include the submodule */
+
+	opts.flags = GIT_STATUS_OPT_DEFAULTS;
+
+	status_counts_init(
+		counts, expected_files_with_sub, expected_status_with_sub);
+	cl_git_pass(
+		git_status_foreach_ext(g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(7, counts.entry_count);
+
+	/* try again with EXCLUDE_SUBMODULES which should skip it */
+
+	opts.flags = GIT_STATUS_OPT_DEFAULTS | GIT_STATUS_OPT_EXCLUDE_SUBMODULES;
+
+	status_counts_init(counts, expected_files, expected_status);
+	cl_git_pass(
+		git_status_foreach_ext(g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(6, counts.entry_count);
+
+	git_repository_free(smrepo);
+}
+
+void test_status_submodules__dirty_workdir_only(void)
+{
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	status_entry_counts counts;
+	static const char *expected_files_with_sub[] = {
+		".gitmodules",
+		"added",
+		"deleted",
+		"ignored",
+		"modified",
+		"testrepo",
+		"untracked"
+	};
+	static unsigned int expected_status_with_sub[] = {
+		GIT_STATUS_WT_MODIFIED,
+		GIT_STATUS_INDEX_NEW,
+		GIT_STATUS_INDEX_DELETED,
+		GIT_STATUS_IGNORED,
+		GIT_STATUS_WT_MODIFIED,
+		GIT_STATUS_WT_MODIFIED,
+		GIT_STATUS_WT_NEW
+	};
+
+	g_repo = setup_fixture_submodules();
+
+	cl_git_rewritefile("submodules/testrepo/README", "heyheyhey");
+	cl_git_mkfile("submodules/testrepo/all_new.txt", "never seen before");
+
+	/* first do a normal status, which should now include the submodule */
+
+	opts.flags = GIT_STATUS_OPT_DEFAULTS;
+
+	status_counts_init(
+		counts, expected_files_with_sub, expected_status_with_sub);
+	cl_git_pass(
+		git_status_foreach_ext(g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(7, counts.entry_count);
+
+	/* try again with EXCLUDE_SUBMODULES which should skip it */
+
+	opts.flags = GIT_STATUS_OPT_DEFAULTS | GIT_STATUS_OPT_EXCLUDE_SUBMODULES;
+
+	status_counts_init(counts, expected_files, expected_status);
+	cl_git_pass(
+		git_status_foreach_ext(g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(6, counts.entry_count);
+}
+
+void test_status_submodules__uninitialized(void)
+{
+	git_repository *cloned_repo;
+	git_status_list *statuslist;
+
+	g_repo = cl_git_sandbox_init("submod2");
+
+	cl_git_pass(git_clone(&cloned_repo, "submod2", "submod2-clone", NULL));
+
+	cl_git_pass(git_status_list_new(&statuslist, cloned_repo, NULL));
+	cl_assert_equal_i(0, git_status_list_entrycount(statuslist));
+
+	git_status_list_free(statuslist);
+	git_repository_free(cloned_repo);
+	cl_git_sandbox_cleanup();
+}
+
+void test_status_submodules__contained_untracked_repo(void)
+{
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	status_entry_counts counts;
+	git_repository *contained;
+	static const char *expected_files_not_ignored[] = {
+		".gitmodules",
+		"added",
+		"deleted",
+		"modified",
+		"untracked"
+	};
+	static unsigned int expected_status_not_ignored[] = {
+		GIT_STATUS_WT_MODIFIED,
+		GIT_STATUS_INDEX_NEW,
+		GIT_STATUS_INDEX_DELETED,
+		GIT_STATUS_WT_MODIFIED,
+		GIT_STATUS_WT_NEW,
+	};
+	static const char *expected_files_with_untracked[] = {
+		".gitmodules",
+		"added",
+		"deleted",
+		"dir/file.md",
+		"modified",
+		"untracked"
+	};
+	static const char *expected_files_with_untracked_dir[] = {
+		".gitmodules",
+		"added",
+		"deleted",
+		"dir/",
+		"modified",
+		"untracked"
+	};
+	static unsigned int expected_status_with_untracked[] = {
+		GIT_STATUS_WT_MODIFIED,
+		GIT_STATUS_INDEX_NEW,
+		GIT_STATUS_INDEX_DELETED,
+		GIT_STATUS_WT_NEW,
+		GIT_STATUS_WT_MODIFIED,
+		GIT_STATUS_WT_NEW
+	};
+
+	g_repo = setup_fixture_submodules();
+
+	/* skip empty directory */
+
+	cl_must_pass(p_mkdir("submodules/dir", 0777));
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED;
+
+	status_counts_init(
+		counts, expected_files_not_ignored, expected_status_not_ignored);
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(5, counts.entry_count);
+
+	/* still skipping because empty == ignored */
+
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
+
+	status_counts_init(
+		counts, expected_files_not_ignored, expected_status_not_ignored);
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(5, counts.entry_count);
+
+	/* find non-ignored contents of directory */
+
+	cl_git_mkfile("submodules/dir/file.md", "hello");
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
+
+	status_counts_init(
+		counts, expected_files_with_untracked, expected_status_with_untracked);
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(6, counts.entry_count);
+
+	/* but skip if all content is ignored */
+
+	cl_git_append2file("submodules/.git/info/exclude", "\n*.md\n\n");
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
+
+	status_counts_init(
+		counts, expected_files_not_ignored, expected_status_not_ignored);
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(5, counts.entry_count);
+
+	/* same is true if it contains a git link */
+
+	cl_git_mkfile("submodules/dir/.git", "gitlink: ../.git");
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
+
+	status_counts_init(
+		counts, expected_files_not_ignored, expected_status_not_ignored);
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(5, counts.entry_count);
+
+	/* but if it contains tracked files, it should just show up as a
+	 * directory and exclude the files in it
+	 */
+
+	cl_git_mkfile("submodules/dir/another_file", "hello");
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
+
+	status_counts_init(
+		counts, expected_files_with_untracked_dir,
+		expected_status_with_untracked);
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(6, counts.entry_count);
+
+	/* that applies to a git repo with a .git directory too */
+
+	cl_must_pass(p_unlink("submodules/dir/.git"));
+	cl_git_pass(git_repository_init(&contained, "submodules/dir", false));
+	git_repository_free(contained);
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
+
+	status_counts_init(
+		counts, expected_files_with_untracked_dir,
+		expected_status_with_untracked);
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(6, counts.entry_count);
+
+	/* same result even if we don't recurse into subdirectories */
+
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED;
+
+	status_counts_init(
+		counts, expected_files_with_untracked_dir,
+		expected_status_with_untracked);
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(6, counts.entry_count);
+
+	/* and if we remove the untracked file, it goes back to ignored */
+
+	cl_must_pass(p_unlink("submodules/dir/another_file"));
+
+	status_counts_init(
+		counts, expected_files_not_ignored, expected_status_not_ignored);
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(5, counts.entry_count);
+}
+
+void test_status_submodules__broken_stuff_that_git_allows(void)
+{
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	status_entry_counts counts;
+	git_repository *contained;
+	static const char *expected_files_with_broken[] = {
+		".gitmodules",
+		"added",
+		"broken/tracked",
+		"deleted",
+		"ignored",
+		"modified",
+		"untracked"
+	};
+	static unsigned int expected_status_with_broken[] = {
+		GIT_STATUS_WT_MODIFIED,
+		GIT_STATUS_INDEX_NEW,
+		GIT_STATUS_INDEX_NEW,
+		GIT_STATUS_INDEX_DELETED,
+		GIT_STATUS_IGNORED,
+		GIT_STATUS_WT_MODIFIED,
+		GIT_STATUS_WT_NEW,
+	};
+
+	g_repo = setup_fixture_submodules();
+
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS |
+		GIT_STATUS_OPT_INCLUDE_IGNORED;
+
+	/* make a directory and stick a tracked item into the index */
+	{
+		git_index *idx;
+		cl_must_pass(p_mkdir("submodules/broken", 0777));
+		cl_git_mkfile("submodules/broken/tracked", "tracked content");
+		cl_git_pass(git_repository_index(&idx, g_repo));
+		cl_git_pass(git_index_add_bypath(idx, "broken/tracked"));
+		cl_git_pass(git_index_write(idx));
+		git_index_free(idx);
+	}
+
+	status_counts_init(
+		counts, expected_files_with_broken, expected_status_with_broken);
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(7, counts.entry_count);
+
+	/* directory with tracked items that looks a little bit like a repo */
+
+	cl_must_pass(p_mkdir("submodules/broken/.git", 0777));
+	cl_must_pass(p_mkdir("submodules/broken/.git/info", 0777));
+	cl_git_mkfile("submodules/broken/.git/info/exclude", "# bogus");
+
+	status_counts_init(
+		counts, expected_files_with_broken, expected_status_with_broken);
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(7, counts.entry_count);
+
+	/* directory with tracked items that is a repo */
+
+	cl_git_pass(git_futils_rmdir_r(
+		"submodules/broken/.git", NULL, GIT_RMDIR_REMOVE_FILES));
+	cl_git_pass(git_repository_init(&contained, "submodules/broken", false));
+	git_repository_free(contained);
+
+	status_counts_init(
+		counts, expected_files_with_broken, expected_status_with_broken);
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(7, counts.entry_count);
+
+	/* directory with tracked items that claims to be a submodule but is not */
+
+	cl_git_pass(git_futils_rmdir_r(
+		"submodules/broken/.git", NULL, GIT_RMDIR_REMOVE_FILES));
+	cl_git_append2file("submodules/.gitmodules",
+		"\n[submodule \"broken\"]\n"
+		"\tpath = broken\n"
+		"\turl = https://github.com/not/used\n\n");
+
+	status_counts_init(
+		counts, expected_files_with_broken, expected_status_with_broken);
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, cb_status__match, &counts));
+	cl_assert_equal_i(7, counts.entry_count);
+}
+
+void test_status_submodules__entry_but_dir_tracked(void)
+{
+	git_repository *repo;
+	git_status_list *status;
+	git_diff *diff;
+	git_index *index;
+	git_tree *tree;
+
+	cl_git_pass(git_repository_init(&repo, "mixed-submodule", 0));
+	cl_git_mkfile("mixed-submodule/.gitmodules", "[submodule \"sub\"]\n path = sub\n url = ../foo\n");
+	cl_git_pass(p_mkdir("mixed-submodule/sub", 0777));
+	cl_git_mkfile("mixed-submodule/sub/file", "");
+
+	/* Create the commit with sub/file as a file, and an entry for sub in the modules list */
+	{
+		git_oid tree_id, commit_id;
+		git_signature *sig;
+		git_reference *ref;
+
+		cl_git_pass(git_repository_index(&index, repo));
+		cl_git_pass(git_index_add_bypath(index, ".gitmodules"));
+		cl_git_pass(git_index_add_bypath(index, "sub/file"));
+		cl_git_pass(git_index_write(index));
+		cl_git_pass(git_index_write_tree(&tree_id, index));
+		cl_git_pass(git_signature_now(&sig, "Sloppy Submoduler", "sloppy at example.com"));
+		cl_git_pass(git_tree_lookup(&tree, repo, &tree_id));
+		cl_git_pass(git_commit_create(&commit_id, repo, NULL, sig, sig, NULL, "message", tree, 0, NULL));
+		cl_git_pass(git_reference_create(&ref, repo, "refs/heads/master", &commit_id, 1, "commit: foo"));
+		git_reference_free(ref);
+		git_signature_free(sig);
+	}
+
+	cl_git_pass(git_diff_tree_to_index(&diff, repo, tree, index, NULL));
+	cl_assert_equal_i(0, git_diff_num_deltas(diff));
+	git_diff_free(diff);
+
+	cl_git_pass(git_diff_index_to_workdir(&diff, repo, index, NULL));
+	cl_assert_equal_i(0, git_diff_num_deltas(diff));
+	git_diff_free(diff);
+
+	cl_git_pass(git_status_list_new(&status, repo, NULL));
+	cl_assert_equal_i(0, git_status_list_entrycount(status));
+
+	git_status_list_free(status);
+	git_index_free(index);
+	git_tree_free(tree);
+	git_repository_free(repo);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/worktree.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/worktree.c
new file mode 100755
index 0000000..75c7b71
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/worktree.c
@@ -0,0 +1,1148 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "ignore.h"
+#include "status_data.h"
+#include "posix.h"
+#include "util.h"
+#include "path.h"
+#include "../diff/diff_helpers.h"
+#include "../checkout/checkout_helpers.h"
+#include "git2/sys/diff.h"
+
+/**
+ * Cleanup
+ *
+ * This will be called once after each test finishes, even
+ * if the test failed
+ */
+void test_status_worktree__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+/**
+ * Tests - Status determination on a working tree
+ */
+/* this test is equivalent to t18-status.c:statuscb0 */
+void test_status_worktree__whole_repository(void)
+{
+	status_entry_counts counts;
+	git_repository *repo = cl_git_sandbox_init("status");
+
+	memset(&counts, 0x0, sizeof(status_entry_counts));
+	counts.expected_entry_count = entry_count0;
+	counts.expected_paths = entry_paths0;
+	counts.expected_statuses = entry_statuses0;
+
+	cl_git_pass(
+		git_status_foreach(repo, cb_status__normal, &counts)
+	);
+
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+}
+
+void assert_show(
+	const int entry_counts,
+	const char *entry_paths[],
+	const unsigned int entry_statuses[],
+	git_repository *repo,
+	git_status_show_t show,
+	unsigned int extra_flags)
+{
+	status_entry_counts counts;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+
+	memset(&counts, 0x0, sizeof(status_entry_counts));
+	counts.expected_entry_count = entry_counts;
+	counts.expected_paths = entry_paths;
+	counts.expected_statuses = entry_statuses;
+
+	opts.flags = GIT_STATUS_OPT_DEFAULTS | extra_flags;
+	opts.show = show;
+
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts)
+	);
+
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+}
+
+void test_status_worktree__show_index_and_workdir(void)
+{
+	assert_show(entry_count0, entry_paths0, entry_statuses0,
+		cl_git_sandbox_init("status"), GIT_STATUS_SHOW_INDEX_AND_WORKDIR, 0);
+}
+
+void test_status_worktree__show_index_only(void)
+{
+	assert_show(entry_count5, entry_paths5, entry_statuses5,
+		cl_git_sandbox_init("status"), GIT_STATUS_SHOW_INDEX_ONLY, 0);
+}
+
+void test_status_worktree__show_workdir_only(void)
+{
+	assert_show(entry_count6, entry_paths6, entry_statuses6,
+		cl_git_sandbox_init("status"), GIT_STATUS_SHOW_WORKDIR_ONLY, 0);
+}
+
+/* this test is equivalent to t18-status.c:statuscb1 */
+void test_status_worktree__empty_repository(void)
+{
+	int count = 0;
+	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
+
+	cl_git_pass(git_status_foreach(repo, cb_status__count, &count));
+
+	cl_assert_equal_i(0, count);
+}
+
+static int remove_file_cb(void *data, git_buf *file)
+{
+	const char *filename = git_buf_cstr(file);
+
+	GIT_UNUSED(data);
+
+	if (git__suffixcmp(filename, ".git") == 0)
+		return 0;
+
+	if (git_path_isdir(filename))
+		cl_git_pass(git_futils_rmdir_r(filename, NULL, GIT_RMDIR_REMOVE_FILES));
+	else
+		cl_git_pass(p_unlink(git_buf_cstr(file)));
+
+	return 0;
+}
+
+/* this test is equivalent to t18-status.c:statuscb2 */
+void test_status_worktree__purged_worktree(void)
+{
+	status_entry_counts counts;
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_buf workdir = GIT_BUF_INIT;
+
+	/* first purge the contents of the worktree */
+	cl_git_pass(git_buf_sets(&workdir, git_repository_workdir(repo)));
+	cl_git_pass(git_path_direach(&workdir, 0, remove_file_cb, NULL));
+	git_buf_free(&workdir);
+
+	/* now get status */
+	memset(&counts, 0x0, sizeof(status_entry_counts));
+	counts.expected_entry_count = entry_count2;
+	counts.expected_paths = entry_paths2;
+	counts.expected_statuses = entry_statuses2;
+
+	cl_git_pass(
+		git_status_foreach(repo, cb_status__normal, &counts)
+	);
+
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+}
+
+/* this test is similar to t18-status.c:statuscb3 */
+void test_status_worktree__swap_subdir_and_file(void)
+{
+	status_entry_counts counts;
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_index *index;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	bool ignore_case;
+
+	cl_git_pass(git_repository_index(&index, repo));
+	ignore_case = (git_index_caps(index) & GIT_INDEXCAP_IGNORE_CASE) != 0;
+	git_index_free(index);
+
+	/* first alter the contents of the worktree */
+	cl_git_pass(p_rename("status/current_file", "status/swap"));
+	cl_git_pass(p_rename("status/subdir", "status/current_file"));
+	cl_git_pass(p_rename("status/swap", "status/subdir"));
+
+	cl_git_mkfile("status/.HEADER", "dummy");
+	cl_git_mkfile("status/42-is-not-prime.sigh", "dummy");
+	cl_git_mkfile("status/README.md", "dummy");
+
+	/* now get status */
+	memset(&counts, 0x0, sizeof(status_entry_counts));
+	counts.expected_entry_count = entry_count3;
+	counts.expected_paths = ignore_case ? entry_paths3_icase : entry_paths3;
+	counts.expected_statuses = ignore_case ? entry_statuses3_icase : entry_statuses3;
+
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_INCLUDE_IGNORED;
+
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts)
+	);
+
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+}
+
+void test_status_worktree__swap_subdir_with_recurse_and_pathspec(void)
+{
+	status_entry_counts counts;
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+
+	/* first alter the contents of the worktree */
+	cl_git_pass(p_rename("status/current_file", "status/swap"));
+	cl_git_pass(p_rename("status/subdir", "status/current_file"));
+	cl_git_pass(p_rename("status/swap", "status/subdir"));
+	cl_git_mkfile("status/.new_file", "dummy");
+	cl_git_pass(git_futils_mkdir_r("status/zzz_new_dir", NULL, 0777));
+	cl_git_mkfile("status/zzz_new_dir/new_file", "dummy");
+	cl_git_mkfile("status/zzz_new_file", "dummy");
+
+	/* now get status */
+	memset(&counts, 0x0, sizeof(status_entry_counts));
+	counts.expected_entry_count = entry_count4;
+	counts.expected_paths = entry_paths4;
+	counts.expected_statuses = entry_statuses4;
+
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
+	/* TODO: set pathspec to "current_file" eventually */
+
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts)
+	);
+
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+}
+
+/* this test is equivalent to t18-status.c:singlestatus0 */
+void test_status_worktree__single_file(void)
+{
+	int i;
+	unsigned int status_flags;
+	git_repository *repo = cl_git_sandbox_init("status");
+
+	for (i = 0; i < (int)entry_count0; i++) {
+		cl_git_pass(
+			git_status_file(&status_flags, repo, entry_paths0[i])
+		);
+		cl_assert(entry_statuses0[i] == status_flags);
+	}
+}
+
+/* this test is equivalent to t18-status.c:singlestatus1 */
+void test_status_worktree__single_nonexistent_file(void)
+{
+	int error;
+	unsigned int status_flags;
+	git_repository *repo = cl_git_sandbox_init("status");
+
+	error = git_status_file(&status_flags, repo, "nonexistent");
+	cl_git_fail(error);
+	cl_assert(error == GIT_ENOTFOUND);
+}
+
+/* this test is equivalent to t18-status.c:singlestatus2 */
+void test_status_worktree__single_nonexistent_file_empty_repo(void)
+{
+	int error;
+	unsigned int status_flags;
+	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
+
+	error = git_status_file(&status_flags, repo, "nonexistent");
+	cl_git_fail(error);
+	cl_assert(error == GIT_ENOTFOUND);
+}
+
+/* this test is equivalent to t18-status.c:singlestatus3 */
+void test_status_worktree__single_file_empty_repo(void)
+{
+	unsigned int status_flags;
+	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
+
+	cl_git_mkfile("empty_standard_repo/new_file", "new_file\n");
+
+	cl_git_pass(git_status_file(&status_flags, repo, "new_file"));
+	cl_assert(status_flags == GIT_STATUS_WT_NEW);
+}
+
+/* this test is equivalent to t18-status.c:singlestatus4 */
+void test_status_worktree__single_folder(void)
+{
+	int error;
+	unsigned int status_flags;
+	git_repository *repo = cl_git_sandbox_init("status");
+
+	error = git_status_file(&status_flags, repo, "subdir");
+	cl_git_fail(error);
+	cl_assert(error != GIT_ENOTFOUND);
+}
+
+
+void test_status_worktree__ignores(void)
+{
+	int i, ignored;
+	git_repository *repo = cl_git_sandbox_init("status");
+
+	for (i = 0; i < (int)entry_count0; i++) {
+		cl_git_pass(
+			git_status_should_ignore(&ignored, repo, entry_paths0[i])
+		);
+		cl_assert(ignored == (entry_statuses0[i] == GIT_STATUS_IGNORED));
+	}
+
+	cl_git_pass(
+		git_status_should_ignore(&ignored, repo, "nonexistent_file")
+	);
+	cl_assert(!ignored);
+
+	cl_git_pass(
+		git_status_should_ignore(&ignored, repo, "ignored_nonexistent_file")
+	);
+	cl_assert(ignored);
+}
+
+static int cb_status__check_592(const char *p, unsigned int s, void *payload)
+{
+	if (s != GIT_STATUS_WT_DELETED ||
+		(payload != NULL && strcmp(p, (const char *)payload) != 0))
+		return -1;
+
+	return 0;
+}
+
+void test_status_worktree__issue_592(void)
+{
+	git_repository *repo;
+	git_buf path = GIT_BUF_INIT;
+
+	repo = cl_git_sandbox_init("issue_592");
+	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "l.txt"));
+	cl_git_pass(p_unlink(git_buf_cstr(&path)));
+	cl_assert(!git_path_exists("issue_592/l.txt"));
+
+	cl_git_pass(git_status_foreach(repo, cb_status__check_592, "l.txt"));
+
+	git_buf_free(&path);
+}
+
+void test_status_worktree__issue_592_2(void)
+{
+	git_repository *repo;
+	git_buf path = GIT_BUF_INIT;
+
+	repo = cl_git_sandbox_init("issue_592");
+	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "c/a.txt"));
+	cl_git_pass(p_unlink(git_buf_cstr(&path)));
+	cl_assert(!git_path_exists("issue_592/c/a.txt"));
+
+	cl_git_pass(git_status_foreach(repo, cb_status__check_592, "c/a.txt"));
+
+	git_buf_free(&path);
+}
+
+void test_status_worktree__issue_592_3(void)
+{
+	git_repository *repo;
+	git_buf path = GIT_BUF_INIT;
+
+	repo = cl_git_sandbox_init("issue_592");
+
+	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "c"));
+	cl_git_pass(git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_RMDIR_REMOVE_FILES));
+	cl_assert(!git_path_exists("issue_592/c/a.txt"));
+
+	cl_git_pass(git_status_foreach(repo, cb_status__check_592, "c/a.txt"));
+
+	git_buf_free(&path);
+}
+
+void test_status_worktree__issue_592_4(void)
+{
+	git_repository *repo;
+	git_buf path = GIT_BUF_INIT;
+
+	repo = cl_git_sandbox_init("issue_592");
+
+	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "t/b.txt"));
+	cl_git_pass(p_unlink(git_buf_cstr(&path)));
+
+	cl_git_pass(git_status_foreach(repo, cb_status__check_592, "t/b.txt"));
+
+	git_buf_free(&path);
+}
+
+void test_status_worktree__issue_592_5(void)
+{
+	git_repository *repo;
+	git_buf path = GIT_BUF_INIT;
+
+	repo = cl_git_sandbox_init("issue_592");
+
+	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "t"));
+	cl_git_pass(git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_RMDIR_REMOVE_FILES));
+	cl_git_pass(p_mkdir(git_buf_cstr(&path), 0777));
+
+	cl_git_pass(git_status_foreach(repo, cb_status__check_592, NULL));
+
+	git_buf_free(&path);
+}
+
+void test_status_worktree__issue_592_ignores_0(void)
+{
+	int count = 0;
+	status_entry_single st;
+	git_repository *repo = cl_git_sandbox_init("issue_592");
+
+	cl_git_pass(git_status_foreach(repo, cb_status__count, &count));
+	cl_assert_equal_i(0, count);
+
+	cl_git_rewritefile("issue_592/.gitignore",
+		".gitignore\n*.txt\nc/\n[tT]*/\n");
+
+	cl_git_pass(git_status_foreach(repo, cb_status__count, &count));
+	cl_assert_equal_i(1, count);
+
+	/* This is a situation where the behavior of libgit2 is
+	 * different from core git.  Core git will show ignored.txt
+	 * in the list of ignored files, even though the directory
+	 * "t" is ignored and the file is untracked because we have
+	 * the explicit "*.txt" ignore rule.  Libgit2 just excludes
+	 * all untracked files that are contained within ignored
+	 * directories without explicitly listing them.
+	 */
+	cl_git_rewritefile("issue_592/t/ignored.txt", "ping");
+
+	memset(&st, 0, sizeof(st));
+	cl_git_pass(git_status_foreach(repo, cb_status__single, &st));
+	cl_assert_equal_i(1, st.count);
+	cl_assert(st.status == GIT_STATUS_IGNORED);
+
+	cl_git_rewritefile("issue_592/c/ignored_by_dir", "ping");
+
+	memset(&st, 0, sizeof(st));
+	cl_git_pass(git_status_foreach(repo, cb_status__single, &st));
+	cl_assert_equal_i(1, st.count);
+	cl_assert(st.status == GIT_STATUS_IGNORED);
+
+	cl_git_rewritefile("issue_592/t/ignored_by_dir_pattern", "ping");
+
+	memset(&st, 0, sizeof(st));
+	cl_git_pass(git_status_foreach(repo, cb_status__single, &st));
+	cl_assert_equal_i(1, st.count);
+	cl_assert(st.status == GIT_STATUS_IGNORED);
+}
+
+void test_status_worktree__issue_592_ignored_dirs_with_tracked_content(void)
+{
+	int count = 0;
+	git_repository *repo = cl_git_sandbox_init("issue_592b");
+
+	cl_git_pass(git_status_foreach(repo, cb_status__count, &count));
+	cl_assert_equal_i(1, count);
+
+	/* if we are really mimicking core git, then only ignored1.txt
+	 * at the top level will show up in the ignores list here.
+	 * everything else will be unmodified or skipped completely.
+	 */
+}
+
+void test_status_worktree__conflict_with_diff3(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_index *index;
+	unsigned int status;
+	git_index_entry ancestor_entry, our_entry, their_entry;
+
+	memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
+	memset(&our_entry, 0x0, sizeof(git_index_entry));
+	memset(&their_entry, 0x0, sizeof(git_index_entry));
+
+	ancestor_entry.path = "modified_file";
+	ancestor_entry.mode = 0100644;
+	git_oid_fromstr(&ancestor_entry.id,
+		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
+
+	our_entry.path = "modified_file";
+	our_entry.mode = 0100644;
+	git_oid_fromstr(&our_entry.id,
+		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
+
+	their_entry.path = "modified_file";
+	their_entry.mode = 0100644;
+	git_oid_fromstr(&their_entry.id,
+		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
+
+	cl_git_pass(git_status_file(&status, repo, "modified_file"));
+	cl_assert_equal_i(GIT_STATUS_WT_MODIFIED, status);
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_remove(index, "modified_file", 0));
+	cl_git_pass(git_index_conflict_add(
+		index, &ancestor_entry, &our_entry, &their_entry));
+	cl_git_pass(git_index_write(index));
+	git_index_free(index);
+
+	cl_git_pass(git_status_file(&status, repo, "modified_file"));
+
+	cl_assert_equal_i(GIT_STATUS_CONFLICTED, status);
+}
+
+static const char *filemode_paths[] = {
+	"exec_off",
+	"exec_off2on_staged",
+	"exec_off2on_workdir",
+	"exec_off_untracked",
+	"exec_on",
+	"exec_on2off_staged",
+	"exec_on2off_workdir",
+	"exec_on_untracked",
+};
+
+static unsigned int filemode_statuses[] = {
+	GIT_STATUS_CURRENT,
+	GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_WT_MODIFIED,
+	GIT_STATUS_WT_NEW,
+	GIT_STATUS_CURRENT,
+	GIT_STATUS_INDEX_MODIFIED,
+	GIT_STATUS_WT_MODIFIED,
+	GIT_STATUS_WT_NEW
+};
+
+static const int filemode_count = 8;
+
+void test_status_worktree__filemode_changes(void)
+{
+	git_repository *repo = cl_git_sandbox_init("filemodes");
+	status_entry_counts counts;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+
+	/* overwrite stored filemode with platform appropriate value */
+	if (cl_is_chmod_supported())
+		cl_repo_set_bool(repo, "core.filemode", true);
+	else {
+		int i;
+
+		cl_repo_set_bool(repo, "core.filemode", false);
+
+		/* won't trust filesystem mode diffs, so these will appear unchanged */
+		for (i = 0; i < filemode_count; ++i)
+			if (filemode_statuses[i] == GIT_STATUS_WT_MODIFIED)
+				filemode_statuses[i] = GIT_STATUS_CURRENT;
+	}
+
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_INCLUDE_IGNORED |
+		GIT_STATUS_OPT_INCLUDE_UNMODIFIED;
+
+	memset(&counts, 0, sizeof(counts));
+	counts.expected_entry_count = filemode_count;
+	counts.expected_paths = filemode_paths;
+	counts.expected_statuses = filemode_statuses;
+
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts)
+	);
+
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+}
+
+static int cb_status__interrupt(const char *p, unsigned int s, void *payload)
+{
+	volatile int *count = (int *)payload;
+
+	GIT_UNUSED(p);
+	GIT_UNUSED(s);
+
+	(*count)++;
+
+	return (*count == 8) ? -111 : 0;
+}
+
+void test_status_worktree__interruptable_foreach(void)
+{
+	int count = 0;
+	git_repository *repo = cl_git_sandbox_init("status");
+
+	cl_assert_equal_i(
+		-111, git_status_foreach(repo, cb_status__interrupt, &count)
+	);
+
+	cl_assert_equal_i(8, count);
+}
+
+void test_status_worktree__line_endings_dont_count_as_changes_with_autocrlf(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	unsigned int status;
+
+	cl_repo_set_bool(repo, "core.autocrlf", true);
+
+	cl_git_rewritefile("status/current_file", "current_file\r\n");
+
+	cl_git_pass(git_status_file(&status, repo, "current_file"));
+
+	/* stat data on file should no longer match stat cache, even though
+	 * file diff will be empty because of line-ending conversion - matches
+	 * the Git command-line behavior here.
+	 */
+	cl_assert_equal_i(GIT_STATUS_WT_MODIFIED, status);
+}
+
+void test_status_worktree__line_endings_dont_count_as_changes_with_autocrlf_issue_1397(void)
+{
+	git_repository *repo = cl_git_sandbox_init("issue_1397");
+	unsigned int status;
+
+	cl_repo_set_bool(repo, "core.autocrlf", true);
+
+	cl_git_pass(git_status_file(&status, repo, "crlf_file.txt"));
+
+	cl_assert_equal_i(GIT_STATUS_CURRENT, status);
+}
+
+void test_status_worktree__conflicted_item(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_index *index;
+	unsigned int status;
+	git_index_entry ancestor_entry, our_entry, their_entry;
+
+	memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
+	memset(&our_entry, 0x0, sizeof(git_index_entry));
+	memset(&their_entry, 0x0, sizeof(git_index_entry));
+
+	ancestor_entry.mode = 0100644;
+	ancestor_entry.path = "modified_file";
+	git_oid_fromstr(&ancestor_entry.id,
+		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
+
+	our_entry.mode = 0100644;
+	our_entry.path = "modified_file";
+	git_oid_fromstr(&our_entry.id,
+		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
+
+	their_entry.mode = 0100644;
+	their_entry.path = "modified_file";
+	git_oid_fromstr(&their_entry.id,
+		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
+
+	cl_git_pass(git_status_file(&status, repo, "modified_file"));
+	cl_assert_equal_i(GIT_STATUS_WT_MODIFIED, status);
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_conflict_add(index, &ancestor_entry,
+		&our_entry, &their_entry));
+
+	cl_git_pass(git_status_file(&status, repo, "modified_file"));
+	cl_assert_equal_i(GIT_STATUS_CONFLICTED, status);
+
+	git_index_free(index);
+}
+
+void test_status_worktree__conflict_has_no_oid(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_index *index;
+	git_index_entry entry = {{0}};
+	git_status_list *statuslist;
+	const git_status_entry *status;
+	git_oid zero_id = {{0}};
+
+	entry.mode = 0100644;
+	entry.path = "modified_file";
+	git_oid_fromstr(&entry.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_conflict_add(index, &entry, &entry, &entry));
+
+	git_status_list_new(&statuslist, repo, NULL);
+
+	cl_assert_equal_i(16, git_status_list_entrycount(statuslist));
+
+	status = git_status_byindex(statuslist, 2);
+
+	cl_assert_equal_i(GIT_STATUS_CONFLICTED, status->status);
+	cl_assert_equal_s("modified_file", status->head_to_index->old_file.path);
+	cl_assert(!git_oid_equal(&zero_id, &status->head_to_index->old_file.id));
+	cl_assert(0 != status->head_to_index->old_file.mode);
+	cl_assert_equal_s("modified_file", status->head_to_index->new_file.path);
+	cl_assert_equal_oid(&zero_id, &status->head_to_index->new_file.id);
+	cl_assert_equal_i(0, status->head_to_index->new_file.mode);
+	cl_assert_equal_i(0, status->head_to_index->new_file.size);
+
+	cl_assert_equal_s("modified_file", status->index_to_workdir->old_file.path);
+	cl_assert_equal_oid(&zero_id, &status->index_to_workdir->old_file.id);
+	cl_assert_equal_i(0, status->index_to_workdir->old_file.mode);
+	cl_assert_equal_i(0, status->index_to_workdir->old_file.size);
+	cl_assert_equal_s("modified_file", status->index_to_workdir->new_file.path);
+	cl_assert(
+		!git_oid_equal(&zero_id, &status->index_to_workdir->new_file.id) ||
+		!(status->index_to_workdir->new_file.flags & GIT_DIFF_FLAG_VALID_ID));
+	cl_assert(0 != status->index_to_workdir->new_file.mode);
+	cl_assert(0 != status->index_to_workdir->new_file.size);
+
+	git_index_free(index);
+	git_status_list_free(statuslist);
+}
+
+static void stage_and_commit(git_repository *repo, const char *path)
+{
+	git_index *index;
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_add_bypath(index, path));
+	cl_repo_commit_from_index(NULL, repo, NULL, 1323847743, "Initial commit\n");
+	git_index_free(index);
+}
+
+static void assert_ignore_case(
+	bool should_ignore_case,
+	int expected_lower_cased_file_status,
+	int expected_camel_cased_file_status)
+{
+	unsigned int status;
+	git_buf lower_case_path = GIT_BUF_INIT, camel_case_path = GIT_BUF_INIT;
+	git_repository *repo, *repo2;
+
+	repo = cl_git_sandbox_init("empty_standard_repo");
+	cl_git_remove_placeholders(git_repository_path(repo), "dummy-marker.txt");
+
+	cl_repo_set_bool(repo, "core.ignorecase", should_ignore_case);
+
+	cl_git_pass(git_buf_joinpath(&lower_case_path,
+		git_repository_workdir(repo), "plop"));
+
+	cl_git_mkfile(git_buf_cstr(&lower_case_path), "");
+
+	stage_and_commit(repo, "plop");
+
+	cl_git_pass(git_repository_open(&repo2, "./empty_standard_repo"));
+
+	cl_git_pass(git_status_file(&status, repo2, "plop"));
+	cl_assert_equal_i(GIT_STATUS_CURRENT, status);
+
+	cl_git_pass(git_buf_joinpath(&camel_case_path,
+		git_repository_workdir(repo), "Plop"));
+
+	cl_git_pass(p_rename(git_buf_cstr(&lower_case_path), git_buf_cstr(&camel_case_path)));
+
+	cl_git_pass(git_status_file(&status, repo2, "plop"));
+	cl_assert_equal_i(expected_lower_cased_file_status, status);
+
+	cl_git_pass(git_status_file(&status, repo2, "Plop"));
+	cl_assert_equal_i(expected_camel_cased_file_status, status);
+
+	git_repository_free(repo2);
+	git_buf_free(&lower_case_path);
+	git_buf_free(&camel_case_path);
+}
+
+void test_status_worktree__file_status_honors_core_ignorecase_true(void)
+{
+	assert_ignore_case(true, GIT_STATUS_CURRENT, GIT_STATUS_CURRENT);
+}
+
+void test_status_worktree__file_status_honors_core_ignorecase_false(void)
+{
+	assert_ignore_case(false, GIT_STATUS_WT_DELETED, GIT_STATUS_WT_NEW);
+}
+
+void test_status_worktree__file_status_honors_case_ignorecase_regarding_untracked_files(void)
+{
+    git_repository *repo = cl_git_sandbox_init("status");
+    unsigned int status;
+    git_index *index;
+
+    cl_repo_set_bool(repo, "core.ignorecase", false);
+
+	repo = cl_git_sandbox_reopen();
+
+    /* Actually returns GIT_STATUS_IGNORED on Windows */
+    cl_git_fail_with(git_status_file(&status, repo, "NEW_FILE"), GIT_ENOTFOUND);
+
+    cl_git_pass(git_repository_index(&index, repo));
+
+    cl_git_pass(git_index_add_bypath(index, "new_file"));
+    cl_git_pass(git_index_write(index));
+    git_index_free(index);
+
+    /* Actually returns GIT_STATUS_IGNORED on Windows */
+    cl_git_fail_with(git_status_file(&status, repo, "NEW_FILE"), GIT_ENOTFOUND);
+}
+
+void test_status_worktree__simple_delete(void)
+{
+    git_repository *repo = cl_git_sandbox_init("renames");
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	int count;
+
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH |
+		GIT_STATUS_OPT_EXCLUDE_SUBMODULES |
+		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
+
+	count = 0;
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__count, &count) );
+	cl_assert_equal_i(0, count);
+
+	cl_must_pass(p_unlink("renames/untimely.txt"));
+
+	count = 0;
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__count, &count) );
+	cl_assert_equal_i(1, count);
+}
+
+void test_status_worktree__simple_delete_indexed(void)
+{
+	git_repository *repo = cl_git_sandbox_init("renames");
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	git_status_list *status;
+
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH |
+		GIT_STATUS_OPT_EXCLUDE_SUBMODULES |
+		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
+
+	cl_git_pass(git_status_list_new(&status, repo, &opts));
+	cl_assert_equal_sz(0, git_status_list_entrycount(status));
+	git_status_list_free(status);
+
+	cl_must_pass(p_unlink("renames/untimely.txt"));
+
+	cl_git_pass(git_status_list_new(&status, repo, &opts));
+	cl_assert_equal_sz(1, git_status_list_entrycount(status));
+	cl_assert_equal_i(
+		GIT_STATUS_WT_DELETED, git_status_byindex(status, 0)->status);
+	git_status_list_free(status);
+}
+
+static const char *icase_paths[] = { "B", "c", "g", "H" };
+static unsigned int icase_statuses[] = {
+	GIT_STATUS_WT_MODIFIED, GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_MODIFIED, GIT_STATUS_WT_DELETED,
+};
+
+static const char *case_paths[] = { "B", "H", "c", "g" };
+static unsigned int case_statuses[] = {
+	GIT_STATUS_WT_MODIFIED, GIT_STATUS_WT_DELETED,
+	GIT_STATUS_WT_DELETED, GIT_STATUS_WT_MODIFIED,
+};
+
+void test_status_worktree__sorting_by_case(void)
+{
+	git_repository *repo = cl_git_sandbox_init("icase");
+	git_index *index;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	bool native_ignore_case;
+	status_entry_counts counts;
+
+	cl_git_pass(git_repository_index(&index, repo));
+	native_ignore_case =
+		(git_index_caps(index) & GIT_INDEXCAP_IGNORE_CASE) != 0;
+	git_index_free(index);
+
+	memset(&counts, 0, sizeof(counts));
+	counts.expected_entry_count = 0;
+	counts.expected_paths = NULL;
+	counts.expected_statuses = NULL;
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts));
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+
+	cl_git_rewritefile("icase/B", "new stuff");
+	cl_must_pass(p_unlink("icase/c"));
+	cl_git_rewritefile("icase/g", "new stuff");
+	cl_must_pass(p_unlink("icase/H"));
+
+	memset(&counts, 0, sizeof(counts));
+	counts.expected_entry_count = 4;
+	if (native_ignore_case) {
+		counts.expected_paths = icase_paths;
+		counts.expected_statuses = icase_statuses;
+	} else {
+		counts.expected_paths = case_paths;
+		counts.expected_statuses = case_statuses;
+	}
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts));
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+
+	opts.flags = GIT_STATUS_OPT_SORT_CASE_SENSITIVELY;
+
+	memset(&counts, 0, sizeof(counts));
+	counts.expected_entry_count = 4;
+	counts.expected_paths = case_paths;
+	counts.expected_statuses = case_statuses;
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts));
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+
+	opts.flags = GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY;
+
+	memset(&counts, 0, sizeof(counts));
+	counts.expected_entry_count = 4;
+	counts.expected_paths = icase_paths;
+	counts.expected_statuses = icase_statuses;
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts));
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+}
+
+void test_status_worktree__long_filenames(void)
+{
+	char path[260*4+1];
+	const char *expected_paths[] = {path};
+	const unsigned int expected_statuses[] = {GIT_STATUS_WT_NEW};
+
+	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	status_entry_counts counts = {0};
+
+	// Create directory with amazingly long filename
+	sprintf(path, "empty_standard_repo/%s", longname);
+	cl_git_pass(git_futils_mkdir_r(path, NULL, 0777));
+	sprintf(path, "empty_standard_repo/%s/foo", longname);
+	cl_git_mkfile(path, "dummy");
+
+	sprintf(path, "%s/foo", longname);
+	counts.expected_entry_count = 1;
+	counts.expected_paths = expected_paths;
+	counts.expected_statuses = expected_statuses;
+
+	opts.show = GIT_STATUS_SHOW_WORKDIR_ONLY;
+	opts.flags = GIT_STATUS_OPT_DEFAULTS;
+
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts) );
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+}
+
+/* The update stat cache tests mostly just mirror other tests and try
+ * to make sure that updating the stat cache doesn't change the results
+ * while reducing the amount of work that needs to be done
+ */
+
+static void check_status0(git_status_list *status)
+{
+	size_t i, max_i = git_status_list_entrycount(status);
+	cl_assert_equal_sz(entry_count0, max_i);
+	for (i = 0; i < max_i; ++i) {
+		const git_status_entry *entry = git_status_byindex(status, i);
+		cl_assert_equal_i(entry_statuses0[i], entry->status);
+	}
+}
+
+void test_status_worktree__update_stat_cache_0(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	git_status_list *status;
+	git_diff_perfdata perf = GIT_DIFF_PERFDATA_INIT;
+	git_index *index;
+
+	opts.flags = GIT_STATUS_OPT_DEFAULTS;
+
+	cl_git_pass(git_status_list_new(&status, repo, &opts));
+	check_status0(status);
+	cl_git_pass(git_status_list_get_perfdata(&perf, status));
+	cl_assert_equal_sz(13 + 3, perf.stat_calls);
+	cl_assert_equal_sz(5, perf.oid_calculations);
+
+	git_status_list_free(status);
+
+	/* tick the index so we avoid recalculating racily-clean entries */
+	cl_git_pass(git_repository_index__weakptr(&index, repo));
+	tick_index(index);
+
+	opts.flags |= GIT_STATUS_OPT_UPDATE_INDEX;
+
+	cl_git_pass(git_status_list_new(&status, repo, &opts));
+	check_status0(status);
+	cl_git_pass(git_status_list_get_perfdata(&perf, status));
+	cl_assert_equal_sz(13 + 3, perf.stat_calls);
+	cl_assert_equal_sz(5, perf.oid_calculations);
+
+	git_status_list_free(status);
+
+	opts.flags &= ~GIT_STATUS_OPT_UPDATE_INDEX;
+
+	/* tick again as the index updating from the previous diff might have reset the timestamp */
+	tick_index(index);
+	cl_git_pass(git_status_list_new(&status, repo, &opts));
+	check_status0(status);
+	cl_git_pass(git_status_list_get_perfdata(&perf, status));
+	cl_assert_equal_sz(13 + 3, perf.stat_calls);
+	cl_assert_equal_sz(0, perf.oid_calculations);
+
+	git_status_list_free(status);
+}
+
+void test_status_worktree__unreadable(void)
+{
+#ifndef GIT_WIN32
+	const char *expected_paths[] = { "no_permission/foo" };
+	const unsigned int expected_statuses[] = {GIT_STATUS_WT_UNREADABLE};
+
+	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	status_entry_counts counts = {0};
+
+	/* Create directory with no read permission */
+	cl_git_pass(git_futils_mkdir_r("empty_standard_repo/no_permission", NULL, 0777));
+	cl_git_mkfile("empty_standard_repo/no_permission/foo", "dummy");
+	p_chmod("empty_standard_repo/no_permission", 0644);
+
+	counts.expected_entry_count = 1;
+	counts.expected_paths = expected_paths;
+	counts.expected_statuses = expected_statuses;
+
+	opts.show = GIT_STATUS_SHOW_WORKDIR_ONLY;
+	opts.flags = GIT_STATUS_OPT_DEFAULTS | GIT_STATUS_OPT_INCLUDE_UNREADABLE;
+
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts) );
+
+	/* Restore permissions so we can cleanup :) */
+	p_chmod("empty_standard_repo/no_permission", 0777);
+
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+#endif
+}
+
+void test_status_worktree__unreadable_not_included(void)
+{
+#ifndef GIT_WIN32
+	const char *expected_paths[] = { "no_permission/" };
+	const unsigned int expected_statuses[] = {GIT_STATUS_WT_NEW};
+
+	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	status_entry_counts counts = {0};
+
+	/* Create directory with no read permission */
+	cl_git_pass(git_futils_mkdir_r("empty_standard_repo/no_permission", NULL, 0777));
+	cl_git_mkfile("empty_standard_repo/no_permission/foo", "dummy");
+	p_chmod("empty_standard_repo/no_permission", 0644);
+
+	counts.expected_entry_count = 1;
+	counts.expected_paths = expected_paths;
+	counts.expected_statuses = expected_statuses;
+
+	opts.show = GIT_STATUS_SHOW_WORKDIR_ONLY;
+	opts.flags = (GIT_STATUS_OPT_INCLUDE_IGNORED | GIT_STATUS_OPT_INCLUDE_UNTRACKED);
+
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts) );
+
+	/* Restore permissions so we can cleanup :) */
+	p_chmod("empty_standard_repo/no_permission", 0777);
+
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+#endif
+}
+
+void test_status_worktree__unreadable_as_untracked(void)
+{
+	const char *expected_paths[] = { "no_permission/foo" };
+	const unsigned int expected_statuses[] = {GIT_STATUS_WT_NEW};
+
+	git_repository *repo = cl_git_sandbox_init("empty_standard_repo");
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	status_entry_counts counts = {0};
+
+	/* Create directory with no read permission */
+	cl_git_pass(git_futils_mkdir_r("empty_standard_repo/no_permission", NULL, 0777));
+	cl_git_mkfile("empty_standard_repo/no_permission/foo", "dummy");
+	p_chmod("empty_standard_repo/no_permission", 0644);
+
+	counts.expected_entry_count = 1;
+	counts.expected_paths = expected_paths;
+	counts.expected_statuses = expected_statuses;
+
+	opts.show = GIT_STATUS_SHOW_WORKDIR_ONLY;
+	opts.flags = GIT_STATUS_OPT_DEFAULTS |
+		GIT_STATUS_OPT_INCLUDE_UNREADABLE |
+		GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED;
+
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts) );
+
+	/* Restore permissions so we can cleanup :) */
+	p_chmod("empty_standard_repo/no_permission", 0777);
+
+	cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+	cl_assert_equal_i(0, counts.wrong_status_flags_count);
+	cl_assert_equal_i(0, counts.wrong_sorted_path);
+}
+
+void test_status_worktree__update_index_with_symlink_doesnt_change_mode(void)
+{
+	git_repository *repo = cl_git_sandbox_init("testrepo");
+	git_reference *head;
+	git_object *head_object;
+	git_index *index;
+	const git_index_entry *idx_entry;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	status_entry_counts counts = {0};
+	const char *expected_paths[] = { "README" };
+	const unsigned int expected_statuses[] = {GIT_STATUS_WT_NEW};
+
+	opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
+	opts.flags = GIT_STATUS_OPT_DEFAULTS | GIT_STATUS_OPT_UPDATE_INDEX;
+
+	cl_git_pass(git_repository_head(&head, repo));
+	cl_git_pass(git_reference_peel(&head_object, head, GIT_OBJ_COMMIT));
+
+	cl_git_pass(git_reset(repo, head_object, GIT_RESET_HARD, NULL));
+
+	cl_git_rewritefile("testrepo/README", "This was rewritten.");
+
+	/* this status rewrites the index because we have changed the
+	 * contents of a tracked file
+	 */
+	counts.expected_entry_count = 1;
+	counts.expected_paths = expected_paths;
+	counts.expected_statuses = expected_statuses;
+
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__normal, &counts));
+	cl_assert_equal_i(1, counts.entry_count);
+
+	/* now ensure that the status's rewrite of the index did not screw
+	 * up the mode of the symlink `link_to_new.txt`, particularly
+	 * on platforms that don't support symlinks
+	 */
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_read(index, true));
+
+	cl_assert(idx_entry = git_index_get_bypath(index, "link_to_new.txt", 0));
+	cl_assert(S_ISLNK(idx_entry->mode));
+
+	git_index_free(index);
+	git_object_free(head_object);
+	git_reference_free(head);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/worktree_init.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/worktree_init.c
new file mode 100755
index 0000000..cc7e126
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/status/worktree_init.c
@@ -0,0 +1,338 @@
+#include "clar_libgit2.h"
+#include "git2/sys/repository.h"
+
+#include "fileops.h"
+#include "ignore.h"
+#include "status_helpers.h"
+#include "posix.h"
+#include "util.h"
+#include "path.h"
+
+static void cleanup_new_repo(void *path)
+{
+	cl_fixture_cleanup((char *)path);
+}
+
+void test_status_worktree_init__cannot_retrieve_the_status_of_a_bare_repository(void)
+{
+	git_repository *repo;
+	unsigned int status = 0;
+
+	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+	cl_assert_equal_i(GIT_EBAREREPO, git_status_file(&status, repo, "dummy"));
+	git_repository_free(repo);
+}
+
+void test_status_worktree_init__first_commit_in_progress(void)
+{
+	git_repository *repo;
+	git_index *index;
+	status_entry_single result;
+
+	cl_set_cleanup(&cleanup_new_repo, "getting_started");
+
+	cl_git_pass(git_repository_init(&repo, "getting_started", 0));
+	cl_git_mkfile("getting_started/testfile.txt", "content\n");
+
+	memset(&result, 0, sizeof(result));
+	cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
+	cl_assert_equal_i(1, result.count);
+	cl_assert(result.status == GIT_STATUS_WT_NEW);
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_add_bypath(index, "testfile.txt"));
+	cl_git_pass(git_index_write(index));
+
+	memset(&result, 0, sizeof(result));
+	cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
+	cl_assert_equal_i(1, result.count);
+	cl_assert(result.status == GIT_STATUS_INDEX_NEW);
+
+	git_index_free(index);
+	git_repository_free(repo);
+}
+
+
+
+void test_status_worktree_init__status_file_without_index_or_workdir(void)
+{
+	git_repository *repo;
+	unsigned int status = 0;
+	git_index *index;
+
+	cl_git_pass(p_mkdir("wd", 0777));
+
+	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+	cl_git_pass(git_repository_set_workdir(repo, "wd", false));
+
+	cl_git_pass(git_index_open(&index, "empty-index"));
+	cl_assert_equal_i(0, (int)git_index_entrycount(index));
+	git_repository_set_index(repo, index);
+
+	cl_git_pass(git_status_file(&status, repo, "branch_file.txt"));
+
+	cl_assert_equal_i(GIT_STATUS_INDEX_DELETED, status);
+
+	git_repository_free(repo);
+	git_index_free(index);
+	cl_git_pass(p_rmdir("wd"));
+}
+
+static void fill_index_wth_head_entries(git_repository *repo, git_index *index)
+{
+	git_oid oid;
+	git_commit *commit;
+	git_tree *tree;
+
+	cl_git_pass(git_reference_name_to_id(&oid, repo, "HEAD"));
+	cl_git_pass(git_commit_lookup(&commit, repo, &oid));
+	cl_git_pass(git_commit_tree(&tree, commit));
+
+	cl_git_pass(git_index_read_tree(index, tree));
+	cl_git_pass(git_index_write(index));
+
+	git_tree_free(tree);
+	git_commit_free(commit);
+}
+
+void test_status_worktree_init__status_file_with_clean_index_and_empty_workdir(void)
+{
+	git_repository *repo;
+	unsigned int status = 0;
+	git_index *index;
+
+	cl_git_pass(p_mkdir("wd", 0777));
+
+	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+	cl_git_pass(git_repository_set_workdir(repo, "wd", false));
+
+	cl_git_pass(git_index_open(&index, "my-index"));
+	fill_index_wth_head_entries(repo, index);
+
+	git_repository_set_index(repo, index);
+
+	cl_git_pass(git_status_file(&status, repo, "branch_file.txt"));
+
+	cl_assert_equal_i(GIT_STATUS_WT_DELETED, status);
+
+	git_repository_free(repo);
+	git_index_free(index);
+	cl_git_pass(p_rmdir("wd"));
+	cl_git_pass(p_unlink("my-index"));
+}
+
+void test_status_worktree_init__bracket_in_filename(void)
+{
+	git_repository *repo;
+	git_index *index;
+	status_entry_single result;
+	unsigned int status_flags;
+
+	#define FILE_WITH_BRACKET "LICENSE[1].md"
+	#define FILE_WITHOUT_BRACKET "LICENSE1.md"
+
+	cl_set_cleanup(&cleanup_new_repo, "with_bracket");
+
+	cl_git_pass(git_repository_init(&repo, "with_bracket", 0));
+	cl_git_mkfile("with_bracket/" FILE_WITH_BRACKET, "I have a bracket in my name\n");
+
+	/* file is new to working directory */
+
+	memset(&result, 0, sizeof(result));
+	cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
+	cl_assert_equal_i(1, result.count);
+	cl_assert(result.status == GIT_STATUS_WT_NEW);
+
+	cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET));
+	cl_assert(status_flags == GIT_STATUS_WT_NEW);
+
+	/* ignore the file */
+
+	cl_git_rewritefile("with_bracket/.gitignore", "*.md\n.gitignore\n");
+
+	memset(&result, 0, sizeof(result));
+	cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
+	cl_assert_equal_i(2, result.count);
+	cl_assert(result.status == GIT_STATUS_IGNORED);
+
+	cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET));
+	cl_assert(status_flags == GIT_STATUS_IGNORED);
+
+	/* don't ignore the file */
+
+	cl_git_rewritefile("with_bracket/.gitignore", ".gitignore\n");
+
+	memset(&result, 0, sizeof(result));
+	cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
+	cl_assert_equal_i(2, result.count);
+	cl_assert(result.status == GIT_STATUS_WT_NEW);
+
+	cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET));
+	cl_assert(status_flags == GIT_STATUS_WT_NEW);
+
+	/* add the file to the index */
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_add_bypath(index, FILE_WITH_BRACKET));
+	cl_git_pass(git_index_write(index));
+
+	memset(&result, 0, sizeof(result));
+	cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
+	cl_assert_equal_i(2, result.count);
+	cl_assert(result.status == GIT_STATUS_INDEX_NEW);
+
+	cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET));
+	cl_assert(status_flags == GIT_STATUS_INDEX_NEW);
+
+	/* Create file without bracket */
+
+	cl_git_mkfile("with_bracket/" FILE_WITHOUT_BRACKET, "I have no bracket in my name!\n");
+
+	cl_git_pass(git_status_file(&status_flags, repo, FILE_WITHOUT_BRACKET));
+	cl_assert(status_flags == GIT_STATUS_WT_NEW);
+
+	cl_git_pass(git_status_file(&status_flags, repo, "LICENSE\\[1\\].md"));
+	cl_assert(status_flags == GIT_STATUS_INDEX_NEW);
+
+	cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET));
+
+	git_index_free(index);
+	git_repository_free(repo);
+}
+
+void test_status_worktree_init__space_in_filename(void)
+{
+	git_repository *repo;
+	git_index *index;
+	status_entry_single result;
+	unsigned int status_flags;
+
+#define FILE_WITH_SPACE "LICENSE - copy.md"
+
+	cl_set_cleanup(&cleanup_new_repo, "with_space");
+	cl_git_pass(git_repository_init(&repo, "with_space", 0));
+	cl_git_mkfile("with_space/" FILE_WITH_SPACE, "I have a space in my name\n");
+
+	/* file is new to working directory */
+
+	memset(&result, 0, sizeof(result));
+	cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
+	cl_assert_equal_i(1, result.count);
+	cl_assert(result.status == GIT_STATUS_WT_NEW);
+
+	cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE));
+	cl_assert(status_flags == GIT_STATUS_WT_NEW);
+
+	/* ignore the file */
+
+	cl_git_rewritefile("with_space/.gitignore", "*.md\n.gitignore\n");
+
+	memset(&result, 0, sizeof(result));
+	cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
+	cl_assert_equal_i(2, result.count);
+	cl_assert(result.status == GIT_STATUS_IGNORED);
+
+	cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE));
+	cl_assert(status_flags == GIT_STATUS_IGNORED);
+
+	/* don't ignore the file */
+
+	cl_git_rewritefile("with_space/.gitignore", ".gitignore\n");
+
+	memset(&result, 0, sizeof(result));
+	cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
+	cl_assert_equal_i(2, result.count);
+	cl_assert(result.status == GIT_STATUS_WT_NEW);
+
+	cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE));
+	cl_assert(status_flags == GIT_STATUS_WT_NEW);
+
+	/* add the file to the index */
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_add_bypath(index, FILE_WITH_SPACE));
+	cl_git_pass(git_index_write(index));
+
+	memset(&result, 0, sizeof(result));
+	cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
+	cl_assert_equal_i(2, result.count);
+	cl_assert(result.status == GIT_STATUS_INDEX_NEW);
+
+	cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE));
+	cl_assert(status_flags == GIT_STATUS_INDEX_NEW);
+
+	git_index_free(index);
+	git_repository_free(repo);
+}
+
+static int cb_status__expected_path(const char *p, unsigned int s, void *payload)
+{
+	const char *expected_path = (const char *)payload;
+
+	GIT_UNUSED(s);
+
+	if (payload == NULL)
+		cl_fail("Unexpected path");
+
+	cl_assert_equal_s(expected_path, p);
+
+	return 0;
+}
+
+void test_status_worktree_init__disable_pathspec_match(void)
+{
+	git_repository *repo;
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	char *file_with_bracket = "LICENSE[1].md", 
+		*imaginary_file_with_bracket = "LICENSE[1-2].md";
+
+	cl_set_cleanup(&cleanup_new_repo, "pathspec");
+	cl_git_pass(git_repository_init(&repo, "pathspec", 0));
+	cl_git_mkfile("pathspec/LICENSE[1].md", "screaming bracket\n");
+	cl_git_mkfile("pathspec/LICENSE1.md", "no bracket\n");
+
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED | 
+		GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH;
+	opts.pathspec.count = 1;
+	opts.pathspec.strings = &file_with_bracket;
+
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__expected_path, 
+		file_with_bracket)
+	);
+
+	/* Test passing a pathspec matching files in the workdir. */
+	/* Must not match because pathspecs are disabled. */ 
+	opts.pathspec.strings = &imaginary_file_with_bracket;
+	cl_git_pass(
+		git_status_foreach_ext(repo, &opts, cb_status__expected_path, NULL)
+	);
+
+	git_repository_free(repo);
+}
+
+void test_status_worktree_init__new_staged_file_must_handle_crlf(void)
+{
+	git_repository *repo;
+	git_index *index;
+	unsigned int status;
+
+	cl_set_cleanup(&cleanup_new_repo, "getting_started");
+	cl_git_pass(git_repository_init(&repo, "getting_started", 0));
+
+	/* Ensure that repo has core.autocrlf=true */
+	cl_repo_set_bool(repo, "core.autocrlf", true);
+
+	cl_git_mkfile("getting_started/testfile.txt", "content\r\n");	/* Content with CRLF */
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_add_bypath(index, "testfile.txt"));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_status_file(&status, repo, "testfile.txt"));
+	cl_assert_equal_i(GIT_STATUS_INDEX_NEW, status);
+
+	git_index_free(index);
+	git_repository_free(repo);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stress/diff.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stress/diff.c
new file mode 100755
index 0000000..a3ba4fa
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/stress/diff.c
@@ -0,0 +1,146 @@
+#include "clar_libgit2.h"
+#include "../diff/diff_helpers.h"
+
+static git_repository *g_repo = NULL;
+
+void test_stress_diff__initialize(void)
+{
+}
+
+void test_stress_diff__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+#define ANOTHER_POEM \
+"OH, glorious are the guarded heights\nWhere guardian souls abide—\nSelf-exiled from our gross delights—\nAbove, beyond, outside:\nAn ampler arc their spirit swings—\nCommands a juster view—\nWe have their word for all these things,\nNo doubt their words are true.\n\nYet we, the bond slaves of our day,\nWhom dirt and danger press—\nCo-heirs of insolence, delay,\nAnd leagued unfaithfulness—\nSuch is our need must seek indeed\nAnd, having found, engage\nThe men who merely do the work\nFor which they draw the wage.\n\nFrom forge and farm and mine and bench,\nDeck, altar, outpost lone—\nMill, school, battalion, counter, trench,\nRail, senate, sheepfold, throne—\nCreation's cry goes up on high\nFrom age to cheated age:\n\"Send us the men who do the work\n\"For which they draw the wage!\"\n"
+
+static void test_with_many(int expected_new)
+{
+	git_index *index;
+	git_tree *tree, *new_tree;
+	git_diff *diff = NULL;
+	diff_expects exp;
+	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(
+		git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(p_rename("renames/ikeepsix.txt", "renames/ikeepsix2.txt"));
+	cl_git_pass(git_index_remove_bypath(index, "ikeepsix.txt"));
+	cl_git_pass(git_index_add_bypath(index, "ikeepsix2.txt"));
+	cl_git_pass(git_index_write(index));
+
+	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, NULL, NULL, NULL, &exp));
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(expected_new + 1, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(expected_new + 2, exp.files);
+
+	opts.flags = GIT_DIFF_FIND_ALL;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, NULL, NULL, NULL, &exp));
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
+	cl_assert_equal_i(expected_new, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(expected_new + 1, exp.files);
+
+	git_diff_free(diff);
+
+	cl_repo_commit_from_index(NULL, g_repo, NULL, 1372350000, "yoyoyo");
+	cl_git_pass(git_revparse_single(
+		(git_object **)&new_tree, g_repo, "HEAD^{tree}"));
+
+	cl_git_pass(git_diff_tree_to_tree(
+		&diff, g_repo, tree, new_tree, &diffopts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, NULL, NULL, NULL, &exp));
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
+	cl_assert_equal_i(expected_new + 1, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(expected_new + 2, exp.files);
+
+	opts.flags = GIT_DIFF_FIND_ALL;
+	cl_git_pass(git_diff_find_similar(diff, &opts));
+
+	memset(&exp, 0, sizeof(exp));
+	cl_git_pass(git_diff_foreach(
+		diff, diff_file_cb, NULL, NULL, NULL, &exp));
+	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
+	cl_assert_equal_i(expected_new, exp.file_status[GIT_DELTA_ADDED]);
+	cl_assert_equal_i(expected_new + 1, exp.files);
+
+	git_diff_free(diff);
+
+	git_tree_free(new_tree);
+	git_tree_free(tree);
+	git_index_free(index);
+}
+
+void test_stress_diff__rename_big_files(void)
+{
+	git_index *index;
+	char tmp[64];
+	int i, j;
+	git_buf b = GIT_BUF_INIT;
+
+	g_repo = cl_git_sandbox_init("renames");
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	for (i = 0; i < 100; i += 1) {
+		p_snprintf(tmp, sizeof(tmp), "renames/newfile%03d", i);
+		for (j = i * 256; j > 0; --j)
+			git_buf_printf(&b, "more content %d\n", i);
+		cl_git_mkfile(tmp, b.ptr);
+	}
+
+	for (i = 0; i < 100; i += 1) {
+		p_snprintf(tmp, sizeof(tmp), "renames/newfile%03d", i);
+		cl_git_pass(git_index_add_bypath(index, tmp + strlen("renames/")));
+	}
+
+	git_buf_free(&b);
+	git_index_free(index);
+
+	test_with_many(100);
+}
+
+void test_stress_diff__rename_many_files(void)
+{
+	git_index *index;
+	char tmp[64];
+	int i;
+	git_buf b = GIT_BUF_INIT;
+
+	g_repo = cl_git_sandbox_init("renames");
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+
+	git_buf_printf(&b, "%08d\n" ANOTHER_POEM "%08d\n" ANOTHER_POEM ANOTHER_POEM, 0, 0);
+
+	for (i = 0; i < 2500; i += 1) {
+		p_snprintf(tmp, sizeof(tmp), "renames/newfile%03d", i);
+		p_snprintf(b.ptr, 9, "%08d", i);
+		b.ptr[8] = '\n';
+		cl_git_mkfile(tmp, b.ptr);
+	}
+	git_buf_free(&b);
+
+	for (i = 0; i < 2500; i += 1) {
+		p_snprintf(tmp, sizeof(tmp), "renames/newfile%03d", i);
+		cl_git_pass(git_index_add_bypath(index, tmp + strlen("renames/")));
+	}
+
+	git_index_free(index);
+
+	test_with_many(2500);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/add.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/add.c
new file mode 100755
index 0000000..c3b3e63
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/add.c
@@ -0,0 +1,130 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "path.h"
+#include "submodule_helpers.h"
+#include "config/config_helpers.h"
+#include "fileops.h"
+#include "repository.h"
+
+static git_repository *g_repo = NULL;
+
+void test_submodule_add__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static void assert_submodule_url(const char* name, const char *url)
+{
+	git_buf key = GIT_BUF_INIT;
+
+
+	cl_git_pass(git_buf_printf(&key, "submodule.%s.url", name));
+	assert_config_entry_value(g_repo, git_buf_cstr(&key), url);
+
+	git_buf_free(&key);
+}
+
+void test_submodule_add__url_absolute(void)
+{
+	git_submodule *sm;
+	git_repository *repo;
+	git_buf dot_git_content = GIT_BUF_INIT;
+
+	g_repo = setup_fixture_submod2();
+
+	/* re-add existing submodule */
+	cl_git_fail_with(
+		GIT_EEXISTS,
+		git_submodule_add_setup(NULL, g_repo, "whatever", "sm_unchanged", 1));
+
+	/* add a submodule using a gitlink */
+
+	cl_git_pass(
+		git_submodule_add_setup(&sm, g_repo, "https://github.com/libgit2/libgit2.git", "sm_libgit2", 1)
+		);
+	git_submodule_free(sm);
+
+	cl_assert(git_path_isfile("submod2/" "sm_libgit2" "/.git"));
+
+	cl_assert(git_path_isdir("submod2/.git/modules"));
+	cl_assert(git_path_isdir("submod2/.git/modules/" "sm_libgit2"));
+	cl_assert(git_path_isfile("submod2/.git/modules/" "sm_libgit2" "/HEAD"));
+	assert_submodule_url("sm_libgit2", "https://github.com/libgit2/libgit2.git");
+
+	cl_git_pass(git_repository_open(&repo, "submod2/" "sm_libgit2"));
+
+	/* Verify worktree path is relative */
+	assert_config_entry_value(repo, "core.worktree", "../../../sm_libgit2/");
+
+	/* Verify gitdir path is relative */
+	cl_git_pass(git_futils_readbuffer(&dot_git_content, "submod2/" "sm_libgit2" "/.git"));
+	cl_assert_equal_s("gitdir: ../.git/modules/sm_libgit2/", dot_git_content.ptr);
+
+	git_repository_free(repo);
+	git_buf_free(&dot_git_content);
+
+	/* add a submodule not using a gitlink */
+
+	cl_git_pass(
+		git_submodule_add_setup(&sm, g_repo, "https://github.com/libgit2/libgit2.git", "sm_libgit2b", 0)
+		);
+	git_submodule_free(sm);
+
+	cl_assert(git_path_isdir("submod2/" "sm_libgit2b" "/.git"));
+	cl_assert(git_path_isfile("submod2/" "sm_libgit2b" "/.git/HEAD"));
+	cl_assert(!git_path_exists("submod2/.git/modules/" "sm_libgit2b"));
+	assert_submodule_url("sm_libgit2b", "https://github.com/libgit2/libgit2.git");
+}
+
+void test_submodule_add__url_relative(void)
+{
+	git_submodule *sm;
+	git_remote *remote;
+	git_strarray problems = {0};
+
+	/* default remote url is https://github.com/libgit2/false.git */
+	g_repo = cl_git_sandbox_init("testrepo2");
+
+	/* make sure we don't default to origin - rename origin -> test_remote */
+	cl_git_pass(git_remote_rename(&problems, g_repo, "origin", "test_remote"));
+	cl_assert_equal_i(0, problems.count);
+	git_strarray_free(&problems);
+	cl_git_fail(git_remote_lookup(&remote, g_repo, "origin"));
+
+	cl_git_pass(
+		git_submodule_add_setup(&sm, g_repo, "../TestGitRepository", "TestGitRepository", 1)
+		);
+	git_submodule_free(sm);
+
+	assert_submodule_url("TestGitRepository", "https://github.com/libgit2/TestGitRepository");
+}
+
+void test_submodule_add__url_relative_to_origin(void)
+{
+	git_submodule *sm;
+
+	/* default remote url is https://github.com/libgit2/false.git */
+	g_repo = cl_git_sandbox_init("testrepo2");
+
+	cl_git_pass(
+		git_submodule_add_setup(&sm, g_repo, "../TestGitRepository", "TestGitRepository", 1)
+		);
+	git_submodule_free(sm);
+
+	assert_submodule_url("TestGitRepository", "https://github.com/libgit2/TestGitRepository");
+}
+
+void test_submodule_add__url_relative_to_workdir(void)
+{
+	git_submodule *sm;
+
+	/* In this repo, HEAD (master) has no remote tracking branc h*/
+	g_repo = cl_git_sandbox_init("testrepo");
+
+	cl_git_pass(
+		git_submodule_add_setup(&sm, g_repo, "./", "TestGitRepository", 1)
+		);
+	git_submodule_free(sm);
+
+	assert_submodule_url("TestGitRepository", git_repository_workdir(g_repo));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/init.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/init.c
new file mode 100755
index 0000000..9e0cf57
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/init.c
@@ -0,0 +1,115 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "path.h"
+#include "submodule_helpers.h"
+#include "fileops.h"
+
+static git_repository *g_repo = NULL;
+
+void test_submodule_init__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_submodule_init__absolute_url(void)
+{
+	git_submodule *sm;
+	git_config *cfg;
+	git_buf absolute_url = GIT_BUF_INIT;
+	const char *config_url;
+
+	g_repo = setup_fixture_submodule_simple();
+
+	cl_assert(git_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0);
+	cl_git_pass(git_buf_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git"));
+
+	/* write the absolute url to the .gitmodules file*/
+	cl_git_pass(git_submodule_set_url(g_repo, "testrepo", absolute_url.ptr));
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
+	/* verify that the .gitmodules is set with an absolute path*/
+	cl_assert_equal_s(absolute_url.ptr, git_submodule_url(sm));
+
+	/* init and verify that absolute path is written to .git/config */
+	cl_git_pass(git_submodule_init(sm, false));
+
+	cl_git_pass(git_repository_config_snapshot(&cfg, g_repo));
+
+	cl_git_pass(git_config_get_string(&config_url, cfg, "submodule.testrepo.url"));
+	cl_assert_equal_s(absolute_url.ptr, config_url);
+
+	git_buf_free(&absolute_url);
+	git_config_free(cfg);
+	git_submodule_free(sm);
+}
+
+void test_submodule_init__relative_url(void)
+{
+	git_submodule *sm;
+	git_config *cfg;
+	git_buf absolute_url = GIT_BUF_INIT;
+	const char *config_url;
+
+	g_repo = setup_fixture_submodule_simple();
+
+	cl_assert(git_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0);
+	cl_git_pass(git_buf_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git"));
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
+	/* verify that the .gitmodules is set with an absolute path*/
+	cl_assert_equal_s("../testrepo.git", git_submodule_url(sm));
+
+	/* init and verify that absolute path is written to .git/config */
+	cl_git_pass(git_submodule_init(sm, false));
+
+	cl_git_pass(git_repository_config_snapshot(&cfg, g_repo));
+
+	cl_git_pass(git_config_get_string(&config_url, cfg, "submodule.testrepo.url"));
+	cl_assert_equal_s(absolute_url.ptr, config_url);
+
+	git_buf_free(&absolute_url);
+	git_config_free(cfg);
+	git_submodule_free(sm);
+}
+
+void test_submodule_init__relative_url_detached_head(void)
+{
+	git_submodule *sm;
+	git_config *cfg;
+	git_buf absolute_url = GIT_BUF_INIT;
+	const char *config_url;
+	git_reference *head_ref = NULL;
+	git_object *head_commit = NULL;
+
+	g_repo = setup_fixture_submodule_simple();
+
+	/* Put the parent repository into a detached head state. */
+	cl_git_pass(git_repository_head(&head_ref, g_repo));
+	cl_git_pass(git_reference_peel(&head_commit, head_ref, GIT_OBJ_COMMIT));
+
+	cl_git_pass(git_repository_set_head_detached(g_repo, git_commit_id((git_commit *)head_commit)));
+
+	cl_assert(git_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0);
+	cl_git_pass(git_buf_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git"));
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
+	/* verify that the .gitmodules is set with an absolute path*/
+	cl_assert_equal_s("../testrepo.git", git_submodule_url(sm));
+
+	/* init and verify that absolute path is written to .git/config */
+	cl_git_pass(git_submodule_init(sm, false));
+
+	cl_git_pass(git_repository_config_snapshot(&cfg, g_repo));
+
+	cl_git_pass(git_config_get_string(&config_url, cfg, "submodule.testrepo.url"));
+	cl_assert_equal_s(absolute_url.ptr, config_url);
+
+	git_buf_free(&absolute_url);
+	git_config_free(cfg);
+	git_object_free(head_commit);
+	git_reference_free(head_ref);
+	git_submodule_free(sm);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/lookup.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/lookup.c
new file mode 100755
index 0000000..ecea694
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/lookup.c
@@ -0,0 +1,335 @@
+#include "clar_libgit2.h"
+#include "submodule_helpers.h"
+#include "git2/sys/repository.h"
+#include "repository.h"
+#include "fileops.h"
+
+static git_repository *g_repo = NULL;
+
+void test_submodule_lookup__initialize(void)
+{
+	g_repo = setup_fixture_submod2();
+}
+
+void test_submodule_lookup__simple_lookup(void)
+{
+	assert_submodule_exists(g_repo, "sm_unchanged");
+
+	/* lookup pending change in .gitmodules that is not in HEAD */
+	assert_submodule_exists(g_repo, "sm_added_and_uncommited");
+
+	/* lookup pending change in .gitmodules that is not in HEAD nor index */
+	assert_submodule_exists(g_repo, "sm_gitmodules_only");
+
+	/* lookup git repo subdir that is not added as submodule */
+	refute_submodule_exists(g_repo, "not-submodule", GIT_EEXISTS);
+
+	/* lookup existing directory that is not a submodule */
+	refute_submodule_exists(g_repo, "just_a_dir", GIT_ENOTFOUND);
+
+	/* lookup existing file that is not a submodule */
+	refute_submodule_exists(g_repo, "just_a_file", GIT_ENOTFOUND);
+
+	/* lookup non-existent item */
+	refute_submodule_exists(g_repo, "no_such_file", GIT_ENOTFOUND);
+
+	/* lookup a submodule by path with a trailing slash */
+	assert_submodule_exists(g_repo, "sm_added_and_uncommited/");
+}
+
+void test_submodule_lookup__accessors(void)
+{
+	git_submodule *sm;
+	const char *oid = "480095882d281ed676fe5b863569520e54a7d5c0";
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_unchanged"));
+	cl_assert(git_submodule_owner(sm) == g_repo);
+	cl_assert_equal_s("sm_unchanged", git_submodule_name(sm));
+	cl_assert(git__suffixcmp(git_submodule_path(sm), "sm_unchanged") == 0);
+	cl_assert(git__suffixcmp(git_submodule_url(sm), "/submod2_target") == 0);
+
+	cl_assert(git_oid_streq(git_submodule_index_id(sm), oid) == 0);
+	cl_assert(git_oid_streq(git_submodule_head_id(sm), oid) == 0);
+	cl_assert(git_oid_streq(git_submodule_wd_id(sm), oid) == 0);
+
+	cl_assert(git_submodule_ignore(sm) == GIT_SUBMODULE_IGNORE_NONE);
+	cl_assert(git_submodule_update_strategy(sm) == GIT_SUBMODULE_UPDATE_CHECKOUT);
+
+	git_submodule_free(sm);
+
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+	cl_assert_equal_s("sm_changed_head", git_submodule_name(sm));
+
+	cl_assert(git_oid_streq(git_submodule_index_id(sm), oid) == 0);
+	cl_assert(git_oid_streq(git_submodule_head_id(sm), oid) == 0);
+	cl_assert(git_oid_streq(git_submodule_wd_id(sm),
+		"3d9386c507f6b093471a3e324085657a3c2b4247") == 0);
+
+	git_submodule_free(sm);
+
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_added_and_uncommited"));
+	cl_assert_equal_s("sm_added_and_uncommited", git_submodule_name(sm));
+
+	cl_assert(git_oid_streq(git_submodule_index_id(sm), oid) == 0);
+	cl_assert(git_submodule_head_id(sm) == NULL);
+	cl_assert(git_oid_streq(git_submodule_wd_id(sm), oid) == 0);
+
+	git_submodule_free(sm);
+
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_missing_commits"));
+	cl_assert_equal_s("sm_missing_commits", git_submodule_name(sm));
+
+	cl_assert(git_oid_streq(git_submodule_index_id(sm), oid) == 0);
+	cl_assert(git_oid_streq(git_submodule_head_id(sm), oid) == 0);
+	cl_assert(git_oid_streq(git_submodule_wd_id(sm),
+		"5e4963595a9774b90524d35a807169049de8ccad") == 0);
+
+	git_submodule_free(sm);
+}
+
+typedef struct {
+	int count;
+} sm_lookup_data;
+
+static int sm_lookup_cb(git_submodule *sm, const char *name, void *payload)
+{
+	sm_lookup_data *data = payload;
+	data->count += 1;
+	cl_assert_equal_s(git_submodule_name(sm), name);
+	return 0;
+}
+
+void test_submodule_lookup__foreach(void)
+{
+	git_config *cfg;
+	sm_lookup_data data;
+
+	memset(&data, 0, sizeof(data));
+	cl_git_pass(git_submodule_foreach(g_repo, sm_lookup_cb, &data));
+	cl_assert_equal_i(8, data.count);
+
+	memset(&data, 0, sizeof(data));
+
+	/* Change the path for a submodule so it doesn't match the name */
+	cl_git_pass(git_config_open_ondisk(&cfg, "submod2/.gitmodules"));
+
+	cl_git_pass(git_config_set_string(cfg, "submodule.smchangedindex.path", "sm_changed_index"));
+	cl_git_pass(git_config_set_string(cfg, "submodule.smchangedindex.url", "../submod2_target"));
+	cl_git_pass(git_config_delete_entry(cfg, "submodule.sm_changed_index.path"));
+	cl_git_pass(git_config_delete_entry(cfg, "submodule.sm_changed_index.url"));
+
+	git_config_free(cfg);
+
+	cl_git_pass(git_submodule_foreach(g_repo, sm_lookup_cb, &data));
+	cl_assert_equal_i(8, data.count);
+}
+
+void test_submodule_lookup__lookup_even_with_unborn_head(void)
+{
+	git_reference *head;
+
+	/* put us on an unborn branch */
+	cl_git_pass(git_reference_symbolic_create(
+		&head, g_repo, "HEAD", "refs/heads/garbage", 1, NULL));
+	git_reference_free(head);
+
+	test_submodule_lookup__simple_lookup(); /* baseline should still pass */
+}
+
+void test_submodule_lookup__lookup_even_with_missing_index(void)
+{
+	git_index *idx;
+
+	/* give the repo an empty index */
+	cl_git_pass(git_index_new(&idx));
+	git_repository_set_index(g_repo, idx);
+	git_index_free(idx);
+
+	test_submodule_lookup__simple_lookup(); /* baseline should still pass */
+}
+
+void test_submodule_lookup__backslashes(void)
+{
+	git_config *cfg;
+	git_submodule *sm;
+	git_repository *subrepo;
+	git_buf buf = GIT_BUF_INIT;
+	const char *backslashed_path = "..\\submod2_target";
+
+	cl_git_pass(git_config_open_ondisk(&cfg, "submod2/.gitmodules"));
+	cl_git_pass(git_config_set_string(cfg, "submodule.sm_unchanged.url", backslashed_path));
+	git_config_free(cfg);
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_unchanged"));
+	cl_assert_equal_s(backslashed_path, git_submodule_url(sm));
+	cl_git_pass(git_submodule_open(&subrepo, sm));
+
+	cl_git_pass(git_submodule_resolve_url(&buf, g_repo, backslashed_path));
+
+	git_buf_free(&buf);
+	git_submodule_free(sm);
+	git_repository_free(subrepo);
+}
+
+static void baseline_tests(void)
+{
+	/* small baseline that should work even if we change the index or make
+	 * commits from the index
+	 */
+	assert_submodule_exists(g_repo, "sm_unchanged");
+	assert_submodule_exists(g_repo, "sm_gitmodules_only");
+	refute_submodule_exists(g_repo, "not-submodule", GIT_EEXISTS);
+}
+
+static void add_submodule_with_commit(const char *name)
+{
+	git_submodule *sm;
+	git_repository *smrepo;
+	git_index *idx;
+	git_buf p = GIT_BUF_INIT;
+
+	cl_git_pass(git_submodule_add_setup(&sm, g_repo,
+		"https://github.com/libgit2/libgit2.git", name, 1));
+
+	assert_submodule_exists(g_repo, name);
+
+	cl_git_pass(git_submodule_open(&smrepo, sm));
+	cl_git_pass(git_repository_index(&idx, smrepo));
+
+	cl_git_pass(git_buf_joinpath(&p, git_repository_workdir(smrepo), "file"));
+	cl_git_mkfile(p.ptr, "new file");
+	git_buf_free(&p);
+
+	cl_git_pass(git_index_add_bypath(idx, "file"));
+	cl_git_pass(git_index_write(idx));
+	git_index_free(idx);
+
+	cl_repo_commit_from_index(NULL, smrepo, NULL, 0, "initial commit");
+	git_repository_free(smrepo);
+
+	cl_git_pass(git_submodule_add_finalize(sm));
+
+	git_submodule_free(sm);
+}
+
+void test_submodule_lookup__just_added(void)
+{
+	git_submodule *sm;
+	git_buf snap1 = GIT_BUF_INIT, snap2 = GIT_BUF_INIT;
+	git_reference *original_head = NULL;
+
+	refute_submodule_exists(g_repo, "sm_just_added", GIT_ENOTFOUND);
+	refute_submodule_exists(g_repo, "sm_just_added_2", GIT_ENOTFOUND);
+	refute_submodule_exists(g_repo, "sm_just_added_idx", GIT_ENOTFOUND);
+	refute_submodule_exists(g_repo, "sm_just_added_head", GIT_ENOTFOUND);
+	refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND);
+	refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND);
+	baseline_tests();
+
+	cl_git_pass(git_futils_readbuffer(&snap1, "submod2/.gitmodules"));
+	cl_git_pass(git_repository_head(&original_head, g_repo));
+
+	cl_git_pass(git_submodule_add_setup(&sm, g_repo,
+		"https://github.com/libgit2/libgit2.git", "sm_just_added", 1));
+	git_submodule_free(sm);
+	assert_submodule_exists(g_repo, "sm_just_added");
+
+	cl_git_pass(git_submodule_add_setup(&sm, g_repo,
+		"https://github.com/libgit2/libgit2.git", "sm_just_added_2", 1));
+	assert_submodule_exists(g_repo, "sm_just_added_2");
+	cl_git_fail(git_submodule_add_finalize(sm)); /* fails if no HEAD */
+	git_submodule_free(sm);
+
+	add_submodule_with_commit("sm_just_added_head");
+	cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "commit new sm to head");
+	assert_submodule_exists(g_repo, "sm_just_added_head");
+
+	add_submodule_with_commit("sm_just_added_idx");
+	assert_submodule_exists(g_repo, "sm_just_added_idx");
+
+	cl_git_pass(git_futils_readbuffer(&snap2, "submod2/.gitmodules"));
+
+	cl_git_append2file(
+		"submod2/.gitmodules",
+		"\n[submodule \"mismatch_name\"]\n"
+		"\tpath = mismatch_path\n"
+		"\turl = https://example.com/example.git\n\n");
+
+	assert_submodule_exists(g_repo, "mismatch_name");
+	assert_submodule_exists(g_repo, "mismatch_path");
+	assert_submodule_exists(g_repo, "sm_just_added");
+	assert_submodule_exists(g_repo, "sm_just_added_2");
+	assert_submodule_exists(g_repo, "sm_just_added_idx");
+	assert_submodule_exists(g_repo, "sm_just_added_head");
+	baseline_tests();
+
+	cl_git_rewritefile("submod2/.gitmodules", snap2.ptr);
+	git_buf_free(&snap2);
+
+	refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND);
+	refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND);
+	assert_submodule_exists(g_repo, "sm_just_added");
+	assert_submodule_exists(g_repo, "sm_just_added_2");
+	assert_submodule_exists(g_repo, "sm_just_added_idx");
+	assert_submodule_exists(g_repo, "sm_just_added_head");
+	baseline_tests();
+
+	cl_git_rewritefile("submod2/.gitmodules", snap1.ptr);
+	git_buf_free(&snap1);
+
+	refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND);
+	refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND);
+	/* note error code change, because add_setup made a repo in the workdir */
+	refute_submodule_exists(g_repo, "sm_just_added", GIT_EEXISTS);
+	refute_submodule_exists(g_repo, "sm_just_added_2", GIT_EEXISTS);
+	/* these still exist in index and head respectively */
+	assert_submodule_exists(g_repo, "sm_just_added_idx");
+	assert_submodule_exists(g_repo, "sm_just_added_head");
+	baseline_tests();
+
+	{
+		git_index *idx;
+		cl_git_pass(git_repository_index(&idx, g_repo));
+		cl_git_pass(git_index_remove_bypath(idx, "sm_just_added_idx"));
+		cl_git_pass(git_index_remove_bypath(idx, "sm_just_added_head"));
+		cl_git_pass(git_index_write(idx));
+		git_index_free(idx);
+	}
+
+	refute_submodule_exists(g_repo, "sm_just_added_idx", GIT_EEXISTS);
+	assert_submodule_exists(g_repo, "sm_just_added_head");
+
+	{
+		cl_git_pass(git_reference_create(NULL, g_repo, "refs/heads/master", git_reference_target(original_head), 1, "move head back"));
+		git_reference_free(original_head);
+	}
+
+	refute_submodule_exists(g_repo, "sm_just_added_head", GIT_EEXISTS);
+}
+
+/* Test_App and Test_App2 are fairly similar names, make sure we load the right one */
+void test_submodule_lookup__prefix_name(void)
+{
+	git_submodule *sm;
+
+	cl_git_rewritefile("submod2/.gitmodules",
+			   "[submodule \"Test_App\"]\n"
+			   "    path = Test_App\n"
+			   "    url = ../Test_App\n"
+			   "[submodule \"Test_App2\"]\n"
+			   "    path = Test_App2\n"
+			   "    url = ../Test_App\n");
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "Test_App"));
+	cl_assert_equal_s("Test_App", git_submodule_name(sm));
+
+	git_submodule_free(sm);
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "Test_App2"));
+	cl_assert_equal_s("Test_App2", git_submodule_name(sm));
+
+	git_submodule_free(sm);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/modify.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/modify.c
new file mode 100755
index 0000000..f7a089e
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/modify.c
@@ -0,0 +1,212 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "path.h"
+#include "submodule_helpers.h"
+#include "config/config_helpers.h"
+
+static git_repository *g_repo = NULL;
+
+#define SM_LIBGIT2_URL    "https://github.com/libgit2/libgit2.git"
+#define SM_LIBGIT2_BRANCH "github-branch"
+#define SM_LIBGIT2        "sm_libgit2"
+
+void test_submodule_modify__initialize(void)
+{
+	g_repo = setup_fixture_submod2();
+}
+
+static int delete_one_config(const git_config_entry *entry, void *payload)
+{
+	git_config *cfg = payload;
+	return git_config_delete_entry(cfg, entry->name);
+}
+
+static int init_one_submodule(
+	git_submodule *sm, const char *name, void *payload)
+{
+	GIT_UNUSED(name);
+	GIT_UNUSED(payload);
+	return git_submodule_init(sm, false);
+}
+
+void test_submodule_modify__init(void)
+{
+	git_config *cfg;
+	const char *str;
+
+	/* erase submodule data from .git/config */
+	cl_git_pass(git_repository_config(&cfg, g_repo));
+	cl_git_pass(
+		git_config_foreach_match(cfg, "submodule\\..*", delete_one_config, cfg));
+	git_config_free(cfg);
+
+	/* confirm no submodule data in config */
+	cl_git_pass(git_repository_config_snapshot(&cfg, g_repo));
+	cl_git_fail_with(GIT_ENOTFOUND, git_config_get_string(&str, cfg, "submodule.sm_unchanged.url"));
+	cl_git_fail_with(GIT_ENOTFOUND, git_config_get_string(&str, cfg, "submodule.sm_changed_head.url"));
+	cl_git_fail_with(GIT_ENOTFOUND, git_config_get_string(&str, cfg, "submodule.sm_added_and_uncommited.url"));
+	git_config_free(cfg);
+
+	/* call init and see that settings are copied */
+	cl_git_pass(git_submodule_foreach(g_repo, init_one_submodule, NULL));
+
+	/* confirm submodule data in config */
+	cl_git_pass(git_repository_config_snapshot(&cfg, g_repo));
+	cl_git_pass(git_config_get_string(&str, cfg, "submodule.sm_unchanged.url"));
+	cl_assert(git__suffixcmp(str, "/submod2_target") == 0);
+	cl_git_pass(git_config_get_string(&str, cfg, "submodule.sm_changed_head.url"));
+	cl_assert(git__suffixcmp(str, "/submod2_target") == 0);
+	cl_git_pass(git_config_get_string(&str, cfg, "submodule.sm_added_and_uncommited.url"));
+	cl_assert(git__suffixcmp(str, "/submod2_target") == 0);
+	git_config_free(cfg);
+}
+
+static int sync_one_submodule(
+	git_submodule *sm, const char *name, void *payload)
+{
+	GIT_UNUSED(name);
+	GIT_UNUSED(payload);
+	return git_submodule_sync(sm);
+}
+
+static void assert_submodule_url_is_synced(
+	git_submodule *sm, const char *parent_key, const char *child_key)
+{
+	git_repository *smrepo;
+
+	assert_config_entry_value(g_repo, parent_key, git_submodule_url(sm));
+
+	cl_git_pass(git_submodule_open(&smrepo, sm));
+	assert_config_entry_value(smrepo, child_key,  git_submodule_url(sm));
+	git_repository_free(smrepo);
+}
+
+void test_submodule_modify__sync(void)
+{
+	git_submodule *sm1, *sm2, *sm3;
+	git_config *cfg;
+	const char *str;
+
+#define SM1 "sm_unchanged"
+#define SM2 "sm_changed_head"
+#define SM3 "sm_added_and_uncommited"
+
+	/* look up some submodules */
+	cl_git_pass(git_submodule_lookup(&sm1, g_repo, SM1));
+	cl_git_pass(git_submodule_lookup(&sm2, g_repo, SM2));
+	cl_git_pass(git_submodule_lookup(&sm3, g_repo, SM3));
+
+	/* At this point, the .git/config URLs for the submodules have
+	 * not be rewritten with the absolute paths (although the
+	 * .gitmodules have.  Let's confirm that they DO NOT match
+	 * yet, then we can do a sync to make them match...
+	 */
+
+	/* check submodule info does not match before sync */
+	cl_git_pass(git_repository_config_snapshot(&cfg, g_repo));
+	cl_git_pass(git_config_get_string(&str, cfg, "submodule."SM1".url"));
+	cl_assert(strcmp(git_submodule_url(sm1), str) != 0);
+	cl_git_pass(git_config_get_string(&str, cfg, "submodule."SM2".url"));
+	cl_assert(strcmp(git_submodule_url(sm2), str) != 0);
+	cl_git_pass(git_config_get_string(&str, cfg, "submodule."SM3".url"));
+	cl_assert(strcmp(git_submodule_url(sm3), str) != 0);
+	git_config_free(cfg);
+
+	/* sync all the submodules */
+	cl_git_pass(git_submodule_foreach(g_repo, sync_one_submodule, NULL));
+
+	/* check that submodule config is updated */
+	assert_submodule_url_is_synced(
+		sm1, "submodule."SM1".url", "remote.origin.url");
+	assert_submodule_url_is_synced(
+		sm2, "submodule."SM2".url", "remote.origin.url");
+	assert_submodule_url_is_synced(
+		sm3, "submodule."SM3".url", "remote.origin.url");
+
+	git_submodule_free(sm1);
+	git_submodule_free(sm2);
+	git_submodule_free(sm3);
+}
+
+void assert_ignore_change(git_submodule_ignore_t ignore)
+{
+	git_submodule *sm;
+
+	cl_git_pass(git_submodule_set_ignore(g_repo, "sm_changed_head", ignore));
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+	cl_assert_equal_i(ignore, git_submodule_ignore(sm));
+	git_submodule_free(sm);
+}
+
+void test_submodule_modify__set_ignore(void)
+{
+	assert_ignore_change(GIT_SUBMODULE_IGNORE_UNTRACKED);
+	assert_ignore_change(GIT_SUBMODULE_IGNORE_NONE);
+	assert_ignore_change(GIT_SUBMODULE_IGNORE_ALL);
+}
+
+void assert_update_change(git_submodule_update_t update)
+{
+	git_submodule *sm;
+
+	cl_git_pass(git_submodule_set_update(g_repo, "sm_changed_head", update));
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+	cl_assert_equal_i(update, git_submodule_update_strategy(sm));
+	git_submodule_free(sm);
+}
+
+void test_submodule_modify__set_update(void)
+{
+	assert_update_change(GIT_SUBMODULE_UPDATE_REBASE);
+	assert_update_change(GIT_SUBMODULE_UPDATE_NONE);
+	assert_update_change(GIT_SUBMODULE_UPDATE_CHECKOUT);
+}
+
+void assert_recurse_change(git_submodule_recurse_t recurse)
+{
+	git_submodule *sm;
+
+	cl_git_pass(git_submodule_set_fetch_recurse_submodules(g_repo, "sm_changed_head", recurse));
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+	cl_assert_equal_i(recurse, git_submodule_fetch_recurse_submodules(sm));
+	git_submodule_free(sm);
+}
+
+void test_submodule_modify__set_fetch_recurse_submodules(void)
+{
+	assert_recurse_change(GIT_SUBMODULE_RECURSE_YES);
+	assert_recurse_change(GIT_SUBMODULE_RECURSE_NO);
+	assert_recurse_change(GIT_SUBMODULE_RECURSE_ONDEMAND);
+}
+
+void test_submodule_modify__set_branch(void)
+{
+	git_submodule *sm;
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+	cl_assert(git_submodule_branch(sm) == NULL);
+	git_submodule_free(sm);
+
+	cl_git_pass(git_submodule_set_branch(g_repo, "sm_changed_head", SM_LIBGIT2_BRANCH));
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+	cl_assert_equal_s(SM_LIBGIT2_BRANCH, git_submodule_branch(sm));
+	git_submodule_free(sm);
+
+	cl_git_pass(git_submodule_set_branch(g_repo, "sm_changed_head", NULL));
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+	cl_assert(git_submodule_branch(sm) == NULL);
+	git_submodule_free(sm);
+}
+
+void test_submodule_modify__set_url(void)
+{
+	git_submodule *sm;
+
+	cl_git_pass(git_submodule_set_url(g_repo, "sm_changed_head", SM_LIBGIT2_URL));
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+	cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm));
+	git_submodule_free(sm);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/nosubs.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/nosubs.c
new file mode 100755
index 0000000..8a73dc1
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/nosubs.c
@@ -0,0 +1,130 @@
+/* test the submodule APIs on repositories where there are no submodules */
+
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "fileops.h"
+
+void test_submodule_nosubs__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_submodule_nosubs__lookup(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_submodule *sm = NULL;
+
+	p_mkdir("status/subrepo", 0777);
+	cl_git_mkfile("status/subrepo/.git", "gitdir: ../.git");
+
+	cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(&sm, repo, "subdir"));
+
+	cl_assert_equal_i(GIT_EEXISTS, git_submodule_lookup(&sm, repo, "subrepo"));
+
+	cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(&sm, repo, "subdir"));
+
+	cl_assert_equal_i(GIT_EEXISTS, git_submodule_lookup(&sm, repo, "subrepo"));
+}
+
+static int fake_submod_cb(git_submodule *sm, const char *n, void *p)
+{
+	GIT_UNUSED(sm); GIT_UNUSED(n); GIT_UNUSED(p);
+	return 0;
+}
+
+void test_submodule_nosubs__foreach(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	cl_git_pass(git_submodule_foreach(repo, fake_submod_cb, NULL));
+}
+
+void test_submodule_nosubs__add(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_submodule *sm, *sm2;
+
+	cl_git_pass(git_submodule_add_setup(&sm, repo, "https://github.com/libgit2/libgit2.git", "submodules/libgit2", 1));
+
+	cl_git_pass(git_submodule_lookup(&sm2, repo, "submodules/libgit2"));
+	git_submodule_free(sm2);
+
+	cl_git_pass(git_submodule_foreach(repo, fake_submod_cb, NULL));
+
+	git_submodule_free(sm);
+}
+
+void test_submodule_nosubs__bad_gitmodules(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+
+	cl_git_mkfile("status/.gitmodules", "[submodule \"foobar\"]\tpath=blargle\n\turl=\n\tbranch=\n\tupdate=flooble\n\n");
+
+	cl_git_rewritefile("status/.gitmodules", "[submodule \"foobar\"]\tpath=blargle\n\turl=\n\tbranch=\n\tupdate=rebase\n\n");
+
+	cl_git_pass(git_submodule_lookup(NULL, repo, "foobar"));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(NULL, repo, "subdir"));
+}
+
+void test_submodule_nosubs__add_and_delete(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_submodule *sm;
+	git_buf buf = GIT_BUF_INIT;
+
+	cl_git_fail(git_submodule_lookup(NULL, repo, "libgit2"));
+	cl_git_fail(git_submodule_lookup(NULL, repo, "submodules/libgit2"));
+
+	/* create */
+
+	cl_git_pass(git_submodule_add_setup(
+		&sm, repo, "https://github.com/libgit2/libgit2.git", "submodules/libgit2", 1));
+	cl_assert_equal_s("submodules/libgit2", git_submodule_name(sm));
+	cl_assert_equal_s("submodules/libgit2", git_submodule_path(sm));
+	git_submodule_free(sm);
+
+	cl_git_pass(git_futils_readbuffer(&buf, "status/.gitmodules"));
+	cl_assert(strstr(buf.ptr, "[submodule \"submodules/libgit2\"]") != NULL);
+	cl_assert(strstr(buf.ptr, "path = submodules/libgit2") != NULL);
+	git_buf_free(&buf);
+
+	/* lookup */
+
+	cl_git_fail(git_submodule_lookup(&sm, repo, "libgit2"));
+	cl_git_pass(git_submodule_lookup(&sm, repo, "submodules/libgit2"));
+	cl_assert_equal_s("submodules/libgit2", git_submodule_name(sm));
+	cl_assert_equal_s("submodules/libgit2", git_submodule_path(sm));
+	git_submodule_free(sm);
+
+	/* update name */
+
+	cl_git_rewritefile(
+		"status/.gitmodules",
+		"[submodule \"libgit2\"]\n"
+		"  path = submodules/libgit2\n"
+		"  url = https://github.com/libgit2/libgit2.git\n");
+
+	cl_git_pass(git_submodule_lookup(&sm, repo, "libgit2"));
+	cl_assert_equal_s("libgit2", git_submodule_name(sm));
+	cl_assert_equal_s("submodules/libgit2", git_submodule_path(sm));
+	git_submodule_free(sm);
+	cl_git_pass(git_submodule_lookup(&sm, repo, "submodules/libgit2"));
+	git_submodule_free(sm);
+
+	/* revert name update */
+
+	cl_git_rewritefile(
+		"status/.gitmodules",
+		"[submodule \"submodules/libgit2\"]\n"
+		"  path = submodules/libgit2\n"
+		"  url = https://github.com/libgit2/libgit2.git\n");
+
+	cl_git_fail(git_submodule_lookup(&sm, repo, "libgit2"));
+	cl_git_pass(git_submodule_lookup(&sm, repo, "submodules/libgit2"));
+	git_submodule_free(sm);
+
+	/* remove completely */
+
+	cl_must_pass(p_unlink("status/.gitmodules"));
+	cl_git_fail(git_submodule_lookup(&sm, repo, "libgit2"));
+	cl_git_fail(git_submodule_lookup(&sm, repo, "submodules/libgit2"));
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/repository_init.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/repository_init.c
new file mode 100755
index 0000000..9be1e0b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/repository_init.c
@@ -0,0 +1,38 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "path.h"
+#include "submodule_helpers.h"
+#include "config/config_helpers.h"
+#include "fileops.h"
+
+static git_repository *g_repo = NULL;
+
+void test_submodule_repository_init__basic(void)
+{
+	git_submodule *sm;
+	git_repository *repo;
+	git_buf dot_git_content = GIT_BUF_INIT;
+
+	g_repo = setup_fixture_submod2();
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_gitmodules_only"));
+	cl_git_pass(git_submodule_init(sm, 0));
+	cl_git_pass(git_submodule_repo_init(&repo, sm, 1));
+
+	/* Verify worktree */
+	assert_config_entry_value(repo, "core.worktree", "../../../sm_gitmodules_only/");
+
+	/* Verify gitlink */
+	cl_git_pass(git_futils_readbuffer(&dot_git_content, "submod2/" "sm_gitmodules_only" "/.git"));
+	cl_assert_equal_s("gitdir: ../.git/modules/sm_gitmodules_only/", dot_git_content.ptr);
+
+	cl_assert(git_path_isfile("submod2/" "sm_gitmodules_only" "/.git"));
+
+	cl_assert(git_path_isdir("submod2/.git/modules"));
+	cl_assert(git_path_isdir("submod2/.git/modules/" "sm_gitmodules_only"));
+	cl_assert(git_path_isfile("submod2/.git/modules/" "sm_gitmodules_only" "/HEAD"));
+
+	git_submodule_free(sm);
+	git_repository_free(repo);
+	git_buf_free(&dot_git_content);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/status.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/status.c
new file mode 100755
index 0000000..6721ee9
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/status.c
@@ -0,0 +1,352 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "path.h"
+#include "submodule_helpers.h"
+#include "fileops.h"
+#include "iterator.h"
+
+static git_repository *g_repo = NULL;
+
+void test_submodule_status__initialize(void)
+{
+	g_repo = setup_fixture_submod2();
+}
+
+void test_submodule_status__cleanup(void)
+{
+}
+
+void test_submodule_status__unchanged(void)
+{
+	unsigned int status = get_submodule_status(g_repo, "sm_unchanged");
+	unsigned int expected =
+		GIT_SUBMODULE_STATUS_IN_HEAD |
+		GIT_SUBMODULE_STATUS_IN_INDEX |
+		GIT_SUBMODULE_STATUS_IN_CONFIG |
+		GIT_SUBMODULE_STATUS_IN_WD;
+
+	cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
+	cl_assert(expected == status);
+}
+
+static void rm_submodule(const char *name)
+{
+	git_buf path = GIT_BUF_INIT;
+	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), name));
+	cl_git_pass(git_futils_rmdir_r(path.ptr, NULL, GIT_RMDIR_REMOVE_FILES));
+	git_buf_free(&path);
+}
+
+static void add_submodule_to_index(const char *name)
+{
+	git_submodule *sm;
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, name));
+	cl_git_pass(git_submodule_add_to_index(sm, true));
+	git_submodule_free(sm);
+}
+
+static void rm_submodule_from_index(const char *name)
+{
+	git_index *index;
+	size_t pos;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_assert(!git_index_find(&pos, index, name));
+	cl_git_pass(git_index_remove(index, name, 0));
+	cl_git_pass(git_index_write(index));
+	git_index_free(index);
+}
+
+/* 4 values of GIT_SUBMODULE_IGNORE to check */
+
+void test_submodule_status__ignore_none(void)
+{
+	unsigned int status;
+
+	rm_submodule("sm_unchanged");
+
+	refute_submodule_exists(g_repo, "just_a_dir", GIT_ENOTFOUND);
+	refute_submodule_exists(g_repo, "not-submodule", GIT_EEXISTS);
+	refute_submodule_exists(g_repo, "not", GIT_EEXISTS);
+
+	status = get_submodule_status(g_repo, "sm_changed_index");
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED) != 0);
+
+	status = get_submodule_status(g_repo, "sm_changed_head");
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_MODIFIED) != 0);
+
+	status = get_submodule_status(g_repo, "sm_changed_file");
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_WD_MODIFIED) != 0);
+
+	status = get_submodule_status(g_repo, "sm_changed_untracked_file");
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_UNTRACKED) != 0);
+
+	status = get_submodule_status(g_repo, "sm_missing_commits");
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_MODIFIED) != 0);
+
+	status = get_submodule_status(g_repo, "sm_added_and_uncommited");
+	cl_assert((status & GIT_SUBMODULE_STATUS_INDEX_ADDED) != 0);
+
+	/* removed sm_unchanged for deleted workdir */
+	status = get_submodule_status(g_repo, "sm_unchanged");
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_DELETED) != 0);
+
+	/* now mkdir sm_unchanged to test uninitialized */
+	cl_git_pass(git_futils_mkdir("sm_unchanged", "submod2", 0755, 0));
+	status = get_submodule_status(g_repo, "sm_unchanged");
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_UNINITIALIZED) != 0);
+
+	/* update sm_changed_head in index */
+	add_submodule_to_index("sm_changed_head");
+	status = get_submodule_status(g_repo, "sm_changed_head");
+	cl_assert((status & GIT_SUBMODULE_STATUS_INDEX_MODIFIED) != 0);
+
+	/* remove sm_changed_head from index */
+	rm_submodule_from_index("sm_changed_head");
+	status = get_submodule_status(g_repo, "sm_changed_head");
+	cl_assert((status & GIT_SUBMODULE_STATUS_INDEX_DELETED) != 0);
+}
+
+void test_submodule_status__ignore_untracked(void)
+{
+	unsigned int status;
+	git_submodule_ignore_t ign = GIT_SUBMODULE_IGNORE_UNTRACKED;
+
+	rm_submodule("sm_unchanged");
+
+	refute_submodule_exists(g_repo, "just_a_dir", GIT_ENOTFOUND);
+	refute_submodule_exists(g_repo, "not-submodule", GIT_EEXISTS);
+	refute_submodule_exists(g_repo, "not", GIT_EEXISTS);
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_index", ign));
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED) != 0);
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_head", ign));
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_MODIFIED) != 0);
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_file", ign));
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_WD_MODIFIED) != 0);
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_untracked_file", ign));
+	cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_missing_commits", ign));
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_MODIFIED) != 0);
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_added_and_uncommited", ign));
+	cl_assert((status & GIT_SUBMODULE_STATUS_INDEX_ADDED) != 0);
+
+	/* removed sm_unchanged for deleted workdir */
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_unchanged", ign));
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_DELETED) != 0);
+
+	/* now mkdir sm_unchanged to test uninitialized */
+	cl_git_pass(git_futils_mkdir("sm_unchanged", "submod2", 0755, 0));
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_unchanged", ign));
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_UNINITIALIZED) != 0);
+
+	/* update sm_changed_head in index */
+	add_submodule_to_index("sm_changed_head");
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_head", ign));
+	cl_assert((status & GIT_SUBMODULE_STATUS_INDEX_MODIFIED) != 0);
+}
+
+void test_submodule_status__ignore_dirty(void)
+{
+	unsigned int status;
+	git_submodule_ignore_t ign = GIT_SUBMODULE_IGNORE_DIRTY;
+
+	rm_submodule("sm_unchanged");
+
+	refute_submodule_exists(g_repo, "just_a_dir", GIT_ENOTFOUND);
+	refute_submodule_exists(g_repo, "not-submodule", GIT_EEXISTS);
+	refute_submodule_exists(g_repo, "not", GIT_EEXISTS);
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_index", ign));
+	cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_head", ign));
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_MODIFIED) != 0);
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_file", ign));
+	cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_untracked_file", ign));
+	cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_missing_commits", ign));
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_MODIFIED) != 0);
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_added_and_uncommited", ign));
+	cl_assert((status & GIT_SUBMODULE_STATUS_INDEX_ADDED) != 0);
+
+	/* removed sm_unchanged for deleted workdir */
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_unchanged", ign));
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_DELETED) != 0);
+
+	/* now mkdir sm_unchanged to test uninitialized */
+	cl_git_pass(git_futils_mkdir("sm_unchanged", "submod2", 0755, 0));
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_unchanged", ign));
+	cl_assert((status & GIT_SUBMODULE_STATUS_WD_UNINITIALIZED) != 0);
+
+	/* update sm_changed_head in index */
+	add_submodule_to_index("sm_changed_head");
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_head", ign));
+	cl_assert((status & GIT_SUBMODULE_STATUS_INDEX_MODIFIED) != 0);
+}
+
+void test_submodule_status__ignore_all(void)
+{
+	unsigned int status;
+	git_submodule_ignore_t ign = GIT_SUBMODULE_IGNORE_ALL;
+
+	rm_submodule("sm_unchanged");
+
+	refute_submodule_exists(g_repo, "just_a_dir", GIT_ENOTFOUND);
+	refute_submodule_exists(g_repo, "not-submodule", GIT_EEXISTS);
+	refute_submodule_exists(g_repo, "not", GIT_EEXISTS);
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_index", ign));
+	cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_head", ign));
+	cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_file", ign));
+	cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_untracked_file", ign));
+	cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_missing_commits", ign));
+	cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
+
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_added_and_uncommited", ign));
+	cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
+
+	/* removed sm_unchanged for deleted workdir */
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_unchanged", ign));
+	cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
+
+	/* now mkdir sm_unchanged to test uninitialized */
+	cl_git_pass(git_futils_mkdir("sm_unchanged", "submod2", 0755, 0));
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_unchanged", ign));
+	cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
+
+	/* update sm_changed_head in index */
+	add_submodule_to_index("sm_changed_head");
+	cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_head", ign));
+	cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
+}
+
+typedef struct {
+	size_t counter;
+	const char **paths;
+	int *statuses;
+} submodule_expectations;
+
+static int confirm_submodule_status(
+	const char *path, unsigned int status_flags, void *payload)
+{
+	submodule_expectations *exp = payload;
+
+	while (exp->statuses[exp->counter] < 0)
+		exp->counter++;
+
+	cl_assert_equal_i(exp->statuses[exp->counter], (int)status_flags);
+	cl_assert_equal_s(exp->paths[exp->counter++], path);
+
+	GIT_UNUSED(status_flags);
+
+	return 0;
+}
+
+void test_submodule_status__iterator(void)
+{
+	git_iterator *iter;
+	const git_index_entry *entry;
+	size_t i;
+	static const char *expected[] = {
+		".gitmodules",
+		"just_a_dir/",
+		"just_a_dir/contents",
+		"just_a_file",
+		"not-submodule/",
+		"not-submodule/README.txt",
+		"not/",
+		"not/README.txt",
+		"README.txt",
+		"sm_added_and_uncommited",
+		"sm_changed_file",
+		"sm_changed_head",
+		"sm_changed_index",
+		"sm_changed_untracked_file",
+		"sm_missing_commits",
+		"sm_unchanged",
+		NULL
+	};
+	static int expected_flags[] = {
+		GIT_STATUS_INDEX_MODIFIED | GIT_STATUS_WT_MODIFIED, /* ".gitmodules" */
+		-1,					    /* "just_a_dir/" will be skipped */
+		GIT_STATUS_CURRENT,     /* "just_a_dir/contents" */
+		GIT_STATUS_CURRENT,	    /* "just_a_file" */
+		GIT_STATUS_WT_NEW,      /* "not-submodule/" untracked item */
+		-1,                     /* "not-submodule/README.txt" */
+		GIT_STATUS_WT_NEW,      /* "not/" untracked item */
+		-1,                     /* "not/README.txt" */
+		GIT_STATUS_CURRENT,     /* "README.txt */
+		GIT_STATUS_INDEX_NEW,   /* "sm_added_and_uncommited" */
+		GIT_STATUS_WT_MODIFIED, /* "sm_changed_file" */
+		GIT_STATUS_WT_MODIFIED, /* "sm_changed_head" */
+		GIT_STATUS_WT_MODIFIED, /* "sm_changed_index" */
+		GIT_STATUS_WT_MODIFIED, /* "sm_changed_untracked_file" */
+		GIT_STATUS_WT_MODIFIED, /* "sm_missing_commits" */
+		GIT_STATUS_CURRENT,     /* "sm_unchanged" */
+		0
+	};
+	submodule_expectations exp = { 0, expected, expected_flags };
+	git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+	git_index *index;
+
+	cl_git_pass(git_repository_index(&index, g_repo));
+	cl_git_pass(git_iterator_for_workdir(&iter, g_repo, index, NULL,
+		GIT_ITERATOR_IGNORE_CASE | GIT_ITERATOR_INCLUDE_TREES, NULL, NULL));
+
+	for (i = 0; !git_iterator_advance(&entry, iter); ++i)
+		cl_assert_equal_s(expected[i], entry->path);
+
+	git_iterator_free(iter);
+	git_index_free(index);
+
+	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
+		GIT_STATUS_OPT_INCLUDE_UNMODIFIED |
+		GIT_STATUS_OPT_INCLUDE_IGNORED |
+		GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS |
+		GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY;
+
+	cl_git_pass(git_status_foreach_ext(
+		g_repo, &opts, confirm_submodule_status, &exp));
+}
+
+void test_submodule_status__untracked_dirs_containing_ignored_files(void)
+{
+	unsigned int status, expected;
+
+	cl_git_append2file(
+		"submod2/.git/modules/sm_unchanged/info/exclude", "\n*.ignored\n");
+
+	cl_git_pass(
+		git_futils_mkdir("sm_unchanged/directory", "submod2", 0755, 0));
+	cl_git_mkfile(
+		"submod2/sm_unchanged/directory/i_am.ignored",
+		"ignore this file, please\n");
+
+	status = get_submodule_status(g_repo, "sm_unchanged");
+	cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
+
+	expected = GIT_SUBMODULE_STATUS_IN_HEAD |
+		GIT_SUBMODULE_STATUS_IN_INDEX |
+		GIT_SUBMODULE_STATUS_IN_CONFIG |
+		GIT_SUBMODULE_STATUS_IN_WD;
+	cl_assert(status == expected);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/submodule_helpers.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/submodule_helpers.c
new file mode 100755
index 0000000..1dc6872
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/submodule_helpers.c
@@ -0,0 +1,189 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "path.h"
+#include "util.h"
+#include "posix.h"
+#include "submodule_helpers.h"
+#include "git2/sys/repository.h"
+
+/* rewrite gitmodules -> .gitmodules
+ * rewrite the empty or relative urls inside each module
+ * rename the .gitted directory inside any submodule to .git
+ */
+void rewrite_gitmodules(const char *workdir)
+{
+	git_buf in_f = GIT_BUF_INIT, out_f = GIT_BUF_INIT, path = GIT_BUF_INIT;
+	FILE *in, *out;
+	char line[256];
+
+	cl_git_pass(git_buf_joinpath(&in_f, workdir, "gitmodules"));
+	cl_git_pass(git_buf_joinpath(&out_f, workdir, ".gitmodules"));
+
+	cl_assert((in  = fopen(in_f.ptr, "rb")) != NULL);
+	cl_assert((out = fopen(out_f.ptr, "wb")) != NULL);
+
+	while (fgets(line, sizeof(line), in) != NULL) {
+		char *scan = line;
+
+		while (*scan == ' ' || *scan == '\t') scan++;
+
+		/* rename .gitted -> .git in submodule directories */
+		if (git__prefixcmp(scan, "path =") == 0) {
+			scan += strlen("path =");
+			while (*scan == ' ') scan++;
+
+			git_buf_joinpath(&path, workdir, scan);
+			git_buf_rtrim(&path);
+			git_buf_joinpath(&path, path.ptr, ".gitted");
+
+			if (!git_buf_oom(&path) && p_access(path.ptr, F_OK) == 0) {
+				git_buf_joinpath(&out_f, workdir, scan);
+				git_buf_rtrim(&out_f);
+				git_buf_joinpath(&out_f, out_f.ptr, ".git");
+
+				if (!git_buf_oom(&out_f))
+					p_rename(path.ptr, out_f.ptr);
+			}
+		}
+
+		/* copy non-"url =" lines verbatim */
+		if (git__prefixcmp(scan, "url =") != 0) {
+			fputs(line, out);
+			continue;
+		}
+
+		/* convert relative URLs in "url =" lines */
+		scan += strlen("url =");
+		while (*scan == ' ') scan++;
+
+		if (*scan == '.') {
+			git_buf_joinpath(&path, workdir, scan);
+			git_buf_rtrim(&path);
+		} else if (!*scan || *scan == '\n') {
+			git_buf_joinpath(&path, workdir, "../testrepo.git");
+		} else {
+			fputs(line, out);
+			continue;
+		}
+
+		git_path_prettify(&path, path.ptr, NULL);
+		git_buf_putc(&path, '\n');
+		cl_assert(!git_buf_oom(&path));
+
+		fwrite(line, scan - line, sizeof(char), out);
+		fputs(path.ptr, out);
+	}
+
+	fclose(in);
+	fclose(out);
+
+	cl_must_pass(p_unlink(in_f.ptr));
+
+	git_buf_free(&in_f);
+	git_buf_free(&out_f);
+	git_buf_free(&path);
+}
+
+static void cleanup_fixture_submodules(void *payload)
+{
+	cl_git_sandbox_cleanup(); /* either "submodules" or "submod2" */
+
+	if (payload)
+		cl_fixture_cleanup(payload);
+}
+
+git_repository *setup_fixture_submodules(void)
+{
+	git_repository *repo = cl_git_sandbox_init("submodules");
+
+	cl_fixture_sandbox("testrepo.git");
+
+	rewrite_gitmodules(git_repository_workdir(repo));
+	p_rename("submodules/testrepo/.gitted", "submodules/testrepo/.git");
+
+	cl_set_cleanup(cleanup_fixture_submodules, "testrepo.git");
+
+	cl_git_pass(git_repository_reinit_filesystem(repo, 1));
+
+	return repo;
+}
+
+git_repository *setup_fixture_submod2(void)
+{
+	git_repository *repo = cl_git_sandbox_init("submod2");
+
+	cl_fixture_sandbox("submod2_target");
+	p_rename("submod2_target/.gitted", "submod2_target/.git");
+
+	rewrite_gitmodules(git_repository_workdir(repo));
+	p_rename("submod2/not-submodule/.gitted", "submod2/not-submodule/.git");
+	p_rename("submod2/not/.gitted", "submod2/not/.git");
+
+	cl_set_cleanup(cleanup_fixture_submodules, "submod2_target");
+
+	cl_git_pass(git_repository_reinit_filesystem(repo, 1));
+
+	return repo;
+}
+
+git_repository *setup_fixture_submodule_simple(void)
+{
+	git_repository *repo = cl_git_sandbox_init("submodule_simple");
+
+	cl_fixture_sandbox("testrepo.git");
+	p_mkdir("submodule_simple/testrepo", 0777);
+
+	cl_set_cleanup(cleanup_fixture_submodules, "testrepo.git");
+
+	cl_git_pass(git_repository_reinit_filesystem(repo, 1));
+
+	return repo;
+}
+
+void assert__submodule_exists(
+	git_repository *repo, const char *name,
+	const char *msg, const char *file, int line)
+{
+	git_submodule *sm;
+	int error = git_submodule_lookup(&sm, repo, name);
+	if (error)
+		cl_git_report_failure(error, file, line, msg);
+	cl_assert_at_line(sm != NULL, file, line);
+	git_submodule_free(sm);
+}
+
+void refute__submodule_exists(
+	git_repository *repo, const char *name, int expected_error,
+	const char *msg, const char *file, int line)
+{
+	clar__assert_equal(
+		file, line, msg, 1, "%i",
+		expected_error, (int)(git_submodule_lookup(NULL, repo, name)));
+}
+
+unsigned int get_submodule_status(git_repository *repo, const char *name)
+{
+	unsigned int status = 0;
+
+	assert(repo && name);
+
+	cl_git_pass(git_submodule_status(&status, repo, name, GIT_SUBMODULE_IGNORE_UNSPECIFIED));
+
+	return status;
+}
+
+static int print_submodules(git_submodule *sm, const char *name, void *p)
+{
+	unsigned int loc = 0;
+	GIT_UNUSED(p);
+	git_submodule_location(&loc, sm);
+	fprintf(stderr, "# submodule %s (at %s) flags %x\n",
+		name, git_submodule_path(sm), loc);
+	return 0;
+}
+
+void dump_submodules(git_repository *repo)
+{
+	git_submodule_foreach(repo, print_submodules, NULL);
+}
+
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/submodule_helpers.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/submodule_helpers.h
new file mode 100755
index 0000000..1493f24
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/submodule_helpers.h
@@ -0,0 +1,22 @@
+extern void rewrite_gitmodules(const char *workdir);
+
+/* these will automatically set a cleanup callback */
+extern git_repository *setup_fixture_submodules(void);
+extern git_repository *setup_fixture_submod2(void);
+extern git_repository *setup_fixture_submodule_simple(void);
+
+extern unsigned int get_submodule_status(git_repository *, const char *);
+
+extern void assert__submodule_exists(
+	git_repository *, const char *, const char *, const char *, int);
+
+#define assert_submodule_exists(repo,name)								\
+	assert__submodule_exists(repo, name, "git_submodule_lookup(" #name ") failed", __FILE__, __LINE__)
+
+extern void refute__submodule_exists(
+	git_repository *, const char *, int err, const char *, const char *, int);
+
+#define refute_submodule_exists(repo,name,code) \
+	refute__submodule_exists(repo, name, code, "expected git_submodule_lookup(" #name ") to fail with error " #code, __FILE__, __LINE__)
+
+extern void dump_submodules(git_repository *repo);
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/update.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/update.c
new file mode 100755
index 0000000..40d24d0
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/submodule/update.c
@@ -0,0 +1,392 @@
+#include "clar_libgit2.h"
+#include "posix.h"
+#include "path.h"
+#include "submodule_helpers.h"
+#include "fileops.h"
+
+static git_repository *g_repo = NULL;
+
+void test_submodule_update__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_submodule_update__unitialized_submodule_no_init(void)
+{
+	git_submodule *sm;
+	git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
+
+	g_repo = setup_fixture_submodule_simple();
+
+	/* get the submodule */
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
+	/* updating an unitialized repository throws */
+	cl_git_fail_with(
+		GIT_ERROR,
+		git_submodule_update(sm, 0, &update_options));
+
+	git_submodule_free(sm);
+}
+
+struct update_submodule_cb_payload {
+	int update_tips_called;
+	int checkout_progress_called;
+	int checkout_notify_called;
+};
+
+static void checkout_progress_cb(
+	const char *path,
+	size_t completed_steps,
+	size_t total_steps,
+	void *payload)
+{
+	struct update_submodule_cb_payload *update_payload = payload;
+
+	GIT_UNUSED(path);
+	GIT_UNUSED(completed_steps);
+	GIT_UNUSED(total_steps);
+
+	update_payload->checkout_progress_called = 1;
+}
+
+static int checkout_notify_cb(
+	git_checkout_notify_t why,
+	const char *path,
+	const git_diff_file *baseline,
+	const git_diff_file *target,
+	const git_diff_file *workdir,
+	void *payload)
+{
+	struct update_submodule_cb_payload *update_payload = payload;
+
+	GIT_UNUSED(why);
+	GIT_UNUSED(path);
+	GIT_UNUSED(baseline);
+	GIT_UNUSED(target);
+	GIT_UNUSED(workdir);
+
+	update_payload->checkout_notify_called = 1;
+
+	return 0;
+}
+
+static int update_tips(const char *refname, const git_oid *a, const git_oid *b, void *data)
+{
+	struct update_submodule_cb_payload *update_payload = data;
+
+	GIT_UNUSED(refname);
+	GIT_UNUSED(a);
+	GIT_UNUSED(b);
+
+	update_payload->update_tips_called = 1;
+
+	return 1;
+}
+
+void test_submodule_update__update_submodule(void)
+{
+	git_submodule *sm;
+	git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
+	unsigned int submodule_status = 0;
+	struct update_submodule_cb_payload update_payload = { 0 };
+
+	g_repo = setup_fixture_submodule_simple();
+
+	update_options.checkout_opts.progress_cb = checkout_progress_cb;
+	update_options.checkout_opts.progress_payload = &update_payload;
+
+	update_options.fetch_opts.callbacks.update_tips = update_tips;
+	update_options.fetch_opts.callbacks.payload = &update_payload;
+
+	/* get the submodule */
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
+	/* verify the initial state of the submodule */
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_UNSPECIFIED));
+	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
+		GIT_SUBMODULE_STATUS_IN_INDEX |
+		GIT_SUBMODULE_STATUS_IN_CONFIG |
+		GIT_SUBMODULE_STATUS_WD_UNINITIALIZED);
+
+	/* initialize and update the submodule */
+	cl_git_pass(git_submodule_init(sm, 0));
+	cl_git_pass(git_submodule_update(sm, 0, &update_options));
+
+	/* verify state */
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_UNSPECIFIED));
+	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
+		GIT_SUBMODULE_STATUS_IN_INDEX |
+		GIT_SUBMODULE_STATUS_IN_CONFIG |
+		GIT_SUBMODULE_STATUS_IN_WD);
+
+	cl_assert(git_oid_streq(git_submodule_head_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+	cl_assert(git_oid_streq(git_submodule_wd_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+	cl_assert(git_oid_streq(git_submodule_index_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+
+	/* verify that the expected callbacks have been called. */
+	cl_assert_equal_i(1, update_payload.checkout_progress_called);
+	cl_assert_equal_i(1, update_payload.update_tips_called);
+
+	git_submodule_free(sm);
+}
+
+void test_submodule_update__update_and_init_submodule(void)
+{
+	git_submodule *sm;
+	git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
+	unsigned int submodule_status = 0;
+
+	g_repo = setup_fixture_submodule_simple();
+
+	/* get the submodule */
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_UNSPECIFIED));
+	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
+		GIT_SUBMODULE_STATUS_IN_INDEX |
+		GIT_SUBMODULE_STATUS_IN_CONFIG |
+		GIT_SUBMODULE_STATUS_WD_UNINITIALIZED);
+
+	/* update (with option to initialize sub repo) */
+	cl_git_pass(git_submodule_update(sm, 1, &update_options));
+
+	/* verify expected state */
+	cl_assert(git_oid_streq(git_submodule_head_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+	cl_assert(git_oid_streq(git_submodule_wd_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+	cl_assert(git_oid_streq(git_submodule_index_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+
+	git_submodule_free(sm);
+}
+
+void test_submodule_update__update_already_checked_out_submodule(void)
+{
+	git_submodule *sm = NULL;
+	git_checkout_options checkout_options = GIT_CHECKOUT_OPTIONS_INIT;
+	git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
+	unsigned int submodule_status = 0;
+	git_reference *branch_reference = NULL;
+	git_object *branch_commit = NULL;
+	struct update_submodule_cb_payload update_payload = { 0 };
+
+	g_repo = setup_fixture_submodule_simple();
+
+	update_options.checkout_opts.progress_cb = checkout_progress_cb;
+	update_options.checkout_opts.progress_payload = &update_payload;
+
+	/* Initialize and update the sub repository */
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_UNSPECIFIED));
+	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
+		GIT_SUBMODULE_STATUS_IN_INDEX |
+		GIT_SUBMODULE_STATUS_IN_CONFIG |
+		GIT_SUBMODULE_STATUS_WD_UNINITIALIZED);
+
+	cl_git_pass(git_submodule_update(sm, 1, &update_options));
+
+	/* verify expected state */
+	cl_assert(git_oid_streq(git_submodule_head_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+	cl_assert(git_oid_streq(git_submodule_wd_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+	cl_assert(git_oid_streq(git_submodule_index_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+
+	/* checkout the alternate_1 branch */
+	checkout_options.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+	cl_git_pass(git_reference_lookup(&branch_reference, g_repo, "refs/heads/alternate_1"));
+	cl_git_pass(git_reference_peel(&branch_commit, branch_reference, GIT_OBJ_COMMIT));
+	cl_git_pass(git_checkout_tree(g_repo, branch_commit, &checkout_options));
+	cl_git_pass(git_repository_set_head(g_repo, git_reference_name(branch_reference)));
+
+	/*
+	 * Verify state after checkout of parent repository. The submodule ID in the
+	 * HEAD commit and index should be updated, but not the workdir.
+	 */
+
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_UNSPECIFIED));
+
+	git_submodule_free(sm);
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
+	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
+		GIT_SUBMODULE_STATUS_IN_INDEX |
+		GIT_SUBMODULE_STATUS_IN_CONFIG |
+		GIT_SUBMODULE_STATUS_IN_WD |
+		GIT_SUBMODULE_STATUS_WD_MODIFIED);
+
+	cl_assert(git_oid_streq(git_submodule_head_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
+	cl_assert(git_oid_streq(git_submodule_wd_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+	cl_assert(git_oid_streq(git_submodule_index_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
+
+	/*
+	 * Update the submodule and verify the state.
+	 * Now, the HEAD, index, and Workdir commits should all be updated to
+	 * the new commit.
+	 */
+	cl_git_pass(git_submodule_update(sm, 0, &update_options));
+	cl_assert(git_oid_streq(git_submodule_head_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
+	cl_assert(git_oid_streq(git_submodule_wd_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
+	cl_assert(git_oid_streq(git_submodule_index_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
+
+	/* verify that the expected callbacks have been called. */
+	cl_assert_equal_i(1, update_payload.checkout_progress_called);
+	
+	git_submodule_free(sm);
+	git_object_free(branch_commit);
+	git_reference_free(branch_reference);
+}
+
+void test_submodule_update__update_blocks_on_dirty_wd(void)
+{
+	git_submodule *sm = NULL;
+	git_checkout_options checkout_options = GIT_CHECKOUT_OPTIONS_INIT;
+	git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
+	unsigned int submodule_status = 0;
+	git_reference *branch_reference = NULL;
+	git_object *branch_commit = NULL;
+	struct update_submodule_cb_payload update_payload = { 0 };
+
+	g_repo = setup_fixture_submodule_simple();
+
+	update_options.checkout_opts.notify_flags = GIT_CHECKOUT_NOTIFY_CONFLICT;
+	update_options.checkout_opts.notify_cb = checkout_notify_cb;
+	update_options.checkout_opts.notify_payload = &update_payload;
+
+	/* Initialize and update the sub repository */
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_UNSPECIFIED));
+	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
+		GIT_SUBMODULE_STATUS_IN_INDEX |
+		GIT_SUBMODULE_STATUS_IN_CONFIG |
+		GIT_SUBMODULE_STATUS_WD_UNINITIALIZED);
+
+	cl_git_pass(git_submodule_update(sm, 1, &update_options));
+
+	/* verify expected state */
+	cl_assert(git_oid_streq(git_submodule_head_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+	cl_assert(git_oid_streq(git_submodule_wd_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+	cl_assert(git_oid_streq(git_submodule_index_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+
+	/* checkout the alternate_1 branch */
+	checkout_options.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+	cl_git_pass(git_reference_lookup(&branch_reference, g_repo, "refs/heads/alternate_1"));
+	cl_git_pass(git_reference_peel(&branch_commit, branch_reference, GIT_OBJ_COMMIT));
+	cl_git_pass(git_checkout_tree(g_repo, branch_commit, &checkout_options));
+	cl_git_pass(git_repository_set_head(g_repo, git_reference_name(branch_reference)));
+
+	/*
+	 * Verify state after checkout of parent repository. The submodule ID in the
+	 * HEAD commit and index should be updated, but not the workdir.
+	 */
+
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_UNSPECIFIED));
+
+	git_submodule_free(sm);
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
+	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
+		GIT_SUBMODULE_STATUS_IN_INDEX |
+		GIT_SUBMODULE_STATUS_IN_CONFIG |
+		GIT_SUBMODULE_STATUS_IN_WD |
+		GIT_SUBMODULE_STATUS_WD_MODIFIED);
+
+	cl_assert(git_oid_streq(git_submodule_head_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
+	cl_assert(git_oid_streq(git_submodule_wd_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+	cl_assert(git_oid_streq(git_submodule_index_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
+
+	/*
+	 * Create a conflicting edit in the subrepository to verify that
+	 * the submodule update action is blocked.
+	 */
+	cl_git_write2file("submodule_simple/testrepo/branch_file.txt", "a conflicting edit", 0,
+		O_WRONLY | O_CREAT | O_TRUNC, 0755);
+
+	cl_git_fail(git_submodule_update(sm, 0, &update_options));
+
+	/* verify that the expected callbacks have been called. */
+	cl_assert_equal_i(1, update_payload.checkout_notify_called);
+
+	/* verify that the submodule state has not changed. */
+	cl_assert(git_oid_streq(git_submodule_head_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
+	cl_assert(git_oid_streq(git_submodule_wd_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+	cl_assert(git_oid_streq(git_submodule_index_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
+
+	git_submodule_free(sm);
+	git_object_free(branch_commit);
+	git_reference_free(branch_reference);
+}
+
+void test_submodule_update__can_force_update(void)
+{
+	git_submodule *sm = NULL;
+	git_checkout_options checkout_options = GIT_CHECKOUT_OPTIONS_INIT;
+	git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
+	unsigned int submodule_status = 0;
+	git_reference *branch_reference = NULL;
+	git_object *branch_commit = NULL;
+
+	g_repo = setup_fixture_submodule_simple();
+
+	/* Initialize and update the sub repository */
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_UNSPECIFIED));
+	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
+		GIT_SUBMODULE_STATUS_IN_INDEX |
+		GIT_SUBMODULE_STATUS_IN_CONFIG |
+		GIT_SUBMODULE_STATUS_WD_UNINITIALIZED);
+
+	cl_git_pass(git_submodule_update(sm, 1, &update_options));
+
+	/* verify expected state */
+	cl_assert(git_oid_streq(git_submodule_head_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+	cl_assert(git_oid_streq(git_submodule_wd_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+	cl_assert(git_oid_streq(git_submodule_index_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+
+	/* checkout the alternate_1 branch */
+	checkout_options.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+	cl_git_pass(git_reference_lookup(&branch_reference, g_repo, "refs/heads/alternate_1"));
+	cl_git_pass(git_reference_peel(&branch_commit, branch_reference, GIT_OBJ_COMMIT));
+	cl_git_pass(git_checkout_tree(g_repo, branch_commit, &checkout_options));
+	cl_git_pass(git_repository_set_head(g_repo, git_reference_name(branch_reference)));
+
+	/*
+	 * Verify state after checkout of parent repository. The submodule ID in the
+	 * HEAD commit and index should be updated, but not the workdir.
+	 */
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_UNSPECIFIED));
+
+	git_submodule_free(sm);
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
+	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
+		GIT_SUBMODULE_STATUS_IN_INDEX |
+		GIT_SUBMODULE_STATUS_IN_CONFIG |
+		GIT_SUBMODULE_STATUS_IN_WD |
+		GIT_SUBMODULE_STATUS_WD_MODIFIED);
+
+	cl_assert(git_oid_streq(git_submodule_head_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
+	cl_assert(git_oid_streq(git_submodule_wd_id(sm), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644") == 0);
+	cl_assert(git_oid_streq(git_submodule_index_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
+
+	/*
+	 * Create a conflicting edit in the subrepository to verify that
+	 * the submodule update action is blocked.
+	 */
+	cl_git_write2file("submodule_simple/testrepo/branch_file.txt", "a conflicting edit", 0,
+		O_WRONLY | O_CREAT | O_TRUNC, 0777);
+
+	/* forcefully checkout and verify the submodule state was updated. */
+	update_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+	cl_git_pass(git_submodule_update(sm, 0, &update_options));
+	cl_assert(git_oid_streq(git_submodule_head_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
+	cl_assert(git_oid_streq(git_submodule_wd_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
+	cl_assert(git_oid_streq(git_submodule_index_id(sm), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750") == 0);
+
+	git_submodule_free(sm);
+	git_object_free(branch_commit);
+	git_reference_free(branch_reference);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/basic.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/basic.c
new file mode 100755
index 0000000..9c342bc
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/basic.c
@@ -0,0 +1,50 @@
+#include "clar_libgit2.h"
+
+#include "thread_helpers.h"
+#include "cache.h"
+
+
+static git_repository *g_repo;
+
+void test_threads_basic__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo");
+}
+
+void test_threads_basic__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+
+void test_threads_basic__cache(void)
+{
+	// run several threads polling the cache at the same time
+	cl_assert(1 == 1);
+}
+
+void test_threads_basic__multiple_init(void)
+{
+	git_repository *nested_repo;
+
+	git_libgit2_init();
+	cl_git_pass(git_repository_open(&nested_repo, cl_fixture("testrepo.git")));
+	git_repository_free(nested_repo);
+
+	git_libgit2_shutdown();
+	cl_git_pass(git_repository_open(&nested_repo, cl_fixture("testrepo.git")));
+	git_repository_free(nested_repo);
+}
+
+static void *set_error(void *dummy)
+{
+	giterr_set(GITERR_INVALID, "oh no, something happened!\n");
+
+	return dummy;
+}
+
+/* Set errors so we can check that we free it */
+void test_threads_basic__set_error(void)
+{
+	run_in_parallel(1, 4, set_error, NULL, NULL);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/diff.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/diff.c
new file mode 100755
index 0000000..c328114
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/diff.c
@@ -0,0 +1,196 @@
+#include "clar_libgit2.h"
+#include "thread_helpers.h"
+
+#ifdef GIT_THREADS
+
+# if defined(GIT_WIN32)
+#  define git_thread_yield() Sleep(0)
+# elif defined(__FreeBSD__) || defined(__MidnightBSD__) || defined(__DragonFly__)
+#  define git_thread_yield() pthread_yield()
+# else
+#  define git_thread_yield() sched_yield()
+# endif
+
+#else
+# define git_thread_yield() (void)0
+#endif
+
+static git_repository *_repo;
+static git_tree *_a, *_b;
+static git_atomic _counts[4];
+static int _check_counts;
+
+#define THREADS 20
+
+void test_threads_diff__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static void setup_trees(void)
+{
+	git_index *idx;
+
+	_repo = cl_git_sandbox_reopen(); /* reopen sandbox to flush caches */
+
+	/* avoid competing to load initial index */
+	cl_git_pass(git_repository_index(&idx, _repo));
+	git_index_free(idx);
+
+	cl_git_pass(git_revparse_single(
+		(git_object **)&_a, _repo, "0017bd4ab1^{tree}"));
+	cl_git_pass(git_revparse_single(
+		(git_object **)&_b, _repo, "26a125ee1b^{tree}"));
+
+	memset(_counts, 0, sizeof(_counts));
+}
+
+static void free_trees(void)
+{
+	git_tree_free(_a); _a = NULL;
+	git_tree_free(_b); _b = NULL;
+
+	if (_check_counts) {
+		cl_assert_equal_i(288, git_atomic_get(&_counts[0]));
+		cl_assert_equal_i(112, git_atomic_get(&_counts[1]));
+		cl_assert_equal_i( 80, git_atomic_get(&_counts[2]));
+		cl_assert_equal_i( 96, git_atomic_get(&_counts[3]));
+	}
+}
+
+static void *run_index_diffs(void *arg)
+{
+	int thread = *(int *)arg;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	size_t i;
+	int exp[4] = { 0, 0, 0, 0 };
+
+	switch (thread & 0x03) {
+	case 0: /* diff index to workdir */;
+		cl_git_pass(git_diff_index_to_workdir(&diff, _repo, NULL, &opts));
+		break;
+	case 1: /* diff tree 'a' to index */;
+		cl_git_pass(git_diff_tree_to_index(&diff, _repo, _a, NULL, &opts));
+		break;
+	case 2: /* diff tree 'b' to index */;
+		cl_git_pass(git_diff_tree_to_index(&diff, _repo, _b, NULL, &opts));
+		break;
+	case 3: /* diff index to workdir (explicit index) */;
+		{
+			git_index *idx;
+			cl_git_pass(git_repository_index(&idx, _repo));
+			cl_git_pass(git_diff_index_to_workdir(&diff, _repo, idx, &opts));
+			git_index_free(idx);
+			break;
+		}
+	}
+
+	/* keep some diff stats to make sure results are as expected */
+
+	i = git_diff_num_deltas(diff);
+	git_atomic_add(&_counts[0], (int32_t)i);
+	exp[0] = (int)i;
+
+	while (i > 0) {
+		switch (git_diff_get_delta(diff, --i)->status) {
+		case GIT_DELTA_MODIFIED: exp[1]++; git_atomic_inc(&_counts[1]); break;
+		case GIT_DELTA_ADDED:    exp[2]++; git_atomic_inc(&_counts[2]); break;
+		case GIT_DELTA_DELETED:  exp[3]++; git_atomic_inc(&_counts[3]); break;
+		default: break;
+		}
+	}
+
+	switch (thread & 0x03) {
+	case 0: case 3:
+		cl_assert_equal_i(8, exp[0]); cl_assert_equal_i(4, exp[1]);
+		cl_assert_equal_i(0, exp[2]); cl_assert_equal_i(4, exp[3]);
+		break;
+	case 1:
+		cl_assert_equal_i(12, exp[0]); cl_assert_equal_i(3, exp[1]);
+		cl_assert_equal_i(7, exp[2]); cl_assert_equal_i(2, exp[3]);
+		break;
+	case 2:
+		cl_assert_equal_i(8, exp[0]); cl_assert_equal_i(3, exp[1]);
+		cl_assert_equal_i(3, exp[2]); cl_assert_equal_i(2, exp[3]);
+		break;
+	}
+
+	git_diff_free(diff);
+	giterr_clear();
+
+	return arg;
+}
+
+void test_threads_diff__concurrent_diffs(void)
+{
+	_repo = cl_git_sandbox_init("status");
+	_check_counts = 1;
+
+	run_in_parallel(
+		5, 32, run_index_diffs, setup_trees, free_trees);
+}
+
+static void *run_index_diffs_with_modifier(void *arg)
+{
+	int thread = *(int *)arg;
+	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+	git_diff *diff = NULL;
+	git_index *idx = NULL;
+
+	cl_git_pass(git_repository_index(&idx, _repo));
+
+	/* have first thread altering the index as we go */
+	if (thread == 0) {
+		int i;
+
+		for (i = 0; i < 300; ++i) {
+			switch (i & 0x03) {
+			case 0: (void)git_index_add_bypath(idx, "new_file"); break;
+			case 1: (void)git_index_remove_bypath(idx, "modified_file"); break;
+			case 2: (void)git_index_remove_bypath(idx, "new_file"); break;
+			case 3: (void)git_index_add_bypath(idx, "modified_file"); break;
+			}
+			git_thread_yield();
+		}
+
+		goto done;
+	}
+
+	/* only use explicit index in this test to prevent reloading */
+
+	switch (thread & 0x03) {
+	case 0: /* diff index to workdir */;
+		cl_git_pass(git_diff_index_to_workdir(&diff, _repo, idx, &opts));
+		break;
+	case 1: /* diff tree 'a' to index */;
+		cl_git_pass(git_diff_tree_to_index(&diff, _repo, _a, idx, &opts));
+		break;
+	case 2: /* diff tree 'b' to index */;
+		cl_git_pass(git_diff_tree_to_index(&diff, _repo, _b, idx, &opts));
+		break;
+	case 3: /* diff index to workdir reversed */;
+		opts.flags |= GIT_DIFF_REVERSE;
+		cl_git_pass(git_diff_index_to_workdir(&diff, _repo, idx, &opts));
+		break;
+	}
+
+	/* results will be unpredictable with index modifier thread running */
+
+	git_diff_free(diff);
+
+done:
+	git_index_free(idx);
+	giterr_clear();
+
+	return arg;
+}
+
+void test_threads_diff__with_concurrent_index_modified(void)
+{
+	_repo = cl_git_sandbox_init("status");
+	_check_counts = 0;
+
+	run_in_parallel(
+		5, 16, run_index_diffs_with_modifier, setup_trees, free_trees);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/iterator.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/iterator.c
new file mode 100755
index 0000000..8a2d79c
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/iterator.c
@@ -0,0 +1,49 @@
+#include "clar_libgit2.h"
+#include "thread_helpers.h"
+#include "iterator.h"
+
+static git_repository *_repo;
+
+void test_threads_iterator__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+static void *run_workdir_iterator(void *arg)
+{
+	int error = 0;
+	git_iterator *iter;
+	const git_index_entry *entry = NULL;
+
+	cl_git_pass(git_iterator_for_workdir(
+		&iter, _repo, NULL, NULL, GIT_ITERATOR_DONT_AUTOEXPAND, NULL, NULL));
+
+	while (!error) {
+		if (entry && entry->mode == GIT_FILEMODE_TREE) {
+			error = git_iterator_advance_into(&entry, iter);
+
+			if (error == GIT_ENOTFOUND)
+				error = git_iterator_advance(&entry, iter);
+		} else {
+			error = git_iterator_advance(&entry, iter);
+		}
+
+		if (!error)
+			(void)git_iterator_current_is_ignored(iter);
+	}
+
+	cl_assert_equal_i(GIT_ITEROVER, error);
+
+	git_iterator_free(iter);
+	giterr_clear();
+	return arg;
+}
+
+
+void test_threads_iterator__workdir(void)
+{
+	_repo = cl_git_sandbox_init("status");
+
+	run_in_parallel(
+		1, 20, run_workdir_iterator, NULL, NULL);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/refdb.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/refdb.c
new file mode 100755
index 0000000..6589e39
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/refdb.c
@@ -0,0 +1,221 @@
+#include "clar_libgit2.h"
+#include "git2/refdb.h"
+#include "refdb.h"
+
+static git_repository *g_repo;
+static int g_expected = 0;
+
+void test_threads_refdb__initialize(void)
+{
+	g_repo = NULL;
+}
+
+void test_threads_refdb__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+	g_repo = NULL;
+}
+
+#define REPEAT 20
+#define THREADS 20
+
+static void *iterate_refs(void *arg)
+{
+	git_reference_iterator *i;
+	git_reference *ref;
+	int count = 0;
+
+	cl_git_pass(git_reference_iterator_new(&i, g_repo));
+
+	for (count = 0; !git_reference_next(&ref, i); ++count) {
+		cl_assert(ref != NULL);
+		git_reference_free(ref);
+	}
+
+	if (g_expected > 0)
+		cl_assert_equal_i(g_expected, count);
+
+	git_reference_iterator_free(i);
+
+	giterr_clear();
+	return arg;
+}
+
+void test_threads_refdb__iterator(void)
+{
+	int r, t;
+	git_thread th[THREADS];
+	int id[THREADS];
+	git_oid head;
+	git_reference *ref;
+	char name[128];
+	git_refdb *refdb;
+
+	g_repo = cl_git_sandbox_init("testrepo2");
+
+	cl_git_pass(git_reference_name_to_id(&head, g_repo, "HEAD"));
+
+	/* make a bunch of references */
+
+	for (r = 0; r < 200; ++r) {
+		p_snprintf(name, sizeof(name), "refs/heads/direct-%03d", r);
+		cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0, NULL));
+		git_reference_free(ref);
+	}
+
+	cl_git_pass(git_repository_refdb(&refdb, g_repo));
+	cl_git_pass(git_refdb_compress(refdb));
+	git_refdb_free(refdb);
+
+	g_expected = 206;
+
+	for (r = 0; r < REPEAT; ++r) {
+		g_repo = cl_git_sandbox_reopen(); /* reopen to flush caches */
+
+		for (t = 0; t < THREADS; ++t) {
+			id[t] = t;
+#ifdef GIT_THREADS
+			cl_git_pass(git_thread_create(&th[t], NULL, iterate_refs, &id[t]));
+#else
+			th[t] = t;
+			iterate_refs(&id[t]);
+#endif
+		}
+
+#ifdef GIT_THREADS
+		for (t = 0; t < THREADS; ++t) {
+			cl_git_pass(git_thread_join(&th[t], NULL));
+		}
+#endif
+
+		memset(th, 0, sizeof(th));
+	}
+}
+
+static void *create_refs(void *arg)
+{
+	int *id = arg, i;
+	git_oid head;
+	char name[128];
+	git_reference *ref[10];
+
+	cl_git_pass(git_reference_name_to_id(&head, g_repo, "HEAD"));
+
+	for (i = 0; i < 10; ++i) {
+		p_snprintf(name, sizeof(name), "refs/heads/thread-%03d-%02d", *id, i);
+		cl_git_pass(git_reference_create(&ref[i], g_repo, name, &head, 0, NULL));
+
+		if (i == 5) {
+			git_refdb *refdb;
+			cl_git_pass(git_repository_refdb(&refdb, g_repo));
+			cl_git_pass(git_refdb_compress(refdb));
+			git_refdb_free(refdb);
+		}
+	}
+
+	for (i = 0; i < 10; ++i)
+		git_reference_free(ref[i]);
+
+	giterr_clear();
+	return arg;
+}
+
+static void *delete_refs(void *arg)
+{
+	int *id = arg, i;
+	git_reference *ref;
+	char name[128];
+
+	for (i = 0; i < 10; ++i) {
+		p_snprintf(
+			name, sizeof(name), "refs/heads/thread-%03d-%02d", (*id) & ~0x3, i);
+
+		if (!git_reference_lookup(&ref, g_repo, name)) {
+			cl_git_pass(git_reference_delete(ref));
+			git_reference_free(ref);
+		}
+
+		if (i == 5) {
+			git_refdb *refdb;
+			cl_git_pass(git_repository_refdb(&refdb, g_repo));
+			cl_git_pass(git_refdb_compress(refdb));
+			git_refdb_free(refdb);
+		}
+	}
+
+	giterr_clear();
+	return arg;
+}
+
+void test_threads_refdb__edit_while_iterate(void)
+{
+	int r, t;
+	int id[THREADS];
+	git_oid head;
+	git_reference *ref;
+	char name[128];
+	git_refdb *refdb;
+
+#ifdef GIT_THREADS
+	git_thread th[THREADS];
+#endif
+
+	g_repo = cl_git_sandbox_init("testrepo2");
+
+	cl_git_pass(git_reference_name_to_id(&head, g_repo, "HEAD"));
+
+	/* make a bunch of references */
+
+	for (r = 0; r < 50; ++r) {
+		p_snprintf(name, sizeof(name), "refs/heads/starter-%03d", r);
+		cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0, NULL));
+		git_reference_free(ref);
+	}
+
+	cl_git_pass(git_repository_refdb(&refdb, g_repo));
+	cl_git_pass(git_refdb_compress(refdb));
+	git_refdb_free(refdb);
+
+	g_expected = -1;
+
+	g_repo = cl_git_sandbox_reopen(); /* reopen to flush caches */
+
+	for (t = 0; t < THREADS; ++t) {
+		void *(*fn)(void *arg);
+
+		switch (t & 0x3) {
+		case 0:  fn = create_refs;  break;
+		case 1:  fn = delete_refs;  break;
+		default: fn = iterate_refs; break;
+		}
+
+		id[t] = t;
+
+		/* It appears with all reflog writing changes, etc., that this
+		 * test has started to fail quite frequently, so let's disable it
+		 * for now by just running on a single thread...
+		 */
+/* #ifdef GIT_THREADS */
+/*		cl_git_pass(git_thread_create(&th[t], NULL, fn, &id[t])); */
+/* #else */
+		fn(&id[t]);
+/* #endif */
+	}
+
+#ifdef GIT_THREADS
+/*	for (t = 0; t < THREADS; ++t) { */
+/*		cl_git_pass(git_thread_join(th[t], NULL)); */
+/*	} */
+
+	memset(th, 0, sizeof(th));
+
+	for (t = 0; t < THREADS; ++t) {
+		id[t] = t;
+		cl_git_pass(git_thread_create(&th[t], NULL, iterate_refs, &id[t]));
+	}
+
+	for (t = 0; t < THREADS; ++t) {
+		cl_git_pass(git_thread_join(&th[t], NULL));
+	}
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/thread_helpers.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/thread_helpers.c
new file mode 100755
index 0000000..760a7bd
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/thread_helpers.c
@@ -0,0 +1,44 @@
+#include "clar_libgit2.h"
+#include "thread_helpers.h"
+
+void run_in_parallel(
+	int repeats,
+	int threads,
+	void *(*func)(void *),
+	void (*before_test)(void),
+	void (*after_test)(void))
+{
+	int r, t, *id = git__calloc(threads, sizeof(int));
+#ifdef GIT_THREADS
+	git_thread *th = git__calloc(threads, sizeof(git_thread));
+	cl_assert(th != NULL);
+#else
+	void *th = NULL;
+#endif
+
+	cl_assert(id != NULL);
+
+	for (r = 0; r < repeats; ++r) {
+		if (before_test) before_test();
+
+		for (t = 0; t < threads; ++t) {
+			id[t] = t;
+#ifdef GIT_THREADS
+			cl_git_pass(git_thread_create(&th[t], NULL, func, &id[t]));
+#else
+			cl_assert(func(&id[t]) == &id[t]);
+#endif
+		}
+
+#ifdef GIT_THREADS
+		for (t = 0; t < threads; ++t)
+			cl_git_pass(git_thread_join(&th[t], NULL));
+		memset(th, 0, threads * sizeof(git_thread));
+#endif
+
+		if (after_test) after_test();
+	}
+
+	git__free(id);
+	git__free(th);
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/thread_helpers.h b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/thread_helpers.h
new file mode 100755
index 0000000..3c13cfb
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/threads/thread_helpers.h
@@ -0,0 +1,8 @@
+#include "thread-utils.h"
+
+void run_in_parallel(
+	int repeats,
+	int threads,
+	void *(*func)(void *),
+	void (*before_test)(void),
+	void (*after_test)(void));
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/trace/trace.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/trace/trace.c
new file mode 100755
index 0000000..097208b
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/trace/trace.c
@@ -0,0 +1,106 @@
+#include "clar_libgit2.h"
+#include "clar_libgit2_trace.h"
+#include "trace.h"
+
+static int written = 0;
+
+static void trace_callback(git_trace_level_t level, const char *message)
+{
+	GIT_UNUSED(level);
+
+	cl_assert(strcmp(message, "Hello world!") == 0);
+
+	written = 1;
+}
+
+void test_trace_trace__initialize(void)
+{
+	/* If global tracing is enabled, disable for the duration of this test. */
+	cl_global_trace_disable();
+
+	git_trace_set(GIT_TRACE_INFO, trace_callback);
+	written = 0;
+}
+
+void test_trace_trace__cleanup(void)
+{
+	git_trace_set(GIT_TRACE_NONE, NULL);
+
+	/* If global tracing was enabled, restart it. */
+	cl_global_trace_register();
+}
+
+void test_trace_trace__sets(void)
+{
+#ifdef GIT_TRACE
+	cl_assert(git_trace_level() == GIT_TRACE_INFO);
+#else
+	cl_skip();
+#endif
+}
+
+void test_trace_trace__can_reset(void)
+{
+#ifdef GIT_TRACE
+	cl_assert(git_trace_level() == GIT_TRACE_INFO);
+	cl_git_pass(git_trace_set(GIT_TRACE_ERROR, trace_callback));
+
+	cl_assert(written == 0);
+	git_trace(GIT_TRACE_INFO, "Hello %s!", "world");
+	cl_assert(written == 0);
+
+	git_trace(GIT_TRACE_ERROR, "Hello %s!", "world");
+	cl_assert(written == 1);
+#else
+	cl_skip();
+#endif
+}
+
+void test_trace_trace__can_unset(void)
+{
+#ifdef GIT_TRACE
+	cl_assert(git_trace_level() == GIT_TRACE_INFO);
+	cl_git_pass(git_trace_set(GIT_TRACE_NONE, NULL));
+
+	cl_assert(git_trace_level() == GIT_TRACE_NONE);
+
+	cl_assert(written == 0);
+	git_trace(GIT_TRACE_FATAL, "Hello %s!", "world");
+	cl_assert(written == 0);
+#else
+	cl_skip();
+#endif
+}
+
+void test_trace_trace__skips_higher_level(void)
+{
+#ifdef GIT_TRACE
+	cl_assert(written == 0);
+	git_trace(GIT_TRACE_DEBUG, "Hello %s!", "world");
+	cl_assert(written == 0);
+#else
+	cl_skip();
+#endif
+}
+
+void test_trace_trace__writes(void)
+{
+#ifdef GIT_TRACE
+	cl_assert(written == 0);
+	git_trace(GIT_TRACE_INFO, "Hello %s!", "world");
+	cl_assert(written == 1);
+#else
+	cl_skip();
+#endif
+}
+
+void test_trace_trace__writes_lower_level(void)
+{
+#ifdef GIT_TRACE
+	cl_assert(written == 0);
+	git_trace(GIT_TRACE_ERROR, "Hello %s!", "world");
+	cl_assert(written == 1);
+#else
+	cl_skip();
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/transport/register.c b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/transport/register.c
new file mode 100755
index 0000000..ea917d5
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/transport/register.c
@@ -0,0 +1,68 @@
+#include "clar_libgit2.h"
+#include "git2/sys/transport.h"
+
+static git_transport _transport = GIT_TRANSPORT_INIT;
+
+static int dummy_transport(git_transport **transport, git_remote *owner, void *param)
+{
+	*transport = &_transport;
+	GIT_UNUSED(owner);
+	GIT_UNUSED(param);
+	return 0;
+}
+
+void test_transport_register__custom_transport(void)
+{
+	git_transport *transport;
+
+	cl_git_pass(git_transport_register("something", dummy_transport, NULL));
+
+	cl_git_pass(git_transport_new(&transport, NULL, "something://somepath"));
+
+	cl_assert(transport == &_transport);
+
+	cl_git_pass(git_transport_unregister("something"));
+}
+
+void test_transport_register__custom_transport_error_doubleregister(void)
+{
+	cl_git_pass(git_transport_register("something", dummy_transport, NULL));
+
+	cl_git_fail_with(git_transport_register("something", dummy_transport, NULL), GIT_EEXISTS);
+
+	cl_git_pass(git_transport_unregister("something"));
+}
+
+void test_transport_register__custom_transport_error_remove_non_existing(void)
+{
+	cl_git_fail_with(git_transport_unregister("something"), GIT_ENOTFOUND);
+}
+
+void test_transport_register__custom_transport_ssh(void)
+{
+	git_transport *transport;
+
+#ifndef GIT_SSH
+	cl_git_fail_with(git_transport_new(&transport, NULL, "ssh://somehost:somepath"), -1);
+	cl_git_fail_with(git_transport_new(&transport, NULL, "git at somehost:somepath"), -1);
+#else
+	cl_git_pass(git_transport_new(&transport, NULL, "git at somehost:somepath"));
+	transport->free(transport);
+#endif
+
+	cl_git_pass(git_transport_register("ssh", dummy_transport, NULL));
+
+	cl_git_pass(git_transport_new(&transport, NULL, "git at somehost:somepath"));
+
+	cl_assert(transport == &_transport);
+
+	cl_git_pass(git_transport_unregister("ssh"));
+
+#ifndef GIT_SSH
+	cl_git_fail_with(git_transport_new(&transport, NULL, "ssh://somehost:somepath"), -1);
+	cl_git_fail_with(git_transport_new(&transport, NULL, "git at somehost:somepath"), -1);
+#else
+	cl_git_pass(git_transport_new(&transport, NULL, "git at somehost:somepath"));
+	transport->free(transport);
+#endif
+}
diff --git a/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/valgrind-supp-mac.txt b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/valgrind-supp-mac.txt
new file mode 100755
index 0000000..0cdc975
--- /dev/null
+++ b/app/server/vendor/rugged-0.23.3/vendor/libgit2/tests/valgrind-supp-mac.txt
@@ -0,0 +1,176 @@
+{
+   libgit2-giterr-set-buffer
+   Memcheck:Leak
+   ...
+   fun:git__realloc
+   fun:git_buf_try_grow
+   fun:git_buf_grow
+   fun:git_buf_vprintf
+   fun:giterr_set
+}
+{
+   mac-setenv-leak-1
+   Memcheck:Leak
+   fun:malloc_zone_malloc
+   fun:__setenv
+   fun:setenv
+}
+{
+   mac-setenv-leak-2
+   Memcheck:Leak
+   fun:malloc_zone_malloc
+   fun:malloc_set_zone_name
+   ...
+   fun:init__zone0
+   fun:setenv
+}
+{
+   mac-dyld-initializer-leak
+   Memcheck:Leak
+   fun:malloc
+   ...
+   fun:dyld_register_image_state_change_handler
+   fun:_dyld_initializer
+}
+{
+   mac-tz-leak-1
+   Memcheck:Leak
+   ...
+   fun:token_table_add
+   fun:notify_register_check
+   fun:notify_register_tz
+}
+{
+   mac-tz-leak-2
+   Memcheck:Leak
+   fun:malloc
+   fun:tzload
+}
+{
+   mac-tz-leak-3
+   Memcheck:Leak
+   fun:malloc
+   fun:tzsetwall_basic
+}
+{
+   mac-tz-leak-4
+   Memcheck:Leak
+   fun:malloc
+   fun:gmtsub
+}
+{
+   mac-system-init-leak-1
+   Memcheck:Leak
+   ...
+   fun:_libxpc_initializer
+   fun:libSystem_initializer
+}
+{
+   mac-system-init-leak-2
+   Memcheck:Leak
+   ...
+   fun:__keymgr_initializer
+   fun:libSystem_initializer
+}
+{
+   mac-puts-leak
+   Memcheck:Leak
+   fun:malloc
+   fun:__smakebuf
+   ...
+   fun:puts
+}
+{
+	mac-ssl-uninitialized-1
+	Memcheck:Cond
+	obj:/usr/lib/libcrypto.0.9.8.dylib
+	...
+	fun:ssl23_connect
+}
+{
+	mac-ssl-uninitialized-2
+	Memcheck:Cond
+	...
+	obj:/usr/lib/libssl.0.9.8.dylib
+	...
+	fun:ssl23_connect
+}
+{
+	mac-ssl-uninitialized-3
+	Memcheck:Value8
+	obj:/usr/lib/libcrypto.0.9.8.dylib
+	...
+	fun:ssl23_connect
+}
+{
+	mac-ssl-leak-1
+	Memcheck:Leak
+	...
+	fun:ERR_load_strings
+}
+{
+	mac-ssl-leak-2
+	Memcheck:Leak
+	...
+	fun:SSL_library_init
+}
+{
+	mac-ssl-leak-3
+	Memcheck:Leak
+	...
+	fun:si_module_with_name
+	fun:getaddrinfo
+}
+{
+	mac-ssl-leak-4
+	Memcheck:Leak
+	fun:malloc
+	fun:CRYPTO_malloc
+	...
+	fun:ssl3_get_server_certificate
+}
+{
+	mac-ssl-leak-5
+	Memcheck:Leak
+	fun:malloc
+	fun:CRYPTO_malloc
+	...
+	fun:ERR_put_error
+}
+{
+	clar-printf-buf
+	Memcheck:Leak
+	fun:malloc
+	fun:__smakebuf
+	...
+	fun:printf
+	fun:clar_print_init
+}
+{
+	molo-1
+	Memcheck:Leak
+	fun:malloc_zone_malloc
+	...
+	fun:_objc_init
+}
+{
+	molo-2
+	Memcheck:Leak
+	fun:malloc_zone_calloc
+	...
+	fun:_objc_init
+}
+{
+	molo-3
+	Memcheck:Leak
+	fun:malloc
+	...
+	fun:_objc_init
+}
+{
+	molo-4
+	Memcheck:Leak
+	fun:malloc
+	...
+	fun:dyld_register_image_state_change_handler
+}
diff --git a/app/server/vendor/thread_safe/.gitignore b/app/server/vendor/thread_safe/.gitignore
new file mode 100644
index 0000000..eaa8ce4
--- /dev/null
+++ b/app/server/vendor/thread_safe/.gitignore
@@ -0,0 +1,22 @@
+*.gem
+*.rbc
+.rbx/*
+.bundle
+.config
+.yardoc
+Gemfile.lock
+InstalledFiles
+_yardoc
+coverage
+doc/
+lib/bundler/man
+lib/thread_safe/jruby_cache_backend.jar
+pkg
+rdoc
+spec/reports
+test/tmp
+test/version_tmp
+tmp
+.DS_Store
+*.swp
+test/package.jar
diff --git a/app/server/vendor/thread_safe/.travis.yml b/app/server/vendor/thread_safe/.travis.yml
new file mode 100644
index 0000000..0d087fd
--- /dev/null
+++ b/app/server/vendor/thread_safe/.travis.yml
@@ -0,0 +1,24 @@
+language: ruby
+rvm:
+  - jruby-18mode
+  - jruby-19mode
+  - rbx-2
+  - 1.8.7
+  - 1.9.3
+  - 2.0.0
+  - 2.1.0
+jdk: # for JRuby only
+  - openjdk7
+  - oraclejdk8
+matrix:
+  exclude:
+    - rvm: rbx-2
+      jdk: oraclejdk8
+    - rvm: 1.8.7
+      jdk: oraclejdk8
+    - rvm: 1.9.3
+      jdk: oraclejdk8
+    - rvm: 2.0.0
+      jdk: oraclejdk8
+    - rvm: 2.1.0
+      jdk: oraclejdk8
\ No newline at end of file
diff --git a/app/server/vendor/thread_safe/Gemfile b/app/server/vendor/thread_safe/Gemfile
new file mode 100644
index 0000000..fa65970
--- /dev/null
+++ b/app/server/vendor/thread_safe/Gemfile
@@ -0,0 +1,4 @@
+source 'https://rubygems.org'
+
+# Specify your gem's dependencies in thread_safe.gemspec
+gemspec
diff --git a/app/server/vendor/thread_safe/LICENSE b/app/server/vendor/thread_safe/LICENSE
new file mode 100644
index 0000000..5336718
--- /dev/null
+++ b/app/server/vendor/thread_safe/LICENSE
@@ -0,0 +1,144 @@
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and distribution as 
+defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that 
+is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities that 
+control, are controlled by, or are under common control with that entity. For the purposes 
+of this definition, "control" means (i) the power, direct or indirect, to cause the 
+direction or management of such entity, whether by contract or otherwise, or (ii) ownership 
+of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of 
+such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by 
+this License.
+
+"Source" form shall mean the preferred form for making modifications, including but not 
+limited to software source code, documentation source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or translation of 
+a Source form, including but not limited to compiled object code, generated documentation, 
+and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made available 
+under the License, as indicated by a copyright notice that is included in or attached to the 
+work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on 
+(or derived from) the Work and for which the editorial revisions, annotations, elaborations, 
+or other modifications represent, as a whole, an original work of authorship. For the 
+purposes of this License, Derivative Works shall not include works that remain separable 
+from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works 
+thereof.
+
+"Contribution" shall mean any work of authorship, including the original version of the Work 
+and any modifications or additions to that Work or Derivative Works thereof, that is 
+intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by 
+an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the 
+purposes of this definition, "submitted" means any form of electronic, verbal, or written 
+communication sent to the Licensor or its representatives, including but not limited to 
+communication on electronic mailing lists, source code control systems, and issue tracking 
+systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and 
+improving the Work, but excluding communication that is conspicuously marked or otherwise 
+designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a 
+Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each 
+Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, 
+royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, 
+publicly display, publicly perform, sublicense, and distribute the Work and such Derivative 
+Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this License, each 
+Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, 
+royalty-free, irrevocable (except as stated in this section) patent license to make, have 
+made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license 
+applies only to those patent claims licensable by such Contributor that are necessarily 
+infringed by their Contribution(s) alone or by combination of their Contribution(s) with the 
+Work to which such Contribution(s) was submitted. If You institute patent litigation against 
+any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or 
+a Contribution incorporated within the Work constitutes direct or contributory patent 
+infringement, then any patent licenses granted to You under this License for that Work shall 
+terminate as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works 
+thereof in any medium, with or without modifications, and in Source or Object form, provided 
+that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of this License; 
+and
+
+You must cause any modified files to carry prominent notices stating that You changed the 
+files; and
+
+You must retain, in the Source form of any Derivative Works that You distribute, all 
+copyright, patent, trademark, and attribution notices from the Source form of the Work, 
+excluding those notices that do not pertain to any part of the Derivative Works; and
+
+If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative 
+Works that You distribute must include a readable copy of the attribution notices contained 
+within such NOTICE file, excluding those notices that do not pertain to any part of the 
+Derivative Works, in at least one of the following places: within a NOTICE text file 
+distributed as part of the Derivative Works; within the Source form or documentation, if 
+provided along with the Derivative Works; or, within a display generated by the Derivative 
+Works, if and wherever such third-party notices normally appear. The contents of the NOTICE 
+file are for informational purposes only and do not modify the License. You may add Your own 
+attribution notices within Derivative Works that You distribute, alongside or as an addendum 
+to the NOTICE text from the Work, provided that such additional attribution notices cannot 
+be construed as modifying the License. You may add Your own copyright statement to Your 
+modifications and may provide additional or different license terms and conditions for use, 
+reproduction, or distribution of Your modifications, or for any such Derivative Works as a 
+whole, provided Your use, reproduction, and distribution of the Work otherwise complies with 
+the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution 
+intentionally submitted for inclusion in the Work by You to the Licensor shall be under the 
+terms and conditions of this License, without any additional terms or conditions. 
+Notwithstanding the above, nothing herein shall supersede or modify the terms of any 
+separate license agreement you may have executed with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names, trademarks, 
+service marks, or product names of the Licensor, except as required for reasonable and 
+customary use in describing the origin of the Work and reproducing the content of the NOTICE 
+file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, 
+Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" 
+BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, 
+without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, 
+MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for 
+determining the appropriateness of using or redistributing the Work and assume any risks 
+associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in tort 
+(including negligence), contract, or otherwise, unless required by applicable law (such as 
+deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be 
+liable to You for damages, including any direct, indirect, special, incidental, or 
+consequential damages of any character arising as a result of this License or out of the use 
+or inability to use the Work (including but not limited to damages for loss of goodwill, 
+work stoppage, computer failure or malfunction, or any and all other commercial damages or 
+losses), even if such Contributor has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative 
+Works thereof, You may choose to offer, and charge a fee for, acceptance of support, 
+warranty, indemnity, or other liability obligations and/or rights consistent with this 
+License. However, in accepting such obligations, You may act only on Your own behalf and on 
+Your sole responsibility, not on behalf of any other Contributor, and only if You agree to 
+indemnify, defend, and hold each Contributor harmless for any liability incurred by, or 
+claims asserted against, such Contributor by reason of your accepting any such warranty or 
+additional liability.
+
+END OF TERMS AND CONDITIONS
diff --git a/app/server/vendor/thread_safe/README.md b/app/server/vendor/thread_safe/README.md
new file mode 100644
index 0000000..3f964f5
--- /dev/null
+++ b/app/server/vendor/thread_safe/README.md
@@ -0,0 +1,56 @@
+# Threadsafe
+
+[![Build Status](https://travis-ci.org/headius/thread_safe.png)](https://travis-ci.org/headius/thread_safe)
+
+A collection of thread-safe versions of common core Ruby classes.
+
+## Installation
+
+Add this line to your application's Gemfile:
+
+    gem 'thread_safe'
+
+And then execute:
+
+    $ bundle
+
+Or install it yourself as:
+
+    $ gem install thread_safe
+
+## Usage
+
+```ruby
+require 'thread_safe'
+
+sa = ThreadSafe::Array.new # supports standard Array.new forms
+sh = ThreadSafe::Hash.new # supports standard Hash.new forms
+```
+
+`ThreadSafe::Cache` also exists, as a hash-like object, and should have
+much better performance characteristics esp. under high concurrency than
+`ThreadSafe::Hash`. However, `ThreadSafe::Cache` is not strictly semantically
+equivalent to a ruby `Hash` -- for instance, it does not necessarily retain
+ordering by insertion time as `Hash` does. For most uses it should do fine
+though, and we recommend you consider `ThreadSafe::Cache` instead of
+`ThreadSafe::Hash` for your concurrency-safe hash needs. It understands some
+options when created (depending on your ruby platform) that control some of the
+internals - when unsure just leave them out:
+
+
+```ruby
+require 'thread_safe'
+
+cache = ThreadSafe::Cache.new
+```
+
+## Contributing
+
+1. Fork it
+2. Clone it (`git clone git at github.com:you/thread_safe.git`)
+3. Create your feature branch (`git checkout -b my-new-feature`)
+4. Build the jar (`rake jar`) NOTE: Requires JRuby
+5. Install dependencies (`bundle install`)
+6. Commit your changes (`git commit -am 'Added some feature'`)
+7. Push to the branch (`git push origin my-new-feature`)
+8. Create new Pull Request
diff --git a/app/server/vendor/thread_safe/Rakefile b/app/server/vendor/thread_safe/Rakefile
new file mode 100644
index 0000000..8717d2f
--- /dev/null
+++ b/app/server/vendor/thread_safe/Rakefile
@@ -0,0 +1,48 @@
+require "bundler/gem_tasks"
+require "rake/testtask"
+
+task :default => :test
+
+if defined?(JRUBY_VERSION)
+  require "ant"
+
+  directory "pkg/classes"
+  directory 'pkg/tests'
+
+  desc "Clean up build artifacts"
+  task :clean do
+    rm_rf "pkg/classes"
+    rm_rf "pkg/tests"
+    rm_rf "lib/thread_safe/jruby_cache_backend.jar"
+  end
+
+  desc "Compile the extension"
+  task :compile => "pkg/classes" do |t|
+    ant.javac :srcdir => "ext", :destdir => t.prerequisites.first,
+      :source => "1.5", :target => "1.5", :debug => true,
+      :classpath => "${java.class.path}:${sun.boot.class.path}"
+  end
+
+  desc "Build the jar"
+  task :jar => :compile do
+    ant.jar :basedir => "pkg/classes", :destfile => "lib/thread_safe/jruby_cache_backend.jar", :includes => "**/*.class"
+  end
+
+  desc "Build test jar"
+  task 'test-jar' => 'pkg/tests' do |t|
+    ant.javac :srcdir => 'test/src', :destdir => t.prerequisites.first,
+      :source => "1.5", :target => "1.5", :debug => true
+
+    ant.jar :basedir => 'pkg/tests', :destfile => 'test/package.jar', :includes => '**/*.class'
+  end
+
+  task :package => [ :jar, 'test-jar' ]
+else
+  # No need to package anything for non-jruby rubies
+  task :package
+end
+
+Rake::TestTask.new :test => :package do |t|
+  t.libs << "lib"
+  t.test_files = FileList["test/**/*.rb"]
+end
diff --git a/app/server/vendor/thread_safe/examples/bench_cache.rb b/app/server/vendor/thread_safe/examples/bench_cache.rb
new file mode 100755
index 0000000..14171c9
--- /dev/null
+++ b/app/server/vendor/thread_safe/examples/bench_cache.rb
@@ -0,0 +1,35 @@
+#!/usr/bin/env ruby -wKU
+
+require "benchmark"
+require "thread_safe"
+
+hash  = {}
+cache = ThreadSafe::Cache.new
+
+ENTRIES = 10_000
+
+ENTRIES.times do |i|
+  hash[i]  = i
+  cache[i] = i
+end
+
+TESTS = 40_000_000
+Benchmark.bmbm do |results|
+  key = rand(10_000)
+
+  results.report('Hash#[]') do
+    TESTS.times { hash[key] }
+  end
+
+  results.report('Cache#[]') do
+    TESTS.times { cache[key] }
+  end
+
+  results.report('Hash#each_pair') do
+    (TESTS / ENTRIES).times { hash.each_pair {|k,v| v} }
+  end
+
+  results.report('Cache#each_pair') do
+    (TESTS / ENTRIES).times { cache.each_pair {|k,v| v} }
+  end
+end
diff --git a/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/JRubyCacheBackendLibrary.java b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/JRubyCacheBackendLibrary.java
new file mode 100644
index 0000000..8ff7b64
--- /dev/null
+++ b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/JRubyCacheBackendLibrary.java
@@ -0,0 +1,245 @@
+package org.jruby.ext.thread_safe;
+
+import org.jruby.*;
+import org.jruby.anno.JRubyClass;
+import org.jruby.anno.JRubyMethod;
+import org.jruby.ext.thread_safe.jsr166e.ConcurrentHashMap;
+import org.jruby.ext.thread_safe.jsr166e.ConcurrentHashMapV8;
+import org.jruby.ext.thread_safe.jsr166e.nounsafe.*;
+import org.jruby.runtime.Block;
+import org.jruby.runtime.ObjectAllocator;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.runtime.load.Library;
+
+import java.io.IOException;
+import java.util.Map;
+
+import static org.jruby.runtime.Visibility.PRIVATE;
+
+/**
+ * Native Java implementation to avoid the JI overhead.
+ *
+ * @author thedarkone
+ */
+public class JRubyCacheBackendLibrary implements Library {
+    public void load(Ruby runtime, boolean wrap) throws IOException {
+        RubyClass jrubyRefClass = runtime.defineClassUnder("JRubyCacheBackend", runtime.getObject(), BACKEND_ALLOCATOR, runtime.getModule("ThreadSafe"));
+        jrubyRefClass.setAllocator(BACKEND_ALLOCATOR);
+        jrubyRefClass.defineAnnotatedMethods(JRubyCacheBackend.class);
+    }
+
+    private static final ObjectAllocator BACKEND_ALLOCATOR = new ObjectAllocator() {
+        public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+            return new JRubyCacheBackend(runtime, klazz);
+        }
+    };
+
+    @JRubyClass(name="JRubyCacheBackend", parent="Object")
+    public static class JRubyCacheBackend extends RubyObject {
+        // Defaults used by the CHM
+        static final int DEFAULT_INITIAL_CAPACITY = 16;
+        static final float DEFAULT_LOAD_FACTOR = 0.75f;
+
+        public static final boolean CAN_USE_UNSAFE_CHM = canUseUnsafeCHM();
+
+        private ConcurrentHashMap<IRubyObject, IRubyObject> map;
+
+        private static ConcurrentHashMap<IRubyObject, IRubyObject> newCHM(int initialCapacity, float loadFactor) {
+            if (CAN_USE_UNSAFE_CHM) {
+                return new ConcurrentHashMapV8<IRubyObject, IRubyObject>(initialCapacity, loadFactor);
+            } else {
+                return new org.jruby.ext.thread_safe.jsr166e.nounsafe.ConcurrentHashMapV8<IRubyObject, IRubyObject>(initialCapacity, loadFactor);
+            }
+        }
+
+        private static ConcurrentHashMap<IRubyObject, IRubyObject> newCHM() {
+            return newCHM(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
+        }
+
+        private static boolean canUseUnsafeCHM() {
+            try {
+                new org.jruby.ext.thread_safe.jsr166e.ConcurrentHashMapV8(); // force class load and initialization
+                return true;
+            } catch (Throwable t) { // ensuring we really do catch everything
+                // Doug's Unsafe setup errors always have this "Could not ini.." message
+                if (t.getMessage().contains("Could not initialize intrinsics") || isCausedBySecurityException(t)) {
+                    return false;
+                }
+                throw (t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t));
+            }
+        }
+
+        private static boolean isCausedBySecurityException(Throwable t) {
+            while (t != null) {
+                if (t instanceof SecurityException) {
+                    return true;
+                }
+                t = t.getCause();
+            }
+            return false;
+        }
+
+        public JRubyCacheBackend(Ruby runtime, RubyClass klass) {
+            super(runtime, klass);
+        }
+
+        @JRubyMethod
+        public IRubyObject initialize(ThreadContext context) {
+            map = newCHM();
+            return context.getRuntime().getNil();
+        }
+
+        @JRubyMethod
+        public IRubyObject initialize(ThreadContext context, IRubyObject options) {
+            map = toCHM(context, options);
+            return context.getRuntime().getNil();
+        }
+
+        private ConcurrentHashMap<IRubyObject, IRubyObject> toCHM(ThreadContext context, IRubyObject options) {
+            Ruby runtime = context.getRuntime();
+            if (!options.isNil() && options.respondsTo("[]")) {
+                IRubyObject rInitialCapacity = options.callMethod(context, "[]", runtime.newSymbol("initial_capacity"));
+                IRubyObject rLoadFactor      = options.callMethod(context, "[]", runtime.newSymbol("load_factor"));
+                int initialCapacity = !rInitialCapacity.isNil() ? RubyNumeric.num2int(rInitialCapacity.convertToInteger()) : DEFAULT_INITIAL_CAPACITY;
+                float loadFactor    = !rLoadFactor.isNil() ?      (float)RubyNumeric.num2dbl(rLoadFactor.convertToFloat()) : DEFAULT_LOAD_FACTOR;
+                return newCHM(initialCapacity, loadFactor);
+            } else {
+                return newCHM();
+            }
+        }
+
+        @JRubyMethod(name = "[]", required = 1)
+        public IRubyObject op_aref(ThreadContext context, IRubyObject key) {
+            IRubyObject value;
+            return ((value = map.get(key)) == null) ? context.getRuntime().getNil() : value;
+        }
+
+        @JRubyMethod(name = {"[]="}, required = 2)
+        public IRubyObject op_aset(IRubyObject key, IRubyObject value) {
+            map.put(key, value);
+            return value;
+        }
+
+        @JRubyMethod
+        public IRubyObject put_if_absent(IRubyObject key, IRubyObject value) {
+            IRubyObject result = map.putIfAbsent(key, value);
+            return result == null ? getRuntime().getNil() : result;
+        }
+
+        @JRubyMethod
+        public IRubyObject compute_if_absent(final ThreadContext context, final IRubyObject key, final Block block) {
+            return map.computeIfAbsent(key, new ConcurrentHashMap.Fun<IRubyObject, IRubyObject>() {
+                @Override
+                public IRubyObject apply(IRubyObject key) {
+                    return block.yieldSpecific(context);
+                }
+            });
+        }
+
+        @JRubyMethod
+        public IRubyObject compute_if_present(final ThreadContext context, final IRubyObject key, final Block block) {
+            IRubyObject result = map.computeIfPresent(key, new ConcurrentHashMap.BiFun<IRubyObject, IRubyObject, IRubyObject>() {
+                @Override
+                public IRubyObject apply(IRubyObject key, IRubyObject oldValue) {
+                    IRubyObject result = block.yieldSpecific(context, oldValue == null ? context.getRuntime().getNil() : oldValue);
+                    return result.isNil() ? null : result;
+                }
+            });
+            return result == null ? context.getRuntime().getNil() : result;
+        }
+
+        @JRubyMethod
+        public IRubyObject compute(final ThreadContext context, final IRubyObject key, final Block block) {
+            IRubyObject result = map.compute(key, new ConcurrentHashMap.BiFun<IRubyObject, IRubyObject, IRubyObject>() {
+                @Override
+                public IRubyObject apply(IRubyObject key, IRubyObject oldValue) {
+                    IRubyObject result = block.yieldSpecific(context, oldValue == null ? context.getRuntime().getNil() : oldValue);
+                    return result.isNil() ? null : result;
+                }
+            });
+            return result == null ? context.getRuntime().getNil() : result;
+        }
+
+        @JRubyMethod
+        public IRubyObject merge_pair(final ThreadContext context, final IRubyObject key, final IRubyObject value, final Block block) {
+            IRubyObject result = map.merge(key, value, new ConcurrentHashMap.BiFun<IRubyObject, IRubyObject, IRubyObject>() {
+                @Override
+                public IRubyObject apply(IRubyObject oldValue, IRubyObject newValue) {
+                    IRubyObject result = block.yieldSpecific(context, oldValue == null ? context.getRuntime().getNil() : oldValue);
+                    return result.isNil() ? null : result;
+                }
+            });
+            return result == null ? context.getRuntime().getNil() : result;
+        }
+
+        @JRubyMethod
+        public RubyBoolean replace_pair(IRubyObject key, IRubyObject oldValue, IRubyObject newValue) {
+            return getRuntime().newBoolean(map.replace(key, oldValue, newValue));
+        }
+
+        @JRubyMethod(name = "key?", required = 1)
+        public RubyBoolean has_key_p(IRubyObject key) {
+            return map.containsKey(key) ? getRuntime().getTrue() : getRuntime().getFalse();
+        }
+
+        @JRubyMethod
+        public IRubyObject key(IRubyObject value) {
+            final IRubyObject key = map.findKey(value);
+            return key == null ? getRuntime().getNil() : key;
+        }
+
+        @JRubyMethod
+        public IRubyObject replace_if_exists(IRubyObject key, IRubyObject value) {
+            IRubyObject result = map.replace(key, value);
+            return result == null ? getRuntime().getNil() : result;
+        }
+
+        @JRubyMethod
+        public IRubyObject get_and_set(IRubyObject key, IRubyObject value) {
+            IRubyObject result = map.put(key, value);
+            return result == null ? getRuntime().getNil() : result;
+        }
+
+        @JRubyMethod
+        public IRubyObject delete(IRubyObject key) {
+            IRubyObject result = map.remove(key);
+            return result == null ? getRuntime().getNil() : result;
+        }
+
+        @JRubyMethod
+        public RubyBoolean delete_pair(IRubyObject key, IRubyObject value) {
+            return getRuntime().newBoolean(map.remove(key, value));
+        }
+
+        @JRubyMethod
+        public IRubyObject clear() {
+            map.clear();
+            return this;
+        }
+
+        @JRubyMethod
+         public IRubyObject each_pair(ThreadContext context, Block block) {
+            for (Map.Entry<IRubyObject,IRubyObject> entry : map.entrySet()) {
+                block.yieldSpecific(context, entry.getKey(), entry.getValue());
+            }
+            return this;
+        }
+
+        @JRubyMethod
+        public RubyFixnum size(ThreadContext context) {
+            return context.getRuntime().newFixnum(map.size());
+        }
+
+        @JRubyMethod
+        public IRubyObject get_or_default(IRubyObject key, IRubyObject defaultValue) {
+            return map.getValueOrDefault(key, defaultValue);
+        }
+
+        @JRubyMethod(visibility = PRIVATE)
+        public JRubyCacheBackend initialize_copy(ThreadContext context, IRubyObject other) {
+            map = newCHM();
+            return this;
+        }
+    }
+}
diff --git a/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/ConcurrentHashMap.java b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/ConcurrentHashMap.java
new file mode 100644
index 0000000..90ae1a2
--- /dev/null
+++ b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/ConcurrentHashMap.java
@@ -0,0 +1,31 @@
+package org.jruby.ext.thread_safe.jsr166e;
+
+import java.util.Map;
+import java.util.Set;
+
+public interface ConcurrentHashMap<K, V> {
+    /** Interface describing a function of one argument */
+    public interface Fun<A,T> { T apply(A a); }
+    /** Interface describing a function of two arguments */
+    public interface BiFun<A,B,T> { T apply(A a, B b); }
+
+    public V get(K key);
+    public V put(K key, V value);
+    public V putIfAbsent(K key, V value);
+    public V computeIfAbsent(K key, Fun<? super K, ? extends V> mf);
+    public V computeIfPresent(K key, BiFun<? super K, ? super V, ? extends V> mf);
+    public V compute(K key, BiFun<? super K, ? super V, ? extends V> mf);
+    public V merge(K key, V value, BiFun<? super V, ? super V, ? extends V> mf);
+    public boolean replace(K key, V oldVal, V newVal);
+    public V replace(K key, V value);
+    public boolean containsKey(K key);
+    public boolean remove(Object key, Object value);
+    public V remove(K key);
+    public void clear();
+    public Set<Map.Entry<K,V>> entrySet();
+    public int size();
+    public V getValueOrDefault(Object key, V defaultValue);
+
+    public boolean containsValue(V value);
+    public K findKey(V value);
+}
diff --git a/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/ConcurrentHashMapV8.java b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/ConcurrentHashMapV8.java
new file mode 100644
index 0000000..c85b989
--- /dev/null
+++ b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/ConcurrentHashMapV8.java
@@ -0,0 +1,3863 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// This is based on the 1.79 version.
+
+package org.jruby.ext.thread_safe.jsr166e;
+
+import org.jruby.RubyClass;
+import org.jruby.RubyNumeric;
+import org.jruby.RubyObject;
+import org.jruby.exceptions.RaiseException;
+import org.jruby.ext.thread_safe.jsr166y.ThreadLocalRandom;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.builtin.IRubyObject;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Enumeration;
+import java.util.ConcurrentModificationException;
+import java.util.NoSuchElementException;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.locks.AbstractQueuedSynchronizer;
+
+import java.io.Serializable;
+
+/**
+ * A hash table supporting full concurrency of retrievals and
+ * high expected concurrency for updates. This class obeys the
+ * same functional specification as {@link java.util.Hashtable}, and
+ * includes versions of methods corresponding to each method of
+ * {@code Hashtable}. However, even though all operations are
+ * thread-safe, retrieval operations do <em>not</em> entail locking,
+ * and there is <em>not</em> any support for locking the entire table
+ * in a way that prevents all access.  This class is fully
+ * interoperable with {@code Hashtable} in programs that rely on its
+ * thread safety but not on its synchronization details.
+ *
+ * <p>Retrieval operations (including {@code get}) generally do not
+ * block, so may overlap with update operations (including {@code put}
+ * and {@code remove}). Retrievals reflect the results of the most
+ * recently <em>completed</em> update operations holding upon their
+ * onset. (More formally, an update operation for a given key bears a
+ * <em>happens-before</em> relation with any (non-null) retrieval for
+ * that key reporting the updated value.)  For aggregate operations
+ * such as {@code putAll} and {@code clear}, concurrent retrievals may
+ * reflect insertion or removal of only some entries.  Similarly,
+ * Iterators and Enumerations return elements reflecting the state of
+ * the hash table at some point at or since the creation of the
+ * iterator/enumeration.  They do <em>not</em> throw {@link
+ * ConcurrentModificationException}.  However, iterators are designed
+ * to be used by only one thread at a time.  Bear in mind that the
+ * results of aggregate status methods including {@code size}, {@code
+ * isEmpty}, and {@code containsValue} are typically useful only when
+ * a map is not undergoing concurrent updates in other threads.
+ * Otherwise the results of these methods reflect transient states
+ * that may be adequate for monitoring or estimation purposes, but not
+ * for program control.
+ *
+ * <p>The table is dynamically expanded when there are too many
+ * collisions (i.e., keys that have distinct hash codes but fall into
+ * the same slot modulo the table size), with the expected average
+ * effect of maintaining roughly two bins per mapping (corresponding
+ * to a 0.75 load factor threshold for resizing). There may be much
+ * variance around this average as mappings are added and removed, but
+ * overall, this maintains a commonly accepted time/space tradeoff for
+ * hash tables.  However, resizing this or any other kind of hash
+ * table may be a relatively slow operation. When possible, it is a
+ * good idea to provide a size estimate as an optional {@code
+ * initialCapacity} constructor argument. An additional optional
+ * {@code loadFactor} constructor argument provides a further means of
+ * customizing initial table capacity by specifying the table density
+ * to be used in calculating the amount of space to allocate for the
+ * given number of elements.  Also, for compatibility with previous
+ * versions of this class, constructors may optionally specify an
+ * expected {@code concurrencyLevel} as an additional hint for
+ * internal sizing.  Note that using many keys with exactly the same
+ * {@code hashCode()} is a sure way to slow down performance of any
+ * hash table.
+ *
+ * <p>A {@link Set} projection of a ConcurrentHashMapV8 may be created
+ * (using {@link #newKeySet()} or {@link #newKeySet(int)}), or viewed
+ * (using {@link #keySet(Object)} when only keys are of interest, and the
+ * mapped values are (perhaps transiently) not used or all take the
+ * same mapping value.
+ *
+ * <p>A ConcurrentHashMapV8 can be used as scalable frequency map (a
+ * form of histogram or multiset) by using {@link LongAdder} values
+ * and initializing via {@link #computeIfAbsent}. For example, to add
+ * a count to a {@code ConcurrentHashMapV8<String,LongAdder> freqs}, you
+ * can use {@code freqs.computeIfAbsent(k -> new
+ * LongAdder()).increment();}
+ *
+ * <p>This class and its views and iterators implement all of the
+ * <em>optional</em> methods of the {@link Map} and {@link Iterator}
+ * interfaces.
+ *
+ * <p>Like {@link Hashtable} but unlike {@link HashMap}, this class
+ * does <em>not</em> allow {@code null} to be used as a key or value.
+ *
+ * <p>ConcurrentHashMapV8s support parallel operations using the {@link
+ * ForkJoinPool#commonPool}. (Tasks that may be used in other contexts
+ * are available in class {@link ForkJoinTasks}). These operations are
+ * designed to be safely, and often sensibly, applied even with maps
+ * that are being concurrently updated by other threads; for example,
+ * when computing a snapshot summary of the values in a shared
+ * registry.  There are three kinds of operation, each with four
+ * forms, accepting functions with Keys, Values, Entries, and (Key,
+ * Value) arguments and/or return values. (The first three forms are
+ * also available via the {@link #keySet()}, {@link #values()} and
+ * {@link #entrySet()} views). Because the elements of a
+ * ConcurrentHashMapV8 are not ordered in any particular way, and may be
+ * processed in different orders in different parallel executions, the
+ * correctness of supplied functions should not depend on any
+ * ordering, or on any other objects or values that may transiently
+ * change while computation is in progress; and except for forEach
+ * actions, should ideally be side-effect-free.
+ *
+ * <ul>
+ * <li> forEach: Perform a given action on each element.
+ * A variant form applies a given transformation on each element
+ * before performing the action.</li>
+ *
+ * <li> search: Return the first available non-null result of
+ * applying a given function on each element; skipping further
+ * search when a result is found.</li>
+ *
+ * <li> reduce: Accumulate each element.  The supplied reduction
+ * function cannot rely on ordering (more formally, it should be
+ * both associative and commutative).  There are five variants:
+ *
+ * <ul>
+ *
+ * <li> Plain reductions. (There is not a form of this method for
+ * (key, value) function arguments since there is no corresponding
+ * return type.)</li>
+ *
+ * <li> Mapped reductions that accumulate the results of a given
+ * function applied to each element.</li>
+ *
+ * <li> Reductions to scalar doubles, longs, and ints, using a
+ * given basis value.</li>
+ *
+ * </li>
+ * </ul>
+ * </ul>
+ *
+ * <p>The concurrency properties of bulk operations follow
+ * from those of ConcurrentHashMapV8: Any non-null result returned
+ * from {@code get(key)} and related access methods bears a
+ * happens-before relation with the associated insertion or
+ * update.  The result of any bulk operation reflects the
+ * composition of these per-element relations (but is not
+ * necessarily atomic with respect to the map as a whole unless it
+ * is somehow known to be quiescent).  Conversely, because keys
+ * and values in the map are never null, null serves as a reliable
+ * atomic indicator of the current lack of any result.  To
+ * maintain this property, null serves as an implicit basis for
+ * all non-scalar reduction operations. For the double, long, and
+ * int versions, the basis should be one that, when combined with
+ * any other value, returns that other value (more formally, it
+ * should be the identity element for the reduction). Most common
+ * reductions have these properties; for example, computing a sum
+ * with basis 0 or a minimum with basis MAX_VALUE.
+ *
+ * <p>Search and transformation functions provided as arguments
+ * should similarly return null to indicate the lack of any result
+ * (in which case it is not used). In the case of mapped
+ * reductions, this also enables transformations to serve as
+ * filters, returning null (or, in the case of primitive
+ * specializations, the identity basis) if the element should not
+ * be combined. You can create compound transformations and
+ * filterings by composing them yourself under this "null means
+ * there is nothing there now" rule before using them in search or
+ * reduce operations.
+ *
+ * <p>Methods accepting and/or returning Entry arguments maintain
+ * key-value associations. They may be useful for example when
+ * finding the key for the greatest value. Note that "plain" Entry
+ * arguments can be supplied using {@code new
+ * AbstractMap.SimpleEntry(k,v)}.
+ *
+ * <p>Bulk operations may complete abruptly, throwing an
+ * exception encountered in the application of a supplied
+ * function. Bear in mind when handling such exceptions that other
+ * concurrently executing functions could also have thrown
+ * exceptions, or would have done so if the first exception had
+ * not occurred.
+ *
+ * <p>Parallel speedups for bulk operations compared to sequential
+ * processing are common but not guaranteed.  Operations involving
+ * brief functions on small maps may execute more slowly than
+ * sequential loops if the underlying work to parallelize the
+ * computation is more expensive than the computation itself.
+ * Similarly, parallelization may not lead to much actual parallelism
+ * if all processors are busy performing unrelated tasks.
+ *
+ * <p>All arguments to all task methods must be non-null.
+ *
+ * <p><em>jsr166e note: During transition, this class
+ * uses nested functional interfaces with different names but the
+ * same forms as those expected for JDK8.</em>
+ *
+ * <p>This class is a member of the
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ * Java Collections Framework</a>.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <K> the type of keys maintained by this map
+ * @param <V> the type of mapped values
+ */
+public class ConcurrentHashMapV8<K, V>
+        implements ConcurrentMap<K, V>, Serializable, ConcurrentHashMap<K, V> {
+    private static final long serialVersionUID = 7249069246763182397L;
+
+    /**
+     * A partitionable iterator. A Spliterator can be traversed
+     * directly, but can also be partitioned (before traversal) by
+     * creating another Spliterator that covers a non-overlapping
+     * portion of the elements, and so may be amenable to parallel
+     * execution.
+     *
+     * <p>This interface exports a subset of expected JDK8
+     * functionality.
+     *
+     * <p>Sample usage: Here is one (of the several) ways to compute
+     * the sum of the values held in a map using the ForkJoin
+     * framework. As illustrated here, Spliterators are well suited to
+     * designs in which a task repeatedly splits off half its work
+     * into forked subtasks until small enough to process directly,
+     * and then joins these subtasks. Variants of this style can also
+     * be used in completion-based designs.
+     *
+     * <pre>
+     * {@code ConcurrentHashMapV8<String, Long> m = ...
+     * // split as if have 8 * parallelism, for load balance
+     * int n = m.size();
+     * int p = aForkJoinPool.getParallelism() * 8;
+     * int split = (n < p)? n : p;
+     * long sum = aForkJoinPool.invoke(new SumValues(m.valueSpliterator(), split, null));
+     * // ...
+     * static class SumValues extends RecursiveTask<Long> {
+     *   final Spliterator<Long> s;
+     *   final int split;             // split while > 1
+     *   final SumValues nextJoin;    // records forked subtasks to join
+     *   SumValues(Spliterator<Long> s, int depth, SumValues nextJoin) {
+     *     this.s = s; this.depth = depth; this.nextJoin = nextJoin;
+     *   }
+     *   public Long compute() {
+     *     long sum = 0;
+     *     SumValues subtasks = null; // fork subtasks
+     *     for (int s = split >>> 1; s > 0; s >>>= 1)
+     *       (subtasks = new SumValues(s.split(), s, subtasks)).fork();
+     *     while (s.hasNext())        // directly process remaining elements
+     *       sum += s.next();
+     *     for (SumValues t = subtasks; t != null; t = t.nextJoin)
+     *       sum += t.join();         // collect subtask results
+     *     return sum;
+     *   }
+     * }
+     * }</pre>
+     */
+    public static interface Spliterator<T> extends Iterator<T> {
+        /**
+         * Returns a Spliterator covering approximately half of the
+         * elements, guaranteed not to overlap with those subsequently
+         * returned by this Spliterator.  After invoking this method,
+         * the current Spliterator will <em>not</em> produce any of
+         * the elements of the returned Spliterator, but the two
+         * Spliterators together will produce all of the elements that
+         * would have been produced by this Spliterator had this
+         * method not been called. The exact number of elements
+         * produced by the returned Spliterator is not guaranteed, and
+         * may be zero (i.e., with {@code hasNext()} reporting {@code
+         * false}) if this Spliterator cannot be further split.
+         *
+         * @return a Spliterator covering approximately half of the
+         * elements
+         * @throws IllegalStateException if this Spliterator has
+         * already commenced traversing elements
+         */
+        Spliterator<T> split();
+    }
+
+
+    /*
+     * Overview:
+     *
+     * The primary design goal of this hash table is to maintain
+     * concurrent readability (typically method get(), but also
+     * iterators and related methods) while minimizing update
+     * contention. Secondary goals are to keep space consumption about
+     * the same or better than java.util.HashMap, and to support high
+     * initial insertion rates on an empty table by many threads.
+     *
+     * Each key-value mapping is held in a Node.  Because Node fields
+     * can contain special values, they are defined using plain Object
+     * types. Similarly in turn, all internal methods that use them
+     * work off Object types. And similarly, so do the internal
+     * methods of auxiliary iterator and view classes.  All public
+     * generic typed methods relay in/out of these internal methods,
+     * supplying null-checks and casts as needed. This also allows
+     * many of the public methods to be factored into a smaller number
+     * of internal methods (although sadly not so for the five
+     * variants of put-related operations). The validation-based
+     * approach explained below leads to a lot of code sprawl because
+     * retry-control precludes factoring into smaller methods.
+     *
+     * The table is lazily initialized to a power-of-two size upon the
+     * first insertion.  Each bin in the table normally contains a
+     * list of Nodes (most often, the list has only zero or one Node).
+     * Table accesses require volatile/atomic reads, writes, and
+     * CASes.  Because there is no other way to arrange this without
+     * adding further indirections, we use intrinsics
+     * (sun.misc.Unsafe) operations.  The lists of nodes within bins
+     * are always accurately traversable under volatile reads, so long
+     * as lookups check hash code and non-nullness of value before
+     * checking key equality.
+     *
+     * We use the top two bits of Node hash fields for control
+     * purposes -- they are available anyway because of addressing
+     * constraints.  As explained further below, these top bits are
+     * used as follows:
+     *  00 - Normal
+     *  01 - Locked
+     *  11 - Locked and may have a thread waiting for lock
+     *  10 - Node is a forwarding node
+     *
+     * The lower 30 bits of each Node's hash field contain a
+     * transformation of the key's hash code, except for forwarding
+     * nodes, for which the lower bits are zero (and so always have
+     * hash field == MOVED).
+     *
+     * Insertion (via put or its variants) of the first node in an
+     * empty bin is performed by just CASing it to the bin.  This is
+     * by far the most common case for put operations under most
+     * key/hash distributions.  Other update operations (insert,
+     * delete, and replace) require locks.  We do not want to waste
+     * the space required to associate a distinct lock object with
+     * each bin, so instead use the first node of a bin list itself as
+     * a lock. Blocking support for these locks relies on the builtin
+     * "synchronized" monitors.  However, we also need a tryLock
+     * construction, so we overlay these by using bits of the Node
+     * hash field for lock control (see above), and so normally use
+     * builtin monitors only for blocking and signalling using
+     * wait/notifyAll constructions. See Node.tryAwaitLock.
+     *
+     * Using the first node of a list as a lock does not by itself
+     * suffice though: When a node is locked, any update must first
+     * validate that it is still the first node after locking it, and
+     * retry if not. Because new nodes are always appended to lists,
+     * once a node is first in a bin, it remains first until deleted
+     * or the bin becomes invalidated (upon resizing).  However,
+     * operations that only conditionally update may inspect nodes
+     * until the point of update. This is a converse of sorts to the
+     * lazy locking technique described by Herlihy & Shavit.
+     *
+     * The main disadvantage of per-bin locks is that other update
+     * operations on other nodes in a bin list protected by the same
+     * lock can stall, for example when user equals() or mapping
+     * functions take a long time.  However, statistically, under
+     * random hash codes, this is not a common problem.  Ideally, the
+     * frequency of nodes in bins follows a Poisson distribution
+     * (http://en.wikipedia.org/wiki/Poisson_distribution) with a
+     * parameter of about 0.5 on average, given the resizing threshold
+     * of 0.75, although with a large variance because of resizing
+     * granularity. Ignoring variance, the expected occurrences of
+     * list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The
+     * first values are:
+     *
+     * 0:    0.60653066
+     * 1:    0.30326533
+     * 2:    0.07581633
+     * 3:    0.01263606
+     * 4:    0.00157952
+     * 5:    0.00015795
+     * 6:    0.00001316
+     * 7:    0.00000094
+     * 8:    0.00000006
+     * more: less than 1 in ten million
+     *
+     * Lock contention probability for two threads accessing distinct
+     * elements is roughly 1 / (8 * #elements) under random hashes.
+     *
+     * Actual hash code distributions encountered in practice
+     * sometimes deviate significantly from uniform randomness.  This
+     * includes the case when N > (1<<30), so some keys MUST collide.
+     * Similarly for dumb or hostile usages in which multiple keys are
+     * designed to have identical hash codes. Also, although we guard
+     * against the worst effects of this (see method spread), sets of
+     * hashes may differ only in bits that do not impact their bin
+     * index for a given power-of-two mask.  So we use a secondary
+     * strategy that applies when the number of nodes in a bin exceeds
+     * a threshold, and at least one of the keys implements
+     * Comparable.  These TreeBins use a balanced tree to hold nodes
+     * (a specialized form of red-black trees), bounding search time
+     * to O(log N).  Each search step in a TreeBin is around twice as
+     * slow as in a regular list, but given that N cannot exceed
+     * (1<<64) (before running out of addresses) this bounds search
+     * steps, lock hold times, etc, to reasonable constants (roughly
+     * 100 nodes inspected per operation worst case) so long as keys
+     * are Comparable (which is very common -- String, Long, etc).
+     * TreeBin nodes (TreeNodes) also maintain the same "next"
+     * traversal pointers as regular nodes, so can be traversed in
+     * iterators in the same way.
+     *
+     * The table is resized when occupancy exceeds a percentage
+     * threshold (nominally, 0.75, but see below).  Only a single
+     * thread performs the resize (using field "sizeCtl", to arrange
+     * exclusion), but the table otherwise remains usable for reads
+     * and updates. Resizing proceeds by transferring bins, one by
+     * one, from the table to the next table.  Because we are using
+     * power-of-two expansion, the elements from each bin must either
+     * stay at same index, or move with a power of two offset. We
+     * eliminate unnecessary node creation by catching cases where old
+     * nodes can be reused because their next fields won't change.  On
+     * average, only about one-sixth of them need cloning when a table
+     * doubles. The nodes they replace will be garbage collectable as
+     * soon as they are no longer referenced by any reader thread that
+     * may be in the midst of concurrently traversing table.  Upon
+     * transfer, the old table bin contains only a special forwarding
+     * node (with hash field "MOVED") that contains the next table as
+     * its key. On encountering a forwarding node, access and update
+     * operations restart, using the new table.
+     *
+     * Each bin transfer requires its bin lock. However, unlike other
+     * cases, a transfer can skip a bin if it fails to acquire its
+     * lock, and revisit it later (unless it is a TreeBin). Method
+     * rebuild maintains a buffer of TRANSFER_BUFFER_SIZE bins that
+     * have been skipped because of failure to acquire a lock, and
+     * blocks only if none are available (i.e., only very rarely).
+     * The transfer operation must also ensure that all accessible
+     * bins in both the old and new table are usable by any traversal.
+     * When there are no lock acquisition failures, this is arranged
+     * simply by proceeding from the last bin (table.length - 1) up
+     * towards the first.  Upon seeing a forwarding node, traversals
+     * (see class Iter) arrange to move to the new table
+     * without revisiting nodes.  However, when any node is skipped
+     * during a transfer, all earlier table bins may have become
+     * visible, so are initialized with a reverse-forwarding node back
+     * to the old table until the new ones are established. (This
+     * sometimes requires transiently locking a forwarding node, which
+     * is possible under the above encoding.) These more expensive
+     * mechanics trigger only when necessary.
+     *
+     * The traversal scheme also applies to partial traversals of
+     * ranges of bins (via an alternate Traverser constructor)
+     * to support partitioned aggregate operations.  Also, read-only
+     * operations give up if ever forwarded to a null table, which
+     * provides support for shutdown-style clearing, which is also not
+     * currently implemented.
+     *
+     * Lazy table initialization minimizes footprint until first use,
+     * and also avoids resizings when the first operation is from a
+     * putAll, constructor with map argument, or deserialization.
+     * These cases attempt to override the initial capacity settings,
+     * but harmlessly fail to take effect in cases of races.
+     *
+     * The element count is maintained using a LongAdder, which avoids
+     * contention on updates but can encounter cache thrashing if read
+     * too frequently during concurrent access. To avoid reading so
+     * often, resizing is attempted either when a bin lock is
+     * contended, or upon adding to a bin already holding two or more
+     * nodes (checked before adding in the xIfAbsent methods, after
+     * adding in others). Under uniform hash distributions, the
+     * probability of this occurring at threshold is around 13%,
+     * meaning that only about 1 in 8 puts check threshold (and after
+     * resizing, many fewer do so). But this approximation has high
+     * variance for small table sizes, so we check on any collision
+     * for sizes <= 64. The bulk putAll operation further reduces
+     * contention by only committing count updates upon these size
+     * checks.
+     *
+     * Maintaining API and serialization compatibility with previous
+     * versions of this class introduces several oddities. Mainly: We
+     * leave untouched but unused constructor arguments refering to
+     * concurrencyLevel. We accept a loadFactor constructor argument,
+     * but apply it only to initial table capacity (which is the only
+     * time that we can guarantee to honor it.) We also declare an
+     * unused "Segment" class that is instantiated in minimal form
+     * only when serializing.
+     */
+
+    /* ---------------- Constants -------------- */
+
+    /**
+     * The largest possible table capacity.  This value must be
+     * exactly 1<<30 to stay within Java array allocation and indexing
+     * bounds for power of two table sizes, and is further required
+     * because the top two bits of 32bit hash fields are used for
+     * control purposes.
+     */
+    private static final int MAXIMUM_CAPACITY = 1 << 30;
+
+    /**
+     * The default initial table capacity.  Must be a power of 2
+     * (i.e., at least 1) and at most MAXIMUM_CAPACITY.
+     */
+    private static final int DEFAULT_CAPACITY = 16;
+
+    /**
+     * The largest possible (non-power of two) array size.
+     * Needed by toArray and related methods.
+     */
+    static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+    /**
+     * The default concurrency level for this table. Unused but
+     * defined for compatibility with previous versions of this class.
+     */
+    private static final int DEFAULT_CONCURRENCY_LEVEL = 16;
+
+    /**
+     * The load factor for this table. Overrides of this value in
+     * constructors affect only the initial table capacity.  The
+     * actual floating point value isn't normally used -- it is
+     * simpler to use expressions such as {@code n - (n >>> 2)} for
+     * the associated resizing threshold.
+     */
+    private static final float LOAD_FACTOR = 0.75f;
+
+    /**
+     * The buffer size for skipped bins during transfers. The
+     * value is arbitrary but should be large enough to avoid
+     * most locking stalls during resizes.
+     */
+    private static final int TRANSFER_BUFFER_SIZE = 32;
+
+    /**
+     * The bin count threshold for using a tree rather than list for a
+     * bin.  The value reflects the approximate break-even point for
+     * using tree-based operations.
+     * Note that Doug's version defaults to 8, but when dealing with
+     * Ruby objects it is actually beneficial to avoid TreeNodes
+     * as long as possible as it usually means going into Ruby land.
+     */
+    private static final int TREE_THRESHOLD = 16;
+
+    /*
+     * Encodings for special uses of Node hash fields. See above for
+     * explanation.
+     */
+    static final int MOVED     = 0x80000000; // hash field for forwarding nodes
+    static final int LOCKED    = 0x40000000; // set/tested only as a bit
+    static final int WAITING   = 0xc0000000; // both bits set/tested together
+    static final int HASH_BITS = 0x3fffffff; // usable bits of normal node hash
+
+    /* ---------------- Fields -------------- */
+
+    /**
+     * The array of bins. Lazily initialized upon first insertion.
+     * Size is always a power of two. Accessed directly by iterators.
+     */
+    transient volatile Node[] table;
+
+    /**
+     * The counter maintaining number of elements.
+     */
+    private transient final LongAdder counter;
+
+    /**
+     * Table initialization and resizing control.  When negative, the
+     * table is being initialized or resized. Otherwise, when table is
+     * null, holds the initial table size to use upon creation, or 0
+     * for default. After initialization, holds the next element count
+     * value upon which to resize the table.
+     */
+    private transient volatile int sizeCtl;
+
+    // views
+    private transient KeySetView<K,V> keySet;
+    private transient ValuesView<K,V> values;
+    private transient EntrySetView<K,V> entrySet;
+
+    /** For serialization compatibility. Null unless serialized; see below */
+    private Segment<K,V>[] segments;
+
+    /* ---------------- Table element access -------------- */
+
+    /*
+     * Volatile access methods are used for table elements as well as
+     * elements of in-progress next table while resizing.  Uses are
+     * null checked by callers, and implicitly bounds-checked, relying
+     * on the invariants that tab arrays have non-zero size, and all
+     * indices are masked with (tab.length - 1) which is never
+     * negative and always less than length. Note that, to be correct
+     * wrt arbitrary concurrency errors by users, bounds checks must
+     * operate on local variables, which accounts for some odd-looking
+     * inline assignments below.
+     */
+
+    static final Node tabAt(Node[] tab, int i) { // used by Iter
+        return (Node)UNSAFE.getObjectVolatile(tab, ((long)i<<ASHIFT)+ABASE);
+    }
+
+    private static final boolean casTabAt(Node[] tab, int i, Node c, Node v) {
+        return UNSAFE.compareAndSwapObject(tab, ((long)i<<ASHIFT)+ABASE, c, v);
+    }
+
+    private static final void setTabAt(Node[] tab, int i, Node v) {
+        UNSAFE.putObjectVolatile(tab, ((long)i<<ASHIFT)+ABASE, v);
+    }
+
+    /* ---------------- Nodes -------------- */
+
+    /**
+     * Key-value entry. Note that this is never exported out as a
+     * user-visible Map.Entry (see MapEntry below). Nodes with a hash
+     * field of MOVED are special, and do not contain user keys or
+     * values.  Otherwise, keys are never null, and null val fields
+     * indicate that a node is in the process of being deleted or
+     * created. For purposes of read-only access, a key may be read
+     * before a val, but can only be used after checking val to be
+     * non-null.
+     */
+    static class Node {
+        volatile int hash;
+        final Object key;
+        volatile Object val;
+        volatile Node next;
+
+        Node(int hash, Object key, Object val, Node next) {
+            this.hash = hash;
+            this.key = key;
+            this.val = val;
+            this.next = next;
+        }
+
+        /** CompareAndSet the hash field */
+        final boolean casHash(int cmp, int val) {
+            return UNSAFE.compareAndSwapInt(this, hashOffset, cmp, val);
+        }
+
+        /** The number of spins before blocking for a lock */
+        static final int MAX_SPINS =
+                Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1;
+
+        /**
+         * Spins a while if LOCKED bit set and this node is the first
+         * of its bin, and then sets WAITING bits on hash field and
+         * blocks (once) if they are still set.  It is OK for this
+         * method to return even if lock is not available upon exit,
+         * which enables these simple single-wait mechanics.
+         *
+         * The corresponding signalling operation is performed within
+         * callers: Upon detecting that WAITING has been set when
+         * unlocking lock (via a failed CAS from non-waiting LOCKED
+         * state), unlockers acquire the sync lock and perform a
+         * notifyAll.
+         *
+         * The initial sanity check on tab and bounds is not currently
+         * necessary in the only usages of this method, but enables
+         * use in other future contexts.
+         */
+        final void tryAwaitLock(Node[] tab, int i) {
+            if (tab != null && i >= 0 && i < tab.length) { // sanity check
+                int r = ThreadLocalRandom.current().nextInt(); // randomize spins
+                int spins = MAX_SPINS, h;
+                while (tabAt(tab, i) == this && ((h = hash) & LOCKED) != 0) {
+                    if (spins >= 0) {
+                        r ^= r << 1; r ^= r >>> 3; r ^= r << 10; // xorshift
+                        if (r >= 0 && --spins == 0)
+                            Thread.yield();  // yield before block
+                    }
+                    else if (casHash(h, h | WAITING)) {
+                        synchronized (this) {
+                            if (tabAt(tab, i) == this &&
+                                    (hash & WAITING) == WAITING) {
+                                try {
+                                    wait();
+                                } catch (InterruptedException ie) {
+                                    Thread.currentThread().interrupt();
+                                }
+                            }
+                            else
+                                notifyAll(); // possibly won race vs signaller
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+
+        // Unsafe mechanics for casHash
+        private static final sun.misc.Unsafe UNSAFE;
+        private static final long hashOffset;
+
+        static {
+            try {
+                UNSAFE = getUnsafe();
+                Class<?> k = Node.class;
+                hashOffset = UNSAFE.objectFieldOffset
+                        (k.getDeclaredField("hash"));
+            } catch (Exception e) {
+                throw new Error(e);
+            }
+        }
+    }
+
+    /* ---------------- TreeBins -------------- */
+
+    /**
+     * Nodes for use in TreeBins
+     */
+    static final class TreeNode extends Node {
+        TreeNode parent;  // red-black tree links
+        TreeNode left;
+        TreeNode right;
+        TreeNode prev;    // needed to unlink next upon deletion
+        boolean red;
+
+        TreeNode(int hash, Object key, Object val, Node next, TreeNode parent) {
+            super(hash, key, val, next);
+            this.parent = parent;
+        }
+    }
+
+    /**
+     * A specialized form of red-black tree for use in bins
+     * whose size exceeds a threshold.
+     *
+     * TreeBins use a special form of comparison for search and
+     * related operations (which is the main reason we cannot use
+     * existing collections such as TreeMaps). TreeBins contain
+     * Comparable elements, but may contain others, as well as
+     * elements that are Comparable but not necessarily Comparable<T>
+     * for the same T, so we cannot invoke compareTo among them. To
+     * handle this, the tree is ordered primarily by hash value, then
+     * by getClass().getName() order, and then by Comparator order
+     * among elements of the same class.  On lookup at a node, if
+     * elements are not comparable or compare as 0, both left and
+     * right children may need to be searched in the case of tied hash
+     * values. (This corresponds to the full list search that would be
+     * necessary if all elements were non-Comparable and had tied
+     * hashes.)  The red-black balancing code is updated from
+     * pre-jdk-collections
+     * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java)
+     * based in turn on Cormen, Leiserson, and Rivest "Introduction to
+     * Algorithms" (CLR).
+     *
+     * TreeBins also maintain a separate locking discipline than
+     * regular bins. Because they are forwarded via special MOVED
+     * nodes at bin heads (which can never change once established),
+     * we cannot use those nodes as locks. Instead, TreeBin
+     * extends AbstractQueuedSynchronizer to support a simple form of
+     * read-write lock. For update operations and table validation,
+     * the exclusive form of lock behaves in the same way as bin-head
+     * locks. However, lookups use shared read-lock mechanics to allow
+     * multiple readers in the absence of writers.  Additionally,
+     * these lookups do not ever block: While the lock is not
+     * available, they proceed along the slow traversal path (via
+     * next-pointers) until the lock becomes available or the list is
+     * exhausted, whichever comes first. (These cases are not fast,
+     * but maximize aggregate expected throughput.)  The AQS mechanics
+     * for doing this are straightforward.  The lock state is held as
+     * AQS getState().  Read counts are negative; the write count (1)
+     * is positive.  There are no signalling preferences among readers
+     * and writers. Since we don't need to export full Lock API, we
+     * just override the minimal AQS methods and use them directly.
+     */
+    static final class TreeBin extends AbstractQueuedSynchronizer {
+        private static final long serialVersionUID = 2249069246763182397L;
+        transient TreeNode root;  // root of tree
+        transient TreeNode first; // head of next-pointer list
+
+        /* AQS overrides */
+        public final boolean isHeldExclusively() { return getState() > 0; }
+        public final boolean tryAcquire(int ignore) {
+            if (compareAndSetState(0, 1)) {
+                setExclusiveOwnerThread(Thread.currentThread());
+                return true;
+            }
+            return false;
+        }
+        public final boolean tryRelease(int ignore) {
+            setExclusiveOwnerThread(null);
+            setState(0);
+            return true;
+        }
+        public final int tryAcquireShared(int ignore) {
+            for (int c;;) {
+                if ((c = getState()) > 0)
+                    return -1;
+                if (compareAndSetState(c, c -1))
+                    return 1;
+            }
+        }
+        public final boolean tryReleaseShared(int ignore) {
+            int c;
+            do {} while (!compareAndSetState(c = getState(), c + 1));
+            return c == -1;
+        }
+
+        /** From CLR */
+        private void rotateLeft(TreeNode p) {
+            if (p != null) {
+                TreeNode r = p.right, pp, rl;
+                if ((rl = p.right = r.left) != null)
+                    rl.parent = p;
+                if ((pp = r.parent = p.parent) == null)
+                    root = r;
+                else if (pp.left == p)
+                    pp.left = r;
+                else
+                    pp.right = r;
+                r.left = p;
+                p.parent = r;
+            }
+        }
+
+        /** From CLR */
+        private void rotateRight(TreeNode p) {
+            if (p != null) {
+                TreeNode l = p.left, pp, lr;
+                if ((lr = p.left = l.right) != null)
+                    lr.parent = p;
+                if ((pp = l.parent = p.parent) == null)
+                    root = l;
+                else if (pp.right == p)
+                    pp.right = l;
+                else
+                    pp.left = l;
+                l.right = p;
+                p.parent = l;
+            }
+        }
+
+        @SuppressWarnings("unchecked") final TreeNode getTreeNode
+        (int h, Object k, TreeNode p) {
+            return getTreeNode(h, (RubyObject)k, p);
+        }
+
+        /**
+         * Returns the TreeNode (or null if not found) for the given key
+         * starting at given root.
+         */
+        @SuppressWarnings("unchecked") final TreeNode getTreeNode
+        (int h, RubyObject k, TreeNode p) {
+            RubyClass c = k.getMetaClass(); boolean kNotComparable = !k.respondsTo("<=>");
+            while (p != null) {
+                int dir, ph;  RubyObject pk; RubyClass pc;
+                if ((ph = p.hash) == h) {
+                    if ((pk = (RubyObject)p.key) == k || k.equals(pk))
+                        return p;
+                    if (c != (pc = (RubyClass)pk.getMetaClass()) ||
+                            kNotComparable ||
+                            (dir = rubyCompare(k, pk)) == 0) {
+                        dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName());
+                        if (dir == 0) { // if still stuck, need to check both sides
+                            TreeNode r = null, pl, pr;
+                            // try to recurse on the right
+                            if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null)
+                                return r;
+                            // try to continue iterating on the left side
+                            else if ((pl = p.left) != null && h <= pl.hash)
+                                dir = -1;
+                            else // no matching node found
+                                return null;
+                        }
+                    }
+                }
+                else
+                    dir = (h < ph) ? -1 : 1;
+                p = (dir > 0) ? p.right : p.left;
+            }
+            return null;
+        }
+
+        int rubyCompare(RubyObject l, RubyObject r) {
+            ThreadContext context = l.getMetaClass().getRuntime().getCurrentContext();
+            IRubyObject result;
+            try {
+                result = l.callMethod(context, "<=>", r);
+            } catch (RaiseException e) {
+                // handle objects "lying" about responding to <=>, ie: an Array containing non-comparable keys
+                if (context.runtime.getNoMethodError().isInstance(e.getException())) {
+                    return 0;
+                }
+                throw e;
+            }
+
+            return result.isNil() ? 0 : RubyNumeric.num2int(result.convertToInteger());
+        }
+
+        /**
+         * Wrapper for getTreeNode used by CHM.get. Tries to obtain
+         * read-lock to call getTreeNode, but during failure to get
+         * lock, searches along next links.
+         */
+        final Object getValue(int h, Object k) {
+            Node r = null;
+            int c = getState(); // Must read lock state first
+            for (Node e = first; e != null; e = e.next) {
+                if (c <= 0 && compareAndSetState(c, c - 1)) {
+                    try {
+                        r = getTreeNode(h, k, root);
+                    } finally {
+                        releaseShared(0);
+                    }
+                    break;
+                }
+                else if ((e.hash & HASH_BITS) == h && k.equals(e.key)) {
+                    r = e;
+                    break;
+                }
+                else
+                    c = getState();
+            }
+            return r == null ? null : r.val;
+        }
+
+        @SuppressWarnings("unchecked") final TreeNode putTreeNode
+                (int h, Object k, Object v) {
+            return putTreeNode(h, (RubyObject)k, v);
+        }
+
+        /**
+         * Finds or adds a node.
+         * @return null if added
+         */
+        @SuppressWarnings("unchecked") final TreeNode putTreeNode
+        (int h, RubyObject k, Object v) {
+            RubyClass c = k.getMetaClass();
+            boolean kNotComparable = !k.respondsTo("<=>");
+            TreeNode pp = root, p = null;
+            int dir = 0;
+            while (pp != null) { // find existing node or leaf to insert at
+                int ph;  RubyObject pk; RubyClass pc;
+                p = pp;
+                if ((ph = p.hash) == h) {
+                    if ((pk = (RubyObject)p.key) == k || k.equals(pk))
+                        return p;
+                    if (c != (pc = pk.getMetaClass()) ||
+                            kNotComparable ||
+                            (dir = rubyCompare(k, pk)) == 0) {
+                        dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName());
+                        if (dir == 0) { // if still stuck, need to check both sides
+                            TreeNode r = null, pr;
+                            // try to recurse on the right
+                            if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null)
+                                return r;
+                            else // continue descending down the left subtree
+                                dir = -1;
+                        }
+                    }
+                }
+                else
+                    dir = (h < ph) ? -1 : 1;
+                pp = (dir > 0) ? p.right : p.left;
+            }
+
+            TreeNode f = first;
+            TreeNode x = first = new TreeNode(h, (Object)k, v, f, p);
+            if (p == null)
+                root = x;
+            else { // attach and rebalance; adapted from CLR
+                TreeNode xp, xpp;
+                if (f != null)
+                    f.prev = x;
+                if (dir <= 0)
+                    p.left = x;
+                else
+                    p.right = x;
+                x.red = true;
+                while (x != null && (xp = x.parent) != null && xp.red &&
+                        (xpp = xp.parent) != null) {
+                    TreeNode xppl = xpp.left;
+                    if (xp == xppl) {
+                        TreeNode y = xpp.right;
+                        if (y != null && y.red) {
+                            y.red = false;
+                            xp.red = false;
+                            xpp.red = true;
+                            x = xpp;
+                        }
+                        else {
+                            if (x == xp.right) {
+                                rotateLeft(x = xp);
+                                xpp = (xp = x.parent) == null ? null : xp.parent;
+                            }
+                            if (xp != null) {
+                                xp.red = false;
+                                if (xpp != null) {
+                                    xpp.red = true;
+                                    rotateRight(xpp);
+                                }
+                            }
+                        }
+                    }
+                    else {
+                        TreeNode y = xppl;
+                        if (y != null && y.red) {
+                            y.red = false;
+                            xp.red = false;
+                            xpp.red = true;
+                            x = xpp;
+                        }
+                        else {
+                            if (x == xp.left) {
+                                rotateRight(x = xp);
+                                xpp = (xp = x.parent) == null ? null : xp.parent;
+                            }
+                            if (xp != null) {
+                                xp.red = false;
+                                if (xpp != null) {
+                                    xpp.red = true;
+                                    rotateLeft(xpp);
+                                }
+                            }
+                        }
+                    }
+                }
+                TreeNode r = root;
+                if (r != null && r.red)
+                    r.red = false;
+            }
+            return null;
+        }
+
+        /**
+         * Removes the given node, that must be present before this
+         * call.  This is messier than typical red-black deletion code
+         * because we cannot swap the contents of an interior node
+         * with a leaf successor that is pinned by "next" pointers
+         * that are accessible independently of lock. So instead we
+         * swap the tree linkages.
+         */
+        final void deleteTreeNode(TreeNode p) {
+            TreeNode next = (TreeNode)p.next; // unlink traversal pointers
+            TreeNode pred = p.prev;
+            if (pred == null)
+                first = next;
+            else
+                pred.next = next;
+            if (next != null)
+                next.prev = pred;
+            TreeNode replacement;
+            TreeNode pl = p.left;
+            TreeNode pr = p.right;
+            if (pl != null && pr != null) {
+                TreeNode s = pr, sl;
+                while ((sl = s.left) != null) // find successor
+                    s = sl;
+                boolean c = s.red; s.red = p.red; p.red = c; // swap colors
+                TreeNode sr = s.right;
+                TreeNode pp = p.parent;
+                if (s == pr) { // p was s's direct parent
+                    p.parent = s;
+                    s.right = p;
+                }
+                else {
+                    TreeNode sp = s.parent;
+                    if ((p.parent = sp) != null) {
+                        if (s == sp.left)
+                            sp.left = p;
+                        else
+                            sp.right = p;
+                    }
+                    if ((s.right = pr) != null)
+                        pr.parent = s;
+                }
+                p.left = null;
+                if ((p.right = sr) != null)
+                    sr.parent = p;
+                if ((s.left = pl) != null)
+                    pl.parent = s;
+                if ((s.parent = pp) == null)
+                    root = s;
+                else if (p == pp.left)
+                    pp.left = s;
+                else
+                    pp.right = s;
+                replacement = sr;
+            }
+            else
+                replacement = (pl != null) ? pl : pr;
+            TreeNode pp = p.parent;
+            if (replacement == null) {
+                if (pp == null) {
+                    root = null;
+                    return;
+                }
+                replacement = p;
+            }
+            else {
+                replacement.parent = pp;
+                if (pp == null)
+                    root = replacement;
+                else if (p == pp.left)
+                    pp.left = replacement;
+                else
+                    pp.right = replacement;
+                p.left = p.right = p.parent = null;
+            }
+            if (!p.red) { // rebalance, from CLR
+                TreeNode x = replacement;
+                while (x != null) {
+                    TreeNode xp, xpl;
+                    if (x.red || (xp = x.parent) == null) {
+                        x.red = false;
+                        break;
+                    }
+                    if (x == (xpl = xp.left)) {
+                        TreeNode sib = xp.right;
+                        if (sib != null && sib.red) {
+                            sib.red = false;
+                            xp.red = true;
+                            rotateLeft(xp);
+                            sib = (xp = x.parent) == null ? null : xp.right;
+                        }
+                        if (sib == null)
+                            x = xp;
+                        else {
+                            TreeNode sl = sib.left, sr = sib.right;
+                            if ((sr == null || !sr.red) &&
+                                    (sl == null || !sl.red)) {
+                                sib.red = true;
+                                x = xp;
+                            }
+                            else {
+                                if (sr == null || !sr.red) {
+                                    if (sl != null)
+                                        sl.red = false;
+                                    sib.red = true;
+                                    rotateRight(sib);
+                                    sib = (xp = x.parent) == null ? null : xp.right;
+                                }
+                                if (sib != null) {
+                                    sib.red = (xp == null) ? false : xp.red;
+                                    if ((sr = sib.right) != null)
+                                        sr.red = false;
+                                }
+                                if (xp != null) {
+                                    xp.red = false;
+                                    rotateLeft(xp);
+                                }
+                                x = root;
+                            }
+                        }
+                    }
+                    else { // symmetric
+                        TreeNode sib = xpl;
+                        if (sib != null && sib.red) {
+                            sib.red = false;
+                            xp.red = true;
+                            rotateRight(xp);
+                            sib = (xp = x.parent) == null ? null : xp.left;
+                        }
+                        if (sib == null)
+                            x = xp;
+                        else {
+                            TreeNode sl = sib.left, sr = sib.right;
+                            if ((sl == null || !sl.red) &&
+                                    (sr == null || !sr.red)) {
+                                sib.red = true;
+                                x = xp;
+                            }
+                            else {
+                                if (sl == null || !sl.red) {
+                                    if (sr != null)
+                                        sr.red = false;
+                                    sib.red = true;
+                                    rotateLeft(sib);
+                                    sib = (xp = x.parent) == null ? null : xp.left;
+                                }
+                                if (sib != null) {
+                                    sib.red = (xp == null) ? false : xp.red;
+                                    if ((sl = sib.left) != null)
+                                        sl.red = false;
+                                }
+                                if (xp != null) {
+                                    xp.red = false;
+                                    rotateRight(xp);
+                                }
+                                x = root;
+                            }
+                        }
+                    }
+                }
+            }
+            if (p == replacement && (pp = p.parent) != null) {
+                if (p == pp.left) // detach pointers
+                    pp.left = null;
+                else if (p == pp.right)
+                    pp.right = null;
+                p.parent = null;
+            }
+        }
+    }
+
+    /* ---------------- Collision reduction methods -------------- */
+
+    /**
+     * Spreads higher bits to lower, and also forces top 2 bits to 0.
+     * Because the table uses power-of-two masking, sets of hashes
+     * that vary only in bits above the current mask will always
+     * collide. (Among known examples are sets of Float keys holding
+     * consecutive whole numbers in small tables.)  To counter this,
+     * we apply a transform that spreads the impact of higher bits
+     * downward. There is a tradeoff between speed, utility, and
+     * quality of bit-spreading. Because many common sets of hashes
+     * are already reasonably distributed across bits (so don't benefit
+     * from spreading), and because we use trees to handle large sets
+     * of collisions in bins, we don't need excessively high quality.
+     */
+    private static final int spread(int h) {
+        h ^= (h >>> 18) ^ (h >>> 12);
+        return (h ^ (h >>> 10)) & HASH_BITS;
+    }
+
+    /**
+     * Replaces a list bin with a tree bin. Call only when locked.
+     * Fails to replace if the given key is non-comparable or table
+     * is, or needs, resizing.
+     */
+    private final void replaceWithTreeBin(Node[] tab, int index, Object key) {
+        if ((key instanceof Comparable) &&
+                (tab.length >= MAXIMUM_CAPACITY || counter.sum() < (long)sizeCtl)) {
+            TreeBin t = new TreeBin();
+            for (Node e = tabAt(tab, index); e != null; e = e.next)
+                t.putTreeNode(e.hash & HASH_BITS, e.key, e.val);
+            setTabAt(tab, index, new Node(MOVED, t, null, null));
+        }
+    }
+
+    /* ---------------- Internal access and update methods -------------- */
+
+    /** Implementation for get and containsKey */
+    private final Object internalGet(Object k) {
+        int h = spread(k.hashCode());
+        retry: for (Node[] tab = table; tab != null;) {
+            Node e, p; Object ek, ev; int eh;      // locals to read fields once
+            for (e = tabAt(tab, (tab.length - 1) & h); e != null; e = e.next) {
+                if ((eh = e.hash) == MOVED) {
+                    if ((ek = e.key) instanceof TreeBin)  // search TreeBin
+                        return ((TreeBin)ek).getValue(h, k);
+                    else {                        // restart with new table
+                        tab = (Node[])ek;
+                        continue retry;
+                    }
+                }
+                else if ((eh & HASH_BITS) == h && (ev = e.val) != null &&
+                        ((ek = e.key) == k || k.equals(ek)))
+                    return ev;
+            }
+            break;
+        }
+        return null;
+    }
+
+    /**
+     * Implementation for the four public remove/replace methods:
+     * Replaces node value with v, conditional upon match of cv if
+     * non-null.  If resulting value is null, delete.
+     */
+    private final Object internalReplace(Object k, Object v, Object cv) {
+        int h = spread(k.hashCode());
+        Object oldVal = null;
+        for (Node[] tab = table;;) {
+            Node f; int i, fh; Object fk;
+            if (tab == null ||
+                    (f = tabAt(tab, i = (tab.length - 1) & h)) == null)
+                break;
+            else if ((fh = f.hash) == MOVED) {
+                if ((fk = f.key) instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    boolean validated = false;
+                    boolean deleted = false;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            validated = true;
+                            TreeNode p = t.getTreeNode(h, k, t.root);
+                            if (p != null) {
+                                Object pv = p.val;
+                                if (cv == null || cv == pv || cv.equals(pv)) {
+                                    oldVal = pv;
+                                    if ((p.val = v) == null) {
+                                        deleted = true;
+                                        t.deleteTreeNode(p);
+                                    }
+                                }
+                            }
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                    if (validated) {
+                        if (deleted)
+                            counter.add(-1L);
+                        break;
+                    }
+                }
+                else
+                    tab = (Node[])fk;
+            }
+            else if ((fh & HASH_BITS) != h && f.next == null) // precheck
+                break;                          // rules out possible existence
+            else if ((fh & LOCKED) != 0) {
+                checkForResize();               // try resizing if can't get lock
+                f.tryAwaitLock(tab, i);
+            }
+            else if (f.casHash(fh, fh | LOCKED)) {
+                boolean validated = false;
+                boolean deleted = false;
+                try {
+                    if (tabAt(tab, i) == f) {
+                        validated = true;
+                        for (Node e = f, pred = null;;) {
+                            Object ek, ev;
+                            if ((e.hash & HASH_BITS) == h &&
+                                    ((ev = e.val) != null) &&
+                                    ((ek = e.key) == k || k.equals(ek))) {
+                                if (cv == null || cv == ev || cv.equals(ev)) {
+                                    oldVal = ev;
+                                    if ((e.val = v) == null) {
+                                        deleted = true;
+                                        Node en = e.next;
+                                        if (pred != null)
+                                            pred.next = en;
+                                        else
+                                            setTabAt(tab, i, en);
+                                    }
+                                }
+                                break;
+                            }
+                            pred = e;
+                            if ((e = e.next) == null)
+                                break;
+                        }
+                    }
+                } finally {
+                    if (!f.casHash(fh | LOCKED, fh)) {
+                        f.hash = fh;
+                        synchronized (f) { f.notifyAll(); };
+                    }
+                }
+                if (validated) {
+                    if (deleted)
+                        counter.add(-1L);
+                    break;
+                }
+            }
+        }
+        return oldVal;
+    }
+
+    /*
+     * Internal versions of the six insertion methods, each a
+     * little more complicated than the last. All have
+     * the same basic structure as the first (internalPut):
+     *  1. If table uninitialized, create
+     *  2. If bin empty, try to CAS new node
+     *  3. If bin stale, use new table
+     *  4. if bin converted to TreeBin, validate and relay to TreeBin methods
+     *  5. Lock and validate; if valid, scan and add or update
+     *
+     * The others interweave other checks and/or alternative actions:
+     *  * Plain put checks for and performs resize after insertion.
+     *  * putIfAbsent prescans for mapping without lock (and fails to add
+     *    if present), which also makes pre-emptive resize checks worthwhile.
+     *  * computeIfAbsent extends form used in putIfAbsent with additional
+     *    mechanics to deal with, calls, potential exceptions and null
+     *    returns from function call.
+     *  * compute uses the same function-call mechanics, but without
+     *    the prescans
+     *  * merge acts as putIfAbsent in the absent case, but invokes the
+     *    update function if present
+     *  * putAll attempts to pre-allocate enough table space
+     *    and more lazily performs count updates and checks.
+     *
+     * Someday when details settle down a bit more, it might be worth
+     * some factoring to reduce sprawl.
+     */
+
+    /** Implementation for put */
+    private final Object internalPut(Object k, Object v) {
+        int h = spread(k.hashCode());
+        int count = 0;
+        for (Node[] tab = table;;) {
+            int i; Node f; int fh; Object fk;
+            if (tab == null)
+                tab = initTable();
+            else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) {
+                if (casTabAt(tab, i, null, new Node(h, k, v, null)))
+                    break;                   // no lock when adding to empty bin
+            }
+            else if ((fh = f.hash) == MOVED) {
+                if ((fk = f.key) instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    Object oldVal = null;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            count = 2;
+                            TreeNode p = t.putTreeNode(h, k, v);
+                            if (p != null) {
+                                oldVal = p.val;
+                                p.val = v;
+                            }
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                    if (count != 0) {
+                        if (oldVal != null)
+                            return oldVal;
+                        break;
+                    }
+                }
+                else
+                    tab = (Node[])fk;
+            }
+            else if ((fh & LOCKED) != 0) {
+                checkForResize();
+                f.tryAwaitLock(tab, i);
+            }
+            else if (f.casHash(fh, fh | LOCKED)) {
+                Object oldVal = null;
+                try {                        // needed in case equals() throws
+                    if (tabAt(tab, i) == f) {
+                        count = 1;
+                        for (Node e = f;; ++count) {
+                            Object ek, ev;
+                            if ((e.hash & HASH_BITS) == h &&
+                                    (ev = e.val) != null &&
+                                    ((ek = e.key) == k || k.equals(ek))) {
+                                oldVal = ev;
+                                e.val = v;
+                                break;
+                            }
+                            Node last = e;
+                            if ((e = e.next) == null) {
+                                last.next = new Node(h, k, v, null);
+                                if (count >= TREE_THRESHOLD)
+                                    replaceWithTreeBin(tab, i, k);
+                                break;
+                            }
+                        }
+                    }
+                } finally {                  // unlock and signal if needed
+                    if (!f.casHash(fh | LOCKED, fh)) {
+                        f.hash = fh;
+                        synchronized (f) { f.notifyAll(); };
+                    }
+                }
+                if (count != 0) {
+                    if (oldVal != null)
+                        return oldVal;
+                    if (tab.length <= 64)
+                        count = 2;
+                    break;
+                }
+            }
+        }
+        counter.add(1L);
+        if (count > 1)
+            checkForResize();
+        return null;
+    }
+
+    /** Implementation for putIfAbsent */
+    private final Object internalPutIfAbsent(Object k, Object v) {
+        int h = spread(k.hashCode());
+        int count = 0;
+        for (Node[] tab = table;;) {
+            int i; Node f; int fh; Object fk, fv;
+            if (tab == null)
+                tab = initTable();
+            else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) {
+                if (casTabAt(tab, i, null, new Node(h, k, v, null)))
+                    break;
+            }
+            else if ((fh = f.hash) == MOVED) {
+                if ((fk = f.key) instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    Object oldVal = null;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            count = 2;
+                            TreeNode p = t.putTreeNode(h, k, v);
+                            if (p != null)
+                                oldVal = p.val;
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                    if (count != 0) {
+                        if (oldVal != null)
+                            return oldVal;
+                        break;
+                    }
+                }
+                else
+                    tab = (Node[])fk;
+            }
+            else if ((fh & HASH_BITS) == h && (fv = f.val) != null &&
+                    ((fk = f.key) == k || k.equals(fk)))
+                return fv;
+            else {
+                Node g = f.next;
+                if (g != null) { // at least 2 nodes -- search and maybe resize
+                    for (Node e = g;;) {
+                        Object ek, ev;
+                        if ((e.hash & HASH_BITS) == h && (ev = e.val) != null &&
+                                ((ek = e.key) == k || k.equals(ek)))
+                            return ev;
+                        if ((e = e.next) == null) {
+                            checkForResize();
+                            break;
+                        }
+                    }
+                }
+                if (((fh = f.hash) & LOCKED) != 0) {
+                    checkForResize();
+                    f.tryAwaitLock(tab, i);
+                }
+                else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) {
+                    Object oldVal = null;
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            count = 1;
+                            for (Node e = f;; ++count) {
+                                Object ek, ev;
+                                if ((e.hash & HASH_BITS) == h &&
+                                        (ev = e.val) != null &&
+                                        ((ek = e.key) == k || k.equals(ek))) {
+                                    oldVal = ev;
+                                    break;
+                                }
+                                Node last = e;
+                                if ((e = e.next) == null) {
+                                    last.next = new Node(h, k, v, null);
+                                    if (count >= TREE_THRESHOLD)
+                                        replaceWithTreeBin(tab, i, k);
+                                    break;
+                                }
+                            }
+                        }
+                    } finally {
+                        if (!f.casHash(fh | LOCKED, fh)) {
+                            f.hash = fh;
+                            synchronized (f) { f.notifyAll(); };
+                        }
+                    }
+                    if (count != 0) {
+                        if (oldVal != null)
+                            return oldVal;
+                        if (tab.length <= 64)
+                            count = 2;
+                        break;
+                    }
+                }
+            }
+        }
+        counter.add(1L);
+        if (count > 1)
+            checkForResize();
+        return null;
+    }
+
+    /** Implementation for computeIfAbsent */
+    private final Object internalComputeIfAbsent(K k,
+                                                 Fun<? super K, ?> mf) {
+        int h = spread(k.hashCode());
+        Object val = null;
+        int count = 0;
+        for (Node[] tab = table;;) {
+            Node f; int i, fh; Object fk, fv;
+            if (tab == null)
+                tab = initTable();
+            else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) {
+                Node node = new Node(fh = h | LOCKED, k, null, null);
+                if (casTabAt(tab, i, null, node)) {
+                    count = 1;
+                    try {
+                        if ((val = mf.apply(k)) != null)
+                            node.val = val;
+                    } finally {
+                        if (val == null)
+                            setTabAt(tab, i, null);
+                        if (!node.casHash(fh, h)) {
+                            node.hash = h;
+                            synchronized (node) { node.notifyAll(); };
+                        }
+                    }
+                }
+                if (count != 0)
+                    break;
+            }
+            else if ((fh = f.hash) == MOVED) {
+                if ((fk = f.key) instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    boolean added = false;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            count = 1;
+                            TreeNode p = t.getTreeNode(h, k, t.root);
+                            if (p != null)
+                                val = p.val;
+                            else if ((val = mf.apply(k)) != null) {
+                                added = true;
+                                count = 2;
+                                t.putTreeNode(h, k, val);
+                            }
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                    if (count != 0) {
+                        if (!added)
+                            return val;
+                        break;
+                    }
+                }
+                else
+                    tab = (Node[])fk;
+            }
+            else if ((fh & HASH_BITS) == h && (fv = f.val) != null &&
+                    ((fk = f.key) == k || k.equals(fk)))
+                return fv;
+            else {
+                Node g = f.next;
+                if (g != null) {
+                    for (Node e = g;;) {
+                        Object ek, ev;
+                        if ((e.hash & HASH_BITS) == h && (ev = e.val) != null &&
+                                ((ek = e.key) == k || k.equals(ek)))
+                            return ev;
+                        if ((e = e.next) == null) {
+                            checkForResize();
+                            break;
+                        }
+                    }
+                }
+                if (((fh = f.hash) & LOCKED) != 0) {
+                    checkForResize();
+                    f.tryAwaitLock(tab, i);
+                }
+                else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) {
+                    boolean added = false;
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            count = 1;
+                            for (Node e = f;; ++count) {
+                                Object ek, ev;
+                                if ((e.hash & HASH_BITS) == h &&
+                                        (ev = e.val) != null &&
+                                        ((ek = e.key) == k || k.equals(ek))) {
+                                    val = ev;
+                                    break;
+                                }
+                                Node last = e;
+                                if ((e = e.next) == null) {
+                                    if ((val = mf.apply(k)) != null) {
+                                        added = true;
+                                        last.next = new Node(h, k, val, null);
+                                        if (count >= TREE_THRESHOLD)
+                                            replaceWithTreeBin(tab, i, k);
+                                    }
+                                    break;
+                                }
+                            }
+                        }
+                    } finally {
+                        if (!f.casHash(fh | LOCKED, fh)) {
+                            f.hash = fh;
+                            synchronized (f) { f.notifyAll(); };
+                        }
+                    }
+                    if (count != 0) {
+                        if (!added)
+                            return val;
+                        if (tab.length <= 64)
+                            count = 2;
+                        break;
+                    }
+                }
+            }
+        }
+        if (val != null) {
+            counter.add(1L);
+            if (count > 1)
+                checkForResize();
+        }
+        return val;
+    }
+
+    /** Implementation for compute */
+    @SuppressWarnings("unchecked") private final Object internalCompute
+    (K k, boolean onlyIfPresent, BiFun<? super K, ? super V, ? extends V> mf) {
+        int h = spread(k.hashCode());
+        Object val = null;
+        int delta = 0;
+        int count = 0;
+        for (Node[] tab = table;;) {
+            Node f; int i, fh; Object fk;
+            if (tab == null)
+                tab = initTable();
+            else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) {
+                if (onlyIfPresent)
+                    break;
+                Node node = new Node(fh = h | LOCKED, k, null, null);
+                if (casTabAt(tab, i, null, node)) {
+                    try {
+                        count = 1;
+                        if ((val = mf.apply(k, null)) != null) {
+                            node.val = val;
+                            delta = 1;
+                        }
+                    } finally {
+                        if (delta == 0)
+                            setTabAt(tab, i, null);
+                        if (!node.casHash(fh, h)) {
+                            node.hash = h;
+                            synchronized (node) { node.notifyAll(); };
+                        }
+                    }
+                }
+                if (count != 0)
+                    break;
+            }
+            else if ((fh = f.hash) == MOVED) {
+                if ((fk = f.key) instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            count = 1;
+                            TreeNode p = t.getTreeNode(h, k, t.root);
+                            Object pv;
+                            if (p == null) {
+                                if (onlyIfPresent)
+                                    break;
+                                pv = null;
+                            } else
+                                pv = p.val;
+                            if ((val = mf.apply(k, (V)pv)) != null) {
+                                if (p != null)
+                                    p.val = val;
+                                else {
+                                    count = 2;
+                                    delta = 1;
+                                    t.putTreeNode(h, k, val);
+                                }
+                            }
+                            else if (p != null) {
+                                delta = -1;
+                                t.deleteTreeNode(p);
+                            }
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                    if (count != 0)
+                        break;
+                }
+                else
+                    tab = (Node[])fk;
+            }
+            else if ((fh & LOCKED) != 0) {
+                checkForResize();
+                f.tryAwaitLock(tab, i);
+            }
+            else if (f.casHash(fh, fh | LOCKED)) {
+                try {
+                    if (tabAt(tab, i) == f) {
+                        count = 1;
+                        for (Node e = f, pred = null;; ++count) {
+                            Object ek, ev;
+                            if ((e.hash & HASH_BITS) == h &&
+                                    (ev = e.val) != null &&
+                                    ((ek = e.key) == k || k.equals(ek))) {
+                                val = mf.apply(k, (V)ev);
+                                if (val != null)
+                                    e.val = val;
+                                else {
+                                    delta = -1;
+                                    Node en = e.next;
+                                    if (pred != null)
+                                        pred.next = en;
+                                    else
+                                        setTabAt(tab, i, en);
+                                }
+                                break;
+                            }
+                            pred = e;
+                            if ((e = e.next) == null) {
+                                if (!onlyIfPresent && (val = mf.apply(k, null)) != null) {
+                                    pred.next = new Node(h, k, val, null);
+                                    delta = 1;
+                                    if (count >= TREE_THRESHOLD)
+                                        replaceWithTreeBin(tab, i, k);
+                                }
+                                break;
+                            }
+                        }
+                    }
+                } finally {
+                    if (!f.casHash(fh | LOCKED, fh)) {
+                        f.hash = fh;
+                        synchronized (f) { f.notifyAll(); };
+                    }
+                }
+                if (count != 0) {
+                    if (tab.length <= 64)
+                        count = 2;
+                    break;
+                }
+            }
+        }
+        if (delta != 0) {
+            counter.add((long)delta);
+            if (count > 1)
+                checkForResize();
+        }
+        return val;
+    }
+
+    /** Implementation for merge */
+    @SuppressWarnings("unchecked") private final Object internalMerge
+    (K k, V v, BiFun<? super V, ? super V, ? extends V> mf) {
+        int h = spread(k.hashCode());
+        Object val = null;
+        int delta = 0;
+        int count = 0;
+        for (Node[] tab = table;;) {
+            int i; Node f; int fh; Object fk, fv;
+            if (tab == null)
+                tab = initTable();
+            else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) {
+                if (casTabAt(tab, i, null, new Node(h, k, v, null))) {
+                    delta = 1;
+                    val = v;
+                    break;
+                }
+            }
+            else if ((fh = f.hash) == MOVED) {
+                if ((fk = f.key) instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            count = 1;
+                            TreeNode p = t.getTreeNode(h, k, t.root);
+                            val = (p == null) ? v : mf.apply((V)p.val, v);
+                            if (val != null) {
+                                if (p != null)
+                                    p.val = val;
+                                else {
+                                    count = 2;
+                                    delta = 1;
+                                    t.putTreeNode(h, k, val);
+                                }
+                            }
+                            else if (p != null) {
+                                delta = -1;
+                                t.deleteTreeNode(p);
+                            }
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                    if (count != 0)
+                        break;
+                }
+                else
+                    tab = (Node[])fk;
+            }
+            else if ((fh & LOCKED) != 0) {
+                checkForResize();
+                f.tryAwaitLock(tab, i);
+            }
+            else if (f.casHash(fh, fh | LOCKED)) {
+                try {
+                    if (tabAt(tab, i) == f) {
+                        count = 1;
+                        for (Node e = f, pred = null;; ++count) {
+                            Object ek, ev;
+                            if ((e.hash & HASH_BITS) == h &&
+                                    (ev = e.val) != null &&
+                                    ((ek = e.key) == k || k.equals(ek))) {
+                                val = mf.apply((V)ev, v);
+                                if (val != null)
+                                    e.val = val;
+                                else {
+                                    delta = -1;
+                                    Node en = e.next;
+                                    if (pred != null)
+                                        pred.next = en;
+                                    else
+                                        setTabAt(tab, i, en);
+                                }
+                                break;
+                            }
+                            pred = e;
+                            if ((e = e.next) == null) {
+                                val = v;
+                                pred.next = new Node(h, k, val, null);
+                                delta = 1;
+                                if (count >= TREE_THRESHOLD)
+                                    replaceWithTreeBin(tab, i, k);
+                                break;
+                            }
+                        }
+                    }
+                } finally {
+                    if (!f.casHash(fh | LOCKED, fh)) {
+                        f.hash = fh;
+                        synchronized (f) { f.notifyAll(); };
+                    }
+                }
+                if (count != 0) {
+                    if (tab.length <= 64)
+                        count = 2;
+                    break;
+                }
+            }
+        }
+        if (delta != 0) {
+            counter.add((long)delta);
+            if (count > 1)
+                checkForResize();
+        }
+        return val;
+    }
+
+    /** Implementation for putAll */
+    private final void internalPutAll(Map<?, ?> m) {
+        tryPresize(m.size());
+        long delta = 0L;     // number of uncommitted additions
+        boolean npe = false; // to throw exception on exit for nulls
+        try {                // to clean up counts on other exceptions
+            for (Map.Entry<?, ?> entry : m.entrySet()) {
+                Object k, v;
+                if (entry == null || (k = entry.getKey()) == null ||
+                        (v = entry.getValue()) == null) {
+                    npe = true;
+                    break;
+                }
+                int h = spread(k.hashCode());
+                for (Node[] tab = table;;) {
+                    int i; Node f; int fh; Object fk;
+                    if (tab == null)
+                        tab = initTable();
+                    else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null){
+                        if (casTabAt(tab, i, null, new Node(h, k, v, null))) {
+                            ++delta;
+                            break;
+                        }
+                    }
+                    else if ((fh = f.hash) == MOVED) {
+                        if ((fk = f.key) instanceof TreeBin) {
+                            TreeBin t = (TreeBin)fk;
+                            boolean validated = false;
+                            t.acquire(0);
+                            try {
+                                if (tabAt(tab, i) == f) {
+                                    validated = true;
+                                    TreeNode p = t.getTreeNode(h, k, t.root);
+                                    if (p != null)
+                                        p.val = v;
+                                    else {
+                                        t.putTreeNode(h, k, v);
+                                        ++delta;
+                                    }
+                                }
+                            } finally {
+                                t.release(0);
+                            }
+                            if (validated)
+                                break;
+                        }
+                        else
+                            tab = (Node[])fk;
+                    }
+                    else if ((fh & LOCKED) != 0) {
+                        counter.add(delta);
+                        delta = 0L;
+                        checkForResize();
+                        f.tryAwaitLock(tab, i);
+                    }
+                    else if (f.casHash(fh, fh | LOCKED)) {
+                        int count = 0;
+                        try {
+                            if (tabAt(tab, i) == f) {
+                                count = 1;
+                                for (Node e = f;; ++count) {
+                                    Object ek, ev;
+                                    if ((e.hash & HASH_BITS) == h &&
+                                            (ev = e.val) != null &&
+                                            ((ek = e.key) == k || k.equals(ek))) {
+                                        e.val = v;
+                                        break;
+                                    }
+                                    Node last = e;
+                                    if ((e = e.next) == null) {
+                                        ++delta;
+                                        last.next = new Node(h, k, v, null);
+                                        if (count >= TREE_THRESHOLD)
+                                            replaceWithTreeBin(tab, i, k);
+                                        break;
+                                    }
+                                }
+                            }
+                        } finally {
+                            if (!f.casHash(fh | LOCKED, fh)) {
+                                f.hash = fh;
+                                synchronized (f) { f.notifyAll(); };
+                            }
+                        }
+                        if (count != 0) {
+                            if (count > 1) {
+                                counter.add(delta);
+                                delta = 0L;
+                                checkForResize();
+                            }
+                            break;
+                        }
+                    }
+                }
+            }
+        } finally {
+            if (delta != 0)
+                counter.add(delta);
+        }
+        if (npe)
+            throw new NullPointerException();
+    }
+
+    /* ---------------- Table Initialization and Resizing -------------- */
+
+    /**
+     * Returns a power of two table size for the given desired capacity.
+     * See Hackers Delight, sec 3.2
+     */
+    private static final int tableSizeFor(int c) {
+        int n = c - 1;
+        n |= n >>> 1;
+        n |= n >>> 2;
+        n |= n >>> 4;
+        n |= n >>> 8;
+        n |= n >>> 16;
+        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
+    }
+
+    /**
+     * Initializes table, using the size recorded in sizeCtl.
+     */
+    private final Node[] initTable() {
+        Node[] tab; int sc;
+        while ((tab = table) == null) {
+            if ((sc = sizeCtl) < 0)
+                Thread.yield(); // lost initialization race; just spin
+            else if (UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) {
+                try {
+                    if ((tab = table) == null) {
+                        int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
+                        tab = table = new Node[n];
+                        sc = n - (n >>> 2);
+                    }
+                } finally {
+                    sizeCtl = sc;
+                }
+                break;
+            }
+        }
+        return tab;
+    }
+
+    /**
+     * If table is too small and not already resizing, creates next
+     * table and transfers bins.  Rechecks occupancy after a transfer
+     * to see if another resize is already needed because resizings
+     * are lagging additions.
+     */
+    private final void checkForResize() {
+        Node[] tab; int n, sc;
+        while ((tab = table) != null &&
+                (n = tab.length) < MAXIMUM_CAPACITY &&
+                (sc = sizeCtl) >= 0 && counter.sum() >= (long)sc &&
+                UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) {
+            try {
+                if (tab == table) {
+                    table = rebuild(tab);
+                    sc = (n << 1) - (n >>> 1);
+                }
+            } finally {
+                sizeCtl = sc;
+            }
+        }
+    }
+
+    /**
+     * Tries to presize table to accommodate the given number of elements.
+     *
+     * @param size number of elements (doesn't need to be perfectly accurate)
+     */
+    private final void tryPresize(int size) {
+        int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY :
+                tableSizeFor(size + (size >>> 1) + 1);
+        int sc;
+        while ((sc = sizeCtl) >= 0) {
+            Node[] tab = table; int n;
+            if (tab == null || (n = tab.length) == 0) {
+                n = (sc > c) ? sc : c;
+                if (UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) {
+                    try {
+                        if (table == tab) {
+                            table = new Node[n];
+                            sc = n - (n >>> 2);
+                        }
+                    } finally {
+                        sizeCtl = sc;
+                    }
+                }
+            }
+            else if (c <= sc || n >= MAXIMUM_CAPACITY)
+                break;
+            else if (UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) {
+                try {
+                    if (table == tab) {
+                        table = rebuild(tab);
+                        sc = (n << 1) - (n >>> 1);
+                    }
+                } finally {
+                    sizeCtl = sc;
+                }
+            }
+        }
+    }
+
+    /*
+     * Moves and/or copies the nodes in each bin to new table. See
+     * above for explanation.
+     *
+     * @return the new table
+     */
+    private static final Node[] rebuild(Node[] tab) {
+        int n = tab.length;
+        Node[] nextTab = new Node[n << 1];
+        Node fwd = new Node(MOVED, nextTab, null, null);
+        int[] buffer = null;       // holds bins to revisit; null until needed
+        Node rev = null;           // reverse forwarder; null until needed
+        int nbuffered = 0;         // the number of bins in buffer list
+        int bufferIndex = 0;       // buffer index of current buffered bin
+        int bin = n - 1;           // current non-buffered bin or -1 if none
+
+        for (int i = bin;;) {      // start upwards sweep
+            int fh; Node f;
+            if ((f = tabAt(tab, i)) == null) {
+                if (bin >= 0) {    // Unbuffered; no lock needed (or available)
+                    if (!casTabAt(tab, i, f, fwd))
+                        continue;
+                }
+                else {             // transiently use a locked forwarding node
+                    Node g = new Node(MOVED|LOCKED, nextTab, null, null);
+                    if (!casTabAt(tab, i, f, g))
+                        continue;
+                    setTabAt(nextTab, i, null);
+                    setTabAt(nextTab, i + n, null);
+                    setTabAt(tab, i, fwd);
+                    if (!g.casHash(MOVED|LOCKED, MOVED)) {
+                        g.hash = MOVED;
+                        synchronized (g) { g.notifyAll(); }
+                    }
+                }
+            }
+            else if ((fh = f.hash) == MOVED) {
+                Object fk = f.key;
+                if (fk instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    boolean validated = false;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            validated = true;
+                            splitTreeBin(nextTab, i, t);
+                            setTabAt(tab, i, fwd);
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                    if (!validated)
+                        continue;
+                }
+            }
+            else if ((fh & LOCKED) == 0 && f.casHash(fh, fh|LOCKED)) {
+                boolean validated = false;
+                try {              // split to lo and hi lists; copying as needed
+                    if (tabAt(tab, i) == f) {
+                        validated = true;
+                        splitBin(nextTab, i, f);
+                        setTabAt(tab, i, fwd);
+                    }
+                } finally {
+                    if (!f.casHash(fh | LOCKED, fh)) {
+                        f.hash = fh;
+                        synchronized (f) { f.notifyAll(); };
+                    }
+                }
+                if (!validated)
+                    continue;
+            }
+            else {
+                if (buffer == null) // initialize buffer for revisits
+                    buffer = new int[TRANSFER_BUFFER_SIZE];
+                if (bin < 0 && bufferIndex > 0) {
+                    int j = buffer[--bufferIndex];
+                    buffer[bufferIndex] = i;
+                    i = j;         // swap with another bin
+                    continue;
+                }
+                if (bin < 0 || nbuffered >= TRANSFER_BUFFER_SIZE) {
+                    f.tryAwaitLock(tab, i);
+                    continue;      // no other options -- block
+                }
+                if (rev == null)   // initialize reverse-forwarder
+                    rev = new Node(MOVED, tab, null, null);
+                if (tabAt(tab, i) != f || (f.hash & LOCKED) == 0)
+                    continue;      // recheck before adding to list
+                buffer[nbuffered++] = i;
+                setTabAt(nextTab, i, rev);     // install place-holders
+                setTabAt(nextTab, i + n, rev);
+            }
+
+            if (bin > 0)
+                i = --bin;
+            else if (buffer != null && nbuffered > 0) {
+                bin = -1;
+                i = buffer[bufferIndex = --nbuffered];
+            }
+            else
+                return nextTab;
+        }
+    }
+
+    /**
+     * Splits a normal bin with list headed by e into lo and hi parts;
+     * installs in given table.
+     */
+    private static void splitBin(Node[] nextTab, int i, Node e) {
+        int bit = nextTab.length >>> 1; // bit to split on
+        int runBit = e.hash & bit;
+        Node lastRun = e, lo = null, hi = null;
+        for (Node p = e.next; p != null; p = p.next) {
+            int b = p.hash & bit;
+            if (b != runBit) {
+                runBit = b;
+                lastRun = p;
+            }
+        }
+        if (runBit == 0)
+            lo = lastRun;
+        else
+            hi = lastRun;
+        for (Node p = e; p != lastRun; p = p.next) {
+            int ph = p.hash & HASH_BITS;
+            Object pk = p.key, pv = p.val;
+            if ((ph & bit) == 0)
+                lo = new Node(ph, pk, pv, lo);
+            else
+                hi = new Node(ph, pk, pv, hi);
+        }
+        setTabAt(nextTab, i, lo);
+        setTabAt(nextTab, i + bit, hi);
+    }
+
+    /**
+     * Splits a tree bin into lo and hi parts; installs in given table.
+     */
+    private static void splitTreeBin(Node[] nextTab, int i, TreeBin t) {
+        int bit = nextTab.length >>> 1;
+        TreeBin lt = new TreeBin();
+        TreeBin ht = new TreeBin();
+        int lc = 0, hc = 0;
+        for (Node e = t.first; e != null; e = e.next) {
+            int h = e.hash & HASH_BITS;
+            Object k = e.key, v = e.val;
+            if ((h & bit) == 0) {
+                ++lc;
+                lt.putTreeNode(h, k, v);
+            }
+            else {
+                ++hc;
+                ht.putTreeNode(h, k, v);
+            }
+        }
+        Node ln, hn; // throw away trees if too small
+        if (lc <= (TREE_THRESHOLD >>> 1)) {
+            ln = null;
+            for (Node p = lt.first; p != null; p = p.next)
+                ln = new Node(p.hash, p.key, p.val, ln);
+        }
+        else
+            ln = new Node(MOVED, lt, null, null);
+        setTabAt(nextTab, i, ln);
+        if (hc <= (TREE_THRESHOLD >>> 1)) {
+            hn = null;
+            for (Node p = ht.first; p != null; p = p.next)
+                hn = new Node(p.hash, p.key, p.val, hn);
+        }
+        else
+            hn = new Node(MOVED, ht, null, null);
+        setTabAt(nextTab, i + bit, hn);
+    }
+
+    /**
+     * Implementation for clear. Steps through each bin, removing all
+     * nodes.
+     */
+    private final void internalClear() {
+        long delta = 0L; // negative number of deletions
+        int i = 0;
+        Node[] tab = table;
+        while (tab != null && i < tab.length) {
+            int fh; Object fk;
+            Node f = tabAt(tab, i);
+            if (f == null)
+                ++i;
+            else if ((fh = f.hash) == MOVED) {
+                if ((fk = f.key) instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            for (Node p = t.first; p != null; p = p.next) {
+                                if (p.val != null) { // (currently always true)
+                                    p.val = null;
+                                    --delta;
+                                }
+                            }
+                            t.first = null;
+                            t.root = null;
+                            ++i;
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                }
+                else
+                    tab = (Node[])fk;
+            }
+            else if ((fh & LOCKED) != 0) {
+                counter.add(delta); // opportunistically update count
+                delta = 0L;
+                f.tryAwaitLock(tab, i);
+            }
+            else if (f.casHash(fh, fh | LOCKED)) {
+                try {
+                    if (tabAt(tab, i) == f) {
+                        for (Node e = f; e != null; e = e.next) {
+                            if (e.val != null) {  // (currently always true)
+                                e.val = null;
+                                --delta;
+                            }
+                        }
+                        setTabAt(tab, i, null);
+                        ++i;
+                    }
+                } finally {
+                    if (!f.casHash(fh | LOCKED, fh)) {
+                        f.hash = fh;
+                        synchronized (f) { f.notifyAll(); };
+                    }
+                }
+            }
+        }
+        if (delta != 0)
+            counter.add(delta);
+    }
+
+    /* ----------------Table Traversal -------------- */
+
+    /**
+     * Encapsulates traversal for methods such as containsValue; also
+     * serves as a base class for other iterators and bulk tasks.
+     *
+     * At each step, the iterator snapshots the key ("nextKey") and
+     * value ("nextVal") of a valid node (i.e., one that, at point of
+     * snapshot, has a non-null user value). Because val fields can
+     * change (including to null, indicating deletion), field nextVal
+     * might not be accurate at point of use, but still maintains the
+     * weak consistency property of holding a value that was once
+     * valid. To support iterator.remove, the nextKey field is not
+     * updated (nulled out) when the iterator cannot advance.
+     *
+     * Internal traversals directly access these fields, as in:
+     * {@code while (it.advance() != null) { process(it.nextKey); }}
+     *
+     * Exported iterators must track whether the iterator has advanced
+     * (in hasNext vs next) (by setting/checking/nulling field
+     * nextVal), and then extract key, value, or key-value pairs as
+     * return values of next().
+     *
+     * The iterator visits once each still-valid node that was
+     * reachable upon iterator construction. It might miss some that
+     * were added to a bin after the bin was visited, which is OK wrt
+     * consistency guarantees. Maintaining this property in the face
+     * of possible ongoing resizes requires a fair amount of
+     * bookkeeping state that is difficult to optimize away amidst
+     * volatile accesses.  Even so, traversal maintains reasonable
+     * throughput.
+     *
+     * Normally, iteration proceeds bin-by-bin traversing lists.
+     * However, if the table has been resized, then all future steps
+     * must traverse both the bin at the current index as well as at
+     * (index + baseSize); and so on for further resizings. To
+     * paranoically cope with potential sharing by users of iterators
+     * across threads, iteration terminates if a bounds checks fails
+     * for a table read.
+     *
+     * This class extends ForkJoinTask to streamline parallel
+     * iteration in bulk operations (see BulkTask). This adds only an
+     * int of space overhead, which is close enough to negligible in
+     * cases where it is not needed to not worry about it.  Because
+     * ForkJoinTask is Serializable, but iterators need not be, we
+     * need to add warning suppressions.
+     */
+    @SuppressWarnings("serial") static class Traverser<K,V,R> {
+        final ConcurrentHashMapV8<K, V> map;
+        Node next;           // the next entry to use
+        K nextKey;           // cached key field of next
+        V nextVal;           // cached val field of next
+        Node[] tab;          // current table; updated if resized
+        int index;           // index of bin to use next
+        int baseIndex;       // current index of initial table
+        int baseLimit;       // index bound for initial table
+        int baseSize;        // initial table size
+
+        /** Creates iterator for all entries in the table. */
+        Traverser(ConcurrentHashMapV8<K, V> map) {
+            this.map = map;
+        }
+
+        /** Creates iterator for split() methods */
+        Traverser(Traverser<K,V,?> it) {
+            ConcurrentHashMapV8<K, V> m; Node[] t;
+            if ((m = this.map = it.map) == null)
+                t = null;
+            else if ((t = it.tab) == null && // force parent tab initialization
+                    (t = it.tab = m.table) != null)
+                it.baseLimit = it.baseSize = t.length;
+            this.tab = t;
+            this.baseSize = it.baseSize;
+            it.baseLimit = this.index = this.baseIndex =
+                    ((this.baseLimit = it.baseLimit) + it.baseIndex + 1) >>> 1;
+        }
+
+        /**
+         * Advances next; returns nextVal or null if terminated.
+         * See above for explanation.
+         */
+        final V advance() {
+            Node e = next;
+            V ev = null;
+            outer: do {
+                if (e != null)                  // advance past used/skipped node
+                    e = e.next;
+                while (e == null) {             // get to next non-null bin
+                    ConcurrentHashMapV8<K, V> m;
+                    Node[] t; int b, i, n; Object ek; // checks must use locals
+                    if ((t = tab) != null)
+                        n = t.length;
+                    else if ((m = map) != null && (t = tab = m.table) != null)
+                        n = baseLimit = baseSize = t.length;
+                    else
+                        break outer;
+                    if ((b = baseIndex) >= baseLimit ||
+                            (i = index) < 0 || i >= n)
+                        break outer;
+                    if ((e = tabAt(t, i)) != null && e.hash == MOVED) {
+                        if ((ek = e.key) instanceof TreeBin)
+                            e = ((TreeBin)ek).first;
+                        else {
+                            tab = (Node[])ek;
+                            continue;           // restarts due to null val
+                        }
+                    }                           // visit upper slots if present
+                    index = (i += baseSize) < n ? i : (baseIndex = b + 1);
+                }
+                nextKey = (K) e.key;
+            } while ((ev = (V) e.val) == null);    // skip deleted or special nodes
+            next = e;
+            return nextVal = ev;
+        }
+
+        public final void remove() {
+            Object k = nextKey;
+            if (k == null && (advance() == null || (k = nextKey) == null))
+                throw new IllegalStateException();
+            map.internalReplace(k, null, null);
+        }
+
+        public final boolean hasNext() {
+            return nextVal != null || advance() != null;
+        }
+
+        public final boolean hasMoreElements() { return hasNext(); }
+        public final void setRawResult(Object x) { }
+        public R getRawResult() { return null; }
+        public boolean exec() { return true; }
+    }
+
+    /* ---------------- Public operations -------------- */
+
+    /**
+     * Creates a new, empty map with the default initial table size (16).
+     */
+    public ConcurrentHashMapV8() {
+        this.counter = new LongAdder();
+    }
+
+    /**
+     * Creates a new, empty map with an initial table size
+     * accommodating the specified number of elements without the need
+     * to dynamically resize.
+     *
+     * @param initialCapacity The implementation performs internal
+     * sizing to accommodate this many elements.
+     * @throws IllegalArgumentException if the initial capacity of
+     * elements is negative
+     */
+    public ConcurrentHashMapV8(int initialCapacity) {
+        if (initialCapacity < 0)
+            throw new IllegalArgumentException();
+        int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ?
+                MAXIMUM_CAPACITY :
+                tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1));
+        this.counter = new LongAdder();
+        this.sizeCtl = cap;
+    }
+
+    /**
+     * Creates a new map with the same mappings as the given map.
+     *
+     * @param m the map
+     */
+    public ConcurrentHashMapV8(Map<? extends K, ? extends V> m) {
+        this.counter = new LongAdder();
+        this.sizeCtl = DEFAULT_CAPACITY;
+        internalPutAll(m);
+    }
+
+    /**
+     * Creates a new, empty map with an initial table size based on
+     * the given number of elements ({@code initialCapacity}) and
+     * initial table density ({@code loadFactor}).
+     *
+     * @param initialCapacity the initial capacity. The implementation
+     * performs internal sizing to accommodate this many elements,
+     * given the specified load factor.
+     * @param loadFactor the load factor (table density) for
+     * establishing the initial table size
+     * @throws IllegalArgumentException if the initial capacity of
+     * elements is negative or the load factor is nonpositive
+     *
+     * @since 1.6
+     */
+    public ConcurrentHashMapV8(int initialCapacity, float loadFactor) {
+        this(initialCapacity, loadFactor, 1);
+    }
+
+    /**
+     * Creates a new, empty map with an initial table size based on
+     * the given number of elements ({@code initialCapacity}), table
+     * density ({@code loadFactor}), and number of concurrently
+     * updating threads ({@code concurrencyLevel}).
+     *
+     * @param initialCapacity the initial capacity. The implementation
+     * performs internal sizing to accommodate this many elements,
+     * given the specified load factor.
+     * @param loadFactor the load factor (table density) for
+     * establishing the initial table size
+     * @param concurrencyLevel the estimated number of concurrently
+     * updating threads. The implementation may use this value as
+     * a sizing hint.
+     * @throws IllegalArgumentException if the initial capacity is
+     * negative or the load factor or concurrencyLevel are
+     * nonpositive
+     */
+    public ConcurrentHashMapV8(int initialCapacity,
+                               float loadFactor, int concurrencyLevel) {
+        if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0)
+            throw new IllegalArgumentException();
+        if (initialCapacity < concurrencyLevel)   // Use at least as many bins
+            initialCapacity = concurrencyLevel;   // as estimated threads
+        long size = (long)(1.0 + (long)initialCapacity / loadFactor);
+        int cap = (size >= (long)MAXIMUM_CAPACITY) ?
+                MAXIMUM_CAPACITY : tableSizeFor((int)size);
+        this.counter = new LongAdder();
+        this.sizeCtl = cap;
+    }
+
+    /**
+     * Creates a new {@link Set} backed by a ConcurrentHashMapV8
+     * from the given type to {@code Boolean.TRUE}.
+     *
+     * @return the new set
+     */
+    public static <K> KeySetView<K,Boolean> newKeySet() {
+        return new KeySetView<K,Boolean>(new ConcurrentHashMapV8<K,Boolean>(),
+                Boolean.TRUE);
+    }
+
+    /**
+     * Creates a new {@link Set} backed by a ConcurrentHashMapV8
+     * from the given type to {@code Boolean.TRUE}.
+     *
+     * @param initialCapacity The implementation performs internal
+     * sizing to accommodate this many elements.
+     * @throws IllegalArgumentException if the initial capacity of
+     * elements is negative
+     * @return the new set
+     */
+    public static <K> KeySetView<K,Boolean> newKeySet(int initialCapacity) {
+        return new KeySetView<K,Boolean>(new ConcurrentHashMapV8<K,Boolean>(initialCapacity),
+                Boolean.TRUE);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isEmpty() {
+        return counter.sum() <= 0L; // ignore transient negative values
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int size() {
+        long n = counter.sum();
+        return ((n < 0L) ? 0 :
+                (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE :
+                        (int)n);
+    }
+
+    /**
+     * Returns the number of mappings. This method should be used
+     * instead of {@link #size} because a ConcurrentHashMapV8 may
+     * contain more mappings than can be represented as an int. The
+     * value returned is a snapshot; the actual count may differ if
+     * there are ongoing concurrent insertions or removals.
+     *
+     * @return the number of mappings
+     */
+    public long mappingCount() {
+        long n = counter.sum();
+        return (n < 0L) ? 0L : n; // ignore transient negative values
+    }
+
+    /**
+     * Returns the value to which the specified key is mapped,
+     * or {@code null} if this map contains no mapping for the key.
+     *
+     * <p>More formally, if this map contains a mapping from a key
+     * {@code k} to a value {@code v} such that {@code key.equals(k)},
+     * then this method returns {@code v}; otherwise it returns
+     * {@code null}.  (There can be at most one such mapping.)
+     *
+     * @throws NullPointerException if the specified key is null
+     */
+    @SuppressWarnings("unchecked") public V get(Object key) {
+        if (key == null)
+            throw new NullPointerException();
+        return (V)internalGet(key);
+    }
+
+    /**
+     * Returns the value to which the specified key is mapped,
+     * or the given defaultValue if this map contains no mapping for the key.
+     *
+     * @param key the key
+     * @param defaultValue the value to return if this map contains
+     * no mapping for the given key
+     * @return the mapping for the key, if present; else the defaultValue
+     * @throws NullPointerException if the specified key is null
+     */
+    @SuppressWarnings("unchecked") public V getValueOrDefault(Object key, V defaultValue) {
+        if (key == null)
+            throw new NullPointerException();
+        V v = (V) internalGet(key);
+        return v == null ? defaultValue : v;
+    }
+
+    /**
+     * Tests if the specified object is a key in this table.
+     *
+     * @param  key   possible key
+     * @return {@code true} if and only if the specified object
+     *         is a key in this table, as determined by the
+     *         {@code equals} method; {@code false} otherwise
+     * @throws NullPointerException if the specified key is null
+     */
+    public boolean containsKey(Object key) {
+        if (key == null)
+            throw new NullPointerException();
+        return internalGet(key) != null;
+    }
+
+    /**
+     * Returns {@code true} if this map maps one or more keys to the
+     * specified value. Note: This method may require a full traversal
+     * of the map, and is much slower than method {@code containsKey}.
+     *
+     * @param value value whose presence in this map is to be tested
+     * @return {@code true} if this map maps one or more keys to the
+     *         specified value
+     * @throws NullPointerException if the specified value is null
+     */
+    public boolean containsValue(Object value) {
+        if (value == null)
+            throw new NullPointerException();
+        Object v;
+        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
+        while ((v = it.advance()) != null) {
+            if (v == value || value.equals(v))
+                return true;
+        }
+        return false;
+    }
+
+    public K findKey(Object value) {
+        if (value == null)
+            throw new NullPointerException();
+        Object v;
+        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
+        while ((v = it.advance()) != null) {
+            if (v == value || value.equals(v))
+                return it.nextKey;
+        }
+        return null;
+    }
+
+    /**
+     * Legacy method testing if some key maps into the specified value
+     * in this table.  This method is identical in functionality to
+     * {@link #containsValue}, and exists solely to ensure
+     * full compatibility with class {@link java.util.Hashtable},
+     * which supported this method prior to introduction of the
+     * Java Collections framework.
+     *
+     * @param  value a value to search for
+     * @return {@code true} if and only if some key maps to the
+     *         {@code value} argument in this table as
+     *         determined by the {@code equals} method;
+     *         {@code false} otherwise
+     * @throws NullPointerException if the specified value is null
+     */
+    public boolean contains(Object value) {
+        return containsValue(value);
+    }
+
+    /**
+     * Maps the specified key to the specified value in this table.
+     * Neither the key nor the value can be null.
+     *
+     * <p>The value can be retrieved by calling the {@code get} method
+     * with a key that is equal to the original key.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param value value to be associated with the specified key
+     * @return the previous value associated with {@code key}, or
+     *         {@code null} if there was no mapping for {@code key}
+     * @throws NullPointerException if the specified key or value is null
+     */
+    @SuppressWarnings("unchecked") public V put(K key, V value) {
+        if (key == null || value == null)
+            throw new NullPointerException();
+        return (V)internalPut(key, value);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the previous value associated with the specified key,
+     *         or {@code null} if there was no mapping for the key
+     * @throws NullPointerException if the specified key or value is null
+     */
+    @SuppressWarnings("unchecked") public V putIfAbsent(K key, V value) {
+        if (key == null || value == null)
+            throw new NullPointerException();
+        return (V)internalPutIfAbsent(key, value);
+    }
+
+    /**
+     * Copies all of the mappings from the specified map to this one.
+     * These mappings replace any mappings that this map had for any of the
+     * keys currently in the specified map.
+     *
+     * @param m mappings to be stored in this map
+     */
+    public void putAll(Map<? extends K, ? extends V> m) {
+        internalPutAll(m);
+    }
+
+    /**
+     * If the specified key is not already associated with a value,
+     * computes its value using the given mappingFunction and enters
+     * it into the map unless null.  This is equivalent to
+     * <pre> {@code
+     * if (map.containsKey(key))
+     *   return map.get(key);
+     * value = mappingFunction.apply(key);
+     * if (value != null)
+     *   map.put(key, value);
+     * return value;}</pre>
+     *
+     * except that the action is performed atomically.  If the
+     * function returns {@code null} no mapping is recorded. If the
+     * function itself throws an (unchecked) exception, the exception
+     * is rethrown to its caller, and no mapping is recorded.  Some
+     * attempted update operations on this map by other threads may be
+     * blocked while computation is in progress, so the computation
+     * should be short and simple, and must not attempt to update any
+     * other mappings of this Map. The most appropriate usage is to
+     * construct a new object serving as an initial mapped value, or
+     * memoized result, as in:
+     *
+     *  <pre> {@code
+     * map.computeIfAbsent(key, new Fun<K, V>() {
+     *   public V map(K k) { return new Value(f(k)); }});}</pre>
+     *
+     * @param key key with which the specified value is to be associated
+     * @param mappingFunction the function to compute a value
+     * @return the current (existing or computed) value associated with
+     *         the specified key, or null if the computed value is null
+     * @throws NullPointerException if the specified key or mappingFunction
+     *         is null
+     * @throws IllegalStateException if the computation detectably
+     *         attempts a recursive update to this map that would
+     *         otherwise never complete
+     * @throws RuntimeException or Error if the mappingFunction does so,
+     *         in which case the mapping is left unestablished
+     */
+    @SuppressWarnings("unchecked") public V computeIfAbsent
+    (K key, Fun<? super K, ? extends V> mappingFunction) {
+        if (key == null || mappingFunction == null)
+            throw new NullPointerException();
+        return (V)internalComputeIfAbsent(key, mappingFunction);
+    }
+
+    /**
+     * If the given key is present, computes a new mapping value given a key and
+     * its current mapped value. This is equivalent to
+     *  <pre> {@code
+     *   if (map.containsKey(key)) {
+     *     value = remappingFunction.apply(key, map.get(key));
+     *     if (value != null)
+     *       map.put(key, value);
+     *     else
+     *       map.remove(key);
+     *   }
+     * }</pre>
+     *
+     * except that the action is performed atomically.  If the
+     * function returns {@code null}, the mapping is removed.  If the
+     * function itself throws an (unchecked) exception, the exception
+     * is rethrown to its caller, and the current mapping is left
+     * unchanged.  Some attempted update operations on this map by
+     * other threads may be blocked while computation is in progress,
+     * so the computation should be short and simple, and must not
+     * attempt to update any other mappings of this Map. For example,
+     * to either create or append new messages to a value mapping:
+     *
+     * @param key key with which the specified value is to be associated
+     * @param remappingFunction the function to compute a value
+     * @return the new value associated with the specified key, or null if none
+     * @throws NullPointerException if the specified key or remappingFunction
+     *         is null
+     * @throws IllegalStateException if the computation detectably
+     *         attempts a recursive update to this map that would
+     *         otherwise never complete
+     * @throws RuntimeException or Error if the remappingFunction does so,
+     *         in which case the mapping is unchanged
+     */
+    @SuppressWarnings("unchecked") public V computeIfPresent
+    (K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
+        if (key == null || remappingFunction == null)
+            throw new NullPointerException();
+        return (V)internalCompute(key, true, remappingFunction);
+    }
+
+    /**
+     * Computes a new mapping value given a key and
+     * its current mapped value (or {@code null} if there is no current
+     * mapping). This is equivalent to
+     *  <pre> {@code
+     *   value = remappingFunction.apply(key, map.get(key));
+     *   if (value != null)
+     *     map.put(key, value);
+     *   else
+     *     map.remove(key);
+     * }</pre>
+     *
+     * except that the action is performed atomically.  If the
+     * function returns {@code null}, the mapping is removed.  If the
+     * function itself throws an (unchecked) exception, the exception
+     * is rethrown to its caller, and the current mapping is left
+     * unchanged.  Some attempted update operations on this map by
+     * other threads may be blocked while computation is in progress,
+     * so the computation should be short and simple, and must not
+     * attempt to update any other mappings of this Map. For example,
+     * to either create or append new messages to a value mapping:
+     *
+     * <pre> {@code
+     * Map<Key, String> map = ...;
+     * final String msg = ...;
+     * map.compute(key, new BiFun<Key, String, String>() {
+     *   public String apply(Key k, String v) {
+     *    return (v == null) ? msg : v + msg;});}}</pre>
+     *
+     * @param key key with which the specified value is to be associated
+     * @param remappingFunction the function to compute a value
+     * @return the new value associated with the specified key, or null if none
+     * @throws NullPointerException if the specified key or remappingFunction
+     *         is null
+     * @throws IllegalStateException if the computation detectably
+     *         attempts a recursive update to this map that would
+     *         otherwise never complete
+     * @throws RuntimeException or Error if the remappingFunction does so,
+     *         in which case the mapping is unchanged
+     */
+    @SuppressWarnings("unchecked") public V compute
+    (K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
+        if (key == null || remappingFunction == null)
+            throw new NullPointerException();
+        return (V)internalCompute(key, false, remappingFunction);
+    }
+
+    /**
+     * If the specified key is not already associated
+     * with a value, associate it with the given value.
+     * Otherwise, replace the value with the results of
+     * the given remapping function. This is equivalent to:
+     *  <pre> {@code
+     *   if (!map.containsKey(key))
+     *     map.put(value);
+     *   else {
+     *     newValue = remappingFunction.apply(map.get(key), value);
+     *     if (value != null)
+     *       map.put(key, value);
+     *     else
+     *       map.remove(key);
+     *   }
+     * }</pre>
+     * except that the action is performed atomically.  If the
+     * function returns {@code null}, the mapping is removed.  If the
+     * function itself throws an (unchecked) exception, the exception
+     * is rethrown to its caller, and the current mapping is left
+     * unchanged.  Some attempted update operations on this map by
+     * other threads may be blocked while computation is in progress,
+     * so the computation should be short and simple, and must not
+     * attempt to update any other mappings of this Map.
+     */
+    @SuppressWarnings("unchecked") public V merge
+    (K key, V value, BiFun<? super V, ? super V, ? extends V> remappingFunction) {
+        if (key == null || value == null || remappingFunction == null)
+            throw new NullPointerException();
+        return (V)internalMerge(key, value, remappingFunction);
+    }
+
+    /**
+     * Removes the key (and its corresponding value) from this map.
+     * This method does nothing if the key is not in the map.
+     *
+     * @param  key the key that needs to be removed
+     * @return the previous value associated with {@code key}, or
+     *         {@code null} if there was no mapping for {@code key}
+     * @throws NullPointerException if the specified key is null
+     */
+    @SuppressWarnings("unchecked") public V remove(Object key) {
+        if (key == null)
+            throw new NullPointerException();
+        return (V)internalReplace(key, null, null);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @throws NullPointerException if the specified key is null
+     */
+    public boolean remove(Object key, Object value) {
+        if (key == null)
+            throw new NullPointerException();
+        if (value == null)
+            return false;
+        return internalReplace(key, null, value) != null;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @throws NullPointerException if any of the arguments are null
+     */
+    public boolean replace(K key, V oldValue, V newValue) {
+        if (key == null || oldValue == null || newValue == null)
+            throw new NullPointerException();
+        return internalReplace(key, newValue, oldValue) != null;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the previous value associated with the specified key,
+     *         or {@code null} if there was no mapping for the key
+     * @throws NullPointerException if the specified key or value is null
+     */
+    @SuppressWarnings("unchecked") public V replace(K key, V value) {
+        if (key == null || value == null)
+            throw new NullPointerException();
+        return (V)internalReplace(key, value, null);
+    }
+
+    /**
+     * Removes all of the mappings from this map.
+     */
+    public void clear() {
+        internalClear();
+    }
+
+    /**
+     * Returns a {@link Set} view of the keys contained in this map.
+     * The set is backed by the map, so changes to the map are
+     * reflected in the set, and vice-versa.
+     *
+     * @return the set view
+     */
+    public KeySetView<K,V> keySet() {
+        KeySetView<K,V> ks = keySet;
+        return (ks != null) ? ks : (keySet = new KeySetView<K,V>(this, null));
+    }
+
+    /**
+     * Returns a {@link Set} view of the keys in this map, using the
+     * given common mapped value for any additions (i.e., {@link
+     * Collection#add} and {@link Collection#addAll}). This is of
+     * course only appropriate if it is acceptable to use the same
+     * value for all additions from this view.
+     *
+     * @param mappedValue the mapped value to use for any
+     * additions.
+     * @return the set view
+     * @throws NullPointerException if the mappedValue is null
+     */
+    public KeySetView<K,V> keySet(V mappedValue) {
+        if (mappedValue == null)
+            throw new NullPointerException();
+        return new KeySetView<K,V>(this, mappedValue);
+    }
+
+    /**
+     * Returns a {@link Collection} view of the values contained in this map.
+     * The collection is backed by the map, so changes to the map are
+     * reflected in the collection, and vice-versa.
+     */
+    public ValuesView<K,V> values() {
+        ValuesView<K,V> vs = values;
+        return (vs != null) ? vs : (values = new ValuesView<K,V>(this));
+    }
+
+    /**
+     * Returns a {@link Set} view of the mappings contained in this map.
+     * The set is backed by the map, so changes to the map are
+     * reflected in the set, and vice-versa.  The set supports element
+     * removal, which removes the corresponding mapping from the map,
+     * via the {@code Iterator.remove}, {@code Set.remove},
+     * {@code removeAll}, {@code retainAll}, and {@code clear}
+     * operations.  It does not support the {@code add} or
+     * {@code addAll} operations.
+     *
+     * <p>The view's {@code iterator} is a "weakly consistent" iterator
+     * that will never throw {@link ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     */
+    public Set<Map.Entry<K,V>> entrySet() {
+        EntrySetView<K,V> es = entrySet;
+        return (es != null) ? es : (entrySet = new EntrySetView<K,V>(this));
+    }
+
+    /**
+     * Returns an enumeration of the keys in this table.
+     *
+     * @return an enumeration of the keys in this table
+     * @see #keySet()
+     */
+    public Enumeration<K> keys() {
+        return new KeyIterator<K,V>(this);
+    }
+
+    /**
+     * Returns an enumeration of the values in this table.
+     *
+     * @return an enumeration of the values in this table
+     * @see #values()
+     */
+    public Enumeration<V> elements() {
+        return new ValueIterator<K,V>(this);
+    }
+
+    /**
+     * Returns a partitionable iterator of the keys in this map.
+     *
+     * @return a partitionable iterator of the keys in this map
+     */
+    public Spliterator<K> keySpliterator() {
+        return new KeyIterator<K,V>(this);
+    }
+
+    /**
+     * Returns a partitionable iterator of the values in this map.
+     *
+     * @return a partitionable iterator of the values in this map
+     */
+    public Spliterator<V> valueSpliterator() {
+        return new ValueIterator<K,V>(this);
+    }
+
+    /**
+     * Returns a partitionable iterator of the entries in this map.
+     *
+     * @return a partitionable iterator of the entries in this map
+     */
+    public Spliterator<Map.Entry<K,V>> entrySpliterator() {
+        return new EntryIterator<K,V>(this);
+    }
+
+    /**
+     * Returns the hash code value for this {@link Map}, i.e.,
+     * the sum of, for each key-value pair in the map,
+     * {@code key.hashCode() ^ value.hashCode()}.
+     *
+     * @return the hash code value for this map
+     */
+    public int hashCode() {
+        int h = 0;
+        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
+        Object v;
+        while ((v = it.advance()) != null) {
+            h += it.nextKey.hashCode() ^ v.hashCode();
+        }
+        return h;
+    }
+
+    /**
+     * Returns a string representation of this map.  The string
+     * representation consists of a list of key-value mappings (in no
+     * particular order) enclosed in braces ("{@code {}}").  Adjacent
+     * mappings are separated by the characters {@code ", "} (comma
+     * and space).  Each key-value mapping is rendered as the key
+     * followed by an equals sign ("{@code =}") followed by the
+     * associated value.
+     *
+     * @return a string representation of this map
+     */
+    public String toString() {
+        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
+        StringBuilder sb = new StringBuilder();
+        sb.append('{');
+        Object v;
+        if ((v = it.advance()) != null) {
+            for (;;) {
+                Object k = it.nextKey;
+                sb.append(k == this ? "(this Map)" : k);
+                sb.append('=');
+                sb.append(v == this ? "(this Map)" : v);
+                if ((v = it.advance()) == null)
+                    break;
+                sb.append(',').append(' ');
+            }
+        }
+        return sb.append('}').toString();
+    }
+
+    /**
+     * Compares the specified object with this map for equality.
+     * Returns {@code true} if the given object is a map with the same
+     * mappings as this map.  This operation may return misleading
+     * results if either map is concurrently modified during execution
+     * of this method.
+     *
+     * @param o object to be compared for equality with this map
+     * @return {@code true} if the specified object is equal to this map
+     */
+    public boolean equals(Object o) {
+        if (o != this) {
+            if (!(o instanceof Map))
+                return false;
+            Map<?,?> m = (Map<?,?>) o;
+            Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
+            Object val;
+            while ((val = it.advance()) != null) {
+                Object v = m.get(it.nextKey);
+                if (v == null || (v != val && !v.equals(val)))
+                    return false;
+            }
+            for (Map.Entry<?,?> e : m.entrySet()) {
+                Object mk, mv, v;
+                if ((mk = e.getKey()) == null ||
+                        (mv = e.getValue()) == null ||
+                        (v = internalGet(mk)) == null ||
+                        (mv != v && !mv.equals(v)))
+                    return false;
+            }
+        }
+        return true;
+    }
+
+    /* ----------------Iterators -------------- */
+
+    @SuppressWarnings("serial") static final class KeyIterator<K,V> extends Traverser<K,V,Object>
+            implements Spliterator<K>, Enumeration<K> {
+        KeyIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
+        KeyIterator(Traverser<K,V,Object> it) {
+            super(it);
+        }
+        public KeyIterator<K,V> split() {
+            if (nextKey != null)
+                throw new IllegalStateException();
+            return new KeyIterator<K,V>(this);
+        }
+        @SuppressWarnings("unchecked") public final K next() {
+            if (nextVal == null && advance() == null)
+                throw new NoSuchElementException();
+            Object k = nextKey;
+            nextVal = null;
+            return (K) k;
+        }
+
+        public final K nextElement() { return next(); }
+    }
+
+    @SuppressWarnings("serial") static final class ValueIterator<K,V> extends Traverser<K,V,Object>
+            implements Spliterator<V>, Enumeration<V> {
+        ValueIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
+        ValueIterator(Traverser<K,V,Object> it) {
+            super(it);
+        }
+        public ValueIterator<K,V> split() {
+            if (nextKey != null)
+                throw new IllegalStateException();
+            return new ValueIterator<K,V>(this);
+        }
+
+        @SuppressWarnings("unchecked") public final V next() {
+            Object v;
+            if ((v = nextVal) == null && (v = advance()) == null)
+                throw new NoSuchElementException();
+            nextVal = null;
+            return (V) v;
+        }
+
+        public final V nextElement() { return next(); }
+    }
+
+    @SuppressWarnings("serial") static final class EntryIterator<K,V> extends Traverser<K,V,Object>
+            implements Spliterator<Map.Entry<K,V>> {
+        EntryIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
+        EntryIterator(Traverser<K,V,Object> it) {
+            super(it);
+        }
+        public EntryIterator<K,V> split() {
+            if (nextKey != null)
+                throw new IllegalStateException();
+            return new EntryIterator<K,V>(this);
+        }
+
+        @SuppressWarnings("unchecked") public final Map.Entry<K,V> next() {
+            Object v;
+            if ((v = nextVal) == null && (v = advance()) == null)
+                throw new NoSuchElementException();
+            Object k = nextKey;
+            nextVal = null;
+            return new MapEntry<K,V>((K)k, (V)v, map);
+        }
+    }
+
+    /**
+     * Exported Entry for iterators
+     */
+    static final class MapEntry<K,V> implements Map.Entry<K, V> {
+        final K key; // non-null
+        V val;       // non-null
+        final ConcurrentHashMapV8<K, V> map;
+        MapEntry(K key, V val, ConcurrentHashMapV8<K, V> map) {
+            this.key = key;
+            this.val = val;
+            this.map = map;
+        }
+        public final K getKey()       { return key; }
+        public final V getValue()     { return val; }
+        public final int hashCode()   { return key.hashCode() ^ val.hashCode(); }
+        public final String toString(){ return key + "=" + val; }
+
+        public final boolean equals(Object o) {
+            Object k, v; Map.Entry<?,?> e;
+            return ((o instanceof Map.Entry) &&
+                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
+                    (v = e.getValue()) != null &&
+                    (k == key || k.equals(key)) &&
+                    (v == val || v.equals(val)));
+        }
+
+        /**
+         * Sets our entry's value and writes through to the map. The
+         * value to return is somewhat arbitrary here. Since we do not
+         * necessarily track asynchronous changes, the most recent
+         * "previous" value could be different from what we return (or
+         * could even have been removed in which case the put will
+         * re-establish). We do not and cannot guarantee more.
+         */
+        public final V setValue(V value) {
+            if (value == null) throw new NullPointerException();
+            V v = val;
+            val = value;
+            map.put(key, value);
+            return v;
+        }
+    }
+
+    /* ---------------- Serialization Support -------------- */
+
+    /**
+     * Stripped-down version of helper class used in previous version,
+     * declared for the sake of serialization compatibility
+     */
+    static class Segment<K,V> implements Serializable {
+        private static final long serialVersionUID = 2249069246763182397L;
+        final float loadFactor;
+        Segment(float lf) { this.loadFactor = lf; }
+    }
+
+    /**
+     * Saves the state of the {@code ConcurrentHashMapV8} instance to a
+     * stream (i.e., serializes it).
+     * @param s the stream
+     * @serialData
+     * the key (Object) and value (Object)
+     * for each key-value mapping, followed by a null pair.
+     * The key-value mappings are emitted in no particular order.
+     */
+    @SuppressWarnings("unchecked") private void writeObject(java.io.ObjectOutputStream s)
+            throws java.io.IOException {
+        if (segments == null) { // for serialization compatibility
+            segments = (Segment<K,V>[])
+                    new Segment<?,?>[DEFAULT_CONCURRENCY_LEVEL];
+            for (int i = 0; i < segments.length; ++i)
+                segments[i] = new Segment<K,V>(LOAD_FACTOR);
+        }
+        s.defaultWriteObject();
+        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
+        Object v;
+        while ((v = it.advance()) != null) {
+            s.writeObject(it.nextKey);
+            s.writeObject(v);
+        }
+        s.writeObject(null);
+        s.writeObject(null);
+        segments = null; // throw away
+    }
+
+    /**
+     * Reconstitutes the instance from a stream (that is, deserializes it).
+     * @param s the stream
+     */
+    @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s)
+            throws java.io.IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        this.segments = null; // unneeded
+        // initialize transient final field
+        UNSAFE.putObjectVolatile(this, counterOffset, new LongAdder());
+
+        // Create all nodes, then place in table once size is known
+        long size = 0L;
+        Node p = null;
+        for (;;) {
+            K k = (K) s.readObject();
+            V v = (V) s.readObject();
+            if (k != null && v != null) {
+                int h = spread(k.hashCode());
+                p = new Node(h, k, v, p);
+                ++size;
+            }
+            else
+                break;
+        }
+        if (p != null) {
+            boolean init = false;
+            int n;
+            if (size >= (long)(MAXIMUM_CAPACITY >>> 1))
+                n = MAXIMUM_CAPACITY;
+            else {
+                int sz = (int)size;
+                n = tableSizeFor(sz + (sz >>> 1) + 1);
+            }
+            int sc = sizeCtl;
+            boolean collide = false;
+            if (n > sc &&
+                    UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) {
+                try {
+                    if (table == null) {
+                        init = true;
+                        Node[] tab = new Node[n];
+                        int mask = n - 1;
+                        while (p != null) {
+                            int j = p.hash & mask;
+                            Node next = p.next;
+                            Node q = p.next = tabAt(tab, j);
+                            setTabAt(tab, j, p);
+                            if (!collide && q != null && q.hash == p.hash)
+                                collide = true;
+                            p = next;
+                        }
+                        table = tab;
+                        counter.add(size);
+                        sc = n - (n >>> 2);
+                    }
+                } finally {
+                    sizeCtl = sc;
+                }
+                if (collide) { // rescan and convert to TreeBins
+                    Node[] tab = table;
+                    for (int i = 0; i < tab.length; ++i) {
+                        int c = 0;
+                        for (Node e = tabAt(tab, i); e != null; e = e.next) {
+                            if (++c > TREE_THRESHOLD &&
+                                    (e.key instanceof Comparable)) {
+                                replaceWithTreeBin(tab, i, e.key);
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+            if (!init) { // Can only happen if unsafely published.
+                while (p != null) {
+                    internalPut(p.key, p.val);
+                    p = p.next;
+                }
+            }
+        }
+    }
+
+
+    // -------------------------------------------------------
+
+    // Sams
+    /** Interface describing a void action of one argument */
+    public interface Action<A> { void apply(A a); }
+    /** Interface describing a void action of two arguments */
+    public interface BiAction<A,B> { void apply(A a, B b); }
+    /** Interface describing a function of one argument */
+    public interface Generator<T> { T apply(); }
+    /** Interface describing a function mapping its argument to a double */
+    public interface ObjectToDouble<A> { double apply(A a); }
+    /** Interface describing a function mapping its argument to a long */
+    public interface ObjectToLong<A> { long apply(A a); }
+    /** Interface describing a function mapping its argument to an int */
+    public interface ObjectToInt<A> {int apply(A a); }
+    /** Interface describing a function mapping two arguments to a double */
+    public interface ObjectByObjectToDouble<A,B> { double apply(A a, B b); }
+    /** Interface describing a function mapping two arguments to a long */
+    public interface ObjectByObjectToLong<A,B> { long apply(A a, B b); }
+    /** Interface describing a function mapping two arguments to an int */
+    public interface ObjectByObjectToInt<A,B> {int apply(A a, B b); }
+    /** Interface describing a function mapping a double to a double */
+    public interface DoubleToDouble { double apply(double a); }
+    /** Interface describing a function mapping a long to a long */
+    public interface LongToLong { long apply(long a); }
+    /** Interface describing a function mapping an int to an int */
+    public interface IntToInt { int apply(int a); }
+    /** Interface describing a function mapping two doubles to a double */
+    public interface DoubleByDoubleToDouble { double apply(double a, double b); }
+    /** Interface describing a function mapping two longs to a long */
+    public interface LongByLongToLong { long apply(long a, long b); }
+    /** Interface describing a function mapping two ints to an int */
+    public interface IntByIntToInt { int apply(int a, int b); }
+
+
+    /* ----------------Views -------------- */
+
+    /**
+     * Base class for views.
+     */
+    static abstract class CHMView<K, V> {
+        final ConcurrentHashMapV8<K, V> map;
+        CHMView(ConcurrentHashMapV8<K, V> map)  { this.map = map; }
+
+        /**
+         * Returns the map backing this view.
+         *
+         * @return the map backing this view
+         */
+        public ConcurrentHashMapV8<K,V> getMap() { return map; }
+
+        public final int size()                 { return map.size(); }
+        public final boolean isEmpty()          { return map.isEmpty(); }
+        public final void clear()               { map.clear(); }
+
+        // implementations below rely on concrete classes supplying these
+        abstract public Iterator<?> iterator();
+        abstract public boolean contains(Object o);
+        abstract public boolean remove(Object o);
+
+        private static final String oomeMsg = "Required array size too large";
+
+        public final Object[] toArray() {
+            long sz = map.mappingCount();
+            if (sz > (long)(MAX_ARRAY_SIZE))
+                throw new OutOfMemoryError(oomeMsg);
+            int n = (int)sz;
+            Object[] r = new Object[n];
+            int i = 0;
+            Iterator<?> it = iterator();
+            while (it.hasNext()) {
+                if (i == n) {
+                    if (n >= MAX_ARRAY_SIZE)
+                        throw new OutOfMemoryError(oomeMsg);
+                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
+                        n = MAX_ARRAY_SIZE;
+                    else
+                        n += (n >>> 1) + 1;
+                    r = Arrays.copyOf(r, n);
+                }
+                r[i++] = it.next();
+            }
+            return (i == n) ? r : Arrays.copyOf(r, i);
+        }
+
+        @SuppressWarnings("unchecked") public final <T> T[] toArray(T[] a) {
+            long sz = map.mappingCount();
+            if (sz > (long)(MAX_ARRAY_SIZE))
+                throw new OutOfMemoryError(oomeMsg);
+            int m = (int)sz;
+            T[] r = (a.length >= m) ? a :
+                    (T[])java.lang.reflect.Array
+                            .newInstance(a.getClass().getComponentType(), m);
+            int n = r.length;
+            int i = 0;
+            Iterator<?> it = iterator();
+            while (it.hasNext()) {
+                if (i == n) {
+                    if (n >= MAX_ARRAY_SIZE)
+                        throw new OutOfMemoryError(oomeMsg);
+                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
+                        n = MAX_ARRAY_SIZE;
+                    else
+                        n += (n >>> 1) + 1;
+                    r = Arrays.copyOf(r, n);
+                }
+                r[i++] = (T)it.next();
+            }
+            if (a == r && i < n) {
+                r[i] = null; // null-terminate
+                return r;
+            }
+            return (i == n) ? r : Arrays.copyOf(r, i);
+        }
+
+        public final int hashCode() {
+            int h = 0;
+            for (Iterator<?> it = iterator(); it.hasNext();)
+                h += it.next().hashCode();
+            return h;
+        }
+
+        public final String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append('[');
+            Iterator<?> it = iterator();
+            if (it.hasNext()) {
+                for (;;) {
+                    Object e = it.next();
+                    sb.append(e == this ? "(this Collection)" : e);
+                    if (!it.hasNext())
+                        break;
+                    sb.append(',').append(' ');
+                }
+            }
+            return sb.append(']').toString();
+        }
+
+        public final boolean containsAll(Collection<?> c) {
+            if (c != this) {
+                for (Iterator<?> it = c.iterator(); it.hasNext();) {
+                    Object e = it.next();
+                    if (e == null || !contains(e))
+                        return false;
+                }
+            }
+            return true;
+        }
+
+        public final boolean removeAll(Collection<?> c) {
+            boolean modified = false;
+            for (Iterator<?> it = iterator(); it.hasNext();) {
+                if (c.contains(it.next())) {
+                    it.remove();
+                    modified = true;
+                }
+            }
+            return modified;
+        }
+
+        public final boolean retainAll(Collection<?> c) {
+            boolean modified = false;
+            for (Iterator<?> it = iterator(); it.hasNext();) {
+                if (!c.contains(it.next())) {
+                    it.remove();
+                    modified = true;
+                }
+            }
+            return modified;
+        }
+
+    }
+
+    /**
+     * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in
+     * which additions may optionally be enabled by mapping to a
+     * common value.  This class cannot be directly instantiated. See
+     * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()},
+     * {@link #newKeySet(int)}.
+     */
+    public static class KeySetView<K,V> extends CHMView<K,V> implements Set<K>, java.io.Serializable {
+        private static final long serialVersionUID = 7249069246763182397L;
+        private final V value;
+        KeySetView(ConcurrentHashMapV8<K, V> map, V value) {  // non-public
+            super(map);
+            this.value = value;
+        }
+
+        /**
+         * Returns the default mapped value for additions,
+         * or {@code null} if additions are not supported.
+         *
+         * @return the default mapped value for additions, or {@code null}
+         * if not supported.
+         */
+        public V getMappedValue() { return value; }
+
+        // implement Set API
+
+        public boolean contains(Object o) { return map.containsKey(o); }
+        public boolean remove(Object o)   { return map.remove(o) != null; }
+
+        /**
+         * Returns a "weakly consistent" iterator that will never
+         * throw {@link ConcurrentModificationException}, and
+         * guarantees to traverse elements as they existed upon
+         * construction of the iterator, and may (but is not
+         * guaranteed to) reflect any modifications subsequent to
+         * construction.
+         *
+         * @return an iterator over the keys of this map
+         */
+        public Iterator<K> iterator()     { return new KeyIterator<K,V>(map); }
+        public boolean add(K e) {
+            V v;
+            if ((v = value) == null)
+                throw new UnsupportedOperationException();
+            if (e == null)
+                throw new NullPointerException();
+            return map.internalPutIfAbsent(e, v) == null;
+        }
+        public boolean addAll(Collection<? extends K> c) {
+            boolean added = false;
+            V v;
+            if ((v = value) == null)
+                throw new UnsupportedOperationException();
+            for (K e : c) {
+                if (e == null)
+                    throw new NullPointerException();
+                if (map.internalPutIfAbsent(e, v) == null)
+                    added = true;
+            }
+            return added;
+        }
+        public boolean equals(Object o) {
+            Set<?> c;
+            return ((o instanceof Set) &&
+                    ((c = (Set<?>)o) == this ||
+                            (containsAll(c) && c.containsAll(this))));
+        }
+    }
+
+    /**
+     * A view of a ConcurrentHashMapV8 as a {@link Collection} of
+     * values, in which additions are disabled. This class cannot be
+     * directly instantiated. See {@link #values},
+     *
+     * <p>The view's {@code iterator} is a "weakly consistent" iterator
+     * that will never throw {@link ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     */
+    public static final class ValuesView<K,V> extends CHMView<K,V>
+            implements Collection<V> {
+        ValuesView(ConcurrentHashMapV8<K, V> map)   { super(map); }
+        public final boolean contains(Object o) { return map.containsValue(o); }
+        public final boolean remove(Object o) {
+            if (o != null) {
+                Iterator<V> it = new ValueIterator<K,V>(map);
+                while (it.hasNext()) {
+                    if (o.equals(it.next())) {
+                        it.remove();
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+        /**
+         * Returns a "weakly consistent" iterator that will never
+         * throw {@link ConcurrentModificationException}, and
+         * guarantees to traverse elements as they existed upon
+         * construction of the iterator, and may (but is not
+         * guaranteed to) reflect any modifications subsequent to
+         * construction.
+         *
+         * @return an iterator over the values of this map
+         */
+        public final Iterator<V> iterator() {
+            return new ValueIterator<K,V>(map);
+        }
+        public final boolean add(V e) {
+            throw new UnsupportedOperationException();
+        }
+        public final boolean addAll(Collection<? extends V> c) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    /**
+     * A view of a ConcurrentHashMapV8 as a {@link Set} of (key, value)
+     * entries.  This class cannot be directly instantiated. See
+     * {@link #entrySet}.
+     */
+    public static final class EntrySetView<K,V> extends CHMView<K,V>
+            implements Set<Map.Entry<K,V>> {
+        EntrySetView(ConcurrentHashMapV8<K, V> map) { super(map); }
+        public final boolean contains(Object o) {
+            Object k, v, r; Map.Entry<?,?> e;
+            return ((o instanceof Map.Entry) &&
+                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
+                    (r = map.get(k)) != null &&
+                    (v = e.getValue()) != null &&
+                    (v == r || v.equals(r)));
+        }
+        public final boolean remove(Object o) {
+            Object k, v; Map.Entry<?,?> e;
+            return ((o instanceof Map.Entry) &&
+                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
+                    (v = e.getValue()) != null &&
+                    map.remove(k, v));
+        }
+
+        /**
+         * Returns a "weakly consistent" iterator that will never
+         * throw {@link ConcurrentModificationException}, and
+         * guarantees to traverse elements as they existed upon
+         * construction of the iterator, and may (but is not
+         * guaranteed to) reflect any modifications subsequent to
+         * construction.
+         *
+         * @return an iterator over the entries of this map
+         */
+        public final Iterator<Map.Entry<K,V>> iterator() {
+            return new EntryIterator<K,V>(map);
+        }
+
+        public final boolean add(Entry<K,V> e) {
+            K key = e.getKey();
+            V value = e.getValue();
+            if (key == null || value == null)
+                throw new NullPointerException();
+            return map.internalPut(key, value) == null;
+        }
+        public final boolean addAll(Collection<? extends Entry<K,V>> c) {
+            boolean added = false;
+            for (Entry<K,V> e : c) {
+                if (add(e))
+                    added = true;
+            }
+            return added;
+        }
+        public boolean equals(Object o) {
+            Set<?> c;
+            return ((o instanceof Set) &&
+                    ((c = (Set<?>)o) == this ||
+                            (containsAll(c) && c.containsAll(this))));
+        }
+    }
+
+    // Unsafe mechanics
+    private static final sun.misc.Unsafe UNSAFE;
+    private static final long counterOffset;
+    private static final long sizeCtlOffset;
+    private static final long ABASE;
+    private static final int ASHIFT;
+
+    static {
+        int ss;
+        try {
+            UNSAFE = getUnsafe();
+            Class<?> k = ConcurrentHashMapV8.class;
+            counterOffset = UNSAFE.objectFieldOffset
+                    (k.getDeclaredField("counter"));
+            sizeCtlOffset = UNSAFE.objectFieldOffset
+                    (k.getDeclaredField("sizeCtl"));
+            Class<?> sc = Node[].class;
+            ABASE = UNSAFE.arrayBaseOffset(sc);
+            ss = UNSAFE.arrayIndexScale(sc);
+        } catch (Exception e) {
+            throw new Error(e);
+        }
+        if ((ss & (ss-1)) != 0)
+            throw new Error("data type scale not a power of two");
+        ASHIFT = 31 - Integer.numberOfLeadingZeros(ss);
+    }
+
+    /**
+     * Returns a sun.misc.Unsafe.  Suitable for use in a 3rd party package.
+     * Replace with a simple call to Unsafe.getUnsafe when integrating
+     * into a jdk.
+     *
+     * @return a sun.misc.Unsafe
+     */
+    private static sun.misc.Unsafe getUnsafe() {
+        try {
+            return sun.misc.Unsafe.getUnsafe();
+        } catch (SecurityException se) {
+            try {
+                return java.security.AccessController.doPrivileged
+                        (new java.security
+                                .PrivilegedExceptionAction<sun.misc.Unsafe>() {
+                            public sun.misc.Unsafe run() throws Exception {
+                                java.lang.reflect.Field f = sun.misc
+                                        .Unsafe.class.getDeclaredField("theUnsafe");
+                                f.setAccessible(true);
+                                return (sun.misc.Unsafe) f.get(null);
+                            }});
+            } catch (java.security.PrivilegedActionException e) {
+                throw new RuntimeException("Could not initialize intrinsics",
+                        e.getCause());
+            }
+        }
+    }
+}
diff --git a/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/LongAdder.java b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/LongAdder.java
new file mode 100644
index 0000000..22d0cbc
--- /dev/null
+++ b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/LongAdder.java
@@ -0,0 +1,203 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// This is based on 1.9 version.
+
+package org.jruby.ext.thread_safe.jsr166e;
+import java.util.concurrent.atomic.AtomicLong;
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.ObjectInputStream;
+
+/**
+ * One or more variables that together maintain an initially zero
+ * {@code long} sum.  When updates (method {@link #add}) are contended
+ * across threads, the set of variables may grow dynamically to reduce
+ * contention. Method {@link #sum} (or, equivalently, {@link
+ * #longValue}) returns the current total combined across the
+ * variables maintaining the sum.
+ *
+ * <p>This class is usually preferable to {@link AtomicLong} when
+ * multiple threads update a common sum that is used for purposes such
+ * as collecting statistics, not for fine-grained synchronization
+ * control.  Under low update contention, the two classes have similar
+ * characteristics. But under high contention, expected throughput of
+ * this class is significantly higher, at the expense of higher space
+ * consumption.
+ *
+ * <p>This class extends {@link Number}, but does <em>not</em> define
+ * methods such as {@code hashCode} and {@code compareTo} because
+ * instances are expected to be mutated, and so are not useful as
+ * collection keys.
+ *
+ * <p><em>jsr166e note: This class is targeted to be placed in
+ * java.util.concurrent.atomic.</em>
+ *
+ * @since 1.8
+ * @author Doug Lea
+ */
+public class LongAdder extends Striped64 implements Serializable {
+    private static final long serialVersionUID = 7249069246863182397L;
+
+    /**
+     * Version of plus for use in retryUpdate
+     */
+    final long fn(long v, long x) { return v + x; }
+
+    /**
+     * Creates a new adder with initial sum of zero.
+     */
+    public LongAdder() {
+    }
+
+    /**
+     * Adds the given value.
+     *
+     * @param x the value to add
+     */
+    public void add(long x) {
+        Cell[] as; long b, v; HashCode hc; Cell a; int n;
+        if ((as = cells) != null || !casBase(b = base, b + x)) {
+            boolean uncontended = true;
+            int h = (hc = threadHashCode.get()).code;
+            if (as == null || (n = as.length) < 1 ||
+                    (a = as[(n - 1) & h]) == null ||
+                    !(uncontended = a.cas(v = a.value, v + x)))
+                retryUpdate(x, hc, uncontended);
+        }
+    }
+
+    /**
+     * Equivalent to {@code add(1)}.
+     */
+    public void increment() {
+        add(1L);
+    }
+
+    /**
+     * Equivalent to {@code add(-1)}.
+     */
+    public void decrement() {
+        add(-1L);
+    }
+
+    /**
+     * Returns the current sum.  The returned value is <em>NOT</em> an
+     * atomic snapshot: Invocation in the absence of concurrent
+     * updates returns an accurate result, but concurrent updates that
+     * occur while the sum is being calculated might not be
+     * incorporated.
+     *
+     * @return the sum
+     */
+    public long sum() {
+        long sum = base;
+        Cell[] as = cells;
+        if (as != null) {
+            int n = as.length;
+            for (int i = 0; i < n; ++i) {
+                Cell a = as[i];
+                if (a != null)
+                    sum += a.value;
+            }
+        }
+        return sum;
+    }
+
+    /**
+     * Resets variables maintaining the sum to zero.  This method may
+     * be a useful alternative to creating a new adder, but is only
+     * effective if there are no concurrent updates.  Because this
+     * method is intrinsically racy, it should only be used when it is
+     * known that no threads are concurrently updating.
+     */
+    public void reset() {
+        internalReset(0L);
+    }
+
+    /**
+     * Equivalent in effect to {@link #sum} followed by {@link
+     * #reset}. This method may apply for example during quiescent
+     * points between multithreaded computations.  If there are
+     * updates concurrent with this method, the returned value is
+     * <em>not</em> guaranteed to be the final value occurring before
+     * the reset.
+     *
+     * @return the sum
+     */
+    public long sumThenReset() {
+        long sum = base;
+        Cell[] as = cells;
+        base = 0L;
+        if (as != null) {
+            int n = as.length;
+            for (int i = 0; i < n; ++i) {
+                Cell a = as[i];
+                if (a != null) {
+                    sum += a.value;
+                    a.value = 0L;
+                }
+            }
+        }
+        return sum;
+    }
+
+    /**
+     * Returns the String representation of the {@link #sum}.
+     * @return the String representation of the {@link #sum}
+     */
+    public String toString() {
+        return Long.toString(sum());
+    }
+
+    /**
+     * Equivalent to {@link #sum}.
+     *
+     * @return the sum
+     */
+    public long longValue() {
+        return sum();
+    }
+
+    /**
+     * Returns the {@link #sum} as an {@code int} after a narrowing
+     * primitive conversion.
+     */
+    public int intValue() {
+        return (int)sum();
+    }
+
+    /**
+     * Returns the {@link #sum} as a {@code float}
+     * after a widening primitive conversion.
+     */
+    public float floatValue() {
+        return (float)sum();
+    }
+
+    /**
+     * Returns the {@link #sum} as a {@code double} after a widening
+     * primitive conversion.
+     */
+    public double doubleValue() {
+        return (double)sum();
+    }
+
+    private void writeObject(java.io.ObjectOutputStream s)
+            throws java.io.IOException {
+        s.defaultWriteObject();
+        s.writeLong(sum());
+    }
+
+    private void readObject(ObjectInputStream s)
+            throws IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        busy = 0;
+        cells = null;
+        base = s.readLong();
+    }
+
+}
diff --git a/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/Striped64.java b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/Striped64.java
new file mode 100644
index 0000000..8651cdc
--- /dev/null
+++ b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/Striped64.java
@@ -0,0 +1,342 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// This is based on 1.5 version.
+
+package org.jruby.ext.thread_safe.jsr166e;
+import java.util.Random;
+
+/**
+ * A package-local class holding common representation and mechanics
+ * for classes supporting dynamic striping on 64bit values. The class
+ * extends Number so that concrete subclasses must publicly do so.
+ */
+abstract class Striped64 extends Number {
+    /*
+     * This class maintains a lazily-initialized table of atomically
+     * updated variables, plus an extra "base" field. The table size
+     * is a power of two. Indexing uses masked per-thread hash codes.
+     * Nearly all declarations in this class are package-private,
+     * accessed directly by subclasses.
+     *
+     * Table entries are of class Cell; a variant of AtomicLong padded
+     * to reduce cache contention on most processors. Padding is
+     * overkill for most Atomics because they are usually irregularly
+     * scattered in memory and thus don't interfere much with each
+     * other. But Atomic objects residing in arrays will tend to be
+     * placed adjacent to each other, and so will most often share
+     * cache lines (with a huge negative performance impact) without
+     * this precaution.
+     *
+     * In part because Cells are relatively large, we avoid creating
+     * them until they are needed.  When there is no contention, all
+     * updates are made to the base field.  Upon first contention (a
+     * failed CAS on base update), the table is initialized to size 2.
+     * The table size is doubled upon further contention until
+     * reaching the nearest power of two greater than or equal to the
+     * number of CPUS. Table slots remain empty (null) until they are
+     * needed.
+     *
+     * A single spinlock ("busy") is used for initializing and
+     * resizing the table, as well as populating slots with new Cells.
+     * There is no need for a blocking lock: When the lock is not
+     * available, threads try other slots (or the base).  During these
+     * retries, there is increased contention and reduced locality,
+     * which is still better than alternatives.
+     *
+     * Per-thread hash codes are initialized to random values.
+     * Contention and/or table collisions are indicated by failed
+     * CASes when performing an update operation (see method
+     * retryUpdate). Upon a collision, if the table size is less than
+     * the capacity, it is doubled in size unless some other thread
+     * holds the lock. If a hashed slot is empty, and lock is
+     * available, a new Cell is created. Otherwise, if the slot
+     * exists, a CAS is tried.  Retries proceed by "double hashing",
+     * using a secondary hash (Marsaglia XorShift) to try to find a
+     * free slot.
+     *
+     * The table size is capped because, when there are more threads
+     * than CPUs, supposing that each thread were bound to a CPU,
+     * there would exist a perfect hash function mapping threads to
+     * slots that eliminates collisions. When we reach capacity, we
+     * search for this mapping by randomly varying the hash codes of
+     * colliding threads.  Because search is random, and collisions
+     * only become known via CAS failures, convergence can be slow,
+     * and because threads are typically not bound to CPUS forever,
+     * may not occur at all. However, despite these limitations,
+     * observed contention rates are typically low in these cases.
+     *
+     * It is possible for a Cell to become unused when threads that
+     * once hashed to it terminate, as well as in the case where
+     * doubling the table causes no thread to hash to it under
+     * expanded mask.  We do not try to detect or remove such cells,
+     * under the assumption that for long-running instances, observed
+     * contention levels will recur, so the cells will eventually be
+     * needed again; and for short-lived ones, it does not matter.
+     */
+
+    /**
+     * Padded variant of AtomicLong supporting only raw accesses plus CAS.
+     * The value field is placed between pads, hoping that the JVM doesn't
+     * reorder them.
+     *
+     * JVM intrinsics note: It would be possible to use a release-only
+     * form of CAS here, if it were provided.
+     */
+    static final class Cell {
+        volatile long p0, p1, p2, p3, p4, p5, p6;
+        volatile long value;
+        volatile long q0, q1, q2, q3, q4, q5, q6;
+        Cell(long x) { value = x; }
+
+        final boolean cas(long cmp, long val) {
+            return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val);
+        }
+
+        // Unsafe mechanics
+        private static final sun.misc.Unsafe UNSAFE;
+        private static final long valueOffset;
+        static {
+            try {
+                UNSAFE = getUnsafe();
+                Class<?> ak = Cell.class;
+                valueOffset = UNSAFE.objectFieldOffset
+                        (ak.getDeclaredField("value"));
+            } catch (Exception e) {
+                throw new Error(e);
+            }
+        }
+
+    }
+
+    /**
+     * Holder for the thread-local hash code. The code is initially
+     * random, but may be set to a different value upon collisions.
+     */
+    static final class HashCode {
+        static final Random rng = new Random();
+        int code;
+        HashCode() {
+            int h = rng.nextInt(); // Avoid zero to allow xorShift rehash
+            code = (h == 0) ? 1 : h;
+        }
+    }
+
+    /**
+     * The corresponding ThreadLocal class
+     */
+    static final class ThreadHashCode extends ThreadLocal<HashCode> {
+        public HashCode initialValue() { return new HashCode(); }
+    }
+
+    /**
+     * Static per-thread hash codes. Shared across all instances to
+     * reduce ThreadLocal pollution and because adjustments due to
+     * collisions in one table are likely to be appropriate for
+     * others.
+     */
+    static final ThreadHashCode threadHashCode = new ThreadHashCode();
+
+    /** Number of CPUS, to place bound on table size */
+    static final int NCPU = Runtime.getRuntime().availableProcessors();
+
+    /**
+     * Table of cells. When non-null, size is a power of 2.
+     */
+    transient volatile Cell[] cells;
+
+    /**
+     * Base value, used mainly when there is no contention, but also as
+     * a fallback during table initialization races. Updated via CAS.
+     */
+    transient volatile long base;
+
+    /**
+     * Spinlock (locked via CAS) used when resizing and/or creating Cells.
+     */
+    transient volatile int busy;
+
+    /**
+     * Package-private default constructor
+     */
+    Striped64() {
+    }
+
+    /**
+     * CASes the base field.
+     */
+    final boolean casBase(long cmp, long val) {
+        return UNSAFE.compareAndSwapLong(this, baseOffset, cmp, val);
+    }
+
+    /**
+     * CASes the busy field from 0 to 1 to acquire lock.
+     */
+    final boolean casBusy() {
+        return UNSAFE.compareAndSwapInt(this, busyOffset, 0, 1);
+    }
+
+    /**
+     * Computes the function of current and new value. Subclasses
+     * should open-code this update function for most uses, but the
+     * virtualized form is needed within retryUpdate.
+     *
+     * @param currentValue the current value (of either base or a cell)
+     * @param newValue the argument from a user update call
+     * @return result of the update function
+     */
+    abstract long fn(long currentValue, long newValue);
+
+    /**
+     * Handles cases of updates involving initialization, resizing,
+     * creating new Cells, and/or contention. See above for
+     * explanation. This method suffers the usual non-modularity
+     * problems of optimistic retry code, relying on rechecked sets of
+     * reads.
+     *
+     * @param x the value
+     * @param hc the hash code holder
+     * @param wasUncontended false if CAS failed before call
+     */
+    final void retryUpdate(long x, HashCode hc, boolean wasUncontended) {
+        int h = hc.code;
+        boolean collide = false;                // True if last slot nonempty
+        for (;;) {
+            Cell[] as; Cell a; int n; long v;
+            if ((as = cells) != null && (n = as.length) > 0) {
+                if ((a = as[(n - 1) & h]) == null) {
+                    if (busy == 0) {            // Try to attach new Cell
+                        Cell r = new Cell(x);   // Optimistically create
+                        if (busy == 0 && casBusy()) {
+                            boolean created = false;
+                            try {               // Recheck under lock
+                                Cell[] rs; int m, j;
+                                if ((rs = cells) != null &&
+                                        (m = rs.length) > 0 &&
+                                        rs[j = (m - 1) & h] == null) {
+                                    rs[j] = r;
+                                    created = true;
+                                }
+                            } finally {
+                                busy = 0;
+                            }
+                            if (created)
+                                break;
+                            continue;           // Slot is now non-empty
+                        }
+                    }
+                    collide = false;
+                }
+                else if (!wasUncontended)       // CAS already known to fail
+                    wasUncontended = true;      // Continue after rehash
+                else if (a.cas(v = a.value, fn(v, x)))
+                    break;
+                else if (n >= NCPU || cells != as)
+                    collide = false;            // At max size or stale
+                else if (!collide)
+                    collide = true;
+                else if (busy == 0 && casBusy()) {
+                    try {
+                        if (cells == as) {      // Expand table unless stale
+                            Cell[] rs = new Cell[n << 1];
+                            for (int i = 0; i < n; ++i)
+                                rs[i] = as[i];
+                            cells = rs;
+                        }
+                    } finally {
+                        busy = 0;
+                    }
+                    collide = false;
+                    continue;                   // Retry with expanded table
+                }
+                h ^= h << 13;                   // Rehash
+                h ^= h >>> 17;
+                h ^= h << 5;
+            }
+            else if (busy == 0 && cells == as && casBusy()) {
+                boolean init = false;
+                try {                           // Initialize table
+                    if (cells == as) {
+                        Cell[] rs = new Cell[2];
+                        rs[h & 1] = new Cell(x);
+                        cells = rs;
+                        init = true;
+                    }
+                } finally {
+                    busy = 0;
+                }
+                if (init)
+                    break;
+            }
+            else if (casBase(v = base, fn(v, x)))
+                break;                          // Fall back on using base
+        }
+        hc.code = h;                            // Record index for next time
+    }
+
+
+    /**
+     * Sets base and all cells to the given value.
+     */
+    final void internalReset(long initialValue) {
+        Cell[] as = cells;
+        base = initialValue;
+        if (as != null) {
+            int n = as.length;
+            for (int i = 0; i < n; ++i) {
+                Cell a = as[i];
+                if (a != null)
+                    a.value = initialValue;
+            }
+        }
+    }
+
+    // Unsafe mechanics
+    private static final sun.misc.Unsafe UNSAFE;
+    private static final long baseOffset;
+    private static final long busyOffset;
+    static {
+        try {
+            UNSAFE = getUnsafe();
+            Class<?> sk = Striped64.class;
+            baseOffset = UNSAFE.objectFieldOffset
+                    (sk.getDeclaredField("base"));
+            busyOffset = UNSAFE.objectFieldOffset
+                    (sk.getDeclaredField("busy"));
+        } catch (Exception e) {
+            throw new Error(e);
+        }
+    }
+
+    /**
+     * Returns a sun.misc.Unsafe.  Suitable for use in a 3rd party package.
+     * Replace with a simple call to Unsafe.getUnsafe when integrating
+     * into a jdk.
+     *
+     * @return a sun.misc.Unsafe
+     */
+    private static sun.misc.Unsafe getUnsafe() {
+        try {
+            return sun.misc.Unsafe.getUnsafe();
+        } catch (SecurityException se) {
+            try {
+                return java.security.AccessController.doPrivileged
+                        (new java.security
+                                .PrivilegedExceptionAction<sun.misc.Unsafe>() {
+                            public sun.misc.Unsafe run() throws Exception {
+                                java.lang.reflect.Field f = sun.misc
+                                        .Unsafe.class.getDeclaredField("theUnsafe");
+                                f.setAccessible(true);
+                                return (sun.misc.Unsafe) f.get(null);
+                            }});
+            } catch (java.security.PrivilegedActionException e) {
+                throw new RuntimeException("Could not initialize intrinsics",
+                        e.getCause());
+            }
+        }
+    }
+
+}
diff --git a/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/nounsafe/ConcurrentHashMapV8.java b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/nounsafe/ConcurrentHashMapV8.java
new file mode 100644
index 0000000..4e1e33a
--- /dev/null
+++ b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/nounsafe/ConcurrentHashMapV8.java
@@ -0,0 +1,3800 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// This is based on the 1.79 version.
+
+package org.jruby.ext.thread_safe.jsr166e.nounsafe;
+
+import org.jruby.RubyClass;
+import org.jruby.RubyNumeric;
+import org.jruby.RubyObject;
+import org.jruby.exceptions.RaiseException;
+import org.jruby.ext.thread_safe.jsr166e.ConcurrentHashMap;
+import org.jruby.ext.thread_safe.jsr166y.ThreadLocalRandom;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.builtin.IRubyObject;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Enumeration;
+import java.util.ConcurrentModificationException;
+import java.util.NoSuchElementException;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+import java.util.concurrent.locks.AbstractQueuedSynchronizer;
+
+import java.io.Serializable;
+
+/**
+ * A hash table supporting full concurrency of retrievals and
+ * high expected concurrency for updates. This class obeys the
+ * same functional specification as {@link java.util.Hashtable}, and
+ * includes versions of methods corresponding to each method of
+ * {@code Hashtable}. However, even though all operations are
+ * thread-safe, retrieval operations do <em>not</em> entail locking,
+ * and there is <em>not</em> any support for locking the entire table
+ * in a way that prevents all access.  This class is fully
+ * interoperable with {@code Hashtable} in programs that rely on its
+ * thread safety but not on its synchronization details.
+ *
+ * <p>Retrieval operations (including {@code get}) generally do not
+ * block, so may overlap with update operations (including {@code put}
+ * and {@code remove}). Retrievals reflect the results of the most
+ * recently <em>completed</em> update operations holding upon their
+ * onset. (More formally, an update operation for a given key bears a
+ * <em>happens-before</em> relation with any (non-null) retrieval for
+ * that key reporting the updated value.)  For aggregate operations
+ * such as {@code putAll} and {@code clear}, concurrent retrievals may
+ * reflect insertion or removal of only some entries.  Similarly,
+ * Iterators and Enumerations return elements reflecting the state of
+ * the hash table at some point at or since the creation of the
+ * iterator/enumeration.  They do <em>not</em> throw {@link
+ * ConcurrentModificationException}.  However, iterators are designed
+ * to be used by only one thread at a time.  Bear in mind that the
+ * results of aggregate status methods including {@code size}, {@code
+ * isEmpty}, and {@code containsValue} are typically useful only when
+ * a map is not undergoing concurrent updates in other threads.
+ * Otherwise the results of these methods reflect transient states
+ * that may be adequate for monitoring or estimation purposes, but not
+ * for program control.
+ *
+ * <p>The table is dynamically expanded when there are too many
+ * collisions (i.e., keys that have distinct hash codes but fall into
+ * the same slot modulo the table size), with the expected average
+ * effect of maintaining roughly two bins per mapping (corresponding
+ * to a 0.75 load factor threshold for resizing). There may be much
+ * variance around this average as mappings are added and removed, but
+ * overall, this maintains a commonly accepted time/space tradeoff for
+ * hash tables.  However, resizing this or any other kind of hash
+ * table may be a relatively slow operation. When possible, it is a
+ * good idea to provide a size estimate as an optional {@code
+ * initialCapacity} constructor argument. An additional optional
+ * {@code loadFactor} constructor argument provides a further means of
+ * customizing initial table capacity by specifying the table density
+ * to be used in calculating the amount of space to allocate for the
+ * given number of elements.  Also, for compatibility with previous
+ * versions of this class, constructors may optionally specify an
+ * expected {@code concurrencyLevel} as an additional hint for
+ * internal sizing.  Note that using many keys with exactly the same
+ * {@code hashCode()} is a sure way to slow down performance of any
+ * hash table.
+ *
+ * <p>A {@link Set} projection of a ConcurrentHashMapV8 may be created
+ * (using {@link #newKeySet()} or {@link #newKeySet(int)}), or viewed
+ * (using {@link #keySet(Object)} when only keys are of interest, and the
+ * mapped values are (perhaps transiently) not used or all take the
+ * same mapping value.
+ *
+ * <p>A ConcurrentHashMapV8 can be used as scalable frequency map (a
+ * form of histogram or multiset) by using {@link LongAdder} values
+ * and initializing via {@link #computeIfAbsent}. For example, to add
+ * a count to a {@code ConcurrentHashMapV8<String,LongAdder> freqs}, you
+ * can use {@code freqs.computeIfAbsent(k -> new
+ * LongAdder()).increment();}
+ *
+ * <p>This class and its views and iterators implement all of the
+ * <em>optional</em> methods of the {@link Map} and {@link Iterator}
+ * interfaces.
+ *
+ * <p>Like {@link Hashtable} but unlike {@link HashMap}, this class
+ * does <em>not</em> allow {@code null} to be used as a key or value.
+ *
+ * <p>ConcurrentHashMapV8s support parallel operations using the {@link
+ * ForkJoinPool#commonPool}. (Tasks that may be used in other contexts
+ * are available in class {@link ForkJoinTasks}). These operations are
+ * designed to be safely, and often sensibly, applied even with maps
+ * that are being concurrently updated by other threads; for example,
+ * when computing a snapshot summary of the values in a shared
+ * registry.  There are three kinds of operation, each with four
+ * forms, accepting functions with Keys, Values, Entries, and (Key,
+ * Value) arguments and/or return values. (The first three forms are
+ * also available via the {@link #keySet()}, {@link #values()} and
+ * {@link #entrySet()} views). Because the elements of a
+ * ConcurrentHashMapV8 are not ordered in any particular way, and may be
+ * processed in different orders in different parallel executions, the
+ * correctness of supplied functions should not depend on any
+ * ordering, or on any other objects or values that may transiently
+ * change while computation is in progress; and except for forEach
+ * actions, should ideally be side-effect-free.
+ *
+ * <ul>
+ * <li> forEach: Perform a given action on each element.
+ * A variant form applies a given transformation on each element
+ * before performing the action.</li>
+ *
+ * <li> search: Return the first available non-null result of
+ * applying a given function on each element; skipping further
+ * search when a result is found.</li>
+ *
+ * <li> reduce: Accumulate each element.  The supplied reduction
+ * function cannot rely on ordering (more formally, it should be
+ * both associative and commutative).  There are five variants:
+ *
+ * <ul>
+ *
+ * <li> Plain reductions. (There is not a form of this method for
+ * (key, value) function arguments since there is no corresponding
+ * return type.)</li>
+ *
+ * <li> Mapped reductions that accumulate the results of a given
+ * function applied to each element.</li>
+ *
+ * <li> Reductions to scalar doubles, longs, and ints, using a
+ * given basis value.</li>
+ *
+ * </li>
+ * </ul>
+ * </ul>
+ *
+ * <p>The concurrency properties of bulk operations follow
+ * from those of ConcurrentHashMapV8: Any non-null result returned
+ * from {@code get(key)} and related access methods bears a
+ * happens-before relation with the associated insertion or
+ * update.  The result of any bulk operation reflects the
+ * composition of these per-element relations (but is not
+ * necessarily atomic with respect to the map as a whole unless it
+ * is somehow known to be quiescent).  Conversely, because keys
+ * and values in the map are never null, null serves as a reliable
+ * atomic indicator of the current lack of any result.  To
+ * maintain this property, null serves as an implicit basis for
+ * all non-scalar reduction operations. For the double, long, and
+ * int versions, the basis should be one that, when combined with
+ * any other value, returns that other value (more formally, it
+ * should be the identity element for the reduction). Most common
+ * reductions have these properties; for example, computing a sum
+ * with basis 0 or a minimum with basis MAX_VALUE.
+ *
+ * <p>Search and transformation functions provided as arguments
+ * should similarly return null to indicate the lack of any result
+ * (in which case it is not used). In the case of mapped
+ * reductions, this also enables transformations to serve as
+ * filters, returning null (or, in the case of primitive
+ * specializations, the identity basis) if the element should not
+ * be combined. You can create compound transformations and
+ * filterings by composing them yourself under this "null means
+ * there is nothing there now" rule before using them in search or
+ * reduce operations.
+ *
+ * <p>Methods accepting and/or returning Entry arguments maintain
+ * key-value associations. They may be useful for example when
+ * finding the key for the greatest value. Note that "plain" Entry
+ * arguments can be supplied using {@code new
+ * AbstractMap.SimpleEntry(k,v)}.
+ *
+ * <p>Bulk operations may complete abruptly, throwing an
+ * exception encountered in the application of a supplied
+ * function. Bear in mind when handling such exceptions that other
+ * concurrently executing functions could also have thrown
+ * exceptions, or would have done so if the first exception had
+ * not occurred.
+ *
+ * <p>Parallel speedups for bulk operations compared to sequential
+ * processing are common but not guaranteed.  Operations involving
+ * brief functions on small maps may execute more slowly than
+ * sequential loops if the underlying work to parallelize the
+ * computation is more expensive than the computation itself.
+ * Similarly, parallelization may not lead to much actual parallelism
+ * if all processors are busy performing unrelated tasks.
+ *
+ * <p>All arguments to all task methods must be non-null.
+ *
+ * <p><em>jsr166e note: During transition, this class
+ * uses nested functional interfaces with different names but the
+ * same forms as those expected for JDK8.</em>
+ *
+ * <p>This class is a member of the
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ * Java Collections Framework</a>.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <K> the type of keys maintained by this map
+ * @param <V> the type of mapped values
+ */
+public class ConcurrentHashMapV8<K, V>
+        implements ConcurrentMap<K, V>, Serializable, ConcurrentHashMap<K, V> {
+    private static final long serialVersionUID = 7249069246763182397L;
+
+    /**
+     * A partitionable iterator. A Spliterator can be traversed
+     * directly, but can also be partitioned (before traversal) by
+     * creating another Spliterator that covers a non-overlapping
+     * portion of the elements, and so may be amenable to parallel
+     * execution.
+     *
+     * <p>This interface exports a subset of expected JDK8
+     * functionality.
+     *
+     * <p>Sample usage: Here is one (of the several) ways to compute
+     * the sum of the values held in a map using the ForkJoin
+     * framework. As illustrated here, Spliterators are well suited to
+     * designs in which a task repeatedly splits off half its work
+     * into forked subtasks until small enough to process directly,
+     * and then joins these subtasks. Variants of this style can also
+     * be used in completion-based designs.
+     *
+     * <pre>
+     * {@code ConcurrentHashMapV8<String, Long> m = ...
+     * // split as if have 8 * parallelism, for load balance
+     * int n = m.size();
+     * int p = aForkJoinPool.getParallelism() * 8;
+     * int split = (n < p)? n : p;
+     * long sum = aForkJoinPool.invoke(new SumValues(m.valueSpliterator(), split, null));
+     * // ...
+     * static class SumValues extends RecursiveTask<Long> {
+     *   final Spliterator<Long> s;
+     *   final int split;             // split while > 1
+     *   final SumValues nextJoin;    // records forked subtasks to join
+     *   SumValues(Spliterator<Long> s, int depth, SumValues nextJoin) {
+     *     this.s = s; this.depth = depth; this.nextJoin = nextJoin;
+     *   }
+     *   public Long compute() {
+     *     long sum = 0;
+     *     SumValues subtasks = null; // fork subtasks
+     *     for (int s = split >>> 1; s > 0; s >>>= 1)
+     *       (subtasks = new SumValues(s.split(), s, subtasks)).fork();
+     *     while (s.hasNext())        // directly process remaining elements
+     *       sum += s.next();
+     *     for (SumValues t = subtasks; t != null; t = t.nextJoin)
+     *       sum += t.join();         // collect subtask results
+     *     return sum;
+     *   }
+     * }
+     * }</pre>
+     */
+    public static interface Spliterator<T> extends Iterator<T> {
+        /**
+         * Returns a Spliterator covering approximately half of the
+         * elements, guaranteed not to overlap with those subsequently
+         * returned by this Spliterator.  After invoking this method,
+         * the current Spliterator will <em>not</em> produce any of
+         * the elements of the returned Spliterator, but the two
+         * Spliterators together will produce all of the elements that
+         * would have been produced by this Spliterator had this
+         * method not been called. The exact number of elements
+         * produced by the returned Spliterator is not guaranteed, and
+         * may be zero (i.e., with {@code hasNext()} reporting {@code
+         * false}) if this Spliterator cannot be further split.
+         *
+         * @return a Spliterator covering approximately half of the
+         * elements
+         * @throws IllegalStateException if this Spliterator has
+         * already commenced traversing elements
+         */
+        Spliterator<T> split();
+    }
+
+
+    /*
+     * Overview:
+     *
+     * The primary design goal of this hash table is to maintain
+     * concurrent readability (typically method get(), but also
+     * iterators and related methods) while minimizing update
+     * contention. Secondary goals are to keep space consumption about
+     * the same or better than java.util.HashMap, and to support high
+     * initial insertion rates on an empty table by many threads.
+     *
+     * Each key-value mapping is held in a Node.  Because Node fields
+     * can contain special values, they are defined using plain Object
+     * types. Similarly in turn, all internal methods that use them
+     * work off Object types. And similarly, so do the internal
+     * methods of auxiliary iterator and view classes.  All public
+     * generic typed methods relay in/out of these internal methods,
+     * supplying null-checks and casts as needed. This also allows
+     * many of the public methods to be factored into a smaller number
+     * of internal methods (although sadly not so for the five
+     * variants of put-related operations). The validation-based
+     * approach explained below leads to a lot of code sprawl because
+     * retry-control precludes factoring into smaller methods.
+     *
+     * The table is lazily initialized to a power-of-two size upon the
+     * first insertion.  Each bin in the table normally contains a
+     * list of Nodes (most often, the list has only zero or one Node).
+     * Table accesses require volatile/atomic reads, writes, and
+     * CASes.  Because there is no other way to arrange this without
+     * adding further indirections, we use intrinsics
+     * (sun.misc.Unsafe) operations.  The lists of nodes within bins
+     * are always accurately traversable under volatile reads, so long
+     * as lookups check hash code and non-nullness of value before
+     * checking key equality.
+     *
+     * We use the top two bits of Node hash fields for control
+     * purposes -- they are available anyway because of addressing
+     * constraints.  As explained further below, these top bits are
+     * used as follows:
+     *  00 - Normal
+     *  01 - Locked
+     *  11 - Locked and may have a thread waiting for lock
+     *  10 - Node is a forwarding node
+     *
+     * The lower 30 bits of each Node's hash field contain a
+     * transformation of the key's hash code, except for forwarding
+     * nodes, for which the lower bits are zero (and so always have
+     * hash field == MOVED).
+     *
+     * Insertion (via put or its variants) of the first node in an
+     * empty bin is performed by just CASing it to the bin.  This is
+     * by far the most common case for put operations under most
+     * key/hash distributions.  Other update operations (insert,
+     * delete, and replace) require locks.  We do not want to waste
+     * the space required to associate a distinct lock object with
+     * each bin, so instead use the first node of a bin list itself as
+     * a lock. Blocking support for these locks relies on the builtin
+     * "synchronized" monitors.  However, we also need a tryLock
+     * construction, so we overlay these by using bits of the Node
+     * hash field for lock control (see above), and so normally use
+     * builtin monitors only for blocking and signalling using
+     * wait/notifyAll constructions. See Node.tryAwaitLock.
+     *
+     * Using the first node of a list as a lock does not by itself
+     * suffice though: When a node is locked, any update must first
+     * validate that it is still the first node after locking it, and
+     * retry if not. Because new nodes are always appended to lists,
+     * once a node is first in a bin, it remains first until deleted
+     * or the bin becomes invalidated (upon resizing).  However,
+     * operations that only conditionally update may inspect nodes
+     * until the point of update. This is a converse of sorts to the
+     * lazy locking technique described by Herlihy & Shavit.
+     *
+     * The main disadvantage of per-bin locks is that other update
+     * operations on other nodes in a bin list protected by the same
+     * lock can stall, for example when user equals() or mapping
+     * functions take a long time.  However, statistically, under
+     * random hash codes, this is not a common problem.  Ideally, the
+     * frequency of nodes in bins follows a Poisson distribution
+     * (http://en.wikipedia.org/wiki/Poisson_distribution) with a
+     * parameter of about 0.5 on average, given the resizing threshold
+     * of 0.75, although with a large variance because of resizing
+     * granularity. Ignoring variance, the expected occurrences of
+     * list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The
+     * first values are:
+     *
+     * 0:    0.60653066
+     * 1:    0.30326533
+     * 2:    0.07581633
+     * 3:    0.01263606
+     * 4:    0.00157952
+     * 5:    0.00015795
+     * 6:    0.00001316
+     * 7:    0.00000094
+     * 8:    0.00000006
+     * more: less than 1 in ten million
+     *
+     * Lock contention probability for two threads accessing distinct
+     * elements is roughly 1 / (8 * #elements) under random hashes.
+     *
+     * Actual hash code distributions encountered in practice
+     * sometimes deviate significantly from uniform randomness.  This
+     * includes the case when N > (1<<30), so some keys MUST collide.
+     * Similarly for dumb or hostile usages in which multiple keys are
+     * designed to have identical hash codes. Also, although we guard
+     * against the worst effects of this (see method spread), sets of
+     * hashes may differ only in bits that do not impact their bin
+     * index for a given power-of-two mask.  So we use a secondary
+     * strategy that applies when the number of nodes in a bin exceeds
+     * a threshold, and at least one of the keys implements
+     * Comparable.  These TreeBins use a balanced tree to hold nodes
+     * (a specialized form of red-black trees), bounding search time
+     * to O(log N).  Each search step in a TreeBin is around twice as
+     * slow as in a regular list, but given that N cannot exceed
+     * (1<<64) (before running out of addresses) this bounds search
+     * steps, lock hold times, etc, to reasonable constants (roughly
+     * 100 nodes inspected per operation worst case) so long as keys
+     * are Comparable (which is very common -- String, Long, etc).
+     * TreeBin nodes (TreeNodes) also maintain the same "next"
+     * traversal pointers as regular nodes, so can be traversed in
+     * iterators in the same way.
+     *
+     * The table is resized when occupancy exceeds a percentage
+     * threshold (nominally, 0.75, but see below).  Only a single
+     * thread performs the resize (using field "sizeCtl", to arrange
+     * exclusion), but the table otherwise remains usable for reads
+     * and updates. Resizing proceeds by transferring bins, one by
+     * one, from the table to the next table.  Because we are using
+     * power-of-two expansion, the elements from each bin must either
+     * stay at same index, or move with a power of two offset. We
+     * eliminate unnecessary node creation by catching cases where old
+     * nodes can be reused because their next fields won't change.  On
+     * average, only about one-sixth of them need cloning when a table
+     * doubles. The nodes they replace will be garbage collectable as
+     * soon as they are no longer referenced by any reader thread that
+     * may be in the midst of concurrently traversing table.  Upon
+     * transfer, the old table bin contains only a special forwarding
+     * node (with hash field "MOVED") that contains the next table as
+     * its key. On encountering a forwarding node, access and update
+     * operations restart, using the new table.
+     *
+     * Each bin transfer requires its bin lock. However, unlike other
+     * cases, a transfer can skip a bin if it fails to acquire its
+     * lock, and revisit it later (unless it is a TreeBin). Method
+     * rebuild maintains a buffer of TRANSFER_BUFFER_SIZE bins that
+     * have been skipped because of failure to acquire a lock, and
+     * blocks only if none are available (i.e., only very rarely).
+     * The transfer operation must also ensure that all accessible
+     * bins in both the old and new table are usable by any traversal.
+     * When there are no lock acquisition failures, this is arranged
+     * simply by proceeding from the last bin (table.length - 1) up
+     * towards the first.  Upon seeing a forwarding node, traversals
+     * (see class Iter) arrange to move to the new table
+     * without revisiting nodes.  However, when any node is skipped
+     * during a transfer, all earlier table bins may have become
+     * visible, so are initialized with a reverse-forwarding node back
+     * to the old table until the new ones are established. (This
+     * sometimes requires transiently locking a forwarding node, which
+     * is possible under the above encoding.) These more expensive
+     * mechanics trigger only when necessary.
+     *
+     * The traversal scheme also applies to partial traversals of
+     * ranges of bins (via an alternate Traverser constructor)
+     * to support partitioned aggregate operations.  Also, read-only
+     * operations give up if ever forwarded to a null table, which
+     * provides support for shutdown-style clearing, which is also not
+     * currently implemented.
+     *
+     * Lazy table initialization minimizes footprint until first use,
+     * and also avoids resizings when the first operation is from a
+     * putAll, constructor with map argument, or deserialization.
+     * These cases attempt to override the initial capacity settings,
+     * but harmlessly fail to take effect in cases of races.
+     *
+     * The element count is maintained using a LongAdder, which avoids
+     * contention on updates but can encounter cache thrashing if read
+     * too frequently during concurrent access. To avoid reading so
+     * often, resizing is attempted either when a bin lock is
+     * contended, or upon adding to a bin already holding two or more
+     * nodes (checked before adding in the xIfAbsent methods, after
+     * adding in others). Under uniform hash distributions, the
+     * probability of this occurring at threshold is around 13%,
+     * meaning that only about 1 in 8 puts check threshold (and after
+     * resizing, many fewer do so). But this approximation has high
+     * variance for small table sizes, so we check on any collision
+     * for sizes <= 64. The bulk putAll operation further reduces
+     * contention by only committing count updates upon these size
+     * checks.
+     *
+     * Maintaining API and serialization compatibility with previous
+     * versions of this class introduces several oddities. Mainly: We
+     * leave untouched but unused constructor arguments refering to
+     * concurrencyLevel. We accept a loadFactor constructor argument,
+     * but apply it only to initial table capacity (which is the only
+     * time that we can guarantee to honor it.) We also declare an
+     * unused "Segment" class that is instantiated in minimal form
+     * only when serializing.
+     */
+
+    /* ---------------- Constants -------------- */
+
+    /**
+     * The largest possible table capacity.  This value must be
+     * exactly 1<<30 to stay within Java array allocation and indexing
+     * bounds for power of two table sizes, and is further required
+     * because the top two bits of 32bit hash fields are used for
+     * control purposes.
+     */
+    private static final int MAXIMUM_CAPACITY = 1 << 30;
+
+    /**
+     * The default initial table capacity.  Must be a power of 2
+     * (i.e., at least 1) and at most MAXIMUM_CAPACITY.
+     */
+    private static final int DEFAULT_CAPACITY = 16;
+
+    /**
+     * The largest possible (non-power of two) array size.
+     * Needed by toArray and related methods.
+     */
+    static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+    /**
+     * The default concurrency level for this table. Unused but
+     * defined for compatibility with previous versions of this class.
+     */
+    private static final int DEFAULT_CONCURRENCY_LEVEL = 16;
+
+    /**
+     * The load factor for this table. Overrides of this value in
+     * constructors affect only the initial table capacity.  The
+     * actual floating point value isn't normally used -- it is
+     * simpler to use expressions such as {@code n - (n >>> 2)} for
+     * the associated resizing threshold.
+     */
+    private static final float LOAD_FACTOR = 0.75f;
+
+    /**
+     * The buffer size for skipped bins during transfers. The
+     * value is arbitrary but should be large enough to avoid
+     * most locking stalls during resizes.
+     */
+    private static final int TRANSFER_BUFFER_SIZE = 32;
+
+    /**
+     * The bin count threshold for using a tree rather than list for a
+     * bin.  The value reflects the approximate break-even point for
+     * using tree-based operations.
+     * Note that Doug's version defaults to 8, but when dealing with
+     * Ruby objects it is actually beneficial to avoid TreeNodes
+     * as long as possible as it usually means going into Ruby land.
+     */
+    private static final int TREE_THRESHOLD = 16;
+
+    /*
+     * Encodings for special uses of Node hash fields. See above for
+     * explanation.
+     */
+    static final int MOVED     = 0x80000000; // hash field for forwarding nodes
+    static final int LOCKED    = 0x40000000; // set/tested only as a bit
+    static final int WAITING   = 0xc0000000; // both bits set/tested together
+    static final int HASH_BITS = 0x3fffffff; // usable bits of normal node hash
+
+    /* ---------------- Fields -------------- */
+
+    /**
+     * The array of bins. Lazily initialized upon first insertion.
+     * Size is always a power of two. Accessed directly by iterators.
+     */
+    transient volatile AtomicReferenceArray<Node> table;
+
+    /**
+     * The counter maintaining number of elements.
+     */
+    private transient LongAdder counter;
+
+    /**
+     * Table initialization and resizing control.  When negative, the
+     * table is being initialized or resized. Otherwise, when table is
+     * null, holds the initial table size to use upon creation, or 0
+     * for default. After initialization, holds the next element count
+     * value upon which to resize the table.
+     */
+    private transient volatile int sizeCtl;
+
+    // views
+    private transient KeySetView<K,V> keySet;
+    private transient ValuesView<K,V> values;
+    private transient EntrySetView<K,V> entrySet;
+
+    /** For serialization compatibility. Null unless serialized; see below */
+    private Segment<K,V>[] segments;
+
+    static AtomicIntegerFieldUpdater SIZE_CTRL_UPDATER = AtomicIntegerFieldUpdater.newUpdater(ConcurrentHashMapV8.class, "sizeCtl");
+
+    /* ---------------- Table element access -------------- */
+
+    /*
+     * Volatile access methods are used for table elements as well as
+     * elements of in-progress next table while resizing.  Uses are
+     * null checked by callers, and implicitly bounds-checked, relying
+     * on the invariants that tab arrays have non-zero size, and all
+     * indices are masked with (tab.length - 1) which is never
+     * negative and always less than length. Note that, to be correct
+     * wrt arbitrary concurrency errors by users, bounds checks must
+     * operate on local variables, which accounts for some odd-looking
+     * inline assignments below.
+     */
+
+    static final Node tabAt(AtomicReferenceArray<Node> tab, int i) { // used by Iter
+        return tab.get(i);
+    }
+
+    private static final boolean casTabAt(AtomicReferenceArray<Node> tab, int i, Node c, Node v) {
+        return tab.compareAndSet(i, c, v);
+    }
+
+    private static final void setTabAt(AtomicReferenceArray<Node> tab, int i, Node v) {
+        tab.set(i, v);
+    }
+
+    /* ---------------- Nodes -------------- */
+
+    /**
+     * Key-value entry. Note that this is never exported out as a
+     * user-visible Map.Entry (see MapEntry below). Nodes with a hash
+     * field of MOVED are special, and do not contain user keys or
+     * values.  Otherwise, keys are never null, and null val fields
+     * indicate that a node is in the process of being deleted or
+     * created. For purposes of read-only access, a key may be read
+     * before a val, but can only be used after checking val to be
+     * non-null.
+     */
+    static class Node {
+        volatile int hash;
+        final Object key;
+        volatile Object val;
+        volatile Node next;
+
+        static AtomicIntegerFieldUpdater HASH_UPDATER = AtomicIntegerFieldUpdater.newUpdater(Node.class, "hash");
+
+        Node(int hash, Object key, Object val, Node next) {
+            this.hash = hash;
+            this.key = key;
+            this.val = val;
+            this.next = next;
+        }
+
+        /** CompareAndSet the hash field */
+        final boolean casHash(int cmp, int val) {
+            return HASH_UPDATER.compareAndSet(this, cmp, val);
+        }
+
+        /** The number of spins before blocking for a lock */
+        static final int MAX_SPINS =
+                Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1;
+
+        /**
+         * Spins a while if LOCKED bit set and this node is the first
+         * of its bin, and then sets WAITING bits on hash field and
+         * blocks (once) if they are still set.  It is OK for this
+         * method to return even if lock is not available upon exit,
+         * which enables these simple single-wait mechanics.
+         *
+         * The corresponding signalling operation is performed within
+         * callers: Upon detecting that WAITING has been set when
+         * unlocking lock (via a failed CAS from non-waiting LOCKED
+         * state), unlockers acquire the sync lock and perform a
+         * notifyAll.
+         *
+         * The initial sanity check on tab and bounds is not currently
+         * necessary in the only usages of this method, but enables
+         * use in other future contexts.
+         */
+        final void tryAwaitLock(AtomicReferenceArray<Node> tab, int i) {
+            if (tab != null && i >= 0 && i < tab.length()) { // sanity check
+                int r = ThreadLocalRandom.current().nextInt(); // randomize spins
+                int spins = MAX_SPINS, h;
+                while (tabAt(tab, i) == this && ((h = hash) & LOCKED) != 0) {
+                    if (spins >= 0) {
+                        r ^= r << 1; r ^= r >>> 3; r ^= r << 10; // xorshift
+                        if (r >= 0 && --spins == 0)
+                            Thread.yield();  // yield before block
+                    }
+                    else if (casHash(h, h | WAITING)) {
+                        synchronized (this) {
+                            if (tabAt(tab, i) == this &&
+                                    (hash & WAITING) == WAITING) {
+                                try {
+                                    wait();
+                                } catch (InterruptedException ie) {
+                                    Thread.currentThread().interrupt();
+                                }
+                            }
+                            else
+                                notifyAll(); // possibly won race vs signaller
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    /* ---------------- TreeBins -------------- */
+
+    /**
+     * Nodes for use in TreeBins
+     */
+    static final class TreeNode extends Node {
+        TreeNode parent;  // red-black tree links
+        TreeNode left;
+        TreeNode right;
+        TreeNode prev;    // needed to unlink next upon deletion
+        boolean red;
+
+        TreeNode(int hash, Object key, Object val, Node next, TreeNode parent) {
+            super(hash, key, val, next);
+            this.parent = parent;
+        }
+    }
+
+    /**
+     * A specialized form of red-black tree for use in bins
+     * whose size exceeds a threshold.
+     *
+     * TreeBins use a special form of comparison for search and
+     * related operations (which is the main reason we cannot use
+     * existing collections such as TreeMaps). TreeBins contain
+     * Comparable elements, but may contain others, as well as
+     * elements that are Comparable but not necessarily Comparable<T>
+     * for the same T, so we cannot invoke compareTo among them. To
+     * handle this, the tree is ordered primarily by hash value, then
+     * by getClass().getName() order, and then by Comparator order
+     * among elements of the same class.  On lookup at a node, if
+     * elements are not comparable or compare as 0, both left and
+     * right children may need to be searched in the case of tied hash
+     * values. (This corresponds to the full list search that would be
+     * necessary if all elements were non-Comparable and had tied
+     * hashes.)  The red-black balancing code is updated from
+     * pre-jdk-collections
+     * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java)
+     * based in turn on Cormen, Leiserson, and Rivest "Introduction to
+     * Algorithms" (CLR).
+     *
+     * TreeBins also maintain a separate locking discipline than
+     * regular bins. Because they are forwarded via special MOVED
+     * nodes at bin heads (which can never change once established),
+     * we cannot use those nodes as locks. Instead, TreeBin
+     * extends AbstractQueuedSynchronizer to support a simple form of
+     * read-write lock. For update operations and table validation,
+     * the exclusive form of lock behaves in the same way as bin-head
+     * locks. However, lookups use shared read-lock mechanics to allow
+     * multiple readers in the absence of writers.  Additionally,
+     * these lookups do not ever block: While the lock is not
+     * available, they proceed along the slow traversal path (via
+     * next-pointers) until the lock becomes available or the list is
+     * exhausted, whichever comes first. (These cases are not fast,
+     * but maximize aggregate expected throughput.)  The AQS mechanics
+     * for doing this are straightforward.  The lock state is held as
+     * AQS getState().  Read counts are negative; the write count (1)
+     * is positive.  There are no signalling preferences among readers
+     * and writers. Since we don't need to export full Lock API, we
+     * just override the minimal AQS methods and use them directly.
+     */
+    static final class TreeBin extends AbstractQueuedSynchronizer {
+        private static final long serialVersionUID = 2249069246763182397L;
+        transient TreeNode root;  // root of tree
+        transient TreeNode first; // head of next-pointer list
+
+        /* AQS overrides */
+        public final boolean isHeldExclusively() { return getState() > 0; }
+        public final boolean tryAcquire(int ignore) {
+            if (compareAndSetState(0, 1)) {
+                setExclusiveOwnerThread(Thread.currentThread());
+                return true;
+            }
+            return false;
+        }
+        public final boolean tryRelease(int ignore) {
+            setExclusiveOwnerThread(null);
+            setState(0);
+            return true;
+        }
+        public final int tryAcquireShared(int ignore) {
+            for (int c;;) {
+                if ((c = getState()) > 0)
+                    return -1;
+                if (compareAndSetState(c, c -1))
+                    return 1;
+            }
+        }
+        public final boolean tryReleaseShared(int ignore) {
+            int c;
+            do {} while (!compareAndSetState(c = getState(), c + 1));
+            return c == -1;
+        }
+
+        /** From CLR */
+        private void rotateLeft(TreeNode p) {
+            if (p != null) {
+                TreeNode r = p.right, pp, rl;
+                if ((rl = p.right = r.left) != null)
+                    rl.parent = p;
+                if ((pp = r.parent = p.parent) == null)
+                    root = r;
+                else if (pp.left == p)
+                    pp.left = r;
+                else
+                    pp.right = r;
+                r.left = p;
+                p.parent = r;
+            }
+        }
+
+        /** From CLR */
+        private void rotateRight(TreeNode p) {
+            if (p != null) {
+                TreeNode l = p.left, pp, lr;
+                if ((lr = p.left = l.right) != null)
+                    lr.parent = p;
+                if ((pp = l.parent = p.parent) == null)
+                    root = l;
+                else if (pp.right == p)
+                    pp.right = l;
+                else
+                    pp.left = l;
+                l.right = p;
+                p.parent = l;
+            }
+        }
+
+        @SuppressWarnings("unchecked") final TreeNode getTreeNode
+        (int h, Object k, TreeNode p) {
+            return getTreeNode(h, (RubyObject)k, p);
+        }
+
+        /**
+         * Returns the TreeNode (or null if not found) for the given key
+         * starting at given root.
+         */
+        @SuppressWarnings("unchecked") final TreeNode getTreeNode
+        (int h, RubyObject k, TreeNode p) {
+            RubyClass c = k.getMetaClass(); boolean kNotComparable = !k.respondsTo("<=>");
+            while (p != null) {
+                int dir, ph;  RubyObject pk; RubyClass pc;
+                if ((ph = p.hash) == h) {
+                    if ((pk = (RubyObject)p.key) == k || k.equals(pk))
+                        return p;
+                    if (c != (pc = (RubyClass)pk.getMetaClass()) ||
+                            kNotComparable ||
+                            (dir = rubyCompare(k, pk)) == 0) {
+                        dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName());
+                        if (dir == 0) { // if still stuck, need to check both sides
+                            TreeNode r = null, pl, pr;
+                            // try to recurse on the right
+                            if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null)
+                                return r;
+                            // try to continue iterating on the left side
+                            else if ((pl = p.left) != null && h <= pl.hash)
+                                dir = -1;
+                            else // no matching node found
+                                return null;
+                        }
+                    }
+                }
+                else
+                    dir = (h < ph) ? -1 : 1;
+                p = (dir > 0) ? p.right : p.left;
+            }
+            return null;
+        }
+
+        int rubyCompare(RubyObject l, RubyObject r) {
+            ThreadContext context = l.getMetaClass().getRuntime().getCurrentContext();
+            IRubyObject result;
+            try {
+                result = l.callMethod(context, "<=>", r);
+            } catch (RaiseException e) {
+                // handle objects "lying" about responding to <=>, ie: an Array containing non-comparable keys
+                if (context.runtime.getNoMethodError().isInstance(e.getException())) {
+                    return 0;
+                }
+                throw e;
+            }
+
+            return result.isNil() ? 0 : RubyNumeric.num2int(result.convertToInteger());
+        }
+
+        /**
+         * Wrapper for getTreeNode used by CHM.get. Tries to obtain
+         * read-lock to call getTreeNode, but during failure to get
+         * lock, searches along next links.
+         */
+        final Object getValue(int h, Object k) {
+            Node r = null;
+            int c = getState(); // Must read lock state first
+            for (Node e = first; e != null; e = e.next) {
+                if (c <= 0 && compareAndSetState(c, c - 1)) {
+                    try {
+                        r = getTreeNode(h, k, root);
+                    } finally {
+                        releaseShared(0);
+                    }
+                    break;
+                }
+                else if ((e.hash & HASH_BITS) == h && k.equals(e.key)) {
+                    r = e;
+                    break;
+                }
+                else
+                    c = getState();
+            }
+            return r == null ? null : r.val;
+        }
+
+        @SuppressWarnings("unchecked") final TreeNode putTreeNode
+                (int h, Object k, Object v) {
+            return putTreeNode(h, (RubyObject)k, v);
+        }
+
+        /**
+         * Finds or adds a node.
+         * @return null if added
+         */
+        @SuppressWarnings("unchecked") final TreeNode putTreeNode
+        (int h, RubyObject k, Object v) {
+            RubyClass c = k.getMetaClass();
+            boolean kNotComparable = !k.respondsTo("<=>");
+            TreeNode pp = root, p = null;
+            int dir = 0;
+            while (pp != null) { // find existing node or leaf to insert at
+                int ph;  RubyObject pk; RubyClass pc;
+                p = pp;
+                if ((ph = p.hash) == h) {
+                    if ((pk = (RubyObject)p.key) == k || k.equals(pk))
+                        return p;
+                    if (c != (pc = pk.getMetaClass()) ||
+                            kNotComparable ||
+                            (dir = rubyCompare(k, pk)) == 0) {
+                        dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName());
+                        if (dir == 0) { // if still stuck, need to check both sides
+                            TreeNode r = null, pr;
+                            // try to recurse on the right
+                            if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null)
+                                return r;
+                            else // continue descending down the left subtree
+                                dir = -1;
+                        }
+                    }
+                }
+                else
+                    dir = (h < ph) ? -1 : 1;
+                pp = (dir > 0) ? p.right : p.left;
+            }
+
+            TreeNode f = first;
+            TreeNode x = first = new TreeNode(h, (Object)k, v, f, p);
+            if (p == null)
+                root = x;
+            else { // attach and rebalance; adapted from CLR
+                TreeNode xp, xpp;
+                if (f != null)
+                    f.prev = x;
+                if (dir <= 0)
+                    p.left = x;
+                else
+                    p.right = x;
+                x.red = true;
+                while (x != null && (xp = x.parent) != null && xp.red &&
+                        (xpp = xp.parent) != null) {
+                    TreeNode xppl = xpp.left;
+                    if (xp == xppl) {
+                        TreeNode y = xpp.right;
+                        if (y != null && y.red) {
+                            y.red = false;
+                            xp.red = false;
+                            xpp.red = true;
+                            x = xpp;
+                        }
+                        else {
+                            if (x == xp.right) {
+                                rotateLeft(x = xp);
+                                xpp = (xp = x.parent) == null ? null : xp.parent;
+                            }
+                            if (xp != null) {
+                                xp.red = false;
+                                if (xpp != null) {
+                                    xpp.red = true;
+                                    rotateRight(xpp);
+                                }
+                            }
+                        }
+                    }
+                    else {
+                        TreeNode y = xppl;
+                        if (y != null && y.red) {
+                            y.red = false;
+                            xp.red = false;
+                            xpp.red = true;
+                            x = xpp;
+                        }
+                        else {
+                            if (x == xp.left) {
+                                rotateRight(x = xp);
+                                xpp = (xp = x.parent) == null ? null : xp.parent;
+                            }
+                            if (xp != null) {
+                                xp.red = false;
+                                if (xpp != null) {
+                                    xpp.red = true;
+                                    rotateLeft(xpp);
+                                }
+                            }
+                        }
+                    }
+                }
+                TreeNode r = root;
+                if (r != null && r.red)
+                    r.red = false;
+            }
+            return null;
+        }
+
+        /**
+         * Removes the given node, that must be present before this
+         * call.  This is messier than typical red-black deletion code
+         * because we cannot swap the contents of an interior node
+         * with a leaf successor that is pinned by "next" pointers
+         * that are accessible independently of lock. So instead we
+         * swap the tree linkages.
+         */
+        final void deleteTreeNode(TreeNode p) {
+            TreeNode next = (TreeNode)p.next; // unlink traversal pointers
+            TreeNode pred = p.prev;
+            if (pred == null)
+                first = next;
+            else
+                pred.next = next;
+            if (next != null)
+                next.prev = pred;
+            TreeNode replacement;
+            TreeNode pl = p.left;
+            TreeNode pr = p.right;
+            if (pl != null && pr != null) {
+                TreeNode s = pr, sl;
+                while ((sl = s.left) != null) // find successor
+                    s = sl;
+                boolean c = s.red; s.red = p.red; p.red = c; // swap colors
+                TreeNode sr = s.right;
+                TreeNode pp = p.parent;
+                if (s == pr) { // p was s's direct parent
+                    p.parent = s;
+                    s.right = p;
+                }
+                else {
+                    TreeNode sp = s.parent;
+                    if ((p.parent = sp) != null) {
+                        if (s == sp.left)
+                            sp.left = p;
+                        else
+                            sp.right = p;
+                    }
+                    if ((s.right = pr) != null)
+                        pr.parent = s;
+                }
+                p.left = null;
+                if ((p.right = sr) != null)
+                    sr.parent = p;
+                if ((s.left = pl) != null)
+                    pl.parent = s;
+                if ((s.parent = pp) == null)
+                    root = s;
+                else if (p == pp.left)
+                    pp.left = s;
+                else
+                    pp.right = s;
+                replacement = sr;
+            }
+            else
+                replacement = (pl != null) ? pl : pr;
+            TreeNode pp = p.parent;
+            if (replacement == null) {
+                if (pp == null) {
+                    root = null;
+                    return;
+                }
+                replacement = p;
+            }
+            else {
+                replacement.parent = pp;
+                if (pp == null)
+                    root = replacement;
+                else if (p == pp.left)
+                    pp.left = replacement;
+                else
+                    pp.right = replacement;
+                p.left = p.right = p.parent = null;
+            }
+            if (!p.red) { // rebalance, from CLR
+                TreeNode x = replacement;
+                while (x != null) {
+                    TreeNode xp, xpl;
+                    if (x.red || (xp = x.parent) == null) {
+                        x.red = false;
+                        break;
+                    }
+                    if (x == (xpl = xp.left)) {
+                        TreeNode sib = xp.right;
+                        if (sib != null && sib.red) {
+                            sib.red = false;
+                            xp.red = true;
+                            rotateLeft(xp);
+                            sib = (xp = x.parent) == null ? null : xp.right;
+                        }
+                        if (sib == null)
+                            x = xp;
+                        else {
+                            TreeNode sl = sib.left, sr = sib.right;
+                            if ((sr == null || !sr.red) &&
+                                    (sl == null || !sl.red)) {
+                                sib.red = true;
+                                x = xp;
+                            }
+                            else {
+                                if (sr == null || !sr.red) {
+                                    if (sl != null)
+                                        sl.red = false;
+                                    sib.red = true;
+                                    rotateRight(sib);
+                                    sib = (xp = x.parent) == null ? null : xp.right;
+                                }
+                                if (sib != null) {
+                                    sib.red = (xp == null) ? false : xp.red;
+                                    if ((sr = sib.right) != null)
+                                        sr.red = false;
+                                }
+                                if (xp != null) {
+                                    xp.red = false;
+                                    rotateLeft(xp);
+                                }
+                                x = root;
+                            }
+                        }
+                    }
+                    else { // symmetric
+                        TreeNode sib = xpl;
+                        if (sib != null && sib.red) {
+                            sib.red = false;
+                            xp.red = true;
+                            rotateRight(xp);
+                            sib = (xp = x.parent) == null ? null : xp.left;
+                        }
+                        if (sib == null)
+                            x = xp;
+                        else {
+                            TreeNode sl = sib.left, sr = sib.right;
+                            if ((sl == null || !sl.red) &&
+                                    (sr == null || !sr.red)) {
+                                sib.red = true;
+                                x = xp;
+                            }
+                            else {
+                                if (sl == null || !sl.red) {
+                                    if (sr != null)
+                                        sr.red = false;
+                                    sib.red = true;
+                                    rotateLeft(sib);
+                                    sib = (xp = x.parent) == null ? null : xp.left;
+                                }
+                                if (sib != null) {
+                                    sib.red = (xp == null) ? false : xp.red;
+                                    if ((sl = sib.left) != null)
+                                        sl.red = false;
+                                }
+                                if (xp != null) {
+                                    xp.red = false;
+                                    rotateRight(xp);
+                                }
+                                x = root;
+                            }
+                        }
+                    }
+                }
+            }
+            if (p == replacement && (pp = p.parent) != null) {
+                if (p == pp.left) // detach pointers
+                    pp.left = null;
+                else if (p == pp.right)
+                    pp.right = null;
+                p.parent = null;
+            }
+        }
+    }
+
+    /* ---------------- Collision reduction methods -------------- */
+
+    /**
+     * Spreads higher bits to lower, and also forces top 2 bits to 0.
+     * Because the table uses power-of-two masking, sets of hashes
+     * that vary only in bits above the current mask will always
+     * collide. (Among known examples are sets of Float keys holding
+     * consecutive whole numbers in small tables.)  To counter this,
+     * we apply a transform that spreads the impact of higher bits
+     * downward. There is a tradeoff between speed, utility, and
+     * quality of bit-spreading. Because many common sets of hashes
+     * are already reasonably distributed across bits (so don't benefit
+     * from spreading), and because we use trees to handle large sets
+     * of collisions in bins, we don't need excessively high quality.
+     */
+    private static final int spread(int h) {
+        h ^= (h >>> 18) ^ (h >>> 12);
+        return (h ^ (h >>> 10)) & HASH_BITS;
+    }
+
+    /**
+     * Replaces a list bin with a tree bin. Call only when locked.
+     * Fails to replace if the given key is non-comparable or table
+     * is, or needs, resizing.
+     */
+    private final void replaceWithTreeBin(AtomicReferenceArray<Node> tab, int index, Object key) {
+        if ((key instanceof Comparable) &&
+                (tab.length() >= MAXIMUM_CAPACITY || counter.sum() < (long)sizeCtl)) {
+            TreeBin t = new TreeBin();
+            for (Node e = tabAt(tab, index); e != null; e = e.next)
+                t.putTreeNode(e.hash & HASH_BITS, e.key, e.val);
+            setTabAt(tab, index, new Node(MOVED, t, null, null));
+        }
+    }
+
+    /* ---------------- Internal access and update methods -------------- */
+
+    /** Implementation for get and containsKey */
+    private final Object internalGet(Object k) {
+        int h = spread(k.hashCode());
+        retry: for (AtomicReferenceArray<Node> tab = table; tab != null;) {
+            Node e, p; Object ek, ev; int eh;      // locals to read fields once
+            for (e = tabAt(tab, (tab.length() - 1) & h); e != null; e = e.next) {
+                if ((eh = e.hash) == MOVED) {
+                    if ((ek = e.key) instanceof TreeBin)  // search TreeBin
+                        return ((TreeBin)ek).getValue(h, k);
+                    else {                        // restart with new table
+                        tab = (AtomicReferenceArray<Node>)ek;
+                        continue retry;
+                    }
+                }
+                else if ((eh & HASH_BITS) == h && (ev = e.val) != null &&
+                        ((ek = e.key) == k || k.equals(ek)))
+                    return ev;
+            }
+            break;
+        }
+        return null;
+    }
+
+    /**
+     * Implementation for the four public remove/replace methods:
+     * Replaces node value with v, conditional upon match of cv if
+     * non-null.  If resulting value is null, delete.
+     */
+    private final Object internalReplace(Object k, Object v, Object cv) {
+        int h = spread(k.hashCode());
+        Object oldVal = null;
+        for (AtomicReferenceArray<Node> tab = table;;) {
+            Node f; int i, fh; Object fk;
+            if (tab == null ||
+                    (f = tabAt(tab, i = (tab.length() - 1) & h)) == null)
+                break;
+            else if ((fh = f.hash) == MOVED) {
+                if ((fk = f.key) instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    boolean validated = false;
+                    boolean deleted = false;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            validated = true;
+                            TreeNode p = t.getTreeNode(h, k, t.root);
+                            if (p != null) {
+                                Object pv = p.val;
+                                if (cv == null || cv == pv || cv.equals(pv)) {
+                                    oldVal = pv;
+                                    if ((p.val = v) == null) {
+                                        deleted = true;
+                                        t.deleteTreeNode(p);
+                                    }
+                                }
+                            }
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                    if (validated) {
+                        if (deleted)
+                            counter.add(-1L);
+                        break;
+                    }
+                }
+                else
+                    tab = (AtomicReferenceArray<Node>)fk;
+            }
+            else if ((fh & HASH_BITS) != h && f.next == null) // precheck
+                break;                          // rules out possible existence
+            else if ((fh & LOCKED) != 0) {
+                checkForResize();               // try resizing if can't get lock
+                f.tryAwaitLock(tab, i);
+            }
+            else if (f.casHash(fh, fh | LOCKED)) {
+                boolean validated = false;
+                boolean deleted = false;
+                try {
+                    if (tabAt(tab, i) == f) {
+                        validated = true;
+                        for (Node e = f, pred = null;;) {
+                            Object ek, ev;
+                            if ((e.hash & HASH_BITS) == h &&
+                                    ((ev = e.val) != null) &&
+                                    ((ek = e.key) == k || k.equals(ek))) {
+                                if (cv == null || cv == ev || cv.equals(ev)) {
+                                    oldVal = ev;
+                                    if ((e.val = v) == null) {
+                                        deleted = true;
+                                        Node en = e.next;
+                                        if (pred != null)
+                                            pred.next = en;
+                                        else
+                                            setTabAt(tab, i, en);
+                                    }
+                                }
+                                break;
+                            }
+                            pred = e;
+                            if ((e = e.next) == null)
+                                break;
+                        }
+                    }
+                } finally {
+                    if (!f.casHash(fh | LOCKED, fh)) {
+                        f.hash = fh;
+                        synchronized (f) { f.notifyAll(); };
+                    }
+                }
+                if (validated) {
+                    if (deleted)
+                        counter.add(-1L);
+                    break;
+                }
+            }
+        }
+        return oldVal;
+    }
+
+    /*
+     * Internal versions of the six insertion methods, each a
+     * little more complicated than the last. All have
+     * the same basic structure as the first (internalPut):
+     *  1. If table uninitialized, create
+     *  2. If bin empty, try to CAS new node
+     *  3. If bin stale, use new table
+     *  4. if bin converted to TreeBin, validate and relay to TreeBin methods
+     *  5. Lock and validate; if valid, scan and add or update
+     *
+     * The others interweave other checks and/or alternative actions:
+     *  * Plain put checks for and performs resize after insertion.
+     *  * putIfAbsent prescans for mapping without lock (and fails to add
+     *    if present), which also makes pre-emptive resize checks worthwhile.
+     *  * computeIfAbsent extends form used in putIfAbsent with additional
+     *    mechanics to deal with, calls, potential exceptions and null
+     *    returns from function call.
+     *  * compute uses the same function-call mechanics, but without
+     *    the prescans
+     *  * merge acts as putIfAbsent in the absent case, but invokes the
+     *    update function if present
+     *  * putAll attempts to pre-allocate enough table space
+     *    and more lazily performs count updates and checks.
+     *
+     * Someday when details settle down a bit more, it might be worth
+     * some factoring to reduce sprawl.
+     */
+
+    /** Implementation for put */
+    private final Object internalPut(Object k, Object v) {
+        int h = spread(k.hashCode());
+        int count = 0;
+        for (AtomicReferenceArray<Node> tab = table;;) {
+            int i; Node f; int fh; Object fk;
+            if (tab == null)
+                tab = initTable();
+            else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) {
+                if (casTabAt(tab, i, null, new Node(h, k, v, null)))
+                    break;                   // no lock when adding to empty bin
+            }
+            else if ((fh = f.hash) == MOVED) {
+                if ((fk = f.key) instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    Object oldVal = null;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            count = 2;
+                            TreeNode p = t.putTreeNode(h, k, v);
+                            if (p != null) {
+                                oldVal = p.val;
+                                p.val = v;
+                            }
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                    if (count != 0) {
+                        if (oldVal != null)
+                            return oldVal;
+                        break;
+                    }
+                }
+                else
+                    tab = (AtomicReferenceArray<Node>)fk;
+            }
+            else if ((fh & LOCKED) != 0) {
+                checkForResize();
+                f.tryAwaitLock(tab, i);
+            }
+            else if (f.casHash(fh, fh | LOCKED)) {
+                Object oldVal = null;
+                try {                        // needed in case equals() throws
+                    if (tabAt(tab, i) == f) {
+                        count = 1;
+                        for (Node e = f;; ++count) {
+                            Object ek, ev;
+                            if ((e.hash & HASH_BITS) == h &&
+                                    (ev = e.val) != null &&
+                                    ((ek = e.key) == k || k.equals(ek))) {
+                                oldVal = ev;
+                                e.val = v;
+                                break;
+                            }
+                            Node last = e;
+                            if ((e = e.next) == null) {
+                                last.next = new Node(h, k, v, null);
+                                if (count >= TREE_THRESHOLD)
+                                    replaceWithTreeBin(tab, i, k);
+                                break;
+                            }
+                        }
+                    }
+                } finally {                  // unlock and signal if needed
+                    if (!f.casHash(fh | LOCKED, fh)) {
+                        f.hash = fh;
+                        synchronized (f) { f.notifyAll(); };
+                    }
+                }
+                if (count != 0) {
+                    if (oldVal != null)
+                        return oldVal;
+                    if (tab.length() <= 64)
+                        count = 2;
+                    break;
+                }
+            }
+        }
+        counter.add(1L);
+        if (count > 1)
+            checkForResize();
+        return null;
+    }
+
+    /** Implementation for putIfAbsent */
+    private final Object internalPutIfAbsent(Object k, Object v) {
+        int h = spread(k.hashCode());
+        int count = 0;
+        for (AtomicReferenceArray<Node> tab = table;;) {
+            int i; Node f; int fh; Object fk, fv;
+            if (tab == null)
+                tab = initTable();
+            else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) {
+                if (casTabAt(tab, i, null, new Node(h, k, v, null)))
+                    break;
+            }
+            else if ((fh = f.hash) == MOVED) {
+                if ((fk = f.key) instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    Object oldVal = null;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            count = 2;
+                            TreeNode p = t.putTreeNode(h, k, v);
+                            if (p != null)
+                                oldVal = p.val;
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                    if (count != 0) {
+                        if (oldVal != null)
+                            return oldVal;
+                        break;
+                    }
+                }
+                else
+                    tab = (AtomicReferenceArray<Node>)fk;
+            }
+            else if ((fh & HASH_BITS) == h && (fv = f.val) != null &&
+                    ((fk = f.key) == k || k.equals(fk)))
+                return fv;
+            else {
+                Node g = f.next;
+                if (g != null) { // at least 2 nodes -- search and maybe resize
+                    for (Node e = g;;) {
+                        Object ek, ev;
+                        if ((e.hash & HASH_BITS) == h && (ev = e.val) != null &&
+                                ((ek = e.key) == k || k.equals(ek)))
+                            return ev;
+                        if ((e = e.next) == null) {
+                            checkForResize();
+                            break;
+                        }
+                    }
+                }
+                if (((fh = f.hash) & LOCKED) != 0) {
+                    checkForResize();
+                    f.tryAwaitLock(tab, i);
+                }
+                else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) {
+                    Object oldVal = null;
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            count = 1;
+                            for (Node e = f;; ++count) {
+                                Object ek, ev;
+                                if ((e.hash & HASH_BITS) == h &&
+                                        (ev = e.val) != null &&
+                                        ((ek = e.key) == k || k.equals(ek))) {
+                                    oldVal = ev;
+                                    break;
+                                }
+                                Node last = e;
+                                if ((e = e.next) == null) {
+                                    last.next = new Node(h, k, v, null);
+                                    if (count >= TREE_THRESHOLD)
+                                        replaceWithTreeBin(tab, i, k);
+                                    break;
+                                }
+                            }
+                        }
+                    } finally {
+                        if (!f.casHash(fh | LOCKED, fh)) {
+                            f.hash = fh;
+                            synchronized (f) { f.notifyAll(); };
+                        }
+                    }
+                    if (count != 0) {
+                        if (oldVal != null)
+                            return oldVal;
+                        if (tab.length() <= 64)
+                            count = 2;
+                        break;
+                    }
+                }
+            }
+        }
+        counter.add(1L);
+        if (count > 1)
+            checkForResize();
+        return null;
+    }
+
+    /** Implementation for computeIfAbsent */
+    private final Object internalComputeIfAbsent(K k,
+                                                 Fun<? super K, ?> mf) {
+        int h = spread(k.hashCode());
+        Object val = null;
+        int count = 0;
+        for (AtomicReferenceArray<Node> tab = table;;) {
+            Node f; int i, fh; Object fk, fv;
+            if (tab == null)
+                tab = initTable();
+            else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) {
+                Node node = new Node(fh = h | LOCKED, k, null, null);
+                if (casTabAt(tab, i, null, node)) {
+                    count = 1;
+                    try {
+                        if ((val = mf.apply(k)) != null)
+                            node.val = val;
+                    } finally {
+                        if (val == null)
+                            setTabAt(tab, i, null);
+                        if (!node.casHash(fh, h)) {
+                            node.hash = h;
+                            synchronized (node) { node.notifyAll(); };
+                        }
+                    }
+                }
+                if (count != 0)
+                    break;
+            }
+            else if ((fh = f.hash) == MOVED) {
+                if ((fk = f.key) instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    boolean added = false;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            count = 1;
+                            TreeNode p = t.getTreeNode(h, k, t.root);
+                            if (p != null)
+                                val = p.val;
+                            else if ((val = mf.apply(k)) != null) {
+                                added = true;
+                                count = 2;
+                                t.putTreeNode(h, k, val);
+                            }
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                    if (count != 0) {
+                        if (!added)
+                            return val;
+                        break;
+                    }
+                }
+                else
+                    tab = (AtomicReferenceArray<Node>)fk;
+            }
+            else if ((fh & HASH_BITS) == h && (fv = f.val) != null &&
+                    ((fk = f.key) == k || k.equals(fk)))
+                return fv;
+            else {
+                Node g = f.next;
+                if (g != null) {
+                    for (Node e = g;;) {
+                        Object ek, ev;
+                        if ((e.hash & HASH_BITS) == h && (ev = e.val) != null &&
+                                ((ek = e.key) == k || k.equals(ek)))
+                            return ev;
+                        if ((e = e.next) == null) {
+                            checkForResize();
+                            break;
+                        }
+                    }
+                }
+                if (((fh = f.hash) & LOCKED) != 0) {
+                    checkForResize();
+                    f.tryAwaitLock(tab, i);
+                }
+                else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) {
+                    boolean added = false;
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            count = 1;
+                            for (Node e = f;; ++count) {
+                                Object ek, ev;
+                                if ((e.hash & HASH_BITS) == h &&
+                                        (ev = e.val) != null &&
+                                        ((ek = e.key) == k || k.equals(ek))) {
+                                    val = ev;
+                                    break;
+                                }
+                                Node last = e;
+                                if ((e = e.next) == null) {
+                                    if ((val = mf.apply(k)) != null) {
+                                        added = true;
+                                        last.next = new Node(h, k, val, null);
+                                        if (count >= TREE_THRESHOLD)
+                                            replaceWithTreeBin(tab, i, k);
+                                    }
+                                    break;
+                                }
+                            }
+                        }
+                    } finally {
+                        if (!f.casHash(fh | LOCKED, fh)) {
+                            f.hash = fh;
+                            synchronized (f) { f.notifyAll(); };
+                        }
+                    }
+                    if (count != 0) {
+                        if (!added)
+                            return val;
+                        if (tab.length() <= 64)
+                            count = 2;
+                        break;
+                    }
+                }
+            }
+        }
+        if (val != null) {
+            counter.add(1L);
+            if (count > 1)
+                checkForResize();
+        }
+        return val;
+    }
+
+    /** Implementation for compute */
+    @SuppressWarnings("unchecked") private final Object internalCompute
+    (K k, boolean onlyIfPresent, BiFun<? super K, ? super V, ? extends V> mf) {
+        int h = spread(k.hashCode());
+        Object val = null;
+        int delta = 0;
+        int count = 0;
+        for (AtomicReferenceArray<Node> tab = table;;) {
+            Node f; int i, fh; Object fk;
+            if (tab == null)
+                tab = initTable();
+            else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) {
+                if (onlyIfPresent)
+                    break;
+                Node node = new Node(fh = h | LOCKED, k, null, null);
+                if (casTabAt(tab, i, null, node)) {
+                    try {
+                        count = 1;
+                        if ((val = mf.apply(k, null)) != null) {
+                            node.val = val;
+                            delta = 1;
+                        }
+                    } finally {
+                        if (delta == 0)
+                            setTabAt(tab, i, null);
+                        if (!node.casHash(fh, h)) {
+                            node.hash = h;
+                            synchronized (node) { node.notifyAll(); };
+                        }
+                    }
+                }
+                if (count != 0)
+                    break;
+            }
+            else if ((fh = f.hash) == MOVED) {
+                if ((fk = f.key) instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            count = 1;
+                            TreeNode p = t.getTreeNode(h, k, t.root);
+                            Object pv;
+                            if (p == null) {
+                                if (onlyIfPresent)
+                                    break;
+                                pv = null;
+                            } else
+                                pv = p.val;
+                            if ((val = mf.apply(k, (V)pv)) != null) {
+                                if (p != null)
+                                    p.val = val;
+                                else {
+                                    count = 2;
+                                    delta = 1;
+                                    t.putTreeNode(h, k, val);
+                                }
+                            }
+                            else if (p != null) {
+                                delta = -1;
+                                t.deleteTreeNode(p);
+                            }
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                    if (count != 0)
+                        break;
+                }
+                else
+                    tab = (AtomicReferenceArray<Node>)fk;
+            }
+            else if ((fh & LOCKED) != 0) {
+                checkForResize();
+                f.tryAwaitLock(tab, i);
+            }
+            else if (f.casHash(fh, fh | LOCKED)) {
+                try {
+                    if (tabAt(tab, i) == f) {
+                        count = 1;
+                        for (Node e = f, pred = null;; ++count) {
+                            Object ek, ev;
+                            if ((e.hash & HASH_BITS) == h &&
+                                    (ev = e.val) != null &&
+                                    ((ek = e.key) == k || k.equals(ek))) {
+                                val = mf.apply(k, (V)ev);
+                                if (val != null)
+                                    e.val = val;
+                                else {
+                                    delta = -1;
+                                    Node en = e.next;
+                                    if (pred != null)
+                                        pred.next = en;
+                                    else
+                                        setTabAt(tab, i, en);
+                                }
+                                break;
+                            }
+                            pred = e;
+                            if ((e = e.next) == null) {
+                                if (!onlyIfPresent && (val = mf.apply(k, null)) != null) {
+                                    pred.next = new Node(h, k, val, null);
+                                    delta = 1;
+                                    if (count >= TREE_THRESHOLD)
+                                        replaceWithTreeBin(tab, i, k);
+                                }
+                                break;
+                            }
+                        }
+                    }
+                } finally {
+                    if (!f.casHash(fh | LOCKED, fh)) {
+                        f.hash = fh;
+                        synchronized (f) { f.notifyAll(); };
+                    }
+                }
+                if (count != 0) {
+                    if (tab.length() <= 64)
+                        count = 2;
+                    break;
+                }
+            }
+        }
+        if (delta != 0) {
+            counter.add((long)delta);
+            if (count > 1)
+                checkForResize();
+        }
+        return val;
+    }
+
+    /** Implementation for merge */
+    @SuppressWarnings("unchecked") private final Object internalMerge
+    (K k, V v, BiFun<? super V, ? super V, ? extends V> mf) {
+        int h = spread(k.hashCode());
+        Object val = null;
+        int delta = 0;
+        int count = 0;
+        for (AtomicReferenceArray<Node> tab = table;;) {
+            int i; Node f; int fh; Object fk, fv;
+            if (tab == null)
+                tab = initTable();
+            else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) {
+                if (casTabAt(tab, i, null, new Node(h, k, v, null))) {
+                    delta = 1;
+                    val = v;
+                    break;
+                }
+            }
+            else if ((fh = f.hash) == MOVED) {
+                if ((fk = f.key) instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            count = 1;
+                            TreeNode p = t.getTreeNode(h, k, t.root);
+                            val = (p == null) ? v : mf.apply((V)p.val, v);
+                            if (val != null) {
+                                if (p != null)
+                                    p.val = val;
+                                else {
+                                    count = 2;
+                                    delta = 1;
+                                    t.putTreeNode(h, k, val);
+                                }
+                            }
+                            else if (p != null) {
+                                delta = -1;
+                                t.deleteTreeNode(p);
+                            }
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                    if (count != 0)
+                        break;
+                }
+                else
+                    tab = (AtomicReferenceArray<Node>)fk;
+            }
+            else if ((fh & LOCKED) != 0) {
+                checkForResize();
+                f.tryAwaitLock(tab, i);
+            }
+            else if (f.casHash(fh, fh | LOCKED)) {
+                try {
+                    if (tabAt(tab, i) == f) {
+                        count = 1;
+                        for (Node e = f, pred = null;; ++count) {
+                            Object ek, ev;
+                            if ((e.hash & HASH_BITS) == h &&
+                                    (ev = e.val) != null &&
+                                    ((ek = e.key) == k || k.equals(ek))) {
+                                val = mf.apply((V)ev, v);
+                                if (val != null)
+                                    e.val = val;
+                                else {
+                                    delta = -1;
+                                    Node en = e.next;
+                                    if (pred != null)
+                                        pred.next = en;
+                                    else
+                                        setTabAt(tab, i, en);
+                                }
+                                break;
+                            }
+                            pred = e;
+                            if ((e = e.next) == null) {
+                                val = v;
+                                pred.next = new Node(h, k, val, null);
+                                delta = 1;
+                                if (count >= TREE_THRESHOLD)
+                                    replaceWithTreeBin(tab, i, k);
+                                break;
+                            }
+                        }
+                    }
+                } finally {
+                    if (!f.casHash(fh | LOCKED, fh)) {
+                        f.hash = fh;
+                        synchronized (f) { f.notifyAll(); };
+                    }
+                }
+                if (count != 0) {
+                    if (tab.length() <= 64)
+                        count = 2;
+                    break;
+                }
+            }
+        }
+        if (delta != 0) {
+            counter.add((long)delta);
+            if (count > 1)
+                checkForResize();
+        }
+        return val;
+    }
+
+    /** Implementation for putAll */
+    private final void internalPutAll(Map<?, ?> m) {
+        tryPresize(m.size());
+        long delta = 0L;     // number of uncommitted additions
+        boolean npe = false; // to throw exception on exit for nulls
+        try {                // to clean up counts on other exceptions
+            for (Map.Entry<?, ?> entry : m.entrySet()) {
+                Object k, v;
+                if (entry == null || (k = entry.getKey()) == null ||
+                        (v = entry.getValue()) == null) {
+                    npe = true;
+                    break;
+                }
+                int h = spread(k.hashCode());
+                for (AtomicReferenceArray<Node> tab = table;;) {
+                    int i; Node f; int fh; Object fk;
+                    if (tab == null)
+                        tab = initTable();
+                    else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null){
+                        if (casTabAt(tab, i, null, new Node(h, k, v, null))) {
+                            ++delta;
+                            break;
+                        }
+                    }
+                    else if ((fh = f.hash) == MOVED) {
+                        if ((fk = f.key) instanceof TreeBin) {
+                            TreeBin t = (TreeBin)fk;
+                            boolean validated = false;
+                            t.acquire(0);
+                            try {
+                                if (tabAt(tab, i) == f) {
+                                    validated = true;
+                                    TreeNode p = t.getTreeNode(h, k, t.root);
+                                    if (p != null)
+                                        p.val = v;
+                                    else {
+                                        t.putTreeNode(h, k, v);
+                                        ++delta;
+                                    }
+                                }
+                            } finally {
+                                t.release(0);
+                            }
+                            if (validated)
+                                break;
+                        }
+                        else
+                            tab = (AtomicReferenceArray<Node>)fk;
+                    }
+                    else if ((fh & LOCKED) != 0) {
+                        counter.add(delta);
+                        delta = 0L;
+                        checkForResize();
+                        f.tryAwaitLock(tab, i);
+                    }
+                    else if (f.casHash(fh, fh | LOCKED)) {
+                        int count = 0;
+                        try {
+                            if (tabAt(tab, i) == f) {
+                                count = 1;
+                                for (Node e = f;; ++count) {
+                                    Object ek, ev;
+                                    if ((e.hash & HASH_BITS) == h &&
+                                            (ev = e.val) != null &&
+                                            ((ek = e.key) == k || k.equals(ek))) {
+                                        e.val = v;
+                                        break;
+                                    }
+                                    Node last = e;
+                                    if ((e = e.next) == null) {
+                                        ++delta;
+                                        last.next = new Node(h, k, v, null);
+                                        if (count >= TREE_THRESHOLD)
+                                            replaceWithTreeBin(tab, i, k);
+                                        break;
+                                    }
+                                }
+                            }
+                        } finally {
+                            if (!f.casHash(fh | LOCKED, fh)) {
+                                f.hash = fh;
+                                synchronized (f) { f.notifyAll(); };
+                            }
+                        }
+                        if (count != 0) {
+                            if (count > 1) {
+                                counter.add(delta);
+                                delta = 0L;
+                                checkForResize();
+                            }
+                            break;
+                        }
+                    }
+                }
+            }
+        } finally {
+            if (delta != 0)
+                counter.add(delta);
+        }
+        if (npe)
+            throw new NullPointerException();
+    }
+
+    /* ---------------- Table Initialization and Resizing -------------- */
+
+    /**
+     * Returns a power of two table size for the given desired capacity.
+     * See Hackers Delight, sec 3.2
+     */
+    private static final int tableSizeFor(int c) {
+        int n = c - 1;
+        n |= n >>> 1;
+        n |= n >>> 2;
+        n |= n >>> 4;
+        n |= n >>> 8;
+        n |= n >>> 16;
+        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
+    }
+
+    /**
+     * Initializes table, using the size recorded in sizeCtl.
+     */
+    private final AtomicReferenceArray<Node> initTable() {
+        AtomicReferenceArray<Node> tab; int sc;
+        while ((tab = table) == null) {
+            if ((sc = sizeCtl) < 0)
+                Thread.yield(); // lost initialization race; just spin
+            else if (SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) {
+                try {
+                    if ((tab = table) == null) {
+                        int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
+                        tab = table = new AtomicReferenceArray<Node>(n);
+                        sc = n - (n >>> 2);
+                    }
+                } finally {
+                    sizeCtl = sc;
+                }
+                break;
+            }
+        }
+        return tab;
+    }
+
+    /**
+     * If table is too small and not already resizing, creates next
+     * table and transfers bins.  Rechecks occupancy after a transfer
+     * to see if another resize is already needed because resizings
+     * are lagging additions.
+     */
+    private final void checkForResize() {
+        AtomicReferenceArray<Node> tab; int n, sc;
+        while ((tab = table) != null &&
+                (n = tab.length()) < MAXIMUM_CAPACITY &&
+                (sc = sizeCtl) >= 0 && counter.sum() >= (long)sc &&
+                SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) {
+            try {
+                if (tab == table) {
+                    table = rebuild(tab);
+                    sc = (n << 1) - (n >>> 1);
+                }
+            } finally {
+                sizeCtl = sc;
+            }
+        }
+    }
+
+    /**
+     * Tries to presize table to accommodate the given number of elements.
+     *
+     * @param size number of elements (doesn't need to be perfectly accurate)
+     */
+    private final void tryPresize(int size) {
+        int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY :
+                tableSizeFor(size + (size >>> 1) + 1);
+        int sc;
+        while ((sc = sizeCtl) >= 0) {
+            AtomicReferenceArray<Node> tab = table; int n;
+            if (tab == null || (n = tab.length()) == 0) {
+                n = (sc > c) ? sc : c;
+                if (SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) {
+                    try {
+                        if (table == tab) {
+                            table = new AtomicReferenceArray<Node>(n);
+                            sc = n - (n >>> 2);
+                        }
+                    } finally {
+                        sizeCtl = sc;
+                    }
+                }
+            }
+            else if (c <= sc || n >= MAXIMUM_CAPACITY)
+                break;
+            else if (SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) {
+                try {
+                    if (table == tab) {
+                        table = rebuild(tab);
+                        sc = (n << 1) - (n >>> 1);
+                    }
+                } finally {
+                    sizeCtl = sc;
+                }
+            }
+        }
+    }
+
+    /*
+     * Moves and/or copies the nodes in each bin to new table. See
+     * above for explanation.
+     *
+     * @return the new table
+     */
+    private static final AtomicReferenceArray<Node> rebuild(AtomicReferenceArray<Node> tab) {
+        int n = tab.length();
+        AtomicReferenceArray<Node> nextTab = new AtomicReferenceArray<Node>(n << 1);
+        Node fwd = new Node(MOVED, nextTab, null, null);
+        int[] buffer = null;       // holds bins to revisit; null until needed
+        Node rev = null;           // reverse forwarder; null until needed
+        int nbuffered = 0;         // the number of bins in buffer list
+        int bufferIndex = 0;       // buffer index of current buffered bin
+        int bin = n - 1;           // current non-buffered bin or -1 if none
+
+        for (int i = bin;;) {      // start upwards sweep
+            int fh; Node f;
+            if ((f = tabAt(tab, i)) == null) {
+                if (bin >= 0) {    // Unbuffered; no lock needed (or available)
+                    if (!casTabAt(tab, i, f, fwd))
+                        continue;
+                }
+                else {             // transiently use a locked forwarding node
+                    Node g = new Node(MOVED|LOCKED, nextTab, null, null);
+                    if (!casTabAt(tab, i, f, g))
+                        continue;
+                    setTabAt(nextTab, i, null);
+                    setTabAt(nextTab, i + n, null);
+                    setTabAt(tab, i, fwd);
+                    if (!g.casHash(MOVED|LOCKED, MOVED)) {
+                        g.hash = MOVED;
+                        synchronized (g) { g.notifyAll(); }
+                    }
+                }
+            }
+            else if ((fh = f.hash) == MOVED) {
+                Object fk = f.key;
+                if (fk instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    boolean validated = false;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            validated = true;
+                            splitTreeBin(nextTab, i, t);
+                            setTabAt(tab, i, fwd);
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                    if (!validated)
+                        continue;
+                }
+            }
+            else if ((fh & LOCKED) == 0 && f.casHash(fh, fh|LOCKED)) {
+                boolean validated = false;
+                try {              // split to lo and hi lists; copying as needed
+                    if (tabAt(tab, i) == f) {
+                        validated = true;
+                        splitBin(nextTab, i, f);
+                        setTabAt(tab, i, fwd);
+                    }
+                } finally {
+                    if (!f.casHash(fh | LOCKED, fh)) {
+                        f.hash = fh;
+                        synchronized (f) { f.notifyAll(); };
+                    }
+                }
+                if (!validated)
+                    continue;
+            }
+            else {
+                if (buffer == null) // initialize buffer for revisits
+                    buffer = new int[TRANSFER_BUFFER_SIZE];
+                if (bin < 0 && bufferIndex > 0) {
+                    int j = buffer[--bufferIndex];
+                    buffer[bufferIndex] = i;
+                    i = j;         // swap with another bin
+                    continue;
+                }
+                if (bin < 0 || nbuffered >= TRANSFER_BUFFER_SIZE) {
+                    f.tryAwaitLock(tab, i);
+                    continue;      // no other options -- block
+                }
+                if (rev == null)   // initialize reverse-forwarder
+                    rev = new Node(MOVED, tab, null, null);
+                if (tabAt(tab, i) != f || (f.hash & LOCKED) == 0)
+                    continue;      // recheck before adding to list
+                buffer[nbuffered++] = i;
+                setTabAt(nextTab, i, rev);     // install place-holders
+                setTabAt(nextTab, i + n, rev);
+            }
+
+            if (bin > 0)
+                i = --bin;
+            else if (buffer != null && nbuffered > 0) {
+                bin = -1;
+                i = buffer[bufferIndex = --nbuffered];
+            }
+            else
+                return nextTab;
+        }
+    }
+
+    /**
+     * Splits a normal bin with list headed by e into lo and hi parts;
+     * installs in given table.
+     */
+    private static void splitBin(AtomicReferenceArray<Node> nextTab, int i, Node e) {
+        int bit = nextTab.length() >>> 1; // bit to split on
+        int runBit = e.hash & bit;
+        Node lastRun = e, lo = null, hi = null;
+        for (Node p = e.next; p != null; p = p.next) {
+            int b = p.hash & bit;
+            if (b != runBit) {
+                runBit = b;
+                lastRun = p;
+            }
+        }
+        if (runBit == 0)
+            lo = lastRun;
+        else
+            hi = lastRun;
+        for (Node p = e; p != lastRun; p = p.next) {
+            int ph = p.hash & HASH_BITS;
+            Object pk = p.key, pv = p.val;
+            if ((ph & bit) == 0)
+                lo = new Node(ph, pk, pv, lo);
+            else
+                hi = new Node(ph, pk, pv, hi);
+        }
+        setTabAt(nextTab, i, lo);
+        setTabAt(nextTab, i + bit, hi);
+    }
+
+    /**
+     * Splits a tree bin into lo and hi parts; installs in given table.
+     */
+    private static void splitTreeBin(AtomicReferenceArray<Node> nextTab, int i, TreeBin t) {
+        int bit = nextTab.length() >>> 1;
+        TreeBin lt = new TreeBin();
+        TreeBin ht = new TreeBin();
+        int lc = 0, hc = 0;
+        for (Node e = t.first; e != null; e = e.next) {
+            int h = e.hash & HASH_BITS;
+            Object k = e.key, v = e.val;
+            if ((h & bit) == 0) {
+                ++lc;
+                lt.putTreeNode(h, k, v);
+            }
+            else {
+                ++hc;
+                ht.putTreeNode(h, k, v);
+            }
+        }
+        Node ln, hn; // throw away trees if too small
+        if (lc <= (TREE_THRESHOLD >>> 1)) {
+            ln = null;
+            for (Node p = lt.first; p != null; p = p.next)
+                ln = new Node(p.hash, p.key, p.val, ln);
+        }
+        else
+            ln = new Node(MOVED, lt, null, null);
+        setTabAt(nextTab, i, ln);
+        if (hc <= (TREE_THRESHOLD >>> 1)) {
+            hn = null;
+            for (Node p = ht.first; p != null; p = p.next)
+                hn = new Node(p.hash, p.key, p.val, hn);
+        }
+        else
+            hn = new Node(MOVED, ht, null, null);
+        setTabAt(nextTab, i + bit, hn);
+    }
+
+    /**
+     * Implementation for clear. Steps through each bin, removing all
+     * nodes.
+     */
+    private final void internalClear() {
+        long delta = 0L; // negative number of deletions
+        int i = 0;
+        AtomicReferenceArray<Node> tab = table;
+        while (tab != null && i < tab.length()) {
+            int fh; Object fk;
+            Node f = tabAt(tab, i);
+            if (f == null)
+                ++i;
+            else if ((fh = f.hash) == MOVED) {
+                if ((fk = f.key) instanceof TreeBin) {
+                    TreeBin t = (TreeBin)fk;
+                    t.acquire(0);
+                    try {
+                        if (tabAt(tab, i) == f) {
+                            for (Node p = t.first; p != null; p = p.next) {
+                                if (p.val != null) { // (currently always true)
+                                    p.val = null;
+                                    --delta;
+                                }
+                            }
+                            t.first = null;
+                            t.root = null;
+                            ++i;
+                        }
+                    } finally {
+                        t.release(0);
+                    }
+                }
+                else
+                    tab = (AtomicReferenceArray<Node>)fk;
+            }
+            else if ((fh & LOCKED) != 0) {
+                counter.add(delta); // opportunistically update count
+                delta = 0L;
+                f.tryAwaitLock(tab, i);
+            }
+            else if (f.casHash(fh, fh | LOCKED)) {
+                try {
+                    if (tabAt(tab, i) == f) {
+                        for (Node e = f; e != null; e = e.next) {
+                            if (e.val != null) {  // (currently always true)
+                                e.val = null;
+                                --delta;
+                            }
+                        }
+                        setTabAt(tab, i, null);
+                        ++i;
+                    }
+                } finally {
+                    if (!f.casHash(fh | LOCKED, fh)) {
+                        f.hash = fh;
+                        synchronized (f) { f.notifyAll(); };
+                    }
+                }
+            }
+        }
+        if (delta != 0)
+            counter.add(delta);
+    }
+
+    /* ----------------Table Traversal -------------- */
+
+    /**
+     * Encapsulates traversal for methods such as containsValue; also
+     * serves as a base class for other iterators and bulk tasks.
+     *
+     * At each step, the iterator snapshots the key ("nextKey") and
+     * value ("nextVal") of a valid node (i.e., one that, at point of
+     * snapshot, has a non-null user value). Because val fields can
+     * change (including to null, indicating deletion), field nextVal
+     * might not be accurate at point of use, but still maintains the
+     * weak consistency property of holding a value that was once
+     * valid. To support iterator.remove, the nextKey field is not
+     * updated (nulled out) when the iterator cannot advance.
+     *
+     * Internal traversals directly access these fields, as in:
+     * {@code while (it.advance() != null) { process(it.nextKey); }}
+     *
+     * Exported iterators must track whether the iterator has advanced
+     * (in hasNext vs next) (by setting/checking/nulling field
+     * nextVal), and then extract key, value, or key-value pairs as
+     * return values of next().
+     *
+     * The iterator visits once each still-valid node that was
+     * reachable upon iterator construction. It might miss some that
+     * were added to a bin after the bin was visited, which is OK wrt
+     * consistency guarantees. Maintaining this property in the face
+     * of possible ongoing resizes requires a fair amount of
+     * bookkeeping state that is difficult to optimize away amidst
+     * volatile accesses.  Even so, traversal maintains reasonable
+     * throughput.
+     *
+     * Normally, iteration proceeds bin-by-bin traversing lists.
+     * However, if the table has been resized, then all future steps
+     * must traverse both the bin at the current index as well as at
+     * (index + baseSize); and so on for further resizings. To
+     * paranoically cope with potential sharing by users of iterators
+     * across threads, iteration terminates if a bounds checks fails
+     * for a table read.
+     *
+     * This class extends ForkJoinTask to streamline parallel
+     * iteration in bulk operations (see BulkTask). This adds only an
+     * int of space overhead, which is close enough to negligible in
+     * cases where it is not needed to not worry about it.  Because
+     * ForkJoinTask is Serializable, but iterators need not be, we
+     * need to add warning suppressions.
+     */
+    @SuppressWarnings("serial") static class Traverser<K,V,R> {
+        final ConcurrentHashMapV8<K, V> map;
+        Node next;           // the next entry to use
+        K nextKey;      // cached key field of next
+        V nextVal;      // cached val field of next
+        AtomicReferenceArray<Node> tab;          // current table; updated if resized
+        int index;           // index of bin to use next
+        int baseIndex;       // current index of initial table
+        int baseLimit;       // index bound for initial table
+        int baseSize;        // initial table size
+
+        /** Creates iterator for all entries in the table. */
+        Traverser(ConcurrentHashMapV8<K, V> map) {
+            this.map = map;
+        }
+
+        /** Creates iterator for split() methods */
+        Traverser(Traverser<K,V,?> it) {
+            ConcurrentHashMapV8<K, V> m; AtomicReferenceArray<Node> t;
+            if ((m = this.map = it.map) == null)
+                t = null;
+            else if ((t = it.tab) == null && // force parent tab initialization
+                    (t = it.tab = m.table) != null)
+                it.baseLimit = it.baseSize = t.length();
+            this.tab = t;
+            this.baseSize = it.baseSize;
+            it.baseLimit = this.index = this.baseIndex =
+                    ((this.baseLimit = it.baseLimit) + it.baseIndex + 1) >>> 1;
+        }
+
+        /**
+         * Advances next; returns nextVal or null if terminated.
+         * See above for explanation.
+         */
+        final V advance() {
+            Node e = next;
+            V ev = null;
+            outer: do {
+                if (e != null)                  // advance past used/skipped node
+                    e = e.next;
+                while (e == null) {             // get to next non-null bin
+                    ConcurrentHashMapV8<K, V> m;
+                    AtomicReferenceArray<Node> t; int b, i, n; Object ek; // checks must use locals
+                    if ((t = tab) != null)
+                        n = t.length();
+                    else if ((m = map) != null && (t = tab = m.table) != null)
+                        n = baseLimit = baseSize = t.length();
+                    else
+                        break outer;
+                    if ((b = baseIndex) >= baseLimit ||
+                            (i = index) < 0 || i >= n)
+                        break outer;
+                    if ((e = tabAt(t, i)) != null && e.hash == MOVED) {
+                        if ((ek = e.key) instanceof TreeBin)
+                            e = ((TreeBin)ek).first;
+                        else {
+                            tab = (AtomicReferenceArray<Node>)ek;
+                            continue;           // restarts due to null val
+                        }
+                    }                           // visit upper slots if present
+                    index = (i += baseSize) < n ? i : (baseIndex = b + 1);
+                }
+                nextKey = (K) e.key;
+            } while ((ev = (V) e.val) == null);    // skip deleted or special nodes
+            next = e;
+            return nextVal = ev;
+        }
+
+        public final void remove() {
+            Object k = nextKey;
+            if (k == null && (advance() == null || (k = nextKey) == null))
+                throw new IllegalStateException();
+            map.internalReplace(k, null, null);
+        }
+
+        public final boolean hasNext() {
+            return nextVal != null || advance() != null;
+        }
+
+        public final boolean hasMoreElements() { return hasNext(); }
+        public final void setRawResult(Object x) { }
+        public R getRawResult() { return null; }
+        public boolean exec() { return true; }
+    }
+
+    /* ---------------- Public operations -------------- */
+
+    /**
+     * Creates a new, empty map with the default initial table size (16).
+     */
+    public ConcurrentHashMapV8() {
+        this.counter = new LongAdder();
+    }
+
+    /**
+     * Creates a new, empty map with an initial table size
+     * accommodating the specified number of elements without the need
+     * to dynamically resize.
+     *
+     * @param initialCapacity The implementation performs internal
+     * sizing to accommodate this many elements.
+     * @throws IllegalArgumentException if the initial capacity of
+     * elements is negative
+     */
+    public ConcurrentHashMapV8(int initialCapacity) {
+        if (initialCapacity < 0)
+            throw new IllegalArgumentException();
+        int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ?
+                MAXIMUM_CAPACITY :
+                tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1));
+        this.counter = new LongAdder();
+        this.sizeCtl = cap;
+    }
+
+    /**
+     * Creates a new map with the same mappings as the given map.
+     *
+     * @param m the map
+     */
+    public ConcurrentHashMapV8(Map<? extends K, ? extends V> m) {
+        this.counter = new LongAdder();
+        this.sizeCtl = DEFAULT_CAPACITY;
+        internalPutAll(m);
+    }
+
+    /**
+     * Creates a new, empty map with an initial table size based on
+     * the given number of elements ({@code initialCapacity}) and
+     * initial table density ({@code loadFactor}).
+     *
+     * @param initialCapacity the initial capacity. The implementation
+     * performs internal sizing to accommodate this many elements,
+     * given the specified load factor.
+     * @param loadFactor the load factor (table density) for
+     * establishing the initial table size
+     * @throws IllegalArgumentException if the initial capacity of
+     * elements is negative or the load factor is nonpositive
+     *
+     * @since 1.6
+     */
+    public ConcurrentHashMapV8(int initialCapacity, float loadFactor) {
+        this(initialCapacity, loadFactor, 1);
+    }
+
+    /**
+     * Creates a new, empty map with an initial table size based on
+     * the given number of elements ({@code initialCapacity}), table
+     * density ({@code loadFactor}), and number of concurrently
+     * updating threads ({@code concurrencyLevel}).
+     *
+     * @param initialCapacity the initial capacity. The implementation
+     * performs internal sizing to accommodate this many elements,
+     * given the specified load factor.
+     * @param loadFactor the load factor (table density) for
+     * establishing the initial table size
+     * @param concurrencyLevel the estimated number of concurrently
+     * updating threads. The implementation may use this value as
+     * a sizing hint.
+     * @throws IllegalArgumentException if the initial capacity is
+     * negative or the load factor or concurrencyLevel are
+     * nonpositive
+     */
+    public ConcurrentHashMapV8(int initialCapacity,
+                               float loadFactor, int concurrencyLevel) {
+        if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0)
+            throw new IllegalArgumentException();
+        if (initialCapacity < concurrencyLevel)   // Use at least as many bins
+            initialCapacity = concurrencyLevel;   // as estimated threads
+        long size = (long)(1.0 + (long)initialCapacity / loadFactor);
+        int cap = (size >= (long)MAXIMUM_CAPACITY) ?
+                MAXIMUM_CAPACITY : tableSizeFor((int)size);
+        this.counter = new LongAdder();
+        this.sizeCtl = cap;
+    }
+
+    /**
+     * Creates a new {@link Set} backed by a ConcurrentHashMapV8
+     * from the given type to {@code Boolean.TRUE}.
+     *
+     * @return the new set
+     */
+    public static <K> KeySetView<K,Boolean> newKeySet() {
+        return new KeySetView<K,Boolean>(new ConcurrentHashMapV8<K,Boolean>(),
+                Boolean.TRUE);
+    }
+
+    /**
+     * Creates a new {@link Set} backed by a ConcurrentHashMapV8
+     * from the given type to {@code Boolean.TRUE}.
+     *
+     * @param initialCapacity The implementation performs internal
+     * sizing to accommodate this many elements.
+     * @throws IllegalArgumentException if the initial capacity of
+     * elements is negative
+     * @return the new set
+     */
+    public static <K> KeySetView<K,Boolean> newKeySet(int initialCapacity) {
+        return new KeySetView<K,Boolean>(new ConcurrentHashMapV8<K,Boolean>(initialCapacity),
+                Boolean.TRUE);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isEmpty() {
+        return counter.sum() <= 0L; // ignore transient negative values
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int size() {
+        long n = counter.sum();
+        return ((n < 0L) ? 0 :
+                (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE :
+                        (int)n);
+    }
+
+    /**
+     * Returns the number of mappings. This method should be used
+     * instead of {@link #size} because a ConcurrentHashMapV8 may
+     * contain more mappings than can be represented as an int. The
+     * value returned is a snapshot; the actual count may differ if
+     * there are ongoing concurrent insertions or removals.
+     *
+     * @return the number of mappings
+     */
+    public long mappingCount() {
+        long n = counter.sum();
+        return (n < 0L) ? 0L : n; // ignore transient negative values
+    }
+
+    /**
+     * Returns the value to which the specified key is mapped,
+     * or {@code null} if this map contains no mapping for the key.
+     *
+     * <p>More formally, if this map contains a mapping from a key
+     * {@code k} to a value {@code v} such that {@code key.equals(k)},
+     * then this method returns {@code v}; otherwise it returns
+     * {@code null}.  (There can be at most one such mapping.)
+     *
+     * @throws NullPointerException if the specified key is null
+     */
+    @SuppressWarnings("unchecked") public V get(Object key) {
+        if (key == null)
+            throw new NullPointerException();
+        return (V)internalGet(key);
+    }
+
+    /**
+     * Returns the value to which the specified key is mapped,
+     * or the given defaultValue if this map contains no mapping for the key.
+     *
+     * @param key the key
+     * @param defaultValue the value to return if this map contains
+     * no mapping for the given key
+     * @return the mapping for the key, if present; else the defaultValue
+     * @throws NullPointerException if the specified key is null
+     */
+    @SuppressWarnings("unchecked") public V getValueOrDefault(Object key, V defaultValue) {
+        if (key == null)
+            throw new NullPointerException();
+        V v = (V) internalGet(key);
+        return v == null ? defaultValue : v;
+    }
+
+    /**
+     * Tests if the specified object is a key in this table.
+     *
+     * @param  key   possible key
+     * @return {@code true} if and only if the specified object
+     *         is a key in this table, as determined by the
+     *         {@code equals} method; {@code false} otherwise
+     * @throws NullPointerException if the specified key is null
+     */
+    public boolean containsKey(Object key) {
+        if (key == null)
+            throw new NullPointerException();
+        return internalGet(key) != null;
+    }
+
+    /**
+     * Returns {@code true} if this map maps one or more keys to the
+     * specified value. Note: This method may require a full traversal
+     * of the map, and is much slower than method {@code containsKey}.
+     *
+     * @param value value whose presence in this map is to be tested
+     * @return {@code true} if this map maps one or more keys to the
+     *         specified value
+     * @throws NullPointerException if the specified value is null
+     */
+    public boolean containsValue(Object value) {
+        if (value == null)
+            throw new NullPointerException();
+        Object v;
+        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
+        while ((v = it.advance()) != null) {
+            if (v == value || value.equals(v))
+                return true;
+        }
+        return false;
+    }
+
+    public K findKey(Object value) {
+        if (value == null)
+            throw new NullPointerException();
+        Object v;
+        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
+        while ((v = it.advance()) != null) {
+            if (v == value || value.equals(v))
+                return it.nextKey;
+        }
+        return null;
+    }
+
+    /**
+     * Legacy method testing if some key maps into the specified value
+     * in this table.  This method is identical in functionality to
+     * {@link #containsValue}, and exists solely to ensure
+     * full compatibility with class {@link java.util.Hashtable},
+     * which supported this method prior to introduction of the
+     * Java Collections framework.
+     *
+     * @param  value a value to search for
+     * @return {@code true} if and only if some key maps to the
+     *         {@code value} argument in this table as
+     *         determined by the {@code equals} method;
+     *         {@code false} otherwise
+     * @throws NullPointerException if the specified value is null
+     */
+    public boolean contains(Object value) {
+        return containsValue(value);
+    }
+
+    /**
+     * Maps the specified key to the specified value in this table.
+     * Neither the key nor the value can be null.
+     *
+     * <p>The value can be retrieved by calling the {@code get} method
+     * with a key that is equal to the original key.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param value value to be associated with the specified key
+     * @return the previous value associated with {@code key}, or
+     *         {@code null} if there was no mapping for {@code key}
+     * @throws NullPointerException if the specified key or value is null
+     */
+    @SuppressWarnings("unchecked") public V put(K key, V value) {
+        if (key == null || value == null)
+            throw new NullPointerException();
+        return (V)internalPut(key, value);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the previous value associated with the specified key,
+     *         or {@code null} if there was no mapping for the key
+     * @throws NullPointerException if the specified key or value is null
+     */
+    @SuppressWarnings("unchecked") public V putIfAbsent(K key, V value) {
+        if (key == null || value == null)
+            throw new NullPointerException();
+        return (V)internalPutIfAbsent(key, value);
+    }
+
+    /**
+     * Copies all of the mappings from the specified map to this one.
+     * These mappings replace any mappings that this map had for any of the
+     * keys currently in the specified map.
+     *
+     * @param m mappings to be stored in this map
+     */
+    public void putAll(Map<? extends K, ? extends V> m) {
+        internalPutAll(m);
+    }
+
+    /**
+     * If the specified key is not already associated with a value,
+     * computes its value using the given mappingFunction and enters
+     * it into the map unless null.  This is equivalent to
+     * <pre> {@code
+     * if (map.containsKey(key))
+     *   return map.get(key);
+     * value = mappingFunction.apply(key);
+     * if (value != null)
+     *   map.put(key, value);
+     * return value;}</pre>
+     *
+     * except that the action is performed atomically.  If the
+     * function returns {@code null} no mapping is recorded. If the
+     * function itself throws an (unchecked) exception, the exception
+     * is rethrown to its caller, and no mapping is recorded.  Some
+     * attempted update operations on this map by other threads may be
+     * blocked while computation is in progress, so the computation
+     * should be short and simple, and must not attempt to update any
+     * other mappings of this Map. The most appropriate usage is to
+     * construct a new object serving as an initial mapped value, or
+     * memoized result, as in:
+     *
+     *  <pre> {@code
+     * map.computeIfAbsent(key, new Fun<K, V>() {
+     *   public V map(K k) { return new Value(f(k)); }});}</pre>
+     *
+     * @param key key with which the specified value is to be associated
+     * @param mappingFunction the function to compute a value
+     * @return the current (existing or computed) value associated with
+     *         the specified key, or null if the computed value is null
+     * @throws NullPointerException if the specified key or mappingFunction
+     *         is null
+     * @throws IllegalStateException if the computation detectably
+     *         attempts a recursive update to this map that would
+     *         otherwise never complete
+     * @throws RuntimeException or Error if the mappingFunction does so,
+     *         in which case the mapping is left unestablished
+     */
+    @SuppressWarnings("unchecked") public V computeIfAbsent
+    (K key, Fun<? super K, ? extends V> mappingFunction) {
+        if (key == null || mappingFunction == null)
+            throw new NullPointerException();
+        return (V)internalComputeIfAbsent(key, mappingFunction);
+    }
+
+    /**
+     * If the given key is present, computes a new mapping value given a key and
+     * its current mapped value. This is equivalent to
+     *  <pre> {@code
+     *   if (map.containsKey(key)) {
+     *     value = remappingFunction.apply(key, map.get(key));
+     *     if (value != null)
+     *       map.put(key, value);
+     *     else
+     *       map.remove(key);
+     *   }
+     * }</pre>
+     *
+     * except that the action is performed atomically.  If the
+     * function returns {@code null}, the mapping is removed.  If the
+     * function itself throws an (unchecked) exception, the exception
+     * is rethrown to its caller, and the current mapping is left
+     * unchanged.  Some attempted update operations on this map by
+     * other threads may be blocked while computation is in progress,
+     * so the computation should be short and simple, and must not
+     * attempt to update any other mappings of this Map. For example,
+     * to either create or append new messages to a value mapping:
+     *
+     * @param key key with which the specified value is to be associated
+     * @param remappingFunction the function to compute a value
+     * @return the new value associated with the specified key, or null if none
+     * @throws NullPointerException if the specified key or remappingFunction
+     *         is null
+     * @throws IllegalStateException if the computation detectably
+     *         attempts a recursive update to this map that would
+     *         otherwise never complete
+     * @throws RuntimeException or Error if the remappingFunction does so,
+     *         in which case the mapping is unchanged
+     */
+    @SuppressWarnings("unchecked") public V computeIfPresent
+    (K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
+        if (key == null || remappingFunction == null)
+            throw new NullPointerException();
+        return (V)internalCompute(key, true, remappingFunction);
+    }
+
+    /**
+     * Computes a new mapping value given a key and
+     * its current mapped value (or {@code null} if there is no current
+     * mapping). This is equivalent to
+     *  <pre> {@code
+     *   value = remappingFunction.apply(key, map.get(key));
+     *   if (value != null)
+     *     map.put(key, value);
+     *   else
+     *     map.remove(key);
+     * }</pre>
+     *
+     * except that the action is performed atomically.  If the
+     * function returns {@code null}, the mapping is removed.  If the
+     * function itself throws an (unchecked) exception, the exception
+     * is rethrown to its caller, and the current mapping is left
+     * unchanged.  Some attempted update operations on this map by
+     * other threads may be blocked while computation is in progress,
+     * so the computation should be short and simple, and must not
+     * attempt to update any other mappings of this Map. For example,
+     * to either create or append new messages to a value mapping:
+     *
+     * <pre> {@code
+     * Map<Key, String> map = ...;
+     * final String msg = ...;
+     * map.compute(key, new BiFun<Key, String, String>() {
+     *   public String apply(Key k, String v) {
+     *    return (v == null) ? msg : v + msg;});}}</pre>
+     *
+     * @param key key with which the specified value is to be associated
+     * @param remappingFunction the function to compute a value
+     * @return the new value associated with the specified key, or null if none
+     * @throws NullPointerException if the specified key or remappingFunction
+     *         is null
+     * @throws IllegalStateException if the computation detectably
+     *         attempts a recursive update to this map that would
+     *         otherwise never complete
+     * @throws RuntimeException or Error if the remappingFunction does so,
+     *         in which case the mapping is unchanged
+     */
+    @SuppressWarnings("unchecked") public V compute
+    (K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
+        if (key == null || remappingFunction == null)
+            throw new NullPointerException();
+        return (V)internalCompute(key, false, remappingFunction);
+    }
+
+    /**
+     * If the specified key is not already associated
+     * with a value, associate it with the given value.
+     * Otherwise, replace the value with the results of
+     * the given remapping function. This is equivalent to:
+     *  <pre> {@code
+     *   if (!map.containsKey(key))
+     *     map.put(value);
+     *   else {
+     *     newValue = remappingFunction.apply(map.get(key), value);
+     *     if (value != null)
+     *       map.put(key, value);
+     *     else
+     *       map.remove(key);
+     *   }
+     * }</pre>
+     * except that the action is performed atomically.  If the
+     * function returns {@code null}, the mapping is removed.  If the
+     * function itself throws an (unchecked) exception, the exception
+     * is rethrown to its caller, and the current mapping is left
+     * unchanged.  Some attempted update operations on this map by
+     * other threads may be blocked while computation is in progress,
+     * so the computation should be short and simple, and must not
+     * attempt to update any other mappings of this Map.
+     */
+    @SuppressWarnings("unchecked") public V merge
+    (K key, V value, BiFun<? super V, ? super V, ? extends V> remappingFunction) {
+        if (key == null || value == null || remappingFunction == null)
+            throw new NullPointerException();
+        return (V)internalMerge(key, value, remappingFunction);
+    }
+
+    /**
+     * Removes the key (and its corresponding value) from this map.
+     * This method does nothing if the key is not in the map.
+     *
+     * @param  key the key that needs to be removed
+     * @return the previous value associated with {@code key}, or
+     *         {@code null} if there was no mapping for {@code key}
+     * @throws NullPointerException if the specified key is null
+     */
+    @SuppressWarnings("unchecked") public V remove(Object key) {
+        if (key == null)
+            throw new NullPointerException();
+        return (V)internalReplace(key, null, null);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @throws NullPointerException if the specified key is null
+     */
+    public boolean remove(Object key, Object value) {
+        if (key == null)
+            throw new NullPointerException();
+        if (value == null)
+            return false;
+        return internalReplace(key, null, value) != null;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @throws NullPointerException if any of the arguments are null
+     */
+    public boolean replace(K key, V oldValue, V newValue) {
+        if (key == null || oldValue == null || newValue == null)
+            throw new NullPointerException();
+        return internalReplace(key, newValue, oldValue) != null;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the previous value associated with the specified key,
+     *         or {@code null} if there was no mapping for the key
+     * @throws NullPointerException if the specified key or value is null
+     */
+    @SuppressWarnings("unchecked") public V replace(K key, V value) {
+        if (key == null || value == null)
+            throw new NullPointerException();
+        return (V)internalReplace(key, value, null);
+    }
+
+    /**
+     * Removes all of the mappings from this map.
+     */
+    public void clear() {
+        internalClear();
+    }
+
+    /**
+     * Returns a {@link Set} view of the keys contained in this map.
+     * The set is backed by the map, so changes to the map are
+     * reflected in the set, and vice-versa.
+     *
+     * @return the set view
+     */
+    public KeySetView<K,V> keySet() {
+        KeySetView<K,V> ks = keySet;
+        return (ks != null) ? ks : (keySet = new KeySetView<K,V>(this, null));
+    }
+
+    /**
+     * Returns a {@link Set} view of the keys in this map, using the
+     * given common mapped value for any additions (i.e., {@link
+     * Collection#add} and {@link Collection#addAll}). This is of
+     * course only appropriate if it is acceptable to use the same
+     * value for all additions from this view.
+     *
+     * @param mappedValue the mapped value to use for any
+     * additions.
+     * @return the set view
+     * @throws NullPointerException if the mappedValue is null
+     */
+    public KeySetView<K,V> keySet(V mappedValue) {
+        if (mappedValue == null)
+            throw new NullPointerException();
+        return new KeySetView<K,V>(this, mappedValue);
+    }
+
+    /**
+     * Returns a {@link Collection} view of the values contained in this map.
+     * The collection is backed by the map, so changes to the map are
+     * reflected in the collection, and vice-versa.
+     */
+    public ValuesView<K,V> values() {
+        ValuesView<K,V> vs = values;
+        return (vs != null) ? vs : (values = new ValuesView<K,V>(this));
+    }
+
+    /**
+     * Returns a {@link Set} view of the mappings contained in this map.
+     * The set is backed by the map, so changes to the map are
+     * reflected in the set, and vice-versa.  The set supports element
+     * removal, which removes the corresponding mapping from the map,
+     * via the {@code Iterator.remove}, {@code Set.remove},
+     * {@code removeAll}, {@code retainAll}, and {@code clear}
+     * operations.  It does not support the {@code add} or
+     * {@code addAll} operations.
+     *
+     * <p>The view's {@code iterator} is a "weakly consistent" iterator
+     * that will never throw {@link ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     */
+    public Set<Map.Entry<K,V>> entrySet() {
+        EntrySetView<K,V> es = entrySet;
+        return (es != null) ? es : (entrySet = new EntrySetView<K,V>(this));
+    }
+
+    /**
+     * Returns an enumeration of the keys in this table.
+     *
+     * @return an enumeration of the keys in this table
+     * @see #keySet()
+     */
+    public Enumeration<K> keys() {
+        return new KeyIterator<K,V>(this);
+    }
+
+    /**
+     * Returns an enumeration of the values in this table.
+     *
+     * @return an enumeration of the values in this table
+     * @see #values()
+     */
+    public Enumeration<V> elements() {
+        return new ValueIterator<K,V>(this);
+    }
+
+    /**
+     * Returns a partitionable iterator of the keys in this map.
+     *
+     * @return a partitionable iterator of the keys in this map
+     */
+    public Spliterator<K> keySpliterator() {
+        return new KeyIterator<K,V>(this);
+    }
+
+    /**
+     * Returns a partitionable iterator of the values in this map.
+     *
+     * @return a partitionable iterator of the values in this map
+     */
+    public Spliterator<V> valueSpliterator() {
+        return new ValueIterator<K,V>(this);
+    }
+
+    /**
+     * Returns a partitionable iterator of the entries in this map.
+     *
+     * @return a partitionable iterator of the entries in this map
+     */
+    public Spliterator<Map.Entry<K,V>> entrySpliterator() {
+        return new EntryIterator<K,V>(this);
+    }
+
+    /**
+     * Returns the hash code value for this {@link Map}, i.e.,
+     * the sum of, for each key-value pair in the map,
+     * {@code key.hashCode() ^ value.hashCode()}.
+     *
+     * @return the hash code value for this map
+     */
+    public int hashCode() {
+        int h = 0;
+        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
+        Object v;
+        while ((v = it.advance()) != null) {
+            h += it.nextKey.hashCode() ^ v.hashCode();
+        }
+        return h;
+    }
+
+    /**
+     * Returns a string representation of this map.  The string
+     * representation consists of a list of key-value mappings (in no
+     * particular order) enclosed in braces ("{@code {}}").  Adjacent
+     * mappings are separated by the characters {@code ", "} (comma
+     * and space).  Each key-value mapping is rendered as the key
+     * followed by an equals sign ("{@code =}") followed by the
+     * associated value.
+     *
+     * @return a string representation of this map
+     */
+    public String toString() {
+        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
+        StringBuilder sb = new StringBuilder();
+        sb.append('{');
+        Object v;
+        if ((v = it.advance()) != null) {
+            for (;;) {
+                Object k = it.nextKey;
+                sb.append(k == this ? "(this Map)" : k);
+                sb.append('=');
+                sb.append(v == this ? "(this Map)" : v);
+                if ((v = it.advance()) == null)
+                    break;
+                sb.append(',').append(' ');
+            }
+        }
+        return sb.append('}').toString();
+    }
+
+    /**
+     * Compares the specified object with this map for equality.
+     * Returns {@code true} if the given object is a map with the same
+     * mappings as this map.  This operation may return misleading
+     * results if either map is concurrently modified during execution
+     * of this method.
+     *
+     * @param o object to be compared for equality with this map
+     * @return {@code true} if the specified object is equal to this map
+     */
+    public boolean equals(Object o) {
+        if (o != this) {
+            if (!(o instanceof Map))
+                return false;
+            Map<?,?> m = (Map<?,?>) o;
+            Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
+            Object val;
+            while ((val = it.advance()) != null) {
+                Object v = m.get(it.nextKey);
+                if (v == null || (v != val && !v.equals(val)))
+                    return false;
+            }
+            for (Map.Entry<?,?> e : m.entrySet()) {
+                Object mk, mv, v;
+                if ((mk = e.getKey()) == null ||
+                        (mv = e.getValue()) == null ||
+                        (v = internalGet(mk)) == null ||
+                        (mv != v && !mv.equals(v)))
+                    return false;
+            }
+        }
+        return true;
+    }
+
+    /* ----------------Iterators -------------- */
+
+    @SuppressWarnings("serial") static final class KeyIterator<K,V> extends Traverser<K,V,Object>
+            implements Spliterator<K>, Enumeration<K> {
+        KeyIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
+        KeyIterator(Traverser<K,V,Object> it) {
+            super(it);
+        }
+        public KeyIterator<K,V> split() {
+            if (nextKey != null)
+                throw new IllegalStateException();
+            return new KeyIterator<K,V>(this);
+        }
+        @SuppressWarnings("unchecked") public final K next() {
+            if (nextVal == null && advance() == null)
+                throw new NoSuchElementException();
+            Object k = nextKey;
+            nextVal = null;
+            return (K) k;
+        }
+
+        public final K nextElement() { return next(); }
+    }
+
+    @SuppressWarnings("serial") static final class ValueIterator<K,V> extends Traverser<K,V,Object>
+            implements Spliterator<V>, Enumeration<V> {
+        ValueIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
+        ValueIterator(Traverser<K,V,Object> it) {
+            super(it);
+        }
+        public ValueIterator<K,V> split() {
+            if (nextKey != null)
+                throw new IllegalStateException();
+            return new ValueIterator<K,V>(this);
+        }
+
+        @SuppressWarnings("unchecked") public final V next() {
+            Object v;
+            if ((v = nextVal) == null && (v = advance()) == null)
+                throw new NoSuchElementException();
+            nextVal = null;
+            return (V) v;
+        }
+
+        public final V nextElement() { return next(); }
+    }
+
+    @SuppressWarnings("serial") static final class EntryIterator<K,V> extends Traverser<K,V,Object>
+            implements Spliterator<Map.Entry<K,V>> {
+        EntryIterator(ConcurrentHashMapV8<K, V> map) { super(map); }
+        EntryIterator(Traverser<K,V,Object> it) {
+            super(it);
+        }
+        public EntryIterator<K,V> split() {
+            if (nextKey != null)
+                throw new IllegalStateException();
+            return new EntryIterator<K,V>(this);
+        }
+
+        @SuppressWarnings("unchecked") public final Map.Entry<K,V> next() {
+            Object v;
+            if ((v = nextVal) == null && (v = advance()) == null)
+                throw new NoSuchElementException();
+            Object k = nextKey;
+            nextVal = null;
+            return new MapEntry<K,V>((K)k, (V)v, map);
+        }
+    }
+
+    /**
+     * Exported Entry for iterators
+     */
+    static final class MapEntry<K,V> implements Map.Entry<K, V> {
+        final K key; // non-null
+        V val;       // non-null
+        final ConcurrentHashMapV8<K, V> map;
+        MapEntry(K key, V val, ConcurrentHashMapV8<K, V> map) {
+            this.key = key;
+            this.val = val;
+            this.map = map;
+        }
+        public final K getKey()       { return key; }
+        public final V getValue()     { return val; }
+        public final int hashCode()   { return key.hashCode() ^ val.hashCode(); }
+        public final String toString(){ return key + "=" + val; }
+
+        public final boolean equals(Object o) {
+            Object k, v; Map.Entry<?,?> e;
+            return ((o instanceof Map.Entry) &&
+                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
+                    (v = e.getValue()) != null &&
+                    (k == key || k.equals(key)) &&
+                    (v == val || v.equals(val)));
+        }
+
+        /**
+         * Sets our entry's value and writes through to the map. The
+         * value to return is somewhat arbitrary here. Since we do not
+         * necessarily track asynchronous changes, the most recent
+         * "previous" value could be different from what we return (or
+         * could even have been removed in which case the put will
+         * re-establish). We do not and cannot guarantee more.
+         */
+        public final V setValue(V value) {
+            if (value == null) throw new NullPointerException();
+            V v = val;
+            val = value;
+            map.put(key, value);
+            return v;
+        }
+    }
+
+    /* ---------------- Serialization Support -------------- */
+
+    /**
+     * Stripped-down version of helper class used in previous version,
+     * declared for the sake of serialization compatibility
+     */
+    static class Segment<K,V> implements Serializable {
+        private static final long serialVersionUID = 2249069246763182397L;
+        final float loadFactor;
+        Segment(float lf) { this.loadFactor = lf; }
+    }
+
+    /**
+     * Saves the state of the {@code ConcurrentHashMapV8} instance to a
+     * stream (i.e., serializes it).
+     * @param s the stream
+     * @serialData
+     * the key (Object) and value (Object)
+     * for each key-value mapping, followed by a null pair.
+     * The key-value mappings are emitted in no particular order.
+     */
+    @SuppressWarnings("unchecked") private void writeObject(java.io.ObjectOutputStream s)
+            throws java.io.IOException {
+        if (segments == null) { // for serialization compatibility
+            segments = (Segment<K,V>[])
+                    new Segment<?,?>[DEFAULT_CONCURRENCY_LEVEL];
+            for (int i = 0; i < segments.length; ++i)
+                segments[i] = new Segment<K,V>(LOAD_FACTOR);
+        }
+        s.defaultWriteObject();
+        Traverser<K,V,Object> it = new Traverser<K,V,Object>(this);
+        Object v;
+        while ((v = it.advance()) != null) {
+            s.writeObject(it.nextKey);
+            s.writeObject(v);
+        }
+        s.writeObject(null);
+        s.writeObject(null);
+        segments = null; // throw away
+    }
+
+    /**
+     * Reconstitutes the instance from a stream (that is, deserializes it).
+     * @param s the stream
+     */
+    @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s)
+            throws java.io.IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        this.segments = null; // unneeded
+        // initialize transient final field
+        this.counter = new LongAdder();
+
+        // Create all nodes, then place in table once size is known
+        long size = 0L;
+        Node p = null;
+        for (;;) {
+            K k = (K) s.readObject();
+            V v = (V) s.readObject();
+            if (k != null && v != null) {
+                int h = spread(k.hashCode());
+                p = new Node(h, k, v, p);
+                ++size;
+            }
+            else
+                break;
+        }
+        if (p != null) {
+            boolean init = false;
+            int n;
+            if (size >= (long)(MAXIMUM_CAPACITY >>> 1))
+                n = MAXIMUM_CAPACITY;
+            else {
+                int sz = (int)size;
+                n = tableSizeFor(sz + (sz >>> 1) + 1);
+            }
+            int sc = sizeCtl;
+            boolean collide = false;
+            if (n > sc &&
+                    SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) {
+                try {
+                    if (table == null) {
+                        init = true;
+                        AtomicReferenceArray<Node> tab = new AtomicReferenceArray<Node>(n);
+                        int mask = n - 1;
+                        while (p != null) {
+                            int j = p.hash & mask;
+                            Node next = p.next;
+                            Node q = p.next = tabAt(tab, j);
+                            setTabAt(tab, j, p);
+                            if (!collide && q != null && q.hash == p.hash)
+                                collide = true;
+                            p = next;
+                        }
+                        table = tab;
+                        counter.add(size);
+                        sc = n - (n >>> 2);
+                    }
+                } finally {
+                    sizeCtl = sc;
+                }
+                if (collide) { // rescan and convert to TreeBins
+                    AtomicReferenceArray<Node> tab = table;
+                    for (int i = 0; i < tab.length(); ++i) {
+                        int c = 0;
+                        for (Node e = tabAt(tab, i); e != null; e = e.next) {
+                            if (++c > TREE_THRESHOLD &&
+                                    (e.key instanceof Comparable)) {
+                                replaceWithTreeBin(tab, i, e.key);
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+            if (!init) { // Can only happen if unsafely published.
+                while (p != null) {
+                    internalPut(p.key, p.val);
+                    p = p.next;
+                }
+            }
+        }
+    }
+
+
+    // -------------------------------------------------------
+
+    // Sams
+    /** Interface describing a void action of one argument */
+    public interface Action<A> { void apply(A a); }
+    /** Interface describing a void action of two arguments */
+    public interface BiAction<A,B> { void apply(A a, B b); }
+    /** Interface describing a function of one argument */
+    public interface Generator<T> { T apply(); }
+    /** Interface describing a function mapping its argument to a double */
+    public interface ObjectToDouble<A> { double apply(A a); }
+    /** Interface describing a function mapping its argument to a long */
+    public interface ObjectToLong<A> { long apply(A a); }
+    /** Interface describing a function mapping its argument to an int */
+    public interface ObjectToInt<A> {int apply(A a); }
+    /** Interface describing a function mapping two arguments to a double */
+    public interface ObjectByObjectToDouble<A,B> { double apply(A a, B b); }
+    /** Interface describing a function mapping two arguments to a long */
+    public interface ObjectByObjectToLong<A,B> { long apply(A a, B b); }
+    /** Interface describing a function mapping two arguments to an int */
+    public interface ObjectByObjectToInt<A,B> {int apply(A a, B b); }
+    /** Interface describing a function mapping a double to a double */
+    public interface DoubleToDouble { double apply(double a); }
+    /** Interface describing a function mapping a long to a long */
+    public interface LongToLong { long apply(long a); }
+    /** Interface describing a function mapping an int to an int */
+    public interface IntToInt { int apply(int a); }
+    /** Interface describing a function mapping two doubles to a double */
+    public interface DoubleByDoubleToDouble { double apply(double a, double b); }
+    /** Interface describing a function mapping two longs to a long */
+    public interface LongByLongToLong { long apply(long a, long b); }
+    /** Interface describing a function mapping two ints to an int */
+    public interface IntByIntToInt { int apply(int a, int b); }
+
+
+    /* ----------------Views -------------- */
+
+    /**
+     * Base class for views.
+     */
+    static abstract class CHMView<K, V> {
+        final ConcurrentHashMapV8<K, V> map;
+        CHMView(ConcurrentHashMapV8<K, V> map)  { this.map = map; }
+
+        /**
+         * Returns the map backing this view.
+         *
+         * @return the map backing this view
+         */
+        public ConcurrentHashMapV8<K,V> getMap() { return map; }
+
+        public final int size()                 { return map.size(); }
+        public final boolean isEmpty()          { return map.isEmpty(); }
+        public final void clear()               { map.clear(); }
+
+        // implementations below rely on concrete classes supplying these
+        abstract public Iterator<?> iterator();
+        abstract public boolean contains(Object o);
+        abstract public boolean remove(Object o);
+
+        private static final String oomeMsg = "Required array size too large";
+
+        public final Object[] toArray() {
+            long sz = map.mappingCount();
+            if (sz > (long)(MAX_ARRAY_SIZE))
+                throw new OutOfMemoryError(oomeMsg);
+            int n = (int)sz;
+            Object[] r = new Object[n];
+            int i = 0;
+            Iterator<?> it = iterator();
+            while (it.hasNext()) {
+                if (i == n) {
+                    if (n >= MAX_ARRAY_SIZE)
+                        throw new OutOfMemoryError(oomeMsg);
+                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
+                        n = MAX_ARRAY_SIZE;
+                    else
+                        n += (n >>> 1) + 1;
+                    r = Arrays.copyOf(r, n);
+                }
+                r[i++] = it.next();
+            }
+            return (i == n) ? r : Arrays.copyOf(r, i);
+        }
+
+        @SuppressWarnings("unchecked") public final <T> T[] toArray(T[] a) {
+            long sz = map.mappingCount();
+            if (sz > (long)(MAX_ARRAY_SIZE))
+                throw new OutOfMemoryError(oomeMsg);
+            int m = (int)sz;
+            T[] r = (a.length >= m) ? a :
+                    (T[])java.lang.reflect.Array
+                            .newInstance(a.getClass().getComponentType(), m);
+            int n = r.length;
+            int i = 0;
+            Iterator<?> it = iterator();
+            while (it.hasNext()) {
+                if (i == n) {
+                    if (n >= MAX_ARRAY_SIZE)
+                        throw new OutOfMemoryError(oomeMsg);
+                    if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
+                        n = MAX_ARRAY_SIZE;
+                    else
+                        n += (n >>> 1) + 1;
+                    r = Arrays.copyOf(r, n);
+                }
+                r[i++] = (T)it.next();
+            }
+            if (a == r && i < n) {
+                r[i] = null; // null-terminate
+                return r;
+            }
+            return (i == n) ? r : Arrays.copyOf(r, i);
+        }
+
+        public final int hashCode() {
+            int h = 0;
+            for (Iterator<?> it = iterator(); it.hasNext();)
+                h += it.next().hashCode();
+            return h;
+        }
+
+        public final String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append('[');
+            Iterator<?> it = iterator();
+            if (it.hasNext()) {
+                for (;;) {
+                    Object e = it.next();
+                    sb.append(e == this ? "(this Collection)" : e);
+                    if (!it.hasNext())
+                        break;
+                    sb.append(',').append(' ');
+                }
+            }
+            return sb.append(']').toString();
+        }
+
+        public final boolean containsAll(Collection<?> c) {
+            if (c != this) {
+                for (Iterator<?> it = c.iterator(); it.hasNext();) {
+                    Object e = it.next();
+                    if (e == null || !contains(e))
+                        return false;
+                }
+            }
+            return true;
+        }
+
+        public final boolean removeAll(Collection<?> c) {
+            boolean modified = false;
+            for (Iterator<?> it = iterator(); it.hasNext();) {
+                if (c.contains(it.next())) {
+                    it.remove();
+                    modified = true;
+                }
+            }
+            return modified;
+        }
+
+        public final boolean retainAll(Collection<?> c) {
+            boolean modified = false;
+            for (Iterator<?> it = iterator(); it.hasNext();) {
+                if (!c.contains(it.next())) {
+                    it.remove();
+                    modified = true;
+                }
+            }
+            return modified;
+        }
+
+    }
+
+    /**
+     * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in
+     * which additions may optionally be enabled by mapping to a
+     * common value.  This class cannot be directly instantiated. See
+     * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()},
+     * {@link #newKeySet(int)}.
+     */
+    public static class KeySetView<K,V> extends CHMView<K,V> implements Set<K>, java.io.Serializable {
+        private static final long serialVersionUID = 7249069246763182397L;
+        private final V value;
+        KeySetView(ConcurrentHashMapV8<K, V> map, V value) {  // non-public
+            super(map);
+            this.value = value;
+        }
+
+        /**
+         * Returns the default mapped value for additions,
+         * or {@code null} if additions are not supported.
+         *
+         * @return the default mapped value for additions, or {@code null}
+         * if not supported.
+         */
+        public V getMappedValue() { return value; }
+
+        // implement Set API
+
+        public boolean contains(Object o) { return map.containsKey(o); }
+        public boolean remove(Object o)   { return map.remove(o) != null; }
+
+        /**
+         * Returns a "weakly consistent" iterator that will never
+         * throw {@link ConcurrentModificationException}, and
+         * guarantees to traverse elements as they existed upon
+         * construction of the iterator, and may (but is not
+         * guaranteed to) reflect any modifications subsequent to
+         * construction.
+         *
+         * @return an iterator over the keys of this map
+         */
+        public Iterator<K> iterator()     { return new KeyIterator<K,V>(map); }
+        public boolean add(K e) {
+            V v;
+            if ((v = value) == null)
+                throw new UnsupportedOperationException();
+            if (e == null)
+                throw new NullPointerException();
+            return map.internalPutIfAbsent(e, v) == null;
+        }
+        public boolean addAll(Collection<? extends K> c) {
+            boolean added = false;
+            V v;
+            if ((v = value) == null)
+                throw new UnsupportedOperationException();
+            for (K e : c) {
+                if (e == null)
+                    throw new NullPointerException();
+                if (map.internalPutIfAbsent(e, v) == null)
+                    added = true;
+            }
+            return added;
+        }
+        public boolean equals(Object o) {
+            Set<?> c;
+            return ((o instanceof Set) &&
+                    ((c = (Set<?>)o) == this ||
+                            (containsAll(c) && c.containsAll(this))));
+        }
+    }
+
+    /**
+     * A view of a ConcurrentHashMapV8 as a {@link Collection} of
+     * values, in which additions are disabled. This class cannot be
+     * directly instantiated. See {@link #values},
+     *
+     * <p>The view's {@code iterator} is a "weakly consistent" iterator
+     * that will never throw {@link ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     */
+    public static final class ValuesView<K,V> extends CHMView<K,V>
+            implements Collection<V> {
+        ValuesView(ConcurrentHashMapV8<K, V> map)   { super(map); }
+        public final boolean contains(Object o) { return map.containsValue(o); }
+        public final boolean remove(Object o) {
+            if (o != null) {
+                Iterator<V> it = new ValueIterator<K,V>(map);
+                while (it.hasNext()) {
+                    if (o.equals(it.next())) {
+                        it.remove();
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+        /**
+         * Returns a "weakly consistent" iterator that will never
+         * throw {@link ConcurrentModificationException}, and
+         * guarantees to traverse elements as they existed upon
+         * construction of the iterator, and may (but is not
+         * guaranteed to) reflect any modifications subsequent to
+         * construction.
+         *
+         * @return an iterator over the values of this map
+         */
+        public final Iterator<V> iterator() {
+            return new ValueIterator<K,V>(map);
+        }
+        public final boolean add(V e) {
+            throw new UnsupportedOperationException();
+        }
+        public final boolean addAll(Collection<? extends V> c) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    /**
+     * A view of a ConcurrentHashMapV8 as a {@link Set} of (key, value)
+     * entries.  This class cannot be directly instantiated. See
+     * {@link #entrySet}.
+     */
+    public static final class EntrySetView<K,V> extends CHMView<K,V>
+            implements Set<Map.Entry<K,V>> {
+        EntrySetView(ConcurrentHashMapV8<K, V> map) { super(map); }
+        public final boolean contains(Object o) {
+            Object k, v, r; Map.Entry<?,?> e;
+            return ((o instanceof Map.Entry) &&
+                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
+                    (r = map.get(k)) != null &&
+                    (v = e.getValue()) != null &&
+                    (v == r || v.equals(r)));
+        }
+        public final boolean remove(Object o) {
+            Object k, v; Map.Entry<?,?> e;
+            return ((o instanceof Map.Entry) &&
+                    (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
+                    (v = e.getValue()) != null &&
+                    map.remove(k, v));
+        }
+
+        /**
+         * Returns a "weakly consistent" iterator that will never
+         * throw {@link ConcurrentModificationException}, and
+         * guarantees to traverse elements as they existed upon
+         * construction of the iterator, and may (but is not
+         * guaranteed to) reflect any modifications subsequent to
+         * construction.
+         *
+         * @return an iterator over the entries of this map
+         */
+        public final Iterator<Map.Entry<K,V>> iterator() {
+            return new EntryIterator<K,V>(map);
+        }
+
+        public final boolean add(Entry<K,V> e) {
+            K key = e.getKey();
+            V value = e.getValue();
+            if (key == null || value == null)
+                throw new NullPointerException();
+            return map.internalPut(key, value) == null;
+        }
+        public final boolean addAll(Collection<? extends Entry<K,V>> c) {
+            boolean added = false;
+            for (Entry<K,V> e : c) {
+                if (add(e))
+                    added = true;
+            }
+            return added;
+        }
+        public boolean equals(Object o) {
+            Set<?> c;
+            return ((o instanceof Set) &&
+                    ((c = (Set<?>)o) == this ||
+                            (containsAll(c) && c.containsAll(this))));
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/nounsafe/LongAdder.java b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/nounsafe/LongAdder.java
new file mode 100644
index 0000000..e7a1c5f
--- /dev/null
+++ b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/nounsafe/LongAdder.java
@@ -0,0 +1,204 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// This is based on 1.9 version.
+
+package org.jruby.ext.thread_safe.jsr166e.nounsafe;
+
+import java.util.concurrent.atomic.AtomicLong;
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.ObjectInputStream;
+
+/**
+ * One or more variables that together maintain an initially zero
+ * {@code long} sum.  When updates (method {@link #add}) are contended
+ * across threads, the set of variables may grow dynamically to reduce
+ * contention. Method {@link #sum} (or, equivalently, {@link
+ * #longValue}) returns the current total combined across the
+ * variables maintaining the sum.
+ *
+ * <p>This class is usually preferable to {@link AtomicLong} when
+ * multiple threads update a common sum that is used for purposes such
+ * as collecting statistics, not for fine-grained synchronization
+ * control.  Under low update contention, the two classes have similar
+ * characteristics. But under high contention, expected throughput of
+ * this class is significantly higher, at the expense of higher space
+ * consumption.
+ *
+ * <p>This class extends {@link Number}, but does <em>not</em> define
+ * methods such as {@code hashCode} and {@code compareTo} because
+ * instances are expected to be mutated, and so are not useful as
+ * collection keys.
+ *
+ * <p><em>jsr166e note: This class is targeted to be placed in
+ * java.util.concurrent.atomic.</em>
+ *
+ * @since 1.8
+ * @author Doug Lea
+ */
+public class LongAdder extends Striped64 implements Serializable {
+    private static final long serialVersionUID = 7249069246863182397L;
+
+    /**
+     * Version of plus for use in retryUpdate
+     */
+    final long fn(long v, long x) { return v + x; }
+
+    /**
+     * Creates a new adder with initial sum of zero.
+     */
+    public LongAdder() {
+    }
+
+    /**
+     * Adds the given value.
+     *
+     * @param x the value to add
+     */
+    public void add(long x) {
+        Cell[] as; long b, v; HashCode hc; Cell a; int n;
+        if ((as = cells) != null || !casBase(b = base, b + x)) {
+            boolean uncontended = true;
+            int h = (hc = threadHashCode.get()).code;
+            if (as == null || (n = as.length) < 1 ||
+                    (a = as[(n - 1) & h]) == null ||
+                    !(uncontended = a.cas(v = a.value, v + x)))
+                retryUpdate(x, hc, uncontended);
+        }
+    }
+
+    /**
+     * Equivalent to {@code add(1)}.
+     */
+    public void increment() {
+        add(1L);
+    }
+
+    /**
+     * Equivalent to {@code add(-1)}.
+     */
+    public void decrement() {
+        add(-1L);
+    }
+
+    /**
+     * Returns the current sum.  The returned value is <em>NOT</em> an
+     * atomic snapshot: Invocation in the absence of concurrent
+     * updates returns an accurate result, but concurrent updates that
+     * occur while the sum is being calculated might not be
+     * incorporated.
+     *
+     * @return the sum
+     */
+    public long sum() {
+        long sum = base;
+        Cell[] as = cells;
+        if (as != null) {
+            int n = as.length;
+            for (int i = 0; i < n; ++i) {
+                Cell a = as[i];
+                if (a != null)
+                    sum += a.value;
+            }
+        }
+        return sum;
+    }
+
+    /**
+     * Resets variables maintaining the sum to zero.  This method may
+     * be a useful alternative to creating a new adder, but is only
+     * effective if there are no concurrent updates.  Because this
+     * method is intrinsically racy, it should only be used when it is
+     * known that no threads are concurrently updating.
+     */
+    public void reset() {
+        internalReset(0L);
+    }
+
+    /**
+     * Equivalent in effect to {@link #sum} followed by {@link
+     * #reset}. This method may apply for example during quiescent
+     * points between multithreaded computations.  If there are
+     * updates concurrent with this method, the returned value is
+     * <em>not</em> guaranteed to be the final value occurring before
+     * the reset.
+     *
+     * @return the sum
+     */
+    public long sumThenReset() {
+        long sum = base;
+        Cell[] as = cells;
+        base = 0L;
+        if (as != null) {
+            int n = as.length;
+            for (int i = 0; i < n; ++i) {
+                Cell a = as[i];
+                if (a != null) {
+                    sum += a.value;
+                    a.value = 0L;
+                }
+            }
+        }
+        return sum;
+    }
+
+    /**
+     * Returns the String representation of the {@link #sum}.
+     * @return the String representation of the {@link #sum}
+     */
+    public String toString() {
+        return Long.toString(sum());
+    }
+
+    /**
+     * Equivalent to {@link #sum}.
+     *
+     * @return the sum
+     */
+    public long longValue() {
+        return sum();
+    }
+
+    /**
+     * Returns the {@link #sum} as an {@code int} after a narrowing
+     * primitive conversion.
+     */
+    public int intValue() {
+        return (int)sum();
+    }
+
+    /**
+     * Returns the {@link #sum} as a {@code float}
+     * after a widening primitive conversion.
+     */
+    public float floatValue() {
+        return (float)sum();
+    }
+
+    /**
+     * Returns the {@link #sum} as a {@code double} after a widening
+     * primitive conversion.
+     */
+    public double doubleValue() {
+        return (double)sum();
+    }
+
+    private void writeObject(java.io.ObjectOutputStream s)
+            throws java.io.IOException {
+        s.defaultWriteObject();
+        s.writeLong(sum());
+    }
+
+    private void readObject(ObjectInputStream s)
+            throws IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        busy = 0;
+        cells = null;
+        base = s.readLong();
+    }
+
+}
diff --git a/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/nounsafe/Striped64.java b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/nounsafe/Striped64.java
new file mode 100644
index 0000000..ee69567
--- /dev/null
+++ b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166e/nounsafe/Striped64.java
@@ -0,0 +1,291 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// This is based on 1.5 version.
+
+package org.jruby.ext.thread_safe.jsr166e.nounsafe;
+
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import java.util.concurrent.atomic.AtomicLongFieldUpdater;
+
+/**
+ * A package-local class holding common representation and mechanics
+ * for classes supporting dynamic striping on 64bit values. The class
+ * extends Number so that concrete subclasses must publicly do so.
+ */
+abstract class Striped64 extends Number {
+    /*
+     * This class maintains a lazily-initialized table of atomically
+     * updated variables, plus an extra "base" field. The table size
+     * is a power of two. Indexing uses masked per-thread hash codes.
+     * Nearly all declarations in this class are package-private,
+     * accessed directly by subclasses.
+     *
+     * Table entries are of class Cell; a variant of AtomicLong padded
+     * to reduce cache contention on most processors. Padding is
+     * overkill for most Atomics because they are usually irregularly
+     * scattered in memory and thus don't interfere much with each
+     * other. But Atomic objects residing in arrays will tend to be
+     * placed adjacent to each other, and so will most often share
+     * cache lines (with a huge negative performance impact) without
+     * this precaution.
+     *
+     * In part because Cells are relatively large, we avoid creating
+     * them until they are needed.  When there is no contention, all
+     * updates are made to the base field.  Upon first contention (a
+     * failed CAS on base update), the table is initialized to size 2.
+     * The table size is doubled upon further contention until
+     * reaching the nearest power of two greater than or equal to the
+     * number of CPUS. Table slots remain empty (null) until they are
+     * needed.
+     *
+     * A single spinlock ("busy") is used for initializing and
+     * resizing the table, as well as populating slots with new Cells.
+     * There is no need for a blocking lock: When the lock is not
+     * available, threads try other slots (or the base).  During these
+     * retries, there is increased contention and reduced locality,
+     * which is still better than alternatives.
+     *
+     * Per-thread hash codes are initialized to random values.
+     * Contention and/or table collisions are indicated by failed
+     * CASes when performing an update operation (see method
+     * retryUpdate). Upon a collision, if the table size is less than
+     * the capacity, it is doubled in size unless some other thread
+     * holds the lock. If a hashed slot is empty, and lock is
+     * available, a new Cell is created. Otherwise, if the slot
+     * exists, a CAS is tried.  Retries proceed by "double hashing",
+     * using a secondary hash (Marsaglia XorShift) to try to find a
+     * free slot.
+     *
+     * The table size is capped because, when there are more threads
+     * than CPUs, supposing that each thread were bound to a CPU,
+     * there would exist a perfect hash function mapping threads to
+     * slots that eliminates collisions. When we reach capacity, we
+     * search for this mapping by randomly varying the hash codes of
+     * colliding threads.  Because search is random, and collisions
+     * only become known via CAS failures, convergence can be slow,
+     * and because threads are typically not bound to CPUS forever,
+     * may not occur at all. However, despite these limitations,
+     * observed contention rates are typically low in these cases.
+     *
+     * It is possible for a Cell to become unused when threads that
+     * once hashed to it terminate, as well as in the case where
+     * doubling the table causes no thread to hash to it under
+     * expanded mask.  We do not try to detect or remove such cells,
+     * under the assumption that for long-running instances, observed
+     * contention levels will recur, so the cells will eventually be
+     * needed again; and for short-lived ones, it does not matter.
+     */
+
+    /**
+     * Padded variant of AtomicLong supporting only raw accesses plus CAS.
+     * The value field is placed between pads, hoping that the JVM doesn't
+     * reorder them.
+     *
+     * JVM intrinsics note: It would be possible to use a release-only
+     * form of CAS here, if it were provided.
+     */
+    static final class Cell {
+        volatile long p0, p1, p2, p3, p4, p5, p6;
+        volatile long value;
+        volatile long q0, q1, q2, q3, q4, q5, q6;
+
+        static AtomicLongFieldUpdater<Cell> VALUE_UPDATER = AtomicLongFieldUpdater.newUpdater(Cell.class, "value");
+
+        Cell(long x) { value = x; }
+
+        final boolean cas(long cmp, long val) {
+            return VALUE_UPDATER.compareAndSet(this, cmp, val);
+        }
+
+    }
+
+    /**
+     * Holder for the thread-local hash code. The code is initially
+     * random, but may be set to a different value upon collisions.
+     */
+    static final class HashCode {
+        static final Random rng = new Random();
+        int code;
+        HashCode() {
+            int h = rng.nextInt(); // Avoid zero to allow xorShift rehash
+            code = (h == 0) ? 1 : h;
+        }
+    }
+
+    /**
+     * The corresponding ThreadLocal class
+     */
+    static final class ThreadHashCode extends ThreadLocal<HashCode> {
+        public HashCode initialValue() { return new HashCode(); }
+    }
+
+    /**
+     * Static per-thread hash codes. Shared across all instances to
+     * reduce ThreadLocal pollution and because adjustments due to
+     * collisions in one table are likely to be appropriate for
+     * others.
+     */
+    static final ThreadHashCode threadHashCode = new ThreadHashCode();
+
+    /** Number of CPUS, to place bound on table size */
+    static final int NCPU = Runtime.getRuntime().availableProcessors();
+
+    /**
+     * Table of cells. When non-null, size is a power of 2.
+     */
+    transient volatile Cell[] cells;
+
+    /**
+     * Base value, used mainly when there is no contention, but also as
+     * a fallback during table initialization races. Updated via CAS.
+     */
+    transient volatile long base;
+
+    /**
+     * Spinlock (locked via CAS) used when resizing and/or creating Cells.
+     */
+    transient volatile int busy;
+
+    AtomicLongFieldUpdater<Striped64>    BASE_UPDATER = AtomicLongFieldUpdater.newUpdater(Striped64.class, "base");
+    AtomicIntegerFieldUpdater<Striped64> BUSY_UPDATER = AtomicIntegerFieldUpdater.newUpdater(Striped64.class, "busy");
+
+    /**
+     * Package-private default constructor
+     */
+    Striped64() {
+    }
+
+    /**
+     * CASes the base field.
+     */
+    final boolean casBase(long cmp, long val) {
+        return BASE_UPDATER.compareAndSet(this, cmp, val);
+    }
+
+    /**
+     * CASes the busy field from 0 to 1 to acquire lock.
+     */
+    final boolean casBusy() {
+        return BUSY_UPDATER.compareAndSet(this, 0, 1);
+    }
+
+    /**
+     * Computes the function of current and new value. Subclasses
+     * should open-code this update function for most uses, but the
+     * virtualized form is needed within retryUpdate.
+     *
+     * @param currentValue the current value (of either base or a cell)
+     * @param newValue the argument from a user update call
+     * @return result of the update function
+     */
+    abstract long fn(long currentValue, long newValue);
+
+    /**
+     * Handles cases of updates involving initialization, resizing,
+     * creating new Cells, and/or contention. See above for
+     * explanation. This method suffers the usual non-modularity
+     * problems of optimistic retry code, relying on rechecked sets of
+     * reads.
+     *
+     * @param x the value
+     * @param hc the hash code holder
+     * @param wasUncontended false if CAS failed before call
+     */
+    final void retryUpdate(long x, HashCode hc, boolean wasUncontended) {
+        int h = hc.code;
+        boolean collide = false;                // True if last slot nonempty
+        for (;;) {
+            Cell[] as; Cell a; int n; long v;
+            if ((as = cells) != null && (n = as.length) > 0) {
+                if ((a = as[(n - 1) & h]) == null) {
+                    if (busy == 0) {            // Try to attach new Cell
+                        Cell r = new Cell(x);   // Optimistically create
+                        if (busy == 0 && casBusy()) {
+                            boolean created = false;
+                            try {               // Recheck under lock
+                                Cell[] rs; int m, j;
+                                if ((rs = cells) != null &&
+                                        (m = rs.length) > 0 &&
+                                        rs[j = (m - 1) & h] == null) {
+                                    rs[j] = r;
+                                    created = true;
+                                }
+                            } finally {
+                                busy = 0;
+                            }
+                            if (created)
+                                break;
+                            continue;           // Slot is now non-empty
+                        }
+                    }
+                    collide = false;
+                }
+                else if (!wasUncontended)       // CAS already known to fail
+                    wasUncontended = true;      // Continue after rehash
+                else if (a.cas(v = a.value, fn(v, x)))
+                    break;
+                else if (n >= NCPU || cells != as)
+                    collide = false;            // At max size or stale
+                else if (!collide)
+                    collide = true;
+                else if (busy == 0 && casBusy()) {
+                    try {
+                        if (cells == as) {      // Expand table unless stale
+                            Cell[] rs = new Cell[n << 1];
+                            for (int i = 0; i < n; ++i)
+                                rs[i] = as[i];
+                            cells = rs;
+                        }
+                    } finally {
+                        busy = 0;
+                    }
+                    collide = false;
+                    continue;                   // Retry with expanded table
+                }
+                h ^= h << 13;                   // Rehash
+                h ^= h >>> 17;
+                h ^= h << 5;
+            }
+            else if (busy == 0 && cells == as && casBusy()) {
+                boolean init = false;
+                try {                           // Initialize table
+                    if (cells == as) {
+                        Cell[] rs = new Cell[2];
+                        rs[h & 1] = new Cell(x);
+                        cells = rs;
+                        init = true;
+                    }
+                } finally {
+                    busy = 0;
+                }
+                if (init)
+                    break;
+            }
+            else if (casBase(v = base, fn(v, x)))
+                break;                          // Fall back on using base
+        }
+        hc.code = h;                            // Record index for next time
+    }
+
+
+    /**
+     * Sets base and all cells to the given value.
+     */
+    final void internalReset(long initialValue) {
+        Cell[] as = cells;
+        base = initialValue;
+        if (as != null) {
+            int n = as.length;
+            for (int i = 0; i < n; ++i) {
+                Cell a = as[i];
+                if (a != null)
+                    a.value = initialValue;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166y/ThreadLocalRandom.java b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166y/ThreadLocalRandom.java
new file mode 100644
index 0000000..81ba441
--- /dev/null
+++ b/app/server/vendor/thread_safe/ext/org/jruby/ext/thread_safe/jsr166y/ThreadLocalRandom.java
@@ -0,0 +1,199 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// This is based on 1.16 version
+
+package org.jruby.ext.thread_safe.jsr166y;
+
+import java.util.Random;
+
+/**
+ * A random number generator isolated to the current thread.  Like the
+ * global {@link java.util.Random} generator used by the {@link
+ * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized
+ * with an internally generated seed that may not otherwise be
+ * modified. When applicable, use of {@code ThreadLocalRandom} rather
+ * than shared {@code Random} objects in concurrent programs will
+ * typically encounter much less overhead and contention.  Use of
+ * {@code ThreadLocalRandom} is particularly appropriate when multiple
+ * tasks (for example, each a {@link ForkJoinTask}) use random numbers
+ * in parallel in thread pools.
+ *
+ * <p>Usages of this class should typically be of the form:
+ * {@code ThreadLocalRandom.current().nextX(...)} (where
+ * {@code X} is {@code Int}, {@code Long}, etc).
+ * When all usages are of this form, it is never possible to
+ * accidently share a {@code ThreadLocalRandom} across multiple threads.
+ *
+ * <p>This class also provides additional commonly used bounded random
+ * generation methods.
+ *
+ * @since 1.7
+ * @author Doug Lea
+ */
+public class ThreadLocalRandom extends Random {
+    // same constants as Random, but must be redeclared because private
+    private static final long multiplier = 0x5DEECE66DL;
+    private static final long addend = 0xBL;
+    private static final long mask = (1L << 48) - 1;
+
+    /**
+     * The random seed. We can't use super.seed.
+     */
+    private long rnd;
+
+    /**
+     * Initialization flag to permit calls to setSeed to succeed only
+     * while executing the Random constructor.  We can't allow others
+     * since it would cause setting seed in one part of a program to
+     * unintentionally impact other usages by the thread.
+     */
+    boolean initialized;
+
+    // Padding to help avoid memory contention among seed updates in
+    // different TLRs in the common case that they are located near
+    // each other.
+    private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;
+
+    /**
+     * The actual ThreadLocal
+     */
+    private static final ThreadLocal<ThreadLocalRandom> localRandom =
+        new ThreadLocal<ThreadLocalRandom>() {
+            protected ThreadLocalRandom initialValue() {
+                return new ThreadLocalRandom();
+            }
+    };
+
+
+    /**
+     * Constructor called only by localRandom.initialValue.
+     */
+    ThreadLocalRandom() {
+        super();
+        initialized = true;
+    }
+
+    /**
+     * Returns the current thread's {@code ThreadLocalRandom}.
+     *
+     * @return the current thread's {@code ThreadLocalRandom}
+     */
+    public static ThreadLocalRandom current() {
+        return localRandom.get();
+    }
+
+    /**
+     * Throws {@code UnsupportedOperationException}.  Setting seeds in
+     * this generator is not supported.
+     *
+     * @throws UnsupportedOperationException always
+     */
+    public void setSeed(long seed) {
+        if (initialized)
+            throw new UnsupportedOperationException();
+        rnd = (seed ^ multiplier) & mask;
+    }
+
+    protected int next(int bits) {
+        rnd = (rnd * multiplier + addend) & mask;
+        return (int) (rnd >>> (48-bits));
+    }
+
+    /**
+     * Returns a pseudorandom, uniformly distributed value between the
+     * given least value (inclusive) and bound (exclusive).
+     *
+     * @param least the least value returned
+     * @param bound the upper bound (exclusive)
+     * @throws IllegalArgumentException if least greater than or equal
+     * to bound
+     * @return the next value
+     */
+    public int nextInt(int least, int bound) {
+        if (least >= bound)
+            throw new IllegalArgumentException();
+        return nextInt(bound - least) + least;
+    }
+
+    /**
+     * Returns a pseudorandom, uniformly distributed value
+     * between 0 (inclusive) and the specified value (exclusive).
+     *
+     * @param n the bound on the random number to be returned.  Must be
+     *        positive.
+     * @return the next value
+     * @throws IllegalArgumentException if n is not positive
+     */
+    public long nextLong(long n) {
+        if (n <= 0)
+            throw new IllegalArgumentException("n must be positive");
+        // Divide n by two until small enough for nextInt. On each
+        // iteration (at most 31 of them but usually much less),
+        // randomly choose both whether to include high bit in result
+        // (offset) and whether to continue with the lower vs upper
+        // half (which makes a difference only if odd).
+        long offset = 0;
+        while (n >= Integer.MAX_VALUE) {
+            int bits = next(2);
+            long half = n >>> 1;
+            long nextn = ((bits & 2) == 0) ? half : n - half;
+            if ((bits & 1) == 0)
+                offset += n - nextn;
+            n = nextn;
+        }
+        return offset + nextInt((int) n);
+    }
+
+    /**
+     * Returns a pseudorandom, uniformly distributed value between the
+     * given least value (inclusive) and bound (exclusive).
+     *
+     * @param least the least value returned
+     * @param bound the upper bound (exclusive)
+     * @return the next value
+     * @throws IllegalArgumentException if least greater than or equal
+     * to bound
+     */
+    public long nextLong(long least, long bound) {
+        if (least >= bound)
+            throw new IllegalArgumentException();
+        return nextLong(bound - least) + least;
+    }
+
+    /**
+     * Returns a pseudorandom, uniformly distributed {@code double} value
+     * between 0 (inclusive) and the specified value (exclusive).
+     *
+     * @param n the bound on the random number to be returned.  Must be
+     *        positive.
+     * @return the next value
+     * @throws IllegalArgumentException if n is not positive
+     */
+    public double nextDouble(double n) {
+        if (n <= 0)
+            throw new IllegalArgumentException("n must be positive");
+        return nextDouble() * n;
+    }
+
+    /**
+     * Returns a pseudorandom, uniformly distributed value between the
+     * given least value (inclusive) and bound (exclusive).
+     *
+     * @param least the least value returned
+     * @param bound the upper bound (exclusive)
+     * @return the next value
+     * @throws IllegalArgumentException if least greater than or equal
+     * to bound
+     */
+    public double nextDouble(double least, double bound) {
+        if (least >= bound)
+            throw new IllegalArgumentException();
+        return nextDouble() * (bound - least) + least;
+    }
+
+    private static final long serialVersionUID = -5851777807851030925L;
+}
diff --git a/app/server/vendor/thread_safe/ext/thread_safe/JrubyCacheBackendService.java b/app/server/vendor/thread_safe/ext/thread_safe/JrubyCacheBackendService.java
new file mode 100644
index 0000000..2c5bcea
--- /dev/null
+++ b/app/server/vendor/thread_safe/ext/thread_safe/JrubyCacheBackendService.java
@@ -0,0 +1,15 @@
+package thread_safe;
+
+import java.io.IOException;
+
+import org.jruby.Ruby;
+import org.jruby.ext.thread_safe.JRubyCacheBackendLibrary;
+import org.jruby.runtime.load.BasicLibraryService;
+
+// can't name this JRubyCacheBackendService or else JRuby doesn't pick this up
+public class JrubyCacheBackendService implements BasicLibraryService {
+    public boolean basicLoad(final Ruby runtime) throws IOException {
+        new JRubyCacheBackendLibrary().load(runtime, false);
+        return true;
+    }
+}
diff --git a/app/server/vendor/thread_safe/lib/thread_safe.rb b/app/server/vendor/thread_safe/lib/thread_safe.rb
new file mode 100644
index 0000000..5b8fb27
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe.rb
@@ -0,0 +1,65 @@
+require 'thread_safe/version'
+require 'thread_safe/synchronized_delegator'
+
+module ThreadSafe
+  autoload :Cache, 'thread_safe/cache'
+  autoload :Util,  'thread_safe/util'
+
+  # Various classes within allows for +nil+ values to be stored, so a special +NULL+ token is required to indicate the "nil-ness".
+  NULL = Object.new
+
+  if defined?(JRUBY_VERSION)
+    require 'jruby/synchronized'
+
+    # A thread-safe subclass of Array. This version locks
+    # against the object itself for every method call,
+    # ensuring only one thread can be reading or writing
+    # at a time. This includes iteration methods like
+    # #each.
+    class Array < ::Array
+      include JRuby::Synchronized
+    end
+
+    # A thread-safe subclass of Hash. This version locks
+    # against the object itself for every method call,
+    # ensuring only one thread can be reading or writing
+    # at a time. This includes iteration methods like
+    # #each.
+    class Hash < ::Hash
+      include JRuby::Synchronized
+    end
+  elsif !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby'
+    # Because MRI never runs code in parallel, the existing
+    # non-thread-safe structures should usually work fine.
+    Array = ::Array
+    Hash  = ::Hash
+  elsif defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
+    require 'monitor'
+
+    class Hash < ::Hash; end
+    class Array < ::Array; end
+
+    [Hash, Array].each do |klass|
+      klass.class_eval do
+        private
+        def _mon_initialize
+          @_monitor = Monitor.new unless @_monitor # avoid double initialisation
+        end
+
+        def self.allocate
+          obj = super
+          obj.send(:_mon_initialize)
+          obj
+        end
+      end
+
+      klass.superclass.instance_methods(false).each do |method|
+        klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
+          def #{method}(*args)
+            @_monitor.synchronize { super }
+          end
+        RUBY_EVAL
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/atomic_reference_cache_backend.rb b/app/server/vendor/thread_safe/lib/thread_safe/atomic_reference_cache_backend.rb
new file mode 100644
index 0000000..0e4af2d
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/atomic_reference_cache_backend.rb
@@ -0,0 +1,922 @@
+module ThreadSafe
+  # A Ruby port of the Doug Lea's jsr166e.ConcurrentHashMapV8 class version 1.59 available in public domain.
+  # Original source code available here: http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/ConcurrentHashMapV8.java?revision=1.59
+  #
+  # The Ruby port skips out the +TreeBin+ (red-black trees for use in bins
+  # whose size exceeds a threshold).
+  #
+  # A hash table supporting full concurrency of retrievals and
+  # high expected concurrency for updates. However, even though all
+  # operations are thread-safe, retrieval operations do _not_ entail locking,
+  # and there is _not_ any support for locking the entire table
+  # in a way that prevents all access.
+  #
+  # Retrieval operations generally do not block, so may overlap with
+  # update operations. Retrievals reflect the results of the most
+  # recently _completed_ update operations holding upon their
+  # onset. (More formally, an update operation for a given key bears a
+  # _happens-before_ relation with any (non +nil+) retrieval for
+  # that key reporting the updated value.)  For aggregate operations
+  # such as +clear()+, concurrent retrievals may reflect insertion or removal
+  # of only some entries.  Similarly, the +each_pair+ iterator yields elements
+  # reflecting the state of the hash table at some point at or since
+  # the start of the +each_pair+. Bear in mind that the results of
+  # aggregate status methods including +size()+ and +empty?+} are typically
+  # useful only when a map is not undergoing concurrent updates in other
+  # threads. Otherwise the results of these methods reflect transient
+  # states that may be adequate for monitoring or estimation purposes, but not
+  # for program control.
+  #
+  # The table is dynamically expanded when there are too many
+  # collisions (i.e., keys that have distinct hash codes but fall into
+  # the same slot modulo the table size), with the expected average
+  # effect of maintaining roughly two bins per mapping (corresponding
+  # to a 0.75 load factor threshold for resizing). There may be much
+  # variance around this average as mappings are added and removed, but
+  # overall, this maintains a commonly accepted time/space tradeoff for
+  # hash tables.  However, resizing this or any other kind of hash
+  # table may be a relatively slow operation. When possible, it is a
+  # good idea to provide a size estimate as an optional :initial_capacity
+  # initializer argument. An additional optional :load_factor constructor
+  # argument provides a further means of customizing initial table capacity
+  # by specifying the table density to be used in calculating the amount of
+  # space to allocate for the given number of elements. Note that using
+  # many keys with exactly the same +hash+ is a sure way to slow down
+  # performance of any hash table.
+  #
+  # == Design overview
+  #
+  # The primary design goal of this hash table is to maintain
+  # concurrent readability (typically method +[]+, but also
+  # iteration and related methods) while minimizing update
+  # contention. Secondary goals are to keep space consumption about
+  # the same or better than plain +Hash+, and to support high
+  # initial insertion rates on an empty table by many threads.
+  #
+  # Each key-value mapping is held in a +Node+. The validation-based
+  # approach explained below leads to a lot of code sprawl because
+  # retry-control precludes factoring into smaller methods.
+  #
+  # The table is lazily initialized to a power-of-two size upon the
+  # first insertion.  Each bin in the table normally contains a
+  # list of +Node+s (most often, the list has only zero or one +Node+).
+  # Table accesses require volatile/atomic reads, writes, and
+  # CASes. The lists of nodes within bins are always accurately traversable
+  # under volatile reads, so long as lookups check hash code
+  # and non-nullness of value before checking key equality.
+  #
+  # We use the top two bits of +Node+ hash fields for control
+  # purposes -- they are available anyway because of addressing
+  # constraints.  As explained further below, these top bits are
+  # used as follows:
+  #  00 - Normal
+  #  01 - Locked
+  #  11 - Locked and may have a thread waiting for lock
+  #  10 - +Node+ is a forwarding node
+  #
+  # The lower 28 bits of each +Node+'s hash field contain a
+  # the key's hash code, except for forwarding nodes, for which
+  # the lower bits are zero (and so always have hash field == +MOVED+).
+  #
+  # Insertion (via +[]=+ or its variants) of the first node in an
+  # empty bin is performed by just CASing it to the bin.  This is
+  # by far the most common case for put operations under most
+  # key/hash distributions.  Other update operations (insert,
+  # delete, and replace) require locks.  We do not want to waste
+  # the space required to associate a distinct lock object with
+  # each bin, so instead use the first node of a bin list itself as
+  # a lock. Blocking support for these locks relies +Util::CheapLockable.
+  # However, we also need a +try_lock+ construction, so we overlay
+  # these by using bits of the +Node+ hash field for lock control (see above),
+  # and so normally use builtin monitors only for blocking and signalling using
+  # +cheap_wait+/+cheap_broadcast+ constructions. See +Node#try_await_lock+.
+  #
+  # Using the first node of a list as a lock does not by itself
+  # suffice though: When a node is locked, any update must first
+  # validate that it is still the first node after locking it, and
+  # retry if not. Because new nodes are always appended to lists,
+  # once a node is first in a bin, it remains first until deleted
+  # or the bin becomes invalidated (upon resizing).  However,
+  # operations that only conditionally update may inspect nodes
+  # until the point of update. This is a converse of sorts to the
+  # lazy locking technique described by Herlihy & Shavit.
+  #
+  # The main disadvantage of per-bin locks is that other update
+  # operations on other nodes in a bin list protected by the same
+  # lock can stall, for example when user +eql?+ or mapping
+  # functions take a long time.  However, statistically, under
+  # random hash codes, this is not a common problem.  Ideally, the
+  # frequency of nodes in bins follows a Poisson distribution
+  # (http://en.wikipedia.org/wiki/Poisson_distribution) with a
+  # parameter of about 0.5 on average, given the resizing threshold
+  # of 0.75, although with a large variance because of resizing
+  # granularity. Ignoring variance, the expected occurrences of
+  # list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The
+  # first values are:
+  #
+  #  0:    0.60653066
+  #  1:    0.30326533
+  #  2:    0.07581633
+  #  3:    0.01263606
+  #  4:    0.00157952
+  #  5:    0.00015795
+  #  6:    0.00001316
+  #  7:    0.00000094
+  #  8:    0.00000006
+  #  more: less than 1 in ten million
+  #
+  # Lock contention probability for two threads accessing distinct
+  # elements is roughly 1 / (8 * #elements) under random hashes.
+  #
+  # The table is resized when occupancy exceeds a percentage
+  # threshold (nominally, 0.75, but see below).  Only a single
+  # thread performs the resize (using field +size_control+, to arrange
+  # exclusion), but the table otherwise remains usable for reads
+  # and updates. Resizing proceeds by transferring bins, one by
+  # one, from the table to the next table.  Because we are using
+  # power-of-two expansion, the elements from each bin must either
+  # stay at same index, or move with a power of two offset. We
+  # eliminate unnecessary node creation by catching cases where old
+  # nodes can be reused because their next fields won't change.  On
+  # average, only about one-sixth of them need cloning when a table
+  # doubles. The nodes they replace will be garbage collectable as
+  # soon as they are no longer referenced by any reader thread that
+  # may be in the midst of concurrently traversing table.  Upon
+  # transfer, the old table bin contains only a special forwarding
+  # node (with hash field +MOVED+) that contains the next table as
+  # its key. On encountering a forwarding node, access and update
+  # operations restart, using the new table.
+  #
+  # Each bin transfer requires its bin lock. However, unlike other
+  # cases, a transfer can skip a bin if it fails to acquire its
+  # lock, and revisit it later. Method +rebuild+ maintains a buffer of
+  # TRANSFER_BUFFER_SIZE bins that have been skipped because of failure
+  # to acquire a lock, and blocks only if none are available
+  # (i.e., only very rarely). The transfer operation must also ensure
+  # that all accessible bins in both the old and new table are usable by
+  # any traversal. When there are no lock acquisition failures, this is
+  # arranged simply by proceeding from the last bin (+table.size - 1+) up
+  # towards the first.  Upon seeing a forwarding node, traversals arrange
+  # to move to the new table without revisiting nodes. However, when any
+  # node is skipped during a transfer, all earlier table bins may have
+  # become visible, so are initialized with a reverse-forwarding node back
+  # to the old table until the new ones are established. (This
+  # sometimes requires transiently locking a forwarding node, which
+  # is possible under the above encoding.) These more expensive
+  # mechanics trigger only when necessary.
+  #
+  # The traversal scheme also applies to partial traversals of
+  # ranges of bins (via an alternate Traverser constructor)
+  # to support partitioned aggregate operations.  Also, read-only
+  # operations give up if ever forwarded to a null table, which
+  # provides support for shutdown-style clearing, which is also not
+  # currently implemented.
+  #
+  # Lazy table initialization minimizes footprint until first use.
+  #
+  # The element count is maintained using a +ThreadSafe::Util::Adder+,
+  # which avoids contention on updates but can encounter cache thrashing
+  # if read too frequently during concurrent access. To avoid reading so
+  # often, resizing is attempted either when a bin lock is
+  # contended, or upon adding to a bin already holding two or more
+  # nodes (checked before adding in the +x_if_absent+ methods, after
+  # adding in others). Under uniform hash distributions, the
+  # probability of this occurring at threshold is around 13%,
+  # meaning that only about 1 in 8 puts check threshold (and after
+  # resizing, many fewer do so). But this approximation has high
+  # variance for small table sizes, so we check on any collision
+  # for sizes <= 64. The bulk putAll operation further reduces
+  # contention by only committing count updates upon these size
+  # checks.
+  class AtomicReferenceCacheBackend
+    class Table < Util::PowerOfTwoTuple
+      def cas_new_node(i, hash, key, value)
+        cas(i, nil, Node.new(hash, key, value))
+      end
+
+      def try_to_cas_in_computed(i, hash, key)
+        succeeded = false
+        new_value = nil
+        new_node  = Node.new(locked_hash = hash | LOCKED, key, NULL)
+        if cas(i, nil, new_node)
+          begin
+            if NULL == (new_value = yield(NULL))
+              was_null = true
+            else
+              new_node.value = new_value
+            end
+            succeeded = true
+          ensure
+            volatile_set(i, nil) if !succeeded || was_null
+            new_node.unlock_via_hash(locked_hash, hash)
+          end
+        end
+        return succeeded, new_value
+      end
+
+      def try_lock_via_hash(i, node, node_hash)
+        node.try_lock_via_hash(node_hash) do
+          yield if volatile_get(i) == node
+        end
+      end
+
+      def delete_node_at(i, node, predecessor_node)
+        if predecessor_node
+          predecessor_node.next = node.next
+        else
+          volatile_set(i, node.next)
+        end
+      end
+    end
+
+    # Key-value entry. Nodes with a hash field of +MOVED+ are special,
+    # and do not contain user keys or values.  Otherwise, keys are never +nil+,
+    # and +NULL+ +value+ fields indicate that a node is in the process
+    # of being deleted or created. For purposes of read-only access, a key may be read
+    # before a value, but can only be used after checking value to be +!= NULL+.
+    class Node
+      extend Util::Volatile
+      attr_volatile :hash, :value, :next
+
+      include Util::CheapLockable
+
+      bit_shift = Util::FIXNUM_BIT_SIZE - 2 # need 2 bits for ourselves
+      # Encodings for special uses of Node hash fields. See above for explanation.
+      MOVED     = ('10' << ('0' * bit_shift)).to_i(2) # hash field for forwarding nodes
+      LOCKED    = ('01' << ('0' * bit_shift)).to_i(2) # set/tested only as a bit
+      WAITING   = ('11' << ('0' * bit_shift)).to_i(2) # both bits set/tested together
+      HASH_BITS = ('00' << ('1' * bit_shift)).to_i(2) # usable bits of normal node hash
+
+      SPIN_LOCK_ATTEMPTS = Util::CPU_COUNT > 1 ? Util::CPU_COUNT * 2 : 0
+
+      attr_reader :key
+
+      def initialize(hash, key, value, next_node = nil)
+        super()
+        @key = key
+        self.lazy_set_hash(hash)
+        self.lazy_set_value(value)
+        self.next = next_node
+      end
+
+      # Spins a while if +LOCKED+ bit set and this node is the first
+      # of its bin, and then sets +WAITING+ bits on hash field and
+      # blocks (once) if they are still set.  It is OK for this
+      # method to return even if lock is not available upon exit,
+      # which enables these simple single-wait mechanics.
+      #
+      # The corresponding signalling operation is performed within
+      # callers: Upon detecting that +WAITING+ has been set when
+      # unlocking lock (via a failed CAS from non-waiting +LOCKED+
+      # state), unlockers acquire the +cheap_synchronize+ lock and
+      # perform a +cheap_broadcast+.
+      def try_await_lock(table, i)
+        if table && i >= 0 && i < table.size # bounds check, TODO: why are we bounds checking?
+          spins = SPIN_LOCK_ATTEMPTS
+          randomizer = base_randomizer = Util::XorShiftRandom.get
+          while equal?(table.volatile_get(i)) && self.class.locked_hash?(my_hash = hash)
+            if spins >= 0
+              if (randomizer = (randomizer >> 1)).even? # spin at random
+                if (spins -= 1) == 0
+                  Thread.pass # yield before blocking
+                else
+                  randomizer = base_randomizer = Util::XorShiftRandom.xorshift(base_randomizer) if randomizer.zero?
+                end
+              end
+            elsif cas_hash(my_hash, my_hash | WAITING)
+              force_aquire_lock(table, i)
+              break
+            end
+          end
+        end
+      end
+
+      def key?(key)
+        @key.eql?(key)
+      end
+
+      def matches?(key, hash)
+        pure_hash == hash && key?(key)
+      end
+
+      def pure_hash
+        hash & HASH_BITS
+      end
+
+      def try_lock_via_hash(node_hash = hash)
+        if cas_hash(node_hash, locked_hash = node_hash | LOCKED)
+          begin
+            yield
+          ensure
+            unlock_via_hash(locked_hash, node_hash)
+          end
+        end
+      end
+
+      def locked?
+        self.class.locked_hash?(hash)
+      end
+
+      def unlock_via_hash(locked_hash, node_hash)
+        unless cas_hash(locked_hash, node_hash)
+          self.hash = node_hash
+          cheap_synchronize { cheap_broadcast }
+        end
+      end
+
+      private
+      def force_aquire_lock(table, i)
+        cheap_synchronize do
+          if equal?(table.volatile_get(i)) && (hash & WAITING) == WAITING
+            cheap_wait
+          else
+            cheap_broadcast # possibly won race vs signaller
+          end
+        end
+      end
+
+      class << self
+        def locked_hash?(hash)
+          (hash & LOCKED) != 0
+        end
+      end
+    end
+
+    # shorthands
+    MOVED     = Node::MOVED
+    LOCKED    = Node::LOCKED
+    WAITING   = Node::WAITING
+    HASH_BITS = Node::HASH_BITS
+
+    NOW_RESIZING     = -1
+    DEFAULT_CAPACITY = 16
+    MAX_CAPACITY     = Util::MAX_INT
+
+    # The buffer size for skipped bins during transfers. The
+    # value is arbitrary but should be large enough to avoid
+    # most locking stalls during resizes.
+    TRANSFER_BUFFER_SIZE = 32
+
+    extend Util::Volatile
+    attr_volatile :table, # The array of bins. Lazily initialized upon first insertion. Size is always a power of two.
+
+                  # Table initialization and resizing control.  When negative, the
+                  # table is being initialized or resized. Otherwise, when table is
+                  # null, holds the initial table size to use upon creation, or 0
+                  # for default. After initialization, holds the next element count
+                  # value upon which to resize the table.
+                  :size_control
+
+    def initialize(options = nil)
+      super()
+      @counter = Util::Adder.new
+      initial_capacity  = options && options[:initial_capacity] || DEFAULT_CAPACITY
+      self.size_control = (capacity = table_size_for(initial_capacity)) > MAX_CAPACITY ? MAX_CAPACITY : capacity
+    end
+
+    def get_or_default(key, else_value = nil)
+      hash          = key_hash(key)
+      current_table = table
+      while current_table
+        node = current_table.volatile_get_by_hash(hash)
+        current_table =
+          while node
+            if (node_hash = node.hash) == MOVED
+              break node.key
+            elsif (node_hash & HASH_BITS) == hash && node.key?(key) && NULL != (value = node.value)
+              return value
+            end
+            node = node.next
+          end
+      end
+      else_value
+    end
+
+    def [](key)
+      get_or_default(key)
+    end
+
+    def key?(key)
+      get_or_default(key, NULL) != NULL
+    end
+
+    def []=(key, value)
+      get_and_set(key, value)
+      value
+    end
+
+    def compute_if_absent(key)
+      hash          = key_hash(key)
+      current_table = table || initialize_table
+      while true
+        if !(node = current_table.volatile_get(i = current_table.hash_to_index(hash)))
+          succeeded, new_value = current_table.try_to_cas_in_computed(i, hash, key) { yield }
+          if succeeded
+            increment_size
+            return new_value
+          end
+        elsif (node_hash = node.hash) == MOVED
+          current_table = node.key
+        elsif NULL != (current_value = find_value_in_node_list(node, key, hash, node_hash & HASH_BITS))
+          return current_value
+        elsif Node.locked_hash?(node_hash)
+          try_await_lock(current_table, i, node)
+        else
+          succeeded, value = attempt_internal_compute_if_absent(key, hash, current_table, i, node, node_hash) { yield }
+          return value if succeeded
+        end
+      end
+    end
+
+    def compute_if_present(key)
+      new_value = nil
+      internal_replace(key) do |old_value|
+        if (new_value = yield(NULL == old_value ? nil : old_value)).nil?
+          NULL
+        else
+          new_value
+        end
+      end
+      new_value
+    end
+
+    def compute(key)
+      internal_compute(key) do |old_value|
+        if (new_value = yield(NULL == old_value ? nil : old_value)).nil?
+          NULL
+        else
+          new_value
+        end
+      end
+    end
+
+    def merge_pair(key, value)
+      internal_compute(key) do |old_value|
+        if NULL == old_value || !(value = yield(old_value)).nil?
+          value
+        else
+          NULL
+        end
+      end
+    end
+
+    def replace_pair(key, old_value, new_value)
+      NULL != internal_replace(key, old_value) { new_value }
+    end
+
+    def replace_if_exists(key, new_value)
+      if (result = internal_replace(key) { new_value }) && NULL != result
+        result
+      end
+    end
+
+    def get_and_set(key, value) # internalPut in the original CHMV8
+      hash          = key_hash(key)
+      current_table = table || initialize_table
+      while true
+        if !(node = current_table.volatile_get(i = current_table.hash_to_index(hash)))
+          if current_table.cas_new_node(i, hash, key, value)
+            increment_size
+            break
+          end
+        elsif (node_hash = node.hash) == MOVED
+          current_table = node.key
+        elsif Node.locked_hash?(node_hash)
+          try_await_lock(current_table, i, node)
+        else
+          succeeded, old_value = attempt_get_and_set(key, value, hash, current_table, i, node, node_hash)
+          break old_value if succeeded
+        end
+      end
+    end
+
+    def delete(key)
+      replace_if_exists(key, NULL)
+    end
+
+    def delete_pair(key, value)
+      result = internal_replace(key, value) { NULL }
+      if result && NULL != result
+        !!result
+      else
+        false
+      end
+    end
+
+    def each_pair
+      return self unless current_table = table
+      current_table_size = base_size = current_table.size
+      i = base_index = 0
+      while base_index < base_size
+        if node = current_table.volatile_get(i)
+          if node.hash == MOVED
+            current_table      = node.key
+            current_table_size = current_table.size
+          else
+            begin
+              if NULL != (value = node.value) # skip deleted or special nodes
+                yield node.key, value
+              end
+            end while node = node.next
+          end
+        end
+
+        if (i_with_base = i + base_size) < current_table_size
+          i = i_with_base # visit upper slots if present
+        else
+          i = base_index += 1
+        end
+      end
+      self
+    end
+
+    def size
+      (sum = @counter.sum) < 0 ? 0 : sum # ignore transient negative values
+    end
+
+    def empty?
+      size == 0
+    end
+
+    # Implementation for clear. Steps through each bin, removing all nodes.
+    def clear
+      return self unless current_table = table
+      current_table_size = current_table.size
+      deleted_count = i = 0
+      while i < current_table_size
+        if !(node = current_table.volatile_get(i))
+          i += 1
+        elsif (node_hash = node.hash) == MOVED
+          current_table      = node.key
+          current_table_size = current_table.size
+        elsif Node.locked_hash?(node_hash)
+          decrement_size(deleted_count) # opportunistically update count
+          deleted_count = 0
+          node.try_await_lock(current_table, i)
+        else
+          current_table.try_lock_via_hash(i, node, node_hash) do
+            begin
+              deleted_count += 1 if NULL != node.value # recheck under lock
+              node.value = nil
+            end while node = node.next
+            current_table.volatile_set(i, nil)
+            i += 1
+          end
+        end
+      end
+      decrement_size(deleted_count)
+      self
+    end
+
+    private
+    # Internal versions of the insertion methods, each a
+    # little more complicated than the last. All have
+    # the same basic structure:
+    #  1. If table uninitialized, create
+    #  2. If bin empty, try to CAS new node
+    #  3. If bin stale, use new table
+    #  4. Lock and validate; if valid, scan and add or update
+    #
+    # The others interweave other checks and/or alternative actions:
+    #  * Plain +get_and_set+ checks for and performs resize after insertion.
+    #  * compute_if_absent prescans for mapping without lock (and fails to add
+    #    if present), which also makes pre-emptive resize checks worthwhile.
+    #
+    # Someday when details settle down a bit more, it might be worth
+    # some factoring to reduce sprawl.
+    def internal_replace(key, expected_old_value = NULL, &block)
+      hash          = key_hash(key)
+      current_table = table
+      while current_table
+        if !(node = current_table.volatile_get(i = current_table.hash_to_index(hash)))
+          break
+        elsif (node_hash = node.hash) == MOVED
+          current_table = node.key
+        elsif (node_hash & HASH_BITS) != hash && !node.next # precheck
+          break # rules out possible existence
+        elsif Node.locked_hash?(node_hash)
+          try_await_lock(current_table, i, node)
+        else
+          succeeded, old_value = attempt_internal_replace(key, expected_old_value, hash, current_table, i, node, node_hash, &block)
+          return old_value if succeeded
+        end
+      end
+      NULL
+    end
+
+    def attempt_internal_replace(key, expected_old_value, hash, current_table, i, node, node_hash)
+      current_table.try_lock_via_hash(i, node, node_hash) do
+        predecessor_node = nil
+        old_value        = NULL
+        begin
+          if node.matches?(key, hash) && NULL != (current_value = node.value)
+            if NULL == expected_old_value || expected_old_value == current_value # NULL == expected_old_value means whatever value
+              old_value = current_value
+              if NULL == (node.value = yield(old_value))
+                current_table.delete_node_at(i, node, predecessor_node)
+                decrement_size
+              end
+            end
+            break
+          end
+
+          predecessor_node = node
+        end while node = node.next
+
+        return true, old_value
+      end
+    end
+
+    def find_value_in_node_list(node, key, hash, pure_hash)
+      do_check_for_resize = false
+      while true
+        if pure_hash == hash && node.key?(key) && NULL != (value = node.value)
+          return value
+        elsif node = node.next
+          do_check_for_resize = true # at least 2 nodes -> check for resize
+          pure_hash = node.pure_hash
+        else
+          return NULL
+        end
+      end
+    ensure
+      check_for_resize if do_check_for_resize
+    end
+
+    def internal_compute(key, &block)
+      hash          = key_hash(key)
+      current_table = table || initialize_table
+      while true
+        if !(node = current_table.volatile_get(i = current_table.hash_to_index(hash)))
+          succeeded, new_value = current_table.try_to_cas_in_computed(i, hash, key, &block)
+          if succeeded
+            if NULL == new_value
+              break nil
+            else
+              increment_size
+              break new_value
+            end
+          end
+        elsif (node_hash = node.hash) == MOVED
+          current_table = node.key
+        elsif Node.locked_hash?(node_hash)
+          try_await_lock(current_table, i, node)
+        else
+          succeeded, new_value = attempt_compute(key, hash, current_table, i, node, node_hash, &block)
+          break new_value if succeeded
+        end
+      end
+    end
+
+    def attempt_internal_compute_if_absent(key, hash, current_table, i, node, node_hash)
+      added = false
+      current_table.try_lock_via_hash(i, node, node_hash) do
+        while true
+          if node.matches?(key, hash) && NULL != (value = node.value)
+            return true, value
+          end
+          last = node
+          unless node = node.next
+            last.next = Node.new(hash, key, value = yield)
+            added = true
+            increment_size
+            return true, value
+          end
+        end
+      end
+    ensure
+      check_for_resize if added
+    end
+
+    def attempt_compute(key, hash, current_table, i, node, node_hash)
+      added = false
+      current_table.try_lock_via_hash(i, node, node_hash) do
+        predecessor_node = nil
+        while true
+          if node.matches?(key, hash) && NULL != (value = node.value)
+            if NULL == (node.value = value = yield(value))
+              current_table.delete_node_at(i, node, predecessor_node)
+              decrement_size
+              value = nil
+            end
+            return true, value
+          end
+          predecessor_node = node
+          unless node = node.next
+            if NULL == (value = yield(NULL))
+              value = nil
+            else
+              predecessor_node.next = Node.new(hash, key, value)
+              added = true
+              increment_size
+            end
+            return true, value
+          end
+        end
+      end
+    ensure
+      check_for_resize if added
+    end
+
+    def attempt_get_and_set(key, value, hash, current_table, i, node, node_hash)
+      node_nesting = nil
+      current_table.try_lock_via_hash(i, node, node_hash) do
+        node_nesting    = 1
+        old_value       = nil
+        found_old_value = false
+        while node
+          if node.matches?(key, hash) && NULL != (old_value = node.value)
+            found_old_value = true
+            node.value = value
+            break
+          end
+          last = node
+          unless node = node.next
+            last.next = Node.new(hash, key, value)
+            break
+          end
+          node_nesting += 1
+        end
+
+        return true, old_value if found_old_value
+        increment_size
+        true
+      end
+    ensure
+      check_for_resize if node_nesting && (node_nesting > 1 || current_table.size <= 64)
+    end
+
+    def initialize_copy(other)
+      super
+      @counter = Util::Adder.new
+      self.table = nil
+      self.size_control = (other_table = other.table) ? other_table.size : DEFAULT_CAPACITY
+      self
+    end
+
+    def try_await_lock(current_table, i, node)
+      check_for_resize # try resizing if can't get lock
+      node.try_await_lock(current_table, i)
+    end
+
+    def key_hash(key)
+      key.hash & HASH_BITS
+    end
+
+    # Returns a power of two table size for the given desired capacity.
+    def table_size_for(entry_count)
+      size = 2
+      size <<= 1 while size < entry_count
+      size
+    end
+
+    # Initializes table, using the size recorded in +size_control+.
+    def initialize_table
+      until current_table ||= table
+        if (size_ctrl = size_control) == NOW_RESIZING
+          Thread.pass # lost initialization race; just spin
+        else
+          try_in_resize_lock(current_table, size_ctrl) do
+            initial_size = size_ctrl > 0 ? size_ctrl : DEFAULT_CAPACITY
+            current_table = self.table = Table.new(initial_size)
+            initial_size - (initial_size >> 2) # 75% load factor
+          end
+        end
+      end
+      current_table
+    end
+
+    # If table is too small and not already resizing, creates next
+    # table and transfers bins.  Rechecks occupancy after a transfer
+    # to see if another resize is already needed because resizings
+    # are lagging additions.
+    def check_for_resize
+      while (current_table = table) && MAX_CAPACITY > (table_size = current_table.size) && NOW_RESIZING != (size_ctrl = size_control) && size_ctrl < @counter.sum
+        try_in_resize_lock(current_table, size_ctrl) do
+          self.table = rebuild(current_table)
+          (table_size << 1) - (table_size >> 1) # 75% load factor
+        end
+      end
+    end
+
+    def try_in_resize_lock(current_table, size_ctrl)
+      if cas_size_control(size_ctrl, NOW_RESIZING)
+        begin
+          if current_table == table # recheck under lock
+            size_ctrl = yield # get new size_control
+          end
+        ensure
+          self.size_control = size_ctrl
+        end
+      end
+    end
+
+    # Moves and/or copies the nodes in each bin to new table. See above for explanation.
+    def rebuild(table)
+      old_table_size = table.size
+      new_table      = table.next_in_size_table
+      # puts "#{old_table_size} -> #{new_table.size}"
+      forwarder      = Node.new(MOVED, new_table, NULL)
+      rev_forwarder  = nil
+      locked_indexes = nil # holds bins to revisit; nil until needed
+      locked_arr_idx = 0
+      bin            = old_table_size - 1
+      i              = bin
+      while true
+        if !(node = table.volatile_get(i))
+          # no lock needed (or available) if bin >= 0, because we're not popping values from locked_indexes until we've run through the whole table
+          redo unless (bin >= 0 ? table.cas(i, nil, forwarder) : lock_and_clean_up_reverse_forwarders(table, old_table_size, new_table, i, forwarder))
+        elsif Node.locked_hash?(node_hash = node.hash)
+          locked_indexes ||= Array.new
+          if bin < 0 && locked_arr_idx > 0
+            locked_arr_idx -= 1
+            i, locked_indexes[locked_arr_idx] = locked_indexes[locked_arr_idx], i # swap with another bin
+            redo
+          end
+          if bin < 0 || locked_indexes.size >= TRANSFER_BUFFER_SIZE
+            node.try_await_lock(table, i) # no other options -- block
+            redo
+          end
+          rev_forwarder ||= Node.new(MOVED, table, NULL)
+          redo unless table.volatile_get(i) == node && node.locked? # recheck before adding to list
+          locked_indexes << i
+          new_table.volatile_set(i, rev_forwarder)
+          new_table.volatile_set(i + old_table_size, rev_forwarder)
+        else
+          redo unless split_old_bin(table, new_table, i, node, node_hash, forwarder)
+        end
+
+        if bin > 0
+          i = (bin -= 1)
+        elsif locked_indexes && !locked_indexes.empty?
+          bin = -1
+          i = locked_indexes.pop
+          locked_arr_idx = locked_indexes.size - 1
+        else
+          return new_table
+        end
+      end
+    end
+
+    def lock_and_clean_up_reverse_forwarders(old_table, old_table_size, new_table, i, forwarder)
+      # transiently use a locked forwarding node
+      locked_forwarder = Node.new(moved_locked_hash = MOVED | LOCKED, new_table, NULL)
+      if old_table.cas(i, nil, locked_forwarder)
+        new_table.volatile_set(i, nil) # kill the potential reverse forwarders
+        new_table.volatile_set(i + old_table_size, nil) # kill the potential reverse forwarders
+        old_table.volatile_set(i, forwarder)
+        locked_forwarder.unlock_via_hash(moved_locked_hash, MOVED)
+        true
+      end
+    end
+
+    # Splits a normal bin with list headed by e into lo and hi parts; installs in given table.
+    def split_old_bin(table, new_table, i, node, node_hash, forwarder)
+      table.try_lock_via_hash(i, node, node_hash) do
+        split_bin(new_table, i, node, node_hash)
+        table.volatile_set(i, forwarder)
+      end
+    end
+
+    def split_bin(new_table, i, node, node_hash)
+      bit          = new_table.size >> 1 # bit to split on
+      run_bit      = node_hash & bit
+      last_run     = nil
+      low          = nil
+      high         = nil
+      current_node = node
+      # this optimises for the lowest amount of volatile writes and objects created
+      while current_node = current_node.next
+        unless (b = current_node.hash & bit) == run_bit
+          run_bit  = b
+          last_run = current_node
+        end
+      end
+      if run_bit == 0
+        low = last_run
+      else
+        high = last_run
+      end
+      current_node = node
+      until current_node == last_run
+        pure_hash = current_node.pure_hash
+        if (pure_hash & bit) == 0
+          low = Node.new(pure_hash, current_node.key, current_node.value, low)
+        else
+          high = Node.new(pure_hash, current_node.key, current_node.value, high)
+        end
+        current_node = current_node.next
+      end
+      new_table.volatile_set(i, low)
+      new_table.volatile_set(i + bit, high)
+    end
+
+    def increment_size
+      @counter.increment
+    end
+
+    def decrement_size(by = 1)
+      @counter.add(-by)
+    end
+  end
+end
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/cache.rb b/app/server/vendor/thread_safe/lib/thread_safe/cache.rb
new file mode 100644
index 0000000..2539941
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/cache.rb
@@ -0,0 +1,163 @@
+require 'thread'
+
+module ThreadSafe
+  autoload :JRubyCacheBackend,           'thread_safe/jruby_cache_backend'
+  autoload :MriCacheBackend,             'thread_safe/mri_cache_backend'
+  autoload :NonConcurrentCacheBackend,   'thread_safe/non_concurrent_cache_backend'
+  autoload :AtomicReferenceCacheBackend, 'thread_safe/atomic_reference_cache_backend'
+  autoload :SynchronizedCacheBackend,    'thread_safe/synchronized_cache_backend'
+
+  ConcurrentCacheBackend = if defined?(RUBY_ENGINE)
+    case RUBY_ENGINE
+    when 'jruby'; JRubyCacheBackend
+    when 'ruby';  MriCacheBackend
+    when 'rbx';   AtomicReferenceCacheBackend
+    else
+      warn 'ThreadSafe: unsupported Ruby engine, using a fully synchronized ThreadSafe::Cache implementation' if $VERBOSE
+      SynchronizedCacheBackend
+    end
+  else
+    MriCacheBackend
+  end
+
+  class Cache < ConcurrentCacheBackend
+    KEY_ERROR = defined?(KeyError) ? KeyError : IndexError # there is no KeyError in 1.8 mode
+
+    def initialize(options = nil, &block)
+      if options.kind_of?(::Hash)
+        validate_options_hash!(options)
+      else
+        options = nil
+      end
+
+      super(options)
+      @default_proc = block
+    end
+
+    def [](key)
+      if value = super # non-falsy value is an existing mapping, return it right away
+        value
+      # re-check is done with get_or_default(key, NULL) instead of a simple !key?(key) in order to avoid a race condition, whereby by the time the current thread gets to the key?(key) call
+      # a key => value mapping might have already been created by a different thread (key?(key) would then return true, this elsif branch wouldn't be taken and an incorrent +nil+ value
+      # would be returned)
+      # note: nil == value check is not technically necessary
+      elsif @default_proc && nil == value && NULL == (value = get_or_default(key, NULL))
+        @default_proc.call(self, key)
+      else
+        value
+      end
+    end
+
+    alias_method :get, :[]
+    alias_method :put, :[]=
+
+    def fetch(key, default_value = NULL)
+      if NULL != (value = get_or_default(key, NULL))
+        value
+      elsif block_given?
+        yield key
+      elsif NULL != default_value
+        default_value
+      else
+        raise_fetch_no_key
+      end
+    end
+
+    def fetch_or_store(key, default_value = NULL)
+      fetch(key) do
+        put(key, block_given? ? yield(key) : (NULL == default_value ? raise_fetch_no_key : default_value))
+      end
+    end
+
+    def put_if_absent(key, value)
+      computed = false
+      result = compute_if_absent(key) do
+        computed = true
+        value
+      end
+      computed ? nil : result
+    end unless method_defined?(:put_if_absent)
+
+    def value?(value)
+      each_value do |v|
+        return true if value.equal?(v)
+      end
+      false
+    end unless method_defined?(:value?)
+
+    def keys
+      arr = []
+      each_pair {|k, v| arr << k}
+      arr
+    end unless method_defined?(:keys)
+
+    def values
+      arr = []
+      each_pair {|k, v| arr << v}
+      arr
+    end unless method_defined?(:values)
+
+    def each_key
+      each_pair {|k, v| yield k}
+    end unless method_defined?(:each_key)
+
+    def each_value
+      each_pair {|k, v| yield v}
+    end unless method_defined?(:each_value)
+
+    def key(value)
+      each_pair {|k, v| return k if v == value}
+      nil
+    end unless method_defined?(:key)
+    alias_method :index, :key if RUBY_VERSION < '1.9'
+
+    def empty?
+      each_pair {|k, v| return false}
+      true
+    end unless method_defined?(:empty?)
+
+    def size
+      count = 0
+      each_pair {|k, v| count += 1}
+      count
+    end unless method_defined?(:size)
+
+    def marshal_dump
+      raise TypeError, "can't dump hash with default proc" if @default_proc
+      h = {}
+      each_pair {|k, v| h[k] = v}
+      h
+    end
+
+    def marshal_load(hash)
+      initialize
+      populate_from(hash)
+    end
+
+    undef :freeze
+
+    private
+    def raise_fetch_no_key
+      raise KEY_ERROR, 'key not found'
+    end
+
+    def initialize_copy(other)
+      super
+      populate_from(other)
+    end
+
+    def populate_from(hash)
+      hash.each_pair {|k, v| self[k] = v}
+      self
+    end
+
+    def validate_options_hash!(options)
+      if (initial_capacity = options[:initial_capacity]) && (!initial_capacity.kind_of?(Fixnum) || initial_capacity < 0)
+        raise ArgumentError, ":initial_capacity must be a positive Fixnum"
+      end
+      if (load_factor = options[:load_factor]) && (!load_factor.kind_of?(Numeric) || load_factor <= 0 || load_factor > 1)
+        raise ArgumentError, ":load_factor must be a number between 0 and 1"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/mri_cache_backend.rb b/app/server/vendor/thread_safe/lib/thread_safe/mri_cache_backend.rb
new file mode 100644
index 0000000..8768297
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/mri_cache_backend.rb
@@ -0,0 +1,62 @@
+module ThreadSafe
+  class MriCacheBackend < NonConcurrentCacheBackend
+    # We can get away with a single global write lock (instead of a per-instance one) because of the GVL/green threads.
+    #
+    # The previous implementation used `Thread.critical` on 1.8 MRI to implement the 4 composed atomic operations (`put_if_absent`, `replace_pair`,
+    # `replace_if_exists`, `delete_pair`) this however doesn't work for `compute_if_absent` because on 1.8 the Mutex class is itself implemented
+    # via `Thread.critical` and a call to `Mutex#lock` does not restore the previous `Thread.critical` value (thus any synchronisation clears the
+    # `Thread.critical` flag and we loose control). This poses a problem as the provided block might use synchronisation on its own.
+    #
+    # NOTE: a neat idea of writing a c-ext to manually perform atomic put_if_absent, while relying on Ruby not releasing a GVL while calling
+    # a c-ext will not work because of the potentially Ruby implemented `#hash` and `#eql?` key methods.
+    WRITE_LOCK = Mutex.new
+
+    def []=(key, value)
+      WRITE_LOCK.synchronize { super }
+    end
+
+    def compute_if_absent(key)
+      if stored_value = _get(key) # fast non-blocking path for the most likely case
+        stored_value
+      else
+        WRITE_LOCK.synchronize { super }
+      end
+    end
+
+    def compute_if_present(key)
+      WRITE_LOCK.synchronize { super }
+    end
+
+    def compute(key)
+      WRITE_LOCK.synchronize { super }
+    end
+
+    def merge_pair(key, value)
+      WRITE_LOCK.synchronize { super }
+    end
+
+    def replace_pair(key, old_value, new_value)
+      WRITE_LOCK.synchronize { super }
+    end
+
+    def replace_if_exists(key, new_value)
+      WRITE_LOCK.synchronize { super }
+    end
+
+    def get_and_set(key, value)
+      WRITE_LOCK.synchronize { super }
+    end
+
+    def delete(key)
+      WRITE_LOCK.synchronize { super }
+    end
+
+    def delete_pair(key, value)
+      WRITE_LOCK.synchronize { super }
+    end
+
+    def clear
+      WRITE_LOCK.synchronize { super }
+    end
+  end
+end
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/non_concurrent_cache_backend.rb b/app/server/vendor/thread_safe/lib/thread_safe/non_concurrent_cache_backend.rb
new file mode 100644
index 0000000..2ef86d8
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/non_concurrent_cache_backend.rb
@@ -0,0 +1,133 @@
+module ThreadSafe
+  class NonConcurrentCacheBackend
+    # WARNING: all public methods of the class must operate on the @backend directly without calling each other. This is important
+    # because of the SynchronizedCacheBackend which uses a non-reentrant mutex for perfomance reasons.
+    def initialize(options = nil)
+      @backend = {}
+    end
+
+    def [](key)
+      @backend[key]
+    end
+
+    def []=(key, value)
+      @backend[key] = value
+    end
+
+    def compute_if_absent(key)
+      if NULL != (stored_value = @backend.fetch(key, NULL))
+        stored_value
+      else
+        @backend[key] = yield
+      end
+    end
+
+    def replace_pair(key, old_value, new_value)
+      if pair?(key, old_value)
+        @backend[key] = new_value
+        true
+      else
+        false
+      end
+    end
+
+    def replace_if_exists(key, new_value)
+      if NULL != (stored_value = @backend.fetch(key, NULL))
+        @backend[key] = new_value
+        stored_value
+      end
+    end
+
+    def compute_if_present(key)
+      if NULL != (stored_value = @backend.fetch(key, NULL))
+        store_computed_value(key, yield(stored_value))
+      end
+    end
+
+    def compute(key)
+      store_computed_value(key, yield(@backend[key]))
+    end
+
+    def merge_pair(key, value)
+      if NULL == (stored_value = @backend.fetch(key, NULL))
+        @backend[key] = value
+      else
+        store_computed_value(key, yield(stored_value))
+      end
+    end
+
+    def get_and_set(key, value)
+      stored_value = @backend[key]
+      @backend[key] = value
+      stored_value
+    end
+
+    def key?(key)
+      @backend.key?(key)
+    end
+
+    def value?(value)
+      @backend.value?(value)
+    end
+
+    def delete(key)
+      @backend.delete(key)
+    end
+
+    def delete_pair(key, value)
+      if pair?(key, value)
+        @backend.delete(key)
+        true
+      else
+        false
+      end
+    end
+
+    def clear
+      @backend.clear
+      self
+    end
+
+    def each_pair
+      dupped_backend.each_pair do |k, v|
+        yield k, v
+      end
+      self
+    end
+
+    def size
+      @backend.size
+    end
+
+    def get_or_default(key, default_value)
+      @backend.fetch(key, default_value)
+    end
+
+    alias_method :_get, :[]
+    alias_method :_set, :[]=
+    private :_get, :_set
+    private
+    def initialize_copy(other)
+      super
+      @backend = {}
+      self
+    end
+
+    def dupped_backend
+      @backend.dup
+    end
+
+    def pair?(key, expected_value)
+      NULL != (stored_value = @backend.fetch(key, NULL)) && expected_value.equal?(stored_value)
+    end
+
+    def store_computed_value(key, new_value)
+      if new_value.nil?
+        @backend.delete(key)
+        nil
+      else
+        @backend[key] = new_value
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/synchronized_cache_backend.rb b/app/server/vendor/thread_safe/lib/thread_safe/synchronized_cache_backend.rb
new file mode 100644
index 0000000..37a897f
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/synchronized_cache_backend.rb
@@ -0,0 +1,76 @@
+module ThreadSafe
+  class SynchronizedCacheBackend < NonConcurrentCacheBackend
+    require 'mutex_m'
+    include Mutex_m
+    # WARNING: Mutex_m is a non-reentrant lock, so the synchronized methods are not allowed to call each other.
+
+    def [](key)
+      synchronize { super }
+    end
+
+    def []=(key, value)
+      synchronize { super }
+    end
+
+    def compute_if_absent(key)
+      synchronize { super }
+    end
+
+    def compute_if_present(key)
+      synchronize { super }
+    end
+
+    def compute(key)
+      synchronize { super }
+    end
+
+    def merge_pair(key, value)
+      synchronize { super }
+    end
+
+    def replace_pair(key, old_value, new_value)
+      synchronize { super }
+    end
+
+    def replace_if_exists(key, new_value)
+      synchronize { super }
+    end
+
+    def get_and_set(key, value)
+      synchronize { super }
+    end
+
+    def key?(key)
+      synchronize { super }
+    end
+
+    def value?(value)
+      synchronize { super }
+    end
+
+    def delete(key)
+      synchronize { super }
+    end
+
+    def delete_pair(key, value)
+      synchronize { super }
+    end
+
+    def clear
+      synchronize { super }
+    end
+
+    def size
+      synchronize { super }
+    end
+
+    def get_or_default(key, default_value)
+      synchronize { super }
+    end
+
+    private
+    def dupped_backend
+      synchronize { super }
+    end
+  end
+end
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/synchronized_delegator.rb b/app/server/vendor/thread_safe/lib/thread_safe/synchronized_delegator.rb
new file mode 100644
index 0000000..9e18a56
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/synchronized_delegator.rb
@@ -0,0 +1,60 @@
+require 'delegate'
+require 'monitor'
+
+# This class provides a trivial way to synchronize all calls to a given object
+# by wrapping it with a `Delegator` that performs `Monitor#enter/exit` calls
+# around the delegated `#send`. Example:
+#
+#   array = [] # not thread-safe on many impls
+#   array = SynchronizedDelegator.new([]) # thread-safe
+#
+# A simple `Monitor` provides a very coarse-grained way to synchronize a given
+# object, in that it will cause synchronization for methods that have no
+# need for it, but this is a trivial way to get thread-safety where none may
+# exist currently on some implementations.
+#
+# This class is currently being considered for inclusion into stdlib, via
+# https://bugs.ruby-lang.org/issues/8556
+class SynchronizedDelegator < SimpleDelegator
+  def setup
+    @old_abort = Thread.abort_on_exception
+    Thread.abort_on_exception = true
+  end
+
+  def teardown
+    Thread.abort_on_exception = @old_abort
+  end
+
+  def initialize(obj)
+    __setobj__(obj)
+    @monitor = Monitor.new
+  end
+
+  def method_missing(method, *args, &block)
+    monitor = @monitor
+    begin
+      monitor.enter
+      super
+    ensure
+      monitor.exit
+    end
+  end
+
+  # Work-around for 1.8 std-lib not passing block around to delegate.
+  # @private
+  def method_missing(method, *args, &block)
+    monitor = @monitor
+    begin
+      monitor.enter
+      target = self.__getobj__
+      if target.respond_to?(method)
+        target.__send__(method, *args, &block)
+      else
+        super(method, *args, &block)
+      end
+    ensure
+      monitor.exit
+    end
+  end if RUBY_VERSION[0, 3] == '1.8'
+
+end unless defined?(SynchronizedDelegator)
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/util.rb b/app/server/vendor/thread_safe/lib/thread_safe/util.rb
new file mode 100644
index 0000000..bad4238
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/util.rb
@@ -0,0 +1,16 @@
+module ThreadSafe
+  module Util
+    FIXNUM_BIT_SIZE = (0.size * 8) - 2
+    MAX_INT         = (2 ** FIXNUM_BIT_SIZE) - 1
+    CPU_COUNT       = 16 # is there a way to determine this?
+
+    autoload :AtomicReference, 'thread_safe/util/atomic_reference'
+    autoload :Adder,           'thread_safe/util/adder'
+    autoload :CheapLockable,   'thread_safe/util/cheap_lockable'
+    autoload :PowerOfTwoTuple, 'thread_safe/util/power_of_two_tuple'
+    autoload :Striped64,       'thread_safe/util/striped64'
+    autoload :Volatile,        'thread_safe/util/volatile'
+    autoload :VolatileTuple,   'thread_safe/util/volatile_tuple'
+    autoload :XorShiftRandom,  'thread_safe/util/xor_shift_random'
+  end
+end
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/util/adder.rb b/app/server/vendor/thread_safe/lib/thread_safe/util/adder.rb
new file mode 100644
index 0000000..35d01ee
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/util/adder.rb
@@ -0,0 +1,59 @@
+module ThreadSafe
+  module Util
+    # A Ruby port of the Doug Lea's jsr166e.LondAdder class version 1.8 available in public domain.
+    # Original source code available here: http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/LongAdder.java?revision=1.8
+    #
+    # One or more variables that together maintain an initially zero
+    # sum. When updates (method +add+) are contended across threads,
+    # the set of variables may grow dynamically to reduce contention.
+    # Method +sum+ returns the current total combined across the
+    # variables maintaining the sum.
+    #
+    # This class is usually preferable to single +Atomic+ reference when
+    # multiple threads update a common sum that is used for purposes such
+    # as collecting statistics, not for fine-grained synchronization
+    # control.  Under low update contention, the two classes have similar
+    # characteristics. But under high contention, expected throughput of
+    # this class is significantly higher, at the expense of higher space
+    # consumption.
+    class Adder < Striped64
+      # Adds the given value.
+      def add(x)
+        if (current_cells = cells) || !cas_base_computed {|current_base| current_base + x}
+          was_uncontended = true
+          hash            = hash_code
+          unless current_cells && (cell = current_cells.volatile_get_by_hash(hash)) && (was_uncontended = cell.cas_computed {|current_value| current_value + x})
+            retry_update(x, hash, was_uncontended) {|current_value| current_value + x}
+          end
+        end
+      end
+
+      def increment
+        add(1)
+      end
+
+      def decrement
+        add(-1)
+      end
+
+      # Returns the current sum.  The returned value is _NOT_ an
+      # atomic snapshot: Invocation in the absence of concurrent
+      # updates returns an accurate result, but concurrent updates that
+      # occur while the sum is being calculated might not be
+      # incorporated.
+      def sum
+        x = base
+        if current_cells = cells
+          current_cells.each do |cell|
+            x += cell.value if cell
+          end
+        end
+        x
+      end
+
+      def reset
+        internal_reset(0)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/util/atomic_reference.rb b/app/server/vendor/thread_safe/lib/thread_safe/util/atomic_reference.rb
new file mode 100644
index 0000000..4d01e9f
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/util/atomic_reference.rb
@@ -0,0 +1,45 @@
+module ThreadSafe
+  module Util
+    AtomicReference =
+      if defined?(Rubinius::AtomicReference)
+        # An overhead-less atomic reference.
+        Rubinius::AtomicReference
+      else
+        begin
+          require 'atomic'
+          defined?(Atomic::InternalReference) ? Atomic::InternalReference : Atomic
+        rescue LoadError, NameError
+          require 'thread' # get Mutex on 1.8
+          class FullLockingAtomicReference
+            def initialize(value = nil)
+              @___mutex = Mutex.new
+              @___value = value
+            end
+
+            def get
+              @___mutex.synchronize { @___value }
+            end
+            alias_method :value, :get
+
+            def set(new_value)
+              @___mutex.synchronize { @___value = new_value }
+            end
+            alias_method :value=, :set
+
+            def compare_and_set(old_value, new_value)
+              return false unless @___mutex.try_lock
+              begin
+                return false unless @___value.equal? old_value
+                @___value = new_value
+              ensure
+                @___mutex.unlock
+              end
+              true
+            end
+          end
+
+          FullLockingAtomicReference
+        end
+      end
+  end
+end
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/util/cheap_lockable.rb b/app/server/vendor/thread_safe/lib/thread_safe/util/cheap_lockable.rb
new file mode 100644
index 0000000..b317ed2
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/util/cheap_lockable.rb
@@ -0,0 +1,105 @@
+module ThreadSafe
+  module Util
+    # Provides a cheapest possible (mainly in terms of memory usage) +Mutex+ with the +ConditionVariable+ bundled in.
+    #
+    # Usage:
+    #   class A
+    #     include CheapLockable
+    #
+    #     def do_exlusively
+    #       cheap_synchronize { yield }
+    #     end
+    #
+    #     def wait_for_something
+    #       cheap_synchronize do
+    #         cheap_wait until resource_available?
+    #         do_something
+    #         cheap_broadcast # wake up others
+    #       end
+    #     end
+    #   end
+    module CheapLockable
+      private
+      engine = defined?(RUBY_ENGINE) && RUBY_ENGINE
+      if engine == 'rbx'
+        # Making use of the Rubinius' ability to lock via object headers to avoid the overhead of the extra Mutex objects.
+        def cheap_synchronize
+          Rubinius.lock(self)
+          begin
+            yield
+          ensure
+            Rubinius.unlock(self)
+          end
+        end
+
+        def cheap_wait
+          wchan = Rubinius::Channel.new
+
+          begin
+            waiters = @waiters ||= []
+            waiters.push wchan
+            Rubinius.unlock(self)
+            signaled = wchan.receive_timeout nil
+          ensure
+            Rubinius.lock(self)
+
+            unless signaled or waiters.delete(wchan)
+              # we timed out, but got signaled afterwards (e.g. while waiting to
+              # acquire @lock), so pass that signal on to the next waiter
+              waiters.shift << true unless waiters.empty?
+            end
+          end
+
+          self
+        end
+
+        def cheap_broadcast
+          waiters = @waiters ||= []
+          waiters.shift << true until waiters.empty?
+          self
+        end
+      elsif engine == 'jruby'
+        # Use Java's native synchronized (this) { wait(); notifyAll(); } to avoid the overhead of the extra Mutex objects
+        require 'jruby'
+
+        def cheap_synchronize
+          JRuby.reference0(self).synchronized { yield }
+        end
+
+        def cheap_wait
+          JRuby.reference0(self).wait
+        end
+
+        def cheap_broadcast
+          JRuby.reference0(self).notify_all
+        end
+      else
+        require 'thread'
+
+        extend Volatile
+        attr_volatile :mutex
+
+        # Non-reentrant Mutex#syncrhonize
+        def cheap_synchronize
+          true until (my_mutex = mutex) || cas_mutex(nil, my_mutex = Mutex.new)
+          my_mutex.synchronize { yield }
+        end
+
+        # Releases this object's +cheap_synchronize+ lock and goes to sleep waiting for other threads to +cheap_broadcast+, reacquires the lock on wakeup.
+        # Must only be called in +cheap_broadcast+'s block.
+        def cheap_wait
+          conditional_variable = @conditional_variable ||= ConditionVariable.new
+          conditional_variable.wait(mutex)
+        end
+
+        # Wakes up all threads waiting for this object's +cheap_synchronize+ lock.
+        # Must only be called in +cheap_broadcast+'s block.
+        def cheap_broadcast
+          if conditional_variable = @conditional_variable
+            conditional_variable.broadcast
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/util/power_of_two_tuple.rb b/app/server/vendor/thread_safe/lib/thread_safe/util/power_of_two_tuple.rb
new file mode 100644
index 0000000..3e2d076
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/util/power_of_two_tuple.rb
@@ -0,0 +1,26 @@
+module ThreadSafe
+  module Util
+    class PowerOfTwoTuple < VolatileTuple
+      def initialize(size)
+        raise ArgumentError, "size must be a power of 2 (#{size.inspect} provided)" unless size > 0 && size & (size - 1) == 0
+        super(size)
+      end
+
+      def hash_to_index(hash)
+        (size - 1) & hash
+      end
+
+      def volatile_get_by_hash(hash)
+        volatile_get(hash_to_index(hash))
+      end
+
+      def volatile_set_by_hash(hash, value)
+        volatile_set(hash_to_index(hash), value)
+      end
+
+      def next_in_size_table
+        self.class.new(size << 1)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/util/striped64.rb b/app/server/vendor/thread_safe/lib/thread_safe/util/striped64.rb
new file mode 100644
index 0000000..5296204
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/util/striped64.rb
@@ -0,0 +1,226 @@
+module ThreadSafe
+  module Util
+    # A Ruby port of the Doug Lea's jsr166e.Striped64 class version 1.6 available in public domain.
+    # Original source code available here: http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/Striped64.java?revision=1.6
+    #
+    # Class holding common representation and mechanics for classes supporting dynamic striping on 64bit values.
+    #
+    # This class maintains a lazily-initialized table of atomically
+    # updated variables, plus an extra +base+ field. The table size
+    # is a power of two. Indexing uses masked per-thread hash codes.
+    # Nearly all methods on this class are private, accessed directly
+    # by subclasses.
+    #
+    # Table entries are of class +Cell+; a variant of AtomicLong padded
+    # to reduce cache contention on most processors. Padding is
+    # overkill for most Atomics because they are usually irregularly
+    # scattered in memory and thus don't interfere much with each
+    # other. But Atomic objects residing in arrays will tend to be
+    # placed adjacent to each other, and so will most often share
+    # cache lines (with a huge negative performance impact) without
+    # this precaution.
+    #
+    # In part because +Cell+s are relatively large, we avoid creating
+    # them until they are needed.  When there is no contention, all
+    # updates are made to the +base+ field.  Upon first contention (a
+    # failed CAS on +base+ update), the table is initialized to size 2.
+    # The table size is doubled upon further contention until
+    # reaching the nearest power of two greater than or equal to the
+    # number of CPUS. Table slots remain empty (+nil+) until they are
+    # needed.
+    #
+    # A single spinlock (+busy+) is used for initializing and
+    # resizing the table, as well as populating slots with new +Cell+s.
+    # There is no need for a blocking lock: When the lock is not
+    # available, threads try other slots (or the base).  During these
+    # retries, there is increased contention and reduced locality,
+    # which is still better than alternatives.
+    #
+    # Per-thread hash codes are initialized to random values.
+    # Contention and/or table collisions are indicated by failed
+    # CASes when performing an update operation (see method
+    # +retry_update+). Upon a collision, if the table size is less than
+    # the capacity, it is doubled in size unless some other thread
+    # holds the lock. If a hashed slot is empty, and lock is
+    # available, a new +Cell+ is created. Otherwise, if the slot
+    # exists, a CAS is tried.  Retries proceed by "double hashing",
+    # using a secondary hash (XorShift) to try to find a
+    # free slot.
+    #
+    # The table size is capped because, when there are more threads
+    # than CPUs, supposing that each thread were bound to a CPU,
+    # there would exist a perfect hash function mapping threads to
+    # slots that eliminates collisions. When we reach capacity, we
+    # search for this mapping by randomly varying the hash codes of
+    # colliding threads.  Because search is random, and collisions
+    # only become known via CAS failures, convergence can be slow,
+    # and because threads are typically not bound to CPUS forever,
+    # may not occur at all. However, despite these limitations,
+    # observed contention rates are typically low in these cases.
+    #
+    # It is possible for a +Cell+ to become unused when threads that
+    # once hashed to it terminate, as well as in the case where
+    # doubling the table causes no thread to hash to it under
+    # expanded mask.  We do not try to detect or remove such cells,
+    # under the assumption that for long-running instances, observed
+    # contention levels will recur, so the cells will eventually be
+    # needed again; and for short-lived ones, it does not matter.
+    class Striped64
+      # Padded variant of AtomicLong supporting only raw accesses plus CAS.
+      # The +value+ field is placed between pads, hoping that the JVM doesn't
+      # reorder them.
+      #
+      # Optimisation note: It would be possible to use a release-only
+      # form of CAS here, if it were provided.
+      class Cell < AtomicReference
+        # TODO: this only adds padding after the :value slot, need to find a way to add padding before the slot
+        attr_reader *(Array.new(12).map {|i| :"padding_#{i}"})
+
+        alias_method :cas, :compare_and_set
+
+        def cas_computed
+          cas(current_value = value, yield(current_value))
+        end
+      end
+
+      extend Volatile
+      attr_volatile :cells, # Table of cells. When non-null, size is a power of 2.
+                    :base,  # Base value, used mainly when there is no contention, but also as a fallback during table initialization races. Updated via CAS.
+                    :busy   # Spinlock (locked via CAS) used when resizing and/or creating Cells.
+
+      alias_method :busy?, :busy
+
+      def initialize
+        super()
+        self.busy = false
+        self.base = 0
+      end
+
+      # Handles cases of updates involving initialization, resizing,
+      # creating new Cells, and/or contention. See above for
+      # explanation. This method suffers the usual non-modularity
+      # problems of optimistic retry code, relying on rechecked sets of
+      # reads.
+      #
+      # Arguments:
+      # [+x+]
+      #   the value
+      # [+hash_code+]
+      #   hash code used
+      # [+x+]
+      #   false if CAS failed before call
+      def retry_update(x, hash_code, was_uncontended) # :yields: current_value
+        hash     = hash_code
+        collided = false # True if last slot nonempty
+        while true
+          if current_cells = cells
+            if !(cell = current_cells.volatile_get_by_hash(hash))
+              if busy?
+                collided = false
+              else # Try to attach new Cell
+                if try_to_install_new_cell(Cell.new(x), hash) # Optimistically create and try to insert new cell
+                  break
+                else
+                  redo # Slot is now non-empty
+                end
+              end
+            elsif !was_uncontended # CAS already known to fail
+              was_uncontended = true # Continue after rehash
+            elsif cell.cas_computed {|current_value| yield current_value}
+              break
+            elsif current_cells.size >= CPU_COUNT || cells != current_cells # At max size or stale
+              collided = false
+            elsif collided && expand_table_unless_stale(current_cells)
+              collided = false
+              redo # Retry with expanded table
+            else
+              collided = true
+            end
+            hash = XorShiftRandom.xorshift(hash)
+
+          elsif try_initialize_cells(x, hash) || cas_base_computed {|current_base| yield current_base}
+            break
+          end
+        end
+        self.hash_code = hash
+      end
+
+      private
+      # Static per-thread hash code key. Shared across all instances to
+      # reduce Thread locals pollution and because adjustments due to
+      # collisions in one table are likely to be appropriate for
+      # others.
+      THREAD_LOCAL_KEY = "#{name}.hash_code".to_sym
+
+      # A thread-local hash code accessor. The code is initially
+      # random, but may be set to a different value upon collisions.
+      def hash_code
+        Thread.current[THREAD_LOCAL_KEY] ||= XorShiftRandom.get
+      end
+
+      def hash_code=(hash)
+        Thread.current[THREAD_LOCAL_KEY] = hash
+      end
+
+      # Sets base and all +cells+ to the given value.
+      def internal_reset(initial_value)
+        current_cells = cells
+        self.base     = initial_value
+        if current_cells
+          current_cells.each do |cell|
+            cell.value = initial_value if cell
+          end
+        end
+      end
+
+      def cas_base_computed
+        cas_base(current_base = base, yield(current_base))
+      end
+
+      def free?
+        !busy?
+      end
+
+      def try_initialize_cells(x, hash)
+        if free? && !cells
+          try_in_busy do
+            unless cells # Recheck under lock
+              new_cells = PowerOfTwoTuple.new(2)
+              new_cells.volatile_set_by_hash(hash, Cell.new(x))
+              self.cells = new_cells
+            end
+          end
+        end
+      end
+
+      def expand_table_unless_stale(current_cells)
+        try_in_busy do
+          if current_cells == cells # Recheck under lock
+            new_cells = current_cells.next_in_size_table
+            current_cells.each_with_index {|x, i| new_cells.volatile_set(i, x)}
+            self.cells = new_cells
+          end
+        end
+      end
+
+      def try_to_install_new_cell(new_cell, hash)
+        try_in_busy do
+          # Recheck under lock
+          if (current_cells = cells) && !current_cells.volatile_get(i = current_cells.hash_to_index(hash))
+            current_cells.volatile_set(i, new_cell)
+          end
+        end
+      end
+
+      def try_in_busy
+        if cas_busy(false, true)
+          begin
+            yield
+          ensure
+            self.busy = false
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/util/volatile.rb b/app/server/vendor/thread_safe/lib/thread_safe/util/volatile.rb
new file mode 100644
index 0000000..8a8b9fb
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/util/volatile.rb
@@ -0,0 +1,62 @@
+module ThreadSafe
+  module Util
+    module Volatile
+      # Provides +volatile+ (in the JVM's sense) attribute accessors implemented atop of the +AtomicReference+s.
+      # Usage:
+      #   class Foo
+      #     extend ThreadSafe::Util::Volatile
+      #     attr_volatile :foo, :bar
+      #
+      #     def initialize(bar)
+      #       super() # must super() into parent initializers before using the volatile attribute accessors
+      #       self.bar = bar
+      #     end
+      #
+      #     def hello
+      #       my_foo = foo # volatile read
+      #       self.foo = 1 # volatile write
+      #       cas_foo(1, 2) # => true | a strong CAS
+      #     end
+      #   end
+      def attr_volatile(*attr_names)
+        return if attr_names.empty?
+        include(Module.new do
+          atomic_ref_setup = attr_names.map {|attr_name| "@__#{attr_name} = ThreadSafe::Util::AtomicReference.new"}
+          initialize_copy_setup = attr_names.zip(atomic_ref_setup).map do |attr_name, ref_setup|
+            "#{ref_setup}(other.instance_variable_get(:@__#{attr_name}).get)"
+          end
+          class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
+            def initialize(*)
+              super
+              #{atomic_ref_setup.join('; ')}
+            end
+
+            def initialize_copy(other)
+              super
+              #{initialize_copy_setup.join('; ')}
+            end
+          RUBY_EVAL
+
+          attr_names.each do |attr_name|
+            class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
+              def #{attr_name}
+                @__#{attr_name}.get
+              end
+
+              def #{attr_name}=(value)
+                @__#{attr_name}.set(value)
+              end
+
+              def compare_and_set_#{attr_name}(old_value, new_value)
+                @__#{attr_name}.compare_and_set(old_value, new_value)
+              end
+            RUBY_EVAL
+
+            alias_method :"cas_#{attr_name}", :"compare_and_set_#{attr_name}"
+            alias_method :"lazy_set_#{attr_name}", :"#{attr_name}="
+          end
+        end)
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/util/volatile_tuple.rb b/app/server/vendor/thread_safe/lib/thread_safe/util/volatile_tuple.rb
new file mode 100644
index 0000000..500beb7
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/util/volatile_tuple.rb
@@ -0,0 +1,46 @@
+module ThreadSafe
+  module Util
+    # A fixed size array with volatile volatile getters/setters.
+    # Usage:
+    #   arr = VolatileTuple.new(16)
+    #   arr.volatile_set(0, :foo)
+    #   arr.volatile_get(0)    # => :foo
+    #   arr.cas(0, :foo, :bar) # => true
+    #   arr.volatile_get(0)    # => :bar
+    class VolatileTuple
+      include Enumerable
+
+      Tuple = defined?(Rubinius::Tuple) ? Rubinius::Tuple : Array
+
+      def initialize(size)
+        @tuple = tuple = Tuple.new(size)
+        i = 0
+        while i < size
+          tuple[i] = AtomicReference.new
+          i += 1
+        end
+      end
+
+      def volatile_get(i)
+        @tuple[i].get
+      end
+
+      def volatile_set(i, value)
+        @tuple[i].set(value)
+      end
+
+      def compare_and_set(i, old_value, new_value)
+        @tuple[i].compare_and_set(old_value, new_value)
+      end
+      alias_method :cas, :compare_and_set
+
+      def size
+        @tuple.size
+      end
+
+      def each
+        @tuple.each {|ref| yield ref.get}
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/util/xor_shift_random.rb b/app/server/vendor/thread_safe/lib/thread_safe/util/xor_shift_random.rb
new file mode 100644
index 0000000..ad8bf7b
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/util/xor_shift_random.rb
@@ -0,0 +1,39 @@
+module ThreadSafe
+  module Util
+    # A xorshift random number (positive +Fixnum+s) generator, provides reasonably cheap way to generate thread local random numbers without contending for
+    # the global +Kernel.rand+.
+    # Usage:
+    #   x = XorShiftRandom.get # uses Kernel.rand to generate an initial seed
+    #   while true
+    #     if (x = XorShiftRandom.xorshift).odd? # thread-localy generate a next random number
+    #       do_something_at_random
+    #     end
+    #   end
+    module XorShiftRandom
+      extend self
+      MAX_XOR_SHIFTABLE_INT = MAX_INT - 1
+
+      # Generates an initial non-zero positive +Fixnum+ via +Kernel.rand+.
+      def get
+        Kernel.rand(MAX_XOR_SHIFTABLE_INT) + 1 # 0 can't be xorshifted
+      end
+
+      # xorshift based on: http://www.jstatsoft.org/v08/i14/paper
+      if 0.size == 4
+        # using the "yˆ=y>>a; yˆ=y<<b; yˆ=y>>c;" transform with the (a,b,c) tuple with values (3,1,14) to minimise Bignum overflows
+        def xorshift(x)
+          x ^= x >> 3
+          x ^= (x << 1) & MAX_INT # cut-off Bignum overflow
+          x ^= x >> 14
+        end
+      else
+        # using the "yˆ=y>>a; yˆ=y<<b; yˆ=y>>c;" transform with the (a,b,c) tuple with values (1,1,54) to minimise Bignum overflows
+        def xorshift(x)
+          x ^= x >> 1
+          x ^= (x << 1) & MAX_INT # cut-off Bignum overflow
+          x ^= x >> 54
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/thread_safe/lib/thread_safe/version.rb b/app/server/vendor/thread_safe/lib/thread_safe/version.rb
new file mode 100644
index 0000000..e5e7c92
--- /dev/null
+++ b/app/server/vendor/thread_safe/lib/thread_safe/version.rb
@@ -0,0 +1,21 @@
+module ThreadSafe
+  VERSION = "0.3.4"
+end
+
+# NOTE: <= 0.2.0 used Threadsafe::VERSION
+# @private
+module Threadsafe
+
+  # @private
+  def self.const_missing(name)
+    name = name.to_sym
+    if ThreadSafe.const_defined?(name)
+      warn "[DEPRECATION] `Threadsafe::#{name}' is deprecated, use `ThreadSafe::#{name}' instead."
+      ThreadSafe.const_get(name)
+    else
+      warn "[DEPRECATION] the `Threadsafe' module is deprecated, please use `ThreadSafe` instead."
+      super
+    end
+  end
+
+end
diff --git a/app/server/vendor/thread_safe/test/src/thread_safe/SecurityManager.java b/app/server/vendor/thread_safe/test/src/thread_safe/SecurityManager.java
new file mode 100644
index 0000000..beb6c02
--- /dev/null
+++ b/app/server/vendor/thread_safe/test/src/thread_safe/SecurityManager.java
@@ -0,0 +1,21 @@
+package thread_safe;
+
+import java.security.Permission;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SecurityManager extends java.lang.SecurityManager {
+  private final List<Permission> deniedPermissions =
+      new ArrayList<Permission>();
+
+  @Override
+  public void checkPermission(Permission p) {
+    if (deniedPermissions.contains(p)) {
+      throw new SecurityException("Denied!");
+    }
+  }
+
+  public void deny(Permission p) {
+    deniedPermissions.add(p);
+  }
+}
diff --git a/app/server/vendor/thread_safe/test/test_array.rb b/app/server/vendor/thread_safe/test/test_array.rb
new file mode 100644
index 0000000..7a6023a
--- /dev/null
+++ b/app/server/vendor/thread_safe/test/test_array.rb
@@ -0,0 +1,18 @@
+require 'thread_safe'
+require File.join(File.dirname(__FILE__), "test_helper")
+
+class TestArray < Minitest::Test
+  def test_concurrency
+    ary = ThreadSafe::Array.new
+    (1..100).map do |i|
+      Thread.new do
+        1000.times do
+          ary << i
+          ary.each {|x| x * 2}
+          ary.shift
+          ary.last
+        end
+      end
+    end.map(&:join)
+  end
+end
diff --git a/app/server/vendor/thread_safe/test/test_cache.rb b/app/server/vendor/thread_safe/test/test_cache.rb
new file mode 100644
index 0000000..1dfb42d
--- /dev/null
+++ b/app/server/vendor/thread_safe/test/test_cache.rb
@@ -0,0 +1,901 @@
+require 'thread_safe'
+require 'thread'
+require File.join(File.dirname(__FILE__), "test_helper")
+
+Thread.abort_on_exception = true
+
+class TestCache < Minitest::Test
+  def setup
+    @cache = ThreadSafe::Cache.new
+  end
+
+  def test_concurrency
+    cache = @cache
+    (1..100).map do |i|
+      Thread.new do
+        1000.times do |j|
+          key = i*1000+j
+          cache[key] = i
+          cache[key]
+          cache.delete(key)
+        end
+      end
+    end.map(&:join)
+  end
+
+  def test_retrieval
+    assert_size_change 1 do
+      assert_equal nil, @cache[:a]
+      assert_equal nil, @cache.get(:a)
+      @cache[:a] = 1
+      assert_equal 1,   @cache[:a]
+      assert_equal 1,   @cache.get(:a)
+    end
+  end
+
+  def test_put_if_absent
+    with_or_without_default_proc do
+      assert_size_change 1 do
+        assert_equal nil, @cache.put_if_absent(:a, 1)
+        assert_equal 1,   @cache.put_if_absent(:a, 1)
+        assert_equal 1,   @cache.put_if_absent(:a, 2)
+        assert_equal 1,   @cache[:a]
+      end
+    end
+  end
+
+  def test_compute_if_absent
+    with_or_without_default_proc do
+      assert_size_change 3 do
+        assert_equal(1,   (@cache.compute_if_absent(:a) {1}))
+        assert_equal(1,   (@cache.compute_if_absent(:a) {2}))
+        assert_equal 1,    @cache[:a]
+        @cache[:b] = nil
+        assert_equal(nil, (@cache.compute_if_absent(:b) {1}))
+        assert_equal(nil, (@cache.compute_if_absent(:c) {}))
+        assert_equal nil,  @cache[:c]
+        assert_equal true, @cache.key?(:c)
+      end
+    end
+  end
+
+  def test_compute_if_absent_with_return
+    with_or_without_default_proc { assert_handles_return_lambda(:compute_if_absent, :a) }
+  end
+
+  def test_compute_if_absent_exception
+    with_or_without_default_proc { assert_handles_exception(:compute_if_absent, :a) }
+  end
+
+  def test_compute_if_absent_atomicity
+    late_compute_threads_count       = 10
+    late_put_if_absent_threads_count = 10
+    getter_threads_count             = 5
+    compute_started = ThreadSafe::Test::Latch.new(1)
+    compute_proceed = ThreadSafe::Test::Latch.new(late_compute_threads_count + late_put_if_absent_threads_count + getter_threads_count)
+    block_until_compute_started = lambda do |name|
+      if (v = @cache[:a]) != nil
+        assert_equal nil, v
+      end
+      compute_proceed.release
+      compute_started.await
+    end
+
+    assert_size_change 1 do
+      late_compute_threads = Array.new(late_compute_threads_count) do
+        Thread.new do
+          block_until_compute_started.call('compute_if_absent')
+          assert_equal(1, (@cache.compute_if_absent(:a) { flunk }))
+        end
+      end
+
+      late_put_if_absent_threads = Array.new(late_put_if_absent_threads_count) do
+        Thread.new do
+          block_until_compute_started.call('put_if_absent')
+          assert_equal(1, @cache.put_if_absent(:a, 2))
+        end
+      end
+
+      getter_threads = Array.new(getter_threads_count) do
+        Thread.new do
+          block_until_compute_started.call('getter')
+          Thread.pass while @cache[:a].nil?
+          assert_equal 1, @cache[:a]
+        end
+      end
+
+      Thread.new do
+        @cache.compute_if_absent(:a) do
+          compute_started.release
+          compute_proceed.await
+          sleep(0.2)
+          1
+        end
+      end.join
+      (late_compute_threads + late_put_if_absent_threads + getter_threads).each(&:join)
+    end
+  end
+
+  def test_compute_if_present
+    with_or_without_default_proc do
+      assert_no_size_change do
+        assert_equal(nil,   @cache.compute_if_present(:a) {})
+        assert_equal(nil,   @cache.compute_if_present(:a) {1})
+        assert_equal(nil,   @cache.compute_if_present(:a) {flunk})
+        assert_equal false, @cache.key?(:a)
+      end
+
+      @cache[:a] = 1
+      assert_no_size_change do
+        assert_equal(1,     @cache.compute_if_present(:a) {1})
+        assert_equal(1,     @cache[:a])
+        assert_equal(2,     @cache.compute_if_present(:a) {2})
+        assert_equal(2,     @cache[:a])
+        assert_equal(false, @cache.compute_if_present(:a) {false})
+        assert_equal(false, @cache[:a])
+
+        @cache[:a] = 1
+        yielded    = false
+        @cache.compute_if_present(:a) do |old_value|
+          yielded = true
+          assert_equal 1, old_value
+          2
+        end
+        assert yielded
+      end
+
+      assert_size_change -1 do
+        assert_equal(nil,   @cache.compute_if_present(:a) {})
+        assert_equal(false, @cache.key?(:a))
+        assert_equal(nil,   @cache.compute_if_present(:a) {1})
+        assert_equal(false, @cache.key?(:a))
+      end
+    end
+  end
+
+  def test_compute_if_present_with_return
+    with_or_without_default_proc do
+      @cache[:a] = 1
+      assert_handles_return_lambda(:compute_if_present, :a)
+    end
+  end
+
+  def test_compute_if_present_exception
+    with_or_without_default_proc do
+      @cache[:a] = 1
+      assert_handles_exception(:compute_if_present, :a)
+    end
+  end
+
+  def test_compute
+    with_or_without_default_proc do
+      assert_no_size_change do
+        assert_compute(:a, nil, nil) {}
+      end
+
+      assert_size_change 1 do
+        assert_compute(:a, nil, 1)   {1}
+        assert_compute(:a, 1,   2)   {2}
+        assert_compute(:a, 2, false) {false}
+        assert_equal false, @cache[:a]
+      end
+
+      assert_size_change -1 do
+        assert_compute(:a, false, nil) {}
+      end
+    end
+  end
+
+  def test_compute_with_return
+    with_or_without_default_proc do
+      assert_handles_return_lambda(:compute, :a)
+      @cache[:a] = 1
+      assert_handles_return_lambda(:compute, :a)
+    end
+  end
+
+  def test_compute_exception
+    with_or_without_default_proc do
+      assert_handles_exception(:compute, :a)
+      @cache[:a] = 1
+      assert_handles_exception(:compute, :a)
+    end
+  end
+
+  def test_merge_pair
+    with_or_without_default_proc do
+      assert_size_change 1 do
+        assert_equal(nil,  @cache.merge_pair(:a, nil) {flunk})
+        assert_equal true, @cache.key?(:a)
+        assert_equal nil,  @cache[:a]
+      end
+
+      assert_no_size_change do
+        assert_merge_pair(:a, nil, nil,   false) {false}
+        assert_merge_pair(:a, nil, false, 1)     {1}
+        assert_merge_pair(:a, nil, 1,     2)     {2}
+      end
+
+      assert_size_change -1 do
+        assert_merge_pair(:a, nil, 2, nil) {}
+        assert_equal false, @cache.key?(:a)
+      end
+    end
+  end
+
+  def test_merge_pair_with_return
+    with_or_without_default_proc do
+      @cache[:a] = 1
+      assert_handles_return_lambda(:merge_pair, :a, 2)
+    end
+  end
+
+  def test_merge_pair_exception
+    with_or_without_default_proc do
+      @cache[:a] = 1
+      assert_handles_exception(:merge_pair, :a, 2)
+    end
+  end
+
+  def test_updates_dont_block_reads
+    getters_count = 20
+    key_klass     = ThreadSafe::Test::HashCollisionKey
+    keys          = [key_klass.new(1, 100), key_klass.new(2, 100), key_klass.new(3, 100)] # hash colliding keys
+    inserted_keys = []
+
+    keys.each do |key, i|
+      compute_started  = ThreadSafe::Test::Latch.new(1)
+      compute_finished = ThreadSafe::Test::Latch.new(1)
+      getters_started  = ThreadSafe::Test::Latch.new(getters_count)
+      getters_finished = ThreadSafe::Test::Latch.new(getters_count)
+
+      computer_thread = Thread.new do
+        getters_started.await
+        @cache.compute_if_absent(key) do
+          compute_started.release
+          getters_finished.await
+          1
+        end
+        compute_finished.release
+      end
+
+      getter_threads = (1..getters_count).map do
+        Thread.new do
+          getters_started.release
+          inserted_keys.each do |inserted_key|
+            assert_equal true, @cache.key?(inserted_key)
+            assert_equal 1,    @cache[inserted_key]
+          end
+          assert_equal false, @cache.key?(key)
+          compute_started.await
+          inserted_keys.each do |inserted_key|
+            assert_equal true, @cache.key?(inserted_key)
+            assert_equal 1,    @cache[inserted_key]
+          end
+          assert_equal false, @cache.key?(key)
+          assert_equal nil,   @cache[key]
+          getters_finished.release
+          compute_finished.await
+          assert_equal true,  @cache.key?(key)
+          assert_equal 1,     @cache[key]
+        end
+      end
+
+      (getter_threads << computer_thread).map {|t| assert(t.join(2))} # asserting no deadlocks
+      inserted_keys << key
+    end
+  end
+
+  def test_collision_resistance
+    assert_collision_resistance((0..1000).map {|i| ThreadSafe::Test::HashCollisionKey(i, 1)})
+  end
+
+  def test_collision_resistance_with_arrays
+    special_array_class = Class.new(Array) do
+      def key # assert_collision_resistance expects to be able to call .key to get the "real" key
+        first.key
+      end
+    end
+    # Test collision resistance with a keys that say they responds_to <=>, but then raise exceptions
+    # when actually called (ie: an Array filled with non-comparable keys).
+    # See https://github.com/headius/thread_safe/issues/19 for more info.
+    assert_collision_resistance((0..100).map do |i|
+      special_array_class.new([ThreadSafe::Test::HashCollisionKeyNonComparable.new(i, 1)])
+    end)
+  end
+
+  def test_replace_pair
+    with_or_without_default_proc do
+      assert_no_size_change do
+        assert_equal false, @cache.replace_pair(:a, 1, 2)
+        assert_equal false, @cache.replace_pair(:a, nil, nil)
+        assert_equal false, @cache.key?(:a)
+      end
+
+      @cache[:a] = 1
+      assert_no_size_change do
+        assert_equal true,  @cache.replace_pair(:a, 1, 2)
+        assert_equal false, @cache.replace_pair(:a, 1, 2)
+        assert_equal 2,     @cache[:a]
+        assert_equal true,  @cache.replace_pair(:a, 2, 2)
+        assert_equal 2,     @cache[:a]
+        assert_equal true,  @cache.replace_pair(:a, 2, nil)
+        assert_equal false, @cache.replace_pair(:a, 2, nil)
+        assert_equal nil,   @cache[:a]
+        assert_equal true,  @cache.key?(:a)
+        assert_equal true,  @cache.replace_pair(:a, nil, nil)
+        assert_equal true,  @cache.key?(:a)
+        assert_equal true,  @cache.replace_pair(:a, nil, 1)
+        assert_equal 1,     @cache[:a]
+      end
+    end
+  end
+
+  def test_replace_if_exists
+    with_or_without_default_proc do
+      assert_no_size_change do
+        assert_equal nil,   @cache.replace_if_exists(:a, 1)
+        assert_equal false, @cache.key?(:a)
+      end
+
+      @cache[:a] = 1
+      assert_no_size_change do
+        assert_equal 1,     @cache.replace_if_exists(:a, 2)
+        assert_equal 2,     @cache[:a]
+        assert_equal 2,     @cache.replace_if_exists(:a, nil)
+        assert_equal nil,   @cache[:a]
+        assert_equal true,  @cache.key?(:a)
+        assert_equal nil,   @cache.replace_if_exists(:a, 1)
+        assert_equal 1,     @cache[:a]
+      end
+    end
+  end
+
+  def test_get_and_set
+    with_or_without_default_proc do
+      assert_size_change 1 do
+        assert_equal nil,   @cache.get_and_set(:a, 1)
+        assert_equal true,  @cache.key?(:a)
+        assert_equal 1,     @cache[:a]
+        assert_equal 1,     @cache.get_and_set(:a, 2)
+        assert_equal 2,     @cache.get_and_set(:a, nil)
+        assert_equal nil,   @cache[:a]
+        assert_equal true,  @cache.key?(:a)
+        assert_equal nil,   @cache.get_and_set(:a, 1)
+        assert_equal 1,     @cache[:a]
+      end
+    end
+  end
+
+  def test_key
+    with_or_without_default_proc do
+      assert_equal nil, @cache.key(1)
+      @cache[:a] = 1
+      assert_equal :a,  @cache.key(1)
+      assert_equal nil,  @cache.key(0)
+      assert_equal :a,  @cache.index(1) if RUBY_VERSION =~ /1\.8/
+    end
+  end
+
+  def test_key?
+    with_or_without_default_proc do
+      assert_equal false, @cache.key?(:a)
+      @cache[:a] = 1
+      assert_equal true,  @cache.key?(:a)
+    end
+  end
+
+  def test_value?
+    with_or_without_default_proc do
+      assert_equal false, @cache.value?(1)
+      @cache[:a] = 1
+      assert_equal true,  @cache.value?(1)
+    end
+  end
+
+  def test_delete
+    with_or_without_default_proc do |default_proc_set|
+      assert_no_size_change do
+        assert_equal nil,   @cache.delete(:a)
+      end
+      @cache[:a] = 1
+      assert_size_change -1 do
+        assert_equal 1,     @cache.delete(:a)
+      end
+      assert_no_size_change do
+        assert_equal nil, @cache[:a] unless default_proc_set
+
+        assert_equal false, @cache.key?(:a)
+        assert_equal nil,   @cache.delete(:a)
+      end
+    end
+  end
+
+  def test_delete_pair
+    with_or_without_default_proc do
+      assert_no_size_change do
+        assert_equal false, @cache.delete_pair(:a, 2)
+        assert_equal false, @cache.delete_pair(:a, nil)
+      end
+      @cache[:a] = 1
+      assert_no_size_change do
+        assert_equal false, @cache.delete_pair(:a, 2)
+      end
+      assert_size_change -1 do
+        assert_equal 1,     @cache[:a]
+        assert_equal true,  @cache.delete_pair(:a, 1)
+        assert_equal false, @cache.delete_pair(:a, 1)
+        assert_equal false, @cache.key?(:a)
+      end
+    end
+  end
+
+  def test_default_proc
+    @cache = cache_with_default_proc(1)
+    assert_no_size_change do
+      assert_equal false, @cache.key?(:a)
+    end
+    assert_size_change 1 do
+      assert_equal 1,     @cache[:a]
+      assert_equal true,  @cache.key?(:a)
+    end
+  end
+
+  def test_falsy_default_proc
+    @cache = cache_with_default_proc(nil)
+    assert_no_size_change do
+      assert_equal false, @cache.key?(:a)
+    end
+    assert_size_change 1 do
+      assert_equal nil,   @cache[:a]
+      assert_equal true,  @cache.key?(:a)
+    end
+  end
+
+  def test_fetch
+    with_or_without_default_proc do |default_proc_set|
+      assert_no_size_change do
+        assert_equal 1,      @cache.fetch(:a, 1)
+        assert_equal(1,     (@cache.fetch(:a) {1}))
+        assert_equal false,  @cache.key?(:a)
+
+        assert_equal nil, @cache[:a] unless default_proc_set
+      end
+
+      @cache[:a] = 1
+      assert_no_size_change do
+        assert_equal(1, (@cache.fetch(:a) {flunk}))
+      end
+
+      assert_raises(ThreadSafe::Cache::KEY_ERROR) do
+        @cache.fetch(:b)
+      end
+
+      assert_no_size_change do
+        assert_equal 1,     (@cache.fetch(:b, :c) {1}) # assert block supersedes default value argument
+        assert_equal false,  @cache.key?(:b)
+      end
+    end
+  end
+
+  def test_falsy_fetch
+    with_or_without_default_proc do
+      assert_equal false, @cache.key?(:a)
+
+      assert_no_size_change do
+        assert_equal(nil,    @cache.fetch(:a, nil))
+        assert_equal(false,  @cache.fetch(:a, false))
+        assert_equal(nil,   (@cache.fetch(:a) {}))
+        assert_equal(false, (@cache.fetch(:a) {false}))
+      end
+
+      @cache[:a] = nil
+      assert_no_size_change do
+        assert_equal true, @cache.key?(:a)
+        assert_equal(nil, (@cache.fetch(:a) {flunk}))
+      end
+    end
+  end
+
+  def test_fetch_with_return
+    with_or_without_default_proc do
+      r = lambda do
+        @cache.fetch(:a) { return 10 }
+      end.call
+
+      assert_no_size_change do
+        assert_equal 10,    r
+        assert_equal false, @cache.key?(:a)
+      end
+    end
+  end
+
+  def test_fetch_or_store
+    with_or_without_default_proc do |default_proc_set|
+      assert_size_change 1 do
+        assert_equal 1, @cache.fetch_or_store(:a, 1)
+        assert_equal 1, @cache[:a]
+      end
+
+      @cache.delete(:a)
+
+      assert_size_change 1 do
+        assert_equal 1, (@cache.fetch_or_store(:a) {1})
+        assert_equal 1,  @cache[:a]
+      end
+
+      assert_no_size_change do
+        assert_equal(1, (@cache.fetch_or_store(:a) {flunk}))
+      end
+
+      assert_raises(ThreadSafe::Cache::KEY_ERROR) do
+        @cache.fetch_or_store(:b)
+      end
+
+      assert_size_change 1 do
+        assert_equal 1, (@cache.fetch_or_store(:b, :c) {1}) # assert block supersedes default value argument
+        assert_equal 1,  @cache[:b]
+      end
+    end
+  end
+
+  def test_falsy_fetch_or_store
+    with_or_without_default_proc do
+      assert_equal false, @cache.key?(:a)
+
+      assert_size_change 1 do
+        assert_equal(nil,  @cache.fetch_or_store(:a, nil))
+        assert_equal nil,  @cache[:a]
+        assert_equal true, @cache.key?(:a)
+      end
+      @cache.delete(:a)
+
+      assert_size_change 1 do
+        assert_equal(false, @cache.fetch_or_store(:a, false))
+        assert_equal false, @cache[:a]
+        assert_equal true,  @cache.key?(:a)
+      end
+      @cache.delete(:a)
+
+      assert_size_change 1 do
+        assert_equal(nil, (@cache.fetch_or_store(:a) {}))
+        assert_equal nil,  @cache[:a]
+        assert_equal true, @cache.key?(:a)
+      end
+      @cache.delete(:a)
+
+      assert_size_change 1 do
+        assert_equal(false, (@cache.fetch_or_store(:a) {false}))
+        assert_equal false,  @cache[:a]
+        assert_equal true,   @cache.key?(:a)
+      end
+
+      @cache[:a] = nil
+      assert_no_size_change do
+        assert_equal(nil, (@cache.fetch_or_store(:a) {flunk}))
+      end
+    end
+  end
+
+  def test_fetch_or_store_with_return
+    with_or_without_default_proc do
+      r = lambda do
+        @cache.fetch_or_store(:a) { return 10 }
+      end.call
+
+      assert_no_size_change do
+        assert_equal 10,    r
+        assert_equal false, @cache.key?(:a)
+      end
+    end
+  end
+
+  def test_clear
+    @cache[:a] = 1
+    assert_size_change -1 do
+      assert_equal @cache, @cache.clear
+      assert_equal false,  @cache.key?(:a)
+      assert_equal nil,    @cache[:a]
+    end
+  end
+
+  def test_each_pair
+    @cache.each_pair {|k, v| flunk}
+    assert_equal(@cache, (@cache.each_pair {}))
+    @cache[:a] = 1
+
+    h = {}
+    @cache.each_pair {|k, v| h[k] = v}
+    assert_equal({:a => 1}, h)
+
+    @cache[:b] = 2
+    h = {}
+    @cache.each_pair {|k, v| h[k] = v}
+    assert_equal({:a => 1, :b => 2}, h)
+  end
+
+  def test_each_pair_iterator
+    @cache[:a] = 1
+    @cache[:b] = 2
+    i = 0
+    r = @cache.each_pair do |k, v|
+      if i == 0
+        i += 1
+        next
+        flunk
+      elsif i == 1
+        break :breaked
+      end
+    end
+
+    assert_equal :breaked, r
+  end
+
+  def test_each_pair_allows_modification
+    @cache[:a] = 1
+    @cache[:b] = 1
+    @cache[:c] = 1
+
+    assert_size_change 1 do
+      @cache.each_pair do |k, v|
+        @cache[:z] = 1
+      end
+    end
+  end
+
+  def test_keys
+    assert_equal [], @cache.keys
+
+    @cache[1] = 1
+    assert_equal [1], @cache.keys
+
+    @cache[2] = 2
+    assert_equal [1, 2], @cache.keys.sort
+  end
+
+  def test_values
+    assert_equal [], @cache.values
+
+    @cache[1] = 1
+    assert_equal [1], @cache.values
+
+    @cache[2] = 2
+    assert_equal [1, 2], @cache.values.sort
+  end
+
+  def test_each_key
+    assert_equal(@cache, (@cache.each_key {flunk}))
+
+    @cache[1] = 1
+    arr = []
+    @cache.each_key {|k| arr << k}
+    assert_equal [1], arr
+
+    @cache[2] = 2
+    arr = []
+    @cache.each_key {|k| arr << k}
+    assert_equal [1, 2], arr.sort
+  end
+
+  def test_each_value
+    assert_equal(@cache, (@cache.each_value {flunk}))
+
+    @cache[1] = 1
+    arr = []
+    @cache.each_value {|k| arr << k}
+    assert_equal [1], arr
+
+    @cache[2] = 2
+    arr = []
+    @cache.each_value {|k| arr << k}
+    assert_equal [1, 2], arr.sort
+  end
+
+  def test_empty
+    assert_equal true,  @cache.empty?
+    @cache[:a] = 1
+    assert_equal false, @cache.empty?
+  end
+
+  def test_options_validation
+    assert_valid_options(nil)
+    assert_valid_options({})
+    assert_valid_options(:foo => :bar)
+  end
+
+  def test_initial_capacity_options_validation
+    assert_valid_option(:initial_capacity, nil)
+    assert_valid_option(:initial_capacity, 1)
+    assert_invalid_option(:initial_capacity, '')
+    assert_invalid_option(:initial_capacity, 1.0)
+    assert_invalid_option(:initial_capacity, -1)
+  end
+
+  def test_load_factor_options_validation
+    assert_valid_option(:load_factor, nil)
+    assert_valid_option(:load_factor, 0.01)
+    assert_valid_option(:load_factor, 0.75)
+    assert_valid_option(:load_factor, 1)
+    assert_invalid_option(:load_factor, '')
+    assert_invalid_option(:load_factor, 0)
+    assert_invalid_option(:load_factor, 1.1)
+    assert_invalid_option(:load_factor, 2)
+    assert_invalid_option(:load_factor, -1)
+  end
+
+  def test_size
+    assert_equal 0, @cache.size
+    @cache[:a] = 1
+    assert_equal 1, @cache.size
+    @cache[:b] = 1
+    assert_equal 2, @cache.size
+    @cache.delete(:a)
+    assert_equal 1, @cache.size
+    @cache.delete(:b)
+    assert_equal 0, @cache.size
+  end
+
+  def test_get_or_default
+    with_or_without_default_proc do
+      assert_equal 1,     @cache.get_or_default(:a, 1)
+      assert_equal nil,   @cache.get_or_default(:a, nil)
+      assert_equal false, @cache.get_or_default(:a, false)
+      assert_equal false, @cache.key?(:a)
+
+      @cache[:a] = 1
+      assert_equal 1, @cache.get_or_default(:a, 2)
+    end
+  end
+
+  def test_dup_clone
+    [:dup, :clone].each do |meth|
+      cache = cache_with_default_proc(:default_value)
+      cache[:a] = 1
+      dupped = cache.send(meth)
+      assert_equal 1, dupped[:a]
+      assert_equal 1, dupped.size
+      assert_size_change 1, cache do
+        assert_no_size_change dupped do
+          cache[:b] = 1
+        end
+      end
+      assert_equal false, dupped.key?(:b)
+      assert_no_size_change cache do
+        assert_size_change -1, dupped do
+          dupped.delete(:a)
+        end
+      end
+      assert_equal false, dupped.key?(:a)
+      assert_equal true,  cache.key?(:a)
+      # test default proc
+      assert_size_change 1, cache do
+        assert_no_size_change dupped do
+          assert_equal :default_value, cache[:c]
+          assert_equal false,          dupped.key?(:c)
+        end
+      end
+      assert_no_size_change cache do
+        assert_size_change 1, dupped do
+          assert_equal :default_value, dupped[:d]
+          assert_equal false,          cache.key?(:d)
+        end
+      end
+    end
+  end
+
+  def test_is_unfreezable
+    assert_raises(NoMethodError) { @cache.freeze }
+  end
+
+  def test_marshal_dump_load
+    new_cache = Marshal.load(Marshal.dump(@cache))
+    assert_instance_of ThreadSafe::Cache, new_cache
+    assert_equal 0, new_cache.size
+    @cache[:a] = 1
+    new_cache = Marshal.load(Marshal.dump(@cache))
+    assert_equal 1, @cache[:a]
+    assert_equal 1, new_cache.size
+  end
+
+  def test_marshal_dump_doesnt_work_with_default_proc
+    assert_raises(TypeError) do
+      Marshal.dump(ThreadSafe::Cache.new {})
+    end
+  end
+
+  private
+  def with_or_without_default_proc
+    yield false
+    @cache = ThreadSafe::Cache.new {|h, k| h[k] = :default_value}
+    yield true
+  end
+
+  def cache_with_default_proc(default_value = 1)
+    ThreadSafe::Cache.new {|cache, k| cache[k] = default_value}
+  end
+
+  def assert_valid_option(option_name, value)
+    assert_valid_options(option_name => value)
+  end
+
+  def assert_valid_options(options)
+    c = ThreadSafe::Cache.new(options)
+    assert_instance_of ThreadSafe::Cache, c
+  end
+
+  def assert_invalid_option(option_name, value)
+    assert_invalid_options(option_name => value)
+  end
+
+  def assert_invalid_options(options)
+    assert_raises(ArgumentError) { ThreadSafe::Cache.new(options) }
+  end
+
+  def assert_size_change(change, cache = @cache)
+    start = cache.size
+    yield
+    assert_equal change, cache.size - start
+  end
+
+  def assert_no_size_change(cache = @cache, &block)
+    assert_size_change(0, cache, &block)
+  end
+
+  def assert_handles_return_lambda(method, key, *args)
+    before_had_key   = @cache.key?(key)
+    before_had_value = before_had_key ? @cache[key] : nil
+
+    returning_lambda = lambda do
+      @cache.send(method, key, *args) { return :direct_return }
+    end
+
+    assert_no_size_change do
+      assert_equal(:direct_return,   returning_lambda.call)
+      assert_equal before_had_key,   @cache.key?(key)
+      assert_equal before_had_value, @cache[key] if before_had_value
+    end
+  end
+
+  class TestException < Exception; end
+  def assert_handles_exception(method, key, *args)
+    before_had_key   = @cache.key?(key)
+    before_had_value = before_had_key ? @cache[key] : nil
+
+    assert_no_size_change do
+      assert_raises(TestException) do
+        @cache.send(method, key, *args) { raise TestException, '' }
+      end
+      assert_equal before_had_key,   @cache.key?(key)
+      assert_equal before_had_value, @cache[key] if before_had_value
+    end
+  end
+
+  def assert_compute(key, expected_old_value, expected_result)
+    result = @cache.compute(:a) do |old_value|
+      assert_equal expected_old_value, old_value
+      yield
+    end
+    assert_equal expected_result, result
+  end
+
+  def assert_merge_pair(key, value, expected_old_value, expected_result)
+    result = @cache.merge_pair(key, value) do |old_value|
+      assert_equal expected_old_value, old_value
+      yield
+    end
+    assert_equal expected_result, result
+  end
+
+  def assert_collision_resistance(keys)
+    keys.each {|k| @cache[k] = k.key}
+    10.times do |i|
+      size = keys.size
+      while i < size
+        k = keys[i]
+        assert(k.key == @cache.delete(k) && !@cache.key?(k) && (@cache[k] = k.key; @cache[k] == k.key))
+        i += 10
+      end
+    end
+    assert(keys.all? {|k| @cache[k] == k.key})
+  end
+end
diff --git a/app/server/vendor/thread_safe/test/test_cache_loops.rb b/app/server/vendor/thread_safe/test/test_cache_loops.rb
new file mode 100644
index 0000000..e3a92ed
--- /dev/null
+++ b/app/server/vendor/thread_safe/test/test_cache_loops.rb
@@ -0,0 +1,449 @@
+require 'thread'
+require 'thread_safe'
+require File.join(File.dirname(__FILE__), "test_helper")
+
+Thread.abort_on_exception = true
+
+class TestCacheTorture < Minitest::Test # this is not run unless RUBY_VERSION =~ /1\.8/ || ENV['TRAVIS'] (see the end of the file)
+  THREAD_COUNT  = 40
+  KEY_COUNT     = (((2**13) - 2) * 0.75).to_i # get close to the doubling cliff
+  LOW_KEY_COUNT = (((2**8 ) - 2) * 0.75).to_i # get close to the doubling cliff
+
+  INITIAL_VALUE_CACHE_SETUP = lambda do |options, keys|
+    cache         = ThreadSafe::Cache.new
+    initial_value = options[:initial_value] || 0
+    keys.each {|key| cache[key] = initial_value}
+    cache
+  end
+  ZERO_VALUE_CACHE_SETUP = lambda do |options, keys|
+    INITIAL_VALUE_CACHE_SETUP.call(options.merge(:initial_value => 0), keys)
+  end
+
+  DEFAULTS = {
+    :key_count    => KEY_COUNT,
+    :thread_count => THREAD_COUNT,
+    :loop_count   => 1,
+    :prelude      => '',
+    :cache_setup  => lambda {|options, keys| ThreadSafe::Cache.new}
+  }
+
+  LOW_KEY_COUNT_OPTIONS    = {:loop_count => 150,     :key_count => LOW_KEY_COUNT}
+  SINGLE_KEY_COUNT_OPTIONS = {:loop_count => 100_000, :key_count => 1}
+
+  def test_concurrency
+    code = <<-RUBY_EVAL
+      cache[key]
+      cache[key] = key
+      cache[key]
+      cache.delete(key)
+    RUBY_EVAL
+    do_thread_loop(__method__, code)
+  end
+
+  def test_put_if_absent
+    do_thread_loop(__method__, 'acc += 1 unless cache.put_if_absent(key, key)', :key_count => 100_000) do |result, cache, options, keys|
+      assert_standard_accumulator_test_result(result, cache, options, keys)
+    end
+  end
+
+  def test_compute_if_absent
+    code = 'cache.compute_if_absent(key) { acc += 1; key }'
+    do_thread_loop(__method__, code) do |result, cache, options, keys|
+      assert_standard_accumulator_test_result(result, cache, options, keys)
+    end
+  end
+
+  def test_compute_put_if_absent
+    code = <<-RUBY_EVAL
+      if key.even?
+        cache.compute_if_absent(key) { acc += 1; key }
+      else
+        acc += 1 unless cache.put_if_absent(key, key)
+      end
+    RUBY_EVAL
+    do_thread_loop(__method__, code) do |result, cache, options, keys|
+      assert_standard_accumulator_test_result(result, cache, options, keys)
+    end
+  end
+
+  def test_compute_if_absent_and_present
+    compute_if_absent_and_present
+    compute_if_absent_and_present(LOW_KEY_COUNT_OPTIONS)
+    compute_if_absent_and_present(SINGLE_KEY_COUNT_OPTIONS)
+  end
+
+  def test_add_remove_to_zero
+    add_remove_to_zero
+    add_remove_to_zero(LOW_KEY_COUNT_OPTIONS)
+    add_remove_to_zero(SINGLE_KEY_COUNT_OPTIONS)
+  end
+
+  def test_add_remove_to_zero_via_merge_pair
+    add_remove_to_zero_via_merge_pair
+    add_remove_to_zero_via_merge_pair(LOW_KEY_COUNT_OPTIONS)
+    add_remove_to_zero_via_merge_pair(SINGLE_KEY_COUNT_OPTIONS)
+  end
+
+  def test_add_remove
+    add_remove
+    add_remove(LOW_KEY_COUNT_OPTIONS)
+    add_remove(SINGLE_KEY_COUNT_OPTIONS)
+  end
+
+  def test_add_remove_via_compute
+    add_remove_via_compute
+    add_remove_via_compute(LOW_KEY_COUNT_OPTIONS)
+    add_remove_via_compute(SINGLE_KEY_COUNT_OPTIONS)
+  end
+
+  def add_remove_via_compute_if_absent_present
+    add_remove_via_compute_if_absent_present
+    add_remove_via_compute_if_absent_present(LOW_KEY_COUNT_OPTIONS)
+    add_remove_via_compute_if_absent_present(SINGLE_KEY_COUNT_OPTIONS)
+  end
+
+  def test_add_remove_indiscriminate
+    add_remove_indiscriminate
+    add_remove_indiscriminate(LOW_KEY_COUNT_OPTIONS)
+    add_remove_indiscriminate(SINGLE_KEY_COUNT_OPTIONS)
+  end
+
+  def test_count_up
+    count_up
+    count_up(LOW_KEY_COUNT_OPTIONS)
+    count_up(SINGLE_KEY_COUNT_OPTIONS)
+  end
+
+  def test_count_up_via_compute
+    count_up_via_compute
+    count_up_via_compute(LOW_KEY_COUNT_OPTIONS)
+    count_up_via_compute(SINGLE_KEY_COUNT_OPTIONS)
+  end
+
+  def test_count_up_via_merge_pair
+    count_up_via_merge_pair
+    count_up_via_merge_pair(LOW_KEY_COUNT_OPTIONS)
+    count_up_via_merge_pair(SINGLE_KEY_COUNT_OPTIONS)
+  end
+
+  def test_count_race
+    prelude = 'change = (rand(2) == 1) ? 1 : -1'
+    code = <<-RUBY_EVAL
+      v = cache[key]
+      acc += change if cache.replace_pair(key, v, v + change)
+    RUBY_EVAL
+    do_thread_loop(__method__, code, :loop_count => 5, :prelude => prelude, :cache_setup => ZERO_VALUE_CACHE_SETUP) do |result, cache, options, keys|
+      result_sum = sum(result)
+      assert_equal(sum(keys.map {|key| cache[key]}), result_sum)
+      assert_equal(sum(cache.values), result_sum)
+      assert_equal(options[:key_count], cache.size)
+    end
+  end
+
+  def test_get_and_set_new
+    code = 'acc += 1 unless cache.get_and_set(key, key)'
+    do_thread_loop(__method__, code) do |result, cache, options, keys|
+      assert_standard_accumulator_test_result(result, cache, options, keys)
+    end
+  end
+
+  def test_get_and_set_existing
+    code = 'acc += 1 if cache.get_and_set(key, key) == -1'
+    do_thread_loop(__method__, code, :cache_setup => INITIAL_VALUE_CACHE_SETUP, :initial_value => -1) do |result, cache, options, keys|
+      assert_standard_accumulator_test_result(result, cache, options, keys)
+    end
+  end
+
+  private
+  def compute_if_absent_and_present(opts = {})
+    prelude = 'on_present = rand(2) == 1'
+    code = <<-RUBY_EVAL
+      if on_present
+        cache.compute_if_present(key) {|old_value| acc += 1; old_value + 1}
+      else
+        cache.compute_if_absent(key)  { acc += 1; 1 }
+      end
+    RUBY_EVAL
+    do_thread_loop(__method__, code, {:loop_count => 5, :prelude => prelude}.merge(opts)) do |result, cache, options, keys|
+      stored_sum       = 0
+      stored_key_count = 0
+      keys.each do |k|
+        if value = cache[k]
+          stored_sum += value
+          stored_key_count += 1
+        end
+      end
+      assert_equal(stored_sum, sum(result))
+      assert_equal(stored_key_count, cache.size)
+    end
+  end
+
+  def add_remove(opts = {})
+    prelude = 'do_add = rand(2) == 1'
+    code = <<-RUBY_EVAL
+      if do_add
+        acc += 1 unless cache.put_if_absent(key, key)
+      else
+        acc -= 1 if cache.delete_pair(key, key)
+      end
+    RUBY_EVAL
+    do_thread_loop(__method__, code, {:loop_count => 5, :prelude => prelude}.merge(opts)) do |result, cache, options, keys|
+      assert_all_key_mappings_exist(cache, keys, false)
+      assert_equal(cache.size, sum(result))
+    end
+  end
+
+  def add_remove_via_compute(opts = {})
+    prelude = 'do_add = rand(2) == 1'
+    code = <<-RUBY_EVAL
+      cache.compute(key) do |old_value|
+        if do_add
+          acc += 1 unless old_value
+          key
+        else
+          acc -= 1 if old_value
+          nil
+        end
+      end
+    RUBY_EVAL
+    do_thread_loop(__method__, code, {:loop_count => 5, :prelude => prelude}.merge(opts)) do |result, cache, options, keys|
+      assert_all_key_mappings_exist(cache, keys, false)
+      assert_equal(cache.size, sum(result))
+    end
+  end
+
+  def add_remove_via_compute_if_absent_present(opts = {})
+    prelude = 'do_add = rand(2) == 1'
+    code = <<-RUBY_EVAL
+      if do_add
+        cache.compute_if_absent(key)  { acc += 1; key }
+      else
+        cache.compute_if_present(key) { acc -= 1; nil }
+      end
+    RUBY_EVAL
+    do_thread_loop(__method__, code, {:loop_count => 5, :prelude => prelude}.merge(opts)) do |result, cache, options, keys|
+      assert_all_key_mappings_exist(cache, keys, false)
+      assert_equal(cache.size, sum(result))
+    end
+  end
+
+  def add_remove_indiscriminate(opts = {})
+    prelude = 'do_add = rand(2) == 1'
+    code = <<-RUBY_EVAL
+      if do_add
+        acc += 1 unless cache.put_if_absent(key, key)
+      else
+        acc -= 1 if cache.delete(key)
+      end
+    RUBY_EVAL
+    do_thread_loop(__method__, code, {:loop_count => 5, :prelude => prelude}.merge(opts)) do |result, cache, options, keys|
+      assert_all_key_mappings_exist(cache, keys, false)
+      assert_equal(cache.size, sum(result))
+    end
+  end
+
+  def count_up(opts = {})
+    code = <<-RUBY_EVAL
+      v = cache[key]
+      acc += 1 if cache.replace_pair(key, v, v + 1)
+    RUBY_EVAL
+    do_thread_loop(__method__, code, {:loop_count => 5, :cache_setup => ZERO_VALUE_CACHE_SETUP}.merge(opts)) do |result, cache, options, keys|
+      assert_count_up(result, cache, options, keys)
+    end
+  end
+
+  def count_up_via_compute(opts = {})
+    code = <<-RUBY_EVAL
+      cache.compute(key) do |old_value|
+        acc += 1
+        old_value ? old_value + 1 : 1
+      end
+    RUBY_EVAL
+    do_thread_loop(__method__, code, {:loop_count => 5}.merge(opts)) do |result, cache, options, keys|
+      assert_count_up(result, cache, options, keys)
+      result.inject(nil) do |previous_value, next_value| # since compute guarantees atomicity all count ups should be equal
+        assert_equal previous_value, next_value if previous_value
+        next_value
+      end
+    end
+  end
+
+  def count_up_via_merge_pair(opts = {})
+    code = <<-RUBY_EVAL
+      cache.merge_pair(key, 1) {|old_value| old_value + 1}
+    RUBY_EVAL
+    do_thread_loop(__method__, code, {:loop_count => 5}.merge(opts)) do |result, cache, options, keys|
+      all_match      = true
+      expected_value = options[:loop_count] * options[:thread_count]
+      keys.each do |key|
+        if expected_value != (value = cache[key])
+          all_match = false
+          break
+        end
+      end
+      assert all_match
+    end
+  end
+
+  def add_remove_to_zero(opts = {})
+    code = <<-RUBY_EVAL
+      acc += 1 unless cache.put_if_absent(key, key)
+      acc -= 1 if cache.delete_pair(key, key)
+    RUBY_EVAL
+    do_thread_loop(__method__, code, {:loop_count => 5}.merge(opts)) do |result, cache, options, keys|
+      assert_all_key_mappings_exist(cache, keys, false)
+      assert_equal(cache.size, sum(result))
+    end
+  end
+
+  def add_remove_to_zero_via_merge_pair(opts = {})
+    code = <<-RUBY_EVAL
+      acc += (cache.merge_pair(key, key) {}) ? 1 : -1
+    RUBY_EVAL
+    do_thread_loop(__method__, code, {:loop_count => 5}.merge(opts)) do |result, cache, options, keys|
+      assert_all_key_mappings_exist(cache, keys, false)
+      assert_equal(cache.size, sum(result))
+    end
+  end
+
+  def do_thread_loop(name, code, options = {}, &block)
+    options = DEFAULTS.merge(options)
+    meth    = define_loop name, code, options[:prelude]
+    keys = to_keys_array(options[:key_count])
+    run_thread_loop(meth, keys, options, &block)
+
+    if options[:key_count] > 1
+      options[:key_count] = (options[:key_count] / 40).to_i
+      keys = to_hash_collision_keys_array(options[:key_count])
+      run_thread_loop(meth, keys, options.merge(:loop_count => (options[:loop_count] * 5)), &block)
+    end
+  end
+
+  def run_thread_loop(meth, keys, options)
+    cache   = options[:cache_setup].call(options, keys)
+    barrier = ThreadSafe::Test::Barrier.new(options[:thread_count])
+    result = (1..options[:thread_count]).map do
+      Thread.new do
+        setup_sync_and_start_loop(meth, cache, keys, barrier, options[:loop_count])
+      end
+    end.map(&:value)
+    yield result, cache, options, keys if block_given?
+  end
+
+  def setup_sync_and_start_loop(meth, cache, keys, barrier, loop_count)
+    my_keys = keys.shuffle
+    barrier.await
+    if my_keys.size == 1
+      key = my_keys.first
+      send("#{meth}_single_key", cache, key, loop_count)
+    else
+      send("#{meth}_multiple_keys", cache, my_keys, loop_count)
+    end
+  end
+
+  def define_loop(name, body, prelude)
+    inner_meth_name = :"_#{name}_loop_inner"
+    outer_meth_name = :"_#{name}_loop_outer"
+    # looping is splitted into the "loop methods" to trigger the JIT
+    self.class.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
+      def #{inner_meth_name}_multiple_keys(cache, keys, i, length, acc)
+        #{prelude}
+        target = i + length
+        while i < target
+          key = keys[i]
+          #{body}
+          i += 1
+        end
+        acc
+      end unless method_defined?(:#{inner_meth_name}_multiple_keys)
+    RUBY_EVAL
+
+    self.class.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
+      def #{inner_meth_name}_single_key(cache, key, i, length, acc)
+        #{prelude}
+        target = i + length
+        while i < target
+          #{body}
+          i += 1
+        end
+        acc
+      end unless method_defined?(:#{inner_meth_name}_single_key)
+    RUBY_EVAL
+
+    self.class.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
+      def #{outer_meth_name}_multiple_keys(cache, keys, loop_count)
+        total_length = keys.size
+        acc = 0
+        inc = 100
+        loop_count.times do
+          i = 0
+          pre_loop_inc = total_length % inc
+          acc = #{inner_meth_name}_multiple_keys(cache, keys, i, pre_loop_inc, acc)
+          i += pre_loop_inc
+          while i < total_length
+            acc = #{inner_meth_name}_multiple_keys(cache, keys, i, inc, acc)
+            i += inc
+          end
+        end
+        acc
+      end unless method_defined?(:#{outer_meth_name}_multiple_keys)
+    RUBY_EVAL
+
+    self.class.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
+      def #{outer_meth_name}_single_key(cache, key, loop_count)
+        acc = 0
+        i   = 0
+        inc = 100
+
+        pre_loop_inc = loop_count % inc
+        acc          = #{inner_meth_name}_single_key(cache, key, i, pre_loop_inc, acc)
+        i += pre_loop_inc
+
+        while i < loop_count
+          acc = #{inner_meth_name}_single_key(cache, key, i, inc, acc)
+          i += inc
+        end
+        acc
+      end unless method_defined?(:#{outer_meth_name}_single_key)
+    RUBY_EVAL
+    outer_meth_name
+  end
+
+  def to_keys_array(key_count)
+    arr = []
+    key_count.times {|i| arr << i}
+    arr
+  end
+
+  def to_hash_collision_keys_array(key_count)
+    to_keys_array(key_count).map {|key| ThreadSafe::Test::HashCollisionKey(key)}
+  end
+
+  def sum(result)
+    result.inject(0) {|acc, i| acc + i}
+  end
+
+  def assert_standard_accumulator_test_result(result, cache, options, keys)
+    assert_all_key_mappings_exist(cache, keys)
+    assert_equal(options[:key_count], sum(result))
+    assert_equal(options[:key_count], cache.size)
+  end
+
+  def assert_all_key_mappings_exist(cache, keys, all_must_exist = true)
+    keys.each do |key|
+      if (value = cache[key]) || all_must_exist
+        assert_equal key, value unless key == value # don't do a bazzilion assertions unless necessary
+      end
+    end
+  end
+
+  def assert_count_up(result, cache, options, keys)
+    keys.each do |key|
+      unless value = cache[key]
+        assert value
+      end
+    end
+    assert_equal(sum(cache.values), sum(result))
+    assert_equal(options[:key_count], cache.size)
+  end
+end unless RUBY_VERSION =~ /1\.8/ || ENV['TRAVIS']
diff --git a/app/server/vendor/thread_safe/test/test_hash.rb b/app/server/vendor/thread_safe/test/test_hash.rb
new file mode 100644
index 0000000..12f4975
--- /dev/null
+++ b/app/server/vendor/thread_safe/test/test_hash.rb
@@ -0,0 +1,17 @@
+require 'thread_safe'
+require File.join(File.dirname(__FILE__), "test_helper")
+
+class TestHash < Minitest::Test
+  def test_concurrency
+    hsh = ThreadSafe::Hash.new
+    (1..100).map do |i|
+      Thread.new do
+        1000.times do |j|
+          hsh[i*1000+j] = i
+          hsh[i*1000+j]
+          hsh.delete(i*1000+j)
+        end
+      end
+    end.map(&:join)
+  end
+end
diff --git a/app/server/vendor/thread_safe/test/test_helper.rb b/app/server/vendor/thread_safe/test/test_helper.rb
new file mode 100644
index 0000000..9e49ad4
--- /dev/null
+++ b/app/server/vendor/thread_safe/test/test_helper.rb
@@ -0,0 +1,113 @@
+require 'thread'
+require 'rubygems'
+gem 'minitest', '>= 4'
+require 'minitest/autorun'
+
+if Minitest.const_defined?('Test')
+  # We're on Minitest 5+. Nothing to do here.
+else
+  # Minitest 4 doesn't have Minitest::Test yet.
+  Minitest::Test = MiniTest::Unit::TestCase
+end
+
+if defined?(JRUBY_VERSION) && ENV['TEST_NO_UNSAFE']
+  # to be used like this: rake test TEST_NO_UNSAFE=true
+  load 'test/package.jar'
+  java_import 'thread_safe.SecurityManager'
+  manager = SecurityManager.new
+
+  # Prevent accessing internal classes
+  manager.deny java.lang.RuntimePermission.new("accessClassInPackage.sun.misc")
+  java.lang.System.setSecurityManager manager
+
+  class TestNoUnsafe < Minitest::Test
+    def test_security_manager_is_used
+      begin
+        java_import 'sun.misc.Unsafe'
+        flunk
+      rescue SecurityError
+      end
+    end
+
+    def test_no_unsafe_version_of_chmv8_is_used
+      require 'thread_safe/jruby_cache_backend' # make sure the jar has been loaded
+      assert !Java::OrgJrubyExtThread_safe::JRubyCacheBackendLibrary::JRubyCacheBackend::CAN_USE_UNSAFE_CHM
+    end
+  end
+end
+
+module ThreadSafe
+  module Test
+    class Latch
+      def initialize(count = 1)
+        @count = count
+        @mutex = Mutex.new
+        @cond  = ConditionVariable.new
+      end
+
+      def release
+        @mutex.synchronize do
+          @count -= 1 if @count > 0
+          @cond.broadcast if @count.zero?
+        end
+      end
+
+      def await
+        @mutex.synchronize do
+          @cond.wait @mutex if @count > 0
+        end
+      end
+    end
+
+    class Barrier < Latch
+      def await
+        @mutex.synchronize do
+          if @count.zero? # fall through
+          elsif @count > 0
+            @count -= 1
+            @count.zero? ? @cond.broadcast : @cond.wait(@mutex)
+          end
+        end
+      end
+    end
+
+    class HashCollisionKey
+      attr_reader :hash, :key
+      def initialize(key, hash = key.hash % 3)
+        @key  = key
+        @hash = hash
+      end
+
+      def eql?(other)
+        other.kind_of?(self.class) && @key.eql?(other.key)
+      end
+
+      def even?
+        @key.even?
+      end
+
+      def <=>(other)
+        @key <=> other.key
+      end
+    end
+
+    # having 4 separate HCK classes helps for a more thorough CHMV8 testing
+    class HashCollisionKey2 < HashCollisionKey; end
+    class HashCollisionKeyNoCompare < HashCollisionKey
+      def <=>(other)
+        0
+      end
+    end
+    class HashCollisionKey4 < HashCollisionKeyNoCompare; end
+
+    HASH_COLLISION_CLASSES = [HashCollisionKey, HashCollisionKey2, HashCollisionKeyNoCompare, HashCollisionKey4]
+
+    def self.HashCollisionKey(key, hash = key.hash % 3)
+      HASH_COLLISION_CLASSES[rand(4)].new(key, hash)
+    end
+
+    class HashCollisionKeyNonComparable < HashCollisionKey
+      undef <=>
+    end
+  end
+end
diff --git a/app/server/vendor/thread_safe/test/test_synchronized_delegator.rb b/app/server/vendor/thread_safe/test/test_synchronized_delegator.rb
new file mode 100644
index 0000000..40c9438
--- /dev/null
+++ b/app/server/vendor/thread_safe/test/test_synchronized_delegator.rb
@@ -0,0 +1,84 @@
+require 'thread_safe/synchronized_delegator.rb'
+require File.join(File.dirname(__FILE__), "test_helper")
+
+class TestSynchronizedDelegator < Minitest::Test
+
+  def test_wraps_array
+    sync_array = SynchronizedDelegator.new(array = [])
+
+    array << 1
+    assert_equal 1, sync_array[0]
+
+    sync_array << 2
+    assert_equal 2, array[1]
+  end
+
+  def test_synchronizes_access
+    t1_continue, t2_continue = false, false
+
+    hash = Hash.new do |hash, key|
+      t2_continue = true
+      unless hash.find { |e| e[1] == key.to_s } # just to do something
+        hash[key] = key.to_s
+        Thread.pass until t1_continue
+      end
+    end
+    sync_hash = SynchronizedDelegator.new(hash)
+    sync_hash[1] = 'egy'
+
+    t1 = Thread.new do
+      sync_hash[2] = 'dva'
+      sync_hash[3] # triggers t2_continue
+    end
+
+    t2 = Thread.new do
+      Thread.pass until t2_continue
+      sync_hash[4] = '42'
+    end
+
+    sleep(0.05) # sleep some to allow threads to boot
+
+    until t2.status == 'sleep' do
+      Thread.pass
+    end
+
+    assert_equal 3, hash.keys.size
+
+    t1_continue = true
+    t1.join; t2.join
+
+    assert_equal 4, sync_hash.size
+  end
+
+  def test_synchronizes_access_with_block
+    t1_continue, t2_continue = false, false
+
+    sync_array = SynchronizedDelegator.new(array = [])
+
+    t1 = Thread.new do
+      sync_array << 1
+      sync_array.each do
+        t2_continue = true
+        Thread.pass until t1_continue
+      end
+    end
+
+    t2 = Thread.new do
+      # sleep(0.01)
+      Thread.pass until t2_continue
+      sync_array << 2
+    end
+
+    until t2.status == 'sleep' || t2.status == false do
+      Thread.pass
+    end
+
+    assert_equal 1, array.size
+
+    t1_continue = true
+    t1.join; t2.join
+
+    assert_equal [1, 2], array
+  end
+
+end
diff --git a/app/server/vendor/thread_safe/thread_safe.gemspec b/app/server/vendor/thread_safe/thread_safe.gemspec
new file mode 100644
index 0000000..be217a0
--- /dev/null
+++ b/app/server/vendor/thread_safe/thread_safe.gemspec
@@ -0,0 +1,26 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path('../lib', __FILE__) unless $:.include?('lib')
+require 'thread_safe/version'
+
+Gem::Specification.new do |gem|
+  gem.authors       = ["Charles Oliver Nutter", "thedarkone"]
+  gem.email         = ["headius at headius.com", "thedarkone2 at gmail.com"]
+  gem.description   = %q{Thread-safe collections and utilities for Ruby}
+  gem.summary       = %q{A collection of data structures and utilities to make thread-safe programming in Ruby easier}
+  gem.homepage      = "https://github.com/headius/thread_safe"
+
+  gem.files         = `git ls-files`.split($\)
+  gem.files        += ['lib/thread_safe/jruby_cache_backend.jar'] if defined?(JRUBY_VERSION)
+  gem.files        -= ['.gitignore'] # see https://github.com/headius/thread_safe/issues/40#issuecomment-42315441
+  gem.platform      = 'java' if defined?(JRUBY_VERSION)
+  gem.executables   = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
+  gem.test_files    = gem.files.grep(%r{^(test|spec|features)/})
+  gem.name          = "thread_safe"
+  gem.require_paths = ["lib"]
+  gem.version       = ThreadSafe::VERSION
+  gem.license       = "Apache-2.0"
+
+  gem.add_development_dependency 'atomic', ['>= 1.1.7', '< 2']
+  gem.add_development_dependency 'rake'
+  gem.add_development_dependency 'minitest', '>= 4'
+end
diff --git a/app/server/vendor/wavefile-0.7.0/LICENSE b/app/server/vendor/wavefile-0.7.0/LICENSE
new file mode 100755
index 0000000..bc88fa9
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/LICENSE
@@ -0,0 +1,24 @@
+== WaveFile
+
+# Copyright (c) 2009-16 Joel Strait
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/wavefile-0.7.0/README.markdown b/app/server/vendor/wavefile-0.7.0/README.markdown
new file mode 100644
index 0000000..3bcb1d9
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/README.markdown
@@ -0,0 +1,100 @@
+A pure Ruby gem for reading and writing sound files in Wave format (*.wav).
+
+You can use this gem to create Ruby programs that work with audio, such as [drum machine](http://beatsdrummachine.com). Since it is written in pure Ruby (as opposed to wrapping an existing C library), you can use it without having to compile a separate extension.
+
+For more info, check out the website: <http://wavefilegem.com/>
+
+# Example Usage
+
+This is a short example that shows how to append three separate Wave files into a single file:
+
+    require 'wavefile'
+    include WaveFile
+    
+    FILES_TO_APPEND = ["file1.wav", "file2.wav", "file3.wav"]
+    SAMPLES_PER_BUFFER = 4096
+
+    Writer.new("append.wav", Format.new(:stereo, :pcm_16, 44100)) do |writer|
+      FILES_TO_APPEND.each do |file_name|
+        Reader.new(file_name).each_buffer(SAMPLES_PER_BUFFER) do |buffer|
+          writer.write(buffer)
+        end
+      end
+    end
+
+More examples can be [found on the wiki](https://github.com/jstrait/wavefile/wiki).
+
+
+# Features
+
+* Ability to read and write Wave files with any number of channels in the following formats:
+  * PCM (8, 16, 24, and 32 bits per sample)
+  * Floating Point (32 and 64 bits per sample)
+* Ability to read sample data from a file in any of the supported formats, regardless of the file's actual sample format
+
+            # Sample data will be returned as 32-bit floating point samples,
+            # regardless of the actual sample format in the file.
+            Reader.new("some_file.wav", Format.new(:mono, :float_32, 44100))
+
+* Automatic file management, similar to how `IO.open` works. That is, you can open a file for reading or writing, and if a block is given, the file will automatically be closed when the block exits.
+
+        Writer.new("some_file.wav", Format.new(:mono, :pcm_16, 44100)) do |writer|
+          # write some sample data
+        end
+        # At this point, the writer will automatically be closed, no need to do it manually
+
+* Ability to query metadata about Wave files (sample rate, number of channels, number of sample frames, etc.), including files that are in a format this gem can't read or write.
+* Pure Ruby, so no need to compile a separate extension in order to use it.
+
+
+# Current Release: v0.7.0
+
+Released on March 6, 2016, this version includes these changes:
+
+* The minimum supported Ruby version is now 1.9.3 - earlier versions are no longer supported.
+* New method: `Reader.native_format`. Returns a `Format` instance with information about the underlaying format of the Wave file being read, which is not necessarily the same format the sample data is being converted to as it's being read.
+* `Reader.info()` has been removed. Instead, construct a new `Reader` instance and use `Reader.native_format()` - this will return a `Format` instance with the same info that would have been returned by `Reader.info()`.
+* Similarly, the `Info` class has been removed, due to `Reader.info()` being removed.
+* Constructing a `Reader` instance will no longer raise an exception if the file is valid Wave file, but in a format unsupported by this gem. The purpose of this is to allow calling `Reader.native_format()` on this instance, to get format information for files not supported by this gem.
+* New method: `Reader.readable_format?` returns true if the file is a valid format that the gem can read, false otherwise.
+* `Reader.read()` and `Reader.each_buffer()` will now raise an exception if the file is a valid Wave file, but not a format that the gem can read. Or put differently, if `Reader.readable_format?` returns `false`, any subsequent calls to `Reader.read()` or `Reader.each_buffer()` will raise an exception.
+* Some constants have been made private since they are intended for internal use.
+* Bug fix: Files will now be read/written correctly on big-endian platforms. Or in other words, sample data is always read as little-endian, regardless of the native endianness of the platform.
+
+
+# Compatibility
+
+WaveFile has been tested with these Ruby versions, and appears to be compatible with them:
+
+* MRI 2.3, 2.2, 2.1, 2.0, 1.9.3
+
+1.9.3 is the minimum supported Ruby version.
+
+If you find any compatibility issues, please let me know by opening a GitHub issue.
+
+
+# Dependencies
+
+WaveFile has no external dependencies. It is written in pure Ruby, and is entirely self-contained.
+
+
+# Installation
+
+First, install the WaveFile gem from rubygems.org:
+
+    gem install wavefile
+
+...and include it in your Ruby program:
+
+    require 'wavefile'
+
+Note that if you're installing the gem into the default Ruby that comes pre-installed on MacOS (as opposed to a Ruby installed via [RVM](http://rvm.io/) or [rbenv](https://github.com/sstephenson/rbenv/)), you should used `sudo gem install wavefile`. Otherwise you might run into a file permission error.
+
+
+# Contributing
+
+1. Fork my repo
+2. Create a branch for your changes
+3. Add your changes, and please include tests
+4. Make sure the tests pass by running `rake test`
+5. Create a pull request
diff --git a/app/server/vendor/wavefile-0.7.0/Rakefile b/app/server/vendor/wavefile-0.7.0/Rakefile
new file mode 100755
index 0000000..e856e2e
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/Rakefile
@@ -0,0 +1,6 @@
+require 'rake/testtask'
+
+Rake::TestTask.new do |t|
+  t.libs << "test"
+  t.test_files = FileList['test/**/*_test.rb']
+end
diff --git a/app/server/vendor/wavefile-0.7.0/lib/wavefile.rb b/app/server/vendor/wavefile-0.7.0/lib/wavefile.rb
new file mode 100644
index 0000000..3d1bd07
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/lib/wavefile.rb
@@ -0,0 +1,33 @@
+require 'wavefile/buffer'
+require 'wavefile/chunk_readers'
+require 'wavefile/duration'
+require 'wavefile/format'
+require 'wavefile/reader'
+require 'wavefile/unvalidated_format'
+require 'wavefile/writer'
+
+module WaveFile
+  VERSION = "0.7.0"
+
+  WAVEFILE_FORMAT_CODE = "WAVE"    # :nodoc:
+  FORMAT_CODES = {:pcm => 1, :float => 3}    # :nodoc:
+  CHUNK_IDS = {:riff         => "RIFF",
+               :format       => "fmt ",
+               :data         => "data",
+               :fact         => "fact",
+               :silence      => "slnt",
+               :cue          => "cue ",
+               :playlist     => "plst",
+               :list         => "list",
+               :label        => "labl",
+               :labeled_text => "ltxt",
+               :note         => "note",
+               :sample       => "smpl",
+               :instrument   => "inst" }    # :nodoc:
+
+  PACK_CODES = {:pcm   => { 8  => "C*", 16 => "s<*", 24 => "C*", 32 => "l<*"},
+                :float => { 32 => "e*", 64 => "E*"}}    # :nodoc:
+
+  UNSIGNED_INT_16 = "v"    # :nodoc:
+  UNSIGNED_INT_32 = "V"    # :nodoc:
+end
diff --git a/app/server/vendor/wavefile-0.7.0/lib/wavefile/buffer.rb b/app/server/vendor/wavefile-0.7.0/lib/wavefile/buffer.rb
new file mode 100644
index 0000000..13d172a
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/lib/wavefile/buffer.rb
@@ -0,0 +1,217 @@
+module WaveFile
+  # Error that is raised when an attempt is made to perform an unsupported or undefined 
+  # conversion between two sample data formats. For example, converting a Buffer with 
+  # 3 channels into a Buffer with 2 channels is undefined.
+  class BufferConversionError < StandardError; end
+
+
+  # Represents a collection of samples in a certain format (e.g. 16-bit mono). 
+  # Reader returns sample data contained in Buffers, and Writer expects incoming sample 
+  # data to be contained in a Buffer as well.
+  #
+  # Contains methods to convert the sample data in the buffer to a different format.
+  class Buffer
+
+    # Creates a new Buffer.
+    #
+    # samples - An array of samples. If the Format has 1 channel (i.e. is mono), this 
+    #           should be a flat array of samples such as [0.5, 0.4, -0.3, ...]. If the 
+    #           Format has 2 or more channels the array should include a sub-array for 
+    #           each sample frame. For example, [[0.5, 0.2], [0.1, 0.6], [-0.2, 0.4], ...] 
+    #           for a stereo file.
+    #
+    # format - A Format instance which describes the sample format of the sample array. 
+    #
+    #          Note that the sample array is not compared with the format to make sure 
+    #          they match - you are on the honor system to make sure they do. If they
+    #          don't match, unexpected things will happen.
+    #
+    # Examples
+    #
+    #   samples = ([0.5] * 50) + ([-0.5] * 50)   # A 440Hz mono square wave
+    #   buffer = Buffer.new(samples, Format.new(:mono, :float, 44100)
+    #
+    #   samples = ([0.5, 0.5] * 50) + ([-0.5, -0.5] * 50)   # A 440Hz stereo square wave
+    #   buffer = Buffer.new(samples, Format.new(2, :float, 44100)
+    #
+    # Returns a constructed Buffer.
+    def initialize(samples, format)
+      @samples = samples
+      @format = format
+    end
+
+
+    # Creates a new Buffer containing the sample data of this Buffer, but converted to 
+    # a different format.
+    #
+    # new_format - The format that the sample data should be converted to
+    #
+    # Examples
+    #
+    #   new_format = Format.new(:mono, :pcm_16, 44100)
+    #   new_buffer = old_buffer.convert(new_format)
+    #
+    # Returns a new Buffer; the existing Buffer is unmodified.
+    def convert(new_format)
+      new_samples = convert_buffer(@samples.dup, @format, new_format)
+      Buffer.new(new_samples, new_format)
+    end
+
+
+    # Converts the sample data contained in the Buffer to a new format. The sample data 
+    # is converted in place, so the existing Buffer is modified.
+    #
+    # new_format - The format that the sample data should be converted to
+    #
+    # Examples
+    #
+    #   new_format = Format.new(:mono, :pcm_16, 44100)
+    #   old_buffer.convert!(new_format)
+    #
+    # Returns self.
+    def convert!(new_format)
+      @samples = convert_buffer(@samples, @format, new_format)
+      @format = new_format
+      self
+    end
+
+
+    # Returns the number of channels the buffer's sample data has
+    def channels
+      @format.channels
+    end
+
+
+    # Returns the bits per sample of the buffer's sample data
+    def bits_per_sample
+      @format.bits_per_sample
+    end
+
+
+    # Returns the sample rate of the buffer's sample data
+    def sample_rate
+      @format.sample_rate
+    end
+
+    # Returns the sample data contained in the Buffer as an Array. If the Format has 
+    # 1 channel, the Array will be a flat list of samples. If the Format has 2 or more 
+    # channels, the Array will include sub arrays for each sample frame, with a sample 
+    # for each channel.
+    #
+    # Examples
+    #
+    #   samples = mono_buffer.samples
+    #   # => [-0.5, 0.3, 0.2, -0.9, ...]
+    #
+    #   samples = stereo_buffer.samples
+    #   # => [[-0.2, 0.5], [0.1, 0.2], [-0.4, 0.7], [0.1, 0.2], ...]
+    #
+    #   samples = three_channel_buffer.samples
+    #   # => [[0.3, 0.5, 0.2], [-0.1, 0.2, -0.9], [0.2, 0.3, -0.4], [0.1, 0.2, -0.8], ...]
+    attr_reader :samples
+
+  private
+
+    def convert_buffer(samples, old_format, new_format)
+      if old_format.channels > new_format.channels
+        samples = convert_channels(samples, old_format.channels, new_format.channels)
+        samples = convert_sample_format(samples, old_format, new_format)
+      else
+        samples = convert_sample_format(samples, old_format, new_format)
+        samples = convert_channels(samples, old_format.channels, new_format.channels)
+      end
+
+      samples
+    end
+
+    def convert_channels(samples, old_channels, new_channels)
+      return samples if old_channels == new_channels
+
+      # The cases of mono -> stereo and vice-versa are handled specially,
+      # because those conversion methods are faster than the general methods,
+      # and the large majority of wave files are expected to be either mono or stereo.
+      if old_channels == 1 && new_channels == 2
+        samples.map! {|sample| [sample, sample]}
+      elsif old_channels == 2 && new_channels == 1
+        samples.map! {|sample| (sample[0] + sample[1]) / 2}
+      elsif old_channels == 1 && new_channels >= 2
+        samples.map! {|sample| [].fill(sample, 0, new_channels)}
+      elsif old_channels >= 2 && new_channels == 1
+        samples.map! {|sample| sample.inject(0) {|sub_sample, sum| sum + sub_sample } / old_channels }
+      elsif old_channels > 2 && new_channels == 2
+        samples.map! {|sample| [sample[0], sample[1]]}
+      else
+        raise BufferConversionError,
+              "Conversion of sample data from #{old_channels} channels to #{new_channels} channels is unsupported"
+      end
+
+      samples
+    end
+
+    def convert_sample_format(samples, old_format, new_format)
+      return samples if old_format.sample_format == :float && new_format.sample_format == :float
+
+      if old_format.sample_format == :pcm && new_format.sample_format == :pcm
+        convert_sample_format_pcm_to_pcm(samples, old_format.bits_per_sample, new_format.bits_per_sample)
+      elsif old_format.sample_format == :pcm && new_format.sample_format == :float
+        convert_sample_format_pcm_to_float(samples, old_format.bits_per_sample, new_format.bits_per_sample)
+      elsif old_format.sample_format == :float && new_format.sample_format == :pcm
+        convert_sample_format_float_to_pcm(samples, old_format.bits_per_sample, new_format.bits_per_sample)
+      end
+    end
+
+    def convert_sample_format_pcm_to_pcm(samples, old_bits_per_sample, new_bits_per_sample)
+      return samples if old_bits_per_sample == new_bits_per_sample
+
+      shift_amount = (new_bits_per_sample - old_bits_per_sample).abs
+
+      if old_bits_per_sample == 8
+        convert_sample_format_helper(samples) {|sample| (sample - 128) << shift_amount }
+      elsif new_bits_per_sample == 8
+        convert_sample_format_helper(samples) {|sample| (sample >> shift_amount) + 128 }
+      else
+        if new_bits_per_sample > old_bits_per_sample
+          convert_sample_format_helper(samples) {|sample| sample << shift_amount }
+        else
+          convert_sample_format_helper(samples) {|sample| sample >> shift_amount }
+        end
+      end
+    end
+
+    def convert_sample_format_pcm_to_float(samples, old_bits_per_sample, new_bits_per_sample)
+      if old_bits_per_sample == 8
+        convert_sample_format_helper(samples) {|sample| (sample - 128).to_f / 128.0 }
+      elsif old_bits_per_sample == 16
+        convert_sample_format_helper(samples) {|sample| sample.to_f / 32768.0 }
+      elsif old_bits_per_sample == 24
+        convert_sample_format_helper(samples) {|sample| sample.to_f / 8388608.0 }
+      elsif old_bits_per_sample == 32
+        convert_sample_format_helper(samples) {|sample| sample.to_f / 2147483648.0 }
+      end
+    end
+
+    def convert_sample_format_float_to_pcm(samples, old_bits_per_sample, new_bits_per_sample)
+      if new_bits_per_sample == 8
+        convert_sample_format_helper(samples) {|sample| (sample * 127.0).round + 128 }
+      elsif new_bits_per_sample == 16
+        convert_sample_format_helper(samples) {|sample| (sample * 32767.0).round }
+      elsif new_bits_per_sample == 24
+        convert_sample_format_helper(samples) {|sample| (sample * 8388607.0).round }
+      elsif new_bits_per_sample == 32
+        convert_sample_format_helper(samples) {|sample| (sample * 2147483647.0).round }
+      end
+    end
+
+    def convert_sample_format_helper(samples, &converter)
+      more_than_one_channel = (Array === samples.first)
+
+      if more_than_one_channel
+        samples.map! do |sample|
+          sample.map! &converter
+        end
+      else
+        samples.map! &converter
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/wavefile-0.7.0/lib/wavefile/chunk_readers.rb b/app/server/vendor/wavefile-0.7.0/lib/wavefile/chunk_readers.rb
new file mode 100644
index 0000000..3ce6ed9
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/lib/wavefile/chunk_readers.rb
@@ -0,0 +1,6 @@
+require 'wavefile/chunk_readers/header_reader'
+
+module WaveFile
+  module ChunkReaders    # :nodoc:
+  end
+end
diff --git a/app/server/vendor/wavefile-0.7.0/lib/wavefile/chunk_readers/header_reader.rb b/app/server/vendor/wavefile-0.7.0/lib/wavefile/chunk_readers/header_reader.rb
new file mode 100644
index 0000000..513e477
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/lib/wavefile/chunk_readers/header_reader.rb
@@ -0,0 +1,163 @@
+module WaveFile
+  module ChunkReaders
+    # Used to read the RIFF chunks in a wave file up until the data chunk. Thus is can be used
+    # to open a wave file and "queue it up" to the start of the actual sample data, as well as
+    # extract information out of pre-data chunks, such as the format chunk.
+    class RiffReader    # :nodoc:
+      def initialize(file, file_name)
+        @file = file
+        @file_name = file_name
+
+        read_until_data_chunk
+      end
+
+      attr_reader :native_format, :data_chunk_reader
+
+    private
+
+      def read_until_data_chunk
+        begin
+          chunk_id = @file.sysread(4)
+          unless chunk_id == CHUNK_IDS[:riff]
+            raise_error InvalidFormatError, "Expected chunk ID '#{CHUNK_IDS[:riff]}', but was '#{chunk_id}'"
+          end
+          RiffChunkReader.new(@file).read
+
+          chunk_id = @file.sysread(4)
+          while chunk_id != CHUNK_IDS[:data]
+            if chunk_id == CHUNK_IDS[:format]
+              @native_format = FormatChunkReader.new(@file).read
+            else
+              # Other chunk types besides the format chunk are ignored. This may change in the future.
+              GenericChunkReader.new(@file).read              
+            end
+
+            chunk_id = @file.sysread(4)
+          end
+        rescue EOFError
+          raise_error InvalidFormatError, "It doesn't have a data chunk."
+        end
+
+        if @native_format == nil
+          raise_error InvalidFormatError, "The format chunk is either missing, or it comes after the data chunk."
+        end
+
+        @data_chunk_reader = DataChunkReader.new(@file, @native_format)
+      end
+
+      class BaseChunkReader    # :nodoc:
+        def read_chunk_size
+          chunk_size = @file.sysread(4).unpack(UNSIGNED_INT_32).first || 0
+
+          # The RIFF specification requires that each chunk be aligned to an even number of bytes,
+          # even if the byte count is an odd number.
+          #
+          # See http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf, page 11.
+          if chunk_size.odd?
+            chunk_size += 1
+          end
+
+          chunk_size
+        end
+
+        def raise_error(exception_class, message)
+          raise exception_class, "File '#{@file_name}' is not a supported wave file. #{message}"
+        end
+      end
+
+      class GenericChunkReader < BaseChunkReader    # :nodoc:
+        def initialize(file)
+          @file = file
+        end
+
+        def read
+          chunk_size = read_chunk_size
+          @file.sysread(chunk_size)
+        end
+      end
+
+      class RiffChunkReader < BaseChunkReader    # :nodoc:
+        def initialize(file)
+          @file = file
+        end
+
+        def read
+          chunk_size = read_chunk_size
+          riff_format = @file.sysread(4)
+
+          unless riff_format == WAVEFILE_FORMAT_CODE
+            raise_error InvalidFormatError, "Expected RIFF format of '#{WAVEFILE_FORMAT_CODE}', but was '#{riff_format}'"
+          end
+        end
+      end
+
+      class DataChunkReader < BaseChunkReader    # :nodoc:
+        def initialize(file, native_format)
+          @file = file
+          @native_format = native_format
+
+          data_chunk_size = @file.sysread(4).unpack(UNSIGNED_INT_32).first
+          @sample_frame_count = data_chunk_size / @native_format.block_align
+        end
+
+        attr_reader :sample_frame_count
+      end
+
+      class FormatChunkReader < BaseChunkReader    # :nodoc:
+        def initialize(file)
+          @file = file
+        end
+
+        def read
+          chunk_size = read_chunk_size
+
+          if chunk_size < MINIMUM_CHUNK_SIZE
+            raise_error InvalidFormatError, "The format chunk is incomplete."
+          end
+
+          raw_bytes = read_chunk_body(CHUNK_IDS[:format], chunk_size)
+
+          format_chunk = {}
+          format_chunk[:audio_format],
+          format_chunk[:channels],
+          format_chunk[:sample_rate],
+          format_chunk[:byte_rate],
+          format_chunk[:block_align],
+          format_chunk[:bits_per_sample] = raw_bytes.slice!(0...MINIMUM_CHUNK_SIZE).unpack("vvVVvv")
+
+          if chunk_size > MINIMUM_CHUNK_SIZE
+            format_chunk[:extension_size] = raw_bytes.slice!(0...2).unpack(UNSIGNED_INT_16).first
+
+            if format_chunk[:extension_size] == nil
+              raise_error InvalidFormatError, "The format chunk is missing an expected extension."
+            end
+
+            if format_chunk[:extension_size] != raw_bytes.length
+              raise_error InvalidFormatError, "The format chunk extension is shorter than expected."
+            end
+
+            # TODO: Parse the extension
+          end
+
+          UnvalidatedFormat.new(format_chunk)
+        end
+
+        private
+
+        MINIMUM_CHUNK_SIZE = 16
+
+        def read_chunk_body(chunk_id, chunk_size)
+          begin
+            return @file.sysread(chunk_size)
+          rescue EOFError
+            raise_error InvalidFormatError, "The #{chunk_id} chunk has incomplete data."
+          end
+        end
+      end
+
+      def raise_error(exception_class, message)
+        raise exception_class, "File '#{@file_name}' is not a supported wave file. #{message}"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/wavefile-0.7.0/lib/wavefile/duration.rb b/app/server/vendor/wavefile-0.7.0/lib/wavefile/duration.rb
new file mode 100644
index 0000000..ecbc812
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/lib/wavefile/duration.rb
@@ -0,0 +1,65 @@
+module WaveFile
+  # Calculates playback time given the number of sample frames and the sample rate. For 
+  # example, you can use this to calculate how long a given Wave file is. 
+  #
+  # The hours, minutes, seconds, and milliseconds fields return values like you would 
+  # see on a stopwatch, and not the total amount of time in that unit. For example, a 
+  # stopwatch running for exactly 2 hours would show something like "2:00:00.000". 
+  # Accordingly, if the given sample frame count and sample rate add up to exactly 
+  # 2 hours, then hours will be 2, and minutes, seconds, and milliseconds will all be 0.
+  #
+  # This class is immutable - once a new Duration is constructed, it can't be modified.
+  class Duration
+    # Constructs a new immutable Duration.
+    #
+    # sample_frame_count - The number of sample frames, i.e. the number 
+    #                      samples in each channel.
+    # sample_rate - The number of samples per second, such as 44100
+    #
+    # Examples:
+    #
+    #   duration = Duration.new(400_000_000, 44100)
+    #   duration.hours         # => 2
+    #   duration.minutes       # => 31
+    #   duration.seconds       # => 10
+    #   duration.milliseconds  # => 294
+    #
+    # Note that the hours, minutes, seconds, and milliseconds fields do not return 
+    # the total of the respective unit in the entire duration. For example, if a 
+    # duration is exactly 2 hours, then minutes will be 0, not 120.
+    def initialize(sample_frame_count, sample_rate)
+      @sample_frame_count = sample_frame_count
+      @sample_rate = sample_rate
+
+      sample_frames_per_millisecond = sample_rate / 1000.0
+      sample_frames_per_second = sample_rate
+      sample_frames_per_minute = sample_frames_per_second * 60
+      sample_frames_per_hour = sample_frames_per_minute * 60
+      @hours, @minutes, @seconds, @milliseconds = 0, 0, 0, 0
+
+      if(sample_frame_count >= sample_frames_per_hour)
+        @hours = sample_frame_count / sample_frames_per_hour
+        sample_frame_count -= sample_frames_per_hour * @hours
+      end
+
+      if(sample_frame_count >= sample_frames_per_minute)
+        @minutes = sample_frame_count / sample_frames_per_minute
+        sample_frame_count -= sample_frames_per_minute * @minutes
+      end
+
+      if(sample_frame_count >= sample_frames_per_second)
+        @seconds = sample_frame_count / sample_frames_per_second
+        sample_frame_count -= sample_frames_per_second * @seconds
+      end
+
+      @milliseconds = (sample_frame_count / sample_frames_per_millisecond).floor
+    end
+ 
+    attr_reader :sample_frame_count
+    attr_reader :sample_rate 
+    attr_reader :hours
+    attr_reader :minutes
+    attr_reader :seconds
+    attr_reader :milliseconds
+  end
+end
diff --git a/app/server/vendor/wavefile-0.7.0/lib/wavefile/format.rb b/app/server/vendor/wavefile-0.7.0/lib/wavefile/format.rb
new file mode 100644
index 0000000..72818c3
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/lib/wavefile/format.rb
@@ -0,0 +1,138 @@
+module WaveFile
+  # Represents information about the data format for a Wave file, such as number of 
+  # channels, bits per sample, sample rate, and so forth. A Format instance is used 
+  # by Reader to indicate what format to read samples out as, and by Writer to 
+  # indicate what format to write samples as.
+  #
+  # This class is immutable - once a new Format is constructed, it can't be modified.
+  class Format
+
+    # Constructs a new immutable Format.
+    #
+    # channels - The number of channels in the format. Can either be a Fixnum 
+    #            (e.g. 1, 2, 3) or the symbols :mono (equivalent to 1) or 
+    #            :stereo (equivalent to 2).
+    # format_code - A symbol indicating the format of each sample. Consists of 
+    #               two parts: a format code, and the bits per sample. The valid 
+    #               values are :pcm_8, :pcm_16, :pcm_32, :float_32, :float_64,
+    #               and :float (equivalent to :float_32)
+    # sample_rate - The number of samples per second, such as 44100
+    #
+    # Examples
+    #
+    #   format = Format.new(1, :pcm_16, 44100)
+    #   format = Format.new(:mono, :pcm_16, 44100)  # Equivalent to above
+    #
+    #   format = Format.new(:stereo, :float_32, 44100)
+    #   format = Format.new(:stereo, :float, 44100)
+    def initialize(channels, format_code, sample_rate)
+      channels = normalize_channels(channels)
+      sample_format, bits_per_sample = normalize_format_code(format_code)
+      validate_channels(channels)
+      validate_sample_format(sample_format)
+      validate_bits_per_sample(sample_format, bits_per_sample)
+      validate_sample_rate(sample_rate)
+
+      @channels = channels
+      @sample_format = sample_format
+      @bits_per_sample = bits_per_sample
+      @sample_rate = sample_rate
+      @block_align = (@bits_per_sample / 8) * @channels
+      @byte_rate = @block_align * @sample_rate
+    end
+
+    # Returns true if the format has 1 channel, false otherwise.
+    def mono?
+      @channels == 1
+    end
+
+    # Returns true if the format has 2 channels, false otherwise.
+    def stereo?
+      @channels == 2
+    end
+
+    # Returns the number of channels, such as 1 or 2. This will always return a 
+    # Fixnum, even if the number of channels is specified with a symbol (e.g. :mono) 
+    # in the constructor.
+    attr_reader :channels
+
+    # Returns a symbol indicating the sample format, such as :pcm or :float
+    attr_reader :sample_format
+
+    # Returns the number of bits per sample, such as 8, 16, 24, 32, or 64.
+    attr_reader :bits_per_sample
+
+    # Returns the number of samples per second, such as 44100.
+    attr_reader :sample_rate
+
+    # Returns the number of bytes in each sample frame. For example, in a 16-bit stereo file, 
+    # this will be 4 (2 bytes for each 16-bit sample, times 2 channels).
+    attr_reader :block_align
+
+    # Returns the number of bytes contained in 1 second of sample data. 
+    # Is equivalent to block_align * sample_rate.
+    attr_reader :byte_rate
+
+  private
+
+    VALID_CHANNEL_RANGE     = 1..65535    # :nodoc:
+    VALID_SAMPLE_RATE_RANGE = 1..4_294_967_296    # :nodoc:
+
+    SUPPORTED_SAMPLE_FORMATS = [:pcm, :float]    # :nodoc:
+    SUPPORTED_BITS_PER_SAMPLE = {
+                                  :pcm => [8, 16, 24, 32],
+                                  :float => [32, 64],
+                                }    # :nodoc:
+
+    def normalize_channels(channels)
+      if channels == :mono
+        return 1
+      elsif channels == :stereo
+        return 2
+      else
+        return channels
+      end
+    end
+
+    def normalize_format_code(format_code)
+      if SUPPORTED_BITS_PER_SAMPLE[:pcm].include? format_code
+        [:pcm, format_code]
+      elsif format_code == :float
+        [:float, 32]
+      else
+        sample_format, bits_per_sample = format_code.to_s.split("_")
+        [sample_format.to_sym, bits_per_sample.to_i]
+      end
+    end
+
+    def validate_sample_format(candidate_sample_format)
+      unless SUPPORTED_SAMPLE_FORMATS.include? candidate_sample_format
+        raise InvalidFormatError,
+              "Sample format of #{candidate_sample_format} is unsupported. " +
+              "Only #{SUPPORTED_SAMPLE_FORMATS.inspect} are supported."
+      end
+    end
+
+    def validate_channels(candidate_channels)
+      unless VALID_CHANNEL_RANGE === candidate_channels
+        raise InvalidFormatError,
+              "Invalid number of channels. Must be between #{VALID_CHANNEL_RANGE.min} and #{VALID_CHANNEL_RANGE.max}."
+      end
+    end
+
+    def validate_bits_per_sample(candidate_sample_format, candidate_bits_per_sample)
+      unless SUPPORTED_BITS_PER_SAMPLE[candidate_sample_format].include? candidate_bits_per_sample
+        raise InvalidFormatError,
+              "Bits per sample of #{candidate_bits_per_sample} is unsupported for " +
+              "sample format #{candidate_sample_format}."
+      end
+    end
+
+    def validate_sample_rate(candidate_sample_rate)
+      unless VALID_SAMPLE_RATE_RANGE === candidate_sample_rate
+        raise InvalidFormatError,
+              "Invalid sample rate. Must be between #{VALID_SAMPLE_RATE_RANGE.min} and #{VALID_SAMPLE_RATE_RANGE.max}"
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/wavefile-0.7.0/lib/wavefile/reader.rb b/app/server/vendor/wavefile-0.7.0/lib/wavefile/reader.rb
new file mode 100644
index 0000000..f8d4a30
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/lib/wavefile/reader.rb
@@ -0,0 +1,205 @@
+module WaveFile
+  # Error that is raised when a file is not in a format supported by this Gem,
+  # because it's a valid Wave file whose format is not supported by this Gem,
+  # because it's a not a valid Wave file period, etc.
+  class FormatError < StandardError; end
+
+  # Error that is raised when trying to read from a file that is either not a wave file, 
+  # or that is not valid according to the wave file spec.
+  class InvalidFormatError < FormatError; end
+
+  # Error that is raised when trying to read from a valid wave file that has its sample data 
+  # stored in a format that Reader doesn't understand.
+  class UnsupportedFormatError < FormatError; end
+
+
+  # Provides the ability to read sample data out of a wave file, as well as query a 
+  # wave file about its metadata (e.g. number of channels, sample rate, etc).
+  #
+  # When constructing a Reader a block can be given. All data should be read inside this 
+  # block, and when the block exits the Reader will automatically be closed.
+  #
+  #     Reader.new("my_file.wav") do |reader|
+  #       # Read sample data here
+  #     end
+  #
+  # Alternately, if a block isn't given you should make sure to call close when finished reading.
+  #
+  #     reader = Reader.new("my_file.wav")
+  #     # Read sample data here
+  #     reader.close
+  class Reader
+    # Returns a Reader object that is ready to start reading the specified file's sample data. 
+    #
+    # file_name - The name of the wave file to read from.
+    # format - The format that read sample data should be returned in 
+    #          (default: the wave file's internal format).
+    #
+    # Returns a Reader object that is ready to start reading the specified file's sample data.
+    # Raises Errno::ENOENT if the specified file can't be found
+    # Raises InvalidFormatError if the specified file isn't a valid wave file
+    def initialize(file_name, format=nil)
+      @file_name = file_name
+      @file = File.open(file_name, "rb")
+
+      begin
+        @riff_reader = ChunkReaders::RiffReader.new(@file, @file_name)
+      rescue InvalidFormatError
+        raise InvalidFormatError, "'#{@file_name}' does not appear to be a valid Wave file"
+      end
+      
+      @raw_native_format = @riff_reader.native_format
+      @total_sample_frames = @riff_reader.data_chunk_reader.sample_frame_count
+      @current_sample_frame = 0
+
+      native_sample_format = "#{FORMAT_CODES.invert[native_format.audio_format]}_#{native_format.bits_per_sample}".to_sym
+
+      @readable_format = true
+      begin
+        @native_format = Format.new(@raw_native_format.channels,
+                                    native_sample_format,
+                                    @raw_native_format.sample_rate)
+        @pack_code = PACK_CODES[@native_format.sample_format][@native_format.bits_per_sample]
+      rescue FormatError
+        @readable_format = false
+        @pack_code = nil
+      end
+
+      @format = (format == nil) ? (@native_format || @raw_native_format) : format
+
+      if block_given?
+        begin
+          yield(self)
+        ensure
+          close
+        end
+      end
+    end
+
+
+    # Reads sample data of the into successive Buffers of the specified size, until there is no more 
+    # sample data to be read. When all sample data has been read, the Reader is automatically closed. 
+    # Each Buffer is passed to the given block.
+    #
+    # Note that sample_frame_count indicates the number of sample frames to read, not number of samples. 
+    # A sample frame include one sample for each channel. For example, if sample_frame_count is 1024, then 
+    # for a stereo file 1024 samples will be read from the left channel, and 1024 samples will be read from 
+    # the right channel.
+    #
+    # sample_frame_count - The number of sample frames to read into each Buffer from each channel. The number 
+    #                      of sample frames read into the final Buffer could be less than this size, if there 
+    #                      are not enough remaining.
+    #
+    # Returns nothing.
+    def each_buffer(sample_frame_count)
+      begin
+        while true do
+          yield(read(sample_frame_count))
+        end
+      rescue EOFError
+        close
+      end
+    end
+
+
+    # Reads the specified number of sample frames from the wave file into a Buffer. Note that the Buffer will have 
+    # at most sample_frame_count sample frames, but could have less if the file doesn't have enough remaining.
+    #
+    # sample_frame_count - The number of sample frames to read. Note that each sample frame includes a sample for 
+    #                      each channel.
+    #
+    # Returns a Buffer containing sample_frame_count sample frames
+    # Raises UnsupportedFormatError if file is in a format that can't be read by this gem
+    # Raises EOFError if no samples could be read due to reaching the end of the file
+    def read(sample_frame_count)
+      raise UnsupportedFormatError unless @readable_format
+
+      if @current_sample_frame >= @total_sample_frames
+        #FIXME: Do something different here, because the end of the file has not actually necessarily been reached
+        raise EOFError
+      elsif sample_frame_count > sample_frames_remaining
+        sample_frame_count = sample_frames_remaining
+      end
+
+      samples = @file.sysread(sample_frame_count * @native_format.block_align).unpack(@pack_code)
+      @current_sample_frame += sample_frame_count
+
+      if @native_format.bits_per_sample == 24
+        # Since the sample data is little endian, the 3 bytes will go from least->most significant
+        samples = samples.each_slice(3).map {|least_significant_byte, middle_byte, most_significant_byte|
+          # Convert the byte read as "C" to one read as "c"
+          most_significant_byte = [most_significant_byte].pack("c").unpack("c").first
+          
+          (most_significant_byte << 16) | (middle_byte << 8) | least_significant_byte
+        }
+      end
+
+      if @native_format.channels > 1
+        samples = samples.each_slice(@native_format.channels).to_a
+      end
+
+      buffer = Buffer.new(samples, @native_format)
+      buffer.convert(@format)
+    end
+
+
+    # Returns true if the Reader is closed, and false if it is open and available for reading.
+    def closed?
+      @file.closed?
+    end
+
+
+    # Closes the Reader. After a Reader is closed, no more sample data can be read from it.
+    #
+    # Returns nothing.
+    # Raises IOError if the Reader is already closed.
+    def close
+      @file.close
+    end
+
+    # Returns a Duration instance for the total number of sample frames in the file
+    def total_duration
+      Duration.new(total_sample_frames, @format.sample_rate)
+    end
+
+    # Returns a Format object describing the sample format of the Wave file being read.
+    # This is not necessarily the format that the sample data will be read as - to determine
+    # that, use #format.
+    def native_format
+      @raw_native_format
+    end
+
+    # Returns true if this is a valid Wave file and contains sample data that is in a format
+    # that this class can read, and returns false if this is a valid Wave file but does not
+    # contain a sample format supported by this class.
+    def readable_format?
+      @readable_format
+    end
+
+    # Returns the name of the Wave file that is being read
+    attr_reader :file_name
+
+    # Returns a Format object describing how sample data is being read from the Wave file (number of 
+    # channels, sample format and bits per sample, etc). Note that this might be different from the 
+    # underlying format of the Wave file on disk.
+    attr_reader :format
+
+    # Returns the index of the sample frame which is "cued up" for reading. I.e., the index 
+    # of the next sample frame that will be read. A sample frame contains a single sample 
+    # for each channel. So if there are 1,000 sample frames in a stereo file, this means 
+    # there are 1,000 left-channel samples and 1,000 right-channel samples.
+    attr_reader :current_sample_frame
+
+    # Returns the total number of sample frames in the file. A sample frame contains a single 
+    # sample for each channel. So if there are 1,000 sample frames in a stereo file, this means 
+    # there are 1,000 left-channel samples and 1,000 right-channel samples.
+    attr_reader :total_sample_frames
+
+  private
+
+    # The number of sample frames in the file after the current sample frame
+    def sample_frames_remaining
+      @total_sample_frames - @current_sample_frame
+    end
+  end
+end
diff --git a/app/server/vendor/wavefile-0.7.0/lib/wavefile/unvalidated_format.rb b/app/server/vendor/wavefile-0.7.0/lib/wavefile/unvalidated_format.rb
new file mode 100644
index 0000000..0932efc
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/lib/wavefile/unvalidated_format.rb
@@ -0,0 +1,23 @@
+module WaveFile
+  # Represents information about the data format for a Wave file, such as number of 
+  # channels, bits per sample, sample rate, and so forth. A Format instance is used 
+  # by Reader to indicate what format to read samples out as, and by Writer to 
+  # indicate what format to write samples as.
+  #
+  # This class is immutable - once a new Format is constructed, it can't be modified.
+  class UnvalidatedFormat < Format    # :nodoc:
+    # Constructs a new immutable UnvalidatedFormat.
+    def initialize(fields)
+      @audio_format = fields[:audio_format]
+      @channels = fields[:channels]
+      @sample_rate = fields[:sample_rate]
+      @byte_rate = fields[:byte_rate]
+      @block_align = fields[:block_align]
+      @bits_per_sample = fields[:bits_per_sample]
+    end
+
+    # Returns a number indicating the sample format, such as 1 (PCM) or 3 (Float)
+    attr_reader :audio_format
+  end
+end
+
diff --git a/app/server/vendor/wavefile-0.7.0/lib/wavefile/writer.rb b/app/server/vendor/wavefile-0.7.0/lib/wavefile/writer.rb
new file mode 100644
index 0000000..6b8ccaf
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/lib/wavefile/writer.rb
@@ -0,0 +1,182 @@
+module WaveFile
+  # Provides the ability to write data to a wave file.
+  #
+  # When a Writer is constructed it can be given a block. All samples should be written inside this 
+  # block, and when the block exits the file will automatically be closed:
+  #
+  #    Writer.new("my_file.wav", Format.new(:mono, :pcm_16, 44100)) do |writer|
+  #      # Write sample data here
+  #    end
+  #
+  # If no block is given, you'll need to manually close the Writer when done. The underlaying 
+  # file will not be valid or playable until close is called.
+  #
+  #    writer = Writer.new("my_file.wav", Format.new(:mono, :pcm_16, 44100))
+  #    # Write sample data here
+  #    writer.close
+  class Writer
+
+    # Returns a constructed Writer object which is available for writing sample data to the specified 
+    # file (via the write method). When all sample data has been written, the Writer should be closed. 
+    # Note that the wave file being written to will NOT be valid (and playable in other programs) until 
+    # the Writer has been closed.
+    #
+    # If a block is given to this method, sample data can be written inside the given block. When the 
+    # block terminates, the Writer will be automatically closed (and no more sample data can be written). 
+    #
+    # If no block is given, then sample data can be written until the close method is called.
+    def initialize(file_name, format)
+      @file_name = file_name
+      @file = File.open(file_name, "wb")
+      @format = format
+
+      @total_sample_frames = 0
+      @pack_code = PACK_CODES[format.sample_format][format.bits_per_sample]
+
+      # Note that the correct sizes for the RIFF and data chunks can't be determined
+      # until all samples have been written, so this header as written will be incorrect.
+      # When close is called, the correct sizes will be re-written.
+      write_header(0)
+
+      if block_given?
+        begin
+          yield(self)
+        ensure
+          close
+        end
+      end
+    end
+
+
+    # Appends the sample data in the given Buffer to the end of the wave file.
+    #
+    # Returns the number of sample frames that have been written to the file so far.
+    # Raises IOError if the Writer has been closed.
+    def write(buffer)
+      samples = buffer.convert(@format).samples
+
+      if @format.bits_per_sample == 24 && @format.sample_format == :pcm
+        samples.flatten.each do |sample|
+          @file.syswrite([sample].pack("l<X"))
+        end
+      else
+        @file.syswrite(samples.flatten.pack(@pack_code))
+      end
+
+      @total_sample_frames += samples.length
+    end
+
+
+    # Returns true if the Writer is closed, and false if it is open and available for writing.
+    def closed?
+      @file.closed?
+    end
+
+
+    # Closes the Writer. After a Writer is closed, no more sample data can be written to it.
+    #
+    # Note that the wave file will NOT be valid until this method is called. The wave file 
+    # format requires certain information about the amount of sample data, and this can't be 
+    # determined until all samples have been written. (This method doesn't need to be called 
+    # when passing a block to Writer.new, as this method will automatically be called when 
+    # the block exits).
+    #
+    # Returns nothing.
+    # Raises IOError if the Writer is already closed.
+    def close
+      # The RIFF specification requires that each chunk be aligned to an even number of bytes,
+      # even if the byte count is an odd number. Therefore if an odd number of bytes has been
+      # written, write an empty padding byte.
+      #
+      # See http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf, page 11.
+      bytes_written = @total_sample_frames * @format.block_align
+      if bytes_written.odd?
+        @file.syswrite(EMPTY_BYTE)
+      end
+
+      # We can't know what chunk sizes to write for the RIFF and data chunks until all
+      # samples have been written, so go back to the beginning of the file and re-write
+      # those chunk headers with the correct sizes.
+      @file.sysseek(0)
+      write_header(@total_sample_frames)
+
+      @file.close
+    end
+
+    # Returns a Duration instance for the number of sample frames that have been written so far
+    def total_duration
+      Duration.new(@total_sample_frames, @format.sample_rate)
+    end
+
+    # Returns the name of the Wave file that is being written to
+    attr_reader :file_name
+
+    # Returns a Format object describing the Wave file being written (number of channels, sample 
+    # format and bits per sample, sample rate, etc.)
+    attr_reader :format
+
+    # Returns the number of samples (per channel) that have been written to the file so far. 
+    # For example, if 1000 "left" samples and 1000 "right" samples have been written to a stereo file, 
+    # this will return 1000.
+    attr_reader :total_sample_frames
+
+  private
+
+    # Padding value written to the end of chunks whose payload is an odd number of bytes. The RIFF 
+    # specification requires that each chunk be aligned to an even number of bytes, even if the byte 
+    # count is an odd number.
+    #
+    # See http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf, page 11.
+    EMPTY_BYTE = "\000"    # :nodoc:
+
+    # The number of bytes at the beginning of a wave file before the sample data in the data chunk 
+    # starts, assuming this canonical format:
+    #
+    # RIFF Chunk Header (12 bytes)
+    # Format Chunk (16 bytes for PCM, 18 bytes for floating point)
+    # FACT Chunk (0 bytes for PCM, 12 bytes for floating point)
+    # Data Chunk Header (8 bytes)
+    #
+    # All wave files written by Writer use this canonical format.
+    CANONICAL_HEADER_BYTE_LENGTH = {:pcm => 36, :float => 50}    # :nodoc:
+
+    FORMAT_CHUNK_BYTE_LENGTH = {:pcm => 16, :float => 18}    # :nodoc:
+
+    # Writes the RIFF chunk header, format chunk, and the header for the data chunk. After this
+    # method is called the file will be "queued up" and ready for writing actual sample data.
+    def write_header(sample_frame_count)
+      sample_data_byte_count = sample_frame_count * @format.block_align
+
+      # Write the header for the RIFF chunk
+      header = CHUNK_IDS[:riff]
+      header += [CANONICAL_HEADER_BYTE_LENGTH[@format.sample_format] + sample_data_byte_count].pack(UNSIGNED_INT_32)
+      header += WAVEFILE_FORMAT_CODE
+
+      # Write the format chunk
+      header += CHUNK_IDS[:format]
+      header += [FORMAT_CHUNK_BYTE_LENGTH[@format.sample_format]].pack(UNSIGNED_INT_32)
+      header += [FORMAT_CODES[@format.sample_format]].pack(UNSIGNED_INT_16)
+      header += [@format.channels].pack(UNSIGNED_INT_16)
+      header += [@format.sample_rate].pack(UNSIGNED_INT_32)
+      header += [@format.byte_rate].pack(UNSIGNED_INT_32)
+      header += [@format.block_align].pack(UNSIGNED_INT_16)
+      header += [@format.bits_per_sample].pack(UNSIGNED_INT_16)
+      if @format.sample_format == :float
+        header += [0].pack(UNSIGNED_INT_16)
+      end
+
+      # Write the FACT chunk, if necessary
+      unless @format.sample_format == :pcm
+        header += CHUNK_IDS[:fact]
+        header += [4].pack(UNSIGNED_INT_32)
+        header += [sample_frame_count].pack(UNSIGNED_INT_32)
+      end
+
+      # Write the header for the data chunk
+      header += CHUNK_IDS[:data]
+      header += [sample_data_byte_count].pack(UNSIGNED_INT_32)
+
+      @file.syswrite(header)
+    end
+  end
+end
diff --git a/app/server/vendor/wavefile-0.7.0/test/buffer_test.rb b/app/server/vendor/wavefile-0.7.0/test/buffer_test.rb
new file mode 100644
index 0000000..0578ac5
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/test/buffer_test.rb
@@ -0,0 +1,452 @@
+require 'minitest/autorun'
+require 'wavefile.rb'
+
+include WaveFile
+
+class BufferTest < MiniTest::Unit::TestCase
+  def test_convert
+    old_format = Format.new(:mono, :pcm_16, 44100)
+    new_format = Format.new(:stereo, :pcm_16, 22050)
+
+    old_buffer = Buffer.new([-100, 0, 200], old_format)
+    new_buffer = old_buffer.convert(new_format)
+
+    assert_equal([-100, 0, 200], old_buffer.samples)
+    assert_equal(1, old_buffer.channels)
+    assert_equal(16, old_buffer.bits_per_sample)
+    assert_equal(44100, old_buffer.sample_rate)
+
+    assert_equal([[-100, -100], [0, 0], [200, 200]], new_buffer.samples)
+    assert_equal(2, new_buffer.channels)
+    assert_equal(16, new_buffer.bits_per_sample)
+    assert_equal(22050, new_buffer.sample_rate)
+  end
+
+  def test_convert!
+    old_format = Format.new(:mono, :pcm_16, 44100)
+    new_format = Format.new(:stereo, :pcm_16, 22050)
+
+    old_buffer = Buffer.new([-100, 0, 200], old_format)
+    new_buffer = old_buffer.convert!(new_format)
+
+    assert(old_buffer.equal?(new_buffer))
+    assert_equal([[-100, -100], [0, 0], [200, 200]], old_buffer.samples)
+    assert_equal(2, old_buffer.channels)
+    assert_equal(16, old_buffer.bits_per_sample)
+    assert_equal(22050, old_buffer.sample_rate)
+  end
+
+
+  def test_convert_buffer_channels
+    Format::SUPPORTED_BITS_PER_SAMPLE[:pcm].each do |bits_per_sample|
+      [44100, 22050].each do |sample_rate|
+        # Assert that not changing the number of channels is a no-op
+        b = Buffer.new([-100, 0, 200], Format.new(:mono, bits_per_sample, sample_rate))
+        b.convert!(Format.new(:mono, bits_per_sample, sample_rate))
+        assert_equal([-100, 0, 200], b.samples)
+
+        # Mono => Stereo
+        b = Buffer.new([-100, 0, 200], Format.new(:mono, bits_per_sample, sample_rate))
+        b.convert!(Format.new(:stereo, bits_per_sample, sample_rate))
+        assert_equal([[-100, -100], [0, 0], [200, 200]], b.samples)
+
+        # Mono => 3-channel
+        b = Buffer.new([-100, 0, 200], Format.new(:mono, bits_per_sample, sample_rate))
+        b.convert!(Format.new(3, bits_per_sample, sample_rate))
+        assert_equal([[-100, -100, -100], [0, 0, 0], [200, 200, 200]], b.samples)
+
+        # Stereo => Mono
+        b = Buffer.new([[-100, -100], [0, 0], [200, 50], [8, 1]], Format.new(:stereo, bits_per_sample, sample_rate))
+        b.convert!(Format.new(:mono, bits_per_sample, sample_rate))
+        assert_equal([-100, 0, 125, 4], b.samples)
+
+        # 3-channel => Mono
+        b = Buffer.new([[-100, -100, -100], [0, 0, 0], [200, 50, 650], [5, 1, 1], [5, 1, 2]],
+                       Format.new(3, bits_per_sample, sample_rate))
+        b.convert!(Format.new(:mono, bits_per_sample, sample_rate))
+        assert_equal([-100, 0, 300, 2, 2], b.samples)
+
+        # 3-channel => Stereo
+        b = Buffer.new([[-100, -100, -100], [1, 2, 3], [200, 50, 650]],
+                       Format.new(3, bits_per_sample, sample_rate))
+        b.convert!(Format.new(:stereo, bits_per_sample, sample_rate))
+        assert_equal([[-100, -100], [1, 2], [200, 50]], b.samples)
+
+        # Unsupported conversion (4-channel => 3-channel)
+        b = Buffer.new([[-100, 200, -300, 400], [1, 2, 3, 4]],
+                       Format.new(4, bits_per_sample, sample_rate))
+        assert_raises(BufferConversionError) { b.convert!(Format.new(3, bits_per_sample, sample_rate)) }
+      end
+    end
+  end
+
+  def test_convert_buffer_bits_per_sample_no_op
+    Format::SUPPORTED_BITS_PER_SAMPLE[:pcm].each do |bits_per_sample|
+      b = Buffer.new([0, 128, 255], Format.new(:mono, bits_per_sample, 44100))
+      b.convert!(Format.new(:mono, bits_per_sample, 44100))
+
+      # Target format is the same as the original format, so the sample data should not change
+      assert_equal([0, 128, 255], b.samples)
+    end
+  end
+
+  def test_convert_buffer_bits_per_sample_8_to_16
+    # Mono
+    b = Buffer.new([0, 32, 64, 96, 128, 160, 192, 223, 255], Format.new(:mono, :pcm_8, 44100))
+    b.convert!(Format.new(:mono, :pcm_16, 44100))
+    assert_equal([-32768, -24576, -16384, -8192, 0, 8192, 16384, 24320, 32512], b.samples)
+
+    # Stereo
+    b = Buffer.new([[0, 255],  [32, 223], [64, 192], [96, 160], [128, 128],
+                    [160, 96], [192, 64], [223, 32], [255, 0]],
+                   Format.new(:stereo, :pcm_8, 44100))
+    b.convert!(Format.new(:stereo, :pcm_16, 44100))
+    assert_equal([[-32768, 32512], [-24576, 24320], [-16384, 16384], [-8192, 8192], [0, 0],
+                  [8192, -8192],   [16384, -16384], [24320, -24576], [32512, -32768]],
+                 b.samples)
+  end
+
+  def test_convert_buffer_bits_per_sample_8_to_24
+    # Mono
+    b = Buffer.new([0, 32, 64, 96, 128, 160, 192, 223, 255], Format.new(:mono, :pcm_8, 44100))
+    b.convert!(Format.new(:mono, :pcm_24, 44100))
+    assert_equal([-8388608, -6291456, -4194304, -2097152, 0, 2097152, 4194304, 6225920, 8323072], b.samples)
+
+    # Stereo
+    b = Buffer.new([[0, 255],  [32, 223], [64, 192], [96, 160], [128, 128],
+                    [160, 96], [192, 64], [223, 32], [255, 0]],
+                   Format.new(:stereo, :pcm_8, 44100))
+    b.convert!(Format.new(:stereo, :pcm_24, 44100))
+    assert_equal([[-8388608, 8323072], [-6291456, 6225920], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
+                  [2097152, -2097152],   [4194304, -4194304], [6225920, -6291456], [8323072, -8388608]],
+                 b.samples)
+  end
+
+  def test_convert_buffer_bits_per_sample_8_to_32
+    # Mono
+    b = Buffer.new([0, 32, 64, 96, 128, 160, 192, 223, 255], Format.new(:mono, :pcm_8, 44100))
+    b.convert!(Format.new(:mono, :pcm_32, 44100))
+    assert_equal([-2147483648, -1610612736, -1073741824, -536870912, 0, 536870912, 1073741824, 1593835520, 2130706432], b.samples)
+
+    # Stereo
+    b = Buffer.new([[0, 255],  [32, 223], [64, 192], [96, 160], [128, 128],
+                    [160, 96], [192, 64], [223, 32], [255, 0]],
+                   Format.new(:stereo, :pcm_8, 44100))
+    b.convert!(Format.new(:stereo, :pcm_32, 44100))
+    assert_equal([[-2147483648, 2130706432], [-1610612736, 1593835520], [-1073741824, 1073741824], [-536870912, 536870912], [0, 0],
+                  [536870912, -536870912],   [1073741824, -1073741824], [1593835520, -1610612736], [2130706432, -2147483648]],
+                 b.samples)
+  end
+
+  def test_convert_buffer_bits_per_sample_8_to_float
+    Format::SUPPORTED_BITS_PER_SAMPLE[:float].each do |bits_per_sample|
+      float_format = "float_#{bits_per_sample}".to_sym
+
+      # Mono
+      b = Buffer.new([0, 32, 64, 96, 128, 160, 192, 223, 255], Format.new(:mono, :pcm_8, 44100))
+      b.convert!(Format.new(:mono, float_format, 44100))
+      assert_equal([-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.7421875, 0.9921875], b.samples)
+
+      # Stereo
+      b = Buffer.new([[0, 255],  [32, 223], [64, 192], [96, 160], [128, 128],
+                      [160, 96], [192, 64], [223, 32], [255, 0]],
+                     Format.new(:stereo, :pcm_8, 44100))
+      b.convert!(Format.new(:stereo, float_format, 44100))
+      assert_equal([[-1.0, 0.9921875], [-0.75, 0.7421875], [-0.5, 0.5], [-0.25, 0.25], [0.0, 0.0],
+                    [0.25, -0.25],   [0.5, -0.5], [0.7421875, -0.75], [0.9921875, -1.0]],
+                   b.samples)
+    end
+  end
+
+  def test_convert_buffer_bits_per_sample_16_to_8
+    # Mono
+    b = Buffer.new([-32768, -24576, -16384, -8192, 0, 8192, 16384, 24575, 32767], Format.new(:mono, :pcm_16, 44100))
+    b.convert!(Format.new(:mono, :pcm_8, 44100))
+    assert_equal([0, 32, 64, 96, 128, 160, 192, 223, 255], b.samples)
+
+    # Stereo
+    b = Buffer.new([[-32768, 32767], [-24576, 24575], [-16384, 16384], [-8192, 8192], [0, 0],
+                    [8192, -8192],   [16384, -16384], [24575, -24576], [32767, -32768]],
+                   Format.new(:stereo, :pcm_16, 44100))
+    b.convert!(Format.new(:stereo, :pcm_8, 44100))
+    assert_equal([[0, 255],  [32, 223], [64, 192], [96, 160], [128, 128],
+                  [160, 96], [192, 64], [223, 32], [255, 0]],
+                 b.samples)
+  end
+
+  def test_convert_buffer_bits_per_sample_16_to_24
+    # Mono
+    b = Buffer.new([-32768, -24576, -16384, -8192, 0, 8192, 16384, 24575, 32767], Format.new(:mono, :pcm_16, 44100))
+    b.convert!(Format.new(:mono, :pcm_24, 44100))
+    assert_equal([-8388608, -6291456, -4194304, -2097152, 0, 2097152, 4194304, 6291200, 8388352], b.samples)
+
+    # Stereo
+    b = Buffer.new([[-32768, 32767], [-24576, 24575], [-16384, 16384], [-8192, 8192], [0, 0],
+                    [8192, -8192],   [16384, -16384], [24575, -24576], [32767, -32768]],
+                   Format.new(:stereo, :pcm_16, 44100))
+    b.convert!(Format.new(:stereo, :pcm_24, 44100))
+    assert_equal([[-8388608, 8388352], [-6291456, 6291200], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
+                  [2097152, -2097152], [4194304, -4194304], [6291200, -6291456], [8388352, -8388608]],
+                 b.samples)
+  end
+
+  def test_convert_buffer_bits_per_sample_16_to_32
+    # Mono
+    b = Buffer.new([-32768, -24576, -16384, -8192, 0, 8192, 16384, 24575, 32767], Format.new(:mono, :pcm_16, 44100))
+    b.convert!(Format.new(:mono, :pcm_32, 44100))
+    assert_equal([-2147483648, -1610612736, -1073741824, -536870912, 0, 536870912, 1073741824, 1610547200, 2147418112], b.samples)
+
+    # Stereo
+    b = Buffer.new([[-32768, 32767], [-24576, 24575], [-16384, 16384], [-8192, 8192], [0, 0],
+                    [8192, -8192],   [16384, -16384], [24575, -24576], [32767, -32768]],
+                   Format.new(:stereo, :pcm_16, 44100))
+    b.convert!(Format.new(:stereo, :pcm_32, 44100))
+    assert_equal([[-2147483648, 2147418112], [-1610612736, 1610547200], [-1073741824, 1073741824], [-536870912, 536870912], [0, 0],
+                  [536870912, -536870912],   [1073741824, -1073741824], [1610547200, -1610612736], [2147418112, -2147483648]],
+                 b.samples)
+  end
+
+  def test_convert_buffer_bits_per_sample_16_to_float
+    Format::SUPPORTED_BITS_PER_SAMPLE[:float].each do |bits_per_sample|
+      float_format = "float_#{bits_per_sample}".to_sym
+
+      # Mono
+      b = Buffer.new([-32768, -24576, -16384, -8192, 0, 8192, 16384, 24575, 32767], Format.new(:mono, :pcm_16, 44100))
+      b.convert!(Format.new(:mono, float_format, 44100))
+      assert_equal([-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.749969482421875, 0.999969482421875], b.samples)
+
+      # Stereo
+      b = Buffer.new([[-32768, 32767], [-24576, 24575], [-16384, 16384], [-8192, 8192], [0, 0],
+                      [8192, -8192],   [16384, -16384], [24575, -24576], [32767, -32768]],
+                     Format.new(:stereo, :pcm_16, 44100))
+      b.convert!(Format.new(:stereo, float_format, 44100))
+      assert_equal([[-1.0, 0.999969482421875], [-0.75, 0.749969482421875], [-0.5, 0.5], [-0.25, 0.25], [0.0, 0.0],
+                    [0.25, -0.25], [0.5, -0.5], [0.749969482421875, -0.75], [0.999969482421875, -1.0]],
+                   b.samples)
+    end
+  end
+
+  def test_convert_buffer_bits_per_sample_24_to_8
+    # Mono
+    b = Buffer.new([-8388608, -6291456, -4194304, -2097152, 0, 2097152, 4194304, 6291455, 8388607],
+                   Format.new(:mono, :pcm_24, 44100))
+    b.convert!(Format.new(:mono, :pcm_8, 44100))
+    assert_equal([0, 32, 64, 96, 128, 160, 192, 223, 255], b.samples)
+
+    # Stereo
+    b = Buffer.new([[-8388608, 8388607], [-6291456, 6291455], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
+                    [2097152, -2097152], [4194304, -4194304], [6291455, -6291456], [8388607, -8388608]],
+                   Format.new(:stereo, :pcm_24, 44100))
+    b.convert!(Format.new(:stereo, :pcm_8, 44100))
+    assert_equal([[0, 255],  [32, 223], [64, 192], [96, 160], [128, 128],
+                  [160, 96], [192, 64], [223, 32], [255, 0]],
+                 b.samples)
+  end
+
+  def test_convert_buffer_bits_per_sample_24_to_16
+    # Mono
+    b = Buffer.new([-8388608, -6291456, -4194304, -2097152, 0, 2097152, 4194304, 6291455, 8388607],
+                   Format.new(:mono, :pcm_24, 44100))
+    b.convert!(Format.new(:mono, :pcm_16, 44100))
+    assert_equal([-32768, -24576, -16384, -8192, 0, 8192, 16384, 24575, 32767], b.samples)
+
+    # Stereo
+    b = Buffer.new([[-8388608, 8388607], [-6291456, 6291455], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
+                    [2097152, -2097152], [4194304, -4194304], [6291455, -6291456], [8388607, -8388608]],
+                   Format.new(:stereo, :pcm_24, 44100))
+    b.convert!(Format.new(:stereo, :pcm_16, 44100))
+    assert_equal([[-32768, 32767], [-24576, 24575], [-16384, 16384], [-8192, 8192], [0, 0],
+                  [8192, -8192],   [16384, -16384], [24575, -24576], [32767, -32768]],
+                 b.samples)
+  end
+
+  def test_convert_buffer_bits_per_sample_24_to_32
+    # Mono
+    b = Buffer.new([-8388608, -6291456, -4194304, -2097152, 0, 2097152, 4194304, 6291455, 8388607],
+                   Format.new(:mono, :pcm_24, 44100))
+    b.convert!(Format.new(:mono, :pcm_32, 44100))
+    assert_equal([-2147483648, -1610612736, -1073741824, -536870912, 0, 536870912, 1073741824, 1610612480, 2147483392], b.samples)
+
+    # Stereo
+    b = Buffer.new([[-8388608, 8388607], [-6291456, 6291455], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
+                    [2097152, -2097152], [4194304, -4194304], [6291455, -6291456], [8388607, -8388608]],
+                   Format.new(:stereo, :pcm_24, 44100))
+    b.convert!(Format.new(:stereo, :pcm_32, 44100))
+    assert_equal([[-2147483648, 2147483392], [-1610612736, 1610612480], [-1073741824, 1073741824], [-536870912, 536870912], [0, 0],
+                  [536870912, -536870912],   [1073741824, -1073741824], [1610612480, -1610612736], [2147483392, -2147483648]],
+                 b.samples)
+  end
+
+  def test_convert_buffer_bits_per_sample_24_to_float
+    Format::SUPPORTED_BITS_PER_SAMPLE[:float].each do |bits_per_sample|
+      float_format = "float_#{bits_per_sample}".to_sym
+
+      # Mono
+      b = Buffer.new([-8388608, -6291456, -4194304, -2097152, 0, 2097152, 4194304, 6291455, 8388607],
+                     Format.new(:mono, :pcm_24, 44100))
+      b.convert!(Format.new(:mono, float_format, 44100))
+      assert_equal([-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.7499998807907104, 0.9999998807907104], b.samples)
+
+      # Stereo
+      b = Buffer.new([[-8388608, 8388607], [-6291456, 6291455], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
+                      [2097152, -2097152], [4194304, -4194304], [6291455, -6291456], [8388607, -8388608]],
+                     Format.new(:stereo, :pcm_24, 44100))
+      b.convert!(Format.new(:stereo, float_format, 44100))
+      assert_equal([[-1.0, 0.9999998807907104], [-0.75, 0.7499998807907104 ], [-0.5, 0.5], [-0.25, 0.25], [0.0, 0.0],
+                    [0.25, -0.25], [0.5, -0.5], [0.7499998807907104 , -0.75], [0.9999998807907104, -1.0]],
+                   b.samples)
+    end
+  end
+
+  def test_convert_buffer_bits_per_sample_32_to_8
+    # Mono
+    b = Buffer.new([-2147483648, -1610612736, -1073741824, -536870912, 0, 536870912, 1073741824, 1610612735, 2147483647],
+                   Format.new(:mono, :pcm_32, 44100))
+    b.convert!(Format.new(:mono, :pcm_8, 44100))
+    assert_equal([0, 32, 64, 96, 128, 160, 192, 223, 255], b.samples)
+
+    # Stereo
+    b = Buffer.new([[-2147483648, 2147483647], [-1610612736, 1610612735], [-1073741824, 1073741824], [-536870912, 536870912], [0, 0],
+                    [536870912, -536870912],   [1073741824, -1073741824], [1610612735, -1610612736], [2147483647, -2147483648]],
+                   Format.new(:stereo, :pcm_32, 44100))
+    b.convert!(Format.new(:stereo, :pcm_8, 44100))
+    assert_equal([[0, 255],  [32, 223], [64, 192], [96, 160], [128, 128],
+                  [160, 96], [192, 64], [223, 32], [255, 0]],
+                 b.samples)
+  end
+
+  def test_convert_buffer_bits_per_sample_32_to_16
+    # Mono
+    b = Buffer.new([-2147483648, -1610612736, -1073741824, -536870912, 0, 536870912, 1073741824, 1610612735, 2147483647],
+                   Format.new(:mono, :pcm_32, 44100))
+    b.convert!(Format.new(:mono, :pcm_16, 44100))
+    assert_equal([-32768, -24576, -16384, -8192, 0, 8192, 16384, 24575, 32767], b.samples)
+
+    # Stereo
+    b = Buffer.new([[-2147483648, 2147483647], [-1610612736, 1610612735], [-1073741824, 1073741824], [-536870912, 536870912], [0, 0],
+                  [536870912, -536870912],   [1073741824, -1073741824], [1610612735, -1610612736], [2147483647, -2147483648]],
+                   Format.new(:stereo, :pcm_32, 44100))
+    b.convert!(Format.new(:stereo, :pcm_16, 44100))
+    assert_equal([[-32768, 32767], [-24576, 24575], [-16384, 16384], [-8192, 8192], [0, 0],
+                  [8192, -8192],   [16384, -16384], [24575, -24576], [32767, -32768]],
+                 b.samples)
+  end
+
+  def test_convert_buffer_bits_per_sample_32_to_24
+    # Mono
+    b = Buffer.new([-2147483648, -1610612736, -1073741824, -536870912, 0, 536870912, 1073741824, 1610612735, 2147483647],
+                   Format.new(:mono, :pcm_32, 44100))
+    b.convert!(Format.new(:mono, :pcm_24, 44100))
+    assert_equal([-8388608, -6291456, -4194304, -2097152, 0, 2097152, 4194304, 6291455, 8388607], b.samples)
+
+    # Stereo
+    b = Buffer.new([[-2147483648, 2147483647], [-1610612736, 1610612735], [-1073741824, 1073741824], [-536870912, 536870912], [0, 0],
+                  [536870912, -536870912],   [1073741824, -1073741824], [1610612735, -1610612736], [2147483647, -2147483648]],
+                   Format.new(:stereo, :pcm_32, 44100))
+    b.convert!(Format.new(:stereo, :pcm_24, 44100))
+    assert_equal([[-8388608, 8388607], [-6291456, 6291455], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
+                  [2097152, -2097152],   [4194304, -4194304], [6291455, -6291456], [8388607, -8388608]],
+                 b.samples)
+  end
+
+  def test_convert_buffer_bits_per_sample_32_to_float
+    Format::SUPPORTED_BITS_PER_SAMPLE[:float].each do |bits_per_sample|
+      float_format = "float_#{bits_per_sample}".to_sym
+
+      # Mono
+      b = Buffer.new([-2147483648, -1610612736, -1073741824, -536870912, 0, 536870912, 1073741824, 1610612735, 2147483647],
+                     Format.new(:mono, :pcm_32, 44100))
+      b.convert!(Format.new(:mono, float_format, 44100))
+      assert_equal([-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.7499999995343387, 0.9999999995343387], b.samples)
+
+      # Stereo
+      b = Buffer.new([[-2147483648, 2147483647], [-1610612736, 1610612735], [-1073741824, 1073741824], [-536870912, 536870912], [0, 0],
+                      [536870912, -536870912],   [1073741824, -1073741824], [1610612735, -1610612736], [2147483647, -2147483648]],
+                     Format.new(:stereo, :pcm_32, 44100))
+      b.convert!(Format.new(:stereo, float_format, 44100))
+      assert_equal([[-1.0, 0.9999999995343387], [-0.75, 0.7499999995343387], [-0.5, 0.5], [-0.25, 0.25], [0.0, 0.0],
+                    [0.25, -0.25], [0.5, -0.5], [0.7499999995343387, -0.75], [0.9999999995343387, -1.0]],
+                   b.samples)
+    end
+  end
+
+  def test_convert_buffer_bits_per_sample_float_to_8
+    Format::SUPPORTED_BITS_PER_SAMPLE[:float].each do |bits_per_sample|
+      float_format = "float_#{bits_per_sample}".to_sym
+
+      # Mono
+      b = Buffer.new([-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0], Format.new(:mono, float_format, 44100))
+      b.convert!(Format.new(:mono, :pcm_8, 44100))
+      assert_equal([1, 33, 64, 96, 128, 160, 192, 223, 255], b.samples)
+
+      # Stereo
+      b = Buffer.new([[-1.0, 1.0], [-0.75, 0.75], [-0.5, 0.5], [-0.25, 0.25], [0.0, 0.0],
+                      [0.25, -0.25],   [0.5, -0.5], [0.75, -0.75], [1.0, -1.0]],
+                     Format.new(:stereo, float_format, 44100))
+      b.convert!(Format.new(:stereo, :pcm_8, 44100))
+      assert_equal([[1, 255], [33, 223], [64, 192], [96, 160], [128, 128],
+                    [160, 96], [192, 64], [223, 33], [255, 1]],
+                   b.samples)
+    end
+  end
+
+  def test_convert_buffer_bits_per_sample_float_to_16
+    Format::SUPPORTED_BITS_PER_SAMPLE[:float].each do |bits_per_sample|
+      float_format = "float_#{bits_per_sample}".to_sym
+
+      # Mono
+      b = Buffer.new([-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0], Format.new(:mono, float_format, 44100))
+      b.convert!(Format.new(:mono, :pcm_16, 44100))
+      assert_equal([-32767, -24575, -16384, -8192, 0, 8192, 16384, 24575, 32767], b.samples)
+
+      # Stereo
+      b = Buffer.new([[-1.0, 1.0], [-0.75, 0.75], [-0.5, 0.5], [-0.25, 0.25], [0.0, 0.0],
+                      [0.25, -0.25], [0.5, -0.5], [0.75, -0.75], [1.0, -1.0]],
+                     Format.new(:stereo, float_format, 44100))
+      b.convert!(Format.new(:stereo, :pcm_16, 44100))
+      assert_equal([[-32767, 32767], [-24575, 24575], [-16384, 16384], [-8192, 8192], [0, 0],
+                    [8192, -8192], [16384, -16384], [24575, -24575], [32767, -32767]],
+                   b.samples)
+    end
+  end
+
+  def test_convert_buffer_bits_per_sample_float_to_24
+    Format::SUPPORTED_BITS_PER_SAMPLE[:float].each do |bits_per_sample|
+      float_format = "float_#{bits_per_sample}".to_sym
+
+      # Mono
+      b = Buffer.new([-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0], Format.new(:mono, float_format, 44100))
+      b.convert!(Format.new(:mono, :pcm_24, 44100))
+      assert_equal([-8388607, -6291455, -4194304, -2097152, 0, 2097152, 4194304, 6291455, 8388607], b.samples)
+
+      # Stereo
+      b = Buffer.new([[-1.0, 1.0], [-0.75, 0.75], [-0.5, 0.5], [-0.25, 0.25], [0.0, 0.0],
+                      [0.25, -0.25], [0.5, -0.5], [0.75, -0.75], [1.0, -1.0]],
+                     Format.new(:stereo, float_format, 44100))
+      b.convert!(Format.new(:stereo, :pcm_24, 44100))
+      assert_equal([[-8388607, 8388607], [-6291455, 6291455], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
+                    [2097152, -2097152], [4194304, -4194304], [6291455, -6291455], [8388607, -8388607]],
+                   b.samples)
+    end
+  end
+
+  def test_convert_buffer_bits_per_sample_float_to_32
+    Format::SUPPORTED_BITS_PER_SAMPLE[:float].each do |bits_per_sample|
+      float_format = "float_#{bits_per_sample}".to_sym
+
+      # Mono
+      b = Buffer.new([-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0], Format.new(:mono, float_format, 44100))
+      b.convert!(Format.new(:mono, :pcm_32, 44100))
+      assert_equal([-2147483647, -1610612735, -1073741824, -536870912, 0, 536870912, 1073741824, 1610612735, 2147483647], b.samples)
+
+      # Stereo
+      b = Buffer.new([[-1.0, 1.0], [-0.75, 0.75], [-0.5, 0.5], [-0.25, 0.25], [0.0, 0.0],
+                      [0.25, -0.25], [0.5, -0.5], [0.75, -0.75], [1.0, -1.0]],
+                     Format.new(:stereo, float_format, 44100))
+      b.convert!(Format.new(:stereo, :pcm_32, 44100))
+      assert_equal([[-2147483647, 2147483647], [-1610612735, 1610612735], [-1073741824, 1073741824], [-536870912, 536870912], [0, 0],
+                    [536870912, -536870912], [1073741824, -1073741824], [1610612735, -1610612735], [2147483647, -2147483647]],
+                   b.samples)
+    end
+  end
+end
diff --git a/app/server/vendor/wavefile-0.7.0/test/duration_test.rb b/app/server/vendor/wavefile-0.7.0/test/duration_test.rb
new file mode 100644
index 0000000..411cc31
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/test/duration_test.rb
@@ -0,0 +1,73 @@
+require 'minitest/autorun'
+require 'wavefile.rb'
+
+include WaveFile
+
+class DurationTest < MiniTest::Unit::TestCase
+  SECONDS_IN_MINUTE = 60
+  SECONDS_IN_HOUR = SECONDS_IN_MINUTE * 60
+
+  def test_constructor
+    # Test common sample rates (22050 and 44100), and some crazy arbitrary sample rate (12346)
+    [22050, 44100, 12346].each do |sample_rate|
+      duration = Duration.new(0, sample_rate)
+      assert_equal(0, duration.hours)
+      assert_equal(0, duration.minutes)
+      assert_equal(0, duration.seconds)
+      assert_equal(0, duration.milliseconds)
+      assert_equal(0, duration.sample_frame_count)
+      assert_equal(sample_rate, duration.sample_rate)
+
+      duration = Duration.new(sample_rate / 2, sample_rate)
+      assert_equal(0, duration.hours)
+      assert_equal(0, duration.minutes)
+      assert_equal(0, duration.seconds)
+      assert_equal(500, duration.milliseconds)
+      assert_equal(sample_rate / 2, duration.sample_frame_count)
+      assert_equal(sample_rate, duration.sample_rate)
+
+      duration = Duration.new(sample_rate, sample_rate)
+      assert_equal(0, duration.hours)
+      assert_equal(0, duration.minutes)
+      assert_equal(1, duration.seconds)
+      assert_equal(0, duration.milliseconds)
+      assert_equal(sample_rate, duration.sample_frame_count)
+      assert_equal(sample_rate, duration.sample_rate)
+
+      duration = Duration.new(sample_rate * SECONDS_IN_MINUTE, sample_rate)
+      assert_equal(0, duration.hours)
+      assert_equal(1, duration.minutes)
+      assert_equal(0, duration.seconds)
+      assert_equal(0, duration.milliseconds)
+      assert_equal(sample_rate * SECONDS_IN_MINUTE, duration.sample_frame_count)
+      assert_equal(sample_rate, duration.sample_rate)
+
+      duration = Duration.new(sample_rate * SECONDS_IN_HOUR, sample_rate)
+      assert_equal(1, duration.hours)
+      assert_equal(0, duration.minutes)
+      assert_equal(0, duration.seconds)
+      assert_equal(0, duration.milliseconds)
+      assert_equal(sample_rate * SECONDS_IN_HOUR, duration.sample_frame_count)
+      assert_equal(sample_rate, duration.sample_rate)
+
+      sample_frame_count = (sample_rate * SECONDS_IN_MINUTE) + sample_rate + (sample_rate / 2)
+      duration = Duration.new(sample_frame_count, sample_rate)
+      assert_equal(0, duration.hours)
+      assert_equal(1, duration.minutes)
+      assert_equal(1, duration.seconds)
+      assert_equal(500, duration.milliseconds)
+      assert_equal(sample_frame_count, duration.sample_frame_count)
+      assert_equal(sample_rate, duration.sample_rate)
+    end
+
+    # Test for when the number of hours is more than a day.
+    samples_per_hour = 44100 * 60 * 60
+    duration = Duration.new(samples_per_hour * 25, 44100)
+    assert_equal(25, duration.hours)
+    assert_equal(0, duration.minutes)
+    assert_equal(0, duration.seconds)
+    assert_equal(0, duration.milliseconds)
+    assert_equal(samples_per_hour * 25, duration.sample_frame_count)
+    assert_equal(44100, duration.sample_rate)
+  end
+end
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/actual_output/no_samples.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/actual_output/no_samples.wav
new file mode 100644
index 0000000..e1e59e1
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/actual_output/no_samples.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/README.markdown b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/README.markdown
new file mode 100644
index 0000000..a9f2a16
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/README.markdown
@@ -0,0 +1,10 @@
+The files in this folder are not valid wave files, and should not be readable by the WaveFile gem and other audio tools/programs.
+
+* **empty.wav** - An empty file, size of 0 bytes.
+* **incomplete_riff_header.wav** - The file consists of the characters "RIFF" and nothing else.
+* **bad_riff_header.wav** - The first four bytes in the file are not "RIFF", which is a magic number required for wave files.
+* **bad_wavefile_format.wav** - The format code inside the RIFF header is not "WAVE".
+* **no_format_chunk.wav** - The file contains a valid RIFF header, but not after that.
+* **empty_format_chunk.wav** - The format chunk has no data in it, despite the format chunk header indicating is is 16 bytes long.
+* **insufficient_format_chunk.wav** - The format chunk has some data, but not the minimum amount required.
+* **no_data_chunk.wav** - The RIFF header and format chunk are valid, but there is no data chunk.
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/bad_riff_header.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/bad_riff_header.wav
new file mode 100644
index 0000000..935a4cb
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/bad_riff_header.wav
@@ -0,0 +1 @@
+This is not a wave file
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/bad_wavefile_format.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/bad_wavefile_format.wav
new file mode 100644
index 0000000..3c626b2
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/bad_wavefile_format.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/empty.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/empty.wav
new file mode 100644
index 0000000..e69de29
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/empty_format_chunk.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/empty_format_chunk.wav
new file mode 100644
index 0000000..254bedb
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/empty_format_chunk.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/incomplete_riff_header.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/incomplete_riff_header.wav
new file mode 100644
index 0000000..f515e17
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/incomplete_riff_header.wav
@@ -0,0 +1 @@
+RIFF
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/insufficient_format_chunk.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/insufficient_format_chunk.wav
new file mode 100644
index 0000000..d03fbd2
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/insufficient_format_chunk.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/no_data_chunk.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/no_data_chunk.wav
new file mode 100644
index 0000000..40ad36f
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/no_data_chunk.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/no_format_chunk.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/no_format_chunk.wav
new file mode 100644
index 0000000..dd3e4df
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/invalid/no_format_chunk.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/README.markdown b/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/README.markdown
new file mode 100644
index 0000000..40e86b1
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/README.markdown
@@ -0,0 +1,6 @@
+The files in this folder are wave files that do not violate the wave file spec, but can not be read by the WaveFile gem.
+
+* **unsupported_audio_format.wav** - The audio format defined in the format chunk is 2, or ADPCM. While a valid format, this gem only supports 1 (PCM).
+* **unsupported_bits_per_sample.wav** - The bits per sample is 24. While this is a valid sample rate, this gem only supports 8, 16, and 32 bits per sample.
+* **bad_channel_count.wav** - The channel count defined in the format chunk is 0.
+* **bad_sample_rate.wav** - The sample rate defined in the format chunk is 0.
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/bad_audio_format.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/bad_audio_format.wav
new file mode 100644
index 0000000..2943609
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/bad_audio_format.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/bad_channel_count.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/bad_channel_count.wav
new file mode 100644
index 0000000..4b0f81f
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/bad_channel_count.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/bad_sample_rate.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/bad_sample_rate.wav
new file mode 100644
index 0000000..851b636
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/bad_sample_rate.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/unsupported_audio_format.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/unsupported_audio_format.wav
new file mode 100644
index 0000000..c7ba136
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/unsupported_audio_format.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/unsupported_bits_per_sample.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/unsupported_bits_per_sample.wav
new file mode 100644
index 0000000..8060052
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/unsupported/unsupported_bits_per_sample.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/README.markdown b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/README.markdown
new file mode 100644
index 0000000..975951a
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/README.markdown
@@ -0,0 +1,3 @@
+The files in this folder are valid wave files that the WaveFile gem should be able to read.
+
+Note that these files won't necessarily sound like anything if you play them. They intentionally have a small amount of sample data to make tests easy to write and test failures easier to diagnose.
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/no_samples.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/no_samples.wav
new file mode 100644
index 0000000..e1e59e1
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/no_samples.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_float_32_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_float_32_44100.wav
new file mode 100644
index 0000000..b239761
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_float_32_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_float_64_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_float_64_44100.wav
new file mode 100644
index 0000000..3ca5582
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_float_64_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_16_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_16_44100.wav
new file mode 100644
index 0000000..d2c9bbc
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_16_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_16_44100_junk_chunk_with_padding_byte.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_16_44100_junk_chunk_with_padding_byte.wav
new file mode 100644
index 0000000..e15d1e5
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_16_44100_junk_chunk_with_padding_byte.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_24_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_24_44100.wav
new file mode 100644
index 0000000..8a02fbf
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_24_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_32_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_32_44100.wav
new file mode 100644
index 0000000..5d35222
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_32_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_8_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_8_44100.wav
new file mode 100644
index 0000000..6996b40
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_8_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_8_44100_with_padding_byte.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_8_44100_with_padding_byte.wav
new file mode 100644
index 0000000..330a1c8
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_mono_pcm_8_44100_with_padding_byte.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_float_32_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_float_32_44100.wav
new file mode 100644
index 0000000..117e102
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_float_32_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_float_64_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_float_64_44100.wav
new file mode 100644
index 0000000..0e3c385
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_float_64_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_pcm_16_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_pcm_16_44100.wav
new file mode 100644
index 0000000..a4101ac
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_pcm_16_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_pcm_24_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_pcm_24_44100.wav
new file mode 100644
index 0000000..933cf41
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_pcm_24_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_pcm_32_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_pcm_32_44100.wav
new file mode 100644
index 0000000..801ab7a
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_pcm_32_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_pcm_8_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_pcm_8_44100.wav
new file mode 100644
index 0000000..44f3657
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_stereo_pcm_8_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_float_32_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_float_32_44100.wav
new file mode 100644
index 0000000..4730834
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_float_32_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_float_64_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_float_64_44100.wav
new file mode 100644
index 0000000..410202e
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_float_64_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_pcm_16_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_pcm_16_44100.wav
new file mode 100644
index 0000000..20fed66
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_pcm_16_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_pcm_24_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_pcm_24_44100.wav
new file mode 100644
index 0000000..d9d3667
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_pcm_24_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_pcm_32_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_pcm_32_44100.wav
new file mode 100644
index 0000000..0ea8bc3
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_pcm_32_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_pcm_8_44100.wav b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_pcm_8_44100.wav
new file mode 100644
index 0000000..9478eef
Binary files /dev/null and b/app/server/vendor/wavefile-0.7.0/test/fixtures/valid/valid_tri_pcm_8_44100.wav differ
diff --git a/app/server/vendor/wavefile-0.7.0/test/format_test.rb b/app/server/vendor/wavefile-0.7.0/test/format_test.rb
new file mode 100644
index 0000000..5df01cf
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/test/format_test.rb
@@ -0,0 +1,151 @@
+require 'minitest/autorun'
+require 'wavefile.rb'
+
+include WaveFile
+
+class FormatTest < MiniTest::Unit::TestCase
+  def test_valid_channels
+    [1, 2, 3, 4, 65535].each do |valid_channels|
+      assert_equal(valid_channels, Format.new(valid_channels, :pcm_16, 44100).channels)
+    end
+
+    assert_equal(1, Format.new(:mono, :pcm_16, 44100).channels)
+    assert_equal(2, Format.new(:stereo, :pcm_16, 44100).channels)
+  end
+
+  def test_invalid_channels
+    ["dsfsfsdf", :foo, 0, -1, 65536].each do |invalid_channels|
+      assert_raises(InvalidFormatError) { Format.new(invalid_channels, :pcm_16, 44100) }
+    end
+  end
+
+  def test_valid_sample_format
+    assert_equal(:pcm, Format.new(:mono, 8, 44100).sample_format)
+    assert_equal(:pcm, Format.new(:mono, 16, 44100).sample_format)
+    assert_equal(:pcm, Format.new(:mono, 24, 44100).sample_format)
+    assert_equal(:pcm, Format.new(:mono, 32, 44100).sample_format)
+    assert_equal(:pcm, Format.new(:mono, :pcm_8, 44100).sample_format)
+    assert_equal(:pcm, Format.new(:mono, :pcm_16, 44100).sample_format)
+    assert_equal(:pcm, Format.new(:mono, :pcm_24, 44100).sample_format)
+    assert_equal(:pcm, Format.new(:mono, :pcm_32, 44100).sample_format)
+    assert_equal(:float, Format.new(:mono, :float, 44100).sample_format)
+    assert_equal(:float, Format.new(:mono, :float_32, 44100).sample_format)
+    assert_equal(:float, Format.new(:mono, :float_64, 44100).sample_format)
+  end
+
+  def test_invalid_sample_format
+    ["dsfsfsdf", :foo, 12, :pcm_14, :float_20].each do |invalid_sample_format|
+      assert_raises(InvalidFormatError) { Format.new(:mono, invalid_sample_format, 44100) }
+    end
+  end
+
+  def test_valid_bits_per_sample
+    assert_equal(8, Format.new(:mono, 8, 44100).bits_per_sample)
+    assert_equal(16, Format.new(:mono, 16, 44100).bits_per_sample)
+    assert_equal(24, Format.new(:mono, 24, 44100).bits_per_sample)
+    assert_equal(32, Format.new(:mono, 32, 44100).bits_per_sample)
+    assert_equal(8, Format.new(:mono, :pcm_8, 44100).bits_per_sample)
+    assert_equal(16, Format.new(:mono, :pcm_16, 44100).bits_per_sample)
+    assert_equal(24, Format.new(:mono, :pcm_24, 44100).bits_per_sample)
+    assert_equal(32, Format.new(:mono, :pcm_32, 44100).bits_per_sample)
+    assert_equal(32, Format.new(:mono, :float, 44100).bits_per_sample)
+    assert_equal(32, Format.new(:mono, :float_32, 44100).bits_per_sample)
+    assert_equal(64, Format.new(:mono, :float_64, 44100).bits_per_sample)
+  end
+
+  def test_invalid_bits_per_sample
+    ["dsfsfsdf", :foo, :pcm, 0, 12, :pcm_14, :pcm_abc, :float_40].each do |invalid_sample_format|
+      assert_raises(InvalidFormatError) { Format.new(:mono, invalid_sample_format, 44100) }
+    end
+  end
+
+  def test_valid_sample_rate
+    [1, 44100, 4294967296].each do |valid_sample_rate|
+      assert_equal(valid_sample_rate, Format.new(:mono, :pcm_16, valid_sample_rate).sample_rate)
+    end
+  end
+
+  def test_invalid_sample_rate
+    ["dsfsfsdf", :foo, 0, -1, 4294967297].each do |invalid_sample_rate|
+      assert_raises(InvalidFormatError) { Format.new(:mono, :pcm_16, invalid_sample_rate) }
+    end
+  end
+
+  def test_byte_and_block_align
+    [1, :mono].each do |one_channel|
+      [:pcm_8, 8].each do |format_code|
+        format = Format.new(one_channel, format_code, 44100)
+        assert_equal(44100, format.byte_rate)
+        assert_equal(1, format.block_align)
+      end
+
+      [:pcm_16, 16].each do |format_code|
+        format = Format.new(one_channel, format_code, 44100)
+        assert_equal(88200, format.byte_rate)
+        assert_equal(2, format.block_align)
+      end
+
+      [:pcm_24, 24].each do |format_code|
+        format = Format.new(one_channel, format_code, 44100)
+        assert_equal(132300, format.byte_rate)
+        assert_equal(3, format.block_align)
+      end
+
+      [:pcm_32, 32, :float, :float_32].each do |format_code|
+        format = Format.new(one_channel, format_code, 44100)
+        assert_equal(176400, format.byte_rate)
+        assert_equal(4, format.block_align)
+      end
+
+      format = Format.new(one_channel, :float_64, 44100)
+      assert_equal(352800, format.byte_rate)
+      assert_equal(8, format.block_align) 
+    end
+
+    [2, :stereo].each do |two_channels|
+      [:pcm_8, 8].each do |format_code|
+        format = Format.new(two_channels, format_code, 44100)
+        assert_equal(88200, format.byte_rate)
+        assert_equal(2, format.block_align)
+      end
+
+      [:pcm_16, 16].each do |format_code|
+        format = Format.new(two_channels, format_code, 44100)
+        assert_equal(176400, format.byte_rate)
+        assert_equal(4, format.block_align)
+      end
+
+      [:pcm_24, 24].each do |format_code|
+        format = Format.new(two_channels, format_code, 44100)
+        assert_equal(264600, format.byte_rate)
+        assert_equal(6, format.block_align)
+      end
+
+      [:pcm_32, 32, :float, :float_32].each do |format_code|
+        format = Format.new(two_channels, format_code, 44100)
+        assert_equal(352800, format.byte_rate)
+        assert_equal(8, format.block_align)
+      end
+
+      format = Format.new(two_channels, :float_64, 44100)
+      assert_equal(705600, format.byte_rate)
+      assert_equal(16, format.block_align)
+    end
+  end
+
+  def test_mono?
+    [1, :mono].each do |one_channel|
+      format = Format.new(one_channel, :pcm_8, 44100)
+      assert_equal(true, format.mono?)
+      assert_equal(false, format.stereo?)
+    end
+  end
+
+  def test_stereo?
+    [2, :stereo].each do |two_channels|
+      format = Format.new(two_channels, :pcm_8, 44100)
+      assert_equal(false, format.mono?)
+      assert_equal(true, format.stereo?)
+    end
+  end
+end
diff --git a/app/server/vendor/wavefile-0.7.0/test/reader_test.rb b/app/server/vendor/wavefile-0.7.0/test/reader_test.rb
new file mode 100644
index 0000000..dcf6dd0
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/test/reader_test.rb
@@ -0,0 +1,375 @@
+require 'minitest/autorun'
+require 'wavefile.rb'
+require 'wavefile_io_test_helper.rb'
+
+include WaveFile
+
+class ReaderTest < MiniTest::Unit::TestCase
+  include WaveFileIOTestHelper
+
+  FIXTURE_ROOT_PATH = "test/fixtures"
+
+
+  def test_nonexistent_file
+    assert_raises(Errno::ENOENT) { Reader.new(fixture("i_do_not_exist.wav")) }
+  end
+
+  def test_invalid_formats
+    invalid_fixtures = [
+      # File contains 0 bytes
+      "invalid/empty.wav",
+
+      # File consists of "RIFF" and nothing else
+      "invalid/incomplete_riff_header.wav",
+
+      # First 4 bytes in the file are not "RIFF"
+      "invalid/bad_riff_header.wav",
+
+      # The format code in the RIFF header is not "WAVE"
+      "invalid/bad_wavefile_format.wav",
+
+      # The file consists of just a valid RIFF header
+      "invalid/no_format_chunk.wav",
+
+      # The format chunk has 0 bytes in it (despite the chunk size being 16)
+      "invalid/empty_format_chunk.wav",
+
+      # The format chunk has some data, but not all of the minimum required.
+      "invalid/insufficient_format_chunk.wav",
+
+      # The RIFF header and format chunk are OK, but there is no data chunk
+      "invalid/no_data_chunk.wav",
+    ]
+
+    # Reader.new and Reader.info should raise the same errors for invalid files,
+    # so run the tests for both methods.
+    invalid_fixtures.each do |fixture_name|
+      assert_raises(InvalidFormatError) { Reader.new(fixture(fixture_name)) }
+    end
+  end
+
+  def test_unsupported_formats
+    unsupported_fixtures = [
+      # Audio format is 2, which is not supported
+      "unsupported/unsupported_audio_format.wav",
+
+      # Bits per sample is 20, which is not supported
+      "unsupported/unsupported_bits_per_sample.wav",
+
+      # Channel count is 0
+      "unsupported/bad_channel_count.wav",
+
+      # Sample rate is 0
+      "unsupported/bad_sample_rate.wav",
+    ]
+
+    unsupported_fixtures.each do |fixture_name|
+      reader = Reader.new(fixture(fixture_name))
+      assert_equal(false, reader.readable_format?)
+      assert_raises(UnsupportedFormatError) { reader.read(1024) }
+      assert_raises(UnsupportedFormatError) { reader.each_buffer(1024) {|buffer| buffer } }
+    end
+  end
+
+  def test_initialize_unsupported_format
+    file_name = fixture("unsupported/unsupported_bits_per_sample.wav")
+
+    # Unsupported format, no read format given
+    reader = Reader.new(file_name)
+    assert_equal(2, reader.native_format.channels)
+    assert_equal(20, reader.native_format.bits_per_sample)
+    assert_equal(44100, reader.native_format.sample_rate)
+    assert_equal(2, reader.format.channels)
+    assert_equal(20, reader.format.bits_per_sample)
+    assert_equal(44100, reader.format.sample_rate)
+    assert_equal(false, reader.closed?)
+    assert_equal(file_name, reader.file_name)
+    assert_equal(0, reader.current_sample_frame)
+    assert_equal(2240, reader.total_sample_frames)
+    assert_equal(false, reader.readable_format?)
+    reader.close
+
+    # Unsupported format, different read format given
+    reader = Reader.new(file_name, Format.new(:mono, :pcm_16, 22050))
+    assert_equal(2, reader.native_format.channels)
+    assert_equal(20, reader.native_format.bits_per_sample)
+    assert_equal(44100, reader.native_format.sample_rate)
+    assert_equal(1, reader.format.channels)
+    assert_equal(16, reader.format.bits_per_sample)
+    assert_equal(22050, reader.format.sample_rate)
+    assert_equal(false, reader.closed?)
+    assert_equal(file_name, reader.file_name)
+    assert_equal(0, reader.current_sample_frame)
+    assert_equal(2240, reader.total_sample_frames)
+    assert_equal(false, reader.readable_format?)
+    reader.close
+  end
+
+  def test_initialize
+    format = Format.new(:stereo, :pcm_16, 22050)
+
+    exhaustively_test do |channels, sample_format|
+      file_name = fixture("valid/valid_#{channels}_#{sample_format}_44100.wav")
+
+      # Native format
+      reader = Reader.new(file_name)
+      assert_equal(CHANNEL_ALIAS[channels], reader.native_format.channels)
+      assert_equal(extract_bits_per_sample(sample_format), reader.native_format.bits_per_sample)
+      assert_equal(44100, reader.native_format.sample_rate)
+      assert_equal(CHANNEL_ALIAS[channels], reader.format.channels)
+      assert_equal(extract_bits_per_sample(sample_format), reader.format.bits_per_sample)
+      assert_equal(44100, reader.format.sample_rate)
+      assert_equal(false, reader.closed?)
+      assert_equal(file_name, reader.file_name)
+      assert_equal(0, reader.current_sample_frame)
+      assert_equal(2240, reader.total_sample_frames)
+      assert_equal(true, reader.readable_format?)
+      reader.close
+
+      # Non-native format
+      reader = Reader.new(file_name, format)
+      assert_equal(CHANNEL_ALIAS[channels], reader.native_format.channels)
+      assert_equal(extract_bits_per_sample(sample_format), reader.native_format.bits_per_sample)
+      assert_equal(44100, reader.native_format.sample_rate)
+      assert_equal(2, reader.format.channels)
+      assert_equal(16, reader.format.bits_per_sample)
+      assert_equal(22050, reader.format.sample_rate)
+      assert_equal(false, reader.closed?)
+      assert_equal(file_name, reader.file_name)
+      assert_equal(0, reader.current_sample_frame)
+      assert_equal(2240, reader.total_sample_frames)
+      assert_equal(true, reader.readable_format?)
+      reader.close
+
+      # Block is given.
+      reader = Reader.new(file_name) {|reader| reader.read(1024) }
+      assert_equal(CHANNEL_ALIAS[channels], reader.native_format.channels)
+      assert_equal(extract_bits_per_sample(sample_format), reader.native_format.bits_per_sample)
+      assert_equal(44100, reader.native_format.sample_rate)
+      assert_equal(CHANNEL_ALIAS[channels], reader.format.channels)
+      assert_equal(extract_bits_per_sample(sample_format), reader.format.bits_per_sample)
+      assert_equal(44100, reader.format.sample_rate)
+      assert(reader.closed?)
+      assert_equal(file_name, reader.file_name)
+      assert_equal(1024, reader.current_sample_frame)
+      assert_equal(2240, reader.total_sample_frames)
+      assert_equal(true, reader.readable_format?)
+    end
+  end
+
+  def test_read_native_format
+    exhaustively_test do |channels, sample_format|
+      buffers = read_file("valid/valid_#{channels}_#{sample_format}_44100.wav", 1024)
+
+      assert_equal(3, buffers.length)
+      assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
+      assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 128, buffers[0].samples)
+      assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 128, buffers[1].samples)
+      assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 24,  buffers[2].samples)
+    end
+  end
+
+  def test_read_with_format_conversion
+    buffers = read_file("valid/valid_mono_pcm_16_44100.wav", 1024, Format.new(:stereo, :pcm_8, 22100))
+
+    assert_equal(3, buffers.length)
+    assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
+    assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_8] * 128, buffers[0].samples)
+    assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_8] * 128, buffers[1].samples)
+    assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_8] * 24,  buffers[2].samples)
+  end
+
+  def test_read_with_padding_byte
+    buffers = read_file("valid/valid_mono_pcm_8_44100_with_padding_byte.wav", 1024)
+
+    assert_equal(3, buffers.length)
+    assert_equal([1024, 1024, 191], buffers.map {|buffer| buffer.samples.length })
+    assert_equal(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 128, buffers[0].samples)
+    assert_equal(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 128, buffers[1].samples)
+    assert_equal((SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 23) + [88, 88, 88, 88, 167, 167, 167],
+                 buffers[2].samples)
+  end
+
+  def test_each_buffer_no_block_given
+    reader = Reader.new(fixture("valid/valid_mono_pcm_16_44100.wav"))
+    assert_raises(LocalJumpError) { reader.each_buffer(1024) }
+  end
+
+  def test_each_buffer_native_format
+    exhaustively_test do |channels, sample_format|
+      reader = Reader.new(fixture("valid/valid_#{channels}_#{sample_format}_44100.wav"))
+
+      buffers = []
+      reader.each_buffer(1024) {|buffer| buffers << buffer }
+
+      assert(reader.closed?)
+      assert_equal(3, buffers.length)
+      assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
+      assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 128, buffers[0].samples)
+      assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 128, buffers[1].samples)
+      assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 24,  buffers[2].samples)
+      assert_equal(2240, reader.current_sample_frame)
+      assert_equal(2240, reader.total_sample_frames)
+    end
+  end
+
+  def test_each_buffer_with_format_conversion
+    reader = Reader.new(fixture("valid/valid_mono_pcm_16_44100.wav"), Format.new(:stereo, :pcm_8, 22050))
+    assert_equal(2, reader.format.channels)
+    assert_equal(8, reader.format.bits_per_sample)
+    assert_equal(22050, reader.format.sample_rate)
+
+    buffers = []
+    reader.each_buffer(1024) {|buffer| buffers << buffer }
+
+    assert_equal(3, buffers.length)
+    assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
+    assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_8] * 128, buffers[0].samples)
+    assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_8] * 128, buffers[1].samples)
+    assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_8] * 24,  buffers[2].samples)
+    assert_equal(2240, reader.current_sample_frame)
+    assert_equal(2240, reader.total_sample_frames)
+  end
+
+  def test_each_buffer_with_padding_byte
+    buffers = []
+    reader = Reader.new(fixture("valid/valid_mono_pcm_8_44100_with_padding_byte.wav"))
+    reader.each_buffer(1024) {|buffer| buffers << buffer }
+
+    assert_equal(3, buffers.length)
+    assert_equal([1024, 1024, 191], buffers.map {|buffer| buffer.samples.length })
+    assert_equal(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 128, buffers[0].samples)
+    assert_equal(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 128, buffers[1].samples)
+    assert_equal((SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 23) + [88, 88, 88, 88, 167, 167, 167],
+                 buffers[2].samples)
+    assert_equal(2239, reader.current_sample_frame)
+    assert_equal(2239, reader.total_sample_frames)
+  end
+
+  def test_read_non_data_chunk_with_padding_byte
+    # This fixture file contains a JUNK chunk with an odd size, aligned to an even number of
+    # bytes via an appended padding byte. If the padding byte is not taken into account, this
+    # test will blow up due to the file not being synced up to the data chunk in the right place.
+    reader = Reader.new(fixture("valid/valid_mono_pcm_16_44100_junk_chunk_with_padding_byte.wav"))
+    buffer = reader.read(1024)
+    assert_equal(buffer.samples, SQUARE_WAVE_CYCLE[:mono][:pcm_16] * 128)
+    assert_equal(1024, reader.current_sample_frame)
+    assert_equal(2240, reader.total_sample_frames)
+  end
+
+  def test_closed?
+    reader = Reader.new(fixture("valid/valid_mono_pcm_16_44100.wav"))
+    assert_equal(false, reader.closed?)
+    reader.close
+    assert(reader.closed?)
+
+    # For Reader.each_buffer
+    reader = Reader.new(fixture("valid/valid_mono_pcm_16_44100.wav"))
+    assert_equal(false, reader.closed?)
+    reader.each_buffer(1024) do |buffer|
+      # No-op
+    end
+    assert_equal(true, reader.closed?)
+  end
+
+  def test_read_after_close
+    reader = Reader.new(fixture("valid/valid_mono_pcm_16_44100.wav"))
+    buffer = reader.read(1024)
+    reader.close
+    assert_raises(IOError) { reader.read(1024) }
+  end
+
+  def test_sample_counts_manual_reads
+    exhaustively_test do |channels, sample_format|
+      reader = Reader.new(fixture("valid/valid_#{channels}_#{sample_format}_44100.wav"))
+      
+      assert_equal(0, reader.current_sample_frame)
+      assert_equal(2240, reader.total_sample_frames)
+      test_duration({:hours => 0, :minutes => 0, :seconds => 0, :milliseconds => 50, :sample_count => 2240},
+                    reader.total_duration)
+
+
+      reader.read(1024)
+      assert_equal(1024, reader.current_sample_frame)
+      assert_equal(2240, reader.total_sample_frames)
+      test_duration({:hours => 0, :minutes => 0, :seconds => 0, :milliseconds => 50, :sample_count => 2240},
+                    reader.total_duration)
+
+
+      reader.read(1024)
+      assert_equal(2048, reader.current_sample_frame)
+      assert_equal(2240, reader.total_sample_frames)
+      test_duration({:hours => 0, :minutes => 0, :seconds => 0, :milliseconds => 50, :sample_count => 2240},
+                    reader.total_duration)
+
+
+      reader.read(192)
+      assert_equal(2240, reader.current_sample_frame)
+      assert_equal(2240, reader.total_sample_frames)
+      test_duration({:hours => 0, :minutes => 0, :seconds => 0, :milliseconds => 50, :sample_count => 2240},
+                    reader.total_duration)
+ 
+
+      reader.close
+      assert_equal(2240, reader.current_sample_frame)
+      assert_equal(2240, reader.total_sample_frames)
+      test_duration({:hours => 0, :minutes => 0, :seconds => 0, :milliseconds => 50, :sample_count => 2240},
+                    reader.total_duration)
+    end
+  end
+
+  def test_sample_counts_each_buffer
+    exhaustively_test do |channels, sample_format|
+      expected_results = [ 1024, 2048, 2240 ]
+
+      file_name = fixture("valid/valid_#{channels}_#{sample_format}_44100.wav")
+      reader = Reader.new(file_name)
+
+      assert_equal(0, reader.current_sample_frame)
+      assert_equal(2240, reader.total_sample_frames)
+
+      reader.each_buffer(1024) do |buffer|
+        expected_result = expected_results.slice!(0)
+
+        assert_equal(expected_result, reader.current_sample_frame)
+        assert_equal(2240, reader.total_sample_frames)
+      end
+      
+      assert_equal(2240, reader.current_sample_frame)
+      assert_equal(2240, reader.total_sample_frames)
+    end
+  end
+
+private
+
+  def read_file(file_name, buffer_size, format=nil)
+    buffers = []
+    reader = Reader.new(fixture(file_name), format)
+
+    begin
+      while true do
+        buffers << reader.read(buffer_size)
+      end
+    rescue EOFError
+      reader.close
+    end
+
+    return buffers
+  end
+
+  def fixture(fixture_name)
+    return "#{FIXTURE_ROOT_PATH}/#{fixture_name}"
+  end
+
+  def extract_bits_per_sample(sample_format)
+    sample_format.to_s.split("_").last.to_i
+  end
+
+  def test_duration(expected_hash, duration)
+    assert_equal(expected_hash[:hours], duration.hours)
+    assert_equal(expected_hash[:minutes], duration.minutes)
+    assert_equal(expected_hash[:seconds], duration.seconds)
+    assert_equal(expected_hash[:milliseconds], duration.milliseconds)
+    assert_equal(expected_hash[:sample_count], duration.sample_frame_count)
+  end
+end
diff --git a/app/server/vendor/wavefile-0.7.0/test/unvalidated_format_test.rb b/app/server/vendor/wavefile-0.7.0/test/unvalidated_format_test.rb
new file mode 100644
index 0000000..4447eb7
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/test/unvalidated_format_test.rb
@@ -0,0 +1,24 @@
+require 'minitest/autorun'
+require 'wavefile.rb'
+
+include WaveFile
+
+class UnvalidatedFormatTest < MiniTest::Unit::TestCase
+  def test_initialize
+    format = UnvalidatedFormat.new({:audio_format => 1,
+                                    :channels => 2,
+                                    :sample_rate => 44100,
+                                    :byte_rate => 176400,
+                                    :block_align => 4,
+                                    :bits_per_sample => 16})
+
+    assert_equal(1,      format.audio_format)
+    assert_equal(2,      format.channels)
+    assert_equal(false,  format.mono?)
+    assert_equal(true,   format.stereo?)
+    assert_equal(44100,  format.sample_rate)
+    assert_equal(176400, format.byte_rate)
+    assert_equal(4,      format.block_align)
+    assert_equal(16,     format.bits_per_sample)
+  end
+end
diff --git a/app/server/vendor/wavefile-0.7.0/test/wavefile_io_test_helper.rb b/app/server/vendor/wavefile-0.7.0/test/wavefile_io_test_helper.rb
new file mode 100644
index 0000000..940285b
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/test/wavefile_io_test_helper.rb
@@ -0,0 +1,64 @@
+module WaveFileIOTestHelper
+  CHANNEL_ALIAS = { :mono => 1, :stereo => 2, :tri => 3}
+
+  SQUARE_WAVE_CYCLE = {}
+  SQUARE_WAVE_CYCLE[:mono] = {}
+
+  SQUARE_WAVE_CYCLE[:mono][:pcm_8] =    [88, 88, 88, 88, 167, 167, 167, 167]
+  SQUARE_WAVE_CYCLE[:mono][:pcm_16] =   [-10000, -10000, -10000, -10000, 10000, 10000, 10000, 10000]
+  SQUARE_WAVE_CYCLE[:mono][:pcm_24] =   [-1000000, -1000000, -1000000, -1000000, 1000000, 1000000, 1000000, 1000000]
+  SQUARE_WAVE_CYCLE[:mono][:pcm_32] =   [-1000000000, -1000000000, -1000000000, -1000000000,
+                                          1000000000, 1000000000, 1000000000, 1000000000]
+  SQUARE_WAVE_CYCLE[:mono][:float_32] = [-0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5]
+  SQUARE_WAVE_CYCLE[:mono][:float_64] = SQUARE_WAVE_CYCLE[:mono][:float_32]
+
+  SQUARE_WAVE_CYCLE[:stereo] = {}
+  SQUARE_WAVE_CYCLE[:stereo][:pcm_8] =  [[88, 88], [88, 88], [88, 88], [88, 88],
+                                         [167, 167], [167, 167], [167, 167], [167, 167]]
+  SQUARE_WAVE_CYCLE[:stereo][:pcm_16] = [[-10000, -10000], [-10000, -10000], [-10000, -10000], [-10000, -10000],
+                                         [10000, 10000], [10000, 10000], [10000, 10000], [10000, 10000]]
+  SQUARE_WAVE_CYCLE[:stereo][:pcm_24] = [[-1000000, -1000000], [-1000000, -1000000], [-1000000, -1000000], [-1000000, -1000000],
+                                         [1000000, 1000000], [1000000, 1000000], [1000000, 1000000], [1000000, 1000000]]
+  SQUARE_WAVE_CYCLE[:stereo][:pcm_32] = [[-1000000000, -1000000000], [-1000000000, -1000000000],
+                                         [-1000000000, -1000000000], [-1000000000, -1000000000],
+                                         [ 1000000000,  1000000000], [ 1000000000,  1000000000],
+                                         [ 1000000000,  1000000000], [ 1000000000,  1000000000]]
+  SQUARE_WAVE_CYCLE[:stereo][:float_32] = [[-0.5, -0.5], [-0.5, -0.5], [-0.5, -0.5], [-0.5, -0.5],
+                                         [0.5, 0.5], [0.5, 0.5], [0.5, 0.5], [0.5, 0.5]]
+  SQUARE_WAVE_CYCLE[:stereo][:float_64] = SQUARE_WAVE_CYCLE[:stereo][:float_32]
+
+  SQUARE_WAVE_CYCLE[:tri] = {}
+  SQUARE_WAVE_CYCLE[:tri][:pcm_8] =    [[88, 88, 88], [88, 88, 88], [88, 88, 88], [88, 88, 88],
+                                    [167, 167, 167], [167, 167, 167], [167, 167, 167], [167, 167, 167]]
+  SQUARE_WAVE_CYCLE[:tri][:pcm_16] =   [[-10000, -10000, -10000], [-10000, -10000, -10000],
+                                        [-10000, -10000, -10000], [-10000, -10000, -10000],
+                                        [ 10000,  10000,  10000], [ 10000,  10000,  10000],
+                                        [ 10000,  10000,  10000], [ 10000,  10000,  10000]]
+  SQUARE_WAVE_CYCLE[:tri][:pcm_24] =   [[-1000000, -1000000, -1000000], [-1000000, -1000000, -1000000],
+                                        [-1000000, -1000000, -1000000], [-1000000, -1000000, -1000000],
+                                        [ 1000000,  1000000,  1000000], [ 1000000,  1000000,  1000000],
+                                        [ 1000000,  1000000,  1000000], [ 1000000,  1000000,  1000000]]
+  SQUARE_WAVE_CYCLE[:tri][:pcm_32] =   [[-1000000000, -1000000000, -1000000000],
+                                        [-1000000000, -1000000000, -1000000000],
+                                        [-1000000000, -1000000000, -1000000000],
+                                        [-1000000000, -1000000000, -1000000000],
+                                        [ 1000000000,  1000000000,  1000000000],
+                                        [ 1000000000,  1000000000,  1000000000],
+                                        [ 1000000000,  1000000000,  1000000000],
+                                        [ 1000000000,  1000000000,  1000000000]]
+  SQUARE_WAVE_CYCLE[:tri][:float_32] = [[-0.5, -0.5, -0.5], [-0.5, -0.5, -0.5], [-0.5, -0.5, -0.5], [-0.5, -0.5, -0.5],
+                                        [0.5, 0.5, 0.5], [0.5, 0.5, 0.5], [0.5, 0.5, 0.5], [0.5, 0.5, 0.5]]
+  SQUARE_WAVE_CYCLE[:tri][:float_64] = SQUARE_WAVE_CYCLE[:tri][:float_32]
+
+
+  # Executes the given block against different combinations of number of channels and sample_format
+  def exhaustively_test
+    [:mono, :stereo, :tri].each do |channels|
+      [:pcm, :float].each do |sample_format|
+        Format::SUPPORTED_BITS_PER_SAMPLE[sample_format].each do |bits_per_sample|
+          yield(channels, "#{sample_format}_#{bits_per_sample}".to_sym)
+        end
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/wavefile-0.7.0/test/writer_test.rb b/app/server/vendor/wavefile-0.7.0/test/writer_test.rb
new file mode 100644
index 0000000..18ed38a
--- /dev/null
+++ b/app/server/vendor/wavefile-0.7.0/test/writer_test.rb
@@ -0,0 +1,205 @@
+require 'minitest/autorun'
+require 'wavefile.rb'
+require 'wavefile_io_test_helper.rb'
+
+include WaveFile
+
+class WriterTest < MiniTest::Unit::TestCase
+  include WaveFileIOTestHelper
+
+  OUTPUT_FOLDER = "test/fixtures/actual_output"
+
+  def setup
+    clean_output_folder
+  end
+
+  def test_write_file_with_no_sample_data
+    writer = Writer.new("#{OUTPUT_FOLDER}/no_samples.wav", Format.new(:mono, :pcm_8, 44100))
+    writer.close
+
+    assert_equal(read_file(:expected, "no_samples.wav"), read_file(:actual, "no_samples.wav"))
+  end
+
+  def test_write_basic_file
+    exhaustively_test do |channels, sample_format|
+      file_name = "valid_#{channels}_#{sample_format}_44100.wav"
+      format = Format.new(CHANNEL_ALIAS[channels], sample_format, 44100)
+
+      writer = Writer.new("#{OUTPUT_FOLDER}/#{file_name}", format)
+      writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][sample_format] * 128, format))
+      writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][sample_format] * 128, format))
+      writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][sample_format] * 24, format))
+      writer.close
+
+      assert_equal(read_file(:expected, file_name), read_file(:actual, file_name))
+    end
+  end
+
+  def test_write_basic_file_with_a_block
+    exhaustively_test do |channels, sample_format|
+      file_name = "valid_#{channels}_#{sample_format}_44100.wav"
+      format = Format.new(CHANNEL_ALIAS[channels], sample_format, 44100)
+
+      writer = Writer.new("#{OUTPUT_FOLDER}/#{file_name}", format) do |writer|
+        4.times do
+          writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][sample_format] * 70, format))
+        end
+      end
+
+      assert_equal(read_file(:expected, file_name), read_file(:actual, file_name))
+      assert(writer.closed?)
+    end
+  end
+
+  def test_write_buffers_of_different_formats
+    file_name = "valid_mono_pcm_8_44100.wav"
+    format_8bit_mono    = Format.new(:mono,   :pcm_8,  44100)
+    format_16_bit_mono  = Format.new(:mono,   :pcm_16, 22050)
+    format_16bit_stereo = Format.new(:stereo, :pcm_16, 44100)
+
+    writer = Writer.new("#{OUTPUT_FOLDER}/#{file_name}", format_8bit_mono)
+    writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:stereo][:pcm_16] * 128, format_16bit_stereo))
+    writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][:pcm_16] * 128,   format_16_bit_mono))
+    writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:stereo][:pcm_16] * 24,  format_16bit_stereo))
+    writer.close
+
+    assert_equal(read_file(:expected, file_name), read_file(:actual, file_name))
+  end
+
+  def test_write_file_with_padding_byte
+    file_name = "valid_mono_pcm_8_44100_with_padding_byte.wav"
+    format = Format.new(:mono, :pcm_8, 44100)
+
+    writer = Writer.new("#{OUTPUT_FOLDER}/#{file_name}", format)
+    writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 128, format))
+    writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 128, format))
+    writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 23 + [88, 88, 88, 88, 167, 167, 167], format))
+    writer.close
+
+    assert_equal(read_file(:expected, file_name), read_file(:actual, file_name))
+  end
+
+  def test_file_name
+    file_name = "#{OUTPUT_FOLDER}/example.wav"
+
+    writer = Writer.new(file_name, Format.new(:mono, :pcm_8, 44100))
+    assert_equal("#{OUTPUT_FOLDER}/example.wav", writer.file_name)
+
+    writer.close
+    assert_equal("#{OUTPUT_FOLDER}/example.wav", writer.file_name)
+  end
+
+  def test_closed?
+    writer = Writer.new("#{OUTPUT_FOLDER}/closed_test.wav", Format.new(:mono, :pcm_16, 44100))
+    assert_equal(false, writer.closed?)
+    writer.close
+    assert(writer.closed?)
+  end
+
+  def test_attempt_to_write_after_close
+    format = Format.new(:mono, :pcm_8, 44100)
+
+    writer = Writer.new("#{OUTPUT_FOLDER}/write_after_close.wav", format)
+    writer.write(Buffer.new([1, 2, 3, 4], format))
+    writer.close
+
+    assert_raises(IOError) { writer.write(Buffer.new([5, 6, 7, 8], format)) }
+  end
+
+  def test_total_duration
+    exhaustively_test do |channels, sample_format|
+      format = Format.new(CHANNEL_ALIAS[channels], sample_format, 44100)
+
+      writer = Writer.new("#{OUTPUT_FOLDER}/total_duration_#{channels}_#{sample_format}_44100.wav", format)
+
+      assert_equal(0, writer.total_sample_frames)
+      duration = writer.total_duration
+      assert_equal(0, duration.sample_frame_count)
+      assert_equal(44100, duration.sample_rate)
+      assert_equal(0, duration.hours)
+      assert_equal(0, duration.minutes)
+      assert_equal(0, duration.seconds)
+      assert_equal(0, duration.milliseconds)
+
+      writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][sample_format] * 2756, format))
+
+      assert_equal(8 * 2756, writer.total_sample_frames)
+      duration = writer.total_duration
+      assert_equal(8 * 2756, duration.sample_frame_count)
+      assert_equal(44100, duration.sample_rate)
+      assert_equal(0, duration.hours)
+      assert_equal(0, duration.minutes)
+      assert_equal(0, duration.seconds)
+      assert_equal(499, duration.milliseconds)
+
+      writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][sample_format] * 2756, format))
+      writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][sample_format] * 2756, format))
+
+      assert_equal(8 * 2756 * 3, writer.total_sample_frames)
+      duration = writer.total_duration
+      assert_equal(8 * 2756 * 3, duration.sample_frame_count)
+      assert_equal(44100, duration.sample_rate)
+      assert_equal(0, duration.hours)
+      assert_equal(0, duration.minutes)
+      assert_equal(1, duration.seconds)
+      assert_equal(499, duration.milliseconds)
+
+      writer.close
+
+      assert_equal(8 * 2756 * 3, writer.total_sample_frames)
+      duration = writer.total_duration
+      assert_equal(8 * 2756 * 3, duration.sample_frame_count)
+      assert_equal(44100, duration.sample_rate)
+      assert_equal(0, duration.hours)
+      assert_equal(0, duration.minutes)
+      assert_equal(1, duration.seconds)
+      assert_equal(499, duration.milliseconds)
+    end
+  end
+
+  # Cause an exception within the block passed to Writer.new, to prove
+  # that close is still called (due to an ensure statement in Writer.new).
+  def test_exception_with_block
+    format = Format.new(:mono, :pcm_8, 44100)
+    samples = [1, 2, 3, 4, 5, 6]
+    Writer.new("#{OUTPUT_FOLDER}/exception_with_block.wav", format) do |writer|
+      begin
+        writer.write(Buffer.new(samples, format))
+        1 / 0 # cause divide-by-zero exception
+      rescue
+        # catch the exception and ignore, so test passes OK
+      end
+    end
+    
+    reader = Reader.new("#{OUTPUT_FOLDER}/exception_with_block.wav")
+    assert_equal(samples.size, reader.total_sample_frames)
+  end
+
+private
+
+  def read_file(type, file_name)
+    if type == :expected
+      fixture_folder = 'valid'
+    elsif type == :actual
+      fixture_folder = 'actual_output'
+    else
+      raise 'Invalid fixture type'
+    end
+
+    # For Windows compatibility with binary files, File.read is not directly used
+    File.open("test/fixtures/#{fixture_folder}/#{file_name}", "rb") {|f| f.read }
+  end
+
+  def clean_output_folder
+    # Make the folder if it doesn't already exist
+    Dir.mkdir(OUTPUT_FOLDER) unless File.exists?(OUTPUT_FOLDER)
+
+    dir = Dir.new(OUTPUT_FOLDER)
+    file_names = dir.entries
+    file_names.each do |file_name|
+      if(file_name != "." && file_name != "..")
+        File.delete("#{OUTPUT_FOLDER}/#{file_name}")
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/.gitignore b/app/server/vendor/websocket/.gitignore
new file mode 100755
index 0000000..99c9252
--- /dev/null
+++ b/app/server/vendor/websocket/.gitignore
@@ -0,0 +1,3 @@
+Gemfile.lock
+autobahn
+pkg/*.gem
diff --git a/app/server/vendor/websocket/.travis.yml b/app/server/vendor/websocket/.travis.yml
new file mode 100755
index 0000000..5b2ddb0
--- /dev/null
+++ b/app/server/vendor/websocket/.travis.yml
@@ -0,0 +1,12 @@
+language: ruby
+script: "bundle exec rake spec"
+rvm:
+  - 1.8.7
+  - 1.9.2
+  - 1.9.3
+  - 2.0.0
+  - jruby-18mode
+  - jruby-19mode
+  - rbx-18mode
+  - rbx-19mode
+  - ree
diff --git a/app/server/vendor/websocket/CHANGELOG.md b/app/server/vendor/websocket/CHANGELOG.md
new file mode 100755
index 0000000..ddd36db
--- /dev/null
+++ b/app/server/vendor/websocket/CHANGELOG.md
@@ -0,0 +1,60 @@
+# Changelog
+
+## 1.1.2
+
+- fix support for rack input that is blocking (i.e. Passenger)
+
+## 1.1.1
+
+- fix handling close code for frames version 5+
+
+## 1.1.0
+
+- allow raising ruby errors instead of setting `error` flag
+- allow access to handshake headers
+- add from_rack method
+- add from_hash method
+- stop extending handlers - it should improve performance for opening connection
+
+## 1.0.7
+
+- fix requiring url under Ruby 1.9.1
+- support for Ruby 2.0.0
+
+## 1.0.6
+
+- support text frame types instead of only symbol ones
+- support for sending masked frames
+
+## 1.0.5
+
+- add support for close codes
+
+## 1.0.4
+
+- nicer inspect - handful during debugging
+
+## 1.0.3
+
+- improve pure ruby implementation performance by ~30%
+- add support for native extension
+
+## 1.0.2
+
+- allow configuration of max frame size via WebSocket.max_frame_size option
+- much better documentation
+- remove handler-specific methods from public list
+- refactor code for easier use
+- make parsers return more consistent values
+- fix server handshake #to_s when no version was found
+- add #uri to server handshake
+
+## 1.0.1
+
+- allow creating client with :uri and :url options
+- prevent strange results when header is mailformed
+- set client path to '/' when :uri option is provided but without trailing slash
+
+## 1.0.0
+
+- initial release
diff --git a/app/server/vendor/websocket/Gemfile b/app/server/vendor/websocket/Gemfile
new file mode 100755
index 0000000..2d129a7
--- /dev/null
+++ b/app/server/vendor/websocket/Gemfile
@@ -0,0 +1,6 @@
+source "http://rubygems.org"
+
+gemspec
+
+gem 'rake'
+gem 'rspec', '~> 2.11'
diff --git a/app/server/vendor/websocket/README.md b/app/server/vendor/websocket/README.md
new file mode 100755
index 0000000..c2ec81e
--- /dev/null
+++ b/app/server/vendor/websocket/README.md
@@ -0,0 +1,126 @@
+# WebSocket Ruby
+
+- Travis CI build: [![](https://travis-ci.org/imanel/websocket-ruby.png)](http://travis-ci.org/imanel/websocket-ruby)
+- Autobahn tests: [server](http://imanel.github.com/websocket-ruby/autobahn/server/), [client](http://imanel.github.com/websocket-ruby/autobahn/client/)
+
+Universal Ruby library to handle WebSocket protocol. It focuses on providing abstraction layer over [WebSocket API](http://dev.w3.org/html5/websockets/) instead of providing server or client functionality.
+
+Currently WebSocket Ruby supports all existing drafts of WebSocket, which include:
+
+- [hixie-75](http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75)
+- [hixie-76](http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76)
+- [all hybi drafts (00-13)](http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17)
+- [RFC 6455](http://datatracker.ietf.org/doc/rfc6455/)
+
+## Installation
+
+WebSocket Ruby has no external dependencies, so it can be installed from source or directly from rubygems:
+
+```
+gem install "websocket"
+```
+
+or via Gemfile:
+
+```
+gem "websocket"
+```
+
+## Server handshake
+
+``` ruby
+ at handshake = WebSocket::Handshake::Server.new
+
+# Parse client request
+ at handshake << <<EOF
+GET /demo HTTP/1.1\r
+Upgrade: websocket\r
+Connection: Upgrade\r
+Host: example.com\r
+Sec-WebSocket-Origin: http://example.com\r
+Sec-WebSocket-Version: 13\r
+Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r
+\r
+EOF
+
+# All data received?
+ at handshake.finished?
+
+# No parsing errors?
+ at handshake.valid?
+
+# Create response
+ at handshake.to_s # HTTP/1.1 101 Switching Protocols
+                # Upgrade: websocket
+                # Connection: Upgrade
+                # Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
+```
+
+## Client handshake
+
+``` ruby
+ at handshake = WebSocket::Handshake::Client.new(:url => 'ws://example.com')
+
+# Create request
+ at handshake.to_s # GET /demo HTTP/1.1
+                # Upgrade: websocket
+                # Connection: Upgrade
+                # Host: example.com
+                # Sec-WebSocket-Origin: http://example.com
+                # Sec-WebSocket-Version: 13
+                # Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+
+# Parse server response
+ at handshake << <<EOF
+HTTP/1.1 101 Switching Protocols\r
+Upgrade: websocket\r
+Connection: Upgrade\r
+Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r
+\r
+EOF
+
+# All data received?
+ at handshake.finished?
+
+# No parsing errors?
+ at handshake.valid?
+```
+
+## Parsing and constructing frames
+
+``` ruby
+# Prepare frame for sending
+frame = WebSocket::Frame::Outgoing::Server.new(:version => @handshake.version, :data => "Hello", :type => :text)
+frame.to_s # "\x81\x05\x48\x65\x6c\x6c\x6f"
+
+# Parse incoming frames
+frame = WebSocket::Frame::Incoming::Server.new(:version => @handshake.version)
+frame << "\x81\x05\x48\x65\x6c\x6c\x6f\x81\x06\x77\x6f\x72\x6c\x64\x21"
+frame.next # "Hello"
+frame.next # "world!""
+```
+
+## Examples & Projects using WebSocket-Ruby
+
+- [WebSocket-EventMachine-Client](https://github.com/imanel/websocket-eventmachine-client) - client based on EventMachine
+- [WebSocket-EventMachine-Server](https://github.com/imanel/websocket-eventmachine-server) - server based on EventMachine (drop-in replacement for EM-WebSocket)
+- [Selenium-WebDriver](https://rubygems.org/gems/selenium-webdriver) - tool for writing automated tests of websites
+- [Rubame](https://github.com/saward/Rubame) - websocket game server
+
+## Native extension
+
+WebSocket gem is written in pure Ruby, without any dependencies or native extensions and still is one of the fastest implementations of WebSocket API. However, if you want to increase it's speed even further, I created additional gem with dedicated native extensions for both C and Java. Those extensions provide 20-30% increase in speed(more accurate comparison can be found in autobahn test results)
+
+In order to use native extension just install [websocket-native](http://github.com/imanel/websocket-ruby-native) gem or add it to Gemfile - WebSocket will automatically detect and load it.
+
+## License
+
+(The MIT License)
+
+Copyright © 2012 Bernard Potocki
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/server/vendor/websocket/Rakefile b/app/server/vendor/websocket/Rakefile
new file mode 100755
index 0000000..e9e1137
--- /dev/null
+++ b/app/server/vendor/websocket/Rakefile
@@ -0,0 +1,23 @@
+require 'bundler'
+Bundler::GemHelper.install_tasks
+
+require 'rspec/core/rake_task'
+
+RSpec::Core::RakeTask.new do |t|
+  t.rspec_opts = ["-c", "-f progress"]
+  t.pattern = 'spec/**/*_spec.rb'
+end
+
+task :default => :spec
+
+namespace :autobahn do
+  desc "Run autobahn tests for client"
+  task :client do
+    system('wstest --mode=fuzzingserver --spec=autobahn-client.json')
+  end
+
+  desc "Run autobahn tests for server"
+  task :server do
+    system('wstest --mode=fuzzingclient --spec=autobahn-server.json')
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket.rb b/app/server/vendor/websocket/lib/websocket.rb
new file mode 100755
index 0000000..5decc7f
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket.rb
@@ -0,0 +1,44 @@
+# WebSocket protocol implementation in Ruby
+# This module does not provide a WebSocket server or client, but is made for using
+# in http servers or clients to provide WebSocket support.
+# @author Bernard "Imanel" Potocki
+# @see http://github.com/imanel/websocket-ruby main repository
+module WebSocket
+
+  # Default WebSocket version to use
+  DEFAULT_VERSION = 13
+  ROOT = File.expand_path(File.dirname(__FILE__))
+
+  autoload :Error,            "#{ROOT}/websocket/error"
+  autoload :ExceptionHandler, "#{ROOT}/websocket/exception_handler"
+  autoload :Frame,            "#{ROOT}/websocket/frame"
+  autoload :Handshake,        "#{ROOT}/websocket/handshake"
+
+  # Limit of frame size payload in bytes
+  def self.max_frame_size
+    @max_frame_size ||= 20 * 1024 * 1024 # 20MB
+  end
+
+  # Set limit of frame size payload in bytes
+  def self.max_frame_size=(val)
+    @max_frame_size = val
+  end
+
+  # If set to true error will be raised instead of setting `error` method.
+  # All errors inherit from WebSocket::Error.
+  def self.should_raise
+    @should_raise ||= false
+  end
+
+  # Should protocol errors raise ruby errors? If false then `error` flag is set instead.
+  def self.should_raise=(val)
+    @should_raise = val
+  end
+
+end
+
+# Try loading websocket-native if available
+begin
+  require "websocket-native"
+rescue LoadError
+end
diff --git a/app/server/vendor/websocket/lib/websocket/error.rb b/app/server/vendor/websocket/lib/websocket/error.rb
new file mode 100755
index 0000000..7fd14be
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/error.rb
@@ -0,0 +1,85 @@
+module WebSocket
+  class Error < RuntimeError
+
+    class Frame < ::WebSocket::Error
+
+      class ControlFramePayloadTooLong < ::WebSocket::Error::Frame
+        def message; :control_frame_payload_too_long; end
+      end
+
+      class DataFrameInsteadContinuation < ::WebSocket::Error::Frame
+        def message; :data_frame_instead_continuation; end
+      end
+
+      class FragmentedControlFrame < ::WebSocket::Error::Frame
+        def message; :fragmented_control_frame; end
+      end
+
+      class Invalid < ::WebSocket::Error::Frame
+        def message; :invalid_frame; end
+      end
+
+      class InvalidPayloadEncoding < ::WebSocket::Error::Frame
+        def message; :invalid_payload_encoding; end
+      end
+
+      class MaskTooShort < ::WebSocket::Error::Frame
+        def message; :mask_is_too_short; end
+      end
+
+      class ReservedBitUsed < ::WebSocket::Error::Frame
+        def message; :reserved_bit_used; end
+      end
+
+      class TooLong < ::WebSocket::Error::Frame
+        def message; :frame_too_long; end
+      end
+
+      class UnexpectedContinuationFrame < ::WebSocket::Error::Frame
+        def message; :unexpected_continuation_frame; end
+      end
+
+      class UnknownFrameType < ::WebSocket::Error::Frame
+        def message; :unknown_frame_type; end
+      end
+
+      class UnknownOpcode < ::WebSocket::Error::Frame
+        def message; :unknown_opcode; end
+      end
+
+      class UnknownVersion < ::WebSocket::Error::Frame
+        def message; :unknown_protocol_version; end
+      end
+
+    end
+
+    class Handshake < ::WebSocket::Error
+
+      class GetRequestRequired < ::WebSocket::Error::Handshake
+        def message; :get_request_required; end
+      end
+
+      class InvalidAuthentication < ::WebSocket::Error::Handshake
+        def message; :invalid_handshake_authentication; end
+      end
+
+      class InvalidHeader < ::WebSocket::Error::Handshake
+        def message; :invalid_header; end
+      end
+
+      class InvalidStatusCode < ::WebSocket::Error::Handshake
+        def message; :invalid_status_code; end
+      end
+
+      class NoHostProvided < ::WebSocket::Error::Handshake
+        def message; :no_host_provided; end
+      end
+
+      class UnknownVersion < ::WebSocket::Error::Handshake
+        def message; :unknown_protocol_version; end
+      end
+
+    end
+
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/exception_handler.rb b/app/server/vendor/websocket/lib/websocket/exception_handler.rb
new file mode 100755
index 0000000..53614f7
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/exception_handler.rb
@@ -0,0 +1,36 @@
+module WebSocket
+  module ExceptionHandler
+
+    attr_reader :error
+
+    def self.included(base)
+      base.extend(ClassMethods)
+    end
+
+    private
+
+    # Changes state to error and sets error message
+    # @param [String] message Error message to set
+    def set_error(message)
+      @error = message
+    end
+
+    module ClassMethods
+
+      def rescue_method(method_name, options = {})
+        define_method "#{method_name}_with_rescue" do |*args|
+          begin
+            send("#{method_name}_without_rescue", *args)
+          rescue WebSocket::Error => e
+            set_error(e.message.to_sym)
+            WebSocket.should_raise ? raise : options[:return]
+          end
+        end
+        alias_method "#{method_name}_without_rescue", method_name
+        alias_method method_name, "#{method_name}_with_rescue"
+      end
+
+    end
+
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame.rb b/app/server/vendor/websocket/lib/websocket/frame.rb
new file mode 100755
index 0000000..b4879f2
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame.rb
@@ -0,0 +1,11 @@
+module WebSocket
+  module Frame
+
+    autoload :Base,     "#{::WebSocket::ROOT}/websocket/frame/base"
+    autoload :Data,     "#{::WebSocket::ROOT}/websocket/frame/data"
+    autoload :Handler,  "#{::WebSocket::ROOT}/websocket/frame/handler"
+    autoload :Incoming, "#{::WebSocket::ROOT}/websocket/frame/incoming"
+    autoload :Outgoing, "#{::WebSocket::ROOT}/websocket/frame/outgoing"
+
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame/base.rb b/app/server/vendor/websocket/lib/websocket/frame/base.rb
new file mode 100755
index 0000000..8c706c2
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame/base.rb
@@ -0,0 +1,67 @@
+module WebSocket
+  module Frame
+    # @abstract Subclass and override to implement custom frames
+    class Base
+      include ExceptionHandler
+
+      attr_reader :type, :version
+      attr_accessor :data, :code
+
+      # Initialize frame
+      # @param args [Hash] Arguments for frame
+      # @option args [String]  :data default data for frame
+      # @option args [String]  :type Type of frame - available types are "text", "binary", "ping", "pong" and "close"(support depends on draft version)
+      # @option args [Integer] :code Code for close frame. Supported by drafts > 05.
+      # @option args [Integer] :version Version of draft. Currently supported version are 75, 76 and 00-13.
+      def initialize(args = {})
+        @type = args[:type].to_sym if args[:type]
+        @code = args[:code]
+        @data = Data.new(args[:data].to_s)
+        @version = args[:version] || DEFAULT_VERSION
+        @handler = nil
+        include_version
+      end
+      rescue_method :initialize
+
+      # Check if some errors occured
+      # @return [Boolean] True if error is set
+      def error?
+        !!@error
+      end
+
+      # Is selected type supported for selected handler?
+      def support_type?
+        @handler.supported_frames.include?(@type)
+      end
+
+      # Implement in submodules
+      def supported_frames
+        raise NotImplementedError
+      end
+
+      # Recreate inspect as #to_s was overwritten
+      def inspect
+        vars = self.instance_variables.map{|v| "#{v}=#{instance_variable_get(v).inspect}"}.join(", ")
+        insp = "#{self.class}:0x%08x" % (self.__id__ * 2)
+        "<#{insp} #{vars}>"
+      end
+
+      private
+
+      # Include set of methods for selected protocol version
+      # @return [Boolean] false if protocol number is unknown, otherwise true
+      def include_version
+        @handler = case @version
+          when 75..76 then Handler::Handler75.new(self)
+          when 0..2 then Handler::Handler75.new(self)
+          when 3 then Handler::Handler03.new(self)
+          when 4 then Handler::Handler04.new(self)
+          when 5..6 then Handler::Handler05.new(self)
+          when 7..13 then Handler::Handler07.new(self)
+          else raise WebSocket::Error::Frame::UnknownVersion
+        end
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame/data.rb b/app/server/vendor/websocket/lib/websocket/frame/data.rb
new file mode 100755
index 0000000..0d10ace
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame/data.rb
@@ -0,0 +1,46 @@
+module WebSocket
+  module Frame
+    class Data < String
+
+      def initialize(*args)
+        super *args.each { |arg| arg.force_encoding('ASCII-8BIT') if respond_to?(:force_encoding) }
+      end
+
+      def <<(*args)
+        super *args.each { |arg| arg.force_encoding('ASCII-8BIT') if respond_to?(:force_encoding) }
+      end
+
+      def set_mask
+        raise WebSocket::Error::Frame::MaskTooShort if bytesize < 4
+        @masking_key = self[0..3].bytes.to_a
+      end
+
+      def unset_mask
+        @masking_key = nil
+      end
+
+      def getbytes(start_index, count)
+        data = self[start_index, count]
+        data = mask(data.bytes.to_a, @masking_key).pack('C*') if @masking_key
+        data
+      end
+
+      # Required for support of Ruby 1.8
+      unless new.respond_to?(:getbyte)
+        def getbyte(index)
+          self[index]
+        end
+      end
+
+      def mask(payload, mask)
+        return mask_native(payload, mask) if respond_to?(:mask_native)
+        result = []
+        payload.each_with_index do |byte, i|
+          result[i] = byte ^ mask[i % 4]
+        end
+        result
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame/handler.rb b/app/server/vendor/websocket/lib/websocket/frame/handler.rb
new file mode 100755
index 0000000..56d4550
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame/handler.rb
@@ -0,0 +1,15 @@
+module WebSocket
+  module Frame
+    module Handler
+
+      autoload :Base,     "#{::WebSocket::ROOT}/websocket/frame/handler/base"
+
+      autoload :Handler03, "#{::WebSocket::ROOT}/websocket/frame/handler/handler03"
+      autoload :Handler04, "#{::WebSocket::ROOT}/websocket/frame/handler/handler04"
+      autoload :Handler05, "#{::WebSocket::ROOT}/websocket/frame/handler/handler05"
+      autoload :Handler07, "#{::WebSocket::ROOT}/websocket/frame/handler/handler07"
+      autoload :Handler75, "#{::WebSocket::ROOT}/websocket/frame/handler/handler75"
+
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame/handler/base.rb b/app/server/vendor/websocket/lib/websocket/frame/handler/base.rb
new file mode 100755
index 0000000..2b6ab6a
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame/handler/base.rb
@@ -0,0 +1,41 @@
+module WebSocket
+  module Frame
+    module Handler
+      class Base
+
+        def initialize(frame)
+          @frame = frame
+        end
+
+        # Convert data to raw frame ready to send to client
+        # @return [String] Encoded frame
+        def encode_frame
+          raise NotImplementedError
+        end
+
+        # Convert raw data to decoded frame
+        # @return [WebSocket::Frame::Incoming] Frame if found, nil otherwise
+        def decode_frame
+          raise NotImplementedError
+        end
+
+        private
+
+        # Check if frame is one of control frames
+        # @param [Symbol] frame_type Frame type
+        # @return [Boolean] True if given frame type is control frame
+        def control_frame?(frame_type)
+          ![:text, :binary, :continuation].include?(frame_type)
+        end
+
+        # Check if frame is one of data frames
+        # @param [Symbol] frame_type Frame type
+        # @return [Boolean] True if given frame type is data frame
+        def data_frame?(frame_type)
+          [:text, :binary].include?(frame_type)
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame/handler/handler03.rb b/app/server/vendor/websocket/lib/websocket/frame/handler/handler03.rb
new file mode 100755
index 0000000..ffb4bc8
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame/handler/handler03.rb
@@ -0,0 +1,180 @@
+# encoding: binary
+
+module WebSocket
+  module Frame
+    module Handler
+      class Handler03 < Base
+
+        # Hash of frame names and it's opcodes
+        FRAME_TYPES = {
+          :continuation => 0,
+          :close => 1,
+          :ping => 2,
+          :pong => 3,
+          :text => 4,
+          :binary => 5
+        }
+
+        # Hash of frame opcodes and it's names
+        FRAME_TYPES_INVERSE = FRAME_TYPES.invert
+
+        # @see WebSocket::Frame::Base#supported_frames
+        def supported_frames
+          [:text, :binary, :close, :ping, :pong]
+        end
+
+        # @see WebSocket::Frame::Handler::Base#encode_frame
+        def encode_frame
+          frame = ''
+
+          opcode = type_to_opcode(@frame.type)
+          byte1 = opcode | (fin ? 0b10000000 : 0b00000000) # since more, rsv1-3 are 0 and 0x80 for Draft 4
+          frame << byte1
+
+          mask = @frame.outgoing_masking? ? 0b10000000 : 0b00000000
+
+          length = @frame.data.size
+          if length <= 125
+            byte2 = length # since rsv4 is 0
+            frame << (byte2 | mask)
+          elsif length < 65536 # write 2 byte length
+            frame << (126 | mask)
+            frame << [length].pack('n')
+          else # write 8 byte length
+            frame << (127 | mask)
+            frame << [length >> 32, length & 0xFFFFFFFF].pack("NN")
+          end
+
+          if @frame.outgoing_masking?
+            masking_key = [rand(256).chr, rand(256).chr, rand(256).chr, rand(256).chr].join
+            tmp_data = Data.new([masking_key, @frame.data.to_s].join)
+            tmp_data.set_mask
+            frame << masking_key + tmp_data.getbytes(4, tmp_data.size)
+          else
+            frame << @frame.data
+          end
+
+          frame
+        end
+
+        # @see WebSocket::Frame::Handler::Base#decode_frame
+        def decode_frame
+          while @frame.data.size > 1
+            pointer = 0
+
+            more = ((@frame.data.getbyte(pointer) & 0b10000000) == 0b10000000) ^ fin
+
+            raise(WebSocket::Error::Frame::ReservedBitUsed) if @frame.data.getbyte(pointer) & 0b01110000 != 0b00000000
+
+            opcode = @frame.data.getbyte(pointer) & 0b00001111
+            frame_type = opcode_to_type(opcode)
+            pointer += 1
+
+            raise(WebSocket::Error::Frame::FragmentedControlFrame) if more && control_frame?(frame_type)
+            raise(WebSocket::Error::Frame::DataFrameInsteadContinuation) if data_frame?(frame_type) && !@application_data_buffer.nil?
+
+            mask = @frame.incoming_masking? && (@frame.data.getbyte(pointer) & 0b10000000) == 0b10000000
+            length = @frame.data.getbyte(pointer) & 0b01111111
+
+            raise(WebSocket::Error::Frame::ControlFramePayloadTooLong) if length > 125 && control_frame?(frame_type)
+
+            pointer += 1
+
+            payload_length = case length
+            when 127 # Length defined by 8 bytes
+              # Check buffer size
+              return if @frame.data.getbyte(pointer+8-1) == nil # Buffer incomplete
+
+              # Only using the last 4 bytes for now, till I work out how to
+              # unpack 8 bytes. I'm sure 4GB frames will do for now :)
+              l = @frame.data.getbytes(pointer+4, 4).unpack('N').first
+              pointer += 8
+              l
+            when 126 # Length defined by 2 bytes
+              # Check buffer size
+              return if @frame.data.getbyte(pointer+2-1) == nil # Buffer incomplete
+
+              l = @frame.data.getbytes(pointer, 2).unpack('n').first
+              pointer += 2
+              l
+            else
+              length
+            end
+
+            # Compute the expected frame length
+            frame_length = pointer + payload_length
+            frame_length += 4 if mask
+
+            raise(WebSocket::Error::Frame::TooLong) if frame_length > WebSocket.max_frame_size
+
+            # Check buffer size
+            return if @frame.data.getbyte(frame_length-1) == nil # Buffer incomplete
+
+            # Remove frame header
+            @frame.data.slice!(0...pointer)
+            pointer = 0
+
+            # Read application data (unmasked if required)
+            @frame.data.set_mask if mask
+            pointer += 4 if mask
+            application_data = @frame.data.getbytes(pointer, payload_length)
+            application_data.force_encoding('UTF-8') if application_data.respond_to?(:force_encoding)
+            pointer += payload_length
+            @frame.data.unset_mask if mask
+
+            # Throw away data up to pointer
+            @frame.data.slice!(0...pointer)
+
+            raise(WebSocket::Error::Frame::UnexpectedContinuationFrame) if frame_type == :continuation && !@frame_type
+
+            if more
+              @application_data_buffer ||= ''
+              @application_data_buffer << application_data
+              @frame_type ||= frame_type
+            else
+              # Message is complete
+              if frame_type == :continuation
+                @application_data_buffer << application_data
+                # Test valid UTF-8 encoding
+                raise(WebSocket::Error::Frame::InvalidPayloadEncoding) if @frame_type == :text && @application_data_buffer.respond_to?(:valid_encoding?) && !@application_data_buffer.valid_encoding?
+                message = @frame.class.new(:version => @frame.version, :type => @frame_type, :data => @application_data_buffer, :decoded => true)
+                @application_data_buffer = nil
+                @frame_type = nil
+                return message
+              else
+                raise(WebSocket::Error::Frame::InvalidPayloadEncoding) if frame_type == :text && application_data.respond_to?(:valid_encoding?) && !application_data.valid_encoding?
+                return @frame.class.new(:version => @frame.version, :type => frame_type, :data => application_data, :decoded => true)
+              end
+            end
+          end
+          return nil
+        end
+
+        # Allow turning on or off masking
+        def masking?; false; end
+
+        private
+
+        # This allows flipping the more bit to fin for draft 04
+        def fin; false; end
+
+        # Convert frame type name to opcode
+        # @param [Symbol] frame_type Frame type name
+        # @return [Integer] opcode or nil
+        # @raise [WebSocket::Error] if frame opcode is not known
+        def type_to_opcode(frame_type)
+          FRAME_TYPES[frame_type] || raise(WebSocket::Error::Frame::UnknownFrameType)
+        end
+
+        # Convert frame opcode to type name
+        # @param [Integer] opcode Opcode
+        # @return [Symbol] Frame type name or nil
+        # @raise [WebSocket::Error] if frame type name is not known
+        def opcode_to_type(opcode)
+          FRAME_TYPES_INVERSE[opcode] || raise(WebSocket::Error::Frame::UnknownOpcode)
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame/handler/handler04.rb b/app/server/vendor/websocket/lib/websocket/frame/handler/handler04.rb
new file mode 100755
index 0000000..815edb4
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame/handler/handler04.rb
@@ -0,0 +1,17 @@
+# encoding: binary
+
+module WebSocket
+  module Frame
+    module Handler
+      class Handler04 < Handler03
+
+        private
+
+        # The only difference between draft 03 framing and draft 04 framing is
+        # that the MORE bit has been changed to a FIN bit
+        def fin; true; end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame/handler/handler05.rb b/app/server/vendor/websocket/lib/websocket/frame/handler/handler05.rb
new file mode 100755
index 0000000..7397f41
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame/handler/handler05.rb
@@ -0,0 +1,22 @@
+# encoding: binary
+
+module WebSocket
+  module Frame
+    module Handler
+      class Handler05 < Handler04
+
+        def encode_frame
+          if @frame.code
+            @frame.data = Data.new([@frame.code].pack('n') + @frame.data.to_s)
+            @frame.code = nil
+          end
+          super
+        end
+
+        # Since handler 5 masking should be enabled by default
+        def masking?; true; end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame/handler/handler07.rb b/app/server/vendor/websocket/lib/websocket/frame/handler/handler07.rb
new file mode 100755
index 0000000..b9b66f5
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame/handler/handler07.rb
@@ -0,0 +1,42 @@
+# encoding: binary
+
+module WebSocket
+  module Frame
+    module Handler
+      class Handler07 < Handler05
+
+        # Hash of frame names and it's opcodes
+        FRAME_TYPES = {
+          :continuation => 0,
+          :text => 1,
+          :binary => 2,
+          :close => 8,
+          :ping => 9,
+          :pong => 10,
+        }
+
+        # Hash of frame opcodes and it's names
+        FRAME_TYPES_INVERSE = FRAME_TYPES.invert
+
+        private
+
+        # Convert frame type name to opcode
+        # @param [Symbol] frame_type Frame type name
+        # @return [Integer] opcode or nil
+        # @raise [WebSocket::Error] if frame opcode is not known
+        def type_to_opcode(frame_type)
+          FRAME_TYPES[frame_type] || raise(WebSocket::Error::Frame::UnknownFrameType)
+        end
+
+        # Convert frame opcode to type name
+        # @param [Integer] opcode Opcode
+        # @return [Symbol] Frame type name or nil
+        # @raise [WebSocket::Error] if frame type name is not known
+        def opcode_to_type(opcode)
+          FRAME_TYPES_INVERSE[opcode] || raise(WebSocket::Error::Frame::UnknownOpcode)
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame/handler/handler75.rb b/app/server/vendor/websocket/lib/websocket/frame/handler/handler75.rb
new file mode 100755
index 0000000..7bbc806
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame/handler/handler75.rb
@@ -0,0 +1,78 @@
+# encoding: binary
+
+module WebSocket
+  module Frame
+    module Handler
+      class Handler75 < Base
+
+        # @see WebSocket::Frame::Base#supported_frames
+        def supported_frames
+          [:text, :close]
+        end
+
+        # @see WebSocket::Frame::Handler::Base#encode_frame
+        def encode_frame
+          case @frame.type
+            when :close then "\xff\x00"
+            when :text then
+              ary = ["\x00", @frame.data, "\xff"]
+              ary.collect{ |s| s.encode('UTF-8', 'UTF-8', :invalid => :replace) if s.respond_to?(:encode) }
+              ary.join
+          end
+        end
+
+        # @see WebSocket::Frame::Handler::Base#decode_frame
+        def decode_frame
+          return if @frame.data.size == 0
+
+          pointer = 0
+          frame_type = @frame.data.getbyte(pointer)
+          pointer += 1
+
+          if (frame_type & 0x80) == 0x80
+            # If the high-order bit of the /frame type/ byte is set
+            length = 0
+
+            loop do
+              return if !@frame.data.getbyte(pointer)
+              b = @frame.data.getbyte(pointer)
+              pointer += 1
+              b_v = b & 0x7F
+              length = length * 128 + b_v
+              break unless (b & 0x80) == 0x80
+            end
+
+            raise WebSocket::Error::Frame::TooLong if length > ::WebSocket.max_frame_size
+
+            unless @frame.data.getbyte(pointer+length-1) == nil
+              # Straight from spec - I'm sure this isn't crazy...
+              # 6. Read /length/ bytes.
+              # 7. Discard the read bytes.
+              @frame.instance_variable_set '@data', @frame.data[(pointer+length)..-1]
+
+              # If the /frame type/ is 0xFF and the /length/ was 0, then close
+              if length == 0
+                @frame.class.new(:version => @frame.version, :type => :close, :decoded => true)
+              end
+            end
+          else
+            # If the high-order bit of the /frame type/ byte is _not_ set
+
+            raise WebSocket::Error::Frame::Invalid if @frame.data.getbyte(0) != 0x00
+
+            # Addition to the spec to protect against malicious requests
+            raise WebSocket::Error::Frame::TooLong if @frame.data.size > ::WebSocket.max_frame_size
+
+            msg = @frame.data.slice!(/\A\x00[^\xff]*\xff/)
+            if msg
+              msg.gsub!(/\A\x00|\xff\z/, '')
+              msg.force_encoding('UTF-8') if msg.respond_to?(:force_encoding)
+              @frame.class.new(:version => @frame.version, :type => :text, :data => msg, :decoded => true)
+            end
+          end
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame/incoming.rb b/app/server/vendor/websocket/lib/websocket/frame/incoming.rb
new file mode 100755
index 0000000..a1b9797
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame/incoming.rb
@@ -0,0 +1,52 @@
+module WebSocket
+  module Frame
+    # Construct or parse incoming WebSocket Frame.
+    # @note You should NEVER use this class directly - use Client or Server subclasses instead, as they contain additional frame options(i.e. Client-side masking in draft 04)
+    #
+    # @example
+    #   frame = WebSocket::Frame::Incoming::Server.new(:version => @handshake.version)
+    #   frame << "\x81\x05\x48\x65\x6c\x6c\x6f\x81\x06\x77\x6f\x72\x6c\x64\x21"
+    #   frame.next # "Hello"
+    #   frame.next # "world!""
+    class Incoming < Base
+
+      autoload :Client, "#{::WebSocket::ROOT}/websocket/frame/incoming/client"
+      autoload :Server, "#{::WebSocket::ROOT}/websocket/frame/incoming/server"
+
+      def initialize(args = {})
+        @decoded = args[:decoded] || false
+        super
+      end
+
+      # If data is still encoded after receiving then this is false. After calling "next" you will receive
+      # another instance of incoming frame, but with data decoded - this function will return true and
+      # to_s will return frame content instead of raw data.
+      # @return [Boolean] If frame already decoded?
+      def decoded?
+        @decoded
+      end
+
+      # Add provided string as raw incoming frame.
+      # @param data [String] Raw frame
+      def <<(data)
+        @data << data
+      end
+
+      # Return next complete frame.
+      # This function will merge together splitted frames and return as combined content.
+      # Check #error if nil received to check for eventual parsing errors
+      # @return [WebSocket::Frame::Incoming] Single incoming frame or nil if no complete frame is available.
+      def next
+        @handler.decode_frame unless decoded?
+      end
+      rescue_method :next
+
+      # If decoded then this will return frame content. Otherwise it will return raw frame.
+      # @return [String] Data of frame
+      def to_s
+        @data
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame/incoming/client.rb b/app/server/vendor/websocket/lib/websocket/frame/incoming/client.rb
new file mode 100755
index 0000000..6d2d922
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame/incoming/client.rb
@@ -0,0 +1,17 @@
+module WebSocket
+  module Frame
+    class Incoming
+      class Client < Incoming
+
+        def incoming_masking?
+          false
+        end
+
+        def outgoing_masking?
+          @handler.masking?
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame/incoming/server.rb b/app/server/vendor/websocket/lib/websocket/frame/incoming/server.rb
new file mode 100755
index 0000000..bad7fbb
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame/incoming/server.rb
@@ -0,0 +1,17 @@
+module WebSocket
+  module Frame
+    class Incoming
+      class Server < Incoming
+
+        def incoming_masking?
+          @handler.masking?
+        end
+
+        def outgoing_masking?
+          false
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame/outgoing.rb b/app/server/vendor/websocket/lib/websocket/frame/outgoing.rb
new file mode 100755
index 0000000..f678fa6
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame/outgoing.rb
@@ -0,0 +1,35 @@
+module WebSocket
+  module Frame
+    # Construct or parse incoming WebSocket Frame.
+    # @note You should NEVER use this class directly - use Client or Server subclasses instead, as they contain additional frame options(i.e. Client-side masking in draft 04)
+    #
+    # @example
+    #   frame = WebSocket::Frame::Outgoing::Server.new(:version => @handshake.version, :data => "Hello", :type => :text)
+    #   frame.to_s # "\x81\x05\x48\x65\x6c\x6c\x6f"
+    class Outgoing < Base
+
+      autoload :Client, "#{::WebSocket::ROOT}/websocket/frame/outgoing/client"
+      autoload :Server, "#{::WebSocket::ROOT}/websocket/frame/outgoing/server"
+
+      # Is selected type supported by current draft version?
+      # @return [Boolean] true if frame type is supported
+      def supported?
+        support_type?
+      end
+
+      # Should current frame be sent? Exclude empty frames etc.
+      # @return [Boolean] true if frame should be sent
+      def require_sending?
+        !error?
+      end
+
+      # Return raw frame formatted for sending.
+      def to_s
+        raise WebSocket::Error::Frame::UnknownFrameType unless supported?
+        @handler.encode_frame
+      end
+      rescue_method :to_s
+
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame/outgoing/client.rb b/app/server/vendor/websocket/lib/websocket/frame/outgoing/client.rb
new file mode 100755
index 0000000..7f6dc91
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame/outgoing/client.rb
@@ -0,0 +1,17 @@
+module WebSocket
+  module Frame
+    class Outgoing
+      class Client < Outgoing
+
+        def incoming_masking?
+          false
+        end
+
+        def outgoing_masking?
+          @handler.masking?
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/frame/outgoing/server.rb b/app/server/vendor/websocket/lib/websocket/frame/outgoing/server.rb
new file mode 100755
index 0000000..16040ed
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/frame/outgoing/server.rb
@@ -0,0 +1,17 @@
+module WebSocket
+  module Frame
+    class Outgoing
+      class Server < Outgoing
+
+        def incoming_masking?
+          @handler.masking?
+        end
+
+        def outgoing_masking?
+          false
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/handshake.rb b/app/server/vendor/websocket/lib/websocket/handshake.rb
new file mode 100755
index 0000000..0e83bfc
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/handshake.rb
@@ -0,0 +1,10 @@
+module WebSocket
+  module Handshake
+
+    autoload :Base,    "#{::WebSocket::ROOT}/websocket/handshake/base"
+    autoload :Client,  "#{::WebSocket::ROOT}/websocket/handshake/client"
+    autoload :Handler, "#{::WebSocket::ROOT}/websocket/handshake/handler"
+    autoload :Server,  "#{::WebSocket::ROOT}/websocket/handshake/server"
+
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/handshake/base.rb b/app/server/vendor/websocket/lib/websocket/handshake/base.rb
new file mode 100755
index 0000000..9ea363d
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/handshake/base.rb
@@ -0,0 +1,114 @@
+module WebSocket
+  module Handshake
+    # @abstract Subclass and override to implement custom handshakes
+    class Base
+      include ExceptionHandler
+
+      attr_reader :host, :port, :path, :query,
+                  :state, :version, :secure, :headers
+
+      # Initialize new WebSocket Handshake and set it's state to :new
+      def initialize(args = {})
+        @state = :new
+        @handler = nil
+
+        @data = ""
+        @headers = {}
+      end
+
+      # @abstract Add data to handshake
+      def <<(data)
+        raise NotImplementedError
+      end
+
+      # Return textual representation of handshake request or response
+      # @return [String] text of response
+      def to_s
+        @handler ? @handler.to_s : ""
+      end
+      rescue_method :to_s, :return => ""
+
+      # Recreate inspect as #to_s was overwritten
+      def inspect
+        vars = self.instance_variables.map{|v| "#{v}=#{instance_variable_get(v).inspect}"}.join(", ")
+        insp = "#{self.class}:0x%08x" % (self.__id__ * 2)
+        "<#{insp} #{vars}>"
+      end
+
+      # Is parsing of data finished?
+      # @return [Boolena] True if request was completely parsed or error occured. False otherwise
+      def finished?
+        @state == :finished || @state == :error
+      end
+
+      # Is parsed data valid?
+      # @return [Boolean] False if some errors occured. Reason for error could be found in error method
+      def valid?
+        finished? && @error == nil && @handler && @handler.valid?
+      end
+      rescue_method :valid?, :return => false
+
+      # @abstract Should send data after parsing is finished?
+      def should_respond?
+        raise NotImplementedError
+      end
+
+      # Data left from parsing. Sometimes data that doesn't belong to handshake are added - use this method to retrieve them.
+      # @return [String] String if some data are available. Nil otherwise
+      def leftovers
+        @leftovers.split("\n", reserved_leftover_lines + 1)[reserved_leftover_lines]
+      end
+
+      # URI of request.
+      # @return [String] Full URI with protocol
+      # @example
+      #   @handshake.uri #=> "ws://example.com/path?query=true"
+      def uri
+        uri =  secure ? "wss://" : "ws://"
+        uri << host
+        uri << ":#{port}" if port
+        uri << path
+        uri << "?#{query}" if query
+        uri
+      end
+
+      private
+
+      # Number of lines after header that should be handled as belonging to handshake. Any data after those lines will be handled as leftovers.
+      # @return [Integer] Number of lines
+      def reserved_leftover_lines
+        0
+      end
+
+      # Changes state to error and sets error message
+      # @param [String] message Error message to set
+      def set_error(message)
+        @state = :error
+        super
+      end
+
+      HEADER = /^([^:]+):\s*(.+)$/
+
+      # Parse data imported to handshake and sets state to finished if necessary.
+      # @return [Boolean] True if finished parsing. False if not all data received yet.
+      def parse_data
+        header, @leftovers = @data.split("\r\n\r\n", 2)
+        return false unless @leftovers # The whole header has not been received yet.
+
+        lines = header.split("\r\n")
+
+        first_line = lines.shift
+        parse_first_line(first_line)
+
+        lines.each do |line|
+          h = HEADER.match(line)
+          @headers[h[1].strip.downcase] = h[2].strip if h
+        end
+
+        @state = :finished
+        true
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/handshake/client.rb b/app/server/vendor/websocket/lib/websocket/handshake/client.rb
new file mode 100755
index 0000000..56153af
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/handshake/client.rb
@@ -0,0 +1,137 @@
+require 'uri'
+
+module WebSocket
+  module Handshake
+    # Construct or parse a client WebSocket handshake.
+    #
+    # @example
+    #   @handshake = WebSocket::Handshake::Client.new(:url => 'ws://example.com')
+    #
+    #   # Create request
+    #   @handshake.to_s # GET /demo HTTP/1.1
+    #                   # Upgrade: websocket
+    #                   # Connection: Upgrade
+    #                   # Host: example.com
+    #                   # Sec-WebSocket-Origin: http://example.com
+    #                   # Sec-WebSocket-Version: 13
+    #                   # Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+    #
+    #   # Parse server response
+    #   @handshake << <<EOF
+    #   HTTP/1.1 101 Switching Protocols\r
+    #   Upgrade: websocket\r
+    #   Connection: Upgrade\r
+    #   Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r
+    #   \r
+    #   EOF
+    #
+    #   # All data received?
+    #   @handshake.finished?
+    #
+    #   # No parsing errors?
+    #   @handshake.valid?
+    #
+    class Client < Base
+
+      attr_reader :origin
+
+      # Initialize new WebSocket Client
+      #
+      # @param [Hash] args Arguments for client
+      #
+      # @option args [String]  :host Host of request. Required if no :url param was provided.
+      # @option args [String]  :origin Origin of request. Optional, should be used mostly by browsers. Default: nil
+      # @option args [String]  :path Path of request. Should start with '/'. Default: '/'
+      # @option args [Integer] :port Port of request. Default: nil
+      # @option args [String]  :query. Query for request. Should be in format "aaa=bbb&ccc=ddd"
+      # @option args [Boolean] :secure Defines protocol to use. If true then wss://, otherwise ws://. This option will not change default port - it should be handled by programmer.
+      # @option args [String]  :url URL of request. Must by in format like ws://example.com/path?query=true. Every part of this url will be overriden by more specific arguments.
+      # @option args [String]  :uri Alias to :url
+      # @option args [Integer] :version Version of WebSocket to use. Default: 13 (this is version from RFC)
+      #
+      # @example
+      #   Websocket::Handshake::Client.new(:url => "ws://example.com/path?query=true")
+      def initialize(args = {})
+        super
+
+        @version = args[:version] || DEFAULT_VERSION
+        @origin = args[:origin]
+
+        if args[:url] || args[:uri]
+          uri     = URI.parse(args[:url] || args[:uri])
+          @secure = (uri.scheme == 'wss')
+          @host   = uri.host
+          @port   = uri.port
+          @path   = uri.path
+          @query  = uri.query
+        end
+
+        @secure = args[:secure] if args[:secure]
+        @host   = args[:host]   if args[:host]
+        @port   = args[:port]   if args[:port]
+        @path   = args[:path]   if args[:path]
+        @query  = args[:query]  if args[:query]
+
+        @path   = '/'           if @path.nil? || @path.empty?
+
+        raise WebSocket::Error::Handshake::NoHostProvided unless @host
+
+        include_version
+      end
+      rescue_method :initialize
+
+      # Add text of response from Server. This method will parse content immediately and update state and error(if neccessary)
+      #
+      # @param [String] data Data to add
+      #
+      # @example
+      #   @handshake << <<EOF
+      #   HTTP/1.1 101 Switching Protocols
+      #   Upgrade: websocket
+      #   Connection: Upgrade
+      #   Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
+      #
+      #   EOF
+      def <<(data)
+        @data << data
+        if parse_data
+
+        end
+      end
+      rescue_method :<<
+
+      # Should send content to server after finished parsing?
+      # @return [Boolean] false
+      def should_respond?
+        false
+      end
+
+      private
+
+      # Include set of methods for selected protocol version
+      # @return [Boolean] false if protocol number is unknown, otherwise true
+      def include_version
+        @handler = case @version
+          when 75 then Handler::Client75.new(self)
+          when 76, 0 then Handler::Client76.new(self)
+          when 1..3  then Handler::Client01.new(self)
+          when 4..13 then Handler::Client04.new(self)
+          else raise WebSocket::Error::Handshake::UnknownVersion
+        end
+      end
+
+      FIRST_LINE = /^HTTP\/1\.1 (\d{3})[\w\s]*$/
+
+      # Parse first line of Server response.
+      # @param [String] line Line to parse
+      # @return [Boolean] True if parsed correctly. False otherwise
+      def parse_first_line(line)
+        line_parts = line.match(FIRST_LINE)
+        raise WebSocket::Error::Handshake::InvalidHeader unless line_parts
+        status = line_parts[1]
+        raise WebSocket::Error::Handshake::InvalidStatusCode unless status == '101'
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/handshake/handler.rb b/app/server/vendor/websocket/lib/websocket/handshake/handler.rb
new file mode 100755
index 0000000..23dec95
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/handshake/handler.rb
@@ -0,0 +1,20 @@
+module WebSocket
+  module Handshake
+    module Handler
+
+      autoload :Base,     "#{::WebSocket::ROOT}/websocket/handshake/handler/base"
+
+      autoload :Client,   "#{::WebSocket::ROOT}/websocket/handshake/handler/client"
+      autoload :Client01, "#{::WebSocket::ROOT}/websocket/handshake/handler/client01"
+      autoload :Client04, "#{::WebSocket::ROOT}/websocket/handshake/handler/client04"
+      autoload :Client75, "#{::WebSocket::ROOT}/websocket/handshake/handler/client75"
+      autoload :Client76, "#{::WebSocket::ROOT}/websocket/handshake/handler/client76"
+
+      autoload :Server,   "#{::WebSocket::ROOT}/websocket/handshake/handler/server"
+      autoload :Server04, "#{::WebSocket::ROOT}/websocket/handshake/handler/server04"
+      autoload :Server75, "#{::WebSocket::ROOT}/websocket/handshake/handler/server75"
+      autoload :Server76, "#{::WebSocket::ROOT}/websocket/handshake/handler/server76"
+
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/handshake/handler/base.rb b/app/server/vendor/websocket/lib/websocket/handshake/handler/base.rb
new file mode 100755
index 0000000..06e73bd
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/handshake/handler/base.rb
@@ -0,0 +1,49 @@
+module WebSocket
+  module Handshake
+    module Handler
+      # This class and it's descendants are included in client or server handshake in order to extend basic functionality
+      class Base
+
+        def initialize(handshake)
+          @handshake = handshake
+        end
+
+        # @see WebSocket::Handshake::Base#to_s
+        def to_s
+          result = [ header_line ]
+          handshake_keys.each do |key|
+            result << key.join(': ')
+          end
+          result << ""
+          result << finishing_line
+          result.join("\r\n")
+        end
+
+        def valid?
+          true
+        end
+
+        private
+
+        # Set first line of text representation according to specification.
+        # @return [String] First line of HTTP header
+        def header_line
+          ""
+        end
+
+        # Set handshake headers. Provided as array because some protocol version require specific order of fields.
+        # @return [Array] List of headers as arrays [ key, value ]
+        def handshake_keys
+          []
+        end
+
+        # Set data to send after headers. In most cases it will be blank data.
+        # @return [String] data
+        def finishing_line
+          ""
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/handshake/handler/client.rb b/app/server/vendor/websocket/lib/websocket/handshake/handler/client.rb
new file mode 100755
index 0000000..1e1771c
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/handshake/handler/client.rb
@@ -0,0 +1,18 @@
+module WebSocket
+  module Handshake
+    module Handler
+      class Client < Base
+
+        private
+
+        # @see WebSocket::Handshake::Handler::Base#header_line
+        def header_line
+          path = @handshake.path
+          path += "?" + @handshake.query if @handshake.query
+          "GET #{path} HTTP/1.1"
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/handshake/handler/client01.rb b/app/server/vendor/websocket/lib/websocket/handshake/handler/client01.rb
new file mode 100755
index 0000000..a59bc48
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/handshake/handler/client01.rb
@@ -0,0 +1,20 @@
+require 'digest/md5'
+
+module WebSocket
+  module Handshake
+    module Handler
+      class Client01 < Client76
+
+        private
+
+        # @see WebSocket::Handshake::Handler::Base#handshake_keys
+        def handshake_keys
+          keys = super
+          keys << ['Sec-WebSocket-Draft', @handshake.version]
+          keys
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/handshake/handler/client04.rb b/app/server/vendor/websocket/lib/websocket/handshake/handler/client04.rb
new file mode 100755
index 0000000..69e0a80
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/handshake/handler/client04.rb
@@ -0,0 +1,53 @@
+require 'digest/sha1'
+require 'base64'
+
+module WebSocket
+  module Handshake
+    module Handler
+      class Client04 < Client
+
+        # @see WebSocket::Handshake::Base#valid?
+        def valid?
+          super && verify_accept
+        end
+
+        private
+
+        # @see WebSocket::Handshake::Handler::Base#handshake_keys
+        def handshake_keys
+          keys = [
+            ["Upgrade", "websocket"],
+            ["Connection", "Upgrade"]
+          ]
+          host = @handshake.host
+          host += ":#{@handshake.port}" if @handshake.port
+          keys << ["Host", host]
+          keys << ["Sec-WebSocket-Origin", @handshake.origin] if @handshake.origin
+          keys << ["Sec-WebSocket-Version", @handshake.version ]
+          keys << ["Sec-WebSocket-Key", key]
+          keys
+        end
+
+        # Sec-WebSocket-Key value
+        # @return [String] key
+        def key
+          @key ||= Base64.encode64((1..16).map { rand(255).chr } * '').strip
+        end
+
+        # Value of Sec-WebSocket-Accept that should be delivered back by server
+        # @return [Sering] accept
+        def accept
+          @accept ||= Base64.encode64(Digest::SHA1.digest(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')).strip
+        end
+
+        # Verify if received header Sec-WebSocket-Accept matches generated one.
+        # @return [Boolean] True if accept is matching. False otherwise(appropriate error is set)
+        def verify_accept
+          raise WebSocket::Error::Handshake::InvalidAuthentication unless @handshake.headers['sec-websocket-accept'] == accept
+          true
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/handshake/handler/client75.rb b/app/server/vendor/websocket/lib/websocket/handshake/handler/client75.rb
new file mode 100755
index 0000000..ffef5cf
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/handshake/handler/client75.rb
@@ -0,0 +1,24 @@
+module WebSocket
+  module Handshake
+    module Handler
+      class Client75 < Client
+
+        private
+
+        # @see WebSocket::Handshake::Handler::Base#handshake_keys
+        def handshake_keys
+          keys = [
+            ["Upgrade", "WebSocket"],
+            ["Connection", "Upgrade"]
+          ]
+          host = @handshake.host
+          host += ":#{@handshake.port}" if @handshake.port
+          keys << ["Host", host]
+          keys << ["Origin", @handshake.origin] if @handshake.origin
+          keys
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/handshake/handler/client76.rb b/app/server/vendor/websocket/lib/websocket/handshake/handler/client76.rb
new file mode 100755
index 0000000..cfb8a70
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/handshake/handler/client76.rb
@@ -0,0 +1,101 @@
+require 'digest/md5'
+
+module WebSocket
+  module Handshake
+    module Handler
+      class Client76 < Client75
+
+        # @see WebSocket::Handshake::Base#valid?
+        def valid?
+          super && verify_challenge
+        end
+
+        private
+
+        # @see WebSocket::Handshake::Base#reserved_leftover_lines
+        def reserved_leftover_lines
+          1
+        end
+
+        # @see WebSocket::Handshake::Handler::Base#handshake_keys
+        def handshake_keys
+          keys = super
+          keys << ['Sec-WebSocket-Key1', key1]
+          keys << ['Sec-WebSocket-Key2', key2]
+          keys
+        end
+
+        # @see WebSocket::Handshake::Handler::Base#finishing_line
+        def finishing_line
+          key3
+        end
+
+        # Sec-WebSocket-Key1 value
+        # @return [String] key
+        def key1
+          @key1 ||= generate_key(:key1)
+        end
+
+        # Sec-WebSocket-Key2 value
+        # @return [String] key
+        def key2
+          @key2 ||= generate_key(:key2)
+        end
+
+        # Value of third key, sent in body
+        # @return [String] key
+        def key3
+          @key3 ||= generate_key3
+        end
+
+        # Expected challenge that should be sent by server
+        # @return [String] challenge
+        def challenge
+          return @challenge if defined?(@challenge)
+          key1 && key2
+          sum = [@key1_number].pack("N*") +
+                [@key2_number].pack("N*") +
+                key3
+
+          @challenge = Digest::MD5.digest(sum)
+        end
+
+        # Verify if challenge sent by server match generated one
+        # @return [Boolena] True if challenge matches, false otherwise(sets appropriate error)
+        def verify_challenge
+          raise WebSocket::Error::Handshake::InvalidAuthentication unless @handshake.instance_variable_get('@leftovers') == challenge
+          true
+        end
+
+        NOISE_CHARS = ("\x21".."\x2f").to_a() + ("\x3a".."\x7e").to_a()
+
+        # Generate Sec-WebSocket-Key1 and Sec-WebSocket-Key2
+        # @param [String] name of key. Will be used to set number variable needed later. Valid values: key1, key2
+        # @return [String] generated key
+        def generate_key(key)
+          spaces = 1 + rand(12)
+          max = 0xffffffff / spaces
+          number = rand(max + 1)
+          instance_variable_set("@#{key}_number", number)
+          key = (number * spaces).to_s
+          (1 + rand(12)).times() do
+            char = NOISE_CHARS[rand(NOISE_CHARS.size)]
+            pos = rand(key.size + 1)
+            key[pos...pos] = char
+          end
+          spaces.times() do
+            pos = 1 + rand(key.size - 1)
+            key[pos...pos] = " "
+          end
+          return key
+        end
+
+        # Generate third key
+        def generate_key3
+          [rand(0x100000000)].pack("N") + [rand(0x100000000)].pack("N")
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/handshake/handler/server.rb b/app/server/vendor/websocket/lib/websocket/handshake/handler/server.rb
new file mode 100755
index 0000000..44503fd
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/handshake/handler/server.rb
@@ -0,0 +1,9 @@
+module WebSocket
+  module Handshake
+    module Handler
+      class Server < Base
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/handshake/handler/server04.rb b/app/server/vendor/websocket/lib/websocket/handshake/handler/server04.rb
new file mode 100755
index 0000000..15f105e
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/handshake/handler/server04.rb
@@ -0,0 +1,45 @@
+require 'digest/sha1'
+require 'base64'
+
+module WebSocket
+  module Handshake
+    module Handler
+      class Server04 < Server
+
+        # @see WebSocket::Handshake::Base#valid?
+        def valid?
+          super && verify_key
+        end
+
+        private
+
+        # @see WebSocket::Handshake::Handler::Base#header_line
+        def header_line
+          "HTTP/1.1 101 Switching Protocols"
+        end
+
+        # @see WebSocket::Handshake::Handler::Base#handshake_keys
+        def handshake_keys
+          [
+            ["Upgrade", "websocket"],
+            ["Connection", "Upgrade"],
+            ["Sec-WebSocket-Accept", signature]
+          ]
+        end
+
+        # Signature of response, created from client request Sec-WebSocket-Key
+        # @return [String] signature
+        def signature
+          return unless key = @handshake.headers['sec-websocket-key']
+          string_to_sign = "#{key}258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
+          Base64.encode64(Digest::SHA1.digest(string_to_sign)).chomp
+        end
+
+        def verify_key
+          (@handshake.headers['sec-websocket-key'] ? true : raise(WebSocket::Error::Handshake::InvalidAuthentication))
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/handshake/handler/server75.rb b/app/server/vendor/websocket/lib/websocket/handshake/handler/server75.rb
new file mode 100755
index 0000000..fd20b1c
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/handshake/handler/server75.rb
@@ -0,0 +1,26 @@
+module WebSocket
+  module Handshake
+    module Handler
+      class Server75 < Server
+
+        private
+
+        # @see WebSocket::Handshake::Handler::Base#header_line
+        def header_line
+          "HTTP/1.1 101 Web Socket Protocol Handshake"
+        end
+
+        # @see WebSocket::Handshake::Handler::Base#handshake_keys
+        def handshake_keys
+          [
+            ["Upgrade", "WebSocket"],
+            ["Connection", "Upgrade"],
+            ["WebSocket-Origin", @handshake.headers['origin']],
+            ["WebSocket-Location", @handshake.uri]
+          ]
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/handshake/handler/server76.rb b/app/server/vendor/websocket/lib/websocket/handshake/handler/server76.rb
new file mode 100755
index 0000000..56ca568
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/handshake/handler/server76.rb
@@ -0,0 +1,79 @@
+require 'digest/md5'
+
+module WebSocket
+  module Handshake
+    module Handler
+      class Server76 < Server
+
+        # @see WebSocket::Handshake::Base#valid?
+        def valid?
+          super && !!finishing_line
+        end
+
+        private
+
+        # @see WebSocket::Handshake::Base#reserved_leftover_lines
+        def reserved_leftover_lines
+          1
+        end
+
+        # @see WebSocket::Handshake::Handler::Base#header_line
+        def header_line
+          "HTTP/1.1 101 WebSocket Protocol Handshake"
+        end
+
+        # @see WebSocket::Handshake::Handler::Base#handshake_keys
+        def handshake_keys
+          [
+            ["Upgrade", "WebSocket"],
+            ["Connection", "Upgrade"],
+            ["Sec-WebSocket-Origin", @handshake.headers['origin']],
+            ["Sec-WebSocket-Location", @handshake.uri]
+          ]
+        end
+
+        # @see WebSocket::Handshake::Handler::Base#finishing_line
+        def finishing_line
+          @finishing_line ||= challenge_response
+        end
+
+        private
+
+        # Response to client challenge from request Sec-WebSocket-Key1, Sec-WebSocket-Key2 and leftovers
+        # @return [String] Challenge response or nil if error occured
+        def challenge_response
+          # Refer to 5.2 4-9 of the draft 76
+          first = numbers_over_spaces(@handshake.headers['sec-websocket-key1'].to_s)
+          second = numbers_over_spaces(@handshake.headers['sec-websocket-key2'].to_s)
+          third = @handshake.instance_variable_get('@leftovers').strip
+
+          sum = [first].pack("N*") +
+                [second].pack("N*") +
+                third
+          Digest::MD5.digest(sum)
+        end
+
+        # Calculate numbers over spaces, according to spec 5.2
+        # @param [String] string Key to parse
+        # @return [Integer] Result of calculations or nil if error occured
+        def numbers_over_spaces(string)
+          numbers = string.scan(/[0-9]/).join.to_i
+
+          spaces = string.scan(/ /).size
+          # As per 5.2.5, abort the connection if spaces are zero.
+          raise WebSocket::Error::Handshake::InvalidAuthentication if spaces == 0
+
+          # As per 5.2.6, abort if numbers is not an integral multiple of spaces
+          raise WebSocket::Error::Handshake::InvalidAuthentication if numbers % spaces != 0
+
+          quotient = numbers / spaces
+
+          raise WebSocket::Error::Handshake::InvalidAuthentication if quotient > 2**32-1
+
+          return quotient
+        end
+
+      end
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/handshake/server.rb b/app/server/vendor/websocket/lib/websocket/handshake/server.rb
new file mode 100755
index 0000000..3fcbc6e
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/handshake/server.rb
@@ -0,0 +1,180 @@
+module WebSocket
+  module Handshake
+    # Construct or parse a server WebSocket handshake.
+    #
+    # @example
+    #   handshake = WebSocket::Handshake::Server.new
+    #
+    #   # Parse client request
+    #   @handshake << <<EOF
+    #   GET /demo HTTP/1.1\r
+    #   Upgrade: websocket\r
+    #   Connection: Upgrade\r
+    #   Host: example.com\r
+    #   Sec-WebSocket-Origin: http://example.com\r
+    #   Sec-WebSocket-Version: 13\r
+    #   Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r
+    #   \r
+    #   EOF
+    #
+    #   # All data received?
+    #   @handshake.finished?
+    #
+    #   # No parsing errors?
+    #   @handshake.valid?
+    #
+    #   # Create response
+    #   @handshake.to_s # HTTP/1.1 101 Switching Protocols
+    #                   # Upgrade: websocket
+    #                   # Connection: Upgrade
+    #                   # Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
+    #
+    class Server < Base
+
+      # Initialize new WebSocket Server
+      #
+      # @param [Hash] args Arguments for server
+      #
+      # @option args [Boolean] :secure If true then server will use wss:// protocol
+      #
+      # @example
+      #   Websocket::Handshake::Server.new(:secure => true)
+      def initialize(args = {})
+        super
+        @secure = !!args[:secure]
+      end
+
+      # Add text of request from Client. This method will parse content immediately and update version, state and error(if neccessary)
+      #
+      # @param [String] data Data to add
+      #
+      # @example
+      #   @handshake << <<EOF
+      #   GET /demo HTTP/1.1
+      #   Upgrade: websocket
+      #   Connection: Upgrade
+      #   Host: example.com
+      #   Sec-WebSocket-Origin: http://example.com
+      #   Sec-WebSocket-Version: 13
+      #   Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+      #
+      #   EOF
+      def <<(data)
+        @data << data
+        if parse_data
+          set_version
+        end
+      end
+      rescue_method :<<
+
+      # Parse the request from a rack environment
+      # @param env Rack Environment
+      #
+      # @example
+      #   @handshake.from_rack(env)
+      def from_rack(env)
+        @headers = env.select {|key, value|
+          key =~ /\AHTTP_/
+        }.inject({}) {|memo, tuple|
+          key, value = tuple
+          memo[key.gsub(/\AHTTP_/, '').gsub('_', '-').downcase] = value
+          memo
+        }
+
+        @path      = env["REQUEST_PATH"]
+        @query     = env["QUERY_STRING"]
+
+        # Passenger is blocking on read
+        # Unicorn doesn't support readpartial
+        # Maybe someone is providing even plain string?
+        # Better safe than sorry...
+        input = env['rack.input']
+        @leftovers =  if input.respond_to?(:readpartial)
+                        input.readpartial
+                      elsif input.respond_to?(:read)
+                        input.read
+                      else
+                        input.to_s
+                      end
+
+        set_version
+        @state = :finished
+      end
+
+      # Parse the request from hash
+      # @param hash Hash to import data
+      # @option hash [Hash] :headers HTTP headers of request, downcased
+      # @option hash [String] :path Path for request(without host and query string)
+      # @option hash [String] :query Query string for request
+      # @option hash [String] :body Body of request(if exists)
+      #
+      # @example
+      #   @handshake.from_hash(hash)
+      def from_hash(hash)
+        @headers = hash[:headers] || {}
+        @path = hash[:path] || "/"
+        @query = hash[:query] || ""
+        @leftovers = hash[:body]
+
+        set_version
+        @state = :finished
+      end
+
+      # Should send content to client after finished parsing?
+      # @return [Boolean] true
+      def should_respond?
+        true
+      end
+
+      # Host of server according to client header
+      # @return [String] host
+      def host
+        @headers["host"].to_s.split(":")[0].to_s
+      end
+
+      # Port of server according to client header
+      # @return [String] port
+      def port
+        @headers["host"].to_s.split(":")[1]
+      end
+
+      private
+
+      # Set version of protocol basing on client requets. AFter cotting method calls include_version.
+      def set_version
+        @version = @headers['sec-websocket-version'].to_i if @headers['sec-websocket-version']
+        @version ||= @headers['sec-websocket-draft'].to_i if @headers['sec-websocket-draft']
+        @version ||= 76 if @leftovers != ""
+        @version ||= 75
+        include_version
+      end
+
+      # Include set of methods for selected protocol version
+      # @return [Boolean] false if protocol number is unknown, otherwise true
+      def include_version
+        @handler = case @version
+          when 75 then Handler::Server75.new(self)
+          when 76, 0..3 then Handler::Server76.new(self)
+          when 4..13 then Handler::Server04.new(self)
+          else raise WebSocket::Error::Handshake::UnknownVersion
+        end
+      end
+
+      PATH = /^(\w+) (\/[^\s]*) HTTP\/1\.1$/
+
+      # Parse first line of Client response.
+      # @param [String] line Line to parse
+      # @return [Boolean] True if parsed correctly. False otherwise
+      def parse_first_line(line)
+        line_parts = line.match(PATH)
+        raise WebSocket::Error::Handshake::InvalidHeader unless line_parts
+        method = line_parts[1].strip
+        raise WebSocket::Error::Handshake::GetRequestRequired unless method == "GET"
+
+        resource_name = line_parts[2].strip
+        @path, @query = resource_name.split('?', 2)
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/lib/websocket/version.rb b/app/server/vendor/websocket/lib/websocket/version.rb
new file mode 100755
index 0000000..5ce5b1f
--- /dev/null
+++ b/app/server/vendor/websocket/lib/websocket/version.rb
@@ -0,0 +1,3 @@
+module WebSocket
+  VERSION = '1.1.2'
+end
diff --git a/app/server/vendor/websocket/spec/frame/incoming_03_spec.rb b/app/server/vendor/websocket/spec/frame/incoming_03_spec.rb
new file mode 100755
index 0000000..ca17681
--- /dev/null
+++ b/app/server/vendor/websocket/spec/frame/incoming_03_spec.rb
@@ -0,0 +1,118 @@
+# encoding: binary
+require 'spec_helper'
+
+describe 'Incoming frame draft 03' do
+  let(:version) { 3 }
+  let(:frame) { WebSocket::Frame::Incoming.new(:version => version, :data => encoded_text) }
+  let(:encoded_text) { nil }
+  let(:decoded_text) { nil }
+  let(:frame_type) { nil }
+  let(:error) { nil }
+  subject { frame }
+
+  it_should_behave_like 'valid_incoming_frame'
+
+  context "should properly decode close frame" do
+    let(:encoded_text) { "\x01\x05" + decoded_text }
+    let(:frame_type) { :close }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode ping frame" do
+    let(:encoded_text) { "\x02\x05" + decoded_text }
+    let(:frame_type) { :ping }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode pong frame" do
+    let(:encoded_text) { "\x03\x05" + decoded_text }
+    let(:frame_type) { :pong }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode text frame" do
+    let(:encoded_text) { "\x04\x05" + decoded_text }
+    let(:decoded_text) { "Hello" }
+    let(:frame_type) { :text }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode text frame with continuation" do
+    let(:encoded_text) { "\x84\x03Hel\x00\x02lo" }
+    let(:frame_type)   { :text }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode text frame in between of continuation" do
+    let(:encoded_text) { "\x84\x03Hel\x03\x03abc\x00\x02lo" }
+    let(:frame_type)   { [:pong, :text] }
+    let(:decoded_text) { ["abc", "Hello"] }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should not return unfinished more frame" do
+    let(:encoded_text) { "\x84\x03Hel\x03\x03abc" }
+    let(:frame_type)   { :pong }
+    let(:decoded_text) { "abc" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode 256 bytes binary frame" do
+    let(:encoded_text) { "\x05\x7E\x01\x00" + decoded_text }
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 256 }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode 64KiB binary frame" do
+    let(:encoded_text) { "\x05\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text }
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 65536 }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should wait with incomplete frame" do
+    let(:encoded_text) { "\x04\x06Hello" }
+    let(:decoded_text) { nil }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should raise error with invalid opcode" do
+    let(:encoded_text) { "\x09\x05Hello" }
+    let(:decoded_text) { nil }
+    let(:error) { WebSocket::Error::Frame::UnknownOpcode }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should raise error with too long frame" do
+    let(:encoded_text) { "\x04\x7F" + "a" * WebSocket.max_frame_size }
+    let(:decoded_text) { nil }
+    let(:error) { WebSocket::Error::Frame::TooLong }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should raise error with continuation frame without more frame earlier" do
+    let(:encoded_text) { "\x00\x05Hello" }
+    let(:decoded_text) { nil }
+    let(:error) { WebSocket::Error::Frame::UnexpectedContinuationFrame }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+end
diff --git a/app/server/vendor/websocket/spec/frame/incoming_04_spec.rb b/app/server/vendor/websocket/spec/frame/incoming_04_spec.rb
new file mode 100755
index 0000000..7703182
--- /dev/null
+++ b/app/server/vendor/websocket/spec/frame/incoming_04_spec.rb
@@ -0,0 +1,118 @@
+# encoding: binary
+require 'spec_helper'
+
+describe 'Incoming frame draft 04' do
+  let(:version) { 4 }
+  let(:frame) { WebSocket::Frame::Incoming.new(:version => version, :data => encoded_text) }
+  let(:encoded_text) { nil }
+  let(:decoded_text) { nil }
+  let(:frame_type) { nil }
+  let(:error) { nil }
+  subject { frame }
+
+  it_should_behave_like 'valid_incoming_frame'
+
+  context "should properly decode close frame" do
+    let(:encoded_text) { "\x81\x05" + decoded_text }
+    let(:frame_type) { :close }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode ping frame" do
+    let(:encoded_text) { "\x82\x05" + decoded_text }
+    let(:frame_type) { :ping }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode pong frame" do
+    let(:encoded_text) { "\x83\x05" + decoded_text }
+    let(:frame_type) { :pong }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode text frame" do
+    let(:encoded_text) { "\x84\x05" + decoded_text }
+    let(:decoded_text) { "Hello" }
+    let(:frame_type) { :text }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode text frame with continuation" do
+    let(:encoded_text) { "\x04\x03Hel\x80\x02lo" }
+    let(:frame_type)   { :text }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode text frame in between of continuation" do
+    let(:encoded_text) { "\x04\x03Hel\x83\x03abc\x80\x02lo" }
+    let(:frame_type)   { [:pong, :text] }
+    let(:decoded_text) { ["abc", "Hello"] }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should not return unfinished more frame" do
+    let(:encoded_text) { "\x04\x03Hel\x83\x03abc" }
+    let(:frame_type)   { :pong }
+    let(:decoded_text) { "abc" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode 256 bytes binary frame" do
+    let(:encoded_text) { "\x85\x7E\x01\x00" + decoded_text }
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 256 }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode 64KiB binary frame" do
+    let(:encoded_text) { "\x85\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text }
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 65536 }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should wait with incomplete frame" do
+    let(:encoded_text) { "\x84\x06Hello" }
+    let(:decoded_text) { nil }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should raise error with invalid opcode" do
+    let(:encoded_text) { "\x89\x05Hello" }
+    let(:decoded_text) { nil }
+    let(:error) { WebSocket::Error::Frame::UnknownOpcode }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should raise error with too long frame" do
+    let(:encoded_text) { "\x84\x7F" + "a" * WebSocket.max_frame_size }
+    let(:decoded_text) { nil }
+    let(:error) { WebSocket::Error::Frame::TooLong }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should raise error with continuation frame without more frame earlier" do
+    let(:encoded_text) { "\x80\x05Hello" }
+    let(:decoded_text) { nil }
+    let(:error) { WebSocket::Error::Frame::UnexpectedContinuationFrame }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+end
diff --git a/app/server/vendor/websocket/spec/frame/incoming_05_spec.rb b/app/server/vendor/websocket/spec/frame/incoming_05_spec.rb
new file mode 100755
index 0000000..2753590
--- /dev/null
+++ b/app/server/vendor/websocket/spec/frame/incoming_05_spec.rb
@@ -0,0 +1,134 @@
+# encoding: binary
+require 'spec_helper'
+
+describe 'Incoming frame draft 05' do
+  let(:version) { 5 }
+  let(:frame) { WebSocket::Frame::Incoming.new(:version => version, :data => encoded_text) }
+  let(:encoded_text) { nil }
+  let(:decoded_text) { nil }
+  let(:frame_type) { nil }
+  let(:error) { nil }
+  subject { frame }
+
+  it_should_behave_like 'valid_incoming_frame'
+
+  context "should properly decode close frame" do
+    let(:encoded_text) { "\x81\x05" + decoded_text }
+    let(:frame_type) { :close }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode ping frame" do
+    let(:encoded_text) { "\x82\x05" + decoded_text }
+    let(:frame_type) { :ping }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode pong frame" do
+    let(:encoded_text) { "\x83\x05" + decoded_text }
+    let(:frame_type) { :pong }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode text frame" do
+    let(:encoded_text) { "\x84\x05" + decoded_text }
+    let(:decoded_text) { "Hello" }
+    let(:frame_type) { :text }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode masked text frame" do
+    let(:encoded_text) { "\x84\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58" }
+    let(:decoded_text) { "Hello" }
+    let(:frame_type) { :text }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode text frame with continuation" do
+    let(:encoded_text) { "\x04\x03Hel\x80\x02lo" }
+    let(:frame_type)   { :text }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode masked text frame with continuation" do
+    let(:encoded_text) { "\x04\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x80\x82\x37\xfa\x21\x3d\x5b\x95" }
+    let(:frame_type)   { :text }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode text frame in between of continuation" do
+    let(:encoded_text) { "\x04\x03Hel\x83\x03abc\x80\x02lo" }
+    let(:frame_type)   { [:pong, :text] }
+    let(:decoded_text) { ["abc", "Hello"] }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should not return unfinished more frame" do
+    let(:encoded_text) { "\x04\x03Hel\x83\x03abc" }
+    let(:frame_type)   { :pong }
+    let(:decoded_text) { "abc" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode 256 bytes binary frame" do
+    let(:encoded_text) { "\x85\x7E\x01\x00" + decoded_text }
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 256 }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode 64KiB binary frame" do
+    let(:encoded_text) { "\x85\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text }
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 65536 }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should wait with incomplete frame" do
+    let(:encoded_text) { "\x84\x06Hello" }
+    let(:decoded_text) { nil }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should raise error with invalid opcode" do
+    let(:encoded_text) { "\x89\x05Hello" }
+    let(:decoded_text) { nil }
+    let(:error) { WebSocket::Error::Frame::UnknownOpcode }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should raise error with too long frame" do
+    let(:encoded_text) { "\x84\x7F" + "a" * WebSocket.max_frame_size }
+    let(:decoded_text) { nil }
+    let(:error) { WebSocket::Error::Frame::TooLong }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should raise error with continuation frame without more frame earlier" do
+    let(:encoded_text) { "\x80\x05Hello" }
+    let(:decoded_text) { nil }
+    let(:error) { WebSocket::Error::Frame::UnexpectedContinuationFrame }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+end
diff --git a/app/server/vendor/websocket/spec/frame/incoming_07_spec.rb b/app/server/vendor/websocket/spec/frame/incoming_07_spec.rb
new file mode 100755
index 0000000..1706046
--- /dev/null
+++ b/app/server/vendor/websocket/spec/frame/incoming_07_spec.rb
@@ -0,0 +1,134 @@
+# encoding: binary
+require 'spec_helper'
+
+describe 'Incoming frame draft 07' do
+  let(:version) { 7 }
+  let(:frame) { WebSocket::Frame::Incoming.new(:version => version, :data => encoded_text) }
+  let(:encoded_text) { nil }
+  let(:decoded_text) { nil }
+  let(:frame_type) { nil }
+  let(:error) { nil }
+  subject { frame }
+
+  it_should_behave_like 'valid_incoming_frame'
+
+  context "should properly decode close frame" do
+    let(:encoded_text) { "\x88\x05" + decoded_text }
+    let(:frame_type) { :close }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode ping frame" do
+    let(:encoded_text) { "\x89\x05" + decoded_text }
+    let(:frame_type) { :ping }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode pong frame" do
+    let(:encoded_text) { "\x8a\x05" + decoded_text }
+    let(:frame_type) { :pong }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode text frame" do
+    let(:encoded_text) { "\x81\x05\x48\x65\x6c\x6c\x6f" }
+    let(:decoded_text) { "Hello" }
+    let(:frame_type) { :text }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode masked text frame" do
+    let(:encoded_text) { "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58" }
+    let(:decoded_text) { "Hello" }
+    let(:frame_type) { :text }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode text frame with continuation" do
+    let(:encoded_text) { "\x01\x03Hel\x80\x02lo" }
+    let(:frame_type)   { :text }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode masked text frame with continuation" do
+    let(:encoded_text) { "\x01\x83\x37\xfa\x21\x3d\x7f\x9f\x4d\x80\x82\x37\xfa\x21\x3d\x5b\x95" }
+    let(:frame_type)   { :text }
+    let(:decoded_text) { "Hello" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode text frame in between of continuation" do
+    let(:encoded_text) { "\x01\x03Hel\x8a\x03abc\x80\x02lo" }
+    let(:frame_type)   { [:pong, :text] }
+    let(:decoded_text) { ["abc", "Hello"] }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should not return unfinished more frame" do
+    let(:encoded_text) { "\x01\x03Hel\x8a\x03abc" }
+    let(:frame_type)   { :pong }
+    let(:decoded_text) { "abc" }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode 256 bytes binary frame" do
+    let(:encoded_text) { "\x82\x7E\x01\x00" + decoded_text }
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 256 }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should properly decode 64KiB binary frame" do
+    let(:encoded_text) { "\x82\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text }
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 65536 }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should wait with incomplete frame" do
+    let(:encoded_text) { "\x81\x06Hello" }
+    let(:decoded_text) { nil }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should raise error with invalid opcode" do
+    let(:encoded_text) { "\x85\x05Hello" }
+    let(:decoded_text) { nil }
+    let(:error) { WebSocket::Error::Frame::UnknownOpcode }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should raise error with too long frame" do
+    let(:encoded_text) { "\x81\x7F" + "a" * WebSocket.max_frame_size }
+    let(:decoded_text) { nil }
+    let(:error) { WebSocket::Error::Frame::TooLong }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "should raise error with continuation frame without more frame earlier" do
+    let(:encoded_text) { "\x80\x05Hello" }
+    let(:decoded_text) { nil }
+    let(:error) { WebSocket::Error::Frame::UnexpectedContinuationFrame }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+end
diff --git a/app/server/vendor/websocket/spec/frame/incoming_75_spec.rb b/app/server/vendor/websocket/spec/frame/incoming_75_spec.rb
new file mode 100755
index 0000000..d41ba4f
--- /dev/null
+++ b/app/server/vendor/websocket/spec/frame/incoming_75_spec.rb
@@ -0,0 +1,60 @@
+# encoding: binary
+require 'spec_helper'
+
+describe 'Incoming frame draft 75' do
+  let(:version) { 75 }
+  let(:frame) { WebSocket::Frame::Incoming.new(:version => version, :data => encoded_text) }
+  let(:encoded_text) { nil }
+  let(:decoded_text) { nil }
+  let(:frame_type) { nil }
+  let(:error) { nil }
+  subject { frame }
+
+  it_should_behave_like 'valid_incoming_frame'
+
+  context "with valid text frame" do
+    let(:encoded_text) { "\x00abc\xFF" }
+    let(:decoded_text) { "abc" }
+    let(:frame_type) { :text }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "with two frames" do
+    let(:encoded_text) { "\x00abc\xFF\x00def\xFF" }
+    let(:decoded_text) { ["abc", "def"] }
+    let(:frame_type)   { [:text, :text] }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "with close frame" do
+    let(:encoded_text) { "\xFF\x00" }
+    let(:decoded_text) { "" }
+    let(:frame_type) { :close }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "with incomplete frame" do
+    let(:encoded_text) { "\x00test" }
+    let(:decoded_text) { nil }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "with invalid frame" do
+    let(:encoded_text) { "invalid" }
+    let(:error) { WebSocket::Error::Frame::Invalid }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+  context "with too long frame" do
+    let(:encoded_text) { "\x00" + "a" * WebSocket.max_frame_size + "\xFF" }
+    let(:error) { WebSocket::Error::Frame::TooLong }
+
+    it_should_behave_like 'valid_incoming_frame'
+  end
+
+end
diff --git a/app/server/vendor/websocket/spec/frame/incoming_common_spec.rb b/app/server/vendor/websocket/spec/frame/incoming_common_spec.rb
new file mode 100755
index 0000000..78b7de4
--- /dev/null
+++ b/app/server/vendor/websocket/spec/frame/incoming_common_spec.rb
@@ -0,0 +1,23 @@
+# encoding: binary
+require 'spec_helper'
+
+describe 'Incoming common frame' do
+  subject { WebSocket::Frame::Incoming.new }
+
+  its(:version) { should eql(13) }
+  its(:decoded?) { should be_false }
+  # Not implemented yet
+  # its(:error?) { should be_false }
+
+  it "should allow adding data via <<" do
+    subject.data.should eql("")
+    subject << "test"
+    subject.data.should eql("test")
+  end
+
+  it "should raise error on invalid version" do
+    subject = WebSocket::Frame::Incoming.new(:version => 70)
+    subject.error?.should be_true
+    subject.error.should eql(:unknown_protocol_version)
+  end
+end
diff --git a/app/server/vendor/websocket/spec/frame/masking_spec.rb b/app/server/vendor/websocket/spec/frame/masking_spec.rb
new file mode 100755
index 0000000..4d3284e
--- /dev/null
+++ b/app/server/vendor/websocket/spec/frame/masking_spec.rb
@@ -0,0 +1,16 @@
+# encoding: binary
+require 'spec_helper'
+
+describe 'Masking frame draft 07' do
+  it "should encode and decode masked frame correctly" do
+    outgoing_frame = WebSocket::Frame::Outgoing::Client.new(:data => "Hello World", :type => "text")
+    outgoing_frame.to_s
+    outgoing_frame.error.should be_nil
+    incoming_frame = WebSocket::Frame::Incoming::Server.new(:data => outgoing_frame.to_s).next
+    incoming_frame.should_not be_nil
+    incoming_frame.class.should eql(WebSocket::Frame::Incoming::Server)
+    incoming_frame.error.should be_nil
+    incoming_frame.decoded?.should be_true
+    incoming_frame.to_s.should eql('Hello World')
+  end
+end
diff --git a/app/server/vendor/websocket/spec/frame/outgoing_03_spec.rb b/app/server/vendor/websocket/spec/frame/outgoing_03_spec.rb
new file mode 100755
index 0000000..b7dc22e
--- /dev/null
+++ b/app/server/vendor/websocket/spec/frame/outgoing_03_spec.rb
@@ -0,0 +1,78 @@
+# encoding: binary
+require 'spec_helper'
+
+describe 'Outgoing frame draft 03' do
+  let(:version) { 03 }
+  let(:frame) { WebSocket::Frame::Outgoing.new(:version => version, :data => decoded_text, :type => frame_type) }
+  let(:decoded_text) { "" }
+  let(:encoded_text) { "\x04\x00" }
+  let(:frame_type) { :text }
+  let(:require_sending) { true }
+  let(:error) { nil }
+  subject { frame }
+
+  it_should_behave_like 'valid_outgoing_frame'
+
+  context "should properly encode close frame" do
+    let(:frame_type) { :close }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x01\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode ping frame" do
+    let(:frame_type) { :ping }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x02\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode pong frame" do
+    let(:frame_type) { :pong }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x03\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode text frame" do
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x04\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode 256 bytes binary frame" do
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 256 }
+    let(:encoded_text) { "\x05\x7E\x01\x00" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode 64KiB binary frame" do
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 65536 }
+    let(:encoded_text) { "\x05\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should return error for unknown frame type" do
+    let(:frame_type) { :unknown }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { nil }
+    let(:error) { :unknown_frame_type }
+    let(:require_sending) { false }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+end
diff --git a/app/server/vendor/websocket/spec/frame/outgoing_04_spec.rb b/app/server/vendor/websocket/spec/frame/outgoing_04_spec.rb
new file mode 100755
index 0000000..4eaeaf3
--- /dev/null
+++ b/app/server/vendor/websocket/spec/frame/outgoing_04_spec.rb
@@ -0,0 +1,78 @@
+# encoding: binary
+require 'spec_helper'
+
+describe 'Outgoing frame draft 04' do
+  let(:version) { 04 }
+  let(:frame) { WebSocket::Frame::Outgoing.new(:version => version, :data => decoded_text, :type => frame_type) }
+  let(:decoded_text) { "" }
+  let(:encoded_text) { "\x84\x00" }
+  let(:frame_type) { :text }
+  let(:require_sending) { true }
+  let(:error) { nil }
+  subject { frame }
+
+  it_should_behave_like 'valid_outgoing_frame'
+
+  context "should properly encode close frame" do
+    let(:frame_type) { :close }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x81\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode ping frame" do
+    let(:frame_type) { :ping }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x82\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode pong frame" do
+    let(:frame_type) { :pong }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x83\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode text frame" do
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x84\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode 256 bytes binary frame" do
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 256 }
+    let(:encoded_text) { "\x85\x7E\x01\x00" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode 64KiB binary frame" do
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 65536 }
+    let(:encoded_text) { "\x85\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should return error for unknown frame type" do
+    let(:frame_type) { :unknown }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { nil }
+    let(:error) { :unknown_frame_type }
+    let(:require_sending) { false }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+end
diff --git a/app/server/vendor/websocket/spec/frame/outgoing_05_spec.rb b/app/server/vendor/websocket/spec/frame/outgoing_05_spec.rb
new file mode 100755
index 0000000..6a83fb2
--- /dev/null
+++ b/app/server/vendor/websocket/spec/frame/outgoing_05_spec.rb
@@ -0,0 +1,78 @@
+# encoding: binary
+require 'spec_helper'
+
+describe 'Outgoing frame draft 05' do
+  let(:version) { 5 }
+  let(:frame) { WebSocket::Frame::Outgoing.new(:version => version, :data => decoded_text, :type => frame_type) }
+  let(:decoded_text) { "" }
+  let(:encoded_text) { "\x84\x00" }
+  let(:frame_type) { :text }
+  let(:require_sending) { true }
+  let(:error) { nil }
+  subject { frame }
+
+  it_should_behave_like 'valid_outgoing_frame'
+
+  context "should properly encode close frame" do
+    let(:frame_type) { :close }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x81\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode ping frame" do
+    let(:frame_type) { :ping }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x82\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode pong frame" do
+    let(:frame_type) { :pong }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x83\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode text frame" do
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x84\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode 256 bytes binary frame" do
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 256 }
+    let(:encoded_text) { "\x85\x7E\x01\x00" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode 64KiB binary frame" do
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 65536 }
+    let(:encoded_text) { "\x85\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should return error for unknown frame type" do
+    let(:frame_type) { :unknown }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { nil }
+    let(:error) { :unknown_frame_type }
+    let(:require_sending) { false }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+end
diff --git a/app/server/vendor/websocket/spec/frame/outgoing_07_spec.rb b/app/server/vendor/websocket/spec/frame/outgoing_07_spec.rb
new file mode 100755
index 0000000..0684fa0
--- /dev/null
+++ b/app/server/vendor/websocket/spec/frame/outgoing_07_spec.rb
@@ -0,0 +1,78 @@
+# encoding: binary
+require 'spec_helper'
+
+describe 'Outgoing frame draft 07' do
+  let(:version) { 7 }
+  let(:frame) { WebSocket::Frame::Outgoing.new(:version => version, :data => decoded_text, :type => frame_type) }
+  let(:decoded_text) { "" }
+  let(:encoded_text) { "\x81\x00" }
+  let(:frame_type) { :text }
+  let(:require_sending) { true }
+  let(:error) { nil }
+  subject { frame }
+
+  it_should_behave_like 'valid_outgoing_frame'
+
+  context "should properly encode close frame" do
+    let(:frame_type) { :close }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x88\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode ping frame" do
+    let(:frame_type) { :ping }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x89\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode pong frame" do
+    let(:frame_type) { :pong }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x8a\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode text frame" do
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { "\x81\x05" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode 256 bytes binary frame" do
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 256 }
+    let(:encoded_text) { "\x82\x7E\x01\x00" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode 64KiB binary frame" do
+    let(:frame_type) { :binary }
+    let(:decoded_text) { "a" * 65536 }
+    let(:encoded_text) { "\x82\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + decoded_text }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should return error for unknown frame type" do
+    let(:frame_type) { :unknown }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { nil }
+    let(:error) { :unknown_frame_type }
+    let(:require_sending) { false }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+end
diff --git a/app/server/vendor/websocket/spec/frame/outgoing_75_spec.rb b/app/server/vendor/websocket/spec/frame/outgoing_75_spec.rb
new file mode 100755
index 0000000..786a776
--- /dev/null
+++ b/app/server/vendor/websocket/spec/frame/outgoing_75_spec.rb
@@ -0,0 +1,42 @@
+# encoding: binary
+require 'spec_helper'
+
+describe 'Outgoing frame draft 75' do
+  let(:version) { 75 }
+  let(:frame) { WebSocket::Frame::Outgoing.new(:version => version, :data => decoded_text, :type => frame_type) }
+  let(:decoded_text) { "" }
+  let(:encoded_text) { "\x00\xFF" }
+  let(:frame_type) { :text }
+  let(:require_sending) { true }
+  let(:error) { nil }
+  subject { frame }
+
+  it_should_behave_like 'valid_outgoing_frame'
+
+  context "should properly encode text frame" do
+    let(:decoded_text) { "abc" }
+    let(:encoded_text) { "\x00abc\xFF" }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should properly encode close frame" do
+    let(:frame_type) { :close }
+    let(:decoded_text) { "abc" }
+    let(:encoded_text) { "\xFF\x00" }
+    let(:require_sending) { true }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+
+  context "should return error for unknown frame type" do
+    let(:frame_type) { :unknown }
+    let(:decoded_text) { "Hello" }
+    let(:encoded_text) { nil }
+    let(:error) { :unknown_frame_type }
+    let(:require_sending) { false }
+
+    it_should_behave_like 'valid_outgoing_frame'
+  end
+end
diff --git a/app/server/vendor/websocket/spec/frame/outgoing_common_spec.rb b/app/server/vendor/websocket/spec/frame/outgoing_common_spec.rb
new file mode 100755
index 0000000..0527867
--- /dev/null
+++ b/app/server/vendor/websocket/spec/frame/outgoing_common_spec.rb
@@ -0,0 +1,16 @@
+# encoding: binary
+require 'spec_helper'
+
+describe 'Outgoing common frame' do
+  subject { WebSocket::Frame::Outgoing.new }
+
+  its(:version) { should eql(13) }
+  # Not implemented yet
+  # its(:error?) { should be_false }
+
+  it "should raise error on invalid version" do
+    subject = WebSocket::Frame::Incoming.new(:version => 70)
+    subject.error?.should be_true
+    subject.error.should eql(:unknown_protocol_version)
+  end
+end
diff --git a/app/server/vendor/websocket/spec/handshake/client_04_spec.rb b/app/server/vendor/websocket/spec/handshake/client_04_spec.rb
new file mode 100755
index 0000000..0406adf
--- /dev/null
+++ b/app/server/vendor/websocket/spec/handshake/client_04_spec.rb
@@ -0,0 +1,20 @@
+require 'spec_helper'
+
+describe 'Client draft 4 handshake' do
+  let(:handshake) { WebSocket::Handshake::Client.new({ :uri => 'ws://example.com/demo', :origin => 'http://example.com', :version => version }.merge(@request_params || {})) }
+
+  let(:version) { 4 }
+  let(:client_request) { client_handshake_04({ :key => handshake.handler.send(:key), :version => version }.merge(@request_params || {})) }
+  let(:server_response) { server_handshake_04({ :accept => handshake.handler.send(:accept) }.merge(@request_params || {})) }
+
+  it_should_behave_like 'all client drafts'
+
+  it "should disallow client with invalid challenge" do
+    @request_params = { :accept => "invalid" }
+    handshake << server_response
+
+    handshake.should be_finished
+    handshake.should_not be_valid
+    handshake.error.should eql(:invalid_handshake_authentication)
+  end
+end
diff --git a/app/server/vendor/websocket/spec/handshake/client_75_spec.rb b/app/server/vendor/websocket/spec/handshake/client_75_spec.rb
new file mode 100755
index 0000000..59d746b
--- /dev/null
+++ b/app/server/vendor/websocket/spec/handshake/client_75_spec.rb
@@ -0,0 +1,11 @@
+require 'spec_helper'
+
+describe 'Client draft 75 handshake' do
+  let(:handshake) { WebSocket::Handshake::Client.new({ :uri => 'ws://example.com/demo', :origin => 'http://example.com', :version => version }.merge(@request_params || {})) }
+
+  let(:version) { 75 }
+  let(:client_request) { client_handshake_75(@request_params || {}) }
+  let(:server_response) { server_handshake_75(@request_params || {}) }
+
+  it_should_behave_like 'all client drafts'
+end
diff --git a/app/server/vendor/websocket/spec/handshake/client_76_spec.rb b/app/server/vendor/websocket/spec/handshake/client_76_spec.rb
new file mode 100755
index 0000000..b4c6549
--- /dev/null
+++ b/app/server/vendor/websocket/spec/handshake/client_76_spec.rb
@@ -0,0 +1,20 @@
+require 'spec_helper'
+
+describe 'Client draft 76 handshake' do
+  let(:handshake) { WebSocket::Handshake::Client.new({ :uri => 'ws://example.com/demo', :origin => 'http://example.com', :version => version }.merge(@request_params || {})) }
+
+  let(:version) { 76 }
+  let(:client_request) { client_handshake_76({ :key1 => handshake.handler.send(:key1), :key2 => handshake.handler.send(:key2), :key3 => handshake.handler.send(:key3) }.merge(@request_params || {})) }
+  let(:server_response) { server_handshake_76({ :challenge => handshake.handler.send(:challenge) }.merge(@request_params || {})) }
+
+  it_should_behave_like 'all client drafts'
+
+  it "should disallow client with invalid challenge" do
+    @request_params = { :challenge => "invalid" }
+    handshake << server_response
+
+    handshake.should be_finished
+    handshake.should_not be_valid
+    handshake.error.should eql(:invalid_handshake_authentication)
+  end
+end
diff --git a/app/server/vendor/websocket/spec/handshake/server_04_spec.rb b/app/server/vendor/websocket/spec/handshake/server_04_spec.rb
new file mode 100755
index 0000000..235c9b2
--- /dev/null
+++ b/app/server/vendor/websocket/spec/handshake/server_04_spec.rb
@@ -0,0 +1,18 @@
+require 'spec_helper'
+
+describe 'Server draft 04 handshake' do
+  let(:handshake) { WebSocket::Handshake::Server.new }
+  let(:version) { 04 }
+  let(:client_request) { client_handshake_04(@request_params || {}) }
+  let(:server_response) { server_handshake_04(@request_params || {}) }
+
+  it_should_behave_like 'all server drafts'
+
+  it "should disallow request without Sec-WebSocket-Key" do
+    handshake << client_request.gsub(/^Sec-WebSocket-Key:.*\n/, '')
+
+    handshake.should be_finished
+    handshake.should_not be_valid
+    handshake.error.should eql(:invalid_handshake_authentication)
+  end
+end
diff --git a/app/server/vendor/websocket/spec/handshake/server_75_spec.rb b/app/server/vendor/websocket/spec/handshake/server_75_spec.rb
new file mode 100755
index 0000000..44a9db6
--- /dev/null
+++ b/app/server/vendor/websocket/spec/handshake/server_75_spec.rb
@@ -0,0 +1,11 @@
+require 'spec_helper'
+
+describe 'Server draft 75 handshake' do
+  let(:handshake) { WebSocket::Handshake::Server.new }
+
+  let(:version) { 75 }
+  let(:client_request) { client_handshake_75(@request_params || {}) }
+  let(:server_response) { server_handshake_75(@request_params || {}) }
+
+  it_should_behave_like 'all server drafts'
+end
diff --git a/app/server/vendor/websocket/spec/handshake/server_76_spec.rb b/app/server/vendor/websocket/spec/handshake/server_76_spec.rb
new file mode 100755
index 0000000..9afa6f3
--- /dev/null
+++ b/app/server/vendor/websocket/spec/handshake/server_76_spec.rb
@@ -0,0 +1,46 @@
+require 'spec_helper'
+
+describe 'Server draft 76 handshake' do
+  let(:handshake) { WebSocket::Handshake::Server.new }
+  let(:version) { 76 }
+  let(:client_request) { client_handshake_76(@request_params || {}) }
+  let(:server_response) { server_handshake_76(@request_params || {}) }
+
+  it_should_behave_like 'all server drafts'
+
+  it "should disallow request without spaces in key 1" do
+    @request_params = { :key1 => "4 at 146546xW%0l15" }
+    handshake << client_request
+
+    handshake.should be_finished
+    handshake.should_not be_valid
+    handshake.error.should eql(:invalid_handshake_authentication)
+  end
+
+  it "should disallow request without spaces in key 2" do
+    @request_params = { :key2 => "129985Y31.P00" }
+    handshake << client_request
+
+    handshake.should be_finished
+    handshake.should_not be_valid
+    handshake.error.should eql(:invalid_handshake_authentication)
+  end
+
+  it "should disallow request with invalid number of spaces or numbers in key 1" do
+    @request_params = { :key1 => "4 @1   46546xW%0l 1 5" }
+    handshake << client_request
+
+    handshake.should be_finished
+    handshake.should_not be_valid
+    handshake.error.should eql(:invalid_handshake_authentication)
+  end
+
+  it "should disallow request with invalid number of spaces or numbers in key 2" do
+    @request_params = { :key2 => "12998  5 Y3 1  .P00" }
+    handshake << client_request
+
+    handshake.should be_finished
+    handshake.should_not be_valid
+    handshake.error.should eql(:invalid_handshake_authentication)
+  end
+end
diff --git a/app/server/vendor/websocket/spec/spec_helper.rb b/app/server/vendor/websocket/spec/spec_helper.rb
new file mode 100755
index 0000000..72777bd
--- /dev/null
+++ b/app/server/vendor/websocket/spec/spec_helper.rb
@@ -0,0 +1,11 @@
+require 'rspec'
+require 'webrick'
+
+require 'websocket'
+Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
+
+RSpec.configure do |config|
+  config.before(:suite) do
+    WebSocket.max_frame_size = 100 * 1024 # 100kb
+  end
+end
diff --git a/app/server/vendor/websocket/spec/support/all_client_drafts.rb b/app/server/vendor/websocket/spec/support/all_client_drafts.rb
new file mode 100755
index 0000000..b979744
--- /dev/null
+++ b/app/server/vendor/websocket/spec/support/all_client_drafts.rb
@@ -0,0 +1,98 @@
+shared_examples_for 'all client drafts' do
+  def validate_request
+    handshake.to_s.should eql(client_request)
+
+    handshake << server_response
+
+    handshake.error.should be_nil
+    handshake.should be_finished
+    handshake.should be_valid
+  end
+
+  it "should be valid" do
+    handshake << server_response
+
+    handshake.error.should be_nil
+    handshake.should be_finished
+    handshake.should be_valid
+  end
+
+  it "should return valid version" do
+    handshake.version.should eql(version)
+  end
+
+  it "should return valid host" do
+    @request_params = { :host => "www.test.cc" }
+    handshake.host.should eql('www.test.cc')
+  end
+
+  it "should return valid path" do
+    @request_params = { :path => "/custom" }
+    handshake.path.should eql('/custom')
+  end
+
+  it "should return valid query" do
+    @request_params = { :query => "aaa=bbb" }
+    handshake.query.should eql("aaa=bbb")
+  end
+
+  it "should return valid port" do
+    @request_params = { :port => 123 }
+    handshake.port.should eql(123)
+  end
+
+  it "should parse uri" do
+    @request_params = { :uri => "ws://test.example.org:301/test_path?query=true" }
+    handshake.host.should eql('test.example.org')
+    handshake.port.should eql(301)
+    handshake.path.should eql('/test_path')
+    handshake.query.should eql('query=true')
+  end
+
+  it "should parse url" do
+    @request_params = { :url => "ws://test.example.org:301/test_path?query=true" }
+    handshake.host.should eql('test.example.org')
+    handshake.port.should eql(301)
+    handshake.path.should eql('/test_path')
+    handshake.query.should eql('query=true')
+  end
+
+  it "should resolve correct path with root server provided" do
+    @request_params = { :url => "ws://test.example.org" }
+    handshake.path.should eql('/')
+  end
+
+  it "should return valid response" do
+    validate_request
+  end
+
+  it "should allow custom path" do
+    @request_params = { :path => "/custom" }
+    validate_request
+  end
+
+  it "should allow query in path" do
+    @request_params = { :query => "test=true" }
+    validate_request
+  end
+
+  it "should allow custom port" do
+    @request_params = { :port => 123 }
+    validate_request
+  end
+
+  it "should recognize unfinished requests" do
+    handshake << server_response[0..-20]
+
+    handshake.should_not be_finished
+    handshake.should_not be_valid
+  end
+
+  it "should disallow requests with invalid request method" do
+    handshake << server_response.gsub('101', '404')
+
+    handshake.should be_finished
+    handshake.should_not be_valid
+    handshake.error.should eql(:invalid_status_code)
+  end
+end
diff --git a/app/server/vendor/websocket/spec/support/all_server_drafts.rb b/app/server/vendor/websocket/spec/support/all_server_drafts.rb
new file mode 100755
index 0000000..55b4fc4
--- /dev/null
+++ b/app/server/vendor/websocket/spec/support/all_server_drafts.rb
@@ -0,0 +1,119 @@
+shared_examples_for 'all server drafts' do
+  def validate_request
+    handshake << client_request
+
+    handshake.error.should be_nil
+    handshake.should be_finished
+    handshake.should be_valid
+    handshake.to_s.should eql(server_response)
+  end
+
+  it "should be valid" do
+    handshake << client_request
+
+    handshake.error.should be_nil
+    handshake.should be_finished
+    handshake.should be_valid
+  end
+
+  it "should return valid version" do
+    handshake << client_request
+
+    handshake.version.should eql(version)
+  end
+
+  it "should return valid host" do
+    @request_params = { :host => "www.test.cc" }
+    handshake << client_request
+
+    handshake.host.should eql('www.test.cc')
+  end
+
+  it "should return valid path" do
+    @request_params = { :path => "/custom" }
+    handshake << client_request
+
+    handshake.path.should eql('/custom')
+  end
+
+  it "should return valid query" do
+    @request_params = { :path => "/custom?aaa=bbb" }
+    handshake << client_request
+
+    handshake.query.should eql('aaa=bbb')
+  end
+
+  it "should return valid port" do
+    @request_params = { :port => 123 }
+    handshake << client_request
+
+    handshake.port.should eql("123")
+  end
+
+  it "should return valid response" do
+    validate_request
+  end
+
+  it "should allow custom path" do
+    @request_params = { :path => "/custom" }
+    validate_request
+  end
+
+  it "should allow query in path" do
+    @request_params = { :path => "/custom?test=true" }
+    validate_request
+  end
+
+  it "should allow custom port" do
+    @request_params = { :port => 123 }
+    validate_request
+  end
+
+  it "should recognize unfinished requests" do
+    handshake << client_request[0..-10]
+
+    handshake.should_not be_finished
+    handshake.should_not be_valid
+  end
+
+  it "should disallow requests with invalid request method" do
+    handshake << client_request.gsub('GET', 'POST')
+
+    handshake.should be_finished
+    handshake.should_not be_valid
+    handshake.error.should eql(:get_request_required)
+  end
+
+  it "should parse a rack request" do
+    request = WEBrick::HTTPRequest.new( :ServerSoftware => "rspec" )
+    request.parse(StringIO.new(client_request)).should be_true
+    rest    = client_request.slice((request.to_s.length..-1))
+
+    handshake.from_rack(request.meta_vars.merge(
+      "rack.input" => StringIO.new(rest)
+    ))
+    validate_request
+  end
+
+  it "should parse a hash request" do
+    request = WEBrick::HTTPRequest.new( :ServerSoftware => "rspec" )
+    request.parse(StringIO.new(client_request)).should be_true
+    body = client_request.slice((request.to_s.length..-1))
+
+    path = request.path
+    query = request.query_string
+    headers = request.header.inject({}) do |hash, header|
+      hash[header[0]] = header[1].first if header[0] && header[1]
+      hash
+    end
+
+    handshake.from_hash({
+      :headers => headers,
+      :path => path,
+      :query => query,
+      :body => body
+    })
+
+    validate_request
+  end
+end
diff --git a/app/server/vendor/websocket/spec/support/frames_base.rb b/app/server/vendor/websocket/spec/support/frames_base.rb
new file mode 100755
index 0000000..3afbb13
--- /dev/null
+++ b/app/server/vendor/websocket/spec/support/frames_base.rb
@@ -0,0 +1,15 @@
+module WebSocket
+  module Frame
+    class Base
+
+      def incoming_masking?
+        @handler.masking?
+      end
+
+      def outgoing_masking?
+        false
+      end
+
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/spec/support/handshake_requests.rb b/app/server/vendor/websocket/spec/support/handshake_requests.rb
new file mode 100755
index 0000000..f0b8e88
--- /dev/null
+++ b/app/server/vendor/websocket/spec/support/handshake_requests.rb
@@ -0,0 +1,72 @@
+def client_handshake_75(args = {})
+  <<-EOF
+GET #{args[:path] || "/demo"}#{"?#{args[:query]}" if args[:query]} HTTP/1.1\r
+Upgrade: WebSocket\r
+Connection: Upgrade\r
+Host: #{args[:host] || "example.com"}#{":#{args[:port]}" if args[:port]}\r
+Origin: http://example.com\r
+\r
+  EOF
+end
+
+def server_handshake_75(args = {})
+  <<-EOF
+HTTP/1.1 101 Web Socket Protocol Handshake\r
+Upgrade: WebSocket\r
+Connection: Upgrade\r
+WebSocket-Origin: http://example.com\r
+WebSocket-Location: ws#{args[:secure] ? "s" : ""}://#{args[:host] || "example.com"}#{":#{args[:port]}" if args[:port]}#{args[:path] || "/demo"}\r
+\r
+  EOF
+end
+
+def client_handshake_76(args = {})
+  request = <<-EOF
+GET #{args[:path] || "/demo"}#{"?#{args[:query]}" if args[:query]} HTTP/1.1\r
+Upgrade: WebSocket\r
+Connection: Upgrade\r
+Host: #{args[:host] || "example.com"}#{":#{args[:port]}" if args[:port]}\r
+Origin: http://example.com\r
+Sec-WebSocket-Key1: #{args[:key1] || "4 @1  46546xW%0l 1 5"}\r
+Sec-WebSocket-Key2: #{args[:key2] || "12998 5 Y3 1  .P00"}\r
+\r
+#{args[:key3] || "^n:ds[4U"}
+  EOF
+  request[0..-2]
+end
+
+def server_handshake_76(args = {})
+  request = <<-EOF
+HTTP/1.1 101 WebSocket Protocol Handshake\r
+Upgrade: WebSocket\r
+Connection: Upgrade\r
+Sec-WebSocket-Origin: http://example.com\r
+Sec-WebSocket-Location: ws#{args[:secure] ? "s" : ""}://#{args[:host] || "example.com"}#{":#{args[:port]}" if args[:port]}#{args[:path] || "/demo"}\r
+\r
+#{args[:challenge] || "8jKS'y:G*Co,Wxa-"}
+  EOF
+  request[0..-2]
+end
+
+def client_handshake_04(args = {})
+  <<-EOF
+GET #{args[:path] || "/demo"}#{"?#{args[:query]}" if args[:query]} HTTP/1.1\r
+Upgrade: websocket\r
+Connection: Upgrade\r
+Host: #{args[:host] || "example.com"}#{":#{args[:port]}" if args[:port]}\r
+Sec-WebSocket-Origin: http://example.com\r
+Sec-WebSocket-Version: #{args[:version] || "4"}\r
+Sec-WebSocket-Key: #{args[:key] || "dGhlIHNhbXBsZSBub25jZQ=="}\r
+\r
+  EOF
+end
+
+def server_handshake_04(args = {})
+  <<-EOF
+HTTP/1.1 101 Switching Protocols\r
+Upgrade: websocket\r
+Connection: Upgrade\r
+Sec-WebSocket-Accept: #{args[:accept] || "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="}\r
+\r
+  EOF
+end
diff --git a/app/server/vendor/websocket/spec/support/incoming_frames.rb b/app/server/vendor/websocket/spec/support/incoming_frames.rb
new file mode 100755
index 0000000..59d17ac
--- /dev/null
+++ b/app/server/vendor/websocket/spec/support/incoming_frames.rb
@@ -0,0 +1,55 @@
+shared_examples_for 'valid_incoming_frame' do
+  let(:decoded_text_array) { decoded_text == "" ? [""] : Array(decoded_text) } # Bug in Ruby 1.8 -> Array("") => [] instead of [""]
+  let(:frame_type_array) { Array(frame_type) }
+
+  its(:class) { should eql(WebSocket::Frame::Incoming) }
+  its(:data) { should eql(encoded_text || "") }
+  its(:version) { should eql(version) }
+  its(:type) { should be_nil }
+  its(:decoded?) { should be_false }
+  its(:to_s) { should eql(encoded_text || "") }
+
+  it "should have specified number of returned frames" do
+    decoded_text_array.each_with_index do |da, index|
+      n = subject.next
+      n.should_not be_nil, "Should return frame for #{da}, #{frame_type_array[index]}"
+      n.class.should eql(WebSocket::Frame::Incoming), "Should be WebSocket::Frame::Incoming, #{n} received instead"
+    end
+    subject.next.should be_nil
+    if error.is_a?(Class)
+      subject.error.should eql(error.new.message)
+    else
+      subject.error.should eql(error)
+    end
+  end
+
+  it "should return valid decoded frame for each specified decoded texts" do
+    decoded_text_array.each_with_index do |da, index|
+      f = subject.next
+      f.decoded?.should be_true
+      f.type.should eql(frame_type_array[index])
+      f.to_s.should eql(da)
+    end
+  end
+
+  context "with raising" do
+    before { WebSocket.should_raise = true }
+    after { WebSocket.should_raise = false }
+
+    it "should have specified number of returned frames" do
+      expect do
+        decoded_text_array.each_with_index do |da, index|
+          n = subject.next
+          n.should_not be_nil, "Should return frame for #{da}, #{frame_type_array[index]}"
+          n.class.should eql(WebSocket::Frame::Incoming), "Should be WebSocket::Frame::Incoming, #{n} received instead"
+        end
+        subject.next.should be_nil
+        if error.is_a?(Class)
+          subject.error.should eql(error.new.message)
+        else
+          subject.error.should eql(error)
+        end
+      end.to raise_error(error) if error
+    end
+  end
+end
diff --git a/app/server/vendor/websocket/spec/support/outgoing_frames.rb b/app/server/vendor/websocket/spec/support/outgoing_frames.rb
new file mode 100755
index 0000000..2722171
--- /dev/null
+++ b/app/server/vendor/websocket/spec/support/outgoing_frames.rb
@@ -0,0 +1,14 @@
+shared_examples_for 'valid_outgoing_frame' do
+  its(:class) { should eql(WebSocket::Frame::Outgoing) }
+  its(:version) { should eql(version) }
+  its(:type) { should eql(frame_type) }
+  its(:data) { should eql(decoded_text) }
+  its(:to_s) { should eql(encoded_text) }
+
+  context "after parsing" do
+    before { subject.to_s }
+    its(:error) { should eql(error) }
+    its(:require_sending?) { should eql(require_sending) }
+  end
+
+end
diff --git a/app/server/vendor/websocket/spec/support/overwrites.rb b/app/server/vendor/websocket/spec/support/overwrites.rb
new file mode 100755
index 0000000..beb9386
--- /dev/null
+++ b/app/server/vendor/websocket/spec/support/overwrites.rb
@@ -0,0 +1,9 @@
+module WebSocket
+
+  module Handshake
+    class Base
+      attr_reader :handler
+    end
+  end
+
+end
diff --git a/app/server/vendor/websocket/websocket.gemspec b/app/server/vendor/websocket/websocket.gemspec
new file mode 100755
index 0000000..169971d
--- /dev/null
+++ b/app/server/vendor/websocket/websocket.gemspec
@@ -0,0 +1,19 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "websocket/version"
+
+Gem::Specification.new do |s|
+  s.name        = "websocket"
+  s.version     = WebSocket::VERSION
+  s.platform    = Gem::Platform::RUBY
+  s.authors     = ["Bernard Potocki"]
+  s.email       = ["bernard.potocki at imanel.org"]
+  s.homepage    = "http://github.com/imanel/websocket-ruby"
+  s.summary     = %q{Universal Ruby library to handle WebSocket protocol}
+  s.description = %q{Universal Ruby library to handle WebSocket protocol}
+
+  s.files         = `git ls-files`.split("\n")
+  s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
+  s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+  s.require_paths = ["lib"]
+end
diff --git a/bin/sonic-pi b/bin/sonic-pi
index 0dde0e4..5f7d776 100755
--- a/bin/sonic-pi
+++ b/bin/sonic-pi
@@ -1,5 +1,18 @@
 #!/bin/bash
 
+#--
+# This file is part of Sonic Pi: http://sonic-pi.net
+# Full project source: https://github.com/samaaron/sonic-pi
+# License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+#
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+# All rights reserved.
+#
+# Permission is granted for use, copying, modification, and
+# distribution of modified versions of this work as long as this
+# notice is included.
+#++
+
 eval $(dbus-launch --auto-syntax)
 
 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
diff --git a/bin/sonic-pi-graffiti b/bin/sonic-pi-graffiti
new file mode 100755
index 0000000..1f113d4
--- /dev/null
+++ b/bin/sonic-pi-graffiti
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+#--
+# This file is part of Sonic Pi: http://sonic-pi.net
+# Full project source: https://github.com/samaaron/sonic-pi
+# License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+#
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+# All rights reserved.
+#
+# Permission is granted for use, copying, modification, and
+# distribution of modified versions of this work as long as this
+# notice is included.
+#++
+echo '
+
+                                ╘
+                         ─       ╛▒╛
+                          ▐╫       ▄█├
+                   ─╟╛      █▄      ╪▓▀
+         ╓┤┤┤┤┤┤┤┤┤  ╩▌      ██      ▀▓▌
+          ▐▒   ╬▒     ╟▓╘    ─▓█      ▓▓├
+          ▒╫   ▒╪      ▓█     ▓▓─     ▓▓▄
+         ╒▒─  │▒       ▓█     ▓▓     ─▓▓─
+         ╬▒   ▄▒ ╒    ╪▓═    ╬▓╬     ▌▓▄
+         ╥╒   ╦╥     ╕█╒    ╙▓▐     ▄▓╫
+                    ▐╩     ▒▒      ▀▀
+                         ╒╪      ▐▄
+
+       _____             __        ____  __
+      / ___/____  ____  /_/____   / __ \/_/
+      \__ \/ __ \/ __ \/ / ___/  / /_/ / /
+     ___/ / /_/ / / / / / /__   / ____/ /
+    /____/\____/_/ /_/_/\___/  /_/   /_/
+
+     The Live Coding Synth for Everyone
+
+            http://sonic-pi.net
+
+'
diff --git a/etc/doc/cheatsheets/fx.md b/etc/doc/cheatsheets/fx.md
index 1394db5..91aaead 100644
--- a/etc/doc/cheatsheets/fx.md
+++ b/etc/doc/cheatsheets/fx.md
@@ -1,1263 +1,1736 @@
 # FX
 
-* [FX Reverb](#fx-reverb)
-* [FX Reverb](#fx-reverb)
-* [FX Level Amplifier](#fx-level-amplifier)
-* [FX Level Amplifier](#fx-level-amplifier)
-* [FX Echo](#fx-echo)
-* [FX Echo](#fx-echo)
-* [FX Slicer](#fx-slicer)
-* [FX Slicer](#fx-slicer)
-* [FX Techno](#fx-techno)
-* [FX Techno](#fx-techno)
-* [FX Compressor](#fx-compressor)
-* [FX Compressor](#fx-compressor)
-* [FX Resonant Low Pass Filter](#fx-resonant-low-pass-filter)
-* [FX Resonant Low Pass Filter](#fx-resonant-low-pass-filter)
-* [FX Normalised Resonant Low Pass Filter](#fx-normalised-resonant-low-pass-filter)
-* [FX Normalised Resonant Low Pass Filter](#fx-normalised-resonant-low-pass-filter)
-* [FX Resonant High Pass Filter](#fx-resonant-high-pass-filter)
-* [FX Resonant High Pass Filter](#fx-resonant-high-pass-filter)
-* [FX Normalised Resonant High Pass Filter](#fx-normalised-resonant-high-pass-filter)
-* [FX Normalised Resonant High Pass Filter](#fx-normalised-resonant-high-pass-filter)
-* [FX High Pass Filter](#fx-high-pass-filter)
-* [FX High Pass Filter](#fx-high-pass-filter)
-* [FX Normalised High Pass Filter](#fx-normalised-high-pass-filter)
-* [FX Normalised High Pass Filter](#fx-normalised-high-pass-filter)
-* [FX Low Pass Filter](#fx-low-pass-filter)
-* [FX Low Pass Filter](#fx-low-pass-filter)
-* [FX Normalised Low Pass Filter](#fx-normalised-low-pass-filter)
-* [FX Normalised Low Pass Filter](#fx-normalised-low-pass-filter)
-* [FX Normaliser](#fx-normaliser)
-* [FX Normaliser](#fx-normaliser)
-* [FX Distortion](#fx-distortion)
-* [FX Distortion](#fx-distortion)
-
-## FX Reverb
+* [Bitcrusher](#bitcrusher)
+* [krush](#krush)
+* [Reverb](#reverb)
+* [GVerb](#gverb)
+* [Level Amplifier](#level-amplifier)
+* [Echo](#echo)
+* [Slicer](#slicer)
+* [Pan Slicer](#pan-slicer)
+* [Wobble](#wobble)
+* [Techno from IXI Lang](#techno-from-ixi-lang)
+* [Compressor](#compressor)
+* [Whammy](#whammy)
+* [Resonant Low Pass Filter](#resonant-low-pass-filter)
+* [Normalised Resonant Low Pass Filter](#normalised-resonant-low-pass-filter)
+* [Resonant High Pass Filter](#resonant-high-pass-filter)
+* [Normalised Resonant High Pass Filter](#normalised-resonant-high-pass-filter)
+* [High Pass Filter](#high-pass-filter)
+* [Normalised High Pass Filter](#normalised-high-pass-filter)
+* [Low Pass Filter](#low-pass-filter)
+* [Normalised Low Pass Filter.](#normalised-low-pass-filter.)
+* [Normaliser](#normaliser)
+* [Distortion](#distortion)
+* [Pan](#pan)
+* [Band Pass Filter](#band-pass-filter)
+* [Normalised Band Pass Filter](#normalised-band-pass-filter)
+* [Resonant Band Pass Filter](#resonant-band-pass-filter)
+* [Normalised Resonant Band Pass Filter](#normalised-resonant-band-pass-filter)
+* [Band EQ Filter](#band-eq-filter)
+* [Hyperbolic Tangent](#hyperbolic-tangent)
+* [Pitch shift](#pitch-shift)
+* [Ring Modulator](#ring-modulator)
+* [Octaver](#octaver)
+* [Vowel](#vowel)
+* [Flanger](#flanger)
+
+## Bitcrusher
 
 ### Key:
-  :reverb
+  :bitcrusher
 
 ### Doc:
-  Please write documentation!
+  Creates lo-fi output by decimating and deconstructing the incoming audio by lowering both the sample rate and bit depth. The default sample rate for CD audio is 44100, so use values less than that for that crunchy chip-tune sound full of artefacts and bitty distortion. Similarly, the default bit depth for CD audio is 16, so use values less than that for lo-fi sound.
 
-### Arguments:
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * mix:
-    - doc: write me
-    - default: 0.4
-    - constraints: none
-    - Can not be changed once set
-
-  * mix_slide:
-    - doc: write me
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * sample_rate:
+    - doc: The sample rate the audio will be resampled at. This represents the number of times per second the audio is sampled. The higher the sample rate, the closer to the original the sound will be, the lower the more low-fi it will sound. The highest sample rate is 44100 (full quality) and the lowest is ~100 (extremely low quality). Try values in between such as 1000, 3000, 8000...
+    - default: 10000
+    - constraints: must be greater than zero
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * bits:
+    - doc: The bit depth of the resampled audio. Lower bit depths make the audio sound grainy and less defined. The highest bit depth is 16 (full quality) and the lowest is 1 (lowest quality).
+    - default: 8
+    - constraints: must be greater than zero
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
     - default: 0
-    - constraints: none
-    - Can not be changed once set
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
-  * room:
-    - doc: write me
-    - default: 0.6
-    - constraints: none
-    - Can not be changed once set
 
-  * room_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
+## krush
 
-  * damp:
-    - doc: write me
-    - default: 0.5
-    - constraints: none
-    - Can not be changed once set
+### Key:
+  :krush
 
-  * damp_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
+### Doc:
+  Krush that sound!
 
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * gain:
+    - doc: Amount of crushing to serve
+    - default: 5
+    - constraints: must be greater than zero
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## FX Reverb
+## Reverb
 
 ### Key:
-  :replace_reverb
+  :reverb
 
 ### Doc:
-  Please write documentation!
+  Make the incoming signal sound more spacious or distant as if it were played in a large room or cave. Signal may also be dampened by reducing the amplitude of the higher frequencies.
 
-### Arguments:
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * mix:
-    - doc: write me
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
     - default: 0.4
-    - constraints: none
-    - Can not be changed once set
-
-  * mix_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * room:
-    - doc: write me
+    - doc: The room size - a value between 0 (no reverb) and 1 (maximum reverb).
     - default: 0.6
-    - constraints: none
-    - Can not be changed once set
-
-  * room_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * damp:
-    - doc: write me
+    - doc: High frequency dampening - a value between 0 (no dampening) and 1 (maximum dampening)
     - default: 0.5
-    - constraints: none
-    - Can not be changed once set
-
-  * damp_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## FX Level Amplifier
+## GVerb
 
 ### Key:
-  :level
+  :gverb
 
 ### Doc:
-  Please write documentation!
+  Make the incoming signal sound more spacious or distant as if it were played in a large room or cave. Similar to reverb but with a more spacious feel.
 
-### Arguments:
+### Opts:
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 0.4
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * spread:
+    - doc: Stereo spread. Amount of stereo spread the reverb has over the left and right channels. A value of 0 means no spread at all - left and right stereo values of the incoming signal are preserved. A value of 1 means full spread - the left and right channels are fully mixed within the reverb - bleeding into each other.
+    - default: 0.5
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * damp:
+    - doc: High frequency rolloff. 0 is no damping (the reverb will ring out more) and 1 dampens the reverb signal completely
+    - default: 0.5
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_damp:
+    - doc: High frequency rolloff of input signal. 0 is no damping (the reverb will ring out more) and 1 dampens the reverb signal completely
+    - default: 0.5
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * dry:
+    - doc: Amount of original dry signal present in the effect. This is distinct from mix.
+    - default: 1
+    - constraints: must be a value greater than or equal to 0
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * room:
+    - doc: The room size in squared metres
+    - default: 10
+    - constraints: must be a value greater than or equal to 0
+    - May be changed whilst playing
+  * release:
+    - doc: Time for reverberation to complete in seconds
+    - default: 3
+    - constraints: must be a value greater than 0
+    - May be changed whilst playing
+  * ref_level:
+    - doc: Reflection level
+    - default: 0.7
+    - constraints: must be a value greater than or equal to 0
+    - May be changed whilst playing
+  * tail_level:
+    - doc: Tail level amount
+    - default: 0.5
+    - constraints: must be a value greater than or equal to 0
+    - May be changed whilst playing
 
 
-
-## FX Level Amplifier
+## Level Amplifier
 
 ### Key:
-  :replace_level
+  :level
 
 ### Doc:
-  Please write documentation!
+  Amplitude modifier. All FX have their own amp built in, so it may be the case that you don't specifically need an isolated amp FX. However, it is useful to be able to control the overall amplitude of a number of running synths. All sounds created in the FX block will have their amplitudes multipled by the amp level of this FX. For example, use an amp of 0 to silence all internal synths.
 
-### Arguments:
+### Opts:
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
 
 
-## FX Echo
+## Echo
 
 ### Key:
   :echo
 
 ### Doc:
-  Please write documentation!
+  Standard echo with variable phase duration (time between echoes) and decay (length of echo fade out). If you wish to have a phase duration longer than 2s, you need to specify the longest phase duration you'd like with the arg max_phase. Be warned, echo FX with very long phases can consume a lot of memory and take longer to initialise.
 
-### Arguments:
-  * max_delay:
-    - doc: The maximum delay time in seconds.
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
-    - constraints: must be greater than zero
-    - Can not be changed once set
-
-  * delay:
-    - doc: The time between echoes in seconds.
-    - default: 0.4
-    - constraints: must be greater than zero
-    - May be changed whilst playing
-
-  * delay_slide:
-    - doc: Slide time in seconds between delay values
-    - default: 0
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * decay:
-    - doc: The time it takes for the echoes to fade away in seconds.
-    - default: 8
-    - constraints: must be greater than zero
-    - May be changed whilst playing
-
-  * decay_slide:
-    - doc: Slide time in seconds between decay times
-    - default: 0
-    - constraints: must be zero or greater
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
     - May be changed whilst playing
-
-  * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * phase:
+    - doc: The time between echoes in beats.
+    - default: 0.25
+    - constraints: must be greater than zero
+    - May be changed whilst playing
+    - Scaled with current BPM value
+    - Has slide parameters for shaping changes
+  * decay:
+    - doc: The time it takes for the echoes to fade away in beats.
+    - default: 2
+    - constraints: must be greater than zero
+    - May be changed whilst playing
+    - Scaled with current BPM value
+    - Has slide parameters for shaping changes
+  * max_phase:
+    - doc: The maximum phase duration in beats.
+    - default: 2
+    - constraints: must be greater than zero
+    - Can not be changed once set
 
 
-
-## FX Echo
+## Slicer
 
 ### Key:
-  :replace_echo
+  :slicer
 
 ### Doc:
-  Please write documentation!
+  Modulates the amplitude of the input signal with a specific control wave and phase duration. With the default pulse wave, slices the signal in and out, with the triangle wave, fades the signal in and out and with the saw wave, phases the signal in and then dramatically out. Control wave may be inverted with the arg invert_wave for more variety.
 
-### Arguments:
-  * max_delay:
-    - doc: The maximum delay time in seconds.
+### Opts:
+  * amp:
+    - doc: The amplitude of the resulting effect.
     - default: 1
-    - constraints: must be greater than zero
-    - Can not be changed once set
-
-  * delay:
-    - doc: The time between echoes in seconds.
-    - default: 0.4
-    - constraints: must be greater than zero
+    - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * delay_slide:
-    - doc: Slide time in seconds between delay values
-    - default: 0
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * decay:
-    - doc: The time it takes for the echoes to fade away in seconds.
-    - default: 8
+    - Has slide parameters for shaping changes
+  * phase:
+    - doc: The phase duration (in beats) of the slices
+    - default: 0.25
     - constraints: must be greater than zero
     - May be changed whilst playing
-
-  * decay_slide:
-    - doc: Slide time in seconds between decay times
+    - Scaled with current BPM value
+    - Has slide parameters for shaping changes
+  * amp_min:
+    - doc: Minimum amplitude of the slicer
     - default: 0
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - Has slide parameters for shaping changes
+  * amp_max:
+    - doc: Maximum amplitude of the slicer
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-
-
-## FX Slicer
-
-### Key:
-  :slicer
-
-### Doc:
-  Please write documentation!
-
-### Arguments:
-  * rate:
-    - doc: The frequency of the slices
-    - default: 4
-    - constraints: must be greater than zero
+    - Has slide parameters for shaping changes
+  * pulse_width:
+    - doc: The width of the pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Different values will change the timbre of the sound. Only valid if wave is type pulse.
+    - default: 0.5
+    - constraints: must be a value between 0 and 1 exclusively
     - May be changed whilst playing
-
-  * rate_slide:
-    - doc: Slide time in seconds between rate values
+    - Has slide parameters for shaping changes
+  * phase_offset:
+    - doc: Initial phase offset.
     - default: 0
-    - constraints: must be zero or greater
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+  * wave:
+    - doc: Control waveform used to modulate the amplitude. 0=saw, 1=pulse, 2=tri, 3=sine
+    - default: 1
+    - constraints: must be one of the following values: [0, 1, 2, 3]
     - May be changed whilst playing
-
-  * width:
-    - doc: The width of the slices - 0 - 1.
-    - default: 0.5
-    - constraints: must be a value between 0 and 1 exclusively
+  * invert_wave:
+    - doc: Invert control waveform (i.e. flip it on the y axis). 0=uninverted wave, 1=inverted wave.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
     - May be changed whilst playing
-
-  * width_slide:
-    - doc: Slide time in seconds between width values
+  * probability:
+    - doc: Probability (as a value between 0 and 1) that a given slice will be replaced by the value of the  prob_pos opt (which defaults to 0, i.e. silence)
     - default: 0
-    - constraints: must be zero or greater
+    - constraints: must be a value between 0 and 1 inclusively
     - May be changed whilst playing
-
-  * phase:
-    - doc: Initial phase.
+    - Has slide parameters for shaping changes
+  * prob_pos:
+    - doc: Position of the slicer that will be jumped to when the probability test passes as a value between 0 and 1
     - default: 0
     - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * seed:
+    - doc: Seed value for rand num generator used for probability test
+    - default: 0
+    - constraints: none
     - Can not be changed once set
-
-  * amp:
-    - doc: The amplitude of the resulting effect.
-    - default: 1
+  * smooth:
+    - doc: Amount of time in seconds to transition from the current value to the next. Allows you to round off harsh edges in the slicer wave which may cause clicks.
+    - default: 0
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: The slide lag time for amplitude changes.
-    - default: 0.05
+    - Has slide parameters for shaping changes
+  * smooth_up:
+    - doc: Amount of time in seconds to transition from the current value to the next only when the value is going up. This smoothing happens before the main smooth mechanism.
+    - default: 0
     - constraints: must be zero or greater
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * smooth_down:
+    - doc: Amount of time in seconds to transition from the current value to the next only when the value is going down. This smoothing happens before the main smooth mechanism.
+    - default: 0
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## FX Slicer
+## Pan Slicer
 
 ### Key:
-  :replace_slicer
+  :panslicer
 
 ### Doc:
-  Please write documentation!
+  Slice the pan automatically from left to right. Behaves similarly to slicer and wobble FX but modifies stereo panning of sound in left and right speakers. Default slice wave form is square (hard slicing between left and right) however other wave forms can be set with the `wave:` opt.
 
-### Arguments:
-  * rate:
-    - doc: The frequency of the slices
-    - default: 4
-    - constraints: must be greater than zero
+### Opts:
+  * amp:
+    - doc: The amplitude of the resulting effect.
+    - default: 1
+    - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * rate_slide:
-    - doc: Slide time in seconds between rate values
-    - default: 0
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * width:
-    - doc: The width of the slices - 0 - 1.
+    - Has slide parameters for shaping changes
+  * phase:
+    - doc: The phase duration (in beats) of the slices
+    - default: 0.25
+    - constraints: must be greater than zero
+    - May be changed whilst playing
+    - Scaled with current BPM value
+    - Has slide parameters for shaping changes
+  * pan_min:
+    - doc: Minimum pan value (-1 is the left speaker only)
+    - default: -1
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan_max:
+    - doc: Maximum pan value (+1 is the right speaker only)
+    - default: 1
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pulse_width:
+    - doc: The width of the pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Different values will change the timbre of the sound. Only valid if wave is type pulse.
     - default: 0.5
     - constraints: must be a value between 0 and 1 exclusively
     - May be changed whilst playing
-
-  * width_slide:
-    - doc: Slide time in seconds between width values
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * phase:
-    - doc: Initial phase.
+    - Has slide parameters for shaping changes
+  * phase_offset:
+    - doc: Initial phase offset.
     - default: 0
     - constraints: must be a value between 0 and 1 inclusively
     - Can not be changed once set
-
-  * amp:
-    - doc: The amplitude of the resulting effect.
+  * wave:
+    - doc: Control waveform used to modulate the amplitude. 0=saw, 1=pulse, 2=tri, 3=sine
     - default: 1
+    - constraints: must be one of the following values: [0, 1, 2, 3]
+    - May be changed whilst playing
+  * invert_wave:
+    - doc: Invert control waveform (i.e. flip it on the y axis). 0=uninverted wave, 1=inverted wave.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * probability:
+    - doc: Probability (as a value between 0 and 1) that a given slice will be replaced by the value of the  prob_pos opt (which defaults to 0, i.e. silence)
+    - default: 0
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * prob_pos:
+    - doc: Position of the slicer that will be jumped to when the probability test passes as a value between 0 and 1
+    - default: 0
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * seed:
+    - doc: Seed value for rand num generator used for probability test
+    - default: 0
+    - constraints: none
+    - Can not be changed once set
+  * smooth:
+    - doc: Amount of time in seconds to transition from the current value to the next. Allows you to round off harsh edges in the slicer wave which may cause clicks.
+    - default: 0
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: The slide lag time for amplitude changes.
-    - default: 0.05
+    - Has slide parameters for shaping changes
+  * smooth_up:
+    - doc: Amount of time in seconds to transition from the current value to the next only when the value is going up. This smoothing happens before the main smooth mechanism.
+    - default: 0
     - constraints: must be zero or greater
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * smooth_down:
+    - doc: Amount of time in seconds to transition from the current value to the next only when the value is going down. This smoothing happens before the main smooth mechanism.
+    - default: 0
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## FX Techno
+## Wobble
 
 ### Key:
-  :techno
+  :wobble
 
 ### Doc:
-  Please write documentation!
+  Versatile wobble FX. Will repeatedly modulate a range of filters (rlpf, rhpf) between two cutoff values using a range of control wave forms (saw, pulse, tri, sine). You may alter the phase duration of the wobble, and the resonance of the filter. Combines well with the dsaw synth for crazy dub wobbles. Cutoff value is at cutoff_min at the start of phase
 
-### Arguments:
-  * rate:
-    - doc: The frequency of filter modulation
-    - default: 0.1
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * phase:
+    - doc: The phase duration (in beats) for filter modulation cycles
+    - default: 0.5
     - constraints: must be greater than zero
     - May be changed whilst playing
-
-  * rate_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - Scaled with current BPM value
+    - Has slide parameters for shaping changes
   * cutoff_min:
-    - doc: write me
-    - default: 880
-    - constraints: none
-    - Can not be changed once set
-
-  * cutoff_min_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - doc: Minimum (MIDI) note that filter will move to whilst wobbling. Choose a lower note for a higher range of movement. Full range of movement is the distance between cutoff_max and cutoff_min
+    - default: 60
+    - constraints: must be zero or greater,must be a value less than 130
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * cutoff_max:
-    - doc: write me
-    - default: 12000
-    - constraints: none
-    - Can not be changed once set
-
-  * cutoff_max_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - doc: Maximum (MIDI) note that filter will move to whilst wobbling. Choose a higher note for a higher range of movement. Full range of movement is the distance between cutoff_max and cutoff_min
+    - default: 120
+    - constraints: must be zero or greater,must be a value less than 130
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * res:
-    - doc: write me
-    - default: 0.2
-    - constraints: none
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0.8
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * phase_offset:
+    - doc: Initial modulation phase offset (a value between 0 and 1).
+    - default: 0
+    - constraints: must be a value between 0 and 1 inclusively
     - Can not be changed once set
-
-  * res_slide:
-    - doc: write me
+  * wave:
+    - doc: Wave shape of wobble. Use 0 for saw wave, 1 for pulse, 2 for triangle wave and 3 for a sine wave.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1, 2, 3]
+    - May be changed whilst playing
+  * invert_wave:
+    - doc: Invert control waveform (i.e. flip it on the y axis). 0=uninverted wave, 1=inverted wave.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * pulse_width:
+    - doc: Only valid if wave is type pulse.
+    - default: 0.5
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * filter:
+    - doc: Filter used for wobble effect. Use 0 for a resonant low pass filter or 1 for a resonant high pass filter
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * probability:
+    - doc: Probability (as a value between 0 and 1) that a given wobble will be replaced by the value of the  prob_pos opt (which defaults to 0, i.e. min_cutoff)
+    - default: 0
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * prob_pos:
+    - doc: Position of the wobble that will be jumped to when the probability test passes as a value between 0 and 1
+    - default: 0
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * seed:
+    - doc: Seed value for rand num generator used for probability test
     - default: 0
     - constraints: none
     - Can not be changed once set
+  * smooth:
+    - doc: Amount of time in seconds to transition from the current value to the next. Allows you to round off harsh edges in the slicer wave which may cause clicks.
+    - default: 0
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * smooth_up:
+    - doc: Amount of time in seconds to transition from the current value to the next only when the value is going up. This smoothing happens before the main smooth mechanism.
+    - default: 0
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * smooth_down:
+    - doc: Amount of time in seconds to transition from the current value to the next only when the value is going down. This smoothing happens before the main smooth mechanism.
+    - default: 0
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## FX Techno
+## Techno from IXI Lang
 
 ### Key:
-  :replace_techno
+  :ixi_techno
 
 ### Doc:
-  Please write documentation!
+  Moving resonant low pass filter between min and max cutoffs. Great for sweeping effects across long synths or samples.
 
-### Arguments:
-  * rate:
-    - doc: The frequency of filter modulation
-    - default: 0.1
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * phase:
+    - doc: The phase duration (in beats) for filter modulation cycles
+    - default: 4
     - constraints: must be greater than zero
     - May be changed whilst playing
-
-  * rate_slide:
-    - doc: write me
+    - Scaled with current BPM value
+    - Has slide parameters for shaping changes
+  * phase_offset:
+    - doc: Initial modulation phase offset (a value between 0 and 1).
     - default: 0
-    - constraints: none
+    - constraints: must be a value between 0 and 1 inclusively
     - Can not be changed once set
-
   * cutoff_min:
-    - doc: write me
-    - default: 880
-    - constraints: none
-    - Can not be changed once set
-
-  * cutoff_min_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - doc: Minimum (MIDI) note that filter will move to whilst wobbling. Choose a lower note for a higher range of movement. Full range of movement is the distance between cutoff_max and cutoff_min
+    - default: 60
+    - constraints: must be zero or greater,must be a value less than 130
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * cutoff_max:
-    - doc: write me
-    - default: 12000
-    - constraints: none
-    - Can not be changed once set
-
-  * cutoff_max_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - doc: Maximum (MIDI) note that filter will move to whilst wobbling. Choose a higher note for a higher range of movement. Full range of movement is the distance between cutoff_max and cutoff_min
+    - default: 120
+    - constraints: must be zero or greater,must be a value less than 130
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * res:
-    - doc: write me
-    - default: 0.2
-    - constraints: none
-    - Can not be changed once set
-
-  * res_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0.8
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## FX Compressor
+## Compressor
 
 ### Key:
   :compressor
 
 ### Doc:
-  Please write documentation!
+  Compresses the dynamic range of the incoming signal. Equivalent to automatically turning the amp down when the signal gets too loud and then back up again when it's quiet. Useful for ensuring the containing signal doesn't overwhelm other aspects of the sound. Also a general purpose hard-knee dynamic range processor which can be tuned via the opts to both expand and compress the signal.
 
-### Arguments:
+### Opts:
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * threshold:
-    - doc: write me
+    - doc: Threshold value determining the break point between slope_below and slope_above.
     - default: 0.2
-    - constraints: none
-    - Can not be changed once set
-
-  * threshold_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * clamp_time:
-    - doc: write me
+    - doc: Time taken for the amplitude adjustments to kick in fully (in seconds). This is usually pretty small (not much more than 10 milliseconds). Also known as the time of the attack phase
     - default: 0.01
-    - constraints: none
-    - Can not be changed once set
-
-  * clamp_time_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * slope_above:
-    - doc: write me
+    - doc: Slope of the amplitude curve above the threshold. A value of 1 means that the output of signals with amplitude above the threshold will be unaffected. Greater values will magnify and smaller values will attenuate the signal.
     - default: 0.5
     - constraints: none
-    - Can not be changed once set
-
-  * slope_above_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * slope_below:
-    - doc: write me
+    - doc: Slope of the amplitude curve below the threshold. A value of 1 means that the output of signals with amplitude below the threshold will be unaffected. Greater values will magnify and smaller values will attenuate the signal.
     - default: 1
     - constraints: none
-    - Can not be changed once set
-
-  * slope_below_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * relax_time:
-    - doc: write me
+    - doc: Time taken for the amplitude adjustments to be released. Usually a little longer than clamp_time. If both times are too short, you can get some (possibly unwanted) artefacts. Also known as the time of the release phase.
     - default: 0.01
-    - constraints: none
-    - Can not be changed once set
-
-  * relax_time_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## FX Compressor
+## Whammy
 
 ### Key:
-  :replace_compressor
+  :whammy
 
 ### Doc:
-  Please write documentation!
+  A cheap sounding transposition effect, with a slightly robotic edge. Good for adding alien sounds and harmonies to everything from beeps to guitar samples. It's similar to pitch shift although not as smooth sounding.
 
-### Arguments:
+### Opts:
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * threshold:
-    - doc: write me
-    - default: 0.2
-    - constraints: none
-    - Can not be changed once set
-
-  * threshold_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
-  * clamp_time:
-    - doc: write me
-    - default: 0.01
+    - Has slide parameters for shaping changes
+  * transpose:
+    - doc: This is how much to transpose the input, expressed as a midi pitch.
+    - default: 12
     - constraints: none
-    - Can not be changed once set
-
-  * clamp_time_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
-  * slope_above:
-    - doc: write me
-    - default: 0.5
-    - constraints: none
-    - Can not be changed once set
-
-  * slope_above_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
-  * slope_below:
-    - doc: write me
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * max_delay_time:
+    - doc: The max delay time to be used for the effect. This shouldn't need to be adjusted.
     - default: 1
-    - constraints: none
-    - Can not be changed once set
-
-  * slope_below_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
+    - constraints: must be zero or greater
     - Can not be changed once set
-
-  * relax_time:
-    - doc: write me
-    - default: 0.01
-    - constraints: none
+  * deltime:
+    - doc: The delay time to be used for the effect. This shouldn't need to be adjusted.
+    - default: 0.05
+    - constraints: must be zero or greater
     - Can not be changed once set
-
-  * relax_time_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
+  * grainsize:
+    - doc: The size of the initial grain used for transposition. This shouldn't need to be adjusted.
+    - default: 0.075
+    - constraints: must be zero or greater
     - Can not be changed once set
 
 
-
-## FX Resonant Low Pass Filter
+## Resonant Low Pass Filter
 
 ### Key:
   :rlpf
 
 ### Doc:
-  Please write documentation!
+  Dampens the parts of the signal that are higher than the cutoff point (typically the crunchy fizzy harmonic overtones) and keeps the lower parts (typically the bass/mid of the sound). The resonant part of the resonant low pass filter emphasises/resonates the frequencies around the cutoff point. The amount of emphasis is controlled by the res opt with a higher res resulting in greater resonance. High amounts of resonance (rq ~1) can create a whistling sound around the cutoff frequency.
 
-### Arguments:
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
-    - May be changed whilst playing
+  Choose a higher cutoff to keep more of the high frequences/treble of the sound and a lower cutoff to make the sound more dull and only keep the bass.
 
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * res:
-    - doc: write me
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
     - default: 0.5
-    - constraints: none
-    - Can not be changed once set
-
-  * res_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## FX Resonant Low Pass Filter
+## Normalised Resonant Low Pass Filter
 
 ### Key:
-  :replace_rlpf
+  :nrlpf
 
 ### Doc:
-  Please write documentation!
+  Dampens the parts of the signal that are higher than the cutoff point (typically the crunchy fizzy harmonic overtones) and keeps the lower parts (typically the bass/mid of the sound). The resonant part of the resonant low pass filter emphasises/resonates the frequencies around the cutoff point. The amount of emphasis is controlled by the res opt with a higher res resulting in greater resonance. High amounts of resonance (rq ~1) can create a whistling sound around the cutoff frequency.
 
-### Arguments:
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
-    - May be changed whilst playing
+  Choose a higher cutoff to keep more of the high frequences/treble of the sound and a lower cutoff to make the sound more dull and only keep the bass.
 
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * res:
-    - doc: write me
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
     - default: 0.5
-    - constraints: none
-    - Can not be changed once set
-
-  * res_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## FX Normalised Resonant Low Pass Filter
+## Resonant High Pass Filter
 
 ### Key:
-  :norm_rlpf
+  :rhpf
 
 ### Doc:
-  Please write documentation!
+  Dampens the parts of the signal that are lower than the cutoff point (typically the bass of the sound) and keeps the higher parts (typically the crunchy fizzy harmonic overtones). The resonant part of the resonant high pass filter emphasises/resonates the frequencies around the cutoff point. The amount of emphasis is controlled by the res opt with a higher res resulting in greater resonance. High amounts of resonance (rq ~1) can create a whistling sound around the cutoff frequency.
 
-### Arguments:
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
-    - May be changed whilst playing
+  Choose a lower cutoff to keep more of the bass/mid and a higher cutoff to make the sound more light and crispy.
 
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * res:
-    - doc: write me
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
     - default: 0.5
-    - constraints: none
-    - Can not be changed once set
-
-  * res_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## FX Normalised Resonant Low Pass Filter
+## Normalised Resonant High Pass Filter
 
 ### Key:
-  :replace_norm_rlpf
+  :nrhpf
 
 ### Doc:
-  Please write documentation!
+  Dampens the parts of the signal that are lower than the cutoff point (typically the bass of the sound) and keeps the higher parts (typically the crunchy fizzy harmonic overtones). The resonant part of the resonant high pass filter emphasises/resonates the frequencies around the cutoff point. The amount of emphasis is controlled by the res opt with a higher res resulting in greater resonance. High amounts of resonance (rq ~1) can create a whistling sound around the cutoff frequency.
 
-### Arguments:
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
-    - May be changed whilst playing
+  Choose a lower cutoff to keep more of the bass/mid and a higher cutoff to make the sound more light and crispy.
 
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * res:
-    - doc: write me
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
     - default: 0.5
-    - constraints: none
-    - Can not be changed once set
-
-  * res_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## FX Resonant High Pass Filter
+## High Pass Filter
 
 ### Key:
-  :rhpf
+  :hpf
 
 ### Doc:
-  Please write documentation!
+  Dampens the parts of the signal that are lower than the cutoff point (typically the bass of the sound) and keeps the higher parts (typically the crunchy fizzy harmonic overtones). Choose a lower cutoff to keep more of the bass/mid and a higher cutoff to make the sound more light and crispy.
 
-### Arguments:
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
     - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
+    - constraints: must be zero or greater,must be a value less than 131
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
 
-  * res:
-    - doc: write me
-    - default: 0.5
-    - constraints: none
-    - Can not be changed once set
+## Normalised High Pass Filter
 
-  * res_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
+### Key:
+  :nhpf
 
+### Doc:
+  A high pass filter chained to a normaliser. Ensures that the signal is both filtered by a standard high pass filter and then normalised to ensure the amplitude of the final output is constant. A high pass filter will reduce the amplitude of the resulting signal (as some of the sound has been filtered out) the normaliser can compensate for this loss (although will also have the side effect of flattening all dynamics). See doc for hpf.
+
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## FX Resonant High Pass Filter
+## Low Pass Filter
 
 ### Key:
-  :replace_rhpf
+  :lpf
 
 ### Doc:
-  Please write documentation!
+  Dampens the parts of the signal that are higher than the cutoff point (typically the crunchy fizzy harmonic overtones) and keeps the lower parts (typically the bass/mid of the sound). Choose a higher cutoff to keep more of the high frequences/treble of the sound and a lower cutoff to make the sound more dull and only keep the bass.
 
-### Arguments:
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
     - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
+    - constraints: must be zero or greater,must be a value less than 131
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
 
-  * res:
-    - doc: write me
-    - default: 0.5
-    - constraints: none
-    - Can not be changed once set
+## Normalised Low Pass Filter.
 
-  * res_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
+### Key:
+  :nlpf
 
+### Doc:
+  A low pass filter chained to a normaliser. Ensures that the signal is both filtered by a standard low pass filter and then normalised to ensure the amplitude of the final output is constant. A low pass filter will reduce the amplitude of the resulting signal (as some of the sound has been filtered out) the normaliser can compensate for this loss (although will also have the side effect of flattening all dynamics). See doc for lpf.
+
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## FX Normalised Resonant High Pass Filter
+## Normaliser
 
 ### Key:
-  :norm_rhpf
+  :normaliser
 
 ### Doc:
-  Please write documentation!
+  Raise or lower amplitude of sound to a specified level. Evens out the amplitude of incoming sound across the frequency spectrum by flattening all dynamics.
 
-### Arguments:
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * level:
+    - doc: The peak output amplitude level at which to normalise the input.
+    - default: 1
+    - constraints: must be a value greater than or equal to 0
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
-  * res:
-    - doc: write me
-    - default: 0.5
-    - constraints: none
-    - Can not be changed once set
 
-  * res_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
+## Distortion
 
+### Key:
+  :distortion
 
+### Doc:
+  Distorts the signal reducing clarity in favour of raw crunchy noise.
+
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * distort:
+    - doc: Amount of distortion to be applied (as a value between 0 and 1)
+    - default: 0.5
+    - constraints: must be a value greater than or equal to 0,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
-## FX Normalised Resonant High Pass Filter
+
+## Pan
 
 ### Key:
-  :replace_norm_rhpf
+  :pan
 
 ### Doc:
-  Please write documentation!
+  Specify where in the stereo field the sound should be heard. A value of -1 for pan will put the sound in the left speaker, a value of 1 will put the sound in the right speaker and values in between will shift the sound accordingly.
 
-### Arguments:
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * res:
-    - doc: write me
-    - default: 0.5
-    - constraints: none
-    - Can not be changed once set
-
-  * res_slide:
-    - doc: write me
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## FX High Pass Filter
+## Band Pass Filter
 
 ### Key:
-  :hpf
+  :bpf
 
 ### Doc:
-  Please write documentation!
+  Combines low pass and high pass filters to only allow a 'band' of frequencies through. If the band is very narrow (a low res value like 0.0001) then the BPF will reduce the original sound, almost down to a single frequency (controlled by the centre opt).
 
-### Arguments:
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
+  With higher values for res we can simulate other filters e.g. telephone lines, by cutting off low and high frequencies.
+
+Use FX `:band_eq` with a negative db for the opposite effect - to attenuate a given band of frequencies.
+
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
     - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * centre:
+    - doc: Centre frequency for the filter as a MIDI note.
+    - default: 100
+    - constraints: must be a value greater than or equal to 0
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0.6
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## FX High Pass Filter
+## Normalised Band Pass Filter
 
 ### Key:
-  :replace_hpf
+  :nbpf
 
 ### Doc:
-  Please write documentation!
+  Like the Band Pass Filter but normalised. The normaliser is useful here as some volume is lost when filtering the original signal.
 
-### Arguments:
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * centre:
+    - doc: Centre frequency for the filter as a MIDI note.
+    - default: 100
+    - constraints: must be a value greater than or equal to 0
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0.6
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## FX Normalised High Pass Filter
+## Resonant Band Pass Filter
 
 ### Key:
-  :norm_hpf
+  :rbpf
 
 ### Doc:
-  Please write documentation!
+  Like the Band Pass Filter but with a resonance (slight volume boost) around the target frequency. This can produce an interesting whistling effect, especially when used with larger values for the res opt.
 
-### Arguments:
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
+  * centre:
+    - doc: Centre frequency for the filter as a MIDI note.
+    - default: 100
+    - constraints: must be a value greater than or equal to 0
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * res:
-    - doc: write me
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
     - default: 0.5
-    - constraints: none
-    - Can not be changed once set
-
-  * res_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## FX Normalised High Pass Filter
+## Normalised Resonant Band Pass Filter
 
 ### Key:
-  :replace_norm_hpf
+  :nrbpf
 
 ### Doc:
-  Please write documentation!
+  Like the Band Pass Filter but normalised, with a resonance (slight volume boost) around the target frequency. This can produce an interesting whistling effect, especially when used with larger values for the res opt.
 
-### Arguments:
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
-    - May be changed whilst playing
+  The normaliser is useful here as some volume is lost when filtering the original signal.
 
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * centre:
+    - doc: Centre frequency for the filter as a MIDI note.
+    - default: 100
+    - constraints: must be a value greater than or equal to 0
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * res:
-    - doc: write me
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
     - default: 0.5
-    - constraints: none
-    - Can not be changed once set
-
-  * res_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## FX Low Pass Filter
+## Band EQ Filter
 
 ### Key:
-  :lpf
+  :band_eq
 
 ### Doc:
-  Please write documentation!
+  Attenuate or Boost a frequency band
 
-### Arguments:
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-
-
-## FX Low Pass Filter
-
-### Key:
-  :replace_lpf
-
-### Doc:
-  Please write documentation!
-
-### Arguments:
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - Has slide parameters for shaping changes
+  * freq:
+    - doc: Centre frequency of the band in MIDI.
     - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
+    - constraints: must be greater than zero
     - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Width of the band as a value between 0 and 1
+    - default: 0.6
+    - constraints: must be zero or greater,must be a value less than 1
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * db:
+    - doc: Amount of boost or attenuation of the frequency band. A positive value boosts frequencies in the band, a negative value attenuates them.
+    - default: 0.6
+    - constraints: none
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## FX Normalised Low Pass Filter
+## Hyperbolic Tangent
 
 ### Key:
-  :norm_lpf
+  :tanh
 
 ### Doc:
   Please write documentation!
 
-### Arguments:
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * res:
-    - doc: write me
-    - default: 0.5
-    - constraints: none
-    - Can not be changed once set
-
-  * res_slide:
-    - doc: write me
-    - default: 0
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * krunch:
+    - doc: Higher values progressively destroy the sound. Achieved through a balanced manipulation of pre_amp and amp such that the tanh is pushed harder with higher krunch values yet the overall amplitude stays similar.
+    - default: 5
     - constraints: none
-    - Can not be changed once set
-
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## FX Normalised Low Pass Filter
+## Pitch shift
 
 ### Key:
-  :replace_norm_lpf
+  :pitch_shift
 
 ### Doc:
-  Please write documentation!
+  Changes the pitch of a signal without affecting tempo. Does this mainly through the pitch parameter which takes a midi number to transpose by. You can also play with the other params to produce some interesting textures and sounds.
 
-### Arguments:
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * window_size:
+    - doc: Pitch shift works by chopping the input into tiny slices, then playing these slices at a higher or lower rate. If we make the slices small enough and overlap them, it sounds like the original sound with the pitch changed.
 
-  * res:
-    - doc: write me
-    - default: 0.5
-    - constraints: none
-    - Can not be changed once set
-
-  * res_slide:
-    - doc: write me
+  The window_size is the length of the slices and is measured in seconds. It needs to be around 0.2 (200ms) or greater for pitched sounds like guitar or bass, and needs to be around 0.02 (20ms) or lower for percussive sounds like drum loops. You can experiment with this to get the best sound for your input.
+    - default: 0.2
+    - constraints: must be a value greater than 5.0e-05
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pitch:
+    - doc: Pitch adjustment in semitones. 1 is up a semitone, 12 is up an octave, -12 is down an octave etc. Maximum upper limit of 24 (up 2 octaves). Lower limit of -72 (down 6 octaves). Decimal numbers can be used for fine tuning.
     - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be a value greater than or equal to -72,must be a value less than or equal to 24
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pitch_dis:
+    - doc: Pitch dispersion - how much random variation in pitch to add. Using a low value like 0.001 can help to "soften up" the metallic sounds, especially on drum loops. To be really technical, pitch_dispersion is the maximum random deviation of the pitch from the pitch ratio (which is set by the pitch param)
+    - default: 0.0
+    - constraints: must be a value greater than or equal to 0
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * time_dis:
+    - doc: Time dispersion - how much random delay before playing each grain (measured in seconds). Again, low values here like 0.001 can help to soften up metallic sounds introduced by the effect. Large values are also fun as they can make soundscapes and textures from the input, although you will most likely lose the rhythm of the original. NB - This won't have an effect if it's larger than window_size.
+    - default: 0.0
+    - constraints: must be a value greater than or equal to 0
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## FX Normaliser
+## Ring Modulator
 
 ### Key:
-  :normaliser
+  :ring_mod
 
 ### Doc:
-  Please write documentation!
+  Attack of the Daleks! Ring mod is a classic effect often used on soundtracks to evoke robots or aliens as it sounds hollow or metallic. We take a 'carrier' signal (a sine wave controlled by the freq opt) and modulate its amplitude using the signal given inside the fx block. This produces a wide variety of sounds - the best way to learn is to experiment!
 
-### Arguments:
+### Opts:
+  * freq:
+    - doc: Frequency of the carrier signal (as a midi note).
+    - default: 30
+    - constraints: must be greater than zero
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mod_amp:
+    - doc: Amplitude of the modulation
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## FX Normaliser
+## Octaver
 
 ### Key:
-  :replace_normaliser
+  :octaver
 
 ### Doc:
-  Please write documentation!
+  This effect adds three pitches based on the input sound. The first is the original sound transposed up an octave (super_amp), the second is the original sound transposed down an octave (sub_amp) and the third is the original sound transposed down two octaves (subsub_amp).
 
-### Arguments:
+  The way the transpositions are done adds some distortion/fuzz, particularly to the lower octaves, whilst the upper octave has a 'cheap' quality. This effect is often used in guitar effects pedals but it can work with other sounds too. There's a great description of the science behind this on Wikipedia here: https://en.wikipedia.org/wiki/Octave_effect
+
+### Opts:
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * super_amp:
+    - doc: Volume of the signal 1 octave above the input
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * sub_amp:
+    - doc: Volume of the signal 1 octave below the input
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * subsub_amp:
+    - doc: Volume of the signal 2 octaves below the input
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## FX Distortion
+## Vowel
 
 ### Key:
-  :distortion
+  :vowel
 
 ### Doc:
-  Please write documentation!
-
-### Arguments:
-  * distort:
-    - doc: write me
-    - default: 0.5
-    - constraints: none
-    - Can not be changed once set
+  This effect filters the input to match a human voice singing a certain vowel sound. Human singing voice sounds are easily achieved with a source of a saw wave with a little vibrato.
 
-  * distort_slide:
-    - doc: write me
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * vowel_sound:
+    - doc: 1,2,3,4,5 => A,E,I,O,U
+    - default: 1
+    - constraints: must be one of the following values: [1, 2, 3, 4, 5]
+    - May be changed whilst playing
+  * voice:
+    - doc: 0,1,2,3,4 => Soprano,Alto,Counter Tenor, Tenor, Bass
     - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be one of the following values: [0, 1, 2, 3, 4]
+    - May be changed whilst playing
 
 
-## FX Distortion
+## Flanger
 
 ### Key:
-  :replace_distortion
+  :flanger
 
 ### Doc:
-  Please write documentation!
+  Mix the incoming signal with a copy of itself which has a rate modulating faster and slower than the original. Creates a swirling/whooshing effect.
 
-### Arguments:
-  * distort:
-    - doc: write me
-    - default: 0.5
-    - constraints: none
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mix:
+    - doc: The amount (percentage) of FX present in the resulting sound represented as a value between 0 and 1. For example, a mix of 0 means that only the original sound is heard, a mix of 1 means that only the FX is heard (typically the default) and a mix of 0.5 means that half the original and half of the FX is heard.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplification applied to the input signal immediately before it is passed to the FX.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * phase:
+    - doc: Phase duration in beats of flanger modulation.
+    - default: 4
+    - constraints: must be greater than zero
+    - May be changed whilst playing
+    - Scaled with current BPM value
+    - Has slide parameters for shaping changes
+  * phase_offset:
+    - doc: Initial modulation phase offset (a value between 0 and 1).
+    - default: 0
+    - constraints: must be a value between 0 and 1 inclusively
     - Can not be changed once set
-
-  * distort_slide:
-    - doc: write me
+  * wave:
+    - doc: Wave type - 0 saw, 1 pulse, 2 triangle, 3 sine, 4 cubic. Different waves will produce different flanging modulation effects.
+    - default: 4
+    - constraints: must be one of the following values: [0, 1, 2, 3, 4]
+    - May be changed whilst playing
+  * invert_wave:
+    - doc: Invert flanger control waveform (i.e. flip it on the y axis). 0=uninverted wave, 1=inverted wave.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * stereo_invert_wave:
+    - doc: Make the flanger control waveform in the left ear an inversion of the control waveform in the right ear. 0=uninverted wave, 1=inverted wave. This happens after the standard wave inversion with param :invert_wave.
     - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * delay:
+    - doc: Amount of delay time between original and flanged version of audio.
+    - default: 5
     - constraints: none
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * max_delay:
+    - doc: Max delay time. Used to set internal buffer size.
+    - default: 20
+    - constraints: must be zero or greater
     - Can not be changed once set
-
+  * depth:
+    - doc: Flange depth - greater depths produce a more prominent effect.
+    - default: 5
+    - constraints: none
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * decay:
+    - doc: Flange decay time in ms
+    - default: 2
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * feedback:
+    - doc: Amount of feedback.
+    - default: 0
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * invert_flange:
+    - doc: Invert flanger signal. 0=no inversion, 1=inverted signal.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
 
 
diff --git a/etc/doc/cheatsheets/samples.md b/etc/doc/cheatsheets/samples.md
index 48ede27..190d0b4 100644
--- a/etc/doc/cheatsheets/samples.md
+++ b/etc/doc/cheatsheets/samples.md
@@ -53,14 +53,17 @@
 * :guit_harmonics
 * :guit_e_fifths
 * :guit_e_slide
+* :guit_em9
 
 
 ## Miscellaneous Sounds
 * :misc_burp
 
 
-## Percurssive Sounds
+## Percussive Sounds
 * :perc_bell
+* :perc_snap
+* :perc_snap2
 
 
 ## Ambient Sounds
@@ -87,10 +90,34 @@
 * :bass_dnb_f
 
 
+## Snare Drums
+* :sn_dub
+* :sn_dolf
+* :sn_zome
+
+
+## Bass Drums
+* :bd_ada
+* :bd_pure
+* :bd_808
+* :bd_zum
+* :bd_gas
+* :bd_sone
+* :bd_haus
+* :bd_zome
+* :bd_boom
+* :bd_klub
+* :bd_fat
+* :bd_tek
+
+
 ## Sounds for Looping
 * :loop_industrial
 * :loop_compus
 * :loop_amen
 * :loop_amen_full
+* :loop_garzul
+* :loop_mika
+* :loop_breakbeat
 
 
diff --git a/etc/doc/cheatsheets/synths.md b/etc/doc/cheatsheets/synths.md
index 9b8c7f0..dfd42e5 100644
--- a/etc/doc/cheatsheets/synths.md
+++ b/etc/doc/cheatsheets/synths.md
@@ -2,29 +2,47 @@
 
 * [Dull Bell](#dull-bell)
 * [Pretty Bell](#pretty-bell)
-* [Saw Wave](#saw-wave)
 * [Sine Wave](#sine-wave)
+* [Sine Wave](#sine-wave)
+* [Saw Wave](#saw-wave)
+* [Pulse Wave](#pulse-wave)
+* [Pulse Wave with sub](#pulse-wave-with-sub)
+* [Square Wave](#square-wave)
+* [Triangle Wave](#triangle-wave)
 * [Detuned Saw wave](#detuned-saw-wave)
+* [Detuned Pulse Wave](#detuned-pulse-wave)
+* [Detuned Triangle Wave](#detuned-triangle-wave)
 * [Basic FM synthesis](#basic-fm-synthesis)
+* [Basic FM synthesis with frequency modulation.](#basic-fm-synthesis-with-frequency-modulation.)
 * [Modulated Saw Wave](#modulated-saw-wave)
-* [Simple Modulated Saw Wave](#simple-modulated-saw-wave)
 * [Modulated Detuned Saw Waves](#modulated-detuned-saw-waves)
-* [Modulated Detuned Saw Waves Simple](#modulated-detuned-saw-waves-simple)
 * [Modulated Sine Wave](#modulated-sine-wave)
-* [Simple Modulated Sine Wave](#simple-modulated-sine-wave)
+* [Modulated Sine Wave](#modulated-sine-wave)
 * [Modulated Triangle Wave](#modulated-triangle-wave)
-* [Simple Modulated Triangle Wave](#simple-modulated-triangle-wave)
 * [Modulated Pulse](#modulated-pulse)
-* [Simple Modulated Pulse](#simple-modulated-pulse)
 * [TB-303 Emulation](#tb-303-emulation)
 * [Supersaw](#supersaw)
-* [Supersaw Simple](#supersaw-simple)
+* [Hoover](#hoover)
 * [The Prophet](#the-prophet)
 * [Zawa](#zawa)
+* [Dark Ambience](#dark-ambience)
+* [Growl](#growl)
+* [Hollow](#hollow)
 * [Mono Sample Player](#mono-sample-player)
 * [Stereo Sample Player](#stereo-sample-player)
-* [Basic Mono Sample Player - (no envelope)](#basic-mono-sample-player---(no-envelope))
-* [Basic Stereo Sample Player - (no envelope)](#basic-stereo-sample-player---(no-envelope))
+* [Blade Runner style strings](#blade-runner-style-strings)
+* [SynthPiano](#synthpiano)
+* [SynthPluck](#synthpluck)
+* [Sound In](#sound-in)
+* [Noise](#noise)
+* [Pink Noise](#pink-noise)
+* [Brown Noise](#brown-noise)
+* [Grey Noise](#grey-noise)
+* [Clip Noise](#clip-noise)
+* [Basic Mono Sample Player (no env)](#basic-mono-sample-player-(no-env))
+* [Basic Stereo Sample Player (no env)](#basic-stereo-sample-player-(no-env))
+* [Basic Mixer](#basic-mixer)
+* [Main Mixer](#main-mixer)
 
 ## Dull Bell
 
@@ -34,61 +52,69 @@
 ### Doc:
   A simple dull discordant bell sound.
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
     - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
 
 
 ## Pretty Bell
@@ -97,1960 +123,3732 @@
   :pretty_bell
 
 ### Doc:
-  A simple pretty bell sound.
+  A pretty bell sound. Works well with short attacks and long decays.
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
     - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
 
 
-
-## Saw Wave
+## Sine Wave
 
 ### Key:
-  :saw_beep
+  :beep
 
 ### Doc:
-  A simple saw wave with a low pass filter.
+  A simple pure sine wave. The sine wave is the simplest, purest sound there is and is the fundamental building block of all noise. The mathematician Fourier demonstrated that any sound could be built out of a number of sine waves (the more complex the sound, the more sine waves needed). Have a play combining a number of sine waves to design your own sounds!
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.1
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
-    - default: 0.3
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
 
 
 ## Sine Wave
 
 ### Key:
-  :beep
+  :sine
 
 ### Doc:
-  A simple pure sine wave.
+  A simple pure sine wave. The sine wave is the simplest, purest sound there is and is the fundamental building block of all noise. The mathematician Fourier demonstrated that any sound could be built out of a number of sine waves (the more complex the sound, the more sine waves needed). Have a play combining a number of sine waves to design your own sounds!
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.1
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
-    - default: 0.3
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
 
 
-
-## Detuned Saw wave
+## Saw Wave
 
 ### Key:
-  :dsaw
+  :saw
 
 ### Doc:
-  A pair of detuned saw waves with a lop pass filter.
+  A saw wave with a low pass filter. Great for using with FX such as the built in low pass filter (available via the cutoff arg) due to the complexity and thickness of the sound.
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
-    - default: 0.2
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
-    - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * detune:
-    - doc: Distance (in MIDI notes) between components of sound. Affects thickness, sense of tuning and harmony. Tiny values such as 0.1 create a thick sound. Larger values such as 0.5 make the tuning sound strange. Even bigger values such as 5 create chord-like sounds.
-    - default: 0.1
-    - constraints: none
-    - May be changed whilst playing
-
-  * detune_slide:
-    - doc: Amount of time (in seconds) for the detune value to change. A long detune_slide value means that the detune takes a long time to slide from the previous value to the new value. A detune_slide of 0 means that the detune instantly changes to the new value.
-    - default: 0
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
 
 
-## Basic FM synthesis
+## Pulse Wave
 
 ### Key:
-  :fm
+  :pulse
 
 ### Doc:
-  A sine wave with a fundamental frequency which is modulated at audio rate by another sine wave with a specific modulation division and depth.
+  A simple pulse wave with a low pass filter. This defaults to a square wave, but the timbre can be changed dramatically by adjusting the pulse_width arg between 0 and 1. The pulse wave is thick and heavy with lower notes and is a great ingredient for bass sounds.
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 1
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
     - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * divisor:
-    - doc: Modifies the frequency of the modulator oscillator relative to the carrier. Don't worry too much about what this means - just try different numbers out!
-    - default: 2
-    - constraints: none
-    - May be changed whilst playing
-
-  * divisor_slide:
-    - doc: Amount of time (in seconds) for the divisor value to change. A long divisor_slide value means that the divisor takes a long time to slide from the previous value to the new value. A divisor_slide of 0 means that the divisor instantly changes to the new value.
-    - default: 0
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * depth:
-    - doc: Modifies the depth of the carrier wave used to modify fundamental frequency. Don't worry too much about what this means - just try different numbers out!
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
     - default: 1
-    - constraints: none
-    - May be changed whilst playing
-
-  * depth_slide:
-    - doc: Amount of time (in seconds) for the depth value to change. A long depth_slide value means that the depth takes a long time to slide from the previous value to the new value. A depth_slide of 0 means that the depth instantly changes to the new value.
-    - default: 0
     - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pulse_width:
+    - doc: The width of the pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Different values will change the timbre of the sound. Only valid if wave is type pulse.
+    - default: 0.5
+    - constraints: must be a value between 0 and 1 exclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## Modulated Saw Wave
+## Pulse Wave with sub
 
 ### Key:
-  :mod_saw
+  :subpulse
 
 ### Doc:
-  A saw wave which modulates between two separate notes.
+  A pulse wave with a sub sine wave passed through a low pass filter. The pulse wave is thick and heavy with lower notes and is a great ingredient for bass sounds - especially with the sub wave.
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
-    - default: 2
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
-    - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_rate:
-    - doc: Number of times per second that the note switches between the two notes.
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
     - default: 1
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_rate_slide:
-    - doc: Amount of time (in seconds) for the mod_rate value to change. A long mod_rate_slide value means that the mod_rate takes a long time to slide from the previous value to the new value. A mod_rate_slide of 0 means that the mod_rate instantly changes to the new value.
-    - default: 0
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_range:
-    - doc: The size of gap between modulation notes. A gap of 12 is one octave.
-    - default: 5
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_range__slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
     - Can not be changed once set
-
-  * mod_width:
-    - doc: The phase width of the modulation. Represents how even the gap between modulations is.
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pulse_width:
+    - doc: The width of the pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Different values will change the timbre of the sound. Only valid if wave is type pulse.
     - default: 0.5
     - constraints: must be a value between 0 and 1 exclusively
     - May be changed whilst playing
-
-  * mod_width_slide:
-    - doc: Amount of time (in seconds) for the mod_width value to change. A long mod_width_slide value means that the mod_width takes a long time to slide from the previous value to the new value. A mod_width_slide of 0 means that the mod_width instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
+    - Has slide parameters for shaping changes
+  * sub_amp:
+    - doc: Amplitude for the additional sine wave.
+    - default: 1
+    - constraints: none
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * sub_detune:
+    - doc: Amount of detune from the note for the additional sine wave. Default is -12
+    - default: -12
+    - constraints: none
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## Simple Modulated Saw Wave
+## Square Wave
 
 ### Key:
-  :mod_saw_s
+  :square
 
 ### Doc:
-  
+  A simple square wave with a low pass filter. The square wave is thick and heavy with lower notes and is a great ingredient for bass sounds. If you wish to modulate the width of the square wave see the synth pulse.
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
-    - default: 2
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
-  * mod_rate:
-    - doc: Number of times per second that the note switches between the two notes.
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
     - default: 1
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_range:
-    - doc: The size of gap between modulation notes. A gap of 12 is one octave.
-    - default: 5
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
     - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
     - May be changed whilst playing
-
-  * mod_width:
-    - doc: The phase width of the modulation. Represents how even the gap between modulations is.
-    - default: 0.5
-    - constraints: must be a value between 0 and 1 exclusively
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
 
 
-## Modulated Detuned Saw Waves
+## Triangle Wave
 
 ### Key:
-  :mod_dsaw
+  :tri
 
 ### Doc:
-  
+  A simple triangle wave with a low pass filter.
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
-    - default: 2
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
     - Can not be changed once set
-
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
-    - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_rate:
-    - doc: Number of times per second that the note switches between the two notes.
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
     - default: 1
     - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
     - May be changed whilst playing
-
-  * mod_range:
-    - doc: The size of gap between modulation notes. A gap of 12 is one octave.
-    - default: 5
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_width:
-    - doc: The phase width of the modulation. Represents how even the gap between modulations is.
+    - Has slide parameters for shaping changes
+  * pulse_width:
+    - doc: The width of the pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Different values will change the timbre of the sound. Only valid if wave is type pulse.
     - default: 0.5
     - constraints: must be a value between 0 and 1 exclusively
     - May be changed whilst playing
-
-  * detune:
-    - doc: Distance (in MIDI notes) between components of sound. Affects thickness, sense of tuning and harmony. Tiny values such as 0.1 create a thick sound. Larger values such as 0.5 make the tuning sound strange. Even bigger values such as 5 create chord-like sounds.
-    - default: 0.1
-    - constraints: none
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
 
 
-## Modulated Detuned Saw Waves Simple
+## Detuned Saw wave
 
 ### Key:
-  :mod_dsaw_s
+  :dsaw
 
 ### Doc:
-  
+  A pair of detuned saw waves passed through a low pass filter. Two saw waves with slightly different frequencies generates a nice thick sound which is the basis for a lot of famous synth sounds. Thicken the sound by increasing the detune value, or create an octave-playing synth by choosing a detune of 12 (12 MIDI notes is an octave).
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
-    - default: 2
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * mod_rate:
-    - doc: Number of times per second that the note switches between the two notes.
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
     - default: 1
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_rate_slide:
-    - doc: Amount of time (in seconds) for the mod_rate value to change. A long mod_rate_slide value means that the mod_rate takes a long time to slide from the previous value to the new value. A mod_rate_slide of 0 means that the mod_rate instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_range:
-    - doc: The size of gap between modulation notes. A gap of 12 is one octave.
-    - default: 5
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_range_slide:
-    - doc: Amount of time (in seconds) for the mod_range value to change. A long mod_range_slide value means that the mod_range takes a long time to slide from the previous value to the new value. A mod_range_slide of 0 means that the mod_range instantly changes to the new value.
-    - default: 0
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_width:
-    - doc: The phase width of the modulation. Represents how even the gap between modulations is.
-    - default: 0.5
-    - constraints: must be a value between 0 and 1 exclusively
-    - May be changed whilst playing
-
-  * mod_width_slide:
-    - doc: Amount of time (in seconds) for the mod_width value to change. A long mod_width_slide value means that the mod_width takes a long time to slide from the previous value to the new value. A mod_width_slide of 0 means that the mod_width instantly changes to the new value.
-    - default: 0
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
     - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * detune:
     - doc: Distance (in MIDI notes) between components of sound. Affects thickness, sense of tuning and harmony. Tiny values such as 0.1 create a thick sound. Larger values such as 0.5 make the tuning sound strange. Even bigger values such as 5 create chord-like sounds.
     - default: 0.1
     - constraints: none
     - May be changed whilst playing
-
-  * detune_slide:
-    - doc: Amount of time (in seconds) for the detune value to change. A long detune_slide value means that the detune takes a long time to slide from the previous value to the new value. A detune_slide of 0 means that the detune instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
 
 
-## Modulated Sine Wave
+## Detuned Pulse Wave
 
 ### Key:
-  :mod_sine
+  :dpulse
 
 ### Doc:
-  
+  A pair of detuned pulse waves passed through a low pass filter. Two pulse waves with slightly different frequencies generates a nice thick sound which can be used as a basis for some nice bass sounds. Thicken the sound by increasing the detune value, or create an octave-playing synth by choosing a detune of 12 (12 MIDI notes is an octave). Each pulse wave can also have individual widths (although the default is for the detuned pulse to mirror the width of the main pulse).
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
-    - default: 2
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
-    - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_rate:
-    - doc: Number of times per second that the note switches between the two notes.
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
     - default: 1
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_rate_slide:
-    - doc: Amount of time (in seconds) for the mod_rate value to change. A long mod_rate_slide value means that the mod_rate takes a long time to slide from the previous value to the new value. A mod_rate_slide of 0 means that the mod_rate instantly changes to the new value.
-    - default: 0
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_range:
-    - doc: The size of gap between modulation notes. A gap of 12 is one octave.
-    - default: 5
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
     - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
     - May be changed whilst playing
-
-  * mod_range_slide:
-    - doc: Amount of time (in seconds) for the mod_range value to change. A long mod_range_slide value means that the mod_range takes a long time to slide from the previous value to the new value. A mod_range_slide of 0 means that the mod_range instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
+    - Has slide parameters for shaping changes
+  * detune:
+    - doc: Distance (in MIDI notes) between components of sound. Affects thickness, sense of tuning and harmony. Tiny values such as 0.1 create a thick sound. Larger values such as 0.5 make the tuning sound strange. Even bigger values such as 5 create chord-like sounds.
+    - default: 0.1
+    - constraints: none
     - May be changed whilst playing
-
-  * mod_width:
-    - doc: The phase width of the modulation. Represents how even the gap between modulations is.
+    - Has slide parameters for shaping changes
+  * pulse_width:
+    - doc: The width of the pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Different values will change the timbre of the sound. Only valid if wave is type pulse.
     - default: 0.5
     - constraints: must be a value between 0 and 1 exclusively
     - May be changed whilst playing
-
-  * mod_width_slide:
-    - doc: Amount of time (in seconds) for the mod_width value to change. A long mod_width_slide value means that the mod_width takes a long time to slide from the previous value to the new value. A mod_width_slide of 0 means that the mod_width instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
+    - Has slide parameters for shaping changes
+  * dpulse_width:
+    - doc: The width of the second detuned pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Different values will change the timbre of the sound. Only valid if wave is type pulse.
+    - default: pulse_width
+    - constraints: must be a value between 0 and 1 exclusively
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## Simple Modulated Sine Wave
+## Detuned Triangle Wave
 
 ### Key:
-  :mod_sine_s
+  :dtri
 
 ### Doc:
-  
+  A pair of detuned triangle waves passed through a low pass filter. Two pulse waves with slightly different frequencies generates a nice thick sound which can be used as a basis for some nice bass sounds. Thicken the sound by increasing the detune value, or create an octave-playing synth by choosing a detune of 12 (12 MIDI notes is an octave).
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
-    - default: 2
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
-    - Can not be changed once set
-
-  * mod_rate:
-    - doc: Number of times per second that the note switches between the two notes.
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
     - default: 1
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_rate_slide:
-    - doc: Amount of time (in seconds) for the mod_rate value to change. A long mod_rate_slide value means that the mod_rate takes a long time to slide from the previous value to the new value. A mod_rate_slide of 0 means that the mod_rate instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_range:
-    - doc: The size of gap between modulation notes. A gap of 12 is one octave.
-    - default: 5
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_range_slide:
-    - doc: Amount of time (in seconds) for the mod_range value to change. A long mod_range_slide value means that the mod_range takes a long time to slide from the previous value to the new value. A mod_range_slide of 0 means that the mod_range instantly changes to the new value.
-    - default: 0
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
     - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
     - May be changed whilst playing
-
-  * mod_width:
-    - doc: The phase width of the modulation. Represents how even the gap between modulations is.
-    - default: 0.5
-    - constraints: must be a value between 0 and 1 exclusively
-    - May be changed whilst playing
-
-  * mod_width_slide:
-    - doc: Amount of time (in seconds) for the mod_width value to change. A long mod_width_slide value means that the mod_width takes a long time to slide from the previous value to the new value. A mod_width_slide of 0 means that the mod_width instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
+    - Has slide parameters for shaping changes
+  * detune:
+    - doc: Distance (in MIDI notes) between components of sound. Affects thickness, sense of tuning and harmony. Tiny values such as 0.1 create a thick sound. Larger values such as 0.5 make the tuning sound strange. Even bigger values such as 5 create chord-like sounds.
+    - default: 0.1
+    - constraints: none
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## Modulated Triangle Wave
+## Basic FM synthesis
 
 ### Key:
-  :mod_tri
+  :fm
 
 ### Doc:
-  
+  A sine wave with a fundamental frequency which is modulated at audio rate by another sine wave with a specific modulation, division and depth. Useful for generating a wide range of sounds by playing with the divisor and depth params. Great for deep powerful bass and crazy 70s sci-fi sounds.
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
-    - default: 2
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
-    - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_rate:
-    - doc: Number of times per second that the note switches between the two notes.
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
     - default: 1
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_rate_slide:
-    - doc: Amount of time (in seconds) for the mod_rate value to change. A long mod_rate_slide value means that the mod_rate takes a long time to slide from the previous value to the new value. A mod_rate_slide of 0 means that the mod_rate instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_range:
-    - doc: The size of gap between modulation notes. A gap of 12 is one octave.
-    - default: 5
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_range_slide:
-    - doc: Amount of time (in seconds) for the mod_range value to change. A long mod_range_slide value means that the mod_range takes a long time to slide from the previous value to the new value. A mod_range_slide of 0 means that the mod_range instantly changes to the new value.
-    - default: 0
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
     - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
     - May be changed whilst playing
-
-  * mod_width:
-    - doc: The phase width of the modulation. Represents how even the gap between modulations is.
-    - default: 0.5
-    - constraints: must be a value between 0 and 1 exclusively
+    - Has slide parameters for shaping changes
+  * divisor:
+    - doc: Modifies the frequency of the modulator oscillator relative to the carrier. Don't worry too much about what this means - just try different numbers out!
+    - default: 2
+    - constraints: none
     - May be changed whilst playing
-
-  * mod_width_slide:
-    - doc: Amount of time (in seconds) for the mod_width value to change. A long mod_width_slide value means that the mod_width takes a long time to slide from the previous value to the new value. A mod_width_slide of 0 means that the mod_width instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
+    - Has slide parameters for shaping changes
+  * depth:
+    - doc: Modifies the depth of the carrier wave used to modify fundamental frequency. Don't worry too much about what this means - just try different numbers out!
+    - default: 1
+    - constraints: none
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## Simple Modulated Triangle Wave
+## Basic FM synthesis with frequency modulation.
 
 ### Key:
-  :mod_tri_s
+  :mod_fm
 
 ### Doc:
-  
+  The FM synth modulating between two notes - the duration of the modulation can be modified using the mod_phase arg, the range (number of notes jumped between) by the mod_range arg and the width of the jumps by the mod_width param. The FM synth is a sine wave with a fundamental frequency which is modulated at audio rate by another sine wave with a specific modulation, division and depth. Useful for generating a wide range of sounds by playing with the `:divisor` and `:depth` params. Great for deep powerful bass and crazy 70s sci-fi sounds.
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
-    - default: 2
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
     - Can not be changed once set
-
-  * mod_rate:
-    - doc: Number of times per second that the note switches between the two notes.
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
     - default: 1
     - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
+  * divisor:
+    - doc: Modifies the frequency of the modulator oscillator relative to the carrier. Don't worry too much about what this means - just try different numbers out!
+    - default: 2
+    - constraints: none
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * depth:
+    - doc: Modifies the depth of the carrier wave used to modify fundamental frequency. Don't worry too much about what this means - just try different numbers out!
+    - default: 1
+    - constraints: none
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mod_phase:
+    - doc: Phase duration in beats of oscillations between the two notes. Time it takes to switch between the notes.
+    - default: 0.25
+    - constraints: must be greater than zero
+    - May be changed whilst playing
+    - Scaled with current BPM value
   * mod_range:
     - doc: The size of gap between modulation notes. A gap of 12 is one octave.
     - default: 5
-    - constraints: must be zero or greater
+    - constraints: none
     - May be changed whilst playing
-
-  * mod_width:
-    - doc: The phase width of the modulation. Represents how even the gap between modulations is.
+  * mod_pulse_width:
+    - doc: The width of the modulated pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Only valid if mod wave is type pulse.
     - default: 0.5
     - constraints: must be a value between 0 and 1 exclusively
     - May be changed whilst playing
+  * mod_phase_offset:
+    - doc: Initial modulation phase offset (a value between 0 and 1).
+    - default: 0
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+  * mod_invert_wave:
+    - doc: Invert mod waveform (i.e. flip it on the y axis). 0=normal wave, 1=inverted wave.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * mod_wave:
+    - doc: Wave shape of mod wave. 0=saw wave, 1=pulse, 2=triangle wave and 3=sine wave.
+    - default: 1
+    - constraints: must be one of the following values: [0, 1, 2, 3]
+    - May be changed whilst playing
 
 
-
-## Modulated Pulse
+## Modulated Saw Wave
 
 ### Key:
-  :mod_pulse
+  :mod_saw
 
 ### Doc:
-  
+  A saw wave passed through a low pass filter which modulates between two separate notes via a variety of control waves.
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
-    - default: 2
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
-    - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_rate:
-    - doc: Number of times per second that the note switches between the two notes.
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
     - default: 1
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_rate__slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
     - Can not be changed once set
-
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mod_phase:
+    - doc: Phase duration in beats of oscillations between the two notes. Time it takes to switch between the notes.
+    - default: 0.25
+    - constraints: must be greater than zero
+    - May be changed whilst playing
+    - Scaled with current BPM value
+    - Has slide parameters for shaping changes
   * mod_range:
     - doc: The size of gap between modulation notes. A gap of 12 is one octave.
     - default: 5
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * mod_range_slide:
-    - doc: Amount of time (in seconds) for the mod_range value to change. A long mod_range_slide value means that the mod_range takes a long time to slide from the previous value to the new value. A mod_range_slide of 0 means that the mod_range instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
+    - constraints: none
     - May be changed whilst playing
-
-  * mod_width:
-    - doc: The phase width of the modulation. Represents how even the gap between modulations is.
+    - Has slide parameters for shaping changes
+  * mod_pulse_width:
+    - doc: The width of the modulated pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Only valid if mod wave is type pulse.
     - default: 0.5
     - constraints: must be a value between 0 and 1 exclusively
     - May be changed whilst playing
-
-  * mod_width_slide:
-    - doc: Amount of time (in seconds) for the mod_width value to change. A long mod_width_slide value means that the mod_width takes a long time to slide from the previous value to the new value. A mod_width_slide of 0 means that the mod_width instantly changes to the new value.
+    - Has slide parameters for shaping changes
+  * mod_phase_offset:
+    - doc: Initial modulation phase offset (a value between 0 and 1).
     - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * pulse_width:
-    - doc: write me
-    - default: 0.5
-    - constraints: none
+    - constraints: must be a value between 0 and 1 inclusively
     - Can not be changed once set
-
-  * pulse_width_slide:
-    - doc: write me
+  * mod_invert_wave:
+    - doc: Invert mod waveform (i.e. flip it on the y axis). 0=normal wave, 1=inverted wave.
     - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * mod_wave:
+    - doc: Wave shape of mod wave. 0=saw wave, 1=pulse, 2=triangle wave and 3=sine wave.
+    - default: 1
+    - constraints: must be one of the following values: [0, 1, 2, 3]
+    - May be changed whilst playing
 
 
-## Simple Modulated Pulse
+## Modulated Detuned Saw Waves
 
 ### Key:
-  :mod_pulse_s
+  :mod_dsaw
 
 ### Doc:
-  
+  A pair of detuned saw waves (see the dsaw synth) which are modulated between two fixed notes at a given rate.
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
-    - default: 2
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * mod_rate:
-    - doc: Number of times per second that the note switches between the two notes.
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
     - default: 1
     - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
+  * mod_phase:
+    - doc: Phase duration in beats of oscillations between the two notes. Time it takes to switch between the notes.
+    - default: 0.25
+    - constraints: must be greater than zero
+    - May be changed whilst playing
+    - Scaled with current BPM value
+    - Has slide parameters for shaping changes
   * mod_range:
     - doc: The size of gap between modulation notes. A gap of 12 is one octave.
     - default: 5
-    - constraints: must be zero or greater
+    - constraints: none
     - May be changed whilst playing
-
-  * mod_width:
-    - doc: The phase width of the modulation. Represents how even the gap between modulations is.
+    - Has slide parameters for shaping changes
+  * mod_pulse_width:
+    - doc: The width of the modulated pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Only valid if mod wave is type pulse.
     - default: 0.5
     - constraints: must be a value between 0 and 1 exclusively
     - May be changed whilst playing
-
-  * pulse_width:
-    - doc: write me
-    - default: 0.5
-    - constraints: none
+    - Has slide parameters for shaping changes
+  * mod_phase_offset:
+    - doc: Initial modulation phase offset (a value between 0 and 1).
+    - default: 0
+    - constraints: must be a value between 0 and 1 inclusively
     - Can not be changed once set
+  * mod_invert_wave:
+    - doc: Invert mod waveform (i.e. flip it on the y axis). 0=normal wave, 1=inverted wave.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * mod_wave:
+    - doc: Wave shape of mod wave. 0=saw wave, 1=pulse, 2=triangle wave and 3=sine wave.
+    - default: 1
+    - constraints: must be one of the following values: [0, 1, 2, 3]
+    - May be changed whilst playing
+  * detune:
+    - doc: Distance (in MIDI notes) between components of sound. Affects thickness, sense of tuning and harmony. Tiny values such as 0.1 create a thick sound. Larger values such as 0.5 make the tuning sound strange. Even bigger values such as 5 create chord-like sounds.
+    - default: 0.1
+    - constraints: none
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## TB-303 Emulation
+## Modulated Sine Wave
 
 ### Key:
-  :tb303
+  :mod_sine
 
 ### Doc:
-  
+  A sine wave passed through a low pass filter which modulates between two separate notes via a variety of control waves.
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
-    - default: 2
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * cutoff:
-    - doc: 
-    - default: 80
-    - constraints: must be zero or greater, must be a value less than 130
-    - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
     - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
     - May be changed whilst playing
-
-  * cutoff_min:
-    - doc: 
-    - default: 30
-    - constraints: must be zero or greater, must be a value less than 130
+    - Has slide parameters for shaping changes
+  * mod_phase:
+    - doc: Phase duration in beats of oscillations between the two notes. Time it takes to switch between the notes.
+    - default: 0.25
+    - constraints: must be greater than zero
     - May be changed whilst playing
-
-  * res:
-    - doc: write me
-    - default: 0.1
+    - Scaled with current BPM value
+    - Has slide parameters for shaping changes
+  * mod_range:
+    - doc: The size of gap between modulation notes. A gap of 12 is one octave.
+    - default: 5
     - constraints: none
-    - Can not be changed once set
-
-  * res_slide:
-    - doc: write me
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mod_pulse_width:
+    - doc: The width of the modulated pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Only valid if mod wave is type pulse.
+    - default: 0.5
+    - constraints: must be a value between 0 and 1 exclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mod_phase_offset:
+    - doc: Initial modulation phase offset (a value between 0 and 1).
     - default: 0
-    - constraints: none
+    - constraints: must be a value between 0 and 1 inclusively
     - Can not be changed once set
-
-  * wave:
-    - doc: Wave type - 0 saw, 1 pulse
+  * mod_invert_wave:
+    - doc: Invert mod waveform (i.e. flip it on the y axis). 0=normal wave, 1=inverted wave.
     - default: 0
     - constraints: must be one of the following values: [0, 1]
     - May be changed whilst playing
-
-  * pulse_width:
-    - doc: Only valid if wave is type pulse.
-    - default: 0.5
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * pulse_width_slide:
-    - doc: Time in seconds for pulse width to change. Only valid if wave is type pulse.
-    - default: 0
-    - constraints: must be zero or greater
+  * mod_wave:
+    - doc: Wave shape of mod wave. 0=saw wave, 1=pulse, 2=triangle wave and 3=sine wave.
+    - default: 1
+    - constraints: must be one of the following values: [0, 1, 2, 3]
     - May be changed whilst playing
 
 
-
-## Supersaw
+## Modulated Sine Wave
 
 ### Key:
-  :supersaw
+  :mod_beep
 
 ### Doc:
-  
+  A sine wave passed through a low pass filter which modulates between two separate notes via a variety of control waves.
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
-    - default: 2
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
   * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 130
-    - constraints: must be zero or greater, must be a value less than 130
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
     - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
+    - Has slide parameters for shaping changes
+  * mod_phase:
+    - doc: Phase duration in beats of oscillations between the two notes. Time it takes to switch between the notes.
+    - default: 0.25
+    - constraints: must be greater than zero
     - May be changed whilst playing
-
-  * res:
-    - doc: write me
-    - default: 0.3
+    - Scaled with current BPM value
+    - Has slide parameters for shaping changes
+  * mod_range:
+    - doc: The size of gap between modulation notes. A gap of 12 is one octave.
+    - default: 5
     - constraints: none
-    - Can not be changed once set
-
-  * res_slide:
-    - doc: write me
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mod_pulse_width:
+    - doc: The width of the modulated pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Only valid if mod wave is type pulse.
+    - default: 0.5
+    - constraints: must be a value between 0 and 1 exclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mod_phase_offset:
+    - doc: Initial modulation phase offset (a value between 0 and 1).
     - default: 0
-    - constraints: none
+    - constraints: must be a value between 0 and 1 inclusively
     - Can not be changed once set
+  * mod_invert_wave:
+    - doc: Invert mod waveform (i.e. flip it on the y axis). 0=normal wave, 1=inverted wave.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * mod_wave:
+    - doc: Wave shape of mod wave. 0=saw wave, 1=pulse, 2=triangle wave and 3=sine wave.
+    - default: 1
+    - constraints: must be one of the following values: [0, 1, 2, 3]
+    - May be changed whilst playing
 
 
-
-## Supersaw Simple
+## Modulated Triangle Wave
 
 ### Key:
-  :supersaw_s
+  :mod_tri
 
 ### Doc:
-  
+  A triangle wave passed through a low pass filter which modulates between two separate notes via a variety of control waves.
 
-### Arguments:
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
+    - Scaled with current BPM value
+  * release:
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mod_phase:
+    - doc: Phase duration in beats of oscillations between the two notes. Time it takes to switch between the notes.
+    - default: 0.25
+    - constraints: must be greater than zero
+    - May be changed whilst playing
+    - Scaled with current BPM value
+    - Has slide parameters for shaping changes
+  * mod_range:
+    - doc: The size of gap between modulation notes. A gap of 12 is one octave.
+    - default: 5
+    - constraints: none
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mod_pulse_width:
+    - doc: The width of the modulated pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Only valid if mod wave is type pulse.
+    - default: 0.5
+    - constraints: must be a value between 0 and 1 exclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mod_phase_offset:
+    - doc: Initial modulation phase offset (a value between 0 and 1).
+    - default: 0
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+  * mod_invert_wave:
+    - doc: Invert mod waveform (i.e. flip it on the y axis). 0=normal wave, 1=inverted wave.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * mod_wave:
+    - doc: Wave shape of mod wave. 0=saw wave, 1=pulse, 2=triangle wave and 3=sine wave.
+    - default: 1
+    - constraints: must be one of the following values: [0, 1, 2, 3]
+    - May be changed whilst playing
 
 
-
-## The Prophet
+## Modulated Pulse
 
 ### Key:
-  :prophet
+  :mod_pulse
 
 ### Doc:
-  Dark and swirly, this synth uses Pulse Width Modulation
-      (PWM) to create a timbre which continually moves around. This
-      effect is created using the pulse ugen which produces a variable
-      width square wave. We then control the width of the pulses using a
-      variety of LFOs - sin-osc and lf-tri in this case. We use a number
-      of these LFO modulated pulse ugens with varying LFO type and rate
-      (and phase in some cases) to provide the LFO with a different
-      starting point. We then mix all these pulses together to create a
-      thick sound and then feed it through a resonant low pass filter
-      (rlpf).
-
-      For extra bass, one of the pulses is an octave lower (half the
-      frequency) and its LFO has a little bit of randomisation thrown
-      into its frequency component for that extra bit of variety.
-
-### Arguments:
+  A pulse wave with a low pass filter modulating between two notes via a variety of control waves (see mod_wave: arg). The pulse wave defaults to a square wave, but the timbre can be changed dramatically by adjusting the pulse_width arg between 0 and 1.
+
+### Opts:
   * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
     - default: 52
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * sustain:
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * release:
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mod_phase:
+    - doc: Phase duration in beats of oscillations between the two notes. Time it takes to switch between the notes.
+    - default: 0.25
+    - constraints: must be greater than zero
+    - May be changed whilst playing
+    - Scaled with current BPM value
+    - Has slide parameters for shaping changes
+  * mod_range:
+    - doc: The size of gap between modulation notes. A gap of 12 is one octave.
+    - default: 5
+    - constraints: none
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mod_pulse_width:
+    - doc: The width of the modulated pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Only valid if mod wave is type pulse.
+    - default: 0.5
+    - constraints: must be a value between 0 and 1 exclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * mod_phase_offset:
+    - doc: Initial modulation phase offset (a value between 0 and 1).
+    - default: 0
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+  * mod_invert_wave:
+    - doc: Invert mod waveform (i.e. flip it on the y axis). 0=normal wave, 1=inverted wave.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * mod_wave:
+    - doc: Wave shape of mod wave. 0=saw wave, 1=pulse, 2=triangle wave and 3=sine wave.
+    - default: 1
+    - constraints: must be one of the following values: [0, 1, 2, 3]
+    - May be changed whilst playing
+  * pulse_width:
+    - doc: The width of the pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Different values will change the timbre of the sound. Only valid if wave is type pulse.
+    - default: 0.5
+    - constraints: must be a value between 0 and 1 exclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+
+
+## TB-303 Emulation
+
+### Key:
+  :tb303
+
+### Doc:
+  Emulation of the classic Roland TB-303 Bass Line synthesiser. Overdrive the res (i.e. use very large values) for that classic late 80s acid sound.
+
+### Opts:
+  * note:
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
+    - default: 52
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * sustain:
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * release:
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: The maximum cutoff value as a MIDI note
+    - default: 120
+    - constraints: must be a value less than or equal to 130
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * cutoff_min:
+    - doc: The minimum cutoff value.
+    - default: 30
+    - constraints: must be a value less than or equal to 130
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * cutoff_attack:
+    - doc: Attack time for cutoff filter. Amount of time (in beats) for sound to reach full cutoff value. Default value is set to match amp envelope's attack value.
+    - default: attack
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * cutoff_decay:
+    - doc: Decay time for cutoff filter. Amount of time (in beats) for sound to move from full cutoff value (cutoff attack level) to the cutoff sustain level. Default value is set to match amp envelope's decay value.
+    - default: decay
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * cutoff_sustain:
+    - doc: Amount of time for cutoff value to remain at sustain level in beats. Default value is set to match amp envelope's sustain value.
+    - default: sustain
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * cutoff_release:
+    - doc: Amount of time (in beats) for sound to move from cutoff sustain value to cutoff min value. Default value is set to match amp envelope's release value.
+    - default: release
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * cutoff_attack_level:
+    - doc: The peak cutoff (value of cutoff at peak of attack) as a value between 0 and 1 where 0 is the :cutoff_min and 1 is the :cutoff value
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+  * cutoff_decay_level:
+    - doc: The level of cutoff after the decay phase as a value between 0 and 1 where 0 is the :cutoff_min and 1 is the :cutoff value
+    - default: cutoff_sustain_level
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+  * cutoff_sustain_level:
+    - doc: The sustain cutoff (value of cutoff at sustain time) as a value between 0 and 1 where 0 is the :cutoff_min and 1 is the :cutoff value.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0.9
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * wave:
+    - doc: Wave type - 0 saw, 1 pulse, 2 triangle. Different waves will produce different sounds.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1, 2]
+    - May be changed whilst playing
+  * pulse_width:
+    - doc: The width of the pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Different values will change the timbre of the sound. Only valid if wave is type pulse.
+    - default: 0.5
+    - constraints: must be a value between 0 and 1 exclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+
+
+## Supersaw
+
+### Key:
+  :supersaw
+
+### Doc:
+  Thick swirly saw waves sparkling and moving about to create a rich trancy sound.
+
+### Opts:
+  * note:
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
+    - default: 52
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * sustain:
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * release:
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 130
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0.7
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+
+
+## Hoover
+
+### Key:
+  :hoover
+
+### Doc:
+  Classic early 90's rave synth - 'a sort of slurry chorussy synth line like the classic Dominator by Human Resource'. Based on Dan Stowell's implementation in SuperCollider and Daniel Turczanski's port to Overtone. Works really well with portamento (see docs for the 'control' method).
+
+### Opts:
+  * note:
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
+    - default: 52
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0.05
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * sustain:
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * release:
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 130
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0.1
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+
+
+## The Prophet
+
+### Key:
+  :prophet
+
+### Doc:
+  Dark and swirly, this synth uses Pulse Width Modulation (PWM) to create a timbre which continually moves around. This effect is created using the pulse ugen which produces a variable width square wave. We then control the width of the pulses using a variety of LFOs - sin-osc and lf-tri in this case. We use a number of these LFO modulated pulse ugens with varying LFO type and rate (and phase in some cases) to provide the LFO with a different starting point. We then mix all these pulses together to create a thick sound and then feed it through a resonant low pass filter (rlpf). For extra bass, one of the pulses is an octave lower (half the frequency) and its LFO has a little bit of randomisation thrown into its frequency component for that extra bit of variety.
+
+### Opts:
+  * note:
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
+    - default: 52
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * sustain:
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * release:
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 110
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0.7
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+
+
+## Zawa
+
+### Key:
+  :zawa
+
+### Doc:
+  Saw wave with oscillating timbre. Produces moving saw waves with a unique character controllable with the control oscillator (usage similar to mod synths).
+
+### Opts:
+  * note:
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
+    - default: 52
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * sustain:
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * release:
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0.9
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * phase:
+    - doc: Phase duration in beats of timbre modulation.
+    - default: 1
+    - constraints: must be greater than zero
+    - May be changed whilst playing
+    - Scaled with current BPM value
+    - Has slide parameters for shaping changes
+  * phase_offset:
+    - doc: Initial phase offset of the sync wave (a value between 0 and 1).
+    - default: 0
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+  * wave:
+    - doc: Wave shape controlling freq sync saw wave. 0=saw wave, 1=pulse, 2=triangle wave and 3=sine wave.
+    - default: 3
+    - constraints: must be one of the following values: [0, 1, 2, 3]
+    - May be changed whilst playing
+  * invert_wave:
+    - doc: Invert sync freq control waveform (i.e. flip it on the y axis). 0=uninverted wave, 1=inverted wave.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * range:
+    - doc: Range of the associated sync saw in MIDI notes from the main note. Modifies timbre.
+    - default: 24
+    - constraints: must be a value between 0 and 90 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * disable_wave:
+    - doc: Enable and disable sync control wave (setting to 1 will stop timbre movement).
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * pulse_width:
+    - doc: The width of the pulse wave as a value between 0 and 1. A width of 0.5 will produce a square wave. Different values will change the timbre of the sound. Only valid if wave is type pulse.
+    - default: 0.5
+    - constraints: must be a value between 0 and 1 exclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+
+
+## Dark Ambience
+
+### Key:
+  :dark_ambience
+
+### Doc:
+  A slow rolling bass with a sparkle of light trying to escape the darkness. Great for an ambient sound.
+
+### Opts:
+  * note:
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
+    - default: 52
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * sustain:
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * release:
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 110
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0.7
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * detune1:
+    - doc: Distance (in MIDI notes) between the main note and the second component of sound. Affects thickness, sense of tuning and harmony.
+    - default: 12
+    - constraints: none
+    - Can not be changed once set
+    - Has slide parameters for shaping changes
+  * detune2:
+    - doc: Distance (in MIDI notes) between the main note and the third component of sound. Affects thickness, sense of tuning and harmony. Tiny values such as 0.1 create a thick sound.
+    - default: 24
+    - constraints: none
+    - Can not be changed once set
+    - Has slide parameters for shaping changes
+  * noise:
+    - doc: Noise source. Has a subtle effect on the timbre of the sound. 0=pink noise (the default), 1=brown noise, 2=white noise, 3=clip noise and 4=grey noise
+    - default: 0
+    - constraints: must be one of the following values: [0, 1, 2, 3, 4]
+    - May be changed whilst playing
+  * ring:
+    - doc: Amount of ring in the sound. Lower values create a more rough sound, higher values produce a sound with more focus.
+    - default: 0.2
+    - constraints: must be a value between 0.1 and 50 inclusively
+    - May be changed whilst playing
+  * room:
+    - doc: Room size in squared metres used to calculate the reverb.
+    - default: 70
+    - constraints: must be a value greater than or equal to 0.1,must be a value less than or equal to 300
+    - Can not be changed once set
+  * reverb_time:
+    - doc: How long in beats the reverb should go on for.
+    - default: 100
+    - constraints: must be zero or greater
+    - Can not be changed once set
+
+
+## Growl
+
+### Key:
+  :growl
+
+### Doc:
+  A deep rumbling growl with a bright sine shining through at higher notes.
+
+### Opts:
+  * note:
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
+    - default: 52
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0.1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * sustain:
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * release:
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 130
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0.7
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+
+
+## Hollow
+
+### Key:
+  :hollow
+
+### Doc:
+  A hollow breathy sound constructed from random noise
+
+### Opts:
+  * note:
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
+    - default: 52
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * sustain:
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * release:
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 90
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Only functional if a cutoff value is specified. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0.99
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * noise:
+    - doc: Noise source. Has a subtle effect on the timbre of the sound. 0=pink noise, 1=brown noise (the default), 2=white noise, 3=clip noise and 4=grey noise
+    - default: 1
+    - constraints: must be one of the following values: [0, 1, 2, 3, 4]
+    - May be changed whilst playing
+  * norm:
+    - doc: Normalise the audio (make quieter parts of the sample louder and louder parts quieter) - this is similar to the normaliser FX. This may emphasise any clicks caused by clipping.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+
+
+## Mono Sample Player
+
+### Key:
+  :mono_player
+
+### Doc:
+  
+
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplitude multiplier which takes place immediately before any internal FX such as the low pass filter, compressor or pitch modification. Use this opt if you want to overload the compressor.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Duration of the attack phase of the envelope.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay:
+    - doc: Duration of the decay phase of the envelope.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain:
+    - doc: Duration of the sustain phase of the envelope. When -1 (the default) will auto-stretch.
+    - default: -1
+    - constraints: must either be a positive value or -1
+    - Can not be changed once set
+  * release:
+    - doc: Duration of the release phase of the envelope.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff_attack:
+    - doc: Attack time for cutoff filter. Amount of time (in beats) for sound to reach full cutoff value. Default value is set to match amp envelope's attack value.
+    - default: attack
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * cutoff_decay:
+    - doc: Decay time for cutoff filter. Amount of time (in beats) for sound to move from full cutoff value (cutoff attack level) to the cutoff sustain level. Default value is set to match amp envelope's decay value.
+    - default: decay
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * cutoff_sustain:
+    - doc: Amount of time for cutoff value to remain at sustain level in beats. When -1 (the default) will auto-stretch.
+    - default: sustain
+    - constraints: must either be a positive value or -1
+    - Can not be changed once set
+  * cutoff_release:
+    - doc: Amount of time (in beats) for sound to move from cutoff sustain value to cutoff min value. Default value is set to match amp envelope's release value.
+    - default: release
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * cutoff_attack_level:
+    - doc: The peak cutoff (value of cutoff at peak of attack) as a MIDI note.
+    - default: cutoff
+    - constraints: must be a value between 0 and 130 inclusively
+    - Can not be changed once set
+  * cutoff_decay_level:
+    - doc: The level of cutoff after the decay phase as a MIDI note.
+    - default: cutoff
+    - constraints: must be a value between 0 and 130 inclusively
+    - Can not be changed once set
+  * cutoff_sustain_level:
+    - doc: The sustain cutoff (value of cutoff at sustain time) as a MIDI note.
+    - default: cutoff
+    - constraints: must be a value between 0 and 130 inclusively
+    - Can not be changed once set
+  * cutoff_env_curve:
+    - doc: Select the shape of the curve between levels in the cutoff envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff_min:
+    - doc: The minimum cutoff value.
+    - default: 30
+    - constraints: must be a value less than or equal to 130
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * rate:
+    - doc: Rate with which to play back - default is 1. Playing the sample at rate 2 will play it back at double the normal speed. This will have the effect of doubling the frequencies in the sample and halving the playback time. Use rates lower than 1 to slow the sample down. Negative rates will play the sample in reverse.
+    - default: 1
+    - constraints: must not be zero
+    - Can not be changed once set
+  * start:
+    - doc: A fraction (between 0 and 1) representing where in the sample to start playback. 1 represents the end of the sample, 0.5 half-way through etc.
+    - default: 0
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+  * finish:
+    - doc: A fraction (between 0 and 1) representing where in the sample to finish playback. 1 represents the end of the sample, 0.5 half-way through etc.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Only functional if a cutoff value is specified. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 0
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * norm:
+    - doc: Normalise the audio (make quieter parts of the sample louder and louder parts quieter) - this is similar to the normaliser FX. This may emphasise any clicks caused by clipping.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * pitch:
+    - doc: write me
+    - default: 0
+    - constraints: none
+    - Can not be changed once set
+    - Has slide parameters for shaping changes
+  * window_size:
+    - doc: Pitch shift works by chopping the input into tiny slices, then playing these slices at a higher or lower rate. If we make the slices small enough and overlap them, it sounds like the original sound with the pitch changed.
+
+  The window_size is the length of the slices and is measured in seconds. It needs to be around 0.2 (200ms) or greater for pitched sounds like guitar or bass, and needs to be around 0.02 (20ms) or lower for percussive sounds like drum loops. You can experiment with this to get the best sound for your input.
+    - default: 0.2
+    - constraints: must be a value greater than 5.0e-05
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pitch_dis:
+    - doc: Pitch dispersion - how much random variation in pitch to add. Using a low value like 0.001 can help to "soften up" the metallic sounds, especially on drum loops. To be really technical, pitch_dispersion is the maximum random deviation of the pitch from the pitch ratio (which is set by the pitch param)
+    - default: 0.0
+    - constraints: must be a value greater than or equal to 0
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * time_dis:
+    - doc: Time dispersion - how much random delay before playing each grain (measured in seconds). Again, low values here like 0.001 can help to soften up metallic sounds introduced by the effect. Large values are also fun as they can make soundscapes and textures from the input, although you will most likely lose the rhythm of the original. NB - This won't have an effect if it's larger than window_size.
+    - default: 0.0
+    - constraints: must be a value greater than or equal to 0
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * compress:
+    - doc: Enable the compressor. This sits at the end of the internal FX chain immediately before the `amp:` opt. Therefore to drive the compressor use the `pre_amp:` opt which will amplify the signal before it hits any internal FX. The compressor compresses the dynamic range of the incoming signal. Equivalent to automatically turning the amp down when the signal gets too loud and then back up again when it's quiet. Useful for ensuring the containing signal doesn't overwhelm other aspects of the sound. Also a general purpose hard-knee dynamic range processor which can be tuned via the opts to both expand and compress the signal.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * threshold:
+    - doc: Threshold value determining the break point between slope_below and slope_above. Only valid if the compressor is enabled by turning on the comp: opt.
+    - default: 0.2
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * clamp_time:
+    - doc: Time taken for the amplitude adjustments to kick in fully (in seconds). This is usually pretty small (not much more than 10 milliseconds). Also known as the time of the attack phase. Only valid if the compressor is enabled by turning on the comp: opt.
+    - default: 0.01
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * slope_above:
+    - doc: Slope of the amplitude curve above the threshold. A value of 1 means that the output of signals with amplitude above the threshold will be unaffected. Greater values will magnify and smaller values will attenuate the signal. Only valid if the compressor is enabled by turning on the comp: opt.
+    - default: 0.5
+    - constraints: none
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * slope_below:
+    - doc: Slope of the amplitude curve below the threshold. A value of 1 means that the output of signals with amplitude below the threshold will be unaffected. Greater values will magnify and smaller values will attenuate the signal. Only valid if the compressor is enabled by turning on the comp: opt.
+    - default: 1
+    - constraints: none
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * relax_time:
+    - doc: Time taken for the amplitude adjustments to be released. Usually a little longer than clamp_time. If both times are too short, you can get some (possibly unwanted) artefacts. Also known as the time of the release phase. Only valid if the compressor is enabled by turning on the comp: opt.
+    - default: 0.01
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+
+
+## Stereo Sample Player
+
+### Key:
+  :stereo_player
+
+### Doc:
+  
+
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: Amplitude multiplier which takes place immediately before any internal FX such as the low pass filter, compressor or pitch modification. Use this opt if you want to overload the compressor.
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Duration of the attack phase of the envelope.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay:
+    - doc: Duration of the decay phase of the envelope.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain:
+    - doc: Duration of the sustain phase of the envelope. When -1 (the default) will auto-stretch.
+    - default: -1
+    - constraints: must either be a positive value or -1
+    - Can not be changed once set
+  * release:
+    - doc: Duration of the release phase of the envelope.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff_attack:
+    - doc: Attack time for cutoff filter. Amount of time (in beats) for sound to reach full cutoff value. Default value is set to match amp envelope's attack value.
+    - default: attack
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * cutoff_decay:
+    - doc: Decay time for cutoff filter. Amount of time (in beats) for sound to move from full cutoff value (cutoff attack level) to the cutoff sustain level. Default value is set to match amp envelope's decay value.
+    - default: decay
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * cutoff_sustain:
+    - doc: Amount of time for cutoff value to remain at sustain level in beats. When -1 (the default) will auto-stretch.
+    - default: sustain
+    - constraints: must either be a positive value or -1
+    - Can not be changed once set
+  * cutoff_release:
+    - doc: Amount of time (in beats) for sound to move from cutoff sustain value to cutoff min value. Default value is set to match amp envelope's release value.
+    - default: release
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * cutoff_attack_level:
+    - doc: The peak cutoff (value of cutoff at peak of attack) as a MIDI note.
+    - default: cutoff
+    - constraints: must be a value between 0 and 130 inclusively
+    - Can not be changed once set
+  * cutoff_decay_level:
+    - doc: The level of cutoff after the decay phase as a MIDI note.
+    - default: cutoff
+    - constraints: must be a value between 0 and 130 inclusively
+    - Can not be changed once set
+  * cutoff_sustain_level:
+    - doc: The sustain cutoff (value of cutoff at sustain time) as a MIDI note.
+    - default: cutoff
+    - constraints: must be a value between 0 and 130 inclusively
+    - Can not be changed once set
+  * cutoff_env_curve:
+    - doc: Select the shape of the curve between levels in the cutoff envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff_min:
+    - doc: The minimum cutoff value.
+    - default: 30
+    - constraints: must be a value less than or equal to 130
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * rate:
+    - doc: Rate with which to play back - default is 1. Playing the sample at rate 2 will play it back at double the normal speed. This will have the effect of doubling the frequencies in the sample and halving the playback time. Use rates lower than 1 to slow the sample down. Negative rates will play the sample in reverse.
+    - default: 1
+    - constraints: must not be zero
+    - Can not be changed once set
+  * start:
+    - doc: A fraction (between 0 and 1) representing where in the sample to start playback. 1 represents the end of the sample, 0.5 half-way through etc.
+    - default: 0
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+  * finish:
+    - doc: A fraction (between 0 and 1) representing where in the sample to finish playback. 1 represents the end of the sample, 0.5 half-way through etc.
+    - default: 1
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Only functional if a cutoff value is specified. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 0
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * norm:
+    - doc: Normalise the audio (make quieter parts of the sample louder and louder parts quieter) - this is similar to the normaliser FX. This may emphasise any clicks caused by clipping.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * pitch:
+    - doc: write me
+    - default: 0
+    - constraints: none
+    - Can not be changed once set
+    - Has slide parameters for shaping changes
+  * window_size:
+    - doc: Pitch shift works by chopping the input into tiny slices, then playing these slices at a higher or lower rate. If we make the slices small enough and overlap them, it sounds like the original sound with the pitch changed.
+
+  The window_size is the length of the slices and is measured in seconds. It needs to be around 0.2 (200ms) or greater for pitched sounds like guitar or bass, and needs to be around 0.02 (20ms) or lower for percussive sounds like drum loops. You can experiment with this to get the best sound for your input.
+    - default: 0.2
+    - constraints: must be a value greater than 5.0e-05
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pitch_dis:
+    - doc: Pitch dispersion - how much random variation in pitch to add. Using a low value like 0.001 can help to "soften up" the metallic sounds, especially on drum loops. To be really technical, pitch_dispersion is the maximum random deviation of the pitch from the pitch ratio (which is set by the pitch param)
+    - default: 0.0
+    - constraints: must be a value greater than or equal to 0
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * time_dis:
+    - doc: Time dispersion - how much random delay before playing each grain (measured in seconds). Again, low values here like 0.001 can help to soften up metallic sounds introduced by the effect. Large values are also fun as they can make soundscapes and textures from the input, although you will most likely lose the rhythm of the original. NB - This won't have an effect if it's larger than window_size.
+    - default: 0.0
+    - constraints: must be a value greater than or equal to 0
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * compress:
+    - doc: Enable the compressor. This sits at the end of the internal FX chain immediately before the `amp:` opt. Therefore to drive the compressor use the `pre_amp:` opt which will amplify the signal before it hits any internal FX. The compressor compresses the dynamic range of the incoming signal. Equivalent to automatically turning the amp down when the signal gets too loud and then back up again when it's quiet. Useful for ensuring the containing signal doesn't overwhelm other aspects of the sound. Also a general purpose hard-knee dynamic range processor which can be tuned via the opts to both expand and compress the signal.
+    - default: 0
+    - constraints: must be one of the following values: [0, 1]
+    - May be changed whilst playing
+  * threshold:
+    - doc: Threshold value determining the break point between slope_below and slope_above. Only valid if the compressor is enabled by turning on the comp: opt.
+    - default: 0.2
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * clamp_time:
+    - doc: Time taken for the amplitude adjustments to kick in fully (in seconds). This is usually pretty small (not much more than 10 milliseconds). Also known as the time of the attack phase. Only valid if the compressor is enabled by turning on the comp: opt.
+    - default: 0.01
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * slope_above:
+    - doc: Slope of the amplitude curve above the threshold. A value of 1 means that the output of signals with amplitude above the threshold will be unaffected. Greater values will magnify and smaller values will attenuate the signal. Only valid if the compressor is enabled by turning on the comp: opt.
+    - default: 0.5
+    - constraints: none
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * slope_below:
+    - doc: Slope of the amplitude curve below the threshold. A value of 1 means that the output of signals with amplitude below the threshold will be unaffected. Greater values will magnify and smaller values will attenuate the signal. Only valid if the compressor is enabled by turning on the comp: opt.
+    - default: 1
+    - constraints: none
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * relax_time:
+    - doc: Time taken for the amplitude adjustments to be released. Usually a little longer than clamp_time. If both times are too short, you can get some (possibly unwanted) artefacts. Also known as the time of the release phase. Only valid if the compressor is enabled by turning on the comp: opt.
+    - default: 0.01
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+
+
+## Blade Runner style strings
+
+### Key:
+  :blade
+
+### Doc:
+  Straight from the 70s, evoking the mists of Blade Runner, this simple electro-style string synth is based on filtered saw waves and a variable vibrato.
 
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+### Opts:
+  * note:
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`
+    - default: 52
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
     - default: 0
     - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * sustain:
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * release:
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 100
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * vibrato_rate:
+    - doc: Number of wobbles per second. For realism this should be between 6 and 8, maybe even faster for really high notes.
+    - default: 6
+    - constraints: must be a value greater than or equal to 0.0,must be a value less than or equal to 20.0
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * vibrato_depth:
+    - doc: Amount of variation around the central note. 1 is the sensible maximum (but you can go up to 5 if you want a special effect), 0 would mean no vibrato. Works well around 0.15 but you can experiment.
+    - default: 0.15
+    - constraints: must be a value greater than or equal to 0.0,must be a value less than or equal to 5.0
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * vibrato_delay:
+    - doc: How long in seconds before the vibrato kicks in.
+    - default: 0.5
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * vibrato_onset:
+    - doc: How long in seconds before the vibrato reaches full power.
+    - default: 0.1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+
+
+## SynthPiano
+
+### Key:
+  :piano
+
+### Doc:
+  A basic piano synthesiser. Note that due to the plucked nature of this synth the envelope opts such as `attack:`, `sustain:` and `release:` do not work as expected. They can only shorten the natural length of the note, not prolong it. Also, the `note:` opt will only honour whole tones.
+
+### Opts:
+  * note:
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`. Note that the piano synth can only play whole tones such as 60 and does not handle floats such as 60.3
+    - default: 52
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * vel:
+    - doc: Velocity of keypress. 
+    - default: 0.2
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. With the piano synth, this opt can only have the effect of shortening the attack phase, not prolonging it.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level). With the piano synth, this opt can only have the effect of controlling the amp within the natural duration of the note and can not prolong the sound.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * sustain:
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. With the piano synth, this opt can only have the effect of controlling the amp within the natural duration of the note and can not prolong the sound.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * release:
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. With the piano synth, this opt can only have the effect of controlling the amp within the natural duration of the note and can not prolong the sound.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * hard:
+    - doc: Hardness of keypress. 
+    - default: 0.5
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+  * stereo_width:
+    - doc: Width of the stereo effect (which makes low notes sound towards the left, high notes towards the right). 0 to 1.
+    - default: 0
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+
+
+## SynthPluck
+
+### Key:
+  :pluck
+
+### Doc:
+  A basic plucked string synthesiser that uses Karplus-Strong synthesis. Note that due to the plucked nature of this synth the envelope opts such as `attack:`, `sustain:` and `release:` do not work as expected. They can only shorten the natural length of the note, not prolong it. Also, the `note:` opt will only honour whole tones.
 
+### Opts:
+  * note:
+    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: `30`, `52`, `:C`, `:C2`, `:Eb4`, or `:Ds3`. Note that the piano synth can only play whole tones such as 60 and does not handle floats such as 60.3
+    - default: 52
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
   * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.01
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * sustain:
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. With the piano synth, this opt can only have the effect of controlling the amp within the natural duration of the note and can not prolong the sound.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * release:
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. With the piano synth, this opt can only have the effect of controlling the amp within the natural duration of the note and can not prolong the sound.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level). With the piano synth, this opt can only have the effect of controlling the amp within the natural duration of the note and can not prolong the sound.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * noise_amp:
+    - doc: Amplitude of source (pink) noise.
+    - default: 0.8
+    - constraints: must be a value between 0 and 1 inclusively
+    - Can not be changed once set
+  * max_delay_time:
+    - doc: Maximum length of the delay line buffer.
+    - default: 0.125
+    - constraints: must be a value between 0.125 and 1 inclusively
+    - Can not be changed once set
+  * pluck_decay:
+    - doc: How long the pluck takes to stabilise on a note. This doesn't have a dramatic effect on the sound.
+    - default: 30
+    - constraints: must be a value between 1 and 100 inclusively
+    - Can not be changed once set
+  * coef:
+    - doc: Coefficient of the internal OnePole filter. Values around zero are resonant and bright, values towards 1 sound more dampened and cutoff. It's a little bit like playing nearer the soundhole/fingerboard for values near zero and more toward the bridge for values approaching one, although this isn't an exact comparison.
+    - default: 0.3
+    - constraints: must be a value between -1 and 1 inclusively
+    - Can not be changed once set
+
+
+## Sound In
+
+### Key:
+  :sound_in
+
+### Doc:
+  Please write documentation!
+
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * input:
+    - doc: write me
+    - default: 0
+    - constraints: none
+    - Can not be changed once set
+
+
+## Noise
+
+### Key:
+  :noise
+
+### Doc:
+  Noise that contains equal amounts of energy at every frequency - comparable to radio static. Useful for generating percussive sounds such as snares and hand claps. Also useful for simulating wind or sea effects.
+
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * sustain:
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * release:
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 110
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+
+
+## Pink Noise
+
+### Key:
+  :pnoise
+
+### Doc:
+  Noise whose spectrum falls off in power by 3 dB per octave. Useful for generating percussive sounds such as snares and hand claps. Also useful for simulating wind or sea effects.
+
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
+    - constraints: must be zero or greater
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * pan:
+    - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
+    - default: 0
+    - constraints: must be a value between -1 and 1 inclusively
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * sustain:
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
+    - default: 0
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * release:
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
+    - default: 1
+    - constraints: must be zero or greater
+    - Can not be changed once set
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
-    - default: 0
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
     - default: 2
-    - constraints: must be zero or greater
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
     - Can not be changed once set
-
   * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
     - default: 110
-    - constraints: must be zero or greater, must be a value less than 130
-    - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
+    - constraints: must be zero or greater,must be a value less than 131
     - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * res:
-    - doc: write me
-    - default: 0.3
-    - constraints: none
-    - Can not be changed once set
-
-  * res_slide:
-    - doc: write me
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
     - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## Zawa
+## Brown Noise
 
 ### Key:
-  :zawa
+  :bnoise
 
 ### Doc:
-  Write me
-
-### Arguments:
-  * note:
-    - doc: Note to play. Either a MIDI number or a symbol representing a note. For example: 30, 52, :C, :C2, :Eb4, or :Ds3
-    - default: 52
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * note_slide:
-    - doc: Amount of time (in seconds) for the note to change. A long slide value means that the note takes a long time to slide from the previous note to the new note. A slide of 0 means that the note instantly changes to the new note.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
+  Noise whose spectrum falls off in power by 6 dB per octave. Useful for generating percussive sounds such as snares and hand claps. Also useful for simulating wind or sea effects.
 
+### Opts:
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: Amount of time (in seconds) for sound to reach full amplitude. A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + sustain + release.
-    - default: 0.1
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: Amount of time (in seconds) for sound to remain at full amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: Amount of time (in seconds) for sound to move from full amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + sustain + release.
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
     - default: 1
     - constraints: must be zero or greater
     - Can not be changed once set
-
-  * cutoff:
-    - doc: MIDI note representing the highest frequences allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
-    - default: 100
-    - constraints: must be zero or greater, must be a value less than 130
-    - May be changed whilst playing
-
-  * cutoff_slide:
-    - doc: Amount of time (in seconds) for the cutoff value to change. A long cutoff_slide value means that the cutoff takes a long time to slide from the previous value to the new value. A cutoff_slide of 0 means that the cutoff instantly changes to the new value.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * rate:
-    - doc: write me
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
     - default: 1
-    - constraints: none
+    - constraints: must be zero or greater
     - Can not be changed once set
-
-  * rate_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
     - Can not be changed once set
-
-  * depth:
-    - doc: write me
-    - default: 1.5
-    - constraints: none
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
+    - default: 1
+    - constraints: must be zero or greater
     - Can not be changed once set
-
-  * depth_slide:
-    - doc: write me
-    - default: 0
-    - constraints: none
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
     - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 110
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## Mono Sample Player
+## Grey Noise
 
 ### Key:
-  :mono_player
+  :gnoise
 
 ### Doc:
-  
+  Generates noise which results from flipping random bits in a word. The spectrum is emphasised towards lower frequencies. Useful for generating percussive sounds such as snares and hand claps. Also useful for simulating wind or sea effects.
 
-### Arguments:
+### Opts:
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: 
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: 
-    - default: -1
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: 
-    - default: 0
-    - constraints: must either be a positive value or -1
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
+    - constraints: must be zero or greater
     - Can not be changed once set
-
-  * rate:
-    - doc: 
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
     - default: 1
-    - constraints: none
+    - constraints: must be zero or greater
     - Can not be changed once set
-
-  * start:
-    - doc: 
-    - default: 0
-    - constraints: must be zero or greater, must be a value between 0 and 1 inclusively
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
     - Can not be changed once set
-
-  * finish:
-    - doc: 
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
     - default: 1
-    - constraints: must be zero or greater, must be a value between 0 and 1 inclusively
+    - constraints: must be zero or greater
     - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 110
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## Stereo Sample Player
+## Clip Noise
 
 ### Key:
-  :stereo_player
+  :cnoise
 
 ### Doc:
-  
+  Generates noise whose values are either -1 or 1. This produces the maximum energy for the least peak to peak amplitude. Useful for generating percussive sounds such as snares and hand claps. Also useful for simulating wind or sea effects.
 
-### Arguments:
+### Opts:
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * attack:
+    - doc: Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently. Full length of sound is attack + decay + sustain + release.
     - default: 0
     - constraints: must be zero or greater
-    - May be changed whilst playing
-
-  * attack:
-    - doc: 
+    - Can not be changed once set
+    - Scaled with current BPM value
+  * decay:
+    - doc: Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).
     - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * sustain:
-    - doc: 
-    - default: -1
+    - doc: Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.
+    - default: 0
     - constraints: must be zero or greater
     - Can not be changed once set
-
+    - Scaled with current BPM value
   * release:
-    - doc: 
-    - default: 0
-    - constraints: must either be a positive value or -1
+    - doc: Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently. Full length of sound is attack + decay + sustain + release.
+    - default: 1
+    - constraints: must be zero or greater
     - Can not be changed once set
-
-  * rate:
-    - doc: 
+    - Scaled with current BPM value
+  * attack_level:
+    - doc: Amplitude level reached after attack phase and immediately before decay phase
     - default: 1
-    - constraints: none
+    - constraints: must be zero or greater
     - Can not be changed once set
-
-  * start:
-    - doc: 
-    - default: 0
-    - constraints: must be zero or greater, must be a value between 0 and 1 inclusively
+  * decay_level:
+    - doc: Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set
+    - default: sustain_level
+    - constraints: must be zero or greater
     - Can not be changed once set
-
-  * finish:
-    - doc: 
+  * sustain_level:
+    - doc: Amplitude level reached after decay phase and immediately before release phase.
     - default: 1
-    - constraints: must be zero or greater, must be a value between 0 and 1 inclusively
+    - constraints: must be zero or greater
     - Can not be changed once set
+  * env_curve:
+    - doc: Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed
+    - default: 2
+    - constraints: must be one of the following values: [1, 2, 3, 4, 6, 7]
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 110
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-
-## Basic Mono Sample Player - (no envelope)
+## Basic Mono Sample Player (no env)
 
 ### Key:
   :basic_mono_player
@@ -2058,46 +3856,39 @@
 ### Doc:
   
 
-### Arguments:
+### Opts:
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * rate:
     - doc: write me
     - default: 1
-    - constraints: none
+    - constraints: must not be zero
     - Can not be changed once set
-
-  * rate_slide:
-    - doc: write me
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
     - default: 0
-    - constraints: none
-    - Can not be changed once set
-
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
+    - default: 0
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
 
-## Basic Stereo Sample Player - (no envelope)
+## Basic Stereo Sample Player (no env)
 
 ### Key:
   :basic_stereo_player
@@ -2105,42 +3896,117 @@
 ### Doc:
   
 
-### Arguments:
+### Opts:
   * amp:
-    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, it will just reduce the quality of all the sounds currently being played (due to compression.)
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
     - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
-
-  * amp_slide:
-    - doc: Amount of time (in seconds) for the amplitude (amp) to change. A long slide value means that the amp takes a long time to slide from the previous amplitude to the new amplitude. A slide of 0 means that the amplitude instantly changes to the new amplitude.
-    - default: 0
-    - constraints: must be zero or greater
-    - May be changed whilst playing
-
+    - Has slide parameters for shaping changes
   * pan:
     - doc: Position of sound in stereo. With headphones on, this means how much of the sound is in the left ear, and how much is in the right ear. With a value of -1, the sound is completely in the left ear, a value of 0 puts the sound equally in both ears and a value of 1 puts the sound in the right ear. Values in between -1 and 1 move the sound accordingly.
     - default: 0
     - constraints: must be a value between -1 and 1 inclusively
     - May be changed whilst playing
-
-  * pan_slide:
-    - doc: Amount of time (in seconds) for the pan to change. A long slide value means that the pan takes a long time to slide from the previous pan position to the new pan position. A slide of 0 means that the pan instantly changes to the new pan position.
+    - Has slide parameters for shaping changes
+  * rate:
+    - doc: write me
+    - default: 1
+    - constraints: must not be zero
+    - Can not be changed once set
+  * cutoff:
+    - doc: MIDI note representing the highest frequencies allowed to be present in the sound. A low value like 30 makes the sound round and dull, a high value like 100 makes the sound buzzy and crispy.
+    - default: 0
+    - constraints: must be zero or greater,must be a value less than 131
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+  * res:
+    - doc: Filter resonance as a value between 0 and 1. Large amounts of resonance (a res: near 1) can create a whistling sound around the cutoff frequency. Smaller values produce less resonance.
     - default: 0
+    - constraints: must be zero or greater,must be a value less than 1
+    - May be changed whilst playing
+    - Has slide parameters for shaping changes
+
+
+## Basic Mixer
+
+### Key:
+  :basic_mixer
+
+### Doc:
+  Please write documentation!
+
+### Opts:
+  * amp:
+    - doc: The amplitude of the sound. Typically a value between 0 and 1. Higher amplitudes may be used, but won't make the sound louder, they will just reduce the quality of all the sounds currently being played (due to compression.)
+    - default: 1
     - constraints: must be zero or greater
     - May be changed whilst playing
+    - Has slide parameters for shaping changes
 
-  * rate:
+
+## Main Mixer
+
+### Key:
+  :main_mixer
+
+### Doc:
+  Please write documentation!
+
+### Opts:
+  * amp:
     - doc: write me
     - default: 1
     - constraints: none
     - Can not be changed once set
-
-  * rate_slide:
+    - Has slide parameters for shaping changes
+  * pre_amp:
+    - doc: write me
+    - default: 1
+    - constraints: none
+    - Can not be changed once set
+    - Has slide parameters for shaping changes
+  * hpf:
+    - doc: write me
+    - default: 0
+    - constraints: none
+    - Can not be changed once set
+    - Has slide parameters for shaping changes
+  * lpf:
+    - doc: write me
+    - default: 135.5
+    - constraints: none
+    - Can not be changed once set
+    - Has slide parameters for shaping changes
+  * hpf_bypass:
+    - doc: write me
+    - default: 0
+    - constraints: none
+    - Can not be changed once set
+  * lpf_bypass:
+    - doc: write me
+    - default: 0
+    - constraints: none
+    - Can not be changed once set
+  * force_mono:
+    - doc: write me
+    - default: 0
+    - constraints: none
+    - Can not be changed once set
+  * invert_stereo:
+    - doc: write me
+    - default: 0
+    - constraints: none
+    - Can not be changed once set
+  * limiter_bypass:
+    - doc: write me
+    - default: 0
+    - constraints: none
+    - Can not be changed once set
+  * leak_dc_bypass:
     - doc: write me
     - default: 0
     - constraints: none
     - Can not be changed once set
-
 
 
diff --git a/etc/doc/tutorial/de/01.2-Exploring-the-Interface.md b/etc/doc/tutorial/de/01.2-Exploring-the-Interface.md
index c43a207..a66d90f 100644
--- a/etc/doc/tutorial/de/01.2-Exploring-the-Interface.md
+++ b/etc/doc/tutorial/de/01.2-Exploring-the-Interface.md
@@ -25,7 +25,7 @@ ablaufenden Code an, `Speichern` schreibt den Code in eine Datei und
 ## B. Editor-Steuerung
 
 Die orangefarbenen Buttons steuern den Code-Editor. Die `Text vergrößern` 
-and `Text verkleinern`-Buttons verändern die Schriftgröße.
+und `Text verkleinern`-Buttons verändern die Schriftgröße.
 `Auto-Align Text`-Button richtet den Code ordentlich aus, damit er
 professioneller aussieht und besser lesbar ist.
 
@@ -43,7 +43,7 @@ Fenster, wo Du einige grundsätzliche Einstellungen regeln kannst.
 In diesem Bereich schreibst Du Deinen Code, komponierst Du Deine Musik
 und führst sie später auf. Es ist ein einfacher Texteditor, in dem
 Du Code eingibst und bearbeitest; so eine Art sehr einfache
-Textverabeitung wie Word oder Google Docs. Der Editor färbt 
+Textverarbeitung wie Word oder Google Docs. Der Editor färbt 
 bestimmte Begriffe automatisch ein, je nachdem, welche Bedeutung sie 
 innerhalb des Codes haben. Am Anfang ist das vielleicht ein wenig 
 merkwürdig, aber Du wirst es bald nützlich finden. Zum Beispiel erkennst
diff --git a/etc/doc/tutorial/en/03.6-External-Samples.md b/etc/doc/tutorial/en/03.6-External-Samples.md
index 249a742..d225602 100644
--- a/etc/doc/tutorial/en/03.6-External-Samples.md
+++ b/etc/doc/tutorial/en/03.6-External-Samples.md
@@ -23,29 +23,9 @@ for others to manipulate, mash-up and experiment with your work. Of
 course this shouldn't stop you from using your own samples, it's just
 something to consider.
 
-<!-- ## Freesound Support -->
-
-<!-- One way to get the ability to experiment with new sounds whilst keeping -->
-<!-- code portability is to use the [Freesound](http:freesound.org) -->
-<!-- support. http://freesound.org is a website which allows people to upload -->
-<!-- and share their samples. Each sample uploaded gets a special number -->
-<!-- (kind of like a phone number) which you can use to dial up that sample -->
-<!-- from Sonic Pi. The only drawback is that you need to have internet -->
-<!-- access for it to work. -->
-
-<!-- If you currently have internet access, try it for yourself: -->
-
-<!-- ``` -->
-<!-- freesound 24787 -->
-<!-- ``` -->
-
-<!-- The first time you do this you'll hear a standard `:elec_beep` as a -->
-<!-- placeholder for the sound. Y -->
-
-
 ## Local Samples
 
-So how do you play any arbitrary WAV or AIFF file on your computer?
+So how do you play any arbitrary WAV, AIFF or FLAC file on your computer?
 All you need to do is pass the path of that file to `sample`:
 
 ```
@@ -64,3 +44,4 @@ sample "/Users/sam/Desktop/my-sound.wav", rate: 0.5, amp: 0.3
 # Windows
 sample "C:/Users/sam/Desktop/my-sound.wav", rate: 0.5, amp: 0.3
 ```
+
diff --git a/etc/doc/tutorial/en/03.7-Sample-Packs.md b/etc/doc/tutorial/en/03.7-Sample-Packs.md
new file mode 100644
index 0000000..0d4aa34
--- /dev/null
+++ b/etc/doc/tutorial/en/03.7-Sample-Packs.md
@@ -0,0 +1,230 @@
+3.7 Sample Packs
+
+# Sample Packs
+
+**Note: this section of the tutorial covers the advanced topic of
+working with large directories of your own samples. This will be the
+case if you've downloaded or bought your own sample packs and wish to
+use them within Sonic Pi.**
+
+**Feel free to skip this if you're happy working with the built-in
+samples.**
+
+When working with large folders of external samples it can be cumbersome
+to have to type the whole path every time to trigger an individual
+sample.
+
+For example, say you have the following folder on your machine:
+
+```
+/path/to/my/samples/
+```
+
+When we look inside that folder we find the following samples:
+
+* `100_A#_melody1.wav`
+* `100_A#_melody2.wav`
+* `100_A#_melody3.wav`
+* `120_A#_melody4.wav`
+* `120_Bb_guit1.wav`
+* `120_Bb_piano1.wav`
+
+Typically in order to play the piano sample we can use the full path:
+
+```
+sample "/path/to/my/samples/120_Bb_piano1.wav"
+```
+
+If we want to then play the guitar sample we can use its full path too:
+
+```
+sample "/path/to/my/samples/120_Bb_guit.wav"
+```
+
+However, both of these calls to sample requires us to *know* the names
+of the samples within our directory. What if we just want to listen to
+each sample in turn quickly? 
+
+## Indexing Sample Packs
+
+If we want to play the first sample in a directory we just need to pass
+the directory's name to `sample` and the index `0` as follows:
+
+```
+sample "/path/to/my/samples/", 0
+```
+
+We can even make a shortcut to our directory path using a variable:
+
+```
+samps = "/path/to/my/samples/"
+sample samps, 0
+```
+
+Now, if we want to play the second sample in our directory, we just need
+to add 1 to our index:
+
+```
+samps = "/path/to/my/samples/"
+sample samps, 1
+```
+
+Notice that we no longer need to know the names of the samples in the
+directory - we just need to know the directory itself (or have a
+shortcut to it). If we ask for an index which is larger than the number
+of samples, it simply wraps round just like Rings. Therefore, whatever
+number we use we're guaranteed to get one of the samples in that
+directory.
+
+## Filtering Sample Packs
+
+Usually indexing is enough, but sometimes we need more power to sort
+and organise our samples. Luckily many sample packs add useful
+information in the filenames. Let's take another look at the sample file
+names in our directory:
+
+* `100_A#_melody1.wav`
+* `100_A#_melody2.wav`
+* `100_A#_melody3.wav`
+* `120_A#_melody4.wav`
+* `120_Bb_guit1.wav`
+* `120_Bb_piano1.wav`
+
+Notice that in these filenames we have quite a bit of
+information. Firstly, we have the BPM of the sample (beats per minute)
+at the start. So, the piano sample is at 120 BPM and our first three
+melodies are at 100 BPM. Also, our sample names contain the key. So the
+guitar sample is in Bb and the melodies are in A#. This information is
+very useful for mixing in these samples with our other code. For
+example, we know we can only play the piano sample with code that's in
+120 BPM and in the key of Bb.
+
+It turns out that we can use this particular naming convention of our
+sample sets in the code to help us filter out the ones we want. For
+example, if we're working at 120 BPM, we can filter down to all the
+samples that contain the string `"120"` with the following:
+
+```
+samps = "/path/to/my/samples/"
+sample samps, "120"
+```
+
+This will play us the first match. If we want the second match we just
+need to use the index:
+
+```
+samps = "/path/to/my/samples/"
+sample samps, "120", 1
+```
+
+We can even use multiple filters at the same time. For example, if we
+want a sample whose filename contains both the substrings "120" and "A#"
+we can find it easily with the following code:
+
+```
+samps = "/path/to/my/samples/"
+sample samps, "120", "A#"
+```
+
+Finally, we're still free to add our usual opts to the call to `sample`:
+
+```
+samps = "/path/to/my/samples/"
+sample samps, "120", "Bb", 1, lpf: 70, amp: 2
+```
+
+## Sources
+
+The sample filter pre-arg system understands two types of information:
+sources and filters. Sources are information used to create the list of
+potential candidates. A source can take two forms:
+
+1. "/path/to/samples" - a string representing a valid path to a directory 
+2. "/path/to/samples/foo.wav" - a string representing a valid path to a sample
+
+The `sample` fn will first gather all sources and use them to create a
+large list of candidates. This list is constructed by first adding all
+valid paths and then by adding all the valid `.flac`, `.aif`, `.aiff`,
+`.wav`, `.wave` files contained within the directories.
+
+For example, take a look at the following code:
+
+```
+samps = "/path/to/my/samples/"
+samps2 = "/path/to/my/samples2/"
+path = "/path/to/my/samples3/foo.wav"
+
+sample samps, samps2, path, 0
+```
+
+Here, we're combining the contents of the samples within two directories
+and adding a specific sample. If `"/path/to/my/samples/"` contained 3
+samples and `"/path/to/my/samples2/"` contained 12, we'd have 16
+potential samples to index and filter (3 + 12 + 1).
+
+By default, only the sample files within a directory are gathered into
+the candidate list. Sometimes you might have a number of nested folders of
+samples you wish to search and filter within. You can therefore do a
+recursive search for all samples within all subfolders of a particular
+folder by adding `**` to the end of the path:
+
+```
+samps = "/path/to/nested/samples/**"
+sample samps, 0
+```
+
+Take care though as searching through a very large set of folders may
+take a long time. However, the contents of all folder sources are
+cached, so the delay will only happen the first time.
+
+Finally, note that the sources *must go first*. If no source is given,
+then the set of built-in samples will be selected as the default list of
+candidates to work with:
+
+## Filters
+
+Once you have a list of candidates you may use the following filtering
+types to further reduce the selection:
+
+* `"foo"` Strings will filter on substring occurrence within file name (minus directory path and extension).
+* `/fo[oO]/` Regular Expressions will filter on pattern matching of file name (minus directory path and extension).
+* `:foo` - Keywords will filter candidates on whether the keyword is a direct match of the filename (minus directory path and extension).
+* `lambda{|a| ... }` - Procs with one argument will be treated as a candidate filter or generator function. It will be passed the list of current candidates and must return a new list of candidates (a list of valid paths to sample files).
+* `1` - Numbers will select the candidate with that index (wrapping round like a ring if necessary).
+
+For example, we can filter over all the samples in a directory
+containing the string \"foo\" and play the first matching sample at half
+speed:
+
+```
+sample \"/path/to/samples\", \"foo\", rate: 0.5
+```
+
+See the help for `sample` for many detailed usage examples. Note that
+the ordering of the filters is honoured.
+
+## Composites
+
+Finally, you may use lists wherever you may place a source or
+filter. The list will be automatically flattened and the contents will
+be treated as regular sources and filters. Therefore the following calls
+to `sample` are semantically equivalent:
+
+```
+sample "/path/to/dir", "100", "C#"
+sample ["/path/to/dir", "100", "C#"]
+sample "/path/to/dir", ["100", "C#"]
+sample ["/path/to/dir", ["100", ["C#"]]]
+```
+
+## Wrapping Up
+
+This was an advanced section for people that need real power to
+manipulate and use sample packs. If most of this section didn't make too
+much sense, don't worry. It's likely you don't need any of this
+functionality just yet. However, you'll know when you do need it and you
+can come back and re-read this when you start working with large
+directories of samples.
+
+
+
diff --git a/etc/doc/tutorial/en/08.5-Ring-Chains.md b/etc/doc/tutorial/en/08.5-Ring-Chains.md
index 4b49590..bac4094 100644
--- a/etc/doc/tutorial/en/08.5-Ring-Chains.md
+++ b/etc/doc/tutorial/en/08.5-Ring-Chains.md
@@ -50,7 +50,7 @@ Can you see how we can just create a long chain of these methods by just
 creating an extremely rich and powerful way of generating new rings from
 existing ones.
 
-## Immutablility
+## Immutability
 
 These rings have a powerful and important property. They are immutable
 which means that they can not change. This means that the chaining
@@ -66,10 +66,12 @@ Here's a list of the available chain methods for you to play with:
 * `.reverse` - returns a reversed version of the ring
 * `.sort`    - creates a sorted version of the ring
 * `.shuffle` - creates a shuffled version of the ring
+* `.pick(3)` - returns a ring with the results of calling `.choose` 3 times
+* `.pick`    - similar to `.pick(3)` only the size defaults to the same as the original ring
 * `.take(5)` - returns a new ring containing only the first 5 elements
 * `.drop(3)` - returns a new ring with everything but the first 3 elements
 * `.butlast` - returns a new ring with the last element missing
-* `.drop_last(3)` - returns a new ring with the 3 elements missing
+* `.drop_last(3)` - returns a new ring with the last 3 elements missing
 * `.take_last(6)`- returns a new ring with only the last 6 elements
 * `.stretch(2)` - repeats each element in the ring twice
 * `.repeat(3)` - repeats the entire ring 3 times
diff --git a/etc/doc/tutorial/en/09.4-Ticking.md b/etc/doc/tutorial/en/09.4-Ticking.md
index bccdd72..c9b5014 100644
--- a/etc/doc/tutorial/en/09.4-Ticking.md
+++ b/etc/doc/tutorial/en/09.4-Ticking.md
@@ -9,7 +9,18 @@ sleeps for rhythms, chord progressions, timbral variations, etc. etc.
 ## Ticking Rings
 
 Sonic Pi provides a *very* handy tool for working with rings within
-`live_loop`s. It's called the tick system. It provides you with the ability to *tick through rings*. Let's look at an example:
+`live_loop`s. It's called the tick system. In the section about the rings we were talking about the counter that is constantly increasing, like a current beat number. Tick just implements this idea. It provides you with the ability to *tick through rings*. Let's look at an example:
+
+```
+counter = 0
+live_loop :arp do
+  play (scale :e3, :minor_pentatonic)[counter], release: 0.1
+  counter += 1
+  sleep 0.125
+end
+```
+
+This is equivalent to:
 
 ```
 live_loop :arp do
diff --git a/etc/doc/tutorial/en/10.2-Shortcut-Cheatsheet.md b/etc/doc/tutorial/en/10.2-Shortcut-Cheatsheet.md
index 57a40c3..63e541e 100644
--- a/etc/doc/tutorial/en/10.2-Shortcut-Cheatsheet.md
+++ b/etc/doc/tutorial/en/10.2-Shortcut-Cheatsheet.md
@@ -44,9 +44,9 @@ Windows/Linux or *Cmd* on Mac):
 ## Text Manipulation
 
 * `M-m` - Align all text
-* `Tab` - Align current line/selection (or complete list)
+* `Tab` - Align current line or selection (or select autocompletion)
 * `C-l` - Centre editor
-* `M-/` - Comment/Uncomment current line
+* `M-/` - Comment/Uncomment current line or selection
 * `C-t` - Transpose/swap characters
 * `M-u` - Convert next word (or selection) to upper case.  
 * `M-l` - Convert next word (or selection) to lower case.  
diff --git a/etc/doc/tutorial/en/A.04-synth-riffs.md b/etc/doc/tutorial/en/A.04-synth-riffs.md
index 1cc8b3e..5a20639 100644
--- a/etc/doc/tutorial/en/A.04-synth-riffs.md
+++ b/etc/doc/tutorial/en/A.04-synth-riffs.md
@@ -9,7 +9,7 @@ tutorial series we covered how to code our beats. In this tutorial we'll
 cover how to code up the three core components of a synth riff - the
 timbre, melody and rhythm.
 
-OK, so power up you Raspberry Pi, crack open Sonic Pi v2.6+ and let's
+OK, so power up your Raspberry Pi, crack open Sonic Pi v2.6+ and let's
 make some noise!
 
 
@@ -93,7 +93,7 @@ things: rings, randomisation and random seeds. Let's look at an example:
     end
 
 There's a few things going on - let's look at them in turn. First, we
-specify that we're using random seed 3. What does this mean? Well, The
+specify that we're using random seed 3. What does this mean? Well, the
 useful thing is that when we set the seed, we can predict what the next
 random value is going to be - it's the same as it was last time we set
 the seed to 3! Another useful thing to know is that shuffling a ring of
@@ -148,7 +148,7 @@ will return `true`. In other words, 50% of the time it will return
 `true`. Using higher values will make it return `false` more often
 introducing more space into the riff.
 
-Notices that we've added some iteration in here with `16.times`. This is
+Notice that we've added some iteration in here with `16.times`. This is
 because we only want to reset our random seed value every 16 notes so
 our rhythm repeats every 16 times. This doesn't affect the shuffling as
 that is still done immediately after the seed is set. We can use the
diff --git a/etc/doc/tutorial/en/A.06-minecraft.md b/etc/doc/tutorial/en/A.06-minecraft.md
index 0a0c76a..6bc6ded 100644
--- a/etc/doc/tutorial/en/A.06-minecraft.md
+++ b/etc/doc/tutorial/en/A.06-minecraft.md
@@ -125,7 +125,7 @@ trail again. Now, without stopping the code, just simply change `:melon` to
 `:brick` and hit run. Hey presto, you're now making a brick trail. How
 simple was that! Fancy some music to go with it? Easy. Try this:
 
-    live_loop :bass_trail
+    live_loop :bass_trail do
       tick
       x, y, z = mc_location
       b = (ring :melon, :brick, :glass).look
diff --git a/etc/doc/tutorial/en/A.09-randomisation.md b/etc/doc/tutorial/en/A.09-randomisation.md
new file mode 100644
index 0000000..8c89801
--- /dev/null
+++ b/etc/doc/tutorial/en/A.09-randomisation.md
@@ -0,0 +1,180 @@
+A.9 Randomisation
+
+# Surfing Random Streams
+
+Back in episode 4 of this tutorial series we took a brief look at
+randomisation whilst coding up some sizzling synth riffs. Given that
+randomisation is such an important part of my live coding DJ sets I
+thought it would be useful to cover the fundamentals in much greater
+detail. So, get your lucky hat on and let's surf some random streams!
+
+# There is no random
+
+The first thing to learn which might really surprise you when playing
+with Sonic Pi's randomisation functions is that they're not actually
+really random. What does this actually mean? Well, let's try a couple of
+tests. First, imagine a number in your head between 0 and 1. Keep it
+there and don't tell me. Now let me guess... was it `0.321567`? No? Bah,
+I'm clearly no good at this. Let me have another go, but let's ask Sonic
+Pi to choose a number this time. Fire up Sonic Pi v2.7+ and ask it for a
+random number but again don't tell me:
+
+    print rand
+    
+Now for the reveal... was it `0.75006103515625`? Yes! Ha, I can see
+you're a little sceptical. Perhaps it was just a lucky guess. Let's try
+again. Press the Run button again and see what we get... What?
+`0.75006103515625` again? This clearly can't be random! You're right,
+it's not.
+
+What's going on here? The fancy computer science word here is
+determinism. This just means that nothing is by chance and everything is
+destined to be. Your version of Sonic Pi is destined to always return
+`0.75006103515625` in the program above. This might sound pretty
+useless, but let me assure you that it's one of the most powerful parts
+of Sonic Pi. If you stick at it you'll learn how to rely on the
+deterministic nature of Sonic Pi's randomisation as a fundamental
+building block for your compositions and live coded DJ sets.
+
+# A Random Melody
+
+When Sonic Pi boots it actually loads into memory a sequence of 441,000
+pre-generated random values. When you call a random function such as
+`rand` or `rrand`, this random stream is used to generate your
+result. Each call to a random function consumes a value from this
+stream. Therefore the 10th call to a random function will use the 10th
+value from the stream. Also, every time you press the Run button, the
+stream is reset for that run. This is why I could predict the result to
+`rand` and why the 'random' melody was the same every time. Everybody's
+version of Sonic Pi uses the exact same random stream which is very
+important when we start sharing our pieces with each other. 
+
+Let's use this knowledge to generate a repeatable random melody:
+
+    8.times do
+     play rrand_i(50, 95)
+     sleep 0.125
+    end
+
+Type this into a spare buffer and hit Run. You'll hear a melody
+consisting of 'random' notes between 50 and 95. When it's finished, hit
+Run again to hear exactly the same melody again.
+
+*start breakout box*
+## Handy Randomisation Functions
+ Sonic Pi comes with a number of useful functions for working with the
+random stream. Here's a list of some of the most useful:
+
+* `rand` - Simply returns the next value in the random stream
+* `rrand` - Returns a random value within a range
+* `rrand_i` - Returns a random whole number within a range
+* `one_in` - Returns true or false with the given probability
+* `dice` - Imitates rolling a dice and returns a value between 1 and 6
+* `choose` - Chooses a random value from a list
+
+Check out their documentation in the Help system for detailed
+information and examples.
+
+ *end breakout box*
+
+# Resetting the Stream
+
+Whilst the ability to repeat a sequence of chosen notes is essential to
+allow you to replay a riff on the dance floor, it might not be exactly
+the riff you want. Wouldn't it be great if we could try a number of
+different riffs and choose the one we liked best? This is where the real
+magic starts.
+
+We can manually set the stream with the fn `use_random_seed`. In
+Computer Science, a random seed is the starting point from which a new
+stream of random values can sprout out and blossom. Let's try it:
+
+    use_random_seed 0
+    3.times do
+      play rrand_i(50, 95)
+      sleep 0.125
+    end
+    
+Great, we get the first three notes of our random melody above: `84`,
+`83` and `71`. However, we can now change the seed to something
+else. How about this:
+
+    use_random_seed 1
+    3.times do
+      play rrand_i(50, 95)
+      sleep 0.125
+    end
+    
+    
+Interesting, we get `83`, `71` and `61` . You might notice that the
+first two numbers here are the same as the last two numbers before -
+this isn't a coincidence.
+
+Remember that the random stream is just a giant list of 'pre-rolled'
+values. Using a random seed simply jumps us to a point in that
+list. Another way of thinking about it is to imagine a huge deck of
+pre-shuffled cards. Using a random seed is cutting the deck at a
+particular point. The fabulous part of this is that it's precisely this
+ability to jump around the random stream which gives us huge power when making
+music.
+
+Let's revisit our random melody of 8 notes with this new stream
+resetting power, but let's also throw in a live loop so we can
+experiment live whilst it's playing:
+
+    live_loop :random_riff do    
+      use_random_seed 0
+      8.times do
+        play rrand_i(50, 95), release: 0.1
+        sleep 0.125
+      end
+    end
+
+Now, whilst it's still playing, change the seed value from `0` to
+something else. Try `100`, what about `999`. Try your own values,
+experiment and play around - see which seed generates the riff you like
+best.
+
+# Bringing it all together
+
+This month's tutorial has been quite a technical dive into the workings
+of Sonic Pi's randomisation functionality. Hopefully it has given you
+some insight into how it works and how you can start using randomisation
+in a reliable way to create repeatable patterns within your music. It's
+important to stress that you can use repeatable randomisation *anywhere*
+you want. For example, you can randomise the amplitude of notes, the
+timing of the rhythm, the amount of reverb, the current synth, the mix
+of an FX, etc. etc. In the future we'll take a close look at some of
+these applications, but for now let me leave you with a short example.
+
+Type the following into a spare buffer, hit Run, and then start changing
+the seeds around, hit Run again (whilst it's still playing) and explore
+the different sounds, rhythms and melodies you can make. When you find a
+nice one, remember the seed number so you can get back to it. Finally,
+when you've found a few seeds you like, put on a live coded performance
+for your friends by simply switching between your favourite seeds to
+create a full piece.
+
+live_loop :random_riff do
+  use_random_seed 10300
+  use_synth :prophet
+  s = [0.125, 0.25, 0.5].choose
+  8.times do
+    r = [0.125, 0.25, 1, 2].choose
+    n = (scale :e3, :minor).choose
+    co = rrand(30, 100)
+    play n, release: r, cutoff: co
+    sleep s
+  end
+end
+
+live_loop :drums do
+  use_random_seed 2001
+  16.times do
+    r = rrand(0.5, 10)
+    sample :drum_bass_hard, rate: r, amp: rand
+    sleep 0.125
+  end
+end
+
+
diff --git a/etc/doc/tutorial/en/A.10-controlling-your-sound.md b/etc/doc/tutorial/en/A.10-controlling-your-sound.md
new file mode 100644
index 0000000..e3e6e08
--- /dev/null
+++ b/etc/doc/tutorial/en/A.10-controlling-your-sound.md
@@ -0,0 +1,182 @@
+A.10 Control
+
+# Controlling Your Sound
+
+So far during this series we've focussed on triggering sounds. We've
+discovered that we can trigger the many synths built into Sonic Pi with
+`play` or `synth` and how to trigger pre-recorded samples with
+`sample`. We've also looked at how we can wrap these triggered sounds
+within studio FX such as reverb and distortion using the `with_fx`
+command. Combine this with Sonic Pi's incredibly accurate timing system
+and you can produce a vast array of sounds, beats and riffs. However,
+once you've carefully selected a particular sound's options and
+triggered it, there's no ability to mess with it whilst it's playing
+right? Wrong! Today you're going to learn something very powerful - how
+to control running synths.
+
+## A Basic Sound
+
+Let's create a nice simple sound. Fire up Sonic Pi and in a fresh buffer
+type the following:
+
+```
+synth :prophet, note: :e1, release: 8, cutoff: 100
+```
+
+Now press the Run button at the top left to hear a lovely rumbling synth
+sound. Go ahead, press it again a few times to get a feel for it. OK,
+done? Let's start controlling it!
+
+
+## Synth Nodes
+
+A little known feature in Sonic Pi is that the fns `play`, `synth` and
+`sample`, return something called a `SynthNode` which represents a
+running sound. You can capture one of these `SynthNode`s using a
+standard variable and then **control** it at a later point in time. For
+example, let's change the value of the `cutoff:` opt after 1 beat:
+
+```
+sn = synth :prophet, note: :e1, release: 8, cutoff: 100
+sleep 1
+control sn, cutoff: 130
+```
+
+Let's look at each line in turn: 
+
+Firstly we trigger the `:prophet` synth using the `synth` fn as
+normal. However we also capture the result in a variable called `sn`. We
+could have called this variable something completely different such as
+`synth_node` or `jane` - the name doesn't matter. However, it's
+important to choose a name that's meaningful to you for your
+performances and for people reading your code. I chose `sn` as it's a nice
+short mnemonic for synth node.
+
+On line 2 we have a standard `sleep` command. This does nothing special
+- it just asks the computer to wait for 1 beat before moving onto the
+next line.
+
+Line 3 is where the control fun starts. Here, we use the `control` fn to
+tell our running `SynthNode` to change the cutoff value to `130`. If you
+hit the **Run** button, you'll hear the `:prophet` synth start playing
+as before, but after 1 beat it will shift to sound a lot brighter.
+
+
+** Breakout Box Start **
+Modulatable Options
+
+Most of Sonic Pi's synths and FX opts may be changed after being
+triggered. However, this isn't the case for all of them. For example,
+the envelope opts `attack:`, `decay:`, `sustain:` and `release:` can
+only be set when triggering the synth. Figuring out which opts can and
+can't be changed is simple - just head to the documentation for a given
+synth or FX and then scroll down to the individual option documentation
+and look for the phrases "May be changed whilst playing" or "Can not be
+changed once set". For example, the documentation for the `:beep`
+synth's `attack:` opt makes it clear that it's not possible to change
+it:
+
+* Default: 0 
+* Must be zero or greater 
+* Can not be changed once set 
+* Scaled with current BPM value 
+** Breakout Box End **
+
+## Multiple Changes
+
+Whilst a synth is running you're not limited to changing it only once -
+you're free to change it as many times as you like. For example, we can
+turn our `:prophet` into a mini arpeggiator with the following:
+
+```
+notes = (scale :e3, :minor_pentatonic)
+sn = synth :prophet, note: :e1, release: 8, cutoff: 100
+sleep 1
+16.times do
+  control sn, note: notes.tick
+  sleep 0.125
+end
+```
+
+In this snippet of code we just added a couple of extra things. First we
+defined a new variable called `notes` which contains the notes we'd like
+to cycle through (an arpeggiator is just a fancy name for something that
+cycles through a list of notes in order). Secondly we replaced our
+single call to `control` with an iteration calling it 16 times. In each
+call to `control` we `.tick` through our ring of `notes` which will
+automatically repeat once we get to the end (thanks to the fabulous power
+of Sonic Pi's rings). For a bit of variety try replacing `.tick` with
+`.choose` and see if you can hear the difference.
+
+Note that we can change multiple opts simultaneously. Try changing the
+control line to the following and listen for the difference:
+
+```
+control sn, note: notes.tick, cutoff: rrand(70, 130)
+```
+
+## Sliding 
+
+When we control a `SynthNode`, it responds exactly on time and instantly
+changes the value of the opt to the new one as if you'd pressed a button
+or flicked a switch requesting the change. This can sound rhythmical and percussive -
+especially if the opt controls an aspect of the timbre such as
+`cutoff:`. However, sometimes you don't want the change to happen
+instantaneously. Instead, you might want to smoothly move from the
+current value to the new one as if you'd moved a slider or dial. Of
+course, Sonic Pi can also do this too using the `_slide:` opts.
+
+Each opt that can be modified also has a special corresponding `_slide:`
+opt that allows you to specify a slide time. For example, `amp:` has
+`amp_slide:` and `cutoff:` has `cutoff_slide:`. These slide opts work
+slightly differently than all the other opts in that they tell the synth
+note how to behave **next time they are controlled**. Let's take a look:
+
+```
+sn = synth :prophet, note: :e1, release: 8, cutoff: 70, cutoff_slide: 2
+sleep 1
+control sn, cutoff: 130
+```
+
+Notice how this example is exactly the same as before except with the
+addition of `cutoff_slide:`. This is saying that next time this synth
+has its `cutoff:` opt controlled, it will take 2 beats to slide from the
+current value to the new one. Therefore, when we use `control` you can
+hear the cutoff slide from 70 to 130. It creates an interesting dynamic
+feel to the sound. Now, try changing the `cutoff_slide:` time to a
+shorter value such as 0.5 or a longer value such as 4 to see how it
+changes the sound. Remember, you can slide any of the modifiable opts in
+exactly this way and each `_slide:` value can be totally different so
+you can have the cutoff sliding slowly, the amp sliding fast and the pan
+sliding somewhere in between if that's what you're looking to create...
+
+
+## Bringing it all together
+
+Let's look at a short example which demonstrates the power of
+controlling synths after they've been triggered. Notice that you can
+also slide FX just like synths although with a slightly different
+syntax. Check out section 7.2 of the built-in tutorial for more
+information on controlling FX.
+
+Copy the code into a spare buffer and take a listen. Don't stop there
+though - play around with the code. Change the slide times, change the
+notes, the synth, the FX and the sleep times and see if you can turn it
+into something completely different!
+
+
+```
+live_loop :moon_rise do
+  with_fx :echo, mix: 0, mix_slide: 8 do |fx|
+    control fx, mix: 1
+    notes = (scale :e3, :minor_pentatonic, num_octaves: 2).shuffle
+    sn = synth :prophet , sustain: 8, note: :e1, cutoff: 70, cutoff_slide: 8
+    control sn, cutoff: 130
+    sleep 2
+    32.times do
+      control sn, note: notes.tick, pan: rrand(-1, 1)
+      sleep 0.125
+    end
+  end
+end
+```
diff --git a/etc/doc/tutorial/en/A.11-beat-tracking.md b/etc/doc/tutorial/en/A.11-beat-tracking.md
new file mode 100644
index 0000000..55828ac
--- /dev/null
+++ b/etc/doc/tutorial/en/A.11-beat-tracking.md
@@ -0,0 +1,203 @@
+A.11 Tick Tock
+
+# Tracking the Beat
+
+Last month in this series we took a deep technical dive into the
+randomisation system underpinning Sonic Pi. We explored how we can use
+it to deterministically add new levels of dynamic control over our
+code. This month we're going to continue our technical dive and turn our
+attention to Sonic Pi's unique tick system. By the end of this article
+you'll be ticking your way through rhythms and riffs on your way to
+being a live coding DJ.
+
+
+# Beat Counting
+
+When making music we often want to do a different thing depending on
+which beat it is. Sonic Pi has a special beat counting system called
+`tick` to give you precise control over when a beat actually occurs and
+even supports multiple beats with their own tempos. 
+
+Let's have a play - to advance the beat we just need to call
+`tick`. Open up a fresh buffer, type in the following and hit Run:
+
+```
+puts tick #=> 0
+```
+
+This will return the current beat: `0`. Notice that even if you press
+the Run button a few times it will always return `0`. This is because
+each run starts a fresh beat counting from 0.  However, whilst the run
+is still active, we can advance the beat as many times as we want:
+
+```
+puts tick #=> 0
+puts tick #=> 1
+puts tick #=> 2
+```
+
+<breakout> Whenever you see the symbol `#=>` at the end of a line of
+code it means that that line will log the text on the
+right-hand-side. For example, `puts foo #=> 0` means the code `puts foo`
+prints `0` to the log at that point in the program.  </breakout>
+
+# Checking the Beat
+
+We've seen that `tick` does two things. It increments (adds one)
+and returns the current beat. Sometimes we just want to look at the
+current beat without having to increment it which we can do via `look`:
+
+``` 
+puts tick #=> 0
+puts tick #=> 1
+puts look #=> 1
+puts look #=> 1
+``` 
+
+In this code we tick the beat up twice and then call `look` twice. We'll
+see the following values in the log: `0`, `1`, `1`, `1`. The first two
+`tick`s returned `0`, then `1` as expected, then the two `look`s just
+returned the last beat value twice which was `1`. 
+
+
+# Rings
+
+So now we can advance the beat with `tick` and check the beat with
+`look`. What next? We need something to tick over. Sonic Pi uses rings
+for representing riffs, melodies and rhythms and the tick system has
+been specifically designed to work very closely with them. In fact,
+rings have their own dot version of `tick` which does two things. Firstly,
+it acts like a regular tick and increments the beat. Secondly it looks
+up the ring value using the beat as the index. Let's take a look:
+
+```
+puts (ring :a, :b, :c).tick #=> :a
+```
+
+`.tick` is a special dot version of `tick` which will return the first
+value of the ring `:a`. We can grab each of the values in the ring by
+calling `.tick` multiple times:
+
+```
+puts (ring :a, :b, :c).tick #=> :a
+puts (ring :a, :b, :c).tick #=> :b
+puts (ring :a, :b, :c).tick #=> :c
+puts (ring :a, :b, :c).tick #=> :a
+puts look                   #=> 3
+```
+
+Take a look at the log and you'll see `:a`, `:b`, `:c` and then `:a`
+again. Notice that `look` returns `3`. Calls to `.tick` act just like
+they are regular calls to `tick` - they increment the local beat.
+
+
+# A Live Loop Arpeggiator 
+
+The real power comes when you mix `tick` with rings and
+`live_loop`s. When combined we have all the tools we need to both build
+and understand a simple arpegiator. We need just four things:
+
+1. A ring containing the notes we want to loop over.
+2. A means of incrementing and obtaining the beat. 
+3. The ability to play a note based on the current beat.
+4. A loop structure to keep the arpegiator repeating.
+
+These concepts can all be found in the following code:
+
+```
+notes = (ring 57, 62, 55, 59, 64)
+
+live_loop :arp do
+  use_synth :dpulse
+  play notes.tick, release: 0.2
+  sleep 0.125
+end
+```
+
+Let's look at each of these lines. First we define our ring of notes
+which we'll continually play. We then create a `live_loop` called `:arp`
+which loops round for us. Each time round the `live_loop` we set our
+synth to `:dpulse` and then play the next note in our ring using
+`.tick`. Remember that this will increment our beat counter and use the
+latest beat value as an index into our notes ring. Finally, we wait for
+an eighth of a beat before looping round again.
+
+# Multiple Simultaneous Beats
+
+A really important thing to know is that `tick`s are local to the
+`live_loop`. This means that each `live_loop` has its own independent
+beat counter. This is much more powerful than having a global metronome
+and beat. Let's take a look at this in action:
+
+notes = (ring 57, 62, 55, 59, 64)
+
+with_fx :reverb do
+  live_loop :arp do
+    use_synth :dpulse
+    play notes.tick + 12, release: 0.1
+    sleep 0.125
+  end
+end
+
+live_loop :arp2 do
+  use_synth :dsaw
+  play notes.tick - 12, release: 0.2
+  sleep 0.75
+end
+
+# Clashing Beats
+
+A big cause of confusion with Sonic Pi's tick system is when people want
+to tick over multiple rings in the same `live_loop`:
+
+use_bpm 300
+use_synth :blade
+live_loop :foo do
+  play (ring :e1, :e2, :e3).tick
+  play (scale :e3, :minor_pentatonic).tick
+  sleep 1
+end
+
+Even though each `live_loop` has its own independent beat counter, we're
+calling `.tick` twice within the same `live_loop`. This means that the
+beat will be incremented twice every time round. This can produce some
+interesting polyrhythms but is often not what you want. There are two
+solutions to this problem. One option is to manually call `tick` at the
+start of the `live_loop` and then use `.look` to look up the current
+beat in each `live_loop`. The second solution is to pass a unique name
+to each call to `.tick` such as `.tick(:foo)`. Sonic Pi will then create
+and track a separate beat counter for each named tick you use. That way
+you can work with as many beats as you need! See the section on named
+ticks in 9.4 of the built-in tutorial for more information.
+
+# Bringing it all together
+
+Let's bring all this knowledge of `tick`s, `ring`s and `live_loop`s
+together for a final fun example. As usual, don't treat this as a
+finished piece. Start changing things and play around with it and see
+what you can turn it into. See you next time...
+
+
+use_bpm 240
+notes = (scale :e3, :minor_pentatonic).shuffle
+
+live_loop :foo do
+  use_synth :blade
+  with_fx :reverb, reps: 8, room: 1 do
+    tick
+    co = (line 70, 130, steps: 32).tick(:cutoff)
+    play (octs :e3, 3).look, cutoff: co, amp: 2
+    play notes.look, amp: 4
+    sleep 1
+  end
+end
+
+live_loop :bar do
+  tick
+  sample :bd_ada if (spread 1, 4).look
+  use_synth :tb303
+  co = (line 70, 130, steps: 16).look
+  r = (line 0.1, 0.5, steps: 64).mirror.look
+  play notes.look, release: r, cutoff: co
+  sleep 0.5
+end
diff --git a/etc/doc/tutorial/es/03.5-Partial-Samples.md b/etc/doc/tutorial/es/03.5-Partial-Samples.md
index 75eafb9..9903cb9 100644
--- a/etc/doc/tutorial/es/03.5-Partial-Samples.md
+++ b/etc/doc/tutorial/es/03.5-Partial-Samples.md
@@ -33,7 +33,7 @@ release con valores cortos:
 sample :loop_amen, rate: 2, attack: 0.01, sustain: 0, release: 0.35
 ```
 
-Sin embargo, ¿no sería mejor si no tuviésemos que comenzar por el principio
+Sin embargo, ¿No sería mejor si no tuviésemos que comenzar por el principio
 ó terminar por el fin..siempre?
 
 
@@ -48,17 +48,16 @@ del sampleo de amen break:
 sample :loop_amen, start: 0.5
 ```
 
-How about the last quarter of the sample:
+¿Qué tal escuchar el último cuarto del sample?:
 
 ```
 sample :loop_amen, start: 0.75
 ```
 
-## Choosing a finish point
+## Escogiendo punto de termino
 
-Similarly, it is possible to choose an arbitrary finish point in the
-sample as a value between 0 and 1. Let's finish the amen break half way
-through:
+Igualmente, es posible escoger un punto de termino arbitrario en el sample,
+con un valor entre 0 y 1. Vamos a terminar el amen break a la mitad:
 
 ```
 sample :loop_amen, finish: 0.5
@@ -67,13 +66,13 @@ sample :loop_amen, finish: 0.5
 ## Especificando el comienzo y el fin 
 
 Por supuesto que podemos combinar dos para tocar segmentos del archivo de
-audio arbitrariamente. ¿qué tal una pequeña sección en el medio?
+audio arbitrariamente. ¿Qué tal una pequeña sección en el medio?
 
 ```
 sample :loop_amen, start: 0.4, finish: 0.6
 ```
 
-¿qué pasa si elegimos comenzar en una posición después del final?
+¿Qué pasa si elegimos comenzar en una posición después del final?
 
 
 ```
diff --git a/etc/doc/tutorial/es/05-Programming-Structures.md b/etc/doc/tutorial/es/05-Programming-Structures.md
index 2dc23f4..535224c 100644
--- a/etc/doc/tutorial/es/05-Programming-Structures.md
+++ b/etc/doc/tutorial/es/05-Programming-Structures.md
@@ -4,8 +4,7 @@
 
 Ahora que has aprendido lo básico de crear sonidos con `play` y `sample`
 y crear ritmos y melodías simples con `sleep` en medio de los sonidos,
-podrías preguntarte ¿qué es lo que codificar puede ofrecerte?
-you...
+podrías preguntarte ¿Qué es lo que codificar puede ofrecerte?
 
 Bueno, estás a punto de ser sorprendido, porque resulta que herramientas
 básicas de estructuras de programación como bules, condicionales, 
diff --git a/etc/doc/tutorial/fr/01.2-Exploring-the-Interface.md b/etc/doc/tutorial/fr/01.2-Exploring-the-Interface.md
index 146f27e..d6b68d3 100644
--- a/etc/doc/tutorial/fr/01.2-Exploring-the-Interface.md
+++ b/etc/doc/tutorial/fr/01.2-Exploring-the-Interface.md
@@ -37,7 +37,7 @@ Ces boutons bleus vous donnent accès à l'information, à l'aide et aux
 préférences. Le bouton *Info* ouvre la fenêtre d'information qui contient
 de l'information sur Sonic Pi lui-même - le noyau de l'équipe, l'historique,
 les contributeurs, et la communauté. Le bouton *Help* active le système
-d'aide (*F*) et le bouton *Prefs* active la fenêtre des préférences
+d'aide (*G*) et le bouton *Prefs* active la fenêtre des préférences
 qui vous permet de contrôler quelques paramètres systèmes basiques.
 
 ## D. Éditeur de code
diff --git a/etc/doc/tutorial/fr/03.6-External-Samples.md b/etc/doc/tutorial/fr/03.6-External-Samples.md
index f37ceb3..4aaa160 100644
--- a/etc/doc/tutorial/fr/03.6-External-Samples.md
+++ b/etc/doc/tutorial/fr/03.6-External-Samples.md
@@ -27,30 +27,10 @@ triturer et expérimenter votre oeuvre. Bien entendu, ceci ne devrait
 pas vous faire arrêter d'utiliser vos propres échantillons, c'est 
 juste quelque chose à prendre en compte.
 
-<!-- ## Support Freesound -->
-
-<!-- Un moyen d'obtenir la faculté d'expérimenter de nouveaux sons tout en gardant-->
-<!-- la portabilité du code est d'utiliser le site [Freesound](http:freesound.org) -->
-<!-- http://freesound.org est un site web qui permet de mettre en ligne et partager -->
-<!-- des échantillons. Chaque échantillon téléchargé obtient un numéro spécial -->
-<!-- (comme un numéro de téléphone) que vous pouvez utiliser pour récupérer cet -->
-<!-- échantillon depuis Sonic Pi. Le seul inconvénient est que vous devez avoir -->
-<!-- une connexion internet pour que ça fonctionne. -->
-
-<!-- Si vous avez actuellement internet, essayez-le pour vous-même : -->
-
-<!-- ``` -->
-<!-- freesound 24787 -->
-<!-- ``` -->
-
-<!-- La première fois que vous ferez cela, vous entendrez un `:elec_beep` -->
-<!-- standard comme gardien de la place numéro 24787. Y -->
-
-
 ## Échantillons locaux
 
 
-Alors comment jouez-vous n'importe quel fichier WAV ou AIFF sur votre
+Alors comment jouez-vous n'importe quel fichier WAV, AIFF ou FLAC sur votre
 ordinateur ? Tout ce dont vous avez besoin est de passer le chemin de ce
 fichier à `sample` :
 
diff --git a/etc/doc/tutorial/fr/03.7-Sample-Packs.md b/etc/doc/tutorial/fr/03.7-Sample-Packs.md
new file mode 100644
index 0000000..3e4bfe7
--- /dev/null
+++ b/etc/doc/tutorial/fr/03.7-Sample-Packs.md
@@ -0,0 +1,231 @@
+3.7 Paquets de samples
+
+# Paquets de samples
+
+**Note: cette section du tutoriel couvre le sujet avancé de
+travailler avec des grands dossiers de vos propres samples. Ce sera le
+cas si vous avez téléchargé ou acheté vos propre paquets de samples et
+souhaitez les utiliser dans Sonic Pi.**
+
+**N'hésitez pas à sauter cette section si vous vous contentez des
+samples fournis dans Sonic Pi.**
+
+Quand on travaille avec de grands dossiers de samples externes il
+peut être ennuyeux de taper le chemin entier chaque fois qu'on veut
+déclencher un sample particulier.
+
+Par exemple, imaginons que vous avez le dossier suivant sur votre
+machine :
+
+```
+/path/to/my/samples/
+```
+
+Quand on regarde dans ce dossier on voit les samples suivants :
+
+* `100_A#_melody1.wav`
+* `100_A#_melody2.wav`
+* `100_A#_melody3.wav`
+* `120_A#_melody4.wav`
+* `120_Bb_guit1.wav`
+* `120_Bb_piano1.wav`
+
+Typiquement pour jouer le sample de piano on peut utiliser le chemin
+complet :
+
+```
+sample "/path/to/my/samples/120_Bb_piano1.wav"
+```
+
+Si on veut jouer le sample de guitare on peut aussi utiliser son
+chemin complet :
+
+```
+sample "/path/to/my/samples/120_Bb_guit.wav"
+```
+
+Cependant ces deux appels de samples nous forcent à *connaître* le nom
+de chacun des samples de notre dossier. Et si on voulait juste écouter
+chaque sample à son tour rapidement ?
+
+## Indexer les paquets de samples
+
+Si on veut jouer le premier sample d'un dossier on peut juste passer
+le nom du dossier à `sample` et l'index `0` comme suit :
+
+```
+sample "/path/to/my/samples/", 0
+```
+
+On peut même construire un raccourci vers notre chemin de dossier en
+utilisant une variable :
+
+```
+samps = "/path/to/my/samples/"
+sample samps, 0
+```
+
+Maintenant, si on veut jouer le deuxième sample de notre dossier, on
+peut juste incrémenter notre index :
+
+```
+samps = "/path/to/my/samples/"
+sample samps, 1
+```
+
+Remarquez qu'on n'a plus besoin de connaître le nom des samples du
+dossier : on doit juste connaître le dossier lui-même (ou avoir un
+raccourci vers lui). Si on demande un index qui est plus grand que le
+nombre de samples, il va juste boucler comme pour les anneaux. Ainsi,
+quel que soit le nombre qu'on utilise on a la garantie de récupérer un
+des samples de ce dossier.
+
+## Filtrer des paquets de samples
+
+D'habitude indexer suffit, mais parfois on a besoin de plus de
+puissance pour trier et organiser nos samples. Heureusement de nombreux
+paquets de samples ajoutent des informations utiles dans les noms de
+fichiers.  Jetons un autre oeil aux noms de fichier des samples de
+notre dossier :
+
+* `100_A#_melody1.wav`
+* `100_A#_melody2.wav`
+* `100_A#_melody3.wav`
+* `120_A#_melody4.wav`
+* `120_Bb_guit1.wav`
+* `120_Bb_piano1.wav`
+
+Remarquez que dans ces noms de fichier nous avons pas mal
+d'informations. On a le BPM du sample (nombre de battements par
+minute) au début. Donc le sample de piano est à 120 BPM et nos trois
+premières mélodies sont à 100 BPM. Nos noms de samples contiennent
+aussi la clef. Donc le sample de guitare est en Bb (si bémol) et les
+mélodies sont en A# (la dièse). Cette information est très utile pour
+mélanger ces samples avec le reste de notre code. Par exemple, on sait
+qu'on ne peut jouer le sample de piano que dans du code qui est à 120
+BPM et dans la clef de Bb.
+
+Il se trouve qu'on peut utiliser cette convention de nommage
+particulière de nos ensembles de samples dans le code pour nous aider
+à ne garder que ceux qu'on veut. Par exemple, si nous travaillons à
+120 BPM, on peut ne garder que les samples qui contiennent la chaîne
+`"120"` avec le code suivant :
+
+```
+samps = "/path/to/my/samples/"
+sample samps, "120"
+```
+
+Cela jouera le premier sample qui correspond. Si on veut le deuxième,
+on n'a qu'à utiliser l'index :
+
+```
+samps = "/path/to/my/samples/"
+sample samps, "120", 1
+```
+
+On peut même utiliser de multiples filtres en même temps. Par exemple,
+si on veut un sample dont le nom de fichier contient à la fois les
+sous-chaînes "120" et "A#", on peut le trouver facilement avec le code
+suivant :
+
+```
+samps = "/path/to/my/samples/"
+sample samps, "120", "A#"
+```
+
+Enfin, on a toujours la possibilité d'ajouter nos options habituelles
+lors de l'appel à `sample`:
+
+```
+samps = "/path/to/my/samples/"
+sample samps, "120", "Bb", 1, lpf: 70, amp: 2
+```
+
+## Sources
+
+Le système de pré-argument de filtre de samples comprend deux types
+d'information : les sources et les filtres. Les sources sont des
+informations utilisées pour créer la liste des candidats potentiels.
+Une source peut prendre deux formes :
+
+1. "/path/to/samples" : une chaîne représentant un chemin valide vers un dossier
+2. "/path/to/samples/foo.wav" : une chaîne représentant un chemin valide vers un sample
+
+La fonction `sample` va d'abord rassembler toutes les sources et les
+utiliser pour créer une grande liste de candidats. Cette liste est
+construite en ajoutant d'abord tous les chemins valides et puis en
+ajoutant tous les fichiers valides `.flac`, `.aif`, `.aiff`, `.wav`,
+et `.wave` contenus dans les dossiers.
+
+Par exemple, regardez le code suivant :
+
+```
+samps = "/path/to/my/samples/"
+samps2 = "/path/to/my/samples2/"
+path = "/path/to/my/samples3/foo.wav"
+
+sample samps, samps2, path, 0
+```
+
+Ici nous combinons les contenus des samples de deux dossiers en y
+ajoutant un sample en particulier. Si `"/path/to/my/samples/"` contient
+trois samples et `"/path/to/my/samples2/"` en contient douze, on
+aurait seize samples potentiels à indexer et filtrer (3 + 12 + 1).
+
+Par défaut, seuls les fichiers de samples d'un dossier sont rassemblés
+dans la liste de candidats. Parfois vous pourriez avoir un certain
+nombre de dossiers imbriqués dans lesquels vous aimeriez chercher et
+filtrer. Vous pouvez faire une recherche récursive dans tous les
+samples de tous les sous-dossiers d'un dossier en particulier en
+ajoutant `**` à la fin du chemin :
+
+```
+samps = "/path/to/nested/samples/**"
+sample samps, 0
+```
+
+Attention parce que chercher dans un très grand ensemble de dossiers
+peut prendre beaucoup de temps. Cela dit, le contenu des dossiers
+sources est mis en cache, donc le retard n'arrivera que la première
+fois.
+
+
+## Filtres
+
+Une fois qu'on a une liste de candidats on peut utiliser les types de
+filtres suivants pour réduire la sélection :
+
+* `"foo"` : les chaînes vont filtrer sur les occurrences de sous-chaîne dans le nom du fichier (moins le chemin du dossier et l'extension)
+* `/fo[oO]/` : les expressions régulières filtrent sur des motifs du nom du fichier (moins le chemin du dossier et l'extension)
+* `:foo` : les mots-clefs filtrent les candidats si le mot-clef correspond exactement au nom du fichier (moins le chemin du dossier et l'extension)
+* `lambda{ "foo" }` : les procédures sans argument seront appelées automatiquement et leur résultat sera traité comme une source ou un filtre
+* `lambda{|a| ... }` : les procédures avec un argument seront traitées comme un filtre de candidat ou une fonction génératrice. On lui passera la liste des candidats actuels et elle doit retourner une nouvelle liste de candidats (une liste de chemins valides vers des fichiers de samples)
+* `1` : Les nombres sélectionnent le candidat avec cet index (en bouclant comme un anneau si nécessaire)
+
+## Composites
+
+Enfin vous pouvez utiliser des listes partout où on peut placer une
+source ou un filtre. La liste sera automatiquement aplatie et son
+contenu sera traité comme des sources et filtres. Ainsi les appels
+suivants à `sample` sont sémantiquement équivalents :
+
+```
+sample "/path/to/dir", "100", "C#"
+sample ["/path/to/dir", "100", "C#"]
+sample "/path/to/dir", ["100", "C#"]
+sample ["/path/to/dir", ["100", ["C#"]]]
+```
+
+## Résumé
+
+C'était une section avancée pour les gens qui ont besoin de vraie
+puissance pour manipuler et utiliser des paquets de samples. Si la
+plupart de cette section n'avait pas trop de sens pour vous, ne vous
+inquiétez pas. Vous n'avez probablement pas encore besoin de cette
+fonctionnalité. Mais vous vous rendrez compte quand vous en aurez
+besoin et vous pourrez revenir et relire ceci quand vous commencerez à
+travailler avec de grands dossiers de samples.
+
+
+
diff --git a/etc/doc/tutorial/fr/06.2-FX-in-Practice.md b/etc/doc/tutorial/fr/06.2-FX-in-Practice.md
index 67b4984..742e16d 100644
--- a/etc/doc/tutorial/fr/06.2-FX-in-Practice.md
+++ b/etc/doc/tutorial/fr/06.2-FX-in-Practice.md
@@ -76,8 +76,26 @@ De cette façon, nous avons remonté le `with_fx` en dehors de la partie
 la plus intérieure de la boucle, et nous créons maintenant une 
 nouvelle réverbération toutes les 16 notes.
 
+C'est quelque chose que l'on fait si souvent que `with_fx` supporte
+une option pour faire exactement cela sans devoir écrire le bloc
+`16.times` :
+
+```
+loop do
+  with_fx :reverb, reps: 16 do
+    play 60, release: 0.1
+    sleep 0.125
+  end
+end
+```
+
+Les deux exemples `reps: 16` et `16.times do` se comporteront de la
+même manière. L'exemple avec `reps: 16` répète en fait le code dans le
+bloc `do/end` seize fois donc vous pouvez choisir l'un ou l'autre en
+fonction de vos préférences.
+
 Rappelez-vous, il n'y a pas de fautes, juste des possibilités. 
-Toutefois, chacune de ces approches donnera un son différent et aura 
-des caractéristiques de performance différentes. Donc, jouez et 
+Toutefois, certaines de ces approches donneront un son différent et
+auront des caractéristiques de performance différentes. Donc, jouez et
 utilisez l'approche qui sonne le mieux pour vous tout en restant dans 
 les contraintes de performance de votre plateforme.
diff --git a/etc/doc/tutorial/fr/08.5-Ring-Chains.md b/etc/doc/tutorial/fr/08.5-Ring-Chains.md
new file mode 100644
index 0000000..646bc4a
--- /dev/null
+++ b/etc/doc/tutorial/fr/08.5-Ring-Chains.md
@@ -0,0 +1,86 @@
+8.5 Chaînes d'anneaux
+
+En plus des constructeurs comme `range` et `spread`, une autre façon
+de créer de nouveaux anneaux est de manipuler des anneaux existants.
+
+## Commandes de chaîne
+
+Pour explorer ceci, prenons un anneau simple :
+
+```
+(ring 10, 20, 30, 40, 50)
+```
+
+Et si on voulait son inverse ? Eh bien on utiliserait la commande
+de chaîne `.reverse` pour prendre l'anneau et l'inverser :
+
+```
+(ring 10, 20, 30, 40, 50).reverse  #=> (ring 50, 40, 30, 20, 10)
+```
+
+Et si on voulait les trois premières valeurs de l'anneau ?
+
+```
+(ring 10, 20, 30, 40, 50).take(3)  #=> (ring 10, 20, 30)
+```
+
+Enfin, et si on voulait mélanger l'anneau ?
+
+```
+(ring 10, 20, 30, 40, 50).shuffle  #=> (ring 40, 30, 10, 50, 20)
+```
+
+## Chaînes multiples
+
+C'est déjà une manière puissante de créer de nouveaux anneaux. Ceci
+dit la *vraie* puissance vient quand on enchaîne quelques unes de ces
+commandes à la suite.
+
+Et si on mélangeait l'anneau, on lâchait un élément puis on en prenait
+les trois suivants ?
+
+Regardons ceci par étapes :
+
+1. `(ring 10, 20, 30, 40, 50)` - notre anneau initial
+2. `(ring 10, 20, 30, 40, 50).shuffle` - mélange - `(ring 40, 30, 10, 50, 20)`
+3. `(ring 10, 20, 30, 40, 50).shuffle.drop(1)` - en lâche un - `(ring 30, 10, 50, 20)`
+4. `(ring 10, 20, 30, 40, 50).shuffle.drop(1).take(3)` - en prend trois - `(ring 30, 10, 50)`
+
+Vous voyez comme on peut créer une longue chaîne de ces méthodes juste
+*en les collant à la suite*. On peut les combiner dans l'ordre qu'on
+veut, ce qui crée une manière extrêmement riche et puissante de
+générer de nouveaux anneaux à partir d'anneaux existants.
+
+## Immutabilité
+
+Ces anneaux ont une propriété puissante et importante. Ils sont
+immutables, ce qui veut dire qu'ils ne peuvent pas changer. Cela veut
+dire que les méthodes de chaîne décrites dans cette section *ne
+changent pas les anneaux*, elles *créent plutôt de nouveaux anneaux*.
+Cela veut dire que vous êtes libres de partager des anneaux entre
+fils et de les chaîner dans un fil en sachant que vous n'affecterez
+aucun autre fil qui utilise le même anneau.
+
+## Méthodes de chaîne disponibles
+
+Voici une liste des méthodes de chaîne disponibles :
+
+* `.reverse` - retourne une version inversée de l'anneau
+* `.sort`    - crée une version triée de l'anneau
+* `.shuffle` - crée une version mélangée de l'anneau
+* `.pick(3)` - retourne un anneau avec le résultat de trois appels à `.choose`
+* `.pick`    - similaire à `.pick(3)` mais la taille correspond à la taille de l'anneau initial
+* `.take(5)` - retourne un nouvel anneau contenant uniquement les cinq premiers éléments
+* `.drop(3)` - retourne un nouvel anneau avec tout sauf les trois premiers éléments
+* `.butlast` - retourne un nouvel anneau sans le dernier élément
+* `.drop_last(3)` - retourne un nouvel anneau sans les trois derniers éléments
+* `.take_last(6)`- retourne un nouvel anneau avec les six derniers éléments seulement
+* `.stretch(2)` - répète chaque élément dans l'anneau deux fois
+* `.repeat(3)` - répète l'anneau entier trois fois
+* `.mirror` - ajoute l'anneau à une version inversée de lui-même
+* `.reflect` - comme mirror mais sans dupliquer la valeur du milieu
+
+Evidemment, les méthodes de chaîne qui prennent des nombres peuvent
+prendre d'autres nombres aussi ! N'hésitez donc pas à appeler
+`.drop(5)` au lieu de `.drop(3)` si vous voulez lâcher les cinq
+premiers éléments.
diff --git a/etc/doc/tutorial/fr/09.4-Ticking.md b/etc/doc/tutorial/fr/09.4-Ticking.md
index fbdee2e..c6c068a 100644
--- a/etc/doc/tutorial/fr/09.4-Ticking.md
+++ b/etc/doc/tutorial/fr/09.4-Ticking.md
@@ -12,10 +12,24 @@ variations de timbre, etc. etc.
 
 Sonic Pi fournit un outil *très* pratique pour travailler avec des anneaux 
 ("rings") à l'intérieur des `live_loop`s. Il s'agit du système d'avance 
-automatique ("tick"). Il vous fournit la capacité de *parcourir des anneaux*.
+automatique ("tick"). Dans la section sur les anneaux on parlait d'un
+compteur qui augmente constamment, comme un nombre courant de
+battement. "Tick" implémente justement cette idée.  Il vous fournit
+la capacité de *parcourir des anneaux*.
 Regardons un exemple :
 
 ```
+counter = 0
+live_loop :arp do
+  play (scale :e3, :minor_pentatonic)[counter], release: 0.1
+  counter += 1
+  sleep 0.125
+end
+```
+
+C'est l'équivalent de :
+
+```
 live_loop :arp do
   play (scale :e3, :minor_pentatonic).tick, release: 0.1
   sleep 0.125
diff --git a/etc/doc/tutorial/fr/10.2-Shortcut-Cheatsheet.md b/etc/doc/tutorial/fr/10.2-Shortcut-Cheatsheet.md
index 5f67414..19fae8a 100644
--- a/etc/doc/tutorial/fr/10.2-Shortcut-Cheatsheet.md
+++ b/etc/doc/tutorial/fr/10.2-Shortcut-Cheatsheet.md
@@ -44,7 +44,9 @@ est la touche *Alt* pour Windows/Linux et *Cmd* sur Mac) :
 ## Manipulation du texte
 
 * `M-m` - aligne et indente tout le texte
-* `Tab` - aligne et indente la ligne courante ou la sélection (ou la liste complète)
+* `Tab` - aligne et indente la ligne courante ou la sélection (ou sélectionne l'auto-complétion)
+* `C-l` - Centre l'éditeur
+* `M-/` - Commente / décommente la ligne courante ou la sélection
 * `C-t` - Intervertit les caractères sélectionnés 
 * `M-u` - Convertit le mot suivant (ou la sélection) en majuscule.  
 * `M-l` - Convertit le mot suivant (ou la sélection) en minuscule.
diff --git a/etc/doc/tutorial/fr/A-Articles.md b/etc/doc/tutorial/fr/A-Articles.md
new file mode 100644
index 0000000..79e82ca
--- /dev/null
+++ b/etc/doc/tutorial/fr/A-Articles.md
@@ -0,0 +1,28 @@
+A Appendice A - Articles MagPi
+
+# Articles MagPi
+
+L'appendice A rassemble tous les articles Sonic Pi écrits pour le
+magazine MagPi.
+
+## Plongez vous dans les sujets
+
+Ces articles ne sont pas destinés à être lus dans un ordre particulier
+et contiennent beaucoup de choses qui sont aussi dans le tutoriel.
+Plutôt que d'essayer de vous apprendre tout Sonic Pi, chacun se
+focalise plutôt sur un aspect particulier de Sonic Pi et le couvre
+d'une manière amusante et accessible.
+
+## Lisez MagPi
+
+Vous les trouverez avec leur présentation très professionnelle dans
+les PDFs gratuits en téléchargement ici :
+https://www.raspberrypi.org/magpi/
+
+## Suggérez un sujet
+
+Si vous ne trouvez pas de sujet qui vous intéresse parmi ceux couverts
+dans ces articles, pourquoi ne pas en suggérer un ? La manière la plus
+simple de faire cela est de tweeter votre suggestion à
+[@Sonic_Pi](http://twitter.com/sonic_pi). On ne sait jamais, votre
+suggestion sera peut-être le sujet du prochain article !
diff --git a/etc/doc/tutorial/fr/A.01-tips.md b/etc/doc/tutorial/fr/A.01-tips.md
new file mode 100644
index 0000000..1494aef
--- /dev/null
+++ b/etc/doc/tutorial/fr/A.01-tips.md
@@ -0,0 +1,183 @@
+A.1 Conseils pour Sonic Pi
+
+# Les cinq meilleurs conseils
+
+## 1. Il n'y a pas d'erreur
+
+La plus importante leçon à apprendre avec Sonic Pi c'est qu'il n'y a
+vraiment pas d'erreur. La meilleure façon d'apprendre c'est juste
+d'essayer, essayer, et essayer. Essayez beaucoup de choses
+différentes, ne vous inquiétez pas de savoir si votre code sonne bien
+ou pas et commencez par expérimenter avec le plus de synthés, notes,
+effets et options possibles. Vous découvrirez beaucoup de choses qui
+vous feront rire parce qu'elles ne sonnent pas bien du tout et aussi
+quelques joyaux qui sonnent magnifiquement bien. Débarrassez-vous
+ensuite de ce que vous n'aimez pas et gardez les choses qui vous
+plaisent. Plus vous vous permettrez de faire des erreurs et plus vous
+apprendrez et découvrirez votre son de code personnel.
+
+## 2. Utilisez les effets
+
+Disons que vous maîtrisez déjà les bases de Sonic Pi pour créer des
+sons avec `sample` et `play`. Qu'est-ce qui vient ensuite ? Savez-vous
+que Sonic Pi supporte plus de 27 effets studio pour changer le son de
+votre code ? Les effets sont comme des filtres pour images dans les
+programmes de dessin, mais à la place de rendre l'image floue ou noir
+et blanc, on peut ajouter de la reverb, de la distorsion ou de l'écho
+au son. On peut voir ça comme brancher le câble d'une guitare dans une
+pédale d'effet puis dans un ampli. Heureusement Sonic Pi rend
+l'utilisation d'effets très simple et n'a pas besoin de câble. Tout
+ce dont vous avez besoin c'est de choisir à quelle section de votre
+code ajouter l'effet puis de l'entourer avec le code de l'effet.
+Prenons un exemple. Disons que vous avez le code suivant :
+
+
+    sample :loop_garzul
+     
+    16.times do
+      sample :bd_haus
+      sleep 0.5
+    end
+
+
+Si vous voulez ajouter un effet au sample `:loop_garzul`, il suffit de
+le mettre dans un bloc `with_fx` comme ceci :
+
+
+    with_fx :flanger do
+      sample :loop_garzul
+    end
+     
+    16.times do
+      sample :bd_haus
+      sleep 0.5
+    end
+
+
+Maintenant si voulez ajouter un effet au tambour basse, enveloppez-le
+aussi dans un `with_fx` :
+
+
+    with_fx :flanger do
+      sample :loop_garzul
+    end
+     
+    with_fx :echo do
+      16.times do
+        sample :bd_haus
+        sleep 0.5
+      end
+    end
+
+
+Rappelez-vous, vous pouvez entourer *n'importe quel* code dans
+`with_fx` et tous les sons créés passeront dans cet effet.
+
+
+## 3. Paramétrez vos synthés
+
+Pour découvrir vraiment votre son de code vous voudrez savoir comment
+modifier et contrôler les synthés et effets. Par exemple, vous voudrez
+peut-être changer la durée d'une note, ajouter plus de reverb, ou
+changer la durée entre échos. Heureusement, Sonic Pi vous donne un
+niveau de contrôle incroyable pour faire cela avec des paramètres
+optionnels ou opts pour faire court. Regardons ça rapidement. Copiez
+ce code dans un buffer et exécutez-le :
+
+    sample :guit_em9
+
+
+Oh, un joli son de guitare ! Commençons à jouer un peu avec. Et si on
+changeait sa fréquence ?
+
+    sample :guit_em9, rate: 0.5
+
+
+Hé, qu'est-ce que ce `rate: 0.5` que j'ai ajouté à la fin ? C'est ce
+qu'on appelle une opt. Tous les synthés et samples de Sonic Pi les
+supportent et il y en a beaucoup avec lesquels on peut jouer. Ils
+sont disponibles pour les effets aussi. Essayez ceci :
+
+
+    with_fx :flanger, feedback: 0.6 do
+      sample :guit_em9
+    end
+
+
+Maintenant essayez d'augmenter ce feedback à 1 pour entendre des sons
+fous ! Lisez la documentation pour des détails complets sur les
+nombreuses opts disponibles.
+
+
+## 5. Coder de manière interactive
+
+La meilleure manière d'expérimenter rapidement et d'explorer Sonic Pi
+est de coder de manière interactive. Cela vous permet de partir d'un
+peu de code et de le changer de manière continue pendant qu'il est en
+train de s'exécuter. Par exemple, si vous ne savez pas ce que le
+paramètre cutoff fait à un sample, jouez avec. Essayons ! Copiez ce
+code dans un de vos buffers Sonic Pi :
+
+
+    live_loop :experiment do
+      sample :loop_amen, cutoff: 70
+      sleep 1.75
+    end
+
+
+Maintenant cliquez sur 'Run' et vous entendrez un rhythme de batterie
+un peu étouffé. Maintenant changez la valeur de `cutoff:` en `80` et
+cliquez à nouveau sur 'Run'. Entendez-vous la différence ? Essayez
+`90`, `100`, `110`...
+
+Quand vous aurez pris la main à utiliser des `live_loop`, vous ne
+pourrez plus vous en passer. Quand je donne un concert de live coding
+je m'appuie autant sur `live_loop` qu'un batteur sur ses baguettes.
+Pour plus d'informations à propos du live coding regardez la section
+9 du tutoriel inclus dans Sonic Pi.
+
+## 5. Surfez sur les suites aléatoires
+
+Enfin, une chose que j'adore faire est de tricher en faisant que Sonic
+Pi compose des choses pour moi. Une manière géniale de faire ça est
+d'utiliser l'aléatoire. Cela peut paraître compliqué mais ça ne l'est
+pas du tout. Regardons. Copiez ceci dans un buffer :
+
+
+    live_loop :rand_surfer do
+      use_synth :dsaw
+      notes = (scale :e2, :minor_pentatonic, num_octaves: 2)
+      16.times do
+        play notes.choose, release: 0.1, cutoff: rrand(70, 120)
+        sleep 0.125
+      end
+    end
+
+
+Maintenant, quand vous jouez cela, vous entendrez une suite continue
+de notes aléatoires de la gamme `:e2 :minor_pentatonic` jouée avec le
+synthé `:dsaw`. "Attendez, attendez ! Ce n'est pas une mélodie", vous
+entends-je crier ! Eh bien, voici la première partie du tour de magie.
+Chaque fois que l'on recommence le `live_loop` on peut dire à Sonic Pi
+de fixer la suite aléatoire à un point connu. C'est un peu comme
+voyager dans le temps. Essayons ceci : ajoutez la ligne
+`use_random_seed 1` au `live_loop` :
+
+    live_loop :rand_surfer do
+      use_random_seed 1
+      use_synth :dsaw
+      notes = (scale :e2, :minor_pentatonic, num_octaves: 2)
+      16.times do
+        play notes.choose, release: 0.1, cutoff: rrand(70, 120)
+        sleep 0.125
+      end
+    end
+    
+Maintenant, chaque fois que la `live_loop` boucle, la suite aléatoire
+est réinitialisée. Cela veut dire qu'elle contient exactement les même
+16 notes à chaque fois. Et voilà ! Une mélodie de composée. Et
+maintenant voici la partie excitante. Changez la valeur de `1` en un
+autre nombre. Par exemple `4923`. Ouaou, une autre mélodie ! Donc, en
+changeant juste un nombre (la graine aléatoire), on peut explorer
+autant de combinaisons mélodiques qu'on peut imaginer ! C'est ça la
+magie du code.
diff --git a/etc/doc/tutorial/fr/A.02-live-coding.md b/etc/doc/tutorial/fr/A.02-live-coding.md
new file mode 100644
index 0000000..f0b70d8
--- /dev/null
+++ b/etc/doc/tutorial/fr/A.02-live-coding.md
@@ -0,0 +1,184 @@
+A.2 Live Coding
+
+# Live Coding
+
+Les rayons lasers perçaient à travers les bouffées de fumée et les
+baffles transmettaient des basses profondes dans les corps de la foule.
+L'atmosphère était remplie d'un mélange de synthés et de danse. Il y
+avait pourtant quelque chose d'étrange dans cette boîte de nuit.
+Du texte futuriste était projeté au dessus de la cabine du DJ,
+bougeant, dansant, clignotant. Ce n'étaient pas de belles
+visualisations, c'était juste une projection de Sonic Pi tournant sur
+un Raspberry Pi. La personne dans la cabine de DJ n'était pas en train
+de tourner des disques, elle écrivait, éditait et évaluait du code. En
+direct. C'est ça le Live Coding.
+
+![Sam Aaron Live Coding](../images/tutorial/articles/A.02-live-coding/sam-aaron-live-coding.png)
+
+Cela peut sonner comme une histoire tirée par les cheveux dans une
+boîte de nuit futuriste mais coder de la musique comme cela est une
+tendance qui se développe et qu'on appelle souvent Live Coding
+(programmation interactive) (http://toplap.org). Une des directions
+récentes que cette approche de la musique a prise est l'Algorave
+(http://algorave.com) : des événements où des artistes comme moi
+codent de la musique pour que les gens dansent. Cependant vous n'avez
+pas besoin d'une boîte de nuit pour coder en live : avec Sonic Pi
+version 2.6 et plus vous pouvez le faire dans n'importe quel endroit
+où vous pouvez prendre votre Raspberry Pi et un casque ou des
+haut-parleurs. Quand vous aurez atteint la fin de cet article, vous
+saurez programmez vos rythmes et les modifier en direct. Où vous irez
+ensuite ne sera limité que par votre imagination.
+
+## Boucle interactive
+
+La clef de la programmation interactive est la maîtrise de la
+`live_loop`. En voici une :
+
+    live_loop :beats do
+      sample :bd_haus
+      sleep 0.5
+    end
+
+Il y a quatre ingrédients principaux dans une `live_loop`. La première
+est son nom. Notre `live_loop` s'appelle ici `:beats`. Vous pouvez
+donner le nom que vous voulez à votre `live_loop`. Défoulez-vous.
+Soyez créatifs. J'utilise souvent des noms qui communiquent à
+l'audience qu'est-ce que la musique va faire. Le deuxième ingrédient
+est le mot `do` qui marque où la `live_loop` commence. Le troisième
+est le mot `end` qui marque où la `live_loop` finit, et enfin il y a
+le corps de la `live_loop` qui décrit ce que la boucle va répéter :
+c'est la partie entre `do` et `end`. Dans ce cas on joue en boucle un
+sample de tambour basse et on attend un demi temps. Cela produit un
+beau rythme régulier de basse. Allez, copiez-le dans un buffer vide de
+Sonic Pi et cliquez sur 'Run'. Boum, boum, boum !
+
+## Redéfinir à la volée
+
+OK, qu'est-ce qu'elle a de si spécial, cette `live_loop` ? Jusqu'ici
+on dirait que c'est juste une boucle ! Eh bien, la beauté des
+`live_loop`s c'est qu'on peut les redéfinir à la volée. Cela veut
+dire que pendant qu'elles sont en train de tourner, on peut changer ce
+qu'elles font. C'est le secret de la programmation interactive avec
+Sonic Pi. Essayons :
+
+    live_loop :choral_drone do
+      sample :ambi_choir, rate: 0.4
+      sleep 1
+    end
+
+Maintenant cliquez le bouton 'Run' ou tapez 'alt-r'. Vous entendez
+maintenant de beaux sons de chorale. Ensuite, alors qu'il est encore
+en train de jouer, changer la fréquence de `0.4` en `0.38`. Cliquez à
+nouveau sur 'Run'. Ouaou ! Vous avez entendu le choeur changer de
+note ? Ecrivez à nouveau `0.4` pour revenir comme avant. Puis `0.2`,
+puis `0.19`, puis à nouveau `0.4`. Voyez-vous comment juste changer un
+paramètre à la volée vous donne un réel contrôle sur la musique ?
+Maintenant jouez vous-même avec la fréquence, choisissez vos propres
+valeurs. Essayez des nombres négatifs, de très petits nombres et de
+grands nombres. Amusez-vous !
+
+## Il est important de dormir
+
+Une des leçons les plus importantes avec les `live_loop` c'est
+qu'elles ont besoin de se reposer. Prenons par exemple cette
+`live_loop` :
+
+    live_loop :infinite_impossibilities do
+      sample :ambi_choir
+    end
+
+Si vous essayez d'exécuter ce code, vous verrez immédiatement que
+Sonic Pi se plaint que la `live_loop` n'a pas dormi. C'est un
+mécanisme de sécurité qui se met en place. Prenons un moment pour
+penser à ce que ce code demande à l'ordinateur de faire. C'est cela,
+on demande à l'ordinateur de jouer un nombre infini de samples de
+chorale dans un temps nul. Sans le mécanisme de sécurité le pauvre
+ordinateur essaierait de faire ça et exploserait. Souvenez-vous en
+bien : vos `live_loop`s doivent contenir un appel à `sleep`.
+
+
+## Combiner des sons
+
+La musique est pleine de choses qui arrivent en même temps. La
+batterie en même temps que la basse, en même temps que du chant, en
+même temps que des guitares... En informatique on appelle ça la
+concurrence et Sonic Pi nous donne une manière étonnamment simple de
+jouer des choses en même temps. Il suffit d'utiliser plus qu'une
+`live_loop` !
+
+    live_loop :beats do
+      sample :bd_tek
+      with_fx :echo, phase: 0.125, mix: 0.4 do
+        sample  :drum_cymbal_soft, sustain: 0, release: 0.1
+        sleep 0.5
+      end
+    end
+  
+    live_loop :bass do
+      use_synth :tb303
+      synth :tb303, note: :e1, release: 4, cutoff: 120, cutoff_attack: 1
+      sleep 4
+    end
+
+Ici nous avons deux `live_loop`s, une qui tourne rapidement pour faire
+un rythme et une qui boucle lentement pour faire un son fou de basse.
+
+Une des choses intéressantes quand on utilise plusieurs `live_loop`s
+c'est que chacune gère son propre temps. Cela veut dire qu'il est très
+facile de créer des structures polyrythmiques intéressantes et même de
+jouer avec la phase dans le style de Steve Reich. Par exemple :
+
+    # La phase piano de Steve Reich
+  
+    notes = (ring :E4, :Fs4, :B4, :Cs5, :D5, :Fs4, :E4, :Cs5, :B4, :Fs4, :D5, :Cs5)
+  
+    live_loop :slow do
+      play notes.tick, release: 0.1
+      sleep 0.3
+    end
+  
+    live_loop :faster do
+      play notes.tick, release: 0.1
+      sleep 0.295
+    end
+
+
+## Rassemblons tout
+
+Dans chacun de ces tutoriels, nous finirons avec un exemple qui montre
+un nouveau morceau de musique qui utilise toutes les idées
+introduites. Lisez ce code et essayez d'imaginer ce qu'il fait.
+Ensuite, copiez-le dans un buffer frais de Sonic Pi et cliquez 'Run'
+pour entendre comment il sonne. Enfin changez un des nombres ou
+commentez / décommentez des parties. Voyez si vous pouvez prendre ça
+comme point de départ d'une nouvelle performance, et surtout
+amusez-vous ! A la prochaine...
+
+    with_fx :reverb, room: 1 do
+      live_loop :time do
+        synth :prophet, release: 8, note: :e1, cutoff: 90, amp: 3
+        sleep 8
+      end
+    end
+  
+    live_loop :machine do
+      sample :loop_garzul, rate: 0.5, finish: 0.25
+      sample :loop_industrial, beat_stretch: 4, amp: 1
+      sleep 4
+    end
+  
+    live_loop :kik do
+      sample :bd_haus, amp: 2
+      sleep 0.5
+    end
+  
+    with_fx :echo do
+      live_loop :vortex do
+        # use_random_seed 800
+        notes = (scale :e3, :minor_pentatonic, num_octaves: 3)
+        16.times do
+          play notes.choose, release: 0.1, amp: 1.5
+          sleep 0.125
+        end
+      end
+    end
diff --git a/etc/doc/tutorial/fr/A.03-coded-beats.md b/etc/doc/tutorial/fr/A.03-coded-beats.md
new file mode 100644
index 0000000..fe9a868
--- /dev/null
+++ b/etc/doc/tutorial/fr/A.03-coded-beats.md
@@ -0,0 +1,191 @@
+A.3 Rythmes codés
+
+# Rythmes codés
+
+Une des évolutions techniques les plus excitantes et disruptives dans
+la musique moderne a été l'invention des samplers. C'étaient des
+boîtes qui permettaient d'enregistrer n'importe quels sons dedans et
+de les manipuler et jouer de nombreuses manières intéressantes. Par
+exemple, on pouvait prendre un vieux disque, trouver un solo de
+batterie (ou un break), l'enregistrer dans le sampler et ensuite le
+jouer deux fois moins vite pour créer la fondation de vos derniers
+rythmes. C'est ainsi que la musique hip-hop est née et aujourd'hui il
+est presque impossible de trouver de la musique électronique qui
+n'incorpore pas de samples. Utiliser des samples est une très bonne
+manière d'introduire facilement des éléments nouveaux et intéressants
+dans vos performances de live coding.
+
+Comment pouvez-vous vous procurer un sampler ? Eh bien, vous en avez
+déjà un : c'est votre Raspberry Pi ! L'application de live coding
+Sonic Pi comprend un sampler très puissant. Jouons avec !
+
+## Le break Amen
+
+Un des samples de break de batterie les plus classiques et
+reconnaissables s'appelle le break Amen. Il a été joué pour la
+première fois en 1969 dans la chanson "Amen Brother" des Winstons dans
+un break de batterie. Cependant c'est quand il a été découvert par
+les premiers musiciens de hip-hop dans les années 80 et utilisé dans
+des samplers qu'il a commencé à être très utilisé dans des styles
+aussi variés que le drum and bass, le breakbeat, la techno hardcore et
+le breakcore.
+
+
+Je suis sûr que vous êtes ravis d'entendre qu'il est aussi inclus dans
+Sonic Pi. Choisissez un buffer vide et copiez-y ce code :
+ 
+    sample :loop_amen
+
+Cliquez sur *Run* et boum ! Vous ententez l'un des breaks de batterie
+les plus influents de l'histoire de la musique dance. Ceci dit, ce
+sample n'est pas célèbre pour être joué juste une fois, il est fait
+pour être joué en boucle.
+
+
+## Etirer des rythmes
+
+Jouons le break Amen en boucle en utilisant notre vieille amie la
+`live_loop`, introduite dans le tutoriel du mois dernier :
+
+    live_loop :amen_break do
+      sample :loop_amen
+      sleep 2
+    end
+
+OK, ça boucle, mais il y a une pause ennuyeuse à chaque fois. C'est
+parce qu'on a demandé d'attendre `2` temps et avec le nombre par défaut
+de 60 BPM (battements par minute), le sample `:loop_amen` ne dure que
+`1.753` temps. Nous avons donc un silence de `2 - 1.753 = 0.247`
+temps. Même s'il est court, c'est notable.
+
+Pour corriger ce problème on peut utiliser l'option `beat_stretch`
+pour demander à Sonic Pi d'étirer (ou rétrécir) le sample pour
+correspondre au temps spécifié.
+
+[Breakout box start] Les fonctions `sample` et `synth` de Sonic Pi
+vous donnent beaucoup de contrôle via des paramètres optionnels comme
+`amp:`, `cutoff:` et `release:`. Cela dit le terme `paramètre
+optionnel` est très long à dire donc on les appelle juste *opts* pour
+rester simple.
+[Breakout box end]
+
+    live_loop :amen_break do
+      sample :loop_amen, beat_stretch: 2
+      sleep 2
+    end  
+
+Maintenant on peut danser ! Quoique, peut-être qu'on veut l'accélérer
+ou le ralentir en fonction de l'ambiance.
+
+## Jouer avec le temps
+
+OK, et si on voulait changer de style pour faire du hip hop old school
+ou du breakcore ? Une manière simple de faire ça est de jouer avec le
+temps : ou en d'autres mots jouer avec le tempo. C'est très facile
+avec Sonic Pi : il suffit d'appeler `use_bpm` dans votre boucle
+interactive :
+
+    live_loop :amen_break do
+      use_bpm 30
+      sample :loop_amen, beat_stretch: 2
+      sleep 2
+    end 
+
+Pendant que vous rappez sur ces rythmes lents, remarquez que nous
+avons toujours un repos de 2 et que notre BPM vaut 30, mais tout est
+bien synchronisé. L'option `beat_stretch` marche avec le BPM courant
+pour s'assurer que tout fonctionne bien.
+
+Maintenant voici la partie amusante. Alors que la boucle est en train
+de tourner, changez le `30` dans la ligne `use_bpm 30` en `50`. Oh,
+tout est devenu plus rapide, mais toujours *synchro* ! Essayez d'aller
+plus vite : jusque 80, jusque 120, ou même, soyons fous, 200 !
+
+
+## Filtrer
+
+Maintenant qu'on peut jouer des samples en boucle de manière
+interactive, regardons les options les plus amusantes proposées par le
+synthé `sample`. La première est le `cutoff:` qui contrôle le filtre
+de coupure du sampler. Par défaut il est désactivé mais on peut
+facilement l'activer :
+
+
+    live_loop :amen_break do
+      use_bpm 50
+      sample :loop_amen, beat_stretch: 2, cutoff: 70
+      sleep 2
+    end  
+
+
+Allez-y, changez la valeur de l'option `cutoff:`. Par exemple
+montez-la à 100, cliquez sur *Run* et attendez la prochaine boucle
+pour entendre la différence dans le son. Remarquez que des valeurs
+basses comme 50 sonnent plus doux et bas et que des hautes valeurs
+comme 100 ou 120 sonnent plus plein et râpeux. C'est parce que
+l'option `cutoff:` va couper les parties haute-fréquence du son tout
+comme une tondeuse coupe le haut de la pelouse. L'option `cutoff:`
+est comme le réglage de la longueur : cela détermine combien il reste
+d'herbe.
+
+
+## Couper
+
+Un autre super outil avec lequel on peut jouer est l'effet slicer.
+Il va couper le son en tranches. Entourez la ligne de `sample` avec le
+code de l'effet ainsi :
+
+    live_loop :amen_break do
+      use_bpm 50
+      with_fx :slicer, phase: 0.25, wave: 0, mix: 1 do
+        sample :loop_amen, beat_stretch: 2, cutoff: 100
+      end
+      sleep 2
+    end
+
+Remarquez comme le son bondit un peu plus de haut en bas. (Vous pouvez
+entendre le son original sans l'effet en changeant l'option `mix:` en
+`0`.) Maintenant essayez de modifier la valeur de l'option `phase:`.
+C'est la fréquence (en battements) de l'effet de coupe. Une plus
+petite valeur comme `0.5` va couper plus rapidement et une plus grande
+valeur comme `0.5` va couper plus lentement. Remarquez que si on
+divise ou multiplie successivement par deux l'option `phase:` cela
+sonne généralement bien. Enfin, choisissez une valeur pour l'option
+`wave:` entre 0, 1 et 2 et écoutez comment le son change. Ce sont
+différentes formes d'onde. 0 est une onde scie (elle commence fort et
+finit en fondu), 1 est une onde carrée (commence et finit fort) et 2
+est une onde en triangle (commence en fondu, finit en fondu).
+
+## Rassemblons tout
+
+Enfin, revenons dans le temps et revisitons la jeune scène de drum and
+bass de Bristol avec l'exemple de ce mois. Ne vous inquiétez pas trop
+de tout ce que cela signifie, tapez le, cliquez sur Run, puis
+commencez à coder interactivement en changement les valeurs des
+options et voyez où cela vous amène. Partagez ce que vous créez ! A la
+prochaine...
+
+    use_bpm 100
+  
+    live_loop :amen_break do
+      p = [0.125, 0.25, 0.5].choose
+      with_fx :slicer, phase: p, wave: 0, mix: rrand(0.7, 1) do
+        r = [1, 1, 1, -1].choose
+        sample :loop_amen, beat_stretch: 2, rate: r, amp: 2
+      end
+      sleep 2
+    end
+  
+    live_loop :bass_drum do
+      sample :bd_haus, cutoff: 70, amp: 1.5
+      sleep 0.5
+    end
+  
+    live_loop :landing do
+      bass_line = (knit :e1, 3, [:c1, :c2].choose, 1)
+      with_fx :slicer, phase: [0.25, 0.5].choose, invert_wave: 1, wave: 0 do
+        s = synth :square, note: bass_line.tick, sustain: 4, cutoff: 60
+        control s, cutoff_slide: 4, cutoff: 120
+      end
+      sleep 4
+    end
diff --git a/etc/doc/tutorial/fr/A.04-synth-riffs.md b/etc/doc/tutorial/fr/A.04-synth-riffs.md
new file mode 100644
index 0000000..c5ed4ac
--- /dev/null
+++ b/etc/doc/tutorial/fr/A.04-synth-riffs.md
@@ -0,0 +1,201 @@
+A.4 Riffs de synthés
+
+# Riffs de synthés
+
+Que ce soit la dérive hantée d'oscillateurs grondants ou le coup de
+poing désaccordé des ondes scies perçant à travers le mix, le synthé
+principal joue un rôle essentiel dans chaque piste électronique. Dans
+l'édition du mois dernier de cette série de tutoriels nous avons
+couvert comment coder nos rythmes. Dans ce tutoriel nous verrons
+comment coder les trois composants principaux d'un riff de synthé : le
+timbre, la mélodie et le rythme.
+
+OK, allumez votre Raspberry Pi, ouvrez Sonic Pi (version 2.6 ou plus)
+et faisons du bruit !
+
+
+## Les possibilités du timbre
+
+Une partie essentielle de n'importe quel riff de synthé est de jouer
+avec le timbre des sons. On peut contrôler le timbre dans Sonic Pi de
+deux manières : en choisissant différents synthés pour un changement
+dramatique et en définissant les diverses options des synthés pour des
+modifications plus subtiles. On peut aussi utiliser des effets, mais
+ce sera pour un autre tutoriel...
+
+Créons une boucle interactive simple où l'on modifiera en continu le
+synthé courant :
+
+    live_loop :timbre do
+      use_synth (ring :tb303, :blade, :prophet, :saw, :beep, :tri).tick
+      play :e2, attack: 0, release: 0.5, cutoff: 100
+      sleep 0.5
+    end
+
+Regardez ce code. On parcourt (avec `tick`) juste un anneau de noms de
+synthés (on boucle sur chacun d'eux à leur tour puis on répéte la
+liste encore et encore). On passe ce nom de synthé à la fonction (fn)
+`use_synth`, ce qui changera le synthé courant de la `live_loop`. On
+joue aussi la note `:e2` (E (ou Mi) à la deuxième octave), avec un
+temps de relâche de 0.5 battement (une demi seconde au BPM par défaut
+de 60) et avec l'option `:cutoff` fixée à 100.
+
+Vous entendez que les différents synthés ont des sons très différents
+même s'ils jouent tous la même note. Maintenant expérimentez et jouez.
+Changez le temps de relâche en lui donnant des valeurs plus grandes et
+plus petites. Par exemple, changez les options `attack:` et `release:`
+pour voir comme des temps différents de fondu d'entrée et de sortie
+ont un grand effet sur le son. Enfin changez l'option `cutoff:` pour
+voir comment différentes valeurs de coupure ont une influence massive
+sur le timbre (des valeurs entre 60 et 130 sont bonnes). Voyez combien
+de sons vous pouvez créer juste en changeant quelques valeurs. Une
+fois que vous maîtrisez cela, allez dans l'onglet Synthés dans le
+système d'aide pour voir la liste entière des synthés et des options
+que chacun d'eux supporte pour voir l'étendue du pouvoir que vous avez
+au bouts de vos doigts de codeur.
+
+## Timbre
+
+Le timbre est juste un mot savant pour décrire comment sonne un son.
+Si vous jouez la même note avec différents instruments comme un
+violon, une guitare, ou un piano, la fréquence (si elle sonne haut ou
+bas) sera la même, mais la qualité du son sera différente. La qualité
+du son, ce qui fait qu'on peut différencier un piano et une guitare,
+c'est le timbre.
+
+## Composition mélodique
+
+Un autre aspect important de notre synthé principal est le choix de
+notes que l'on veut jouer. Si vous avez déjà une bonne idée, alors
+vous pouvez juste créer un anneau avec vos notes et les parcourir :
+
+    live_loop :riff do
+      use_synth :prophet
+      riff = (ring :e3, :e3, :r, :g3, :r, :r, :r, :a3)
+      play riff.tick, release: 0.5, cutoff: 80
+      sleep 0.25
+    end
+
+Ici nous avons défini une mélodie avec un anneau qui inclut des notes
+comme `:e3` et des silences représentés par `:r`. On utilise ensuite
+`.tick` pour jouer chaque note à son tour, ce qui nous donne un riff
+qui se répète.
+
+## Mélodie automatique
+
+Ce n'est pas toujours facile d'inventer un riff sympa. C'est souvent
+plus simple de demander à Sonic Pi une sélection de riffs aléatoires
+et de choisir celui que l'on préfère. Pour faire cela on doit combiner
+trois choses : des anneaux, de l'aléatoire et des graines aléatoires.
+Regardons un exemple :
+
+    live_loop :random_riff do
+      use_synth :dsaw
+      use_random_seed 3
+      notes = (scale :e3, :minor_pentatonic).shuffle
+      play notes.tick, release: 0.25, cutoff: 80
+      sleep 0.25
+    end
+
+Plusieurs choses se passent : regardons les une par une. On commence
+par spécifier la graine aléatoire 3. Qu'est-ce que cela signifie ? Eh
+bien, c'est utile parce que quand on définit la graine, on sait
+prédire quelle sera la prochaine valeur aléatoire : ce sera la même
+que la dernière fois qu'on a choisi la graine 3 ! Une autre chose
+utile à savoir est que mélanger un anneau de notes fonctionne de la
+même façon. Dans l'exemple ci-dessus c'est comme si on demandait le
+'troisième mélange' dans la liste standard de mélanges : il sera le
+même chaque fois comme on définit toujours la graine aléatoire à la
+même valeur avant le mélange. Enfin on parcourt juste nos notes
+mélangées pour jouer le riff.
+
+Maintenant, c'est ici qu'on commence à s'amuser. Si on change la
+valeur de la graine aléatoire, par exemple en 3000, on a un mélange
+entièrement différent des notes. Ainsi il est très facile d'explorer
+de nouvelles mélodies. Il suffit de choisir la liste de notes que l'on
+veut mélanger (les gammes sont un très bon endroit pour commencer) et
+ensuite de choisir la graine avec laquelle on veut les mélanger. Si on
+n'aime pas la mélodie, on peut juste changer une de ces deux choses et
+essayer à nouveau. Répétez jusqu'à ce que vous aimiez ce que vous
+entendez !
+
+
+## Pseudo aléatoire
+
+L'aléatoire de Sonic Pi n'est pas vraiment aléatoire, on appelle ça du
+pseudo aléatoire. Imaginez que vous jetez un dé 100 fois et que vous
+écrivez le résultat de chaque jet sur une feuille de papier. Sonic Pi
+a l'équivalent de cette liste de résultats qu'il utilise quand on
+demande une valeur aléatoire. Au lieu de jeter un vrai dé, il prend
+juste la valeur suivante dans la liste. Définir la graine aléatoire
+revient à sauter à un endroit particulier de cette liste.
+
+## Trouver votre rythme
+
+Un autre aspect important de notre riff est le rythme : quand jouer
+une note et quand ne pas le faire. Comme on a vu, on peut utiliser
+`:r` dans nos anneaux pour insérer des silences. Une autre manière
+puissante consiste à utiliser des 'spreads' que l'on couvrira dans un
+futur tutoriel. Aujourd'hui nous allons utiliser l'aléatoire pour nous
+aider à trouver notre rythme. Au lieu de jouer toutes les notes on
+peut utiliser une condition pour jouer une note avec une probabilité
+donnée. Voyons cela :
+
+    live_loop :random_riff do
+      use_synth :dsaw
+      use_random_seed 30
+      notes = (scale :e3, :minor_pentatonic).shuffle
+      16.times do
+        play notes.tick, release: 0.2, cutoff: 90 if one_in(2)
+        sleep 0.125
+      end
+    end
+
+Une fonction très utile à connaître est `one_in` qui nous donne une
+valeur `true` ou `false` (vrai ou faux) avec la probabilité spécifiée.
+Ici nous utilisons une valeur de 2 donc en moyenne un appel sur deux à
+`one_in` retournera `true`. En d'autres termes, elle retournera `true`
+50% du temps. Si on choisit des valeurs plus grandes elle retournera
+`false` plus souvent ce qui mettra plus d'espace dans notre riff.
+
+Remarquez qu'on a introduit un peu d'itération ici avec `16.times`.
+C'est parce qu'on ne veut redéfinir notre valeur de graine aléatoire
+que toutes les 16 notes pour que notre rythme se répète toutes les 16
+fois. Cela n'affecte pas le mélange comme il est toujours fait juste
+après avoir défini la graine. On peut utiliser la longueur d'itération
+pour modifier la longueur de notre riff. Essayez de changer le 16 en 8
+ou même en 4 ou 3 et voyez comment cela affecte le rythme du riff.
+
+## Rassemblons tout
+
+OK, combinons tout ce que nous avons appris dans un dernier exemple.
+A la prochaine !
+
+    live_loop :random_riff do
+      #  uncomment to bring in:
+      #  synth :blade, note: :e4, release: 4, cutoff: 100, amp: 1.5
+      use_synth :dsaw
+      use_random_seed 43
+      notes = (scale :e3, :minor_pentatonic, num_octaves: 2).shuffle.take(8)
+      8.times do
+        play notes.tick, release: rand(0.5), cutoff: rrand(60, 130) if one_in(2)
+        sleep 0.125
+      end
+    end
+     
+    live_loop :drums do
+      use_random_seed 500
+      16.times do
+        sample :bd_haus, rate: 2, cutoff: 110 if rand < 0.35
+        sleep 0.125
+      end
+    end
+     
+    live_loop :bd do
+      sample :bd_haus, cutoff: 100, amp: 3
+      sleep 0.5
+    end
+
+
+
+
diff --git a/etc/doc/tutorial/fr/A.05-acid-bass.md b/etc/doc/tutorial/fr/A.05-acid-bass.md
new file mode 100644
index 0000000..11b7f08
--- /dev/null
+++ b/etc/doc/tutorial/fr/A.05-acid-bass.md
@@ -0,0 +1,183 @@
+A.5 Basse acide
+
+# Basse acide
+
+Il est impossible de regarder l'histoire de la musique de danse
+électronique sans voir l'énorme impact du petit synthétiseur Roland
+TB-303. C'est la sauce secrète derrière le son original de basse
+acide. On entend ces riffs de basse classiques crissants et
+pataugeants depuis la jeune scène de house de Chicago jusqu'à des
+artistes plus récents comme Plastikman, Squarepusher et Aphex Twin.
+
+Il est intéressant de savoir que Roland n'avait pas l'intention que le
+TB-303 soit utilisé dans de la musique pour danser. Il a été créé à
+l'origine comme une aide de travail pour les guitaristes. Ils ont
+imaginé que les gens les programmeraient pour jouer des lignes de
+basse d'accompagnement. Malheureusement il y avait un certain nombre
+de problèmes : ils étaient un peu compliqués à programmer, ne
+sonnaient pas particulièrement bien comme remplacement de guitare
+basse et ils étaient assez chers. Décidant d'arrêter les frais, Roland
+a cessé d'en fabriquer après en avoir vendu 10'000 unités et après un
+certain nombres d'années à rester sur les étagères des guitaristes,
+ils se retrouvés dans les vitrines des magasins d'occasion. C'est
+pauvres TB-303 rejetés attendaient d'être découverts par une nouvelle
+génération d'expérimentateurs qui ont commencé à les utiliser dans des
+manières que Roland n'avait pas imaginées pour créer des sons fous.
+La house acide était née.
+
+
+Même si se procurer un TB-303 original n'est pas si facile vous serez
+heureux d'apprendre que vous pouvez transformer votre Raspberry Pi en
+TB-303 en utilisant la puissance de Sonic Pi. Lancez Sonic Pi, copiez
+ce code dans un buffer vide et cliquez sur 'Run' :
+
+    use_synth :tb303
+    play :e1
+    
+Instant acid bass! Let's play around...
+
+# Presse cette basse
+
+Commençons par construire un arpège interactif pour rendre les choses
+amusantes. Dans le dernier tutoriel nous avons vu comment des mélodies
+peuvent être juste un anneau de notes qu'on joue les unes après les
+autres, en répétant quand on arrive à la fin. Créons une boucle
+interactive qui fait cela :
+
+    use_synth :tb303
+    live_loop :squelch do
+      n = (ring :e1, :e2, :e3).tick
+      play n, release: 0.125, cutoff: 100, res: 0.8, wave: 0
+      sleep 0.125
+    end
+    
+Regardons chaque ligne.
+
+1. A la première ligne choisit `tb303` comme synthé par défaut avec la
+  fonction `use_synth`.
+
+2. A la deuxième ligne on crée une boucle interactive du nom de
+   `:squelch` qui va juste boucler encore et encore.
+
+3. A la troisième ligne on crée notre mélodie : un anneau de notes (E
+   ou Mi aux octaves 1, 2 et 3) et on le parcourt simplement avec
+   `.tick`. On définit `n` pour représenter la note courante de la
+   mélodie. Le signe égal veut juste dire qu'on affecte la valeur à
+   droite au nom à gauche. Cette valeur sera différente à chaque
+   boucle. La première fois `n` aura la valeur `:e1`. La deuxième fois
+   ce sera `:e2`, puis `:e3`, puis de nouveau `:e1`, en bouclant à
+   l'infini.
+   
+4. A la ligne quatre on joue notre synthé `:tb303`. On lui passe
+   quelques options intéressantes : `release:`, `cutoff:`, `res:` et
+   `wave:` que l'on décrira plus bas.
+
+5. La ligne cinq est notre `sleep` : on demande à la boucle
+   interactive de boucler toutes les `0.125`secondes ou 8 fois par
+   seconde au BPM par défaut de 60
+   
+6. La ligne six est la fin de la boucle interactive. Le mot `end`
+   indique juste à Sonic Pi où se termine la boucle interactive.
+
+
+Alors que vous êtes encore en train de vous familiariser avec ce qui
+se passe, tapez le code ci-dessous et cliquez sur le bouton 'Run'.
+Vous devriez entendre le `:tb303` entrer en action. C'est ici le coeur
+de l'action : commençons à programmer de manière interactive.
+
+Pendant que la boucle tourne, changez l'option `cutoff:` en `110`.
+Puis cliquez à nouveau sur le bouton 'Run'. Vous devriez entendre le
+son devenir un peu plus dur et sec. Montez à `120` et cliquez sur
+'Run'. Puis `130`. Ecoutez comme les valeurs hautes de coupure rendent
+le son plus perçant et intense. Enfin, descendez à `80` quand vous
+sentirez que vous voulez un peu de repos. Puis répétez ça autant que
+vous voulez. Pas d'inquiétude, je serai toujours là...
+
+Une autre option qui vaut le coup d'être utilisée est `res:`. Elle
+contrôle le niveau de résonance du filtre. Une haute résonance est
+caractéristique des sons de basse acide. Nous avons pour le moment une
+`res:` de `0.8`. Essayez de la monter à `0.85`, puis `0.9`, et enfin
+`0.95`. Un cutoff de `110` ou plus peut permettre d'entendre plus
+facilement les différences. Enfin défoulez-vous et montez jusque
+`0.999` pour avoir des sons déments. Avec une `res` aussi haute vous
+entendez le filtre de coupure résonner tant qu'il commence à faire ses
+propres sons.
+
+Enfin pour avoir un grand impact sur le timbre essayez de mettre
+l'option `wave:` à `1`. C'est le choix de l'oscillateur source. La
+valeur par défaut est `0` qui est une onde en dents de scie.
+
+Bien sûr, essayez différentes mélodies en changeant les notes dans
+l'anneau ou même en choisissant des notes de gammes ou d'accords.
+Amusez-vous bien avec votre premier synthé de basse acide.
+
+# Déconstruisons le TB-303
+
+Le design du TB-303 original était en fait assez simple. Comme vous
+pouvez le voir sur le diagramme suivant il n'y a que quatre parties
+principales.
+
+![TB-303 Design](../images/tutorial/articles/A.05-acid-bass/tb303-design.png)
+
+En premier on a l'onde oscillatoire : les ingrédients de base du son.
+Dans ce cas nous avons une onde carrée. Ensuite on a l'enveloppe
+d'amplitude de l'oscillateur qui contrôle l'amplitude de l'onde carrée
+au cours du temps. On peut y accéder dans Sonic Pi avec les options 
+`attack:`, `decay:`, `sustain:` et `release:` ainsi que leur niveau
+correspondant. Pour plus d'informations lisez la Section 2.4 'Durée
+avec enveloppes' dans le tutoriel inclus dans Sonic Pi. On passe
+ensuite notre onde carrée enveloppée dans un filtre passe bas
+résonant. Cela coupe les hautes fréquences et a un bel effet de
+résonance. Et c'est ici que ça devient amusant. La valeur de coupure
+de ce filtre est aussi contrôlée par sa propre enveloppe ! Cela veut
+dire que nous avons un contrôle incroyable sur le timbre du son en
+jouant avec ces deux enveloppes. Jetons-y un oeil :
+
+  
+    use_synth :tb303
+    with_fx :reverb, room: 1 do
+      live_loop :space_scanner do
+        play :e1, cutoff: 100, release: 7, attack: 1, cutoff_attack: 4, cutoff_release: 4
+        sleep 8
+      end
+    end
+    
+Pour chaque option standard d'enveloppe, il y a une option `cutoff_`
+équivalente dans le synthé `:tb303`. Donc, pour changer le temps
+d'attaque de la coupure on peut utiliser l'option `:cutoff_attack`.
+Copiez le code ci-dessus dans un buffer vide et cliquez sur 'Run'.
+Vous entendrez un son fou entrer et sortir. Maintenant essayez de
+jouer avec. Essayez de changer la durée de `cutoff_attack:` en `1`
+puis en `0.5`. Puis essayez `8`.
+
+Remarquez que j'ai passé tout cela à travers un effet `:reverb` pour
+plus d'atmosphère : essayez d'autres effets pour voir ce qui marche !
+
+## Rassemblons tout
+
+Enfin voici un morceau que j'ai composé en utilisant les idées de ce
+tutoriel. Copiez le dans un buffer vide, écoutez un peu, puis
+commencez à programmer interactivement vos changements. Voyez quels
+sons fous vous pouvez faire avec ! A la prochaine...
+
+    use_synth :tb303
+    use_debug false
+     
+    with_fx :reverb, room: 0.8 do
+      live_loop :space_scanner do
+        with_fx :slicer, phase: 0.25, amp: 1.5 do
+          co = (line 70, 130, steps: 8).tick
+          play :e1, cutoff: co, release: 7, attack: 1, cutoff_attack: 4, cutoff_release: 4
+          sleep 8
+        end
+      end
+     
+      live_loop :squelch do
+        use_random_seed 3000
+        16.times do
+          n = (ring :e1, :e2, :e3).tick
+          play n, release: 0.125, cutoff: rrand(70, 130), res: 0.9, wave: 1, amp: 0.8
+          sleep 0.125
+        end
+      end
+    end
diff --git a/etc/doc/tutorial/fr/A.06-minecraft.md b/etc/doc/tutorial/fr/A.06-minecraft.md
new file mode 100644
index 0000000..dc0185f
--- /dev/null
+++ b/etc/doc/tutorial/fr/A.06-minecraft.md
@@ -0,0 +1,203 @@
+A.6 Minecraft musical
+
+# Minecraft musical
+
+
+
+Bonjour et bienvenue à nouveau ! Dans les tutoriels précédents nous
+nous somes concentrés exclusivement sur les possibilités mnusicales de
+Sonic Pi, en transformant votre Raspberry Pi en instrument de musique
+prêt à l'emploi. Jusqu'ici nous avons appris comment :
+
+* Programmer de manière interactive, en changeant les sons à la volée,
+* Coder des rythmes imposants,
+* Générer des mélodies de synthé puissantes
+* recréer le fameux son TB-303 de basse acide
+
+Il y a tellement plus à vous montrer, et nous l'explorerons dans de
+futures éditions. Cependant, ce mois-ci, nous allons regarder une
+chose que Sonic Pi sait faire et que vous n'avez probablement pas
+remarquée : contrôler Minecraft.
+
+
+# Bonjour, monde de Minecraft
+
+OK, commençons. Démarrez votre Raspberry Pi, lancez Minecraft Pi et
+créez un nouveau monde. Maintenant démarrez Sonic Pi et déplacez vos
+fenêtres de manière à pouvoir voir Sonic Pi et Minecraft Pi en même
+temps.
+
+Dans un buffer disponible tapez ce qui suit :
+
+    mc_message "Hello Minecraft from Sonic Pi!"
+    
+Maintenant cliquez sur 'Run'. Boum ! Votre message est apparu dans
+Minecraft ! C'était facile, non ? Maintenant arrêtez un moment de lire
+ceci et jouez un peu avec vos propres messages. Amusez-vous !
+
+![Screen 0](../images/tutorial/articles/A.06-minecraft/Musical-Minecraft-0-small.png)
+
+# Téléportation sonique
+
+Explorons un peu. L'option standard est de saisir la souris et le
+clavier et de commencer à se promener. Ca marche, mais c'est assez
+lent et ennuyeux. Ce serait beaucoup mieux si on avait une sorte de
+machine de téléportation. Eh bien, grâce à Sonic Pi, on en a une.
+Essayez ceci :
+
+    mc_teleport 80, 40, 100
+    
+Oh ! On est monté bien haut. Si vous n'étiez pas en mode volant vous
+avez du retomber jusqu'au sol. Si vous double-tapez Espace pour entrer
+en mode volant et vous téléportez à nouveau, vous resterez en l'air
+à l'endroit où vous vous êtes déplacés.
+
+Maintenant, qu'est-ce que ces nombres signifient ? Nous avons trois
+nombres qui décrivent les coordonnées de l'endroit du monde où vous
+voulez vous déplacer. On donne à chacun de ces nombres un nom : x, y
+et z.
+
+* x - à quelle distance vers la gauche ou la droite (80 dans notre exemple)
+* y - à quelle hauteur on veut être (40 dans notre exemple)
+* z - à quelle distance vers l'avant ou l'arrière (100 dans notre exemple)
+
+En choisissant différentes valeurs pour x, y, et z, on peut se
+téléporter *n'importe où* dans notre monde. Essayez ! Choisissez
+différents nombres et regardez où vous vous retrouvez. Si l'écran
+devient noir c'est que vous vous êtes téléportés sous terre ou dans
+une montagne. Choisissez juste une valeur de y plus grande pour vous
+retrouver au-dessus de la terre. Continuez à explorer jusqu'à ce que
+vous trouviez un endroit qui vous plaise...
+
+En utilisant les idées vues jusqu'ici, construisons un téléporteur
+sonique qui fera un son amusant de téléportation quand il nous fera
+voyager à travers le monde de Minecraft :
+
+    mc_message "Preparing to teleport...."
+    sample :ambi_lunar_land, rate: -1
+    sleep 1
+    mc_message "3"
+    sleep 1
+    mc_message "2"
+    sleep 1
+    mc_message "1"
+    sleep 1
+    mc_teleport 90, 20, 10
+    mc_message "Whoooosh!"
+    
+![Screen 1](../images/tutorial/articles/A.06-minecraft/Musical-Minecraft-1-small.png)
+
+# Blocs magiques
+
+Maintenant que vous avez trouvé un endroit sympathique, commençons à
+construire. Vous pourriez faire comme vous en avez l'habitude et
+commencer à cliquer furieusement la souris pour placer des blocs sous
+le curseur. Ou vous pourriez utiliser la magie de Sonic Pi. Essayez
+ceci :
+
+
+    x, y, z = mc_location
+    mc_set_block :melon, x, y + 5, z
+
+Maintenant regardez vers le haut ! Il y a un melon dans le ciel !
+Prenez un moment pour regarder le code. Qu'est-ce qu'on a fait ? Sur
+la première ligne on a attrapé l'emplacement actuel de Steve dans les
+variables x, y et z. Elles correspondent aux coordonnées décrites
+ci-dessus. Nous utilisons ces coordonnées dans la fonction
+`mc_set_block` qui va placer le bloc de votre choix aux coordonnées
+spécifiées. Pour placer quelque chose plus haut dans le ciel on doit
+juste augmenter la valeur de y, c'est pour ça qu'on lui ajoute 5.
+Faisons un chemin de melons :
+
+    live_loop :melon_trail do
+      x, y, z = mc_location
+      mc_set_block :melon, x, y-1, z
+      sleep 0.125
+    end
+
+Maintenant sautez dans Minecraft, assurez-vous d'être en mode volant
+(tapez deux fois sur Espace sinon) et volez autour du monde. Regardez
+derrière vous pour voir un beau chemin de blocs de melon ! Voyez quels
+dessins tordus vous pouvez faire dans le ciel.
+
+# Programmer Minecraft de manière interactive
+
+Ceux d'entre vous qui ont suivi ce tutoriel pendant les derniers mois
+doivent être bien étonnés. Le chemin de melons est assez cool, mais la
+partie la plus excitante de l'exemple précédent est qu'on peut
+utiliser la `live_loop` avec Minecraft ! Pour ceux qui ne savent pas,
+la `live_loop` est la faculté magique et spéciale de Sonic Pi qu'aucun
+autre langage de programmation ne possède. Elle vous permet d'exécuter
+des boucles multiples en même temps et vous permet de les modifier
+pendant qu'elles tournent. Elles sont incroyablement puissantes et
+amusantes. J'utilise les `live_loop`s pour jouer de la musique dans
+des boîtes de nuit avec Sonic Pi : les DJs utilisent des disques et
+moi j'utilise des `live_loop`s :-) Cependant aujourd'hui nous allons
+programmer de manière interactive de la musique et Minecraft.
+
+
+
+Commençons. Exécutez le code ci-dessus et commencez à faire votre
+chemin de melons de nouveau. Maintenant, sans arrêter le code, changez
+simplement `:melon` en `:brick` et cliquez sur `Run`. Eh voilà, vous
+construisez maintenant un chemin de briques. C'était simple, non ?
+Un peu de musique pour accompagner ça ? Facile. Essayez ceci :
+
+    live_loop :bass_trail do
+      tick
+      x, y, z = mc_location
+      b = (ring :melon, :brick, :glass).look
+      mc_set_block b, x, y -1, z
+      note = (ring :e1, :e2, :e3).look
+      use_synth :tb303
+      play note, release: 0.1, cutoff: 70
+      sleep 0.125
+    end
+    
+Maintenant pendant que ça joue commencez à modifier le code. Changez
+les types de bloc : essayez `:water`, `:grass` ou votre type de bloc
+préféré. Aussi, essayez de changer la valeur de coupure de `70` à `80`
+puis jusque `100`. N'est-ce pas amusant ?
+
+## Rassemblons tout
+
+![Screen 2](../images/tutorial/articles/A.06-minecraft/Musical-Minecraft-2-small.png)
+
+Rassemblons tout ce que nous avons vu jusqu'ici avec un peu de magie
+en plus. Combinons notre faculté de téléportation avec placement de
+blocs et la musique pour faire une vidéo de musique Minecraft. Ne vous
+inquiétez pas si vous ne comprenez pas tout, tapez juste le code et
+jouez ensuite à modifier quelques-unes des valeurs pendant qu'il
+s'exécute. Amusez-vous bien et à la prochaine...
+    
+
+    live_loop :note_blocks do
+      mc_message "This is Sonic Minecraft"
+      with_fx :reverb do
+        with_fx :echo, phase: 0.125, reps: 32 do
+          tick
+          x = (range 30, 90, step: 0.1).look
+          y = 20
+          z = -10
+          mc_teleport x, y, z
+          ns = (scale :e3, :minor_pentatonic)
+          n = ns.shuffle.choose
+          bs = (knit :glass, 3, :sand, 1)
+          b = bs.look
+          synth :beep, note: n, release: 0.1
+          mc_set_block b, x+20, n-60+y, z+10
+          mc_set_block b, x+20, n-60+y, z-10
+          sleep 0.25
+        end
+      end
+    end
+    
+    live_loop :beats do
+      sample :bd_haus, cutoff: 100
+      sleep 0.5
+    end
+          
+
+
+
+
diff --git a/etc/doc/tutorial/fr/A.07-bizet.md b/etc/doc/tutorial/fr/A.07-bizet.md
new file mode 100644
index 0000000..693c73a
--- /dev/null
+++ b/etc/doc/tutorial/fr/A.07-bizet.md
@@ -0,0 +1,183 @@
+A.7 Battements de Bizet
+
+# Battements de Bizet
+
+Après notre briève excursion dans le monde fantastique de la
+programmation Minecraft avec Sonic Pi le mois dernier, penchons nous
+sur la musique à nouveau. Aujourd'hui nous allons amener un morceau
+classique de danse d'opéra droit dans le 21e siècle en utilisant
+la puissance fantastique du code.
+
+# Scandaleux et perturbateur
+
+Sautons dans une machine à remonter le temps jusqu'en 1875. Un
+compositeur nommé Bizet avait juste terminé son dernier opéra :
+Carmen. Malheureusement comme beaucoup de nouveaux morceaux excitants
+et perturbateurs les gens ne l'aimaient pas du tout au début parce
+qu'il était trop scandaleux et différent. Malheureusement Bizet est
+mort dix ans avant que l'opéra ne connaisse un grand succès
+international et ne devienne un des opéras les plus connus et les plus
+fréquemment interprétés de tous les temps. Par sympathie pour cette
+tragédie nous allons prendre un des thèmes principaux de Carmen et
+nous allons le convertir dans un format moderne de musique qui est
+aussi trop scandaleux et différent pour la plupart des gens de notre
+époque : la musique codée interactive !
+
+# La Habanera décryptée
+
+Essayez de programmer un opéra entier de manière interactive serait un
+peu ambitieux pour ce tutoriel, concentrons nous sur une des ses plus
+célèbres parties : la ligne de basse de la Habanera :
+
+![Habanera Riff](../images/tutorial/articles/A.07-bizet/habanera.png)
+
+Cela peut vous sembler complètement illisible si vous n'avez pas
+étudié la notation musicale. Cependant, en tant que programmeurs nous
+voyons la notation musicale comme juste une autre forme de code, elle
+représente juste des instructions pour un musicien au lieu d'un
+ordinateur.
+
+# Notes
+
+Les notes sont arrangées de gauche à droite comme les mots dans ce
+magasine mais elles ont aussi différentes hauteurs. *La hauteur sur la
+partition représente la hauteur d'une note.* Plus une note est haut
+sur la partition, plus sa hauteur est grande.
+
+Dans Sonic Pi nous savons déjà comment changer la hauteur d'une note :
+on peut utiliser des grands ou petits nombres comme `play 75` et
+`play 80` ou on peut utiliser les noms des notes : `play :E` et
+`play :F`. Heureusement chacune des positions verticales sur la
+partition représente un nom de note en particulier. Jetez un oeil à
+cette table de correspondance bien pratique :
+
+![Notes](../images/tutorial/articles/A.07-bizet/notes.png)
+
+# Silences
+
+Les partitions sont une sorte de code extrêmement riche et expressif
+capable de communiquer de nombreuses choses. Cela ne devrait donc pas
+nous surprendre que les partitions peuvent non seulement nous dire
+quelles notes jouer mais aussi quand *ne pas* jouer de note. En
+programmation c'est à peu près l'équivalent de l'idée de `nil` ou
+`null` : l'absence de valeur. En d'autres mots ne pas jouer une note
+c'est comme une absence de note.
+
+Si vous regardez de près la partition vous verrez que c'est en fait
+une combinaison de ronds noirs avec des barres qui représentent les
+notes à jouer et des choses ondulées qui représentent les silences.
+Heureusement, Sonic Pi a une notation très pratique pour un silence :
+`:r`, donc si on exécute `play :r` il jouera en fait un silence ! On
+pourrait aussi écrire `play :rest`, `play nil` ou `play false` qui
+sont autant de manières équivalentes de représenter un silence.
+
+# Rythme
+
+Enfin il y a une dernière chose à apprendre à décoder dans la
+notation : la notion du temps. Dans la notation originale vous verrez
+que les notes sont liées par des traits épais. La deuxième note a
+deux de ces traits ce qui veut dire qu'elle dure un 16e de temps. Les
+autres notes ont un seul trait ce qui veut dire qu'elles durent un 8e
+de temps. Le silence a aussi deux traits ondulés ce qui veut dire
+qu'il représente aussi un 16e de temps.
+
+Quand on essaie de décoder et d'explorer de nouvelles choses un truc
+très pratique est de rendre tout le plus semblable possible pour
+essayer de voir des relations ou modèles. Par exemple quand on réécrit
+notre notation uniquement en double-croches on peut voir que notre
+notation devient une séquence agréable de notes et de silences.
+
+
+![Habanera Riff 2](../images/tutorial/articles/A.07-bizet/habanera2.png)
+
+# Re-programmer la Habanera
+
+Nous sommes maintenant prêts a traduire cette ligne de basse dans
+Sonic Pi. Encodons ces notes et silences dans un anneau :
+
+    (ring :d, :r, :r, :a, :f5, :r, :a, :r)
+    
+Voyons ce que ça donne. Jetons ça dans une boucle interactive et
+parcourons-là :
+
+    live_loop :habanera do
+      play (ring :d, :r, :r, :a, :f5, :r, :a, :r).tick
+      sleep 0.25
+    end
+    
+Fabuleux, cette mélodie qu'on reconnait immédiatement prend vie dans
+vos haut-parleurs. On a fait des efforts pour en arriver là, mais ça
+valait la peine, bravo !
+    
+# Synthés de mauvaise humeur
+
+Maintenant qu'on a la ligne de basse, essayons de re-créer une partie
+de l'ambiance de la scène d'opéra. Un synthé à essayer est `:blade`
+qui est un synthé style années 80. Essayons le avec la note de départ
+`:d` passée dans un slicer et de la reverb :
+
+    live_loop :habanera do
+      use_synth :fm
+      use_transpose -12
+      play (ring :d, :r, :r, :a, :f5, :r, :a, :r).tick
+      sleep 0.25
+    end
+
+    with_fx :reverb do
+      live_loop :space_light do
+        with_fx :slicer, phase: 0.25 do
+          synth :blade, note: :d, release: 8, cutoff: 100, amp: 2
+        end
+        sleep 8
+      end
+    end
+
+Maintenant essayez les autres notes de la ligne de basse : `:a` et
+`:f5`. Souvenez-vous que vous n'avez pas besoin de cliquer sur 'Stop',
+vous pouvez juste modifier le code pendant que la musique tourne et
+ensuite cliquer sur 'Run' à nouveau. Aussi essayez différentes valeurs
+pour l'option `phase:` du slicer comme `0.5`, `0.75` et `1`.
+
+
+## Rassemblons tout
+
+Enfin, combinons toutes les idées vues jusqu'ici dans un nouveau remix
+de la Habanera. Vous remarquerez peut-être que j'ai inclus une autre
+partie de la ligne de basse en commentaire. Quand vous aurez tout tapé
+dans un buffer de libre cliquez sur 'Run' pour entendre la
+composition. Maintenant, sans cliquer sur 'Stop', *décommentez* la
+seconde ligne en enlevant le `#` et cliquez sur 'Run' à nouveau :
+c'est merveilleux, non ? Maintenant amusez-vous à le modifier vous-même.
+
+    use_debug false
+    bizet_bass = (ring :d, :r, :r, :a, :f5, :r, :a, :r)
+    #bizet_bass = (ring :d, :r, :r, :Bb, :g5, :r, :Bb, :r)
+     
+    with_fx :reverb, room: 1, mix: 0.3 do
+      live_loop :bizet do
+        with_fx :slicer, phase: 0.125 do
+          synth :blade, note: :d4, release: 8,
+            cutoff: 100, amp: 1.5
+        end
+        16.times do
+          tick
+          play bizet_bass.look, release: 0.1
+          play bizet_bass.look - 12, release: 0.3
+          sleep 0.125
+        end
+      end
+    end
+     
+    live_loop :ind do
+      sample :loop_industrial, beat_stretch: 1,
+        cutoff: 100, rate: 1
+      sleep 1
+    end
+     
+    live_loop :drums do
+      sample :bd_haus, cutoff: 110
+      synth :beep, note: 49, attack: 0,
+        release: 0.1
+      sleep 0.5
+    end
+
diff --git a/etc/doc/tutorial/fr/A.08-minecraft-vj.md b/etc/doc/tutorial/fr/A.08-minecraft-vj.md
new file mode 100644
index 0000000..78b9c7e
--- /dev/null
+++ b/etc/doc/tutorial/fr/A.08-minecraft-vj.md
@@ -0,0 +1,181 @@
+A.8 Devenez un VJ Minecraft
+
+# Devenez un VJ Minecraft
+
+![Screen 0](../images/tutorial/articles/A.08-minecraft-vj/minecraft-vj-0-small.png)
+
+Tout le monde a joué à Minecraft. Vous aurez tous construit des
+structures incroyables, conçu des pièges rusés et même créé des lignes
+de chariots raffinées contrôlées par des interrupteurs de pierre
+rouge. Mais qui parmi vous s'est produit avec Minecraft ? On parie que
+vous ne saviez pas que vous pouvez utiliser Minecraft pour créer des
+animations visuelles incroyables tout comme un VJ professionnel.
+
+Si votre seule possibilité de modifier Minecraft était d'utiliser la
+souris, vous auriez du mal à changer les choses suffisamment vite.
+Heureusement pour vous votre Raspberry Pi a une version de Minecraft
+qui peut être contrôlée avec du code. Il contient aussi une application
+nommée Sonic Pi qui rend la programmation Minecraft non seulement facile
+mais aussi incroyablement amusante.
+
+Dans l'article d'aujourd'hui nous allons vous montrer quelques trucs
+et astuces que nous avons utilisés pour créer des spectacles dans des
+boîtes de nuit et salles de concert autour du monde.
+
+Commençons...
+
+# Commencer
+
+Commençons avec un simple exercice d'échauffement pour nous rappeler
+les bases. Commencez par allumer votre Raspberry Pi et lancer
+Minecraft et Sonic Pi. Dans Minecraft, créez un nouveau monde, et dans
+Sonic Pi choisissez un buffer de libre et écrivez-y ce code :
+
+    mc_message "Let's get started..."
+    
+Cliquez sur le bouton 'Run' et vous verrez le message dans la fenêtre
+Minecraft. OK, on est prêt à démarrer, on va s'amuser...
+
+# Tempêtes de sable
+
+Quand on utilise Minecraft pour créer des visuels on essaie de penser
+à des choses qui auront l'air intéressantes et qui seront aussi
+faciles à générer avec du code. Un truc sympa est de créer une tempête
+de sable en laissant tomber des bloc de sable du ciel. Pour cela on a
+juste besoin de quelques fonctions simples :
+
+* `sleep` : pour insérer un délai entre des actions
+* `mc_location` : pour trouver notre emplacement courant
+* `mc_set_block` : pour positionner des blocs de sable à un endroit particulier
+* `rrand` : pour nous permetre de générer des valeurs aléatoires dans un intervalle
+* `live_loop` : pour nous permettre de faire pleuvoir du sable en continu
+
+<!-- Breakout box start --> 
+
+Si vous ne connaissez pas une des ces fonctions comme `rrand`, vous
+pouvez juste taper le mot dans votre buffer, cliquer dessus, puis
+taper `Control-i` sur le clavier pour ouvrir la documentation. Vous
+pouvez aussi aller dans l'onglet *lang* du système d'aide puis
+y chercher directement les fonctions et toutes sortes d'autres choses
+excitantes que vous pouvez faire.
+
+
+<!-- Breakout box end -->
+
+Commençons par faire tomber un peu de pluie avant de laisser la
+tempête complète éclater. Récupérez votre emplacement courant et
+utilisez-la pour créer quelques blocs de sable dans le ciel pas loin :
+
+    x, y, z = mc_location
+    mc_set_block :sand, x, y + 20, z + 5
+    sleep 2
+    mc_set_block :sand, x, y + 20, z + 6
+    sleep 2
+    mc_set_block :sand, x, y + 20, z + 7
+    sleep 2
+    mc_set_block :sand, x, y + 20, z + 8
+    
+Après avoir cliqué sur 'Run', vous devrez peut-être un peu regarder
+autour de vous car les blocs peuvent commencer par tomber derrière
+vous, suivant dans quelle direction vous êtes pour le moment. N'ayez
+pas peur, si vous les avez raté, cliquez à nouveau sur 'Run' pour
+créer encore un peu de pluie de sable, assurez-vous juste de regarder
+dans la bonne direction.
+
+Parcourons rapidement ce qui se passe ici. Sur la première ligne nous
+avons récupéré l'emplacement Steve en coordonnées avec la fonction
+`mc_location` et les avons placées dans les variables `x`, `y` et `z`.
+Puis sur les lignes suivantes nous avons utilisé la fonction
+`mc_set_block` pour placer un peu de sable aux mêmes coordonnées que
+Steve mais avec quelques modifications. On a utilisé la même
+coordonnée x, une coordonnée y 20 blocs plus haut et des coordonnées z
+successivement plus larges pour que le sable tombe dans une ligne en
+s'éloignant de Steve.
+
+Et si vous preniez ce code et commenciez à jouer avec ? Essayez
+d'ajouter plus de lignes, de changer la durée d'attente, essayez de
+mélanger du `:sand` avec du `:gravel` et choisissez différentes
+coordonnées. Expérimentez et amusez-vous !
+
+# Boucles interactives déchaînées
+
+OK, il est l'heure de lancer la tempête en déchaînant la puissance
+complète de la `live_loop` : la capacité magique de Sonic Pi qui
+montre la puissance entière de la programmation interactive : changer
+le code à la volée pendant qu'il est en train de s'exécuter !
+
+    live_loop :sand_storm do
+      x, y, z = mc_location
+      xd = rrand(-10, 10)
+      zd = rrand(-10, 10)
+      co = rrand(70, 130)
+      synth :cnoise, attack: 0, release: 0.125, cutoff: co
+      mc_set_block :sand, x + xd, y+20, z+zd
+      sleep 0.125
+    end
+    
+Qu'est-ce que c'est amusant ! On boucle assez vite (8 fois par
+seconde) et pendant chaque boucle on trouve l'emplacement de Steve
+comme avant mais on génère ensuite trois valeurs aléatoires :
+
+* `xd` : la différence pour x qui sera entre -10 et 10
+* `zd` : la différence pour z, aussi entre -10 et 10
+* `co` : une valeur de coupure pour le filtre passe-bas, entre 70 et 130
+
+On utilise ensuite ces valeurs aléatoires dans les fonctions `synth`
+et `mc_set_block` ce qui nous donne du sable qui tombe dans des
+endroits aléatoires autour de Steve ainsi qu'un son percussif
+semblable à de la pluie, joué le synthé `:cnoise`.
+
+Pour ceux d'entre vous qui ne connaissaient pas les boucles
+interactives : c'est là qu'on commence vraiment à s'amuser avec Sonic
+Pi. Pendant que le code tourne et que le sable pleut, essayez de
+changer une des valeurs, peut-être la valeur d'attente à `0.25` ou
+le type de bloc `:sand` en `:gravel`. Ensuite cliquez sur 'Run' à
+nouveau. Et voilà ! Les choses changent sans que le code ne s'arrête.
+C'est votre passerelle pour vous produire comme un vrai VJ. Continuez
+à vous exercer à changer des choses. Jusqu'où arrivez-vous à modifier
+les visuels sans arrêter le code ?
+
+
+# Des formes de blocs épiques
+
+![Screen 1](../images/tutorial/articles/A.08-minecraft-vj/minecraft-vj-1-small.png)
+
+Enfin une autre super façon de générer des visuels intéressants est de
+générer des énormes murs de motifs vers lesquels voler. Pour cet effet
+nous allons devoir passer d'un placement aléatoire de blocs à un
+placement de manière ordonnée. On peut faire cela en imbriquant deux
+itérations (cliquez sur le bouton 'Aide' et allez dans la section 5.2
+du tutoriel "Itération et boucles" pour plus d'informations sur
+l'itération). L'étrange `|xd|` après le `do` veut dire que `xd`
+prendra une valeur à chaque boucle de l'itération. La première fois il
+vaudra `0`, puis `1`, puis `2`, etc. En imbriquant deux itérations
+comme cela on peut générer toutes les coordonnées d'un carré. On peut
+ensuite choisir aléatoirement des types de blocs d'un anneau de blocs
+pour obtenir un effet intéressant :
+
+    x, y, z = mc_location
+    bs = (ring :gold, :diamond, :glass)
+    10.times do |xd|
+      10.times do |yd|
+        mc_set_block bs.choose, x + xd, y + yd, z
+      end
+    end
+
+Pas mal. Pendant qu'on s'amuse ici, essayez de changer `bs.choose` en
+`bs.tick` pour passer d'un motif aléatoire à un motif plus régulier.
+Essayez de changer les types de blocs et les plus aventureux parmi
+vous voudrons peut-être mettre ce code dans une `live_loop` pour que
+les modifs continuent à changer automatiquement.
+
+Enfin, pour la fin du set du VJ, changez les deux `10.times` en
+`100.times` et cliquez sur 'Run'. Boum ! Un énorme mur géant de
+briques aléatoires. Imaginez combien de temps ça vous aurait pris de
+construire ça avec votre souris ! Double-tapez la touche Espace pour
+entrer en mode volant et commencez à planer pour obtenir de super
+effets visuels. Ne vous arrêtez pas là, utilisez votre imagination 
+pour trouver des idées sympa et utilisez ensuite la puissance de
+programmation de Sonic Pi pour le réaliser. Quand vous vous serez
+suffisamment exercés, baissez la lumière et donnez un spectacle de VJ
+pour vos amis !
diff --git a/etc/doc/tutorial/fr/A.09-randomisation.md b/etc/doc/tutorial/fr/A.09-randomisation.md
new file mode 100644
index 0000000..3ea25e6
--- /dev/null
+++ b/etc/doc/tutorial/fr/A.09-randomisation.md
@@ -0,0 +1,196 @@
+A.9 L'aléatoire
+
+# Surfer sur des flux aléatoires
+
+Dans le quatrième épisode de cette série de tutoriels nous avons jeté
+un oeil brièvement à l'aléatoire en codant des riffs grésillants de
+synthé. Vu comme l'aléatoire est une partie très importante de mes
+performances de live coding j'ai pensé qu'il serait utile d'en couvrir
+les bases plus en détail. Mettez votre casquette et surfons sur des
+flux aléatoires !
+
+# Il n'y a pas d'aléatoire
+
+La première chose à apprendre qui pourrait vraiment vous surprendre en
+jouant avec les fonctions aléatoires de Sonic Pi c'est qu'elles ne
+sont en fait pas vraiment aléatoires. Qu'est-ce que cela signifie ?
+Eh bien, faisons quelques essais. Commencez par imaginer un nombre
+dans votre tête entre 0 et 1. Gardez-le en tête et ne me le dites pas.
+Maintenant, laissez-moi deviner... est-ce que c'était `0.321567` ?
+Non ? Bah, je ne suis clairement pas bon à ce jeu. Essayons encore une
+fois, mais demandons à Sonic Pi de choisir un nombre cette fois.
+Lancez Sonic Pi version 2.7 ou plus et demandez lui un nombre
+aléatoire mais de nouveau ne me dites pas le résultat.
+
+
+    print rand
+    
+Et maintenant pour le truc... est-ce que c'était `0.75006103515625` ?
+Oui ! Ha, je vois que vous êtes un peu sceptique. C'était peut-être
+juste de la chance. Essayons encore. Cliquez sur 'Run' à nouveau et
+regardons ce qu'on obtient... Quoi ? Encore `0.75006103515625` ? Ca ne
+peut clairement pas être aléatoire ! Vous avez raison, ça ne l'est pas.
+
+Qu'est-ce qui se passe ici ? Le mot savant d'informatique pour ceci
+est le déterminisme. Cela veut juste dire que rien n'a lieu par hasard
+et que tout a sa destinée. Votre version de Sonic Pi a le destin de
+toujours retourner `0.75006103515625` dans le programme ci-dessus.
+Cela peut sembler assez inutile, mais laissez moi vous assurer que
+c'est une des parties les plus puissantes de Sonic Pi. Si vous
+persévérez vous apprendrez comment compter sur la nature
+déterministique de l'aléatoire dans Sonic Pi comme un bloc de
+construction fondamental pour vos compositions et performances de live
+coding.
+
+# Une mélodie aléatoire
+
+Quand Sonic Pi démarre il charge en fait en mémoire une séquence de
+441 000 valeurs aléatoires pré-générées. Quand vous appelez une
+fonction aléatoire comme `rand` ou `rrand`, ce flux aléatoire est
+utilisé pour générer votre résultat. Chaque appel à une fonction
+aléatoire consomme une valeur de ce flux. Ainsi le dixième appel à une
+fonction aléatoire utilisera la dixième valeur du flux. Aussi, chaque
+fois que vous cliquez sur le bouton 'Run', le flux est réinitialisé
+pour cette exécution. C'est pour cela que j'ai pu prédire le résultat
+de `rand` et pourquoi la mélodie 'aléatoire' était la même à chaque
+fois. La version de Sonic Pi de chacun utilise exactement le même flux
+aléatoire ce qui est très important quand on commence à partager nos
+morceaux.
+
+Utilisons cette connaissance pour générer une mélodie aléatoire
+répétable :
+
+    8.times do
+     play rrand_i(50, 95)
+     sleep 0.125
+    end
+
+Tapez ceci dans un buffer de libre et cliquez sur 'Run'. Vous
+entendrez une mélodie de notes aléatoires entre 50 et 95. Quand elle
+aura fini, cliquez sur 'Run' à nouveau pour entendre exactement la
+même mélodie à nouveau.
+
+*start breakout box*
+## Des fonctions aléatoires pratiques
+
+Sonic Pi contient un certain nombre de fonctions utiles pour
+travailler avec le flux aléatoire. Voici une liste des plus utiles :
+
+* `rand` : retourne simplement la prochaine valeur dans le flux aléatoire
+* `rrand` : retourne une valeur aléatoire dans un intervalle
+* `rrand_i` : retourne une valeur entière aléatoire dans un intervalle
+* `one_in` : retourne vrai ou faux pour une probabilité donnée
+* `dice` : imite un jet de dé et retourne une valeur entre 1 et 6
+* `choose` : choisit une valeur aléatoire dans une liste
+
+Regardez leur documentation dans le système d'aide pour des
+informations détaillées et des exemples.
+
+ *end breakout box*
+
+# Réinitialiser le flux
+
+Même si la capacité de répéter une séquence de notes choisies est
+essentielle pour vous permettre de rejouer une mélodie sur la piste de
+danse, ça pourrait ne pas être exactement la mélodie que vous
+souhaitez. Ne serait-ce pas génial si on pouvait essayez différentes
+mélodies et choisir celle qu'on préfère ? C'est ici que la vraie
+magie commence.
+
+On peut régler le flux manuellement avec la fonction
+`use_random_seed`. En informatique, une graine aléatoire est le point
+de départ à partir duquel un nouveau flux de valeurs aléatoires peut
+fleurir. Essayons-le :
+
+
+    use_random_seed 0
+    3.times do
+      play rrand_i(50, 95)
+      sleep 0.125
+    end
+    
+Super, on récupère les trois premières notes de notre mélodie
+aléatoire ci-dessus : `84`, `83` et `71`. Cependant on peut
+maintenant changer la graine. Par exemple :
+
+    use_random_seed 1
+    3.times do
+      play rrand_i(50, 95)
+      sleep 0.125
+    end
+    
+    
+Intéressant, on obtient `83`, `71` et `61`. Vous avez peut-être
+remarqué que les deux premiers nombres ici sont les mêmes que les deux
+derniers nombres d'avant : ce n'est pas une coïncidence.
+
+Rappelez-vous que le flux aléatoire est juste une liste géante de
+valeurs pré-choisies. Choisir une graine aléatoire nous déplace juste
+en un point de la liste. Une autre manière de voir ça est d'imaginer
+un énorme jeu de cartes pré-mélangées. Utiliser une graine aléatoire,
+c'est couper le jeu en un point particulier. Ce qui est fabuleux avec
+ça c'est qu'on peut se déplacer dans le flux aléatoire, ce qui nous
+donne un énorme pouvoir quand on fait de la musique.
+
+Revisitons notre mélodie aléatoire de huit notes avec cette nouvelle
+capacité de réinitialiser le flux, et mettons là dans une boucle
+interactive pour pouvoir expérimenter pendant qu'elle joue :
+
+    live_loop :random_riff do    
+      use_random_seed 0
+      8.times do
+        play rrand_i(50, 95), release: 0.1
+        sleep 0.125
+      end
+    end
+
+Maintenant, pendant qu'elle est en train de jouer, changez la valeur
+de la graine de `0` en quelque chose d'autre. Essayez `100`, ou
+pourquoi pas `999`. Essayez vos propres valeurs, expérimentez et
+amusez-vous : voyez quelle graine génère la mélodie que vous préférez.
+
+# Rassemblons tout
+
+Le tutoriel de ce mois a été un plongeon bien technique dans les 
+entrailles de la fonctionnalité aléatoire de Sonic Pi. J'espère que
+cela vous a montré un peu comment elle marche et comment vous pouvez
+commencer à utiliser de l'aléatoire de manière fiable pour créer des
+motifs reproductibles dans votre musique. Il est important de souligner
+qu'on peut utiliser de l'aléatoire reproductible *où* on veut. Par
+exemple, on peut rendre aléatoire l'amplitude des notes, le mix d'un
+effet, etc. Dans l'avenir nous regarderons de plus près certaines de
+ces applications, mais pour le moment je vais vous laisser avec un
+exemple court.
+
+Tapez le code suivant dans un buffer disponible, cliquez sur 'Run' et
+commencez à modifier les graines, cliquez sur 'Run' de nouveau
+(pendant que le code tourne) et explorez les différents sons, rythmes
+et mélodies que vous pouvez créer. Quand vous en trouvez une qui sonne
+bien, notez la graine pour pouvoir y revenir plus tard. Enfin, quand
+vous aurez trouvé quelques graines qui vous plaisent, donnez un
+concert de live coding à vos amis en changeant simplement entre vos
+graines préférées pour créer un morceau entier.
+
+live_loop :random_riff do
+  use_random_seed 10300
+  use_synth :prophet
+  s = [0.125, 0.25, 0.5].choose
+  8.times do
+    r = [0.125, 0.25, 1, 2].choose
+    n = (scale :e3, :minor).choose
+    co = rrand(30, 100)
+    play n, release: r, cutoff: co
+    sleep s
+  end
+end
+
+live_loop :drums do
+  use_random_seed 2001
+  16.times do
+    r = rrand(0.5, 10)
+    sample :drum_bass_hard, rate: r, amp: rand
+    sleep 0.125
+  end
+end
+
+
diff --git a/etc/doc/tutorial/fr/A.10-controlling-your-sound.md b/etc/doc/tutorial/fr/A.10-controlling-your-sound.md
new file mode 100644
index 0000000..747448d
--- /dev/null
+++ b/etc/doc/tutorial/fr/A.10-controlling-your-sound.md
@@ -0,0 +1,201 @@
+A.10 Contrôle
+
+# Contrôler votre son
+
+Jusqu'ici dans cette série nous nous sommes concentrés sur le
+déclenchement de sons. Nous avons découvert qu'on pouvait déclencher
+les nombreux synthés présents dans Sonic Pi avec `play` ou `synth` et
+comment déclencher des samples pré-enregistrés avec `sample`. Nous
+avons aussi vu comment on pouvait entourer ces sons dans des effets
+studio tels que la reverb et la distorsion en utilisant la commande
+`with_fx`. En combinant cela avec le système de chronométrage
+incroyablement précis de Sonic Pi on peut produire un vaste ensemble
+de sons, rythmes et mélodies. Cependant, une fois qu'on a
+soigneusement sélectionné les options d'un son en particulier et qu'on
+l'a déclenché, on ne peut plus le modifier pendant qu'il est joué,
+c'est ça ? Non ! Aujourd'hui vous allez apprendre quelque chose de
+très puissant : comment contrôler des synthés qui sont en train d'être
+joués.
+
+## Un son de base
+
+Créons un simple son agréable. Lancez Sonic Pi et tapez le code
+suivant dans un buffer disponible :
+
+```
+synth :prophet, note: :e1, release: 8, cutoff: 100
+```
+
+Maintenant cliquez sur le bouton 'Run' en haut à gauche pour entendre
+un beau son de synthé grondant. Allez-y, cliquez à nouveau dessus
+quelques fois pour vous habituer. OK, fini? Commençons à le contrôler !
+
+## Noeuds de synthé
+
+Une fonctionnalité peu connue de Sonic Pi est que les fonctions
+`play`, `synth` et `sample` retournent ce qu'on appelle un `SynthNode`
+qui représente un son en train d'être joué. Vous pouvez capturer un de
+ces `SynthNode`s en utilisant une variable standard et le *contrôler*
+ensuite dans le futur. Par exemple, changeons la valeur de l'option
+`cutoff:` après un battement :
+
+```
+sn = synth :prophet, note: :e1, release: 8, cutoff: 100
+sleep 1
+control sn, cutoff: 130
+```
+
+Regardons chaque ligne une par une :
+
+On commence par déclencher le synthé `:prophet` en utilisant la
+fonction `synth` habituelle. Cependant on capture aussi le résultat
+dans une variable nommée `sn`. On aurait pu appeler cette variable
+complètement différemment comme par exemple `synth_node` ou `jane` :
+le nom n'a pas d'importance. Enfin il est important de choisir un nom
+qui a du sens pour vous pour vos performances et pour les gens qui
+lisent votre code. J'ai choisi `sn` parce que c'est un bon petit moyen
+mnémotechnique pour 'synth node'.
+
+A la ligne 2 on a une commande `sleep` standard. Ca ne fait rien de
+spécial : ça demande juste à l'ordinateur d'attendre un battement
+avant d'avancer à la ligne suivante.
+
+C'est à la ligne 3 qu'on commence à s'amuser. Ici on utilise la
+fonction `control` pour dire à notre `SynthNode` courant de changer la
+valeur de coupure en `130`. Si vous cliquez sur le bouton 'Run', vous
+entendrez le synthé `:prophet` commencer à jouer comme avant, mais
+après un battement il changera et sonnera beaucoup plus clair.
+
+
+** Breakout Box Start **
+Options modulables
+
+La plupart des options des synthés et effets de Sonic Pi peuvent être
+modifiées après avoir été déclenchées. Cependant, ce n'est pas le cas
+pour toutes. Par exemple, les options d'enveloppe `attack:`, `decay:`,
+`sustain:` et `release:` ne peuvent être définies que quand on
+déclenche le synthé. Pour savoir quelles options peuvent être
+modifiées ou non, c'est simple : allez voir la documentation d'un
+synthé ou effet et regardez la documentation des options individuelles
+et cherchez les phrases "May be changed whilst playing" (Peut être
+modifiée en jouant) ou "Can not be changed once set" (ne peut pas être
+modifiée une fois définie). Par exemple, la documentation de l'option
+`attack:` du synthé `:beep` indique clairement qu'on ne peut pas la
+modifier ultérieurement :
+
+* Valeur par défaut: 0 
+* Doit être supérieure ou égal à 0
+* Ne peut pas être modifiée après sa définition
+* Mise à l'échelle avec la valeur courante de BPM
+** Breakout Box End **
+
+## Modifications multiples
+
+Pendant qu'un synthé est joué vous n'êtes pas limités à ne le changer
+qu'une fois : vous êtes libres de le modifier autant que vous le
+souhaitez. Par exemple, on peut transformer notre `:prophet` en petit
+arpégiateur avec le code suivant :
+
+```
+notes = (scale :e3, :minor_pentatonic)
+sn = synth :prophet, note: :e1, release: 8, cutoff: 100
+sleep 1
+16.times do
+  control sn, note: notes.tick
+  sleep 0.125
+end
+```
+
+Dans cet extrait de code nous avons juste introduit quelques choses en
+plus. On commence par définir une nouvelle variable appelée `notes`
+qui contient les notes qu'on aimerait parcourir en boucle (un
+arpégiateur est juste un mot savant pour quelque chose qui parcourt en
+boucle une liste de notes dans un ordre donné). Ensuite on déplace
+notre appel à `control` dans une itération en l'appelant 16 fois. A
+chaque appel à `control` on parcourt notre anneau de `notes` qui va se
+répéter automatiquement quand on arrivera à sa fin (grâce à la
+puissance fabuleuse des anneaux de Sonic Pi). Pour un peu de variété
+essayez de remplacer `.tick` par `.choose` et tentez d'entendre la
+différence.
+
+
+Notez qu'on peut modifier plusieurs options en même temps. Essayez de
+changer la ligne de contrôle en la suivante et écoutez la différence :
+
+```
+control sn, note: notes.tick, cutoff: rrand(70, 130)
+```
+
+## Transitions
+
+Quand on contrôle un `SynthNode`, il répond exactement à ce moment-là
+et change immédiatement la valeur de l'option comme si vous aviez
+pressé un bouton ou actionné un interrupteur pour demander la
+modification. Cela peut sonner rythmique et percussif, notamment si
+l'option contrôle un aspect du timbre comme `cutoff:`. Cependant, on
+n'a pas toujours envie que la modification arrive immédiatement. On a
+parfois envie de se déplacer en douceur de la valeur courante à la
+nouvelle, comme si on avait déplacé un curseur. Bien sûr, Sonic Pi
+sait aussi faire cela en utilisant les options `_slide:`
+
+Chaque option qui peut être modifiée a aussi une option spéciale
+correspondante `_slide:` qui vous permet de définir un temps de
+transition. Par exemple, `amp:` a `amp_slide:` et `cutoff:` a
+`cutoff_slide:`. Ces options de transition marchent un peu
+différemment de toutes les autres options parce qu'elles disent à la
+note de synthé comment se comporter *la prochaine fois qu'elle seront
+contrôlées*. Voyons ça :
+
+```
+sn = synth :prophet, note: :e1, release: 8, cutoff: 70, cutoff_slide: 2
+sleep 1
+control sn, cutoff: 130
+```
+
+Remarquez que cet exemple est exactement le même qu'avant sauf qu'on a
+ajouté `cutoff_slide:`. Ceci indique que la prochaine fois que
+l'option `cutoff:` de ce synthé sera contrôlée, il mettra deux
+battements pour passer de sa valeur courante à la nouvelle valeur.
+Par conséquent, quand on utilise `control` vous pouvez entendre la
+coupure changer graduellement de 70 à 130. Cela crée une sensation
+dynamique intéressante pour le son. Maintenant essayez de changer la
+durée de `cutoff_slide:` en une valeur plus courte comme 0.5 ou une
+valeur plus longue comme 4 pour voir comment ça change le son.
+Souvenez-vous que vous pouvez transitionner chacune des options
+modifiables de cette même manière, et chaque valeur de `_slide:` peut
+être complètement différente donc vous pouvez avoir une transition
+lente de la coupure, une transition rapide de l'amplitude, et une
+transition de la stéréo un peu entre les deux si c'est ce que vous
+avez envie de créer.
+
+
+## Rassemblons tout
+
+Regardons un court exemple qui montre la puissance du contrôle des
+synthés après leur déclenchement. Remarquez que vous pouvez aussi
+transitionner les effets comme les synthés, mais avec une syntaxe
+légèrement différente. Regardez la section 7.2 du tutoriel inclus dans
+Sonic Pi pour plus d'information sur le contrôle des effets.
+
+Copiez le code dans un buffer de libre et écoutez. Ne vous arrêtez pas
+là : jouez à modifier le code. Changez les durées de transition,
+changez les notes, le synthé, l'effet et les durées d'attente et voyez
+si vous pouvez le transformer en quelque chose de complètement
+différent !
+
+
+```
+live_loop :moon_rise do
+  with_fx :echo, mix: 0, mix_slide: 8 do |fx|
+    control fx, mix: 1
+    notes = (scale :e3, :minor_pentatonic, num_octaves: 2).shuffle
+    sn = synth :prophet , sustain: 8, note: :e1, cutoff: 70, cutoff_slide: 8
+    control sn, cutoff: 130
+    sleep 2
+    32.times do
+      control sn, note: notes.tick, pan: rrand(-1, 1)
+      sleep 0.125
+    end
+  end
+end
+```
diff --git a/etc/doc/tutorial/fr/A.11-beat-tracking.md b/etc/doc/tutorial/fr/A.11-beat-tracking.md
new file mode 100644
index 0000000..45eaa4c
--- /dev/null
+++ b/etc/doc/tutorial/fr/A.11-beat-tracking.md
@@ -0,0 +1,217 @@
+A.11 Tic tac
+
+# Suivre le rythme
+
+Le mois dernier dans cette série nous avons regardé en détail comment
+fonctionne le système de gestion de l'aléatoire de Sonic Pi. On a
+exploré comment on peut l'utiliser de manière déterministe pour avoir
+de nouveaux niveaux de contrôle dynamique sur notre code. Ce mois-ci
+nous allons continuer notre exploration technique et regarder le
+système unique de 'tick' de Sonic Pi. D'ici la fin de cet article vous
+parcourrez des rythmes et mélodies sur votre chemin pour devenir un DJ
+de programmation interactive.
+
+
+# Compter les temps
+
+Quand on fait de la musique on a souvent envie de faire quelque chose
+de différent en fonction du temps sur lequel on est. Sonic Pi a un
+système spécial pour compter les temps appelé `tick` pour vous donner
+un contrôle précis sur quand est-ce qu'un battement arrive réellement
+et il supporte même des battements multiples avec leur propre tempo.
+
+Amusons-nous : pour avancer le temps on a juste besoin d'appeler
+`tick`. Ouvrez un buffer libre, tapez le code suivant et cliquez sur
+le bouton 'Run' :
+
+```
+puts tick #=> 0
+```
+
+Cela retournera le battement courant : `0`. Remarquez que même si
+vous cliquez plusieurs fois sur le bouton 'Run', il retournera
+toujours `0`. Cela parce que chaque exécution commence avec un
+compteur qui part de 0. Cependant, pendant que le programme tourne, on
+peut avancer le compteur autant qu'on veut :
+
+```
+puts tick #=> 0
+puts tick #=> 1
+puts tick #=> 2
+```
+
+<breakout> Quand vous voyez le symbole `#=>` à la fin d'une ligne de
+code cela veut dire que cette ligne va noter ce texte dans la partie
+de droite de Sonic Pi. Par exemple, `puts foo #=> 0` veut dire que le
+code `puts foo` affiche `0` dans le log à cet endroit du programme.
+</breakout>
+
+# Vérifier le compteur
+
+On a vu que `tick` fait deux choses. Il incrémente (ajoute un) et
+retourne le compteur courant. Parfois on veut juste regarder le
+battement courant sans devoir l'incrémenter et on peut faire cela via
+`look`.
+
+``` 
+puts tick #=> 0
+puts tick #=> 1
+puts look #=> 1
+puts look #=> 1
+``` 
+
+Dans ce code on incrémente le compteur deux fois puis on appelle
+`look` deux fois. On verra les valeurs suivantes dans le log : `0`,
+`1`, `1`, `1`. Les deux premiers `tick`s ont retourné `0` et `1`,
+comme attendu, puis les deux `look`s ont juste retourné la dernière
+valeur du compteur deux fois, donc `1`.
+
+
+# Anneaux
+
+On peut donc avancer le compteur avec `tick` et en connaître la valeur
+avec `look`. Qu'est-ce qui vient suite ? On a besoin de quelque chose
+à parcourir. Sonic Pi utilise les anneaux pour représenter les
+mélodies et rythmes et le système de tick a été conçu spécialement
+pour fonctionner avec eux. En fait, les anneaux ont leur propre
+version de `tick` qui fait deux choses. D'un côté elle agit comme un
+tick normal et incrémente le compteur. D'un autre, elle donne une
+valeur de l'anneau en utilisant le compteur comme index. Voyons cela :
+
+```
+puts (ring :a, :b, :c).tick #=> :a
+```
+
+`.tick` est une version spéciale avec un point de `tick` qui nous
+retourne la première valeur de l'anneau: : `:a`. On peut attraper
+chacune des notes de l'anneau en appelant `:tick` plusieurs fois :
+
+```
+puts (ring :a, :b, :c).tick #=> :a
+puts (ring :a, :b, :c).tick #=> :b
+puts (ring :a, :b, :c).tick #=> :c
+puts (ring :a, :b, :c).tick #=> :a
+puts look                   #=> 3
+```
+
+Regardez le log et vous verrez `:a`, `:b`, `:c` et puis de nouveau
+`:a`. Remarquez que `look` retourne `3`. Les appels à `.tick` se
+comportent comme les appels à `tick` : ils incrémentent le compteur
+local.
+
+
+# Un arpégiateur dans une boucle interactive
+
+La véritable puissance vient quand on mélange `tick` avec des anneaux
+et des `live_loop`s. En les combinant on a tous les outils dont on a
+besoin pour construire et comprendre un arpégiateur simple. On a juste
+besoin de quatre choses :
+
+1. Un anneau qui contient les notes sur lesquelles on va boucler
+2. Une manière d'incrémenter et de lire le compteur
+3. La capacité de jouer une note en se basant sur le compteur courant
+4. Une structure de boucle qui répète l'arpégiateur en continu
+
+Ces concepts se retrouvent tous dans le code suivant :
+
+```
+notes = (ring 57, 62, 55, 59, 64)
+
+live_loop :arp do
+  use_synth :dpulse
+  play notes.tick, release: 0.2
+  sleep 0.125
+end
+```
+
+Regardons chacune de ces lignes. On commence par définir notre anneau
+de notes que nous allons jouer en continu. On crée ensuite une
+`live_loop` nommée `:arp` qui va boucler pour nous. A chaque itération
+de la `live_loop` on choisit un synthé `:dpulse` et on joue ensuite la
+note suivante de notre anneau en utilisant `.tick`. Souvenez-vous que
+cela va incrémenter notre compteur de temps et en utiliser la valeur
+comme index dans notre anneau de notes. Enfin on attend un huitième de
+temps avant de recommencer la boucle.
+
+# Battements multiples simultanés
+
+Une chose très importante à savoir est que les `tick`s sont liés à la
+`live_loop`. Cela veut dire que chaque `live_loop` a son propre
+compteur indépendant. C'est beaucoup plus puissant que d'avoir un
+métronome et battement global. Regardons ce que cela donne :
+
+notes = (ring 57, 62, 55, 59, 64)
+
+with_fx :reverb do
+  live_loop :arp do
+    use_synth :dpulse
+    play notes.tick + 12, release: 0.1
+    sleep 0.125
+  end
+end
+
+live_loop :arp2 do
+  use_synth :dsaw
+  play notes.tick - 12, release: 0.2
+  sleep 0.75
+end
+
+# Collisions de battements
+
+Une grande source de confusion dans le système de tick de Sonic Pi est
+quand on veut parcourir plusieurs anneaux dans le même `live_loop`.
+
+use_bpm 300
+use_synth :blade
+live_loop :foo do
+  play (ring :e1, :e2, :e3).tick
+  play (scale :e3, :minor_pentatonic).tick
+  sleep 1
+end
+
+Même si chaque `live_loop` a son compteur indépendant, ici on appelle
+`.tick` deux fois dans la même `live_loop`. Cela veut dire que le
+compteur sera incrémenté deux fois à chaque boucle. Cela peut produire
+des polyrythmes intéressants mais ce n'est souvent pas ce que l'on
+souhaite. Il y a deux solutions à ce problème. Une option est
+d'appeler `tick` manuellement au début de la `live_loop` puis
+d'utiliser `look` pour chercher la valeur courante du compteur dans
+chaque `live_loop`. La seconde solution est de passer un nom unique
+à chaque appel à `.tick`, comme par exemple `.tick(:foo)`. Sonic Pi
+créera alors un compteur séparé pour chaque tick nommé que vous
+utiliserez. Ainsi on peut travailler avec autant de compteurs que
+nécessaire ! Lisez le section 9.4 sur les ticks nommés dans le
+tutoriel inclus dans Sonic Pi pour plus d'informations.
+
+# Rassemblons tout
+
+Combinons nos connaissances sur les `tick`s, `ring`s (anneaux) et
+`live_loop`s pour un dernier exemple amusant. Comme d'habitude, ne
+traitez pas ceci comme un morceau terminé. Commencez à changer des
+choses et amusez-vous avec et voyez en quoi vous pouvez le
+transformer. A la prochaine...
+
+
+use_bpm 240
+notes = (scale :e3, :minor_pentatonic).shuffle
+
+live_loop :foo do
+  use_synth :blade
+  with_fx :reverb, reps: 8, room: 1 do
+    tick
+    co = (line 70, 130, steps: 32).tick(:cutoff)
+    play (octs :e3, 3).look, cutoff: co, amp: 2
+    play notes.look, amp: 4
+    sleep 1
+  end
+end
+
+live_loop :bar do
+  tick
+  sample :bd_ada if (spread 1, 4).look
+  use_synth :tb303
+  co = (line 70, 130, steps: 16).look
+  r = (line 0.1, 0.5, steps: 64).mirror.look
+  play notes.look, release: r, cutoff: co
+  sleep 0.5
+end
diff --git a/etc/doc/tutorial/ja/02.1-Your-First-Beeps.md b/etc/doc/tutorial/ja/02.1-Your-First-Beeps.md
index a51e534..603b7c6 100755
--- a/etc/doc/tutorial/ja/02.1-Your-First-Beeps.md
+++ b/etc/doc/tutorial/ja/02.1-Your-First-Beeps.md
@@ -107,7 +107,7 @@ sleep 0.5
 play :E4
 ```
 
-半音♭(シャープ)にしたい場合は、’play :Fs3'のように音名の後に's'を追加します。 
-半音♯(フラット)にしたい場合は、'play :Eb3'のように'b'を追加します。
+半音♯(シャープ)にしたい場合は、’play :Fs3'のように音名の後に's'を追加します。 
+半音♭(フラット)にしたい場合は、'play :Eb3'のように'b'を追加します。
 
 *夢中*になって、自分の曲を作って楽しみましょう。
diff --git a/etc/doc/tutorial/ja/02.2-Synth-Params.md b/etc/doc/tutorial/ja/02.2-Synth-Params.md
index eaab028..8c8bcc2 100755
--- a/etc/doc/tutorial/ja/02.2-Synth-Params.md
+++ b/etc/doc/tutorial/ja/02.2-Synth-Params.md
@@ -1,61 +1,61 @@
-2.2 シンセのパラメータ
+2.2 シンセのオプション
 
-# シンセのパラメータ:Amp と Pan
+# シンセのオプション:Amp と Pan
 
-Sonic Piはあらゆる音を作りだし、コントロールするためのパラメータの全てを提供します。
+Sonic Piはあらゆる音を作りだし、コントロールするためのオプションの全てを提供します。
 どんな音符を演奏するのか、そしてどんなサンプルをトリガー(きっかけ)にするのかはあなた次第です。
 このチュートリアルでは、これらの多くをカバーするそれぞれについての詳細なドキュメントが
 ヘルプシステムにあります。しかし、これから最も有用なのうちの2つ、*Amplitude(振幅)*と*Pan(パン)*を紹介します。
-まずはパラメータを見てみましょう。
+まずはオプションを見てみましょう。
 
-## パラメータ
+## オプション
 
-Sonic Piはシンセのためにパラメータ(変数)という概念を備えています。
-パラメータは、あなたが耳にするサウンドの特徴をコントロールしたり、
+Sonic Piはシンセのためにオプションという概念を備えています。
+オプションは、あなたが耳にするサウンドの特徴をコントロールしたり、
 変更するための手段で、演奏に反映されます。シンセはそれぞれ細かく音を
-チューニングするためのパラメータを持っています。
-Sonic Piには、`amp:`(音量)やエンベロープ・パラメータ(ほかのセクションで紹介します)のような、
-多くのサウンドに共通するパラメータを持っています。
+チューニングするためのオプションを持っています。
+Sonic Piには、`amp:`(音量)やエンベロープ・オプション(ほかのセクションで紹介します)のような、
+多くのサウンドに共通するオプションを持っています。
 
-パラメータには2つの主要な役割があり、ひとつはその名前(制御の名前)、もうひとつは
-数値(あなたが制御したい値)です。例えば、`cheese:`いうパラメータがあったとして、 
+オプションには2つの主要な役割があり、ひとつはその名前(制御の名前)、もうひとつは
+数値(あなたが制御したい値)です。例えば、`cheese:`いうオプションがあったとして、
 `1`の値にセットしたいとします。
 
-パラメータは、play`の後にカンマ`,`を入れて、その後、`amp:`(コロン : を忘れずに)のような
-パラメータの名前、スペース、そしてパラメータの値、というように渡していきます。例えば、
+オプションは、play`の後にカンマ`,`を入れて、その後、`amp:`(コロン : を忘れずに)のような
+オプションの名前、スペース、そしてオプションの値、というように渡していきます。例えば、
 
 ```
 play 50, cheese: 1
 ```
 
-(cheese: は無効なパラメータです。例として使っています。)
+(cheese: は無効なオプションです。例として使っています。)
 
-カンマを使って区切り、複数のパラメータを使用することができます。
+カンマを使って区切り、複数のオプションを使用することができます。
 
 ```
 play 50, cheese: 1, beans: 0.5
 ```
 
-パラメータの順番は問題ではないので、以下は同じものです。
+オプションの順番は問題ではないので、以下は同じものです。
 
 
 ```
 play 50, beans: 0.5, cheese: 1
 ```
 
-シンセで認識されないパラメータは無視されます(`cheese` (チーズ)と`beans`(豆)などは明らかに馬鹿げた名前でしょう!)
+シンセで認識されないオプションは無視されます(`cheese` (チーズ)と`beans`(豆)などは明らかに馬鹿げた名前でしょう!)
 
-もし偶然同じパラメータを2回、違う値で使った場合は、最後のものが有効になります。
+もし偶然同じオプションを2回、違う値で使った場合は、最後のものが有効になります。
 例えば、ここでの`beans:`は、0.5 ではなく 2 の値が採用されます。
 
 ```
 play 50, beans: 0.5, cheese: 3, eggs: 0.1, beans: 2
 ```
 
-Sonic Piの中の命令には多くのパラメータが用意されているので、その使い方に
+Sonic Piの中の命令には多くのオプションが用意されているので、その使い方に
 ちょっとだけ時間を使って、習得しましょう!
 
-それでは最初のパラメータ`amp:`で演奏してみましょう。
+それでは最初のオプション`amp:`で演奏してみましょう。
 
 ## アンプ(増幅)
 
@@ -70,7 +70,7 @@ Sonic Piの中の命令には多くのパラメータが用意されているの
 
 ## 音量を上げる
 
-音の大きさを変えるために、 amp: パラメータを使います。
+音の大きさを変えるために、 amp: オプションを使います。
 例として、半分の音量で演奏するために、0.5 にしてみます。
 
 ```
@@ -83,7 +83,7 @@ play 60, amp: 0.5
 play 60, amp: 2
 ```
 
- `amp:`パラメータは、関連付けられている`play`への命令だけを変更します。
+ `amp:`オプションは、関連付けられている`play`への命令だけを変更します。
  ですから、この例では、最初の命令は半分の音量になり、次にはデフォルト(1の値)に戻ります。
 
 ```
@@ -105,7 +105,7 @@ play 62, amp: 1
 
 ## パンニング
 
-もうひとつの面白いパラメータは`pan:`です。ステレオで音の位置を制御します。
+もうひとつの面白いオプションは`pan:`です。ステレオで音の位置を制御します。
 左に音をパンすることは左のスピーカーから音が聞こえることを意味し、
 右にパンすれば右のスピーカーから聞こえます。値としては、-1 は最も左、
 0 は中心、1 は最も右、というようにステレオの領域で表現することができます。
diff --git a/etc/doc/tutorial/ja/02.4-Durations-with-Envelopes.md b/etc/doc/tutorial/ja/02.4-Durations-with-Envelopes.md
index c78fae5..6a4f166 100755
--- a/etc/doc/tutorial/ja/02.4-Durations-with-Envelopes.md
+++ b/etc/doc/tutorial/ja/02.4-Durations-with-Envelopes.md
@@ -32,27 +32,41 @@ Sonic Piはエンベロープでこれをプログラムできるようにして
 
 前のセクションで見てきたように、アンプの`0`は無音、`1`は通常の音量です。
 
+では、エンベロープのそれぞれの部分を順番に見ていきましょう。
 
-## リリース・タイム(終わるまでの時間)
+## リリース・フェーズ(終わるまでの時間)
 
-通常、全てのシンセのリリース・タイム(終わるまでの時間)は1です。
-これは、終了するまでに1秒間のデュレーションを持っているということです。
-`play`に対して`release:`という命令を渡すことで、デュレーションを
-変更することができます。例えば、2 秒間シンセを再生するには、`release:`を`2`に設定します。
+エンベロープのうちデフォルトで使われている唯一の部分はリリース・フェーズです。
+通常、全てのシンセのリリース・フェーズ(終わるまでの時間)は1で、
+これは終了するまでに1ビート(デフォルトBPMの60の場合には1秒)のデュレーションを持っているということです。
+
+```
+play 70
+```
+
+この音は1秒間だけ聞こえます。続いて時間を指定しよう。
+上の記述は、次の明示的で長い記述を簡略化したものです。
+
+```
+play 70, release: 1
+```
+
+これも全く同じように(1秒間持続する)音が出たと思います。
+しかし、`release:`のオプションを変更することでとても簡単に
+持続時間を変更することができるようになりました。
 
 ```
 play 60, release: 2
 ```
 
-非常に小さなリリース・タイムの値を使って、シンセのサウンドをとても短くすることができます。
+また、非常に小さなリリース・フェーズの値を使って、シンセのサウンドをとても短くすることができます。
 
 ```
 play 60, release: 0.2
 ```
 
-だから、リリース・タイムって一体なんなのでしょうか?それはサウンドが、フル・アンプ(だいたい1の値)から
-ゼロ・アンプ(無音)になるまでにかかる時間のことです。これはリリース・フェーズと呼ばれていて、
-リニア・トランジション(直線的な移行、つまり真っ直ぐ)です。以下の図は、この移行を表したものです。
+音がリリースされるまでの持続時間はリリース・フェーズと呼ばれていて、
+デフォルトではリニア・トランジション(直線的な移行、つまり真っ直ぐ)です。以下の図は、この移行を表したものです。
 
 ![release envelope](:/images/tutorial/env-release.png)
 
@@ -61,14 +75,14 @@ play 60, release: 0.2
 いったんフル・アンプになり、それから`release:`で指定した値を取りながら、直線的にゼロに下がります。
 *長いリリース・タイムは長いシンセ・フェード・アウト(徐々に消えること)を生成します*。
 
-これにより、リリース・タイムを変更して、あなたのサウンドのデュレーションを
+これにより、リリース・フェーズを変更して、あなたのサウンドのデュレーションを
 変えることができます。自分の音楽にリリース・タイムを追加して演奏してみましょう。
 
-## アタック・タイム
+## アタック・フェーズ
 
 通常、アタック・フェーズは全てのシンセにおいて`0`です。つまり、`0`アンプから
  `1`にただちに移動することを意味します。シンセは最初から音が打たれます。
- けれども、あなたは音をフェード・イン(徐々に大きく)したいかも知れません。 これは、`attack:`の命令で実現することができます。いくつかの音をフェード・インしてみましょう。
+ けれども、あなたは音をフェード・イン(徐々に大きく)したいかも知れません。 これは、`attack:`のオプションで実現することができます。いくつかの音をフェード・インしてみましょう。
 
 ```
 play 60, attack: 2
@@ -76,7 +90,7 @@ sleep 3
 play 65, attack: 0.5
 ```
 
-複数の命令を使うこともできます。例えば、短いアタック、長いリリースに、変更してみましょう。
+複数のオプションを使うこともできます。例えば、短いアタック、長いリリースに、変更してみましょう。
 
 ```
 play 60, attack: 0.7, release: 4
@@ -104,33 +118,31 @@ play 60, attack: 0.5, release: 0.5
 
 ![short attack short release envelope](:/images/tutorial/env-short-attack-short-release.png)
 
-## サステイン・タイム(持続時間)
+## サステイン・フェーズ(持続時間)
 
-アタック・タイムとリリース・タイムの設定に付け加えて、サステイン・タイム(持続時間)を
-指定することができます。サステイン・タイムとは、アタックとリリースの間でフル・アンプの
+アタック・フェーズとリリース・フェーズの設定に付け加えて、サステイン・フェーズ(持続時間)を
+指定することができます。サステイン・フェーズとは、アタックとリリースの間でフル・アンプの
 音が鳴り続ける時間のことです。
 
-
 ```
 play 60, attack: 0.3, sustain: 1, release: 1
 ```
 
 ![ASR envelope](:/images/tutorial/env-attack-sustain-release.png)
 
-サステイン・タイムは、オプションのリリース・フェーズに入る前に、ミックスの中で主となる
-存在感を与えたい重要なサウンドにとって有効です。もちろん、アタックとリリース両方の命令を
+サステイン・フェーズは、オプションのリリース・フェーズに入る前に、ミックスの中で主となる
+存在感を与えたい重要なサウンドにとって有効です。もちろん、`attack:`と`release:`両方のオプションを
 0に設定することもとても有効ですし、サウンドに対して、完全にフェード・インなし、
 フェード・アウトなしにするためにサステインを使えば良いのです。けれど、注意してください、
 0 のリリースはオーディオの中にクリック音を生成します。たいていの場合、0.2のような
 ごく小さい値を使う方が良いです。
 
-## ディケイ・タイム(減衰時間)
+## ディケイ・フェーズ(減衰時間)
 
 そして、今あなたがさらなる制御のレベルを必要としているならば、ディケイ・タイムというものを
 設定することもできます。これは、アタックとサステインの間にくるエンベロープのフェーズで、
-音量が`attack_level`から`sustain_level`に落ちる時間を指定します。
-通常では、ディケイの指令は 0 で、アタックとサステインのレベルは両方とも 1 です。ですから、ディケイ・タイムで効果を得るには、アタック、サステインのレベルも指定しなくてはなりません。
-
+音量が`attack_level:`から`decay_level:`(もしこれを明示的に指定しなければ、この値は `sustain_level:`と同じ値に設定されます)に落ちる時間を指定します。
+通常では、`decay:`のオプションは 0 で、アタックとサステインのレベルは両方とも 1 です。ですから、ディケイ・フェーズで効果を得るには、アタック、サステインのレベルも指定しなくてはなりません。
 
 ```
 play 60, attack: 0.1, attack_level: 1, decay: 0.2, sustain_level: 0.4, sustain: 1, release: 0.5
@@ -138,20 +150,39 @@ play 60, attack: 0.1, attack_level: 1, decay: 0.2, sustain_level: 0.4, sustain:
 
 ![ADSR envelope](:/images/tutorial/env-attack-decay-sustain-release.png)
 
-## AADSR エンベロープ
+## ディケイレベル
+
+最後の仕掛けは、`decay_level:`オプションがデフォルトでは`sustain_level:`と同じ値に設定されていて、エンベロープを完全に制御したい場合に明示的に別な値に設定できることです。
+これにより次のようなエンベロープを作ることができるでしょう。
+
+```
+play 60, attack: 0.1, attack_level: 1, decay: 0.2, decay_level: 0.3, sustain: 1, sustain_level: 0.4, release: 0.5
+```
+
+![ASR envelope](../images/tutorial/env-decay-level.png)
+
+また`decay_level:`を`sustain_level:`より大きく設定することもできます。
+
+```
+play 60, attack: 0.1, attack_level: 0.1, decay: 0.2, decay_level: 1, sustain: 0.5, sustain_level: 0.8, release: 1.5
+```
+
+![ASR envelope](../images/tutorial/env-decay-level-2.png)
+
+## ADSR エンベロープ
 
 つまり要約すると、Sonic PiのADSRエンベロープには、以下のフェーズがあります。
 
 1. *attack*(アタック)- 0 アンプから`attack_level`までの時間
-2. *decay*(ディケイ)- 音量を`attack_level`から`sustain_level`まで移行させる時間
-3. *sustain*(サステイン)- 音量を`sustain_level`で保持する時間
+2. *decay*(ディケイ)- 音量を`attack_level`から`decay_level`まで移行させる時間
+3. *sustain*(サステイン)- 音量を`decay_level`から`sustain_level`まで移行させる時間
 4. *release*(リリース) - 音量を`sustain_level`から 0 に移行させる時間
 
 サウンドのデュレーションは、これらのフェーズの合計であることに注意することが大切です。
 したがって、以下のサウンドは 0.5 + 1 + 2 + 0.5 = 4 で、4秒のデュレーションになります。
 
 ```
-play 60, attack: 0.5, decay: 1, sustain_level: 0.4, sustain: 2, release: 0.5
+play 60, attack: 0.5, attack_level: 1, decay: 1, sustain_level: 0.4, sustain: 2, release: 0.5
 ```
 
-ではあなたのサウンドにエンベロープを追加して演奏してみましょう。
\ No newline at end of file
+ではあなたのサウンドにエンベロープを追加して演奏してみましょう。
diff --git a/etc/doc/tutorial/ja/03.3-Stretching-Samples.md b/etc/doc/tutorial/ja/03.3-Stretching-Samples.md
index 28b56ad..cdec220 100755
--- a/etc/doc/tutorial/ja/03.3-Stretching-Samples.md
+++ b/etc/doc/tutorial/ja/03.3-Stretching-Samples.md
@@ -10,7 +10,7 @@
 
 ## レートを変える
 
-アンビエント・サウンドのひとつ、`:ambi_choir`で演奏してみましょう。デフォルト(既定値)で演奏するには、`sample`に`rate:` の命令を渡します。
+アンビエント・サウンドのひとつ、`:ambi_choir`で演奏してみましょう。デフォルト(既定値)で演奏するには、`sample`に`rate:` のオプションを渡します。
 
 sample :ambi_choir, rate: 1
 
diff --git a/etc/doc/tutorial/ja/03.4-Enveloped-Samples.md b/etc/doc/tutorial/ja/03.4-Enveloped-Samples.md
index df0fba1..0a7f397 100755
--- a/etc/doc/tutorial/ja/03.4-Enveloped-Samples.md
+++ b/etc/doc/tutorial/ja/03.4-Enveloped-Samples.md
@@ -11,7 +11,7 @@ ADSRエンベロープを用いて、サンプルのデュレーション(再
 sample :loop_amen
 ```
 
-パラメータが設定されていない場合、全サンプルがフル・アンプ(最大音量)で聞こえます。
+オプションが設定されていない場合、全サンプルがフル・アンプ(最大音量)で聞こえます。
 もし1秒間のフェード・インを使いたい場合、`attack:`パラメータを使います。
 (フェード・インとは徐々に音が大きくなることです。)
 
diff --git a/etc/doc/tutorial/ja/06-FX.md b/etc/doc/tutorial/ja/06-FX.md
index 0218d2c..4089558 100755
--- a/etc/doc/tutorial/ja/06-FX.md
+++ b/etc/doc/tutorial/ja/06-FX.md
@@ -4,7 +4,7 @@
 
 Sonic Piには、あなたの作ったサウンドに簡単にスタジオ·エフェクトを追加できるという最もやりがいのある楽しい側面があります。たとえば、部分的にリバーブを追加したり、エコーやディストーション(歪み)、ワブルベース(ベース音にフィルターLFOを掛け、断続的な音にすること)を加えることができます。
 
-Sonic Piには、エフェクト(効果)を追加する非常にシンプルで強力な方法があります。それも、あなたが作った音にディストーション(歪み)を通し、その後エコー、さらにリバーブと、それらをチェーン(連結)させ、また、シンセやサンプルにパラメータを与えるのと同様の方法でエフェクトユニットのパラメータを個別に制御することができ、実行されている間でも、パラメータを変更することも可能です。だから、例えば、トラックのいたるところでベースのリバーブを強くするということができるのです。
+Sonic Piには、エフェクト(効果)を追加する非常にシンプルで強力な方法があります。それも、あなたが作った音にディストーション(歪み)を通し、その後エコー、さらにリバーブと、それらをチェーン(連結)させ、また、シンセやサンプルにオプションを与えるのと同様の方法でエフェクトユニットのオプションを個別に制御することができ、実行されている間でも、オプションを変更することも可能です。だから、例えば、トラックのいたるところでベースのリバーブを強くするということができるのです。
 
 ## ギター エフェクター
 
diff --git a/etc/doc/tutorial/ja/06.1-Adding-FX.md b/etc/doc/tutorial/ja/06.1-Adding-FX.md
index 95635e2..0631da0 100755
--- a/etc/doc/tutorial/ja/06.1-Adding-FX.md
+++ b/etc/doc/tutorial/ja/06.1-Adding-FX.md
@@ -75,7 +75,7 @@ end
 ```
 
 Sonic Piのエフェクトブロックの強力な側面の一つは、既に`play`と`sample`で見てきたように、
-パラメータと同様の数値が渡されることです。たとえば、エコーの楽しいパラメータは、
+オプションと同様の数値が渡されることです。たとえば、エコーの楽しいオプションは、
 秒単位で遅れを示す`phase`で表され、エコーの長さを指定します。
 
 下記のコードで、音の響きをゆっくりにしてみましょう。
diff --git a/etc/doc/tutorial/ja/07-Control.md b/etc/doc/tutorial/ja/07-Control.md
index f4af83d..673396d 100755
--- a/etc/doc/tutorial/ja/07-Control.md
+++ b/etc/doc/tutorial/ja/07-Control.md
@@ -2,8 +2,8 @@
 
 # 演奏中のサウンド制御
 
-これまでの章では、どのようにシンセやサンプルを扱い、アンプ(増幅)、パン、エンベロープなどのパラメーターを変更するのかを見てきました。呼び出された個々の音には、元来、音の継続時間を設定するデュレーションパラメータが備わっています。
+これまでの章では、どのようにシンセやサンプルを扱い、アンプ(増幅)、パン、エンベロープなどのオプションを変更するのかを見てきました。呼び出された個々の音には、元来、音の継続時間を設定するデュレーションオプションが備わっています。
 
-もしも演奏中にギターの弦を歪めビブラートさせるように、パラメータを変更できたなら、それってクールではないでしょうか?
+もしも演奏中にギターの弦を歪めビブラートさせるように、オプションを変更できたなら、それってクールではないでしょうか?
 
 あなたは幸運です-このセクションでは、まさしくそれをどのように行うのかを紹介します。
diff --git a/etc/doc/tutorial/ja/07.1-Controlling-Running-Synths.md b/etc/doc/tutorial/ja/07.1-Controlling-Running-Synths.md
index 0b34ea9..1fc3555 100755
--- a/etc/doc/tutorial/ja/07.1-Controlling-Running-Synths.md
+++ b/etc/doc/tutorial/ja/07.1-Controlling-Running-Synths.md
@@ -24,8 +24,8 @@ control s, note: 72
 
 演奏している間に、1つのシンセのみを呼び出し、3回ピッチを変更します。ここで注目すべき点は、4つの異なるシンセを呼び出していないということです。
 
-標準的なパラメータ(関数)は`control`へ渡すことができます。そして`amp:`, `cutoff:`あるいは`pan:`のようなパラメータを制御することができます。 
+標準的なオプション(関数)は`control`へ渡すことができます。そして`amp:`, `cutoff:`あるいは`pan:`のようなオプションを制御することができます。
 
-## 制御不可能なパラメータ
+## 制御不可能なオプション
 
-一度シンセが開始されると、一部のパラメータは制御することができなくなります。ADSRエンベロープ·パラメータがこれに該当します。そのパラメータが制御可能かは、ヘルプシステムのドキュメントを参照してください。ドキュメントに「設定を変更することは出来ません」というコメントがある場合、シンセが開始した後にパラメータを制御することはできません。
+一度シンセが開始されると、一部のオプションは制御することができなくなります。ADSRエンベロープ·パラメータがこれに該当します。そのオプションが制御可能かは、ヘルプシステムのドキュメントを参照してください。ドキュメントに「設定を変更することは出来ません」というコメントがある場合、シンセが開始した後にオプションを制御することはできません。
diff --git a/etc/doc/tutorial/ja/07.3-Sliding-Parameters.md b/etc/doc/tutorial/ja/07.3-Sliding-Parameters.md
index 0317675..856f34b 100755
--- a/etc/doc/tutorial/ja/07.3-Sliding-Parameters.md
+++ b/etc/doc/tutorial/ja/07.3-Sliding-Parameters.md
@@ -1,8 +1,8 @@
-7.3 パラメータのスライド
+7.3 オプションのスライド
 
-# パラメータのスライド
+# オプションのスライド
 
-シンセやエフェクトの引数を探索しながら、`_slide`で終わるパラメータがあることに気づいたかもしれません。それらを呼び出しても、何の効果を示さなかった可能性があります。これは正常のパラメータではなく、前回のセクションで紹介したように、シンセを制御するときのみ動作をする特別なパラメータです。
+シンセやエフェクトの引数を探索しながら、`_slide`で終わるオプションがあることに気づいたかもしれません。それらを呼び出しても、何の効果を示さなかった可能性があります。これは正常のオプションではなく、前回のセクションで紹介したように、シンセを制御するときのみ動作をする特別なオプションです。
 
 次の例を考えてみましょう。
 
@@ -16,7 +16,7 @@ sleep 3
 control s, note: 72
 ```
 
-ここでは、各`control`の呼び出し後、すぐにシンセのピッチの変更を聞くことができますが、ピッチが変化する間にスライドさせたくなるかもしれません。その場合、スライドを追加するために、`note:`パラメータを制御するように、シンセの`note_slide`パラメータを追加する必要があります。
+ここでは、各`control`の呼び出し後、すぐにシンセのピッチの変更を聞くことができますが、ピッチが変化する間にスライドさせたくなるかもしれません。その場合、スライドを追加するために、`note:`オプションを制御するように、シンセの`note_slide`オプションを追加する必要があります。
 
 ```
 s = play 60, release: 5, note_slide: 1
@@ -32,13 +32,13 @@ control s, note: 72
 
 ## ネバネバするスライド
 
-一度、実行しているシンセの `_slidee`パラメータを設定したら、それは記憶され、
-対応するパラメータがスライドする度に使用されます。
+一度、実行しているシンセの `_slide`オプションを設定したら、それは記憶され、
+対応するオプションがスライドする度に使用されます。
 スライドを停止するためには、次の`control`を呼び出す前に`0`に`_slide`値を設定する必要があります。
 
-## エフェクト・パラメータのスライド
+## エフェクト・オプションのスライド
 
-また、エフェクトパラメータをスライドさせることも可能です。
+また、エフェクトオプションをスライドさせることも可能です。
 
 ```
 with_fx :wobble, phase: 1, phase_slide: 5 do |e|
diff --git a/etc/doc/tutorial/ja/08.4-Rings.md b/etc/doc/tutorial/ja/08.4-Rings.md
index 8010800..8a8a787 100755
--- a/etc/doc/tutorial/ja/08.4-Rings.md
+++ b/etc/doc/tutorial/ja/08.4-Rings.md
@@ -77,5 +77,6 @@ puts notes[counter]
 * `range`は始点、終点とステップサイズを指定します。
 * `bools`は簡単に1と0を使用するためのブール値を扱うことができます。
 * `knit`は一連の繰り返される値のために構成することを可能にします。
+* `spread`はユークリッド分布に従ったブール値のリングを作成します。
 
 詳細については、それら個々のドキュメンテーションを見てください。
diff --git a/etc/doc/tutorial/ja/08.5-Ring-Chains.md b/etc/doc/tutorial/ja/08.5-Ring-Chains.md
new file mode 100644
index 0000000..8dc5e95
--- /dev/null
+++ b/etc/doc/tutorial/ja/08.5-Ring-Chains.md
@@ -0,0 +1,74 @@
+8.5 リングのチェーン
+
+`range`や`spread`のようなコンストラクタに加えて、別なリングの作成方法としては、作成済みのリングを操作する方法があります。
+
+## チェーンコマンド
+
+次のような単純なリングを作成します:
+
+```
+(ring 10, 20, 30, 40, 50)
+```
+
+リングを逆にしたいときにはどうしたらよいでしょう?リングを反転させるには、チェーンコマンドの`.reverse`を使います:
+
+```
+(ring 10, 20, 30, 40, 50).reverse  #=> (ring 50, 40, 30, 20, 10)
+```
+
+では次に、リングから最初の3つの値を取得するにはどうしたらよいでしょう?
+
+```
+(ring 10, 20, 30, 40, 50).take(3)  #=> (ring 10, 20, 30)
+```
+
+最後に、リングをシャッフルするにはどうしたらよいでしょう?
+
+```
+(ring 10, 20, 30, 40, 50).shuffle  #=> (ring 40, 30, 10, 50, 20)
+```
+
+## 多重チェーン
+
+ここまでで既に強力なリングの作成方法を見てきましたが、
+これらのコマンドを一緒に用いることで本当の力を発揮します。
+
+リングをシャッフルし、最初の要素を削除し、次の3つの要素を得る場合にはどうでしょう?
+
+段階的に見ていきましょう:
+
+1. `(ring 10, 20, 30, 40, 50)` - リングの最初の状態
+2. `(ring 10, 20, 30, 40, 50).shuffle` - シャッフルし - `(ring 40, 30, 10, 50, 20)`
+3. `(ring 10, 20, 30, 40, 50).shuffle.drop(1)` - 最初の要素を削除し - `(ring 30, 10, 50, 20)`
+4. `(ring 10, 20, 30, 40, 50).shuffle.drop(1).take(3)` - 3つの要素を得る - `(ring 30, 10, 50)`
+
+*コマンドを一緒にくっつける*だけでこれらのコマンドの長いチェーンを作ることが分かったと思います。
+チェーンコマンドを好きな順序で組み合わせることができ、それにより既に存在するリングから新しいリングを
+生成するとても豊かで強力な方法を作り出しています。
+
+## 不変性
+
+リングは強力で重要な特徴を持っています。それは不変性と言って、リングを変更できないということを
+意味しています。このセクションで紹介しているチェインコマンドが*リングを変更するのではなく*、
+*新しいリングを作成*していることを意味しています。これにより、スレッドを跨いでリングを共有して、
+同じリングを使っている他のスレッドに影響を与えないで、チェインを開始できることを意味しています。
+
+## 利用可能なチェーンコマンド
+
+ここに利用可能なチェーンコマンドを記載しておきます。
+
+* `.reverse` - 逆順のリングを返却します
+* `.sort`    - ソートされたリングを作成します
+* `.shuffle` - シャッフルされたリングを作成します
+* `.take(5)` - 最初の5つの要素をのみからなる新しいリングを返却します
+* `.drop(3)` - 最初の3つの要素以外の要素からなる新しいリングを返却します
+* `.butlast` - 最後の要素が欠けた状態の新しいリングをを返却します
+* `.drop_last(3)` - 最後の3つの要素が欠けた状態の新しいリングをを返却します
+* `.take_last(6)`- 最後の6つの要素をのみからなる新しいリングを返却します
+* `.stretch(2)` - リングの個々の要素を2回ずつ繰り返します
+* `.repeat(3)` - リング全体を3回繰り返します
+* `.mirror` - 逆順のリングを自分自身に追加します
+* `.reflect` - mirrorと同様ですが、真ん中の要素を重複させないようにします
+
+数字を引数に取っているチェーンコマンドは、他の数字を取ることももちろん可能です。
+最初の5個の要素を削除したい場合には、`.drop(3)`の代わりに遠慮無く`.drop(5)`を呼んでください。
diff --git a/etc/doc/tutorial/ja/09.4-Ticking.md b/etc/doc/tutorial/ja/09.4-Ticking.md
new file mode 100644
index 0000000..b7a61c1
--- /dev/null
+++ b/etc/doc/tutorial/ja/09.4-Ticking.md
@@ -0,0 +1,87 @@
+9.4 チック
+
+# チック
+
+ライブコーディングでリングをループしていて、気が付くとたくさんのことをしていたことはないでしょうか。
+例えば、リングにメロディーの音符を入れたり、リズムのスリープ、
+コード進行や音色のバリエーションを入れたり等々。
+
+## リングのチック
+
+Sonic Piは`live_loop`内でリングと共に使える*とても*手軽なツールを提供しています。
+それはチックシステムと呼ばれ、*tick through rings(リングをチックタックと進める)*
+機能を提供しています。次の例を見てください。
+
+```
+live_loop :arp do
+  play (scale :e3, :minor_pentatonic).tick, release: 0.1
+  sleep 0.125
+end
+```
+
+ここでは、E3マイナーペンタトニックのスケールを作成し、各要素をチックしています。これは`.tick`を
+スケール宣言の末尾に追加することによって実現されています。このチックはライブループ内で局所的であるため、
+個々のライブループは独立したチックを持つことができます。
+
+```
+live_loop :arp do
+  play (scale :e3, :minor_pentatonic).tick, release: 0.1
+  sleep 0.125
+end
+
+live_loop :arp2 do
+  use_synth :dsaw
+  play (scale :e2, :minor_pentatonic, num_octaves: 3).tick, release: 0.25
+  sleep 0.25
+end
+```
+
+## 標準関数としてのチック
+
+`tick`はまた標準関数としても呼ぶことができ、その値はインデックスとして使うことができます。
+
+```
+live_loop :arp do
+  idx = tick
+  play (scale :e3, :minor_pentatonic)[idx], release: 0.1
+  sleep 0.125
+end
+```
+
+しかし、この場合は`.tick`を呼ぶほうが良いでしょう。`tick`関数の用途は、
+チックの値で手の込んだことをしたかったり、リングのインデックス以外のことにチックの値を使いたかったりする場合です。
+
+## ルック
+
+チックの魅力的なところはそれが新しいインデックス(もしくはそのインデックスにあるリングの値)
+を返すだけでなく、次にチックを呼んだときに必ず次の値を返すことを保証していることでしょう。
+`tick`が色んな形でこのような動作をしていることをこのドキュメントの例で見てみてください。
+しかし、ここでチックの現在の値を見たいだけで値を*増加させたくない*の場合もあることを指摘することは重要でしょう。
+これは`look`関数により実現可能です。`look`を標準関数として呼んだり、リングの後ろに`.look`を付けたりできます。
+
+## チックの名前付け
+
+最後に、1つのライブループに複数のチックが必要になることがあるかも
+しれません。これはチックに名前を付けることで実現できます。
+
+```
+live_loop :arp do
+  play (scale :e3, :minor_pentatonic).tick(:foo), release: 0.1
+  sleep (ring 0.125, 0.25).tick(:bar)
+end
+```
+
+ここでは2つのチックを使っていて、1つは音符用に、1つはスリープ時間用にしています。
+これらのチックは同じライブループにあるので、別々にしておくためにユニークな名前を与えています。
+これはちょうど`live_loop`に名前を付ける(`:`から始まるシンボル名を渡すだけ)のと同じことです。
+上の例では1つは`:foo`でチックを呼び出し、もう1つは`:bar`で呼び出しています。
+また、これらの値を`look`したい場合には、チックの名前を`look`に渡す必要があります。
+
+## 複雑にしすぎないように
+
+チックシステムの能力のほどんどは、最初のうちは役に立たないでしょう。
+このセクションの全ての内容を学習しようとしないでください。
+一つのリングでチックすることだけに集中するとよいでしょう。
+そうすることで、`live_loop`でリングをチックする簡単さや楽しみを得ることができるでしょう。
+
+`tick`のドキュメントには役に立つ例がたくさんあるので、それを見て楽しくチックしてみましょう!
diff --git a/etc/doc/tutorial/pl/03.7-Sample-Filters.md b/etc/doc/tutorial/pl/03.7-Sample-Filters.md
new file mode 100644
index 0000000..c9a402c
--- /dev/null
+++ b/etc/doc/tutorial/pl/03.7-Sample-Filters.md
@@ -0,0 +1,217 @@
+3.7 Sample Packs
+
+# Sample Packs
+
+**Note: this section of the tutorial covers the advanced topic of
+working with large directories of your own samples. This will be the
+case if you've downloaded or bought your own sample packs and wish to
+use them within Sonic Pi.**
+
+**Feel free to skip this if you're happy working with the built-in
+samples.**
+
+When working with large folders of external samples it can be cumbersome
+to have to type the whole path every time to trigger an individual
+sample.
+
+For example, say you have the following folder on your machine:
+
+```
+/path/to/my/samples/
+```
+
+When we look inside that folder we find the following samples:
+
+* `100_A#_melody1.wav`
+* `100_A#_melody2.wav`
+* `100_A#_melody3.wav`
+* `120_A#_melody4.wav`
+* `120_Bb_guit1.wav`
+* `120_Bb_piano1.wav`
+
+Typically in order to play the piano sample we can use the full path:
+
+```
+sample "/path/to/my/samples/120_Bb_piano1.wav"
+```
+
+If we want to then play the guitar sample we can use its full path too:
+
+```
+sample "/path/to/my/samples/120_Bb_guit.wav"
+```
+
+However, both of these calls to sample requires us to *know* the names
+of the samples within our directory. What if we just want to listen to
+each sample in turn quickly? 
+
+## Indexing Sample Packs
+
+If we want to play the first sample in a directory we just need to pass
+the directory's name to `sample` and the index `0` as follows:
+
+```
+sample "/path/to/my/samples/", 0
+```
+
+We can even make a shortcut to our directory path using a variable:
+
+```
+samps = "/path/to/my/samples/"
+sample samps, 0
+```
+
+Now, if we want to play the second sample in our directory, we just need
+to add 1 to our index:
+
+```
+samps = "/path/to/my/samples/"
+sample samps, 1
+```
+
+Notice that we no longer need to know the names of the samples in the
+directory - we just need to know the directory itself (or have a
+shortcut to it). If we ask for an index which is larger than the number
+of samples, it simply wraps round just like Rings. Therefore, whatever
+number we use we're guaranteed to get one of the samples in that
+directory.
+
+## Filtering Sample Packs
+
+Ususally indexing is enough, but sometimes we need more power to sort
+and organise our samples. Luckily many sample packs add useful
+information in the filenames. Let's take another look at the sample file
+names in our directory:
+
+* `100_A#_melody1.wav`
+* `100_A#_melody2.wav`
+* `100_A#_melody3.wav`
+* `120_A#_melody4.wav`
+* `120_Bb_guit1.wav`
+* `120_Bb_piano1.wav`
+
+Notice that in these filenames we have quite a bit of
+information. Firstly, we have the BPM of the sample (beats per minute)
+at the start. So, the piano sample is at 120 BPM and our first three
+melodies are at 100 BPM. Also, our sample names containtain the key. So
+the guitar sample is in Bb and the melodies are in A#. This information
+is very useful for mixing in these samples with our other code. For
+example, we know we can only play the piano sample with code that's in
+120 BPM and in the key of Bb.
+
+It turns out that we can use this particular naming convention of our
+sample sets in the code to help us filter out the ones we want. For
+example, if we're working at 120 BPM, we can filter down to all the
+samples that contain the string `"120"` with the following:
+
+```
+samps = "/path/to/my/samples/"
+sample samps, "120"
+```
+
+This will play us the first match. If we want the second match we just
+need to use the index:
+
+```
+samps = "/path/to/my/samples/"
+sample samps, "120", 1
+```
+
+We can even use multiple filters at the same time. For example, if we
+want a sample that's filename contains both the substring "120" and "A#"
+we can find it easily with the following code:
+
+```
+samps = "/path/to/my/samples/"
+sample samps, "120", "A#"
+```
+
+Finally, we're still free to add our usual opts to the call to `sample`:
+
+```
+samps = "/path/to/my/samples/"
+sample samps, "120", "Bb", 1, lpf: 70, amp: 2
+```
+
+## Sources
+
+The sample filter pre-arg system understands two types of information:
+sources and filters. Sources are information used to create the list of
+potential candidates. A source can take two forms:
+
+1. "/path/to/samples" - a string representing a valid path to a directory 
+2. "/path/to/samples/foo.wav" - a string representing a valid path to a sample
+
+The `sample` fn will first gather all sources and use them to create a
+large list of candidates. This list is constructed by first adding all
+valid paths and then by adding all the valid `.flac`, `.aif`, `.aiff`,
+`.wav`, `.wave` files contained within the directories.
+
+For example, take a look at the following code:
+
+```
+samps = "/path/to/my/samples/"
+samps2 = "/path/to/my/samples2/"
+path = "/path/to/my/samples3/foo.wav"
+
+sample samps, samps2, path, 0
+```
+
+Here, we're combining the contents of the samples within two directories
+and adding a specific sample. If `"/path/to/my/samples/"` contained 3
+samples and `"/path/to/my/samples2/"` contained 12, we'd have 16
+potential samples to index and filter (3 + 12 + 1).
+
+By default, only the sample files within a directory are gathered into
+the candidate list. Sometimes you might have number of nested folders of
+samples you wish to search and filter within. You can therefore do a
+recursive search for all samples within all subfolders of a particular
+folder by adding `**` to the end of the path:
+
+```
+samps = "/path/to/nested/samples/**"
+sample samps, 0
+```
+
+Take care though as searching through a very large set of folders may
+take a long time. However, the contents of all folder sources are
+cached, so the delay will only happen the first time.
+
+
+## Filters
+
+Once you have a list of candidates you may use the following filtering
+types to further reduce the selection:
+
+* `"foo"` Strings will filter on substring occurrance within file name (minus directory path and extension).
+* `/fo[oO]/` Regular Expressions will filter on pattern matching of file name (minus directory path and extension).
+* `:foo` - Keywords will filter candidates on whether the keyword is a direct match of the filename (minus directory path and extension).
+* `lambda{ "foo" }` - Procs with no arguments will be automatically called and their result be treated as a source or filter.
+* `lambda{|a| ... }` - Procs with one argument will be treated as a candidate filter or genrator function. It will be passed the list of current candidates and must return a new list of candidates (a list of valid paths to sample files).
+* `1` - Numbers will select the candidate with that index (wrapping round like a ring if necessary).
+
+## Composites
+
+Finally, you may use lists wherever you may place a source or
+filter. The list will be automatically flattened and the contents be
+treated as regular sources and filters. Therefore the following calls to
+`sample` are semantically equivalent:
+
+```
+sample "/path/to/dir", "100", "C#"
+sample ["/path/to/dir", "100", "C#"]
+sample "/path/to/dir", ["100", "C#"]
+sample ["/path/to/dir", ["100", ["C#"]]]
+```
+
+## Wrapping Up
+
+This was an advanced section for people that need real power to
+manipulate and use sample packs. If most of this section didn't make too
+much sense, don't worry. It's likely you don't need any of this
+functionality just yet. However, you'll know when you do need it and you
+can come back and re-read this when you start working with large
+directories of samples.
+
+
+
diff --git a/etc/doc/tutorial/pl/08.5-Ring-Chains.md b/etc/doc/tutorial/pl/08.5-Ring-Chains.md
new file mode 100644
index 0000000..fc88fff
--- /dev/null
+++ b/etc/doc/tutorial/pl/08.5-Ring-Chains.md
@@ -0,0 +1,92 @@
+8.5 Łańcuchy Pierścieni (Ring Chains)
+
+Oprócz konstruktorów takich jak `range` i `spread` innym sposobem 
+tworzenia nowych pierścieni jest manipulowanie i modyfikacja istniejących 
+pierścieni (rings).
+
+## Łańcuchy poleceń (Chain Commands)
+
+Aby zbadać ten temat stwórzmy prosty pierścień: 
+
+```
+(ring 10, 20, 30, 40, 50)
+```
+
+Co jeśli chcielibyśmy otrzymać wszystkie elementy tego pierścienia 
+w odwrotnej kolejności? Wystarczy, że użyjemy w łańuchu poleceń 
+`.reverse` aby wziąć nasz pierścień i odwrócić go:
+
+```
+(ring 10, 20, 30, 40, 50).reverse  #=> (ring 50, 40, 30, 20, 10)
+```
+
+A co, jeśli teraz potrzebujemy tylko pierwsze trzy elementy 
+z naszego pierścienia?
+
+```
+(ring 10, 20, 30, 40, 50).take(3)  #=> (ring 10, 20, 30)
+```
+
+I na koniec jeszcze jedno, co jeśli chcielibyśmy przetasować 
+elementy naszego pierścienia tak jak tasujemy karty przed grą?
+
+```
+(ring 10, 20, 30, 40, 50).shuffle  #=> (ring 40, 30, 10, 50, 20)
+```
+
+## Wiele Łańcuchów
+
+Powyższe polecenia dają bardzo duże możliwości tworzenia nowych pierścieni (rings). 
+Jednakże, *prawdziwa* moc pojawia się dopiero w momencie, gdy połączysz kilka 
+poleceni w jeden łańcuch.
+
+Co powiesz na to aby najpierw przetasować pierścień, potem usunać z niego 
+1 element i z elementów, które pozostały wybrać tylko pierwsze 3?
+
+Zróbmy to krok po kroku: 
+
+1. `(ring 10, 20, 30, 40, 50)` - nasz początkowy pierścień
+2. `(ring 10, 20, 30, 40, 50).shuffle` - tasujemy - `(ring 40, 30, 10, 50, 20)`
+3. `(ring 10, 20, 30, 40, 50).shuffle.drop(1)` - usuwamy 1-wszy element - `(ring 30, 10, 50, 20)`
+4. `(ring 10, 20, 30, 40, 50).shuffle.drop(1).take(3)` - pozostawiamy tylko pierwsze 3 - `(ring 30, 10, 50)`
+
+Widzisz jak łatwo możemy stworzyć długi łańcuch tych metod  *sklejając 
+je po prostu razem*? Możemy użyć tych metod w dowolnej kolejności 
+na jaką nas tylko najdzie ochota. Dzięki temu mamy bardzo bogatą 
+i potężną paletę sposobów, dzięki którym możemy tworzyć nowe pierścienie 
+z już istniejących.
+
+## Niezmienność
+
+Pierścienie posiadają pewną potężną i ważną cechę. Są niezmienne co 
+oznacza, że gdy raz zostaną już utworzone to nie mogą zostać zmienione. 
+Z tego wynika, że łańcuchy wywołań metod opisane w tym rozdziale 
+*nie zmieniają pierścieni* lecz *tworzą nowe pierścienie*. Dzięki takiemu 
+podejśćiu nic nie stoi na przeszkodzie abyś mógł współdzielić dany 
+pierścień pomiędzy różnymi wątkami i wywyływać na nim łańcuchy metod 
+w ramach jednego wątku, gdyż wiesz że nie wpłynie to w żaden sposób 
+na jakikolwiek inny wątek, który korzysta z tego samego pierścienia.
+
+## Dostępne Łańcuchy Metod
+
+Oto lista metod, które możesz łączyć w łańcuchy wywołań:
+
+* `.reverse` - zwraca odwróconą wersję pierścienia
+* `.sort`    - tworzy posortowaną wersję pierścienia
+* `.shuffle` - tworzy pierścień z wartościami, które są przetasowane
+* `.pick(3)` - zwraca pierścień, który zawiera 3 losowo wybrane elementy z oryginalnego pierścienia (działanie analogiczne do funkcji `choose`)
+* `.pick`    - działanie analogiczne do funkcji `.pick(3)`, z tym że w tym przypadku liczba wylosowanych elementów jest równa ilości elementów znajdujących się w oryginalnym pierścieniu  
+* `.take(5)` - zwraca nowy pierścień, który zawiera tylko 5 pierwszych elementów
+* `.drop(3)` - zwraca nowy pierścień, który zawiera wszystkie elementy oprócz pierwszych 3 
+* `.butlast` - zwraca nowy pierścień, który nie zawiera ostatniego elementu 
+* `.drop_last(3)` - zwraca nowy pierścień, kóry nie zawiera 3 ostatnich elementów
+* `.take_last(6)`- zwraca nowy pierścień, który posiada tylko 6 ostatnich elementów
+* `.stretch(2)` - powtarza każdy z elementów w pierścieniu dwukrotnie
+* `.repeat(3)` - powtarza cały pierścień trzykrotnie
+* `.mirror` - dodaje pierścień do odwróconej wersji samego siebie
+* `.reflect` - działa tak samo jak mirror, ale nie powtarza środkowej wartości z pierścienia
+
+Oczywiście, metody które przyjmują jako parametr liczbę, mogą przyjmować 
+też inne liczby! Nie krępuj się więc i spróbuj wywołać metodę `.drop(5)` 
+zamiast widocznej parę linijek wyżej metody `.drop(3)`. Pozwoli Ci to stworzyć 
+nową listę, która nie będzie zawierała 5 pierwszych elementów.
diff --git a/etc/doc/tutorial/pl/09.2-Live-Loops.md b/etc/doc/tutorial/pl/09.2-Live-Loops.md
index e1976aa..50f1135 100644
--- a/etc/doc/tutorial/pl/09.2-Live-Loops.md
+++ b/etc/doc/tutorial/pl/09.2-Live-Loops.md
@@ -25,10 +25,6 @@ Naciśnij przycisk Run. Słyszysz podstawowy bip przy każdym uderzeniu.
 Nic szczególnego. Powstrzymaj się jednak i nie naciskaj jeszcze przycisku 
 Stop. Zmień wartość `60` na `65` i naciśnij przycisk Run jeszcze raz. 
 
-Now press the Run button. You hear a basic beep every beat. Nothing
-fun there. However, don't press Stop just yet. Change the `60` to `65`
-and press Run again.
-
 Łał! Brzmienie zmieniło się *automatycznie* bez utraty żadnego uderzenia. 
 
 Czemu więc nie spróbować zmienić ten kawałek aby brzmiał trochę bardziej jak linia 
diff --git a/etc/doc/tutorial/pl/10.2-Shortcut-Cheatsheet.md b/etc/doc/tutorial/pl/10.2-Shortcut-Cheatsheet.md
index 1be25ae..4dfb9e0 100644
--- a/etc/doc/tutorial/pl/10.2-Shortcut-Cheatsheet.md
+++ b/etc/doc/tutorial/pl/10.2-Shortcut-Cheatsheet.md
@@ -20,10 +20,10 @@ W poniższej liście używamy następujących konwencji (gdzie *Meta* oznacza kl
 * `C-M-f` oznacza naciśnij i przytrzymaj klawisz *Control*, potem naciśnij i przytrzymaj klawisz *Meta*, po czym 
   na końcu naciśnij do tego jeszcze klawisz *f* i puść wszystkie klawisze.
 
-## Postawowe Manipulowanie AplikacjÄ…
+## Podstawowe Manipulowanie AplikacjÄ…
 
 * `M-r` - Uruchom kod (przycisk Run)
-* `M-s` - Zatrzymaj przycisk (przycisk Stop)
+* `M-s` - Zatrzymaj kod (przycisk Stop)
 * `M-i` - Otwórz/Zamknij System Pomocy
 * `M-p` - Otwórz/Zamknij Ustawienia
 * `M-{` - Przejdź do buforu po lewej stronie
diff --git a/etc/doc/tutorial/en/A-Articles.md b/etc/doc/tutorial/pl/A-Articles.md
similarity index 100%
copy from etc/doc/tutorial/en/A-Articles.md
copy to etc/doc/tutorial/pl/A-Articles.md
diff --git a/etc/doc/tutorial/en/A.01-tips.md b/etc/doc/tutorial/pl/A.01-tips.md
similarity index 100%
copy from etc/doc/tutorial/en/A.01-tips.md
copy to etc/doc/tutorial/pl/A.01-tips.md
diff --git a/etc/doc/tutorial/en/A.02-live-coding.md b/etc/doc/tutorial/pl/A.02-live-coding.md
similarity index 100%
copy from etc/doc/tutorial/en/A.02-live-coding.md
copy to etc/doc/tutorial/pl/A.02-live-coding.md
diff --git a/etc/doc/tutorial/en/A.03-coded-beats.md b/etc/doc/tutorial/pl/A.03-coded-beats.md
similarity index 100%
copy from etc/doc/tutorial/en/A.03-coded-beats.md
copy to etc/doc/tutorial/pl/A.03-coded-beats.md
diff --git a/etc/doc/tutorial/en/A.04-synth-riffs.md b/etc/doc/tutorial/pl/A.04-synth-riffs.md
similarity index 100%
copy from etc/doc/tutorial/en/A.04-synth-riffs.md
copy to etc/doc/tutorial/pl/A.04-synth-riffs.md
diff --git a/etc/doc/tutorial/en/A.05-acid-bass.md b/etc/doc/tutorial/pl/A.05-acid-bass.md
similarity index 100%
copy from etc/doc/tutorial/en/A.05-acid-bass.md
copy to etc/doc/tutorial/pl/A.05-acid-bass.md
diff --git a/etc/doc/tutorial/pl/A.06-minecraft.md b/etc/doc/tutorial/pl/A.06-minecraft.md
new file mode 100644
index 0000000..6bc6ded
--- /dev/null
+++ b/etc/doc/tutorial/pl/A.06-minecraft.md
@@ -0,0 +1,184 @@
+A.6 Musical Minecraft 
+
+# Musical Minecraft
+
+
+
+Hello and welcome back! In the previous tutorials we've focussed purely
+on the music possibilities of Sonic Pi - (turning your Raspberry Pi into
+a performance ready musical instrument). So far we've learned how to:
+
+* Live Code - changing the sounds on-the-fly,
+* Code some huge beats,
+* Generate powerful synth leads,
+* Re-create the famous TB-303 acid-bass sound.
+
+There's so much more to show you (which we will explore in future
+editions). However, this month, let's look at something Sonic Pi can do
+that you probably didn't realise: control Minecraft.
+
+# Hello Minecraft World
+
+OK, let's get started. Boot up your Raspberry Pi, fire up Minecraft Pi
+and create a new world. Now start up Sonic Pi and re-size and move your
+windows so you can see both Sonic Pi and Minecraft Pi at the same time.
+
+In a fresh buffer type the following:
+
+    mc_message "Hello Minecraft from Sonic Pi!"
+    
+Now, hit Run. Boom! Your message appeared in Minecraft! How easy was
+that? Now, stop reading this for a moment and play about with your own
+messages. Have fun!
+
+![Screen 0](../images/tutorial/articles/A.06-minecraft/Musical-Minecraft-0-small.png)
+
+# Sonic Teleporter
+
+Now let's do some exploring. The standard option is to reach for the
+mouse and keyboard and start walking around. That works, but it's pretty
+slow and boring. It would be far better if we had some sort of teleport
+machine. Well, thanks to Sonic Pi, we have one. Try this:
+
+    mc_teleport 80, 40, 100
+    
+Crikey! That was a long way up. If you weren't in flying-mode then you
+would have fallen back down all the way to the ground. If you double-tap
+space to enter flying-mode and teleport again, you'll stay hovering at
+the location you zap to.
+
+Now, what do those numbers mean? We have three numbers which describe
+the coordinates of where in the world we want to go. We give each number
+a name - x, y and z:
+
+* x - how far left and right (80 in our example)
+* y - how high we want to be (40 in our example)
+* z - how far forward and back (100 in our example)
+
+By choosing different values for x, y and z we can teleport *anywhere*
+in our world. Try it! Choose different numbers and see where you can end
+up. If the screen goes black it's because you've teleported yourself
+under the ground or into a mountain. Just choose a higher y value to get
+back out above land. Keep on exploring until you find somewhere you
+like...
+
+Using the ideas so far, let's build a Sonic Teleporter which makes a fun
+teleport sound whilst it whizzes us across the Minecraft world:
+
+    mc_message "Preparing to teleport...."
+    sample :ambi_lunar_land, rate: -1
+    sleep 1
+    mc_message "3"
+    sleep 1
+    mc_message "2"
+    sleep 1
+    mc_message "1"
+    sleep 1
+    mc_teleport 90, 20, 10
+    mc_message "Whoooosh!"
+    
+![Screen 1](../images/tutorial/articles/A.06-minecraft/Musical-Minecraft-1-small.png)
+
+# Magic Blocks
+
+Now you've found a nice spot, let's start building. You could do what
+you're used to and start clicking the mouse furiously to place blocks
+under the cursor. Or you could use the magic of Sonic Pi. Try this:
+
+    x, y, z = mc_location
+    mc_set_block :melon, x, y + 5, z
+
+Now look up! There's a melon in the sky! Take a moment to look at the
+code. What did we do? On line one we grabbed the current location of
+Steve as the variables x, y and z. These correspond to our coordinates
+described above. We use these coordinates in the fn `mc_set_block` which
+will place the block of your choosing at the specified coordinates. In
+order to make something higher up in the sky we just need to increase
+the y value which is why we add 5 to it. Let's make a long trail of them:
+
+    live_loop :melon_trail do
+      x, y, z = mc_location
+      mc_set_block :melon, x, y-1, z
+      sleep 0.125
+    end
+
+Now, jump over to Minecraft, make sure you're in flying-mode (double tap
+space if not) and fly all around the world. Look behind you to see a
+pretty trail of melon blocks! See what kind of twisty patterns you can
+make in the sky.
+
+# Live Coding Minecraft
+
+Those of you that have been following this tutorial over the last few
+months will probably have your minds blown at this point. The trail of
+melons is pretty cool, but the most exciting part of the previous
+example is that you can use `live_loop` with Minecraft! For those that
+don't know, `live_loop` is Sonic Pi's special magic ability that no
+other programming language has. It lets you run multiple loops at the
+same time and allows you to change them whilst they run. They are
+incredibly powerful and amazing fun. I use `live_loop`s to perform music
+in nightclubs with Sonic Pi - DJs use discs and I use `live_loop`s :-)
+However, today we're going to live code both music and Minecraft.
+
+Let's get started. Run the code above and start making your melon
+trail again. Now, without stopping the code, just simply change `:melon` to
+`:brick` and hit run. Hey presto, you're now making a brick trail. How
+simple was that! Fancy some music to go with it? Easy. Try this:
+
+    live_loop :bass_trail do
+      tick
+      x, y, z = mc_location
+      b = (ring :melon, :brick, :glass).look
+      mc_set_block b, x, y -1, z
+      note = (ring :e1, :e2, :e3).look
+      use_synth :tb303
+      play note, release: 0.1, cutoff: 70
+      sleep 0.125
+    end
+    
+Now, whilst that's playing start changing the code. Change the block
+types - try `:water`, `:grass` or your favourite block type. Also, try
+changing the cutoff value from `70` to `80` and then up to `100`. Isn't
+this fun?
+
+# Bringing it all together
+
+![Screen 2](../images/tutorial/articles/A.06-minecraft/Musical-Minecraft-2-small.png)
+
+Let's combine everything we've seen so far with a little extra
+magic. Let's combine our teleportation ability with block placing and
+music to make a Minecraft Music Video. Don't worry if you don't
+understand it all, just type it in and have a play by changing some of
+the values whilst it's running live. Have fun and see you next time...
+    
+
+    live_loop :note_blocks do
+      mc_message "This is Sonic Minecraft"
+      with_fx :reverb do
+        with_fx :echo, phase: 0.125, reps: 32 do
+          tick
+          x = (range 30, 90, step: 0.1).look
+          y = 20
+          z = -10
+          mc_teleport x, y, z
+          ns = (scale :e3, :minor_pentatonic)
+          n = ns.shuffle.choose
+          bs = (knit :glass, 3, :sand, 1)
+          b = bs.look
+          synth :beep, note: n, release: 0.1
+          mc_set_block b, x+20, n-60+y, z+10
+          mc_set_block b, x+20, n-60+y, z-10
+          sleep 0.25
+        end
+      end
+    end
+    
+    live_loop :beats do
+      sample :bd_haus, cutoff: 100
+      sleep 0.5
+    end
+          
+
+
+
+
diff --git a/etc/doc/tutorial/en/A.07-bizet.md b/etc/doc/tutorial/pl/A.07-bizet.md
similarity index 100%
copy from etc/doc/tutorial/en/A.07-bizet.md
copy to etc/doc/tutorial/pl/A.07-bizet.md
diff --git a/etc/doc/tutorial/en/A.08-minecraft-vj.md b/etc/doc/tutorial/pl/A.08-minecraft-vj.md
similarity index 100%
copy from etc/doc/tutorial/en/A.08-minecraft-vj.md
copy to etc/doc/tutorial/pl/A.08-minecraft-vj.md
diff --git a/etc/doc/tutorial/pl/A.09-randomisation.md b/etc/doc/tutorial/pl/A.09-randomisation.md
new file mode 100644
index 0000000..ee06487
--- /dev/null
+++ b/etc/doc/tutorial/pl/A.09-randomisation.md
@@ -0,0 +1,180 @@
+A.9 Randomisation
+
+# Surfing Random Streams
+
+Back in episode 4 of this tutorial series we took a brief look at
+randomisation whilst coding up some sizzling synth riffs. Given that
+randomisation is such an important part of my live coding DJ sets I
+thought it would be useful to cover the fundamentals in much greater
+detail. So, get your lucky hat on and let's surf some random streams!
+
+# There is no random
+
+The first thing to learn which might really surprise you when playing
+with Sonic Pi's randomisation functions is that they're not actually
+really random. What does this actually mean? Well, let's try a couple of
+tests. First, imagine a number in your head between 0 and 1. Keep it
+there and don't tell me. Now let me guess... was it `0.321567`? No? Bah,
+I'm clearly no good at this. Let me have another go, but let's ask Sonic
+Pi to choose a number this time. Fire up Sonic Pi v2.7+ and ask it for a
+random number but again don't tell me:
+
+    print rand
+    
+Now for the reveal... was it `0.75006103515625`? Yes! Ha, I can see
+you're a little sceptical. Perhaps it was just a lucky guess. Let's try
+again. Press the Run button again and see what we get... What?
+`0.75006103515625` again? This clearly can't be random! You're right,
+it's not.
+
+What's going on here? The fancy computer science word here is
+determinism. This just means that nothing is by chance and everything is
+destined to be. Your version of Sonic Pi is destined to always return
+`0.75006103515625` in the program above. This might sound pretty
+useless, but let me assure you that it's one of the most powerful parts
+of Sonic Pi. If you stick at it you'll learn how to rely on the
+deterministic nature of Sonic Pi's randomisation as a fundamental
+building block to your compositions and live coded DJ sets.
+
+# A Random Melody
+
+When Sonic Pi boots it actually loads into memory a sequence of 441,000
+pre-generated random values. When you call a random function such as
+`rand` or `rrand`, this random stream is used to generate your
+result. Each call to a random function consumes a value from this
+stream. Therefore the 10th call to a random function will use the 10th
+value from the stream. Also, every time you press the Run button, the
+stream is reset for that run. This is why I could predict the result to
+`rand` and why the 'random' melody was the same every time. Everybody's
+version of Sonic Pi uses the exact same random stream which is very
+important when we start sharing our pieces with each other. 
+
+Let's use this knowledge to generate a repeatable random melody:
+
+    8.times do
+     play rrand_i(50, 95)
+     sleep 0.125
+    end
+
+Type this into a spare buffer and hit Run. You'll hear a melody
+consisting of 'random' notes between 50 and 95. When it's finished, hit
+Run again to hear exactly the same melody again.
+
+*start breakout box*
+## Handy Randomisation Functions
+ Sonic Pi comes with a number of useful functions for working with the
+random stream. Here's a list of some of the most useful:
+
+* `rand` - Simply returns the next value in the random stream
+* `rrand` - Returns a random value within a range
+* `rrand_i` - Returns a random whole number within a range
+* `one_in` - Returns true or false with the given probability
+* `dice` - Imitates rolling a dice and returns a value between 1 and 6
+* `choose` - Chooses a random value from a list
+
+Check out their documentation in the Help system for detailed
+information and examples.
+
+ *end breakout box*
+
+# Resetting the Stream
+
+Whilst the ability to repeat a sequence of chosen notes is essential to
+allow you to replay a riff on the dance floor, it might not be the
+exactly riff you want. Wouldn't it be great if we could try a number of
+different riffs and choose the one we liked best? This is where the real
+magic starts.
+
+We can manually set the stream with the fn `use_random_seed`. In
+Computer Science, a random seed is the starting point from which a new
+stream of random values can sprout out and blossom. Let's try it:
+
+    use_random_seed 0
+    3.times do
+      play rrand_i(50, 95)
+      sleep 0.125
+    end
+    
+Great, we get the first three notes of our random melody above: `84`,
+`83` and `71`. However, we can now change the seed to something
+else. How about this:
+
+    use_random_seed 1
+    3.times do
+      play rrand_i(50, 95)
+      sleep 0.125
+    end
+    
+    
+Interesting, we get `83`, `71` and `61` . You might notice that the
+first two numbers here are the same as the last two numbers before -
+this isn't a coincidence.
+
+Remember that the random stream is just a giant list of 'pre-rolled'
+values. Using a random seed simply jumps us to a point in that
+list. Another way of thinking about it is to imagine a huge deck of
+pre-shuffled cards. Using a random seed is cutting the deck at a
+particular point. The fabulous part of this is that it's precisely this
+ability to jump around the random which gives us huge power when making
+music.
+
+Let's revisit our random melody of 8 notes with this new stream
+resetting power, but let's also throw in a live loop so we can
+experiment live whilst it's playing:
+
+    live_loop :random_riff do    
+      use_random_seed 0
+      8.times do
+        play rrand_i(50, 95), release: 0.1
+        sleep 0.125
+      end
+    end
+
+Now, whilst it's still playing, change the seed value from `0` to
+something else. Try `100`, what about `999`. Try your own values,
+experiment and play around - see which seed generates the riff you like
+best.
+
+# Bringing it all together
+
+This month's tutorial has been quite a technical dive into the workings
+of Sonic Pi's randomisation functionality. Hopefully it has given you
+some insight into how it works and how you can start using randomisation
+in a reliable way to create repeatable patterns within your music. It's
+important to stress that you can use repeatable randomisation *anywhere*
+you want. For example, you can randomise the amplitude of notes, the
+timing of the rhythm, the amount of reverb, the current synth, the mix
+of an FX, etc. etc. In the future we'll take a close look at some of
+these applications, but for now let me leave you with a short example.
+
+Type the following into a spare buffer, hit Run, and then start changing
+the seeds around, hit Run again (whilst it's still playing) and explore
+the different sounds, rhythms and melodies you can make. When you find a
+nice one, remember the seed number so you can get back to it. Finally,
+when you've found a few seeds you like, put on a live coded performance
+for your friends by simply switching between your favourite seeds to
+create a full piece.
+
+live_loop :random_riff do
+  use_random_seed 10300
+  use_synth :prophet
+  s = [0.125, 0.25, 0.5].choose
+  8.times do
+    r = [0.125, 0.25, 1, 2].choose
+    n = (scale :e3, :minor).choose
+    co = rrand(30, 100)
+    play n, release: r, cutoff: co
+    sleep s
+  end
+end
+
+live_loop :drums do
+  use_random_seed 2001
+  16.times do
+    r = rrand(0.5, 10)
+    sample :drum_bass_hard, rate: r, amp: rand
+    sleep 0.125
+  end
+end
+
+
diff --git a/etc/doc/tutorial/pl/A.10-controlling-your-sound.md b/etc/doc/tutorial/pl/A.10-controlling-your-sound.md
new file mode 100644
index 0000000..2961aff
--- /dev/null
+++ b/etc/doc/tutorial/pl/A.10-controlling-your-sound.md
@@ -0,0 +1,182 @@
+A.10 Control
+
+# Controlling Your Sound
+
+So far during this series we've focussed on triggering sounds. We've
+discovered that we can trigger the many synths built into Sonic Pi with
+`play` or `synth` and how to trigger pre-recorded samples with
+`sample`. We've also looked at how we can wrap these triggered sounds
+within studio FX such as reverb and distortion using the `with_fx`
+command. Combine this with Sonic Pi's incredibly accurate timing system
+and you can produce a vast array of sounds, beats and riffs. However,
+once you've carefully selected a particular sound's options and
+triggered it, there's no ability to mess with it whilst it's playing
+right? Wrong! Today you're going to learn something very powerful - how
+to control running synths.
+
+## A Basic Sound
+
+Let's create a nice simple sound. Fire up Sonic Pi and in a fresh buffer
+type the following:
+
+```
+synth :prophet, note: :e1, release: 8, cutoff: 100
+```
+
+Now press the Run button at the top left to hear a lovely rumbling synth
+sound. Go ahead, press it again a few times to get a feel for it. OK,
+done? Let's start controlling it!
+
+
+## Synth Nodes
+
+A little known feature in Sonic Pi is that the fns `play`, `synth` and
+`sample`, return something called a `SynthNode` which represents a
+running sound. You can capture one of these `SynthNode`s using a
+standard variable and then **control** it at a later point in time. For
+example, let's change the value of the `cutoff:` opt after 1 beat:
+
+```
+sn = synth :prophet, note: :e1, release: 8, cutoff: 100
+sleep 1
+control sn, cutoff: 130
+```
+
+Let's look at each line in turn: 
+
+Firstly we trigger the `:prophet` synth using the `synth` fn as
+norml. However we also capture the result in a variable called `sn`. We
+could have called this variable something completely different such as
+`synth_node` or `jane` - the name doesn't matter. However, it's
+important to choose a name that's meaningful to you for your
+performances and for people reading your code. I chose `sn` as it's a nice
+short mnemonic for synth node.
+
+On line 2 we have a standard `sleep` command. This does nothing special
+- it just asks the computer to wait for 1 beat before moving onto the
+next line.
+
+Line 3 is where the control fun starts. Here, we use the `control` fn to
+tell our running `SynthNode` to change the cutoff value to `130`. If you
+hit the **Run** button, you'll hear the `:prophet` synth start playing
+as before, but after 1 beat it will shift to sound a lot brighter.
+
+
+** Breakout Box Start **
+Modulatable Options
+
+Most of Sonic Pi's synths and FX opts may be changed after being
+triggered. However, this isn't the case for all of them. For example,
+the envelope opts `attack:`, `decay:`, `sustain:` and `release:` can
+only be set when triggering the synth. Figuring out which opts can and
+can't be changed is simple - just head to the documentation for a given
+synth or FX and then scroll down to the individual option documentation
+and look for the phrases "May be changed whilst playing " or "Can not be
+changed once set". For example, the documentation for the `:beep`
+synth's `attack:` opt makes it clear that it's not possible to change
+it:
+
+* Default: 0 
+* Must be zero or greater 
+* Can not be changed once set 
+* Scaled with current BPM value 
+** Breakout Box End **
+
+## Multiple Changes
+
+Whilst a synth is running you're not limited to changing it only once -
+you're free to change it as many times as you like. For example, we can
+turn our `:prophet` into a mini arpegiator with the following:
+
+```
+notes = (scale :e3, :minor_pentatonic)
+sn = synth :prophet, note: :e1, release: 8, cutoff: 100
+sleep 1
+16.times do
+  control sn, note: notes.tick
+  sleep 0.125
+end
+```
+
+In this snippet of code we just added a couple of extra things. First we
+defined a new variable called `notes` which contains the notes we'd like
+to cycle through (an arpeggiator is just a fancy name for something that
+cycles through a list of notes in order). Secondly we replaced our
+single call to `control` with an iteration calling it 16 times. In each
+call to `control` we `.tick` through our ring of `notes` which will
+automaticall repeat once we get to the end (thanks to the fabulous power
+of Sonic Pi's rings). For a bit of variety try replacing `.tick` with
+`.choose` and see if you can hear the difference.
+
+Note that we can change multiple opts simultaneously. Try changing the
+control line to the following and listen for the difference:
+
+```
+control sn, note: notes.tick, cutoff: rrand(70, 130)
+```
+
+## Sliding 
+
+When we control a `SynthNode`, it responds exactly on time and instantly
+changes the value of the opt to the new one as if you'd pressed a button
+or flicked a switch requesting the change. This can sound rhythmical and percussive -
+especially if the opt controls an aspect of the timbre such as
+`cutoff:`. However, sometimes you don't want the change to happen
+instantaneously. Instead, you might want to smoothly move from the
+current value to the new one as if you'd moved a slider or dial. Of
+course, Sonic Pi can also do this too using the `_slide:` opts.
+
+Each opt that can be modified also has a special corresonding `_slide:`
+opt that allows you to specify a slide time. For example, `amp:` has
+`amp_slide:` and `cutoff:` has `cutoff_slide:`. These slide opts work
+slightly differently than all the other opts in that they tell the synth
+note how to behave **next time they are controlled**. Let's take a look:
+
+```
+sn = synth :prophet, note: :e1, release: 8, cutoff: 70, cutoff_slide: 2
+sleep 1
+control sn, cutoff: 130
+```
+
+Notice how this example is exactly the same as before except with the
+addition of `cutoff_slide:`. This is saying that next time this synth
+has its `cutoff:` opt controlled, it will take 2 beats to slide from the
+current value to the new one. Therefore, when we use `control` you can
+hear the cutoff slide from 70 to 130. It creates an interesting dynamic
+feel to the sound. Now, try changing the `cutoff_slide:` time to a
+shorter value such as 0.5 or a longer value such as 4 to see how it
+changes the sound. Remember, you can slide any of the modifiable opts in
+exactly this way and each `_slide:` value can be totally different so
+you can have the cutoff sliding slowly, the amp sliding fast and the pan
+sliding somewhere in between if that's what you're looking to create...
+
+
+## Bringing it all together
+
+Let's look at a short example which demonstrates the power of
+controlling synths after they've been triggered. Notice that you can
+also slide FX just like synths although with a slightly different
+syntax. Check out section 7.2 of the built-in tutorial for more
+information on controlling FX.
+
+Copy the code into a spare buffer and take a listen. Don't stop there
+though - play around with the code. Change the slide times, change the
+notes, the synth, the FX and the sleep times and see if you can turn it
+into something completely different!
+
+
+```
+live_loop :moon_rise do
+  with_fx :echo, mix: 0, mix_slide: 8 do |fx|
+    control fx, mix: 1
+    notes = (scale :e3, :minor_pentatonic, num_octaves: 2).shuffle
+    sn = synth :prophet , sustain: 8, note: :e1, cutoff: 70, cutoff_slide: 8
+    control sn, cutoff: 130
+    sleep 2
+    32.times do
+      control sn, note: notes.tick, pan: rrand(-1, 1)
+      sleep 0.125
+    end
+  end
+end
+```
diff --git a/etc/samples/README.md b/etc/samples/README.md
index f5a7248..27c3126 100644
--- a/etc/samples/README.md
+++ b/etc/samples/README.md
@@ -12,121 +12,177 @@ Links to original samples:
 
 ## Drums
 
-* :drum_heavy_kick - http://freesound.org/people/Zajo/sounds/4832/
-* :drum_tom_mid_soft - http://www.freesound.org/people/menegass/sounds/100067/
-* :drum_tom_mid_hard - http://www.freesound.org/people/menegass/sounds/100066/
-* :drum_tom_lo_soft - http://www.freesound.org/people/menegass/sounds/100065/
-* :drum_tom_lo_hard - http://www.freesound.org/people/menegass/sounds/100064/
-* :drum_tom_hi_soft - http://www.freesound.org/people/menegass/sounds/100063/
-* :drum_tom_hi_hard - http://www.freesound.org/people/menegass/sounds/100062/
-* :drum_splash_soft - http://www.freesound.org/people/menegass/sounds/100061/
-* :drum_splash_hard - http://www.freesound.org/people/menegass/sounds/100060/
-* :drum_snare_soft - http://www.freesound.org/people/menegass/sounds/100059/
-* :drum_snare_hard - http://www.freesound.org/people/menegass/sounds/100058/
-* :drum_cymbal_soft - http://www.freesound.org/people/menegass/sounds/100057/
-* :drum_cymbal_hard - http://www.freesound.org/people/menegass/sounds/100056/
-* :drum_cymbal_open - http://www.freesound.org/people/menegass/sounds/100055/
-* :drum_cymbal_closed - http://www.freesound.org/people/menegass/sounds/100053/
-* :drum_cymbal_pedal - http://www.freesound.org/people/menegass/sounds/100054/
-* :drum_bass_soft - http://www.freesound.org/people/menegass/sounds/100052/
-* :drum_bass_hard - http://www.freesound.org/people/menegass/sounds/100051/
+* `:drum_heavy_kick` - http://freesound.org/people/Zajo/sounds/4832/
+* `:drum_tom_mid_soft` - http://www.freesound.org/people/menegass/sounds/100067/
+* `:drum_tom_mid_hard` - http://www.freesound.org/people/menegass/sounds/100066/
+* `:drum_tom_lo_soft` - http://www.freesound.org/people/menegass/sounds/100065/
+* `:drum_tom_lo_hard` - http://www.freesound.org/people/menegass/sounds/100064/
+* `:drum_tom_hi_soft` - http://www.freesound.org/people/menegass/sounds/100063/
+* `:drum_tom_hi_hard` - http://www.freesound.org/people/menegass/sounds/100062/
+* `:drum_splash_soft` - http://www.freesound.org/people/menegass/sounds/100061/
+* `:drum_splash_hard` - http://www.freesound.org/people/menegass/sounds/100060/
+* `:drum_snare_soft` - http://www.freesound.org/people/menegass/sounds/100059/
+* `:drum_snare_hard` - http://www.freesound.org/people/menegass/sounds/100058/
+* `:drum_cymbal_soft` - http://www.freesound.org/people/menegass/sounds/100057/
+* `:drum_cymbal_hard` - http://www.freesound.org/people/menegass/sounds/100056/
+* `:drum_cymbal_open` - http://www.freesound.org/people/menegass/sounds/100055/
+* `:drum_cymbal_closed` - http://www.freesound.org/people/menegass/sounds/100053/
+* `:drum_cymbal_pedal` - http://www.freesound.org/people/menegass/sounds/100054/
+* `:drum_bass_soft` - http://www.freesound.org/people/menegass/sounds/100052/
+* `:drum_bass_hard` - http://www.freesound.org/people/menegass/sounds/100051/
+* `:drum_cowbell` - http://freesound.org/people/Neotone/sounds/75338/
+* `:drum_roll` - http://freesound.org/people/Heigh-hoo/sounds/19433/
+
 
 ## Electric sounds
 
-* :elec_triangle - http://www.freesound.org/people/looppool/sounds/13147/
-* :elec_snare - http://www.freesound.org/people/looppool/sounds/13146/
-* :elec_lo_snare - http://www.freesound.org/people/looppool/sounds/13145/
-* :elec_hi_snare - http://www.freesound.org/people/looppool/sounds/13125/
-* :elec_mid_snare - http://www.freesound.org/people/looppool/sounds/13132/
-* :elec_cymbal - http://www.freesound.org/people/looppool/sounds/13143/
-* :elec_soft_kick - http://www.freesound.org/people/looppool/sounds/13142/
-* :elec_filt_snare - http://www.freesound.org/people/looppool/sounds/13141/
-* :elec_fuzz_tom - http://www.freesound.org/people/looppool/sounds/13140/
-* :elec_chime - http://www.freesound.org/people/looppool/sounds/13138/
-* :elec_bong - http://www.freesound.org/people/looppool/sounds/13137/
-* :elec_twang - http://www.freesound.org/people/looppool/sounds/13136/
-* :elec_wood - http://www.freesound.org/people/looppool/sounds/13135/
-* :elec_pop - http://www.freesound.org/people/looppool/sounds/13134/
-* :elec_beep - http://www.freesound.org/people/looppool/sounds/13126/
-* :elec_blip - http://www.freesound.org/people/looppool/sounds/13121/
-* :elec_blip2 - http://www.freesound.org/people/looppool/sounds/13120/
-* :elec_ping - http://www.freesound.org/people/looppool/sounds/13119/
-* :elec_bell - http://www.freesound.org/people/looppool/sounds/13116/
-* :elec_flip - http://www.freesound.org/people/looppool/sounds/13114/
-* :elec_tick - http://www.freesound.org/people/looppool/sounds/13113/
-* :elec_hollow_kick - http://www.freesound.org/people/looppool/sounds/13099/
-* :elec_twip - http://www.freesound.org/people/looppool/sounds/13094/
-* :elec_plip - http://www.freesound.org/people/looppool/sounds/13093/
-* :elec_blup - http://www.freesound.org/people/looppool/sounds/13092/
+* `:elec_triangle` - http://www.freesound.org/people/looppool/sounds/13147/
+* `:elec_snare` - http://www.freesound.org/people/looppool/sounds/13146/
+* `:elec_lo_snare` - http://www.freesound.org/people/looppool/sounds/13145/
+* `:elec_hi_snare` - http://www.freesound.org/people/looppool/sounds/13125/
+* `:elec_mid_snare` - http://www.freesound.org/people/looppool/sounds/13132/
+* `:elec_cymbal` - http://www.freesound.org/people/looppool/sounds/13143/
+* `:elec_soft_kick` - http://www.freesound.org/people/looppool/sounds/13142/
+* `:elec_filt_snare` - http://www.freesound.org/people/looppool/sounds/13141/
+* `:elec_fuzz_tom` - http://www.freesound.org/people/looppool/sounds/13140/
+* `:elec_chime` - http://www.freesound.org/people/looppool/sounds/13138/
+* `:elec_bong` - http://www.freesound.org/people/looppool/sounds/13137/
+* `:elec_twang` - http://www.freesound.org/people/looppool/sounds/13136/
+* `:elec_wood` - http://www.freesound.org/people/looppool/sounds/13135/
+* `:elec_pop` - http://www.freesound.org/people/looppool/sounds/13134/
+* `:elec_beep` - http://www.freesound.org/people/looppool/sounds/13126/
+* `:elec_blip` - http://www.freesound.org/people/looppool/sounds/13121/
+* `:elec_blip2` - http://www.freesound.org/people/looppool/sounds/13120/
+* `:elec_ping` - http://www.freesound.org/people/looppool/sounds/13119/
+* `:elec_bell` - http://www.freesound.org/people/looppool/sounds/13116/
+* `:elec_flip` - http://www.freesound.org/people/looppool/sounds/13114/
+* `:elec_tick` - http://www.freesound.org/people/looppool/sounds/13113/
+* `:elec_hollow_kick` - http://www.freesound.org/people/looppool/sounds/13099/
+* `:elec_twip` - http://www.freesound.org/people/looppool/sounds/13094/
+* `:elec_plip` - http://www.freesound.org/people/looppool/sounds/13093/
+* `:elec_blup` - http://www.freesound.org/people/looppool/sounds/13092/
+
 
 ## Guitar
 
-* :guit_harmonics - http://freesound.org/people/BStateham/sounds/141524/<
-* :guit_e_fifths - http://freesound.org/people/Sub-d/sounds/46990/
-* :guit_e_slide - http://freesound.org/people/Suva/sounds/2410/
-* :guit_em9 - http://www.freesound.org/people/Sub-d/sounds/46992/ 
+* `:guit_harmonics` - http://freesound.org/people/BStateham/sounds/141524/<
+* `:guit_e_fifths` - http://freesound.org/people/Sub-d/sounds/46990/
+* `:guit_e_slide` - http://freesound.org/people/Suva/sounds/2410/
+* `:guit_em9` - http://www.freesound.org/people/Sub-d/sounds/46992/ 
+
 
 ## Misc
 
-* :misc_burp - http://freesound.org/people/anas76/sounds/222022/
+* `:misc_burp` - http://freesound.org/people/anas76/sounds/222022/
+* `:misc_crow` - http://freesound.org/people/davidworksonline/sounds/54973/
+* `:misc_cineboom` - http://freesound.org/people/Northern_Monkey/sounds/177242/
+
 
 ## Percussion
 
-* :perc_bell - http://freesound.org/people/AlaskaRobotics/sounds/221515/
-* :perc_snap - http://www.freesound.org/people/SoundCollectah/sounds/109400/
-* :perc_snap2 - http://www.freesound.org/people/Peram/sounds/158615/
+* `:perc_bell` - http://freesound.org/people/AlaskaRobotics/sounds/221515/
+* `:perc_snap` - http://www.freesound.org/people/SoundCollectah/sounds/109400/
+* `:perc_snap2` - http://www.freesound.org/people/Peram/sounds/158615/
+* `:perc_swash` - http://freesound.org/people/qubodup/sounds/60009/
+* `:perc_till` - http://freesound.org/people/Zott820/sounds/209578/
+
 
 ## Ambient
 
-* :ambi_soft_buzz - http://freesound.org/people/ludvique/sounds/71852/
-* :ambi_swoosh - http://freesound.org/people/Halgrimm/sounds/169867/
-* :ambi_drone - http://freesound.org/people/Autistic%20Lucario/sounds/195341/
-* :ambi_glass_hum - http://freesound.org/people/kaligari/sounds/35391/
-* :ambi_glass_rub - http://freesound.org/people/ani_music/sounds/198403/
-* :ambi_haunted_hum - http://freesound.org/people/kaligari/sounds/35392/
-* :ambi_piano - http://freesound.org/people/RutgerMuller/sounds/51245/
-* :ambi_lunar_land - http://freesound.org/people/maqsim/sounds/172157/
-* :ambi_dark_woosh - http://freesound.org/people/EcoDTR/sounds/27281/
-* :ambi_choir - http://freesound.org/people/Exsomniel/sounds/207809/
+* `:ambi_soft_buzz` - http://freesound.org/people/ludvique/sounds/71852/
+* `:ambi_swoosh` - http://freesound.org/people/Halgrimm/sounds/169867/
+* `:ambi_drone` - http://freesound.org/people/Autistic%20Lucario/sounds/195341/
+* `:ambi_glass_hum` - http://freesound.org/people/kaligari/sounds/35391/
+* `:ambi_glass_rub` - http://freesound.org/people/ani_music/sounds/198403/
+* `:ambi_haunted_hum` - http://freesound.org/people/kaligari/sounds/35392/
+* `:ambi_piano` - http://freesound.org/people/RutgerMuller/sounds/51245/
+* `:ambi_lunar_land` - http://freesound.org/people/maqsim/sounds/172157/
+* `:ambi_dark_woosh` - http://freesound.org/people/EcoDTR/sounds/27281/
+* `:ambi_choir` - http://freesound.org/people/Exsomniel/sounds/207809/
+
 
 ## Bass
 
-* :bass_hit_c - http://freesound.org/people/oceanictrancer/sounds/211614/
-* :bass_hard_c - http://freesound.org/people/ani_music/sounds/165309/
-* :bass_thick_c - http://freesound.org/people/ani_music/sounds/165314/
-* :bass_drop_c - http://freesound.org/people/ani_music/sounds/165320/ 
-* :bass_woodsy_c - http://freesound.org/people/ani_music/sounds/165322/
-* :bass_voxy_c - http://freesound.org/people/ani_music/sounds/165325/
-* :bass_voxy_hit_c - http://freesound.org/people/ani_music/sounds/165327/
-* :bass_dnb_f - http://freesound.org/people/Exsomniel/sounds/206134/
+* `:bass_hit_c` - http://freesound.org/people/oceanictrancer/sounds/211614/
+* `:bass_hard_c` - http://freesound.org/people/ani_music/sounds/165309/
+* `:bass_thick_c` - http://freesound.org/people/ani_music/sounds/165314/
+* `:bass_trance_c` - http://freesound.org/people/ani_music/sounds/165329/
+* `:bass_drop_c` - http://freesound.org/people/ani_music/sounds/165320/ 
+* `:bass_woodsy_c` - http://freesound.org/people/ani_music/sounds/165322/
+* `:bass_voxy_c` - http://freesound.org/people/ani_music/sounds/165325/
+* `:bass_voxy_hit_c` - http://freesound.org/people/ani_music/sounds/165327/
+* `:bass_dnb_f` - http://freesound.org/people/Exsomniel/sounds/206134/
 
 
 ## Bass Drums
 
-* :bd_pure - http://freesound.org/people/EKVelika/sounds/209571/
-* :bd_808 - http://freesound.org/people/EKVelika/sounds/208447/
-* :bd_zum - http://freesound.org/people/n1ghthawk/sounds/172124/
-* :bd_gas  - http://freesound.org/people/menegass/sounds/89460/
-* :bd_sone - http://freesound.org/people/soneproject/sounds/223090/
-* :bd_haus - http://freesound.org/people/Rodrigo%20The%20Mad/sounds/137722/
-* :bd_zome - http://freesound.org/people/Dolfeus/sounds/55231/
-* :bd_boom - http://freesound.org/people/Snapper4298/sounds/157245/
-* :bd_klub - http://freesound.org/people/zgump/sounds/83262/
-* :bd_fat - http://freesound.org/people/cubix/sounds/124386/
-* :bd_tek - http://freesound.org/people/DWSD/sounds/171104/
-* :bd_ada - http://www.freesound.org/people/adammusic18/sounds/208871/
+* `:bd_pure` - http://freesound.org/people/EKVelika/sounds/209571/
+* `:bd_808` - http://freesound.org/people/EKVelika/sounds/208447/
+* `:bd_zum` - http://freesound.org/people/n1ghthawk/sounds/172124/
+* `:bd_gas`  - http://freesound.org/people/menegass/sounds/89460/
+* `:bd_sone` - http://freesound.org/people/soneproject/sounds/223090/
+* `:bd_haus` - http://freesound.org/people/Rodrigo%20The%20Mad/sounds/137722/
+* `:bd_zome` - http://freesound.org/people/Dolfeus/sounds/55231/
+* `:bd_boom` - http://freesound.org/people/Snapper4298/sounds/157245/
+* `:bd_klub` - http://freesound.org/people/zgump/sounds/83262/
+* `:bd_fat` - http://freesound.org/people/cubix/sounds/124386/
+* `:bd_tek` - http://freesound.org/people/DWSD/sounds/171104/
+* `:bd_ada` - http://www.freesound.org/people/adammusic18/sounds/208871/
+
 
 ## Snares
 
-* :sn_dub - http://freesound.org/people/Adriak909/sounds/173142/
-* :sn_dolf - http://freesound.org/people/Dolfeus/sounds/57534/
-* :sn_zome - http://freesound.org/people/Dolfeus/sounds/55232/
+* `:sn_dub` - http://freesound.org/people/Adriak909/sounds/173142/
+* `:sn_dolf` - http://freesound.org/people/Dolfeus/sounds/57534/
+* `:sn_zome` - http://freesound.org/people/Dolfeus/sounds/55232/
+
 
 ## Loops
 
-* :loop_industrial - http://freesound.org/people/godspine/sounds/222072/
-* :loop_compus - http://freesound.org/people/godspine/sounds/212288/
-* :loop_amen - http://freesound.org/people/Dolfeus/sounds/43389/
-* :loop_amen_full - http://freesound.org/people/gowers/sounds/202537/
-* :loop_garzul - http://freesound.org/people/Garzul/sounds/213524/
-* :loop_mika - http://freesound.org/people/mika55/sounds/188551/
+* `:loop_industrial` - http://freesound.org/people/godspine/sounds/222072/
+* `:loop_compus` - http://freesound.org/people/godspine/sounds/212288/
+* `:loop_amen` - http://freesound.org/people/Dolfeus/sounds/43389/
+* `:loop_amen_full` - http://freesound.org/people/gowers/sounds/202537/
+* `:loop_garzul` - http://freesound.org/people/Garzul/sounds/213524/
+* `:loop_mika` - http://freesound.org/people/mika55/sounds/188551/
+* `:loop_breakbeat` - http://freesound.org/people/Snapper4298/sounds/160354/
+* `:loop_safari` - http://freesound.org/people/nemaavla/sounds/318759/
+* `:loop_tabla` - http://freesound.org/people/lezaarth/sounds/242591/
+
+
+## Tabla
+
+* `:tabla_tas1` - http://freesound.org/people/dio_333/sounds/130427/
+* `:tabla_tas2` - http://freesound.org/people/dio_333/sounds/130425/
+* `:tabla_tas3` - http://freesound.org/people/dio_333/sounds/130430/
+* `:tabla_ke1` - http://freesound.org/people/dio_333/sounds/130413/
+* `:tabla_ke2` - http://freesound.org/people/dio_333/sounds/130424/
+* `:tabla_ke3` - http://freesound.org/people/dio_333/sounds/130423/
+* `:tabla_na` - http://freesound.org/people/dio_333/sounds/130421/
+* `:tabla_na_o` - http://freesound.org/people/dio_333/sounds/130422/
+* `:tabla_tun1` - http://freesound.org/people/dio_333/sounds/130416/
+* `:tabla_tun2` - http://freesound.org/people/dio_333/sounds/130419/
+* `:tabla_tun3` - http://freesound.org/people/dio_333/sounds/130420/
+* `:tabla_te1` - http://freesound.org/people/dio_333/sounds/130429/
+* `:tabla_te2` - http://freesound.org/people/dio_333/sounds/130418/
+* `:tabla_te_ne` - http://freesound.org/people/dio_333/sounds/130417/
+* `:tabla_te_m` - http://freesound.org/people/dio_333/sounds/130415/
+* `:tabla_ghe1` - http://freesound.org/people/dio_333/sounds/130406/
+* `:tabla_ghe2` - http://freesound.org/people/dio_333/sounds/130405/
+* `:tabla_ghe3` - http://freesound.org/people/dio_333/sounds/130404/
+* `:tabla_ghe4` - http://freesound.org/people/dio_333/sounds/130411/
+* `:tabla_ghe5` - http://freesound.org/people/dio_333/sounds/130410/
+* `:tabla_ghe6` - http://freesound.org/people/dio_333/sounds/130409/
+* `:tabla_ghe7` - http://freesound.org/people/dio_333/sounds/130408/
+* `:tabla_ghe8` - http://freesound.org/people/dio_333/sounds/130414/
+* `:tabla_dhec` - http://freesound.org/people/dio_333/sounds/130407/
+* `:tabla_na_s` - http://freesound.org/people/dio_333/sounds/130428/
+* `:tabla_re` - http://freesound.org/people/dio_333/sounds/130427/
+
+
+# Vinyl
+
+* `:vinyl_backspin` - http://freesound.org/people/il112/sounds/182316/
+* `:vinyl_rewind` - http://freesound.org/people/TasmanianPower/sounds/162493/
+* `:vinyl_scratch` - http://freesound.org/people/hello_flowers/sounds/28681/
+* `:vinyl_hiss` - http://freesound.org/people/veezay/sounds/130393/
diff --git a/etc/samples/ambi_choir.flac b/etc/samples/ambi_choir.flac
new file mode 100644
index 0000000..6882735
Binary files /dev/null and b/etc/samples/ambi_choir.flac differ
diff --git a/etc/samples/ambi_choir.wav b/etc/samples/ambi_choir.wav
deleted file mode 100644
index 66ce123..0000000
Binary files a/etc/samples/ambi_choir.wav and /dev/null differ
diff --git a/etc/samples/ambi_dark_woosh.flac b/etc/samples/ambi_dark_woosh.flac
new file mode 100644
index 0000000..e1fe79f
Binary files /dev/null and b/etc/samples/ambi_dark_woosh.flac differ
diff --git a/etc/samples/ambi_dark_woosh.wav b/etc/samples/ambi_dark_woosh.wav
deleted file mode 100644
index 97909af..0000000
Binary files a/etc/samples/ambi_dark_woosh.wav and /dev/null differ
diff --git a/etc/samples/ambi_drone.flac b/etc/samples/ambi_drone.flac
new file mode 100644
index 0000000..ca86bf2
Binary files /dev/null and b/etc/samples/ambi_drone.flac differ
diff --git a/etc/samples/ambi_drone.wav b/etc/samples/ambi_drone.wav
deleted file mode 100644
index 5420593..0000000
Binary files a/etc/samples/ambi_drone.wav and /dev/null differ
diff --git a/etc/samples/ambi_glass_hum.flac b/etc/samples/ambi_glass_hum.flac
new file mode 100644
index 0000000..db110e4
Binary files /dev/null and b/etc/samples/ambi_glass_hum.flac differ
diff --git a/etc/samples/ambi_glass_hum.wav b/etc/samples/ambi_glass_hum.wav
deleted file mode 100644
index d1ad55c..0000000
Binary files a/etc/samples/ambi_glass_hum.wav and /dev/null differ
diff --git a/etc/samples/ambi_glass_rub.flac b/etc/samples/ambi_glass_rub.flac
new file mode 100644
index 0000000..16d8860
Binary files /dev/null and b/etc/samples/ambi_glass_rub.flac differ
diff --git a/etc/samples/ambi_glass_rub.wav b/etc/samples/ambi_glass_rub.wav
deleted file mode 100644
index 42c5ce7..0000000
Binary files a/etc/samples/ambi_glass_rub.wav and /dev/null differ
diff --git a/etc/samples/ambi_haunted_hum.flac b/etc/samples/ambi_haunted_hum.flac
new file mode 100644
index 0000000..1987959
Binary files /dev/null and b/etc/samples/ambi_haunted_hum.flac differ
diff --git a/etc/samples/ambi_haunted_hum.wav b/etc/samples/ambi_haunted_hum.wav
deleted file mode 100644
index 21247f4..0000000
Binary files a/etc/samples/ambi_haunted_hum.wav and /dev/null differ
diff --git a/etc/samples/ambi_lunar_land.flac b/etc/samples/ambi_lunar_land.flac
new file mode 100644
index 0000000..b36a4bc
Binary files /dev/null and b/etc/samples/ambi_lunar_land.flac differ
diff --git a/etc/samples/ambi_lunar_land.wav b/etc/samples/ambi_lunar_land.wav
deleted file mode 100644
index 0d303ba..0000000
Binary files a/etc/samples/ambi_lunar_land.wav and /dev/null differ
diff --git a/etc/samples/ambi_piano.flac b/etc/samples/ambi_piano.flac
new file mode 100644
index 0000000..1a7775a
Binary files /dev/null and b/etc/samples/ambi_piano.flac differ
diff --git a/etc/samples/ambi_piano.wav b/etc/samples/ambi_piano.wav
deleted file mode 100644
index a256548..0000000
Binary files a/etc/samples/ambi_piano.wav and /dev/null differ
diff --git a/etc/samples/ambi_soft_buzz.flac b/etc/samples/ambi_soft_buzz.flac
new file mode 100644
index 0000000..fd64c88
Binary files /dev/null and b/etc/samples/ambi_soft_buzz.flac differ
diff --git a/etc/samples/ambi_soft_buzz.wav b/etc/samples/ambi_soft_buzz.wav
deleted file mode 100644
index e29a59e..0000000
Binary files a/etc/samples/ambi_soft_buzz.wav and /dev/null differ
diff --git a/etc/samples/ambi_swoosh.flac b/etc/samples/ambi_swoosh.flac
new file mode 100644
index 0000000..4bf00cc
Binary files /dev/null and b/etc/samples/ambi_swoosh.flac differ
diff --git a/etc/samples/ambi_swoosh.wav b/etc/samples/ambi_swoosh.wav
deleted file mode 100644
index 6f79b1a..0000000
Binary files a/etc/samples/ambi_swoosh.wav and /dev/null differ
diff --git a/etc/samples/bass_dnb_f.flac b/etc/samples/bass_dnb_f.flac
new file mode 100644
index 0000000..9ed1954
Binary files /dev/null and b/etc/samples/bass_dnb_f.flac differ
diff --git a/etc/samples/bass_dnb_f.wav b/etc/samples/bass_dnb_f.wav
deleted file mode 100644
index bda60b5..0000000
Binary files a/etc/samples/bass_dnb_f.wav and /dev/null differ
diff --git a/etc/samples/bass_drop_c.flac b/etc/samples/bass_drop_c.flac
new file mode 100644
index 0000000..e354324
Binary files /dev/null and b/etc/samples/bass_drop_c.flac differ
diff --git a/etc/samples/bass_drop_c.wav b/etc/samples/bass_drop_c.wav
deleted file mode 100644
index 5f34489..0000000
Binary files a/etc/samples/bass_drop_c.wav and /dev/null differ
diff --git a/etc/samples/bass_hard_c.flac b/etc/samples/bass_hard_c.flac
new file mode 100644
index 0000000..8ce7648
Binary files /dev/null and b/etc/samples/bass_hard_c.flac differ
diff --git a/etc/samples/bass_hard_c.wav b/etc/samples/bass_hard_c.wav
deleted file mode 100644
index c9b2a21..0000000
Binary files a/etc/samples/bass_hard_c.wav and /dev/null differ
diff --git a/etc/samples/bass_hit_c.flac b/etc/samples/bass_hit_c.flac
new file mode 100644
index 0000000..2262b80
Binary files /dev/null and b/etc/samples/bass_hit_c.flac differ
diff --git a/etc/samples/bass_hit_c.wav b/etc/samples/bass_hit_c.wav
deleted file mode 100644
index 83cbcff..0000000
Binary files a/etc/samples/bass_hit_c.wav and /dev/null differ
diff --git a/etc/samples/bass_thick_c.flac b/etc/samples/bass_thick_c.flac
new file mode 100644
index 0000000..305ddbe
Binary files /dev/null and b/etc/samples/bass_thick_c.flac differ
diff --git a/etc/samples/bass_thick_c.wav b/etc/samples/bass_thick_c.wav
deleted file mode 100644
index 711cad2..0000000
Binary files a/etc/samples/bass_thick_c.wav and /dev/null differ
diff --git a/etc/samples/bass_trance_c.flac b/etc/samples/bass_trance_c.flac
new file mode 100644
index 0000000..62ac597
Binary files /dev/null and b/etc/samples/bass_trance_c.flac differ
diff --git a/etc/samples/bass_trance_c.wav b/etc/samples/bass_trance_c.wav
deleted file mode 100644
index c9f005a..0000000
Binary files a/etc/samples/bass_trance_c.wav and /dev/null differ
diff --git a/etc/samples/bass_voxy_c.flac b/etc/samples/bass_voxy_c.flac
new file mode 100644
index 0000000..68a6c0e
Binary files /dev/null and b/etc/samples/bass_voxy_c.flac differ
diff --git a/etc/samples/bass_voxy_c.wav b/etc/samples/bass_voxy_c.wav
deleted file mode 100644
index bb6854e..0000000
Binary files a/etc/samples/bass_voxy_c.wav and /dev/null differ
diff --git a/etc/samples/bass_voxy_hit_c.flac b/etc/samples/bass_voxy_hit_c.flac
new file mode 100644
index 0000000..150d465
Binary files /dev/null and b/etc/samples/bass_voxy_hit_c.flac differ
diff --git a/etc/samples/bass_voxy_hit_c.wav b/etc/samples/bass_voxy_hit_c.wav
deleted file mode 100644
index dc6318d..0000000
Binary files a/etc/samples/bass_voxy_hit_c.wav and /dev/null differ
diff --git a/etc/samples/bass_woodsy_c.flac b/etc/samples/bass_woodsy_c.flac
new file mode 100644
index 0000000..3f41bc6
Binary files /dev/null and b/etc/samples/bass_woodsy_c.flac differ
diff --git a/etc/samples/bass_woodsy_c.wav b/etc/samples/bass_woodsy_c.wav
deleted file mode 100644
index f7f942f..0000000
Binary files a/etc/samples/bass_woodsy_c.wav and /dev/null differ
diff --git a/etc/samples/bd_808.flac b/etc/samples/bd_808.flac
new file mode 100644
index 0000000..f08b8f2
Binary files /dev/null and b/etc/samples/bd_808.flac differ
diff --git a/etc/samples/bd_808.wav b/etc/samples/bd_808.wav
deleted file mode 100644
index 9d2617c..0000000
Binary files a/etc/samples/bd_808.wav and /dev/null differ
diff --git a/etc/samples/bd_ada.flac b/etc/samples/bd_ada.flac
new file mode 100644
index 0000000..32e2af6
Binary files /dev/null and b/etc/samples/bd_ada.flac differ
diff --git a/etc/samples/bd_ada.wav b/etc/samples/bd_ada.wav
deleted file mode 100644
index c536c74..0000000
Binary files a/etc/samples/bd_ada.wav and /dev/null differ
diff --git a/etc/samples/bd_boom.flac b/etc/samples/bd_boom.flac
new file mode 100644
index 0000000..319ffe9
Binary files /dev/null and b/etc/samples/bd_boom.flac differ
diff --git a/etc/samples/bd_boom.wav b/etc/samples/bd_boom.wav
deleted file mode 100644
index 911f81c..0000000
Binary files a/etc/samples/bd_boom.wav and /dev/null differ
diff --git a/etc/samples/bd_fat.flac b/etc/samples/bd_fat.flac
new file mode 100644
index 0000000..82d7e74
Binary files /dev/null and b/etc/samples/bd_fat.flac differ
diff --git a/etc/samples/bd_fat.wav b/etc/samples/bd_fat.wav
deleted file mode 100644
index ebb6ff7..0000000
Binary files a/etc/samples/bd_fat.wav and /dev/null differ
diff --git a/etc/samples/bd_gas.flac b/etc/samples/bd_gas.flac
new file mode 100644
index 0000000..be52acc
Binary files /dev/null and b/etc/samples/bd_gas.flac differ
diff --git a/etc/samples/bd_gas.wav b/etc/samples/bd_gas.wav
deleted file mode 100644
index 61ecb87..0000000
Binary files a/etc/samples/bd_gas.wav and /dev/null differ
diff --git a/etc/samples/bd_haus.flac b/etc/samples/bd_haus.flac
new file mode 100644
index 0000000..73ba6ce
Binary files /dev/null and b/etc/samples/bd_haus.flac differ
diff --git a/etc/samples/bd_haus.wav b/etc/samples/bd_haus.wav
deleted file mode 100644
index f55e934..0000000
Binary files a/etc/samples/bd_haus.wav and /dev/null differ
diff --git a/etc/samples/bd_klub.flac b/etc/samples/bd_klub.flac
new file mode 100644
index 0000000..9ffe97e
Binary files /dev/null and b/etc/samples/bd_klub.flac differ
diff --git a/etc/samples/bd_klub.wav b/etc/samples/bd_klub.wav
deleted file mode 100644
index 8f0cd52..0000000
Binary files a/etc/samples/bd_klub.wav and /dev/null differ
diff --git a/etc/samples/bd_pure.flac b/etc/samples/bd_pure.flac
new file mode 100644
index 0000000..c6a2f6a
Binary files /dev/null and b/etc/samples/bd_pure.flac differ
diff --git a/etc/samples/bd_pure.wav b/etc/samples/bd_pure.wav
deleted file mode 100644
index 3095acd..0000000
Binary files a/etc/samples/bd_pure.wav and /dev/null differ
diff --git a/etc/samples/bd_sone.flac b/etc/samples/bd_sone.flac
new file mode 100644
index 0000000..ffcff48
Binary files /dev/null and b/etc/samples/bd_sone.flac differ
diff --git a/etc/samples/bd_sone.wav b/etc/samples/bd_sone.wav
deleted file mode 100644
index 89964d3..0000000
Binary files a/etc/samples/bd_sone.wav and /dev/null differ
diff --git a/etc/samples/bd_tek.flac b/etc/samples/bd_tek.flac
new file mode 100644
index 0000000..b5d8c79
Binary files /dev/null and b/etc/samples/bd_tek.flac differ
diff --git a/etc/samples/bd_tek.wav b/etc/samples/bd_tek.wav
deleted file mode 100644
index c759088..0000000
Binary files a/etc/samples/bd_tek.wav and /dev/null differ
diff --git a/etc/samples/bd_zome.flac b/etc/samples/bd_zome.flac
new file mode 100644
index 0000000..35f705d
Binary files /dev/null and b/etc/samples/bd_zome.flac differ
diff --git a/etc/samples/bd_zome.wav b/etc/samples/bd_zome.wav
deleted file mode 100644
index 21a65af..0000000
Binary files a/etc/samples/bd_zome.wav and /dev/null differ
diff --git a/etc/samples/bd_zum.flac b/etc/samples/bd_zum.flac
new file mode 100644
index 0000000..271004a
Binary files /dev/null and b/etc/samples/bd_zum.flac differ
diff --git a/etc/samples/bd_zum.wav b/etc/samples/bd_zum.wav
deleted file mode 100644
index a235691..0000000
Binary files a/etc/samples/bd_zum.wav and /dev/null differ
diff --git a/etc/samples/drum_bass_hard.flac b/etc/samples/drum_bass_hard.flac
new file mode 100644
index 0000000..9ed00e3
Binary files /dev/null and b/etc/samples/drum_bass_hard.flac differ
diff --git a/etc/samples/drum_bass_hard.wav b/etc/samples/drum_bass_hard.wav
deleted file mode 100644
index 6812cad..0000000
Binary files a/etc/samples/drum_bass_hard.wav and /dev/null differ
diff --git a/etc/samples/drum_bass_soft.flac b/etc/samples/drum_bass_soft.flac
new file mode 100644
index 0000000..06a12c5
Binary files /dev/null and b/etc/samples/drum_bass_soft.flac differ
diff --git a/etc/samples/drum_bass_soft.wav b/etc/samples/drum_bass_soft.wav
deleted file mode 100644
index e3c6fbc..0000000
Binary files a/etc/samples/drum_bass_soft.wav and /dev/null differ
diff --git a/etc/samples/drum_cowbell.flac b/etc/samples/drum_cowbell.flac
new file mode 100644
index 0000000..43e5f38
Binary files /dev/null and b/etc/samples/drum_cowbell.flac differ
diff --git a/etc/samples/drum_cymbal_closed.flac b/etc/samples/drum_cymbal_closed.flac
new file mode 100644
index 0000000..8c886e1
Binary files /dev/null and b/etc/samples/drum_cymbal_closed.flac differ
diff --git a/etc/samples/drum_cymbal_closed.wav b/etc/samples/drum_cymbal_closed.wav
deleted file mode 100644
index 39ab498..0000000
Binary files a/etc/samples/drum_cymbal_closed.wav and /dev/null differ
diff --git a/etc/samples/drum_cymbal_hard.flac b/etc/samples/drum_cymbal_hard.flac
new file mode 100644
index 0000000..4650289
Binary files /dev/null and b/etc/samples/drum_cymbal_hard.flac differ
diff --git a/etc/samples/drum_cymbal_hard.wav b/etc/samples/drum_cymbal_hard.wav
deleted file mode 100644
index 9904005..0000000
Binary files a/etc/samples/drum_cymbal_hard.wav and /dev/null differ
diff --git a/etc/samples/drum_cymbal_open.flac b/etc/samples/drum_cymbal_open.flac
new file mode 100644
index 0000000..bcfee94
Binary files /dev/null and b/etc/samples/drum_cymbal_open.flac differ
diff --git a/etc/samples/drum_cymbal_open.wav b/etc/samples/drum_cymbal_open.wav
deleted file mode 100644
index acf9eba..0000000
Binary files a/etc/samples/drum_cymbal_open.wav and /dev/null differ
diff --git a/etc/samples/drum_cymbal_pedal.flac b/etc/samples/drum_cymbal_pedal.flac
new file mode 100644
index 0000000..f09d80b
Binary files /dev/null and b/etc/samples/drum_cymbal_pedal.flac differ
diff --git a/etc/samples/drum_cymbal_pedal.wav b/etc/samples/drum_cymbal_pedal.wav
deleted file mode 100644
index b277095..0000000
Binary files a/etc/samples/drum_cymbal_pedal.wav and /dev/null differ
diff --git a/etc/samples/drum_cymbal_soft.flac b/etc/samples/drum_cymbal_soft.flac
new file mode 100644
index 0000000..9ae03ee
Binary files /dev/null and b/etc/samples/drum_cymbal_soft.flac differ
diff --git a/etc/samples/drum_cymbal_soft.wav b/etc/samples/drum_cymbal_soft.wav
deleted file mode 100644
index 414fbe0..0000000
Binary files a/etc/samples/drum_cymbal_soft.wav and /dev/null differ
diff --git a/etc/samples/drum_heavy_kick.flac b/etc/samples/drum_heavy_kick.flac
new file mode 100644
index 0000000..69b894f
Binary files /dev/null and b/etc/samples/drum_heavy_kick.flac differ
diff --git a/etc/samples/drum_heavy_kick.wav b/etc/samples/drum_heavy_kick.wav
deleted file mode 100644
index 2705ee2..0000000
Binary files a/etc/samples/drum_heavy_kick.wav and /dev/null differ
diff --git a/etc/samples/drum_roll.flac b/etc/samples/drum_roll.flac
new file mode 100644
index 0000000..2ab8d7b
Binary files /dev/null and b/etc/samples/drum_roll.flac differ
diff --git a/etc/samples/drum_snare_hard.flac b/etc/samples/drum_snare_hard.flac
new file mode 100644
index 0000000..d02f133
Binary files /dev/null and b/etc/samples/drum_snare_hard.flac differ
diff --git a/etc/samples/drum_snare_hard.wav b/etc/samples/drum_snare_hard.wav
deleted file mode 100644
index fbafee8..0000000
Binary files a/etc/samples/drum_snare_hard.wav and /dev/null differ
diff --git a/etc/samples/drum_snare_soft.flac b/etc/samples/drum_snare_soft.flac
new file mode 100644
index 0000000..8dc76ce
Binary files /dev/null and b/etc/samples/drum_snare_soft.flac differ
diff --git a/etc/samples/drum_snare_soft.wav b/etc/samples/drum_snare_soft.wav
deleted file mode 100644
index 533c2fd..0000000
Binary files a/etc/samples/drum_snare_soft.wav and /dev/null differ
diff --git a/etc/samples/drum_splash_hard.flac b/etc/samples/drum_splash_hard.flac
new file mode 100644
index 0000000..9e083cd
Binary files /dev/null and b/etc/samples/drum_splash_hard.flac differ
diff --git a/etc/samples/drum_splash_hard.wav b/etc/samples/drum_splash_hard.wav
deleted file mode 100644
index bde7195..0000000
Binary files a/etc/samples/drum_splash_hard.wav and /dev/null differ
diff --git a/etc/samples/drum_splash_soft.flac b/etc/samples/drum_splash_soft.flac
new file mode 100644
index 0000000..187d647
Binary files /dev/null and b/etc/samples/drum_splash_soft.flac differ
diff --git a/etc/samples/drum_splash_soft.wav b/etc/samples/drum_splash_soft.wav
deleted file mode 100644
index 593e2bb..0000000
Binary files a/etc/samples/drum_splash_soft.wav and /dev/null differ
diff --git a/etc/samples/drum_tom_hi_hard.flac b/etc/samples/drum_tom_hi_hard.flac
new file mode 100644
index 0000000..c52cd33
Binary files /dev/null and b/etc/samples/drum_tom_hi_hard.flac differ
diff --git a/etc/samples/drum_tom_hi_hard.wav b/etc/samples/drum_tom_hi_hard.wav
deleted file mode 100644
index 239e769..0000000
Binary files a/etc/samples/drum_tom_hi_hard.wav and /dev/null differ
diff --git a/etc/samples/drum_tom_hi_soft.flac b/etc/samples/drum_tom_hi_soft.flac
new file mode 100644
index 0000000..74bbc3f
Binary files /dev/null and b/etc/samples/drum_tom_hi_soft.flac differ
diff --git a/etc/samples/drum_tom_hi_soft.wav b/etc/samples/drum_tom_hi_soft.wav
deleted file mode 100644
index 9598363..0000000
Binary files a/etc/samples/drum_tom_hi_soft.wav and /dev/null differ
diff --git a/etc/samples/drum_tom_lo_hard.flac b/etc/samples/drum_tom_lo_hard.flac
new file mode 100644
index 0000000..43f0ca6
Binary files /dev/null and b/etc/samples/drum_tom_lo_hard.flac differ
diff --git a/etc/samples/drum_tom_lo_hard.wav b/etc/samples/drum_tom_lo_hard.wav
deleted file mode 100644
index 255ee9c..0000000
Binary files a/etc/samples/drum_tom_lo_hard.wav and /dev/null differ
diff --git a/etc/samples/drum_tom_lo_soft.flac b/etc/samples/drum_tom_lo_soft.flac
new file mode 100644
index 0000000..71c1e61
Binary files /dev/null and b/etc/samples/drum_tom_lo_soft.flac differ
diff --git a/etc/samples/drum_tom_lo_soft.wav b/etc/samples/drum_tom_lo_soft.wav
deleted file mode 100644
index 23589bf..0000000
Binary files a/etc/samples/drum_tom_lo_soft.wav and /dev/null differ
diff --git a/etc/samples/drum_tom_mid_hard.flac b/etc/samples/drum_tom_mid_hard.flac
new file mode 100644
index 0000000..bc40cee
Binary files /dev/null and b/etc/samples/drum_tom_mid_hard.flac differ
diff --git a/etc/samples/drum_tom_mid_hard.wav b/etc/samples/drum_tom_mid_hard.wav
deleted file mode 100644
index 66b961f..0000000
Binary files a/etc/samples/drum_tom_mid_hard.wav and /dev/null differ
diff --git a/etc/samples/drum_tom_mid_soft.flac b/etc/samples/drum_tom_mid_soft.flac
new file mode 100644
index 0000000..d2c6864
Binary files /dev/null and b/etc/samples/drum_tom_mid_soft.flac differ
diff --git a/etc/samples/drum_tom_mid_soft.wav b/etc/samples/drum_tom_mid_soft.wav
deleted file mode 100644
index 73c4dba..0000000
Binary files a/etc/samples/drum_tom_mid_soft.wav and /dev/null differ
diff --git a/etc/samples/elec_beep.flac b/etc/samples/elec_beep.flac
new file mode 100644
index 0000000..73e83cb
Binary files /dev/null and b/etc/samples/elec_beep.flac differ
diff --git a/etc/samples/elec_beep.wav b/etc/samples/elec_beep.wav
deleted file mode 100644
index f314f0f..0000000
Binary files a/etc/samples/elec_beep.wav and /dev/null differ
diff --git a/etc/samples/elec_bell.flac b/etc/samples/elec_bell.flac
new file mode 100644
index 0000000..532bc29
Binary files /dev/null and b/etc/samples/elec_bell.flac differ
diff --git a/etc/samples/elec_bell.wav b/etc/samples/elec_bell.wav
deleted file mode 100644
index 8faed6b..0000000
Binary files a/etc/samples/elec_bell.wav and /dev/null differ
diff --git a/etc/samples/elec_blip.flac b/etc/samples/elec_blip.flac
new file mode 100644
index 0000000..9968ebb
Binary files /dev/null and b/etc/samples/elec_blip.flac differ
diff --git a/etc/samples/elec_blip.wav b/etc/samples/elec_blip.wav
deleted file mode 100644
index 53baa40..0000000
Binary files a/etc/samples/elec_blip.wav and /dev/null differ
diff --git a/etc/samples/elec_blip2.flac b/etc/samples/elec_blip2.flac
new file mode 100644
index 0000000..29a7f8e
Binary files /dev/null and b/etc/samples/elec_blip2.flac differ
diff --git a/etc/samples/elec_blip2.wav b/etc/samples/elec_blip2.wav
deleted file mode 100644
index a9c79a8..0000000
Binary files a/etc/samples/elec_blip2.wav and /dev/null differ
diff --git a/etc/samples/elec_blup.flac b/etc/samples/elec_blup.flac
new file mode 100644
index 0000000..c9c0a77
Binary files /dev/null and b/etc/samples/elec_blup.flac differ
diff --git a/etc/samples/elec_blup.wav b/etc/samples/elec_blup.wav
deleted file mode 100644
index 5e6e05f..0000000
Binary files a/etc/samples/elec_blup.wav and /dev/null differ
diff --git a/etc/samples/elec_bong.flac b/etc/samples/elec_bong.flac
new file mode 100644
index 0000000..49663c3
Binary files /dev/null and b/etc/samples/elec_bong.flac differ
diff --git a/etc/samples/elec_bong.wav b/etc/samples/elec_bong.wav
deleted file mode 100644
index 3f1ec76..0000000
Binary files a/etc/samples/elec_bong.wav and /dev/null differ
diff --git a/etc/samples/elec_chime.flac b/etc/samples/elec_chime.flac
new file mode 100644
index 0000000..eab1e39
Binary files /dev/null and b/etc/samples/elec_chime.flac differ
diff --git a/etc/samples/elec_chime.wav b/etc/samples/elec_chime.wav
deleted file mode 100644
index 9c0f0b4..0000000
Binary files a/etc/samples/elec_chime.wav and /dev/null differ
diff --git a/etc/samples/elec_cymbal.flac b/etc/samples/elec_cymbal.flac
new file mode 100644
index 0000000..b496dfd
Binary files /dev/null and b/etc/samples/elec_cymbal.flac differ
diff --git a/etc/samples/elec_cymbal.wav b/etc/samples/elec_cymbal.wav
deleted file mode 100644
index a47d498..0000000
Binary files a/etc/samples/elec_cymbal.wav and /dev/null differ
diff --git a/etc/samples/elec_filt_snare.flac b/etc/samples/elec_filt_snare.flac
new file mode 100644
index 0000000..94f7814
Binary files /dev/null and b/etc/samples/elec_filt_snare.flac differ
diff --git a/etc/samples/elec_filt_snare.wav b/etc/samples/elec_filt_snare.wav
deleted file mode 100644
index 5222653..0000000
Binary files a/etc/samples/elec_filt_snare.wav and /dev/null differ
diff --git a/etc/samples/elec_flip.flac b/etc/samples/elec_flip.flac
new file mode 100644
index 0000000..d00ccb1
Binary files /dev/null and b/etc/samples/elec_flip.flac differ
diff --git a/etc/samples/elec_flip.wav b/etc/samples/elec_flip.wav
deleted file mode 100644
index 74c5c99..0000000
Binary files a/etc/samples/elec_flip.wav and /dev/null differ
diff --git a/etc/samples/elec_fuzz_tom.flac b/etc/samples/elec_fuzz_tom.flac
new file mode 100644
index 0000000..4de082b
Binary files /dev/null and b/etc/samples/elec_fuzz_tom.flac differ
diff --git a/etc/samples/elec_fuzz_tom.wav b/etc/samples/elec_fuzz_tom.wav
deleted file mode 100644
index 39d4cf2..0000000
Binary files a/etc/samples/elec_fuzz_tom.wav and /dev/null differ
diff --git a/etc/samples/elec_hi_snare.flac b/etc/samples/elec_hi_snare.flac
new file mode 100644
index 0000000..3f8b90c
Binary files /dev/null and b/etc/samples/elec_hi_snare.flac differ
diff --git a/etc/samples/elec_hi_snare.wav b/etc/samples/elec_hi_snare.wav
deleted file mode 100644
index b293598..0000000
Binary files a/etc/samples/elec_hi_snare.wav and /dev/null differ
diff --git a/etc/samples/elec_hollow_kick.flac b/etc/samples/elec_hollow_kick.flac
new file mode 100644
index 0000000..bdfc44c
Binary files /dev/null and b/etc/samples/elec_hollow_kick.flac differ
diff --git a/etc/samples/elec_hollow_kick.wav b/etc/samples/elec_hollow_kick.wav
deleted file mode 100644
index 273bd9c..0000000
Binary files a/etc/samples/elec_hollow_kick.wav and /dev/null differ
diff --git a/etc/samples/elec_lo_snare.flac b/etc/samples/elec_lo_snare.flac
new file mode 100644
index 0000000..ad636a6
Binary files /dev/null and b/etc/samples/elec_lo_snare.flac differ
diff --git a/etc/samples/elec_lo_snare.wav b/etc/samples/elec_lo_snare.wav
deleted file mode 100644
index 7409020..0000000
Binary files a/etc/samples/elec_lo_snare.wav and /dev/null differ
diff --git a/etc/samples/elec_mid_snare.flac b/etc/samples/elec_mid_snare.flac
new file mode 100644
index 0000000..f0d2cb6
Binary files /dev/null and b/etc/samples/elec_mid_snare.flac differ
diff --git a/etc/samples/elec_mid_snare.wav b/etc/samples/elec_mid_snare.wav
deleted file mode 100644
index bcb92a7..0000000
Binary files a/etc/samples/elec_mid_snare.wav and /dev/null differ
diff --git a/etc/samples/elec_ping.flac b/etc/samples/elec_ping.flac
new file mode 100644
index 0000000..1ab31f7
Binary files /dev/null and b/etc/samples/elec_ping.flac differ
diff --git a/etc/samples/elec_ping.wav b/etc/samples/elec_ping.wav
deleted file mode 100644
index 7d4489f..0000000
Binary files a/etc/samples/elec_ping.wav and /dev/null differ
diff --git a/etc/samples/elec_plip.flac b/etc/samples/elec_plip.flac
new file mode 100644
index 0000000..b1978b7
Binary files /dev/null and b/etc/samples/elec_plip.flac differ
diff --git a/etc/samples/elec_plip.wav b/etc/samples/elec_plip.wav
deleted file mode 100644
index d61460d..0000000
Binary files a/etc/samples/elec_plip.wav and /dev/null differ
diff --git a/etc/samples/elec_pop.flac b/etc/samples/elec_pop.flac
new file mode 100644
index 0000000..88de47d
Binary files /dev/null and b/etc/samples/elec_pop.flac differ
diff --git a/etc/samples/elec_pop.wav b/etc/samples/elec_pop.wav
deleted file mode 100644
index f14f167..0000000
Binary files a/etc/samples/elec_pop.wav and /dev/null differ
diff --git a/etc/samples/elec_snare.flac b/etc/samples/elec_snare.flac
new file mode 100644
index 0000000..4248bc3
Binary files /dev/null and b/etc/samples/elec_snare.flac differ
diff --git a/etc/samples/elec_snare.wav b/etc/samples/elec_snare.wav
deleted file mode 100644
index c05502a..0000000
Binary files a/etc/samples/elec_snare.wav and /dev/null differ
diff --git a/etc/samples/elec_soft_kick.flac b/etc/samples/elec_soft_kick.flac
new file mode 100644
index 0000000..b966854
Binary files /dev/null and b/etc/samples/elec_soft_kick.flac differ
diff --git a/etc/samples/elec_soft_kick.wav b/etc/samples/elec_soft_kick.wav
deleted file mode 100644
index eac25fe..0000000
Binary files a/etc/samples/elec_soft_kick.wav and /dev/null differ
diff --git a/etc/samples/elec_tick.flac b/etc/samples/elec_tick.flac
new file mode 100644
index 0000000..2efde00
Binary files /dev/null and b/etc/samples/elec_tick.flac differ
diff --git a/etc/samples/elec_tick.wav b/etc/samples/elec_tick.wav
deleted file mode 100644
index c367398..0000000
Binary files a/etc/samples/elec_tick.wav and /dev/null differ
diff --git a/etc/samples/elec_triangle.flac b/etc/samples/elec_triangle.flac
new file mode 100644
index 0000000..7d5fada
Binary files /dev/null and b/etc/samples/elec_triangle.flac differ
diff --git a/etc/samples/elec_triangle.wav b/etc/samples/elec_triangle.wav
deleted file mode 100644
index 8426bbd..0000000
Binary files a/etc/samples/elec_triangle.wav and /dev/null differ
diff --git a/etc/samples/elec_twang.flac b/etc/samples/elec_twang.flac
new file mode 100644
index 0000000..f9f68f9
Binary files /dev/null and b/etc/samples/elec_twang.flac differ
diff --git a/etc/samples/elec_twang.wav b/etc/samples/elec_twang.wav
deleted file mode 100644
index 8dc2650..0000000
Binary files a/etc/samples/elec_twang.wav and /dev/null differ
diff --git a/etc/samples/elec_twip.flac b/etc/samples/elec_twip.flac
new file mode 100644
index 0000000..283a7df
Binary files /dev/null and b/etc/samples/elec_twip.flac differ
diff --git a/etc/samples/elec_twip.wav b/etc/samples/elec_twip.wav
deleted file mode 100644
index 907ca16..0000000
Binary files a/etc/samples/elec_twip.wav and /dev/null differ
diff --git a/etc/samples/elec_wood.flac b/etc/samples/elec_wood.flac
new file mode 100644
index 0000000..ff263dc
Binary files /dev/null and b/etc/samples/elec_wood.flac differ
diff --git a/etc/samples/elec_wood.wav b/etc/samples/elec_wood.wav
deleted file mode 100644
index aeec991..0000000
Binary files a/etc/samples/elec_wood.wav and /dev/null differ
diff --git a/etc/samples/guit_e_fifths.flac b/etc/samples/guit_e_fifths.flac
new file mode 100644
index 0000000..a317152
Binary files /dev/null and b/etc/samples/guit_e_fifths.flac differ
diff --git a/etc/samples/guit_e_fifths.wav b/etc/samples/guit_e_fifths.wav
deleted file mode 100644
index 76a2316..0000000
Binary files a/etc/samples/guit_e_fifths.wav and /dev/null differ
diff --git a/etc/samples/guit_e_slide.flac b/etc/samples/guit_e_slide.flac
new file mode 100644
index 0000000..1f65b46
Binary files /dev/null and b/etc/samples/guit_e_slide.flac differ
diff --git a/etc/samples/guit_e_slide.wav b/etc/samples/guit_e_slide.wav
deleted file mode 100644
index 6cfc64e..0000000
Binary files a/etc/samples/guit_e_slide.wav and /dev/null differ
diff --git a/etc/samples/guit_em9.flac b/etc/samples/guit_em9.flac
new file mode 100644
index 0000000..03ccccd
Binary files /dev/null and b/etc/samples/guit_em9.flac differ
diff --git a/etc/samples/guit_em9.wav b/etc/samples/guit_em9.wav
deleted file mode 100644
index 9212842..0000000
Binary files a/etc/samples/guit_em9.wav and /dev/null differ
diff --git a/etc/samples/guit_harmonics.flac b/etc/samples/guit_harmonics.flac
new file mode 100644
index 0000000..0f4d324
Binary files /dev/null and b/etc/samples/guit_harmonics.flac differ
diff --git a/etc/samples/guit_harmonics.wav b/etc/samples/guit_harmonics.wav
deleted file mode 100644
index d8ff492..0000000
Binary files a/etc/samples/guit_harmonics.wav and /dev/null differ
diff --git a/etc/samples/loop_amen.flac b/etc/samples/loop_amen.flac
new file mode 100644
index 0000000..0023491
Binary files /dev/null and b/etc/samples/loop_amen.flac differ
diff --git a/etc/samples/loop_amen.wav b/etc/samples/loop_amen.wav
deleted file mode 100644
index 0fc715a..0000000
Binary files a/etc/samples/loop_amen.wav and /dev/null differ
diff --git a/etc/samples/loop_amen_full.flac b/etc/samples/loop_amen_full.flac
new file mode 100644
index 0000000..e072cf5
Binary files /dev/null and b/etc/samples/loop_amen_full.flac differ
diff --git a/etc/samples/loop_amen_full.wav b/etc/samples/loop_amen_full.wav
deleted file mode 100644
index 563df3c..0000000
Binary files a/etc/samples/loop_amen_full.wav and /dev/null differ
diff --git a/etc/samples/loop_breakbeat.flac b/etc/samples/loop_breakbeat.flac
new file mode 100644
index 0000000..6b0851d
Binary files /dev/null and b/etc/samples/loop_breakbeat.flac differ
diff --git a/etc/samples/loop_breakbeat.wav b/etc/samples/loop_breakbeat.wav
deleted file mode 100644
index 610a2c8..0000000
Binary files a/etc/samples/loop_breakbeat.wav and /dev/null differ
diff --git a/etc/samples/loop_compus.flac b/etc/samples/loop_compus.flac
new file mode 100644
index 0000000..740f809
Binary files /dev/null and b/etc/samples/loop_compus.flac differ
diff --git a/etc/samples/loop_compus.wav b/etc/samples/loop_compus.wav
deleted file mode 100644
index 1af504a..0000000
Binary files a/etc/samples/loop_compus.wav and /dev/null differ
diff --git a/etc/samples/loop_garzul.flac b/etc/samples/loop_garzul.flac
new file mode 100644
index 0000000..89be4d1
Binary files /dev/null and b/etc/samples/loop_garzul.flac differ
diff --git a/etc/samples/loop_garzul.wav b/etc/samples/loop_garzul.wav
deleted file mode 100644
index 0524c91..0000000
Binary files a/etc/samples/loop_garzul.wav and /dev/null differ
diff --git a/etc/samples/loop_industrial.flac b/etc/samples/loop_industrial.flac
new file mode 100644
index 0000000..b762c34
Binary files /dev/null and b/etc/samples/loop_industrial.flac differ
diff --git a/etc/samples/loop_industrial.wav b/etc/samples/loop_industrial.wav
deleted file mode 100644
index ac068e9..0000000
Binary files a/etc/samples/loop_industrial.wav and /dev/null differ
diff --git a/etc/samples/loop_mika.flac b/etc/samples/loop_mika.flac
new file mode 100644
index 0000000..bb03397
Binary files /dev/null and b/etc/samples/loop_mika.flac differ
diff --git a/etc/samples/loop_mika.wav b/etc/samples/loop_mika.wav
deleted file mode 100644
index 6b0e839..0000000
Binary files a/etc/samples/loop_mika.wav and /dev/null differ
diff --git a/etc/samples/loop_safari.flac b/etc/samples/loop_safari.flac
new file mode 100644
index 0000000..0b965fb
Binary files /dev/null and b/etc/samples/loop_safari.flac differ
diff --git a/etc/samples/loop_tabla.flac b/etc/samples/loop_tabla.flac
new file mode 100644
index 0000000..baf95f4
Binary files /dev/null and b/etc/samples/loop_tabla.flac differ
diff --git a/etc/samples/misc_burp.flac b/etc/samples/misc_burp.flac
new file mode 100644
index 0000000..236b508
Binary files /dev/null and b/etc/samples/misc_burp.flac differ
diff --git a/etc/samples/misc_burp.wav b/etc/samples/misc_burp.wav
deleted file mode 100644
index 63dfaf6..0000000
Binary files a/etc/samples/misc_burp.wav and /dev/null differ
diff --git a/etc/samples/misc_cineboom.flac b/etc/samples/misc_cineboom.flac
new file mode 100644
index 0000000..e770212
Binary files /dev/null and b/etc/samples/misc_cineboom.flac differ
diff --git a/etc/samples/misc_crow.flac b/etc/samples/misc_crow.flac
new file mode 100644
index 0000000..ae866ae
Binary files /dev/null and b/etc/samples/misc_crow.flac differ
diff --git a/etc/samples/perc_bell.flac b/etc/samples/perc_bell.flac
new file mode 100644
index 0000000..d543e90
Binary files /dev/null and b/etc/samples/perc_bell.flac differ
diff --git a/etc/samples/perc_bell.wav b/etc/samples/perc_bell.wav
deleted file mode 100644
index 2c39d48..0000000
Binary files a/etc/samples/perc_bell.wav and /dev/null differ
diff --git a/etc/samples/perc_snap.flac b/etc/samples/perc_snap.flac
new file mode 100644
index 0000000..160cfd2
Binary files /dev/null and b/etc/samples/perc_snap.flac differ
diff --git a/etc/samples/perc_snap.wav b/etc/samples/perc_snap.wav
deleted file mode 100644
index 4bb908a..0000000
Binary files a/etc/samples/perc_snap.wav and /dev/null differ
diff --git a/etc/samples/perc_snap2.flac b/etc/samples/perc_snap2.flac
new file mode 100644
index 0000000..8e99917
Binary files /dev/null and b/etc/samples/perc_snap2.flac differ
diff --git a/etc/samples/perc_snap2.wav b/etc/samples/perc_snap2.wav
deleted file mode 100644
index 9013dc9..0000000
Binary files a/etc/samples/perc_snap2.wav and /dev/null differ
diff --git a/etc/samples/perc_swash.flac b/etc/samples/perc_swash.flac
new file mode 100644
index 0000000..265f60b
Binary files /dev/null and b/etc/samples/perc_swash.flac differ
diff --git a/etc/samples/perc_till.flac b/etc/samples/perc_till.flac
new file mode 100644
index 0000000..a6b9277
Binary files /dev/null and b/etc/samples/perc_till.flac differ
diff --git a/etc/samples/sn_dolf.flac b/etc/samples/sn_dolf.flac
new file mode 100644
index 0000000..121019d
Binary files /dev/null and b/etc/samples/sn_dolf.flac differ
diff --git a/etc/samples/sn_dolf.wav b/etc/samples/sn_dolf.wav
deleted file mode 100644
index e61a0b3a..0000000
Binary files a/etc/samples/sn_dolf.wav and /dev/null differ
diff --git a/etc/samples/sn_dub.flac b/etc/samples/sn_dub.flac
new file mode 100644
index 0000000..01236bb
Binary files /dev/null and b/etc/samples/sn_dub.flac differ
diff --git a/etc/samples/sn_dub.wav b/etc/samples/sn_dub.wav
deleted file mode 100644
index 485f8b2..0000000
Binary files a/etc/samples/sn_dub.wav and /dev/null differ
diff --git a/etc/samples/sn_zome.flac b/etc/samples/sn_zome.flac
new file mode 100644
index 0000000..cc8f3ba
Binary files /dev/null and b/etc/samples/sn_zome.flac differ
diff --git a/etc/samples/sn_zome.wav b/etc/samples/sn_zome.wav
deleted file mode 100644
index ca1bbd0..0000000
Binary files a/etc/samples/sn_zome.wav and /dev/null differ
diff --git a/etc/samples/tabla_dhec.flac b/etc/samples/tabla_dhec.flac
new file mode 100644
index 0000000..01e7a51
Binary files /dev/null and b/etc/samples/tabla_dhec.flac differ
diff --git a/etc/samples/tabla_ghe1.flac b/etc/samples/tabla_ghe1.flac
new file mode 100644
index 0000000..127023f
Binary files /dev/null and b/etc/samples/tabla_ghe1.flac differ
diff --git a/etc/samples/tabla_ghe2.flac b/etc/samples/tabla_ghe2.flac
new file mode 100644
index 0000000..1c07aae
Binary files /dev/null and b/etc/samples/tabla_ghe2.flac differ
diff --git a/etc/samples/tabla_ghe3.flac b/etc/samples/tabla_ghe3.flac
new file mode 100644
index 0000000..2f7fcc4
Binary files /dev/null and b/etc/samples/tabla_ghe3.flac differ
diff --git a/etc/samples/tabla_ghe4.flac b/etc/samples/tabla_ghe4.flac
new file mode 100644
index 0000000..331399d
Binary files /dev/null and b/etc/samples/tabla_ghe4.flac differ
diff --git a/etc/samples/tabla_ghe5.flac b/etc/samples/tabla_ghe5.flac
new file mode 100644
index 0000000..c96910a
Binary files /dev/null and b/etc/samples/tabla_ghe5.flac differ
diff --git a/etc/samples/tabla_ghe6.flac b/etc/samples/tabla_ghe6.flac
new file mode 100644
index 0000000..2dd9018
Binary files /dev/null and b/etc/samples/tabla_ghe6.flac differ
diff --git a/etc/samples/tabla_ghe7.flac b/etc/samples/tabla_ghe7.flac
new file mode 100644
index 0000000..0f8d6f0
Binary files /dev/null and b/etc/samples/tabla_ghe7.flac differ
diff --git a/etc/samples/tabla_ghe8.flac b/etc/samples/tabla_ghe8.flac
new file mode 100644
index 0000000..1572904
Binary files /dev/null and b/etc/samples/tabla_ghe8.flac differ
diff --git a/etc/samples/tabla_ke1.flac b/etc/samples/tabla_ke1.flac
new file mode 100644
index 0000000..69fef79
Binary files /dev/null and b/etc/samples/tabla_ke1.flac differ
diff --git a/etc/samples/tabla_ke2.flac b/etc/samples/tabla_ke2.flac
new file mode 100644
index 0000000..c6b6179
Binary files /dev/null and b/etc/samples/tabla_ke2.flac differ
diff --git a/etc/samples/tabla_ke3.flac b/etc/samples/tabla_ke3.flac
new file mode 100644
index 0000000..16d4031
Binary files /dev/null and b/etc/samples/tabla_ke3.flac differ
diff --git a/etc/samples/tabla_na.flac b/etc/samples/tabla_na.flac
new file mode 100644
index 0000000..6cf5dfd
Binary files /dev/null and b/etc/samples/tabla_na.flac differ
diff --git a/etc/samples/tabla_na_o.flac b/etc/samples/tabla_na_o.flac
new file mode 100644
index 0000000..a08eac5
Binary files /dev/null and b/etc/samples/tabla_na_o.flac differ
diff --git a/etc/samples/tabla_na_s.flac b/etc/samples/tabla_na_s.flac
new file mode 100644
index 0000000..d57ea77
Binary files /dev/null and b/etc/samples/tabla_na_s.flac differ
diff --git a/etc/samples/tabla_re.flac b/etc/samples/tabla_re.flac
new file mode 100644
index 0000000..1622fdd
Binary files /dev/null and b/etc/samples/tabla_re.flac differ
diff --git a/etc/samples/tabla_tas1.flac b/etc/samples/tabla_tas1.flac
new file mode 100644
index 0000000..4be4342
Binary files /dev/null and b/etc/samples/tabla_tas1.flac differ
diff --git a/etc/samples/tabla_tas2.flac b/etc/samples/tabla_tas2.flac
new file mode 100644
index 0000000..87b5cf1
Binary files /dev/null and b/etc/samples/tabla_tas2.flac differ
diff --git a/etc/samples/tabla_tas3.flac b/etc/samples/tabla_tas3.flac
new file mode 100644
index 0000000..0f1325f
Binary files /dev/null and b/etc/samples/tabla_tas3.flac differ
diff --git a/etc/samples/tabla_te1.flac b/etc/samples/tabla_te1.flac
new file mode 100644
index 0000000..b014669
Binary files /dev/null and b/etc/samples/tabla_te1.flac differ
diff --git a/etc/samples/tabla_te2.flac b/etc/samples/tabla_te2.flac
new file mode 100644
index 0000000..3fbd6e9
Binary files /dev/null and b/etc/samples/tabla_te2.flac differ
diff --git a/etc/samples/tabla_te_m.flac b/etc/samples/tabla_te_m.flac
new file mode 100644
index 0000000..09224b0
Binary files /dev/null and b/etc/samples/tabla_te_m.flac differ
diff --git a/etc/samples/tabla_te_ne.flac b/etc/samples/tabla_te_ne.flac
new file mode 100644
index 0000000..d6466c8
Binary files /dev/null and b/etc/samples/tabla_te_ne.flac differ
diff --git a/etc/samples/tabla_tun1.flac b/etc/samples/tabla_tun1.flac
new file mode 100644
index 0000000..7b56a52
Binary files /dev/null and b/etc/samples/tabla_tun1.flac differ
diff --git a/etc/samples/tabla_tun2.flac b/etc/samples/tabla_tun2.flac
new file mode 100644
index 0000000..a8f65df
Binary files /dev/null and b/etc/samples/tabla_tun2.flac differ
diff --git a/etc/samples/tabla_tun3.flac b/etc/samples/tabla_tun3.flac
new file mode 100644
index 0000000..a1d069e
Binary files /dev/null and b/etc/samples/tabla_tun3.flac differ
diff --git a/etc/samples/vinyl_backspin.flac b/etc/samples/vinyl_backspin.flac
new file mode 100644
index 0000000..4a9dc42
Binary files /dev/null and b/etc/samples/vinyl_backspin.flac differ
diff --git a/etc/samples/vinyl_hiss.flac b/etc/samples/vinyl_hiss.flac
new file mode 100644
index 0000000..47a6023
Binary files /dev/null and b/etc/samples/vinyl_hiss.flac differ
diff --git a/etc/samples/vinyl_rewind.flac b/etc/samples/vinyl_rewind.flac
new file mode 100644
index 0000000..3ae8569
Binary files /dev/null and b/etc/samples/vinyl_rewind.flac differ
diff --git a/etc/samples/vinyl_scratch.flac b/etc/samples/vinyl_scratch.flac
new file mode 100644
index 0000000..e20b016
Binary files /dev/null and b/etc/samples/vinyl_scratch.flac differ
diff --git a/etc/snippets/fx/compressor.sps b/etc/snippets/fx/compressor.sps
new file mode 100644
index 0000000..8b09258
--- /dev/null
+++ b/etc/snippets/fx/compressor.sps
@@ -0,0 +1,7 @@
+# key: fx c
+# point_line: 1
+# point_index: 2
+# --
+with_fx :compressor do
+
+end
diff --git a/etc/snippets/fx/fx.sps b/etc/snippets/fx/fx.sps
new file mode 100644
index 0000000..cf5f504
--- /dev/null
+++ b/etc/snippets/fx/fx.sps
@@ -0,0 +1,7 @@
+# key: fx
+# point_line: 0
+# point_index: 7
+# --
+with_fx do
+
+end
diff --git a/etc/synthdefs/compiled/sonic-pi-basic_mono_player.scsyndef b/etc/synthdefs/compiled/sonic-pi-basic_mono_player.scsyndef
index 09acf1e..36f3233 100644
Binary files a/etc/synthdefs/compiled/sonic-pi-basic_mono_player.scsyndef and b/etc/synthdefs/compiled/sonic-pi-basic_mono_player.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-basic_stereo_player.scsyndef b/etc/synthdefs/compiled/sonic-pi-basic_stereo_player.scsyndef
index 09568df..a965bca 100644
Binary files a/etc/synthdefs/compiled/sonic-pi-basic_stereo_player.scsyndef and b/etc/synthdefs/compiled/sonic-pi-basic_stereo_player.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-chipbass.scsyndef b/etc/synthdefs/compiled/sonic-pi-chipbass.scsyndef
new file mode 100644
index 0000000..81cce77
Binary files /dev/null and b/etc/synthdefs/compiled/sonic-pi-chipbass.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-chiplead.scsyndef b/etc/synthdefs/compiled/sonic-pi-chiplead.scsyndef
new file mode 100644
index 0000000..5c674d6
Binary files /dev/null and b/etc/synthdefs/compiled/sonic-pi-chiplead.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-chipnoise.scsyndef b/etc/synthdefs/compiled/sonic-pi-chipnoise.scsyndef
new file mode 100644
index 0000000..4e4f574
Binary files /dev/null and b/etc/synthdefs/compiled/sonic-pi-chipnoise.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-dtri.scsyndef b/etc/synthdefs/compiled/sonic-pi-dtri.scsyndef
new file mode 100644
index 0000000..857edeb
Binary files /dev/null and b/etc/synthdefs/compiled/sonic-pi-dtri.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-fx_compressor.scsyndef b/etc/synthdefs/compiled/sonic-pi-fx_compressor.scsyndef
index 25e53a8..fdd9b60 100644
Binary files a/etc/synthdefs/compiled/sonic-pi-fx_compressor.scsyndef and b/etc/synthdefs/compiled/sonic-pi-fx_compressor.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-fx_krush.scsyndef b/etc/synthdefs/compiled/sonic-pi-fx_krush.scsyndef
index 5dcce0d..afeb306 100644
Binary files a/etc/synthdefs/compiled/sonic-pi-fx_krush.scsyndef and b/etc/synthdefs/compiled/sonic-pi-fx_krush.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-fx_mono.scsyndef b/etc/synthdefs/compiled/sonic-pi-fx_mono.scsyndef
new file mode 100644
index 0000000..09dff74
Binary files /dev/null and b/etc/synthdefs/compiled/sonic-pi-fx_mono.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-fx_octaver.scsyndef b/etc/synthdefs/compiled/sonic-pi-fx_octaver.scsyndef
index 3d3ad45..f1dc371 100644
Binary files a/etc/synthdefs/compiled/sonic-pi-fx_octaver.scsyndef and b/etc/synthdefs/compiled/sonic-pi-fx_octaver.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-fx_tanh.scsyndef b/etc/synthdefs/compiled/sonic-pi-fx_tanh.scsyndef
index 2477eb0..794de93 100644
Binary files a/etc/synthdefs/compiled/sonic-pi-fx_tanh.scsyndef and b/etc/synthdefs/compiled/sonic-pi-fx_tanh.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-fx_vowel.scsyndef b/etc/synthdefs/compiled/sonic-pi-fx_vowel.scsyndef
new file mode 100644
index 0000000..533f0d2
Binary files /dev/null and b/etc/synthdefs/compiled/sonic-pi-fx_vowel.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-fx_whammy.scsyndef b/etc/synthdefs/compiled/sonic-pi-fx_whammy.scsyndef
new file mode 100644
index 0000000..b77ac16
Binary files /dev/null and b/etc/synthdefs/compiled/sonic-pi-fx_whammy.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-mono_player.scsyndef b/etc/synthdefs/compiled/sonic-pi-mono_player.scsyndef
index 8348cf9..cf01039 100644
Binary files a/etc/synthdefs/compiled/sonic-pi-mono_player.scsyndef and b/etc/synthdefs/compiled/sonic-pi-mono_player.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-pluck.scsyndef b/etc/synthdefs/compiled/sonic-pi-pluck.scsyndef
new file mode 100644
index 0000000..e67dc4d
Binary files /dev/null and b/etc/synthdefs/compiled/sonic-pi-pluck.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-sound_in.scsyndef b/etc/synthdefs/compiled/sonic-pi-sound_in.scsyndef
index d41d5c8..0bd1f2a 100644
Binary files a/etc/synthdefs/compiled/sonic-pi-sound_in.scsyndef and b/etc/synthdefs/compiled/sonic-pi-sound_in.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-sound_in_stereo.scsyndef b/etc/synthdefs/compiled/sonic-pi-sound_in_stereo.scsyndef
new file mode 100644
index 0000000..79428fc
Binary files /dev/null and b/etc/synthdefs/compiled/sonic-pi-sound_in_stereo.scsyndef differ
diff --git a/etc/synthdefs/compiled/sonic-pi-stereo_player.scsyndef b/etc/synthdefs/compiled/sonic-pi-stereo_player.scsyndef
index 54ab8ed..9fbf648 100644
Binary files a/etc/synthdefs/compiled/sonic-pi-stereo_player.scsyndef and b/etc/synthdefs/compiled/sonic-pi-stereo_player.scsyndef differ
diff --git a/etc/synthdefs/designs/sonic_pi/synths/basic.clj b/etc/synthdefs/designs/sonic_pi/synths/basic.clj
index 0fdf3c1..8309e4c 100644
--- a/etc/synthdefs/designs/sonic_pi/synths/basic.clj
+++ b/etc/synthdefs/designs/sonic_pi/synths/basic.clj
@@ -313,6 +313,50 @@
      (out out_bus (pan2 (* amp-fudge snd env) pan amp))))
 
 
+  (defsynth sonic-pi-dtri [note 52
+                          note_slide 0
+                          note_slide_shape 1
+                          note_slide_curve 0
+                          amp 1
+                          amp_slide 0
+                          amp_slide_shape 1
+                          amp_slide_curve 0
+                          pan 0
+                          pan_slide 0
+                          pan_slide_shape 1
+                          pan_slide_curve 0
+                          attack 0
+                          decay 0
+                          sustain 0
+                          release 1
+                          attack_level 1
+                          decay_level -1
+                          sustain_level 1
+                          env_curve 1
+                          cutoff 100
+                          cutoff_slide 0
+                          cutoff_slide_shape 1
+                          cutoff_slide_curve 0
+                          detune 0.1
+                          detune_slide 0
+                          detune_slide_shape 1
+                          detune_slide_curve 0
+                          out_bus 0]
+   (let [decay_level (select:kr (= -1 decay_level) [decay_level sustain_level])
+         note        (varlag note note_slide note_slide_curve note_slide_shape)
+         amp         (varlag amp amp_slide amp_slide_curve amp_slide_shape)
+         amp-fudge   1.1
+         pan         (varlag pan pan_slide pan_slide_curve pan_slide_shape)
+         detune      (varlag detune detune_slide detune_slide_curve detune_slide_shape)
+         cutoff      (varlag cutoff cutoff_slide cutoff_slide_curve cutoff_slide_shape)
+         freq        (midicps note)
+         cutoff-freq (midicps cutoff)
+         detune-freq (midicps (+ note detune))
+         snd         (normalizer (lpf (mix (lf-tri [freq detune-freq])) cutoff-freq))
+         env         (env-gen:kr (core/shaped-adsr attack decay sustain release attack_level decay_level sustain_level env_curve) :action FREE)]
+     (out out_bus (pan2 (* amp-fudge snd env) pan amp))))
+
+
  (defsynth sonic-pi-dpulse [note 52
                             note_slide 0
                             note_slide_shape 1
@@ -906,6 +950,7 @@
    (core/save-synthdef sonic-pi-subpulse)
    (core/save-synthdef sonic-pi-square)
    (core/save-synthdef sonic-pi-dsaw)
+   (core/save-synthdef sonic-pi-dtri)
    (core/save-synthdef sonic-pi-dpulse)
    (core/save-synthdef sonic-pi-fm)
 
diff --git a/etc/synthdefs/designs/sonic_pi/synths/chiptune.clj b/etc/synthdefs/designs/sonic_pi/synths/chiptune.clj
new file mode 100644
index 0000000..a126c61
--- /dev/null
+++ b/etc/synthdefs/designs/sonic_pi/synths/chiptune.clj
@@ -0,0 +1,149 @@
+;;--
+;; This file is part of Sonic Pi: http://sonic-pi.net
+;; Full project source: https://github.com/samaaron/sonic-pi
+;; License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
+;;
+;; Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
+;; All rights reserved.
+;;
+;; Permission is granted for use, copying, modification, and
+;; distribution of modified versions of this work as long as this
+;; notice is included.
+;;++
+
+(ns sonic-pi.synths.chiptune
+  (:use [overtone.live])
+  (:require [sonic-pi.synths.core :as core]))
+
+(without-namespace-in-synthdef
+
+  (defsynth sonic-pi-chiplead
+    [note 60
+     note_slide 0
+     note_slide_shape 1
+     note_slide_curve 0
+     note_resolution 0.1
+     amp 1
+     amp_slide 0
+     amp_slide_shape 1
+     amp_slide_curve 0
+     pan 0
+     pan_slide 0
+     pan_slide_shape 1
+     pan_slide_curve 0
+     attack 0
+     sustain 0
+     decay 0
+     release 1
+     attack_level 1
+     decay_level -1
+     sustain_level 1
+     env_curve 1
+     width 0
+     out_bus 0]
+    (let [decay_level (select:kr (= -1 decay_level) [decay_level sustain_level])
+          note        (round-down (varlag note note_slide note_slide_curve note_slide_shape) note_resolution)
+          freq        (midicps note)
+          amp         (varlag amp amp_slide amp_slide_curve amp_slide_shape)
+          amp-fudge   0.8
+          pan         (varlag pan pan_slide pan_slide_curve pan_slide_shape)
+          width       (select:kr width [0.125
+                                        0.25
+                                        0.5])
+          snd         (softclip (pulse freq width))
+          env         (env-gen (core/shaped-adsr attack decay sustain release attack_level decay_level sustain_level env_curve) :action FREE)
+          snd         (* amp-fudge snd env)]
+
+      (out out_bus (pan2 snd pan amp))))
+
+  (defsynth sonic-pi-chipbass
+    [note 60
+     note_slide 0
+     note_slide_shape 1
+     note_slide_curve 0
+     note_resolution 0
+     amp 1
+     amp_slide 0
+     amp_slide_shape 1
+     amp_slide_curve 0
+     pan 0
+     pan_slide 0
+     pan_slide_shape 1
+     pan_slide_curve 0
+     attack 0
+     sustain 0
+     decay 0
+     release 1
+     attack_level 1
+     decay_level -1
+     sustain_level 1
+     env_curve 1
+     out_bus 0]
+    (let [decay_level (select:kr (= -1 decay_level) [decay_level sustain_level])
+          note        (round-down (varlag note note_slide note_slide_curve note_slide_shape) note_resolution)
+          freq        (midicps note)
+          amp         (varlag amp amp_slide amp_slide_curve amp_slide_shape)
+          amp-fudge   1
+          pan         (varlag pan pan_slide pan_slide_curve pan_slide_shape)
+          snd         (lin-lin (demand:ar (impulse:ar (* 32 freq)) 0 (dseq [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0] INF)) 0 15 -1 1)
+          env         (env-gen (core/shaped-adsr attack decay sustain release attack_level decay_level sustain_level env_curve) :action FREE)
+          snd         (* amp-fudge snd env)]
+
+      (out out_bus (pan2 snd pan amp))))
+
+  (defsynth sonic-pi-chipnoise
+    [amp 1
+     amp_slide 0
+     amp_slide_shape 0
+     amp_slide_curve 0
+     pan 0
+     pan_slide 0
+     pan_slide_shape 1
+     pan_slide_curve 0
+     attack 0
+     sustain 0
+     decay 0
+     release 1
+     attack_level 1
+     decay_level -1
+     sustain_level 1
+     env_curve 1
+     freq_band 0
+     freq_band_slide 0
+     freq_band_slide_shape 1
+     freq_band_slide_curve 0
+     out_bus 0]
+    (let [decay_level (select:kr (= -1 decay_level) [decay_level sustain_level])
+          amp         (varlag amp amp_slide amp_slide_curve amp_slide_shape)
+          amp-fudge   0.8
+          pan         (varlag pan pan_slide pan_slide_curve pan_slide_shape)
+          ;; Frequency bands taken from information on http://nesdev.com/NESSOUND.txt
+          freq_band   (floor (varlag freq_band freq_band_slide freq_band_slide_curve freq_band_slide_shape))
+          noise_freq  (select:kr freq_band [1.0
+                                            2.0
+                                            4.0
+                                            5.34
+                                            8.0
+                                            10.68
+                                            16.0
+                                            19.03
+                                            25.4
+                                            32.0
+                                            42.71
+                                            64.0
+                                            128.0
+                                            256.0
+                                            512.0
+                                            1024.0])
+          snd         (softclip (lfd-clip-noise (* 220  noise_freq)))
+          env         (env-gen (core/shaped-adsr attack decay sustain release attack_level decay_level sustain_level env_curve) :action FREE)
+          snd         (* amp-fudge snd env)]
+
+      (out out_bus (pan2 snd pan amp))))
+
+ (comment
+   (core/save-synthdef sonic-pi-chipnoise)
+   (core/save-synthdef sonic-pi-chiplead)
+   (core/save-synthdef sonic-pi-chipbass)
+ )
+)
diff --git a/etc/synthdefs/designs/sonic_pi/synths/core.clj b/etc/synthdefs/designs/sonic_pi/synths/core.clj
index 87e1a4a..eaaab4c 100644
--- a/etc/synthdefs/designs/sonic_pi/synths/core.clj
+++ b/etc/synthdefs/designs/sonic_pi/synths/core.clj
@@ -71,4 +71,20 @@
    attack_level  attack  env_curve 0
    decay_level   decay   env_curve 0
    sustain_level sustain env_curve 0
-   min           release env_curve 0] ))
+   min           release env_curve 0] )
+
+  ([attack
+    decay
+    sustain
+    release
+    init_level
+    attack_level
+    decay_level
+    sustain_level
+    release_level
+    env_curve]
+  [init_level 4 -99 -99
+   attack_level  attack  env_curve 0
+   decay_level   decay   env_curve 0
+   sustain_level sustain env_curve 0
+   release_level release env_curve 0] ))
diff --git a/etc/synthdefs/designs/sonic_pi/synths/fx.clj b/etc/synthdefs/designs/sonic_pi/synths/fx.clj
index 7c322b4..1d013ea 100644
--- a/etc/synthdefs/designs/sonic_pi/synths/fx.clj
+++ b/etc/synthdefs/designs/sonic_pi/synths/fx.clj
@@ -18,6 +18,160 @@
 
 (without-namespace-in-synthdef
 
+ (defsynth sonic-pi-fx_mono
+   [amp 1
+    amp_slide 0
+    amp_slide_shape 1
+    amp_slide_curve 0
+    mix 1
+    mix_slide 0
+    mix_slide_shape 1
+    mix_slide_curve 0
+    pan 0
+    pan_slide 0
+    pan_slide_shape 1
+    pan_slide_curve 0
+    in_bus 0
+    out_bus 0]
+   (let [amp           (varlag amp amp_slide amp_slide_curve amp_slide_shape)
+         mix           (varlag mix mix_slide mix_slide_curve mix_slide_shape)
+         pan           (varlag pan pan_slide pan_slide_curve pan_slide_shape)
+
+         [in-l in-r]   (in in_bus 2)
+         mono          (sum [in-l in-r])
+         [new-l new-r] (pan2 mono pan amp)
+
+         fin-l         (x-fade2 in-l new-l (- (* mix 2) 1) amp)
+         fin-r         (x-fade2 in-r new-r (- (* mix 2) 1) amp)]
+     (out out_bus [fin-l fin-r])))
+
+ (defsynth sonic-pi-fx_vowel
+    [amp 1
+     amp_slide 0
+     amp_slide_shape 1
+     amp_slide_curve 0
+     mix 1
+     mix_slide 0
+     mix_slide_shape 1
+     mix_slide_curve 0
+     voice 0
+     vowel_sound 1
+     pre_amp 1
+     pre_amp_slide 0
+     pre_amp_slide_shape 1
+     pre_amp_slide_curve 0
+     in_bus 0
+     out_bus 0]
+    (let [amp                 (varlag amp amp_slide amp_slide_curve amp_slide_shape)
+          pre_amp             (varlag pre_amp pre_amp_slide pre_amp_slide_curve pre_amp_slide_shape)
+          mix                 (varlag mix mix_slide mix_slide_curve mix_slide_shape)
+          freqs               [800, 1150, 2900, 3900, 4950
+                               350, 2000, 2800, 3600, 4950
+                               270, 2140, 2950, 3900, 4950
+                               450, 800, 2830, 3800, 4950
+                               325, 700, 2700, 3800, 4950
+                               800, 1150, 2800, 3500, 4950
+                               400, 1600, 2700, 3300, 4950
+                               350, 1700, 2700, 3700, 4950
+                               450, 800, 2830, 3500, 4950
+                               325, 700, 2530, 3500, 4950
+                               660, 1120, 2750, 3000, 3350
+                               440, 1800, 2700, 3000, 3300
+                               270, 1850, 2900, 3350, 3590
+                               430, 820, 2700, 3000, 3300
+                               370, 630, 2750, 3000, 3400
+                               650, 1080, 2650, 2900, 3250
+                               400, 1700, 2600, 3200, 3580
+                               290, 1870, 2800, 3250, 3540
+                               400, 800, 2600, 2800, 3000
+                               350, 600, 2700, 2900, 3300
+                               600, 1040, 2250, 2450, 2750
+                               400, 1620, 2400, 2800, 3100
+                               250, 1750, 2600, 3050, 3340
+                               400, 750, 2400, 2600, 2900
+                               350, 600, 2400, 2675, 2950]
+          amps                [1.0 0.5011872336272722 0.025118864315095784 0.09999999999999998 0.0031622776601683764
+                               1.0 0.09999999999999998 0.17782794100389226 0.009999999999999995 0.0015848931924611136
+                               1.0 0.251188643150958 0.050118723362727206 0.050118723362727206 0.006309573444801925
+                               1.0 0.2818382931264453 0.0794328234724281 0.0794328234724281 0.0031622776601683764
+                               1.0 0.1584893192461113 0.017782794100389226 0.009999999999999995 9.999999999999994E-4
+                               1.0 0.6309573444801931 0.09999999999999998 0.015848931924611127 9.999999999999994E-4
+                               1.0 0.06309573444801932 0.031622776601683784 0.017782794100389226 9.999999999999994E-4
+                               1.0 0.09999999999999998 0.031622776601683784 0.015848931924611127 9.999999999999994E-4
+                               1.0 0.3548133892335754 0.1584893192461113 0.03981071705534973 0.001778279410038922
+                               1.0 0.251188643150958 0.031622776601683784 0.009999999999999995 6.309573444801923E-4
+                               1.0 0.5011872336272722 0.07079457843841379 0.06309573444801932 0.012589254117941666
+                               1.0 0.19952623149688797 0.12589254117941667 0.09999999999999998 0.09999999999999998
+                               1.0 0.06309573444801932 0.06309573444801932 0.015848931924611127 0.015848931924611127
+                               1.0 0.3162277660168379 0.050118723362727206 0.0794328234724281 0.019952623149688792
+                               1.0 0.09999999999999998 0.07079457843841379 0.031622776601683784 0.019952623149688792
+                               1.0 0.5011872336272722 0.44668359215096315 0.3981071705534972 0.0794328234724281
+                               1.0 0.19952623149688797 0.251188643150958 0.19952623149688797 0.09999999999999998
+                               1.0 0.17782794100389226 0.12589254117941667 0.09999999999999998 0.031622776601683784
+                               1.0 0.3162277660168379 0.251188643150958 0.251188643150958 0.050118723362727206
+                               1.0 0.09999999999999998 0.14125375446227542 0.19952623149688797 0.050118723362727206
+                               1.0 0.44668359215096315 0.3548133892335754 0.3548133892335754 0.09999999999999998
+                               1.0 0.251188643150958 0.3548133892335754 0.251188643150958 0.12589254117941667
+                               1.0 0.031622776601683784 0.1584893192461113 0.0794328234724281 0.03981071705534973
+                               1.0 0.2818382931264453 0.08912509381337454 0.09999999999999998 0.009999999999999995
+                               1.0 0.09999999999999998 0.025118864315095784 0.03981071705534973 0.015848931924611127]
+          bws                 [1/80 1/90 1/120 1/130 1/140
+                               1/60 1/100 1/120 1/150 1/200
+                               1/60 1/90 1/100 1/120 1/120
+                               1/70 1/80 1/100 1/130 1/135
+                               1/50 1/60 1/170 1/180 1/200
+                               1/80 1/90 1/120 1/130 1/140
+                               1/60 1/80 1/120 1/150 1/200
+                               1/50 1/100 1/120 1/150 1/200
+                               1/70 1/80 1/100 1/130 1/135
+                               1/50 1/60 1/170 1/180 1/200
+                               1/80 1/90 1/120 1/130 1/140
+                               1/70 1/80 1/100 1/120 1/120
+                               1/40 1/90 1/100 1/120 1/120
+                               1/40 1/80 1/100 1/120 1/120
+                               1/40 1/60 1/100 1/120 1/120
+                               1/80 1/90 1/120 1/130 1/140
+                               1/70 1/80 1/100 1/120 1/120
+                               1/40 1/90 1/100 1/120 1/120
+                               1/40 1/80 1/100 1/120 1/120
+                               1/40 1/60 1/100 1/120 1/120
+                               1/60 1/70 1/110 1/120 1/130
+                               1/40 1/80 1/100 1/120 1/120
+                               1/60 1/90 1/100 1/120 1/120
+                               1/40 1/80 1/100 1/120 1/120
+                               1/40 1/80 1/100 1/120 1/120]
+          ;; voice is 0 indexed, vowel_sound is 1 indexed
+          vowel_freq_one     (select:kr (+ (* 5 voice) (- (* 5 vowel_sound) 5)) freqs)
+          vowel_freq_two     (select:kr (+ (* 5 voice) (- (* 5 vowel_sound) 4)) freqs)
+          vowel_freq_three   (select:kr (+ (* 5 voice) (- (* 5 vowel_sound) 3)) freqs)
+          vowel_freq_four    (select:kr (+ (* 5 voice) (- (* 5 vowel_sound) 2)) freqs)
+          vowel_freq_five    (select:kr (+ (* 5 voice) (- (* 5 vowel_sound) 1)) freqs)
+          vowel_amp_one      (select:kr (+ (* 5 voice) (- (* 5 vowel_sound) 5)) amps)
+          vowel_amp_two      (select:kr (+ (* 5 voice) (- (* 5 vowel_sound) 4)) amps)
+          vowel_amp_three    (select:kr (+ (* 5 voice) (- (* 5 vowel_sound) 3)) amps)
+          vowel_amp_four     (select:kr (+ (* 5 voice) (- (* 5 vowel_sound) 2)) amps)
+          vowel_amp_five     (select:kr (+ (* 5 voice) (- (* 5 vowel_sound) 1)) amps)
+          vowel_bw_one       (select:kr (+ (* 5 voice) (- (* 5 vowel_sound) 5)) bws)
+          vowel_bw_two       (select:kr (+ (* 5 voice) (- (* 5 vowel_sound) 4)) bws)
+          vowel_bw_three     (select:kr (+ (* 5 voice) (- (* 5 vowel_sound) 3)) bws)
+          vowel_bw_four      (select:kr (+ (* 5 voice) (- (* 5 vowel_sound) 2)) bws)
+          vowel_bw_five      (select:kr (+ (* 5 voice) (- (* 5 vowel_sound) 1)) bws)
+          amp-fudge          5
+          [in-l in-r]        (* (* amp-fudge pre_amp) (in in_bus 2))
+          new-l              (+ (b-band-pass in-l vowel_freq_one (* vowel_bw_one vowel_amp_one))
+                                (b-band-pass in-l vowel_freq_two (* vowel_bw_two vowel_amp_two))
+                                (b-band-pass in-l vowel_freq_three (* vowel_bw_three vowel_amp_three))
+                                (b-band-pass in-l vowel_freq_four (* vowel_bw_four vowel_amp_four))
+                                (b-band-pass in-l vowel_freq_five (* vowel_bw_five vowel_amp_five)))
+          new-r              (+ (b-band-pass in-r vowel_freq_one (* vowel_bw_one vowel_amp_one))
+                                (b-band-pass in-r vowel_freq_two (* vowel_bw_two vowel_amp_two))
+                                (b-band-pass in-r vowel_freq_three (* vowel_bw_three vowel_amp_three))
+                                (b-band-pass in-r vowel_freq_four (* vowel_bw_four vowel_amp_four))
+                                (b-band-pass in-r vowel_freq_five (* vowel_bw_five vowel_amp_five)))
+          fin-l              (x-fade2 in-l new-l (- (* mix 2) 1) (* amp-fudge amp))
+          fin-r              (x-fade2 in-r new-r (- (* mix 2) 1) (* amp-fudge amp))]
+      (out out_bus [fin-l fin-r])))
+
  (defsynth sonic-pi-fx_krush
    [amp 1
     amp_slide 0
@@ -53,12 +207,16 @@
          res         (lin-lin res 1 0 0 1)
          res         (varlag res res_slide res_slide_curve res_slide_shape)
          cutoff-freq (midicps cutoff)
+         [in-l in-r] (* pre_amp (in in_bus 2))
+
+         new-l-abs   (abs in-l)
+         new-l-sqr   (squared new-l-abs)
+         new-l       (/ (+ new-l-sqr (* gain new-l-abs)) (+ new-l-sqr (* new-l-abs (- gain 1)) 1))
+
+         new-r-abs   (abs in-r)
+         new-r-sqr   (squared new-r-abs)
+         new-r       (/ (+ new-r-sqr (* gain new-r-abs)) (+ new-r-sqr (* new-r-abs (- gain 1)) 1))
 
-         [in-l in-r] (abs (* pre_amp (in in_bus 2)))
-         new-l-sqr   (squared in-l)
-         new-l       (/ (+ new-l-sqr (* gain in-l)) (+ new-l-sqr (* in-l (- gain 1)) 1))
-         new-r-sqr   (squared in-r)
-         new-r       (/ (+ new-r-sqr (* gain in-r)) (+ new-r-sqr (* in-r (- gain 1)) 1))
          new-l       (rlpf new-l cutoff-freq res)
          new-r       (rlpf new-r cutoff-freq res)
          fin-l       (x-fade2 in-l new-l (- (* mix 2) 1) amp)
@@ -68,6 +226,53 @@
 
 
 
+  (defsynth sonic-pi-fx_whammy
+    [amp 1
+     amp_slide 0
+     amp_slide_shape 1
+     amp_slide_curve 0
+     mix 1
+     mix_slide 0
+     mix_slide_shape 1
+     mix_slide_curve 0
+     transpose 12
+     transpose_slide 0
+     transpose_slide_shape 1
+     transpose_slide_curve 0
+     deltime 0.05
+     max_delay_time 1
+     grainsize 0.075
+     pre_amp 1
+     pre_amp_slide 0
+     pre_amp_slide_shape 1
+     pre_amp_slide_curve 0
+     in_bus 0
+     out_bus 0]
+    (let [amp             (varlag amp amp_slide amp_slide_curve amp_slide_shape)
+          mix             (varlag mix mix_slide mix_slide_curve mix_slide_shape)
+          pre_amp         (varlag pre_amp pre_amp_slide pre_amp_slide_curve pre_amp_slide_shape)
+          transpose       (varlag (midiratio transpose) transpose_slide transpose_slide_curve transpose_slide_shape)
+          grainfreq       (/ transpose grainsize)
+          [in-l in-r]     (in in_bus 2)
+          new-l           (leak-dc (* (delay-c :in (* pre_amp in-l)
+                                               :max-delay-time max_delay_time
+                                               :delay-time (+ (* (lf-saw grainfreq 1.0)
+                                                                 (/ grainsize -2))
+                                                               deltime))
+                                      (lin-lin (sin-osc grainfreq
+                                                        (/ (* -1 Math/PI) 2))
+                                               -1 1 0 1 )))
+          new-r           (leak-dc (* (delay-c :in (* pre_amp in-r)
+                                               :max-delay-time max_delay_time
+                                               :delay-time (+ (* (lf-saw grainfreq 0.0)
+                                                                 (/ grainsize -2))
+                                                               deltime))
+                                      (lin-lin (sin-osc grainfreq
+                                                        (/ Math/PI 2))
+                                             -1 1 0 1 )))
+          fin-l           (x-fade2 in-l new-l (- (* mix 2) 1) amp)
+          fin-r           (x-fade2 in-r new-r (- (* mix 2) 1) amp)]
+          (out out_bus [fin-l fin-r])))
 
  (defsynth sonic-pi-fx_tanh
    [amp 1
@@ -78,7 +283,7 @@
     mix_slide 0
     mix_slide_shape 1
     mix_slide_curve 0
-    krunch 1
+    krunch 5
     krunch_slide 0
     krunch_slide_shape 1
     krunch_slide_curve 0
@@ -93,9 +298,11 @@
          pre_amp       (varlag pre_amp pre_amp_slide pre_amp_slide_curve pre_amp_slide_shape)
          krunch        (varlag krunch krunch_slide krunch_slide_curve krunch_slide_shape)
          krunch        (select:kr (= 0 krunch) [krunch 0.0001])
+         krunch        (* 5 krunch)
          [in-l in-r]   (* pre_amp (in in_bus 2))
          [new-l new-r] (* (/ (tanh (* krunch [in-l in-r])) krunch) (+ 1 (/ krunch 8)))
 
+
          fin-l         (x-fade2 in-l new-l (- (* mix 2) 1) amp)
          fin-r         (x-fade2 in-r new-r (- (* mix 2) 1) amp)]
      (out out_bus [fin-l fin-r])))
@@ -764,25 +971,26 @@
     relax_time_slide_curve 0
     in_bus 0
     out_bus 0]
-   (let [amp           (varlag amp amp_slide amp_slide_curve amp_slide_shape)
-         mix           (varlag mix mix_slide mix_slide_curve mix_slide_shape)
-         pre_amp       (varlag pre_amp pre_amp_slide pre_amp_slide_curve pre_amp_slide_shape)
-         threshold     (varlag threshold threshold_slide threshold_slide_curve threshold_slide_shape)
-         clamp_time    (varlag clamp_time clamp_time_slide clamp_time_slide_curve clamp_time_slide_shape)
-         slope_above   (varlag slope_above slope_above_slide slope_above_slide_curve slope_above_slide_shape)
-         slope_below   (varlag slope_below slope_below_slide slope_below_slide_curve slope_below_slide_shape)
-         relax_time    (varlag relax_time relax_time_slide relax_time_slide_curve relax_time_slide_shape)
-
-         src           (* pre_amp (in in_bus 2))
-         [in-l in-r]   src
-
-         control-sig   (/ (+ in-l in-r) 2)
-
-         [new-l new-r] (compander src control-sig threshold
-                                  slope_below slope_above
-                                  clamp_time relax_time)
-         fin-l         (x-fade2 in-l new-l (- (* mix 2) 1) amp)
-         fin-r         (x-fade2 in-r new-r (- (* mix 2) 1) amp)]
+   (let [amp                       (varlag amp amp_slide amp_slide_curve amp_slide_shape)
+         mix                       (varlag mix mix_slide mix_slide_curve mix_slide_shape)
+         pre_amp                   (varlag pre_amp pre_amp_slide pre_amp_slide_curve pre_amp_slide_shape)
+         threshold                 (varlag threshold threshold_slide threshold_slide_curve threshold_slide_shape)
+         clamp_time                (varlag clamp_time clamp_time_slide clamp_time_slide_curve clamp_time_slide_shape)
+         slope_above               (varlag slope_above slope_above_slide slope_above_slide_curve slope_above_slide_shape)
+         slope_below               (varlag slope_below slope_below_slide slope_below_slide_curve slope_below_slide_shape)
+         relax_time                (varlag relax_time relax_time_slide relax_time_slide_curve relax_time_slide_shape)
+
+         src                       (in in_bus 2)
+         [orig-in-l orig-in-r]     src
+         pre-amped-src             (* pre_amp src)
+         [pre-amped-l pre-amped-r] pre-amped-src
+         control-sig               (/ (+ pre-amped-l pre-amped-r) 2)
+
+         [new-l new-r]             (compander pre-amped-src control-sig threshold
+                                              slope_below slope_above
+                                              clamp_time relax_time)
+         fin-l                     (x-fade2 orig-in-l new-l (- (* mix 2) 1) amp)
+         fin-r                     (x-fade2 orig-in-r new-r (- (* mix 2) 1) amp)]
      (out out_bus [fin-l fin-r])))
 
  (defsynth sonic-pi-fx_band_eq
@@ -1334,33 +1542,33 @@
      amp_slide 0
      amp_slide_shape 1
      amp_slide_curve 0
-     oct1_amp 1
-     oct1_amp_slide 0
-     oct1_amp_slide_shape 1
-     oct1_amp_slide_curve 0
-     oct2_amp 1
-     oct2_amp_slide 0
-     oct2_amp_slide_shape 1
-     oct2_amp_slide_curve 0
-     oct3_amp 1
-     oct3_amp_slide 0
-     oct3_amp_slide_shape 1
-     oct3_amp_slide_curve 0
+     super_amp 1
+     super_amp_slide 0
+     super_amp_slide_shape 1
+     super_amp_slide_curve 0
+     sub_amp 1
+     sub_amp_slide 0
+     sub_amp_slide_shape 1
+     sub_amp_slide_curve 0
+     subsub_amp 1
+     subsub_amp_slide 0
+     subsub_amp_slide_shape 1
+     subsub_amp_slide_curve 0
      in_bus 0
      out_bus 0]
     (let [amp           (varlag amp amp_slide amp_slide_curve amp_slide_shape)
-          oct1_amp      (varlag oct1_amp oct1_amp_slide oct1_amp_slide_curve oct1_amp_slide_shape)
-          oct2_amp      (varlag oct2_amp oct2_amp_slide oct2_amp_slide_curve oct2_amp_slide_shape)
-          oct3_amp      (varlag oct3_amp oct3_amp_slide oct3_amp_slide_curve oct3_amp_slide_shape)
+          super_amp     (varlag super_amp super_amp_slide super_amp_slide_curve super_amp_slide_shape)
+          sub_amp       (varlag sub_amp sub_amp_slide sub_amp_slide_curve sub_amp_slide_shape)
+          subsub_amp    (varlag subsub_amp subsub_amp_slide subsub_amp_slide_curve subsub_amp_slide_shape)
           mix           (varlag mix mix_slide mix_slide_curve mix_slide_shape)
           pre_amp       (varlag pre_amp pre_amp_slide pre_amp_slide_curve pre_amp_slide_shape)
           direct-lpf    (lpf (* pre_amp (in in_bus 2)) 440)
-          super-oct     (abs direct-lpf)
+          super-oct     (* 2 (leak-dc (abs direct-lpf))) ;; Compensate for resulting wave being half amplitude
           sub-oct       (toggle-ff:ar direct-lpf)
           sub-sub-oct   (toggle-ff:ar sub-oct)
 
           [in-l in-r]   (* pre_amp (in in_bus 2))
-          [new-l new-r] (+ (* super-oct oct1_amp) (* direct-lpf sub-oct oct2_amp) (* direct-lpf sub-sub-oct oct3_amp))
+          [new-l new-r] (+ (* super-oct super_amp) (* direct-lpf sub-oct sub_amp) (* direct-lpf sub-sub-oct subsub_amp))
           fin-l         (x-fade2 in-l new-l (- (* mix 2) 1) amp)
           fin-r         (x-fade2 in-r new-r (- (* mix 2) 1) amp)]
       (out out_bus [fin-l fin-r])))
@@ -1517,6 +1725,7 @@
 )
 
 (comment
+  (core/save-synthdef sonic-pi-fx_mono)
   (core/save-synthdef sonic-pi-fx_krush)
   (core/save-synthdef sonic-pi-fx_bitcrusher)
   (core/save-synthdef sonic-pi-fx_reverb)
@@ -1544,8 +1753,9 @@
   (core/save-synthdef sonic-pi-fx_rbpf)
   (core/save-synthdef sonic-pi-fx_nrbpf)
   (core/save-synthdef sonic-pi-fx_tanh)
+  (core/save-synthdef sonic-pi-fx_whammy)
   (core/save-synthdef sonic-pi-fx_pitch_shift)
   (core/save-synthdef sonic-pi-fx_ring_mod)
   (core/save-synthdef sonic-pi-fx_octaver)
   (core/save-synthdef sonic-pi-fx_flanger)
-  )
+  (core/save-synthdef sonic-pi-fx_vowel))
diff --git a/etc/synthdefs/designs/sonic_pi/synths/samplers.clj b/etc/synthdefs/designs/sonic_pi/synths/samplers.clj
index 4979b72..3ae3288 100644
--- a/etc/synthdefs/designs/sonic_pi/synths/samplers.clj
+++ b/etc/synthdefs/designs/sonic_pi/synths/samplers.clj
@@ -24,36 +24,53 @@
     amp_slide 0
     amp_slide_shape 1
     amp_slide_curve 0
+    attack [0.0 :ir]
+    decay [0 :ir]
+    sustain [-1 :ir]
+    release [0.0 :ir]
+    attack_level [1 :ir]
+    decay_level [-1 :ir]
+    sustain_level [1 :ir]
+    env_curve [1 :ir]
     pan 0
     pan_slide 0
     pan_slide_shape 1
     pan_slide_curve 0
-    cutoff 0
-    cutoff_slide 0
-    cutoff_slide_shape 1
-    cutoff_slide_curve 0
-    res 0
-    res_slide 0
-    res_slide_shape 1
-    res_slide_curve 0
+    lpf -1
+    lpf_slide 0
+    lpf_slide_shape 1
+    lpf_slide_curve 0
+    hpf -1
+    hpf_slide 0
+    hpf_slide_shape 1
+    hpf_slide_curve 0
     rate [1 :ir]
     out_bus [0 :ir]]
 
-   (let [amp         (varlag amp amp_slide amp_slide_curve amp_slide_shape)
-         pan         (varlag pan pan_slide pan_slide_curve pan_slide_shape)
-         cutoff      (varlag cutoff cutoff_slide cutoff_slide_curve cutoff_slide_shape)
-         res         (varlag res res_slide res_slide_curve res_slide_shape)
-         res         (lin-lin:kr res 1 0 0 1)
-         scaled-rate (* rate (buf-rate-scale:ir buf))
-         cutoff-freq (midicps cutoff)
-         use-filter  (> cutoff 0)
-         dur         (* (/ 1 (abs rate)) (buf-dur:ir buf))
-         start       (select:kr (< rate 0) [0
-                                            (- (buf-frames:ir buf) 1)])
-         snd         (play-buf 1 buf scaled-rate 0 start)
-         snd         (select use-filter [snd (rlpf snd cutoff-freq res)])
-         killer      (line:kr 1 1 (+ 0.03 dur) FREE)]
-
+   (let [amp            (varlag amp amp_slide amp_slide_curve amp_slide_shape)
+         pan            (varlag pan pan_slide pan_slide_curve pan_slide_shape)
+         lpf            (varlag lpf lpf_slide lpf_slide_curve lpf_slide_shape)
+         hpf            (varlag hpf hpf_slide hpf_slide_curve hpf_slide_shape)
+         scaled-rate    (* rate (buf-rate-scale:ir buf))
+         lpf-freq       (midicps lpf)
+         hpf-freq       (midicps hpf)
+         use-lpf-filter (> lpf -1)
+         use-hpf-filter (> hpf -1)
+         dur            (* (/ 1 (abs rate)) (buf-dur:ir buf))
+         start          (select:kr (< rate 0) [0
+                                               (- (buf-frames:ir buf) 1)])
+         sustain        (select:kr (= -1 sustain) [sustain (- dur attack release decay)])
+         decay_level    (select:kr (= -1 decay_level) [decay_level sustain_level])
+         env-dur        (+ attack sustain decay release)
+         env            (env-gen (core/shaped-adsr attack decay sustain release attack_level decay_level sustain_level env_curve))
+         snd            (play-buf 1 buf scaled-rate 0 start)
+
+         snd            (select use-lpf-filter [snd (overtone.live/lpf snd lpf-freq)])
+         snd            (select use-hpf-filter [snd (overtone.live/hpf snd hpf-freq)])
+
+
+         snd            (* env snd)]
+     (line:kr 1 1 (+ 0.03 (min dur env-dur)) FREE)
      (out out_bus (pan2 snd pan amp))))
 
  (defsynth sonic-pi-basic_stereo_player
@@ -62,39 +79,56 @@
     amp_slide 0
     amp_slide_shape 1
     amp_slide_curve 0
+    attack [0.0 :ir]
+    decay [0 :ir]
+    sustain [-1 :ir]
+    release [0.0 :ir]
+    attack_level [1 :ir]
+    decay_level [-1 :ir]
+    sustain_level [1 :ir]
+    env_curve [1 :ir]
     pan 0
     pan_slide 0
     pan_slide_shape 1
     pan_slide_curve 0
-    cutoff 0
-    cutoff_slide 0
-    cutoff_slide_shape 1
-    cutoff_slide_curve 0
-    res 0
-    res_slide 0
-    res_slide_shape 1
-    res_slide_curve 0
+    lpf -1
+    lpf_slide 0
+    lpf_slide_shape 1
+    lpf_slide_curve 0
+    hpf -1
+    hpf_slide 0
+    hpf_slide_shape 1
+    hpf_slide_curve 0
     rate [1 :ir]
     out_bus [0 :ir]]
 
-   (let [amp           (varlag amp amp_slide amp_slide_curve amp_slide_shape)
-         pan           (varlag pan pan_slide pan_slide_curve pan_slide_shape)
-         cutoff        (varlag cutoff cutoff_slide cutoff_slide_curve cutoff_slide_shape)
-         res           (varlag res res_slide res_slide_curve res_slide_shape)
-         res           (lin-lin:kr res 1 0 0 1)
-         scaled-rate   (* rate (buf-rate-scale:ir buf))
-         cutoff-freq   (midicps cutoff)
-         use-filter    (> cutoff 0)
-         dur           (* (/ 1 (abs rate)) (buf-dur:ir buf))
-         start         (select:kr (< rate 0) [0
-                                              (- (buf-frames:ir buf) 1)])
-         [snd-l snd-r] (play-buf 2 buf scaled-rate 0 start)
-         snd-l         (select use-filter [snd-l (rlpf snd-l cutoff-freq res)])
-         snd-r         (select use-filter [snd-r (rlpf snd-r cutoff-freq res)])
-         killer        (line:kr 1 1 (+ 0.03 dur) FREE)
-
-         snd           (balance2 snd-l snd-r pan amp)]
-
+   (let [amp            (varlag amp amp_slide amp_slide_curve amp_slide_shape)
+         pan            (varlag pan pan_slide pan_slide_curve pan_slide_shape)
+         lpf            (varlag lpf lpf_slide lpf_slide_curve lpf_slide_shape)
+         hpf            (varlag hpf hpf_slide hpf_slide_curve hpf_slide_shape)
+         scaled-rate    (* rate (buf-rate-scale:ir buf))
+         lpf-freq       (midicps lpf)
+         hpf-freq       (midicps hpf)
+         use-lpf-filter (> lpf -1)
+         use-hpf-filter (> hpf -1)
+         dur            (* (/ 1 (abs rate)) (buf-dur:ir buf))
+         sustain        (select:kr (= -1 sustain) [sustain (- dur attack release decay)])
+         decay_level    (select:kr (= -1 decay_level) [decay_level sustain_level])
+         env-dur        (+ attack sustain decay release)
+         env            (env-gen (core/shaped-adsr attack decay sustain release attack_level decay_level sustain_level env_curve))
+         start          (select:kr (< rate 0) [0
+                                               (- (buf-frames:ir buf) 1)])
+         [snd-l snd-r]  (play-buf 2 buf scaled-rate 0 start)
+         snd-l          (select use-lpf-filter [snd-l (overtone.live/lpf snd-l lpf-freq)])
+         snd-r          (select use-lpf-filter [snd-r (overtone.live/lpf snd-r lpf-freq)])
+
+         snd-l          (select use-hpf-filter [snd-l (overtone.live/hpf snd-l hpf-freq)])
+         snd-r          (select use-hpf-filter [snd-r (overtone.live/hpf snd-r hpf-freq)])
+
+         snd-l          (* env snd-l)
+         snd-r          (* env snd-r)
+         snd            (balance2 snd-l snd-r pan amp)]
+     (line:kr 1 1 (+ 0.03 (min dur env-dur)) FREE)
      (out out_bus snd)))
 
 
@@ -110,26 +144,7 @@
     pan_slide 0
     pan_slide_shape 1
     pan_slide_curve 0
-    cutoff -1
-    cutoff_slide 0
-    cutoff_slide_shape 1
-    cutoff_slide_curve 0
-    cutoff_attack 0
-    cutoff_sustain -1
-    cutoff_decay 0
-    cutoff_release 0
-    cutoff_min -1
-    cutoff_min_slide 0
-    cutoff_min_slide_shape 1
-    cutoff_min_slide_curve 0
-    cutoff_attack_level [-1 :ir]
-    cutoff_decay_level [-1 :ir]
-    cutoff_sustain_level [-1 :ir]
-    cutoff_env_curve 1
-    res 0
-    res_slide 0
-    res_slide_shape 1
-    res_slide_curve 0
+
     attack [0.0 :ir]
     decay [0 :ir]
     sustain [-1 :ir]
@@ -141,6 +156,50 @@
     rate 1
     start 0
     finish 1
+
+    lpf -1
+    lpf_slide 0
+    lpf_slide_shape 1
+    lpf_slide_curve 0
+
+    lpf_attack 0
+    lpf_sustain -1
+    lpf_decay 0
+    lpf_release 0
+
+    lpf_min -1
+    lpf_min_slide 0
+    lpf_min_slide_shape 1
+    lpf_min_slide_curve 0
+
+    lpf_init_level [-1 :ir]
+    lpf_attack_level [-1 :ir]
+    lpf_decay_level [-1 :ir]
+    lpf_sustain_level [-1 :ir]
+    lpf_release_level [-1 :ir]
+    lpf_env_curve 1
+
+    hpf -1
+    hpf_slide 0
+    hpf_slide_shape 1
+    hpf_slide_curve 0
+
+    hpf_max -1
+    hpf_max_slide 0
+    hpf_max_slide_shape 1
+    hpf_max_slide_curve 0
+
+    hpf_attack 0
+    hpf_sustain -1
+    hpf_decay 0
+    hpf_release 0
+    hpf_init_level [-1 :ir]
+    hpf_attack_level [-1 :ir]
+    hpf_decay_level [-1 :ir]
+    hpf_sustain_level [-1 :ir]
+    hpf_release_level [-1 :ir]
+    hpf_env_curve 1
+
     norm 0
     pitch 0
     pitch_slide 0
@@ -158,82 +217,199 @@
     time_dis_slide 0
     time_dis_slide_shape 1
     time_dis_slide_curve 0
+    compress 0
+    pre_amp 1
+    pre_amp_slide 0
+    pre_amp_slide_shape 1
+    pre_amp_slide_curve 0
+    threshold 0.2
+    threshold_slide 0
+    threshold_slide_shape 1
+    threshold_slide_curve 0
+    clamp_time 0.01
+    clamp_time_slide 0
+    clamp_time_slide_shape 1
+    clamp_time_slide_curve 0
+    slope_above 0.5
+    slope_above_slide 0
+    slope_above_slide_shape 1
+    slope_above_slide_curve 0
+    slope_below 1
+    slope_below_slide 0
+    slope_below_slide_shape 1
+    slope_below_slide_curve 0
+    relax_time 0.01
+    relax_time_slide 0
+    relax_time_slide_shape 1
+    relax_time_slide_curve 0
     out_bus 0]
-   (let [decay_level               (select:kr (= -1 decay_level) [decay_level sustain_level])
-         amp                       (varlag amp amp_slide amp_slide_curve amp_slide_shape)
-         pan                       (varlag pan pan_slide pan_slide_curve pan_slide_shape)
-         used_cutoff               (not= -1 cutoff)
-         used_cutoff_attack_level  (not= -1 cutoff_attack_level)
-         used_cutoff_decay_level   (not= -1 cutoff_decay_level)
-         used_cutoff_sustain_level (not= -1 cutoff_sustain_level)
-         used_cutoff_attack        (not= 0  cutoff_attack)
-         used_cutoff_decay         (not= 0  cutoff_decay)
-         used_cutoff_release       (not= 0  cutoff_release)
-         used_cutoff_sustain       (not= -1  cutoff_sustain)
-         used_cutoff_min           (not= -1 cutoff_min)
-         use-filter-env            (or used_cutoff_attack_level
-                                       used_cutoff_decay_level
-                                       used_cutoff_sustain_level
-                                       used_cutoff_attack
-                                       used_cutoff_decay
-                                       used_cutoff_release
-                                       used_cutoff_sustain
-                                       used_cutoff_min)
-
-         use-filter                (or used_cutoff
-                                       use-filter-env)
-
-
-         cutoff                    (select:kr (= -1 cutoff) [cutoff 130])
-         cutoff_min                (select:kr (= -1 cutoff_min) [cutoff_min 50])
-         cutoff_attack_level       (select:kr (= -1 cutoff_attack_level) [cutoff_attack_level cutoff])
-
-         cutoff_sustain_level      (select:kr (= -1 cutoff_sustain_level) [cutoff_sustain_level cutoff_attack_level])
-         cutoff_decay_level        (select:kr (= -1 cutoff_decay_level) [cutoff_decay_level cutoff_sustain_level])
-
-         cutoff                    (varlag cutoff cutoff_slide cutoff_slide_curve cutoff_slide_shape)
-         pitch                     (varlag pitch pitch_slide pitch_slide_curve pitch_slide_shape)
-         window_size               (varlag window_size window_size_slide window_size_slide_curve window_size_slide_shape)
-         pitch_dis                 (varlag pitch_dis pitch_dis_slide pitch_dis_slide_curve pitch_dis_slide_shape)
-         time_dis                  (varlag time_dis time_dis_slide time_dis_slide_curve time_dis_slide_shape)
-         cutoff_min                (varlag cutoff_min cutoff_min_slide cutoff_min_slide_curve cutoff_min_slide_shape)
-         pitch_ratio               (midiratio pitch)
-         res                       (lin-lin res 1 0 0 1)
-         res                       (varlag res res_slide res_slide_curve res_slide_shape)
-         cutoff-freq               (midicps cutoff)
-         cutoff-min-freq           (midicps cutoff_min)
-
-         n-frames                  (- (buf-frames buf) 1)
-         start-pos                 (* start n-frames)
-         end-pos                   (* finish n-frames)
-         n-start-pos               (select:kr (not-pos? rate) [start-pos end-pos])
-         n-end-pos                 (select:kr (not-pos? rate) [end-pos start-pos])
-         rate                      (abs rate)
-         play-time                 (/ (* (buf-dur buf) (absdif finish start))
-                                      rate)
-         phase                     (line:ar :start n-start-pos :end n-end-pos :dur play-time)
-         sustain                   (select:kr (= -1 sustain) [sustain (- play-time attack release decay)])
-         cutoff_sustain            (select:kr (= -1 cutoff_sustain) [cutoff_sustain (- play-time cutoff_attack cutoff_release cutoff_decay)])
-         env                       (env-gen (core/shaped-adsr attack decay sustain release attack_level decay_level sustain_level env_curve))
-         filt-env                  (midicps (env-gen (core/shaped-adsr cutoff_attack, cutoff_decay cutoff_sustain cutoff_release cutoff_attack_level cutoff_decay_level cutoff_sustain_level cutoff_env_curve cutoff_min)))
-
-         snd                       (buf-rd 1 buf phase)
-         killer                    (line:kr 1 1 (+ 0.03 play-time) FREE)
-
-         snd                       (select:ar (not= 0 pitch)
-                                              [snd
-                                               (pitch-shift snd window_size pitch_ratio pitch_dis time_dis)])
-
-         filt-env                  (select use-filter-env [cutoff-freq (min filt-env cutoff-freq)])
-         snd                       (select use-filter
-                                           [snd
-                                            (rlpf snd filt-env res)])
-
-         snd                       (select norm [snd (normalizer snd)])
-         snd                       (* env snd)
-
-
-         snd                       (pan2 snd pan amp)]
+  (let [decay_level            (select:kr (= -1 decay_level) [decay_level sustain_level])
+
+        amp                    (varlag amp amp_slide amp_slide_curve amp_slide_shape)
+        pan                    (varlag pan pan_slide pan_slide_curve pan_slide_shape)
+        lpf                    (varlag lpf lpf_slide lpf_slide_curve lpf_slide_shape)
+        lpf_min                (varlag lpf_min lpf_min_slide lpf_min_slide_curve lpf_min_slide_shape)
+        hpf                    (varlag hpf hpf_slide hpf_slide_curve hpf_slide_shape)
+        hpf_max                (varlag hpf_max hpf_max_slide hpf_max_slide_curve hpf_max_slide_shape)
+        pitch                  (varlag pitch pitch_slide pitch_slide_curve pitch_slide_shape)
+        window_size            (varlag window_size window_size_slide window_size_slide_curve window_size_slide_shape)
+        pitch_dis              (varlag pitch_dis pitch_dis_slide pitch_dis_slide_curve pitch_dis_slide_shape)
+        time_dis               (varlag time_dis time_dis_slide time_dis_slide_curve time_dis_slide_shape)
+
+        pre_amp                (varlag pre_amp pre_amp_slide pre_amp_slide_curve pre_amp_slide_shape)
+        threshold              (varlag threshold threshold_slide threshold_slide_curve threshold_slide_shape)
+        clamp_time             (varlag clamp_time clamp_time_slide clamp_time_slide_curve clamp_time_slide_shape)
+
+        slope_above            (varlag slope_above slope_above_slide slope_above_slide_curve slope_above_slide_shape)
+        slope_below            (varlag slope_below slope_below_slide slope_below_slide_curve slope_below_slide_shape)
+        relax_time             (varlag relax_time relax_time_slide relax_time_slide_curve relax_time_slide_shape)
+
+        used_lpf               (not= -1 lpf)
+
+        used_lpf_init_level    (not= -1 lpf_init_level)
+        used_lpf_attack_level  (not= -1 lpf_attack_level)
+        used_lpf_decay_level   (not= -1 lpf_decay_level)
+        used_lpf_sustain_level (not= -1 lpf_sustain_level)
+        used_lpf_release_level (not= -1 lpf_release_level)
+
+        used_lpf_attack        (not= 0  lpf_attack)
+        used_lpf_decay         (not= 0  lpf_decay)
+        used_lpf_release       (not= 0  lpf_release)
+        used_lpf_sustain       (not= -1 lpf_sustain)
+        used_lpf_min           (not= -1 lpf_min)
+
+        used_hpf               (not= -1 hpf)
+        used_hpf_init_level    (not= -1 hpf_init_level)
+        used_hpf_attack_level  (not= -1 hpf_attack_level)
+        used_hpf_decay_level   (not= -1 hpf_decay_level)
+        used_hpf_sustain_level (not= -1 hpf_sustain_level)
+        used_hpf_release_level (not= -1 hpf_release_level)
+
+        used_hpf_attack        (not= 0  hpf_attack)
+        used_hpf_decay         (not= 0  hpf_decay)
+        used_hpf_release       (not= 0  hpf_release)
+        used_hpf_sustain       (not= -1 hpf_sustain)
+        used_hpf_max           (not= -1 hpf_max)
+
+        use-lpf-env            (or used_lpf_attack_level
+                                   used_lpf_decay_level
+                                   used_lpf_sustain_level
+                                   used_lpf_attack
+                                   used_lpf_decay
+                                   used_lpf_release
+                                   used_lpf_sustain
+                                   used_lpf_min)
+
+        use-hpf-env            (or used_hpf_init_level
+                                   used_hpf_attack_level
+                                   used_hpf_decay_level
+                                   used_hpf_sustain_level
+                                   used_hpf_release_level
+                                   used_hpf_attack
+                                   used_hpf_decay
+                                   used_hpf_release
+                                   used_hpf_sustain
+                                   used_hpf_max)
+
+        use-lpf                (or used_lpf
+                                   use-lpf-env)
+
+
+        use-hpf                (or used_hpf
+                                   use-hpf-env)
+
+        lpf                    (select:kr used_lpf [130 lpf])
+        hpf                    (select:kr used_hpf [50 hpf])
+        hpf_max                (select:kr used_hpf_max [200 hpf_max])
+        lpf_min                (select:kr used_lpf_min [30 lpf_min])
+
+        lpf_release_level      (select:kr used_lpf_release_level [lpf lpf_release_level])
+        lpf_sustain_level      (select:kr used_lpf_sustain_level [lpf_release_level lpf_sustain_level])
+        lpf_decay_level        (select:kr used_lpf_decay_level [lpf_sustain_level lpf_decay_level])
+        lpf_attack_level       (select:kr used_lpf_attack_level [lpf_decay_level lpf_attack_level])
+        lpf_init_level         (select:kr used_lpf_init_level [lpf_min lpf_init_level])
+
+        hpf_release_level      (select:kr used_hpf_release_level [hpf hpf_release_level])
+        hpf_sustain_level      (select:kr used_hpf_sustain_level [hpf_release_level hpf_sustain_level])
+        hpf_decay_level        (select:kr used_hpf_decay_level [hpf_sustain_level hpf_decay_level])
+        hpf_attack_level       (select:kr used_hpf_attack_level [hpf_decay_level hpf_attack_level])
+        hpf_init_level         (select:kr used_hpf_init_level [130 hpf_init_level])
+
+        lpf_attack             (select:kr used_lpf_attack [attack lpf_attack])
+        lpf_decay              (select:kr used_lpf_decay [decay lpf_decay])
+        lpf_sustain            (select:kr used_lpf_sustain [sustain lpf_sustain])
+        lpf_release            (select:kr used_lpf_release [release lpf_release])
+
+        hpf_attack             (select:kr used_hpf_attack [attack hpf_attack])
+        hpf_decay              (select:kr used_hpf_decay [decay hpf_decay])
+        hpf_sustain            (select:kr used_hpf_sustain [sustain hpf_sustain])
+        hpf_release            (select:kr used_hpf_release [release hpf_release])
+
+        pitch_ratio            (midiratio pitch)
+        lpf-freq               (midicps lpf)
+        hpf-freq               (midicps hpf)
+        hpf_max                (midicps hpf_max)
+        lpf_min                (midicps lpf_min)
+
+        n-frames               (- (buf-frames buf) 1)
+        start-pos              (* start n-frames)
+        end-pos                (* finish n-frames)
+        n-start-pos            (select:kr (not-pos? rate) [start-pos end-pos])
+        n-end-pos              (select:kr (not-pos? rate) [end-pos start-pos])
+        rate                   (abs rate)
+        play-time              (/ (* (buf-dur buf) (absdif finish start))
+                                  rate)
+        phase                  (line:ar :start n-start-pos :end n-end-pos :dur play-time)
+        sustain                (select:kr (= -1 sustain) [sustain (- play-time attack release decay)])
+        lpf_sustain            (select:kr (= -1 lpf_sustain) [lpf_sustain (- play-time lpf_attack lpf_release lpf_decay)])
+        hpf_sustain            (select:kr (= -1 hpf_sustain) [hpf_sustain (- play-time hpf_attack hpf_release hpf_decay)])
+        env-dur                (+ attack sustain decay release)
+        env                    (env-gen (core/shaped-adsr attack decay sustain release attack_level decay_level sustain_level env_curve))
+        lpf-env                (midicps (env-gen (core/shaped-adsr lpf_attack, lpf_decay lpf_sustain (+ 0.1 lpf_release) lpf_init_level lpf_attack_level lpf_decay_level lpf_sustain_level lpf_release_level lpf_env_curve)))
+        hpf-env                (midicps (env-gen (core/shaped-adsr hpf_attack, hpf_decay hpf_sustain (+ 0.1 hpf_release) hpf_init_level hpf_attack_level hpf_decay_level hpf_sustain_level hpf_release_level hpf_env_curve)))
+
+        lpf-env                (select use-lpf-env [lpf-freq (min lpf-freq
+                                                                  (max lpf-env lpf_min))])
+        hpf-env                (select use-hpf-env [hpf-freq (max hpf-freq
+                                                                  (min hpf-env hpf_max))])
+
+
+        snd                    (* pre_amp (buf-rd 1 buf phase))
+
+        snd                    (select:ar (not= 0 pitch)
+                                          [snd
+                                           (pitch-shift snd window_size pitch_ratio pitch_dis time_dis)])
+
+        lpf-env                (select use-lpf-env [lpf-freq (min lpf-env lpf-freq)])
+        hpf-env                (select use-hpf-env [hpf-freq (max hpf-freq
+
+
+
+                                                                  (min hpf-env hpf_max))])
+
+
+
+
+        snd                    (select use-lpf
+                                       [snd
+                                        (overtone.live/lpf snd lpf-env)])
+
+        snd                    (select use-hpf
+                                       [snd
+                                        (overtone.live/hpf snd hpf-env)])
+
+        snd                    (select norm [snd (normalizer snd)])
+        snd                    (* env snd)
+
+        compressed             (compander snd snd threshold
+                                          slope_below slope_above
+                                          clamp_time relax_time)
+
+        snd                    (select:ar compress [snd compressed])
+
+
+        snd                    (pan2 snd pan amp)]
+     (line:kr 1 1 (+ 0.03 (min play-time env-dur)) FREE)
      (out out_bus snd)))
 
  (defsynth sonic-pi-stereo_player
@@ -248,26 +424,7 @@
     pan_slide 0
     pan_slide_shape 1
     pan_slide_curve 0
-    cutoff -1
-    cutoff_slide 0
-    cutoff_slide_shape 1
-    cutoff_slide_curve 0
-    cutoff_attack 0
-    cutoff_sustain -1
-    cutoff_decay 0
-    cutoff_release 0
-    cutoff_min -1
-    cutoff_min_slide 0
-    cutoff_min_slide_shape 1
-    cutoff_min_slide_curve 0
-    cutoff_attack_level [-1 :ir]
-    cutoff_decay_level [-1 :ir]
-    cutoff_sustain_level [-1 :ir]
-    cutoff_env_curve 1
-    res 0
-    res_slide 0
-    res_slide_shape 1
-    res_slide_curve 0
+
     attack [0.0 :ir]
     decay [0 :ir]
     sustain [-1 :ir]
@@ -279,6 +436,50 @@
     rate 1
     start 0
     finish 1
+
+    lpf -1
+    lpf_slide 0
+    lpf_slide_shape 1
+    lpf_slide_curve 0
+
+    lpf_attack 0
+    lpf_sustain -1
+    lpf_decay 0
+    lpf_release 0
+
+    lpf_min -1
+    lpf_min_slide 0
+    lpf_min_slide_shape 1
+    lpf_min_slide_curve 0
+
+    lpf_init_level [-1 :ir]
+    lpf_attack_level [-1 :ir]
+    lpf_decay_level [-1 :ir]
+    lpf_sustain_level [-1 :ir]
+    lpf_release_level [-1 :ir]
+    lpf_env_curve 1
+
+    hpf -1
+    hpf_slide 0
+    hpf_slide_shape 1
+    hpf_slide_curve 0
+
+    hpf_max -1
+    hpf_max_slide 0
+    hpf_max_slide_shape 1
+    hpf_max_slide_curve 0
+
+    hpf_attack 0
+    hpf_sustain -1
+    hpf_decay 0
+    hpf_release 0
+    hpf_init_level [-1 :ir]
+    hpf_attack_level [-1 :ir]
+    hpf_decay_level [-1 :ir]
+    hpf_sustain_level [-1 :ir]
+    hpf_release_level [-1 :ir]
+    hpf_env_curve 1
+
     norm 0
     pitch 0
     pitch_slide 0
@@ -296,87 +497,205 @@
     time_dis_slide 0
     time_dis_slide_shape 1
     time_dis_slide_curve 0
+    compress 0
+    pre_amp 1
+    pre_amp_slide 0
+    pre_amp_slide_shape 1
+    pre_amp_slide_curve 0
+    threshold 0.2
+    threshold_slide 0
+    threshold_slide_shape 1
+    threshold_slide_curve 0
+    clamp_time 0.01
+    clamp_time_slide 0
+    clamp_time_slide_shape 1
+    clamp_time_slide_curve 0
+    slope_above 0.5
+    slope_above_slide 0
+    slope_above_slide_shape 1
+    slope_above_slide_curve 0
+    slope_below 1
+    slope_below_slide 0
+    slope_below_slide_shape 1
+    slope_below_slide_curve 0
+    relax_time 0.01
+    relax_time_slide 0
+    relax_time_slide_shape 1
+    relax_time_slide_curve 0
     out_bus 0]
-   (let [decay_level               (select:kr (= -1 decay_level) [decay_level sustain_level])
-         amp                       (varlag amp amp_slide amp_slide_curve amp_slide_shape)
-         pan                       (varlag pan pan_slide pan_slide_curve pan_slide_shape)
-         used_cutoff               (not= -1 cutoff)
-         used_cutoff_attack_level  (not= -1 cutoff_attack_level)
-         used_cutoff_decay_level   (not= -1 cutoff_decay_level)
-         used_cutoff_sustain_level (not= -1 cutoff_sustain_level)
-         used_cutoff_attack        (not= 0  cutoff_attack)
-         used_cutoff_decay         (not= 0  cutoff_decay)
-         used_cutoff_release       (not= 0  cutoff_release)
-         used_cutoff_sustain       (not= -1  cutoff_sustain)
-         used_cutoff_min           (not= -1 cutoff_min)
-         use-filter-env            (or used_cutoff_attack_level
-                                       used_cutoff_decay_level
-                                       used_cutoff_sustain_level
-                                       used_cutoff_attack
-                                       used_cutoff_decay
-                                       used_cutoff_release
-                                       used_cutoff_sustain
-                                       used_cutoff_min)
-
-         use-filter                (or used_cutoff
-                                       use-filter-env)
-
-         cutoff                    (select:kr (= -1 cutoff) [cutoff 130])
-         cutoff_min                (select:kr (= -1 cutoff_min) [cutoff_min 50])
-         cutoff_attack_level       (select:kr (= -1 cutoff_attack_level) [cutoff_attack_level cutoff])
-
-         cutoff_sustain_level      (select:kr (= -1 cutoff_sustain_level) [cutoff_sustain_level cutoff_attack_level])
-         cutoff_decay_level        (select:kr (= -1 cutoff_decay_level) [cutoff_decay_level cutoff_sustain_level])
-
-         cutoff                    (varlag cutoff cutoff_slide cutoff_slide_curve cutoff_slide_shape)
-         pitch                     (varlag pitch pitch_slide pitch_slide_curve pitch_slide_shape)
-         window_size               (varlag window_size window_size_slide window_size_slide_curve window_size_slide_shape)
-         pitch_dis                 (varlag pitch_dis pitch_dis_slide pitch_dis_slide_curve pitch_dis_slide_shape)
-         time_dis                  (varlag time_dis time_dis_slide time_dis_slide_curve time_dis_slide_shape)
-         cutoff_min                (varlag cutoff_min cutoff_min_slide cutoff_min_slide_curve cutoff_min_slide_shape)
-         pitch_ratio               (midiratio pitch)
-         res                       (lin-lin res 1 0 0 1)
-         res                       (varlag res res_slide res_slide_curve res_slide_shape)
-         cutoff-freq               (midicps cutoff)
-
-         n-frames                  (- (buf-frames:ir buf) 1)
-         start-pos                 (* start n-frames)
-         end-pos                   (* finish n-frames)
-         n-start-pos               (select:kr (not-pos? rate) [start-pos end-pos])
-         n-end-pos                 (select:kr (not-pos? rate) [end-pos start-pos])
-         rate                      (abs rate)
-         play-time                 (/ (* (buf-dur buf) (absdif finish start))
-                                      rate)
-         phase                     (line:ar :start n-start-pos :end n-end-pos :dur play-time)
-         sustain                   (select:kr (= -1 sustain) [sustain (- play-time attack release decay)])
-         cutoff_sustain            (select:kr (= -1 cutoff_sustain) [cutoff_sustain (- play-time cutoff_attack cutoff_release cutoff_decay)])
-         env                       (env-gen (core/shaped-adsr attack decay sustain release attack_level decay_level sustain_level env_curve))
-         filt-env                  (midicps (env-gen (core/shaped-adsr cutoff_attack, cutoff_decay cutoff_sustain cutoff_release cutoff_attack_level cutoff_decay_level cutoff_sustain_level cutoff_env_curve cutoff_min)))
-
-         [snd-l snd-r]             (buf-rd 2 buf phase)
-         killer                    (line:kr 1 1 (+ 0.03 play-time) FREE)
-
-         snd-l                     (select:ar (not= 0 pitch)
-                                              [snd-l
-                                               (pitch-shift snd-l window_size pitch_ratio pitch_dis time_dis)])
-
-         snd-r                     (select:ar (not= 0 pitch)
-                                              [snd-r
-                                               (pitch-shift snd-r window_size pitch_ratio pitch_dis time_dis)])
-
-         filt-env                  (select use-filter-env [cutoff-freq (min filt-env cutoff-freq)])
-         snd-l                     (select use-filter [snd-l (rlpf snd-l filt-env res)])
-         snd-r                     (select use-filter [snd-r (rlpf snd-r filt-env res)])
-
-         snd-l                     (select norm [snd-l (normalizer snd-l)])
-         snd-r                     (select norm [snd-r (normalizer snd-r)])
-         snd-l                     (* env snd-l)
-         snd-r                     (* env snd-r)
-         snd                       (balance2 snd-l snd-r pan amp)]
-
-      (out out_bus snd)))
+   (let [decay_level            (select:kr (= -1 decay_level) [decay_level sustain_level])
+
+         amp                    (varlag amp amp_slide amp_slide_curve amp_slide_shape)
+         pan                    (varlag pan pan_slide pan_slide_curve pan_slide_shape)
+         lpf                    (varlag lpf lpf_slide lpf_slide_curve lpf_slide_shape)
+         lpf_min                (varlag lpf_min lpf_min_slide lpf_min_slide_curve lpf_min_slide_shape)
+         hpf                    (varlag hpf hpf_slide hpf_slide_curve hpf_slide_shape)
+         hpf_max                (varlag hpf_max hpf_max_slide hpf_max_slide_curve hpf_max_slide_shape)
+         pitch                  (varlag pitch pitch_slide pitch_slide_curve pitch_slide_shape)
+         window_size            (varlag window_size window_size_slide window_size_slide_curve window_size_slide_shape)
+         pitch_dis              (varlag pitch_dis pitch_dis_slide pitch_dis_slide_curve pitch_dis_slide_shape)
+         time_dis               (varlag time_dis time_dis_slide time_dis_slide_curve time_dis_slide_shape)
+
+         pre_amp                (varlag pre_amp pre_amp_slide pre_amp_slide_curve pre_amp_slide_shape)
+         threshold              (varlag threshold threshold_slide threshold_slide_curve threshold_slide_shape)
+         clamp_time             (varlag clamp_time clamp_time_slide clamp_time_slide_curve clamp_time_slide_shape)
+
+         slope_above            (varlag slope_above slope_above_slide slope_above_slide_curve slope_above_slide_shape)
+         slope_below            (varlag slope_below slope_below_slide slope_below_slide_curve slope_below_slide_shape)
+         relax_time             (varlag relax_time relax_time_slide relax_time_slide_curve relax_time_slide_shape)
+
+         used_lpf               (not= -1 lpf)
+
+         used_lpf_init_level    (not= -1 lpf_init_level)
+         used_lpf_attack_level  (not= -1 lpf_attack_level)
+         used_lpf_decay_level   (not= -1 lpf_decay_level)
+         used_lpf_sustain_level (not= -1 lpf_sustain_level)
+         used_lpf_release_level (not= -1 lpf_release_level)
+
+         used_lpf_attack        (not= 0  lpf_attack)
+         used_lpf_decay         (not= 0  lpf_decay)
+         used_lpf_release       (not= 0  lpf_release)
+         used_lpf_sustain       (not= -1 lpf_sustain)
+         used_lpf_min           (not= -1 lpf_min)
+
+         used_hpf               (not= -1 hpf)
+         used_hpf_init_level    (not= -1 hpf_init_level)
+         used_hpf_attack_level  (not= -1 hpf_attack_level)
+         used_hpf_decay_level   (not= -1 hpf_decay_level)
+         used_hpf_sustain_level (not= -1 hpf_sustain_level)
+         used_hpf_release_level (not= -1 hpf_release_level)
+
+         used_hpf_attack        (not= 0  hpf_attack)
+         used_hpf_decay         (not= 0  hpf_decay)
+         used_hpf_release       (not= 0  hpf_release)
+         used_hpf_sustain       (not= -1 hpf_sustain)
+         used_hpf_max           (not= -1 hpf_max)
+
+         use-lpf-env            (or used_lpf_attack_level
+                                    used_lpf_decay_level
+                                    used_lpf_sustain_level
+                                    used_lpf_attack
+                                    used_lpf_decay
+                                    used_lpf_release
+                                    used_lpf_sustain
+                                    used_lpf_min)
+
+         use-hpf-env            (or used_hpf_init_level
+                                    used_hpf_attack_level
+                                    used_hpf_decay_level
+                                    used_hpf_sustain_level
+                                    used_hpf_release_level
+                                    used_hpf_attack
+                                    used_hpf_decay
+                                    used_hpf_release
+                                    used_hpf_sustain
+                                    used_hpf_max)
+
+         use-lpf                (or used_lpf
+                                    use-lpf-env)
+
+
+         use-hpf                (or used_hpf
+                                    use-hpf-env)
+
+         lpf                    (select:kr used_lpf [130 lpf])
+         hpf                    (select:kr used_hpf [50 hpf])
+         hpf_max                (select:kr used_hpf_max [200 hpf_max])
+         lpf_min                (select:kr used_lpf_min [30 lpf_min])
+
+         lpf_release_level      (select:kr used_lpf_release_level [lpf lpf_release_level])
+         lpf_sustain_level      (select:kr used_lpf_sustain_level [lpf_release_level lpf_sustain_level])
+         lpf_decay_level        (select:kr used_lpf_decay_level [lpf_sustain_level lpf_decay_level])
+         lpf_attack_level       (select:kr used_lpf_attack_level [lpf_decay_level lpf_attack_level])
+         lpf_init_level         (select:kr used_lpf_init_level [lpf_min lpf_init_level])
+
+         hpf_release_level      (select:kr used_hpf_release_level [hpf hpf_release_level])
+         hpf_sustain_level      (select:kr used_hpf_sustain_level [hpf_release_level hpf_sustain_level])
+         hpf_decay_level        (select:kr used_hpf_decay_level [hpf_sustain_level hpf_decay_level])
+         hpf_attack_level       (select:kr used_hpf_attack_level [hpf_decay_level hpf_attack_level])
+         hpf_init_level         (select:kr used_hpf_init_level [130 hpf_init_level])
+
+         lpf_attack             (select:kr used_lpf_attack [attack lpf_attack])
+         lpf_decay              (select:kr used_lpf_decay [decay lpf_decay])
+         lpf_sustain            (select:kr used_lpf_sustain [sustain lpf_sustain])
+         lpf_release            (select:kr used_lpf_release [release lpf_release])
+
+         hpf_attack             (select:kr used_hpf_attack [attack hpf_attack])
+         hpf_decay              (select:kr used_hpf_decay [decay hpf_decay])
+         hpf_sustain            (select:kr used_hpf_sustain [sustain hpf_sustain])
+         hpf_release            (select:kr used_hpf_release [release hpf_release])
+
+
+         pitch_ratio            (midiratio pitch)
+         lpf-freq               (midicps lpf)
+         hpf-freq               (midicps hpf)
+         hpf_max                (midicps hpf_max)
+         lpf_min                (midicps lpf_min)
+
+         n-frames               (- (buf-frames buf) 1)
+         start-pos              (* start n-frames)
+         end-pos                (* finish n-frames)
+         n-start-pos            (select:kr (not-pos? rate) [start-pos end-pos])
+         n-end-pos              (select:kr (not-pos? rate) [end-pos start-pos])
+         rate                   (abs rate)
+         play-time              (/ (* (buf-dur buf) (absdif finish start))
+                                   rate)
+         phase                  (line:ar :start n-start-pos :end n-end-pos :dur play-time)
+         sustain                (select:kr (= -1 sustain) [sustain (- play-time attack release decay)])
+         lpf_sustain            (select:kr (= -1 lpf_sustain) [lpf_sustain (- play-time lpf_attack lpf_release lpf_decay)])
+         hpf_sustain            (select:kr (= -1 hpf_sustain) [hpf_sustain (- play-time hpf_attack hpf_release hpf_decay)])
+         env-dur                (+ attack sustain decay release)
+         env                    (env-gen (core/shaped-adsr attack decay sustain release attack_level decay_level sustain_level env_curve))
+         lpf-env                (midicps (env-gen (core/shaped-adsr lpf_attack, lpf_decay lpf_sustain (+ 0.1 lpf_release) lpf_init_level lpf_attack_level lpf_decay_level lpf_sustain_level lpf_release_level lpf_env_curve)))
+         hpf-env                (midicps (env-gen (core/shaped-adsr hpf_attack, hpf_decay hpf_sustain (+ 0.1 hpf_release) hpf_init_level hpf_attack_level hpf_decay_level hpf_sustain_level hpf_release_level hpf_env_curve)))
+
+         lpf-env                (select use-lpf-env [lpf-freq (min lpf-freq
+                                                                   (max lpf-env lpf_min))])
+         hpf-env                (select use-hpf-env [hpf-freq (max hpf-freq
+                                                                   (min hpf-env hpf_max))])
+
+         [snd-l snd-r]          (* pre_amp (buf-rd 2 buf phase))
+
+         snd-l                  (select:ar (not= 0 pitch)
+                                           [snd-l
+                                            (pitch-shift snd-l window_size pitch_ratio pitch_dis time_dis)])
+
+         snd-r                  (select:ar (not= 0 pitch)
+                                           [snd-r
+                                            (pitch-shift snd-r window_size pitch_ratio pitch_dis time_dis)])
+
+
+         snd-l                  (select use-lpf [snd-l (overtone.live/lpf snd-l lpf-env)])
+         snd-r                  (select use-lpf [snd-r (overtone.live/lpf snd-r lpf-env)])
+
+         snd-l                  (select use-hpf [snd-l (overtone.live/hpf snd-l hpf-env)])
+         snd-r                  (select use-hpf [snd-r (overtone.live/hpf snd-r hpf-env)])
+
+         snd-l                  (select norm [snd-l (normalizer snd-l)])
+         snd-r                  (select norm [snd-r (normalizer snd-r)])
+         snd-l                  (* env snd-l)
+         snd-r                  (* env snd-r)
+
+         control-sig            (/ (+ snd-l snd-r) 2)
+
+         compressed-l           (compander snd-l control-sig threshold
+                                           slope_below slope_above
+                                           clamp_time relax_time)
+
+         compressed-r           (compander snd-r control-sig threshold
+                                           slope_below slope_above
+                                           clamp_time relax_time)
+
+
+         snd-l                  (select:ar compress [snd-l compressed-l])
+         snd-r                  (select:ar compress [snd-r compressed-r])
 
+         snd                    (balance2 snd-l snd-r pan amp)]
+
+     (line:kr 1 1 (+ 0.03 (min play-time env-dur)) FREE)
+     (out out_bus snd)))
 
+;(show-graphviz-synth  sonic-pi-stereo_player)
  (comment
    (core/save-synthdef sonic-pi-mono_player)
    (core/save-synthdef sonic-pi-stereo_player)
diff --git a/etc/synthdefs/designs/sonic_pi/synths/studio.clj b/etc/synthdefs/designs/sonic_pi/synths/studio.clj
index 9fc9fde..7dc4ddd 100644
--- a/etc/synthdefs/designs/sonic_pi/synths/studio.clj
+++ b/etc/synthdefs/designs/sonic_pi/synths/studio.clj
@@ -123,7 +123,6 @@
      [out-buf 0 in_bus 0]
      (disk-out out-buf (in in_bus 2)))
 
-
    (defsynth sonic-pi-sound_in [amp 1
                                 amp_slide 0
                                 amp_slide_shape 1
@@ -132,34 +131,60 @@
                                 pan_slide 0
                                 pan_slide_shape 1
                                 pan_slide_curve 0
-                                attack 0.01
+                                attack 0
                                 decay 0
-                                sustain 0
-                                release 2
+                                sustain 1
+                                release 0
                                 attack_level 1
                                 decay_level -1
                                 sustain_level 1
                                 env_curve 1
-                                cutoff 100
-                                cutoff_slide 0
-                                cutoff_slide_shape 1
-                                cutoff_slide_curve 0
 
                                 input 0
                                 out_bus 0]
      (let [decay_level (select:kr (= -1 decay_level) [decay_level sustain_level])
            amp         (varlag amp amp_slide amp_slide_curve amp_slide_shape)
            pan         (varlag pan pan_slide pan_slide_curve pan_slide_shape)
-           cutoff      (varlag cutoff cutoff_slide cutoff_slide_curve cutoff_slide_shape)
-           cutoff-freq (midicps cutoff)
            snd         (sound-in input)
-           snd         (lpf snd cutoff-freq)
            env         (env-gen:kr (core/shaped-adsr attack decay sustain release attack_level decay_level sustain_level env_curve) :action FREE)]
-       (out out_bus (pan2 (* env snd) pan amp)))))
+       (out out_bus (pan2 (* env snd) pan amp))))
+
+   (defsynth sonic-pi-sound_in_stereo [amp 1
+                                       amp_slide 0
+                                       amp_slide_shape 1
+                                       amp_slide_curve 0
+                                       pan 0
+                                       pan_slide 0
+                                       pan_slide_shape 1
+                                       pan_slide_curve 0
+                                       attack 0
+                                       decay 0
+                                       sustain 1
+                                       release 0
+                                       attack_level 1
+                                       decay_level -1
+                                       sustain_level 1
+                                       env_curve 1
+
+                                       input 0
+                                       out_bus 0]
+     (let [decay_level (select:kr (= -1 decay_level) [decay_level sustain_level])
+           amp         (varlag amp amp_slide amp_slide_curve amp_slide_shape)
+           pan         (varlag pan pan_slide pan_slide_curve pan_slide_shape)
+           snd-l       (sound-in input)
+           snd-r       (sound-in (+ input 1))
+           env         (env-gen:kr (core/shaped-adsr attack decay sustain release attack_level decay_level sustain_level env_curve) :action FREE)
+           snd-l       (* env snd-l)
+           snd-r       (* env snd-r)
+           snd         (balance2 snd-l snd-r pan amp)]
+
+       (out out_bus (pan2 (* env snd) pan amp))))
+   )
 
 
   (comment
     (core/save-synthdef sonic-pi-sound_in)
+    (core/save-synthdef sonic-pi-sound_in_stereo)
     (core/save-synthdef sonic-pi-mixer)
     (core/save-synthdef sonic-pi-basic_mixer)
     (core/save-synthdef sonic-pi-recorder)))
diff --git a/etc/synthdefs/designs/sonic_pi/synths/traditional.clj b/etc/synthdefs/designs/sonic_pi/synths/traditional.clj
index 5e79e4e..8dd4969 100644
--- a/etc/synthdefs/designs/sonic_pi/synths/traditional.clj
+++ b/etc/synthdefs/designs/sonic_pi/synths/traditional.clj
@@ -17,6 +17,46 @@
   (:require [sonic-pi.synths.core :as core]))
 
 (without-namespace-in-synthdef
+ (defsynth sonic-pi-pluck [note 52
+                           amp 1
+                           amp_slide 0
+                           amp_slide_shape 1
+                           amp_slide_curve 0
+                           pan 0
+                           pan_slide 0
+                           pan_slide_shape 1
+                           pan_slide_curve 0
+                           attack 0
+                           decay 0
+                           sustain 0
+                           release 1
+                           attack_level 1
+                           decay_level -1
+                           sustain_level 1
+                           env_curve 1
+                           noise_amp 0.8
+                           max_delay_time 0.125
+                           pluck_decay 30
+                           coef 0.3
+
+                           out_bus 0]
+   (let [amp           (varlag amp amp_slide amp_slide_curve amp_slide_shape)
+         amp-fudge     2.5 ;; Given the filtering involved this synth is naturally quiet
+         pan           (varlag pan pan_slide pan_slide_curve pan_slide_shape)
+         freq          (midicps note)
+
+         snd           (pluck     {:in           (* noise_amp (pink-noise))
+                                   :trig         1
+                                   :maxdelaytime max_delay_time
+                                   :delaytime    (/ 1.0 freq)
+                                   :decaytime    pluck_decay
+                                   :coef         coef})
+
+         env           (env-gen:kr (core/shaped-adsr attack decay sustain release attack_level decay_level sustain_level env_curve) :action FREE)
+         [new-l new-r] (pan2 (* amp-fudge snd env) pan amp)]
+     (out out_bus [new-l new-r]))
+   )
+
  (defsynth sonic-pi-piano [note 52
                            amp 1
                            amp_slide 0
@@ -157,4 +197,5 @@
 
 (comment
   (core/save-synthdef sonic-pi-piano)
+  (core/save-synthdef sonic-pi-pluck)
   (core/save-synthdef sonic-pi-synth_violin))
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-amp_stereo_monitor.dot b/etc/synthdefs/graphviz/dot/sonic-pi-amp_stereo_monitor.dot
new file mode 100644
index 0000000..e43097f
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-amp_stereo_monitor.dot
@@ -0,0 +1,36 @@
+digraph synthdef {
+2 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+6 [label = "{{ <in> in} |<__UG_NAME__>a2k }" style="bold, rounded" shape=record rankdir=LR];
+10 [label = "{{ <in> in} |<__UG_NAME__>a2k }" style="bold, rounded" shape=record rankdir=LR];
+4 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
+8 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :smoothness
+ default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "{{ <phase> phase 0.0|<freq> freq 5.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+3 [label = "{{ <num____channels> num-channels 1|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+7 [label = "{{ <num____channels> num-channels 1|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+5 [label = "{{ <lag____time> lag-time|<in> in} |<__UG_NAME__>lag }" style="filled, bold, rounded"  shape=record rankdir=LR];
+9 [label = "{{ <lag____time> lag-time|<in> in} |<__UG_NAME__>lag }" style="filled, bold, rounded"  shape=record rankdir=LR];
+12 [label = "{{ <reply____id> reply-id|{{13}|values}|{{47|115|111|110|105|99|45|112|105|47|97|109|112|<cmd____name___a2k___13>|<cmd____name___a2k___14>}|cmd-name}|<trig> trig} |<__UG_NAME__>send-reply }" style="bold, rounded" shape=record rankdir=LR];
+
+0:__UG_NAME__ -> 2:a ;
+5:__UG_NAME__ -> 6:in ;
+9:__UG_NAME__ -> 10:in ;
+3:__UG_NAME__ -> 4:a ;
+7:__UG_NAME__ -> 8:a ;
+2:__UG_NAME__ -> 3:bus ;
+0:__UG_NAME__ -> 7:bus ;
+4:__UG_NAME__ -> 5:in ;
+1:__UG_NAME__ -> 5:lag____time ;
+8:__UG_NAME__ -> 9:in ;
+1:__UG_NAME__ -> 9:lag____time ;
+11:__UG_NAME__ -> 12:trig ;
+10:__UG_NAME__ -> 12:cmd____name___a2k___13 ;
+6:__UG_NAME__ -> 12:cmd____name___a2k___14 ;
+0:__UG_NAME__ -> 12:reply____id ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-basic_mixer.dot b/etc/synthdefs/graphviz/dot/sonic-pi-basic_mixer.dot
new file mode 100644
index 0000000..2d8c9ec
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-basic_mixer.dot
@@ -0,0 +1,60 @@
+digraph synthdef {
+17 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+18 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+12 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+14 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+8 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+13 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+7 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+10 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide
+ default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+6 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+9 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+11 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+16 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+19 [label = "{{ {{<signals___binary____op____u____gen___0>|<signals___binary____op____u____gen___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+15:__UG_NAME__ -> 17:a ;
+16:__UG_NAME__ -> 17:b ;
+15:__UG_NAME__ -> 18:a ;
+16:__UG_NAME__ -> 18:b ;
+11:__UG_NAME__ -> 12:a ;
+8:__UG_NAME__ -> 12:b ;
+12:__UG_NAME__ -> 14:a ;
+13:__UG_NAME__ -> 14:b ;
+7:__UG_NAME__ -> 8:a ;
+10:__UG_NAME__ -> 13:a ;
+6:__UG_NAME__ -> 7:a ;
+9:__UG_NAME__ -> 10:a ;
+2:__UG_NAME__ -> 15:envelope___control___0 ;
+2:__UG_NAME__ -> 15:envelope___control___4 ;
+3:__UG_NAME__ -> 15:envelope___control___5 ;
+4:__UG_NAME__ -> 15:envelope___control___6 ;
+5:__UG_NAME__ -> 15:envelope___control___7 ;
+14:__UG_NAME__ -> 15:gate ;
+2:__UG_NAME__ -> 6:in ;
+3:__UG_NAME__ -> 9:in ;
+0:__UG_NAME__ -> 16:bus ;
+1:__UG_NAME__ -> 19:bus ;
+18:__UG_NAME__ -> 19:signals___binary____op____u____gen___0 ;
+17:__UG_NAME__ -> 19:signals___binary____op____u____gen___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-basic_mono_player.dot b/etc/synthdefs/graphviz/dot/sonic-pi-basic_mono_player.dot
new file mode 100644
index 0000000..1ac739b
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-basic_mono_player.dot
@@ -0,0 +1,298 @@
+digraph synthdef {
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="dashed, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="dashed, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+32 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> |<a> 0.03} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="dashed, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="dashed, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="dashed, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="dashed, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="dashed, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\< }" style="dashed, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> -1.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> -1.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="dashed, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <buf> buf} |<__UG_NAME__>buf-dur }" style="dashed, rounded" shape=record rankdir=LR];
+76 [label = "{{ <buf> buf} |<__UG_NAME__>buf-frames }" style="dashed, rounded" shape=record rankdir=LR];
+60 [label = "{{ <buf> buf} |<__UG_NAME__>buf-rate-scale }" style="dashed, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :buf
+ default: 0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+1 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+2 [label = "control
+ :decay
+ default: 0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+3 [label = "control
+ :sustain
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+4 [label = "control
+ :release
+ default: 0.0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+5 [label = "control
+ :attack_level
+ default: 1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+6 [label = "control
+ :decay_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+7 [label = "control
+ :sustain_level
+ default: 1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+8 [label = "control
+ :env_curve
+ default: 1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+9 [label = "control
+ :rate
+ default: 1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+10 [label = "control
+ :out_bus
+ default: 0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+11 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :lpf
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :lpf_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :lpf_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :lpf_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :hpf
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :hpf_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :hpf_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :hpf_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___select___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <action> action 2.0|<dur> dur|<end> end 1.0|<start> start 1.0} |<__UG_NAME__>line }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> |<a> } |<__UG_NAME__>min }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+95 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+79 [label = "{{ <action> action 0.0|<loop> loop 0.0|<start____pos> start-pos|<trigger> trigger 0.0|<rate> rate|<bufnum> bufnum|<num____channels> num-channels 1} |<__UG_NAME__>play-buf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+64 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ {{<array___control___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ {{0.0|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ {{<array___play____buf___0>|<array___lpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+83 [label = "{{ {{<array___select___0>|<array___hpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+9:__UG_NAME__ -> 61:a ;
+60:__UG_NAME__ -> 61:b ;
+66:__UG_NAME__ -> 68:a ;
+67:__UG_NAME__ -> 68:b ;
+73:__UG_NAME__ -> 84:a ;
+83:__UG_NAME__ -> 84:b ;
+28:__UG_NAME__ -> 32:a ;
+31:__UG_NAME__ -> 32:b ;
+32:__UG_NAME__ -> 36:a ;
+35:__UG_NAME__ -> 36:b ;
+39:__UG_NAME__ -> 43:a ;
+42:__UG_NAME__ -> 43:b ;
+43:__UG_NAME__ -> 47:a ;
+46:__UG_NAME__ -> 47:b ;
+50:__UG_NAME__ -> 55:a ;
+54:__UG_NAME__ -> 55:b ;
+55:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+86:__UG_NAME__ -> 90:a ;
+89:__UG_NAME__ -> 90:b ;
+90:__UG_NAME__ -> 93:a ;
+92:__UG_NAME__ -> 93:b ;
+1:__UG_NAME__ -> 97:a ;
+72:__UG_NAME__ -> 97:b ;
+97:__UG_NAME__ -> 98:a ;
+2:__UG_NAME__ -> 98:b ;
+98:__UG_NAME__ -> 99:a ;
+4:__UG_NAME__ -> 99:b ;
+100:__UG_NAME__ -> 101:b ;
+68:__UG_NAME__ -> 69:a ;
+1:__UG_NAME__ -> 69:b ;
+69:__UG_NAME__ -> 70:a ;
+4:__UG_NAME__ -> 70:b ;
+70:__UG_NAME__ -> 71:a ;
+2:__UG_NAME__ -> 71:b ;
+76:__UG_NAME__ -> 77:a ;
+65:__UG_NAME__ -> 66:b ;
+9:__UG_NAME__ -> 75:a ;
+3:__UG_NAME__ -> 51:b ;
+6:__UG_NAME__ -> 63:b ;
+30:__UG_NAME__ -> 31:a ;
+34:__UG_NAME__ -> 35:a ;
+37:__UG_NAME__ -> 38:a ;
+41:__UG_NAME__ -> 42:a ;
+45:__UG_NAME__ -> 46:a ;
+53:__UG_NAME__ -> 54:a ;
+57:__UG_NAME__ -> 58:a ;
+48:__UG_NAME__ -> 74:a ;
+88:__UG_NAME__ -> 89:a ;
+91:__UG_NAME__ -> 92:a ;
+29:__UG_NAME__ -> 30:a ;
+33:__UG_NAME__ -> 34:a ;
+40:__UG_NAME__ -> 41:a ;
+44:__UG_NAME__ -> 45:a ;
+52:__UG_NAME__ -> 53:a ;
+56:__UG_NAME__ -> 57:a ;
+9:__UG_NAME__ -> 65:a ;
+87:__UG_NAME__ -> 88:a ;
+27:__UG_NAME__ -> 91:a ;
+0:__UG_NAME__ -> 67:buf ;
+0:__UG_NAME__ -> 76:buf ;
+0:__UG_NAME__ -> 60:buf ;
+19:__UG_NAME__ -> 37:envelope___control___0 ;
+19:__UG_NAME__ -> 37:envelope___control___4 ;
+20:__UG_NAME__ -> 37:envelope___control___5 ;
+21:__UG_NAME__ -> 37:envelope___control___6 ;
+22:__UG_NAME__ -> 37:envelope___control___7 ;
+36:__UG_NAME__ -> 37:gate ;
+23:__UG_NAME__ -> 48:envelope___control___0 ;
+23:__UG_NAME__ -> 48:envelope___control___4 ;
+24:__UG_NAME__ -> 48:envelope___control___5 ;
+25:__UG_NAME__ -> 48:envelope___control___6 ;
+26:__UG_NAME__ -> 48:envelope___control___7 ;
+47:__UG_NAME__ -> 48:gate ;
+5:__UG_NAME__ -> 73:envelope___control___4 ;
+1:__UG_NAME__ -> 73:envelope___control___5 ;
+8:__UG_NAME__ -> 73:envelope___control___6 ;
+64:__UG_NAME__ -> 73:envelope___select___8 ;
+2:__UG_NAME__ -> 73:envelope___control___9 ;
+8:__UG_NAME__ -> 73:envelope___control___10 ;
+7:__UG_NAME__ -> 73:envelope___control___12 ;
+72:__UG_NAME__ -> 73:envelope___select___13 ;
+8:__UG_NAME__ -> 73:envelope___control___14 ;
+4:__UG_NAME__ -> 73:envelope___control___17 ;
+8:__UG_NAME__ -> 73:envelope___control___18 ;
+15:__UG_NAME__ -> 85:envelope___control___0 ;
+15:__UG_NAME__ -> 85:envelope___control___4 ;
+16:__UG_NAME__ -> 85:envelope___control___5 ;
+17:__UG_NAME__ -> 85:envelope___control___6 ;
+18:__UG_NAME__ -> 85:envelope___control___7 ;
+59:__UG_NAME__ -> 85:gate ;
+11:__UG_NAME__ -> 94:envelope___control___0 ;
+11:__UG_NAME__ -> 94:envelope___control___4 ;
+12:__UG_NAME__ -> 94:envelope___control___5 ;
+13:__UG_NAME__ -> 94:envelope___control___6 ;
+14:__UG_NAME__ -> 94:envelope___control___7 ;
+93:__UG_NAME__ -> 94:gate ;
+81:__UG_NAME__ -> 82:in ;
+49:__UG_NAME__ -> 82:freq ;
+12:__UG_NAME__ -> 27:in ;
+19:__UG_NAME__ -> 29:in ;
+20:__UG_NAME__ -> 33:in ;
+23:__UG_NAME__ -> 40:in ;
+24:__UG_NAME__ -> 44:in ;
+15:__UG_NAME__ -> 52:in ;
+16:__UG_NAME__ -> 56:in ;
+11:__UG_NAME__ -> 87:in ;
+101:__UG_NAME__ -> 102:dur ;
+79:__UG_NAME__ -> 80:in ;
+62:__UG_NAME__ -> 80:freq ;
+48:__UG_NAME__ -> 49:a ;
+37:__UG_NAME__ -> 62:a ;
+68:__UG_NAME__ -> 100:a ;
+99:__UG_NAME__ -> 100:b ;
+10:__UG_NAME__ -> 96:bus ;
+95:__UG_NAME__ -> 96:signals___pan2___0 ;
+95:__UG_NAME__ -> 96:signals___pan2___1 ;
+84:__UG_NAME__ -> 95:in ;
+85:__UG_NAME__ -> 95:pos ;
+94:__UG_NAME__ -> 95:level ;
+0:__UG_NAME__ -> 79:bufnum ;
+61:__UG_NAME__ -> 79:rate ;
+78:__UG_NAME__ -> 79:start____pos ;
+63:__UG_NAME__ -> 64:which ;
+6:__UG_NAME__ -> 64:array___control___0 ;
+7:__UG_NAME__ -> 64:array___control___1 ;
+51:__UG_NAME__ -> 72:which ;
+3:__UG_NAME__ -> 72:array___control___0 ;
+71:__UG_NAME__ -> 72:array___binary____op____u____gen___1 ;
+75:__UG_NAME__ -> 78:which ;
+77:__UG_NAME__ -> 78:array___binary____op____u____gen___1 ;
+38:__UG_NAME__ -> 81:which ;
+79:__UG_NAME__ -> 81:array___play____buf___0 ;
+80:__UG_NAME__ -> 81:array___lpf___1 ;
+74:__UG_NAME__ -> 83:which ;
+81:__UG_NAME__ -> 83:array___select___0 ;
+82:__UG_NAME__ -> 83:array___hpf___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-basic_stereo_player.dot b/etc/synthdefs/graphviz/dot/sonic-pi-basic_stereo_player.dot
new file mode 100644
index 0000000..39aa2dd
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-basic_stereo_player.dot
@@ -0,0 +1,316 @@
+digraph synthdef {
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="dashed, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="dashed, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+98 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <b> |<a> 0.03} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="dashed, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="dashed, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="dashed, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="dashed, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="dashed, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\< }" style="dashed, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> -1.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> -1.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="dashed, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <level> level|<pos> pos|<right> right|<left> left} |<__UG_NAME__>balance2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+71 [label = "{{ <buf> buf} |<__UG_NAME__>buf-dur }" style="dashed, rounded" shape=record rankdir=LR];
+28 [label = "{{ <buf> buf} |<__UG_NAME__>buf-frames }" style="dashed, rounded" shape=record rankdir=LR];
+55 [label = "{{ <buf> buf} |<__UG_NAME__>buf-rate-scale }" style="dashed, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :buf
+ default: 0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+1 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+2 [label = "control
+ :decay
+ default: 0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+3 [label = "control
+ :sustain
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+4 [label = "control
+ :release
+ default: 0.0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+5 [label = "control
+ :attack_level
+ default: 1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+6 [label = "control
+ :decay_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+7 [label = "control
+ :sustain_level
+ default: 1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+8 [label = "control
+ :env_curve
+ default: 1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+9 [label = "control
+ :rate
+ default: 1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+10 [label = "control
+ :out_bus
+ default: 0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+11 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :lpf
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :lpf_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :lpf_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :lpf_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :hpf
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :hpf_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :hpf_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :hpf_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+62 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___select___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+94 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <action> action 2.0|<dur> dur|<end> end 1.0|<start> start 1.0} |<__UG_NAME__>line }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+92 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> |<a> } |<__UG_NAME__>min }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ {{<signals___balance2___0>|<signals___balance2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+64 [label = "{{ <action> action 0.0|<loop> loop 0.0|<start____pos> start-pos|<trigger> trigger 0.0|<rate> rate|<bufnum> bufnum|<num____channels> num-channels 2} |<__UG_NAME__>play-buf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+30 [label = "{{ {{0.0|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ {{<array___control___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ {{<array___play____buf___0>|<array___lpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+93 [label = "{{ {{<array___play____buf___0>|<array___lpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+95 [label = "{{ {{<array___select___0>|<array___hpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+97 [label = "{{ {{<array___select___0>|<array___hpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+9:__UG_NAME__ -> 63:a ;
+55:__UG_NAME__ -> 63:b ;
+57:__UG_NAME__ -> 72:a ;
+71:__UG_NAME__ -> 72:b ;
+77:__UG_NAME__ -> 96:a ;
+95:__UG_NAME__ -> 96:b ;
+77:__UG_NAME__ -> 98:a ;
+97:__UG_NAME__ -> 98:b ;
+38:__UG_NAME__ -> 39:a ;
+33:__UG_NAME__ -> 39:b ;
+39:__UG_NAME__ -> 43:a ;
+42:__UG_NAME__ -> 43:b ;
+49:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+53:__UG_NAME__ -> 54:a ;
+48:__UG_NAME__ -> 54:b ;
+58:__UG_NAME__ -> 59:a ;
+37:__UG_NAME__ -> 59:b ;
+59:__UG_NAME__ -> 61:a ;
+60:__UG_NAME__ -> 61:b ;
+34:__UG_NAME__ -> 88:a ;
+87:__UG_NAME__ -> 88:b ;
+88:__UG_NAME__ -> 89:a ;
+80:__UG_NAME__ -> 89:b ;
+1:__UG_NAME__ -> 102:a ;
+76:__UG_NAME__ -> 102:b ;
+102:__UG_NAME__ -> 103:a ;
+2:__UG_NAME__ -> 103:b ;
+103:__UG_NAME__ -> 104:a ;
+4:__UG_NAME__ -> 104:b ;
+105:__UG_NAME__ -> 106:b ;
+28:__UG_NAME__ -> 29:a ;
+72:__UG_NAME__ -> 73:a ;
+1:__UG_NAME__ -> 73:b ;
+73:__UG_NAME__ -> 74:a ;
+4:__UG_NAME__ -> 74:b ;
+74:__UG_NAME__ -> 75:a ;
+2:__UG_NAME__ -> 75:b ;
+56:__UG_NAME__ -> 57:b ;
+9:__UG_NAME__ -> 27:a ;
+6:__UG_NAME__ -> 68:b ;
+3:__UG_NAME__ -> 70:b ;
+32:__UG_NAME__ -> 33:a ;
+36:__UG_NAME__ -> 37:a ;
+41:__UG_NAME__ -> 42:a ;
+47:__UG_NAME__ -> 48:a ;
+51:__UG_NAME__ -> 52:a ;
+45:__UG_NAME__ -> 60:a ;
+79:__UG_NAME__ -> 80:a ;
+65:__UG_NAME__ -> 81:a ;
+86:__UG_NAME__ -> 87:a ;
+62:__UG_NAME__ -> 91:a ;
+31:__UG_NAME__ -> 32:a ;
+35:__UG_NAME__ -> 36:a ;
+40:__UG_NAME__ -> 41:a ;
+44:__UG_NAME__ -> 45:a ;
+46:__UG_NAME__ -> 47:a ;
+50:__UG_NAME__ -> 51:a ;
+9:__UG_NAME__ -> 56:a ;
+78:__UG_NAME__ -> 79:a ;
+85:__UG_NAME__ -> 86:a ;
+96:__UG_NAME__ -> 100:left ;
+98:__UG_NAME__ -> 100:right ;
+90:__UG_NAME__ -> 100:pos ;
+99:__UG_NAME__ -> 100:level ;
+0:__UG_NAME__ -> 71:buf ;
+0:__UG_NAME__ -> 28:buf ;
+0:__UG_NAME__ -> 55:buf ;
+23:__UG_NAME__ -> 62:envelope___control___0 ;
+23:__UG_NAME__ -> 62:envelope___control___4 ;
+24:__UG_NAME__ -> 62:envelope___control___5 ;
+25:__UG_NAME__ -> 62:envelope___control___6 ;
+26:__UG_NAME__ -> 62:envelope___control___7 ;
+61:__UG_NAME__ -> 62:gate ;
+19:__UG_NAME__ -> 65:envelope___control___0 ;
+19:__UG_NAME__ -> 65:envelope___control___4 ;
+20:__UG_NAME__ -> 65:envelope___control___5 ;
+21:__UG_NAME__ -> 65:envelope___control___6 ;
+22:__UG_NAME__ -> 65:envelope___control___7 ;
+54:__UG_NAME__ -> 65:gate ;
+5:__UG_NAME__ -> 77:envelope___control___4 ;
+1:__UG_NAME__ -> 77:envelope___control___5 ;
+8:__UG_NAME__ -> 77:envelope___control___6 ;
+69:__UG_NAME__ -> 77:envelope___select___8 ;
+2:__UG_NAME__ -> 77:envelope___control___9 ;
+8:__UG_NAME__ -> 77:envelope___control___10 ;
+7:__UG_NAME__ -> 77:envelope___control___12 ;
+76:__UG_NAME__ -> 77:envelope___select___13 ;
+8:__UG_NAME__ -> 77:envelope___control___14 ;
+4:__UG_NAME__ -> 77:envelope___control___17 ;
+8:__UG_NAME__ -> 77:envelope___control___18 ;
+15:__UG_NAME__ -> 90:envelope___control___0 ;
+15:__UG_NAME__ -> 90:envelope___control___4 ;
+16:__UG_NAME__ -> 90:envelope___control___5 ;
+17:__UG_NAME__ -> 90:envelope___control___6 ;
+18:__UG_NAME__ -> 90:envelope___control___7 ;
+43:__UG_NAME__ -> 90:gate ;
+11:__UG_NAME__ -> 99:envelope___control___0 ;
+11:__UG_NAME__ -> 99:envelope___control___4 ;
+12:__UG_NAME__ -> 99:envelope___control___5 ;
+13:__UG_NAME__ -> 99:envelope___control___6 ;
+14:__UG_NAME__ -> 99:envelope___control___7 ;
+89:__UG_NAME__ -> 99:gate ;
+82:__UG_NAME__ -> 84:in ;
+83:__UG_NAME__ -> 84:freq ;
+93:__UG_NAME__ -> 94:in ;
+83:__UG_NAME__ -> 94:freq ;
+15:__UG_NAME__ -> 31:in ;
+23:__UG_NAME__ -> 35:in ;
+16:__UG_NAME__ -> 40:in ;
+24:__UG_NAME__ -> 44:in ;
+20:__UG_NAME__ -> 46:in ;
+19:__UG_NAME__ -> 50:in ;
+12:__UG_NAME__ -> 78:in ;
+11:__UG_NAME__ -> 85:in ;
+106:__UG_NAME__ -> 107:dur ;
+64:__UG_NAME__ -> 67:in ;
+66:__UG_NAME__ -> 67:freq ;
+64:__UG_NAME__ -> 92:in ;
+66:__UG_NAME__ -> 92:freq ;
+65:__UG_NAME__ -> 66:a ;
+62:__UG_NAME__ -> 83:a ;
+72:__UG_NAME__ -> 105:a ;
+104:__UG_NAME__ -> 105:b ;
+10:__UG_NAME__ -> 101:bus ;
+100:__UG_NAME__ -> 101:signals___balance2___0 ;
+100:__UG_NAME__ -> 101:signals___balance2___1 ;
+0:__UG_NAME__ -> 64:bufnum ;
+63:__UG_NAME__ -> 64:rate ;
+30:__UG_NAME__ -> 64:start____pos ;
+27:__UG_NAME__ -> 30:which ;
+29:__UG_NAME__ -> 30:array___binary____op____u____gen___1 ;
+68:__UG_NAME__ -> 69:which ;
+6:__UG_NAME__ -> 69:array___control___0 ;
+7:__UG_NAME__ -> 69:array___control___1 ;
+70:__UG_NAME__ -> 76:which ;
+3:__UG_NAME__ -> 76:array___control___0 ;
+75:__UG_NAME__ -> 76:array___binary____op____u____gen___1 ;
+81:__UG_NAME__ -> 82:which ;
+64:__UG_NAME__ -> 82:array___play____buf___0 ;
+67:__UG_NAME__ -> 82:array___lpf___1 ;
+81:__UG_NAME__ -> 93:which ;
+64:__UG_NAME__ -> 93:array___play____buf___0 ;
+92:__UG_NAME__ -> 93:array___lpf___1 ;
+91:__UG_NAME__ -> 95:which ;
+93:__UG_NAME__ -> 95:array___select___0 ;
+94:__UG_NAME__ -> 95:array___hpf___1 ;
+91:__UG_NAME__ -> 97:which ;
+82:__UG_NAME__ -> 97:array___select___0 ;
+84:__UG_NAME__ -> 97:array___hpf___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-beep.dot b/etc/synthdefs/graphviz/dot/sonic-pi-beep.dot
new file mode 100644
index 0000000..b329bac
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-beep.dot
@@ -0,0 +1,180 @@
+digraph synthdef {
+40 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+21 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+58 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+25 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+26:__UG_NAME__ -> 40:b ;
+40:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+27:__UG_NAME__ -> 31:a ;
+30:__UG_NAME__ -> 31:b ;
+32:__UG_NAME__ -> 36:a ;
+35:__UG_NAME__ -> 36:b ;
+36:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+41:__UG_NAME__ -> 45:a ;
+44:__UG_NAME__ -> 45:b ;
+45:__UG_NAME__ -> 49:a ;
+48:__UG_NAME__ -> 49:b ;
+31:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+17:__UG_NAME__ -> 24:b ;
+29:__UG_NAME__ -> 30:a ;
+34:__UG_NAME__ -> 35:a ;
+22:__UG_NAME__ -> 37:a ;
+43:__UG_NAME__ -> 44:a ;
+47:__UG_NAME__ -> 48:a ;
+54:__UG_NAME__ -> 55:a ;
+21:__UG_NAME__ -> 22:a ;
+28:__UG_NAME__ -> 29:a ;
+33:__UG_NAME__ -> 34:a ;
+42:__UG_NAME__ -> 43:a ;
+46:__UG_NAME__ -> 47:a ;
+23:__UG_NAME__ -> 54:a ;
+16:__UG_NAME__ -> 26:envelope___control___4 ;
+12:__UG_NAME__ -> 26:envelope___control___5 ;
+19:__UG_NAME__ -> 26:envelope___control___6 ;
+25:__UG_NAME__ -> 26:envelope___select___8 ;
+13:__UG_NAME__ -> 26:envelope___control___9 ;
+19:__UG_NAME__ -> 26:envelope___control___10 ;
+18:__UG_NAME__ -> 26:envelope___control___12 ;
+14:__UG_NAME__ -> 26:envelope___control___13 ;
+19:__UG_NAME__ -> 26:envelope___control___14 ;
+15:__UG_NAME__ -> 26:envelope___control___17 ;
+19:__UG_NAME__ -> 26:envelope___control___18 ;
+8:__UG_NAME__ -> 39:envelope___control___0 ;
+8:__UG_NAME__ -> 39:envelope___control___4 ;
+9:__UG_NAME__ -> 39:envelope___control___5 ;
+10:__UG_NAME__ -> 39:envelope___control___6 ;
+11:__UG_NAME__ -> 39:envelope___control___7 ;
+38:__UG_NAME__ -> 39:gate ;
+0:__UG_NAME__ -> 50:envelope___control___0 ;
+0:__UG_NAME__ -> 50:envelope___control___4 ;
+1:__UG_NAME__ -> 50:envelope___control___5 ;
+2:__UG_NAME__ -> 50:envelope___control___6 ;
+3:__UG_NAME__ -> 50:envelope___control___7 ;
+49:__UG_NAME__ -> 50:gate ;
+4:__UG_NAME__ -> 57:envelope___control___0 ;
+4:__UG_NAME__ -> 57:envelope___control___4 ;
+5:__UG_NAME__ -> 57:envelope___control___5 ;
+6:__UG_NAME__ -> 57:envelope___control___6 ;
+7:__UG_NAME__ -> 57:envelope___control___7 ;
+56:__UG_NAME__ -> 57:gate ;
+9:__UG_NAME__ -> 21:in ;
+5:__UG_NAME__ -> 23:in ;
+4:__UG_NAME__ -> 28:in ;
+8:__UG_NAME__ -> 33:in ;
+0:__UG_NAME__ -> 42:in ;
+1:__UG_NAME__ -> 46:in ;
+50:__UG_NAME__ -> 51:a ;
+20:__UG_NAME__ -> 59:bus ;
+58:__UG_NAME__ -> 59:signals___pan2___0 ;
+58:__UG_NAME__ -> 59:signals___pan2___1 ;
+53:__UG_NAME__ -> 58:in ;
+39:__UG_NAME__ -> 58:pos ;
+57:__UG_NAME__ -> 58:level ;
+24:__UG_NAME__ -> 25:which ;
+17:__UG_NAME__ -> 25:array___control___0 ;
+18:__UG_NAME__ -> 25:array___control___1 ;
+51:__UG_NAME__ -> 52:freq ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-bnoise.dot b/etc/synthdefs/graphviz/dot/sonic-pi-bnoise.dot
new file mode 100644
index 0000000..7e532e3
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-bnoise.dot
@@ -0,0 +1,223 @@
+digraph synthdef {
+62 [label = "{{ <b> |<a> 1.2} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{<__UG_NAME__>brown-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :cutoff
+ default: 110.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :res
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+49 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+74 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+61 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+64 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+61:__UG_NAME__ -> 62:b ;
+62:__UG_NAME__ -> 66:a ;
+65:__UG_NAME__ -> 66:b ;
+29:__UG_NAME__ -> 33:a ;
+32:__UG_NAME__ -> 33:b ;
+33:__UG_NAME__ -> 37:a ;
+36:__UG_NAME__ -> 37:b ;
+38:__UG_NAME__ -> 42:a ;
+41:__UG_NAME__ -> 42:b ;
+47:__UG_NAME__ -> 55:a ;
+54:__UG_NAME__ -> 55:b ;
+55:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+42:__UG_NAME__ -> 68:a ;
+67:__UG_NAME__ -> 68:b ;
+70:__UG_NAME__ -> 71:a ;
+46:__UG_NAME__ -> 71:b ;
+71:__UG_NAME__ -> 72:a ;
+28:__UG_NAME__ -> 72:b ;
+13:__UG_NAME__ -> 63:b ;
+27:__UG_NAME__ -> 28:a ;
+31:__UG_NAME__ -> 32:a ;
+35:__UG_NAME__ -> 36:a ;
+40:__UG_NAME__ -> 41:a ;
+45:__UG_NAME__ -> 46:a ;
+53:__UG_NAME__ -> 54:a ;
+57:__UG_NAME__ -> 58:a ;
+43:__UG_NAME__ -> 67:a ;
+26:__UG_NAME__ -> 27:a ;
+30:__UG_NAME__ -> 31:a ;
+34:__UG_NAME__ -> 35:a ;
+39:__UG_NAME__ -> 40:a ;
+25:__UG_NAME__ -> 43:a ;
+44:__UG_NAME__ -> 45:a ;
+52:__UG_NAME__ -> 53:a ;
+56:__UG_NAME__ -> 57:a ;
+16:__UG_NAME__ -> 49:envelope___control___0 ;
+16:__UG_NAME__ -> 49:envelope___control___4 ;
+17:__UG_NAME__ -> 49:envelope___control___5 ;
+18:__UG_NAME__ -> 49:envelope___control___6 ;
+19:__UG_NAME__ -> 49:envelope___control___7 ;
+37:__UG_NAME__ -> 49:gate ;
+51:__UG_NAME__ -> 60:envelope___mul____add___0 ;
+51:__UG_NAME__ -> 60:envelope___mul____add___4 ;
+21:__UG_NAME__ -> 60:envelope___control___5 ;
+22:__UG_NAME__ -> 60:envelope___control___6 ;
+23:__UG_NAME__ -> 60:envelope___control___7 ;
+59:__UG_NAME__ -> 60:gate ;
+12:__UG_NAME__ -> 65:envelope___control___4 ;
+8:__UG_NAME__ -> 65:envelope___control___5 ;
+15:__UG_NAME__ -> 65:envelope___control___6 ;
+64:__UG_NAME__ -> 65:envelope___select___8 ;
+10:__UG_NAME__ -> 65:envelope___control___9 ;
+15:__UG_NAME__ -> 65:envelope___control___10 ;
+14:__UG_NAME__ -> 65:envelope___control___12 ;
+9:__UG_NAME__ -> 65:envelope___control___13 ;
+15:__UG_NAME__ -> 65:envelope___control___14 ;
+11:__UG_NAME__ -> 65:envelope___control___17 ;
+15:__UG_NAME__ -> 65:envelope___control___18 ;
+4:__UG_NAME__ -> 69:envelope___control___0 ;
+4:__UG_NAME__ -> 69:envelope___control___4 ;
+5:__UG_NAME__ -> 69:envelope___control___5 ;
+6:__UG_NAME__ -> 69:envelope___control___6 ;
+7:__UG_NAME__ -> 69:envelope___control___7 ;
+68:__UG_NAME__ -> 69:gate ;
+0:__UG_NAME__ -> 73:envelope___control___0 ;
+0:__UG_NAME__ -> 73:envelope___control___4 ;
+1:__UG_NAME__ -> 73:envelope___control___5 ;
+2:__UG_NAME__ -> 73:envelope___control___6 ;
+3:__UG_NAME__ -> 73:envelope___control___7 ;
+72:__UG_NAME__ -> 73:gate ;
+5:__UG_NAME__ -> 25:in ;
+1:__UG_NAME__ -> 26:in ;
+16:__UG_NAME__ -> 30:in ;
+17:__UG_NAME__ -> 34:in ;
+4:__UG_NAME__ -> 39:in ;
+0:__UG_NAME__ -> 44:in ;
+51:__UG_NAME__ -> 52:in ;
+21:__UG_NAME__ -> 56:in ;
+49:__UG_NAME__ -> 50:a ;
+20:__UG_NAME__ -> 51:in ;
+24:__UG_NAME__ -> 75:bus ;
+74:__UG_NAME__ -> 75:signals___pan2___0 ;
+74:__UG_NAME__ -> 75:signals___pan2___1 ;
+66:__UG_NAME__ -> 74:in ;
+69:__UG_NAME__ -> 74:pos ;
+73:__UG_NAME__ -> 74:level ;
+48:__UG_NAME__ -> 61:in ;
+50:__UG_NAME__ -> 61:freq ;
+60:__UG_NAME__ -> 61:rq ;
+63:__UG_NAME__ -> 64:which ;
+13:__UG_NAME__ -> 64:array___control___0 ;
+14:__UG_NAME__ -> 64:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-chipbass.dot b/etc/synthdefs/graphviz/dot/sonic-pi-chipbass.dot
new file mode 100644
index 0000000..6ae0275
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-chipbass.dot
@@ -0,0 +1,194 @@
+digraph synthdef {
+35 [label = "{{ <b> |<a> 32.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> 0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> 0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> 0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> 0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> 0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 60.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :note_resolution
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "{{ {{<demand____ugens___dseq___0>}|demand-ugens}|<reset> reset 0|<trig> trig} |<__UG_NAME__>demand }" style="filled, bold, rounded"  shape=record rankdir=LR];
+37 [label = "{{ <num____repeats> num-repeats Infinity|{{0|1.0|2.0|3|4|5|6|7|8|9|10|11|12|13|14|15|15|14|13|12|11|10|9|8|7|6|5|4|3|2.0|1.0|0}|list}} |<__UG_NAME__>dseq }" style="bold, diagonals"  shape=record rankdir=LR];
+32 [label = "{{ <action> action 0|<time____scale> time-scale 1.0|<level____bias> level-bias 0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0|0|<envelope___control___17>|<envelope___control___18>|0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <action> action 0|<time____scale> time-scale 1.0|<level____bias> level-bias 0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <action> action 0|<time____scale> time-scale 1.0|<level____bias> level-bias 0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <phase> phase 0|<freq> freq 0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <phase> phase 0|<freq> freq} |<__UG_NAME__>impulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+45 [label = "{{ <phase> phase 0|<freq> freq 0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <phase> phase 0|<freq> freq 0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <add> add -1.0|<mul> mul 0.13333334|<in> in} |<__UG_NAME__>mul-add }" style="filled, bold, rounded"  shape=record rankdir=LR];
+65 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+64 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>round-down }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+34:__UG_NAME__ -> 35:b ;
+39:__UG_NAME__ -> 40:b ;
+40:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+23:__UG_NAME__ -> 27:a ;
+26:__UG_NAME__ -> 27:b ;
+27:__UG_NAME__ -> 31:a ;
+30:__UG_NAME__ -> 31:b ;
+45:__UG_NAME__ -> 49:a ;
+48:__UG_NAME__ -> 49:b ;
+49:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+55:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+59:__UG_NAME__ -> 62:a ;
+61:__UG_NAME__ -> 62:b ;
+18:__UG_NAME__ -> 41:b ;
+25:__UG_NAME__ -> 26:a ;
+29:__UG_NAME__ -> 30:a ;
+47:__UG_NAME__ -> 48:a ;
+51:__UG_NAME__ -> 52:a ;
+57:__UG_NAME__ -> 58:a ;
+60:__UG_NAME__ -> 61:a ;
+24:__UG_NAME__ -> 25:a ;
+28:__UG_NAME__ -> 29:a ;
+46:__UG_NAME__ -> 47:a ;
+50:__UG_NAME__ -> 51:a ;
+56:__UG_NAME__ -> 57:a ;
+22:__UG_NAME__ -> 60:a ;
+36:__UG_NAME__ -> 38:trig ;
+37:__UG_NAME__ -> 38:demand____ugens___dseq___0 ;
+0:__UG_NAME__ -> 32:envelope___control___0 ;
+0:__UG_NAME__ -> 32:envelope___control___4 ;
+1:__UG_NAME__ -> 32:envelope___control___5 ;
+2:__UG_NAME__ -> 32:envelope___control___6 ;
+3:__UG_NAME__ -> 32:envelope___control___7 ;
+31:__UG_NAME__ -> 32:gate ;
+17:__UG_NAME__ -> 43:envelope___control___4 ;
+13:__UG_NAME__ -> 43:envelope___control___5 ;
+20:__UG_NAME__ -> 43:envelope___control___6 ;
+42:__UG_NAME__ -> 43:envelope___select___8 ;
+15:__UG_NAME__ -> 43:envelope___control___9 ;
+20:__UG_NAME__ -> 43:envelope___control___10 ;
+19:__UG_NAME__ -> 43:envelope___control___12 ;
+14:__UG_NAME__ -> 43:envelope___control___13 ;
+20:__UG_NAME__ -> 43:envelope___control___14 ;
+16:__UG_NAME__ -> 43:envelope___control___17 ;
+20:__UG_NAME__ -> 43:envelope___control___18 ;
+9:__UG_NAME__ -> 54:envelope___control___0 ;
+9:__UG_NAME__ -> 54:envelope___control___4 ;
+10:__UG_NAME__ -> 54:envelope___control___5 ;
+11:__UG_NAME__ -> 54:envelope___control___6 ;
+12:__UG_NAME__ -> 54:envelope___control___7 ;
+53:__UG_NAME__ -> 54:gate ;
+5:__UG_NAME__ -> 63:envelope___control___0 ;
+5:__UG_NAME__ -> 63:envelope___control___4 ;
+6:__UG_NAME__ -> 63:envelope___control___5 ;
+7:__UG_NAME__ -> 63:envelope___control___6 ;
+8:__UG_NAME__ -> 63:envelope___control___7 ;
+62:__UG_NAME__ -> 63:gate ;
+6:__UG_NAME__ -> 22:in ;
+0:__UG_NAME__ -> 24:in ;
+1:__UG_NAME__ -> 28:in ;
+9:__UG_NAME__ -> 46:in ;
+10:__UG_NAME__ -> 50:in ;
+5:__UG_NAME__ -> 56:in ;
+35:__UG_NAME__ -> 36:freq ;
+33:__UG_NAME__ -> 34:a ;
+38:__UG_NAME__ -> 39:in ;
+21:__UG_NAME__ -> 65:bus ;
+64:__UG_NAME__ -> 65:signals___pan2___0 ;
+64:__UG_NAME__ -> 65:signals___pan2___1 ;
+44:__UG_NAME__ -> 64:in ;
+54:__UG_NAME__ -> 64:pos ;
+63:__UG_NAME__ -> 64:level ;
+32:__UG_NAME__ -> 33:a ;
+4:__UG_NAME__ -> 33:b ;
+41:__UG_NAME__ -> 42:which ;
+18:__UG_NAME__ -> 42:array___control___0 ;
+19:__UG_NAME__ -> 42:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-chiplead.dot b/etc/synthdefs/graphviz/dot/sonic-pi-chiplead.dot
new file mode 100644
index 0000000..841360f
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-chiplead.dot
@@ -0,0 +1,194 @@
+digraph synthdef {
+51 [label = "{{ <b> |<a> 0.8} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 60.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :note_resolution
+ default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :width
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+63 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+49 [label = "{{ <width> width|<freq> freq} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>round-down }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ {{0.125|0.25|0.5}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>softclip }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+50:__UG_NAME__ -> 51:b ;
+51:__UG_NAME__ -> 55:a ;
+54:__UG_NAME__ -> 55:b ;
+25:__UG_NAME__ -> 29:a ;
+28:__UG_NAME__ -> 29:b ;
+29:__UG_NAME__ -> 31:a ;
+30:__UG_NAME__ -> 31:b ;
+36:__UG_NAME__ -> 40:a ;
+39:__UG_NAME__ -> 40:b ;
+40:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+33:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+59:__UG_NAME__ -> 61:a ;
+60:__UG_NAME__ -> 61:b ;
+18:__UG_NAME__ -> 52:b ;
+27:__UG_NAME__ -> 28:a ;
+24:__UG_NAME__ -> 30:a ;
+38:__UG_NAME__ -> 39:a ;
+42:__UG_NAME__ -> 43:a ;
+57:__UG_NAME__ -> 58:a ;
+35:__UG_NAME__ -> 60:a ;
+23:__UG_NAME__ -> 24:a ;
+26:__UG_NAME__ -> 27:a ;
+34:__UG_NAME__ -> 35:a ;
+37:__UG_NAME__ -> 38:a ;
+41:__UG_NAME__ -> 42:a ;
+56:__UG_NAME__ -> 57:a ;
+9:__UG_NAME__ -> 32:envelope___control___0 ;
+9:__UG_NAME__ -> 32:envelope___control___4 ;
+10:__UG_NAME__ -> 32:envelope___control___5 ;
+11:__UG_NAME__ -> 32:envelope___control___6 ;
+12:__UG_NAME__ -> 32:envelope___control___7 ;
+31:__UG_NAME__ -> 32:gate ;
+0:__UG_NAME__ -> 45:envelope___control___0 ;
+0:__UG_NAME__ -> 45:envelope___control___4 ;
+1:__UG_NAME__ -> 45:envelope___control___5 ;
+2:__UG_NAME__ -> 45:envelope___control___6 ;
+3:__UG_NAME__ -> 45:envelope___control___7 ;
+44:__UG_NAME__ -> 45:gate ;
+17:__UG_NAME__ -> 54:envelope___control___4 ;
+13:__UG_NAME__ -> 54:envelope___control___5 ;
+20:__UG_NAME__ -> 54:envelope___control___6 ;
+53:__UG_NAME__ -> 54:envelope___select___8 ;
+15:__UG_NAME__ -> 54:envelope___control___9 ;
+20:__UG_NAME__ -> 54:envelope___control___10 ;
+19:__UG_NAME__ -> 54:envelope___control___12 ;
+14:__UG_NAME__ -> 54:envelope___control___13 ;
+20:__UG_NAME__ -> 54:envelope___control___14 ;
+16:__UG_NAME__ -> 54:envelope___control___17 ;
+20:__UG_NAME__ -> 54:envelope___control___18 ;
+5:__UG_NAME__ -> 62:envelope___control___0 ;
+5:__UG_NAME__ -> 62:envelope___control___4 ;
+6:__UG_NAME__ -> 62:envelope___control___5 ;
+7:__UG_NAME__ -> 62:envelope___control___6 ;
+8:__UG_NAME__ -> 62:envelope___control___7 ;
+61:__UG_NAME__ -> 62:gate ;
+10:__UG_NAME__ -> 23:in ;
+9:__UG_NAME__ -> 26:in ;
+6:__UG_NAME__ -> 34:in ;
+0:__UG_NAME__ -> 37:in ;
+1:__UG_NAME__ -> 41:in ;
+5:__UG_NAME__ -> 56:in ;
+46:__UG_NAME__ -> 47:a ;
+22:__UG_NAME__ -> 64:bus ;
+63:__UG_NAME__ -> 64:signals___pan2___0 ;
+63:__UG_NAME__ -> 64:signals___pan2___1 ;
+55:__UG_NAME__ -> 63:in ;
+32:__UG_NAME__ -> 63:pos ;
+62:__UG_NAME__ -> 63:level ;
+47:__UG_NAME__ -> 49:freq ;
+48:__UG_NAME__ -> 49:width ;
+45:__UG_NAME__ -> 46:a ;
+4:__UG_NAME__ -> 46:b ;
+21:__UG_NAME__ -> 48:which ;
+52:__UG_NAME__ -> 53:which ;
+18:__UG_NAME__ -> 53:array___control___0 ;
+19:__UG_NAME__ -> 53:array___control___1 ;
+49:__UG_NAME__ -> 50:a ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-chipnoise.dot b/etc/synthdefs/graphviz/dot/sonic-pi-chipnoise.dot
new file mode 100644
index 0000000..5e0d23f
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-chipnoise.dot
@@ -0,0 +1,186 @@
+digraph synthdef {
+42 [label = "{{ <b> |<a> 220.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> 0.8} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+25 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :freq_band
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :freq_band_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :freq_band_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :freq_band_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>floor }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+21 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <freq> freq} |<__UG_NAME__>lfd-clip-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+62 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+61 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+41 [label = "{{ {{1.0|2.0|4.0|5.34|8.0|10.68|16.0|19.03|25.4|32.0|42.71|64.0|128.0|256.0|512.0|1024.0}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>softclip }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+41:__UG_NAME__ -> 42:b ;
+44:__UG_NAME__ -> 48:b ;
+48:__UG_NAME__ -> 52:a ;
+51:__UG_NAME__ -> 52:b ;
+21:__UG_NAME__ -> 25:a ;
+24:__UG_NAME__ -> 25:b ;
+25:__UG_NAME__ -> 29:a ;
+28:__UG_NAME__ -> 29:b ;
+30:__UG_NAME__ -> 34:a ;
+33:__UG_NAME__ -> 34:b ;
+34:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+53:__UG_NAME__ -> 55:a ;
+54:__UG_NAME__ -> 55:b ;
+55:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+13:__UG_NAME__ -> 49:b ;
+23:__UG_NAME__ -> 24:a ;
+27:__UG_NAME__ -> 28:a ;
+32:__UG_NAME__ -> 33:a ;
+36:__UG_NAME__ -> 37:a ;
+47:__UG_NAME__ -> 54:a ;
+57:__UG_NAME__ -> 58:a ;
+22:__UG_NAME__ -> 23:a ;
+26:__UG_NAME__ -> 27:a ;
+31:__UG_NAME__ -> 32:a ;
+35:__UG_NAME__ -> 36:a ;
+46:__UG_NAME__ -> 47:a ;
+56:__UG_NAME__ -> 57:a ;
+16:__UG_NAME__ -> 39:envelope___control___0 ;
+16:__UG_NAME__ -> 39:envelope___control___4 ;
+17:__UG_NAME__ -> 39:envelope___control___5 ;
+18:__UG_NAME__ -> 39:envelope___control___6 ;
+19:__UG_NAME__ -> 39:envelope___control___7 ;
+38:__UG_NAME__ -> 39:gate ;
+0:__UG_NAME__ -> 45:envelope___control___0 ;
+0:__UG_NAME__ -> 45:envelope___control___4 ;
+1:__UG_NAME__ -> 45:envelope___control___5 ;
+2:__UG_NAME__ -> 45:envelope___control___6 ;
+3:__UG_NAME__ -> 45:envelope___control___7 ;
+29:__UG_NAME__ -> 45:gate ;
+12:__UG_NAME__ -> 51:envelope___control___4 ;
+8:__UG_NAME__ -> 51:envelope___control___5 ;
+15:__UG_NAME__ -> 51:envelope___control___6 ;
+50:__UG_NAME__ -> 51:envelope___select___8 ;
+10:__UG_NAME__ -> 51:envelope___control___9 ;
+15:__UG_NAME__ -> 51:envelope___control___10 ;
+14:__UG_NAME__ -> 51:envelope___control___12 ;
+9:__UG_NAME__ -> 51:envelope___control___13 ;
+15:__UG_NAME__ -> 51:envelope___control___14 ;
+11:__UG_NAME__ -> 51:envelope___control___17 ;
+15:__UG_NAME__ -> 51:envelope___control___18 ;
+4:__UG_NAME__ -> 60:envelope___control___0 ;
+4:__UG_NAME__ -> 60:envelope___control___4 ;
+5:__UG_NAME__ -> 60:envelope___control___5 ;
+6:__UG_NAME__ -> 60:envelope___control___6 ;
+7:__UG_NAME__ -> 60:envelope___control___7 ;
+59:__UG_NAME__ -> 60:gate ;
+39:__UG_NAME__ -> 40:a ;
+0:__UG_NAME__ -> 22:in ;
+1:__UG_NAME__ -> 26:in ;
+16:__UG_NAME__ -> 31:in ;
+17:__UG_NAME__ -> 35:in ;
+4:__UG_NAME__ -> 46:in ;
+5:__UG_NAME__ -> 56:in ;
+42:__UG_NAME__ -> 43:freq ;
+20:__UG_NAME__ -> 62:bus ;
+61:__UG_NAME__ -> 62:signals___pan2___0 ;
+61:__UG_NAME__ -> 62:signals___pan2___1 ;
+52:__UG_NAME__ -> 61:in ;
+60:__UG_NAME__ -> 61:pos ;
+45:__UG_NAME__ -> 61:level ;
+40:__UG_NAME__ -> 41:which ;
+49:__UG_NAME__ -> 50:which ;
+13:__UG_NAME__ -> 50:array___control___0 ;
+14:__UG_NAME__ -> 50:array___control___1 ;
+43:__UG_NAME__ -> 44:a ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-cnoise.dot b/etc/synthdefs/graphviz/dot/sonic-pi-cnoise.dot
new file mode 100644
index 0000000..0284f25
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-cnoise.dot
@@ -0,0 +1,223 @@
+digraph synthdef {
+72 [label = "{{ <b> |<a> 0.6} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{<__UG_NAME__>clip-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :cutoff
+ default: 110.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :res
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+53 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+74 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+71 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+57 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+71:__UG_NAME__ -> 72:b ;
+72:__UG_NAME__ -> 73:a ;
+58:__UG_NAME__ -> 73:b ;
+27:__UG_NAME__ -> 29:a ;
+28:__UG_NAME__ -> 29:b ;
+29:__UG_NAME__ -> 33:a ;
+32:__UG_NAME__ -> 33:b ;
+34:__UG_NAME__ -> 39:a ;
+38:__UG_NAME__ -> 39:b ;
+39:__UG_NAME__ -> 43:a ;
+42:__UG_NAME__ -> 43:b ;
+47:__UG_NAME__ -> 50:a ;
+49:__UG_NAME__ -> 50:b ;
+50:__UG_NAME__ -> 52:a ;
+51:__UG_NAME__ -> 52:b ;
+62:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+65:__UG_NAME__ -> 67:a ;
+66:__UG_NAME__ -> 67:b ;
+13:__UG_NAME__ -> 56:b ;
+26:__UG_NAME__ -> 28:a ;
+31:__UG_NAME__ -> 32:a ;
+37:__UG_NAME__ -> 38:a ;
+41:__UG_NAME__ -> 42:a ;
+48:__UG_NAME__ -> 49:a ;
+45:__UG_NAME__ -> 51:a ;
+63:__UG_NAME__ -> 64:a ;
+60:__UG_NAME__ -> 66:a ;
+25:__UG_NAME__ -> 26:a ;
+30:__UG_NAME__ -> 31:a ;
+36:__UG_NAME__ -> 37:a ;
+40:__UG_NAME__ -> 41:a ;
+44:__UG_NAME__ -> 45:a ;
+46:__UG_NAME__ -> 48:a ;
+55:__UG_NAME__ -> 60:a ;
+54:__UG_NAME__ -> 63:a ;
+4:__UG_NAME__ -> 53:envelope___control___0 ;
+4:__UG_NAME__ -> 53:envelope___control___4 ;
+5:__UG_NAME__ -> 53:envelope___control___5 ;
+6:__UG_NAME__ -> 53:envelope___control___6 ;
+7:__UG_NAME__ -> 53:envelope___control___7 ;
+52:__UG_NAME__ -> 53:gate ;
+12:__UG_NAME__ -> 58:envelope___control___4 ;
+8:__UG_NAME__ -> 58:envelope___control___5 ;
+15:__UG_NAME__ -> 58:envelope___control___6 ;
+57:__UG_NAME__ -> 58:envelope___select___8 ;
+10:__UG_NAME__ -> 58:envelope___control___9 ;
+15:__UG_NAME__ -> 58:envelope___control___10 ;
+14:__UG_NAME__ -> 58:envelope___control___12 ;
+9:__UG_NAME__ -> 58:envelope___control___13 ;
+15:__UG_NAME__ -> 58:envelope___control___14 ;
+11:__UG_NAME__ -> 58:envelope___control___17 ;
+15:__UG_NAME__ -> 58:envelope___control___18 ;
+0:__UG_NAME__ -> 59:envelope___control___0 ;
+0:__UG_NAME__ -> 59:envelope___control___4 ;
+1:__UG_NAME__ -> 59:envelope___control___5 ;
+2:__UG_NAME__ -> 59:envelope___control___6 ;
+3:__UG_NAME__ -> 59:envelope___control___7 ;
+33:__UG_NAME__ -> 59:gate ;
+16:__UG_NAME__ -> 68:envelope___control___0 ;
+16:__UG_NAME__ -> 68:envelope___control___4 ;
+17:__UG_NAME__ -> 68:envelope___control___5 ;
+18:__UG_NAME__ -> 68:envelope___control___6 ;
+19:__UG_NAME__ -> 68:envelope___control___7 ;
+67:__UG_NAME__ -> 68:gate ;
+35:__UG_NAME__ -> 70:envelope___mul____add___0 ;
+35:__UG_NAME__ -> 70:envelope___mul____add___4 ;
+21:__UG_NAME__ -> 70:envelope___control___5 ;
+22:__UG_NAME__ -> 70:envelope___control___6 ;
+23:__UG_NAME__ -> 70:envelope___control___7 ;
+43:__UG_NAME__ -> 70:gate ;
+0:__UG_NAME__ -> 25:in ;
+1:__UG_NAME__ -> 30:in ;
+35:__UG_NAME__ -> 36:in ;
+21:__UG_NAME__ -> 40:in ;
+5:__UG_NAME__ -> 44:in ;
+4:__UG_NAME__ -> 46:in ;
+16:__UG_NAME__ -> 54:in ;
+17:__UG_NAME__ -> 55:in ;
+68:__UG_NAME__ -> 69:a ;
+20:__UG_NAME__ -> 35:in ;
+24:__UG_NAME__ -> 75:bus ;
+74:__UG_NAME__ -> 75:signals___pan2___0 ;
+74:__UG_NAME__ -> 75:signals___pan2___1 ;
+73:__UG_NAME__ -> 74:in ;
+53:__UG_NAME__ -> 74:pos ;
+59:__UG_NAME__ -> 74:level ;
+61:__UG_NAME__ -> 71:in ;
+69:__UG_NAME__ -> 71:freq ;
+70:__UG_NAME__ -> 71:rq ;
+56:__UG_NAME__ -> 57:which ;
+13:__UG_NAME__ -> 57:array___control___0 ;
+14:__UG_NAME__ -> 57:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-dark_ambience.dot b/etc/synthdefs/graphviz/dot/sonic-pi-dark_ambience.dot
new file mode 100644
index 0000000..933360b
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-dark_ambience.dot
@@ -0,0 +1,430 @@
+digraph synthdef {
+74 [label = "{{ <b> |<a> 0.005} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> 0.002} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> 0.002} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> 0.001} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> 0.001} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+114 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+129 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+135 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+149 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+118 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+122 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+140 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+143 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+151 [label = "{{ <level> level|<pos> pos|<right> right|<left> left} |<__UG_NAME__>balance2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+75 [label = "{<__UG_NAME__>brown-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+79 [label = "{<__UG_NAME__>clip-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 110.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :res
+ default: 0.7" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :detune1
+ default: 12.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :detune1_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :detune1_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :detune1_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :detune2
+ default: 24.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :detune2_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :detune2_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :detune2_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :noise
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "control
+ :ring
+ default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "control
+ :room
+ default: 70.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "control
+ :reverb_time
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+40 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+54 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+145 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <in> in|<taillevel> taillevel 0.5|<earlyreflevel> earlyreflevel 0.7|<roomsize> roomsize|<damping> damping 0.5|<inputbw> inputbw 0.5|<maxroomsize> maxroomsize 300.0|<revtime> revtime|<spread> spread 15.0|<drylevel> drylevel 1.0} |<__UG_NAME__>g-verb }" style="filled, bold, rounded"  shape=record rankdir=LR];
+81 [label = "{<__UG_NAME__>gray-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <b> |<a> 0.1} |<__UG_NAME__>max }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+146 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <b> |<a> 300.0} |<__UG_NAME__>min }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+152 [label = "{{ {{<signals___balance2___0>|<signals___balance2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+73 [label = "{<__UG_NAME__>pink-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+106 [label = "{{ <decay____time> decay-time|<freq> freq|<in> in} |<__UG_NAME__>ringz }" style="filled, bold, rounded"  shape=record rankdir=LR];
+116 [label = "{{ <decay____time> decay-time|<freq> freq|<in> in} |<__UG_NAME__>ringz }" style="filled, bold, rounded"  shape=record rankdir=LR];
+126 [label = "{{ <decay____time> decay-time|<freq> freq|<in> in} |<__UG_NAME__>ringz }" style="filled, bold, rounded"  shape=record rankdir=LR];
+147 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+150 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+83 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___binary____op____u____gen___2>|<array___binary____op____u____gen___3>|<array___binary____op____u____gen___4>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+112 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+134 [label = "{{ <b> |<a> } |<__UG_NAME__>tanh }" style="filled, bold, rounded"  shape=record rankdir=LR];
+148 [label = "{{ <b> |<a> } |<__UG_NAME__>tanh }" style="filled, bold, rounded"  shape=record rankdir=LR];
+77 [label = "{<__UG_NAME__>white-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+73:__UG_NAME__ -> 74:b ;
+75:__UG_NAME__ -> 76:b ;
+77:__UG_NAME__ -> 78:b ;
+79:__UG_NAME__ -> 80:b ;
+81:__UG_NAME__ -> 82:b ;
+113:__UG_NAME__ -> 114:b ;
+127:__UG_NAME__ -> 128:a ;
+113:__UG_NAME__ -> 129:a ;
+128:__UG_NAME__ -> 129:b ;
+114:__UG_NAME__ -> 135:a ;
+134:__UG_NAME__ -> 135:b ;
+114:__UG_NAME__ -> 149:a ;
+148:__UG_NAME__ -> 149:b ;
+48:__UG_NAME__ -> 52:a ;
+51:__UG_NAME__ -> 52:b ;
+52:__UG_NAME__ -> 53:a ;
+43:__UG_NAME__ -> 53:b ;
+55:__UG_NAME__ -> 58:a ;
+57:__UG_NAME__ -> 58:b ;
+58:__UG_NAME__ -> 62:a ;
+61:__UG_NAME__ -> 62:b ;
+64:__UG_NAME__ -> 68:a ;
+67:__UG_NAME__ -> 68:b ;
+68:__UG_NAME__ -> 70:a ;
+69:__UG_NAME__ -> 70:b ;
+84:__UG_NAME__ -> 88:a ;
+87:__UG_NAME__ -> 88:b ;
+88:__UG_NAME__ -> 92:a ;
+91:__UG_NAME__ -> 92:b ;
+94:__UG_NAME__ -> 98:a ;
+97:__UG_NAME__ -> 98:b ;
+98:__UG_NAME__ -> 102:a ;
+101:__UG_NAME__ -> 102:b ;
+93:__UG_NAME__ -> 104:a ;
+103:__UG_NAME__ -> 104:b ;
+107:__UG_NAME__ -> 111:a ;
+110:__UG_NAME__ -> 111:b ;
+116:__UG_NAME__ -> 117:a ;
+116:__UG_NAME__ -> 117:b ;
+117:__UG_NAME__ -> 118:a ;
+106:__UG_NAME__ -> 118:b ;
+111:__UG_NAME__ -> 122:a ;
+121:__UG_NAME__ -> 122:b ;
+93:__UG_NAME__ -> 124:a ;
+123:__UG_NAME__ -> 124:b ;
+118:__UG_NAME__ -> 127:a ;
+126:__UG_NAME__ -> 127:b ;
+136:__UG_NAME__ -> 140:a ;
+139:__UG_NAME__ -> 140:b ;
+140:__UG_NAME__ -> 144:a ;
+143:__UG_NAME__ -> 144:b ;
+17:__UG_NAME__ -> 72:b ;
+42:__UG_NAME__ -> 43:a ;
+50:__UG_NAME__ -> 51:a ;
+56:__UG_NAME__ -> 57:a ;
+60:__UG_NAME__ -> 61:a ;
+66:__UG_NAME__ -> 67:a ;
+45:__UG_NAME__ -> 69:a ;
+86:__UG_NAME__ -> 87:a ;
+90:__UG_NAME__ -> 91:a ;
+96:__UG_NAME__ -> 97:a ;
+100:__UG_NAME__ -> 101:a ;
+109:__UG_NAME__ -> 110:a ;
+120:__UG_NAME__ -> 121:a ;
+138:__UG_NAME__ -> 139:a ;
+142:__UG_NAME__ -> 143:a ;
+41:__UG_NAME__ -> 42:a ;
+44:__UG_NAME__ -> 45:a ;
+49:__UG_NAME__ -> 50:a ;
+47:__UG_NAME__ -> 56:a ;
+59:__UG_NAME__ -> 60:a ;
+65:__UG_NAME__ -> 66:a ;
+85:__UG_NAME__ -> 86:a ;
+89:__UG_NAME__ -> 90:a ;
+95:__UG_NAME__ -> 96:a ;
+99:__UG_NAME__ -> 100:a ;
+108:__UG_NAME__ -> 109:a ;
+119:__UG_NAME__ -> 120:a ;
+38:__UG_NAME__ -> 130:a ;
+137:__UG_NAME__ -> 138:a ;
+141:__UG_NAME__ -> 142:a ;
+150:__UG_NAME__ -> 151:left ;
+147:__UG_NAME__ -> 151:right ;
+54:__UG_NAME__ -> 151:pos ;
+71:__UG_NAME__ -> 151:level ;
+8:__UG_NAME__ -> 54:envelope___control___0 ;
+8:__UG_NAME__ -> 54:envelope___control___4 ;
+9:__UG_NAME__ -> 54:envelope___control___5 ;
+10:__UG_NAME__ -> 54:envelope___control___6 ;
+11:__UG_NAME__ -> 54:envelope___control___7 ;
+53:__UG_NAME__ -> 54:gate ;
+46:__UG_NAME__ -> 63:envelope___mul____add___0 ;
+46:__UG_NAME__ -> 63:envelope___mul____add___4 ;
+25:__UG_NAME__ -> 63:envelope___control___5 ;
+26:__UG_NAME__ -> 63:envelope___control___6 ;
+27:__UG_NAME__ -> 63:envelope___control___7 ;
+62:__UG_NAME__ -> 63:gate ;
+4:__UG_NAME__ -> 71:envelope___control___0 ;
+4:__UG_NAME__ -> 71:envelope___control___4 ;
+5:__UG_NAME__ -> 71:envelope___control___5 ;
+6:__UG_NAME__ -> 71:envelope___control___6 ;
+7:__UG_NAME__ -> 71:envelope___control___7 ;
+70:__UG_NAME__ -> 71:gate ;
+0:__UG_NAME__ -> 93:envelope___control___0 ;
+0:__UG_NAME__ -> 93:envelope___control___4 ;
+1:__UG_NAME__ -> 93:envelope___control___5 ;
+2:__UG_NAME__ -> 93:envelope___control___6 ;
+3:__UG_NAME__ -> 93:envelope___control___7 ;
+92:__UG_NAME__ -> 93:gate ;
+28:__UG_NAME__ -> 103:envelope___control___0 ;
+28:__UG_NAME__ -> 103:envelope___control___4 ;
+29:__UG_NAME__ -> 103:envelope___control___5 ;
+30:__UG_NAME__ -> 103:envelope___control___6 ;
+31:__UG_NAME__ -> 103:envelope___control___7 ;
+102:__UG_NAME__ -> 103:gate ;
+16:__UG_NAME__ -> 113:envelope___control___4 ;
+12:__UG_NAME__ -> 113:envelope___control___5 ;
+19:__UG_NAME__ -> 113:envelope___control___6 ;
+112:__UG_NAME__ -> 113:envelope___select___8 ;
+13:__UG_NAME__ -> 113:envelope___control___9 ;
+19:__UG_NAME__ -> 113:envelope___control___10 ;
+18:__UG_NAME__ -> 113:envelope___control___12 ;
+14:__UG_NAME__ -> 113:envelope___control___13 ;
+19:__UG_NAME__ -> 113:envelope___control___14 ;
+15:__UG_NAME__ -> 113:envelope___control___17 ;
+19:__UG_NAME__ -> 113:envelope___control___18 ;
+32:__UG_NAME__ -> 123:envelope___control___0 ;
+32:__UG_NAME__ -> 123:envelope___control___4 ;
+33:__UG_NAME__ -> 123:envelope___control___5 ;
+34:__UG_NAME__ -> 123:envelope___control___6 ;
+35:__UG_NAME__ -> 123:envelope___control___7 ;
+122:__UG_NAME__ -> 123:gate ;
+20:__UG_NAME__ -> 145:envelope___control___0 ;
+20:__UG_NAME__ -> 145:envelope___control___4 ;
+21:__UG_NAME__ -> 145:envelope___control___5 ;
+22:__UG_NAME__ -> 145:envelope___control___6 ;
+23:__UG_NAME__ -> 145:envelope___control___7 ;
+144:__UG_NAME__ -> 145:gate ;
+39:__UG_NAME__ -> 133:revtime ;
+132:__UG_NAME__ -> 133:roomsize ;
+129:__UG_NAME__ -> 133:in ;
+9:__UG_NAME__ -> 41:in ;
+5:__UG_NAME__ -> 44:in ;
+46:__UG_NAME__ -> 47:in ;
+8:__UG_NAME__ -> 49:in ;
+25:__UG_NAME__ -> 59:in ;
+4:__UG_NAME__ -> 65:in ;
+0:__UG_NAME__ -> 85:in ;
+1:__UG_NAME__ -> 89:in ;
+28:__UG_NAME__ -> 95:in ;
+29:__UG_NAME__ -> 99:in ;
+32:__UG_NAME__ -> 108:in ;
+33:__UG_NAME__ -> 119:in ;
+20:__UG_NAME__ -> 137:in ;
+21:__UG_NAME__ -> 141:in ;
+131:__UG_NAME__ -> 132:b ;
+104:__UG_NAME__ -> 105:a ;
+93:__UG_NAME__ -> 115:a ;
+124:__UG_NAME__ -> 125:a ;
+145:__UG_NAME__ -> 146:a ;
+130:__UG_NAME__ -> 131:b ;
+24:__UG_NAME__ -> 46:in ;
+40:__UG_NAME__ -> 152:bus ;
+151:__UG_NAME__ -> 152:signals___balance2___0 ;
+151:__UG_NAME__ -> 152:signals___balance2___1 ;
+83:__UG_NAME__ -> 106:in ;
+105:__UG_NAME__ -> 106:freq ;
+37:__UG_NAME__ -> 106:decay____time ;
+83:__UG_NAME__ -> 116:in ;
+115:__UG_NAME__ -> 116:freq ;
+37:__UG_NAME__ -> 116:decay____time ;
+83:__UG_NAME__ -> 126:in ;
+125:__UG_NAME__ -> 126:freq ;
+37:__UG_NAME__ -> 126:decay____time ;
+135:__UG_NAME__ -> 147:in ;
+146:__UG_NAME__ -> 147:freq ;
+63:__UG_NAME__ -> 147:rq ;
+149:__UG_NAME__ -> 150:in ;
+146:__UG_NAME__ -> 150:freq ;
+63:__UG_NAME__ -> 150:rq ;
+36:__UG_NAME__ -> 83:which ;
+74:__UG_NAME__ -> 83:array___binary____op____u____gen___0 ;
+76:__UG_NAME__ -> 83:array___binary____op____u____gen___1 ;
+78:__UG_NAME__ -> 83:array___binary____op____u____gen___2 ;
+80:__UG_NAME__ -> 83:array___binary____op____u____gen___3 ;
+82:__UG_NAME__ -> 83:array___binary____op____u____gen___4 ;
+72:__UG_NAME__ -> 112:which ;
+17:__UG_NAME__ -> 112:array___control___0 ;
+18:__UG_NAME__ -> 112:array___control___1 ;
+133:__UG_NAME__ -> 134:a ;
+133:__UG_NAME__ -> 148:a ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-dpulse.dot b/etc/synthdefs/graphviz/dot/sonic-pi-dpulse.dot
new file mode 100644
index 0000000..a15a206
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-dpulse.dot
@@ -0,0 +1,377 @@
+digraph synthdef {
+124 [label = "{{ <b> |<a> 1.1} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+128 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+120 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :detune
+ default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :detune_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :detune_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :detune_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :dpulse_width
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :dpulse_width_slide
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :dpulse_width_slide_shape
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :dpulse_width_slide_curve
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+57 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___select___0>|1.0|-99|-99|<envelope___select___4>|<envelope___select___5>|<envelope___select___6>|<envelope___select___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+131 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+130 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+77 [label = "{{ <width> width|<freq> freq} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+117 [label = "{{ <width> width|<freq> freq} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+38 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+123:__UG_NAME__ -> 124:b ;
+124:__UG_NAME__ -> 128:a ;
+127:__UG_NAME__ -> 128:b ;
+48:__UG_NAME__ -> 52:a ;
+51:__UG_NAME__ -> 52:b ;
+52:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+58:__UG_NAME__ -> 62:a ;
+61:__UG_NAME__ -> 62:b ;
+62:__UG_NAME__ -> 64:a ;
+63:__UG_NAME__ -> 64:b ;
+67:__UG_NAME__ -> 71:a ;
+70:__UG_NAME__ -> 71:b ;
+71:__UG_NAME__ -> 75:a ;
+74:__UG_NAME__ -> 75:b ;
+81:__UG_NAME__ -> 84:a ;
+83:__UG_NAME__ -> 84:b ;
+84:__UG_NAME__ -> 88:a ;
+87:__UG_NAME__ -> 88:b ;
+91:__UG_NAME__ -> 95:a ;
+94:__UG_NAME__ -> 95:b ;
+98:__UG_NAME__ -> 102:a ;
+101:__UG_NAME__ -> 102:b ;
+102:__UG_NAME__ -> 103:a ;
+80:__UG_NAME__ -> 103:b ;
+65:__UG_NAME__ -> 105:a ;
+104:__UG_NAME__ -> 105:b ;
+107:__UG_NAME__ -> 111:a ;
+110:__UG_NAME__ -> 111:b ;
+111:__UG_NAME__ -> 115:a ;
+114:__UG_NAME__ -> 115:b ;
+77:__UG_NAME__ -> 118:a ;
+117:__UG_NAME__ -> 118:b ;
+95:__UG_NAME__ -> 120:a ;
+119:__UG_NAME__ -> 120:b ;
+118:__UG_NAME__ -> 121:a ;
+32:__UG_NAME__ -> 37:b ;
+33:__UG_NAME__ -> 42:b ;
+34:__UG_NAME__ -> 44:b ;
+35:__UG_NAME__ -> 46:b ;
+17:__UG_NAME__ -> 125:b ;
+50:__UG_NAME__ -> 51:a ;
+54:__UG_NAME__ -> 55:a ;
+60:__UG_NAME__ -> 61:a ;
+41:__UG_NAME__ -> 63:a ;
+69:__UG_NAME__ -> 70:a ;
+73:__UG_NAME__ -> 74:a ;
+79:__UG_NAME__ -> 80:a ;
+82:__UG_NAME__ -> 83:a ;
+86:__UG_NAME__ -> 87:a ;
+93:__UG_NAME__ -> 94:a ;
+100:__UG_NAME__ -> 101:a ;
+109:__UG_NAME__ -> 110:a ;
+113:__UG_NAME__ -> 114:a ;
+97:__UG_NAME__ -> 119:a ;
+40:__UG_NAME__ -> 41:a ;
+49:__UG_NAME__ -> 50:a ;
+53:__UG_NAME__ -> 54:a ;
+59:__UG_NAME__ -> 60:a ;
+68:__UG_NAME__ -> 69:a ;
+72:__UG_NAME__ -> 73:a ;
+78:__UG_NAME__ -> 79:a ;
+39:__UG_NAME__ -> 82:a ;
+85:__UG_NAME__ -> 86:a ;
+92:__UG_NAME__ -> 93:a ;
+96:__UG_NAME__ -> 97:a ;
+99:__UG_NAME__ -> 100:a ;
+108:__UG_NAME__ -> 109:a ;
+112:__UG_NAME__ -> 113:a ;
+4:__UG_NAME__ -> 57:envelope___control___0 ;
+4:__UG_NAME__ -> 57:envelope___control___4 ;
+5:__UG_NAME__ -> 57:envelope___control___5 ;
+6:__UG_NAME__ -> 57:envelope___control___6 ;
+7:__UG_NAME__ -> 57:envelope___control___7 ;
+56:__UG_NAME__ -> 57:gate ;
+0:__UG_NAME__ -> 65:envelope___control___0 ;
+0:__UG_NAME__ -> 65:envelope___control___4 ;
+1:__UG_NAME__ -> 65:envelope___control___5 ;
+2:__UG_NAME__ -> 65:envelope___control___6 ;
+3:__UG_NAME__ -> 65:envelope___control___7 ;
+64:__UG_NAME__ -> 65:gate ;
+28:__UG_NAME__ -> 76:envelope___control___0 ;
+28:__UG_NAME__ -> 76:envelope___control___4 ;
+29:__UG_NAME__ -> 76:envelope___control___5 ;
+31:__UG_NAME__ -> 76:envelope___control___6 ;
+30:__UG_NAME__ -> 76:envelope___control___7 ;
+75:__UG_NAME__ -> 76:gate ;
+20:__UG_NAME__ -> 89:envelope___control___0 ;
+20:__UG_NAME__ -> 89:envelope___control___4 ;
+21:__UG_NAME__ -> 89:envelope___control___5 ;
+22:__UG_NAME__ -> 89:envelope___control___6 ;
+23:__UG_NAME__ -> 89:envelope___control___7 ;
+88:__UG_NAME__ -> 89:gate ;
+24:__UG_NAME__ -> 104:envelope___control___0 ;
+24:__UG_NAME__ -> 104:envelope___control___4 ;
+25:__UG_NAME__ -> 104:envelope___control___5 ;
+26:__UG_NAME__ -> 104:envelope___control___6 ;
+27:__UG_NAME__ -> 104:envelope___control___7 ;
+103:__UG_NAME__ -> 104:gate ;
+38:__UG_NAME__ -> 116:envelope___select___0 ;
+38:__UG_NAME__ -> 116:envelope___select___4 ;
+43:__UG_NAME__ -> 116:envelope___select___5 ;
+47:__UG_NAME__ -> 116:envelope___select___6 ;
+45:__UG_NAME__ -> 116:envelope___select___7 ;
+115:__UG_NAME__ -> 116:gate ;
+16:__UG_NAME__ -> 127:envelope___control___4 ;
+12:__UG_NAME__ -> 127:envelope___control___5 ;
+19:__UG_NAME__ -> 127:envelope___control___6 ;
+126:__UG_NAME__ -> 127:envelope___select___8 ;
+13:__UG_NAME__ -> 127:envelope___control___9 ;
+19:__UG_NAME__ -> 127:envelope___control___10 ;
+18:__UG_NAME__ -> 127:envelope___control___12 ;
+14:__UG_NAME__ -> 127:envelope___control___13 ;
+19:__UG_NAME__ -> 127:envelope___control___14 ;
+15:__UG_NAME__ -> 127:envelope___control___17 ;
+19:__UG_NAME__ -> 127:envelope___control___18 ;
+8:__UG_NAME__ -> 129:envelope___control___0 ;
+8:__UG_NAME__ -> 129:envelope___control___4 ;
+9:__UG_NAME__ -> 129:envelope___control___5 ;
+10:__UG_NAME__ -> 129:envelope___control___6 ;
+11:__UG_NAME__ -> 129:envelope___control___7 ;
+120:__UG_NAME__ -> 129:gate ;
+20:__UG_NAME__ -> 39:in ;
+1:__UG_NAME__ -> 40:in ;
+4:__UG_NAME__ -> 49:in ;
+5:__UG_NAME__ -> 53:in ;
+0:__UG_NAME__ -> 59:in ;
+28:__UG_NAME__ -> 68:in ;
+29:__UG_NAME__ -> 72:in ;
+25:__UG_NAME__ -> 78:in ;
+21:__UG_NAME__ -> 85:in ;
+8:__UG_NAME__ -> 92:in ;
+9:__UG_NAME__ -> 96:in ;
+24:__UG_NAME__ -> 99:in ;
+38:__UG_NAME__ -> 108:in ;
+43:__UG_NAME__ -> 112:in ;
+121:__UG_NAME__ -> 122:in ;
+90:__UG_NAME__ -> 122:freq ;
+65:__UG_NAME__ -> 66:a ;
+89:__UG_NAME__ -> 90:a ;
+105:__UG_NAME__ -> 106:a ;
+122:__UG_NAME__ -> 123:in ;
+36:__UG_NAME__ -> 131:bus ;
+130:__UG_NAME__ -> 131:signals___pan2___0 ;
+130:__UG_NAME__ -> 131:signals___pan2___1 ;
+128:__UG_NAME__ -> 130:in ;
+129:__UG_NAME__ -> 130:pos ;
+57:__UG_NAME__ -> 130:level ;
+66:__UG_NAME__ -> 77:freq ;
+76:__UG_NAME__ -> 77:width ;
+106:__UG_NAME__ -> 117:freq ;
+116:__UG_NAME__ -> 117:width ;
+37:__UG_NAME__ -> 38:which ;
+32:__UG_NAME__ -> 38:array___control___0 ;
+28:__UG_NAME__ -> 38:array___control___1 ;
+42:__UG_NAME__ -> 43:which ;
+33:__UG_NAME__ -> 43:array___control___0 ;
+29:__UG_NAME__ -> 43:array___control___1 ;
+44:__UG_NAME__ -> 45:which ;
+38:__UG_NAME__ -> 45:array___select___0 ;
+30:__UG_NAME__ -> 45:array___control___1 ;
+46:__UG_NAME__ -> 47:which ;
+38:__UG_NAME__ -> 47:array___select___0 ;
+31:__UG_NAME__ -> 47:array___control___1 ;
+125:__UG_NAME__ -> 126:which ;
+17:__UG_NAME__ -> 126:array___control___0 ;
+18:__UG_NAME__ -> 126:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-dsaw.dot b/etc/synthdefs/graphviz/dot/sonic-pi-dsaw.dot
new file mode 100644
index 0000000..bd2a571
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-dsaw.dot
@@ -0,0 +1,275 @@
+digraph synthdef {
+70 [label = "{{ <b> 0.5|<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> 1.1} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+74 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :detune
+ default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :detune_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :detune_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :detune_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+55 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+95 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+94 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+57 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+68 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+83 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+69:__UG_NAME__ -> 70:a ;
+81:__UG_NAME__ -> 82:b ;
+82:__UG_NAME__ -> 85:a ;
+84:__UG_NAME__ -> 85:b ;
+32:__UG_NAME__ -> 36:a ;
+35:__UG_NAME__ -> 36:b ;
+37:__UG_NAME__ -> 40:a ;
+39:__UG_NAME__ -> 40:b ;
+40:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+46:__UG_NAME__ -> 50:a ;
+49:__UG_NAME__ -> 50:b ;
+50:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+58:__UG_NAME__ -> 60:a ;
+59:__UG_NAME__ -> 60:b ;
+60:__UG_NAME__ -> 64:a ;
+63:__UG_NAME__ -> 64:b ;
+55:__UG_NAME__ -> 66:a ;
+65:__UG_NAME__ -> 66:b ;
+57:__UG_NAME__ -> 69:a ;
+68:__UG_NAME__ -> 69:b ;
+36:__UG_NAME__ -> 74:a ;
+73:__UG_NAME__ -> 74:b ;
+87:__UG_NAME__ -> 88:a ;
+86:__UG_NAME__ -> 88:b ;
+88:__UG_NAME__ -> 91:a ;
+90:__UG_NAME__ -> 91:b ;
+17:__UG_NAME__ -> 45:b ;
+34:__UG_NAME__ -> 35:a ;
+38:__UG_NAME__ -> 39:a ;
+42:__UG_NAME__ -> 43:a ;
+48:__UG_NAME__ -> 49:a ;
+52:__UG_NAME__ -> 53:a ;
+30:__UG_NAME__ -> 59:a ;
+62:__UG_NAME__ -> 63:a ;
+72:__UG_NAME__ -> 73:a ;
+79:__UG_NAME__ -> 86:a ;
+89:__UG_NAME__ -> 90:a ;
+29:__UG_NAME__ -> 30:a ;
+33:__UG_NAME__ -> 34:a ;
+31:__UG_NAME__ -> 38:a ;
+41:__UG_NAME__ -> 42:a ;
+47:__UG_NAME__ -> 48:a ;
+51:__UG_NAME__ -> 52:a ;
+61:__UG_NAME__ -> 62:a ;
+71:__UG_NAME__ -> 72:a ;
+78:__UG_NAME__ -> 79:a ;
+80:__UG_NAME__ -> 89:a ;
+0:__UG_NAME__ -> 55:envelope___control___0 ;
+0:__UG_NAME__ -> 55:envelope___control___4 ;
+1:__UG_NAME__ -> 55:envelope___control___5 ;
+2:__UG_NAME__ -> 55:envelope___control___6 ;
+3:__UG_NAME__ -> 55:envelope___control___7 ;
+54:__UG_NAME__ -> 55:gate ;
+24:__UG_NAME__ -> 65:envelope___control___0 ;
+24:__UG_NAME__ -> 65:envelope___control___4 ;
+25:__UG_NAME__ -> 65:envelope___control___5 ;
+26:__UG_NAME__ -> 65:envelope___control___6 ;
+27:__UG_NAME__ -> 65:envelope___control___7 ;
+64:__UG_NAME__ -> 65:gate ;
+20:__UG_NAME__ -> 75:envelope___control___0 ;
+20:__UG_NAME__ -> 75:envelope___control___4 ;
+21:__UG_NAME__ -> 75:envelope___control___5 ;
+22:__UG_NAME__ -> 75:envelope___control___6 ;
+23:__UG_NAME__ -> 75:envelope___control___7 ;
+74:__UG_NAME__ -> 75:gate ;
+16:__UG_NAME__ -> 84:envelope___control___4 ;
+12:__UG_NAME__ -> 84:envelope___control___5 ;
+19:__UG_NAME__ -> 84:envelope___control___6 ;
+83:__UG_NAME__ -> 84:envelope___select___8 ;
+13:__UG_NAME__ -> 84:envelope___control___9 ;
+19:__UG_NAME__ -> 84:envelope___control___10 ;
+18:__UG_NAME__ -> 84:envelope___control___12 ;
+14:__UG_NAME__ -> 84:envelope___control___13 ;
+19:__UG_NAME__ -> 84:envelope___control___14 ;
+15:__UG_NAME__ -> 84:envelope___control___17 ;
+19:__UG_NAME__ -> 84:envelope___control___18 ;
+8:__UG_NAME__ -> 92:envelope___control___0 ;
+8:__UG_NAME__ -> 92:envelope___control___4 ;
+9:__UG_NAME__ -> 92:envelope___control___5 ;
+10:__UG_NAME__ -> 92:envelope___control___6 ;
+11:__UG_NAME__ -> 92:envelope___control___7 ;
+44:__UG_NAME__ -> 92:gate ;
+4:__UG_NAME__ -> 93:envelope___control___0 ;
+4:__UG_NAME__ -> 93:envelope___control___4 ;
+5:__UG_NAME__ -> 93:envelope___control___5 ;
+6:__UG_NAME__ -> 93:envelope___control___6 ;
+7:__UG_NAME__ -> 93:envelope___control___7 ;
+91:__UG_NAME__ -> 93:gate ;
+24:__UG_NAME__ -> 29:in ;
+8:__UG_NAME__ -> 31:in ;
+20:__UG_NAME__ -> 33:in ;
+9:__UG_NAME__ -> 41:in ;
+0:__UG_NAME__ -> 47:in ;
+1:__UG_NAME__ -> 51:in ;
+25:__UG_NAME__ -> 61:in ;
+21:__UG_NAME__ -> 71:in ;
+4:__UG_NAME__ -> 78:in ;
+5:__UG_NAME__ -> 80:in ;
+70:__UG_NAME__ -> 77:in ;
+76:__UG_NAME__ -> 77:freq ;
+55:__UG_NAME__ -> 56:a ;
+66:__UG_NAME__ -> 67:a ;
+75:__UG_NAME__ -> 76:a ;
+77:__UG_NAME__ -> 81:in ;
+28:__UG_NAME__ -> 95:bus ;
+94:__UG_NAME__ -> 95:signals___pan2___0 ;
+94:__UG_NAME__ -> 95:signals___pan2___1 ;
+85:__UG_NAME__ -> 94:in ;
+92:__UG_NAME__ -> 94:pos ;
+93:__UG_NAME__ -> 94:level ;
+56:__UG_NAME__ -> 57:freq ;
+67:__UG_NAME__ -> 68:freq ;
+45:__UG_NAME__ -> 83:which ;
+17:__UG_NAME__ -> 83:array___control___0 ;
+18:__UG_NAME__ -> 83:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-dtri.dot b/etc/synthdefs/graphviz/dot/sonic-pi-dtri.dot
new file mode 100644
index 0000000..43c6d6e
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-dtri.dot
@@ -0,0 +1,275 @@
+digraph synthdef {
+70 [label = "{{ <b> 0.5|<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+92 [label = "{{ <b> |<a> 1.1} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+93 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+74 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :detune
+ default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :detune_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :detune_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :detune_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <iphase> iphase 0.0|<freq> freq} |<__UG_NAME__>lf-tri }" style="filled, bold, rounded"  shape=record rankdir=LR];
+68 [label = "{{ <iphase> iphase 0.0|<freq> freq} |<__UG_NAME__>lf-tri }" style="filled, bold, rounded"  shape=record rankdir=LR];
+77 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+95 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+94 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+89 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+69:__UG_NAME__ -> 70:a ;
+78:__UG_NAME__ -> 92:b ;
+92:__UG_NAME__ -> 93:a ;
+90:__UG_NAME__ -> 93:b ;
+30:__UG_NAME__ -> 34:a ;
+33:__UG_NAME__ -> 34:b ;
+34:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+40:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+48:__UG_NAME__ -> 49:a ;
+47:__UG_NAME__ -> 49:b ;
+49:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+29:__UG_NAME__ -> 60:a ;
+59:__UG_NAME__ -> 60:b ;
+60:__UG_NAME__ -> 64:a ;
+63:__UG_NAME__ -> 64:b ;
+54:__UG_NAME__ -> 66:a ;
+65:__UG_NAME__ -> 66:b ;
+56:__UG_NAME__ -> 69:a ;
+68:__UG_NAME__ -> 69:b ;
+44:__UG_NAME__ -> 74:a ;
+73:__UG_NAME__ -> 74:b ;
+79:__UG_NAME__ -> 83:a ;
+82:__UG_NAME__ -> 83:b ;
+83:__UG_NAME__ -> 87:a ;
+86:__UG_NAME__ -> 87:b ;
+17:__UG_NAME__ -> 88:b ;
+32:__UG_NAME__ -> 33:a ;
+36:__UG_NAME__ -> 37:a ;
+42:__UG_NAME__ -> 43:a ;
+46:__UG_NAME__ -> 47:a ;
+51:__UG_NAME__ -> 52:a ;
+58:__UG_NAME__ -> 59:a ;
+62:__UG_NAME__ -> 63:a ;
+72:__UG_NAME__ -> 73:a ;
+81:__UG_NAME__ -> 82:a ;
+85:__UG_NAME__ -> 86:a ;
+31:__UG_NAME__ -> 32:a ;
+35:__UG_NAME__ -> 36:a ;
+41:__UG_NAME__ -> 42:a ;
+45:__UG_NAME__ -> 46:a ;
+50:__UG_NAME__ -> 51:a ;
+57:__UG_NAME__ -> 58:a ;
+61:__UG_NAME__ -> 62:a ;
+71:__UG_NAME__ -> 72:a ;
+80:__UG_NAME__ -> 81:a ;
+84:__UG_NAME__ -> 85:a ;
+4:__UG_NAME__ -> 39:envelope___control___0 ;
+4:__UG_NAME__ -> 39:envelope___control___4 ;
+5:__UG_NAME__ -> 39:envelope___control___5 ;
+6:__UG_NAME__ -> 39:envelope___control___6 ;
+7:__UG_NAME__ -> 39:envelope___control___7 ;
+38:__UG_NAME__ -> 39:gate ;
+0:__UG_NAME__ -> 54:envelope___control___0 ;
+0:__UG_NAME__ -> 54:envelope___control___4 ;
+1:__UG_NAME__ -> 54:envelope___control___5 ;
+2:__UG_NAME__ -> 54:envelope___control___6 ;
+3:__UG_NAME__ -> 54:envelope___control___7 ;
+53:__UG_NAME__ -> 54:gate ;
+24:__UG_NAME__ -> 65:envelope___control___0 ;
+24:__UG_NAME__ -> 65:envelope___control___4 ;
+25:__UG_NAME__ -> 65:envelope___control___5 ;
+26:__UG_NAME__ -> 65:envelope___control___6 ;
+27:__UG_NAME__ -> 65:envelope___control___7 ;
+64:__UG_NAME__ -> 65:gate ;
+20:__UG_NAME__ -> 75:envelope___control___0 ;
+20:__UG_NAME__ -> 75:envelope___control___4 ;
+21:__UG_NAME__ -> 75:envelope___control___5 ;
+22:__UG_NAME__ -> 75:envelope___control___6 ;
+23:__UG_NAME__ -> 75:envelope___control___7 ;
+74:__UG_NAME__ -> 75:gate ;
+16:__UG_NAME__ -> 90:envelope___control___4 ;
+12:__UG_NAME__ -> 90:envelope___control___5 ;
+19:__UG_NAME__ -> 90:envelope___control___6 ;
+89:__UG_NAME__ -> 90:envelope___select___8 ;
+13:__UG_NAME__ -> 90:envelope___control___9 ;
+19:__UG_NAME__ -> 90:envelope___control___10 ;
+18:__UG_NAME__ -> 90:envelope___control___12 ;
+14:__UG_NAME__ -> 90:envelope___control___13 ;
+19:__UG_NAME__ -> 90:envelope___control___14 ;
+15:__UG_NAME__ -> 90:envelope___control___17 ;
+19:__UG_NAME__ -> 90:envelope___control___18 ;
+8:__UG_NAME__ -> 91:envelope___control___0 ;
+8:__UG_NAME__ -> 91:envelope___control___4 ;
+9:__UG_NAME__ -> 91:envelope___control___5 ;
+10:__UG_NAME__ -> 91:envelope___control___6 ;
+11:__UG_NAME__ -> 91:envelope___control___7 ;
+87:__UG_NAME__ -> 91:gate ;
+4:__UG_NAME__ -> 31:in ;
+5:__UG_NAME__ -> 35:in ;
+20:__UG_NAME__ -> 41:in ;
+0:__UG_NAME__ -> 45:in ;
+1:__UG_NAME__ -> 50:in ;
+24:__UG_NAME__ -> 57:in ;
+25:__UG_NAME__ -> 61:in ;
+21:__UG_NAME__ -> 71:in ;
+8:__UG_NAME__ -> 80:in ;
+9:__UG_NAME__ -> 84:in ;
+55:__UG_NAME__ -> 56:freq ;
+67:__UG_NAME__ -> 68:freq ;
+70:__UG_NAME__ -> 77:in ;
+76:__UG_NAME__ -> 77:freq ;
+54:__UG_NAME__ -> 55:a ;
+66:__UG_NAME__ -> 67:a ;
+75:__UG_NAME__ -> 76:a ;
+77:__UG_NAME__ -> 78:in ;
+28:__UG_NAME__ -> 95:bus ;
+94:__UG_NAME__ -> 95:signals___pan2___0 ;
+94:__UG_NAME__ -> 95:signals___pan2___1 ;
+93:__UG_NAME__ -> 94:in ;
+91:__UG_NAME__ -> 94:pos ;
+39:__UG_NAME__ -> 94:level ;
+88:__UG_NAME__ -> 89:which ;
+17:__UG_NAME__ -> 89:array___control___0 ;
+18:__UG_NAME__ -> 89:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-dull_bell.dot b/etc/synthdefs/graphviz/dot/sonic-pi-dull_bell.dot
new file mode 100644
index 0000000..7956af5
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-dull_bell.dot
@@ -0,0 +1,258 @@
+digraph synthdef {
+21 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> 0.56} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+39 [label = "{{ <b> 0.5|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> 0.5|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> 0.5|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> 1.19} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+57 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> 3.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+65 [label = "{{ <b> 0.125|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> 0.125|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> 0.125|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> 3.76} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+88 [label = "{{ <action> action 2.0|<time> time 0.1|<amp> amp 1.0E-4|<in> in} |<__UG_NAME__>detect-silence }" style="filled, bold, rounded"  shape=record rankdir=LR];
+24 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 0.5|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|1.0|0.0|<envelope___control___8>|<envelope___binary____op____u____gen___9>|1.0|0.0|<envelope___control___12>|<envelope___binary____op____u____gen___13>|1.0|0.0|0.0|<envelope___binary____op____u____gen___17>|1.0|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 0.25|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|1.0|0.0|<envelope___control___8>|<envelope___binary____op____u____gen___9>|1.0|0.0|<envelope___control___12>|<envelope___binary____op____u____gen___13>|1.0|0.0|0.0|<envelope___binary____op____u____gen___17>|1.0|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 0.125|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|1.0|0.0|<envelope___control___8>|<envelope___binary____op____u____gen___9>|1.0|0.0|<envelope___control___12>|<envelope___binary____op____u____gen___13>|1.0|0.0|0.0|<envelope___binary____op____u____gen___17>|1.0|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 0.0625|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|1.0|0.0|<envelope___control___8>|<envelope___binary____op____u____gen___9>|1.0|0.0|<envelope___control___12>|<envelope___binary____op____u____gen___13>|1.0|0.0|0.0|<envelope___binary____op____u____gen___17>|1.0|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+84 [label = "{{ <level> level 1.0|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+87 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+44 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+62 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+70 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+13:__UG_NAME__ -> 21:a ;
+14:__UG_NAME__ -> 22:a ;
+15:__UG_NAME__ -> 23:a ;
+35:__UG_NAME__ -> 36:b ;
+24:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+13:__UG_NAME__ -> 39:a ;
+14:__UG_NAME__ -> 40:a ;
+15:__UG_NAME__ -> 41:a ;
+35:__UG_NAME__ -> 43:b ;
+42:__UG_NAME__ -> 45:a ;
+44:__UG_NAME__ -> 45:b ;
+13:__UG_NAME__ -> 57:a ;
+14:__UG_NAME__ -> 58:a ;
+15:__UG_NAME__ -> 59:a ;
+35:__UG_NAME__ -> 61:b ;
+60:__UG_NAME__ -> 63:a ;
+62:__UG_NAME__ -> 63:b ;
+13:__UG_NAME__ -> 65:a ;
+14:__UG_NAME__ -> 66:a ;
+15:__UG_NAME__ -> 67:a ;
+35:__UG_NAME__ -> 69:b ;
+68:__UG_NAME__ -> 71:a ;
+70:__UG_NAME__ -> 71:b ;
+56:__UG_NAME__ -> 73:a ;
+72:__UG_NAME__ -> 73:b ;
+25:__UG_NAME__ -> 29:a ;
+28:__UG_NAME__ -> 29:b ;
+29:__UG_NAME__ -> 33:a ;
+32:__UG_NAME__ -> 33:b ;
+38:__UG_NAME__ -> 46:a ;
+45:__UG_NAME__ -> 46:b ;
+47:__UG_NAME__ -> 51:a ;
+50:__UG_NAME__ -> 51:b ;
+51:__UG_NAME__ -> 55:a ;
+54:__UG_NAME__ -> 55:b ;
+46:__UG_NAME__ -> 64:a ;
+63:__UG_NAME__ -> 64:b ;
+64:__UG_NAME__ -> 72:a ;
+71:__UG_NAME__ -> 72:b ;
+74:__UG_NAME__ -> 78:a ;
+77:__UG_NAME__ -> 78:b ;
+78:__UG_NAME__ -> 82:a ;
+81:__UG_NAME__ -> 82:b ;
+17:__UG_NAME__ -> 86:b ;
+27:__UG_NAME__ -> 28:a ;
+31:__UG_NAME__ -> 32:a ;
+49:__UG_NAME__ -> 50:a ;
+53:__UG_NAME__ -> 54:a ;
+76:__UG_NAME__ -> 77:a ;
+80:__UG_NAME__ -> 81:a ;
+26:__UG_NAME__ -> 27:a ;
+30:__UG_NAME__ -> 31:a ;
+48:__UG_NAME__ -> 49:a ;
+52:__UG_NAME__ -> 53:a ;
+75:__UG_NAME__ -> 76:a ;
+79:__UG_NAME__ -> 80:a ;
+73:__UG_NAME__ -> 88:in ;
+16:__UG_NAME__ -> 24:envelope___control___4 ;
+12:__UG_NAME__ -> 24:envelope___control___5 ;
+18:__UG_NAME__ -> 24:envelope___control___8 ;
+21:__UG_NAME__ -> 24:envelope___binary____op____u____gen___9 ;
+18:__UG_NAME__ -> 24:envelope___control___12 ;
+22:__UG_NAME__ -> 24:envelope___binary____op____u____gen___13 ;
+23:__UG_NAME__ -> 24:envelope___binary____op____u____gen___17 ;
+0:__UG_NAME__ -> 34:envelope___control___0 ;
+0:__UG_NAME__ -> 34:envelope___control___4 ;
+1:__UG_NAME__ -> 34:envelope___control___5 ;
+2:__UG_NAME__ -> 34:envelope___control___6 ;
+3:__UG_NAME__ -> 34:envelope___control___7 ;
+33:__UG_NAME__ -> 34:gate ;
+16:__UG_NAME__ -> 42:envelope___control___4 ;
+12:__UG_NAME__ -> 42:envelope___control___5 ;
+18:__UG_NAME__ -> 42:envelope___control___8 ;
+39:__UG_NAME__ -> 42:envelope___binary____op____u____gen___9 ;
+18:__UG_NAME__ -> 42:envelope___control___12 ;
+40:__UG_NAME__ -> 42:envelope___binary____op____u____gen___13 ;
+41:__UG_NAME__ -> 42:envelope___binary____op____u____gen___17 ;
+4:__UG_NAME__ -> 56:envelope___control___0 ;
+4:__UG_NAME__ -> 56:envelope___control___4 ;
+5:__UG_NAME__ -> 56:envelope___control___5 ;
+6:__UG_NAME__ -> 56:envelope___control___6 ;
+7:__UG_NAME__ -> 56:envelope___control___7 ;
+55:__UG_NAME__ -> 56:gate ;
+16:__UG_NAME__ -> 60:envelope___control___4 ;
+12:__UG_NAME__ -> 60:envelope___control___5 ;
+18:__UG_NAME__ -> 60:envelope___control___8 ;
+57:__UG_NAME__ -> 60:envelope___binary____op____u____gen___9 ;
+18:__UG_NAME__ -> 60:envelope___control___12 ;
+58:__UG_NAME__ -> 60:envelope___binary____op____u____gen___13 ;
+59:__UG_NAME__ -> 60:envelope___binary____op____u____gen___17 ;
+16:__UG_NAME__ -> 68:envelope___control___4 ;
+12:__UG_NAME__ -> 68:envelope___control___5 ;
+18:__UG_NAME__ -> 68:envelope___control___8 ;
+65:__UG_NAME__ -> 68:envelope___binary____op____u____gen___9 ;
+18:__UG_NAME__ -> 68:envelope___control___12 ;
+66:__UG_NAME__ -> 68:envelope___binary____op____u____gen___13 ;
+67:__UG_NAME__ -> 68:envelope___binary____op____u____gen___17 ;
+8:__UG_NAME__ -> 83:envelope___control___0 ;
+8:__UG_NAME__ -> 83:envelope___control___4 ;
+9:__UG_NAME__ -> 83:envelope___control___5 ;
+10:__UG_NAME__ -> 83:envelope___control___6 ;
+11:__UG_NAME__ -> 83:envelope___control___7 ;
+82:__UG_NAME__ -> 83:gate ;
+0:__UG_NAME__ -> 26:in ;
+1:__UG_NAME__ -> 30:in ;
+4:__UG_NAME__ -> 48:in ;
+5:__UG_NAME__ -> 52:in ;
+8:__UG_NAME__ -> 75:in ;
+9:__UG_NAME__ -> 79:in ;
+34:__UG_NAME__ -> 35:a ;
+20:__UG_NAME__ -> 85:bus ;
+84:__UG_NAME__ -> 85:signals___pan2___0 ;
+84:__UG_NAME__ -> 85:signals___pan2___1 ;
+73:__UG_NAME__ -> 84:in ;
+83:__UG_NAME__ -> 84:pos ;
+86:__UG_NAME__ -> 87:which ;
+17:__UG_NAME__ -> 87:array___control___0 ;
+18:__UG_NAME__ -> 87:array___control___1 ;
+36:__UG_NAME__ -> 37:freq ;
+43:__UG_NAME__ -> 44:freq ;
+61:__UG_NAME__ -> 62:freq ;
+69:__UG_NAME__ -> 70:freq ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fm.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fm.dot
new file mode 100644
index 0000000..2df1190
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fm.dot
@@ -0,0 +1,316 @@
+digraph synthdef {
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+105 [label = "{{ <b> |<a> 0.8} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :divisor
+ default: 2.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :divisor_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :divisor_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :divisor_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :depth
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :depth_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :depth_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :depth_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+108 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+56 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+84 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+54:__UG_NAME__ -> 68:a ;
+67:__UG_NAME__ -> 68:b ;
+57:__UG_NAME__ -> 69:a ;
+68:__UG_NAME__ -> 69:b ;
+69:__UG_NAME__ -> 82:a ;
+81:__UG_NAME__ -> 82:b ;
+57:__UG_NAME__ -> 97:a ;
+96:__UG_NAME__ -> 97:b ;
+97:__UG_NAME__ -> 105:b ;
+34:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+38:__UG_NAME__ -> 42:a ;
+41:__UG_NAME__ -> 42:b ;
+44:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+48:__UG_NAME__ -> 52:a ;
+51:__UG_NAME__ -> 52:b ;
+58:__UG_NAME__ -> 62:a ;
+61:__UG_NAME__ -> 62:b ;
+62:__UG_NAME__ -> 66:a ;
+65:__UG_NAME__ -> 66:b ;
+70:__UG_NAME__ -> 74:a ;
+73:__UG_NAME__ -> 74:b ;
+74:__UG_NAME__ -> 78:a ;
+77:__UG_NAME__ -> 78:b ;
+54:__UG_NAME__ -> 83:a ;
+82:__UG_NAME__ -> 83:b ;
+85:__UG_NAME__ -> 89:a ;
+88:__UG_NAME__ -> 89:b ;
+89:__UG_NAME__ -> 93:a ;
+92:__UG_NAME__ -> 93:b ;
+101:__UG_NAME__ -> 104:a ;
+103:__UG_NAME__ -> 104:b ;
+104:__UG_NAME__ -> 106:a ;
+100:__UG_NAME__ -> 106:b ;
+54:__UG_NAME__ -> 80:a ;
+79:__UG_NAME__ -> 80:b ;
+17:__UG_NAME__ -> 55:b ;
+36:__UG_NAME__ -> 37:a ;
+40:__UG_NAME__ -> 41:a ;
+46:__UG_NAME__ -> 47:a ;
+50:__UG_NAME__ -> 51:a ;
+60:__UG_NAME__ -> 61:a ;
+64:__UG_NAME__ -> 65:a ;
+72:__UG_NAME__ -> 73:a ;
+76:__UG_NAME__ -> 77:a ;
+87:__UG_NAME__ -> 88:a ;
+91:__UG_NAME__ -> 92:a ;
+99:__UG_NAME__ -> 100:a ;
+102:__UG_NAME__ -> 103:a ;
+35:__UG_NAME__ -> 36:a ;
+39:__UG_NAME__ -> 40:a ;
+45:__UG_NAME__ -> 46:a ;
+49:__UG_NAME__ -> 50:a ;
+59:__UG_NAME__ -> 60:a ;
+63:__UG_NAME__ -> 64:a ;
+71:__UG_NAME__ -> 72:a ;
+75:__UG_NAME__ -> 76:a ;
+86:__UG_NAME__ -> 87:a ;
+90:__UG_NAME__ -> 91:a ;
+98:__UG_NAME__ -> 99:a ;
+33:__UG_NAME__ -> 102:a ;
+8:__UG_NAME__ -> 43:envelope___control___0 ;
+8:__UG_NAME__ -> 43:envelope___control___4 ;
+9:__UG_NAME__ -> 43:envelope___control___5 ;
+10:__UG_NAME__ -> 43:envelope___control___6 ;
+11:__UG_NAME__ -> 43:envelope___control___7 ;
+42:__UG_NAME__ -> 43:gate ;
+0:__UG_NAME__ -> 53:envelope___control___0 ;
+0:__UG_NAME__ -> 53:envelope___control___4 ;
+1:__UG_NAME__ -> 53:envelope___control___5 ;
+2:__UG_NAME__ -> 53:envelope___control___6 ;
+3:__UG_NAME__ -> 53:envelope___control___7 ;
+52:__UG_NAME__ -> 53:gate ;
+16:__UG_NAME__ -> 57:envelope___control___4 ;
+12:__UG_NAME__ -> 57:envelope___control___5 ;
+19:__UG_NAME__ -> 57:envelope___control___6 ;
+56:__UG_NAME__ -> 57:envelope___select___8 ;
+13:__UG_NAME__ -> 57:envelope___control___9 ;
+19:__UG_NAME__ -> 57:envelope___control___10 ;
+18:__UG_NAME__ -> 57:envelope___control___12 ;
+14:__UG_NAME__ -> 57:envelope___control___13 ;
+19:__UG_NAME__ -> 57:envelope___control___14 ;
+15:__UG_NAME__ -> 57:envelope___control___17 ;
+19:__UG_NAME__ -> 57:envelope___control___18 ;
+28:__UG_NAME__ -> 67:envelope___control___0 ;
+28:__UG_NAME__ -> 67:envelope___control___4 ;
+29:__UG_NAME__ -> 67:envelope___control___5 ;
+30:__UG_NAME__ -> 67:envelope___control___6 ;
+31:__UG_NAME__ -> 67:envelope___control___7 ;
+66:__UG_NAME__ -> 67:gate ;
+24:__UG_NAME__ -> 79:envelope___control___0 ;
+24:__UG_NAME__ -> 79:envelope___control___4 ;
+25:__UG_NAME__ -> 79:envelope___control___5 ;
+26:__UG_NAME__ -> 79:envelope___control___6 ;
+27:__UG_NAME__ -> 79:envelope___control___7 ;
+78:__UG_NAME__ -> 79:gate ;
+20:__UG_NAME__ -> 94:envelope___control___0 ;
+20:__UG_NAME__ -> 94:envelope___control___4 ;
+21:__UG_NAME__ -> 94:envelope___control___5 ;
+22:__UG_NAME__ -> 94:envelope___control___6 ;
+23:__UG_NAME__ -> 94:envelope___control___7 ;
+93:__UG_NAME__ -> 94:gate ;
+4:__UG_NAME__ -> 107:envelope___control___0 ;
+4:__UG_NAME__ -> 107:envelope___control___4 ;
+5:__UG_NAME__ -> 107:envelope___control___5 ;
+6:__UG_NAME__ -> 107:envelope___control___6 ;
+7:__UG_NAME__ -> 107:envelope___control___7 ;
+106:__UG_NAME__ -> 107:gate ;
+4:__UG_NAME__ -> 33:in ;
+8:__UG_NAME__ -> 35:in ;
+9:__UG_NAME__ -> 39:in ;
+0:__UG_NAME__ -> 45:in ;
+1:__UG_NAME__ -> 49:in ;
+28:__UG_NAME__ -> 59:in ;
+29:__UG_NAME__ -> 63:in ;
+24:__UG_NAME__ -> 71:in ;
+25:__UG_NAME__ -> 75:in ;
+20:__UG_NAME__ -> 86:in ;
+21:__UG_NAME__ -> 90:in ;
+5:__UG_NAME__ -> 98:in ;
+84:__UG_NAME__ -> 96:in ;
+95:__UG_NAME__ -> 96:freq ;
+53:__UG_NAME__ -> 54:a ;
+94:__UG_NAME__ -> 95:a ;
+32:__UG_NAME__ -> 109:bus ;
+108:__UG_NAME__ -> 109:signals___pan2___0 ;
+108:__UG_NAME__ -> 109:signals___pan2___1 ;
+105:__UG_NAME__ -> 108:in ;
+43:__UG_NAME__ -> 108:pos ;
+107:__UG_NAME__ -> 108:level ;
+55:__UG_NAME__ -> 56:which ;
+17:__UG_NAME__ -> 56:array___control___0 ;
+18:__UG_NAME__ -> 56:array___control___1 ;
+80:__UG_NAME__ -> 81:freq ;
+83:__UG_NAME__ -> 84:freq ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_band_eq.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_band_eq.dot
new file mode 100644
index 0000000..e0272c8
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_band_eq.dot
@@ -0,0 +1,282 @@
+digraph synthdef {
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+81 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+96 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :freq
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :freq_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :freq_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :freq_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :res
+ default: 0.6" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :db
+ default: 0.6" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :db_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :db_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :db_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+70 [label = "{{ <db> db|<rq> rq|<freq> freq|<in> in} |<__UG_NAME__>mid-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
+95 [label = "{{ <db> db|<rq> rq|<freq> freq|<in> in} |<__UG_NAME__>mid-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+93 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+98 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+46:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+80:__UG_NAME__ -> 81:a ;
+46:__UG_NAME__ -> 94:a ;
+47:__UG_NAME__ -> 94:b ;
+80:__UG_NAME__ -> 96:a ;
+28:__UG_NAME__ -> 31:a ;
+30:__UG_NAME__ -> 31:b ;
+31:__UG_NAME__ -> 35:a ;
+34:__UG_NAME__ -> 35:b ;
+37:__UG_NAME__ -> 41:a ;
+40:__UG_NAME__ -> 41:b ;
+41:__UG_NAME__ -> 45:a ;
+44:__UG_NAME__ -> 45:b ;
+49:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+53:__UG_NAME__ -> 57:a ;
+56:__UG_NAME__ -> 57:b ;
+60:__UG_NAME__ -> 64:a ;
+63:__UG_NAME__ -> 64:b ;
+64:__UG_NAME__ -> 68:a ;
+67:__UG_NAME__ -> 68:b ;
+71:__UG_NAME__ -> 75:a ;
+74:__UG_NAME__ -> 75:b ;
+75:__UG_NAME__ -> 79:a ;
+78:__UG_NAME__ -> 79:b ;
+83:__UG_NAME__ -> 87:a ;
+86:__UG_NAME__ -> 87:b ;
+87:__UG_NAME__ -> 91:a ;
+90:__UG_NAME__ -> 91:b ;
+81:__UG_NAME__ -> 82:a ;
+96:__UG_NAME__ -> 97:a ;
+29:__UG_NAME__ -> 30:a ;
+33:__UG_NAME__ -> 34:a ;
+39:__UG_NAME__ -> 40:a ;
+43:__UG_NAME__ -> 44:a ;
+51:__UG_NAME__ -> 52:a ;
+55:__UG_NAME__ -> 56:a ;
+62:__UG_NAME__ -> 63:a ;
+66:__UG_NAME__ -> 67:a ;
+73:__UG_NAME__ -> 74:a ;
+77:__UG_NAME__ -> 78:a ;
+85:__UG_NAME__ -> 86:a ;
+89:__UG_NAME__ -> 90:a ;
+27:__UG_NAME__ -> 29:a ;
+32:__UG_NAME__ -> 33:a ;
+38:__UG_NAME__ -> 39:a ;
+42:__UG_NAME__ -> 43:a ;
+50:__UG_NAME__ -> 51:a ;
+54:__UG_NAME__ -> 55:a ;
+61:__UG_NAME__ -> 62:a ;
+65:__UG_NAME__ -> 66:a ;
+72:__UG_NAME__ -> 73:a ;
+76:__UG_NAME__ -> 77:a ;
+84:__UG_NAME__ -> 85:a ;
+88:__UG_NAME__ -> 89:a ;
+26:__UG_NAME__ -> 36:envelope___mul____add___0 ;
+26:__UG_NAME__ -> 36:envelope___mul____add___4 ;
+17:__UG_NAME__ -> 36:envelope___control___5 ;
+18:__UG_NAME__ -> 36:envelope___control___6 ;
+19:__UG_NAME__ -> 36:envelope___control___7 ;
+35:__UG_NAME__ -> 36:gate ;
+8:__UG_NAME__ -> 46:envelope___control___0 ;
+8:__UG_NAME__ -> 46:envelope___control___4 ;
+9:__UG_NAME__ -> 46:envelope___control___5 ;
+10:__UG_NAME__ -> 46:envelope___control___6 ;
+11:__UG_NAME__ -> 46:envelope___control___7 ;
+45:__UG_NAME__ -> 46:gate ;
+12:__UG_NAME__ -> 58:envelope___control___0 ;
+12:__UG_NAME__ -> 58:envelope___control___4 ;
+13:__UG_NAME__ -> 58:envelope___control___5 ;
+14:__UG_NAME__ -> 58:envelope___control___6 ;
+15:__UG_NAME__ -> 58:envelope___control___7 ;
+57:__UG_NAME__ -> 58:gate ;
+20:__UG_NAME__ -> 69:envelope___control___0 ;
+20:__UG_NAME__ -> 69:envelope___control___4 ;
+21:__UG_NAME__ -> 69:envelope___control___5 ;
+22:__UG_NAME__ -> 69:envelope___control___6 ;
+23:__UG_NAME__ -> 69:envelope___control___7 ;
+68:__UG_NAME__ -> 69:gate ;
+4:__UG_NAME__ -> 80:envelope___control___0 ;
+4:__UG_NAME__ -> 80:envelope___control___4 ;
+5:__UG_NAME__ -> 80:envelope___control___5 ;
+6:__UG_NAME__ -> 80:envelope___control___6 ;
+7:__UG_NAME__ -> 80:envelope___control___7 ;
+79:__UG_NAME__ -> 80:gate ;
+0:__UG_NAME__ -> 92:envelope___control___0 ;
+0:__UG_NAME__ -> 92:envelope___control___4 ;
+1:__UG_NAME__ -> 92:envelope___control___5 ;
+2:__UG_NAME__ -> 92:envelope___control___6 ;
+3:__UG_NAME__ -> 92:envelope___control___7 ;
+91:__UG_NAME__ -> 92:gate ;
+26:__UG_NAME__ -> 27:in ;
+17:__UG_NAME__ -> 32:in ;
+8:__UG_NAME__ -> 38:in ;
+9:__UG_NAME__ -> 42:in ;
+12:__UG_NAME__ -> 50:in ;
+13:__UG_NAME__ -> 54:in ;
+20:__UG_NAME__ -> 61:in ;
+21:__UG_NAME__ -> 65:in ;
+4:__UG_NAME__ -> 72:in ;
+5:__UG_NAME__ -> 76:in ;
+0:__UG_NAME__ -> 84:in ;
+1:__UG_NAME__ -> 88:in ;
+24:__UG_NAME__ -> 47:bus ;
+48:__UG_NAME__ -> 70:in ;
+59:__UG_NAME__ -> 70:freq ;
+36:__UG_NAME__ -> 70:rq ;
+69:__UG_NAME__ -> 70:db ;
+94:__UG_NAME__ -> 95:in ;
+59:__UG_NAME__ -> 95:freq ;
+36:__UG_NAME__ -> 95:rq ;
+69:__UG_NAME__ -> 95:db ;
+58:__UG_NAME__ -> 59:a ;
+16:__UG_NAME__ -> 26:in ;
+25:__UG_NAME__ -> 99:bus ;
+98:__UG_NAME__ -> 99:signals___x____fade2___0 ;
+93:__UG_NAME__ -> 99:signals___x____fade2___1 ;
+48:__UG_NAME__ -> 93:ina ;
+70:__UG_NAME__ -> 93:inb ;
+82:__UG_NAME__ -> 93:pan ;
+92:__UG_NAME__ -> 93:level ;
+94:__UG_NAME__ -> 98:ina ;
+95:__UG_NAME__ -> 98:inb ;
+97:__UG_NAME__ -> 98:pan ;
+92:__UG_NAME__ -> 98:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_bitcrusher.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_bitcrusher.dot
new file mode 100644
index 0000000..dab20ef
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_bitcrusher.dot
@@ -0,0 +1,294 @@
+digraph synthdef {
+71 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+96 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+100 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :sample_rate
+ default: 10000.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :sample_rate_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sample_rate_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :sample_rate_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :bits
+ default: 8.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :bits_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :bits_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :bits_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+90 [label = "{{ <bits> bits|<rate> rate|<in> in} |<__UG_NAME__>decimator }" style="filled, bold, rounded"  shape=record rankdir=LR];
+97 [label = "{{ <bits> bits|<rate> rate|<in> in} |<__UG_NAME__>decimator }" style="filled, bold, rounded"  shape=record rankdir=LR];
+35 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+92 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+98 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+93 [label = "{{ {{<array___decimator___0>|<array___lpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+99 [label = "{{ {{<array___decimator___0>|<array___lpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+95 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+102 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+70:__UG_NAME__ -> 71:a ;
+75:__UG_NAME__ -> 76:a ;
+74:__UG_NAME__ -> 76:b ;
+75:__UG_NAME__ -> 96:a ;
+74:__UG_NAME__ -> 96:b ;
+70:__UG_NAME__ -> 100:a ;
+26:__UG_NAME__ -> 30:a ;
+29:__UG_NAME__ -> 30:b ;
+30:__UG_NAME__ -> 34:a ;
+33:__UG_NAME__ -> 34:b ;
+42:__UG_NAME__ -> 46:a ;
+45:__UG_NAME__ -> 46:b ;
+46:__UG_NAME__ -> 51:a ;
+50:__UG_NAME__ -> 51:b ;
+55:__UG_NAME__ -> 56:a ;
+41:__UG_NAME__ -> 56:b ;
+56:__UG_NAME__ -> 60:a ;
+59:__UG_NAME__ -> 60:b ;
+47:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+65:__UG_NAME__ -> 69:a ;
+68:__UG_NAME__ -> 69:b ;
+38:__UG_NAME__ -> 80:a ;
+79:__UG_NAME__ -> 80:b ;
+80:__UG_NAME__ -> 81:a ;
+54:__UG_NAME__ -> 81:b ;
+61:__UG_NAME__ -> 86:a ;
+85:__UG_NAME__ -> 86:b ;
+86:__UG_NAME__ -> 89:a ;
+88:__UG_NAME__ -> 89:b ;
+71:__UG_NAME__ -> 72:a ;
+100:__UG_NAME__ -> 101:a ;
+28:__UG_NAME__ -> 29:a ;
+32:__UG_NAME__ -> 33:a ;
+35:__UG_NAME__ -> 36:a ;
+40:__UG_NAME__ -> 41:a ;
+44:__UG_NAME__ -> 45:a ;
+49:__UG_NAME__ -> 50:a ;
+53:__UG_NAME__ -> 54:a ;
+58:__UG_NAME__ -> 59:a ;
+63:__UG_NAME__ -> 64:a ;
+67:__UG_NAME__ -> 68:a ;
+78:__UG_NAME__ -> 79:a ;
+84:__UG_NAME__ -> 85:a ;
+87:__UG_NAME__ -> 88:a ;
+27:__UG_NAME__ -> 28:a ;
+31:__UG_NAME__ -> 32:a ;
+39:__UG_NAME__ -> 40:a ;
+43:__UG_NAME__ -> 44:a ;
+48:__UG_NAME__ -> 49:a ;
+52:__UG_NAME__ -> 53:a ;
+57:__UG_NAME__ -> 58:a ;
+62:__UG_NAME__ -> 63:a ;
+66:__UG_NAME__ -> 67:a ;
+77:__UG_NAME__ -> 78:a ;
+83:__UG_NAME__ -> 84:a ;
+37:__UG_NAME__ -> 87:a ;
+76:__UG_NAME__ -> 90:in ;
+82:__UG_NAME__ -> 90:rate ;
+73:__UG_NAME__ -> 90:bits ;
+96:__UG_NAME__ -> 97:in ;
+82:__UG_NAME__ -> 97:rate ;
+73:__UG_NAME__ -> 97:bits ;
+20:__UG_NAME__ -> 35:envelope___control___0 ;
+20:__UG_NAME__ -> 35:envelope___control___4 ;
+21:__UG_NAME__ -> 35:envelope___control___5 ;
+22:__UG_NAME__ -> 35:envelope___control___6 ;
+23:__UG_NAME__ -> 35:envelope___control___7 ;
+34:__UG_NAME__ -> 35:gate ;
+4:__UG_NAME__ -> 70:envelope___control___0 ;
+4:__UG_NAME__ -> 70:envelope___control___4 ;
+5:__UG_NAME__ -> 70:envelope___control___5 ;
+6:__UG_NAME__ -> 70:envelope___control___6 ;
+7:__UG_NAME__ -> 70:envelope___control___7 ;
+69:__UG_NAME__ -> 70:gate ;
+16:__UG_NAME__ -> 73:envelope___control___0 ;
+16:__UG_NAME__ -> 73:envelope___control___4 ;
+17:__UG_NAME__ -> 73:envelope___control___5 ;
+18:__UG_NAME__ -> 73:envelope___control___6 ;
+19:__UG_NAME__ -> 73:envelope___control___7 ;
+51:__UG_NAME__ -> 73:gate ;
+8:__UG_NAME__ -> 75:envelope___control___0 ;
+8:__UG_NAME__ -> 75:envelope___control___4 ;
+9:__UG_NAME__ -> 75:envelope___control___5 ;
+10:__UG_NAME__ -> 75:envelope___control___6 ;
+11:__UG_NAME__ -> 75:envelope___control___7 ;
+60:__UG_NAME__ -> 75:gate ;
+12:__UG_NAME__ -> 82:envelope___control___0 ;
+12:__UG_NAME__ -> 82:envelope___control___4 ;
+13:__UG_NAME__ -> 82:envelope___control___5 ;
+14:__UG_NAME__ -> 82:envelope___control___6 ;
+15:__UG_NAME__ -> 82:envelope___control___7 ;
+81:__UG_NAME__ -> 82:gate ;
+0:__UG_NAME__ -> 94:envelope___control___0 ;
+0:__UG_NAME__ -> 94:envelope___control___4 ;
+1:__UG_NAME__ -> 94:envelope___control___5 ;
+2:__UG_NAME__ -> 94:envelope___control___6 ;
+3:__UG_NAME__ -> 94:envelope___control___7 ;
+89:__UG_NAME__ -> 94:gate ;
+20:__UG_NAME__ -> 27:in ;
+21:__UG_NAME__ -> 31:in ;
+1:__UG_NAME__ -> 37:in ;
+8:__UG_NAME__ -> 39:in ;
+16:__UG_NAME__ -> 43:in ;
+17:__UG_NAME__ -> 48:in ;
+13:__UG_NAME__ -> 52:in ;
+9:__UG_NAME__ -> 57:in ;
+4:__UG_NAME__ -> 62:in ;
+5:__UG_NAME__ -> 66:in ;
+12:__UG_NAME__ -> 77:in ;
+0:__UG_NAME__ -> 83:in ;
+24:__UG_NAME__ -> 74:bus ;
+90:__UG_NAME__ -> 92:in ;
+91:__UG_NAME__ -> 92:freq ;
+97:__UG_NAME__ -> 98:in ;
+91:__UG_NAME__ -> 98:freq ;
+35:__UG_NAME__ -> 91:a ;
+25:__UG_NAME__ -> 103:bus ;
+102:__UG_NAME__ -> 103:signals___x____fade2___0 ;
+95:__UG_NAME__ -> 103:signals___x____fade2___1 ;
+36:__UG_NAME__ -> 93:which ;
+90:__UG_NAME__ -> 93:array___decimator___0 ;
+92:__UG_NAME__ -> 93:array___lpf___1 ;
+36:__UG_NAME__ -> 99:which ;
+97:__UG_NAME__ -> 99:array___decimator___0 ;
+98:__UG_NAME__ -> 99:array___lpf___1 ;
+76:__UG_NAME__ -> 95:ina ;
+93:__UG_NAME__ -> 95:inb ;
+72:__UG_NAME__ -> 95:pan ;
+94:__UG_NAME__ -> 95:level ;
+96:__UG_NAME__ -> 102:ina ;
+99:__UG_NAME__ -> 102:inb ;
+101:__UG_NAME__ -> 102:pan ;
+94:__UG_NAME__ -> 102:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_bpf.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_bpf.dot
new file mode 100644
index 0000000..23f970d
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_bpf.dot
@@ -0,0 +1,242 @@
+digraph synthdef {
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+67 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+82 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+81 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :centre
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :centre_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :centre_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :centre_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :res
+ default: 0.6" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+79 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+84 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+31:__UG_NAME__ -> 33:a ;
+32:__UG_NAME__ -> 33:b ;
+66:__UG_NAME__ -> 67:a ;
+31:__UG_NAME__ -> 80:a ;
+32:__UG_NAME__ -> 80:b ;
+66:__UG_NAME__ -> 82:a ;
+22:__UG_NAME__ -> 26:a ;
+25:__UG_NAME__ -> 26:b ;
+26:__UG_NAME__ -> 30:a ;
+29:__UG_NAME__ -> 30:b ;
+34:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+38:__UG_NAME__ -> 42:a ;
+41:__UG_NAME__ -> 42:b ;
+45:__UG_NAME__ -> 50:a ;
+49:__UG_NAME__ -> 50:b ;
+50:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+57:__UG_NAME__ -> 61:a ;
+60:__UG_NAME__ -> 61:b ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+69:__UG_NAME__ -> 73:a ;
+72:__UG_NAME__ -> 73:b ;
+73:__UG_NAME__ -> 77:a ;
+76:__UG_NAME__ -> 77:b ;
+67:__UG_NAME__ -> 68:a ;
+82:__UG_NAME__ -> 83:a ;
+24:__UG_NAME__ -> 25:a ;
+28:__UG_NAME__ -> 29:a ;
+36:__UG_NAME__ -> 37:a ;
+40:__UG_NAME__ -> 41:a ;
+48:__UG_NAME__ -> 49:a ;
+52:__UG_NAME__ -> 53:a ;
+59:__UG_NAME__ -> 60:a ;
+63:__UG_NAME__ -> 64:a ;
+71:__UG_NAME__ -> 72:a ;
+75:__UG_NAME__ -> 76:a ;
+23:__UG_NAME__ -> 24:a ;
+27:__UG_NAME__ -> 28:a ;
+35:__UG_NAME__ -> 36:a ;
+39:__UG_NAME__ -> 40:a ;
+47:__UG_NAME__ -> 48:a ;
+51:__UG_NAME__ -> 52:a ;
+58:__UG_NAME__ -> 59:a ;
+62:__UG_NAME__ -> 63:a ;
+70:__UG_NAME__ -> 71:a ;
+74:__UG_NAME__ -> 75:a ;
+33:__UG_NAME__ -> 56:in ;
+44:__UG_NAME__ -> 56:freq ;
+55:__UG_NAME__ -> 56:rq ;
+80:__UG_NAME__ -> 81:in ;
+44:__UG_NAME__ -> 81:freq ;
+55:__UG_NAME__ -> 81:rq ;
+8:__UG_NAME__ -> 31:envelope___control___0 ;
+8:__UG_NAME__ -> 31:envelope___control___4 ;
+9:__UG_NAME__ -> 31:envelope___control___5 ;
+10:__UG_NAME__ -> 31:envelope___control___6 ;
+11:__UG_NAME__ -> 31:envelope___control___7 ;
+30:__UG_NAME__ -> 31:gate ;
+12:__UG_NAME__ -> 43:envelope___control___0 ;
+12:__UG_NAME__ -> 43:envelope___control___4 ;
+13:__UG_NAME__ -> 43:envelope___control___5 ;
+14:__UG_NAME__ -> 43:envelope___control___6 ;
+15:__UG_NAME__ -> 43:envelope___control___7 ;
+42:__UG_NAME__ -> 43:gate ;
+46:__UG_NAME__ -> 55:envelope___mul____add___0 ;
+46:__UG_NAME__ -> 55:envelope___mul____add___4 ;
+17:__UG_NAME__ -> 55:envelope___control___5 ;
+18:__UG_NAME__ -> 55:envelope___control___6 ;
+19:__UG_NAME__ -> 55:envelope___control___7 ;
+54:__UG_NAME__ -> 55:gate ;
+4:__UG_NAME__ -> 66:envelope___control___0 ;
+4:__UG_NAME__ -> 66:envelope___control___4 ;
+5:__UG_NAME__ -> 66:envelope___control___5 ;
+6:__UG_NAME__ -> 66:envelope___control___6 ;
+7:__UG_NAME__ -> 66:envelope___control___7 ;
+65:__UG_NAME__ -> 66:gate ;
+0:__UG_NAME__ -> 78:envelope___control___0 ;
+0:__UG_NAME__ -> 78:envelope___control___4 ;
+1:__UG_NAME__ -> 78:envelope___control___5 ;
+2:__UG_NAME__ -> 78:envelope___control___6 ;
+3:__UG_NAME__ -> 78:envelope___control___7 ;
+77:__UG_NAME__ -> 78:gate ;
+8:__UG_NAME__ -> 23:in ;
+9:__UG_NAME__ -> 27:in ;
+12:__UG_NAME__ -> 35:in ;
+13:__UG_NAME__ -> 39:in ;
+46:__UG_NAME__ -> 47:in ;
+17:__UG_NAME__ -> 51:in ;
+4:__UG_NAME__ -> 58:in ;
+5:__UG_NAME__ -> 62:in ;
+0:__UG_NAME__ -> 70:in ;
+1:__UG_NAME__ -> 74:in ;
+20:__UG_NAME__ -> 32:bus ;
+43:__UG_NAME__ -> 44:a ;
+16:__UG_NAME__ -> 46:in ;
+21:__UG_NAME__ -> 85:bus ;
+79:__UG_NAME__ -> 85:signals___x____fade2___0 ;
+84:__UG_NAME__ -> 85:signals___x____fade2___1 ;
+33:__UG_NAME__ -> 79:ina ;
+56:__UG_NAME__ -> 79:inb ;
+68:__UG_NAME__ -> 79:pan ;
+78:__UG_NAME__ -> 79:level ;
+80:__UG_NAME__ -> 84:ina ;
+81:__UG_NAME__ -> 84:inb ;
+83:__UG_NAME__ -> 84:pan ;
+78:__UG_NAME__ -> 84:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_compressor.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_compressor.dot
new file mode 100644
index 0000000..8b42bb7
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_compressor.dot
@@ -0,0 +1,365 @@
+digraph synthdef {
+83 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+98 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+123 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+116 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <relax____time> relax-time|<clamp____time> clamp-time|<slope____above> slope-above|<slope____below> slope-below|<thresh> thresh|<control> control|<in> in} |<__UG_NAME__>compander }" style="filled, bold, rounded"  shape=record rankdir=LR];
+125 [label = "{{ <relax____time> relax-time|<clamp____time> clamp-time|<slope____above> slope-above|<slope____below> slope-below|<thresh> thresh|<control> control|<in> in} |<__UG_NAME__>compander }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :threshold
+ default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :threshold_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :threshold_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :threshold_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :clamp_time
+ default: 0.01" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :clamp_time_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :clamp_time_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :clamp_time_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :slope_above
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :slope_above_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :slope_above_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :slope_above_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :slope_below
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :slope_below_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :slope_below_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :slope_below_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :relax_time
+ default: 0.01" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :relax_time_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :relax_time_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :relax_time_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+127 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+122 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+126 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+81:__UG_NAME__ -> 83:a ;
+82:__UG_NAME__ -> 83:b ;
+97:__UG_NAME__ -> 98:a ;
+81:__UG_NAME__ -> 108:a ;
+82:__UG_NAME__ -> 108:b ;
+97:__UG_NAME__ -> 123:a ;
+34:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+38:__UG_NAME__ -> 42:a ;
+41:__UG_NAME__ -> 42:b ;
+45:__UG_NAME__ -> 49:a ;
+48:__UG_NAME__ -> 49:b ;
+49:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+60:__UG_NAME__ -> 64:a ;
+63:__UG_NAME__ -> 64:b ;
+64:__UG_NAME__ -> 68:a ;
+67:__UG_NAME__ -> 68:b ;
+70:__UG_NAME__ -> 74:a ;
+73:__UG_NAME__ -> 74:b ;
+75:__UG_NAME__ -> 79:a ;
+78:__UG_NAME__ -> 79:b ;
+79:__UG_NAME__ -> 80:a ;
+56:__UG_NAME__ -> 80:b ;
+85:__UG_NAME__ -> 89:a ;
+88:__UG_NAME__ -> 89:b ;
+89:__UG_NAME__ -> 92:a ;
+91:__UG_NAME__ -> 92:b ;
+74:__UG_NAME__ -> 96:a ;
+95:__UG_NAME__ -> 96:b ;
+44:__UG_NAME__ -> 103:a ;
+102:__UG_NAME__ -> 103:b ;
+103:__UG_NAME__ -> 104:a ;
+59:__UG_NAME__ -> 104:b ;
+108:__UG_NAME__ -> 109:a ;
+83:__UG_NAME__ -> 109:b ;
+113:__UG_NAME__ -> 116:a ;
+115:__UG_NAME__ -> 116:b ;
+116:__UG_NAME__ -> 118:a ;
+117:__UG_NAME__ -> 118:b ;
+98:__UG_NAME__ -> 99:a ;
+123:__UG_NAME__ -> 124:a ;
+109:__UG_NAME__ -> 111:a ;
+36:__UG_NAME__ -> 37:a ;
+40:__UG_NAME__ -> 41:a ;
+47:__UG_NAME__ -> 48:a ;
+51:__UG_NAME__ -> 52:a ;
+55:__UG_NAME__ -> 56:a ;
+58:__UG_NAME__ -> 59:a ;
+62:__UG_NAME__ -> 63:a ;
+66:__UG_NAME__ -> 67:a ;
+72:__UG_NAME__ -> 73:a ;
+77:__UG_NAME__ -> 78:a ;
+87:__UG_NAME__ -> 88:a ;
+90:__UG_NAME__ -> 91:a ;
+94:__UG_NAME__ -> 95:a ;
+101:__UG_NAME__ -> 102:a ;
+114:__UG_NAME__ -> 115:a ;
+107:__UG_NAME__ -> 117:a ;
+35:__UG_NAME__ -> 36:a ;
+39:__UG_NAME__ -> 40:a ;
+46:__UG_NAME__ -> 47:a ;
+50:__UG_NAME__ -> 51:a ;
+54:__UG_NAME__ -> 55:a ;
+57:__UG_NAME__ -> 58:a ;
+61:__UG_NAME__ -> 62:a ;
+65:__UG_NAME__ -> 66:a ;
+71:__UG_NAME__ -> 72:a ;
+76:__UG_NAME__ -> 77:a ;
+86:__UG_NAME__ -> 87:a ;
+84:__UG_NAME__ -> 90:a ;
+93:__UG_NAME__ -> 94:a ;
+100:__UG_NAME__ -> 101:a ;
+106:__UG_NAME__ -> 107:a ;
+110:__UG_NAME__ -> 114:a ;
+108:__UG_NAME__ -> 120:in ;
+111:__UG_NAME__ -> 120:control ;
+69:__UG_NAME__ -> 120:thresh ;
+112:__UG_NAME__ -> 120:slope____below ;
+43:__UG_NAME__ -> 120:slope____above ;
+119:__UG_NAME__ -> 120:clamp____time ;
+105:__UG_NAME__ -> 120:relax____time ;
+83:__UG_NAME__ -> 125:in ;
+111:__UG_NAME__ -> 125:control ;
+69:__UG_NAME__ -> 125:thresh ;
+112:__UG_NAME__ -> 125:slope____below ;
+43:__UG_NAME__ -> 125:slope____above ;
+119:__UG_NAME__ -> 125:clamp____time ;
+105:__UG_NAME__ -> 125:relax____time ;
+20:__UG_NAME__ -> 43:envelope___control___0 ;
+20:__UG_NAME__ -> 43:envelope___control___4 ;
+21:__UG_NAME__ -> 43:envelope___control___5 ;
+22:__UG_NAME__ -> 43:envelope___control___6 ;
+23:__UG_NAME__ -> 43:envelope___control___7 ;
+42:__UG_NAME__ -> 43:gate ;
+12:__UG_NAME__ -> 69:envelope___control___0 ;
+12:__UG_NAME__ -> 69:envelope___control___4 ;
+13:__UG_NAME__ -> 69:envelope___control___5 ;
+14:__UG_NAME__ -> 69:envelope___control___6 ;
+15:__UG_NAME__ -> 69:envelope___control___7 ;
+68:__UG_NAME__ -> 69:gate ;
+8:__UG_NAME__ -> 81:envelope___control___0 ;
+8:__UG_NAME__ -> 81:envelope___control___4 ;
+9:__UG_NAME__ -> 81:envelope___control___5 ;
+10:__UG_NAME__ -> 81:envelope___control___6 ;
+11:__UG_NAME__ -> 81:envelope___control___7 ;
+80:__UG_NAME__ -> 81:gate ;
+4:__UG_NAME__ -> 97:envelope___control___0 ;
+4:__UG_NAME__ -> 97:envelope___control___4 ;
+5:__UG_NAME__ -> 97:envelope___control___5 ;
+6:__UG_NAME__ -> 97:envelope___control___6 ;
+7:__UG_NAME__ -> 97:envelope___control___7 ;
+96:__UG_NAME__ -> 97:gate ;
+28:__UG_NAME__ -> 105:envelope___control___0 ;
+28:__UG_NAME__ -> 105:envelope___control___4 ;
+29:__UG_NAME__ -> 105:envelope___control___5 ;
+30:__UG_NAME__ -> 105:envelope___control___6 ;
+31:__UG_NAME__ -> 105:envelope___control___7 ;
+104:__UG_NAME__ -> 105:gate ;
+24:__UG_NAME__ -> 112:envelope___control___0 ;
+24:__UG_NAME__ -> 112:envelope___control___4 ;
+25:__UG_NAME__ -> 112:envelope___control___5 ;
+26:__UG_NAME__ -> 112:envelope___control___6 ;
+27:__UG_NAME__ -> 112:envelope___control___7 ;
+53:__UG_NAME__ -> 112:gate ;
+16:__UG_NAME__ -> 119:envelope___control___0 ;
+16:__UG_NAME__ -> 119:envelope___control___4 ;
+17:__UG_NAME__ -> 119:envelope___control___5 ;
+18:__UG_NAME__ -> 119:envelope___control___6 ;
+19:__UG_NAME__ -> 119:envelope___control___7 ;
+118:__UG_NAME__ -> 119:gate ;
+0:__UG_NAME__ -> 121:envelope___control___0 ;
+0:__UG_NAME__ -> 121:envelope___control___4 ;
+1:__UG_NAME__ -> 121:envelope___control___5 ;
+2:__UG_NAME__ -> 121:envelope___control___6 ;
+3:__UG_NAME__ -> 121:envelope___control___7 ;
+92:__UG_NAME__ -> 121:gate ;
+20:__UG_NAME__ -> 35:in ;
+21:__UG_NAME__ -> 39:in ;
+24:__UG_NAME__ -> 46:in ;
+25:__UG_NAME__ -> 50:in ;
+9:__UG_NAME__ -> 54:in ;
+29:__UG_NAME__ -> 57:in ;
+12:__UG_NAME__ -> 61:in ;
+13:__UG_NAME__ -> 65:in ;
+4:__UG_NAME__ -> 71:in ;
+8:__UG_NAME__ -> 76:in ;
+1:__UG_NAME__ -> 84:in ;
+0:__UG_NAME__ -> 86:in ;
+5:__UG_NAME__ -> 93:in ;
+28:__UG_NAME__ -> 100:in ;
+17:__UG_NAME__ -> 106:in ;
+16:__UG_NAME__ -> 110:in ;
+32:__UG_NAME__ -> 82:bus ;
+33:__UG_NAME__ -> 127:bus ;
+122:__UG_NAME__ -> 127:signals___x____fade2___0 ;
+126:__UG_NAME__ -> 127:signals___x____fade2___1 ;
+82:__UG_NAME__ -> 122:ina ;
+120:__UG_NAME__ -> 122:inb ;
+99:__UG_NAME__ -> 122:pan ;
+121:__UG_NAME__ -> 122:level ;
+82:__UG_NAME__ -> 126:ina ;
+125:__UG_NAME__ -> 126:inb ;
+124:__UG_NAME__ -> 126:pan ;
+121:__UG_NAME__ -> 126:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_distortion.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_distortion.dot
new file mode 100644
index 0000000..0c27277
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_distortion.dot
@@ -0,0 +1,227 @@
+digraph synthdef {
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+67 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+23 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :distort
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :distort_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :distort_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :distort_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+18 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+19 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+21 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+20 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+81 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+77 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+80 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+29:__UG_NAME__ -> 31:a ;
+30:__UG_NAME__ -> 31:b ;
+40:__UG_NAME__ -> 41:b ;
+31:__UG_NAME__ -> 45:a ;
+44:__UG_NAME__ -> 45:b ;
+43:__UG_NAME__ -> 47:a ;
+46:__UG_NAME__ -> 47:b ;
+29:__UG_NAME__ -> 52:a ;
+30:__UG_NAME__ -> 52:b ;
+52:__UG_NAME__ -> 53:a ;
+44:__UG_NAME__ -> 53:b ;
+43:__UG_NAME__ -> 55:a ;
+54:__UG_NAME__ -> 55:b ;
+66:__UG_NAME__ -> 67:a ;
+66:__UG_NAME__ -> 78:a ;
+20:__UG_NAME__ -> 24:a ;
+23:__UG_NAME__ -> 24:b ;
+24:__UG_NAME__ -> 28:a ;
+27:__UG_NAME__ -> 28:b ;
+32:__UG_NAME__ -> 35:a ;
+34:__UG_NAME__ -> 35:b ;
+35:__UG_NAME__ -> 39:a ;
+38:__UG_NAME__ -> 39:b ;
+43:__UG_NAME__ -> 44:b ;
+47:__UG_NAME__ -> 48:b ;
+55:__UG_NAME__ -> 56:b ;
+58:__UG_NAME__ -> 62:a ;
+61:__UG_NAME__ -> 62:b ;
+62:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+69:__UG_NAME__ -> 73:a ;
+72:__UG_NAME__ -> 73:b ;
+73:__UG_NAME__ -> 75:a ;
+74:__UG_NAME__ -> 75:b ;
+40:__UG_NAME__ -> 42:b ;
+67:__UG_NAME__ -> 68:a ;
+78:__UG_NAME__ -> 79:a ;
+41:__UG_NAME__ -> 43:a ;
+42:__UG_NAME__ -> 43:b ;
+45:__UG_NAME__ -> 49:a ;
+48:__UG_NAME__ -> 49:b ;
+53:__UG_NAME__ -> 57:a ;
+56:__UG_NAME__ -> 57:b ;
+22:__UG_NAME__ -> 23:a ;
+26:__UG_NAME__ -> 27:a ;
+33:__UG_NAME__ -> 34:a ;
+37:__UG_NAME__ -> 38:a ;
+60:__UG_NAME__ -> 61:a ;
+63:__UG_NAME__ -> 64:a ;
+71:__UG_NAME__ -> 72:a ;
+51:__UG_NAME__ -> 74:a ;
+21:__UG_NAME__ -> 22:a ;
+25:__UG_NAME__ -> 26:a ;
+18:__UG_NAME__ -> 33:a ;
+36:__UG_NAME__ -> 37:a ;
+31:__UG_NAME__ -> 46:a ;
+50:__UG_NAME__ -> 51:a ;
+52:__UG_NAME__ -> 54:a ;
+59:__UG_NAME__ -> 60:a ;
+19:__UG_NAME__ -> 63:a ;
+70:__UG_NAME__ -> 71:a ;
+8:__UG_NAME__ -> 29:envelope___control___0 ;
+8:__UG_NAME__ -> 29:envelope___control___4 ;
+9:__UG_NAME__ -> 29:envelope___control___5 ;
+10:__UG_NAME__ -> 29:envelope___control___6 ;
+11:__UG_NAME__ -> 29:envelope___control___7 ;
+28:__UG_NAME__ -> 29:gate ;
+12:__UG_NAME__ -> 40:envelope___control___0 ;
+12:__UG_NAME__ -> 40:envelope___control___4 ;
+13:__UG_NAME__ -> 40:envelope___control___5 ;
+14:__UG_NAME__ -> 40:envelope___control___6 ;
+15:__UG_NAME__ -> 40:envelope___control___7 ;
+39:__UG_NAME__ -> 40:gate ;
+4:__UG_NAME__ -> 66:envelope___control___0 ;
+4:__UG_NAME__ -> 66:envelope___control___4 ;
+5:__UG_NAME__ -> 66:envelope___control___5 ;
+6:__UG_NAME__ -> 66:envelope___control___6 ;
+7:__UG_NAME__ -> 66:envelope___control___7 ;
+65:__UG_NAME__ -> 66:gate ;
+0:__UG_NAME__ -> 76:envelope___control___0 ;
+0:__UG_NAME__ -> 76:envelope___control___4 ;
+1:__UG_NAME__ -> 76:envelope___control___5 ;
+2:__UG_NAME__ -> 76:envelope___control___6 ;
+3:__UG_NAME__ -> 76:envelope___control___7 ;
+75:__UG_NAME__ -> 76:gate ;
+12:__UG_NAME__ -> 18:in ;
+5:__UG_NAME__ -> 19:in ;
+8:__UG_NAME__ -> 21:in ;
+9:__UG_NAME__ -> 25:in ;
+13:__UG_NAME__ -> 36:in ;
+1:__UG_NAME__ -> 50:in ;
+4:__UG_NAME__ -> 59:in ;
+0:__UG_NAME__ -> 70:in ;
+16:__UG_NAME__ -> 30:bus ;
+17:__UG_NAME__ -> 81:bus ;
+77:__UG_NAME__ -> 81:signals___x____fade2___0 ;
+80:__UG_NAME__ -> 81:signals___x____fade2___1 ;
+52:__UG_NAME__ -> 77:ina ;
+57:__UG_NAME__ -> 77:inb ;
+68:__UG_NAME__ -> 77:pan ;
+76:__UG_NAME__ -> 77:level ;
+31:__UG_NAME__ -> 80:ina ;
+49:__UG_NAME__ -> 80:inb ;
+79:__UG_NAME__ -> 80:pan ;
+76:__UG_NAME__ -> 80:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_echo.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_echo.dot
new file mode 100644
index 0000000..1ee738d
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_echo.dot
@@ -0,0 +1,249 @@
+digraph synthdef {
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+73 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+74 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <decay____time> decay-time|<delay____time> delay-time|<max____delay____time> max-delay-time|<in> in} |<__UG_NAME__>comb-n }" style="filled, bold, rounded"  shape=record rankdir=LR];
+81 [label = "{{ <decay____time> decay-time|<delay____time> delay-time|<max____delay____time> max-delay-time|<in> in} |<__UG_NAME__>comb-n }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :phase
+ default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :phase_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :phase_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :phase_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :decay
+ default: 2.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :decay_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :decay_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :max_phase
+ default: 2.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+86 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+80 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+85 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+32:__UG_NAME__ -> 34:a ;
+33:__UG_NAME__ -> 34:b ;
+32:__UG_NAME__ -> 49:a ;
+33:__UG_NAME__ -> 49:b ;
+72:__UG_NAME__ -> 73:a ;
+72:__UG_NAME__ -> 83:a ;
+26:__UG_NAME__ -> 27:a ;
+25:__UG_NAME__ -> 27:b ;
+27:__UG_NAME__ -> 31:a ;
+30:__UG_NAME__ -> 31:b ;
+35:__UG_NAME__ -> 39:a ;
+38:__UG_NAME__ -> 39:b ;
+43:__UG_NAME__ -> 47:a ;
+46:__UG_NAME__ -> 47:b ;
+47:__UG_NAME__ -> 48:a ;
+42:__UG_NAME__ -> 48:b ;
+51:__UG_NAME__ -> 55:a ;
+54:__UG_NAME__ -> 55:b ;
+55:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+49:__UG_NAME__ -> 62:a ;
+61:__UG_NAME__ -> 62:b ;
+63:__UG_NAME__ -> 67:a ;
+66:__UG_NAME__ -> 67:b ;
+67:__UG_NAME__ -> 71:a ;
+70:__UG_NAME__ -> 71:b ;
+39:__UG_NAME__ -> 78:a ;
+77:__UG_NAME__ -> 78:b ;
+34:__UG_NAME__ -> 82:a ;
+81:__UG_NAME__ -> 82:b ;
+73:__UG_NAME__ -> 74:a ;
+83:__UG_NAME__ -> 84:a ;
+24:__UG_NAME__ -> 25:a ;
+29:__UG_NAME__ -> 30:a ;
+37:__UG_NAME__ -> 38:a ;
+41:__UG_NAME__ -> 42:a ;
+45:__UG_NAME__ -> 46:a ;
+53:__UG_NAME__ -> 54:a ;
+57:__UG_NAME__ -> 58:a ;
+65:__UG_NAME__ -> 66:a ;
+69:__UG_NAME__ -> 70:a ;
+76:__UG_NAME__ -> 77:a ;
+23:__UG_NAME__ -> 24:a ;
+28:__UG_NAME__ -> 29:a ;
+36:__UG_NAME__ -> 37:a ;
+40:__UG_NAME__ -> 41:a ;
+44:__UG_NAME__ -> 45:a ;
+52:__UG_NAME__ -> 53:a ;
+56:__UG_NAME__ -> 57:a ;
+64:__UG_NAME__ -> 65:a ;
+68:__UG_NAME__ -> 69:a ;
+75:__UG_NAME__ -> 76:a ;
+49:__UG_NAME__ -> 61:in ;
+20:__UG_NAME__ -> 61:max____delay____time ;
+50:__UG_NAME__ -> 61:delay____time ;
+60:__UG_NAME__ -> 61:decay____time ;
+34:__UG_NAME__ -> 81:in ;
+20:__UG_NAME__ -> 81:max____delay____time ;
+50:__UG_NAME__ -> 81:delay____time ;
+60:__UG_NAME__ -> 81:decay____time ;
+8:__UG_NAME__ -> 32:envelope___control___0 ;
+8:__UG_NAME__ -> 32:envelope___control___4 ;
+9:__UG_NAME__ -> 32:envelope___control___5 ;
+10:__UG_NAME__ -> 32:envelope___control___6 ;
+11:__UG_NAME__ -> 32:envelope___control___7 ;
+31:__UG_NAME__ -> 32:gate ;
+12:__UG_NAME__ -> 50:envelope___control___0 ;
+12:__UG_NAME__ -> 50:envelope___control___4 ;
+13:__UG_NAME__ -> 50:envelope___control___5 ;
+14:__UG_NAME__ -> 50:envelope___control___6 ;
+15:__UG_NAME__ -> 50:envelope___control___7 ;
+48:__UG_NAME__ -> 50:gate ;
+16:__UG_NAME__ -> 60:envelope___control___0 ;
+16:__UG_NAME__ -> 60:envelope___control___4 ;
+17:__UG_NAME__ -> 60:envelope___control___5 ;
+18:__UG_NAME__ -> 60:envelope___control___6 ;
+19:__UG_NAME__ -> 60:envelope___control___7 ;
+59:__UG_NAME__ -> 60:gate ;
+4:__UG_NAME__ -> 72:envelope___control___0 ;
+4:__UG_NAME__ -> 72:envelope___control___4 ;
+5:__UG_NAME__ -> 72:envelope___control___5 ;
+6:__UG_NAME__ -> 72:envelope___control___6 ;
+7:__UG_NAME__ -> 72:envelope___control___7 ;
+71:__UG_NAME__ -> 72:gate ;
+0:__UG_NAME__ -> 79:envelope___control___0 ;
+0:__UG_NAME__ -> 79:envelope___control___4 ;
+1:__UG_NAME__ -> 79:envelope___control___5 ;
+2:__UG_NAME__ -> 79:envelope___control___6 ;
+3:__UG_NAME__ -> 79:envelope___control___7 ;
+78:__UG_NAME__ -> 79:gate ;
+8:__UG_NAME__ -> 23:in ;
+9:__UG_NAME__ -> 28:in ;
+0:__UG_NAME__ -> 36:in ;
+13:__UG_NAME__ -> 40:in ;
+12:__UG_NAME__ -> 44:in ;
+16:__UG_NAME__ -> 52:in ;
+17:__UG_NAME__ -> 56:in ;
+4:__UG_NAME__ -> 64:in ;
+5:__UG_NAME__ -> 68:in ;
+1:__UG_NAME__ -> 75:in ;
+21:__UG_NAME__ -> 33:bus ;
+22:__UG_NAME__ -> 86:bus ;
+80:__UG_NAME__ -> 86:signals___x____fade2___0 ;
+85:__UG_NAME__ -> 86:signals___x____fade2___1 ;
+49:__UG_NAME__ -> 80:ina ;
+62:__UG_NAME__ -> 80:inb ;
+74:__UG_NAME__ -> 80:pan ;
+79:__UG_NAME__ -> 80:level ;
+34:__UG_NAME__ -> 85:ina ;
+82:__UG_NAME__ -> 85:inb ;
+84:__UG_NAME__ -> 85:pan ;
+79:__UG_NAME__ -> 85:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_flanger.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_flanger.dot
new file mode 100644
index 0000000..29ef80c
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_flanger.dot
@@ -0,0 +1,547 @@
+digraph synthdef {
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> -2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+74 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+88 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <b> 6.2831855|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+154 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+156 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+159 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+160 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+181 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+182 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+188 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> 0.5|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+146 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+150 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+155 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+161 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+175 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+179 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+186 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+189 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+192 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+158 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+183 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+194 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> 1000.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <b> 1000.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ <b> 1000.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+152 [label = "{{ <b> 1000.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+162 [label = "{{ <b> 1000.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+163 [label = "{{ <b> 1000.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+164 [label = "{{ <b> 1000.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+167 [label = "{{ <b> 1000.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+198 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+145 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+149 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+174 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+178 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+185 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+191 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+148 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+170 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+173 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+177 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+190 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+153 [label = "{{ <decay____time> decay-time|<delay____time> delay-time|<max____delay____time> max-delay-time|<in> in} |<__UG_NAME__>allpass-c }" style="filled, bold, rounded"  shape=record rankdir=LR];
+168 [label = "{{ <decay____time> decay-time|<delay____time> delay-time|<max____delay____time> max-delay-time|<in> in} |<__UG_NAME__>allpass-c }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :phase
+ default: 4.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :phase_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :phase_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :phase_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :phase_offset
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :wave
+ default: 4.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :invert_wave
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :stereo_invert_wave
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :delay
+ default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :delay_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :delay_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :delay_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :max_delay
+ default: 20.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :depth
+ default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :depth_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :depth_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :depth_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :feedback
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :feedback_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :feedback_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :feedback_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "control
+ :decay
+ default: 2.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "control
+ :decay_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "control
+ :decay_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+40 [label = "control
+ :decay_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+41 [label = "control
+ :invert_flange
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+42 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+54 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+151 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+180 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+193 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+134 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+143 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+147 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+169 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+172 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+176 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+187 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+171 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+184 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+111 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-cub }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <width> width|<iphase> iphase|<freq> freq} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>limiter }" style="filled, bold, rounded"  shape=record rankdir=LR];
+157 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>limiter }" style="filled, bold, rounded"  shape=record rankdir=LR];
+60 [label = "{{ <num____channels> num-channels 2} |<__UG_NAME__>local-in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+199 [label = "{{ {{<channels____array___binary____op____u____gen___0>|<channels____array___binary____op____u____gen___1>}|channels-array}} |<__UG_NAME__>local-out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+141 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>max }" style="bold, rounded" shape=record rankdir=LR];
+166 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>max }" style="bold, rounded" shape=record rankdir=LR];
+140 [label = "{{ <add> add|<mul> mul|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+165 [label = "{{ <add> add|<mul> mul|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+197 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+112 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>|<array___lf____cub___4>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ {{<array___select___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase|<freq> freq} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+195 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+196 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+54:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+57:__UG_NAME__ -> 58:b ;
+60:__UG_NAME__ -> 71:a ;
+70:__UG_NAME__ -> 71:b ;
+73:__UG_NAME__ -> 74:a ;
+56:__UG_NAME__ -> 74:b ;
+16:__UG_NAME__ -> 88:b ;
+90:__UG_NAME__ -> 91:b ;
+102:__UG_NAME__ -> 103:b ;
+107:__UG_NAME__ -> 108:a ;
+59:__UG_NAME__ -> 154:a ;
+153:__UG_NAME__ -> 154:b ;
+60:__UG_NAME__ -> 156:a ;
+70:__UG_NAME__ -> 156:b ;
+54:__UG_NAME__ -> 159:a ;
+55:__UG_NAME__ -> 159:b ;
+158:__UG_NAME__ -> 160:a ;
+159:__UG_NAME__ -> 160:b ;
+180:__UG_NAME__ -> 181:a ;
+180:__UG_NAME__ -> 182:a ;
+59:__UG_NAME__ -> 188:a ;
+168:__UG_NAME__ -> 188:b ;
+45:__UG_NAME__ -> 49:a ;
+48:__UG_NAME__ -> 49:b ;
+49:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+58:__UG_NAME__ -> 59:a ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+65:__UG_NAME__ -> 69:a ;
+68:__UG_NAME__ -> 69:b ;
+72:__UG_NAME__ -> 75:a ;
+74:__UG_NAME__ -> 75:b ;
+77:__UG_NAME__ -> 81:a ;
+80:__UG_NAME__ -> 81:b ;
+81:__UG_NAME__ -> 85:a ;
+84:__UG_NAME__ -> 85:b ;
+88:__UG_NAME__ -> 89:a ;
+92:__UG_NAME__ -> 96:a ;
+95:__UG_NAME__ -> 96:b ;
+96:__UG_NAME__ -> 100:a ;
+99:__UG_NAME__ -> 100:b ;
+88:__UG_NAME__ -> 105:a ;
+16:__UG_NAME__ -> 107:a ;
+16:__UG_NAME__ -> 110:a ;
+112:__UG_NAME__ -> 113:a ;
+119:__UG_NAME__ -> 123:a ;
+122:__UG_NAME__ -> 123:b ;
+123:__UG_NAME__ -> 126:a ;
+125:__UG_NAME__ -> 126:b ;
+129:__UG_NAME__ -> 133:a ;
+132:__UG_NAME__ -> 133:b ;
+133:__UG_NAME__ -> 137:a ;
+136:__UG_NAME__ -> 137:b ;
+142:__UG_NAME__ -> 146:a ;
+145:__UG_NAME__ -> 146:b ;
+146:__UG_NAME__ -> 150:a ;
+149:__UG_NAME__ -> 150:b ;
+56:__UG_NAME__ -> 155:a ;
+154:__UG_NAME__ -> 155:b ;
+157:__UG_NAME__ -> 161:a ;
+160:__UG_NAME__ -> 161:b ;
+171:__UG_NAME__ -> 175:a ;
+174:__UG_NAME__ -> 175:b ;
+175:__UG_NAME__ -> 179:a ;
+178:__UG_NAME__ -> 179:b ;
+184:__UG_NAME__ -> 186:a ;
+185:__UG_NAME__ -> 186:b ;
+159:__UG_NAME__ -> 189:a ;
+188:__UG_NAME__ -> 189:b ;
+186:__UG_NAME__ -> 192:a ;
+191:__UG_NAME__ -> 192:b ;
+70:__UG_NAME__ -> 73:b ;
+103:__UG_NAME__ -> 104:a ;
+114:__UG_NAME__ -> 115:b ;
+116:__UG_NAME__ -> 117:b ;
+70:__UG_NAME__ -> 158:b ;
+182:__UG_NAME__ -> 183:a ;
+181:__UG_NAME__ -> 194:a ;
+28:__UG_NAME__ -> 76:a ;
+86:__UG_NAME__ -> 87:b ;
+113:__UG_NAME__ -> 114:a ;
+127:__UG_NAME__ -> 128:a ;
+138:__UG_NAME__ -> 139:a ;
+151:__UG_NAME__ -> 152:a ;
+28:__UG_NAME__ -> 162:a ;
+127:__UG_NAME__ -> 163:a ;
+138:__UG_NAME__ -> 164:a ;
+151:__UG_NAME__ -> 167:a ;
+86:__UG_NAME__ -> 198:b ;
+47:__UG_NAME__ -> 48:a ;
+51:__UG_NAME__ -> 52:a ;
+41:__UG_NAME__ -> 57:a ;
+63:__UG_NAME__ -> 64:a ;
+67:__UG_NAME__ -> 68:a ;
+79:__UG_NAME__ -> 80:a ;
+83:__UG_NAME__ -> 84:a ;
+94:__UG_NAME__ -> 95:a ;
+98:__UG_NAME__ -> 99:a ;
+121:__UG_NAME__ -> 122:a ;
+124:__UG_NAME__ -> 125:a ;
+131:__UG_NAME__ -> 132:a ;
+135:__UG_NAME__ -> 136:a ;
+144:__UG_NAME__ -> 145:a ;
+148:__UG_NAME__ -> 149:a ;
+173:__UG_NAME__ -> 174:a ;
+177:__UG_NAME__ -> 178:a ;
+170:__UG_NAME__ -> 185:a ;
+190:__UG_NAME__ -> 191:a ;
+46:__UG_NAME__ -> 47:a ;
+50:__UG_NAME__ -> 51:a ;
+62:__UG_NAME__ -> 63:a ;
+66:__UG_NAME__ -> 67:a ;
+78:__UG_NAME__ -> 79:a ;
+82:__UG_NAME__ -> 83:a ;
+93:__UG_NAME__ -> 94:a ;
+97:__UG_NAME__ -> 98:a ;
+120:__UG_NAME__ -> 121:a ;
+44:__UG_NAME__ -> 124:a ;
+130:__UG_NAME__ -> 131:a ;
+134:__UG_NAME__ -> 135:a ;
+143:__UG_NAME__ -> 144:a ;
+147:__UG_NAME__ -> 148:a ;
+169:__UG_NAME__ -> 170:a ;
+172:__UG_NAME__ -> 173:a ;
+176:__UG_NAME__ -> 177:a ;
+187:__UG_NAME__ -> 190:a ;
+75:__UG_NAME__ -> 153:in ;
+76:__UG_NAME__ -> 153:max____delay____time ;
+141:__UG_NAME__ -> 153:delay____time ;
+152:__UG_NAME__ -> 153:decay____time ;
+161:__UG_NAME__ -> 168:in ;
+162:__UG_NAME__ -> 168:max____delay____time ;
+166:__UG_NAME__ -> 168:delay____time ;
+167:__UG_NAME__ -> 168:decay____time ;
+8:__UG_NAME__ -> 54:envelope___control___0 ;
+8:__UG_NAME__ -> 54:envelope___control___4 ;
+9:__UG_NAME__ -> 54:envelope___control___5 ;
+10:__UG_NAME__ -> 54:envelope___control___6 ;
+11:__UG_NAME__ -> 54:envelope___control___7 ;
+53:__UG_NAME__ -> 54:gate ;
+33:__UG_NAME__ -> 70:envelope___control___0 ;
+33:__UG_NAME__ -> 70:envelope___control___4 ;
+34:__UG_NAME__ -> 70:envelope___control___5 ;
+35:__UG_NAME__ -> 70:envelope___control___6 ;
+36:__UG_NAME__ -> 70:envelope___control___7 ;
+69:__UG_NAME__ -> 70:gate ;
+12:__UG_NAME__ -> 86:envelope___control___0 ;
+12:__UG_NAME__ -> 86:envelope___control___4 ;
+13:__UG_NAME__ -> 86:envelope___control___5 ;
+14:__UG_NAME__ -> 86:envelope___control___6 ;
+15:__UG_NAME__ -> 86:envelope___control___7 ;
+85:__UG_NAME__ -> 86:gate ;
+20:__UG_NAME__ -> 101:envelope___control___0 ;
+20:__UG_NAME__ -> 101:envelope___control___4 ;
+21:__UG_NAME__ -> 101:envelope___control___5 ;
+22:__UG_NAME__ -> 101:envelope___control___6 ;
+23:__UG_NAME__ -> 101:envelope___control___7 ;
+100:__UG_NAME__ -> 101:gate ;
+29:__UG_NAME__ -> 127:envelope___control___0 ;
+29:__UG_NAME__ -> 127:envelope___control___4 ;
+30:__UG_NAME__ -> 127:envelope___control___5 ;
+31:__UG_NAME__ -> 127:envelope___control___6 ;
+32:__UG_NAME__ -> 127:envelope___control___7 ;
+126:__UG_NAME__ -> 127:gate ;
+24:__UG_NAME__ -> 138:envelope___control___0 ;
+24:__UG_NAME__ -> 138:envelope___control___4 ;
+25:__UG_NAME__ -> 138:envelope___control___5 ;
+26:__UG_NAME__ -> 138:envelope___control___6 ;
+27:__UG_NAME__ -> 138:envelope___control___7 ;
+137:__UG_NAME__ -> 138:gate ;
+37:__UG_NAME__ -> 151:envelope___control___0 ;
+37:__UG_NAME__ -> 151:envelope___control___4 ;
+38:__UG_NAME__ -> 151:envelope___control___5 ;
+39:__UG_NAME__ -> 151:envelope___control___6 ;
+40:__UG_NAME__ -> 151:envelope___control___7 ;
+150:__UG_NAME__ -> 151:gate ;
+4:__UG_NAME__ -> 180:envelope___control___0 ;
+4:__UG_NAME__ -> 180:envelope___control___4 ;
+5:__UG_NAME__ -> 180:envelope___control___5 ;
+6:__UG_NAME__ -> 180:envelope___control___6 ;
+7:__UG_NAME__ -> 180:envelope___control___7 ;
+179:__UG_NAME__ -> 180:gate ;
+0:__UG_NAME__ -> 193:envelope___control___0 ;
+0:__UG_NAME__ -> 193:envelope___control___4 ;
+1:__UG_NAME__ -> 193:envelope___control___5 ;
+2:__UG_NAME__ -> 193:envelope___control___6 ;
+3:__UG_NAME__ -> 193:envelope___control___7 ;
+192:__UG_NAME__ -> 193:gate ;
+30:__UG_NAME__ -> 44:in ;
+8:__UG_NAME__ -> 46:in ;
+9:__UG_NAME__ -> 50:in ;
+33:__UG_NAME__ -> 62:in ;
+34:__UG_NAME__ -> 66:in ;
+12:__UG_NAME__ -> 78:in ;
+13:__UG_NAME__ -> 82:in ;
+20:__UG_NAME__ -> 93:in ;
+21:__UG_NAME__ -> 97:in ;
+29:__UG_NAME__ -> 120:in ;
+24:__UG_NAME__ -> 130:in ;
+25:__UG_NAME__ -> 134:in ;
+37:__UG_NAME__ -> 143:in ;
+38:__UG_NAME__ -> 147:in ;
+0:__UG_NAME__ -> 169:in ;
+4:__UG_NAME__ -> 172:in ;
+5:__UG_NAME__ -> 176:in ;
+1:__UG_NAME__ -> 187:in ;
+42:__UG_NAME__ -> 55:bus ;
+87:__UG_NAME__ -> 111:freq ;
+110:__UG_NAME__ -> 111:iphase ;
+87:__UG_NAME__ -> 102:freq ;
+16:__UG_NAME__ -> 102:iphase ;
+101:__UG_NAME__ -> 102:width ;
+87:__UG_NAME__ -> 90:freq ;
+89:__UG_NAME__ -> 90:iphase ;
+87:__UG_NAME__ -> 106:freq ;
+105:__UG_NAME__ -> 106:iphase ;
+71:__UG_NAME__ -> 72:in ;
+156:__UG_NAME__ -> 157:in ;
+155:__UG_NAME__ -> 199:channels____array___binary____op____u____gen___0 ;
+189:__UG_NAME__ -> 199:channels____array___binary____op____u____gen___1 ;
+140:__UG_NAME__ -> 141:a ;
+165:__UG_NAME__ -> 166:a ;
+118:__UG_NAME__ -> 140:in ;
+128:__UG_NAME__ -> 140:mul ;
+139:__UG_NAME__ -> 140:add ;
+116:__UG_NAME__ -> 165:in ;
+163:__UG_NAME__ -> 165:mul ;
+164:__UG_NAME__ -> 165:add ;
+43:__UG_NAME__ -> 197:bus ;
+195:__UG_NAME__ -> 197:signals___x____fade2___0 ;
+196:__UG_NAME__ -> 197:signals___x____fade2___1 ;
+17:__UG_NAME__ -> 112:which ;
+91:__UG_NAME__ -> 112:array___binary____op____u____gen___0 ;
+104:__UG_NAME__ -> 112:array___binary____op____u____gen___1 ;
+106:__UG_NAME__ -> 112:array___lf____tri___2 ;
+109:__UG_NAME__ -> 112:array___sin____osc___3 ;
+111:__UG_NAME__ -> 112:array___lf____cub___4 ;
+18:__UG_NAME__ -> 116:which ;
+114:__UG_NAME__ -> 116:array___binary____op____u____gen___0 ;
+115:__UG_NAME__ -> 116:array___binary____op____u____gen___1 ;
+19:__UG_NAME__ -> 118:which ;
+116:__UG_NAME__ -> 118:array___select___0 ;
+117:__UG_NAME__ -> 118:array___binary____op____u____gen___1 ;
+87:__UG_NAME__ -> 109:freq ;
+108:__UG_NAME__ -> 109:phase ;
+56:__UG_NAME__ -> 195:ina ;
+155:__UG_NAME__ -> 195:inb ;
+194:__UG_NAME__ -> 195:pan ;
+193:__UG_NAME__ -> 195:level ;
+159:__UG_NAME__ -> 196:ina ;
+189:__UG_NAME__ -> 196:inb ;
+183:__UG_NAME__ -> 196:pan ;
+193:__UG_NAME__ -> 196:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_gverb.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_gverb.dot
new file mode 100644
index 0000000..35d25d1
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_gverb.dot
@@ -0,0 +1,371 @@
+digraph synthdef {
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+113 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+118 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+119 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+122 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="dashed, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :room
+ default: 10" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+1 [label = "control
+ :max_room
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+2 [label = "control
+ :release
+ default: 3" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+3 [label = "control
+ :ref_level
+ default: 0.7" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+4 [label = "control
+ :tail_level
+ default: 0.5" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+5 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :mix
+ default: 0.4" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :spread
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :spread_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :spread_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :spread_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :damp
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :damp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :damp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :damp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :pre_damp
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :pre_damp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :pre_damp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :pre_damp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :dry
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :dry_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :dry_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :dry_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+44 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <in> in|<taillevel> taillevel|<earlyreflevel> earlyreflevel|<roomsize> roomsize|<damping> damping|<inputbw> inputbw|<maxroomsize> maxroomsize|<revtime> revtime|<spread> spread 0.0|<drylevel> drylevel} |<__UG_NAME__>g-verb }" style="filled, bold, rounded"  shape=record rankdir=LR];
+117 [label = "{{ <in> in|<taillevel> taillevel|<earlyreflevel> earlyreflevel|<roomsize> roomsize|<damping> damping|<inputbw> inputbw|<maxroomsize> maxroomsize|<revtime> revtime|<spread> spread 0.0|<drylevel> drylevel} |<__UG_NAME__>g-verb }" style="filled, bold, rounded"  shape=record rankdir=LR];
+36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+103 [label = "{{ <add> add -1.0|<mul> mul 1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+89 [label = "{{ {{<array___control___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <level> level 1.0|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+121 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+123 [label = "{{ <level> level 1.0|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+125 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+54:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+44:__UG_NAME__ -> 91:a ;
+90:__UG_NAME__ -> 91:b ;
+112:__UG_NAME__ -> 113:a ;
+112:__UG_NAME__ -> 115:a ;
+54:__UG_NAME__ -> 116:a ;
+55:__UG_NAME__ -> 116:b ;
+44:__UG_NAME__ -> 118:a ;
+90:__UG_NAME__ -> 118:b ;
+44:__UG_NAME__ -> 119:a ;
+117:__UG_NAME__ -> 119:b ;
+44:__UG_NAME__ -> 122:a ;
+117:__UG_NAME__ -> 122:b ;
+35:__UG_NAME__ -> 39:a ;
+38:__UG_NAME__ -> 39:b ;
+39:__UG_NAME__ -> 43:a ;
+42:__UG_NAME__ -> 43:b ;
+45:__UG_NAME__ -> 49:a ;
+48:__UG_NAME__ -> 49:b ;
+49:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+57:__UG_NAME__ -> 61:a ;
+60:__UG_NAME__ -> 61:b ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+67:__UG_NAME__ -> 71:a ;
+70:__UG_NAME__ -> 71:b ;
+71:__UG_NAME__ -> 75:a ;
+74:__UG_NAME__ -> 75:b ;
+77:__UG_NAME__ -> 81:a ;
+80:__UG_NAME__ -> 81:b ;
+81:__UG_NAME__ -> 85:a ;
+84:__UG_NAME__ -> 85:b ;
+0:__UG_NAME__ -> 88:a ;
+93:__UG_NAME__ -> 97:a ;
+96:__UG_NAME__ -> 97:b ;
+97:__UG_NAME__ -> 101:a ;
+100:__UG_NAME__ -> 101:b ;
+92:__UG_NAME__ -> 107:a ;
+106:__UG_NAME__ -> 107:b ;
+107:__UG_NAME__ -> 111:a ;
+110:__UG_NAME__ -> 111:b ;
+113:__UG_NAME__ -> 114:a ;
+115:__UG_NAME__ -> 124:a ;
+1:__UG_NAME__ -> 87:b ;
+37:__UG_NAME__ -> 38:a ;
+41:__UG_NAME__ -> 42:a ;
+47:__UG_NAME__ -> 48:a ;
+51:__UG_NAME__ -> 52:a ;
+59:__UG_NAME__ -> 60:a ;
+63:__UG_NAME__ -> 64:a ;
+69:__UG_NAME__ -> 70:a ;
+73:__UG_NAME__ -> 74:a ;
+79:__UG_NAME__ -> 80:a ;
+83:__UG_NAME__ -> 84:a ;
+95:__UG_NAME__ -> 96:a ;
+99:__UG_NAME__ -> 100:a ;
+105:__UG_NAME__ -> 106:a ;
+109:__UG_NAME__ -> 110:a ;
+36:__UG_NAME__ -> 37:a ;
+40:__UG_NAME__ -> 41:a ;
+46:__UG_NAME__ -> 47:a ;
+50:__UG_NAME__ -> 51:a ;
+58:__UG_NAME__ -> 59:a ;
+62:__UG_NAME__ -> 63:a ;
+68:__UG_NAME__ -> 69:a ;
+72:__UG_NAME__ -> 73:a ;
+78:__UG_NAME__ -> 79:a ;
+82:__UG_NAME__ -> 83:a ;
+94:__UG_NAME__ -> 95:a ;
+98:__UG_NAME__ -> 99:a ;
+104:__UG_NAME__ -> 105:a ;
+108:__UG_NAME__ -> 109:a ;
+5:__UG_NAME__ -> 44:envelope___control___0 ;
+5:__UG_NAME__ -> 44:envelope___control___4 ;
+6:__UG_NAME__ -> 44:envelope___control___5 ;
+7:__UG_NAME__ -> 44:envelope___control___6 ;
+8:__UG_NAME__ -> 44:envelope___control___7 ;
+43:__UG_NAME__ -> 44:gate ;
+13:__UG_NAME__ -> 54:envelope___control___0 ;
+13:__UG_NAME__ -> 54:envelope___control___4 ;
+14:__UG_NAME__ -> 54:envelope___control___5 ;
+15:__UG_NAME__ -> 54:envelope___control___6 ;
+16:__UG_NAME__ -> 54:envelope___control___7 ;
+53:__UG_NAME__ -> 54:gate ;
+21:__UG_NAME__ -> 66:envelope___control___0 ;
+21:__UG_NAME__ -> 66:envelope___control___4 ;
+22:__UG_NAME__ -> 66:envelope___control___5 ;
+23:__UG_NAME__ -> 66:envelope___control___6 ;
+24:__UG_NAME__ -> 66:envelope___control___7 ;
+65:__UG_NAME__ -> 66:gate ;
+25:__UG_NAME__ -> 76:envelope___control___0 ;
+25:__UG_NAME__ -> 76:envelope___control___4 ;
+26:__UG_NAME__ -> 76:envelope___control___5 ;
+27:__UG_NAME__ -> 76:envelope___control___6 ;
+28:__UG_NAME__ -> 76:envelope___control___7 ;
+75:__UG_NAME__ -> 76:gate ;
+29:__UG_NAME__ -> 86:envelope___control___0 ;
+29:__UG_NAME__ -> 86:envelope___control___4 ;
+30:__UG_NAME__ -> 86:envelope___control___5 ;
+31:__UG_NAME__ -> 86:envelope___control___6 ;
+32:__UG_NAME__ -> 86:envelope___control___7 ;
+85:__UG_NAME__ -> 86:gate ;
+17:__UG_NAME__ -> 102:envelope___control___0 ;
+17:__UG_NAME__ -> 102:envelope___control___4 ;
+18:__UG_NAME__ -> 102:envelope___control___5 ;
+19:__UG_NAME__ -> 102:envelope___control___6 ;
+20:__UG_NAME__ -> 102:envelope___control___7 ;
+101:__UG_NAME__ -> 102:gate ;
+9:__UG_NAME__ -> 112:envelope___control___0 ;
+9:__UG_NAME__ -> 112:envelope___control___4 ;
+10:__UG_NAME__ -> 112:envelope___control___5 ;
+11:__UG_NAME__ -> 112:envelope___control___6 ;
+12:__UG_NAME__ -> 112:envelope___control___7 ;
+111:__UG_NAME__ -> 112:gate ;
+86:__UG_NAME__ -> 90:drylevel ;
+2:__UG_NAME__ -> 90:revtime ;
+89:__UG_NAME__ -> 90:maxroomsize ;
+76:__UG_NAME__ -> 90:inputbw ;
+66:__UG_NAME__ -> 90:damping ;
+0:__UG_NAME__ -> 90:roomsize ;
+3:__UG_NAME__ -> 90:earlyreflevel ;
+4:__UG_NAME__ -> 90:taillevel ;
+56:__UG_NAME__ -> 90:in ;
+86:__UG_NAME__ -> 117:drylevel ;
+2:__UG_NAME__ -> 117:revtime ;
+89:__UG_NAME__ -> 117:maxroomsize ;
+76:__UG_NAME__ -> 117:inputbw ;
+66:__UG_NAME__ -> 117:damping ;
+0:__UG_NAME__ -> 117:roomsize ;
+3:__UG_NAME__ -> 117:earlyreflevel ;
+4:__UG_NAME__ -> 117:taillevel ;
+116:__UG_NAME__ -> 117:in ;
+5:__UG_NAME__ -> 36:in ;
+6:__UG_NAME__ -> 40:in ;
+13:__UG_NAME__ -> 46:in ;
+14:__UG_NAME__ -> 50:in ;
+21:__UG_NAME__ -> 58:in ;
+22:__UG_NAME__ -> 62:in ;
+25:__UG_NAME__ -> 68:in ;
+26:__UG_NAME__ -> 72:in ;
+29:__UG_NAME__ -> 78:in ;
+30:__UG_NAME__ -> 82:in ;
+17:__UG_NAME__ -> 94:in ;
+18:__UG_NAME__ -> 98:in ;
+9:__UG_NAME__ -> 104:in ;
+10:__UG_NAME__ -> 108:in ;
+33:__UG_NAME__ -> 55:bus ;
+102:__UG_NAME__ -> 103:in ;
+34:__UG_NAME__ -> 126:bus ;
+121:__UG_NAME__ -> 126:signals___x____fade2___0 ;
+125:__UG_NAME__ -> 126:signals___x____fade2___1 ;
+87:__UG_NAME__ -> 89:which ;
+1:__UG_NAME__ -> 89:array___control___0 ;
+88:__UG_NAME__ -> 89:array___binary____op____u____gen___1 ;
+118:__UG_NAME__ -> 120:ina ;
+119:__UG_NAME__ -> 120:inb ;
+103:__UG_NAME__ -> 120:pan ;
+56:__UG_NAME__ -> 121:ina ;
+120:__UG_NAME__ -> 121:inb ;
+114:__UG_NAME__ -> 121:pan ;
+44:__UG_NAME__ -> 121:level ;
+122:__UG_NAME__ -> 123:ina ;
+91:__UG_NAME__ -> 123:inb ;
+103:__UG_NAME__ -> 123:pan ;
+116:__UG_NAME__ -> 125:ina ;
+123:__UG_NAME__ -> 125:inb ;
+124:__UG_NAME__ -> 125:pan ;
+44:__UG_NAME__ -> 125:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_hpf.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_hpf.dot
new file mode 100644
index 0000000..3c1e94e
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_hpf.dot
@@ -0,0 +1,200 @@
+digraph synthdef {
+28 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+63 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+21 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+20 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+67 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+19 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+18 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+68 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+69 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+27:__UG_NAME__ -> 28:a ;
+39:__UG_NAME__ -> 41:a ;
+40:__UG_NAME__ -> 41:b ;
+39:__UG_NAME__ -> 50:a ;
+40:__UG_NAME__ -> 50:b ;
+27:__UG_NAME__ -> 63:a ;
+18:__UG_NAME__ -> 22:a ;
+21:__UG_NAME__ -> 22:b ;
+22:__UG_NAME__ -> 26:a ;
+25:__UG_NAME__ -> 26:b ;
+30:__UG_NAME__ -> 34:a ;
+33:__UG_NAME__ -> 34:b ;
+34:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+42:__UG_NAME__ -> 46:a ;
+45:__UG_NAME__ -> 46:b ;
+51:__UG_NAME__ -> 55:a ;
+54:__UG_NAME__ -> 55:b ;
+55:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+46:__UG_NAME__ -> 65:a ;
+49:__UG_NAME__ -> 65:b ;
+28:__UG_NAME__ -> 29:a ;
+63:__UG_NAME__ -> 64:a ;
+20:__UG_NAME__ -> 21:a ;
+24:__UG_NAME__ -> 25:a ;
+32:__UG_NAME__ -> 33:a ;
+36:__UG_NAME__ -> 37:a ;
+44:__UG_NAME__ -> 45:a ;
+48:__UG_NAME__ -> 49:a ;
+53:__UG_NAME__ -> 54:a ;
+57:__UG_NAME__ -> 58:a ;
+19:__UG_NAME__ -> 20:a ;
+23:__UG_NAME__ -> 24:a ;
+31:__UG_NAME__ -> 32:a ;
+35:__UG_NAME__ -> 36:a ;
+43:__UG_NAME__ -> 44:a ;
+47:__UG_NAME__ -> 48:a ;
+52:__UG_NAME__ -> 53:a ;
+56:__UG_NAME__ -> 57:a ;
+4:__UG_NAME__ -> 27:envelope___control___0 ;
+4:__UG_NAME__ -> 27:envelope___control___4 ;
+5:__UG_NAME__ -> 27:envelope___control___5 ;
+6:__UG_NAME__ -> 27:envelope___control___6 ;
+7:__UG_NAME__ -> 27:envelope___control___7 ;
+26:__UG_NAME__ -> 27:gate ;
+8:__UG_NAME__ -> 39:envelope___control___0 ;
+8:__UG_NAME__ -> 39:envelope___control___4 ;
+9:__UG_NAME__ -> 39:envelope___control___5 ;
+10:__UG_NAME__ -> 39:envelope___control___6 ;
+11:__UG_NAME__ -> 39:envelope___control___7 ;
+38:__UG_NAME__ -> 39:gate ;
+12:__UG_NAME__ -> 60:envelope___control___0 ;
+12:__UG_NAME__ -> 60:envelope___control___4 ;
+13:__UG_NAME__ -> 60:envelope___control___5 ;
+14:__UG_NAME__ -> 60:envelope___control___6 ;
+15:__UG_NAME__ -> 60:envelope___control___7 ;
+59:__UG_NAME__ -> 60:gate ;
+0:__UG_NAME__ -> 66:envelope___control___0 ;
+0:__UG_NAME__ -> 66:envelope___control___4 ;
+1:__UG_NAME__ -> 66:envelope___control___5 ;
+2:__UG_NAME__ -> 66:envelope___control___6 ;
+3:__UG_NAME__ -> 66:envelope___control___7 ;
+65:__UG_NAME__ -> 66:gate ;
+50:__UG_NAME__ -> 62:in ;
+61:__UG_NAME__ -> 62:freq ;
+41:__UG_NAME__ -> 67:in ;
+61:__UG_NAME__ -> 67:freq ;
+4:__UG_NAME__ -> 19:in ;
+5:__UG_NAME__ -> 23:in ;
+8:__UG_NAME__ -> 31:in ;
+9:__UG_NAME__ -> 35:in ;
+0:__UG_NAME__ -> 43:in ;
+1:__UG_NAME__ -> 47:in ;
+12:__UG_NAME__ -> 52:in ;
+13:__UG_NAME__ -> 56:in ;
+16:__UG_NAME__ -> 40:bus ;
+60:__UG_NAME__ -> 61:a ;
+17:__UG_NAME__ -> 70:bus ;
+68:__UG_NAME__ -> 70:signals___x____fade2___0 ;
+69:__UG_NAME__ -> 70:signals___x____fade2___1 ;
+41:__UG_NAME__ -> 68:ina ;
+67:__UG_NAME__ -> 68:inb ;
+29:__UG_NAME__ -> 68:pan ;
+66:__UG_NAME__ -> 68:level ;
+50:__UG_NAME__ -> 69:ina ;
+62:__UG_NAME__ -> 69:inb ;
+64:__UG_NAME__ -> 69:pan ;
+66:__UG_NAME__ -> 69:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_ixi_techno.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_ixi_techno.dot
new file mode 100644
index 0000000..5baee6e
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_ixi_techno.dot
@@ -0,0 +1,336 @@
+digraph synthdef {
+63 [label = "{{ <b> 6.2831855|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+113 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :phase
+ default: 4.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :phase_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :phase_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :phase_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :phase_offset
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :cutoff_min
+ default: 60.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :cutoff_min_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :cutoff_min_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff_min_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_max
+ default: 120.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_max_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_max_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :cutoff_max_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :res
+ default: 0.8" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+55 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+77 [label = "{{ <dsthi> dsthi|<dstlo> dstlo|<srchi> srchi 1.0|<srclo> srclo -1.0|<in> in} |<__UG_NAME__>lin-exp }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+112 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+117 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+64 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase|<freq> freq} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+119 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+31:__UG_NAME__ -> 63:a ;
+87:__UG_NAME__ -> 88:a ;
+108:__UG_NAME__ -> 110:a ;
+109:__UG_NAME__ -> 110:b ;
+87:__UG_NAME__ -> 113:a ;
+108:__UG_NAME__ -> 116:a ;
+109:__UG_NAME__ -> 116:b ;
+32:__UG_NAME__ -> 37:a ;
+36:__UG_NAME__ -> 37:b ;
+37:__UG_NAME__ -> 41:a ;
+40:__UG_NAME__ -> 41:b ;
+46:__UG_NAME__ -> 50:a ;
+49:__UG_NAME__ -> 50:b ;
+50:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+56:__UG_NAME__ -> 58:a ;
+57:__UG_NAME__ -> 58:b ;
+58:__UG_NAME__ -> 60:a ;
+59:__UG_NAME__ -> 60:b ;
+65:__UG_NAME__ -> 69:a ;
+68:__UG_NAME__ -> 69:b ;
+69:__UG_NAME__ -> 73:a ;
+72:__UG_NAME__ -> 73:b ;
+78:__UG_NAME__ -> 82:a ;
+81:__UG_NAME__ -> 82:b ;
+82:__UG_NAME__ -> 86:a ;
+85:__UG_NAME__ -> 86:b ;
+91:__UG_NAME__ -> 95:a ;
+94:__UG_NAME__ -> 95:b ;
+95:__UG_NAME__ -> 98:a ;
+97:__UG_NAME__ -> 98:b ;
+99:__UG_NAME__ -> 103:a ;
+102:__UG_NAME__ -> 103:b ;
+103:__UG_NAME__ -> 106:a ;
+105:__UG_NAME__ -> 106:b ;
+16:__UG_NAME__ -> 31:a ;
+113:__UG_NAME__ -> 114:a ;
+88:__UG_NAME__ -> 118:a ;
+61:__UG_NAME__ -> 62:b ;
+35:__UG_NAME__ -> 36:a ;
+39:__UG_NAME__ -> 40:a ;
+48:__UG_NAME__ -> 49:a ;
+52:__UG_NAME__ -> 53:a ;
+44:__UG_NAME__ -> 57:a ;
+45:__UG_NAME__ -> 59:a ;
+67:__UG_NAME__ -> 68:a ;
+71:__UG_NAME__ -> 72:a ;
+80:__UG_NAME__ -> 81:a ;
+84:__UG_NAME__ -> 85:a ;
+93:__UG_NAME__ -> 94:a ;
+96:__UG_NAME__ -> 97:a ;
+101:__UG_NAME__ -> 102:a ;
+104:__UG_NAME__ -> 105:a ;
+34:__UG_NAME__ -> 35:a ;
+38:__UG_NAME__ -> 39:a ;
+43:__UG_NAME__ -> 44:a ;
+42:__UG_NAME__ -> 45:a ;
+47:__UG_NAME__ -> 48:a ;
+51:__UG_NAME__ -> 52:a ;
+66:__UG_NAME__ -> 67:a ;
+70:__UG_NAME__ -> 71:a ;
+79:__UG_NAME__ -> 80:a ;
+83:__UG_NAME__ -> 84:a ;
+92:__UG_NAME__ -> 93:a ;
+90:__UG_NAME__ -> 96:a ;
+100:__UG_NAME__ -> 101:a ;
+89:__UG_NAME__ -> 104:a ;
+21:__UG_NAME__ -> 55:envelope___control___0 ;
+21:__UG_NAME__ -> 55:envelope___control___4 ;
+22:__UG_NAME__ -> 55:envelope___control___5 ;
+23:__UG_NAME__ -> 55:envelope___control___6 ;
+24:__UG_NAME__ -> 55:envelope___control___7 ;
+54:__UG_NAME__ -> 55:gate ;
+12:__UG_NAME__ -> 61:envelope___control___0 ;
+12:__UG_NAME__ -> 61:envelope___control___4 ;
+13:__UG_NAME__ -> 61:envelope___control___5 ;
+14:__UG_NAME__ -> 61:envelope___control___6 ;
+15:__UG_NAME__ -> 61:envelope___control___7 ;
+60:__UG_NAME__ -> 61:gate ;
+17:__UG_NAME__ -> 74:envelope___control___0 ;
+17:__UG_NAME__ -> 74:envelope___control___4 ;
+18:__UG_NAME__ -> 74:envelope___control___5 ;
+19:__UG_NAME__ -> 74:envelope___control___6 ;
+20:__UG_NAME__ -> 74:envelope___control___7 ;
+73:__UG_NAME__ -> 74:gate ;
+4:__UG_NAME__ -> 87:envelope___control___0 ;
+4:__UG_NAME__ -> 87:envelope___control___4 ;
+5:__UG_NAME__ -> 87:envelope___control___5 ;
+6:__UG_NAME__ -> 87:envelope___control___6 ;
+7:__UG_NAME__ -> 87:envelope___control___7 ;
+86:__UG_NAME__ -> 87:gate ;
+0:__UG_NAME__ -> 107:envelope___control___0 ;
+0:__UG_NAME__ -> 107:envelope___control___4 ;
+1:__UG_NAME__ -> 107:envelope___control___5 ;
+2:__UG_NAME__ -> 107:envelope___control___6 ;
+3:__UG_NAME__ -> 107:envelope___control___7 ;
+106:__UG_NAME__ -> 107:gate ;
+8:__UG_NAME__ -> 108:envelope___control___0 ;
+8:__UG_NAME__ -> 108:envelope___control___4 ;
+9:__UG_NAME__ -> 108:envelope___control___5 ;
+10:__UG_NAME__ -> 108:envelope___control___6 ;
+11:__UG_NAME__ -> 108:envelope___control___7 ;
+98:__UG_NAME__ -> 108:gate ;
+33:__UG_NAME__ -> 111:envelope___mul____add___0 ;
+33:__UG_NAME__ -> 111:envelope___mul____add___4 ;
+26:__UG_NAME__ -> 111:envelope___control___5 ;
+27:__UG_NAME__ -> 111:envelope___control___6 ;
+28:__UG_NAME__ -> 111:envelope___control___7 ;
+41:__UG_NAME__ -> 111:gate ;
+33:__UG_NAME__ -> 34:in ;
+26:__UG_NAME__ -> 38:in ;
+13:__UG_NAME__ -> 42:in ;
+12:__UG_NAME__ -> 43:in ;
+21:__UG_NAME__ -> 47:in ;
+22:__UG_NAME__ -> 51:in ;
+17:__UG_NAME__ -> 66:in ;
+18:__UG_NAME__ -> 70:in ;
+4:__UG_NAME__ -> 79:in ;
+5:__UG_NAME__ -> 83:in ;
+1:__UG_NAME__ -> 89:in ;
+9:__UG_NAME__ -> 90:in ;
+8:__UG_NAME__ -> 92:in ;
+0:__UG_NAME__ -> 100:in ;
+29:__UG_NAME__ -> 109:bus ;
+64:__UG_NAME__ -> 77:in ;
+75:__UG_NAME__ -> 77:dstlo ;
+76:__UG_NAME__ -> 77:dsthi ;
+74:__UG_NAME__ -> 75:a ;
+55:__UG_NAME__ -> 76:a ;
+25:__UG_NAME__ -> 33:in ;
+30:__UG_NAME__ -> 120:bus ;
+115:__UG_NAME__ -> 120:signals___x____fade2___0 ;
+119:__UG_NAME__ -> 120:signals___x____fade2___1 ;
+110:__UG_NAME__ -> 112:in ;
+77:__UG_NAME__ -> 112:freq ;
+111:__UG_NAME__ -> 112:rq ;
+116:__UG_NAME__ -> 117:in ;
+77:__UG_NAME__ -> 117:freq ;
+111:__UG_NAME__ -> 117:rq ;
+62:__UG_NAME__ -> 64:freq ;
+63:__UG_NAME__ -> 64:phase ;
+110:__UG_NAME__ -> 115:ina ;
+112:__UG_NAME__ -> 115:inb ;
+114:__UG_NAME__ -> 115:pan ;
+107:__UG_NAME__ -> 115:level ;
+116:__UG_NAME__ -> 119:ina ;
+117:__UG_NAME__ -> 119:inb ;
+118:__UG_NAME__ -> 119:pan ;
+107:__UG_NAME__ -> 119:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_krush.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_krush.dot
new file mode 100644
index 0000000..fd3602b
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_krush.dot
@@ -0,0 +1,326 @@
+digraph synthdef {
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+92 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+106 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+114 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+55 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+111 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+52 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+112 [label = "{{ <b> |<a> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+29 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :gain
+ default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :gain_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :gain_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :gain_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :res
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+102 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+104 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+113 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>squared }" style="filled, bold, rounded"  shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> } |<__UG_NAME__>squared }" style="filled, bold, rounded"  shape=record rankdir=LR];
+108 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+116 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+35:__UG_NAME__ -> 37:a ;
+36:__UG_NAME__ -> 37:b ;
+49:__UG_NAME__ -> 50:a ;
+38:__UG_NAME__ -> 50:b ;
+38:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+35:__UG_NAME__ -> 67:a ;
+36:__UG_NAME__ -> 67:b ;
+68:__UG_NAME__ -> 92:a ;
+91:__UG_NAME__ -> 92:b ;
+105:__UG_NAME__ -> 106:a ;
+49:__UG_NAME__ -> 109:a ;
+68:__UG_NAME__ -> 109:b ;
+105:__UG_NAME__ -> 114:a ;
+26:__UG_NAME__ -> 30:a ;
+29:__UG_NAME__ -> 30:b ;
+30:__UG_NAME__ -> 34:a ;
+33:__UG_NAME__ -> 34:b ;
+40:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+44:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+39:__UG_NAME__ -> 51:a ;
+50:__UG_NAME__ -> 51:b ;
+39:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+54:__UG_NAME__ -> 55:a ;
+59:__UG_NAME__ -> 61:a ;
+60:__UG_NAME__ -> 61:b ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+69:__UG_NAME__ -> 73:a ;
+72:__UG_NAME__ -> 73:b ;
+73:__UG_NAME__ -> 77:a ;
+76:__UG_NAME__ -> 77:b ;
+78:__UG_NAME__ -> 83:a ;
+82:__UG_NAME__ -> 83:b ;
+83:__UG_NAME__ -> 87:a ;
+86:__UG_NAME__ -> 87:b ;
+90:__UG_NAME__ -> 93:a ;
+92:__UG_NAME__ -> 93:b ;
+94:__UG_NAME__ -> 97:a ;
+96:__UG_NAME__ -> 97:b ;
+97:__UG_NAME__ -> 100:a ;
+99:__UG_NAME__ -> 100:b ;
+90:__UG_NAME__ -> 110:a ;
+109:__UG_NAME__ -> 110:b ;
+93:__UG_NAME__ -> 111:a ;
+49:__UG_NAME__ -> 52:a ;
+49:__UG_NAME__ -> 91:a ;
+106:__UG_NAME__ -> 107:a ;
+114:__UG_NAME__ -> 115:a ;
+51:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+110:__UG_NAME__ -> 112:a ;
+111:__UG_NAME__ -> 112:b ;
+28:__UG_NAME__ -> 29:a ;
+32:__UG_NAME__ -> 33:a ;
+42:__UG_NAME__ -> 43:a ;
+46:__UG_NAME__ -> 47:a ;
+58:__UG_NAME__ -> 60:a ;
+63:__UG_NAME__ -> 64:a ;
+71:__UG_NAME__ -> 72:a ;
+75:__UG_NAME__ -> 76:a ;
+81:__UG_NAME__ -> 82:a ;
+85:__UG_NAME__ -> 86:a ;
+95:__UG_NAME__ -> 96:a ;
+98:__UG_NAME__ -> 99:a ;
+27:__UG_NAME__ -> 28:a ;
+31:__UG_NAME__ -> 32:a ;
+37:__UG_NAME__ -> 38:a ;
+41:__UG_NAME__ -> 42:a ;
+45:__UG_NAME__ -> 46:a ;
+57:__UG_NAME__ -> 58:a ;
+62:__UG_NAME__ -> 63:a ;
+67:__UG_NAME__ -> 68:a ;
+70:__UG_NAME__ -> 71:a ;
+74:__UG_NAME__ -> 75:a ;
+80:__UG_NAME__ -> 81:a ;
+84:__UG_NAME__ -> 85:a ;
+88:__UG_NAME__ -> 95:a ;
+89:__UG_NAME__ -> 98:a ;
+8:__UG_NAME__ -> 35:envelope___control___0 ;
+8:__UG_NAME__ -> 35:envelope___control___4 ;
+9:__UG_NAME__ -> 35:envelope___control___5 ;
+10:__UG_NAME__ -> 35:envelope___control___6 ;
+11:__UG_NAME__ -> 35:envelope___control___7 ;
+34:__UG_NAME__ -> 35:gate ;
+12:__UG_NAME__ -> 49:envelope___control___0 ;
+12:__UG_NAME__ -> 49:envelope___control___4 ;
+13:__UG_NAME__ -> 49:envelope___control___5 ;
+14:__UG_NAME__ -> 49:envelope___control___6 ;
+15:__UG_NAME__ -> 49:envelope___control___7 ;
+48:__UG_NAME__ -> 49:gate ;
+0:__UG_NAME__ -> 66:envelope___control___0 ;
+0:__UG_NAME__ -> 66:envelope___control___4 ;
+1:__UG_NAME__ -> 66:envelope___control___5 ;
+2:__UG_NAME__ -> 66:envelope___control___6 ;
+3:__UG_NAME__ -> 66:envelope___control___7 ;
+65:__UG_NAME__ -> 66:gate ;
+16:__UG_NAME__ -> 101:envelope___control___0 ;
+16:__UG_NAME__ -> 101:envelope___control___4 ;
+17:__UG_NAME__ -> 101:envelope___control___5 ;
+18:__UG_NAME__ -> 101:envelope___control___6 ;
+19:__UG_NAME__ -> 101:envelope___control___7 ;
+100:__UG_NAME__ -> 101:gate ;
+79:__UG_NAME__ -> 103:envelope___mul____add___0 ;
+79:__UG_NAME__ -> 103:envelope___mul____add___4 ;
+21:__UG_NAME__ -> 103:envelope___control___5 ;
+22:__UG_NAME__ -> 103:envelope___control___6 ;
+23:__UG_NAME__ -> 103:envelope___control___7 ;
+87:__UG_NAME__ -> 103:gate ;
+4:__UG_NAME__ -> 105:envelope___control___0 ;
+4:__UG_NAME__ -> 105:envelope___control___4 ;
+5:__UG_NAME__ -> 105:envelope___control___5 ;
+6:__UG_NAME__ -> 105:envelope___control___6 ;
+7:__UG_NAME__ -> 105:envelope___control___7 ;
+77:__UG_NAME__ -> 105:gate ;
+8:__UG_NAME__ -> 27:in ;
+9:__UG_NAME__ -> 31:in ;
+12:__UG_NAME__ -> 41:in ;
+13:__UG_NAME__ -> 45:in ;
+0:__UG_NAME__ -> 57:in ;
+1:__UG_NAME__ -> 62:in ;
+4:__UG_NAME__ -> 70:in ;
+5:__UG_NAME__ -> 74:in ;
+79:__UG_NAME__ -> 80:in ;
+21:__UG_NAME__ -> 84:in ;
+16:__UG_NAME__ -> 88:in ;
+17:__UG_NAME__ -> 89:in ;
+24:__UG_NAME__ -> 36:bus ;
+101:__UG_NAME__ -> 102:a ;
+20:__UG_NAME__ -> 79:in ;
+25:__UG_NAME__ -> 117:bus ;
+108:__UG_NAME__ -> 117:signals___x____fade2___0 ;
+116:__UG_NAME__ -> 117:signals___x____fade2___1 ;
+56:__UG_NAME__ -> 104:in ;
+102:__UG_NAME__ -> 104:freq ;
+103:__UG_NAME__ -> 104:rq ;
+112:__UG_NAME__ -> 113:in ;
+102:__UG_NAME__ -> 113:freq ;
+103:__UG_NAME__ -> 113:rq ;
+38:__UG_NAME__ -> 39:a ;
+68:__UG_NAME__ -> 90:a ;
+37:__UG_NAME__ -> 108:ina ;
+104:__UG_NAME__ -> 108:inb ;
+107:__UG_NAME__ -> 108:pan ;
+66:__UG_NAME__ -> 108:level ;
+67:__UG_NAME__ -> 116:ina ;
+113:__UG_NAME__ -> 116:inb ;
+115:__UG_NAME__ -> 116:pan ;
+66:__UG_NAME__ -> 116:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_level.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_level.dot
new file mode 100644
index 0000000..aabc4d6
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_level.dot
@@ -0,0 +1,60 @@
+digraph synthdef {
+17 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+18 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+10 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+14 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+9 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+13 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+8 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+12 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+7 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+11 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+6 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+16 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+19 [label = "{{ {{<signals___binary____op____u____gen___0>|<signals___binary____op____u____gen___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+15:__UG_NAME__ -> 17:a ;
+16:__UG_NAME__ -> 17:b ;
+15:__UG_NAME__ -> 18:a ;
+16:__UG_NAME__ -> 18:b ;
+6:__UG_NAME__ -> 10:a ;
+9:__UG_NAME__ -> 10:b ;
+10:__UG_NAME__ -> 14:a ;
+13:__UG_NAME__ -> 14:b ;
+8:__UG_NAME__ -> 9:a ;
+12:__UG_NAME__ -> 13:a ;
+7:__UG_NAME__ -> 8:a ;
+11:__UG_NAME__ -> 12:a ;
+0:__UG_NAME__ -> 15:envelope___control___0 ;
+0:__UG_NAME__ -> 15:envelope___control___4 ;
+1:__UG_NAME__ -> 15:envelope___control___5 ;
+2:__UG_NAME__ -> 15:envelope___control___6 ;
+3:__UG_NAME__ -> 15:envelope___control___7 ;
+14:__UG_NAME__ -> 15:gate ;
+0:__UG_NAME__ -> 7:in ;
+1:__UG_NAME__ -> 11:in ;
+4:__UG_NAME__ -> 16:bus ;
+5:__UG_NAME__ -> 19:bus ;
+18:__UG_NAME__ -> 19:signals___binary____op____u____gen___0 ;
+17:__UG_NAME__ -> 19:signals___binary____op____u____gen___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_lpf.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_lpf.dot
new file mode 100644
index 0000000..30141a6
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_lpf.dot
@@ -0,0 +1,200 @@
+digraph synthdef {
+28 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+64 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+22 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+21 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+20 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+19 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+18 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+63 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+67 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+68 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+69 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+27:__UG_NAME__ -> 28:a ;
+59:__UG_NAME__ -> 61:a ;
+60:__UG_NAME__ -> 61:b ;
+27:__UG_NAME__ -> 64:a ;
+59:__UG_NAME__ -> 66:a ;
+60:__UG_NAME__ -> 66:b ;
+18:__UG_NAME__ -> 22:a ;
+21:__UG_NAME__ -> 22:b ;
+22:__UG_NAME__ -> 26:a ;
+25:__UG_NAME__ -> 26:b ;
+30:__UG_NAME__ -> 36:a ;
+35:__UG_NAME__ -> 36:b ;
+36:__UG_NAME__ -> 40:a ;
+39:__UG_NAME__ -> 40:b ;
+42:__UG_NAME__ -> 46:a ;
+45:__UG_NAME__ -> 46:b ;
+46:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+49:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+53:__UG_NAME__ -> 57:a ;
+56:__UG_NAME__ -> 57:b ;
+28:__UG_NAME__ -> 29:a ;
+64:__UG_NAME__ -> 65:a ;
+20:__UG_NAME__ -> 21:a ;
+24:__UG_NAME__ -> 25:a ;
+34:__UG_NAME__ -> 35:a ;
+38:__UG_NAME__ -> 39:a ;
+44:__UG_NAME__ -> 45:a ;
+32:__UG_NAME__ -> 47:a ;
+51:__UG_NAME__ -> 52:a ;
+55:__UG_NAME__ -> 56:a ;
+19:__UG_NAME__ -> 20:a ;
+23:__UG_NAME__ -> 24:a ;
+31:__UG_NAME__ -> 32:a ;
+33:__UG_NAME__ -> 34:a ;
+37:__UG_NAME__ -> 38:a ;
+43:__UG_NAME__ -> 44:a ;
+50:__UG_NAME__ -> 51:a ;
+54:__UG_NAME__ -> 55:a ;
+4:__UG_NAME__ -> 27:envelope___control___0 ;
+4:__UG_NAME__ -> 27:envelope___control___4 ;
+5:__UG_NAME__ -> 27:envelope___control___5 ;
+6:__UG_NAME__ -> 27:envelope___control___6 ;
+7:__UG_NAME__ -> 27:envelope___control___7 ;
+26:__UG_NAME__ -> 27:gate ;
+0:__UG_NAME__ -> 41:envelope___control___0 ;
+0:__UG_NAME__ -> 41:envelope___control___4 ;
+1:__UG_NAME__ -> 41:envelope___control___5 ;
+2:__UG_NAME__ -> 41:envelope___control___6 ;
+3:__UG_NAME__ -> 41:envelope___control___7 ;
+40:__UG_NAME__ -> 41:gate ;
+12:__UG_NAME__ -> 58:envelope___control___0 ;
+12:__UG_NAME__ -> 58:envelope___control___4 ;
+13:__UG_NAME__ -> 58:envelope___control___5 ;
+14:__UG_NAME__ -> 58:envelope___control___6 ;
+15:__UG_NAME__ -> 58:envelope___control___7 ;
+57:__UG_NAME__ -> 58:gate ;
+8:__UG_NAME__ -> 59:envelope___control___0 ;
+8:__UG_NAME__ -> 59:envelope___control___4 ;
+9:__UG_NAME__ -> 59:envelope___control___5 ;
+10:__UG_NAME__ -> 59:envelope___control___6 ;
+11:__UG_NAME__ -> 59:envelope___control___7 ;
+48:__UG_NAME__ -> 59:gate ;
+4:__UG_NAME__ -> 19:in ;
+5:__UG_NAME__ -> 23:in ;
+9:__UG_NAME__ -> 31:in ;
+0:__UG_NAME__ -> 33:in ;
+1:__UG_NAME__ -> 37:in ;
+8:__UG_NAME__ -> 43:in ;
+12:__UG_NAME__ -> 50:in ;
+13:__UG_NAME__ -> 54:in ;
+16:__UG_NAME__ -> 60:bus ;
+61:__UG_NAME__ -> 63:in ;
+62:__UG_NAME__ -> 63:freq ;
+66:__UG_NAME__ -> 67:in ;
+62:__UG_NAME__ -> 67:freq ;
+58:__UG_NAME__ -> 62:a ;
+17:__UG_NAME__ -> 70:bus ;
+69:__UG_NAME__ -> 70:signals___x____fade2___0 ;
+68:__UG_NAME__ -> 70:signals___x____fade2___1 ;
+66:__UG_NAME__ -> 68:ina ;
+67:__UG_NAME__ -> 68:inb ;
+29:__UG_NAME__ -> 68:pan ;
+41:__UG_NAME__ -> 68:level ;
+61:__UG_NAME__ -> 69:ina ;
+63:__UG_NAME__ -> 69:inb ;
+65:__UG_NAME__ -> 69:pan ;
+41:__UG_NAME__ -> 69:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_mono.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_mono.dot
new file mode 100644
index 0000000..44c798f
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_mono.dot
@@ -0,0 +1,155 @@
+digraph synthdef {
+47 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+18 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+30 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+17 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+21 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+16 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+20 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+15 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+19 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+14 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+53 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+46 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+49 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+52 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+23:__UG_NAME__ -> 47:a ;
+23:__UG_NAME__ -> 50:a ;
+14:__UG_NAME__ -> 18:a ;
+17:__UG_NAME__ -> 18:b ;
+18:__UG_NAME__ -> 22:a ;
+21:__UG_NAME__ -> 22:b ;
+24:__UG_NAME__ -> 25:a ;
+24:__UG_NAME__ -> 25:b ;
+26:__UG_NAME__ -> 30:a ;
+29:__UG_NAME__ -> 30:b ;
+30:__UG_NAME__ -> 34:a ;
+33:__UG_NAME__ -> 34:b ;
+36:__UG_NAME__ -> 40:a ;
+39:__UG_NAME__ -> 40:b ;
+40:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+47:__UG_NAME__ -> 48:a ;
+50:__UG_NAME__ -> 51:a ;
+16:__UG_NAME__ -> 17:a ;
+20:__UG_NAME__ -> 21:a ;
+28:__UG_NAME__ -> 29:a ;
+32:__UG_NAME__ -> 33:a ;
+38:__UG_NAME__ -> 39:a ;
+42:__UG_NAME__ -> 43:a ;
+15:__UG_NAME__ -> 16:a ;
+19:__UG_NAME__ -> 20:a ;
+27:__UG_NAME__ -> 28:a ;
+31:__UG_NAME__ -> 32:a ;
+37:__UG_NAME__ -> 38:a ;
+41:__UG_NAME__ -> 42:a ;
+4:__UG_NAME__ -> 23:envelope___control___0 ;
+4:__UG_NAME__ -> 23:envelope___control___4 ;
+5:__UG_NAME__ -> 23:envelope___control___5 ;
+6:__UG_NAME__ -> 23:envelope___control___6 ;
+7:__UG_NAME__ -> 23:envelope___control___7 ;
+22:__UG_NAME__ -> 23:gate ;
+8:__UG_NAME__ -> 35:envelope___control___0 ;
+8:__UG_NAME__ -> 35:envelope___control___4 ;
+9:__UG_NAME__ -> 35:envelope___control___5 ;
+10:__UG_NAME__ -> 35:envelope___control___6 ;
+11:__UG_NAME__ -> 35:envelope___control___7 ;
+34:__UG_NAME__ -> 35:gate ;
+0:__UG_NAME__ -> 45:envelope___control___0 ;
+0:__UG_NAME__ -> 45:envelope___control___4 ;
+1:__UG_NAME__ -> 45:envelope___control___5 ;
+2:__UG_NAME__ -> 45:envelope___control___6 ;
+3:__UG_NAME__ -> 45:envelope___control___7 ;
+44:__UG_NAME__ -> 45:gate ;
+4:__UG_NAME__ -> 15:in ;
+5:__UG_NAME__ -> 19:in ;
+8:__UG_NAME__ -> 27:in ;
+9:__UG_NAME__ -> 31:in ;
+0:__UG_NAME__ -> 37:in ;
+1:__UG_NAME__ -> 41:in ;
+12:__UG_NAME__ -> 24:bus ;
+13:__UG_NAME__ -> 53:bus ;
+49:__UG_NAME__ -> 53:signals___x____fade2___0 ;
+52:__UG_NAME__ -> 53:signals___x____fade2___1 ;
+25:__UG_NAME__ -> 46:in ;
+35:__UG_NAME__ -> 46:pos ;
+45:__UG_NAME__ -> 46:level ;
+24:__UG_NAME__ -> 49:ina ;
+46:__UG_NAME__ -> 49:inb ;
+48:__UG_NAME__ -> 49:pan ;
+45:__UG_NAME__ -> 49:level ;
+24:__UG_NAME__ -> 52:ina ;
+46:__UG_NAME__ -> 52:inb ;
+51:__UG_NAME__ -> 52:pan ;
+45:__UG_NAME__ -> 52:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_nhpf.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_nhpf.dot
new file mode 100644
index 0000000..436d89d
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_nhpf.dot
@@ -0,0 +1,204 @@
+digraph synthdef {
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+60 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+21 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+20 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+49 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+19 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+18 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+50 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+72 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+68 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+71 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+27:__UG_NAME__ -> 29:a ;
+28:__UG_NAME__ -> 29:b ;
+27:__UG_NAME__ -> 48:a ;
+28:__UG_NAME__ -> 48:b ;
+59:__UG_NAME__ -> 60:a ;
+59:__UG_NAME__ -> 69:a ;
+18:__UG_NAME__ -> 22:a ;
+21:__UG_NAME__ -> 22:b ;
+22:__UG_NAME__ -> 26:a ;
+25:__UG_NAME__ -> 26:b ;
+30:__UG_NAME__ -> 34:a ;
+33:__UG_NAME__ -> 34:b ;
+34:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+51:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+54:__UG_NAME__ -> 58:a ;
+57:__UG_NAME__ -> 58:b ;
+62:__UG_NAME__ -> 64:a ;
+63:__UG_NAME__ -> 64:b ;
+64:__UG_NAME__ -> 66:a ;
+65:__UG_NAME__ -> 66:b ;
+60:__UG_NAME__ -> 61:a ;
+69:__UG_NAME__ -> 70:a ;
+20:__UG_NAME__ -> 21:a ;
+24:__UG_NAME__ -> 25:a ;
+32:__UG_NAME__ -> 33:a ;
+36:__UG_NAME__ -> 37:a ;
+52:__UG_NAME__ -> 53:a ;
+56:__UG_NAME__ -> 57:a ;
+44:__UG_NAME__ -> 63:a ;
+46:__UG_NAME__ -> 65:a ;
+19:__UG_NAME__ -> 20:a ;
+23:__UG_NAME__ -> 24:a ;
+31:__UG_NAME__ -> 32:a ;
+35:__UG_NAME__ -> 36:a ;
+43:__UG_NAME__ -> 44:a ;
+45:__UG_NAME__ -> 46:a ;
+47:__UG_NAME__ -> 52:a ;
+55:__UG_NAME__ -> 56:a ;
+8:__UG_NAME__ -> 27:envelope___control___0 ;
+8:__UG_NAME__ -> 27:envelope___control___4 ;
+9:__UG_NAME__ -> 27:envelope___control___5 ;
+10:__UG_NAME__ -> 27:envelope___control___6 ;
+11:__UG_NAME__ -> 27:envelope___control___7 ;
+26:__UG_NAME__ -> 27:gate ;
+12:__UG_NAME__ -> 39:envelope___control___0 ;
+12:__UG_NAME__ -> 39:envelope___control___4 ;
+13:__UG_NAME__ -> 39:envelope___control___5 ;
+14:__UG_NAME__ -> 39:envelope___control___6 ;
+15:__UG_NAME__ -> 39:envelope___control___7 ;
+38:__UG_NAME__ -> 39:gate ;
+4:__UG_NAME__ -> 59:envelope___control___0 ;
+4:__UG_NAME__ -> 59:envelope___control___4 ;
+5:__UG_NAME__ -> 59:envelope___control___5 ;
+6:__UG_NAME__ -> 59:envelope___control___6 ;
+7:__UG_NAME__ -> 59:envelope___control___7 ;
+58:__UG_NAME__ -> 59:gate ;
+0:__UG_NAME__ -> 67:envelope___control___0 ;
+0:__UG_NAME__ -> 67:envelope___control___4 ;
+1:__UG_NAME__ -> 67:envelope___control___5 ;
+2:__UG_NAME__ -> 67:envelope___control___6 ;
+3:__UG_NAME__ -> 67:envelope___control___7 ;
+66:__UG_NAME__ -> 67:gate ;
+29:__UG_NAME__ -> 41:in ;
+40:__UG_NAME__ -> 41:freq ;
+48:__UG_NAME__ -> 49:in ;
+40:__UG_NAME__ -> 49:freq ;
+8:__UG_NAME__ -> 19:in ;
+9:__UG_NAME__ -> 23:in ;
+12:__UG_NAME__ -> 31:in ;
+13:__UG_NAME__ -> 35:in ;
+0:__UG_NAME__ -> 43:in ;
+1:__UG_NAME__ -> 45:in ;
+4:__UG_NAME__ -> 47:in ;
+5:__UG_NAME__ -> 55:in ;
+16:__UG_NAME__ -> 28:bus ;
+39:__UG_NAME__ -> 40:a ;
+41:__UG_NAME__ -> 42:in ;
+49:__UG_NAME__ -> 50:in ;
+17:__UG_NAME__ -> 72:bus ;
+71:__UG_NAME__ -> 72:signals___x____fade2___0 ;
+68:__UG_NAME__ -> 72:signals___x____fade2___1 ;
+48:__UG_NAME__ -> 68:ina ;
+50:__UG_NAME__ -> 68:inb ;
+61:__UG_NAME__ -> 68:pan ;
+67:__UG_NAME__ -> 68:level ;
+29:__UG_NAME__ -> 71:ina ;
+42:__UG_NAME__ -> 71:inb ;
+70:__UG_NAME__ -> 71:pan ;
+67:__UG_NAME__ -> 71:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_nlpf.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_nlpf.dot
new file mode 100644
index 0000000..1b39fd3
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_nlpf.dot
@@ -0,0 +1,204 @@
+digraph synthdef {
+28 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+69 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+21 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+20 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+19 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+18 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+53 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+67 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+68 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+72 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+65 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+71 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+27:__UG_NAME__ -> 28:a ;
+49:__UG_NAME__ -> 51:a ;
+50:__UG_NAME__ -> 51:b ;
+49:__UG_NAME__ -> 66:a ;
+50:__UG_NAME__ -> 66:b ;
+27:__UG_NAME__ -> 69:a ;
+18:__UG_NAME__ -> 22:a ;
+21:__UG_NAME__ -> 22:b ;
+22:__UG_NAME__ -> 26:a ;
+25:__UG_NAME__ -> 26:b ;
+29:__UG_NAME__ -> 33:a ;
+32:__UG_NAME__ -> 33:b ;
+33:__UG_NAME__ -> 37:a ;
+36:__UG_NAME__ -> 37:b ;
+40:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+44:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+55:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+59:__UG_NAME__ -> 63:a ;
+62:__UG_NAME__ -> 63:b ;
+28:__UG_NAME__ -> 38:a ;
+69:__UG_NAME__ -> 70:a ;
+20:__UG_NAME__ -> 21:a ;
+24:__UG_NAME__ -> 25:a ;
+31:__UG_NAME__ -> 32:a ;
+35:__UG_NAME__ -> 36:a ;
+42:__UG_NAME__ -> 43:a ;
+46:__UG_NAME__ -> 47:a ;
+57:__UG_NAME__ -> 58:a ;
+61:__UG_NAME__ -> 62:a ;
+19:__UG_NAME__ -> 20:a ;
+23:__UG_NAME__ -> 24:a ;
+30:__UG_NAME__ -> 31:a ;
+34:__UG_NAME__ -> 35:a ;
+41:__UG_NAME__ -> 42:a ;
+45:__UG_NAME__ -> 46:a ;
+56:__UG_NAME__ -> 57:a ;
+60:__UG_NAME__ -> 61:a ;
+4:__UG_NAME__ -> 27:envelope___control___0 ;
+4:__UG_NAME__ -> 27:envelope___control___4 ;
+5:__UG_NAME__ -> 27:envelope___control___5 ;
+6:__UG_NAME__ -> 27:envelope___control___6 ;
+7:__UG_NAME__ -> 27:envelope___control___7 ;
+26:__UG_NAME__ -> 27:gate ;
+12:__UG_NAME__ -> 39:envelope___control___0 ;
+12:__UG_NAME__ -> 39:envelope___control___4 ;
+13:__UG_NAME__ -> 39:envelope___control___5 ;
+14:__UG_NAME__ -> 39:envelope___control___6 ;
+15:__UG_NAME__ -> 39:envelope___control___7 ;
+37:__UG_NAME__ -> 39:gate ;
+8:__UG_NAME__ -> 49:envelope___control___0 ;
+8:__UG_NAME__ -> 49:envelope___control___4 ;
+9:__UG_NAME__ -> 49:envelope___control___5 ;
+10:__UG_NAME__ -> 49:envelope___control___6 ;
+11:__UG_NAME__ -> 49:envelope___control___7 ;
+48:__UG_NAME__ -> 49:gate ;
+0:__UG_NAME__ -> 64:envelope___control___0 ;
+0:__UG_NAME__ -> 64:envelope___control___4 ;
+1:__UG_NAME__ -> 64:envelope___control___5 ;
+2:__UG_NAME__ -> 64:envelope___control___6 ;
+3:__UG_NAME__ -> 64:envelope___control___7 ;
+63:__UG_NAME__ -> 64:gate ;
+4:__UG_NAME__ -> 19:in ;
+5:__UG_NAME__ -> 23:in ;
+12:__UG_NAME__ -> 30:in ;
+13:__UG_NAME__ -> 34:in ;
+8:__UG_NAME__ -> 41:in ;
+9:__UG_NAME__ -> 45:in ;
+0:__UG_NAME__ -> 56:in ;
+1:__UG_NAME__ -> 60:in ;
+16:__UG_NAME__ -> 50:bus ;
+51:__UG_NAME__ -> 53:in ;
+52:__UG_NAME__ -> 53:freq ;
+66:__UG_NAME__ -> 67:in ;
+52:__UG_NAME__ -> 67:freq ;
+39:__UG_NAME__ -> 52:a ;
+53:__UG_NAME__ -> 54:in ;
+67:__UG_NAME__ -> 68:in ;
+17:__UG_NAME__ -> 72:bus ;
+71:__UG_NAME__ -> 72:signals___x____fade2___0 ;
+65:__UG_NAME__ -> 72:signals___x____fade2___1 ;
+51:__UG_NAME__ -> 65:ina ;
+54:__UG_NAME__ -> 65:inb ;
+38:__UG_NAME__ -> 65:pan ;
+64:__UG_NAME__ -> 65:level ;
+66:__UG_NAME__ -> 71:ina ;
+68:__UG_NAME__ -> 71:inb ;
+70:__UG_NAME__ -> 71:pan ;
+64:__UG_NAME__ -> 71:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_normaliser.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_normaliser.dot
new file mode 100644
index 0000000..25dc3e3
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_normaliser.dot
@@ -0,0 +1,198 @@
+digraph synthdef {
+31 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+66 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+20 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+19 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :level_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :level_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :level_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+18 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+21 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+61 [label = "{{ <dur> dur 0.01|<level> level|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+65 [label = "{{ <dur> dur 0.01|<level> level|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+69 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+63 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+68 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+30:__UG_NAME__ -> 31:a ;
+51:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+51:__UG_NAME__ -> 64:a ;
+52:__UG_NAME__ -> 64:b ;
+30:__UG_NAME__ -> 66:a ;
+21:__UG_NAME__ -> 25:a ;
+24:__UG_NAME__ -> 25:b ;
+25:__UG_NAME__ -> 29:a ;
+28:__UG_NAME__ -> 29:b ;
+33:__UG_NAME__ -> 37:a ;
+36:__UG_NAME__ -> 37:b ;
+37:__UG_NAME__ -> 41:a ;
+40:__UG_NAME__ -> 41:b ;
+45:__UG_NAME__ -> 46:a ;
+44:__UG_NAME__ -> 46:b ;
+46:__UG_NAME__ -> 50:a ;
+49:__UG_NAME__ -> 50:b ;
+54:__UG_NAME__ -> 58:a ;
+57:__UG_NAME__ -> 58:b ;
+58:__UG_NAME__ -> 59:a ;
+20:__UG_NAME__ -> 59:b ;
+31:__UG_NAME__ -> 32:a ;
+66:__UG_NAME__ -> 67:a ;
+19:__UG_NAME__ -> 20:a ;
+23:__UG_NAME__ -> 24:a ;
+27:__UG_NAME__ -> 28:a ;
+35:__UG_NAME__ -> 36:a ;
+39:__UG_NAME__ -> 40:a ;
+43:__UG_NAME__ -> 44:a ;
+48:__UG_NAME__ -> 49:a ;
+56:__UG_NAME__ -> 57:a ;
+18:__UG_NAME__ -> 19:a ;
+22:__UG_NAME__ -> 23:a ;
+26:__UG_NAME__ -> 27:a ;
+34:__UG_NAME__ -> 35:a ;
+38:__UG_NAME__ -> 39:a ;
+42:__UG_NAME__ -> 43:a ;
+47:__UG_NAME__ -> 48:a ;
+55:__UG_NAME__ -> 56:a ;
+4:__UG_NAME__ -> 30:envelope___control___0 ;
+4:__UG_NAME__ -> 30:envelope___control___4 ;
+5:__UG_NAME__ -> 30:envelope___control___5 ;
+6:__UG_NAME__ -> 30:envelope___control___6 ;
+7:__UG_NAME__ -> 30:envelope___control___7 ;
+29:__UG_NAME__ -> 30:gate ;
+8:__UG_NAME__ -> 51:envelope___control___0 ;
+8:__UG_NAME__ -> 51:envelope___control___4 ;
+9:__UG_NAME__ -> 51:envelope___control___5 ;
+10:__UG_NAME__ -> 51:envelope___control___6 ;
+11:__UG_NAME__ -> 51:envelope___control___7 ;
+50:__UG_NAME__ -> 51:gate ;
+12:__UG_NAME__ -> 60:envelope___control___0 ;
+12:__UG_NAME__ -> 60:envelope___control___4 ;
+13:__UG_NAME__ -> 60:envelope___control___5 ;
+14:__UG_NAME__ -> 60:envelope___control___6 ;
+15:__UG_NAME__ -> 60:envelope___control___7 ;
+59:__UG_NAME__ -> 60:gate ;
+0:__UG_NAME__ -> 62:envelope___control___0 ;
+0:__UG_NAME__ -> 62:envelope___control___4 ;
+1:__UG_NAME__ -> 62:envelope___control___5 ;
+2:__UG_NAME__ -> 62:envelope___control___6 ;
+3:__UG_NAME__ -> 62:envelope___control___7 ;
+41:__UG_NAME__ -> 62:gate ;
+13:__UG_NAME__ -> 18:in ;
+4:__UG_NAME__ -> 22:in ;
+5:__UG_NAME__ -> 26:in ;
+0:__UG_NAME__ -> 34:in ;
+1:__UG_NAME__ -> 38:in ;
+8:__UG_NAME__ -> 42:in ;
+9:__UG_NAME__ -> 47:in ;
+12:__UG_NAME__ -> 55:in ;
+16:__UG_NAME__ -> 52:bus ;
+53:__UG_NAME__ -> 61:in ;
+60:__UG_NAME__ -> 61:level ;
+64:__UG_NAME__ -> 65:in ;
+60:__UG_NAME__ -> 65:level ;
+17:__UG_NAME__ -> 69:bus ;
+68:__UG_NAME__ -> 69:signals___x____fade2___0 ;
+63:__UG_NAME__ -> 69:signals___x____fade2___1 ;
+53:__UG_NAME__ -> 63:ina ;
+61:__UG_NAME__ -> 63:inb ;
+32:__UG_NAME__ -> 63:pan ;
+62:__UG_NAME__ -> 63:level ;
+64:__UG_NAME__ -> 68:ina ;
+65:__UG_NAME__ -> 68:inb ;
+67:__UG_NAME__ -> 68:pan ;
+62:__UG_NAME__ -> 68:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_nrbpf.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_nrbpf.dot
new file mode 100644
index 0000000..da46ad0
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_nrbpf.dot
@@ -0,0 +1,246 @@
+digraph synthdef {
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+71 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :centre
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :centre_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :centre_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :centre_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :res
+ default: 0.6" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+85 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+87 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+57 [label = "{{ <bwr> bwr|<freq> freq|<in> in} |<__UG_NAME__>resonz }" style="filled, bold, rounded"  shape=record rankdir=LR];
+59 [label = "{{ <bwr> bwr|<freq> freq|<in> in} |<__UG_NAME__>resonz }" style="filled, bold, rounded"  shape=record rankdir=LR];
+82 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+86 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+32:__UG_NAME__ -> 34:a ;
+33:__UG_NAME__ -> 34:b ;
+32:__UG_NAME__ -> 58:a ;
+33:__UG_NAME__ -> 58:b ;
+70:__UG_NAME__ -> 71:a ;
+70:__UG_NAME__ -> 83:a ;
+23:__UG_NAME__ -> 27:a ;
+26:__UG_NAME__ -> 27:b ;
+27:__UG_NAME__ -> 31:a ;
+30:__UG_NAME__ -> 31:b ;
+35:__UG_NAME__ -> 39:a ;
+38:__UG_NAME__ -> 39:b ;
+39:__UG_NAME__ -> 43:a ;
+42:__UG_NAME__ -> 43:b ;
+46:__UG_NAME__ -> 51:a ;
+50:__UG_NAME__ -> 51:b ;
+51:__UG_NAME__ -> 55:a ;
+54:__UG_NAME__ -> 55:b ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+65:__UG_NAME__ -> 69:a ;
+68:__UG_NAME__ -> 69:b ;
+73:__UG_NAME__ -> 77:a ;
+76:__UG_NAME__ -> 77:b ;
+77:__UG_NAME__ -> 80:a ;
+79:__UG_NAME__ -> 80:b ;
+71:__UG_NAME__ -> 72:a ;
+83:__UG_NAME__ -> 84:a ;
+25:__UG_NAME__ -> 26:a ;
+29:__UG_NAME__ -> 30:a ;
+37:__UG_NAME__ -> 38:a ;
+41:__UG_NAME__ -> 42:a ;
+49:__UG_NAME__ -> 50:a ;
+53:__UG_NAME__ -> 54:a ;
+63:__UG_NAME__ -> 64:a ;
+67:__UG_NAME__ -> 68:a ;
+75:__UG_NAME__ -> 76:a ;
+78:__UG_NAME__ -> 79:a ;
+24:__UG_NAME__ -> 25:a ;
+28:__UG_NAME__ -> 29:a ;
+36:__UG_NAME__ -> 37:a ;
+40:__UG_NAME__ -> 41:a ;
+48:__UG_NAME__ -> 49:a ;
+52:__UG_NAME__ -> 53:a ;
+62:__UG_NAME__ -> 63:a ;
+66:__UG_NAME__ -> 67:a ;
+74:__UG_NAME__ -> 75:a ;
+22:__UG_NAME__ -> 78:a ;
+8:__UG_NAME__ -> 32:envelope___control___0 ;
+8:__UG_NAME__ -> 32:envelope___control___4 ;
+9:__UG_NAME__ -> 32:envelope___control___5 ;
+10:__UG_NAME__ -> 32:envelope___control___6 ;
+11:__UG_NAME__ -> 32:envelope___control___7 ;
+31:__UG_NAME__ -> 32:gate ;
+12:__UG_NAME__ -> 44:envelope___control___0 ;
+12:__UG_NAME__ -> 44:envelope___control___4 ;
+13:__UG_NAME__ -> 44:envelope___control___5 ;
+14:__UG_NAME__ -> 44:envelope___control___6 ;
+15:__UG_NAME__ -> 44:envelope___control___7 ;
+43:__UG_NAME__ -> 44:gate ;
+47:__UG_NAME__ -> 56:envelope___mul____add___0 ;
+47:__UG_NAME__ -> 56:envelope___mul____add___4 ;
+17:__UG_NAME__ -> 56:envelope___control___5 ;
+18:__UG_NAME__ -> 56:envelope___control___6 ;
+19:__UG_NAME__ -> 56:envelope___control___7 ;
+55:__UG_NAME__ -> 56:gate ;
+4:__UG_NAME__ -> 70:envelope___control___0 ;
+4:__UG_NAME__ -> 70:envelope___control___4 ;
+5:__UG_NAME__ -> 70:envelope___control___5 ;
+6:__UG_NAME__ -> 70:envelope___control___6 ;
+7:__UG_NAME__ -> 70:envelope___control___7 ;
+69:__UG_NAME__ -> 70:gate ;
+0:__UG_NAME__ -> 81:envelope___control___0 ;
+0:__UG_NAME__ -> 81:envelope___control___4 ;
+1:__UG_NAME__ -> 81:envelope___control___5 ;
+2:__UG_NAME__ -> 81:envelope___control___6 ;
+3:__UG_NAME__ -> 81:envelope___control___7 ;
+80:__UG_NAME__ -> 81:gate ;
+1:__UG_NAME__ -> 22:in ;
+8:__UG_NAME__ -> 24:in ;
+9:__UG_NAME__ -> 28:in ;
+12:__UG_NAME__ -> 36:in ;
+13:__UG_NAME__ -> 40:in ;
+47:__UG_NAME__ -> 48:in ;
+17:__UG_NAME__ -> 52:in ;
+4:__UG_NAME__ -> 62:in ;
+5:__UG_NAME__ -> 66:in ;
+0:__UG_NAME__ -> 74:in ;
+20:__UG_NAME__ -> 33:bus ;
+44:__UG_NAME__ -> 45:a ;
+16:__UG_NAME__ -> 47:in ;
+59:__UG_NAME__ -> 60:in ;
+57:__UG_NAME__ -> 85:in ;
+21:__UG_NAME__ -> 87:bus ;
+82:__UG_NAME__ -> 87:signals___x____fade2___0 ;
+86:__UG_NAME__ -> 87:signals___x____fade2___1 ;
+34:__UG_NAME__ -> 57:in ;
+45:__UG_NAME__ -> 57:freq ;
+56:__UG_NAME__ -> 57:bwr ;
+58:__UG_NAME__ -> 59:in ;
+45:__UG_NAME__ -> 59:freq ;
+56:__UG_NAME__ -> 59:bwr ;
+58:__UG_NAME__ -> 82:ina ;
+60:__UG_NAME__ -> 82:inb ;
+72:__UG_NAME__ -> 82:pan ;
+81:__UG_NAME__ -> 82:level ;
+34:__UG_NAME__ -> 86:ina ;
+85:__UG_NAME__ -> 86:inb ;
+84:__UG_NAME__ -> 86:pan ;
+81:__UG_NAME__ -> 86:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_nrhpf.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_nrhpf.dot
new file mode 100644
index 0000000..96af779
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_nrhpf.dot
@@ -0,0 +1,244 @@
+digraph synthdef {
+70 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+79 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :res
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+55 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+78 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+86 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+74 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rhpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+77 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rhpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+82 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+85 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+68:__UG_NAME__ -> 70:a ;
+69:__UG_NAME__ -> 70:b ;
+68:__UG_NAME__ -> 76:a ;
+69:__UG_NAME__ -> 76:b ;
+55:__UG_NAME__ -> 79:a ;
+55:__UG_NAME__ -> 83:a ;
+22:__UG_NAME__ -> 26:a ;
+25:__UG_NAME__ -> 26:b ;
+26:__UG_NAME__ -> 30:a ;
+29:__UG_NAME__ -> 30:b ;
+32:__UG_NAME__ -> 36:a ;
+35:__UG_NAME__ -> 36:b ;
+36:__UG_NAME__ -> 40:a ;
+39:__UG_NAME__ -> 40:b ;
+48:__UG_NAME__ -> 52:a ;
+51:__UG_NAME__ -> 52:b ;
+52:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+56:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+59:__UG_NAME__ -> 60:a ;
+43:__UG_NAME__ -> 60:b ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+65:__UG_NAME__ -> 67:a ;
+66:__UG_NAME__ -> 67:b ;
+79:__UG_NAME__ -> 80:a ;
+83:__UG_NAME__ -> 84:a ;
+24:__UG_NAME__ -> 25:a ;
+28:__UG_NAME__ -> 29:a ;
+34:__UG_NAME__ -> 35:a ;
+38:__UG_NAME__ -> 39:a ;
+42:__UG_NAME__ -> 43:a ;
+50:__UG_NAME__ -> 51:a ;
+45:__UG_NAME__ -> 53:a ;
+57:__UG_NAME__ -> 58:a ;
+63:__UG_NAME__ -> 64:a ;
+47:__UG_NAME__ -> 66:a ;
+23:__UG_NAME__ -> 24:a ;
+27:__UG_NAME__ -> 28:a ;
+33:__UG_NAME__ -> 34:a ;
+37:__UG_NAME__ -> 38:a ;
+41:__UG_NAME__ -> 42:a ;
+44:__UG_NAME__ -> 45:a ;
+46:__UG_NAME__ -> 47:a ;
+49:__UG_NAME__ -> 50:a ;
+31:__UG_NAME__ -> 57:a ;
+62:__UG_NAME__ -> 63:a ;
+4:__UG_NAME__ -> 55:envelope___control___0 ;
+4:__UG_NAME__ -> 55:envelope___control___4 ;
+5:__UG_NAME__ -> 55:envelope___control___5 ;
+6:__UG_NAME__ -> 55:envelope___control___6 ;
+7:__UG_NAME__ -> 55:envelope___control___7 ;
+54:__UG_NAME__ -> 55:gate ;
+8:__UG_NAME__ -> 68:envelope___control___0 ;
+8:__UG_NAME__ -> 68:envelope___control___4 ;
+9:__UG_NAME__ -> 68:envelope___control___5 ;
+10:__UG_NAME__ -> 68:envelope___control___6 ;
+11:__UG_NAME__ -> 68:envelope___control___7 ;
+67:__UG_NAME__ -> 68:gate ;
+12:__UG_NAME__ -> 71:envelope___control___0 ;
+12:__UG_NAME__ -> 71:envelope___control___4 ;
+13:__UG_NAME__ -> 71:envelope___control___5 ;
+14:__UG_NAME__ -> 71:envelope___control___6 ;
+15:__UG_NAME__ -> 71:envelope___control___7 ;
+30:__UG_NAME__ -> 71:gate ;
+16:__UG_NAME__ -> 73:envelope___control___0 ;
+16:__UG_NAME__ -> 73:envelope___control___4 ;
+17:__UG_NAME__ -> 73:envelope___control___5 ;
+18:__UG_NAME__ -> 73:envelope___control___6 ;
+19:__UG_NAME__ -> 73:envelope___control___7 ;
+40:__UG_NAME__ -> 73:gate ;
+0:__UG_NAME__ -> 81:envelope___control___0 ;
+0:__UG_NAME__ -> 81:envelope___control___4 ;
+1:__UG_NAME__ -> 81:envelope___control___5 ;
+2:__UG_NAME__ -> 81:envelope___control___6 ;
+3:__UG_NAME__ -> 81:envelope___control___7 ;
+60:__UG_NAME__ -> 81:gate ;
+12:__UG_NAME__ -> 23:in ;
+13:__UG_NAME__ -> 27:in ;
+0:__UG_NAME__ -> 31:in ;
+16:__UG_NAME__ -> 33:in ;
+17:__UG_NAME__ -> 37:in ;
+1:__UG_NAME__ -> 41:in ;
+5:__UG_NAME__ -> 44:in ;
+9:__UG_NAME__ -> 46:in ;
+4:__UG_NAME__ -> 49:in ;
+8:__UG_NAME__ -> 62:in ;
+20:__UG_NAME__ -> 69:bus ;
+71:__UG_NAME__ -> 72:a ;
+74:__UG_NAME__ -> 75:in ;
+77:__UG_NAME__ -> 78:in ;
+21:__UG_NAME__ -> 86:bus ;
+85:__UG_NAME__ -> 86:signals___x____fade2___0 ;
+82:__UG_NAME__ -> 86:signals___x____fade2___1 ;
+70:__UG_NAME__ -> 74:in ;
+72:__UG_NAME__ -> 74:freq ;
+73:__UG_NAME__ -> 74:rq ;
+76:__UG_NAME__ -> 77:in ;
+72:__UG_NAME__ -> 77:freq ;
+73:__UG_NAME__ -> 77:rq ;
+76:__UG_NAME__ -> 82:ina ;
+78:__UG_NAME__ -> 82:inb ;
+80:__UG_NAME__ -> 82:pan ;
+81:__UG_NAME__ -> 82:level ;
+70:__UG_NAME__ -> 85:ina ;
+75:__UG_NAME__ -> 85:inb ;
+84:__UG_NAME__ -> 85:pan ;
+81:__UG_NAME__ -> 85:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_nrlpf.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_nrlpf.dot
new file mode 100644
index 0000000..94aaa11
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_nrlpf.dot
@@ -0,0 +1,246 @@
+digraph synthdef {
+32 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+84 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :res
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+83 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+87 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+67 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+82 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+80 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+86 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+31:__UG_NAME__ -> 32:a ;
+42:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+42:__UG_NAME__ -> 81:a ;
+43:__UG_NAME__ -> 81:b ;
+31:__UG_NAME__ -> 84:a ;
+22:__UG_NAME__ -> 26:a ;
+25:__UG_NAME__ -> 26:b ;
+26:__UG_NAME__ -> 30:a ;
+29:__UG_NAME__ -> 30:b ;
+33:__UG_NAME__ -> 37:a ;
+36:__UG_NAME__ -> 37:b ;
+37:__UG_NAME__ -> 41:a ;
+40:__UG_NAME__ -> 41:b ;
+45:__UG_NAME__ -> 49:a ;
+48:__UG_NAME__ -> 49:b ;
+49:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+56:__UG_NAME__ -> 61:a ;
+60:__UG_NAME__ -> 61:b ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+70:__UG_NAME__ -> 74:a ;
+73:__UG_NAME__ -> 74:b ;
+74:__UG_NAME__ -> 78:a ;
+77:__UG_NAME__ -> 78:b ;
+32:__UG_NAME__ -> 69:a ;
+84:__UG_NAME__ -> 85:a ;
+24:__UG_NAME__ -> 25:a ;
+28:__UG_NAME__ -> 29:a ;
+35:__UG_NAME__ -> 36:a ;
+39:__UG_NAME__ -> 40:a ;
+47:__UG_NAME__ -> 48:a ;
+51:__UG_NAME__ -> 52:a ;
+59:__UG_NAME__ -> 60:a ;
+63:__UG_NAME__ -> 64:a ;
+72:__UG_NAME__ -> 73:a ;
+76:__UG_NAME__ -> 77:a ;
+23:__UG_NAME__ -> 24:a ;
+27:__UG_NAME__ -> 28:a ;
+34:__UG_NAME__ -> 35:a ;
+38:__UG_NAME__ -> 39:a ;
+46:__UG_NAME__ -> 47:a ;
+50:__UG_NAME__ -> 51:a ;
+58:__UG_NAME__ -> 59:a ;
+62:__UG_NAME__ -> 63:a ;
+71:__UG_NAME__ -> 72:a ;
+75:__UG_NAME__ -> 76:a ;
+4:__UG_NAME__ -> 31:envelope___control___0 ;
+4:__UG_NAME__ -> 31:envelope___control___4 ;
+5:__UG_NAME__ -> 31:envelope___control___5 ;
+6:__UG_NAME__ -> 31:envelope___control___6 ;
+7:__UG_NAME__ -> 31:envelope___control___7 ;
+30:__UG_NAME__ -> 31:gate ;
+8:__UG_NAME__ -> 42:envelope___control___0 ;
+8:__UG_NAME__ -> 42:envelope___control___4 ;
+9:__UG_NAME__ -> 42:envelope___control___5 ;
+10:__UG_NAME__ -> 42:envelope___control___6 ;
+11:__UG_NAME__ -> 42:envelope___control___7 ;
+41:__UG_NAME__ -> 42:gate ;
+12:__UG_NAME__ -> 54:envelope___control___0 ;
+12:__UG_NAME__ -> 54:envelope___control___4 ;
+13:__UG_NAME__ -> 54:envelope___control___5 ;
+14:__UG_NAME__ -> 54:envelope___control___6 ;
+15:__UG_NAME__ -> 54:envelope___control___7 ;
+53:__UG_NAME__ -> 54:gate ;
+57:__UG_NAME__ -> 66:envelope___mul____add___0 ;
+57:__UG_NAME__ -> 66:envelope___mul____add___4 ;
+17:__UG_NAME__ -> 66:envelope___control___5 ;
+18:__UG_NAME__ -> 66:envelope___control___6 ;
+19:__UG_NAME__ -> 66:envelope___control___7 ;
+65:__UG_NAME__ -> 66:gate ;
+0:__UG_NAME__ -> 79:envelope___control___0 ;
+0:__UG_NAME__ -> 79:envelope___control___4 ;
+1:__UG_NAME__ -> 79:envelope___control___5 ;
+2:__UG_NAME__ -> 79:envelope___control___6 ;
+3:__UG_NAME__ -> 79:envelope___control___7 ;
+78:__UG_NAME__ -> 79:gate ;
+4:__UG_NAME__ -> 23:in ;
+5:__UG_NAME__ -> 27:in ;
+8:__UG_NAME__ -> 34:in ;
+9:__UG_NAME__ -> 38:in ;
+12:__UG_NAME__ -> 46:in ;
+13:__UG_NAME__ -> 50:in ;
+57:__UG_NAME__ -> 58:in ;
+17:__UG_NAME__ -> 62:in ;
+0:__UG_NAME__ -> 71:in ;
+1:__UG_NAME__ -> 75:in ;
+20:__UG_NAME__ -> 43:bus ;
+54:__UG_NAME__ -> 55:a ;
+16:__UG_NAME__ -> 57:in ;
+67:__UG_NAME__ -> 68:in ;
+82:__UG_NAME__ -> 83:in ;
+21:__UG_NAME__ -> 87:bus ;
+80:__UG_NAME__ -> 87:signals___x____fade2___0 ;
+86:__UG_NAME__ -> 87:signals___x____fade2___1 ;
+44:__UG_NAME__ -> 67:in ;
+55:__UG_NAME__ -> 67:freq ;
+66:__UG_NAME__ -> 67:rq ;
+81:__UG_NAME__ -> 82:in ;
+55:__UG_NAME__ -> 82:freq ;
+66:__UG_NAME__ -> 82:rq ;
+44:__UG_NAME__ -> 80:ina ;
+68:__UG_NAME__ -> 80:inb ;
+69:__UG_NAME__ -> 80:pan ;
+79:__UG_NAME__ -> 80:level ;
+81:__UG_NAME__ -> 86:ina ;
+83:__UG_NAME__ -> 86:inb ;
+85:__UG_NAME__ -> 86:pan ;
+79:__UG_NAME__ -> 86:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_octaver.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_octaver.dot
new file mode 100644
index 0000000..0c0d823
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_octaver.dot
@@ -0,0 +1,354 @@
+digraph synthdef {
+71 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+92 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+94 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+98 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+106 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+109 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+110 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+113 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+116 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+117 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+119 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+120 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+121 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+122 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+99 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+103 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+126 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+73 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
+86 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :super_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :super_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :super_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :super_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :sub_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :sub_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :sub_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :sub_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :subsub_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :subsub_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :subsub_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :subsub_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+118 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+80 [label = "{{ <coef> coef 0.995|<in> in} |<__UG_NAME__>leak-dc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+115 [label = "{{ <coef> coef 0.995|<in> in} |<__UG_NAME__>leak-dc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+78 [label = "{{ <freq> freq 440.0|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+107 [label = "{{ <freq> freq 440.0|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+128 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+91 [label = "{{ <trig> trig} |<__UG_NAME__>toggle-ff }" style="filled, bold, rounded"  shape=record rankdir=LR];
+96 [label = "{{ <trig> trig} |<__UG_NAME__>toggle-ff }" style="filled, bold, rounded"  shape=record rankdir=LR];
+108 [label = "{{ <trig> trig} |<__UG_NAME__>toggle-ff }" style="filled, bold, rounded"  shape=record rankdir=LR];
+111 [label = "{{ <trig> trig} |<__UG_NAME__>toggle-ff }" style="filled, bold, rounded"  shape=record rankdir=LR];
+124 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+127 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+70:__UG_NAME__ -> 71:a ;
+60:__UG_NAME__ -> 77:a ;
+76:__UG_NAME__ -> 77:b ;
+80:__UG_NAME__ -> 81:b ;
+81:__UG_NAME__ -> 90:a ;
+89:__UG_NAME__ -> 90:b ;
+78:__UG_NAME__ -> 92:a ;
+91:__UG_NAME__ -> 92:b ;
+92:__UG_NAME__ -> 94:a ;
+93:__UG_NAME__ -> 94:b ;
+78:__UG_NAME__ -> 97:a ;
+96:__UG_NAME__ -> 97:b ;
+97:__UG_NAME__ -> 98:a ;
+43:__UG_NAME__ -> 98:b ;
+60:__UG_NAME__ -> 106:a ;
+76:__UG_NAME__ -> 106:b ;
+107:__UG_NAME__ -> 109:a ;
+108:__UG_NAME__ -> 109:b ;
+109:__UG_NAME__ -> 110:a ;
+93:__UG_NAME__ -> 110:b ;
+107:__UG_NAME__ -> 113:a ;
+111:__UG_NAME__ -> 113:b ;
+115:__UG_NAME__ -> 116:b ;
+113:__UG_NAME__ -> 117:a ;
+43:__UG_NAME__ -> 117:b ;
+60:__UG_NAME__ -> 119:a ;
+118:__UG_NAME__ -> 119:b ;
+116:__UG_NAME__ -> 120:a ;
+89:__UG_NAME__ -> 120:b ;
+60:__UG_NAME__ -> 121:a ;
+118:__UG_NAME__ -> 121:b ;
+70:__UG_NAME__ -> 122:a ;
+34:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+38:__UG_NAME__ -> 42:a ;
+41:__UG_NAME__ -> 42:b ;
+44:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+48:__UG_NAME__ -> 52:a ;
+51:__UG_NAME__ -> 52:b ;
+53:__UG_NAME__ -> 55:a ;
+54:__UG_NAME__ -> 55:b ;
+55:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+65:__UG_NAME__ -> 69:a ;
+68:__UG_NAME__ -> 69:b ;
+82:__UG_NAME__ -> 84:a ;
+83:__UG_NAME__ -> 84:b ;
+84:__UG_NAME__ -> 88:a ;
+87:__UG_NAME__ -> 88:b ;
+90:__UG_NAME__ -> 95:a ;
+94:__UG_NAME__ -> 95:b ;
+95:__UG_NAME__ -> 99:a ;
+98:__UG_NAME__ -> 99:b ;
+72:__UG_NAME__ -> 103:a ;
+102:__UG_NAME__ -> 103:b ;
+103:__UG_NAME__ -> 105:a ;
+104:__UG_NAME__ -> 105:b ;
+120:__UG_NAME__ -> 125:a ;
+110:__UG_NAME__ -> 125:b ;
+125:__UG_NAME__ -> 126:a ;
+117:__UG_NAME__ -> 126:b ;
+71:__UG_NAME__ -> 73:a ;
+122:__UG_NAME__ -> 123:a ;
+36:__UG_NAME__ -> 37:a ;
+40:__UG_NAME__ -> 41:a ;
+46:__UG_NAME__ -> 47:a ;
+50:__UG_NAME__ -> 51:a ;
+33:__UG_NAME__ -> 54:a ;
+57:__UG_NAME__ -> 58:a ;
+63:__UG_NAME__ -> 64:a ;
+67:__UG_NAME__ -> 68:a ;
+31:__UG_NAME__ -> 83:a ;
+86:__UG_NAME__ -> 87:a ;
+101:__UG_NAME__ -> 102:a ;
+75:__UG_NAME__ -> 104:a ;
+30:__UG_NAME__ -> 31:a ;
+32:__UG_NAME__ -> 33:a ;
+35:__UG_NAME__ -> 36:a ;
+39:__UG_NAME__ -> 40:a ;
+45:__UG_NAME__ -> 46:a ;
+49:__UG_NAME__ -> 50:a ;
+56:__UG_NAME__ -> 57:a ;
+62:__UG_NAME__ -> 63:a ;
+66:__UG_NAME__ -> 67:a ;
+74:__UG_NAME__ -> 75:a ;
+78:__UG_NAME__ -> 79:a ;
+85:__UG_NAME__ -> 86:a ;
+100:__UG_NAME__ -> 101:a ;
+107:__UG_NAME__ -> 114:a ;
+24:__UG_NAME__ -> 43:envelope___control___0 ;
+24:__UG_NAME__ -> 43:envelope___control___4 ;
+25:__UG_NAME__ -> 43:envelope___control___5 ;
+26:__UG_NAME__ -> 43:envelope___control___6 ;
+27:__UG_NAME__ -> 43:envelope___control___7 ;
+42:__UG_NAME__ -> 43:gate ;
+8:__UG_NAME__ -> 60:envelope___control___0 ;
+8:__UG_NAME__ -> 60:envelope___control___4 ;
+9:__UG_NAME__ -> 60:envelope___control___5 ;
+10:__UG_NAME__ -> 60:envelope___control___6 ;
+11:__UG_NAME__ -> 60:envelope___control___7 ;
+59:__UG_NAME__ -> 60:gate ;
+4:__UG_NAME__ -> 70:envelope___control___0 ;
+4:__UG_NAME__ -> 70:envelope___control___4 ;
+5:__UG_NAME__ -> 70:envelope___control___5 ;
+6:__UG_NAME__ -> 70:envelope___control___6 ;
+7:__UG_NAME__ -> 70:envelope___control___7 ;
+69:__UG_NAME__ -> 70:gate ;
+16:__UG_NAME__ -> 89:envelope___control___0 ;
+16:__UG_NAME__ -> 89:envelope___control___4 ;
+17:__UG_NAME__ -> 89:envelope___control___5 ;
+18:__UG_NAME__ -> 89:envelope___control___6 ;
+19:__UG_NAME__ -> 89:envelope___control___7 ;
+88:__UG_NAME__ -> 89:gate ;
+20:__UG_NAME__ -> 93:envelope___control___0 ;
+20:__UG_NAME__ -> 93:envelope___control___4 ;
+21:__UG_NAME__ -> 93:envelope___control___5 ;
+22:__UG_NAME__ -> 93:envelope___control___6 ;
+23:__UG_NAME__ -> 93:envelope___control___7 ;
+52:__UG_NAME__ -> 93:gate ;
+0:__UG_NAME__ -> 112:envelope___control___0 ;
+0:__UG_NAME__ -> 112:envelope___control___4 ;
+1:__UG_NAME__ -> 112:envelope___control___5 ;
+2:__UG_NAME__ -> 112:envelope___control___6 ;
+3:__UG_NAME__ -> 112:envelope___control___7 ;
+105:__UG_NAME__ -> 112:gate ;
+16:__UG_NAME__ -> 30:in ;
+8:__UG_NAME__ -> 32:in ;
+24:__UG_NAME__ -> 35:in ;
+25:__UG_NAME__ -> 39:in ;
+20:__UG_NAME__ -> 45:in ;
+21:__UG_NAME__ -> 49:in ;
+9:__UG_NAME__ -> 56:in ;
+4:__UG_NAME__ -> 62:in ;
+5:__UG_NAME__ -> 66:in ;
+1:__UG_NAME__ -> 74:in ;
+17:__UG_NAME__ -> 85:in ;
+0:__UG_NAME__ -> 100:in ;
+28:__UG_NAME__ -> 76:bus ;
+28:__UG_NAME__ -> 118:bus ;
+79:__UG_NAME__ -> 80:in ;
+114:__UG_NAME__ -> 115:in ;
+77:__UG_NAME__ -> 78:in ;
+106:__UG_NAME__ -> 107:in ;
+29:__UG_NAME__ -> 128:bus ;
+124:__UG_NAME__ -> 128:signals___x____fade2___0 ;
+127:__UG_NAME__ -> 128:signals___x____fade2___1 ;
+78:__UG_NAME__ -> 91:trig ;
+91:__UG_NAME__ -> 96:trig ;
+107:__UG_NAME__ -> 108:trig ;
+108:__UG_NAME__ -> 111:trig ;
+121:__UG_NAME__ -> 124:ina ;
+99:__UG_NAME__ -> 124:inb ;
+123:__UG_NAME__ -> 124:pan ;
+112:__UG_NAME__ -> 124:level ;
+119:__UG_NAME__ -> 127:ina ;
+126:__UG_NAME__ -> 127:inb ;
+73:__UG_NAME__ -> 127:pan ;
+112:__UG_NAME__ -> 127:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_pan.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_pan.dot
new file mode 100644
index 0000000..90c1509
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_pan.dot
@@ -0,0 +1,197 @@
+digraph synthdef {
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+62 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+21 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+20 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <level> level|<pos> pos|<right> right|<left> left} |<__UG_NAME__>balance2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+18 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+19 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+68 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+64 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+67 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+31:__UG_NAME__ -> 33:a ;
+32:__UG_NAME__ -> 33:b ;
+31:__UG_NAME__ -> 34:a ;
+32:__UG_NAME__ -> 34:b ;
+61:__UG_NAME__ -> 62:a ;
+61:__UG_NAME__ -> 65:a ;
+26:__UG_NAME__ -> 27:a ;
+25:__UG_NAME__ -> 27:b ;
+27:__UG_NAME__ -> 30:a ;
+29:__UG_NAME__ -> 30:b ;
+35:__UG_NAME__ -> 36:a ;
+21:__UG_NAME__ -> 36:b ;
+36:__UG_NAME__ -> 40:a ;
+39:__UG_NAME__ -> 40:b ;
+42:__UG_NAME__ -> 46:a ;
+45:__UG_NAME__ -> 46:b ;
+46:__UG_NAME__ -> 49:a ;
+48:__UG_NAME__ -> 49:b ;
+52:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+56:__UG_NAME__ -> 60:a ;
+59:__UG_NAME__ -> 60:b ;
+62:__UG_NAME__ -> 63:a ;
+65:__UG_NAME__ -> 66:a ;
+20:__UG_NAME__ -> 21:a ;
+24:__UG_NAME__ -> 25:a ;
+28:__UG_NAME__ -> 29:a ;
+38:__UG_NAME__ -> 39:a ;
+44:__UG_NAME__ -> 45:a ;
+47:__UG_NAME__ -> 48:a ;
+54:__UG_NAME__ -> 55:a ;
+58:__UG_NAME__ -> 59:a ;
+19:__UG_NAME__ -> 20:a ;
+23:__UG_NAME__ -> 24:a ;
+22:__UG_NAME__ -> 28:a ;
+37:__UG_NAME__ -> 38:a ;
+43:__UG_NAME__ -> 44:a ;
+18:__UG_NAME__ -> 47:a ;
+53:__UG_NAME__ -> 54:a ;
+57:__UG_NAME__ -> 58:a ;
+34:__UG_NAME__ -> 51:left ;
+33:__UG_NAME__ -> 51:right ;
+41:__UG_NAME__ -> 51:pos ;
+50:__UG_NAME__ -> 51:level ;
+8:__UG_NAME__ -> 31:envelope___control___0 ;
+8:__UG_NAME__ -> 31:envelope___control___4 ;
+9:__UG_NAME__ -> 31:envelope___control___5 ;
+10:__UG_NAME__ -> 31:envelope___control___6 ;
+11:__UG_NAME__ -> 31:envelope___control___7 ;
+30:__UG_NAME__ -> 31:gate ;
+12:__UG_NAME__ -> 41:envelope___control___0 ;
+12:__UG_NAME__ -> 41:envelope___control___4 ;
+13:__UG_NAME__ -> 41:envelope___control___5 ;
+14:__UG_NAME__ -> 41:envelope___control___6 ;
+15:__UG_NAME__ -> 41:envelope___control___7 ;
+40:__UG_NAME__ -> 41:gate ;
+0:__UG_NAME__ -> 50:envelope___control___0 ;
+0:__UG_NAME__ -> 50:envelope___control___4 ;
+1:__UG_NAME__ -> 50:envelope___control___5 ;
+2:__UG_NAME__ -> 50:envelope___control___6 ;
+3:__UG_NAME__ -> 50:envelope___control___7 ;
+49:__UG_NAME__ -> 50:gate ;
+4:__UG_NAME__ -> 61:envelope___control___0 ;
+4:__UG_NAME__ -> 61:envelope___control___4 ;
+5:__UG_NAME__ -> 61:envelope___control___5 ;
+6:__UG_NAME__ -> 61:envelope___control___6 ;
+7:__UG_NAME__ -> 61:envelope___control___7 ;
+60:__UG_NAME__ -> 61:gate ;
+1:__UG_NAME__ -> 18:in ;
+12:__UG_NAME__ -> 19:in ;
+9:__UG_NAME__ -> 22:in ;
+8:__UG_NAME__ -> 23:in ;
+13:__UG_NAME__ -> 37:in ;
+0:__UG_NAME__ -> 43:in ;
+4:__UG_NAME__ -> 53:in ;
+5:__UG_NAME__ -> 57:in ;
+16:__UG_NAME__ -> 32:bus ;
+17:__UG_NAME__ -> 68:bus ;
+67:__UG_NAME__ -> 68:signals___x____fade2___0 ;
+64:__UG_NAME__ -> 68:signals___x____fade2___1 ;
+33:__UG_NAME__ -> 64:ina ;
+51:__UG_NAME__ -> 64:inb ;
+63:__UG_NAME__ -> 64:pan ;
+50:__UG_NAME__ -> 64:level ;
+34:__UG_NAME__ -> 67:ina ;
+51:__UG_NAME__ -> 67:inb ;
+66:__UG_NAME__ -> 67:pan ;
+50:__UG_NAME__ -> 67:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_panslicer.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_panslicer.dot
new file mode 100644
index 0000000..c3ecc0e
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_panslicer.dot
@@ -0,0 +1,618 @@
+digraph synthdef {
+68 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> 6.2831855|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+149 [label = "{{ <b> -1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+203 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+204 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+218 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+221 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+140 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+156 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+160 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+166 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+170 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+177 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+181 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+190 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+193 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+198 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+200 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+212 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+216 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+147 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+150 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+219 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+222 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+148 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> |<a> } |<__UG_NAME__>\< }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+143 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+155 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+159 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+165 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+169 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+176 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+180 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+189 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+192 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+197 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+199 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+211 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+215 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+154 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+158 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+164 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+168 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+175 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+179 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+184 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+188 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+191 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+196 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+210 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+214 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+207 [label = "{{ <level> level|<pos> pos|<right> right|<left> left} |<__UG_NAME__>balance2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+109 [label = "{{ <interpolation> interpolation 2.0|<loop> loop 1.0|<phase> phase|<bufnum> bufnum|<num____channels> num-channels 1} |<__UG_NAME__>buf-rd }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <hi> hi 1.0|<lo> lo 0.0|<in> in} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <hi> hi 1.0|<lo> lo 0.0|<in> in} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <hi> hi 1.0|<lo> lo -1.0|<in> in} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
+146 [label = "{{ <hi> hi 1.0|<lo> lo -1.0|<in> in} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :phase
+ default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :phase_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :phase_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :phase_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :pan_min
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :pan_min_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :pan_min_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :pan_min_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :pan_max
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :pan_max_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :pan_max_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :pan_max_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :smooth
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :smooth_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :smooth_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :smooth_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :smooth_up
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :smooth_up_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :smooth_up_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :smooth_up_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :smooth_down
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "control
+ :smooth_down_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "control
+ :smooth_down_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "control
+ :smooth_down_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+40 [label = "control
+ :probability
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+41 [label = "control
+ :probability_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+42 [label = "control
+ :probability_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "control
+ :probability_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+44 [label = "control
+ :prob_pos
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+45 [label = "control
+ :prob_pos_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+46 [label = "control
+ :prob_pos_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+47 [label = "control
+ :prob_pos_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+48 [label = "control
+ :phase_offset
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+49 [label = "control
+ :wave
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+50 [label = "control
+ :invert_wave
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+51 [label = "control
+ :seed
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+52 [label = "control
+ :rand_buf
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+53 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+54 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+65 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___clip___0>|1.0|-99|-99|<envelope___clip___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+134 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+145 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+161 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+171 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+182 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+201 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+206 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+217 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+153 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+157 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+163 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+167 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+174 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+178 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+183 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+185 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+187 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+195 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+209 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+213 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <phase> phase 0.0|<freq> freq} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+152 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+162 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+173 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+186 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+194 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+208 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+202 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+205 [label = "{{ <lag____time> lag-time|<in> in} |<__UG_NAME__>lag }" style="bold, rounded" shape=record rankdir=LR];
+172 [label = "{{ <lag____time____down> lag-time-down|<lag____time____up> lag-time-up|<in> in} |<__UG_NAME__>lag-ud }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <width> width|<iphase> iphase|<freq> freq} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <add> add -1.0|<mul> mul 2.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+151 [label = "{{ <add> add|<mul> mul|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+224 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+107 [label = "{{ <reset> reset 0.0|<trig> trig} |<__UG_NAME__>pulse-count }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ {{<array___env____gen___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ {{<array___binary____op____u____gen___0>|<array___select___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase|<freq> freq} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+220 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+223 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+67:__UG_NAME__ -> 68:b ;
+69:__UG_NAME__ -> 70:b ;
+48:__UG_NAME__ -> 82:b ;
+84:__UG_NAME__ -> 85:b ;
+96:__UG_NAME__ -> 97:b ;
+101:__UG_NAME__ -> 102:a ;
+70:__UG_NAME__ -> 105:a ;
+104:__UG_NAME__ -> 105:b ;
+148:__UG_NAME__ -> 149:a ;
+201:__UG_NAME__ -> 203:a ;
+202:__UG_NAME__ -> 203:b ;
+201:__UG_NAME__ -> 204:a ;
+202:__UG_NAME__ -> 204:b ;
+217:__UG_NAME__ -> 218:a ;
+217:__UG_NAME__ -> 221:a ;
+55:__UG_NAME__ -> 60:a ;
+59:__UG_NAME__ -> 60:b ;
+60:__UG_NAME__ -> 64:a ;
+63:__UG_NAME__ -> 64:b ;
+71:__UG_NAME__ -> 75:a ;
+74:__UG_NAME__ -> 75:b ;
+75:__UG_NAME__ -> 79:a ;
+78:__UG_NAME__ -> 79:b ;
+82:__UG_NAME__ -> 83:a ;
+86:__UG_NAME__ -> 90:a ;
+89:__UG_NAME__ -> 90:b ;
+90:__UG_NAME__ -> 94:a ;
+93:__UG_NAME__ -> 94:b ;
+82:__UG_NAME__ -> 99:a ;
+48:__UG_NAME__ -> 101:a ;
+51:__UG_NAME__ -> 108:a ;
+107:__UG_NAME__ -> 108:b ;
+111:__UG_NAME__ -> 117:a ;
+116:__UG_NAME__ -> 117:b ;
+117:__UG_NAME__ -> 121:a ;
+120:__UG_NAME__ -> 121:b ;
+125:__UG_NAME__ -> 129:a ;
+128:__UG_NAME__ -> 129:b ;
+129:__UG_NAME__ -> 133:a ;
+132:__UG_NAME__ -> 133:b ;
+136:__UG_NAME__ -> 140:a ;
+139:__UG_NAME__ -> 140:b ;
+140:__UG_NAME__ -> 144:a ;
+143:__UG_NAME__ -> 144:b ;
+152:__UG_NAME__ -> 156:a ;
+155:__UG_NAME__ -> 156:b ;
+156:__UG_NAME__ -> 160:a ;
+159:__UG_NAME__ -> 160:b ;
+162:__UG_NAME__ -> 166:a ;
+165:__UG_NAME__ -> 166:b ;
+166:__UG_NAME__ -> 170:a ;
+169:__UG_NAME__ -> 170:b ;
+173:__UG_NAME__ -> 177:a ;
+176:__UG_NAME__ -> 177:b ;
+177:__UG_NAME__ -> 181:a ;
+180:__UG_NAME__ -> 181:b ;
+186:__UG_NAME__ -> 190:a ;
+189:__UG_NAME__ -> 190:b ;
+190:__UG_NAME__ -> 193:a ;
+192:__UG_NAME__ -> 193:b ;
+194:__UG_NAME__ -> 198:a ;
+197:__UG_NAME__ -> 198:b ;
+198:__UG_NAME__ -> 200:a ;
+199:__UG_NAME__ -> 200:b ;
+208:__UG_NAME__ -> 212:a ;
+211:__UG_NAME__ -> 212:b ;
+212:__UG_NAME__ -> 216:a ;
+215:__UG_NAME__ -> 216:b ;
+68:__UG_NAME__ -> 69:a ;
+97:__UG_NAME__ -> 98:a ;
+135:__UG_NAME__ -> 147:a ;
+146:__UG_NAME__ -> 147:b ;
+146:__UG_NAME__ -> 150:a ;
+149:__UG_NAME__ -> 150:b ;
+218:__UG_NAME__ -> 219:a ;
+221:__UG_NAME__ -> 222:a ;
+80:__UG_NAME__ -> 81:b ;
+147:__UG_NAME__ -> 148:a ;
+109:__UG_NAME__ -> 110:a ;
+65:__UG_NAME__ -> 110:b ;
+58:__UG_NAME__ -> 59:a ;
+62:__UG_NAME__ -> 63:a ;
+65:__UG_NAME__ -> 66:a ;
+50:__UG_NAME__ -> 67:a ;
+73:__UG_NAME__ -> 74:a ;
+77:__UG_NAME__ -> 78:a ;
+88:__UG_NAME__ -> 89:a ;
+92:__UG_NAME__ -> 93:a ;
+115:__UG_NAME__ -> 116:a ;
+119:__UG_NAME__ -> 120:a ;
+127:__UG_NAME__ -> 128:a ;
+131:__UG_NAME__ -> 132:a ;
+138:__UG_NAME__ -> 139:a ;
+142:__UG_NAME__ -> 143:a ;
+154:__UG_NAME__ -> 155:a ;
+158:__UG_NAME__ -> 159:a ;
+164:__UG_NAME__ -> 165:a ;
+168:__UG_NAME__ -> 169:a ;
+175:__UG_NAME__ -> 176:a ;
+179:__UG_NAME__ -> 180:a ;
+188:__UG_NAME__ -> 189:a ;
+191:__UG_NAME__ -> 192:a ;
+196:__UG_NAME__ -> 197:a ;
+184:__UG_NAME__ -> 199:a ;
+210:__UG_NAME__ -> 211:a ;
+214:__UG_NAME__ -> 215:a ;
+57:__UG_NAME__ -> 58:a ;
+61:__UG_NAME__ -> 62:a ;
+72:__UG_NAME__ -> 73:a ;
+76:__UG_NAME__ -> 77:a ;
+87:__UG_NAME__ -> 88:a ;
+91:__UG_NAME__ -> 92:a ;
+114:__UG_NAME__ -> 115:a ;
+118:__UG_NAME__ -> 119:a ;
+126:__UG_NAME__ -> 127:a ;
+130:__UG_NAME__ -> 131:a ;
+137:__UG_NAME__ -> 138:a ;
+141:__UG_NAME__ -> 142:a ;
+153:__UG_NAME__ -> 154:a ;
+157:__UG_NAME__ -> 158:a ;
+163:__UG_NAME__ -> 164:a ;
+167:__UG_NAME__ -> 168:a ;
+174:__UG_NAME__ -> 175:a ;
+178:__UG_NAME__ -> 179:a ;
+183:__UG_NAME__ -> 184:a ;
+187:__UG_NAME__ -> 188:a ;
+185:__UG_NAME__ -> 191:a ;
+195:__UG_NAME__ -> 196:a ;
+209:__UG_NAME__ -> 210:a ;
+213:__UG_NAME__ -> 214:a ;
+203:__UG_NAME__ -> 207:left ;
+204:__UG_NAME__ -> 207:right ;
+205:__UG_NAME__ -> 207:pos ;
+206:__UG_NAME__ -> 207:level ;
+52:__UG_NAME__ -> 109:bufnum ;
+108:__UG_NAME__ -> 109:phase ;
+40:__UG_NAME__ -> 56:in ;
+44:__UG_NAME__ -> 112:in ;
+134:__UG_NAME__ -> 135:in ;
+145:__UG_NAME__ -> 146:in ;
+56:__UG_NAME__ -> 65:envelope___clip___0 ;
+56:__UG_NAME__ -> 65:envelope___clip___4 ;
+41:__UG_NAME__ -> 65:envelope___control___5 ;
+42:__UG_NAME__ -> 65:envelope___control___6 ;
+43:__UG_NAME__ -> 65:envelope___control___7 ;
+64:__UG_NAME__ -> 65:gate ;
+12:__UG_NAME__ -> 80:envelope___control___0 ;
+12:__UG_NAME__ -> 80:envelope___control___4 ;
+13:__UG_NAME__ -> 80:envelope___control___5 ;
+14:__UG_NAME__ -> 80:envelope___control___6 ;
+15:__UG_NAME__ -> 80:envelope___control___7 ;
+79:__UG_NAME__ -> 80:gate ;
+24:__UG_NAME__ -> 95:envelope___control___0 ;
+24:__UG_NAME__ -> 95:envelope___control___4 ;
+25:__UG_NAME__ -> 95:envelope___control___5 ;
+26:__UG_NAME__ -> 95:envelope___control___6 ;
+27:__UG_NAME__ -> 95:envelope___control___7 ;
+94:__UG_NAME__ -> 95:gate ;
+113:__UG_NAME__ -> 122:envelope___mul____add___0 ;
+113:__UG_NAME__ -> 122:envelope___mul____add___4 ;
+45:__UG_NAME__ -> 122:envelope___control___5 ;
+46:__UG_NAME__ -> 122:envelope___control___6 ;
+47:__UG_NAME__ -> 122:envelope___control___7 ;
+121:__UG_NAME__ -> 122:gate ;
+20:__UG_NAME__ -> 134:envelope___control___0 ;
+20:__UG_NAME__ -> 134:envelope___control___4 ;
+21:__UG_NAME__ -> 134:envelope___control___5 ;
+22:__UG_NAME__ -> 134:envelope___control___6 ;
+23:__UG_NAME__ -> 134:envelope___control___7 ;
+133:__UG_NAME__ -> 134:gate ;
+16:__UG_NAME__ -> 145:envelope___control___0 ;
+16:__UG_NAME__ -> 145:envelope___control___4 ;
+17:__UG_NAME__ -> 145:envelope___control___5 ;
+18:__UG_NAME__ -> 145:envelope___control___6 ;
+19:__UG_NAME__ -> 145:envelope___control___7 ;
+144:__UG_NAME__ -> 145:gate ;
+32:__UG_NAME__ -> 161:envelope___control___0 ;
+32:__UG_NAME__ -> 161:envelope___control___4 ;
+33:__UG_NAME__ -> 161:envelope___control___5 ;
+34:__UG_NAME__ -> 161:envelope___control___6 ;
+35:__UG_NAME__ -> 161:envelope___control___7 ;
+160:__UG_NAME__ -> 161:gate ;
+36:__UG_NAME__ -> 171:envelope___control___0 ;
+36:__UG_NAME__ -> 171:envelope___control___4 ;
+37:__UG_NAME__ -> 171:envelope___control___5 ;
+38:__UG_NAME__ -> 171:envelope___control___6 ;
+39:__UG_NAME__ -> 171:envelope___control___7 ;
+170:__UG_NAME__ -> 171:gate ;
+28:__UG_NAME__ -> 182:envelope___control___0 ;
+28:__UG_NAME__ -> 182:envelope___control___4 ;
+29:__UG_NAME__ -> 182:envelope___control___5 ;
+30:__UG_NAME__ -> 182:envelope___control___6 ;
+31:__UG_NAME__ -> 182:envelope___control___7 ;
+181:__UG_NAME__ -> 182:gate ;
+8:__UG_NAME__ -> 201:envelope___control___0 ;
+8:__UG_NAME__ -> 201:envelope___control___4 ;
+9:__UG_NAME__ -> 201:envelope___control___5 ;
+10:__UG_NAME__ -> 201:envelope___control___6 ;
+11:__UG_NAME__ -> 201:envelope___control___7 ;
+200:__UG_NAME__ -> 201:gate ;
+0:__UG_NAME__ -> 206:envelope___control___0 ;
+0:__UG_NAME__ -> 206:envelope___control___4 ;
+1:__UG_NAME__ -> 206:envelope___control___5 ;
+2:__UG_NAME__ -> 206:envelope___control___6 ;
+3:__UG_NAME__ -> 206:envelope___control___7 ;
+193:__UG_NAME__ -> 206:gate ;
+4:__UG_NAME__ -> 217:envelope___control___0 ;
+4:__UG_NAME__ -> 217:envelope___control___4 ;
+5:__UG_NAME__ -> 217:envelope___control___5 ;
+6:__UG_NAME__ -> 217:envelope___control___6 ;
+7:__UG_NAME__ -> 217:envelope___control___7 ;
+216:__UG_NAME__ -> 217:gate ;
+56:__UG_NAME__ -> 57:in ;
+41:__UG_NAME__ -> 61:in ;
+12:__UG_NAME__ -> 72:in ;
+13:__UG_NAME__ -> 76:in ;
+24:__UG_NAME__ -> 87:in ;
+25:__UG_NAME__ -> 91:in ;
+113:__UG_NAME__ -> 114:in ;
+45:__UG_NAME__ -> 118:in ;
+20:__UG_NAME__ -> 126:in ;
+21:__UG_NAME__ -> 130:in ;
+16:__UG_NAME__ -> 137:in ;
+17:__UG_NAME__ -> 141:in ;
+32:__UG_NAME__ -> 153:in ;
+33:__UG_NAME__ -> 157:in ;
+36:__UG_NAME__ -> 163:in ;
+37:__UG_NAME__ -> 167:in ;
+28:__UG_NAME__ -> 174:in ;
+29:__UG_NAME__ -> 178:in ;
+9:__UG_NAME__ -> 183:in ;
+1:__UG_NAME__ -> 185:in ;
+0:__UG_NAME__ -> 187:in ;
+8:__UG_NAME__ -> 195:in ;
+4:__UG_NAME__ -> 209:in ;
+5:__UG_NAME__ -> 213:in ;
+81:__UG_NAME__ -> 106:freq ;
+53:__UG_NAME__ -> 202:bus ;
+172:__UG_NAME__ -> 205:in ;
+182:__UG_NAME__ -> 205:lag____time ;
+151:__UG_NAME__ -> 172:in ;
+161:__UG_NAME__ -> 172:lag____time____up ;
+171:__UG_NAME__ -> 172:lag____time____down ;
+81:__UG_NAME__ -> 96:freq ;
+48:__UG_NAME__ -> 96:iphase ;
+95:__UG_NAME__ -> 96:width ;
+81:__UG_NAME__ -> 84:freq ;
+83:__UG_NAME__ -> 84:iphase ;
+81:__UG_NAME__ -> 100:freq ;
+99:__UG_NAME__ -> 100:iphase ;
+112:__UG_NAME__ -> 113:in ;
+124:__UG_NAME__ -> 151:in ;
+148:__UG_NAME__ -> 151:mul ;
+150:__UG_NAME__ -> 151:add ;
+54:__UG_NAME__ -> 224:bus ;
+220:__UG_NAME__ -> 224:signals___x____fade2___0 ;
+223:__UG_NAME__ -> 224:signals___x____fade2___1 ;
+106:__UG_NAME__ -> 107:trig ;
+49:__UG_NAME__ -> 104:which ;
+85:__UG_NAME__ -> 104:array___binary____op____u____gen___0 ;
+98:__UG_NAME__ -> 104:array___binary____op____u____gen___1 ;
+100:__UG_NAME__ -> 104:array___lf____tri___2 ;
+103:__UG_NAME__ -> 104:array___sin____osc___3 ;
+110:__UG_NAME__ -> 123:which ;
+122:__UG_NAME__ -> 123:array___env____gen___0 ;
+105:__UG_NAME__ -> 123:array___binary____op____u____gen___1 ;
+66:__UG_NAME__ -> 124:which ;
+105:__UG_NAME__ -> 124:array___binary____op____u____gen___0 ;
+123:__UG_NAME__ -> 124:array___select___1 ;
+81:__UG_NAME__ -> 103:freq ;
+102:__UG_NAME__ -> 103:phase ;
+203:__UG_NAME__ -> 220:ina ;
+207:__UG_NAME__ -> 220:inb ;
+219:__UG_NAME__ -> 220:pan ;
+206:__UG_NAME__ -> 220:level ;
+204:__UG_NAME__ -> 223:ina ;
+207:__UG_NAME__ -> 223:inb ;
+222:__UG_NAME__ -> 223:pan ;
+206:__UG_NAME__ -> 223:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_pitch_shift.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_pitch_shift.dot
new file mode 100644
index 0000000..b46b20b
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_pitch_shift.dot
@@ -0,0 +1,320 @@
+digraph synthdef {
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+94 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+109 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :pitch
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :pitch_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :pitch_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :pitch_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :window_size
+ default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :window_size_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :window_size_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :window_size_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :pitch_dis
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :pitch_dis_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :pitch_dis_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :pitch_dis_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :time_dis
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :time_dis_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :time_dis_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :time_dis_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>midiratio }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+83 [label = "{{ <time____dispersion> time-dispersion|<pitch____dispersion> pitch-dispersion|<pitch____ratio> pitch-ratio|<window____size> window-size|<in> in} |<__UG_NAME__>pitch-shift }" style="filled, bold, rounded"  shape=record rankdir=LR];
+108 [label = "{{ <time____dispersion> time-dispersion|<pitch____dispersion> pitch-dispersion|<pitch____ratio> pitch-ratio|<window____size> window-size|<in> in} |<__UG_NAME__>pitch-shift }" style="filled, bold, rounded"  shape=record rankdir=LR];
+106 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+111 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+39:__UG_NAME__ -> 41:a ;
+40:__UG_NAME__ -> 41:b ;
+93:__UG_NAME__ -> 94:a ;
+39:__UG_NAME__ -> 107:a ;
+40:__UG_NAME__ -> 107:b ;
+93:__UG_NAME__ -> 109:a ;
+30:__UG_NAME__ -> 34:a ;
+33:__UG_NAME__ -> 34:b ;
+34:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+42:__UG_NAME__ -> 46:a ;
+45:__UG_NAME__ -> 46:b ;
+46:__UG_NAME__ -> 50:a ;
+49:__UG_NAME__ -> 50:b ;
+52:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+56:__UG_NAME__ -> 60:a ;
+59:__UG_NAME__ -> 60:b ;
+63:__UG_NAME__ -> 67:a ;
+66:__UG_NAME__ -> 67:b ;
+67:__UG_NAME__ -> 71:a ;
+70:__UG_NAME__ -> 71:b ;
+73:__UG_NAME__ -> 77:a ;
+76:__UG_NAME__ -> 77:b ;
+77:__UG_NAME__ -> 81:a ;
+80:__UG_NAME__ -> 81:b ;
+84:__UG_NAME__ -> 88:a ;
+87:__UG_NAME__ -> 88:b ;
+88:__UG_NAME__ -> 92:a ;
+91:__UG_NAME__ -> 92:b ;
+96:__UG_NAME__ -> 100:a ;
+99:__UG_NAME__ -> 100:b ;
+100:__UG_NAME__ -> 104:a ;
+103:__UG_NAME__ -> 104:b ;
+94:__UG_NAME__ -> 95:a ;
+109:__UG_NAME__ -> 110:a ;
+32:__UG_NAME__ -> 33:a ;
+36:__UG_NAME__ -> 37:a ;
+44:__UG_NAME__ -> 45:a ;
+48:__UG_NAME__ -> 49:a ;
+54:__UG_NAME__ -> 55:a ;
+58:__UG_NAME__ -> 59:a ;
+65:__UG_NAME__ -> 66:a ;
+69:__UG_NAME__ -> 70:a ;
+75:__UG_NAME__ -> 76:a ;
+79:__UG_NAME__ -> 80:a ;
+86:__UG_NAME__ -> 87:a ;
+90:__UG_NAME__ -> 91:a ;
+98:__UG_NAME__ -> 99:a ;
+102:__UG_NAME__ -> 103:a ;
+31:__UG_NAME__ -> 32:a ;
+35:__UG_NAME__ -> 36:a ;
+43:__UG_NAME__ -> 44:a ;
+47:__UG_NAME__ -> 48:a ;
+53:__UG_NAME__ -> 54:a ;
+57:__UG_NAME__ -> 58:a ;
+64:__UG_NAME__ -> 65:a ;
+68:__UG_NAME__ -> 69:a ;
+74:__UG_NAME__ -> 75:a ;
+78:__UG_NAME__ -> 79:a ;
+85:__UG_NAME__ -> 86:a ;
+89:__UG_NAME__ -> 90:a ;
+97:__UG_NAME__ -> 98:a ;
+101:__UG_NAME__ -> 102:a ;
+8:__UG_NAME__ -> 39:envelope___control___0 ;
+8:__UG_NAME__ -> 39:envelope___control___4 ;
+9:__UG_NAME__ -> 39:envelope___control___5 ;
+10:__UG_NAME__ -> 39:envelope___control___6 ;
+11:__UG_NAME__ -> 39:envelope___control___7 ;
+38:__UG_NAME__ -> 39:gate ;
+16:__UG_NAME__ -> 51:envelope___control___0 ;
+16:__UG_NAME__ -> 51:envelope___control___4 ;
+17:__UG_NAME__ -> 51:envelope___control___5 ;
+18:__UG_NAME__ -> 51:envelope___control___6 ;
+19:__UG_NAME__ -> 51:envelope___control___7 ;
+50:__UG_NAME__ -> 51:gate ;
+12:__UG_NAME__ -> 61:envelope___control___0 ;
+12:__UG_NAME__ -> 61:envelope___control___4 ;
+13:__UG_NAME__ -> 61:envelope___control___5 ;
+14:__UG_NAME__ -> 61:envelope___control___6 ;
+15:__UG_NAME__ -> 61:envelope___control___7 ;
+60:__UG_NAME__ -> 61:gate ;
+20:__UG_NAME__ -> 72:envelope___control___0 ;
+20:__UG_NAME__ -> 72:envelope___control___4 ;
+21:__UG_NAME__ -> 72:envelope___control___5 ;
+22:__UG_NAME__ -> 72:envelope___control___6 ;
+23:__UG_NAME__ -> 72:envelope___control___7 ;
+71:__UG_NAME__ -> 72:gate ;
+24:__UG_NAME__ -> 82:envelope___control___0 ;
+24:__UG_NAME__ -> 82:envelope___control___4 ;
+25:__UG_NAME__ -> 82:envelope___control___5 ;
+26:__UG_NAME__ -> 82:envelope___control___6 ;
+27:__UG_NAME__ -> 82:envelope___control___7 ;
+81:__UG_NAME__ -> 82:gate ;
+4:__UG_NAME__ -> 93:envelope___control___0 ;
+4:__UG_NAME__ -> 93:envelope___control___4 ;
+5:__UG_NAME__ -> 93:envelope___control___5 ;
+6:__UG_NAME__ -> 93:envelope___control___6 ;
+7:__UG_NAME__ -> 93:envelope___control___7 ;
+92:__UG_NAME__ -> 93:gate ;
+0:__UG_NAME__ -> 105:envelope___control___0 ;
+0:__UG_NAME__ -> 105:envelope___control___4 ;
+1:__UG_NAME__ -> 105:envelope___control___5 ;
+2:__UG_NAME__ -> 105:envelope___control___6 ;
+3:__UG_NAME__ -> 105:envelope___control___7 ;
+104:__UG_NAME__ -> 105:gate ;
+8:__UG_NAME__ -> 31:in ;
+9:__UG_NAME__ -> 35:in ;
+16:__UG_NAME__ -> 43:in ;
+17:__UG_NAME__ -> 47:in ;
+12:__UG_NAME__ -> 53:in ;
+13:__UG_NAME__ -> 57:in ;
+20:__UG_NAME__ -> 64:in ;
+21:__UG_NAME__ -> 68:in ;
+24:__UG_NAME__ -> 74:in ;
+25:__UG_NAME__ -> 78:in ;
+4:__UG_NAME__ -> 85:in ;
+5:__UG_NAME__ -> 89:in ;
+0:__UG_NAME__ -> 97:in ;
+1:__UG_NAME__ -> 101:in ;
+28:__UG_NAME__ -> 40:bus ;
+61:__UG_NAME__ -> 62:a ;
+29:__UG_NAME__ -> 112:bus ;
+111:__UG_NAME__ -> 112:signals___x____fade2___0 ;
+106:__UG_NAME__ -> 112:signals___x____fade2___1 ;
+41:__UG_NAME__ -> 83:in ;
+51:__UG_NAME__ -> 83:window____size ;
+62:__UG_NAME__ -> 83:pitch____ratio ;
+72:__UG_NAME__ -> 83:pitch____dispersion ;
+82:__UG_NAME__ -> 83:time____dispersion ;
+107:__UG_NAME__ -> 108:in ;
+51:__UG_NAME__ -> 108:window____size ;
+62:__UG_NAME__ -> 108:pitch____ratio ;
+72:__UG_NAME__ -> 108:pitch____dispersion ;
+82:__UG_NAME__ -> 108:time____dispersion ;
+41:__UG_NAME__ -> 106:ina ;
+83:__UG_NAME__ -> 106:inb ;
+95:__UG_NAME__ -> 106:pan ;
+105:__UG_NAME__ -> 106:level ;
+107:__UG_NAME__ -> 111:ina ;
+108:__UG_NAME__ -> 111:inb ;
+110:__UG_NAME__ -> 111:pan ;
+105:__UG_NAME__ -> 111:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_rbpf.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_rbpf.dot
new file mode 100644
index 0000000..2f40984
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_rbpf.dot
@@ -0,0 +1,242 @@
+digraph synthdef {
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+69 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :centre
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :centre_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :centre_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :centre_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :res
+ default: 0.6" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+61 [label = "{{ <bwr> bwr|<freq> freq|<in> in} |<__UG_NAME__>resonz }" style="filled, bold, rounded"  shape=record rankdir=LR];
+83 [label = "{{ <bwr> bwr|<freq> freq|<in> in} |<__UG_NAME__>resonz }" style="filled, bold, rounded"  shape=record rankdir=LR];
+81 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+84 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+36:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+68:__UG_NAME__ -> 69:a ;
+68:__UG_NAME__ -> 73:a ;
+36:__UG_NAME__ -> 82:a ;
+37:__UG_NAME__ -> 82:b ;
+22:__UG_NAME__ -> 26:a ;
+25:__UG_NAME__ -> 26:b ;
+27:__UG_NAME__ -> 31:a ;
+30:__UG_NAME__ -> 31:b ;
+31:__UG_NAME__ -> 35:a ;
+34:__UG_NAME__ -> 35:b ;
+39:__UG_NAME__ -> 43:a ;
+42:__UG_NAME__ -> 43:b ;
+43:__UG_NAME__ -> 47:a ;
+46:__UG_NAME__ -> 47:b ;
+50:__UG_NAME__ -> 55:a ;
+54:__UG_NAME__ -> 55:b ;
+55:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+26:__UG_NAME__ -> 67:a ;
+66:__UG_NAME__ -> 67:b ;
+76:__UG_NAME__ -> 77:a ;
+70:__UG_NAME__ -> 77:b ;
+77:__UG_NAME__ -> 79:a ;
+78:__UG_NAME__ -> 79:b ;
+73:__UG_NAME__ -> 74:a ;
+69:__UG_NAME__ -> 75:a ;
+24:__UG_NAME__ -> 25:a ;
+29:__UG_NAME__ -> 30:a ;
+33:__UG_NAME__ -> 34:a ;
+41:__UG_NAME__ -> 42:a ;
+45:__UG_NAME__ -> 46:a ;
+53:__UG_NAME__ -> 54:a ;
+57:__UG_NAME__ -> 58:a ;
+65:__UG_NAME__ -> 66:a ;
+63:__UG_NAME__ -> 70:a ;
+72:__UG_NAME__ -> 78:a ;
+23:__UG_NAME__ -> 24:a ;
+28:__UG_NAME__ -> 29:a ;
+32:__UG_NAME__ -> 33:a ;
+40:__UG_NAME__ -> 41:a ;
+44:__UG_NAME__ -> 45:a ;
+52:__UG_NAME__ -> 53:a ;
+56:__UG_NAME__ -> 57:a ;
+62:__UG_NAME__ -> 63:a ;
+64:__UG_NAME__ -> 65:a ;
+71:__UG_NAME__ -> 72:a ;
+8:__UG_NAME__ -> 36:envelope___control___0 ;
+8:__UG_NAME__ -> 36:envelope___control___4 ;
+9:__UG_NAME__ -> 36:envelope___control___5 ;
+10:__UG_NAME__ -> 36:envelope___control___6 ;
+11:__UG_NAME__ -> 36:envelope___control___7 ;
+35:__UG_NAME__ -> 36:gate ;
+12:__UG_NAME__ -> 48:envelope___control___0 ;
+12:__UG_NAME__ -> 48:envelope___control___4 ;
+13:__UG_NAME__ -> 48:envelope___control___5 ;
+14:__UG_NAME__ -> 48:envelope___control___6 ;
+15:__UG_NAME__ -> 48:envelope___control___7 ;
+47:__UG_NAME__ -> 48:gate ;
+51:__UG_NAME__ -> 60:envelope___mul____add___0 ;
+51:__UG_NAME__ -> 60:envelope___mul____add___4 ;
+17:__UG_NAME__ -> 60:envelope___control___5 ;
+18:__UG_NAME__ -> 60:envelope___control___6 ;
+19:__UG_NAME__ -> 60:envelope___control___7 ;
+59:__UG_NAME__ -> 60:gate ;
+4:__UG_NAME__ -> 68:envelope___control___0 ;
+4:__UG_NAME__ -> 68:envelope___control___4 ;
+5:__UG_NAME__ -> 68:envelope___control___5 ;
+6:__UG_NAME__ -> 68:envelope___control___6 ;
+7:__UG_NAME__ -> 68:envelope___control___7 ;
+67:__UG_NAME__ -> 68:gate ;
+0:__UG_NAME__ -> 80:envelope___control___0 ;
+0:__UG_NAME__ -> 80:envelope___control___4 ;
+1:__UG_NAME__ -> 80:envelope___control___5 ;
+2:__UG_NAME__ -> 80:envelope___control___6 ;
+3:__UG_NAME__ -> 80:envelope___control___7 ;
+79:__UG_NAME__ -> 80:gate ;
+4:__UG_NAME__ -> 23:in ;
+8:__UG_NAME__ -> 28:in ;
+9:__UG_NAME__ -> 32:in ;
+12:__UG_NAME__ -> 40:in ;
+13:__UG_NAME__ -> 44:in ;
+51:__UG_NAME__ -> 52:in ;
+17:__UG_NAME__ -> 56:in ;
+0:__UG_NAME__ -> 62:in ;
+5:__UG_NAME__ -> 64:in ;
+1:__UG_NAME__ -> 71:in ;
+20:__UG_NAME__ -> 37:bus ;
+48:__UG_NAME__ -> 49:a ;
+16:__UG_NAME__ -> 51:in ;
+21:__UG_NAME__ -> 85:bus ;
+81:__UG_NAME__ -> 85:signals___x____fade2___0 ;
+84:__UG_NAME__ -> 85:signals___x____fade2___1 ;
+38:__UG_NAME__ -> 61:in ;
+49:__UG_NAME__ -> 61:freq ;
+60:__UG_NAME__ -> 61:bwr ;
+82:__UG_NAME__ -> 83:in ;
+49:__UG_NAME__ -> 83:freq ;
+60:__UG_NAME__ -> 83:bwr ;
+38:__UG_NAME__ -> 81:ina ;
+61:__UG_NAME__ -> 81:inb ;
+75:__UG_NAME__ -> 81:pan ;
+80:__UG_NAME__ -> 81:level ;
+82:__UG_NAME__ -> 84:ina ;
+83:__UG_NAME__ -> 84:inb ;
+74:__UG_NAME__ -> 84:pan ;
+80:__UG_NAME__ -> 84:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_reverb.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_reverb.dot
new file mode 100644
index 0000000..4b2bf80
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_reverb.dot
@@ -0,0 +1,224 @@
+digraph synthdef {
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 0.4" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :room
+ default: 0.6" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :room_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :room_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :room_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :damp
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :damp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :damp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :damp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <damp> damp|<room> room|<mix> mix|<in2> in2|<in> in} |<__UG_NAME__>free-verb2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+78 [label = "{{ {{<signals___binary____op____u____gen___0>|<signals___binary____op____u____gen___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+42:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+42:__UG_NAME__ -> 45:a ;
+43:__UG_NAME__ -> 45:b ;
+32:__UG_NAME__ -> 76:a ;
+75:__UG_NAME__ -> 76:b ;
+32:__UG_NAME__ -> 77:a ;
+75:__UG_NAME__ -> 77:b ;
+23:__UG_NAME__ -> 27:a ;
+26:__UG_NAME__ -> 27:b ;
+27:__UG_NAME__ -> 31:a ;
+30:__UG_NAME__ -> 31:b ;
+33:__UG_NAME__ -> 37:a ;
+36:__UG_NAME__ -> 37:b ;
+37:__UG_NAME__ -> 41:a ;
+40:__UG_NAME__ -> 41:b ;
+46:__UG_NAME__ -> 50:a ;
+49:__UG_NAME__ -> 50:b ;
+50:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+56:__UG_NAME__ -> 60:a ;
+59:__UG_NAME__ -> 60:b ;
+60:__UG_NAME__ -> 63:a ;
+62:__UG_NAME__ -> 63:b ;
+65:__UG_NAME__ -> 69:a ;
+68:__UG_NAME__ -> 69:b ;
+69:__UG_NAME__ -> 73:a ;
+72:__UG_NAME__ -> 73:b ;
+25:__UG_NAME__ -> 26:a ;
+29:__UG_NAME__ -> 30:a ;
+35:__UG_NAME__ -> 36:a ;
+39:__UG_NAME__ -> 40:a ;
+48:__UG_NAME__ -> 49:a ;
+52:__UG_NAME__ -> 53:a ;
+58:__UG_NAME__ -> 59:a ;
+61:__UG_NAME__ -> 62:a ;
+67:__UG_NAME__ -> 68:a ;
+71:__UG_NAME__ -> 72:a ;
+24:__UG_NAME__ -> 25:a ;
+28:__UG_NAME__ -> 29:a ;
+34:__UG_NAME__ -> 35:a ;
+38:__UG_NAME__ -> 39:a ;
+47:__UG_NAME__ -> 48:a ;
+51:__UG_NAME__ -> 52:a ;
+57:__UG_NAME__ -> 58:a ;
+22:__UG_NAME__ -> 61:a ;
+66:__UG_NAME__ -> 67:a ;
+70:__UG_NAME__ -> 71:a ;
+0:__UG_NAME__ -> 32:envelope___control___0 ;
+0:__UG_NAME__ -> 32:envelope___control___4 ;
+1:__UG_NAME__ -> 32:envelope___control___5 ;
+2:__UG_NAME__ -> 32:envelope___control___6 ;
+3:__UG_NAME__ -> 32:envelope___control___7 ;
+31:__UG_NAME__ -> 32:gate ;
+8:__UG_NAME__ -> 42:envelope___control___0 ;
+8:__UG_NAME__ -> 42:envelope___control___4 ;
+9:__UG_NAME__ -> 42:envelope___control___5 ;
+10:__UG_NAME__ -> 42:envelope___control___6 ;
+11:__UG_NAME__ -> 42:envelope___control___7 ;
+41:__UG_NAME__ -> 42:gate ;
+4:__UG_NAME__ -> 55:envelope___control___0 ;
+4:__UG_NAME__ -> 55:envelope___control___4 ;
+5:__UG_NAME__ -> 55:envelope___control___5 ;
+6:__UG_NAME__ -> 55:envelope___control___6 ;
+7:__UG_NAME__ -> 55:envelope___control___7 ;
+54:__UG_NAME__ -> 55:gate ;
+12:__UG_NAME__ -> 64:envelope___control___0 ;
+12:__UG_NAME__ -> 64:envelope___control___4 ;
+13:__UG_NAME__ -> 64:envelope___control___5 ;
+14:__UG_NAME__ -> 64:envelope___control___6 ;
+15:__UG_NAME__ -> 64:envelope___control___7 ;
+63:__UG_NAME__ -> 64:gate ;
+16:__UG_NAME__ -> 74:envelope___control___0 ;
+16:__UG_NAME__ -> 74:envelope___control___4 ;
+17:__UG_NAME__ -> 74:envelope___control___5 ;
+18:__UG_NAME__ -> 74:envelope___control___6 ;
+19:__UG_NAME__ -> 74:envelope___control___7 ;
+73:__UG_NAME__ -> 74:gate ;
+44:__UG_NAME__ -> 75:in ;
+45:__UG_NAME__ -> 75:in2 ;
+55:__UG_NAME__ -> 75:mix ;
+64:__UG_NAME__ -> 75:room ;
+74:__UG_NAME__ -> 75:damp ;
+13:__UG_NAME__ -> 22:in ;
+0:__UG_NAME__ -> 24:in ;
+1:__UG_NAME__ -> 28:in ;
+8:__UG_NAME__ -> 34:in ;
+9:__UG_NAME__ -> 38:in ;
+4:__UG_NAME__ -> 47:in ;
+5:__UG_NAME__ -> 51:in ;
+12:__UG_NAME__ -> 57:in ;
+16:__UG_NAME__ -> 66:in ;
+17:__UG_NAME__ -> 70:in ;
+20:__UG_NAME__ -> 43:bus ;
+21:__UG_NAME__ -> 78:bus ;
+77:__UG_NAME__ -> 78:signals___binary____op____u____gen___0 ;
+76:__UG_NAME__ -> 78:signals___binary____op____u____gen___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_rhpf.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_rhpf.dot
new file mode 100644
index 0000000..7e6ed22
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_rhpf.dot
@@ -0,0 +1,242 @@
+digraph synthdef {
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+67 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+82 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :res
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+56 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rhpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+81 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rhpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+79 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+84 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+36:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+66:__UG_NAME__ -> 67:a ;
+36:__UG_NAME__ -> 80:a ;
+37:__UG_NAME__ -> 80:b ;
+66:__UG_NAME__ -> 82:a ;
+22:__UG_NAME__ -> 26:a ;
+25:__UG_NAME__ -> 26:b ;
+27:__UG_NAME__ -> 31:a ;
+30:__UG_NAME__ -> 31:b ;
+31:__UG_NAME__ -> 35:a ;
+34:__UG_NAME__ -> 35:b ;
+26:__UG_NAME__ -> 42:a ;
+41:__UG_NAME__ -> 42:b ;
+45:__UG_NAME__ -> 50:a ;
+49:__UG_NAME__ -> 50:b ;
+50:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+57:__UG_NAME__ -> 61:a ;
+60:__UG_NAME__ -> 61:b ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+69:__UG_NAME__ -> 73:a ;
+72:__UG_NAME__ -> 73:b ;
+73:__UG_NAME__ -> 77:a ;
+76:__UG_NAME__ -> 77:b ;
+67:__UG_NAME__ -> 68:a ;
+82:__UG_NAME__ -> 83:a ;
+24:__UG_NAME__ -> 25:a ;
+29:__UG_NAME__ -> 30:a ;
+33:__UG_NAME__ -> 34:a ;
+40:__UG_NAME__ -> 41:a ;
+48:__UG_NAME__ -> 49:a ;
+52:__UG_NAME__ -> 53:a ;
+59:__UG_NAME__ -> 60:a ;
+63:__UG_NAME__ -> 64:a ;
+71:__UG_NAME__ -> 72:a ;
+75:__UG_NAME__ -> 76:a ;
+23:__UG_NAME__ -> 24:a ;
+28:__UG_NAME__ -> 29:a ;
+32:__UG_NAME__ -> 33:a ;
+39:__UG_NAME__ -> 40:a ;
+47:__UG_NAME__ -> 48:a ;
+51:__UG_NAME__ -> 52:a ;
+58:__UG_NAME__ -> 59:a ;
+62:__UG_NAME__ -> 63:a ;
+70:__UG_NAME__ -> 71:a ;
+74:__UG_NAME__ -> 75:a ;
+8:__UG_NAME__ -> 36:envelope___control___0 ;
+8:__UG_NAME__ -> 36:envelope___control___4 ;
+9:__UG_NAME__ -> 36:envelope___control___5 ;
+10:__UG_NAME__ -> 36:envelope___control___6 ;
+11:__UG_NAME__ -> 36:envelope___control___7 ;
+35:__UG_NAME__ -> 36:gate ;
+12:__UG_NAME__ -> 43:envelope___control___0 ;
+12:__UG_NAME__ -> 43:envelope___control___4 ;
+13:__UG_NAME__ -> 43:envelope___control___5 ;
+14:__UG_NAME__ -> 43:envelope___control___6 ;
+15:__UG_NAME__ -> 43:envelope___control___7 ;
+42:__UG_NAME__ -> 43:gate ;
+46:__UG_NAME__ -> 55:envelope___mul____add___0 ;
+46:__UG_NAME__ -> 55:envelope___mul____add___4 ;
+17:__UG_NAME__ -> 55:envelope___control___5 ;
+18:__UG_NAME__ -> 55:envelope___control___6 ;
+19:__UG_NAME__ -> 55:envelope___control___7 ;
+54:__UG_NAME__ -> 55:gate ;
+4:__UG_NAME__ -> 66:envelope___control___0 ;
+4:__UG_NAME__ -> 66:envelope___control___4 ;
+5:__UG_NAME__ -> 66:envelope___control___5 ;
+6:__UG_NAME__ -> 66:envelope___control___6 ;
+7:__UG_NAME__ -> 66:envelope___control___7 ;
+65:__UG_NAME__ -> 66:gate ;
+0:__UG_NAME__ -> 78:envelope___control___0 ;
+0:__UG_NAME__ -> 78:envelope___control___4 ;
+1:__UG_NAME__ -> 78:envelope___control___5 ;
+2:__UG_NAME__ -> 78:envelope___control___6 ;
+3:__UG_NAME__ -> 78:envelope___control___7 ;
+77:__UG_NAME__ -> 78:gate ;
+12:__UG_NAME__ -> 23:in ;
+8:__UG_NAME__ -> 28:in ;
+9:__UG_NAME__ -> 32:in ;
+13:__UG_NAME__ -> 39:in ;
+46:__UG_NAME__ -> 47:in ;
+17:__UG_NAME__ -> 51:in ;
+4:__UG_NAME__ -> 58:in ;
+5:__UG_NAME__ -> 62:in ;
+0:__UG_NAME__ -> 70:in ;
+1:__UG_NAME__ -> 74:in ;
+20:__UG_NAME__ -> 37:bus ;
+43:__UG_NAME__ -> 44:a ;
+16:__UG_NAME__ -> 46:in ;
+21:__UG_NAME__ -> 85:bus ;
+79:__UG_NAME__ -> 85:signals___x____fade2___0 ;
+84:__UG_NAME__ -> 85:signals___x____fade2___1 ;
+38:__UG_NAME__ -> 56:in ;
+44:__UG_NAME__ -> 56:freq ;
+55:__UG_NAME__ -> 56:rq ;
+80:__UG_NAME__ -> 81:in ;
+44:__UG_NAME__ -> 81:freq ;
+55:__UG_NAME__ -> 81:rq ;
+38:__UG_NAME__ -> 79:ina ;
+56:__UG_NAME__ -> 79:inb ;
+68:__UG_NAME__ -> 79:pan ;
+78:__UG_NAME__ -> 79:level ;
+80:__UG_NAME__ -> 84:ina ;
+81:__UG_NAME__ -> 84:inb ;
+83:__UG_NAME__ -> 84:pan ;
+78:__UG_NAME__ -> 84:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_ring_mod.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_ring_mod.dot
new file mode 100644
index 0000000..356d5ca
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_ring_mod.dot
@@ -0,0 +1,247 @@
+digraph synthdef {
+35 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+82 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :freq
+ default: 30.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :freq_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :freq_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :freq_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :mod_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :mod_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :mod_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :mod_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+78 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>limiter }" style="filled, bold, rounded"  shape=record rankdir=LR];
+85 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>limiter }" style="filled, bold, rounded"  shape=record rankdir=LR];
+74 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>ring1 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+84 [label = "{{ <b> |<a> } |<__UG_NAME__>ring1 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+75 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+81 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+87 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+34:__UG_NAME__ -> 35:a ;
+52:__UG_NAME__ -> 63:a ;
+62:__UG_NAME__ -> 63:b ;
+45:__UG_NAME__ -> 76:a ;
+75:__UG_NAME__ -> 76:b ;
+34:__UG_NAME__ -> 82:a ;
+52:__UG_NAME__ -> 83:a ;
+62:__UG_NAME__ -> 83:b ;
+25:__UG_NAME__ -> 29:a ;
+28:__UG_NAME__ -> 29:b ;
+29:__UG_NAME__ -> 33:a ;
+32:__UG_NAME__ -> 33:b ;
+36:__UG_NAME__ -> 40:a ;
+39:__UG_NAME__ -> 40:b ;
+40:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+46:__UG_NAME__ -> 47:a ;
+24:__UG_NAME__ -> 47:b ;
+47:__UG_NAME__ -> 51:a ;
+50:__UG_NAME__ -> 51:b ;
+53:__UG_NAME__ -> 57:a ;
+56:__UG_NAME__ -> 57:b ;
+57:__UG_NAME__ -> 61:a ;
+60:__UG_NAME__ -> 61:b ;
+64:__UG_NAME__ -> 68:a ;
+67:__UG_NAME__ -> 68:b ;
+68:__UG_NAME__ -> 72:a ;
+71:__UG_NAME__ -> 72:b ;
+35:__UG_NAME__ -> 79:a ;
+82:__UG_NAME__ -> 86:a ;
+23:__UG_NAME__ -> 24:a ;
+27:__UG_NAME__ -> 28:a ;
+31:__UG_NAME__ -> 32:a ;
+38:__UG_NAME__ -> 39:a ;
+42:__UG_NAME__ -> 43:a ;
+49:__UG_NAME__ -> 50:a ;
+55:__UG_NAME__ -> 56:a ;
+59:__UG_NAME__ -> 60:a ;
+66:__UG_NAME__ -> 67:a ;
+70:__UG_NAME__ -> 71:a ;
+22:__UG_NAME__ -> 23:a ;
+26:__UG_NAME__ -> 27:a ;
+30:__UG_NAME__ -> 31:a ;
+37:__UG_NAME__ -> 38:a ;
+41:__UG_NAME__ -> 42:a ;
+48:__UG_NAME__ -> 49:a ;
+54:__UG_NAME__ -> 55:a ;
+58:__UG_NAME__ -> 59:a ;
+65:__UG_NAME__ -> 66:a ;
+69:__UG_NAME__ -> 70:a ;
+4:__UG_NAME__ -> 34:envelope___control___0 ;
+4:__UG_NAME__ -> 34:envelope___control___4 ;
+5:__UG_NAME__ -> 34:envelope___control___5 ;
+6:__UG_NAME__ -> 34:envelope___control___6 ;
+7:__UG_NAME__ -> 34:envelope___control___7 ;
+33:__UG_NAME__ -> 34:gate ;
+16:__UG_NAME__ -> 45:envelope___control___0 ;
+16:__UG_NAME__ -> 45:envelope___control___4 ;
+17:__UG_NAME__ -> 45:envelope___control___5 ;
+18:__UG_NAME__ -> 45:envelope___control___6 ;
+19:__UG_NAME__ -> 45:envelope___control___7 ;
+44:__UG_NAME__ -> 45:gate ;
+8:__UG_NAME__ -> 52:envelope___control___0 ;
+8:__UG_NAME__ -> 52:envelope___control___4 ;
+9:__UG_NAME__ -> 52:envelope___control___5 ;
+10:__UG_NAME__ -> 52:envelope___control___6 ;
+11:__UG_NAME__ -> 52:envelope___control___7 ;
+51:__UG_NAME__ -> 52:gate ;
+12:__UG_NAME__ -> 73:envelope___control___0 ;
+12:__UG_NAME__ -> 73:envelope___control___4 ;
+13:__UG_NAME__ -> 73:envelope___control___5 ;
+14:__UG_NAME__ -> 73:envelope___control___6 ;
+15:__UG_NAME__ -> 73:envelope___control___7 ;
+72:__UG_NAME__ -> 73:gate ;
+0:__UG_NAME__ -> 80:envelope___control___0 ;
+0:__UG_NAME__ -> 80:envelope___control___4 ;
+1:__UG_NAME__ -> 80:envelope___control___5 ;
+2:__UG_NAME__ -> 80:envelope___control___6 ;
+3:__UG_NAME__ -> 80:envelope___control___7 ;
+61:__UG_NAME__ -> 80:gate ;
+8:__UG_NAME__ -> 22:in ;
+4:__UG_NAME__ -> 26:in ;
+5:__UG_NAME__ -> 30:in ;
+16:__UG_NAME__ -> 37:in ;
+17:__UG_NAME__ -> 41:in ;
+9:__UG_NAME__ -> 48:in ;
+0:__UG_NAME__ -> 54:in ;
+1:__UG_NAME__ -> 58:in ;
+12:__UG_NAME__ -> 65:in ;
+13:__UG_NAME__ -> 69:in ;
+20:__UG_NAME__ -> 62:bus ;
+77:__UG_NAME__ -> 78:in ;
+84:__UG_NAME__ -> 85:in ;
+73:__UG_NAME__ -> 74:a ;
+21:__UG_NAME__ -> 88:bus ;
+87:__UG_NAME__ -> 88:signals___x____fade2___0 ;
+81:__UG_NAME__ -> 88:signals___x____fade2___1 ;
+63:__UG_NAME__ -> 77:a ;
+76:__UG_NAME__ -> 77:b ;
+83:__UG_NAME__ -> 84:a ;
+76:__UG_NAME__ -> 84:b ;
+74:__UG_NAME__ -> 75:freq ;
+63:__UG_NAME__ -> 81:ina ;
+78:__UG_NAME__ -> 81:inb ;
+79:__UG_NAME__ -> 81:pan ;
+80:__UG_NAME__ -> 81:level ;
+83:__UG_NAME__ -> 87:ina ;
+85:__UG_NAME__ -> 87:inb ;
+86:__UG_NAME__ -> 87:pan ;
+80:__UG_NAME__ -> 87:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_rlpf.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_rlpf.dot
new file mode 100644
index 0000000..707f4ab
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_rlpf.dot
@@ -0,0 +1,242 @@
+digraph synthdef {
+36 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+60 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :res
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+69 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+73 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+82 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+84 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+31:__UG_NAME__ -> 36:a ;
+47:__UG_NAME__ -> 49:a ;
+48:__UG_NAME__ -> 49:b ;
+31:__UG_NAME__ -> 60:a ;
+47:__UG_NAME__ -> 70:a ;
+48:__UG_NAME__ -> 70:b ;
+22:__UG_NAME__ -> 26:a ;
+25:__UG_NAME__ -> 26:b ;
+26:__UG_NAME__ -> 30:a ;
+29:__UG_NAME__ -> 30:b ;
+38:__UG_NAME__ -> 42:a ;
+41:__UG_NAME__ -> 42:b ;
+42:__UG_NAME__ -> 46:a ;
+45:__UG_NAME__ -> 46:b ;
+55:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+59:__UG_NAME__ -> 62:a ;
+61:__UG_NAME__ -> 62:b ;
+65:__UG_NAME__ -> 66:a ;
+54:__UG_NAME__ -> 66:b ;
+66:__UG_NAME__ -> 67:a ;
+50:__UG_NAME__ -> 67:b ;
+74:__UG_NAME__ -> 78:a ;
+77:__UG_NAME__ -> 78:b ;
+78:__UG_NAME__ -> 80:a ;
+79:__UG_NAME__ -> 80:b ;
+36:__UG_NAME__ -> 37:a ;
+60:__UG_NAME__ -> 83:a ;
+24:__UG_NAME__ -> 25:a ;
+28:__UG_NAME__ -> 29:a ;
+40:__UG_NAME__ -> 41:a ;
+44:__UG_NAME__ -> 45:a ;
+35:__UG_NAME__ -> 50:a ;
+53:__UG_NAME__ -> 54:a ;
+57:__UG_NAME__ -> 58:a ;
+33:__UG_NAME__ -> 61:a ;
+76:__UG_NAME__ -> 77:a ;
+72:__UG_NAME__ -> 79:a ;
+23:__UG_NAME__ -> 24:a ;
+27:__UG_NAME__ -> 28:a ;
+32:__UG_NAME__ -> 33:a ;
+34:__UG_NAME__ -> 35:a ;
+39:__UG_NAME__ -> 40:a ;
+43:__UG_NAME__ -> 44:a ;
+52:__UG_NAME__ -> 53:a ;
+56:__UG_NAME__ -> 57:a ;
+71:__UG_NAME__ -> 72:a ;
+75:__UG_NAME__ -> 76:a ;
+4:__UG_NAME__ -> 31:envelope___control___0 ;
+4:__UG_NAME__ -> 31:envelope___control___4 ;
+5:__UG_NAME__ -> 31:envelope___control___5 ;
+6:__UG_NAME__ -> 31:envelope___control___6 ;
+7:__UG_NAME__ -> 31:envelope___control___7 ;
+30:__UG_NAME__ -> 31:gate ;
+8:__UG_NAME__ -> 47:envelope___control___0 ;
+8:__UG_NAME__ -> 47:envelope___control___4 ;
+9:__UG_NAME__ -> 47:envelope___control___5 ;
+10:__UG_NAME__ -> 47:envelope___control___6 ;
+11:__UG_NAME__ -> 47:envelope___control___7 ;
+46:__UG_NAME__ -> 47:gate ;
+12:__UG_NAME__ -> 63:envelope___control___0 ;
+12:__UG_NAME__ -> 63:envelope___control___4 ;
+13:__UG_NAME__ -> 63:envelope___control___5 ;
+14:__UG_NAME__ -> 63:envelope___control___6 ;
+15:__UG_NAME__ -> 63:envelope___control___7 ;
+62:__UG_NAME__ -> 63:gate ;
+51:__UG_NAME__ -> 68:envelope___mul____add___0 ;
+51:__UG_NAME__ -> 68:envelope___mul____add___4 ;
+17:__UG_NAME__ -> 68:envelope___control___5 ;
+18:__UG_NAME__ -> 68:envelope___control___6 ;
+19:__UG_NAME__ -> 68:envelope___control___7 ;
+67:__UG_NAME__ -> 68:gate ;
+0:__UG_NAME__ -> 81:envelope___control___0 ;
+0:__UG_NAME__ -> 81:envelope___control___4 ;
+1:__UG_NAME__ -> 81:envelope___control___5 ;
+2:__UG_NAME__ -> 81:envelope___control___6 ;
+3:__UG_NAME__ -> 81:envelope___control___7 ;
+80:__UG_NAME__ -> 81:gate ;
+4:__UG_NAME__ -> 23:in ;
+5:__UG_NAME__ -> 27:in ;
+13:__UG_NAME__ -> 32:in ;
+17:__UG_NAME__ -> 34:in ;
+8:__UG_NAME__ -> 39:in ;
+9:__UG_NAME__ -> 43:in ;
+51:__UG_NAME__ -> 52:in ;
+12:__UG_NAME__ -> 56:in ;
+1:__UG_NAME__ -> 71:in ;
+0:__UG_NAME__ -> 75:in ;
+20:__UG_NAME__ -> 48:bus ;
+63:__UG_NAME__ -> 64:a ;
+16:__UG_NAME__ -> 51:in ;
+21:__UG_NAME__ -> 85:bus ;
+84:__UG_NAME__ -> 85:signals___x____fade2___0 ;
+82:__UG_NAME__ -> 85:signals___x____fade2___1 ;
+49:__UG_NAME__ -> 69:in ;
+64:__UG_NAME__ -> 69:freq ;
+68:__UG_NAME__ -> 69:rq ;
+70:__UG_NAME__ -> 73:in ;
+64:__UG_NAME__ -> 73:freq ;
+68:__UG_NAME__ -> 73:rq ;
+49:__UG_NAME__ -> 82:ina ;
+69:__UG_NAME__ -> 82:inb ;
+37:__UG_NAME__ -> 82:pan ;
+81:__UG_NAME__ -> 82:level ;
+70:__UG_NAME__ -> 84:ina ;
+73:__UG_NAME__ -> 84:inb ;
+83:__UG_NAME__ -> 84:pan ;
+81:__UG_NAME__ -> 84:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_slicer.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_slicer.dot
new file mode 100644
index 0000000..2a0d047
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_slicer.dot
@@ -0,0 +1,615 @@
+digraph synthdef {
+105 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <b> 6.2831855|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+152 [label = "{{ <b> -1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+198 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+204 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+213 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+217 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+218 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+221 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+148 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+158 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+162 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+167 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+171 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+178 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+186 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+190 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+192 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+193 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+202 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+210 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+216 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+150 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+153 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+205 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+214 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+151 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <b> |<a> } |<__UG_NAME__>\< }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+143 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+147 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+157 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+161 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+166 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+170 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+177 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+181 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+185 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+189 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+201 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+209 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+215 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+134 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+146 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+160 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+165 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+169 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+176 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+180 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+184 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+188 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+200 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+208 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+212 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <interpolation> interpolation 2.0|<loop> loop 1.0|<phase> phase|<bufnum> bufnum|<num____channels> num-channels 1} |<__UG_NAME__>buf-rd }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <hi> hi 1.0|<lo> lo 0.0|<in> in} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <hi> hi 1.0|<lo> lo 0.0|<in> in} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :phase
+ default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :phase_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :phase_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :phase_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :amp_min
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :amp_min_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :amp_min_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :amp_min_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :amp_max
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :amp_max_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :amp_max_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :amp_max_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :smooth
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :smooth_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :smooth_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :smooth_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :smooth_up
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :smooth_up_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :smooth_up_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :smooth_up_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :smooth_down
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "control
+ :smooth_down_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "control
+ :smooth_down_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "control
+ :smooth_down_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+40 [label = "control
+ :probability
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+41 [label = "control
+ :probability_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+42 [label = "control
+ :probability_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "control
+ :probability_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+44 [label = "control
+ :prob_pos
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+45 [label = "control
+ :prob_pos_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+46 [label = "control
+ :prob_pos_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+47 [label = "control
+ :prob_pos_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+48 [label = "control
+ :phase_offset
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+49 [label = "control
+ :wave
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+50 [label = "control
+ :invert_wave
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+51 [label = "control
+ :seed
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+52 [label = "control
+ :rand_buf
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+53 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+54 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+67 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___clip___0>|1.0|-99|-99|<envelope___clip___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+149 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+163 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+172 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+194 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+196 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+203 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+219 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+145 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+155 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+159 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+168 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+175 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+179 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+183 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+187 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+199 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+206 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+211 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <phase> phase 0.0|<freq> freq} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+140 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+156 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+164 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+174 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+182 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+191 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+207 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+197 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+195 [label = "{{ <lag____time> lag-time|<in> in} |<__UG_NAME__>lag }" style="bold, rounded" shape=record rankdir=LR];
+173 [label = "{{ <lag____time____down> lag-time-down|<lag____time____up> lag-time-up|<in> in} |<__UG_NAME__>lag-ud }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <width> width|<iphase> iphase|<freq> freq} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <add> add -1.0|<mul> mul 2.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+154 [label = "{{ <add> add|<mul> mul|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+223 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+122 [label = "{{ <reset> reset 0.0|<trig> trig} |<__UG_NAME__>pulse-count }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ {{<array___env____gen___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ {{<array___binary____op____u____gen___0>|<array___select___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase|<freq> freq} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+220 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+222 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+104:__UG_NAME__ -> 105:b ;
+106:__UG_NAME__ -> 107:b ;
+48:__UG_NAME__ -> 108:b ;
+110:__UG_NAME__ -> 111:b ;
+79:__UG_NAME__ -> 112:b ;
+116:__UG_NAME__ -> 117:a ;
+107:__UG_NAME__ -> 120:a ;
+119:__UG_NAME__ -> 120:b ;
+151:__UG_NAME__ -> 152:a ;
+196:__UG_NAME__ -> 198:a ;
+197:__UG_NAME__ -> 198:b ;
+203:__UG_NAME__ -> 204:a ;
+203:__UG_NAME__ -> 213:a ;
+195:__UG_NAME__ -> 217:a ;
+198:__UG_NAME__ -> 217:b ;
+196:__UG_NAME__ -> 218:a ;
+197:__UG_NAME__ -> 218:b ;
+195:__UG_NAME__ -> 221:a ;
+218:__UG_NAME__ -> 221:b ;
+58:__UG_NAME__ -> 62:a ;
+61:__UG_NAME__ -> 62:b ;
+62:__UG_NAME__ -> 66:a ;
+65:__UG_NAME__ -> 66:b ;
+69:__UG_NAME__ -> 73:a ;
+72:__UG_NAME__ -> 73:b ;
+73:__UG_NAME__ -> 77:a ;
+76:__UG_NAME__ -> 77:b ;
+80:__UG_NAME__ -> 86:a ;
+85:__UG_NAME__ -> 86:b ;
+86:__UG_NAME__ -> 90:a ;
+89:__UG_NAME__ -> 90:b ;
+92:__UG_NAME__ -> 97:a ;
+96:__UG_NAME__ -> 97:b ;
+97:__UG_NAME__ -> 101:a ;
+100:__UG_NAME__ -> 101:b ;
+108:__UG_NAME__ -> 109:a ;
+108:__UG_NAME__ -> 114:a ;
+48:__UG_NAME__ -> 116:a ;
+51:__UG_NAME__ -> 123:a ;
+122:__UG_NAME__ -> 123:b ;
+126:__UG_NAME__ -> 132:a ;
+131:__UG_NAME__ -> 132:b ;
+132:__UG_NAME__ -> 136:a ;
+135:__UG_NAME__ -> 136:b ;
+140:__UG_NAME__ -> 144:a ;
+143:__UG_NAME__ -> 144:b ;
+144:__UG_NAME__ -> 148:a ;
+147:__UG_NAME__ -> 148:b ;
+156:__UG_NAME__ -> 158:a ;
+157:__UG_NAME__ -> 158:b ;
+158:__UG_NAME__ -> 162:a ;
+161:__UG_NAME__ -> 162:b ;
+164:__UG_NAME__ -> 167:a ;
+166:__UG_NAME__ -> 167:b ;
+167:__UG_NAME__ -> 171:a ;
+170:__UG_NAME__ -> 171:b ;
+174:__UG_NAME__ -> 178:a ;
+177:__UG_NAME__ -> 178:b ;
+182:__UG_NAME__ -> 186:a ;
+185:__UG_NAME__ -> 186:b ;
+186:__UG_NAME__ -> 190:a ;
+189:__UG_NAME__ -> 190:b ;
+191:__UG_NAME__ -> 192:a ;
+181:__UG_NAME__ -> 192:b ;
+192:__UG_NAME__ -> 193:a ;
+57:__UG_NAME__ -> 193:b ;
+178:__UG_NAME__ -> 202:a ;
+201:__UG_NAME__ -> 202:b ;
+207:__UG_NAME__ -> 210:a ;
+209:__UG_NAME__ -> 210:b ;
+210:__UG_NAME__ -> 216:a ;
+215:__UG_NAME__ -> 216:b ;
+105:__UG_NAME__ -> 106:a ;
+112:__UG_NAME__ -> 113:a ;
+91:__UG_NAME__ -> 150:a ;
+149:__UG_NAME__ -> 150:b ;
+149:__UG_NAME__ -> 153:a ;
+152:__UG_NAME__ -> 153:b ;
+204:__UG_NAME__ -> 205:a ;
+213:__UG_NAME__ -> 214:a ;
+67:__UG_NAME__ -> 68:b ;
+150:__UG_NAME__ -> 151:a ;
+124:__UG_NAME__ -> 125:a ;
+102:__UG_NAME__ -> 125:b ;
+56:__UG_NAME__ -> 57:a ;
+60:__UG_NAME__ -> 61:a ;
+64:__UG_NAME__ -> 65:a ;
+71:__UG_NAME__ -> 72:a ;
+75:__UG_NAME__ -> 76:a ;
+84:__UG_NAME__ -> 85:a ;
+88:__UG_NAME__ -> 89:a ;
+95:__UG_NAME__ -> 96:a ;
+99:__UG_NAME__ -> 100:a ;
+102:__UG_NAME__ -> 103:a ;
+50:__UG_NAME__ -> 104:a ;
+130:__UG_NAME__ -> 131:a ;
+134:__UG_NAME__ -> 135:a ;
+142:__UG_NAME__ -> 143:a ;
+146:__UG_NAME__ -> 147:a ;
+82:__UG_NAME__ -> 157:a ;
+160:__UG_NAME__ -> 161:a ;
+165:__UG_NAME__ -> 166:a ;
+169:__UG_NAME__ -> 170:a ;
+176:__UG_NAME__ -> 177:a ;
+180:__UG_NAME__ -> 181:a ;
+184:__UG_NAME__ -> 185:a ;
+188:__UG_NAME__ -> 189:a ;
+200:__UG_NAME__ -> 201:a ;
+208:__UG_NAME__ -> 209:a ;
+212:__UG_NAME__ -> 215:a ;
+55:__UG_NAME__ -> 56:a ;
+59:__UG_NAME__ -> 60:a ;
+63:__UG_NAME__ -> 64:a ;
+70:__UG_NAME__ -> 71:a ;
+74:__UG_NAME__ -> 75:a ;
+81:__UG_NAME__ -> 82:a ;
+83:__UG_NAME__ -> 84:a ;
+87:__UG_NAME__ -> 88:a ;
+94:__UG_NAME__ -> 95:a ;
+98:__UG_NAME__ -> 99:a ;
+129:__UG_NAME__ -> 130:a ;
+133:__UG_NAME__ -> 134:a ;
+141:__UG_NAME__ -> 142:a ;
+145:__UG_NAME__ -> 146:a ;
+159:__UG_NAME__ -> 160:a ;
+155:__UG_NAME__ -> 165:a ;
+168:__UG_NAME__ -> 169:a ;
+175:__UG_NAME__ -> 176:a ;
+179:__UG_NAME__ -> 180:a ;
+183:__UG_NAME__ -> 184:a ;
+187:__UG_NAME__ -> 188:a ;
+199:__UG_NAME__ -> 200:a ;
+206:__UG_NAME__ -> 208:a ;
+211:__UG_NAME__ -> 212:a ;
+52:__UG_NAME__ -> 124:bufnum ;
+123:__UG_NAME__ -> 124:phase ;
+40:__UG_NAME__ -> 93:in ;
+44:__UG_NAME__ -> 127:in ;
+12:__UG_NAME__ -> 67:envelope___control___0 ;
+12:__UG_NAME__ -> 67:envelope___control___4 ;
+13:__UG_NAME__ -> 67:envelope___control___5 ;
+14:__UG_NAME__ -> 67:envelope___control___6 ;
+15:__UG_NAME__ -> 67:envelope___control___7 ;
+66:__UG_NAME__ -> 67:gate ;
+24:__UG_NAME__ -> 78:envelope___control___0 ;
+24:__UG_NAME__ -> 78:envelope___control___4 ;
+25:__UG_NAME__ -> 78:envelope___control___5 ;
+26:__UG_NAME__ -> 78:envelope___control___6 ;
+27:__UG_NAME__ -> 78:envelope___control___7 ;
+77:__UG_NAME__ -> 78:gate ;
+20:__UG_NAME__ -> 91:envelope___control___0 ;
+20:__UG_NAME__ -> 91:envelope___control___4 ;
+21:__UG_NAME__ -> 91:envelope___control___5 ;
+22:__UG_NAME__ -> 91:envelope___control___6 ;
+23:__UG_NAME__ -> 91:envelope___control___7 ;
+90:__UG_NAME__ -> 91:gate ;
+93:__UG_NAME__ -> 102:envelope___clip___0 ;
+93:__UG_NAME__ -> 102:envelope___clip___4 ;
+41:__UG_NAME__ -> 102:envelope___control___5 ;
+42:__UG_NAME__ -> 102:envelope___control___6 ;
+43:__UG_NAME__ -> 102:envelope___control___7 ;
+101:__UG_NAME__ -> 102:gate ;
+128:__UG_NAME__ -> 137:envelope___mul____add___0 ;
+128:__UG_NAME__ -> 137:envelope___mul____add___4 ;
+45:__UG_NAME__ -> 137:envelope___control___5 ;
+46:__UG_NAME__ -> 137:envelope___control___6 ;
+47:__UG_NAME__ -> 137:envelope___control___7 ;
+136:__UG_NAME__ -> 137:gate ;
+16:__UG_NAME__ -> 149:envelope___control___0 ;
+16:__UG_NAME__ -> 149:envelope___control___4 ;
+17:__UG_NAME__ -> 149:envelope___control___5 ;
+18:__UG_NAME__ -> 149:envelope___control___6 ;
+19:__UG_NAME__ -> 149:envelope___control___7 ;
+148:__UG_NAME__ -> 149:gate ;
+32:__UG_NAME__ -> 163:envelope___control___0 ;
+32:__UG_NAME__ -> 163:envelope___control___4 ;
+33:__UG_NAME__ -> 163:envelope___control___5 ;
+34:__UG_NAME__ -> 163:envelope___control___6 ;
+35:__UG_NAME__ -> 163:envelope___control___7 ;
+162:__UG_NAME__ -> 163:gate ;
+36:__UG_NAME__ -> 172:envelope___control___0 ;
+36:__UG_NAME__ -> 172:envelope___control___4 ;
+37:__UG_NAME__ -> 172:envelope___control___5 ;
+38:__UG_NAME__ -> 172:envelope___control___6 ;
+39:__UG_NAME__ -> 172:envelope___control___7 ;
+171:__UG_NAME__ -> 172:gate ;
+28:__UG_NAME__ -> 194:envelope___control___0 ;
+28:__UG_NAME__ -> 194:envelope___control___4 ;
+29:__UG_NAME__ -> 194:envelope___control___5 ;
+30:__UG_NAME__ -> 194:envelope___control___6 ;
+31:__UG_NAME__ -> 194:envelope___control___7 ;
+193:__UG_NAME__ -> 194:gate ;
+8:__UG_NAME__ -> 196:envelope___control___0 ;
+8:__UG_NAME__ -> 196:envelope___control___4 ;
+9:__UG_NAME__ -> 196:envelope___control___5 ;
+10:__UG_NAME__ -> 196:envelope___control___6 ;
+11:__UG_NAME__ -> 196:envelope___control___7 ;
+190:__UG_NAME__ -> 196:gate ;
+4:__UG_NAME__ -> 203:envelope___control___0 ;
+4:__UG_NAME__ -> 203:envelope___control___4 ;
+5:__UG_NAME__ -> 203:envelope___control___5 ;
+6:__UG_NAME__ -> 203:envelope___control___6 ;
+7:__UG_NAME__ -> 203:envelope___control___7 ;
+202:__UG_NAME__ -> 203:gate ;
+0:__UG_NAME__ -> 219:envelope___control___0 ;
+0:__UG_NAME__ -> 219:envelope___control___4 ;
+1:__UG_NAME__ -> 219:envelope___control___5 ;
+2:__UG_NAME__ -> 219:envelope___control___6 ;
+3:__UG_NAME__ -> 219:envelope___control___7 ;
+216:__UG_NAME__ -> 219:gate ;
+29:__UG_NAME__ -> 55:in ;
+12:__UG_NAME__ -> 59:in ;
+13:__UG_NAME__ -> 63:in ;
+24:__UG_NAME__ -> 70:in ;
+25:__UG_NAME__ -> 74:in ;
+32:__UG_NAME__ -> 81:in ;
+20:__UG_NAME__ -> 83:in ;
+21:__UG_NAME__ -> 87:in ;
+93:__UG_NAME__ -> 94:in ;
+41:__UG_NAME__ -> 98:in ;
+128:__UG_NAME__ -> 129:in ;
+45:__UG_NAME__ -> 133:in ;
+16:__UG_NAME__ -> 141:in ;
+17:__UG_NAME__ -> 145:in ;
+36:__UG_NAME__ -> 155:in ;
+33:__UG_NAME__ -> 159:in ;
+37:__UG_NAME__ -> 168:in ;
+4:__UG_NAME__ -> 175:in ;
+28:__UG_NAME__ -> 179:in ;
+8:__UG_NAME__ -> 183:in ;
+9:__UG_NAME__ -> 187:in ;
+5:__UG_NAME__ -> 199:in ;
+0:__UG_NAME__ -> 206:in ;
+1:__UG_NAME__ -> 211:in ;
+68:__UG_NAME__ -> 121:freq ;
+53:__UG_NAME__ -> 197:bus ;
+173:__UG_NAME__ -> 195:in ;
+194:__UG_NAME__ -> 195:lag____time ;
+154:__UG_NAME__ -> 173:in ;
+163:__UG_NAME__ -> 173:lag____time____up ;
+172:__UG_NAME__ -> 173:lag____time____down ;
+68:__UG_NAME__ -> 79:freq ;
+48:__UG_NAME__ -> 79:iphase ;
+78:__UG_NAME__ -> 79:width ;
+68:__UG_NAME__ -> 110:freq ;
+109:__UG_NAME__ -> 110:iphase ;
+68:__UG_NAME__ -> 115:freq ;
+114:__UG_NAME__ -> 115:iphase ;
+127:__UG_NAME__ -> 128:in ;
+139:__UG_NAME__ -> 154:in ;
+151:__UG_NAME__ -> 154:mul ;
+153:__UG_NAME__ -> 154:add ;
+54:__UG_NAME__ -> 223:bus ;
+220:__UG_NAME__ -> 223:signals___x____fade2___0 ;
+222:__UG_NAME__ -> 223:signals___x____fade2___1 ;
+121:__UG_NAME__ -> 122:trig ;
+49:__UG_NAME__ -> 119:which ;
+111:__UG_NAME__ -> 119:array___binary____op____u____gen___0 ;
+113:__UG_NAME__ -> 119:array___binary____op____u____gen___1 ;
+115:__UG_NAME__ -> 119:array___lf____tri___2 ;
+118:__UG_NAME__ -> 119:array___sin____osc___3 ;
+125:__UG_NAME__ -> 138:which ;
+137:__UG_NAME__ -> 138:array___env____gen___0 ;
+120:__UG_NAME__ -> 138:array___binary____op____u____gen___1 ;
+103:__UG_NAME__ -> 139:which ;
+120:__UG_NAME__ -> 139:array___binary____op____u____gen___0 ;
+138:__UG_NAME__ -> 139:array___select___1 ;
+68:__UG_NAME__ -> 118:freq ;
+117:__UG_NAME__ -> 118:phase ;
+198:__UG_NAME__ -> 220:ina ;
+217:__UG_NAME__ -> 220:inb ;
+214:__UG_NAME__ -> 220:pan ;
+219:__UG_NAME__ -> 220:level ;
+218:__UG_NAME__ -> 222:ina ;
+221:__UG_NAME__ -> 222:inb ;
+205:__UG_NAME__ -> 222:pan ;
+219:__UG_NAME__ -> 222:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_tanh.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_tanh.dot
new file mode 100644
index 0000000..8f0c625
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_tanh.dot
@@ -0,0 +1,225 @@
+digraph synthdef {
+30 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+59 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+76 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+22 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+46 [label = "{{ <b> 8.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+28 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+21 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+20 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :krunch
+ default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :krunch_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :krunch_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :krunch_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+19 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+18 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+80 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+29 [label = "{{ {{<array___env____gen___0>|1.0E-4}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>tanh }" style="filled, bold, rounded"  shape=record rankdir=LR];
+74 [label = "{{ <b> |<a> } |<__UG_NAME__>tanh }" style="filled, bold, rounded"  shape=record rankdir=LR];
+71 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+79 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+29:__UG_NAME__ -> 30:b ;
+40:__UG_NAME__ -> 42:a ;
+41:__UG_NAME__ -> 42:b ;
+30:__UG_NAME__ -> 43:a ;
+42:__UG_NAME__ -> 43:b ;
+45:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+58:__UG_NAME__ -> 59:a ;
+40:__UG_NAME__ -> 72:a ;
+41:__UG_NAME__ -> 72:b ;
+30:__UG_NAME__ -> 73:a ;
+72:__UG_NAME__ -> 73:b ;
+58:__UG_NAME__ -> 76:a ;
+75:__UG_NAME__ -> 78:a ;
+47:__UG_NAME__ -> 78:b ;
+18:__UG_NAME__ -> 22:a ;
+21:__UG_NAME__ -> 22:b ;
+22:__UG_NAME__ -> 26:a ;
+25:__UG_NAME__ -> 26:b ;
+31:__UG_NAME__ -> 35:a ;
+34:__UG_NAME__ -> 35:b ;
+35:__UG_NAME__ -> 39:a ;
+38:__UG_NAME__ -> 39:b ;
+46:__UG_NAME__ -> 47:b ;
+49:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+53:__UG_NAME__ -> 57:a ;
+56:__UG_NAME__ -> 57:b ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+65:__UG_NAME__ -> 69:a ;
+68:__UG_NAME__ -> 69:b ;
+59:__UG_NAME__ -> 60:a ;
+76:__UG_NAME__ -> 77:a ;
+44:__UG_NAME__ -> 45:a ;
+30:__UG_NAME__ -> 45:b ;
+30:__UG_NAME__ -> 46:a ;
+74:__UG_NAME__ -> 75:a ;
+30:__UG_NAME__ -> 75:b ;
+27:__UG_NAME__ -> 28:b ;
+20:__UG_NAME__ -> 21:a ;
+24:__UG_NAME__ -> 25:a ;
+33:__UG_NAME__ -> 34:a ;
+37:__UG_NAME__ -> 38:a ;
+51:__UG_NAME__ -> 52:a ;
+55:__UG_NAME__ -> 56:a ;
+63:__UG_NAME__ -> 64:a ;
+67:__UG_NAME__ -> 68:a ;
+19:__UG_NAME__ -> 20:a ;
+23:__UG_NAME__ -> 24:a ;
+32:__UG_NAME__ -> 33:a ;
+36:__UG_NAME__ -> 37:a ;
+50:__UG_NAME__ -> 51:a ;
+54:__UG_NAME__ -> 55:a ;
+62:__UG_NAME__ -> 63:a ;
+66:__UG_NAME__ -> 67:a ;
+8:__UG_NAME__ -> 27:envelope___control___0 ;
+8:__UG_NAME__ -> 27:envelope___control___4 ;
+9:__UG_NAME__ -> 27:envelope___control___5 ;
+10:__UG_NAME__ -> 27:envelope___control___6 ;
+11:__UG_NAME__ -> 27:envelope___control___7 ;
+26:__UG_NAME__ -> 27:gate ;
+12:__UG_NAME__ -> 40:envelope___control___0 ;
+12:__UG_NAME__ -> 40:envelope___control___4 ;
+13:__UG_NAME__ -> 40:envelope___control___5 ;
+14:__UG_NAME__ -> 40:envelope___control___6 ;
+15:__UG_NAME__ -> 40:envelope___control___7 ;
+39:__UG_NAME__ -> 40:gate ;
+4:__UG_NAME__ -> 58:envelope___control___0 ;
+4:__UG_NAME__ -> 58:envelope___control___4 ;
+5:__UG_NAME__ -> 58:envelope___control___5 ;
+6:__UG_NAME__ -> 58:envelope___control___6 ;
+7:__UG_NAME__ -> 58:envelope___control___7 ;
+57:__UG_NAME__ -> 58:gate ;
+0:__UG_NAME__ -> 70:envelope___control___0 ;
+0:__UG_NAME__ -> 70:envelope___control___4 ;
+1:__UG_NAME__ -> 70:envelope___control___5 ;
+2:__UG_NAME__ -> 70:envelope___control___6 ;
+3:__UG_NAME__ -> 70:envelope___control___7 ;
+69:__UG_NAME__ -> 70:gate ;
+8:__UG_NAME__ -> 19:in ;
+9:__UG_NAME__ -> 23:in ;
+12:__UG_NAME__ -> 32:in ;
+13:__UG_NAME__ -> 36:in ;
+4:__UG_NAME__ -> 50:in ;
+5:__UG_NAME__ -> 54:in ;
+0:__UG_NAME__ -> 62:in ;
+1:__UG_NAME__ -> 66:in ;
+16:__UG_NAME__ -> 41:bus ;
+17:__UG_NAME__ -> 80:bus ;
+79:__UG_NAME__ -> 80:signals___x____fade2___0 ;
+71:__UG_NAME__ -> 80:signals___x____fade2___1 ;
+28:__UG_NAME__ -> 29:which ;
+27:__UG_NAME__ -> 29:array___env____gen___0 ;
+43:__UG_NAME__ -> 44:a ;
+73:__UG_NAME__ -> 74:a ;
+42:__UG_NAME__ -> 71:ina ;
+48:__UG_NAME__ -> 71:inb ;
+60:__UG_NAME__ -> 71:pan ;
+70:__UG_NAME__ -> 71:level ;
+72:__UG_NAME__ -> 79:ina ;
+78:__UG_NAME__ -> 79:inb ;
+77:__UG_NAME__ -> 79:pan ;
+70:__UG_NAME__ -> 79:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_vowel.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_vowel.dot
new file mode 100644
index 0000000..3308bd0
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_vowel.dot
@@ -0,0 +1,425 @@
+digraph synthdef {
+16 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+18 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+19 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+20 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+21 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+140 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+143 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+145 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+148 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+151 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+154 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+157 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+159 [label = "{{ <b> |<a> 5.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+92 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+105 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+124 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+147 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+150 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+153 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+156 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+17 [label = "{{ <b> 4.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> 5.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 5.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> 5.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 4.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> 4.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> 3.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> 3.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> 3.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+158 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+134 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <bw> bw|<freq> freq|<in> in} |<__UG_NAME__>b-band-pass }" style="filled, bold, rounded"  shape=record rankdir=LR];
+70 [label = "{{ <bw> bw|<freq> freq|<in> in} |<__UG_NAME__>b-band-pass }" style="filled, bold, rounded"  shape=record rankdir=LR];
+88 [label = "{{ <bw> bw|<freq> freq|<in> in} |<__UG_NAME__>b-band-pass }" style="filled, bold, rounded"  shape=record rankdir=LR];
+100 [label = "{{ <bw> bw|<freq> freq|<in> in} |<__UG_NAME__>b-band-pass }" style="filled, bold, rounded"  shape=record rankdir=LR];
+118 [label = "{{ <bw> bw|<freq> freq|<in> in} |<__UG_NAME__>b-band-pass }" style="filled, bold, rounded"  shape=record rankdir=LR];
+144 [label = "{{ <bw> bw|<freq> freq|<in> in} |<__UG_NAME__>b-band-pass }" style="filled, bold, rounded"  shape=record rankdir=LR];
+146 [label = "{{ <bw> bw|<freq> freq|<in> in} |<__UG_NAME__>b-band-pass }" style="filled, bold, rounded"  shape=record rankdir=LR];
+149 [label = "{{ <bw> bw|<freq> freq|<in> in} |<__UG_NAME__>b-band-pass }" style="filled, bold, rounded"  shape=record rankdir=LR];
+152 [label = "{{ <bw> bw|<freq> freq|<in> in} |<__UG_NAME__>b-band-pass }" style="filled, bold, rounded"  shape=record rankdir=LR];
+155 [label = "{{ <bw> bw|<freq> freq|<in> in} |<__UG_NAME__>b-band-pass }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :voice
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :vowel_sound
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+161 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+24 [label = "{{ {{1/80|1/90|1/120|1/130|1/140|1/60|1/100|1/120|1/150|1/200|1/60|1/90|1/100|1/120|1/120|1/70|1/80|1/100|1/130|1/135|1/50|1/60|1/170|1/180|1/200|1/80|1/90|1/120|1/130|1/140|1/60|1/80|1/120|1/150|1/200|1/50|1/100|1/120|1/150|1/200|1/70|1/80|1/100|1/130|1/135|1/50|1/60|1/170|1/180|1/200|1/80|1/90|1/120|1/130|1/140|1/70|1/80|1/100|1/120|1/120|1/40|1/90|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120|1/40|1/60|1/100|1/120|1/120|1/80|1/90|1/120|1/130|1/140|1/70|1/80|1/100|1/120|1/120|1/40|1/90|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120|1/40|1/60|1/100|1/120|1/120|1/60|1/70|1/110|1/120|1/130|1/40|1/80|1/100|1/120|1/120|1/60|1/90|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ {{800|1150|2900|3900|4950|350|2000|2800|3600|4950|270|2140|2950|3900|4950|450|800|2830|3800|4950|325|700|2700|3800|4950|800|1150|2800|3500|4950|400|1600|2700|3300|4950|350|1700|2700|3700|4950|450|800|2830|3500|4950|325|700|2530|3500|4950|660|1120|2750|3000|3350|440|1800|2700|3000|3300|270|1850|2900|3350|3590|430|820|2700|3000|3300|370|630|2750|3000|3400|650|1080|2650|2900|3250|400|1700|2600|3200|3580|290|1870|2800|3250|3540|400|800|2600|2800|3000|350|600|2700|2900|3300|600|1040|2250|2450|2750|400|1620|2400|2800|3100|250|1750|2600|3050|3340|400|750|2400|2600|2900|350|600|2400|2675|2950}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ {{1/80|1/90|1/120|1/130|1/140|1/60|1/100|1/120|1/150|1/200|1/60|1/90|1/100|1/120|1/120|1/70|1/80|1/100|1/130|1/135|1/50|1/60|1/170|1/180|1/200|1/80|1/90|1/120|1/130|1/140|1/60|1/80|1/120|1/150|1/200|1/50|1/100|1/120|1/150|1/200|1/70|1/80|1/100|1/130|1/135|1/50|1/60|1/170|1/180|1/200|1/80|1/90|1/120|1/130|1/140|1/70|1/80|1/100|1/120|1/120|1/40|1/90|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120|1/40|1/60|1/100|1/120|1/120|1/80|1/90|1/120|1/130|1/140|1/70|1/80|1/100|1/120|1/120|1/40|1/90|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120|1/40|1/60|1/100|1/120|1/120|1/60|1/70|1/110|1/120|1/130|1/40|1/80|1/100|1/120|1/120|1/60|1/90|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ {{1.0|0.5011872336272722|0.025118864315095784|0.09999999999999998|0.0031622776601683764|1.0|0.09999999999999998|0.17782794100389226|1/100|0.0015848931924611136|1.0|0.251188643150958|0.050118723362727206|0.050118723362727206|0.006309573444801925|1.0|0.2818382931264453|0.0794328234724281|0.0794328234724281|0.0031622776601683764|1.0|0.1584893192461113|0.017782794100389226|1/100|9.999999999999994E-4|1.0|0.6309573444801931|0.09999999999999998|0.015848931924611127|9.999999999999994E-4|1.0|0.06309573444801932|0.031622776601683784|0.017782794100389226|9.999999999999994E-4|1.0|0.09999999999999998|0.031622776601683784|0.015848931924611127|9.999999999999994E-4|1.0|0.3548133892335754|0.1584893192461113|0.03981071705534973|0.001778279410038922|1.0|0.251188643150958|0.031622776601683784|1/100|6.309573444801923E-4|1.0|0.5011872336272722|0.07079457843841379|0.06309573444801932|0.012589254117941666|1.0|0.19952623149688797|0.12589254117941667|0.09999999999999998|0.09999999999999998|1.0|0.06309573444801932|0.06309573444801932|0.015848931924611127|0.015848931924611127|1.0|0.3162277660168379|0.050118723362727206|0.0794328234724281|0.019952623149688792|1.0|0.09999999999999998|0.07079457843841379|0.031622776601683784|0.019952623149688792|1.0|0.5011872336272722|0.44668359215096315|0.3981071705534972|0.0794328234724281|1.0|0.19952623149688797|0.251188643150958|0.19952623149688797|0.09999999999999998|1.0|0.17782794100389226|0.12589254117941667|0.09999999999999998|0.031622776601683784|1.0|0.3162277660168379|0.251188643150958|0.251188643150958|0.050118723362727206|1.0|0.09999999999999998|0.14125375446227542|0.19952623149688797|0.050118723362727206|1.0|0.44668359215096315|0.3548133892335754|0.3548133892335754|0.09999999999999998|1.0|0.251188643150958|0.3548133892335754|0.251188643150958|0.12589254117941667|1.0|0.031622776601683784|0.1584893192461113|0.0794328234724281|0.03981071705534973|1.0|0.2818382931264453|0.08912509381337454|0.09999999999999998|1/100|1.0|0.09999999999999998|0.025118864315095784|0.03981071705534973|0.015848931924611127}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ {{800|1150|2900|3900|4950|350|2000|2800|3600|4950|270|2140|2950|3900|4950|450|800|2830|3800|4950|325|700|2700|3800|4950|800|1150|2800|3500|4950|400|1600|2700|3300|4950|350|1700|2700|3700|4950|450|800|2830|3500|4950|325|700|2530|3500|4950|660|1120|2750|3000|3350|440|1800|2700|3000|3300|270|1850|2900|3350|3590|430|820|2700|3000|3300|370|630|2750|3000|3400|650|1080|2650|2900|3250|400|1700|2600|3200|3580|290|1870|2800|3250|3540|400|800|2600|2800|3000|350|600|2700|2900|3300|600|1040|2250|2450|2750|400|1620|2400|2800|3100|250|1750|2600|3050|3340|400|750|2400|2600|2900|350|600|2400|2675|2950}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ {{1/80|1/90|1/120|1/130|1/140|1/60|1/100|1/120|1/150|1/200|1/60|1/90|1/100|1/120|1/120|1/70|1/80|1/100|1/130|1/135|1/50|1/60|1/170|1/180|1/200|1/80|1/90|1/120|1/130|1/140|1/60|1/80|1/120|1/150|1/200|1/50|1/100|1/120|1/150|1/200|1/70|1/80|1/100|1/130|1/135|1/50|1/60|1/170|1/180|1/200|1/80|1/90|1/120|1/130|1/140|1/70|1/80|1/100|1/120|1/120|1/40|1/90|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120|1/40|1/60|1/100|1/120|1/120|1/80|1/90|1/120|1/130|1/140|1/70|1/80|1/100|1/120|1/120|1/40|1/90|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120|1/40|1/60|1/100|1/120|1/120|1/60|1/70|1/110|1/120|1/130|1/40|1/80|1/100|1/120|1/120|1/60|1/90|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ {{1.0|0.5011872336272722|0.025118864315095784|0.09999999999999998|0.0031622776601683764|1.0|0.09999999999999998|0.17782794100389226|1/100|0.0015848931924611136|1.0|0.251188643150958|0.050118723362727206|0.050118723362727206|0.006309573444801925|1.0|0.2818382931264453|0.0794328234724281|0.0794328234724281|0.0031622776601683764|1.0|0.1584893192461113|0.017782794100389226|1/100|9.999999999999994E-4|1.0|0.6309573444801931|0.09999999999999998|0.015848931924611127|9.999999999999994E-4|1.0|0.06309573444801932|0.031622776601683784|0.017782794100389226|9.999999999999994E-4|1.0|0.09999999999999998|0.031622776601683784|0.015848931924611127|9.999999999999994E-4|1.0|0.3548133892335754|0.1584893192461113|0.03981071705534973|0.001778279410038922|1.0|0.251188643150958|0.031622776601683784|1/100|6.309573444801923E-4|1.0|0.5011872336272722|0.07079457843841379|0.06309573444801932|0.012589254117941666|1.0|0.19952623149688797|0.12589254117941667|0.09999999999999998|0.09999999999999998|1.0|0.06309573444801932|0.06309573444801932|0.015848931924611127|0.015848931924611127|1.0|0.3162277660168379|0.050118723362727206|0.0794328234724281|0.019952623149688792|1.0|0.09999999999999998|0.07079457843841379|0.031622776601683784|0.019952623149688792|1.0|0.5011872336272722|0.44668359215096315|0.3981071705534972|0.0794328234724281|1.0|0.19952623149688797|0.251188643150958|0.19952623149688797|0.09999999999999998|1.0|0.17782794100389226|0.12589254117941667|0.09999999999999998|0.031622776601683784|1.0|0.3162277660168379|0.251188643150958|0.251188643150958|0.050118723362727206|1.0|0.09999999999999998|0.14125375446227542|0.19952623149688797|0.050118723362727206|1.0|0.44668359215096315|0.3548133892335754|0.3548133892335754|0.09999999999999998|1.0|0.251188643150958|0.3548133892335754|0.251188643150958|0.12589254117941667|1.0|0.031622776601683784|0.1584893192461113|0.0794328234724281|0.03981071705534973|1.0|0.2818382931264453|0.08912509381337454|0.09999999999999998|1/100|1.0|0.09999999999999998|0.025118864315095784|0.03981071705534973|0.015848931924611127}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ {{800|1150|2900|3900|4950|350|2000|2800|3600|4950|270|2140|2950|3900|4950|450|800|2830|3800|4950|325|700|2700|3800|4950|800|1150|2800|3500|4950|400|1600|2700|3300|4950|350|1700|2700|3700|4950|450|800|2830|3500|4950|325|700|2530|3500|4950|660|1120|2750|3000|3350|440|1800|2700|3000|3300|270|1850|2900|3350|3590|430|820|2700|3000|3300|370|630|2750|3000|3400|650|1080|2650|2900|3250|400|1700|2600|3200|3580|290|1870|2800|3250|3540|400|800|2600|2800|3000|350|600|2700|2900|3300|600|1040|2250|2450|2750|400|1620|2400|2800|3100|250|1750|2600|3050|3340|400|750|2400|2600|2900|350|600|2400|2675|2950}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ {{1/80|1/90|1/120|1/130|1/140|1/60|1/100|1/120|1/150|1/200|1/60|1/90|1/100|1/120|1/120|1/70|1/80|1/100|1/130|1/135|1/50|1/60|1/170|1/180|1/200|1/80|1/90|1/120|1/130|1/140|1/60|1/80|1/120|1/150|1/200|1/50|1/100|1/120|1/150|1/200|1/70|1/80|1/100|1/130|1/135|1/50|1/60|1/170|1/180|1/200|1/80|1/90|1/120|1/130|1/140|1/70|1/80|1/100|1/120|1/120|1/40|1/90|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120|1/40|1/60|1/100|1/120|1/120|1/80|1/90|1/120|1/130|1/140|1/70|1/80|1/100|1/120|1/120|1/40|1/90|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120|1/40|1/60|1/100|1/120|1/120|1/60|1/70|1/110|1/120|1/130|1/40|1/80|1/100|1/120|1/120|1/60|1/90|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ {{1.0|0.5011872336272722|0.025118864315095784|0.09999999999999998|0.0031622776601683764|1.0|0.09999999999999998|0.17782794100389226|1/100|0.0015848931924611136|1.0|0.251188643150958|0.050118723362727206|0.050118723362727206|0.006309573444801925|1.0|0.2818382931264453|0.0794328234724281|0.0794328234724281|0.0031622776601683764|1.0|0.1584893192461113|0.017782794100389226|1/100|9.999999999999994E-4|1.0|0.6309573444801931|0.09999999999999998|0.015848931924611127|9.999999999999994E-4|1.0|0.06309573444801932|0.031622776601683784|0.017782794100389226|9.999999999999994E-4|1.0|0.09999999999999998|0.031622776601683784|0.015848931924611127|9.999999999999994E-4|1.0|0.3548133892335754|0.1584893192461113|0.03981071705534973|0.001778279410038922|1.0|0.251188643150958|0.031622776601683784|1/100|6.309573444801923E-4|1.0|0.5011872336272722|0.07079457843841379|0.06309573444801932|0.012589254117941666|1.0|0.19952623149688797|0.12589254117941667|0.09999999999999998|0.09999999999999998|1.0|0.06309573444801932|0.06309573444801932|0.015848931924611127|0.015848931924611127|1.0|0.3162277660168379|0.050118723362727206|0.0794328234724281|0.019952623149688792|1.0|0.09999999999999998|0.07079457843841379|0.031622776601683784|0.019952623149688792|1.0|0.5011872336272722|0.44668359215096315|0.3981071705534972|0.0794328234724281|1.0|0.19952623149688797|0.251188643150958|0.19952623149688797|0.09999999999999998|1.0|0.17782794100389226|0.12589254117941667|0.09999999999999998|0.031622776601683784|1.0|0.3162277660168379|0.251188643150958|0.251188643150958|0.050118723362727206|1.0|0.09999999999999998|0.14125375446227542|0.19952623149688797|0.050118723362727206|1.0|0.44668359215096315|0.3548133892335754|0.3548133892335754|0.09999999999999998|1.0|0.251188643150958|0.3548133892335754|0.251188643150958|0.12589254117941667|1.0|0.031622776601683784|0.1584893192461113|0.0794328234724281|0.03981071705534973|1.0|0.2818382931264453|0.08912509381337454|0.09999999999999998|1/100|1.0|0.09999999999999998|0.025118864315095784|0.03981071705534973|0.015848931924611127}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ {{800|1150|2900|3900|4950|350|2000|2800|3600|4950|270|2140|2950|3900|4950|450|800|2830|3800|4950|325|700|2700|3800|4950|800|1150|2800|3500|4950|400|1600|2700|3300|4950|350|1700|2700|3700|4950|450|800|2830|3500|4950|325|700|2530|3500|4950|660|1120|2750|3000|3350|440|1800|2700|3000|3300|270|1850|2900|3350|3590|430|820|2700|3000|3300|370|630|2750|3000|3400|650|1080|2650|2900|3250|400|1700|2600|3200|3580|290|1870|2800|3250|3540|400|800|2600|2800|3000|350|600|2700|2900|3300|600|1040|2250|2450|2750|400|1620|2400|2800|3100|250|1750|2600|3050|3340|400|750|2400|2600|2900|350|600|2400|2675|2950}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ {{1.0|0.5011872336272722|0.025118864315095784|0.09999999999999998|0.0031622776601683764|1.0|0.09999999999999998|0.17782794100389226|1/100|0.0015848931924611136|1.0|0.251188643150958|0.050118723362727206|0.050118723362727206|0.006309573444801925|1.0|0.2818382931264453|0.0794328234724281|0.0794328234724281|0.0031622776601683764|1.0|0.1584893192461113|0.017782794100389226|1/100|9.999999999999994E-4|1.0|0.6309573444801931|0.09999999999999998|0.015848931924611127|9.999999999999994E-4|1.0|0.06309573444801932|0.031622776601683784|0.017782794100389226|9.999999999999994E-4|1.0|0.09999999999999998|0.031622776601683784|0.015848931924611127|9.999999999999994E-4|1.0|0.3548133892335754|0.1584893192461113|0.03981071705534973|0.001778279410038922|1.0|0.251188643150958|0.031622776601683784|1/100|6.309573444801923E-4|1.0|0.5011872336272722|0.07079457843841379|0.06309573444801932|0.012589254117941666|1.0|0.19952623149688797|0.12589254117941667|0.09999999999999998|0.09999999999999998|1.0|0.06309573444801932|0.06309573444801932|0.015848931924611127|0.015848931924611127|1.0|0.3162277660168379|0.050118723362727206|0.0794328234724281|0.019952623149688792|1.0|0.09999999999999998|0.07079457843841379|0.031622776601683784|0.019952623149688792|1.0|0.5011872336272722|0.44668359215096315|0.3981071705534972|0.0794328234724281|1.0|0.19952623149688797|0.251188643150958|0.19952623149688797|0.09999999999999998|1.0|0.17782794100389226|0.12589254117941667|0.09999999999999998|0.031622776601683784|1.0|0.3162277660168379|0.251188643150958|0.251188643150958|0.050118723362727206|1.0|0.09999999999999998|0.14125375446227542|0.19952623149688797|0.050118723362727206|1.0|0.44668359215096315|0.3548133892335754|0.3548133892335754|0.09999999999999998|1.0|0.251188643150958|0.3548133892335754|0.251188643150958|0.12589254117941667|1.0|0.031622776601683784|0.1584893192461113|0.0794328234724281|0.03981071705534973|1.0|0.2818382931264453|0.08912509381337454|0.09999999999999998|1/100|1.0|0.09999999999999998|0.025118864315095784|0.03981071705534973|0.015848931924611127}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ {{800|1150|2900|3900|4950|350|2000|2800|3600|4950|270|2140|2950|3900|4950|450|800|2830|3800|4950|325|700|2700|3800|4950|800|1150|2800|3500|4950|400|1600|2700|3300|4950|350|1700|2700|3700|4950|450|800|2830|3500|4950|325|700|2530|3500|4950|660|1120|2750|3000|3350|440|1800|2700|3000|3300|270|1850|2900|3350|3590|430|820|2700|3000|3300|370|630|2750|3000|3400|650|1080|2650|2900|3250|400|1700|2600|3200|3580|290|1870|2800|3250|3540|400|800|2600|2800|3000|350|600|2700|2900|3300|600|1040|2250|2450|2750|400|1620|2400|2800|3100|250|1750|2600|3050|3340|400|750|2400|2600|2900|350|600|2400|2675|2950}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ {{1/80|1/90|1/120|1/130|1/140|1/60|1/100|1/120|1/150|1/200|1/60|1/90|1/100|1/120|1/120|1/70|1/80|1/100|1/130|1/135|1/50|1/60|1/170|1/180|1/200|1/80|1/90|1/120|1/130|1/140|1/60|1/80|1/120|1/150|1/200|1/50|1/100|1/120|1/150|1/200|1/70|1/80|1/100|1/130|1/135|1/50|1/60|1/170|1/180|1/200|1/80|1/90|1/120|1/130|1/140|1/70|1/80|1/100|1/120|1/120|1/40|1/90|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120|1/40|1/60|1/100|1/120|1/120|1/80|1/90|1/120|1/130|1/140|1/70|1/80|1/100|1/120|1/120|1/40|1/90|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120|1/40|1/60|1/100|1/120|1/120|1/60|1/70|1/110|1/120|1/130|1/40|1/80|1/100|1/120|1/120|1/60|1/90|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120|1/40|1/80|1/100|1/120|1/120}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ {{1.0|0.5011872336272722|0.025118864315095784|0.09999999999999998|0.0031622776601683764|1.0|0.09999999999999998|0.17782794100389226|1/100|0.0015848931924611136|1.0|0.251188643150958|0.050118723362727206|0.050118723362727206|0.006309573444801925|1.0|0.2818382931264453|0.0794328234724281|0.0794328234724281|0.0031622776601683764|1.0|0.1584893192461113|0.017782794100389226|1/100|9.999999999999994E-4|1.0|0.6309573444801931|0.09999999999999998|0.015848931924611127|9.999999999999994E-4|1.0|0.06309573444801932|0.031622776601683784|0.017782794100389226|9.999999999999994E-4|1.0|0.09999999999999998|0.031622776601683784|0.015848931924611127|9.999999999999994E-4|1.0|0.3548133892335754|0.1584893192461113|0.03981071705534973|0.001778279410038922|1.0|0.251188643150958|0.031622776601683784|1/100|6.309573444801923E-4|1.0|0.5011872336272722|0.07079457843841379|0.06309573444801932|0.012589254117941666|1.0|0.19952623149688797|0.12589254117941667|0.09999999999999998|0.09999999999999998|1.0|0.06309573444801932|0.06309573444801932|0.015848931924611127|0.015848931924611127|1.0|0.3162277660168379|0.050118723362727206|0.0794328234724281|0.019952623149688792|1.0|0.09999999999999998|0.07079457843841379|0.031622776601683784|0.019952623149688792|1.0|0.5011872336272722|0.44668359215096315|0.3981071705534972|0.0794328234724281|1.0|0.19952623149688797|0.251188643150958|0.19952623149688797|0.09999999999999998|1.0|0.17782794100389226|0.12589254117941667|0.09999999999999998|0.031622776601683784|1.0|0.3162277660168379|0.251188643150958|0.251188643150958|0.050118723362727206|1.0|0.09999999999999998|0.14125375446227542|0.19952623149688797|0.050118723362727206|1.0|0.44668359215096315|0.3548133892335754|0.3548133892335754|0.09999999999999998|1.0|0.251188643150958|0.3548133892335754|0.251188643150958|0.12589254117941667|1.0|0.031622776601683784|0.1584893192461113|0.0794328234724281|0.03981071705534973|1.0|0.2818382931264453|0.08912509381337454|0.09999999999999998|1/100|1.0|0.09999999999999998|0.025118864315095784|0.03981071705534973|0.015848931924611127}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+160 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+9:__UG_NAME__ -> 16:b ;
+9:__UG_NAME__ -> 18:b ;
+9:__UG_NAME__ -> 19:b ;
+8:__UG_NAME__ -> 20:b ;
+9:__UG_NAME__ -> 21:b ;
+36:__UG_NAME__ -> 37:b ;
+37:__UG_NAME__ -> 39:a ;
+38:__UG_NAME__ -> 39:b ;
+8:__UG_NAME__ -> 40:b ;
+9:__UG_NAME__ -> 41:b ;
+8:__UG_NAME__ -> 45:b ;
+9:__UG_NAME__ -> 46:b ;
+8:__UG_NAME__ -> 50:b ;
+49:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+8:__UG_NAME__ -> 56:b ;
+9:__UG_NAME__ -> 57:b ;
+8:__UG_NAME__ -> 61:b ;
+9:__UG_NAME__ -> 62:b ;
+8:__UG_NAME__ -> 66:b ;
+65:__UG_NAME__ -> 69:a ;
+68:__UG_NAME__ -> 69:b ;
+8:__UG_NAME__ -> 72:b ;
+9:__UG_NAME__ -> 73:b ;
+8:__UG_NAME__ -> 77:b ;
+9:__UG_NAME__ -> 78:b ;
+8:__UG_NAME__ -> 82:b ;
+9:__UG_NAME__ -> 83:b ;
+81:__UG_NAME__ -> 87:a ;
+86:__UG_NAME__ -> 87:b ;
+8:__UG_NAME__ -> 90:b ;
+8:__UG_NAME__ -> 94:b ;
+9:__UG_NAME__ -> 95:b ;
+24:__UG_NAME__ -> 99:a ;
+98:__UG_NAME__ -> 99:b ;
+8:__UG_NAME__ -> 102:b ;
+9:__UG_NAME__ -> 103:b ;
+8:__UG_NAME__ -> 107:b ;
+9:__UG_NAME__ -> 108:b ;
+8:__UG_NAME__ -> 112:b ;
+9:__UG_NAME__ -> 113:b ;
+111:__UG_NAME__ -> 117:a ;
+116:__UG_NAME__ -> 117:b ;
+129:__UG_NAME__ -> 130:a ;
+139:__UG_NAME__ -> 140:b ;
+37:__UG_NAME__ -> 142:a ;
+38:__UG_NAME__ -> 142:b ;
+49:__UG_NAME__ -> 143:a ;
+53:__UG_NAME__ -> 143:b ;
+65:__UG_NAME__ -> 145:a ;
+68:__UG_NAME__ -> 145:b ;
+81:__UG_NAME__ -> 148:a ;
+86:__UG_NAME__ -> 148:b ;
+24:__UG_NAME__ -> 151:a ;
+98:__UG_NAME__ -> 151:b ;
+111:__UG_NAME__ -> 154:a ;
+116:__UG_NAME__ -> 154:b ;
+129:__UG_NAME__ -> 157:a ;
+139:__UG_NAME__ -> 159:b ;
+20:__UG_NAME__ -> 23:a ;
+22:__UG_NAME__ -> 23:b ;
+27:__UG_NAME__ -> 31:a ;
+30:__UG_NAME__ -> 31:b ;
+31:__UG_NAME__ -> 35:a ;
+34:__UG_NAME__ -> 35:b ;
+40:__UG_NAME__ -> 43:a ;
+42:__UG_NAME__ -> 43:b ;
+45:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+50:__UG_NAME__ -> 52:a ;
+51:__UG_NAME__ -> 52:b ;
+56:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+61:__UG_NAME__ -> 64:a ;
+63:__UG_NAME__ -> 64:b ;
+66:__UG_NAME__ -> 67:a ;
+17:__UG_NAME__ -> 67:b ;
+55:__UG_NAME__ -> 71:a ;
+70:__UG_NAME__ -> 71:b ;
+72:__UG_NAME__ -> 75:a ;
+74:__UG_NAME__ -> 75:b ;
+77:__UG_NAME__ -> 80:a ;
+79:__UG_NAME__ -> 80:b ;
+82:__UG_NAME__ -> 85:a ;
+84:__UG_NAME__ -> 85:b ;
+71:__UG_NAME__ -> 89:a ;
+88:__UG_NAME__ -> 89:b ;
+90:__UG_NAME__ -> 92:a ;
+91:__UG_NAME__ -> 92:b ;
+94:__UG_NAME__ -> 97:a ;
+96:__UG_NAME__ -> 97:b ;
+89:__UG_NAME__ -> 101:a ;
+100:__UG_NAME__ -> 101:b ;
+102:__UG_NAME__ -> 105:a ;
+104:__UG_NAME__ -> 105:b ;
+107:__UG_NAME__ -> 110:a ;
+109:__UG_NAME__ -> 110:b ;
+112:__UG_NAME__ -> 115:a ;
+114:__UG_NAME__ -> 115:b ;
+101:__UG_NAME__ -> 119:a ;
+118:__UG_NAME__ -> 119:b ;
+120:__UG_NAME__ -> 124:a ;
+123:__UG_NAME__ -> 124:b ;
+124:__UG_NAME__ -> 128:a ;
+127:__UG_NAME__ -> 128:b ;
+132:__UG_NAME__ -> 136:a ;
+135:__UG_NAME__ -> 136:b ;
+136:__UG_NAME__ -> 138:a ;
+137:__UG_NAME__ -> 138:b ;
+144:__UG_NAME__ -> 147:a ;
+146:__UG_NAME__ -> 147:b ;
+147:__UG_NAME__ -> 150:a ;
+149:__UG_NAME__ -> 150:b ;
+150:__UG_NAME__ -> 153:a ;
+152:__UG_NAME__ -> 153:b ;
+153:__UG_NAME__ -> 156:a ;
+155:__UG_NAME__ -> 156:b ;
+16:__UG_NAME__ -> 17:a ;
+21:__UG_NAME__ -> 22:a ;
+41:__UG_NAME__ -> 42:a ;
+46:__UG_NAME__ -> 47:a ;
+19:__UG_NAME__ -> 51:a ;
+57:__UG_NAME__ -> 58:a ;
+62:__UG_NAME__ -> 63:a ;
+73:__UG_NAME__ -> 74:a ;
+78:__UG_NAME__ -> 79:a ;
+83:__UG_NAME__ -> 84:a ;
+18:__UG_NAME__ -> 91:a ;
+95:__UG_NAME__ -> 96:a ;
+103:__UG_NAME__ -> 104:a ;
+108:__UG_NAME__ -> 109:a ;
+113:__UG_NAME__ -> 114:a ;
+130:__UG_NAME__ -> 131:a ;
+157:__UG_NAME__ -> 158:a ;
+29:__UG_NAME__ -> 30:a ;
+33:__UG_NAME__ -> 34:a ;
+122:__UG_NAME__ -> 123:a ;
+126:__UG_NAME__ -> 127:a ;
+134:__UG_NAME__ -> 135:a ;
+26:__UG_NAME__ -> 137:a ;
+25:__UG_NAME__ -> 26:a ;
+28:__UG_NAME__ -> 29:a ;
+32:__UG_NAME__ -> 33:a ;
+121:__UG_NAME__ -> 122:a ;
+125:__UG_NAME__ -> 126:a ;
+133:__UG_NAME__ -> 134:a ;
+39:__UG_NAME__ -> 55:in ;
+44:__UG_NAME__ -> 55:freq ;
+54:__UG_NAME__ -> 55:bw ;
+39:__UG_NAME__ -> 70:in ;
+60:__UG_NAME__ -> 70:freq ;
+69:__UG_NAME__ -> 70:bw ;
+39:__UG_NAME__ -> 88:in ;
+76:__UG_NAME__ -> 88:freq ;
+87:__UG_NAME__ -> 88:bw ;
+39:__UG_NAME__ -> 100:in ;
+93:__UG_NAME__ -> 100:freq ;
+99:__UG_NAME__ -> 100:bw ;
+39:__UG_NAME__ -> 118:in ;
+106:__UG_NAME__ -> 118:freq ;
+117:__UG_NAME__ -> 118:bw ;
+142:__UG_NAME__ -> 144:in ;
+44:__UG_NAME__ -> 144:freq ;
+143:__UG_NAME__ -> 144:bw ;
+142:__UG_NAME__ -> 146:in ;
+60:__UG_NAME__ -> 146:freq ;
+145:__UG_NAME__ -> 146:bw ;
+142:__UG_NAME__ -> 149:in ;
+76:__UG_NAME__ -> 149:freq ;
+148:__UG_NAME__ -> 149:bw ;
+142:__UG_NAME__ -> 152:in ;
+93:__UG_NAME__ -> 152:freq ;
+151:__UG_NAME__ -> 152:bw ;
+142:__UG_NAME__ -> 155:in ;
+106:__UG_NAME__ -> 155:freq ;
+154:__UG_NAME__ -> 155:bw ;
+10:__UG_NAME__ -> 36:envelope___control___0 ;
+10:__UG_NAME__ -> 36:envelope___control___4 ;
+11:__UG_NAME__ -> 36:envelope___control___5 ;
+12:__UG_NAME__ -> 36:envelope___control___6 ;
+13:__UG_NAME__ -> 36:envelope___control___7 ;
+35:__UG_NAME__ -> 36:gate ;
+4:__UG_NAME__ -> 129:envelope___control___0 ;
+4:__UG_NAME__ -> 129:envelope___control___4 ;
+5:__UG_NAME__ -> 129:envelope___control___5 ;
+6:__UG_NAME__ -> 129:envelope___control___6 ;
+7:__UG_NAME__ -> 129:envelope___control___7 ;
+128:__UG_NAME__ -> 129:gate ;
+0:__UG_NAME__ -> 139:envelope___control___0 ;
+0:__UG_NAME__ -> 139:envelope___control___4 ;
+1:__UG_NAME__ -> 139:envelope___control___5 ;
+2:__UG_NAME__ -> 139:envelope___control___6 ;
+3:__UG_NAME__ -> 139:envelope___control___7 ;
+138:__UG_NAME__ -> 139:gate ;
+1:__UG_NAME__ -> 25:in ;
+10:__UG_NAME__ -> 28:in ;
+11:__UG_NAME__ -> 32:in ;
+4:__UG_NAME__ -> 121:in ;
+5:__UG_NAME__ -> 125:in ;
+0:__UG_NAME__ -> 133:in ;
+14:__UG_NAME__ -> 38:bus ;
+15:__UG_NAME__ -> 161:bus ;
+141:__UG_NAME__ -> 161:signals___x____fade2___0 ;
+160:__UG_NAME__ -> 161:signals___x____fade2___1 ;
+23:__UG_NAME__ -> 24:which ;
+43:__UG_NAME__ -> 44:which ;
+48:__UG_NAME__ -> 49:which ;
+52:__UG_NAME__ -> 53:which ;
+59:__UG_NAME__ -> 60:which ;
+64:__UG_NAME__ -> 65:which ;
+67:__UG_NAME__ -> 68:which ;
+75:__UG_NAME__ -> 76:which ;
+80:__UG_NAME__ -> 81:which ;
+85:__UG_NAME__ -> 86:which ;
+92:__UG_NAME__ -> 93:which ;
+97:__UG_NAME__ -> 98:which ;
+105:__UG_NAME__ -> 106:which ;
+110:__UG_NAME__ -> 111:which ;
+115:__UG_NAME__ -> 116:which ;
+39:__UG_NAME__ -> 141:ina ;
+119:__UG_NAME__ -> 141:inb ;
+131:__UG_NAME__ -> 141:pan ;
+140:__UG_NAME__ -> 141:level ;
+142:__UG_NAME__ -> 160:ina ;
+156:__UG_NAME__ -> 160:inb ;
+158:__UG_NAME__ -> 160:pan ;
+159:__UG_NAME__ -> 160:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_whammy.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_whammy.dot
new file mode 100644
index 0000000..9c7ce07
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_whammy.dot
@@ -0,0 +1,252 @@
+digraph synthdef {
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+64 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> |<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> -2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> -2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :transpose
+ default: 12.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :transpose_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :transpose_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :transpose_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :deltime
+ default: 0.05" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :max_delay_time
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :grainsize
+ default: 0.075" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+49 [label = "{{ <delay____time> delay-time|<max____delay____time> max-delay-time|<in> in} |<__UG_NAME__>delay-c }" style="filled, bold, rounded"  shape=record rankdir=LR];
+74 [label = "{{ <delay____time> delay-time|<max____delay____time> max-delay-time|<in> in} |<__UG_NAME__>delay-c }" style="filled, bold, rounded"  shape=record rankdir=LR];
+31 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___unary____op____u____gen___0>|1.0|-99|-99|<envelope___unary____op____u____gen___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+21 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+53 [label = "{{ <coef> coef 0.995|<in> in} |<__UG_NAME__>leak-dc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+77 [label = "{{ <coef> coef 0.995|<in> in} |<__UG_NAME__>leak-dc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+33 [label = "{{ <iphase> iphase 0.0|<freq> freq} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+70 [label = "{{ <iphase> iphase 1.0|<freq> freq} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+22 [label = "{{ <b> |<a> } |<__UG_NAME__>midiratio }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <add> add 0.5|<mul> mul 0.5|<in> in} |<__UG_NAME__>mul-add }" style="filled, bold, rounded"  shape=record rankdir=LR];
+75 [label = "{{ <add> add 0.5|<mul> mul 0.5|<in> in} |<__UG_NAME__>mul-add }" style="filled, bold, rounded"  shape=record rankdir=LR];
+90 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+50 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 1.5707964|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+66 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase -1.5707964|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+88 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+89 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+33:__UG_NAME__ -> 35:a ;
+34:__UG_NAME__ -> 35:b ;
+45:__UG_NAME__ -> 47:a ;
+46:__UG_NAME__ -> 47:b ;
+49:__UG_NAME__ -> 52:a ;
+51:__UG_NAME__ -> 52:b ;
+63:__UG_NAME__ -> 64:a ;
+63:__UG_NAME__ -> 67:a ;
+45:__UG_NAME__ -> 69:a ;
+46:__UG_NAME__ -> 69:b ;
+70:__UG_NAME__ -> 72:a ;
+71:__UG_NAME__ -> 72:b ;
+74:__UG_NAME__ -> 76:a ;
+75:__UG_NAME__ -> 76:b ;
+21:__UG_NAME__ -> 26:a ;
+25:__UG_NAME__ -> 26:b ;
+26:__UG_NAME__ -> 30:a ;
+29:__UG_NAME__ -> 30:b ;
+36:__UG_NAME__ -> 40:a ;
+39:__UG_NAME__ -> 40:b ;
+40:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+35:__UG_NAME__ -> 48:a ;
+12:__UG_NAME__ -> 48:b ;
+54:__UG_NAME__ -> 58:a ;
+57:__UG_NAME__ -> 58:b ;
+58:__UG_NAME__ -> 62:a ;
+61:__UG_NAME__ -> 62:b ;
+72:__UG_NAME__ -> 73:a ;
+12:__UG_NAME__ -> 73:b ;
+78:__UG_NAME__ -> 82:a ;
+81:__UG_NAME__ -> 82:b ;
+82:__UG_NAME__ -> 86:a ;
+85:__UG_NAME__ -> 86:b ;
+64:__UG_NAME__ -> 65:a ;
+67:__UG_NAME__ -> 68:a ;
+31:__UG_NAME__ -> 32:a ;
+14:__UG_NAME__ -> 32:b ;
+14:__UG_NAME__ -> 34:a ;
+14:__UG_NAME__ -> 71:a ;
+24:__UG_NAME__ -> 25:a ;
+28:__UG_NAME__ -> 29:a ;
+38:__UG_NAME__ -> 39:a ;
+42:__UG_NAME__ -> 43:a ;
+56:__UG_NAME__ -> 57:a ;
+60:__UG_NAME__ -> 61:a ;
+80:__UG_NAME__ -> 81:a ;
+84:__UG_NAME__ -> 85:a ;
+23:__UG_NAME__ -> 24:a ;
+27:__UG_NAME__ -> 28:a ;
+37:__UG_NAME__ -> 38:a ;
+41:__UG_NAME__ -> 42:a ;
+55:__UG_NAME__ -> 56:a ;
+59:__UG_NAME__ -> 60:a ;
+79:__UG_NAME__ -> 80:a ;
+83:__UG_NAME__ -> 84:a ;
+47:__UG_NAME__ -> 49:in ;
+13:__UG_NAME__ -> 49:max____delay____time ;
+48:__UG_NAME__ -> 49:delay____time ;
+69:__UG_NAME__ -> 74:in ;
+13:__UG_NAME__ -> 74:max____delay____time ;
+73:__UG_NAME__ -> 74:delay____time ;
+22:__UG_NAME__ -> 31:envelope___unary____op____u____gen___0 ;
+22:__UG_NAME__ -> 31:envelope___unary____op____u____gen___4 ;
+9:__UG_NAME__ -> 31:envelope___control___5 ;
+10:__UG_NAME__ -> 31:envelope___control___6 ;
+11:__UG_NAME__ -> 31:envelope___control___7 ;
+30:__UG_NAME__ -> 31:gate ;
+15:__UG_NAME__ -> 45:envelope___control___0 ;
+15:__UG_NAME__ -> 45:envelope___control___4 ;
+16:__UG_NAME__ -> 45:envelope___control___5 ;
+17:__UG_NAME__ -> 45:envelope___control___6 ;
+18:__UG_NAME__ -> 45:envelope___control___7 ;
+44:__UG_NAME__ -> 45:gate ;
+4:__UG_NAME__ -> 63:envelope___control___0 ;
+4:__UG_NAME__ -> 63:envelope___control___4 ;
+5:__UG_NAME__ -> 63:envelope___control___5 ;
+6:__UG_NAME__ -> 63:envelope___control___6 ;
+7:__UG_NAME__ -> 63:envelope___control___7 ;
+62:__UG_NAME__ -> 63:gate ;
+0:__UG_NAME__ -> 87:envelope___control___0 ;
+0:__UG_NAME__ -> 87:envelope___control___4 ;
+1:__UG_NAME__ -> 87:envelope___control___5 ;
+2:__UG_NAME__ -> 87:envelope___control___6 ;
+3:__UG_NAME__ -> 87:envelope___control___7 ;
+86:__UG_NAME__ -> 87:gate ;
+22:__UG_NAME__ -> 23:in ;
+9:__UG_NAME__ -> 27:in ;
+15:__UG_NAME__ -> 37:in ;
+16:__UG_NAME__ -> 41:in ;
+4:__UG_NAME__ -> 55:in ;
+5:__UG_NAME__ -> 59:in ;
+0:__UG_NAME__ -> 79:in ;
+1:__UG_NAME__ -> 83:in ;
+19:__UG_NAME__ -> 46:bus ;
+52:__UG_NAME__ -> 53:in ;
+76:__UG_NAME__ -> 77:in ;
+32:__UG_NAME__ -> 33:freq ;
+32:__UG_NAME__ -> 70:freq ;
+8:__UG_NAME__ -> 22:a ;
+50:__UG_NAME__ -> 51:in ;
+66:__UG_NAME__ -> 75:in ;
+20:__UG_NAME__ -> 90:bus ;
+88:__UG_NAME__ -> 90:signals___x____fade2___0 ;
+89:__UG_NAME__ -> 90:signals___x____fade2___1 ;
+32:__UG_NAME__ -> 50:freq ;
+32:__UG_NAME__ -> 66:freq ;
+46:__UG_NAME__ -> 88:ina ;
+77:__UG_NAME__ -> 88:inb ;
+68:__UG_NAME__ -> 88:pan ;
+87:__UG_NAME__ -> 88:level ;
+46:__UG_NAME__ -> 89:ina ;
+53:__UG_NAME__ -> 89:inb ;
+65:__UG_NAME__ -> 89:pan ;
+87:__UG_NAME__ -> 89:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-fx_wobble.dot b/etc/synthdefs/graphviz/dot/sonic-pi-fx_wobble.dot
new file mode 100644
index 0000000..c3db365
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-fx_wobble.dot
@@ -0,0 +1,670 @@
+digraph synthdef {
+68 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> 6.2831855|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+231 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+234 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+238 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+146 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+155 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+159 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+166 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+173 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+177 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+185 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+189 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+194 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+198 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+204 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+212 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+216 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+225 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+229 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+232 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+239 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+148 [label = "{{ <b> |<a> } |<__UG_NAME__>\< }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+140 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+143 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+154 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+158 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+165 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+172 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+176 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+184 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+188 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+193 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+197 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+203 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+211 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+215 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+224 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+228 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+153 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+157 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+164 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+171 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+175 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+183 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+187 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+192 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+196 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+202 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+210 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+214 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+223 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+227 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+147 [label = "{{ <interpolation> interpolation 2.0|<loop> loop 1.0|<phase> phase|<bufnum> bufnum|<num____channels> num-channels 1} |<__UG_NAME__>buf-rd }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <hi> hi 1.0|<lo> lo 0.0|<in> in} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
+150 [label = "{{ <hi> hi 1.0|<lo> lo 0.0|<in> in} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :mix
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :mix_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :mix_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :mix_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :phase
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :phase_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :phase_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :phase_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :cutoff_min
+ default: 60.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :cutoff_min_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :cutoff_min_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :cutoff_min_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff_max
+ default: 120.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_max_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_max_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_max_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :res
+ default: 0.8" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :filter
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :smooth
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :smooth_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :smooth_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :smooth_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "control
+ :smooth_up
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "control
+ :smooth_up_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "control
+ :smooth_up_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+40 [label = "control
+ :smooth_up_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+41 [label = "control
+ :smooth_down
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+42 [label = "control
+ :smooth_down_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "control
+ :smooth_down_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+44 [label = "control
+ :smooth_down_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+45 [label = "control
+ :phase_offset
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+46 [label = "control
+ :wave
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+47 [label = "control
+ :invert_wave
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+48 [label = "control
+ :probability
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+49 [label = "control
+ :probability_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+50 [label = "control
+ :probability_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+51 [label = "control
+ :probability_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+52 [label = "control
+ :prob_pos
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+53 [label = "control
+ :prob_pos_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+54 [label = "control
+ :prob_pos_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+55 [label = "control
+ :prob_pos_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+56 [label = "control
+ :seed
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+57 [label = "control
+ :rand_buf
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+58 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+59 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+80 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___clip___0>|1.0|-99|-99|<envelope___clip___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+160 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+167 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+178 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+190 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+199 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+205 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+217 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+230 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+152 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+156 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+163 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+170 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+174 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+182 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+186 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+195 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+201 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+209 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+213 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+222 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+226 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+134 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <phase> phase 0.0|<freq> freq} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+149 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+169 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+181 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+191 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+207 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+221 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+206 [label = "{{ <lag____time> lag-time|<in> in} |<__UG_NAME__>lag }" style="bold, rounded" shape=record rankdir=LR];
+200 [label = "{{ <lag____time____down> lag-time-down|<lag____time____up> lag-time-up|<in> in} |<__UG_NAME__>lag-ud }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <width> width|<iphase> iphase|<freq> freq} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
+180 [label = "{{ <dsthi> dsthi|<dstlo> dstlo|<srchi> srchi 1.0|<srclo> srclo -1.0|<in> in} |<__UG_NAME__>lin-exp }" style="bold, rounded" shape=record rankdir=LR];
+168 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+179 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+151 [label = "{{ <add> add -1.0|<mul> mul 2.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+208 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+241 [label = "{{ {{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+145 [label = "{{ <reset> reset 0.0|<trig> trig} |<__UG_NAME__>pulse-count }" style="bold, rounded" shape=record rankdir=LR];
+219 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rhpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+236 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rhpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+218 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+235 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+103 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+161 [label = "{{ {{<array___env____gen___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+162 [label = "{{ {{<array___binary____op____u____gen___0>|<array___select___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+220 [label = "{{ {{<array___rlpf___0>|<array___rhpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+237 [label = "{{ {{<array___rlpf___0>|<array___rhpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+102 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase|<freq> freq} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+233 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+240 [label = "{{ <level> level|<pan> pan|<inb> inB|<ina> inA} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+67:__UG_NAME__ -> 68:b ;
+69:__UG_NAME__ -> 70:b ;
+45:__UG_NAME__ -> 82:b ;
+84:__UG_NAME__ -> 85:b ;
+95:__UG_NAME__ -> 96:b ;
+100:__UG_NAME__ -> 101:a ;
+70:__UG_NAME__ -> 104:a ;
+103:__UG_NAME__ -> 104:b ;
+131:__UG_NAME__ -> 133:a ;
+132:__UG_NAME__ -> 133:b ;
+230:__UG_NAME__ -> 231:a ;
+131:__UG_NAME__ -> 234:a ;
+132:__UG_NAME__ -> 234:b ;
+230:__UG_NAME__ -> 238:a ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+71:__UG_NAME__ -> 75:a ;
+74:__UG_NAME__ -> 75:b ;
+75:__UG_NAME__ -> 79:a ;
+78:__UG_NAME__ -> 79:b ;
+82:__UG_NAME__ -> 83:a ;
+86:__UG_NAME__ -> 90:a ;
+89:__UG_NAME__ -> 90:b ;
+90:__UG_NAME__ -> 93:a ;
+92:__UG_NAME__ -> 93:b ;
+82:__UG_NAME__ -> 98:a ;
+45:__UG_NAME__ -> 100:a ;
+106:__UG_NAME__ -> 110:a ;
+109:__UG_NAME__ -> 110:b ;
+110:__UG_NAME__ -> 114:a ;
+113:__UG_NAME__ -> 114:b ;
+118:__UG_NAME__ -> 122:a ;
+121:__UG_NAME__ -> 122:b ;
+105:__UG_NAME__ -> 126:a ;
+125:__UG_NAME__ -> 126:b ;
+126:__UG_NAME__ -> 130:a ;
+129:__UG_NAME__ -> 130:b ;
+134:__UG_NAME__ -> 139:a ;
+138:__UG_NAME__ -> 139:b ;
+139:__UG_NAME__ -> 141:a ;
+140:__UG_NAME__ -> 141:b ;
+56:__UG_NAME__ -> 146:a ;
+145:__UG_NAME__ -> 146:b ;
+149:__UG_NAME__ -> 155:a ;
+154:__UG_NAME__ -> 155:b ;
+155:__UG_NAME__ -> 159:a ;
+158:__UG_NAME__ -> 159:b ;
+65:__UG_NAME__ -> 166:a ;
+165:__UG_NAME__ -> 166:b ;
+169:__UG_NAME__ -> 173:a ;
+172:__UG_NAME__ -> 173:b ;
+173:__UG_NAME__ -> 177:a ;
+176:__UG_NAME__ -> 177:b ;
+181:__UG_NAME__ -> 185:a ;
+184:__UG_NAME__ -> 185:b ;
+185:__UG_NAME__ -> 189:a ;
+188:__UG_NAME__ -> 189:b ;
+191:__UG_NAME__ -> 194:a ;
+193:__UG_NAME__ -> 194:b ;
+194:__UG_NAME__ -> 198:a ;
+197:__UG_NAME__ -> 198:b ;
+122:__UG_NAME__ -> 204:a ;
+203:__UG_NAME__ -> 204:b ;
+207:__UG_NAME__ -> 212:a ;
+211:__UG_NAME__ -> 212:b ;
+212:__UG_NAME__ -> 216:a ;
+215:__UG_NAME__ -> 216:b ;
+221:__UG_NAME__ -> 225:a ;
+224:__UG_NAME__ -> 225:b ;
+225:__UG_NAME__ -> 229:a ;
+228:__UG_NAME__ -> 229:b ;
+68:__UG_NAME__ -> 69:a ;
+96:__UG_NAME__ -> 97:a ;
+231:__UG_NAME__ -> 232:a ;
+238:__UG_NAME__ -> 239:a ;
+80:__UG_NAME__ -> 81:b ;
+147:__UG_NAME__ -> 148:a ;
+142:__UG_NAME__ -> 148:b ;
+63:__UG_NAME__ -> 64:a ;
+47:__UG_NAME__ -> 67:a ;
+73:__UG_NAME__ -> 74:a ;
+77:__UG_NAME__ -> 78:a ;
+88:__UG_NAME__ -> 89:a ;
+91:__UG_NAME__ -> 92:a ;
+108:__UG_NAME__ -> 109:a ;
+112:__UG_NAME__ -> 113:a ;
+120:__UG_NAME__ -> 121:a ;
+124:__UG_NAME__ -> 125:a ;
+128:__UG_NAME__ -> 129:a ;
+137:__UG_NAME__ -> 138:a ;
+117:__UG_NAME__ -> 140:a ;
+142:__UG_NAME__ -> 143:a ;
+153:__UG_NAME__ -> 154:a ;
+157:__UG_NAME__ -> 158:a ;
+164:__UG_NAME__ -> 165:a ;
+171:__UG_NAME__ -> 172:a ;
+175:__UG_NAME__ -> 176:a ;
+183:__UG_NAME__ -> 184:a ;
+187:__UG_NAME__ -> 188:a ;
+192:__UG_NAME__ -> 193:a ;
+196:__UG_NAME__ -> 197:a ;
+202:__UG_NAME__ -> 203:a ;
+210:__UG_NAME__ -> 211:a ;
+214:__UG_NAME__ -> 215:a ;
+223:__UG_NAME__ -> 224:a ;
+227:__UG_NAME__ -> 228:a ;
+62:__UG_NAME__ -> 63:a ;
+72:__UG_NAME__ -> 73:a ;
+76:__UG_NAME__ -> 77:a ;
+87:__UG_NAME__ -> 88:a ;
+60:__UG_NAME__ -> 91:a ;
+107:__UG_NAME__ -> 108:a ;
+111:__UG_NAME__ -> 112:a ;
+116:__UG_NAME__ -> 117:a ;
+119:__UG_NAME__ -> 120:a ;
+123:__UG_NAME__ -> 124:a ;
+127:__UG_NAME__ -> 128:a ;
+136:__UG_NAME__ -> 137:a ;
+152:__UG_NAME__ -> 153:a ;
+156:__UG_NAME__ -> 157:a ;
+163:__UG_NAME__ -> 164:a ;
+170:__UG_NAME__ -> 171:a ;
+174:__UG_NAME__ -> 175:a ;
+182:__UG_NAME__ -> 183:a ;
+186:__UG_NAME__ -> 187:a ;
+66:__UG_NAME__ -> 192:a ;
+195:__UG_NAME__ -> 196:a ;
+201:__UG_NAME__ -> 202:a ;
+209:__UG_NAME__ -> 210:a ;
+213:__UG_NAME__ -> 214:a ;
+222:__UG_NAME__ -> 223:a ;
+226:__UG_NAME__ -> 227:a ;
+57:__UG_NAME__ -> 147:bufnum ;
+146:__UG_NAME__ -> 147:phase ;
+48:__UG_NAME__ -> 135:in ;
+52:__UG_NAME__ -> 150:in ;
+12:__UG_NAME__ -> 80:envelope___control___0 ;
+12:__UG_NAME__ -> 80:envelope___control___4 ;
+13:__UG_NAME__ -> 80:envelope___control___5 ;
+14:__UG_NAME__ -> 80:envelope___control___6 ;
+15:__UG_NAME__ -> 80:envelope___control___7 ;
+79:__UG_NAME__ -> 80:gate ;
+28:__UG_NAME__ -> 94:envelope___control___0 ;
+28:__UG_NAME__ -> 94:envelope___control___4 ;
+29:__UG_NAME__ -> 94:envelope___control___5 ;
+30:__UG_NAME__ -> 94:envelope___control___6 ;
+31:__UG_NAME__ -> 94:envelope___control___7 ;
+93:__UG_NAME__ -> 94:gate ;
+0:__UG_NAME__ -> 115:envelope___control___0 ;
+0:__UG_NAME__ -> 115:envelope___control___4 ;
+1:__UG_NAME__ -> 115:envelope___control___5 ;
+2:__UG_NAME__ -> 115:envelope___control___6 ;
+3:__UG_NAME__ -> 115:envelope___control___7 ;
+114:__UG_NAME__ -> 115:gate ;
+8:__UG_NAME__ -> 131:envelope___control___0 ;
+8:__UG_NAME__ -> 131:envelope___control___4 ;
+9:__UG_NAME__ -> 131:envelope___control___5 ;
+10:__UG_NAME__ -> 131:envelope___control___6 ;
+11:__UG_NAME__ -> 131:envelope___control___7 ;
+130:__UG_NAME__ -> 131:gate ;
+135:__UG_NAME__ -> 142:envelope___clip___0 ;
+135:__UG_NAME__ -> 142:envelope___clip___4 ;
+49:__UG_NAME__ -> 142:envelope___control___5 ;
+50:__UG_NAME__ -> 142:envelope___control___6 ;
+51:__UG_NAME__ -> 142:envelope___control___7 ;
+141:__UG_NAME__ -> 142:gate ;
+151:__UG_NAME__ -> 160:envelope___mul____add___0 ;
+151:__UG_NAME__ -> 160:envelope___mul____add___4 ;
+53:__UG_NAME__ -> 160:envelope___control___5 ;
+54:__UG_NAME__ -> 160:envelope___control___6 ;
+55:__UG_NAME__ -> 160:envelope___control___7 ;
+159:__UG_NAME__ -> 160:gate ;
+16:__UG_NAME__ -> 167:envelope___control___0 ;
+16:__UG_NAME__ -> 167:envelope___control___4 ;
+17:__UG_NAME__ -> 167:envelope___control___5 ;
+18:__UG_NAME__ -> 167:envelope___control___6 ;
+19:__UG_NAME__ -> 167:envelope___control___7 ;
+166:__UG_NAME__ -> 167:gate ;
+20:__UG_NAME__ -> 178:envelope___control___0 ;
+20:__UG_NAME__ -> 178:envelope___control___4 ;
+21:__UG_NAME__ -> 178:envelope___control___5 ;
+22:__UG_NAME__ -> 178:envelope___control___6 ;
+23:__UG_NAME__ -> 178:envelope___control___7 ;
+177:__UG_NAME__ -> 178:gate ;
+37:__UG_NAME__ -> 190:envelope___control___0 ;
+37:__UG_NAME__ -> 190:envelope___control___4 ;
+38:__UG_NAME__ -> 190:envelope___control___5 ;
+39:__UG_NAME__ -> 190:envelope___control___6 ;
+40:__UG_NAME__ -> 190:envelope___control___7 ;
+189:__UG_NAME__ -> 190:gate ;
+41:__UG_NAME__ -> 199:envelope___control___0 ;
+41:__UG_NAME__ -> 199:envelope___control___4 ;
+42:__UG_NAME__ -> 199:envelope___control___5 ;
+43:__UG_NAME__ -> 199:envelope___control___6 ;
+44:__UG_NAME__ -> 199:envelope___control___7 ;
+198:__UG_NAME__ -> 199:gate ;
+33:__UG_NAME__ -> 205:envelope___control___0 ;
+33:__UG_NAME__ -> 205:envelope___control___4 ;
+34:__UG_NAME__ -> 205:envelope___control___5 ;
+35:__UG_NAME__ -> 205:envelope___control___6 ;
+36:__UG_NAME__ -> 205:envelope___control___7 ;
+204:__UG_NAME__ -> 205:gate ;
+208:__UG_NAME__ -> 217:envelope___mul____add___0 ;
+208:__UG_NAME__ -> 217:envelope___mul____add___4 ;
+25:__UG_NAME__ -> 217:envelope___control___5 ;
+26:__UG_NAME__ -> 217:envelope___control___6 ;
+27:__UG_NAME__ -> 217:envelope___control___7 ;
+216:__UG_NAME__ -> 217:gate ;
+4:__UG_NAME__ -> 230:envelope___control___0 ;
+4:__UG_NAME__ -> 230:envelope___control___4 ;
+5:__UG_NAME__ -> 230:envelope___control___5 ;
+6:__UG_NAME__ -> 230:envelope___control___6 ;
+7:__UG_NAME__ -> 230:envelope___control___7 ;
+229:__UG_NAME__ -> 230:gate ;
+29:__UG_NAME__ -> 60:in ;
+16:__UG_NAME__ -> 62:in ;
+41:__UG_NAME__ -> 66:in ;
+12:__UG_NAME__ -> 72:in ;
+13:__UG_NAME__ -> 76:in ;
+28:__UG_NAME__ -> 87:in ;
+0:__UG_NAME__ -> 107:in ;
+1:__UG_NAME__ -> 111:in ;
+49:__UG_NAME__ -> 116:in ;
+33:__UG_NAME__ -> 119:in ;
+8:__UG_NAME__ -> 123:in ;
+9:__UG_NAME__ -> 127:in ;
+135:__UG_NAME__ -> 136:in ;
+151:__UG_NAME__ -> 152:in ;
+53:__UG_NAME__ -> 156:in ;
+17:__UG_NAME__ -> 163:in ;
+20:__UG_NAME__ -> 170:in ;
+21:__UG_NAME__ -> 174:in ;
+37:__UG_NAME__ -> 182:in ;
+38:__UG_NAME__ -> 186:in ;
+42:__UG_NAME__ -> 195:in ;
+34:__UG_NAME__ -> 201:in ;
+208:__UG_NAME__ -> 209:in ;
+25:__UG_NAME__ -> 213:in ;
+4:__UG_NAME__ -> 222:in ;
+5:__UG_NAME__ -> 226:in ;
+81:__UG_NAME__ -> 144:freq ;
+58:__UG_NAME__ -> 132:bus ;
+200:__UG_NAME__ -> 206:in ;
+205:__UG_NAME__ -> 206:lag____time ;
+180:__UG_NAME__ -> 200:in ;
+190:__UG_NAME__ -> 200:lag____time____up ;
+199:__UG_NAME__ -> 200:lag____time____down ;
+81:__UG_NAME__ -> 95:freq ;
+45:__UG_NAME__ -> 95:iphase ;
+94:__UG_NAME__ -> 95:width ;
+81:__UG_NAME__ -> 84:freq ;
+83:__UG_NAME__ -> 84:iphase ;
+81:__UG_NAME__ -> 99:freq ;
+98:__UG_NAME__ -> 99:iphase ;
+162:__UG_NAME__ -> 180:in ;
+168:__UG_NAME__ -> 180:dstlo ;
+179:__UG_NAME__ -> 180:dsthi ;
+167:__UG_NAME__ -> 168:a ;
+178:__UG_NAME__ -> 179:a ;
+150:__UG_NAME__ -> 151:in ;
+24:__UG_NAME__ -> 208:in ;
+59:__UG_NAME__ -> 241:bus ;
+240:__UG_NAME__ -> 241:signals___x____fade2___0 ;
+233:__UG_NAME__ -> 241:signals___x____fade2___1 ;
+144:__UG_NAME__ -> 145:trig ;
+133:__UG_NAME__ -> 219:in ;
+206:__UG_NAME__ -> 219:freq ;
+217:__UG_NAME__ -> 219:rq ;
+234:__UG_NAME__ -> 236:in ;
+206:__UG_NAME__ -> 236:freq ;
+217:__UG_NAME__ -> 236:rq ;
+133:__UG_NAME__ -> 218:in ;
+206:__UG_NAME__ -> 218:freq ;
+217:__UG_NAME__ -> 218:rq ;
+234:__UG_NAME__ -> 235:in ;
+206:__UG_NAME__ -> 235:freq ;
+217:__UG_NAME__ -> 235:rq ;
+46:__UG_NAME__ -> 103:which ;
+85:__UG_NAME__ -> 103:array___binary____op____u____gen___0 ;
+97:__UG_NAME__ -> 103:array___binary____op____u____gen___1 ;
+99:__UG_NAME__ -> 103:array___lf____tri___2 ;
+102:__UG_NAME__ -> 103:array___sin____osc___3 ;
+148:__UG_NAME__ -> 161:which ;
+160:__UG_NAME__ -> 161:array___env____gen___0 ;
+104:__UG_NAME__ -> 161:array___binary____op____u____gen___1 ;
+143:__UG_NAME__ -> 162:which ;
+104:__UG_NAME__ -> 162:array___binary____op____u____gen___0 ;
+161:__UG_NAME__ -> 162:array___select___1 ;
+32:__UG_NAME__ -> 220:which ;
+218:__UG_NAME__ -> 220:array___rlpf___0 ;
+219:__UG_NAME__ -> 220:array___rhpf___1 ;
+32:__UG_NAME__ -> 237:which ;
+235:__UG_NAME__ -> 237:array___rlpf___0 ;
+236:__UG_NAME__ -> 237:array___rhpf___1 ;
+81:__UG_NAME__ -> 102:freq ;
+101:__UG_NAME__ -> 102:phase ;
+133:__UG_NAME__ -> 233:ina ;
+220:__UG_NAME__ -> 233:inb ;
+232:__UG_NAME__ -> 233:pan ;
+115:__UG_NAME__ -> 233:level ;
+234:__UG_NAME__ -> 240:ina ;
+237:__UG_NAME__ -> 240:inb ;
+239:__UG_NAME__ -> 240:pan ;
+115:__UG_NAME__ -> 240:level ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-gnoise.dot b/etc/synthdefs/graphviz/dot/sonic-pi-gnoise.dot
new file mode 100644
index 0000000..cfba187
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-gnoise.dot
@@ -0,0 +1,223 @@
+digraph synthdef {
+70 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :cutoff
+ default: 110.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :res
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{<__UG_NAME__>gray-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+74 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+69 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+66 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+69:__UG_NAME__ -> 70:b ;
+70:__UG_NAME__ -> 72:a ;
+71:__UG_NAME__ -> 72:b ;
+28:__UG_NAME__ -> 33:a ;
+32:__UG_NAME__ -> 33:b ;
+33:__UG_NAME__ -> 37:a ;
+36:__UG_NAME__ -> 37:b ;
+39:__UG_NAME__ -> 41:a ;
+40:__UG_NAME__ -> 41:b ;
+41:__UG_NAME__ -> 45:a ;
+44:__UG_NAME__ -> 45:b ;
+27:__UG_NAME__ -> 51:a ;
+50:__UG_NAME__ -> 51:b ;
+51:__UG_NAME__ -> 55:a ;
+54:__UG_NAME__ -> 55:b ;
+57:__UG_NAME__ -> 61:a ;
+60:__UG_NAME__ -> 61:b ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+13:__UG_NAME__ -> 47:b ;
+31:__UG_NAME__ -> 32:a ;
+35:__UG_NAME__ -> 36:a ;
+26:__UG_NAME__ -> 40:a ;
+43:__UG_NAME__ -> 44:a ;
+49:__UG_NAME__ -> 50:a ;
+53:__UG_NAME__ -> 54:a ;
+59:__UG_NAME__ -> 60:a ;
+63:__UG_NAME__ -> 64:a ;
+25:__UG_NAME__ -> 26:a ;
+30:__UG_NAME__ -> 31:a ;
+34:__UG_NAME__ -> 35:a ;
+42:__UG_NAME__ -> 43:a ;
+48:__UG_NAME__ -> 49:a ;
+52:__UG_NAME__ -> 53:a ;
+58:__UG_NAME__ -> 59:a ;
+62:__UG_NAME__ -> 63:a ;
+29:__UG_NAME__ -> 38:envelope___mul____add___0 ;
+29:__UG_NAME__ -> 38:envelope___mul____add___4 ;
+21:__UG_NAME__ -> 38:envelope___control___5 ;
+22:__UG_NAME__ -> 38:envelope___control___6 ;
+23:__UG_NAME__ -> 38:envelope___control___7 ;
+37:__UG_NAME__ -> 38:gate ;
+16:__UG_NAME__ -> 46:envelope___control___0 ;
+16:__UG_NAME__ -> 46:envelope___control___4 ;
+17:__UG_NAME__ -> 46:envelope___control___5 ;
+18:__UG_NAME__ -> 46:envelope___control___6 ;
+19:__UG_NAME__ -> 46:envelope___control___7 ;
+45:__UG_NAME__ -> 46:gate ;
+4:__UG_NAME__ -> 56:envelope___control___0 ;
+4:__UG_NAME__ -> 56:envelope___control___4 ;
+5:__UG_NAME__ -> 56:envelope___control___5 ;
+6:__UG_NAME__ -> 56:envelope___control___6 ;
+7:__UG_NAME__ -> 56:envelope___control___7 ;
+55:__UG_NAME__ -> 56:gate ;
+12:__UG_NAME__ -> 71:envelope___control___4 ;
+8:__UG_NAME__ -> 71:envelope___control___5 ;
+15:__UG_NAME__ -> 71:envelope___control___6 ;
+66:__UG_NAME__ -> 71:envelope___select___8 ;
+10:__UG_NAME__ -> 71:envelope___control___9 ;
+15:__UG_NAME__ -> 71:envelope___control___10 ;
+14:__UG_NAME__ -> 71:envelope___control___12 ;
+9:__UG_NAME__ -> 71:envelope___control___13 ;
+15:__UG_NAME__ -> 71:envelope___control___14 ;
+11:__UG_NAME__ -> 71:envelope___control___17 ;
+15:__UG_NAME__ -> 71:envelope___control___18 ;
+0:__UG_NAME__ -> 73:envelope___control___0 ;
+0:__UG_NAME__ -> 73:envelope___control___4 ;
+1:__UG_NAME__ -> 73:envelope___control___5 ;
+2:__UG_NAME__ -> 73:envelope___control___6 ;
+3:__UG_NAME__ -> 73:envelope___control___7 ;
+65:__UG_NAME__ -> 73:gate ;
+16:__UG_NAME__ -> 25:in ;
+29:__UG_NAME__ -> 30:in ;
+21:__UG_NAME__ -> 34:in ;
+17:__UG_NAME__ -> 42:in ;
+4:__UG_NAME__ -> 48:in ;
+5:__UG_NAME__ -> 52:in ;
+0:__UG_NAME__ -> 58:in ;
+1:__UG_NAME__ -> 62:in ;
+46:__UG_NAME__ -> 68:a ;
+20:__UG_NAME__ -> 29:in ;
+24:__UG_NAME__ -> 75:bus ;
+74:__UG_NAME__ -> 75:signals___pan2___0 ;
+74:__UG_NAME__ -> 75:signals___pan2___1 ;
+72:__UG_NAME__ -> 74:in ;
+56:__UG_NAME__ -> 74:pos ;
+73:__UG_NAME__ -> 74:level ;
+67:__UG_NAME__ -> 69:in ;
+68:__UG_NAME__ -> 69:freq ;
+38:__UG_NAME__ -> 69:rq ;
+47:__UG_NAME__ -> 66:which ;
+13:__UG_NAME__ -> 66:array___control___0 ;
+14:__UG_NAME__ -> 66:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-growl.dot b/etc/synthdefs/graphviz/dot/sonic-pi-growl.dot
new file mode 100644
index 0000000..e9fd24d
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-growl.dot
@@ -0,0 +1,282 @@
+digraph synthdef {
+68 [label = "{{ <b> |<a> 0.25} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> 1.01} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> 0.5|<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+92 [label = "{{ <b> |<a> 3.0} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+96 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :attack
+ default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff
+ default: 130.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :res
+ default: 0.7" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <freq> freq 440.0|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ {{<signals___binary____op____u____gen___0>|<signals___binary____op____u____gen___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+95 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+90 [label = "{{ <time____dispersion> time-dispersion 0.001|<pitch____dispersion> pitch-dispersion 0.0|<pitch____ratio> pitch-ratio 1.0|<window____size> window-size 0.5|<in> in} |<__UG_NAME__>pitch-shift }" style="filled, bold, rounded"  shape=record rankdir=LR];
+91 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+69 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+93 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+44:__UG_NAME__ -> 68:b ;
+44:__UG_NAME__ -> 70:b ;
+72:__UG_NAME__ -> 73:a ;
+91:__UG_NAME__ -> 92:b ;
+94:__UG_NAME__ -> 96:a ;
+95:__UG_NAME__ -> 96:b ;
+94:__UG_NAME__ -> 97:a ;
+95:__UG_NAME__ -> 97:b ;
+29:__UG_NAME__ -> 33:a ;
+32:__UG_NAME__ -> 33:b ;
+34:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+38:__UG_NAME__ -> 42:a ;
+41:__UG_NAME__ -> 42:b ;
+55:__UG_NAME__ -> 61:a ;
+60:__UG_NAME__ -> 61:b ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+33:__UG_NAME__ -> 66:a ;
+52:__UG_NAME__ -> 66:b ;
+69:__UG_NAME__ -> 72:a ;
+71:__UG_NAME__ -> 72:b ;
+75:__UG_NAME__ -> 79:a ;
+78:__UG_NAME__ -> 79:b ;
+79:__UG_NAME__ -> 80:a ;
+47:__UG_NAME__ -> 80:b ;
+56:__UG_NAME__ -> 82:a ;
+81:__UG_NAME__ -> 82:b ;
+82:__UG_NAME__ -> 85:a ;
+84:__UG_NAME__ -> 85:b ;
+18:__UG_NAME__ -> 53:b ;
+31:__UG_NAME__ -> 32:a ;
+36:__UG_NAME__ -> 37:a ;
+40:__UG_NAME__ -> 41:a ;
+46:__UG_NAME__ -> 47:a ;
+51:__UG_NAME__ -> 52:a ;
+59:__UG_NAME__ -> 60:a ;
+63:__UG_NAME__ -> 64:a ;
+77:__UG_NAME__ -> 78:a ;
+49:__UG_NAME__ -> 81:a ;
+83:__UG_NAME__ -> 84:a ;
+30:__UG_NAME__ -> 31:a ;
+35:__UG_NAME__ -> 36:a ;
+39:__UG_NAME__ -> 40:a ;
+45:__UG_NAME__ -> 46:a ;
+48:__UG_NAME__ -> 49:a ;
+50:__UG_NAME__ -> 51:a ;
+58:__UG_NAME__ -> 59:a ;
+62:__UG_NAME__ -> 63:a ;
+76:__UG_NAME__ -> 77:a ;
+54:__UG_NAME__ -> 83:a ;
+1:__UG_NAME__ -> 43:envelope___control___0 ;
+1:__UG_NAME__ -> 43:envelope___control___4 ;
+2:__UG_NAME__ -> 43:envelope___control___5 ;
+3:__UG_NAME__ -> 43:envelope___control___6 ;
+4:__UG_NAME__ -> 43:envelope___control___7 ;
+42:__UG_NAME__ -> 43:gate ;
+9:__UG_NAME__ -> 67:envelope___control___0 ;
+9:__UG_NAME__ -> 67:envelope___control___4 ;
+10:__UG_NAME__ -> 67:envelope___control___5 ;
+11:__UG_NAME__ -> 67:envelope___control___6 ;
+12:__UG_NAME__ -> 67:envelope___control___7 ;
+66:__UG_NAME__ -> 67:gate ;
+57:__UG_NAME__ -> 86:envelope___mul____add___0 ;
+57:__UG_NAME__ -> 86:envelope___mul____add___4 ;
+26:__UG_NAME__ -> 86:envelope___control___5 ;
+27:__UG_NAME__ -> 86:envelope___control___6 ;
+28:__UG_NAME__ -> 86:envelope___control___7 ;
+65:__UG_NAME__ -> 86:gate ;
+5:__UG_NAME__ -> 87:envelope___control___0 ;
+5:__UG_NAME__ -> 87:envelope___control___4 ;
+6:__UG_NAME__ -> 87:envelope___control___5 ;
+7:__UG_NAME__ -> 87:envelope___control___6 ;
+8:__UG_NAME__ -> 87:envelope___control___7 ;
+85:__UG_NAME__ -> 87:gate ;
+21:__UG_NAME__ -> 88:envelope___control___0 ;
+21:__UG_NAME__ -> 88:envelope___control___4 ;
+22:__UG_NAME__ -> 88:envelope___control___5 ;
+23:__UG_NAME__ -> 88:envelope___control___6 ;
+24:__UG_NAME__ -> 88:envelope___control___7 ;
+80:__UG_NAME__ -> 88:gate ;
+17:__UG_NAME__ -> 94:envelope___control___4 ;
+13:__UG_NAME__ -> 94:envelope___control___5 ;
+20:__UG_NAME__ -> 94:envelope___control___6 ;
+93:__UG_NAME__ -> 94:envelope___select___8 ;
+14:__UG_NAME__ -> 94:envelope___control___9 ;
+20:__UG_NAME__ -> 94:envelope___control___10 ;
+19:__UG_NAME__ -> 94:envelope___control___12 ;
+15:__UG_NAME__ -> 94:envelope___control___13 ;
+20:__UG_NAME__ -> 94:envelope___control___14 ;
+16:__UG_NAME__ -> 94:envelope___control___17 ;
+20:__UG_NAME__ -> 94:envelope___control___18 ;
+9:__UG_NAME__ -> 30:in ;
+1:__UG_NAME__ -> 35:in ;
+2:__UG_NAME__ -> 39:in ;
+22:__UG_NAME__ -> 45:in ;
+5:__UG_NAME__ -> 48:in ;
+10:__UG_NAME__ -> 50:in ;
+6:__UG_NAME__ -> 54:in ;
+57:__UG_NAME__ -> 58:in ;
+26:__UG_NAME__ -> 62:in ;
+21:__UG_NAME__ -> 76:in ;
+73:__UG_NAME__ -> 74:in ;
+43:__UG_NAME__ -> 44:a ;
+88:__UG_NAME__ -> 89:a ;
+25:__UG_NAME__ -> 57:in ;
+0:__UG_NAME__ -> 98:bus ;
+97:__UG_NAME__ -> 98:signals___binary____op____u____gen___0 ;
+96:__UG_NAME__ -> 98:signals___binary____op____u____gen___1 ;
+92:__UG_NAME__ -> 95:in ;
+87:__UG_NAME__ -> 95:pos ;
+67:__UG_NAME__ -> 95:level ;
+74:__UG_NAME__ -> 90:in ;
+90:__UG_NAME__ -> 91:in ;
+89:__UG_NAME__ -> 91:freq ;
+86:__UG_NAME__ -> 91:rq ;
+68:__UG_NAME__ -> 69:freq ;
+53:__UG_NAME__ -> 93:which ;
+18:__UG_NAME__ -> 93:array___control___0 ;
+19:__UG_NAME__ -> 93:array___control___1 ;
+70:__UG_NAME__ -> 71:freq ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-hollow.dot b/etc/synthdefs/graphviz/dot/sonic-pi-hollow.dot
new file mode 100644
index 0000000..5c3ddc9
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-hollow.dot
@@ -0,0 +1,330 @@
+digraph synthdef {
+33 [label = "{{ <b> |<a> 0.2} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> 0.4} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> 0.5} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> 0.2} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+63 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> 0.5} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+83 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+86 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+87 [label = "{{ <b> 4.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> 0.125} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+109 [label = "{{ <b> |<a> 15.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+94 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+84 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+88 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+41 [label = "{<__UG_NAME__>brown-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+45 [label = "{<__UG_NAME__>clip-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 90.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :res
+ default: 0.99" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :noise
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :norm
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+50 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{<__UG_NAME__>gray-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+116 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+115 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+31 [label = "{<__UG_NAME__>pink-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+47 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___binary____op____u____gen___2>|<array___binary____op____u____gen___3>|<array___binary____op____u____gen___4>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+49 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ {{<array___lpf___0>|<array___normalizer___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+43 [label = "{<__UG_NAME__>white-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+32:__UG_NAME__ -> 33:b ;
+31:__UG_NAME__ -> 40:b ;
+41:__UG_NAME__ -> 42:b ;
+43:__UG_NAME__ -> 44:b ;
+45:__UG_NAME__ -> 46:b ;
+47:__UG_NAME__ -> 51:a ;
+50:__UG_NAME__ -> 51:b ;
+62:__UG_NAME__ -> 63:a ;
+71:__UG_NAME__ -> 72:b ;
+47:__UG_NAME__ -> 83:a ;
+50:__UG_NAME__ -> 83:b ;
+47:__UG_NAME__ -> 86:a ;
+50:__UG_NAME__ -> 86:b ;
+62:__UG_NAME__ -> 87:a ;
+88:__UG_NAME__ -> 89:b ;
+50:__UG_NAME__ -> 109:b ;
+109:__UG_NAME__ -> 114:a ;
+113:__UG_NAME__ -> 114:b ;
+52:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+56:__UG_NAME__ -> 60:a ;
+59:__UG_NAME__ -> 60:b ;
+64:__UG_NAME__ -> 65:a ;
+37:__UG_NAME__ -> 65:b ;
+65:__UG_NAME__ -> 69:a ;
+68:__UG_NAME__ -> 69:b ;
+73:__UG_NAME__ -> 77:a ;
+76:__UG_NAME__ -> 77:b ;
+77:__UG_NAME__ -> 81:a ;
+80:__UG_NAME__ -> 81:b ;
+84:__UG_NAME__ -> 85:a ;
+72:__UG_NAME__ -> 85:b ;
+85:__UG_NAME__ -> 90:a ;
+89:__UG_NAME__ -> 90:b ;
+91:__UG_NAME__ -> 94:a ;
+93:__UG_NAME__ -> 94:b ;
+94:__UG_NAME__ -> 98:a ;
+97:__UG_NAME__ -> 98:b ;
+102:__UG_NAME__ -> 106:a ;
+105:__UG_NAME__ -> 106:b ;
+106:__UG_NAME__ -> 107:a ;
+101:__UG_NAME__ -> 107:b ;
+17:__UG_NAME__ -> 48:b ;
+36:__UG_NAME__ -> 37:a ;
+54:__UG_NAME__ -> 55:a ;
+58:__UG_NAME__ -> 59:a ;
+67:__UG_NAME__ -> 68:a ;
+75:__UG_NAME__ -> 76:a ;
+79:__UG_NAME__ -> 80:a ;
+92:__UG_NAME__ -> 93:a ;
+96:__UG_NAME__ -> 97:a ;
+100:__UG_NAME__ -> 101:a ;
+104:__UG_NAME__ -> 105:a ;
+35:__UG_NAME__ -> 36:a ;
+53:__UG_NAME__ -> 54:a ;
+57:__UG_NAME__ -> 58:a ;
+66:__UG_NAME__ -> 67:a ;
+74:__UG_NAME__ -> 75:a ;
+78:__UG_NAME__ -> 79:a ;
+38:__UG_NAME__ -> 92:a ;
+95:__UG_NAME__ -> 96:a ;
+39:__UG_NAME__ -> 100:a ;
+103:__UG_NAME__ -> 104:a ;
+51:__UG_NAME__ -> 71:in ;
+63:__UG_NAME__ -> 71:freq ;
+70:__UG_NAME__ -> 71:rq ;
+83:__UG_NAME__ -> 84:in ;
+62:__UG_NAME__ -> 84:freq ;
+70:__UG_NAME__ -> 84:rq ;
+86:__UG_NAME__ -> 88:in ;
+87:__UG_NAME__ -> 88:freq ;
+70:__UG_NAME__ -> 88:rq ;
+16:__UG_NAME__ -> 50:envelope___control___4 ;
+12:__UG_NAME__ -> 50:envelope___control___5 ;
+19:__UG_NAME__ -> 50:envelope___control___6 ;
+49:__UG_NAME__ -> 50:envelope___select___8 ;
+13:__UG_NAME__ -> 50:envelope___control___9 ;
+19:__UG_NAME__ -> 50:envelope___control___10 ;
+18:__UG_NAME__ -> 50:envelope___control___12 ;
+14:__UG_NAME__ -> 50:envelope___control___13 ;
+19:__UG_NAME__ -> 50:envelope___control___14 ;
+15:__UG_NAME__ -> 50:envelope___control___17 ;
+19:__UG_NAME__ -> 50:envelope___control___18 ;
+0:__UG_NAME__ -> 61:envelope___control___0 ;
+0:__UG_NAME__ -> 61:envelope___control___4 ;
+1:__UG_NAME__ -> 61:envelope___control___5 ;
+2:__UG_NAME__ -> 61:envelope___control___6 ;
+3:__UG_NAME__ -> 61:envelope___control___7 ;
+60:__UG_NAME__ -> 61:gate ;
+34:__UG_NAME__ -> 70:envelope___mul____add___0 ;
+34:__UG_NAME__ -> 70:envelope___mul____add___4 ;
+25:__UG_NAME__ -> 70:envelope___control___5 ;
+26:__UG_NAME__ -> 70:envelope___control___6 ;
+27:__UG_NAME__ -> 70:envelope___control___7 ;
+69:__UG_NAME__ -> 70:gate ;
+4:__UG_NAME__ -> 82:envelope___control___0 ;
+4:__UG_NAME__ -> 82:envelope___control___4 ;
+5:__UG_NAME__ -> 82:envelope___control___5 ;
+6:__UG_NAME__ -> 82:envelope___control___6 ;
+7:__UG_NAME__ -> 82:envelope___control___7 ;
+81:__UG_NAME__ -> 82:gate ;
+8:__UG_NAME__ -> 99:envelope___control___0 ;
+8:__UG_NAME__ -> 99:envelope___control___4 ;
+9:__UG_NAME__ -> 99:envelope___control___5 ;
+10:__UG_NAME__ -> 99:envelope___control___6 ;
+11:__UG_NAME__ -> 99:envelope___control___7 ;
+98:__UG_NAME__ -> 99:gate ;
+20:__UG_NAME__ -> 108:envelope___control___0 ;
+20:__UG_NAME__ -> 108:envelope___control___4 ;
+21:__UG_NAME__ -> 108:envelope___control___5 ;
+22:__UG_NAME__ -> 108:envelope___control___6 ;
+23:__UG_NAME__ -> 108:envelope___control___7 ;
+107:__UG_NAME__ -> 108:gate ;
+34:__UG_NAME__ -> 35:in ;
+8:__UG_NAME__ -> 38:in ;
+21:__UG_NAME__ -> 39:in ;
+0:__UG_NAME__ -> 53:in ;
+1:__UG_NAME__ -> 57:in ;
+25:__UG_NAME__ -> 66:in ;
+4:__UG_NAME__ -> 74:in ;
+5:__UG_NAME__ -> 78:in ;
+9:__UG_NAME__ -> 95:in ;
+20:__UG_NAME__ -> 103:in ;
+90:__UG_NAME__ -> 111:in ;
+110:__UG_NAME__ -> 111:freq ;
+61:__UG_NAME__ -> 62:a ;
+108:__UG_NAME__ -> 110:a ;
+24:__UG_NAME__ -> 34:in ;
+111:__UG_NAME__ -> 112:in ;
+30:__UG_NAME__ -> 116:bus ;
+115:__UG_NAME__ -> 116:signals___pan2___0 ;
+115:__UG_NAME__ -> 116:signals___pan2___1 ;
+114:__UG_NAME__ -> 115:in ;
+82:__UG_NAME__ -> 115:pos ;
+99:__UG_NAME__ -> 115:level ;
+28:__UG_NAME__ -> 47:which ;
+40:__UG_NAME__ -> 47:array___binary____op____u____gen___0 ;
+42:__UG_NAME__ -> 47:array___binary____op____u____gen___1 ;
+44:__UG_NAME__ -> 47:array___binary____op____u____gen___2 ;
+46:__UG_NAME__ -> 47:array___binary____op____u____gen___3 ;
+33:__UG_NAME__ -> 47:array___binary____op____u____gen___4 ;
+48:__UG_NAME__ -> 49:which ;
+17:__UG_NAME__ -> 49:array___control___0 ;
+18:__UG_NAME__ -> 49:array___control___1 ;
+29:__UG_NAME__ -> 113:which ;
+111:__UG_NAME__ -> 113:array___lpf___0 ;
+112:__UG_NAME__ -> 113:array___normalizer___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-hoover.dot b/etc/synthdefs/graphviz/dot/sonic-pi-hoover.dot
new file mode 100644
index 0000000..377923b
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-hoover.dot
@@ -0,0 +1,456 @@
+digraph synthdef {
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> 0.25} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> 0.5|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> 0.5} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> 0.1} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> 0.25} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> |<a> 0.25} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> |<a> 0.5} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+107 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+111 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+146 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+151 [label = "{{ <b> |<a> 0.25} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+158 [label = "{{ <b> |<a> 0.5} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+160 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+161 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+163 [label = "{{ <b> |<a> 0.5} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+165 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+166 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+83 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+106 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+116 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+140 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+153 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+159 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+164 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
+108 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+143 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <db> db 3.0|<rq> rq 1.0|<freq> freq 6000.0|<in> in} |<__UG_NAME__>b-peak-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
+86 [label = "{{ <db> db 6.0|<rq> rq 1.0|<freq> freq 3500.0|<in> in} |<__UG_NAME__>b-peak-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
+100 [label = "{{ <db> db 3.0|<rq> rq 1.0|<freq> freq 6000.0|<in> in} |<__UG_NAME__>b-peak-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
+101 [label = "{{ <db> db 6.0|<rq> rq 1.0|<freq> freq 3500.0|<in> in} |<__UG_NAME__>b-peak-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
+155 [label = "{{ <db> db 3.0|<rq> rq 1.0|<freq> freq 6000.0|<in> in} |<__UG_NAME__>b-peak-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
+156 [label = "{{ <db> db 6.0|<rq> rq 1.0|<freq> freq 3500.0|<in> in} |<__UG_NAME__>b-peak-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
+104 [label = "{{ <decay____time> decay-time 0.0|<delay____time> delay-time|<max____delay____time> max-delay-time 0.005|<in> in} |<__UG_NAME__>comb-c }" style="filled, bold, rounded"  shape=record rankdir=LR];
+150 [label = "{{ <decay____time> decay-time 0.0|<delay____time> delay-time|<max____delay____time> max-delay-time 0.005|<in> in} |<__UG_NAME__>comb-c }" style="filled, bold, rounded"  shape=record rankdir=LR];
+157 [label = "{{ <decay____time> decay-time 0.0|<delay____time> delay-time|<max____delay____time> max-delay-time 0.005|<in> in} |<__UG_NAME__>comb-c }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.05" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 130.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :res
+ default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :pre_amp
+ default: 10.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :amp-fudge
+ default: 2.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+40 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+145 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <iphase> iphase 0.0|<freq> freq} |<__UG_NAME__>lf-par }" style="filled, bold, rounded"  shape=record rankdir=LR];
+97 [label = "{{ <iphase> iphase 0.0|<freq> freq} |<__UG_NAME__>lf-par }" style="filled, bold, rounded"  shape=record rankdir=LR];
+152 [label = "{{ <iphase> iphase 0.0|<freq> freq} |<__UG_NAME__>lf-par }" style="filled, bold, rounded"  shape=record rankdir=LR];
+51 [label = "{{ <width> width|<iphase> iphase 0.0|<freq> freq} |<__UG_NAME__>lf-pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+63 [label = "{{ <width> width|<iphase> iphase 0.0|<freq> freq} |<__UG_NAME__>lf-pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+76 [label = "{{ <width> width|<iphase> iphase 0.0|<freq> freq} |<__UG_NAME__>lf-pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+46 [label = "{{ <iphase> iphase 1.0|<freq> freq} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+58 [label = "{{ <iphase> iphase 1.0|<freq> freq} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+71 [label = "{{ <iphase> iphase 1.0|<freq> freq} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+43 [label = "{{ <dsthi> dsthi 1.005|<dstlo> dstlo 0.995|<srchi> srchi 1.0|<srclo> srclo -1.0|<in> in} |<__UG_NAME__>lin-exp }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <dsthi> dsthi 1.005|<dstlo> dstlo 0.995|<srchi> srchi 1.0|<srclo> srclo -1.0|<in> in} |<__UG_NAME__>lin-exp }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <dsthi> dsthi 1.005|<dstlo> dstlo 0.995|<srchi> srchi 1.0|<srclo> srclo -1.0|<in> in} |<__UG_NAME__>lin-exp }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <add> add 0.5|<mul> mul 0.5|<in> in} |<__UG_NAME__>mul-add }" style="filled, bold, rounded"  shape=record rankdir=LR];
+50 [label = "{{ <add> add 0.5|<mul> mul 0.375|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <add> add 0.5|<mul> mul 0.5|<in> in} |<__UG_NAME__>mul-add }" style="filled, bold, rounded"  shape=record rankdir=LR];
+62 [label = "{{ <add> add 0.5|<mul> mul 0.375|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <add> add 0.5|<mul> mul 0.5|<in> in} |<__UG_NAME__>mul-add }" style="filled, bold, rounded"  shape=record rankdir=LR];
+75 [label = "{{ <add> add 0.5|<mul> mul 0.375|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <add> add 0.0|<mul> mul 0.1|<in> in} |<__UG_NAME__>mul-add }" style="filled, bold, rounded"  shape=record rankdir=LR];
+99 [label = "{{ <add> add 0.0|<mul> mul 0.1|<in> in} |<__UG_NAME__>mul-add }" style="filled, bold, rounded"  shape=record rankdir=LR];
+103 [label = "{{ <add> add 0.004166667|<mul> mul 8.3333335E-4|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+149 [label = "{{ <add> add 0.004166667|<mul> mul 8.3333335E-4|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+154 [label = "{{ <add> add 0.0|<mul> mul 0.1|<in> in} |<__UG_NAME__>mul-add }" style="filled, bold, rounded"  shape=record rankdir=LR];
+170 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>|<signals___pan2___2>|<signals___pan2___3>|<signals___pan2___4>|<signals___pan2___5>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+147 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+167 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+169 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+134 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+162 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+168 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+109 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 4.6028047|<freq> freq 2.915749} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq 3.9668026} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 3.7951565|<freq> freq 3.032818} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq 2.9856791} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.26021367|<freq> freq 2.9540849} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq 3.9303746} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 4.712389|<freq> freq 3.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+148 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 1.5707964|<freq> freq 3.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+
+41:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+44:__UG_NAME__ -> 45:b ;
+44:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+41:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+56:__UG_NAME__ -> 57:b ;
+56:__UG_NAME__ -> 60:a ;
+59:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+41:__UG_NAME__ -> 69:a ;
+68:__UG_NAME__ -> 69:b ;
+69:__UG_NAME__ -> 70:b ;
+69:__UG_NAME__ -> 73:a ;
+72:__UG_NAME__ -> 78:a ;
+77:__UG_NAME__ -> 78:b ;
+79:__UG_NAME__ -> 80:b ;
+69:__UG_NAME__ -> 81:b ;
+56:__UG_NAME__ -> 96:b ;
+104:__UG_NAME__ -> 105:b ;
+28:__UG_NAME__ -> 107:a ;
+106:__UG_NAME__ -> 107:b ;
+107:__UG_NAME__ -> 111:a ;
+110:__UG_NAME__ -> 111:b ;
+29:__UG_NAME__ -> 146:a ;
+145:__UG_NAME__ -> 146:b ;
+44:__UG_NAME__ -> 151:b ;
+157:__UG_NAME__ -> 158:b ;
+28:__UG_NAME__ -> 160:a ;
+159:__UG_NAME__ -> 160:b ;
+160:__UG_NAME__ -> 161:a ;
+110:__UG_NAME__ -> 161:b ;
+150:__UG_NAME__ -> 163:b ;
+28:__UG_NAME__ -> 165:a ;
+164:__UG_NAME__ -> 165:b ;
+165:__UG_NAME__ -> 166:a ;
+110:__UG_NAME__ -> 166:b ;
+31:__UG_NAME__ -> 35:a ;
+34:__UG_NAME__ -> 35:b ;
+35:__UG_NAME__ -> 39:a ;
+38:__UG_NAME__ -> 39:b ;
+53:__UG_NAME__ -> 66:a ;
+65:__UG_NAME__ -> 66:b ;
+66:__UG_NAME__ -> 79:a ;
+78:__UG_NAME__ -> 79:b ;
+80:__UG_NAME__ -> 83:a ;
+82:__UG_NAME__ -> 83:b ;
+87:__UG_NAME__ -> 91:a ;
+90:__UG_NAME__ -> 91:b ;
+91:__UG_NAME__ -> 95:a ;
+94:__UG_NAME__ -> 95:b ;
+80:__UG_NAME__ -> 98:a ;
+97:__UG_NAME__ -> 98:b ;
+101:__UG_NAME__ -> 106:a ;
+105:__UG_NAME__ -> 106:b ;
+112:__UG_NAME__ -> 116:a ;
+115:__UG_NAME__ -> 116:b ;
+116:__UG_NAME__ -> 120:a ;
+119:__UG_NAME__ -> 120:b ;
+123:__UG_NAME__ -> 128:a ;
+127:__UG_NAME__ -> 128:b ;
+128:__UG_NAME__ -> 132:a ;
+131:__UG_NAME__ -> 132:b ;
+136:__UG_NAME__ -> 140:a ;
+139:__UG_NAME__ -> 140:b ;
+140:__UG_NAME__ -> 144:a ;
+143:__UG_NAME__ -> 144:b ;
+80:__UG_NAME__ -> 153:a ;
+152:__UG_NAME__ -> 153:b ;
+156:__UG_NAME__ -> 159:a ;
+158:__UG_NAME__ -> 159:b ;
+86:__UG_NAME__ -> 164:a ;
+163:__UG_NAME__ -> 164:b ;
+51:__UG_NAME__ -> 52:b ;
+63:__UG_NAME__ -> 64:b ;
+76:__UG_NAME__ -> 77:b ;
+17:__UG_NAME__ -> 108:b ;
+33:__UG_NAME__ -> 34:a ;
+37:__UG_NAME__ -> 38:a ;
+89:__UG_NAME__ -> 90:a ;
+93:__UG_NAME__ -> 94:a ;
+114:__UG_NAME__ -> 115:a ;
+118:__UG_NAME__ -> 119:a ;
+126:__UG_NAME__ -> 127:a ;
+130:__UG_NAME__ -> 131:a ;
+138:__UG_NAME__ -> 139:a ;
+142:__UG_NAME__ -> 143:a ;
+32:__UG_NAME__ -> 33:a ;
+36:__UG_NAME__ -> 37:a ;
+88:__UG_NAME__ -> 89:a ;
+92:__UG_NAME__ -> 93:a ;
+113:__UG_NAME__ -> 114:a ;
+117:__UG_NAME__ -> 118:a ;
+125:__UG_NAME__ -> 126:a ;
+129:__UG_NAME__ -> 130:a ;
+137:__UG_NAME__ -> 138:a ;
+141:__UG_NAME__ -> 142:a ;
+84:__UG_NAME__ -> 85:in ;
+85:__UG_NAME__ -> 86:in ;
+99:__UG_NAME__ -> 100:in ;
+100:__UG_NAME__ -> 101:in ;
+154:__UG_NAME__ -> 155:in ;
+155:__UG_NAME__ -> 156:in ;
+101:__UG_NAME__ -> 104:in ;
+103:__UG_NAME__ -> 104:delay____time ;
+86:__UG_NAME__ -> 150:in ;
+149:__UG_NAME__ -> 150:delay____time ;
+156:__UG_NAME__ -> 157:in ;
+149:__UG_NAME__ -> 157:delay____time ;
+0:__UG_NAME__ -> 40:envelope___control___0 ;
+0:__UG_NAME__ -> 40:envelope___control___4 ;
+1:__UG_NAME__ -> 40:envelope___control___5 ;
+2:__UG_NAME__ -> 40:envelope___control___6 ;
+3:__UG_NAME__ -> 40:envelope___control___7 ;
+39:__UG_NAME__ -> 40:gate ;
+16:__UG_NAME__ -> 110:envelope___control___4 ;
+12:__UG_NAME__ -> 110:envelope___control___5 ;
+19:__UG_NAME__ -> 110:envelope___control___6 ;
+109:__UG_NAME__ -> 110:envelope___select___8 ;
+13:__UG_NAME__ -> 110:envelope___control___9 ;
+19:__UG_NAME__ -> 110:envelope___control___10 ;
+18:__UG_NAME__ -> 110:envelope___control___12 ;
+14:__UG_NAME__ -> 110:envelope___control___13 ;
+19:__UG_NAME__ -> 110:envelope___control___14 ;
+15:__UG_NAME__ -> 110:envelope___control___17 ;
+19:__UG_NAME__ -> 110:envelope___control___18 ;
+20:__UG_NAME__ -> 121:envelope___control___0 ;
+20:__UG_NAME__ -> 121:envelope___control___4 ;
+21:__UG_NAME__ -> 121:envelope___control___5 ;
+22:__UG_NAME__ -> 121:envelope___control___6 ;
+23:__UG_NAME__ -> 121:envelope___control___7 ;
+120:__UG_NAME__ -> 121:gate ;
+124:__UG_NAME__ -> 133:envelope___mul____add___0 ;
+124:__UG_NAME__ -> 133:envelope___mul____add___4 ;
+25:__UG_NAME__ -> 133:envelope___control___5 ;
+26:__UG_NAME__ -> 133:envelope___control___6 ;
+27:__UG_NAME__ -> 133:envelope___control___7 ;
+132:__UG_NAME__ -> 133:gate ;
+8:__UG_NAME__ -> 135:envelope___control___0 ;
+8:__UG_NAME__ -> 135:envelope___control___4 ;
+9:__UG_NAME__ -> 135:envelope___control___5 ;
+10:__UG_NAME__ -> 135:envelope___control___6 ;
+11:__UG_NAME__ -> 135:envelope___control___7 ;
+95:__UG_NAME__ -> 135:gate ;
+4:__UG_NAME__ -> 145:envelope___control___0 ;
+4:__UG_NAME__ -> 145:envelope___control___4 ;
+5:__UG_NAME__ -> 145:envelope___control___5 ;
+6:__UG_NAME__ -> 145:envelope___control___6 ;
+7:__UG_NAME__ -> 145:envelope___control___7 ;
+144:__UG_NAME__ -> 145:gate ;
+0:__UG_NAME__ -> 32:in ;
+1:__UG_NAME__ -> 36:in ;
+8:__UG_NAME__ -> 88:in ;
+9:__UG_NAME__ -> 92:in ;
+20:__UG_NAME__ -> 113:in ;
+21:__UG_NAME__ -> 117:in ;
+124:__UG_NAME__ -> 125:in ;
+25:__UG_NAME__ -> 129:in ;
+4:__UG_NAME__ -> 137:in ;
+5:__UG_NAME__ -> 141:in ;
+81:__UG_NAME__ -> 82:freq ;
+96:__UG_NAME__ -> 97:freq ;
+151:__UG_NAME__ -> 152:freq ;
+48:__UG_NAME__ -> 51:freq ;
+50:__UG_NAME__ -> 51:width ;
+60:__UG_NAME__ -> 63:freq ;
+62:__UG_NAME__ -> 63:width ;
+73:__UG_NAME__ -> 76:freq ;
+75:__UG_NAME__ -> 76:width ;
+45:__UG_NAME__ -> 46:freq ;
+57:__UG_NAME__ -> 58:freq ;
+70:__UG_NAME__ -> 71:freq ;
+42:__UG_NAME__ -> 43:in ;
+54:__UG_NAME__ -> 55:in ;
+67:__UG_NAME__ -> 68:in ;
+40:__UG_NAME__ -> 41:a ;
+121:__UG_NAME__ -> 122:a ;
+46:__UG_NAME__ -> 47:in ;
+49:__UG_NAME__ -> 50:in ;
+58:__UG_NAME__ -> 59:in ;
+61:__UG_NAME__ -> 62:in ;
+71:__UG_NAME__ -> 72:in ;
+74:__UG_NAME__ -> 75:in ;
+83:__UG_NAME__ -> 84:in ;
+98:__UG_NAME__ -> 99:in ;
+102:__UG_NAME__ -> 103:in ;
+24:__UG_NAME__ -> 124:in ;
+148:__UG_NAME__ -> 149:in ;
+153:__UG_NAME__ -> 154:in ;
+30:__UG_NAME__ -> 170:bus ;
+167:__UG_NAME__ -> 170:signals___pan2___0 ;
+167:__UG_NAME__ -> 170:signals___pan2___1 ;
+147:__UG_NAME__ -> 170:signals___pan2___2 ;
+147:__UG_NAME__ -> 170:signals___pan2___3 ;
+169:__UG_NAME__ -> 170:signals___pan2___4 ;
+169:__UG_NAME__ -> 170:signals___pan2___5 ;
+134:__UG_NAME__ -> 147:in ;
+135:__UG_NAME__ -> 147:pos ;
+146:__UG_NAME__ -> 147:level ;
+162:__UG_NAME__ -> 167:in ;
+135:__UG_NAME__ -> 167:pos ;
+146:__UG_NAME__ -> 167:level ;
+168:__UG_NAME__ -> 169:in ;
+135:__UG_NAME__ -> 169:pos ;
+146:__UG_NAME__ -> 169:level ;
+111:__UG_NAME__ -> 134:in ;
+122:__UG_NAME__ -> 134:freq ;
+133:__UG_NAME__ -> 134:rq ;
+161:__UG_NAME__ -> 162:in ;
+122:__UG_NAME__ -> 162:freq ;
+133:__UG_NAME__ -> 162:rq ;
+166:__UG_NAME__ -> 168:in ;
+122:__UG_NAME__ -> 168:freq ;
+133:__UG_NAME__ -> 168:rq ;
+108:__UG_NAME__ -> 109:which ;
+17:__UG_NAME__ -> 109:array___control___0 ;
+18:__UG_NAME__ -> 109:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-mixer.dot b/etc/synthdefs/graphviz/dot/sonic-pi-mixer.dot
new file mode 100644
index 0000000..8c2dbb0
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-mixer.dot
@@ -0,0 +1,289 @@
+digraph synthdef {
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+93 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+79 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+26 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <hi> hi 135.5|<lo> lo 0.0|<in> in} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>clip2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+98 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>clip2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :pre_amp_slide
+ default: 0.02" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide
+ default: 0.02" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :hpf
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :hpf_bypass
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :hpf_slide
+ default: 0.02" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :hpf_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :hpf_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :lpf
+ default: 135.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :lpf_bypass
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :lpf_slide
+ default: 0.02" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :lpf_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :lpf_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :force_mono
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :invert_stereo
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :limiter_bypass
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :leak_dc_bypass
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+41 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+74 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+95 [label = "{{ <freq> freq 10.0|<in> in} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+99 [label = "{{ <freq> freq 10.0|<in> in} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+24 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <num____channels> num-channels 1|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+72 [label = "{{ <num____channels> num-channels 1|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+85 [label = "{{ <coef> coef 0.995|<in> in} |<__UG_NAME__>leak-dc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+91 [label = "{{ <coef> coef 0.995|<in> in} |<__UG_NAME__>leak-dc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+83 [label = "{{ <dur> dur 0.01|<level> level 0.99|<in> in} |<__UG_NAME__>limiter }" style="filled, bold, rounded"  shape=record rankdir=LR];
+89 [label = "{{ <dur> dur 0.01|<level> level 0.99|<in> in} |<__UG_NAME__>limiter }" style="filled, bold, rounded"  shape=record rankdir=LR];
+69 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+76 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+96 [label = "{{ <freq> freq 20500.0|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+100 [label = "{{ <freq> freq 20500.0|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ {{<signals___lpf___0>|<signals___lpf___1>}|signals}|<bus> bus 0.0} |<__UG_NAME__>replace-out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+67 [label = "{{ {{<array___hpf___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+70 [label = "{{ {{<array___lpf___0>|<array___select___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+75 [label = "{{ {{<array___hpf___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+77 [label = "{{ {{<array___lpf___0>|<array___select___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+80 [label = "{{ {{<array___select___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+81 [label = "{{ {{<array___select___0>|<array___select___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+82 [label = "{{ {{<array___select___0>|<array___select___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+84 [label = "{{ {{<array___limiter___0>|<array___select___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+86 [label = "{{ {{<array___leak____dc___0>|<array___select___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+88 [label = "{{ {{<array___select___0>|<array___select___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+90 [label = "{{ {{<array___limiter___0>|<array___select___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+92 [label = "{{ {{<array___leak____dc___0>|<array___select___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+52:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+52:__UG_NAME__ -> 73:a ;
+72:__UG_NAME__ -> 73:b ;
+87:__UG_NAME__ -> 93:a ;
+92:__UG_NAME__ -> 93:b ;
+87:__UG_NAME__ -> 97:a ;
+86:__UG_NAME__ -> 97:b ;
+23:__UG_NAME__ -> 27:a ;
+26:__UG_NAME__ -> 27:b ;
+27:__UG_NAME__ -> 31:a ;
+30:__UG_NAME__ -> 31:b ;
+32:__UG_NAME__ -> 36:a ;
+35:__UG_NAME__ -> 36:b ;
+36:__UG_NAME__ -> 40:a ;
+39:__UG_NAME__ -> 40:b ;
+45:__UG_NAME__ -> 49:a ;
+48:__UG_NAME__ -> 49:b ;
+49:__UG_NAME__ -> 51:a ;
+50:__UG_NAME__ -> 51:b ;
+55:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+59:__UG_NAME__ -> 63:a ;
+62:__UG_NAME__ -> 63:b ;
+0:__UG_NAME__ -> 71:a ;
+70:__UG_NAME__ -> 78:a ;
+77:__UG_NAME__ -> 78:b ;
+78:__UG_NAME__ -> 79:a ;
+25:__UG_NAME__ -> 26:a ;
+29:__UG_NAME__ -> 30:a ;
+34:__UG_NAME__ -> 35:a ;
+38:__UG_NAME__ -> 39:a ;
+47:__UG_NAME__ -> 48:a ;
+44:__UG_NAME__ -> 50:a ;
+57:__UG_NAME__ -> 58:a ;
+61:__UG_NAME__ -> 62:a ;
+24:__UG_NAME__ -> 25:a ;
+28:__UG_NAME__ -> 29:a ;
+33:__UG_NAME__ -> 34:a ;
+37:__UG_NAME__ -> 38:a ;
+43:__UG_NAME__ -> 44:a ;
+46:__UG_NAME__ -> 47:a ;
+56:__UG_NAME__ -> 57:a ;
+60:__UG_NAME__ -> 61:a ;
+41:__UG_NAME__ -> 42:in ;
+93:__UG_NAME__ -> 94:a ;
+97:__UG_NAME__ -> 98:a ;
+14:__UG_NAME__ -> 41:envelope___control___0 ;
+14:__UG_NAME__ -> 41:envelope___control___4 ;
+16:__UG_NAME__ -> 41:envelope___control___5 ;
+17:__UG_NAME__ -> 41:envelope___control___6 ;
+18:__UG_NAME__ -> 41:envelope___control___7 ;
+40:__UG_NAME__ -> 41:gate ;
+1:__UG_NAME__ -> 52:envelope___control___0 ;
+1:__UG_NAME__ -> 52:envelope___control___4 ;
+2:__UG_NAME__ -> 52:envelope___control___5 ;
+3:__UG_NAME__ -> 52:envelope___control___6 ;
+4:__UG_NAME__ -> 52:envelope___control___7 ;
+51:__UG_NAME__ -> 52:gate ;
+9:__UG_NAME__ -> 64:envelope___control___0 ;
+9:__UG_NAME__ -> 64:envelope___control___4 ;
+11:__UG_NAME__ -> 64:envelope___control___5 ;
+12:__UG_NAME__ -> 64:envelope___control___6 ;
+13:__UG_NAME__ -> 64:envelope___control___7 ;
+63:__UG_NAME__ -> 64:gate ;
+5:__UG_NAME__ -> 87:envelope___control___0 ;
+5:__UG_NAME__ -> 87:envelope___control___4 ;
+6:__UG_NAME__ -> 87:envelope___control___5 ;
+7:__UG_NAME__ -> 87:envelope___control___6 ;
+8:__UG_NAME__ -> 87:envelope___control___7 ;
+31:__UG_NAME__ -> 87:gate ;
+54:__UG_NAME__ -> 66:in ;
+65:__UG_NAME__ -> 66:freq ;
+73:__UG_NAME__ -> 74:in ;
+65:__UG_NAME__ -> 74:freq ;
+94:__UG_NAME__ -> 95:in ;
+98:__UG_NAME__ -> 99:in ;
+5:__UG_NAME__ -> 24:in ;
+6:__UG_NAME__ -> 28:in ;
+14:__UG_NAME__ -> 33:in ;
+16:__UG_NAME__ -> 37:in ;
+2:__UG_NAME__ -> 43:in ;
+1:__UG_NAME__ -> 46:in ;
+9:__UG_NAME__ -> 56:in ;
+11:__UG_NAME__ -> 60:in ;
+0:__UG_NAME__ -> 53:bus ;
+71:__UG_NAME__ -> 72:bus ;
+84:__UG_NAME__ -> 85:in ;
+90:__UG_NAME__ -> 91:in ;
+82:__UG_NAME__ -> 83:in ;
+88:__UG_NAME__ -> 89:in ;
+67:__UG_NAME__ -> 69:in ;
+68:__UG_NAME__ -> 69:freq ;
+75:__UG_NAME__ -> 76:in ;
+68:__UG_NAME__ -> 76:freq ;
+95:__UG_NAME__ -> 96:in ;
+99:__UG_NAME__ -> 100:in ;
+64:__UG_NAME__ -> 65:a ;
+42:__UG_NAME__ -> 68:a ;
+100:__UG_NAME__ -> 101:signals___lpf___0 ;
+96:__UG_NAME__ -> 101:signals___lpf___1 ;
+10:__UG_NAME__ -> 67:which ;
+66:__UG_NAME__ -> 67:array___hpf___0 ;
+54:__UG_NAME__ -> 67:array___binary____op____u____gen___1 ;
+15:__UG_NAME__ -> 70:which ;
+69:__UG_NAME__ -> 70:array___lpf___0 ;
+67:__UG_NAME__ -> 70:array___select___1 ;
+10:__UG_NAME__ -> 75:which ;
+74:__UG_NAME__ -> 75:array___hpf___0 ;
+73:__UG_NAME__ -> 75:array___binary____op____u____gen___1 ;
+15:__UG_NAME__ -> 77:which ;
+76:__UG_NAME__ -> 77:array___lpf___0 ;
+75:__UG_NAME__ -> 77:array___select___1 ;
+19:__UG_NAME__ -> 80:which ;
+70:__UG_NAME__ -> 80:array___select___0 ;
+79:__UG_NAME__ -> 80:array___binary____op____u____gen___1 ;
+19:__UG_NAME__ -> 81:which ;
+77:__UG_NAME__ -> 81:array___select___0 ;
+80:__UG_NAME__ -> 81:array___select___1 ;
+20:__UG_NAME__ -> 82:which ;
+80:__UG_NAME__ -> 82:array___select___0 ;
+81:__UG_NAME__ -> 82:array___select___1 ;
+21:__UG_NAME__ -> 84:which ;
+83:__UG_NAME__ -> 84:array___limiter___0 ;
+82:__UG_NAME__ -> 84:array___select___1 ;
+22:__UG_NAME__ -> 86:which ;
+85:__UG_NAME__ -> 86:array___leak____dc___0 ;
+84:__UG_NAME__ -> 86:array___select___1 ;
+20:__UG_NAME__ -> 88:which ;
+81:__UG_NAME__ -> 88:array___select___0 ;
+80:__UG_NAME__ -> 88:array___select___1 ;
+21:__UG_NAME__ -> 90:which ;
+89:__UG_NAME__ -> 90:array___limiter___0 ;
+88:__UG_NAME__ -> 90:array___select___1 ;
+22:__UG_NAME__ -> 92:which ;
+91:__UG_NAME__ -> 92:array___leak____dc___0 ;
+90:__UG_NAME__ -> 92:array___select___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-mod_dsaw.dot b/etc/synthdefs/graphviz/dot/sonic-pi-mod_dsaw.dot
new file mode 100644
index 0000000..3826b01
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-mod_dsaw.dot
@@ -0,0 +1,461 @@
+digraph synthdef {
+65 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> 6.2831855|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ <b> -1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <b> 0.5|<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+140 [label = "{{ <b> |<a> 1.3} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+149 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+153 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+158 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+162 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+148 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+152 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+157 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+161 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+147 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+151 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+156 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+160 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :mod_phase
+ default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :mod_phase_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :mod_phase_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :mod_phase_slide_curve
+ default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :mod_range
+ default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :mod_range_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :mod_range_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :mod_range_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :mod_pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :mod_pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :mod_pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :mod_pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :mod_phase_offset
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "control
+ :mod_wave
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "control
+ :mod_invert_wave
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "control
+ :detune
+ default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+40 [label = "control
+ :detune_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+41 [label = "control
+ :detune_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+42 [label = "control
+ :detune_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+53 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|5|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+154 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+163 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+146 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+150 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+159 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+145 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+155 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <width> width|<iphase> iphase|<freq> freq} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+119 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <add> add|<mul> mul|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+143 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+165 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+164 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+120 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+134 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+87 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase|<freq> freq} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+
+36:__UG_NAME__ -> 65:b ;
+67:__UG_NAME__ -> 68:b ;
+79:__UG_NAME__ -> 80:b ;
+84:__UG_NAME__ -> 85:a ;
+87:__UG_NAME__ -> 88:b ;
+89:__UG_NAME__ -> 90:b ;
+88:__UG_NAME__ -> 92:a ;
+91:__UG_NAME__ -> 92:b ;
+115:__UG_NAME__ -> 116:a ;
+135:__UG_NAME__ -> 136:a ;
+139:__UG_NAME__ -> 140:b ;
+140:__UG_NAME__ -> 144:a ;
+143:__UG_NAME__ -> 144:b ;
+44:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+48:__UG_NAME__ -> 52:a ;
+51:__UG_NAME__ -> 52:b ;
+54:__UG_NAME__ -> 58:a ;
+57:__UG_NAME__ -> 58:b ;
+58:__UG_NAME__ -> 62:a ;
+61:__UG_NAME__ -> 62:b ;
+65:__UG_NAME__ -> 66:a ;
+69:__UG_NAME__ -> 73:a ;
+72:__UG_NAME__ -> 73:b ;
+73:__UG_NAME__ -> 77:a ;
+76:__UG_NAME__ -> 77:b ;
+65:__UG_NAME__ -> 82:a ;
+36:__UG_NAME__ -> 84:a ;
+93:__UG_NAME__ -> 97:a ;
+96:__UG_NAME__ -> 97:b ;
+97:__UG_NAME__ -> 101:a ;
+100:__UG_NAME__ -> 101:b ;
+103:__UG_NAME__ -> 107:a ;
+106:__UG_NAME__ -> 107:b ;
+107:__UG_NAME__ -> 111:a ;
+110:__UG_NAME__ -> 111:b ;
+102:__UG_NAME__ -> 113:a ;
+112:__UG_NAME__ -> 113:b ;
+121:__UG_NAME__ -> 125:a ;
+124:__UG_NAME__ -> 125:b ;
+125:__UG_NAME__ -> 129:a ;
+128:__UG_NAME__ -> 129:b ;
+118:__UG_NAME__ -> 132:a ;
+131:__UG_NAME__ -> 132:b ;
+120:__UG_NAME__ -> 135:a ;
+134:__UG_NAME__ -> 135:b ;
+145:__UG_NAME__ -> 149:a ;
+148:__UG_NAME__ -> 149:b ;
+149:__UG_NAME__ -> 153:a ;
+152:__UG_NAME__ -> 153:b ;
+155:__UG_NAME__ -> 158:a ;
+157:__UG_NAME__ -> 158:b ;
+158:__UG_NAME__ -> 162:a ;
+161:__UG_NAME__ -> 162:b ;
+80:__UG_NAME__ -> 81:a ;
+90:__UG_NAME__ -> 91:a ;
+113:__UG_NAME__ -> 114:a ;
+112:__UG_NAME__ -> 114:b ;
+112:__UG_NAME__ -> 117:a ;
+116:__UG_NAME__ -> 117:b ;
+63:__UG_NAME__ -> 64:b ;
+114:__UG_NAME__ -> 115:a ;
+17:__UG_NAME__ -> 137:b ;
+46:__UG_NAME__ -> 47:a ;
+50:__UG_NAME__ -> 51:a ;
+56:__UG_NAME__ -> 57:a ;
+60:__UG_NAME__ -> 61:a ;
+71:__UG_NAME__ -> 72:a ;
+75:__UG_NAME__ -> 76:a ;
+38:__UG_NAME__ -> 89:a ;
+95:__UG_NAME__ -> 96:a ;
+99:__UG_NAME__ -> 100:a ;
+105:__UG_NAME__ -> 106:a ;
+109:__UG_NAME__ -> 110:a ;
+123:__UG_NAME__ -> 124:a ;
+127:__UG_NAME__ -> 128:a ;
+147:__UG_NAME__ -> 148:a ;
+151:__UG_NAME__ -> 152:a ;
+156:__UG_NAME__ -> 157:a ;
+160:__UG_NAME__ -> 161:a ;
+45:__UG_NAME__ -> 46:a ;
+49:__UG_NAME__ -> 50:a ;
+55:__UG_NAME__ -> 56:a ;
+59:__UG_NAME__ -> 60:a ;
+70:__UG_NAME__ -> 71:a ;
+74:__UG_NAME__ -> 75:a ;
+94:__UG_NAME__ -> 95:a ;
+98:__UG_NAME__ -> 99:a ;
+104:__UG_NAME__ -> 105:a ;
+108:__UG_NAME__ -> 109:a ;
+122:__UG_NAME__ -> 123:a ;
+126:__UG_NAME__ -> 127:a ;
+146:__UG_NAME__ -> 147:a ;
+150:__UG_NAME__ -> 151:a ;
+130:__UG_NAME__ -> 156:a ;
+159:__UG_NAME__ -> 160:a ;
+20:__UG_NAME__ -> 53:envelope___control___0 ;
+20:__UG_NAME__ -> 53:envelope___control___4 ;
+21:__UG_NAME__ -> 53:envelope___control___5 ;
+22:__UG_NAME__ -> 53:envelope___control___6 ;
+23:__UG_NAME__ -> 53:envelope___control___7 ;
+52:__UG_NAME__ -> 53:gate ;
+24:__UG_NAME__ -> 63:envelope___control___0 ;
+24:__UG_NAME__ -> 63:envelope___control___4 ;
+25:__UG_NAME__ -> 63:envelope___control___5 ;
+26:__UG_NAME__ -> 63:envelope___control___6 ;
+27:__UG_NAME__ -> 63:envelope___control___7 ;
+62:__UG_NAME__ -> 63:gate ;
+32:__UG_NAME__ -> 78:envelope___control___0 ;
+32:__UG_NAME__ -> 78:envelope___control___4 ;
+33:__UG_NAME__ -> 78:envelope___control___5 ;
+34:__UG_NAME__ -> 78:envelope___control___6 ;
+35:__UG_NAME__ -> 78:envelope___control___7 ;
+77:__UG_NAME__ -> 78:gate ;
+28:__UG_NAME__ -> 102:envelope___control___0 ;
+28:__UG_NAME__ -> 102:envelope___control___4 ;
+29:__UG_NAME__ -> 102:envelope___control___5 ;
+101:__UG_NAME__ -> 102:gate ;
+0:__UG_NAME__ -> 112:envelope___control___0 ;
+0:__UG_NAME__ -> 112:envelope___control___4 ;
+1:__UG_NAME__ -> 112:envelope___control___5 ;
+2:__UG_NAME__ -> 112:envelope___control___6 ;
+3:__UG_NAME__ -> 112:envelope___control___7 ;
+111:__UG_NAME__ -> 112:gate ;
+39:__UG_NAME__ -> 131:envelope___control___0 ;
+39:__UG_NAME__ -> 131:envelope___control___4 ;
+40:__UG_NAME__ -> 131:envelope___control___5 ;
+41:__UG_NAME__ -> 131:envelope___control___6 ;
+42:__UG_NAME__ -> 131:envelope___control___7 ;
+129:__UG_NAME__ -> 131:gate ;
+16:__UG_NAME__ -> 139:envelope___control___4 ;
+12:__UG_NAME__ -> 139:envelope___control___5 ;
+19:__UG_NAME__ -> 139:envelope___control___6 ;
+138:__UG_NAME__ -> 139:envelope___select___8 ;
+13:__UG_NAME__ -> 139:envelope___control___9 ;
+19:__UG_NAME__ -> 139:envelope___control___10 ;
+18:__UG_NAME__ -> 139:envelope___control___12 ;
+14:__UG_NAME__ -> 139:envelope___control___13 ;
+19:__UG_NAME__ -> 139:envelope___control___14 ;
+15:__UG_NAME__ -> 139:envelope___control___17 ;
+19:__UG_NAME__ -> 139:envelope___control___18 ;
+8:__UG_NAME__ -> 154:envelope___control___0 ;
+8:__UG_NAME__ -> 154:envelope___control___4 ;
+9:__UG_NAME__ -> 154:envelope___control___5 ;
+10:__UG_NAME__ -> 154:envelope___control___6 ;
+11:__UG_NAME__ -> 154:envelope___control___7 ;
+153:__UG_NAME__ -> 154:gate ;
+4:__UG_NAME__ -> 163:envelope___control___0 ;
+4:__UG_NAME__ -> 163:envelope___control___4 ;
+5:__UG_NAME__ -> 163:envelope___control___5 ;
+6:__UG_NAME__ -> 163:envelope___control___6 ;
+7:__UG_NAME__ -> 163:envelope___control___7 ;
+162:__UG_NAME__ -> 163:gate ;
+20:__UG_NAME__ -> 45:in ;
+21:__UG_NAME__ -> 49:in ;
+24:__UG_NAME__ -> 55:in ;
+25:__UG_NAME__ -> 59:in ;
+32:__UG_NAME__ -> 70:in ;
+33:__UG_NAME__ -> 74:in ;
+28:__UG_NAME__ -> 94:in ;
+29:__UG_NAME__ -> 98:in ;
+0:__UG_NAME__ -> 104:in ;
+1:__UG_NAME__ -> 108:in ;
+39:__UG_NAME__ -> 122:in ;
+40:__UG_NAME__ -> 126:in ;
+4:__UG_NAME__ -> 130:in ;
+8:__UG_NAME__ -> 146:in ;
+9:__UG_NAME__ -> 150:in ;
+5:__UG_NAME__ -> 159:in ;
+64:__UG_NAME__ -> 79:freq ;
+36:__UG_NAME__ -> 79:iphase ;
+78:__UG_NAME__ -> 79:width ;
+64:__UG_NAME__ -> 67:freq ;
+66:__UG_NAME__ -> 67:iphase ;
+64:__UG_NAME__ -> 83:freq ;
+82:__UG_NAME__ -> 83:iphase ;
+136:__UG_NAME__ -> 142:in ;
+141:__UG_NAME__ -> 142:freq ;
+118:__UG_NAME__ -> 119:a ;
+132:__UG_NAME__ -> 133:a ;
+53:__UG_NAME__ -> 141:a ;
+92:__UG_NAME__ -> 118:in ;
+115:__UG_NAME__ -> 118:mul ;
+117:__UG_NAME__ -> 118:add ;
+142:__UG_NAME__ -> 143:in ;
+43:__UG_NAME__ -> 165:bus ;
+164:__UG_NAME__ -> 165:signals___pan2___0 ;
+164:__UG_NAME__ -> 165:signals___pan2___1 ;
+144:__UG_NAME__ -> 164:in ;
+154:__UG_NAME__ -> 164:pos ;
+163:__UG_NAME__ -> 164:level ;
+119:__UG_NAME__ -> 120:freq ;
+133:__UG_NAME__ -> 134:freq ;
+37:__UG_NAME__ -> 87:which ;
+68:__UG_NAME__ -> 87:array___binary____op____u____gen___0 ;
+81:__UG_NAME__ -> 87:array___binary____op____u____gen___1 ;
+83:__UG_NAME__ -> 87:array___lf____tri___2 ;
+86:__UG_NAME__ -> 87:array___sin____osc___3 ;
+137:__UG_NAME__ -> 138:which ;
+17:__UG_NAME__ -> 138:array___control___0 ;
+18:__UG_NAME__ -> 138:array___control___1 ;
+64:__UG_NAME__ -> 86:freq ;
+85:__UG_NAME__ -> 86:phase ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-mod_fm.dot b/etc/synthdefs/graphviz/dot/sonic-pi-mod_fm.dot
new file mode 100644
index 0000000..ee2132a
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-mod_fm.dot
@@ -0,0 +1,504 @@
+digraph synthdef {
+99 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <b> 6.2831855|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <b> -1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+143 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+146 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+161 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+165 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+140 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+147 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+153 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+157 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+168 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+169 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+175 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+176 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <b> |<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+152 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+156 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+164 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+167 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+174 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+134 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+151 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+155 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+163 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+173 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :mod_phase
+ default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :mod_phase_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :mod_phase_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :mod_phase_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :mod_range
+ default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :mod_range_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :mod_range_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :mod_range_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :mod_pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :mod_pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :mod_pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :mod_pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :mod_phase_offset
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "control
+ :mod_wave
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "control
+ :mod_invert_wave
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "control
+ :divisor
+ default: 2.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+40 [label = "control
+ :divisor_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+41 [label = "control
+ :divisor_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+42 [label = "control
+ :divisor_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "control
+ :depth
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+44 [label = "control
+ :depth_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+45 [label = "control
+ :depth_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+46 [label = "control
+ :depth_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+47 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+58 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+158 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+170 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+177 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+150 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+154 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+162 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+172 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+149 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+166 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+171 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <width> width|<iphase> iphase|<freq> freq} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
+160 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+131 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+159 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <add> add|<mul> mul|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+179 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+178 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+91 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase|<freq> freq} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+145 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+148 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+36:__UG_NAME__ -> 99:b ;
+101:__UG_NAME__ -> 102:b ;
+113:__UG_NAME__ -> 114:b ;
+118:__UG_NAME__ -> 119:a ;
+121:__UG_NAME__ -> 122:b ;
+123:__UG_NAME__ -> 124:b ;
+122:__UG_NAME__ -> 126:a ;
+125:__UG_NAME__ -> 126:b ;
+127:__UG_NAME__ -> 128:a ;
+131:__UG_NAME__ -> 142:a ;
+141:__UG_NAME__ -> 142:b ;
+92:__UG_NAME__ -> 143:a ;
+142:__UG_NAME__ -> 143:b ;
+143:__UG_NAME__ -> 146:a ;
+145:__UG_NAME__ -> 146:b ;
+92:__UG_NAME__ -> 161:a ;
+160:__UG_NAME__ -> 161:b ;
+161:__UG_NAME__ -> 165:b ;
+49:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+53:__UG_NAME__ -> 57:a ;
+56:__UG_NAME__ -> 57:b ;
+59:__UG_NAME__ -> 63:a ;
+62:__UG_NAME__ -> 63:b ;
+64:__UG_NAME__ -> 68:a ;
+67:__UG_NAME__ -> 68:b ;
+68:__UG_NAME__ -> 72:a ;
+71:__UG_NAME__ -> 72:b ;
+74:__UG_NAME__ -> 78:a ;
+77:__UG_NAME__ -> 78:b ;
+78:__UG_NAME__ -> 82:a ;
+81:__UG_NAME__ -> 82:b ;
+73:__UG_NAME__ -> 84:a ;
+83:__UG_NAME__ -> 84:b ;
+63:__UG_NAME__ -> 96:a ;
+95:__UG_NAME__ -> 96:b ;
+99:__UG_NAME__ -> 100:a ;
+103:__UG_NAME__ -> 107:a ;
+106:__UG_NAME__ -> 107:b ;
+107:__UG_NAME__ -> 111:a ;
+110:__UG_NAME__ -> 111:b ;
+99:__UG_NAME__ -> 116:a ;
+36:__UG_NAME__ -> 118:a ;
+132:__UG_NAME__ -> 136:a ;
+135:__UG_NAME__ -> 136:b ;
+136:__UG_NAME__ -> 140:a ;
+139:__UG_NAME__ -> 140:b ;
+131:__UG_NAME__ -> 147:a ;
+146:__UG_NAME__ -> 147:b ;
+149:__UG_NAME__ -> 153:a ;
+152:__UG_NAME__ -> 153:b ;
+153:__UG_NAME__ -> 157:a ;
+156:__UG_NAME__ -> 157:b ;
+166:__UG_NAME__ -> 168:a ;
+167:__UG_NAME__ -> 168:b ;
+168:__UG_NAME__ -> 169:a ;
+88:__UG_NAME__ -> 169:b ;
+171:__UG_NAME__ -> 175:a ;
+174:__UG_NAME__ -> 175:b ;
+175:__UG_NAME__ -> 176:a ;
+164:__UG_NAME__ -> 176:b ;
+84:__UG_NAME__ -> 85:a ;
+83:__UG_NAME__ -> 85:b ;
+114:__UG_NAME__ -> 115:a ;
+124:__UG_NAME__ -> 125:a ;
+83:__UG_NAME__ -> 129:a ;
+128:__UG_NAME__ -> 129:b ;
+97:__UG_NAME__ -> 98:b ;
+85:__UG_NAME__ -> 127:a ;
+131:__UG_NAME__ -> 144:a ;
+58:__UG_NAME__ -> 144:b ;
+17:__UG_NAME__ -> 48:b ;
+51:__UG_NAME__ -> 52:a ;
+55:__UG_NAME__ -> 56:a ;
+61:__UG_NAME__ -> 62:a ;
+66:__UG_NAME__ -> 67:a ;
+70:__UG_NAME__ -> 71:a ;
+76:__UG_NAME__ -> 77:a ;
+80:__UG_NAME__ -> 81:a ;
+87:__UG_NAME__ -> 88:a ;
+94:__UG_NAME__ -> 95:a ;
+105:__UG_NAME__ -> 106:a ;
+109:__UG_NAME__ -> 110:a ;
+38:__UG_NAME__ -> 123:a ;
+134:__UG_NAME__ -> 135:a ;
+138:__UG_NAME__ -> 139:a ;
+151:__UG_NAME__ -> 152:a ;
+155:__UG_NAME__ -> 156:a ;
+163:__UG_NAME__ -> 164:a ;
+90:__UG_NAME__ -> 167:a ;
+173:__UG_NAME__ -> 174:a ;
+50:__UG_NAME__ -> 51:a ;
+54:__UG_NAME__ -> 55:a ;
+60:__UG_NAME__ -> 61:a ;
+65:__UG_NAME__ -> 66:a ;
+69:__UG_NAME__ -> 70:a ;
+75:__UG_NAME__ -> 76:a ;
+79:__UG_NAME__ -> 80:a ;
+86:__UG_NAME__ -> 87:a ;
+89:__UG_NAME__ -> 90:a ;
+93:__UG_NAME__ -> 94:a ;
+104:__UG_NAME__ -> 105:a ;
+108:__UG_NAME__ -> 109:a ;
+133:__UG_NAME__ -> 134:a ;
+137:__UG_NAME__ -> 138:a ;
+150:__UG_NAME__ -> 151:a ;
+154:__UG_NAME__ -> 155:a ;
+162:__UG_NAME__ -> 163:a ;
+172:__UG_NAME__ -> 173:a ;
+39:__UG_NAME__ -> 58:envelope___control___0 ;
+39:__UG_NAME__ -> 58:envelope___control___4 ;
+40:__UG_NAME__ -> 58:envelope___control___5 ;
+41:__UG_NAME__ -> 58:envelope___control___6 ;
+42:__UG_NAME__ -> 58:envelope___control___7 ;
+57:__UG_NAME__ -> 58:gate ;
+28:__UG_NAME__ -> 73:envelope___control___0 ;
+28:__UG_NAME__ -> 73:envelope___control___4 ;
+29:__UG_NAME__ -> 73:envelope___control___5 ;
+30:__UG_NAME__ -> 73:envelope___control___6 ;
+31:__UG_NAME__ -> 73:envelope___control___7 ;
+72:__UG_NAME__ -> 73:gate ;
+0:__UG_NAME__ -> 83:envelope___control___0 ;
+0:__UG_NAME__ -> 83:envelope___control___4 ;
+1:__UG_NAME__ -> 83:envelope___control___5 ;
+2:__UG_NAME__ -> 83:envelope___control___6 ;
+3:__UG_NAME__ -> 83:envelope___control___7 ;
+82:__UG_NAME__ -> 83:gate ;
+16:__UG_NAME__ -> 92:envelope___control___4 ;
+12:__UG_NAME__ -> 92:envelope___control___5 ;
+19:__UG_NAME__ -> 92:envelope___control___6 ;
+91:__UG_NAME__ -> 92:envelope___select___8 ;
+13:__UG_NAME__ -> 92:envelope___control___9 ;
+19:__UG_NAME__ -> 92:envelope___control___10 ;
+18:__UG_NAME__ -> 92:envelope___control___12 ;
+14:__UG_NAME__ -> 92:envelope___control___13 ;
+19:__UG_NAME__ -> 92:envelope___control___14 ;
+15:__UG_NAME__ -> 92:envelope___control___17 ;
+19:__UG_NAME__ -> 92:envelope___control___18 ;
+24:__UG_NAME__ -> 97:envelope___control___0 ;
+24:__UG_NAME__ -> 97:envelope___control___4 ;
+25:__UG_NAME__ -> 97:envelope___control___5 ;
+26:__UG_NAME__ -> 97:envelope___control___6 ;
+27:__UG_NAME__ -> 97:envelope___control___7 ;
+96:__UG_NAME__ -> 97:gate ;
+32:__UG_NAME__ -> 112:envelope___control___0 ;
+32:__UG_NAME__ -> 112:envelope___control___4 ;
+33:__UG_NAME__ -> 112:envelope___control___5 ;
+34:__UG_NAME__ -> 112:envelope___control___6 ;
+35:__UG_NAME__ -> 112:envelope___control___7 ;
+111:__UG_NAME__ -> 112:gate ;
+43:__UG_NAME__ -> 141:envelope___control___0 ;
+43:__UG_NAME__ -> 141:envelope___control___4 ;
+44:__UG_NAME__ -> 141:envelope___control___5 ;
+45:__UG_NAME__ -> 141:envelope___control___6 ;
+46:__UG_NAME__ -> 141:envelope___control___7 ;
+140:__UG_NAME__ -> 141:gate ;
+20:__UG_NAME__ -> 158:envelope___control___0 ;
+20:__UG_NAME__ -> 158:envelope___control___4 ;
+21:__UG_NAME__ -> 158:envelope___control___5 ;
+22:__UG_NAME__ -> 158:envelope___control___6 ;
+23:__UG_NAME__ -> 158:envelope___control___7 ;
+157:__UG_NAME__ -> 158:gate ;
+8:__UG_NAME__ -> 170:envelope___control___0 ;
+8:__UG_NAME__ -> 170:envelope___control___4 ;
+9:__UG_NAME__ -> 170:envelope___control___5 ;
+10:__UG_NAME__ -> 170:envelope___control___6 ;
+11:__UG_NAME__ -> 170:envelope___control___7 ;
+169:__UG_NAME__ -> 170:gate ;
+4:__UG_NAME__ -> 177:envelope___control___0 ;
+4:__UG_NAME__ -> 177:envelope___control___4 ;
+5:__UG_NAME__ -> 177:envelope___control___5 ;
+6:__UG_NAME__ -> 177:envelope___control___6 ;
+7:__UG_NAME__ -> 177:envelope___control___7 ;
+176:__UG_NAME__ -> 177:gate ;
+39:__UG_NAME__ -> 50:in ;
+40:__UG_NAME__ -> 54:in ;
+24:__UG_NAME__ -> 60:in ;
+28:__UG_NAME__ -> 65:in ;
+29:__UG_NAME__ -> 69:in ;
+0:__UG_NAME__ -> 75:in ;
+1:__UG_NAME__ -> 79:in ;
+9:__UG_NAME__ -> 86:in ;
+8:__UG_NAME__ -> 89:in ;
+25:__UG_NAME__ -> 93:in ;
+32:__UG_NAME__ -> 104:in ;
+33:__UG_NAME__ -> 108:in ;
+43:__UG_NAME__ -> 133:in ;
+44:__UG_NAME__ -> 137:in ;
+20:__UG_NAME__ -> 150:in ;
+21:__UG_NAME__ -> 154:in ;
+5:__UG_NAME__ -> 162:in ;
+4:__UG_NAME__ -> 172:in ;
+98:__UG_NAME__ -> 113:freq ;
+36:__UG_NAME__ -> 113:iphase ;
+112:__UG_NAME__ -> 113:width ;
+98:__UG_NAME__ -> 101:freq ;
+100:__UG_NAME__ -> 101:iphase ;
+98:__UG_NAME__ -> 117:freq ;
+116:__UG_NAME__ -> 117:iphase ;
+148:__UG_NAME__ -> 160:in ;
+159:__UG_NAME__ -> 160:freq ;
+130:__UG_NAME__ -> 131:a ;
+158:__UG_NAME__ -> 159:a ;
+126:__UG_NAME__ -> 130:in ;
+127:__UG_NAME__ -> 130:mul ;
+129:__UG_NAME__ -> 130:add ;
+47:__UG_NAME__ -> 179:bus ;
+178:__UG_NAME__ -> 179:signals___pan2___0 ;
+178:__UG_NAME__ -> 179:signals___pan2___1 ;
+165:__UG_NAME__ -> 178:in ;
+170:__UG_NAME__ -> 178:pos ;
+177:__UG_NAME__ -> 178:level ;
+48:__UG_NAME__ -> 91:which ;
+17:__UG_NAME__ -> 91:array___control___0 ;
+18:__UG_NAME__ -> 91:array___control___1 ;
+37:__UG_NAME__ -> 121:which ;
+102:__UG_NAME__ -> 121:array___binary____op____u____gen___0 ;
+115:__UG_NAME__ -> 121:array___binary____op____u____gen___1 ;
+117:__UG_NAME__ -> 121:array___lf____tri___2 ;
+120:__UG_NAME__ -> 121:array___sin____osc___3 ;
+98:__UG_NAME__ -> 120:freq ;
+119:__UG_NAME__ -> 120:phase ;
+144:__UG_NAME__ -> 145:freq ;
+147:__UG_NAME__ -> 148:freq ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-mod_pulse.dot b/etc/synthdefs/graphviz/dot/sonic-pi-mod_pulse.dot
new file mode 100644
index 0000000..6386f6d
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-mod_pulse.dot
@@ -0,0 +1,452 @@
+digraph synthdef {
+70 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> 6.2831855|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <b> -1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <b> |<a> 0.8} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+143 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+134 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+154 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+155 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+157 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+146 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+151 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+153 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+145 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+148 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+150 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :mod_phase
+ default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :mod_phase_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :mod_phase_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :mod_phase_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :mod_range
+ default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :mod_range_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :mod_range_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :mod_range_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :mod_pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :mod_pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :mod_pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :mod_pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :mod_phase_offset
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "control
+ :mod_wave
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "control
+ :mod_invert_wave
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "control
+ :pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+40 [label = "control
+ :pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+41 [label = "control
+ :pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+42 [label = "control
+ :pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+57 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+140 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+156 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+158 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+147 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+149 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+152 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <width> width|<iphase> iphase|<freq> freq} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+116 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <add> add|<mul> mul|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+160 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+159 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+125 [label = "{{ <width> width|<freq> freq} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+90 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase|<freq> freq} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+
+69:__UG_NAME__ -> 70:b ;
+36:__UG_NAME__ -> 73:b ;
+81:__UG_NAME__ -> 82:b ;
+85:__UG_NAME__ -> 86:b ;
+87:__UG_NAME__ -> 88:a ;
+90:__UG_NAME__ -> 91:b ;
+91:__UG_NAME__ -> 92:a ;
+83:__UG_NAME__ -> 92:b ;
+112:__UG_NAME__ -> 113:a ;
+140:__UG_NAME__ -> 141:b ;
+141:__UG_NAME__ -> 143:a ;
+142:__UG_NAME__ -> 143:b ;
+44:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+48:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+59:__UG_NAME__ -> 63:a ;
+62:__UG_NAME__ -> 63:b ;
+63:__UG_NAME__ -> 67:a ;
+66:__UG_NAME__ -> 67:b ;
+73:__UG_NAME__ -> 74:a ;
+76:__UG_NAME__ -> 80:a ;
+79:__UG_NAME__ -> 80:b ;
+73:__UG_NAME__ -> 84:a ;
+36:__UG_NAME__ -> 87:a ;
+93:__UG_NAME__ -> 97:a ;
+96:__UG_NAME__ -> 97:b ;
+97:__UG_NAME__ -> 100:a ;
+99:__UG_NAME__ -> 100:b ;
+102:__UG_NAME__ -> 106:a ;
+105:__UG_NAME__ -> 106:b ;
+106:__UG_NAME__ -> 108:a ;
+107:__UG_NAME__ -> 108:b ;
+101:__UG_NAME__ -> 110:a ;
+109:__UG_NAME__ -> 110:b ;
+117:__UG_NAME__ -> 121:a ;
+120:__UG_NAME__ -> 121:b ;
+121:__UG_NAME__ -> 123:a ;
+122:__UG_NAME__ -> 123:b ;
+126:__UG_NAME__ -> 130:a ;
+129:__UG_NAME__ -> 130:b ;
+130:__UG_NAME__ -> 134:a ;
+133:__UG_NAME__ -> 134:b ;
+152:__UG_NAME__ -> 154:a ;
+153:__UG_NAME__ -> 154:b ;
+80:__UG_NAME__ -> 155:a ;
+146:__UG_NAME__ -> 155:b ;
+154:__UG_NAME__ -> 157:a ;
+151:__UG_NAME__ -> 157:b ;
+70:__UG_NAME__ -> 71:a ;
+82:__UG_NAME__ -> 83:a ;
+110:__UG_NAME__ -> 111:a ;
+109:__UG_NAME__ -> 111:b ;
+109:__UG_NAME__ -> 114:a ;
+113:__UG_NAME__ -> 114:b ;
+57:__UG_NAME__ -> 58:b ;
+111:__UG_NAME__ -> 112:a ;
+17:__UG_NAME__ -> 138:b ;
+46:__UG_NAME__ -> 47:a ;
+54:__UG_NAME__ -> 55:a ;
+61:__UG_NAME__ -> 62:a ;
+65:__UG_NAME__ -> 66:a ;
+78:__UG_NAME__ -> 79:a ;
+38:__UG_NAME__ -> 81:a ;
+95:__UG_NAME__ -> 96:a ;
+98:__UG_NAME__ -> 99:a ;
+104:__UG_NAME__ -> 105:a ;
+50:__UG_NAME__ -> 107:a ;
+119:__UG_NAME__ -> 120:a ;
+52:__UG_NAME__ -> 122:a ;
+128:__UG_NAME__ -> 129:a ;
+132:__UG_NAME__ -> 133:a ;
+145:__UG_NAME__ -> 146:a ;
+150:__UG_NAME__ -> 151:a ;
+148:__UG_NAME__ -> 153:a ;
+45:__UG_NAME__ -> 46:a ;
+49:__UG_NAME__ -> 50:a ;
+51:__UG_NAME__ -> 52:a ;
+53:__UG_NAME__ -> 54:a ;
+60:__UG_NAME__ -> 61:a ;
+64:__UG_NAME__ -> 65:a ;
+77:__UG_NAME__ -> 78:a ;
+94:__UG_NAME__ -> 95:a ;
+72:__UG_NAME__ -> 98:a ;
+103:__UG_NAME__ -> 104:a ;
+118:__UG_NAME__ -> 119:a ;
+127:__UG_NAME__ -> 128:a ;
+131:__UG_NAME__ -> 132:a ;
+144:__UG_NAME__ -> 145:a ;
+147:__UG_NAME__ -> 148:a ;
+149:__UG_NAME__ -> 150:a ;
+24:__UG_NAME__ -> 57:envelope___control___0 ;
+24:__UG_NAME__ -> 57:envelope___control___4 ;
+25:__UG_NAME__ -> 57:envelope___control___5 ;
+26:__UG_NAME__ -> 57:envelope___control___6 ;
+27:__UG_NAME__ -> 57:envelope___control___7 ;
+56:__UG_NAME__ -> 57:gate ;
+32:__UG_NAME__ -> 68:envelope___control___0 ;
+32:__UG_NAME__ -> 68:envelope___control___4 ;
+33:__UG_NAME__ -> 68:envelope___control___5 ;
+34:__UG_NAME__ -> 68:envelope___control___6 ;
+35:__UG_NAME__ -> 68:envelope___control___7 ;
+67:__UG_NAME__ -> 68:gate ;
+28:__UG_NAME__ -> 101:envelope___control___0 ;
+28:__UG_NAME__ -> 101:envelope___control___4 ;
+29:__UG_NAME__ -> 101:envelope___control___5 ;
+30:__UG_NAME__ -> 101:envelope___control___6 ;
+31:__UG_NAME__ -> 101:envelope___control___7 ;
+100:__UG_NAME__ -> 101:gate ;
+0:__UG_NAME__ -> 109:envelope___control___0 ;
+0:__UG_NAME__ -> 109:envelope___control___4 ;
+1:__UG_NAME__ -> 109:envelope___control___5 ;
+2:__UG_NAME__ -> 109:envelope___control___6 ;
+3:__UG_NAME__ -> 109:envelope___control___7 ;
+108:__UG_NAME__ -> 109:gate ;
+39:__UG_NAME__ -> 124:envelope___control___0 ;
+39:__UG_NAME__ -> 124:envelope___control___4 ;
+40:__UG_NAME__ -> 124:envelope___control___5 ;
+41:__UG_NAME__ -> 124:envelope___control___6 ;
+42:__UG_NAME__ -> 124:envelope___control___7 ;
+123:__UG_NAME__ -> 124:gate ;
+20:__UG_NAME__ -> 135:envelope___control___0 ;
+20:__UG_NAME__ -> 135:envelope___control___4 ;
+21:__UG_NAME__ -> 135:envelope___control___5 ;
+22:__UG_NAME__ -> 135:envelope___control___6 ;
+23:__UG_NAME__ -> 135:envelope___control___7 ;
+134:__UG_NAME__ -> 135:gate ;
+16:__UG_NAME__ -> 140:envelope___control___4 ;
+12:__UG_NAME__ -> 140:envelope___control___5 ;
+19:__UG_NAME__ -> 140:envelope___control___6 ;
+139:__UG_NAME__ -> 140:envelope___select___8 ;
+13:__UG_NAME__ -> 140:envelope___control___9 ;
+19:__UG_NAME__ -> 140:envelope___control___10 ;
+18:__UG_NAME__ -> 140:envelope___control___12 ;
+14:__UG_NAME__ -> 140:envelope___control___13 ;
+19:__UG_NAME__ -> 140:envelope___control___14 ;
+15:__UG_NAME__ -> 140:envelope___control___17 ;
+19:__UG_NAME__ -> 140:envelope___control___18 ;
+8:__UG_NAME__ -> 156:envelope___control___0 ;
+8:__UG_NAME__ -> 156:envelope___control___4 ;
+9:__UG_NAME__ -> 156:envelope___control___5 ;
+10:__UG_NAME__ -> 156:envelope___control___6 ;
+11:__UG_NAME__ -> 156:envelope___control___7 ;
+155:__UG_NAME__ -> 156:gate ;
+4:__UG_NAME__ -> 158:envelope___control___0 ;
+4:__UG_NAME__ -> 158:envelope___control___4 ;
+5:__UG_NAME__ -> 158:envelope___control___5 ;
+6:__UG_NAME__ -> 158:envelope___control___6 ;
+7:__UG_NAME__ -> 158:envelope___control___7 ;
+157:__UG_NAME__ -> 158:gate ;
+24:__UG_NAME__ -> 45:in ;
+1:__UG_NAME__ -> 49:in ;
+40:__UG_NAME__ -> 51:in ;
+25:__UG_NAME__ -> 53:in ;
+32:__UG_NAME__ -> 60:in ;
+33:__UG_NAME__ -> 64:in ;
+29:__UG_NAME__ -> 72:in ;
+8:__UG_NAME__ -> 77:in ;
+28:__UG_NAME__ -> 94:in ;
+0:__UG_NAME__ -> 103:in ;
+39:__UG_NAME__ -> 118:in ;
+20:__UG_NAME__ -> 127:in ;
+21:__UG_NAME__ -> 131:in ;
+9:__UG_NAME__ -> 144:in ;
+4:__UG_NAME__ -> 147:in ;
+5:__UG_NAME__ -> 149:in ;
+58:__UG_NAME__ -> 69:freq ;
+36:__UG_NAME__ -> 69:iphase ;
+68:__UG_NAME__ -> 69:width ;
+58:__UG_NAME__ -> 85:freq ;
+84:__UG_NAME__ -> 85:iphase ;
+58:__UG_NAME__ -> 75:freq ;
+74:__UG_NAME__ -> 75:iphase ;
+125:__UG_NAME__ -> 137:in ;
+136:__UG_NAME__ -> 137:freq ;
+115:__UG_NAME__ -> 116:a ;
+135:__UG_NAME__ -> 136:a ;
+92:__UG_NAME__ -> 115:in ;
+112:__UG_NAME__ -> 115:mul ;
+114:__UG_NAME__ -> 115:add ;
+137:__UG_NAME__ -> 142:in ;
+43:__UG_NAME__ -> 160:bus ;
+159:__UG_NAME__ -> 160:signals___pan2___0 ;
+159:__UG_NAME__ -> 160:signals___pan2___1 ;
+143:__UG_NAME__ -> 159:in ;
+156:__UG_NAME__ -> 159:pos ;
+158:__UG_NAME__ -> 159:level ;
+116:__UG_NAME__ -> 125:freq ;
+124:__UG_NAME__ -> 125:width ;
+37:__UG_NAME__ -> 90:which ;
+86:__UG_NAME__ -> 90:array___binary____op____u____gen___0 ;
+71:__UG_NAME__ -> 90:array___binary____op____u____gen___1 ;
+75:__UG_NAME__ -> 90:array___lf____tri___2 ;
+89:__UG_NAME__ -> 90:array___sin____osc___3 ;
+138:__UG_NAME__ -> 139:which ;
+17:__UG_NAME__ -> 139:array___control___0 ;
+18:__UG_NAME__ -> 139:array___control___1 ;
+58:__UG_NAME__ -> 89:freq ;
+88:__UG_NAME__ -> 89:phase ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-mod_saw.dot b/etc/synthdefs/graphviz/dot/sonic-pi-mod_saw.dot
new file mode 100644
index 0000000..d76c57a
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-mod_saw.dot
@@ -0,0 +1,413 @@
+digraph synthdef {
+67 [label = "{{ <b> -1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> 0.8} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> 6.2831855|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+143 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+134 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :mod_phase
+ default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :mod_phase_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :mod_phase_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :mod_phase_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :mod_range
+ default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :mod_range_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :mod_range_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :mod_range_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :mod_pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :mod_pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :mod_pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :mod_pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :mod_phase_offset
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "control
+ :mod_wave
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "control
+ :mod_invert_wave
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+62 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+140 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <width> width|<iphase> iphase|<freq> freq} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+117 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ <add> add|<mul> mul|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+146 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+145 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+118 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+78 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase|<freq> freq} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+
+66:__UG_NAME__ -> 67:a ;
+79:__UG_NAME__ -> 80:b ;
+36:__UG_NAME__ -> 92:b ;
+94:__UG_NAME__ -> 95:b ;
+101:__UG_NAME__ -> 102:b ;
+106:__UG_NAME__ -> 107:a ;
+109:__UG_NAME__ -> 110:b ;
+111:__UG_NAME__ -> 112:b ;
+110:__UG_NAME__ -> 114:a ;
+113:__UG_NAME__ -> 114:b ;
+80:__UG_NAME__ -> 127:a ;
+126:__UG_NAME__ -> 127:b ;
+44:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+48:__UG_NAME__ -> 52:a ;
+51:__UG_NAME__ -> 52:b ;
+53:__UG_NAME__ -> 57:a ;
+56:__UG_NAME__ -> 57:b ;
+57:__UG_NAME__ -> 61:a ;
+60:__UG_NAME__ -> 61:b ;
+62:__UG_NAME__ -> 64:a ;
+63:__UG_NAME__ -> 64:b ;
+74:__UG_NAME__ -> 76:a ;
+75:__UG_NAME__ -> 76:b ;
+81:__UG_NAME__ -> 85:a ;
+84:__UG_NAME__ -> 85:b ;
+85:__UG_NAME__ -> 89:a ;
+88:__UG_NAME__ -> 89:b ;
+92:__UG_NAME__ -> 93:a ;
+96:__UG_NAME__ -> 97:a ;
+73:__UG_NAME__ -> 97:b ;
+97:__UG_NAME__ -> 99:a ;
+98:__UG_NAME__ -> 99:b ;
+92:__UG_NAME__ -> 104:a ;
+36:__UG_NAME__ -> 106:a ;
+76:__UG_NAME__ -> 122:a ;
+121:__UG_NAME__ -> 122:b ;
+128:__UG_NAME__ -> 131:a ;
+130:__UG_NAME__ -> 131:b ;
+131:__UG_NAME__ -> 135:a ;
+134:__UG_NAME__ -> 135:b ;
+137:__UG_NAME__ -> 139:a ;
+138:__UG_NAME__ -> 139:b ;
+139:__UG_NAME__ -> 143:a ;
+142:__UG_NAME__ -> 143:b ;
+64:__UG_NAME__ -> 65:a ;
+63:__UG_NAME__ -> 65:b ;
+102:__UG_NAME__ -> 103:a ;
+112:__UG_NAME__ -> 113:a ;
+63:__UG_NAME__ -> 115:a ;
+67:__UG_NAME__ -> 115:b ;
+65:__UG_NAME__ -> 66:a ;
+90:__UG_NAME__ -> 91:b ;
+17:__UG_NAME__ -> 77:b ;
+46:__UG_NAME__ -> 47:a ;
+50:__UG_NAME__ -> 51:a ;
+55:__UG_NAME__ -> 56:a ;
+59:__UG_NAME__ -> 60:a ;
+72:__UG_NAME__ -> 73:a ;
+69:__UG_NAME__ -> 75:a ;
+83:__UG_NAME__ -> 84:a ;
+87:__UG_NAME__ -> 88:a ;
+41:__UG_NAME__ -> 98:a ;
+38:__UG_NAME__ -> 111:a ;
+120:__UG_NAME__ -> 121:a ;
+129:__UG_NAME__ -> 130:a ;
+133:__UG_NAME__ -> 134:a ;
+43:__UG_NAME__ -> 138:a ;
+141:__UG_NAME__ -> 142:a ;
+40:__UG_NAME__ -> 41:a ;
+42:__UG_NAME__ -> 43:a ;
+45:__UG_NAME__ -> 46:a ;
+49:__UG_NAME__ -> 50:a ;
+54:__UG_NAME__ -> 55:a ;
+58:__UG_NAME__ -> 59:a ;
+68:__UG_NAME__ -> 69:a ;
+71:__UG_NAME__ -> 72:a ;
+82:__UG_NAME__ -> 83:a ;
+86:__UG_NAME__ -> 87:a ;
+119:__UG_NAME__ -> 120:a ;
+70:__UG_NAME__ -> 129:a ;
+132:__UG_NAME__ -> 133:a ;
+140:__UG_NAME__ -> 141:a ;
+28:__UG_NAME__ -> 62:envelope___control___0 ;
+28:__UG_NAME__ -> 62:envelope___control___4 ;
+29:__UG_NAME__ -> 62:envelope___control___5 ;
+30:__UG_NAME__ -> 62:envelope___control___6 ;
+31:__UG_NAME__ -> 62:envelope___control___7 ;
+61:__UG_NAME__ -> 62:gate ;
+0:__UG_NAME__ -> 63:envelope___control___0 ;
+0:__UG_NAME__ -> 63:envelope___control___4 ;
+1:__UG_NAME__ -> 63:envelope___control___5 ;
+2:__UG_NAME__ -> 63:envelope___control___6 ;
+3:__UG_NAME__ -> 63:envelope___control___7 ;
+52:__UG_NAME__ -> 63:gate ;
+16:__UG_NAME__ -> 79:envelope___control___4 ;
+12:__UG_NAME__ -> 79:envelope___control___5 ;
+19:__UG_NAME__ -> 79:envelope___control___6 ;
+78:__UG_NAME__ -> 79:envelope___select___8 ;
+13:__UG_NAME__ -> 79:envelope___control___9 ;
+19:__UG_NAME__ -> 79:envelope___control___10 ;
+18:__UG_NAME__ -> 79:envelope___control___12 ;
+14:__UG_NAME__ -> 79:envelope___control___13 ;
+19:__UG_NAME__ -> 79:envelope___control___14 ;
+15:__UG_NAME__ -> 79:envelope___control___17 ;
+19:__UG_NAME__ -> 79:envelope___control___18 ;
+24:__UG_NAME__ -> 90:envelope___control___0 ;
+24:__UG_NAME__ -> 90:envelope___control___4 ;
+25:__UG_NAME__ -> 90:envelope___control___5 ;
+26:__UG_NAME__ -> 90:envelope___control___6 ;
+27:__UG_NAME__ -> 90:envelope___control___7 ;
+89:__UG_NAME__ -> 90:gate ;
+32:__UG_NAME__ -> 100:envelope___control___0 ;
+32:__UG_NAME__ -> 100:envelope___control___4 ;
+33:__UG_NAME__ -> 100:envelope___control___5 ;
+34:__UG_NAME__ -> 100:envelope___control___6 ;
+35:__UG_NAME__ -> 100:envelope___control___7 ;
+99:__UG_NAME__ -> 100:gate ;
+20:__UG_NAME__ -> 123:envelope___control___0 ;
+20:__UG_NAME__ -> 123:envelope___control___4 ;
+21:__UG_NAME__ -> 123:envelope___control___5 ;
+22:__UG_NAME__ -> 123:envelope___control___6 ;
+23:__UG_NAME__ -> 123:envelope___control___7 ;
+122:__UG_NAME__ -> 123:gate ;
+8:__UG_NAME__ -> 136:envelope___control___0 ;
+8:__UG_NAME__ -> 136:envelope___control___4 ;
+9:__UG_NAME__ -> 136:envelope___control___5 ;
+10:__UG_NAME__ -> 136:envelope___control___6 ;
+11:__UG_NAME__ -> 136:envelope___control___7 ;
+135:__UG_NAME__ -> 136:gate ;
+4:__UG_NAME__ -> 144:envelope___control___0 ;
+4:__UG_NAME__ -> 144:envelope___control___4 ;
+5:__UG_NAME__ -> 144:envelope___control___5 ;
+6:__UG_NAME__ -> 144:envelope___control___6 ;
+7:__UG_NAME__ -> 144:envelope___control___7 ;
+143:__UG_NAME__ -> 144:gate ;
+33:__UG_NAME__ -> 40:in ;
+4:__UG_NAME__ -> 42:in ;
+0:__UG_NAME__ -> 45:in ;
+1:__UG_NAME__ -> 49:in ;
+28:__UG_NAME__ -> 54:in ;
+29:__UG_NAME__ -> 58:in ;
+20:__UG_NAME__ -> 68:in ;
+8:__UG_NAME__ -> 70:in ;
+32:__UG_NAME__ -> 71:in ;
+24:__UG_NAME__ -> 82:in ;
+25:__UG_NAME__ -> 86:in ;
+21:__UG_NAME__ -> 119:in ;
+9:__UG_NAME__ -> 132:in ;
+5:__UG_NAME__ -> 140:in ;
+91:__UG_NAME__ -> 101:freq ;
+36:__UG_NAME__ -> 101:iphase ;
+100:__UG_NAME__ -> 101:width ;
+91:__UG_NAME__ -> 94:freq ;
+93:__UG_NAME__ -> 94:iphase ;
+91:__UG_NAME__ -> 105:freq ;
+104:__UG_NAME__ -> 105:iphase ;
+118:__UG_NAME__ -> 125:in ;
+124:__UG_NAME__ -> 125:freq ;
+116:__UG_NAME__ -> 117:a ;
+123:__UG_NAME__ -> 124:a ;
+114:__UG_NAME__ -> 116:in ;
+66:__UG_NAME__ -> 116:mul ;
+115:__UG_NAME__ -> 116:add ;
+125:__UG_NAME__ -> 126:in ;
+39:__UG_NAME__ -> 146:bus ;
+145:__UG_NAME__ -> 146:signals___pan2___0 ;
+145:__UG_NAME__ -> 146:signals___pan2___1 ;
+127:__UG_NAME__ -> 145:in ;
+136:__UG_NAME__ -> 145:pos ;
+144:__UG_NAME__ -> 145:level ;
+117:__UG_NAME__ -> 118:freq ;
+77:__UG_NAME__ -> 78:which ;
+17:__UG_NAME__ -> 78:array___control___0 ;
+18:__UG_NAME__ -> 78:array___control___1 ;
+37:__UG_NAME__ -> 109:which ;
+95:__UG_NAME__ -> 109:array___binary____op____u____gen___0 ;
+103:__UG_NAME__ -> 109:array___binary____op____u____gen___1 ;
+105:__UG_NAME__ -> 109:array___lf____tri___2 ;
+108:__UG_NAME__ -> 109:array___sin____osc___3 ;
+91:__UG_NAME__ -> 108:freq ;
+107:__UG_NAME__ -> 108:phase ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-mod_sine.dot b/etc/synthdefs/graphviz/dot/sonic-pi-mod_sine.dot
new file mode 100644
index 0000000..81d7eac
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-mod_sine.dot
@@ -0,0 +1,413 @@
+digraph synthdef {
+51 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> 6.2831855|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> -1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+140 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+143 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+134 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :mod_phase
+ default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :mod_phase_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :mod_phase_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :mod_phase_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :mod_range
+ default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :mod_range_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :mod_range_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :mod_range_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :mod_pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :mod_pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :mod_pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :mod_pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :mod_phase_offset
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "control
+ :mod_wave
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "control
+ :mod_invert_wave
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+49 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <width> width|<iphase> iphase|<freq> freq} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+105 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <add> add|<mul> mul|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+146 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+145 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+73 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase|<freq> freq} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+36:__UG_NAME__ -> 51:b ;
+53:__UG_NAME__ -> 54:b ;
+65:__UG_NAME__ -> 66:b ;
+70:__UG_NAME__ -> 71:a ;
+73:__UG_NAME__ -> 74:b ;
+75:__UG_NAME__ -> 76:b ;
+74:__UG_NAME__ -> 78:a ;
+77:__UG_NAME__ -> 78:b ;
+101:__UG_NAME__ -> 102:a ;
+127:__UG_NAME__ -> 128:b ;
+128:__UG_NAME__ -> 142:a ;
+119:__UG_NAME__ -> 142:b ;
+40:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+44:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+51:__UG_NAME__ -> 52:a ;
+55:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+59:__UG_NAME__ -> 63:a ;
+62:__UG_NAME__ -> 63:b ;
+51:__UG_NAME__ -> 68:a ;
+36:__UG_NAME__ -> 70:a ;
+79:__UG_NAME__ -> 83:a ;
+82:__UG_NAME__ -> 83:b ;
+83:__UG_NAME__ -> 87:a ;
+86:__UG_NAME__ -> 87:b ;
+89:__UG_NAME__ -> 93:a ;
+92:__UG_NAME__ -> 93:b ;
+93:__UG_NAME__ -> 97:a ;
+96:__UG_NAME__ -> 97:b ;
+88:__UG_NAME__ -> 99:a ;
+98:__UG_NAME__ -> 99:b ;
+107:__UG_NAME__ -> 111:a ;
+110:__UG_NAME__ -> 111:b ;
+111:__UG_NAME__ -> 115:a ;
+114:__UG_NAME__ -> 115:b ;
+124:__UG_NAME__ -> 132:a ;
+131:__UG_NAME__ -> 132:b ;
+135:__UG_NAME__ -> 139:a ;
+138:__UG_NAME__ -> 139:b ;
+139:__UG_NAME__ -> 140:a ;
+123:__UG_NAME__ -> 140:b ;
+132:__UG_NAME__ -> 143:a ;
+134:__UG_NAME__ -> 143:b ;
+66:__UG_NAME__ -> 67:a ;
+76:__UG_NAME__ -> 77:a ;
+99:__UG_NAME__ -> 100:a ;
+98:__UG_NAME__ -> 100:b ;
+98:__UG_NAME__ -> 103:a ;
+102:__UG_NAME__ -> 103:b ;
+49:__UG_NAME__ -> 50:b ;
+100:__UG_NAME__ -> 101:a ;
+17:__UG_NAME__ -> 125:b ;
+42:__UG_NAME__ -> 43:a ;
+46:__UG_NAME__ -> 47:a ;
+57:__UG_NAME__ -> 58:a ;
+61:__UG_NAME__ -> 62:a ;
+38:__UG_NAME__ -> 75:a ;
+81:__UG_NAME__ -> 82:a ;
+85:__UG_NAME__ -> 86:a ;
+91:__UG_NAME__ -> 92:a ;
+95:__UG_NAME__ -> 96:a ;
+109:__UG_NAME__ -> 110:a ;
+113:__UG_NAME__ -> 114:a ;
+122:__UG_NAME__ -> 123:a ;
+130:__UG_NAME__ -> 131:a ;
+133:__UG_NAME__ -> 134:a ;
+137:__UG_NAME__ -> 138:a ;
+41:__UG_NAME__ -> 42:a ;
+45:__UG_NAME__ -> 46:a ;
+56:__UG_NAME__ -> 57:a ;
+60:__UG_NAME__ -> 61:a ;
+80:__UG_NAME__ -> 81:a ;
+84:__UG_NAME__ -> 85:a ;
+90:__UG_NAME__ -> 91:a ;
+94:__UG_NAME__ -> 95:a ;
+108:__UG_NAME__ -> 109:a ;
+112:__UG_NAME__ -> 113:a ;
+121:__UG_NAME__ -> 122:a ;
+129:__UG_NAME__ -> 130:a ;
+120:__UG_NAME__ -> 133:a ;
+136:__UG_NAME__ -> 137:a ;
+24:__UG_NAME__ -> 49:envelope___control___0 ;
+24:__UG_NAME__ -> 49:envelope___control___4 ;
+25:__UG_NAME__ -> 49:envelope___control___5 ;
+26:__UG_NAME__ -> 49:envelope___control___6 ;
+27:__UG_NAME__ -> 49:envelope___control___7 ;
+48:__UG_NAME__ -> 49:gate ;
+32:__UG_NAME__ -> 64:envelope___control___0 ;
+32:__UG_NAME__ -> 64:envelope___control___4 ;
+33:__UG_NAME__ -> 64:envelope___control___5 ;
+34:__UG_NAME__ -> 64:envelope___control___6 ;
+35:__UG_NAME__ -> 64:envelope___control___7 ;
+63:__UG_NAME__ -> 64:gate ;
+28:__UG_NAME__ -> 88:envelope___control___0 ;
+28:__UG_NAME__ -> 88:envelope___control___4 ;
+29:__UG_NAME__ -> 88:envelope___control___5 ;
+30:__UG_NAME__ -> 88:envelope___control___6 ;
+31:__UG_NAME__ -> 88:envelope___control___7 ;
+87:__UG_NAME__ -> 88:gate ;
+0:__UG_NAME__ -> 98:envelope___control___0 ;
+0:__UG_NAME__ -> 98:envelope___control___4 ;
+1:__UG_NAME__ -> 98:envelope___control___5 ;
+2:__UG_NAME__ -> 98:envelope___control___6 ;
+3:__UG_NAME__ -> 98:envelope___control___7 ;
+97:__UG_NAME__ -> 98:gate ;
+20:__UG_NAME__ -> 116:envelope___control___0 ;
+20:__UG_NAME__ -> 116:envelope___control___4 ;
+21:__UG_NAME__ -> 116:envelope___control___5 ;
+22:__UG_NAME__ -> 116:envelope___control___6 ;
+23:__UG_NAME__ -> 116:envelope___control___7 ;
+115:__UG_NAME__ -> 116:gate ;
+16:__UG_NAME__ -> 127:envelope___control___4 ;
+12:__UG_NAME__ -> 127:envelope___control___5 ;
+19:__UG_NAME__ -> 127:envelope___control___6 ;
+126:__UG_NAME__ -> 127:envelope___select___8 ;
+13:__UG_NAME__ -> 127:envelope___control___9 ;
+19:__UG_NAME__ -> 127:envelope___control___10 ;
+18:__UG_NAME__ -> 127:envelope___control___12 ;
+14:__UG_NAME__ -> 127:envelope___control___13 ;
+19:__UG_NAME__ -> 127:envelope___control___14 ;
+15:__UG_NAME__ -> 127:envelope___control___17 ;
+19:__UG_NAME__ -> 127:envelope___control___18 ;
+8:__UG_NAME__ -> 141:envelope___control___0 ;
+8:__UG_NAME__ -> 141:envelope___control___4 ;
+9:__UG_NAME__ -> 141:envelope___control___5 ;
+10:__UG_NAME__ -> 141:envelope___control___6 ;
+11:__UG_NAME__ -> 141:envelope___control___7 ;
+140:__UG_NAME__ -> 141:gate ;
+4:__UG_NAME__ -> 144:envelope___control___0 ;
+4:__UG_NAME__ -> 144:envelope___control___4 ;
+5:__UG_NAME__ -> 144:envelope___control___5 ;
+6:__UG_NAME__ -> 144:envelope___control___6 ;
+7:__UG_NAME__ -> 144:envelope___control___7 ;
+143:__UG_NAME__ -> 144:gate ;
+24:__UG_NAME__ -> 41:in ;
+25:__UG_NAME__ -> 45:in ;
+32:__UG_NAME__ -> 56:in ;
+33:__UG_NAME__ -> 60:in ;
+28:__UG_NAME__ -> 80:in ;
+29:__UG_NAME__ -> 84:in ;
+0:__UG_NAME__ -> 90:in ;
+1:__UG_NAME__ -> 94:in ;
+20:__UG_NAME__ -> 108:in ;
+21:__UG_NAME__ -> 112:in ;
+5:__UG_NAME__ -> 120:in ;
+9:__UG_NAME__ -> 121:in ;
+4:__UG_NAME__ -> 129:in ;
+8:__UG_NAME__ -> 136:in ;
+50:__UG_NAME__ -> 65:freq ;
+36:__UG_NAME__ -> 65:iphase ;
+64:__UG_NAME__ -> 65:width ;
+50:__UG_NAME__ -> 53:freq ;
+52:__UG_NAME__ -> 53:iphase ;
+50:__UG_NAME__ -> 69:freq ;
+68:__UG_NAME__ -> 69:iphase ;
+106:__UG_NAME__ -> 118:in ;
+117:__UG_NAME__ -> 118:freq ;
+104:__UG_NAME__ -> 105:a ;
+116:__UG_NAME__ -> 117:a ;
+78:__UG_NAME__ -> 104:in ;
+101:__UG_NAME__ -> 104:mul ;
+103:__UG_NAME__ -> 104:add ;
+118:__UG_NAME__ -> 119:in ;
+39:__UG_NAME__ -> 146:bus ;
+145:__UG_NAME__ -> 146:signals___pan2___0 ;
+145:__UG_NAME__ -> 146:signals___pan2___1 ;
+142:__UG_NAME__ -> 145:in ;
+141:__UG_NAME__ -> 145:pos ;
+144:__UG_NAME__ -> 145:level ;
+37:__UG_NAME__ -> 73:which ;
+54:__UG_NAME__ -> 73:array___binary____op____u____gen___0 ;
+67:__UG_NAME__ -> 73:array___binary____op____u____gen___1 ;
+69:__UG_NAME__ -> 73:array___lf____tri___2 ;
+72:__UG_NAME__ -> 73:array___sin____osc___3 ;
+125:__UG_NAME__ -> 126:which ;
+17:__UG_NAME__ -> 126:array___control___0 ;
+18:__UG_NAME__ -> 126:array___control___1 ;
+50:__UG_NAME__ -> 72:freq ;
+71:__UG_NAME__ -> 72:phase ;
+105:__UG_NAME__ -> 106:freq ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-mod_tri.dot b/etc/synthdefs/graphviz/dot/sonic-pi-mod_tri.dot
new file mode 100644
index 0000000..ae5f750
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-mod_tri.dot
@@ -0,0 +1,413 @@
+digraph synthdef {
+75 [label = "{{ <b> -1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> 1.5} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> 6.2831855|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+143 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :mod_phase
+ default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :mod_phase_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :mod_phase_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :mod_phase_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :mod_range
+ default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :mod_range_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :mod_range_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :mod_range_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :mod_pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :mod_pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :mod_pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :mod_pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :mod_phase_offset
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "control
+ :mod_wave
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "control
+ :mod_invert_wave
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+61 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+134 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+140 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <width> width|<iphase> iphase|<freq> freq} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ <iphase> iphase 0.0|<freq> freq} |<__UG_NAME__>lf-tri }" style="filled, bold, rounded"  shape=record rankdir=LR];
+128 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+115 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <add> add|<mul> mul|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+146 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+145 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+77 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase|<freq> freq} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+
+74:__UG_NAME__ -> 75:a ;
+78:__UG_NAME__ -> 79:b ;
+92:__UG_NAME__ -> 93:a ;
+36:__UG_NAME__ -> 96:b ;
+98:__UG_NAME__ -> 99:b ;
+101:__UG_NAME__ -> 102:b ;
+107:__UG_NAME__ -> 108:b ;
+109:__UG_NAME__ -> 110:b ;
+108:__UG_NAME__ -> 112:a ;
+111:__UG_NAME__ -> 112:b ;
+79:__UG_NAME__ -> 130:a ;
+129:__UG_NAME__ -> 130:b ;
+40:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+44:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+52:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+56:__UG_NAME__ -> 60:a ;
+59:__UG_NAME__ -> 60:b ;
+62:__UG_NAME__ -> 66:a ;
+65:__UG_NAME__ -> 66:b ;
+66:__UG_NAME__ -> 70:a ;
+69:__UG_NAME__ -> 70:b ;
+61:__UG_NAME__ -> 72:a ;
+71:__UG_NAME__ -> 72:b ;
+83:__UG_NAME__ -> 87:a ;
+86:__UG_NAME__ -> 87:b ;
+87:__UG_NAME__ -> 91:a ;
+90:__UG_NAME__ -> 91:b ;
+36:__UG_NAME__ -> 92:a ;
+96:__UG_NAME__ -> 97:a ;
+96:__UG_NAME__ -> 104:a ;
+117:__UG_NAME__ -> 121:a ;
+120:__UG_NAME__ -> 121:b ;
+121:__UG_NAME__ -> 125:a ;
+124:__UG_NAME__ -> 125:b ;
+131:__UG_NAME__ -> 132:a ;
+82:__UG_NAME__ -> 132:b ;
+132:__UG_NAME__ -> 133:a ;
+51:__UG_NAME__ -> 133:b ;
+135:__UG_NAME__ -> 139:a ;
+138:__UG_NAME__ -> 139:b ;
+139:__UG_NAME__ -> 143:a ;
+142:__UG_NAME__ -> 143:b ;
+72:__UG_NAME__ -> 73:a ;
+71:__UG_NAME__ -> 73:b ;
+102:__UG_NAME__ -> 103:a ;
+110:__UG_NAME__ -> 111:a ;
+71:__UG_NAME__ -> 113:a ;
+75:__UG_NAME__ -> 113:b ;
+73:__UG_NAME__ -> 74:a ;
+94:__UG_NAME__ -> 95:b ;
+17:__UG_NAME__ -> 76:b ;
+42:__UG_NAME__ -> 43:a ;
+46:__UG_NAME__ -> 47:a ;
+50:__UG_NAME__ -> 51:a ;
+54:__UG_NAME__ -> 55:a ;
+58:__UG_NAME__ -> 59:a ;
+64:__UG_NAME__ -> 65:a ;
+68:__UG_NAME__ -> 69:a ;
+81:__UG_NAME__ -> 82:a ;
+85:__UG_NAME__ -> 86:a ;
+89:__UG_NAME__ -> 90:a ;
+38:__UG_NAME__ -> 109:a ;
+119:__UG_NAME__ -> 120:a ;
+123:__UG_NAME__ -> 124:a ;
+137:__UG_NAME__ -> 138:a ;
+141:__UG_NAME__ -> 142:a ;
+41:__UG_NAME__ -> 42:a ;
+45:__UG_NAME__ -> 46:a ;
+49:__UG_NAME__ -> 50:a ;
+53:__UG_NAME__ -> 54:a ;
+57:__UG_NAME__ -> 58:a ;
+63:__UG_NAME__ -> 64:a ;
+67:__UG_NAME__ -> 68:a ;
+80:__UG_NAME__ -> 81:a ;
+84:__UG_NAME__ -> 85:a ;
+88:__UG_NAME__ -> 89:a ;
+118:__UG_NAME__ -> 119:a ;
+122:__UG_NAME__ -> 123:a ;
+136:__UG_NAME__ -> 137:a ;
+140:__UG_NAME__ -> 141:a ;
+28:__UG_NAME__ -> 61:envelope___control___0 ;
+28:__UG_NAME__ -> 61:envelope___control___4 ;
+29:__UG_NAME__ -> 61:envelope___control___5 ;
+30:__UG_NAME__ -> 61:envelope___control___6 ;
+31:__UG_NAME__ -> 61:envelope___control___7 ;
+60:__UG_NAME__ -> 61:gate ;
+0:__UG_NAME__ -> 71:envelope___control___0 ;
+0:__UG_NAME__ -> 71:envelope___control___4 ;
+1:__UG_NAME__ -> 71:envelope___control___5 ;
+2:__UG_NAME__ -> 71:envelope___control___6 ;
+3:__UG_NAME__ -> 71:envelope___control___7 ;
+70:__UG_NAME__ -> 71:gate ;
+16:__UG_NAME__ -> 78:envelope___control___4 ;
+12:__UG_NAME__ -> 78:envelope___control___5 ;
+19:__UG_NAME__ -> 78:envelope___control___6 ;
+77:__UG_NAME__ -> 78:envelope___select___8 ;
+13:__UG_NAME__ -> 78:envelope___control___9 ;
+19:__UG_NAME__ -> 78:envelope___control___10 ;
+18:__UG_NAME__ -> 78:envelope___control___12 ;
+14:__UG_NAME__ -> 78:envelope___control___13 ;
+19:__UG_NAME__ -> 78:envelope___control___14 ;
+15:__UG_NAME__ -> 78:envelope___control___17 ;
+19:__UG_NAME__ -> 78:envelope___control___18 ;
+24:__UG_NAME__ -> 94:envelope___control___0 ;
+24:__UG_NAME__ -> 94:envelope___control___4 ;
+25:__UG_NAME__ -> 94:envelope___control___5 ;
+26:__UG_NAME__ -> 94:envelope___control___6 ;
+27:__UG_NAME__ -> 94:envelope___control___7 ;
+91:__UG_NAME__ -> 94:gate ;
+32:__UG_NAME__ -> 100:envelope___control___0 ;
+32:__UG_NAME__ -> 100:envelope___control___4 ;
+33:__UG_NAME__ -> 100:envelope___control___5 ;
+34:__UG_NAME__ -> 100:envelope___control___6 ;
+35:__UG_NAME__ -> 100:envelope___control___7 ;
+48:__UG_NAME__ -> 100:gate ;
+20:__UG_NAME__ -> 126:envelope___control___0 ;
+20:__UG_NAME__ -> 126:envelope___control___4 ;
+21:__UG_NAME__ -> 126:envelope___control___5 ;
+22:__UG_NAME__ -> 126:envelope___control___6 ;
+23:__UG_NAME__ -> 126:envelope___control___7 ;
+125:__UG_NAME__ -> 126:gate ;
+8:__UG_NAME__ -> 134:envelope___control___0 ;
+8:__UG_NAME__ -> 134:envelope___control___4 ;
+9:__UG_NAME__ -> 134:envelope___control___5 ;
+10:__UG_NAME__ -> 134:envelope___control___6 ;
+11:__UG_NAME__ -> 134:envelope___control___7 ;
+133:__UG_NAME__ -> 134:gate ;
+4:__UG_NAME__ -> 144:envelope___control___0 ;
+4:__UG_NAME__ -> 144:envelope___control___4 ;
+5:__UG_NAME__ -> 144:envelope___control___5 ;
+6:__UG_NAME__ -> 144:envelope___control___6 ;
+7:__UG_NAME__ -> 144:envelope___control___7 ;
+143:__UG_NAME__ -> 144:gate ;
+32:__UG_NAME__ -> 41:in ;
+33:__UG_NAME__ -> 45:in ;
+9:__UG_NAME__ -> 49:in ;
+28:__UG_NAME__ -> 53:in ;
+29:__UG_NAME__ -> 57:in ;
+0:__UG_NAME__ -> 63:in ;
+1:__UG_NAME__ -> 67:in ;
+8:__UG_NAME__ -> 80:in ;
+24:__UG_NAME__ -> 84:in ;
+25:__UG_NAME__ -> 88:in ;
+20:__UG_NAME__ -> 118:in ;
+21:__UG_NAME__ -> 122:in ;
+4:__UG_NAME__ -> 136:in ;
+5:__UG_NAME__ -> 140:in ;
+95:__UG_NAME__ -> 101:freq ;
+36:__UG_NAME__ -> 101:iphase ;
+100:__UG_NAME__ -> 101:width ;
+95:__UG_NAME__ -> 98:freq ;
+97:__UG_NAME__ -> 98:iphase ;
+95:__UG_NAME__ -> 105:freq ;
+104:__UG_NAME__ -> 105:iphase ;
+115:__UG_NAME__ -> 116:freq ;
+116:__UG_NAME__ -> 128:in ;
+127:__UG_NAME__ -> 128:freq ;
+114:__UG_NAME__ -> 115:a ;
+126:__UG_NAME__ -> 127:a ;
+112:__UG_NAME__ -> 114:in ;
+74:__UG_NAME__ -> 114:mul ;
+113:__UG_NAME__ -> 114:add ;
+128:__UG_NAME__ -> 129:in ;
+39:__UG_NAME__ -> 146:bus ;
+145:__UG_NAME__ -> 146:signals___pan2___0 ;
+145:__UG_NAME__ -> 146:signals___pan2___1 ;
+130:__UG_NAME__ -> 145:in ;
+134:__UG_NAME__ -> 145:pos ;
+144:__UG_NAME__ -> 145:level ;
+76:__UG_NAME__ -> 77:which ;
+17:__UG_NAME__ -> 77:array___control___0 ;
+18:__UG_NAME__ -> 77:array___control___1 ;
+37:__UG_NAME__ -> 107:which ;
+99:__UG_NAME__ -> 107:array___binary____op____u____gen___0 ;
+103:__UG_NAME__ -> 107:array___binary____op____u____gen___1 ;
+105:__UG_NAME__ -> 107:array___lf____tri___2 ;
+106:__UG_NAME__ -> 107:array___sin____osc___3 ;
+95:__UG_NAME__ -> 106:freq ;
+93:__UG_NAME__ -> 106:phase ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-mono_player.dot b/etc/synthdefs/graphviz/dot/sonic-pi-mono_player.dot
new file mode 100644
index 0000000..1e8362a
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-mono_player.dot
@@ -0,0 +1,1160 @@
+digraph synthdef {
+115 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+337 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+106 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+146 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+153 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+157 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+163 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+166 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+190 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+194 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+202 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+206 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+225 [label = "{{ <b> |<a> 0.1} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+237 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+241 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+262 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+266 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+283 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+287 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+321 [label = "{{ <b> |<a> 0.1} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+342 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+346 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+350 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+351 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+357 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+361 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+366 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+367 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+377 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+381 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+383 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+387 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+391 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+392 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+393 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+395 [label = "{{ <b> |<a> 0.03} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="dashed, rounded" shape=record rankdir=LR];
+220 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+222 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+223 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+248 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+251 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+254 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+306 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+307 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+308 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <b> |<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+219 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+303 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
+305 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
+319 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+145 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+152 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+156 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+162 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+165 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+189 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+193 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+201 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+205 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+236 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+240 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+245 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+256 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+261 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+265 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+282 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+286 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+341 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+345 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+349 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+356 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+360 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+365 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+373 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+376 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+380 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+386 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+134 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+140 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+151 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+155 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+161 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+164 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+188 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+192 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+200 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+204 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+235 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+239 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+244 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+255 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+260 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+264 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+281 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+285 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+296 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+300 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+340 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+344 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+355 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+359 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+372 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+379 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+385 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <b> |<a> } |<__UG_NAME__>absdif }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <buf> buf} |<__UG_NAME__>buf-dur }" style="dashed, rounded" shape=record rankdir=LR];
+113 [label = "{{ <buf> buf} |<__UG_NAME__>buf-frames }" style="dashed, rounded" shape=record rankdir=LR];
+126 [label = "{{ <interpolation> interpolation 2.0|<loop> loop 1.0|<phase> phase|<bufnum> bufnum|<num____channels> num-channels 1} |<__UG_NAME__>buf-rd }" style="filled, bold, rounded"  shape=record rankdir=LR];
+369 [label = "{{ <relax____time> relax-time|<clamp____time> clamp-time|<slope____above> slope-above|<slope____below> slope-below|<thresh> thresh|<control> control|<in> in} |<__UG_NAME__>compander }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :buf
+ default: 0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+1 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+2 [label = "control
+ :decay
+ default: 0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+3 [label = "control
+ :sustain
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+4 [label = "control
+ :release
+ default: 0.0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+5 [label = "control
+ :attack_level
+ default: 1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+6 [label = "control
+ :decay_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+7 [label = "control
+ :sustain_level
+ default: 1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+8 [label = "control
+ :lpf_init_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+9 [label = "control
+ :lpf_attack_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+10 [label = "control
+ :lpf_decay_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+11 [label = "control
+ :lpf_sustain_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+12 [label = "control
+ :lpf_release_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+13 [label = "control
+ :hpf_init_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+14 [label = "control
+ :hpf_attack_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+15 [label = "control
+ :hpf_decay_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+16 [label = "control
+ :hpf_sustain_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+17 [label = "control
+ :hpf_release_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+18 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :rate
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :start
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :finish
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :lpf
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :lpf_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :lpf_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :lpf_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :lpf_attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :lpf_sustain
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :lpf_decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "control
+ :lpf_release
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "control
+ :lpf_min
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "control
+ :lpf_min_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+40 [label = "control
+ :lpf_min_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+41 [label = "control
+ :lpf_min_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+42 [label = "control
+ :lpf_env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "control
+ :hpf
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+44 [label = "control
+ :hpf_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+45 [label = "control
+ :hpf_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+46 [label = "control
+ :hpf_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+47 [label = "control
+ :hpf_max
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+48 [label = "control
+ :hpf_max_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+49 [label = "control
+ :hpf_max_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+50 [label = "control
+ :hpf_max_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+51 [label = "control
+ :hpf_attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+52 [label = "control
+ :hpf_sustain
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+53 [label = "control
+ :hpf_decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+54 [label = "control
+ :hpf_release
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+55 [label = "control
+ :hpf_env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+56 [label = "control
+ :norm
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+57 [label = "control
+ :pitch
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+58 [label = "control
+ :pitch_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+59 [label = "control
+ :pitch_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+60 [label = "control
+ :pitch_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+61 [label = "control
+ :window_size
+ default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+62 [label = "control
+ :window_size_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+63 [label = "control
+ :window_size_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+64 [label = "control
+ :window_size_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+65 [label = "control
+ :pitch_dis
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+66 [label = "control
+ :pitch_dis_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+67 [label = "control
+ :pitch_dis_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+68 [label = "control
+ :pitch_dis_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+69 [label = "control
+ :time_dis
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+70 [label = "control
+ :time_dis_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+71 [label = "control
+ :time_dis_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+72 [label = "control
+ :time_dis_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+73 [label = "control
+ :compress
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+74 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+75 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+76 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+77 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+78 [label = "control
+ :threshold
+ default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+79 [label = "control
+ :threshold_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+80 [label = "control
+ :threshold_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+81 [label = "control
+ :threshold_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+82 [label = "control
+ :clamp_time
+ default: 0.01" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+83 [label = "control
+ :clamp_time_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+84 [label = "control
+ :clamp_time_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+85 [label = "control
+ :clamp_time_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+86 [label = "control
+ :slope_above
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+87 [label = "control
+ :slope_above_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+88 [label = "control
+ :slope_above_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+89 [label = "control
+ :slope_above_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+90 [label = "control
+ :slope_below
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+91 [label = "control
+ :slope_below_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+92 [label = "control
+ :slope_below_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+93 [label = "control
+ :slope_below_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+94 [label = "control
+ :relax_time
+ default: 0.01" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+95 [label = "control
+ :relax_time_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+96 [label = "control
+ :relax_time_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+97 [label = "control
+ :relax_time_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+98 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+111 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+147 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+158 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+167 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+195 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+207 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+226 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{<envelope___select___0>|4|-99|-99|<envelope___select___4>|<envelope___select___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___select___9>|<envelope___control___10>|0.0|<envelope___select___12>|<envelope___select___13>|<envelope___control___14>|0.0|<envelope___select___16>|<envelope___binary____op____u____gen___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+267 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+288 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+310 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___select___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+322 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{<envelope___select___0>|4|-99|-99|<envelope___select___4>|<envelope___select___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___select___9>|<envelope___control___10>|0.0|<envelope___select___12>|<envelope___select___13>|<envelope___control___14>|0.0|<envelope___select___16>|<envelope___binary____op____u____gen___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+347 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+352 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+362 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+363 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+368 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+382 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+388 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+333 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+99 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+143 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+150 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+154 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+160 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+187 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+191 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+199 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+203 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+234 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+238 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+242 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+243 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+259 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+263 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+280 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+284 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+295 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+299 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+339 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+343 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+354 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+358 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+371 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+378 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+384 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+149 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+159 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+186 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+198 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+233 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+258 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+279 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+338 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+348 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+353 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+364 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+374 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+375 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <action> action 0.0|<dur> dur|<end> end|<start> start} |<__UG_NAME__>line }" style="filled, bold, rounded"  shape=record rankdir=LR];
+396 [label = "{{ <action> action 2.0|<dur> dur|<end> end 1.0|<start> start 1.0} |<__UG_NAME__>line }" style="bold, rounded" shape=record rankdir=LR];
+330 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+231 [label = "{{ <b> |<a> } |<__UG_NAME__>max }" style="bold, rounded" shape=record rankdir=LR];
+302 [label = "{{ <b> |<a> } |<__UG_NAME__>max }" style="filled, bold, rounded"  shape=record rankdir=LR];
+325 [label = "{{ <b> |<a> } |<__UG_NAME__>max }" style="bold, rounded" shape=record rankdir=LR];
+210 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+227 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+229 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+298 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+323 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+324 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+148 [label = "{{ <b> |<a> } |<__UG_NAME__>midiratio }" style="bold, rounded" shape=record rankdir=LR];
+230 [label = "{{ <b> |<a> } |<__UG_NAME__>min }" style="bold, rounded" shape=record rankdir=LR];
+301 [label = "{{ <b> |<a> } |<__UG_NAME__>min }" style="filled, bold, rounded"  shape=record rankdir=LR];
+326 [label = "{{ <b> |<a> } |<__UG_NAME__>min }" style="bold, rounded" shape=record rankdir=LR];
+328 [label = "{{ <b> |<a> } |<__UG_NAME__>min }" style="filled, bold, rounded"  shape=record rankdir=LR];
+394 [label = "{{ <b> |<a> } |<__UG_NAME__>min }" style="bold, rounded" shape=record rankdir=LR];
+335 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+112 [label = "{{ <b> |<a> } |<__UG_NAME__>not-pos? }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <b> |<a> } |<__UG_NAME__>not-pos? }" style="bold, rounded" shape=record rankdir=LR];
+169 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+170 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+171 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+173 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+175 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+177 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+179 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+181 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+184 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+196 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+208 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+246 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+249 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+252 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+268 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+269 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+270 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+272 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+277 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+289 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+292 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+311 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+313 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+172 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
+174 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
+176 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
+178 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
+180 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+182 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+183 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+185 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+197 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+257 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+271 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
+273 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
+274 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+275 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+276 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+278 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+290 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+291 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+390 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+389 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+168 [label = "{{ <time____dispersion> time-dispersion|<pitch____dispersion> pitch-dispersion|<pitch____ratio> pitch-ratio|<window____size> window-size|<in> in} |<__UG_NAME__>pitch-shift }" style="filled, bold, rounded"  shape=record rankdir=LR];
+117 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+209 [label = "{{ {{50|<array___env____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+211 [label = "{{ {{130|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+212 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+213 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+214 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+215 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+216 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+217 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+218 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+221 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+224 [label = "{{ {{<array___select___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+228 [label = "{{ {{200|<array___env____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+232 [label = "{{ {{<array___unary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+247 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+250 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+253 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+293 [label = "{{ {{30|<array___env____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+294 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+297 [label = "{{ {{130|<array___env____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+304 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+309 [label = "{{ {{<array___control___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+312 [label = "{{ {{<array___binary____op____u____gen___0>|<array___pitch____shift___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+314 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+315 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+316 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+317 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+318 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+320 [label = "{{ {{<array___select___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+327 [label = "{{ {{<array___unary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+329 [label = "{{ {{<array___unary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+331 [label = "{{ {{<array___select___0>|<array___lpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+332 [label = "{{ {{<array___unary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+334 [label = "{{ {{<array___select___0>|<array___hpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+336 [label = "{{ {{<array___select___0>|<array___normalizer___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+370 [label = "{{ {{<array___binary____op____u____gen___0>|<array___compander___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+28:__UG_NAME__ -> 115:a ;
+114:__UG_NAME__ -> 115:b ;
+29:__UG_NAME__ -> 116:a ;
+114:__UG_NAME__ -> 116:b ;
+120:__UG_NAME__ -> 122:a ;
+121:__UG_NAME__ -> 122:b ;
+111:__UG_NAME__ -> 127:a ;
+126:__UG_NAME__ -> 127:b ;
+310:__UG_NAME__ -> 337:a ;
+336:__UG_NAME__ -> 337:b ;
+102:__UG_NAME__ -> 106:a ;
+105:__UG_NAME__ -> 106:b ;
+106:__UG_NAME__ -> 110:a ;
+109:__UG_NAME__ -> 110:b ;
+128:__UG_NAME__ -> 132:a ;
+131:__UG_NAME__ -> 132:b ;
+132:__UG_NAME__ -> 136:a ;
+135:__UG_NAME__ -> 136:b ;
+138:__UG_NAME__ -> 142:a ;
+141:__UG_NAME__ -> 142:b ;
+142:__UG_NAME__ -> 146:a ;
+145:__UG_NAME__ -> 146:b ;
+149:__UG_NAME__ -> 153:a ;
+152:__UG_NAME__ -> 153:b ;
+153:__UG_NAME__ -> 157:a ;
+156:__UG_NAME__ -> 157:b ;
+159:__UG_NAME__ -> 163:a ;
+162:__UG_NAME__ -> 163:b ;
+163:__UG_NAME__ -> 166:a ;
+165:__UG_NAME__ -> 166:b ;
+186:__UG_NAME__ -> 190:a ;
+189:__UG_NAME__ -> 190:b ;
+190:__UG_NAME__ -> 194:a ;
+193:__UG_NAME__ -> 194:b ;
+198:__UG_NAME__ -> 202:a ;
+201:__UG_NAME__ -> 202:b ;
+202:__UG_NAME__ -> 206:a ;
+205:__UG_NAME__ -> 206:b ;
+221:__UG_NAME__ -> 225:b ;
+233:__UG_NAME__ -> 237:a ;
+236:__UG_NAME__ -> 237:b ;
+237:__UG_NAME__ -> 241:a ;
+240:__UG_NAME__ -> 241:b ;
+258:__UG_NAME__ -> 262:a ;
+261:__UG_NAME__ -> 262:b ;
+262:__UG_NAME__ -> 266:a ;
+265:__UG_NAME__ -> 266:b ;
+279:__UG_NAME__ -> 283:a ;
+282:__UG_NAME__ -> 283:b ;
+283:__UG_NAME__ -> 287:a ;
+286:__UG_NAME__ -> 287:b ;
+250:__UG_NAME__ -> 321:b ;
+338:__UG_NAME__ -> 342:a ;
+341:__UG_NAME__ -> 342:b ;
+342:__UG_NAME__ -> 346:a ;
+345:__UG_NAME__ -> 346:b ;
+348:__UG_NAME__ -> 350:a ;
+349:__UG_NAME__ -> 350:b ;
+350:__UG_NAME__ -> 351:a ;
+256:__UG_NAME__ -> 351:b ;
+353:__UG_NAME__ -> 357:a ;
+356:__UG_NAME__ -> 357:b ;
+357:__UG_NAME__ -> 361:a ;
+360:__UG_NAME__ -> 361:b ;
+364:__UG_NAME__ -> 366:a ;
+365:__UG_NAME__ -> 366:b ;
+366:__UG_NAME__ -> 367:a ;
+245:__UG_NAME__ -> 367:b ;
+375:__UG_NAME__ -> 377:a ;
+376:__UG_NAME__ -> 377:b ;
+377:__UG_NAME__ -> 381:a ;
+380:__UG_NAME__ -> 381:b ;
+374:__UG_NAME__ -> 383:a ;
+373:__UG_NAME__ -> 383:b ;
+383:__UG_NAME__ -> 387:a ;
+386:__UG_NAME__ -> 387:b ;
+1:__UG_NAME__ -> 391:a ;
+309:__UG_NAME__ -> 391:b ;
+391:__UG_NAME__ -> 392:a ;
+2:__UG_NAME__ -> 392:b ;
+392:__UG_NAME__ -> 393:a ;
+4:__UG_NAME__ -> 393:b ;
+394:__UG_NAME__ -> 395:b ;
+113:__UG_NAME__ -> 114:a ;
+124:__UG_NAME__ -> 220:a ;
+216:__UG_NAME__ -> 220:b ;
+220:__UG_NAME__ -> 222:a ;
+221:__UG_NAME__ -> 222:b ;
+222:__UG_NAME__ -> 223:a ;
+217:__UG_NAME__ -> 223:b ;
+124:__UG_NAME__ -> 248:a ;
+247:__UG_NAME__ -> 248:b ;
+248:__UG_NAME__ -> 251:a ;
+250:__UG_NAME__ -> 251:b ;
+251:__UG_NAME__ -> 254:a ;
+253:__UG_NAME__ -> 254:b ;
+124:__UG_NAME__ -> 306:a ;
+1:__UG_NAME__ -> 306:b ;
+306:__UG_NAME__ -> 307:a ;
+4:__UG_NAME__ -> 307:b ;
+307:__UG_NAME__ -> 308:a ;
+2:__UG_NAME__ -> 308:b ;
+122:__UG_NAME__ -> 124:a ;
+123:__UG_NAME__ -> 124:b ;
+218:__UG_NAME__ -> 219:b ;
+6:__UG_NAME__ -> 303:b ;
+3:__UG_NAME__ -> 305:b ;
+318:__UG_NAME__ -> 319:b ;
+104:__UG_NAME__ -> 105:a ;
+108:__UG_NAME__ -> 109:a ;
+130:__UG_NAME__ -> 131:a ;
+134:__UG_NAME__ -> 135:a ;
+140:__UG_NAME__ -> 141:a ;
+144:__UG_NAME__ -> 145:a ;
+151:__UG_NAME__ -> 152:a ;
+155:__UG_NAME__ -> 156:a ;
+161:__UG_NAME__ -> 162:a ;
+164:__UG_NAME__ -> 165:a ;
+188:__UG_NAME__ -> 189:a ;
+192:__UG_NAME__ -> 193:a ;
+200:__UG_NAME__ -> 201:a ;
+204:__UG_NAME__ -> 205:a ;
+235:__UG_NAME__ -> 236:a ;
+239:__UG_NAME__ -> 240:a ;
+244:__UG_NAME__ -> 245:a ;
+255:__UG_NAME__ -> 256:a ;
+260:__UG_NAME__ -> 261:a ;
+264:__UG_NAME__ -> 265:a ;
+281:__UG_NAME__ -> 282:a ;
+285:__UG_NAME__ -> 286:a ;
+340:__UG_NAME__ -> 341:a ;
+344:__UG_NAME__ -> 345:a ;
+300:__UG_NAME__ -> 349:a ;
+355:__UG_NAME__ -> 356:a ;
+359:__UG_NAME__ -> 360:a ;
+296:__UG_NAME__ -> 365:a ;
+372:__UG_NAME__ -> 373:a ;
+100:__UG_NAME__ -> 376:a ;
+379:__UG_NAME__ -> 380:a ;
+385:__UG_NAME__ -> 386:a ;
+99:__UG_NAME__ -> 100:a ;
+103:__UG_NAME__ -> 104:a ;
+107:__UG_NAME__ -> 108:a ;
+27:__UG_NAME__ -> 123:a ;
+129:__UG_NAME__ -> 130:a ;
+133:__UG_NAME__ -> 134:a ;
+139:__UG_NAME__ -> 140:a ;
+143:__UG_NAME__ -> 144:a ;
+150:__UG_NAME__ -> 151:a ;
+154:__UG_NAME__ -> 155:a ;
+160:__UG_NAME__ -> 161:a ;
+101:__UG_NAME__ -> 164:a ;
+187:__UG_NAME__ -> 188:a ;
+191:__UG_NAME__ -> 192:a ;
+199:__UG_NAME__ -> 200:a ;
+203:__UG_NAME__ -> 204:a ;
+234:__UG_NAME__ -> 235:a ;
+238:__UG_NAME__ -> 239:a ;
+243:__UG_NAME__ -> 244:a ;
+242:__UG_NAME__ -> 255:a ;
+259:__UG_NAME__ -> 260:a ;
+263:__UG_NAME__ -> 264:a ;
+280:__UG_NAME__ -> 281:a ;
+284:__UG_NAME__ -> 285:a ;
+295:__UG_NAME__ -> 296:a ;
+299:__UG_NAME__ -> 300:a ;
+339:__UG_NAME__ -> 340:a ;
+343:__UG_NAME__ -> 344:a ;
+354:__UG_NAME__ -> 355:a ;
+358:__UG_NAME__ -> 359:a ;
+371:__UG_NAME__ -> 372:a ;
+378:__UG_NAME__ -> 379:a ;
+384:__UG_NAME__ -> 385:a ;
+29:__UG_NAME__ -> 121:a ;
+28:__UG_NAME__ -> 121:b ;
+0:__UG_NAME__ -> 120:buf ;
+0:__UG_NAME__ -> 113:buf ;
+0:__UG_NAME__ -> 126:bufnum ;
+125:__UG_NAME__ -> 126:phase ;
+337:__UG_NAME__ -> 369:in ;
+337:__UG_NAME__ -> 369:control ;
+347:__UG_NAME__ -> 369:thresh ;
+352:__UG_NAME__ -> 369:slope____below ;
+362:__UG_NAME__ -> 369:slope____above ;
+363:__UG_NAME__ -> 369:clamp____time ;
+368:__UG_NAME__ -> 369:relax____time ;
+74:__UG_NAME__ -> 111:envelope___control___0 ;
+74:__UG_NAME__ -> 111:envelope___control___4 ;
+75:__UG_NAME__ -> 111:envelope___control___5 ;
+76:__UG_NAME__ -> 111:envelope___control___6 ;
+77:__UG_NAME__ -> 111:envelope___control___7 ;
+110:__UG_NAME__ -> 111:gate ;
+61:__UG_NAME__ -> 137:envelope___control___0 ;
+61:__UG_NAME__ -> 137:envelope___control___4 ;
+62:__UG_NAME__ -> 137:envelope___control___5 ;
+63:__UG_NAME__ -> 137:envelope___control___6 ;
+64:__UG_NAME__ -> 137:envelope___control___7 ;
+136:__UG_NAME__ -> 137:gate ;
+57:__UG_NAME__ -> 147:envelope___control___0 ;
+57:__UG_NAME__ -> 147:envelope___control___4 ;
+58:__UG_NAME__ -> 147:envelope___control___5 ;
+59:__UG_NAME__ -> 147:envelope___control___6 ;
+60:__UG_NAME__ -> 147:envelope___control___7 ;
+146:__UG_NAME__ -> 147:gate ;
+65:__UG_NAME__ -> 158:envelope___control___0 ;
+65:__UG_NAME__ -> 158:envelope___control___4 ;
+66:__UG_NAME__ -> 158:envelope___control___5 ;
+67:__UG_NAME__ -> 158:envelope___control___6 ;
+68:__UG_NAME__ -> 158:envelope___control___7 ;
+157:__UG_NAME__ -> 158:gate ;
+69:__UG_NAME__ -> 167:envelope___control___0 ;
+69:__UG_NAME__ -> 167:envelope___control___4 ;
+70:__UG_NAME__ -> 167:envelope___control___5 ;
+71:__UG_NAME__ -> 167:envelope___control___6 ;
+72:__UG_NAME__ -> 167:envelope___control___7 ;
+166:__UG_NAME__ -> 167:gate ;
+47:__UG_NAME__ -> 195:envelope___control___0 ;
+47:__UG_NAME__ -> 195:envelope___control___4 ;
+48:__UG_NAME__ -> 195:envelope___control___5 ;
+49:__UG_NAME__ -> 195:envelope___control___6 ;
+50:__UG_NAME__ -> 195:envelope___control___7 ;
+194:__UG_NAME__ -> 195:gate ;
+43:__UG_NAME__ -> 207:envelope___control___0 ;
+43:__UG_NAME__ -> 207:envelope___control___4 ;
+44:__UG_NAME__ -> 207:envelope___control___5 ;
+45:__UG_NAME__ -> 207:envelope___control___6 ;
+46:__UG_NAME__ -> 207:envelope___control___7 ;
+206:__UG_NAME__ -> 207:gate ;
+211:__UG_NAME__ -> 226:envelope___select___0 ;
+215:__UG_NAME__ -> 226:envelope___select___4 ;
+216:__UG_NAME__ -> 226:envelope___select___5 ;
+55:__UG_NAME__ -> 226:envelope___control___6 ;
+214:__UG_NAME__ -> 226:envelope___select___8 ;
+217:__UG_NAME__ -> 226:envelope___select___9 ;
+55:__UG_NAME__ -> 226:envelope___control___10 ;
+213:__UG_NAME__ -> 226:envelope___select___12 ;
+224:__UG_NAME__ -> 226:envelope___select___13 ;
+55:__UG_NAME__ -> 226:envelope___control___14 ;
+212:__UG_NAME__ -> 226:envelope___select___16 ;
+225:__UG_NAME__ -> 226:envelope___binary____op____u____gen___17 ;
+55:__UG_NAME__ -> 226:envelope___control___18 ;
+30:__UG_NAME__ -> 267:envelope___control___0 ;
+30:__UG_NAME__ -> 267:envelope___control___4 ;
+31:__UG_NAME__ -> 267:envelope___control___5 ;
+32:__UG_NAME__ -> 267:envelope___control___6 ;
+33:__UG_NAME__ -> 267:envelope___control___7 ;
+266:__UG_NAME__ -> 267:gate ;
+38:__UG_NAME__ -> 288:envelope___control___0 ;
+38:__UG_NAME__ -> 288:envelope___control___4 ;
+39:__UG_NAME__ -> 288:envelope___control___5 ;
+40:__UG_NAME__ -> 288:envelope___control___6 ;
+41:__UG_NAME__ -> 288:envelope___control___7 ;
+287:__UG_NAME__ -> 288:gate ;
+5:__UG_NAME__ -> 310:envelope___control___4 ;
+1:__UG_NAME__ -> 310:envelope___control___5 ;
+26:__UG_NAME__ -> 310:envelope___control___6 ;
+304:__UG_NAME__ -> 310:envelope___select___8 ;
+2:__UG_NAME__ -> 310:envelope___control___9 ;
+26:__UG_NAME__ -> 310:envelope___control___10 ;
+7:__UG_NAME__ -> 310:envelope___control___12 ;
+309:__UG_NAME__ -> 310:envelope___select___13 ;
+26:__UG_NAME__ -> 310:envelope___control___14 ;
+4:__UG_NAME__ -> 310:envelope___control___17 ;
+26:__UG_NAME__ -> 310:envelope___control___18 ;
+294:__UG_NAME__ -> 322:envelope___select___0 ;
+317:__UG_NAME__ -> 322:envelope___select___4 ;
+247:__UG_NAME__ -> 322:envelope___select___5 ;
+42:__UG_NAME__ -> 322:envelope___control___6 ;
+316:__UG_NAME__ -> 322:envelope___select___8 ;
+253:__UG_NAME__ -> 322:envelope___select___9 ;
+42:__UG_NAME__ -> 322:envelope___control___10 ;
+315:__UG_NAME__ -> 322:envelope___select___12 ;
+320:__UG_NAME__ -> 322:envelope___select___13 ;
+42:__UG_NAME__ -> 322:envelope___control___14 ;
+314:__UG_NAME__ -> 322:envelope___select___16 ;
+321:__UG_NAME__ -> 322:envelope___binary____op____u____gen___17 ;
+42:__UG_NAME__ -> 322:envelope___control___18 ;
+78:__UG_NAME__ -> 347:envelope___control___0 ;
+78:__UG_NAME__ -> 347:envelope___control___4 ;
+79:__UG_NAME__ -> 347:envelope___control___5 ;
+80:__UG_NAME__ -> 347:envelope___control___6 ;
+81:__UG_NAME__ -> 347:envelope___control___7 ;
+346:__UG_NAME__ -> 347:gate ;
+90:__UG_NAME__ -> 352:envelope___control___0 ;
+90:__UG_NAME__ -> 352:envelope___control___4 ;
+91:__UG_NAME__ -> 352:envelope___control___5 ;
+92:__UG_NAME__ -> 352:envelope___control___6 ;
+93:__UG_NAME__ -> 352:envelope___control___7 ;
+351:__UG_NAME__ -> 352:gate ;
+86:__UG_NAME__ -> 362:envelope___control___0 ;
+86:__UG_NAME__ -> 362:envelope___control___4 ;
+87:__UG_NAME__ -> 362:envelope___control___5 ;
+88:__UG_NAME__ -> 362:envelope___control___6 ;
+89:__UG_NAME__ -> 362:envelope___control___7 ;
+361:__UG_NAME__ -> 362:gate ;
+82:__UG_NAME__ -> 363:envelope___control___0 ;
+82:__UG_NAME__ -> 363:envelope___control___4 ;
+83:__UG_NAME__ -> 363:envelope___control___5 ;
+84:__UG_NAME__ -> 363:envelope___control___6 ;
+85:__UG_NAME__ -> 363:envelope___control___7 ;
+241:__UG_NAME__ -> 363:gate ;
+94:__UG_NAME__ -> 368:envelope___control___0 ;
+94:__UG_NAME__ -> 368:envelope___control___4 ;
+95:__UG_NAME__ -> 368:envelope___control___5 ;
+96:__UG_NAME__ -> 368:envelope___control___6 ;
+97:__UG_NAME__ -> 368:envelope___control___7 ;
+367:__UG_NAME__ -> 368:gate ;
+22:__UG_NAME__ -> 382:envelope___control___0 ;
+22:__UG_NAME__ -> 382:envelope___control___4 ;
+23:__UG_NAME__ -> 382:envelope___control___5 ;
+24:__UG_NAME__ -> 382:envelope___control___6 ;
+25:__UG_NAME__ -> 382:envelope___control___7 ;
+381:__UG_NAME__ -> 382:gate ;
+18:__UG_NAME__ -> 388:envelope___control___0 ;
+18:__UG_NAME__ -> 388:envelope___control___4 ;
+19:__UG_NAME__ -> 388:envelope___control___5 ;
+20:__UG_NAME__ -> 388:envelope___control___6 ;
+21:__UG_NAME__ -> 388:envelope___control___7 ;
+387:__UG_NAME__ -> 388:gate ;
+331:__UG_NAME__ -> 333:in ;
+332:__UG_NAME__ -> 333:freq ;
+22:__UG_NAME__ -> 99:in ;
+70:__UG_NAME__ -> 101:in ;
+74:__UG_NAME__ -> 103:in ;
+75:__UG_NAME__ -> 107:in ;
+61:__UG_NAME__ -> 129:in ;
+62:__UG_NAME__ -> 133:in ;
+57:__UG_NAME__ -> 139:in ;
+58:__UG_NAME__ -> 143:in ;
+65:__UG_NAME__ -> 150:in ;
+66:__UG_NAME__ -> 154:in ;
+69:__UG_NAME__ -> 160:in ;
+47:__UG_NAME__ -> 187:in ;
+48:__UG_NAME__ -> 191:in ;
+43:__UG_NAME__ -> 199:in ;
+44:__UG_NAME__ -> 203:in ;
+82:__UG_NAME__ -> 234:in ;
+83:__UG_NAME__ -> 238:in ;
+91:__UG_NAME__ -> 242:in ;
+95:__UG_NAME__ -> 243:in ;
+30:__UG_NAME__ -> 259:in ;
+31:__UG_NAME__ -> 263:in ;
+38:__UG_NAME__ -> 280:in ;
+39:__UG_NAME__ -> 284:in ;
+94:__UG_NAME__ -> 295:in ;
+90:__UG_NAME__ -> 299:in ;
+78:__UG_NAME__ -> 339:in ;
+79:__UG_NAME__ -> 343:in ;
+86:__UG_NAME__ -> 354:in ;
+87:__UG_NAME__ -> 358:in ;
+18:__UG_NAME__ -> 371:in ;
+23:__UG_NAME__ -> 378:in ;
+19:__UG_NAME__ -> 384:in ;
+117:__UG_NAME__ -> 125:start ;
+119:__UG_NAME__ -> 125:end ;
+124:__UG_NAME__ -> 125:dur ;
+395:__UG_NAME__ -> 396:dur ;
+312:__UG_NAME__ -> 330:in ;
+329:__UG_NAME__ -> 330:freq ;
+210:__UG_NAME__ -> 231:a ;
+230:__UG_NAME__ -> 231:b ;
+210:__UG_NAME__ -> 302:a ;
+301:__UG_NAME__ -> 302:b ;
+323:__UG_NAME__ -> 325:a ;
+324:__UG_NAME__ -> 325:b ;
+209:__UG_NAME__ -> 210:a ;
+226:__UG_NAME__ -> 227:a ;
+228:__UG_NAME__ -> 229:a ;
+297:__UG_NAME__ -> 298:a ;
+322:__UG_NAME__ -> 323:a ;
+293:__UG_NAME__ -> 324:a ;
+147:__UG_NAME__ -> 148:a ;
+227:__UG_NAME__ -> 230:a ;
+229:__UG_NAME__ -> 230:b ;
+232:__UG_NAME__ -> 301:a ;
+229:__UG_NAME__ -> 301:b ;
+298:__UG_NAME__ -> 326:a ;
+325:__UG_NAME__ -> 326:b ;
+327:__UG_NAME__ -> 328:a ;
+298:__UG_NAME__ -> 328:b ;
+124:__UG_NAME__ -> 394:a ;
+393:__UG_NAME__ -> 394:b ;
+334:__UG_NAME__ -> 335:in ;
+27:__UG_NAME__ -> 112:a ;
+27:__UG_NAME__ -> 118:a ;
+54:__UG_NAME__ -> 169:b ;
+13:__UG_NAME__ -> 170:b ;
+14:__UG_NAME__ -> 171:b ;
+15:__UG_NAME__ -> 173:b ;
+16:__UG_NAME__ -> 175:b ;
+17:__UG_NAME__ -> 177:b ;
+51:__UG_NAME__ -> 179:b ;
+53:__UG_NAME__ -> 181:b ;
+52:__UG_NAME__ -> 184:b ;
+195:__UG_NAME__ -> 196:b ;
+207:__UG_NAME__ -> 208:b ;
+34:__UG_NAME__ -> 246:b ;
+37:__UG_NAME__ -> 249:b ;
+36:__UG_NAME__ -> 252:b ;
+267:__UG_NAME__ -> 268:b ;
+9:__UG_NAME__ -> 269:b ;
+10:__UG_NAME__ -> 270:b ;
+11:__UG_NAME__ -> 272:b ;
+35:__UG_NAME__ -> 277:b ;
+288:__UG_NAME__ -> 289:b ;
+8:__UG_NAME__ -> 292:b ;
+147:__UG_NAME__ -> 311:b ;
+12:__UG_NAME__ -> 313:b ;
+170:__UG_NAME__ -> 172:a ;
+171:__UG_NAME__ -> 172:b ;
+172:__UG_NAME__ -> 174:a ;
+173:__UG_NAME__ -> 174:b ;
+174:__UG_NAME__ -> 176:a ;
+175:__UG_NAME__ -> 176:b ;
+176:__UG_NAME__ -> 178:a ;
+177:__UG_NAME__ -> 178:b ;
+178:__UG_NAME__ -> 180:a ;
+179:__UG_NAME__ -> 180:b ;
+180:__UG_NAME__ -> 182:a ;
+181:__UG_NAME__ -> 182:b ;
+182:__UG_NAME__ -> 183:a ;
+169:__UG_NAME__ -> 183:b ;
+183:__UG_NAME__ -> 185:a ;
+184:__UG_NAME__ -> 185:b ;
+185:__UG_NAME__ -> 197:a ;
+196:__UG_NAME__ -> 197:b ;
+208:__UG_NAME__ -> 257:a ;
+197:__UG_NAME__ -> 257:b ;
+269:__UG_NAME__ -> 271:a ;
+270:__UG_NAME__ -> 271:b ;
+271:__UG_NAME__ -> 273:a ;
+272:__UG_NAME__ -> 273:b ;
+273:__UG_NAME__ -> 274:a ;
+246:__UG_NAME__ -> 274:b ;
+274:__UG_NAME__ -> 275:a ;
+252:__UG_NAME__ -> 275:b ;
+275:__UG_NAME__ -> 276:a ;
+249:__UG_NAME__ -> 276:b ;
+276:__UG_NAME__ -> 278:a ;
+277:__UG_NAME__ -> 278:b ;
+278:__UG_NAME__ -> 290:a ;
+289:__UG_NAME__ -> 290:b ;
+268:__UG_NAME__ -> 291:a ;
+290:__UG_NAME__ -> 291:b ;
+98:__UG_NAME__ -> 390:bus ;
+389:__UG_NAME__ -> 390:signals___pan2___0 ;
+389:__UG_NAME__ -> 390:signals___pan2___1 ;
+370:__UG_NAME__ -> 389:in ;
+382:__UG_NAME__ -> 389:pos ;
+388:__UG_NAME__ -> 389:level ;
+127:__UG_NAME__ -> 168:in ;
+137:__UG_NAME__ -> 168:window____size ;
+148:__UG_NAME__ -> 168:pitch____ratio ;
+158:__UG_NAME__ -> 168:pitch____dispersion ;
+167:__UG_NAME__ -> 168:time____dispersion ;
+112:__UG_NAME__ -> 117:which ;
+115:__UG_NAME__ -> 117:array___binary____op____u____gen___0 ;
+116:__UG_NAME__ -> 117:array___binary____op____u____gen___1 ;
+118:__UG_NAME__ -> 119:which ;
+116:__UG_NAME__ -> 119:array___binary____op____u____gen___0 ;
+115:__UG_NAME__ -> 119:array___binary____op____u____gen___1 ;
+208:__UG_NAME__ -> 209:which ;
+207:__UG_NAME__ -> 209:array___env____gen___1 ;
+170:__UG_NAME__ -> 211:which ;
+13:__UG_NAME__ -> 211:array___control___1 ;
+177:__UG_NAME__ -> 212:which ;
+209:__UG_NAME__ -> 212:array___select___0 ;
+17:__UG_NAME__ -> 212:array___control___1 ;
+175:__UG_NAME__ -> 213:which ;
+212:__UG_NAME__ -> 213:array___select___0 ;
+16:__UG_NAME__ -> 213:array___control___1 ;
+173:__UG_NAME__ -> 214:which ;
+213:__UG_NAME__ -> 214:array___select___0 ;
+15:__UG_NAME__ -> 214:array___control___1 ;
+171:__UG_NAME__ -> 215:which ;
+214:__UG_NAME__ -> 215:array___select___0 ;
+14:__UG_NAME__ -> 215:array___control___1 ;
+179:__UG_NAME__ -> 216:which ;
+1:__UG_NAME__ -> 216:array___control___0 ;
+51:__UG_NAME__ -> 216:array___control___1 ;
+181:__UG_NAME__ -> 217:which ;
+2:__UG_NAME__ -> 217:array___control___0 ;
+53:__UG_NAME__ -> 217:array___control___1 ;
+184:__UG_NAME__ -> 218:which ;
+3:__UG_NAME__ -> 218:array___control___0 ;
+52:__UG_NAME__ -> 218:array___control___1 ;
+169:__UG_NAME__ -> 221:which ;
+4:__UG_NAME__ -> 221:array___control___0 ;
+54:__UG_NAME__ -> 221:array___control___1 ;
+219:__UG_NAME__ -> 224:which ;
+218:__UG_NAME__ -> 224:array___select___0 ;
+223:__UG_NAME__ -> 224:array___binary____op____u____gen___1 ;
+196:__UG_NAME__ -> 228:which ;
+195:__UG_NAME__ -> 228:array___env____gen___1 ;
+197:__UG_NAME__ -> 232:which ;
+210:__UG_NAME__ -> 232:array___unary____op____u____gen___0 ;
+231:__UG_NAME__ -> 232:array___binary____op____u____gen___1 ;
+246:__UG_NAME__ -> 247:which ;
+1:__UG_NAME__ -> 247:array___control___0 ;
+34:__UG_NAME__ -> 247:array___control___1 ;
+249:__UG_NAME__ -> 250:which ;
+4:__UG_NAME__ -> 250:array___control___0 ;
+37:__UG_NAME__ -> 250:array___control___1 ;
+252:__UG_NAME__ -> 253:which ;
+2:__UG_NAME__ -> 253:array___control___0 ;
+36:__UG_NAME__ -> 253:array___control___1 ;
+289:__UG_NAME__ -> 293:which ;
+288:__UG_NAME__ -> 293:array___env____gen___1 ;
+292:__UG_NAME__ -> 294:which ;
+293:__UG_NAME__ -> 294:array___select___0 ;
+8:__UG_NAME__ -> 294:array___control___1 ;
+268:__UG_NAME__ -> 297:which ;
+267:__UG_NAME__ -> 297:array___env____gen___1 ;
+303:__UG_NAME__ -> 304:which ;
+6:__UG_NAME__ -> 304:array___control___0 ;
+7:__UG_NAME__ -> 304:array___control___1 ;
+305:__UG_NAME__ -> 309:which ;
+3:__UG_NAME__ -> 309:array___control___0 ;
+308:__UG_NAME__ -> 309:array___binary____op____u____gen___1 ;
+311:__UG_NAME__ -> 312:which ;
+127:__UG_NAME__ -> 312:array___binary____op____u____gen___0 ;
+168:__UG_NAME__ -> 312:array___pitch____shift___1 ;
+313:__UG_NAME__ -> 314:which ;
+297:__UG_NAME__ -> 314:array___select___0 ;
+12:__UG_NAME__ -> 314:array___control___1 ;
+272:__UG_NAME__ -> 315:which ;
+314:__UG_NAME__ -> 315:array___select___0 ;
+11:__UG_NAME__ -> 315:array___control___1 ;
+270:__UG_NAME__ -> 316:which ;
+315:__UG_NAME__ -> 316:array___select___0 ;
+10:__UG_NAME__ -> 316:array___control___1 ;
+269:__UG_NAME__ -> 317:which ;
+316:__UG_NAME__ -> 317:array___select___0 ;
+9:__UG_NAME__ -> 317:array___control___1 ;
+277:__UG_NAME__ -> 318:which ;
+3:__UG_NAME__ -> 318:array___control___0 ;
+35:__UG_NAME__ -> 318:array___control___1 ;
+319:__UG_NAME__ -> 320:which ;
+318:__UG_NAME__ -> 320:array___select___0 ;
+254:__UG_NAME__ -> 320:array___binary____op____u____gen___1 ;
+290:__UG_NAME__ -> 327:which ;
+298:__UG_NAME__ -> 327:array___unary____op____u____gen___0 ;
+326:__UG_NAME__ -> 327:array___binary____op____u____gen___1 ;
+290:__UG_NAME__ -> 329:which ;
+298:__UG_NAME__ -> 329:array___unary____op____u____gen___0 ;
+328:__UG_NAME__ -> 329:array___binary____op____u____gen___1 ;
+291:__UG_NAME__ -> 331:which ;
+312:__UG_NAME__ -> 331:array___select___0 ;
+330:__UG_NAME__ -> 331:array___lpf___1 ;
+197:__UG_NAME__ -> 332:which ;
+210:__UG_NAME__ -> 332:array___unary____op____u____gen___0 ;
+302:__UG_NAME__ -> 332:array___binary____op____u____gen___1 ;
+257:__UG_NAME__ -> 334:which ;
+331:__UG_NAME__ -> 334:array___select___0 ;
+333:__UG_NAME__ -> 334:array___hpf___1 ;
+56:__UG_NAME__ -> 336:which ;
+334:__UG_NAME__ -> 336:array___select___0 ;
+335:__UG_NAME__ -> 336:array___normalizer___1 ;
+73:__UG_NAME__ -> 370:which ;
+337:__UG_NAME__ -> 370:array___binary____op____u____gen___0 ;
+369:__UG_NAME__ -> 370:array___compander___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-noise.dot b/etc/synthdefs/graphviz/dot/sonic-pi-noise.dot
new file mode 100644
index 0000000..b865504
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-noise.dot
@@ -0,0 +1,223 @@
+digraph synthdef {
+69 [label = "{{ <b> |<a> 0.9} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :cutoff
+ default: 110.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :res
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+74 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+68 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+71 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{<__UG_NAME__>white-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+68:__UG_NAME__ -> 69:b ;
+69:__UG_NAME__ -> 73:a ;
+72:__UG_NAME__ -> 73:b ;
+25:__UG_NAME__ -> 29:a ;
+28:__UG_NAME__ -> 29:b ;
+29:__UG_NAME__ -> 33:a ;
+32:__UG_NAME__ -> 33:b ;
+39:__UG_NAME__ -> 43:a ;
+42:__UG_NAME__ -> 43:b ;
+43:__UG_NAME__ -> 47:a ;
+46:__UG_NAME__ -> 47:b ;
+49:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+53:__UG_NAME__ -> 57:a ;
+56:__UG_NAME__ -> 57:b ;
+60:__UG_NAME__ -> 61:a ;
+38:__UG_NAME__ -> 61:b ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+13:__UG_NAME__ -> 70:b ;
+27:__UG_NAME__ -> 28:a ;
+31:__UG_NAME__ -> 32:a ;
+37:__UG_NAME__ -> 38:a ;
+41:__UG_NAME__ -> 42:a ;
+45:__UG_NAME__ -> 46:a ;
+51:__UG_NAME__ -> 52:a ;
+55:__UG_NAME__ -> 56:a ;
+63:__UG_NAME__ -> 64:a ;
+26:__UG_NAME__ -> 27:a ;
+30:__UG_NAME__ -> 31:a ;
+36:__UG_NAME__ -> 37:a ;
+40:__UG_NAME__ -> 41:a ;
+44:__UG_NAME__ -> 45:a ;
+50:__UG_NAME__ -> 51:a ;
+54:__UG_NAME__ -> 55:a ;
+62:__UG_NAME__ -> 63:a ;
+4:__UG_NAME__ -> 34:envelope___control___0 ;
+4:__UG_NAME__ -> 34:envelope___control___4 ;
+5:__UG_NAME__ -> 34:envelope___control___5 ;
+6:__UG_NAME__ -> 34:envelope___control___6 ;
+7:__UG_NAME__ -> 34:envelope___control___7 ;
+33:__UG_NAME__ -> 34:gate ;
+0:__UG_NAME__ -> 48:envelope___control___0 ;
+0:__UG_NAME__ -> 48:envelope___control___4 ;
+1:__UG_NAME__ -> 48:envelope___control___5 ;
+2:__UG_NAME__ -> 48:envelope___control___6 ;
+3:__UG_NAME__ -> 48:envelope___control___7 ;
+47:__UG_NAME__ -> 48:gate ;
+16:__UG_NAME__ -> 58:envelope___control___0 ;
+16:__UG_NAME__ -> 58:envelope___control___4 ;
+17:__UG_NAME__ -> 58:envelope___control___5 ;
+18:__UG_NAME__ -> 58:envelope___control___6 ;
+19:__UG_NAME__ -> 58:envelope___control___7 ;
+57:__UG_NAME__ -> 58:gate ;
+35:__UG_NAME__ -> 66:envelope___mul____add___0 ;
+35:__UG_NAME__ -> 66:envelope___mul____add___4 ;
+21:__UG_NAME__ -> 66:envelope___control___5 ;
+22:__UG_NAME__ -> 66:envelope___control___6 ;
+23:__UG_NAME__ -> 66:envelope___control___7 ;
+65:__UG_NAME__ -> 66:gate ;
+12:__UG_NAME__ -> 72:envelope___control___4 ;
+8:__UG_NAME__ -> 72:envelope___control___5 ;
+15:__UG_NAME__ -> 72:envelope___control___6 ;
+71:__UG_NAME__ -> 72:envelope___select___8 ;
+10:__UG_NAME__ -> 72:envelope___control___9 ;
+15:__UG_NAME__ -> 72:envelope___control___10 ;
+14:__UG_NAME__ -> 72:envelope___control___12 ;
+9:__UG_NAME__ -> 72:envelope___control___13 ;
+15:__UG_NAME__ -> 72:envelope___control___14 ;
+11:__UG_NAME__ -> 72:envelope___control___17 ;
+15:__UG_NAME__ -> 72:envelope___control___18 ;
+4:__UG_NAME__ -> 26:in ;
+5:__UG_NAME__ -> 30:in ;
+35:__UG_NAME__ -> 36:in ;
+0:__UG_NAME__ -> 40:in ;
+1:__UG_NAME__ -> 44:in ;
+16:__UG_NAME__ -> 50:in ;
+17:__UG_NAME__ -> 54:in ;
+21:__UG_NAME__ -> 62:in ;
+58:__UG_NAME__ -> 67:a ;
+20:__UG_NAME__ -> 35:in ;
+24:__UG_NAME__ -> 75:bus ;
+74:__UG_NAME__ -> 75:signals___pan2___0 ;
+74:__UG_NAME__ -> 75:signals___pan2___1 ;
+73:__UG_NAME__ -> 74:in ;
+34:__UG_NAME__ -> 74:pos ;
+48:__UG_NAME__ -> 74:level ;
+59:__UG_NAME__ -> 68:in ;
+67:__UG_NAME__ -> 68:freq ;
+66:__UG_NAME__ -> 68:rq ;
+70:__UG_NAME__ -> 71:which ;
+13:__UG_NAME__ -> 71:array___control___0 ;
+14:__UG_NAME__ -> 71:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-piano.dot b/etc/synthdefs/graphviz/dot/sonic-pi-piano.dot
new file mode 100644
index 0000000..46c50c9
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-piano.dot
@@ -0,0 +1,178 @@
+digraph synthdef {
+32 [label = "{{ <b> 127.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <level> level|<pos> pos|<right> right|<left> left} |<__UG_NAME__>balance2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+30 [label = "{{ <hi> hi 1.0|<lo> lo 0.0|<in> in} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <hi> hi 1.0|<lo> lo 0.0|<in> in} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :vel
+ default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :hard
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :velcurve
+ default: 0.8" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :stereo_width
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+40 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <hard> hard|<stretch> stretch 0.0|<velmuff> velmuff 0.8|<vel> vel|<decay> decay|<random> random 0.0|<gate> gate 1.0|<sustain> sustain 0.1|<velhard> velhard 0.8|<stereo> stereo|<release> release|<muffle> muffle 0.8|<velcurve> velcurve|<tune> tune 0.5|<freq> freq} |<__UG_NAME__>mda-piano }" style="filled, bold, rounded"  shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <add> add 0.0|<mul> mul 4.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <add> add -3.0|<mul> mul 6.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ {{<signals___binary____op____u____gen___0>|<signals___binary____op____u____gen___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+44 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+31:__UG_NAME__ -> 32:a ;
+45:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+45:__UG_NAME__ -> 55:a ;
+53:__UG_NAME__ -> 55:b ;
+23:__UG_NAME__ -> 27:a ;
+26:__UG_NAME__ -> 27:b ;
+27:__UG_NAME__ -> 39:a ;
+38:__UG_NAME__ -> 39:b ;
+48:__UG_NAME__ -> 50:a ;
+49:__UG_NAME__ -> 50:b ;
+50:__UG_NAME__ -> 51:a ;
+47:__UG_NAME__ -> 51:b ;
+14:__UG_NAME__ -> 43:b ;
+25:__UG_NAME__ -> 26:a ;
+37:__UG_NAME__ -> 38:a ;
+46:__UG_NAME__ -> 47:a ;
+34:__UG_NAME__ -> 49:a ;
+24:__UG_NAME__ -> 25:a ;
+33:__UG_NAME__ -> 34:a ;
+36:__UG_NAME__ -> 37:a ;
+28:__UG_NAME__ -> 46:a ;
+42:__UG_NAME__ -> 53:left ;
+42:__UG_NAME__ -> 53:right ;
+40:__UG_NAME__ -> 53:pos ;
+52:__UG_NAME__ -> 53:level ;
+17:__UG_NAME__ -> 30:in ;
+19:__UG_NAME__ -> 35:in ;
+5:__UG_NAME__ -> 40:envelope___control___0 ;
+5:__UG_NAME__ -> 40:envelope___control___4 ;
+6:__UG_NAME__ -> 40:envelope___control___5 ;
+7:__UG_NAME__ -> 40:envelope___control___6 ;
+8:__UG_NAME__ -> 40:envelope___control___7 ;
+39:__UG_NAME__ -> 40:gate ;
+13:__UG_NAME__ -> 45:envelope___control___4 ;
+9:__UG_NAME__ -> 45:envelope___control___5 ;
+16:__UG_NAME__ -> 45:envelope___control___6 ;
+44:__UG_NAME__ -> 45:envelope___select___8 ;
+10:__UG_NAME__ -> 45:envelope___control___9 ;
+16:__UG_NAME__ -> 45:envelope___control___10 ;
+15:__UG_NAME__ -> 45:envelope___control___12 ;
+11:__UG_NAME__ -> 45:envelope___control___13 ;
+16:__UG_NAME__ -> 45:envelope___control___14 ;
+12:__UG_NAME__ -> 45:envelope___control___17 ;
+16:__UG_NAME__ -> 45:envelope___control___18 ;
+1:__UG_NAME__ -> 52:envelope___control___0 ;
+1:__UG_NAME__ -> 52:envelope___control___4 ;
+2:__UG_NAME__ -> 52:envelope___control___5 ;
+3:__UG_NAME__ -> 52:envelope___control___6 ;
+4:__UG_NAME__ -> 52:envelope___control___7 ;
+51:__UG_NAME__ -> 52:gate ;
+5:__UG_NAME__ -> 24:in ;
+2:__UG_NAME__ -> 28:in ;
+1:__UG_NAME__ -> 33:in ;
+6:__UG_NAME__ -> 36:in ;
+29:__UG_NAME__ -> 42:freq ;
+20:__UG_NAME__ -> 42:velcurve ;
+12:__UG_NAME__ -> 42:release ;
+21:__UG_NAME__ -> 42:stereo ;
+10:__UG_NAME__ -> 42:decay ;
+32:__UG_NAME__ -> 42:vel ;
+41:__UG_NAME__ -> 42:hard ;
+0:__UG_NAME__ -> 29:a ;
+30:__UG_NAME__ -> 31:in ;
+35:__UG_NAME__ -> 41:in ;
+22:__UG_NAME__ -> 56:bus ;
+54:__UG_NAME__ -> 56:signals___binary____op____u____gen___0 ;
+55:__UG_NAME__ -> 56:signals___binary____op____u____gen___1 ;
+43:__UG_NAME__ -> 44:which ;
+14:__UG_NAME__ -> 44:array___control___0 ;
+15:__UG_NAME__ -> 44:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-pluck.dot b/etc/synthdefs/graphviz/dot/sonic-pi-pluck.dot
new file mode 100644
index 0000000..177c7d5
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-pluck.dot
@@ -0,0 +1,161 @@
+digraph synthdef {
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> 2.5} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :noise_amp
+ default: 0.8" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :max_delay_time
+ default: 0.125" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :pluck_decay
+ default: 30.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :coef
+ default: 0.3" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+46 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___control___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+50 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+22 [label = "{<__UG_NAME__>pink-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+34 [label = "{{ <coef> coef|<decaytime> decaytime|<delaytime> delaytime|<maxdelaytime> maxdelaytime|<trig> trig 1.0|<in> in} |<__UG_NAME__>pluck }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+17:__UG_NAME__ -> 31:a ;
+22:__UG_NAME__ -> 31:b ;
+34:__UG_NAME__ -> 35:b ;
+35:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+37:__UG_NAME__ -> 38:a ;
+27:__UG_NAME__ -> 38:b ;
+38:__UG_NAME__ -> 39:a ;
+30:__UG_NAME__ -> 39:b ;
+36:__UG_NAME__ -> 41:a ;
+40:__UG_NAME__ -> 41:b ;
+41:__UG_NAME__ -> 45:a ;
+44:__UG_NAME__ -> 45:b ;
+32:__UG_NAME__ -> 33:b ;
+26:__UG_NAME__ -> 27:a ;
+29:__UG_NAME__ -> 30:a ;
+24:__UG_NAME__ -> 40:a ;
+43:__UG_NAME__ -> 44:a ;
+23:__UG_NAME__ -> 24:a ;
+25:__UG_NAME__ -> 26:a ;
+28:__UG_NAME__ -> 29:a ;
+42:__UG_NAME__ -> 43:a ;
+5:__UG_NAME__ -> 46:envelope___control___0 ;
+5:__UG_NAME__ -> 46:envelope___control___4 ;
+6:__UG_NAME__ -> 46:envelope___control___5 ;
+7:__UG_NAME__ -> 46:envelope___control___6 ;
+8:__UG_NAME__ -> 46:envelope___control___7 ;
+45:__UG_NAME__ -> 46:gate ;
+13:__UG_NAME__ -> 47:envelope___control___4 ;
+9:__UG_NAME__ -> 47:envelope___control___5 ;
+16:__UG_NAME__ -> 47:envelope___control___6 ;
+14:__UG_NAME__ -> 47:envelope___control___8 ;
+10:__UG_NAME__ -> 47:envelope___control___9 ;
+16:__UG_NAME__ -> 47:envelope___control___10 ;
+15:__UG_NAME__ -> 47:envelope___control___12 ;
+11:__UG_NAME__ -> 47:envelope___control___13 ;
+16:__UG_NAME__ -> 47:envelope___control___14 ;
+12:__UG_NAME__ -> 47:envelope___control___17 ;
+16:__UG_NAME__ -> 47:envelope___control___18 ;
+1:__UG_NAME__ -> 49:envelope___control___0 ;
+1:__UG_NAME__ -> 49:envelope___control___4 ;
+2:__UG_NAME__ -> 49:envelope___control___5 ;
+3:__UG_NAME__ -> 49:envelope___control___6 ;
+4:__UG_NAME__ -> 49:envelope___control___7 ;
+39:__UG_NAME__ -> 49:gate ;
+5:__UG_NAME__ -> 23:in ;
+1:__UG_NAME__ -> 25:in ;
+2:__UG_NAME__ -> 28:in ;
+6:__UG_NAME__ -> 42:in ;
+0:__UG_NAME__ -> 32:a ;
+21:__UG_NAME__ -> 51:bus ;
+50:__UG_NAME__ -> 51:signals___pan2___0 ;
+50:__UG_NAME__ -> 51:signals___pan2___1 ;
+48:__UG_NAME__ -> 50:in ;
+46:__UG_NAME__ -> 50:pos ;
+49:__UG_NAME__ -> 50:level ;
+31:__UG_NAME__ -> 34:in ;
+18:__UG_NAME__ -> 34:maxdelaytime ;
+33:__UG_NAME__ -> 34:delaytime ;
+19:__UG_NAME__ -> 34:decaytime ;
+20:__UG_NAME__ -> 34:coef ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-pnoise.dot b/etc/synthdefs/graphviz/dot/sonic-pi-pnoise.dot
new file mode 100644
index 0000000..1715535
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-pnoise.dot
@@ -0,0 +1,223 @@
+digraph synthdef {
+60 [label = "{{ <b> |<a> 3.0} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :cutoff
+ default: 110.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :res
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+42 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+74 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+32 [label = "{<__UG_NAME__>pink-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
+49 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+62 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+49:__UG_NAME__ -> 60:b ;
+60:__UG_NAME__ -> 64:a ;
+63:__UG_NAME__ -> 64:b ;
+26:__UG_NAME__ -> 31:a ;
+30:__UG_NAME__ -> 31:b ;
+33:__UG_NAME__ -> 37:a ;
+36:__UG_NAME__ -> 37:b ;
+37:__UG_NAME__ -> 41:a ;
+40:__UG_NAME__ -> 41:b ;
+31:__UG_NAME__ -> 47:a ;
+46:__UG_NAME__ -> 47:b ;
+50:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+54:__UG_NAME__ -> 58:a ;
+57:__UG_NAME__ -> 58:b ;
+65:__UG_NAME__ -> 68:a ;
+67:__UG_NAME__ -> 68:b ;
+68:__UG_NAME__ -> 71:a ;
+70:__UG_NAME__ -> 71:b ;
+13:__UG_NAME__ -> 61:b ;
+29:__UG_NAME__ -> 30:a ;
+35:__UG_NAME__ -> 36:a ;
+39:__UG_NAME__ -> 40:a ;
+45:__UG_NAME__ -> 46:a ;
+52:__UG_NAME__ -> 53:a ;
+56:__UG_NAME__ -> 57:a ;
+66:__UG_NAME__ -> 67:a ;
+69:__UG_NAME__ -> 70:a ;
+28:__UG_NAME__ -> 29:a ;
+34:__UG_NAME__ -> 35:a ;
+38:__UG_NAME__ -> 39:a ;
+44:__UG_NAME__ -> 45:a ;
+51:__UG_NAME__ -> 52:a ;
+55:__UG_NAME__ -> 56:a ;
+59:__UG_NAME__ -> 66:a ;
+25:__UG_NAME__ -> 69:a ;
+16:__UG_NAME__ -> 42:envelope___control___0 ;
+16:__UG_NAME__ -> 42:envelope___control___4 ;
+17:__UG_NAME__ -> 42:envelope___control___5 ;
+18:__UG_NAME__ -> 42:envelope___control___6 ;
+19:__UG_NAME__ -> 42:envelope___control___7 ;
+41:__UG_NAME__ -> 42:gate ;
+27:__UG_NAME__ -> 48:envelope___mul____add___0 ;
+27:__UG_NAME__ -> 48:envelope___mul____add___4 ;
+21:__UG_NAME__ -> 48:envelope___control___5 ;
+22:__UG_NAME__ -> 48:envelope___control___6 ;
+23:__UG_NAME__ -> 48:envelope___control___7 ;
+47:__UG_NAME__ -> 48:gate ;
+12:__UG_NAME__ -> 63:envelope___control___4 ;
+8:__UG_NAME__ -> 63:envelope___control___5 ;
+15:__UG_NAME__ -> 63:envelope___control___6 ;
+62:__UG_NAME__ -> 63:envelope___select___8 ;
+10:__UG_NAME__ -> 63:envelope___control___9 ;
+15:__UG_NAME__ -> 63:envelope___control___10 ;
+14:__UG_NAME__ -> 63:envelope___control___12 ;
+9:__UG_NAME__ -> 63:envelope___control___13 ;
+15:__UG_NAME__ -> 63:envelope___control___14 ;
+11:__UG_NAME__ -> 63:envelope___control___17 ;
+15:__UG_NAME__ -> 63:envelope___control___18 ;
+4:__UG_NAME__ -> 72:envelope___control___0 ;
+4:__UG_NAME__ -> 72:envelope___control___4 ;
+5:__UG_NAME__ -> 72:envelope___control___5 ;
+6:__UG_NAME__ -> 72:envelope___control___6 ;
+7:__UG_NAME__ -> 72:envelope___control___7 ;
+71:__UG_NAME__ -> 72:gate ;
+0:__UG_NAME__ -> 73:envelope___control___0 ;
+0:__UG_NAME__ -> 73:envelope___control___4 ;
+1:__UG_NAME__ -> 73:envelope___control___5 ;
+2:__UG_NAME__ -> 73:envelope___control___6 ;
+3:__UG_NAME__ -> 73:envelope___control___7 ;
+58:__UG_NAME__ -> 73:gate ;
+5:__UG_NAME__ -> 25:in ;
+27:__UG_NAME__ -> 28:in ;
+16:__UG_NAME__ -> 34:in ;
+17:__UG_NAME__ -> 38:in ;
+21:__UG_NAME__ -> 44:in ;
+0:__UG_NAME__ -> 51:in ;
+1:__UG_NAME__ -> 55:in ;
+4:__UG_NAME__ -> 59:in ;
+42:__UG_NAME__ -> 43:a ;
+20:__UG_NAME__ -> 27:in ;
+24:__UG_NAME__ -> 75:bus ;
+74:__UG_NAME__ -> 75:signals___pan2___0 ;
+74:__UG_NAME__ -> 75:signals___pan2___1 ;
+64:__UG_NAME__ -> 74:in ;
+72:__UG_NAME__ -> 74:pos ;
+73:__UG_NAME__ -> 74:level ;
+32:__UG_NAME__ -> 49:in ;
+43:__UG_NAME__ -> 49:freq ;
+48:__UG_NAME__ -> 49:rq ;
+61:__UG_NAME__ -> 62:which ;
+13:__UG_NAME__ -> 62:array___control___0 ;
+14:__UG_NAME__ -> 62:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-pretty_bell.dot b/etc/synthdefs/graphviz/dot/sonic-pi-pretty_bell.dot
new file mode 100644
index 0000000..928394a
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-pretty_bell.dot
@@ -0,0 +1,234 @@
+digraph synthdef {
+32 [label = "{{ <b> |<a> 6.8} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+50 [label = "{{ <b> 0.5|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> 0.5|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> 0.5|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> 4.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+58 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+25 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+80 [label = "{{ <action> action 2.0|<time> time 0.1|<amp> amp 1.0E-4|<in> in} |<__UG_NAME__>detect-silence }" style="filled, bold, rounded"  shape=record rankdir=LR];
+30 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 0.5|<gate> gate 1.0|{{0.0|4.0|-99|-99|<envelope___control___4>|<envelope___control___5>|1.0|0.0|<envelope___control___8>|<envelope___binary____op____u____gen___9>|1.0|0.0|<envelope___control___12>|<envelope___binary____op____u____gen___13>|1.0|0.0|0.0|<envelope___binary____op____u____gen___17>|1.0|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 0.25|<gate> gate 1.0|{{0.0|4.0|-99|-99|<envelope___control___4>|<envelope___control___5>|1.0|0.0|<envelope___control___8>|<envelope___binary____op____u____gen___9>|1.0|0.0|<envelope___control___12>|<envelope___binary____op____u____gen___13>|1.0|0.0|0.0|<envelope___binary____op____u____gen___17>|1.0|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 0.125|<gate> gate 1.0|{{0.0|4.0|-99|-99|<envelope___control___4>|<envelope___control___5>|1.0|0.0|<envelope___control___8>|<envelope___binary____op____u____gen___9>|1.0|0.0|<envelope___control___12>|<envelope___binary____op____u____gen___13>|1.0|0.0|0.0|<envelope___binary____op____u____gen___17>|1.0|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+21 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+76 [label = "{{ <level> level 1.0|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+79 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+55 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+62 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+31:__UG_NAME__ -> 32:b ;
+13:__UG_NAME__ -> 33:a ;
+14:__UG_NAME__ -> 34:a ;
+15:__UG_NAME__ -> 35:a ;
+31:__UG_NAME__ -> 37:b ;
+36:__UG_NAME__ -> 39:a ;
+38:__UG_NAME__ -> 39:b ;
+13:__UG_NAME__ -> 50:a ;
+14:__UG_NAME__ -> 51:a ;
+15:__UG_NAME__ -> 52:a ;
+31:__UG_NAME__ -> 54:b ;
+53:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+13:__UG_NAME__ -> 58:a ;
+14:__UG_NAME__ -> 59:a ;
+15:__UG_NAME__ -> 60:a ;
+61:__UG_NAME__ -> 63:a ;
+62:__UG_NAME__ -> 63:b ;
+49:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+21:__UG_NAME__ -> 25:a ;
+24:__UG_NAME__ -> 25:b ;
+25:__UG_NAME__ -> 29:a ;
+28:__UG_NAME__ -> 29:b ;
+40:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+44:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+39:__UG_NAME__ -> 57:a ;
+56:__UG_NAME__ -> 57:b ;
+57:__UG_NAME__ -> 64:a ;
+63:__UG_NAME__ -> 64:b ;
+66:__UG_NAME__ -> 70:a ;
+69:__UG_NAME__ -> 70:b ;
+70:__UG_NAME__ -> 74:a ;
+73:__UG_NAME__ -> 74:b ;
+17:__UG_NAME__ -> 78:b ;
+23:__UG_NAME__ -> 24:a ;
+27:__UG_NAME__ -> 28:a ;
+42:__UG_NAME__ -> 43:a ;
+46:__UG_NAME__ -> 47:a ;
+68:__UG_NAME__ -> 69:a ;
+72:__UG_NAME__ -> 73:a ;
+22:__UG_NAME__ -> 23:a ;
+26:__UG_NAME__ -> 27:a ;
+41:__UG_NAME__ -> 42:a ;
+45:__UG_NAME__ -> 46:a ;
+67:__UG_NAME__ -> 68:a ;
+71:__UG_NAME__ -> 72:a ;
+65:__UG_NAME__ -> 80:in ;
+0:__UG_NAME__ -> 30:envelope___control___0 ;
+0:__UG_NAME__ -> 30:envelope___control___4 ;
+1:__UG_NAME__ -> 30:envelope___control___5 ;
+2:__UG_NAME__ -> 30:envelope___control___6 ;
+3:__UG_NAME__ -> 30:envelope___control___7 ;
+29:__UG_NAME__ -> 30:gate ;
+16:__UG_NAME__ -> 36:envelope___control___4 ;
+12:__UG_NAME__ -> 36:envelope___control___5 ;
+18:__UG_NAME__ -> 36:envelope___control___8 ;
+33:__UG_NAME__ -> 36:envelope___binary____op____u____gen___9 ;
+18:__UG_NAME__ -> 36:envelope___control___12 ;
+34:__UG_NAME__ -> 36:envelope___binary____op____u____gen___13 ;
+35:__UG_NAME__ -> 36:envelope___binary____op____u____gen___17 ;
+4:__UG_NAME__ -> 49:envelope___control___0 ;
+4:__UG_NAME__ -> 49:envelope___control___4 ;
+5:__UG_NAME__ -> 49:envelope___control___5 ;
+6:__UG_NAME__ -> 49:envelope___control___6 ;
+7:__UG_NAME__ -> 49:envelope___control___7 ;
+48:__UG_NAME__ -> 49:gate ;
+16:__UG_NAME__ -> 53:envelope___control___4 ;
+12:__UG_NAME__ -> 53:envelope___control___5 ;
+18:__UG_NAME__ -> 53:envelope___control___8 ;
+50:__UG_NAME__ -> 53:envelope___binary____op____u____gen___9 ;
+18:__UG_NAME__ -> 53:envelope___control___12 ;
+51:__UG_NAME__ -> 53:envelope___binary____op____u____gen___13 ;
+52:__UG_NAME__ -> 53:envelope___binary____op____u____gen___17 ;
+16:__UG_NAME__ -> 61:envelope___control___4 ;
+12:__UG_NAME__ -> 61:envelope___control___5 ;
+18:__UG_NAME__ -> 61:envelope___control___8 ;
+58:__UG_NAME__ -> 61:envelope___binary____op____u____gen___9 ;
+18:__UG_NAME__ -> 61:envelope___control___12 ;
+59:__UG_NAME__ -> 61:envelope___binary____op____u____gen___13 ;
+60:__UG_NAME__ -> 61:envelope___binary____op____u____gen___17 ;
+8:__UG_NAME__ -> 75:envelope___control___0 ;
+8:__UG_NAME__ -> 75:envelope___control___4 ;
+9:__UG_NAME__ -> 75:envelope___control___5 ;
+10:__UG_NAME__ -> 75:envelope___control___6 ;
+11:__UG_NAME__ -> 75:envelope___control___7 ;
+74:__UG_NAME__ -> 75:gate ;
+0:__UG_NAME__ -> 22:in ;
+1:__UG_NAME__ -> 26:in ;
+4:__UG_NAME__ -> 41:in ;
+5:__UG_NAME__ -> 45:in ;
+8:__UG_NAME__ -> 67:in ;
+9:__UG_NAME__ -> 71:in ;
+30:__UG_NAME__ -> 31:a ;
+20:__UG_NAME__ -> 77:bus ;
+76:__UG_NAME__ -> 77:signals___pan2___0 ;
+76:__UG_NAME__ -> 77:signals___pan2___1 ;
+65:__UG_NAME__ -> 76:in ;
+75:__UG_NAME__ -> 76:pos ;
+78:__UG_NAME__ -> 79:which ;
+17:__UG_NAME__ -> 79:array___control___0 ;
+18:__UG_NAME__ -> 79:array___control___1 ;
+37:__UG_NAME__ -> 38:freq ;
+54:__UG_NAME__ -> 55:freq ;
+32:__UG_NAME__ -> 62:freq ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-prophet.dot b/etc/synthdefs/graphviz/dot/sonic-pi-prophet.dot
new file mode 100644
index 0000000..b939867
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-prophet.dot
@@ -0,0 +1,346 @@
+digraph synthdef {
+46 [label = "{{ <b> |<a> 0.1} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> 0.8} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> 0.8} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> 0.8} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> 0.8} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> 0.5} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+77 [label = "{{ <b> 0.2|<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+111 [label = "{{ <b> |<a> 1.5} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> 1.2} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> 1.2} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> 0.7|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> 1.2} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> 1.2} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> 1.2} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+86 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.01" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 110.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :res
+ default: 0.7" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <coef> coef 0.995|<in> in} |<__UG_NAME__>leak-dc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+68 [label = "{{ <freq> freq 0.2} |<__UG_NAME__>lf-noise2 }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <iphase> iphase 0.0|<freq> freq 0.4} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <iphase> iphase 0.19|<freq> freq 0.4} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <iphase> iphase 0.0|<freq> freq} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+128 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+127 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+47 [label = "{{ <width> width|<freq> freq} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+53 [label = "{{ <width> width|<freq> freq} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+59 [label = "{{ <width> width|<freq> freq} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+65 [label = "{{ <width> width|<freq> freq} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+74 [label = "{{ <width> width|<freq> freq} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+103 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+30 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq 1.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq 0.3} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+
+45:__UG_NAME__ -> 46:b ;
+51:__UG_NAME__ -> 52:b ;
+57:__UG_NAME__ -> 58:b ;
+63:__UG_NAME__ -> 64:b ;
+72:__UG_NAME__ -> 73:b ;
+74:__UG_NAME__ -> 75:b ;
+76:__UG_NAME__ -> 77:a ;
+31:__UG_NAME__ -> 79:a ;
+78:__UG_NAME__ -> 79:b ;
+79:__UG_NAME__ -> 81:a ;
+78:__UG_NAME__ -> 81:b ;
+31:__UG_NAME__ -> 111:b ;
+111:__UG_NAME__ -> 112:a ;
+103:__UG_NAME__ -> 112:b ;
+32:__UG_NAME__ -> 36:a ;
+35:__UG_NAME__ -> 36:b ;
+36:__UG_NAME__ -> 40:a ;
+39:__UG_NAME__ -> 40:b ;
+43:__UG_NAME__ -> 44:b ;
+48:__UG_NAME__ -> 49:b ;
+49:__UG_NAME__ -> 50:a ;
+47:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+55:__UG_NAME__ -> 56:b ;
+54:__UG_NAME__ -> 60:a ;
+59:__UG_NAME__ -> 60:b ;
+61:__UG_NAME__ -> 62:b ;
+60:__UG_NAME__ -> 66:a ;
+65:__UG_NAME__ -> 66:b ;
+68:__UG_NAME__ -> 69:b ;
+70:__UG_NAME__ -> 71:b ;
+66:__UG_NAME__ -> 76:a ;
+75:__UG_NAME__ -> 76:b ;
+82:__UG_NAME__ -> 86:a ;
+85:__UG_NAME__ -> 86:b ;
+86:__UG_NAME__ -> 89:a ;
+88:__UG_NAME__ -> 89:b ;
+92:__UG_NAME__ -> 97:a ;
+96:__UG_NAME__ -> 97:b ;
+97:__UG_NAME__ -> 101:a ;
+100:__UG_NAME__ -> 101:b ;
+109:__UG_NAME__ -> 117:a ;
+116:__UG_NAME__ -> 117:b ;
+117:__UG_NAME__ -> 120:a ;
+119:__UG_NAME__ -> 120:b ;
+122:__UG_NAME__ -> 124:a ;
+123:__UG_NAME__ -> 124:b ;
+124:__UG_NAME__ -> 125:a ;
+108:__UG_NAME__ -> 125:b ;
+44:__UG_NAME__ -> 45:b ;
+50:__UG_NAME__ -> 51:a ;
+56:__UG_NAME__ -> 57:a ;
+62:__UG_NAME__ -> 63:a ;
+42:__UG_NAME__ -> 67:a ;
+71:__UG_NAME__ -> 72:a ;
+17:__UG_NAME__ -> 29:b ;
+34:__UG_NAME__ -> 35:a ;
+38:__UG_NAME__ -> 39:a ;
+84:__UG_NAME__ -> 85:a ;
+87:__UG_NAME__ -> 88:a ;
+95:__UG_NAME__ -> 96:a ;
+99:__UG_NAME__ -> 100:a ;
+107:__UG_NAME__ -> 108:a ;
+115:__UG_NAME__ -> 116:a ;
+118:__UG_NAME__ -> 119:a ;
+105:__UG_NAME__ -> 123:a ;
+33:__UG_NAME__ -> 34:a ;
+37:__UG_NAME__ -> 38:a ;
+83:__UG_NAME__ -> 84:a ;
+80:__UG_NAME__ -> 87:a ;
+94:__UG_NAME__ -> 95:a ;
+98:__UG_NAME__ -> 99:a ;
+104:__UG_NAME__ -> 105:a ;
+106:__UG_NAME__ -> 107:a ;
+114:__UG_NAME__ -> 115:a ;
+110:__UG_NAME__ -> 118:a ;
+16:__UG_NAME__ -> 31:envelope___control___4 ;
+12:__UG_NAME__ -> 31:envelope___control___5 ;
+19:__UG_NAME__ -> 31:envelope___control___6 ;
+30:__UG_NAME__ -> 31:envelope___select___8 ;
+13:__UG_NAME__ -> 31:envelope___control___9 ;
+19:__UG_NAME__ -> 31:envelope___control___10 ;
+18:__UG_NAME__ -> 31:envelope___control___12 ;
+14:__UG_NAME__ -> 31:envelope___control___13 ;
+19:__UG_NAME__ -> 31:envelope___control___14 ;
+15:__UG_NAME__ -> 31:envelope___control___17 ;
+19:__UG_NAME__ -> 31:envelope___control___18 ;
+0:__UG_NAME__ -> 41:envelope___control___0 ;
+0:__UG_NAME__ -> 41:envelope___control___4 ;
+1:__UG_NAME__ -> 41:envelope___control___5 ;
+2:__UG_NAME__ -> 41:envelope___control___6 ;
+3:__UG_NAME__ -> 41:envelope___control___7 ;
+40:__UG_NAME__ -> 41:gate ;
+20:__UG_NAME__ -> 90:envelope___control___0 ;
+20:__UG_NAME__ -> 90:envelope___control___4 ;
+21:__UG_NAME__ -> 90:envelope___control___5 ;
+22:__UG_NAME__ -> 90:envelope___control___6 ;
+23:__UG_NAME__ -> 90:envelope___control___7 ;
+89:__UG_NAME__ -> 90:gate ;
+93:__UG_NAME__ -> 102:envelope___mul____add___0 ;
+93:__UG_NAME__ -> 102:envelope___mul____add___4 ;
+25:__UG_NAME__ -> 102:envelope___control___5 ;
+26:__UG_NAME__ -> 102:envelope___control___6 ;
+27:__UG_NAME__ -> 102:envelope___control___7 ;
+101:__UG_NAME__ -> 102:gate ;
+8:__UG_NAME__ -> 121:envelope___control___0 ;
+8:__UG_NAME__ -> 121:envelope___control___4 ;
+9:__UG_NAME__ -> 121:envelope___control___5 ;
+10:__UG_NAME__ -> 121:envelope___control___6 ;
+11:__UG_NAME__ -> 121:envelope___control___7 ;
+120:__UG_NAME__ -> 121:gate ;
+4:__UG_NAME__ -> 126:envelope___control___0 ;
+4:__UG_NAME__ -> 126:envelope___control___4 ;
+5:__UG_NAME__ -> 126:envelope___control___5 ;
+6:__UG_NAME__ -> 126:envelope___control___6 ;
+7:__UG_NAME__ -> 126:envelope___control___7 ;
+125:__UG_NAME__ -> 126:gate ;
+0:__UG_NAME__ -> 33:in ;
+1:__UG_NAME__ -> 37:in ;
+21:__UG_NAME__ -> 80:in ;
+20:__UG_NAME__ -> 83:in ;
+93:__UG_NAME__ -> 94:in ;
+25:__UG_NAME__ -> 98:in ;
+4:__UG_NAME__ -> 104:in ;
+5:__UG_NAME__ -> 106:in ;
+9:__UG_NAME__ -> 110:in ;
+8:__UG_NAME__ -> 114:in ;
+112:__UG_NAME__ -> 113:in ;
+69:__UG_NAME__ -> 70:freq ;
+41:__UG_NAME__ -> 42:a ;
+90:__UG_NAME__ -> 91:a ;
+24:__UG_NAME__ -> 93:in ;
+77:__UG_NAME__ -> 78:in ;
+28:__UG_NAME__ -> 128:bus ;
+127:__UG_NAME__ -> 128:signals___pan2___0 ;
+127:__UG_NAME__ -> 128:signals___pan2___1 ;
+113:__UG_NAME__ -> 127:in ;
+121:__UG_NAME__ -> 127:pos ;
+126:__UG_NAME__ -> 127:level ;
+42:__UG_NAME__ -> 47:freq ;
+46:__UG_NAME__ -> 47:width ;
+42:__UG_NAME__ -> 53:freq ;
+52:__UG_NAME__ -> 53:width ;
+42:__UG_NAME__ -> 59:freq ;
+58:__UG_NAME__ -> 59:width ;
+42:__UG_NAME__ -> 65:freq ;
+64:__UG_NAME__ -> 65:width ;
+67:__UG_NAME__ -> 74:freq ;
+73:__UG_NAME__ -> 74:width ;
+81:__UG_NAME__ -> 103:in ;
+91:__UG_NAME__ -> 103:freq ;
+102:__UG_NAME__ -> 103:rq ;
+29:__UG_NAME__ -> 30:which ;
+17:__UG_NAME__ -> 30:array___control___0 ;
+18:__UG_NAME__ -> 30:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-pulse.dot b/etc/synthdefs/graphviz/dot/sonic-pi-pulse.dot
new file mode 100644
index 0000000..39a23ee
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-pulse.dot
@@ -0,0 +1,264 @@
+digraph synthdef {
+52 [label = "{{ <b> |<a> 0.8} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+90 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+89 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+76 [label = "{{ <width> width|<freq> freq} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+50 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+51:__UG_NAME__ -> 52:b ;
+52:__UG_NAME__ -> 87:a ;
+86:__UG_NAME__ -> 87:b ;
+29:__UG_NAME__ -> 33:a ;
+32:__UG_NAME__ -> 33:b ;
+33:__UG_NAME__ -> 37:a ;
+36:__UG_NAME__ -> 37:b ;
+39:__UG_NAME__ -> 43:a ;
+42:__UG_NAME__ -> 43:b ;
+43:__UG_NAME__ -> 47:a ;
+46:__UG_NAME__ -> 47:b ;
+60:__UG_NAME__ -> 61:a ;
+55:__UG_NAME__ -> 61:b ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+67:__UG_NAME__ -> 70:a ;
+69:__UG_NAME__ -> 70:b ;
+70:__UG_NAME__ -> 74:a ;
+73:__UG_NAME__ -> 74:b ;
+81:__UG_NAME__ -> 84:a ;
+83:__UG_NAME__ -> 84:b ;
+84:__UG_NAME__ -> 85:a ;
+59:__UG_NAME__ -> 85:b ;
+17:__UG_NAME__ -> 49:b ;
+31:__UG_NAME__ -> 32:a ;
+35:__UG_NAME__ -> 36:a ;
+41:__UG_NAME__ -> 42:a ;
+45:__UG_NAME__ -> 46:a ;
+54:__UG_NAME__ -> 55:a ;
+58:__UG_NAME__ -> 59:a ;
+63:__UG_NAME__ -> 64:a ;
+68:__UG_NAME__ -> 69:a ;
+72:__UG_NAME__ -> 73:a ;
+82:__UG_NAME__ -> 83:a ;
+30:__UG_NAME__ -> 31:a ;
+34:__UG_NAME__ -> 35:a ;
+40:__UG_NAME__ -> 41:a ;
+44:__UG_NAME__ -> 45:a ;
+53:__UG_NAME__ -> 54:a ;
+57:__UG_NAME__ -> 58:a ;
+62:__UG_NAME__ -> 63:a ;
+56:__UG_NAME__ -> 68:a ;
+71:__UG_NAME__ -> 72:a ;
+80:__UG_NAME__ -> 82:a ;
+0:__UG_NAME__ -> 38:envelope___control___0 ;
+0:__UG_NAME__ -> 38:envelope___control___4 ;
+1:__UG_NAME__ -> 38:envelope___control___5 ;
+2:__UG_NAME__ -> 38:envelope___control___6 ;
+3:__UG_NAME__ -> 38:envelope___control___7 ;
+37:__UG_NAME__ -> 38:gate ;
+8:__UG_NAME__ -> 48:envelope___control___0 ;
+8:__UG_NAME__ -> 48:envelope___control___4 ;
+9:__UG_NAME__ -> 48:envelope___control___5 ;
+10:__UG_NAME__ -> 48:envelope___control___6 ;
+11:__UG_NAME__ -> 48:envelope___control___7 ;
+47:__UG_NAME__ -> 48:gate ;
+16:__UG_NAME__ -> 51:envelope___control___4 ;
+12:__UG_NAME__ -> 51:envelope___control___5 ;
+19:__UG_NAME__ -> 51:envelope___control___6 ;
+50:__UG_NAME__ -> 51:envelope___select___8 ;
+13:__UG_NAME__ -> 51:envelope___control___9 ;
+19:__UG_NAME__ -> 51:envelope___control___10 ;
+18:__UG_NAME__ -> 51:envelope___control___12 ;
+14:__UG_NAME__ -> 51:envelope___control___13 ;
+19:__UG_NAME__ -> 51:envelope___control___14 ;
+15:__UG_NAME__ -> 51:envelope___control___17 ;
+19:__UG_NAME__ -> 51:envelope___control___18 ;
+24:__UG_NAME__ -> 75:envelope___control___0 ;
+24:__UG_NAME__ -> 75:envelope___control___4 ;
+25:__UG_NAME__ -> 75:envelope___control___5 ;
+27:__UG_NAME__ -> 75:envelope___control___6 ;
+26:__UG_NAME__ -> 75:envelope___control___7 ;
+74:__UG_NAME__ -> 75:gate ;
+20:__UG_NAME__ -> 77:envelope___control___0 ;
+20:__UG_NAME__ -> 77:envelope___control___4 ;
+21:__UG_NAME__ -> 77:envelope___control___5 ;
+22:__UG_NAME__ -> 77:envelope___control___6 ;
+23:__UG_NAME__ -> 77:envelope___control___7 ;
+65:__UG_NAME__ -> 77:gate ;
+4:__UG_NAME__ -> 88:envelope___control___0 ;
+4:__UG_NAME__ -> 88:envelope___control___4 ;
+5:__UG_NAME__ -> 88:envelope___control___5 ;
+6:__UG_NAME__ -> 88:envelope___control___6 ;
+7:__UG_NAME__ -> 88:envelope___control___7 ;
+85:__UG_NAME__ -> 88:gate ;
+0:__UG_NAME__ -> 30:in ;
+1:__UG_NAME__ -> 34:in ;
+8:__UG_NAME__ -> 40:in ;
+9:__UG_NAME__ -> 44:in ;
+20:__UG_NAME__ -> 53:in ;
+24:__UG_NAME__ -> 56:in ;
+5:__UG_NAME__ -> 57:in ;
+21:__UG_NAME__ -> 62:in ;
+25:__UG_NAME__ -> 71:in ;
+4:__UG_NAME__ -> 80:in ;
+76:__UG_NAME__ -> 79:in ;
+78:__UG_NAME__ -> 79:freq ;
+38:__UG_NAME__ -> 66:a ;
+77:__UG_NAME__ -> 78:a ;
+79:__UG_NAME__ -> 86:in ;
+28:__UG_NAME__ -> 90:bus ;
+89:__UG_NAME__ -> 90:signals___pan2___0 ;
+89:__UG_NAME__ -> 90:signals___pan2___1 ;
+87:__UG_NAME__ -> 89:in ;
+48:__UG_NAME__ -> 89:pos ;
+88:__UG_NAME__ -> 89:level ;
+66:__UG_NAME__ -> 76:freq ;
+75:__UG_NAME__ -> 76:width ;
+49:__UG_NAME__ -> 50:which ;
+17:__UG_NAME__ -> 50:array___control___0 ;
+18:__UG_NAME__ -> 50:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-recorder.dot b/etc/synthdefs/graphviz/dot/sonic-pi-recorder.dot
new file mode 100644
index 0000000..a611737
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-recorder.dot
@@ -0,0 +1,16 @@
+digraph synthdef {
+0 [label = "control
+ :out-buf
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :in_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "{{ {{<channelsarray___in___0>|<channelsarray___in___1>}|channelsArray}|<bufnum> bufnum} |<__UG_NAME__>disk-out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+2 [label = "{{ <num____channels> num-channels 2|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+0:__UG_NAME__ -> 3:bufnum ;
+2:__UG_NAME__ -> 3:channelsarray___in___0 ;
+2:__UG_NAME__ -> 3:channelsarray___in___1 ;
+1:__UG_NAME__ -> 2:bus ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-saw.dot b/etc/synthdefs/graphviz/dot/sonic-pi-saw.dot
new file mode 100644
index 0000000..5001dc2
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-saw.dot
@@ -0,0 +1,225 @@
+digraph synthdef {
+53 [label = "{{ <b> |<a> 0.8} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+76 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+75 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+54 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+51 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+52:__UG_NAME__ -> 53:b ;
+53:__UG_NAME__ -> 68:a ;
+67:__UG_NAME__ -> 68:b ;
+25:__UG_NAME__ -> 29:a ;
+28:__UG_NAME__ -> 29:b ;
+29:__UG_NAME__ -> 33:a ;
+32:__UG_NAME__ -> 33:b ;
+35:__UG_NAME__ -> 39:a ;
+38:__UG_NAME__ -> 39:b ;
+39:__UG_NAME__ -> 43:a ;
+42:__UG_NAME__ -> 43:b ;
+55:__UG_NAME__ -> 59:a ;
+58:__UG_NAME__ -> 59:b ;
+59:__UG_NAME__ -> 63:a ;
+62:__UG_NAME__ -> 63:b ;
+46:__UG_NAME__ -> 72:a ;
+71:__UG_NAME__ -> 72:b ;
+72:__UG_NAME__ -> 73:a ;
+49:__UG_NAME__ -> 73:b ;
+17:__UG_NAME__ -> 50:b ;
+27:__UG_NAME__ -> 28:a ;
+31:__UG_NAME__ -> 32:a ;
+37:__UG_NAME__ -> 38:a ;
+41:__UG_NAME__ -> 42:a ;
+48:__UG_NAME__ -> 49:a ;
+57:__UG_NAME__ -> 58:a ;
+61:__UG_NAME__ -> 62:a ;
+70:__UG_NAME__ -> 71:a ;
+26:__UG_NAME__ -> 27:a ;
+30:__UG_NAME__ -> 31:a ;
+36:__UG_NAME__ -> 37:a ;
+40:__UG_NAME__ -> 41:a ;
+47:__UG_NAME__ -> 48:a ;
+56:__UG_NAME__ -> 57:a ;
+60:__UG_NAME__ -> 61:a ;
+69:__UG_NAME__ -> 70:a ;
+4:__UG_NAME__ -> 34:envelope___control___0 ;
+4:__UG_NAME__ -> 34:envelope___control___4 ;
+5:__UG_NAME__ -> 34:envelope___control___5 ;
+6:__UG_NAME__ -> 34:envelope___control___6 ;
+7:__UG_NAME__ -> 34:envelope___control___7 ;
+33:__UG_NAME__ -> 34:gate ;
+0:__UG_NAME__ -> 44:envelope___control___0 ;
+0:__UG_NAME__ -> 44:envelope___control___4 ;
+1:__UG_NAME__ -> 44:envelope___control___5 ;
+2:__UG_NAME__ -> 44:envelope___control___6 ;
+3:__UG_NAME__ -> 44:envelope___control___7 ;
+43:__UG_NAME__ -> 44:gate ;
+16:__UG_NAME__ -> 52:envelope___control___4 ;
+12:__UG_NAME__ -> 52:envelope___control___5 ;
+19:__UG_NAME__ -> 52:envelope___control___6 ;
+51:__UG_NAME__ -> 52:envelope___select___8 ;
+13:__UG_NAME__ -> 52:envelope___control___9 ;
+19:__UG_NAME__ -> 52:envelope___control___10 ;
+18:__UG_NAME__ -> 52:envelope___control___12 ;
+14:__UG_NAME__ -> 52:envelope___control___13 ;
+19:__UG_NAME__ -> 52:envelope___control___14 ;
+15:__UG_NAME__ -> 52:envelope___control___17 ;
+19:__UG_NAME__ -> 52:envelope___control___18 ;
+20:__UG_NAME__ -> 64:envelope___control___0 ;
+20:__UG_NAME__ -> 64:envelope___control___4 ;
+21:__UG_NAME__ -> 64:envelope___control___5 ;
+22:__UG_NAME__ -> 64:envelope___control___6 ;
+23:__UG_NAME__ -> 64:envelope___control___7 ;
+63:__UG_NAME__ -> 64:gate ;
+8:__UG_NAME__ -> 74:envelope___control___0 ;
+8:__UG_NAME__ -> 74:envelope___control___4 ;
+9:__UG_NAME__ -> 74:envelope___control___5 ;
+10:__UG_NAME__ -> 74:envelope___control___6 ;
+11:__UG_NAME__ -> 74:envelope___control___7 ;
+73:__UG_NAME__ -> 74:gate ;
+4:__UG_NAME__ -> 26:in ;
+5:__UG_NAME__ -> 30:in ;
+0:__UG_NAME__ -> 36:in ;
+1:__UG_NAME__ -> 40:in ;
+9:__UG_NAME__ -> 47:in ;
+20:__UG_NAME__ -> 56:in ;
+21:__UG_NAME__ -> 60:in ;
+8:__UG_NAME__ -> 69:in ;
+54:__UG_NAME__ -> 66:in ;
+65:__UG_NAME__ -> 66:freq ;
+44:__UG_NAME__ -> 45:a ;
+64:__UG_NAME__ -> 65:a ;
+66:__UG_NAME__ -> 67:in ;
+24:__UG_NAME__ -> 76:bus ;
+75:__UG_NAME__ -> 76:signals___pan2___0 ;
+75:__UG_NAME__ -> 76:signals___pan2___1 ;
+68:__UG_NAME__ -> 75:in ;
+74:__UG_NAME__ -> 75:pos ;
+34:__UG_NAME__ -> 75:level ;
+45:__UG_NAME__ -> 54:freq ;
+50:__UG_NAME__ -> 51:which ;
+17:__UG_NAME__ -> 51:array___control___0 ;
+18:__UG_NAME__ -> 51:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-sound_in.dot b/etc/synthdefs/graphviz/dot/sonic-pi-sound_in.dot
new file mode 100644
index 0000000..bfa93cf
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-sound_in.dot
@@ -0,0 +1,145 @@
+digraph synthdef {
+35 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+21 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+20 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+19 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :sustain
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :release
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :input
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+18 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+29 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+23 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <num____channels> num-channels 1|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+32 [label = "{<__UG_NAME__>num-output-buses }" style="dashed, rounded" shape=record rankdir=LR];
+46 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+45 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+22 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+31:__UG_NAME__ -> 35:a ;
+34:__UG_NAME__ -> 35:b ;
+23:__UG_NAME__ -> 27:a ;
+26:__UG_NAME__ -> 27:b ;
+27:__UG_NAME__ -> 28:a ;
+20:__UG_NAME__ -> 28:b ;
+32:__UG_NAME__ -> 33:a ;
+16:__UG_NAME__ -> 33:b ;
+30:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+38:__UG_NAME__ -> 43:a ;
+42:__UG_NAME__ -> 43:b ;
+13:__UG_NAME__ -> 21:b ;
+19:__UG_NAME__ -> 20:a ;
+25:__UG_NAME__ -> 26:a ;
+36:__UG_NAME__ -> 37:a ;
+41:__UG_NAME__ -> 42:a ;
+18:__UG_NAME__ -> 19:a ;
+24:__UG_NAME__ -> 25:a ;
+29:__UG_NAME__ -> 36:a ;
+39:__UG_NAME__ -> 41:a ;
+12:__UG_NAME__ -> 31:envelope___control___4 ;
+8:__UG_NAME__ -> 31:envelope___control___5 ;
+15:__UG_NAME__ -> 31:envelope___control___6 ;
+22:__UG_NAME__ -> 31:envelope___select___8 ;
+9:__UG_NAME__ -> 31:envelope___control___9 ;
+15:__UG_NAME__ -> 31:envelope___control___10 ;
+14:__UG_NAME__ -> 31:envelope___control___12 ;
+10:__UG_NAME__ -> 31:envelope___control___13 ;
+15:__UG_NAME__ -> 31:envelope___control___14 ;
+11:__UG_NAME__ -> 31:envelope___control___17 ;
+15:__UG_NAME__ -> 31:envelope___control___18 ;
+4:__UG_NAME__ -> 40:envelope___control___0 ;
+4:__UG_NAME__ -> 40:envelope___control___4 ;
+5:__UG_NAME__ -> 40:envelope___control___5 ;
+6:__UG_NAME__ -> 40:envelope___control___6 ;
+7:__UG_NAME__ -> 40:envelope___control___7 ;
+28:__UG_NAME__ -> 40:gate ;
+0:__UG_NAME__ -> 44:envelope___control___0 ;
+0:__UG_NAME__ -> 44:envelope___control___4 ;
+1:__UG_NAME__ -> 44:envelope___control___5 ;
+2:__UG_NAME__ -> 44:envelope___control___6 ;
+3:__UG_NAME__ -> 44:envelope___control___7 ;
+43:__UG_NAME__ -> 44:gate ;
+5:__UG_NAME__ -> 18:in ;
+4:__UG_NAME__ -> 24:in ;
+0:__UG_NAME__ -> 29:in ;
+1:__UG_NAME__ -> 39:in ;
+33:__UG_NAME__ -> 34:bus ;
+17:__UG_NAME__ -> 46:bus ;
+45:__UG_NAME__ -> 46:signals___pan2___0 ;
+45:__UG_NAME__ -> 46:signals___pan2___1 ;
+35:__UG_NAME__ -> 45:in ;
+40:__UG_NAME__ -> 45:pos ;
+44:__UG_NAME__ -> 45:level ;
+21:__UG_NAME__ -> 22:which ;
+13:__UG_NAME__ -> 22:array___control___0 ;
+14:__UG_NAME__ -> 22:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-sound_in_stereo.dot b/etc/synthdefs/graphviz/dot/sonic-pi-sound_in_stereo.dot
new file mode 100644
index 0000000..f804b89
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-sound_in_stereo.dot
@@ -0,0 +1,173 @@
+digraph synthdef {
+25 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+30 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+23 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+19 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <level> level|<pos> pos|<right> right|<left> left} |<__UG_NAME__>balance2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :sustain
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :release
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :input
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+18 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+24 [label = "{{ <num____channels> num-channels 1|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+29 [label = "{{ <num____channels> num-channels 1|<bus> bus} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
+22 [label = "{<__UG_NAME__>num-output-buses }" style="dashed, rounded" shape=record rankdir=LR];
+26 [label = "{<__UG_NAME__>num-output-buses }" style="dashed, rounded" shape=record rankdir=LR];
+55 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>|<signals___pan2___2>|<signals___pan2___3>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+52 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+54 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+20 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+21:__UG_NAME__ -> 25:a ;
+24:__UG_NAME__ -> 25:b ;
+21:__UG_NAME__ -> 30:a ;
+29:__UG_NAME__ -> 30:b ;
+21:__UG_NAME__ -> 51:a ;
+50:__UG_NAME__ -> 51:b ;
+21:__UG_NAME__ -> 53:a ;
+50:__UG_NAME__ -> 53:b ;
+22:__UG_NAME__ -> 23:a ;
+16:__UG_NAME__ -> 23:b ;
+16:__UG_NAME__ -> 27:a ;
+26:__UG_NAME__ -> 28:a ;
+27:__UG_NAME__ -> 28:b ;
+31:__UG_NAME__ -> 34:a ;
+33:__UG_NAME__ -> 34:b ;
+34:__UG_NAME__ -> 38:a ;
+37:__UG_NAME__ -> 38:b ;
+40:__UG_NAME__ -> 44:a ;
+43:__UG_NAME__ -> 44:b ;
+44:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+13:__UG_NAME__ -> 19:b ;
+32:__UG_NAME__ -> 33:a ;
+36:__UG_NAME__ -> 37:a ;
+42:__UG_NAME__ -> 43:a ;
+46:__UG_NAME__ -> 47:a ;
+18:__UG_NAME__ -> 32:a ;
+35:__UG_NAME__ -> 36:a ;
+41:__UG_NAME__ -> 42:a ;
+45:__UG_NAME__ -> 46:a ;
+25:__UG_NAME__ -> 50:left ;
+30:__UG_NAME__ -> 50:right ;
+39:__UG_NAME__ -> 50:pos ;
+49:__UG_NAME__ -> 50:level ;
+12:__UG_NAME__ -> 21:envelope___control___4 ;
+8:__UG_NAME__ -> 21:envelope___control___5 ;
+15:__UG_NAME__ -> 21:envelope___control___6 ;
+20:__UG_NAME__ -> 21:envelope___select___8 ;
+9:__UG_NAME__ -> 21:envelope___control___9 ;
+15:__UG_NAME__ -> 21:envelope___control___10 ;
+14:__UG_NAME__ -> 21:envelope___control___12 ;
+10:__UG_NAME__ -> 21:envelope___control___13 ;
+15:__UG_NAME__ -> 21:envelope___control___14 ;
+11:__UG_NAME__ -> 21:envelope___control___17 ;
+15:__UG_NAME__ -> 21:envelope___control___18 ;
+4:__UG_NAME__ -> 39:envelope___control___0 ;
+4:__UG_NAME__ -> 39:envelope___control___4 ;
+5:__UG_NAME__ -> 39:envelope___control___5 ;
+6:__UG_NAME__ -> 39:envelope___control___6 ;
+7:__UG_NAME__ -> 39:envelope___control___7 ;
+38:__UG_NAME__ -> 39:gate ;
+0:__UG_NAME__ -> 49:envelope___control___0 ;
+0:__UG_NAME__ -> 49:envelope___control___4 ;
+1:__UG_NAME__ -> 49:envelope___control___5 ;
+2:__UG_NAME__ -> 49:envelope___control___6 ;
+3:__UG_NAME__ -> 49:envelope___control___7 ;
+48:__UG_NAME__ -> 49:gate ;
+4:__UG_NAME__ -> 18:in ;
+5:__UG_NAME__ -> 35:in ;
+0:__UG_NAME__ -> 41:in ;
+1:__UG_NAME__ -> 45:in ;
+23:__UG_NAME__ -> 24:bus ;
+28:__UG_NAME__ -> 29:bus ;
+17:__UG_NAME__ -> 55:bus ;
+52:__UG_NAME__ -> 55:signals___pan2___0 ;
+52:__UG_NAME__ -> 55:signals___pan2___1 ;
+54:__UG_NAME__ -> 55:signals___pan2___2 ;
+54:__UG_NAME__ -> 55:signals___pan2___3 ;
+51:__UG_NAME__ -> 52:in ;
+39:__UG_NAME__ -> 52:pos ;
+49:__UG_NAME__ -> 52:level ;
+53:__UG_NAME__ -> 54:in ;
+39:__UG_NAME__ -> 54:pos ;
+49:__UG_NAME__ -> 54:level ;
+19:__UG_NAME__ -> 20:which ;
+13:__UG_NAME__ -> 20:array___control___0 ;
+14:__UG_NAME__ -> 20:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-square.dot b/etc/synthdefs/graphviz/dot/sonic-pi-square.dot
new file mode 100644
index 0000000..3bf6660
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-square.dot
@@ -0,0 +1,225 @@
+digraph synthdef {
+72 [label = "{{ <b> |<a> 0.8} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+76 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+75 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+66 [label = "{{ <width> width 0.5|<freq> freq} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+29 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+70:__UG_NAME__ -> 72:b ;
+72:__UG_NAME__ -> 74:a ;
+73:__UG_NAME__ -> 74:b ;
+31:__UG_NAME__ -> 34:a ;
+33:__UG_NAME__ -> 34:b ;
+26:__UG_NAME__ -> 41:a ;
+40:__UG_NAME__ -> 41:b ;
+41:__UG_NAME__ -> 42:a ;
+37:__UG_NAME__ -> 42:b ;
+34:__UG_NAME__ -> 47:a ;
+46:__UG_NAME__ -> 47:b ;
+52:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+25:__UG_NAME__ -> 60:a ;
+59:__UG_NAME__ -> 60:b ;
+60:__UG_NAME__ -> 61:a ;
+49:__UG_NAME__ -> 61:b ;
+56:__UG_NAME__ -> 63:a ;
+62:__UG_NAME__ -> 63:b ;
+17:__UG_NAME__ -> 28:b ;
+32:__UG_NAME__ -> 33:a ;
+36:__UG_NAME__ -> 37:a ;
+39:__UG_NAME__ -> 40:a ;
+45:__UG_NAME__ -> 46:a ;
+48:__UG_NAME__ -> 49:a ;
+54:__UG_NAME__ -> 55:a ;
+58:__UG_NAME__ -> 59:a ;
+51:__UG_NAME__ -> 62:a ;
+30:__UG_NAME__ -> 32:a ;
+35:__UG_NAME__ -> 36:a ;
+38:__UG_NAME__ -> 39:a ;
+44:__UG_NAME__ -> 45:a ;
+27:__UG_NAME__ -> 48:a ;
+50:__UG_NAME__ -> 51:a ;
+53:__UG_NAME__ -> 54:a ;
+57:__UG_NAME__ -> 58:a ;
+4:__UG_NAME__ -> 43:envelope___control___0 ;
+4:__UG_NAME__ -> 43:envelope___control___4 ;
+5:__UG_NAME__ -> 43:envelope___control___5 ;
+6:__UG_NAME__ -> 43:envelope___control___6 ;
+7:__UG_NAME__ -> 43:envelope___control___7 ;
+42:__UG_NAME__ -> 43:gate ;
+0:__UG_NAME__ -> 64:envelope___control___0 ;
+0:__UG_NAME__ -> 64:envelope___control___4 ;
+1:__UG_NAME__ -> 64:envelope___control___5 ;
+2:__UG_NAME__ -> 64:envelope___control___6 ;
+3:__UG_NAME__ -> 64:envelope___control___7 ;
+63:__UG_NAME__ -> 64:gate ;
+20:__UG_NAME__ -> 67:envelope___control___0 ;
+20:__UG_NAME__ -> 67:envelope___control___4 ;
+21:__UG_NAME__ -> 67:envelope___control___5 ;
+22:__UG_NAME__ -> 67:envelope___control___6 ;
+23:__UG_NAME__ -> 67:envelope___control___7 ;
+47:__UG_NAME__ -> 67:gate ;
+16:__UG_NAME__ -> 70:envelope___control___4 ;
+12:__UG_NAME__ -> 70:envelope___control___5 ;
+19:__UG_NAME__ -> 70:envelope___control___6 ;
+29:__UG_NAME__ -> 70:envelope___select___8 ;
+13:__UG_NAME__ -> 70:envelope___control___9 ;
+19:__UG_NAME__ -> 70:envelope___control___10 ;
+18:__UG_NAME__ -> 70:envelope___control___12 ;
+14:__UG_NAME__ -> 70:envelope___control___13 ;
+19:__UG_NAME__ -> 70:envelope___control___14 ;
+15:__UG_NAME__ -> 70:envelope___control___17 ;
+19:__UG_NAME__ -> 70:envelope___control___18 ;
+8:__UG_NAME__ -> 71:envelope___control___0 ;
+8:__UG_NAME__ -> 71:envelope___control___4 ;
+9:__UG_NAME__ -> 71:envelope___control___5 ;
+10:__UG_NAME__ -> 71:envelope___control___6 ;
+11:__UG_NAME__ -> 71:envelope___control___7 ;
+61:__UG_NAME__ -> 71:gate ;
+9:__UG_NAME__ -> 27:in ;
+20:__UG_NAME__ -> 30:in ;
+5:__UG_NAME__ -> 35:in ;
+4:__UG_NAME__ -> 38:in ;
+21:__UG_NAME__ -> 44:in ;
+1:__UG_NAME__ -> 50:in ;
+0:__UG_NAME__ -> 53:in ;
+8:__UG_NAME__ -> 57:in ;
+66:__UG_NAME__ -> 69:in ;
+68:__UG_NAME__ -> 69:freq ;
+64:__UG_NAME__ -> 65:a ;
+67:__UG_NAME__ -> 68:a ;
+69:__UG_NAME__ -> 73:in ;
+24:__UG_NAME__ -> 76:bus ;
+75:__UG_NAME__ -> 76:signals___pan2___0 ;
+75:__UG_NAME__ -> 76:signals___pan2___1 ;
+74:__UG_NAME__ -> 75:in ;
+71:__UG_NAME__ -> 75:pos ;
+43:__UG_NAME__ -> 75:level ;
+65:__UG_NAME__ -> 66:freq ;
+28:__UG_NAME__ -> 29:which ;
+17:__UG_NAME__ -> 29:array___control___0 ;
+18:__UG_NAME__ -> 29:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-stereo_player.dot b/etc/synthdefs/graphviz/dot/sonic-pi-stereo_player.dot
new file mode 100644
index 0000000..b746e59
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-stereo_player.dot
@@ -0,0 +1,1199 @@
+digraph synthdef {
+175 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+176 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+182 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+187 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+331 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+340 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+341 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+105 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+162 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+166 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+192 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+196 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+203 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+205 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+211 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+215 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+238 [label = "{{ <b> |<a> 0.1} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+268 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+272 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+280 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+284 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+303 [label = "{{ <b> |<a> 0.1} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+320 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+342 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+348 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+352 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+357 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+363 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+367 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+372 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+373 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+379 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+383 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+393 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+397 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+401 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+402 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+403 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+405 [label = "{{ <b> |<a> 0.03} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+174 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="dashed, rounded" shape=record rankdir=LR];
+233 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+235 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+236 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+298 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+300 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+301 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+325 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+326 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+327 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+184 [label = "{{ <b> |<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+343 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+232 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+297 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+322 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
+324 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+161 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+165 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+191 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+195 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+202 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+204 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+210 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+214 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+267 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+271 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+279 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+283 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+319 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+347 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+351 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+356 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+362 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+366 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+371 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+378 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+382 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+392 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+396 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+140 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+160 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+164 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+183 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+190 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+194 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+201 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+209 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+213 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+266 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+270 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+278 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+282 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+318 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+346 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+350 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+355 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+361 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+365 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+370 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+377 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+381 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+391 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+395 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+181 [label = "{{ <b> |<a> } |<__UG_NAME__>absdif }" style="bold, rounded" shape=record rankdir=LR];
+399 [label = "{{ <level> level|<pos> pos|<right> right|<left> left} |<__UG_NAME__>balance2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+180 [label = "{{ <buf> buf} |<__UG_NAME__>buf-dur }" style="dashed, rounded" shape=record rankdir=LR];
+173 [label = "{{ <buf> buf} |<__UG_NAME__>buf-frames }" style="dashed, rounded" shape=record rankdir=LR];
+186 [label = "{{ <interpolation> interpolation 2.0|<loop> loop 1.0|<phase> phase|<bufnum> bufnum|<num____channels> num-channels 2} |<__UG_NAME__>buf-rd }" style="filled, bold, rounded"  shape=record rankdir=LR];
+385 [label = "{{ <relax____time> relax-time|<clamp____time> clamp-time|<slope____above> slope-above|<slope____below> slope-below|<thresh> thresh|<control> control|<in> in} |<__UG_NAME__>compander }" style="filled, bold, rounded"  shape=record rankdir=LR];
+387 [label = "{{ <relax____time> relax-time|<clamp____time> clamp-time|<slope____above> slope-above|<slope____below> slope-below|<thresh> thresh|<control> control|<in> in} |<__UG_NAME__>compander }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :buf
+ default: 0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+1 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+2 [label = "control
+ :decay
+ default: 0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+3 [label = "control
+ :sustain
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+4 [label = "control
+ :release
+ default: 0.0" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+5 [label = "control
+ :attack_level
+ default: 1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+6 [label = "control
+ :decay_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+7 [label = "control
+ :sustain_level
+ default: 1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+8 [label = "control
+ :lpf_init_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+9 [label = "control
+ :lpf_attack_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+10 [label = "control
+ :lpf_decay_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+11 [label = "control
+ :lpf_sustain_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+12 [label = "control
+ :lpf_release_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+13 [label = "control
+ :hpf_init_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+14 [label = "control
+ :hpf_attack_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+15 [label = "control
+ :hpf_decay_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+16 [label = "control
+ :hpf_sustain_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+17 [label = "control
+ :hpf_release_level
+ default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
+18 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :rate
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :start
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :finish
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :lpf
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :lpf_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :lpf_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :lpf_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :lpf_attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :lpf_sustain
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :lpf_decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "control
+ :lpf_release
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "control
+ :lpf_min
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "control
+ :lpf_min_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+40 [label = "control
+ :lpf_min_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+41 [label = "control
+ :lpf_min_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+42 [label = "control
+ :lpf_env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "control
+ :hpf
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+44 [label = "control
+ :hpf_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+45 [label = "control
+ :hpf_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+46 [label = "control
+ :hpf_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+47 [label = "control
+ :hpf_max
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+48 [label = "control
+ :hpf_max_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+49 [label = "control
+ :hpf_max_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+50 [label = "control
+ :hpf_max_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+51 [label = "control
+ :hpf_attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+52 [label = "control
+ :hpf_sustain
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+53 [label = "control
+ :hpf_decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+54 [label = "control
+ :hpf_release
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+55 [label = "control
+ :hpf_env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+56 [label = "control
+ :norm
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+57 [label = "control
+ :pitch
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+58 [label = "control
+ :pitch_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+59 [label = "control
+ :pitch_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+60 [label = "control
+ :pitch_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+61 [label = "control
+ :window_size
+ default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+62 [label = "control
+ :window_size_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+63 [label = "control
+ :window_size_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+64 [label = "control
+ :window_size_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+65 [label = "control
+ :pitch_dis
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+66 [label = "control
+ :pitch_dis_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+67 [label = "control
+ :pitch_dis_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+68 [label = "control
+ :pitch_dis_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+69 [label = "control
+ :time_dis
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+70 [label = "control
+ :time_dis_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+71 [label = "control
+ :time_dis_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+72 [label = "control
+ :time_dis_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+73 [label = "control
+ :compress
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+74 [label = "control
+ :pre_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+75 [label = "control
+ :pre_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+76 [label = "control
+ :pre_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+77 [label = "control
+ :pre_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+78 [label = "control
+ :threshold
+ default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+79 [label = "control
+ :threshold_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+80 [label = "control
+ :threshold_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+81 [label = "control
+ :threshold_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+82 [label = "control
+ :clamp_time
+ default: 0.01" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+83 [label = "control
+ :clamp_time_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+84 [label = "control
+ :clamp_time_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+85 [label = "control
+ :clamp_time_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+86 [label = "control
+ :slope_above
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+87 [label = "control
+ :slope_above_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+88 [label = "control
+ :slope_above_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+89 [label = "control
+ :slope_above_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+90 [label = "control
+ :slope_below
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+91 [label = "control
+ :slope_below_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+92 [label = "control
+ :slope_below_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+93 [label = "control
+ :slope_below_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+94 [label = "control
+ :relax_time
+ default: 0.01" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+95 [label = "control
+ :relax_time_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+96 [label = "control
+ :relax_time_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+97 [label = "control
+ :relax_time_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+98 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+110 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+143 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+167 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+197 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+206 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+216 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+239 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{<envelope___select___0>|4|-99|-99|<envelope___select___4>|<envelope___select___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___select___9>|<envelope___control___10>|0.0|<envelope___select___12>|<envelope___select___13>|<envelope___control___14>|0.0|<envelope___select___16>|<envelope___binary____op____u____gen___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+273 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+285 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+304 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{<envelope___select___0>|4|-99|-99|<envelope___select___4>|<envelope___select___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___select___9>|<envelope___control___10>|0.0|<envelope___select___12>|<envelope___select___13>|<envelope___control___14>|0.0|<envelope___select___16>|<envelope___binary____op____u____gen___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+329 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___select___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+353 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+358 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+368 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+374 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+384 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+398 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+311 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+336 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+99 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+159 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+163 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+189 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+193 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+200 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+208 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+212 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+265 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+269 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+277 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+281 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+317 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+321 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+345 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+349 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+354 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+360 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+364 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+376 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+380 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+390 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+394 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+134 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+158 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+188 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+199 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+207 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+264 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+276 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+316 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+344 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+359 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+369 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+375 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+389 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+185 [label = "{{ <action> action 0.0|<dur> dur|<end> end|<start> start} |<__UG_NAME__>line }" style="filled, bold, rounded"  shape=record rankdir=LR];
+406 [label = "{{ <action> action 2.0|<dur> dur|<end> end 1.0|<start> start 1.0} |<__UG_NAME__>line }" style="bold, rounded" shape=record rankdir=LR];
+245 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+334 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+242 [label = "{{ <b> |<a> } |<__UG_NAME__>max }" style="bold, rounded" shape=record rankdir=LR];
+309 [label = "{{ <b> |<a> } |<__UG_NAME__>max }" style="bold, rounded" shape=record rankdir=LR];
+220 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+240 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+241 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+288 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+305 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+307 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+198 [label = "{{ <b> |<a> } |<__UG_NAME__>midiratio }" style="bold, rounded" shape=record rankdir=LR];
+243 [label = "{{ <b> |<a> } |<__UG_NAME__>min }" style="bold, rounded" shape=record rankdir=LR];
+308 [label = "{{ <b> |<a> } |<__UG_NAME__>min }" style="bold, rounded" shape=record rankdir=LR];
+404 [label = "{{ <b> |<a> } |<__UG_NAME__>min }" style="bold, rounded" shape=record rankdir=LR];
+314 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+338 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+172 [label = "{{ <b> |<a> } |<__UG_NAME__>not-pos? }" style="bold, rounded" shape=record rankdir=LR];
+178 [label = "{{ <b> |<a> } |<__UG_NAME__>not-pos? }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+145 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+146 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+148 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+150 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+152 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+154 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+156 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+168 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+171 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+221 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+224 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+247 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+248 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+250 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+252 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+254 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
+256 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+258 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+260 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+262 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+274 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+286 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+330 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
+147 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
+149 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
+151 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+153 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+155 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+157 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+169 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+170 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+249 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
+251 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
+253 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
+255 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
+257 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+259 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+261 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+263 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+275 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+312 [label = "{{ <b> |<a> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
+400 [label = "{{ {{<signals___balance2___0>|<signals___balance2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+217 [label = "{{ <time____dispersion> time-dispersion|<pitch____dispersion> pitch-dispersion|<pitch____ratio> pitch-ratio|<window____size> window-size|<in> in} |<__UG_NAME__>pitch-shift }" style="filled, bold, rounded"  shape=record rankdir=LR];
+332 [label = "{{ <time____dispersion> time-dispersion|<pitch____dispersion> pitch-dispersion|<pitch____ratio> pitch-ratio|<window____size> window-size|<in> in} |<__UG_NAME__>pitch-shift }" style="filled, bold, rounded"  shape=record rankdir=LR];
+177 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+179 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+218 [label = "{{ {{<array___binary____op____u____gen___0>|<array___pitch____shift___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+219 [label = "{{ {{130|<array___env____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+222 [label = "{{ {{30|<array___env____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+223 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+225 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+226 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+227 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+228 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+229 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+230 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+231 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+234 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+237 [label = "{{ {{<array___select___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+244 [label = "{{ {{<array___unary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+246 [label = "{{ {{<array___select___0>|<array___lpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+287 [label = "{{ {{50|<array___env____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+289 [label = "{{ {{130|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+290 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+291 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+292 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+293 [label = "{{ {{<array___select___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+294 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+295 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+296 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+299 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+302 [label = "{{ {{<array___select___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+306 [label = "{{ {{200|<array___env____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+310 [label = "{{ {{<array___unary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+313 [label = "{{ {{<array___select___0>|<array___hpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+315 [label = "{{ {{<array___select___0>|<array___normalizer___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+323 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+328 [label = "{{ {{<array___control___0>|<array___binary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+333 [label = "{{ {{<array___binary____op____u____gen___0>|<array___pitch____shift___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+335 [label = "{{ {{<array___select___0>|<array___lpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+337 [label = "{{ {{<array___select___0>|<array___hpf___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+339 [label = "{{ {{<array___select___0>|<array___normalizer___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+386 [label = "{{ {{<array___binary____op____u____gen___0>|<array___compander___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+388 [label = "{{ {{<array___binary____op____u____gen___0>|<array___compander___1>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+28:__UG_NAME__ -> 175:a ;
+174:__UG_NAME__ -> 175:b ;
+29:__UG_NAME__ -> 176:a ;
+174:__UG_NAME__ -> 176:b ;
+180:__UG_NAME__ -> 182:a ;
+181:__UG_NAME__ -> 182:b ;
+133:__UG_NAME__ -> 187:a ;
+186:__UG_NAME__ -> 187:b ;
+133:__UG_NAME__ -> 331:a ;
+186:__UG_NAME__ -> 331:b ;
+329:__UG_NAME__ -> 340:a ;
+339:__UG_NAME__ -> 340:b ;
+329:__UG_NAME__ -> 341:a ;
+315:__UG_NAME__ -> 341:b ;
+101:__UG_NAME__ -> 105:a ;
+104:__UG_NAME__ -> 105:b ;
+105:__UG_NAME__ -> 109:a ;
+108:__UG_NAME__ -> 109:b ;
+111:__UG_NAME__ -> 115:a ;
+114:__UG_NAME__ -> 115:b ;
+115:__UG_NAME__ -> 119:a ;
+118:__UG_NAME__ -> 119:b ;
+124:__UG_NAME__ -> 128:a ;
+127:__UG_NAME__ -> 128:b ;
+128:__UG_NAME__ -> 132:a ;
+131:__UG_NAME__ -> 132:b ;
+134:__UG_NAME__ -> 138:a ;
+137:__UG_NAME__ -> 138:b ;
+138:__UG_NAME__ -> 142:a ;
+141:__UG_NAME__ -> 142:b ;
+158:__UG_NAME__ -> 162:a ;
+161:__UG_NAME__ -> 162:b ;
+162:__UG_NAME__ -> 166:a ;
+165:__UG_NAME__ -> 166:b ;
+188:__UG_NAME__ -> 192:a ;
+191:__UG_NAME__ -> 192:b ;
+192:__UG_NAME__ -> 196:a ;
+195:__UG_NAME__ -> 196:b ;
+199:__UG_NAME__ -> 203:a ;
+202:__UG_NAME__ -> 203:b ;
+203:__UG_NAME__ -> 205:a ;
+204:__UG_NAME__ -> 205:b ;
+207:__UG_NAME__ -> 211:a ;
+210:__UG_NAME__ -> 211:b ;
+211:__UG_NAME__ -> 215:a ;
+214:__UG_NAME__ -> 215:b ;
+234:__UG_NAME__ -> 238:b ;
+264:__UG_NAME__ -> 268:a ;
+267:__UG_NAME__ -> 268:b ;
+268:__UG_NAME__ -> 272:a ;
+271:__UG_NAME__ -> 272:b ;
+276:__UG_NAME__ -> 280:a ;
+279:__UG_NAME__ -> 280:b ;
+280:__UG_NAME__ -> 284:a ;
+283:__UG_NAME__ -> 284:b ;
+299:__UG_NAME__ -> 303:b ;
+316:__UG_NAME__ -> 320:a ;
+319:__UG_NAME__ -> 320:b ;
+341:__UG_NAME__ -> 342:a ;
+340:__UG_NAME__ -> 342:b ;
+344:__UG_NAME__ -> 348:a ;
+347:__UG_NAME__ -> 348:b ;
+348:__UG_NAME__ -> 352:a ;
+351:__UG_NAME__ -> 352:b ;
+320:__UG_NAME__ -> 357:a ;
+356:__UG_NAME__ -> 357:b ;
+359:__UG_NAME__ -> 363:a ;
+362:__UG_NAME__ -> 363:b ;
+363:__UG_NAME__ -> 367:a ;
+366:__UG_NAME__ -> 367:b ;
+369:__UG_NAME__ -> 372:a ;
+371:__UG_NAME__ -> 372:b ;
+372:__UG_NAME__ -> 373:a ;
+123:__UG_NAME__ -> 373:b ;
+375:__UG_NAME__ -> 379:a ;
+378:__UG_NAME__ -> 379:b ;
+379:__UG_NAME__ -> 383:a ;
+382:__UG_NAME__ -> 383:b ;
+389:__UG_NAME__ -> 393:a ;
+392:__UG_NAME__ -> 393:b ;
+393:__UG_NAME__ -> 397:a ;
+396:__UG_NAME__ -> 397:b ;
+1:__UG_NAME__ -> 401:a ;
+328:__UG_NAME__ -> 401:b ;
+401:__UG_NAME__ -> 402:a ;
+2:__UG_NAME__ -> 402:b ;
+402:__UG_NAME__ -> 403:a ;
+4:__UG_NAME__ -> 403:b ;
+404:__UG_NAME__ -> 405:b ;
+173:__UG_NAME__ -> 174:a ;
+184:__UG_NAME__ -> 233:a ;
+229:__UG_NAME__ -> 233:b ;
+233:__UG_NAME__ -> 235:a ;
+234:__UG_NAME__ -> 235:b ;
+235:__UG_NAME__ -> 236:a ;
+230:__UG_NAME__ -> 236:b ;
+184:__UG_NAME__ -> 298:a ;
+294:__UG_NAME__ -> 298:b ;
+298:__UG_NAME__ -> 300:a ;
+299:__UG_NAME__ -> 300:b ;
+300:__UG_NAME__ -> 301:a ;
+295:__UG_NAME__ -> 301:b ;
+184:__UG_NAME__ -> 325:a ;
+1:__UG_NAME__ -> 325:b ;
+325:__UG_NAME__ -> 326:a ;
+4:__UG_NAME__ -> 326:b ;
+326:__UG_NAME__ -> 327:a ;
+2:__UG_NAME__ -> 327:b ;
+182:__UG_NAME__ -> 184:a ;
+183:__UG_NAME__ -> 184:b ;
+342:__UG_NAME__ -> 343:a ;
+231:__UG_NAME__ -> 232:b ;
+296:__UG_NAME__ -> 297:b ;
+6:__UG_NAME__ -> 322:b ;
+3:__UG_NAME__ -> 324:b ;
+103:__UG_NAME__ -> 104:a ;
+107:__UG_NAME__ -> 108:a ;
+113:__UG_NAME__ -> 114:a ;
+117:__UG_NAME__ -> 118:a ;
+122:__UG_NAME__ -> 123:a ;
+126:__UG_NAME__ -> 127:a ;
+130:__UG_NAME__ -> 131:a ;
+136:__UG_NAME__ -> 137:a ;
+140:__UG_NAME__ -> 141:a ;
+160:__UG_NAME__ -> 161:a ;
+164:__UG_NAME__ -> 165:a ;
+190:__UG_NAME__ -> 191:a ;
+194:__UG_NAME__ -> 195:a ;
+201:__UG_NAME__ -> 202:a ;
+100:__UG_NAME__ -> 204:a ;
+209:__UG_NAME__ -> 210:a ;
+213:__UG_NAME__ -> 214:a ;
+266:__UG_NAME__ -> 267:a ;
+270:__UG_NAME__ -> 271:a ;
+278:__UG_NAME__ -> 279:a ;
+282:__UG_NAME__ -> 283:a ;
+318:__UG_NAME__ -> 319:a ;
+346:__UG_NAME__ -> 347:a ;
+350:__UG_NAME__ -> 351:a ;
+355:__UG_NAME__ -> 356:a ;
+361:__UG_NAME__ -> 362:a ;
+365:__UG_NAME__ -> 366:a ;
+370:__UG_NAME__ -> 371:a ;
+377:__UG_NAME__ -> 378:a ;
+381:__UG_NAME__ -> 382:a ;
+391:__UG_NAME__ -> 392:a ;
+395:__UG_NAME__ -> 396:a ;
+99:__UG_NAME__ -> 100:a ;
+102:__UG_NAME__ -> 103:a ;
+106:__UG_NAME__ -> 107:a ;
+112:__UG_NAME__ -> 113:a ;
+116:__UG_NAME__ -> 117:a ;
+121:__UG_NAME__ -> 122:a ;
+125:__UG_NAME__ -> 126:a ;
+129:__UG_NAME__ -> 130:a ;
+135:__UG_NAME__ -> 136:a ;
+139:__UG_NAME__ -> 140:a ;
+159:__UG_NAME__ -> 160:a ;
+163:__UG_NAME__ -> 164:a ;
+27:__UG_NAME__ -> 183:a ;
+189:__UG_NAME__ -> 190:a ;
+193:__UG_NAME__ -> 194:a ;
+200:__UG_NAME__ -> 201:a ;
+208:__UG_NAME__ -> 209:a ;
+212:__UG_NAME__ -> 213:a ;
+265:__UG_NAME__ -> 266:a ;
+269:__UG_NAME__ -> 270:a ;
+277:__UG_NAME__ -> 278:a ;
+281:__UG_NAME__ -> 282:a ;
+317:__UG_NAME__ -> 318:a ;
+345:__UG_NAME__ -> 346:a ;
+349:__UG_NAME__ -> 350:a ;
+354:__UG_NAME__ -> 355:a ;
+360:__UG_NAME__ -> 361:a ;
+364:__UG_NAME__ -> 365:a ;
+321:__UG_NAME__ -> 370:a ;
+376:__UG_NAME__ -> 377:a ;
+380:__UG_NAME__ -> 381:a ;
+390:__UG_NAME__ -> 391:a ;
+394:__UG_NAME__ -> 395:a ;
+29:__UG_NAME__ -> 181:a ;
+28:__UG_NAME__ -> 181:b ;
+388:__UG_NAME__ -> 399:left ;
+386:__UG_NAME__ -> 399:right ;
+398:__UG_NAME__ -> 399:pos ;
+110:__UG_NAME__ -> 399:level ;
+0:__UG_NAME__ -> 180:buf ;
+0:__UG_NAME__ -> 173:buf ;
+0:__UG_NAME__ -> 186:bufnum ;
+185:__UG_NAME__ -> 186:phase ;
+340:__UG_NAME__ -> 385:in ;
+343:__UG_NAME__ -> 385:control ;
+353:__UG_NAME__ -> 385:thresh ;
+358:__UG_NAME__ -> 385:slope____below ;
+368:__UG_NAME__ -> 385:slope____above ;
+374:__UG_NAME__ -> 385:clamp____time ;
+384:__UG_NAME__ -> 385:relax____time ;
+341:__UG_NAME__ -> 387:in ;
+343:__UG_NAME__ -> 387:control ;
+353:__UG_NAME__ -> 387:thresh ;
+358:__UG_NAME__ -> 387:slope____below ;
+368:__UG_NAME__ -> 387:slope____above ;
+374:__UG_NAME__ -> 387:clamp____time ;
+384:__UG_NAME__ -> 387:relax____time ;
+18:__UG_NAME__ -> 110:envelope___control___0 ;
+18:__UG_NAME__ -> 110:envelope___control___4 ;
+19:__UG_NAME__ -> 110:envelope___control___5 ;
+20:__UG_NAME__ -> 110:envelope___control___6 ;
+21:__UG_NAME__ -> 110:envelope___control___7 ;
+109:__UG_NAME__ -> 110:gate ;
+57:__UG_NAME__ -> 120:envelope___control___0 ;
+57:__UG_NAME__ -> 120:envelope___control___4 ;
+58:__UG_NAME__ -> 120:envelope___control___5 ;
+59:__UG_NAME__ -> 120:envelope___control___6 ;
+60:__UG_NAME__ -> 120:envelope___control___7 ;
+119:__UG_NAME__ -> 120:gate ;
+74:__UG_NAME__ -> 133:envelope___control___0 ;
+74:__UG_NAME__ -> 133:envelope___control___4 ;
+75:__UG_NAME__ -> 133:envelope___control___5 ;
+76:__UG_NAME__ -> 133:envelope___control___6 ;
+77:__UG_NAME__ -> 133:envelope___control___7 ;
+132:__UG_NAME__ -> 133:gate ;
+30:__UG_NAME__ -> 143:envelope___control___0 ;
+30:__UG_NAME__ -> 143:envelope___control___4 ;
+31:__UG_NAME__ -> 143:envelope___control___5 ;
+32:__UG_NAME__ -> 143:envelope___control___6 ;
+33:__UG_NAME__ -> 143:envelope___control___7 ;
+142:__UG_NAME__ -> 143:gate ;
+38:__UG_NAME__ -> 167:envelope___control___0 ;
+38:__UG_NAME__ -> 167:envelope___control___4 ;
+39:__UG_NAME__ -> 167:envelope___control___5 ;
+40:__UG_NAME__ -> 167:envelope___control___6 ;
+41:__UG_NAME__ -> 167:envelope___control___7 ;
+166:__UG_NAME__ -> 167:gate ;
+61:__UG_NAME__ -> 197:envelope___control___0 ;
+61:__UG_NAME__ -> 197:envelope___control___4 ;
+62:__UG_NAME__ -> 197:envelope___control___5 ;
+63:__UG_NAME__ -> 197:envelope___control___6 ;
+64:__UG_NAME__ -> 197:envelope___control___7 ;
+196:__UG_NAME__ -> 197:gate ;
+65:__UG_NAME__ -> 206:envelope___control___0 ;
+65:__UG_NAME__ -> 206:envelope___control___4 ;
+66:__UG_NAME__ -> 206:envelope___control___5 ;
+67:__UG_NAME__ -> 206:envelope___control___6 ;
+68:__UG_NAME__ -> 206:envelope___control___7 ;
+205:__UG_NAME__ -> 206:gate ;
+69:__UG_NAME__ -> 216:envelope___control___0 ;
+69:__UG_NAME__ -> 216:envelope___control___4 ;
+70:__UG_NAME__ -> 216:envelope___control___5 ;
+71:__UG_NAME__ -> 216:envelope___control___6 ;
+72:__UG_NAME__ -> 216:envelope___control___7 ;
+215:__UG_NAME__ -> 216:gate ;
+223:__UG_NAME__ -> 239:envelope___select___0 ;
+228:__UG_NAME__ -> 239:envelope___select___4 ;
+229:__UG_NAME__ -> 239:envelope___select___5 ;
+42:__UG_NAME__ -> 239:envelope___control___6 ;
+227:__UG_NAME__ -> 239:envelope___select___8 ;
+230:__UG_NAME__ -> 239:envelope___select___9 ;
+42:__UG_NAME__ -> 239:envelope___control___10 ;
+226:__UG_NAME__ -> 239:envelope___select___12 ;
+237:__UG_NAME__ -> 239:envelope___select___13 ;
+42:__UG_NAME__ -> 239:envelope___control___14 ;
+225:__UG_NAME__ -> 239:envelope___select___16 ;
+238:__UG_NAME__ -> 239:envelope___binary____op____u____gen___17 ;
+42:__UG_NAME__ -> 239:envelope___control___18 ;
+47:__UG_NAME__ -> 273:envelope___control___0 ;
+47:__UG_NAME__ -> 273:envelope___control___4 ;
+48:__UG_NAME__ -> 273:envelope___control___5 ;
+49:__UG_NAME__ -> 273:envelope___control___6 ;
+50:__UG_NAME__ -> 273:envelope___control___7 ;
+272:__UG_NAME__ -> 273:gate ;
+43:__UG_NAME__ -> 285:envelope___control___0 ;
+43:__UG_NAME__ -> 285:envelope___control___4 ;
+44:__UG_NAME__ -> 285:envelope___control___5 ;
+45:__UG_NAME__ -> 285:envelope___control___6 ;
+46:__UG_NAME__ -> 285:envelope___control___7 ;
+284:__UG_NAME__ -> 285:gate ;
+289:__UG_NAME__ -> 304:envelope___select___0 ;
+293:__UG_NAME__ -> 304:envelope___select___4 ;
+294:__UG_NAME__ -> 304:envelope___select___5 ;
+55:__UG_NAME__ -> 304:envelope___control___6 ;
+292:__UG_NAME__ -> 304:envelope___select___8 ;
+295:__UG_NAME__ -> 304:envelope___select___9 ;
+55:__UG_NAME__ -> 304:envelope___control___10 ;
+291:__UG_NAME__ -> 304:envelope___select___12 ;
+302:__UG_NAME__ -> 304:envelope___select___13 ;
+55:__UG_NAME__ -> 304:envelope___control___14 ;
+290:__UG_NAME__ -> 304:envelope___select___16 ;
+303:__UG_NAME__ -> 304:envelope___binary____op____u____gen___17 ;
+55:__UG_NAME__ -> 304:envelope___control___18 ;
+5:__UG_NAME__ -> 329:envelope___control___4 ;
+1:__UG_NAME__ -> 329:envelope___control___5 ;
+26:__UG_NAME__ -> 329:envelope___control___6 ;
+323:__UG_NAME__ -> 329:envelope___select___8 ;
+2:__UG_NAME__ -> 329:envelope___control___9 ;
+26:__UG_NAME__ -> 329:envelope___control___10 ;
+7:__UG_NAME__ -> 329:envelope___control___12 ;
+328:__UG_NAME__ -> 329:envelope___select___13 ;
+26:__UG_NAME__ -> 329:envelope___control___14 ;
+4:__UG_NAME__ -> 329:envelope___control___17 ;
+26:__UG_NAME__ -> 329:envelope___control___18 ;
+78:__UG_NAME__ -> 353:envelope___control___0 ;
+78:__UG_NAME__ -> 353:envelope___control___4 ;
+79:__UG_NAME__ -> 353:envelope___control___5 ;
+80:__UG_NAME__ -> 353:envelope___control___6 ;
+81:__UG_NAME__ -> 353:envelope___control___7 ;
+352:__UG_NAME__ -> 353:gate ;
+90:__UG_NAME__ -> 358:envelope___control___0 ;
+90:__UG_NAME__ -> 358:envelope___control___4 ;
+91:__UG_NAME__ -> 358:envelope___control___5 ;
+92:__UG_NAME__ -> 358:envelope___control___6 ;
+93:__UG_NAME__ -> 358:envelope___control___7 ;
+357:__UG_NAME__ -> 358:gate ;
+86:__UG_NAME__ -> 368:envelope___control___0 ;
+86:__UG_NAME__ -> 368:envelope___control___4 ;
+87:__UG_NAME__ -> 368:envelope___control___5 ;
+88:__UG_NAME__ -> 368:envelope___control___6 ;
+89:__UG_NAME__ -> 368:envelope___control___7 ;
+367:__UG_NAME__ -> 368:gate ;
+82:__UG_NAME__ -> 374:envelope___control___0 ;
+82:__UG_NAME__ -> 374:envelope___control___4 ;
+83:__UG_NAME__ -> 374:envelope___control___5 ;
+84:__UG_NAME__ -> 374:envelope___control___6 ;
+85:__UG_NAME__ -> 374:envelope___control___7 ;
+373:__UG_NAME__ -> 374:gate ;
+94:__UG_NAME__ -> 384:envelope___control___0 ;
+94:__UG_NAME__ -> 384:envelope___control___4 ;
+95:__UG_NAME__ -> 384:envelope___control___5 ;
+96:__UG_NAME__ -> 384:envelope___control___6 ;
+97:__UG_NAME__ -> 384:envelope___control___7 ;
+383:__UG_NAME__ -> 384:gate ;
+22:__UG_NAME__ -> 398:envelope___control___0 ;
+22:__UG_NAME__ -> 398:envelope___control___4 ;
+23:__UG_NAME__ -> 398:envelope___control___5 ;
+24:__UG_NAME__ -> 398:envelope___control___6 ;
+25:__UG_NAME__ -> 398:envelope___control___7 ;
+397:__UG_NAME__ -> 398:gate ;
+246:__UG_NAME__ -> 311:in ;
+310:__UG_NAME__ -> 311:freq ;
+335:__UG_NAME__ -> 336:in ;
+310:__UG_NAME__ -> 336:freq ;
+66:__UG_NAME__ -> 99:in ;
+18:__UG_NAME__ -> 102:in ;
+19:__UG_NAME__ -> 106:in ;
+57:__UG_NAME__ -> 112:in ;
+58:__UG_NAME__ -> 116:in ;
+83:__UG_NAME__ -> 121:in ;
+74:__UG_NAME__ -> 125:in ;
+75:__UG_NAME__ -> 129:in ;
+30:__UG_NAME__ -> 135:in ;
+31:__UG_NAME__ -> 139:in ;
+38:__UG_NAME__ -> 159:in ;
+39:__UG_NAME__ -> 163:in ;
+61:__UG_NAME__ -> 189:in ;
+62:__UG_NAME__ -> 193:in ;
+65:__UG_NAME__ -> 200:in ;
+69:__UG_NAME__ -> 208:in ;
+70:__UG_NAME__ -> 212:in ;
+47:__UG_NAME__ -> 265:in ;
+48:__UG_NAME__ -> 269:in ;
+43:__UG_NAME__ -> 277:in ;
+44:__UG_NAME__ -> 281:in ;
+90:__UG_NAME__ -> 317:in ;
+82:__UG_NAME__ -> 321:in ;
+78:__UG_NAME__ -> 345:in ;
+79:__UG_NAME__ -> 349:in ;
+91:__UG_NAME__ -> 354:in ;
+86:__UG_NAME__ -> 360:in ;
+87:__UG_NAME__ -> 364:in ;
+94:__UG_NAME__ -> 376:in ;
+95:__UG_NAME__ -> 380:in ;
+22:__UG_NAME__ -> 390:in ;
+23:__UG_NAME__ -> 394:in ;
+177:__UG_NAME__ -> 185:start ;
+179:__UG_NAME__ -> 185:end ;
+184:__UG_NAME__ -> 185:dur ;
+405:__UG_NAME__ -> 406:dur ;
+218:__UG_NAME__ -> 245:in ;
+244:__UG_NAME__ -> 245:freq ;
+333:__UG_NAME__ -> 334:in ;
+244:__UG_NAME__ -> 334:freq ;
+240:__UG_NAME__ -> 242:a ;
+241:__UG_NAME__ -> 242:b ;
+288:__UG_NAME__ -> 309:a ;
+308:__UG_NAME__ -> 309:b ;
+219:__UG_NAME__ -> 220:a ;
+239:__UG_NAME__ -> 240:a ;
+222:__UG_NAME__ -> 241:a ;
+287:__UG_NAME__ -> 288:a ;
+304:__UG_NAME__ -> 305:a ;
+306:__UG_NAME__ -> 307:a ;
+120:__UG_NAME__ -> 198:a ;
+220:__UG_NAME__ -> 243:a ;
+242:__UG_NAME__ -> 243:b ;
+305:__UG_NAME__ -> 308:a ;
+307:__UG_NAME__ -> 308:b ;
+184:__UG_NAME__ -> 404:a ;
+403:__UG_NAME__ -> 404:b ;
+313:__UG_NAME__ -> 314:in ;
+337:__UG_NAME__ -> 338:in ;
+27:__UG_NAME__ -> 172:a ;
+27:__UG_NAME__ -> 178:a ;
+143:__UG_NAME__ -> 144:b ;
+9:__UG_NAME__ -> 145:b ;
+10:__UG_NAME__ -> 146:b ;
+11:__UG_NAME__ -> 148:b ;
+34:__UG_NAME__ -> 150:b ;
+36:__UG_NAME__ -> 152:b ;
+37:__UG_NAME__ -> 154:b ;
+35:__UG_NAME__ -> 156:b ;
+167:__UG_NAME__ -> 168:b ;
+120:__UG_NAME__ -> 171:b ;
+8:__UG_NAME__ -> 221:b ;
+12:__UG_NAME__ -> 224:b ;
+13:__UG_NAME__ -> 247:b ;
+14:__UG_NAME__ -> 248:b ;
+15:__UG_NAME__ -> 250:b ;
+16:__UG_NAME__ -> 252:b ;
+17:__UG_NAME__ -> 254:b ;
+51:__UG_NAME__ -> 256:b ;
+53:__UG_NAME__ -> 258:b ;
+54:__UG_NAME__ -> 260:b ;
+52:__UG_NAME__ -> 262:b ;
+273:__UG_NAME__ -> 274:b ;
+285:__UG_NAME__ -> 286:b ;
+120:__UG_NAME__ -> 330:b ;
+145:__UG_NAME__ -> 147:a ;
+146:__UG_NAME__ -> 147:b ;
+147:__UG_NAME__ -> 149:a ;
+148:__UG_NAME__ -> 149:b ;
+149:__UG_NAME__ -> 151:a ;
+150:__UG_NAME__ -> 151:b ;
+151:__UG_NAME__ -> 153:a ;
+152:__UG_NAME__ -> 153:b ;
+153:__UG_NAME__ -> 155:a ;
+154:__UG_NAME__ -> 155:b ;
+155:__UG_NAME__ -> 157:a ;
+156:__UG_NAME__ -> 157:b ;
+157:__UG_NAME__ -> 169:a ;
+168:__UG_NAME__ -> 169:b ;
+144:__UG_NAME__ -> 170:a ;
+169:__UG_NAME__ -> 170:b ;
+247:__UG_NAME__ -> 249:a ;
+248:__UG_NAME__ -> 249:b ;
+249:__UG_NAME__ -> 251:a ;
+250:__UG_NAME__ -> 251:b ;
+251:__UG_NAME__ -> 253:a ;
+252:__UG_NAME__ -> 253:b ;
+253:__UG_NAME__ -> 255:a ;
+254:__UG_NAME__ -> 255:b ;
+255:__UG_NAME__ -> 257:a ;
+256:__UG_NAME__ -> 257:b ;
+257:__UG_NAME__ -> 259:a ;
+258:__UG_NAME__ -> 259:b ;
+259:__UG_NAME__ -> 261:a ;
+260:__UG_NAME__ -> 261:b ;
+261:__UG_NAME__ -> 263:a ;
+262:__UG_NAME__ -> 263:b ;
+263:__UG_NAME__ -> 275:a ;
+274:__UG_NAME__ -> 275:b ;
+286:__UG_NAME__ -> 312:a ;
+275:__UG_NAME__ -> 312:b ;
+98:__UG_NAME__ -> 400:bus ;
+399:__UG_NAME__ -> 400:signals___balance2___0 ;
+399:__UG_NAME__ -> 400:signals___balance2___1 ;
+187:__UG_NAME__ -> 217:in ;
+197:__UG_NAME__ -> 217:window____size ;
+198:__UG_NAME__ -> 217:pitch____ratio ;
+206:__UG_NAME__ -> 217:pitch____dispersion ;
+216:__UG_NAME__ -> 217:time____dispersion ;
+331:__UG_NAME__ -> 332:in ;
+197:__UG_NAME__ -> 332:window____size ;
+198:__UG_NAME__ -> 332:pitch____ratio ;
+206:__UG_NAME__ -> 332:pitch____dispersion ;
+216:__UG_NAME__ -> 332:time____dispersion ;
+172:__UG_NAME__ -> 177:which ;
+175:__UG_NAME__ -> 177:array___binary____op____u____gen___0 ;
+176:__UG_NAME__ -> 177:array___binary____op____u____gen___1 ;
+178:__UG_NAME__ -> 179:which ;
+176:__UG_NAME__ -> 179:array___binary____op____u____gen___0 ;
+175:__UG_NAME__ -> 179:array___binary____op____u____gen___1 ;
+171:__UG_NAME__ -> 218:which ;
+187:__UG_NAME__ -> 218:array___binary____op____u____gen___0 ;
+217:__UG_NAME__ -> 218:array___pitch____shift___1 ;
+144:__UG_NAME__ -> 219:which ;
+143:__UG_NAME__ -> 219:array___env____gen___1 ;
+168:__UG_NAME__ -> 222:which ;
+167:__UG_NAME__ -> 222:array___env____gen___1 ;
+221:__UG_NAME__ -> 223:which ;
+222:__UG_NAME__ -> 223:array___select___0 ;
+8:__UG_NAME__ -> 223:array___control___1 ;
+224:__UG_NAME__ -> 225:which ;
+219:__UG_NAME__ -> 225:array___select___0 ;
+12:__UG_NAME__ -> 225:array___control___1 ;
+148:__UG_NAME__ -> 226:which ;
+225:__UG_NAME__ -> 226:array___select___0 ;
+11:__UG_NAME__ -> 226:array___control___1 ;
+146:__UG_NAME__ -> 227:which ;
+226:__UG_NAME__ -> 227:array___select___0 ;
+10:__UG_NAME__ -> 227:array___control___1 ;
+145:__UG_NAME__ -> 228:which ;
+227:__UG_NAME__ -> 228:array___select___0 ;
+9:__UG_NAME__ -> 228:array___control___1 ;
+150:__UG_NAME__ -> 229:which ;
+1:__UG_NAME__ -> 229:array___control___0 ;
+34:__UG_NAME__ -> 229:array___control___1 ;
+152:__UG_NAME__ -> 230:which ;
+2:__UG_NAME__ -> 230:array___control___0 ;
+36:__UG_NAME__ -> 230:array___control___1 ;
+156:__UG_NAME__ -> 231:which ;
+3:__UG_NAME__ -> 231:array___control___0 ;
+35:__UG_NAME__ -> 231:array___control___1 ;
+154:__UG_NAME__ -> 234:which ;
+4:__UG_NAME__ -> 234:array___control___0 ;
+37:__UG_NAME__ -> 234:array___control___1 ;
+232:__UG_NAME__ -> 237:which ;
+231:__UG_NAME__ -> 237:array___select___0 ;
+236:__UG_NAME__ -> 237:array___binary____op____u____gen___1 ;
+169:__UG_NAME__ -> 244:which ;
+220:__UG_NAME__ -> 244:array___unary____op____u____gen___0 ;
+243:__UG_NAME__ -> 244:array___binary____op____u____gen___1 ;
+170:__UG_NAME__ -> 246:which ;
+218:__UG_NAME__ -> 246:array___select___0 ;
+245:__UG_NAME__ -> 246:array___lpf___1 ;
+286:__UG_NAME__ -> 287:which ;
+285:__UG_NAME__ -> 287:array___env____gen___1 ;
+247:__UG_NAME__ -> 289:which ;
+13:__UG_NAME__ -> 289:array___control___1 ;
+254:__UG_NAME__ -> 290:which ;
+287:__UG_NAME__ -> 290:array___select___0 ;
+17:__UG_NAME__ -> 290:array___control___1 ;
+252:__UG_NAME__ -> 291:which ;
+290:__UG_NAME__ -> 291:array___select___0 ;
+16:__UG_NAME__ -> 291:array___control___1 ;
+250:__UG_NAME__ -> 292:which ;
+291:__UG_NAME__ -> 292:array___select___0 ;
+15:__UG_NAME__ -> 292:array___control___1 ;
+248:__UG_NAME__ -> 293:which ;
+292:__UG_NAME__ -> 293:array___select___0 ;
+14:__UG_NAME__ -> 293:array___control___1 ;
+256:__UG_NAME__ -> 294:which ;
+1:__UG_NAME__ -> 294:array___control___0 ;
+51:__UG_NAME__ -> 294:array___control___1 ;
+258:__UG_NAME__ -> 295:which ;
+2:__UG_NAME__ -> 295:array___control___0 ;
+53:__UG_NAME__ -> 295:array___control___1 ;
+262:__UG_NAME__ -> 296:which ;
+3:__UG_NAME__ -> 296:array___control___0 ;
+52:__UG_NAME__ -> 296:array___control___1 ;
+260:__UG_NAME__ -> 299:which ;
+4:__UG_NAME__ -> 299:array___control___0 ;
+54:__UG_NAME__ -> 299:array___control___1 ;
+297:__UG_NAME__ -> 302:which ;
+296:__UG_NAME__ -> 302:array___select___0 ;
+301:__UG_NAME__ -> 302:array___binary____op____u____gen___1 ;
+274:__UG_NAME__ -> 306:which ;
+273:__UG_NAME__ -> 306:array___env____gen___1 ;
+275:__UG_NAME__ -> 310:which ;
+288:__UG_NAME__ -> 310:array___unary____op____u____gen___0 ;
+309:__UG_NAME__ -> 310:array___binary____op____u____gen___1 ;
+312:__UG_NAME__ -> 313:which ;
+246:__UG_NAME__ -> 313:array___select___0 ;
+311:__UG_NAME__ -> 313:array___hpf___1 ;
+56:__UG_NAME__ -> 315:which ;
+313:__UG_NAME__ -> 315:array___select___0 ;
+314:__UG_NAME__ -> 315:array___normalizer___1 ;
+322:__UG_NAME__ -> 323:which ;
+6:__UG_NAME__ -> 323:array___control___0 ;
+7:__UG_NAME__ -> 323:array___control___1 ;
+324:__UG_NAME__ -> 328:which ;
+3:__UG_NAME__ -> 328:array___control___0 ;
+327:__UG_NAME__ -> 328:array___binary____op____u____gen___1 ;
+330:__UG_NAME__ -> 333:which ;
+331:__UG_NAME__ -> 333:array___binary____op____u____gen___0 ;
+332:__UG_NAME__ -> 333:array___pitch____shift___1 ;
+170:__UG_NAME__ -> 335:which ;
+333:__UG_NAME__ -> 335:array___select___0 ;
+334:__UG_NAME__ -> 335:array___lpf___1 ;
+312:__UG_NAME__ -> 337:which ;
+335:__UG_NAME__ -> 337:array___select___0 ;
+336:__UG_NAME__ -> 337:array___hpf___1 ;
+56:__UG_NAME__ -> 339:which ;
+337:__UG_NAME__ -> 339:array___select___0 ;
+338:__UG_NAME__ -> 339:array___normalizer___1 ;
+73:__UG_NAME__ -> 386:which ;
+340:__UG_NAME__ -> 386:array___binary____op____u____gen___0 ;
+385:__UG_NAME__ -> 386:array___compander___1 ;
+73:__UG_NAME__ -> 388:which ;
+341:__UG_NAME__ -> 388:array___binary____op____u____gen___0 ;
+387:__UG_NAME__ -> 388:array___compander___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-subpulse.dot b/etc/synthdefs/graphviz/dot/sonic-pi-subpulse.dot
new file mode 100644
index 0000000..96ac19d
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-subpulse.dot
@@ -0,0 +1,327 @@
+digraph synthdef {
+74 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> 0.8} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+43 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :sub_amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :sub_amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :sub_amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :sub_amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :sub_detune
+ default: -12.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :sub_detune_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :sub_detune_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :sub_detune_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+48 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+113 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+112 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+60 [label = "{{ <width> width|<freq> freq} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+38 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+28:__UG_NAME__ -> 74:a ;
+73:__UG_NAME__ -> 74:b ;
+88:__UG_NAME__ -> 89:b ;
+89:__UG_NAME__ -> 91:a ;
+90:__UG_NAME__ -> 91:b ;
+39:__UG_NAME__ -> 43:a ;
+42:__UG_NAME__ -> 43:b ;
+43:__UG_NAME__ -> 47:a ;
+46:__UG_NAME__ -> 47:b ;
+50:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+54:__UG_NAME__ -> 58:a ;
+57:__UG_NAME__ -> 58:b ;
+61:__UG_NAME__ -> 65:a ;
+64:__UG_NAME__ -> 65:b ;
+65:__UG_NAME__ -> 69:a ;
+68:__UG_NAME__ -> 69:b ;
+48:__UG_NAME__ -> 71:a ;
+70:__UG_NAME__ -> 71:b ;
+60:__UG_NAME__ -> 75:a ;
+74:__UG_NAME__ -> 75:b ;
+76:__UG_NAME__ -> 80:a ;
+79:__UG_NAME__ -> 80:b ;
+80:__UG_NAME__ -> 84:a ;
+83:__UG_NAME__ -> 84:b ;
+95:__UG_NAME__ -> 99:a ;
+98:__UG_NAME__ -> 99:b ;
+99:__UG_NAME__ -> 103:a ;
+102:__UG_NAME__ -> 103:b ;
+105:__UG_NAME__ -> 106:a ;
+94:__UG_NAME__ -> 106:b ;
+106:__UG_NAME__ -> 110:a ;
+109:__UG_NAME__ -> 110:b ;
+17:__UG_NAME__ -> 37:b ;
+41:__UG_NAME__ -> 42:a ;
+45:__UG_NAME__ -> 46:a ;
+52:__UG_NAME__ -> 53:a ;
+56:__UG_NAME__ -> 57:a ;
+63:__UG_NAME__ -> 64:a ;
+67:__UG_NAME__ -> 68:a ;
+78:__UG_NAME__ -> 79:a ;
+82:__UG_NAME__ -> 83:a ;
+93:__UG_NAME__ -> 94:a ;
+97:__UG_NAME__ -> 98:a ;
+101:__UG_NAME__ -> 102:a ;
+108:__UG_NAME__ -> 109:a ;
+40:__UG_NAME__ -> 41:a ;
+44:__UG_NAME__ -> 45:a ;
+51:__UG_NAME__ -> 52:a ;
+55:__UG_NAME__ -> 56:a ;
+62:__UG_NAME__ -> 63:a ;
+66:__UG_NAME__ -> 67:a ;
+77:__UG_NAME__ -> 78:a ;
+81:__UG_NAME__ -> 82:a ;
+92:__UG_NAME__ -> 93:a ;
+96:__UG_NAME__ -> 97:a ;
+100:__UG_NAME__ -> 101:a ;
+107:__UG_NAME__ -> 108:a ;
+0:__UG_NAME__ -> 48:envelope___control___0 ;
+0:__UG_NAME__ -> 48:envelope___control___4 ;
+1:__UG_NAME__ -> 48:envelope___control___5 ;
+2:__UG_NAME__ -> 48:envelope___control___6 ;
+3:__UG_NAME__ -> 48:envelope___control___7 ;
+47:__UG_NAME__ -> 48:gate ;
+24:__UG_NAME__ -> 59:envelope___control___0 ;
+24:__UG_NAME__ -> 59:envelope___control___4 ;
+25:__UG_NAME__ -> 59:envelope___control___5 ;
+27:__UG_NAME__ -> 59:envelope___control___6 ;
+26:__UG_NAME__ -> 59:envelope___control___7 ;
+58:__UG_NAME__ -> 59:gate ;
+32:__UG_NAME__ -> 70:envelope___control___0 ;
+32:__UG_NAME__ -> 70:envelope___control___4 ;
+33:__UG_NAME__ -> 70:envelope___control___5 ;
+35:__UG_NAME__ -> 70:envelope___control___6 ;
+34:__UG_NAME__ -> 70:envelope___control___7 ;
+69:__UG_NAME__ -> 70:gate ;
+20:__UG_NAME__ -> 85:envelope___control___0 ;
+20:__UG_NAME__ -> 85:envelope___control___4 ;
+21:__UG_NAME__ -> 85:envelope___control___5 ;
+22:__UG_NAME__ -> 85:envelope___control___6 ;
+23:__UG_NAME__ -> 85:envelope___control___7 ;
+84:__UG_NAME__ -> 85:gate ;
+16:__UG_NAME__ -> 88:envelope___control___4 ;
+12:__UG_NAME__ -> 88:envelope___control___5 ;
+19:__UG_NAME__ -> 88:envelope___control___6 ;
+38:__UG_NAME__ -> 88:envelope___select___8 ;
+13:__UG_NAME__ -> 88:envelope___control___9 ;
+19:__UG_NAME__ -> 88:envelope___control___10 ;
+18:__UG_NAME__ -> 88:envelope___control___12 ;
+14:__UG_NAME__ -> 88:envelope___control___13 ;
+19:__UG_NAME__ -> 88:envelope___control___14 ;
+15:__UG_NAME__ -> 88:envelope___control___17 ;
+19:__UG_NAME__ -> 88:envelope___control___18 ;
+4:__UG_NAME__ -> 104:envelope___control___0 ;
+4:__UG_NAME__ -> 104:envelope___control___4 ;
+5:__UG_NAME__ -> 104:envelope___control___5 ;
+6:__UG_NAME__ -> 104:envelope___control___6 ;
+7:__UG_NAME__ -> 104:envelope___control___7 ;
+103:__UG_NAME__ -> 104:gate ;
+8:__UG_NAME__ -> 111:envelope___control___0 ;
+8:__UG_NAME__ -> 111:envelope___control___4 ;
+9:__UG_NAME__ -> 111:envelope___control___5 ;
+10:__UG_NAME__ -> 111:envelope___control___6 ;
+11:__UG_NAME__ -> 111:envelope___control___7 ;
+110:__UG_NAME__ -> 111:gate ;
+0:__UG_NAME__ -> 40:in ;
+1:__UG_NAME__ -> 44:in ;
+24:__UG_NAME__ -> 51:in ;
+25:__UG_NAME__ -> 55:in ;
+32:__UG_NAME__ -> 62:in ;
+33:__UG_NAME__ -> 66:in ;
+20:__UG_NAME__ -> 77:in ;
+21:__UG_NAME__ -> 81:in ;
+8:__UG_NAME__ -> 92:in ;
+4:__UG_NAME__ -> 96:in ;
+5:__UG_NAME__ -> 100:in ;
+9:__UG_NAME__ -> 107:in ;
+75:__UG_NAME__ -> 87:in ;
+86:__UG_NAME__ -> 87:freq ;
+48:__UG_NAME__ -> 49:a ;
+71:__UG_NAME__ -> 72:a ;
+85:__UG_NAME__ -> 86:a ;
+87:__UG_NAME__ -> 90:in ;
+36:__UG_NAME__ -> 113:bus ;
+112:__UG_NAME__ -> 113:signals___pan2___0 ;
+112:__UG_NAME__ -> 113:signals___pan2___1 ;
+91:__UG_NAME__ -> 112:in ;
+111:__UG_NAME__ -> 112:pos ;
+104:__UG_NAME__ -> 112:level ;
+49:__UG_NAME__ -> 60:freq ;
+59:__UG_NAME__ -> 60:width ;
+37:__UG_NAME__ -> 38:which ;
+17:__UG_NAME__ -> 38:array___control___0 ;
+18:__UG_NAME__ -> 38:array___control___1 ;
+72:__UG_NAME__ -> 73:freq ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-supersaw.dot b/etc/synthdefs/graphviz/dot/sonic-pi-supersaw.dot
new file mode 100644
index 0000000..c55c783
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-supersaw.dot
@@ -0,0 +1,310 @@
+digraph synthdef {
+60 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+103 [label = "{{ <b> |<a> 0.9} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
+57 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+35 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> |<a> } |<__UG_NAME__>\> }" style="filled, bold, rounded"  shape=record rankdir=LR];
+48 [label = "{{ <b> |<a> } |<__UG_NAME__>\> }" style="filled, bold, rounded"  shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>\> }" style="filled, bold, rounded"  shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>\> }" style="filled, bold, rounded"  shape=record rankdir=LR];
+65 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 130.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :res
+ default: 0.7" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <coef> coef 0.995|<in> in} |<__UG_NAME__>leak-dc }" style="filled, bold, rounded"  shape=record rankdir=LR];
+43 [label = "{{ <iphase> iphase 0.0|<freq> freq} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+44 [label = "{{ <iphase> iphase 0.0|<freq> freq 4.0} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+47 [label = "{{ <iphase> iphase 0.0|<freq> freq 7.0} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+51 [label = "{{ <iphase> iphase 0.0|<freq> freq 5.0} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+55 [label = "{{ <iphase> iphase 0.0|<freq> freq 2.0} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+109 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+108 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+84 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+30 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+59:__UG_NAME__ -> 60:a ;
+31:__UG_NAME__ -> 103:b ;
+103:__UG_NAME__ -> 107:a ;
+106:__UG_NAME__ -> 107:b ;
+32:__UG_NAME__ -> 36:a ;
+35:__UG_NAME__ -> 36:b ;
+36:__UG_NAME__ -> 40:a ;
+39:__UG_NAME__ -> 40:b ;
+46:__UG_NAME__ -> 50:a ;
+49:__UG_NAME__ -> 50:b ;
+50:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+54:__UG_NAME__ -> 58:a ;
+57:__UG_NAME__ -> 58:b ;
+62:__UG_NAME__ -> 66:a ;
+65:__UG_NAME__ -> 66:b ;
+66:__UG_NAME__ -> 70:a ;
+69:__UG_NAME__ -> 70:b ;
+73:__UG_NAME__ -> 78:a ;
+77:__UG_NAME__ -> 78:b ;
+78:__UG_NAME__ -> 82:a ;
+81:__UG_NAME__ -> 82:b ;
+88:__UG_NAME__ -> 91:a ;
+90:__UG_NAME__ -> 91:b ;
+91:__UG_NAME__ -> 93:a ;
+92:__UG_NAME__ -> 93:b ;
+94:__UG_NAME__ -> 98:a ;
+97:__UG_NAME__ -> 98:b ;
+98:__UG_NAME__ -> 102:a ;
+101:__UG_NAME__ -> 102:b ;
+43:__UG_NAME__ -> 46:a ;
+45:__UG_NAME__ -> 46:b ;
+43:__UG_NAME__ -> 49:a ;
+48:__UG_NAME__ -> 49:b ;
+43:__UG_NAME__ -> 53:a ;
+52:__UG_NAME__ -> 53:b ;
+43:__UG_NAME__ -> 57:a ;
+56:__UG_NAME__ -> 57:b ;
+58:__UG_NAME__ -> 59:a ;
+43:__UG_NAME__ -> 59:b ;
+17:__UG_NAME__ -> 29:b ;
+34:__UG_NAME__ -> 35:a ;
+38:__UG_NAME__ -> 39:a ;
+43:__UG_NAME__ -> 45:a ;
+44:__UG_NAME__ -> 45:b ;
+43:__UG_NAME__ -> 48:a ;
+47:__UG_NAME__ -> 48:b ;
+43:__UG_NAME__ -> 52:a ;
+51:__UG_NAME__ -> 52:b ;
+43:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+64:__UG_NAME__ -> 65:a ;
+68:__UG_NAME__ -> 69:a ;
+76:__UG_NAME__ -> 77:a ;
+80:__UG_NAME__ -> 81:a ;
+89:__UG_NAME__ -> 90:a ;
+87:__UG_NAME__ -> 92:a ;
+96:__UG_NAME__ -> 97:a ;
+100:__UG_NAME__ -> 101:a ;
+33:__UG_NAME__ -> 34:a ;
+37:__UG_NAME__ -> 38:a ;
+63:__UG_NAME__ -> 64:a ;
+67:__UG_NAME__ -> 68:a ;
+75:__UG_NAME__ -> 76:a ;
+79:__UG_NAME__ -> 80:a ;
+86:__UG_NAME__ -> 87:a ;
+85:__UG_NAME__ -> 89:a ;
+95:__UG_NAME__ -> 96:a ;
+99:__UG_NAME__ -> 100:a ;
+16:__UG_NAME__ -> 31:envelope___control___4 ;
+12:__UG_NAME__ -> 31:envelope___control___5 ;
+19:__UG_NAME__ -> 31:envelope___control___6 ;
+30:__UG_NAME__ -> 31:envelope___select___8 ;
+13:__UG_NAME__ -> 31:envelope___control___9 ;
+19:__UG_NAME__ -> 31:envelope___control___10 ;
+18:__UG_NAME__ -> 31:envelope___control___12 ;
+14:__UG_NAME__ -> 31:envelope___control___13 ;
+19:__UG_NAME__ -> 31:envelope___control___14 ;
+15:__UG_NAME__ -> 31:envelope___control___17 ;
+19:__UG_NAME__ -> 31:envelope___control___18 ;
+0:__UG_NAME__ -> 41:envelope___control___0 ;
+0:__UG_NAME__ -> 41:envelope___control___4 ;
+1:__UG_NAME__ -> 41:envelope___control___5 ;
+2:__UG_NAME__ -> 41:envelope___control___6 ;
+3:__UG_NAME__ -> 41:envelope___control___7 ;
+40:__UG_NAME__ -> 41:gate ;
+20:__UG_NAME__ -> 71:envelope___control___0 ;
+20:__UG_NAME__ -> 71:envelope___control___4 ;
+21:__UG_NAME__ -> 71:envelope___control___5 ;
+22:__UG_NAME__ -> 71:envelope___control___6 ;
+23:__UG_NAME__ -> 71:envelope___control___7 ;
+70:__UG_NAME__ -> 71:gate ;
+74:__UG_NAME__ -> 83:envelope___mul____add___0 ;
+74:__UG_NAME__ -> 83:envelope___mul____add___4 ;
+25:__UG_NAME__ -> 83:envelope___control___5 ;
+26:__UG_NAME__ -> 83:envelope___control___6 ;
+27:__UG_NAME__ -> 83:envelope___control___7 ;
+82:__UG_NAME__ -> 83:gate ;
+8:__UG_NAME__ -> 104:envelope___control___0 ;
+8:__UG_NAME__ -> 104:envelope___control___4 ;
+9:__UG_NAME__ -> 104:envelope___control___5 ;
+10:__UG_NAME__ -> 104:envelope___control___6 ;
+11:__UG_NAME__ -> 104:envelope___control___7 ;
+102:__UG_NAME__ -> 104:gate ;
+4:__UG_NAME__ -> 105:envelope___control___0 ;
+4:__UG_NAME__ -> 105:envelope___control___4 ;
+5:__UG_NAME__ -> 105:envelope___control___5 ;
+6:__UG_NAME__ -> 105:envelope___control___6 ;
+7:__UG_NAME__ -> 105:envelope___control___7 ;
+93:__UG_NAME__ -> 105:gate ;
+0:__UG_NAME__ -> 33:in ;
+1:__UG_NAME__ -> 37:in ;
+20:__UG_NAME__ -> 63:in ;
+21:__UG_NAME__ -> 67:in ;
+74:__UG_NAME__ -> 75:in ;
+25:__UG_NAME__ -> 79:in ;
+4:__UG_NAME__ -> 85:in ;
+5:__UG_NAME__ -> 86:in ;
+8:__UG_NAME__ -> 95:in ;
+9:__UG_NAME__ -> 99:in ;
+60:__UG_NAME__ -> 61:in ;
+42:__UG_NAME__ -> 43:freq ;
+41:__UG_NAME__ -> 42:a ;
+71:__UG_NAME__ -> 72:a ;
+24:__UG_NAME__ -> 74:in ;
+84:__UG_NAME__ -> 106:in ;
+28:__UG_NAME__ -> 109:bus ;
+108:__UG_NAME__ -> 109:signals___pan2___0 ;
+108:__UG_NAME__ -> 109:signals___pan2___1 ;
+107:__UG_NAME__ -> 108:in ;
+104:__UG_NAME__ -> 108:pos ;
+105:__UG_NAME__ -> 108:level ;
+61:__UG_NAME__ -> 84:in ;
+72:__UG_NAME__ -> 84:freq ;
+83:__UG_NAME__ -> 84:rq ;
+29:__UG_NAME__ -> 30:which ;
+17:__UG_NAME__ -> 30:array___control___0 ;
+18:__UG_NAME__ -> 30:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-synth_violin.dot b/etc/synthdefs/graphviz/dot/sonic-pi-synth_violin.dot
new file mode 100644
index 0000000..94f8b59
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-synth_violin.dot
@@ -0,0 +1,333 @@
+digraph synthdef {
+73 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <b> |<a> 1.1} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+109 [label = "{{ <b> |<a> 1.1} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+113 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+51 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+106 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
+110 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <rq> rq 0.2857143|<freq> freq 700.0|<in> in} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+103 [label = "{{ <rq> rq 0.2857143|<freq> freq 300.0|<in> in} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+105 [label = "{{ <rq> rq 0.5|<freq> freq 3000.0|<in> in} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :vibrato_rate
+ default: 6.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :vibrato_rate_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :vibrato_rate_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :vibrato_rate_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :vibrato_depth
+ default: 0.15" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :vibrato_depth_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :vibrato_depth_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :vibrato_depth_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :vibrato_delay
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :vibrato_onset
+ default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+56 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|2.0|-99|-99|0.0|<envelope___control___5>|1.0|0.0|<envelope___env____gen___8>|<envelope___control___9>|1.0|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <freq> freq 30.0|<in> in} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+115 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+76 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+111 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase 0.0|<freq> freq} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+
+64:__UG_NAME__ -> 73:a ;
+72:__UG_NAME__ -> 73:b ;
+107:__UG_NAME__ -> 108:b ;
+108:__UG_NAME__ -> 109:b ;
+109:__UG_NAME__ -> 113:a ;
+112:__UG_NAME__ -> 113:b ;
+47:__UG_NAME__ -> 51:a ;
+50:__UG_NAME__ -> 51:b ;
+51:__UG_NAME__ -> 55:a ;
+54:__UG_NAME__ -> 55:b ;
+57:__UG_NAME__ -> 61:a ;
+60:__UG_NAME__ -> 61:b ;
+61:__UG_NAME__ -> 62:a ;
+39:__UG_NAME__ -> 62:b ;
+65:__UG_NAME__ -> 66:a ;
+42:__UG_NAME__ -> 66:b ;
+66:__UG_NAME__ -> 70:a ;
+69:__UG_NAME__ -> 70:b ;
+56:__UG_NAME__ -> 74:a ;
+73:__UG_NAME__ -> 74:b ;
+77:__UG_NAME__ -> 81:a ;
+80:__UG_NAME__ -> 81:b ;
+81:__UG_NAME__ -> 84:a ;
+83:__UG_NAME__ -> 84:b ;
+89:__UG_NAME__ -> 91:a ;
+90:__UG_NAME__ -> 91:b ;
+91:__UG_NAME__ -> 95:a ;
+94:__UG_NAME__ -> 95:b ;
+96:__UG_NAME__ -> 100:a ;
+99:__UG_NAME__ -> 100:b ;
+100:__UG_NAME__ -> 101:a ;
+45:__UG_NAME__ -> 101:b ;
+103:__UG_NAME__ -> 104:a ;
+88:__UG_NAME__ -> 104:b ;
+104:__UG_NAME__ -> 106:a ;
+105:__UG_NAME__ -> 106:b ;
+17:__UG_NAME__ -> 110:b ;
+38:__UG_NAME__ -> 39:a ;
+41:__UG_NAME__ -> 42:a ;
+44:__UG_NAME__ -> 45:a ;
+49:__UG_NAME__ -> 50:a ;
+53:__UG_NAME__ -> 54:a ;
+59:__UG_NAME__ -> 60:a ;
+68:__UG_NAME__ -> 69:a ;
+79:__UG_NAME__ -> 80:a ;
+82:__UG_NAME__ -> 83:a ;
+36:__UG_NAME__ -> 90:a ;
+93:__UG_NAME__ -> 94:a ;
+98:__UG_NAME__ -> 99:a ;
+35:__UG_NAME__ -> 36:a ;
+37:__UG_NAME__ -> 38:a ;
+40:__UG_NAME__ -> 41:a ;
+43:__UG_NAME__ -> 44:a ;
+48:__UG_NAME__ -> 49:a ;
+52:__UG_NAME__ -> 53:a ;
+58:__UG_NAME__ -> 59:a ;
+67:__UG_NAME__ -> 68:a ;
+78:__UG_NAME__ -> 79:a ;
+46:__UG_NAME__ -> 82:a ;
+92:__UG_NAME__ -> 93:a ;
+97:__UG_NAME__ -> 98:a ;
+87:__UG_NAME__ -> 88:in ;
+87:__UG_NAME__ -> 103:in ;
+87:__UG_NAME__ -> 105:in ;
+0:__UG_NAME__ -> 56:envelope___control___0 ;
+0:__UG_NAME__ -> 56:envelope___control___4 ;
+1:__UG_NAME__ -> 56:envelope___control___5 ;
+2:__UG_NAME__ -> 56:envelope___control___6 ;
+3:__UG_NAME__ -> 56:envelope___control___7 ;
+55:__UG_NAME__ -> 56:gate ;
+28:__UG_NAME__ -> 63:envelope___control___0 ;
+28:__UG_NAME__ -> 63:envelope___control___4 ;
+29:__UG_NAME__ -> 63:envelope___control___5 ;
+30:__UG_NAME__ -> 63:envelope___control___6 ;
+31:__UG_NAME__ -> 63:envelope___control___7 ;
+62:__UG_NAME__ -> 63:gate ;
+32:__UG_NAME__ -> 64:envelope___control___5 ;
+63:__UG_NAME__ -> 64:envelope___env____gen___8 ;
+33:__UG_NAME__ -> 64:envelope___control___9 ;
+24:__UG_NAME__ -> 71:envelope___control___0 ;
+24:__UG_NAME__ -> 71:envelope___control___4 ;
+25:__UG_NAME__ -> 71:envelope___control___5 ;
+26:__UG_NAME__ -> 71:envelope___control___6 ;
+27:__UG_NAME__ -> 71:envelope___control___7 ;
+70:__UG_NAME__ -> 71:gate ;
+20:__UG_NAME__ -> 85:envelope___control___0 ;
+20:__UG_NAME__ -> 85:envelope___control___4 ;
+21:__UG_NAME__ -> 85:envelope___control___5 ;
+22:__UG_NAME__ -> 85:envelope___control___6 ;
+23:__UG_NAME__ -> 85:envelope___control___7 ;
+84:__UG_NAME__ -> 85:gate ;
+4:__UG_NAME__ -> 102:envelope___control___0 ;
+4:__UG_NAME__ -> 102:envelope___control___4 ;
+5:__UG_NAME__ -> 102:envelope___control___5 ;
+6:__UG_NAME__ -> 102:envelope___control___6 ;
+7:__UG_NAME__ -> 102:envelope___control___7 ;
+101:__UG_NAME__ -> 102:gate ;
+16:__UG_NAME__ -> 112:envelope___control___4 ;
+12:__UG_NAME__ -> 112:envelope___control___5 ;
+19:__UG_NAME__ -> 112:envelope___control___6 ;
+111:__UG_NAME__ -> 112:envelope___select___8 ;
+13:__UG_NAME__ -> 112:envelope___control___9 ;
+19:__UG_NAME__ -> 112:envelope___control___10 ;
+18:__UG_NAME__ -> 112:envelope___control___12 ;
+14:__UG_NAME__ -> 112:envelope___control___13 ;
+19:__UG_NAME__ -> 112:envelope___control___14 ;
+15:__UG_NAME__ -> 112:envelope___control___17 ;
+19:__UG_NAME__ -> 112:envelope___control___18 ;
+8:__UG_NAME__ -> 114:envelope___control___0 ;
+8:__UG_NAME__ -> 114:envelope___control___4 ;
+9:__UG_NAME__ -> 114:envelope___control___5 ;
+10:__UG_NAME__ -> 114:envelope___control___6 ;
+11:__UG_NAME__ -> 114:envelope___control___7 ;
+95:__UG_NAME__ -> 114:gate ;
+106:__UG_NAME__ -> 107:in ;
+8:__UG_NAME__ -> 35:in ;
+29:__UG_NAME__ -> 37:in ;
+24:__UG_NAME__ -> 40:in ;
+5:__UG_NAME__ -> 43:in ;
+21:__UG_NAME__ -> 46:in ;
+0:__UG_NAME__ -> 48:in ;
+1:__UG_NAME__ -> 52:in ;
+28:__UG_NAME__ -> 58:in ;
+25:__UG_NAME__ -> 67:in ;
+20:__UG_NAME__ -> 78:in ;
+9:__UG_NAME__ -> 92:in ;
+4:__UG_NAME__ -> 97:in ;
+76:__UG_NAME__ -> 87:in ;
+86:__UG_NAME__ -> 87:freq ;
+74:__UG_NAME__ -> 75:a ;
+85:__UG_NAME__ -> 86:a ;
+34:__UG_NAME__ -> 116:bus ;
+115:__UG_NAME__ -> 116:signals___pan2___0 ;
+115:__UG_NAME__ -> 116:signals___pan2___1 ;
+113:__UG_NAME__ -> 115:in ;
+114:__UG_NAME__ -> 115:pos ;
+102:__UG_NAME__ -> 115:level ;
+75:__UG_NAME__ -> 76:freq ;
+110:__UG_NAME__ -> 111:which ;
+17:__UG_NAME__ -> 111:array___control___0 ;
+18:__UG_NAME__ -> 111:array___control___1 ;
+71:__UG_NAME__ -> 72:freq ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-tb303.dot b/etc/synthdefs/graphviz/dot/sonic-pi-tb303.dot
new file mode 100644
index 0000000..daf7267
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-tb303.dot
@@ -0,0 +1,459 @@
+digraph synthdef {
+80 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+138 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+146 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+47 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> 0.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+99 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+134 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+140 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+143 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+148 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+152 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+147 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+151 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+97 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+150 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.01" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 2.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 120.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :cutoff_attack
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :cutoff_sustain
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :cutoff_decay
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :cutoff_release
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :cutoff_min
+ default: 30.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :cutoff_min_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :cutoff_min_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :cutoff_min_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :cutoff_attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :cutoff_decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :cutoff_sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :cutoff_env_curve
+ default: 2.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :res
+ default: 0.9" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+40 [label = "control
+ :wave
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+41 [label = "control
+ :pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+42 [label = "control
+ :pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "control
+ :pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+44 [label = "control
+ :pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+45 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+59 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{<envelope___binary____op____u____gen___0>|4|-99|-99|<envelope___binary____op____u____gen___4>|<envelope___select___5>|5|<envelope___control___7>|<envelope___binary____op____u____gen___8>|<envelope___select___9>|5|<envelope___control___11>|<envelope___binary____op____u____gen___12>|<envelope___select___13>|5|<envelope___control___15>|<envelope___binary____op____u____gen___16>|<envelope___select___17>|5|<envelope___control___19>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{<envelope___binary____op____u____gen___0>|4|-99|-99|<envelope___binary____op____u____gen___4>|<envelope___control___5>|5|<envelope___control___7>|<envelope___binary____op____u____gen___8>|<envelope___control___9>|5|<envelope___control___11>|<envelope___binary____op____u____gen___12>|<envelope___control___13>|5|<envelope___control___15>|<envelope___binary____op____u____gen___16>|<envelope___control___17>|5|<envelope___control___19>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+153 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+149 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <iphase> iphase 0.0|<freq> freq} |<__UG_NAME__>lf-tri }" style="filled, bold, rounded"  shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+155 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+154 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+116 [label = "{{ <width> width|<freq> freq} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
+145 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+115 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+65 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ {{<array___saw___0>|<array___pulse___1>|<array___binary____op____u____gen___2>}|array}|<which> which} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
+133 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+79:__UG_NAME__ -> 80:a ;
+60:__UG_NAME__ -> 80:b ;
+117:__UG_NAME__ -> 118:b ;
+137:__UG_NAME__ -> 138:b ;
+138:__UG_NAME__ -> 146:a ;
+145:__UG_NAME__ -> 146:b ;
+19:__UG_NAME__ -> 47:b ;
+50:__UG_NAME__ -> 54:a ;
+53:__UG_NAME__ -> 54:b ;
+54:__UG_NAME__ -> 58:a ;
+57:__UG_NAME__ -> 58:b ;
+35:__UG_NAME__ -> 67:b ;
+32:__UG_NAME__ -> 68:a ;
+35:__UG_NAME__ -> 68:b ;
+71:__UG_NAME__ -> 72:a ;
+35:__UG_NAME__ -> 72:b ;
+71:__UG_NAME__ -> 75:a ;
+35:__UG_NAME__ -> 75:b ;
+35:__UG_NAME__ -> 78:b ;
+19:__UG_NAME__ -> 81:b ;
+85:__UG_NAME__ -> 89:a ;
+88:__UG_NAME__ -> 89:b ;
+89:__UG_NAME__ -> 90:a ;
+63:__UG_NAME__ -> 90:b ;
+96:__UG_NAME__ -> 99:a ;
+98:__UG_NAME__ -> 99:b ;
+99:__UG_NAME__ -> 103:a ;
+102:__UG_NAME__ -> 103:b ;
+105:__UG_NAME__ -> 109:a ;
+108:__UG_NAME__ -> 109:b ;
+109:__UG_NAME__ -> 112:a ;
+111:__UG_NAME__ -> 112:b ;
+121:__UG_NAME__ -> 126:a ;
+125:__UG_NAME__ -> 126:b ;
+126:__UG_NAME__ -> 130:a ;
+129:__UG_NAME__ -> 130:b ;
+95:__UG_NAME__ -> 131:a ;
+84:__UG_NAME__ -> 131:b ;
+133:__UG_NAME__ -> 134:a ;
+19:__UG_NAME__ -> 134:b ;
+16:__UG_NAME__ -> 135:a ;
+19:__UG_NAME__ -> 135:b ;
+133:__UG_NAME__ -> 136:a ;
+19:__UG_NAME__ -> 136:b ;
+131:__UG_NAME__ -> 140:a ;
+139:__UG_NAME__ -> 140:b ;
+142:__UG_NAME__ -> 143:a ;
+80:__UG_NAME__ -> 143:b ;
+92:__UG_NAME__ -> 148:a ;
+147:__UG_NAME__ -> 148:b ;
+148:__UG_NAME__ -> 152:a ;
+151:__UG_NAME__ -> 152:b ;
+27:__UG_NAME__ -> 64:b ;
+24:__UG_NAME__ -> 66:b ;
+33:__UG_NAME__ -> 70:b ;
+26:__UG_NAME__ -> 73:b ;
+25:__UG_NAME__ -> 76:b ;
+17:__UG_NAME__ -> 132:b ;
+52:__UG_NAME__ -> 53:a ;
+56:__UG_NAME__ -> 57:a ;
+62:__UG_NAME__ -> 63:a ;
+83:__UG_NAME__ -> 84:a ;
+87:__UG_NAME__ -> 88:a ;
+97:__UG_NAME__ -> 98:a ;
+101:__UG_NAME__ -> 102:a ;
+107:__UG_NAME__ -> 108:a ;
+110:__UG_NAME__ -> 111:a ;
+124:__UG_NAME__ -> 125:a ;
+128:__UG_NAME__ -> 129:a ;
+94:__UG_NAME__ -> 139:a ;
+120:__UG_NAME__ -> 147:a ;
+150:__UG_NAME__ -> 151:a ;
+51:__UG_NAME__ -> 52:a ;
+55:__UG_NAME__ -> 56:a ;
+61:__UG_NAME__ -> 62:a ;
+82:__UG_NAME__ -> 83:a ;
+86:__UG_NAME__ -> 87:a ;
+93:__UG_NAME__ -> 94:a ;
+49:__UG_NAME__ -> 97:a ;
+100:__UG_NAME__ -> 101:a ;
+106:__UG_NAME__ -> 107:a ;
+48:__UG_NAME__ -> 110:a ;
+46:__UG_NAME__ -> 120:a ;
+123:__UG_NAME__ -> 124:a ;
+127:__UG_NAME__ -> 128:a ;
+149:__UG_NAME__ -> 150:a ;
+20:__UG_NAME__ -> 59:envelope___control___0 ;
+20:__UG_NAME__ -> 59:envelope___control___4 ;
+21:__UG_NAME__ -> 59:envelope___control___5 ;
+22:__UG_NAME__ -> 59:envelope___control___6 ;
+23:__UG_NAME__ -> 59:envelope___control___7 ;
+58:__UG_NAME__ -> 59:gate ;
+67:__UG_NAME__ -> 79:envelope___binary____op____u____gen___0 ;
+68:__UG_NAME__ -> 79:envelope___binary____op____u____gen___4 ;
+69:__UG_NAME__ -> 79:envelope___select___5 ;
+34:__UG_NAME__ -> 79:envelope___control___7 ;
+72:__UG_NAME__ -> 79:envelope___binary____op____u____gen___8 ;
+74:__UG_NAME__ -> 79:envelope___select___9 ;
+34:__UG_NAME__ -> 79:envelope___control___11 ;
+75:__UG_NAME__ -> 79:envelope___binary____op____u____gen___12 ;
+77:__UG_NAME__ -> 79:envelope___select___13 ;
+34:__UG_NAME__ -> 79:envelope___control___15 ;
+78:__UG_NAME__ -> 79:envelope___binary____op____u____gen___16 ;
+65:__UG_NAME__ -> 79:envelope___select___17 ;
+34:__UG_NAME__ -> 79:envelope___control___19 ;
+41:__UG_NAME__ -> 91:envelope___control___0 ;
+41:__UG_NAME__ -> 91:envelope___control___4 ;
+42:__UG_NAME__ -> 91:envelope___control___5 ;
+43:__UG_NAME__ -> 91:envelope___control___6 ;
+44:__UG_NAME__ -> 91:envelope___control___7 ;
+90:__UG_NAME__ -> 91:gate ;
+8:__UG_NAME__ -> 104:envelope___control___0 ;
+8:__UG_NAME__ -> 104:envelope___control___4 ;
+9:__UG_NAME__ -> 104:envelope___control___5 ;
+10:__UG_NAME__ -> 104:envelope___control___6 ;
+11:__UG_NAME__ -> 104:envelope___control___7 ;
+103:__UG_NAME__ -> 104:gate ;
+0:__UG_NAME__ -> 113:envelope___control___0 ;
+0:__UG_NAME__ -> 113:envelope___control___4 ;
+1:__UG_NAME__ -> 113:envelope___control___5 ;
+2:__UG_NAME__ -> 113:envelope___control___6 ;
+3:__UG_NAME__ -> 113:envelope___control___7 ;
+112:__UG_NAME__ -> 113:gate ;
+81:__UG_NAME__ -> 137:envelope___binary____op____u____gen___0 ;
+135:__UG_NAME__ -> 137:envelope___binary____op____u____gen___4 ;
+12:__UG_NAME__ -> 137:envelope___control___5 ;
+18:__UG_NAME__ -> 137:envelope___control___7 ;
+136:__UG_NAME__ -> 137:envelope___binary____op____u____gen___8 ;
+14:__UG_NAME__ -> 137:envelope___control___9 ;
+18:__UG_NAME__ -> 137:envelope___control___11 ;
+134:__UG_NAME__ -> 137:envelope___binary____op____u____gen___12 ;
+13:__UG_NAME__ -> 137:envelope___control___13 ;
+18:__UG_NAME__ -> 137:envelope___control___15 ;
+47:__UG_NAME__ -> 137:envelope___binary____op____u____gen___16 ;
+15:__UG_NAME__ -> 137:envelope___control___17 ;
+18:__UG_NAME__ -> 137:envelope___control___19 ;
+28:__UG_NAME__ -> 141:envelope___control___0 ;
+28:__UG_NAME__ -> 141:envelope___control___4 ;
+29:__UG_NAME__ -> 141:envelope___control___5 ;
+30:__UG_NAME__ -> 141:envelope___control___6 ;
+31:__UG_NAME__ -> 141:envelope___control___7 ;
+140:__UG_NAME__ -> 141:gate ;
+122:__UG_NAME__ -> 144:envelope___mul____add___0 ;
+122:__UG_NAME__ -> 144:envelope___mul____add___4 ;
+37:__UG_NAME__ -> 144:envelope___control___5 ;
+38:__UG_NAME__ -> 144:envelope___control___6 ;
+39:__UG_NAME__ -> 144:envelope___control___7 ;
+130:__UG_NAME__ -> 144:gate ;
+4:__UG_NAME__ -> 153:envelope___control___0 ;
+4:__UG_NAME__ -> 153:envelope___control___4 ;
+5:__UG_NAME__ -> 153:envelope___control___5 ;
+6:__UG_NAME__ -> 153:envelope___control___6 ;
+7:__UG_NAME__ -> 153:envelope___control___7 ;
+152:__UG_NAME__ -> 153:gate ;
+4:__UG_NAME__ -> 46:in ;
+1:__UG_NAME__ -> 48:in ;
+8:__UG_NAME__ -> 49:in ;
+20:__UG_NAME__ -> 51:in ;
+21:__UG_NAME__ -> 55:in ;
+42:__UG_NAME__ -> 61:in ;
+28:__UG_NAME__ -> 82:in ;
+41:__UG_NAME__ -> 86:in ;
+29:__UG_NAME__ -> 93:in ;
+9:__UG_NAME__ -> 100:in ;
+0:__UG_NAME__ -> 106:in ;
+122:__UG_NAME__ -> 123:in ;
+37:__UG_NAME__ -> 127:in ;
+5:__UG_NAME__ -> 149:in ;
+114:__UG_NAME__ -> 117:freq ;
+59:__UG_NAME__ -> 60:a ;
+113:__UG_NAME__ -> 114:a ;
+141:__UG_NAME__ -> 142:a ;
+36:__UG_NAME__ -> 122:in ;
+45:__UG_NAME__ -> 155:bus ;
+154:__UG_NAME__ -> 155:signals___pan2___0 ;
+154:__UG_NAME__ -> 155:signals___pan2___1 ;
+146:__UG_NAME__ -> 154:in ;
+104:__UG_NAME__ -> 154:pos ;
+153:__UG_NAME__ -> 154:level ;
+114:__UG_NAME__ -> 116:freq ;
+91:__UG_NAME__ -> 116:width ;
+119:__UG_NAME__ -> 145:in ;
+143:__UG_NAME__ -> 145:freq ;
+144:__UG_NAME__ -> 145:rq ;
+114:__UG_NAME__ -> 115:freq ;
+64:__UG_NAME__ -> 65:which ;
+27:__UG_NAME__ -> 65:array___control___0 ;
+15:__UG_NAME__ -> 65:array___control___1 ;
+66:__UG_NAME__ -> 69:which ;
+24:__UG_NAME__ -> 69:array___control___0 ;
+12:__UG_NAME__ -> 69:array___control___1 ;
+70:__UG_NAME__ -> 71:which ;
+33:__UG_NAME__ -> 71:array___control___0 ;
+34:__UG_NAME__ -> 71:array___control___1 ;
+73:__UG_NAME__ -> 74:which ;
+26:__UG_NAME__ -> 74:array___control___0 ;
+14:__UG_NAME__ -> 74:array___control___1 ;
+76:__UG_NAME__ -> 77:which ;
+25:__UG_NAME__ -> 77:array___control___0 ;
+13:__UG_NAME__ -> 77:array___control___1 ;
+40:__UG_NAME__ -> 119:which ;
+115:__UG_NAME__ -> 119:array___saw___0 ;
+116:__UG_NAME__ -> 119:array___pulse___1 ;
+118:__UG_NAME__ -> 119:array___binary____op____u____gen___2 ;
+132:__UG_NAME__ -> 133:which ;
+17:__UG_NAME__ -> 133:array___control___0 ;
+18:__UG_NAME__ -> 133:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-tri.dot b/etc/synthdefs/graphviz/dot/sonic-pi-tri.dot
new file mode 100644
index 0000000..3d70043
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-tri.dot
@@ -0,0 +1,225 @@
+digraph synthdef {
+65 [label = "{{ <b> |<a> 1.4} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+29 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+33 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+42 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+34 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+28 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+32 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+41 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+43 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+27 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+31 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+37 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+39 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+48 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+61 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+25 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+40 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <iphase> iphase 0.0|<freq> freq} |<__UG_NAME__>lf-tri }" style="filled, bold, rounded"  shape=record rankdir=LR];
+63 [label = "{{ <freq> freq|<in> in} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <dur> dur 0.01|<level> level 1.0|<in> in} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
+76 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+75 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+35 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+
+64:__UG_NAME__ -> 65:b ;
+65:__UG_NAME__ -> 66:a ;
+48:__UG_NAME__ -> 66:b ;
+25:__UG_NAME__ -> 29:a ;
+28:__UG_NAME__ -> 29:b ;
+29:__UG_NAME__ -> 33:a ;
+32:__UG_NAME__ -> 33:b ;
+40:__UG_NAME__ -> 42:a ;
+41:__UG_NAME__ -> 42:b ;
+49:__UG_NAME__ -> 52:a ;
+51:__UG_NAME__ -> 52:b ;
+52:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+42:__UG_NAME__ -> 60:a ;
+43:__UG_NAME__ -> 60:b ;
+67:__UG_NAME__ -> 71:a ;
+70:__UG_NAME__ -> 71:b ;
+71:__UG_NAME__ -> 72:a ;
+47:__UG_NAME__ -> 72:b ;
+17:__UG_NAME__ -> 34:b ;
+27:__UG_NAME__ -> 28:a ;
+31:__UG_NAME__ -> 32:a ;
+37:__UG_NAME__ -> 41:a ;
+39:__UG_NAME__ -> 43:a ;
+46:__UG_NAME__ -> 47:a ;
+50:__UG_NAME__ -> 51:a ;
+54:__UG_NAME__ -> 55:a ;
+69:__UG_NAME__ -> 70:a ;
+26:__UG_NAME__ -> 27:a ;
+30:__UG_NAME__ -> 31:a ;
+36:__UG_NAME__ -> 37:a ;
+38:__UG_NAME__ -> 39:a ;
+45:__UG_NAME__ -> 46:a ;
+44:__UG_NAME__ -> 50:a ;
+53:__UG_NAME__ -> 54:a ;
+68:__UG_NAME__ -> 69:a ;
+16:__UG_NAME__ -> 48:envelope___control___4 ;
+12:__UG_NAME__ -> 48:envelope___control___5 ;
+19:__UG_NAME__ -> 48:envelope___control___6 ;
+35:__UG_NAME__ -> 48:envelope___select___8 ;
+13:__UG_NAME__ -> 48:envelope___control___9 ;
+19:__UG_NAME__ -> 48:envelope___control___10 ;
+18:__UG_NAME__ -> 48:envelope___control___12 ;
+14:__UG_NAME__ -> 48:envelope___control___13 ;
+19:__UG_NAME__ -> 48:envelope___control___14 ;
+15:__UG_NAME__ -> 48:envelope___control___17 ;
+19:__UG_NAME__ -> 48:envelope___control___18 ;
+0:__UG_NAME__ -> 57:envelope___control___0 ;
+0:__UG_NAME__ -> 57:envelope___control___4 ;
+1:__UG_NAME__ -> 57:envelope___control___5 ;
+2:__UG_NAME__ -> 57:envelope___control___6 ;
+3:__UG_NAME__ -> 57:envelope___control___7 ;
+56:__UG_NAME__ -> 57:gate ;
+20:__UG_NAME__ -> 61:envelope___control___0 ;
+20:__UG_NAME__ -> 61:envelope___control___4 ;
+21:__UG_NAME__ -> 61:envelope___control___5 ;
+22:__UG_NAME__ -> 61:envelope___control___6 ;
+23:__UG_NAME__ -> 61:envelope___control___7 ;
+60:__UG_NAME__ -> 61:gate ;
+8:__UG_NAME__ -> 73:envelope___control___0 ;
+8:__UG_NAME__ -> 73:envelope___control___4 ;
+9:__UG_NAME__ -> 73:envelope___control___5 ;
+10:__UG_NAME__ -> 73:envelope___control___6 ;
+11:__UG_NAME__ -> 73:envelope___control___7 ;
+72:__UG_NAME__ -> 73:gate ;
+4:__UG_NAME__ -> 74:envelope___control___0 ;
+4:__UG_NAME__ -> 74:envelope___control___4 ;
+5:__UG_NAME__ -> 74:envelope___control___5 ;
+6:__UG_NAME__ -> 74:envelope___control___6 ;
+7:__UG_NAME__ -> 74:envelope___control___7 ;
+33:__UG_NAME__ -> 74:gate ;
+4:__UG_NAME__ -> 26:in ;
+5:__UG_NAME__ -> 30:in ;
+20:__UG_NAME__ -> 36:in ;
+21:__UG_NAME__ -> 38:in ;
+0:__UG_NAME__ -> 44:in ;
+9:__UG_NAME__ -> 45:in ;
+1:__UG_NAME__ -> 53:in ;
+8:__UG_NAME__ -> 68:in ;
+58:__UG_NAME__ -> 59:freq ;
+59:__UG_NAME__ -> 63:in ;
+62:__UG_NAME__ -> 63:freq ;
+57:__UG_NAME__ -> 58:a ;
+61:__UG_NAME__ -> 62:a ;
+63:__UG_NAME__ -> 64:in ;
+24:__UG_NAME__ -> 76:bus ;
+75:__UG_NAME__ -> 76:signals___pan2___0 ;
+75:__UG_NAME__ -> 76:signals___pan2___1 ;
+66:__UG_NAME__ -> 75:in ;
+73:__UG_NAME__ -> 75:pos ;
+74:__UG_NAME__ -> 75:level ;
+34:__UG_NAME__ -> 35:which ;
+17:__UG_NAME__ -> 35:array___control___0 ;
+18:__UG_NAME__ -> 35:array___control___1 ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/dot/sonic-pi-zawa.dot b/etc/synthdefs/graphviz/dot/sonic-pi-zawa.dot
new file mode 100644
index 0000000..cee278b
--- /dev/null
+++ b/etc/synthdefs/graphviz/dot/sonic-pi-zawa.dot
@@ -0,0 +1,469 @@
+digraph synthdef {
+99 [label = "{{ <b> |<a> 0.5} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+109 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+112 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+114 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+119 [label = "{{ <b> 6.2831855|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+122 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+124 [label = "{{ <b> |<a> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+126 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+129 [label = "{{ <b> -1.0|<a> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
+144 [label = "{{ <b> |<a> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
+56 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+60 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+66 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+70 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+72 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+78 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+81 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+84 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+90 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+94 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+105 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+106 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+110 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+116 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+118 [label = "{{ <b> 0.25|<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+137 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+141 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+149 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+153 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+158 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+162 [label = "{{ <b> |<a> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
+115 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+125 [label = "{{ <b> 1.0|<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+127 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+130 [label = "{{ <b> |<a> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
+108 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+128 [label = "{{ <b> 2.0|<a> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+166 [label = "{{ <b> |<a> 1.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
+96 [label = "{{ <b> |<a> -1.0} |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
+47 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+55 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+59 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+65 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+69 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+77 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+80 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+85 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+89 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+93 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+104 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+123 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+140 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+148 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+152 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+157 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+161 [label = "{{ <b> 0.0|<a> } |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
+46 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+50 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+54 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+58 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+64 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+68 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+76 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+79 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+88 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+92 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+103 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+139 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+147 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+151 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+156 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+160 [label = "{{ <b> |<a> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
+0 [label = "control
+ :note
+ default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+1 [label = "control
+ :note_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+2 [label = "control
+ :note_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+3 [label = "control
+ :note_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+4 [label = "control
+ :amp
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+5 [label = "control
+ :amp_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+6 [label = "control
+ :amp_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+7 [label = "control
+ :amp_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+8 [label = "control
+ :pan
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+9 [label = "control
+ :pan_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+10 [label = "control
+ :pan_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+11 [label = "control
+ :pan_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+12 [label = "control
+ :attack
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+13 [label = "control
+ :decay
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+14 [label = "control
+ :sustain
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+15 [label = "control
+ :release
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+16 [label = "control
+ :attack_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+17 [label = "control
+ :decay_level
+ default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+18 [label = "control
+ :sustain_level
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+19 [label = "control
+ :env_curve
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+20 [label = "control
+ :cutoff
+ default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+21 [label = "control
+ :cutoff_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+22 [label = "control
+ :cutoff_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+23 [label = "control
+ :cutoff_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+24 [label = "control
+ :res
+ default: 0.9" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+25 [label = "control
+ :res_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+26 [label = "control
+ :res_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+27 [label = "control
+ :res_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+28 [label = "control
+ :phase
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+29 [label = "control
+ :phase_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+30 [label = "control
+ :phase_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+31 [label = "control
+ :phase_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+32 [label = "control
+ :phase_offset
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+33 [label = "control
+ :wave
+ default: 3.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+34 [label = "control
+ :disable_wave
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+35 [label = "control
+ :invert_wave
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+36 [label = "control
+ :pulse_width
+ default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+37 [label = "control
+ :pulse_width_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+38 [label = "control
+ :pulse_width_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+39 [label = "control
+ :pulse_width_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+40 [label = "control
+ :range
+ default: 24.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+41 [label = "control
+ :range_slide
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+42 [label = "control
+ :range_slide_shape
+ default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+43 [label = "control
+ :range_slide_curve
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+44 [label = "control
+ :out_bus
+ default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
+61 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+71 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+82 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+95 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+98 [label = "{{ <action> action 2.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate 1.0|{{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+107 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+142 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+154 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+163 [label = "{{ <action> action 0.0|<time____scale> time-scale 1.0|<level____bias> level-bias 0.0|<level____scale> level-scale 1.0|<gate> gate|{{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
+45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+63 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+67 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+73 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+75 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+87 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+91 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+102 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+138 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+146 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+150 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+159 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
+52 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+62 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+74 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+86 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+101 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+136 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+145 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+155 [label = "{{ <phase> phase 0.0|<freq> freq 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
+113 [label = "{{ <width> width|<iphase> iphase|<freq> freq} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
+111 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
+117 [label = "{{ <iphase> iphase|<freq> freq} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
+83 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+100 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+132 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+133 [label = "{{ <b> |<a> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
+48 [label = "{{ <add> add 1.0|<mul> mul -1.0|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+131 [label = "{{ <add> add|<mul> mul|<in> in} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
+165 [label = "{{ {{<signals___pan2___0>|<signals___pan2___1>}|signals}|<bus> bus} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
+164 [label = "{{ <level> level|<pos> pos|<in> in} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
+143 [label = "{{ <rq> rq|<freq> freq|<in> in} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
+97 [label = "{{ {{<array___control___0>|<array___control___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+121 [label = "{{ {{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+134 [label = "{{ {{<array___unary____op____u____gen___0>|<array___unary____op____u____gen___1>}|array}|<which> which} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
+120 [label = "{{ <add> add 0.0|<mul> mul 1.0|<phase> phase|<freq> freq} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
+135 [label = "{{ <saw____freq> saw-freq|<sync____freq> sync-freq} |<__UG_NAME__>sync-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
+
+98:__UG_NAME__ -> 99:b ;
+32:__UG_NAME__ -> 109:b ;
+111:__UG_NAME__ -> 112:b ;
+113:__UG_NAME__ -> 114:b ;
+118:__UG_NAME__ -> 119:a ;
+121:__UG_NAME__ -> 122:b ;
+123:__UG_NAME__ -> 124:b ;
+122:__UG_NAME__ -> 126:a ;
+125:__UG_NAME__ -> 126:b ;
+128:__UG_NAME__ -> 129:a ;
+99:__UG_NAME__ -> 144:a ;
+143:__UG_NAME__ -> 144:b ;
+52:__UG_NAME__ -> 56:a ;
+55:__UG_NAME__ -> 56:b ;
+56:__UG_NAME__ -> 60:a ;
+59:__UG_NAME__ -> 60:b ;
+62:__UG_NAME__ -> 66:a ;
+65:__UG_NAME__ -> 66:b ;
+66:__UG_NAME__ -> 70:a ;
+69:__UG_NAME__ -> 70:b ;
+61:__UG_NAME__ -> 72:a ;
+71:__UG_NAME__ -> 72:b ;
+74:__UG_NAME__ -> 78:a ;
+77:__UG_NAME__ -> 78:b ;
+78:__UG_NAME__ -> 81:a ;
+80:__UG_NAME__ -> 81:b ;
+61:__UG_NAME__ -> 84:a ;
+71:__UG_NAME__ -> 84:b ;
+86:__UG_NAME__ -> 90:a ;
+89:__UG_NAME__ -> 90:b ;
+90:__UG_NAME__ -> 94:a ;
+93:__UG_NAME__ -> 94:b ;
+101:__UG_NAME__ -> 105:a ;
+104:__UG_NAME__ -> 105:b ;
+105:__UG_NAME__ -> 106:a ;
+47:__UG_NAME__ -> 106:b ;
+109:__UG_NAME__ -> 110:a ;
+109:__UG_NAME__ -> 116:a ;
+32:__UG_NAME__ -> 118:a ;
+136:__UG_NAME__ -> 137:a ;
+85:__UG_NAME__ -> 137:b ;
+137:__UG_NAME__ -> 141:a ;
+140:__UG_NAME__ -> 141:b ;
+145:__UG_NAME__ -> 149:a ;
+148:__UG_NAME__ -> 149:b ;
+149:__UG_NAME__ -> 153:a ;
+152:__UG_NAME__ -> 153:b ;
+155:__UG_NAME__ -> 158:a ;
+157:__UG_NAME__ -> 158:b ;
+158:__UG_NAME__ -> 162:a ;
+161:__UG_NAME__ -> 162:b ;
+114:__UG_NAME__ -> 115:a ;
+124:__UG_NAME__ -> 125:a ;
+84:__UG_NAME__ -> 127:a ;
+61:__UG_NAME__ -> 127:b ;
+61:__UG_NAME__ -> 130:a ;
+129:__UG_NAME__ -> 130:b ;
+107:__UG_NAME__ -> 108:b ;
+127:__UG_NAME__ -> 128:a ;
+107:__UG_NAME__ -> 166:b ;
+17:__UG_NAME__ -> 96:b ;
+46:__UG_NAME__ -> 47:a ;
+54:__UG_NAME__ -> 55:a ;
+58:__UG_NAME__ -> 59:a ;
+64:__UG_NAME__ -> 65:a ;
+68:__UG_NAME__ -> 69:a ;
+76:__UG_NAME__ -> 77:a ;
+79:__UG_NAME__ -> 80:a ;
+50:__UG_NAME__ -> 85:a ;
+88:__UG_NAME__ -> 89:a ;
+92:__UG_NAME__ -> 93:a ;
+103:__UG_NAME__ -> 104:a ;
+35:__UG_NAME__ -> 123:a ;
+139:__UG_NAME__ -> 140:a ;
+147:__UG_NAME__ -> 148:a ;
+151:__UG_NAME__ -> 152:a ;
+156:__UG_NAME__ -> 157:a ;
+160:__UG_NAME__ -> 161:a ;
+45:__UG_NAME__ -> 46:a ;
+49:__UG_NAME__ -> 50:a ;
+53:__UG_NAME__ -> 54:a ;
+57:__UG_NAME__ -> 58:a ;
+63:__UG_NAME__ -> 64:a ;
+67:__UG_NAME__ -> 68:a ;
+75:__UG_NAME__ -> 76:a ;
+51:__UG_NAME__ -> 79:a ;
+87:__UG_NAME__ -> 88:a ;
+91:__UG_NAME__ -> 92:a ;
+102:__UG_NAME__ -> 103:a ;
+138:__UG_NAME__ -> 139:a ;
+146:__UG_NAME__ -> 147:a ;
+150:__UG_NAME__ -> 151:a ;
+73:__UG_NAME__ -> 156:a ;
+159:__UG_NAME__ -> 160:a ;
+0:__UG_NAME__ -> 61:envelope___control___0 ;
+0:__UG_NAME__ -> 61:envelope___control___4 ;
+1:__UG_NAME__ -> 61:envelope___control___5 ;
+2:__UG_NAME__ -> 61:envelope___control___6 ;
+3:__UG_NAME__ -> 61:envelope___control___7 ;
+60:__UG_NAME__ -> 61:gate ;
+40:__UG_NAME__ -> 71:envelope___control___0 ;
+40:__UG_NAME__ -> 71:envelope___control___4 ;
+41:__UG_NAME__ -> 71:envelope___control___5 ;
+42:__UG_NAME__ -> 71:envelope___control___6 ;
+43:__UG_NAME__ -> 71:envelope___control___7 ;
+70:__UG_NAME__ -> 71:gate ;
+20:__UG_NAME__ -> 82:envelope___control___0 ;
+20:__UG_NAME__ -> 82:envelope___control___4 ;
+21:__UG_NAME__ -> 82:envelope___control___5 ;
+22:__UG_NAME__ -> 82:envelope___control___6 ;
+23:__UG_NAME__ -> 82:envelope___control___7 ;
+81:__UG_NAME__ -> 82:gate ;
+36:__UG_NAME__ -> 95:envelope___control___0 ;
+36:__UG_NAME__ -> 95:envelope___control___4 ;
+37:__UG_NAME__ -> 95:envelope___control___5 ;
+38:__UG_NAME__ -> 95:envelope___control___6 ;
+39:__UG_NAME__ -> 95:envelope___control___7 ;
+94:__UG_NAME__ -> 95:gate ;
+16:__UG_NAME__ -> 98:envelope___control___4 ;
+12:__UG_NAME__ -> 98:envelope___control___5 ;
+19:__UG_NAME__ -> 98:envelope___control___6 ;
+97:__UG_NAME__ -> 98:envelope___select___8 ;
+13:__UG_NAME__ -> 98:envelope___control___9 ;
+19:__UG_NAME__ -> 98:envelope___control___10 ;
+18:__UG_NAME__ -> 98:envelope___control___12 ;
+14:__UG_NAME__ -> 98:envelope___control___13 ;
+19:__UG_NAME__ -> 98:envelope___control___14 ;
+15:__UG_NAME__ -> 98:envelope___control___17 ;
+19:__UG_NAME__ -> 98:envelope___control___18 ;
+28:__UG_NAME__ -> 107:envelope___control___0 ;
+28:__UG_NAME__ -> 107:envelope___control___4 ;
+29:__UG_NAME__ -> 107:envelope___control___5 ;
+30:__UG_NAME__ -> 107:envelope___control___6 ;
+31:__UG_NAME__ -> 107:envelope___control___7 ;
+106:__UG_NAME__ -> 107:gate ;
+48:__UG_NAME__ -> 142:envelope___mul____add___0 ;
+48:__UG_NAME__ -> 142:envelope___mul____add___4 ;
+25:__UG_NAME__ -> 142:envelope___control___5 ;
+26:__UG_NAME__ -> 142:envelope___control___6 ;
+27:__UG_NAME__ -> 142:envelope___control___7 ;
+141:__UG_NAME__ -> 142:gate ;
+8:__UG_NAME__ -> 154:envelope___control___0 ;
+8:__UG_NAME__ -> 154:envelope___control___4 ;
+9:__UG_NAME__ -> 154:envelope___control___5 ;
+10:__UG_NAME__ -> 154:envelope___control___6 ;
+11:__UG_NAME__ -> 154:envelope___control___7 ;
+153:__UG_NAME__ -> 154:gate ;
+4:__UG_NAME__ -> 163:envelope___control___0 ;
+4:__UG_NAME__ -> 163:envelope___control___4 ;
+5:__UG_NAME__ -> 163:envelope___control___5 ;
+6:__UG_NAME__ -> 163:envelope___control___6 ;
+7:__UG_NAME__ -> 163:envelope___control___7 ;
+162:__UG_NAME__ -> 163:gate ;
+29:__UG_NAME__ -> 45:in ;
+48:__UG_NAME__ -> 49:in ;
+21:__UG_NAME__ -> 51:in ;
+0:__UG_NAME__ -> 53:in ;
+1:__UG_NAME__ -> 57:in ;
+40:__UG_NAME__ -> 63:in ;
+41:__UG_NAME__ -> 67:in ;
+4:__UG_NAME__ -> 73:in ;
+20:__UG_NAME__ -> 75:in ;
+36:__UG_NAME__ -> 87:in ;
+37:__UG_NAME__ -> 91:in ;
+28:__UG_NAME__ -> 102:in ;
+25:__UG_NAME__ -> 138:in ;
+8:__UG_NAME__ -> 146:in ;
+9:__UG_NAME__ -> 150:in ;
+5:__UG_NAME__ -> 159:in ;
+108:__UG_NAME__ -> 113:freq ;
+32:__UG_NAME__ -> 113:iphase ;
+95:__UG_NAME__ -> 113:width ;
+108:__UG_NAME__ -> 111:freq ;
+110:__UG_NAME__ -> 111:iphase ;
+108:__UG_NAME__ -> 117:freq ;
+116:__UG_NAME__ -> 117:iphase ;
+82:__UG_NAME__ -> 83:a ;
+61:__UG_NAME__ -> 100:a ;
+131:__UG_NAME__ -> 132:a ;
+72:__UG_NAME__ -> 133:a ;
+24:__UG_NAME__ -> 48:in ;
+126:__UG_NAME__ -> 131:in ;
+128:__UG_NAME__ -> 131:mul ;
+130:__UG_NAME__ -> 131:add ;
+44:__UG_NAME__ -> 165:bus ;
+164:__UG_NAME__ -> 165:signals___pan2___0 ;
+164:__UG_NAME__ -> 165:signals___pan2___1 ;
+144:__UG_NAME__ -> 164:in ;
+154:__UG_NAME__ -> 164:pos ;
+163:__UG_NAME__ -> 164:level ;
+135:__UG_NAME__ -> 143:in ;
+83:__UG_NAME__ -> 143:freq ;
+142:__UG_NAME__ -> 143:rq ;
+96:__UG_NAME__ -> 97:which ;
+17:__UG_NAME__ -> 97:array___control___0 ;
+18:__UG_NAME__ -> 97:array___control___1 ;
+33:__UG_NAME__ -> 121:which ;
+112:__UG_NAME__ -> 121:array___binary____op____u____gen___0 ;
+115:__UG_NAME__ -> 121:array___binary____op____u____gen___1 ;
+117:__UG_NAME__ -> 121:array___lf____tri___2 ;
+120:__UG_NAME__ -> 121:array___sin____osc___3 ;
+34:__UG_NAME__ -> 134:which ;
+132:__UG_NAME__ -> 134:array___unary____op____u____gen___0 ;
+133:__UG_NAME__ -> 134:array___unary____op____u____gen___1 ;
+108:__UG_NAME__ -> 120:freq ;
+119:__UG_NAME__ -> 120:phase ;
+100:__UG_NAME__ -> 135:sync____freq ;
+134:__UG_NAME__ -> 135:saw____freq ;
+
+}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-amp_stereo_monitor.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-amp_stereo_monitor.pdf
new file mode 100644
index 0000000..0e71096
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-amp_stereo_monitor.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-basic_mixer.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-basic_mixer.pdf
index d4fc137..a0405ae 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-basic_mixer.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-basic_mixer.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-basic_mono_player.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-basic_mono_player.pdf
index 640a14d..9018abc 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-basic_mono_player.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-basic_mono_player.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-basic_stereo_player.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-basic_stereo_player.pdf
index 055ce67..e7ce15a 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-basic_stereo_player.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-basic_stereo_player.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-beep.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-beep.pdf
index 57b588c..c6797aa 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-beep.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-beep.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-bnoise.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-bnoise.pdf
index 96e0c58..a59d0f4 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-bnoise.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-bnoise.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-chipbass.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-chipbass.pdf
new file mode 100644
index 0000000..053baaf
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-chipbass.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-chiplead.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-chiplead.pdf
new file mode 100644
index 0000000..90954b0
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-chiplead.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-chipnoise.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-chipnoise.pdf
new file mode 100644
index 0000000..20f93be
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-chipnoise.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-cnoise.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-cnoise.pdf
index 2b05165..8aedb12 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-cnoise.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-cnoise.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-dark_ambience.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-dark_ambience.pdf
index 422f8b9..e290771 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-dark_ambience.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-dark_ambience.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-dpulse.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-dpulse.pdf
new file mode 100644
index 0000000..2dd495a
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-dpulse.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-dsaw.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-dsaw.pdf
index 5557185..6b053ad 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-dsaw.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-dsaw.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-dtri.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-dtri.pdf
new file mode 100644
index 0000000..4a63431
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-dtri.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-dull_bell.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-dull_bell.pdf
index 60414cb..68f52ab 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-dull_bell.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-dull_bell.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fm.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fm.pdf
index ccc73ae..bc3c866 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fm.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fm.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_band_eq.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_band_eq.pdf
new file mode 100644
index 0000000..2828ac4
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_band_eq.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_bitcrusher.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_bitcrusher.pdf
index 29ca054..48bb128 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_bitcrusher.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_bitcrusher.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_bpf.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_bpf.pdf
index c5c4443..162609a 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_bpf.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_bpf.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_compressor.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_compressor.pdf
index 094cf3b..b60f408 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_compressor.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_compressor.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_distortion.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_distortion.pdf
index df34652..556d940 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_distortion.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_distortion.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_echo.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_echo.pdf
index 2d1f6e0..df37073 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_echo.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_echo.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_flanger.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_flanger.pdf
index 51e6ac8..d7bce17 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_flanger.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_flanger.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_gverb.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_gverb.pdf
new file mode 100644
index 0000000..d9ba69d
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_gverb.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_hpf.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_hpf.pdf
index 9be0353..4f2f8bb 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_hpf.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_hpf.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_ixi_techno.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_ixi_techno.pdf
index f172285..36cdb41 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_ixi_techno.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_ixi_techno.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_krush.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_krush.pdf
index 1460bf6..bde4941 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_krush.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_krush.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_level.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_level.pdf
index 64484a4..8604f42 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_level.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_level.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_lpf.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_lpf.pdf
index a90051f..052b7f4 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_lpf.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_lpf.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_mono.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_mono.pdf
new file mode 100644
index 0000000..3658936
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_mono.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nhpf.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nhpf.pdf
index 0d5d2a4..aa1b2d6 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nhpf.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nhpf.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nlpf.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nlpf.pdf
index 5c04c41..ab792ce 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nlpf.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nlpf.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_normaliser.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_normaliser.pdf
index c4f6553..9c25498 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_normaliser.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_normaliser.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nrbpf.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nrbpf.pdf
index fd7d2d4..6ce715e 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nrbpf.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nrbpf.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nrhpf.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nrhpf.pdf
index 8b377d2..6fdc304 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nrhpf.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nrhpf.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nrlpf.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nrlpf.pdf
index 7a8fc63..4fe474d 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nrlpf.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_nrlpf.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_octaver.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_octaver.pdf
index 0c77e07..8562421 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_octaver.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_octaver.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_pan.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_pan.pdf
index 405eab9..2b9b0bf 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_pan.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_pan.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_panslicer.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_panslicer.pdf
new file mode 100644
index 0000000..b101cb4
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_panslicer.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_pitch_shift.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_pitch_shift.pdf
index e60e96f..a8b32b2 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_pitch_shift.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_pitch_shift.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_rbpf.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_rbpf.pdf
index 140c5f4..0296225 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_rbpf.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_rbpf.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_reverb.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_reverb.pdf
index fb55863..8de936c 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_reverb.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_reverb.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_rhpf.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_rhpf.pdf
index b0255ef..35c3937 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_rhpf.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_rhpf.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_ring_mod.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_ring_mod.pdf
index f598027..0d7eabe 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_ring_mod.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_ring_mod.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_rlpf.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_rlpf.pdf
index fac734d..f7b3bac 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_rlpf.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_rlpf.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_slicer.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_slicer.pdf
index b360efe..64f4cd4 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_slicer.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_slicer.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_tanh.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_tanh.pdf
new file mode 100644
index 0000000..a1f98fa
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_tanh.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_vowel.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_vowel.pdf
new file mode 100644
index 0000000..2ee237d
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_vowel.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_whammy.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_whammy.pdf
new file mode 100644
index 0000000..4343111
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_whammy.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_wobble.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_wobble.pdf
index 1d7da63..83b8a9b 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-fx_wobble.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-fx_wobble.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-gnoise.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-gnoise.pdf
index cea7f49..1fef5de 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-gnoise.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-gnoise.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-growl.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-growl.pdf
index ba2aba9..8ac6f08 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-growl.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-growl.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-hollow.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-hollow.pdf
index c9b071f..7c316f5 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-hollow.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-hollow.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-hoover.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-hoover.pdf
index 019c4f9..706095d 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-hoover.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-hoover.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-mixer.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-mixer.pdf
index e302b18..d4eec0e 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-mixer.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-mixer.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-mod_dsaw.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-mod_dsaw.pdf
index 299878a..d08f630 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-mod_dsaw.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-mod_dsaw.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-mod_fm.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-mod_fm.pdf
index f1315b8..98551ba 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-mod_fm.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-mod_fm.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-mod_pulse.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-mod_pulse.pdf
index 60f4b4c..f404532 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-mod_pulse.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-mod_pulse.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-mod_saw.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-mod_saw.pdf
index 17f9317..c5a9af7 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-mod_saw.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-mod_saw.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-mod_sine.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-mod_sine.pdf
index 8db696b..03e7779 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-mod_sine.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-mod_sine.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-mod_tri.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-mod_tri.pdf
index d1ab9e4..f891323 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-mod_tri.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-mod_tri.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-mono_player.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-mono_player.pdf
index e391e23..94a3c8e 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-mono_player.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-mono_player.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-noise.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-noise.pdf
index f15d016..e68b307 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-noise.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-noise.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-piano.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-piano.pdf
new file mode 100644
index 0000000..20c352e
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-piano.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-pluck.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-pluck.pdf
new file mode 100644
index 0000000..79f29e5
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-pluck.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-pnoise.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-pnoise.pdf
index 406c158..b8be021 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-pnoise.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-pnoise.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-pretty_bell.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-pretty_bell.pdf
index 2269524..b362344 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-pretty_bell.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-pretty_bell.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-prophet.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-prophet.pdf
index 337f75a..8dedce3 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-prophet.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-prophet.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-pulse.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-pulse.pdf
index f44d2bd..e5c6e10 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-pulse.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-pulse.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-recorder.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-recorder.pdf
index f69f7c0..830ce4c 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-recorder.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-recorder.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-saw.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-saw.pdf
index 9e7bec5..b5252f8 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-saw.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-saw.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-sound_in.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-sound_in.pdf
index 861865c..bfb548c 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-sound_in.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-sound_in.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-sound_in_stereo.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-sound_in_stereo.pdf
new file mode 100644
index 0000000..839fc8a
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-sound_in_stereo.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-square.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-square.pdf
index 662320f..787c359 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-square.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-square.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-stereo_player.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-stereo_player.pdf
index a01ab36..95b0b38 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-stereo_player.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-stereo_player.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-subpulse.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-subpulse.pdf
new file mode 100644
index 0000000..4138594
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-subpulse.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-supersaw.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-supersaw.pdf
index f271324..f35ee91 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-supersaw.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-supersaw.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-synth_violin.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-synth_violin.pdf
new file mode 100644
index 0000000..9740cb7
Binary files /dev/null and b/etc/synthdefs/graphviz/pdf/sonic-pi-synth_violin.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-tb303.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-tb303.pdf
index bcf3431..2bef876 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-tb303.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-tb303.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-tri.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-tri.pdf
index 284eb7f..9bdf445 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-tri.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-tri.pdf differ
diff --git a/etc/synthdefs/graphviz/pdf/sonic-pi-zawa.pdf b/etc/synthdefs/graphviz/pdf/sonic-pi-zawa.pdf
index 1dda1bc..92c7b29 100644
Binary files a/etc/synthdefs/graphviz/pdf/sonic-pi-zawa.pdf and b/etc/synthdefs/graphviz/pdf/sonic-pi-zawa.pdf differ
diff --git a/etc/synthdefs/graphviz/render.rb b/etc/synthdefs/graphviz/render.rb
index db1fb4e..33a8c84 100644
--- a/etc/synthdefs/graphviz/render.rb
+++ b/etc/synthdefs/graphviz/render.rb
@@ -5,7 +5,7 @@
 # Full project source: https://github.com/samaaron/sonic-pi
 # License: https://github.com/samaaron/sonic-pi/blob/master/LICENSE.md
 #
-# Copyright 2013, 2014, 2015 by Sam Aaron (http://sam.aaron.name).
+# Copyright 2013, 2014, 2015, 2016 by Sam Aaron (http://sam.aaron.name).
 # All rights reserved.
 #
 # Permission is granted for use, copying, modification, and
diff --git a/etc/synthdefs/graphviz/sonic-pi-amp_stereo_monitor.dot b/etc/synthdefs/graphviz/sonic-pi-amp_stereo_monitor.dot
deleted file mode 100644
index 59cb74f..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-amp_stereo_monitor.dot
+++ /dev/null
@@ -1,36 +0,0 @@
-digraph synthdef {
-4 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-8 [label = "{{ <in> in} |<__UG_NAME__>a2k }" style="bold, rounded" shape=record rankdir=LR];
-11 [label = "{{ <in> in} |<__UG_NAME__>a2k }" style="bold, rounded" shape=record rankdir=LR];
-3 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
-6 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :smoothness
- default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "{{ <freq> freq 5.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-2 [label = "{{ <bus> bus|<num____channels> num-channels 1} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-5 [label = "{{ <bus> bus|<num____channels> num-channels 1} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-7 [label = "{{ <in> in|<lag____time> lag-time} |<__UG_NAME__>lag }" style="filled, bold, rounded"  shape=record rankdir=LR];
-10 [label = "{{ <in> in|<lag____time> lag-time} |<__UG_NAME__>lag }" style="filled, bold, rounded"  shape=record rankdir=LR];
-12 [label = "{{ <trig> trig|{{47|115|111|110|105|99|45|112|105|47|97|109|112|<cmd____name___a2k___13>|<cmd____name___a2k___14>}|cmd-name}|{{13}|values}|<reply____id> reply-id} |<__UG_NAME__>send-reply }" style="bold, rounded" shape=record rankdir=LR];
-
-0:__UG_NAME__ -> 4:a ;
-7:__UG_NAME__ -> 8:in ;
-10:__UG_NAME__ -> 11:in ;
-2:__UG_NAME__ -> 3:a ;
-5:__UG_NAME__ -> 6:a ;
-0:__UG_NAME__ -> 2:bus ;
-4:__UG_NAME__ -> 5:bus ;
-1:__UG_NAME__ -> 7:lag____time ;
-6:__UG_NAME__ -> 7:in ;
-1:__UG_NAME__ -> 10:lag____time ;
-3:__UG_NAME__ -> 10:in ;
-0:__UG_NAME__ -> 12:reply____id ;
-11:__UG_NAME__ -> 12:cmd____name___a2k___13 ;
-8:__UG_NAME__ -> 12:cmd____name___a2k___14 ;
-9:__UG_NAME__ -> 12:trig ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-basic_mixer.dot b/etc/synthdefs/graphviz/sonic-pi-basic_mixer.dot
deleted file mode 100644
index bacc7a2..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-basic_mixer.dot
+++ /dev/null
@@ -1,60 +0,0 @@
-digraph synthdef {
-17 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-18 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-13 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-14 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-8 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-12 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-7 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-11 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide
- default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-6 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-10 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-9 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-16 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-19 [label = "{{ <bus> bus|{{<signals___binary____op____u____gen___0>|<signals___binary____op____u____gen___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-16:__UG_NAME__ -> 17:b ;
-15:__UG_NAME__ -> 17:a ;
-16:__UG_NAME__ -> 18:b ;
-15:__UG_NAME__ -> 18:a ;
-12:__UG_NAME__ -> 13:b ;
-9:__UG_NAME__ -> 13:a ;
-8:__UG_NAME__ -> 14:b ;
-13:__UG_NAME__ -> 14:a ;
-7:__UG_NAME__ -> 8:a ;
-11:__UG_NAME__ -> 12:a ;
-6:__UG_NAME__ -> 7:a ;
-10:__UG_NAME__ -> 11:a ;
-14:__UG_NAME__ -> 15:gate ;
-2:__UG_NAME__ -> 15:envelope___control___0 ;
-2:__UG_NAME__ -> 15:envelope___control___4 ;
-3:__UG_NAME__ -> 15:envelope___control___5 ;
-4:__UG_NAME__ -> 15:envelope___control___6 ;
-5:__UG_NAME__ -> 15:envelope___control___7 ;
-3:__UG_NAME__ -> 6:in ;
-2:__UG_NAME__ -> 10:in ;
-0:__UG_NAME__ -> 16:bus ;
-17:__UG_NAME__ -> 19:signals___binary____op____u____gen___0 ;
-18:__UG_NAME__ -> 19:signals___binary____op____u____gen___1 ;
-1:__UG_NAME__ -> 19:bus ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-basic_mono_player.dot b/etc/synthdefs/graphviz/sonic-pi-basic_mono_player.dot
deleted file mode 100644
index 56cb13c..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-basic_mono_player.dot
+++ /dev/null
@@ -1,218 +0,0 @@
-digraph synthdef {
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="dashed, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="dashed, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> 0.03|<b> } |<__UG_NAME__>+ }" style="dashed, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="dashed, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="dashed, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\< }" style="dashed, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-20 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="dashed, rounded" shape=record rankdir=LR];
-75 [label = "{{ <buf> buf} |<__UG_NAME__>buf-dur }" style="dashed, rounded" shape=record rankdir=LR];
-57 [label = "{{ <buf> buf} |<__UG_NAME__>buf-frames }" style="dashed, rounded" shape=record rankdir=LR];
-54 [label = "{{ <buf> buf} |<__UG_NAME__>buf-rate-scale }" style="dashed, rounded" shape=record rankdir=LR];
-0 [label = "control
- :buf
- default: 0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :rate
- default: 1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :out_bus
- default: 0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :buf
- default: 0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :rate
- default: 1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :out_bus
- default: 0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :cutoff
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :res
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-19 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-21 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <start> start 1.0|<end> end 1.0|<dur> dur|<action> action 2.0} |<__UG_NAME__>line }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-71 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-60 [label = "{{ <num____channels> num-channels 1|<bufnum> bufnum|<rate> rate|<trigger> trigger 0.0|<start____pos> start-pos|<loop> loop 0.0|<action> action 0.0} |<__UG_NAME__>play-buf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-65 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-59 [label = "{{ <which> which|{{0.0|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <which> which|{{<array___play____buf___0>|<array___rlpf___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-54:__UG_NAME__ -> 55:b ;
-1:__UG_NAME__ -> 55:a ;
-75:__UG_NAME__ -> 76:b ;
-74:__UG_NAME__ -> 76:a ;
-29:__UG_NAME__ -> 30:b ;
-26:__UG_NAME__ -> 30:a ;
-33:__UG_NAME__ -> 34:b ;
-30:__UG_NAME__ -> 34:a ;
-42:__UG_NAME__ -> 43:b ;
-37:__UG_NAME__ -> 43:a ;
-46:__UG_NAME__ -> 47:b ;
-43:__UG_NAME__ -> 47:a ;
-51:__UG_NAME__ -> 52:b ;
-48:__UG_NAME__ -> 52:a ;
-25:__UG_NAME__ -> 53:b ;
-52:__UG_NAME__ -> 53:a ;
-67:__UG_NAME__ -> 68:b ;
-63:__UG_NAME__ -> 68:a ;
-41:__UG_NAME__ -> 69:b ;
-68:__UG_NAME__ -> 69:a ;
-76:__UG_NAME__ -> 77:b ;
-57:__UG_NAME__ -> 58:a ;
-73:__UG_NAME__ -> 74:b ;
-1:__UG_NAME__ -> 56:a ;
-24:__UG_NAME__ -> 25:a ;
-28:__UG_NAME__ -> 29:a ;
-32:__UG_NAME__ -> 33:a ;
-35:__UG_NAME__ -> 36:a ;
-40:__UG_NAME__ -> 41:a ;
-20:__UG_NAME__ -> 42:a ;
-45:__UG_NAME__ -> 46:a ;
-50:__UG_NAME__ -> 51:a ;
-22:__UG_NAME__ -> 67:a ;
-19:__UG_NAME__ -> 20:a ;
-21:__UG_NAME__ -> 22:a ;
-23:__UG_NAME__ -> 24:a ;
-27:__UG_NAME__ -> 28:a ;
-31:__UG_NAME__ -> 32:a ;
-39:__UG_NAME__ -> 40:a ;
-44:__UG_NAME__ -> 45:a ;
-49:__UG_NAME__ -> 50:a ;
-1:__UG_NAME__ -> 73:a ;
-0:__UG_NAME__ -> 75:buf ;
-0:__UG_NAME__ -> 57:buf ;
-0:__UG_NAME__ -> 54:buf ;
-34:__UG_NAME__ -> 35:gate ;
-11:__UG_NAME__ -> 35:envelope___control___0 ;
-11:__UG_NAME__ -> 35:envelope___control___4 ;
-12:__UG_NAME__ -> 35:envelope___control___5 ;
-13:__UG_NAME__ -> 35:envelope___control___6 ;
-14:__UG_NAME__ -> 35:envelope___control___7 ;
-53:__UG_NAME__ -> 61:gate ;
-3:__UG_NAME__ -> 61:envelope___control___0 ;
-3:__UG_NAME__ -> 61:envelope___control___4 ;
-4:__UG_NAME__ -> 61:envelope___control___5 ;
-5:__UG_NAME__ -> 61:envelope___control___6 ;
-6:__UG_NAME__ -> 61:envelope___control___7 ;
-47:__UG_NAME__ -> 62:gate ;
-15:__UG_NAME__ -> 62:envelope___control___0 ;
-15:__UG_NAME__ -> 62:envelope___control___4 ;
-16:__UG_NAME__ -> 62:envelope___control___5 ;
-17:__UG_NAME__ -> 62:envelope___control___6 ;
-18:__UG_NAME__ -> 62:envelope___control___7 ;
-69:__UG_NAME__ -> 70:gate ;
-7:__UG_NAME__ -> 70:envelope___control___0 ;
-7:__UG_NAME__ -> 70:envelope___control___4 ;
-8:__UG_NAME__ -> 70:envelope___control___5 ;
-9:__UG_NAME__ -> 70:envelope___control___6 ;
-10:__UG_NAME__ -> 70:envelope___control___7 ;
-15:__UG_NAME__ -> 19:in ;
-7:__UG_NAME__ -> 21:in ;
-4:__UG_NAME__ -> 23:in ;
-11:__UG_NAME__ -> 27:in ;
-12:__UG_NAME__ -> 31:in ;
-8:__UG_NAME__ -> 39:in ;
-16:__UG_NAME__ -> 44:in ;
-3:__UG_NAME__ -> 49:in ;
-77:__UG_NAME__ -> 78:dur ;
-35:__UG_NAME__ -> 38:a ;
-62:__UG_NAME__ -> 64:in ;
-71:__UG_NAME__ -> 72:signals___pan2___0 ;
-71:__UG_NAME__ -> 72:signals___pan2___1 ;
-2:__UG_NAME__ -> 72:bus ;
-61:__UG_NAME__ -> 71:level ;
-70:__UG_NAME__ -> 71:pos ;
-66:__UG_NAME__ -> 71:in ;
-59:__UG_NAME__ -> 60:start____pos ;
-55:__UG_NAME__ -> 60:rate ;
-0:__UG_NAME__ -> 60:bufnum ;
-64:__UG_NAME__ -> 65:rq ;
-38:__UG_NAME__ -> 65:freq ;
-60:__UG_NAME__ -> 65:in ;
-58:__UG_NAME__ -> 59:array___binary____op____u____gen___1 ;
-56:__UG_NAME__ -> 59:which ;
-60:__UG_NAME__ -> 66:array___play____buf___0 ;
-65:__UG_NAME__ -> 66:array___rlpf___1 ;
-36:__UG_NAME__ -> 66:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-basic_stereo_player.dot b/etc/synthdefs/graphviz/sonic-pi-basic_stereo_player.dot
deleted file mode 100644
index 090861b..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-basic_stereo_player.dot
+++ /dev/null
@@ -1,227 +0,0 @@
-digraph synthdef {
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="dashed, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="dashed, rounded" shape=record rankdir=LR];
-23 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> 0.03|<b> } |<__UG_NAME__>+ }" style="dashed, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="dashed, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="dashed, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\< }" style="dashed, rounded" shape=record rankdir=LR];
-22 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-21 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="dashed, rounded" shape=record rankdir=LR];
-73 [label = "{{ <left> left|<right> right|<pos> pos|<level> level} |<__UG_NAME__>balance2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-77 [label = "{{ <buf> buf} |<__UG_NAME__>buf-dur }" style="dashed, rounded" shape=record rankdir=LR];
-38 [label = "{{ <buf> buf} |<__UG_NAME__>buf-frames }" style="dashed, rounded" shape=record rankdir=LR];
-35 [label = "{{ <buf> buf} |<__UG_NAME__>buf-rate-scale }" style="dashed, rounded" shape=record rankdir=LR];
-0 [label = "control
- :buf
- default: 0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :rate
- default: 1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :out_bus
- default: 0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :buf
- default: 0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :rate
- default: 1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :out_bus
- default: 0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :cutoff
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :res
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-20 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-19 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <start> start 1.0|<end> end 1.0|<dur> dur|<action> action 2.0} |<__UG_NAME__>line }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <bus> bus|{{<signals___balance2___0>|<signals___balance2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-41 [label = "{{ <num____channels> num-channels 2|<bufnum> bufnum|<rate> rate|<trigger> trigger 0.0|<start____pos> start-pos|<loop> loop 0.0|<action> action 0.0} |<__UG_NAME__>play-buf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-49 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-60 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-40 [label = "{{ <which> which|{{0.0|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <which> which|{{<array___play____buf___0>|<array___rlpf___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-62 [label = "{{ <which> which|{{<array___play____buf___0>|<array___rlpf___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-35:__UG_NAME__ -> 36:b ;
-1:__UG_NAME__ -> 36:a ;
-77:__UG_NAME__ -> 78:b ;
-76:__UG_NAME__ -> 78:a ;
-22:__UG_NAME__ -> 23:b ;
-19:__UG_NAME__ -> 23:a ;
-27:__UG_NAME__ -> 28:b ;
-24:__UG_NAME__ -> 28:a ;
-31:__UG_NAME__ -> 32:b ;
-28:__UG_NAME__ -> 32:a ;
-45:__UG_NAME__ -> 46:b ;
-23:__UG_NAME__ -> 46:a ;
-53:__UG_NAME__ -> 54:b ;
-50:__UG_NAME__ -> 54:a ;
-57:__UG_NAME__ -> 63:b ;
-54:__UG_NAME__ -> 63:a ;
-66:__UG_NAME__ -> 67:b ;
-65:__UG_NAME__ -> 67:a ;
-70:__UG_NAME__ -> 71:b ;
-67:__UG_NAME__ -> 71:a ;
-78:__UG_NAME__ -> 79:b ;
-38:__UG_NAME__ -> 39:a ;
-75:__UG_NAME__ -> 76:b ;
-1:__UG_NAME__ -> 37:a ;
-21:__UG_NAME__ -> 22:a ;
-26:__UG_NAME__ -> 27:a ;
-30:__UG_NAME__ -> 31:a ;
-33:__UG_NAME__ -> 34:a ;
-44:__UG_NAME__ -> 45:a ;
-52:__UG_NAME__ -> 53:a ;
-56:__UG_NAME__ -> 57:a ;
-59:__UG_NAME__ -> 66:a ;
-69:__UG_NAME__ -> 70:a ;
-20:__UG_NAME__ -> 21:a ;
-25:__UG_NAME__ -> 26:a ;
-29:__UG_NAME__ -> 30:a ;
-43:__UG_NAME__ -> 44:a ;
-51:__UG_NAME__ -> 52:a ;
-55:__UG_NAME__ -> 56:a ;
-58:__UG_NAME__ -> 59:a ;
-68:__UG_NAME__ -> 69:a ;
-1:__UG_NAME__ -> 75:a ;
-72:__UG_NAME__ -> 73:level ;
-64:__UG_NAME__ -> 73:pos ;
-62:__UG_NAME__ -> 73:right ;
-61:__UG_NAME__ -> 73:left ;
-0:__UG_NAME__ -> 77:buf ;
-0:__UG_NAME__ -> 38:buf ;
-0:__UG_NAME__ -> 35:buf ;
-32:__UG_NAME__ -> 33:gate ;
-11:__UG_NAME__ -> 33:envelope___control___0 ;
-11:__UG_NAME__ -> 33:envelope___control___4 ;
-12:__UG_NAME__ -> 33:envelope___control___5 ;
-13:__UG_NAME__ -> 33:envelope___control___6 ;
-14:__UG_NAME__ -> 33:envelope___control___7 ;
-46:__UG_NAME__ -> 47:gate ;
-15:__UG_NAME__ -> 47:envelope___control___0 ;
-15:__UG_NAME__ -> 47:envelope___control___4 ;
-16:__UG_NAME__ -> 47:envelope___control___5 ;
-17:__UG_NAME__ -> 47:envelope___control___6 ;
-18:__UG_NAME__ -> 47:envelope___control___7 ;
-63:__UG_NAME__ -> 64:gate ;
-7:__UG_NAME__ -> 64:envelope___control___0 ;
-7:__UG_NAME__ -> 64:envelope___control___4 ;
-8:__UG_NAME__ -> 64:envelope___control___5 ;
-9:__UG_NAME__ -> 64:envelope___control___6 ;
-10:__UG_NAME__ -> 64:envelope___control___7 ;
-71:__UG_NAME__ -> 72:gate ;
-3:__UG_NAME__ -> 72:envelope___control___0 ;
-3:__UG_NAME__ -> 72:envelope___control___4 ;
-4:__UG_NAME__ -> 72:envelope___control___5 ;
-5:__UG_NAME__ -> 72:envelope___control___6 ;
-6:__UG_NAME__ -> 72:envelope___control___7 ;
-15:__UG_NAME__ -> 20:in ;
-11:__UG_NAME__ -> 25:in ;
-12:__UG_NAME__ -> 29:in ;
-16:__UG_NAME__ -> 43:in ;
-7:__UG_NAME__ -> 51:in ;
-8:__UG_NAME__ -> 55:in ;
-3:__UG_NAME__ -> 58:in ;
-4:__UG_NAME__ -> 68:in ;
-79:__UG_NAME__ -> 80:dur ;
-33:__UG_NAME__ -> 42:a ;
-47:__UG_NAME__ -> 48:in ;
-73:__UG_NAME__ -> 74:signals___balance2___0 ;
-73:__UG_NAME__ -> 74:signals___balance2___1 ;
-2:__UG_NAME__ -> 74:bus ;
-40:__UG_NAME__ -> 41:start____pos ;
-36:__UG_NAME__ -> 41:rate ;
-0:__UG_NAME__ -> 41:bufnum ;
-48:__UG_NAME__ -> 49:rq ;
-42:__UG_NAME__ -> 49:freq ;
-41:__UG_NAME__ -> 49:in ;
-48:__UG_NAME__ -> 60:rq ;
-42:__UG_NAME__ -> 60:freq ;
-41:__UG_NAME__ -> 60:in ;
-39:__UG_NAME__ -> 40:array___binary____op____u____gen___1 ;
-37:__UG_NAME__ -> 40:which ;
-41:__UG_NAME__ -> 61:array___play____buf___0 ;
-60:__UG_NAME__ -> 61:array___rlpf___1 ;
-34:__UG_NAME__ -> 61:which ;
-41:__UG_NAME__ -> 62:array___play____buf___0 ;
-49:__UG_NAME__ -> 62:array___rlpf___1 ;
-34:__UG_NAME__ -> 62:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-beep.dot b/etc/synthdefs/graphviz/sonic-pi-beep.dot
deleted file mode 100644
index 3485d98..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-beep.dot
+++ /dev/null
@@ -1,180 +0,0 @@
-digraph synthdef {
-56 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-21 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-58 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-54 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-55:__UG_NAME__ -> 56:b ;
-52:__UG_NAME__ -> 57:b ;
-56:__UG_NAME__ -> 57:a ;
-25:__UG_NAME__ -> 26:b ;
-22:__UG_NAME__ -> 26:a ;
-29:__UG_NAME__ -> 30:b ;
-26:__UG_NAME__ -> 30:a ;
-35:__UG_NAME__ -> 36:b ;
-32:__UG_NAME__ -> 36:a ;
-38:__UG_NAME__ -> 42:b ;
-41:__UG_NAME__ -> 42:a ;
-45:__UG_NAME__ -> 46:b ;
-42:__UG_NAME__ -> 46:a ;
-48:__UG_NAME__ -> 49:b ;
-36:__UG_NAME__ -> 49:a ;
-17:__UG_NAME__ -> 53:b ;
-24:__UG_NAME__ -> 25:a ;
-28:__UG_NAME__ -> 29:a ;
-34:__UG_NAME__ -> 35:a ;
-37:__UG_NAME__ -> 38:a ;
-44:__UG_NAME__ -> 45:a ;
-40:__UG_NAME__ -> 48:a ;
-23:__UG_NAME__ -> 24:a ;
-27:__UG_NAME__ -> 28:a ;
-33:__UG_NAME__ -> 34:a ;
-21:__UG_NAME__ -> 37:a ;
-39:__UG_NAME__ -> 40:a ;
-43:__UG_NAME__ -> 44:a ;
-30:__UG_NAME__ -> 31:gate ;
-8:__UG_NAME__ -> 31:envelope___control___0 ;
-8:__UG_NAME__ -> 31:envelope___control___4 ;
-9:__UG_NAME__ -> 31:envelope___control___5 ;
-10:__UG_NAME__ -> 31:envelope___control___6 ;
-11:__UG_NAME__ -> 31:envelope___control___7 ;
-46:__UG_NAME__ -> 47:gate ;
-4:__UG_NAME__ -> 47:envelope___control___0 ;
-4:__UG_NAME__ -> 47:envelope___control___4 ;
-5:__UG_NAME__ -> 47:envelope___control___5 ;
-6:__UG_NAME__ -> 47:envelope___control___6 ;
-7:__UG_NAME__ -> 47:envelope___control___7 ;
-49:__UG_NAME__ -> 50:gate ;
-0:__UG_NAME__ -> 50:envelope___control___0 ;
-0:__UG_NAME__ -> 50:envelope___control___4 ;
-1:__UG_NAME__ -> 50:envelope___control___5 ;
-2:__UG_NAME__ -> 50:envelope___control___6 ;
-3:__UG_NAME__ -> 50:envelope___control___7 ;
-16:__UG_NAME__ -> 55:envelope___control___4 ;
-12:__UG_NAME__ -> 55:envelope___control___5 ;
-19:__UG_NAME__ -> 55:envelope___control___6 ;
-54:__UG_NAME__ -> 55:envelope___select___8 ;
-13:__UG_NAME__ -> 55:envelope___control___9 ;
-19:__UG_NAME__ -> 55:envelope___control___10 ;
-18:__UG_NAME__ -> 55:envelope___control___12 ;
-14:__UG_NAME__ -> 55:envelope___control___13 ;
-19:__UG_NAME__ -> 55:envelope___control___14 ;
-15:__UG_NAME__ -> 55:envelope___control___17 ;
-19:__UG_NAME__ -> 55:envelope___control___18 ;
-4:__UG_NAME__ -> 21:in ;
-8:__UG_NAME__ -> 23:in ;
-9:__UG_NAME__ -> 27:in ;
-0:__UG_NAME__ -> 33:in ;
-1:__UG_NAME__ -> 39:in ;
-5:__UG_NAME__ -> 43:in ;
-50:__UG_NAME__ -> 51:a ;
-58:__UG_NAME__ -> 59:signals___pan2___0 ;
-58:__UG_NAME__ -> 59:signals___pan2___1 ;
-20:__UG_NAME__ -> 59:bus ;
-47:__UG_NAME__ -> 58:level ;
-31:__UG_NAME__ -> 58:pos ;
-57:__UG_NAME__ -> 58:in ;
-17:__UG_NAME__ -> 54:array___control___0 ;
-18:__UG_NAME__ -> 54:array___control___1 ;
-53:__UG_NAME__ -> 54:which ;
-51:__UG_NAME__ -> 52:freq ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-bnoise.dot b/etc/synthdefs/graphviz/sonic-pi-bnoise.dot
deleted file mode 100644
index dc50acb..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-bnoise.dot
+++ /dev/null
@@ -1,223 +0,0 @@
-digraph synthdef {
-62 [label = "{{ <a> 1.2|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{<__UG_NAME__>brown-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :cutoff
- default: 110.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :res
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-46 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-74 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-61 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-58 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-
-61:__UG_NAME__ -> 62:b ;
-59:__UG_NAME__ -> 63:b ;
-62:__UG_NAME__ -> 63:a ;
-34:__UG_NAME__ -> 35:b ;
-31:__UG_NAME__ -> 35:a ;
-41:__UG_NAME__ -> 42:b ;
-40:__UG_NAME__ -> 42:a ;
-44:__UG_NAME__ -> 45:b ;
-42:__UG_NAME__ -> 45:a ;
-49:__UG_NAME__ -> 50:b ;
-35:__UG_NAME__ -> 50:a ;
-27:__UG_NAME__ -> 65:b ;
-64:__UG_NAME__ -> 65:a ;
-66:__UG_NAME__ -> 67:b ;
-65:__UG_NAME__ -> 67:a ;
-38:__UG_NAME__ -> 69:b ;
-56:__UG_NAME__ -> 69:a ;
-71:__UG_NAME__ -> 72:b ;
-69:__UG_NAME__ -> 72:a ;
-13:__UG_NAME__ -> 57:b ;
-26:__UG_NAME__ -> 27:a ;
-33:__UG_NAME__ -> 34:a ;
-37:__UG_NAME__ -> 38:a ;
-30:__UG_NAME__ -> 41:a ;
-43:__UG_NAME__ -> 44:a ;
-48:__UG_NAME__ -> 49:a ;
-55:__UG_NAME__ -> 66:a ;
-68:__UG_NAME__ -> 71:a ;
-25:__UG_NAME__ -> 26:a ;
-29:__UG_NAME__ -> 30:a ;
-32:__UG_NAME__ -> 33:a ;
-36:__UG_NAME__ -> 37:a ;
-39:__UG_NAME__ -> 43:a ;
-47:__UG_NAME__ -> 48:a ;
-54:__UG_NAME__ -> 55:a ;
-53:__UG_NAME__ -> 68:a ;
-45:__UG_NAME__ -> 46:gate ;
-28:__UG_NAME__ -> 46:envelope___mul____add___0 ;
-28:__UG_NAME__ -> 46:envelope___mul____add___4 ;
-21:__UG_NAME__ -> 46:envelope___control___5 ;
-22:__UG_NAME__ -> 46:envelope___control___6 ;
-23:__UG_NAME__ -> 46:envelope___control___7 ;
-50:__UG_NAME__ -> 51:gate ;
-16:__UG_NAME__ -> 51:envelope___control___0 ;
-16:__UG_NAME__ -> 51:envelope___control___4 ;
-17:__UG_NAME__ -> 51:envelope___control___5 ;
-18:__UG_NAME__ -> 51:envelope___control___6 ;
-19:__UG_NAME__ -> 51:envelope___control___7 ;
-12:__UG_NAME__ -> 59:envelope___control___4 ;
-8:__UG_NAME__ -> 59:envelope___control___5 ;
-15:__UG_NAME__ -> 59:envelope___control___6 ;
-58:__UG_NAME__ -> 59:envelope___select___8 ;
-10:__UG_NAME__ -> 59:envelope___control___9 ;
-15:__UG_NAME__ -> 59:envelope___control___10 ;
-14:__UG_NAME__ -> 59:envelope___control___12 ;
-9:__UG_NAME__ -> 59:envelope___control___13 ;
-15:__UG_NAME__ -> 59:envelope___control___14 ;
-11:__UG_NAME__ -> 59:envelope___control___17 ;
-15:__UG_NAME__ -> 59:envelope___control___18 ;
-67:__UG_NAME__ -> 70:gate ;
-4:__UG_NAME__ -> 70:envelope___control___0 ;
-4:__UG_NAME__ -> 70:envelope___control___4 ;
-5:__UG_NAME__ -> 70:envelope___control___5 ;
-6:__UG_NAME__ -> 70:envelope___control___6 ;
-7:__UG_NAME__ -> 70:envelope___control___7 ;
-72:__UG_NAME__ -> 73:gate ;
-0:__UG_NAME__ -> 73:envelope___control___0 ;
-0:__UG_NAME__ -> 73:envelope___control___4 ;
-1:__UG_NAME__ -> 73:envelope___control___5 ;
-2:__UG_NAME__ -> 73:envelope___control___6 ;
-3:__UG_NAME__ -> 73:envelope___control___7 ;
-4:__UG_NAME__ -> 25:in ;
-28:__UG_NAME__ -> 29:in ;
-16:__UG_NAME__ -> 32:in ;
-0:__UG_NAME__ -> 36:in ;
-21:__UG_NAME__ -> 39:in ;
-17:__UG_NAME__ -> 47:in ;
-1:__UG_NAME__ -> 53:in ;
-5:__UG_NAME__ -> 54:in ;
-51:__UG_NAME__ -> 52:a ;
-20:__UG_NAME__ -> 28:in ;
-74:__UG_NAME__ -> 75:signals___pan2___0 ;
-74:__UG_NAME__ -> 75:signals___pan2___1 ;
-24:__UG_NAME__ -> 75:bus ;
-73:__UG_NAME__ -> 74:level ;
-70:__UG_NAME__ -> 74:pos ;
-63:__UG_NAME__ -> 74:in ;
-46:__UG_NAME__ -> 61:rq ;
-52:__UG_NAME__ -> 61:freq ;
-60:__UG_NAME__ -> 61:in ;
-13:__UG_NAME__ -> 58:array___control___0 ;
-14:__UG_NAME__ -> 58:array___control___1 ;
-57:__UG_NAME__ -> 58:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-cnoise.dot b/etc/synthdefs/graphviz/sonic-pi-cnoise.dot
deleted file mode 100644
index f9f30a5..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-cnoise.dot
+++ /dev/null
@@ -1,223 +0,0 @@
-digraph synthdef {
-64 [label = "{{ <a> 0.6|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{<__UG_NAME__>clip-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :cutoff
- default: 110.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :res
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-48 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-74 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-63 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-66 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-
-63:__UG_NAME__ -> 64:b ;
-67:__UG_NAME__ -> 68:b ;
-64:__UG_NAME__ -> 68:a ;
-28:__UG_NAME__ -> 29:b ;
-25:__UG_NAME__ -> 29:a ;
-32:__UG_NAME__ -> 36:b ;
-35:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:b ;
-36:__UG_NAME__ -> 40:a ;
-42:__UG_NAME__ -> 43:b ;
-41:__UG_NAME__ -> 43:a ;
-46:__UG_NAME__ -> 47:b ;
-43:__UG_NAME__ -> 47:a ;
-56:__UG_NAME__ -> 57:b ;
-55:__UG_NAME__ -> 57:a ;
-60:__UG_NAME__ -> 61:b ;
-57:__UG_NAME__ -> 61:a ;
-71:__UG_NAME__ -> 72:b ;
-29:__UG_NAME__ -> 72:a ;
-13:__UG_NAME__ -> 65:b ;
-27:__UG_NAME__ -> 28:a ;
-31:__UG_NAME__ -> 32:a ;
-38:__UG_NAME__ -> 39:a ;
-34:__UG_NAME__ -> 42:a ;
-45:__UG_NAME__ -> 46:a ;
-51:__UG_NAME__ -> 56:a ;
-59:__UG_NAME__ -> 60:a ;
-70:__UG_NAME__ -> 71:a ;
-26:__UG_NAME__ -> 27:a ;
-30:__UG_NAME__ -> 31:a ;
-33:__UG_NAME__ -> 34:a ;
-37:__UG_NAME__ -> 38:a ;
-44:__UG_NAME__ -> 45:a ;
-50:__UG_NAME__ -> 51:a ;
-58:__UG_NAME__ -> 59:a ;
-69:__UG_NAME__ -> 70:a ;
-47:__UG_NAME__ -> 48:gate ;
-0:__UG_NAME__ -> 48:envelope___control___0 ;
-0:__UG_NAME__ -> 48:envelope___control___4 ;
-1:__UG_NAME__ -> 48:envelope___control___5 ;
-2:__UG_NAME__ -> 48:envelope___control___6 ;
-3:__UG_NAME__ -> 48:envelope___control___7 ;
-40:__UG_NAME__ -> 52:gate ;
-16:__UG_NAME__ -> 52:envelope___control___0 ;
-16:__UG_NAME__ -> 52:envelope___control___4 ;
-17:__UG_NAME__ -> 52:envelope___control___5 ;
-18:__UG_NAME__ -> 52:envelope___control___6 ;
-19:__UG_NAME__ -> 52:envelope___control___7 ;
-61:__UG_NAME__ -> 62:gate ;
-49:__UG_NAME__ -> 62:envelope___mul____add___0 ;
-49:__UG_NAME__ -> 62:envelope___mul____add___4 ;
-21:__UG_NAME__ -> 62:envelope___control___5 ;
-22:__UG_NAME__ -> 62:envelope___control___6 ;
-23:__UG_NAME__ -> 62:envelope___control___7 ;
-12:__UG_NAME__ -> 67:envelope___control___4 ;
-8:__UG_NAME__ -> 67:envelope___control___5 ;
-15:__UG_NAME__ -> 67:envelope___control___6 ;
-66:__UG_NAME__ -> 67:envelope___select___8 ;
-10:__UG_NAME__ -> 67:envelope___control___9 ;
-15:__UG_NAME__ -> 67:envelope___control___10 ;
-14:__UG_NAME__ -> 67:envelope___control___12 ;
-9:__UG_NAME__ -> 67:envelope___control___13 ;
-15:__UG_NAME__ -> 67:envelope___control___14 ;
-11:__UG_NAME__ -> 67:envelope___control___17 ;
-15:__UG_NAME__ -> 67:envelope___control___18 ;
-72:__UG_NAME__ -> 73:gate ;
-4:__UG_NAME__ -> 73:envelope___control___0 ;
-4:__UG_NAME__ -> 73:envelope___control___4 ;
-5:__UG_NAME__ -> 73:envelope___control___5 ;
-6:__UG_NAME__ -> 73:envelope___control___6 ;
-7:__UG_NAME__ -> 73:envelope___control___7 ;
-4:__UG_NAME__ -> 26:in ;
-16:__UG_NAME__ -> 30:in ;
-0:__UG_NAME__ -> 33:in ;
-17:__UG_NAME__ -> 37:in ;
-1:__UG_NAME__ -> 44:in ;
-49:__UG_NAME__ -> 50:in ;
-21:__UG_NAME__ -> 58:in ;
-5:__UG_NAME__ -> 69:in ;
-52:__UG_NAME__ -> 54:a ;
-20:__UG_NAME__ -> 49:in ;
-74:__UG_NAME__ -> 75:signals___pan2___0 ;
-74:__UG_NAME__ -> 75:signals___pan2___1 ;
-24:__UG_NAME__ -> 75:bus ;
-48:__UG_NAME__ -> 74:level ;
-73:__UG_NAME__ -> 74:pos ;
-68:__UG_NAME__ -> 74:in ;
-62:__UG_NAME__ -> 63:rq ;
-54:__UG_NAME__ -> 63:freq ;
-53:__UG_NAME__ -> 63:in ;
-13:__UG_NAME__ -> 66:array___control___0 ;
-14:__UG_NAME__ -> 66:array___control___1 ;
-65:__UG_NAME__ -> 66:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-dark_ambience.dot b/etc/synthdefs/graphviz/sonic-pi-dark_ambience.dot
deleted file mode 100644
index 046d203..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-dark_ambience.dot
+++ /dev/null
@@ -1,430 +0,0 @@
-digraph synthdef {
-49 [label = "{{ <a> 0.005|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-50 [label = "{{ <a> 0.002|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-52 [label = "{{ <a> 0.002|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-54 [label = "{{ <a> 0.001|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-56 [label = "{{ <a> 0.001|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-102 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-132 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-126 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-138 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-145 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-149 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-137 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-148 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-136 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-147 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-151 [label = "{{ <left> left|<right> right|<pos> pos|<level> level} |<__UG_NAME__>balance2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-47 [label = "{<__UG_NAME__>brown-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
-53 [label = "{<__UG_NAME__>clip-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 110.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :res
- default: 0.7" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :detune1
- default: 12.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :detune1_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :detune1_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :detune1_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :detune2
- default: 24.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :detune2_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :detune2_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :detune2_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :noise
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "control
- :ring
- default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "control
- :room
- default: 70.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "control
- :reverb_time
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-40 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-64 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-143 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-150 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <in> in|<taillevel> taillevel 0.5|<earlyreflevel> earlyreflevel 0.7|<roomsize> roomsize|<damping> damping 0.5|<inputbw> inputbw 0.5|<maxroomsize> maxroomsize 300.0|<revtime> revtime|<spread> spread 15.0|<drylevel> drylevel 1.0} |<__UG_NAME__>g-verb }" style="filled, bold, rounded"  shape=record rankdir=LR];
-55 [label = "{<__UG_NAME__>gray-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
-41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-135 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-139 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-146 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-134 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> 0.1|<b> } |<__UG_NAME__>max }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> 300.0|<b> } |<__UG_NAME__>min }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-152 [label = "{{ <bus> bus|{{<signals___balance2___0>|<signals___balance2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-48 [label = "{<__UG_NAME__>pink-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
-66 [label = "{{ <in> in|<freq> freq|<decay____time> decay-time} |<__UG_NAME__>ringz }" style="filled, bold, rounded"  shape=record rankdir=LR];
-79 [label = "{{ <in> in|<freq> freq|<decay____time> decay-time} |<__UG_NAME__>ringz }" style="filled, bold, rounded"  shape=record rankdir=LR];
-93 [label = "{{ <in> in|<freq> freq|<decay____time> decay-time} |<__UG_NAME__>ringz }" style="filled, bold, rounded"  shape=record rankdir=LR];
-130 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-133 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-57 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___binary____op____u____gen___2>|<array___binary____op____u____gen___3>|<array___binary____op____u____gen___4>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-100 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <a> |<b> } |<__UG_NAME__>tanh }" style="filled, bold, rounded"  shape=record rankdir=LR];
-131 [label = "{{ <a> |<b> } |<__UG_NAME__>tanh }" style="filled, bold, rounded"  shape=record rankdir=LR];
-51 [label = "{<__UG_NAME__>white-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-48:__UG_NAME__ -> 49:b ;
-47:__UG_NAME__ -> 50:b ;
-51:__UG_NAME__ -> 52:b ;
-53:__UG_NAME__ -> 54:b ;
-55:__UG_NAME__ -> 56:b ;
-94:__UG_NAME__ -> 95:a ;
-101:__UG_NAME__ -> 102:b ;
-95:__UG_NAME__ -> 103:b ;
-101:__UG_NAME__ -> 103:a ;
-108:__UG_NAME__ -> 109:b ;
-102:__UG_NAME__ -> 109:a ;
-131:__UG_NAME__ -> 132:b ;
-102:__UG_NAME__ -> 132:a ;
-46:__UG_NAME__ -> 59:b ;
-58:__UG_NAME__ -> 59:a ;
-62:__UG_NAME__ -> 63:b ;
-59:__UG_NAME__ -> 63:a ;
-66:__UG_NAME__ -> 67:b ;
-66:__UG_NAME__ -> 67:a ;
-70:__UG_NAME__ -> 71:b ;
-43:__UG_NAME__ -> 71:a ;
-74:__UG_NAME__ -> 75:b ;
-71:__UG_NAME__ -> 75:a ;
-76:__UG_NAME__ -> 77:b ;
-64:__UG_NAME__ -> 77:a ;
-79:__UG_NAME__ -> 80:b ;
-67:__UG_NAME__ -> 80:a ;
-84:__UG_NAME__ -> 85:b ;
-81:__UG_NAME__ -> 85:a ;
-88:__UG_NAME__ -> 89:b ;
-85:__UG_NAME__ -> 89:a ;
-90:__UG_NAME__ -> 91:b ;
-64:__UG_NAME__ -> 91:a ;
-93:__UG_NAME__ -> 94:b ;
-80:__UG_NAME__ -> 94:a ;
-113:__UG_NAME__ -> 114:b ;
-110:__UG_NAME__ -> 114:a ;
-117:__UG_NAME__ -> 118:b ;
-114:__UG_NAME__ -> 118:a ;
-125:__UG_NAME__ -> 126:b ;
-121:__UG_NAME__ -> 126:a ;
-127:__UG_NAME__ -> 128:b ;
-126:__UG_NAME__ -> 128:a ;
-137:__UG_NAME__ -> 138:b ;
-134:__UG_NAME__ -> 138:a ;
-141:__UG_NAME__ -> 142:b ;
-138:__UG_NAME__ -> 142:a ;
-98:__UG_NAME__ -> 145:b ;
-144:__UG_NAME__ -> 145:a ;
-148:__UG_NAME__ -> 149:b ;
-145:__UG_NAME__ -> 149:a ;
-17:__UG_NAME__ -> 99:b ;
-45:__UG_NAME__ -> 46:a ;
-61:__UG_NAME__ -> 62:a ;
-69:__UG_NAME__ -> 70:a ;
-73:__UG_NAME__ -> 74:a ;
-83:__UG_NAME__ -> 84:a ;
-87:__UG_NAME__ -> 88:a ;
-97:__UG_NAME__ -> 98:a ;
-112:__UG_NAME__ -> 113:a ;
-116:__UG_NAME__ -> 117:a ;
-124:__UG_NAME__ -> 125:a ;
-42:__UG_NAME__ -> 127:a ;
-136:__UG_NAME__ -> 137:a ;
-140:__UG_NAME__ -> 141:a ;
-147:__UG_NAME__ -> 148:a ;
-41:__UG_NAME__ -> 42:a ;
-44:__UG_NAME__ -> 45:a ;
-60:__UG_NAME__ -> 61:a ;
-68:__UG_NAME__ -> 69:a ;
-72:__UG_NAME__ -> 73:a ;
-82:__UG_NAME__ -> 83:a ;
-86:__UG_NAME__ -> 87:a ;
-96:__UG_NAME__ -> 97:a ;
-38:__UG_NAME__ -> 104:a ;
-111:__UG_NAME__ -> 112:a ;
-115:__UG_NAME__ -> 116:a ;
-123:__UG_NAME__ -> 124:a ;
-135:__UG_NAME__ -> 136:a ;
-139:__UG_NAME__ -> 140:a ;
-146:__UG_NAME__ -> 147:a ;
-150:__UG_NAME__ -> 151:level ;
-143:__UG_NAME__ -> 151:pos ;
-133:__UG_NAME__ -> 151:right ;
-130:__UG_NAME__ -> 151:left ;
-63:__UG_NAME__ -> 64:gate ;
-0:__UG_NAME__ -> 64:envelope___control___0 ;
-0:__UG_NAME__ -> 64:envelope___control___4 ;
-1:__UG_NAME__ -> 64:envelope___control___5 ;
-2:__UG_NAME__ -> 64:envelope___control___6 ;
-3:__UG_NAME__ -> 64:envelope___control___7 ;
-75:__UG_NAME__ -> 76:gate ;
-28:__UG_NAME__ -> 76:envelope___control___0 ;
-28:__UG_NAME__ -> 76:envelope___control___4 ;
-29:__UG_NAME__ -> 76:envelope___control___5 ;
-30:__UG_NAME__ -> 76:envelope___control___6 ;
-31:__UG_NAME__ -> 76:envelope___control___7 ;
-89:__UG_NAME__ -> 90:gate ;
-32:__UG_NAME__ -> 90:envelope___control___0 ;
-32:__UG_NAME__ -> 90:envelope___control___4 ;
-33:__UG_NAME__ -> 90:envelope___control___5 ;
-34:__UG_NAME__ -> 90:envelope___control___6 ;
-35:__UG_NAME__ -> 90:envelope___control___7 ;
-16:__UG_NAME__ -> 101:envelope___control___4 ;
-12:__UG_NAME__ -> 101:envelope___control___5 ;
-19:__UG_NAME__ -> 101:envelope___control___6 ;
-100:__UG_NAME__ -> 101:envelope___select___8 ;
-13:__UG_NAME__ -> 101:envelope___control___9 ;
-19:__UG_NAME__ -> 101:envelope___control___10 ;
-18:__UG_NAME__ -> 101:envelope___control___12 ;
-14:__UG_NAME__ -> 101:envelope___control___13 ;
-19:__UG_NAME__ -> 101:envelope___control___14 ;
-15:__UG_NAME__ -> 101:envelope___control___17 ;
-19:__UG_NAME__ -> 101:envelope___control___18 ;
-118:__UG_NAME__ -> 119:gate ;
-20:__UG_NAME__ -> 119:envelope___control___0 ;
-20:__UG_NAME__ -> 119:envelope___control___4 ;
-21:__UG_NAME__ -> 119:envelope___control___5 ;
-22:__UG_NAME__ -> 119:envelope___control___6 ;
-23:__UG_NAME__ -> 119:envelope___control___7 ;
-128:__UG_NAME__ -> 129:gate ;
-122:__UG_NAME__ -> 129:envelope___mul____add___0 ;
-122:__UG_NAME__ -> 129:envelope___mul____add___4 ;
-25:__UG_NAME__ -> 129:envelope___control___5 ;
-26:__UG_NAME__ -> 129:envelope___control___6 ;
-27:__UG_NAME__ -> 129:envelope___control___7 ;
-142:__UG_NAME__ -> 143:gate ;
-8:__UG_NAME__ -> 143:envelope___control___0 ;
-8:__UG_NAME__ -> 143:envelope___control___4 ;
-9:__UG_NAME__ -> 143:envelope___control___5 ;
-10:__UG_NAME__ -> 143:envelope___control___6 ;
-11:__UG_NAME__ -> 143:envelope___control___7 ;
-149:__UG_NAME__ -> 150:gate ;
-4:__UG_NAME__ -> 150:envelope___control___0 ;
-4:__UG_NAME__ -> 150:envelope___control___4 ;
-5:__UG_NAME__ -> 150:envelope___control___5 ;
-6:__UG_NAME__ -> 150:envelope___control___6 ;
-7:__UG_NAME__ -> 150:envelope___control___7 ;
-39:__UG_NAME__ -> 107:revtime ;
-106:__UG_NAME__ -> 107:roomsize ;
-103:__UG_NAME__ -> 107:in ;
-25:__UG_NAME__ -> 41:in ;
-0:__UG_NAME__ -> 44:in ;
-1:__UG_NAME__ -> 60:in ;
-28:__UG_NAME__ -> 68:in ;
-29:__UG_NAME__ -> 72:in ;
-32:__UG_NAME__ -> 82:in ;
-33:__UG_NAME__ -> 86:in ;
-4:__UG_NAME__ -> 96:in ;
-20:__UG_NAME__ -> 111:in ;
-21:__UG_NAME__ -> 115:in ;
-122:__UG_NAME__ -> 123:in ;
-8:__UG_NAME__ -> 135:in ;
-9:__UG_NAME__ -> 139:in ;
-5:__UG_NAME__ -> 146:in ;
-105:__UG_NAME__ -> 106:b ;
-64:__UG_NAME__ -> 65:a ;
-77:__UG_NAME__ -> 78:a ;
-91:__UG_NAME__ -> 92:a ;
-119:__UG_NAME__ -> 120:a ;
-104:__UG_NAME__ -> 105:b ;
-24:__UG_NAME__ -> 122:in ;
-151:__UG_NAME__ -> 152:signals___balance2___0 ;
-151:__UG_NAME__ -> 152:signals___balance2___1 ;
-40:__UG_NAME__ -> 152:bus ;
-37:__UG_NAME__ -> 66:decay____time ;
-65:__UG_NAME__ -> 66:freq ;
-57:__UG_NAME__ -> 66:in ;
-37:__UG_NAME__ -> 79:decay____time ;
-78:__UG_NAME__ -> 79:freq ;
-57:__UG_NAME__ -> 79:in ;
-37:__UG_NAME__ -> 93:decay____time ;
-92:__UG_NAME__ -> 93:freq ;
-57:__UG_NAME__ -> 93:in ;
-129:__UG_NAME__ -> 130:rq ;
-120:__UG_NAME__ -> 130:freq ;
-109:__UG_NAME__ -> 130:in ;
-129:__UG_NAME__ -> 133:rq ;
-120:__UG_NAME__ -> 133:freq ;
-132:__UG_NAME__ -> 133:in ;
-49:__UG_NAME__ -> 57:array___binary____op____u____gen___0 ;
-50:__UG_NAME__ -> 57:array___binary____op____u____gen___1 ;
-52:__UG_NAME__ -> 57:array___binary____op____u____gen___2 ;
-54:__UG_NAME__ -> 57:array___binary____op____u____gen___3 ;
-56:__UG_NAME__ -> 57:array___binary____op____u____gen___4 ;
-36:__UG_NAME__ -> 57:which ;
-17:__UG_NAME__ -> 100:array___control___0 ;
-18:__UG_NAME__ -> 100:array___control___1 ;
-99:__UG_NAME__ -> 100:which ;
-107:__UG_NAME__ -> 108:a ;
-107:__UG_NAME__ -> 131:a ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-dpulse.dot b/etc/synthdefs/graphviz/sonic-pi-dpulse.dot
deleted file mode 100644
index 90125e7..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-dpulse.dot
+++ /dev/null
@@ -1,377 +0,0 @@
-digraph synthdef {
-117 [label = "{{ <a> 1.1|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-119 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-40 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :detune
- default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :detune_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :detune_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :detune_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :dpulse_width
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :dpulse_width_slide
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :dpulse_width_slide_shape
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :dpulse_width_slide_curve
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-66 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ {{<envelope___select___0>|1.0|-99|-99|<envelope___select___4>|<envelope___select___5>|<envelope___select___6>|<envelope___select___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-126 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-131 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-130 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-83 [label = "{{ <freq> freq|<width> width} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
-102 [label = "{{ <freq> freq|<width> width} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
-47 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <which> which|{{<array___select___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <which> which|{{<array___select___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-
-116:__UG_NAME__ -> 117:b ;
-118:__UG_NAME__ -> 119:b ;
-117:__UG_NAME__ -> 119:a ;
-59:__UG_NAME__ -> 60:b ;
-56:__UG_NAME__ -> 60:a ;
-63:__UG_NAME__ -> 64:b ;
-60:__UG_NAME__ -> 64:a ;
-71:__UG_NAME__ -> 72:b ;
-68:__UG_NAME__ -> 72:a ;
-76:__UG_NAME__ -> 77:b ;
-52:__UG_NAME__ -> 77:a ;
-80:__UG_NAME__ -> 81:b ;
-77:__UG_NAME__ -> 81:a ;
-39:__UG_NAME__ -> 85:b ;
-84:__UG_NAME__ -> 85:a ;
-55:__UG_NAME__ -> 86:b ;
-85:__UG_NAME__ -> 86:a ;
-87:__UG_NAME__ -> 88:b ;
-66:__UG_NAME__ -> 88:a ;
-91:__UG_NAME__ -> 92:b ;
-90:__UG_NAME__ -> 92:a ;
-96:__UG_NAME__ -> 97:b ;
-92:__UG_NAME__ -> 97:a ;
-102:__UG_NAME__ -> 103:b ;
-83:__UG_NAME__ -> 103:a ;
-105:__UG_NAME__ -> 106:b ;
-73:__UG_NAME__ -> 106:a ;
-109:__UG_NAME__ -> 110:b ;
-106:__UG_NAME__ -> 110:a ;
-121:__UG_NAME__ -> 122:b ;
-120:__UG_NAME__ -> 122:a ;
-124:__UG_NAME__ -> 125:b ;
-122:__UG_NAME__ -> 125:a ;
-127:__UG_NAME__ -> 128:b ;
-72:__UG_NAME__ -> 128:a ;
-103:__UG_NAME__ -> 104:a ;
-32:__UG_NAME__ -> 40:b ;
-34:__UG_NAME__ -> 41:b ;
-17:__UG_NAME__ -> 46:b ;
-33:__UG_NAME__ -> 65:b ;
-35:__UG_NAME__ -> 98:b ;
-38:__UG_NAME__ -> 39:a ;
-45:__UG_NAME__ -> 55:a ;
-58:__UG_NAME__ -> 59:a ;
-62:__UG_NAME__ -> 63:a ;
-70:__UG_NAME__ -> 71:a ;
-75:__UG_NAME__ -> 76:a ;
-79:__UG_NAME__ -> 80:a ;
-51:__UG_NAME__ -> 91:a ;
-95:__UG_NAME__ -> 96:a ;
-54:__UG_NAME__ -> 105:a ;
-108:__UG_NAME__ -> 109:a ;
-115:__UG_NAME__ -> 121:a ;
-123:__UG_NAME__ -> 124:a ;
-43:__UG_NAME__ -> 127:a ;
-37:__UG_NAME__ -> 38:a ;
-42:__UG_NAME__ -> 43:a ;
-44:__UG_NAME__ -> 45:a ;
-50:__UG_NAME__ -> 51:a ;
-53:__UG_NAME__ -> 54:a ;
-57:__UG_NAME__ -> 58:a ;
-61:__UG_NAME__ -> 62:a ;
-69:__UG_NAME__ -> 70:a ;
-74:__UG_NAME__ -> 75:a ;
-78:__UG_NAME__ -> 79:a ;
-94:__UG_NAME__ -> 95:a ;
-107:__UG_NAME__ -> 108:a ;
-114:__UG_NAME__ -> 115:a ;
-48:__UG_NAME__ -> 123:a ;
-64:__UG_NAME__ -> 66:gate ;
-0:__UG_NAME__ -> 66:envelope___control___0 ;
-0:__UG_NAME__ -> 66:envelope___control___4 ;
-1:__UG_NAME__ -> 66:envelope___control___5 ;
-2:__UG_NAME__ -> 66:envelope___control___6 ;
-3:__UG_NAME__ -> 66:envelope___control___7 ;
-81:__UG_NAME__ -> 82:gate ;
-28:__UG_NAME__ -> 82:envelope___control___0 ;
-28:__UG_NAME__ -> 82:envelope___control___4 ;
-29:__UG_NAME__ -> 82:envelope___control___5 ;
-31:__UG_NAME__ -> 82:envelope___control___6 ;
-30:__UG_NAME__ -> 82:envelope___control___7 ;
-86:__UG_NAME__ -> 87:gate ;
-24:__UG_NAME__ -> 87:envelope___control___0 ;
-24:__UG_NAME__ -> 87:envelope___control___4 ;
-25:__UG_NAME__ -> 87:envelope___control___5 ;
-26:__UG_NAME__ -> 87:envelope___control___6 ;
-27:__UG_NAME__ -> 87:envelope___control___7 ;
-97:__UG_NAME__ -> 101:gate ;
-49:__UG_NAME__ -> 101:envelope___select___0 ;
-49:__UG_NAME__ -> 101:envelope___select___4 ;
-93:__UG_NAME__ -> 101:envelope___select___5 ;
-99:__UG_NAME__ -> 101:envelope___select___6 ;
-100:__UG_NAME__ -> 101:envelope___select___7 ;
-110:__UG_NAME__ -> 111:gate ;
-20:__UG_NAME__ -> 111:envelope___control___0 ;
-20:__UG_NAME__ -> 111:envelope___control___4 ;
-21:__UG_NAME__ -> 111:envelope___control___5 ;
-22:__UG_NAME__ -> 111:envelope___control___6 ;
-23:__UG_NAME__ -> 111:envelope___control___7 ;
-16:__UG_NAME__ -> 118:envelope___control___4 ;
-12:__UG_NAME__ -> 118:envelope___control___5 ;
-19:__UG_NAME__ -> 118:envelope___control___6 ;
-47:__UG_NAME__ -> 118:envelope___select___8 ;
-13:__UG_NAME__ -> 118:envelope___control___9 ;
-19:__UG_NAME__ -> 118:envelope___control___10 ;
-18:__UG_NAME__ -> 118:envelope___control___12 ;
-14:__UG_NAME__ -> 118:envelope___control___13 ;
-19:__UG_NAME__ -> 118:envelope___control___14 ;
-15:__UG_NAME__ -> 118:envelope___control___17 ;
-19:__UG_NAME__ -> 118:envelope___control___18 ;
-125:__UG_NAME__ -> 126:gate ;
-8:__UG_NAME__ -> 126:envelope___control___0 ;
-8:__UG_NAME__ -> 126:envelope___control___4 ;
-9:__UG_NAME__ -> 126:envelope___control___5 ;
-10:__UG_NAME__ -> 126:envelope___control___6 ;
-11:__UG_NAME__ -> 126:envelope___control___7 ;
-128:__UG_NAME__ -> 129:gate ;
-4:__UG_NAME__ -> 129:envelope___control___0 ;
-4:__UG_NAME__ -> 129:envelope___control___4 ;
-5:__UG_NAME__ -> 129:envelope___control___5 ;
-6:__UG_NAME__ -> 129:envelope___control___6 ;
-7:__UG_NAME__ -> 129:envelope___control___7 ;
-24:__UG_NAME__ -> 37:in ;
-5:__UG_NAME__ -> 42:in ;
-25:__UG_NAME__ -> 44:in ;
-9:__UG_NAME__ -> 48:in ;
-49:__UG_NAME__ -> 50:in ;
-20:__UG_NAME__ -> 53:in ;
-0:__UG_NAME__ -> 57:in ;
-1:__UG_NAME__ -> 61:in ;
-4:__UG_NAME__ -> 69:in ;
-28:__UG_NAME__ -> 74:in ;
-29:__UG_NAME__ -> 78:in ;
-93:__UG_NAME__ -> 94:in ;
-21:__UG_NAME__ -> 107:in ;
-8:__UG_NAME__ -> 114:in ;
-112:__UG_NAME__ -> 113:freq ;
-104:__UG_NAME__ -> 113:in ;
-66:__UG_NAME__ -> 67:a ;
-88:__UG_NAME__ -> 89:a ;
-111:__UG_NAME__ -> 112:a ;
-113:__UG_NAME__ -> 116:in ;
-130:__UG_NAME__ -> 131:signals___pan2___0 ;
-130:__UG_NAME__ -> 131:signals___pan2___1 ;
-36:__UG_NAME__ -> 131:bus ;
-129:__UG_NAME__ -> 130:level ;
-126:__UG_NAME__ -> 130:pos ;
-119:__UG_NAME__ -> 130:in ;
-82:__UG_NAME__ -> 83:width ;
-67:__UG_NAME__ -> 83:freq ;
-101:__UG_NAME__ -> 102:width ;
-89:__UG_NAME__ -> 102:freq ;
-17:__UG_NAME__ -> 47:array___control___0 ;
-18:__UG_NAME__ -> 47:array___control___1 ;
-46:__UG_NAME__ -> 47:which ;
-32:__UG_NAME__ -> 49:array___control___0 ;
-28:__UG_NAME__ -> 49:array___control___1 ;
-40:__UG_NAME__ -> 49:which ;
-33:__UG_NAME__ -> 93:array___control___0 ;
-29:__UG_NAME__ -> 93:array___control___1 ;
-65:__UG_NAME__ -> 93:which ;
-49:__UG_NAME__ -> 99:array___select___0 ;
-31:__UG_NAME__ -> 99:array___control___1 ;
-98:__UG_NAME__ -> 99:which ;
-49:__UG_NAME__ -> 100:array___select___0 ;
-30:__UG_NAME__ -> 100:array___control___1 ;
-41:__UG_NAME__ -> 100:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-dsaw.dot b/etc/synthdefs/graphviz/sonic-pi-dsaw.dot
deleted file mode 100644
index 453f5ef..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-dsaw.dot
+++ /dev/null
@@ -1,275 +0,0 @@
-digraph synthdef {
-59 [label = "{{ <a> |<b> 0.5} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-73 [label = "{{ <a> 1.1|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :detune
- default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :detune_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :detune_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :detune_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-95 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-94 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-44 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-57 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-30 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-
-58:__UG_NAME__ -> 59:a ;
-72:__UG_NAME__ -> 73:b ;
-74:__UG_NAME__ -> 75:b ;
-73:__UG_NAME__ -> 75:a ;
-36:__UG_NAME__ -> 37:b ;
-31:__UG_NAME__ -> 37:a ;
-40:__UG_NAME__ -> 41:b ;
-37:__UG_NAME__ -> 41:a ;
-48:__UG_NAME__ -> 49:b ;
-45:__UG_NAME__ -> 49:a ;
-52:__UG_NAME__ -> 53:b ;
-49:__UG_NAME__ -> 53:a ;
-54:__UG_NAME__ -> 55:b ;
-42:__UG_NAME__ -> 55:a ;
-57:__UG_NAME__ -> 58:b ;
-44:__UG_NAME__ -> 58:a ;
-63:__UG_NAME__ -> 64:b ;
-61:__UG_NAME__ -> 64:a ;
-67:__UG_NAME__ -> 68:b ;
-64:__UG_NAME__ -> 68:a ;
-82:__UG_NAME__ -> 83:b ;
-79:__UG_NAME__ -> 83:a ;
-78:__UG_NAME__ -> 84:b ;
-83:__UG_NAME__ -> 84:a ;
-89:__UG_NAME__ -> 90:b ;
-86:__UG_NAME__ -> 90:a ;
-91:__UG_NAME__ -> 92:b ;
-90:__UG_NAME__ -> 92:a ;
-17:__UG_NAME__ -> 29:b ;
-35:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:a ;
-47:__UG_NAME__ -> 48:a ;
-51:__UG_NAME__ -> 52:a ;
-62:__UG_NAME__ -> 63:a ;
-66:__UG_NAME__ -> 67:a ;
-33:__UG_NAME__ -> 78:a ;
-81:__UG_NAME__ -> 82:a ;
-88:__UG_NAME__ -> 89:a ;
-77:__UG_NAME__ -> 91:a ;
-32:__UG_NAME__ -> 33:a ;
-34:__UG_NAME__ -> 35:a ;
-38:__UG_NAME__ -> 39:a ;
-46:__UG_NAME__ -> 47:a ;
-50:__UG_NAME__ -> 51:a ;
-60:__UG_NAME__ -> 62:a ;
-65:__UG_NAME__ -> 66:a ;
-76:__UG_NAME__ -> 77:a ;
-80:__UG_NAME__ -> 81:a ;
-87:__UG_NAME__ -> 88:a ;
-41:__UG_NAME__ -> 42:gate ;
-0:__UG_NAME__ -> 42:envelope___control___0 ;
-0:__UG_NAME__ -> 42:envelope___control___4 ;
-1:__UG_NAME__ -> 42:envelope___control___5 ;
-2:__UG_NAME__ -> 42:envelope___control___6 ;
-3:__UG_NAME__ -> 42:envelope___control___7 ;
-53:__UG_NAME__ -> 54:gate ;
-24:__UG_NAME__ -> 54:envelope___control___0 ;
-24:__UG_NAME__ -> 54:envelope___control___4 ;
-25:__UG_NAME__ -> 54:envelope___control___5 ;
-26:__UG_NAME__ -> 54:envelope___control___6 ;
-27:__UG_NAME__ -> 54:envelope___control___7 ;
-68:__UG_NAME__ -> 69:gate ;
-20:__UG_NAME__ -> 69:envelope___control___0 ;
-20:__UG_NAME__ -> 69:envelope___control___4 ;
-21:__UG_NAME__ -> 69:envelope___control___5 ;
-22:__UG_NAME__ -> 69:envelope___control___6 ;
-23:__UG_NAME__ -> 69:envelope___control___7 ;
-16:__UG_NAME__ -> 74:envelope___control___4 ;
-12:__UG_NAME__ -> 74:envelope___control___5 ;
-19:__UG_NAME__ -> 74:envelope___control___6 ;
-30:__UG_NAME__ -> 74:envelope___select___8 ;
-13:__UG_NAME__ -> 74:envelope___control___9 ;
-19:__UG_NAME__ -> 74:envelope___control___10 ;
-18:__UG_NAME__ -> 74:envelope___control___12 ;
-14:__UG_NAME__ -> 74:envelope___control___13 ;
-19:__UG_NAME__ -> 74:envelope___control___14 ;
-15:__UG_NAME__ -> 74:envelope___control___17 ;
-19:__UG_NAME__ -> 74:envelope___control___18 ;
-84:__UG_NAME__ -> 85:gate ;
-4:__UG_NAME__ -> 85:envelope___control___0 ;
-4:__UG_NAME__ -> 85:envelope___control___4 ;
-5:__UG_NAME__ -> 85:envelope___control___5 ;
-6:__UG_NAME__ -> 85:envelope___control___6 ;
-7:__UG_NAME__ -> 85:envelope___control___7 ;
-92:__UG_NAME__ -> 93:gate ;
-8:__UG_NAME__ -> 93:envelope___control___0 ;
-8:__UG_NAME__ -> 93:envelope___control___4 ;
-9:__UG_NAME__ -> 93:envelope___control___5 ;
-10:__UG_NAME__ -> 93:envelope___control___6 ;
-11:__UG_NAME__ -> 93:envelope___control___7 ;
-5:__UG_NAME__ -> 32:in ;
-0:__UG_NAME__ -> 34:in ;
-1:__UG_NAME__ -> 38:in ;
-24:__UG_NAME__ -> 46:in ;
-25:__UG_NAME__ -> 50:in ;
-20:__UG_NAME__ -> 60:in ;
-21:__UG_NAME__ -> 65:in ;
-9:__UG_NAME__ -> 76:in ;
-4:__UG_NAME__ -> 80:in ;
-8:__UG_NAME__ -> 87:in ;
-70:__UG_NAME__ -> 71:freq ;
-59:__UG_NAME__ -> 71:in ;
-42:__UG_NAME__ -> 43:a ;
-55:__UG_NAME__ -> 56:a ;
-69:__UG_NAME__ -> 70:a ;
-71:__UG_NAME__ -> 72:in ;
-94:__UG_NAME__ -> 95:signals___pan2___0 ;
-94:__UG_NAME__ -> 95:signals___pan2___1 ;
-28:__UG_NAME__ -> 95:bus ;
-85:__UG_NAME__ -> 94:level ;
-93:__UG_NAME__ -> 94:pos ;
-75:__UG_NAME__ -> 94:in ;
-43:__UG_NAME__ -> 44:freq ;
-56:__UG_NAME__ -> 57:freq ;
-17:__UG_NAME__ -> 30:array___control___0 ;
-18:__UG_NAME__ -> 30:array___control___1 ;
-29:__UG_NAME__ -> 30:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-dull_bell.dot b/etc/synthdefs/graphviz/sonic-pi-dull_bell.dot
deleted file mode 100644
index 0914434..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-dull_bell.dot
+++ /dev/null
@@ -1,258 +0,0 @@
-digraph synthdef {
-32 [label = "{{ <a> 3.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> 0.5} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> 0.56|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> 0.125} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> 0.5} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> 1.19|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> 0.125} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> 0.125} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> 0.5} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-77 [label = "{{ <a> 3.76|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-25 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-86 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-88 [label = "{{ <in> in|<amp> amp 1.0E-4|<time> time 0.1|<action> action 2.0} |<__UG_NAME__>detect-silence }" style="filled, bold, rounded"  shape=record rankdir=LR];
-30 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|1.0|0.0|<envelope___control___8>|<envelope___binary____op____u____gen___9>|1.0|0.0|<envelope___control___12>|<envelope___binary____op____u____gen___13>|1.0|0.0|0.0|<envelope___binary____op____u____gen___17>|1.0|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 0.0625|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|1.0|0.0|<envelope___control___8>|<envelope___binary____op____u____gen___9>|1.0|0.0|<envelope___control___12>|<envelope___binary____op____u____gen___13>|1.0|0.0|0.0|<envelope___binary____op____u____gen___17>|1.0|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 0.5|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|1.0|0.0|<envelope___control___8>|<envelope___binary____op____u____gen___9>|1.0|0.0|<envelope___control___12>|<envelope___binary____op____u____gen___13>|1.0|0.0|0.0|<envelope___binary____op____u____gen___17>|1.0|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 0.25|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|1.0|0.0|<envelope___control___8>|<envelope___binary____op____u____gen___9>|1.0|0.0|<envelope___control___12>|<envelope___binary____op____u____gen___13>|1.0|0.0|0.0|<envelope___binary____op____u____gen___17>|1.0|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 0.125|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-21 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-84 [label = "{{ <in> in|<pos> pos|<level> level 1.0} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-87 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-36 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-50 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-78 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-31:__UG_NAME__ -> 32:b ;
-13:__UG_NAME__ -> 34:a ;
-31:__UG_NAME__ -> 35:b ;
-15:__UG_NAME__ -> 37:a ;
-15:__UG_NAME__ -> 47:a ;
-15:__UG_NAME__ -> 48:a ;
-31:__UG_NAME__ -> 49:b ;
-13:__UG_NAME__ -> 60:a ;
-14:__UG_NAME__ -> 61:a ;
-13:__UG_NAME__ -> 63:a ;
-14:__UG_NAME__ -> 64:a ;
-36:__UG_NAME__ -> 66:b ;
-65:__UG_NAME__ -> 66:a ;
-14:__UG_NAME__ -> 67:a ;
-50:__UG_NAME__ -> 69:b ;
-68:__UG_NAME__ -> 69:a ;
-13:__UG_NAME__ -> 71:a ;
-14:__UG_NAME__ -> 72:a ;
-15:__UG_NAME__ -> 73:a ;
-33:__UG_NAME__ -> 75:b ;
-74:__UG_NAME__ -> 75:a ;
-31:__UG_NAME__ -> 77:b ;
-78:__UG_NAME__ -> 79:b ;
-62:__UG_NAME__ -> 79:a ;
-80:__UG_NAME__ -> 82:b ;
-81:__UG_NAME__ -> 82:a ;
-24:__UG_NAME__ -> 25:b ;
-21:__UG_NAME__ -> 25:a ;
-28:__UG_NAME__ -> 29:b ;
-25:__UG_NAME__ -> 29:a ;
-41:__UG_NAME__ -> 42:b ;
-38:__UG_NAME__ -> 42:a ;
-45:__UG_NAME__ -> 46:b ;
-42:__UG_NAME__ -> 46:a ;
-54:__UG_NAME__ -> 55:b ;
-51:__UG_NAME__ -> 55:a ;
-58:__UG_NAME__ -> 59:b ;
-55:__UG_NAME__ -> 59:a ;
-69:__UG_NAME__ -> 70:b ;
-66:__UG_NAME__ -> 70:a ;
-75:__UG_NAME__ -> 76:b ;
-70:__UG_NAME__ -> 76:a ;
-79:__UG_NAME__ -> 80:b ;
-76:__UG_NAME__ -> 80:a ;
-17:__UG_NAME__ -> 86:b ;
-23:__UG_NAME__ -> 24:a ;
-27:__UG_NAME__ -> 28:a ;
-40:__UG_NAME__ -> 41:a ;
-44:__UG_NAME__ -> 45:a ;
-53:__UG_NAME__ -> 54:a ;
-57:__UG_NAME__ -> 58:a ;
-22:__UG_NAME__ -> 23:a ;
-26:__UG_NAME__ -> 27:a ;
-39:__UG_NAME__ -> 40:a ;
-43:__UG_NAME__ -> 44:a ;
-52:__UG_NAME__ -> 53:a ;
-56:__UG_NAME__ -> 57:a ;
-82:__UG_NAME__ -> 88:in ;
-29:__UG_NAME__ -> 30:gate ;
-0:__UG_NAME__ -> 30:envelope___control___0 ;
-0:__UG_NAME__ -> 30:envelope___control___4 ;
-1:__UG_NAME__ -> 30:envelope___control___5 ;
-2:__UG_NAME__ -> 30:envelope___control___6 ;
-3:__UG_NAME__ -> 30:envelope___control___7 ;
-16:__UG_NAME__ -> 62:envelope___control___4 ;
-12:__UG_NAME__ -> 62:envelope___control___5 ;
-18:__UG_NAME__ -> 62:envelope___control___8 ;
-60:__UG_NAME__ -> 62:envelope___binary____op____u____gen___9 ;
-18:__UG_NAME__ -> 62:envelope___control___12 ;
-61:__UG_NAME__ -> 62:envelope___binary____op____u____gen___13 ;
-37:__UG_NAME__ -> 62:envelope___binary____op____u____gen___17 ;
-16:__UG_NAME__ -> 65:envelope___control___4 ;
-12:__UG_NAME__ -> 65:envelope___control___5 ;
-18:__UG_NAME__ -> 65:envelope___control___8 ;
-63:__UG_NAME__ -> 65:envelope___binary____op____u____gen___9 ;
-18:__UG_NAME__ -> 65:envelope___control___12 ;
-64:__UG_NAME__ -> 65:envelope___binary____op____u____gen___13 ;
-48:__UG_NAME__ -> 65:envelope___binary____op____u____gen___17 ;
-16:__UG_NAME__ -> 68:envelope___control___4 ;
-12:__UG_NAME__ -> 68:envelope___control___5 ;
-18:__UG_NAME__ -> 68:envelope___control___8 ;
-34:__UG_NAME__ -> 68:envelope___binary____op____u____gen___9 ;
-18:__UG_NAME__ -> 68:envelope___control___12 ;
-67:__UG_NAME__ -> 68:envelope___binary____op____u____gen___13 ;
-47:__UG_NAME__ -> 68:envelope___binary____op____u____gen___17 ;
-16:__UG_NAME__ -> 74:envelope___control___4 ;
-12:__UG_NAME__ -> 74:envelope___control___5 ;
-18:__UG_NAME__ -> 74:envelope___control___8 ;
-71:__UG_NAME__ -> 74:envelope___binary____op____u____gen___9 ;
-18:__UG_NAME__ -> 74:envelope___control___12 ;
-72:__UG_NAME__ -> 74:envelope___binary____op____u____gen___13 ;
-73:__UG_NAME__ -> 74:envelope___binary____op____u____gen___17 ;
-46:__UG_NAME__ -> 81:gate ;
-4:__UG_NAME__ -> 81:envelope___control___0 ;
-4:__UG_NAME__ -> 81:envelope___control___4 ;
-5:__UG_NAME__ -> 81:envelope___control___5 ;
-6:__UG_NAME__ -> 81:envelope___control___6 ;
-7:__UG_NAME__ -> 81:envelope___control___7 ;
-59:__UG_NAME__ -> 83:gate ;
-8:__UG_NAME__ -> 83:envelope___control___0 ;
-8:__UG_NAME__ -> 83:envelope___control___4 ;
-9:__UG_NAME__ -> 83:envelope___control___5 ;
-10:__UG_NAME__ -> 83:envelope___control___6 ;
-11:__UG_NAME__ -> 83:envelope___control___7 ;
-0:__UG_NAME__ -> 22:in ;
-1:__UG_NAME__ -> 26:in ;
-4:__UG_NAME__ -> 39:in ;
-5:__UG_NAME__ -> 43:in ;
-8:__UG_NAME__ -> 52:in ;
-9:__UG_NAME__ -> 56:in ;
-30:__UG_NAME__ -> 31:a ;
-84:__UG_NAME__ -> 85:signals___pan2___0 ;
-84:__UG_NAME__ -> 85:signals___pan2___1 ;
-20:__UG_NAME__ -> 85:bus ;
-83:__UG_NAME__ -> 84:pos ;
-82:__UG_NAME__ -> 84:in ;
-17:__UG_NAME__ -> 87:array___control___0 ;
-18:__UG_NAME__ -> 87:array___control___1 ;
-86:__UG_NAME__ -> 87:which ;
-32:__UG_NAME__ -> 33:freq ;
-35:__UG_NAME__ -> 36:freq ;
-49:__UG_NAME__ -> 50:freq ;
-77:__UG_NAME__ -> 78:freq ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fm.dot b/etc/synthdefs/graphviz/sonic-pi-fm.dot
deleted file mode 100644
index d42b2dd..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fm.dot
+++ /dev/null
@@ -1,316 +0,0 @@
-digraph synthdef {
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-96 [label = "{{ <a> 0.8|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :divisor
- default: 2.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :divisor_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :divisor_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :divisor_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :depth
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :depth_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :depth_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :depth_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-108 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-45 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-73 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-56:__UG_NAME__ -> 57:b ;
-43:__UG_NAME__ -> 57:a ;
-57:__UG_NAME__ -> 58:b ;
-46:__UG_NAME__ -> 58:a ;
-70:__UG_NAME__ -> 71:b ;
-58:__UG_NAME__ -> 71:a ;
-94:__UG_NAME__ -> 95:b ;
-46:__UG_NAME__ -> 95:a ;
-95:__UG_NAME__ -> 96:b ;
-36:__UG_NAME__ -> 37:b ;
-34:__UG_NAME__ -> 37:a ;
-40:__UG_NAME__ -> 41:b ;
-37:__UG_NAME__ -> 41:a ;
-50:__UG_NAME__ -> 51:b ;
-47:__UG_NAME__ -> 51:a ;
-54:__UG_NAME__ -> 55:b ;
-51:__UG_NAME__ -> 55:a ;
-62:__UG_NAME__ -> 63:b ;
-59:__UG_NAME__ -> 63:a ;
-66:__UG_NAME__ -> 67:b ;
-63:__UG_NAME__ -> 67:a ;
-71:__UG_NAME__ -> 72:b ;
-43:__UG_NAME__ -> 72:a ;
-79:__UG_NAME__ -> 80:b ;
-76:__UG_NAME__ -> 80:a ;
-83:__UG_NAME__ -> 84:b ;
-80:__UG_NAME__ -> 84:a ;
-88:__UG_NAME__ -> 89:b ;
-85:__UG_NAME__ -> 89:a ;
-90:__UG_NAME__ -> 91:b ;
-89:__UG_NAME__ -> 91:a ;
-100:__UG_NAME__ -> 101:b ;
-97:__UG_NAME__ -> 101:a ;
-104:__UG_NAME__ -> 105:b ;
-101:__UG_NAME__ -> 105:a ;
-68:__UG_NAME__ -> 69:b ;
-43:__UG_NAME__ -> 69:a ;
-17:__UG_NAME__ -> 44:b ;
-35:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:a ;
-49:__UG_NAME__ -> 50:a ;
-53:__UG_NAME__ -> 54:a ;
-61:__UG_NAME__ -> 62:a ;
-65:__UG_NAME__ -> 66:a ;
-78:__UG_NAME__ -> 79:a ;
-82:__UG_NAME__ -> 83:a ;
-87:__UG_NAME__ -> 88:a ;
-75:__UG_NAME__ -> 90:a ;
-99:__UG_NAME__ -> 100:a ;
-103:__UG_NAME__ -> 104:a ;
-33:__UG_NAME__ -> 35:a ;
-38:__UG_NAME__ -> 39:a ;
-48:__UG_NAME__ -> 49:a ;
-52:__UG_NAME__ -> 53:a ;
-60:__UG_NAME__ -> 61:a ;
-64:__UG_NAME__ -> 65:a ;
-74:__UG_NAME__ -> 75:a ;
-77:__UG_NAME__ -> 78:a ;
-81:__UG_NAME__ -> 82:a ;
-86:__UG_NAME__ -> 87:a ;
-98:__UG_NAME__ -> 99:a ;
-102:__UG_NAME__ -> 103:a ;
-41:__UG_NAME__ -> 42:gate ;
-0:__UG_NAME__ -> 42:envelope___control___0 ;
-0:__UG_NAME__ -> 42:envelope___control___4 ;
-1:__UG_NAME__ -> 42:envelope___control___5 ;
-2:__UG_NAME__ -> 42:envelope___control___6 ;
-3:__UG_NAME__ -> 42:envelope___control___7 ;
-16:__UG_NAME__ -> 46:envelope___control___4 ;
-12:__UG_NAME__ -> 46:envelope___control___5 ;
-19:__UG_NAME__ -> 46:envelope___control___6 ;
-45:__UG_NAME__ -> 46:envelope___select___8 ;
-13:__UG_NAME__ -> 46:envelope___control___9 ;
-19:__UG_NAME__ -> 46:envelope___control___10 ;
-18:__UG_NAME__ -> 46:envelope___control___12 ;
-14:__UG_NAME__ -> 46:envelope___control___13 ;
-19:__UG_NAME__ -> 46:envelope___control___14 ;
-15:__UG_NAME__ -> 46:envelope___control___17 ;
-19:__UG_NAME__ -> 46:envelope___control___18 ;
-55:__UG_NAME__ -> 56:gate ;
-28:__UG_NAME__ -> 56:envelope___control___0 ;
-28:__UG_NAME__ -> 56:envelope___control___4 ;
-29:__UG_NAME__ -> 56:envelope___control___5 ;
-30:__UG_NAME__ -> 56:envelope___control___6 ;
-31:__UG_NAME__ -> 56:envelope___control___7 ;
-67:__UG_NAME__ -> 68:gate ;
-24:__UG_NAME__ -> 68:envelope___control___0 ;
-24:__UG_NAME__ -> 68:envelope___control___4 ;
-25:__UG_NAME__ -> 68:envelope___control___5 ;
-26:__UG_NAME__ -> 68:envelope___control___6 ;
-27:__UG_NAME__ -> 68:envelope___control___7 ;
-91:__UG_NAME__ -> 92:gate ;
-20:__UG_NAME__ -> 92:envelope___control___0 ;
-20:__UG_NAME__ -> 92:envelope___control___4 ;
-21:__UG_NAME__ -> 92:envelope___control___5 ;
-22:__UG_NAME__ -> 92:envelope___control___6 ;
-23:__UG_NAME__ -> 92:envelope___control___7 ;
-105:__UG_NAME__ -> 106:gate ;
-8:__UG_NAME__ -> 106:envelope___control___0 ;
-8:__UG_NAME__ -> 106:envelope___control___4 ;
-9:__UG_NAME__ -> 106:envelope___control___5 ;
-10:__UG_NAME__ -> 106:envelope___control___6 ;
-11:__UG_NAME__ -> 106:envelope___control___7 ;
-84:__UG_NAME__ -> 107:gate ;
-4:__UG_NAME__ -> 107:envelope___control___0 ;
-4:__UG_NAME__ -> 107:envelope___control___4 ;
-5:__UG_NAME__ -> 107:envelope___control___5 ;
-6:__UG_NAME__ -> 107:envelope___control___6 ;
-7:__UG_NAME__ -> 107:envelope___control___7 ;
-0:__UG_NAME__ -> 33:in ;
-1:__UG_NAME__ -> 38:in ;
-28:__UG_NAME__ -> 48:in ;
-29:__UG_NAME__ -> 52:in ;
-24:__UG_NAME__ -> 60:in ;
-25:__UG_NAME__ -> 64:in ;
-21:__UG_NAME__ -> 74:in ;
-4:__UG_NAME__ -> 77:in ;
-5:__UG_NAME__ -> 81:in ;
-20:__UG_NAME__ -> 86:in ;
-8:__UG_NAME__ -> 98:in ;
-9:__UG_NAME__ -> 102:in ;
-93:__UG_NAME__ -> 94:freq ;
-73:__UG_NAME__ -> 94:in ;
-42:__UG_NAME__ -> 43:a ;
-92:__UG_NAME__ -> 93:a ;
-108:__UG_NAME__ -> 109:signals___pan2___0 ;
-108:__UG_NAME__ -> 109:signals___pan2___1 ;
-32:__UG_NAME__ -> 109:bus ;
-107:__UG_NAME__ -> 108:level ;
-106:__UG_NAME__ -> 108:pos ;
-96:__UG_NAME__ -> 108:in ;
-17:__UG_NAME__ -> 45:array___control___0 ;
-18:__UG_NAME__ -> 45:array___control___1 ;
-44:__UG_NAME__ -> 45:which ;
-69:__UG_NAME__ -> 70:freq ;
-72:__UG_NAME__ -> 73:freq ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_band_eq.dot b/etc/synthdefs/graphviz/sonic-pi-fx_band_eq.dot
deleted file mode 100644
index afbb636..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_band_eq.dot
+++ /dev/null
@@ -1,282 +0,0 @@
-digraph synthdef {
-39 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :freq
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :freq_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :freq_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :freq_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :res
- default: 0.6" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :db
- default: 0.6" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :db_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :db_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :db_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-94 [label = "{{ <in> in|<freq> freq|<rq> rq|<db> db} |<__UG_NAME__>mid-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
-96 [label = "{{ <in> in|<freq> freq|<rq> rq|<db> db} |<__UG_NAME__>mid-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-95 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-98 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-38:__UG_NAME__ -> 39:a ;
-38:__UG_NAME__ -> 58:a ;
-61:__UG_NAME__ -> 62:b ;
-60:__UG_NAME__ -> 62:a ;
-61:__UG_NAME__ -> 83:b ;
-60:__UG_NAME__ -> 83:a ;
-28:__UG_NAME__ -> 33:b ;
-32:__UG_NAME__ -> 33:a ;
-36:__UG_NAME__ -> 37:b ;
-33:__UG_NAME__ -> 37:a ;
-44:__UG_NAME__ -> 45:b ;
-41:__UG_NAME__ -> 45:a ;
-46:__UG_NAME__ -> 47:b ;
-45:__UG_NAME__ -> 47:a ;
-53:__UG_NAME__ -> 54:b ;
-50:__UG_NAME__ -> 54:a ;
-74:__UG_NAME__ -> 75:b ;
-57:__UG_NAME__ -> 75:a ;
-76:__UG_NAME__ -> 77:b ;
-75:__UG_NAME__ -> 77:a ;
-68:__UG_NAME__ -> 79:b ;
-54:__UG_NAME__ -> 79:a ;
-84:__UG_NAME__ -> 85:b ;
-59:__UG_NAME__ -> 85:a ;
-65:__UG_NAME__ -> 86:b ;
-85:__UG_NAME__ -> 86:a ;
-49:__UG_NAME__ -> 89:b ;
-72:__UG_NAME__ -> 89:a ;
-91:__UG_NAME__ -> 92:b ;
-89:__UG_NAME__ -> 92:a ;
-39:__UG_NAME__ -> 40:a ;
-58:__UG_NAME__ -> 97:a ;
-27:__UG_NAME__ -> 28:a ;
-35:__UG_NAME__ -> 36:a ;
-43:__UG_NAME__ -> 44:a ;
-30:__UG_NAME__ -> 46:a ;
-48:__UG_NAME__ -> 49:a ;
-52:__UG_NAME__ -> 53:a ;
-64:__UG_NAME__ -> 65:a ;
-67:__UG_NAME__ -> 68:a ;
-73:__UG_NAME__ -> 74:a ;
-56:__UG_NAME__ -> 76:a ;
-81:__UG_NAME__ -> 84:a ;
-90:__UG_NAME__ -> 91:a ;
-26:__UG_NAME__ -> 27:a ;
-29:__UG_NAME__ -> 30:a ;
-34:__UG_NAME__ -> 35:a ;
-42:__UG_NAME__ -> 43:a ;
-31:__UG_NAME__ -> 48:a ;
-51:__UG_NAME__ -> 52:a ;
-55:__UG_NAME__ -> 56:a ;
-63:__UG_NAME__ -> 64:a ;
-66:__UG_NAME__ -> 67:a ;
-71:__UG_NAME__ -> 73:a ;
-80:__UG_NAME__ -> 81:a ;
-69:__UG_NAME__ -> 90:a ;
-37:__UG_NAME__ -> 38:gate ;
-4:__UG_NAME__ -> 38:envelope___control___0 ;
-4:__UG_NAME__ -> 38:envelope___control___4 ;
-5:__UG_NAME__ -> 38:envelope___control___5 ;
-6:__UG_NAME__ -> 38:envelope___control___6 ;
-7:__UG_NAME__ -> 38:envelope___control___7 ;
-47:__UG_NAME__ -> 60:gate ;
-8:__UG_NAME__ -> 60:envelope___control___0 ;
-8:__UG_NAME__ -> 60:envelope___control___4 ;
-9:__UG_NAME__ -> 60:envelope___control___5 ;
-10:__UG_NAME__ -> 60:envelope___control___6 ;
-11:__UG_NAME__ -> 60:envelope___control___7 ;
-77:__UG_NAME__ -> 78:gate ;
-70:__UG_NAME__ -> 78:envelope___mul____add___0 ;
-70:__UG_NAME__ -> 78:envelope___mul____add___4 ;
-17:__UG_NAME__ -> 78:envelope___control___5 ;
-18:__UG_NAME__ -> 78:envelope___control___6 ;
-19:__UG_NAME__ -> 78:envelope___control___7 ;
-79:__UG_NAME__ -> 82:gate ;
-0:__UG_NAME__ -> 82:envelope___control___0 ;
-0:__UG_NAME__ -> 82:envelope___control___4 ;
-1:__UG_NAME__ -> 82:envelope___control___5 ;
-2:__UG_NAME__ -> 82:envelope___control___6 ;
-3:__UG_NAME__ -> 82:envelope___control___7 ;
-86:__UG_NAME__ -> 87:gate ;
-12:__UG_NAME__ -> 87:envelope___control___0 ;
-12:__UG_NAME__ -> 87:envelope___control___4 ;
-13:__UG_NAME__ -> 87:envelope___control___5 ;
-14:__UG_NAME__ -> 87:envelope___control___6 ;
-15:__UG_NAME__ -> 87:envelope___control___7 ;
-92:__UG_NAME__ -> 93:gate ;
-20:__UG_NAME__ -> 93:envelope___control___0 ;
-20:__UG_NAME__ -> 93:envelope___control___4 ;
-21:__UG_NAME__ -> 93:envelope___control___5 ;
-22:__UG_NAME__ -> 93:envelope___control___6 ;
-23:__UG_NAME__ -> 93:envelope___control___7 ;
-4:__UG_NAME__ -> 26:in ;
-9:__UG_NAME__ -> 29:in ;
-20:__UG_NAME__ -> 31:in ;
-5:__UG_NAME__ -> 34:in ;
-8:__UG_NAME__ -> 42:in ;
-0:__UG_NAME__ -> 51:in ;
-17:__UG_NAME__ -> 55:in ;
-13:__UG_NAME__ -> 63:in ;
-1:__UG_NAME__ -> 66:in ;
-21:__UG_NAME__ -> 69:in ;
-70:__UG_NAME__ -> 71:in ;
-12:__UG_NAME__ -> 80:in ;
-24:__UG_NAME__ -> 61:bus ;
-93:__UG_NAME__ -> 94:db ;
-78:__UG_NAME__ -> 94:rq ;
-88:__UG_NAME__ -> 94:freq ;
-83:__UG_NAME__ -> 94:in ;
-93:__UG_NAME__ -> 96:db ;
-78:__UG_NAME__ -> 96:rq ;
-88:__UG_NAME__ -> 96:freq ;
-62:__UG_NAME__ -> 96:in ;
-87:__UG_NAME__ -> 88:a ;
-16:__UG_NAME__ -> 70:in ;
-95:__UG_NAME__ -> 99:signals___x____fade2___0 ;
-98:__UG_NAME__ -> 99:signals___x____fade2___1 ;
-25:__UG_NAME__ -> 99:bus ;
-82:__UG_NAME__ -> 95:level ;
-40:__UG_NAME__ -> 95:pan ;
-94:__UG_NAME__ -> 95:inb ;
-83:__UG_NAME__ -> 95:ina ;
-82:__UG_NAME__ -> 98:level ;
-97:__UG_NAME__ -> 98:pan ;
-96:__UG_NAME__ -> 98:inb ;
-62:__UG_NAME__ -> 98:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_bitcrusher.dot b/etc/synthdefs/graphviz/sonic-pi-fx_bitcrusher.dot
deleted file mode 100644
index 8a4ab6a..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_bitcrusher.dot
+++ /dev/null
@@ -1,294 +0,0 @@
-digraph synthdef {
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-84 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :sample_rate
- default: 10000.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :sample_rate_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sample_rate_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :sample_rate_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :bits
- default: 8.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :bits_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :bits_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :bits_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-59 [label = "{{ <in> in|<rate> rate|<bits> bits} |<__UG_NAME__>decimator }" style="filled, bold, rounded"  shape=record rankdir=LR];
-86 [label = "{{ <in> in|<rate> rate|<bits> bits} |<__UG_NAME__>decimator }" style="filled, bold, rounded"  shape=record rankdir=LR];
-35 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-81 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-87 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-82 [label = "{{ <which> which|{{<array___decimator___0>|<array___lpf___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-99 [label = "{{ <which> which|{{<array___decimator___0>|<array___lpf___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-98 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-102 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-36:__UG_NAME__ -> 37:b ;
-35:__UG_NAME__ -> 37:a ;
-36:__UG_NAME__ -> 38:b ;
-35:__UG_NAME__ -> 38:a ;
-83:__UG_NAME__ -> 84:a ;
-83:__UG_NAME__ -> 100:a ;
-29:__UG_NAME__ -> 30:b ;
-26:__UG_NAME__ -> 30:a ;
-33:__UG_NAME__ -> 34:b ;
-30:__UG_NAME__ -> 34:a ;
-42:__UG_NAME__ -> 43:b ;
-39:__UG_NAME__ -> 43:a ;
-46:__UG_NAME__ -> 47:b ;
-43:__UG_NAME__ -> 47:a ;
-52:__UG_NAME__ -> 53:b ;
-49:__UG_NAME__ -> 53:a ;
-56:__UG_NAME__ -> 57:b ;
-53:__UG_NAME__ -> 57:a ;
-63:__UG_NAME__ -> 64:b ;
-60:__UG_NAME__ -> 64:a ;
-67:__UG_NAME__ -> 68:b ;
-64:__UG_NAME__ -> 68:a ;
-72:__UG_NAME__ -> 73:b ;
-69:__UG_NAME__ -> 73:a ;
-76:__UG_NAME__ -> 77:b ;
-73:__UG_NAME__ -> 77:a ;
-91:__UG_NAME__ -> 92:b ;
-88:__UG_NAME__ -> 92:a ;
-95:__UG_NAME__ -> 96:b ;
-92:__UG_NAME__ -> 96:a ;
-84:__UG_NAME__ -> 85:a ;
-100:__UG_NAME__ -> 101:a ;
-28:__UG_NAME__ -> 29:a ;
-32:__UG_NAME__ -> 33:a ;
-41:__UG_NAME__ -> 42:a ;
-45:__UG_NAME__ -> 46:a ;
-51:__UG_NAME__ -> 52:a ;
-55:__UG_NAME__ -> 56:a ;
-62:__UG_NAME__ -> 63:a ;
-66:__UG_NAME__ -> 67:a ;
-71:__UG_NAME__ -> 72:a ;
-75:__UG_NAME__ -> 76:a ;
-78:__UG_NAME__ -> 79:a ;
-90:__UG_NAME__ -> 91:a ;
-94:__UG_NAME__ -> 95:a ;
-27:__UG_NAME__ -> 28:a ;
-31:__UG_NAME__ -> 32:a ;
-40:__UG_NAME__ -> 41:a ;
-44:__UG_NAME__ -> 45:a ;
-50:__UG_NAME__ -> 51:a ;
-54:__UG_NAME__ -> 55:a ;
-61:__UG_NAME__ -> 62:a ;
-65:__UG_NAME__ -> 66:a ;
-70:__UG_NAME__ -> 71:a ;
-74:__UG_NAME__ -> 75:a ;
-89:__UG_NAME__ -> 90:a ;
-93:__UG_NAME__ -> 94:a ;
-58:__UG_NAME__ -> 59:bits ;
-48:__UG_NAME__ -> 59:rate ;
-38:__UG_NAME__ -> 59:in ;
-58:__UG_NAME__ -> 86:bits ;
-48:__UG_NAME__ -> 86:rate ;
-37:__UG_NAME__ -> 86:in ;
-34:__UG_NAME__ -> 35:gate ;
-8:__UG_NAME__ -> 35:envelope___control___0 ;
-8:__UG_NAME__ -> 35:envelope___control___4 ;
-9:__UG_NAME__ -> 35:envelope___control___5 ;
-10:__UG_NAME__ -> 35:envelope___control___6 ;
-11:__UG_NAME__ -> 35:envelope___control___7 ;
-47:__UG_NAME__ -> 48:gate ;
-12:__UG_NAME__ -> 48:envelope___control___0 ;
-12:__UG_NAME__ -> 48:envelope___control___4 ;
-13:__UG_NAME__ -> 48:envelope___control___5 ;
-14:__UG_NAME__ -> 48:envelope___control___6 ;
-15:__UG_NAME__ -> 48:envelope___control___7 ;
-57:__UG_NAME__ -> 58:gate ;
-16:__UG_NAME__ -> 58:envelope___control___0 ;
-16:__UG_NAME__ -> 58:envelope___control___4 ;
-17:__UG_NAME__ -> 58:envelope___control___5 ;
-18:__UG_NAME__ -> 58:envelope___control___6 ;
-19:__UG_NAME__ -> 58:envelope___control___7 ;
-77:__UG_NAME__ -> 78:gate ;
-20:__UG_NAME__ -> 78:envelope___control___0 ;
-20:__UG_NAME__ -> 78:envelope___control___4 ;
-21:__UG_NAME__ -> 78:envelope___control___5 ;
-22:__UG_NAME__ -> 78:envelope___control___6 ;
-23:__UG_NAME__ -> 78:envelope___control___7 ;
-68:__UG_NAME__ -> 83:gate ;
-4:__UG_NAME__ -> 83:envelope___control___0 ;
-4:__UG_NAME__ -> 83:envelope___control___4 ;
-5:__UG_NAME__ -> 83:envelope___control___5 ;
-6:__UG_NAME__ -> 83:envelope___control___6 ;
-7:__UG_NAME__ -> 83:envelope___control___7 ;
-96:__UG_NAME__ -> 97:gate ;
-0:__UG_NAME__ -> 97:envelope___control___0 ;
-0:__UG_NAME__ -> 97:envelope___control___4 ;
-1:__UG_NAME__ -> 97:envelope___control___5 ;
-2:__UG_NAME__ -> 97:envelope___control___6 ;
-3:__UG_NAME__ -> 97:envelope___control___7 ;
-8:__UG_NAME__ -> 27:in ;
-9:__UG_NAME__ -> 31:in ;
-12:__UG_NAME__ -> 40:in ;
-13:__UG_NAME__ -> 44:in ;
-16:__UG_NAME__ -> 50:in ;
-17:__UG_NAME__ -> 54:in ;
-4:__UG_NAME__ -> 61:in ;
-5:__UG_NAME__ -> 65:in ;
-20:__UG_NAME__ -> 70:in ;
-21:__UG_NAME__ -> 74:in ;
-0:__UG_NAME__ -> 89:in ;
-1:__UG_NAME__ -> 93:in ;
-24:__UG_NAME__ -> 36:bus ;
-80:__UG_NAME__ -> 81:freq ;
-59:__UG_NAME__ -> 81:in ;
-80:__UG_NAME__ -> 87:freq ;
-86:__UG_NAME__ -> 87:in ;
-78:__UG_NAME__ -> 80:a ;
-102:__UG_NAME__ -> 103:signals___x____fade2___0 ;
-98:__UG_NAME__ -> 103:signals___x____fade2___1 ;
-25:__UG_NAME__ -> 103:bus ;
-59:__UG_NAME__ -> 82:array___decimator___0 ;
-81:__UG_NAME__ -> 82:array___lpf___1 ;
-79:__UG_NAME__ -> 82:which ;
-86:__UG_NAME__ -> 99:array___decimator___0 ;
-87:__UG_NAME__ -> 99:array___lpf___1 ;
-79:__UG_NAME__ -> 99:which ;
-97:__UG_NAME__ -> 98:level ;
-85:__UG_NAME__ -> 98:pan ;
-82:__UG_NAME__ -> 98:inb ;
-38:__UG_NAME__ -> 98:ina ;
-97:__UG_NAME__ -> 102:level ;
-101:__UG_NAME__ -> 102:pan ;
-99:__UG_NAME__ -> 102:inb ;
-37:__UG_NAME__ -> 102:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_bpf.dot b/etc/synthdefs/graphviz/sonic-pi-fx_bpf.dot
deleted file mode 100644
index 091fbba..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_bpf.dot
+++ /dev/null
@@ -1,242 +0,0 @@
-digraph synthdef {
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-81 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :centre
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :centre_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :centre_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :centre_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :res
- default: 0.6" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-79 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-84 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-55:__UG_NAME__ -> 56:b ;
-54:__UG_NAME__ -> 56:a ;
-34:__UG_NAME__ -> 67:a ;
-55:__UG_NAME__ -> 80:b ;
-54:__UG_NAME__ -> 80:a ;
-34:__UG_NAME__ -> 82:a ;
-28:__UG_NAME__ -> 29:b ;
-25:__UG_NAME__ -> 29:a ;
-32:__UG_NAME__ -> 33:b ;
-29:__UG_NAME__ -> 33:a ;
-24:__UG_NAME__ -> 36:b ;
-35:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:b ;
-36:__UG_NAME__ -> 40:a ;
-48:__UG_NAME__ -> 49:b ;
-45:__UG_NAME__ -> 49:a ;
-52:__UG_NAME__ -> 53:b ;
-49:__UG_NAME__ -> 53:a ;
-62:__UG_NAME__ -> 63:b ;
-58:__UG_NAME__ -> 63:a ;
-44:__UG_NAME__ -> 64:b ;
-63:__UG_NAME__ -> 64:a ;
-72:__UG_NAME__ -> 73:b ;
-69:__UG_NAME__ -> 73:a ;
-76:__UG_NAME__ -> 77:b ;
-73:__UG_NAME__ -> 77:a ;
-67:__UG_NAME__ -> 68:a ;
-82:__UG_NAME__ -> 83:a ;
-23:__UG_NAME__ -> 24:a ;
-27:__UG_NAME__ -> 28:a ;
-31:__UG_NAME__ -> 32:a ;
-38:__UG_NAME__ -> 39:a ;
-43:__UG_NAME__ -> 44:a ;
-47:__UG_NAME__ -> 48:a ;
-51:__UG_NAME__ -> 52:a ;
-61:__UG_NAME__ -> 62:a ;
-71:__UG_NAME__ -> 72:a ;
-75:__UG_NAME__ -> 76:a ;
-22:__UG_NAME__ -> 23:a ;
-26:__UG_NAME__ -> 27:a ;
-30:__UG_NAME__ -> 31:a ;
-37:__UG_NAME__ -> 38:a ;
-42:__UG_NAME__ -> 43:a ;
-46:__UG_NAME__ -> 47:a ;
-50:__UG_NAME__ -> 51:a ;
-60:__UG_NAME__ -> 61:a ;
-70:__UG_NAME__ -> 71:a ;
-74:__UG_NAME__ -> 75:a ;
-65:__UG_NAME__ -> 66:rq ;
-57:__UG_NAME__ -> 66:freq ;
-56:__UG_NAME__ -> 66:in ;
-65:__UG_NAME__ -> 81:rq ;
-57:__UG_NAME__ -> 81:freq ;
-80:__UG_NAME__ -> 81:in ;
-33:__UG_NAME__ -> 34:gate ;
-4:__UG_NAME__ -> 34:envelope___control___0 ;
-4:__UG_NAME__ -> 34:envelope___control___4 ;
-5:__UG_NAME__ -> 34:envelope___control___5 ;
-6:__UG_NAME__ -> 34:envelope___control___6 ;
-7:__UG_NAME__ -> 34:envelope___control___7 ;
-40:__UG_NAME__ -> 41:gate ;
-12:__UG_NAME__ -> 41:envelope___control___0 ;
-12:__UG_NAME__ -> 41:envelope___control___4 ;
-13:__UG_NAME__ -> 41:envelope___control___5 ;
-14:__UG_NAME__ -> 41:envelope___control___6 ;
-15:__UG_NAME__ -> 41:envelope___control___7 ;
-53:__UG_NAME__ -> 54:gate ;
-8:__UG_NAME__ -> 54:envelope___control___0 ;
-8:__UG_NAME__ -> 54:envelope___control___4 ;
-9:__UG_NAME__ -> 54:envelope___control___5 ;
-10:__UG_NAME__ -> 54:envelope___control___6 ;
-11:__UG_NAME__ -> 54:envelope___control___7 ;
-64:__UG_NAME__ -> 65:gate ;
-59:__UG_NAME__ -> 65:envelope___mul____add___0 ;
-59:__UG_NAME__ -> 65:envelope___mul____add___4 ;
-17:__UG_NAME__ -> 65:envelope___control___5 ;
-18:__UG_NAME__ -> 65:envelope___control___6 ;
-19:__UG_NAME__ -> 65:envelope___control___7 ;
-77:__UG_NAME__ -> 78:gate ;
-0:__UG_NAME__ -> 78:envelope___control___0 ;
-0:__UG_NAME__ -> 78:envelope___control___4 ;
-1:__UG_NAME__ -> 78:envelope___control___5 ;
-2:__UG_NAME__ -> 78:envelope___control___6 ;
-3:__UG_NAME__ -> 78:envelope___control___7 ;
-12:__UG_NAME__ -> 22:in ;
-4:__UG_NAME__ -> 26:in ;
-5:__UG_NAME__ -> 30:in ;
-13:__UG_NAME__ -> 37:in ;
-17:__UG_NAME__ -> 42:in ;
-8:__UG_NAME__ -> 46:in ;
-9:__UG_NAME__ -> 50:in ;
-59:__UG_NAME__ -> 60:in ;
-0:__UG_NAME__ -> 70:in ;
-1:__UG_NAME__ -> 74:in ;
-20:__UG_NAME__ -> 55:bus ;
-41:__UG_NAME__ -> 57:a ;
-16:__UG_NAME__ -> 59:in ;
-84:__UG_NAME__ -> 85:signals___x____fade2___0 ;
-79:__UG_NAME__ -> 85:signals___x____fade2___1 ;
-21:__UG_NAME__ -> 85:bus ;
-78:__UG_NAME__ -> 79:level ;
-68:__UG_NAME__ -> 79:pan ;
-66:__UG_NAME__ -> 79:inb ;
-56:__UG_NAME__ -> 79:ina ;
-78:__UG_NAME__ -> 84:level ;
-83:__UG_NAME__ -> 84:pan ;
-81:__UG_NAME__ -> 84:inb ;
-80:__UG_NAME__ -> 84:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_compressor.dot b/etc/synthdefs/graphviz/sonic-pi-fx_compressor.dot
deleted file mode 100644
index bbd87bb..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_compressor.dot
+++ /dev/null
@@ -1,365 +0,0 @@
-digraph synthdef {
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-84 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-119 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <in> in|<control> control|<thresh> thresh|<slope____below> slope-below|<slope____above> slope-above|<clamp____time> clamp-time|<relax____time> relax-time} |<__UG_NAME__>compander }" style="filled, bold, rounded"  shape=record rankdir=LR];
-124 [label = "{{ <in> in|<control> control|<thresh> thresh|<slope____below> slope-below|<slope____above> slope-above|<clamp____time> clamp-time|<relax____time> relax-time} |<__UG_NAME__>compander }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :threshold
- default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :threshold_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :threshold_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :threshold_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :clamp_time
- default: 0.01" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :clamp_time_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :clamp_time_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :clamp_time_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :slope_above
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :slope_above_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :slope_above_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :slope_above_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :slope_below
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :slope_below_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :slope_below_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :slope_below_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :relax_time
- default: 0.01" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :relax_time_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :relax_time_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :relax_time_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-48 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-127 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-122 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-126 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-70:__UG_NAME__ -> 71:b ;
-69:__UG_NAME__ -> 71:a ;
-70:__UG_NAME__ -> 84:b ;
-69:__UG_NAME__ -> 84:a ;
-118:__UG_NAME__ -> 119:a ;
-118:__UG_NAME__ -> 123:a ;
-42:__UG_NAME__ -> 43:b ;
-39:__UG_NAME__ -> 43:a ;
-46:__UG_NAME__ -> 47:b ;
-43:__UG_NAME__ -> 47:a ;
-54:__UG_NAME__ -> 55:b ;
-51:__UG_NAME__ -> 55:a ;
-57:__UG_NAME__ -> 58:b ;
-55:__UG_NAME__ -> 58:a ;
-63:__UG_NAME__ -> 64:b ;
-60:__UG_NAME__ -> 64:a ;
-67:__UG_NAME__ -> 68:b ;
-64:__UG_NAME__ -> 68:a ;
-75:__UG_NAME__ -> 76:b ;
-72:__UG_NAME__ -> 76:a ;
-77:__UG_NAME__ -> 78:b ;
-76:__UG_NAME__ -> 78:a ;
-84:__UG_NAME__ -> 85:b ;
-71:__UG_NAME__ -> 85:a ;
-89:__UG_NAME__ -> 90:b ;
-80:__UG_NAME__ -> 90:a ;
-36:__UG_NAME__ -> 91:b ;
-90:__UG_NAME__ -> 91:a ;
-101:__UG_NAME__ -> 102:b ;
-99:__UG_NAME__ -> 102:a ;
-83:__UG_NAME__ -> 103:b ;
-102:__UG_NAME__ -> 103:a ;
-108:__UG_NAME__ -> 109:b ;
-105:__UG_NAME__ -> 109:a ;
-96:__UG_NAME__ -> 110:b ;
-109:__UG_NAME__ -> 110:a ;
-114:__UG_NAME__ -> 115:b ;
-113:__UG_NAME__ -> 115:a ;
-116:__UG_NAME__ -> 117:b ;
-115:__UG_NAME__ -> 117:a ;
-119:__UG_NAME__ -> 120:a ;
-123:__UG_NAME__ -> 125:a ;
-85:__UG_NAME__ -> 98:a ;
-35:__UG_NAME__ -> 36:a ;
-41:__UG_NAME__ -> 42:a ;
-45:__UG_NAME__ -> 46:a ;
-53:__UG_NAME__ -> 54:a ;
-56:__UG_NAME__ -> 57:a ;
-62:__UG_NAME__ -> 63:a ;
-66:__UG_NAME__ -> 67:a ;
-74:__UG_NAME__ -> 75:a ;
-50:__UG_NAME__ -> 77:a ;
-82:__UG_NAME__ -> 83:a ;
-88:__UG_NAME__ -> 89:a ;
-95:__UG_NAME__ -> 96:a ;
-100:__UG_NAME__ -> 101:a ;
-107:__UG_NAME__ -> 108:a ;
-93:__UG_NAME__ -> 114:a ;
-87:__UG_NAME__ -> 116:a ;
-34:__UG_NAME__ -> 35:a ;
-40:__UG_NAME__ -> 41:a ;
-44:__UG_NAME__ -> 45:a ;
-49:__UG_NAME__ -> 50:a ;
-52:__UG_NAME__ -> 53:a ;
-38:__UG_NAME__ -> 56:a ;
-61:__UG_NAME__ -> 62:a ;
-65:__UG_NAME__ -> 66:a ;
-73:__UG_NAME__ -> 74:a ;
-81:__UG_NAME__ -> 82:a ;
-86:__UG_NAME__ -> 87:a ;
-37:__UG_NAME__ -> 88:a ;
-79:__UG_NAME__ -> 93:a ;
-94:__UG_NAME__ -> 95:a ;
-97:__UG_NAME__ -> 100:a ;
-106:__UG_NAME__ -> 107:a ;
-59:__UG_NAME__ -> 112:relax____time ;
-111:__UG_NAME__ -> 112:clamp____time ;
-48:__UG_NAME__ -> 112:slope____above ;
-104:__UG_NAME__ -> 112:slope____below ;
-92:__UG_NAME__ -> 112:thresh ;
-98:__UG_NAME__ -> 112:control ;
-84:__UG_NAME__ -> 112:in ;
-59:__UG_NAME__ -> 124:relax____time ;
-111:__UG_NAME__ -> 124:clamp____time ;
-48:__UG_NAME__ -> 124:slope____above ;
-104:__UG_NAME__ -> 124:slope____below ;
-92:__UG_NAME__ -> 124:thresh ;
-98:__UG_NAME__ -> 124:control ;
-71:__UG_NAME__ -> 124:in ;
-47:__UG_NAME__ -> 48:gate ;
-20:__UG_NAME__ -> 48:envelope___control___0 ;
-20:__UG_NAME__ -> 48:envelope___control___4 ;
-21:__UG_NAME__ -> 48:envelope___control___5 ;
-22:__UG_NAME__ -> 48:envelope___control___6 ;
-23:__UG_NAME__ -> 48:envelope___control___7 ;
-58:__UG_NAME__ -> 59:gate ;
-28:__UG_NAME__ -> 59:envelope___control___0 ;
-28:__UG_NAME__ -> 59:envelope___control___4 ;
-29:__UG_NAME__ -> 59:envelope___control___5 ;
-30:__UG_NAME__ -> 59:envelope___control___6 ;
-31:__UG_NAME__ -> 59:envelope___control___7 ;
-68:__UG_NAME__ -> 69:gate ;
-8:__UG_NAME__ -> 69:envelope___control___0 ;
-8:__UG_NAME__ -> 69:envelope___control___4 ;
-9:__UG_NAME__ -> 69:envelope___control___5 ;
-10:__UG_NAME__ -> 69:envelope___control___6 ;
-11:__UG_NAME__ -> 69:envelope___control___7 ;
-91:__UG_NAME__ -> 92:gate ;
-12:__UG_NAME__ -> 92:envelope___control___0 ;
-12:__UG_NAME__ -> 92:envelope___control___4 ;
-13:__UG_NAME__ -> 92:envelope___control___5 ;
-14:__UG_NAME__ -> 92:envelope___control___6 ;
-15:__UG_NAME__ -> 92:envelope___control___7 ;
-103:__UG_NAME__ -> 104:gate ;
-24:__UG_NAME__ -> 104:envelope___control___0 ;
-24:__UG_NAME__ -> 104:envelope___control___4 ;
-25:__UG_NAME__ -> 104:envelope___control___5 ;
-26:__UG_NAME__ -> 104:envelope___control___6 ;
-27:__UG_NAME__ -> 104:envelope___control___7 ;
-110:__UG_NAME__ -> 111:gate ;
-16:__UG_NAME__ -> 111:envelope___control___0 ;
-16:__UG_NAME__ -> 111:envelope___control___4 ;
-17:__UG_NAME__ -> 111:envelope___control___5 ;
-18:__UG_NAME__ -> 111:envelope___control___6 ;
-19:__UG_NAME__ -> 111:envelope___control___7 ;
-117:__UG_NAME__ -> 118:gate ;
-4:__UG_NAME__ -> 118:envelope___control___0 ;
-4:__UG_NAME__ -> 118:envelope___control___4 ;
-5:__UG_NAME__ -> 118:envelope___control___5 ;
-6:__UG_NAME__ -> 118:envelope___control___6 ;
-7:__UG_NAME__ -> 118:envelope___control___7 ;
-78:__UG_NAME__ -> 121:gate ;
-0:__UG_NAME__ -> 121:envelope___control___0 ;
-0:__UG_NAME__ -> 121:envelope___control___4 ;
-1:__UG_NAME__ -> 121:envelope___control___5 ;
-2:__UG_NAME__ -> 121:envelope___control___6 ;
-3:__UG_NAME__ -> 121:envelope___control___7 ;
-13:__UG_NAME__ -> 34:in ;
-12:__UG_NAME__ -> 37:in ;
-29:__UG_NAME__ -> 38:in ;
-20:__UG_NAME__ -> 40:in ;
-21:__UG_NAME__ -> 44:in ;
-1:__UG_NAME__ -> 49:in ;
-28:__UG_NAME__ -> 52:in ;
-8:__UG_NAME__ -> 61:in ;
-9:__UG_NAME__ -> 65:in ;
-0:__UG_NAME__ -> 73:in ;
-4:__UG_NAME__ -> 79:in ;
-25:__UG_NAME__ -> 81:in ;
-5:__UG_NAME__ -> 86:in ;
-17:__UG_NAME__ -> 94:in ;
-24:__UG_NAME__ -> 97:in ;
-16:__UG_NAME__ -> 106:in ;
-32:__UG_NAME__ -> 70:bus ;
-126:__UG_NAME__ -> 127:signals___x____fade2___0 ;
-122:__UG_NAME__ -> 127:signals___x____fade2___1 ;
-33:__UG_NAME__ -> 127:bus ;
-121:__UG_NAME__ -> 122:level ;
-120:__UG_NAME__ -> 122:pan ;
-112:__UG_NAME__ -> 122:inb ;
-84:__UG_NAME__ -> 122:ina ;
-121:__UG_NAME__ -> 126:level ;
-125:__UG_NAME__ -> 126:pan ;
-124:__UG_NAME__ -> 126:inb ;
-71:__UG_NAME__ -> 126:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_distortion.dot b/etc/synthdefs/graphviz/sonic-pi-fx_distortion.dot
deleted file mode 100644
index 3216243..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_distortion.dot
+++ /dev/null
@@ -1,227 +0,0 @@
-digraph synthdef {
-31 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-41 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-20 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :distort
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :distort_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :distort_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :distort_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-19 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-21 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-18 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-81 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-76 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-80 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-18:__UG_NAME__ -> 31:b ;
-30:__UG_NAME__ -> 31:a ;
-40:__UG_NAME__ -> 41:b ;
-18:__UG_NAME__ -> 44:b ;
-30:__UG_NAME__ -> 44:a ;
-45:__UG_NAME__ -> 46:b ;
-43:__UG_NAME__ -> 46:a ;
-32:__UG_NAME__ -> 65:b ;
-43:__UG_NAME__ -> 65:a ;
-66:__UG_NAME__ -> 67:b ;
-44:__UG_NAME__ -> 67:a ;
-57:__UG_NAME__ -> 68:a ;
-66:__UG_NAME__ -> 70:b ;
-31:__UG_NAME__ -> 70:a ;
-57:__UG_NAME__ -> 78:a ;
-24:__UG_NAME__ -> 25:b ;
-21:__UG_NAME__ -> 25:a ;
-28:__UG_NAME__ -> 29:b ;
-25:__UG_NAME__ -> 29:a ;
-34:__UG_NAME__ -> 35:b ;
-33:__UG_NAME__ -> 35:a ;
-38:__UG_NAME__ -> 39:b ;
-35:__UG_NAME__ -> 39:a ;
-46:__UG_NAME__ -> 47:b ;
-51:__UG_NAME__ -> 52:b ;
-48:__UG_NAME__ -> 52:a ;
-55:__UG_NAME__ -> 56:b ;
-52:__UG_NAME__ -> 56:a ;
-61:__UG_NAME__ -> 62:b ;
-58:__UG_NAME__ -> 62:a ;
-43:__UG_NAME__ -> 66:b ;
-65:__UG_NAME__ -> 71:b ;
-73:__UG_NAME__ -> 74:b ;
-62:__UG_NAME__ -> 74:a ;
-40:__UG_NAME__ -> 42:b ;
-68:__UG_NAME__ -> 69:a ;
-78:__UG_NAME__ -> 79:a ;
-42:__UG_NAME__ -> 43:b ;
-41:__UG_NAME__ -> 43:a ;
-71:__UG_NAME__ -> 72:b ;
-70:__UG_NAME__ -> 72:a ;
-47:__UG_NAME__ -> 77:b ;
-67:__UG_NAME__ -> 77:a ;
-23:__UG_NAME__ -> 24:a ;
-27:__UG_NAME__ -> 28:a ;
-20:__UG_NAME__ -> 34:a ;
-37:__UG_NAME__ -> 38:a ;
-50:__UG_NAME__ -> 51:a ;
-54:__UG_NAME__ -> 55:a ;
-60:__UG_NAME__ -> 61:a ;
-64:__UG_NAME__ -> 73:a ;
-19:__UG_NAME__ -> 20:a ;
-22:__UG_NAME__ -> 23:a ;
-26:__UG_NAME__ -> 27:a ;
-31:__UG_NAME__ -> 32:a ;
-36:__UG_NAME__ -> 37:a ;
-44:__UG_NAME__ -> 45:a ;
-49:__UG_NAME__ -> 50:a ;
-53:__UG_NAME__ -> 54:a ;
-59:__UG_NAME__ -> 60:a ;
-63:__UG_NAME__ -> 64:a ;
-29:__UG_NAME__ -> 30:gate ;
-8:__UG_NAME__ -> 30:envelope___control___0 ;
-8:__UG_NAME__ -> 30:envelope___control___4 ;
-9:__UG_NAME__ -> 30:envelope___control___5 ;
-10:__UG_NAME__ -> 30:envelope___control___6 ;
-11:__UG_NAME__ -> 30:envelope___control___7 ;
-39:__UG_NAME__ -> 40:gate ;
-12:__UG_NAME__ -> 40:envelope___control___0 ;
-12:__UG_NAME__ -> 40:envelope___control___4 ;
-13:__UG_NAME__ -> 40:envelope___control___5 ;
-14:__UG_NAME__ -> 40:envelope___control___6 ;
-15:__UG_NAME__ -> 40:envelope___control___7 ;
-56:__UG_NAME__ -> 57:gate ;
-4:__UG_NAME__ -> 57:envelope___control___0 ;
-4:__UG_NAME__ -> 57:envelope___control___4 ;
-5:__UG_NAME__ -> 57:envelope___control___5 ;
-6:__UG_NAME__ -> 57:envelope___control___6 ;
-7:__UG_NAME__ -> 57:envelope___control___7 ;
-74:__UG_NAME__ -> 75:gate ;
-0:__UG_NAME__ -> 75:envelope___control___0 ;
-0:__UG_NAME__ -> 75:envelope___control___4 ;
-1:__UG_NAME__ -> 75:envelope___control___5 ;
-2:__UG_NAME__ -> 75:envelope___control___6 ;
-3:__UG_NAME__ -> 75:envelope___control___7 ;
-12:__UG_NAME__ -> 19:in ;
-8:__UG_NAME__ -> 22:in ;
-9:__UG_NAME__ -> 26:in ;
-13:__UG_NAME__ -> 36:in ;
-4:__UG_NAME__ -> 49:in ;
-5:__UG_NAME__ -> 53:in ;
-0:__UG_NAME__ -> 59:in ;
-1:__UG_NAME__ -> 63:in ;
-16:__UG_NAME__ -> 18:bus ;
-76:__UG_NAME__ -> 81:signals___x____fade2___0 ;
-80:__UG_NAME__ -> 81:signals___x____fade2___1 ;
-17:__UG_NAME__ -> 81:bus ;
-75:__UG_NAME__ -> 76:level ;
-69:__UG_NAME__ -> 76:pan ;
-72:__UG_NAME__ -> 76:inb ;
-31:__UG_NAME__ -> 76:ina ;
-75:__UG_NAME__ -> 80:level ;
-79:__UG_NAME__ -> 80:pan ;
-77:__UG_NAME__ -> 80:inb ;
-44:__UG_NAME__ -> 80:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_echo.dot b/etc/synthdefs/graphviz/sonic-pi-fx_echo.dot
deleted file mode 100644
index 7da8d21..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_echo.dot
+++ /dev/null
@@ -1,249 +0,0 @@
-digraph synthdef {
-42 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <in> in|<max____delay____time> max-delay-time|<delay____time> delay-time|<decay____time> decay-time} |<__UG_NAME__>comb-n }" style="filled, bold, rounded"  shape=record rankdir=LR];
-82 [label = "{{ <in> in|<max____delay____time> max-delay-time|<delay____time> delay-time|<decay____time> decay-time} |<__UG_NAME__>comb-n }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :phase
- default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :phase_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :phase_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :phase_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :decay
- default: 2.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :decay_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :decay_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :max_phase
- default: 2.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-41 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-86 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-80 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-85 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-41:__UG_NAME__ -> 42:a ;
-65:__UG_NAME__ -> 66:b ;
-64:__UG_NAME__ -> 66:a ;
-41:__UG_NAME__ -> 78:a ;
-65:__UG_NAME__ -> 81:b ;
-64:__UG_NAME__ -> 81:a ;
-29:__UG_NAME__ -> 30:b ;
-26:__UG_NAME__ -> 30:a ;
-33:__UG_NAME__ -> 34:b ;
-30:__UG_NAME__ -> 34:a ;
-38:__UG_NAME__ -> 39:b ;
-35:__UG_NAME__ -> 39:a ;
-25:__UG_NAME__ -> 40:b ;
-39:__UG_NAME__ -> 40:a ;
-46:__UG_NAME__ -> 47:b ;
-43:__UG_NAME__ -> 47:a ;
-51:__UG_NAME__ -> 52:b ;
-48:__UG_NAME__ -> 52:a ;
-55:__UG_NAME__ -> 56:b ;
-52:__UG_NAME__ -> 56:a ;
-62:__UG_NAME__ -> 63:b ;
-47:__UG_NAME__ -> 63:a ;
-70:__UG_NAME__ -> 71:b ;
-67:__UG_NAME__ -> 71:a ;
-72:__UG_NAME__ -> 73:b ;
-71:__UG_NAME__ -> 73:a ;
-75:__UG_NAME__ -> 76:b ;
-66:__UG_NAME__ -> 76:a ;
-82:__UG_NAME__ -> 83:b ;
-81:__UG_NAME__ -> 83:a ;
-78:__UG_NAME__ -> 79:a ;
-42:__UG_NAME__ -> 84:a ;
-24:__UG_NAME__ -> 25:a ;
-28:__UG_NAME__ -> 29:a ;
-32:__UG_NAME__ -> 33:a ;
-37:__UG_NAME__ -> 38:a ;
-45:__UG_NAME__ -> 46:a ;
-50:__UG_NAME__ -> 51:a ;
-54:__UG_NAME__ -> 55:a ;
-61:__UG_NAME__ -> 62:a ;
-69:__UG_NAME__ -> 70:a ;
-59:__UG_NAME__ -> 72:a ;
-23:__UG_NAME__ -> 24:a ;
-27:__UG_NAME__ -> 28:a ;
-31:__UG_NAME__ -> 32:a ;
-36:__UG_NAME__ -> 37:a ;
-44:__UG_NAME__ -> 45:a ;
-49:__UG_NAME__ -> 50:a ;
-53:__UG_NAME__ -> 54:a ;
-58:__UG_NAME__ -> 59:a ;
-60:__UG_NAME__ -> 61:a ;
-68:__UG_NAME__ -> 69:a ;
-57:__UG_NAME__ -> 75:decay____time ;
-74:__UG_NAME__ -> 75:delay____time ;
-20:__UG_NAME__ -> 75:max____delay____time ;
-66:__UG_NAME__ -> 75:in ;
-57:__UG_NAME__ -> 82:decay____time ;
-74:__UG_NAME__ -> 82:delay____time ;
-20:__UG_NAME__ -> 82:max____delay____time ;
-81:__UG_NAME__ -> 82:in ;
-40:__UG_NAME__ -> 41:gate ;
-4:__UG_NAME__ -> 41:envelope___control___0 ;
-4:__UG_NAME__ -> 41:envelope___control___4 ;
-5:__UG_NAME__ -> 41:envelope___control___5 ;
-6:__UG_NAME__ -> 41:envelope___control___6 ;
-7:__UG_NAME__ -> 41:envelope___control___7 ;
-56:__UG_NAME__ -> 57:gate ;
-16:__UG_NAME__ -> 57:envelope___control___0 ;
-16:__UG_NAME__ -> 57:envelope___control___4 ;
-17:__UG_NAME__ -> 57:envelope___control___5 ;
-18:__UG_NAME__ -> 57:envelope___control___6 ;
-19:__UG_NAME__ -> 57:envelope___control___7 ;
-63:__UG_NAME__ -> 64:gate ;
-8:__UG_NAME__ -> 64:envelope___control___0 ;
-8:__UG_NAME__ -> 64:envelope___control___4 ;
-9:__UG_NAME__ -> 64:envelope___control___5 ;
-10:__UG_NAME__ -> 64:envelope___control___6 ;
-11:__UG_NAME__ -> 64:envelope___control___7 ;
-73:__UG_NAME__ -> 74:gate ;
-12:__UG_NAME__ -> 74:envelope___control___0 ;
-12:__UG_NAME__ -> 74:envelope___control___4 ;
-13:__UG_NAME__ -> 74:envelope___control___5 ;
-14:__UG_NAME__ -> 74:envelope___control___6 ;
-15:__UG_NAME__ -> 74:envelope___control___7 ;
-34:__UG_NAME__ -> 77:gate ;
-0:__UG_NAME__ -> 77:envelope___control___0 ;
-0:__UG_NAME__ -> 77:envelope___control___4 ;
-1:__UG_NAME__ -> 77:envelope___control___5 ;
-2:__UG_NAME__ -> 77:envelope___control___6 ;
-3:__UG_NAME__ -> 77:envelope___control___7 ;
-5:__UG_NAME__ -> 23:in ;
-0:__UG_NAME__ -> 27:in ;
-1:__UG_NAME__ -> 31:in ;
-4:__UG_NAME__ -> 36:in ;
-8:__UG_NAME__ -> 44:in ;
-16:__UG_NAME__ -> 49:in ;
-17:__UG_NAME__ -> 53:in ;
-13:__UG_NAME__ -> 58:in ;
-9:__UG_NAME__ -> 60:in ;
-12:__UG_NAME__ -> 68:in ;
-21:__UG_NAME__ -> 65:bus ;
-80:__UG_NAME__ -> 86:signals___x____fade2___0 ;
-85:__UG_NAME__ -> 86:signals___x____fade2___1 ;
-22:__UG_NAME__ -> 86:bus ;
-77:__UG_NAME__ -> 80:level ;
-79:__UG_NAME__ -> 80:pan ;
-76:__UG_NAME__ -> 80:inb ;
-66:__UG_NAME__ -> 80:ina ;
-77:__UG_NAME__ -> 85:level ;
-84:__UG_NAME__ -> 85:pan ;
-83:__UG_NAME__ -> 85:inb ;
-81:__UG_NAME__ -> 85:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_flanger.dot b/etc/synthdefs/graphviz/sonic-pi-fx_flanger.dot
deleted file mode 100644
index 10771a5..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_flanger.dot
+++ /dev/null
@@ -1,547 +0,0 @@
-digraph synthdef {
-72 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> 6.2831855} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <a> -2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-126 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-127 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-156 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-167 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-169 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-172 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-173 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-187 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-188 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> 0.5} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-136 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-143 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-149 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-152 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-161 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-165 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-168 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-174 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-186 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-189 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-192 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-130 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-171 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-175 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-190 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-195 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> 1000.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ <a> |<b> 1000.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ <a> |<b> 1000.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-145 [label = "{{ <a> |<b> 1000.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-154 [label = "{{ <a> |<b> 1000.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-177 [label = "{{ <a> |<b> 1000.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-178 [label = "{{ <a> |<b> 1000.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-181 [label = "{{ <a> |<b> 1000.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-198 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-135 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-139 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-151 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-160 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-164 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-185 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-191 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-134 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-138 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-150 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-159 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-163 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-184 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-155 [label = "{{ <in> in|<max____delay____time> max-delay-time|<delay____time> delay-time|<decay____time> decay-time} |<__UG_NAME__>allpass-c }" style="filled, bold, rounded"  shape=record rankdir=LR];
-182 [label = "{{ <in> in|<max____delay____time> max-delay-time|<delay____time> delay-time|<decay____time> decay-time} |<__UG_NAME__>allpass-c }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :phase
- default: 4.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :phase_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :phase_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :phase_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :phase_offset
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :wave
- default: 4.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :invert_wave
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :stereo_invert_wave
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :delay
- default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :delay_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :delay_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :delay_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :max_delay
- default: 20.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :depth
- default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :depth_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :depth_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :depth_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :feedback
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :feedback_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :feedback_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :feedback_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "control
- :decay
- default: 2.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "control
- :decay_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "control
- :decay_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-40 [label = "control
- :decay_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-41 [label = "control
- :invert_flange
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-43 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-70 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-153 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-166 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-193 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-133 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-137 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-158 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-162 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-132 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-148 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-157 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-183 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-92 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-cub }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <freq> freq|<iphase> iphase|<width> width} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>limiter }" style="filled, bold, rounded"  shape=record rankdir=LR];
-170 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>limiter }" style="filled, bold, rounded"  shape=record rankdir=LR];
-58 [label = "{{ <num____channels> num-channels 2} |<__UG_NAME__>local-in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-199 [label = "{{ {{<channels____array___binary____op____u____gen___0>|<channels____array___binary____op____u____gen___1>}|channels-array}} |<__UG_NAME__>local-out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-147 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>max }" style="bold, rounded" shape=record rankdir=LR];
-180 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>max }" style="bold, rounded" shape=record rankdir=LR];
-146 [label = "{{ <in> in|<mul> mul|<add> add} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-179 [label = "{{ <in> in|<mul> mul|<add> add} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-197 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-93 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>|<array___lf____cub___4>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-131 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-176 [label = "{{ <which> which|{{<array___select___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <freq> freq|<phase> phase|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-194 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-196 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-16:__UG_NAME__ -> 72:b ;
-74:__UG_NAME__ -> 75:b ;
-83:__UG_NAME__ -> 84:b ;
-88:__UG_NAME__ -> 89:a ;
-106:__UG_NAME__ -> 107:b ;
-116:__UG_NAME__ -> 117:b ;
-58:__UG_NAME__ -> 117:a ;
-125:__UG_NAME__ -> 126:b ;
-124:__UG_NAME__ -> 126:a ;
-126:__UG_NAME__ -> 127:b ;
-119:__UG_NAME__ -> 127:a ;
-155:__UG_NAME__ -> 156:b ;
-108:__UG_NAME__ -> 156:a ;
-166:__UG_NAME__ -> 167:a ;
-116:__UG_NAME__ -> 169:b ;
-58:__UG_NAME__ -> 169:a ;
-125:__UG_NAME__ -> 172:b ;
-124:__UG_NAME__ -> 172:a ;
-172:__UG_NAME__ -> 173:b ;
-171:__UG_NAME__ -> 173:a ;
-166:__UG_NAME__ -> 187:a ;
-182:__UG_NAME__ -> 188:b ;
-108:__UG_NAME__ -> 188:a ;
-64:__UG_NAME__ -> 65:b ;
-61:__UG_NAME__ -> 65:a ;
-68:__UG_NAME__ -> 69:b ;
-65:__UG_NAME__ -> 69:a ;
-72:__UG_NAME__ -> 73:a ;
-78:__UG_NAME__ -> 79:b ;
-57:__UG_NAME__ -> 79:a ;
-80:__UG_NAME__ -> 81:b ;
-79:__UG_NAME__ -> 81:a ;
-72:__UG_NAME__ -> 86:a ;
-16:__UG_NAME__ -> 88:a ;
-16:__UG_NAME__ -> 91:a ;
-93:__UG_NAME__ -> 94:a ;
-99:__UG_NAME__ -> 100:b ;
-96:__UG_NAME__ -> 100:a ;
-104:__UG_NAME__ -> 105:b ;
-101:__UG_NAME__ -> 105:a ;
-107:__UG_NAME__ -> 108:a ;
-110:__UG_NAME__ -> 111:b ;
-109:__UG_NAME__ -> 111:a ;
-114:__UG_NAME__ -> 115:b ;
-111:__UG_NAME__ -> 115:a ;
-122:__UG_NAME__ -> 123:b ;
-105:__UG_NAME__ -> 123:a ;
-127:__UG_NAME__ -> 128:b ;
-118:__UG_NAME__ -> 128:a ;
-135:__UG_NAME__ -> 136:b ;
-132:__UG_NAME__ -> 136:a ;
-139:__UG_NAME__ -> 140:b ;
-136:__UG_NAME__ -> 140:a ;
-56:__UG_NAME__ -> 143:b ;
-100:__UG_NAME__ -> 143:a ;
-46:__UG_NAME__ -> 149:b ;
-148:__UG_NAME__ -> 149:a ;
-151:__UG_NAME__ -> 152:b ;
-149:__UG_NAME__ -> 152:a ;
-160:__UG_NAME__ -> 161:b ;
-157:__UG_NAME__ -> 161:a ;
-164:__UG_NAME__ -> 165:b ;
-161:__UG_NAME__ -> 165:a ;
-156:__UG_NAME__ -> 168:b ;
-126:__UG_NAME__ -> 168:a ;
-173:__UG_NAME__ -> 174:b ;
-170:__UG_NAME__ -> 174:a ;
-185:__UG_NAME__ -> 186:b ;
-183:__UG_NAME__ -> 186:a ;
-188:__UG_NAME__ -> 189:b ;
-172:__UG_NAME__ -> 189:a ;
-191:__UG_NAME__ -> 192:b ;
-186:__UG_NAME__ -> 192:a ;
-84:__UG_NAME__ -> 85:a ;
-116:__UG_NAME__ -> 119:b ;
-95:__UG_NAME__ -> 130:b ;
-116:__UG_NAME__ -> 171:b ;
-131:__UG_NAME__ -> 175:b ;
-167:__UG_NAME__ -> 190:a ;
-187:__UG_NAME__ -> 195:a ;
-28:__UG_NAME__ -> 53:a ;
-70:__UG_NAME__ -> 71:b ;
-94:__UG_NAME__ -> 95:a ;
-28:__UG_NAME__ -> 129:a ;
-141:__UG_NAME__ -> 142:a ;
-144:__UG_NAME__ -> 145:a ;
-153:__UG_NAME__ -> 154:a ;
-141:__UG_NAME__ -> 177:a ;
-144:__UG_NAME__ -> 178:a ;
-153:__UG_NAME__ -> 181:a ;
-70:__UG_NAME__ -> 198:b ;
-45:__UG_NAME__ -> 46:a ;
-55:__UG_NAME__ -> 56:a ;
-63:__UG_NAME__ -> 64:a ;
-67:__UG_NAME__ -> 68:a ;
-77:__UG_NAME__ -> 78:a ;
-60:__UG_NAME__ -> 80:a ;
-98:__UG_NAME__ -> 99:a ;
-103:__UG_NAME__ -> 104:a ;
-41:__UG_NAME__ -> 106:a ;
-48:__UG_NAME__ -> 110:a ;
-113:__UG_NAME__ -> 114:a ;
-121:__UG_NAME__ -> 122:a ;
-134:__UG_NAME__ -> 135:a ;
-138:__UG_NAME__ -> 139:a ;
-150:__UG_NAME__ -> 151:a ;
-159:__UG_NAME__ -> 160:a ;
-163:__UG_NAME__ -> 164:a ;
-184:__UG_NAME__ -> 185:a ;
-50:__UG_NAME__ -> 191:a ;
-44:__UG_NAME__ -> 45:a ;
-47:__UG_NAME__ -> 48:a ;
-49:__UG_NAME__ -> 50:a ;
-54:__UG_NAME__ -> 55:a ;
-59:__UG_NAME__ -> 60:a ;
-62:__UG_NAME__ -> 63:a ;
-66:__UG_NAME__ -> 67:a ;
-76:__UG_NAME__ -> 77:a ;
-97:__UG_NAME__ -> 98:a ;
-102:__UG_NAME__ -> 103:a ;
-112:__UG_NAME__ -> 113:a ;
-120:__UG_NAME__ -> 121:a ;
-133:__UG_NAME__ -> 134:a ;
-137:__UG_NAME__ -> 138:a ;
-51:__UG_NAME__ -> 150:a ;
-158:__UG_NAME__ -> 159:a ;
-162:__UG_NAME__ -> 163:a ;
-52:__UG_NAME__ -> 184:a ;
-154:__UG_NAME__ -> 155:decay____time ;
-147:__UG_NAME__ -> 155:delay____time ;
-129:__UG_NAME__ -> 155:max____delay____time ;
-128:__UG_NAME__ -> 155:in ;
-181:__UG_NAME__ -> 182:decay____time ;
-180:__UG_NAME__ -> 182:delay____time ;
-53:__UG_NAME__ -> 182:max____delay____time ;
-174:__UG_NAME__ -> 182:in ;
-69:__UG_NAME__ -> 70:gate ;
-12:__UG_NAME__ -> 70:envelope___control___0 ;
-12:__UG_NAME__ -> 70:envelope___control___4 ;
-13:__UG_NAME__ -> 70:envelope___control___5 ;
-14:__UG_NAME__ -> 70:envelope___control___6 ;
-15:__UG_NAME__ -> 70:envelope___control___7 ;
-81:__UG_NAME__ -> 82:gate ;
-20:__UG_NAME__ -> 82:envelope___control___0 ;
-20:__UG_NAME__ -> 82:envelope___control___4 ;
-21:__UG_NAME__ -> 82:envelope___control___5 ;
-22:__UG_NAME__ -> 82:envelope___control___6 ;
-23:__UG_NAME__ -> 82:envelope___control___7 ;
-115:__UG_NAME__ -> 116:gate ;
-33:__UG_NAME__ -> 116:envelope___control___0 ;
-33:__UG_NAME__ -> 116:envelope___control___4 ;
-34:__UG_NAME__ -> 116:envelope___control___5 ;
-35:__UG_NAME__ -> 116:envelope___control___6 ;
-36:__UG_NAME__ -> 116:envelope___control___7 ;
-123:__UG_NAME__ -> 124:gate ;
-8:__UG_NAME__ -> 124:envelope___control___0 ;
-8:__UG_NAME__ -> 124:envelope___control___4 ;
-9:__UG_NAME__ -> 124:envelope___control___5 ;
-10:__UG_NAME__ -> 124:envelope___control___6 ;
-11:__UG_NAME__ -> 124:envelope___control___7 ;
-140:__UG_NAME__ -> 141:gate ;
-29:__UG_NAME__ -> 141:envelope___control___0 ;
-29:__UG_NAME__ -> 141:envelope___control___4 ;
-30:__UG_NAME__ -> 141:envelope___control___5 ;
-31:__UG_NAME__ -> 141:envelope___control___6 ;
-32:__UG_NAME__ -> 141:envelope___control___7 ;
-143:__UG_NAME__ -> 144:gate ;
-24:__UG_NAME__ -> 144:envelope___control___0 ;
-24:__UG_NAME__ -> 144:envelope___control___4 ;
-25:__UG_NAME__ -> 144:envelope___control___5 ;
-26:__UG_NAME__ -> 144:envelope___control___6 ;
-27:__UG_NAME__ -> 144:envelope___control___7 ;
-152:__UG_NAME__ -> 153:gate ;
-37:__UG_NAME__ -> 153:envelope___control___0 ;
-37:__UG_NAME__ -> 153:envelope___control___4 ;
-38:__UG_NAME__ -> 153:envelope___control___5 ;
-39:__UG_NAME__ -> 153:envelope___control___6 ;
-40:__UG_NAME__ -> 153:envelope___control___7 ;
-165:__UG_NAME__ -> 166:gate ;
-4:__UG_NAME__ -> 166:envelope___control___0 ;
-4:__UG_NAME__ -> 166:envelope___control___4 ;
-5:__UG_NAME__ -> 166:envelope___control___5 ;
-6:__UG_NAME__ -> 166:envelope___control___6 ;
-7:__UG_NAME__ -> 166:envelope___control___7 ;
-192:__UG_NAME__ -> 193:gate ;
-0:__UG_NAME__ -> 193:envelope___control___0 ;
-0:__UG_NAME__ -> 193:envelope___control___4 ;
-1:__UG_NAME__ -> 193:envelope___control___5 ;
-2:__UG_NAME__ -> 193:envelope___control___6 ;
-3:__UG_NAME__ -> 193:envelope___control___7 ;
-37:__UG_NAME__ -> 44:in ;
-33:__UG_NAME__ -> 47:in ;
-1:__UG_NAME__ -> 49:in ;
-38:__UG_NAME__ -> 51:in ;
-0:__UG_NAME__ -> 52:in ;
-25:__UG_NAME__ -> 54:in ;
-21:__UG_NAME__ -> 59:in ;
-12:__UG_NAME__ -> 62:in ;
-13:__UG_NAME__ -> 66:in ;
-20:__UG_NAME__ -> 76:in ;
-24:__UG_NAME__ -> 97:in ;
-8:__UG_NAME__ -> 102:in ;
-34:__UG_NAME__ -> 112:in ;
-9:__UG_NAME__ -> 120:in ;
-29:__UG_NAME__ -> 133:in ;
-30:__UG_NAME__ -> 137:in ;
-4:__UG_NAME__ -> 158:in ;
-5:__UG_NAME__ -> 162:in ;
-42:__UG_NAME__ -> 125:bus ;
-91:__UG_NAME__ -> 92:iphase ;
-71:__UG_NAME__ -> 92:freq ;
-82:__UG_NAME__ -> 83:width ;
-16:__UG_NAME__ -> 83:iphase ;
-71:__UG_NAME__ -> 83:freq ;
-73:__UG_NAME__ -> 74:iphase ;
-71:__UG_NAME__ -> 74:freq ;
-86:__UG_NAME__ -> 87:iphase ;
-71:__UG_NAME__ -> 87:freq ;
-117:__UG_NAME__ -> 118:in ;
-169:__UG_NAME__ -> 170:in ;
-189:__UG_NAME__ -> 199:channels____array___binary____op____u____gen___0 ;
-168:__UG_NAME__ -> 199:channels____array___binary____op____u____gen___1 ;
-146:__UG_NAME__ -> 147:a ;
-179:__UG_NAME__ -> 180:a ;
-145:__UG_NAME__ -> 146:add ;
-142:__UG_NAME__ -> 146:mul ;
-131:__UG_NAME__ -> 146:in ;
-178:__UG_NAME__ -> 179:add ;
-177:__UG_NAME__ -> 179:mul ;
-176:__UG_NAME__ -> 179:in ;
-194:__UG_NAME__ -> 197:signals___x____fade2___0 ;
-196:__UG_NAME__ -> 197:signals___x____fade2___1 ;
-43:__UG_NAME__ -> 197:bus ;
-75:__UG_NAME__ -> 93:array___binary____op____u____gen___0 ;
-85:__UG_NAME__ -> 93:array___binary____op____u____gen___1 ;
-87:__UG_NAME__ -> 93:array___lf____tri___2 ;
-90:__UG_NAME__ -> 93:array___sin____osc___3 ;
-92:__UG_NAME__ -> 93:array___lf____cub___4 ;
-17:__UG_NAME__ -> 93:which ;
-95:__UG_NAME__ -> 131:array___binary____op____u____gen___0 ;
-130:__UG_NAME__ -> 131:array___binary____op____u____gen___1 ;
-18:__UG_NAME__ -> 131:which ;
-131:__UG_NAME__ -> 176:array___select___0 ;
-175:__UG_NAME__ -> 176:array___binary____op____u____gen___1 ;
-19:__UG_NAME__ -> 176:which ;
-89:__UG_NAME__ -> 90:phase ;
-71:__UG_NAME__ -> 90:freq ;
-193:__UG_NAME__ -> 194:level ;
-190:__UG_NAME__ -> 194:pan ;
-189:__UG_NAME__ -> 194:inb ;
-172:__UG_NAME__ -> 194:ina ;
-193:__UG_NAME__ -> 196:level ;
-195:__UG_NAME__ -> 196:pan ;
-168:__UG_NAME__ -> 196:inb ;
-126:__UG_NAME__ -> 196:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_gverb.dot b/etc/synthdefs/graphviz/sonic-pi-fx_gverb.dot
deleted file mode 100644
index d99b46f..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_gverb.dot
+++ /dev/null
@@ -1,371 +0,0 @@
-digraph synthdef {
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-100 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-123 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="dashed, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :room
- default: 10" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
-1 [label = "control
- :max_room
- default: -1" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
-2 [label = "control
- :release
- default: 3" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
-3 [label = "control
- :ref_level
- default: 0.7" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
-4 [label = "control
- :tail_level
- default: 0.5" shape=invhouse style="rounded, dashed, filled, bold" fillcolor=white fontcolor=black ]; 
-5 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :mix
- default: 0.4" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :spread
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :spread_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :spread_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :spread_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :damp
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :damp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :damp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :damp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :pre_damp
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :pre_damp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :pre_damp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :pre_damp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :dry
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :dry_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :dry_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :dry_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-53 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <in> in|<taillevel> taillevel|<earlyreflevel> earlyreflevel|<roomsize> roomsize|<damping> damping|<inputbw> inputbw|<maxroomsize> maxroomsize|<revtime> revtime|<spread> spread 0.0|<drylevel> drylevel} |<__UG_NAME__>g-verb }" style="filled, bold, rounded"  shape=record rankdir=LR];
-102 [label = "{{ <in> in|<taillevel> taillevel|<earlyreflevel> earlyreflevel|<roomsize> roomsize|<damping> damping|<inputbw> inputbw|<maxroomsize> maxroomsize|<revtime> revtime|<spread> spread 0.0|<drylevel> drylevel} |<__UG_NAME__>g-verb }" style="filled, bold, rounded"  shape=record rankdir=LR];
-36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-109 [label = "{{ <in> in|<mul> mul 1.0|<add> add -1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-126 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-98 [label = "{{ <which> which|{{<array___control___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level 1.0} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-119 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-122 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level 1.0} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-125 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-75:__UG_NAME__ -> 76:b ;
-74:__UG_NAME__ -> 76:a ;
-99:__UG_NAME__ -> 100:b ;
-85:__UG_NAME__ -> 100:a ;
-75:__UG_NAME__ -> 101:b ;
-74:__UG_NAME__ -> 101:a ;
-102:__UG_NAME__ -> 103:b ;
-85:__UG_NAME__ -> 103:a ;
-116:__UG_NAME__ -> 117:a ;
-102:__UG_NAME__ -> 120:b ;
-85:__UG_NAME__ -> 120:a ;
-99:__UG_NAME__ -> 121:b ;
-85:__UG_NAME__ -> 121:a ;
-116:__UG_NAME__ -> 123:a ;
-47:__UG_NAME__ -> 48:b ;
-44:__UG_NAME__ -> 48:a ;
-51:__UG_NAME__ -> 52:b ;
-48:__UG_NAME__ -> 52:a ;
-58:__UG_NAME__ -> 59:b ;
-55:__UG_NAME__ -> 59:a ;
-62:__UG_NAME__ -> 63:b ;
-59:__UG_NAME__ -> 63:a ;
-68:__UG_NAME__ -> 69:b ;
-65:__UG_NAME__ -> 69:a ;
-72:__UG_NAME__ -> 73:b ;
-69:__UG_NAME__ -> 73:a ;
-79:__UG_NAME__ -> 80:b ;
-77:__UG_NAME__ -> 80:a ;
-83:__UG_NAME__ -> 84:b ;
-80:__UG_NAME__ -> 84:a ;
-89:__UG_NAME__ -> 90:b ;
-86:__UG_NAME__ -> 90:a ;
-93:__UG_NAME__ -> 94:b ;
-90:__UG_NAME__ -> 94:a ;
-0:__UG_NAME__ -> 97:a ;
-40:__UG_NAME__ -> 104:b ;
-35:__UG_NAME__ -> 104:a ;
-106:__UG_NAME__ -> 107:b ;
-104:__UG_NAME__ -> 107:a ;
-111:__UG_NAME__ -> 112:b ;
-43:__UG_NAME__ -> 112:a ;
-114:__UG_NAME__ -> 115:b ;
-112:__UG_NAME__ -> 115:a ;
-117:__UG_NAME__ -> 118:a ;
-123:__UG_NAME__ -> 124:a ;
-1:__UG_NAME__ -> 96:b ;
-39:__UG_NAME__ -> 40:a ;
-46:__UG_NAME__ -> 47:a ;
-50:__UG_NAME__ -> 51:a ;
-57:__UG_NAME__ -> 58:a ;
-61:__UG_NAME__ -> 62:a ;
-67:__UG_NAME__ -> 68:a ;
-71:__UG_NAME__ -> 72:a ;
-78:__UG_NAME__ -> 79:a ;
-82:__UG_NAME__ -> 83:a ;
-88:__UG_NAME__ -> 89:a ;
-92:__UG_NAME__ -> 93:a ;
-105:__UG_NAME__ -> 106:a ;
-42:__UG_NAME__ -> 111:a ;
-113:__UG_NAME__ -> 114:a ;
-38:__UG_NAME__ -> 39:a ;
-41:__UG_NAME__ -> 42:a ;
-45:__UG_NAME__ -> 46:a ;
-49:__UG_NAME__ -> 50:a ;
-56:__UG_NAME__ -> 57:a ;
-60:__UG_NAME__ -> 61:a ;
-66:__UG_NAME__ -> 67:a ;
-70:__UG_NAME__ -> 71:a ;
-54:__UG_NAME__ -> 78:a ;
-81:__UG_NAME__ -> 82:a ;
-87:__UG_NAME__ -> 88:a ;
-91:__UG_NAME__ -> 92:a ;
-36:__UG_NAME__ -> 105:a ;
-37:__UG_NAME__ -> 113:a ;
-52:__UG_NAME__ -> 53:gate ;
-21:__UG_NAME__ -> 53:envelope___control___0 ;
-21:__UG_NAME__ -> 53:envelope___control___4 ;
-22:__UG_NAME__ -> 53:envelope___control___5 ;
-23:__UG_NAME__ -> 53:envelope___control___6 ;
-24:__UG_NAME__ -> 53:envelope___control___7 ;
-63:__UG_NAME__ -> 64:gate ;
-29:__UG_NAME__ -> 64:envelope___control___0 ;
-29:__UG_NAME__ -> 64:envelope___control___4 ;
-30:__UG_NAME__ -> 64:envelope___control___5 ;
-31:__UG_NAME__ -> 64:envelope___control___6 ;
-32:__UG_NAME__ -> 64:envelope___control___7 ;
-73:__UG_NAME__ -> 74:gate ;
-13:__UG_NAME__ -> 74:envelope___control___0 ;
-13:__UG_NAME__ -> 74:envelope___control___4 ;
-14:__UG_NAME__ -> 74:envelope___control___5 ;
-15:__UG_NAME__ -> 74:envelope___control___6 ;
-16:__UG_NAME__ -> 74:envelope___control___7 ;
-84:__UG_NAME__ -> 85:gate ;
-5:__UG_NAME__ -> 85:envelope___control___0 ;
-5:__UG_NAME__ -> 85:envelope___control___4 ;
-6:__UG_NAME__ -> 85:envelope___control___5 ;
-7:__UG_NAME__ -> 85:envelope___control___6 ;
-8:__UG_NAME__ -> 85:envelope___control___7 ;
-94:__UG_NAME__ -> 95:gate ;
-25:__UG_NAME__ -> 95:envelope___control___0 ;
-25:__UG_NAME__ -> 95:envelope___control___4 ;
-26:__UG_NAME__ -> 95:envelope___control___5 ;
-27:__UG_NAME__ -> 95:envelope___control___6 ;
-28:__UG_NAME__ -> 95:envelope___control___7 ;
-107:__UG_NAME__ -> 108:gate ;
-17:__UG_NAME__ -> 108:envelope___control___0 ;
-17:__UG_NAME__ -> 108:envelope___control___4 ;
-18:__UG_NAME__ -> 108:envelope___control___5 ;
-19:__UG_NAME__ -> 108:envelope___control___6 ;
-20:__UG_NAME__ -> 108:envelope___control___7 ;
-115:__UG_NAME__ -> 116:gate ;
-9:__UG_NAME__ -> 116:envelope___control___0 ;
-9:__UG_NAME__ -> 116:envelope___control___4 ;
-10:__UG_NAME__ -> 116:envelope___control___5 ;
-11:__UG_NAME__ -> 116:envelope___control___6 ;
-12:__UG_NAME__ -> 116:envelope___control___7 ;
-64:__UG_NAME__ -> 99:drylevel ;
-2:__UG_NAME__ -> 99:revtime ;
-98:__UG_NAME__ -> 99:maxroomsize ;
-95:__UG_NAME__ -> 99:inputbw ;
-53:__UG_NAME__ -> 99:damping ;
-0:__UG_NAME__ -> 99:roomsize ;
-3:__UG_NAME__ -> 99:earlyreflevel ;
-4:__UG_NAME__ -> 99:taillevel ;
-76:__UG_NAME__ -> 99:in ;
-64:__UG_NAME__ -> 102:drylevel ;
-2:__UG_NAME__ -> 102:revtime ;
-98:__UG_NAME__ -> 102:maxroomsize ;
-95:__UG_NAME__ -> 102:inputbw ;
-53:__UG_NAME__ -> 102:damping ;
-0:__UG_NAME__ -> 102:roomsize ;
-3:__UG_NAME__ -> 102:earlyreflevel ;
-4:__UG_NAME__ -> 102:taillevel ;
-101:__UG_NAME__ -> 102:in ;
-18:__UG_NAME__ -> 36:in ;
-10:__UG_NAME__ -> 37:in ;
-17:__UG_NAME__ -> 38:in ;
-9:__UG_NAME__ -> 41:in ;
-21:__UG_NAME__ -> 45:in ;
-22:__UG_NAME__ -> 49:in ;
-5:__UG_NAME__ -> 54:in ;
-29:__UG_NAME__ -> 56:in ;
-30:__UG_NAME__ -> 60:in ;
-13:__UG_NAME__ -> 66:in ;
-14:__UG_NAME__ -> 70:in ;
-6:__UG_NAME__ -> 81:in ;
-25:__UG_NAME__ -> 87:in ;
-26:__UG_NAME__ -> 91:in ;
-33:__UG_NAME__ -> 75:bus ;
-108:__UG_NAME__ -> 109:in ;
-119:__UG_NAME__ -> 126:signals___x____fade2___0 ;
-125:__UG_NAME__ -> 126:signals___x____fade2___1 ;
-34:__UG_NAME__ -> 126:bus ;
-1:__UG_NAME__ -> 98:array___control___0 ;
-97:__UG_NAME__ -> 98:array___binary____op____u____gen___1 ;
-96:__UG_NAME__ -> 98:which ;
-109:__UG_NAME__ -> 110:pan ;
-103:__UG_NAME__ -> 110:inb ;
-100:__UG_NAME__ -> 110:ina ;
-85:__UG_NAME__ -> 119:level ;
-118:__UG_NAME__ -> 119:pan ;
-110:__UG_NAME__ -> 119:inb ;
-76:__UG_NAME__ -> 119:ina ;
-109:__UG_NAME__ -> 122:pan ;
-121:__UG_NAME__ -> 122:inb ;
-120:__UG_NAME__ -> 122:ina ;
-85:__UG_NAME__ -> 125:level ;
-124:__UG_NAME__ -> 125:pan ;
-122:__UG_NAME__ -> 125:inb ;
-101:__UG_NAME__ -> 125:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_hpf.dot b/etc/synthdefs/graphviz/sonic-pi-fx_hpf.dot
deleted file mode 100644
index f1b86f4..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_hpf.dot
+++ /dev/null
@@ -1,200 +0,0 @@
-digraph synthdef {
-28 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-21 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-20 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-68 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-19 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-18 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-67 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-69 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-27:__UG_NAME__ -> 28:a ;
-58:__UG_NAME__ -> 59:b ;
-57:__UG_NAME__ -> 59:a ;
-58:__UG_NAME__ -> 60:b ;
-57:__UG_NAME__ -> 60:a ;
-27:__UG_NAME__ -> 62:a ;
-21:__UG_NAME__ -> 22:b ;
-18:__UG_NAME__ -> 22:a ;
-25:__UG_NAME__ -> 26:b ;
-22:__UG_NAME__ -> 26:a ;
-33:__UG_NAME__ -> 34:b ;
-30:__UG_NAME__ -> 34:a ;
-40:__UG_NAME__ -> 41:b ;
-37:__UG_NAME__ -> 41:a ;
-44:__UG_NAME__ -> 45:b ;
-41:__UG_NAME__ -> 45:a ;
-52:__UG_NAME__ -> 53:b ;
-49:__UG_NAME__ -> 53:a ;
-55:__UG_NAME__ -> 56:b ;
-53:__UG_NAME__ -> 56:a ;
-64:__UG_NAME__ -> 65:b ;
-34:__UG_NAME__ -> 65:a ;
-28:__UG_NAME__ -> 29:a ;
-62:__UG_NAME__ -> 63:a ;
-20:__UG_NAME__ -> 21:a ;
-24:__UG_NAME__ -> 25:a ;
-32:__UG_NAME__ -> 33:a ;
-39:__UG_NAME__ -> 40:a ;
-43:__UG_NAME__ -> 44:a ;
-51:__UG_NAME__ -> 52:a ;
-54:__UG_NAME__ -> 55:a ;
-36:__UG_NAME__ -> 64:a ;
-19:__UG_NAME__ -> 20:a ;
-23:__UG_NAME__ -> 24:a ;
-31:__UG_NAME__ -> 32:a ;
-35:__UG_NAME__ -> 36:a ;
-38:__UG_NAME__ -> 39:a ;
-42:__UG_NAME__ -> 43:a ;
-50:__UG_NAME__ -> 51:a ;
-48:__UG_NAME__ -> 54:a ;
-26:__UG_NAME__ -> 27:gate ;
-4:__UG_NAME__ -> 27:envelope___control___0 ;
-4:__UG_NAME__ -> 27:envelope___control___4 ;
-5:__UG_NAME__ -> 27:envelope___control___5 ;
-6:__UG_NAME__ -> 27:envelope___control___6 ;
-7:__UG_NAME__ -> 27:envelope___control___7 ;
-45:__UG_NAME__ -> 46:gate ;
-12:__UG_NAME__ -> 46:envelope___control___0 ;
-12:__UG_NAME__ -> 46:envelope___control___4 ;
-13:__UG_NAME__ -> 46:envelope___control___5 ;
-14:__UG_NAME__ -> 46:envelope___control___6 ;
-15:__UG_NAME__ -> 46:envelope___control___7 ;
-56:__UG_NAME__ -> 57:gate ;
-8:__UG_NAME__ -> 57:envelope___control___0 ;
-8:__UG_NAME__ -> 57:envelope___control___4 ;
-9:__UG_NAME__ -> 57:envelope___control___5 ;
-10:__UG_NAME__ -> 57:envelope___control___6 ;
-11:__UG_NAME__ -> 57:envelope___control___7 ;
-65:__UG_NAME__ -> 66:gate ;
-0:__UG_NAME__ -> 66:envelope___control___0 ;
-0:__UG_NAME__ -> 66:envelope___control___4 ;
-1:__UG_NAME__ -> 66:envelope___control___5 ;
-2:__UG_NAME__ -> 66:envelope___control___6 ;
-3:__UG_NAME__ -> 66:envelope___control___7 ;
-47:__UG_NAME__ -> 61:freq ;
-60:__UG_NAME__ -> 61:in ;
-47:__UG_NAME__ -> 68:freq ;
-59:__UG_NAME__ -> 68:in ;
-4:__UG_NAME__ -> 19:in ;
-5:__UG_NAME__ -> 23:in ;
-0:__UG_NAME__ -> 31:in ;
-1:__UG_NAME__ -> 35:in ;
-12:__UG_NAME__ -> 38:in ;
-13:__UG_NAME__ -> 42:in ;
-9:__UG_NAME__ -> 48:in ;
-8:__UG_NAME__ -> 50:in ;
-16:__UG_NAME__ -> 58:bus ;
-46:__UG_NAME__ -> 47:a ;
-67:__UG_NAME__ -> 70:signals___x____fade2___0 ;
-69:__UG_NAME__ -> 70:signals___x____fade2___1 ;
-17:__UG_NAME__ -> 70:bus ;
-66:__UG_NAME__ -> 67:level ;
-63:__UG_NAME__ -> 67:pan ;
-61:__UG_NAME__ -> 67:inb ;
-60:__UG_NAME__ -> 67:ina ;
-66:__UG_NAME__ -> 69:level ;
-29:__UG_NAME__ -> 69:pan ;
-68:__UG_NAME__ -> 69:inb ;
-59:__UG_NAME__ -> 69:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_ixi_techno.dot b/etc/synthdefs/graphviz/sonic-pi-fx_ixi_techno.dot
deleted file mode 100644
index 55bd7e3..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_ixi_techno.dot
+++ /dev/null
@@ -1,336 +0,0 @@
-digraph synthdef {
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-94 [label = "{{ <a> |<b> 6.2831855} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :phase
- default: 4.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :phase_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :phase_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :phase_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :phase_offset
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :cutoff_min
- default: 60.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :cutoff_min_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :cutoff_min_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff_min_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_max
- default: 120.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_max_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_max_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :cutoff_max_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :res
- default: 0.8" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-105 [label = "{{ <in> in|<srclo> srclo -1.0|<srchi> srchi 1.0|<dstlo> dstlo|<dsthi> dsthi} |<__UG_NAME__>lin-exp }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-106 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-116 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-95 [label = "{{ <freq> freq|<phase> phase|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-119 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-58:__UG_NAME__ -> 59:b ;
-57:__UG_NAME__ -> 59:a ;
-58:__UG_NAME__ -> 81:b ;
-57:__UG_NAME__ -> 81:a ;
-93:__UG_NAME__ -> 94:a ;
-42:__UG_NAME__ -> 110:a ;
-42:__UG_NAME__ -> 117:a ;
-36:__UG_NAME__ -> 37:b ;
-33:__UG_NAME__ -> 37:a ;
-40:__UG_NAME__ -> 41:b ;
-37:__UG_NAME__ -> 41:a ;
-51:__UG_NAME__ -> 52:b ;
-48:__UG_NAME__ -> 52:a ;
-55:__UG_NAME__ -> 56:b ;
-52:__UG_NAME__ -> 56:a ;
-61:__UG_NAME__ -> 62:b ;
-60:__UG_NAME__ -> 62:a ;
-65:__UG_NAME__ -> 66:b ;
-62:__UG_NAME__ -> 66:a ;
-72:__UG_NAME__ -> 73:b ;
-68:__UG_NAME__ -> 73:a ;
-76:__UG_NAME__ -> 77:b ;
-73:__UG_NAME__ -> 77:a ;
-85:__UG_NAME__ -> 86:b ;
-82:__UG_NAME__ -> 86:a ;
-89:__UG_NAME__ -> 90:b ;
-86:__UG_NAME__ -> 90:a ;
-45:__UG_NAME__ -> 97:b ;
-96:__UG_NAME__ -> 97:a ;
-100:__UG_NAME__ -> 101:b ;
-97:__UG_NAME__ -> 101:a ;
-108:__UG_NAME__ -> 109:b ;
-107:__UG_NAME__ -> 109:a ;
-112:__UG_NAME__ -> 113:b ;
-109:__UG_NAME__ -> 113:a ;
-16:__UG_NAME__ -> 93:a ;
-110:__UG_NAME__ -> 111:a ;
-117:__UG_NAME__ -> 118:a ;
-91:__UG_NAME__ -> 92:b ;
-35:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:a ;
-44:__UG_NAME__ -> 45:a ;
-50:__UG_NAME__ -> 51:a ;
-54:__UG_NAME__ -> 55:a ;
-47:__UG_NAME__ -> 61:a ;
-64:__UG_NAME__ -> 65:a ;
-71:__UG_NAME__ -> 72:a ;
-75:__UG_NAME__ -> 76:a ;
-84:__UG_NAME__ -> 85:a ;
-88:__UG_NAME__ -> 89:a ;
-99:__UG_NAME__ -> 100:a ;
-32:__UG_NAME__ -> 108:a ;
-80:__UG_NAME__ -> 112:a ;
-31:__UG_NAME__ -> 32:a ;
-34:__UG_NAME__ -> 35:a ;
-38:__UG_NAME__ -> 39:a ;
-43:__UG_NAME__ -> 44:a ;
-46:__UG_NAME__ -> 47:a ;
-49:__UG_NAME__ -> 50:a ;
-53:__UG_NAME__ -> 54:a ;
-63:__UG_NAME__ -> 64:a ;
-70:__UG_NAME__ -> 71:a ;
-74:__UG_NAME__ -> 75:a ;
-79:__UG_NAME__ -> 80:a ;
-83:__UG_NAME__ -> 84:a ;
-87:__UG_NAME__ -> 88:a ;
-98:__UG_NAME__ -> 99:a ;
-41:__UG_NAME__ -> 42:gate ;
-4:__UG_NAME__ -> 42:envelope___control___0 ;
-4:__UG_NAME__ -> 42:envelope___control___4 ;
-5:__UG_NAME__ -> 42:envelope___control___5 ;
-6:__UG_NAME__ -> 42:envelope___control___6 ;
-7:__UG_NAME__ -> 42:envelope___control___7 ;
-56:__UG_NAME__ -> 57:gate ;
-8:__UG_NAME__ -> 57:envelope___control___0 ;
-8:__UG_NAME__ -> 57:envelope___control___4 ;
-9:__UG_NAME__ -> 57:envelope___control___5 ;
-10:__UG_NAME__ -> 57:envelope___control___6 ;
-11:__UG_NAME__ -> 57:envelope___control___7 ;
-66:__UG_NAME__ -> 67:gate ;
-21:__UG_NAME__ -> 67:envelope___control___0 ;
-21:__UG_NAME__ -> 67:envelope___control___4 ;
-22:__UG_NAME__ -> 67:envelope___control___5 ;
-23:__UG_NAME__ -> 67:envelope___control___6 ;
-24:__UG_NAME__ -> 67:envelope___control___7 ;
-77:__UG_NAME__ -> 78:gate ;
-69:__UG_NAME__ -> 78:envelope___mul____add___0 ;
-69:__UG_NAME__ -> 78:envelope___mul____add___4 ;
-26:__UG_NAME__ -> 78:envelope___control___5 ;
-27:__UG_NAME__ -> 78:envelope___control___6 ;
-28:__UG_NAME__ -> 78:envelope___control___7 ;
-90:__UG_NAME__ -> 91:gate ;
-12:__UG_NAME__ -> 91:envelope___control___0 ;
-12:__UG_NAME__ -> 91:envelope___control___4 ;
-13:__UG_NAME__ -> 91:envelope___control___5 ;
-14:__UG_NAME__ -> 91:envelope___control___6 ;
-15:__UG_NAME__ -> 91:envelope___control___7 ;
-101:__UG_NAME__ -> 102:gate ;
-17:__UG_NAME__ -> 102:envelope___control___0 ;
-17:__UG_NAME__ -> 102:envelope___control___4 ;
-18:__UG_NAME__ -> 102:envelope___control___5 ;
-19:__UG_NAME__ -> 102:envelope___control___6 ;
-20:__UG_NAME__ -> 102:envelope___control___7 ;
-113:__UG_NAME__ -> 114:gate ;
-0:__UG_NAME__ -> 114:envelope___control___0 ;
-0:__UG_NAME__ -> 114:envelope___control___4 ;
-1:__UG_NAME__ -> 114:envelope___control___5 ;
-2:__UG_NAME__ -> 114:envelope___control___6 ;
-3:__UG_NAME__ -> 114:envelope___control___7 ;
-0:__UG_NAME__ -> 31:in ;
-4:__UG_NAME__ -> 34:in ;
-5:__UG_NAME__ -> 38:in ;
-17:__UG_NAME__ -> 43:in ;
-21:__UG_NAME__ -> 46:in ;
-8:__UG_NAME__ -> 49:in ;
-9:__UG_NAME__ -> 53:in ;
-22:__UG_NAME__ -> 63:in ;
-69:__UG_NAME__ -> 70:in ;
-26:__UG_NAME__ -> 74:in ;
-1:__UG_NAME__ -> 79:in ;
-12:__UG_NAME__ -> 83:in ;
-13:__UG_NAME__ -> 87:in ;
-18:__UG_NAME__ -> 98:in ;
-29:__UG_NAME__ -> 58:bus ;
-104:__UG_NAME__ -> 105:dsthi ;
-103:__UG_NAME__ -> 105:dstlo ;
-95:__UG_NAME__ -> 105:in ;
-102:__UG_NAME__ -> 103:a ;
-67:__UG_NAME__ -> 104:a ;
-25:__UG_NAME__ -> 69:in ;
-119:__UG_NAME__ -> 120:signals___x____fade2___0 ;
-115:__UG_NAME__ -> 120:signals___x____fade2___1 ;
-30:__UG_NAME__ -> 120:bus ;
-78:__UG_NAME__ -> 106:rq ;
-105:__UG_NAME__ -> 106:freq ;
-81:__UG_NAME__ -> 106:in ;
-78:__UG_NAME__ -> 116:rq ;
-105:__UG_NAME__ -> 116:freq ;
-59:__UG_NAME__ -> 116:in ;
-94:__UG_NAME__ -> 95:phase ;
-92:__UG_NAME__ -> 95:freq ;
-114:__UG_NAME__ -> 115:level ;
-111:__UG_NAME__ -> 115:pan ;
-106:__UG_NAME__ -> 115:inb ;
-81:__UG_NAME__ -> 115:ina ;
-114:__UG_NAME__ -> 119:level ;
-118:__UG_NAME__ -> 119:pan ;
-116:__UG_NAME__ -> 119:inb ;
-59:__UG_NAME__ -> 119:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_krush.dot b/etc/synthdefs/graphviz/sonic-pi-fx_krush.dot
deleted file mode 100644
index 63712bc..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_krush.dot
+++ /dev/null
@@ -1,326 +0,0 @@
-digraph synthdef {
-36 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-98 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-100 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :gain
- default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :gain_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :gain_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :gain_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :res
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-112 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-113 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>squared }" style="filled, bold, rounded"  shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> } |<__UG_NAME__>squared }" style="filled, bold, rounded"  shape=record rankdir=LR];
-115 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-116 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-35:__UG_NAME__ -> 36:a ;
-35:__UG_NAME__ -> 39:a ;
-59:__UG_NAME__ -> 60:b ;
-58:__UG_NAME__ -> 60:a ;
-73:__UG_NAME__ -> 74:b ;
-61:__UG_NAME__ -> 74:a ;
-59:__UG_NAME__ -> 76:b ;
-58:__UG_NAME__ -> 76:a ;
-78:__UG_NAME__ -> 79:b ;
-77:__UG_NAME__ -> 79:a ;
-61:__UG_NAME__ -> 80:b ;
-72:__UG_NAME__ -> 80:a ;
-77:__UG_NAME__ -> 93:b ;
-72:__UG_NAME__ -> 93:a ;
-29:__UG_NAME__ -> 30:b ;
-26:__UG_NAME__ -> 30:a ;
-33:__UG_NAME__ -> 34:b ;
-30:__UG_NAME__ -> 34:a ;
-42:__UG_NAME__ -> 43:b ;
-40:__UG_NAME__ -> 43:a ;
-46:__UG_NAME__ -> 47:b ;
-43:__UG_NAME__ -> 47:a ;
-52:__UG_NAME__ -> 53:b ;
-49:__UG_NAME__ -> 53:a ;
-56:__UG_NAME__ -> 57:b ;
-53:__UG_NAME__ -> 57:a ;
-66:__UG_NAME__ -> 67:b ;
-63:__UG_NAME__ -> 67:a ;
-70:__UG_NAME__ -> 71:b ;
-67:__UG_NAME__ -> 71:a ;
-74:__UG_NAME__ -> 75:b ;
-62:__UG_NAME__ -> 75:a ;
-80:__UG_NAME__ -> 81:b ;
-62:__UG_NAME__ -> 81:a ;
-75:__UG_NAME__ -> 82:a ;
-93:__UG_NAME__ -> 98:b ;
-88:__UG_NAME__ -> 98:a ;
-79:__UG_NAME__ -> 99:b ;
-88:__UG_NAME__ -> 99:a ;
-99:__UG_NAME__ -> 100:a ;
-104:__UG_NAME__ -> 105:b ;
-102:__UG_NAME__ -> 105:a ;
-92:__UG_NAME__ -> 106:b ;
-105:__UG_NAME__ -> 106:a ;
-87:__UG_NAME__ -> 109:b ;
-108:__UG_NAME__ -> 109:a ;
-96:__UG_NAME__ -> 110:b ;
-109:__UG_NAME__ -> 110:a ;
-36:__UG_NAME__ -> 37:a ;
-72:__UG_NAME__ -> 73:a ;
-72:__UG_NAME__ -> 78:a ;
-39:__UG_NAME__ -> 114:a ;
-82:__UG_NAME__ -> 83:b ;
-81:__UG_NAME__ -> 83:a ;
-100:__UG_NAME__ -> 101:b ;
-98:__UG_NAME__ -> 101:a ;
-28:__UG_NAME__ -> 29:a ;
-32:__UG_NAME__ -> 33:a ;
-41:__UG_NAME__ -> 42:a ;
-45:__UG_NAME__ -> 46:a ;
-51:__UG_NAME__ -> 52:a ;
-55:__UG_NAME__ -> 56:a ;
-65:__UG_NAME__ -> 66:a ;
-69:__UG_NAME__ -> 70:a ;
-86:__UG_NAME__ -> 87:a ;
-91:__UG_NAME__ -> 92:a ;
-95:__UG_NAME__ -> 96:a ;
-103:__UG_NAME__ -> 104:a ;
-27:__UG_NAME__ -> 28:a ;
-31:__UG_NAME__ -> 32:a ;
-38:__UG_NAME__ -> 41:a ;
-44:__UG_NAME__ -> 45:a ;
-50:__UG_NAME__ -> 51:a ;
-54:__UG_NAME__ -> 55:a ;
-60:__UG_NAME__ -> 61:a ;
-64:__UG_NAME__ -> 65:a ;
-68:__UG_NAME__ -> 69:a ;
-76:__UG_NAME__ -> 77:a ;
-85:__UG_NAME__ -> 86:a ;
-90:__UG_NAME__ -> 91:a ;
-94:__UG_NAME__ -> 95:a ;
-97:__UG_NAME__ -> 103:a ;
-34:__UG_NAME__ -> 35:gate ;
-4:__UG_NAME__ -> 35:envelope___control___0 ;
-4:__UG_NAME__ -> 35:envelope___control___4 ;
-5:__UG_NAME__ -> 35:envelope___control___5 ;
-6:__UG_NAME__ -> 35:envelope___control___6 ;
-7:__UG_NAME__ -> 35:envelope___control___7 ;
-47:__UG_NAME__ -> 48:gate ;
-16:__UG_NAME__ -> 48:envelope___control___0 ;
-16:__UG_NAME__ -> 48:envelope___control___4 ;
-17:__UG_NAME__ -> 48:envelope___control___5 ;
-18:__UG_NAME__ -> 48:envelope___control___6 ;
-19:__UG_NAME__ -> 48:envelope___control___7 ;
-57:__UG_NAME__ -> 58:gate ;
-8:__UG_NAME__ -> 58:envelope___control___0 ;
-8:__UG_NAME__ -> 58:envelope___control___4 ;
-9:__UG_NAME__ -> 58:envelope___control___5 ;
-10:__UG_NAME__ -> 58:envelope___control___6 ;
-11:__UG_NAME__ -> 58:envelope___control___7 ;
-71:__UG_NAME__ -> 72:gate ;
-12:__UG_NAME__ -> 72:envelope___control___0 ;
-12:__UG_NAME__ -> 72:envelope___control___4 ;
-13:__UG_NAME__ -> 72:envelope___control___5 ;
-14:__UG_NAME__ -> 72:envelope___control___6 ;
-15:__UG_NAME__ -> 72:envelope___control___7 ;
-106:__UG_NAME__ -> 107:gate ;
-0:__UG_NAME__ -> 107:envelope___control___0 ;
-0:__UG_NAME__ -> 107:envelope___control___4 ;
-1:__UG_NAME__ -> 107:envelope___control___5 ;
-2:__UG_NAME__ -> 107:envelope___control___6 ;
-3:__UG_NAME__ -> 107:envelope___control___7 ;
-110:__UG_NAME__ -> 111:gate ;
-84:__UG_NAME__ -> 111:envelope___mul____add___0 ;
-84:__UG_NAME__ -> 111:envelope___mul____add___4 ;
-21:__UG_NAME__ -> 111:envelope___control___5 ;
-22:__UG_NAME__ -> 111:envelope___control___6 ;
-23:__UG_NAME__ -> 111:envelope___control___7 ;
-4:__UG_NAME__ -> 27:in ;
-5:__UG_NAME__ -> 31:in ;
-16:__UG_NAME__ -> 38:in ;
-17:__UG_NAME__ -> 44:in ;
-8:__UG_NAME__ -> 50:in ;
-9:__UG_NAME__ -> 54:in ;
-12:__UG_NAME__ -> 64:in ;
-13:__UG_NAME__ -> 68:in ;
-84:__UG_NAME__ -> 85:in ;
-1:__UG_NAME__ -> 90:in ;
-21:__UG_NAME__ -> 94:in ;
-0:__UG_NAME__ -> 97:in ;
-24:__UG_NAME__ -> 59:bus ;
-48:__UG_NAME__ -> 89:a ;
-20:__UG_NAME__ -> 84:in ;
-115:__UG_NAME__ -> 117:signals___x____fade2___0 ;
-116:__UG_NAME__ -> 117:signals___x____fade2___1 ;
-25:__UG_NAME__ -> 117:bus ;
-111:__UG_NAME__ -> 112:rq ;
-89:__UG_NAME__ -> 112:freq ;
-101:__UG_NAME__ -> 112:in ;
-111:__UG_NAME__ -> 113:rq ;
-89:__UG_NAME__ -> 113:freq ;
-83:__UG_NAME__ -> 113:in ;
-61:__UG_NAME__ -> 62:a ;
-77:__UG_NAME__ -> 88:a ;
-107:__UG_NAME__ -> 115:level ;
-114:__UG_NAME__ -> 115:pan ;
-113:__UG_NAME__ -> 115:inb ;
-61:__UG_NAME__ -> 115:ina ;
-107:__UG_NAME__ -> 116:level ;
-37:__UG_NAME__ -> 116:pan ;
-112:__UG_NAME__ -> 116:inb ;
-77:__UG_NAME__ -> 116:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_level.dot b/etc/synthdefs/graphviz/sonic-pi-fx_level.dot
deleted file mode 100644
index d83d1c8..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_level.dot
+++ /dev/null
@@ -1,60 +0,0 @@
-digraph synthdef {
-17 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-18 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-11 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-15 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-8 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-14 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-7 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-13 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-6 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-12 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-10 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-9 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-19 [label = "{{ <bus> bus|{{<signals___binary____op____u____gen___0>|<signals___binary____op____u____gen___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-9:__UG_NAME__ -> 17:b ;
-16:__UG_NAME__ -> 17:a ;
-9:__UG_NAME__ -> 18:b ;
-16:__UG_NAME__ -> 18:a ;
-8:__UG_NAME__ -> 11:b ;
-10:__UG_NAME__ -> 11:a ;
-14:__UG_NAME__ -> 15:b ;
-11:__UG_NAME__ -> 15:a ;
-7:__UG_NAME__ -> 8:a ;
-13:__UG_NAME__ -> 14:a ;
-6:__UG_NAME__ -> 7:a ;
-12:__UG_NAME__ -> 13:a ;
-15:__UG_NAME__ -> 16:gate ;
-0:__UG_NAME__ -> 16:envelope___control___0 ;
-0:__UG_NAME__ -> 16:envelope___control___4 ;
-1:__UG_NAME__ -> 16:envelope___control___5 ;
-2:__UG_NAME__ -> 16:envelope___control___6 ;
-3:__UG_NAME__ -> 16:envelope___control___7 ;
-0:__UG_NAME__ -> 6:in ;
-1:__UG_NAME__ -> 12:in ;
-4:__UG_NAME__ -> 9:bus ;
-17:__UG_NAME__ -> 19:signals___binary____op____u____gen___0 ;
-18:__UG_NAME__ -> 19:signals___binary____op____u____gen___1 ;
-5:__UG_NAME__ -> 19:bus ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_lpf.dot b/etc/synthdefs/graphviz/sonic-pi-fx_lpf.dot
deleted file mode 100644
index 51948e5..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_lpf.dot
+++ /dev/null
@@ -1,200 +0,0 @@
-digraph synthdef {
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-20 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-19 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-18 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-21 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-47 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-66 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-65 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-69 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-31:__UG_NAME__ -> 32:b ;
-30:__UG_NAME__ -> 32:a ;
-31:__UG_NAME__ -> 36:b ;
-30:__UG_NAME__ -> 36:a ;
-54:__UG_NAME__ -> 55:a ;
-54:__UG_NAME__ -> 67:a ;
-27:__UG_NAME__ -> 28:b ;
-24:__UG_NAME__ -> 28:a ;
-20:__UG_NAME__ -> 29:b ;
-28:__UG_NAME__ -> 29:a ;
-40:__UG_NAME__ -> 41:b ;
-37:__UG_NAME__ -> 41:a ;
-43:__UG_NAME__ -> 44:b ;
-41:__UG_NAME__ -> 44:a ;
-51:__UG_NAME__ -> 52:b ;
-48:__UG_NAME__ -> 52:a ;
-23:__UG_NAME__ -> 53:b ;
-52:__UG_NAME__ -> 53:a ;
-60:__UG_NAME__ -> 61:b ;
-57:__UG_NAME__ -> 61:a ;
-62:__UG_NAME__ -> 63:b ;
-61:__UG_NAME__ -> 63:a ;
-55:__UG_NAME__ -> 56:a ;
-67:__UG_NAME__ -> 68:a ;
-19:__UG_NAME__ -> 20:a ;
-22:__UG_NAME__ -> 23:a ;
-26:__UG_NAME__ -> 27:a ;
-39:__UG_NAME__ -> 40:a ;
-42:__UG_NAME__ -> 43:a ;
-50:__UG_NAME__ -> 51:a ;
-59:__UG_NAME__ -> 60:a ;
-35:__UG_NAME__ -> 62:a ;
-18:__UG_NAME__ -> 19:a ;
-21:__UG_NAME__ -> 22:a ;
-25:__UG_NAME__ -> 26:a ;
-34:__UG_NAME__ -> 35:a ;
-38:__UG_NAME__ -> 39:a ;
-33:__UG_NAME__ -> 42:a ;
-49:__UG_NAME__ -> 50:a ;
-58:__UG_NAME__ -> 59:a ;
-29:__UG_NAME__ -> 30:gate ;
-8:__UG_NAME__ -> 30:envelope___control___0 ;
-8:__UG_NAME__ -> 30:envelope___control___4 ;
-9:__UG_NAME__ -> 30:envelope___control___5 ;
-10:__UG_NAME__ -> 30:envelope___control___6 ;
-11:__UG_NAME__ -> 30:envelope___control___7 ;
-44:__UG_NAME__ -> 45:gate ;
-12:__UG_NAME__ -> 45:envelope___control___0 ;
-12:__UG_NAME__ -> 45:envelope___control___4 ;
-13:__UG_NAME__ -> 45:envelope___control___5 ;
-14:__UG_NAME__ -> 45:envelope___control___6 ;
-15:__UG_NAME__ -> 45:envelope___control___7 ;
-53:__UG_NAME__ -> 54:gate ;
-4:__UG_NAME__ -> 54:envelope___control___0 ;
-4:__UG_NAME__ -> 54:envelope___control___4 ;
-5:__UG_NAME__ -> 54:envelope___control___5 ;
-6:__UG_NAME__ -> 54:envelope___control___6 ;
-7:__UG_NAME__ -> 54:envelope___control___7 ;
-63:__UG_NAME__ -> 64:gate ;
-0:__UG_NAME__ -> 64:envelope___control___0 ;
-0:__UG_NAME__ -> 64:envelope___control___4 ;
-1:__UG_NAME__ -> 64:envelope___control___5 ;
-2:__UG_NAME__ -> 64:envelope___control___6 ;
-3:__UG_NAME__ -> 64:envelope___control___7 ;
-9:__UG_NAME__ -> 18:in ;
-5:__UG_NAME__ -> 21:in ;
-8:__UG_NAME__ -> 25:in ;
-13:__UG_NAME__ -> 33:in ;
-1:__UG_NAME__ -> 34:in ;
-12:__UG_NAME__ -> 38:in ;
-4:__UG_NAME__ -> 49:in ;
-0:__UG_NAME__ -> 58:in ;
-16:__UG_NAME__ -> 31:bus ;
-46:__UG_NAME__ -> 47:freq ;
-36:__UG_NAME__ -> 47:in ;
-46:__UG_NAME__ -> 66:freq ;
-32:__UG_NAME__ -> 66:in ;
-45:__UG_NAME__ -> 46:a ;
-65:__UG_NAME__ -> 70:signals___x____fade2___0 ;
-69:__UG_NAME__ -> 70:signals___x____fade2___1 ;
-17:__UG_NAME__ -> 70:bus ;
-64:__UG_NAME__ -> 65:level ;
-56:__UG_NAME__ -> 65:pan ;
-47:__UG_NAME__ -> 65:inb ;
-36:__UG_NAME__ -> 65:ina ;
-64:__UG_NAME__ -> 69:level ;
-68:__UG_NAME__ -> 69:pan ;
-66:__UG_NAME__ -> 69:inb ;
-32:__UG_NAME__ -> 69:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_nhpf.dot b/etc/synthdefs/graphviz/sonic-pi-fx_nhpf.dot
deleted file mode 100644
index db64b96..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_nhpf.dot
+++ /dev/null
@@ -1,204 +0,0 @@
-digraph synthdef {
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-23 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-21 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-61 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-18 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-20 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-19 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-63 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-72 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-70 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-71 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-29:__UG_NAME__ -> 30:b ;
-28:__UG_NAME__ -> 30:a ;
-57:__UG_NAME__ -> 58:a ;
-57:__UG_NAME__ -> 59:a ;
-29:__UG_NAME__ -> 60:b ;
-28:__UG_NAME__ -> 60:a ;
-22:__UG_NAME__ -> 23:b ;
-19:__UG_NAME__ -> 23:a ;
-26:__UG_NAME__ -> 27:b ;
-23:__UG_NAME__ -> 27:a ;
-34:__UG_NAME__ -> 35:b ;
-31:__UG_NAME__ -> 35:a ;
-38:__UG_NAME__ -> 39:b ;
-35:__UG_NAME__ -> 39:a ;
-47:__UG_NAME__ -> 48:b ;
-44:__UG_NAME__ -> 48:a ;
-52:__UG_NAME__ -> 53:b ;
-49:__UG_NAME__ -> 53:a ;
-55:__UG_NAME__ -> 56:b ;
-53:__UG_NAME__ -> 56:a ;
-67:__UG_NAME__ -> 68:b ;
-48:__UG_NAME__ -> 68:a ;
-59:__UG_NAME__ -> 62:a ;
-58:__UG_NAME__ -> 64:a ;
-21:__UG_NAME__ -> 22:a ;
-25:__UG_NAME__ -> 26:a ;
-33:__UG_NAME__ -> 34:a ;
-37:__UG_NAME__ -> 38:a ;
-46:__UG_NAME__ -> 47:a ;
-51:__UG_NAME__ -> 52:a ;
-54:__UG_NAME__ -> 55:a ;
-66:__UG_NAME__ -> 67:a ;
-20:__UG_NAME__ -> 21:a ;
-24:__UG_NAME__ -> 25:a ;
-32:__UG_NAME__ -> 33:a ;
-36:__UG_NAME__ -> 37:a ;
-45:__UG_NAME__ -> 46:a ;
-50:__UG_NAME__ -> 51:a ;
-18:__UG_NAME__ -> 54:a ;
-65:__UG_NAME__ -> 66:a ;
-27:__UG_NAME__ -> 28:gate ;
-8:__UG_NAME__ -> 28:envelope___control___0 ;
-8:__UG_NAME__ -> 28:envelope___control___4 ;
-9:__UG_NAME__ -> 28:envelope___control___5 ;
-10:__UG_NAME__ -> 28:envelope___control___6 ;
-11:__UG_NAME__ -> 28:envelope___control___7 ;
-39:__UG_NAME__ -> 40:gate ;
-12:__UG_NAME__ -> 40:envelope___control___0 ;
-12:__UG_NAME__ -> 40:envelope___control___4 ;
-13:__UG_NAME__ -> 40:envelope___control___5 ;
-14:__UG_NAME__ -> 40:envelope___control___6 ;
-15:__UG_NAME__ -> 40:envelope___control___7 ;
-56:__UG_NAME__ -> 57:gate ;
-4:__UG_NAME__ -> 57:envelope___control___0 ;
-4:__UG_NAME__ -> 57:envelope___control___4 ;
-5:__UG_NAME__ -> 57:envelope___control___5 ;
-6:__UG_NAME__ -> 57:envelope___control___6 ;
-7:__UG_NAME__ -> 57:envelope___control___7 ;
-68:__UG_NAME__ -> 69:gate ;
-0:__UG_NAME__ -> 69:envelope___control___0 ;
-0:__UG_NAME__ -> 69:envelope___control___4 ;
-1:__UG_NAME__ -> 69:envelope___control___5 ;
-2:__UG_NAME__ -> 69:envelope___control___6 ;
-3:__UG_NAME__ -> 69:envelope___control___7 ;
-41:__UG_NAME__ -> 42:freq ;
-30:__UG_NAME__ -> 42:in ;
-41:__UG_NAME__ -> 61:freq ;
-60:__UG_NAME__ -> 61:in ;
-5:__UG_NAME__ -> 18:in ;
-8:__UG_NAME__ -> 20:in ;
-9:__UG_NAME__ -> 24:in ;
-12:__UG_NAME__ -> 32:in ;
-13:__UG_NAME__ -> 36:in ;
-0:__UG_NAME__ -> 45:in ;
-4:__UG_NAME__ -> 50:in ;
-1:__UG_NAME__ -> 65:in ;
-16:__UG_NAME__ -> 29:bus ;
-40:__UG_NAME__ -> 41:a ;
-42:__UG_NAME__ -> 43:in ;
-61:__UG_NAME__ -> 63:in ;
-70:__UG_NAME__ -> 72:signals___x____fade2___0 ;
-71:__UG_NAME__ -> 72:signals___x____fade2___1 ;
-17:__UG_NAME__ -> 72:bus ;
-69:__UG_NAME__ -> 70:level ;
-64:__UG_NAME__ -> 70:pan ;
-63:__UG_NAME__ -> 70:inb ;
-60:__UG_NAME__ -> 70:ina ;
-69:__UG_NAME__ -> 71:level ;
-62:__UG_NAME__ -> 71:pan ;
-43:__UG_NAME__ -> 71:inb ;
-30:__UG_NAME__ -> 71:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_nlpf.dot b/etc/synthdefs/graphviz/sonic-pi-fx_nlpf.dot
deleted file mode 100644
index c347b94..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_nlpf.dot
+++ /dev/null
@@ -1,204 +0,0 @@
-digraph synthdef {
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-21 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-18 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-20 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-19 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-54 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-67 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-68 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-72 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-65 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-71 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-36:__UG_NAME__ -> 37:b ;
-35:__UG_NAME__ -> 37:a ;
-43:__UG_NAME__ -> 56:a ;
-36:__UG_NAME__ -> 66:b ;
-35:__UG_NAME__ -> 66:a ;
-43:__UG_NAME__ -> 69:a ;
-22:__UG_NAME__ -> 23:b ;
-19:__UG_NAME__ -> 23:a ;
-33:__UG_NAME__ -> 34:b ;
-23:__UG_NAME__ -> 34:a ;
-40:__UG_NAME__ -> 41:b ;
-38:__UG_NAME__ -> 41:a ;
-26:__UG_NAME__ -> 42:b ;
-41:__UG_NAME__ -> 42:a ;
-47:__UG_NAME__ -> 48:b ;
-44:__UG_NAME__ -> 48:a ;
-50:__UG_NAME__ -> 51:b ;
-48:__UG_NAME__ -> 51:a ;
-61:__UG_NAME__ -> 62:b ;
-58:__UG_NAME__ -> 62:a ;
-30:__UG_NAME__ -> 63:b ;
-62:__UG_NAME__ -> 63:a ;
-56:__UG_NAME__ -> 57:a ;
-69:__UG_NAME__ -> 70:a ;
-21:__UG_NAME__ -> 22:a ;
-25:__UG_NAME__ -> 26:a ;
-29:__UG_NAME__ -> 30:a ;
-32:__UG_NAME__ -> 33:a ;
-39:__UG_NAME__ -> 40:a ;
-46:__UG_NAME__ -> 47:a ;
-49:__UG_NAME__ -> 50:a ;
-60:__UG_NAME__ -> 61:a ;
-20:__UG_NAME__ -> 21:a ;
-24:__UG_NAME__ -> 25:a ;
-28:__UG_NAME__ -> 29:a ;
-31:__UG_NAME__ -> 32:a ;
-18:__UG_NAME__ -> 39:a ;
-45:__UG_NAME__ -> 46:a ;
-27:__UG_NAME__ -> 49:a ;
-59:__UG_NAME__ -> 60:a ;
-34:__UG_NAME__ -> 35:gate ;
-8:__UG_NAME__ -> 35:envelope___control___0 ;
-8:__UG_NAME__ -> 35:envelope___control___4 ;
-9:__UG_NAME__ -> 35:envelope___control___5 ;
-10:__UG_NAME__ -> 35:envelope___control___6 ;
-11:__UG_NAME__ -> 35:envelope___control___7 ;
-42:__UG_NAME__ -> 43:gate ;
-4:__UG_NAME__ -> 43:envelope___control___0 ;
-4:__UG_NAME__ -> 43:envelope___control___4 ;
-5:__UG_NAME__ -> 43:envelope___control___5 ;
-6:__UG_NAME__ -> 43:envelope___control___6 ;
-7:__UG_NAME__ -> 43:envelope___control___7 ;
-51:__UG_NAME__ -> 52:gate ;
-12:__UG_NAME__ -> 52:envelope___control___0 ;
-12:__UG_NAME__ -> 52:envelope___control___4 ;
-13:__UG_NAME__ -> 52:envelope___control___5 ;
-14:__UG_NAME__ -> 52:envelope___control___6 ;
-15:__UG_NAME__ -> 52:envelope___control___7 ;
-63:__UG_NAME__ -> 64:gate ;
-0:__UG_NAME__ -> 64:envelope___control___0 ;
-0:__UG_NAME__ -> 64:envelope___control___4 ;
-1:__UG_NAME__ -> 64:envelope___control___5 ;
-2:__UG_NAME__ -> 64:envelope___control___6 ;
-3:__UG_NAME__ -> 64:envelope___control___7 ;
-4:__UG_NAME__ -> 18:in ;
-8:__UG_NAME__ -> 20:in ;
-5:__UG_NAME__ -> 24:in ;
-13:__UG_NAME__ -> 27:in ;
-1:__UG_NAME__ -> 28:in ;
-9:__UG_NAME__ -> 31:in ;
-12:__UG_NAME__ -> 45:in ;
-0:__UG_NAME__ -> 59:in ;
-16:__UG_NAME__ -> 36:bus ;
-53:__UG_NAME__ -> 54:freq ;
-37:__UG_NAME__ -> 54:in ;
-53:__UG_NAME__ -> 67:freq ;
-66:__UG_NAME__ -> 67:in ;
-52:__UG_NAME__ -> 53:a ;
-54:__UG_NAME__ -> 55:in ;
-67:__UG_NAME__ -> 68:in ;
-71:__UG_NAME__ -> 72:signals___x____fade2___0 ;
-65:__UG_NAME__ -> 72:signals___x____fade2___1 ;
-17:__UG_NAME__ -> 72:bus ;
-64:__UG_NAME__ -> 65:level ;
-57:__UG_NAME__ -> 65:pan ;
-55:__UG_NAME__ -> 65:inb ;
-37:__UG_NAME__ -> 65:ina ;
-64:__UG_NAME__ -> 71:level ;
-70:__UG_NAME__ -> 71:pan ;
-68:__UG_NAME__ -> 71:inb ;
-66:__UG_NAME__ -> 71:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_normaliser.dot b/etc/synthdefs/graphviz/sonic-pi-fx_normaliser.dot
deleted file mode 100644
index 99f0bd5..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_normaliser.dot
+++ /dev/null
@@ -1,198 +0,0 @@
-digraph synthdef {
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-21 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-20 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :level_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :level_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :level_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-19 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-18 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-59 [label = "{{ <in> in|<level> level|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-65 [label = "{{ <in> in|<level> level|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-69 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-63 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-68 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-38:__UG_NAME__ -> 58:b ;
-57:__UG_NAME__ -> 58:a ;
-60:__UG_NAME__ -> 61:a ;
-38:__UG_NAME__ -> 64:b ;
-57:__UG_NAME__ -> 64:a ;
-60:__UG_NAME__ -> 66:a ;
-21:__UG_NAME__ -> 22:b ;
-18:__UG_NAME__ -> 22:a ;
-25:__UG_NAME__ -> 26:b ;
-22:__UG_NAME__ -> 26:a ;
-31:__UG_NAME__ -> 32:b ;
-28:__UG_NAME__ -> 32:a ;
-35:__UG_NAME__ -> 36:b ;
-32:__UG_NAME__ -> 36:a ;
-42:__UG_NAME__ -> 43:b ;
-39:__UG_NAME__ -> 43:a ;
-46:__UG_NAME__ -> 47:b ;
-43:__UG_NAME__ -> 47:a ;
-51:__UG_NAME__ -> 52:b ;
-48:__UG_NAME__ -> 52:a ;
-55:__UG_NAME__ -> 56:b ;
-52:__UG_NAME__ -> 56:a ;
-61:__UG_NAME__ -> 62:a ;
-66:__UG_NAME__ -> 67:a ;
-20:__UG_NAME__ -> 21:a ;
-24:__UG_NAME__ -> 25:a ;
-30:__UG_NAME__ -> 31:a ;
-34:__UG_NAME__ -> 35:a ;
-41:__UG_NAME__ -> 42:a ;
-45:__UG_NAME__ -> 46:a ;
-50:__UG_NAME__ -> 51:a ;
-54:__UG_NAME__ -> 55:a ;
-19:__UG_NAME__ -> 20:a ;
-23:__UG_NAME__ -> 24:a ;
-29:__UG_NAME__ -> 30:a ;
-33:__UG_NAME__ -> 34:a ;
-40:__UG_NAME__ -> 41:a ;
-44:__UG_NAME__ -> 45:a ;
-49:__UG_NAME__ -> 50:a ;
-53:__UG_NAME__ -> 54:a ;
-26:__UG_NAME__ -> 27:gate ;
-12:__UG_NAME__ -> 27:envelope___control___0 ;
-12:__UG_NAME__ -> 27:envelope___control___4 ;
-13:__UG_NAME__ -> 27:envelope___control___5 ;
-14:__UG_NAME__ -> 27:envelope___control___6 ;
-15:__UG_NAME__ -> 27:envelope___control___7 ;
-36:__UG_NAME__ -> 37:gate ;
-0:__UG_NAME__ -> 37:envelope___control___0 ;
-0:__UG_NAME__ -> 37:envelope___control___4 ;
-1:__UG_NAME__ -> 37:envelope___control___5 ;
-2:__UG_NAME__ -> 37:envelope___control___6 ;
-3:__UG_NAME__ -> 37:envelope___control___7 ;
-56:__UG_NAME__ -> 57:gate ;
-8:__UG_NAME__ -> 57:envelope___control___0 ;
-8:__UG_NAME__ -> 57:envelope___control___4 ;
-9:__UG_NAME__ -> 57:envelope___control___5 ;
-10:__UG_NAME__ -> 57:envelope___control___6 ;
-11:__UG_NAME__ -> 57:envelope___control___7 ;
-47:__UG_NAME__ -> 60:gate ;
-4:__UG_NAME__ -> 60:envelope___control___0 ;
-4:__UG_NAME__ -> 60:envelope___control___4 ;
-5:__UG_NAME__ -> 60:envelope___control___5 ;
-6:__UG_NAME__ -> 60:envelope___control___6 ;
-7:__UG_NAME__ -> 60:envelope___control___7 ;
-12:__UG_NAME__ -> 19:in ;
-13:__UG_NAME__ -> 23:in ;
-0:__UG_NAME__ -> 29:in ;
-1:__UG_NAME__ -> 33:in ;
-4:__UG_NAME__ -> 40:in ;
-5:__UG_NAME__ -> 44:in ;
-8:__UG_NAME__ -> 49:in ;
-9:__UG_NAME__ -> 53:in ;
-16:__UG_NAME__ -> 38:bus ;
-27:__UG_NAME__ -> 59:level ;
-58:__UG_NAME__ -> 59:in ;
-27:__UG_NAME__ -> 65:level ;
-64:__UG_NAME__ -> 65:in ;
-68:__UG_NAME__ -> 69:signals___x____fade2___0 ;
-63:__UG_NAME__ -> 69:signals___x____fade2___1 ;
-17:__UG_NAME__ -> 69:bus ;
-37:__UG_NAME__ -> 63:level ;
-62:__UG_NAME__ -> 63:pan ;
-59:__UG_NAME__ -> 63:inb ;
-58:__UG_NAME__ -> 63:ina ;
-37:__UG_NAME__ -> 68:level ;
-67:__UG_NAME__ -> 68:pan ;
-65:__UG_NAME__ -> 68:inb ;
-64:__UG_NAME__ -> 68:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_nrbpf.dot b/etc/synthdefs/graphviz/sonic-pi-fx_nrbpf.dot
deleted file mode 100644
index bc387f6..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_nrbpf.dot
+++ /dev/null
@@ -1,246 +0,0 @@
-digraph synthdef {
-33 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :centre
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :centre_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :centre_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :centre_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :res
- default: 0.6" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-84 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-87 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-56 [label = "{{ <in> in|<freq> freq|<bwr> bwr} |<__UG_NAME__>resonz }" style="filled, bold, rounded"  shape=record rankdir=LR];
-83 [label = "{{ <in> in|<freq> freq|<bwr> bwr} |<__UG_NAME__>resonz }" style="filled, bold, rounded"  shape=record rankdir=LR];
-80 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-86 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-32:__UG_NAME__ -> 33:b ;
-31:__UG_NAME__ -> 33:a ;
-67:__UG_NAME__ -> 68:a ;
-67:__UG_NAME__ -> 81:a ;
-32:__UG_NAME__ -> 82:b ;
-31:__UG_NAME__ -> 82:a ;
-25:__UG_NAME__ -> 26:b ;
-22:__UG_NAME__ -> 26:a ;
-29:__UG_NAME__ -> 30:b ;
-26:__UG_NAME__ -> 30:a ;
-37:__UG_NAME__ -> 38:b ;
-34:__UG_NAME__ -> 38:a ;
-41:__UG_NAME__ -> 42:b ;
-38:__UG_NAME__ -> 42:a ;
-49:__UG_NAME__ -> 50:b ;
-45:__UG_NAME__ -> 50:a ;
-53:__UG_NAME__ -> 54:b ;
-50:__UG_NAME__ -> 54:a ;
-61:__UG_NAME__ -> 62:b ;
-58:__UG_NAME__ -> 62:a ;
-65:__UG_NAME__ -> 66:b ;
-62:__UG_NAME__ -> 66:a ;
-73:__UG_NAME__ -> 74:b ;
-70:__UG_NAME__ -> 74:a ;
-77:__UG_NAME__ -> 78:b ;
-74:__UG_NAME__ -> 78:a ;
-68:__UG_NAME__ -> 69:a ;
-81:__UG_NAME__ -> 85:a ;
-24:__UG_NAME__ -> 25:a ;
-28:__UG_NAME__ -> 29:a ;
-36:__UG_NAME__ -> 37:a ;
-40:__UG_NAME__ -> 41:a ;
-48:__UG_NAME__ -> 49:a ;
-52:__UG_NAME__ -> 53:a ;
-60:__UG_NAME__ -> 61:a ;
-64:__UG_NAME__ -> 65:a ;
-72:__UG_NAME__ -> 73:a ;
-76:__UG_NAME__ -> 77:a ;
-23:__UG_NAME__ -> 24:a ;
-27:__UG_NAME__ -> 28:a ;
-35:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:a ;
-47:__UG_NAME__ -> 48:a ;
-51:__UG_NAME__ -> 52:a ;
-59:__UG_NAME__ -> 60:a ;
-63:__UG_NAME__ -> 64:a ;
-71:__UG_NAME__ -> 72:a ;
-75:__UG_NAME__ -> 76:a ;
-30:__UG_NAME__ -> 31:gate ;
-8:__UG_NAME__ -> 31:envelope___control___0 ;
-8:__UG_NAME__ -> 31:envelope___control___4 ;
-9:__UG_NAME__ -> 31:envelope___control___5 ;
-10:__UG_NAME__ -> 31:envelope___control___6 ;
-11:__UG_NAME__ -> 31:envelope___control___7 ;
-42:__UG_NAME__ -> 43:gate ;
-12:__UG_NAME__ -> 43:envelope___control___0 ;
-12:__UG_NAME__ -> 43:envelope___control___4 ;
-13:__UG_NAME__ -> 43:envelope___control___5 ;
-14:__UG_NAME__ -> 43:envelope___control___6 ;
-15:__UG_NAME__ -> 43:envelope___control___7 ;
-54:__UG_NAME__ -> 55:gate ;
-46:__UG_NAME__ -> 55:envelope___mul____add___0 ;
-46:__UG_NAME__ -> 55:envelope___mul____add___4 ;
-17:__UG_NAME__ -> 55:envelope___control___5 ;
-18:__UG_NAME__ -> 55:envelope___control___6 ;
-19:__UG_NAME__ -> 55:envelope___control___7 ;
-66:__UG_NAME__ -> 67:gate ;
-4:__UG_NAME__ -> 67:envelope___control___0 ;
-4:__UG_NAME__ -> 67:envelope___control___4 ;
-5:__UG_NAME__ -> 67:envelope___control___5 ;
-6:__UG_NAME__ -> 67:envelope___control___6 ;
-7:__UG_NAME__ -> 67:envelope___control___7 ;
-78:__UG_NAME__ -> 79:gate ;
-0:__UG_NAME__ -> 79:envelope___control___0 ;
-0:__UG_NAME__ -> 79:envelope___control___4 ;
-1:__UG_NAME__ -> 79:envelope___control___5 ;
-2:__UG_NAME__ -> 79:envelope___control___6 ;
-3:__UG_NAME__ -> 79:envelope___control___7 ;
-8:__UG_NAME__ -> 23:in ;
-9:__UG_NAME__ -> 27:in ;
-12:__UG_NAME__ -> 35:in ;
-13:__UG_NAME__ -> 39:in ;
-46:__UG_NAME__ -> 47:in ;
-17:__UG_NAME__ -> 51:in ;
-4:__UG_NAME__ -> 59:in ;
-5:__UG_NAME__ -> 63:in ;
-0:__UG_NAME__ -> 71:in ;
-1:__UG_NAME__ -> 75:in ;
-20:__UG_NAME__ -> 32:bus ;
-43:__UG_NAME__ -> 44:a ;
-16:__UG_NAME__ -> 46:in ;
-56:__UG_NAME__ -> 57:in ;
-83:__UG_NAME__ -> 84:in ;
-86:__UG_NAME__ -> 87:signals___x____fade2___0 ;
-80:__UG_NAME__ -> 87:signals___x____fade2___1 ;
-21:__UG_NAME__ -> 87:bus ;
-55:__UG_NAME__ -> 56:bwr ;
-44:__UG_NAME__ -> 56:freq ;
-33:__UG_NAME__ -> 56:in ;
-55:__UG_NAME__ -> 83:bwr ;
-44:__UG_NAME__ -> 83:freq ;
-82:__UG_NAME__ -> 83:in ;
-79:__UG_NAME__ -> 80:level ;
-69:__UG_NAME__ -> 80:pan ;
-57:__UG_NAME__ -> 80:inb ;
-33:__UG_NAME__ -> 80:ina ;
-79:__UG_NAME__ -> 86:level ;
-85:__UG_NAME__ -> 86:pan ;
-84:__UG_NAME__ -> 86:inb ;
-82:__UG_NAME__ -> 86:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_nrhpf.dot b/etc/synthdefs/graphviz/sonic-pi-fx_nrhpf.dot
deleted file mode 100644
index 24d2656..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_nrhpf.dot
+++ /dev/null
@@ -1,244 +0,0 @@
-digraph synthdef {
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :res
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-51 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-84 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-86 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-66 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rhpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-83 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rhpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-80 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-85 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-52:__UG_NAME__ -> 53:b ;
-51:__UG_NAME__ -> 53:a ;
-52:__UG_NAME__ -> 54:b ;
-51:__UG_NAME__ -> 54:a ;
-67:__UG_NAME__ -> 68:a ;
-67:__UG_NAME__ -> 81:a ;
-28:__UG_NAME__ -> 29:b ;
-25:__UG_NAME__ -> 29:a ;
-32:__UG_NAME__ -> 33:b ;
-29:__UG_NAME__ -> 33:a ;
-37:__UG_NAME__ -> 38:b ;
-34:__UG_NAME__ -> 38:a ;
-45:__UG_NAME__ -> 46:b ;
-42:__UG_NAME__ -> 46:a ;
-49:__UG_NAME__ -> 50:b ;
-46:__UG_NAME__ -> 50:a ;
-57:__UG_NAME__ -> 58:b ;
-55:__UG_NAME__ -> 58:a ;
-59:__UG_NAME__ -> 60:b ;
-58:__UG_NAME__ -> 60:a ;
-63:__UG_NAME__ -> 64:b ;
-38:__UG_NAME__ -> 64:a ;
-73:__UG_NAME__ -> 74:b ;
-71:__UG_NAME__ -> 74:a ;
-77:__UG_NAME__ -> 78:b ;
-74:__UG_NAME__ -> 78:a ;
-68:__UG_NAME__ -> 69:a ;
-81:__UG_NAME__ -> 82:a ;
-27:__UG_NAME__ -> 28:a ;
-31:__UG_NAME__ -> 32:a ;
-36:__UG_NAME__ -> 37:a ;
-44:__UG_NAME__ -> 45:a ;
-48:__UG_NAME__ -> 49:a ;
-56:__UG_NAME__ -> 57:a ;
-40:__UG_NAME__ -> 59:a ;
-23:__UG_NAME__ -> 63:a ;
-72:__UG_NAME__ -> 73:a ;
-76:__UG_NAME__ -> 77:a ;
-22:__UG_NAME__ -> 23:a ;
-26:__UG_NAME__ -> 27:a ;
-30:__UG_NAME__ -> 31:a ;
-35:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:a ;
-43:__UG_NAME__ -> 44:a ;
-47:__UG_NAME__ -> 48:a ;
-41:__UG_NAME__ -> 56:a ;
-24:__UG_NAME__ -> 72:a ;
-75:__UG_NAME__ -> 76:a ;
-50:__UG_NAME__ -> 51:gate ;
-8:__UG_NAME__ -> 51:envelope___control___0 ;
-8:__UG_NAME__ -> 51:envelope___control___4 ;
-9:__UG_NAME__ -> 51:envelope___control___5 ;
-10:__UG_NAME__ -> 51:envelope___control___6 ;
-11:__UG_NAME__ -> 51:envelope___control___7 ;
-60:__UG_NAME__ -> 61:gate ;
-12:__UG_NAME__ -> 61:envelope___control___0 ;
-12:__UG_NAME__ -> 61:envelope___control___4 ;
-13:__UG_NAME__ -> 61:envelope___control___5 ;
-14:__UG_NAME__ -> 61:envelope___control___6 ;
-15:__UG_NAME__ -> 61:envelope___control___7 ;
-64:__UG_NAME__ -> 65:gate ;
-16:__UG_NAME__ -> 65:envelope___control___0 ;
-16:__UG_NAME__ -> 65:envelope___control___4 ;
-17:__UG_NAME__ -> 65:envelope___control___5 ;
-18:__UG_NAME__ -> 65:envelope___control___6 ;
-19:__UG_NAME__ -> 65:envelope___control___7 ;
-33:__UG_NAME__ -> 67:gate ;
-4:__UG_NAME__ -> 67:envelope___control___0 ;
-4:__UG_NAME__ -> 67:envelope___control___4 ;
-5:__UG_NAME__ -> 67:envelope___control___5 ;
-6:__UG_NAME__ -> 67:envelope___control___6 ;
-7:__UG_NAME__ -> 67:envelope___control___7 ;
-78:__UG_NAME__ -> 79:gate ;
-0:__UG_NAME__ -> 79:envelope___control___0 ;
-0:__UG_NAME__ -> 79:envelope___control___4 ;
-1:__UG_NAME__ -> 79:envelope___control___5 ;
-2:__UG_NAME__ -> 79:envelope___control___6 ;
-3:__UG_NAME__ -> 79:envelope___control___7 ;
-17:__UG_NAME__ -> 22:in ;
-0:__UG_NAME__ -> 24:in ;
-4:__UG_NAME__ -> 26:in ;
-5:__UG_NAME__ -> 30:in ;
-16:__UG_NAME__ -> 35:in ;
-13:__UG_NAME__ -> 39:in ;
-12:__UG_NAME__ -> 41:in ;
-8:__UG_NAME__ -> 43:in ;
-9:__UG_NAME__ -> 47:in ;
-1:__UG_NAME__ -> 75:in ;
-20:__UG_NAME__ -> 52:bus ;
-61:__UG_NAME__ -> 62:a ;
-66:__UG_NAME__ -> 70:in ;
-83:__UG_NAME__ -> 84:in ;
-85:__UG_NAME__ -> 86:signals___x____fade2___0 ;
-80:__UG_NAME__ -> 86:signals___x____fade2___1 ;
-21:__UG_NAME__ -> 86:bus ;
-65:__UG_NAME__ -> 66:rq ;
-62:__UG_NAME__ -> 66:freq ;
-54:__UG_NAME__ -> 66:in ;
-65:__UG_NAME__ -> 83:rq ;
-62:__UG_NAME__ -> 83:freq ;
-53:__UG_NAME__ -> 83:in ;
-79:__UG_NAME__ -> 80:level ;
-69:__UG_NAME__ -> 80:pan ;
-70:__UG_NAME__ -> 80:inb ;
-54:__UG_NAME__ -> 80:ina ;
-79:__UG_NAME__ -> 85:level ;
-82:__UG_NAME__ -> 85:pan ;
-84:__UG_NAME__ -> 85:inb ;
-53:__UG_NAME__ -> 85:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_nrlpf.dot b/etc/synthdefs/graphviz/sonic-pi-fx_nrlpf.dot
deleted file mode 100644
index 610fb6b..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_nrlpf.dot
+++ /dev/null
@@ -1,246 +0,0 @@
-digraph synthdef {
-33 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :res
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-76 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-87 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-68 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-73 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-84 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-86 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-32:__UG_NAME__ -> 33:a ;
-46:__UG_NAME__ -> 47:b ;
-45:__UG_NAME__ -> 47:a ;
-46:__UG_NAME__ -> 72:b ;
-45:__UG_NAME__ -> 72:a ;
-32:__UG_NAME__ -> 77:a ;
-24:__UG_NAME__ -> 27:b ;
-26:__UG_NAME__ -> 27:a ;
-30:__UG_NAME__ -> 31:b ;
-27:__UG_NAME__ -> 31:a ;
-39:__UG_NAME__ -> 40:b ;
-36:__UG_NAME__ -> 40:a ;
-43:__UG_NAME__ -> 44:b ;
-40:__UG_NAME__ -> 44:a ;
-50:__UG_NAME__ -> 51:b ;
-25:__UG_NAME__ -> 51:a ;
-54:__UG_NAME__ -> 55:b ;
-51:__UG_NAME__ -> 55:a ;
-61:__UG_NAME__ -> 62:b ;
-34:__UG_NAME__ -> 62:a ;
-65:__UG_NAME__ -> 66:b ;
-62:__UG_NAME__ -> 66:a ;
-80:__UG_NAME__ -> 81:b ;
-35:__UG_NAME__ -> 81:a ;
-71:__UG_NAME__ -> 82:b ;
-81:__UG_NAME__ -> 82:a ;
-77:__UG_NAME__ -> 78:a ;
-33:__UG_NAME__ -> 85:a ;
-23:__UG_NAME__ -> 24:a ;
-29:__UG_NAME__ -> 30:a ;
-38:__UG_NAME__ -> 39:a ;
-42:__UG_NAME__ -> 43:a ;
-49:__UG_NAME__ -> 50:a ;
-53:__UG_NAME__ -> 54:a ;
-60:__UG_NAME__ -> 61:a ;
-64:__UG_NAME__ -> 65:a ;
-70:__UG_NAME__ -> 71:a ;
-79:__UG_NAME__ -> 80:a ;
-22:__UG_NAME__ -> 23:a ;
-28:__UG_NAME__ -> 29:a ;
-37:__UG_NAME__ -> 38:a ;
-41:__UG_NAME__ -> 42:a ;
-48:__UG_NAME__ -> 49:a ;
-52:__UG_NAME__ -> 53:a ;
-59:__UG_NAME__ -> 60:a ;
-63:__UG_NAME__ -> 64:a ;
-69:__UG_NAME__ -> 70:a ;
-75:__UG_NAME__ -> 79:a ;
-31:__UG_NAME__ -> 32:gate ;
-4:__UG_NAME__ -> 32:envelope___control___0 ;
-4:__UG_NAME__ -> 32:envelope___control___4 ;
-5:__UG_NAME__ -> 32:envelope___control___5 ;
-6:__UG_NAME__ -> 32:envelope___control___6 ;
-7:__UG_NAME__ -> 32:envelope___control___7 ;
-44:__UG_NAME__ -> 45:gate ;
-8:__UG_NAME__ -> 45:envelope___control___0 ;
-8:__UG_NAME__ -> 45:envelope___control___4 ;
-9:__UG_NAME__ -> 45:envelope___control___5 ;
-10:__UG_NAME__ -> 45:envelope___control___6 ;
-11:__UG_NAME__ -> 45:envelope___control___7 ;
-55:__UG_NAME__ -> 56:gate ;
-12:__UG_NAME__ -> 56:envelope___control___0 ;
-12:__UG_NAME__ -> 56:envelope___control___4 ;
-13:__UG_NAME__ -> 56:envelope___control___5 ;
-14:__UG_NAME__ -> 56:envelope___control___6 ;
-15:__UG_NAME__ -> 56:envelope___control___7 ;
-66:__UG_NAME__ -> 67:gate ;
-58:__UG_NAME__ -> 67:envelope___mul____add___0 ;
-58:__UG_NAME__ -> 67:envelope___mul____add___4 ;
-17:__UG_NAME__ -> 67:envelope___control___5 ;
-18:__UG_NAME__ -> 67:envelope___control___6 ;
-19:__UG_NAME__ -> 67:envelope___control___7 ;
-82:__UG_NAME__ -> 83:gate ;
-0:__UG_NAME__ -> 83:envelope___control___0 ;
-0:__UG_NAME__ -> 83:envelope___control___4 ;
-1:__UG_NAME__ -> 83:envelope___control___5 ;
-2:__UG_NAME__ -> 83:envelope___control___6 ;
-3:__UG_NAME__ -> 83:envelope___control___7 ;
-4:__UG_NAME__ -> 22:in ;
-5:__UG_NAME__ -> 28:in ;
-8:__UG_NAME__ -> 37:in ;
-9:__UG_NAME__ -> 41:in ;
-12:__UG_NAME__ -> 48:in ;
-13:__UG_NAME__ -> 52:in ;
-58:__UG_NAME__ -> 59:in ;
-17:__UG_NAME__ -> 63:in ;
-1:__UG_NAME__ -> 69:in ;
-0:__UG_NAME__ -> 75:in ;
-20:__UG_NAME__ -> 46:bus ;
-56:__UG_NAME__ -> 57:a ;
-16:__UG_NAME__ -> 58:in ;
-73:__UG_NAME__ -> 74:in ;
-68:__UG_NAME__ -> 76:in ;
-84:__UG_NAME__ -> 87:signals___x____fade2___0 ;
-86:__UG_NAME__ -> 87:signals___x____fade2___1 ;
-21:__UG_NAME__ -> 87:bus ;
-67:__UG_NAME__ -> 68:rq ;
-57:__UG_NAME__ -> 68:freq ;
-47:__UG_NAME__ -> 68:in ;
-67:__UG_NAME__ -> 73:rq ;
-57:__UG_NAME__ -> 73:freq ;
-72:__UG_NAME__ -> 73:in ;
-83:__UG_NAME__ -> 84:level ;
-78:__UG_NAME__ -> 84:pan ;
-76:__UG_NAME__ -> 84:inb ;
-47:__UG_NAME__ -> 84:ina ;
-83:__UG_NAME__ -> 86:level ;
-85:__UG_NAME__ -> 86:pan ;
-74:__UG_NAME__ -> 86:inb ;
-72:__UG_NAME__ -> 86:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_octaver.dot b/etc/synthdefs/graphviz/sonic-pi-fx_octaver.dot
deleted file mode 100644
index fa9cb04..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_octaver.dot
+++ /dev/null
@@ -1,346 +0,0 @@
-digraph synthdef {
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-115 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-116 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-118 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-119 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-98 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-120 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-102 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :oct1_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :oct1_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :oct1_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :oct1_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :oct2_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :oct2_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :oct2_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :oct2_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :oct3_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :oct3_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :oct3_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :oct3_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-45 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-52 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-60 [label = "{{ <in> in|<freq> freq 440.0} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-65 [label = "{{ <in> in|<freq> freq 440.0} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-124 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-61 [label = "{{ <trig> trig} |<__UG_NAME__>toggle-ff }" style="filled, bold, rounded"  shape=record rankdir=LR];
-62 [label = "{{ <trig> trig} |<__UG_NAME__>toggle-ff }" style="filled, bold, rounded"  shape=record rankdir=LR];
-77 [label = "{{ <trig> trig} |<__UG_NAME__>toggle-ff }" style="filled, bold, rounded"  shape=record rankdir=LR];
-81 [label = "{{ <trig> trig} |<__UG_NAME__>toggle-ff }" style="filled, bold, rounded"  shape=record rankdir=LR];
-111 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-123 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-51:__UG_NAME__ -> 59:b ;
-58:__UG_NAME__ -> 59:a ;
-52:__UG_NAME__ -> 63:b ;
-58:__UG_NAME__ -> 63:a ;
-51:__UG_NAME__ -> 64:b ;
-58:__UG_NAME__ -> 64:a ;
-75:__UG_NAME__ -> 76:b ;
-66:__UG_NAME__ -> 76:a ;
-77:__UG_NAME__ -> 78:b ;
-65:__UG_NAME__ -> 78:a ;
-45:__UG_NAME__ -> 79:b ;
-78:__UG_NAME__ -> 79:a ;
-81:__UG_NAME__ -> 82:b ;
-65:__UG_NAME__ -> 82:a ;
-92:__UG_NAME__ -> 93:b ;
-82:__UG_NAME__ -> 93:a ;
-100:__UG_NAME__ -> 101:a ;
-52:__UG_NAME__ -> 112:b ;
-58:__UG_NAME__ -> 112:a ;
-75:__UG_NAME__ -> 114:b ;
-113:__UG_NAME__ -> 114:a ;
-61:__UG_NAME__ -> 115:b ;
-60:__UG_NAME__ -> 115:a ;
-45:__UG_NAME__ -> 116:b ;
-115:__UG_NAME__ -> 116:a ;
-62:__UG_NAME__ -> 118:b ;
-60:__UG_NAME__ -> 118:a ;
-92:__UG_NAME__ -> 119:b ;
-118:__UG_NAME__ -> 119:a ;
-100:__UG_NAME__ -> 121:a ;
-34:__UG_NAME__ -> 35:b ;
-31:__UG_NAME__ -> 35:a ;
-39:__UG_NAME__ -> 40:b ;
-36:__UG_NAME__ -> 40:a ;
-43:__UG_NAME__ -> 44:b ;
-40:__UG_NAME__ -> 44:a ;
-56:__UG_NAME__ -> 57:b ;
-35:__UG_NAME__ -> 57:a ;
-69:__UG_NAME__ -> 70:b ;
-30:__UG_NAME__ -> 70:a ;
-73:__UG_NAME__ -> 74:b ;
-70:__UG_NAME__ -> 74:a ;
-79:__UG_NAME__ -> 80:b ;
-76:__UG_NAME__ -> 80:a ;
-86:__UG_NAME__ -> 87:b ;
-83:__UG_NAME__ -> 87:a ;
-90:__UG_NAME__ -> 91:b ;
-87:__UG_NAME__ -> 91:a ;
-93:__UG_NAME__ -> 94:b ;
-80:__UG_NAME__ -> 94:a ;
-97:__UG_NAME__ -> 98:b ;
-47:__UG_NAME__ -> 98:a ;
-50:__UG_NAME__ -> 99:b ;
-98:__UG_NAME__ -> 99:a ;
-104:__UG_NAME__ -> 105:b ;
-53:__UG_NAME__ -> 105:a ;
-108:__UG_NAME__ -> 109:b ;
-105:__UG_NAME__ -> 109:a ;
-116:__UG_NAME__ -> 117:b ;
-114:__UG_NAME__ -> 117:a ;
-119:__UG_NAME__ -> 120:b ;
-117:__UG_NAME__ -> 120:a ;
-101:__UG_NAME__ -> 102:a ;
-121:__UG_NAME__ -> 122:a ;
-33:__UG_NAME__ -> 34:a ;
-38:__UG_NAME__ -> 39:a ;
-42:__UG_NAME__ -> 43:a ;
-49:__UG_NAME__ -> 50:a ;
-55:__UG_NAME__ -> 56:a ;
-68:__UG_NAME__ -> 69:a ;
-72:__UG_NAME__ -> 73:a ;
-85:__UG_NAME__ -> 86:a ;
-89:__UG_NAME__ -> 90:a ;
-96:__UG_NAME__ -> 97:a ;
-103:__UG_NAME__ -> 104:a ;
-107:__UG_NAME__ -> 108:a ;
-32:__UG_NAME__ -> 33:a ;
-37:__UG_NAME__ -> 38:a ;
-41:__UG_NAME__ -> 42:a ;
-48:__UG_NAME__ -> 49:a ;
-54:__UG_NAME__ -> 55:a ;
-65:__UG_NAME__ -> 66:a ;
-67:__UG_NAME__ -> 68:a ;
-71:__UG_NAME__ -> 72:a ;
-84:__UG_NAME__ -> 85:a ;
-88:__UG_NAME__ -> 89:a ;
-95:__UG_NAME__ -> 96:a ;
-46:__UG_NAME__ -> 103:a ;
-106:__UG_NAME__ -> 107:a ;
-60:__UG_NAME__ -> 113:a ;
-44:__UG_NAME__ -> 45:gate ;
-20:__UG_NAME__ -> 45:envelope___control___0 ;
-20:__UG_NAME__ -> 45:envelope___control___4 ;
-21:__UG_NAME__ -> 45:envelope___control___5 ;
-22:__UG_NAME__ -> 45:envelope___control___6 ;
-23:__UG_NAME__ -> 45:envelope___control___7 ;
-57:__UG_NAME__ -> 58:gate ;
-8:__UG_NAME__ -> 58:envelope___control___0 ;
-8:__UG_NAME__ -> 58:envelope___control___4 ;
-9:__UG_NAME__ -> 58:envelope___control___5 ;
-10:__UG_NAME__ -> 58:envelope___control___6 ;
-11:__UG_NAME__ -> 58:envelope___control___7 ;
-74:__UG_NAME__ -> 75:gate ;
-16:__UG_NAME__ -> 75:envelope___control___0 ;
-16:__UG_NAME__ -> 75:envelope___control___4 ;
-17:__UG_NAME__ -> 75:envelope___control___5 ;
-18:__UG_NAME__ -> 75:envelope___control___6 ;
-19:__UG_NAME__ -> 75:envelope___control___7 ;
-91:__UG_NAME__ -> 92:gate ;
-24:__UG_NAME__ -> 92:envelope___control___0 ;
-24:__UG_NAME__ -> 92:envelope___control___4 ;
-25:__UG_NAME__ -> 92:envelope___control___5 ;
-26:__UG_NAME__ -> 92:envelope___control___6 ;
-27:__UG_NAME__ -> 92:envelope___control___7 ;
-99:__UG_NAME__ -> 100:gate ;
-4:__UG_NAME__ -> 100:envelope___control___0 ;
-4:__UG_NAME__ -> 100:envelope___control___4 ;
-5:__UG_NAME__ -> 100:envelope___control___5 ;
-6:__UG_NAME__ -> 100:envelope___control___6 ;
-7:__UG_NAME__ -> 100:envelope___control___7 ;
-109:__UG_NAME__ -> 110:gate ;
-0:__UG_NAME__ -> 110:envelope___control___0 ;
-0:__UG_NAME__ -> 110:envelope___control___4 ;
-1:__UG_NAME__ -> 110:envelope___control___5 ;
-2:__UG_NAME__ -> 110:envelope___control___6 ;
-3:__UG_NAME__ -> 110:envelope___control___7 ;
-8:__UG_NAME__ -> 32:in ;
-20:__UG_NAME__ -> 37:in ;
-21:__UG_NAME__ -> 41:in ;
-0:__UG_NAME__ -> 46:in ;
-5:__UG_NAME__ -> 48:in ;
-9:__UG_NAME__ -> 54:in ;
-16:__UG_NAME__ -> 67:in ;
-17:__UG_NAME__ -> 71:in ;
-24:__UG_NAME__ -> 84:in ;
-25:__UG_NAME__ -> 88:in ;
-4:__UG_NAME__ -> 95:in ;
-1:__UG_NAME__ -> 106:in ;
-28:__UG_NAME__ -> 51:bus ;
-28:__UG_NAME__ -> 52:bus ;
-59:__UG_NAME__ -> 60:in ;
-64:__UG_NAME__ -> 65:in ;
-123:__UG_NAME__ -> 124:signals___x____fade2___0 ;
-111:__UG_NAME__ -> 124:signals___x____fade2___1 ;
-29:__UG_NAME__ -> 124:bus ;
-60:__UG_NAME__ -> 61:trig ;
-61:__UG_NAME__ -> 62:trig ;
-65:__UG_NAME__ -> 77:trig ;
-77:__UG_NAME__ -> 81:trig ;
-110:__UG_NAME__ -> 111:level ;
-102:__UG_NAME__ -> 111:pan ;
-94:__UG_NAME__ -> 111:inb ;
-63:__UG_NAME__ -> 111:ina ;
-110:__UG_NAME__ -> 123:level ;
-122:__UG_NAME__ -> 123:pan ;
-120:__UG_NAME__ -> 123:inb ;
-112:__UG_NAME__ -> 123:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_pan.dot b/etc/synthdefs/graphviz/sonic-pi-fx_pan.dot
deleted file mode 100644
index 0d09e5d..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_pan.dot
+++ /dev/null
@@ -1,197 +0,0 @@
-digraph synthdef {
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-21 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-20 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <left> left|<right> right|<pos> pos|<level> level} |<__UG_NAME__>balance2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-43 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-19 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-18 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-68 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-64 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-67 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-44:__UG_NAME__ -> 45:b ;
-43:__UG_NAME__ -> 45:a ;
-44:__UG_NAME__ -> 46:b ;
-43:__UG_NAME__ -> 46:a ;
-61:__UG_NAME__ -> 62:a ;
-61:__UG_NAME__ -> 65:a ;
-21:__UG_NAME__ -> 22:b ;
-18:__UG_NAME__ -> 22:a ;
-25:__UG_NAME__ -> 26:b ;
-22:__UG_NAME__ -> 26:a ;
-33:__UG_NAME__ -> 34:b ;
-30:__UG_NAME__ -> 34:a ;
-37:__UG_NAME__ -> 38:b ;
-34:__UG_NAME__ -> 38:a ;
-42:__UG_NAME__ -> 49:b ;
-48:__UG_NAME__ -> 49:a ;
-52:__UG_NAME__ -> 53:b ;
-49:__UG_NAME__ -> 53:a ;
-58:__UG_NAME__ -> 59:b ;
-39:__UG_NAME__ -> 59:a ;
-29:__UG_NAME__ -> 60:b ;
-59:__UG_NAME__ -> 60:a ;
-62:__UG_NAME__ -> 63:a ;
-65:__UG_NAME__ -> 66:a ;
-20:__UG_NAME__ -> 21:a ;
-24:__UG_NAME__ -> 25:a ;
-28:__UG_NAME__ -> 29:a ;
-32:__UG_NAME__ -> 33:a ;
-36:__UG_NAME__ -> 37:a ;
-41:__UG_NAME__ -> 42:a ;
-51:__UG_NAME__ -> 52:a ;
-57:__UG_NAME__ -> 58:a ;
-19:__UG_NAME__ -> 20:a ;
-23:__UG_NAME__ -> 24:a ;
-27:__UG_NAME__ -> 28:a ;
-31:__UG_NAME__ -> 32:a ;
-35:__UG_NAME__ -> 36:a ;
-40:__UG_NAME__ -> 41:a ;
-50:__UG_NAME__ -> 51:a ;
-56:__UG_NAME__ -> 57:a ;
-54:__UG_NAME__ -> 55:level ;
-47:__UG_NAME__ -> 55:pos ;
-46:__UG_NAME__ -> 55:right ;
-45:__UG_NAME__ -> 55:left ;
-38:__UG_NAME__ -> 43:gate ;
-8:__UG_NAME__ -> 43:envelope___control___0 ;
-8:__UG_NAME__ -> 43:envelope___control___4 ;
-9:__UG_NAME__ -> 43:envelope___control___5 ;
-10:__UG_NAME__ -> 43:envelope___control___6 ;
-11:__UG_NAME__ -> 43:envelope___control___7 ;
-26:__UG_NAME__ -> 47:gate ;
-12:__UG_NAME__ -> 47:envelope___control___0 ;
-12:__UG_NAME__ -> 47:envelope___control___4 ;
-13:__UG_NAME__ -> 47:envelope___control___5 ;
-14:__UG_NAME__ -> 47:envelope___control___6 ;
-15:__UG_NAME__ -> 47:envelope___control___7 ;
-53:__UG_NAME__ -> 54:gate ;
-0:__UG_NAME__ -> 54:envelope___control___0 ;
-0:__UG_NAME__ -> 54:envelope___control___4 ;
-1:__UG_NAME__ -> 54:envelope___control___5 ;
-2:__UG_NAME__ -> 54:envelope___control___6 ;
-3:__UG_NAME__ -> 54:envelope___control___7 ;
-60:__UG_NAME__ -> 61:gate ;
-4:__UG_NAME__ -> 61:envelope___control___0 ;
-4:__UG_NAME__ -> 61:envelope___control___4 ;
-5:__UG_NAME__ -> 61:envelope___control___5 ;
-6:__UG_NAME__ -> 61:envelope___control___6 ;
-7:__UG_NAME__ -> 61:envelope___control___7 ;
-12:__UG_NAME__ -> 19:in ;
-13:__UG_NAME__ -> 23:in ;
-5:__UG_NAME__ -> 27:in ;
-8:__UG_NAME__ -> 31:in ;
-9:__UG_NAME__ -> 35:in ;
-0:__UG_NAME__ -> 40:in ;
-1:__UG_NAME__ -> 50:in ;
-4:__UG_NAME__ -> 56:in ;
-16:__UG_NAME__ -> 44:bus ;
-64:__UG_NAME__ -> 68:signals___x____fade2___0 ;
-67:__UG_NAME__ -> 68:signals___x____fade2___1 ;
-17:__UG_NAME__ -> 68:bus ;
-54:__UG_NAME__ -> 64:level ;
-63:__UG_NAME__ -> 64:pan ;
-55:__UG_NAME__ -> 64:inb ;
-45:__UG_NAME__ -> 64:ina ;
-54:__UG_NAME__ -> 67:level ;
-66:__UG_NAME__ -> 67:pan ;
-55:__UG_NAME__ -> 67:inb ;
-46:__UG_NAME__ -> 67:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_panslicer.dot b/etc/synthdefs/graphviz/sonic-pi-fx_panslicer.dot
deleted file mode 100644
index 2717d2e..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_panslicer.dot
+++ /dev/null
@@ -1,618 +0,0 @@
-digraph synthdef {
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-84 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <a> |<b> 6.2831855} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-165 [label = "{{ <a> |<b> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-218 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-220 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-133 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-137 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-145 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-149 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-156 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-160 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-172 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-176 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-181 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-185 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-192 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-196 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-201 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-205 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-212 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-216 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-163 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-166 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-219 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-221 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-164 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-126 [label = "{{ <a> |<b> } |<__UG_NAME__>\< }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-132 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-136 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-148 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-155 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-159 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-171 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-175 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-180 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-184 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-191 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-195 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-200 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-204 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-211 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-215 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-131 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-135 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-143 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-147 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-154 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-158 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-170 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-174 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-179 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-183 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-190 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-194 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-203 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-210 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-214 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-207 [label = "{{ <left> left|<right> right|<pos> pos|<level> level} |<__UG_NAME__>balance2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-125 [label = "{{ <num____channels> num-channels 1|<bufnum> bufnum|<phase> phase|<loop> loop 1.0|<interpolation> interpolation 2.0} |<__UG_NAME__>buf-rd }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <in> in|<lo> lo 0.0|<hi> hi 1.0} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <in> in|<lo> lo 0.0|<hi> hi 1.0} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
-151 [label = "{{ <in> in|<lo> lo -1.0|<hi> hi 1.0} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
-162 [label = "{{ <in> in|<lo> lo -1.0|<hi> hi 1.0} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :phase
- default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :phase_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :phase_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :phase_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :pan_min
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :pan_min_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :pan_min_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :pan_min_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :pan_max
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :pan_max_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :pan_max_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :pan_max_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :smooth
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :smooth_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :smooth_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :smooth_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :smooth_up
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :smooth_up_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :smooth_up_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :smooth_up_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :smooth_down
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "control
- :smooth_down_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "control
- :smooth_down_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "control
- :smooth_down_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-40 [label = "control
- :probability
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-41 [label = "control
- :probability_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "control
- :probability_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-43 [label = "control
- :probability_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-44 [label = "control
- :prob_pos
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-45 [label = "control
- :prob_pos_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-46 [label = "control
- :prob_pos_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-47 [label = "control
- :prob_pos_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-48 [label = "control
- :phase_offset
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-49 [label = "control
- :wave
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-50 [label = "control
- :invert_wave
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-51 [label = "control
- :seed
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-52 [label = "control
- :rand_buf
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-53 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-54 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-67 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ {{<envelope___clip___0>|1.0|-99|-99|<envelope___clip___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-138 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-150 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-161 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-177 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-186 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-197 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-206 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-217 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-130 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-134 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-146 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-153 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-157 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-169 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-173 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-182 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-189 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-193 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-202 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-209 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-213 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <freq> freq|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-152 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-168 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-178 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-188 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-199 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-208 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-198 [label = "{{ <in> in|<lag____time> lag-time} |<__UG_NAME__>lag }" style="bold, rounded" shape=record rankdir=LR];
-187 [label = "{{ <in> in|<lag____time____up> lag-time-up|<lag____time____down> lag-time-down} |<__UG_NAME__>lag-ud }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <freq> freq|<iphase> iphase|<width> width} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ <in> in|<mul> mul 2.0|<add> add -1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-167 [label = "{{ <in> in|<mul> mul|<add> add} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-224 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-123 [label = "{{ <trig> trig|<reset> reset 0.0} |<__UG_NAME__>pulse-count }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-139 [label = "{{ <which> which|{{<array___env____gen___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ <freq> freq|<phase> phase|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-222 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-223 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-68:__UG_NAME__ -> 69:b ;
-67:__UG_NAME__ -> 69:a ;
-68:__UG_NAME__ -> 70:b ;
-67:__UG_NAME__ -> 70:a ;
-83:__UG_NAME__ -> 84:b ;
-85:__UG_NAME__ -> 86:b ;
-48:__UG_NAME__ -> 98:b ;
-100:__UG_NAME__ -> 101:b ;
-112:__UG_NAME__ -> 113:b ;
-117:__UG_NAME__ -> 118:a ;
-120:__UG_NAME__ -> 121:b ;
-86:__UG_NAME__ -> 121:a ;
-164:__UG_NAME__ -> 165:a ;
-217:__UG_NAME__ -> 218:a ;
-217:__UG_NAME__ -> 220:a ;
-61:__UG_NAME__ -> 62:b ;
-58:__UG_NAME__ -> 62:a ;
-65:__UG_NAME__ -> 66:b ;
-62:__UG_NAME__ -> 66:a ;
-75:__UG_NAME__ -> 76:b ;
-71:__UG_NAME__ -> 76:a ;
-79:__UG_NAME__ -> 80:b ;
-76:__UG_NAME__ -> 80:a ;
-90:__UG_NAME__ -> 91:b ;
-87:__UG_NAME__ -> 91:a ;
-94:__UG_NAME__ -> 95:b ;
-91:__UG_NAME__ -> 95:a ;
-98:__UG_NAME__ -> 99:a ;
-105:__UG_NAME__ -> 106:b ;
-102:__UG_NAME__ -> 106:a ;
-109:__UG_NAME__ -> 110:b ;
-106:__UG_NAME__ -> 110:a ;
-98:__UG_NAME__ -> 115:a ;
-48:__UG_NAME__ -> 117:a ;
-123:__UG_NAME__ -> 124:b ;
-51:__UG_NAME__ -> 124:a ;
-132:__UG_NAME__ -> 133:b ;
-127:__UG_NAME__ -> 133:a ;
-136:__UG_NAME__ -> 137:b ;
-133:__UG_NAME__ -> 137:a ;
-144:__UG_NAME__ -> 145:b ;
-141:__UG_NAME__ -> 145:a ;
-148:__UG_NAME__ -> 149:b ;
-145:__UG_NAME__ -> 149:a ;
-155:__UG_NAME__ -> 156:b ;
-152:__UG_NAME__ -> 156:a ;
-159:__UG_NAME__ -> 160:b ;
-156:__UG_NAME__ -> 160:a ;
-171:__UG_NAME__ -> 172:b ;
-168:__UG_NAME__ -> 172:a ;
-175:__UG_NAME__ -> 176:b ;
-172:__UG_NAME__ -> 176:a ;
-180:__UG_NAME__ -> 181:b ;
-178:__UG_NAME__ -> 181:a ;
-184:__UG_NAME__ -> 185:b ;
-181:__UG_NAME__ -> 185:a ;
-191:__UG_NAME__ -> 192:b ;
-188:__UG_NAME__ -> 192:a ;
-195:__UG_NAME__ -> 196:b ;
-192:__UG_NAME__ -> 196:a ;
-200:__UG_NAME__ -> 201:b ;
-199:__UG_NAME__ -> 201:a ;
-204:__UG_NAME__ -> 205:b ;
-201:__UG_NAME__ -> 205:a ;
-211:__UG_NAME__ -> 212:b ;
-208:__UG_NAME__ -> 212:a ;
-215:__UG_NAME__ -> 216:b ;
-212:__UG_NAME__ -> 216:a ;
-84:__UG_NAME__ -> 85:a ;
-113:__UG_NAME__ -> 114:a ;
-162:__UG_NAME__ -> 163:b ;
-151:__UG_NAME__ -> 163:a ;
-165:__UG_NAME__ -> 166:b ;
-162:__UG_NAME__ -> 166:a ;
-218:__UG_NAME__ -> 219:a ;
-220:__UG_NAME__ -> 221:a ;
-96:__UG_NAME__ -> 97:b ;
-163:__UG_NAME__ -> 164:a ;
-81:__UG_NAME__ -> 126:b ;
-125:__UG_NAME__ -> 126:a ;
-60:__UG_NAME__ -> 61:a ;
-64:__UG_NAME__ -> 65:a ;
-74:__UG_NAME__ -> 75:a ;
-78:__UG_NAME__ -> 79:a ;
-81:__UG_NAME__ -> 82:a ;
-50:__UG_NAME__ -> 83:a ;
-89:__UG_NAME__ -> 90:a ;
-93:__UG_NAME__ -> 94:a ;
-104:__UG_NAME__ -> 105:a ;
-108:__UG_NAME__ -> 109:a ;
-131:__UG_NAME__ -> 132:a ;
-135:__UG_NAME__ -> 136:a ;
-143:__UG_NAME__ -> 144:a ;
-147:__UG_NAME__ -> 148:a ;
-154:__UG_NAME__ -> 155:a ;
-158:__UG_NAME__ -> 159:a ;
-170:__UG_NAME__ -> 171:a ;
-174:__UG_NAME__ -> 175:a ;
-179:__UG_NAME__ -> 180:a ;
-183:__UG_NAME__ -> 184:a ;
-190:__UG_NAME__ -> 191:a ;
-194:__UG_NAME__ -> 195:a ;
-56:__UG_NAME__ -> 200:a ;
-203:__UG_NAME__ -> 204:a ;
-210:__UG_NAME__ -> 211:a ;
-214:__UG_NAME__ -> 215:a ;
-55:__UG_NAME__ -> 56:a ;
-59:__UG_NAME__ -> 60:a ;
-63:__UG_NAME__ -> 64:a ;
-73:__UG_NAME__ -> 74:a ;
-77:__UG_NAME__ -> 78:a ;
-88:__UG_NAME__ -> 89:a ;
-92:__UG_NAME__ -> 93:a ;
-103:__UG_NAME__ -> 104:a ;
-107:__UG_NAME__ -> 108:a ;
-130:__UG_NAME__ -> 131:a ;
-134:__UG_NAME__ -> 135:a ;
-142:__UG_NAME__ -> 143:a ;
-146:__UG_NAME__ -> 147:a ;
-153:__UG_NAME__ -> 154:a ;
-157:__UG_NAME__ -> 158:a ;
-169:__UG_NAME__ -> 170:a ;
-173:__UG_NAME__ -> 174:a ;
-57:__UG_NAME__ -> 179:a ;
-182:__UG_NAME__ -> 183:a ;
-189:__UG_NAME__ -> 190:a ;
-193:__UG_NAME__ -> 194:a ;
-202:__UG_NAME__ -> 203:a ;
-209:__UG_NAME__ -> 210:a ;
-213:__UG_NAME__ -> 214:a ;
-206:__UG_NAME__ -> 207:level ;
-198:__UG_NAME__ -> 207:pos ;
-70:__UG_NAME__ -> 207:right ;
-69:__UG_NAME__ -> 207:left ;
-124:__UG_NAME__ -> 125:phase ;
-52:__UG_NAME__ -> 125:bufnum ;
-40:__UG_NAME__ -> 72:in ;
-44:__UG_NAME__ -> 128:in ;
-150:__UG_NAME__ -> 151:in ;
-161:__UG_NAME__ -> 162:in ;
-66:__UG_NAME__ -> 67:gate ;
-8:__UG_NAME__ -> 67:envelope___control___0 ;
-8:__UG_NAME__ -> 67:envelope___control___4 ;
-9:__UG_NAME__ -> 67:envelope___control___5 ;
-10:__UG_NAME__ -> 67:envelope___control___6 ;
-11:__UG_NAME__ -> 67:envelope___control___7 ;
-80:__UG_NAME__ -> 81:gate ;
-72:__UG_NAME__ -> 81:envelope___clip___0 ;
-72:__UG_NAME__ -> 81:envelope___clip___4 ;
-41:__UG_NAME__ -> 81:envelope___control___5 ;
-42:__UG_NAME__ -> 81:envelope___control___6 ;
-43:__UG_NAME__ -> 81:envelope___control___7 ;
-95:__UG_NAME__ -> 96:gate ;
-12:__UG_NAME__ -> 96:envelope___control___0 ;
-12:__UG_NAME__ -> 96:envelope___control___4 ;
-13:__UG_NAME__ -> 96:envelope___control___5 ;
-14:__UG_NAME__ -> 96:envelope___control___6 ;
-15:__UG_NAME__ -> 96:envelope___control___7 ;
-110:__UG_NAME__ -> 111:gate ;
-24:__UG_NAME__ -> 111:envelope___control___0 ;
-24:__UG_NAME__ -> 111:envelope___control___4 ;
-25:__UG_NAME__ -> 111:envelope___control___5 ;
-26:__UG_NAME__ -> 111:envelope___control___6 ;
-27:__UG_NAME__ -> 111:envelope___control___7 ;
-137:__UG_NAME__ -> 138:gate ;
-129:__UG_NAME__ -> 138:envelope___mul____add___0 ;
-129:__UG_NAME__ -> 138:envelope___mul____add___4 ;
-45:__UG_NAME__ -> 138:envelope___control___5 ;
-46:__UG_NAME__ -> 138:envelope___control___6 ;
-47:__UG_NAME__ -> 138:envelope___control___7 ;
-149:__UG_NAME__ -> 150:gate ;
-20:__UG_NAME__ -> 150:envelope___control___0 ;
-20:__UG_NAME__ -> 150:envelope___control___4 ;
-21:__UG_NAME__ -> 150:envelope___control___5 ;
-22:__UG_NAME__ -> 150:envelope___control___6 ;
-23:__UG_NAME__ -> 150:envelope___control___7 ;
-160:__UG_NAME__ -> 161:gate ;
-16:__UG_NAME__ -> 161:envelope___control___0 ;
-16:__UG_NAME__ -> 161:envelope___control___4 ;
-17:__UG_NAME__ -> 161:envelope___control___5 ;
-18:__UG_NAME__ -> 161:envelope___control___6 ;
-19:__UG_NAME__ -> 161:envelope___control___7 ;
-176:__UG_NAME__ -> 177:gate ;
-32:__UG_NAME__ -> 177:envelope___control___0 ;
-32:__UG_NAME__ -> 177:envelope___control___4 ;
-33:__UG_NAME__ -> 177:envelope___control___5 ;
-34:__UG_NAME__ -> 177:envelope___control___6 ;
-35:__UG_NAME__ -> 177:envelope___control___7 ;
-185:__UG_NAME__ -> 186:gate ;
-36:__UG_NAME__ -> 186:envelope___control___0 ;
-36:__UG_NAME__ -> 186:envelope___control___4 ;
-37:__UG_NAME__ -> 186:envelope___control___5 ;
-38:__UG_NAME__ -> 186:envelope___control___6 ;
-39:__UG_NAME__ -> 186:envelope___control___7 ;
-196:__UG_NAME__ -> 197:gate ;
-28:__UG_NAME__ -> 197:envelope___control___0 ;
-28:__UG_NAME__ -> 197:envelope___control___4 ;
-29:__UG_NAME__ -> 197:envelope___control___5 ;
-30:__UG_NAME__ -> 197:envelope___control___6 ;
-31:__UG_NAME__ -> 197:envelope___control___7 ;
-205:__UG_NAME__ -> 206:gate ;
-0:__UG_NAME__ -> 206:envelope___control___0 ;
-0:__UG_NAME__ -> 206:envelope___control___4 ;
-1:__UG_NAME__ -> 206:envelope___control___5 ;
-2:__UG_NAME__ -> 206:envelope___control___6 ;
-3:__UG_NAME__ -> 206:envelope___control___7 ;
-216:__UG_NAME__ -> 217:gate ;
-4:__UG_NAME__ -> 217:envelope___control___0 ;
-4:__UG_NAME__ -> 217:envelope___control___4 ;
-5:__UG_NAME__ -> 217:envelope___control___5 ;
-6:__UG_NAME__ -> 217:envelope___control___6 ;
-7:__UG_NAME__ -> 217:envelope___control___7 ;
-0:__UG_NAME__ -> 55:in ;
-36:__UG_NAME__ -> 57:in ;
-8:__UG_NAME__ -> 59:in ;
-9:__UG_NAME__ -> 63:in ;
-72:__UG_NAME__ -> 73:in ;
-41:__UG_NAME__ -> 77:in ;
-12:__UG_NAME__ -> 88:in ;
-13:__UG_NAME__ -> 92:in ;
-24:__UG_NAME__ -> 103:in ;
-25:__UG_NAME__ -> 107:in ;
-129:__UG_NAME__ -> 130:in ;
-45:__UG_NAME__ -> 134:in ;
-20:__UG_NAME__ -> 142:in ;
-21:__UG_NAME__ -> 146:in ;
-16:__UG_NAME__ -> 153:in ;
-17:__UG_NAME__ -> 157:in ;
-32:__UG_NAME__ -> 169:in ;
-33:__UG_NAME__ -> 173:in ;
-37:__UG_NAME__ -> 182:in ;
-28:__UG_NAME__ -> 189:in ;
-29:__UG_NAME__ -> 193:in ;
-1:__UG_NAME__ -> 202:in ;
-4:__UG_NAME__ -> 209:in ;
-5:__UG_NAME__ -> 213:in ;
-97:__UG_NAME__ -> 122:freq ;
-53:__UG_NAME__ -> 68:bus ;
-197:__UG_NAME__ -> 198:lag____time ;
-187:__UG_NAME__ -> 198:in ;
-186:__UG_NAME__ -> 187:lag____time____down ;
-177:__UG_NAME__ -> 187:lag____time____up ;
-167:__UG_NAME__ -> 187:in ;
-111:__UG_NAME__ -> 112:width ;
-48:__UG_NAME__ -> 112:iphase ;
-97:__UG_NAME__ -> 112:freq ;
-99:__UG_NAME__ -> 100:iphase ;
-97:__UG_NAME__ -> 100:freq ;
-115:__UG_NAME__ -> 116:iphase ;
-97:__UG_NAME__ -> 116:freq ;
-128:__UG_NAME__ -> 129:in ;
-166:__UG_NAME__ -> 167:add ;
-164:__UG_NAME__ -> 167:mul ;
-140:__UG_NAME__ -> 167:in ;
-222:__UG_NAME__ -> 224:signals___x____fade2___0 ;
-223:__UG_NAME__ -> 224:signals___x____fade2___1 ;
-54:__UG_NAME__ -> 224:bus ;
-122:__UG_NAME__ -> 123:trig ;
-101:__UG_NAME__ -> 120:array___binary____op____u____gen___0 ;
-114:__UG_NAME__ -> 120:array___binary____op____u____gen___1 ;
-116:__UG_NAME__ -> 120:array___lf____tri___2 ;
-119:__UG_NAME__ -> 120:array___sin____osc___3 ;
-49:__UG_NAME__ -> 120:which ;
-138:__UG_NAME__ -> 139:array___env____gen___0 ;
-121:__UG_NAME__ -> 139:array___binary____op____u____gen___1 ;
-126:__UG_NAME__ -> 139:which ;
-121:__UG_NAME__ -> 140:array___binary____op____u____gen___0 ;
-139:__UG_NAME__ -> 140:array___select___1 ;
-82:__UG_NAME__ -> 140:which ;
-118:__UG_NAME__ -> 119:phase ;
-97:__UG_NAME__ -> 119:freq ;
-206:__UG_NAME__ -> 222:level ;
-221:__UG_NAME__ -> 222:pan ;
-207:__UG_NAME__ -> 222:inb ;
-69:__UG_NAME__ -> 222:ina ;
-206:__UG_NAME__ -> 223:level ;
-219:__UG_NAME__ -> 223:pan ;
-207:__UG_NAME__ -> 223:inb ;
-70:__UG_NAME__ -> 223:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_pitch_shift.dot b/etc/synthdefs/graphviz/sonic-pi-fx_pitch_shift.dot
deleted file mode 100644
index 10a87ce..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_pitch_shift.dot
+++ /dev/null
@@ -1,320 +0,0 @@
-digraph synthdef {
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :pitch
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :pitch_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :pitch_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :pitch_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :window_size
- default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :window_size_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :window_size_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :window_size_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :pitch_dis
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :pitch_dis_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :pitch_dis_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :pitch_dis_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :time_dis
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :time_dis_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :time_dis_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :time_dis_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> } |<__UG_NAME__>midiratio }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-101 [label = "{{ <in> in|<window____size> window-size|<pitch____ratio> pitch-ratio|<pitch____dispersion> pitch-dispersion|<time____dispersion> time-dispersion} |<__UG_NAME__>pitch-shift }" style="filled, bold, rounded"  shape=record rankdir=LR];
-110 [label = "{{ <in> in|<window____size> window-size|<pitch____ratio> pitch-ratio|<pitch____dispersion> pitch-dispersion|<time____dispersion> time-dispersion} |<__UG_NAME__>pitch-shift }" style="filled, bold, rounded"  shape=record rankdir=LR];
-108 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-111 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-43:__UG_NAME__ -> 44:b ;
-42:__UG_NAME__ -> 44:a ;
-54:__UG_NAME__ -> 55:a ;
-54:__UG_NAME__ -> 77:a ;
-43:__UG_NAME__ -> 109:b ;
-42:__UG_NAME__ -> 109:a ;
-36:__UG_NAME__ -> 37:b ;
-33:__UG_NAME__ -> 37:a ;
-40:__UG_NAME__ -> 41:b ;
-37:__UG_NAME__ -> 41:a ;
-48:__UG_NAME__ -> 49:b ;
-45:__UG_NAME__ -> 49:a ;
-52:__UG_NAME__ -> 53:b ;
-49:__UG_NAME__ -> 53:a ;
-65:__UG_NAME__ -> 66:b ;
-62:__UG_NAME__ -> 66:a ;
-59:__UG_NAME__ -> 67:b ;
-66:__UG_NAME__ -> 67:a ;
-74:__UG_NAME__ -> 75:b ;
-71:__UG_NAME__ -> 75:a ;
-85:__UG_NAME__ -> 86:b ;
-82:__UG_NAME__ -> 86:a ;
-69:__UG_NAME__ -> 87:b ;
-76:__UG_NAME__ -> 87:a ;
-90:__UG_NAME__ -> 91:b ;
-87:__UG_NAME__ -> 91:a ;
-96:__UG_NAME__ -> 97:b ;
-86:__UG_NAME__ -> 97:a ;
-32:__UG_NAME__ -> 99:b ;
-75:__UG_NAME__ -> 99:a ;
-81:__UG_NAME__ -> 102:b ;
-70:__UG_NAME__ -> 102:a ;
-105:__UG_NAME__ -> 106:b ;
-102:__UG_NAME__ -> 106:a ;
-55:__UG_NAME__ -> 56:a ;
-77:__UG_NAME__ -> 78:a ;
-31:__UG_NAME__ -> 32:a ;
-35:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:a ;
-47:__UG_NAME__ -> 48:a ;
-51:__UG_NAME__ -> 52:a ;
-58:__UG_NAME__ -> 59:a ;
-64:__UG_NAME__ -> 65:a ;
-61:__UG_NAME__ -> 69:a ;
-73:__UG_NAME__ -> 74:a ;
-80:__UG_NAME__ -> 81:a ;
-84:__UG_NAME__ -> 85:a ;
-89:__UG_NAME__ -> 90:a ;
-95:__UG_NAME__ -> 96:a ;
-104:__UG_NAME__ -> 105:a ;
-30:__UG_NAME__ -> 31:a ;
-34:__UG_NAME__ -> 35:a ;
-38:__UG_NAME__ -> 39:a ;
-46:__UG_NAME__ -> 47:a ;
-50:__UG_NAME__ -> 51:a ;
-57:__UG_NAME__ -> 58:a ;
-60:__UG_NAME__ -> 61:a ;
-63:__UG_NAME__ -> 64:a ;
-72:__UG_NAME__ -> 73:a ;
-79:__UG_NAME__ -> 80:a ;
-83:__UG_NAME__ -> 84:a ;
-88:__UG_NAME__ -> 89:a ;
-94:__UG_NAME__ -> 95:a ;
-103:__UG_NAME__ -> 104:a ;
-41:__UG_NAME__ -> 42:gate ;
-8:__UG_NAME__ -> 42:envelope___control___0 ;
-8:__UG_NAME__ -> 42:envelope___control___4 ;
-9:__UG_NAME__ -> 42:envelope___control___5 ;
-10:__UG_NAME__ -> 42:envelope___control___6 ;
-11:__UG_NAME__ -> 42:envelope___control___7 ;
-53:__UG_NAME__ -> 54:gate ;
-4:__UG_NAME__ -> 54:envelope___control___0 ;
-4:__UG_NAME__ -> 54:envelope___control___4 ;
-5:__UG_NAME__ -> 54:envelope___control___5 ;
-6:__UG_NAME__ -> 54:envelope___control___6 ;
-7:__UG_NAME__ -> 54:envelope___control___7 ;
-67:__UG_NAME__ -> 68:gate ;
-16:__UG_NAME__ -> 68:envelope___control___0 ;
-16:__UG_NAME__ -> 68:envelope___control___4 ;
-17:__UG_NAME__ -> 68:envelope___control___5 ;
-18:__UG_NAME__ -> 68:envelope___control___6 ;
-19:__UG_NAME__ -> 68:envelope___control___7 ;
-91:__UG_NAME__ -> 92:gate ;
-12:__UG_NAME__ -> 92:envelope___control___0 ;
-12:__UG_NAME__ -> 92:envelope___control___4 ;
-13:__UG_NAME__ -> 92:envelope___control___5 ;
-14:__UG_NAME__ -> 92:envelope___control___6 ;
-15:__UG_NAME__ -> 92:envelope___control___7 ;
-97:__UG_NAME__ -> 98:gate ;
-20:__UG_NAME__ -> 98:envelope___control___0 ;
-20:__UG_NAME__ -> 98:envelope___control___4 ;
-21:__UG_NAME__ -> 98:envelope___control___5 ;
-22:__UG_NAME__ -> 98:envelope___control___6 ;
-23:__UG_NAME__ -> 98:envelope___control___7 ;
-99:__UG_NAME__ -> 100:gate ;
-24:__UG_NAME__ -> 100:envelope___control___0 ;
-24:__UG_NAME__ -> 100:envelope___control___4 ;
-25:__UG_NAME__ -> 100:envelope___control___5 ;
-26:__UG_NAME__ -> 100:envelope___control___6 ;
-27:__UG_NAME__ -> 100:envelope___control___7 ;
-106:__UG_NAME__ -> 107:gate ;
-0:__UG_NAME__ -> 107:envelope___control___0 ;
-0:__UG_NAME__ -> 107:envelope___control___4 ;
-1:__UG_NAME__ -> 107:envelope___control___5 ;
-2:__UG_NAME__ -> 107:envelope___control___6 ;
-3:__UG_NAME__ -> 107:envelope___control___7 ;
-25:__UG_NAME__ -> 30:in ;
-8:__UG_NAME__ -> 34:in ;
-9:__UG_NAME__ -> 38:in ;
-4:__UG_NAME__ -> 46:in ;
-5:__UG_NAME__ -> 50:in ;
-17:__UG_NAME__ -> 57:in ;
-12:__UG_NAME__ -> 60:in ;
-16:__UG_NAME__ -> 63:in ;
-24:__UG_NAME__ -> 72:in ;
-0:__UG_NAME__ -> 79:in ;
-20:__UG_NAME__ -> 83:in ;
-13:__UG_NAME__ -> 88:in ;
-21:__UG_NAME__ -> 94:in ;
-1:__UG_NAME__ -> 103:in ;
-28:__UG_NAME__ -> 43:bus ;
-92:__UG_NAME__ -> 93:a ;
-108:__UG_NAME__ -> 112:signals___x____fade2___0 ;
-111:__UG_NAME__ -> 112:signals___x____fade2___1 ;
-29:__UG_NAME__ -> 112:bus ;
-100:__UG_NAME__ -> 101:time____dispersion ;
-98:__UG_NAME__ -> 101:pitch____dispersion ;
-93:__UG_NAME__ -> 101:pitch____ratio ;
-68:__UG_NAME__ -> 101:window____size ;
-44:__UG_NAME__ -> 101:in ;
-100:__UG_NAME__ -> 110:time____dispersion ;
-98:__UG_NAME__ -> 110:pitch____dispersion ;
-93:__UG_NAME__ -> 110:pitch____ratio ;
-68:__UG_NAME__ -> 110:window____size ;
-109:__UG_NAME__ -> 110:in ;
-107:__UG_NAME__ -> 108:level ;
-56:__UG_NAME__ -> 108:pan ;
-101:__UG_NAME__ -> 108:inb ;
-44:__UG_NAME__ -> 108:ina ;
-107:__UG_NAME__ -> 111:level ;
-78:__UG_NAME__ -> 111:pan ;
-110:__UG_NAME__ -> 111:inb ;
-109:__UG_NAME__ -> 111:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_rbpf.dot b/etc/synthdefs/graphviz/sonic-pi-fx_rbpf.dot
deleted file mode 100644
index 803e540..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_rbpf.dot
+++ /dev/null
@@ -1,242 +0,0 @@
-digraph synthdef {
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :centre
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :centre_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :centre_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :centre_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :res
- default: 0.6" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-40 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-65 [label = "{{ <in> in|<freq> freq|<bwr> bwr} |<__UG_NAME__>resonz }" style="filled, bold, rounded"  shape=record rankdir=LR];
-82 [label = "{{ <in> in|<freq> freq|<bwr> bwr} |<__UG_NAME__>resonz }" style="filled, bold, rounded"  shape=record rankdir=LR];
-79 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-84 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-41:__UG_NAME__ -> 42:b ;
-40:__UG_NAME__ -> 42:a ;
-66:__UG_NAME__ -> 67:a ;
-66:__UG_NAME__ -> 80:a ;
-41:__UG_NAME__ -> 81:b ;
-40:__UG_NAME__ -> 81:a ;
-25:__UG_NAME__ -> 26:b ;
-22:__UG_NAME__ -> 26:a ;
-29:__UG_NAME__ -> 30:b ;
-26:__UG_NAME__ -> 30:a ;
-34:__UG_NAME__ -> 35:b ;
-31:__UG_NAME__ -> 35:a ;
-38:__UG_NAME__ -> 39:b ;
-35:__UG_NAME__ -> 39:a ;
-46:__UG_NAME__ -> 47:b ;
-43:__UG_NAME__ -> 47:a ;
-50:__UG_NAME__ -> 51:b ;
-47:__UG_NAME__ -> 51:a ;
-58:__UG_NAME__ -> 59:b ;
-54:__UG_NAME__ -> 59:a ;
-62:__UG_NAME__ -> 63:b ;
-59:__UG_NAME__ -> 63:a ;
-72:__UG_NAME__ -> 73:b ;
-69:__UG_NAME__ -> 73:a ;
-76:__UG_NAME__ -> 77:b ;
-73:__UG_NAME__ -> 77:a ;
-67:__UG_NAME__ -> 68:a ;
-80:__UG_NAME__ -> 83:a ;
-24:__UG_NAME__ -> 25:a ;
-28:__UG_NAME__ -> 29:a ;
-33:__UG_NAME__ -> 34:a ;
-37:__UG_NAME__ -> 38:a ;
-45:__UG_NAME__ -> 46:a ;
-49:__UG_NAME__ -> 50:a ;
-57:__UG_NAME__ -> 58:a ;
-61:__UG_NAME__ -> 62:a ;
-71:__UG_NAME__ -> 72:a ;
-75:__UG_NAME__ -> 76:a ;
-23:__UG_NAME__ -> 24:a ;
-27:__UG_NAME__ -> 28:a ;
-32:__UG_NAME__ -> 33:a ;
-36:__UG_NAME__ -> 37:a ;
-44:__UG_NAME__ -> 45:a ;
-48:__UG_NAME__ -> 49:a ;
-56:__UG_NAME__ -> 57:a ;
-60:__UG_NAME__ -> 61:a ;
-70:__UG_NAME__ -> 71:a ;
-74:__UG_NAME__ -> 75:a ;
-39:__UG_NAME__ -> 40:gate ;
-8:__UG_NAME__ -> 40:envelope___control___0 ;
-8:__UG_NAME__ -> 40:envelope___control___4 ;
-9:__UG_NAME__ -> 40:envelope___control___5 ;
-10:__UG_NAME__ -> 40:envelope___control___6 ;
-11:__UG_NAME__ -> 40:envelope___control___7 ;
-51:__UG_NAME__ -> 52:gate ;
-12:__UG_NAME__ -> 52:envelope___control___0 ;
-12:__UG_NAME__ -> 52:envelope___control___4 ;
-13:__UG_NAME__ -> 52:envelope___control___5 ;
-14:__UG_NAME__ -> 52:envelope___control___6 ;
-15:__UG_NAME__ -> 52:envelope___control___7 ;
-63:__UG_NAME__ -> 64:gate ;
-55:__UG_NAME__ -> 64:envelope___mul____add___0 ;
-55:__UG_NAME__ -> 64:envelope___mul____add___4 ;
-17:__UG_NAME__ -> 64:envelope___control___5 ;
-18:__UG_NAME__ -> 64:envelope___control___6 ;
-19:__UG_NAME__ -> 64:envelope___control___7 ;
-30:__UG_NAME__ -> 66:gate ;
-4:__UG_NAME__ -> 66:envelope___control___0 ;
-4:__UG_NAME__ -> 66:envelope___control___4 ;
-5:__UG_NAME__ -> 66:envelope___control___5 ;
-6:__UG_NAME__ -> 66:envelope___control___6 ;
-7:__UG_NAME__ -> 66:envelope___control___7 ;
-77:__UG_NAME__ -> 78:gate ;
-0:__UG_NAME__ -> 78:envelope___control___0 ;
-0:__UG_NAME__ -> 78:envelope___control___4 ;
-1:__UG_NAME__ -> 78:envelope___control___5 ;
-2:__UG_NAME__ -> 78:envelope___control___6 ;
-3:__UG_NAME__ -> 78:envelope___control___7 ;
-4:__UG_NAME__ -> 23:in ;
-5:__UG_NAME__ -> 27:in ;
-8:__UG_NAME__ -> 32:in ;
-9:__UG_NAME__ -> 36:in ;
-12:__UG_NAME__ -> 44:in ;
-13:__UG_NAME__ -> 48:in ;
-55:__UG_NAME__ -> 56:in ;
-17:__UG_NAME__ -> 60:in ;
-0:__UG_NAME__ -> 70:in ;
-1:__UG_NAME__ -> 74:in ;
-20:__UG_NAME__ -> 41:bus ;
-52:__UG_NAME__ -> 53:a ;
-16:__UG_NAME__ -> 55:in ;
-84:__UG_NAME__ -> 85:signals___x____fade2___0 ;
-79:__UG_NAME__ -> 85:signals___x____fade2___1 ;
-21:__UG_NAME__ -> 85:bus ;
-64:__UG_NAME__ -> 65:bwr ;
-53:__UG_NAME__ -> 65:freq ;
-42:__UG_NAME__ -> 65:in ;
-64:__UG_NAME__ -> 82:bwr ;
-53:__UG_NAME__ -> 82:freq ;
-81:__UG_NAME__ -> 82:in ;
-78:__UG_NAME__ -> 79:level ;
-68:__UG_NAME__ -> 79:pan ;
-65:__UG_NAME__ -> 79:inb ;
-42:__UG_NAME__ -> 79:ina ;
-78:__UG_NAME__ -> 84:level ;
-83:__UG_NAME__ -> 84:pan ;
-82:__UG_NAME__ -> 84:inb ;
-81:__UG_NAME__ -> 84:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_reverb.dot b/etc/synthdefs/graphviz/sonic-pi-fx_reverb.dot
deleted file mode 100644
index 3e5c760..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_reverb.dot
+++ /dev/null
@@ -1,224 +0,0 @@
-digraph synthdef {
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 0.4" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :room
- default: 0.6" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :room_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :room_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :room_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :damp
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :damp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :damp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :damp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-54 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <in> in|<in2> in2|<mix> mix|<room> room|<damp> damp} |<__UG_NAME__>free-verb2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-78 [label = "{{ <bus> bus|{{<signals___binary____op____u____gen___0>|<signals___binary____op____u____gen___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-59:__UG_NAME__ -> 60:b ;
-54:__UG_NAME__ -> 60:a ;
-59:__UG_NAME__ -> 61:b ;
-54:__UG_NAME__ -> 61:a ;
-75:__UG_NAME__ -> 76:b ;
-58:__UG_NAME__ -> 76:a ;
-75:__UG_NAME__ -> 77:b ;
-58:__UG_NAME__ -> 77:a ;
-42:__UG_NAME__ -> 43:b ;
-41:__UG_NAME__ -> 43:a ;
-46:__UG_NAME__ -> 47:b ;
-43:__UG_NAME__ -> 47:a ;
-51:__UG_NAME__ -> 52:b ;
-48:__UG_NAME__ -> 52:a ;
-34:__UG_NAME__ -> 53:b ;
-52:__UG_NAME__ -> 53:a ;
-30:__UG_NAME__ -> 56:b ;
-55:__UG_NAME__ -> 56:a ;
-24:__UG_NAME__ -> 57:b ;
-56:__UG_NAME__ -> 57:a ;
-27:__UG_NAME__ -> 63:b ;
-62:__UG_NAME__ -> 63:a ;
-64:__UG_NAME__ -> 65:b ;
-63:__UG_NAME__ -> 65:a ;
-71:__UG_NAME__ -> 72:b ;
-68:__UG_NAME__ -> 72:a ;
-39:__UG_NAME__ -> 73:b ;
-72:__UG_NAME__ -> 73:a ;
-23:__UG_NAME__ -> 24:a ;
-26:__UG_NAME__ -> 27:a ;
-29:__UG_NAME__ -> 30:a ;
-33:__UG_NAME__ -> 34:a ;
-38:__UG_NAME__ -> 39:a ;
-36:__UG_NAME__ -> 42:a ;
-45:__UG_NAME__ -> 46:a ;
-50:__UG_NAME__ -> 51:a ;
-40:__UG_NAME__ -> 64:a ;
-70:__UG_NAME__ -> 71:a ;
-22:__UG_NAME__ -> 23:a ;
-25:__UG_NAME__ -> 26:a ;
-28:__UG_NAME__ -> 29:a ;
-32:__UG_NAME__ -> 33:a ;
-35:__UG_NAME__ -> 36:a ;
-37:__UG_NAME__ -> 38:a ;
-31:__UG_NAME__ -> 40:a ;
-44:__UG_NAME__ -> 45:a ;
-49:__UG_NAME__ -> 50:a ;
-69:__UG_NAME__ -> 70:a ;
-53:__UG_NAME__ -> 54:gate ;
-8:__UG_NAME__ -> 54:envelope___control___0 ;
-8:__UG_NAME__ -> 54:envelope___control___4 ;
-9:__UG_NAME__ -> 54:envelope___control___5 ;
-10:__UG_NAME__ -> 54:envelope___control___6 ;
-11:__UG_NAME__ -> 54:envelope___control___7 ;
-57:__UG_NAME__ -> 58:gate ;
-0:__UG_NAME__ -> 58:envelope___control___0 ;
-0:__UG_NAME__ -> 58:envelope___control___4 ;
-1:__UG_NAME__ -> 58:envelope___control___5 ;
-2:__UG_NAME__ -> 58:envelope___control___6 ;
-3:__UG_NAME__ -> 58:envelope___control___7 ;
-65:__UG_NAME__ -> 66:gate ;
-4:__UG_NAME__ -> 66:envelope___control___0 ;
-4:__UG_NAME__ -> 66:envelope___control___4 ;
-5:__UG_NAME__ -> 66:envelope___control___5 ;
-6:__UG_NAME__ -> 66:envelope___control___6 ;
-7:__UG_NAME__ -> 66:envelope___control___7 ;
-47:__UG_NAME__ -> 67:gate ;
-12:__UG_NAME__ -> 67:envelope___control___0 ;
-12:__UG_NAME__ -> 67:envelope___control___4 ;
-13:__UG_NAME__ -> 67:envelope___control___5 ;
-14:__UG_NAME__ -> 67:envelope___control___6 ;
-15:__UG_NAME__ -> 67:envelope___control___7 ;
-73:__UG_NAME__ -> 74:gate ;
-16:__UG_NAME__ -> 74:envelope___control___0 ;
-16:__UG_NAME__ -> 74:envelope___control___4 ;
-17:__UG_NAME__ -> 74:envelope___control___5 ;
-18:__UG_NAME__ -> 74:envelope___control___6 ;
-19:__UG_NAME__ -> 74:envelope___control___7 ;
-74:__UG_NAME__ -> 75:damp ;
-67:__UG_NAME__ -> 75:room ;
-66:__UG_NAME__ -> 75:mix ;
-61:__UG_NAME__ -> 75:in2 ;
-60:__UG_NAME__ -> 75:in ;
-1:__UG_NAME__ -> 22:in ;
-4:__UG_NAME__ -> 25:in ;
-0:__UG_NAME__ -> 28:in ;
-5:__UG_NAME__ -> 31:in ;
-9:__UG_NAME__ -> 32:in ;
-12:__UG_NAME__ -> 35:in ;
-17:__UG_NAME__ -> 37:in ;
-13:__UG_NAME__ -> 44:in ;
-8:__UG_NAME__ -> 49:in ;
-16:__UG_NAME__ -> 69:in ;
-20:__UG_NAME__ -> 59:bus ;
-76:__UG_NAME__ -> 78:signals___binary____op____u____gen___0 ;
-77:__UG_NAME__ -> 78:signals___binary____op____u____gen___1 ;
-21:__UG_NAME__ -> 78:bus ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_rhpf.dot b/etc/synthdefs/graphviz/sonic-pi-fx_rhpf.dot
deleted file mode 100644
index 5e4c059..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_rhpf.dot
+++ /dev/null
@@ -1,242 +0,0 @@
-digraph synthdef {
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :res
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-66 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rhpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-70 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rhpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-81 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-84 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-52:__UG_NAME__ -> 53:b ;
-51:__UG_NAME__ -> 53:a ;
-52:__UG_NAME__ -> 69:b ;
-51:__UG_NAME__ -> 69:a ;
-33:__UG_NAME__ -> 71:a ;
-33:__UG_NAME__ -> 82:a ;
-30:__UG_NAME__ -> 31:b ;
-27:__UG_NAME__ -> 31:a ;
-26:__UG_NAME__ -> 32:b ;
-31:__UG_NAME__ -> 32:a ;
-35:__UG_NAME__ -> 36:b ;
-34:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:b ;
-36:__UG_NAME__ -> 40:a ;
-44:__UG_NAME__ -> 45:b ;
-41:__UG_NAME__ -> 45:a ;
-48:__UG_NAME__ -> 49:b ;
-45:__UG_NAME__ -> 49:a ;
-59:__UG_NAME__ -> 60:b ;
-55:__UG_NAME__ -> 60:a ;
-63:__UG_NAME__ -> 64:b ;
-60:__UG_NAME__ -> 64:a ;
-76:__UG_NAME__ -> 77:b ;
-73:__UG_NAME__ -> 77:a ;
-78:__UG_NAME__ -> 79:b ;
-77:__UG_NAME__ -> 79:a ;
-71:__UG_NAME__ -> 72:a ;
-82:__UG_NAME__ -> 83:a ;
-25:__UG_NAME__ -> 26:a ;
-29:__UG_NAME__ -> 30:a ;
-23:__UG_NAME__ -> 35:a ;
-38:__UG_NAME__ -> 39:a ;
-43:__UG_NAME__ -> 44:a ;
-47:__UG_NAME__ -> 48:a ;
-58:__UG_NAME__ -> 59:a ;
-62:__UG_NAME__ -> 63:a ;
-75:__UG_NAME__ -> 76:a ;
-68:__UG_NAME__ -> 78:a ;
-22:__UG_NAME__ -> 23:a ;
-24:__UG_NAME__ -> 25:a ;
-28:__UG_NAME__ -> 29:a ;
-37:__UG_NAME__ -> 38:a ;
-42:__UG_NAME__ -> 43:a ;
-46:__UG_NAME__ -> 47:a ;
-57:__UG_NAME__ -> 58:a ;
-61:__UG_NAME__ -> 62:a ;
-67:__UG_NAME__ -> 68:a ;
-74:__UG_NAME__ -> 75:a ;
-32:__UG_NAME__ -> 33:gate ;
-4:__UG_NAME__ -> 33:envelope___control___0 ;
-4:__UG_NAME__ -> 33:envelope___control___4 ;
-5:__UG_NAME__ -> 33:envelope___control___5 ;
-6:__UG_NAME__ -> 33:envelope___control___6 ;
-7:__UG_NAME__ -> 33:envelope___control___7 ;
-49:__UG_NAME__ -> 50:gate ;
-12:__UG_NAME__ -> 50:envelope___control___0 ;
-12:__UG_NAME__ -> 50:envelope___control___4 ;
-13:__UG_NAME__ -> 50:envelope___control___5 ;
-14:__UG_NAME__ -> 50:envelope___control___6 ;
-15:__UG_NAME__ -> 50:envelope___control___7 ;
-40:__UG_NAME__ -> 51:gate ;
-8:__UG_NAME__ -> 51:envelope___control___0 ;
-8:__UG_NAME__ -> 51:envelope___control___4 ;
-9:__UG_NAME__ -> 51:envelope___control___5 ;
-10:__UG_NAME__ -> 51:envelope___control___6 ;
-11:__UG_NAME__ -> 51:envelope___control___7 ;
-64:__UG_NAME__ -> 65:gate ;
-56:__UG_NAME__ -> 65:envelope___mul____add___0 ;
-56:__UG_NAME__ -> 65:envelope___mul____add___4 ;
-17:__UG_NAME__ -> 65:envelope___control___5 ;
-18:__UG_NAME__ -> 65:envelope___control___6 ;
-19:__UG_NAME__ -> 65:envelope___control___7 ;
-79:__UG_NAME__ -> 80:gate ;
-0:__UG_NAME__ -> 80:envelope___control___0 ;
-0:__UG_NAME__ -> 80:envelope___control___4 ;
-1:__UG_NAME__ -> 80:envelope___control___5 ;
-2:__UG_NAME__ -> 80:envelope___control___6 ;
-3:__UG_NAME__ -> 80:envelope___control___7 ;
-8:__UG_NAME__ -> 22:in ;
-5:__UG_NAME__ -> 24:in ;
-4:__UG_NAME__ -> 28:in ;
-9:__UG_NAME__ -> 37:in ;
-12:__UG_NAME__ -> 42:in ;
-13:__UG_NAME__ -> 46:in ;
-56:__UG_NAME__ -> 57:in ;
-17:__UG_NAME__ -> 61:in ;
-1:__UG_NAME__ -> 67:in ;
-0:__UG_NAME__ -> 74:in ;
-20:__UG_NAME__ -> 52:bus ;
-50:__UG_NAME__ -> 54:a ;
-16:__UG_NAME__ -> 56:in ;
-84:__UG_NAME__ -> 85:signals___x____fade2___0 ;
-81:__UG_NAME__ -> 85:signals___x____fade2___1 ;
-21:__UG_NAME__ -> 85:bus ;
-65:__UG_NAME__ -> 66:rq ;
-54:__UG_NAME__ -> 66:freq ;
-53:__UG_NAME__ -> 66:in ;
-65:__UG_NAME__ -> 70:rq ;
-54:__UG_NAME__ -> 70:freq ;
-69:__UG_NAME__ -> 70:in ;
-80:__UG_NAME__ -> 81:level ;
-72:__UG_NAME__ -> 81:pan ;
-70:__UG_NAME__ -> 81:inb ;
-69:__UG_NAME__ -> 81:ina ;
-80:__UG_NAME__ -> 84:level ;
-83:__UG_NAME__ -> 84:pan ;
-66:__UG_NAME__ -> 84:inb ;
-53:__UG_NAME__ -> 84:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_ring_mod.dot b/etc/synthdefs/graphviz/sonic-pi-fx_ring_mod.dot
deleted file mode 100644
index 5bca3f0..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_ring_mod.dot
+++ /dev/null
@@ -1,247 +0,0 @@
-digraph synthdef {
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :freq
- default: 30.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :freq_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :freq_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :freq_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :mod_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :mod_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :mod_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :mod_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-80 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>limiter }" style="filled, bold, rounded"  shape=record rankdir=LR];
-84 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>limiter }" style="filled, bold, rounded"  shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>ring1 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> } |<__UG_NAME__>ring1 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-74 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-81 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-87 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-60:__UG_NAME__ -> 61:b ;
-59:__UG_NAME__ -> 61:a ;
-74:__UG_NAME__ -> 75:b ;
-62:__UG_NAME__ -> 75:a ;
-77:__UG_NAME__ -> 78:a ;
-60:__UG_NAME__ -> 82:b ;
-59:__UG_NAME__ -> 82:a ;
-77:__UG_NAME__ -> 85:a ;
-27:__UG_NAME__ -> 28:b ;
-24:__UG_NAME__ -> 28:a ;
-31:__UG_NAME__ -> 32:b ;
-28:__UG_NAME__ -> 32:a ;
-35:__UG_NAME__ -> 36:b ;
-34:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:b ;
-36:__UG_NAME__ -> 40:a ;
-50:__UG_NAME__ -> 51:b ;
-49:__UG_NAME__ -> 51:a ;
-52:__UG_NAME__ -> 53:b ;
-51:__UG_NAME__ -> 53:a ;
-43:__UG_NAME__ -> 55:b ;
-54:__UG_NAME__ -> 55:a ;
-57:__UG_NAME__ -> 58:b ;
-55:__UG_NAME__ -> 58:a ;
-66:__UG_NAME__ -> 67:b ;
-63:__UG_NAME__ -> 67:a ;
-70:__UG_NAME__ -> 71:b ;
-67:__UG_NAME__ -> 71:a ;
-78:__UG_NAME__ -> 79:a ;
-85:__UG_NAME__ -> 86:a ;
-26:__UG_NAME__ -> 27:a ;
-30:__UG_NAME__ -> 31:a ;
-23:__UG_NAME__ -> 35:a ;
-38:__UG_NAME__ -> 39:a ;
-42:__UG_NAME__ -> 43:a ;
-45:__UG_NAME__ -> 50:a ;
-47:__UG_NAME__ -> 52:a ;
-56:__UG_NAME__ -> 57:a ;
-65:__UG_NAME__ -> 66:a ;
-69:__UG_NAME__ -> 70:a ;
-22:__UG_NAME__ -> 23:a ;
-25:__UG_NAME__ -> 26:a ;
-29:__UG_NAME__ -> 30:a ;
-37:__UG_NAME__ -> 38:a ;
-41:__UG_NAME__ -> 42:a ;
-44:__UG_NAME__ -> 45:a ;
-46:__UG_NAME__ -> 47:a ;
-48:__UG_NAME__ -> 56:a ;
-64:__UG_NAME__ -> 65:a ;
-68:__UG_NAME__ -> 69:a ;
-32:__UG_NAME__ -> 33:gate ;
-0:__UG_NAME__ -> 33:envelope___control___0 ;
-0:__UG_NAME__ -> 33:envelope___control___4 ;
-1:__UG_NAME__ -> 33:envelope___control___5 ;
-2:__UG_NAME__ -> 33:envelope___control___6 ;
-3:__UG_NAME__ -> 33:envelope___control___7 ;
-58:__UG_NAME__ -> 59:gate ;
-8:__UG_NAME__ -> 59:envelope___control___0 ;
-8:__UG_NAME__ -> 59:envelope___control___4 ;
-9:__UG_NAME__ -> 59:envelope___control___5 ;
-10:__UG_NAME__ -> 59:envelope___control___6 ;
-11:__UG_NAME__ -> 59:envelope___control___7 ;
-40:__UG_NAME__ -> 62:gate ;
-16:__UG_NAME__ -> 62:envelope___control___0 ;
-16:__UG_NAME__ -> 62:envelope___control___4 ;
-17:__UG_NAME__ -> 62:envelope___control___5 ;
-18:__UG_NAME__ -> 62:envelope___control___6 ;
-19:__UG_NAME__ -> 62:envelope___control___7 ;
-71:__UG_NAME__ -> 72:gate ;
-12:__UG_NAME__ -> 72:envelope___control___0 ;
-12:__UG_NAME__ -> 72:envelope___control___4 ;
-13:__UG_NAME__ -> 72:envelope___control___5 ;
-14:__UG_NAME__ -> 72:envelope___control___6 ;
-15:__UG_NAME__ -> 72:envelope___control___7 ;
-53:__UG_NAME__ -> 77:gate ;
-4:__UG_NAME__ -> 77:envelope___control___0 ;
-4:__UG_NAME__ -> 77:envelope___control___4 ;
-5:__UG_NAME__ -> 77:envelope___control___5 ;
-6:__UG_NAME__ -> 77:envelope___control___6 ;
-7:__UG_NAME__ -> 77:envelope___control___7 ;
-16:__UG_NAME__ -> 22:in ;
-0:__UG_NAME__ -> 25:in ;
-1:__UG_NAME__ -> 29:in ;
-17:__UG_NAME__ -> 37:in ;
-8:__UG_NAME__ -> 41:in ;
-4:__UG_NAME__ -> 44:in ;
-5:__UG_NAME__ -> 46:in ;
-9:__UG_NAME__ -> 48:in ;
-12:__UG_NAME__ -> 64:in ;
-13:__UG_NAME__ -> 68:in ;
-20:__UG_NAME__ -> 60:bus ;
-76:__UG_NAME__ -> 80:in ;
-83:__UG_NAME__ -> 84:in ;
-72:__UG_NAME__ -> 73:a ;
-81:__UG_NAME__ -> 88:signals___x____fade2___0 ;
-87:__UG_NAME__ -> 88:signals___x____fade2___1 ;
-21:__UG_NAME__ -> 88:bus ;
-75:__UG_NAME__ -> 76:b ;
-61:__UG_NAME__ -> 76:a ;
-75:__UG_NAME__ -> 83:b ;
-82:__UG_NAME__ -> 83:a ;
-73:__UG_NAME__ -> 74:freq ;
-33:__UG_NAME__ -> 81:level ;
-79:__UG_NAME__ -> 81:pan ;
-80:__UG_NAME__ -> 81:inb ;
-61:__UG_NAME__ -> 81:ina ;
-33:__UG_NAME__ -> 87:level ;
-86:__UG_NAME__ -> 87:pan ;
-84:__UG_NAME__ -> 87:inb ;
-82:__UG_NAME__ -> 87:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_rlpf.dot b/etc/synthdefs/graphviz/sonic-pi-fx_rlpf.dot
deleted file mode 100644
index 536b528..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_rlpf.dot
+++ /dev/null
@@ -1,242 +0,0 @@
-digraph synthdef {
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :res
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-62 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-64 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-81 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-84 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-48:__UG_NAME__ -> 49:b ;
-47:__UG_NAME__ -> 49:a ;
-48:__UG_NAME__ -> 63:b ;
-47:__UG_NAME__ -> 63:a ;
-71:__UG_NAME__ -> 72:a ;
-71:__UG_NAME__ -> 82:a ;
-31:__UG_NAME__ -> 32:b ;
-28:__UG_NAME__ -> 32:a ;
-35:__UG_NAME__ -> 36:b ;
-32:__UG_NAME__ -> 36:a ;
-41:__UG_NAME__ -> 42:b ;
-38:__UG_NAME__ -> 42:a ;
-45:__UG_NAME__ -> 46:b ;
-42:__UG_NAME__ -> 46:a ;
-55:__UG_NAME__ -> 56:b ;
-51:__UG_NAME__ -> 56:a ;
-59:__UG_NAME__ -> 60:b ;
-56:__UG_NAME__ -> 60:a ;
-66:__UG_NAME__ -> 67:b ;
-65:__UG_NAME__ -> 67:a ;
-69:__UG_NAME__ -> 70:b ;
-67:__UG_NAME__ -> 70:a ;
-77:__UG_NAME__ -> 78:b ;
-74:__UG_NAME__ -> 78:a ;
-24:__UG_NAME__ -> 79:b ;
-78:__UG_NAME__ -> 79:a ;
-72:__UG_NAME__ -> 73:a ;
-82:__UG_NAME__ -> 83:a ;
-23:__UG_NAME__ -> 24:a ;
-30:__UG_NAME__ -> 31:a ;
-34:__UG_NAME__ -> 35:a ;
-40:__UG_NAME__ -> 41:a ;
-44:__UG_NAME__ -> 45:a ;
-54:__UG_NAME__ -> 55:a ;
-58:__UG_NAME__ -> 59:a ;
-27:__UG_NAME__ -> 66:a ;
-68:__UG_NAME__ -> 69:a ;
-76:__UG_NAME__ -> 77:a ;
-22:__UG_NAME__ -> 23:a ;
-26:__UG_NAME__ -> 27:a ;
-29:__UG_NAME__ -> 30:a ;
-33:__UG_NAME__ -> 34:a ;
-39:__UG_NAME__ -> 40:a ;
-43:__UG_NAME__ -> 44:a ;
-53:__UG_NAME__ -> 54:a ;
-57:__UG_NAME__ -> 58:a ;
-25:__UG_NAME__ -> 68:a ;
-75:__UG_NAME__ -> 76:a ;
-36:__UG_NAME__ -> 37:gate ;
-12:__UG_NAME__ -> 37:envelope___control___0 ;
-12:__UG_NAME__ -> 37:envelope___control___4 ;
-13:__UG_NAME__ -> 37:envelope___control___5 ;
-14:__UG_NAME__ -> 37:envelope___control___6 ;
-15:__UG_NAME__ -> 37:envelope___control___7 ;
-46:__UG_NAME__ -> 47:gate ;
-8:__UG_NAME__ -> 47:envelope___control___0 ;
-8:__UG_NAME__ -> 47:envelope___control___4 ;
-9:__UG_NAME__ -> 47:envelope___control___5 ;
-10:__UG_NAME__ -> 47:envelope___control___6 ;
-11:__UG_NAME__ -> 47:envelope___control___7 ;
-60:__UG_NAME__ -> 61:gate ;
-52:__UG_NAME__ -> 61:envelope___mul____add___0 ;
-52:__UG_NAME__ -> 61:envelope___mul____add___4 ;
-17:__UG_NAME__ -> 61:envelope___control___5 ;
-18:__UG_NAME__ -> 61:envelope___control___6 ;
-19:__UG_NAME__ -> 61:envelope___control___7 ;
-70:__UG_NAME__ -> 71:gate ;
-4:__UG_NAME__ -> 71:envelope___control___0 ;
-4:__UG_NAME__ -> 71:envelope___control___4 ;
-5:__UG_NAME__ -> 71:envelope___control___5 ;
-6:__UG_NAME__ -> 71:envelope___control___6 ;
-7:__UG_NAME__ -> 71:envelope___control___7 ;
-79:__UG_NAME__ -> 80:gate ;
-0:__UG_NAME__ -> 80:envelope___control___0 ;
-0:__UG_NAME__ -> 80:envelope___control___4 ;
-1:__UG_NAME__ -> 80:envelope___control___5 ;
-2:__UG_NAME__ -> 80:envelope___control___6 ;
-3:__UG_NAME__ -> 80:envelope___control___7 ;
-1:__UG_NAME__ -> 22:in ;
-5:__UG_NAME__ -> 25:in ;
-4:__UG_NAME__ -> 26:in ;
-12:__UG_NAME__ -> 29:in ;
-13:__UG_NAME__ -> 33:in ;
-8:__UG_NAME__ -> 39:in ;
-9:__UG_NAME__ -> 43:in ;
-52:__UG_NAME__ -> 53:in ;
-17:__UG_NAME__ -> 57:in ;
-0:__UG_NAME__ -> 75:in ;
-20:__UG_NAME__ -> 48:bus ;
-37:__UG_NAME__ -> 50:a ;
-16:__UG_NAME__ -> 52:in ;
-84:__UG_NAME__ -> 85:signals___x____fade2___0 ;
-81:__UG_NAME__ -> 85:signals___x____fade2___1 ;
-21:__UG_NAME__ -> 85:bus ;
-61:__UG_NAME__ -> 62:rq ;
-50:__UG_NAME__ -> 62:freq ;
-49:__UG_NAME__ -> 62:in ;
-61:__UG_NAME__ -> 64:rq ;
-50:__UG_NAME__ -> 64:freq ;
-63:__UG_NAME__ -> 64:in ;
-80:__UG_NAME__ -> 81:level ;
-73:__UG_NAME__ -> 81:pan ;
-64:__UG_NAME__ -> 81:inb ;
-63:__UG_NAME__ -> 81:ina ;
-80:__UG_NAME__ -> 84:level ;
-83:__UG_NAME__ -> 84:pan ;
-62:__UG_NAME__ -> 84:inb ;
-49:__UG_NAME__ -> 84:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_slicer.dot b/etc/synthdefs/graphviz/sonic-pi-fx_slicer.dot
deleted file mode 100644
index fee4ae2..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_slicer.dot
+++ /dev/null
@@ -1,615 +0,0 @@
-digraph synthdef {
-111 [label = "{{ <a> |<b> 6.2831855} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-136 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-148 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-150 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-153 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-155 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-160 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-199 [label = "{{ <a> |<b> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-203 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-214 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-215 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-218 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-219 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-220 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-131 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-135 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-138 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-145 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-151 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-157 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-167 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-171 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-177 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-182 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-186 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-192 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-194 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-208 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-211 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-149 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-156 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-197 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-200 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-216 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-221 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-198 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ <a> |<b> } |<__UG_NAME__>\< }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-130 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-134 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-147 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-166 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-170 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-176 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-181 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-185 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-193 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-207 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-210 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-133 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-143 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-165 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-169 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-174 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-175 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-180 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-184 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-206 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-209 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-139 [label = "{{ <num____channels> num-channels 1|<bufnum> bufnum|<phase> phase|<loop> loop 1.0|<interpolation> interpolation 2.0} |<__UG_NAME__>buf-rd }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <in> in|<lo> lo 0.0|<hi> hi 1.0} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <in> in|<lo> lo 0.0|<hi> hi 1.0} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :phase
- default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :phase_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :phase_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :phase_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :amp_min
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :amp_min_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :amp_min_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :amp_min_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :amp_max
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :amp_max_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :amp_max_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :amp_max_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :smooth
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :smooth_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :smooth_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :smooth_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :smooth_up
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :smooth_up_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :smooth_up_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :smooth_up_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :smooth_down
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "control
- :smooth_down_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "control
- :smooth_down_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "control
- :smooth_down_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-40 [label = "control
- :probability
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-41 [label = "control
- :probability_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "control
- :probability_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-43 [label = "control
- :probability_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-44 [label = "control
- :prob_pos
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-45 [label = "control
- :prob_pos_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-46 [label = "control
- :prob_pos_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-47 [label = "control
- :prob_pos_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-48 [label = "control
- :phase_offset
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-49 [label = "control
- :wave
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-50 [label = "control
- :invert_wave
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-51 [label = "control
- :seed
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-52 [label = "control
- :rand_buf
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-53 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-54 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-82 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ {{<envelope___clip___0>|1.0|-99|-99|<envelope___clip___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-146 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-172 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-178 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-187 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-189 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-195 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-196 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-212 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-126 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-132 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-162 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-164 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-168 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-183 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-188 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-205 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <freq> freq|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-163 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-173 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-179 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-190 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-202 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-213 [label = "{{ <in> in|<lag____time> lag-time} |<__UG_NAME__>lag }" style="bold, rounded" shape=record rankdir=LR];
-204 [label = "{{ <in> in|<lag____time____up> lag-time-up|<lag____time____down> lag-time-down} |<__UG_NAME__>lag-ud }" style="bold, rounded" shape=record rankdir=LR];
-154 [label = "{{ <freq> freq|<iphase> iphase|<width> width} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
-152 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
-158 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <in> in|<mul> mul 2.0|<add> add -1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-201 [label = "{{ <in> in|<mul> mul|<add> add} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-223 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-137 [label = "{{ <trig> trig|<reset> reset 0.0} |<__UG_NAME__>pulse-count }" style="bold, rounded" shape=record rankdir=LR];
-159 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-161 [label = "{{ <which> which|{{<array___env____gen___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-191 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <freq> freq|<phase> phase|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-217 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-222 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-110:__UG_NAME__ -> 111:a ;
-48:__UG_NAME__ -> 136:b ;
-147:__UG_NAME__ -> 148:b ;
-149:__UG_NAME__ -> 150:b ;
-152:__UG_NAME__ -> 153:b ;
-154:__UG_NAME__ -> 155:b ;
-159:__UG_NAME__ -> 160:b ;
-150:__UG_NAME__ -> 160:a ;
-198:__UG_NAME__ -> 199:a ;
-202:__UG_NAME__ -> 203:b ;
-82:__UG_NAME__ -> 203:a ;
-203:__UG_NAME__ -> 214:b ;
-213:__UG_NAME__ -> 214:a ;
-187:__UG_NAME__ -> 215:a ;
-202:__UG_NAME__ -> 218:b ;
-82:__UG_NAME__ -> 218:a ;
-218:__UG_NAME__ -> 219:b ;
-213:__UG_NAME__ -> 219:a ;
-187:__UG_NAME__ -> 220:a ;
-58:__UG_NAME__ -> 59:b ;
-55:__UG_NAME__ -> 59:a ;
-64:__UG_NAME__ -> 65:b ;
-60:__UG_NAME__ -> 65:a ;
-68:__UG_NAME__ -> 69:b ;
-65:__UG_NAME__ -> 69:a ;
-76:__UG_NAME__ -> 77:b ;
-73:__UG_NAME__ -> 77:a ;
-80:__UG_NAME__ -> 81:b ;
-77:__UG_NAME__ -> 81:a ;
-90:__UG_NAME__ -> 91:b ;
-70:__UG_NAME__ -> 91:a ;
-94:__UG_NAME__ -> 95:b ;
-91:__UG_NAME__ -> 95:a ;
-101:__UG_NAME__ -> 104:b ;
-103:__UG_NAME__ -> 104:a ;
-107:__UG_NAME__ -> 108:b ;
-104:__UG_NAME__ -> 108:a ;
-48:__UG_NAME__ -> 110:a ;
-120:__UG_NAME__ -> 121:b ;
-72:__UG_NAME__ -> 121:a ;
-124:__UG_NAME__ -> 125:b ;
-121:__UG_NAME__ -> 125:a ;
-130:__UG_NAME__ -> 131:b ;
-127:__UG_NAME__ -> 131:a ;
-134:__UG_NAME__ -> 135:b ;
-131:__UG_NAME__ -> 135:a ;
-137:__UG_NAME__ -> 138:b ;
-51:__UG_NAME__ -> 138:a ;
-87:__UG_NAME__ -> 142:b ;
-141:__UG_NAME__ -> 142:a ;
-144:__UG_NAME__ -> 145:b ;
-142:__UG_NAME__ -> 145:a ;
-136:__UG_NAME__ -> 151:a ;
-136:__UG_NAME__ -> 157:a ;
-166:__UG_NAME__ -> 167:b ;
-163:__UG_NAME__ -> 167:a ;
-170:__UG_NAME__ -> 171:b ;
-167:__UG_NAME__ -> 171:a ;
-176:__UG_NAME__ -> 177:b ;
-59:__UG_NAME__ -> 177:a ;
-181:__UG_NAME__ -> 182:b ;
-179:__UG_NAME__ -> 182:a ;
-185:__UG_NAME__ -> 186:b ;
-182:__UG_NAME__ -> 186:a ;
-117:__UG_NAME__ -> 192:b ;
-173:__UG_NAME__ -> 192:a ;
-193:__UG_NAME__ -> 194:b ;
-192:__UG_NAME__ -> 194:a ;
-207:__UG_NAME__ -> 208:b ;
-190:__UG_NAME__ -> 208:a ;
-210:__UG_NAME__ -> 211:b ;
-208:__UG_NAME__ -> 211:a ;
-148:__UG_NAME__ -> 149:a ;
-155:__UG_NAME__ -> 156:a ;
-196:__UG_NAME__ -> 197:b ;
-195:__UG_NAME__ -> 197:a ;
-199:__UG_NAME__ -> 200:b ;
-196:__UG_NAME__ -> 200:a ;
-215:__UG_NAME__ -> 216:a ;
-220:__UG_NAME__ -> 221:a ;
-96:__UG_NAME__ -> 97:b ;
-197:__UG_NAME__ -> 198:a ;
-113:__UG_NAME__ -> 140:b ;
-139:__UG_NAME__ -> 140:a ;
-57:__UG_NAME__ -> 58:a ;
-63:__UG_NAME__ -> 64:a ;
-67:__UG_NAME__ -> 68:a ;
-75:__UG_NAME__ -> 76:a ;
-79:__UG_NAME__ -> 80:a ;
-86:__UG_NAME__ -> 87:a ;
-89:__UG_NAME__ -> 90:a ;
-93:__UG_NAME__ -> 94:a ;
-100:__UG_NAME__ -> 101:a ;
-106:__UG_NAME__ -> 107:a ;
-113:__UG_NAME__ -> 114:a ;
-116:__UG_NAME__ -> 117:a ;
-119:__UG_NAME__ -> 120:a ;
-123:__UG_NAME__ -> 124:a ;
-129:__UG_NAME__ -> 130:a ;
-133:__UG_NAME__ -> 134:a ;
-143:__UG_NAME__ -> 144:a ;
-50:__UG_NAME__ -> 147:a ;
-165:__UG_NAME__ -> 166:a ;
-169:__UG_NAME__ -> 170:a ;
-175:__UG_NAME__ -> 176:a ;
-180:__UG_NAME__ -> 181:a ;
-184:__UG_NAME__ -> 185:a ;
-174:__UG_NAME__ -> 193:a ;
-206:__UG_NAME__ -> 207:a ;
-209:__UG_NAME__ -> 210:a ;
-56:__UG_NAME__ -> 57:a ;
-62:__UG_NAME__ -> 63:a ;
-66:__UG_NAME__ -> 67:a ;
-74:__UG_NAME__ -> 75:a ;
-78:__UG_NAME__ -> 79:a ;
-85:__UG_NAME__ -> 86:a ;
-88:__UG_NAME__ -> 89:a ;
-92:__UG_NAME__ -> 93:a ;
-99:__UG_NAME__ -> 100:a ;
-105:__UG_NAME__ -> 106:a ;
-115:__UG_NAME__ -> 116:a ;
-118:__UG_NAME__ -> 119:a ;
-122:__UG_NAME__ -> 123:a ;
-128:__UG_NAME__ -> 129:a ;
-132:__UG_NAME__ -> 133:a ;
-126:__UG_NAME__ -> 143:a ;
-164:__UG_NAME__ -> 165:a ;
-168:__UG_NAME__ -> 169:a ;
-71:__UG_NAME__ -> 174:a ;
-102:__UG_NAME__ -> 175:a ;
-162:__UG_NAME__ -> 180:a ;
-183:__UG_NAME__ -> 184:a ;
-205:__UG_NAME__ -> 206:a ;
-188:__UG_NAME__ -> 209:a ;
-138:__UG_NAME__ -> 139:phase ;
-52:__UG_NAME__ -> 139:bufnum ;
-40:__UG_NAME__ -> 61:in ;
-44:__UG_NAME__ -> 83:in ;
-81:__UG_NAME__ -> 82:gate ;
-8:__UG_NAME__ -> 82:envelope___control___0 ;
-8:__UG_NAME__ -> 82:envelope___control___4 ;
-9:__UG_NAME__ -> 82:envelope___control___5 ;
-10:__UG_NAME__ -> 82:envelope___control___6 ;
-11:__UG_NAME__ -> 82:envelope___control___7 ;
-95:__UG_NAME__ -> 96:gate ;
-12:__UG_NAME__ -> 96:envelope___control___0 ;
-12:__UG_NAME__ -> 96:envelope___control___4 ;
-13:__UG_NAME__ -> 96:envelope___control___5 ;
-14:__UG_NAME__ -> 96:envelope___control___6 ;
-15:__UG_NAME__ -> 96:envelope___control___7 ;
-108:__UG_NAME__ -> 109:gate ;
-24:__UG_NAME__ -> 109:envelope___control___0 ;
-24:__UG_NAME__ -> 109:envelope___control___4 ;
-25:__UG_NAME__ -> 109:envelope___control___5 ;
-26:__UG_NAME__ -> 109:envelope___control___6 ;
-27:__UG_NAME__ -> 109:envelope___control___7 ;
-69:__UG_NAME__ -> 113:gate ;
-61:__UG_NAME__ -> 113:envelope___clip___0 ;
-61:__UG_NAME__ -> 113:envelope___clip___4 ;
-41:__UG_NAME__ -> 113:envelope___control___5 ;
-42:__UG_NAME__ -> 113:envelope___control___6 ;
-43:__UG_NAME__ -> 113:envelope___control___7 ;
-145:__UG_NAME__ -> 146:gate ;
-84:__UG_NAME__ -> 146:envelope___mul____add___0 ;
-84:__UG_NAME__ -> 146:envelope___mul____add___4 ;
-45:__UG_NAME__ -> 146:envelope___control___5 ;
-46:__UG_NAME__ -> 146:envelope___control___6 ;
-47:__UG_NAME__ -> 146:envelope___control___7 ;
-171:__UG_NAME__ -> 172:gate ;
-36:__UG_NAME__ -> 172:envelope___control___0 ;
-36:__UG_NAME__ -> 172:envelope___control___4 ;
-37:__UG_NAME__ -> 172:envelope___control___5 ;
-38:__UG_NAME__ -> 172:envelope___control___6 ;
-39:__UG_NAME__ -> 172:envelope___control___7 ;
-177:__UG_NAME__ -> 178:gate ;
-32:__UG_NAME__ -> 178:envelope___control___0 ;
-32:__UG_NAME__ -> 178:envelope___control___4 ;
-33:__UG_NAME__ -> 178:envelope___control___5 ;
-34:__UG_NAME__ -> 178:envelope___control___6 ;
-35:__UG_NAME__ -> 178:envelope___control___7 ;
-186:__UG_NAME__ -> 187:gate ;
-4:__UG_NAME__ -> 187:envelope___control___0 ;
-4:__UG_NAME__ -> 187:envelope___control___4 ;
-5:__UG_NAME__ -> 187:envelope___control___5 ;
-6:__UG_NAME__ -> 187:envelope___control___6 ;
-7:__UG_NAME__ -> 187:envelope___control___7 ;
-125:__UG_NAME__ -> 189:gate ;
-0:__UG_NAME__ -> 189:envelope___control___0 ;
-0:__UG_NAME__ -> 189:envelope___control___4 ;
-1:__UG_NAME__ -> 189:envelope___control___5 ;
-2:__UG_NAME__ -> 189:envelope___control___6 ;
-3:__UG_NAME__ -> 189:envelope___control___7 ;
-194:__UG_NAME__ -> 195:gate ;
-20:__UG_NAME__ -> 195:envelope___control___0 ;
-20:__UG_NAME__ -> 195:envelope___control___4 ;
-21:__UG_NAME__ -> 195:envelope___control___5 ;
-22:__UG_NAME__ -> 195:envelope___control___6 ;
-23:__UG_NAME__ -> 195:envelope___control___7 ;
-135:__UG_NAME__ -> 196:gate ;
-16:__UG_NAME__ -> 196:envelope___control___0 ;
-16:__UG_NAME__ -> 196:envelope___control___4 ;
-17:__UG_NAME__ -> 196:envelope___control___5 ;
-18:__UG_NAME__ -> 196:envelope___control___6 ;
-19:__UG_NAME__ -> 196:envelope___control___7 ;
-211:__UG_NAME__ -> 212:gate ;
-28:__UG_NAME__ -> 212:envelope___control___0 ;
-28:__UG_NAME__ -> 212:envelope___control___4 ;
-29:__UG_NAME__ -> 212:envelope___control___5 ;
-30:__UG_NAME__ -> 212:envelope___control___6 ;
-31:__UG_NAME__ -> 212:envelope___control___7 ;
-32:__UG_NAME__ -> 56:in ;
-61:__UG_NAME__ -> 62:in ;
-41:__UG_NAME__ -> 66:in ;
-21:__UG_NAME__ -> 71:in ;
-8:__UG_NAME__ -> 74:in ;
-9:__UG_NAME__ -> 78:in ;
-84:__UG_NAME__ -> 85:in ;
-12:__UG_NAME__ -> 88:in ;
-13:__UG_NAME__ -> 92:in ;
-24:__UG_NAME__ -> 99:in ;
-33:__UG_NAME__ -> 102:in ;
-25:__UG_NAME__ -> 105:in ;
-20:__UG_NAME__ -> 115:in ;
-0:__UG_NAME__ -> 118:in ;
-1:__UG_NAME__ -> 122:in ;
-45:__UG_NAME__ -> 126:in ;
-16:__UG_NAME__ -> 128:in ;
-17:__UG_NAME__ -> 132:in ;
-4:__UG_NAME__ -> 162:in ;
-36:__UG_NAME__ -> 164:in ;
-37:__UG_NAME__ -> 168:in ;
-5:__UG_NAME__ -> 183:in ;
-29:__UG_NAME__ -> 188:in ;
-28:__UG_NAME__ -> 205:in ;
-97:__UG_NAME__ -> 98:freq ;
-53:__UG_NAME__ -> 202:bus ;
-212:__UG_NAME__ -> 213:lag____time ;
-204:__UG_NAME__ -> 213:in ;
-172:__UG_NAME__ -> 204:lag____time____down ;
-178:__UG_NAME__ -> 204:lag____time____up ;
-201:__UG_NAME__ -> 204:in ;
-109:__UG_NAME__ -> 154:width ;
-48:__UG_NAME__ -> 154:iphase ;
-97:__UG_NAME__ -> 154:freq ;
-151:__UG_NAME__ -> 152:iphase ;
-97:__UG_NAME__ -> 152:freq ;
-157:__UG_NAME__ -> 158:iphase ;
-97:__UG_NAME__ -> 158:freq ;
-83:__UG_NAME__ -> 84:in ;
-200:__UG_NAME__ -> 201:add ;
-198:__UG_NAME__ -> 201:mul ;
-191:__UG_NAME__ -> 201:in ;
-217:__UG_NAME__ -> 223:signals___x____fade2___0 ;
-222:__UG_NAME__ -> 223:signals___x____fade2___1 ;
-54:__UG_NAME__ -> 223:bus ;
-98:__UG_NAME__ -> 137:trig ;
-153:__UG_NAME__ -> 159:array___binary____op____u____gen___0 ;
-156:__UG_NAME__ -> 159:array___binary____op____u____gen___1 ;
-158:__UG_NAME__ -> 159:array___lf____tri___2 ;
-112:__UG_NAME__ -> 159:array___sin____osc___3 ;
-49:__UG_NAME__ -> 159:which ;
-146:__UG_NAME__ -> 161:array___env____gen___0 ;
-160:__UG_NAME__ -> 161:array___binary____op____u____gen___1 ;
-140:__UG_NAME__ -> 161:which ;
-160:__UG_NAME__ -> 191:array___binary____op____u____gen___0 ;
-161:__UG_NAME__ -> 191:array___select___1 ;
-114:__UG_NAME__ -> 191:which ;
-111:__UG_NAME__ -> 112:phase ;
-97:__UG_NAME__ -> 112:freq ;
-189:__UG_NAME__ -> 217:level ;
-216:__UG_NAME__ -> 217:pan ;
-214:__UG_NAME__ -> 217:inb ;
-203:__UG_NAME__ -> 217:ina ;
-189:__UG_NAME__ -> 222:level ;
-221:__UG_NAME__ -> 222:pan ;
-219:__UG_NAME__ -> 222:inb ;
-218:__UG_NAME__ -> 222:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_tanh.dot b/etc/synthdefs/graphviz/sonic-pi-fx_tanh.dot
deleted file mode 100644
index 3064129..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_tanh.dot
+++ /dev/null
@@ -1,223 +0,0 @@
-digraph synthdef {
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> 8.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-30 [label = "{{ <a> 0.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-19 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :krunch
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :krunch_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :krunch_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :krunch_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-18 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-21 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-20 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-79 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-31 [label = "{{ <which> which|{{<array___env____gen___0>|1.0E-4}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>tanh }" style="filled, bold, rounded"  shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>tanh }" style="filled, bold, rounded"  shape=record rankdir=LR];
-76 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-78 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-42:__UG_NAME__ -> 43:b ;
-41:__UG_NAME__ -> 43:a ;
-43:__UG_NAME__ -> 44:b ;
-31:__UG_NAME__ -> 44:a ;
-42:__UG_NAME__ -> 45:b ;
-41:__UG_NAME__ -> 45:a ;
-45:__UG_NAME__ -> 46:b ;
-31:__UG_NAME__ -> 46:a ;
-50:__UG_NAME__ -> 51:b ;
-48:__UG_NAME__ -> 51:a ;
-59:__UG_NAME__ -> 60:a ;
-50:__UG_NAME__ -> 63:b ;
-62:__UG_NAME__ -> 63:a ;
-59:__UG_NAME__ -> 64:a ;
-23:__UG_NAME__ -> 24:b ;
-20:__UG_NAME__ -> 24:a ;
-27:__UG_NAME__ -> 28:b ;
-24:__UG_NAME__ -> 28:a ;
-35:__UG_NAME__ -> 36:b ;
-32:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:b ;
-36:__UG_NAME__ -> 40:a ;
-49:__UG_NAME__ -> 50:b ;
-55:__UG_NAME__ -> 56:b ;
-52:__UG_NAME__ -> 56:a ;
-57:__UG_NAME__ -> 58:b ;
-56:__UG_NAME__ -> 58:a ;
-69:__UG_NAME__ -> 70:b ;
-66:__UG_NAME__ -> 70:a ;
-73:__UG_NAME__ -> 74:b ;
-70:__UG_NAME__ -> 74:a ;
-64:__UG_NAME__ -> 65:a ;
-60:__UG_NAME__ -> 77:a ;
-31:__UG_NAME__ -> 48:b ;
-47:__UG_NAME__ -> 48:a ;
-31:__UG_NAME__ -> 49:a ;
-31:__UG_NAME__ -> 62:b ;
-61:__UG_NAME__ -> 62:a ;
-29:__UG_NAME__ -> 30:b ;
-22:__UG_NAME__ -> 23:a ;
-26:__UG_NAME__ -> 27:a ;
-34:__UG_NAME__ -> 35:a ;
-38:__UG_NAME__ -> 39:a ;
-54:__UG_NAME__ -> 55:a ;
-19:__UG_NAME__ -> 57:a ;
-68:__UG_NAME__ -> 69:a ;
-72:__UG_NAME__ -> 73:a ;
-18:__UG_NAME__ -> 19:a ;
-21:__UG_NAME__ -> 22:a ;
-25:__UG_NAME__ -> 26:a ;
-33:__UG_NAME__ -> 34:a ;
-37:__UG_NAME__ -> 38:a ;
-53:__UG_NAME__ -> 54:a ;
-67:__UG_NAME__ -> 68:a ;
-71:__UG_NAME__ -> 72:a ;
-28:__UG_NAME__ -> 29:gate ;
-8:__UG_NAME__ -> 29:envelope___control___0 ;
-8:__UG_NAME__ -> 29:envelope___control___4 ;
-9:__UG_NAME__ -> 29:envelope___control___5 ;
-10:__UG_NAME__ -> 29:envelope___control___6 ;
-11:__UG_NAME__ -> 29:envelope___control___7 ;
-40:__UG_NAME__ -> 41:gate ;
-12:__UG_NAME__ -> 41:envelope___control___0 ;
-12:__UG_NAME__ -> 41:envelope___control___4 ;
-13:__UG_NAME__ -> 41:envelope___control___5 ;
-14:__UG_NAME__ -> 41:envelope___control___6 ;
-15:__UG_NAME__ -> 41:envelope___control___7 ;
-58:__UG_NAME__ -> 59:gate ;
-4:__UG_NAME__ -> 59:envelope___control___0 ;
-4:__UG_NAME__ -> 59:envelope___control___4 ;
-5:__UG_NAME__ -> 59:envelope___control___5 ;
-6:__UG_NAME__ -> 59:envelope___control___6 ;
-7:__UG_NAME__ -> 59:envelope___control___7 ;
-74:__UG_NAME__ -> 75:gate ;
-0:__UG_NAME__ -> 75:envelope___control___0 ;
-0:__UG_NAME__ -> 75:envelope___control___4 ;
-1:__UG_NAME__ -> 75:envelope___control___5 ;
-2:__UG_NAME__ -> 75:envelope___control___6 ;
-3:__UG_NAME__ -> 75:envelope___control___7 ;
-5:__UG_NAME__ -> 18:in ;
-8:__UG_NAME__ -> 21:in ;
-9:__UG_NAME__ -> 25:in ;
-12:__UG_NAME__ -> 33:in ;
-13:__UG_NAME__ -> 37:in ;
-4:__UG_NAME__ -> 53:in ;
-0:__UG_NAME__ -> 67:in ;
-1:__UG_NAME__ -> 71:in ;
-16:__UG_NAME__ -> 42:bus ;
-76:__UG_NAME__ -> 79:signals___x____fade2___0 ;
-78:__UG_NAME__ -> 79:signals___x____fade2___1 ;
-17:__UG_NAME__ -> 79:bus ;
-29:__UG_NAME__ -> 31:array___env____gen___0 ;
-30:__UG_NAME__ -> 31:which ;
-46:__UG_NAME__ -> 47:a ;
-44:__UG_NAME__ -> 61:a ;
-75:__UG_NAME__ -> 76:level ;
-65:__UG_NAME__ -> 76:pan ;
-63:__UG_NAME__ -> 76:inb ;
-43:__UG_NAME__ -> 76:ina ;
-75:__UG_NAME__ -> 78:level ;
-77:__UG_NAME__ -> 78:pan ;
-51:__UG_NAME__ -> 78:inb ;
-45:__UG_NAME__ -> 78:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-fx_wobble.dot b/etc/synthdefs/graphviz/sonic-pi-fx_wobble.dot
deleted file mode 100644
index 6950b44..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-fx_wobble.dot
+++ /dev/null
@@ -1,670 +0,0 @@
-digraph synthdef {
-80 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-111 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-130 [label = "{{ <a> |<b> 6.2831855} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-133 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-221 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-234 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-238 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-135 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-143 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-147 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-155 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-159 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-164 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-168 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-176 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-180 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-186 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-190 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-197 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-201 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-209 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-213 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-219 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-226 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-229 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-126 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-222 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-239 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-137 [label = "{{ <a> |<b> } |<__UG_NAME__>\< }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-146 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-154 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-158 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-163 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-167 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-175 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-179 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-185 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-189 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-196 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-200 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-208 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-212 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-218 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-225 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-228 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-145 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-153 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-157 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-166 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-174 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-178 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-184 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-188 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-195 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-199 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-207 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-211 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-224 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-227 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-136 [label = "{{ <num____channels> num-channels 1|<bufnum> bufnum|<phase> phase|<loop> loop 1.0|<interpolation> interpolation 2.0} |<__UG_NAME__>buf-rd }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <in> in|<lo> lo 0.0|<hi> hi 1.0} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <in> in|<lo> lo 0.0|<hi> hi 1.0} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :mix
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :mix_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :mix_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :mix_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pre_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :phase
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :phase_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :phase_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :phase_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :cutoff_min
- default: 60.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :cutoff_min_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :cutoff_min_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :cutoff_min_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff_max
- default: 120.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_max_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_max_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_max_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :res
- default: 0.8" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :filter
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :smooth
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :smooth_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :smooth_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :smooth_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "control
- :smooth_up
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "control
- :smooth_up_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "control
- :smooth_up_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-40 [label = "control
- :smooth_up_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-41 [label = "control
- :smooth_down
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "control
- :smooth_down_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-43 [label = "control
- :smooth_down_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-44 [label = "control
- :smooth_down_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-45 [label = "control
- :phase_offset
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-46 [label = "control
- :wave
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-47 [label = "control
- :invert_wave
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-48 [label = "control
- :probability
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-49 [label = "control
- :probability_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-50 [label = "control
- :probability_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-51 [label = "control
- :probability_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-52 [label = "control
- :prob_pos
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-53 [label = "control
- :prob_pos_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-54 [label = "control
- :prob_pos_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-55 [label = "control
- :prob_pos_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-56 [label = "control
- :seed
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-57 [label = "control
- :rand_buf
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-58 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-59 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-70 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ {{<envelope___clip___0>|1.0|-99|-99|<envelope___clip___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-148 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-160 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-169 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-181 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-191 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-202 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-214 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-220 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-230 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-152 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-156 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-165 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-173 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-177 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-183 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-187 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-194 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-198 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-206 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-210 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-216 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-217 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <freq> freq|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-138 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-151 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-162 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-172 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-182 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-193 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-204 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-223 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-203 [label = "{{ <in> in|<lag____time> lag-time} |<__UG_NAME__>lag }" style="bold, rounded" shape=record rankdir=LR];
-192 [label = "{{ <in> in|<lag____time____up> lag-time-up|<lag____time____down> lag-time-down} |<__UG_NAME__>lag-ud }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <freq> freq|<iphase> iphase|<width> width} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
-171 [label = "{{ <in> in|<srclo> srclo -1.0|<srchi> srchi 1.0|<dstlo> dstlo|<dsthi> dsthi} |<__UG_NAME__>lin-exp }" style="bold, rounded" shape=record rankdir=LR];
-161 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-170 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-139 [label = "{{ <in> in|<mul> mul 2.0|<add> add -1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-205 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-241 [label = "{{ <bus> bus|{{<signals___x____fade2___0>|<signals___x____fade2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-134 [label = "{{ <trig> trig|<reset> reset 0.0} |<__UG_NAME__>pulse-count }" style="bold, rounded" shape=record rankdir=LR];
-215 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rhpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-236 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rhpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-231 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-235 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-132 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-149 [label = "{{ <which> which|{{<array___env____gen___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-150 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-232 [label = "{{ <which> which|{{<array___rlpf___0>|<array___rhpf___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-237 [label = "{{ <which> which|{{<array___rlpf___0>|<array___rhpf___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-131 [label = "{{ <freq> freq|<phase> phase|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-233 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-240 [label = "{{ <ina> inA|<inb> inB|<pan> pan|<level> level} |<__UG_NAME__>x-fade2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-45:__UG_NAME__ -> 80:b ;
-82:__UG_NAME__ -> 83:b ;
-96:__UG_NAME__ -> 97:b ;
-95:__UG_NAME__ -> 97:a ;
-110:__UG_NAME__ -> 111:b ;
-112:__UG_NAME__ -> 113:b ;
-124:__UG_NAME__ -> 125:b ;
-129:__UG_NAME__ -> 130:a ;
-132:__UG_NAME__ -> 133:b ;
-113:__UG_NAME__ -> 133:a ;
-220:__UG_NAME__ -> 221:a ;
-96:__UG_NAME__ -> 234:b ;
-95:__UG_NAME__ -> 234:a ;
-220:__UG_NAME__ -> 238:a ;
-64:__UG_NAME__ -> 65:b ;
-61:__UG_NAME__ -> 65:a ;
-68:__UG_NAME__ -> 69:b ;
-65:__UG_NAME__ -> 69:a ;
-76:__UG_NAME__ -> 77:b ;
-73:__UG_NAME__ -> 77:a ;
-80:__UG_NAME__ -> 81:a ;
-92:__UG_NAME__ -> 93:b ;
-89:__UG_NAME__ -> 93:a ;
-86:__UG_NAME__ -> 94:b ;
-93:__UG_NAME__ -> 94:a ;
-102:__UG_NAME__ -> 103:b ;
-98:__UG_NAME__ -> 103:a ;
-106:__UG_NAME__ -> 107:b ;
-103:__UG_NAME__ -> 107:a ;
-117:__UG_NAME__ -> 118:b ;
-114:__UG_NAME__ -> 118:a ;
-121:__UG_NAME__ -> 122:b ;
-118:__UG_NAME__ -> 122:a ;
-80:__UG_NAME__ -> 127:a ;
-45:__UG_NAME__ -> 129:a ;
-134:__UG_NAME__ -> 135:b ;
-56:__UG_NAME__ -> 135:a ;
-142:__UG_NAME__ -> 143:b ;
-138:__UG_NAME__ -> 143:a ;
-146:__UG_NAME__ -> 147:b ;
-143:__UG_NAME__ -> 147:a ;
-154:__UG_NAME__ -> 155:b ;
-151:__UG_NAME__ -> 155:a ;
-158:__UG_NAME__ -> 159:b ;
-155:__UG_NAME__ -> 159:a ;
-163:__UG_NAME__ -> 164:b ;
-162:__UG_NAME__ -> 164:a ;
-167:__UG_NAME__ -> 168:b ;
-164:__UG_NAME__ -> 168:a ;
-175:__UG_NAME__ -> 176:b ;
-172:__UG_NAME__ -> 176:a ;
-179:__UG_NAME__ -> 180:b ;
-176:__UG_NAME__ -> 180:a ;
-185:__UG_NAME__ -> 186:b ;
-182:__UG_NAME__ -> 186:a ;
-189:__UG_NAME__ -> 190:b ;
-186:__UG_NAME__ -> 190:a ;
-196:__UG_NAME__ -> 197:b ;
-193:__UG_NAME__ -> 197:a ;
-200:__UG_NAME__ -> 201:b ;
-197:__UG_NAME__ -> 201:a ;
-208:__UG_NAME__ -> 209:b ;
-204:__UG_NAME__ -> 209:a ;
-212:__UG_NAME__ -> 213:b ;
-209:__UG_NAME__ -> 213:a ;
-218:__UG_NAME__ -> 219:b ;
-77:__UG_NAME__ -> 219:a ;
-225:__UG_NAME__ -> 226:b ;
-223:__UG_NAME__ -> 226:a ;
-228:__UG_NAME__ -> 229:b ;
-226:__UG_NAME__ -> 229:a ;
-111:__UG_NAME__ -> 112:a ;
-125:__UG_NAME__ -> 126:a ;
-221:__UG_NAME__ -> 222:a ;
-238:__UG_NAME__ -> 239:a ;
-70:__UG_NAME__ -> 71:b ;
-108:__UG_NAME__ -> 137:b ;
-136:__UG_NAME__ -> 137:a ;
-63:__UG_NAME__ -> 64:a ;
-67:__UG_NAME__ -> 68:a ;
-75:__UG_NAME__ -> 76:a ;
-85:__UG_NAME__ -> 86:a ;
-91:__UG_NAME__ -> 92:a ;
-101:__UG_NAME__ -> 102:a ;
-105:__UG_NAME__ -> 106:a ;
-108:__UG_NAME__ -> 109:a ;
-47:__UG_NAME__ -> 110:a ;
-116:__UG_NAME__ -> 117:a ;
-120:__UG_NAME__ -> 121:a ;
-141:__UG_NAME__ -> 142:a ;
-145:__UG_NAME__ -> 146:a ;
-153:__UG_NAME__ -> 154:a ;
-157:__UG_NAME__ -> 158:a ;
-79:__UG_NAME__ -> 163:a ;
-166:__UG_NAME__ -> 167:a ;
-174:__UG_NAME__ -> 175:a ;
-178:__UG_NAME__ -> 179:a ;
-184:__UG_NAME__ -> 185:a ;
-188:__UG_NAME__ -> 189:a ;
-195:__UG_NAME__ -> 196:a ;
-199:__UG_NAME__ -> 200:a ;
-207:__UG_NAME__ -> 208:a ;
-211:__UG_NAME__ -> 212:a ;
-88:__UG_NAME__ -> 218:a ;
-224:__UG_NAME__ -> 225:a ;
-227:__UG_NAME__ -> 228:a ;
-62:__UG_NAME__ -> 63:a ;
-66:__UG_NAME__ -> 67:a ;
-74:__UG_NAME__ -> 75:a ;
-78:__UG_NAME__ -> 79:a ;
-84:__UG_NAME__ -> 85:a ;
-87:__UG_NAME__ -> 88:a ;
-90:__UG_NAME__ -> 91:a ;
-100:__UG_NAME__ -> 101:a ;
-104:__UG_NAME__ -> 105:a ;
-115:__UG_NAME__ -> 116:a ;
-119:__UG_NAME__ -> 120:a ;
-140:__UG_NAME__ -> 141:a ;
-144:__UG_NAME__ -> 145:a ;
-152:__UG_NAME__ -> 153:a ;
-156:__UG_NAME__ -> 157:a ;
-165:__UG_NAME__ -> 166:a ;
-173:__UG_NAME__ -> 174:a ;
-177:__UG_NAME__ -> 178:a ;
-183:__UG_NAME__ -> 184:a ;
-187:__UG_NAME__ -> 188:a ;
-194:__UG_NAME__ -> 195:a ;
-198:__UG_NAME__ -> 199:a ;
-206:__UG_NAME__ -> 207:a ;
-210:__UG_NAME__ -> 211:a ;
-216:__UG_NAME__ -> 224:a ;
-217:__UG_NAME__ -> 227:a ;
-135:__UG_NAME__ -> 136:phase ;
-57:__UG_NAME__ -> 136:bufnum ;
-52:__UG_NAME__ -> 60:in ;
-48:__UG_NAME__ -> 99:in ;
-69:__UG_NAME__ -> 70:gate ;
-12:__UG_NAME__ -> 70:envelope___control___0 ;
-12:__UG_NAME__ -> 70:envelope___control___4 ;
-13:__UG_NAME__ -> 70:envelope___control___5 ;
-14:__UG_NAME__ -> 70:envelope___control___6 ;
-15:__UG_NAME__ -> 70:envelope___control___7 ;
-94:__UG_NAME__ -> 95:gate ;
-8:__UG_NAME__ -> 95:envelope___control___0 ;
-8:__UG_NAME__ -> 95:envelope___control___4 ;
-9:__UG_NAME__ -> 95:envelope___control___5 ;
-10:__UG_NAME__ -> 95:envelope___control___6 ;
-11:__UG_NAME__ -> 95:envelope___control___7 ;
-107:__UG_NAME__ -> 108:gate ;
-99:__UG_NAME__ -> 108:envelope___clip___0 ;
-99:__UG_NAME__ -> 108:envelope___clip___4 ;
-49:__UG_NAME__ -> 108:envelope___control___5 ;
-50:__UG_NAME__ -> 108:envelope___control___6 ;
-51:__UG_NAME__ -> 108:envelope___control___7 ;
-122:__UG_NAME__ -> 123:gate ;
-28:__UG_NAME__ -> 123:envelope___control___0 ;
-28:__UG_NAME__ -> 123:envelope___control___4 ;
-29:__UG_NAME__ -> 123:envelope___control___5 ;
-30:__UG_NAME__ -> 123:envelope___control___6 ;
-31:__UG_NAME__ -> 123:envelope___control___7 ;
-147:__UG_NAME__ -> 148:gate ;
-139:__UG_NAME__ -> 148:envelope___mul____add___0 ;
-139:__UG_NAME__ -> 148:envelope___mul____add___4 ;
-53:__UG_NAME__ -> 148:envelope___control___5 ;
-54:__UG_NAME__ -> 148:envelope___control___6 ;
-55:__UG_NAME__ -> 148:envelope___control___7 ;
-159:__UG_NAME__ -> 160:gate ;
-16:__UG_NAME__ -> 160:envelope___control___0 ;
-16:__UG_NAME__ -> 160:envelope___control___4 ;
-17:__UG_NAME__ -> 160:envelope___control___5 ;
-18:__UG_NAME__ -> 160:envelope___control___6 ;
-19:__UG_NAME__ -> 160:envelope___control___7 ;
-168:__UG_NAME__ -> 169:gate ;
-20:__UG_NAME__ -> 169:envelope___control___0 ;
-20:__UG_NAME__ -> 169:envelope___control___4 ;
-21:__UG_NAME__ -> 169:envelope___control___5 ;
-22:__UG_NAME__ -> 169:envelope___control___6 ;
-23:__UG_NAME__ -> 169:envelope___control___7 ;
-180:__UG_NAME__ -> 181:gate ;
-37:__UG_NAME__ -> 181:envelope___control___0 ;
-37:__UG_NAME__ -> 181:envelope___control___4 ;
-38:__UG_NAME__ -> 181:envelope___control___5 ;
-39:__UG_NAME__ -> 181:envelope___control___6 ;
-40:__UG_NAME__ -> 181:envelope___control___7 ;
-190:__UG_NAME__ -> 191:gate ;
-41:__UG_NAME__ -> 191:envelope___control___0 ;
-41:__UG_NAME__ -> 191:envelope___control___4 ;
-42:__UG_NAME__ -> 191:envelope___control___5 ;
-43:__UG_NAME__ -> 191:envelope___control___6 ;
-44:__UG_NAME__ -> 191:envelope___control___7 ;
-201:__UG_NAME__ -> 202:gate ;
-33:__UG_NAME__ -> 202:envelope___control___0 ;
-33:__UG_NAME__ -> 202:envelope___control___4 ;
-34:__UG_NAME__ -> 202:envelope___control___5 ;
-35:__UG_NAME__ -> 202:envelope___control___6 ;
-36:__UG_NAME__ -> 202:envelope___control___7 ;
-213:__UG_NAME__ -> 214:gate ;
-205:__UG_NAME__ -> 214:envelope___mul____add___0 ;
-205:__UG_NAME__ -> 214:envelope___mul____add___4 ;
-25:__UG_NAME__ -> 214:envelope___control___5 ;
-26:__UG_NAME__ -> 214:envelope___control___6 ;
-27:__UG_NAME__ -> 214:envelope___control___7 ;
-219:__UG_NAME__ -> 220:gate ;
-4:__UG_NAME__ -> 220:envelope___control___0 ;
-4:__UG_NAME__ -> 220:envelope___control___4 ;
-5:__UG_NAME__ -> 220:envelope___control___5 ;
-6:__UG_NAME__ -> 220:envelope___control___6 ;
-7:__UG_NAME__ -> 220:envelope___control___7 ;
-229:__UG_NAME__ -> 230:gate ;
-0:__UG_NAME__ -> 230:envelope___control___0 ;
-0:__UG_NAME__ -> 230:envelope___control___4 ;
-1:__UG_NAME__ -> 230:envelope___control___5 ;
-2:__UG_NAME__ -> 230:envelope___control___6 ;
-3:__UG_NAME__ -> 230:envelope___control___7 ;
-12:__UG_NAME__ -> 62:in ;
-13:__UG_NAME__ -> 66:in ;
-4:__UG_NAME__ -> 74:in ;
-20:__UG_NAME__ -> 78:in ;
-9:__UG_NAME__ -> 84:in ;
-5:__UG_NAME__ -> 87:in ;
-8:__UG_NAME__ -> 90:in ;
-99:__UG_NAME__ -> 100:in ;
-49:__UG_NAME__ -> 104:in ;
-28:__UG_NAME__ -> 115:in ;
-29:__UG_NAME__ -> 119:in ;
-139:__UG_NAME__ -> 140:in ;
-53:__UG_NAME__ -> 144:in ;
-16:__UG_NAME__ -> 152:in ;
-17:__UG_NAME__ -> 156:in ;
-21:__UG_NAME__ -> 165:in ;
-37:__UG_NAME__ -> 173:in ;
-38:__UG_NAME__ -> 177:in ;
-41:__UG_NAME__ -> 183:in ;
-42:__UG_NAME__ -> 187:in ;
-33:__UG_NAME__ -> 194:in ;
-34:__UG_NAME__ -> 198:in ;
-205:__UG_NAME__ -> 206:in ;
-25:__UG_NAME__ -> 210:in ;
-0:__UG_NAME__ -> 216:in ;
-1:__UG_NAME__ -> 217:in ;
-71:__UG_NAME__ -> 72:freq ;
-58:__UG_NAME__ -> 96:bus ;
-202:__UG_NAME__ -> 203:lag____time ;
-192:__UG_NAME__ -> 203:in ;
-191:__UG_NAME__ -> 192:lag____time____down ;
-181:__UG_NAME__ -> 192:lag____time____up ;
-171:__UG_NAME__ -> 192:in ;
-123:__UG_NAME__ -> 124:width ;
-45:__UG_NAME__ -> 124:iphase ;
-71:__UG_NAME__ -> 124:freq ;
-81:__UG_NAME__ -> 82:iphase ;
-71:__UG_NAME__ -> 82:freq ;
-127:__UG_NAME__ -> 128:iphase ;
-71:__UG_NAME__ -> 128:freq ;
-170:__UG_NAME__ -> 171:dsthi ;
-161:__UG_NAME__ -> 171:dstlo ;
-150:__UG_NAME__ -> 171:in ;
-160:__UG_NAME__ -> 161:a ;
-169:__UG_NAME__ -> 170:a ;
-60:__UG_NAME__ -> 139:in ;
-24:__UG_NAME__ -> 205:in ;
-233:__UG_NAME__ -> 241:signals___x____fade2___0 ;
-240:__UG_NAME__ -> 241:signals___x____fade2___1 ;
-59:__UG_NAME__ -> 241:bus ;
-72:__UG_NAME__ -> 134:trig ;
-214:__UG_NAME__ -> 215:rq ;
-203:__UG_NAME__ -> 215:freq ;
-97:__UG_NAME__ -> 215:in ;
-214:__UG_NAME__ -> 236:rq ;
-203:__UG_NAME__ -> 236:freq ;
-234:__UG_NAME__ -> 236:in ;
-214:__UG_NAME__ -> 231:rq ;
-203:__UG_NAME__ -> 231:freq ;
-97:__UG_NAME__ -> 231:in ;
-214:__UG_NAME__ -> 235:rq ;
-203:__UG_NAME__ -> 235:freq ;
-234:__UG_NAME__ -> 235:in ;
-83:__UG_NAME__ -> 132:array___binary____op____u____gen___0 ;
-126:__UG_NAME__ -> 132:array___binary____op____u____gen___1 ;
-128:__UG_NAME__ -> 132:array___lf____tri___2 ;
-131:__UG_NAME__ -> 132:array___sin____osc___3 ;
-46:__UG_NAME__ -> 132:which ;
-148:__UG_NAME__ -> 149:array___env____gen___0 ;
-133:__UG_NAME__ -> 149:array___binary____op____u____gen___1 ;
-137:__UG_NAME__ -> 149:which ;
-133:__UG_NAME__ -> 150:array___binary____op____u____gen___0 ;
-149:__UG_NAME__ -> 150:array___select___1 ;
-109:__UG_NAME__ -> 150:which ;
-231:__UG_NAME__ -> 232:array___rlpf___0 ;
-215:__UG_NAME__ -> 232:array___rhpf___1 ;
-32:__UG_NAME__ -> 232:which ;
-235:__UG_NAME__ -> 237:array___rlpf___0 ;
-236:__UG_NAME__ -> 237:array___rhpf___1 ;
-32:__UG_NAME__ -> 237:which ;
-130:__UG_NAME__ -> 131:phase ;
-71:__UG_NAME__ -> 131:freq ;
-230:__UG_NAME__ -> 233:level ;
-222:__UG_NAME__ -> 233:pan ;
-232:__UG_NAME__ -> 233:inb ;
-97:__UG_NAME__ -> 233:ina ;
-230:__UG_NAME__ -> 240:level ;
-239:__UG_NAME__ -> 240:pan ;
-237:__UG_NAME__ -> 240:inb ;
-234:__UG_NAME__ -> 240:ina ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-gnoise.dot b/etc/synthdefs/graphviz/sonic-pi-gnoise.dot
deleted file mode 100644
index 8c9ebbc..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-gnoise.dot
+++ /dev/null
@@ -1,223 +0,0 @@
-digraph synthdef {
-71 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :cutoff
- default: 110.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :res
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{<__UG_NAME__>gray-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
-25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-74 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-70 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-39 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-
-70:__UG_NAME__ -> 71:b ;
-40:__UG_NAME__ -> 72:b ;
-71:__UG_NAME__ -> 72:a ;
-31:__UG_NAME__ -> 32:b ;
-28:__UG_NAME__ -> 32:a ;
-35:__UG_NAME__ -> 36:b ;
-32:__UG_NAME__ -> 36:a ;
-46:__UG_NAME__ -> 47:b ;
-42:__UG_NAME__ -> 47:a ;
-50:__UG_NAME__ -> 51:b ;
-47:__UG_NAME__ -> 51:a ;
-59:__UG_NAME__ -> 60:b ;
-56:__UG_NAME__ -> 60:a ;
-63:__UG_NAME__ -> 64:b ;
-53:__UG_NAME__ -> 64:a ;
-55:__UG_NAME__ -> 65:b ;
-64:__UG_NAME__ -> 65:a ;
-27:__UG_NAME__ -> 68:b ;
-60:__UG_NAME__ -> 68:a ;
-13:__UG_NAME__ -> 38:b ;
-26:__UG_NAME__ -> 27:a ;
-30:__UG_NAME__ -> 31:a ;
-34:__UG_NAME__ -> 35:a ;
-45:__UG_NAME__ -> 46:a ;
-49:__UG_NAME__ -> 50:a ;
-54:__UG_NAME__ -> 55:a ;
-58:__UG_NAME__ -> 59:a ;
-62:__UG_NAME__ -> 63:a ;
-25:__UG_NAME__ -> 26:a ;
-29:__UG_NAME__ -> 30:a ;
-33:__UG_NAME__ -> 34:a ;
-44:__UG_NAME__ -> 45:a ;
-48:__UG_NAME__ -> 49:a ;
-41:__UG_NAME__ -> 54:a ;
-57:__UG_NAME__ -> 58:a ;
-61:__UG_NAME__ -> 62:a ;
-36:__UG_NAME__ -> 37:gate ;
-0:__UG_NAME__ -> 37:envelope___control___0 ;
-0:__UG_NAME__ -> 37:envelope___control___4 ;
-1:__UG_NAME__ -> 37:envelope___control___5 ;
-2:__UG_NAME__ -> 37:envelope___control___6 ;
-3:__UG_NAME__ -> 37:envelope___control___7 ;
-12:__UG_NAME__ -> 40:envelope___control___4 ;
-8:__UG_NAME__ -> 40:envelope___control___5 ;
-15:__UG_NAME__ -> 40:envelope___control___6 ;
-39:__UG_NAME__ -> 40:envelope___select___8 ;
-10:__UG_NAME__ -> 40:envelope___control___9 ;
-15:__UG_NAME__ -> 40:envelope___control___10 ;
-14:__UG_NAME__ -> 40:envelope___control___12 ;
-9:__UG_NAME__ -> 40:envelope___control___13 ;
-15:__UG_NAME__ -> 40:envelope___control___14 ;
-11:__UG_NAME__ -> 40:envelope___control___17 ;
-15:__UG_NAME__ -> 40:envelope___control___18 ;
-51:__UG_NAME__ -> 52:gate ;
-43:__UG_NAME__ -> 52:envelope___mul____add___0 ;
-43:__UG_NAME__ -> 52:envelope___mul____add___4 ;
-21:__UG_NAME__ -> 52:envelope___control___5 ;
-22:__UG_NAME__ -> 52:envelope___control___6 ;
-23:__UG_NAME__ -> 52:envelope___control___7 ;
-65:__UG_NAME__ -> 66:gate ;
-16:__UG_NAME__ -> 66:envelope___control___0 ;
-16:__UG_NAME__ -> 66:envelope___control___4 ;
-17:__UG_NAME__ -> 66:envelope___control___5 ;
-18:__UG_NAME__ -> 66:envelope___control___6 ;
-19:__UG_NAME__ -> 66:envelope___control___7 ;
-68:__UG_NAME__ -> 73:gate ;
-4:__UG_NAME__ -> 73:envelope___control___0 ;
-4:__UG_NAME__ -> 73:envelope___control___4 ;
-5:__UG_NAME__ -> 73:envelope___control___5 ;
-6:__UG_NAME__ -> 73:envelope___control___6 ;
-7:__UG_NAME__ -> 73:envelope___control___7 ;
-5:__UG_NAME__ -> 25:in ;
-0:__UG_NAME__ -> 29:in ;
-1:__UG_NAME__ -> 33:in ;
-17:__UG_NAME__ -> 41:in ;
-43:__UG_NAME__ -> 44:in ;
-21:__UG_NAME__ -> 48:in ;
-4:__UG_NAME__ -> 57:in ;
-16:__UG_NAME__ -> 61:in ;
-66:__UG_NAME__ -> 67:a ;
-20:__UG_NAME__ -> 43:in ;
-74:__UG_NAME__ -> 75:signals___pan2___0 ;
-74:__UG_NAME__ -> 75:signals___pan2___1 ;
-24:__UG_NAME__ -> 75:bus ;
-37:__UG_NAME__ -> 74:level ;
-73:__UG_NAME__ -> 74:pos ;
-72:__UG_NAME__ -> 74:in ;
-52:__UG_NAME__ -> 70:rq ;
-67:__UG_NAME__ -> 70:freq ;
-69:__UG_NAME__ -> 70:in ;
-13:__UG_NAME__ -> 39:array___control___0 ;
-14:__UG_NAME__ -> 39:array___control___1 ;
-38:__UG_NAME__ -> 39:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-growl.dot b/etc/synthdefs/graphviz/sonic-pi-growl.dot
deleted file mode 100644
index 1990ba6..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-growl.dot
+++ /dev/null
@@ -1,282 +0,0 @@
-digraph synthdef {
-43 [label = "{{ <a> 0.25|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> 1.01|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> 0.5} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-75 [label = "{{ <a> 3.0|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :attack
- default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff
- default: 130.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :res
- default: 0.7" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-41 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in|<freq> freq 440.0} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <bus> bus|{{<signals___binary____op____u____gen___0>|<signals___binary____op____u____gen___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-95 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-50 [label = "{{ <in> in|<window____size> window-size 0.5|<pitch____ratio> pitch-ratio 1.0|<pitch____dispersion> pitch-dispersion 0.0|<time____dispersion> time-dispersion 0.001} |<__UG_NAME__>pitch-shift }" style="filled, bold, rounded"  shape=record rankdir=LR];
-74 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-44 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-83 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-42:__UG_NAME__ -> 43:b ;
-42:__UG_NAME__ -> 45:b ;
-47:__UG_NAME__ -> 48:a ;
-74:__UG_NAME__ -> 75:b ;
-95:__UG_NAME__ -> 96:b ;
-84:__UG_NAME__ -> 96:a ;
-95:__UG_NAME__ -> 97:b ;
-84:__UG_NAME__ -> 97:a ;
-35:__UG_NAME__ -> 36:b ;
-32:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:b ;
-36:__UG_NAME__ -> 40:a ;
-46:__UG_NAME__ -> 47:b ;
-44:__UG_NAME__ -> 47:a ;
-59:__UG_NAME__ -> 60:b ;
-56:__UG_NAME__ -> 60:a ;
-63:__UG_NAME__ -> 64:b ;
-60:__UG_NAME__ -> 64:a ;
-52:__UG_NAME__ -> 68:b ;
-67:__UG_NAME__ -> 68:a ;
-71:__UG_NAME__ -> 72:b ;
-68:__UG_NAME__ -> 72:a ;
-55:__UG_NAME__ -> 77:b ;
-76:__UG_NAME__ -> 77:a ;
-80:__UG_NAME__ -> 81:b ;
-77:__UG_NAME__ -> 81:a ;
-88:__UG_NAME__ -> 89:b ;
-85:__UG_NAME__ -> 89:a ;
-92:__UG_NAME__ -> 93:b ;
-89:__UG_NAME__ -> 93:a ;
-18:__UG_NAME__ -> 31:b ;
-34:__UG_NAME__ -> 35:a ;
-38:__UG_NAME__ -> 39:a ;
-51:__UG_NAME__ -> 52:a ;
-54:__UG_NAME__ -> 55:a ;
-58:__UG_NAME__ -> 59:a ;
-62:__UG_NAME__ -> 63:a ;
-70:__UG_NAME__ -> 71:a ;
-79:__UG_NAME__ -> 80:a ;
-87:__UG_NAME__ -> 88:a ;
-91:__UG_NAME__ -> 92:a ;
-33:__UG_NAME__ -> 34:a ;
-37:__UG_NAME__ -> 38:a ;
-30:__UG_NAME__ -> 51:a ;
-53:__UG_NAME__ -> 54:a ;
-57:__UG_NAME__ -> 58:a ;
-61:__UG_NAME__ -> 62:a ;
-69:__UG_NAME__ -> 70:a ;
-78:__UG_NAME__ -> 79:a ;
-86:__UG_NAME__ -> 87:a ;
-90:__UG_NAME__ -> 91:a ;
-40:__UG_NAME__ -> 41:gate ;
-1:__UG_NAME__ -> 41:envelope___control___0 ;
-1:__UG_NAME__ -> 41:envelope___control___4 ;
-2:__UG_NAME__ -> 41:envelope___control___5 ;
-3:__UG_NAME__ -> 41:envelope___control___6 ;
-4:__UG_NAME__ -> 41:envelope___control___7 ;
-64:__UG_NAME__ -> 65:gate ;
-21:__UG_NAME__ -> 65:envelope___control___0 ;
-21:__UG_NAME__ -> 65:envelope___control___4 ;
-22:__UG_NAME__ -> 65:envelope___control___5 ;
-23:__UG_NAME__ -> 65:envelope___control___6 ;
-24:__UG_NAME__ -> 65:envelope___control___7 ;
-72:__UG_NAME__ -> 73:gate ;
-29:__UG_NAME__ -> 73:envelope___mul____add___0 ;
-29:__UG_NAME__ -> 73:envelope___mul____add___4 ;
-26:__UG_NAME__ -> 73:envelope___control___5 ;
-27:__UG_NAME__ -> 73:envelope___control___6 ;
-28:__UG_NAME__ -> 73:envelope___control___7 ;
-81:__UG_NAME__ -> 82:gate ;
-9:__UG_NAME__ -> 82:envelope___control___0 ;
-9:__UG_NAME__ -> 82:envelope___control___4 ;
-10:__UG_NAME__ -> 82:envelope___control___5 ;
-11:__UG_NAME__ -> 82:envelope___control___6 ;
-12:__UG_NAME__ -> 82:envelope___control___7 ;
-17:__UG_NAME__ -> 84:envelope___control___4 ;
-13:__UG_NAME__ -> 84:envelope___control___5 ;
-20:__UG_NAME__ -> 84:envelope___control___6 ;
-83:__UG_NAME__ -> 84:envelope___select___8 ;
-14:__UG_NAME__ -> 84:envelope___control___9 ;
-20:__UG_NAME__ -> 84:envelope___control___10 ;
-19:__UG_NAME__ -> 84:envelope___control___12 ;
-15:__UG_NAME__ -> 84:envelope___control___13 ;
-20:__UG_NAME__ -> 84:envelope___control___14 ;
-16:__UG_NAME__ -> 84:envelope___control___17 ;
-20:__UG_NAME__ -> 84:envelope___control___18 ;
-93:__UG_NAME__ -> 94:gate ;
-5:__UG_NAME__ -> 94:envelope___control___0 ;
-5:__UG_NAME__ -> 94:envelope___control___4 ;
-6:__UG_NAME__ -> 94:envelope___control___5 ;
-7:__UG_NAME__ -> 94:envelope___control___6 ;
-8:__UG_NAME__ -> 94:envelope___control___7 ;
-29:__UG_NAME__ -> 30:in ;
-1:__UG_NAME__ -> 33:in ;
-2:__UG_NAME__ -> 37:in ;
-9:__UG_NAME__ -> 53:in ;
-21:__UG_NAME__ -> 57:in ;
-22:__UG_NAME__ -> 61:in ;
-26:__UG_NAME__ -> 69:in ;
-10:__UG_NAME__ -> 78:in ;
-5:__UG_NAME__ -> 86:in ;
-6:__UG_NAME__ -> 90:in ;
-48:__UG_NAME__ -> 49:in ;
-41:__UG_NAME__ -> 42:a ;
-65:__UG_NAME__ -> 66:a ;
-25:__UG_NAME__ -> 29:in ;
-96:__UG_NAME__ -> 98:signals___binary____op____u____gen___0 ;
-97:__UG_NAME__ -> 98:signals___binary____op____u____gen___1 ;
-0:__UG_NAME__ -> 98:bus ;
-82:__UG_NAME__ -> 95:level ;
-94:__UG_NAME__ -> 95:pos ;
-75:__UG_NAME__ -> 95:in ;
-49:__UG_NAME__ -> 50:in ;
-73:__UG_NAME__ -> 74:rq ;
-66:__UG_NAME__ -> 74:freq ;
-50:__UG_NAME__ -> 74:in ;
-43:__UG_NAME__ -> 44:freq ;
-18:__UG_NAME__ -> 83:array___control___0 ;
-19:__UG_NAME__ -> 83:array___control___1 ;
-31:__UG_NAME__ -> 83:which ;
-45:__UG_NAME__ -> 46:freq ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-hollow.dot b/etc/synthdefs/graphviz/sonic-pi-hollow.dot
deleted file mode 100644
index d570774..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-hollow.dot
+++ /dev/null
@@ -1,330 +0,0 @@
-digraph synthdef {
-36 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-38 [label = "{{ <a> 0.4|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-40 [label = "{{ <a> 0.5|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-41 [label = "{{ <a> 0.2|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-43 [label = "{{ <a> 0.2|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> 0.5|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> 4.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> 0.125|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-96 [label = "{{ <a> 15.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-75 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-79 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-37 [label = "{<__UG_NAME__>brown-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
-31 [label = "{<__UG_NAME__>clip-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 90.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :res
- default: 0.99" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :noise
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :norm
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-47 [label = "{{ {{0.0|4.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{<__UG_NAME__>gray-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
-32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-116 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-115 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-35 [label = "{<__UG_NAME__>pink-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
-44 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___binary____op____u____gen___2>|<array___binary____op____u____gen___3>|<array___binary____op____u____gen___4>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-46 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <which> which|{{<array___lpf___0>|<array___normalizer___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-39 [label = "{<__UG_NAME__>white-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-35:__UG_NAME__ -> 36:b ;
-37:__UG_NAME__ -> 38:b ;
-39:__UG_NAME__ -> 40:b ;
-31:__UG_NAME__ -> 41:b ;
-42:__UG_NAME__ -> 43:b ;
-47:__UG_NAME__ -> 48:b ;
-44:__UG_NAME__ -> 48:a ;
-47:__UG_NAME__ -> 53:b ;
-44:__UG_NAME__ -> 53:a ;
-47:__UG_NAME__ -> 73:b ;
-44:__UG_NAME__ -> 73:a ;
-64:__UG_NAME__ -> 74:a ;
-75:__UG_NAME__ -> 76:b ;
-64:__UG_NAME__ -> 78:a ;
-79:__UG_NAME__ -> 80:b ;
-47:__UG_NAME__ -> 96:b ;
-95:__UG_NAME__ -> 97:b ;
-96:__UG_NAME__ -> 97:a ;
-57:__UG_NAME__ -> 58:b ;
-54:__UG_NAME__ -> 58:a ;
-61:__UG_NAME__ -> 62:b ;
-58:__UG_NAME__ -> 62:a ;
-52:__UG_NAME__ -> 66:b ;
-65:__UG_NAME__ -> 66:a ;
-69:__UG_NAME__ -> 70:b ;
-66:__UG_NAME__ -> 70:a ;
-76:__UG_NAME__ -> 77:b ;
-72:__UG_NAME__ -> 77:a ;
-80:__UG_NAME__ -> 81:b ;
-77:__UG_NAME__ -> 81:a ;
-85:__UG_NAME__ -> 86:b ;
-82:__UG_NAME__ -> 86:a ;
-89:__UG_NAME__ -> 90:b ;
-86:__UG_NAME__ -> 90:a ;
-101:__UG_NAME__ -> 102:b ;
-98:__UG_NAME__ -> 102:a ;
-105:__UG_NAME__ -> 106:b ;
-102:__UG_NAME__ -> 106:a ;
-34:__UG_NAME__ -> 109:b ;
-108:__UG_NAME__ -> 109:a ;
-112:__UG_NAME__ -> 113:b ;
-109:__UG_NAME__ -> 113:a ;
-17:__UG_NAME__ -> 45:b ;
-33:__UG_NAME__ -> 34:a ;
-51:__UG_NAME__ -> 52:a ;
-56:__UG_NAME__ -> 57:a ;
-60:__UG_NAME__ -> 61:a ;
-68:__UG_NAME__ -> 69:a ;
-84:__UG_NAME__ -> 85:a ;
-88:__UG_NAME__ -> 89:a ;
-100:__UG_NAME__ -> 101:a ;
-104:__UG_NAME__ -> 105:a ;
-111:__UG_NAME__ -> 112:a ;
-32:__UG_NAME__ -> 33:a ;
-50:__UG_NAME__ -> 51:a ;
-55:__UG_NAME__ -> 56:a ;
-59:__UG_NAME__ -> 60:a ;
-67:__UG_NAME__ -> 68:a ;
-83:__UG_NAME__ -> 84:a ;
-87:__UG_NAME__ -> 88:a ;
-99:__UG_NAME__ -> 100:a ;
-103:__UG_NAME__ -> 104:a ;
-110:__UG_NAME__ -> 111:a ;
-71:__UG_NAME__ -> 72:rq ;
-64:__UG_NAME__ -> 72:freq ;
-53:__UG_NAME__ -> 72:in ;
-71:__UG_NAME__ -> 75:rq ;
-74:__UG_NAME__ -> 75:freq ;
-73:__UG_NAME__ -> 75:in ;
-71:__UG_NAME__ -> 79:rq ;
-78:__UG_NAME__ -> 79:freq ;
-48:__UG_NAME__ -> 79:in ;
-16:__UG_NAME__ -> 47:envelope___control___4 ;
-12:__UG_NAME__ -> 47:envelope___control___5 ;
-19:__UG_NAME__ -> 47:envelope___control___6 ;
-46:__UG_NAME__ -> 47:envelope___select___8 ;
-13:__UG_NAME__ -> 47:envelope___control___9 ;
-19:__UG_NAME__ -> 47:envelope___control___10 ;
-18:__UG_NAME__ -> 47:envelope___control___12 ;
-14:__UG_NAME__ -> 47:envelope___control___13 ;
-19:__UG_NAME__ -> 47:envelope___control___14 ;
-15:__UG_NAME__ -> 47:envelope___control___17 ;
-19:__UG_NAME__ -> 47:envelope___control___18 ;
-62:__UG_NAME__ -> 63:gate ;
-0:__UG_NAME__ -> 63:envelope___control___0 ;
-0:__UG_NAME__ -> 63:envelope___control___4 ;
-1:__UG_NAME__ -> 63:envelope___control___5 ;
-2:__UG_NAME__ -> 63:envelope___control___6 ;
-3:__UG_NAME__ -> 63:envelope___control___7 ;
-70:__UG_NAME__ -> 71:gate ;
-49:__UG_NAME__ -> 71:envelope___mul____add___0 ;
-49:__UG_NAME__ -> 71:envelope___mul____add___4 ;
-25:__UG_NAME__ -> 71:envelope___control___5 ;
-26:__UG_NAME__ -> 71:envelope___control___6 ;
-27:__UG_NAME__ -> 71:envelope___control___7 ;
-90:__UG_NAME__ -> 91:gate ;
-20:__UG_NAME__ -> 91:envelope___control___0 ;
-20:__UG_NAME__ -> 91:envelope___control___4 ;
-21:__UG_NAME__ -> 91:envelope___control___5 ;
-22:__UG_NAME__ -> 91:envelope___control___6 ;
-23:__UG_NAME__ -> 91:envelope___control___7 ;
-106:__UG_NAME__ -> 107:gate ;
-4:__UG_NAME__ -> 107:envelope___control___0 ;
-4:__UG_NAME__ -> 107:envelope___control___4 ;
-5:__UG_NAME__ -> 107:envelope___control___5 ;
-6:__UG_NAME__ -> 107:envelope___control___6 ;
-7:__UG_NAME__ -> 107:envelope___control___7 ;
-113:__UG_NAME__ -> 114:gate ;
-8:__UG_NAME__ -> 114:envelope___control___0 ;
-8:__UG_NAME__ -> 114:envelope___control___4 ;
-9:__UG_NAME__ -> 114:envelope___control___5 ;
-10:__UG_NAME__ -> 114:envelope___control___6 ;
-11:__UG_NAME__ -> 114:envelope___control___7 ;
-8:__UG_NAME__ -> 32:in ;
-49:__UG_NAME__ -> 50:in ;
-0:__UG_NAME__ -> 55:in ;
-1:__UG_NAME__ -> 59:in ;
-25:__UG_NAME__ -> 67:in ;
-20:__UG_NAME__ -> 83:in ;
-21:__UG_NAME__ -> 87:in ;
-4:__UG_NAME__ -> 99:in ;
-5:__UG_NAME__ -> 103:in ;
-9:__UG_NAME__ -> 110:in ;
-92:__UG_NAME__ -> 93:freq ;
-81:__UG_NAME__ -> 93:in ;
-63:__UG_NAME__ -> 64:a ;
-91:__UG_NAME__ -> 92:a ;
-24:__UG_NAME__ -> 49:in ;
-93:__UG_NAME__ -> 94:in ;
-115:__UG_NAME__ -> 116:signals___pan2___0 ;
-115:__UG_NAME__ -> 116:signals___pan2___1 ;
-30:__UG_NAME__ -> 116:bus ;
-114:__UG_NAME__ -> 115:level ;
-107:__UG_NAME__ -> 115:pos ;
-97:__UG_NAME__ -> 115:in ;
-36:__UG_NAME__ -> 44:array___binary____op____u____gen___0 ;
-38:__UG_NAME__ -> 44:array___binary____op____u____gen___1 ;
-40:__UG_NAME__ -> 44:array___binary____op____u____gen___2 ;
-41:__UG_NAME__ -> 44:array___binary____op____u____gen___3 ;
-43:__UG_NAME__ -> 44:array___binary____op____u____gen___4 ;
-28:__UG_NAME__ -> 44:which ;
-17:__UG_NAME__ -> 46:array___control___0 ;
-18:__UG_NAME__ -> 46:array___control___1 ;
-45:__UG_NAME__ -> 46:which ;
-93:__UG_NAME__ -> 95:array___lpf___0 ;
-94:__UG_NAME__ -> 95:array___normalizer___1 ;
-29:__UG_NAME__ -> 95:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-hoover.dot b/etc/synthdefs/graphviz/sonic-pi-hoover.dot
deleted file mode 100644
index 87b0c98..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-hoover.dot
+++ /dev/null
@@ -1,456 +0,0 @@
-digraph synthdef {
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> 0.25|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> 0.5} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> 0.5|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-80 [label = "{{ <a> 0.1|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-81 [label = "{{ <a> 0.25|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> 0.5|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-91 [label = "{{ <a> 0.25|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <a> 0.5|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-102 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-131 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-132 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-154 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-157 [label = "{{ <a> 0.25|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-164 [label = "{{ <a> 0.5|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-166 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-167 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-111 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-130 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-138 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-148 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-152 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-159 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-165 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-52 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
-64 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
-77 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
-103 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-126 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-137 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-147 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-151 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-136 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-146 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-150 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <in> in|<freq> freq 6000.0|<rq> rq 1.0|<db> db 3.0} |<__UG_NAME__>b-peak-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
-86 [label = "{{ <in> in|<freq> freq 3500.0|<rq> rq 1.0|<db> db 6.0} |<__UG_NAME__>b-peak-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
-95 [label = "{{ <in> in|<freq> freq 6000.0|<rq> rq 1.0|<db> db 3.0} |<__UG_NAME__>b-peak-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
-96 [label = "{{ <in> in|<freq> freq 3500.0|<rq> rq 1.0|<db> db 6.0} |<__UG_NAME__>b-peak-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
-161 [label = "{{ <in> in|<freq> freq 6000.0|<rq> rq 1.0|<db> db 3.0} |<__UG_NAME__>b-peak-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
-162 [label = "{{ <in> in|<freq> freq 3500.0|<rq> rq 1.0|<db> db 6.0} |<__UG_NAME__>b-peak-eq }" style="filled, bold, rounded"  shape=record rankdir=LR];
-89 [label = "{{ <in> in|<max____delay____time> max-delay-time 0.005|<delay____time> delay-time|<decay____time> decay-time 0.0} |<__UG_NAME__>comb-c }" style="filled, bold, rounded"  shape=record rankdir=LR];
-99 [label = "{{ <in> in|<max____delay____time> max-delay-time 0.005|<delay____time> delay-time|<decay____time> decay-time 0.0} |<__UG_NAME__>comb-c }" style="filled, bold, rounded"  shape=record rankdir=LR];
-163 [label = "{{ <in> in|<max____delay____time> max-delay-time 0.005|<delay____time> delay-time|<decay____time> decay-time 0.0} |<__UG_NAME__>comb-c }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.05" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 130.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :res
- default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :pre_amp
- default: 10.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :amp-fudge
- default: 2.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-40 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-143 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-153 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-135 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-139 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-145 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-149 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-134 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <freq> freq|<iphase> iphase 0.0} |<__UG_NAME__>lf-par }" style="filled, bold, rounded"  shape=record rankdir=LR];
-92 [label = "{{ <freq> freq|<iphase> iphase 0.0} |<__UG_NAME__>lf-par }" style="filled, bold, rounded"  shape=record rankdir=LR];
-158 [label = "{{ <freq> freq|<iphase> iphase 0.0} |<__UG_NAME__>lf-par }" style="filled, bold, rounded"  shape=record rankdir=LR];
-51 [label = "{{ <freq> freq|<iphase> iphase 0.0|<width> width} |<__UG_NAME__>lf-pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
-63 [label = "{{ <freq> freq|<iphase> iphase 0.0|<width> width} |<__UG_NAME__>lf-pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
-76 [label = "{{ <freq> freq|<iphase> iphase 0.0|<width> width} |<__UG_NAME__>lf-pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
-46 [label = "{{ <freq> freq|<iphase> iphase 1.0} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-58 [label = "{{ <freq> freq|<iphase> iphase 1.0} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-71 [label = "{{ <freq> freq|<iphase> iphase 1.0} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-43 [label = "{{ <in> in|<srclo> srclo -1.0|<srchi> srchi 1.0|<dstlo> dstlo 0.995|<dsthi> dsthi 1.005} |<__UG_NAME__>lin-exp }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <in> in|<srclo> srclo -1.0|<srchi> srchi 1.0|<dstlo> dstlo 0.995|<dsthi> dsthi 1.005} |<__UG_NAME__>lin-exp }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <in> in|<srclo> srclo -1.0|<srchi> srchi 1.0|<dstlo> dstlo 0.995|<dsthi> dsthi 1.005} |<__UG_NAME__>lin-exp }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <in> in|<mul> mul 0.5|<add> add 0.5} |<__UG_NAME__>mul-add }" style="filled, bold, rounded"  shape=record rankdir=LR];
-50 [label = "{{ <in> in|<mul> mul 0.375|<add> add 0.5} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in|<mul> mul 0.5|<add> add 0.5} |<__UG_NAME__>mul-add }" style="filled, bold, rounded"  shape=record rankdir=LR];
-62 [label = "{{ <in> in|<mul> mul 0.375|<add> add 0.5} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <in> in|<mul> mul 0.5|<add> add 0.5} |<__UG_NAME__>mul-add }" style="filled, bold, rounded"  shape=record rankdir=LR];
-75 [label = "{{ <in> in|<mul> mul 0.375|<add> add 0.5} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <in> in|<mul> mul 0.1|<add> add 0.0} |<__UG_NAME__>mul-add }" style="filled, bold, rounded"  shape=record rankdir=LR];
-88 [label = "{{ <in> in|<mul> mul 8.3333335E-4|<add> add 0.004166667} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <in> in|<mul> mul 0.1|<add> add 0.0} |<__UG_NAME__>mul-add }" style="filled, bold, rounded"  shape=record rankdir=LR];
-98 [label = "{{ <in> in|<mul> mul 8.3333335E-4|<add> add 0.004166667} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-160 [label = "{{ <in> in|<mul> mul 0.1|<add> add 0.0} |<__UG_NAME__>mul-add }" style="filled, bold, rounded"  shape=record rankdir=LR];
-170 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>|<signals___pan2___2>|<signals___pan2___3>|<signals___pan2___4>|<signals___pan2___5>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-155 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-156 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-169 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-129 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-133 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-168 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-104 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <freq> freq 2.9495428|<phase> phase 3.0215828|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <freq> freq 2.7397006|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <freq> freq 2.9825559|<phase> phase 4.7889028|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <freq> freq 2.2917612|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <freq> freq 2.9804978|<phase> phase 2.7581153|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <freq> freq 2.8854527|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <freq> freq 3.0|<phase> phase 1.5707964|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <freq> freq 3.0|<phase> phase 4.712389|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-
-43:__UG_NAME__ -> 44:b ;
-41:__UG_NAME__ -> 44:a ;
-44:__UG_NAME__ -> 45:b ;
-44:__UG_NAME__ -> 48:a ;
-52:__UG_NAME__ -> 53:b ;
-47:__UG_NAME__ -> 53:a ;
-55:__UG_NAME__ -> 56:b ;
-41:__UG_NAME__ -> 56:a ;
-56:__UG_NAME__ -> 57:b ;
-56:__UG_NAME__ -> 60:a ;
-64:__UG_NAME__ -> 65:b ;
-59:__UG_NAME__ -> 65:a ;
-68:__UG_NAME__ -> 69:b ;
-41:__UG_NAME__ -> 69:a ;
-69:__UG_NAME__ -> 70:b ;
-69:__UG_NAME__ -> 73:a ;
-77:__UG_NAME__ -> 78:b ;
-72:__UG_NAME__ -> 78:a ;
-79:__UG_NAME__ -> 80:b ;
-44:__UG_NAME__ -> 81:b ;
-89:__UG_NAME__ -> 90:b ;
-56:__UG_NAME__ -> 91:b ;
-99:__UG_NAME__ -> 100:b ;
-101:__UG_NAME__ -> 102:b ;
-28:__UG_NAME__ -> 102:a ;
-105:__UG_NAME__ -> 106:b ;
-102:__UG_NAME__ -> 106:a ;
-130:__UG_NAME__ -> 131:b ;
-28:__UG_NAME__ -> 131:a ;
-105:__UG_NAME__ -> 132:b ;
-131:__UG_NAME__ -> 132:a ;
-153:__UG_NAME__ -> 154:b ;
-29:__UG_NAME__ -> 154:a ;
-69:__UG_NAME__ -> 157:b ;
-163:__UG_NAME__ -> 164:b ;
-165:__UG_NAME__ -> 166:b ;
-28:__UG_NAME__ -> 166:a ;
-105:__UG_NAME__ -> 167:b ;
-166:__UG_NAME__ -> 167:a ;
-34:__UG_NAME__ -> 35:b ;
-31:__UG_NAME__ -> 35:a ;
-38:__UG_NAME__ -> 39:b ;
-35:__UG_NAME__ -> 39:a ;
-65:__UG_NAME__ -> 66:b ;
-53:__UG_NAME__ -> 66:a ;
-78:__UG_NAME__ -> 79:b ;
-66:__UG_NAME__ -> 79:a ;
-82:__UG_NAME__ -> 83:b ;
-80:__UG_NAME__ -> 83:a ;
-92:__UG_NAME__ -> 93:b ;
-80:__UG_NAME__ -> 93:a ;
-100:__UG_NAME__ -> 101:b ;
-96:__UG_NAME__ -> 101:a ;
-110:__UG_NAME__ -> 111:b ;
-107:__UG_NAME__ -> 111:a ;
-114:__UG_NAME__ -> 115:b ;
-111:__UG_NAME__ -> 115:a ;
-122:__UG_NAME__ -> 123:b ;
-118:__UG_NAME__ -> 123:a ;
-126:__UG_NAME__ -> 127:b ;
-123:__UG_NAME__ -> 127:a ;
-90:__UG_NAME__ -> 130:b ;
-86:__UG_NAME__ -> 130:a ;
-137:__UG_NAME__ -> 138:b ;
-134:__UG_NAME__ -> 138:a ;
-141:__UG_NAME__ -> 142:b ;
-138:__UG_NAME__ -> 142:a ;
-147:__UG_NAME__ -> 148:b ;
-144:__UG_NAME__ -> 148:a ;
-151:__UG_NAME__ -> 152:b ;
-148:__UG_NAME__ -> 152:a ;
-158:__UG_NAME__ -> 159:b ;
-80:__UG_NAME__ -> 159:a ;
-164:__UG_NAME__ -> 165:b ;
-162:__UG_NAME__ -> 165:a ;
-51:__UG_NAME__ -> 52:b ;
-63:__UG_NAME__ -> 64:b ;
-76:__UG_NAME__ -> 77:b ;
-17:__UG_NAME__ -> 103:b ;
-33:__UG_NAME__ -> 34:a ;
-37:__UG_NAME__ -> 38:a ;
-109:__UG_NAME__ -> 110:a ;
-113:__UG_NAME__ -> 114:a ;
-121:__UG_NAME__ -> 122:a ;
-125:__UG_NAME__ -> 126:a ;
-136:__UG_NAME__ -> 137:a ;
-140:__UG_NAME__ -> 141:a ;
-146:__UG_NAME__ -> 147:a ;
-150:__UG_NAME__ -> 151:a ;
-32:__UG_NAME__ -> 33:a ;
-36:__UG_NAME__ -> 37:a ;
-108:__UG_NAME__ -> 109:a ;
-112:__UG_NAME__ -> 113:a ;
-120:__UG_NAME__ -> 121:a ;
-124:__UG_NAME__ -> 125:a ;
-135:__UG_NAME__ -> 136:a ;
-139:__UG_NAME__ -> 140:a ;
-145:__UG_NAME__ -> 146:a ;
-149:__UG_NAME__ -> 150:a ;
-84:__UG_NAME__ -> 85:in ;
-85:__UG_NAME__ -> 86:in ;
-94:__UG_NAME__ -> 95:in ;
-95:__UG_NAME__ -> 96:in ;
-160:__UG_NAME__ -> 161:in ;
-161:__UG_NAME__ -> 162:in ;
-88:__UG_NAME__ -> 89:delay____time ;
-86:__UG_NAME__ -> 89:in ;
-98:__UG_NAME__ -> 99:delay____time ;
-96:__UG_NAME__ -> 99:in ;
-88:__UG_NAME__ -> 163:delay____time ;
-162:__UG_NAME__ -> 163:in ;
-39:__UG_NAME__ -> 40:gate ;
-0:__UG_NAME__ -> 40:envelope___control___0 ;
-0:__UG_NAME__ -> 40:envelope___control___4 ;
-1:__UG_NAME__ -> 40:envelope___control___5 ;
-2:__UG_NAME__ -> 40:envelope___control___6 ;
-3:__UG_NAME__ -> 40:envelope___control___7 ;
-16:__UG_NAME__ -> 105:envelope___control___4 ;
-12:__UG_NAME__ -> 105:envelope___control___5 ;
-19:__UG_NAME__ -> 105:envelope___control___6 ;
-104:__UG_NAME__ -> 105:envelope___select___8 ;
-13:__UG_NAME__ -> 105:envelope___control___9 ;
-19:__UG_NAME__ -> 105:envelope___control___10 ;
-18:__UG_NAME__ -> 105:envelope___control___12 ;
-14:__UG_NAME__ -> 105:envelope___control___13 ;
-19:__UG_NAME__ -> 105:envelope___control___14 ;
-15:__UG_NAME__ -> 105:envelope___control___17 ;
-19:__UG_NAME__ -> 105:envelope___control___18 ;
-115:__UG_NAME__ -> 116:gate ;
-20:__UG_NAME__ -> 116:envelope___control___0 ;
-20:__UG_NAME__ -> 116:envelope___control___4 ;
-21:__UG_NAME__ -> 116:envelope___control___5 ;
-22:__UG_NAME__ -> 116:envelope___control___6 ;
-23:__UG_NAME__ -> 116:envelope___control___7 ;
-127:__UG_NAME__ -> 128:gate ;
-119:__UG_NAME__ -> 128:envelope___mul____add___0 ;
-119:__UG_NAME__ -> 128:envelope___mul____add___4 ;
-25:__UG_NAME__ -> 128:envelope___control___5 ;
-26:__UG_NAME__ -> 128:envelope___control___6 ;
-27:__UG_NAME__ -> 128:envelope___control___7 ;
-142:__UG_NAME__ -> 143:gate ;
-8:__UG_NAME__ -> 143:envelope___control___0 ;
-8:__UG_NAME__ -> 143:envelope___control___4 ;
-9:__UG_NAME__ -> 143:envelope___control___5 ;
-10:__UG_NAME__ -> 143:envelope___control___6 ;
-11:__UG_NAME__ -> 143:envelope___control___7 ;
-152:__UG_NAME__ -> 153:gate ;
-4:__UG_NAME__ -> 153:envelope___control___0 ;
-4:__UG_NAME__ -> 153:envelope___control___4 ;
-5:__UG_NAME__ -> 153:envelope___control___5 ;
-6:__UG_NAME__ -> 153:envelope___control___6 ;
-7:__UG_NAME__ -> 153:envelope___control___7 ;
-0:__UG_NAME__ -> 32:in ;
-1:__UG_NAME__ -> 36:in ;
-20:__UG_NAME__ -> 108:in ;
-21:__UG_NAME__ -> 112:in ;
-119:__UG_NAME__ -> 120:in ;
-25:__UG_NAME__ -> 124:in ;
-8:__UG_NAME__ -> 135:in ;
-9:__UG_NAME__ -> 139:in ;
-4:__UG_NAME__ -> 145:in ;
-5:__UG_NAME__ -> 149:in ;
-81:__UG_NAME__ -> 82:freq ;
-91:__UG_NAME__ -> 92:freq ;
-157:__UG_NAME__ -> 158:freq ;
-50:__UG_NAME__ -> 51:width ;
-48:__UG_NAME__ -> 51:freq ;
-62:__UG_NAME__ -> 63:width ;
-60:__UG_NAME__ -> 63:freq ;
-75:__UG_NAME__ -> 76:width ;
-73:__UG_NAME__ -> 76:freq ;
-45:__UG_NAME__ -> 46:freq ;
-57:__UG_NAME__ -> 58:freq ;
-70:__UG_NAME__ -> 71:freq ;
-42:__UG_NAME__ -> 43:in ;
-54:__UG_NAME__ -> 55:in ;
-67:__UG_NAME__ -> 68:in ;
-40:__UG_NAME__ -> 41:a ;
-116:__UG_NAME__ -> 117:a ;
-46:__UG_NAME__ -> 47:in ;
-49:__UG_NAME__ -> 50:in ;
-58:__UG_NAME__ -> 59:in ;
-61:__UG_NAME__ -> 62:in ;
-71:__UG_NAME__ -> 72:in ;
-74:__UG_NAME__ -> 75:in ;
-83:__UG_NAME__ -> 84:in ;
-87:__UG_NAME__ -> 88:in ;
-93:__UG_NAME__ -> 94:in ;
-97:__UG_NAME__ -> 98:in ;
-24:__UG_NAME__ -> 119:in ;
-159:__UG_NAME__ -> 160:in ;
-155:__UG_NAME__ -> 170:signals___pan2___0 ;
-155:__UG_NAME__ -> 170:signals___pan2___1 ;
-156:__UG_NAME__ -> 170:signals___pan2___2 ;
-156:__UG_NAME__ -> 170:signals___pan2___3 ;
-169:__UG_NAME__ -> 170:signals___pan2___4 ;
-169:__UG_NAME__ -> 170:signals___pan2___5 ;
-30:__UG_NAME__ -> 170:bus ;
-154:__UG_NAME__ -> 155:level ;
-143:__UG_NAME__ -> 155:pos ;
-133:__UG_NAME__ -> 155:in ;
-154:__UG_NAME__ -> 156:level ;
-143:__UG_NAME__ -> 156:pos ;
-129:__UG_NAME__ -> 156:in ;
-154:__UG_NAME__ -> 169:level ;
-143:__UG_NAME__ -> 169:pos ;
-168:__UG_NAME__ -> 169:in ;
-128:__UG_NAME__ -> 129:rq ;
-117:__UG_NAME__ -> 129:freq ;
-106:__UG_NAME__ -> 129:in ;
-128:__UG_NAME__ -> 133:rq ;
-117:__UG_NAME__ -> 133:freq ;
-132:__UG_NAME__ -> 133:in ;
-128:__UG_NAME__ -> 168:rq ;
-117:__UG_NAME__ -> 168:freq ;
-167:__UG_NAME__ -> 168:in ;
-17:__UG_NAME__ -> 104:array___control___0 ;
-18:__UG_NAME__ -> 104:array___control___1 ;
-103:__UG_NAME__ -> 104:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-mixer.dot b/etc/synthdefs/graphviz/sonic-pi-mixer.dot
deleted file mode 100644
index e543587..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-mixer.dot
+++ /dev/null
@@ -1,292 +0,0 @@
-digraph synthdef {
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-98 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <in> in|<lo> lo 0.0|<hi> hi 135.5} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>clip2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>clip2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :pre_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :pre_amp_slide
- default: 0.02" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :pre_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :pre_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide
- default: 0.02" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :safe-recovery-time
- default: 3.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :hpf
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :hpf_bypass
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :hpf_slide
- default: 0.02" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :hpf_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :hpf_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :lpf
- default: 135.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :lpf_bypass
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :lpf_slide
- default: 0.02" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :lpf_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :lpf_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :force_mono
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :invert_stereo
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :limiter_bypass
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :leak_dc_bypass
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-44 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-76 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-91 [label = "{{ <in> in|<freq> freq 10.0} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-100 [label = "{{ <in> in|<freq> freq 10.0} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-24 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <bus> bus|<num____channels> num-channels 1} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-74 [label = "{{ <bus> bus|<num____channels> num-channels 1} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-87 [label = "{{ <in> in|<coef> coef 0.995} |<__UG_NAME__>leak-dc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-96 [label = "{{ <in> in|<coef> coef 0.995} |<__UG_NAME__>leak-dc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-85 [label = "{{ <in> in|<level> level 0.99|<dur> dur 0.01} |<__UG_NAME__>limiter }" style="filled, bold, rounded"  shape=record rankdir=LR];
-94 [label = "{{ <in> in|<level> level 0.99|<dur> dur 0.01} |<__UG_NAME__>limiter }" style="filled, bold, rounded"  shape=record rankdir=LR];
-72 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-78 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-92 [label = "{{ <in> in|<freq> freq 20500.0} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-101 [label = "{{ <in> in|<freq> freq 20500.0} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <bus> bus 0.0|{{<signals___lpf___0>|<signals___lpf___1>}|signals}} |<__UG_NAME__>replace-out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-68 [label = "{{ <which> which|{{<array___hpf___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-73 [label = "{{ <which> which|{{<array___lpf___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-77 [label = "{{ <which> which|{{<array___hpf___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-79 [label = "{{ <which> which|{{<array___lpf___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-82 [label = "{{ <which> which|{{<array___select___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-83 [label = "{{ <which> which|{{<array___select___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-84 [label = "{{ <which> which|{{<array___select___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-86 [label = "{{ <which> which|{{<array___limiter___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-88 [label = "{{ <which> which|{{<array___leak____dc___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-93 [label = "{{ <which> which|{{<array___select___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-95 [label = "{{ <which> which|{{<array___limiter___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-97 [label = "{{ <which> which|{{<array___leak____dc___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-55:__UG_NAME__ -> 56:b ;
-53:__UG_NAME__ -> 56:a ;
-74:__UG_NAME__ -> 75:b ;
-53:__UG_NAME__ -> 75:a ;
-88:__UG_NAME__ -> 89:b ;
-44:__UG_NAME__ -> 89:a ;
-97:__UG_NAME__ -> 98:b ;
-44:__UG_NAME__ -> 98:a ;
-31:__UG_NAME__ -> 32:b ;
-28:__UG_NAME__ -> 32:a ;
-35:__UG_NAME__ -> 36:b ;
-32:__UG_NAME__ -> 36:a ;
-38:__UG_NAME__ -> 39:b ;
-37:__UG_NAME__ -> 39:a ;
-42:__UG_NAME__ -> 43:b ;
-39:__UG_NAME__ -> 43:a ;
-47:__UG_NAME__ -> 48:b ;
-26:__UG_NAME__ -> 48:a ;
-51:__UG_NAME__ -> 52:b ;
-48:__UG_NAME__ -> 52:a ;
-0:__UG_NAME__ -> 54:a ;
-59:__UG_NAME__ -> 60:b ;
-57:__UG_NAME__ -> 60:a ;
-63:__UG_NAME__ -> 64:b ;
-60:__UG_NAME__ -> 64:a ;
-73:__UG_NAME__ -> 80:b ;
-79:__UG_NAME__ -> 80:a ;
-80:__UG_NAME__ -> 81:a ;
-30:__UG_NAME__ -> 31:a ;
-34:__UG_NAME__ -> 35:a ;
-25:__UG_NAME__ -> 38:a ;
-41:__UG_NAME__ -> 42:a ;
-46:__UG_NAME__ -> 47:a ;
-50:__UG_NAME__ -> 51:a ;
-58:__UG_NAME__ -> 59:a ;
-62:__UG_NAME__ -> 63:a ;
-24:__UG_NAME__ -> 25:a ;
-29:__UG_NAME__ -> 30:a ;
-33:__UG_NAME__ -> 34:a ;
-40:__UG_NAME__ -> 41:a ;
-45:__UG_NAME__ -> 46:a ;
-49:__UG_NAME__ -> 50:a ;
-27:__UG_NAME__ -> 58:a ;
-61:__UG_NAME__ -> 62:a ;
-69:__UG_NAME__ -> 70:in ;
-89:__UG_NAME__ -> 90:a ;
-98:__UG_NAME__ -> 99:a ;
-43:__UG_NAME__ -> 44:gate ;
-5:__UG_NAME__ -> 44:envelope___control___0 ;
-5:__UG_NAME__ -> 44:envelope___control___4 ;
-6:__UG_NAME__ -> 44:envelope___control___5 ;
-7:__UG_NAME__ -> 44:envelope___control___6 ;
-8:__UG_NAME__ -> 44:envelope___control___7 ;
-52:__UG_NAME__ -> 53:gate ;
-1:__UG_NAME__ -> 53:envelope___control___0 ;
-1:__UG_NAME__ -> 53:envelope___control___4 ;
-2:__UG_NAME__ -> 53:envelope___control___5 ;
-3:__UG_NAME__ -> 53:envelope___control___6 ;
-4:__UG_NAME__ -> 53:envelope___control___7 ;
-64:__UG_NAME__ -> 65:gate ;
-10:__UG_NAME__ -> 65:envelope___control___0 ;
-10:__UG_NAME__ -> 65:envelope___control___4 ;
-12:__UG_NAME__ -> 65:envelope___control___5 ;
-13:__UG_NAME__ -> 65:envelope___control___6 ;
-14:__UG_NAME__ -> 65:envelope___control___7 ;
-36:__UG_NAME__ -> 69:gate ;
-15:__UG_NAME__ -> 69:envelope___control___0 ;
-15:__UG_NAME__ -> 69:envelope___control___4 ;
-17:__UG_NAME__ -> 69:envelope___control___5 ;
-18:__UG_NAME__ -> 69:envelope___control___6 ;
-19:__UG_NAME__ -> 69:envelope___control___7 ;
-66:__UG_NAME__ -> 67:freq ;
-56:__UG_NAME__ -> 67:in ;
-66:__UG_NAME__ -> 76:freq ;
-75:__UG_NAME__ -> 76:in ;
-90:__UG_NAME__ -> 91:in ;
-99:__UG_NAME__ -> 100:in ;
-5:__UG_NAME__ -> 24:in ;
-10:__UG_NAME__ -> 27:in ;
-15:__UG_NAME__ -> 29:in ;
-17:__UG_NAME__ -> 33:in ;
-6:__UG_NAME__ -> 40:in ;
-1:__UG_NAME__ -> 45:in ;
-2:__UG_NAME__ -> 49:in ;
-12:__UG_NAME__ -> 61:in ;
-54:__UG_NAME__ -> 55:bus ;
-0:__UG_NAME__ -> 74:bus ;
-86:__UG_NAME__ -> 87:in ;
-95:__UG_NAME__ -> 96:in ;
-84:__UG_NAME__ -> 85:in ;
-93:__UG_NAME__ -> 94:in ;
-71:__UG_NAME__ -> 72:freq ;
-68:__UG_NAME__ -> 72:in ;
-71:__UG_NAME__ -> 78:freq ;
-77:__UG_NAME__ -> 78:in ;
-91:__UG_NAME__ -> 92:in ;
-100:__UG_NAME__ -> 101:in ;
-65:__UG_NAME__ -> 66:a ;
-70:__UG_NAME__ -> 71:a ;
-101:__UG_NAME__ -> 102:signals___lpf___0 ;
-92:__UG_NAME__ -> 102:signals___lpf___1 ;
-67:__UG_NAME__ -> 68:array___hpf___0 ;
-56:__UG_NAME__ -> 68:array___binary____op____u____gen___1 ;
-11:__UG_NAME__ -> 68:which ;
-72:__UG_NAME__ -> 73:array___lpf___0 ;
-68:__UG_NAME__ -> 73:array___select___1 ;
-16:__UG_NAME__ -> 73:which ;
-76:__UG_NAME__ -> 77:array___hpf___0 ;
-75:__UG_NAME__ -> 77:array___binary____op____u____gen___1 ;
-11:__UG_NAME__ -> 77:which ;
-78:__UG_NAME__ -> 79:array___lpf___0 ;
-77:__UG_NAME__ -> 79:array___select___1 ;
-16:__UG_NAME__ -> 79:which ;
-79:__UG_NAME__ -> 82:array___select___0 ;
-81:__UG_NAME__ -> 82:array___binary____op____u____gen___1 ;
-20:__UG_NAME__ -> 82:which ;
-73:__UG_NAME__ -> 83:array___select___0 ;
-82:__UG_NAME__ -> 83:array___select___1 ;
-20:__UG_NAME__ -> 83:which ;
-83:__UG_NAME__ -> 84:array___select___0 ;
-82:__UG_NAME__ -> 84:array___select___1 ;
-21:__UG_NAME__ -> 84:which ;
-85:__UG_NAME__ -> 86:array___limiter___0 ;
-84:__UG_NAME__ -> 86:array___select___1 ;
-22:__UG_NAME__ -> 86:which ;
-87:__UG_NAME__ -> 88:array___leak____dc___0 ;
-86:__UG_NAME__ -> 88:array___select___1 ;
-23:__UG_NAME__ -> 88:which ;
-82:__UG_NAME__ -> 93:array___select___0 ;
-83:__UG_NAME__ -> 93:array___select___1 ;
-21:__UG_NAME__ -> 93:which ;
-94:__UG_NAME__ -> 95:array___limiter___0 ;
-93:__UG_NAME__ -> 95:array___select___1 ;
-22:__UG_NAME__ -> 95:which ;
-96:__UG_NAME__ -> 97:array___leak____dc___0 ;
-95:__UG_NAME__ -> 97:array___select___1 ;
-23:__UG_NAME__ -> 97:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-mod_dsaw.dot b/etc/synthdefs/graphviz/sonic-pi-mod_dsaw.dot
deleted file mode 100644
index 1b40a08..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-mod_dsaw.dot
+++ /dev/null
@@ -1,461 +0,0 @@
-digraph synthdef {
-60 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> 6.2831855} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <a> |<b> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ <a> |<b> 0.5} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-157 [label = "{{ <a> 1.3|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-158 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-131 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-135 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-137 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-148 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-152 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-162 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-154 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-130 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-134 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-147 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-151 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-161 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-133 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-146 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-150 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-160 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :mod_phase
- default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :mod_phase_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :mod_phase_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :mod_phase_slide_curve
- default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :mod_range
- default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :mod_range_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :mod_range_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :mod_range_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :mod_pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :mod_pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :mod_pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :mod_pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :mod_phase_offset
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "control
- :mod_wave
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "control
- :mod_invert_wave
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "control
- :detune
- default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-40 [label = "control
- :detune_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-41 [label = "control
- :detune_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "control
- :detune_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-43 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-58 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|5|0.0}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-136 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-153 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-156 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-163 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-132 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-145 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-149 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-159 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <freq> freq|<iphase> iphase|<width> width} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-138 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <in> in|<mul> mul|<add> add} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-143 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-165 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-164 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-126 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-139 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-93 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-155 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <freq> freq|<phase> phase|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-
-36:__UG_NAME__ -> 60:b ;
-73:__UG_NAME__ -> 74:b ;
-85:__UG_NAME__ -> 86:b ;
-90:__UG_NAME__ -> 91:a ;
-93:__UG_NAME__ -> 94:b ;
-95:__UG_NAME__ -> 96:b ;
-97:__UG_NAME__ -> 98:b ;
-94:__UG_NAME__ -> 98:a ;
-121:__UG_NAME__ -> 122:a ;
-140:__UG_NAME__ -> 141:a ;
-156:__UG_NAME__ -> 157:b ;
-143:__UG_NAME__ -> 158:b ;
-157:__UG_NAME__ -> 158:a ;
-47:__UG_NAME__ -> 48:b ;
-44:__UG_NAME__ -> 48:a ;
-51:__UG_NAME__ -> 53:b ;
-52:__UG_NAME__ -> 53:a ;
-56:__UG_NAME__ -> 57:b ;
-53:__UG_NAME__ -> 57:a ;
-64:__UG_NAME__ -> 65:b ;
-61:__UG_NAME__ -> 65:a ;
-68:__UG_NAME__ -> 69:b ;
-65:__UG_NAME__ -> 69:a ;
-60:__UG_NAME__ -> 72:a ;
-78:__UG_NAME__ -> 79:b ;
-75:__UG_NAME__ -> 79:a ;
-82:__UG_NAME__ -> 83:b ;
-79:__UG_NAME__ -> 83:a ;
-60:__UG_NAME__ -> 88:a ;
-36:__UG_NAME__ -> 90:a ;
-102:__UG_NAME__ -> 103:b ;
-99:__UG_NAME__ -> 103:a ;
-106:__UG_NAME__ -> 107:b ;
-103:__UG_NAME__ -> 107:a ;
-112:__UG_NAME__ -> 113:b ;
-109:__UG_NAME__ -> 113:a ;
-116:__UG_NAME__ -> 117:b ;
-113:__UG_NAME__ -> 117:a ;
-118:__UG_NAME__ -> 119:b ;
-108:__UG_NAME__ -> 119:a ;
-130:__UG_NAME__ -> 131:b ;
-127:__UG_NAME__ -> 131:a ;
-134:__UG_NAME__ -> 135:b ;
-131:__UG_NAME__ -> 135:a ;
-136:__UG_NAME__ -> 137:b ;
-124:__UG_NAME__ -> 137:a ;
-139:__UG_NAME__ -> 140:b ;
-126:__UG_NAME__ -> 140:a ;
-147:__UG_NAME__ -> 148:b ;
-144:__UG_NAME__ -> 148:a ;
-151:__UG_NAME__ -> 152:b ;
-148:__UG_NAME__ -> 152:a ;
-161:__UG_NAME__ -> 162:b ;
-48:__UG_NAME__ -> 162:a ;
-86:__UG_NAME__ -> 87:a ;
-96:__UG_NAME__ -> 97:a ;
-118:__UG_NAME__ -> 120:b ;
-119:__UG_NAME__ -> 120:a ;
-122:__UG_NAME__ -> 123:b ;
-118:__UG_NAME__ -> 123:a ;
-70:__UG_NAME__ -> 71:b ;
-120:__UG_NAME__ -> 121:a ;
-17:__UG_NAME__ -> 154:b ;
-46:__UG_NAME__ -> 47:a ;
-50:__UG_NAME__ -> 51:a ;
-55:__UG_NAME__ -> 56:a ;
-63:__UG_NAME__ -> 64:a ;
-67:__UG_NAME__ -> 68:a ;
-77:__UG_NAME__ -> 78:a ;
-81:__UG_NAME__ -> 82:a ;
-38:__UG_NAME__ -> 95:a ;
-101:__UG_NAME__ -> 102:a ;
-105:__UG_NAME__ -> 106:a ;
-111:__UG_NAME__ -> 112:a ;
-115:__UG_NAME__ -> 116:a ;
-129:__UG_NAME__ -> 130:a ;
-133:__UG_NAME__ -> 134:a ;
-146:__UG_NAME__ -> 147:a ;
-150:__UG_NAME__ -> 151:a ;
-160:__UG_NAME__ -> 161:a ;
-45:__UG_NAME__ -> 46:a ;
-49:__UG_NAME__ -> 50:a ;
-54:__UG_NAME__ -> 55:a ;
-62:__UG_NAME__ -> 63:a ;
-66:__UG_NAME__ -> 67:a ;
-76:__UG_NAME__ -> 77:a ;
-80:__UG_NAME__ -> 81:a ;
-100:__UG_NAME__ -> 101:a ;
-104:__UG_NAME__ -> 105:a ;
-110:__UG_NAME__ -> 111:a ;
-114:__UG_NAME__ -> 115:a ;
-128:__UG_NAME__ -> 129:a ;
-132:__UG_NAME__ -> 133:a ;
-145:__UG_NAME__ -> 146:a ;
-149:__UG_NAME__ -> 150:a ;
-159:__UG_NAME__ -> 160:a ;
-57:__UG_NAME__ -> 58:gate ;
-20:__UG_NAME__ -> 58:envelope___control___0 ;
-20:__UG_NAME__ -> 58:envelope___control___4 ;
-21:__UG_NAME__ -> 58:envelope___control___5 ;
-22:__UG_NAME__ -> 58:envelope___control___6 ;
-23:__UG_NAME__ -> 58:envelope___control___7 ;
-69:__UG_NAME__ -> 70:gate ;
-24:__UG_NAME__ -> 70:envelope___control___0 ;
-24:__UG_NAME__ -> 70:envelope___control___4 ;
-25:__UG_NAME__ -> 70:envelope___control___5 ;
-26:__UG_NAME__ -> 70:envelope___control___6 ;
-27:__UG_NAME__ -> 70:envelope___control___7 ;
-83:__UG_NAME__ -> 84:gate ;
-32:__UG_NAME__ -> 84:envelope___control___0 ;
-32:__UG_NAME__ -> 84:envelope___control___4 ;
-33:__UG_NAME__ -> 84:envelope___control___5 ;
-34:__UG_NAME__ -> 84:envelope___control___6 ;
-35:__UG_NAME__ -> 84:envelope___control___7 ;
-107:__UG_NAME__ -> 108:gate ;
-28:__UG_NAME__ -> 108:envelope___control___0 ;
-28:__UG_NAME__ -> 108:envelope___control___4 ;
-29:__UG_NAME__ -> 108:envelope___control___5 ;
-117:__UG_NAME__ -> 118:gate ;
-0:__UG_NAME__ -> 118:envelope___control___0 ;
-0:__UG_NAME__ -> 118:envelope___control___4 ;
-1:__UG_NAME__ -> 118:envelope___control___5 ;
-2:__UG_NAME__ -> 118:envelope___control___6 ;
-3:__UG_NAME__ -> 118:envelope___control___7 ;
-135:__UG_NAME__ -> 136:gate ;
-39:__UG_NAME__ -> 136:envelope___control___0 ;
-39:__UG_NAME__ -> 136:envelope___control___4 ;
-40:__UG_NAME__ -> 136:envelope___control___5 ;
-41:__UG_NAME__ -> 136:envelope___control___6 ;
-42:__UG_NAME__ -> 136:envelope___control___7 ;
-152:__UG_NAME__ -> 153:gate ;
-8:__UG_NAME__ -> 153:envelope___control___0 ;
-8:__UG_NAME__ -> 153:envelope___control___4 ;
-9:__UG_NAME__ -> 153:envelope___control___5 ;
-10:__UG_NAME__ -> 153:envelope___control___6 ;
-11:__UG_NAME__ -> 153:envelope___control___7 ;
-16:__UG_NAME__ -> 156:envelope___control___4 ;
-12:__UG_NAME__ -> 156:envelope___control___5 ;
-19:__UG_NAME__ -> 156:envelope___control___6 ;
-155:__UG_NAME__ -> 156:envelope___select___8 ;
-13:__UG_NAME__ -> 156:envelope___control___9 ;
-19:__UG_NAME__ -> 156:envelope___control___10 ;
-18:__UG_NAME__ -> 156:envelope___control___12 ;
-14:__UG_NAME__ -> 156:envelope___control___13 ;
-19:__UG_NAME__ -> 156:envelope___control___14 ;
-15:__UG_NAME__ -> 156:envelope___control___17 ;
-19:__UG_NAME__ -> 156:envelope___control___18 ;
-162:__UG_NAME__ -> 163:gate ;
-4:__UG_NAME__ -> 163:envelope___control___0 ;
-4:__UG_NAME__ -> 163:envelope___control___4 ;
-5:__UG_NAME__ -> 163:envelope___control___5 ;
-6:__UG_NAME__ -> 163:envelope___control___6 ;
-7:__UG_NAME__ -> 163:envelope___control___7 ;
-4:__UG_NAME__ -> 45:in ;
-20:__UG_NAME__ -> 49:in ;
-21:__UG_NAME__ -> 54:in ;
-24:__UG_NAME__ -> 62:in ;
-25:__UG_NAME__ -> 66:in ;
-32:__UG_NAME__ -> 76:in ;
-33:__UG_NAME__ -> 80:in ;
-28:__UG_NAME__ -> 100:in ;
-29:__UG_NAME__ -> 104:in ;
-0:__UG_NAME__ -> 110:in ;
-1:__UG_NAME__ -> 114:in ;
-39:__UG_NAME__ -> 128:in ;
-40:__UG_NAME__ -> 132:in ;
-8:__UG_NAME__ -> 145:in ;
-9:__UG_NAME__ -> 149:in ;
-5:__UG_NAME__ -> 159:in ;
-84:__UG_NAME__ -> 85:width ;
-36:__UG_NAME__ -> 85:iphase ;
-71:__UG_NAME__ -> 85:freq ;
-72:__UG_NAME__ -> 73:iphase ;
-71:__UG_NAME__ -> 73:freq ;
-88:__UG_NAME__ -> 89:iphase ;
-71:__UG_NAME__ -> 89:freq ;
-59:__UG_NAME__ -> 142:freq ;
-141:__UG_NAME__ -> 142:in ;
-58:__UG_NAME__ -> 59:a ;
-124:__UG_NAME__ -> 125:a ;
-137:__UG_NAME__ -> 138:a ;
-123:__UG_NAME__ -> 124:add ;
-121:__UG_NAME__ -> 124:mul ;
-98:__UG_NAME__ -> 124:in ;
-142:__UG_NAME__ -> 143:in ;
-164:__UG_NAME__ -> 165:signals___pan2___0 ;
-164:__UG_NAME__ -> 165:signals___pan2___1 ;
-43:__UG_NAME__ -> 165:bus ;
-163:__UG_NAME__ -> 164:level ;
-153:__UG_NAME__ -> 164:pos ;
-158:__UG_NAME__ -> 164:in ;
-125:__UG_NAME__ -> 126:freq ;
-138:__UG_NAME__ -> 139:freq ;
-74:__UG_NAME__ -> 93:array___binary____op____u____gen___0 ;
-87:__UG_NAME__ -> 93:array___binary____op____u____gen___1 ;
-89:__UG_NAME__ -> 93:array___lf____tri___2 ;
-92:__UG_NAME__ -> 93:array___sin____osc___3 ;
-37:__UG_NAME__ -> 93:which ;
-17:__UG_NAME__ -> 155:array___control___0 ;
-18:__UG_NAME__ -> 155:array___control___1 ;
-154:__UG_NAME__ -> 155:which ;
-91:__UG_NAME__ -> 92:phase ;
-71:__UG_NAME__ -> 92:freq ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-mod_fm.dot b/etc/synthdefs/graphviz/sonic-pi-mod_fm.dot
deleted file mode 100644
index 072a7b9..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-mod_fm.dot
+++ /dev/null
@@ -1,504 +0,0 @@
-digraph synthdef {
-74 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> |<b> 6.2831855} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <a> |<b> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-156 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-157 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-133 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-137 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-148 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-152 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-162 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-166 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-172 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-176 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-139 [label = "{{ <a> |<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-132 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-136 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-147 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-151 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-161 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-165 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-171 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-175 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-131 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-135 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-146 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-150 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-160 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-164 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-170 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-174 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :mod_phase
- default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :mod_phase_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :mod_phase_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :mod_phase_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :mod_range
- default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :mod_range_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :mod_range_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :mod_range_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :mod_pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :mod_pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :mod_pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :mod_pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :mod_phase_offset
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "control
- :mod_wave
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "control
- :mod_invert_wave
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "control
- :divisor
- default: 2.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-40 [label = "control
- :divisor_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-41 [label = "control
- :divisor_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "control
- :divisor_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-43 [label = "control
- :depth
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-44 [label = "control
- :depth_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-45 [label = "control
- :depth_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-46 [label = "control
- :depth_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-47 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-57 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-138 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-153 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-167 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-177 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-130 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-134 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-145 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-149 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-159 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-163 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-169 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-173 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-158 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-168 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <freq> freq|<iphase> iphase|<width> width} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
-155 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-126 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-154 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <in> in|<mul> mul|<add> add} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-179 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-178 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-61 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <freq> freq|<phase> phase|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-143 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-36:__UG_NAME__ -> 74:b ;
-76:__UG_NAME__ -> 77:b ;
-86:__UG_NAME__ -> 87:b ;
-91:__UG_NAME__ -> 92:a ;
-94:__UG_NAME__ -> 95:b ;
-96:__UG_NAME__ -> 97:b ;
-98:__UG_NAME__ -> 99:b ;
-95:__UG_NAME__ -> 99:a ;
-122:__UG_NAME__ -> 123:a ;
-57:__UG_NAME__ -> 127:b ;
-126:__UG_NAME__ -> 127:a ;
-127:__UG_NAME__ -> 128:b ;
-62:__UG_NAME__ -> 128:a ;
-140:__UG_NAME__ -> 141:b ;
-128:__UG_NAME__ -> 141:a ;
-155:__UG_NAME__ -> 156:b ;
-62:__UG_NAME__ -> 156:a ;
-156:__UG_NAME__ -> 157:b ;
-50:__UG_NAME__ -> 52:b ;
-51:__UG_NAME__ -> 52:a ;
-55:__UG_NAME__ -> 56:b ;
-52:__UG_NAME__ -> 56:a ;
-66:__UG_NAME__ -> 67:b ;
-63:__UG_NAME__ -> 67:a ;
-70:__UG_NAME__ -> 71:b ;
-67:__UG_NAME__ -> 71:a ;
-74:__UG_NAME__ -> 75:a ;
-79:__UG_NAME__ -> 80:b ;
-78:__UG_NAME__ -> 80:a ;
-83:__UG_NAME__ -> 84:b ;
-80:__UG_NAME__ -> 84:a ;
-74:__UG_NAME__ -> 89:a ;
-36:__UG_NAME__ -> 91:a ;
-103:__UG_NAME__ -> 104:b ;
-100:__UG_NAME__ -> 104:a ;
-107:__UG_NAME__ -> 108:b ;
-104:__UG_NAME__ -> 108:a ;
-113:__UG_NAME__ -> 114:b ;
-110:__UG_NAME__ -> 114:a ;
-117:__UG_NAME__ -> 118:b ;
-114:__UG_NAME__ -> 118:a ;
-119:__UG_NAME__ -> 120:b ;
-109:__UG_NAME__ -> 120:a ;
-132:__UG_NAME__ -> 133:b ;
-129:__UG_NAME__ -> 133:a ;
-136:__UG_NAME__ -> 137:b ;
-133:__UG_NAME__ -> 137:a ;
-141:__UG_NAME__ -> 142:b ;
-126:__UG_NAME__ -> 142:a ;
-147:__UG_NAME__ -> 148:b ;
-144:__UG_NAME__ -> 148:a ;
-151:__UG_NAME__ -> 152:b ;
-148:__UG_NAME__ -> 152:a ;
-161:__UG_NAME__ -> 162:b ;
-158:__UG_NAME__ -> 162:a ;
-165:__UG_NAME__ -> 166:b ;
-162:__UG_NAME__ -> 166:a ;
-171:__UG_NAME__ -> 172:b ;
-168:__UG_NAME__ -> 172:a ;
-175:__UG_NAME__ -> 176:b ;
-172:__UG_NAME__ -> 176:a ;
-87:__UG_NAME__ -> 88:a ;
-97:__UG_NAME__ -> 98:a ;
-119:__UG_NAME__ -> 121:b ;
-120:__UG_NAME__ -> 121:a ;
-123:__UG_NAME__ -> 124:b ;
-119:__UG_NAME__ -> 124:a ;
-72:__UG_NAME__ -> 73:b ;
-121:__UG_NAME__ -> 122:a ;
-138:__UG_NAME__ -> 139:b ;
-126:__UG_NAME__ -> 139:a ;
-17:__UG_NAME__ -> 60:b ;
-49:__UG_NAME__ -> 50:a ;
-54:__UG_NAME__ -> 55:a ;
-65:__UG_NAME__ -> 66:a ;
-69:__UG_NAME__ -> 70:a ;
-59:__UG_NAME__ -> 79:a ;
-82:__UG_NAME__ -> 83:a ;
-38:__UG_NAME__ -> 96:a ;
-102:__UG_NAME__ -> 103:a ;
-106:__UG_NAME__ -> 107:a ;
-112:__UG_NAME__ -> 113:a ;
-116:__UG_NAME__ -> 117:a ;
-131:__UG_NAME__ -> 132:a ;
-135:__UG_NAME__ -> 136:a ;
-146:__UG_NAME__ -> 147:a ;
-150:__UG_NAME__ -> 151:a ;
-160:__UG_NAME__ -> 161:a ;
-164:__UG_NAME__ -> 165:a ;
-170:__UG_NAME__ -> 171:a ;
-174:__UG_NAME__ -> 175:a ;
-48:__UG_NAME__ -> 49:a ;
-53:__UG_NAME__ -> 54:a ;
-58:__UG_NAME__ -> 59:a ;
-64:__UG_NAME__ -> 65:a ;
-68:__UG_NAME__ -> 69:a ;
-81:__UG_NAME__ -> 82:a ;
-101:__UG_NAME__ -> 102:a ;
-105:__UG_NAME__ -> 106:a ;
-111:__UG_NAME__ -> 112:a ;
-115:__UG_NAME__ -> 116:a ;
-130:__UG_NAME__ -> 131:a ;
-134:__UG_NAME__ -> 135:a ;
-145:__UG_NAME__ -> 146:a ;
-149:__UG_NAME__ -> 150:a ;
-159:__UG_NAME__ -> 160:a ;
-163:__UG_NAME__ -> 164:a ;
-169:__UG_NAME__ -> 170:a ;
-173:__UG_NAME__ -> 174:a ;
-56:__UG_NAME__ -> 57:gate ;
-43:__UG_NAME__ -> 57:envelope___control___0 ;
-43:__UG_NAME__ -> 57:envelope___control___4 ;
-44:__UG_NAME__ -> 57:envelope___control___5 ;
-45:__UG_NAME__ -> 57:envelope___control___6 ;
-46:__UG_NAME__ -> 57:envelope___control___7 ;
-16:__UG_NAME__ -> 62:envelope___control___4 ;
-12:__UG_NAME__ -> 62:envelope___control___5 ;
-19:__UG_NAME__ -> 62:envelope___control___6 ;
-61:__UG_NAME__ -> 62:envelope___select___8 ;
-13:__UG_NAME__ -> 62:envelope___control___9 ;
-19:__UG_NAME__ -> 62:envelope___control___10 ;
-18:__UG_NAME__ -> 62:envelope___control___12 ;
-14:__UG_NAME__ -> 62:envelope___control___13 ;
-19:__UG_NAME__ -> 62:envelope___control___14 ;
-15:__UG_NAME__ -> 62:envelope___control___17 ;
-19:__UG_NAME__ -> 62:envelope___control___18 ;
-71:__UG_NAME__ -> 72:gate ;
-24:__UG_NAME__ -> 72:envelope___control___0 ;
-24:__UG_NAME__ -> 72:envelope___control___4 ;
-25:__UG_NAME__ -> 72:envelope___control___5 ;
-26:__UG_NAME__ -> 72:envelope___control___6 ;
-27:__UG_NAME__ -> 72:envelope___control___7 ;
-84:__UG_NAME__ -> 85:gate ;
-32:__UG_NAME__ -> 85:envelope___control___0 ;
-32:__UG_NAME__ -> 85:envelope___control___4 ;
-33:__UG_NAME__ -> 85:envelope___control___5 ;
-34:__UG_NAME__ -> 85:envelope___control___6 ;
-35:__UG_NAME__ -> 85:envelope___control___7 ;
-108:__UG_NAME__ -> 109:gate ;
-28:__UG_NAME__ -> 109:envelope___control___0 ;
-28:__UG_NAME__ -> 109:envelope___control___4 ;
-29:__UG_NAME__ -> 109:envelope___control___5 ;
-30:__UG_NAME__ -> 109:envelope___control___6 ;
-31:__UG_NAME__ -> 109:envelope___control___7 ;
-118:__UG_NAME__ -> 119:gate ;
-0:__UG_NAME__ -> 119:envelope___control___0 ;
-0:__UG_NAME__ -> 119:envelope___control___4 ;
-1:__UG_NAME__ -> 119:envelope___control___5 ;
-2:__UG_NAME__ -> 119:envelope___control___6 ;
-3:__UG_NAME__ -> 119:envelope___control___7 ;
-137:__UG_NAME__ -> 138:gate ;
-39:__UG_NAME__ -> 138:envelope___control___0 ;
-39:__UG_NAME__ -> 138:envelope___control___4 ;
-40:__UG_NAME__ -> 138:envelope___control___5 ;
-41:__UG_NAME__ -> 138:envelope___control___6 ;
-42:__UG_NAME__ -> 138:envelope___control___7 ;
-152:__UG_NAME__ -> 153:gate ;
-20:__UG_NAME__ -> 153:envelope___control___0 ;
-20:__UG_NAME__ -> 153:envelope___control___4 ;
-21:__UG_NAME__ -> 153:envelope___control___5 ;
-22:__UG_NAME__ -> 153:envelope___control___6 ;
-23:__UG_NAME__ -> 153:envelope___control___7 ;
-166:__UG_NAME__ -> 167:gate ;
-8:__UG_NAME__ -> 167:envelope___control___0 ;
-8:__UG_NAME__ -> 167:envelope___control___4 ;
-9:__UG_NAME__ -> 167:envelope___control___5 ;
-10:__UG_NAME__ -> 167:envelope___control___6 ;
-11:__UG_NAME__ -> 167:envelope___control___7 ;
-176:__UG_NAME__ -> 177:gate ;
-4:__UG_NAME__ -> 177:envelope___control___0 ;
-4:__UG_NAME__ -> 177:envelope___control___4 ;
-5:__UG_NAME__ -> 177:envelope___control___5 ;
-6:__UG_NAME__ -> 177:envelope___control___6 ;
-7:__UG_NAME__ -> 177:envelope___control___7 ;
-43:__UG_NAME__ -> 48:in ;
-44:__UG_NAME__ -> 53:in ;
-32:__UG_NAME__ -> 58:in ;
-24:__UG_NAME__ -> 64:in ;
-25:__UG_NAME__ -> 68:in ;
-33:__UG_NAME__ -> 81:in ;
-28:__UG_NAME__ -> 101:in ;
-29:__UG_NAME__ -> 105:in ;
-0:__UG_NAME__ -> 111:in ;
-1:__UG_NAME__ -> 115:in ;
-39:__UG_NAME__ -> 130:in ;
-40:__UG_NAME__ -> 134:in ;
-20:__UG_NAME__ -> 145:in ;
-21:__UG_NAME__ -> 149:in ;
-8:__UG_NAME__ -> 159:in ;
-9:__UG_NAME__ -> 163:in ;
-4:__UG_NAME__ -> 169:in ;
-5:__UG_NAME__ -> 173:in ;
-85:__UG_NAME__ -> 86:width ;
-36:__UG_NAME__ -> 86:iphase ;
-73:__UG_NAME__ -> 86:freq ;
-75:__UG_NAME__ -> 76:iphase ;
-73:__UG_NAME__ -> 76:freq ;
-89:__UG_NAME__ -> 90:iphase ;
-73:__UG_NAME__ -> 90:freq ;
-154:__UG_NAME__ -> 155:freq ;
-143:__UG_NAME__ -> 155:in ;
-125:__UG_NAME__ -> 126:a ;
-153:__UG_NAME__ -> 154:a ;
-124:__UG_NAME__ -> 125:add ;
-122:__UG_NAME__ -> 125:mul ;
-99:__UG_NAME__ -> 125:in ;
-178:__UG_NAME__ -> 179:signals___pan2___0 ;
-178:__UG_NAME__ -> 179:signals___pan2___1 ;
-47:__UG_NAME__ -> 179:bus ;
-177:__UG_NAME__ -> 178:level ;
-167:__UG_NAME__ -> 178:pos ;
-157:__UG_NAME__ -> 178:in ;
-17:__UG_NAME__ -> 61:array___control___0 ;
-18:__UG_NAME__ -> 61:array___control___1 ;
-60:__UG_NAME__ -> 61:which ;
-77:__UG_NAME__ -> 94:array___binary____op____u____gen___0 ;
-88:__UG_NAME__ -> 94:array___binary____op____u____gen___1 ;
-90:__UG_NAME__ -> 94:array___lf____tri___2 ;
-93:__UG_NAME__ -> 94:array___sin____osc___3 ;
-37:__UG_NAME__ -> 94:which ;
-92:__UG_NAME__ -> 93:phase ;
-73:__UG_NAME__ -> 93:freq ;
-139:__UG_NAME__ -> 140:freq ;
-142:__UG_NAME__ -> 143:freq ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-mod_pulse.dot b/etc/synthdefs/graphviz/sonic-pi-mod_pulse.dot
deleted file mode 100644
index 58e37bf..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-mod_pulse.dot
+++ /dev/null
@@ -1,452 +0,0 @@
-digraph synthdef {
-66 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> 6.2831855} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-153 [label = "{{ <a> 0.8|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-158 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-130 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-134 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-147 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-151 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-133 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-143 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-150 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-132 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-139 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-149 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :mod_phase
- default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :mod_phase_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :mod_phase_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :mod_phase_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :mod_range
- default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :mod_range_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :mod_range_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :mod_range_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :mod_pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :mod_pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :mod_pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :mod_pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :mod_phase_offset
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "control
- :mod_wave
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "control
- :mod_invert_wave
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "control
- :pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-40 [label = "control
- :pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-41 [label = "control
- :pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "control
- :pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-43 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-53 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-135 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-145 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-152 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-154 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-131 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-138 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-148 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-137 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-146 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <freq> freq|<iphase> iphase|<width> width} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
-156 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-126 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-155 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <in> in|<mul> mul|<add> add} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-157 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-160 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-159 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-136 [label = "{{ <freq> freq|<width> width} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
-77 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <freq> freq|<phase> phase|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-
-65:__UG_NAME__ -> 66:b ;
-36:__UG_NAME__ -> 68:b ;
-70:__UG_NAME__ -> 71:b ;
-74:__UG_NAME__ -> 75:a ;
-77:__UG_NAME__ -> 78:b ;
-79:__UG_NAME__ -> 80:b ;
-81:__UG_NAME__ -> 82:b ;
-78:__UG_NAME__ -> 82:a ;
-105:__UG_NAME__ -> 106:a ;
-124:__UG_NAME__ -> 153:b ;
-157:__UG_NAME__ -> 158:b ;
-153:__UG_NAME__ -> 158:a ;
-47:__UG_NAME__ -> 48:b ;
-44:__UG_NAME__ -> 48:a ;
-51:__UG_NAME__ -> 52:b ;
-48:__UG_NAME__ -> 52:a ;
-58:__UG_NAME__ -> 59:b ;
-55:__UG_NAME__ -> 59:a ;
-62:__UG_NAME__ -> 63:b ;
-59:__UG_NAME__ -> 63:a ;
-68:__UG_NAME__ -> 69:a ;
-68:__UG_NAME__ -> 72:a ;
-36:__UG_NAME__ -> 74:a ;
-86:__UG_NAME__ -> 87:b ;
-83:__UG_NAME__ -> 87:a ;
-90:__UG_NAME__ -> 91:b ;
-87:__UG_NAME__ -> 91:a ;
-96:__UG_NAME__ -> 97:b ;
-93:__UG_NAME__ -> 97:a ;
-100:__UG_NAME__ -> 101:b ;
-97:__UG_NAME__ -> 101:a ;
-102:__UG_NAME__ -> 103:b ;
-92:__UG_NAME__ -> 103:a ;
-112:__UG_NAME__ -> 113:b ;
-109:__UG_NAME__ -> 113:a ;
-116:__UG_NAME__ -> 117:b ;
-113:__UG_NAME__ -> 117:a ;
-129:__UG_NAME__ -> 130:b ;
-125:__UG_NAME__ -> 130:a ;
-133:__UG_NAME__ -> 134:b ;
-130:__UG_NAME__ -> 134:a ;
-140:__UG_NAME__ -> 141:b ;
-137:__UG_NAME__ -> 141:a ;
-143:__UG_NAME__ -> 144:b ;
-141:__UG_NAME__ -> 144:a ;
-121:__UG_NAME__ -> 147:b ;
-146:__UG_NAME__ -> 147:a ;
-150:__UG_NAME__ -> 151:b ;
-147:__UG_NAME__ -> 151:a ;
-66:__UG_NAME__ -> 67:a ;
-80:__UG_NAME__ -> 81:a ;
-102:__UG_NAME__ -> 104:b ;
-103:__UG_NAME__ -> 104:a ;
-106:__UG_NAME__ -> 107:b ;
-102:__UG_NAME__ -> 107:a ;
-53:__UG_NAME__ -> 54:b ;
-104:__UG_NAME__ -> 105:a ;
-17:__UG_NAME__ -> 122:b ;
-46:__UG_NAME__ -> 47:a ;
-50:__UG_NAME__ -> 51:a ;
-57:__UG_NAME__ -> 58:a ;
-61:__UG_NAME__ -> 62:a ;
-38:__UG_NAME__ -> 79:a ;
-85:__UG_NAME__ -> 86:a ;
-89:__UG_NAME__ -> 90:a ;
-95:__UG_NAME__ -> 96:a ;
-99:__UG_NAME__ -> 100:a ;
-111:__UG_NAME__ -> 112:a ;
-115:__UG_NAME__ -> 116:a ;
-120:__UG_NAME__ -> 121:a ;
-128:__UG_NAME__ -> 129:a ;
-132:__UG_NAME__ -> 133:a ;
-139:__UG_NAME__ -> 140:a ;
-142:__UG_NAME__ -> 143:a ;
-149:__UG_NAME__ -> 150:a ;
-45:__UG_NAME__ -> 46:a ;
-49:__UG_NAME__ -> 50:a ;
-56:__UG_NAME__ -> 57:a ;
-60:__UG_NAME__ -> 61:a ;
-84:__UG_NAME__ -> 85:a ;
-88:__UG_NAME__ -> 89:a ;
-94:__UG_NAME__ -> 95:a ;
-98:__UG_NAME__ -> 99:a ;
-110:__UG_NAME__ -> 111:a ;
-114:__UG_NAME__ -> 115:a ;
-119:__UG_NAME__ -> 120:a ;
-127:__UG_NAME__ -> 128:a ;
-131:__UG_NAME__ -> 132:a ;
-138:__UG_NAME__ -> 139:a ;
-118:__UG_NAME__ -> 142:a ;
-148:__UG_NAME__ -> 149:a ;
-52:__UG_NAME__ -> 53:gate ;
-24:__UG_NAME__ -> 53:envelope___control___0 ;
-24:__UG_NAME__ -> 53:envelope___control___4 ;
-25:__UG_NAME__ -> 53:envelope___control___5 ;
-26:__UG_NAME__ -> 53:envelope___control___6 ;
-27:__UG_NAME__ -> 53:envelope___control___7 ;
-63:__UG_NAME__ -> 64:gate ;
-32:__UG_NAME__ -> 64:envelope___control___0 ;
-32:__UG_NAME__ -> 64:envelope___control___4 ;
-33:__UG_NAME__ -> 64:envelope___control___5 ;
-34:__UG_NAME__ -> 64:envelope___control___6 ;
-35:__UG_NAME__ -> 64:envelope___control___7 ;
-91:__UG_NAME__ -> 92:gate ;
-28:__UG_NAME__ -> 92:envelope___control___0 ;
-28:__UG_NAME__ -> 92:envelope___control___4 ;
-29:__UG_NAME__ -> 92:envelope___control___5 ;
-30:__UG_NAME__ -> 92:envelope___control___6 ;
-31:__UG_NAME__ -> 92:envelope___control___7 ;
-101:__UG_NAME__ -> 102:gate ;
-0:__UG_NAME__ -> 102:envelope___control___0 ;
-0:__UG_NAME__ -> 102:envelope___control___4 ;
-1:__UG_NAME__ -> 102:envelope___control___5 ;
-2:__UG_NAME__ -> 102:envelope___control___6 ;
-3:__UG_NAME__ -> 102:envelope___control___7 ;
-16:__UG_NAME__ -> 124:envelope___control___4 ;
-12:__UG_NAME__ -> 124:envelope___control___5 ;
-19:__UG_NAME__ -> 124:envelope___control___6 ;
-123:__UG_NAME__ -> 124:envelope___select___8 ;
-13:__UG_NAME__ -> 124:envelope___control___9 ;
-19:__UG_NAME__ -> 124:envelope___control___10 ;
-18:__UG_NAME__ -> 124:envelope___control___12 ;
-14:__UG_NAME__ -> 124:envelope___control___13 ;
-19:__UG_NAME__ -> 124:envelope___control___14 ;
-15:__UG_NAME__ -> 124:envelope___control___17 ;
-19:__UG_NAME__ -> 124:envelope___control___18 ;
-134:__UG_NAME__ -> 135:gate ;
-39:__UG_NAME__ -> 135:envelope___control___0 ;
-39:__UG_NAME__ -> 135:envelope___control___4 ;
-40:__UG_NAME__ -> 135:envelope___control___5 ;
-41:__UG_NAME__ -> 135:envelope___control___6 ;
-42:__UG_NAME__ -> 135:envelope___control___7 ;
-144:__UG_NAME__ -> 145:gate ;
-20:__UG_NAME__ -> 145:envelope___control___0 ;
-20:__UG_NAME__ -> 145:envelope___control___4 ;
-21:__UG_NAME__ -> 145:envelope___control___5 ;
-22:__UG_NAME__ -> 145:envelope___control___6 ;
-23:__UG_NAME__ -> 145:envelope___control___7 ;
-151:__UG_NAME__ -> 152:gate ;
-8:__UG_NAME__ -> 152:envelope___control___0 ;
-8:__UG_NAME__ -> 152:envelope___control___4 ;
-9:__UG_NAME__ -> 152:envelope___control___5 ;
-10:__UG_NAME__ -> 152:envelope___control___6 ;
-11:__UG_NAME__ -> 152:envelope___control___7 ;
-117:__UG_NAME__ -> 154:gate ;
-4:__UG_NAME__ -> 154:envelope___control___0 ;
-4:__UG_NAME__ -> 154:envelope___control___4 ;
-5:__UG_NAME__ -> 154:envelope___control___5 ;
-6:__UG_NAME__ -> 154:envelope___control___6 ;
-7:__UG_NAME__ -> 154:envelope___control___7 ;
-24:__UG_NAME__ -> 45:in ;
-25:__UG_NAME__ -> 49:in ;
-32:__UG_NAME__ -> 56:in ;
-33:__UG_NAME__ -> 60:in ;
-28:__UG_NAME__ -> 84:in ;
-29:__UG_NAME__ -> 88:in ;
-0:__UG_NAME__ -> 94:in ;
-1:__UG_NAME__ -> 98:in ;
-4:__UG_NAME__ -> 110:in ;
-5:__UG_NAME__ -> 114:in ;
-21:__UG_NAME__ -> 118:in ;
-8:__UG_NAME__ -> 119:in ;
-39:__UG_NAME__ -> 127:in ;
-40:__UG_NAME__ -> 131:in ;
-20:__UG_NAME__ -> 138:in ;
-9:__UG_NAME__ -> 148:in ;
-64:__UG_NAME__ -> 65:width ;
-36:__UG_NAME__ -> 65:iphase ;
-54:__UG_NAME__ -> 65:freq ;
-69:__UG_NAME__ -> 70:iphase ;
-54:__UG_NAME__ -> 70:freq ;
-72:__UG_NAME__ -> 73:iphase ;
-54:__UG_NAME__ -> 73:freq ;
-155:__UG_NAME__ -> 156:freq ;
-136:__UG_NAME__ -> 156:in ;
-108:__UG_NAME__ -> 126:a ;
-145:__UG_NAME__ -> 155:a ;
-107:__UG_NAME__ -> 108:add ;
-105:__UG_NAME__ -> 108:mul ;
-82:__UG_NAME__ -> 108:in ;
-156:__UG_NAME__ -> 157:in ;
-159:__UG_NAME__ -> 160:signals___pan2___0 ;
-159:__UG_NAME__ -> 160:signals___pan2___1 ;
-43:__UG_NAME__ -> 160:bus ;
-154:__UG_NAME__ -> 159:level ;
-152:__UG_NAME__ -> 159:pos ;
-158:__UG_NAME__ -> 159:in ;
-135:__UG_NAME__ -> 136:width ;
-126:__UG_NAME__ -> 136:freq ;
-71:__UG_NAME__ -> 77:array___binary____op____u____gen___0 ;
-67:__UG_NAME__ -> 77:array___binary____op____u____gen___1 ;
-73:__UG_NAME__ -> 77:array___lf____tri___2 ;
-76:__UG_NAME__ -> 77:array___sin____osc___3 ;
-37:__UG_NAME__ -> 77:which ;
-17:__UG_NAME__ -> 123:array___control___0 ;
-18:__UG_NAME__ -> 123:array___control___1 ;
-122:__UG_NAME__ -> 123:which ;
-75:__UG_NAME__ -> 76:phase ;
-54:__UG_NAME__ -> 76:freq ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-mod_saw.dot b/etc/synthdefs/graphviz/sonic-pi-mod_saw.dot
deleted file mode 100644
index d05672d..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-mod_saw.dot
+++ /dev/null
@@ -1,413 +0,0 @@
-digraph synthdef {
-51 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> 6.2831855} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> 0.8|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-131 [label = "{{ <a> |<b> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-126 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-139 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-132 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-130 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-138 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-137 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :mod_phase
- default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :mod_phase_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :mod_phase_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :mod_phase_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :mod_range
- default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :mod_range_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :mod_range_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :mod_range_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :mod_pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :mod_pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :mod_pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :mod_pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :mod_phase_offset
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "control
- :mod_wave
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "control
- :mod_invert_wave
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-49 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-136 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <freq> freq|<iphase> iphase|<width> width} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-134 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-133 [label = "{{ <in> in|<mul> mul|<add> add} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-143 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-146 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-145 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-135 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-101 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <freq> freq|<phase> phase|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-
-50:__UG_NAME__ -> 51:b ;
-36:__UG_NAME__ -> 79:b ;
-81:__UG_NAME__ -> 82:b ;
-93:__UG_NAME__ -> 94:b ;
-98:__UG_NAME__ -> 99:a ;
-101:__UG_NAME__ -> 102:b ;
-52:__UG_NAME__ -> 103:b ;
-102:__UG_NAME__ -> 103:a ;
-108:__UG_NAME__ -> 109:b ;
-130:__UG_NAME__ -> 131:a ;
-143:__UG_NAME__ -> 144:b ;
-109:__UG_NAME__ -> 144:a ;
-43:__UG_NAME__ -> 44:b ;
-40:__UG_NAME__ -> 44:a ;
-47:__UG_NAME__ -> 48:b ;
-44:__UG_NAME__ -> 48:a ;
-56:__UG_NAME__ -> 57:b ;
-53:__UG_NAME__ -> 57:a ;
-61:__UG_NAME__ -> 62:b ;
-58:__UG_NAME__ -> 62:a ;
-66:__UG_NAME__ -> 67:b ;
-63:__UG_NAME__ -> 67:a ;
-70:__UG_NAME__ -> 71:b ;
-67:__UG_NAME__ -> 71:a ;
-75:__UG_NAME__ -> 76:b ;
-62:__UG_NAME__ -> 76:a ;
-79:__UG_NAME__ -> 80:a ;
-86:__UG_NAME__ -> 87:b ;
-83:__UG_NAME__ -> 87:a ;
-90:__UG_NAME__ -> 91:b ;
-87:__UG_NAME__ -> 91:a ;
-79:__UG_NAME__ -> 96:a ;
-36:__UG_NAME__ -> 98:a ;
-111:__UG_NAME__ -> 112:b ;
-110:__UG_NAME__ -> 112:a ;
-115:__UG_NAME__ -> 116:b ;
-112:__UG_NAME__ -> 116:a ;
-121:__UG_NAME__ -> 122:b ;
-118:__UG_NAME__ -> 122:a ;
-125:__UG_NAME__ -> 126:b ;
-122:__UG_NAME__ -> 126:a ;
-127:__UG_NAME__ -> 128:b ;
-117:__UG_NAME__ -> 128:a ;
-138:__UG_NAME__ -> 139:b ;
-57:__UG_NAME__ -> 139:a ;
-51:__UG_NAME__ -> 52:a ;
-94:__UG_NAME__ -> 95:a ;
-127:__UG_NAME__ -> 129:b ;
-128:__UG_NAME__ -> 129:a ;
-131:__UG_NAME__ -> 132:b ;
-127:__UG_NAME__ -> 132:a ;
-77:__UG_NAME__ -> 78:b ;
-129:__UG_NAME__ -> 130:a ;
-17:__UG_NAME__ -> 106:b ;
-42:__UG_NAME__ -> 43:a ;
-46:__UG_NAME__ -> 47:a ;
-38:__UG_NAME__ -> 50:a ;
-55:__UG_NAME__ -> 56:a ;
-60:__UG_NAME__ -> 61:a ;
-65:__UG_NAME__ -> 66:a ;
-69:__UG_NAME__ -> 70:a ;
-74:__UG_NAME__ -> 75:a ;
-85:__UG_NAME__ -> 86:a ;
-89:__UG_NAME__ -> 90:a ;
-105:__UG_NAME__ -> 111:a ;
-114:__UG_NAME__ -> 115:a ;
-120:__UG_NAME__ -> 121:a ;
-124:__UG_NAME__ -> 125:a ;
-137:__UG_NAME__ -> 138:a ;
-41:__UG_NAME__ -> 42:a ;
-45:__UG_NAME__ -> 46:a ;
-54:__UG_NAME__ -> 55:a ;
-59:__UG_NAME__ -> 60:a ;
-64:__UG_NAME__ -> 65:a ;
-68:__UG_NAME__ -> 69:a ;
-73:__UG_NAME__ -> 74:a ;
-84:__UG_NAME__ -> 85:a ;
-88:__UG_NAME__ -> 89:a ;
-104:__UG_NAME__ -> 105:a ;
-113:__UG_NAME__ -> 114:a ;
-119:__UG_NAME__ -> 120:a ;
-123:__UG_NAME__ -> 124:a ;
-136:__UG_NAME__ -> 137:a ;
-48:__UG_NAME__ -> 49:gate ;
-8:__UG_NAME__ -> 49:envelope___control___0 ;
-8:__UG_NAME__ -> 49:envelope___control___4 ;
-9:__UG_NAME__ -> 49:envelope___control___5 ;
-10:__UG_NAME__ -> 49:envelope___control___6 ;
-11:__UG_NAME__ -> 49:envelope___control___7 ;
-71:__UG_NAME__ -> 72:gate ;
-4:__UG_NAME__ -> 72:envelope___control___0 ;
-4:__UG_NAME__ -> 72:envelope___control___4 ;
-5:__UG_NAME__ -> 72:envelope___control___5 ;
-6:__UG_NAME__ -> 72:envelope___control___6 ;
-7:__UG_NAME__ -> 72:envelope___control___7 ;
-76:__UG_NAME__ -> 77:gate ;
-24:__UG_NAME__ -> 77:envelope___control___0 ;
-24:__UG_NAME__ -> 77:envelope___control___4 ;
-25:__UG_NAME__ -> 77:envelope___control___5 ;
-26:__UG_NAME__ -> 77:envelope___control___6 ;
-27:__UG_NAME__ -> 77:envelope___control___7 ;
-91:__UG_NAME__ -> 92:gate ;
-32:__UG_NAME__ -> 92:envelope___control___0 ;
-32:__UG_NAME__ -> 92:envelope___control___4 ;
-33:__UG_NAME__ -> 92:envelope___control___5 ;
-34:__UG_NAME__ -> 92:envelope___control___6 ;
-35:__UG_NAME__ -> 92:envelope___control___7 ;
-16:__UG_NAME__ -> 108:envelope___control___4 ;
-12:__UG_NAME__ -> 108:envelope___control___5 ;
-19:__UG_NAME__ -> 108:envelope___control___6 ;
-107:__UG_NAME__ -> 108:envelope___select___8 ;
-13:__UG_NAME__ -> 108:envelope___control___9 ;
-19:__UG_NAME__ -> 108:envelope___control___10 ;
-18:__UG_NAME__ -> 108:envelope___control___12 ;
-14:__UG_NAME__ -> 108:envelope___control___13 ;
-19:__UG_NAME__ -> 108:envelope___control___14 ;
-15:__UG_NAME__ -> 108:envelope___control___17 ;
-19:__UG_NAME__ -> 108:envelope___control___18 ;
-116:__UG_NAME__ -> 117:gate ;
-28:__UG_NAME__ -> 117:envelope___control___0 ;
-28:__UG_NAME__ -> 117:envelope___control___4 ;
-29:__UG_NAME__ -> 117:envelope___control___5 ;
-30:__UG_NAME__ -> 117:envelope___control___6 ;
-31:__UG_NAME__ -> 117:envelope___control___7 ;
-126:__UG_NAME__ -> 127:gate ;
-0:__UG_NAME__ -> 127:envelope___control___0 ;
-0:__UG_NAME__ -> 127:envelope___control___4 ;
-1:__UG_NAME__ -> 127:envelope___control___5 ;
-2:__UG_NAME__ -> 127:envelope___control___6 ;
-3:__UG_NAME__ -> 127:envelope___control___7 ;
-139:__UG_NAME__ -> 140:gate ;
-20:__UG_NAME__ -> 140:envelope___control___0 ;
-20:__UG_NAME__ -> 140:envelope___control___4 ;
-21:__UG_NAME__ -> 140:envelope___control___5 ;
-22:__UG_NAME__ -> 140:envelope___control___6 ;
-23:__UG_NAME__ -> 140:envelope___control___7 ;
-8:__UG_NAME__ -> 41:in ;
-9:__UG_NAME__ -> 45:in ;
-20:__UG_NAME__ -> 54:in ;
-24:__UG_NAME__ -> 59:in ;
-4:__UG_NAME__ -> 64:in ;
-5:__UG_NAME__ -> 68:in ;
-25:__UG_NAME__ -> 73:in ;
-32:__UG_NAME__ -> 84:in ;
-33:__UG_NAME__ -> 88:in ;
-28:__UG_NAME__ -> 104:in ;
-29:__UG_NAME__ -> 113:in ;
-0:__UG_NAME__ -> 119:in ;
-1:__UG_NAME__ -> 123:in ;
-21:__UG_NAME__ -> 136:in ;
-92:__UG_NAME__ -> 93:width ;
-36:__UG_NAME__ -> 93:iphase ;
-78:__UG_NAME__ -> 93:freq ;
-80:__UG_NAME__ -> 81:iphase ;
-78:__UG_NAME__ -> 81:freq ;
-96:__UG_NAME__ -> 97:iphase ;
-78:__UG_NAME__ -> 97:freq ;
-141:__UG_NAME__ -> 142:freq ;
-135:__UG_NAME__ -> 142:in ;
-133:__UG_NAME__ -> 134:a ;
-140:__UG_NAME__ -> 141:a ;
-132:__UG_NAME__ -> 133:add ;
-130:__UG_NAME__ -> 133:mul ;
-103:__UG_NAME__ -> 133:in ;
-142:__UG_NAME__ -> 143:in ;
-145:__UG_NAME__ -> 146:signals___pan2___0 ;
-145:__UG_NAME__ -> 146:signals___pan2___1 ;
-39:__UG_NAME__ -> 146:bus ;
-72:__UG_NAME__ -> 145:level ;
-49:__UG_NAME__ -> 145:pos ;
-144:__UG_NAME__ -> 145:in ;
-134:__UG_NAME__ -> 135:freq ;
-82:__UG_NAME__ -> 101:array___binary____op____u____gen___0 ;
-95:__UG_NAME__ -> 101:array___binary____op____u____gen___1 ;
-97:__UG_NAME__ -> 101:array___lf____tri___2 ;
-100:__UG_NAME__ -> 101:array___sin____osc___3 ;
-37:__UG_NAME__ -> 101:which ;
-17:__UG_NAME__ -> 107:array___control___0 ;
-18:__UG_NAME__ -> 107:array___control___1 ;
-106:__UG_NAME__ -> 107:which ;
-99:__UG_NAME__ -> 100:phase ;
-78:__UG_NAME__ -> 100:freq ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-mod_sine.dot b/etc/synthdefs/graphviz/sonic-pi-mod_sine.dot
deleted file mode 100644
index a0754a8..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-mod_sine.dot
+++ /dev/null
@@ -1,413 +0,0 @@
-digraph synthdef {
-51 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> 6.2831855} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <a> |<b> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-134 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-136 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-143 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-131 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-126 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-130 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-139 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :mod_phase
- default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :mod_phase_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :mod_phase_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :mod_phase_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :mod_range
- default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :mod_range_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :mod_range_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :mod_range_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :mod_pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :mod_pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :mod_pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :mod_pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :mod_phase_offset
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "control
- :mod_wave
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "control
- :mod_invert_wave
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-49 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-133 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-137 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-138 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <freq> freq|<iphase> iphase|<width> width} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <in> in|<mul> mul|<add> add} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-135 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-146 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-145 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-73 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-132 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <freq> freq|<phase> phase|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-36:__UG_NAME__ -> 51:b ;
-53:__UG_NAME__ -> 54:b ;
-65:__UG_NAME__ -> 66:b ;
-70:__UG_NAME__ -> 71:a ;
-73:__UG_NAME__ -> 74:b ;
-75:__UG_NAME__ -> 76:b ;
-77:__UG_NAME__ -> 78:b ;
-74:__UG_NAME__ -> 78:a ;
-101:__UG_NAME__ -> 102:a ;
-133:__UG_NAME__ -> 134:b ;
-135:__UG_NAME__ -> 136:b ;
-134:__UG_NAME__ -> 136:a ;
-43:__UG_NAME__ -> 44:b ;
-40:__UG_NAME__ -> 44:a ;
-47:__UG_NAME__ -> 48:b ;
-44:__UG_NAME__ -> 48:a ;
-51:__UG_NAME__ -> 52:a ;
-58:__UG_NAME__ -> 59:b ;
-55:__UG_NAME__ -> 59:a ;
-62:__UG_NAME__ -> 63:b ;
-59:__UG_NAME__ -> 63:a ;
-51:__UG_NAME__ -> 68:a ;
-36:__UG_NAME__ -> 70:a ;
-82:__UG_NAME__ -> 83:b ;
-79:__UG_NAME__ -> 83:a ;
-86:__UG_NAME__ -> 87:b ;
-83:__UG_NAME__ -> 87:a ;
-92:__UG_NAME__ -> 93:b ;
-89:__UG_NAME__ -> 93:a ;
-96:__UG_NAME__ -> 97:b ;
-93:__UG_NAME__ -> 97:a ;
-98:__UG_NAME__ -> 99:b ;
-88:__UG_NAME__ -> 99:a ;
-110:__UG_NAME__ -> 111:b ;
-107:__UG_NAME__ -> 111:a ;
-114:__UG_NAME__ -> 115:b ;
-111:__UG_NAME__ -> 115:a ;
-123:__UG_NAME__ -> 124:b ;
-121:__UG_NAME__ -> 124:a ;
-127:__UG_NAME__ -> 128:b ;
-124:__UG_NAME__ -> 128:a ;
-140:__UG_NAME__ -> 141:b ;
-138:__UG_NAME__ -> 141:a ;
-142:__UG_NAME__ -> 143:b ;
-141:__UG_NAME__ -> 143:a ;
-66:__UG_NAME__ -> 67:a ;
-76:__UG_NAME__ -> 77:a ;
-98:__UG_NAME__ -> 100:b ;
-99:__UG_NAME__ -> 100:a ;
-102:__UG_NAME__ -> 103:b ;
-98:__UG_NAME__ -> 103:a ;
-49:__UG_NAME__ -> 50:b ;
-100:__UG_NAME__ -> 101:a ;
-17:__UG_NAME__ -> 131:b ;
-42:__UG_NAME__ -> 43:a ;
-46:__UG_NAME__ -> 47:a ;
-57:__UG_NAME__ -> 58:a ;
-61:__UG_NAME__ -> 62:a ;
-38:__UG_NAME__ -> 75:a ;
-81:__UG_NAME__ -> 82:a ;
-85:__UG_NAME__ -> 86:a ;
-91:__UG_NAME__ -> 92:a ;
-95:__UG_NAME__ -> 96:a ;
-109:__UG_NAME__ -> 110:a ;
-113:__UG_NAME__ -> 114:a ;
-122:__UG_NAME__ -> 123:a ;
-126:__UG_NAME__ -> 127:a ;
-139:__UG_NAME__ -> 140:a ;
-130:__UG_NAME__ -> 142:a ;
-41:__UG_NAME__ -> 42:a ;
-45:__UG_NAME__ -> 46:a ;
-56:__UG_NAME__ -> 57:a ;
-60:__UG_NAME__ -> 61:a ;
-80:__UG_NAME__ -> 81:a ;
-84:__UG_NAME__ -> 85:a ;
-90:__UG_NAME__ -> 91:a ;
-94:__UG_NAME__ -> 95:a ;
-108:__UG_NAME__ -> 109:a ;
-112:__UG_NAME__ -> 113:a ;
-120:__UG_NAME__ -> 122:a ;
-125:__UG_NAME__ -> 126:a ;
-119:__UG_NAME__ -> 130:a ;
-137:__UG_NAME__ -> 139:a ;
-48:__UG_NAME__ -> 49:gate ;
-24:__UG_NAME__ -> 49:envelope___control___0 ;
-24:__UG_NAME__ -> 49:envelope___control___4 ;
-25:__UG_NAME__ -> 49:envelope___control___5 ;
-26:__UG_NAME__ -> 49:envelope___control___6 ;
-27:__UG_NAME__ -> 49:envelope___control___7 ;
-63:__UG_NAME__ -> 64:gate ;
-32:__UG_NAME__ -> 64:envelope___control___0 ;
-32:__UG_NAME__ -> 64:envelope___control___4 ;
-33:__UG_NAME__ -> 64:envelope___control___5 ;
-34:__UG_NAME__ -> 64:envelope___control___6 ;
-35:__UG_NAME__ -> 64:envelope___control___7 ;
-87:__UG_NAME__ -> 88:gate ;
-28:__UG_NAME__ -> 88:envelope___control___0 ;
-28:__UG_NAME__ -> 88:envelope___control___4 ;
-29:__UG_NAME__ -> 88:envelope___control___5 ;
-30:__UG_NAME__ -> 88:envelope___control___6 ;
-31:__UG_NAME__ -> 88:envelope___control___7 ;
-97:__UG_NAME__ -> 98:gate ;
-0:__UG_NAME__ -> 98:envelope___control___0 ;
-0:__UG_NAME__ -> 98:envelope___control___4 ;
-1:__UG_NAME__ -> 98:envelope___control___5 ;
-2:__UG_NAME__ -> 98:envelope___control___6 ;
-3:__UG_NAME__ -> 98:envelope___control___7 ;
-115:__UG_NAME__ -> 116:gate ;
-20:__UG_NAME__ -> 116:envelope___control___0 ;
-20:__UG_NAME__ -> 116:envelope___control___4 ;
-21:__UG_NAME__ -> 116:envelope___control___5 ;
-22:__UG_NAME__ -> 116:envelope___control___6 ;
-23:__UG_NAME__ -> 116:envelope___control___7 ;
-128:__UG_NAME__ -> 129:gate ;
-4:__UG_NAME__ -> 129:envelope___control___0 ;
-4:__UG_NAME__ -> 129:envelope___control___4 ;
-5:__UG_NAME__ -> 129:envelope___control___5 ;
-6:__UG_NAME__ -> 129:envelope___control___6 ;
-7:__UG_NAME__ -> 129:envelope___control___7 ;
-16:__UG_NAME__ -> 133:envelope___control___4 ;
-12:__UG_NAME__ -> 133:envelope___control___5 ;
-19:__UG_NAME__ -> 133:envelope___control___6 ;
-132:__UG_NAME__ -> 133:envelope___select___8 ;
-13:__UG_NAME__ -> 133:envelope___control___9 ;
-19:__UG_NAME__ -> 133:envelope___control___10 ;
-18:__UG_NAME__ -> 133:envelope___control___12 ;
-14:__UG_NAME__ -> 133:envelope___control___13 ;
-19:__UG_NAME__ -> 133:envelope___control___14 ;
-15:__UG_NAME__ -> 133:envelope___control___17 ;
-19:__UG_NAME__ -> 133:envelope___control___18 ;
-143:__UG_NAME__ -> 144:gate ;
-8:__UG_NAME__ -> 144:envelope___control___0 ;
-8:__UG_NAME__ -> 144:envelope___control___4 ;
-9:__UG_NAME__ -> 144:envelope___control___5 ;
-10:__UG_NAME__ -> 144:envelope___control___6 ;
-11:__UG_NAME__ -> 144:envelope___control___7 ;
-24:__UG_NAME__ -> 41:in ;
-25:__UG_NAME__ -> 45:in ;
-32:__UG_NAME__ -> 56:in ;
-33:__UG_NAME__ -> 60:in ;
-28:__UG_NAME__ -> 80:in ;
-29:__UG_NAME__ -> 84:in ;
-0:__UG_NAME__ -> 90:in ;
-1:__UG_NAME__ -> 94:in ;
-20:__UG_NAME__ -> 108:in ;
-21:__UG_NAME__ -> 112:in ;
-9:__UG_NAME__ -> 119:in ;
-4:__UG_NAME__ -> 120:in ;
-5:__UG_NAME__ -> 125:in ;
-8:__UG_NAME__ -> 137:in ;
-64:__UG_NAME__ -> 65:width ;
-36:__UG_NAME__ -> 65:iphase ;
-50:__UG_NAME__ -> 65:freq ;
-52:__UG_NAME__ -> 53:iphase ;
-50:__UG_NAME__ -> 53:freq ;
-68:__UG_NAME__ -> 69:iphase ;
-50:__UG_NAME__ -> 69:freq ;
-117:__UG_NAME__ -> 118:freq ;
-106:__UG_NAME__ -> 118:in ;
-104:__UG_NAME__ -> 105:a ;
-116:__UG_NAME__ -> 117:a ;
-103:__UG_NAME__ -> 104:add ;
-101:__UG_NAME__ -> 104:mul ;
-78:__UG_NAME__ -> 104:in ;
-118:__UG_NAME__ -> 135:in ;
-145:__UG_NAME__ -> 146:signals___pan2___0 ;
-145:__UG_NAME__ -> 146:signals___pan2___1 ;
-39:__UG_NAME__ -> 146:bus ;
-129:__UG_NAME__ -> 145:level ;
-144:__UG_NAME__ -> 145:pos ;
-136:__UG_NAME__ -> 145:in ;
-54:__UG_NAME__ -> 73:array___binary____op____u____gen___0 ;
-67:__UG_NAME__ -> 73:array___binary____op____u____gen___1 ;
-69:__UG_NAME__ -> 73:array___lf____tri___2 ;
-72:__UG_NAME__ -> 73:array___sin____osc___3 ;
-37:__UG_NAME__ -> 73:which ;
-17:__UG_NAME__ -> 132:array___control___0 ;
-18:__UG_NAME__ -> 132:array___control___1 ;
-131:__UG_NAME__ -> 132:which ;
-71:__UG_NAME__ -> 72:phase ;
-50:__UG_NAME__ -> 72:freq ;
-105:__UG_NAME__ -> 106:freq ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-mod_tri.dot b/etc/synthdefs/graphviz/sonic-pi-mod_tri.dot
deleted file mode 100644
index 7f15c2b..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-mod_tri.dot
+++ /dev/null
@@ -1,413 +0,0 @@
-digraph synthdef {
-55 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> 6.2831855} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-143 [label = "{{ <a> 1.5|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-131 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-139 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-134 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-126 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-130 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-138 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-137 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :mod_phase
- default: 0.25" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :mod_phase_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :mod_phase_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :mod_phase_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :mod_range
- default: 5.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :mod_range_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :mod_range_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :mod_range_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :mod_pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :mod_pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :mod_pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :mod_pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :mod_phase_offset
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "control
- :mod_wave
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "control
- :mod_invert_wave
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-53 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-136 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-133 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-132 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <freq> freq|<iphase> iphase|<width> width} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <freq> freq|<iphase> iphase 0.0} |<__UG_NAME__>lf-tri }" style="filled, bold, rounded"  shape=record rankdir=LR];
-118 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-107 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <in> in|<mul> mul|<add> add} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-146 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-145 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-77 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-135 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <freq> freq|<phase> phase|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-
-36:__UG_NAME__ -> 55:b ;
-57:__UG_NAME__ -> 58:b ;
-69:__UG_NAME__ -> 70:b ;
-74:__UG_NAME__ -> 75:a ;
-77:__UG_NAME__ -> 78:b ;
-79:__UG_NAME__ -> 80:b ;
-81:__UG_NAME__ -> 82:b ;
-78:__UG_NAME__ -> 82:a ;
-103:__UG_NAME__ -> 104:a ;
-136:__UG_NAME__ -> 143:b ;
-119:__UG_NAME__ -> 144:b ;
-143:__UG_NAME__ -> 144:a ;
-47:__UG_NAME__ -> 48:b ;
-44:__UG_NAME__ -> 48:a ;
-51:__UG_NAME__ -> 52:b ;
-48:__UG_NAME__ -> 52:a ;
-55:__UG_NAME__ -> 56:a ;
-62:__UG_NAME__ -> 63:b ;
-59:__UG_NAME__ -> 63:a ;
-66:__UG_NAME__ -> 67:b ;
-63:__UG_NAME__ -> 67:a ;
-55:__UG_NAME__ -> 72:a ;
-36:__UG_NAME__ -> 74:a ;
-86:__UG_NAME__ -> 87:b ;
-83:__UG_NAME__ -> 87:a ;
-90:__UG_NAME__ -> 91:b ;
-87:__UG_NAME__ -> 91:a ;
-96:__UG_NAME__ -> 97:b ;
-93:__UG_NAME__ -> 97:a ;
-98:__UG_NAME__ -> 99:b ;
-97:__UG_NAME__ -> 99:a ;
-100:__UG_NAME__ -> 101:b ;
-92:__UG_NAME__ -> 101:a ;
-112:__UG_NAME__ -> 113:b ;
-109:__UG_NAME__ -> 113:a ;
-114:__UG_NAME__ -> 115:b ;
-113:__UG_NAME__ -> 115:a ;
-126:__UG_NAME__ -> 127:b ;
-123:__UG_NAME__ -> 127:a ;
-130:__UG_NAME__ -> 131:b ;
-127:__UG_NAME__ -> 131:a ;
-138:__UG_NAME__ -> 139:b ;
-132:__UG_NAME__ -> 139:a ;
-122:__UG_NAME__ -> 140:b ;
-139:__UG_NAME__ -> 140:a ;
-70:__UG_NAME__ -> 71:a ;
-80:__UG_NAME__ -> 81:a ;
-100:__UG_NAME__ -> 102:b ;
-101:__UG_NAME__ -> 102:a ;
-104:__UG_NAME__ -> 105:b ;
-100:__UG_NAME__ -> 105:a ;
-53:__UG_NAME__ -> 54:b ;
-102:__UG_NAME__ -> 103:a ;
-17:__UG_NAME__ -> 134:b ;
-46:__UG_NAME__ -> 47:a ;
-50:__UG_NAME__ -> 51:a ;
-61:__UG_NAME__ -> 62:a ;
-65:__UG_NAME__ -> 66:a ;
-38:__UG_NAME__ -> 79:a ;
-85:__UG_NAME__ -> 86:a ;
-89:__UG_NAME__ -> 90:a ;
-95:__UG_NAME__ -> 96:a ;
-43:__UG_NAME__ -> 98:a ;
-111:__UG_NAME__ -> 112:a ;
-41:__UG_NAME__ -> 114:a ;
-121:__UG_NAME__ -> 122:a ;
-125:__UG_NAME__ -> 126:a ;
-129:__UG_NAME__ -> 130:a ;
-137:__UG_NAME__ -> 138:a ;
-40:__UG_NAME__ -> 41:a ;
-42:__UG_NAME__ -> 43:a ;
-45:__UG_NAME__ -> 46:a ;
-49:__UG_NAME__ -> 50:a ;
-60:__UG_NAME__ -> 61:a ;
-64:__UG_NAME__ -> 65:a ;
-84:__UG_NAME__ -> 85:a ;
-88:__UG_NAME__ -> 89:a ;
-94:__UG_NAME__ -> 95:a ;
-110:__UG_NAME__ -> 111:a ;
-120:__UG_NAME__ -> 121:a ;
-124:__UG_NAME__ -> 125:a ;
-128:__UG_NAME__ -> 129:a ;
-133:__UG_NAME__ -> 137:a ;
-52:__UG_NAME__ -> 53:gate ;
-24:__UG_NAME__ -> 53:envelope___control___0 ;
-24:__UG_NAME__ -> 53:envelope___control___4 ;
-25:__UG_NAME__ -> 53:envelope___control___5 ;
-26:__UG_NAME__ -> 53:envelope___control___6 ;
-27:__UG_NAME__ -> 53:envelope___control___7 ;
-67:__UG_NAME__ -> 68:gate ;
-32:__UG_NAME__ -> 68:envelope___control___0 ;
-32:__UG_NAME__ -> 68:envelope___control___4 ;
-33:__UG_NAME__ -> 68:envelope___control___5 ;
-34:__UG_NAME__ -> 68:envelope___control___6 ;
-35:__UG_NAME__ -> 68:envelope___control___7 ;
-91:__UG_NAME__ -> 92:gate ;
-28:__UG_NAME__ -> 92:envelope___control___0 ;
-28:__UG_NAME__ -> 92:envelope___control___4 ;
-29:__UG_NAME__ -> 92:envelope___control___5 ;
-30:__UG_NAME__ -> 92:envelope___control___6 ;
-31:__UG_NAME__ -> 92:envelope___control___7 ;
-99:__UG_NAME__ -> 100:gate ;
-0:__UG_NAME__ -> 100:envelope___control___0 ;
-0:__UG_NAME__ -> 100:envelope___control___4 ;
-1:__UG_NAME__ -> 100:envelope___control___5 ;
-2:__UG_NAME__ -> 100:envelope___control___6 ;
-3:__UG_NAME__ -> 100:envelope___control___7 ;
-115:__UG_NAME__ -> 116:gate ;
-20:__UG_NAME__ -> 116:envelope___control___0 ;
-20:__UG_NAME__ -> 116:envelope___control___4 ;
-21:__UG_NAME__ -> 116:envelope___control___5 ;
-22:__UG_NAME__ -> 116:envelope___control___6 ;
-23:__UG_NAME__ -> 116:envelope___control___7 ;
-16:__UG_NAME__ -> 136:envelope___control___4 ;
-12:__UG_NAME__ -> 136:envelope___control___5 ;
-19:__UG_NAME__ -> 136:envelope___control___6 ;
-135:__UG_NAME__ -> 136:envelope___select___8 ;
-13:__UG_NAME__ -> 136:envelope___control___9 ;
-19:__UG_NAME__ -> 136:envelope___control___10 ;
-18:__UG_NAME__ -> 136:envelope___control___12 ;
-14:__UG_NAME__ -> 136:envelope___control___13 ;
-19:__UG_NAME__ -> 136:envelope___control___14 ;
-15:__UG_NAME__ -> 136:envelope___control___17 ;
-19:__UG_NAME__ -> 136:envelope___control___18 ;
-140:__UG_NAME__ -> 141:gate ;
-4:__UG_NAME__ -> 141:envelope___control___0 ;
-4:__UG_NAME__ -> 141:envelope___control___4 ;
-5:__UG_NAME__ -> 141:envelope___control___5 ;
-6:__UG_NAME__ -> 141:envelope___control___6 ;
-7:__UG_NAME__ -> 141:envelope___control___7 ;
-131:__UG_NAME__ -> 142:gate ;
-8:__UG_NAME__ -> 142:envelope___control___0 ;
-8:__UG_NAME__ -> 142:envelope___control___4 ;
-9:__UG_NAME__ -> 142:envelope___control___5 ;
-10:__UG_NAME__ -> 142:envelope___control___6 ;
-11:__UG_NAME__ -> 142:envelope___control___7 ;
-21:__UG_NAME__ -> 40:in ;
-1:__UG_NAME__ -> 42:in ;
-24:__UG_NAME__ -> 45:in ;
-25:__UG_NAME__ -> 49:in ;
-32:__UG_NAME__ -> 60:in ;
-33:__UG_NAME__ -> 64:in ;
-28:__UG_NAME__ -> 84:in ;
-29:__UG_NAME__ -> 88:in ;
-0:__UG_NAME__ -> 94:in ;
-20:__UG_NAME__ -> 110:in ;
-5:__UG_NAME__ -> 120:in ;
-8:__UG_NAME__ -> 124:in ;
-9:__UG_NAME__ -> 128:in ;
-4:__UG_NAME__ -> 133:in ;
-68:__UG_NAME__ -> 69:width ;
-36:__UG_NAME__ -> 69:iphase ;
-54:__UG_NAME__ -> 69:freq ;
-56:__UG_NAME__ -> 57:iphase ;
-54:__UG_NAME__ -> 57:freq ;
-72:__UG_NAME__ -> 73:iphase ;
-54:__UG_NAME__ -> 73:freq ;
-107:__UG_NAME__ -> 108:freq ;
-117:__UG_NAME__ -> 118:freq ;
-108:__UG_NAME__ -> 118:in ;
-106:__UG_NAME__ -> 107:a ;
-116:__UG_NAME__ -> 117:a ;
-105:__UG_NAME__ -> 106:add ;
-103:__UG_NAME__ -> 106:mul ;
-82:__UG_NAME__ -> 106:in ;
-118:__UG_NAME__ -> 119:in ;
-145:__UG_NAME__ -> 146:signals___pan2___0 ;
-145:__UG_NAME__ -> 146:signals___pan2___1 ;
-39:__UG_NAME__ -> 146:bus ;
-141:__UG_NAME__ -> 145:level ;
-142:__UG_NAME__ -> 145:pos ;
-144:__UG_NAME__ -> 145:in ;
-58:__UG_NAME__ -> 77:array___binary____op____u____gen___0 ;
-71:__UG_NAME__ -> 77:array___binary____op____u____gen___1 ;
-73:__UG_NAME__ -> 77:array___lf____tri___2 ;
-76:__UG_NAME__ -> 77:array___sin____osc___3 ;
-37:__UG_NAME__ -> 77:which ;
-17:__UG_NAME__ -> 135:array___control___0 ;
-18:__UG_NAME__ -> 135:array___control___1 ;
-134:__UG_NAME__ -> 135:which ;
-75:__UG_NAME__ -> 76:phase ;
-54:__UG_NAME__ -> 76:freq ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-mono_player.dot b/etc/synthdefs/graphviz/sonic-pi-mono_player.dot
deleted file mode 100644
index 290a37e..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-mono_player.dot
+++ /dev/null
@@ -1,644 +0,0 @@
-digraph synthdef {
-86 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-215 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-153 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-157 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-164 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-168 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-173 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-177 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-185 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-188 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-195 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-199 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-205 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-208 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-212 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-213 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-221 [label = "{{ <a> 0.03|<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="dashed, rounded" shape=record rankdir=LR];
-125 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-126 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
-209 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-152 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-156 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-163 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-167 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-172 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-176 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-184 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-187 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-198 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-207 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-130 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-151 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-155 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-162 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-166 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-171 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-175 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-183 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-186 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-197 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>absdif }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <buf> buf} |<__UG_NAME__>buf-dur }" style="dashed, rounded" shape=record rankdir=LR];
-94 [label = "{{ <buf> buf} |<__UG_NAME__>buf-frames }" style="dashed, rounded" shape=record rankdir=LR];
-121 [label = "{{ <num____channels> num-channels 1|<bufnum> bufnum|<phase> phase|<loop> loop 1.0|<interpolation> interpolation 2.0} |<__UG_NAME__>buf-rd }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :buf
- default: 0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :cutoff_attack_level
- default: -1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :cutoff_decay_level
- default: -1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :cutoff_sustain_level
- default: -1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :decay
- default: 0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :sustain
- default: -1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :release
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :attack_level
- default: 1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :decay_level
- default: -1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :sustain_level
- default: 1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :cutoff
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :cutoff_sustain
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :cutoff_decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :cutoff_release
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :cutoff_min
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :cutoff_min_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :cutoff_min_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :cutoff_min_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :cutoff_env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :res
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "control
- :rate
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "control
- :start
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "control
- :finish
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-40 [label = "control
- :norm
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-41 [label = "control
- :pitch
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "control
- :pitch_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-43 [label = "control
- :pitch_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-44 [label = "control
- :pitch_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-45 [label = "control
- :window_size
- default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-46 [label = "control
- :window_size_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-47 [label = "control
- :window_size_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-48 [label = "control
- :window_size_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-49 [label = "control
- :pitch_dis
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-50 [label = "control
- :pitch_dis_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-51 [label = "control
- :pitch_dis_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-52 [label = "control
- :pitch_dis_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-53 [label = "control
- :time_dis
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-54 [label = "control
- :time_dis_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-55 [label = "control
- :time_dis_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-56 [label = "control
- :time_dis_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-57 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-74 [label = "{{ {{<envelope___select___0>|1.0|-99|-99|<envelope___select___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ {{<envelope___env____gen___0>|4|-99|-99|<envelope___select___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___select___12>|<envelope___select___13>|<envelope___control___14>|0.0|<envelope___env____gen___16>|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-147 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-158 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-169 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-178 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-189 [label = "{{ {{<envelope___select___0>|1.0|-99|-99|<envelope___select___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-200 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-211 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___select___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-216 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-217 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-150 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-154 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-161 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-165 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-170 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-174 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-182 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-196 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-149 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-160 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-181 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-194 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-204 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-206 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <start> start|<end> end|<dur> dur|<action> action 0.0} |<__UG_NAME__>line }" style="filled, bold, rounded"  shape=record rankdir=LR];
-222 [label = "{{ <start> start 1.0|<end> end 1.0|<dur> dur|<action> action 2.0} |<__UG_NAME__>line }" style="bold, rounded" shape=record rankdir=LR];
-190 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-191 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-220 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-159 [label = "{{ <a> |<b> } |<__UG_NAME__>midiratio }" style="bold, rounded" shape=record rankdir=LR];
-192 [label = "{{ <a> |<b> } |<__UG_NAME__>min }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-203 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-115 [label = "{{ <a> |<b> } |<__UG_NAME__>not-pos? }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <a> |<b> } |<__UG_NAME__>not-pos? }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <a> 0.0|<b> } |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
-131 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
-132 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
-133 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
-135 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
-137 [label = "{{ <a> 0.0|<b> } |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
-139 [label = "{{ <a> 0.0|<b> } |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
-148 [label = "{{ <a> 0.0|<b> } |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
-134 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
-136 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
-138 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
-143 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
-145 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
-146 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
-219 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-218 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-179 [label = "{{ <in> in|<window____size> window-size|<pitch____ratio> pitch-ratio|<pitch____dispersion> pitch-dispersion|<time____dispersion> time-dispersion} |<__UG_NAME__>pitch-shift }" style="filled, bold, rounded"  shape=record rankdir=LR];
-201 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-65 [label = "{{ <which> which|{{<array___control___0>|50}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <which> which|{{<array___control___0>|130}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <which> which|{{<array___control___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <which> which|{{<array___control___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <which> which|{{<array___control___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <which> which|{{<array___control___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <which> which|{{<array___control___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-180 [label = "{{ <which> which|{{<array___buf____rd___0>|<array___pitch____shift___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-193 [label = "{{ <which> which|{{<array___unary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-202 [label = "{{ <which> which|{{<array___select___0>|<array___rlpf___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-210 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-214 [label = "{{ <which> which|{{<array___select___0>|<array___normalizer___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-85:__UG_NAME__ -> 86:b ;
-84:__UG_NAME__ -> 86:a ;
-95:__UG_NAME__ -> 96:b ;
-38:__UG_NAME__ -> 96:a ;
-95:__UG_NAME__ -> 116:b ;
-39:__UG_NAME__ -> 116:a ;
-214:__UG_NAME__ -> 215:b ;
-211:__UG_NAME__ -> 215:a ;
-68:__UG_NAME__ -> 69:b ;
-63:__UG_NAME__ -> 69:a ;
-72:__UG_NAME__ -> 73:b ;
-69:__UG_NAME__ -> 73:a ;
-106:__UG_NAME__ -> 107:b ;
-103:__UG_NAME__ -> 107:a ;
-113:__UG_NAME__ -> 114:b ;
-107:__UG_NAME__ -> 114:a ;
-152:__UG_NAME__ -> 153:b ;
-149:__UG_NAME__ -> 153:a ;
-156:__UG_NAME__ -> 157:b ;
-153:__UG_NAME__ -> 157:a ;
-163:__UG_NAME__ -> 164:b ;
-160:__UG_NAME__ -> 164:a ;
-167:__UG_NAME__ -> 168:b ;
-164:__UG_NAME__ -> 168:a ;
-172:__UG_NAME__ -> 173:b ;
-110:__UG_NAME__ -> 173:a ;
-176:__UG_NAME__ -> 177:b ;
-173:__UG_NAME__ -> 177:a ;
-184:__UG_NAME__ -> 185:b ;
-181:__UG_NAME__ -> 185:a ;
-187:__UG_NAME__ -> 188:b ;
-185:__UG_NAME__ -> 188:a ;
-61:__UG_NAME__ -> 195:b ;
-194:__UG_NAME__ -> 195:a ;
-198:__UG_NAME__ -> 199:b ;
-195:__UG_NAME__ -> 199:a ;
-99:__UG_NAME__ -> 205:b ;
-204:__UG_NAME__ -> 205:a ;
-207:__UG_NAME__ -> 208:b ;
-205:__UG_NAME__ -> 208:a ;
-123:__UG_NAME__ -> 212:b ;
-206:__UG_NAME__ -> 212:a ;
-102:__UG_NAME__ -> 213:b ;
-212:__UG_NAME__ -> 213:a ;
-88:__UG_NAME__ -> 221:b ;
-23:__UG_NAME__ -> 89:b ;
-88:__UG_NAME__ -> 89:a ;
-26:__UG_NAME__ -> 90:b ;
-89:__UG_NAME__ -> 90:a ;
-25:__UG_NAME__ -> 91:b ;
-90:__UG_NAME__ -> 91:a ;
-94:__UG_NAME__ -> 95:a ;
-4:__UG_NAME__ -> 125:b ;
-88:__UG_NAME__ -> 125:a ;
-7:__UG_NAME__ -> 126:b ;
-125:__UG_NAME__ -> 126:a ;
-5:__UG_NAME__ -> 127:b ;
-126:__UG_NAME__ -> 127:a ;
-87:__UG_NAME__ -> 88:b ;
-86:__UG_NAME__ -> 88:a ;
-27:__UG_NAME__ -> 64:b ;
-1:__UG_NAME__ -> 75:b ;
-19:__UG_NAME__ -> 76:b ;
-2:__UG_NAME__ -> 79:b ;
-3:__UG_NAME__ -> 80:b ;
-24:__UG_NAME__ -> 83:b ;
-6:__UG_NAME__ -> 124:b ;
-9:__UG_NAME__ -> 209:b ;
-60:__UG_NAME__ -> 61:a ;
-67:__UG_NAME__ -> 68:a ;
-71:__UG_NAME__ -> 72:a ;
-98:__UG_NAME__ -> 99:a ;
-101:__UG_NAME__ -> 102:a ;
-105:__UG_NAME__ -> 106:a ;
-112:__UG_NAME__ -> 113:a ;
-109:__UG_NAME__ -> 123:a ;
-151:__UG_NAME__ -> 152:a ;
-155:__UG_NAME__ -> 156:a ;
-162:__UG_NAME__ -> 163:a ;
-166:__UG_NAME__ -> 167:a ;
-171:__UG_NAME__ -> 172:a ;
-175:__UG_NAME__ -> 176:a ;
-183:__UG_NAME__ -> 184:a ;
-186:__UG_NAME__ -> 187:a ;
-197:__UG_NAME__ -> 198:a ;
-130:__UG_NAME__ -> 207:a ;
-59:__UG_NAME__ -> 60:a ;
-66:__UG_NAME__ -> 67:a ;
-70:__UG_NAME__ -> 71:a ;
-37:__UG_NAME__ -> 87:a ;
-97:__UG_NAME__ -> 98:a ;
-100:__UG_NAME__ -> 101:a ;
-104:__UG_NAME__ -> 105:a ;
-108:__UG_NAME__ -> 109:a ;
-111:__UG_NAME__ -> 112:a ;
-129:__UG_NAME__ -> 130:a ;
-150:__UG_NAME__ -> 151:a ;
-154:__UG_NAME__ -> 155:a ;
-161:__UG_NAME__ -> 162:a ;
-165:__UG_NAME__ -> 166:a ;
-170:__UG_NAME__ -> 171:a ;
-174:__UG_NAME__ -> 175:a ;
-182:__UG_NAME__ -> 183:a ;
-62:__UG_NAME__ -> 186:a ;
-196:__UG_NAME__ -> 197:a ;
-38:__UG_NAME__ -> 85:b ;
-39:__UG_NAME__ -> 85:a ;
-0:__UG_NAME__ -> 84:buf ;
-0:__UG_NAME__ -> 94:buf ;
-120:__UG_NAME__ -> 121:phase ;
-0:__UG_NAME__ -> 121:bufnum ;
-73:__UG_NAME__ -> 74:gate ;
-65:__UG_NAME__ -> 74:envelope___select___0 ;
-65:__UG_NAME__ -> 74:envelope___select___4 ;
-28:__UG_NAME__ -> 74:envelope___control___5 ;
-29:__UG_NAME__ -> 74:envelope___control___6 ;
-30:__UG_NAME__ -> 74:envelope___control___7 ;
-74:__UG_NAME__ -> 93:envelope___env____gen___0 ;
-78:__UG_NAME__ -> 93:envelope___select___4 ;
-23:__UG_NAME__ -> 93:envelope___control___5 ;
-31:__UG_NAME__ -> 93:envelope___control___6 ;
-82:__UG_NAME__ -> 93:envelope___select___8 ;
-25:__UG_NAME__ -> 93:envelope___control___9 ;
-31:__UG_NAME__ -> 93:envelope___control___10 ;
-81:__UG_NAME__ -> 93:envelope___select___12 ;
-92:__UG_NAME__ -> 93:envelope___select___13 ;
-31:__UG_NAME__ -> 93:envelope___control___14 ;
-74:__UG_NAME__ -> 93:envelope___env____gen___16 ;
-26:__UG_NAME__ -> 93:envelope___control___17 ;
-31:__UG_NAME__ -> 93:envelope___control___18 ;
-114:__UG_NAME__ -> 147:gate ;
-41:__UG_NAME__ -> 147:envelope___control___0 ;
-41:__UG_NAME__ -> 147:envelope___control___4 ;
-42:__UG_NAME__ -> 147:envelope___control___5 ;
-43:__UG_NAME__ -> 147:envelope___control___6 ;
-44:__UG_NAME__ -> 147:envelope___control___7 ;
-157:__UG_NAME__ -> 158:gate ;
-45:__UG_NAME__ -> 158:envelope___control___0 ;
-45:__UG_NAME__ -> 158:envelope___control___4 ;
-46:__UG_NAME__ -> 158:envelope___control___5 ;
-47:__UG_NAME__ -> 158:envelope___control___6 ;
-48:__UG_NAME__ -> 158:envelope___control___7 ;
-168:__UG_NAME__ -> 169:gate ;
-49:__UG_NAME__ -> 169:envelope___control___0 ;
-49:__UG_NAME__ -> 169:envelope___control___4 ;
-50:__UG_NAME__ -> 169:envelope___control___5 ;
-51:__UG_NAME__ -> 169:envelope___control___6 ;
-52:__UG_NAME__ -> 169:envelope___control___7 ;
-177:__UG_NAME__ -> 178:gate ;
-53:__UG_NAME__ -> 178:envelope___control___0 ;
-53:__UG_NAME__ -> 178:envelope___control___4 ;
-54:__UG_NAME__ -> 178:envelope___control___5 ;
-55:__UG_NAME__ -> 178:envelope___control___6 ;
-56:__UG_NAME__ -> 178:envelope___control___7 ;
-188:__UG_NAME__ -> 189:gate ;
-77:__UG_NAME__ -> 189:envelope___select___0 ;
-77:__UG_NAME__ -> 189:envelope___select___4 ;
-20:__UG_NAME__ -> 189:envelope___control___5 ;
-21:__UG_NAME__ -> 189:envelope___control___6 ;
-22:__UG_NAME__ -> 189:envelope___control___7 ;
-199:__UG_NAME__ -> 200:gate ;
-58:__UG_NAME__ -> 200:envelope___mul____add___0 ;
-58:__UG_NAME__ -> 200:envelope___mul____add___4 ;
-33:__UG_NAME__ -> 200:envelope___control___5 ;
-34:__UG_NAME__ -> 200:envelope___control___6 ;
-35:__UG_NAME__ -> 200:envelope___control___7 ;
-8:__UG_NAME__ -> 211:envelope___control___4 ;
-4:__UG_NAME__ -> 211:envelope___control___5 ;
-36:__UG_NAME__ -> 211:envelope___control___6 ;
-210:__UG_NAME__ -> 211:envelope___select___8 ;
-5:__UG_NAME__ -> 211:envelope___control___9 ;
-36:__UG_NAME__ -> 211:envelope___control___10 ;
-10:__UG_NAME__ -> 211:envelope___control___12 ;
-128:__UG_NAME__ -> 211:envelope___select___13 ;
-36:__UG_NAME__ -> 211:envelope___control___14 ;
-7:__UG_NAME__ -> 211:envelope___control___17 ;
-36:__UG_NAME__ -> 211:envelope___control___18 ;
-213:__UG_NAME__ -> 216:gate ;
-15:__UG_NAME__ -> 216:envelope___control___0 ;
-15:__UG_NAME__ -> 216:envelope___control___4 ;
-16:__UG_NAME__ -> 216:envelope___control___5 ;
-17:__UG_NAME__ -> 216:envelope___control___6 ;
-18:__UG_NAME__ -> 216:envelope___control___7 ;
-208:__UG_NAME__ -> 217:gate ;
-11:__UG_NAME__ -> 217:envelope___control___0 ;
-11:__UG_NAME__ -> 217:envelope___control___4 ;
-12:__UG_NAME__ -> 217:envelope___control___5 ;
-13:__UG_NAME__ -> 217:envelope___control___6 ;
-14:__UG_NAME__ -> 217:envelope___control___7 ;
-58:__UG_NAME__ -> 59:in ;
-20:__UG_NAME__ -> 62:in ;
-65:__UG_NAME__ -> 66:in ;
-28:__UG_NAME__ -> 70:in ;
-11:__UG_NAME__ -> 97:in ;
-16:__UG_NAME__ -> 100:in ;
-41:__UG_NAME__ -> 104:in ;
-15:__UG_NAME__ -> 108:in ;
-42:__UG_NAME__ -> 111:in ;
-12:__UG_NAME__ -> 129:in ;
-45:__UG_NAME__ -> 150:in ;
-46:__UG_NAME__ -> 154:in ;
-49:__UG_NAME__ -> 161:in ;
-50:__UG_NAME__ -> 165:in ;
-53:__UG_NAME__ -> 170:in ;
-54:__UG_NAME__ -> 174:in ;
-77:__UG_NAME__ -> 182:in ;
-33:__UG_NAME__ -> 196:in ;
-88:__UG_NAME__ -> 120:dur ;
-119:__UG_NAME__ -> 120:end ;
-117:__UG_NAME__ -> 120:start ;
-221:__UG_NAME__ -> 222:dur ;
-189:__UG_NAME__ -> 190:a ;
-93:__UG_NAME__ -> 191:a ;
-74:__UG_NAME__ -> 220:a ;
-147:__UG_NAME__ -> 159:a ;
-190:__UG_NAME__ -> 192:b ;
-191:__UG_NAME__ -> 192:a ;
-32:__UG_NAME__ -> 58:in ;
-202:__UG_NAME__ -> 203:in ;
-37:__UG_NAME__ -> 115:a ;
-37:__UG_NAME__ -> 118:a ;
-26:__UG_NAME__ -> 122:b ;
-19:__UG_NAME__ -> 131:b ;
-1:__UG_NAME__ -> 132:b ;
-2:__UG_NAME__ -> 133:b ;
-3:__UG_NAME__ -> 135:b ;
-23:__UG_NAME__ -> 137:b ;
-25:__UG_NAME__ -> 139:b ;
-24:__UG_NAME__ -> 142:b ;
-27:__UG_NAME__ -> 144:b ;
-147:__UG_NAME__ -> 148:b ;
-133:__UG_NAME__ -> 134:b ;
-132:__UG_NAME__ -> 134:a ;
-135:__UG_NAME__ -> 136:b ;
-134:__UG_NAME__ -> 136:a ;
-137:__UG_NAME__ -> 138:b ;
-136:__UG_NAME__ -> 138:a ;
-139:__UG_NAME__ -> 140:b ;
-138:__UG_NAME__ -> 140:a ;
-122:__UG_NAME__ -> 141:b ;
-140:__UG_NAME__ -> 141:a ;
-142:__UG_NAME__ -> 143:b ;
-141:__UG_NAME__ -> 143:a ;
-144:__UG_NAME__ -> 145:b ;
-143:__UG_NAME__ -> 145:a ;
-145:__UG_NAME__ -> 146:b ;
-131:__UG_NAME__ -> 146:a ;
-218:__UG_NAME__ -> 219:signals___pan2___0 ;
-218:__UG_NAME__ -> 219:signals___pan2___1 ;
-57:__UG_NAME__ -> 219:bus ;
-217:__UG_NAME__ -> 218:level ;
-216:__UG_NAME__ -> 218:pos ;
-215:__UG_NAME__ -> 218:in ;
-178:__UG_NAME__ -> 179:time____dispersion ;
-169:__UG_NAME__ -> 179:pitch____dispersion ;
-159:__UG_NAME__ -> 179:pitch____ratio ;
-158:__UG_NAME__ -> 179:window____size ;
-121:__UG_NAME__ -> 179:in ;
-200:__UG_NAME__ -> 201:rq ;
-193:__UG_NAME__ -> 201:freq ;
-180:__UG_NAME__ -> 201:in ;
-27:__UG_NAME__ -> 65:array___control___0 ;
-64:__UG_NAME__ -> 65:which ;
-19:__UG_NAME__ -> 77:array___control___0 ;
-76:__UG_NAME__ -> 77:which ;
-1:__UG_NAME__ -> 78:array___control___0 ;
-77:__UG_NAME__ -> 78:array___select___1 ;
-75:__UG_NAME__ -> 78:which ;
-3:__UG_NAME__ -> 81:array___control___0 ;
-78:__UG_NAME__ -> 81:array___select___1 ;
-80:__UG_NAME__ -> 81:which ;
-2:__UG_NAME__ -> 82:array___control___0 ;
-81:__UG_NAME__ -> 82:array___select___1 ;
-79:__UG_NAME__ -> 82:which ;
-24:__UG_NAME__ -> 92:array___control___0 ;
-91:__UG_NAME__ -> 92:array___binary____op____u____gen___1 ;
-83:__UG_NAME__ -> 92:which ;
-96:__UG_NAME__ -> 117:array___binary____op____u____gen___0 ;
-116:__UG_NAME__ -> 117:array___binary____op____u____gen___1 ;
-115:__UG_NAME__ -> 117:which ;
-116:__UG_NAME__ -> 119:array___binary____op____u____gen___0 ;
-96:__UG_NAME__ -> 119:array___binary____op____u____gen___1 ;
-118:__UG_NAME__ -> 119:which ;
-6:__UG_NAME__ -> 128:array___control___0 ;
-127:__UG_NAME__ -> 128:array___binary____op____u____gen___1 ;
-124:__UG_NAME__ -> 128:which ;
-121:__UG_NAME__ -> 180:array___buf____rd___0 ;
-179:__UG_NAME__ -> 180:array___pitch____shift___1 ;
-148:__UG_NAME__ -> 180:which ;
-190:__UG_NAME__ -> 193:array___unary____op____u____gen___0 ;
-192:__UG_NAME__ -> 193:array___binary____op____u____gen___1 ;
-145:__UG_NAME__ -> 193:which ;
-180:__UG_NAME__ -> 202:array___select___0 ;
-201:__UG_NAME__ -> 202:array___rlpf___1 ;
-146:__UG_NAME__ -> 202:which ;
-9:__UG_NAME__ -> 210:array___control___0 ;
-10:__UG_NAME__ -> 210:array___control___1 ;
-209:__UG_NAME__ -> 210:which ;
-202:__UG_NAME__ -> 214:array___select___0 ;
-203:__UG_NAME__ -> 214:array___normalizer___1 ;
-40:__UG_NAME__ -> 214:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-noise.dot b/etc/synthdefs/graphviz/sonic-pi-noise.dot
deleted file mode 100644
index bc5234f..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-noise.dot
+++ /dev/null
@@ -1,223 +0,0 @@
-digraph synthdef {
-53 [label = "{{ <a> 0.9|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :cutoff
- default: 110.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :res
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-74 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-52 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-55 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{<__UG_NAME__>white-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-52:__UG_NAME__ -> 53:b ;
-56:__UG_NAME__ -> 57:b ;
-53:__UG_NAME__ -> 57:a ;
-37:__UG_NAME__ -> 38:b ;
-34:__UG_NAME__ -> 38:a ;
-40:__UG_NAME__ -> 41:b ;
-38:__UG_NAME__ -> 41:a ;
-45:__UG_NAME__ -> 46:b ;
-44:__UG_NAME__ -> 46:a ;
-49:__UG_NAME__ -> 50:b ;
-46:__UG_NAME__ -> 50:a ;
-61:__UG_NAME__ -> 62:b ;
-58:__UG_NAME__ -> 62:a ;
-64:__UG_NAME__ -> 65:b ;
-62:__UG_NAME__ -> 65:a ;
-68:__UG_NAME__ -> 69:b ;
-67:__UG_NAME__ -> 69:a ;
-71:__UG_NAME__ -> 72:b ;
-69:__UG_NAME__ -> 72:a ;
-13:__UG_NAME__ -> 54:b ;
-36:__UG_NAME__ -> 37:a ;
-39:__UG_NAME__ -> 40:a ;
-27:__UG_NAME__ -> 45:a ;
-48:__UG_NAME__ -> 49:a ;
-60:__UG_NAME__ -> 61:a ;
-63:__UG_NAME__ -> 64:a ;
-29:__UG_NAME__ -> 68:a ;
-70:__UG_NAME__ -> 71:a ;
-26:__UG_NAME__ -> 27:a ;
-28:__UG_NAME__ -> 29:a ;
-35:__UG_NAME__ -> 36:a ;
-30:__UG_NAME__ -> 39:a ;
-47:__UG_NAME__ -> 48:a ;
-59:__UG_NAME__ -> 60:a ;
-32:__UG_NAME__ -> 63:a ;
-31:__UG_NAME__ -> 70:a ;
-41:__UG_NAME__ -> 42:gate ;
-16:__UG_NAME__ -> 42:envelope___control___0 ;
-16:__UG_NAME__ -> 42:envelope___control___4 ;
-17:__UG_NAME__ -> 42:envelope___control___5 ;
-18:__UG_NAME__ -> 42:envelope___control___6 ;
-19:__UG_NAME__ -> 42:envelope___control___7 ;
-50:__UG_NAME__ -> 51:gate ;
-25:__UG_NAME__ -> 51:envelope___mul____add___0 ;
-25:__UG_NAME__ -> 51:envelope___mul____add___4 ;
-21:__UG_NAME__ -> 51:envelope___control___5 ;
-22:__UG_NAME__ -> 51:envelope___control___6 ;
-23:__UG_NAME__ -> 51:envelope___control___7 ;
-12:__UG_NAME__ -> 56:envelope___control___4 ;
-8:__UG_NAME__ -> 56:envelope___control___5 ;
-15:__UG_NAME__ -> 56:envelope___control___6 ;
-55:__UG_NAME__ -> 56:envelope___select___8 ;
-10:__UG_NAME__ -> 56:envelope___control___9 ;
-15:__UG_NAME__ -> 56:envelope___control___10 ;
-14:__UG_NAME__ -> 56:envelope___control___12 ;
-9:__UG_NAME__ -> 56:envelope___control___13 ;
-15:__UG_NAME__ -> 56:envelope___control___14 ;
-11:__UG_NAME__ -> 56:envelope___control___17 ;
-15:__UG_NAME__ -> 56:envelope___control___18 ;
-65:__UG_NAME__ -> 66:gate ;
-4:__UG_NAME__ -> 66:envelope___control___0 ;
-4:__UG_NAME__ -> 66:envelope___control___4 ;
-5:__UG_NAME__ -> 66:envelope___control___5 ;
-6:__UG_NAME__ -> 66:envelope___control___6 ;
-7:__UG_NAME__ -> 66:envelope___control___7 ;
-72:__UG_NAME__ -> 73:gate ;
-0:__UG_NAME__ -> 73:envelope___control___0 ;
-0:__UG_NAME__ -> 73:envelope___control___4 ;
-1:__UG_NAME__ -> 73:envelope___control___5 ;
-2:__UG_NAME__ -> 73:envelope___control___6 ;
-3:__UG_NAME__ -> 73:envelope___control___7 ;
-25:__UG_NAME__ -> 26:in ;
-0:__UG_NAME__ -> 28:in ;
-17:__UG_NAME__ -> 30:in ;
-1:__UG_NAME__ -> 31:in ;
-5:__UG_NAME__ -> 32:in ;
-16:__UG_NAME__ -> 35:in ;
-21:__UG_NAME__ -> 47:in ;
-4:__UG_NAME__ -> 59:in ;
-42:__UG_NAME__ -> 43:a ;
-20:__UG_NAME__ -> 25:in ;
-74:__UG_NAME__ -> 75:signals___pan2___0 ;
-74:__UG_NAME__ -> 75:signals___pan2___1 ;
-24:__UG_NAME__ -> 75:bus ;
-73:__UG_NAME__ -> 74:level ;
-66:__UG_NAME__ -> 74:pos ;
-57:__UG_NAME__ -> 74:in ;
-51:__UG_NAME__ -> 52:rq ;
-43:__UG_NAME__ -> 52:freq ;
-33:__UG_NAME__ -> 52:in ;
-13:__UG_NAME__ -> 55:array___control___0 ;
-14:__UG_NAME__ -> 55:array___control___1 ;
-54:__UG_NAME__ -> 55:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-piano.dot b/etc/synthdefs/graphviz/sonic-pi-piano.dot
deleted file mode 100644
index ccd863a..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-piano.dot
+++ /dev/null
@@ -1,178 +0,0 @@
-digraph synthdef {
-48 [label = "{{ <a> |<b> 127.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <left> left|<right> right|<pos> pos|<level> level} |<__UG_NAME__>balance2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-45 [label = "{{ <in> in|<lo> lo 0.0|<hi> hi 1.0} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <in> in|<lo> lo 0.0|<hi> hi 1.0} |<__UG_NAME__>clip }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :vel
- default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :hard
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :velcurve
- default: 0.8" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :stereo_width
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ {{0.0|4.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-23 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <hard> hard|<stretch> stretch 0.0|<velmuff> velmuff 0.8|<vel> vel|<decay> decay|<random> random 0.0|<gate> gate 1.0|<sustain> sustain 0.1|<velhard> velhard 0.8|<stereo> stereo|<release> release|<muffle> muffle 0.8|<velcurve> velcurve|<tune> tune 0.5|<freq> freq} |<__UG_NAME__>mda-piano }" style="filled, bold, rounded"  shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <in> in|<mul> mul 4.0|<add> add 0.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <in> in|<mul> mul 6.0|<add> add -3.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <bus> bus|{{<signals___binary____op____u____gen___0>|<signals___binary____op____u____gen___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-43 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-
-47:__UG_NAME__ -> 48:a ;
-53:__UG_NAME__ -> 54:b ;
-44:__UG_NAME__ -> 54:a ;
-53:__UG_NAME__ -> 55:b ;
-44:__UG_NAME__ -> 55:a ;
-28:__UG_NAME__ -> 29:b ;
-25:__UG_NAME__ -> 29:a ;
-33:__UG_NAME__ -> 34:b ;
-30:__UG_NAME__ -> 34:a ;
-37:__UG_NAME__ -> 38:b ;
-34:__UG_NAME__ -> 38:a ;
-40:__UG_NAME__ -> 41:b ;
-29:__UG_NAME__ -> 41:a ;
-14:__UG_NAME__ -> 42:b ;
-27:__UG_NAME__ -> 28:a ;
-32:__UG_NAME__ -> 33:a ;
-36:__UG_NAME__ -> 37:a ;
-24:__UG_NAME__ -> 40:a ;
-23:__UG_NAME__ -> 24:a ;
-26:__UG_NAME__ -> 27:a ;
-31:__UG_NAME__ -> 32:a ;
-35:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 53:level ;
-49:__UG_NAME__ -> 53:pos ;
-52:__UG_NAME__ -> 53:right ;
-52:__UG_NAME__ -> 53:left ;
-19:__UG_NAME__ -> 45:in ;
-17:__UG_NAME__ -> 46:in ;
-38:__UG_NAME__ -> 39:gate ;
-1:__UG_NAME__ -> 39:envelope___control___0 ;
-1:__UG_NAME__ -> 39:envelope___control___4 ;
-2:__UG_NAME__ -> 39:envelope___control___5 ;
-3:__UG_NAME__ -> 39:envelope___control___6 ;
-4:__UG_NAME__ -> 39:envelope___control___7 ;
-13:__UG_NAME__ -> 44:envelope___control___4 ;
-9:__UG_NAME__ -> 44:envelope___control___5 ;
-16:__UG_NAME__ -> 44:envelope___control___6 ;
-43:__UG_NAME__ -> 44:envelope___select___8 ;
-10:__UG_NAME__ -> 44:envelope___control___9 ;
-16:__UG_NAME__ -> 44:envelope___control___10 ;
-15:__UG_NAME__ -> 44:envelope___control___12 ;
-11:__UG_NAME__ -> 44:envelope___control___13 ;
-16:__UG_NAME__ -> 44:envelope___control___14 ;
-12:__UG_NAME__ -> 44:envelope___control___17 ;
-16:__UG_NAME__ -> 44:envelope___control___18 ;
-41:__UG_NAME__ -> 49:gate ;
-5:__UG_NAME__ -> 49:envelope___control___0 ;
-5:__UG_NAME__ -> 49:envelope___control___4 ;
-6:__UG_NAME__ -> 49:envelope___control___5 ;
-7:__UG_NAME__ -> 49:envelope___control___6 ;
-8:__UG_NAME__ -> 49:envelope___control___7 ;
-6:__UG_NAME__ -> 23:in ;
-5:__UG_NAME__ -> 26:in ;
-1:__UG_NAME__ -> 31:in ;
-2:__UG_NAME__ -> 35:in ;
-50:__UG_NAME__ -> 52:freq ;
-20:__UG_NAME__ -> 52:velcurve ;
-12:__UG_NAME__ -> 52:release ;
-21:__UG_NAME__ -> 52:stereo ;
-10:__UG_NAME__ -> 52:decay ;
-48:__UG_NAME__ -> 52:vel ;
-51:__UG_NAME__ -> 52:hard ;
-0:__UG_NAME__ -> 50:a ;
-46:__UG_NAME__ -> 47:in ;
-45:__UG_NAME__ -> 51:in ;
-54:__UG_NAME__ -> 56:signals___binary____op____u____gen___0 ;
-55:__UG_NAME__ -> 56:signals___binary____op____u____gen___1 ;
-22:__UG_NAME__ -> 56:bus ;
-14:__UG_NAME__ -> 43:array___control___0 ;
-15:__UG_NAME__ -> 43:array___control___1 ;
-42:__UG_NAME__ -> 43:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-pnoise.dot b/etc/synthdefs/graphviz/sonic-pi-pnoise.dot
deleted file mode 100644
index 9551f49..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-pnoise.dot
+++ /dev/null
@@ -1,223 +0,0 @@
-digraph synthdef {
-56 [label = "{{ <a> 3.0|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :cutoff
- default: 110.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :res
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-74 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-33 [label = "{<__UG_NAME__>pink-noise }" style="filled, bold, rounded"  shape=record rankdir=LR];
-55 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-26 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-
-55:__UG_NAME__ -> 56:b ;
-27:__UG_NAME__ -> 70:b ;
-56:__UG_NAME__ -> 70:a ;
-37:__UG_NAME__ -> 38:b ;
-34:__UG_NAME__ -> 38:a ;
-41:__UG_NAME__ -> 42:b ;
-38:__UG_NAME__ -> 42:a ;
-49:__UG_NAME__ -> 50:b ;
-45:__UG_NAME__ -> 50:a ;
-52:__UG_NAME__ -> 53:b ;
-50:__UG_NAME__ -> 53:a ;
-62:__UG_NAME__ -> 63:b ;
-57:__UG_NAME__ -> 63:a ;
-32:__UG_NAME__ -> 64:b ;
-63:__UG_NAME__ -> 64:a ;
-68:__UG_NAME__ -> 69:b ;
-66:__UG_NAME__ -> 69:a ;
-71:__UG_NAME__ -> 72:b ;
-69:__UG_NAME__ -> 72:a ;
-13:__UG_NAME__ -> 25:b ;
-31:__UG_NAME__ -> 32:a ;
-36:__UG_NAME__ -> 37:a ;
-40:__UG_NAME__ -> 41:a ;
-48:__UG_NAME__ -> 49:a ;
-51:__UG_NAME__ -> 52:a ;
-61:__UG_NAME__ -> 62:a ;
-67:__UG_NAME__ -> 68:a ;
-60:__UG_NAME__ -> 71:a ;
-30:__UG_NAME__ -> 31:a ;
-35:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:a ;
-47:__UG_NAME__ -> 48:a ;
-28:__UG_NAME__ -> 51:a ;
-59:__UG_NAME__ -> 60:a ;
-29:__UG_NAME__ -> 61:a ;
-58:__UG_NAME__ -> 67:a ;
-12:__UG_NAME__ -> 27:envelope___control___4 ;
-8:__UG_NAME__ -> 27:envelope___control___5 ;
-15:__UG_NAME__ -> 27:envelope___control___6 ;
-26:__UG_NAME__ -> 27:envelope___select___8 ;
-10:__UG_NAME__ -> 27:envelope___control___9 ;
-15:__UG_NAME__ -> 27:envelope___control___10 ;
-14:__UG_NAME__ -> 27:envelope___control___12 ;
-9:__UG_NAME__ -> 27:envelope___control___13 ;
-15:__UG_NAME__ -> 27:envelope___control___14 ;
-11:__UG_NAME__ -> 27:envelope___control___17 ;
-15:__UG_NAME__ -> 27:envelope___control___18 ;
-42:__UG_NAME__ -> 43:gate ;
-16:__UG_NAME__ -> 43:envelope___control___0 ;
-16:__UG_NAME__ -> 43:envelope___control___4 ;
-17:__UG_NAME__ -> 43:envelope___control___5 ;
-18:__UG_NAME__ -> 43:envelope___control___6 ;
-19:__UG_NAME__ -> 43:envelope___control___7 ;
-53:__UG_NAME__ -> 54:gate ;
-46:__UG_NAME__ -> 54:envelope___mul____add___0 ;
-46:__UG_NAME__ -> 54:envelope___mul____add___4 ;
-21:__UG_NAME__ -> 54:envelope___control___5 ;
-22:__UG_NAME__ -> 54:envelope___control___6 ;
-23:__UG_NAME__ -> 54:envelope___control___7 ;
-64:__UG_NAME__ -> 65:gate ;
-4:__UG_NAME__ -> 65:envelope___control___0 ;
-4:__UG_NAME__ -> 65:envelope___control___4 ;
-5:__UG_NAME__ -> 65:envelope___control___5 ;
-6:__UG_NAME__ -> 65:envelope___control___6 ;
-7:__UG_NAME__ -> 65:envelope___control___7 ;
-72:__UG_NAME__ -> 73:gate ;
-0:__UG_NAME__ -> 73:envelope___control___0 ;
-0:__UG_NAME__ -> 73:envelope___control___4 ;
-1:__UG_NAME__ -> 73:envelope___control___5 ;
-2:__UG_NAME__ -> 73:envelope___control___6 ;
-3:__UG_NAME__ -> 73:envelope___control___7 ;
-21:__UG_NAME__ -> 28:in ;
-4:__UG_NAME__ -> 29:in ;
-5:__UG_NAME__ -> 30:in ;
-16:__UG_NAME__ -> 35:in ;
-17:__UG_NAME__ -> 39:in ;
-46:__UG_NAME__ -> 47:in ;
-0:__UG_NAME__ -> 58:in ;
-1:__UG_NAME__ -> 59:in ;
-43:__UG_NAME__ -> 44:a ;
-20:__UG_NAME__ -> 46:in ;
-74:__UG_NAME__ -> 75:signals___pan2___0 ;
-74:__UG_NAME__ -> 75:signals___pan2___1 ;
-24:__UG_NAME__ -> 75:bus ;
-73:__UG_NAME__ -> 74:level ;
-65:__UG_NAME__ -> 74:pos ;
-70:__UG_NAME__ -> 74:in ;
-54:__UG_NAME__ -> 55:rq ;
-44:__UG_NAME__ -> 55:freq ;
-33:__UG_NAME__ -> 55:in ;
-13:__UG_NAME__ -> 26:array___control___0 ;
-14:__UG_NAME__ -> 26:array___control___1 ;
-25:__UG_NAME__ -> 26:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-pretty_bell.dot b/etc/synthdefs/graphviz/sonic-pi-pretty_bell.dot
deleted file mode 100644
index 8e171ab..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-pretty_bell.dot
+++ /dev/null
@@ -1,234 +0,0 @@
-digraph synthdef {
-23 [label = "{{ <a> |<b> 0.5} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> 0.5} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> 0.5} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> 4.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> 6.8|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-26 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-24 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-80 [label = "{{ <in> in|<amp> amp 1.0E-4|<time> time 0.1|<action> action 2.0} |<__UG_NAME__>detect-silence }" style="filled, bold, rounded"  shape=record rankdir=LR];
-31 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ {{0.0|4.0|-99|-99|<envelope___control___4>|<envelope___control___5>|1.0|0.0|<envelope___control___8>|<envelope___binary____op____u____gen___9>|1.0|0.0|<envelope___control___12>|<envelope___binary____op____u____gen___13>|1.0|0.0|0.0|<envelope___binary____op____u____gen___17>|1.0|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 0.5|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ {{0.0|4.0|-99|-99|<envelope___control___4>|<envelope___control___5>|1.0|0.0|<envelope___control___8>|<envelope___binary____op____u____gen___9>|1.0|0.0|<envelope___control___12>|<envelope___binary____op____u____gen___13>|1.0|0.0|0.0|<envelope___binary____op____u____gen___17>|1.0|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 0.25|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ {{0.0|4.0|-99|-99|<envelope___control___4>|<envelope___control___5>|1.0|0.0|<envelope___control___8>|<envelope___binary____op____u____gen___9>|1.0|0.0|<envelope___control___12>|<envelope___binary____op____u____gen___13>|1.0|0.0|0.0|<envelope___binary____op____u____gen___17>|1.0|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 0.125|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-21 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-76 [label = "{{ <in> in|<pos> pos|<level> level 1.0} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-79 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-54 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-62 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-15:__UG_NAME__ -> 23:a ;
-13:__UG_NAME__ -> 32:a ;
-14:__UG_NAME__ -> 33:a ;
-15:__UG_NAME__ -> 34:a ;
-46:__UG_NAME__ -> 47:b ;
-48:__UG_NAME__ -> 49:b ;
-35:__UG_NAME__ -> 49:a ;
-13:__UG_NAME__ -> 50:a ;
-14:__UG_NAME__ -> 51:a ;
-46:__UG_NAME__ -> 53:b ;
-54:__UG_NAME__ -> 55:b ;
-52:__UG_NAME__ -> 55:a ;
-13:__UG_NAME__ -> 57:a ;
-14:__UG_NAME__ -> 58:a ;
-15:__UG_NAME__ -> 59:a ;
-46:__UG_NAME__ -> 61:b ;
-62:__UG_NAME__ -> 63:b ;
-60:__UG_NAME__ -> 63:a ;
-64:__UG_NAME__ -> 65:b ;
-31:__UG_NAME__ -> 65:a ;
-25:__UG_NAME__ -> 26:b ;
-22:__UG_NAME__ -> 26:a ;
-29:__UG_NAME__ -> 30:b ;
-26:__UG_NAME__ -> 30:a ;
-39:__UG_NAME__ -> 40:b ;
-36:__UG_NAME__ -> 40:a ;
-43:__UG_NAME__ -> 44:b ;
-40:__UG_NAME__ -> 44:a ;
-55:__UG_NAME__ -> 56:b ;
-49:__UG_NAME__ -> 56:a ;
-63:__UG_NAME__ -> 64:b ;
-56:__UG_NAME__ -> 64:a ;
-71:__UG_NAME__ -> 72:b ;
-68:__UG_NAME__ -> 72:a ;
-73:__UG_NAME__ -> 74:b ;
-72:__UG_NAME__ -> 74:a ;
-17:__UG_NAME__ -> 78:b ;
-24:__UG_NAME__ -> 25:a ;
-28:__UG_NAME__ -> 29:a ;
-38:__UG_NAME__ -> 39:a ;
-42:__UG_NAME__ -> 43:a ;
-70:__UG_NAME__ -> 71:a ;
-67:__UG_NAME__ -> 73:a ;
-21:__UG_NAME__ -> 24:a ;
-27:__UG_NAME__ -> 28:a ;
-37:__UG_NAME__ -> 38:a ;
-41:__UG_NAME__ -> 42:a ;
-66:__UG_NAME__ -> 67:a ;
-69:__UG_NAME__ -> 70:a ;
-65:__UG_NAME__ -> 80:in ;
-30:__UG_NAME__ -> 31:gate ;
-4:__UG_NAME__ -> 31:envelope___control___0 ;
-4:__UG_NAME__ -> 31:envelope___control___4 ;
-5:__UG_NAME__ -> 31:envelope___control___5 ;
-6:__UG_NAME__ -> 31:envelope___control___6 ;
-7:__UG_NAME__ -> 31:envelope___control___7 ;
-16:__UG_NAME__ -> 35:envelope___control___4 ;
-12:__UG_NAME__ -> 35:envelope___control___5 ;
-18:__UG_NAME__ -> 35:envelope___control___8 ;
-32:__UG_NAME__ -> 35:envelope___binary____op____u____gen___9 ;
-18:__UG_NAME__ -> 35:envelope___control___12 ;
-33:__UG_NAME__ -> 35:envelope___binary____op____u____gen___13 ;
-34:__UG_NAME__ -> 35:envelope___binary____op____u____gen___17 ;
-44:__UG_NAME__ -> 45:gate ;
-0:__UG_NAME__ -> 45:envelope___control___0 ;
-0:__UG_NAME__ -> 45:envelope___control___4 ;
-1:__UG_NAME__ -> 45:envelope___control___5 ;
-2:__UG_NAME__ -> 45:envelope___control___6 ;
-3:__UG_NAME__ -> 45:envelope___control___7 ;
-16:__UG_NAME__ -> 52:envelope___control___4 ;
-12:__UG_NAME__ -> 52:envelope___control___5 ;
-18:__UG_NAME__ -> 52:envelope___control___8 ;
-50:__UG_NAME__ -> 52:envelope___binary____op____u____gen___9 ;
-18:__UG_NAME__ -> 52:envelope___control___12 ;
-51:__UG_NAME__ -> 52:envelope___binary____op____u____gen___13 ;
-23:__UG_NAME__ -> 52:envelope___binary____op____u____gen___17 ;
-16:__UG_NAME__ -> 60:envelope___control___4 ;
-12:__UG_NAME__ -> 60:envelope___control___5 ;
-18:__UG_NAME__ -> 60:envelope___control___8 ;
-57:__UG_NAME__ -> 60:envelope___binary____op____u____gen___9 ;
-18:__UG_NAME__ -> 60:envelope___control___12 ;
-58:__UG_NAME__ -> 60:envelope___binary____op____u____gen___13 ;
-59:__UG_NAME__ -> 60:envelope___binary____op____u____gen___17 ;
-74:__UG_NAME__ -> 75:gate ;
-8:__UG_NAME__ -> 75:envelope___control___0 ;
-8:__UG_NAME__ -> 75:envelope___control___4 ;
-9:__UG_NAME__ -> 75:envelope___control___5 ;
-10:__UG_NAME__ -> 75:envelope___control___6 ;
-11:__UG_NAME__ -> 75:envelope___control___7 ;
-4:__UG_NAME__ -> 21:in ;
-5:__UG_NAME__ -> 27:in ;
-0:__UG_NAME__ -> 37:in ;
-1:__UG_NAME__ -> 41:in ;
-9:__UG_NAME__ -> 66:in ;
-8:__UG_NAME__ -> 69:in ;
-45:__UG_NAME__ -> 46:a ;
-76:__UG_NAME__ -> 77:signals___pan2___0 ;
-76:__UG_NAME__ -> 77:signals___pan2___1 ;
-20:__UG_NAME__ -> 77:bus ;
-75:__UG_NAME__ -> 76:pos ;
-65:__UG_NAME__ -> 76:in ;
-17:__UG_NAME__ -> 79:array___control___0 ;
-18:__UG_NAME__ -> 79:array___control___1 ;
-78:__UG_NAME__ -> 79:which ;
-47:__UG_NAME__ -> 48:freq ;
-53:__UG_NAME__ -> 54:freq ;
-61:__UG_NAME__ -> 62:freq ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-prophet.dot b/etc/synthdefs/graphviz/sonic-pi-prophet.dot
deleted file mode 100644
index 39621f2..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-prophet.dot
+++ /dev/null
@@ -1,346 +0,0 @@
-digraph synthdef {
-46 [label = "{{ <a> 0.1|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> 0.8|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> 0.8|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> 0.8|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> 0.8|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> 0.5|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> 0.2} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-108 [label = "{{ <a> 1.5|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> 1.2|<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> 1.2|<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> 0.7} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-56 [label = "{{ <a> 1.2|<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-62 [label = "{{ <a> 1.2|<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-69 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> 1.2|<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.01" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 110.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :res
- default: 0.7" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-126 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <in> in|<coef> coef 0.995} |<__UG_NAME__>leak-dc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-68 [label = "{{ <freq> freq 0.2} |<__UG_NAME__>lf-noise2 }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <freq> freq 0.4|<iphase> iphase 0.0} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <freq> freq 0.4|<iphase> iphase 0.19} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <freq> freq|<iphase> iphase 0.0} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-128 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-127 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-47 [label = "{{ <freq> freq|<width> width} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
-53 [label = "{{ <freq> freq|<width> width} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
-59 [label = "{{ <freq> freq|<width> width} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
-65 [label = "{{ <freq> freq|<width> width} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
-74 [label = "{{ <freq> freq|<width> width} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
-103 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-30 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <freq> freq 1.0|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <freq> freq 0.3|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-
-45:__UG_NAME__ -> 46:b ;
-51:__UG_NAME__ -> 52:b ;
-57:__UG_NAME__ -> 58:b ;
-63:__UG_NAME__ -> 64:b ;
-72:__UG_NAME__ -> 73:b ;
-74:__UG_NAME__ -> 75:b ;
-76:__UG_NAME__ -> 77:a ;
-78:__UG_NAME__ -> 79:b ;
-31:__UG_NAME__ -> 79:a ;
-78:__UG_NAME__ -> 80:b ;
-79:__UG_NAME__ -> 80:a ;
-31:__UG_NAME__ -> 108:b ;
-103:__UG_NAME__ -> 109:b ;
-108:__UG_NAME__ -> 109:a ;
-35:__UG_NAME__ -> 36:b ;
-32:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:b ;
-36:__UG_NAME__ -> 40:a ;
-43:__UG_NAME__ -> 44:b ;
-48:__UG_NAME__ -> 49:b ;
-49:__UG_NAME__ -> 50:a ;
-53:__UG_NAME__ -> 54:b ;
-47:__UG_NAME__ -> 54:a ;
-55:__UG_NAME__ -> 56:b ;
-59:__UG_NAME__ -> 60:b ;
-54:__UG_NAME__ -> 60:a ;
-61:__UG_NAME__ -> 62:b ;
-65:__UG_NAME__ -> 66:b ;
-60:__UG_NAME__ -> 66:a ;
-68:__UG_NAME__ -> 69:b ;
-70:__UG_NAME__ -> 71:b ;
-75:__UG_NAME__ -> 76:b ;
-66:__UG_NAME__ -> 76:a ;
-84:__UG_NAME__ -> 85:b ;
-81:__UG_NAME__ -> 85:a ;
-88:__UG_NAME__ -> 89:b ;
-85:__UG_NAME__ -> 89:a ;
-96:__UG_NAME__ -> 97:b ;
-92:__UG_NAME__ -> 97:a ;
-100:__UG_NAME__ -> 101:b ;
-97:__UG_NAME__ -> 101:a ;
-114:__UG_NAME__ -> 115:b ;
-111:__UG_NAME__ -> 115:a ;
-117:__UG_NAME__ -> 118:b ;
-115:__UG_NAME__ -> 118:a ;
-107:__UG_NAME__ -> 121:b ;
-120:__UG_NAME__ -> 121:a ;
-124:__UG_NAME__ -> 125:b ;
-121:__UG_NAME__ -> 125:a ;
-44:__UG_NAME__ -> 45:b ;
-50:__UG_NAME__ -> 51:a ;
-56:__UG_NAME__ -> 57:a ;
-62:__UG_NAME__ -> 63:a ;
-42:__UG_NAME__ -> 67:a ;
-71:__UG_NAME__ -> 72:a ;
-17:__UG_NAME__ -> 29:b ;
-34:__UG_NAME__ -> 35:a ;
-38:__UG_NAME__ -> 39:a ;
-83:__UG_NAME__ -> 84:a ;
-87:__UG_NAME__ -> 88:a ;
-95:__UG_NAME__ -> 96:a ;
-99:__UG_NAME__ -> 100:a ;
-106:__UG_NAME__ -> 107:a ;
-113:__UG_NAME__ -> 114:a ;
-116:__UG_NAME__ -> 117:a ;
-123:__UG_NAME__ -> 124:a ;
-33:__UG_NAME__ -> 34:a ;
-37:__UG_NAME__ -> 38:a ;
-82:__UG_NAME__ -> 83:a ;
-86:__UG_NAME__ -> 87:a ;
-94:__UG_NAME__ -> 95:a ;
-98:__UG_NAME__ -> 99:a ;
-105:__UG_NAME__ -> 106:a ;
-112:__UG_NAME__ -> 113:a ;
-104:__UG_NAME__ -> 116:a ;
-122:__UG_NAME__ -> 123:a ;
-16:__UG_NAME__ -> 31:envelope___control___4 ;
-12:__UG_NAME__ -> 31:envelope___control___5 ;
-19:__UG_NAME__ -> 31:envelope___control___6 ;
-30:__UG_NAME__ -> 31:envelope___select___8 ;
-13:__UG_NAME__ -> 31:envelope___control___9 ;
-19:__UG_NAME__ -> 31:envelope___control___10 ;
-18:__UG_NAME__ -> 31:envelope___control___12 ;
-14:__UG_NAME__ -> 31:envelope___control___13 ;
-19:__UG_NAME__ -> 31:envelope___control___14 ;
-15:__UG_NAME__ -> 31:envelope___control___17 ;
-19:__UG_NAME__ -> 31:envelope___control___18 ;
-40:__UG_NAME__ -> 41:gate ;
-0:__UG_NAME__ -> 41:envelope___control___0 ;
-0:__UG_NAME__ -> 41:envelope___control___4 ;
-1:__UG_NAME__ -> 41:envelope___control___5 ;
-2:__UG_NAME__ -> 41:envelope___control___6 ;
-3:__UG_NAME__ -> 41:envelope___control___7 ;
-89:__UG_NAME__ -> 90:gate ;
-20:__UG_NAME__ -> 90:envelope___control___0 ;
-20:__UG_NAME__ -> 90:envelope___control___4 ;
-21:__UG_NAME__ -> 90:envelope___control___5 ;
-22:__UG_NAME__ -> 90:envelope___control___6 ;
-23:__UG_NAME__ -> 90:envelope___control___7 ;
-101:__UG_NAME__ -> 102:gate ;
-93:__UG_NAME__ -> 102:envelope___mul____add___0 ;
-93:__UG_NAME__ -> 102:envelope___mul____add___4 ;
-25:__UG_NAME__ -> 102:envelope___control___5 ;
-26:__UG_NAME__ -> 102:envelope___control___6 ;
-27:__UG_NAME__ -> 102:envelope___control___7 ;
-118:__UG_NAME__ -> 119:gate ;
-8:__UG_NAME__ -> 119:envelope___control___0 ;
-8:__UG_NAME__ -> 119:envelope___control___4 ;
-9:__UG_NAME__ -> 119:envelope___control___5 ;
-10:__UG_NAME__ -> 119:envelope___control___6 ;
-11:__UG_NAME__ -> 119:envelope___control___7 ;
-125:__UG_NAME__ -> 126:gate ;
-4:__UG_NAME__ -> 126:envelope___control___0 ;
-4:__UG_NAME__ -> 126:envelope___control___4 ;
-5:__UG_NAME__ -> 126:envelope___control___5 ;
-6:__UG_NAME__ -> 126:envelope___control___6 ;
-7:__UG_NAME__ -> 126:envelope___control___7 ;
-0:__UG_NAME__ -> 33:in ;
-1:__UG_NAME__ -> 37:in ;
-20:__UG_NAME__ -> 82:in ;
-21:__UG_NAME__ -> 86:in ;
-93:__UG_NAME__ -> 94:in ;
-25:__UG_NAME__ -> 98:in ;
-9:__UG_NAME__ -> 104:in ;
-4:__UG_NAME__ -> 105:in ;
-8:__UG_NAME__ -> 112:in ;
-5:__UG_NAME__ -> 122:in ;
-109:__UG_NAME__ -> 110:in ;
-69:__UG_NAME__ -> 70:freq ;
-41:__UG_NAME__ -> 42:a ;
-90:__UG_NAME__ -> 91:a ;
-24:__UG_NAME__ -> 93:in ;
-77:__UG_NAME__ -> 78:in ;
-127:__UG_NAME__ -> 128:signals___pan2___0 ;
-127:__UG_NAME__ -> 128:signals___pan2___1 ;
-28:__UG_NAME__ -> 128:bus ;
-126:__UG_NAME__ -> 127:level ;
-119:__UG_NAME__ -> 127:pos ;
-110:__UG_NAME__ -> 127:in ;
-46:__UG_NAME__ -> 47:width ;
-42:__UG_NAME__ -> 47:freq ;
-52:__UG_NAME__ -> 53:width ;
-42:__UG_NAME__ -> 53:freq ;
-58:__UG_NAME__ -> 59:width ;
-42:__UG_NAME__ -> 59:freq ;
-64:__UG_NAME__ -> 65:width ;
-42:__UG_NAME__ -> 65:freq ;
-73:__UG_NAME__ -> 74:width ;
-67:__UG_NAME__ -> 74:freq ;
-102:__UG_NAME__ -> 103:rq ;
-91:__UG_NAME__ -> 103:freq ;
-80:__UG_NAME__ -> 103:in ;
-17:__UG_NAME__ -> 30:array___control___0 ;
-18:__UG_NAME__ -> 30:array___control___1 ;
-29:__UG_NAME__ -> 30:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-pulse.dot b/etc/synthdefs/graphviz/sonic-pi-pulse.dot
deleted file mode 100644
index 49df04c..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-pulse.dot
+++ /dev/null
@@ -1,264 +0,0 @@
-digraph synthdef {
-81 [label = "{{ <a> 0.8|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-90 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-89 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-50 [label = "{{ <freq> freq|<width> width} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
-78 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-
-80:__UG_NAME__ -> 81:b ;
-82:__UG_NAME__ -> 83:b ;
-81:__UG_NAME__ -> 83:a ;
-32:__UG_NAME__ -> 33:b ;
-29:__UG_NAME__ -> 33:a ;
-36:__UG_NAME__ -> 37:b ;
-33:__UG_NAME__ -> 37:a ;
-43:__UG_NAME__ -> 44:b ;
-40:__UG_NAME__ -> 44:a ;
-47:__UG_NAME__ -> 48:b ;
-44:__UG_NAME__ -> 48:a ;
-57:__UG_NAME__ -> 58:b ;
-54:__UG_NAME__ -> 58:a ;
-53:__UG_NAME__ -> 60:b ;
-59:__UG_NAME__ -> 60:a ;
-63:__UG_NAME__ -> 64:b ;
-60:__UG_NAME__ -> 64:a ;
-71:__UG_NAME__ -> 72:b ;
-68:__UG_NAME__ -> 72:a ;
-75:__UG_NAME__ -> 76:b ;
-72:__UG_NAME__ -> 76:a ;
-86:__UG_NAME__ -> 87:b ;
-58:__UG_NAME__ -> 87:a ;
-17:__UG_NAME__ -> 77:b ;
-31:__UG_NAME__ -> 32:a ;
-35:__UG_NAME__ -> 36:a ;
-42:__UG_NAME__ -> 43:a ;
-46:__UG_NAME__ -> 47:a ;
-52:__UG_NAME__ -> 53:a ;
-56:__UG_NAME__ -> 57:a ;
-62:__UG_NAME__ -> 63:a ;
-70:__UG_NAME__ -> 71:a ;
-74:__UG_NAME__ -> 75:a ;
-85:__UG_NAME__ -> 86:a ;
-30:__UG_NAME__ -> 31:a ;
-34:__UG_NAME__ -> 35:a ;
-41:__UG_NAME__ -> 42:a ;
-45:__UG_NAME__ -> 46:a ;
-51:__UG_NAME__ -> 52:a ;
-55:__UG_NAME__ -> 56:a ;
-61:__UG_NAME__ -> 62:a ;
-69:__UG_NAME__ -> 70:a ;
-73:__UG_NAME__ -> 74:a ;
-84:__UG_NAME__ -> 85:a ;
-37:__UG_NAME__ -> 38:gate ;
-0:__UG_NAME__ -> 38:envelope___control___0 ;
-0:__UG_NAME__ -> 38:envelope___control___4 ;
-1:__UG_NAME__ -> 38:envelope___control___5 ;
-2:__UG_NAME__ -> 38:envelope___control___6 ;
-3:__UG_NAME__ -> 38:envelope___control___7 ;
-48:__UG_NAME__ -> 49:gate ;
-24:__UG_NAME__ -> 49:envelope___control___0 ;
-24:__UG_NAME__ -> 49:envelope___control___4 ;
-25:__UG_NAME__ -> 49:envelope___control___5 ;
-27:__UG_NAME__ -> 49:envelope___control___6 ;
-26:__UG_NAME__ -> 49:envelope___control___7 ;
-64:__UG_NAME__ -> 65:gate ;
-20:__UG_NAME__ -> 65:envelope___control___0 ;
-20:__UG_NAME__ -> 65:envelope___control___4 ;
-21:__UG_NAME__ -> 65:envelope___control___5 ;
-22:__UG_NAME__ -> 65:envelope___control___6 ;
-23:__UG_NAME__ -> 65:envelope___control___7 ;
-76:__UG_NAME__ -> 79:gate ;
-8:__UG_NAME__ -> 79:envelope___control___0 ;
-8:__UG_NAME__ -> 79:envelope___control___4 ;
-9:__UG_NAME__ -> 79:envelope___control___5 ;
-10:__UG_NAME__ -> 79:envelope___control___6 ;
-11:__UG_NAME__ -> 79:envelope___control___7 ;
-16:__UG_NAME__ -> 80:envelope___control___4 ;
-12:__UG_NAME__ -> 80:envelope___control___5 ;
-19:__UG_NAME__ -> 80:envelope___control___6 ;
-78:__UG_NAME__ -> 80:envelope___select___8 ;
-13:__UG_NAME__ -> 80:envelope___control___9 ;
-19:__UG_NAME__ -> 80:envelope___control___10 ;
-18:__UG_NAME__ -> 80:envelope___control___12 ;
-14:__UG_NAME__ -> 80:envelope___control___13 ;
-19:__UG_NAME__ -> 80:envelope___control___14 ;
-15:__UG_NAME__ -> 80:envelope___control___17 ;
-19:__UG_NAME__ -> 80:envelope___control___18 ;
-87:__UG_NAME__ -> 88:gate ;
-4:__UG_NAME__ -> 88:envelope___control___0 ;
-4:__UG_NAME__ -> 88:envelope___control___4 ;
-5:__UG_NAME__ -> 88:envelope___control___5 ;
-6:__UG_NAME__ -> 88:envelope___control___6 ;
-7:__UG_NAME__ -> 88:envelope___control___7 ;
-0:__UG_NAME__ -> 30:in ;
-1:__UG_NAME__ -> 34:in ;
-24:__UG_NAME__ -> 41:in ;
-25:__UG_NAME__ -> 45:in ;
-20:__UG_NAME__ -> 51:in ;
-4:__UG_NAME__ -> 55:in ;
-21:__UG_NAME__ -> 61:in ;
-8:__UG_NAME__ -> 69:in ;
-9:__UG_NAME__ -> 73:in ;
-5:__UG_NAME__ -> 84:in ;
-66:__UG_NAME__ -> 67:freq ;
-50:__UG_NAME__ -> 67:in ;
-38:__UG_NAME__ -> 39:a ;
-65:__UG_NAME__ -> 66:a ;
-67:__UG_NAME__ -> 82:in ;
-89:__UG_NAME__ -> 90:signals___pan2___0 ;
-89:__UG_NAME__ -> 90:signals___pan2___1 ;
-28:__UG_NAME__ -> 90:bus ;
-88:__UG_NAME__ -> 89:level ;
-79:__UG_NAME__ -> 89:pos ;
-83:__UG_NAME__ -> 89:in ;
-49:__UG_NAME__ -> 50:width ;
-39:__UG_NAME__ -> 50:freq ;
-17:__UG_NAME__ -> 78:array___control___0 ;
-18:__UG_NAME__ -> 78:array___control___1 ;
-77:__UG_NAME__ -> 78:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-recorder.dot b/etc/synthdefs/graphviz/sonic-pi-recorder.dot
deleted file mode 100644
index 3c370b1..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-recorder.dot
+++ /dev/null
@@ -1,16 +0,0 @@
-digraph synthdef {
-0 [label = "control
- :out-buf
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :in_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "{{ <bufnum> bufnum|{{<channelsarray___in___0>|<channelsarray___in___1>}|channelsArray}} |<__UG_NAME__>disk-out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-2 [label = "{{ <bus> bus|<num____channels> num-channels 2} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-2:__UG_NAME__ -> 3:channelsarray___in___0 ;
-2:__UG_NAME__ -> 3:channelsarray___in___1 ;
-0:__UG_NAME__ -> 3:bufnum ;
-1:__UG_NAME__ -> 2:bus ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-saw.dot b/etc/synthdefs/graphviz/sonic-pi-saw.dot
deleted file mode 100644
index 2341131..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-saw.dot
+++ /dev/null
@@ -1,225 +0,0 @@
-digraph synthdef {
-28 [label = "{{ <a> 0.8|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-76 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-75 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-40 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-26 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-
-27:__UG_NAME__ -> 28:b ;
-53:__UG_NAME__ -> 54:b ;
-28:__UG_NAME__ -> 54:a ;
-32:__UG_NAME__ -> 33:b ;
-29:__UG_NAME__ -> 33:a ;
-36:__UG_NAME__ -> 37:b ;
-33:__UG_NAME__ -> 37:a ;
-44:__UG_NAME__ -> 45:b ;
-41:__UG_NAME__ -> 45:a ;
-48:__UG_NAME__ -> 49:b ;
-45:__UG_NAME__ -> 49:a ;
-58:__UG_NAME__ -> 59:b ;
-55:__UG_NAME__ -> 59:a ;
-62:__UG_NAME__ -> 63:b ;
-59:__UG_NAME__ -> 63:a ;
-68:__UG_NAME__ -> 69:b ;
-65:__UG_NAME__ -> 69:a ;
-72:__UG_NAME__ -> 73:b ;
-69:__UG_NAME__ -> 73:a ;
-17:__UG_NAME__ -> 25:b ;
-31:__UG_NAME__ -> 32:a ;
-35:__UG_NAME__ -> 36:a ;
-43:__UG_NAME__ -> 44:a ;
-47:__UG_NAME__ -> 48:a ;
-57:__UG_NAME__ -> 58:a ;
-61:__UG_NAME__ -> 62:a ;
-67:__UG_NAME__ -> 68:a ;
-71:__UG_NAME__ -> 72:a ;
-30:__UG_NAME__ -> 31:a ;
-34:__UG_NAME__ -> 35:a ;
-42:__UG_NAME__ -> 43:a ;
-46:__UG_NAME__ -> 47:a ;
-56:__UG_NAME__ -> 57:a ;
-60:__UG_NAME__ -> 61:a ;
-66:__UG_NAME__ -> 67:a ;
-70:__UG_NAME__ -> 71:a ;
-16:__UG_NAME__ -> 27:envelope___control___4 ;
-12:__UG_NAME__ -> 27:envelope___control___5 ;
-19:__UG_NAME__ -> 27:envelope___control___6 ;
-26:__UG_NAME__ -> 27:envelope___select___8 ;
-13:__UG_NAME__ -> 27:envelope___control___9 ;
-19:__UG_NAME__ -> 27:envelope___control___10 ;
-18:__UG_NAME__ -> 27:envelope___control___12 ;
-14:__UG_NAME__ -> 27:envelope___control___13 ;
-19:__UG_NAME__ -> 27:envelope___control___14 ;
-15:__UG_NAME__ -> 27:envelope___control___17 ;
-19:__UG_NAME__ -> 27:envelope___control___18 ;
-37:__UG_NAME__ -> 38:gate ;
-0:__UG_NAME__ -> 38:envelope___control___0 ;
-0:__UG_NAME__ -> 38:envelope___control___4 ;
-1:__UG_NAME__ -> 38:envelope___control___5 ;
-2:__UG_NAME__ -> 38:envelope___control___6 ;
-3:__UG_NAME__ -> 38:envelope___control___7 ;
-49:__UG_NAME__ -> 50:gate ;
-20:__UG_NAME__ -> 50:envelope___control___0 ;
-20:__UG_NAME__ -> 50:envelope___control___4 ;
-21:__UG_NAME__ -> 50:envelope___control___5 ;
-22:__UG_NAME__ -> 50:envelope___control___6 ;
-23:__UG_NAME__ -> 50:envelope___control___7 ;
-63:__UG_NAME__ -> 64:gate ;
-8:__UG_NAME__ -> 64:envelope___control___0 ;
-8:__UG_NAME__ -> 64:envelope___control___4 ;
-9:__UG_NAME__ -> 64:envelope___control___5 ;
-10:__UG_NAME__ -> 64:envelope___control___6 ;
-11:__UG_NAME__ -> 64:envelope___control___7 ;
-73:__UG_NAME__ -> 74:gate ;
-4:__UG_NAME__ -> 74:envelope___control___0 ;
-4:__UG_NAME__ -> 74:envelope___control___4 ;
-5:__UG_NAME__ -> 74:envelope___control___5 ;
-6:__UG_NAME__ -> 74:envelope___control___6 ;
-7:__UG_NAME__ -> 74:envelope___control___7 ;
-0:__UG_NAME__ -> 30:in ;
-1:__UG_NAME__ -> 34:in ;
-20:__UG_NAME__ -> 42:in ;
-21:__UG_NAME__ -> 46:in ;
-8:__UG_NAME__ -> 56:in ;
-9:__UG_NAME__ -> 60:in ;
-4:__UG_NAME__ -> 66:in ;
-5:__UG_NAME__ -> 70:in ;
-51:__UG_NAME__ -> 52:freq ;
-40:__UG_NAME__ -> 52:in ;
-38:__UG_NAME__ -> 39:a ;
-50:__UG_NAME__ -> 51:a ;
-52:__UG_NAME__ -> 53:in ;
-75:__UG_NAME__ -> 76:signals___pan2___0 ;
-75:__UG_NAME__ -> 76:signals___pan2___1 ;
-24:__UG_NAME__ -> 76:bus ;
-74:__UG_NAME__ -> 75:level ;
-64:__UG_NAME__ -> 75:pos ;
-54:__UG_NAME__ -> 75:in ;
-39:__UG_NAME__ -> 40:freq ;
-17:__UG_NAME__ -> 26:array___control___0 ;
-18:__UG_NAME__ -> 26:array___control___1 ;
-25:__UG_NAME__ -> 26:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-sound_in.dot b/etc/synthdefs/graphviz/sonic-pi-sound_in.dot
deleted file mode 100644
index 082797b..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-sound_in.dot
+++ /dev/null
@@ -1,188 +0,0 @@
-digraph synthdef {
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-22 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :attack
- default: 0.01" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :release
- default: 2.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :input
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <bus> bus|<num____channels> num-channels 1} |<__UG_NAME__>in }" style="filled, bold, rounded"  shape=record rankdir=LR];
-50 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{<__UG_NAME__>num-output-buses }" style="dashed, rounded" shape=record rankdir=LR];
-62 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-61 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-23 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-
-50:__UG_NAME__ -> 51:b ;
-24:__UG_NAME__ -> 51:a ;
-29:__UG_NAME__ -> 30:b ;
-26:__UG_NAME__ -> 30:a ;
-33:__UG_NAME__ -> 34:b ;
-30:__UG_NAME__ -> 34:a ;
-38:__UG_NAME__ -> 39:b ;
-35:__UG_NAME__ -> 39:a ;
-42:__UG_NAME__ -> 43:b ;
-39:__UG_NAME__ -> 43:a ;
-20:__UG_NAME__ -> 48:b ;
-47:__UG_NAME__ -> 48:a ;
-55:__UG_NAME__ -> 56:b ;
-52:__UG_NAME__ -> 56:a ;
-58:__UG_NAME__ -> 59:b ;
-56:__UG_NAME__ -> 59:a ;
-13:__UG_NAME__ -> 22:b ;
-28:__UG_NAME__ -> 29:a ;
-32:__UG_NAME__ -> 33:a ;
-37:__UG_NAME__ -> 38:a ;
-41:__UG_NAME__ -> 42:a ;
-54:__UG_NAME__ -> 55:a ;
-57:__UG_NAME__ -> 58:a ;
-27:__UG_NAME__ -> 28:a ;
-31:__UG_NAME__ -> 32:a ;
-36:__UG_NAME__ -> 37:a ;
-40:__UG_NAME__ -> 41:a ;
-53:__UG_NAME__ -> 54:a ;
-25:__UG_NAME__ -> 57:a ;
-12:__UG_NAME__ -> 24:envelope___control___4 ;
-8:__UG_NAME__ -> 24:envelope___control___5 ;
-15:__UG_NAME__ -> 24:envelope___control___6 ;
-23:__UG_NAME__ -> 24:envelope___select___8 ;
-9:__UG_NAME__ -> 24:envelope___control___9 ;
-15:__UG_NAME__ -> 24:envelope___control___10 ;
-14:__UG_NAME__ -> 24:envelope___control___12 ;
-10:__UG_NAME__ -> 24:envelope___control___13 ;
-15:__UG_NAME__ -> 24:envelope___control___14 ;
-11:__UG_NAME__ -> 24:envelope___control___17 ;
-15:__UG_NAME__ -> 24:envelope___control___18 ;
-43:__UG_NAME__ -> 44:gate ;
-0:__UG_NAME__ -> 44:envelope___control___0 ;
-0:__UG_NAME__ -> 44:envelope___control___4 ;
-1:__UG_NAME__ -> 44:envelope___control___5 ;
-2:__UG_NAME__ -> 44:envelope___control___6 ;
-3:__UG_NAME__ -> 44:envelope___control___7 ;
-34:__UG_NAME__ -> 45:gate ;
-16:__UG_NAME__ -> 45:envelope___control___0 ;
-16:__UG_NAME__ -> 45:envelope___control___4 ;
-17:__UG_NAME__ -> 45:envelope___control___5 ;
-18:__UG_NAME__ -> 45:envelope___control___6 ;
-19:__UG_NAME__ -> 45:envelope___control___7 ;
-59:__UG_NAME__ -> 60:gate ;
-4:__UG_NAME__ -> 60:envelope___control___0 ;
-4:__UG_NAME__ -> 60:envelope___control___4 ;
-5:__UG_NAME__ -> 60:envelope___control___5 ;
-6:__UG_NAME__ -> 60:envelope___control___6 ;
-7:__UG_NAME__ -> 60:envelope___control___7 ;
-5:__UG_NAME__ -> 25:in ;
-16:__UG_NAME__ -> 27:in ;
-17:__UG_NAME__ -> 31:in ;
-0:__UG_NAME__ -> 36:in ;
-1:__UG_NAME__ -> 40:in ;
-4:__UG_NAME__ -> 53:in ;
-48:__UG_NAME__ -> 49:bus ;
-46:__UG_NAME__ -> 50:freq ;
-49:__UG_NAME__ -> 50:in ;
-45:__UG_NAME__ -> 46:a ;
-61:__UG_NAME__ -> 62:signals___pan2___0 ;
-61:__UG_NAME__ -> 62:signals___pan2___1 ;
-21:__UG_NAME__ -> 62:bus ;
-44:__UG_NAME__ -> 61:level ;
-60:__UG_NAME__ -> 61:pos ;
-51:__UG_NAME__ -> 61:in ;
-13:__UG_NAME__ -> 23:array___control___0 ;
-14:__UG_NAME__ -> 23:array___control___1 ;
-22:__UG_NAME__ -> 23:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-square.dot b/etc/synthdefs/graphviz/sonic-pi-square.dot
deleted file mode 100644
index b85377b..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-square.dot
+++ /dev/null
@@ -1,225 +0,0 @@
-digraph synthdef {
-61 [label = "{{ <a> 0.8|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-76 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-75 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-44 [label = "{{ <freq> freq|<width> width 0.5} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
-59 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-
-60:__UG_NAME__ -> 61:b ;
-62:__UG_NAME__ -> 63:b ;
-61:__UG_NAME__ -> 63:a ;
-28:__UG_NAME__ -> 29:b ;
-25:__UG_NAME__ -> 29:a ;
-36:__UG_NAME__ -> 37:b ;
-34:__UG_NAME__ -> 37:a ;
-40:__UG_NAME__ -> 41:b ;
-37:__UG_NAME__ -> 41:a ;
-46:__UG_NAME__ -> 47:b ;
-45:__UG_NAME__ -> 47:a ;
-49:__UG_NAME__ -> 50:b ;
-47:__UG_NAME__ -> 50:a ;
-57:__UG_NAME__ -> 58:b ;
-29:__UG_NAME__ -> 58:a ;
-68:__UG_NAME__ -> 69:b ;
-65:__UG_NAME__ -> 69:a ;
-71:__UG_NAME__ -> 72:b ;
-69:__UG_NAME__ -> 72:a ;
-17:__UG_NAME__ -> 54:b ;
-27:__UG_NAME__ -> 28:a ;
-35:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:a ;
-32:__UG_NAME__ -> 46:a ;
-48:__UG_NAME__ -> 49:a ;
-56:__UG_NAME__ -> 57:a ;
-66:__UG_NAME__ -> 68:a ;
-70:__UG_NAME__ -> 71:a ;
-26:__UG_NAME__ -> 27:a ;
-31:__UG_NAME__ -> 32:a ;
-33:__UG_NAME__ -> 35:a ;
-38:__UG_NAME__ -> 39:a ;
-30:__UG_NAME__ -> 48:a ;
-55:__UG_NAME__ -> 56:a ;
-64:__UG_NAME__ -> 66:a ;
-67:__UG_NAME__ -> 70:a ;
-41:__UG_NAME__ -> 42:gate ;
-0:__UG_NAME__ -> 42:envelope___control___0 ;
-0:__UG_NAME__ -> 42:envelope___control___4 ;
-1:__UG_NAME__ -> 42:envelope___control___5 ;
-2:__UG_NAME__ -> 42:envelope___control___6 ;
-3:__UG_NAME__ -> 42:envelope___control___7 ;
-50:__UG_NAME__ -> 51:gate ;
-20:__UG_NAME__ -> 51:envelope___control___0 ;
-20:__UG_NAME__ -> 51:envelope___control___4 ;
-21:__UG_NAME__ -> 51:envelope___control___5 ;
-22:__UG_NAME__ -> 51:envelope___control___6 ;
-23:__UG_NAME__ -> 51:envelope___control___7 ;
-16:__UG_NAME__ -> 60:envelope___control___4 ;
-12:__UG_NAME__ -> 60:envelope___control___5 ;
-19:__UG_NAME__ -> 60:envelope___control___6 ;
-59:__UG_NAME__ -> 60:envelope___select___8 ;
-13:__UG_NAME__ -> 60:envelope___control___9 ;
-19:__UG_NAME__ -> 60:envelope___control___10 ;
-18:__UG_NAME__ -> 60:envelope___control___12 ;
-14:__UG_NAME__ -> 60:envelope___control___13 ;
-19:__UG_NAME__ -> 60:envelope___control___14 ;
-15:__UG_NAME__ -> 60:envelope___control___17 ;
-19:__UG_NAME__ -> 60:envelope___control___18 ;
-72:__UG_NAME__ -> 73:gate ;
-8:__UG_NAME__ -> 73:envelope___control___0 ;
-8:__UG_NAME__ -> 73:envelope___control___4 ;
-9:__UG_NAME__ -> 73:envelope___control___5 ;
-10:__UG_NAME__ -> 73:envelope___control___6 ;
-11:__UG_NAME__ -> 73:envelope___control___7 ;
-58:__UG_NAME__ -> 74:gate ;
-4:__UG_NAME__ -> 74:envelope___control___0 ;
-4:__UG_NAME__ -> 74:envelope___control___4 ;
-5:__UG_NAME__ -> 74:envelope___control___5 ;
-6:__UG_NAME__ -> 74:envelope___control___6 ;
-7:__UG_NAME__ -> 74:envelope___control___7 ;
-4:__UG_NAME__ -> 26:in ;
-21:__UG_NAME__ -> 30:in ;
-20:__UG_NAME__ -> 31:in ;
-0:__UG_NAME__ -> 33:in ;
-1:__UG_NAME__ -> 38:in ;
-5:__UG_NAME__ -> 55:in ;
-8:__UG_NAME__ -> 64:in ;
-9:__UG_NAME__ -> 67:in ;
-52:__UG_NAME__ -> 53:freq ;
-44:__UG_NAME__ -> 53:in ;
-42:__UG_NAME__ -> 43:a ;
-51:__UG_NAME__ -> 52:a ;
-53:__UG_NAME__ -> 62:in ;
-75:__UG_NAME__ -> 76:signals___pan2___0 ;
-75:__UG_NAME__ -> 76:signals___pan2___1 ;
-24:__UG_NAME__ -> 76:bus ;
-74:__UG_NAME__ -> 75:level ;
-73:__UG_NAME__ -> 75:pos ;
-63:__UG_NAME__ -> 75:in ;
-43:__UG_NAME__ -> 44:freq ;
-17:__UG_NAME__ -> 59:array___control___0 ;
-18:__UG_NAME__ -> 59:array___control___1 ;
-54:__UG_NAME__ -> 59:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-stereo_player.dot b/etc/synthdefs/graphviz/sonic-pi-stereo_player.dot
deleted file mode 100644
index 82b720c..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-stereo_player.dot
+++ /dev/null
@@ -1,672 +0,0 @@
-digraph synthdef {
-90 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-220 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-222 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-130 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-153 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-157 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-179 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-183 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-196 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-200 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-206 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-224 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-228 [label = "{{ <a> 0.03|<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="dashed, rounded" shape=record rankdir=LR];
-166 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-167 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-168 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-189 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-214 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-215 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-135 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-148 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-159 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
-161 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
-162 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
-165 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-211 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
-213 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="dashed, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-126 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-139 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-143 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-152 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-156 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-178 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-182 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-195 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-199 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-205 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-223 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-138 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-151 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-155 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-177 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-181 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-191 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-194 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-198 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-204 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> } |<__UG_NAME__>absdif }" style="bold, rounded" shape=record rankdir=LR];
-226 [label = "{{ <left> left|<right> right|<pos> pos|<level> level} |<__UG_NAME__>balance2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-95 [label = "{{ <buf> buf} |<__UG_NAME__>buf-dur }" style="dashed, rounded" shape=record rankdir=LR];
-88 [label = "{{ <buf> buf} |<__UG_NAME__>buf-frames }" style="dashed, rounded" shape=record rankdir=LR];
-101 [label = "{{ <num____channels> num-channels 2|<bufnum> bufnum|<phase> phase|<loop> loop 1.0|<interpolation> interpolation 2.0} |<__UG_NAME__>buf-rd }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :buf
- default: 0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :cutoff_attack_level
- default: -1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :cutoff_decay_level
- default: -1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :cutoff_sustain_level
- default: -1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :decay
- default: 0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :sustain
- default: -1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :release
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :attack_level
- default: 1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :decay_level
- default: -1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :sustain_level
- default: 1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :cutoff
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :cutoff_sustain
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :cutoff_decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :cutoff_release
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :cutoff_min
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :cutoff_min_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :cutoff_min_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :cutoff_min_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :cutoff_env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :res
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "control
- :rate
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "control
- :start
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "control
- :finish
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-40 [label = "control
- :norm
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-41 [label = "control
- :pitch
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "control
- :pitch_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-43 [label = "control
- :pitch_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-44 [label = "control
- :pitch_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-45 [label = "control
- :window_size
- default: 0.2" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-46 [label = "control
- :window_size_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-47 [label = "control
- :window_size_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-48 [label = "control
- :window_size_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-49 [label = "control
- :pitch_dis
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-50 [label = "control
- :pitch_dis_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-51 [label = "control
- :pitch_dis_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-52 [label = "control
- :pitch_dis_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-53 [label = "control
- :time_dis
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-54 [label = "control
- :time_dis_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-55 [label = "control
- :time_dis_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-56 [label = "control
- :time_dis_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-57 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-86 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-131 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-145 [label = "{{ {{<envelope___select___0>|1.0|-99|-99|<envelope___select___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-158 [label = "{{ {{<envelope___select___0>|1.0|-99|-99|<envelope___select___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-170 [label = "{{ {{<envelope___env____gen___0>|4|-99|-99|<envelope___select___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___select___12>|<envelope___select___13>|<envelope___control___14>|0.0|<envelope___env____gen___16>|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-184 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-217 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___select___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-218 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-225 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-137 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-150 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-154 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-176 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-180 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-190 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-193 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-197 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-203 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-134 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-147 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-174 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-192 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-202 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <start> start|<end> end|<dur> dur|<action> action 0.0} |<__UG_NAME__>line }" style="filled, bold, rounded"  shape=record rankdir=LR];
-229 [label = "{{ <start> start 1.0|<end> end 1.0|<dur> dur|<action> action 2.0} |<__UG_NAME__>line }" style="bold, rounded" shape=record rankdir=LR];
-146 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-171 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> } |<__UG_NAME__>midiratio }" style="bold, rounded" shape=record rankdir=LR];
-172 [label = "{{ <a> |<b> } |<__UG_NAME__>min }" style="bold, rounded" shape=record rankdir=LR];
-175 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-187 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-219 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>not-pos? }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> } |<__UG_NAME__>not-pos? }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>not= }" style="dashed, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> 0.0|<b> } |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> 0.0|<b> } |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> 0.0|<b> } |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> 0.0|<b> } |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
-207 [label = "{{ <a> 0.0|<b> } |<__UG_NAME__>not= }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="dashed, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>or }" style="bold, rounded" shape=record rankdir=LR];
-227 [label = "{{ <bus> bus|{{<signals___balance2___0>|<signals___balance2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-132 [label = "{{ <in> in|<window____size> window-size|<pitch____ratio> pitch-ratio|<pitch____dispersion> pitch-dispersion|<time____dispersion> time-dispersion} |<__UG_NAME__>pitch-shift }" style="filled, bold, rounded"  shape=record rankdir=LR];
-201 [label = "{{ <in> in|<window____size> window-size|<pitch____ratio> pitch-ratio|<pitch____dispersion> pitch-dispersion|<time____dispersion> time-dispersion} |<__UG_NAME__>pitch-shift }" style="filled, bold, rounded"  shape=record rankdir=LR];
-185 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-209 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-92 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-133 [label = "{{ <which> which|{{<array___buf____rd___0>|<array___pitch____shift___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-136 [label = "{{ <which> which|{{<array___control___0>|130}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-149 [label = "{{ <which> which|{{<array___control___0>|50}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-160 [label = "{{ <which> which|{{<array___control___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-163 [label = "{{ <which> which|{{<array___control___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-164 [label = "{{ <which> which|{{<array___control___0>|<array___select___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-169 [label = "{{ <which> which|{{<array___control___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-173 [label = "{{ <which> which|{{<array___unary____op____u____gen___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-186 [label = "{{ <which> which|{{<array___select___0>|<array___rlpf___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-188 [label = "{{ <which> which|{{<array___select___0>|<array___normalizer___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-208 [label = "{{ <which> which|{{<array___buf____rd___0>|<array___pitch____shift___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-210 [label = "{{ <which> which|{{<array___select___0>|<array___rlpf___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-212 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-216 [label = "{{ <which> which|{{<array___control___0>|<array___binary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-221 [label = "{{ <which> which|{{<array___select___0>|<array___normalizer___1>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-89:__UG_NAME__ -> 90:b ;
-38:__UG_NAME__ -> 90:a ;
-89:__UG_NAME__ -> 91:b ;
-39:__UG_NAME__ -> 91:a ;
-96:__UG_NAME__ -> 97:b ;
-95:__UG_NAME__ -> 97:a ;
-188:__UG_NAME__ -> 220:b ;
-217:__UG_NAME__ -> 220:a ;
-221:__UG_NAME__ -> 222:b ;
-217:__UG_NAME__ -> 222:a ;
-61:__UG_NAME__ -> 62:b ;
-58:__UG_NAME__ -> 62:a ;
-65:__UG_NAME__ -> 66:b ;
-62:__UG_NAME__ -> 66:a ;
-105:__UG_NAME__ -> 106:b ;
-102:__UG_NAME__ -> 106:a ;
-109:__UG_NAME__ -> 110:b ;
-106:__UG_NAME__ -> 110:a ;
-116:__UG_NAME__ -> 117:b ;
-113:__UG_NAME__ -> 117:a ;
-120:__UG_NAME__ -> 121:b ;
-117:__UG_NAME__ -> 121:a ;
-126:__UG_NAME__ -> 127:b ;
-123:__UG_NAME__ -> 127:a ;
-129:__UG_NAME__ -> 130:b ;
-127:__UG_NAME__ -> 130:a ;
-139:__UG_NAME__ -> 140:b ;
-134:__UG_NAME__ -> 140:a ;
-143:__UG_NAME__ -> 144:b ;
-140:__UG_NAME__ -> 144:a ;
-152:__UG_NAME__ -> 153:b ;
-147:__UG_NAME__ -> 153:a ;
-156:__UG_NAME__ -> 157:b ;
-153:__UG_NAME__ -> 157:a ;
-178:__UG_NAME__ -> 179:b ;
-174:__UG_NAME__ -> 179:a ;
-182:__UG_NAME__ -> 183:b ;
-179:__UG_NAME__ -> 183:a ;
-195:__UG_NAME__ -> 196:b ;
-192:__UG_NAME__ -> 196:a ;
-199:__UG_NAME__ -> 200:b ;
-196:__UG_NAME__ -> 200:a ;
-205:__UG_NAME__ -> 206:b ;
-202:__UG_NAME__ -> 206:a ;
-223:__UG_NAME__ -> 224:b ;
-206:__UG_NAME__ -> 224:a ;
-99:__UG_NAME__ -> 228:b ;
-88:__UG_NAME__ -> 89:a ;
-23:__UG_NAME__ -> 166:b ;
-99:__UG_NAME__ -> 166:a ;
-26:__UG_NAME__ -> 167:b ;
-166:__UG_NAME__ -> 167:a ;
-25:__UG_NAME__ -> 168:b ;
-167:__UG_NAME__ -> 168:a ;
-4:__UG_NAME__ -> 189:b ;
-99:__UG_NAME__ -> 189:a ;
-7:__UG_NAME__ -> 214:b ;
-189:__UG_NAME__ -> 214:a ;
-5:__UG_NAME__ -> 215:b ;
-214:__UG_NAME__ -> 215:a ;
-98:__UG_NAME__ -> 99:b ;
-97:__UG_NAME__ -> 99:a ;
-19:__UG_NAME__ -> 135:b ;
-27:__UG_NAME__ -> 148:b ;
-1:__UG_NAME__ -> 159:b ;
-2:__UG_NAME__ -> 161:b ;
-3:__UG_NAME__ -> 162:b ;
-24:__UG_NAME__ -> 165:b ;
-9:__UG_NAME__ -> 211:b ;
-6:__UG_NAME__ -> 213:b ;
-60:__UG_NAME__ -> 61:a ;
-64:__UG_NAME__ -> 65:a ;
-104:__UG_NAME__ -> 105:a ;
-108:__UG_NAME__ -> 109:a ;
-115:__UG_NAME__ -> 116:a ;
-119:__UG_NAME__ -> 120:a ;
-125:__UG_NAME__ -> 126:a ;
-128:__UG_NAME__ -> 129:a ;
-138:__UG_NAME__ -> 139:a ;
-142:__UG_NAME__ -> 143:a ;
-151:__UG_NAME__ -> 152:a ;
-155:__UG_NAME__ -> 156:a ;
-177:__UG_NAME__ -> 178:a ;
-181:__UG_NAME__ -> 182:a ;
-194:__UG_NAME__ -> 195:a ;
-198:__UG_NAME__ -> 199:a ;
-204:__UG_NAME__ -> 205:a ;
-191:__UG_NAME__ -> 223:a ;
-59:__UG_NAME__ -> 60:a ;
-63:__UG_NAME__ -> 64:a ;
-37:__UG_NAME__ -> 98:a ;
-103:__UG_NAME__ -> 104:a ;
-107:__UG_NAME__ -> 108:a ;
-114:__UG_NAME__ -> 115:a ;
-118:__UG_NAME__ -> 119:a ;
-124:__UG_NAME__ -> 125:a ;
-68:__UG_NAME__ -> 128:a ;
-137:__UG_NAME__ -> 138:a ;
-141:__UG_NAME__ -> 142:a ;
-150:__UG_NAME__ -> 151:a ;
-154:__UG_NAME__ -> 155:a ;
-176:__UG_NAME__ -> 177:a ;
-180:__UG_NAME__ -> 181:a ;
-190:__UG_NAME__ -> 191:a ;
-193:__UG_NAME__ -> 194:a ;
-197:__UG_NAME__ -> 198:a ;
-203:__UG_NAME__ -> 204:a ;
-38:__UG_NAME__ -> 96:b ;
-39:__UG_NAME__ -> 96:a ;
-218:__UG_NAME__ -> 226:level ;
-225:__UG_NAME__ -> 226:pos ;
-222:__UG_NAME__ -> 226:right ;
-220:__UG_NAME__ -> 226:left ;
-0:__UG_NAME__ -> 95:buf ;
-0:__UG_NAME__ -> 88:buf ;
-100:__UG_NAME__ -> 101:phase ;
-0:__UG_NAME__ -> 101:bufnum ;
-66:__UG_NAME__ -> 86:gate ;
-41:__UG_NAME__ -> 86:envelope___control___0 ;
-41:__UG_NAME__ -> 86:envelope___control___4 ;
-42:__UG_NAME__ -> 86:envelope___control___5 ;
-43:__UG_NAME__ -> 86:envelope___control___6 ;
-44:__UG_NAME__ -> 86:envelope___control___7 ;
-110:__UG_NAME__ -> 111:gate ;
-45:__UG_NAME__ -> 111:envelope___control___0 ;
-45:__UG_NAME__ -> 111:envelope___control___4 ;
-46:__UG_NAME__ -> 111:envelope___control___5 ;
-47:__UG_NAME__ -> 111:envelope___control___6 ;
-48:__UG_NAME__ -> 111:envelope___control___7 ;
-121:__UG_NAME__ -> 122:gate ;
-49:__UG_NAME__ -> 122:envelope___control___0 ;
-49:__UG_NAME__ -> 122:envelope___control___4 ;
-50:__UG_NAME__ -> 122:envelope___control___5 ;
-51:__UG_NAME__ -> 122:envelope___control___6 ;
-52:__UG_NAME__ -> 122:envelope___control___7 ;
-130:__UG_NAME__ -> 131:gate ;
-53:__UG_NAME__ -> 131:envelope___control___0 ;
-53:__UG_NAME__ -> 131:envelope___control___4 ;
-54:__UG_NAME__ -> 131:envelope___control___5 ;
-55:__UG_NAME__ -> 131:envelope___control___6 ;
-56:__UG_NAME__ -> 131:envelope___control___7 ;
-144:__UG_NAME__ -> 145:gate ;
-136:__UG_NAME__ -> 145:envelope___select___0 ;
-136:__UG_NAME__ -> 145:envelope___select___4 ;
-20:__UG_NAME__ -> 145:envelope___control___5 ;
-21:__UG_NAME__ -> 145:envelope___control___6 ;
-22:__UG_NAME__ -> 145:envelope___control___7 ;
-157:__UG_NAME__ -> 158:gate ;
-149:__UG_NAME__ -> 158:envelope___select___0 ;
-149:__UG_NAME__ -> 158:envelope___select___4 ;
-28:__UG_NAME__ -> 158:envelope___control___5 ;
-29:__UG_NAME__ -> 158:envelope___control___6 ;
-30:__UG_NAME__ -> 158:envelope___control___7 ;
-158:__UG_NAME__ -> 170:envelope___env____gen___0 ;
-160:__UG_NAME__ -> 170:envelope___select___4 ;
-23:__UG_NAME__ -> 170:envelope___control___5 ;
-31:__UG_NAME__ -> 170:envelope___control___6 ;
-164:__UG_NAME__ -> 170:envelope___select___8 ;
-25:__UG_NAME__ -> 170:envelope___control___9 ;
-31:__UG_NAME__ -> 170:envelope___control___10 ;
-163:__UG_NAME__ -> 170:envelope___select___12 ;
-169:__UG_NAME__ -> 170:envelope___select___13 ;
-31:__UG_NAME__ -> 170:envelope___control___14 ;
-158:__UG_NAME__ -> 170:envelope___env____gen___16 ;
-26:__UG_NAME__ -> 170:envelope___control___17 ;
-31:__UG_NAME__ -> 170:envelope___control___18 ;
-183:__UG_NAME__ -> 184:gate ;
-175:__UG_NAME__ -> 184:envelope___mul____add___0 ;
-175:__UG_NAME__ -> 184:envelope___mul____add___4 ;
-33:__UG_NAME__ -> 184:envelope___control___5 ;
-34:__UG_NAME__ -> 184:envelope___control___6 ;
-35:__UG_NAME__ -> 184:envelope___control___7 ;
-8:__UG_NAME__ -> 217:envelope___control___4 ;
-4:__UG_NAME__ -> 217:envelope___control___5 ;
-36:__UG_NAME__ -> 217:envelope___control___6 ;
-212:__UG_NAME__ -> 217:envelope___select___8 ;
-5:__UG_NAME__ -> 217:envelope___control___9 ;
-36:__UG_NAME__ -> 217:envelope___control___10 ;
-10:__UG_NAME__ -> 217:envelope___control___12 ;
-216:__UG_NAME__ -> 217:envelope___select___13 ;
-36:__UG_NAME__ -> 217:envelope___control___14 ;
-7:__UG_NAME__ -> 217:envelope___control___17 ;
-36:__UG_NAME__ -> 217:envelope___control___18 ;
-200:__UG_NAME__ -> 218:gate ;
-11:__UG_NAME__ -> 218:envelope___control___0 ;
-11:__UG_NAME__ -> 218:envelope___control___4 ;
-12:__UG_NAME__ -> 218:envelope___control___5 ;
-13:__UG_NAME__ -> 218:envelope___control___6 ;
-14:__UG_NAME__ -> 218:envelope___control___7 ;
-224:__UG_NAME__ -> 225:gate ;
-15:__UG_NAME__ -> 225:envelope___control___0 ;
-15:__UG_NAME__ -> 225:envelope___control___4 ;
-16:__UG_NAME__ -> 225:envelope___control___5 ;
-17:__UG_NAME__ -> 225:envelope___control___6 ;
-18:__UG_NAME__ -> 225:envelope___control___7 ;
-41:__UG_NAME__ -> 59:in ;
-42:__UG_NAME__ -> 63:in ;
-54:__UG_NAME__ -> 68:in ;
-45:__UG_NAME__ -> 103:in ;
-46:__UG_NAME__ -> 107:in ;
-49:__UG_NAME__ -> 114:in ;
-50:__UG_NAME__ -> 118:in ;
-53:__UG_NAME__ -> 124:in ;
-136:__UG_NAME__ -> 137:in ;
-20:__UG_NAME__ -> 141:in ;
-149:__UG_NAME__ -> 150:in ;
-28:__UG_NAME__ -> 154:in ;
-175:__UG_NAME__ -> 176:in ;
-33:__UG_NAME__ -> 180:in ;
-16:__UG_NAME__ -> 190:in ;
-11:__UG_NAME__ -> 193:in ;
-12:__UG_NAME__ -> 197:in ;
-15:__UG_NAME__ -> 203:in ;
-99:__UG_NAME__ -> 100:dur ;
-94:__UG_NAME__ -> 100:end ;
-92:__UG_NAME__ -> 100:start ;
-228:__UG_NAME__ -> 229:dur ;
-145:__UG_NAME__ -> 146:a ;
-170:__UG_NAME__ -> 171:a ;
-86:__UG_NAME__ -> 112:a ;
-146:__UG_NAME__ -> 172:b ;
-171:__UG_NAME__ -> 172:a ;
-32:__UG_NAME__ -> 175:in ;
-186:__UG_NAME__ -> 187:in ;
-210:__UG_NAME__ -> 219:in ;
-37:__UG_NAME__ -> 67:a ;
-37:__UG_NAME__ -> 93:a ;
-19:__UG_NAME__ -> 69:b ;
-1:__UG_NAME__ -> 70:b ;
-2:__UG_NAME__ -> 71:b ;
-3:__UG_NAME__ -> 73:b ;
-23:__UG_NAME__ -> 75:b ;
-25:__UG_NAME__ -> 77:b ;
-26:__UG_NAME__ -> 79:b ;
-24:__UG_NAME__ -> 81:b ;
-27:__UG_NAME__ -> 83:b ;
-86:__UG_NAME__ -> 87:b ;
-86:__UG_NAME__ -> 207:b ;
-71:__UG_NAME__ -> 72:b ;
-70:__UG_NAME__ -> 72:a ;
-73:__UG_NAME__ -> 74:b ;
-72:__UG_NAME__ -> 74:a ;
-75:__UG_NAME__ -> 76:b ;
-74:__UG_NAME__ -> 76:a ;
-77:__UG_NAME__ -> 78:b ;
-76:__UG_NAME__ -> 78:a ;
-79:__UG_NAME__ -> 80:b ;
-78:__UG_NAME__ -> 80:a ;
-81:__UG_NAME__ -> 82:b ;
-80:__UG_NAME__ -> 82:a ;
-83:__UG_NAME__ -> 84:b ;
-82:__UG_NAME__ -> 84:a ;
-84:__UG_NAME__ -> 85:b ;
-69:__UG_NAME__ -> 85:a ;
-226:__UG_NAME__ -> 227:signals___balance2___0 ;
-226:__UG_NAME__ -> 227:signals___balance2___1 ;
-57:__UG_NAME__ -> 227:bus ;
-131:__UG_NAME__ -> 132:time____dispersion ;
-122:__UG_NAME__ -> 132:pitch____dispersion ;
-112:__UG_NAME__ -> 132:pitch____ratio ;
-111:__UG_NAME__ -> 132:window____size ;
-101:__UG_NAME__ -> 132:in ;
-131:__UG_NAME__ -> 201:time____dispersion ;
-122:__UG_NAME__ -> 201:pitch____dispersion ;
-112:__UG_NAME__ -> 201:pitch____ratio ;
-111:__UG_NAME__ -> 201:window____size ;
-101:__UG_NAME__ -> 201:in ;
-184:__UG_NAME__ -> 185:rq ;
-173:__UG_NAME__ -> 185:freq ;
-133:__UG_NAME__ -> 185:in ;
-184:__UG_NAME__ -> 209:rq ;
-173:__UG_NAME__ -> 209:freq ;
-208:__UG_NAME__ -> 209:in ;
-90:__UG_NAME__ -> 92:array___binary____op____u____gen___0 ;
-91:__UG_NAME__ -> 92:array___binary____op____u____gen___1 ;
-67:__UG_NAME__ -> 92:which ;
-91:__UG_NAME__ -> 94:array___binary____op____u____gen___0 ;
-90:__UG_NAME__ -> 94:array___binary____op____u____gen___1 ;
-93:__UG_NAME__ -> 94:which ;
-101:__UG_NAME__ -> 133:array___buf____rd___0 ;
-132:__UG_NAME__ -> 133:array___pitch____shift___1 ;
-87:__UG_NAME__ -> 133:which ;
-19:__UG_NAME__ -> 136:array___control___0 ;
-135:__UG_NAME__ -> 136:which ;
-27:__UG_NAME__ -> 149:array___control___0 ;
-148:__UG_NAME__ -> 149:which ;
-1:__UG_NAME__ -> 160:array___control___0 ;
-136:__UG_NAME__ -> 160:array___select___1 ;
-159:__UG_NAME__ -> 160:which ;
-3:__UG_NAME__ -> 163:array___control___0 ;
-160:__UG_NAME__ -> 163:array___select___1 ;
-162:__UG_NAME__ -> 163:which ;
-2:__UG_NAME__ -> 164:array___control___0 ;
-163:__UG_NAME__ -> 164:array___select___1 ;
-161:__UG_NAME__ -> 164:which ;
-24:__UG_NAME__ -> 169:array___control___0 ;
-168:__UG_NAME__ -> 169:array___binary____op____u____gen___1 ;
-165:__UG_NAME__ -> 169:which ;
-146:__UG_NAME__ -> 173:array___unary____op____u____gen___0 ;
-172:__UG_NAME__ -> 173:array___binary____op____u____gen___1 ;
-84:__UG_NAME__ -> 173:which ;
-133:__UG_NAME__ -> 186:array___select___0 ;
-185:__UG_NAME__ -> 186:array___rlpf___1 ;
-85:__UG_NAME__ -> 186:which ;
-186:__UG_NAME__ -> 188:array___select___0 ;
-187:__UG_NAME__ -> 188:array___normalizer___1 ;
-40:__UG_NAME__ -> 188:which ;
-101:__UG_NAME__ -> 208:array___buf____rd___0 ;
-201:__UG_NAME__ -> 208:array___pitch____shift___1 ;
-207:__UG_NAME__ -> 208:which ;
-208:__UG_NAME__ -> 210:array___select___0 ;
-209:__UG_NAME__ -> 210:array___rlpf___1 ;
-85:__UG_NAME__ -> 210:which ;
-9:__UG_NAME__ -> 212:array___control___0 ;
-10:__UG_NAME__ -> 212:array___control___1 ;
-211:__UG_NAME__ -> 212:which ;
-6:__UG_NAME__ -> 216:array___control___0 ;
-215:__UG_NAME__ -> 216:array___binary____op____u____gen___1 ;
-213:__UG_NAME__ -> 216:which ;
-210:__UG_NAME__ -> 221:array___select___0 ;
-219:__UG_NAME__ -> 221:array___normalizer___1 ;
-40:__UG_NAME__ -> 221:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-subpulse.dot b/etc/synthdefs/graphviz/sonic-pi-subpulse.dot
deleted file mode 100644
index 5c43b58..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-subpulse.dot
+++ /dev/null
@@ -1,327 +0,0 @@
-digraph synthdef {
-72 [label = "{{ <a> 0.8|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-106 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :sub_amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :sub_amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :sub_amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :sub_amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :sub_detune
- default: -12.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :sub_detune_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :sub_detune_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :sub_detune_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-46 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-113 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-112 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-83 [label = "{{ <freq> freq|<width> width} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
-70 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-71:__UG_NAME__ -> 72:b ;
-95:__UG_NAME__ -> 96:b ;
-28:__UG_NAME__ -> 96:a ;
-100:__UG_NAME__ -> 101:b ;
-72:__UG_NAME__ -> 101:a ;
-40:__UG_NAME__ -> 41:b ;
-37:__UG_NAME__ -> 41:a ;
-44:__UG_NAME__ -> 45:b ;
-41:__UG_NAME__ -> 45:a ;
-50:__UG_NAME__ -> 51:b ;
-47:__UG_NAME__ -> 51:a ;
-54:__UG_NAME__ -> 55:b ;
-51:__UG_NAME__ -> 55:a ;
-61:__UG_NAME__ -> 62:b ;
-58:__UG_NAME__ -> 62:a ;
-65:__UG_NAME__ -> 66:b ;
-62:__UG_NAME__ -> 66:a ;
-76:__UG_NAME__ -> 77:b ;
-73:__UG_NAME__ -> 77:a ;
-80:__UG_NAME__ -> 81:b ;
-77:__UG_NAME__ -> 81:a ;
-86:__UG_NAME__ -> 87:b ;
-84:__UG_NAME__ -> 87:a ;
-90:__UG_NAME__ -> 91:b ;
-87:__UG_NAME__ -> 91:a ;
-92:__UG_NAME__ -> 93:b ;
-67:__UG_NAME__ -> 93:a ;
-96:__UG_NAME__ -> 97:b ;
-83:__UG_NAME__ -> 97:a ;
-105:__UG_NAME__ -> 106:b ;
-102:__UG_NAME__ -> 106:a ;
-109:__UG_NAME__ -> 110:b ;
-106:__UG_NAME__ -> 110:a ;
-17:__UG_NAME__ -> 69:b ;
-39:__UG_NAME__ -> 40:a ;
-43:__UG_NAME__ -> 44:a ;
-49:__UG_NAME__ -> 50:a ;
-53:__UG_NAME__ -> 54:a ;
-60:__UG_NAME__ -> 61:a ;
-64:__UG_NAME__ -> 65:a ;
-75:__UG_NAME__ -> 76:a ;
-79:__UG_NAME__ -> 80:a ;
-85:__UG_NAME__ -> 86:a ;
-89:__UG_NAME__ -> 90:a ;
-104:__UG_NAME__ -> 105:a ;
-108:__UG_NAME__ -> 109:a ;
-38:__UG_NAME__ -> 39:a ;
-42:__UG_NAME__ -> 43:a ;
-48:__UG_NAME__ -> 49:a ;
-52:__UG_NAME__ -> 53:a ;
-59:__UG_NAME__ -> 60:a ;
-63:__UG_NAME__ -> 64:a ;
-74:__UG_NAME__ -> 75:a ;
-78:__UG_NAME__ -> 79:a ;
-57:__UG_NAME__ -> 85:a ;
-88:__UG_NAME__ -> 89:a ;
-103:__UG_NAME__ -> 104:a ;
-107:__UG_NAME__ -> 108:a ;
-45:__UG_NAME__ -> 46:gate ;
-20:__UG_NAME__ -> 46:envelope___control___0 ;
-20:__UG_NAME__ -> 46:envelope___control___4 ;
-21:__UG_NAME__ -> 46:envelope___control___5 ;
-22:__UG_NAME__ -> 46:envelope___control___6 ;
-23:__UG_NAME__ -> 46:envelope___control___7 ;
-55:__UG_NAME__ -> 56:gate ;
-8:__UG_NAME__ -> 56:envelope___control___0 ;
-8:__UG_NAME__ -> 56:envelope___control___4 ;
-9:__UG_NAME__ -> 56:envelope___control___5 ;
-10:__UG_NAME__ -> 56:envelope___control___6 ;
-11:__UG_NAME__ -> 56:envelope___control___7 ;
-66:__UG_NAME__ -> 67:gate ;
-0:__UG_NAME__ -> 67:envelope___control___0 ;
-0:__UG_NAME__ -> 67:envelope___control___4 ;
-1:__UG_NAME__ -> 67:envelope___control___5 ;
-2:__UG_NAME__ -> 67:envelope___control___6 ;
-3:__UG_NAME__ -> 67:envelope___control___7 ;
-16:__UG_NAME__ -> 71:envelope___control___4 ;
-12:__UG_NAME__ -> 71:envelope___control___5 ;
-19:__UG_NAME__ -> 71:envelope___control___6 ;
-70:__UG_NAME__ -> 71:envelope___select___8 ;
-13:__UG_NAME__ -> 71:envelope___control___9 ;
-19:__UG_NAME__ -> 71:envelope___control___10 ;
-18:__UG_NAME__ -> 71:envelope___control___12 ;
-14:__UG_NAME__ -> 71:envelope___control___13 ;
-19:__UG_NAME__ -> 71:envelope___control___14 ;
-15:__UG_NAME__ -> 71:envelope___control___17 ;
-19:__UG_NAME__ -> 71:envelope___control___18 ;
-81:__UG_NAME__ -> 82:gate ;
-24:__UG_NAME__ -> 82:envelope___control___0 ;
-24:__UG_NAME__ -> 82:envelope___control___4 ;
-25:__UG_NAME__ -> 82:envelope___control___5 ;
-27:__UG_NAME__ -> 82:envelope___control___6 ;
-26:__UG_NAME__ -> 82:envelope___control___7 ;
-91:__UG_NAME__ -> 92:gate ;
-32:__UG_NAME__ -> 92:envelope___control___0 ;
-32:__UG_NAME__ -> 92:envelope___control___4 ;
-33:__UG_NAME__ -> 92:envelope___control___5 ;
-35:__UG_NAME__ -> 92:envelope___control___6 ;
-34:__UG_NAME__ -> 92:envelope___control___7 ;
-110:__UG_NAME__ -> 111:gate ;
-4:__UG_NAME__ -> 111:envelope___control___0 ;
-4:__UG_NAME__ -> 111:envelope___control___4 ;
-5:__UG_NAME__ -> 111:envelope___control___5 ;
-6:__UG_NAME__ -> 111:envelope___control___6 ;
-7:__UG_NAME__ -> 111:envelope___control___7 ;
-20:__UG_NAME__ -> 38:in ;
-21:__UG_NAME__ -> 42:in ;
-8:__UG_NAME__ -> 48:in ;
-9:__UG_NAME__ -> 52:in ;
-32:__UG_NAME__ -> 57:in ;
-0:__UG_NAME__ -> 59:in ;
-1:__UG_NAME__ -> 63:in ;
-24:__UG_NAME__ -> 74:in ;
-25:__UG_NAME__ -> 78:in ;
-33:__UG_NAME__ -> 88:in ;
-4:__UG_NAME__ -> 103:in ;
-5:__UG_NAME__ -> 107:in ;
-98:__UG_NAME__ -> 99:freq ;
-97:__UG_NAME__ -> 99:in ;
-67:__UG_NAME__ -> 68:a ;
-93:__UG_NAME__ -> 94:a ;
-46:__UG_NAME__ -> 98:a ;
-99:__UG_NAME__ -> 100:in ;
-112:__UG_NAME__ -> 113:signals___pan2___0 ;
-112:__UG_NAME__ -> 113:signals___pan2___1 ;
-36:__UG_NAME__ -> 113:bus ;
-111:__UG_NAME__ -> 112:level ;
-56:__UG_NAME__ -> 112:pos ;
-101:__UG_NAME__ -> 112:in ;
-82:__UG_NAME__ -> 83:width ;
-68:__UG_NAME__ -> 83:freq ;
-17:__UG_NAME__ -> 70:array___control___0 ;
-18:__UG_NAME__ -> 70:array___control___1 ;
-69:__UG_NAME__ -> 70:which ;
-94:__UG_NAME__ -> 95:freq ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-supersaw.dot b/etc/synthdefs/graphviz/sonic-pi-supersaw.dot
deleted file mode 100644
index 6a071ad..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-supersaw.dot
+++ /dev/null
@@ -1,310 +0,0 @@
-digraph synthdef {
-70 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-96 [label = "{{ <a> 0.9|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="filled, bold, rounded"  shape=record rankdir=LR];
-32 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>\> }" style="filled, bold, rounded"  shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>\> }" style="filled, bold, rounded"  shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>\> }" style="filled, bold, rounded"  shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>\> }" style="filled, bold, rounded"  shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 130.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :res
- default: 0.7" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-47 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ {{0.0|4.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-29 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <in> in|<coef> coef 0.995} |<__UG_NAME__>leak-dc }" style="filled, bold, rounded"  shape=record rankdir=LR];
-49 [label = "{{ <freq> freq|<iphase> iphase 0.0} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-54 [label = "{{ <freq> freq 4.0|<iphase> iphase 0.0} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-57 [label = "{{ <freq> freq 7.0|<iphase> iphase 0.0} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-61 [label = "{{ <freq> freq 5.0|<iphase> iphase 0.0} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-65 [label = "{{ <freq> freq 2.0|<iphase> iphase 0.0} |<__UG_NAME__>lf-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-109 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-108 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-86 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-33 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-
-69:__UG_NAME__ -> 70:a ;
-95:__UG_NAME__ -> 96:b ;
-87:__UG_NAME__ -> 97:b ;
-96:__UG_NAME__ -> 97:a ;
-41:__UG_NAME__ -> 42:b ;
-38:__UG_NAME__ -> 42:a ;
-45:__UG_NAME__ -> 46:b ;
-42:__UG_NAME__ -> 46:a ;
-59:__UG_NAME__ -> 60:b ;
-56:__UG_NAME__ -> 60:a ;
-63:__UG_NAME__ -> 64:b ;
-60:__UG_NAME__ -> 64:a ;
-67:__UG_NAME__ -> 68:b ;
-64:__UG_NAME__ -> 68:a ;
-31:__UG_NAME__ -> 73:b ;
-72:__UG_NAME__ -> 73:a ;
-76:__UG_NAME__ -> 77:b ;
-73:__UG_NAME__ -> 77:a ;
-81:__UG_NAME__ -> 82:b ;
-80:__UG_NAME__ -> 82:a ;
-83:__UG_NAME__ -> 84:b ;
-82:__UG_NAME__ -> 84:a ;
-90:__UG_NAME__ -> 91:b ;
-52:__UG_NAME__ -> 91:a ;
-93:__UG_NAME__ -> 94:b ;
-91:__UG_NAME__ -> 94:a ;
-103:__UG_NAME__ -> 104:b ;
-102:__UG_NAME__ -> 104:a ;
-99:__UG_NAME__ -> 105:b ;
-104:__UG_NAME__ -> 105:a ;
-55:__UG_NAME__ -> 56:b ;
-49:__UG_NAME__ -> 56:a ;
-58:__UG_NAME__ -> 59:b ;
-49:__UG_NAME__ -> 59:a ;
-62:__UG_NAME__ -> 63:b ;
-49:__UG_NAME__ -> 63:a ;
-66:__UG_NAME__ -> 67:b ;
-49:__UG_NAME__ -> 67:a ;
-49:__UG_NAME__ -> 69:b ;
-68:__UG_NAME__ -> 69:a ;
-17:__UG_NAME__ -> 32:b ;
-30:__UG_NAME__ -> 31:a ;
-40:__UG_NAME__ -> 41:a ;
-44:__UG_NAME__ -> 45:a ;
-54:__UG_NAME__ -> 55:b ;
-49:__UG_NAME__ -> 55:a ;
-57:__UG_NAME__ -> 58:b ;
-49:__UG_NAME__ -> 58:a ;
-61:__UG_NAME__ -> 62:b ;
-49:__UG_NAME__ -> 62:a ;
-65:__UG_NAME__ -> 66:b ;
-49:__UG_NAME__ -> 66:a ;
-75:__UG_NAME__ -> 76:a ;
-36:__UG_NAME__ -> 81:a ;
-51:__UG_NAME__ -> 83:a ;
-89:__UG_NAME__ -> 90:a ;
-92:__UG_NAME__ -> 93:a ;
-98:__UG_NAME__ -> 99:a ;
-101:__UG_NAME__ -> 103:a ;
-29:__UG_NAME__ -> 30:a ;
-35:__UG_NAME__ -> 36:a ;
-39:__UG_NAME__ -> 40:a ;
-43:__UG_NAME__ -> 44:a ;
-50:__UG_NAME__ -> 51:a ;
-74:__UG_NAME__ -> 75:a ;
-88:__UG_NAME__ -> 89:a ;
-53:__UG_NAME__ -> 92:a ;
-37:__UG_NAME__ -> 98:a ;
-100:__UG_NAME__ -> 101:a ;
-46:__UG_NAME__ -> 47:gate ;
-0:__UG_NAME__ -> 47:envelope___control___0 ;
-0:__UG_NAME__ -> 47:envelope___control___4 ;
-1:__UG_NAME__ -> 47:envelope___control___5 ;
-2:__UG_NAME__ -> 47:envelope___control___6 ;
-3:__UG_NAME__ -> 47:envelope___control___7 ;
-77:__UG_NAME__ -> 78:gate ;
-20:__UG_NAME__ -> 78:envelope___control___0 ;
-20:__UG_NAME__ -> 78:envelope___control___4 ;
-21:__UG_NAME__ -> 78:envelope___control___5 ;
-22:__UG_NAME__ -> 78:envelope___control___6 ;
-23:__UG_NAME__ -> 78:envelope___control___7 ;
-84:__UG_NAME__ -> 85:gate ;
-34:__UG_NAME__ -> 85:envelope___mul____add___0 ;
-34:__UG_NAME__ -> 85:envelope___mul____add___4 ;
-25:__UG_NAME__ -> 85:envelope___control___5 ;
-26:__UG_NAME__ -> 85:envelope___control___6 ;
-27:__UG_NAME__ -> 85:envelope___control___7 ;
-16:__UG_NAME__ -> 95:envelope___control___4 ;
-12:__UG_NAME__ -> 95:envelope___control___5 ;
-19:__UG_NAME__ -> 95:envelope___control___6 ;
-33:__UG_NAME__ -> 95:envelope___select___8 ;
-13:__UG_NAME__ -> 95:envelope___control___9 ;
-19:__UG_NAME__ -> 95:envelope___control___10 ;
-18:__UG_NAME__ -> 95:envelope___control___12 ;
-14:__UG_NAME__ -> 95:envelope___control___13 ;
-19:__UG_NAME__ -> 95:envelope___control___14 ;
-15:__UG_NAME__ -> 95:envelope___control___17 ;
-19:__UG_NAME__ -> 95:envelope___control___18 ;
-105:__UG_NAME__ -> 106:gate ;
-8:__UG_NAME__ -> 106:envelope___control___0 ;
-8:__UG_NAME__ -> 106:envelope___control___4 ;
-9:__UG_NAME__ -> 106:envelope___control___5 ;
-10:__UG_NAME__ -> 106:envelope___control___6 ;
-11:__UG_NAME__ -> 106:envelope___control___7 ;
-94:__UG_NAME__ -> 107:gate ;
-4:__UG_NAME__ -> 107:envelope___control___0 ;
-4:__UG_NAME__ -> 107:envelope___control___4 ;
-5:__UG_NAME__ -> 107:envelope___control___5 ;
-6:__UG_NAME__ -> 107:envelope___control___6 ;
-7:__UG_NAME__ -> 107:envelope___control___7 ;
-20:__UG_NAME__ -> 29:in ;
-34:__UG_NAME__ -> 35:in ;
-9:__UG_NAME__ -> 37:in ;
-0:__UG_NAME__ -> 39:in ;
-1:__UG_NAME__ -> 43:in ;
-25:__UG_NAME__ -> 50:in ;
-5:__UG_NAME__ -> 53:in ;
-21:__UG_NAME__ -> 74:in ;
-4:__UG_NAME__ -> 88:in ;
-8:__UG_NAME__ -> 100:in ;
-70:__UG_NAME__ -> 71:in ;
-48:__UG_NAME__ -> 49:freq ;
-47:__UG_NAME__ -> 48:a ;
-78:__UG_NAME__ -> 79:a ;
-24:__UG_NAME__ -> 34:in ;
-86:__UG_NAME__ -> 87:in ;
-108:__UG_NAME__ -> 109:signals___pan2___0 ;
-108:__UG_NAME__ -> 109:signals___pan2___1 ;
-28:__UG_NAME__ -> 109:bus ;
-107:__UG_NAME__ -> 108:level ;
-106:__UG_NAME__ -> 108:pos ;
-97:__UG_NAME__ -> 108:in ;
-85:__UG_NAME__ -> 86:rq ;
-79:__UG_NAME__ -> 86:freq ;
-71:__UG_NAME__ -> 86:in ;
-17:__UG_NAME__ -> 33:array___control___0 ;
-18:__UG_NAME__ -> 33:array___control___1 ;
-32:__UG_NAME__ -> 33:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-synth_violin.dot b/etc/synthdefs/graphviz/sonic-pi-synth_violin.dot
deleted file mode 100644
index 9e97442..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-synth_violin.dot
+++ /dev/null
@@ -1,333 +0,0 @@
-digraph synthdef {
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> 1.1|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-106 [label = "{{ <a> 1.1|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-108 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="filled, bold, rounded"  shape=record rankdir=LR];
-92 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-44 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <in> in|<freq> freq 300.0|<rq> rq 0.2857143} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-84 [label = "{{ <in> in|<freq> freq 700.0|<rq> rq 0.2857143} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-86 [label = "{{ <in> in|<freq> freq 3000.0|<rq> rq 0.5} |<__UG_NAME__>bpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :vibrato_rate
- default: 6.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :vibrato_rate_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :vibrato_rate_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :vibrato_rate_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :vibrato_depth
- default: 0.15" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :vibrato_depth_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :vibrato_depth_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :vibrato_depth_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :vibrato_delay
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :vibrato_onset
- default: 0.1" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-50 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ {{0.0|2.0|-99|-99|0.0|<envelope___control___5>|1.0|0.0|<envelope___env____gen___8>|<envelope___control___9>|1.0|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <in> in|<freq> freq 30.0} |<__UG_NAME__>hpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-35 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-115 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-70 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-103 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <freq> freq|<phase> phase 0.0|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-
-66:__UG_NAME__ -> 67:b ;
-59:__UG_NAME__ -> 67:a ;
-104:__UG_NAME__ -> 105:b ;
-105:__UG_NAME__ -> 106:b ;
-107:__UG_NAME__ -> 108:b ;
-106:__UG_NAME__ -> 108:a ;
-44:__UG_NAME__ -> 45:b ;
-41:__UG_NAME__ -> 45:a ;
-48:__UG_NAME__ -> 49:b ;
-45:__UG_NAME__ -> 49:a ;
-54:__UG_NAME__ -> 55:b ;
-51:__UG_NAME__ -> 55:a ;
-56:__UG_NAME__ -> 57:b ;
-55:__UG_NAME__ -> 57:a ;
-40:__UG_NAME__ -> 61:b ;
-60:__UG_NAME__ -> 61:a ;
-63:__UG_NAME__ -> 64:b ;
-61:__UG_NAME__ -> 64:a ;
-67:__UG_NAME__ -> 68:b ;
-50:__UG_NAME__ -> 68:a ;
-74:__UG_NAME__ -> 75:b ;
-71:__UG_NAME__ -> 75:a ;
-78:__UG_NAME__ -> 79:b ;
-75:__UG_NAME__ -> 79:a ;
-84:__UG_NAME__ -> 85:b ;
-83:__UG_NAME__ -> 85:a ;
-86:__UG_NAME__ -> 87:b ;
-85:__UG_NAME__ -> 87:a ;
-91:__UG_NAME__ -> 92:b ;
-88:__UG_NAME__ -> 92:a ;
-96:__UG_NAME__ -> 97:b ;
-93:__UG_NAME__ -> 97:a ;
-100:__UG_NAME__ -> 101:b ;
-97:__UG_NAME__ -> 101:a ;
-111:__UG_NAME__ -> 112:b ;
-92:__UG_NAME__ -> 112:a ;
-17:__UG_NAME__ -> 102:b ;
-39:__UG_NAME__ -> 40:a ;
-43:__UG_NAME__ -> 44:a ;
-47:__UG_NAME__ -> 48:a ;
-53:__UG_NAME__ -> 54:a ;
-36:__UG_NAME__ -> 56:a ;
-62:__UG_NAME__ -> 63:a ;
-73:__UG_NAME__ -> 74:a ;
-77:__UG_NAME__ -> 78:a ;
-90:__UG_NAME__ -> 91:a ;
-95:__UG_NAME__ -> 96:a ;
-99:__UG_NAME__ -> 100:a ;
-110:__UG_NAME__ -> 111:a ;
-35:__UG_NAME__ -> 36:a ;
-38:__UG_NAME__ -> 39:a ;
-42:__UG_NAME__ -> 43:a ;
-46:__UG_NAME__ -> 47:a ;
-52:__UG_NAME__ -> 53:a ;
-37:__UG_NAME__ -> 62:a ;
-72:__UG_NAME__ -> 73:a ;
-76:__UG_NAME__ -> 77:a ;
-89:__UG_NAME__ -> 90:a ;
-94:__UG_NAME__ -> 95:a ;
-98:__UG_NAME__ -> 99:a ;
-109:__UG_NAME__ -> 110:a ;
-82:__UG_NAME__ -> 83:in ;
-82:__UG_NAME__ -> 84:in ;
-82:__UG_NAME__ -> 86:in ;
-49:__UG_NAME__ -> 50:gate ;
-0:__UG_NAME__ -> 50:envelope___control___0 ;
-0:__UG_NAME__ -> 50:envelope___control___4 ;
-1:__UG_NAME__ -> 50:envelope___control___5 ;
-2:__UG_NAME__ -> 50:envelope___control___6 ;
-3:__UG_NAME__ -> 50:envelope___control___7 ;
-57:__UG_NAME__ -> 58:gate ;
-28:__UG_NAME__ -> 58:envelope___control___0 ;
-28:__UG_NAME__ -> 58:envelope___control___4 ;
-29:__UG_NAME__ -> 58:envelope___control___5 ;
-30:__UG_NAME__ -> 58:envelope___control___6 ;
-31:__UG_NAME__ -> 58:envelope___control___7 ;
-32:__UG_NAME__ -> 59:envelope___control___5 ;
-58:__UG_NAME__ -> 59:envelope___env____gen___8 ;
-33:__UG_NAME__ -> 59:envelope___control___9 ;
-64:__UG_NAME__ -> 65:gate ;
-24:__UG_NAME__ -> 65:envelope___control___0 ;
-24:__UG_NAME__ -> 65:envelope___control___4 ;
-25:__UG_NAME__ -> 65:envelope___control___5 ;
-26:__UG_NAME__ -> 65:envelope___control___6 ;
-27:__UG_NAME__ -> 65:envelope___control___7 ;
-79:__UG_NAME__ -> 80:gate ;
-20:__UG_NAME__ -> 80:envelope___control___0 ;
-20:__UG_NAME__ -> 80:envelope___control___4 ;
-21:__UG_NAME__ -> 80:envelope___control___5 ;
-22:__UG_NAME__ -> 80:envelope___control___6 ;
-23:__UG_NAME__ -> 80:envelope___control___7 ;
-16:__UG_NAME__ -> 107:envelope___control___4 ;
-12:__UG_NAME__ -> 107:envelope___control___5 ;
-19:__UG_NAME__ -> 107:envelope___control___6 ;
-103:__UG_NAME__ -> 107:envelope___select___8 ;
-13:__UG_NAME__ -> 107:envelope___control___9 ;
-19:__UG_NAME__ -> 107:envelope___control___10 ;
-18:__UG_NAME__ -> 107:envelope___control___12 ;
-14:__UG_NAME__ -> 107:envelope___control___13 ;
-19:__UG_NAME__ -> 107:envelope___control___14 ;
-15:__UG_NAME__ -> 107:envelope___control___17 ;
-19:__UG_NAME__ -> 107:envelope___control___18 ;
-101:__UG_NAME__ -> 113:gate ;
-8:__UG_NAME__ -> 113:envelope___control___0 ;
-8:__UG_NAME__ -> 113:envelope___control___4 ;
-9:__UG_NAME__ -> 113:envelope___control___5 ;
-10:__UG_NAME__ -> 113:envelope___control___6 ;
-11:__UG_NAME__ -> 113:envelope___control___7 ;
-112:__UG_NAME__ -> 114:gate ;
-4:__UG_NAME__ -> 114:envelope___control___0 ;
-4:__UG_NAME__ -> 114:envelope___control___4 ;
-5:__UG_NAME__ -> 114:envelope___control___5 ;
-6:__UG_NAME__ -> 114:envelope___control___6 ;
-7:__UG_NAME__ -> 114:envelope___control___7 ;
-87:__UG_NAME__ -> 104:in ;
-29:__UG_NAME__ -> 35:in ;
-25:__UG_NAME__ -> 37:in ;
-24:__UG_NAME__ -> 38:in ;
-0:__UG_NAME__ -> 42:in ;
-1:__UG_NAME__ -> 46:in ;
-28:__UG_NAME__ -> 52:in ;
-20:__UG_NAME__ -> 72:in ;
-21:__UG_NAME__ -> 76:in ;
-4:__UG_NAME__ -> 89:in ;
-8:__UG_NAME__ -> 94:in ;
-9:__UG_NAME__ -> 98:in ;
-5:__UG_NAME__ -> 109:in ;
-81:__UG_NAME__ -> 82:freq ;
-70:__UG_NAME__ -> 82:in ;
-68:__UG_NAME__ -> 69:a ;
-80:__UG_NAME__ -> 81:a ;
-115:__UG_NAME__ -> 116:signals___pan2___0 ;
-115:__UG_NAME__ -> 116:signals___pan2___1 ;
-34:__UG_NAME__ -> 116:bus ;
-114:__UG_NAME__ -> 115:level ;
-113:__UG_NAME__ -> 115:pos ;
-108:__UG_NAME__ -> 115:in ;
-69:__UG_NAME__ -> 70:freq ;
-17:__UG_NAME__ -> 103:array___control___0 ;
-18:__UG_NAME__ -> 103:array___control___1 ;
-102:__UG_NAME__ -> 103:which ;
-65:__UG_NAME__ -> 66:freq ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-tb303.dot b/etc/synthdefs/graphviz/sonic-pi-tb303.dot
deleted file mode 100644
index e5eb9d1..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-tb303.dot
+++ /dev/null
@@ -1,441 +0,0 @@
-digraph synthdef {
-78 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-126 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-132 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-136 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-147 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-148 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-110 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-139 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-145 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-138 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.01" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 2.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 120.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :cutoff_attack
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :cutoff_sustain
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :cutoff_decay
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :cutoff_release
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :cutoff_min
- default: 30.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :cutoff_min_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :cutoff_min_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :cutoff_min_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :cutoff_attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :cutoff_decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :cutoff_sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :cutoff_env_curve
- default: 2.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :res
- default: 0.9" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-40 [label = "control
- :wave
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-41 [label = "control
- :pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "control
- :pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-43 [label = "control
- :pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-44 [label = "control
- :pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-45 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-77 [label = "{{ {{0.0|4|-99|-99|<envelope___binary____op____u____gen___4>|<envelope___control___5>|5|<envelope___control___7>|<envelope___binary____op____u____gen___8>|<envelope___control___9>|5|<envelope___control___11>|<envelope___binary____op____u____gen___12>|<envelope___control___13>|5|<envelope___control___15>|0.0|<envelope___control___17>|5|<envelope___control___19>}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ {{0.0|4|-99|-99|<envelope___binary____op____u____gen___4>|<envelope___select___5>|5|<envelope___control___7>|<envelope___binary____op____u____gen___8>|<envelope___select___9>|5|<envelope___control___11>|<envelope___binary____op____u____gen___12>|<envelope___select___13>|5|<envelope___control___15>|0.0|<envelope___select___17>|5|<envelope___control___19>}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-130 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-146 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-149 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-134 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-137 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-143 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-133 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-135 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <freq> freq|<iphase> iphase 0.0} |<__UG_NAME__>lf-tri }" style="filled, bold, rounded"  shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-151 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-150 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-105 [label = "{{ <freq> freq|<width> width} |<__UG_NAME__>pulse }" style="filled, bold, rounded"  shape=record rankdir=LR];
-131 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-95 [label = "{{ <freq> freq} |<__UG_NAME__>saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-74 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <which> which|{{<array___saw___0>|<array___pulse___1>|<array___binary____op____u____gen___2>}|array}} |<__UG_NAME__>select }" style="filled, bold, rounded"  shape=record rankdir=LR];
-109 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-
-77:__UG_NAME__ -> 78:b ;
-91:__UG_NAME__ -> 92:b ;
-125:__UG_NAME__ -> 126:b ;
-118:__UG_NAME__ -> 126:a ;
-131:__UG_NAME__ -> 132:b ;
-78:__UG_NAME__ -> 132:a ;
-49:__UG_NAME__ -> 50:b ;
-48:__UG_NAME__ -> 50:a ;
-53:__UG_NAME__ -> 54:b ;
-50:__UG_NAME__ -> 54:a ;
-68:__UG_NAME__ -> 69:b ;
-64:__UG_NAME__ -> 69:a ;
-32:__UG_NAME__ -> 70:a ;
-16:__UG_NAME__ -> 72:a ;
-74:__UG_NAME__ -> 75:a ;
-18:__UG_NAME__ -> 76:a ;
-82:__UG_NAME__ -> 83:b ;
-79:__UG_NAME__ -> 83:a ;
-86:__UG_NAME__ -> 87:b ;
-83:__UG_NAME__ -> 87:a ;
-98:__UG_NAME__ -> 99:b ;
-96:__UG_NAME__ -> 99:a ;
-102:__UG_NAME__ -> 103:b ;
-99:__UG_NAME__ -> 103:a ;
-111:__UG_NAME__ -> 112:a ;
-34:__UG_NAME__ -> 114:a ;
-121:__UG_NAME__ -> 122:b ;
-119:__UG_NAME__ -> 122:a ;
-59:__UG_NAME__ -> 123:b ;
-122:__UG_NAME__ -> 123:a ;
-126:__UG_NAME__ -> 127:b ;
-107:__UG_NAME__ -> 127:a ;
-128:__UG_NAME__ -> 129:b ;
-69:__UG_NAME__ -> 129:a ;
-63:__UG_NAME__ -> 136:b ;
-135:__UG_NAME__ -> 136:a ;
-139:__UG_NAME__ -> 140:b ;
-136:__UG_NAME__ -> 140:a ;
-145:__UG_NAME__ -> 147:b ;
-133:__UG_NAME__ -> 147:a ;
-142:__UG_NAME__ -> 148:b ;
-147:__UG_NAME__ -> 148:a ;
-25:__UG_NAME__ -> 71:b ;
-17:__UG_NAME__ -> 73:b ;
-26:__UG_NAME__ -> 94:b ;
-24:__UG_NAME__ -> 108:b ;
-33:__UG_NAME__ -> 110:b ;
-27:__UG_NAME__ -> 116:b ;
-47:__UG_NAME__ -> 49:a ;
-52:__UG_NAME__ -> 53:a ;
-58:__UG_NAME__ -> 59:a ;
-62:__UG_NAME__ -> 63:a ;
-67:__UG_NAME__ -> 68:a ;
-81:__UG_NAME__ -> 82:a ;
-85:__UG_NAME__ -> 86:a ;
-97:__UG_NAME__ -> 98:a ;
-101:__UG_NAME__ -> 102:a ;
-120:__UG_NAME__ -> 121:a ;
-61:__UG_NAME__ -> 128:a ;
-138:__UG_NAME__ -> 139:a ;
-141:__UG_NAME__ -> 142:a ;
-144:__UG_NAME__ -> 145:a ;
-46:__UG_NAME__ -> 47:a ;
-51:__UG_NAME__ -> 52:a ;
-57:__UG_NAME__ -> 58:a ;
-60:__UG_NAME__ -> 61:a ;
-55:__UG_NAME__ -> 62:a ;
-66:__UG_NAME__ -> 67:a ;
-80:__UG_NAME__ -> 81:a ;
-84:__UG_NAME__ -> 85:a ;
-56:__UG_NAME__ -> 97:a ;
-100:__UG_NAME__ -> 101:a ;
-93:__UG_NAME__ -> 120:a ;
-137:__UG_NAME__ -> 138:a ;
-134:__UG_NAME__ -> 141:a ;
-143:__UG_NAME__ -> 144:a ;
-72:__UG_NAME__ -> 77:envelope___binary____op____u____gen___4 ;
-12:__UG_NAME__ -> 77:envelope___control___5 ;
-19:__UG_NAME__ -> 77:envelope___control___7 ;
-75:__UG_NAME__ -> 77:envelope___binary____op____u____gen___8 ;
-14:__UG_NAME__ -> 77:envelope___control___9 ;
-19:__UG_NAME__ -> 77:envelope___control___11 ;
-76:__UG_NAME__ -> 77:envelope___binary____op____u____gen___12 ;
-13:__UG_NAME__ -> 77:envelope___control___13 ;
-19:__UG_NAME__ -> 77:envelope___control___15 ;
-15:__UG_NAME__ -> 77:envelope___control___17 ;
-19:__UG_NAME__ -> 77:envelope___control___19 ;
-87:__UG_NAME__ -> 88:gate ;
-28:__UG_NAME__ -> 88:envelope___control___0 ;
-28:__UG_NAME__ -> 88:envelope___control___4 ;
-29:__UG_NAME__ -> 88:envelope___control___5 ;
-30:__UG_NAME__ -> 88:envelope___control___6 ;
-31:__UG_NAME__ -> 88:envelope___control___7 ;
-54:__UG_NAME__ -> 89:gate ;
-0:__UG_NAME__ -> 89:envelope___control___0 ;
-0:__UG_NAME__ -> 89:envelope___control___4 ;
-1:__UG_NAME__ -> 89:envelope___control___5 ;
-2:__UG_NAME__ -> 89:envelope___control___6 ;
-3:__UG_NAME__ -> 89:envelope___control___7 ;
-103:__UG_NAME__ -> 104:gate ;
-41:__UG_NAME__ -> 104:envelope___control___0 ;
-41:__UG_NAME__ -> 104:envelope___control___4 ;
-42:__UG_NAME__ -> 104:envelope___control___5 ;
-43:__UG_NAME__ -> 104:envelope___control___6 ;
-44:__UG_NAME__ -> 104:envelope___control___7 ;
-70:__UG_NAME__ -> 118:envelope___binary____op____u____gen___4 ;
-109:__UG_NAME__ -> 118:envelope___select___5 ;
-35:__UG_NAME__ -> 118:envelope___control___7 ;
-112:__UG_NAME__ -> 118:envelope___binary____op____u____gen___8 ;
-113:__UG_NAME__ -> 118:envelope___select___9 ;
-35:__UG_NAME__ -> 118:envelope___control___11 ;
-114:__UG_NAME__ -> 118:envelope___binary____op____u____gen___12 ;
-115:__UG_NAME__ -> 118:envelope___select___13 ;
-35:__UG_NAME__ -> 118:envelope___control___15 ;
-117:__UG_NAME__ -> 118:envelope___select___17 ;
-35:__UG_NAME__ -> 118:envelope___control___19 ;
-123:__UG_NAME__ -> 124:gate ;
-20:__UG_NAME__ -> 124:envelope___control___0 ;
-20:__UG_NAME__ -> 124:envelope___control___4 ;
-21:__UG_NAME__ -> 124:envelope___control___5 ;
-22:__UG_NAME__ -> 124:envelope___control___6 ;
-23:__UG_NAME__ -> 124:envelope___control___7 ;
-129:__UG_NAME__ -> 130:gate ;
-65:__UG_NAME__ -> 130:envelope___mul____add___0 ;
-65:__UG_NAME__ -> 130:envelope___mul____add___4 ;
-37:__UG_NAME__ -> 130:envelope___control___5 ;
-38:__UG_NAME__ -> 130:envelope___control___6 ;
-39:__UG_NAME__ -> 130:envelope___control___7 ;
-140:__UG_NAME__ -> 146:gate ;
-8:__UG_NAME__ -> 146:envelope___control___0 ;
-8:__UG_NAME__ -> 146:envelope___control___4 ;
-9:__UG_NAME__ -> 146:envelope___control___5 ;
-10:__UG_NAME__ -> 146:envelope___control___6 ;
-11:__UG_NAME__ -> 146:envelope___control___7 ;
-148:__UG_NAME__ -> 149:gate ;
-4:__UG_NAME__ -> 149:envelope___control___0 ;
-4:__UG_NAME__ -> 149:envelope___control___4 ;
-5:__UG_NAME__ -> 149:envelope___control___5 ;
-6:__UG_NAME__ -> 149:envelope___control___6 ;
-7:__UG_NAME__ -> 149:envelope___control___7 ;
-0:__UG_NAME__ -> 46:in ;
-1:__UG_NAME__ -> 51:in ;
-8:__UG_NAME__ -> 55:in ;
-41:__UG_NAME__ -> 56:in ;
-21:__UG_NAME__ -> 57:in ;
-37:__UG_NAME__ -> 60:in ;
-65:__UG_NAME__ -> 66:in ;
-28:__UG_NAME__ -> 80:in ;
-29:__UG_NAME__ -> 84:in ;
-20:__UG_NAME__ -> 93:in ;
-42:__UG_NAME__ -> 100:in ;
-5:__UG_NAME__ -> 134:in ;
-9:__UG_NAME__ -> 137:in ;
-4:__UG_NAME__ -> 143:in ;
-90:__UG_NAME__ -> 91:freq ;
-89:__UG_NAME__ -> 90:a ;
-88:__UG_NAME__ -> 107:a ;
-124:__UG_NAME__ -> 125:a ;
-36:__UG_NAME__ -> 65:in ;
-150:__UG_NAME__ -> 151:signals___pan2___0 ;
-150:__UG_NAME__ -> 151:signals___pan2___1 ;
-45:__UG_NAME__ -> 151:bus ;
-149:__UG_NAME__ -> 150:level ;
-146:__UG_NAME__ -> 150:pos ;
-132:__UG_NAME__ -> 150:in ;
-104:__UG_NAME__ -> 105:width ;
-90:__UG_NAME__ -> 105:freq ;
-130:__UG_NAME__ -> 131:rq ;
-127:__UG_NAME__ -> 131:freq ;
-106:__UG_NAME__ -> 131:in ;
-90:__UG_NAME__ -> 95:freq ;
-17:__UG_NAME__ -> 74:array___control___0 ;
-18:__UG_NAME__ -> 74:array___control___1 ;
-73:__UG_NAME__ -> 74:which ;
-95:__UG_NAME__ -> 106:array___saw___0 ;
-105:__UG_NAME__ -> 106:array___pulse___1 ;
-92:__UG_NAME__ -> 106:array___binary____op____u____gen___2 ;
-40:__UG_NAME__ -> 106:which ;
-24:__UG_NAME__ -> 109:array___control___0 ;
-12:__UG_NAME__ -> 109:array___control___1 ;
-108:__UG_NAME__ -> 109:which ;
-33:__UG_NAME__ -> 111:array___control___0 ;
-34:__UG_NAME__ -> 111:array___control___1 ;
-110:__UG_NAME__ -> 111:which ;
-26:__UG_NAME__ -> 113:array___control___0 ;
-14:__UG_NAME__ -> 113:array___control___1 ;
-94:__UG_NAME__ -> 113:which ;
-25:__UG_NAME__ -> 115:array___control___0 ;
-13:__UG_NAME__ -> 115:array___control___1 ;
-71:__UG_NAME__ -> 115:which ;
-27:__UG_NAME__ -> 117:array___control___0 ;
-15:__UG_NAME__ -> 117:array___control___1 ;
-116:__UG_NAME__ -> 117:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-tri.dot b/etc/synthdefs/graphviz/sonic-pi-tri.dot
deleted file mode 100644
index e2bf2db..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-tri.dot
+++ /dev/null
@@ -1,225 +0,0 @@
-digraph synthdef {
-60 [label = "{{ <a> 1.4|<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-29 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-33 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-39 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-43 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-34 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-28 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-32 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-38 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-42 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-54 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-27 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-31 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-37 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-41 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-44 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-56 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-26 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-30 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-36 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-40 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-25 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-35 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <freq> freq|<iphase> iphase 0.0} |<__UG_NAME__>lf-tri }" style="filled, bold, rounded"  shape=record rankdir=LR];
-58 [label = "{{ <in> in|<freq> freq} |<__UG_NAME__>lpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-45 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <in> in|<level> level 1.0|<dur> dur 0.01} |<__UG_NAME__>normalizer }" style="filled, bold, rounded"  shape=record rankdir=LR];
-76 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-75 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-61 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-
-59:__UG_NAME__ -> 60:b ;
-62:__UG_NAME__ -> 63:b ;
-60:__UG_NAME__ -> 63:a ;
-28:__UG_NAME__ -> 29:b ;
-25:__UG_NAME__ -> 29:a ;
-32:__UG_NAME__ -> 33:b ;
-29:__UG_NAME__ -> 33:a ;
-38:__UG_NAME__ -> 39:b ;
-35:__UG_NAME__ -> 39:a ;
-42:__UG_NAME__ -> 43:b ;
-39:__UG_NAME__ -> 43:a ;
-50:__UG_NAME__ -> 51:b ;
-47:__UG_NAME__ -> 51:a ;
-54:__UG_NAME__ -> 55:b ;
-51:__UG_NAME__ -> 55:a ;
-68:__UG_NAME__ -> 69:b ;
-65:__UG_NAME__ -> 69:a ;
-72:__UG_NAME__ -> 73:b ;
-69:__UG_NAME__ -> 73:a ;
-17:__UG_NAME__ -> 34:b ;
-27:__UG_NAME__ -> 28:a ;
-31:__UG_NAME__ -> 32:a ;
-37:__UG_NAME__ -> 38:a ;
-41:__UG_NAME__ -> 42:a ;
-49:__UG_NAME__ -> 50:a ;
-53:__UG_NAME__ -> 54:a ;
-67:__UG_NAME__ -> 68:a ;
-71:__UG_NAME__ -> 72:a ;
-26:__UG_NAME__ -> 27:a ;
-30:__UG_NAME__ -> 31:a ;
-36:__UG_NAME__ -> 37:a ;
-40:__UG_NAME__ -> 41:a ;
-48:__UG_NAME__ -> 49:a ;
-52:__UG_NAME__ -> 53:a ;
-66:__UG_NAME__ -> 67:a ;
-70:__UG_NAME__ -> 71:a ;
-43:__UG_NAME__ -> 44:gate ;
-0:__UG_NAME__ -> 44:envelope___control___0 ;
-0:__UG_NAME__ -> 44:envelope___control___4 ;
-1:__UG_NAME__ -> 44:envelope___control___5 ;
-2:__UG_NAME__ -> 44:envelope___control___6 ;
-3:__UG_NAME__ -> 44:envelope___control___7 ;
-55:__UG_NAME__ -> 56:gate ;
-20:__UG_NAME__ -> 56:envelope___control___0 ;
-20:__UG_NAME__ -> 56:envelope___control___4 ;
-21:__UG_NAME__ -> 56:envelope___control___5 ;
-22:__UG_NAME__ -> 56:envelope___control___6 ;
-23:__UG_NAME__ -> 56:envelope___control___7 ;
-16:__UG_NAME__ -> 62:envelope___control___4 ;
-12:__UG_NAME__ -> 62:envelope___control___5 ;
-19:__UG_NAME__ -> 62:envelope___control___6 ;
-61:__UG_NAME__ -> 62:envelope___select___8 ;
-13:__UG_NAME__ -> 62:envelope___control___9 ;
-19:__UG_NAME__ -> 62:envelope___control___10 ;
-18:__UG_NAME__ -> 62:envelope___control___12 ;
-14:__UG_NAME__ -> 62:envelope___control___13 ;
-19:__UG_NAME__ -> 62:envelope___control___14 ;
-15:__UG_NAME__ -> 62:envelope___control___17 ;
-19:__UG_NAME__ -> 62:envelope___control___18 ;
-33:__UG_NAME__ -> 64:gate ;
-8:__UG_NAME__ -> 64:envelope___control___0 ;
-8:__UG_NAME__ -> 64:envelope___control___4 ;
-9:__UG_NAME__ -> 64:envelope___control___5 ;
-10:__UG_NAME__ -> 64:envelope___control___6 ;
-11:__UG_NAME__ -> 64:envelope___control___7 ;
-73:__UG_NAME__ -> 74:gate ;
-4:__UG_NAME__ -> 74:envelope___control___0 ;
-4:__UG_NAME__ -> 74:envelope___control___4 ;
-5:__UG_NAME__ -> 74:envelope___control___5 ;
-6:__UG_NAME__ -> 74:envelope___control___6 ;
-7:__UG_NAME__ -> 74:envelope___control___7 ;
-8:__UG_NAME__ -> 26:in ;
-9:__UG_NAME__ -> 30:in ;
-0:__UG_NAME__ -> 36:in ;
-1:__UG_NAME__ -> 40:in ;
-20:__UG_NAME__ -> 48:in ;
-21:__UG_NAME__ -> 52:in ;
-4:__UG_NAME__ -> 66:in ;
-5:__UG_NAME__ -> 70:in ;
-45:__UG_NAME__ -> 46:freq ;
-57:__UG_NAME__ -> 58:freq ;
-46:__UG_NAME__ -> 58:in ;
-44:__UG_NAME__ -> 45:a ;
-56:__UG_NAME__ -> 57:a ;
-58:__UG_NAME__ -> 59:in ;
-75:__UG_NAME__ -> 76:signals___pan2___0 ;
-75:__UG_NAME__ -> 76:signals___pan2___1 ;
-24:__UG_NAME__ -> 76:bus ;
-74:__UG_NAME__ -> 75:level ;
-64:__UG_NAME__ -> 75:pos ;
-63:__UG_NAME__ -> 75:in ;
-17:__UG_NAME__ -> 61:array___control___0 ;
-18:__UG_NAME__ -> 61:array___control___1 ;
-34:__UG_NAME__ -> 61:which ;
-
-}
\ No newline at end of file
diff --git a/etc/synthdefs/graphviz/sonic-pi-zawa.dot b/etc/synthdefs/graphviz/sonic-pi-zawa.dot
deleted file mode 100644
index f348a19..0000000
--- a/etc/synthdefs/graphviz/sonic-pi-zawa.dot
+++ /dev/null
@@ -1,469 +0,0 @@
-digraph synthdef {
-56 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-59 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-104 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-108 [label = "{{ <a> |<b> 6.2831855} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-111 [label = "{{ <a> |<b> -1.0} |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-144 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-146 [label = "{{ <a> 2.0|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-148 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-155 [label = "{{ <a> 0.5|<b> } |<__UG_NAME__>* }" style="bold, rounded" shape=record rankdir=LR];
-162 [label = "{{ <a> |<b> } |<__UG_NAME__>* }" style="filled, bold, rounded"  shape=record rankdir=LR];
-49 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-53 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-57 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-64 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-68 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-78 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-83 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-87 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-89 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-92 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-97 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-101 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-107 [label = "{{ <a> |<b> 0.25} |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-118 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-122 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-131 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-135 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-137 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-142 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-143 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-151 [label = "{{ <a> |<b> } |<__UG_NAME__>+ }" style="bold, rounded" shape=record rankdir=LR];
-90 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-105 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-112 [label = "{{ <a> |<b> } |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-147 [label = "{{ <a> |<b> 1.0} |<__UG_NAME__>- }" style="bold, rounded" shape=record rankdir=LR];
-55 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-91 [label = "{{ <a> |<b> 2.0} |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-166 [label = "{{ <a> 1.0|<b> } |<__UG_NAME__>/ }" style="bold, rounded" shape=record rankdir=LR];
-152 [label = "{{ <a> -1.0|<b> } |<__UG_NAME__>= }" style="bold, rounded" shape=record rankdir=LR];
-48 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-52 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-63 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-67 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-72 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-77 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-82 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-86 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-96 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-100 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-117 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-121 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-126 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-130 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-134 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-141 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-145 [label = "{{ <a> |<b> 0.0} |<__UG_NAME__>\> }" style="bold, rounded" shape=record rankdir=LR];
-47 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-51 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-62 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-66 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-71 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-76 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-80 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-85 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-95 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-99 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-116 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-120 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-125 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-129 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-133 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-140 [label = "{{ <a> |<b> } |<__UG_NAME__>abs }" style="bold, rounded" shape=record rankdir=LR];
-0 [label = "control
- :note
- default: 52.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-1 [label = "control
- :note_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-2 [label = "control
- :note_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-3 [label = "control
- :note_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-4 [label = "control
- :amp
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-5 [label = "control
- :amp_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-6 [label = "control
- :amp_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-7 [label = "control
- :amp_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-8 [label = "control
- :pan
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-9 [label = "control
- :pan_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-10 [label = "control
- :pan_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-11 [label = "control
- :pan_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-12 [label = "control
- :attack
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-13 [label = "control
- :decay
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-14 [label = "control
- :sustain
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-15 [label = "control
- :release
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-16 [label = "control
- :attack_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-17 [label = "control
- :decay_level
- default: -1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-18 [label = "control
- :sustain_level
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-19 [label = "control
- :env_curve
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-20 [label = "control
- :cutoff
- default: 100.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-21 [label = "control
- :cutoff_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-22 [label = "control
- :cutoff_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-23 [label = "control
- :cutoff_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-24 [label = "control
- :res
- default: 0.9" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-25 [label = "control
- :res_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-26 [label = "control
- :res_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-27 [label = "control
- :res_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-28 [label = "control
- :phase
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-29 [label = "control
- :phase_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-30 [label = "control
- :phase_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-31 [label = "control
- :phase_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-32 [label = "control
- :phase_offset
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-33 [label = "control
- :wave
- default: 3.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-34 [label = "control
- :disable_wave
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-35 [label = "control
- :invert_wave
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-36 [label = "control
- :pulse_width
- default: 0.5" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-37 [label = "control
- :pulse_width_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-38 [label = "control
- :pulse_width_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-39 [label = "control
- :pulse_width_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-40 [label = "control
- :range
- default: 24.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-41 [label = "control
- :range_slide
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-42 [label = "control
- :range_slide_shape
- default: 1.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-43 [label = "control
- :range_slide_curve
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-44 [label = "control
- :out_bus
- default: 0.0" shape=invhouse style="rounded, filled, bold" fillcolor=black fontcolor=white ]; 
-54 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-69 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-88 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-102 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-123 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-138 [label = "{{ {{<envelope___mul____add___0>|1.0|-99|-99|<envelope___mul____add___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-154 [label = "{{ {{0.0|4|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|0.0|<envelope___select___8>|<envelope___control___9>|<envelope___control___10>|0.0|<envelope___control___12>|<envelope___control___13>|<envelope___control___14>|0.0|0.0|<envelope___control___17>|<envelope___control___18>|0.0}|envelope}|<gate> gate 1.0|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 2.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-159 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-163 [label = "{{ {{<envelope___control___0>|1.0|-99|-99|<envelope___control___4>|<envelope___control___5>|<envelope___control___6>|<envelope___control___7>}|envelope}|<gate> gate|<level____scale> level-scale 1.0|<level____bias> level-bias 0.0|<time____scale> time-scale 1.0|<action> action 0.0} |<__UG_NAME__>env-gen }" style="bold, rounded" shape=record rankdir=LR];
-46 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-50 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-61 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-65 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-70 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-75 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-79 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-84 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-94 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-98 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-115 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-119 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-124 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-128 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-132 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-136 [label = "{{ <in> in} |<__UG_NAME__>hpz1 }" style="bold, rounded" shape=record rankdir=LR];
-45 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-60 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-73 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-81 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-93 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-114 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-127 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-139 [label = "{{ <freq> freq 0.0|<phase> phase 0.0} |<__UG_NAME__>impulse }" style="bold, rounded" shape=record rankdir=LR];
-103 [label = "{{ <freq> freq|<iphase> iphase|<width> width} |<__UG_NAME__>lf-pulse }" style="bold, rounded" shape=record rankdir=LR];
-58 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-saw }" style="bold, rounded" shape=record rankdir=LR];
-106 [label = "{{ <freq> freq|<iphase> iphase} |<__UG_NAME__>lf-tri }" style="bold, rounded" shape=record rankdir=LR];
-113 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-150 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-156 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-160 [label = "{{ <a> |<b> } |<__UG_NAME__>midicps }" style="bold, rounded" shape=record rankdir=LR];
-74 [label = "{{ <in> in|<mul> mul -1.0|<add> add 1.0} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-149 [label = "{{ <in> in|<mul> mul|<add> add} |<__UG_NAME__>mul-add }" style="bold, rounded" shape=record rankdir=LR];
-165 [label = "{{ <bus> bus|{{<signals___pan2___0>|<signals___pan2___1>}|signals}} |<__UG_NAME__>out }" style="filled, bold, rounded"  shape=record rankdir=LR];
-164 [label = "{{ <in> in|<pos> pos|<level> level} |<__UG_NAME__>pan2 }" style="filled, bold, rounded"  shape=record rankdir=LR];
-161 [label = "{{ <in> in|<freq> freq|<rq> rq} |<__UG_NAME__>rlpf }" style="filled, bold, rounded"  shape=record rankdir=LR];
-110 [label = "{{ <which> which|{{<array___binary____op____u____gen___0>|<array___binary____op____u____gen___1>|<array___lf____tri___2>|<array___sin____osc___3>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-153 [label = "{{ <which> which|{{<array___control___0>|<array___control___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-157 [label = "{{ <which> which|{{<array___unary____op____u____gen___0>|<array___unary____op____u____gen___1>}|array}} |<__UG_NAME__>select }" style="bold, rounded" shape=record rankdir=LR];
-109 [label = "{{ <freq> freq|<phase> phase|<mul> mul 1.0|<add> add 0.0} |<__UG_NAME__>sin-osc }" style="bold, rounded" shape=record rankdir=LR];
-158 [label = "{{ <sync____freq> sync-freq|<saw____freq> saw-freq} |<__UG_NAME__>sync-saw }" style="filled, bold, rounded"  shape=record rankdir=LR];
-
-32:__UG_NAME__ -> 56:b ;
-58:__UG_NAME__ -> 59:b ;
-103:__UG_NAME__ -> 104:b ;
-107:__UG_NAME__ -> 108:a ;
-91:__UG_NAME__ -> 111:a ;
-110:__UG_NAME__ -> 144:b ;
-145:__UG_NAME__ -> 146:b ;
-147:__UG_NAME__ -> 148:b ;
-144:__UG_NAME__ -> 148:a ;
-154:__UG_NAME__ -> 155:b ;
-161:__UG_NAME__ -> 162:b ;
-155:__UG_NAME__ -> 162:a ;
-48:__UG_NAME__ -> 49:b ;
-45:__UG_NAME__ -> 49:a ;
-52:__UG_NAME__ -> 53:b ;
-49:__UG_NAME__ -> 53:a ;
-56:__UG_NAME__ -> 57:a ;
-63:__UG_NAME__ -> 64:b ;
-60:__UG_NAME__ -> 64:a ;
-67:__UG_NAME__ -> 68:b ;
-64:__UG_NAME__ -> 68:a ;
-77:__UG_NAME__ -> 78:b ;
-73:__UG_NAME__ -> 78:a ;
-82:__UG_NAME__ -> 83:b ;
-81:__UG_NAME__ -> 83:a ;
-86:__UG_NAME__ -> 87:b ;
-83:__UG_NAME__ -> 87:a ;
-69:__UG_NAME__ -> 89:b ;
-88:__UG_NAME__ -> 89:a ;
-56:__UG_NAME__ -> 92:a ;
-96:__UG_NAME__ -> 97:b ;
-93:__UG_NAME__ -> 97:a ;
-100:__UG_NAME__ -> 101:b ;
-97:__UG_NAME__ -> 101:a ;
-32:__UG_NAME__ -> 107:a ;
-117:__UG_NAME__ -> 118:b ;
-114:__UG_NAME__ -> 118:a ;
-121:__UG_NAME__ -> 122:b ;
-118:__UG_NAME__ -> 122:a ;
-130:__UG_NAME__ -> 131:b ;
-127:__UG_NAME__ -> 131:a ;
-134:__UG_NAME__ -> 135:b ;
-131:__UG_NAME__ -> 135:a ;
-72:__UG_NAME__ -> 137:b ;
-78:__UG_NAME__ -> 137:a ;
-141:__UG_NAME__ -> 142:b ;
-139:__UG_NAME__ -> 142:a ;
-126:__UG_NAME__ -> 143:b ;
-142:__UG_NAME__ -> 143:a ;
-69:__UG_NAME__ -> 151:b ;
-88:__UG_NAME__ -> 151:a ;
-88:__UG_NAME__ -> 90:b ;
-89:__UG_NAME__ -> 90:a ;
-104:__UG_NAME__ -> 105:a ;
-111:__UG_NAME__ -> 112:b ;
-88:__UG_NAME__ -> 112:a ;
-146:__UG_NAME__ -> 147:a ;
-54:__UG_NAME__ -> 55:b ;
-90:__UG_NAME__ -> 91:a ;
-54:__UG_NAME__ -> 166:b ;
-17:__UG_NAME__ -> 152:b ;
-47:__UG_NAME__ -> 48:a ;
-51:__UG_NAME__ -> 52:a ;
-62:__UG_NAME__ -> 63:a ;
-66:__UG_NAME__ -> 67:a ;
-71:__UG_NAME__ -> 72:a ;
-76:__UG_NAME__ -> 77:a ;
-80:__UG_NAME__ -> 82:a ;
-85:__UG_NAME__ -> 86:a ;
-95:__UG_NAME__ -> 96:a ;
-99:__UG_NAME__ -> 100:a ;
-116:__UG_NAME__ -> 117:a ;
-120:__UG_NAME__ -> 121:a ;
-125:__UG_NAME__ -> 126:a ;
-129:__UG_NAME__ -> 130:a ;
-133:__UG_NAME__ -> 134:a ;
-140:__UG_NAME__ -> 141:a ;
-35:__UG_NAME__ -> 145:a ;
-46:__UG_NAME__ -> 47:a ;
-50:__UG_NAME__ -> 51:a ;
-61:__UG_NAME__ -> 62:a ;
-65:__UG_NAME__ -> 66:a ;
-70:__UG_NAME__ -> 71:a ;
-75:__UG_NAME__ -> 76:a ;
-79:__UG_NAME__ -> 80:a ;
-84:__UG_NAME__ -> 85:a ;
-94:__UG_NAME__ -> 95:a ;
-98:__UG_NAME__ -> 99:a ;
-115:__UG_NAME__ -> 116:a ;
-119:__UG_NAME__ -> 120:a ;
-124:__UG_NAME__ -> 125:a ;
-128:__UG_NAME__ -> 129:a ;
-132:__UG_NAME__ -> 133:a ;
-136:__UG_NAME__ -> 140:a ;
-53:__UG_NAME__ -> 54:gate ;
-28:__UG_NAME__ -> 54:envelope___control___0 ;
-28:__UG_NAME__ -> 54:envelope___control___4 ;
-29:__UG_NAME__ -> 54:envelope___control___5 ;
-30:__UG_NAME__ -> 54:envelope___control___6 ;
-31:__UG_NAME__ -> 54:envelope___control___7 ;
-68:__UG_NAME__ -> 69:gate ;
-40:__UG_NAME__ -> 69:envelope___control___0 ;
-40:__UG_NAME__ -> 69:envelope___control___4 ;
-41:__UG_NAME__ -> 69:envelope___control___5 ;
-42:__UG_NAME__ -> 69:envelope___control___6 ;
-43:__UG_NAME__ -> 69:envelope___control___7 ;
-87:__UG_NAME__ -> 88:gate ;
-0:__UG_NAME__ -> 88:envelope___control___0 ;
-0:__UG_NAME__ -> 88:envelope___control___4 ;
-1:__UG_NAME__ -> 88:envelope___control___5 ;
-2:__UG_NAME__ -> 88:envelope___control___6 ;
-3:__UG_NAME__ -> 88:envelope___control___7 ;
-101:__UG_NAME__ -> 102:gate ;
-36:__UG_NAME__ -> 102:envelope___control___0 ;
-36:__UG_NAME__ -> 102:envelope___control___4 ;
-37:__UG_NAME__ -> 102:envelope___control___5 ;
-38:__UG_NAME__ -> 102:envelope___control___6 ;
-39:__UG_NAME__ -> 102:envelope___control___7 ;
-122:__UG_NAME__ -> 123:gate ;
-4:__UG_NAME__ -> 123:envelope___control___0 ;
-4:__UG_NAME__ -> 123:envelope___control___4 ;
-5:__UG_NAME__ -> 123:envelope___control___5 ;
-6:__UG_NAME__ -> 123:envelope___control___6 ;
-7:__UG_NAME__ -> 123:envelope___control___7 ;
-137:__UG_NAME__ -> 138:gate ;
-74:__UG_NAME__ -> 138:envelope___mul____add___0 ;
-74:__UG_NAME__ -> 138:envelope___mul____add___4 ;
-25:__UG_NAME__ -> 138:envelope___control___5 ;
-26:__UG_NAME__ -> 138:envelope___control___6 ;
-27:__UG_NAME__ -> 138:envelope___control___7 ;
-16:__UG_NAME__ -> 154:envelope___control___4 ;
-12:__UG_NAME__ -> 154:envelope___control___5 ;
-19:__UG_NAME__ -> 154:envelope___control___6 ;
-153:__UG_NAME__ -> 154:envelope___select___8 ;
-13:__UG_NAME__ -> 154:envelope___control___9 ;
-19:__UG_NAME__ -> 154:envelope___control___10 ;
-18:__UG_NAME__ -> 154:envelope___control___12 ;
-14:__UG_NAME__ -> 154:envelope___control___13 ;
-19:__UG_NAME__ -> 154:envelope___control___14 ;
-15:__UG_NAME__ -> 154:envelope___control___17 ;
-19:__UG_NAME__ -> 154:envelope___control___18 ;
-135:__UG_NAME__ -> 159:gate ;
-20:__UG_NAME__ -> 159:envelope___control___0 ;
-20:__UG_NAME__ -> 159:envelope___control___4 ;
-21:__UG_NAME__ -> 159:envelope___control___5 ;
-22:__UG_NAME__ -> 159:envelope___control___6 ;
-23:__UG_NAME__ -> 159:envelope___control___7 ;
-143:__UG_NAME__ -> 163:gate ;
-8:__UG_NAME__ -> 163:envelope___control___0 ;
-8:__UG_NAME__ -> 163:envelope___control___4 ;
-9:__UG_NAME__ -> 163:envelope___control___5 ;
-10:__UG_NAME__ -> 163:envelope___control___6 ;
-11:__UG_NAME__ -> 163:envelope___control___7 ;
-28:__UG_NAME__ -> 46:in ;
-29:__UG_NAME__ -> 50:in ;
-40:__UG_NAME__ -> 61:in ;
-41:__UG_NAME__ -> 65:in ;
-25:__UG_NAME__ -> 70:in ;
-74:__UG_NAME__ -> 75:in ;
-0:__UG_NAME__ -> 79:in ;
-1:__UG_NAME__ -> 84:in ;
-36:__UG_NAME__ -> 94:in ;
-37:__UG_NAME__ -> 98:in ;
-4:__UG_NAME__ -> 115:in ;
-5:__UG_NAME__ -> 119:in ;
-9:__UG_NAME__ -> 124:in ;
-20:__UG_NAME__ -> 128:in ;
-21:__UG_NAME__ -> 132:in ;
-8:__UG_NAME__ -> 136:in ;
-102:__UG_NAME__ -> 103:width ;
-32:__UG_NAME__ -> 103:iphase ;
-55:__UG_NAME__ -> 103:freq ;
-57:__UG_NAME__ -> 58:iphase ;
-55:__UG_NAME__ -> 58:freq ;
-92:__UG_NAME__ -> 106:iphase ;
-55:__UG_NAME__ -> 106:freq ;
-88:__UG_NAME__ -> 113:a ;
-149:__UG_NAME__ -> 150:a ;
-151:__UG_NAME__ -> 156:a ;
-159:__UG_NAME__ -> 160:a ;
-24:__UG_NAME__ -> 74:in ;
-112:__UG_NAME__ -> 149:add ;
-91:__UG_NAME__ -> 149:mul ;
-148:__UG_NAME__ -> 149:in ;
-164:__UG_NAME__ -> 165:signals___pan2___0 ;
-164:__UG_NAME__ -> 165:signals___pan2___1 ;
-44:__UG_NAME__ -> 165:bus ;
-123:__UG_NAME__ -> 164:level ;
-163:__UG_NAME__ -> 164:pos ;
-162:__UG_NAME__ -> 164:in ;
-138:__UG_NAME__ -> 161:rq ;
-160:__UG_NAME__ -> 161:freq ;
-158:__UG_NAME__ -> 161:in ;
-59:__UG_NAME__ -> 110:array___binary____op____u____gen___0 ;
-105:__UG_NAME__ -> 110:array___binary____op____u____gen___1 ;
-106:__UG_NAME__ -> 110:array___lf____tri___2 ;
-109:__UG_NAME__ -> 110:array___sin____osc___3 ;
-33:__UG_NAME__ -> 110:which ;
-17:__UG_NAME__ -> 153:array___control___0 ;
-18:__UG_NAME__ -> 153:array___control___1 ;
-152:__UG_NAME__ -> 153:which ;
-150:__UG_NAME__ -> 157:array___unary____op____u____gen___0 ;
-156:__UG_NAME__ -> 157:array___unary____op____u____gen___1 ;
-34:__UG_NAME__ -> 157:which ;
-108:__UG_NAME__ -> 109:phase ;
-55:__UG_NAME__ -> 109:freq ;
-157:__UG_NAME__ -> 158:saw____freq ;
-113:__UG_NAME__ -> 158:sync____freq ;
-
-}
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0001.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0001.wav
new file mode 100644
index 0000000..88031c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0001.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0001.wavetable
new file mode 100644
index 0000000..795e3a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0002.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0002.wav
new file mode 100644
index 0000000..962cb6e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0002.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0002.wavetable
new file mode 100644
index 0000000..f65dd46
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0003.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0003.wav
new file mode 100644
index 0000000..6fc8e35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0003.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0003.wavetable
new file mode 100644
index 0000000..517f851
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0004.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0004.wav
new file mode 100644
index 0000000..dfdaa06
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0004.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0004.wavetable
new file mode 100644
index 0000000..4128b49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0005.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0005.wav
new file mode 100644
index 0000000..cf9111a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0005.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0005.wavetable
new file mode 100644
index 0000000..45e3858
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0006.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0006.wav
new file mode 100644
index 0000000..8bc6dfd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0006.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0006.wavetable
new file mode 100644
index 0000000..5b66e3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0007.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0007.wav
new file mode 100644
index 0000000..ba06ca5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0007.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0007.wavetable
new file mode 100644
index 0000000..aac5a6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0008.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0008.wav
new file mode 100644
index 0000000..958f70f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0008.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0008.wavetable
new file mode 100644
index 0000000..528efb6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0009.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0009.wav
new file mode 100644
index 0000000..7d466df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0009.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0009.wavetable
new file mode 100644
index 0000000..6c7a0bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0010.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0010.wav
new file mode 100644
index 0000000..a3973d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0010.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0010.wavetable
new file mode 100644
index 0000000..a8bf2dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0011.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0011.wav
new file mode 100644
index 0000000..462f665
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0011.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0011.wavetable
new file mode 100644
index 0000000..93d6ed4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0012.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0012.wav
new file mode 100644
index 0000000..44c1e51
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0012.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0012.wavetable
new file mode 100644
index 0000000..900f1d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0013.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0013.wav
new file mode 100644
index 0000000..5195b61
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0013.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0013.wavetable
new file mode 100644
index 0000000..fd59184
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0014.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0014.wav
new file mode 100644
index 0000000..55f84c8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0014.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0014.wavetable
new file mode 100644
index 0000000..b150b48
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0015.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0015.wav
new file mode 100644
index 0000000..5680958
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0015.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0015.wavetable
new file mode 100644
index 0000000..a85a4ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0016.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0016.wav
new file mode 100644
index 0000000..211a8d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0016.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0016.wavetable
new file mode 100644
index 0000000..c5e21a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0017.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0017.wav
new file mode 100644
index 0000000..b7b1d48
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0017.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0017.wavetable
new file mode 100644
index 0000000..fbcde3e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0018.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0018.wav
new file mode 100644
index 0000000..1457d67
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0018.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0018.wavetable
new file mode 100644
index 0000000..7904a71
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0019.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0019.wav
new file mode 100644
index 0000000..fffec35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0019.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0019.wavetable
new file mode 100644
index 0000000..0ea511a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0020.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0020.wav
new file mode 100644
index 0000000..500e2ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0020.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0020.wavetable
new file mode 100644
index 0000000..23ec416
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0021.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0021.wav
new file mode 100644
index 0000000..eed6d4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0021.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0021.wavetable
new file mode 100644
index 0000000..e5f9632
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0022.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0022.wav
new file mode 100644
index 0000000..0f96b09
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0022.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0022.wavetable
new file mode 100644
index 0000000..511a517
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0023.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0023.wav
new file mode 100644
index 0000000..3ce5573
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0023.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0023.wavetable
new file mode 100644
index 0000000..f3084df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0024.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0024.wav
new file mode 100644
index 0000000..3d56cdb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0024.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0024.wavetable
new file mode 100644
index 0000000..5235887
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0025.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0025.wav
new file mode 100644
index 0000000..f2d12d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0025.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0025.wavetable
new file mode 100644
index 0000000..f8b3b61
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0026.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0026.wav
new file mode 100644
index 0000000..6f89ed8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0026.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0026.wavetable
new file mode 100644
index 0000000..1ed42c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0027.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0027.wav
new file mode 100644
index 0000000..7ddd49c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0027.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0027.wavetable
new file mode 100644
index 0000000..d539630
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0028.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0028.wav
new file mode 100644
index 0000000..f54ed8f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0028.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0028.wavetable
new file mode 100644
index 0000000..e4b2d2c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0029.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0029.wav
new file mode 100644
index 0000000..3521aa5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0029.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0029.wavetable
new file mode 100644
index 0000000..5524db6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0030.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0030.wav
new file mode 100644
index 0000000..f682e65
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0030.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0030.wavetable
new file mode 100644
index 0000000..80a624d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0031.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0031.wav
new file mode 100644
index 0000000..911498d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0031.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0031.wavetable
new file mode 100644
index 0000000..dc71ee9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0032.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0032.wav
new file mode 100644
index 0000000..c944195
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0032.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0032.wavetable
new file mode 100644
index 0000000..a6a7838
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0033.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0033.wav
new file mode 100644
index 0000000..3079336
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0033.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0033.wavetable
new file mode 100644
index 0000000..c84727f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0034.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0034.wav
new file mode 100644
index 0000000..903e2db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0034.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0034.wavetable
new file mode 100644
index 0000000..b1d66bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0035.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0035.wav
new file mode 100644
index 0000000..cd94f89
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0035.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0035.wavetable
new file mode 100644
index 0000000..403b68f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0036.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0036.wav
new file mode 100644
index 0000000..4b5600b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0036.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0036.wavetable
new file mode 100644
index 0000000..ce44458
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0037.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0037.wav
new file mode 100644
index 0000000..228a2e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0037.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0037.wavetable
new file mode 100644
index 0000000..38861e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0038.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0038.wav
new file mode 100644
index 0000000..41787bd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0038.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0038.wavetable
new file mode 100644
index 0000000..610c734
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0039.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0039.wav
new file mode 100644
index 0000000..ff63a12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0039.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0039.wavetable
new file mode 100644
index 0000000..eac7fea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0040.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0040.wav
new file mode 100644
index 0000000..40b824d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0040.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0040.wavetable
new file mode 100644
index 0000000..933da19
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0041.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0041.wav
new file mode 100644
index 0000000..996ec45
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0041.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0041.wavetable
new file mode 100644
index 0000000..6c608b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0042.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0042.wav
new file mode 100644
index 0000000..e27259e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0042.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0042.wavetable
new file mode 100644
index 0000000..275df96
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0043.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0043.wav
new file mode 100644
index 0000000..d6be399
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0043.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0043.wavetable
new file mode 100644
index 0000000..4dae933
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0044.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0044.wav
new file mode 100644
index 0000000..f1d4d0e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0044.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0044.wavetable
new file mode 100644
index 0000000..8cd35ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0045.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0045.wav
new file mode 100644
index 0000000..4e7296b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0045.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0045.wavetable
new file mode 100644
index 0000000..05e5ee2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0046.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0046.wav
new file mode 100644
index 0000000..a88df28
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0046.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0046.wavetable
new file mode 100644
index 0000000..98f328e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0047.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0047.wav
new file mode 100644
index 0000000..c7e0618
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0047.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0047.wavetable
new file mode 100644
index 0000000..e50b73a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0048.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0048.wav
new file mode 100644
index 0000000..e75ca67
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0048.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0048.wavetable
new file mode 100644
index 0000000..8d98a86
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0049.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0049.wav
new file mode 100644
index 0000000..f74c209
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0049.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0049.wavetable
new file mode 100644
index 0000000..b2c2ab0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0050.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0050.wav
new file mode 100644
index 0000000..475a09b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0050.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0050.wavetable
new file mode 100644
index 0000000..a5f40a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0051.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0051.wav
new file mode 100644
index 0000000..08308ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0051.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0051.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0051.wavetable
new file mode 100644
index 0000000..8f54793
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0051.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0052.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0052.wav
new file mode 100644
index 0000000..9d6d7e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0052.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0052.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0052.wavetable
new file mode 100644
index 0000000..aa6ca61
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0052.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0053.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0053.wav
new file mode 100644
index 0000000..68acc6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0053.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0053.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0053.wavetable
new file mode 100644
index 0000000..07e10d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0053.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0054.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0054.wav
new file mode 100644
index 0000000..fdd2219
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0054.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0054.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0054.wavetable
new file mode 100644
index 0000000..9d499e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0054.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0055.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0055.wav
new file mode 100644
index 0000000..dff464b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0055.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0055.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0055.wavetable
new file mode 100644
index 0000000..6a8c858
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0055.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0056.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0056.wav
new file mode 100644
index 0000000..7b42c2c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0056.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0056.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0056.wavetable
new file mode 100644
index 0000000..73cd50e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0056.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0057.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0057.wav
new file mode 100644
index 0000000..5155d24
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0057.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0057.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0057.wavetable
new file mode 100644
index 0000000..0a1b56d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0057.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0058.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0058.wav
new file mode 100644
index 0000000..890fe9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0058.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0058.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0058.wavetable
new file mode 100644
index 0000000..2e1375a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0058.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0059.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0059.wav
new file mode 100644
index 0000000..45b2411
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0059.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0059.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0059.wavetable
new file mode 100644
index 0000000..584fde9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0059.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0060.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0060.wav
new file mode 100644
index 0000000..d2deb8c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0060.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0060.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0060.wavetable
new file mode 100644
index 0000000..46067ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0060.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0061.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0061.wav
new file mode 100644
index 0000000..205484e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0061.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0061.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0061.wavetable
new file mode 100644
index 0000000..31135c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0061.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0062.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0062.wav
new file mode 100644
index 0000000..d63addd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0062.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0062.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0062.wavetable
new file mode 100644
index 0000000..8937fc7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0062.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0063.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0063.wav
new file mode 100644
index 0000000..7bad7ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0063.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0063.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0063.wavetable
new file mode 100644
index 0000000..5490463
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0063.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0064.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0064.wav
new file mode 100644
index 0000000..3763a30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0064.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0064.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0064.wavetable
new file mode 100644
index 0000000..cc9c48c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0064.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0065.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0065.wav
new file mode 100644
index 0000000..c36cc2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0065.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0065.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0065.wavetable
new file mode 100644
index 0000000..575c12f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0065.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0066.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0066.wav
new file mode 100644
index 0000000..48afeba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0066.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0066.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0066.wavetable
new file mode 100644
index 0000000..17e3e51
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0066.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0067.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0067.wav
new file mode 100644
index 0000000..fd161d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0067.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0067.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0067.wavetable
new file mode 100644
index 0000000..363be04
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0067.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0068.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0068.wav
new file mode 100644
index 0000000..d7d7f76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0068.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0068.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0068.wavetable
new file mode 100644
index 0000000..e04b408
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0068.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0069.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0069.wav
new file mode 100644
index 0000000..68b3fd3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0069.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0069.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0069.wavetable
new file mode 100644
index 0000000..46d1554
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0069.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0070.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0070.wav
new file mode 100644
index 0000000..2e36319
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0070.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0070.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0070.wavetable
new file mode 100644
index 0000000..390ac7d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0070.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0071.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0071.wav
new file mode 100644
index 0000000..006671f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0071.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0071.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0071.wavetable
new file mode 100644
index 0000000..d8cb95f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0071.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0072.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0072.wav
new file mode 100644
index 0000000..faf9113
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0072.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0072.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0072.wavetable
new file mode 100644
index 0000000..00e829c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0072.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0073.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0073.wav
new file mode 100644
index 0000000..fb82d9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0073.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0073.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0073.wavetable
new file mode 100644
index 0000000..84123bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0073.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0074.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0074.wav
new file mode 100644
index 0000000..3fe83d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0074.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0074.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0074.wavetable
new file mode 100644
index 0000000..b2864ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0074.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0075.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0075.wav
new file mode 100644
index 0000000..d171a81
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0075.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0075.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0075.wavetable
new file mode 100644
index 0000000..f1eef78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0075.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0076.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0076.wav
new file mode 100644
index 0000000..4b5a2af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0076.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0076.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0076.wavetable
new file mode 100644
index 0000000..e460c4b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0076.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0077.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0077.wav
new file mode 100644
index 0000000..7c780c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0077.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0077.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0077.wavetable
new file mode 100644
index 0000000..022a070
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0077.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0078.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0078.wav
new file mode 100644
index 0000000..a3b10ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0078.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0078.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0078.wavetable
new file mode 100644
index 0000000..1bd9e8c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0078.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0079.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0079.wav
new file mode 100644
index 0000000..ac00c80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0079.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0079.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0079.wavetable
new file mode 100644
index 0000000..344d9ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0079.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0080.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0080.wav
new file mode 100644
index 0000000..dfe57ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0080.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0080.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0080.wavetable
new file mode 100644
index 0000000..b484f81
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0080.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0081.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0081.wav
new file mode 100644
index 0000000..91941b7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0081.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0081.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0081.wavetable
new file mode 100644
index 0000000..b0e94c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0081.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0082.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0082.wav
new file mode 100644
index 0000000..47ae93f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0082.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0082.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0082.wavetable
new file mode 100644
index 0000000..855f434
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0082.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0083.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0083.wav
new file mode 100644
index 0000000..ad6cb90
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0083.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0083.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0083.wavetable
new file mode 100644
index 0000000..e01518c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0083.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0084.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0084.wav
new file mode 100644
index 0000000..4188173
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0084.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0084.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0084.wavetable
new file mode 100644
index 0000000..db30f22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0084.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0085.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0085.wav
new file mode 100644
index 0000000..dfb0e89
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0085.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0085.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0085.wavetable
new file mode 100644
index 0000000..9a59813
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0085.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0086.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0086.wav
new file mode 100644
index 0000000..3135d6d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0086.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0086.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0086.wavetable
new file mode 100644
index 0000000..2820130
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0086.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0087.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0087.wav
new file mode 100644
index 0000000..d45340c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0087.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0087.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0087.wavetable
new file mode 100644
index 0000000..f0f0ffb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0087.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0088.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0088.wav
new file mode 100644
index 0000000..dd72c9b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0088.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0088.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0088.wavetable
new file mode 100644
index 0000000..f95f321
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0088.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0089.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0089.wav
new file mode 100644
index 0000000..00dde8d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0089.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0089.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0089.wavetable
new file mode 100644
index 0000000..5fbec6d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0089.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0090.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0090.wav
new file mode 100644
index 0000000..b9441ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0090.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0090.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0090.wavetable
new file mode 100644
index 0000000..0f66a2d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0090.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0091.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0091.wav
new file mode 100644
index 0000000..3a9280a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0091.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0091.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0091.wavetable
new file mode 100644
index 0000000..31c4b03
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0091.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0092.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0092.wav
new file mode 100644
index 0000000..efab7aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0092.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0092.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0092.wavetable
new file mode 100644
index 0000000..ef1374d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0092.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0093.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0093.wav
new file mode 100644
index 0000000..1ceff03
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0093.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0093.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0093.wavetable
new file mode 100644
index 0000000..6164cb7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0093.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0094.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0094.wav
new file mode 100644
index 0000000..1cd3818
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0094.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0094.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0094.wavetable
new file mode 100644
index 0000000..d9299f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0094.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0095.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0095.wav
new file mode 100644
index 0000000..52fe21f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0095.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0095.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0095.wavetable
new file mode 100644
index 0000000..dadf5a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0095.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0096.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0096.wav
new file mode 100644
index 0000000..a95d89e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0096.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0096.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0096.wavetable
new file mode 100644
index 0000000..78ae48e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0096.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0097.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0097.wav
new file mode 100644
index 0000000..74ced0a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0097.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0097.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0097.wavetable
new file mode 100644
index 0000000..7f6094f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0097.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0098.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0098.wav
new file mode 100644
index 0000000..3834e41
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0098.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0098.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0098.wavetable
new file mode 100644
index 0000000..4fd409c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0098.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0099.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0099.wav
new file mode 100644
index 0000000..8a959b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0099.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0099.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0099.wavetable
new file mode 100644
index 0000000..101119b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0099.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0100.wav b/etc/wavetables/AKWF/AKWF_0001/AKWF_0100.wav
new file mode 100644
index 0000000..47042c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0100.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AKWF_0100.wavetable b/etc/wavetables/AKWF/AKWF_0001/AKWF_0100.wavetable
new file mode 100644
index 0000000..59dac8e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0001/AKWF_0100.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0001/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0001/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0001/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0101.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0101.wav
new file mode 100644
index 0000000..c7dc46a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0101.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0101.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0101.wavetable
new file mode 100644
index 0000000..f927bc9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0101.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0102.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0102.wav
new file mode 100644
index 0000000..6b1fe59
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0102.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0102.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0102.wavetable
new file mode 100644
index 0000000..1f729f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0102.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0103.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0103.wav
new file mode 100644
index 0000000..e4d9d55
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0103.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0103.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0103.wavetable
new file mode 100644
index 0000000..6678f51
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0103.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0104.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0104.wav
new file mode 100644
index 0000000..b7326a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0104.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0104.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0104.wavetable
new file mode 100644
index 0000000..51a1a15
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0104.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0105.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0105.wav
new file mode 100644
index 0000000..ab0d635
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0105.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0105.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0105.wavetable
new file mode 100644
index 0000000..50c0c18
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0105.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0106.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0106.wav
new file mode 100644
index 0000000..9c5ae6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0106.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0106.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0106.wavetable
new file mode 100644
index 0000000..7544aca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0106.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0107.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0107.wav
new file mode 100644
index 0000000..3acfb76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0107.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0107.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0107.wavetable
new file mode 100644
index 0000000..f614b40
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0107.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0108.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0108.wav
new file mode 100644
index 0000000..d597e3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0108.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0108.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0108.wavetable
new file mode 100644
index 0000000..cc98f95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0108.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0109.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0109.wav
new file mode 100644
index 0000000..6a151ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0109.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0109.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0109.wavetable
new file mode 100644
index 0000000..fccb799
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0109.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0110.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0110.wav
new file mode 100644
index 0000000..3397ea2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0110.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0110.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0110.wavetable
new file mode 100644
index 0000000..ee3dcf8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0110.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0111.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0111.wav
new file mode 100644
index 0000000..250c5d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0111.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0111.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0111.wavetable
new file mode 100644
index 0000000..54e8f3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0111.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0112.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0112.wav
new file mode 100644
index 0000000..7f0172c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0112.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0112.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0112.wavetable
new file mode 100644
index 0000000..2a6c155
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0112.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0113.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0113.wav
new file mode 100644
index 0000000..2e10acd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0113.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0113.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0113.wavetable
new file mode 100644
index 0000000..8915868
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0113.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0114.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0114.wav
new file mode 100644
index 0000000..c6ffa2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0114.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0114.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0114.wavetable
new file mode 100644
index 0000000..a5d8f35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0114.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0115.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0115.wav
new file mode 100644
index 0000000..5e16eec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0115.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0115.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0115.wavetable
new file mode 100644
index 0000000..62ad767
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0115.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0116.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0116.wav
new file mode 100644
index 0000000..95947d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0116.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0116.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0116.wavetable
new file mode 100644
index 0000000..c719c80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0116.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0117.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0117.wav
new file mode 100644
index 0000000..b55f1da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0117.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0117.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0117.wavetable
new file mode 100644
index 0000000..c47b9bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0117.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0118.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0118.wav
new file mode 100644
index 0000000..b755bfe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0118.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0118.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0118.wavetable
new file mode 100644
index 0000000..d49a346
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0118.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0119.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0119.wav
new file mode 100644
index 0000000..85ee8b7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0119.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0119.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0119.wavetable
new file mode 100644
index 0000000..69a2b5f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0119.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0120.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0120.wav
new file mode 100644
index 0000000..8c8c209
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0120.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0120.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0120.wavetable
new file mode 100644
index 0000000..b8f9f58
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0120.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0121.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0121.wav
new file mode 100644
index 0000000..26847d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0121.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0121.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0121.wavetable
new file mode 100644
index 0000000..d03f743
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0121.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0122.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0122.wav
new file mode 100644
index 0000000..529b6f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0122.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0122.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0122.wavetable
new file mode 100644
index 0000000..f498859
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0122.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0123.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0123.wav
new file mode 100644
index 0000000..461069d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0123.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0123.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0123.wavetable
new file mode 100644
index 0000000..bd9d326
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0123.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0124.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0124.wav
new file mode 100644
index 0000000..9c69196
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0124.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0124.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0124.wavetable
new file mode 100644
index 0000000..431c5a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0124.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0125.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0125.wav
new file mode 100644
index 0000000..468a74f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0125.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0125.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0125.wavetable
new file mode 100644
index 0000000..bcaadf3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0125.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0126.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0126.wav
new file mode 100644
index 0000000..72b94d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0126.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0126.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0126.wavetable
new file mode 100644
index 0000000..3a431a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0126.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0127.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0127.wav
new file mode 100644
index 0000000..fa6a5f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0127.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0127.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0127.wavetable
new file mode 100644
index 0000000..956ede7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0127.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0128.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0128.wav
new file mode 100644
index 0000000..b87c3c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0128.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0128.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0128.wavetable
new file mode 100644
index 0000000..9906b0c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0128.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0129.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0129.wav
new file mode 100644
index 0000000..65d40a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0129.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0129.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0129.wavetable
new file mode 100644
index 0000000..b7a08b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0129.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0130.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0130.wav
new file mode 100644
index 0000000..fb7efae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0130.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0130.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0130.wavetable
new file mode 100644
index 0000000..9109ed5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0130.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0131.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0131.wav
new file mode 100644
index 0000000..4d3d7b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0131.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0131.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0131.wavetable
new file mode 100644
index 0000000..6180b33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0131.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0132.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0132.wav
new file mode 100644
index 0000000..f9d5756
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0132.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0132.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0132.wavetable
new file mode 100644
index 0000000..c8c4c4f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0132.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0133.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0133.wav
new file mode 100644
index 0000000..fb1f465
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0133.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0133.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0133.wavetable
new file mode 100644
index 0000000..c329ac9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0133.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0134.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0134.wav
new file mode 100644
index 0000000..abfdb2c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0134.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0134.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0134.wavetable
new file mode 100644
index 0000000..2a5fbe7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0134.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0135.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0135.wav
new file mode 100644
index 0000000..ce3bdeb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0135.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0135.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0135.wavetable
new file mode 100644
index 0000000..2071a0e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0135.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0136.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0136.wav
new file mode 100644
index 0000000..983d6b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0136.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0136.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0136.wavetable
new file mode 100644
index 0000000..2b76df7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0136.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0137.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0137.wav
new file mode 100644
index 0000000..537f021
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0137.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0137.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0137.wavetable
new file mode 100644
index 0000000..6a30fd8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0137.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0138.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0138.wav
new file mode 100644
index 0000000..2f8d4c7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0138.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0138.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0138.wavetable
new file mode 100644
index 0000000..1c24c6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0138.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0139.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0139.wav
new file mode 100644
index 0000000..eb7e1a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0139.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0139.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0139.wavetable
new file mode 100644
index 0000000..679cc19
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0139.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0140.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0140.wav
new file mode 100644
index 0000000..8809047
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0140.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0140.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0140.wavetable
new file mode 100644
index 0000000..efce942
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0140.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0141.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0141.wav
new file mode 100644
index 0000000..f2fbb4f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0141.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0141.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0141.wavetable
new file mode 100644
index 0000000..a722c0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0141.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0142.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0142.wav
new file mode 100644
index 0000000..375d355
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0142.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0142.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0142.wavetable
new file mode 100644
index 0000000..6aabbac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0142.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0143.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0143.wav
new file mode 100644
index 0000000..59f2774
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0143.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0143.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0143.wavetable
new file mode 100644
index 0000000..6c801f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0143.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0144.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0144.wav
new file mode 100644
index 0000000..24828b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0144.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0144.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0144.wavetable
new file mode 100644
index 0000000..c2788dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0144.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0145.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0145.wav
new file mode 100644
index 0000000..0a3892f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0145.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0145.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0145.wavetable
new file mode 100644
index 0000000..b95745e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0145.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0146.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0146.wav
new file mode 100644
index 0000000..a5a87b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0146.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0146.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0146.wavetable
new file mode 100644
index 0000000..7889ad8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0146.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0147.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0147.wav
new file mode 100644
index 0000000..dcfb17d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0147.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0147.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0147.wavetable
new file mode 100644
index 0000000..e7f3267
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0147.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0148.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0148.wav
new file mode 100644
index 0000000..53cf686
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0148.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0148.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0148.wavetable
new file mode 100644
index 0000000..c0fd5dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0148.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0149.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0149.wav
new file mode 100644
index 0000000..8bec411
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0149.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0149.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0149.wavetable
new file mode 100644
index 0000000..ea29066
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0149.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0150.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0150.wav
new file mode 100644
index 0000000..cf03d56
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0150.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0150.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0150.wavetable
new file mode 100644
index 0000000..49bbe6d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0150.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0151.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0151.wav
new file mode 100644
index 0000000..fc23c4a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0151.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0151.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0151.wavetable
new file mode 100644
index 0000000..593d8a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0151.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0152.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0152.wav
new file mode 100644
index 0000000..41a6d12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0152.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0152.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0152.wavetable
new file mode 100644
index 0000000..5e3693c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0152.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0153.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0153.wav
new file mode 100644
index 0000000..d34e573
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0153.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0153.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0153.wavetable
new file mode 100644
index 0000000..90f3f95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0153.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0154.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0154.wav
new file mode 100644
index 0000000..8b02b22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0154.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0154.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0154.wavetable
new file mode 100644
index 0000000..ca442cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0154.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0155.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0155.wav
new file mode 100644
index 0000000..e82c20b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0155.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0155.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0155.wavetable
new file mode 100644
index 0000000..a900446
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0155.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0156.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0156.wav
new file mode 100644
index 0000000..22e9236
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0156.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0156.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0156.wavetable
new file mode 100644
index 0000000..0203b61
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0156.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0157.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0157.wav
new file mode 100644
index 0000000..2763570
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0157.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0157.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0157.wavetable
new file mode 100644
index 0000000..5031630
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0157.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0158.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0158.wav
new file mode 100644
index 0000000..9ed1ea7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0158.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0158.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0158.wavetable
new file mode 100644
index 0000000..bdab97d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0158.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0159.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0159.wav
new file mode 100644
index 0000000..9a58c63
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0159.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0159.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0159.wavetable
new file mode 100644
index 0000000..2d3ad32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0159.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0160.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0160.wav
new file mode 100644
index 0000000..28f81ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0160.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0160.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0160.wavetable
new file mode 100644
index 0000000..abbedf1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0160.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0161.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0161.wav
new file mode 100644
index 0000000..450b845
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0161.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0161.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0161.wavetable
new file mode 100644
index 0000000..d20531d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0161.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0162.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0162.wav
new file mode 100644
index 0000000..d6c26db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0162.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0162.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0162.wavetable
new file mode 100644
index 0000000..2c6b024
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0162.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0163.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0163.wav
new file mode 100644
index 0000000..f50b4a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0163.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0163.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0163.wavetable
new file mode 100644
index 0000000..ecd8f45
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0163.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0164.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0164.wav
new file mode 100644
index 0000000..0428092
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0164.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0164.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0164.wavetable
new file mode 100644
index 0000000..72d4e1f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0164.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0165.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0165.wav
new file mode 100644
index 0000000..fec4ba5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0165.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0165.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0165.wavetable
new file mode 100644
index 0000000..2f77b88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0165.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0166.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0166.wav
new file mode 100644
index 0000000..d5c753c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0166.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0166.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0166.wavetable
new file mode 100644
index 0000000..73bfad4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0166.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0167.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0167.wav
new file mode 100644
index 0000000..58cbd5a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0167.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0167.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0167.wavetable
new file mode 100644
index 0000000..67768c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0167.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0168.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0168.wav
new file mode 100644
index 0000000..38a415d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0168.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0168.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0168.wavetable
new file mode 100644
index 0000000..1aa17ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0168.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0169.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0169.wav
new file mode 100644
index 0000000..bfee1cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0169.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0169.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0169.wavetable
new file mode 100644
index 0000000..acb0125
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0169.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0170.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0170.wav
new file mode 100644
index 0000000..767bd0e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0170.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0170.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0170.wavetable
new file mode 100644
index 0000000..a0c5dfc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0170.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0171.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0171.wav
new file mode 100644
index 0000000..0676133
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0171.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0171.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0171.wavetable
new file mode 100644
index 0000000..7cb52bd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0171.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0172.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0172.wav
new file mode 100644
index 0000000..0243199
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0172.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0172.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0172.wavetable
new file mode 100644
index 0000000..9fb3821
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0172.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0173.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0173.wav
new file mode 100644
index 0000000..cbd7280
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0173.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0173.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0173.wavetable
new file mode 100644
index 0000000..f5965bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0173.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0174.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0174.wav
new file mode 100644
index 0000000..2329cbc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0174.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0174.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0174.wavetable
new file mode 100644
index 0000000..73f0ceb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0174.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0175.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0175.wav
new file mode 100644
index 0000000..d8e6017
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0175.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0175.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0175.wavetable
new file mode 100644
index 0000000..8f51fe2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0175.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0176.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0176.wav
new file mode 100644
index 0000000..d8ee83c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0176.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0176.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0176.wavetable
new file mode 100644
index 0000000..c9916df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0176.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0177.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0177.wav
new file mode 100644
index 0000000..d1014d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0177.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0177.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0177.wavetable
new file mode 100644
index 0000000..0e9fc3a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0177.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0178.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0178.wav
new file mode 100644
index 0000000..86867d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0178.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0178.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0178.wavetable
new file mode 100644
index 0000000..ebe8459
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0178.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0179.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0179.wav
new file mode 100644
index 0000000..ff881b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0179.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0179.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0179.wavetable
new file mode 100644
index 0000000..d6a695d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0179.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0180.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0180.wav
new file mode 100644
index 0000000..9fc9313
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0180.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0180.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0180.wavetable
new file mode 100644
index 0000000..6c5666e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0180.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0181.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0181.wav
new file mode 100644
index 0000000..64944ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0181.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0181.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0181.wavetable
new file mode 100644
index 0000000..21cd53f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0181.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0182.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0182.wav
new file mode 100644
index 0000000..378010f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0182.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0182.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0182.wavetable
new file mode 100644
index 0000000..91250b3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0182.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0183.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0183.wav
new file mode 100644
index 0000000..997a3d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0183.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0183.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0183.wavetable
new file mode 100644
index 0000000..2735663
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0183.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0184.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0184.wav
new file mode 100644
index 0000000..8d9c78b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0184.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0184.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0184.wavetable
new file mode 100644
index 0000000..284f9ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0184.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0185.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0185.wav
new file mode 100644
index 0000000..5c44bd6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0185.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0185.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0185.wavetable
new file mode 100644
index 0000000..fac1027
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0185.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0186.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0186.wav
new file mode 100644
index 0000000..708002b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0186.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0186.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0186.wavetable
new file mode 100644
index 0000000..777a48f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0186.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0187.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0187.wav
new file mode 100644
index 0000000..5dd342c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0187.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0187.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0187.wavetable
new file mode 100644
index 0000000..5b336b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0187.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0188.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0188.wav
new file mode 100644
index 0000000..d729b5d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0188.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0188.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0188.wavetable
new file mode 100644
index 0000000..60c4f91
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0188.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0189.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0189.wav
new file mode 100644
index 0000000..d65129f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0189.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0189.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0189.wavetable
new file mode 100644
index 0000000..c8b6f79
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0189.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0190.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0190.wav
new file mode 100644
index 0000000..b28d504
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0190.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0190.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0190.wavetable
new file mode 100644
index 0000000..4aceab0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0190.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0191.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0191.wav
new file mode 100644
index 0000000..e29957f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0191.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0191.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0191.wavetable
new file mode 100644
index 0000000..619c021
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0191.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0192.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0192.wav
new file mode 100644
index 0000000..05821b7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0192.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0192.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0192.wavetable
new file mode 100644
index 0000000..f377bc0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0192.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0193.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0193.wav
new file mode 100644
index 0000000..c689935
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0193.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0193.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0193.wavetable
new file mode 100644
index 0000000..96ffe22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0193.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0194.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0194.wav
new file mode 100644
index 0000000..df289ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0194.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0194.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0194.wavetable
new file mode 100644
index 0000000..7f51c3a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0194.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0195.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0195.wav
new file mode 100644
index 0000000..e556487
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0195.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0195.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0195.wavetable
new file mode 100644
index 0000000..10ebe08
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0195.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0196.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0196.wav
new file mode 100644
index 0000000..28cb93e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0196.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0196.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0196.wavetable
new file mode 100644
index 0000000..7060ebe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0196.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0197.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0197.wav
new file mode 100644
index 0000000..8bc5980
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0197.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0197.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0197.wavetable
new file mode 100644
index 0000000..2e1cc5a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0197.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0198.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0198.wav
new file mode 100644
index 0000000..becf4da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0198.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0198.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0198.wavetable
new file mode 100644
index 0000000..b329c61
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0198.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0199.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0199.wav
new file mode 100644
index 0000000..79f280e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0199.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0199.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0199.wavetable
new file mode 100644
index 0000000..a9943d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0199.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0200.wav b/etc/wavetables/AKWF/AKWF_0002/AKWF_0200.wav
new file mode 100644
index 0000000..471fddc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0200.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AKWF_0200.wavetable b/etc/wavetables/AKWF/AKWF_0002/AKWF_0200.wavetable
new file mode 100644
index 0000000..635d7ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0002/AKWF_0200.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0002/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0002/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0002/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0201.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0201.wav
new file mode 100644
index 0000000..d1f3744
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0201.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0201.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0201.wavetable
new file mode 100644
index 0000000..60c7a3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0201.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0202.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0202.wav
new file mode 100644
index 0000000..e6b82b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0202.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0202.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0202.wavetable
new file mode 100644
index 0000000..cfc1f2a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0202.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0203.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0203.wav
new file mode 100644
index 0000000..b772be4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0203.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0203.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0203.wavetable
new file mode 100644
index 0000000..9e1aed2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0203.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0204.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0204.wav
new file mode 100644
index 0000000..258265c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0204.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0204.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0204.wavetable
new file mode 100644
index 0000000..01e0608
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0204.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0205.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0205.wav
new file mode 100644
index 0000000..57022f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0205.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0205.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0205.wavetable
new file mode 100644
index 0000000..2c000eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0205.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0206.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0206.wav
new file mode 100644
index 0000000..9eb237f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0206.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0206.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0206.wavetable
new file mode 100644
index 0000000..0da97d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0206.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0207.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0207.wav
new file mode 100644
index 0000000..b38fdfd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0207.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0207.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0207.wavetable
new file mode 100644
index 0000000..c6ad5c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0207.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0208.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0208.wav
new file mode 100644
index 0000000..afe613a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0208.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0208.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0208.wavetable
new file mode 100644
index 0000000..69d08e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0208.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0209.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0209.wav
new file mode 100644
index 0000000..a7fb3e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0209.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0209.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0209.wavetable
new file mode 100644
index 0000000..d979bf9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0209.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0210.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0210.wav
new file mode 100644
index 0000000..e16a6e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0210.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0210.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0210.wavetable
new file mode 100644
index 0000000..5fd7af0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0210.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0211.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0211.wav
new file mode 100644
index 0000000..4d30755
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0211.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0211.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0211.wavetable
new file mode 100644
index 0000000..cc8b742
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0211.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0212.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0212.wav
new file mode 100644
index 0000000..a62773d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0212.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0212.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0212.wavetable
new file mode 100644
index 0000000..4cfebfd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0212.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0213.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0213.wav
new file mode 100644
index 0000000..3ba36eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0213.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0213.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0213.wavetable
new file mode 100644
index 0000000..43b578b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0213.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0214.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0214.wav
new file mode 100644
index 0000000..5b96d81
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0214.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0214.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0214.wavetable
new file mode 100644
index 0000000..aa26d64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0214.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0215.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0215.wav
new file mode 100644
index 0000000..c1e5930
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0215.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0215.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0215.wavetable
new file mode 100644
index 0000000..1cf4867
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0215.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0216.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0216.wav
new file mode 100644
index 0000000..29896d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0216.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0216.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0216.wavetable
new file mode 100644
index 0000000..0fd00d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0216.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0217.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0217.wav
new file mode 100644
index 0000000..e8c6ffb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0217.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0217.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0217.wavetable
new file mode 100644
index 0000000..e05acb2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0217.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0218.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0218.wav
new file mode 100644
index 0000000..1af3870
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0218.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0218.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0218.wavetable
new file mode 100644
index 0000000..c504ca4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0218.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0219.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0219.wav
new file mode 100644
index 0000000..35011f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0219.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0219.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0219.wavetable
new file mode 100644
index 0000000..92b8d84
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0219.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0220.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0220.wav
new file mode 100644
index 0000000..8d1abf3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0220.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0220.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0220.wavetable
new file mode 100644
index 0000000..27740e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0220.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0221.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0221.wav
new file mode 100644
index 0000000..d5258e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0221.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0221.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0221.wavetable
new file mode 100644
index 0000000..de3c7d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0221.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0222.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0222.wav
new file mode 100644
index 0000000..7cf9835
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0222.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0222.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0222.wavetable
new file mode 100644
index 0000000..e0dadb0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0222.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0223.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0223.wav
new file mode 100644
index 0000000..3781f21
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0223.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0223.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0223.wavetable
new file mode 100644
index 0000000..63ad293
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0223.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0224.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0224.wav
new file mode 100644
index 0000000..5a20fdc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0224.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0224.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0224.wavetable
new file mode 100644
index 0000000..5db3aae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0224.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0225.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0225.wav
new file mode 100644
index 0000000..ebc0bfd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0225.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0225.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0225.wavetable
new file mode 100644
index 0000000..4e0452b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0225.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0226.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0226.wav
new file mode 100644
index 0000000..954c482
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0226.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0226.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0226.wavetable
new file mode 100644
index 0000000..1ce5856
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0226.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0227.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0227.wav
new file mode 100644
index 0000000..d5056da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0227.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0227.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0227.wavetable
new file mode 100644
index 0000000..89732d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0227.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0228.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0228.wav
new file mode 100644
index 0000000..8c846a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0228.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0228.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0228.wavetable
new file mode 100644
index 0000000..612a904
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0228.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0229.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0229.wav
new file mode 100644
index 0000000..00c875e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0229.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0229.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0229.wavetable
new file mode 100644
index 0000000..da43c38
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0229.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0230.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0230.wav
new file mode 100644
index 0000000..eb0cbf1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0230.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0230.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0230.wavetable
new file mode 100644
index 0000000..ad43422
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0230.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0231.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0231.wav
new file mode 100644
index 0000000..0d0e66a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0231.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0231.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0231.wavetable
new file mode 100644
index 0000000..f8041c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0231.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0232.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0232.wav
new file mode 100644
index 0000000..b23c798
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0232.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0232.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0232.wavetable
new file mode 100644
index 0000000..97df400
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0232.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0233.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0233.wav
new file mode 100644
index 0000000..6797162
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0233.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0233.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0233.wavetable
new file mode 100644
index 0000000..99d662c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0233.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0234.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0234.wav
new file mode 100644
index 0000000..9e2317c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0234.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0234.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0234.wavetable
new file mode 100644
index 0000000..2596bca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0234.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0235.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0235.wav
new file mode 100644
index 0000000..702ee39
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0235.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0235.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0235.wavetable
new file mode 100644
index 0000000..28019af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0235.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0236.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0236.wav
new file mode 100644
index 0000000..13d971b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0236.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0236.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0236.wavetable
new file mode 100644
index 0000000..d4b6aac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0236.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0237.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0237.wav
new file mode 100644
index 0000000..7acfeca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0237.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0237.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0237.wavetable
new file mode 100644
index 0000000..b0a25bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0237.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0238.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0238.wav
new file mode 100644
index 0000000..2145c9c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0238.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0238.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0238.wavetable
new file mode 100644
index 0000000..6fad46b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0238.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0239.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0239.wav
new file mode 100644
index 0000000..6e9ff3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0239.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0239.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0239.wavetable
new file mode 100644
index 0000000..44e37f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0239.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0240.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0240.wav
new file mode 100644
index 0000000..e5cb6ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0240.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0240.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0240.wavetable
new file mode 100644
index 0000000..e76b85b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0240.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0241.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0241.wav
new file mode 100644
index 0000000..7f93068
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0241.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0241.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0241.wavetable
new file mode 100644
index 0000000..293ae57
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0241.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0242.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0242.wav
new file mode 100644
index 0000000..f50ee32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0242.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0242.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0242.wavetable
new file mode 100644
index 0000000..b99f6e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0242.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0243.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0243.wav
new file mode 100644
index 0000000..47ab00a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0243.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0243.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0243.wavetable
new file mode 100644
index 0000000..2b02ef6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0243.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0244.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0244.wav
new file mode 100644
index 0000000..7713435
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0244.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0244.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0244.wavetable
new file mode 100644
index 0000000..07720ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0244.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0245.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0245.wav
new file mode 100644
index 0000000..9d701db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0245.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0245.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0245.wavetable
new file mode 100644
index 0000000..d649c79
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0245.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0246.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0246.wav
new file mode 100644
index 0000000..7ae8a47
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0246.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0246.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0246.wavetable
new file mode 100644
index 0000000..0e59c05
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0246.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0247.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0247.wav
new file mode 100644
index 0000000..39ccacb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0247.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0247.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0247.wavetable
new file mode 100644
index 0000000..3e18a55
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0247.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0248.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0248.wav
new file mode 100644
index 0000000..90a977b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0248.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0248.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0248.wavetable
new file mode 100644
index 0000000..aa3ef33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0248.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0249.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0249.wav
new file mode 100644
index 0000000..a1e3571
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0249.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0249.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0249.wavetable
new file mode 100644
index 0000000..1044077
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0249.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0250.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0250.wav
new file mode 100644
index 0000000..1239329
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0250.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0250.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0250.wavetable
new file mode 100644
index 0000000..c9e32b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0250.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0251.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0251.wav
new file mode 100644
index 0000000..f2f2976
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0251.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0251.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0251.wavetable
new file mode 100644
index 0000000..d64c456
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0251.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0252.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0252.wav
new file mode 100644
index 0000000..38f3ca9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0252.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0252.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0252.wavetable
new file mode 100644
index 0000000..256415e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0252.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0253.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0253.wav
new file mode 100644
index 0000000..c7357cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0253.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0253.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0253.wavetable
new file mode 100644
index 0000000..77864ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0253.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0254.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0254.wav
new file mode 100644
index 0000000..86b13be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0254.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0254.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0254.wavetable
new file mode 100644
index 0000000..223a1cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0254.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0255.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0255.wav
new file mode 100644
index 0000000..a18060a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0255.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0255.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0255.wavetable
new file mode 100644
index 0000000..25e0016
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0255.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0256.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0256.wav
new file mode 100644
index 0000000..050de01
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0256.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0256.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0256.wavetable
new file mode 100644
index 0000000..b73de53
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0256.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0257.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0257.wav
new file mode 100644
index 0000000..cb27a72
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0257.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0257.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0257.wavetable
new file mode 100644
index 0000000..74c77de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0257.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0258.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0258.wav
new file mode 100644
index 0000000..100c5d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0258.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0258.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0258.wavetable
new file mode 100644
index 0000000..b838756
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0258.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0259.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0259.wav
new file mode 100644
index 0000000..fabd29a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0259.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0259.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0259.wavetable
new file mode 100644
index 0000000..aa37660
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0259.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0260.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0260.wav
new file mode 100644
index 0000000..33c252e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0260.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0260.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0260.wavetable
new file mode 100644
index 0000000..9de3c53
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0260.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0261.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0261.wav
new file mode 100644
index 0000000..45902ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0261.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0261.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0261.wavetable
new file mode 100644
index 0000000..571c859
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0261.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0262.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0262.wav
new file mode 100644
index 0000000..fd289c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0262.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0262.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0262.wavetable
new file mode 100644
index 0000000..f8b52f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0262.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0263.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0263.wav
new file mode 100644
index 0000000..cd2d22c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0263.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0263.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0263.wavetable
new file mode 100644
index 0000000..1bef0ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0263.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0264.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0264.wav
new file mode 100644
index 0000000..8345402
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0264.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0264.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0264.wavetable
new file mode 100644
index 0000000..0edc3b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0264.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0265.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0265.wav
new file mode 100644
index 0000000..b03973a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0265.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0265.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0265.wavetable
new file mode 100644
index 0000000..c638d97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0265.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0266.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0266.wav
new file mode 100644
index 0000000..0ce2960
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0266.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0266.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0266.wavetable
new file mode 100644
index 0000000..7cf6900
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0266.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0267.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0267.wav
new file mode 100644
index 0000000..ce4c31f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0267.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0267.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0267.wavetable
new file mode 100644
index 0000000..6bd0d0c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0267.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0268.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0268.wav
new file mode 100644
index 0000000..80de43c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0268.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0268.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0268.wavetable
new file mode 100644
index 0000000..d9da4e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0268.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0269.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0269.wav
new file mode 100644
index 0000000..8929269
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0269.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0269.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0269.wavetable
new file mode 100644
index 0000000..d53308f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0269.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0270.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0270.wav
new file mode 100644
index 0000000..04aab8b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0270.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0270.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0270.wavetable
new file mode 100644
index 0000000..3c64a0b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0270.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0271.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0271.wav
new file mode 100644
index 0000000..2b360e3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0271.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0271.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0271.wavetable
new file mode 100644
index 0000000..8e36e92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0271.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0272.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0272.wav
new file mode 100644
index 0000000..bc5bfed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0272.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0272.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0272.wavetable
new file mode 100644
index 0000000..9111d58
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0272.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0273.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0273.wav
new file mode 100644
index 0000000..d9affb5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0273.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0273.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0273.wavetable
new file mode 100644
index 0000000..ff4cd15
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0273.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0274.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0274.wav
new file mode 100644
index 0000000..b0a7796
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0274.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0274.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0274.wavetable
new file mode 100644
index 0000000..a95fd71
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0274.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0275.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0275.wav
new file mode 100644
index 0000000..894cde3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0275.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0275.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0275.wavetable
new file mode 100644
index 0000000..acb1bd2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0275.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0276.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0276.wav
new file mode 100644
index 0000000..4da1866
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0276.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0276.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0276.wavetable
new file mode 100644
index 0000000..d6e3ebc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0276.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0277.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0277.wav
new file mode 100644
index 0000000..d4eb296
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0277.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0277.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0277.wavetable
new file mode 100644
index 0000000..2b71d27
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0277.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0278.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0278.wav
new file mode 100644
index 0000000..9e2b83e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0278.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0278.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0278.wavetable
new file mode 100644
index 0000000..3d2b350
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0278.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0279.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0279.wav
new file mode 100644
index 0000000..ce685d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0279.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0279.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0279.wavetable
new file mode 100644
index 0000000..e72fa96
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0279.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0280.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0280.wav
new file mode 100644
index 0000000..37e3b5a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0280.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0280.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0280.wavetable
new file mode 100644
index 0000000..19c90cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0280.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0281.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0281.wav
new file mode 100644
index 0000000..09091ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0281.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0281.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0281.wavetable
new file mode 100644
index 0000000..dbdd5a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0281.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0282.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0282.wav
new file mode 100644
index 0000000..3f99d3e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0282.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0282.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0282.wavetable
new file mode 100644
index 0000000..d7820f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0282.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0283.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0283.wav
new file mode 100644
index 0000000..d9d645d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0283.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0283.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0283.wavetable
new file mode 100644
index 0000000..b02850f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0283.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0284.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0284.wav
new file mode 100644
index 0000000..aa3b980
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0284.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0284.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0284.wavetable
new file mode 100644
index 0000000..2c8dd88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0284.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0285.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0285.wav
new file mode 100644
index 0000000..db2b1d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0285.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0285.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0285.wavetable
new file mode 100644
index 0000000..d49314c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0285.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0286.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0286.wav
new file mode 100644
index 0000000..59f340e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0286.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0286.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0286.wavetable
new file mode 100644
index 0000000..d999eca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0286.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0287.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0287.wav
new file mode 100644
index 0000000..6a74735
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0287.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0287.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0287.wavetable
new file mode 100644
index 0000000..145b714
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0287.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0288.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0288.wav
new file mode 100644
index 0000000..195c7a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0288.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0288.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0288.wavetable
new file mode 100644
index 0000000..6fa0c6d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0288.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0289.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0289.wav
new file mode 100644
index 0000000..6e5c19b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0289.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0289.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0289.wavetable
new file mode 100644
index 0000000..fe65e74
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0289.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0290.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0290.wav
new file mode 100644
index 0000000..a8d92b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0290.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0290.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0290.wavetable
new file mode 100644
index 0000000..4b0c6da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0290.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0291.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0291.wav
new file mode 100644
index 0000000..418df18
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0291.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0291.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0291.wavetable
new file mode 100644
index 0000000..b02fa16
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0291.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0292.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0292.wav
new file mode 100644
index 0000000..89e5c36
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0292.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0292.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0292.wavetable
new file mode 100644
index 0000000..479ccdd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0292.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0293.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0293.wav
new file mode 100644
index 0000000..44936b3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0293.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0293.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0293.wavetable
new file mode 100644
index 0000000..7b7ea86
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0293.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0294.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0294.wav
new file mode 100644
index 0000000..3e35ad6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0294.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0294.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0294.wavetable
new file mode 100644
index 0000000..6af16f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0294.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0295.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0295.wav
new file mode 100644
index 0000000..61ac0f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0295.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0295.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0295.wavetable
new file mode 100644
index 0000000..07f957b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0295.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0296.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0296.wav
new file mode 100644
index 0000000..2df0e84
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0296.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0296.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0296.wavetable
new file mode 100644
index 0000000..cfcfcf3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0296.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0297.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0297.wav
new file mode 100644
index 0000000..ede6511
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0297.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0297.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0297.wavetable
new file mode 100644
index 0000000..4b1f805
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0297.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0298.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0298.wav
new file mode 100644
index 0000000..c31457f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0298.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0298.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0298.wavetable
new file mode 100644
index 0000000..83463ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0298.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0299.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0299.wav
new file mode 100644
index 0000000..3734b5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0299.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0299.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0299.wavetable
new file mode 100644
index 0000000..6c0939d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0299.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0300.wav b/etc/wavetables/AKWF/AKWF_0003/AKWF_0300.wav
new file mode 100644
index 0000000..f20c8b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0300.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AKWF_0300.wavetable b/etc/wavetables/AKWF/AKWF_0003/AKWF_0300.wavetable
new file mode 100644
index 0000000..73f92bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0003/AKWF_0300.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0003/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0003/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0003/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0301.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0301.wav
new file mode 100644
index 0000000..1371d48
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0301.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0301.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0301.wavetable
new file mode 100644
index 0000000..efd6b4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0301.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0302.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0302.wav
new file mode 100644
index 0000000..f525c35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0302.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0302.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0302.wavetable
new file mode 100644
index 0000000..8bb3808
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0302.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0303.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0303.wav
new file mode 100644
index 0000000..50e8db3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0303.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0303.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0303.wavetable
new file mode 100644
index 0000000..7646c27
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0303.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0304.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0304.wav
new file mode 100644
index 0000000..f4febaf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0304.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0304.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0304.wavetable
new file mode 100644
index 0000000..3a2c26a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0304.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0305.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0305.wav
new file mode 100644
index 0000000..6abdd4b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0305.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0305.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0305.wavetable
new file mode 100644
index 0000000..06b70af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0305.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0306.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0306.wav
new file mode 100644
index 0000000..865a2bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0306.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0306.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0306.wavetable
new file mode 100644
index 0000000..44d692d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0306.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0307.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0307.wav
new file mode 100644
index 0000000..f9da4cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0307.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0307.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0307.wavetable
new file mode 100644
index 0000000..4371a4a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0307.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0308.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0308.wav
new file mode 100644
index 0000000..9b53f4a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0308.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0308.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0308.wavetable
new file mode 100644
index 0000000..fff1c45
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0308.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0309.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0309.wav
new file mode 100644
index 0000000..be93e12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0309.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0309.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0309.wavetable
new file mode 100644
index 0000000..30cc0f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0309.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0310.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0310.wav
new file mode 100644
index 0000000..ce67d6a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0310.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0310.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0310.wavetable
new file mode 100644
index 0000000..3a6d0e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0310.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0311.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0311.wav
new file mode 100644
index 0000000..bab41ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0311.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0311.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0311.wavetable
new file mode 100644
index 0000000..b179bc7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0311.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0312.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0312.wav
new file mode 100644
index 0000000..77690b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0312.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0312.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0312.wavetable
new file mode 100644
index 0000000..05190c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0312.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0313.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0313.wav
new file mode 100644
index 0000000..e0a8861
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0313.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0313.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0313.wavetable
new file mode 100644
index 0000000..754c964
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0313.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0314.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0314.wav
new file mode 100644
index 0000000..58877a9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0314.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0314.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0314.wavetable
new file mode 100644
index 0000000..77a34f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0314.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0315.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0315.wav
new file mode 100644
index 0000000..06287ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0315.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0315.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0315.wavetable
new file mode 100644
index 0000000..1e34888
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0315.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0316.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0316.wav
new file mode 100644
index 0000000..b74abc9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0316.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0316.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0316.wavetable
new file mode 100644
index 0000000..7ff410a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0316.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0317.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0317.wav
new file mode 100644
index 0000000..2f6f4e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0317.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0317.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0317.wavetable
new file mode 100644
index 0000000..fe54622
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0317.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0318.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0318.wav
new file mode 100644
index 0000000..2fda9fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0318.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0318.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0318.wavetable
new file mode 100644
index 0000000..c46a3c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0318.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0319.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0319.wav
new file mode 100644
index 0000000..796442a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0319.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0319.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0319.wavetable
new file mode 100644
index 0000000..0d08f9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0319.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0320.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0320.wav
new file mode 100644
index 0000000..2bc49fc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0320.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0320.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0320.wavetable
new file mode 100644
index 0000000..c72287b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0320.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0321.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0321.wav
new file mode 100644
index 0000000..64c6929
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0321.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0321.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0321.wavetable
new file mode 100644
index 0000000..9471f61
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0321.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0322.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0322.wav
new file mode 100644
index 0000000..3a05b7e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0322.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0322.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0322.wavetable
new file mode 100644
index 0000000..7040a09
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0322.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0323.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0323.wav
new file mode 100644
index 0000000..e0b120e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0323.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0323.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0323.wavetable
new file mode 100644
index 0000000..e024ed1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0323.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0324.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0324.wav
new file mode 100644
index 0000000..cc7bd03
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0324.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0324.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0324.wavetable
new file mode 100644
index 0000000..a4c2096
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0324.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0325.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0325.wav
new file mode 100644
index 0000000..76c8872
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0325.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0325.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0325.wavetable
new file mode 100644
index 0000000..bf077a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0325.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0326.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0326.wav
new file mode 100644
index 0000000..2c08aaa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0326.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0326.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0326.wavetable
new file mode 100644
index 0000000..799a895
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0326.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0327.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0327.wav
new file mode 100644
index 0000000..c0a677b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0327.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0327.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0327.wavetable
new file mode 100644
index 0000000..1f4f780
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0327.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0328.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0328.wav
new file mode 100644
index 0000000..19d2ebb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0328.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0328.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0328.wavetable
new file mode 100644
index 0000000..0acc561
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0328.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0329.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0329.wav
new file mode 100644
index 0000000..7774b1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0329.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0329.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0329.wavetable
new file mode 100644
index 0000000..ef1ab54
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0329.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0330.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0330.wav
new file mode 100644
index 0000000..af08a05
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0330.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0330.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0330.wavetable
new file mode 100644
index 0000000..88b4ae5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0330.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0331.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0331.wav
new file mode 100644
index 0000000..644b20e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0331.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0331.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0331.wavetable
new file mode 100644
index 0000000..fd98538
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0331.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0332.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0332.wav
new file mode 100644
index 0000000..d8d4f9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0332.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0332.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0332.wavetable
new file mode 100644
index 0000000..b6d8169
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0332.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0333.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0333.wav
new file mode 100644
index 0000000..e372f63
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0333.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0333.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0333.wavetable
new file mode 100644
index 0000000..0223792
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0333.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0334.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0334.wav
new file mode 100644
index 0000000..822757e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0334.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0334.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0334.wavetable
new file mode 100644
index 0000000..9257fcb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0334.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0335.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0335.wav
new file mode 100644
index 0000000..f6ff578
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0335.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0335.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0335.wavetable
new file mode 100644
index 0000000..9a3458e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0335.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0336.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0336.wav
new file mode 100644
index 0000000..e67785b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0336.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0336.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0336.wavetable
new file mode 100644
index 0000000..df84599
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0336.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0337.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0337.wav
new file mode 100644
index 0000000..bcd1f55
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0337.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0337.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0337.wavetable
new file mode 100644
index 0000000..ae2ea4f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0337.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0338.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0338.wav
new file mode 100644
index 0000000..a37a88b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0338.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0338.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0338.wavetable
new file mode 100644
index 0000000..2b68a18
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0338.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0339.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0339.wav
new file mode 100644
index 0000000..5ac27cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0339.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0339.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0339.wavetable
new file mode 100644
index 0000000..730410a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0339.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0340.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0340.wav
new file mode 100644
index 0000000..f173462
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0340.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0340.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0340.wavetable
new file mode 100644
index 0000000..5ec9062
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0340.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0341.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0341.wav
new file mode 100644
index 0000000..df81dc5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0341.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0341.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0341.wavetable
new file mode 100644
index 0000000..3d99b1a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0341.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0342.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0342.wav
new file mode 100644
index 0000000..0c08801
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0342.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0342.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0342.wavetable
new file mode 100644
index 0000000..b6e6180
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0342.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0343.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0343.wav
new file mode 100644
index 0000000..9ce15ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0343.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0343.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0343.wavetable
new file mode 100644
index 0000000..4c2e557
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0343.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0344.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0344.wav
new file mode 100644
index 0000000..0495a5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0344.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0344.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0344.wavetable
new file mode 100644
index 0000000..8a17213
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0344.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0345.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0345.wav
new file mode 100644
index 0000000..32252d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0345.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0345.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0345.wavetable
new file mode 100644
index 0000000..ea7905f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0345.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0346.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0346.wav
new file mode 100644
index 0000000..9f2334b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0346.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0346.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0346.wavetable
new file mode 100644
index 0000000..3bcef6e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0346.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0347.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0347.wav
new file mode 100644
index 0000000..842cf4f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0347.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0347.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0347.wavetable
new file mode 100644
index 0000000..d0585cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0347.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0348.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0348.wav
new file mode 100644
index 0000000..8071a6e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0348.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0348.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0348.wavetable
new file mode 100644
index 0000000..ee42531
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0348.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0349.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0349.wav
new file mode 100644
index 0000000..dc0e227
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0349.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0349.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0349.wavetable
new file mode 100644
index 0000000..eeb35e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0349.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0350.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0350.wav
new file mode 100644
index 0000000..6679f8e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0350.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0350.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0350.wavetable
new file mode 100644
index 0000000..d8420c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0350.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0351.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0351.wav
new file mode 100644
index 0000000..b641c52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0351.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0351.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0351.wavetable
new file mode 100644
index 0000000..5477e99
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0351.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0352.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0352.wav
new file mode 100644
index 0000000..74d6205
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0352.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0352.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0352.wavetable
new file mode 100644
index 0000000..4d13b42
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0352.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0353.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0353.wav
new file mode 100644
index 0000000..7fea918
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0353.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0353.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0353.wavetable
new file mode 100644
index 0000000..dcfacfe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0353.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0354.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0354.wav
new file mode 100644
index 0000000..14ec62f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0354.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0354.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0354.wavetable
new file mode 100644
index 0000000..3c09c95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0354.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0355.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0355.wav
new file mode 100644
index 0000000..9911663
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0355.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0355.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0355.wavetable
new file mode 100644
index 0000000..1217287
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0355.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0356.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0356.wav
new file mode 100644
index 0000000..729fd08
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0356.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0356.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0356.wavetable
new file mode 100644
index 0000000..8925bc1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0356.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0357.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0357.wav
new file mode 100644
index 0000000..7ac897b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0357.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0357.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0357.wavetable
new file mode 100644
index 0000000..fde0090
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0357.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0358.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0358.wav
new file mode 100644
index 0000000..7181bf4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0358.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0358.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0358.wavetable
new file mode 100644
index 0000000..ae61088
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0358.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0359.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0359.wav
new file mode 100644
index 0000000..f30ef20
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0359.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0359.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0359.wavetable
new file mode 100644
index 0000000..d03e184
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0359.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0360.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0360.wav
new file mode 100644
index 0000000..2139643
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0360.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0360.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0360.wavetable
new file mode 100644
index 0000000..495ca21
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0360.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0361.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0361.wav
new file mode 100644
index 0000000..9b16ce7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0361.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0361.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0361.wavetable
new file mode 100644
index 0000000..b73272c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0361.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0362.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0362.wav
new file mode 100644
index 0000000..c471074
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0362.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0362.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0362.wavetable
new file mode 100644
index 0000000..6a0f7fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0362.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0363.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0363.wav
new file mode 100644
index 0000000..bcac85f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0363.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0363.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0363.wavetable
new file mode 100644
index 0000000..b462b78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0363.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0364.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0364.wav
new file mode 100644
index 0000000..6603488
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0364.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0364.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0364.wavetable
new file mode 100644
index 0000000..863d2b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0364.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0365.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0365.wav
new file mode 100644
index 0000000..dc74d42
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0365.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0365.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0365.wavetable
new file mode 100644
index 0000000..1acd795
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0365.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0366.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0366.wav
new file mode 100644
index 0000000..6b9565c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0366.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0366.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0366.wavetable
new file mode 100644
index 0000000..41be6d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0366.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0367.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0367.wav
new file mode 100644
index 0000000..bba5923
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0367.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0367.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0367.wavetable
new file mode 100644
index 0000000..c9a8dc0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0367.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0368.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0368.wav
new file mode 100644
index 0000000..43f1d95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0368.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0368.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0368.wavetable
new file mode 100644
index 0000000..37c0f1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0368.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0369.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0369.wav
new file mode 100644
index 0000000..fa9e7b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0369.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0369.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0369.wavetable
new file mode 100644
index 0000000..3917c03
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0369.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0370.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0370.wav
new file mode 100644
index 0000000..b88f0d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0370.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0370.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0370.wavetable
new file mode 100644
index 0000000..826cbfa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0370.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0371.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0371.wav
new file mode 100644
index 0000000..2d3fcd0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0371.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0371.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0371.wavetable
new file mode 100644
index 0000000..8f2ccbe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0371.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0372.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0372.wav
new file mode 100644
index 0000000..ea61e1a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0372.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0372.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0372.wavetable
new file mode 100644
index 0000000..61daf82
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0372.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0373.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0373.wav
new file mode 100644
index 0000000..8cd4d40
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0373.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0373.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0373.wavetable
new file mode 100644
index 0000000..29965a9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0373.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0374.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0374.wav
new file mode 100644
index 0000000..99e6a28
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0374.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0374.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0374.wavetable
new file mode 100644
index 0000000..14e313a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0374.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0375.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0375.wav
new file mode 100644
index 0000000..cda5145
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0375.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0375.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0375.wavetable
new file mode 100644
index 0000000..55d68f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0375.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0376.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0376.wav
new file mode 100644
index 0000000..813657c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0376.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0376.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0376.wavetable
new file mode 100644
index 0000000..bb09513
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0376.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0377.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0377.wav
new file mode 100644
index 0000000..5fcec43
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0377.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0377.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0377.wavetable
new file mode 100644
index 0000000..0147a30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0377.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0378.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0378.wav
new file mode 100644
index 0000000..01ee8c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0378.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0378.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0378.wavetable
new file mode 100644
index 0000000..5c3aaa3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0378.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0379.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0379.wav
new file mode 100644
index 0000000..5d8670a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0379.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0379.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0379.wavetable
new file mode 100644
index 0000000..f9165ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0379.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0380.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0380.wav
new file mode 100644
index 0000000..6b78f8c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0380.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0380.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0380.wavetable
new file mode 100644
index 0000000..1861e6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0380.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0381.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0381.wav
new file mode 100644
index 0000000..eaa4d78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0381.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0381.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0381.wavetable
new file mode 100644
index 0000000..0ea53ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0381.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0382.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0382.wav
new file mode 100644
index 0000000..7ff7a2a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0382.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0382.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0382.wavetable
new file mode 100644
index 0000000..e0eccdd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0382.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0383.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0383.wav
new file mode 100644
index 0000000..1c1f325
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0383.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0383.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0383.wavetable
new file mode 100644
index 0000000..8396962
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0383.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0384.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0384.wav
new file mode 100644
index 0000000..0b2170a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0384.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0384.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0384.wavetable
new file mode 100644
index 0000000..727558d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0384.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0385.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0385.wav
new file mode 100644
index 0000000..b0207d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0385.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0385.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0385.wavetable
new file mode 100644
index 0000000..4e3e6e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0385.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0386.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0386.wav
new file mode 100644
index 0000000..c51f9dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0386.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0386.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0386.wavetable
new file mode 100644
index 0000000..4434342
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0386.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0387.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0387.wav
new file mode 100644
index 0000000..0c9a65f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0387.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0387.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0387.wavetable
new file mode 100644
index 0000000..0b36cc6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0387.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0388.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0388.wav
new file mode 100644
index 0000000..f7d3394
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0388.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0388.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0388.wavetable
new file mode 100644
index 0000000..6ca73e3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0388.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0389.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0389.wav
new file mode 100644
index 0000000..a7dd9d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0389.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0389.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0389.wavetable
new file mode 100644
index 0000000..606ea49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0389.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0390.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0390.wav
new file mode 100644
index 0000000..51daccb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0390.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0390.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0390.wavetable
new file mode 100644
index 0000000..a607efe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0390.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0391.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0391.wav
new file mode 100644
index 0000000..0d5fa1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0391.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0391.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0391.wavetable
new file mode 100644
index 0000000..5eea6b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0391.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0392.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0392.wav
new file mode 100644
index 0000000..89e5cdc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0392.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0392.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0392.wavetable
new file mode 100644
index 0000000..2078004
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0392.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0393.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0393.wav
new file mode 100644
index 0000000..c8ac9ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0393.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0393.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0393.wavetable
new file mode 100644
index 0000000..3d0e593
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0393.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0394.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0394.wav
new file mode 100644
index 0000000..237120c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0394.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0394.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0394.wavetable
new file mode 100644
index 0000000..8d70379
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0394.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0395.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0395.wav
new file mode 100644
index 0000000..26553f8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0395.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0395.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0395.wavetable
new file mode 100644
index 0000000..a3067ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0395.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0396.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0396.wav
new file mode 100644
index 0000000..9570a1e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0396.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0396.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0396.wavetable
new file mode 100644
index 0000000..9fb1703
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0396.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0397.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0397.wav
new file mode 100644
index 0000000..4a7fecd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0397.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0397.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0397.wavetable
new file mode 100644
index 0000000..8708562
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0397.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0398.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0398.wav
new file mode 100644
index 0000000..393d97a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0398.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0398.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0398.wavetable
new file mode 100644
index 0000000..4e8871a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0398.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0399.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0399.wav
new file mode 100644
index 0000000..b5a7df0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0399.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0399.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0399.wavetable
new file mode 100644
index 0000000..3a03a82
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0399.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0400.wav b/etc/wavetables/AKWF/AKWF_0004/AKWF_0400.wav
new file mode 100644
index 0000000..3b8991e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0400.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AKWF_0400.wavetable b/etc/wavetables/AKWF/AKWF_0004/AKWF_0400.wavetable
new file mode 100644
index 0000000..94a63ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0004/AKWF_0400.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0004/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0004/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0004/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0401.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0401.wav
new file mode 100644
index 0000000..4d5c049
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0401.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0401.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0401.wavetable
new file mode 100644
index 0000000..3408ebf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0401.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0402.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0402.wav
new file mode 100644
index 0000000..192da5e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0402.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0402.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0402.wavetable
new file mode 100644
index 0000000..2ef7169
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0402.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0403.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0403.wav
new file mode 100644
index 0000000..5e8eb73
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0403.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0403.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0403.wavetable
new file mode 100644
index 0000000..b6854dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0403.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0404.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0404.wav
new file mode 100644
index 0000000..48ba73a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0404.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0404.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0404.wavetable
new file mode 100644
index 0000000..a9e9205
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0404.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0405.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0405.wav
new file mode 100644
index 0000000..5d2579d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0405.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0405.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0405.wavetable
new file mode 100644
index 0000000..ac14696
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0405.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0406.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0406.wav
new file mode 100644
index 0000000..c9fdc51
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0406.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0406.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0406.wavetable
new file mode 100644
index 0000000..488a246
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0406.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0407.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0407.wav
new file mode 100644
index 0000000..9556eee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0407.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0407.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0407.wavetable
new file mode 100644
index 0000000..f731746
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0407.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0408.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0408.wav
new file mode 100644
index 0000000..7bad91a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0408.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0408.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0408.wavetable
new file mode 100644
index 0000000..8e246ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0408.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0409.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0409.wav
new file mode 100644
index 0000000..28afeb7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0409.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0409.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0409.wavetable
new file mode 100644
index 0000000..614be62
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0409.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0410.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0410.wav
new file mode 100644
index 0000000..307d64e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0410.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0410.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0410.wavetable
new file mode 100644
index 0000000..3e2ab48
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0410.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0411.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0411.wav
new file mode 100644
index 0000000..93eab79
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0411.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0411.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0411.wavetable
new file mode 100644
index 0000000..5a39c27
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0411.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0412.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0412.wav
new file mode 100644
index 0000000..60d8455
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0412.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0412.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0412.wavetable
new file mode 100644
index 0000000..b9ca4ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0412.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0413.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0413.wav
new file mode 100644
index 0000000..0cfb29b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0413.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0413.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0413.wavetable
new file mode 100644
index 0000000..db23df7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0413.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0414.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0414.wav
new file mode 100644
index 0000000..170a13a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0414.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0414.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0414.wavetable
new file mode 100644
index 0000000..1d51fa6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0414.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0415.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0415.wav
new file mode 100644
index 0000000..cb0dc1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0415.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0415.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0415.wavetable
new file mode 100644
index 0000000..97bfcef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0415.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0416.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0416.wav
new file mode 100644
index 0000000..b1c59e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0416.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0416.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0416.wavetable
new file mode 100644
index 0000000..4596fff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0416.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0417.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0417.wav
new file mode 100644
index 0000000..9446b55
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0417.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0417.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0417.wavetable
new file mode 100644
index 0000000..462fc80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0417.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0418.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0418.wav
new file mode 100644
index 0000000..05b1155
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0418.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0418.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0418.wavetable
new file mode 100644
index 0000000..eafb429
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0418.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0419.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0419.wav
new file mode 100644
index 0000000..f50606d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0419.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0419.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0419.wavetable
new file mode 100644
index 0000000..91f179d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0419.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0420.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0420.wav
new file mode 100644
index 0000000..59c19e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0420.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0420.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0420.wavetable
new file mode 100644
index 0000000..fbaee52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0420.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0421.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0421.wav
new file mode 100644
index 0000000..84025e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0421.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0421.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0421.wavetable
new file mode 100644
index 0000000..55448bd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0421.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0422.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0422.wav
new file mode 100644
index 0000000..ff266ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0422.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0422.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0422.wavetable
new file mode 100644
index 0000000..a90edac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0422.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0423.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0423.wav
new file mode 100644
index 0000000..123d393
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0423.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0423.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0423.wavetable
new file mode 100644
index 0000000..ff24966
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0423.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0424.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0424.wav
new file mode 100644
index 0000000..707bef7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0424.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0424.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0424.wavetable
new file mode 100644
index 0000000..61e442f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0424.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0425.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0425.wav
new file mode 100644
index 0000000..fa96f71
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0425.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0425.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0425.wavetable
new file mode 100644
index 0000000..515199e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0425.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0426.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0426.wav
new file mode 100644
index 0000000..959602c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0426.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0426.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0426.wavetable
new file mode 100644
index 0000000..d2090e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0426.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0427.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0427.wav
new file mode 100644
index 0000000..9f5d424
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0427.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0427.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0427.wavetable
new file mode 100644
index 0000000..8ad2803
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0427.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0428.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0428.wav
new file mode 100644
index 0000000..d23d26a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0428.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0428.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0428.wavetable
new file mode 100644
index 0000000..7f6d00b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0428.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0429.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0429.wav
new file mode 100644
index 0000000..7ff705e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0429.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0429.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0429.wavetable
new file mode 100644
index 0000000..7870e20
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0429.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0430.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0430.wav
new file mode 100644
index 0000000..2947928
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0430.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0430.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0430.wavetable
new file mode 100644
index 0000000..966b68f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0430.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0431.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0431.wav
new file mode 100644
index 0000000..3da4e12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0431.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0431.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0431.wavetable
new file mode 100644
index 0000000..f40b642
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0431.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0432.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0432.wav
new file mode 100644
index 0000000..e30ae60
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0432.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0432.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0432.wavetable
new file mode 100644
index 0000000..72baa87
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0432.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0433.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0433.wav
new file mode 100644
index 0000000..f814dce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0433.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0433.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0433.wavetable
new file mode 100644
index 0000000..39190e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0433.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0434.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0434.wav
new file mode 100644
index 0000000..24a5317
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0434.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0434.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0434.wavetable
new file mode 100644
index 0000000..9055002
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0434.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0435.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0435.wav
new file mode 100644
index 0000000..ad9c565
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0435.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0435.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0435.wavetable
new file mode 100644
index 0000000..eada442
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0435.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0436.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0436.wav
new file mode 100644
index 0000000..49f137d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0436.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0436.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0436.wavetable
new file mode 100644
index 0000000..afe7511
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0436.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0437.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0437.wav
new file mode 100644
index 0000000..9d6b2ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0437.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0437.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0437.wavetable
new file mode 100644
index 0000000..dc59798
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0437.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0438.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0438.wav
new file mode 100644
index 0000000..8c409f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0438.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0438.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0438.wavetable
new file mode 100644
index 0000000..3be20a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0438.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0439.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0439.wav
new file mode 100644
index 0000000..22c6355
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0439.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0439.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0439.wavetable
new file mode 100644
index 0000000..29bd4fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0439.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0440.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0440.wav
new file mode 100644
index 0000000..db3f79e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0440.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0440.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0440.wavetable
new file mode 100644
index 0000000..07354f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0440.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0441.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0441.wav
new file mode 100644
index 0000000..8ebe3bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0441.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0441.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0441.wavetable
new file mode 100644
index 0000000..64abe62
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0441.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0442.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0442.wav
new file mode 100644
index 0000000..02ae43c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0442.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0442.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0442.wavetable
new file mode 100644
index 0000000..1a8f235
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0442.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0443.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0443.wav
new file mode 100644
index 0000000..f1f75c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0443.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0443.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0443.wavetable
new file mode 100644
index 0000000..e3776d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0443.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0444.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0444.wav
new file mode 100644
index 0000000..c0dfe6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0444.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0444.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0444.wavetable
new file mode 100644
index 0000000..39e57b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0444.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0445.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0445.wav
new file mode 100644
index 0000000..b5120ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0445.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0445.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0445.wavetable
new file mode 100644
index 0000000..b077294
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0445.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0446.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0446.wav
new file mode 100644
index 0000000..0487f4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0446.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0446.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0446.wavetable
new file mode 100644
index 0000000..83a23d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0446.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0447.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0447.wav
new file mode 100644
index 0000000..3ecc1c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0447.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0447.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0447.wavetable
new file mode 100644
index 0000000..e470686
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0447.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0448.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0448.wav
new file mode 100644
index 0000000..a2318a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0448.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0448.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0448.wavetable
new file mode 100644
index 0000000..99950cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0448.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0449.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0449.wav
new file mode 100644
index 0000000..ce046a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0449.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0449.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0449.wavetable
new file mode 100644
index 0000000..e3703e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0449.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0450.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0450.wav
new file mode 100644
index 0000000..797d9d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0450.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0450.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0450.wavetable
new file mode 100644
index 0000000..54eb547
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0450.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0451.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0451.wav
new file mode 100644
index 0000000..842dc11
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0451.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0451.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0451.wavetable
new file mode 100644
index 0000000..1c3b9e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0451.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0452.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0452.wav
new file mode 100644
index 0000000..6844c34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0452.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0452.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0452.wavetable
new file mode 100644
index 0000000..91821f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0452.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0453.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0453.wav
new file mode 100644
index 0000000..53537c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0453.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0453.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0453.wavetable
new file mode 100644
index 0000000..ac9f1db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0453.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0454.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0454.wav
new file mode 100644
index 0000000..3b35168
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0454.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0454.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0454.wavetable
new file mode 100644
index 0000000..7025f0c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0454.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0455.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0455.wav
new file mode 100644
index 0000000..8b4eca7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0455.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0455.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0455.wavetable
new file mode 100644
index 0000000..33e9442
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0455.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0456.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0456.wav
new file mode 100644
index 0000000..2429b8d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0456.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0456.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0456.wavetable
new file mode 100644
index 0000000..6504166
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0456.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0457.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0457.wav
new file mode 100644
index 0000000..9fb9017
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0457.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0457.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0457.wavetable
new file mode 100644
index 0000000..b3b722c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0457.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0458.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0458.wav
new file mode 100644
index 0000000..ec02700
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0458.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0458.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0458.wavetable
new file mode 100644
index 0000000..cad5ba5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0458.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0459.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0459.wav
new file mode 100644
index 0000000..5b15c60
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0459.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0459.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0459.wavetable
new file mode 100644
index 0000000..d4b0df3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0459.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0460.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0460.wav
new file mode 100644
index 0000000..6bcbab2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0460.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0460.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0460.wavetable
new file mode 100644
index 0000000..fc46de3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0460.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0461.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0461.wav
new file mode 100644
index 0000000..19102ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0461.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0461.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0461.wavetable
new file mode 100644
index 0000000..177673c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0461.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0462.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0462.wav
new file mode 100644
index 0000000..fbbe283
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0462.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0462.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0462.wavetable
new file mode 100644
index 0000000..562b948
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0462.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0463.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0463.wav
new file mode 100644
index 0000000..1018ef6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0463.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0463.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0463.wavetable
new file mode 100644
index 0000000..7e030c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0463.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0464.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0464.wav
new file mode 100644
index 0000000..2007b7e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0464.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0464.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0464.wavetable
new file mode 100644
index 0000000..d24d2a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0464.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0465.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0465.wav
new file mode 100644
index 0000000..448bd0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0465.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0465.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0465.wavetable
new file mode 100644
index 0000000..e82a2c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0465.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0466.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0466.wav
new file mode 100644
index 0000000..476674f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0466.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0466.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0466.wavetable
new file mode 100644
index 0000000..905a037
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0466.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0467.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0467.wav
new file mode 100644
index 0000000..6b34173
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0467.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0467.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0467.wavetable
new file mode 100644
index 0000000..c280df3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0467.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0468.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0468.wav
new file mode 100644
index 0000000..6783251
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0468.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0468.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0468.wavetable
new file mode 100644
index 0000000..a7de5ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0468.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0469.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0469.wav
new file mode 100644
index 0000000..88625cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0469.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0469.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0469.wavetable
new file mode 100644
index 0000000..872a0f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0469.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0470.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0470.wav
new file mode 100644
index 0000000..7b06a42
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0470.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0470.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0470.wavetable
new file mode 100644
index 0000000..1c02081
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0470.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0471.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0471.wav
new file mode 100644
index 0000000..3b190c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0471.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0471.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0471.wavetable
new file mode 100644
index 0000000..7d1e022
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0471.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0472.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0472.wav
new file mode 100644
index 0000000..7528c91
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0472.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0472.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0472.wavetable
new file mode 100644
index 0000000..c79d8de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0472.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0473.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0473.wav
new file mode 100644
index 0000000..6258e4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0473.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0473.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0473.wavetable
new file mode 100644
index 0000000..65d3e5e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0473.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0474.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0474.wav
new file mode 100644
index 0000000..f84b301
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0474.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0474.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0474.wavetable
new file mode 100644
index 0000000..f626b61
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0474.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0475.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0475.wav
new file mode 100644
index 0000000..f33df44
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0475.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0475.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0475.wavetable
new file mode 100644
index 0000000..6e73729
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0475.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0476.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0476.wav
new file mode 100644
index 0000000..5b0c264
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0476.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0476.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0476.wavetable
new file mode 100644
index 0000000..ef0820b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0476.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0477.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0477.wav
new file mode 100644
index 0000000..8b59fbd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0477.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0477.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0477.wavetable
new file mode 100644
index 0000000..ccd3380
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0477.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0478.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0478.wav
new file mode 100644
index 0000000..6ef6093
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0478.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0478.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0478.wavetable
new file mode 100644
index 0000000..1681353
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0478.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0479.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0479.wav
new file mode 100644
index 0000000..f210e74
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0479.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0479.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0479.wavetable
new file mode 100644
index 0000000..0681ae6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0479.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0480.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0480.wav
new file mode 100644
index 0000000..bb2fbaa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0480.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0480.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0480.wavetable
new file mode 100644
index 0000000..d98858e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0480.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0481.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0481.wav
new file mode 100644
index 0000000..ee6bf15
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0481.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0481.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0481.wavetable
new file mode 100644
index 0000000..45232bd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0481.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0482.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0482.wav
new file mode 100644
index 0000000..ada9cfa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0482.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0482.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0482.wavetable
new file mode 100644
index 0000000..93024e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0482.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0483.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0483.wav
new file mode 100644
index 0000000..22f4376
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0483.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0483.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0483.wavetable
new file mode 100644
index 0000000..c85d701
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0483.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0484.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0484.wav
new file mode 100644
index 0000000..7452ece
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0484.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0484.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0484.wavetable
new file mode 100644
index 0000000..e9a07d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0484.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0485.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0485.wav
new file mode 100644
index 0000000..1ebe895
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0485.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0485.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0485.wavetable
new file mode 100644
index 0000000..70e8609
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0485.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0486.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0486.wav
new file mode 100644
index 0000000..e51120d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0486.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0486.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0486.wavetable
new file mode 100644
index 0000000..9a9488f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0486.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0487.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0487.wav
new file mode 100644
index 0000000..cda07f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0487.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0487.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0487.wavetable
new file mode 100644
index 0000000..9362e77
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0487.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0488.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0488.wav
new file mode 100644
index 0000000..afcfbde
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0488.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0488.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0488.wavetable
new file mode 100644
index 0000000..b77f1e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0488.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0489.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0489.wav
new file mode 100644
index 0000000..32608f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0489.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0489.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0489.wavetable
new file mode 100644
index 0000000..2b4ad9b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0489.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0490.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0490.wav
new file mode 100644
index 0000000..0f2b0d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0490.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0490.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0490.wavetable
new file mode 100644
index 0000000..78cfa7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0490.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0491.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0491.wav
new file mode 100644
index 0000000..0d6d811
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0491.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0491.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0491.wavetable
new file mode 100644
index 0000000..222a6e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0491.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0492.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0492.wav
new file mode 100644
index 0000000..1f5cf2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0492.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0492.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0492.wavetable
new file mode 100644
index 0000000..1cc7e02
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0492.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0493.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0493.wav
new file mode 100644
index 0000000..20a3d7a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0493.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0493.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0493.wavetable
new file mode 100644
index 0000000..d058e94
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0493.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0494.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0494.wav
new file mode 100644
index 0000000..f678849
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0494.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0494.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0494.wavetable
new file mode 100644
index 0000000..c47eb19
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0494.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0495.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0495.wav
new file mode 100644
index 0000000..0ca47f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0495.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0495.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0495.wavetable
new file mode 100644
index 0000000..5517d1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0495.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0496.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0496.wav
new file mode 100644
index 0000000..d4aec48
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0496.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0496.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0496.wavetable
new file mode 100644
index 0000000..f6e47a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0496.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0497.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0497.wav
new file mode 100644
index 0000000..8d9b133
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0497.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0497.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0497.wavetable
new file mode 100644
index 0000000..ad5de42
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0497.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0498.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0498.wav
new file mode 100644
index 0000000..4d0f286
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0498.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0498.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0498.wavetable
new file mode 100644
index 0000000..8ede11b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0498.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0499.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0499.wav
new file mode 100644
index 0000000..9410409
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0499.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0499.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0499.wavetable
new file mode 100644
index 0000000..5c5ed8d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0499.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0500.wav b/etc/wavetables/AKWF/AKWF_0005/AKWF_0500.wav
new file mode 100644
index 0000000..1e30442
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0500.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AKWF_0500.wavetable b/etc/wavetables/AKWF/AKWF_0005/AKWF_0500.wavetable
new file mode 100644
index 0000000..0eec9ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0005/AKWF_0500.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0005/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0005/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0005/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0501.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0501.wav
new file mode 100644
index 0000000..fa78aa8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0501.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0501.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0501.wavetable
new file mode 100644
index 0000000..c63b214
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0501.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0502.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0502.wav
new file mode 100644
index 0000000..2d354ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0502.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0502.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0502.wavetable
new file mode 100644
index 0000000..aceb81c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0502.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0503.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0503.wav
new file mode 100644
index 0000000..cbb4cb0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0503.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0503.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0503.wavetable
new file mode 100644
index 0000000..4ed5319
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0503.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0504.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0504.wav
new file mode 100644
index 0000000..040ef63
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0504.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0504.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0504.wavetable
new file mode 100644
index 0000000..b406e33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0504.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0505.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0505.wav
new file mode 100644
index 0000000..b43bc53
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0505.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0505.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0505.wavetable
new file mode 100644
index 0000000..07a8b84
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0505.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0506.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0506.wav
new file mode 100644
index 0000000..b09a2df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0506.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0506.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0506.wavetable
new file mode 100644
index 0000000..763320d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0506.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0507.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0507.wav
new file mode 100644
index 0000000..89dddcd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0507.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0507.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0507.wavetable
new file mode 100644
index 0000000..b0c1a2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0507.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0508.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0508.wav
new file mode 100644
index 0000000..13b9b1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0508.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0508.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0508.wavetable
new file mode 100644
index 0000000..1682b50
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0508.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0509.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0509.wav
new file mode 100644
index 0000000..80e3235
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0509.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0509.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0509.wavetable
new file mode 100644
index 0000000..08e10e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0509.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0510.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0510.wav
new file mode 100644
index 0000000..9aac4de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0510.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0510.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0510.wavetable
new file mode 100644
index 0000000..6fe4597
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0510.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0511.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0511.wav
new file mode 100644
index 0000000..9e08fcf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0511.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0511.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0511.wavetable
new file mode 100644
index 0000000..df49d28
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0511.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0512.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0512.wav
new file mode 100644
index 0000000..d277f1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0512.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0512.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0512.wavetable
new file mode 100644
index 0000000..0e1d29e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0512.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0513.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0513.wav
new file mode 100644
index 0000000..fab2891
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0513.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0513.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0513.wavetable
new file mode 100644
index 0000000..2f1d21e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0513.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0514.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0514.wav
new file mode 100644
index 0000000..4275591
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0514.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0514.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0514.wavetable
new file mode 100644
index 0000000..e0ae981
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0514.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0515.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0515.wav
new file mode 100644
index 0000000..0dfff3d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0515.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0515.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0515.wavetable
new file mode 100644
index 0000000..4f5d918
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0515.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0516.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0516.wav
new file mode 100644
index 0000000..b5264e3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0516.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0516.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0516.wavetable
new file mode 100644
index 0000000..1bb15dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0516.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0517.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0517.wav
new file mode 100644
index 0000000..30a2c4e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0517.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0517.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0517.wavetable
new file mode 100644
index 0000000..a521252
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0517.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0518.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0518.wav
new file mode 100644
index 0000000..17d908f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0518.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0518.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0518.wavetable
new file mode 100644
index 0000000..1150e1f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0518.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0519.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0519.wav
new file mode 100644
index 0000000..8d14331
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0519.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0519.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0519.wavetable
new file mode 100644
index 0000000..de5f282
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0519.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0520.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0520.wav
new file mode 100644
index 0000000..aeae22b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0520.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0520.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0520.wavetable
new file mode 100644
index 0000000..3b15dc8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0520.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0521.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0521.wav
new file mode 100644
index 0000000..1f3eae9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0521.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0521.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0521.wavetable
new file mode 100644
index 0000000..c4cd03b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0521.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0522.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0522.wav
new file mode 100644
index 0000000..5bbea69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0522.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0522.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0522.wavetable
new file mode 100644
index 0000000..061c3aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0522.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0523.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0523.wav
new file mode 100644
index 0000000..7ea1483
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0523.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0523.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0523.wavetable
new file mode 100644
index 0000000..0cf45e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0523.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0524.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0524.wav
new file mode 100644
index 0000000..68eaa84
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0524.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0524.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0524.wavetable
new file mode 100644
index 0000000..0af7277
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0524.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0525.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0525.wav
new file mode 100644
index 0000000..06051fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0525.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0525.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0525.wavetable
new file mode 100644
index 0000000..bc5b8e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0525.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0526.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0526.wav
new file mode 100644
index 0000000..15e300b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0526.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0526.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0526.wavetable
new file mode 100644
index 0000000..1a92832
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0526.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0527.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0527.wav
new file mode 100644
index 0000000..cec7c88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0527.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0527.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0527.wavetable
new file mode 100644
index 0000000..7f5cd0e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0527.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0528.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0528.wav
new file mode 100644
index 0000000..a4cb6bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0528.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0528.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0528.wavetable
new file mode 100644
index 0000000..fa83912
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0528.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0529.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0529.wav
new file mode 100644
index 0000000..6657431
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0529.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0529.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0529.wavetable
new file mode 100644
index 0000000..3d049e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0529.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0530.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0530.wav
new file mode 100644
index 0000000..6e9fcee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0530.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0530.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0530.wavetable
new file mode 100644
index 0000000..e17fc47
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0530.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0531.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0531.wav
new file mode 100644
index 0000000..143c5ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0531.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0531.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0531.wavetable
new file mode 100644
index 0000000..ba60f00
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0531.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0532.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0532.wav
new file mode 100644
index 0000000..9f3a732
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0532.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0532.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0532.wavetable
new file mode 100644
index 0000000..81c0319
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0532.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0533.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0533.wav
new file mode 100644
index 0000000..5d7bf97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0533.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0533.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0533.wavetable
new file mode 100644
index 0000000..b6c7a72
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0533.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0534.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0534.wav
new file mode 100644
index 0000000..e31a551
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0534.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0534.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0534.wavetable
new file mode 100644
index 0000000..c84dd8d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0534.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0535.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0535.wav
new file mode 100644
index 0000000..c5495e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0535.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0535.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0535.wavetable
new file mode 100644
index 0000000..eb124ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0535.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0536.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0536.wav
new file mode 100644
index 0000000..775732a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0536.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0536.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0536.wavetable
new file mode 100644
index 0000000..bcebc80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0536.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0537.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0537.wav
new file mode 100644
index 0000000..b25a6f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0537.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0537.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0537.wavetable
new file mode 100644
index 0000000..a0981c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0537.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0538.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0538.wav
new file mode 100644
index 0000000..c1b0559
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0538.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0538.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0538.wavetable
new file mode 100644
index 0000000..9fdb0e3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0538.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0539.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0539.wav
new file mode 100644
index 0000000..1d1cd17
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0539.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0539.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0539.wavetable
new file mode 100644
index 0000000..7eb78dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0539.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0540.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0540.wav
new file mode 100644
index 0000000..9841259
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0540.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0540.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0540.wavetable
new file mode 100644
index 0000000..83fea65
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0540.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0541.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0541.wav
new file mode 100644
index 0000000..f1760b7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0541.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0541.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0541.wavetable
new file mode 100644
index 0000000..1a63789
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0541.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0542.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0542.wav
new file mode 100644
index 0000000..b83cc34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0542.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0542.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0542.wavetable
new file mode 100644
index 0000000..1428bef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0542.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0543.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0543.wav
new file mode 100644
index 0000000..eaee792
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0543.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0543.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0543.wavetable
new file mode 100644
index 0000000..6075c84
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0543.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0544.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0544.wav
new file mode 100644
index 0000000..b2c9b0b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0544.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0544.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0544.wavetable
new file mode 100644
index 0000000..e505970
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0544.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0545.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0545.wav
new file mode 100644
index 0000000..9de1c69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0545.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0545.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0545.wavetable
new file mode 100644
index 0000000..a487a97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0545.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0546.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0546.wav
new file mode 100644
index 0000000..91578ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0546.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0546.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0546.wavetable
new file mode 100644
index 0000000..15d09d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0546.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0547.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0547.wav
new file mode 100644
index 0000000..342555e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0547.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0547.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0547.wavetable
new file mode 100644
index 0000000..bca2ea8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0547.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0548.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0548.wav
new file mode 100644
index 0000000..8945e76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0548.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0548.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0548.wavetable
new file mode 100644
index 0000000..2fb2247
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0548.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0549.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0549.wav
new file mode 100644
index 0000000..3d1542e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0549.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0549.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0549.wavetable
new file mode 100644
index 0000000..4231f95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0549.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0550.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0550.wav
new file mode 100644
index 0000000..984a413
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0550.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0550.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0550.wavetable
new file mode 100644
index 0000000..ae90cb4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0550.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0551.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0551.wav
new file mode 100644
index 0000000..92c95ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0551.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0551.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0551.wavetable
new file mode 100644
index 0000000..d761682
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0551.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0552.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0552.wav
new file mode 100644
index 0000000..5519328
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0552.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0552.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0552.wavetable
new file mode 100644
index 0000000..2b64290
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0552.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0553.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0553.wav
new file mode 100644
index 0000000..444879c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0553.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0553.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0553.wavetable
new file mode 100644
index 0000000..eca52a9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0553.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0554.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0554.wav
new file mode 100644
index 0000000..71a6d0c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0554.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0554.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0554.wavetable
new file mode 100644
index 0000000..42b8846
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0554.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0555.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0555.wav
new file mode 100644
index 0000000..6754bf9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0555.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0555.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0555.wavetable
new file mode 100644
index 0000000..8e7cd37
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0555.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0556.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0556.wav
new file mode 100644
index 0000000..4640a7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0556.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0556.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0556.wavetable
new file mode 100644
index 0000000..4c8ca82
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0556.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0557.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0557.wav
new file mode 100644
index 0000000..843fa0e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0557.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0557.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0557.wavetable
new file mode 100644
index 0000000..1081671
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0557.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0558.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0558.wav
new file mode 100644
index 0000000..6308a8a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0558.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0558.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0558.wavetable
new file mode 100644
index 0000000..8dd8393
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0558.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0559.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0559.wav
new file mode 100644
index 0000000..3692c62
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0559.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0559.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0559.wavetable
new file mode 100644
index 0000000..f512c1f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0559.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0560.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0560.wav
new file mode 100644
index 0000000..839f464
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0560.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0560.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0560.wavetable
new file mode 100644
index 0000000..1d00f29
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0560.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0561.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0561.wav
new file mode 100644
index 0000000..d72ba1e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0561.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0561.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0561.wavetable
new file mode 100644
index 0000000..cf5447f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0561.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0562.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0562.wav
new file mode 100644
index 0000000..ce650db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0562.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0562.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0562.wavetable
new file mode 100644
index 0000000..bc2feda
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0562.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0563.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0563.wav
new file mode 100644
index 0000000..c61bb7d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0563.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0563.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0563.wavetable
new file mode 100644
index 0000000..a8f8ac8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0563.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0564.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0564.wav
new file mode 100644
index 0000000..80bbca9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0564.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0564.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0564.wavetable
new file mode 100644
index 0000000..61d4d70
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0564.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0565.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0565.wav
new file mode 100644
index 0000000..577a76b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0565.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0565.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0565.wavetable
new file mode 100644
index 0000000..d7aa311
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0565.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0566.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0566.wav
new file mode 100644
index 0000000..2f0f886
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0566.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0566.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0566.wavetable
new file mode 100644
index 0000000..8c94ba3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0566.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0567.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0567.wav
new file mode 100644
index 0000000..3a8e11b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0567.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0567.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0567.wavetable
new file mode 100644
index 0000000..090aca4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0567.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0568.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0568.wav
new file mode 100644
index 0000000..20d89ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0568.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0568.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0568.wavetable
new file mode 100644
index 0000000..3b137cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0568.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0569.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0569.wav
new file mode 100644
index 0000000..aa28209
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0569.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0569.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0569.wavetable
new file mode 100644
index 0000000..3dc14d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0569.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0570.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0570.wav
new file mode 100644
index 0000000..1e36b80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0570.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0570.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0570.wavetable
new file mode 100644
index 0000000..a7756d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0570.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0571.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0571.wav
new file mode 100644
index 0000000..b7e4a77
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0571.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0571.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0571.wavetable
new file mode 100644
index 0000000..36a2af2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0571.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0572.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0572.wav
new file mode 100644
index 0000000..7f02dbe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0572.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0572.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0572.wavetable
new file mode 100644
index 0000000..32a2526
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0572.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0573.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0573.wav
new file mode 100644
index 0000000..ee7ceb3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0573.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0573.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0573.wavetable
new file mode 100644
index 0000000..578cbdd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0573.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0574.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0574.wav
new file mode 100644
index 0000000..9029ab6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0574.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0574.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0574.wavetable
new file mode 100644
index 0000000..d8b1026
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0574.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0575.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0575.wav
new file mode 100644
index 0000000..d9b64e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0575.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0575.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0575.wavetable
new file mode 100644
index 0000000..995d1fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0575.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0576.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0576.wav
new file mode 100644
index 0000000..d7a6549
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0576.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0576.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0576.wavetable
new file mode 100644
index 0000000..07a5b2f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0576.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0577.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0577.wav
new file mode 100644
index 0000000..3bebd54
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0577.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0577.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0577.wavetable
new file mode 100644
index 0000000..ac2df24
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0577.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0578.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0578.wav
new file mode 100644
index 0000000..292abb3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0578.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0578.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0578.wavetable
new file mode 100644
index 0000000..9348041
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0578.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0579.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0579.wav
new file mode 100644
index 0000000..54e6237
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0579.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0579.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0579.wavetable
new file mode 100644
index 0000000..3b5cf1e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0579.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0580.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0580.wav
new file mode 100644
index 0000000..6586ab0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0580.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0580.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0580.wavetable
new file mode 100644
index 0000000..a2fcd5d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0580.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0581.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0581.wav
new file mode 100644
index 0000000..9e792b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0581.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0581.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0581.wavetable
new file mode 100644
index 0000000..f1f1598
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0581.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0582.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0582.wav
new file mode 100644
index 0000000..6976fa6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0582.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0582.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0582.wavetable
new file mode 100644
index 0000000..46f025c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0582.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0583.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0583.wav
new file mode 100644
index 0000000..c912318
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0583.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0583.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0583.wavetable
new file mode 100644
index 0000000..5768150
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0583.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0584.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0584.wav
new file mode 100644
index 0000000..6c1c45e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0584.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0584.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0584.wavetable
new file mode 100644
index 0000000..85f3087
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0584.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0585.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0585.wav
new file mode 100644
index 0000000..5c299a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0585.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0585.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0585.wavetable
new file mode 100644
index 0000000..f7c7394
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0585.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0586.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0586.wav
new file mode 100644
index 0000000..12a0198
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0586.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0586.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0586.wavetable
new file mode 100644
index 0000000..27e9e51
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0586.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0587.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0587.wav
new file mode 100644
index 0000000..95c9673
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0587.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0587.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0587.wavetable
new file mode 100644
index 0000000..a3e658c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0587.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0588.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0588.wav
new file mode 100644
index 0000000..1b5abe7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0588.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0588.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0588.wavetable
new file mode 100644
index 0000000..66f4d90
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0588.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0589.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0589.wav
new file mode 100644
index 0000000..4ab02a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0589.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0589.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0589.wavetable
new file mode 100644
index 0000000..b36af3a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0589.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0590.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0590.wav
new file mode 100644
index 0000000..c00afd1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0590.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0590.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0590.wavetable
new file mode 100644
index 0000000..d44f197
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0590.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0591.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0591.wav
new file mode 100644
index 0000000..e1af950
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0591.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0591.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0591.wavetable
new file mode 100644
index 0000000..6d4dcdc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0591.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0592.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0592.wav
new file mode 100644
index 0000000..a6dade6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0592.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0592.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0592.wavetable
new file mode 100644
index 0000000..120a937
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0592.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0593.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0593.wav
new file mode 100644
index 0000000..2347352
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0593.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0593.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0593.wavetable
new file mode 100644
index 0000000..87bdd34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0593.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0594.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0594.wav
new file mode 100644
index 0000000..e180e6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0594.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0594.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0594.wavetable
new file mode 100644
index 0000000..a91e86b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0594.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0595.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0595.wav
new file mode 100644
index 0000000..57fd430
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0595.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0595.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0595.wavetable
new file mode 100644
index 0000000..a438b7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0595.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0596.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0596.wav
new file mode 100644
index 0000000..272281d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0596.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0596.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0596.wavetable
new file mode 100644
index 0000000..a0bc1a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0596.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0597.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0597.wav
new file mode 100644
index 0000000..e07c48b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0597.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0597.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0597.wavetable
new file mode 100644
index 0000000..8b6a1c8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0597.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0598.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0598.wav
new file mode 100644
index 0000000..78dbaf6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0598.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0598.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0598.wavetable
new file mode 100644
index 0000000..787f0dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0598.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0599.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0599.wav
new file mode 100644
index 0000000..b5a4dc4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0599.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0599.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0599.wavetable
new file mode 100644
index 0000000..a4aa46d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0599.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0600.wav b/etc/wavetables/AKWF/AKWF_0006/AKWF_0600.wav
new file mode 100644
index 0000000..9324eb3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0600.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AKWF_0600.wavetable b/etc/wavetables/AKWF/AKWF_0006/AKWF_0600.wavetable
new file mode 100644
index 0000000..698a656
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0006/AKWF_0600.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0006/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0006/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0006/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0601.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0601.wav
new file mode 100644
index 0000000..7504343
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0601.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0601.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0601.wavetable
new file mode 100644
index 0000000..afe0e35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0601.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0602.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0602.wav
new file mode 100644
index 0000000..ccc0ebf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0602.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0602.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0602.wavetable
new file mode 100644
index 0000000..242e252
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0602.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0603.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0603.wav
new file mode 100644
index 0000000..4a53d4d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0603.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0603.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0603.wavetable
new file mode 100644
index 0000000..7c8c989
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0603.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0604.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0604.wav
new file mode 100644
index 0000000..4c55560
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0604.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0604.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0604.wavetable
new file mode 100644
index 0000000..87bc8b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0604.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0605.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0605.wav
new file mode 100644
index 0000000..4ab84a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0605.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0605.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0605.wavetable
new file mode 100644
index 0000000..daaf451
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0605.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0606.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0606.wav
new file mode 100644
index 0000000..f55eeec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0606.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0606.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0606.wavetable
new file mode 100644
index 0000000..094a61d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0606.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0607.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0607.wav
new file mode 100644
index 0000000..17f76bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0607.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0607.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0607.wavetable
new file mode 100644
index 0000000..f14c3a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0607.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0608.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0608.wav
new file mode 100644
index 0000000..cfcb327
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0608.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0608.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0608.wavetable
new file mode 100644
index 0000000..349f90c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0608.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0609.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0609.wav
new file mode 100644
index 0000000..ee85c27
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0609.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0609.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0609.wavetable
new file mode 100644
index 0000000..bc02c48
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0609.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0610.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0610.wav
new file mode 100644
index 0000000..9ac102d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0610.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0610.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0610.wavetable
new file mode 100644
index 0000000..30b32c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0610.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0611.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0611.wav
new file mode 100644
index 0000000..6832860
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0611.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0611.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0611.wavetable
new file mode 100644
index 0000000..6d34a7d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0611.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0612.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0612.wav
new file mode 100644
index 0000000..ea75dfd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0612.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0612.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0612.wavetable
new file mode 100644
index 0000000..763abfd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0612.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0613.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0613.wav
new file mode 100644
index 0000000..172bbf6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0613.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0613.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0613.wavetable
new file mode 100644
index 0000000..ec41783
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0613.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0614.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0614.wav
new file mode 100644
index 0000000..f57fb71
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0614.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0614.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0614.wavetable
new file mode 100644
index 0000000..d4bd104
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0614.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0615.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0615.wav
new file mode 100644
index 0000000..6e4ac39
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0615.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0615.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0615.wavetable
new file mode 100644
index 0000000..a4c394f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0615.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0616.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0616.wav
new file mode 100644
index 0000000..51485f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0616.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0616.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0616.wavetable
new file mode 100644
index 0000000..83f8d5a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0616.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0617.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0617.wav
new file mode 100644
index 0000000..5f3240b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0617.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0617.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0617.wavetable
new file mode 100644
index 0000000..fcb381b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0617.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0618.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0618.wav
new file mode 100644
index 0000000..6c05324
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0618.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0618.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0618.wavetable
new file mode 100644
index 0000000..ba07c44
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0618.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0619.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0619.wav
new file mode 100644
index 0000000..de62bf3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0619.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0619.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0619.wavetable
new file mode 100644
index 0000000..00577be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0619.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0620.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0620.wav
new file mode 100644
index 0000000..4072896
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0620.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0620.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0620.wavetable
new file mode 100644
index 0000000..08ddd84
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0620.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0621.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0621.wav
new file mode 100644
index 0000000..902f1ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0621.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0621.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0621.wavetable
new file mode 100644
index 0000000..4d3c2b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0621.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0622.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0622.wav
new file mode 100644
index 0000000..12846a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0622.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0622.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0622.wavetable
new file mode 100644
index 0000000..9d6166a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0622.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0623.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0623.wav
new file mode 100644
index 0000000..0d36642
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0623.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0623.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0623.wavetable
new file mode 100644
index 0000000..081a6a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0623.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0624.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0624.wav
new file mode 100644
index 0000000..e07bf89
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0624.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0624.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0624.wavetable
new file mode 100644
index 0000000..bbc8e6a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0624.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0625.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0625.wav
new file mode 100644
index 0000000..82aeed8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0625.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0625.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0625.wavetable
new file mode 100644
index 0000000..c283706
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0625.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0626.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0626.wav
new file mode 100644
index 0000000..21e60e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0626.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0626.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0626.wavetable
new file mode 100644
index 0000000..abd209f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0626.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0627.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0627.wav
new file mode 100644
index 0000000..c7da172
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0627.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0627.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0627.wavetable
new file mode 100644
index 0000000..6ab6115
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0627.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0628.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0628.wav
new file mode 100644
index 0000000..1510f3f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0628.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0628.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0628.wavetable
new file mode 100644
index 0000000..2c15f3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0628.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0629.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0629.wav
new file mode 100644
index 0000000..585b662
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0629.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0629.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0629.wavetable
new file mode 100644
index 0000000..2464fa9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0629.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0630.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0630.wav
new file mode 100644
index 0000000..74dd24b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0630.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0630.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0630.wavetable
new file mode 100644
index 0000000..1ba2f3e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0630.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0631.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0631.wav
new file mode 100644
index 0000000..71dfba4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0631.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0631.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0631.wavetable
new file mode 100644
index 0000000..475b23f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0631.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0632.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0632.wav
new file mode 100644
index 0000000..0537f76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0632.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0632.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0632.wavetable
new file mode 100644
index 0000000..34e714f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0632.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0633.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0633.wav
new file mode 100644
index 0000000..4fae731
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0633.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0633.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0633.wavetable
new file mode 100644
index 0000000..200d36d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0633.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0634.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0634.wav
new file mode 100644
index 0000000..56d3a5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0634.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0634.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0634.wavetable
new file mode 100644
index 0000000..0f53ae2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0634.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0635.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0635.wav
new file mode 100644
index 0000000..d26fc8e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0635.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0635.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0635.wavetable
new file mode 100644
index 0000000..42ca3ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0635.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0636.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0636.wav
new file mode 100644
index 0000000..2c8869a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0636.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0636.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0636.wavetable
new file mode 100644
index 0000000..5988b47
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0636.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0637.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0637.wav
new file mode 100644
index 0000000..09b6cba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0637.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0637.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0637.wavetable
new file mode 100644
index 0000000..e10e19d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0637.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0638.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0638.wav
new file mode 100644
index 0000000..950da36
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0638.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0638.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0638.wavetable
new file mode 100644
index 0000000..f143af3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0638.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0639.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0639.wav
new file mode 100644
index 0000000..377df3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0639.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0639.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0639.wavetable
new file mode 100644
index 0000000..a4a18d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0639.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0640.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0640.wav
new file mode 100644
index 0000000..7efd3b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0640.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0640.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0640.wavetable
new file mode 100644
index 0000000..a22143e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0640.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0641.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0641.wav
new file mode 100644
index 0000000..e53aded
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0641.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0641.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0641.wavetable
new file mode 100644
index 0000000..e115ed4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0641.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0642.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0642.wav
new file mode 100644
index 0000000..7dba30a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0642.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0642.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0642.wavetable
new file mode 100644
index 0000000..2f6b184
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0642.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0643.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0643.wav
new file mode 100644
index 0000000..14ffffe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0643.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0643.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0643.wavetable
new file mode 100644
index 0000000..e1e5444
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0643.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0644.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0644.wav
new file mode 100644
index 0000000..b91b2c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0644.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0644.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0644.wavetable
new file mode 100644
index 0000000..9c5a17b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0644.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0645.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0645.wav
new file mode 100644
index 0000000..563d718
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0645.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0645.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0645.wavetable
new file mode 100644
index 0000000..7751d18
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0645.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0646.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0646.wav
new file mode 100644
index 0000000..5acfea4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0646.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0646.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0646.wavetable
new file mode 100644
index 0000000..965e3cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0646.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0647.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0647.wav
new file mode 100644
index 0000000..fe167f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0647.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0647.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0647.wavetable
new file mode 100644
index 0000000..3d998a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0647.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0648.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0648.wav
new file mode 100644
index 0000000..20b3afb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0648.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0648.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0648.wavetable
new file mode 100644
index 0000000..cd8f36a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0648.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0649.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0649.wav
new file mode 100644
index 0000000..e5f3467
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0649.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0649.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0649.wavetable
new file mode 100644
index 0000000..af233ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0649.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0650.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0650.wav
new file mode 100644
index 0000000..974389f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0650.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0650.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0650.wavetable
new file mode 100644
index 0000000..e483617
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0650.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0651.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0651.wav
new file mode 100644
index 0000000..267d114
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0651.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0651.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0651.wavetable
new file mode 100644
index 0000000..8caac0c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0651.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0652.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0652.wav
new file mode 100644
index 0000000..80ff1ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0652.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0652.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0652.wavetable
new file mode 100644
index 0000000..0d6a81a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0652.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0653.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0653.wav
new file mode 100644
index 0000000..0481f41
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0653.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0653.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0653.wavetable
new file mode 100644
index 0000000..e969e5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0653.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0654.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0654.wav
new file mode 100644
index 0000000..92ea4b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0654.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0654.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0654.wavetable
new file mode 100644
index 0000000..a0896df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0654.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0655.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0655.wav
new file mode 100644
index 0000000..da6d580
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0655.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0655.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0655.wavetable
new file mode 100644
index 0000000..ab2329d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0655.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0656.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0656.wav
new file mode 100644
index 0000000..44ecd8a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0656.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0656.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0656.wavetable
new file mode 100644
index 0000000..a4e4c09
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0656.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0657.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0657.wav
new file mode 100644
index 0000000..60ed667
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0657.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0657.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0657.wavetable
new file mode 100644
index 0000000..a40aeeb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0657.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0658.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0658.wav
new file mode 100644
index 0000000..63a001d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0658.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0658.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0658.wavetable
new file mode 100644
index 0000000..3a3b61d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0658.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0659.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0659.wav
new file mode 100644
index 0000000..74df408
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0659.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0659.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0659.wavetable
new file mode 100644
index 0000000..bc1a29b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0659.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0660.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0660.wav
new file mode 100644
index 0000000..4978e94
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0660.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0660.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0660.wavetable
new file mode 100644
index 0000000..8bfcb04
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0660.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0661.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0661.wav
new file mode 100644
index 0000000..f3b8f1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0661.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0661.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0661.wavetable
new file mode 100644
index 0000000..2227c11
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0661.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0662.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0662.wav
new file mode 100644
index 0000000..0fd8cd6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0662.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0662.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0662.wavetable
new file mode 100644
index 0000000..26c6485
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0662.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0663.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0663.wav
new file mode 100644
index 0000000..9f0c98f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0663.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0663.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0663.wavetable
new file mode 100644
index 0000000..02c22ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0663.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0664.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0664.wav
new file mode 100644
index 0000000..5a5abd4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0664.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0664.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0664.wavetable
new file mode 100644
index 0000000..a93bef3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0664.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0665.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0665.wav
new file mode 100644
index 0000000..dbcb9c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0665.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0665.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0665.wavetable
new file mode 100644
index 0000000..395915e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0665.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0666.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0666.wav
new file mode 100644
index 0000000..acc2d60
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0666.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0666.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0666.wavetable
new file mode 100644
index 0000000..e68275b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0666.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0667.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0667.wav
new file mode 100644
index 0000000..5475422
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0667.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0667.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0667.wavetable
new file mode 100644
index 0000000..0a3a926
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0667.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0668.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0668.wav
new file mode 100644
index 0000000..291c2c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0668.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0668.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0668.wavetable
new file mode 100644
index 0000000..8239564
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0668.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0669.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0669.wav
new file mode 100644
index 0000000..2c82c63
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0669.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0669.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0669.wavetable
new file mode 100644
index 0000000..68dd088
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0669.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0670.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0670.wav
new file mode 100644
index 0000000..385bbf1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0670.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0670.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0670.wavetable
new file mode 100644
index 0000000..20741f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0670.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0671.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0671.wav
new file mode 100644
index 0000000..cb2bc3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0671.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0671.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0671.wavetable
new file mode 100644
index 0000000..33b376b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0671.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0672.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0672.wav
new file mode 100644
index 0000000..0d5e5ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0672.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0672.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0672.wavetable
new file mode 100644
index 0000000..1864f7b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0672.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0673.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0673.wav
new file mode 100644
index 0000000..f2747e2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0673.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0673.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0673.wavetable
new file mode 100644
index 0000000..0512cb3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0673.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0674.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0674.wav
new file mode 100644
index 0000000..9977ca0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0674.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0674.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0674.wavetable
new file mode 100644
index 0000000..1791700
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0674.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0675.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0675.wav
new file mode 100644
index 0000000..8688dad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0675.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0675.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0675.wavetable
new file mode 100644
index 0000000..a37c736
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0675.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0676.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0676.wav
new file mode 100644
index 0000000..9d53602
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0676.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0676.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0676.wavetable
new file mode 100644
index 0000000..e8f823b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0676.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0677.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0677.wav
new file mode 100644
index 0000000..b92854f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0677.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0677.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0677.wavetable
new file mode 100644
index 0000000..e3fdc31
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0677.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0678.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0678.wav
new file mode 100644
index 0000000..ff9f896
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0678.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0678.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0678.wavetable
new file mode 100644
index 0000000..037d9d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0678.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0679.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0679.wav
new file mode 100644
index 0000000..77ec133
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0679.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0679.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0679.wavetable
new file mode 100644
index 0000000..6f48acc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0679.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0680.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0680.wav
new file mode 100644
index 0000000..112b07d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0680.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0680.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0680.wavetable
new file mode 100644
index 0000000..0afae6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0680.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0681.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0681.wav
new file mode 100644
index 0000000..c0feb1d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0681.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0681.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0681.wavetable
new file mode 100644
index 0000000..b988011
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0681.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0682.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0682.wav
new file mode 100644
index 0000000..03b2df7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0682.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0682.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0682.wavetable
new file mode 100644
index 0000000..dee2064
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0682.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0683.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0683.wav
new file mode 100644
index 0000000..3c5efcc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0683.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0683.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0683.wavetable
new file mode 100644
index 0000000..6dd2f92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0683.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0684.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0684.wav
new file mode 100644
index 0000000..a08b273
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0684.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0684.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0684.wavetable
new file mode 100644
index 0000000..ca08047
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0684.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0685.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0685.wav
new file mode 100644
index 0000000..75e467e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0685.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0685.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0685.wavetable
new file mode 100644
index 0000000..016fea3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0685.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0686.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0686.wav
new file mode 100644
index 0000000..f0d732a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0686.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0686.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0686.wavetable
new file mode 100644
index 0000000..851c76a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0686.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0687.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0687.wav
new file mode 100644
index 0000000..5328f7b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0687.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0687.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0687.wavetable
new file mode 100644
index 0000000..aa50373
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0687.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0688.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0688.wav
new file mode 100644
index 0000000..2d13d75
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0688.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0688.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0688.wavetable
new file mode 100644
index 0000000..3791557
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0688.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0689.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0689.wav
new file mode 100644
index 0000000..7ee7c06
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0689.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0689.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0689.wavetable
new file mode 100644
index 0000000..8bede5d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0689.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0690.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0690.wav
new file mode 100644
index 0000000..b1a27e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0690.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0690.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0690.wavetable
new file mode 100644
index 0000000..f374069
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0690.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0691.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0691.wav
new file mode 100644
index 0000000..2f08918
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0691.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0691.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0691.wavetable
new file mode 100644
index 0000000..7a647de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0691.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0692.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0692.wav
new file mode 100644
index 0000000..20ed479
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0692.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0692.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0692.wavetable
new file mode 100644
index 0000000..43443f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0692.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0693.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0693.wav
new file mode 100644
index 0000000..00f7b95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0693.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0693.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0693.wavetable
new file mode 100644
index 0000000..8f84132
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0693.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0694.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0694.wav
new file mode 100644
index 0000000..30a86a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0694.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0694.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0694.wavetable
new file mode 100644
index 0000000..87b4c25
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0694.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0695.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0695.wav
new file mode 100644
index 0000000..8623625
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0695.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0695.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0695.wavetable
new file mode 100644
index 0000000..9442f03
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0695.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0696.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0696.wav
new file mode 100644
index 0000000..7b932dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0696.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0696.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0696.wavetable
new file mode 100644
index 0000000..b7fd2d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0696.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0697.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0697.wav
new file mode 100644
index 0000000..4650fa6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0697.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0697.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0697.wavetable
new file mode 100644
index 0000000..118a9b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0697.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0698.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0698.wav
new file mode 100644
index 0000000..1e47c83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0698.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0698.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0698.wavetable
new file mode 100644
index 0000000..f993886
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0698.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0699.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0699.wav
new file mode 100644
index 0000000..8865cca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0699.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0699.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0699.wavetable
new file mode 100644
index 0000000..abb1ef2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0699.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0700.wav b/etc/wavetables/AKWF/AKWF_0007/AKWF_0700.wav
new file mode 100644
index 0000000..cb77178
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0700.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AKWF_0700.wavetable b/etc/wavetables/AKWF/AKWF_0007/AKWF_0700.wavetable
new file mode 100644
index 0000000..badb8d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0007/AKWF_0700.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0007/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0007/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0007/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0701.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0701.wav
new file mode 100644
index 0000000..01f9a7c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0701.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0701.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0701.wavetable
new file mode 100644
index 0000000..9d81791
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0701.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0702.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0702.wav
new file mode 100644
index 0000000..201ed11
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0702.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0702.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0702.wavetable
new file mode 100644
index 0000000..74f6aba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0702.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0703.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0703.wav
new file mode 100644
index 0000000..e0fb33a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0703.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0703.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0703.wavetable
new file mode 100644
index 0000000..69a1e9b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0703.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0704.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0704.wav
new file mode 100644
index 0000000..597ceae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0704.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0704.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0704.wavetable
new file mode 100644
index 0000000..e3473d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0704.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0705.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0705.wav
new file mode 100644
index 0000000..22fc643
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0705.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0705.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0705.wavetable
new file mode 100644
index 0000000..0fe27b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0705.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0706.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0706.wav
new file mode 100644
index 0000000..806652b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0706.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0706.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0706.wavetable
new file mode 100644
index 0000000..7075353
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0706.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0707.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0707.wav
new file mode 100644
index 0000000..65ef614
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0707.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0707.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0707.wavetable
new file mode 100644
index 0000000..a3f9307
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0707.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0708.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0708.wav
new file mode 100644
index 0000000..3b6561e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0708.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0708.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0708.wavetable
new file mode 100644
index 0000000..d9778ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0708.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0709.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0709.wav
new file mode 100644
index 0000000..d91aa4a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0709.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0709.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0709.wavetable
new file mode 100644
index 0000000..16cc613
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0709.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0710.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0710.wav
new file mode 100644
index 0000000..0268990
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0710.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0710.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0710.wavetable
new file mode 100644
index 0000000..01ef1c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0710.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0711.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0711.wav
new file mode 100644
index 0000000..ca1b0cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0711.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0711.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0711.wavetable
new file mode 100644
index 0000000..69b2299
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0711.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0712.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0712.wav
new file mode 100644
index 0000000..f9c79d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0712.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0712.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0712.wavetable
new file mode 100644
index 0000000..5e25f9b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0712.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0713.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0713.wav
new file mode 100644
index 0000000..2bdbd5d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0713.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0713.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0713.wavetable
new file mode 100644
index 0000000..b9cc1e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0713.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0714.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0714.wav
new file mode 100644
index 0000000..49d683a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0714.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0714.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0714.wavetable
new file mode 100644
index 0000000..3675e5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0714.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0715.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0715.wav
new file mode 100644
index 0000000..c9d2ac2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0715.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0715.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0715.wavetable
new file mode 100644
index 0000000..b16d37c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0715.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0716.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0716.wav
new file mode 100644
index 0000000..4b8e974
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0716.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0716.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0716.wavetable
new file mode 100644
index 0000000..8546cba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0716.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0717.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0717.wav
new file mode 100644
index 0000000..177c85f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0717.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0717.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0717.wavetable
new file mode 100644
index 0000000..c4a7081
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0717.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0718.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0718.wav
new file mode 100644
index 0000000..6eae8cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0718.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0718.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0718.wavetable
new file mode 100644
index 0000000..6a96632
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0718.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0719.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0719.wav
new file mode 100644
index 0000000..816ade0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0719.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0719.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0719.wavetable
new file mode 100644
index 0000000..ad9f65a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0719.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0720.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0720.wav
new file mode 100644
index 0000000..18454de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0720.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0720.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0720.wavetable
new file mode 100644
index 0000000..1a4fb59
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0720.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0721.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0721.wav
new file mode 100644
index 0000000..7920b24
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0721.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0721.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0721.wavetable
new file mode 100644
index 0000000..e3a2e7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0721.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0722.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0722.wav
new file mode 100644
index 0000000..e48249f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0722.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0722.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0722.wavetable
new file mode 100644
index 0000000..94072a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0722.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0723.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0723.wav
new file mode 100644
index 0000000..d598313
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0723.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0723.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0723.wavetable
new file mode 100644
index 0000000..c67b62e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0723.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0724.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0724.wav
new file mode 100644
index 0000000..dbfeaf6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0724.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0724.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0724.wavetable
new file mode 100644
index 0000000..825893e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0724.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0725.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0725.wav
new file mode 100644
index 0000000..aeb8d3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0725.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0725.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0725.wavetable
new file mode 100644
index 0000000..3e05694
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0725.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0726.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0726.wav
new file mode 100644
index 0000000..90982d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0726.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0726.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0726.wavetable
new file mode 100644
index 0000000..ae36d34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0726.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0727.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0727.wav
new file mode 100644
index 0000000..7016b88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0727.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0727.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0727.wavetable
new file mode 100644
index 0000000..3d81ab7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0727.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0728.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0728.wav
new file mode 100644
index 0000000..a5536f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0728.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0728.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0728.wavetable
new file mode 100644
index 0000000..deb02fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0728.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0729.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0729.wav
new file mode 100644
index 0000000..31f2fad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0729.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0729.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0729.wavetable
new file mode 100644
index 0000000..dffa1f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0729.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0730.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0730.wav
new file mode 100644
index 0000000..271bb80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0730.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0730.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0730.wavetable
new file mode 100644
index 0000000..0a719c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0730.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0731.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0731.wav
new file mode 100644
index 0000000..beafcc0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0731.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0731.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0731.wavetable
new file mode 100644
index 0000000..f5eeaa4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0731.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0732.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0732.wav
new file mode 100644
index 0000000..248694e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0732.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0732.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0732.wavetable
new file mode 100644
index 0000000..b67ac21
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0732.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0733.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0733.wav
new file mode 100644
index 0000000..9538348
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0733.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0733.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0733.wavetable
new file mode 100644
index 0000000..541ffd2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0733.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0734.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0734.wav
new file mode 100644
index 0000000..991be9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0734.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0734.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0734.wavetable
new file mode 100644
index 0000000..bd1c500
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0734.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0735.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0735.wav
new file mode 100644
index 0000000..c1dc402
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0735.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0735.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0735.wavetable
new file mode 100644
index 0000000..7dcd50e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0735.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0736.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0736.wav
new file mode 100644
index 0000000..ae7a2b7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0736.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0736.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0736.wavetable
new file mode 100644
index 0000000..9a466c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0736.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0737.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0737.wav
new file mode 100644
index 0000000..f13feb7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0737.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0737.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0737.wavetable
new file mode 100644
index 0000000..b699c47
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0737.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0738.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0738.wav
new file mode 100644
index 0000000..d61c130
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0738.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0738.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0738.wavetable
new file mode 100644
index 0000000..82ae84e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0738.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0739.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0739.wav
new file mode 100644
index 0000000..1eb02fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0739.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0739.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0739.wavetable
new file mode 100644
index 0000000..dd3d146
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0739.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0740.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0740.wav
new file mode 100644
index 0000000..c9178cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0740.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0740.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0740.wavetable
new file mode 100644
index 0000000..181eca4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0740.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0741.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0741.wav
new file mode 100644
index 0000000..7aa1fb9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0741.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0741.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0741.wavetable
new file mode 100644
index 0000000..ffeffcd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0741.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0742.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0742.wav
new file mode 100644
index 0000000..4a9d40c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0742.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0742.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0742.wavetable
new file mode 100644
index 0000000..ce02172
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0742.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0743.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0743.wav
new file mode 100644
index 0000000..9a6bc74
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0743.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0743.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0743.wavetable
new file mode 100644
index 0000000..10481d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0743.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0744.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0744.wav
new file mode 100644
index 0000000..fe9431c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0744.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0744.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0744.wavetable
new file mode 100644
index 0000000..84d4237
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0744.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0745.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0745.wav
new file mode 100644
index 0000000..f450951
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0745.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0745.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0745.wavetable
new file mode 100644
index 0000000..4dc6afb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0745.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0746.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0746.wav
new file mode 100644
index 0000000..f175761
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0746.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0746.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0746.wavetable
new file mode 100644
index 0000000..fe66d62
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0746.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0747.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0747.wav
new file mode 100644
index 0000000..ffd897e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0747.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0747.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0747.wavetable
new file mode 100644
index 0000000..605c209
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0747.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0748.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0748.wav
new file mode 100644
index 0000000..df3e785
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0748.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0748.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0748.wavetable
new file mode 100644
index 0000000..694cb93
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0748.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0749.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0749.wav
new file mode 100644
index 0000000..e67985b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0749.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0749.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0749.wavetable
new file mode 100644
index 0000000..2490193
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0749.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0750.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0750.wav
new file mode 100644
index 0000000..40f615f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0750.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0750.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0750.wavetable
new file mode 100644
index 0000000..654f9fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0750.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0751.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0751.wav
new file mode 100644
index 0000000..95c253a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0751.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0751.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0751.wavetable
new file mode 100644
index 0000000..f00fcba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0751.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0752.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0752.wav
new file mode 100644
index 0000000..a4392e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0752.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0752.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0752.wavetable
new file mode 100644
index 0000000..b45cf3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0752.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0753.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0753.wav
new file mode 100644
index 0000000..5d3e4f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0753.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0753.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0753.wavetable
new file mode 100644
index 0000000..1c75111
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0753.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0754.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0754.wav
new file mode 100644
index 0000000..7a0da00
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0754.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0754.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0754.wavetable
new file mode 100644
index 0000000..e0196c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0754.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0755.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0755.wav
new file mode 100644
index 0000000..df9cab9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0755.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0755.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0755.wavetable
new file mode 100644
index 0000000..4e5829e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0755.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0756.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0756.wav
new file mode 100644
index 0000000..d373c78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0756.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0756.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0756.wavetable
new file mode 100644
index 0000000..38ccbb3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0756.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0757.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0757.wav
new file mode 100644
index 0000000..c4cfd7d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0757.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0757.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0757.wavetable
new file mode 100644
index 0000000..c56aa7b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0757.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0758.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0758.wav
new file mode 100644
index 0000000..050fa47
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0758.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0758.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0758.wavetable
new file mode 100644
index 0000000..d5f588d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0758.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0759.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0759.wav
new file mode 100644
index 0000000..342ca01
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0759.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0759.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0759.wavetable
new file mode 100644
index 0000000..9d04e4b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0759.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0760.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0760.wav
new file mode 100644
index 0000000..6d2bb79
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0760.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0760.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0760.wavetable
new file mode 100644
index 0000000..df42927
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0760.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0761.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0761.wav
new file mode 100644
index 0000000..b7a05a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0761.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0761.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0761.wavetable
new file mode 100644
index 0000000..6ab69d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0761.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0762.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0762.wav
new file mode 100644
index 0000000..0153166
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0762.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0762.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0762.wavetable
new file mode 100644
index 0000000..65fa36a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0762.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0763.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0763.wav
new file mode 100644
index 0000000..da3a5bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0763.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0763.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0763.wavetable
new file mode 100644
index 0000000..6a3c27a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0763.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0764.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0764.wav
new file mode 100644
index 0000000..143dd82
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0764.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0764.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0764.wavetable
new file mode 100644
index 0000000..de3e320
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0764.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0765.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0765.wav
new file mode 100644
index 0000000..33c4f77
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0765.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0765.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0765.wavetable
new file mode 100644
index 0000000..4bcd5c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0765.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0766.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0766.wav
new file mode 100644
index 0000000..f37c4b3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0766.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0766.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0766.wavetable
new file mode 100644
index 0000000..6279763
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0766.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0767.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0767.wav
new file mode 100644
index 0000000..f77f590
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0767.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0767.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0767.wavetable
new file mode 100644
index 0000000..1ed58cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0767.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0768.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0768.wav
new file mode 100644
index 0000000..42925bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0768.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0768.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0768.wavetable
new file mode 100644
index 0000000..d6cb76d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0768.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0769.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0769.wav
new file mode 100644
index 0000000..d1ce044
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0769.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0769.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0769.wavetable
new file mode 100644
index 0000000..3e42ade
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0769.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0770.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0770.wav
new file mode 100644
index 0000000..7d1c227
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0770.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0770.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0770.wavetable
new file mode 100644
index 0000000..4bbc2fc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0770.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0771.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0771.wav
new file mode 100644
index 0000000..8146ab7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0771.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0771.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0771.wavetable
new file mode 100644
index 0000000..21c0e9f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0771.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0772.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0772.wav
new file mode 100644
index 0000000..3c4697b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0772.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0772.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0772.wavetable
new file mode 100644
index 0000000..c86bb3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0772.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0773.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0773.wav
new file mode 100644
index 0000000..36b0515
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0773.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0773.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0773.wavetable
new file mode 100644
index 0000000..e5c936e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0773.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0774.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0774.wav
new file mode 100644
index 0000000..b984699
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0774.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0774.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0774.wavetable
new file mode 100644
index 0000000..0e45ba2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0774.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0775.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0775.wav
new file mode 100644
index 0000000..c74ef63
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0775.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0775.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0775.wavetable
new file mode 100644
index 0000000..91ca157
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0775.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0776.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0776.wav
new file mode 100644
index 0000000..f79eecb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0776.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0776.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0776.wavetable
new file mode 100644
index 0000000..93e7522
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0776.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0777.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0777.wav
new file mode 100644
index 0000000..5e01767
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0777.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0777.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0777.wavetable
new file mode 100644
index 0000000..61c54a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0777.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0778.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0778.wav
new file mode 100644
index 0000000..9c19cda
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0778.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0778.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0778.wavetable
new file mode 100644
index 0000000..8766b20
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0778.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0779.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0779.wav
new file mode 100644
index 0000000..77690c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0779.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0779.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0779.wavetable
new file mode 100644
index 0000000..02200aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0779.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0780.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0780.wav
new file mode 100644
index 0000000..65e5deb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0780.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0780.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0780.wavetable
new file mode 100644
index 0000000..f91a0f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0780.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0781.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0781.wav
new file mode 100644
index 0000000..48b2aa0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0781.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0781.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0781.wavetable
new file mode 100644
index 0000000..1485110
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0781.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0782.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0782.wav
new file mode 100644
index 0000000..dc20284
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0782.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0782.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0782.wavetable
new file mode 100644
index 0000000..d6bd7b7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0782.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0783.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0783.wav
new file mode 100644
index 0000000..2dd284c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0783.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0783.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0783.wavetable
new file mode 100644
index 0000000..370f8b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0783.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0784.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0784.wav
new file mode 100644
index 0000000..55878d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0784.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0784.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0784.wavetable
new file mode 100644
index 0000000..a4ea42d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0784.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0785.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0785.wav
new file mode 100644
index 0000000..1c84209
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0785.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0785.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0785.wavetable
new file mode 100644
index 0000000..417da60
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0785.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0786.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0786.wav
new file mode 100644
index 0000000..85e599f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0786.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0786.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0786.wavetable
new file mode 100644
index 0000000..fba798d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0786.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0787.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0787.wav
new file mode 100644
index 0000000..39f03a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0787.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0787.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0787.wavetable
new file mode 100644
index 0000000..5ec38bd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0787.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0788.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0788.wav
new file mode 100644
index 0000000..6388867
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0788.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0788.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0788.wavetable
new file mode 100644
index 0000000..15b112a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0788.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0789.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0789.wav
new file mode 100644
index 0000000..79056b7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0789.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0789.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0789.wavetable
new file mode 100644
index 0000000..03f6d86
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0789.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0790.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0790.wav
new file mode 100644
index 0000000..bb6bac6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0790.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0790.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0790.wavetable
new file mode 100644
index 0000000..e392797
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0790.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0791.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0791.wav
new file mode 100644
index 0000000..b83efad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0791.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0791.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0791.wavetable
new file mode 100644
index 0000000..542e6c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0791.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0792.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0792.wav
new file mode 100644
index 0000000..b06a31c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0792.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0792.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0792.wavetable
new file mode 100644
index 0000000..d7f1e9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0792.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0793.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0793.wav
new file mode 100644
index 0000000..b11a7dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0793.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0793.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0793.wavetable
new file mode 100644
index 0000000..ae3d319
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0793.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0794.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0794.wav
new file mode 100644
index 0000000..5ee1227
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0794.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0794.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0794.wavetable
new file mode 100644
index 0000000..f045f37
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0794.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0795.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0795.wav
new file mode 100644
index 0000000..ceaba37
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0795.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0795.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0795.wavetable
new file mode 100644
index 0000000..b1f4bae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0795.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0796.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0796.wav
new file mode 100644
index 0000000..c387dd0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0796.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0796.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0796.wavetable
new file mode 100644
index 0000000..81ea1d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0796.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0797.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0797.wav
new file mode 100644
index 0000000..42ade3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0797.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0797.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0797.wavetable
new file mode 100644
index 0000000..834ec94
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0797.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0798.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0798.wav
new file mode 100644
index 0000000..6714af5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0798.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0798.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0798.wavetable
new file mode 100644
index 0000000..499f97c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0798.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0799.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0799.wav
new file mode 100644
index 0000000..0e262da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0799.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0799.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0799.wavetable
new file mode 100644
index 0000000..344c038
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0799.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0800.wav b/etc/wavetables/AKWF/AKWF_0008/AKWF_0800.wav
new file mode 100644
index 0000000..6bb6918
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0800.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AKWF_0800.wavetable b/etc/wavetables/AKWF/AKWF_0008/AKWF_0800.wavetable
new file mode 100644
index 0000000..4b29db2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0008/AKWF_0800.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0008/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0008/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0008/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0801.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0801.wav
new file mode 100644
index 0000000..0aab5fc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0801.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0801.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0801.wavetable
new file mode 100644
index 0000000..f371123
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0801.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0802.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0802.wav
new file mode 100644
index 0000000..68ba72a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0802.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0802.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0802.wavetable
new file mode 100644
index 0000000..fc4cb66
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0802.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0803.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0803.wav
new file mode 100644
index 0000000..d5f51a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0803.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0803.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0803.wavetable
new file mode 100644
index 0000000..798f5cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0803.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0804.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0804.wav
new file mode 100644
index 0000000..cd4d02c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0804.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0804.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0804.wavetable
new file mode 100644
index 0000000..dee3f47
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0804.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0805.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0805.wav
new file mode 100644
index 0000000..b9267a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0805.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0805.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0805.wavetable
new file mode 100644
index 0000000..0693bc7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0805.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0806.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0806.wav
new file mode 100644
index 0000000..9d726ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0806.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0806.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0806.wavetable
new file mode 100644
index 0000000..9d64c04
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0806.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0807.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0807.wav
new file mode 100644
index 0000000..be13467
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0807.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0807.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0807.wavetable
new file mode 100644
index 0000000..0fefbb5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0807.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0808.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0808.wav
new file mode 100644
index 0000000..ef86077
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0808.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0808.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0808.wavetable
new file mode 100644
index 0000000..52bd73d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0808.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0809.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0809.wav
new file mode 100644
index 0000000..47e69de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0809.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0809.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0809.wavetable
new file mode 100644
index 0000000..dbe1daf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0809.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0810.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0810.wav
new file mode 100644
index 0000000..5ab8feb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0810.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0810.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0810.wavetable
new file mode 100644
index 0000000..b19ce00
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0810.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0811.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0811.wav
new file mode 100644
index 0000000..62bf67a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0811.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0811.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0811.wavetable
new file mode 100644
index 0000000..e095e83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0811.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0812.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0812.wav
new file mode 100644
index 0000000..6658c66
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0812.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0812.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0812.wavetable
new file mode 100644
index 0000000..ba5310b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0812.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0813.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0813.wav
new file mode 100644
index 0000000..59dd4aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0813.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0813.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0813.wavetable
new file mode 100644
index 0000000..093e149
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0813.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0814.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0814.wav
new file mode 100644
index 0000000..91106de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0814.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0814.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0814.wavetable
new file mode 100644
index 0000000..0fd8151
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0814.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0815.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0815.wav
new file mode 100644
index 0000000..b2a6a5f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0815.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0815.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0815.wavetable
new file mode 100644
index 0000000..e30762c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0815.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0816.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0816.wav
new file mode 100644
index 0000000..1f841b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0816.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0816.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0816.wavetable
new file mode 100644
index 0000000..c568cb2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0816.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0817.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0817.wav
new file mode 100644
index 0000000..3ddf06c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0817.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0817.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0817.wavetable
new file mode 100644
index 0000000..ad2407b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0817.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0818.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0818.wav
new file mode 100644
index 0000000..fda23f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0818.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0818.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0818.wavetable
new file mode 100644
index 0000000..dbcf7bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0818.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0819.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0819.wav
new file mode 100644
index 0000000..6130209
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0819.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0819.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0819.wavetable
new file mode 100644
index 0000000..fe642ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0819.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0820.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0820.wav
new file mode 100644
index 0000000..5f7d461
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0820.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0820.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0820.wavetable
new file mode 100644
index 0000000..cdf8de5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0820.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0821.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0821.wav
new file mode 100644
index 0000000..24c4a92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0821.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0821.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0821.wavetable
new file mode 100644
index 0000000..331c53f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0821.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0822.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0822.wav
new file mode 100644
index 0000000..4009ac8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0822.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0822.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0822.wavetable
new file mode 100644
index 0000000..52ec86c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0822.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0823.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0823.wav
new file mode 100644
index 0000000..df31d47
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0823.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0823.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0823.wavetable
new file mode 100644
index 0000000..fe09475
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0823.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0824.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0824.wav
new file mode 100644
index 0000000..4ca479f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0824.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0824.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0824.wavetable
new file mode 100644
index 0000000..4cf7d4b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0824.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0825.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0825.wav
new file mode 100644
index 0000000..3843889
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0825.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0825.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0825.wavetable
new file mode 100644
index 0000000..1b340f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0825.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0826.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0826.wav
new file mode 100644
index 0000000..f343d01
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0826.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0826.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0826.wavetable
new file mode 100644
index 0000000..8212161
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0826.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0827.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0827.wav
new file mode 100644
index 0000000..d0b24e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0827.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0827.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0827.wavetable
new file mode 100644
index 0000000..f39b676
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0827.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0828.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0828.wav
new file mode 100644
index 0000000..c015a55
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0828.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0828.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0828.wavetable
new file mode 100644
index 0000000..b6f42ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0828.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0829.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0829.wav
new file mode 100644
index 0000000..d516ca7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0829.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0829.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0829.wavetable
new file mode 100644
index 0000000..eb4e7e3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0829.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0830.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0830.wav
new file mode 100644
index 0000000..a717c57
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0830.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0830.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0830.wavetable
new file mode 100644
index 0000000..cd2af75
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0830.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0831.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0831.wav
new file mode 100644
index 0000000..5fe1cda
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0831.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0831.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0831.wavetable
new file mode 100644
index 0000000..b05aac2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0831.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0832.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0832.wav
new file mode 100644
index 0000000..7d9c3fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0832.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0832.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0832.wavetable
new file mode 100644
index 0000000..416fb88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0832.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0833.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0833.wav
new file mode 100644
index 0000000..d989f35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0833.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0833.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0833.wavetable
new file mode 100644
index 0000000..769c194
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0833.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0834.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0834.wav
new file mode 100644
index 0000000..fc1fbf0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0834.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0834.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0834.wavetable
new file mode 100644
index 0000000..d645b5d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0834.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0835.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0835.wav
new file mode 100644
index 0000000..0304b92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0835.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0835.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0835.wavetable
new file mode 100644
index 0000000..26eda1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0835.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0836.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0836.wav
new file mode 100644
index 0000000..b1a786c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0836.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0836.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0836.wavetable
new file mode 100644
index 0000000..70a7fb8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0836.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0837.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0837.wav
new file mode 100644
index 0000000..7ffbbf1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0837.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0837.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0837.wavetable
new file mode 100644
index 0000000..b8e3ed8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0837.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0838.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0838.wav
new file mode 100644
index 0000000..15f14ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0838.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0838.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0838.wavetable
new file mode 100644
index 0000000..39b4b58
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0838.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0839.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0839.wav
new file mode 100644
index 0000000..f53b1aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0839.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0839.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0839.wavetable
new file mode 100644
index 0000000..406bdc5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0839.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0840.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0840.wav
new file mode 100644
index 0000000..1d3f925
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0840.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0840.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0840.wavetable
new file mode 100644
index 0000000..4f50525
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0840.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0841.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0841.wav
new file mode 100644
index 0000000..6718340
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0841.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0841.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0841.wavetable
new file mode 100644
index 0000000..be1def4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0841.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0842.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0842.wav
new file mode 100644
index 0000000..914f878
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0842.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0842.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0842.wavetable
new file mode 100644
index 0000000..d968b8d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0842.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0843.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0843.wav
new file mode 100644
index 0000000..2a3aaa0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0843.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0843.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0843.wavetable
new file mode 100644
index 0000000..c6bee42
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0843.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0844.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0844.wav
new file mode 100644
index 0000000..3bb9f62
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0844.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0844.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0844.wavetable
new file mode 100644
index 0000000..928915e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0844.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0845.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0845.wav
new file mode 100644
index 0000000..62f2161
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0845.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0845.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0845.wavetable
new file mode 100644
index 0000000..82ea9ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0845.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0846.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0846.wav
new file mode 100644
index 0000000..a14d0a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0846.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0846.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0846.wavetable
new file mode 100644
index 0000000..3eb49f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0846.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0847.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0847.wav
new file mode 100644
index 0000000..2693160
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0847.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0847.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0847.wavetable
new file mode 100644
index 0000000..b41e878
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0847.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0848.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0848.wav
new file mode 100644
index 0000000..31c2fcb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0848.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0848.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0848.wavetable
new file mode 100644
index 0000000..96dede7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0848.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0849.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0849.wav
new file mode 100644
index 0000000..b0a5381
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0849.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0849.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0849.wavetable
new file mode 100644
index 0000000..8dec7f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0849.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0850.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0850.wav
new file mode 100644
index 0000000..d377475
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0850.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0850.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0850.wavetable
new file mode 100644
index 0000000..05cb6e2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0850.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0851.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0851.wav
new file mode 100644
index 0000000..3a71a13
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0851.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0851.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0851.wavetable
new file mode 100644
index 0000000..5cb2bc4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0851.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0852.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0852.wav
new file mode 100644
index 0000000..9f384dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0852.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0852.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0852.wavetable
new file mode 100644
index 0000000..04d7648
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0852.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0853.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0853.wav
new file mode 100644
index 0000000..490e166
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0853.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0853.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0853.wavetable
new file mode 100644
index 0000000..d8d6d06
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0853.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0854.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0854.wav
new file mode 100644
index 0000000..a8340b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0854.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0854.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0854.wavetable
new file mode 100644
index 0000000..945bbe2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0854.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0855.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0855.wav
new file mode 100644
index 0000000..dad42f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0855.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0855.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0855.wavetable
new file mode 100644
index 0000000..60d3c45
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0855.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0856.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0856.wav
new file mode 100644
index 0000000..a6224c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0856.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0856.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0856.wavetable
new file mode 100644
index 0000000..526d8be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0856.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0857.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0857.wav
new file mode 100644
index 0000000..189541f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0857.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0857.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0857.wavetable
new file mode 100644
index 0000000..a001fe8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0857.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0858.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0858.wav
new file mode 100644
index 0000000..8ab33ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0858.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0858.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0858.wavetable
new file mode 100644
index 0000000..3d1efed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0858.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0859.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0859.wav
new file mode 100644
index 0000000..32e1b01
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0859.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0859.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0859.wavetable
new file mode 100644
index 0000000..e609c62
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0859.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0860.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0860.wav
new file mode 100644
index 0000000..8fa11fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0860.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0860.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0860.wavetable
new file mode 100644
index 0000000..0e46f7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0860.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0861.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0861.wav
new file mode 100644
index 0000000..7749d8a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0861.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0861.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0861.wavetable
new file mode 100644
index 0000000..681a219
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0861.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0862.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0862.wav
new file mode 100644
index 0000000..78c7711
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0862.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0862.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0862.wavetable
new file mode 100644
index 0000000..873bf93
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0862.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0863.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0863.wav
new file mode 100644
index 0000000..6ba414d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0863.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0863.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0863.wavetable
new file mode 100644
index 0000000..77634e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0863.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0864.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0864.wav
new file mode 100644
index 0000000..b16a4bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0864.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0864.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0864.wavetable
new file mode 100644
index 0000000..a8d56e2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0864.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0865.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0865.wav
new file mode 100644
index 0000000..51b48f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0865.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0865.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0865.wavetable
new file mode 100644
index 0000000..9039250
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0865.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0866.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0866.wav
new file mode 100644
index 0000000..2392dd3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0866.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0866.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0866.wavetable
new file mode 100644
index 0000000..26de3f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0866.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0867.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0867.wav
new file mode 100644
index 0000000..43fea64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0867.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0867.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0867.wavetable
new file mode 100644
index 0000000..026d1ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0867.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0868.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0868.wav
new file mode 100644
index 0000000..4a91b7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0868.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0868.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0868.wavetable
new file mode 100644
index 0000000..8dd6912
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0868.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0869.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0869.wav
new file mode 100644
index 0000000..d9d36ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0869.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0869.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0869.wavetable
new file mode 100644
index 0000000..8a1d015
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0869.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0870.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0870.wav
new file mode 100644
index 0000000..7296cc8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0870.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0870.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0870.wavetable
new file mode 100644
index 0000000..1435e72
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0870.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0871.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0871.wav
new file mode 100644
index 0000000..8da8b45
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0871.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0871.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0871.wavetable
new file mode 100644
index 0000000..f529cbd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0871.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0872.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0872.wav
new file mode 100644
index 0000000..abd75ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0872.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0872.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0872.wavetable
new file mode 100644
index 0000000..42cc8a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0872.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0873.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0873.wav
new file mode 100644
index 0000000..15b8224
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0873.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0873.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0873.wavetable
new file mode 100644
index 0000000..7a7812f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0873.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0874.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0874.wav
new file mode 100644
index 0000000..949de4a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0874.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0874.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0874.wavetable
new file mode 100644
index 0000000..3c1d6cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0874.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0875.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0875.wav
new file mode 100644
index 0000000..2b593f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0875.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0875.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0875.wavetable
new file mode 100644
index 0000000..5b86102
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0875.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0876.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0876.wav
new file mode 100644
index 0000000..0410e64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0876.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0876.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0876.wavetable
new file mode 100644
index 0000000..4948c46
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0876.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0877.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0877.wav
new file mode 100644
index 0000000..26d87f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0877.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0877.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0877.wavetable
new file mode 100644
index 0000000..045e3f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0877.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0878.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0878.wav
new file mode 100644
index 0000000..a28409e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0878.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0878.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0878.wavetable
new file mode 100644
index 0000000..572c9c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0878.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0879.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0879.wav
new file mode 100644
index 0000000..64ffdd2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0879.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0879.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0879.wavetable
new file mode 100644
index 0000000..cbe85a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0879.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0880.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0880.wav
new file mode 100644
index 0000000..7be2e2c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0880.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0880.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0880.wavetable
new file mode 100644
index 0000000..7ccc1d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0880.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0881.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0881.wav
new file mode 100644
index 0000000..d12cd54
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0881.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0881.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0881.wavetable
new file mode 100644
index 0000000..00c80a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0881.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0882.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0882.wav
new file mode 100644
index 0000000..c47d286
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0882.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0882.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0882.wavetable
new file mode 100644
index 0000000..90e762b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0882.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0883.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0883.wav
new file mode 100644
index 0000000..d4018b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0883.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0883.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0883.wavetable
new file mode 100644
index 0000000..a406fae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0883.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0884.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0884.wav
new file mode 100644
index 0000000..af771f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0884.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0884.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0884.wavetable
new file mode 100644
index 0000000..0f941e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0884.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0885.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0885.wav
new file mode 100644
index 0000000..bea4132
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0885.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0885.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0885.wavetable
new file mode 100644
index 0000000..0bac7cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0885.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0886.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0886.wav
new file mode 100644
index 0000000..07d3abb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0886.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0886.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0886.wavetable
new file mode 100644
index 0000000..5a46a33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0886.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0887.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0887.wav
new file mode 100644
index 0000000..d8c49eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0887.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0887.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0887.wavetable
new file mode 100644
index 0000000..9561fee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0887.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0888.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0888.wav
new file mode 100644
index 0000000..ced3b79
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0888.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0888.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0888.wavetable
new file mode 100644
index 0000000..d36660f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0888.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0889.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0889.wav
new file mode 100644
index 0000000..91f7d38
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0889.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0889.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0889.wavetable
new file mode 100644
index 0000000..ba6f68b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0889.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0890.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0890.wav
new file mode 100644
index 0000000..ee8a50b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0890.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0890.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0890.wavetable
new file mode 100644
index 0000000..5fdf2e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0890.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0891.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0891.wav
new file mode 100644
index 0000000..4bf0923
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0891.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0891.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0891.wavetable
new file mode 100644
index 0000000..c5af8e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0891.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0892.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0892.wav
new file mode 100644
index 0000000..33520c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0892.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0892.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0892.wavetable
new file mode 100644
index 0000000..816261f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0892.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0893.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0893.wav
new file mode 100644
index 0000000..acf9672
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0893.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0893.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0893.wavetable
new file mode 100644
index 0000000..2fc2b4f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0893.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0894.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0894.wav
new file mode 100644
index 0000000..c6f2602
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0894.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0894.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0894.wavetable
new file mode 100644
index 0000000..4ded861
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0894.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0895.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0895.wav
new file mode 100644
index 0000000..68b9631
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0895.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0895.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0895.wavetable
new file mode 100644
index 0000000..aa2c0d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0895.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0896.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0896.wav
new file mode 100644
index 0000000..73fb83b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0896.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0896.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0896.wavetable
new file mode 100644
index 0000000..6ae819b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0896.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0897.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0897.wav
new file mode 100644
index 0000000..24d54af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0897.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0897.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0897.wavetable
new file mode 100644
index 0000000..bb3507c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0897.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0898.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0898.wav
new file mode 100644
index 0000000..1283744
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0898.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0898.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0898.wavetable
new file mode 100644
index 0000000..66bdb47
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0898.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0899.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0899.wav
new file mode 100644
index 0000000..d7ec2a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0899.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0899.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0899.wavetable
new file mode 100644
index 0000000..15314cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0899.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0900.wav b/etc/wavetables/AKWF/AKWF_0009/AKWF_0900.wav
new file mode 100644
index 0000000..3c4388c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0900.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AKWF_0900.wavetable b/etc/wavetables/AKWF/AKWF_0009/AKWF_0900.wavetable
new file mode 100644
index 0000000..effec80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0009/AKWF_0900.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0009/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0009/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0009/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0901.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0901.wav
new file mode 100644
index 0000000..c2baeef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0901.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0901.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0901.wavetable
new file mode 100644
index 0000000..3d48ba4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0901.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0902.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0902.wav
new file mode 100644
index 0000000..e4ee3bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0902.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0902.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0902.wavetable
new file mode 100644
index 0000000..44ecbfb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0902.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0903.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0903.wav
new file mode 100644
index 0000000..bede759
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0903.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0903.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0903.wavetable
new file mode 100644
index 0000000..e701033
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0903.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0904.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0904.wav
new file mode 100644
index 0000000..03f4fb4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0904.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0904.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0904.wavetable
new file mode 100644
index 0000000..ebf432b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0904.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0905.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0905.wav
new file mode 100644
index 0000000..5ee1c2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0905.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0905.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0905.wavetable
new file mode 100644
index 0000000..fccbb73
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0905.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0906.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0906.wav
new file mode 100644
index 0000000..9c6d556
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0906.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0906.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0906.wavetable
new file mode 100644
index 0000000..84abd0f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0906.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0907.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0907.wav
new file mode 100644
index 0000000..f088c61
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0907.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0907.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0907.wavetable
new file mode 100644
index 0000000..76c44e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0907.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0908.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0908.wav
new file mode 100644
index 0000000..a8b85af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0908.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0908.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0908.wavetable
new file mode 100644
index 0000000..9a907e2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0908.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0909.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0909.wav
new file mode 100644
index 0000000..74b6a1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0909.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0909.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0909.wavetable
new file mode 100644
index 0000000..f38beab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0909.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0910.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0910.wav
new file mode 100644
index 0000000..611dcc8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0910.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0910.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0910.wavetable
new file mode 100644
index 0000000..91703ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0910.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0911.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0911.wav
new file mode 100644
index 0000000..53a87ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0911.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0911.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0911.wavetable
new file mode 100644
index 0000000..7567f9c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0911.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0912.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0912.wav
new file mode 100644
index 0000000..5181e1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0912.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0912.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0912.wavetable
new file mode 100644
index 0000000..27a58bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0912.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0913.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0913.wav
new file mode 100644
index 0000000..ee168f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0913.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0913.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0913.wavetable
new file mode 100644
index 0000000..eb39a12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0913.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0914.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0914.wav
new file mode 100644
index 0000000..7601d4d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0914.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0914.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0914.wavetable
new file mode 100644
index 0000000..5b76c49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0914.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0915.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0915.wav
new file mode 100644
index 0000000..ef74d3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0915.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0915.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0915.wavetable
new file mode 100644
index 0000000..fdee7e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0915.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0916.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0916.wav
new file mode 100644
index 0000000..3f4b604
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0916.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0916.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0916.wavetable
new file mode 100644
index 0000000..d17058e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0916.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0917.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0917.wav
new file mode 100644
index 0000000..405cd4a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0917.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0917.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0917.wavetable
new file mode 100644
index 0000000..1233d89
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0917.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0918.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0918.wav
new file mode 100644
index 0000000..2ae0aa8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0918.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0918.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0918.wavetable
new file mode 100644
index 0000000..edb5eb1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0918.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0919.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0919.wav
new file mode 100644
index 0000000..a3e5756
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0919.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0919.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0919.wavetable
new file mode 100644
index 0000000..452d17d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0919.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0920.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0920.wav
new file mode 100644
index 0000000..9cf858a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0920.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0920.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0920.wavetable
new file mode 100644
index 0000000..07969cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0920.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0921.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0921.wav
new file mode 100644
index 0000000..bbb91a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0921.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0921.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0921.wavetable
new file mode 100644
index 0000000..95babc5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0921.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0922.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0922.wav
new file mode 100644
index 0000000..43ca02f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0922.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0922.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0922.wavetable
new file mode 100644
index 0000000..3e23d1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0922.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0923.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0923.wav
new file mode 100644
index 0000000..312f056
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0923.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0923.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0923.wavetable
new file mode 100644
index 0000000..7f188a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0923.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0924.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0924.wav
new file mode 100644
index 0000000..71fe097
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0924.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0924.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0924.wavetable
new file mode 100644
index 0000000..f586263
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0924.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0925.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0925.wav
new file mode 100644
index 0000000..da6e6d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0925.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0925.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0925.wavetable
new file mode 100644
index 0000000..a9fd7cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0925.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0926.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0926.wav
new file mode 100644
index 0000000..1626de6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0926.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0926.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0926.wavetable
new file mode 100644
index 0000000..b09b01a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0926.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0927.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0927.wav
new file mode 100644
index 0000000..82c9e55
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0927.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0927.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0927.wavetable
new file mode 100644
index 0000000..55d084e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0927.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0928.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0928.wav
new file mode 100644
index 0000000..e22f056
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0928.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0928.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0928.wavetable
new file mode 100644
index 0000000..23b2e04
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0928.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0929.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0929.wav
new file mode 100644
index 0000000..3425431
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0929.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0929.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0929.wavetable
new file mode 100644
index 0000000..2a17556
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0929.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0930.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0930.wav
new file mode 100644
index 0000000..2072d51
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0930.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0930.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0930.wavetable
new file mode 100644
index 0000000..27afb07
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0930.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0931.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0931.wav
new file mode 100644
index 0000000..b3cd4d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0931.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0931.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0931.wavetable
new file mode 100644
index 0000000..88eda52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0931.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0932.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0932.wav
new file mode 100644
index 0000000..26da2bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0932.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0932.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0932.wavetable
new file mode 100644
index 0000000..c0e7059
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0932.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0933.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0933.wav
new file mode 100644
index 0000000..4055211
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0933.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0933.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0933.wavetable
new file mode 100644
index 0000000..b7fb488
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0933.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0934.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0934.wav
new file mode 100644
index 0000000..7a1b251
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0934.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0934.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0934.wavetable
new file mode 100644
index 0000000..0c75a84
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0934.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0935.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0935.wav
new file mode 100644
index 0000000..764116c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0935.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0935.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0935.wavetable
new file mode 100644
index 0000000..cd72333
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0935.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0936.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0936.wav
new file mode 100644
index 0000000..886afed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0936.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0936.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0936.wavetable
new file mode 100644
index 0000000..a0a01a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0936.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0937.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0937.wav
new file mode 100644
index 0000000..cc6b330
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0937.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0937.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0937.wavetable
new file mode 100644
index 0000000..55db12a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0937.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0938.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0938.wav
new file mode 100644
index 0000000..395a9da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0938.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0938.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0938.wavetable
new file mode 100644
index 0000000..ad56f53
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0938.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0939.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0939.wav
new file mode 100644
index 0000000..2694089
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0939.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0939.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0939.wavetable
new file mode 100644
index 0000000..573b896
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0939.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0940.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0940.wav
new file mode 100644
index 0000000..863e799
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0940.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0940.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0940.wavetable
new file mode 100644
index 0000000..d26d5af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0940.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0941.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0941.wav
new file mode 100644
index 0000000..881ff6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0941.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0941.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0941.wavetable
new file mode 100644
index 0000000..2cf9547
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0941.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0942.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0942.wav
new file mode 100644
index 0000000..01817c7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0942.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0942.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0942.wavetable
new file mode 100644
index 0000000..f52e5e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0942.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0943.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0943.wav
new file mode 100644
index 0000000..88064db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0943.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0943.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0943.wavetable
new file mode 100644
index 0000000..231a984
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0943.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0944.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0944.wav
new file mode 100644
index 0000000..3db1d93
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0944.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0944.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0944.wavetable
new file mode 100644
index 0000000..cf9a3cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0944.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0945.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0945.wav
new file mode 100644
index 0000000..27ce4d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0945.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0945.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0945.wavetable
new file mode 100644
index 0000000..d462c3a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0945.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0946.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0946.wav
new file mode 100644
index 0000000..485722f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0946.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0946.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0946.wavetable
new file mode 100644
index 0000000..a8b20c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0946.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0947.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0947.wav
new file mode 100644
index 0000000..d69e012
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0947.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0947.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0947.wavetable
new file mode 100644
index 0000000..beef8c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0947.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0948.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0948.wav
new file mode 100644
index 0000000..e2de636
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0948.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0948.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0948.wavetable
new file mode 100644
index 0000000..0f37de5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0948.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0949.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0949.wav
new file mode 100644
index 0000000..287b177
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0949.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0949.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0949.wavetable
new file mode 100644
index 0000000..5838230
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0949.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0950.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0950.wav
new file mode 100644
index 0000000..ba75d5e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0950.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0950.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0950.wavetable
new file mode 100644
index 0000000..87916f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0950.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0951.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0951.wav
new file mode 100644
index 0000000..8955261
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0951.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0951.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0951.wavetable
new file mode 100644
index 0000000..f9722b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0951.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0952.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0952.wav
new file mode 100644
index 0000000..a983482
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0952.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0952.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0952.wavetable
new file mode 100644
index 0000000..155d802
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0952.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0953.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0953.wav
new file mode 100644
index 0000000..b53a10f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0953.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0953.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0953.wavetable
new file mode 100644
index 0000000..602ca2a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0953.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0954.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0954.wav
new file mode 100644
index 0000000..c7093d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0954.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0954.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0954.wavetable
new file mode 100644
index 0000000..a28681b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0954.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0955.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0955.wav
new file mode 100644
index 0000000..6cefdb3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0955.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0955.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0955.wavetable
new file mode 100644
index 0000000..96f83c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0955.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0956.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0956.wav
new file mode 100644
index 0000000..561cb68
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0956.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0956.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0956.wavetable
new file mode 100644
index 0000000..ed26d83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0956.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0957.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0957.wav
new file mode 100644
index 0000000..1894a79
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0957.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0957.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0957.wavetable
new file mode 100644
index 0000000..5b7a4ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0957.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0958.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0958.wav
new file mode 100644
index 0000000..f4fa77d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0958.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0958.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0958.wavetable
new file mode 100644
index 0000000..3cb0b78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0958.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0959.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0959.wav
new file mode 100644
index 0000000..5644433
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0959.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0959.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0959.wavetable
new file mode 100644
index 0000000..d8fd7c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0959.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0960.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0960.wav
new file mode 100644
index 0000000..e11ae27
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0960.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0960.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0960.wavetable
new file mode 100644
index 0000000..418bbb6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0960.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0961.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0961.wav
new file mode 100644
index 0000000..2e58dfd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0961.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0961.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0961.wavetable
new file mode 100644
index 0000000..0531f19
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0961.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0962.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0962.wav
new file mode 100644
index 0000000..58b8284
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0962.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0962.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0962.wavetable
new file mode 100644
index 0000000..4706a82
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0962.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0963.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0963.wav
new file mode 100644
index 0000000..bca28e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0963.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0963.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0963.wavetable
new file mode 100644
index 0000000..b3b0fba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0963.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0964.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0964.wav
new file mode 100644
index 0000000..a82a5aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0964.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0964.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0964.wavetable
new file mode 100644
index 0000000..60ecca2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0964.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0965.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0965.wav
new file mode 100644
index 0000000..24312bd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0965.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0965.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0965.wavetable
new file mode 100644
index 0000000..e1d4802
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0965.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0966.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0966.wav
new file mode 100644
index 0000000..90a77de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0966.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0966.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0966.wavetable
new file mode 100644
index 0000000..ff90f71
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0966.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0967.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0967.wav
new file mode 100644
index 0000000..29f0975
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0967.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0967.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0967.wavetable
new file mode 100644
index 0000000..aa6480f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0967.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0968.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0968.wav
new file mode 100644
index 0000000..2e72881
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0968.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0968.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0968.wavetable
new file mode 100644
index 0000000..87a25d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0968.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0969.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0969.wav
new file mode 100644
index 0000000..5126b06
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0969.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0969.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0969.wavetable
new file mode 100644
index 0000000..f89e045
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0969.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0970.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0970.wav
new file mode 100644
index 0000000..ec53a2a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0970.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0970.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0970.wavetable
new file mode 100644
index 0000000..9b86756
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0970.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0971.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0971.wav
new file mode 100644
index 0000000..a68c8c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0971.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0971.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0971.wavetable
new file mode 100644
index 0000000..1f6b367
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0971.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0972.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0972.wav
new file mode 100644
index 0000000..ba31c93
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0972.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0972.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0972.wavetable
new file mode 100644
index 0000000..717d064
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0972.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0973.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0973.wav
new file mode 100644
index 0000000..3901650
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0973.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0973.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0973.wavetable
new file mode 100644
index 0000000..48714d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0973.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0974.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0974.wav
new file mode 100644
index 0000000..bb08a4d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0974.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0974.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0974.wavetable
new file mode 100644
index 0000000..c45156d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0974.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0975.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0975.wav
new file mode 100644
index 0000000..f99fab4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0975.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0975.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0975.wavetable
new file mode 100644
index 0000000..3bff54e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0975.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0976.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0976.wav
new file mode 100644
index 0000000..abaf9bd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0976.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0976.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0976.wavetable
new file mode 100644
index 0000000..0deeb4e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0976.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0977.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0977.wav
new file mode 100644
index 0000000..b6438f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0977.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0977.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0977.wavetable
new file mode 100644
index 0000000..29cb70b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0977.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0978.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0978.wav
new file mode 100644
index 0000000..6b10c02
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0978.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0978.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0978.wavetable
new file mode 100644
index 0000000..8d64f8d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0978.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0979.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0979.wav
new file mode 100644
index 0000000..f33d00b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0979.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0979.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0979.wavetable
new file mode 100644
index 0000000..346e260
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0979.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0980.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0980.wav
new file mode 100644
index 0000000..0b64ef8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0980.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0980.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0980.wavetable
new file mode 100644
index 0000000..1c2c8db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0980.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0981.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0981.wav
new file mode 100644
index 0000000..e9776ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0981.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0981.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0981.wavetable
new file mode 100644
index 0000000..bc9398b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0981.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0982.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0982.wav
new file mode 100644
index 0000000..0ef6247
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0982.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0982.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0982.wavetable
new file mode 100644
index 0000000..3083b83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0982.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0983.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0983.wav
new file mode 100644
index 0000000..64433d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0983.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0983.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0983.wavetable
new file mode 100644
index 0000000..f2fbb16
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0983.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0984.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0984.wav
new file mode 100644
index 0000000..887dc32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0984.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0984.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0984.wavetable
new file mode 100644
index 0000000..e8398bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0984.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0985.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0985.wav
new file mode 100644
index 0000000..f678d1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0985.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0985.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0985.wavetable
new file mode 100644
index 0000000..574f023
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0985.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0986.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0986.wav
new file mode 100644
index 0000000..b06c410
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0986.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0986.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0986.wavetable
new file mode 100644
index 0000000..de042b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0986.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0987.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0987.wav
new file mode 100644
index 0000000..d61d341
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0987.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0987.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0987.wavetable
new file mode 100644
index 0000000..f8b7f72
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0987.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0988.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0988.wav
new file mode 100644
index 0000000..9604c52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0988.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0988.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0988.wavetable
new file mode 100644
index 0000000..c272d7b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0988.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0989.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0989.wav
new file mode 100644
index 0000000..6c49339
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0989.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0989.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0989.wavetable
new file mode 100644
index 0000000..6acab25
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0989.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0990.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0990.wav
new file mode 100644
index 0000000..2ba3f53
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0990.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0990.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0990.wavetable
new file mode 100644
index 0000000..5582d16
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0990.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0991.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0991.wav
new file mode 100644
index 0000000..c9618a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0991.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0991.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0991.wavetable
new file mode 100644
index 0000000..1841b24
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0991.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0992.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0992.wav
new file mode 100644
index 0000000..d1a9690
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0992.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0992.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0992.wavetable
new file mode 100644
index 0000000..23d6afa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0992.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0993.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0993.wav
new file mode 100644
index 0000000..2bb4070
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0993.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0993.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0993.wavetable
new file mode 100644
index 0000000..c16af30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0993.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0994.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0994.wav
new file mode 100644
index 0000000..62bcf83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0994.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0994.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0994.wavetable
new file mode 100644
index 0000000..d68b896
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0994.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0995.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0995.wav
new file mode 100644
index 0000000..0f63964
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0995.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0995.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0995.wavetable
new file mode 100644
index 0000000..857ad69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0995.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0996.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0996.wav
new file mode 100644
index 0000000..286d46a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0996.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0996.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0996.wavetable
new file mode 100644
index 0000000..57d2c22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0996.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0997.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0997.wav
new file mode 100644
index 0000000..b434221
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0997.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0997.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0997.wavetable
new file mode 100644
index 0000000..6ca3f32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0997.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0998.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0998.wav
new file mode 100644
index 0000000..a70ed00
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0998.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0998.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0998.wavetable
new file mode 100644
index 0000000..77c1044
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0998.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0999.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_0999.wav
new file mode 100644
index 0000000..16c6c99
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0999.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_0999.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_0999.wavetable
new file mode 100644
index 0000000..8abab1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_0999.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_1000.wav b/etc/wavetables/AKWF/AKWF_0010/AKWF_1000.wav
new file mode 100644
index 0000000..cde1819
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_1000.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AKWF_1000.wavetable b/etc/wavetables/AKWF/AKWF_0010/AKWF_1000.wavetable
new file mode 100644
index 0000000..f7efd00
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0010/AKWF_1000.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0010/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0010/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0010/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1001.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1001.wav
new file mode 100644
index 0000000..4aa6167
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1001.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1001.wavetable
new file mode 100644
index 0000000..8b158f8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1002.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1002.wav
new file mode 100644
index 0000000..12b1aa4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1002.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1002.wavetable
new file mode 100644
index 0000000..50484e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1003.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1003.wav
new file mode 100644
index 0000000..a9725a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1003.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1003.wavetable
new file mode 100644
index 0000000..e0202a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1004.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1004.wav
new file mode 100644
index 0000000..0344c5f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1004.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1004.wavetable
new file mode 100644
index 0000000..2dd8fec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1005.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1005.wav
new file mode 100644
index 0000000..c02d378
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1005.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1005.wavetable
new file mode 100644
index 0000000..1c8b7a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1006.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1006.wav
new file mode 100644
index 0000000..a982b6d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1006.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1006.wavetable
new file mode 100644
index 0000000..b137f0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1007.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1007.wav
new file mode 100644
index 0000000..ad2bcd5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1007.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1007.wavetable
new file mode 100644
index 0000000..ba29625
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1008.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1008.wav
new file mode 100644
index 0000000..3892e25
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1008.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1008.wavetable
new file mode 100644
index 0000000..190e4f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1009.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1009.wav
new file mode 100644
index 0000000..cb6f168
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1009.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1009.wavetable
new file mode 100644
index 0000000..d9a0765
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1010.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1010.wav
new file mode 100644
index 0000000..33deec3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1010.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1010.wavetable
new file mode 100644
index 0000000..e3280f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1011.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1011.wav
new file mode 100644
index 0000000..f693fc7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1011.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1011.wavetable
new file mode 100644
index 0000000..323c49a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1012.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1012.wav
new file mode 100644
index 0000000..19db4f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1012.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1012.wavetable
new file mode 100644
index 0000000..2c79437
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1013.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1013.wav
new file mode 100644
index 0000000..92fc837
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1013.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1013.wavetable
new file mode 100644
index 0000000..f64dad0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1014.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1014.wav
new file mode 100644
index 0000000..73d7999
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1014.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1014.wavetable
new file mode 100644
index 0000000..0054b10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1015.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1015.wav
new file mode 100644
index 0000000..0130352
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1015.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1015.wavetable
new file mode 100644
index 0000000..f6cc4ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1016.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1016.wav
new file mode 100644
index 0000000..f42993b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1016.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1016.wavetable
new file mode 100644
index 0000000..c7dc852
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1017.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1017.wav
new file mode 100644
index 0000000..719e582
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1017.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1017.wavetable
new file mode 100644
index 0000000..5bc7c0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1018.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1018.wav
new file mode 100644
index 0000000..c7ddfd8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1018.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1018.wavetable
new file mode 100644
index 0000000..2b3b99b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1019.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1019.wav
new file mode 100644
index 0000000..2a53baf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1019.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1019.wavetable
new file mode 100644
index 0000000..de36fe3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1020.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1020.wav
new file mode 100644
index 0000000..1eb506f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1020.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1020.wavetable
new file mode 100644
index 0000000..83e2d98
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1021.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1021.wav
new file mode 100644
index 0000000..0bf902f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1021.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1021.wavetable
new file mode 100644
index 0000000..45e8cb1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1022.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1022.wav
new file mode 100644
index 0000000..8bb2863
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1022.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1022.wavetable
new file mode 100644
index 0000000..037a9be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1023.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1023.wav
new file mode 100644
index 0000000..28fd0de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1023.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1023.wavetable
new file mode 100644
index 0000000..8dae849
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1024.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1024.wav
new file mode 100644
index 0000000..d68128b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1024.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1024.wavetable
new file mode 100644
index 0000000..90fbf23
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1025.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1025.wav
new file mode 100644
index 0000000..d94185e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1025.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1025.wavetable
new file mode 100644
index 0000000..f68a46d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1026.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1026.wav
new file mode 100644
index 0000000..2959b79
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1026.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1026.wavetable
new file mode 100644
index 0000000..492794a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1027.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1027.wav
new file mode 100644
index 0000000..c9593ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1027.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1027.wavetable
new file mode 100644
index 0000000..3d65cde
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1028.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1028.wav
new file mode 100644
index 0000000..173c972
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1028.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1028.wavetable
new file mode 100644
index 0000000..c458e63
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1029.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1029.wav
new file mode 100644
index 0000000..476d954
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1029.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1029.wavetable
new file mode 100644
index 0000000..e752acd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1030.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1030.wav
new file mode 100644
index 0000000..178ab48
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1030.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1030.wavetable
new file mode 100644
index 0000000..a86ad7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1031.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1031.wav
new file mode 100644
index 0000000..b76b370
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1031.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1031.wavetable
new file mode 100644
index 0000000..109138e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1032.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1032.wav
new file mode 100644
index 0000000..6194d14
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1032.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1032.wavetable
new file mode 100644
index 0000000..9aa8a94
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1033.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1033.wav
new file mode 100644
index 0000000..8436690
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1033.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1033.wavetable
new file mode 100644
index 0000000..6c9c269
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1034.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1034.wav
new file mode 100644
index 0000000..62e1c49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1034.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1034.wavetable
new file mode 100644
index 0000000..a53871c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1035.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1035.wav
new file mode 100644
index 0000000..cd5e2dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1035.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1035.wavetable
new file mode 100644
index 0000000..acae989
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1036.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1036.wav
new file mode 100644
index 0000000..f1320dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1036.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1036.wavetable
new file mode 100644
index 0000000..9c1dbe1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1037.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1037.wav
new file mode 100644
index 0000000..2445dde
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1037.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1037.wavetable
new file mode 100644
index 0000000..91b001f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1038.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1038.wav
new file mode 100644
index 0000000..9adbcae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1038.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1038.wavetable
new file mode 100644
index 0000000..747e51c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1039.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1039.wav
new file mode 100644
index 0000000..d102c01
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1039.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1039.wavetable
new file mode 100644
index 0000000..16117cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1040.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1040.wav
new file mode 100644
index 0000000..444966a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1040.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1040.wavetable
new file mode 100644
index 0000000..3b6f07c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1041.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1041.wav
new file mode 100644
index 0000000..e9a1af8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1041.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1041.wavetable
new file mode 100644
index 0000000..e355b0a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1042.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1042.wav
new file mode 100644
index 0000000..cdff4fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1042.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1042.wavetable
new file mode 100644
index 0000000..f03869b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1043.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1043.wav
new file mode 100644
index 0000000..f981324
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1043.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1043.wavetable
new file mode 100644
index 0000000..bc7233e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1044.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1044.wav
new file mode 100644
index 0000000..7949455
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1044.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1044.wavetable
new file mode 100644
index 0000000..e9f58c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1045.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1045.wav
new file mode 100644
index 0000000..bce9cb9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1045.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1045.wavetable
new file mode 100644
index 0000000..5d1b7de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1046.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1046.wav
new file mode 100644
index 0000000..c50565f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1046.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1046.wavetable
new file mode 100644
index 0000000..9bacf12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1047.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1047.wav
new file mode 100644
index 0000000..c71b60a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1047.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1047.wavetable
new file mode 100644
index 0000000..d645b6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1048.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1048.wav
new file mode 100644
index 0000000..3d327a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1048.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1048.wavetable
new file mode 100644
index 0000000..ddee697
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1049.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1049.wav
new file mode 100644
index 0000000..86da3e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1049.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1049.wavetable
new file mode 100644
index 0000000..b829f8f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1050.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1050.wav
new file mode 100644
index 0000000..efb263b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1050.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1050.wavetable
new file mode 100644
index 0000000..bd9a61f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1051.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1051.wav
new file mode 100644
index 0000000..97ed702
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1051.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1051.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1051.wavetable
new file mode 100644
index 0000000..13682b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1051.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1052.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1052.wav
new file mode 100644
index 0000000..6c7af0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1052.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1052.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1052.wavetable
new file mode 100644
index 0000000..6cfc0ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1052.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1053.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1053.wav
new file mode 100644
index 0000000..e7e1953
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1053.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1053.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1053.wavetable
new file mode 100644
index 0000000..36c6f6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1053.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1054.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1054.wav
new file mode 100644
index 0000000..1cbd9a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1054.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1054.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1054.wavetable
new file mode 100644
index 0000000..c902fd2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1054.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1055.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1055.wav
new file mode 100644
index 0000000..36006fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1055.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1055.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1055.wavetable
new file mode 100644
index 0000000..c0e4f4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1055.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1056.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1056.wav
new file mode 100644
index 0000000..dc31130
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1056.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1056.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1056.wavetable
new file mode 100644
index 0000000..10783a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1056.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1057.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1057.wav
new file mode 100644
index 0000000..aba249a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1057.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1057.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1057.wavetable
new file mode 100644
index 0000000..8db2f1f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1057.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1058.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1058.wav
new file mode 100644
index 0000000..b7d3446
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1058.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1058.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1058.wavetable
new file mode 100644
index 0000000..52c733e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1058.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1059.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1059.wav
new file mode 100644
index 0000000..b538397
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1059.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1059.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1059.wavetable
new file mode 100644
index 0000000..929467f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1059.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1060.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1060.wav
new file mode 100644
index 0000000..4e32aef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1060.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1060.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1060.wavetable
new file mode 100644
index 0000000..4824a24
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1060.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1061.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1061.wav
new file mode 100644
index 0000000..5ec0bb9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1061.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1061.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1061.wavetable
new file mode 100644
index 0000000..4a2c414
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1061.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1062.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1062.wav
new file mode 100644
index 0000000..b2c5a5e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1062.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1062.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1062.wavetable
new file mode 100644
index 0000000..295c000
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1062.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1063.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1063.wav
new file mode 100644
index 0000000..df6ff05
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1063.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1063.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1063.wavetable
new file mode 100644
index 0000000..9e5b721
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1063.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1064.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1064.wav
new file mode 100644
index 0000000..0042f33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1064.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1064.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1064.wavetable
new file mode 100644
index 0000000..7e81ca0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1064.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1065.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1065.wav
new file mode 100644
index 0000000..30ba5b7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1065.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1065.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1065.wavetable
new file mode 100644
index 0000000..73bad03
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1065.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1066.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1066.wav
new file mode 100644
index 0000000..a4cb2f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1066.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1066.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1066.wavetable
new file mode 100644
index 0000000..b0ecfc4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1066.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1067.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1067.wav
new file mode 100644
index 0000000..33d5f81
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1067.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1067.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1067.wavetable
new file mode 100644
index 0000000..ad1d049
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1067.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1068.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1068.wav
new file mode 100644
index 0000000..bb4eb00
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1068.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1068.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1068.wavetable
new file mode 100644
index 0000000..3ce8380
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1068.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1069.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1069.wav
new file mode 100644
index 0000000..8bd85dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1069.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1069.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1069.wavetable
new file mode 100644
index 0000000..e14925f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1069.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1070.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1070.wav
new file mode 100644
index 0000000..e918c0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1070.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1070.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1070.wavetable
new file mode 100644
index 0000000..111278e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1070.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1071.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1071.wav
new file mode 100644
index 0000000..bd3b49d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1071.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1071.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1071.wavetable
new file mode 100644
index 0000000..60bd6df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1071.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1072.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1072.wav
new file mode 100644
index 0000000..2cd4fa4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1072.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1072.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1072.wavetable
new file mode 100644
index 0000000..13ce1d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1072.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1073.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1073.wav
new file mode 100644
index 0000000..15043b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1073.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1073.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1073.wavetable
new file mode 100644
index 0000000..2e7eeec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1073.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1074.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1074.wav
new file mode 100644
index 0000000..c268d6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1074.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1074.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1074.wavetable
new file mode 100644
index 0000000..798e8de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1074.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1075.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1075.wav
new file mode 100644
index 0000000..b1d9f1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1075.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1075.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1075.wavetable
new file mode 100644
index 0000000..4afe705
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1075.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1076.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1076.wav
new file mode 100644
index 0000000..68a7278
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1076.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1076.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1076.wavetable
new file mode 100644
index 0000000..e646aed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1076.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1077.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1077.wav
new file mode 100644
index 0000000..baba490
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1077.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1077.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1077.wavetable
new file mode 100644
index 0000000..26c1ff3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1077.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1078.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1078.wav
new file mode 100644
index 0000000..02c7f94
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1078.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1078.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1078.wavetable
new file mode 100644
index 0000000..32d14d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1078.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1079.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1079.wav
new file mode 100644
index 0000000..023a52e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1079.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1079.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1079.wavetable
new file mode 100644
index 0000000..2e2e6c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1079.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1080.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1080.wav
new file mode 100644
index 0000000..7ed8d29
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1080.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1080.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1080.wavetable
new file mode 100644
index 0000000..fc305d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1080.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1081.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1081.wav
new file mode 100644
index 0000000..fed7686
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1081.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1081.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1081.wavetable
new file mode 100644
index 0000000..69327dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1081.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1082.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1082.wav
new file mode 100644
index 0000000..5956fb0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1082.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1082.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1082.wavetable
new file mode 100644
index 0000000..13078d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1082.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1083.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1083.wav
new file mode 100644
index 0000000..d3ce1be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1083.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1083.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1083.wavetable
new file mode 100644
index 0000000..5bb7e16
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1083.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1084.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1084.wav
new file mode 100644
index 0000000..a526bb5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1084.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1084.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1084.wavetable
new file mode 100644
index 0000000..3415c1d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1084.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1085.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1085.wav
new file mode 100644
index 0000000..306fac5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1085.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1085.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1085.wavetable
new file mode 100644
index 0000000..2042c34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1085.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1086.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1086.wav
new file mode 100644
index 0000000..3f86ebd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1086.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1086.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1086.wavetable
new file mode 100644
index 0000000..c113af6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1086.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1087.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1087.wav
new file mode 100644
index 0000000..fd6528e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1087.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1087.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1087.wavetable
new file mode 100644
index 0000000..69346a9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1087.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1088.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1088.wav
new file mode 100644
index 0000000..b7f1bf8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1088.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1088.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1088.wavetable
new file mode 100644
index 0000000..ad96505
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1088.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1089.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1089.wav
new file mode 100644
index 0000000..7250ce1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1089.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1089.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1089.wavetable
new file mode 100644
index 0000000..cfdc96a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1089.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1090.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1090.wav
new file mode 100644
index 0000000..49986db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1090.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1090.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1090.wavetable
new file mode 100644
index 0000000..8af42bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1090.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1091.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1091.wav
new file mode 100644
index 0000000..5fc0e93
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1091.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1091.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1091.wavetable
new file mode 100644
index 0000000..c9a6774
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1091.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1092.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1092.wav
new file mode 100644
index 0000000..76cddf1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1092.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1092.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1092.wavetable
new file mode 100644
index 0000000..2a2f83b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1092.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1093.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1093.wav
new file mode 100644
index 0000000..9820bfe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1093.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1093.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1093.wavetable
new file mode 100644
index 0000000..3208bb2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1093.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1094.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1094.wav
new file mode 100644
index 0000000..054d936
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1094.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1094.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1094.wavetable
new file mode 100644
index 0000000..ab222f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1094.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1095.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1095.wav
new file mode 100644
index 0000000..62202ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1095.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1095.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1095.wavetable
new file mode 100644
index 0000000..5b7ea97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1095.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1096.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1096.wav
new file mode 100644
index 0000000..b85bfe6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1096.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1096.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1096.wavetable
new file mode 100644
index 0000000..7b4d493
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1096.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1097.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1097.wav
new file mode 100644
index 0000000..cbbac03
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1097.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1097.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1097.wavetable
new file mode 100644
index 0000000..01161b3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1097.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1098.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1098.wav
new file mode 100644
index 0000000..12ed650
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1098.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1098.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1098.wavetable
new file mode 100644
index 0000000..0111352
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1098.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1099.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1099.wav
new file mode 100644
index 0000000..b6f6604
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1099.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1099.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1099.wavetable
new file mode 100644
index 0000000..e2a55e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1099.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1100.wav b/etc/wavetables/AKWF/AKWF_0011/AKWF_1100.wav
new file mode 100644
index 0000000..9d936c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1100.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AKWF_1100.wavetable b/etc/wavetables/AKWF/AKWF_0011/AKWF_1100.wavetable
new file mode 100644
index 0000000..4e30c3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0011/AKWF_1100.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0011/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0011/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0011/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1101.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1101.wav
new file mode 100644
index 0000000..e0bc2ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1101.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1101.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1101.wavetable
new file mode 100644
index 0000000..7b7ff91
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1101.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1102.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1102.wav
new file mode 100644
index 0000000..8f9050c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1102.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1102.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1102.wavetable
new file mode 100644
index 0000000..15c68b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1102.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1103.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1103.wav
new file mode 100644
index 0000000..5b2ad2a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1103.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1103.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1103.wavetable
new file mode 100644
index 0000000..fe5ea4e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1103.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1104.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1104.wav
new file mode 100644
index 0000000..e11d7b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1104.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1104.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1104.wavetable
new file mode 100644
index 0000000..d26ff80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1104.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1105.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1105.wav
new file mode 100644
index 0000000..3dafa44
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1105.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1105.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1105.wavetable
new file mode 100644
index 0000000..6083457
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1105.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1106.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1106.wav
new file mode 100644
index 0000000..ab7df90
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1106.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1106.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1106.wavetable
new file mode 100644
index 0000000..fcb9e62
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1106.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1107.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1107.wav
new file mode 100644
index 0000000..e245862
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1107.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1107.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1107.wavetable
new file mode 100644
index 0000000..f5389cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1107.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1108.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1108.wav
new file mode 100644
index 0000000..1068f91
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1108.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1108.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1108.wavetable
new file mode 100644
index 0000000..6b8bad5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1108.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1109.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1109.wav
new file mode 100644
index 0000000..32b22fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1109.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1109.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1109.wavetable
new file mode 100644
index 0000000..9e859d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1109.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1110.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1110.wav
new file mode 100644
index 0000000..d38c1a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1110.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1110.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1110.wavetable
new file mode 100644
index 0000000..e6c420b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1110.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1111.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1111.wav
new file mode 100644
index 0000000..c68e813
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1111.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1111.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1111.wavetable
new file mode 100644
index 0000000..8354e65
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1111.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1112.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1112.wav
new file mode 100644
index 0000000..f60804f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1112.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1112.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1112.wavetable
new file mode 100644
index 0000000..d2fb713
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1112.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1113.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1113.wav
new file mode 100644
index 0000000..b06cebb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1113.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1113.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1113.wavetable
new file mode 100644
index 0000000..966d3cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1113.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1114.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1114.wav
new file mode 100644
index 0000000..0936382
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1114.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1114.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1114.wavetable
new file mode 100644
index 0000000..9c88a71
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1114.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1115.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1115.wav
new file mode 100644
index 0000000..67f8e88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1115.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1115.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1115.wavetable
new file mode 100644
index 0000000..910abff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1115.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1116.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1116.wav
new file mode 100644
index 0000000..6f29881
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1116.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1116.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1116.wavetable
new file mode 100644
index 0000000..b94bc3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1116.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1117.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1117.wav
new file mode 100644
index 0000000..8d5f7d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1117.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1117.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1117.wavetable
new file mode 100644
index 0000000..91994d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1117.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1118.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1118.wav
new file mode 100644
index 0000000..4bc1055
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1118.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1118.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1118.wavetable
new file mode 100644
index 0000000..40d3e4a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1118.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1119.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1119.wav
new file mode 100644
index 0000000..1dac758
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1119.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1119.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1119.wavetable
new file mode 100644
index 0000000..cf9b8a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1119.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1120.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1120.wav
new file mode 100644
index 0000000..9c4bb81
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1120.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1120.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1120.wavetable
new file mode 100644
index 0000000..e897153
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1120.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1121.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1121.wav
new file mode 100644
index 0000000..625bdc8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1121.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1121.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1121.wavetable
new file mode 100644
index 0000000..00a561d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1121.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1122.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1122.wav
new file mode 100644
index 0000000..83e3d83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1122.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1122.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1122.wavetable
new file mode 100644
index 0000000..be2b3e2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1122.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1123.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1123.wav
new file mode 100644
index 0000000..19be176
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1123.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1123.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1123.wavetable
new file mode 100644
index 0000000..e1550ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1123.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1124.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1124.wav
new file mode 100644
index 0000000..172144d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1124.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1124.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1124.wavetable
new file mode 100644
index 0000000..f88d45b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1124.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1125.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1125.wav
new file mode 100644
index 0000000..83d8bbb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1125.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1125.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1125.wavetable
new file mode 100644
index 0000000..ac31c0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1125.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1126.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1126.wav
new file mode 100644
index 0000000..2f999b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1126.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1126.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1126.wavetable
new file mode 100644
index 0000000..27e4a7c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1126.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1127.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1127.wav
new file mode 100644
index 0000000..313239a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1127.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1127.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1127.wavetable
new file mode 100644
index 0000000..ba76fa7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1127.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1128.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1128.wav
new file mode 100644
index 0000000..65f1072
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1128.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1128.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1128.wavetable
new file mode 100644
index 0000000..e4bba43
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1128.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1129.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1129.wav
new file mode 100644
index 0000000..ff206d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1129.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1129.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1129.wavetable
new file mode 100644
index 0000000..257a294
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1129.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1130.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1130.wav
new file mode 100644
index 0000000..21a39ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1130.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1130.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1130.wavetable
new file mode 100644
index 0000000..5e75a68
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1130.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1131.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1131.wav
new file mode 100644
index 0000000..3c28b44
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1131.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1131.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1131.wavetable
new file mode 100644
index 0000000..ad7b5ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1131.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1132.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1132.wav
new file mode 100644
index 0000000..e31ba25
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1132.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1132.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1132.wavetable
new file mode 100644
index 0000000..da743d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1132.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1133.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1133.wav
new file mode 100644
index 0000000..2b75dd2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1133.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1133.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1133.wavetable
new file mode 100644
index 0000000..7f042c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1133.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1134.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1134.wav
new file mode 100644
index 0000000..8123252
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1134.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1134.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1134.wavetable
new file mode 100644
index 0000000..76bdadc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1134.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1135.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1135.wav
new file mode 100644
index 0000000..e2b6a42
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1135.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1135.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1135.wavetable
new file mode 100644
index 0000000..091a599
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1135.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1136.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1136.wav
new file mode 100644
index 0000000..1bbdc95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1136.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1136.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1136.wavetable
new file mode 100644
index 0000000..1b91ead
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1136.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1137.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1137.wav
new file mode 100644
index 0000000..de9efcc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1137.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1137.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1137.wavetable
new file mode 100644
index 0000000..65cd3dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1137.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1138.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1138.wav
new file mode 100644
index 0000000..01ff86b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1138.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1138.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1138.wavetable
new file mode 100644
index 0000000..ab18b34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1138.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1139.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1139.wav
new file mode 100644
index 0000000..9b3ff50
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1139.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1139.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1139.wavetable
new file mode 100644
index 0000000..29f21f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1139.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1140.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1140.wav
new file mode 100644
index 0000000..f9d812d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1140.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1140.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1140.wavetable
new file mode 100644
index 0000000..9a5662a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1140.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1141.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1141.wav
new file mode 100644
index 0000000..910c40a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1141.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1141.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1141.wavetable
new file mode 100644
index 0000000..ba88a63
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1141.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1142.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1142.wav
new file mode 100644
index 0000000..d202988
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1142.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1142.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1142.wavetable
new file mode 100644
index 0000000..503bebc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1142.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1143.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1143.wav
new file mode 100644
index 0000000..aaa313c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1143.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1143.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1143.wavetable
new file mode 100644
index 0000000..2f0bcba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1143.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1144.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1144.wav
new file mode 100644
index 0000000..6644fbc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1144.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1144.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1144.wavetable
new file mode 100644
index 0000000..835ebd3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1144.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1145.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1145.wav
new file mode 100644
index 0000000..8c06afd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1145.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1145.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1145.wavetable
new file mode 100644
index 0000000..2873b20
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1145.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1146.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1146.wav
new file mode 100644
index 0000000..34acb3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1146.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1146.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1146.wavetable
new file mode 100644
index 0000000..d2d2000
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1146.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1147.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1147.wav
new file mode 100644
index 0000000..b6c3bb6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1147.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1147.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1147.wavetable
new file mode 100644
index 0000000..1b0c85c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1147.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1148.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1148.wav
new file mode 100644
index 0000000..4bb75c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1148.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1148.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1148.wavetable
new file mode 100644
index 0000000..980380b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1148.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1149.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1149.wav
new file mode 100644
index 0000000..5e3e4dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1149.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1149.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1149.wavetable
new file mode 100644
index 0000000..d18ac7d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1149.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1150.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1150.wav
new file mode 100644
index 0000000..118b7cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1150.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1150.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1150.wavetable
new file mode 100644
index 0000000..383c1f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1150.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1151.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1151.wav
new file mode 100644
index 0000000..6ca7db3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1151.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1151.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1151.wavetable
new file mode 100644
index 0000000..92b562a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1151.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1152.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1152.wav
new file mode 100644
index 0000000..9ba2aa3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1152.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1152.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1152.wavetable
new file mode 100644
index 0000000..c9b5212
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1152.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1153.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1153.wav
new file mode 100644
index 0000000..39b5815
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1153.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1153.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1153.wavetable
new file mode 100644
index 0000000..64dea5e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1153.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1154.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1154.wav
new file mode 100644
index 0000000..85ffbfe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1154.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1154.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1154.wavetable
new file mode 100644
index 0000000..4fa53d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1154.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1155.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1155.wav
new file mode 100644
index 0000000..84c0fd6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1155.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1155.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1155.wavetable
new file mode 100644
index 0000000..f3ac133
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1155.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1156.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1156.wav
new file mode 100644
index 0000000..875cb69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1156.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1156.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1156.wavetable
new file mode 100644
index 0000000..05b2199
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1156.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1157.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1157.wav
new file mode 100644
index 0000000..625d8c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1157.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1157.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1157.wavetable
new file mode 100644
index 0000000..d9d3fd5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1157.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1158.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1158.wav
new file mode 100644
index 0000000..c324095
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1158.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1158.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1158.wavetable
new file mode 100644
index 0000000..1a28a7a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1158.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1159.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1159.wav
new file mode 100644
index 0000000..f29eeee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1159.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1159.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1159.wavetable
new file mode 100644
index 0000000..ce8caa1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1159.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1160.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1160.wav
new file mode 100644
index 0000000..d07edf5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1160.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1160.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1160.wavetable
new file mode 100644
index 0000000..742d3d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1160.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1161.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1161.wav
new file mode 100644
index 0000000..c6f70bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1161.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1161.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1161.wavetable
new file mode 100644
index 0000000..9f012cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1161.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1162.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1162.wav
new file mode 100644
index 0000000..27e409f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1162.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1162.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1162.wavetable
new file mode 100644
index 0000000..c5df3d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1162.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1163.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1163.wav
new file mode 100644
index 0000000..b8c53f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1163.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1163.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1163.wavetable
new file mode 100644
index 0000000..2cf0340
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1163.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1164.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1164.wav
new file mode 100644
index 0000000..6450914
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1164.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1164.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1164.wavetable
new file mode 100644
index 0000000..00c4700
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1164.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1165.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1165.wav
new file mode 100644
index 0000000..acb6b4a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1165.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1165.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1165.wavetable
new file mode 100644
index 0000000..283f20f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1165.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1166.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1166.wav
new file mode 100644
index 0000000..384a55d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1166.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1166.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1166.wavetable
new file mode 100644
index 0000000..427f268
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1166.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1167.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1167.wav
new file mode 100644
index 0000000..5fa7d4e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1167.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1167.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1167.wavetable
new file mode 100644
index 0000000..2308ade
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1167.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1168.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1168.wav
new file mode 100644
index 0000000..013cb2d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1168.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1168.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1168.wavetable
new file mode 100644
index 0000000..b0f04ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1168.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1169.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1169.wav
new file mode 100644
index 0000000..c1aa44b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1169.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1169.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1169.wavetable
new file mode 100644
index 0000000..7eade2f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1169.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1170.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1170.wav
new file mode 100644
index 0000000..e454c9f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1170.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1170.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1170.wavetable
new file mode 100644
index 0000000..46c191e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1170.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1171.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1171.wav
new file mode 100644
index 0000000..6ea1093
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1171.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1171.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1171.wavetable
new file mode 100644
index 0000000..2e87236
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1171.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1172.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1172.wav
new file mode 100644
index 0000000..fe04168
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1172.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1172.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1172.wavetable
new file mode 100644
index 0000000..9ef9688
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1172.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1173.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1173.wav
new file mode 100644
index 0000000..9186d65
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1173.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1173.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1173.wavetable
new file mode 100644
index 0000000..4fef056
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1173.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1174.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1174.wav
new file mode 100644
index 0000000..b1f72ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1174.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1174.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1174.wavetable
new file mode 100644
index 0000000..d9f657f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1174.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1175.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1175.wav
new file mode 100644
index 0000000..20119f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1175.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1175.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1175.wavetable
new file mode 100644
index 0000000..158e6f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1175.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1176.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1176.wav
new file mode 100644
index 0000000..69596e2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1176.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1176.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1176.wavetable
new file mode 100644
index 0000000..2284b9b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1176.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1177.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1177.wav
new file mode 100644
index 0000000..57ad5f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1177.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1177.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1177.wavetable
new file mode 100644
index 0000000..7a6a67b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1177.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1178.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1178.wav
new file mode 100644
index 0000000..a497bce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1178.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1178.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1178.wavetable
new file mode 100644
index 0000000..e4a8a4b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1178.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1179.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1179.wav
new file mode 100644
index 0000000..75e8867
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1179.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1179.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1179.wavetable
new file mode 100644
index 0000000..0513c9c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1179.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1180.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1180.wav
new file mode 100644
index 0000000..94c49c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1180.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1180.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1180.wavetable
new file mode 100644
index 0000000..9c4913c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1180.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1181.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1181.wav
new file mode 100644
index 0000000..52d2b94
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1181.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1181.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1181.wavetable
new file mode 100644
index 0000000..635fbba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1181.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1182.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1182.wav
new file mode 100644
index 0000000..0a0922c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1182.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1182.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1182.wavetable
new file mode 100644
index 0000000..311e904
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1182.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1183.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1183.wav
new file mode 100644
index 0000000..52c1aa2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1183.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1183.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1183.wavetable
new file mode 100644
index 0000000..7c0d8ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1183.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1184.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1184.wav
new file mode 100644
index 0000000..b486f5e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1184.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1184.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1184.wavetable
new file mode 100644
index 0000000..350ffd8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1184.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1185.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1185.wav
new file mode 100644
index 0000000..231a408
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1185.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1185.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1185.wavetable
new file mode 100644
index 0000000..c237b11
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1185.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1186.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1186.wav
new file mode 100644
index 0000000..f00e67e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1186.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1186.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1186.wavetable
new file mode 100644
index 0000000..4fa237c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1186.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1187.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1187.wav
new file mode 100644
index 0000000..310c3f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1187.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1187.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1187.wavetable
new file mode 100644
index 0000000..761827c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1187.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1188.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1188.wav
new file mode 100644
index 0000000..86c4069
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1188.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1188.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1188.wavetable
new file mode 100644
index 0000000..c2856a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1188.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1189.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1189.wav
new file mode 100644
index 0000000..50426f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1189.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1189.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1189.wavetable
new file mode 100644
index 0000000..05455aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1189.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1190.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1190.wav
new file mode 100644
index 0000000..8def78f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1190.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1190.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1190.wavetable
new file mode 100644
index 0000000..ac6e030
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1190.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1191.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1191.wav
new file mode 100644
index 0000000..5c55528
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1191.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1191.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1191.wavetable
new file mode 100644
index 0000000..c95de5f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1191.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1192.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1192.wav
new file mode 100644
index 0000000..f4a4434
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1192.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1192.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1192.wavetable
new file mode 100644
index 0000000..3f6d5d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1192.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1193.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1193.wav
new file mode 100644
index 0000000..cea677e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1193.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1193.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1193.wavetable
new file mode 100644
index 0000000..ca08967
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1193.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1194.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1194.wav
new file mode 100644
index 0000000..da82462
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1194.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1194.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1194.wavetable
new file mode 100644
index 0000000..ba6587d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1194.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1195.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1195.wav
new file mode 100644
index 0000000..cb86a0a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1195.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1195.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1195.wavetable
new file mode 100644
index 0000000..a8101ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1195.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1196.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1196.wav
new file mode 100644
index 0000000..9149fb8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1196.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1196.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1196.wavetable
new file mode 100644
index 0000000..a43f640
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1196.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1197.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1197.wav
new file mode 100644
index 0000000..0827a5e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1197.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1197.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1197.wavetable
new file mode 100644
index 0000000..235dc99
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1197.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1198.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1198.wav
new file mode 100644
index 0000000..4a869e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1198.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1198.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1198.wavetable
new file mode 100644
index 0000000..080db26
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1198.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1199.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1199.wav
new file mode 100644
index 0000000..38f02b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1199.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1199.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1199.wavetable
new file mode 100644
index 0000000..09a7185
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1199.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1200.wav b/etc/wavetables/AKWF/AKWF_0012/AKWF_1200.wav
new file mode 100644
index 0000000..ea6c0cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1200.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AKWF_1200.wavetable b/etc/wavetables/AKWF/AKWF_0012/AKWF_1200.wavetable
new file mode 100644
index 0000000..c0249ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0012/AKWF_1200.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0012/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0012/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0012/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1201.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1201.wav
new file mode 100644
index 0000000..2564c37
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1201.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1201.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1201.wavetable
new file mode 100644
index 0000000..ecf9c60
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1201.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1202.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1202.wav
new file mode 100644
index 0000000..8c82694
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1202.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1202.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1202.wavetable
new file mode 100644
index 0000000..feb0d8e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1202.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1203.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1203.wav
new file mode 100644
index 0000000..1c42459
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1203.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1203.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1203.wavetable
new file mode 100644
index 0000000..72104f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1203.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1204.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1204.wav
new file mode 100644
index 0000000..3890046
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1204.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1204.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1204.wavetable
new file mode 100644
index 0000000..80ce2ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1204.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1205.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1205.wav
new file mode 100644
index 0000000..e9b4b97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1205.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1205.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1205.wavetable
new file mode 100644
index 0000000..ab7e457
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1205.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1206.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1206.wav
new file mode 100644
index 0000000..c6b072a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1206.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1206.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1206.wavetable
new file mode 100644
index 0000000..87284ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1206.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1207.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1207.wav
new file mode 100644
index 0000000..35d103d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1207.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1207.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1207.wavetable
new file mode 100644
index 0000000..f426be9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1207.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1208.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1208.wav
new file mode 100644
index 0000000..e5b48ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1208.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1208.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1208.wavetable
new file mode 100644
index 0000000..7d94a82
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1208.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1209.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1209.wav
new file mode 100644
index 0000000..477c5f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1209.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1209.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1209.wavetable
new file mode 100644
index 0000000..9e49795
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1209.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1210.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1210.wav
new file mode 100644
index 0000000..5b292fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1210.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1210.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1210.wavetable
new file mode 100644
index 0000000..abcc820
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1210.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1211.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1211.wav
new file mode 100644
index 0000000..29c2232
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1211.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1211.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1211.wavetable
new file mode 100644
index 0000000..241cca1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1211.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1212.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1212.wav
new file mode 100644
index 0000000..8dd1611
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1212.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1212.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1212.wavetable
new file mode 100644
index 0000000..ef86cf4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1212.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1213.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1213.wav
new file mode 100644
index 0000000..e4c11e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1213.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1213.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1213.wavetable
new file mode 100644
index 0000000..3541c88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1213.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1214.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1214.wav
new file mode 100644
index 0000000..d6e3798
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1214.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1214.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1214.wavetable
new file mode 100644
index 0000000..63d4408
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1214.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1215.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1215.wav
new file mode 100644
index 0000000..8a24165
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1215.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1215.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1215.wavetable
new file mode 100644
index 0000000..2a8edce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1215.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1216.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1216.wav
new file mode 100644
index 0000000..113910c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1216.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1216.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1216.wavetable
new file mode 100644
index 0000000..a6614c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1216.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1217.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1217.wav
new file mode 100644
index 0000000..19cb300
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1217.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1217.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1217.wavetable
new file mode 100644
index 0000000..085caa5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1217.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1218.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1218.wav
new file mode 100644
index 0000000..7099308
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1218.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1218.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1218.wavetable
new file mode 100644
index 0000000..641e7bd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1218.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1219.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1219.wav
new file mode 100644
index 0000000..578b5f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1219.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1219.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1219.wavetable
new file mode 100644
index 0000000..9c24d5f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1219.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1220.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1220.wav
new file mode 100644
index 0000000..9daafe3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1220.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1220.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1220.wavetable
new file mode 100644
index 0000000..407971e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1220.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1221.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1221.wav
new file mode 100644
index 0000000..a2ec368
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1221.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1221.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1221.wavetable
new file mode 100644
index 0000000..a5b4af9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1221.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1222.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1222.wav
new file mode 100644
index 0000000..d092362
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1222.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1222.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1222.wavetable
new file mode 100644
index 0000000..3cd1520
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1222.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1223.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1223.wav
new file mode 100644
index 0000000..778ad28
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1223.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1223.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1223.wavetable
new file mode 100644
index 0000000..db636bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1223.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1224.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1224.wav
new file mode 100644
index 0000000..f0b0afc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1224.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1224.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1224.wavetable
new file mode 100644
index 0000000..f2e595a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1224.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1225.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1225.wav
new file mode 100644
index 0000000..11df81e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1225.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1225.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1225.wavetable
new file mode 100644
index 0000000..eccf42f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1225.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1226.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1226.wav
new file mode 100644
index 0000000..6e50e2d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1226.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1226.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1226.wavetable
new file mode 100644
index 0000000..5257956
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1226.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1227.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1227.wav
new file mode 100644
index 0000000..5de6aa7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1227.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1227.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1227.wavetable
new file mode 100644
index 0000000..e23633a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1227.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1228.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1228.wav
new file mode 100644
index 0000000..799184f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1228.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1228.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1228.wavetable
new file mode 100644
index 0000000..6198bad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1228.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1229.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1229.wav
new file mode 100644
index 0000000..e3ae182
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1229.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1229.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1229.wavetable
new file mode 100644
index 0000000..8b4aa2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1229.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1230.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1230.wav
new file mode 100644
index 0000000..22e57fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1230.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1230.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1230.wavetable
new file mode 100644
index 0000000..91772f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1230.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1231.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1231.wav
new file mode 100644
index 0000000..5434f14
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1231.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1231.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1231.wavetable
new file mode 100644
index 0000000..49c64ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1231.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1232.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1232.wav
new file mode 100644
index 0000000..101e3bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1232.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1232.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1232.wavetable
new file mode 100644
index 0000000..e679c55
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1232.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1233.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1233.wav
new file mode 100644
index 0000000..e42e58e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1233.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1233.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1233.wavetable
new file mode 100644
index 0000000..a3c39d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1233.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1234.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1234.wav
new file mode 100644
index 0000000..d8553e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1234.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1234.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1234.wavetable
new file mode 100644
index 0000000..034cbcd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1234.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1235.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1235.wav
new file mode 100644
index 0000000..ded196a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1235.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1235.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1235.wavetable
new file mode 100644
index 0000000..f2c4d77
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1235.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1236.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1236.wav
new file mode 100644
index 0000000..38c3604
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1236.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1236.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1236.wavetable
new file mode 100644
index 0000000..fc9e5c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1236.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1237.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1237.wav
new file mode 100644
index 0000000..3b4fa4e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1237.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1237.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1237.wavetable
new file mode 100644
index 0000000..128225c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1237.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1238.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1238.wav
new file mode 100644
index 0000000..4e5df9f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1238.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1238.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1238.wavetable
new file mode 100644
index 0000000..7e19471
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1238.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1239.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1239.wav
new file mode 100644
index 0000000..9c062d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1239.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1239.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1239.wavetable
new file mode 100644
index 0000000..2cfbf90
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1239.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1240.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1240.wav
new file mode 100644
index 0000000..ba9a181
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1240.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1240.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1240.wavetable
new file mode 100644
index 0000000..a4fffe2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1240.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1241.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1241.wav
new file mode 100644
index 0000000..7b0b22f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1241.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1241.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1241.wavetable
new file mode 100644
index 0000000..8c7a6d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1241.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1242.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1242.wav
new file mode 100644
index 0000000..ae35acc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1242.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1242.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1242.wavetable
new file mode 100644
index 0000000..6ed44c7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1242.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1243.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1243.wav
new file mode 100644
index 0000000..2808f4a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1243.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1243.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1243.wavetable
new file mode 100644
index 0000000..27578e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1243.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1244.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1244.wav
new file mode 100644
index 0000000..37eab60
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1244.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1244.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1244.wavetable
new file mode 100644
index 0000000..aae28c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1244.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1245.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1245.wav
new file mode 100644
index 0000000..a95767b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1245.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1245.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1245.wavetable
new file mode 100644
index 0000000..8bb5973
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1245.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1246.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1246.wav
new file mode 100644
index 0000000..f5fa2f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1246.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1246.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1246.wavetable
new file mode 100644
index 0000000..043e6c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1246.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1247.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1247.wav
new file mode 100644
index 0000000..f4f5a94
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1247.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1247.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1247.wavetable
new file mode 100644
index 0000000..7bae942
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1247.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1248.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1248.wav
new file mode 100644
index 0000000..d38583e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1248.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1248.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1248.wavetable
new file mode 100644
index 0000000..59997b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1248.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1249.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1249.wav
new file mode 100644
index 0000000..6e0c3ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1249.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1249.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1249.wavetable
new file mode 100644
index 0000000..6c03caa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1249.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1250.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1250.wav
new file mode 100644
index 0000000..cada3b7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1250.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1250.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1250.wavetable
new file mode 100644
index 0000000..b7d1a23
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1250.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1251.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1251.wav
new file mode 100644
index 0000000..e447a77
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1251.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1251.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1251.wavetable
new file mode 100644
index 0000000..fce198b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1251.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1252.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1252.wav
new file mode 100644
index 0000000..56b02c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1252.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1252.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1252.wavetable
new file mode 100644
index 0000000..09c636b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1252.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1253.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1253.wav
new file mode 100644
index 0000000..34bf5df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1253.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1253.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1253.wavetable
new file mode 100644
index 0000000..8125d5d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1253.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1254.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1254.wav
new file mode 100644
index 0000000..c4739af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1254.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1254.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1254.wavetable
new file mode 100644
index 0000000..bb8098f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1254.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1255.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1255.wav
new file mode 100644
index 0000000..7767015
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1255.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1255.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1255.wavetable
new file mode 100644
index 0000000..1ca04f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1255.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1256.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1256.wav
new file mode 100644
index 0000000..7aa856b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1256.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1256.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1256.wavetable
new file mode 100644
index 0000000..9fccee7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1256.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1257.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1257.wav
new file mode 100644
index 0000000..6f30ef3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1257.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1257.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1257.wavetable
new file mode 100644
index 0000000..d1b9293
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1257.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1258.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1258.wav
new file mode 100644
index 0000000..d80dbf0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1258.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1258.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1258.wavetable
new file mode 100644
index 0000000..0daea38
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1258.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1259.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1259.wav
new file mode 100644
index 0000000..9ff91f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1259.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1259.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1259.wavetable
new file mode 100644
index 0000000..566eb25
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1259.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1260.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1260.wav
new file mode 100644
index 0000000..e6a1908
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1260.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1260.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1260.wavetable
new file mode 100644
index 0000000..4d30850
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1260.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1261.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1261.wav
new file mode 100644
index 0000000..c5589be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1261.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1261.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1261.wavetable
new file mode 100644
index 0000000..1e1fe0c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1261.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1262.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1262.wav
new file mode 100644
index 0000000..00a1303
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1262.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1262.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1262.wavetable
new file mode 100644
index 0000000..c890e6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1262.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1263.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1263.wav
new file mode 100644
index 0000000..7293521
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1263.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1263.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1263.wavetable
new file mode 100644
index 0000000..f99098d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1263.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1264.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1264.wav
new file mode 100644
index 0000000..0566950
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1264.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1264.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1264.wavetable
new file mode 100644
index 0000000..87db4fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1264.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1265.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1265.wav
new file mode 100644
index 0000000..49cb430
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1265.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1265.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1265.wavetable
new file mode 100644
index 0000000..49037e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1265.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1266.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1266.wav
new file mode 100644
index 0000000..e20b922
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1266.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1266.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1266.wavetable
new file mode 100644
index 0000000..183b4da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1266.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1267.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1267.wav
new file mode 100644
index 0000000..9127622
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1267.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1267.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1267.wavetable
new file mode 100644
index 0000000..2cd1953
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1267.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1268.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1268.wav
new file mode 100644
index 0000000..f3d9605
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1268.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1268.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1268.wavetable
new file mode 100644
index 0000000..a57c078
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1268.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1269.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1269.wav
new file mode 100644
index 0000000..41da082
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1269.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1269.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1269.wavetable
new file mode 100644
index 0000000..5ea70ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1269.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1270.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1270.wav
new file mode 100644
index 0000000..2be6695
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1270.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1270.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1270.wavetable
new file mode 100644
index 0000000..fc3132b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1270.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1271.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1271.wav
new file mode 100644
index 0000000..5a03f39
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1271.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1271.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1271.wavetable
new file mode 100644
index 0000000..d112892
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1271.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1272.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1272.wav
new file mode 100644
index 0000000..309cecf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1272.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1272.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1272.wavetable
new file mode 100644
index 0000000..33122ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1272.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1273.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1273.wav
new file mode 100644
index 0000000..bbabdd1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1273.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1273.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1273.wavetable
new file mode 100644
index 0000000..0996d59
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1273.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1274.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1274.wav
new file mode 100644
index 0000000..14fc8c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1274.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1274.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1274.wavetable
new file mode 100644
index 0000000..88db399
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1274.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1275.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1275.wav
new file mode 100644
index 0000000..ba757c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1275.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1275.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1275.wavetable
new file mode 100644
index 0000000..5ccd608
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1275.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1276.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1276.wav
new file mode 100644
index 0000000..c9a5979
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1276.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1276.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1276.wavetable
new file mode 100644
index 0000000..fca798c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1276.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1277.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1277.wav
new file mode 100644
index 0000000..36790e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1277.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1277.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1277.wavetable
new file mode 100644
index 0000000..fa14a6f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1277.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1278.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1278.wav
new file mode 100644
index 0000000..0affb35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1278.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1278.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1278.wavetable
new file mode 100644
index 0000000..564adfa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1278.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1279.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1279.wav
new file mode 100644
index 0000000..f3ef049
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1279.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1279.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1279.wavetable
new file mode 100644
index 0000000..23f89d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1279.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1280.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1280.wav
new file mode 100644
index 0000000..9013809
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1280.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1280.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1280.wavetable
new file mode 100644
index 0000000..d970e6e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1280.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1281.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1281.wav
new file mode 100644
index 0000000..11186fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1281.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1281.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1281.wavetable
new file mode 100644
index 0000000..5f51c60
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1281.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1282.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1282.wav
new file mode 100644
index 0000000..0e8fc23
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1282.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1282.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1282.wavetable
new file mode 100644
index 0000000..d25af38
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1282.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1283.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1283.wav
new file mode 100644
index 0000000..053e982
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1283.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1283.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1283.wavetable
new file mode 100644
index 0000000..4bcb9e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1283.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1284.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1284.wav
new file mode 100644
index 0000000..81f7921
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1284.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1284.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1284.wavetable
new file mode 100644
index 0000000..4565183
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1284.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1285.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1285.wav
new file mode 100644
index 0000000..1b8f961
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1285.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1285.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1285.wavetable
new file mode 100644
index 0000000..dcf7b9c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1285.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1286.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1286.wav
new file mode 100644
index 0000000..d0708f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1286.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1286.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1286.wavetable
new file mode 100644
index 0000000..f8eb548
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1286.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1287.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1287.wav
new file mode 100644
index 0000000..a44ce4f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1287.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1287.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1287.wavetable
new file mode 100644
index 0000000..a08c39b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1287.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1288.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1288.wav
new file mode 100644
index 0000000..d7155bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1288.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1288.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1288.wavetable
new file mode 100644
index 0000000..a7312fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1288.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1289.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1289.wav
new file mode 100644
index 0000000..1496a52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1289.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1289.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1289.wavetable
new file mode 100644
index 0000000..af4da43
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1289.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1290.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1290.wav
new file mode 100644
index 0000000..74c2610
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1290.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1290.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1290.wavetable
new file mode 100644
index 0000000..6798a72
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1290.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1291.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1291.wav
new file mode 100644
index 0000000..afa708a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1291.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1291.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1291.wavetable
new file mode 100644
index 0000000..968e81f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1291.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1292.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1292.wav
new file mode 100644
index 0000000..fa91bc9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1292.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1292.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1292.wavetable
new file mode 100644
index 0000000..441df7a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1292.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1293.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1293.wav
new file mode 100644
index 0000000..ed46677
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1293.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1293.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1293.wavetable
new file mode 100644
index 0000000..e9cb611
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1293.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1294.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1294.wav
new file mode 100644
index 0000000..76ae2c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1294.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1294.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1294.wavetable
new file mode 100644
index 0000000..bc40dac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1294.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1295.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1295.wav
new file mode 100644
index 0000000..ece35bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1295.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1295.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1295.wavetable
new file mode 100644
index 0000000..56cc382
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1295.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1296.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1296.wav
new file mode 100644
index 0000000..9d47a2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1296.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1296.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1296.wavetable
new file mode 100644
index 0000000..df3debd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1296.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1297.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1297.wav
new file mode 100644
index 0000000..130f035
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1297.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1297.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1297.wavetable
new file mode 100644
index 0000000..3df56f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1297.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1298.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1298.wav
new file mode 100644
index 0000000..a487e58
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1298.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1298.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1298.wavetable
new file mode 100644
index 0000000..1add129
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1298.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1299.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1299.wav
new file mode 100644
index 0000000..504ae18
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1299.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1299.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1299.wavetable
new file mode 100644
index 0000000..ad32bc1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1299.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1300.wav b/etc/wavetables/AKWF/AKWF_0013/AKWF_1300.wav
new file mode 100644
index 0000000..a2f4d21
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1300.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AKWF_1300.wavetable b/etc/wavetables/AKWF/AKWF_0013/AKWF_1300.wavetable
new file mode 100644
index 0000000..d5bbed5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0013/AKWF_1300.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0013/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0013/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0013/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1301.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1301.wav
new file mode 100644
index 0000000..7bd81b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1301.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1301.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1301.wavetable
new file mode 100644
index 0000000..c431145
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1301.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1302.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1302.wav
new file mode 100644
index 0000000..7d63fbc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1302.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1302.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1302.wavetable
new file mode 100644
index 0000000..535fffe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1302.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1303.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1303.wav
new file mode 100644
index 0000000..7cd2ced
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1303.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1303.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1303.wavetable
new file mode 100644
index 0000000..1117620
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1303.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1304.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1304.wav
new file mode 100644
index 0000000..eb163cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1304.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1304.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1304.wavetable
new file mode 100644
index 0000000..4aff284
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1304.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1305.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1305.wav
new file mode 100644
index 0000000..d88a2c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1305.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1305.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1305.wavetable
new file mode 100644
index 0000000..633e7ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1305.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1306.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1306.wav
new file mode 100644
index 0000000..97c16a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1306.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1306.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1306.wavetable
new file mode 100644
index 0000000..56854a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1306.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1307.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1307.wav
new file mode 100644
index 0000000..437af43
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1307.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1307.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1307.wavetable
new file mode 100644
index 0000000..3352fe4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1307.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1308.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1308.wav
new file mode 100644
index 0000000..adb1b05
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1308.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1308.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1308.wavetable
new file mode 100644
index 0000000..d6130bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1308.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1309.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1309.wav
new file mode 100644
index 0000000..a9ba7ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1309.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1309.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1309.wavetable
new file mode 100644
index 0000000..91745ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1309.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1310.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1310.wav
new file mode 100644
index 0000000..f43b723
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1310.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1310.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1310.wavetable
new file mode 100644
index 0000000..1e3c27f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1310.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1311.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1311.wav
new file mode 100644
index 0000000..6b93306
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1311.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1311.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1311.wavetable
new file mode 100644
index 0000000..71ae06d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1311.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1312.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1312.wav
new file mode 100644
index 0000000..8f58208
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1312.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1312.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1312.wavetable
new file mode 100644
index 0000000..9caeb64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1312.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1313.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1313.wav
new file mode 100644
index 0000000..82bdff2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1313.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1313.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1313.wavetable
new file mode 100644
index 0000000..97d05e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1313.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1314.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1314.wav
new file mode 100644
index 0000000..a481af2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1314.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1314.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1314.wavetable
new file mode 100644
index 0000000..119b56d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1314.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1315.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1315.wav
new file mode 100644
index 0000000..9499a13
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1315.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1315.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1315.wavetable
new file mode 100644
index 0000000..997d835
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1315.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1316.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1316.wav
new file mode 100644
index 0000000..0edd2e3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1316.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1316.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1316.wavetable
new file mode 100644
index 0000000..17f8156
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1316.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1317.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1317.wav
new file mode 100644
index 0000000..feff867
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1317.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1317.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1317.wavetable
new file mode 100644
index 0000000..58ca6d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1317.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1318.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1318.wav
new file mode 100644
index 0000000..a57cd89
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1318.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1318.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1318.wavetable
new file mode 100644
index 0000000..f2c7821
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1318.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1319.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1319.wav
new file mode 100644
index 0000000..ebb7454
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1319.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1319.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1319.wavetable
new file mode 100644
index 0000000..8ddb554
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1319.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1320.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1320.wav
new file mode 100644
index 0000000..eafd271
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1320.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1320.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1320.wavetable
new file mode 100644
index 0000000..d5a7d3a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1320.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1321.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1321.wav
new file mode 100644
index 0000000..635d2f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1321.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1321.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1321.wavetable
new file mode 100644
index 0000000..d22b76e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1321.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1322.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1322.wav
new file mode 100644
index 0000000..cc3c197
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1322.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1322.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1322.wavetable
new file mode 100644
index 0000000..efcf9ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1322.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1323.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1323.wav
new file mode 100644
index 0000000..d76b5a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1323.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1323.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1323.wavetable
new file mode 100644
index 0000000..137ec30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1323.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1324.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1324.wav
new file mode 100644
index 0000000..8a99a9b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1324.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1324.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1324.wavetable
new file mode 100644
index 0000000..9713acd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1324.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1325.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1325.wav
new file mode 100644
index 0000000..68c0bb0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1325.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1325.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1325.wavetable
new file mode 100644
index 0000000..6d12d54
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1325.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1326.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1326.wav
new file mode 100644
index 0000000..d557673
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1326.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1326.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1326.wavetable
new file mode 100644
index 0000000..1464740
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1326.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1327.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1327.wav
new file mode 100644
index 0000000..5b0925f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1327.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1327.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1327.wavetable
new file mode 100644
index 0000000..08b395c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1327.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1328.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1328.wav
new file mode 100644
index 0000000..c916af4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1328.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1328.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1328.wavetable
new file mode 100644
index 0000000..dcdc84f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1328.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1329.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1329.wav
new file mode 100644
index 0000000..f851120
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1329.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1329.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1329.wavetable
new file mode 100644
index 0000000..a5c35ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1329.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1330.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1330.wav
new file mode 100644
index 0000000..7fdc832
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1330.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1330.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1330.wavetable
new file mode 100644
index 0000000..2929d53
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1330.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1331.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1331.wav
new file mode 100644
index 0000000..c5a7885
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1331.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1331.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1331.wavetable
new file mode 100644
index 0000000..809dcc7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1331.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1332.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1332.wav
new file mode 100644
index 0000000..4cd7ab0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1332.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1332.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1332.wavetable
new file mode 100644
index 0000000..24ce0d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1332.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1333.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1333.wav
new file mode 100644
index 0000000..a440e61
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1333.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1333.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1333.wavetable
new file mode 100644
index 0000000..6d83898
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1333.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1334.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1334.wav
new file mode 100644
index 0000000..b45dfe4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1334.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1334.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1334.wavetable
new file mode 100644
index 0000000..f9bf2ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1334.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1335.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1335.wav
new file mode 100644
index 0000000..109b13f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1335.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1335.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1335.wavetable
new file mode 100644
index 0000000..fc76c1f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1335.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1336.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1336.wav
new file mode 100644
index 0000000..59633e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1336.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1336.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1336.wavetable
new file mode 100644
index 0000000..0253424
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1336.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1337.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1337.wav
new file mode 100644
index 0000000..7c4e2d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1337.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1337.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1337.wavetable
new file mode 100644
index 0000000..c265218
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1337.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1338.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1338.wav
new file mode 100644
index 0000000..77017ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1338.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1338.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1338.wavetable
new file mode 100644
index 0000000..c1205d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1338.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1339.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1339.wav
new file mode 100644
index 0000000..25f5841
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1339.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1339.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1339.wavetable
new file mode 100644
index 0000000..dc2229d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1339.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1340.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1340.wav
new file mode 100644
index 0000000..4b9c322
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1340.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1340.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1340.wavetable
new file mode 100644
index 0000000..8d7b32e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1340.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1341.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1341.wav
new file mode 100644
index 0000000..cd19268
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1341.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1341.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1341.wavetable
new file mode 100644
index 0000000..b5b6714
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1341.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1342.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1342.wav
new file mode 100644
index 0000000..d5ff898
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1342.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1342.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1342.wavetable
new file mode 100644
index 0000000..33ac189
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1342.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1343.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1343.wav
new file mode 100644
index 0000000..272dc92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1343.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1343.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1343.wavetable
new file mode 100644
index 0000000..8506938
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1343.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1344.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1344.wav
new file mode 100644
index 0000000..e025386
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1344.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1344.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1344.wavetable
new file mode 100644
index 0000000..d4406e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1344.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1345.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1345.wav
new file mode 100644
index 0000000..fec5b87
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1345.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1345.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1345.wavetable
new file mode 100644
index 0000000..ff06e52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1345.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1346.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1346.wav
new file mode 100644
index 0000000..51d4283
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1346.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1346.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1346.wavetable
new file mode 100644
index 0000000..7aeef0b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1346.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1347.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1347.wav
new file mode 100644
index 0000000..28bcc6e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1347.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1347.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1347.wavetable
new file mode 100644
index 0000000..8a3d695
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1347.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1348.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1348.wav
new file mode 100644
index 0000000..9f553a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1348.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1348.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1348.wavetable
new file mode 100644
index 0000000..0975684
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1348.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1349.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1349.wav
new file mode 100644
index 0000000..541332d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1349.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1349.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1349.wavetable
new file mode 100644
index 0000000..9eb367c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1349.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1350.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1350.wav
new file mode 100644
index 0000000..554581a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1350.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1350.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1350.wavetable
new file mode 100644
index 0000000..a13c88e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1350.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1351.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1351.wav
new file mode 100644
index 0000000..c3ff3b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1351.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1351.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1351.wavetable
new file mode 100644
index 0000000..7436bd1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1351.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1352.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1352.wav
new file mode 100644
index 0000000..498725a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1352.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1352.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1352.wavetable
new file mode 100644
index 0000000..1e1ff82
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1352.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1353.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1353.wav
new file mode 100644
index 0000000..3a11a1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1353.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1353.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1353.wavetable
new file mode 100644
index 0000000..ac00e78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1353.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1354.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1354.wav
new file mode 100644
index 0000000..122ec71
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1354.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1354.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1354.wavetable
new file mode 100644
index 0000000..2e434db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1354.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1355.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1355.wav
new file mode 100644
index 0000000..fdd8327
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1355.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1355.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1355.wavetable
new file mode 100644
index 0000000..86b02f8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1355.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1356.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1356.wav
new file mode 100644
index 0000000..ca6c54a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1356.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1356.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1356.wavetable
new file mode 100644
index 0000000..a42384f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1356.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1357.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1357.wav
new file mode 100644
index 0000000..78d5d34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1357.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1357.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1357.wavetable
new file mode 100644
index 0000000..6fc8102
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1357.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1358.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1358.wav
new file mode 100644
index 0000000..522d83d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1358.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1358.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1358.wavetable
new file mode 100644
index 0000000..1c07661
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1358.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1359.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1359.wav
new file mode 100644
index 0000000..976e751
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1359.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1359.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1359.wavetable
new file mode 100644
index 0000000..99599c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1359.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1360.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1360.wav
new file mode 100644
index 0000000..7a6ffe1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1360.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1360.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1360.wavetable
new file mode 100644
index 0000000..e314e2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1360.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1361.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1361.wav
new file mode 100644
index 0000000..d7038de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1361.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1361.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1361.wavetable
new file mode 100644
index 0000000..72ded02
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1361.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1362.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1362.wav
new file mode 100644
index 0000000..aeb8d24
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1362.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1362.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1362.wavetable
new file mode 100644
index 0000000..2826ff6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1362.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1363.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1363.wav
new file mode 100644
index 0000000..350efa7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1363.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1363.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1363.wavetable
new file mode 100644
index 0000000..d02933e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1363.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1364.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1364.wav
new file mode 100644
index 0000000..397c39c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1364.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1364.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1364.wavetable
new file mode 100644
index 0000000..c3f2260
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1364.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1365.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1365.wav
new file mode 100644
index 0000000..a20d132
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1365.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1365.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1365.wavetable
new file mode 100644
index 0000000..588615f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1365.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1366.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1366.wav
new file mode 100644
index 0000000..cf820e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1366.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1366.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1366.wavetable
new file mode 100644
index 0000000..da21f32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1366.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1367.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1367.wav
new file mode 100644
index 0000000..4557f92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1367.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1367.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1367.wavetable
new file mode 100644
index 0000000..3907653
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1367.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1368.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1368.wav
new file mode 100644
index 0000000..4420420
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1368.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1368.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1368.wavetable
new file mode 100644
index 0000000..677f3b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1368.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1369.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1369.wav
new file mode 100644
index 0000000..d402325
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1369.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1369.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1369.wavetable
new file mode 100644
index 0000000..f6541e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1369.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1370.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1370.wav
new file mode 100644
index 0000000..1a9ec6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1370.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1370.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1370.wavetable
new file mode 100644
index 0000000..149214f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1370.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1371.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1371.wav
new file mode 100644
index 0000000..3aeeffc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1371.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1371.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1371.wavetable
new file mode 100644
index 0000000..b426ea4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1371.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1372.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1372.wav
new file mode 100644
index 0000000..e5a56eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1372.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1372.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1372.wavetable
new file mode 100644
index 0000000..ea37f1e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1372.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1373.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1373.wav
new file mode 100644
index 0000000..ef989a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1373.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1373.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1373.wavetable
new file mode 100644
index 0000000..dfedfbb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1373.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1374.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1374.wav
new file mode 100644
index 0000000..572c236
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1374.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1374.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1374.wavetable
new file mode 100644
index 0000000..a0de04c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1374.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1375.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1375.wav
new file mode 100644
index 0000000..e5a76cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1375.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1375.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1375.wavetable
new file mode 100644
index 0000000..e3b1cc8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1375.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1376.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1376.wav
new file mode 100644
index 0000000..d5df749
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1376.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1376.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1376.wavetable
new file mode 100644
index 0000000..c64d59f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1376.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1377.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1377.wav
new file mode 100644
index 0000000..407cead
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1377.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1377.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1377.wavetable
new file mode 100644
index 0000000..95616ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1377.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1378.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1378.wav
new file mode 100644
index 0000000..eec3201
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1378.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1378.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1378.wavetable
new file mode 100644
index 0000000..44e79b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1378.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1379.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1379.wav
new file mode 100644
index 0000000..d6596b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1379.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1379.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1379.wavetable
new file mode 100644
index 0000000..02bd733
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1379.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1380.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1380.wav
new file mode 100644
index 0000000..1e92a5a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1380.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1380.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1380.wavetable
new file mode 100644
index 0000000..7fd0265
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1380.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1381.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1381.wav
new file mode 100644
index 0000000..acce344
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1381.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1381.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1381.wavetable
new file mode 100644
index 0000000..7634cff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1381.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1382.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1382.wav
new file mode 100644
index 0000000..0d45f22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1382.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1382.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1382.wavetable
new file mode 100644
index 0000000..bcde1b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1382.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1383.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1383.wav
new file mode 100644
index 0000000..193dfc3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1383.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1383.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1383.wavetable
new file mode 100644
index 0000000..6bad939
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1383.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1384.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1384.wav
new file mode 100644
index 0000000..45afe1e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1384.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1384.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1384.wavetable
new file mode 100644
index 0000000..f488f57
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1384.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1385.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1385.wav
new file mode 100644
index 0000000..e474fb8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1385.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1385.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1385.wavetable
new file mode 100644
index 0000000..acf775d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1385.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1386.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1386.wav
new file mode 100644
index 0000000..da5f3ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1386.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1386.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1386.wavetable
new file mode 100644
index 0000000..c6560d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1386.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1387.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1387.wav
new file mode 100644
index 0000000..5189e51
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1387.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1387.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1387.wavetable
new file mode 100644
index 0000000..5982f8b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1387.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1388.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1388.wav
new file mode 100644
index 0000000..fda97bd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1388.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1388.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1388.wavetable
new file mode 100644
index 0000000..16eec58
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1388.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1389.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1389.wav
new file mode 100644
index 0000000..15cb6e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1389.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1389.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1389.wavetable
new file mode 100644
index 0000000..05623fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1389.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1390.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1390.wav
new file mode 100644
index 0000000..500a1ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1390.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1390.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1390.wavetable
new file mode 100644
index 0000000..56a4df9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1390.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1391.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1391.wav
new file mode 100644
index 0000000..91e75db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1391.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1391.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1391.wavetable
new file mode 100644
index 0000000..0791b98
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1391.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1392.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1392.wav
new file mode 100644
index 0000000..e9dc839
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1392.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1392.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1392.wavetable
new file mode 100644
index 0000000..c00fe2f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1392.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1393.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1393.wav
new file mode 100644
index 0000000..92f2140
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1393.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1393.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1393.wavetable
new file mode 100644
index 0000000..d9fc364
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1393.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1394.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1394.wav
new file mode 100644
index 0000000..f4c67e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1394.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1394.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1394.wavetable
new file mode 100644
index 0000000..03176ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1394.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1395.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1395.wav
new file mode 100644
index 0000000..2e287be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1395.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1395.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1395.wavetable
new file mode 100644
index 0000000..c7362d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1395.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1396.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1396.wav
new file mode 100644
index 0000000..6ecdebc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1396.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1396.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1396.wavetable
new file mode 100644
index 0000000..2f91183
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1396.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1397.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1397.wav
new file mode 100644
index 0000000..872ef0b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1397.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1397.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1397.wavetable
new file mode 100644
index 0000000..3f3ccc4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1397.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1398.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1398.wav
new file mode 100644
index 0000000..660a817
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1398.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1398.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1398.wavetable
new file mode 100644
index 0000000..da08c30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1398.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1399.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1399.wav
new file mode 100644
index 0000000..99ac32d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1399.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1399.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1399.wavetable
new file mode 100644
index 0000000..497ccbf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1399.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1400.wav b/etc/wavetables/AKWF/AKWF_0014/AKWF_1400.wav
new file mode 100644
index 0000000..be83619
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1400.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AKWF_1400.wavetable b/etc/wavetables/AKWF/AKWF_0014/AKWF_1400.wavetable
new file mode 100644
index 0000000..3085bba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0014/AKWF_1400.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0014/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0014/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0014/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1401.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1401.wav
new file mode 100644
index 0000000..7c79313
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1401.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1401.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1401.wavetable
new file mode 100644
index 0000000..42f6db2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1401.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1402.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1402.wav
new file mode 100644
index 0000000..266936c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1402.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1402.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1402.wavetable
new file mode 100644
index 0000000..0b6ae4d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1402.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1403.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1403.wav
new file mode 100644
index 0000000..3f60aca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1403.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1403.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1403.wavetable
new file mode 100644
index 0000000..4a2e38e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1403.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1404.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1404.wav
new file mode 100644
index 0000000..6a45b46
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1404.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1404.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1404.wavetable
new file mode 100644
index 0000000..28de216
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1404.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1405.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1405.wav
new file mode 100644
index 0000000..ea9b789
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1405.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1405.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1405.wavetable
new file mode 100644
index 0000000..5e7a07b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1405.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1406.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1406.wav
new file mode 100644
index 0000000..d235b49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1406.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1406.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1406.wavetable
new file mode 100644
index 0000000..757b7ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1406.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1407.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1407.wav
new file mode 100644
index 0000000..2b0806f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1407.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1407.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1407.wavetable
new file mode 100644
index 0000000..1a53f42
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1407.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1408.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1408.wav
new file mode 100644
index 0000000..a354c10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1408.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1408.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1408.wavetable
new file mode 100644
index 0000000..e97fa2f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1408.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1409.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1409.wav
new file mode 100644
index 0000000..20a1e9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1409.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1409.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1409.wavetable
new file mode 100644
index 0000000..153e939
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1409.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1410.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1410.wav
new file mode 100644
index 0000000..1ac65be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1410.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1410.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1410.wavetable
new file mode 100644
index 0000000..60af64d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1410.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1411.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1411.wav
new file mode 100644
index 0000000..81717e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1411.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1411.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1411.wavetable
new file mode 100644
index 0000000..e106fbd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1411.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1412.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1412.wav
new file mode 100644
index 0000000..02af773
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1412.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1412.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1412.wavetable
new file mode 100644
index 0000000..b7dfabb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1412.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1413.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1413.wav
new file mode 100644
index 0000000..6a10cb5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1413.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1413.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1413.wavetable
new file mode 100644
index 0000000..661742f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1413.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1414.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1414.wav
new file mode 100644
index 0000000..b58f8f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1414.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1414.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1414.wavetable
new file mode 100644
index 0000000..471ea25
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1414.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1415.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1415.wav
new file mode 100644
index 0000000..a2d082e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1415.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1415.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1415.wavetable
new file mode 100644
index 0000000..9795d99
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1415.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1416.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1416.wav
new file mode 100644
index 0000000..cd5c411
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1416.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1416.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1416.wavetable
new file mode 100644
index 0000000..640e32f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1416.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1417.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1417.wav
new file mode 100644
index 0000000..2ce4bd1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1417.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1417.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1417.wavetable
new file mode 100644
index 0000000..3db6db0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1417.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1418.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1418.wav
new file mode 100644
index 0000000..56a9adc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1418.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1418.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1418.wavetable
new file mode 100644
index 0000000..bd9f533
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1418.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1419.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1419.wav
new file mode 100644
index 0000000..f2502a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1419.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1419.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1419.wavetable
new file mode 100644
index 0000000..6213b3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1419.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1420.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1420.wav
new file mode 100644
index 0000000..6c4d6e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1420.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1420.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1420.wavetable
new file mode 100644
index 0000000..c2bd5ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1420.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1421.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1421.wav
new file mode 100644
index 0000000..f65e5b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1421.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1421.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1421.wavetable
new file mode 100644
index 0000000..e687578
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1421.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1422.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1422.wav
new file mode 100644
index 0000000..3a8b4a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1422.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1422.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1422.wavetable
new file mode 100644
index 0000000..f910828
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1422.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1423.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1423.wav
new file mode 100644
index 0000000..dde3b48
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1423.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1423.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1423.wavetable
new file mode 100644
index 0000000..17d6210
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1423.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1424.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1424.wav
new file mode 100644
index 0000000..b643365
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1424.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1424.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1424.wavetable
new file mode 100644
index 0000000..ed3ce3f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1424.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1425.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1425.wav
new file mode 100644
index 0000000..180449c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1425.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1425.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1425.wavetable
new file mode 100644
index 0000000..dd03b85
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1425.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1426.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1426.wav
new file mode 100644
index 0000000..6e55ce4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1426.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1426.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1426.wavetable
new file mode 100644
index 0000000..c3d2f59
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1426.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1427.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1427.wav
new file mode 100644
index 0000000..a1e6975
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1427.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1427.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1427.wavetable
new file mode 100644
index 0000000..4cae6bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1427.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1428.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1428.wav
new file mode 100644
index 0000000..59f0095
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1428.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1428.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1428.wavetable
new file mode 100644
index 0000000..2f80b5c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1428.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1429.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1429.wav
new file mode 100644
index 0000000..5f7688c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1429.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1429.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1429.wavetable
new file mode 100644
index 0000000..17c24d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1429.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1430.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1430.wav
new file mode 100644
index 0000000..6518a71
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1430.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1430.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1430.wavetable
new file mode 100644
index 0000000..9d7c88c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1430.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1431.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1431.wav
new file mode 100644
index 0000000..73d0785
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1431.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1431.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1431.wavetable
new file mode 100644
index 0000000..55b14de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1431.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1432.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1432.wav
new file mode 100644
index 0000000..3d05a97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1432.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1432.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1432.wavetable
new file mode 100644
index 0000000..d769614
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1432.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1433.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1433.wav
new file mode 100644
index 0000000..54b7aa3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1433.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1433.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1433.wavetable
new file mode 100644
index 0000000..a6b7431
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1433.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1434.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1434.wav
new file mode 100644
index 0000000..6f94347
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1434.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1434.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1434.wavetable
new file mode 100644
index 0000000..9ac61d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1434.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1435.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1435.wav
new file mode 100644
index 0000000..a209fa4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1435.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1435.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1435.wavetable
new file mode 100644
index 0000000..2dcd0cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1435.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1436.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1436.wav
new file mode 100644
index 0000000..1f4874f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1436.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1436.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1436.wavetable
new file mode 100644
index 0000000..92d743a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1436.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1437.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1437.wav
new file mode 100644
index 0000000..6aa013f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1437.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1437.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1437.wavetable
new file mode 100644
index 0000000..35bcacb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1437.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1438.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1438.wav
new file mode 100644
index 0000000..ba3207a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1438.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1438.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1438.wavetable
new file mode 100644
index 0000000..e1afd62
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1438.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1439.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1439.wav
new file mode 100644
index 0000000..d46c70d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1439.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1439.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1439.wavetable
new file mode 100644
index 0000000..4a01000
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1439.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1440.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1440.wav
new file mode 100644
index 0000000..9e42107
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1440.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1440.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1440.wavetable
new file mode 100644
index 0000000..846a7dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1440.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1441.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1441.wav
new file mode 100644
index 0000000..e6f49a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1441.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1441.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1441.wavetable
new file mode 100644
index 0000000..efd86d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1441.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1442.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1442.wav
new file mode 100644
index 0000000..723c7d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1442.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1442.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1442.wavetable
new file mode 100644
index 0000000..816c748
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1442.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1443.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1443.wav
new file mode 100644
index 0000000..0d36e28
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1443.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1443.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1443.wavetable
new file mode 100644
index 0000000..eafba38
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1443.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1444.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1444.wav
new file mode 100644
index 0000000..cce6198
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1444.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1444.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1444.wavetable
new file mode 100644
index 0000000..1dc9dfa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1444.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1445.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1445.wav
new file mode 100644
index 0000000..56fd1a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1445.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1445.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1445.wavetable
new file mode 100644
index 0000000..c7c7cda
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1445.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1446.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1446.wav
new file mode 100644
index 0000000..9f8db9f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1446.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1446.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1446.wavetable
new file mode 100644
index 0000000..5159289
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1446.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1447.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1447.wav
new file mode 100644
index 0000000..4225035
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1447.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1447.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1447.wavetable
new file mode 100644
index 0000000..11bd8f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1447.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1448.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1448.wav
new file mode 100644
index 0000000..74e05ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1448.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1448.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1448.wavetable
new file mode 100644
index 0000000..8976ddd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1448.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1449.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1449.wav
new file mode 100644
index 0000000..ba0f90c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1449.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1449.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1449.wavetable
new file mode 100644
index 0000000..1a4dd18
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1449.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1450.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1450.wav
new file mode 100644
index 0000000..95237a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1450.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1450.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1450.wavetable
new file mode 100644
index 0000000..5fc0ac9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1450.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1451.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1451.wav
new file mode 100644
index 0000000..d1274a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1451.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1451.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1451.wavetable
new file mode 100644
index 0000000..8f3c864
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1451.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1452.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1452.wav
new file mode 100644
index 0000000..f0e1750
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1452.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1452.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1452.wavetable
new file mode 100644
index 0000000..42c2557
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1452.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1453.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1453.wav
new file mode 100644
index 0000000..793cfc8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1453.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1453.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1453.wavetable
new file mode 100644
index 0000000..9f6f364
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1453.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1454.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1454.wav
new file mode 100644
index 0000000..4a9240b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1454.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1454.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1454.wavetable
new file mode 100644
index 0000000..fd074f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1454.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1455.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1455.wav
new file mode 100644
index 0000000..7779833
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1455.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1455.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1455.wavetable
new file mode 100644
index 0000000..73b04e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1455.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1456.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1456.wav
new file mode 100644
index 0000000..2f008d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1456.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1456.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1456.wavetable
new file mode 100644
index 0000000..e5de0c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1456.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1457.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1457.wav
new file mode 100644
index 0000000..9d70487
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1457.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1457.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1457.wavetable
new file mode 100644
index 0000000..c106b30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1457.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1458.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1458.wav
new file mode 100644
index 0000000..1a38aca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1458.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1458.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1458.wavetable
new file mode 100644
index 0000000..5bc6d22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1458.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1459.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1459.wav
new file mode 100644
index 0000000..189fe0c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1459.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1459.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1459.wavetable
new file mode 100644
index 0000000..42e92d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1459.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1460.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1460.wav
new file mode 100644
index 0000000..9b33e96
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1460.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1460.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1460.wavetable
new file mode 100644
index 0000000..44056b3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1460.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1461.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1461.wav
new file mode 100644
index 0000000..fe75d13
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1461.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1461.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1461.wavetable
new file mode 100644
index 0000000..019fc7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1461.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1462.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1462.wav
new file mode 100644
index 0000000..aaa94de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1462.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1462.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1462.wavetable
new file mode 100644
index 0000000..fa05055
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1462.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1463.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1463.wav
new file mode 100644
index 0000000..627fce4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1463.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1463.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1463.wavetable
new file mode 100644
index 0000000..e4b9a23
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1463.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1464.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1464.wav
new file mode 100644
index 0000000..199173d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1464.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1464.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1464.wavetable
new file mode 100644
index 0000000..03f8bf1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1464.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1465.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1465.wav
new file mode 100644
index 0000000..e9f2360
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1465.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1465.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1465.wavetable
new file mode 100644
index 0000000..9f3bb90
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1465.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1466.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1466.wav
new file mode 100644
index 0000000..aa356e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1466.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1466.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1466.wavetable
new file mode 100644
index 0000000..af622a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1466.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1467.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1467.wav
new file mode 100644
index 0000000..d0fc1d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1467.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1467.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1467.wavetable
new file mode 100644
index 0000000..a07ec51
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1467.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1468.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1468.wav
new file mode 100644
index 0000000..5ae7cee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1468.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1468.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1468.wavetable
new file mode 100644
index 0000000..c11e225
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1468.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1469.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1469.wav
new file mode 100644
index 0000000..a2b744e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1469.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1469.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1469.wavetable
new file mode 100644
index 0000000..3e66b5c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1469.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1470.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1470.wav
new file mode 100644
index 0000000..ea60934
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1470.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1470.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1470.wavetable
new file mode 100644
index 0000000..516e08c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1470.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1471.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1471.wav
new file mode 100644
index 0000000..d799c2c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1471.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1471.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1471.wavetable
new file mode 100644
index 0000000..479519a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1471.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1472.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1472.wav
new file mode 100644
index 0000000..15f724e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1472.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1472.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1472.wavetable
new file mode 100644
index 0000000..ac592c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1472.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1473.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1473.wav
new file mode 100644
index 0000000..cac4ac4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1473.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1473.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1473.wavetable
new file mode 100644
index 0000000..5a5f62d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1473.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1474.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1474.wav
new file mode 100644
index 0000000..dd3612a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1474.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1474.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1474.wavetable
new file mode 100644
index 0000000..dbaa8a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1474.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1475.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1475.wav
new file mode 100644
index 0000000..0f8c1e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1475.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1475.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1475.wavetable
new file mode 100644
index 0000000..bc19bcf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1475.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1476.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1476.wav
new file mode 100644
index 0000000..75b90a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1476.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1476.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1476.wavetable
new file mode 100644
index 0000000..36de246
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1476.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1477.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1477.wav
new file mode 100644
index 0000000..6757b7e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1477.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1477.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1477.wavetable
new file mode 100644
index 0000000..8555e5c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1477.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1478.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1478.wav
new file mode 100644
index 0000000..b1f45bd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1478.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1478.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1478.wavetable
new file mode 100644
index 0000000..497eae4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1478.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1479.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1479.wav
new file mode 100644
index 0000000..218ed99
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1479.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1479.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1479.wavetable
new file mode 100644
index 0000000..80b5535
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1479.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1480.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1480.wav
new file mode 100644
index 0000000..17c20b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1480.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1480.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1480.wavetable
new file mode 100644
index 0000000..752ad86
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1480.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1481.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1481.wav
new file mode 100644
index 0000000..20032ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1481.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1481.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1481.wavetable
new file mode 100644
index 0000000..5cb4235
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1481.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1482.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1482.wav
new file mode 100644
index 0000000..2aeec52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1482.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1482.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1482.wavetable
new file mode 100644
index 0000000..fb0f17e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1482.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1483.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1483.wav
new file mode 100644
index 0000000..5cfae5a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1483.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1483.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1483.wavetable
new file mode 100644
index 0000000..3053c37
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1483.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1484.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1484.wav
new file mode 100644
index 0000000..a3911bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1484.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1484.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1484.wavetable
new file mode 100644
index 0000000..97a8513
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1484.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1485.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1485.wav
new file mode 100644
index 0000000..a3670c7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1485.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1485.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1485.wavetable
new file mode 100644
index 0000000..ef5c44a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1485.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1486.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1486.wav
new file mode 100644
index 0000000..cf1c47d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1486.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1486.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1486.wavetable
new file mode 100644
index 0000000..5efc749
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1486.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1487.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1487.wav
new file mode 100644
index 0000000..7cc3c6f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1487.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1487.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1487.wavetable
new file mode 100644
index 0000000..fc8417f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1487.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1488.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1488.wav
new file mode 100644
index 0000000..1290acb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1488.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1488.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1488.wavetable
new file mode 100644
index 0000000..82aeaaa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1488.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1489.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1489.wav
new file mode 100644
index 0000000..5eea1f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1489.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1489.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1489.wavetable
new file mode 100644
index 0000000..1df4f06
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1489.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1490.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1490.wav
new file mode 100644
index 0000000..93a7894
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1490.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1490.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1490.wavetable
new file mode 100644
index 0000000..79a49f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1490.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1491.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1491.wav
new file mode 100644
index 0000000..b8a01f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1491.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1491.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1491.wavetable
new file mode 100644
index 0000000..9ccb635
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1491.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1492.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1492.wav
new file mode 100644
index 0000000..107b986
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1492.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1492.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1492.wavetable
new file mode 100644
index 0000000..acb2ea1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1492.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1493.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1493.wav
new file mode 100644
index 0000000..f28d546
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1493.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1493.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1493.wavetable
new file mode 100644
index 0000000..1120d8b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1493.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1494.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1494.wav
new file mode 100644
index 0000000..9c51f0a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1494.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1494.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1494.wavetable
new file mode 100644
index 0000000..0ded437
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1494.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1495.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1495.wav
new file mode 100644
index 0000000..cda106c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1495.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1495.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1495.wavetable
new file mode 100644
index 0000000..568715c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1495.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1496.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1496.wav
new file mode 100644
index 0000000..a8022ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1496.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1496.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1496.wavetable
new file mode 100644
index 0000000..3f2ec2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1496.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1497.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1497.wav
new file mode 100644
index 0000000..f3a1a33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1497.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1497.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1497.wavetable
new file mode 100644
index 0000000..9b5151b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1497.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1498.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1498.wav
new file mode 100644
index 0000000..8da67af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1498.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1498.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1498.wavetable
new file mode 100644
index 0000000..446c044
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1498.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1499.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1499.wav
new file mode 100644
index 0000000..f59a10a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1499.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1499.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1499.wavetable
new file mode 100644
index 0000000..a01db98
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1499.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1500.wav b/etc/wavetables/AKWF/AKWF_0015/AKWF_1500.wav
new file mode 100644
index 0000000..d2be077
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1500.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AKWF_1500.wavetable b/etc/wavetables/AKWF/AKWF_0015/AKWF_1500.wavetable
new file mode 100644
index 0000000..a81ff44
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0015/AKWF_1500.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0015/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0015/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0015/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1501.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1501.wav
new file mode 100644
index 0000000..559c279
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1501.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1501.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1501.wavetable
new file mode 100644
index 0000000..b467664
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1501.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1502.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1502.wav
new file mode 100644
index 0000000..4034c70
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1502.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1502.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1502.wavetable
new file mode 100644
index 0000000..d9dc677
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1502.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1503.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1503.wav
new file mode 100644
index 0000000..ff73b97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1503.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1503.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1503.wavetable
new file mode 100644
index 0000000..43c417f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1503.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1504.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1504.wav
new file mode 100644
index 0000000..f8daa7e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1504.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1504.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1504.wavetable
new file mode 100644
index 0000000..04aa2a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1504.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1505.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1505.wav
new file mode 100644
index 0000000..9c9a0d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1505.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1505.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1505.wavetable
new file mode 100644
index 0000000..744adb0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1505.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1506.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1506.wav
new file mode 100644
index 0000000..52d3b08
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1506.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1506.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1506.wavetable
new file mode 100644
index 0000000..c74903e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1506.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1507.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1507.wav
new file mode 100644
index 0000000..f6c1cf7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1507.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1507.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1507.wavetable
new file mode 100644
index 0000000..b3d2f02
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1507.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1508.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1508.wav
new file mode 100644
index 0000000..c94d4eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1508.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1508.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1508.wavetable
new file mode 100644
index 0000000..9078b13
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1508.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1509.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1509.wav
new file mode 100644
index 0000000..16af80e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1509.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1509.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1509.wavetable
new file mode 100644
index 0000000..f91226d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1509.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1510.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1510.wav
new file mode 100644
index 0000000..9afb520
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1510.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1510.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1510.wavetable
new file mode 100644
index 0000000..08766dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1510.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1511.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1511.wav
new file mode 100644
index 0000000..ee845e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1511.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1511.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1511.wavetable
new file mode 100644
index 0000000..6c48cea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1511.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1512.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1512.wav
new file mode 100644
index 0000000..bc24400
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1512.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1512.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1512.wavetable
new file mode 100644
index 0000000..c68ea0a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1512.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1513.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1513.wav
new file mode 100644
index 0000000..5ca13ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1513.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1513.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1513.wavetable
new file mode 100644
index 0000000..3a1d379
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1513.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1514.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1514.wav
new file mode 100644
index 0000000..d6ca182
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1514.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1514.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1514.wavetable
new file mode 100644
index 0000000..9c829f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1514.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1515.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1515.wav
new file mode 100644
index 0000000..db46df3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1515.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1515.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1515.wavetable
new file mode 100644
index 0000000..ddf9e58
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1515.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1516.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1516.wav
new file mode 100644
index 0000000..d93d87b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1516.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1516.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1516.wavetable
new file mode 100644
index 0000000..75888fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1516.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1517.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1517.wav
new file mode 100644
index 0000000..dbbfbac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1517.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1517.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1517.wavetable
new file mode 100644
index 0000000..a875228
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1517.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1518.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1518.wav
new file mode 100644
index 0000000..78890e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1518.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1518.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1518.wavetable
new file mode 100644
index 0000000..c734e3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1518.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1519.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1519.wav
new file mode 100644
index 0000000..fa09820
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1519.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1519.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1519.wavetable
new file mode 100644
index 0000000..9e4e4a9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1519.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1520.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1520.wav
new file mode 100644
index 0000000..9c93596
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1520.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1520.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1520.wavetable
new file mode 100644
index 0000000..b4ea0f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1520.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1521.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1521.wav
new file mode 100644
index 0000000..5cc1a74
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1521.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1521.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1521.wavetable
new file mode 100644
index 0000000..ebf28de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1521.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1522.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1522.wav
new file mode 100644
index 0000000..29a0046
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1522.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1522.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1522.wavetable
new file mode 100644
index 0000000..2a72fbb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1522.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1523.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1523.wav
new file mode 100644
index 0000000..4b12e59
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1523.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1523.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1523.wavetable
new file mode 100644
index 0000000..5564f5a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1523.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1524.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1524.wav
new file mode 100644
index 0000000..74e899f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1524.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1524.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1524.wavetable
new file mode 100644
index 0000000..65f728f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1524.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1525.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1525.wav
new file mode 100644
index 0000000..0f39836
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1525.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1525.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1525.wavetable
new file mode 100644
index 0000000..8ace42e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1525.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1526.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1526.wav
new file mode 100644
index 0000000..f4b6a12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1526.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1526.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1526.wavetable
new file mode 100644
index 0000000..55c67b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1526.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1527.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1527.wav
new file mode 100644
index 0000000..a8e538f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1527.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1527.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1527.wavetable
new file mode 100644
index 0000000..c75796e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1527.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1528.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1528.wav
new file mode 100644
index 0000000..3735a3d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1528.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1528.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1528.wavetable
new file mode 100644
index 0000000..260b55f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1528.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1529.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1529.wav
new file mode 100644
index 0000000..af13b0a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1529.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1529.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1529.wavetable
new file mode 100644
index 0000000..9e89d9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1529.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1530.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1530.wav
new file mode 100644
index 0000000..bd61e75
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1530.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1530.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1530.wavetable
new file mode 100644
index 0000000..1615da1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1530.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1531.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1531.wav
new file mode 100644
index 0000000..d623532
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1531.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1531.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1531.wavetable
new file mode 100644
index 0000000..13b58de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1531.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1532.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1532.wav
new file mode 100644
index 0000000..33254dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1532.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1532.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1532.wavetable
new file mode 100644
index 0000000..fdf6183
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1532.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1533.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1533.wav
new file mode 100644
index 0000000..5f48352
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1533.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1533.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1533.wavetable
new file mode 100644
index 0000000..9ed5fe0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1533.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1534.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1534.wav
new file mode 100644
index 0000000..64d4f15
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1534.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1534.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1534.wavetable
new file mode 100644
index 0000000..e833e61
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1534.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1535.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1535.wav
new file mode 100644
index 0000000..fda5663
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1535.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1535.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1535.wavetable
new file mode 100644
index 0000000..2f63c35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1535.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1536.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1536.wav
new file mode 100644
index 0000000..625972f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1536.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1536.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1536.wavetable
new file mode 100644
index 0000000..a85b145
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1536.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1537.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1537.wav
new file mode 100644
index 0000000..68b53c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1537.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1537.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1537.wavetable
new file mode 100644
index 0000000..165789f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1537.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1538.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1538.wav
new file mode 100644
index 0000000..11d1c8f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1538.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1538.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1538.wavetable
new file mode 100644
index 0000000..347b44c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1538.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1539.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1539.wav
new file mode 100644
index 0000000..28dd358
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1539.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1539.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1539.wavetable
new file mode 100644
index 0000000..e66ec66
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1539.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1540.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1540.wav
new file mode 100644
index 0000000..2e87144
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1540.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1540.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1540.wavetable
new file mode 100644
index 0000000..6d61578
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1540.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1541.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1541.wav
new file mode 100644
index 0000000..86906c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1541.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1541.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1541.wavetable
new file mode 100644
index 0000000..cc70714
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1541.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1542.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1542.wav
new file mode 100644
index 0000000..b96bbb6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1542.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1542.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1542.wavetable
new file mode 100644
index 0000000..189f7f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1542.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1543.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1543.wav
new file mode 100644
index 0000000..d3ef9cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1543.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1543.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1543.wavetable
new file mode 100644
index 0000000..4de02ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1543.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1544.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1544.wav
new file mode 100644
index 0000000..9260c71
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1544.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1544.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1544.wavetable
new file mode 100644
index 0000000..091e8ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1544.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1545.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1545.wav
new file mode 100644
index 0000000..157c817
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1545.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1545.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1545.wavetable
new file mode 100644
index 0000000..b109869
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1545.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1546.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1546.wav
new file mode 100644
index 0000000..9381eef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1546.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1546.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1546.wavetable
new file mode 100644
index 0000000..69ed55f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1546.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1547.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1547.wav
new file mode 100644
index 0000000..77e0410
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1547.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1547.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1547.wavetable
new file mode 100644
index 0000000..c671a31
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1547.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1548.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1548.wav
new file mode 100644
index 0000000..9cdf7e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1548.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1548.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1548.wavetable
new file mode 100644
index 0000000..8f6472f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1548.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1549.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1549.wav
new file mode 100644
index 0000000..9e545da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1549.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1549.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1549.wavetable
new file mode 100644
index 0000000..2bffd32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1549.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1550.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1550.wav
new file mode 100644
index 0000000..8a452f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1550.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1550.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1550.wavetable
new file mode 100644
index 0000000..8b590be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1550.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1551.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1551.wav
new file mode 100644
index 0000000..05242e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1551.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1551.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1551.wavetable
new file mode 100644
index 0000000..18d099a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1551.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1552.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1552.wav
new file mode 100644
index 0000000..cdddb8b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1552.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1552.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1552.wavetable
new file mode 100644
index 0000000..c812633
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1552.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1553.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1553.wav
new file mode 100644
index 0000000..721aac7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1553.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1553.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1553.wavetable
new file mode 100644
index 0000000..0a642d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1553.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1554.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1554.wav
new file mode 100644
index 0000000..fd2f68f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1554.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1554.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1554.wavetable
new file mode 100644
index 0000000..779acdd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1554.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1555.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1555.wav
new file mode 100644
index 0000000..2f5e627
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1555.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1555.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1555.wavetable
new file mode 100644
index 0000000..fc661c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1555.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1556.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1556.wav
new file mode 100644
index 0000000..26d7142
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1556.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1556.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1556.wavetable
new file mode 100644
index 0000000..3258f4e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1556.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1557.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1557.wav
new file mode 100644
index 0000000..8179ce8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1557.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1557.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1557.wavetable
new file mode 100644
index 0000000..57fc117
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1557.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1558.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1558.wav
new file mode 100644
index 0000000..32155ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1558.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1558.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1558.wavetable
new file mode 100644
index 0000000..2f38732
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1558.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1559.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1559.wav
new file mode 100644
index 0000000..8d9d3d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1559.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1559.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1559.wavetable
new file mode 100644
index 0000000..c00ca46
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1559.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1560.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1560.wav
new file mode 100644
index 0000000..93f02dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1560.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1560.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1560.wavetable
new file mode 100644
index 0000000..6f798ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1560.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1561.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1561.wav
new file mode 100644
index 0000000..43862bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1561.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1561.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1561.wavetable
new file mode 100644
index 0000000..9e7a240
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1561.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1562.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1562.wav
new file mode 100644
index 0000000..07f9851
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1562.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1562.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1562.wavetable
new file mode 100644
index 0000000..e5e0cd4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1562.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1563.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1563.wav
new file mode 100644
index 0000000..b30952e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1563.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1563.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1563.wavetable
new file mode 100644
index 0000000..928a519
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1563.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1564.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1564.wav
new file mode 100644
index 0000000..f3fde20
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1564.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1564.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1564.wavetable
new file mode 100644
index 0000000..de65f17
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1564.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1565.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1565.wav
new file mode 100644
index 0000000..49afc05
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1565.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1565.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1565.wavetable
new file mode 100644
index 0000000..491e7b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1565.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1566.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1566.wav
new file mode 100644
index 0000000..a2e5a3f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1566.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1566.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1566.wavetable
new file mode 100644
index 0000000..8f8f11f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1566.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1567.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1567.wav
new file mode 100644
index 0000000..1579715
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1567.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1567.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1567.wavetable
new file mode 100644
index 0000000..ee889f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1567.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1568.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1568.wav
new file mode 100644
index 0000000..e86f773
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1568.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1568.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1568.wavetable
new file mode 100644
index 0000000..45812f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1568.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1569.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1569.wav
new file mode 100644
index 0000000..4c4b73b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1569.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1569.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1569.wavetable
new file mode 100644
index 0000000..1b00868
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1569.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1570.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1570.wav
new file mode 100644
index 0000000..f9f16b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1570.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1570.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1570.wavetable
new file mode 100644
index 0000000..7e3676a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1570.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1571.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1571.wav
new file mode 100644
index 0000000..d3e68c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1571.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1571.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1571.wavetable
new file mode 100644
index 0000000..ba77584
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1571.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1572.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1572.wav
new file mode 100644
index 0000000..37368f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1572.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1572.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1572.wavetable
new file mode 100644
index 0000000..af713db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1572.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1573.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1573.wav
new file mode 100644
index 0000000..fd0b99f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1573.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1573.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1573.wavetable
new file mode 100644
index 0000000..79403f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1573.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1574.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1574.wav
new file mode 100644
index 0000000..a024ade
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1574.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1574.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1574.wavetable
new file mode 100644
index 0000000..03328b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1574.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1575.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1575.wav
new file mode 100644
index 0000000..88ad21b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1575.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1575.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1575.wavetable
new file mode 100644
index 0000000..285d961
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1575.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1576.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1576.wav
new file mode 100644
index 0000000..de637e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1576.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1576.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1576.wavetable
new file mode 100644
index 0000000..e092e59
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1576.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1577.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1577.wav
new file mode 100644
index 0000000..04f5b9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1577.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1577.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1577.wavetable
new file mode 100644
index 0000000..021276d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1577.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1578.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1578.wav
new file mode 100644
index 0000000..5977366
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1578.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1578.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1578.wavetable
new file mode 100644
index 0000000..ae841fc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1578.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1579.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1579.wav
new file mode 100644
index 0000000..90f2a7b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1579.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1579.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1579.wavetable
new file mode 100644
index 0000000..72bdfeb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1579.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1580.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1580.wav
new file mode 100644
index 0000000..2fce3a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1580.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1580.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1580.wavetable
new file mode 100644
index 0000000..c9338fc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1580.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1581.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1581.wav
new file mode 100644
index 0000000..b2ef41b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1581.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1581.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1581.wavetable
new file mode 100644
index 0000000..44b9072
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1581.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1582.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1582.wav
new file mode 100644
index 0000000..3e1b9fc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1582.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1582.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1582.wavetable
new file mode 100644
index 0000000..dfe229e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1582.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1583.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1583.wav
new file mode 100644
index 0000000..19c750a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1583.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1583.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1583.wavetable
new file mode 100644
index 0000000..3a1fcb9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1583.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1584.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1584.wav
new file mode 100644
index 0000000..48d41d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1584.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1584.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1584.wavetable
new file mode 100644
index 0000000..db88401
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1584.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1585.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1585.wav
new file mode 100644
index 0000000..8f713bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1585.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1585.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1585.wavetable
new file mode 100644
index 0000000..e44f42e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1585.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1586.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1586.wav
new file mode 100644
index 0000000..1cff1d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1586.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1586.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1586.wavetable
new file mode 100644
index 0000000..fb4a59f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1586.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1587.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1587.wav
new file mode 100644
index 0000000..ff8ee89
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1587.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1587.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1587.wavetable
new file mode 100644
index 0000000..5113bd4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1587.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1588.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1588.wav
new file mode 100644
index 0000000..2fee1c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1588.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1588.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1588.wavetable
new file mode 100644
index 0000000..2691710
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1588.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1589.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1589.wav
new file mode 100644
index 0000000..42ab8c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1589.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1589.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1589.wavetable
new file mode 100644
index 0000000..ab20b30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1589.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1590.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1590.wav
new file mode 100644
index 0000000..1059f49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1590.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1590.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1590.wavetable
new file mode 100644
index 0000000..2721df4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1590.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1591.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1591.wav
new file mode 100644
index 0000000..14819c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1591.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1591.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1591.wavetable
new file mode 100644
index 0000000..71e2bcf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1591.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1592.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1592.wav
new file mode 100644
index 0000000..58f7ac6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1592.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1592.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1592.wavetable
new file mode 100644
index 0000000..66d5c68
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1592.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1593.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1593.wav
new file mode 100644
index 0000000..c27fa15
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1593.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1593.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1593.wavetable
new file mode 100644
index 0000000..37a9e94
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1593.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1594.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1594.wav
new file mode 100644
index 0000000..e66f1fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1594.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1594.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1594.wavetable
new file mode 100644
index 0000000..160f94f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1594.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1595.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1595.wav
new file mode 100644
index 0000000..0bd7f5a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1595.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1595.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1595.wavetable
new file mode 100644
index 0000000..a962aa7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1595.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1596.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1596.wav
new file mode 100644
index 0000000..9a5cfec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1596.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1596.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1596.wavetable
new file mode 100644
index 0000000..0e2143d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1596.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1597.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1597.wav
new file mode 100644
index 0000000..f62390d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1597.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1597.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1597.wavetable
new file mode 100644
index 0000000..3c7bd35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1597.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1598.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1598.wav
new file mode 100644
index 0000000..638a11d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1598.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1598.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1598.wavetable
new file mode 100644
index 0000000..eb6cae3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1598.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1599.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1599.wav
new file mode 100644
index 0000000..e293ada
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1599.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1599.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1599.wavetable
new file mode 100644
index 0000000..f264bcd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1599.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1600.wav b/etc/wavetables/AKWF/AKWF_0016/AKWF_1600.wav
new file mode 100644
index 0000000..832cc35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1600.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AKWF_1600.wavetable b/etc/wavetables/AKWF/AKWF_0016/AKWF_1600.wavetable
new file mode 100644
index 0000000..7e5ab66
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0016/AKWF_1600.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0016/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0016/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0016/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1601.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1601.wav
new file mode 100644
index 0000000..d3139ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1601.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1601.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1601.wavetable
new file mode 100644
index 0000000..9f0ab59
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1601.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1602.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1602.wav
new file mode 100644
index 0000000..1b8af8e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1602.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1602.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1602.wavetable
new file mode 100644
index 0000000..a0df734
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1602.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1603.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1603.wav
new file mode 100644
index 0000000..f81f806
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1603.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1603.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1603.wavetable
new file mode 100644
index 0000000..ac37ee0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1603.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1604.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1604.wav
new file mode 100644
index 0000000..77d8523
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1604.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1604.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1604.wavetable
new file mode 100644
index 0000000..91d2fac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1604.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1605.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1605.wav
new file mode 100644
index 0000000..92e920b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1605.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1605.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1605.wavetable
new file mode 100644
index 0000000..3920c5e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1605.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1606.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1606.wav
new file mode 100644
index 0000000..e0ad75e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1606.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1606.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1606.wavetable
new file mode 100644
index 0000000..f6f1d1a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1606.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1607.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1607.wav
new file mode 100644
index 0000000..5892f20
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1607.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1607.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1607.wavetable
new file mode 100644
index 0000000..d4a9725
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1607.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1608.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1608.wav
new file mode 100644
index 0000000..944e153
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1608.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1608.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1608.wavetable
new file mode 100644
index 0000000..848a539
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1608.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1609.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1609.wav
new file mode 100644
index 0000000..01378d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1609.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1609.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1609.wavetable
new file mode 100644
index 0000000..29d38aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1609.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1610.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1610.wav
new file mode 100644
index 0000000..aa7484c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1610.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1610.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1610.wavetable
new file mode 100644
index 0000000..7148f21
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1610.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1611.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1611.wav
new file mode 100644
index 0000000..f3f1b1a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1611.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1611.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1611.wavetable
new file mode 100644
index 0000000..c410fc0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1611.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1612.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1612.wav
new file mode 100644
index 0000000..92fc941
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1612.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1612.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1612.wavetable
new file mode 100644
index 0000000..14650f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1612.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1613.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1613.wav
new file mode 100644
index 0000000..6d7f62d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1613.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1613.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1613.wavetable
new file mode 100644
index 0000000..af8a290
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1613.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1614.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1614.wav
new file mode 100644
index 0000000..914818f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1614.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1614.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1614.wavetable
new file mode 100644
index 0000000..aaeb77f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1614.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1615.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1615.wav
new file mode 100644
index 0000000..a5391c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1615.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1615.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1615.wavetable
new file mode 100644
index 0000000..4c1bd86
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1615.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1616.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1616.wav
new file mode 100644
index 0000000..ca0cdf2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1616.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1616.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1616.wavetable
new file mode 100644
index 0000000..1600a45
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1616.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1617.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1617.wav
new file mode 100644
index 0000000..d1b7a26
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1617.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1617.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1617.wavetable
new file mode 100644
index 0000000..7f80ec6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1617.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1618.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1618.wav
new file mode 100644
index 0000000..aeee6f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1618.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1618.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1618.wavetable
new file mode 100644
index 0000000..7d30683
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1618.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1619.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1619.wav
new file mode 100644
index 0000000..e1f3ab5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1619.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1619.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1619.wavetable
new file mode 100644
index 0000000..f38de4b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1619.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1620.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1620.wav
new file mode 100644
index 0000000..9f4d438
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1620.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1620.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1620.wavetable
new file mode 100644
index 0000000..10f0e10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1620.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1621.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1621.wav
new file mode 100644
index 0000000..cbf7a61
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1621.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1621.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1621.wavetable
new file mode 100644
index 0000000..10eac55
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1621.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1622.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1622.wav
new file mode 100644
index 0000000..0e4baac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1622.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1622.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1622.wavetable
new file mode 100644
index 0000000..ac5f91f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1622.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1623.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1623.wav
new file mode 100644
index 0000000..489c8d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1623.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1623.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1623.wavetable
new file mode 100644
index 0000000..93e2393
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1623.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1624.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1624.wav
new file mode 100644
index 0000000..57e26ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1624.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1624.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1624.wavetable
new file mode 100644
index 0000000..fb14939
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1624.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1625.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1625.wav
new file mode 100644
index 0000000..d0ae9d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1625.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1625.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1625.wavetable
new file mode 100644
index 0000000..0d4840c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1625.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1626.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1626.wav
new file mode 100644
index 0000000..f3d899d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1626.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1626.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1626.wavetable
new file mode 100644
index 0000000..8bd909b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1626.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1627.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1627.wav
new file mode 100644
index 0000000..b5539d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1627.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1627.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1627.wavetable
new file mode 100644
index 0000000..64dedb7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1627.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1628.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1628.wav
new file mode 100644
index 0000000..e543112
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1628.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1628.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1628.wavetable
new file mode 100644
index 0000000..68d88ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1628.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1629.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1629.wav
new file mode 100644
index 0000000..d915094
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1629.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1629.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1629.wavetable
new file mode 100644
index 0000000..6b47cc2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1629.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1630.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1630.wav
new file mode 100644
index 0000000..e8dfcc5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1630.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1630.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1630.wavetable
new file mode 100644
index 0000000..7237c93
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1630.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1631.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1631.wav
new file mode 100644
index 0000000..8f0598f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1631.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1631.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1631.wavetable
new file mode 100644
index 0000000..bd6d723
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1631.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1632.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1632.wav
new file mode 100644
index 0000000..93a6884
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1632.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1632.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1632.wavetable
new file mode 100644
index 0000000..708a9d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1632.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1633.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1633.wav
new file mode 100644
index 0000000..156d88e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1633.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1633.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1633.wavetable
new file mode 100644
index 0000000..07bed43
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1633.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1634.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1634.wav
new file mode 100644
index 0000000..94130e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1634.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1634.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1634.wavetable
new file mode 100644
index 0000000..4e8293e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1634.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1635.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1635.wav
new file mode 100644
index 0000000..2c608b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1635.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1635.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1635.wavetable
new file mode 100644
index 0000000..ee5d00d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1635.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1636.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1636.wav
new file mode 100644
index 0000000..ea9d433
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1636.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1636.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1636.wavetable
new file mode 100644
index 0000000..b8dde16
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1636.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1637.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1637.wav
new file mode 100644
index 0000000..520bb3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1637.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1637.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1637.wavetable
new file mode 100644
index 0000000..84e695c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1637.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1638.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1638.wav
new file mode 100644
index 0000000..3ecedbc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1638.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1638.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1638.wavetable
new file mode 100644
index 0000000..2894851
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1638.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1639.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1639.wav
new file mode 100644
index 0000000..42c007d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1639.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1639.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1639.wavetable
new file mode 100644
index 0000000..03dd4ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1639.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1640.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1640.wav
new file mode 100644
index 0000000..c57d2b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1640.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1640.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1640.wavetable
new file mode 100644
index 0000000..75ed0ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1640.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1641.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1641.wav
new file mode 100644
index 0000000..35861d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1641.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1641.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1641.wavetable
new file mode 100644
index 0000000..de9218e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1641.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1642.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1642.wav
new file mode 100644
index 0000000..f6c30e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1642.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1642.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1642.wavetable
new file mode 100644
index 0000000..633564b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1642.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1643.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1643.wav
new file mode 100644
index 0000000..01f94a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1643.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1643.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1643.wavetable
new file mode 100644
index 0000000..78e4991
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1643.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1644.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1644.wav
new file mode 100644
index 0000000..b3bcebf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1644.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1644.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1644.wavetable
new file mode 100644
index 0000000..9c63255
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1644.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1645.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1645.wav
new file mode 100644
index 0000000..670645c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1645.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1645.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1645.wavetable
new file mode 100644
index 0000000..5f703c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1645.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1646.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1646.wav
new file mode 100644
index 0000000..67149f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1646.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1646.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1646.wavetable
new file mode 100644
index 0000000..12ba454
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1646.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1647.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1647.wav
new file mode 100644
index 0000000..e9e2c73
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1647.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1647.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1647.wavetable
new file mode 100644
index 0000000..0d20f8f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1647.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1648.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1648.wav
new file mode 100644
index 0000000..8e6b2cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1648.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1648.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1648.wavetable
new file mode 100644
index 0000000..d666f82
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1648.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1649.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1649.wav
new file mode 100644
index 0000000..466de92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1649.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1649.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1649.wavetable
new file mode 100644
index 0000000..5478cbf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1649.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1650.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1650.wav
new file mode 100644
index 0000000..d9fbad1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1650.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1650.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1650.wavetable
new file mode 100644
index 0000000..2f6c4de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1650.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1651.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1651.wav
new file mode 100644
index 0000000..79dfe54
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1651.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1651.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1651.wavetable
new file mode 100644
index 0000000..4fe48a9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1651.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1652.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1652.wav
new file mode 100644
index 0000000..b9643f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1652.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1652.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1652.wavetable
new file mode 100644
index 0000000..33ee612
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1652.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1653.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1653.wav
new file mode 100644
index 0000000..f849d6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1653.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1653.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1653.wavetable
new file mode 100644
index 0000000..999d674
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1653.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1654.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1654.wav
new file mode 100644
index 0000000..4f96e3e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1654.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1654.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1654.wavetable
new file mode 100644
index 0000000..89c3f39
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1654.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1655.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1655.wav
new file mode 100644
index 0000000..f0f1d09
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1655.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1655.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1655.wavetable
new file mode 100644
index 0000000..9ed008b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1655.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1656.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1656.wav
new file mode 100644
index 0000000..c0fbc10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1656.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1656.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1656.wavetable
new file mode 100644
index 0000000..bc3edf2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1656.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1657.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1657.wav
new file mode 100644
index 0000000..a6e4c8c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1657.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1657.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1657.wavetable
new file mode 100644
index 0000000..62c7d70
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1657.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1658.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1658.wav
new file mode 100644
index 0000000..a7bdf1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1658.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1658.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1658.wavetable
new file mode 100644
index 0000000..46d5d9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1658.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1659.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1659.wav
new file mode 100644
index 0000000..00ce19e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1659.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1659.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1659.wavetable
new file mode 100644
index 0000000..eeb85d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1659.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1660.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1660.wav
new file mode 100644
index 0000000..80d3f0c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1660.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1660.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1660.wavetable
new file mode 100644
index 0000000..c03e295
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1660.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1661.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1661.wav
new file mode 100644
index 0000000..e9c7d80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1661.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1661.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1661.wavetable
new file mode 100644
index 0000000..8ad2fd2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1661.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1662.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1662.wav
new file mode 100644
index 0000000..9ea00f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1662.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1662.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1662.wavetable
new file mode 100644
index 0000000..56ee109
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1662.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1663.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1663.wav
new file mode 100644
index 0000000..1e2e7ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1663.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1663.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1663.wavetable
new file mode 100644
index 0000000..3077654
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1663.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1664.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1664.wav
new file mode 100644
index 0000000..728cdd8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1664.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1664.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1664.wavetable
new file mode 100644
index 0000000..fe9df30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1664.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1665.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1665.wav
new file mode 100644
index 0000000..51fb006
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1665.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1665.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1665.wavetable
new file mode 100644
index 0000000..18ae09d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1665.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1666.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1666.wav
new file mode 100644
index 0000000..445ac39
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1666.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1666.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1666.wavetable
new file mode 100644
index 0000000..ff3982e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1666.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1667.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1667.wav
new file mode 100644
index 0000000..7ce7cf5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1667.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1667.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1667.wavetable
new file mode 100644
index 0000000..b7d7648
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1667.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1668.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1668.wav
new file mode 100644
index 0000000..9f9ae2d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1668.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1668.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1668.wavetable
new file mode 100644
index 0000000..3b3f55a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1668.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1669.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1669.wav
new file mode 100644
index 0000000..a28c663
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1669.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1669.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1669.wavetable
new file mode 100644
index 0000000..5a31b04
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1669.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1670.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1670.wav
new file mode 100644
index 0000000..d0b62ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1670.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1670.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1670.wavetable
new file mode 100644
index 0000000..9812282
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1670.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1671.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1671.wav
new file mode 100644
index 0000000..07dcf26
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1671.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1671.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1671.wavetable
new file mode 100644
index 0000000..156ab65
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1671.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1672.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1672.wav
new file mode 100644
index 0000000..f93fac2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1672.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1672.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1672.wavetable
new file mode 100644
index 0000000..a2faa11
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1672.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1673.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1673.wav
new file mode 100644
index 0000000..27f3547
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1673.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1673.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1673.wavetable
new file mode 100644
index 0000000..67536c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1673.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1674.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1674.wav
new file mode 100644
index 0000000..60e3d59
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1674.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1674.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1674.wavetable
new file mode 100644
index 0000000..25d95de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1674.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1675.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1675.wav
new file mode 100644
index 0000000..b487165
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1675.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1675.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1675.wavetable
new file mode 100644
index 0000000..b06f12b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1675.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1676.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1676.wav
new file mode 100644
index 0000000..9c71cda
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1676.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1676.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1676.wavetable
new file mode 100644
index 0000000..6c1f6ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1676.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1677.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1677.wav
new file mode 100644
index 0000000..11c8eb6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1677.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1677.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1677.wavetable
new file mode 100644
index 0000000..329d177
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1677.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1678.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1678.wav
new file mode 100644
index 0000000..2d8487f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1678.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1678.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1678.wavetable
new file mode 100644
index 0000000..7224a4f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1678.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1679.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1679.wav
new file mode 100644
index 0000000..5b673f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1679.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1679.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1679.wavetable
new file mode 100644
index 0000000..391db78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1679.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1680.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1680.wav
new file mode 100644
index 0000000..3f79a64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1680.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1680.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1680.wavetable
new file mode 100644
index 0000000..8ddf916
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1680.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1681.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1681.wav
new file mode 100644
index 0000000..4db758e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1681.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1681.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1681.wavetable
new file mode 100644
index 0000000..8f414a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1681.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1682.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1682.wav
new file mode 100644
index 0000000..51825c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1682.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1682.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1682.wavetable
new file mode 100644
index 0000000..18c142f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1682.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1683.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1683.wav
new file mode 100644
index 0000000..7c96ee7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1683.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1683.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1683.wavetable
new file mode 100644
index 0000000..a325120
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1683.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1684.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1684.wav
new file mode 100644
index 0000000..3986abb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1684.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1684.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1684.wavetable
new file mode 100644
index 0000000..e2fe707
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1684.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1685.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1685.wav
new file mode 100644
index 0000000..d62eae8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1685.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1685.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1685.wavetable
new file mode 100644
index 0000000..5f2ad13
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1685.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1686.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1686.wav
new file mode 100644
index 0000000..3431876
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1686.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1686.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1686.wavetable
new file mode 100644
index 0000000..8fa4e93
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1686.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1687.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1687.wav
new file mode 100644
index 0000000..1407cfe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1687.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1687.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1687.wavetable
new file mode 100644
index 0000000..0badccc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1687.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1688.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1688.wav
new file mode 100644
index 0000000..de9aeab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1688.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1688.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1688.wavetable
new file mode 100644
index 0000000..676f5dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1688.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1689.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1689.wav
new file mode 100644
index 0000000..6563f32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1689.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1689.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1689.wavetable
new file mode 100644
index 0000000..1394be2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1689.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1690.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1690.wav
new file mode 100644
index 0000000..286b1c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1690.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1690.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1690.wavetable
new file mode 100644
index 0000000..8edb947
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1690.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1691.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1691.wav
new file mode 100644
index 0000000..7f8e81a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1691.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1691.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1691.wavetable
new file mode 100644
index 0000000..07241c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1691.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1692.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1692.wav
new file mode 100644
index 0000000..f86cce6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1692.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1692.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1692.wavetable
new file mode 100644
index 0000000..a235bd8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1692.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1693.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1693.wav
new file mode 100644
index 0000000..f18c41d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1693.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1693.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1693.wavetable
new file mode 100644
index 0000000..ee94ed6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1693.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1694.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1694.wav
new file mode 100644
index 0000000..f02d1e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1694.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1694.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1694.wavetable
new file mode 100644
index 0000000..aafc6a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1694.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1695.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1695.wav
new file mode 100644
index 0000000..6644a3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1695.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1695.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1695.wavetable
new file mode 100644
index 0000000..697e586
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1695.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1696.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1696.wav
new file mode 100644
index 0000000..c9192d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1696.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1696.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1696.wavetable
new file mode 100644
index 0000000..7927f92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1696.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1697.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1697.wav
new file mode 100644
index 0000000..1150719
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1697.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1697.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1697.wavetable
new file mode 100644
index 0000000..c2faaa9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1697.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1698.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1698.wav
new file mode 100644
index 0000000..5404d9c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1698.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1698.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1698.wavetable
new file mode 100644
index 0000000..085ae64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1698.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1699.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1699.wav
new file mode 100644
index 0000000..6def57a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1699.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1699.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1699.wavetable
new file mode 100644
index 0000000..0d8a751
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1699.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1700.wav b/etc/wavetables/AKWF/AKWF_0017/AKWF_1700.wav
new file mode 100644
index 0000000..668f91f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1700.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AKWF_1700.wavetable b/etc/wavetables/AKWF/AKWF_0017/AKWF_1700.wavetable
new file mode 100644
index 0000000..aa02fab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0017/AKWF_1700.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0017/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0017/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0017/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1701.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1701.wav
new file mode 100644
index 0000000..f37cd6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1701.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1701.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1701.wavetable
new file mode 100644
index 0000000..8a9e32a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1701.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1702.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1702.wav
new file mode 100644
index 0000000..39eeeb5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1702.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1702.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1702.wavetable
new file mode 100644
index 0000000..a6bf2d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1702.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1703.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1703.wav
new file mode 100644
index 0000000..94e595c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1703.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1703.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1703.wavetable
new file mode 100644
index 0000000..38053d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1703.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1704.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1704.wav
new file mode 100644
index 0000000..cf076dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1704.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1704.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1704.wavetable
new file mode 100644
index 0000000..7e16386
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1704.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1705.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1705.wav
new file mode 100644
index 0000000..1fedb30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1705.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1705.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1705.wavetable
new file mode 100644
index 0000000..ac16501
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1705.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1706.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1706.wav
new file mode 100644
index 0000000..a8ea248
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1706.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1706.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1706.wavetable
new file mode 100644
index 0000000..679151b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1706.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1707.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1707.wav
new file mode 100644
index 0000000..45f6bbe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1707.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1707.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1707.wavetable
new file mode 100644
index 0000000..14da6c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1707.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1708.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1708.wav
new file mode 100644
index 0000000..018dc4f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1708.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1708.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1708.wavetable
new file mode 100644
index 0000000..a0d0aea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1708.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1709.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1709.wav
new file mode 100644
index 0000000..2fd151e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1709.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1709.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1709.wavetable
new file mode 100644
index 0000000..c24da9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1709.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1710.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1710.wav
new file mode 100644
index 0000000..30bde07
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1710.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1710.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1710.wavetable
new file mode 100644
index 0000000..0280098
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1710.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1711.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1711.wav
new file mode 100644
index 0000000..03b3b3f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1711.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1711.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1711.wavetable
new file mode 100644
index 0000000..ca324fc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1711.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1712.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1712.wav
new file mode 100644
index 0000000..a588d12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1712.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1712.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1712.wavetable
new file mode 100644
index 0000000..a2ef8b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1712.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1713.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1713.wav
new file mode 100644
index 0000000..47ea5c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1713.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1713.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1713.wavetable
new file mode 100644
index 0000000..d6aa44a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1713.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1714.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1714.wav
new file mode 100644
index 0000000..745b456
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1714.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1714.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1714.wavetable
new file mode 100644
index 0000000..ceb7e2d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1714.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1715.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1715.wav
new file mode 100644
index 0000000..9bc40da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1715.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1715.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1715.wavetable
new file mode 100644
index 0000000..647438f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1715.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1716.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1716.wav
new file mode 100644
index 0000000..5df32ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1716.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1716.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1716.wavetable
new file mode 100644
index 0000000..9113069
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1716.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1717.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1717.wav
new file mode 100644
index 0000000..f0fab23
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1717.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1717.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1717.wavetable
new file mode 100644
index 0000000..770169b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1717.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1718.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1718.wav
new file mode 100644
index 0000000..ba7783b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1718.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1718.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1718.wavetable
new file mode 100644
index 0000000..9d737b7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1718.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1719.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1719.wav
new file mode 100644
index 0000000..23d7565
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1719.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1719.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1719.wavetable
new file mode 100644
index 0000000..3a26f58
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1719.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1720.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1720.wav
new file mode 100644
index 0000000..25e71fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1720.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1720.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1720.wavetable
new file mode 100644
index 0000000..826aac5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1720.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1721.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1721.wav
new file mode 100644
index 0000000..0b7ef84
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1721.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1721.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1721.wavetable
new file mode 100644
index 0000000..2196f7b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1721.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1722.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1722.wav
new file mode 100644
index 0000000..811cc08
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1722.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1722.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1722.wavetable
new file mode 100644
index 0000000..8b7e101
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1722.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1723.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1723.wav
new file mode 100644
index 0000000..0700226
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1723.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1723.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1723.wavetable
new file mode 100644
index 0000000..6dcbe59
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1723.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1724.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1724.wav
new file mode 100644
index 0000000..652858e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1724.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1724.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1724.wavetable
new file mode 100644
index 0000000..e017c08
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1724.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1725.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1725.wav
new file mode 100644
index 0000000..6acba7e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1725.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1725.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1725.wavetable
new file mode 100644
index 0000000..6d5240e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1725.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1726.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1726.wav
new file mode 100644
index 0000000..ebd90e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1726.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1726.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1726.wavetable
new file mode 100644
index 0000000..e8541e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1726.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1727.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1727.wav
new file mode 100644
index 0000000..b2f91d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1727.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1727.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1727.wavetable
new file mode 100644
index 0000000..39b4df0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1727.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1728.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1728.wav
new file mode 100644
index 0000000..1e84587
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1728.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1728.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1728.wavetable
new file mode 100644
index 0000000..2bba0dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1728.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1729.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1729.wav
new file mode 100644
index 0000000..4588890
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1729.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1729.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1729.wavetable
new file mode 100644
index 0000000..a37a88f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1729.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1730.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1730.wav
new file mode 100644
index 0000000..6b41025
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1730.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1730.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1730.wavetable
new file mode 100644
index 0000000..3e8a594
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1730.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1731.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1731.wav
new file mode 100644
index 0000000..86439dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1731.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1731.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1731.wavetable
new file mode 100644
index 0000000..a9fd231
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1731.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1732.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1732.wav
new file mode 100644
index 0000000..33b465d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1732.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1732.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1732.wavetable
new file mode 100644
index 0000000..919b1c7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1732.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1733.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1733.wav
new file mode 100644
index 0000000..eb8f2d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1733.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1733.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1733.wavetable
new file mode 100644
index 0000000..3c76202
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1733.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1734.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1734.wav
new file mode 100644
index 0000000..7f63736
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1734.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1734.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1734.wavetable
new file mode 100644
index 0000000..2c41d49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1734.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1735.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1735.wav
new file mode 100644
index 0000000..bcc9b1a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1735.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1735.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1735.wavetable
new file mode 100644
index 0000000..3ad213c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1735.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1736.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1736.wav
new file mode 100644
index 0000000..1175f52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1736.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1736.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1736.wavetable
new file mode 100644
index 0000000..3b116e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1736.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1737.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1737.wav
new file mode 100644
index 0000000..e5e642a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1737.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1737.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1737.wavetable
new file mode 100644
index 0000000..356942c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1737.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1738.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1738.wav
new file mode 100644
index 0000000..8182b77
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1738.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1738.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1738.wavetable
new file mode 100644
index 0000000..aaa7ac2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1738.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1739.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1739.wav
new file mode 100644
index 0000000..a8fb6ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1739.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1739.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1739.wavetable
new file mode 100644
index 0000000..f4364bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1739.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1740.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1740.wav
new file mode 100644
index 0000000..d35cd1d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1740.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1740.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1740.wavetable
new file mode 100644
index 0000000..5f72c33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1740.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1741.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1741.wav
new file mode 100644
index 0000000..76680d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1741.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1741.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1741.wavetable
new file mode 100644
index 0000000..7f5d1a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1741.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1742.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1742.wav
new file mode 100644
index 0000000..b7d31cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1742.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1742.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1742.wavetable
new file mode 100644
index 0000000..4696f54
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1742.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1743.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1743.wav
new file mode 100644
index 0000000..0dc5381
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1743.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1743.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1743.wavetable
new file mode 100644
index 0000000..9360249
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1743.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1744.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1744.wav
new file mode 100644
index 0000000..4fc5202
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1744.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1744.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1744.wavetable
new file mode 100644
index 0000000..ebf9f73
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1744.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1745.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1745.wav
new file mode 100644
index 0000000..5ce4775
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1745.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1745.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1745.wavetable
new file mode 100644
index 0000000..a3f9efb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1745.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1746.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1746.wav
new file mode 100644
index 0000000..92230f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1746.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1746.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1746.wavetable
new file mode 100644
index 0000000..bfe45ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1746.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1747.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1747.wav
new file mode 100644
index 0000000..1bcccc0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1747.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1747.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1747.wavetable
new file mode 100644
index 0000000..71176ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1747.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1748.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1748.wav
new file mode 100644
index 0000000..7e46c93
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1748.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1748.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1748.wavetable
new file mode 100644
index 0000000..6f36240
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1748.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1749.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1749.wav
new file mode 100644
index 0000000..62929b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1749.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1749.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1749.wavetable
new file mode 100644
index 0000000..23edbae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1749.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1750.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1750.wav
new file mode 100644
index 0000000..32f99ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1750.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1750.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1750.wavetable
new file mode 100644
index 0000000..df90bf4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1750.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1751.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1751.wav
new file mode 100644
index 0000000..8fc0484
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1751.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1751.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1751.wavetable
new file mode 100644
index 0000000..edf923c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1751.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1752.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1752.wav
new file mode 100644
index 0000000..9a16de2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1752.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1752.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1752.wavetable
new file mode 100644
index 0000000..d9ca2e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1752.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1753.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1753.wav
new file mode 100644
index 0000000..a574aa9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1753.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1753.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1753.wavetable
new file mode 100644
index 0000000..8261cbb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1753.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1754.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1754.wav
new file mode 100644
index 0000000..cfffe6a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1754.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1754.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1754.wavetable
new file mode 100644
index 0000000..559effa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1754.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1755.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1755.wav
new file mode 100644
index 0000000..d31f467
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1755.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1755.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1755.wavetable
new file mode 100644
index 0000000..492c6ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1755.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1756.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1756.wav
new file mode 100644
index 0000000..6be9c5e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1756.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1756.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1756.wavetable
new file mode 100644
index 0000000..a1b1b57
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1756.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1757.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1757.wav
new file mode 100644
index 0000000..02e91cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1757.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1757.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1757.wavetable
new file mode 100644
index 0000000..5f55354
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1757.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1758.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1758.wav
new file mode 100644
index 0000000..606ee8f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1758.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1758.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1758.wavetable
new file mode 100644
index 0000000..4fa0839
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1758.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1759.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1759.wav
new file mode 100644
index 0000000..11ad7b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1759.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1759.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1759.wavetable
new file mode 100644
index 0000000..f7faa07
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1759.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1760.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1760.wav
new file mode 100644
index 0000000..f1c9aae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1760.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1760.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1760.wavetable
new file mode 100644
index 0000000..15564a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1760.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1761.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1761.wav
new file mode 100644
index 0000000..8725c1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1761.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1761.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1761.wavetable
new file mode 100644
index 0000000..ac759ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1761.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1762.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1762.wav
new file mode 100644
index 0000000..2d88d2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1762.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1762.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1762.wavetable
new file mode 100644
index 0000000..3efd0f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1762.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1763.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1763.wav
new file mode 100644
index 0000000..6697a92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1763.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1763.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1763.wavetable
new file mode 100644
index 0000000..fcd9276
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1763.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1764.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1764.wav
new file mode 100644
index 0000000..b116d3f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1764.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1764.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1764.wavetable
new file mode 100644
index 0000000..e49435e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1764.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1765.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1765.wav
new file mode 100644
index 0000000..84cfbf6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1765.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1765.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1765.wavetable
new file mode 100644
index 0000000..1bbb4fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1765.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1766.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1766.wav
new file mode 100644
index 0000000..4e9ff09
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1766.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1766.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1766.wavetable
new file mode 100644
index 0000000..177bab1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1766.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1767.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1767.wav
new file mode 100644
index 0000000..0463e8d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1767.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1767.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1767.wavetable
new file mode 100644
index 0000000..0729de9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1767.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1768.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1768.wav
new file mode 100644
index 0000000..3f0c548
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1768.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1768.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1768.wavetable
new file mode 100644
index 0000000..e5b4984
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1768.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1769.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1769.wav
new file mode 100644
index 0000000..fd4dea3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1769.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1769.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1769.wavetable
new file mode 100644
index 0000000..00aaad0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1769.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1770.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1770.wav
new file mode 100644
index 0000000..80b13e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1770.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1770.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1770.wavetable
new file mode 100644
index 0000000..7c7fd35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1770.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1771.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1771.wav
new file mode 100644
index 0000000..99aeded
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1771.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1771.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1771.wavetable
new file mode 100644
index 0000000..1a70e5a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1771.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1772.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1772.wav
new file mode 100644
index 0000000..ad2da1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1772.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1772.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1772.wavetable
new file mode 100644
index 0000000..67d2bdf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1772.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1773.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1773.wav
new file mode 100644
index 0000000..9e9e676
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1773.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1773.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1773.wavetable
new file mode 100644
index 0000000..3216e15
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1773.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1774.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1774.wav
new file mode 100644
index 0000000..1782b68
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1774.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1774.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1774.wavetable
new file mode 100644
index 0000000..1a3bc6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1774.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1775.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1775.wav
new file mode 100644
index 0000000..0c9bdfb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1775.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1775.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1775.wavetable
new file mode 100644
index 0000000..812286d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1775.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1776.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1776.wav
new file mode 100644
index 0000000..f525a01
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1776.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1776.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1776.wavetable
new file mode 100644
index 0000000..f46c504
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1776.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1777.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1777.wav
new file mode 100644
index 0000000..cb37dea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1777.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1777.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1777.wavetable
new file mode 100644
index 0000000..860bdc3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1777.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1778.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1778.wav
new file mode 100644
index 0000000..803bbf1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1778.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1778.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1778.wavetable
new file mode 100644
index 0000000..07ede85
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1778.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1779.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1779.wav
new file mode 100644
index 0000000..42d75c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1779.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1779.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1779.wavetable
new file mode 100644
index 0000000..dd4bb1d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1779.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1780.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1780.wav
new file mode 100644
index 0000000..bbc445f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1780.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1780.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1780.wavetable
new file mode 100644
index 0000000..bdc95fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1780.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1781.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1781.wav
new file mode 100644
index 0000000..88bef64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1781.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1781.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1781.wavetable
new file mode 100644
index 0000000..4102bca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1781.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1782.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1782.wav
new file mode 100644
index 0000000..7487508
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1782.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1782.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1782.wavetable
new file mode 100644
index 0000000..18863b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1782.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1783.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1783.wav
new file mode 100644
index 0000000..ad9732f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1783.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1783.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1783.wavetable
new file mode 100644
index 0000000..37004d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1783.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1784.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1784.wav
new file mode 100644
index 0000000..ae02c90
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1784.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1784.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1784.wavetable
new file mode 100644
index 0000000..9b5128c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1784.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1785.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1785.wav
new file mode 100644
index 0000000..a47f491
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1785.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1785.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1785.wavetable
new file mode 100644
index 0000000..0da0aa3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1785.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1786.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1786.wav
new file mode 100644
index 0000000..f607df9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1786.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1786.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1786.wavetable
new file mode 100644
index 0000000..d4355e2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1786.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1787.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1787.wav
new file mode 100644
index 0000000..ddaebeb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1787.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1787.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1787.wavetable
new file mode 100644
index 0000000..0ffffa1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1787.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1788.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1788.wav
new file mode 100644
index 0000000..d7e12a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1788.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1788.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1788.wavetable
new file mode 100644
index 0000000..352759c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1788.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1789.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1789.wav
new file mode 100644
index 0000000..ca433f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1789.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1789.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1789.wavetable
new file mode 100644
index 0000000..d6c082a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1789.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1790.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1790.wav
new file mode 100644
index 0000000..1968597
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1790.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1790.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1790.wavetable
new file mode 100644
index 0000000..46f9c7b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1790.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1791.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1791.wav
new file mode 100644
index 0000000..4e65894
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1791.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1791.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1791.wavetable
new file mode 100644
index 0000000..0b4466a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1791.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1792.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1792.wav
new file mode 100644
index 0000000..740543b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1792.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1792.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1792.wavetable
new file mode 100644
index 0000000..f72f6f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1792.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1793.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1793.wav
new file mode 100644
index 0000000..462503c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1793.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1793.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1793.wavetable
new file mode 100644
index 0000000..ee322d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1793.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1794.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1794.wav
new file mode 100644
index 0000000..af9318a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1794.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1794.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1794.wavetable
new file mode 100644
index 0000000..fdf6091
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1794.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1795.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1795.wav
new file mode 100644
index 0000000..2e8bc9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1795.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1795.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1795.wavetable
new file mode 100644
index 0000000..63eeeb1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1795.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1796.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1796.wav
new file mode 100644
index 0000000..5810e1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1796.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1796.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1796.wavetable
new file mode 100644
index 0000000..cb4c5b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1796.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1797.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1797.wav
new file mode 100644
index 0000000..53b5ba3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1797.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1797.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1797.wavetable
new file mode 100644
index 0000000..44ff08a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1797.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1798.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1798.wav
new file mode 100644
index 0000000..8216687
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1798.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1798.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1798.wavetable
new file mode 100644
index 0000000..1b799b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1798.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1799.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1799.wav
new file mode 100644
index 0000000..6c50e4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1799.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1799.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1799.wavetable
new file mode 100644
index 0000000..a2f1d3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1799.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1800.wav b/etc/wavetables/AKWF/AKWF_0018/AKWF_1800.wav
new file mode 100644
index 0000000..094e36c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1800.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AKWF_1800.wavetable b/etc/wavetables/AKWF/AKWF_0018/AKWF_1800.wavetable
new file mode 100644
index 0000000..2506a37
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0018/AKWF_1800.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0018/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0018/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0018/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1801.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1801.wav
new file mode 100644
index 0000000..8d889cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1801.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1801.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1801.wavetable
new file mode 100644
index 0000000..76c8268
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1801.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1802.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1802.wav
new file mode 100644
index 0000000..41180d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1802.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1802.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1802.wavetable
new file mode 100644
index 0000000..943ccbb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1802.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1803.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1803.wav
new file mode 100644
index 0000000..1916705
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1803.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1803.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1803.wavetable
new file mode 100644
index 0000000..550bdd8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1803.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1804.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1804.wav
new file mode 100644
index 0000000..dc250e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1804.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1804.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1804.wavetable
new file mode 100644
index 0000000..2892f7c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1804.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1805.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1805.wav
new file mode 100644
index 0000000..6c7c416
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1805.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1805.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1805.wavetable
new file mode 100644
index 0000000..700f57c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1805.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1806.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1806.wav
new file mode 100644
index 0000000..13e5364
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1806.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1806.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1806.wavetable
new file mode 100644
index 0000000..49f9868
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1806.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1807.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1807.wav
new file mode 100644
index 0000000..6dab8e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1807.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1807.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1807.wavetable
new file mode 100644
index 0000000..18a9ed1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1807.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1808.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1808.wav
new file mode 100644
index 0000000..4ae2c32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1808.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1808.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1808.wavetable
new file mode 100644
index 0000000..8c31bd9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1808.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1809.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1809.wav
new file mode 100644
index 0000000..010fcd3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1809.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1809.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1809.wavetable
new file mode 100644
index 0000000..af46717
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1809.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1810.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1810.wav
new file mode 100644
index 0000000..f0853cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1810.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1810.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1810.wavetable
new file mode 100644
index 0000000..0f2a14a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1810.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1811.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1811.wav
new file mode 100644
index 0000000..ebb4329
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1811.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1811.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1811.wavetable
new file mode 100644
index 0000000..b56def3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1811.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1812.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1812.wav
new file mode 100644
index 0000000..946edfd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1812.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1812.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1812.wavetable
new file mode 100644
index 0000000..0545565
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1812.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1813.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1813.wav
new file mode 100644
index 0000000..f879e4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1813.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1813.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1813.wavetable
new file mode 100644
index 0000000..8b5de58
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1813.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1814.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1814.wav
new file mode 100644
index 0000000..63116fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1814.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1814.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1814.wavetable
new file mode 100644
index 0000000..d557b5a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1814.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1815.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1815.wav
new file mode 100644
index 0000000..0b84750
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1815.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1815.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1815.wavetable
new file mode 100644
index 0000000..a3766fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1815.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1816.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1816.wav
new file mode 100644
index 0000000..68b9180
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1816.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1816.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1816.wavetable
new file mode 100644
index 0000000..aa104db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1816.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1817.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1817.wav
new file mode 100644
index 0000000..b79b63f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1817.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1817.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1817.wavetable
new file mode 100644
index 0000000..f1234ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1817.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1818.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1818.wav
new file mode 100644
index 0000000..2002c1f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1818.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1818.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1818.wavetable
new file mode 100644
index 0000000..af7cadb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1818.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1819.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1819.wav
new file mode 100644
index 0000000..81245fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1819.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1819.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1819.wavetable
new file mode 100644
index 0000000..8455372
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1819.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1820.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1820.wav
new file mode 100644
index 0000000..e45b8fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1820.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1820.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1820.wavetable
new file mode 100644
index 0000000..c1c84f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1820.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1821.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1821.wav
new file mode 100644
index 0000000..7e8e534
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1821.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1821.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1821.wavetable
new file mode 100644
index 0000000..8e7eb69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1821.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1822.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1822.wav
new file mode 100644
index 0000000..c6df822
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1822.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1822.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1822.wavetable
new file mode 100644
index 0000000..8d462b7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1822.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1823.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1823.wav
new file mode 100644
index 0000000..af9d2fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1823.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1823.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1823.wavetable
new file mode 100644
index 0000000..a7507da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1823.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1824.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1824.wav
new file mode 100644
index 0000000..bde0dd5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1824.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1824.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1824.wavetable
new file mode 100644
index 0000000..022c7ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1824.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1825.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1825.wav
new file mode 100644
index 0000000..3a93c7c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1825.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1825.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1825.wavetable
new file mode 100644
index 0000000..0453f32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1825.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1826.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1826.wav
new file mode 100644
index 0000000..cb36224
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1826.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1826.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1826.wavetable
new file mode 100644
index 0000000..ddf5457
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1826.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1827.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1827.wav
new file mode 100644
index 0000000..8f102b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1827.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1827.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1827.wavetable
new file mode 100644
index 0000000..932d355
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1827.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1828.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1828.wav
new file mode 100644
index 0000000..efec169
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1828.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1828.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1828.wavetable
new file mode 100644
index 0000000..56b8687
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1828.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1829.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1829.wav
new file mode 100644
index 0000000..1d14bc3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1829.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1829.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1829.wavetable
new file mode 100644
index 0000000..dc1efe3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1829.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1830.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1830.wav
new file mode 100644
index 0000000..6924405
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1830.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1830.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1830.wavetable
new file mode 100644
index 0000000..38fe498
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1830.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1831.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1831.wav
new file mode 100644
index 0000000..a01076c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1831.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1831.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1831.wavetable
new file mode 100644
index 0000000..a0a3fbd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1831.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1832.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1832.wav
new file mode 100644
index 0000000..627c829
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1832.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1832.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1832.wavetable
new file mode 100644
index 0000000..3a2acac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1832.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1833.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1833.wav
new file mode 100644
index 0000000..4798fdc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1833.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1833.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1833.wavetable
new file mode 100644
index 0000000..d34da72
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1833.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1834.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1834.wav
new file mode 100644
index 0000000..31f6667
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1834.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1834.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1834.wavetable
new file mode 100644
index 0000000..718762c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1834.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1835.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1835.wav
new file mode 100644
index 0000000..4869e36
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1835.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1835.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1835.wavetable
new file mode 100644
index 0000000..617162c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1835.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1836.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1836.wav
new file mode 100644
index 0000000..cf9f3b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1836.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1836.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1836.wavetable
new file mode 100644
index 0000000..c5a3318
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1836.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1837.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1837.wav
new file mode 100644
index 0000000..a477555
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1837.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1837.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1837.wavetable
new file mode 100644
index 0000000..8b1de23
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1837.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1838.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1838.wav
new file mode 100644
index 0000000..2df7f68
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1838.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1838.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1838.wavetable
new file mode 100644
index 0000000..913ebda
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1838.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1839.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1839.wav
new file mode 100644
index 0000000..271b020
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1839.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1839.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1839.wavetable
new file mode 100644
index 0000000..5c2dcfb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1839.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1840.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1840.wav
new file mode 100644
index 0000000..3cc10f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1840.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1840.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1840.wavetable
new file mode 100644
index 0000000..5bfb5bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1840.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1841.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1841.wav
new file mode 100644
index 0000000..6af84a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1841.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1841.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1841.wavetable
new file mode 100644
index 0000000..dfd5312
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1841.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1842.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1842.wav
new file mode 100644
index 0000000..6482c49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1842.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1842.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1842.wavetable
new file mode 100644
index 0000000..c6a0df6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1842.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1843.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1843.wav
new file mode 100644
index 0000000..9bbb85a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1843.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1843.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1843.wavetable
new file mode 100644
index 0000000..f7b63f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1843.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1844.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1844.wav
new file mode 100644
index 0000000..dc1e997
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1844.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1844.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1844.wavetable
new file mode 100644
index 0000000..73986ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1844.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1845.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1845.wav
new file mode 100644
index 0000000..458c132
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1845.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1845.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1845.wavetable
new file mode 100644
index 0000000..fe9a555
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1845.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1846.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1846.wav
new file mode 100644
index 0000000..0446c28
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1846.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1846.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1846.wavetable
new file mode 100644
index 0000000..d1416ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1846.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1847.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1847.wav
new file mode 100644
index 0000000..ad40468
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1847.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1847.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1847.wavetable
new file mode 100644
index 0000000..ccbbbe3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1847.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1848.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1848.wav
new file mode 100644
index 0000000..0bae50f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1848.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1848.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1848.wavetable
new file mode 100644
index 0000000..6037d6d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1848.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1849.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1849.wav
new file mode 100644
index 0000000..720ce4d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1849.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1849.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1849.wavetable
new file mode 100644
index 0000000..1b15182
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1849.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1850.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1850.wav
new file mode 100644
index 0000000..6d22b24
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1850.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1850.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1850.wavetable
new file mode 100644
index 0000000..c74f286
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1850.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1851.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1851.wav
new file mode 100644
index 0000000..1a8108d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1851.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1851.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1851.wavetable
new file mode 100644
index 0000000..8f2eede
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1851.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1852.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1852.wav
new file mode 100644
index 0000000..a25751e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1852.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1852.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1852.wavetable
new file mode 100644
index 0000000..8c05341
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1852.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1853.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1853.wav
new file mode 100644
index 0000000..ad23574
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1853.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1853.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1853.wavetable
new file mode 100644
index 0000000..865a44f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1853.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1854.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1854.wav
new file mode 100644
index 0000000..4a3b217
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1854.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1854.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1854.wavetable
new file mode 100644
index 0000000..301c633
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1854.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1855.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1855.wav
new file mode 100644
index 0000000..b230171
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1855.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1855.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1855.wavetable
new file mode 100644
index 0000000..b2b72e3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1855.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1856.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1856.wav
new file mode 100644
index 0000000..f9da7f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1856.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1856.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1856.wavetable
new file mode 100644
index 0000000..8d0d0b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1856.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1857.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1857.wav
new file mode 100644
index 0000000..188670f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1857.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1857.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1857.wavetable
new file mode 100644
index 0000000..760873c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1857.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1858.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1858.wav
new file mode 100644
index 0000000..428bf44
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1858.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1858.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1858.wavetable
new file mode 100644
index 0000000..c135c83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1858.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1859.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1859.wav
new file mode 100644
index 0000000..cc1615b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1859.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1859.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1859.wavetable
new file mode 100644
index 0000000..4f72f85
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1859.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1860.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1860.wav
new file mode 100644
index 0000000..8e9c47d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1860.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1860.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1860.wavetable
new file mode 100644
index 0000000..ea1ea03
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1860.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1861.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1861.wav
new file mode 100644
index 0000000..a7f1526
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1861.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1861.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1861.wavetable
new file mode 100644
index 0000000..d620a76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1861.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1862.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1862.wav
new file mode 100644
index 0000000..901e026
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1862.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1862.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1862.wavetable
new file mode 100644
index 0000000..47e264f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1862.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1863.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1863.wav
new file mode 100644
index 0000000..036c6fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1863.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1863.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1863.wavetable
new file mode 100644
index 0000000..592eb16
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1863.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1864.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1864.wav
new file mode 100644
index 0000000..5c8b3ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1864.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1864.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1864.wavetable
new file mode 100644
index 0000000..afc122c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1864.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1865.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1865.wav
new file mode 100644
index 0000000..a3f45c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1865.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1865.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1865.wavetable
new file mode 100644
index 0000000..2e00907
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1865.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1866.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1866.wav
new file mode 100644
index 0000000..8db29e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1866.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1866.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1866.wavetable
new file mode 100644
index 0000000..45f722c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1866.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1867.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1867.wav
new file mode 100644
index 0000000..6fcdc2d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1867.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1867.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1867.wavetable
new file mode 100644
index 0000000..c58b2fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1867.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1868.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1868.wav
new file mode 100644
index 0000000..0f53501
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1868.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1868.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1868.wavetable
new file mode 100644
index 0000000..d4e9ea0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1868.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1869.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1869.wav
new file mode 100644
index 0000000..8a81917
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1869.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1869.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1869.wavetable
new file mode 100644
index 0000000..c1d1678
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1869.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1870.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1870.wav
new file mode 100644
index 0000000..af18fc2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1870.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1870.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1870.wavetable
new file mode 100644
index 0000000..9b5a2ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1870.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1871.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1871.wav
new file mode 100644
index 0000000..9b820d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1871.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1871.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1871.wavetable
new file mode 100644
index 0000000..955d044
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1871.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1872.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1872.wav
new file mode 100644
index 0000000..1500a18
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1872.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1872.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1872.wavetable
new file mode 100644
index 0000000..17f4381
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1872.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1873.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1873.wav
new file mode 100644
index 0000000..6ba9e4f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1873.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1873.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1873.wavetable
new file mode 100644
index 0000000..574f2d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1873.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1874.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1874.wav
new file mode 100644
index 0000000..53af70c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1874.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1874.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1874.wavetable
new file mode 100644
index 0000000..e7fef76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1874.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1875.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1875.wav
new file mode 100644
index 0000000..337a372
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1875.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1875.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1875.wavetable
new file mode 100644
index 0000000..11b508f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1875.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1876.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1876.wav
new file mode 100644
index 0000000..3cc42dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1876.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1876.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1876.wavetable
new file mode 100644
index 0000000..86432c7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1876.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1877.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1877.wav
new file mode 100644
index 0000000..8301d58
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1877.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1877.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1877.wavetable
new file mode 100644
index 0000000..bc00e45
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1877.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1878.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1878.wav
new file mode 100644
index 0000000..4d2712e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1878.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1878.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1878.wavetable
new file mode 100644
index 0000000..5f77383
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1878.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1879.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1879.wav
new file mode 100644
index 0000000..9d16b4a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1879.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1879.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1879.wavetable
new file mode 100644
index 0000000..470fc63
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1879.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1880.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1880.wav
new file mode 100644
index 0000000..1b7bf64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1880.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1880.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1880.wavetable
new file mode 100644
index 0000000..18bd5ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1880.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1881.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1881.wav
new file mode 100644
index 0000000..f265dda
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1881.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1881.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1881.wavetable
new file mode 100644
index 0000000..83bff49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1881.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1882.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1882.wav
new file mode 100644
index 0000000..65da7fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1882.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1882.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1882.wavetable
new file mode 100644
index 0000000..44b45d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1882.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1883.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1883.wav
new file mode 100644
index 0000000..789fa34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1883.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1883.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1883.wavetable
new file mode 100644
index 0000000..464e2cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1883.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1884.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1884.wav
new file mode 100644
index 0000000..972dd60
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1884.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1884.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1884.wavetable
new file mode 100644
index 0000000..8a4127f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1884.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1885.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1885.wav
new file mode 100644
index 0000000..eb2011e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1885.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1885.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1885.wavetable
new file mode 100644
index 0000000..63e3332
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1885.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1886.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1886.wav
new file mode 100644
index 0000000..248246b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1886.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1886.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1886.wavetable
new file mode 100644
index 0000000..dbdb151
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1886.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1887.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1887.wav
new file mode 100644
index 0000000..4b5980c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1887.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1887.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1887.wavetable
new file mode 100644
index 0000000..bbcda2d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1887.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1888.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1888.wav
new file mode 100644
index 0000000..8e10fa7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1888.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1888.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1888.wavetable
new file mode 100644
index 0000000..edeb235
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1888.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1889.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1889.wav
new file mode 100644
index 0000000..bd77ec5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1889.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1889.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1889.wavetable
new file mode 100644
index 0000000..f6b07a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1889.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1890.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1890.wav
new file mode 100644
index 0000000..92e749b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1890.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1890.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1890.wavetable
new file mode 100644
index 0000000..c000052
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1890.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1891.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1891.wav
new file mode 100644
index 0000000..870a6c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1891.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1891.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1891.wavetable
new file mode 100644
index 0000000..a8c3763
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1891.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1892.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1892.wav
new file mode 100644
index 0000000..8bfa4a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1892.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1892.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1892.wavetable
new file mode 100644
index 0000000..9a763e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1892.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1893.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1893.wav
new file mode 100644
index 0000000..2dabfa1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1893.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1893.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1893.wavetable
new file mode 100644
index 0000000..a6459c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1893.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1894.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1894.wav
new file mode 100644
index 0000000..05960c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1894.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1894.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1894.wavetable
new file mode 100644
index 0000000..e8afa4a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1894.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1895.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1895.wav
new file mode 100644
index 0000000..f5c2392
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1895.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1895.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1895.wavetable
new file mode 100644
index 0000000..c50e3bd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1895.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1896.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1896.wav
new file mode 100644
index 0000000..80c0d34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1896.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1896.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1896.wavetable
new file mode 100644
index 0000000..c26492d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1896.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1897.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1897.wav
new file mode 100644
index 0000000..335e4f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1897.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1897.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1897.wavetable
new file mode 100644
index 0000000..7a95e70
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1897.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1898.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1898.wav
new file mode 100644
index 0000000..755d698
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1898.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1898.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1898.wavetable
new file mode 100644
index 0000000..812867c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1898.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1899.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1899.wav
new file mode 100644
index 0000000..4f612a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1899.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1899.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1899.wavetable
new file mode 100644
index 0000000..014ca2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1899.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1900.wav b/etc/wavetables/AKWF/AKWF_0019/AKWF_1900.wav
new file mode 100644
index 0000000..2a9ac8d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1900.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AKWF_1900.wavetable b/etc/wavetables/AKWF/AKWF_0019/AKWF_1900.wavetable
new file mode 100644
index 0000000..8ef192c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0019/AKWF_1900.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0019/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0019/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0019/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1901.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1901.wav
new file mode 100644
index 0000000..55e89ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1901.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1901.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1901.wavetable
new file mode 100644
index 0000000..710af16
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1901.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1902.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1902.wav
new file mode 100644
index 0000000..3daf8cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1902.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1902.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1902.wavetable
new file mode 100644
index 0000000..32d63f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1902.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1903.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1903.wav
new file mode 100644
index 0000000..1d6f1ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1903.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1903.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1903.wavetable
new file mode 100644
index 0000000..15953be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1903.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1904.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1904.wav
new file mode 100644
index 0000000..dcfa96b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1904.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1904.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1904.wavetable
new file mode 100644
index 0000000..6461d38
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1904.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1905.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1905.wav
new file mode 100644
index 0000000..897715c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1905.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1905.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1905.wavetable
new file mode 100644
index 0000000..0b972e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1905.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1906.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1906.wav
new file mode 100644
index 0000000..8875a70
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1906.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1906.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1906.wavetable
new file mode 100644
index 0000000..f7643b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1906.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1907.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1907.wav
new file mode 100644
index 0000000..a4cc047
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1907.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1907.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1907.wavetable
new file mode 100644
index 0000000..4391f4d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1907.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1908.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1908.wav
new file mode 100644
index 0000000..5986f94
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1908.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1908.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1908.wavetable
new file mode 100644
index 0000000..c9eaf61
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1908.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1909.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1909.wav
new file mode 100644
index 0000000..4f08293
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1909.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1909.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1909.wavetable
new file mode 100644
index 0000000..1abe5a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1909.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1910.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1910.wav
new file mode 100644
index 0000000..90b6fce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1910.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1910.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1910.wavetable
new file mode 100644
index 0000000..c9851a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1910.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1911.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1911.wav
new file mode 100644
index 0000000..3495e24
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1911.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1911.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1911.wavetable
new file mode 100644
index 0000000..4d9f14b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1911.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1912.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1912.wav
new file mode 100644
index 0000000..e07e2f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1912.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1912.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1912.wavetable
new file mode 100644
index 0000000..427802e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1912.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1913.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1913.wav
new file mode 100644
index 0000000..6c36cd2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1913.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1913.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1913.wavetable
new file mode 100644
index 0000000..6cbb25b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1913.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1914.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1914.wav
new file mode 100644
index 0000000..45db768
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1914.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1914.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1914.wavetable
new file mode 100644
index 0000000..bef858e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1914.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1915.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1915.wav
new file mode 100644
index 0000000..602b622
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1915.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1915.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1915.wavetable
new file mode 100644
index 0000000..a7ec53a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1915.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1916.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1916.wav
new file mode 100644
index 0000000..107a277
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1916.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1916.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1916.wavetable
new file mode 100644
index 0000000..6b0cee6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1916.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1917.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1917.wav
new file mode 100644
index 0000000..74f60fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1917.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1917.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1917.wavetable
new file mode 100644
index 0000000..04a8e3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1917.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1918.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1918.wav
new file mode 100644
index 0000000..b152286
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1918.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1918.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1918.wavetable
new file mode 100644
index 0000000..e1db271
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1918.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1919.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1919.wav
new file mode 100644
index 0000000..ebb9232
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1919.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1919.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1919.wavetable
new file mode 100644
index 0000000..ba28b15
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1919.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1920.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1920.wav
new file mode 100644
index 0000000..e9def90
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1920.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1920.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1920.wavetable
new file mode 100644
index 0000000..9ddc8b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1920.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1921.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1921.wav
new file mode 100644
index 0000000..2a46cf6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1921.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1921.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1921.wavetable
new file mode 100644
index 0000000..d3517b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1921.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1922.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1922.wav
new file mode 100644
index 0000000..f636493
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1922.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1922.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1922.wavetable
new file mode 100644
index 0000000..634829e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1922.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1923.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1923.wav
new file mode 100644
index 0000000..e454091
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1923.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1923.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1923.wavetable
new file mode 100644
index 0000000..e6110ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1923.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1924.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1924.wav
new file mode 100644
index 0000000..7e8f1c7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1924.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1924.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1924.wavetable
new file mode 100644
index 0000000..3c0ebbc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1924.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1925.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1925.wav
new file mode 100644
index 0000000..d84eaef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1925.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1925.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1925.wavetable
new file mode 100644
index 0000000..a68f8d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1925.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1926.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1926.wav
new file mode 100644
index 0000000..a42289b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1926.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1926.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1926.wavetable
new file mode 100644
index 0000000..9bab417
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1926.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1927.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1927.wav
new file mode 100644
index 0000000..5b4002c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1927.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1927.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1927.wavetable
new file mode 100644
index 0000000..2716751
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1927.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1928.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1928.wav
new file mode 100644
index 0000000..603fed4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1928.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1928.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1928.wavetable
new file mode 100644
index 0000000..2e56508
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1928.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1929.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1929.wav
new file mode 100644
index 0000000..c4094a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1929.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1929.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1929.wavetable
new file mode 100644
index 0000000..49fb2c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1929.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1930.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1930.wav
new file mode 100644
index 0000000..e271b88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1930.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1930.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1930.wavetable
new file mode 100644
index 0000000..7c720f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1930.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1931.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1931.wav
new file mode 100644
index 0000000..252ac25
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1931.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1931.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1931.wavetable
new file mode 100644
index 0000000..c98c9b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1931.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1932.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1932.wav
new file mode 100644
index 0000000..fb53351
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1932.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1932.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1932.wavetable
new file mode 100644
index 0000000..48044f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1932.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1933.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1933.wav
new file mode 100644
index 0000000..5520416
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1933.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1933.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1933.wavetable
new file mode 100644
index 0000000..c1fea1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1933.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1934.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1934.wav
new file mode 100644
index 0000000..3b399b3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1934.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1934.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1934.wavetable
new file mode 100644
index 0000000..f0cdd75
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1934.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1935.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1935.wav
new file mode 100644
index 0000000..62ac3d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1935.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1935.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1935.wavetable
new file mode 100644
index 0000000..ee6651f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1935.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1936.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1936.wav
new file mode 100644
index 0000000..c58d06f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1936.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1936.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1936.wavetable
new file mode 100644
index 0000000..44ceb38
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1936.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1937.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1937.wav
new file mode 100644
index 0000000..6dc2d33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1937.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1937.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1937.wavetable
new file mode 100644
index 0000000..4f6ae6e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1937.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1938.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1938.wav
new file mode 100644
index 0000000..b2be579
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1938.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1938.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1938.wavetable
new file mode 100644
index 0000000..5420644
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1938.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1939.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1939.wav
new file mode 100644
index 0000000..b9c62b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1939.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1939.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1939.wavetable
new file mode 100644
index 0000000..d4eb1ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1939.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1940.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1940.wav
new file mode 100644
index 0000000..5347787
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1940.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1940.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1940.wavetable
new file mode 100644
index 0000000..6c54fe0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1940.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1941.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1941.wav
new file mode 100644
index 0000000..60fbdca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1941.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1941.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1941.wavetable
new file mode 100644
index 0000000..85914f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1941.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1942.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1942.wav
new file mode 100644
index 0000000..5e25414
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1942.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1942.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1942.wavetable
new file mode 100644
index 0000000..c161f90
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1942.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1943.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1943.wav
new file mode 100644
index 0000000..22336cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1943.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1943.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1943.wavetable
new file mode 100644
index 0000000..a1f567e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1943.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1944.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1944.wav
new file mode 100644
index 0000000..940bd83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1944.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1944.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1944.wavetable
new file mode 100644
index 0000000..728e484
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1944.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1945.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1945.wav
new file mode 100644
index 0000000..7a160d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1945.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1945.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1945.wavetable
new file mode 100644
index 0000000..9c00f2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1945.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1946.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1946.wav
new file mode 100644
index 0000000..9ff7e77
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1946.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1946.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1946.wavetable
new file mode 100644
index 0000000..1a4f04d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1946.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1947.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1947.wav
new file mode 100644
index 0000000..1e70cc4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1947.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1947.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1947.wavetable
new file mode 100644
index 0000000..d4bc6b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1947.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1948.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1948.wav
new file mode 100644
index 0000000..7982dd4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1948.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1948.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1948.wavetable
new file mode 100644
index 0000000..404dd21
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1948.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1949.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1949.wav
new file mode 100644
index 0000000..4846f26
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1949.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1949.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1949.wavetable
new file mode 100644
index 0000000..75c53e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1949.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1950.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1950.wav
new file mode 100644
index 0000000..d53c5b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1950.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1950.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1950.wavetable
new file mode 100644
index 0000000..9884e99
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1950.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1951.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1951.wav
new file mode 100644
index 0000000..ec3536b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1951.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1951.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1951.wavetable
new file mode 100644
index 0000000..345142c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1951.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1952.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1952.wav
new file mode 100644
index 0000000..0fe5a1f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1952.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1952.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1952.wavetable
new file mode 100644
index 0000000..3ebd7ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1952.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1953.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1953.wav
new file mode 100644
index 0000000..6d42026
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1953.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1953.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1953.wavetable
new file mode 100644
index 0000000..aa41a47
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1953.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1954.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1954.wav
new file mode 100644
index 0000000..3639546
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1954.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1954.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1954.wavetable
new file mode 100644
index 0000000..926e624
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1954.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1955.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1955.wav
new file mode 100644
index 0000000..834eb4b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1955.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1955.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1955.wavetable
new file mode 100644
index 0000000..5e3c834
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1955.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1956.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1956.wav
new file mode 100644
index 0000000..45ca99e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1956.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1956.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1956.wavetable
new file mode 100644
index 0000000..58248a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1956.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1957.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1957.wav
new file mode 100644
index 0000000..4d32c5f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1957.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1957.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1957.wavetable
new file mode 100644
index 0000000..b211c72
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1957.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1958.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1958.wav
new file mode 100644
index 0000000..1f04466
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1958.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1958.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1958.wavetable
new file mode 100644
index 0000000..1229268
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1958.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1959.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1959.wav
new file mode 100644
index 0000000..218e638
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1959.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1959.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1959.wavetable
new file mode 100644
index 0000000..b806b8a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1959.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1960.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1960.wav
new file mode 100644
index 0000000..a023d1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1960.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1960.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1960.wavetable
new file mode 100644
index 0000000..2d5d5cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1960.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1961.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1961.wav
new file mode 100644
index 0000000..cb193cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1961.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1961.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1961.wavetable
new file mode 100644
index 0000000..5b41211
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1961.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1962.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1962.wav
new file mode 100644
index 0000000..e94956b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1962.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1962.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1962.wavetable
new file mode 100644
index 0000000..413b4f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1962.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1963.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1963.wav
new file mode 100644
index 0000000..21cf22b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1963.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1963.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1963.wavetable
new file mode 100644
index 0000000..5442940
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1963.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1964.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1964.wav
new file mode 100644
index 0000000..da3cdfc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1964.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1964.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1964.wavetable
new file mode 100644
index 0000000..69df153
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1964.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1965.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1965.wav
new file mode 100644
index 0000000..ea95f0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1965.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1965.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1965.wavetable
new file mode 100644
index 0000000..8bdfa01
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1965.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1966.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1966.wav
new file mode 100644
index 0000000..bc6f7fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1966.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1966.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1966.wavetable
new file mode 100644
index 0000000..db0a2ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1966.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1967.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1967.wav
new file mode 100644
index 0000000..1a3f8f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1967.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1967.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1967.wavetable
new file mode 100644
index 0000000..cdc29c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1967.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1968.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1968.wav
new file mode 100644
index 0000000..55877e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1968.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1968.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1968.wavetable
new file mode 100644
index 0000000..514e220
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1968.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1969.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1969.wav
new file mode 100644
index 0000000..45cdc73
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1969.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1969.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1969.wavetable
new file mode 100644
index 0000000..13cf9c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1969.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1970.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1970.wav
new file mode 100644
index 0000000..c3b43d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1970.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1970.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1970.wavetable
new file mode 100644
index 0000000..98ffa7d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1970.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1971.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1971.wav
new file mode 100644
index 0000000..d118a4a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1971.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1971.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1971.wavetable
new file mode 100644
index 0000000..5e1ea8d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1971.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1972.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1972.wav
new file mode 100644
index 0000000..e5c82d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1972.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1972.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1972.wavetable
new file mode 100644
index 0000000..40cef6f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1972.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1973.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1973.wav
new file mode 100644
index 0000000..8e844f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1973.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1973.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1973.wavetable
new file mode 100644
index 0000000..987f4f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1973.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1974.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1974.wav
new file mode 100644
index 0000000..fec60fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1974.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1974.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1974.wavetable
new file mode 100644
index 0000000..e0ebf5e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1974.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1975.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1975.wav
new file mode 100644
index 0000000..8f3c96d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1975.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1975.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1975.wavetable
new file mode 100644
index 0000000..81861a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1975.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1976.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1976.wav
new file mode 100644
index 0000000..1f3fae4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1976.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1976.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1976.wavetable
new file mode 100644
index 0000000..d234d4b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1976.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1977.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1977.wav
new file mode 100644
index 0000000..3e75a15
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1977.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1977.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1977.wavetable
new file mode 100644
index 0000000..346de36
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1977.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1978.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1978.wav
new file mode 100644
index 0000000..a5af907
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1978.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1978.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1978.wavetable
new file mode 100644
index 0000000..13a4192
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1978.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1979.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1979.wav
new file mode 100644
index 0000000..7277067
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1979.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1979.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1979.wavetable
new file mode 100644
index 0000000..3b39ff5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1979.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1980.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1980.wav
new file mode 100644
index 0000000..d5ba834
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1980.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1980.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1980.wavetable
new file mode 100644
index 0000000..04b3030
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1980.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1981.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1981.wav
new file mode 100644
index 0000000..a55529b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1981.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1981.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1981.wavetable
new file mode 100644
index 0000000..bdda775
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1981.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1982.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1982.wav
new file mode 100644
index 0000000..f0cb07e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1982.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1982.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1982.wavetable
new file mode 100644
index 0000000..ae6adb3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1982.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1983.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1983.wav
new file mode 100644
index 0000000..6b26b31
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1983.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1983.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1983.wavetable
new file mode 100644
index 0000000..41e4631
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1983.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1984.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1984.wav
new file mode 100644
index 0000000..14b6d56
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1984.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1984.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1984.wavetable
new file mode 100644
index 0000000..92aba49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1984.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1985.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1985.wav
new file mode 100644
index 0000000..428f748
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1985.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1985.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1985.wavetable
new file mode 100644
index 0000000..f746a22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1985.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1986.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1986.wav
new file mode 100644
index 0000000..e66d2f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1986.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1986.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1986.wavetable
new file mode 100644
index 0000000..01f3f4f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1986.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1987.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1987.wav
new file mode 100644
index 0000000..6f7deb3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1987.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1987.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1987.wavetable
new file mode 100644
index 0000000..59f9484
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1987.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1988.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1988.wav
new file mode 100644
index 0000000..24aa138
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1988.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1988.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1988.wavetable
new file mode 100644
index 0000000..64a6b8e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1988.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1989.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1989.wav
new file mode 100644
index 0000000..581a333
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1989.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1989.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1989.wavetable
new file mode 100644
index 0000000..c6be740
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1989.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1990.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1990.wav
new file mode 100644
index 0000000..b29e506
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1990.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1990.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1990.wavetable
new file mode 100644
index 0000000..54d0c7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1990.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1991.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1991.wav
new file mode 100644
index 0000000..b74e150
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1991.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1991.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1991.wavetable
new file mode 100644
index 0000000..607f672
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1991.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1992.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1992.wav
new file mode 100644
index 0000000..f0fa39f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1992.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1992.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1992.wavetable
new file mode 100644
index 0000000..81bb195
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1992.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1993.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1993.wav
new file mode 100644
index 0000000..b885580
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1993.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1993.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1993.wavetable
new file mode 100644
index 0000000..ad14e71
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1993.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1994.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1994.wav
new file mode 100644
index 0000000..8a80515
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1994.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1994.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1994.wavetable
new file mode 100644
index 0000000..c48d7dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1994.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1995.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1995.wav
new file mode 100644
index 0000000..ec562ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1995.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1995.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1995.wavetable
new file mode 100644
index 0000000..c02af91
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1995.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1996.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1996.wav
new file mode 100644
index 0000000..ae05e96
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1996.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1996.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1996.wavetable
new file mode 100644
index 0000000..996b990
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1996.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1997.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1997.wav
new file mode 100644
index 0000000..61ab9d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1997.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1997.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1997.wavetable
new file mode 100644
index 0000000..d959175
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1997.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1998.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1998.wav
new file mode 100644
index 0000000..1fc2ae0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1998.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1998.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1998.wavetable
new file mode 100644
index 0000000..5805335
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1998.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1999.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_1999.wav
new file mode 100644
index 0000000..5099b7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1999.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_1999.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_1999.wavetable
new file mode 100644
index 0000000..e357915
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_1999.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2000.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_2000.wav
new file mode 100644
index 0000000..4033851
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2000.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2000.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_2000.wavetable
new file mode 100644
index 0000000..cb57c72
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2000.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2001.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_2001.wav
new file mode 100644
index 0000000..b5d9b78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2001.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_2001.wavetable
new file mode 100644
index 0000000..d22e4ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2002.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_2002.wav
new file mode 100644
index 0000000..8678f16
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2002.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_2002.wavetable
new file mode 100644
index 0000000..d2f6cdb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2003.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_2003.wav
new file mode 100644
index 0000000..2a0985c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2003.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_2003.wavetable
new file mode 100644
index 0000000..2407e87
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2004.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_2004.wav
new file mode 100644
index 0000000..679f06d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2004.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_2004.wavetable
new file mode 100644
index 0000000..cc2ab76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2005.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_2005.wav
new file mode 100644
index 0000000..a5b04bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2005.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_2005.wavetable
new file mode 100644
index 0000000..b7cc8e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2006.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_2006.wav
new file mode 100644
index 0000000..a5d15fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2006.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_2006.wavetable
new file mode 100644
index 0000000..1f26b6d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2007.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_2007.wav
new file mode 100644
index 0000000..e213c52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2007.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_2007.wavetable
new file mode 100644
index 0000000..080cc74
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2008.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_2008.wav
new file mode 100644
index 0000000..759ce38
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2008.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_2008.wavetable
new file mode 100644
index 0000000..ed806eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2009.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_2009.wav
new file mode 100644
index 0000000..e101a3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2009.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_2009.wavetable
new file mode 100644
index 0000000..2598247
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2010.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_2010.wav
new file mode 100644
index 0000000..b176b55
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2010.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_2010.wavetable
new file mode 100644
index 0000000..fa296a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2011.wav b/etc/wavetables/AKWF/AKWF_0020/AKWF_2011.wav
new file mode 100644
index 0000000..9a54d9b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AKWF_2011.wavetable b/etc/wavetables/AKWF/AKWF_0020/AKWF_2011.wavetable
new file mode 100644
index 0000000..d42361f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_0020/AKWF_2011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_0020/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_0020/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_0020/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0001.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0001.wav
new file mode 100644
index 0000000..22f1ab0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0001.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0001.wavetable
new file mode 100644
index 0000000..f4f89b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0002.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0002.wav
new file mode 100644
index 0000000..8a2bfc5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0002.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0002.wavetable
new file mode 100644
index 0000000..d5c0726
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0003.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0003.wav
new file mode 100644
index 0000000..f927d10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0003.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0003.wavetable
new file mode 100644
index 0000000..282d35a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0004.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0004.wav
new file mode 100644
index 0000000..48e20e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0004.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0004.wavetable
new file mode 100644
index 0000000..470c5b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0005.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0005.wav
new file mode 100644
index 0000000..bf1f493
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0005.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0005.wavetable
new file mode 100644
index 0000000..3b716b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0006.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0006.wav
new file mode 100644
index 0000000..d2762ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0006.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0006.wavetable
new file mode 100644
index 0000000..335d8cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0007.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0007.wav
new file mode 100644
index 0000000..2f7f838
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0007.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0007.wavetable
new file mode 100644
index 0000000..ae0119a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0008.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0008.wav
new file mode 100644
index 0000000..e3c7db4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0008.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0008.wavetable
new file mode 100644
index 0000000..38744ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0009.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0009.wav
new file mode 100644
index 0000000..43edd66
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0009.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0009.wavetable
new file mode 100644
index 0000000..c4c591c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0010.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0010.wav
new file mode 100644
index 0000000..b2c4c8e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0010.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0010.wavetable
new file mode 100644
index 0000000..eca323b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0011.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0011.wav
new file mode 100644
index 0000000..c49a792
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0011.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0011.wavetable
new file mode 100644
index 0000000..a2610f8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0012.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0012.wav
new file mode 100644
index 0000000..1f641f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0012.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0012.wavetable
new file mode 100644
index 0000000..2abd5b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0013.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0013.wav
new file mode 100644
index 0000000..f2a8c9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0013.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0013.wavetable
new file mode 100644
index 0000000..b15452e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0014.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0014.wav
new file mode 100644
index 0000000..922d632
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0014.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0014.wavetable
new file mode 100644
index 0000000..163865b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0015.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0015.wav
new file mode 100644
index 0000000..b64cb43
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0015.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0015.wavetable
new file mode 100644
index 0000000..3b7d035
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0016.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0016.wav
new file mode 100644
index 0000000..cafafb1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0016.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0016.wavetable
new file mode 100644
index 0000000..508ff0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0017.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0017.wav
new file mode 100644
index 0000000..6536d43
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0017.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0017.wavetable
new file mode 100644
index 0000000..27917ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0018.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0018.wav
new file mode 100644
index 0000000..6ae54cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0018.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0018.wavetable
new file mode 100644
index 0000000..656796a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0019.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0019.wav
new file mode 100644
index 0000000..9bd9261
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0019.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0019.wavetable
new file mode 100644
index 0000000..c1fea72
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0020.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0020.wav
new file mode 100644
index 0000000..6a18360
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0020.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0020.wavetable
new file mode 100644
index 0000000..2e51277
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0021.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0021.wav
new file mode 100644
index 0000000..75f1b43
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0021.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0021.wavetable
new file mode 100644
index 0000000..2024b9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0022.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0022.wav
new file mode 100644
index 0000000..b7b978a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0022.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0022.wavetable
new file mode 100644
index 0000000..5c2ff12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0023.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0023.wav
new file mode 100644
index 0000000..87972a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0023.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0023.wavetable
new file mode 100644
index 0000000..c63bc88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0024.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0024.wav
new file mode 100644
index 0000000..867074e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0024.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0024.wavetable
new file mode 100644
index 0000000..4db6fe3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0025.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0025.wav
new file mode 100644
index 0000000..86107b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0025.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0025.wavetable
new file mode 100644
index 0000000..7f0d14d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0026.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0026.wav
new file mode 100644
index 0000000..fafaac8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0026.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0026.wavetable
new file mode 100644
index 0000000..b943823
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0027.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0027.wav
new file mode 100644
index 0000000..1862acd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0027.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0027.wavetable
new file mode 100644
index 0000000..2e65ddc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0028.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0028.wav
new file mode 100644
index 0000000..58c5006
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0028.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0028.wavetable
new file mode 100644
index 0000000..18a1add
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0029.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0029.wav
new file mode 100644
index 0000000..2da0a7c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0029.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0029.wavetable
new file mode 100644
index 0000000..360faa3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0030.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0030.wav
new file mode 100644
index 0000000..fd07bc9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0030.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0030.wavetable
new file mode 100644
index 0000000..8da1bcc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0031.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0031.wav
new file mode 100644
index 0000000..c06ad9c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0031.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0031.wavetable
new file mode 100644
index 0000000..342c00a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0032.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0032.wav
new file mode 100644
index 0000000..47bb896
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0032.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0032.wavetable
new file mode 100644
index 0000000..7a4d4e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0033.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0033.wav
new file mode 100644
index 0000000..8fa0e30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0033.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0033.wavetable
new file mode 100644
index 0000000..856d58c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0034.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0034.wav
new file mode 100644
index 0000000..f732ff6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0034.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0034.wavetable
new file mode 100644
index 0000000..b300f70
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0035.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0035.wav
new file mode 100644
index 0000000..8da83b7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0035.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0035.wavetable
new file mode 100644
index 0000000..a263365
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0036.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0036.wav
new file mode 100644
index 0000000..3c10d96
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0036.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0036.wavetable
new file mode 100644
index 0000000..e4c4dd4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0037.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0037.wav
new file mode 100644
index 0000000..8aee47c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0037.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0037.wavetable
new file mode 100644
index 0000000..a97d35b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0038.wav b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0038.wav
new file mode 100644
index 0000000..3c7bce9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0038.wavetable b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0038.wavetable
new file mode 100644
index 0000000..4c90fcb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_aguitar/AKWF_aguitar_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_aguitar/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_aguitar/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_aguitar/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0001.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0001.wav
new file mode 100644
index 0000000..0a26383
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0001.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0001.wavetable
new file mode 100644
index 0000000..f8910f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0002.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0002.wav
new file mode 100644
index 0000000..43975ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0002.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0002.wavetable
new file mode 100644
index 0000000..64f28df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0003.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0003.wav
new file mode 100644
index 0000000..8b7c277
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0003.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0003.wavetable
new file mode 100644
index 0000000..ff4b2bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0004.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0004.wav
new file mode 100644
index 0000000..dbb0dcf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0004.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0004.wavetable
new file mode 100644
index 0000000..6f65589
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0005.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0005.wav
new file mode 100644
index 0000000..7498b23
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0005.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0005.wavetable
new file mode 100644
index 0000000..731c664
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0006.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0006.wav
new file mode 100644
index 0000000..aada531
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0006.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0006.wavetable
new file mode 100644
index 0000000..0f26332
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0007.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0007.wav
new file mode 100644
index 0000000..5edc928
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0007.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0007.wavetable
new file mode 100644
index 0000000..36f6f3a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0008.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0008.wav
new file mode 100644
index 0000000..f04c94e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0008.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0008.wavetable
new file mode 100644
index 0000000..08b1775
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0009.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0009.wav
new file mode 100644
index 0000000..ca959f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0009.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0009.wavetable
new file mode 100644
index 0000000..03a123e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0010.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0010.wav
new file mode 100644
index 0000000..3f03f46
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0010.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0010.wavetable
new file mode 100644
index 0000000..d993429
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0011.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0011.wav
new file mode 100644
index 0000000..1274461
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0011.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0011.wavetable
new file mode 100644
index 0000000..3e6ce81
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0012.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0012.wav
new file mode 100644
index 0000000..b11f0ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0012.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0012.wavetable
new file mode 100644
index 0000000..876c82f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0013.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0013.wav
new file mode 100644
index 0000000..9da1021
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0013.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0013.wavetable
new file mode 100644
index 0000000..10efbe7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0014.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0014.wav
new file mode 100644
index 0000000..3f45f94
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0014.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0014.wavetable
new file mode 100644
index 0000000..1112721
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0015.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0015.wav
new file mode 100644
index 0000000..4f1fbed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0015.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0015.wavetable
new file mode 100644
index 0000000..3f075d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0016.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0016.wav
new file mode 100644
index 0000000..ba62268
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0016.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0016.wavetable
new file mode 100644
index 0000000..e2991b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0017.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0017.wav
new file mode 100644
index 0000000..f12d316
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0017.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0017.wavetable
new file mode 100644
index 0000000..70b46b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0018.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0018.wav
new file mode 100644
index 0000000..689f528
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0018.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0018.wavetable
new file mode 100644
index 0000000..381d07d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0019.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0019.wav
new file mode 100644
index 0000000..982f398
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0019.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0019.wavetable
new file mode 100644
index 0000000..0553094
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0020.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0020.wav
new file mode 100644
index 0000000..5b5df1d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0020.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0020.wavetable
new file mode 100644
index 0000000..2ac227b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0021.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0021.wav
new file mode 100644
index 0000000..f2e62c8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0021.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0021.wavetable
new file mode 100644
index 0000000..9e102ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0022.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0022.wav
new file mode 100644
index 0000000..276be95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0022.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0022.wavetable
new file mode 100644
index 0000000..39988c8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0023.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0023.wav
new file mode 100644
index 0000000..ebcc55a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0023.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0023.wavetable
new file mode 100644
index 0000000..1b65b1d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0024.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0024.wav
new file mode 100644
index 0000000..5c86497
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0024.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0024.wavetable
new file mode 100644
index 0000000..05b4080
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0025.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0025.wav
new file mode 100644
index 0000000..034a01b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0025.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0025.wavetable
new file mode 100644
index 0000000..cf13863
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0026.wav b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0026.wav
new file mode 100644
index 0000000..eb69e42
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0026.wavetable b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0026.wavetable
new file mode 100644
index 0000000..34638b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_altosax/AKWF_altosax_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_altosax/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_altosax/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_altosax/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0001.wav b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0001.wav
new file mode 100644
index 0000000..766e673
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0001.wavetable b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0001.wavetable
new file mode 100644
index 0000000..56b3f80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0002.wav b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0002.wav
new file mode 100644
index 0000000..1f149ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0002.wavetable b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0002.wavetable
new file mode 100644
index 0000000..9b72e33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0003.wav b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0003.wav
new file mode 100644
index 0000000..74553a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0003.wavetable b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0003.wavetable
new file mode 100644
index 0000000..f4d3008
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0004.wav b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0004.wav
new file mode 100644
index 0000000..65830a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0004.wavetable b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0004.wavetable
new file mode 100644
index 0000000..f9a76fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0005.wav b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0005.wav
new file mode 100644
index 0000000..6ea1d62
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0005.wavetable b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0005.wavetable
new file mode 100644
index 0000000..f2d3547
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0006.wav b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0006.wav
new file mode 100644
index 0000000..52c8f76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0006.wavetable b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0006.wavetable
new file mode 100644
index 0000000..591bf66
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0007.wav b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0007.wav
new file mode 100644
index 0000000..1476819
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0007.wavetable b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0007.wavetable
new file mode 100644
index 0000000..f0e6c57
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0008.wav b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0008.wav
new file mode 100644
index 0000000..6889e6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0008.wavetable b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0008.wavetable
new file mode 100644
index 0000000..b15ec98
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0009.wav b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0009.wav
new file mode 100644
index 0000000..d6c0f95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0009.wavetable b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0009.wavetable
new file mode 100644
index 0000000..d56373a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0010.wav b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0010.wav
new file mode 100644
index 0000000..6d9457f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0010.wavetable b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0010.wavetable
new file mode 100644
index 0000000..2db8d30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0011.wav b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0011.wav
new file mode 100644
index 0000000..225023e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0011.wavetable b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0011.wavetable
new file mode 100644
index 0000000..c6742a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0012.wav b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0012.wav
new file mode 100644
index 0000000..f3c0e99
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0012.wavetable b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0012.wavetable
new file mode 100644
index 0000000..6ae8487
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0013.wav b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0013.wav
new file mode 100644
index 0000000..3386fe3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0013.wavetable b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0013.wavetable
new file mode 100644
index 0000000..4fcf61a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0014.wav b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0014.wav
new file mode 100644
index 0000000..10e5a4b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0014.wavetable b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0014.wavetable
new file mode 100644
index 0000000..b815d54
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_birds/AKWF_birds_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_birds/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_birds/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_birds/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0001.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0001.wav
new file mode 100644
index 0000000..0c78c74
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0001.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0001.wavetable
new file mode 100644
index 0000000..fc71c64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0002.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0002.wav
new file mode 100644
index 0000000..24e4964
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0002.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0002.wavetable
new file mode 100644
index 0000000..9d4c6a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0003.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0003.wav
new file mode 100644
index 0000000..d4f000c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0003.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0003.wavetable
new file mode 100644
index 0000000..04f831a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0004.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0004.wav
new file mode 100644
index 0000000..f135be4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0004.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0004.wavetable
new file mode 100644
index 0000000..77c5732
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0005.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0005.wav
new file mode 100644
index 0000000..0072129
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0005.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0005.wavetable
new file mode 100644
index 0000000..0f13674
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0006.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0006.wav
new file mode 100644
index 0000000..9bf5ae4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0006.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0006.wavetable
new file mode 100644
index 0000000..3cea2b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0007.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0007.wav
new file mode 100644
index 0000000..1313ce4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0007.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0007.wavetable
new file mode 100644
index 0000000..00521d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0008.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0008.wav
new file mode 100644
index 0000000..bfe5cd6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0008.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0008.wavetable
new file mode 100644
index 0000000..6fa8b98
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0009.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0009.wav
new file mode 100644
index 0000000..92d6e5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0009.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0009.wavetable
new file mode 100644
index 0000000..398b27c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0010.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0010.wav
new file mode 100644
index 0000000..dd7e1b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0010.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0010.wavetable
new file mode 100644
index 0000000..21886e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0011.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0011.wav
new file mode 100644
index 0000000..e00fa50
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0011.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0011.wavetable
new file mode 100644
index 0000000..d75f42b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0012.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0012.wav
new file mode 100644
index 0000000..9259f9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0012.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0012.wavetable
new file mode 100644
index 0000000..6834602
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0013.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0013.wav
new file mode 100644
index 0000000..1f3149b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0013.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0013.wavetable
new file mode 100644
index 0000000..6a343e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0014.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0014.wav
new file mode 100644
index 0000000..2d9a1cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0014.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0014.wavetable
new file mode 100644
index 0000000..8ffbe42
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0015.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0015.wav
new file mode 100644
index 0000000..245f40a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0015.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0015.wavetable
new file mode 100644
index 0000000..19f310a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0016.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0016.wav
new file mode 100644
index 0000000..61e2b55
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0016.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0016.wavetable
new file mode 100644
index 0000000..9dcfb97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0017.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0017.wav
new file mode 100644
index 0000000..0469445
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0017.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0017.wavetable
new file mode 100644
index 0000000..5477dfc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0018.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0018.wav
new file mode 100644
index 0000000..e173faf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0018.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0018.wavetable
new file mode 100644
index 0000000..ecf61e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0019.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0019.wav
new file mode 100644
index 0000000..52e173f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0019.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0019.wavetable
new file mode 100644
index 0000000..9a43b2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0020.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0020.wav
new file mode 100644
index 0000000..5d540d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0020.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0020.wavetable
new file mode 100644
index 0000000..78e119a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0021.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0021.wav
new file mode 100644
index 0000000..afeef29
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0021.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0021.wavetable
new file mode 100644
index 0000000..b6ca6d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0022.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0022.wav
new file mode 100644
index 0000000..c8ebe09
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0022.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0022.wavetable
new file mode 100644
index 0000000..678cb11
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0023.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0023.wav
new file mode 100644
index 0000000..ea8bf2c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0023.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0023.wavetable
new file mode 100644
index 0000000..aa2164c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0024.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0024.wav
new file mode 100644
index 0000000..2a390b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0024.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0024.wavetable
new file mode 100644
index 0000000..d23ce9f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0025.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0025.wav
new file mode 100644
index 0000000..a608434
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0025.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0025.wavetable
new file mode 100644
index 0000000..9a4faf9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0026.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0026.wav
new file mode 100644
index 0000000..cb57654
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0026.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0026.wavetable
new file mode 100644
index 0000000..a60a642
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0027.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0027.wav
new file mode 100644
index 0000000..b0f6356
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0027.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0027.wavetable
new file mode 100644
index 0000000..a26c7ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0028.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0028.wav
new file mode 100644
index 0000000..ea013f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0028.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0028.wavetable
new file mode 100644
index 0000000..a42bc07
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0029.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0029.wav
new file mode 100644
index 0000000..80ee839
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0029.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0029.wavetable
new file mode 100644
index 0000000..b853498
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0030.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0030.wav
new file mode 100644
index 0000000..d50d56e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0030.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0030.wavetable
new file mode 100644
index 0000000..366a2eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0031.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0031.wav
new file mode 100644
index 0000000..0b0520c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0031.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0031.wavetable
new file mode 100644
index 0000000..7fab70b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0032.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0032.wav
new file mode 100644
index 0000000..793eb2d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0032.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0032.wavetable
new file mode 100644
index 0000000..f0faa28
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0033.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0033.wav
new file mode 100644
index 0000000..a1c8e74
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0033.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0033.wavetable
new file mode 100644
index 0000000..e6e8c6a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0034.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0034.wav
new file mode 100644
index 0000000..627d6ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0034.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0034.wavetable
new file mode 100644
index 0000000..5130002
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0035.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0035.wav
new file mode 100644
index 0000000..e3cb043
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0035.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0035.wavetable
new file mode 100644
index 0000000..5333939
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0036.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0036.wav
new file mode 100644
index 0000000..b839a3e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0036.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0036.wavetable
new file mode 100644
index 0000000..7f61205
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0037.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0037.wav
new file mode 100644
index 0000000..57c0465
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0037.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0037.wavetable
new file mode 100644
index 0000000..fc4cd4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0038.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0038.wav
new file mode 100644
index 0000000..c09d097
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0038.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0038.wavetable
new file mode 100644
index 0000000..18856ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0039.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0039.wav
new file mode 100644
index 0000000..f645b4e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0039.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0039.wavetable
new file mode 100644
index 0000000..f485ed5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0040.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0040.wav
new file mode 100644
index 0000000..0613ab6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0040.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0040.wavetable
new file mode 100644
index 0000000..2156782
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_bitreduced_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw2bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw2bit.wav
new file mode 100644
index 0000000..1095831
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw2bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw2bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw2bit.wavetable
new file mode 100644
index 0000000..dc315da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw2bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw3bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw3bit.wav
new file mode 100644
index 0000000..ad7b113
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw3bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw3bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw3bit.wavetable
new file mode 100644
index 0000000..34d38a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw3bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw4bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw4bit.wav
new file mode 100644
index 0000000..2c4dc70
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw4bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw4bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw4bit.wavetable
new file mode 100644
index 0000000..50ad6dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw4bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw5bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw5bit.wav
new file mode 100644
index 0000000..45a7790
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw5bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw5bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw5bit.wavetable
new file mode 100644
index 0000000..6328852
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw5bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw6bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw6bit.wav
new file mode 100644
index 0000000..1cbe465
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw6bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw6bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw6bit.wavetable
new file mode 100644
index 0000000..a27cd18
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw6bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw7bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw7bit.wav
new file mode 100644
index 0000000..0a4abcc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw7bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw7bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw7bit.wavetable
new file mode 100644
index 0000000..fe4dde7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw7bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw8bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw8bit.wav
new file mode 100644
index 0000000..5e512a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw8bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw8bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw8bit.wavetable
new file mode 100644
index 0000000..62838f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_saw8bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin2bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin2bit.wav
new file mode 100644
index 0000000..ca59d4b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin2bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin2bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin2bit.wavetable
new file mode 100644
index 0000000..4d4acab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin2bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin3bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin3bit.wav
new file mode 100644
index 0000000..6327240
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin3bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin3bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin3bit.wavetable
new file mode 100644
index 0000000..167ad3f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin3bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin4bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin4bit.wav
new file mode 100644
index 0000000..0a71c81
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin4bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin4bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin4bit.wavetable
new file mode 100644
index 0000000..d0a2c35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin4bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin5bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin5bit.wav
new file mode 100644
index 0000000..8ab5fa5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin5bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin5bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin5bit.wavetable
new file mode 100644
index 0000000..8b883e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin5bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin6bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin6bit.wav
new file mode 100644
index 0000000..d77cf41
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin6bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin6bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin6bit.wavetable
new file mode 100644
index 0000000..6dcfa4b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin6bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin7bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin7bit.wav
new file mode 100644
index 0000000..00cb16a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin7bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin7bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin7bit.wavetable
new file mode 100644
index 0000000..7ae956b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin7bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin8bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin8bit.wav
new file mode 100644
index 0000000..a94a636
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin8bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin8bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin8bit.wavetable
new file mode 100644
index 0000000..ade30c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_sin8bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ2bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ2bit.wav
new file mode 100644
index 0000000..d5e716a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ2bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ2bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ2bit.wavetable
new file mode 100644
index 0000000..ebe0309
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ2bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ3bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ3bit.wav
new file mode 100644
index 0000000..3c06e31
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ3bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ3bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ3bit.wavetable
new file mode 100644
index 0000000..582f246
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ3bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ4bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ4bit.wav
new file mode 100644
index 0000000..cb6f608
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ4bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ4bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ4bit.wavetable
new file mode 100644
index 0000000..9adfced
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ4bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ5bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ5bit.wav
new file mode 100644
index 0000000..5de1720
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ5bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ5bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ5bit.wavetable
new file mode 100644
index 0000000..4b413ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ5bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ6bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ6bit.wav
new file mode 100644
index 0000000..17563c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ6bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ6bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ6bit.wavetable
new file mode 100644
index 0000000..7ae9498
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ6bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ7bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ7bit.wav
new file mode 100644
index 0000000..77a0f2a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ7bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ7bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ7bit.wavetable
new file mode 100644
index 0000000..694c82c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ7bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ8bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ8bit.wav
new file mode 100644
index 0000000..f2fc54b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ8bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ8bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ8bit.wavetable
new file mode 100644
index 0000000..886bb7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_squ8bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri2bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri2bit.wav
new file mode 100644
index 0000000..7a1fbdb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri2bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri2bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri2bit.wavetable
new file mode 100644
index 0000000..b1e0d37
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri2bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri3bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri3bit.wav
new file mode 100644
index 0000000..4abd876
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri3bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri3bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri3bit.wavetable
new file mode 100644
index 0000000..24b4ef7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri3bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri4bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri4bit.wav
new file mode 100644
index 0000000..5ef72a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri4bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri4bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri4bit.wavetable
new file mode 100644
index 0000000..33735fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri4bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri5bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri5bit.wav
new file mode 100644
index 0000000..40c62d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri5bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri5bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri5bit.wavetable
new file mode 100644
index 0000000..e54fa63
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri5bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri6bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri6bit.wav
new file mode 100644
index 0000000..13c038a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri6bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri6bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri6bit.wavetable
new file mode 100644
index 0000000..ed792e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri6bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri7bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri7bit.wav
new file mode 100644
index 0000000..f257ca0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri7bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri7bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri7bit.wavetable
new file mode 100644
index 0000000..9e74629
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri7bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri8bit.wav b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri8bit.wav
new file mode 100644
index 0000000..b60f988
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri8bit.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri8bit.wavetable b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri8bit.wavetable
new file mode 100644
index 0000000..d150775
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bitreduced/AKWF_tri8bit.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bitreduced/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_bitreduced/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_bitreduced/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0001.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0001.wav
new file mode 100644
index 0000000..f78cad9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0001.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0001.wavetable
new file mode 100644
index 0000000..6e80d86
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0002.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0002.wav
new file mode 100644
index 0000000..60ae9c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0002.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0002.wavetable
new file mode 100644
index 0000000..de36d3d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0003.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0003.wav
new file mode 100644
index 0000000..7c948af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0003.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0003.wavetable
new file mode 100644
index 0000000..5b64dd7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0004.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0004.wav
new file mode 100644
index 0000000..152383b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0004.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0004.wavetable
new file mode 100644
index 0000000..c7a7ecb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0005.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0005.wav
new file mode 100644
index 0000000..fae1b7e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0005.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0005.wavetable
new file mode 100644
index 0000000..d0648ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0006.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0006.wav
new file mode 100644
index 0000000..964c7db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0006.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0006.wavetable
new file mode 100644
index 0000000..4a21dec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0007.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0007.wav
new file mode 100644
index 0000000..e5bfefd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0007.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0007.wavetable
new file mode 100644
index 0000000..3c2c5ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0008.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0008.wav
new file mode 100644
index 0000000..851cb49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0008.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0008.wavetable
new file mode 100644
index 0000000..854f255
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0009.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0009.wav
new file mode 100644
index 0000000..158b944
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0009.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0009.wavetable
new file mode 100644
index 0000000..3eeb3fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0011.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0011.wav
new file mode 100644
index 0000000..9ad525c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0011.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0011.wavetable
new file mode 100644
index 0000000..e9bc66c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0012.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0012.wav
new file mode 100644
index 0000000..68e9fde
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0012.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0012.wavetable
new file mode 100644
index 0000000..3665317
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0013.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0013.wav
new file mode 100644
index 0000000..910ecf2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0013.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0013.wavetable
new file mode 100644
index 0000000..59f9e2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0014.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0014.wav
new file mode 100644
index 0000000..4181f27
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0014.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0014.wavetable
new file mode 100644
index 0000000..6ab267b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0015.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0015.wav
new file mode 100644
index 0000000..f4e2a2c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0015.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0015.wavetable
new file mode 100644
index 0000000..92d7a02
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0016.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0016.wav
new file mode 100644
index 0000000..4d76817
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0016.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0016.wavetable
new file mode 100644
index 0000000..862b1d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0017.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0017.wav
new file mode 100644
index 0000000..3196669
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0017.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0017.wavetable
new file mode 100644
index 0000000..c5e4592
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0018.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0018.wav
new file mode 100644
index 0000000..502eee5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0018.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0018.wavetable
new file mode 100644
index 0000000..9770975
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0019.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0019.wav
new file mode 100644
index 0000000..926bc95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0019.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0019.wavetable
new file mode 100644
index 0000000..cf9cfdb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0021.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0021.wav
new file mode 100644
index 0000000..f76f46f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0021.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0021.wavetable
new file mode 100644
index 0000000..ee1c4f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0022.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0022.wav
new file mode 100644
index 0000000..8d1d7b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0022.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0022.wavetable
new file mode 100644
index 0000000..cad24b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0024.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0024.wav
new file mode 100644
index 0000000..4217a0b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0024.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0024.wavetable
new file mode 100644
index 0000000..be98783
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0025.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0025.wav
new file mode 100644
index 0000000..54c195e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0025.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0025.wavetable
new file mode 100644
index 0000000..7863875
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0026.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0026.wav
new file mode 100644
index 0000000..a5f1d5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0026.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0026.wavetable
new file mode 100644
index 0000000..943ea0a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0028.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0028.wav
new file mode 100644
index 0000000..51d95ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0028.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0028.wavetable
new file mode 100644
index 0000000..40ba4a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0029.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0029.wav
new file mode 100644
index 0000000..c65ae6a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0029.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0029.wavetable
new file mode 100644
index 0000000..637e971
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0030.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0030.wav
new file mode 100644
index 0000000..3c207c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0030.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0030.wavetable
new file mode 100644
index 0000000..78e7329
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0031.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0031.wav
new file mode 100644
index 0000000..d874d36
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0031.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0031.wavetable
new file mode 100644
index 0000000..66362bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0032.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0032.wav
new file mode 100644
index 0000000..589567e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0032.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0032.wavetable
new file mode 100644
index 0000000..e1b6c68
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0033.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0033.wav
new file mode 100644
index 0000000..2a3f3a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0033.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0033.wavetable
new file mode 100644
index 0000000..ca855b3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0035.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0035.wav
new file mode 100644
index 0000000..d320415
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0035.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0035.wavetable
new file mode 100644
index 0000000..46d53ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0036.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0036.wav
new file mode 100644
index 0000000..74c8fd8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0036.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0036.wavetable
new file mode 100644
index 0000000..e7bdd74
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0037.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0037.wav
new file mode 100644
index 0000000..5d3aba0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0037.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0037.wavetable
new file mode 100644
index 0000000..4dab9bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0038.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0038.wav
new file mode 100644
index 0000000..d8ce197
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0038.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0038.wavetable
new file mode 100644
index 0000000..aabc17f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0039.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0039.wav
new file mode 100644
index 0000000..59a8db0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0039.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0039.wavetable
new file mode 100644
index 0000000..7d60e5e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0041.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0041.wav
new file mode 100644
index 0000000..1213e0e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0041.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0041.wavetable
new file mode 100644
index 0000000..f1cec07
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0042.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0042.wav
new file mode 100644
index 0000000..75e69ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0042.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0042.wavetable
new file mode 100644
index 0000000..2d7561b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0044.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0044.wav
new file mode 100644
index 0000000..68e37b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0044.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0044.wavetable
new file mode 100644
index 0000000..487b8ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0045.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0045.wav
new file mode 100644
index 0000000..6693553
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0045.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0045.wavetable
new file mode 100644
index 0000000..f64cda8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0046.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0046.wav
new file mode 100644
index 0000000..d1fb884
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0046.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0046.wavetable
new file mode 100644
index 0000000..997fb22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0047.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0047.wav
new file mode 100644
index 0000000..1ea18c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0047.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0047.wavetable
new file mode 100644
index 0000000..61f40b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0048.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0048.wav
new file mode 100644
index 0000000..c54db2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0048.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0048.wavetable
new file mode 100644
index 0000000..aca445b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0049.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0049.wav
new file mode 100644
index 0000000..806389c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0049.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0049.wavetable
new file mode 100644
index 0000000..5f24b33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0050.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0050.wav
new file mode 100644
index 0000000..0d0ee3d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0050.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0050.wavetable
new file mode 100644
index 0000000..a0a1f0c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0051.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0051.wav
new file mode 100644
index 0000000..191fc0f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0051.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0051.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0051.wavetable
new file mode 100644
index 0000000..6d8ad9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0051.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0052.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0052.wav
new file mode 100644
index 0000000..612dd4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0052.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0052.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0052.wavetable
new file mode 100644
index 0000000..3880c41
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0052.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0053.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0053.wav
new file mode 100644
index 0000000..05513b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0053.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0053.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0053.wavetable
new file mode 100644
index 0000000..c0e1088
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0053.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0054.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0054.wav
new file mode 100644
index 0000000..0c33089
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0054.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0054.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0054.wavetable
new file mode 100644
index 0000000..56df64d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0054.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0055.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0055.wav
new file mode 100644
index 0000000..765fd29
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0055.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0055.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0055.wavetable
new file mode 100644
index 0000000..c80aefc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0055.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0056.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0056.wav
new file mode 100644
index 0000000..31ea121
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0056.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0056.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0056.wavetable
new file mode 100644
index 0000000..92a7b33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0056.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0057.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0057.wav
new file mode 100644
index 0000000..2deab91
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0057.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0057.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0057.wavetable
new file mode 100644
index 0000000..0f24b10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0057.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0058.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0058.wav
new file mode 100644
index 0000000..c2f48da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0058.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0058.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0058.wavetable
new file mode 100644
index 0000000..abb8294
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0058.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0059.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0059.wav
new file mode 100644
index 0000000..e41bd7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0059.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0059.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0059.wavetable
new file mode 100644
index 0000000..7d24e35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0059.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0060.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0060.wav
new file mode 100644
index 0000000..b8ccf58
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0060.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0060.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0060.wavetable
new file mode 100644
index 0000000..94b9135
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0060.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0061.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0061.wav
new file mode 100644
index 0000000..30ba7db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0061.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0061.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0061.wavetable
new file mode 100644
index 0000000..dc3b178
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0061.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0062.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0062.wav
new file mode 100644
index 0000000..5fceab7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0062.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0062.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0062.wavetable
new file mode 100644
index 0000000..a3dd1c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0062.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0063.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0063.wav
new file mode 100644
index 0000000..57c7537
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0063.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0063.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0063.wavetable
new file mode 100644
index 0000000..23f8543
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0063.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0064.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0064.wav
new file mode 100644
index 0000000..3ec3b36
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0064.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0064.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0064.wavetable
new file mode 100644
index 0000000..c04d244
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0064.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0065.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0065.wav
new file mode 100644
index 0000000..92ad6ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0065.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0065.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0065.wavetable
new file mode 100644
index 0000000..c64d555
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0065.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0066.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0066.wav
new file mode 100644
index 0000000..7eb315d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0066.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0066.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0066.wavetable
new file mode 100644
index 0000000..f73cf81
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0066.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0067.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0067.wav
new file mode 100644
index 0000000..ef9042e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0067.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0067.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0067.wavetable
new file mode 100644
index 0000000..a1dde92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0067.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0068.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0068.wav
new file mode 100644
index 0000000..8d7a20c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0068.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0068.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0068.wavetable
new file mode 100644
index 0000000..f0a54a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0068.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0069.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0069.wav
new file mode 100644
index 0000000..e0c8dae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0069.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0069.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0069.wavetable
new file mode 100644
index 0000000..b5f75c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0069.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0070.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0070.wav
new file mode 100644
index 0000000..7c5fe6d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0070.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0070.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0070.wavetable
new file mode 100644
index 0000000..17c2f2c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0070.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0071.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0071.wav
new file mode 100644
index 0000000..264f265
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0071.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0071.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0071.wavetable
new file mode 100644
index 0000000..3310d27
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0071.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0072.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0072.wav
new file mode 100644
index 0000000..5bfb023
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0072.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0072.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0072.wavetable
new file mode 100644
index 0000000..133ec7c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0072.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0073.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0073.wav
new file mode 100644
index 0000000..5b10819
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0073.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0073.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0073.wavetable
new file mode 100644
index 0000000..0c9f8ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0073.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0074.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0074.wav
new file mode 100644
index 0000000..46622c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0074.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0074.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0074.wavetable
new file mode 100644
index 0000000..b364aa8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0074.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0075.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0075.wav
new file mode 100644
index 0000000..f34add8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0075.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0075.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0075.wavetable
new file mode 100644
index 0000000..9729104
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0075.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0076.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0076.wav
new file mode 100644
index 0000000..1a027f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0076.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0076.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0076.wavetable
new file mode 100644
index 0000000..38650db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0076.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0077.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0077.wav
new file mode 100644
index 0000000..4b8aebe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0077.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0077.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0077.wavetable
new file mode 100644
index 0000000..459de91
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0077.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0078.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0078.wav
new file mode 100644
index 0000000..89bdaaf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0078.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0078.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0078.wavetable
new file mode 100644
index 0000000..8617d5f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0078.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0079.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0079.wav
new file mode 100644
index 0000000..a46e1d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0079.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0079.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0079.wavetable
new file mode 100644
index 0000000..e5be662
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0079.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0080.wav b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0080.wav
new file mode 100644
index 0000000..508fdba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0080.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0080.wavetable b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0080.wavetable
new file mode 100644
index 0000000..6e9836b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_blended/AKWF_blended_0080.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_blended/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_bw_blended/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_bw_blended/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_saw.wav b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_saw.wav
new file mode 100644
index 0000000..f2bd5ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_saw.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_saw.wavetable b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_saw.wavetable
new file mode 100644
index 0000000..d183f57
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_saw.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_sin.wav b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_sin.wav
new file mode 100644
index 0000000..9c16198
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_sin.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_sin.wavetable b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_sin.wavetable
new file mode 100644
index 0000000..c0f4c6e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_sin.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_squ.wav b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_squ.wav
new file mode 100644
index 0000000..8e87eb5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_squ.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_squ.wavetable b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_squ.wavetable
new file mode 100644
index 0000000..f0956f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_squ.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_tri.wav b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_tri.wav
new file mode 100644
index 0000000..9e31f21
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_tri.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_tri.wavetable b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_tri.wavetable
new file mode 100644
index 0000000..cc42c1f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AKWF_tri.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_bw_perfectwaves/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0001.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0001.wav
new file mode 100644
index 0000000..37b7342
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0001.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0001.wavetable
new file mode 100644
index 0000000..572c200
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0002.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0002.wav
new file mode 100644
index 0000000..e4bec51
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0002.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0002.wavetable
new file mode 100644
index 0000000..c8d1e5d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0003.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0003.wav
new file mode 100644
index 0000000..ee56668
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0003.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0003.wavetable
new file mode 100644
index 0000000..abf6c2f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0004.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0004.wav
new file mode 100644
index 0000000..987b028
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0004.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0004.wavetable
new file mode 100644
index 0000000..c9fa36c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0005.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0005.wav
new file mode 100644
index 0000000..83a5e66
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0005.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0005.wavetable
new file mode 100644
index 0000000..4098568
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0006.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0006.wav
new file mode 100644
index 0000000..2592c1e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0006.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0006.wavetable
new file mode 100644
index 0000000..c0efa83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0007.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0007.wav
new file mode 100644
index 0000000..9013908
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0007.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0007.wavetable
new file mode 100644
index 0000000..4c09eeb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0008.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0008.wav
new file mode 100644
index 0000000..7c36efd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0008.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0008.wavetable
new file mode 100644
index 0000000..a127897
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0009.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0009.wav
new file mode 100644
index 0000000..89c63f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0009.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0009.wavetable
new file mode 100644
index 0000000..2444db9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0010.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0010.wav
new file mode 100644
index 0000000..a8b1347
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0010.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0010.wavetable
new file mode 100644
index 0000000..48be8ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0011.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0011.wav
new file mode 100644
index 0000000..75da17c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0011.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0011.wavetable
new file mode 100644
index 0000000..b9017d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0012.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0012.wav
new file mode 100644
index 0000000..c3142bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0012.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0012.wavetable
new file mode 100644
index 0000000..0a7687d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0013.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0013.wav
new file mode 100644
index 0000000..ae8dba1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0013.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0013.wavetable
new file mode 100644
index 0000000..161dc52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0014.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0014.wav
new file mode 100644
index 0000000..fc6067e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0014.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0014.wavetable
new file mode 100644
index 0000000..c3a6afe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0015.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0015.wav
new file mode 100644
index 0000000..1506abc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0015.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0015.wavetable
new file mode 100644
index 0000000..677136e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0016.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0016.wav
new file mode 100644
index 0000000..a9dda00
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0016.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0016.wavetable
new file mode 100644
index 0000000..a388677
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0017.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0017.wav
new file mode 100644
index 0000000..1cbe992
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0017.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0017.wavetable
new file mode 100644
index 0000000..961bedd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0018.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0018.wav
new file mode 100644
index 0000000..838dd5c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0018.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0018.wavetable
new file mode 100644
index 0000000..dccdfd9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0019.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0019.wav
new file mode 100644
index 0000000..04433ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0019.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0019.wavetable
new file mode 100644
index 0000000..918caf8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0020.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0020.wav
new file mode 100644
index 0000000..82fa5b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0020.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0020.wavetable
new file mode 100644
index 0000000..9069eef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0021.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0021.wav
new file mode 100644
index 0000000..70ace69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0021.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0021.wavetable
new file mode 100644
index 0000000..d94360f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0022.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0022.wav
new file mode 100644
index 0000000..88fc561
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0022.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0022.wavetable
new file mode 100644
index 0000000..00eca0a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0023.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0023.wav
new file mode 100644
index 0000000..2d26db0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0023.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0023.wavetable
new file mode 100644
index 0000000..3342d36
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0024.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0024.wav
new file mode 100644
index 0000000..eecf89d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0024.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0024.wavetable
new file mode 100644
index 0000000..268bc69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0025.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0025.wav
new file mode 100644
index 0000000..9c6c940
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0025.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0025.wavetable
new file mode 100644
index 0000000..aa11169
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0026.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0026.wav
new file mode 100644
index 0000000..866a674
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0026.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0026.wavetable
new file mode 100644
index 0000000..3b938f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0027.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0027.wav
new file mode 100644
index 0000000..58b922b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0027.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0027.wavetable
new file mode 100644
index 0000000..691c2f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0028.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0028.wav
new file mode 100644
index 0000000..c14494e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0028.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0028.wavetable
new file mode 100644
index 0000000..f2cf8f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0029.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0029.wav
new file mode 100644
index 0000000..1fe4170
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0029.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0029.wavetable
new file mode 100644
index 0000000..39bae12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0030.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0030.wav
new file mode 100644
index 0000000..607356d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0030.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0030.wavetable
new file mode 100644
index 0000000..b656e02
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0031.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0031.wav
new file mode 100644
index 0000000..ba15baf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0031.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0031.wavetable
new file mode 100644
index 0000000..9afe118
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0032.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0032.wav
new file mode 100644
index 0000000..7479b6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0032.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0032.wavetable
new file mode 100644
index 0000000..a4dfc8f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0033.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0033.wav
new file mode 100644
index 0000000..ed92c39
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0033.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0033.wavetable
new file mode 100644
index 0000000..e0ad730
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0034.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0034.wav
new file mode 100644
index 0000000..dcb9754
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0034.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0034.wavetable
new file mode 100644
index 0000000..ab7fa83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0035.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0035.wav
new file mode 100644
index 0000000..727f4ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0035.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0035.wavetable
new file mode 100644
index 0000000..efc4bc8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0036.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0036.wav
new file mode 100644
index 0000000..5750f10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0036.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0036.wavetable
new file mode 100644
index 0000000..c339e05
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0037.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0037.wav
new file mode 100644
index 0000000..134d72f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0037.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0037.wavetable
new file mode 100644
index 0000000..2a0d0d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0038.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0038.wav
new file mode 100644
index 0000000..ccd3b64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0038.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0038.wavetable
new file mode 100644
index 0000000..583e62f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0039.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0039.wav
new file mode 100644
index 0000000..9b1bdc4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0039.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0039.wavetable
new file mode 100644
index 0000000..b8aaa09
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0040.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0040.wav
new file mode 100644
index 0000000..9e7d835
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0040.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0040.wavetable
new file mode 100644
index 0000000..57acce3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0041.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0041.wav
new file mode 100644
index 0000000..c859429
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0041.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0041.wavetable
new file mode 100644
index 0000000..e5e8c02
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0042.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0042.wav
new file mode 100644
index 0000000..04e6da7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0042.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0042.wavetable
new file mode 100644
index 0000000..08a9918
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0043.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0043.wav
new file mode 100644
index 0000000..79ef423
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0043.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0043.wavetable
new file mode 100644
index 0000000..72a5972
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0044.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0044.wav
new file mode 100644
index 0000000..9db8e1e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0044.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0044.wavetable
new file mode 100644
index 0000000..ea10fc6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0045.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0045.wav
new file mode 100644
index 0000000..2b281a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0045.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0045.wavetable
new file mode 100644
index 0000000..64b7460
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0046.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0046.wav
new file mode 100644
index 0000000..1e69859
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0046.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0046.wavetable
new file mode 100644
index 0000000..56f003f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0047.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0047.wav
new file mode 100644
index 0000000..ef89335
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0047.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0047.wavetable
new file mode 100644
index 0000000..7120629
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0048.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0048.wav
new file mode 100644
index 0000000..c2aa3bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0048.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0048.wavetable
new file mode 100644
index 0000000..3c8ddf7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0049.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0049.wav
new file mode 100644
index 0000000..53e2ae5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0049.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0049.wavetable
new file mode 100644
index 0000000..384bb78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0050.wav b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0050.wav
new file mode 100644
index 0000000..425aad9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0050.wavetable b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0050.wavetable
new file mode 100644
index 0000000..58982bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_saw/AKWF_saw_0050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_saw/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_bw_saw/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_bw_saw/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0001.wav b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0001.wav
new file mode 100644
index 0000000..dfef757
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0001.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0001.wavetable
new file mode 100644
index 0000000..2760c6a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0002.wav b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0002.wav
new file mode 100644
index 0000000..a102200
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0002.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0002.wavetable
new file mode 100644
index 0000000..1595621
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0003.wav b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0003.wav
new file mode 100644
index 0000000..25e0cb2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0003.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0003.wavetable
new file mode 100644
index 0000000..d5db619
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0004.wav b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0004.wav
new file mode 100644
index 0000000..590701e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0004.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0004.wavetable
new file mode 100644
index 0000000..55c7b57
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0005.wav b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0005.wav
new file mode 100644
index 0000000..67c1663
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0005.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0005.wavetable
new file mode 100644
index 0000000..7e577f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0006.wav b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0006.wav
new file mode 100644
index 0000000..d2624f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0006.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0006.wavetable
new file mode 100644
index 0000000..c707df9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0007.wav b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0007.wav
new file mode 100644
index 0000000..68cbef0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0007.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0007.wavetable
new file mode 100644
index 0000000..64869ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0008.wav b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0008.wav
new file mode 100644
index 0000000..c683687
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0008.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0008.wavetable
new file mode 100644
index 0000000..a884db6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0009.wav b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0009.wav
new file mode 100644
index 0000000..42b1f8b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0009.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0009.wavetable
new file mode 100644
index 0000000..09e40fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0010.wav b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0010.wav
new file mode 100644
index 0000000..3eed338
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0010.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0010.wavetable
new file mode 100644
index 0000000..84f9867
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawbright/AKWF_bsaw_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawbright/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_bw_sawbright/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_bw_sawbright/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0001.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0001.wav
new file mode 100644
index 0000000..292af0b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0001.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0001.wavetable
new file mode 100644
index 0000000..ccde85f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0002.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0002.wav
new file mode 100644
index 0000000..4d897d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0002.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0002.wavetable
new file mode 100644
index 0000000..7cbc830
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0003.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0003.wav
new file mode 100644
index 0000000..c216bc0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0003.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0003.wavetable
new file mode 100644
index 0000000..ac496ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0004.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0004.wav
new file mode 100644
index 0000000..dc8ec94
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0004.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0004.wavetable
new file mode 100644
index 0000000..2ae5724
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0005.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0005.wav
new file mode 100644
index 0000000..a51e66d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0005.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0005.wavetable
new file mode 100644
index 0000000..04ebdb9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0006.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0006.wav
new file mode 100644
index 0000000..ec48986
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0006.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0006.wavetable
new file mode 100644
index 0000000..6f13f63
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0007.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0007.wav
new file mode 100644
index 0000000..ecf72db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0007.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0007.wavetable
new file mode 100644
index 0000000..a1a0123
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0008.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0008.wav
new file mode 100644
index 0000000..2d5d7cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0008.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0008.wavetable
new file mode 100644
index 0000000..a58690c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0009.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0009.wav
new file mode 100644
index 0000000..c30bb43
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0009.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0009.wavetable
new file mode 100644
index 0000000..588bce0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0010.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0010.wav
new file mode 100644
index 0000000..6386aac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0010.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0010.wavetable
new file mode 100644
index 0000000..9c8d16c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0011.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0011.wav
new file mode 100644
index 0000000..e59cf1f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0011.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0011.wavetable
new file mode 100644
index 0000000..a1f77ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0012.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0012.wav
new file mode 100644
index 0000000..d8bdcfd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0012.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0012.wavetable
new file mode 100644
index 0000000..8a4b056
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0013.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0013.wav
new file mode 100644
index 0000000..7952f09
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0013.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0013.wavetable
new file mode 100644
index 0000000..9505c11
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0014.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0014.wav
new file mode 100644
index 0000000..05e5b1f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0014.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0014.wavetable
new file mode 100644
index 0000000..7171adc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0015.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0015.wav
new file mode 100644
index 0000000..fd158f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0015.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0015.wavetable
new file mode 100644
index 0000000..8e907ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0016.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0016.wav
new file mode 100644
index 0000000..ec5d64d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0016.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0016.wavetable
new file mode 100644
index 0000000..ffc2f71
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0017.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0017.wav
new file mode 100644
index 0000000..69bb92e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0017.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0017.wavetable
new file mode 100644
index 0000000..b7b5b85
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0018.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0018.wav
new file mode 100644
index 0000000..b16517a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0018.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0018.wavetable
new file mode 100644
index 0000000..4128cec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0019.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0019.wav
new file mode 100644
index 0000000..c3fdf9f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0019.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0019.wavetable
new file mode 100644
index 0000000..80580ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0020.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0020.wav
new file mode 100644
index 0000000..d12b8b3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0020.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0020.wavetable
new file mode 100644
index 0000000..5a0f750
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0021.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0021.wav
new file mode 100644
index 0000000..509a8d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0021.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0021.wavetable
new file mode 100644
index 0000000..9839db6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0022.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0022.wav
new file mode 100644
index 0000000..8185c09
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0022.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0022.wavetable
new file mode 100644
index 0000000..d6ed090
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0023.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0023.wav
new file mode 100644
index 0000000..d20c285
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0023.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0023.wavetable
new file mode 100644
index 0000000..4050c9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0024.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0024.wav
new file mode 100644
index 0000000..564d3b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0024.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0024.wavetable
new file mode 100644
index 0000000..c134c95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0025.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0025.wav
new file mode 100644
index 0000000..09f4b64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0025.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0025.wavetable
new file mode 100644
index 0000000..6d113e2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0026.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0026.wav
new file mode 100644
index 0000000..bdd1569
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0026.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0026.wavetable
new file mode 100644
index 0000000..327432d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0027.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0027.wav
new file mode 100644
index 0000000..e2b9b1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0027.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0027.wavetable
new file mode 100644
index 0000000..7c038e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0028.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0028.wav
new file mode 100644
index 0000000..3c4d2f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0028.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0028.wavetable
new file mode 100644
index 0000000..45789f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0029.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0029.wav
new file mode 100644
index 0000000..8274986
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0029.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0029.wavetable
new file mode 100644
index 0000000..dc1fdee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0030.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0030.wav
new file mode 100644
index 0000000..e98e678
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0030.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0030.wavetable
new file mode 100644
index 0000000..6492f0e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0031.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0031.wav
new file mode 100644
index 0000000..21eafd9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0031.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0031.wavetable
new file mode 100644
index 0000000..f0cb0f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0032.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0032.wav
new file mode 100644
index 0000000..d1a763b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0032.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0032.wavetable
new file mode 100644
index 0000000..3931ad1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0033.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0033.wav
new file mode 100644
index 0000000..1bfc2e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0033.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0033.wavetable
new file mode 100644
index 0000000..e973a9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0034.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0034.wav
new file mode 100644
index 0000000..df955c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0034.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0034.wavetable
new file mode 100644
index 0000000..0cb251d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0035.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0035.wav
new file mode 100644
index 0000000..3cd9679
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0035.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0035.wavetable
new file mode 100644
index 0000000..e6f505c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0036.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0036.wav
new file mode 100644
index 0000000..de8e941
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0036.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0036.wavetable
new file mode 100644
index 0000000..0e0558e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0037.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0037.wav
new file mode 100644
index 0000000..c8471f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0037.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0037.wavetable
new file mode 100644
index 0000000..5fe6e14
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0038.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0038.wav
new file mode 100644
index 0000000..c11939b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0038.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0038.wavetable
new file mode 100644
index 0000000..b094336
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0039.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0039.wav
new file mode 100644
index 0000000..d7e8d62
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0039.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0039.wavetable
new file mode 100644
index 0000000..3ccf170
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0040.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0040.wav
new file mode 100644
index 0000000..923d64a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0040.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0040.wavetable
new file mode 100644
index 0000000..45bd7f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0041.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0041.wav
new file mode 100644
index 0000000..a91a485
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0041.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0041.wavetable
new file mode 100644
index 0000000..42ea0d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0042.wav b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0042.wav
new file mode 100644
index 0000000..17cab32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0042.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0042.wavetable
new file mode 100644
index 0000000..a2c67a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawgap/AKWF_gapsaw_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawgap/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_bw_sawgap/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_bw_sawgap/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_01.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_01.wav
new file mode 100644
index 0000000..5a19a2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_01.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_01.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_01.wavetable
new file mode 100644
index 0000000..8f53e47
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_01.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_02.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_02.wav
new file mode 100644
index 0000000..5868fbd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_02.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_02.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_02.wavetable
new file mode 100644
index 0000000..0da1327
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_02.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_03.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_03.wav
new file mode 100644
index 0000000..e41cf74
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_03.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_03.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_03.wavetable
new file mode 100644
index 0000000..d2925aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_03.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_04.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_04.wav
new file mode 100644
index 0000000..f764203
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_04.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_04.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_04.wavetable
new file mode 100644
index 0000000..d7a0d78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_04.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_05.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_05.wav
new file mode 100644
index 0000000..a5d5b39
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_05.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_05.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_05.wavetable
new file mode 100644
index 0000000..237bc91
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_05.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_06.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_06.wav
new file mode 100644
index 0000000..7a89c36
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_06.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_06.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_06.wavetable
new file mode 100644
index 0000000..c43d83e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_06.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_07.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_07.wav
new file mode 100644
index 0000000..325be54
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_07.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_07.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_07.wavetable
new file mode 100644
index 0000000..3097e97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_07.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_08.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_08.wav
new file mode 100644
index 0000000..426daad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_08.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_08.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_08.wavetable
new file mode 100644
index 0000000..1c602cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_08.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_09.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_09.wav
new file mode 100644
index 0000000..3095155
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_09.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_09.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_09.wavetable
new file mode 100644
index 0000000..ffcba58
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_09.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_10.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_10.wav
new file mode 100644
index 0000000..65c20ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_10.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_10.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_10.wavetable
new file mode 100644
index 0000000..56504b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_10.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_11.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_11.wav
new file mode 100644
index 0000000..420bf70
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_11.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_11.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_11.wavetable
new file mode 100644
index 0000000..9b2e4c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_11.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_12.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_12.wav
new file mode 100644
index 0000000..3986d6f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_12.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_12.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_12.wavetable
new file mode 100644
index 0000000..b9de4c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_12.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_13.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_13.wav
new file mode 100644
index 0000000..f9b641a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_13.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_13.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_13.wavetable
new file mode 100644
index 0000000..5890c35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_13.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_14.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_14.wav
new file mode 100644
index 0000000..6933003
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_14.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_14.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_14.wavetable
new file mode 100644
index 0000000..5fbf6ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_14.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_15.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_15.wav
new file mode 100644
index 0000000..d18251d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_15.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_15.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_15.wavetable
new file mode 100644
index 0000000..72abfa7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_15.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_16.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_16.wav
new file mode 100644
index 0000000..931abbf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_16.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_16.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_16.wavetable
new file mode 100644
index 0000000..b89c482
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_16.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_17.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_17.wav
new file mode 100644
index 0000000..c5abcdd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_17.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_17.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_17.wavetable
new file mode 100644
index 0000000..a4ba762
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_17.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_18.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_18.wav
new file mode 100644
index 0000000..f75891c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_18.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_18.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_18.wavetable
new file mode 100644
index 0000000..d932b7c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_18.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_19.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_19.wav
new file mode 100644
index 0000000..e2cdda9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_19.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_19.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_19.wavetable
new file mode 100644
index 0000000..c4c8155
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_19.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_20.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_20.wav
new file mode 100644
index 0000000..11e32ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_20.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_20.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_20.wavetable
new file mode 100644
index 0000000..6929424
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_20.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_21.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_21.wav
new file mode 100644
index 0000000..9cf9883
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_21.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_21.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_21.wavetable
new file mode 100644
index 0000000..f659bcc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_21.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_22.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_22.wav
new file mode 100644
index 0000000..aedfc24
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_22.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_22.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_22.wavetable
new file mode 100644
index 0000000..ca5ae97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_22.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_23.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_23.wav
new file mode 100644
index 0000000..31cc45e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_23.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_23.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_23.wavetable
new file mode 100644
index 0000000..00ed87d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_23.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_24.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_24.wav
new file mode 100644
index 0000000..03b3159
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_24.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_24.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_24.wavetable
new file mode 100644
index 0000000..439e52a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_24.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_25.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_25.wav
new file mode 100644
index 0000000..6c15382
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_25.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_25.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_25.wavetable
new file mode 100644
index 0000000..04b3de4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_25.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_26.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_26.wav
new file mode 100644
index 0000000..2f8898f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_26.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_26.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_26.wavetable
new file mode 100644
index 0000000..0bd4e2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_asym_saw_26.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_01.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_01.wav
new file mode 100644
index 0000000..c69fc21
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_01.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_01.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_01.wavetable
new file mode 100644
index 0000000..86c6881
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_01.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_02.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_02.wav
new file mode 100644
index 0000000..e0cee4b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_02.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_02.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_02.wavetable
new file mode 100644
index 0000000..5100261
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_02.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_03.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_03.wav
new file mode 100644
index 0000000..3acf544
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_03.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_03.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_03.wavetable
new file mode 100644
index 0000000..70bcee9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_03.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_04.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_04.wav
new file mode 100644
index 0000000..e66ac00
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_04.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_04.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_04.wavetable
new file mode 100644
index 0000000..732a291
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_04.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_05.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_05.wav
new file mode 100644
index 0000000..f6b4697
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_05.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_05.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_05.wavetable
new file mode 100644
index 0000000..7c50b8d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_05.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_06.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_06.wav
new file mode 100644
index 0000000..f2afe4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_06.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_06.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_06.wavetable
new file mode 100644
index 0000000..b3a81ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_06.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_07.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_07.wav
new file mode 100644
index 0000000..743a68e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_07.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_07.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_07.wavetable
new file mode 100644
index 0000000..d8aab31
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_07.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_08.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_08.wav
new file mode 100644
index 0000000..f4c448e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_08.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_08.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_08.wavetable
new file mode 100644
index 0000000..1984916
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_08.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_09.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_09.wav
new file mode 100644
index 0000000..d525700
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_09.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_09.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_09.wavetable
new file mode 100644
index 0000000..f2a383b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_09.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_10.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_10.wav
new file mode 100644
index 0000000..a5c00cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_10.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_10.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_10.wavetable
new file mode 100644
index 0000000..b9e9f33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_10.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_11.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_11.wav
new file mode 100644
index 0000000..af3077b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_11.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_11.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_11.wavetable
new file mode 100644
index 0000000..7e964ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_11.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_12.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_12.wav
new file mode 100644
index 0000000..092b79d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_12.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_12.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_12.wavetable
new file mode 100644
index 0000000..9bda299
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_12.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_13.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_13.wav
new file mode 100644
index 0000000..5ece91b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_13.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_13.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_13.wavetable
new file mode 100644
index 0000000..5e0100b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_13.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_14.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_14.wav
new file mode 100644
index 0000000..ceef8a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_14.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_14.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_14.wavetable
new file mode 100644
index 0000000..e42e8e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_14.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_15.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_15.wav
new file mode 100644
index 0000000..cfe28af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_15.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_15.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_15.wavetable
new file mode 100644
index 0000000..8bd5f3d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_15.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_16.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_16.wav
new file mode 100644
index 0000000..e5c205d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_16.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_16.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_16.wavetable
new file mode 100644
index 0000000..30939d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_16.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_17.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_17.wav
new file mode 100644
index 0000000..7ab4dbf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_17.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_17.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_17.wavetable
new file mode 100644
index 0000000..84d07fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_17.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_18.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_18.wav
new file mode 100644
index 0000000..4640a63
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_18.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_18.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_18.wavetable
new file mode 100644
index 0000000..78ffa92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_18.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_19.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_19.wav
new file mode 100644
index 0000000..d18bd12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_19.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_19.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_19.wavetable
new file mode 100644
index 0000000..c9ff7c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_19.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_20.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_20.wav
new file mode 100644
index 0000000..53a24d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_20.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_20.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_20.wavetable
new file mode 100644
index 0000000..47cf0a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_20.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_21.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_21.wav
new file mode 100644
index 0000000..f6e5fd1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_21.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_21.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_21.wavetable
new file mode 100644
index 0000000..6fe1d1a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_21.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_22.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_22.wav
new file mode 100644
index 0000000..8c52a49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_22.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_22.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_22.wavetable
new file mode 100644
index 0000000..71a2471
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_22.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_23.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_23.wav
new file mode 100644
index 0000000..5cbe719
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_23.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_23.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_23.wavetable
new file mode 100644
index 0000000..4f070f8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_23.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_24.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_24.wav
new file mode 100644
index 0000000..636f62d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_24.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_24.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_24.wavetable
new file mode 100644
index 0000000..3412026
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_24.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_25.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_25.wav
new file mode 100644
index 0000000..7379f99
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_25.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_25.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_25.wavetable
new file mode 100644
index 0000000..b201555
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_25.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_26.wav b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_26.wav
new file mode 100644
index 0000000..2a606b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_26.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_26.wavetable b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_26.wavetable
new file mode 100644
index 0000000..839e180
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AKWF_R_sym_saw_26.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sawrounded/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_bw_sawrounded/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0001.wav b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0001.wav
new file mode 100644
index 0000000..8de1e9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0001.wavetable b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0001.wavetable
new file mode 100644
index 0000000..f06d9b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0002.wav b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0002.wav
new file mode 100644
index 0000000..9758d3f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0002.wavetable b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0002.wavetable
new file mode 100644
index 0000000..9b73fc9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0003.wav b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0003.wav
new file mode 100644
index 0000000..509f1a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0003.wavetable b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0003.wavetable
new file mode 100644
index 0000000..ea16462
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0004.wav b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0004.wav
new file mode 100644
index 0000000..0e9c50f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0004.wavetable b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0004.wavetable
new file mode 100644
index 0000000..811c50b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0005.wav b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0005.wav
new file mode 100644
index 0000000..71c7315
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0005.wavetable b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0005.wavetable
new file mode 100644
index 0000000..aa03d53
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0006.wav b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0006.wav
new file mode 100644
index 0000000..ac08e40
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0006.wavetable b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0006.wavetable
new file mode 100644
index 0000000..012500d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0007.wav b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0007.wav
new file mode 100644
index 0000000..1630906
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0007.wavetable b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0007.wavetable
new file mode 100644
index 0000000..707fba6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0008.wav b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0008.wav
new file mode 100644
index 0000000..2386ddb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0008.wavetable b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0008.wavetable
new file mode 100644
index 0000000..91890bd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0009.wav b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0009.wav
new file mode 100644
index 0000000..f3e1e26
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0009.wavetable b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0009.wavetable
new file mode 100644
index 0000000..4285e62
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0010.wav b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0010.wav
new file mode 100644
index 0000000..8be14e2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0010.wavetable b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0010.wavetable
new file mode 100644
index 0000000..67330f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0011.wav b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0011.wav
new file mode 100644
index 0000000..67a5698
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0011.wavetable b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0011.wavetable
new file mode 100644
index 0000000..593d362
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0012.wav b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0012.wav
new file mode 100644
index 0000000..ef97875
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0012.wavetable b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0012.wavetable
new file mode 100644
index 0000000..c4523e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_sin/AKWF_sin_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_sin/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_bw_sin/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_bw_sin/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0001.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0001.wav
new file mode 100644
index 0000000..869fe53
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0001.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0001.wavetable
new file mode 100644
index 0000000..074288e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0002.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0002.wav
new file mode 100644
index 0000000..9c1aa54
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0002.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0002.wavetable
new file mode 100644
index 0000000..8dd5c9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0003.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0003.wav
new file mode 100644
index 0000000..0b39214
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0003.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0003.wavetable
new file mode 100644
index 0000000..28a398c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0004.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0004.wav
new file mode 100644
index 0000000..5097bed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0004.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0004.wavetable
new file mode 100644
index 0000000..1b39dfa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0005.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0005.wav
new file mode 100644
index 0000000..f090b54
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0005.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0005.wavetable
new file mode 100644
index 0000000..833d03e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0006.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0006.wav
new file mode 100644
index 0000000..3818618
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0006.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0006.wavetable
new file mode 100644
index 0000000..86d1615
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0007.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0007.wav
new file mode 100644
index 0000000..62454fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0007.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0007.wavetable
new file mode 100644
index 0000000..ded859b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0008.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0008.wav
new file mode 100644
index 0000000..c5c7e47
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0008.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0008.wavetable
new file mode 100644
index 0000000..2aa9864
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0009.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0009.wav
new file mode 100644
index 0000000..f6a02be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0009.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0009.wavetable
new file mode 100644
index 0000000..be75346
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0010.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0010.wav
new file mode 100644
index 0000000..74848c8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0010.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0010.wavetable
new file mode 100644
index 0000000..a62d104
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0011.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0011.wav
new file mode 100644
index 0000000..274f3eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0011.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0011.wavetable
new file mode 100644
index 0000000..62818ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0012.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0012.wav
new file mode 100644
index 0000000..28a64cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0012.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0012.wavetable
new file mode 100644
index 0000000..473ed41
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0013.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0013.wav
new file mode 100644
index 0000000..20e305d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0013.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0013.wavetable
new file mode 100644
index 0000000..bfd80b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0014.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0014.wav
new file mode 100644
index 0000000..0a30a4d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0014.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0014.wavetable
new file mode 100644
index 0000000..4971b86
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0015.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0015.wav
new file mode 100644
index 0000000..967474b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0015.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0015.wavetable
new file mode 100644
index 0000000..bf8531f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0016.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0016.wav
new file mode 100644
index 0000000..caf4bb7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0016.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0016.wavetable
new file mode 100644
index 0000000..2fb216c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0017.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0017.wav
new file mode 100644
index 0000000..692e2ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0017.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0017.wavetable
new file mode 100644
index 0000000..cf5d8b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0018.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0018.wav
new file mode 100644
index 0000000..bf24e34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0018.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0018.wavetable
new file mode 100644
index 0000000..abd1bd0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0019.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0019.wav
new file mode 100644
index 0000000..41be809
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0019.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0019.wavetable
new file mode 100644
index 0000000..ce71e70
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0020.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0020.wav
new file mode 100644
index 0000000..f39f9cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0020.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0020.wavetable
new file mode 100644
index 0000000..1bcd37c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0021.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0021.wav
new file mode 100644
index 0000000..594f17c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0021.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0021.wavetable
new file mode 100644
index 0000000..d1f64b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0022.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0022.wav
new file mode 100644
index 0000000..950c9bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0022.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0022.wavetable
new file mode 100644
index 0000000..66fdc3f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0023.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0023.wav
new file mode 100644
index 0000000..df04d69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0023.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0023.wavetable
new file mode 100644
index 0000000..27f9324
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0024.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0024.wav
new file mode 100644
index 0000000..93112c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0024.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0024.wavetable
new file mode 100644
index 0000000..93a5b32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0025.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0025.wav
new file mode 100644
index 0000000..8b9f975
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0025.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0025.wavetable
new file mode 100644
index 0000000..db54d1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0026.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0026.wav
new file mode 100644
index 0000000..2292702
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0026.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0026.wavetable
new file mode 100644
index 0000000..2b3235f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0027.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0027.wav
new file mode 100644
index 0000000..abc9b24
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0027.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0027.wavetable
new file mode 100644
index 0000000..f276309
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0028.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0028.wav
new file mode 100644
index 0000000..f4fb068
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0028.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0028.wavetable
new file mode 100644
index 0000000..a124b6a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0029.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0029.wav
new file mode 100644
index 0000000..03dbf45
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0029.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0029.wavetable
new file mode 100644
index 0000000..17a4dc4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0030.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0030.wav
new file mode 100644
index 0000000..0f1d534
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0030.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0030.wavetable
new file mode 100644
index 0000000..b2f46de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0031.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0031.wav
new file mode 100644
index 0000000..693f355
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0031.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0031.wavetable
new file mode 100644
index 0000000..4130a57
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0032.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0032.wav
new file mode 100644
index 0000000..655e1c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0032.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0032.wavetable
new file mode 100644
index 0000000..9f9513c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0033.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0033.wav
new file mode 100644
index 0000000..c24694d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0033.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0033.wavetable
new file mode 100644
index 0000000..dc6e110
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0034.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0034.wav
new file mode 100644
index 0000000..5cfa619
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0034.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0034.wavetable
new file mode 100644
index 0000000..36a2be5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0035.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0035.wav
new file mode 100644
index 0000000..ca62be3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0035.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0035.wavetable
new file mode 100644
index 0000000..3cd5630
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0036.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0036.wav
new file mode 100644
index 0000000..b11e635
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0036.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0036.wavetable
new file mode 100644
index 0000000..efc6695
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0037.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0037.wav
new file mode 100644
index 0000000..2ff2820
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0037.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0037.wavetable
new file mode 100644
index 0000000..dc0e260
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0038.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0038.wav
new file mode 100644
index 0000000..b38bc99
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0038.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0038.wavetable
new file mode 100644
index 0000000..142041e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0039.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0039.wav
new file mode 100644
index 0000000..2637cc5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0039.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0039.wavetable
new file mode 100644
index 0000000..637a131
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0040.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0040.wav
new file mode 100644
index 0000000..23cb31b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0040.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0040.wavetable
new file mode 100644
index 0000000..c1809b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0041.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0041.wav
new file mode 100644
index 0000000..b43e365
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0041.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0041.wavetable
new file mode 100644
index 0000000..3315f40
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0042.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0042.wav
new file mode 100644
index 0000000..09a607f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0042.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0042.wavetable
new file mode 100644
index 0000000..b196264
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0043.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0043.wav
new file mode 100644
index 0000000..d200013
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0043.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0043.wavetable
new file mode 100644
index 0000000..5717952
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0044.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0044.wav
new file mode 100644
index 0000000..34da4a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0044.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0044.wavetable
new file mode 100644
index 0000000..91950fc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0045.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0045.wav
new file mode 100644
index 0000000..db41576
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0045.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0045.wavetable
new file mode 100644
index 0000000..17b320f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0046.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0046.wav
new file mode 100644
index 0000000..f5f243a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0046.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0046.wavetable
new file mode 100644
index 0000000..2318cb8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0047.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0047.wav
new file mode 100644
index 0000000..bc124a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0047.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0047.wavetable
new file mode 100644
index 0000000..29f6428
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0048.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0048.wav
new file mode 100644
index 0000000..0a24531
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0048.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0048.wavetable
new file mode 100644
index 0000000..6d41e9b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0049.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0049.wav
new file mode 100644
index 0000000..7bbb965
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0049.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0049.wavetable
new file mode 100644
index 0000000..6c1a0b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0050.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0050.wav
new file mode 100644
index 0000000..f0f46d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0050.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0050.wavetable
new file mode 100644
index 0000000..e51d1e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0051.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0051.wav
new file mode 100644
index 0000000..c1b1c66
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0051.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0051.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0051.wavetable
new file mode 100644
index 0000000..9e45743
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0051.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0052.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0052.wav
new file mode 100644
index 0000000..302e31c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0052.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0052.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0052.wavetable
new file mode 100644
index 0000000..ce2c03e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0052.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0053.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0053.wav
new file mode 100644
index 0000000..59dd8f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0053.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0053.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0053.wavetable
new file mode 100644
index 0000000..130421d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0053.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0054.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0054.wav
new file mode 100644
index 0000000..bffd14a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0054.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0054.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0054.wavetable
new file mode 100644
index 0000000..1de09b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0054.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0055.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0055.wav
new file mode 100644
index 0000000..3f259d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0055.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0055.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0055.wavetable
new file mode 100644
index 0000000..ebbc451
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0055.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0056.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0056.wav
new file mode 100644
index 0000000..ba0af21
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0056.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0056.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0056.wavetable
new file mode 100644
index 0000000..636d218
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0056.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0057.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0057.wav
new file mode 100644
index 0000000..6bd3bf7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0057.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0057.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0057.wavetable
new file mode 100644
index 0000000..3f71e33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0057.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0058.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0058.wav
new file mode 100644
index 0000000..2ff7530
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0058.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0058.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0058.wavetable
new file mode 100644
index 0000000..3913def
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0058.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0059.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0059.wav
new file mode 100644
index 0000000..51a8070
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0059.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0059.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0059.wavetable
new file mode 100644
index 0000000..7db3282
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0059.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0060.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0060.wav
new file mode 100644
index 0000000..658a6c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0060.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0060.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0060.wavetable
new file mode 100644
index 0000000..0b18072
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0060.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0061.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0061.wav
new file mode 100644
index 0000000..91a159e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0061.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0061.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0061.wavetable
new file mode 100644
index 0000000..353b23f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0061.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0062.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0062.wav
new file mode 100644
index 0000000..3d29d47
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0062.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0062.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0062.wavetable
new file mode 100644
index 0000000..ee924ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0062.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0063.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0063.wav
new file mode 100644
index 0000000..8d67d0f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0063.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0063.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0063.wavetable
new file mode 100644
index 0000000..8c41b14
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0063.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0064.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0064.wav
new file mode 100644
index 0000000..dd746b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0064.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0064.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0064.wavetable
new file mode 100644
index 0000000..7088143
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0064.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0065.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0065.wav
new file mode 100644
index 0000000..d370d5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0065.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0065.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0065.wavetable
new file mode 100644
index 0000000..67a8751
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0065.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0066.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0066.wav
new file mode 100644
index 0000000..0c09c2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0066.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0066.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0066.wavetable
new file mode 100644
index 0000000..945ddc9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0066.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0067.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0067.wav
new file mode 100644
index 0000000..96e26af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0067.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0067.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0067.wavetable
new file mode 100644
index 0000000..7eddb63
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0067.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0068.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0068.wav
new file mode 100644
index 0000000..61eccd9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0068.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0068.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0068.wavetable
new file mode 100644
index 0000000..a100ee6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0068.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0069.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0069.wav
new file mode 100644
index 0000000..57fa1cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0069.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0069.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0069.wavetable
new file mode 100644
index 0000000..d21bdf0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0069.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0070.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0070.wav
new file mode 100644
index 0000000..f235b75
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0070.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0070.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0070.wavetable
new file mode 100644
index 0000000..c71e7cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0070.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0071.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0071.wav
new file mode 100644
index 0000000..8f8f7fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0071.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0071.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0071.wavetable
new file mode 100644
index 0000000..e315aad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0071.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0072.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0072.wav
new file mode 100644
index 0000000..6b30302
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0072.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0072.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0072.wavetable
new file mode 100644
index 0000000..0938dd4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0072.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0073.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0073.wav
new file mode 100644
index 0000000..4b8c28b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0073.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0073.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0073.wavetable
new file mode 100644
index 0000000..0ead81d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0073.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0074.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0074.wav
new file mode 100644
index 0000000..40849e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0074.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0074.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0074.wavetable
new file mode 100644
index 0000000..be48698
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0074.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0075.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0075.wav
new file mode 100644
index 0000000..f2d6621
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0075.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0075.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0075.wavetable
new file mode 100644
index 0000000..aa14b0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0075.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0076.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0076.wav
new file mode 100644
index 0000000..38b0d3d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0076.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0076.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0076.wavetable
new file mode 100644
index 0000000..11f5184
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0076.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0077.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0077.wav
new file mode 100644
index 0000000..a0bbbac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0077.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0077.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0077.wavetable
new file mode 100644
index 0000000..da11abc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0077.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0078.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0078.wav
new file mode 100644
index 0000000..7b4c1c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0078.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0078.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0078.wavetable
new file mode 100644
index 0000000..837faa0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0078.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0079.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0079.wav
new file mode 100644
index 0000000..97eb39d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0079.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0079.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0079.wavetable
new file mode 100644
index 0000000..e60bdf9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0079.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0080.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0080.wav
new file mode 100644
index 0000000..6ee6569
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0080.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0080.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0080.wavetable
new file mode 100644
index 0000000..62c3dc8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0080.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0081.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0081.wav
new file mode 100644
index 0000000..da07583
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0081.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0081.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0081.wavetable
new file mode 100644
index 0000000..f627786
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0081.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0082.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0082.wav
new file mode 100644
index 0000000..dcb75d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0082.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0082.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0082.wavetable
new file mode 100644
index 0000000..cb3f069
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0082.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0083.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0083.wav
new file mode 100644
index 0000000..952f9a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0083.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0083.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0083.wavetable
new file mode 100644
index 0000000..a7cf3f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0083.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0084.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0084.wav
new file mode 100644
index 0000000..525b179
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0084.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0084.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0084.wavetable
new file mode 100644
index 0000000..64ca347
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0084.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0085.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0085.wav
new file mode 100644
index 0000000..d339392
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0085.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0085.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0085.wavetable
new file mode 100644
index 0000000..654f0e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0085.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0086.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0086.wav
new file mode 100644
index 0000000..c5e499e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0086.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0086.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0086.wavetable
new file mode 100644
index 0000000..8b446c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0086.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0087.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0087.wav
new file mode 100644
index 0000000..513cab0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0087.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0087.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0087.wavetable
new file mode 100644
index 0000000..3b14db9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0087.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0088.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0088.wav
new file mode 100644
index 0000000..401fee0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0088.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0088.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0088.wavetable
new file mode 100644
index 0000000..2dd0538
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0088.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0089.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0089.wav
new file mode 100644
index 0000000..b35d1e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0089.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0089.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0089.wavetable
new file mode 100644
index 0000000..27e764c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0089.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0090.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0090.wav
new file mode 100644
index 0000000..cb53043
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0090.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0090.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0090.wavetable
new file mode 100644
index 0000000..8db03f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0090.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0091.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0091.wav
new file mode 100644
index 0000000..bf67e19
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0091.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0091.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0091.wavetable
new file mode 100644
index 0000000..676647b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0091.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0092.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0092.wav
new file mode 100644
index 0000000..efcb522
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0092.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0092.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0092.wavetable
new file mode 100644
index 0000000..59db0b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0092.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0093.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0093.wav
new file mode 100644
index 0000000..fe1fea0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0093.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0093.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0093.wavetable
new file mode 100644
index 0000000..771bda5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0093.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0094.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0094.wav
new file mode 100644
index 0000000..e1fb2a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0094.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0094.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0094.wavetable
new file mode 100644
index 0000000..6142b15
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0094.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0095.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0095.wav
new file mode 100644
index 0000000..311e07e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0095.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0095.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0095.wavetable
new file mode 100644
index 0000000..32e819e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0095.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0096.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0096.wav
new file mode 100644
index 0000000..a5944af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0096.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0096.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0096.wavetable
new file mode 100644
index 0000000..df56b6f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0096.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0097.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0097.wav
new file mode 100644
index 0000000..75b3929
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0097.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0097.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0097.wavetable
new file mode 100644
index 0000000..c721d5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0097.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0098.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0098.wav
new file mode 100644
index 0000000..332ea69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0098.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0098.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0098.wavetable
new file mode 100644
index 0000000..21ff54f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0098.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0099.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0099.wav
new file mode 100644
index 0000000..02119f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0099.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0099.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0099.wavetable
new file mode 100644
index 0000000..dcaca72
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0099.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0100.wav b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0100.wav
new file mode 100644
index 0000000..cddf95e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0100.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0100.wavetable b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0100.wavetable
new file mode 100644
index 0000000..50ae88e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squ/AKWF_squ_0100.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squ/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_bw_squ/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_bw_squ/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_01.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_01.wav
new file mode 100644
index 0000000..1b80de6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_01.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_01.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_01.wavetable
new file mode 100644
index 0000000..b146098
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_01.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_02.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_02.wav
new file mode 100644
index 0000000..08d0ab4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_02.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_02.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_02.wavetable
new file mode 100644
index 0000000..736db28
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_02.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_03.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_03.wav
new file mode 100644
index 0000000..fe49201
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_03.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_03.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_03.wavetable
new file mode 100644
index 0000000..e71da98
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_03.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_04.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_04.wav
new file mode 100644
index 0000000..ae2adbb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_04.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_04.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_04.wavetable
new file mode 100644
index 0000000..4ad00c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_04.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_05.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_05.wav
new file mode 100644
index 0000000..4bd0a5e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_05.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_05.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_05.wavetable
new file mode 100644
index 0000000..eb6f226
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_05.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_06.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_06.wav
new file mode 100644
index 0000000..2c9b4cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_06.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_06.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_06.wavetable
new file mode 100644
index 0000000..e8bde73
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_06.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_07.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_07.wav
new file mode 100644
index 0000000..7c760b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_07.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_07.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_07.wavetable
new file mode 100644
index 0000000..6878c22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_07.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_08.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_08.wav
new file mode 100644
index 0000000..b70d354
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_08.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_08.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_08.wavetable
new file mode 100644
index 0000000..c2efa23
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_08.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_09.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_09.wav
new file mode 100644
index 0000000..e6fe69d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_09.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_09.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_09.wavetable
new file mode 100644
index 0000000..684c1b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_09.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_10.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_10.wav
new file mode 100644
index 0000000..fced234
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_10.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_10.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_10.wavetable
new file mode 100644
index 0000000..5afa4d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_10.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_11.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_11.wav
new file mode 100644
index 0000000..c3688a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_11.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_11.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_11.wavetable
new file mode 100644
index 0000000..0c5fca9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_11.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_12.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_12.wav
new file mode 100644
index 0000000..372dbe0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_12.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_12.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_12.wavetable
new file mode 100644
index 0000000..4360400
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_12.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_13.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_13.wav
new file mode 100644
index 0000000..576c27e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_13.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_13.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_13.wavetable
new file mode 100644
index 0000000..a6b361e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_13.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_14.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_14.wav
new file mode 100644
index 0000000..cb4694d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_14.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_14.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_14.wavetable
new file mode 100644
index 0000000..a3b6ab2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_14.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_15.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_15.wav
new file mode 100644
index 0000000..adcac48
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_15.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_15.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_15.wavetable
new file mode 100644
index 0000000..a1ea3b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_15.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_16.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_16.wav
new file mode 100644
index 0000000..5bfe7b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_16.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_16.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_16.wavetable
new file mode 100644
index 0000000..7979c32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_16.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_17.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_17.wav
new file mode 100644
index 0000000..3c939ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_17.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_17.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_17.wavetable
new file mode 100644
index 0000000..1328bf5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_17.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_18.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_18.wav
new file mode 100644
index 0000000..c7b1e1a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_18.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_18.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_18.wavetable
new file mode 100644
index 0000000..33aeab2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_18.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_19.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_19.wav
new file mode 100644
index 0000000..42efe44
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_19.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_19.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_19.wavetable
new file mode 100644
index 0000000..e325e13
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_19.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_20.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_20.wav
new file mode 100644
index 0000000..8af72e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_20.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_20.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_20.wavetable
new file mode 100644
index 0000000..21dc156
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_20.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_21.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_21.wav
new file mode 100644
index 0000000..75242a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_21.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_21.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_21.wavetable
new file mode 100644
index 0000000..7c1c40c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_21.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_22.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_22.wav
new file mode 100644
index 0000000..e8922a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_22.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_22.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_22.wavetable
new file mode 100644
index 0000000..1c98823
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_22.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_23.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_23.wav
new file mode 100644
index 0000000..cc35cdb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_23.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_23.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_23.wavetable
new file mode 100644
index 0000000..26b6132
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_23.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_24.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_24.wav
new file mode 100644
index 0000000..499a9f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_24.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_24.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_24.wavetable
new file mode 100644
index 0000000..1a7b938
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_24.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_25.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_25.wav
new file mode 100644
index 0000000..202211c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_25.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_25.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_25.wavetable
new file mode 100644
index 0000000..0dd0d7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_25.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_26.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_26.wav
new file mode 100644
index 0000000..7283969
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_26.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_26.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_26.wavetable
new file mode 100644
index 0000000..474aea1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rAsymSqu_26.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_01.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_01.wav
new file mode 100644
index 0000000..b3f63ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_01.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_01.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_01.wavetable
new file mode 100644
index 0000000..81de5e3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_01.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_02.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_02.wav
new file mode 100644
index 0000000..017b0b7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_02.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_02.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_02.wavetable
new file mode 100644
index 0000000..5f2d5d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_02.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_03.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_03.wav
new file mode 100644
index 0000000..365955f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_03.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_03.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_03.wavetable
new file mode 100644
index 0000000..5346ea1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_03.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_04.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_04.wav
new file mode 100644
index 0000000..fac3222
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_04.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_04.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_04.wavetable
new file mode 100644
index 0000000..b10d91d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_04.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_05.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_05.wav
new file mode 100644
index 0000000..b2f8ad2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_05.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_05.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_05.wavetable
new file mode 100644
index 0000000..e112189
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_05.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_06.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_06.wav
new file mode 100644
index 0000000..3a277d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_06.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_06.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_06.wavetable
new file mode 100644
index 0000000..6bd63fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_06.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_07.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_07.wav
new file mode 100644
index 0000000..72e23f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_07.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_07.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_07.wavetable
new file mode 100644
index 0000000..b233841
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_07.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_08.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_08.wav
new file mode 100644
index 0000000..b435d12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_08.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_08.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_08.wavetable
new file mode 100644
index 0000000..eb39746
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_08.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_09.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_09.wav
new file mode 100644
index 0000000..3b327d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_09.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_09.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_09.wavetable
new file mode 100644
index 0000000..5d58f34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_09.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_10.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_10.wav
new file mode 100644
index 0000000..bc745fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_10.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_10.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_10.wavetable
new file mode 100644
index 0000000..d88f1b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_10.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_11.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_11.wav
new file mode 100644
index 0000000..7421add
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_11.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_11.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_11.wavetable
new file mode 100644
index 0000000..ed9317a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_11.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_12.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_12.wav
new file mode 100644
index 0000000..1509a37
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_12.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_12.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_12.wavetable
new file mode 100644
index 0000000..7cd913b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_12.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_13.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_13.wav
new file mode 100644
index 0000000..38bcb87
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_13.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_13.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_13.wavetable
new file mode 100644
index 0000000..f5031a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_13.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_14.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_14.wav
new file mode 100644
index 0000000..dca497d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_14.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_14.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_14.wavetable
new file mode 100644
index 0000000..872ed67
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_14.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_15.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_15.wav
new file mode 100644
index 0000000..4f76823
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_15.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_15.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_15.wavetable
new file mode 100644
index 0000000..d693d6a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_15.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_16.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_16.wav
new file mode 100644
index 0000000..a4d674e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_16.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_16.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_16.wavetable
new file mode 100644
index 0000000..3ade92b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_16.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_17.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_17.wav
new file mode 100644
index 0000000..8482667
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_17.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_17.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_17.wavetable
new file mode 100644
index 0000000..d54e9f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_17.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_18.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_18.wav
new file mode 100644
index 0000000..0b20967
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_18.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_18.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_18.wavetable
new file mode 100644
index 0000000..09aa6d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_18.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_19.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_19.wav
new file mode 100644
index 0000000..c9f15926
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_19.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_19.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_19.wavetable
new file mode 100644
index 0000000..ce1c3b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_19.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_20.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_20.wav
new file mode 100644
index 0000000..00ec93d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_20.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_20.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_20.wavetable
new file mode 100644
index 0000000..fb42342
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_20.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_21.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_21.wav
new file mode 100644
index 0000000..b0b36fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_21.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_21.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_21.wavetable
new file mode 100644
index 0000000..a4c820b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_21.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_22.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_22.wav
new file mode 100644
index 0000000..c028a32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_22.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_22.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_22.wavetable
new file mode 100644
index 0000000..5050009
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_22.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_23.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_23.wav
new file mode 100644
index 0000000..146dcb4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_23.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_23.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_23.wavetable
new file mode 100644
index 0000000..71f8e91
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_23.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_24.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_24.wav
new file mode 100644
index 0000000..2eace09
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_24.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_24.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_24.wavetable
new file mode 100644
index 0000000..6981bd6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_24.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_25.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_25.wav
new file mode 100644
index 0000000..8b07a9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_25.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_25.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_25.wavetable
new file mode 100644
index 0000000..8b356d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_25.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_26.wav b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_26.wav
new file mode 100644
index 0000000..e0fa0ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_26.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_26.wavetable b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_26.wavetable
new file mode 100644
index 0000000..506d793
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_squrounded/AKWF_rSymSqu_26.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_squrounded/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_bw_squrounded/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_bw_squrounded/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0001.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0001.wav
new file mode 100644
index 0000000..5166f1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0001.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0001.wavetable
new file mode 100644
index 0000000..a88bc7e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0002.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0002.wav
new file mode 100644
index 0000000..29b0bd6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0002.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0002.wavetable
new file mode 100644
index 0000000..88acc94
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0003.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0003.wav
new file mode 100644
index 0000000..f00ea30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0003.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0003.wavetable
new file mode 100644
index 0000000..215856a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0004.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0004.wav
new file mode 100644
index 0000000..33332d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0004.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0004.wavetable
new file mode 100644
index 0000000..f3bd89a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0005.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0005.wav
new file mode 100644
index 0000000..12176e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0005.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0005.wavetable
new file mode 100644
index 0000000..2c9b25e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0006.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0006.wav
new file mode 100644
index 0000000..45f6422
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0006.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0006.wavetable
new file mode 100644
index 0000000..15beef3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0007.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0007.wav
new file mode 100644
index 0000000..c9ab8b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0007.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0007.wavetable
new file mode 100644
index 0000000..c0204f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0008.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0008.wav
new file mode 100644
index 0000000..3591264
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0008.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0008.wavetable
new file mode 100644
index 0000000..c0f44ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0009.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0009.wav
new file mode 100644
index 0000000..a3316cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0009.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0009.wavetable
new file mode 100644
index 0000000..bfd7fb0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0010.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0010.wav
new file mode 100644
index 0000000..0aebdfa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0010.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0010.wavetable
new file mode 100644
index 0000000..a0f31fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0011.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0011.wav
new file mode 100644
index 0000000..c79b876
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0011.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0011.wavetable
new file mode 100644
index 0000000..fb084f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0012.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0012.wav
new file mode 100644
index 0000000..911d6de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0012.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0012.wavetable
new file mode 100644
index 0000000..d03f33a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0013.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0013.wav
new file mode 100644
index 0000000..b44e20b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0013.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0013.wavetable
new file mode 100644
index 0000000..0ce86eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0014.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0014.wav
new file mode 100644
index 0000000..5c2b980
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0014.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0014.wavetable
new file mode 100644
index 0000000..405b777
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0015.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0015.wav
new file mode 100644
index 0000000..740d7ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0015.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0015.wavetable
new file mode 100644
index 0000000..fab6a4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0016.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0016.wav
new file mode 100644
index 0000000..6372753
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0016.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0016.wavetable
new file mode 100644
index 0000000..fdcb2c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0017.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0017.wav
new file mode 100644
index 0000000..b26bd85
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0017.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0017.wavetable
new file mode 100644
index 0000000..adc8db6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0018.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0018.wav
new file mode 100644
index 0000000..43821a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0018.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0018.wavetable
new file mode 100644
index 0000000..a50f147
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0019.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0019.wav
new file mode 100644
index 0000000..40d200a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0019.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0019.wavetable
new file mode 100644
index 0000000..ff91b88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0020.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0020.wav
new file mode 100644
index 0000000..636926c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0020.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0020.wavetable
new file mode 100644
index 0000000..2cbb537
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0021.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0021.wav
new file mode 100644
index 0000000..69c475d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0021.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0021.wavetable
new file mode 100644
index 0000000..e117eaa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0022.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0022.wav
new file mode 100644
index 0000000..47988a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0022.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0022.wavetable
new file mode 100644
index 0000000..ff10fa6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0023.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0023.wav
new file mode 100644
index 0000000..a3f9cf8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0023.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0023.wavetable
new file mode 100644
index 0000000..45f0552
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0024.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0024.wav
new file mode 100644
index 0000000..565d2e3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0024.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0024.wavetable
new file mode 100644
index 0000000..cb3c639
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0025.wav b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0025.wav
new file mode 100644
index 0000000..1619ccc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0025.wavetable b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0025.wavetable
new file mode 100644
index 0000000..59d9553
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_bw_tri/AKWF_tri_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_bw_tri/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_bw_tri/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_bw_tri/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0001.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0001.wav
new file mode 100644
index 0000000..c49776c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0001.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0001.wavetable
new file mode 100644
index 0000000..a7d8260
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0002.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0002.wav
new file mode 100644
index 0000000..2f174da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0002.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0002.wavetable
new file mode 100644
index 0000000..4a079ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0003.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0003.wav
new file mode 100644
index 0000000..cc00e1e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0003.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0003.wavetable
new file mode 100644
index 0000000..328bfea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0004.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0004.wav
new file mode 100644
index 0000000..10d3b12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0004.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0004.wavetable
new file mode 100644
index 0000000..3ba81db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0005.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0005.wav
new file mode 100644
index 0000000..122fd66
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0005.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0005.wavetable
new file mode 100644
index 0000000..e7182b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0006.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0006.wav
new file mode 100644
index 0000000..c158951
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0006.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0006.wavetable
new file mode 100644
index 0000000..de4fe05
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0007.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0007.wav
new file mode 100644
index 0000000..52a213b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0007.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0007.wavetable
new file mode 100644
index 0000000..563e80f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0008.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0008.wav
new file mode 100644
index 0000000..8247b3f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0008.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0008.wavetable
new file mode 100644
index 0000000..7ab0a03
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0009.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0009.wav
new file mode 100644
index 0000000..bf18437
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0009.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0009.wavetable
new file mode 100644
index 0000000..7a1fda5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0010.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0010.wav
new file mode 100644
index 0000000..89c8c5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0010.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0010.wavetable
new file mode 100644
index 0000000..57e5fff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0011.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0011.wav
new file mode 100644
index 0000000..9f9eda9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0011.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0011.wavetable
new file mode 100644
index 0000000..771f653
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0012.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0012.wav
new file mode 100644
index 0000000..bb6da7e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0012.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0012.wavetable
new file mode 100644
index 0000000..61500b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0013.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0013.wav
new file mode 100644
index 0000000..8d7f62a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0013.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0013.wavetable
new file mode 100644
index 0000000..f0a9d75
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0014.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0014.wav
new file mode 100644
index 0000000..ed76d25
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0014.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0014.wavetable
new file mode 100644
index 0000000..304f479
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0015.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0015.wav
new file mode 100644
index 0000000..d5cbd34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0015.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0015.wavetable
new file mode 100644
index 0000000..655a8f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0016.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0016.wav
new file mode 100644
index 0000000..da324d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0016.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0016.wavetable
new file mode 100644
index 0000000..773431e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0017.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0017.wav
new file mode 100644
index 0000000..2a0bc88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0017.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0017.wavetable
new file mode 100644
index 0000000..400064e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0018.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0018.wav
new file mode 100644
index 0000000..69e959c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0018.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0018.wavetable
new file mode 100644
index 0000000..ab4ced5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0019.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0019.wav
new file mode 100644
index 0000000..95e04a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0019.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0019.wavetable
new file mode 100644
index 0000000..10ca4a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0020.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0020.wav
new file mode 100644
index 0000000..9a4991a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0020.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0020.wavetable
new file mode 100644
index 0000000..15a257d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0021.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0021.wav
new file mode 100644
index 0000000..7c07399
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0021.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0021.wavetable
new file mode 100644
index 0000000..6f3ecd1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0022.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0022.wav
new file mode 100644
index 0000000..15c4758
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0022.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0022.wavetable
new file mode 100644
index 0000000..dbc86c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0023.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0023.wav
new file mode 100644
index 0000000..fd09f3d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0023.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0023.wavetable
new file mode 100644
index 0000000..0e1b12f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0024.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0024.wav
new file mode 100644
index 0000000..b8bee3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0024.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0024.wavetable
new file mode 100644
index 0000000..bb7d4b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0025.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0025.wav
new file mode 100644
index 0000000..285ca12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0025.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0025.wavetable
new file mode 100644
index 0000000..6c725d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0026.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0026.wav
new file mode 100644
index 0000000..5339799
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0026.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0026.wavetable
new file mode 100644
index 0000000..f87de96
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0027.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0027.wav
new file mode 100644
index 0000000..77fd35d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0027.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0027.wavetable
new file mode 100644
index 0000000..9f082c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0028.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0028.wav
new file mode 100644
index 0000000..7d4cf08
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0028.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0028.wavetable
new file mode 100644
index 0000000..9996e91
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0029.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0029.wav
new file mode 100644
index 0000000..fdd429c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0029.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0029.wavetable
new file mode 100644
index 0000000..9580ab6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0030.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0030.wav
new file mode 100644
index 0000000..38daa7c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0030.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0030.wavetable
new file mode 100644
index 0000000..2ec26ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0031.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0031.wav
new file mode 100644
index 0000000..f7448fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0031.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0031.wavetable
new file mode 100644
index 0000000..12b7bbc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0032.wav b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0032.wav
new file mode 100644
index 0000000..5da5ada
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0032.wavetable b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0032.wavetable
new file mode 100644
index 0000000..a5e84c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_c604/AKWF_c604_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_c604/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_c604/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_c604/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0001.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0001.wav
new file mode 100644
index 0000000..71415ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0001.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0001.wavetable
new file mode 100644
index 0000000..d44dc6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0002.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0002.wav
new file mode 100644
index 0000000..65b6051
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0002.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0002.wavetable
new file mode 100644
index 0000000..ea5fe4a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0003.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0003.wav
new file mode 100644
index 0000000..5dfd12e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0003.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0003.wavetable
new file mode 100644
index 0000000..c089df1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0004.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0004.wav
new file mode 100644
index 0000000..871322b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0004.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0004.wavetable
new file mode 100644
index 0000000..f6b3b59
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0005.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0005.wav
new file mode 100644
index 0000000..1029df3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0005.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0005.wavetable
new file mode 100644
index 0000000..4c1939b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0006.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0006.wav
new file mode 100644
index 0000000..f8d368e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0006.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0006.wavetable
new file mode 100644
index 0000000..abce8d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0007.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0007.wav
new file mode 100644
index 0000000..4c0f24a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0007.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0007.wavetable
new file mode 100644
index 0000000..dfc2bc2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0008.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0008.wav
new file mode 100644
index 0000000..c355ab1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0008.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0008.wavetable
new file mode 100644
index 0000000..8a2ffcb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0009.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0009.wav
new file mode 100644
index 0000000..13a2899
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0009.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0009.wavetable
new file mode 100644
index 0000000..87c4028
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0010.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0010.wav
new file mode 100644
index 0000000..de6b057
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0010.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0010.wavetable
new file mode 100644
index 0000000..1cdda0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0011.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0011.wav
new file mode 100644
index 0000000..53f1dfe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0011.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0011.wavetable
new file mode 100644
index 0000000..82b6d0c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0012.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0012.wav
new file mode 100644
index 0000000..960aabf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0012.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0012.wavetable
new file mode 100644
index 0000000..6e771ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0013.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0013.wav
new file mode 100644
index 0000000..f67e0f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0013.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0013.wavetable
new file mode 100644
index 0000000..34beca3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0014.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0014.wav
new file mode 100644
index 0000000..07a0443
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0014.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0014.wavetable
new file mode 100644
index 0000000..6079a9f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0015.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0015.wav
new file mode 100644
index 0000000..c9c3af0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0015.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0015.wavetable
new file mode 100644
index 0000000..e42613b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0016.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0016.wav
new file mode 100644
index 0000000..a020d73
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0016.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0016.wavetable
new file mode 100644
index 0000000..f507e1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0017.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0017.wav
new file mode 100644
index 0000000..f0048df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0017.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0017.wavetable
new file mode 100644
index 0000000..5c72a0b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0018.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0018.wav
new file mode 100644
index 0000000..5aae4f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0018.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0018.wavetable
new file mode 100644
index 0000000..e15bd10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0019.wav b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0019.wav
new file mode 100644
index 0000000..9f2f52b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0019.wavetable b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0019.wavetable
new file mode 100644
index 0000000..19af622
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_cello/AKWF_cello_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_cello/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_cello/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_cello/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0001.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0001.wav
new file mode 100644
index 0000000..e98981f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0001.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0001.wavetable
new file mode 100644
index 0000000..a50bf87
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0002.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0002.wav
new file mode 100644
index 0000000..9ed8764
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0002.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0002.wavetable
new file mode 100644
index 0000000..c8711d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0003.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0003.wav
new file mode 100644
index 0000000..7566fcc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0003.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0003.wavetable
new file mode 100644
index 0000000..133f73b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0004.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0004.wav
new file mode 100644
index 0000000..e05a2fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0004.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0004.wavetable
new file mode 100644
index 0000000..60cf5c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0005.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0005.wav
new file mode 100644
index 0000000..d8abb8a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0005.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0005.wavetable
new file mode 100644
index 0000000..f1696a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0006.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0006.wav
new file mode 100644
index 0000000..9bfa9b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0006.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0006.wavetable
new file mode 100644
index 0000000..baa212e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0007.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0007.wav
new file mode 100644
index 0000000..2b8100c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0007.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0007.wavetable
new file mode 100644
index 0000000..ed6e930
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0008.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0008.wav
new file mode 100644
index 0000000..5d134d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0008.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0008.wavetable
new file mode 100644
index 0000000..29cc8e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0009.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0009.wav
new file mode 100644
index 0000000..a060f52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0009.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0009.wavetable
new file mode 100644
index 0000000..9ad4772
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0010.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0010.wav
new file mode 100644
index 0000000..6ace5b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0010.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0010.wavetable
new file mode 100644
index 0000000..77911a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0011.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0011.wav
new file mode 100644
index 0000000..5c9e8bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0011.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0011.wavetable
new file mode 100644
index 0000000..497bca2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0012.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0012.wav
new file mode 100644
index 0000000..0a125e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0012.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0012.wavetable
new file mode 100644
index 0000000..d880783
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0013.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0013.wav
new file mode 100644
index 0000000..278145a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0013.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0013.wavetable
new file mode 100644
index 0000000..b745844
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0014.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0014.wav
new file mode 100644
index 0000000..7c28c30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0014.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0014.wavetable
new file mode 100644
index 0000000..466b218
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0015.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0015.wav
new file mode 100644
index 0000000..7588978
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0015.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0015.wavetable
new file mode 100644
index 0000000..ad1bdb8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0016.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0016.wav
new file mode 100644
index 0000000..684baad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0016.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0016.wavetable
new file mode 100644
index 0000000..35e5d3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0017.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0017.wav
new file mode 100644
index 0000000..bc53103
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0017.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0017.wavetable
new file mode 100644
index 0000000..c124a69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0018.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0018.wav
new file mode 100644
index 0000000..263ca69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0018.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0018.wavetable
new file mode 100644
index 0000000..00bd842
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0019.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0019.wav
new file mode 100644
index 0000000..433d02c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0019.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0019.wavetable
new file mode 100644
index 0000000..ea8c8b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0020.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0020.wav
new file mode 100644
index 0000000..9a44908
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0020.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0020.wavetable
new file mode 100644
index 0000000..3c660cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0021.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0021.wav
new file mode 100644
index 0000000..48f8579
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0021.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0021.wavetable
new file mode 100644
index 0000000..0b995d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0022.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0022.wav
new file mode 100644
index 0000000..90e3018
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0022.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0022.wavetable
new file mode 100644
index 0000000..8635405
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0023.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0023.wav
new file mode 100644
index 0000000..c9f9bc5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0023.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0023.wavetable
new file mode 100644
index 0000000..6106926
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0024.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0024.wav
new file mode 100644
index 0000000..3b9a796
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0024.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0024.wavetable
new file mode 100644
index 0000000..f61532b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0025.wav b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0025.wav
new file mode 100644
index 0000000..701fd31
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0025.wavetable b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0025.wavetable
new file mode 100644
index 0000000..984eef9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clarinett/AKWF_clarinett_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clarinett/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_clarinett/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_clarinett/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0001.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0001.wav
new file mode 100644
index 0000000..917da38
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0001.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0001.wavetable
new file mode 100644
index 0000000..deebb7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0002.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0002.wav
new file mode 100644
index 0000000..b8202cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0002.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0002.wavetable
new file mode 100644
index 0000000..6229dff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0003.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0003.wav
new file mode 100644
index 0000000..434bfb8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0003.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0003.wavetable
new file mode 100644
index 0000000..8c39fdf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0004.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0004.wav
new file mode 100644
index 0000000..6c1b678
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0004.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0004.wavetable
new file mode 100644
index 0000000..b0b3ee4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0005.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0005.wav
new file mode 100644
index 0000000..29f443e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0005.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0005.wavetable
new file mode 100644
index 0000000..8022739
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0006.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0006.wav
new file mode 100644
index 0000000..183e78c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0006.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0006.wavetable
new file mode 100644
index 0000000..46260c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0007.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0007.wav
new file mode 100644
index 0000000..6777d3a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0007.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0007.wavetable
new file mode 100644
index 0000000..a7089b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0008.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0008.wav
new file mode 100644
index 0000000..6969dc3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0008.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0008.wavetable
new file mode 100644
index 0000000..2cf1ad0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0009.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0009.wav
new file mode 100644
index 0000000..7e48461
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0009.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0009.wavetable
new file mode 100644
index 0000000..687e8b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0010.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0010.wav
new file mode 100644
index 0000000..4ded64b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0010.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0010.wavetable
new file mode 100644
index 0000000..146f80d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0011.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0011.wav
new file mode 100644
index 0000000..2bfca45
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0011.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0011.wavetable
new file mode 100644
index 0000000..5801548
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0012.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0012.wav
new file mode 100644
index 0000000..3d31d34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0012.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0012.wavetable
new file mode 100644
index 0000000..25cda5f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0013.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0013.wav
new file mode 100644
index 0000000..2cfaa22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0013.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0013.wavetable
new file mode 100644
index 0000000..a6ceee0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0014.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0014.wav
new file mode 100644
index 0000000..4af7e4a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0014.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0014.wavetable
new file mode 100644
index 0000000..5d6778e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0015.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0015.wav
new file mode 100644
index 0000000..050df17
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0015.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0015.wavetable
new file mode 100644
index 0000000..846af85
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0016.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0016.wav
new file mode 100644
index 0000000..575fe1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0016.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0016.wavetable
new file mode 100644
index 0000000..5e2d44a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0017.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0017.wav
new file mode 100644
index 0000000..dce8a30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0017.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0017.wavetable
new file mode 100644
index 0000000..b0eb22c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0018.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0018.wav
new file mode 100644
index 0000000..255f403
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0018.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0018.wavetable
new file mode 100644
index 0000000..1acae66
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0019.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0019.wav
new file mode 100644
index 0000000..41eca76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0019.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0019.wavetable
new file mode 100644
index 0000000..cb57daa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0020.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0020.wav
new file mode 100644
index 0000000..a72e7a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0020.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0020.wavetable
new file mode 100644
index 0000000..b066567
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0021.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0021.wav
new file mode 100644
index 0000000..3a5c03d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0021.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0021.wavetable
new file mode 100644
index 0000000..94c10c8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0022.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0022.wav
new file mode 100644
index 0000000..63f46d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0022.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0022.wavetable
new file mode 100644
index 0000000..4309da8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0023.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0023.wav
new file mode 100644
index 0000000..d0cae08
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0023.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0023.wavetable
new file mode 100644
index 0000000..baff9be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0024.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0024.wav
new file mode 100644
index 0000000..7426316
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0024.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0024.wavetable
new file mode 100644
index 0000000..76d46df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0025.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0025.wav
new file mode 100644
index 0000000..a86e52e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0025.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0025.wavetable
new file mode 100644
index 0000000..e6f6b52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0026.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0026.wav
new file mode 100644
index 0000000..22943de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0026.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0026.wavetable
new file mode 100644
index 0000000..c6f81f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0027.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0027.wav
new file mode 100644
index 0000000..1e14ee7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0027.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0027.wavetable
new file mode 100644
index 0000000..9b74038
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0028.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0028.wav
new file mode 100644
index 0000000..024b182
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0028.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0028.wavetable
new file mode 100644
index 0000000..9300b0c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0029.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0029.wav
new file mode 100644
index 0000000..5043344
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0029.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0029.wavetable
new file mode 100644
index 0000000..f8b93d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0030.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0030.wav
new file mode 100644
index 0000000..952944e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0030.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0030.wavetable
new file mode 100644
index 0000000..5488570
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0031.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0031.wav
new file mode 100644
index 0000000..16245b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0031.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0031.wavetable
new file mode 100644
index 0000000..1f1be62
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0032.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0032.wav
new file mode 100644
index 0000000..2d538fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0032.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0032.wavetable
new file mode 100644
index 0000000..658e741
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0033.wav b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0033.wav
new file mode 100644
index 0000000..8dbd100
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0033.wavetable b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0033.wavetable
new file mode 100644
index 0000000..8073b44
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_clavinet/AKWF_clavinet_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_clavinet/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_clavinet/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_clavinet/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0001.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0001.wav
new file mode 100644
index 0000000..98a4b13
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0001.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0001.wavetable
new file mode 100644
index 0000000..ce1ef1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0002.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0002.wav
new file mode 100644
index 0000000..42ab4db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0002.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0002.wavetable
new file mode 100644
index 0000000..f4238cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0003.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0003.wav
new file mode 100644
index 0000000..f4e4a88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0003.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0003.wavetable
new file mode 100644
index 0000000..741bc1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0004.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0004.wav
new file mode 100644
index 0000000..010a326
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0004.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0004.wavetable
new file mode 100644
index 0000000..f631046
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0005.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0005.wav
new file mode 100644
index 0000000..9f17641
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0005.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0005.wavetable
new file mode 100644
index 0000000..dfdc99d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0006.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0006.wav
new file mode 100644
index 0000000..1e227fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0006.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0006.wavetable
new file mode 100644
index 0000000..04e05c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0007.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0007.wav
new file mode 100644
index 0000000..4117b1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0007.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0007.wavetable
new file mode 100644
index 0000000..2df8b4e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0008.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0008.wav
new file mode 100644
index 0000000..e612162
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0008.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0008.wavetable
new file mode 100644
index 0000000..8e2d815
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0009.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0009.wav
new file mode 100644
index 0000000..7c17444
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0009.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0009.wavetable
new file mode 100644
index 0000000..d4296a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0010.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0010.wav
new file mode 100644
index 0000000..3e36934
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0010.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0010.wavetable
new file mode 100644
index 0000000..1855aa0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0011.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0011.wav
new file mode 100644
index 0000000..75c872f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0011.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0011.wavetable
new file mode 100644
index 0000000..0b992e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0012.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0012.wav
new file mode 100644
index 0000000..1042f8f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0012.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0012.wavetable
new file mode 100644
index 0000000..0f546a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0013.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0013.wav
new file mode 100644
index 0000000..cf4f494
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0013.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0013.wavetable
new file mode 100644
index 0000000..b4e77bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0014.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0014.wav
new file mode 100644
index 0000000..f7dd4e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0014.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0014.wavetable
new file mode 100644
index 0000000..8eb27bd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0015.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0015.wav
new file mode 100644
index 0000000..f6269ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0015.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0015.wavetable
new file mode 100644
index 0000000..f0c0743
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0016.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0016.wav
new file mode 100644
index 0000000..c9835dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0016.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0016.wavetable
new file mode 100644
index 0000000..33a0903
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0017.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0017.wav
new file mode 100644
index 0000000..fd24cfa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0017.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0017.wavetable
new file mode 100644
index 0000000..9c576e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0018.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0018.wav
new file mode 100644
index 0000000..2a21cf2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0018.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0018.wavetable
new file mode 100644
index 0000000..14031a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0019.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0019.wav
new file mode 100644
index 0000000..c92cf2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0019.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0019.wavetable
new file mode 100644
index 0000000..cb1bc41
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0020.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0020.wav
new file mode 100644
index 0000000..510e60a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0020.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0020.wavetable
new file mode 100644
index 0000000..3fa7384
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0021.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0021.wav
new file mode 100644
index 0000000..527f7d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0021.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0021.wavetable
new file mode 100644
index 0000000..3ad33cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0022.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0022.wav
new file mode 100644
index 0000000..53ace9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0022.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0022.wavetable
new file mode 100644
index 0000000..3c44aad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0023.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0023.wav
new file mode 100644
index 0000000..46e4e60
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0023.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0023.wavetable
new file mode 100644
index 0000000..f1bb510
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0024.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0024.wav
new file mode 100644
index 0000000..c463398
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0024.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0024.wavetable
new file mode 100644
index 0000000..b1b6d1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0025.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0025.wav
new file mode 100644
index 0000000..738b9d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0025.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0025.wavetable
new file mode 100644
index 0000000..643baf4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0026.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0026.wav
new file mode 100644
index 0000000..d2f6fd0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0026.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0026.wavetable
new file mode 100644
index 0000000..8bea696
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0027.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0027.wav
new file mode 100644
index 0000000..641c43c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0027.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0027.wavetable
new file mode 100644
index 0000000..d978acd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0028.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0028.wav
new file mode 100644
index 0000000..91e527e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0028.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0028.wavetable
new file mode 100644
index 0000000..1b20433
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0029.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0029.wav
new file mode 100644
index 0000000..b0a9fac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0029.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0029.wavetable
new file mode 100644
index 0000000..4ff275d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0030.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0030.wav
new file mode 100644
index 0000000..4f4cdfc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0030.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0030.wavetable
new file mode 100644
index 0000000..1fbb861
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0031.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0031.wav
new file mode 100644
index 0000000..0e583fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0031.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0031.wavetable
new file mode 100644
index 0000000..ee91093
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0032.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0032.wav
new file mode 100644
index 0000000..97bfe90
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0032.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0032.wavetable
new file mode 100644
index 0000000..7deaa21
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0033.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0033.wav
new file mode 100644
index 0000000..4668203
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0033.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0033.wavetable
new file mode 100644
index 0000000..c5cc72c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0034.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0034.wav
new file mode 100644
index 0000000..ae5567e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0034.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0034.wavetable
new file mode 100644
index 0000000..d683009
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0035.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0035.wav
new file mode 100644
index 0000000..7325c9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0035.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0035.wavetable
new file mode 100644
index 0000000..3667b66
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0036.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0036.wav
new file mode 100644
index 0000000..6a212ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0036.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0036.wavetable
new file mode 100644
index 0000000..1d27151
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0037.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0037.wav
new file mode 100644
index 0000000..6985a9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0037.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0037.wavetable
new file mode 100644
index 0000000..ecb5927
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0038.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0038.wav
new file mode 100644
index 0000000..4d3769e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0038.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0038.wavetable
new file mode 100644
index 0000000..397c3ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0039.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0039.wav
new file mode 100644
index 0000000..33bd097
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0039.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0039.wavetable
new file mode 100644
index 0000000..b188bb2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0040.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0040.wav
new file mode 100644
index 0000000..d0eb2e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0040.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0040.wavetable
new file mode 100644
index 0000000..62dd20b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0041.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0041.wav
new file mode 100644
index 0000000..d07965c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0041.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0041.wavetable
new file mode 100644
index 0000000..3daca24
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0042.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0042.wav
new file mode 100644
index 0000000..73728b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0042.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0042.wavetable
new file mode 100644
index 0000000..533e6a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0043.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0043.wav
new file mode 100644
index 0000000..73eb191
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0043.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0043.wavetable
new file mode 100644
index 0000000..3b5ac8a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0044.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0044.wav
new file mode 100644
index 0000000..702a649
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0044.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0044.wavetable
new file mode 100644
index 0000000..c2ccae1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0045.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0045.wav
new file mode 100644
index 0000000..c8a9669
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0045.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0045.wavetable
new file mode 100644
index 0000000..4969ccc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0046.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0046.wav
new file mode 100644
index 0000000..8f93ae2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0046.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0046.wavetable
new file mode 100644
index 0000000..df61481
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0047.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0047.wav
new file mode 100644
index 0000000..012f0f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0047.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0047.wavetable
new file mode 100644
index 0000000..662ec82
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0048.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0048.wav
new file mode 100644
index 0000000..6e344ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0048.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0048.wavetable
new file mode 100644
index 0000000..47e2d52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0049.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0049.wav
new file mode 100644
index 0000000..51638b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0049.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0049.wavetable
new file mode 100644
index 0000000..663ee44
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0050.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0050.wav
new file mode 100644
index 0000000..cea1312
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0050.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0050.wavetable
new file mode 100644
index 0000000..d6b0b86
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0051.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0051.wav
new file mode 100644
index 0000000..fe92a1e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0051.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0051.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0051.wavetable
new file mode 100644
index 0000000..7a30337
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0051.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0052.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0052.wav
new file mode 100644
index 0000000..cf70b4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0052.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0052.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0052.wavetable
new file mode 100644
index 0000000..28b98fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0052.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0053.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0053.wav
new file mode 100644
index 0000000..6131693
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0053.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0053.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0053.wavetable
new file mode 100644
index 0000000..eb95818
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0053.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0054.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0054.wav
new file mode 100644
index 0000000..9b64357
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0054.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0054.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0054.wavetable
new file mode 100644
index 0000000..8b16dae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0054.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0055.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0055.wav
new file mode 100644
index 0000000..493cf6f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0055.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0055.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0055.wavetable
new file mode 100644
index 0000000..3784db6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0055.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0056.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0056.wav
new file mode 100644
index 0000000..ee06b01
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0056.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0056.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0056.wavetable
new file mode 100644
index 0000000..3ede89b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0056.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0057.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0057.wav
new file mode 100644
index 0000000..1343111
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0057.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0057.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0057.wavetable
new file mode 100644
index 0000000..8194589
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0057.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0058.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0058.wav
new file mode 100644
index 0000000..9ba63cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0058.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0058.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0058.wavetable
new file mode 100644
index 0000000..ed39755
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0058.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0059.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0059.wav
new file mode 100644
index 0000000..b4cd3be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0059.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0059.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0059.wavetable
new file mode 100644
index 0000000..e36b519
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0059.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0060.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0060.wav
new file mode 100644
index 0000000..555c0f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0060.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0060.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0060.wavetable
new file mode 100644
index 0000000..5274bcf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0060.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0061.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0061.wav
new file mode 100644
index 0000000..6a9fee6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0061.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0061.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0061.wavetable
new file mode 100644
index 0000000..392b211
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0061.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0062.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0062.wav
new file mode 100644
index 0000000..d86b858
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0062.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0062.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0062.wavetable
new file mode 100644
index 0000000..44c6353
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0062.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0063.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0063.wav
new file mode 100644
index 0000000..964a101
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0063.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0063.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0063.wavetable
new file mode 100644
index 0000000..775a438
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0063.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0064.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0064.wav
new file mode 100644
index 0000000..4e30bf0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0064.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0064.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0064.wavetable
new file mode 100644
index 0000000..335684f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0064.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0065.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0065.wav
new file mode 100644
index 0000000..5313c9c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0065.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0065.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0065.wavetable
new file mode 100644
index 0000000..2a0cd9f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0065.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0066.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0066.wav
new file mode 100644
index 0000000..c3a9759
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0066.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0066.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0066.wavetable
new file mode 100644
index 0000000..aa9769d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0066.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0067.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0067.wav
new file mode 100644
index 0000000..7bb8d3f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0067.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0067.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0067.wavetable
new file mode 100644
index 0000000..55f6e10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0067.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0068.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0068.wav
new file mode 100644
index 0000000..7afd241
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0068.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0068.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0068.wavetable
new file mode 100644
index 0000000..f9bc3c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0068.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0069.wav b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0069.wav
new file mode 100644
index 0000000..2e0c0ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0069.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0069.wavetable b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0069.wavetable
new file mode 100644
index 0000000..8920b31
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_dbass/AKWF_dbass_0069.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_dbass/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_dbass/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_dbass/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0001.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0001.wav
new file mode 100644
index 0000000..a5c5282
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0001.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0001.wavetable
new file mode 100644
index 0000000..4fb7b3a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0002.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0002.wav
new file mode 100644
index 0000000..5a61d75
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0002.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0002.wavetable
new file mode 100644
index 0000000..c2e979c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0003.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0003.wav
new file mode 100644
index 0000000..1e20b01
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0003.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0003.wavetable
new file mode 100644
index 0000000..9a45787
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0004.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0004.wav
new file mode 100644
index 0000000..c8be808
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0004.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0004.wavetable
new file mode 100644
index 0000000..a7c0f26
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0005.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0005.wav
new file mode 100644
index 0000000..0c8b2fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0005.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0005.wavetable
new file mode 100644
index 0000000..b8e1e5d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0006.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0006.wav
new file mode 100644
index 0000000..0df8234
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0006.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0006.wavetable
new file mode 100644
index 0000000..aa13843
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0007.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0007.wav
new file mode 100644
index 0000000..3663f5e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0007.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0007.wavetable
new file mode 100644
index 0000000..3dfbef4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0008.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0008.wav
new file mode 100644
index 0000000..b8f7054
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0008.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0008.wavetable
new file mode 100644
index 0000000..49d5118
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0009.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0009.wav
new file mode 100644
index 0000000..5c098a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0009.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0009.wavetable
new file mode 100644
index 0000000..d71b3cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0010.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0010.wav
new file mode 100644
index 0000000..da859cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0010.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0010.wavetable
new file mode 100644
index 0000000..183bf34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0011.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0011.wav
new file mode 100644
index 0000000..e7307c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0011.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0011.wavetable
new file mode 100644
index 0000000..124ec9c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0012.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0012.wav
new file mode 100644
index 0000000..18ee41b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0012.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0012.wavetable
new file mode 100644
index 0000000..0dfbb97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0013.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0013.wav
new file mode 100644
index 0000000..aa30ed2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0013.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0013.wavetable
new file mode 100644
index 0000000..95d8eea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0014.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0014.wav
new file mode 100644
index 0000000..d1216b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0014.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0014.wavetable
new file mode 100644
index 0000000..0026514
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0015.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0015.wav
new file mode 100644
index 0000000..ab31588
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0015.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0015.wavetable
new file mode 100644
index 0000000..ded0252
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0016.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0016.wav
new file mode 100644
index 0000000..319a945
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0016.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0016.wavetable
new file mode 100644
index 0000000..7685b8d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0017.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0017.wav
new file mode 100644
index 0000000..051fae5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0017.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0017.wavetable
new file mode 100644
index 0000000..0235363
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0018.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0018.wav
new file mode 100644
index 0000000..9318679
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0018.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0018.wavetable
new file mode 100644
index 0000000..199949f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0019.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0019.wav
new file mode 100644
index 0000000..99a5bb6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0019.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0019.wavetable
new file mode 100644
index 0000000..3109913
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0020.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0020.wav
new file mode 100644
index 0000000..7c0c63d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0020.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0020.wavetable
new file mode 100644
index 0000000..a70a7b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0021.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0021.wav
new file mode 100644
index 0000000..4212e30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0021.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0021.wavetable
new file mode 100644
index 0000000..9475ef5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0022.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0022.wav
new file mode 100644
index 0000000..3f8c64f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0022.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0022.wavetable
new file mode 100644
index 0000000..0f17901
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0023.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0023.wav
new file mode 100644
index 0000000..26dc8dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0023.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0023.wavetable
new file mode 100644
index 0000000..bf15155
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0024.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0024.wav
new file mode 100644
index 0000000..e0ebfad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0024.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0024.wavetable
new file mode 100644
index 0000000..2b86334
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0025.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0025.wav
new file mode 100644
index 0000000..0e0a73e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0025.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0025.wavetable
new file mode 100644
index 0000000..5599cbf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0026.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0026.wav
new file mode 100644
index 0000000..cc927f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0026.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0026.wavetable
new file mode 100644
index 0000000..145d477
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0027.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0027.wav
new file mode 100644
index 0000000..122b6c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0027.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0027.wavetable
new file mode 100644
index 0000000..9583e71
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0028.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0028.wav
new file mode 100644
index 0000000..33ac409
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0028.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0028.wavetable
new file mode 100644
index 0000000..625a80f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0029.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0029.wav
new file mode 100644
index 0000000..1aadcc9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0029.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0029.wavetable
new file mode 100644
index 0000000..7302473
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0030.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0030.wav
new file mode 100644
index 0000000..f5392b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0030.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0030.wavetable
new file mode 100644
index 0000000..852f2e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0031.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0031.wav
new file mode 100644
index 0000000..143dae2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0031.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0031.wavetable
new file mode 100644
index 0000000..e50816b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0032.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0032.wav
new file mode 100644
index 0000000..7c736d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0032.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0032.wavetable
new file mode 100644
index 0000000..408eb02
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0033.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0033.wav
new file mode 100644
index 0000000..345f04e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0033.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0033.wavetable
new file mode 100644
index 0000000..dc47c9b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0034.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0034.wav
new file mode 100644
index 0000000..59a5005
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0034.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0034.wavetable
new file mode 100644
index 0000000..ffed796
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0035.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0035.wav
new file mode 100644
index 0000000..3bc10fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0035.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0035.wavetable
new file mode 100644
index 0000000..2d6c6c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0036.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0036.wav
new file mode 100644
index 0000000..e7d3863
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0036.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0036.wavetable
new file mode 100644
index 0000000..8110c92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0037.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0037.wav
new file mode 100644
index 0000000..29026e3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0037.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0037.wavetable
new file mode 100644
index 0000000..3c23c0f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0038.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0038.wav
new file mode 100644
index 0000000..306bc9f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0038.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0038.wavetable
new file mode 100644
index 0000000..61f2884
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0039.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0039.wav
new file mode 100644
index 0000000..8fae2ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0039.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0039.wavetable
new file mode 100644
index 0000000..c166910
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0040.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0040.wav
new file mode 100644
index 0000000..f3ca0cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0040.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0040.wavetable
new file mode 100644
index 0000000..317ef10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0041.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0041.wav
new file mode 100644
index 0000000..96b191a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0041.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0041.wavetable
new file mode 100644
index 0000000..7dab7ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0042.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0042.wav
new file mode 100644
index 0000000..e5d4254
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0042.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0042.wavetable
new file mode 100644
index 0000000..962b735
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0043.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0043.wav
new file mode 100644
index 0000000..293c72f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0043.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0043.wavetable
new file mode 100644
index 0000000..422a215
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0044.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0044.wav
new file mode 100644
index 0000000..28980f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0044.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0044.wavetable
new file mode 100644
index 0000000..610cd66
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0045.wav b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0045.wav
new file mode 100644
index 0000000..a6413d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0045.wavetable b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0045.wavetable
new file mode 100644
index 0000000..8d777d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_distorted/AKWF_distorted_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_distorted/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_distorted/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_distorted/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0001.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0001.wav
new file mode 100644
index 0000000..2fbafb7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0001.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0001.wavetable
new file mode 100644
index 0000000..92e69dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0002.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0002.wav
new file mode 100644
index 0000000..681a916
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0002.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0002.wavetable
new file mode 100644
index 0000000..253ecbf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0003.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0003.wav
new file mode 100644
index 0000000..d0493e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0003.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0003.wavetable
new file mode 100644
index 0000000..1993e19
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0004.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0004.wav
new file mode 100644
index 0000000..4e7cc69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0004.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0004.wavetable
new file mode 100644
index 0000000..a166e12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0005.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0005.wav
new file mode 100644
index 0000000..3bce535
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0005.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0005.wavetable
new file mode 100644
index 0000000..ec9fc76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0006.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0006.wav
new file mode 100644
index 0000000..285d171
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0006.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0006.wavetable
new file mode 100644
index 0000000..29eb2ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0007.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0007.wav
new file mode 100644
index 0000000..8fcf3fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0007.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0007.wavetable
new file mode 100644
index 0000000..b6d2c1f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0008.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0008.wav
new file mode 100644
index 0000000..7f21c37
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0008.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0008.wavetable
new file mode 100644
index 0000000..57c3aec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0009.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0009.wav
new file mode 100644
index 0000000..5911309
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0009.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0009.wavetable
new file mode 100644
index 0000000..034ff70
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0010.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0010.wav
new file mode 100644
index 0000000..1ce83e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0010.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0010.wavetable
new file mode 100644
index 0000000..2913739
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0011.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0011.wav
new file mode 100644
index 0000000..cac9268
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0011.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0011.wavetable
new file mode 100644
index 0000000..65eb74d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0012.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0012.wav
new file mode 100644
index 0000000..16600c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0012.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0012.wavetable
new file mode 100644
index 0000000..9a0006b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0013.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0013.wav
new file mode 100644
index 0000000..e685c5a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0013.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0013.wavetable
new file mode 100644
index 0000000..4dd5609
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0014.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0014.wav
new file mode 100644
index 0000000..bfaa50e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0014.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0014.wavetable
new file mode 100644
index 0000000..123765f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0015.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0015.wav
new file mode 100644
index 0000000..dc35263
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0015.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0015.wavetable
new file mode 100644
index 0000000..031b1a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0016.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0016.wav
new file mode 100644
index 0000000..9c3bbe6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0016.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0016.wavetable
new file mode 100644
index 0000000..b0905a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0017.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0017.wav
new file mode 100644
index 0000000..82cfc04
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0017.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0017.wavetable
new file mode 100644
index 0000000..1c02c3a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0018.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0018.wav
new file mode 100644
index 0000000..d24c8de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0018.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0018.wavetable
new file mode 100644
index 0000000..76b7cb6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0019.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0019.wav
new file mode 100644
index 0000000..d930774
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0019.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0019.wavetable
new file mode 100644
index 0000000..0c31e3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0020.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0020.wav
new file mode 100644
index 0000000..8fc663e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0020.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0020.wavetable
new file mode 100644
index 0000000..719ba9b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0021.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0021.wav
new file mode 100644
index 0000000..9d4a7e2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0021.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0021.wavetable
new file mode 100644
index 0000000..2b6c0f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0022.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0022.wav
new file mode 100644
index 0000000..26a2d6f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0022.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0022.wavetable
new file mode 100644
index 0000000..535689d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0023.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0023.wav
new file mode 100644
index 0000000..64085aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0023.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0023.wavetable
new file mode 100644
index 0000000..85c692e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0024.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0024.wav
new file mode 100644
index 0000000..8cd8f98
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0024.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0024.wavetable
new file mode 100644
index 0000000..3b0d236
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0025.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0025.wav
new file mode 100644
index 0000000..093a13e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0025.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0025.wavetable
new file mode 100644
index 0000000..d803ff3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0026.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0026.wav
new file mode 100644
index 0000000..9d6f783
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0026.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0026.wavetable
new file mode 100644
index 0000000..1eec5be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0027.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0027.wav
new file mode 100644
index 0000000..4960da3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0027.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0027.wavetable
new file mode 100644
index 0000000..70b3941
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0028.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0028.wav
new file mode 100644
index 0000000..0fa5377
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0028.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0028.wavetable
new file mode 100644
index 0000000..d87827a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0029.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0029.wav
new file mode 100644
index 0000000..c8c2881
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0029.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0029.wavetable
new file mode 100644
index 0000000..2b3a33b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0030.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0030.wav
new file mode 100644
index 0000000..5e18028
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0030.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0030.wavetable
new file mode 100644
index 0000000..911f660
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0031.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0031.wav
new file mode 100644
index 0000000..3064f05
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0031.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0031.wavetable
new file mode 100644
index 0000000..843a28e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0032.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0032.wav
new file mode 100644
index 0000000..d98077a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0032.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0032.wavetable
new file mode 100644
index 0000000..4aaaee6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0033.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0033.wav
new file mode 100644
index 0000000..a650805
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0033.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0033.wavetable
new file mode 100644
index 0000000..d1d3560
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0034.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0034.wav
new file mode 100644
index 0000000..01a9cbc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0034.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0034.wavetable
new file mode 100644
index 0000000..65d6b7c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0035.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0035.wav
new file mode 100644
index 0000000..75b63f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0035.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0035.wavetable
new file mode 100644
index 0000000..960fc83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0036.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0036.wav
new file mode 100644
index 0000000..99b2c08
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0036.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0036.wavetable
new file mode 100644
index 0000000..e453abc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0037.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0037.wav
new file mode 100644
index 0000000..8a15555
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0037.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0037.wavetable
new file mode 100644
index 0000000..4641a42
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0038.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0038.wav
new file mode 100644
index 0000000..50c4682
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0038.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0038.wavetable
new file mode 100644
index 0000000..e377ede
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0039.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0039.wav
new file mode 100644
index 0000000..fdfbce4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0039.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0039.wavetable
new file mode 100644
index 0000000..36542cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0040.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0040.wav
new file mode 100644
index 0000000..29dd5a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0040.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0040.wavetable
new file mode 100644
index 0000000..fa1bcc9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0041.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0041.wav
new file mode 100644
index 0000000..5035c49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0041.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0041.wavetable
new file mode 100644
index 0000000..d66cb27
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0042.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0042.wav
new file mode 100644
index 0000000..410c960
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0042.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0042.wavetable
new file mode 100644
index 0000000..50e1186
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0043.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0043.wav
new file mode 100644
index 0000000..6f8345d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0043.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0043.wavetable
new file mode 100644
index 0000000..5289441
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0044.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0044.wav
new file mode 100644
index 0000000..c35b653
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0044.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0044.wavetable
new file mode 100644
index 0000000..8792619
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0045.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0045.wav
new file mode 100644
index 0000000..5577fe0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0045.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0045.wavetable
new file mode 100644
index 0000000..bea9dd6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0046.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0046.wav
new file mode 100644
index 0000000..72998c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0046.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0046.wavetable
new file mode 100644
index 0000000..99381f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0047.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0047.wav
new file mode 100644
index 0000000..8651315
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0047.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0047.wavetable
new file mode 100644
index 0000000..d56b565
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0048.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0048.wav
new file mode 100644
index 0000000..022d310
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0048.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0048.wavetable
new file mode 100644
index 0000000..78b34fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0049.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0049.wav
new file mode 100644
index 0000000..0517e29
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0049.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0049.wavetable
new file mode 100644
index 0000000..a590a40
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0050.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0050.wav
new file mode 100644
index 0000000..b8d84d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0050.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0050.wavetable
new file mode 100644
index 0000000..9a76d86
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0051.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0051.wav
new file mode 100644
index 0000000..73f38aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0051.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0051.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0051.wavetable
new file mode 100644
index 0000000..2357fce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0051.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0052.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0052.wav
new file mode 100644
index 0000000..5ad4bed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0052.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0052.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0052.wavetable
new file mode 100644
index 0000000..a20adca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0052.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0053.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0053.wav
new file mode 100644
index 0000000..1747380
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0053.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0053.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0053.wavetable
new file mode 100644
index 0000000..7da4046
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0053.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0054.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0054.wav
new file mode 100644
index 0000000..b21c13f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0054.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0054.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0054.wavetable
new file mode 100644
index 0000000..33bd4f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0054.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0055.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0055.wav
new file mode 100644
index 0000000..0725762
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0055.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0055.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0055.wavetable
new file mode 100644
index 0000000..c18ee74
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0055.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0056.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0056.wav
new file mode 100644
index 0000000..698dd88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0056.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0056.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0056.wavetable
new file mode 100644
index 0000000..92d2871
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0056.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0057.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0057.wav
new file mode 100644
index 0000000..c88b0a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0057.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0057.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0057.wavetable
new file mode 100644
index 0000000..f2d360b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0057.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0058.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0058.wav
new file mode 100644
index 0000000..36618fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0058.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0058.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0058.wavetable
new file mode 100644
index 0000000..39f205e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0058.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0059.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0059.wav
new file mode 100644
index 0000000..658e500
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0059.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0059.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0059.wavetable
new file mode 100644
index 0000000..e288b48
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0059.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0060.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0060.wav
new file mode 100644
index 0000000..d98dc64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0060.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0060.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0060.wavetable
new file mode 100644
index 0000000..22b1f18
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0060.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0061.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0061.wav
new file mode 100644
index 0000000..8cb2b8a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0061.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0061.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0061.wavetable
new file mode 100644
index 0000000..7a32d8b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0061.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0062.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0062.wav
new file mode 100644
index 0000000..ddc602b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0062.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0062.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0062.wavetable
new file mode 100644
index 0000000..705dba4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0062.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0063.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0063.wav
new file mode 100644
index 0000000..befc616
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0063.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0063.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0063.wavetable
new file mode 100644
index 0000000..dc46d9b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0063.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0064.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0064.wav
new file mode 100644
index 0000000..dc03aa4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0064.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0064.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0064.wavetable
new file mode 100644
index 0000000..531b5e2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0064.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0065.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0065.wav
new file mode 100644
index 0000000..66eb990
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0065.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0065.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0065.wavetable
new file mode 100644
index 0000000..f7c9b19
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0065.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0066.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0066.wav
new file mode 100644
index 0000000..49a361c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0066.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0066.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0066.wavetable
new file mode 100644
index 0000000..5802085
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0066.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0067.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0067.wav
new file mode 100644
index 0000000..b0f0244
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0067.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0067.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0067.wavetable
new file mode 100644
index 0000000..c846a5d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0067.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0068.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0068.wav
new file mode 100644
index 0000000..af35bcb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0068.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0068.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0068.wavetable
new file mode 100644
index 0000000..576bd96
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0068.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0069.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0069.wav
new file mode 100644
index 0000000..4716e8f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0069.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0069.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0069.wavetable
new file mode 100644
index 0000000..c0775eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0069.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0070.wav b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0070.wav
new file mode 100644
index 0000000..e873a18
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0070.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0070.wavetable b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0070.wavetable
new file mode 100644
index 0000000..145d824
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_ebass/AKWF_ebass_0070.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_ebass/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_ebass/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_ebass/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0001.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0001.wav
new file mode 100644
index 0000000..5c86b70
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0001.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0001.wavetable
new file mode 100644
index 0000000..c894e22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0002.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0002.wav
new file mode 100644
index 0000000..2d10307
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0002.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0002.wavetable
new file mode 100644
index 0000000..20db93c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0003.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0003.wav
new file mode 100644
index 0000000..57b8af4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0003.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0003.wavetable
new file mode 100644
index 0000000..5a8b0c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0004.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0004.wav
new file mode 100644
index 0000000..acbb63d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0004.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0004.wavetable
new file mode 100644
index 0000000..ad1a3da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0005.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0005.wav
new file mode 100644
index 0000000..01f6d08
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0005.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0005.wavetable
new file mode 100644
index 0000000..300096b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0006.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0006.wav
new file mode 100644
index 0000000..7a036f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0006.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0006.wavetable
new file mode 100644
index 0000000..c2e5c3f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0007.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0007.wav
new file mode 100644
index 0000000..6a5d87d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0007.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0007.wavetable
new file mode 100644
index 0000000..8f302f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0008.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0008.wav
new file mode 100644
index 0000000..d94a001
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0008.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0008.wavetable
new file mode 100644
index 0000000..89ad7ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0009.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0009.wav
new file mode 100644
index 0000000..64dbba4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0009.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0009.wavetable
new file mode 100644
index 0000000..fdec4d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0010.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0010.wav
new file mode 100644
index 0000000..f8845a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0010.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0010.wavetable
new file mode 100644
index 0000000..e6835da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0011.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0011.wav
new file mode 100644
index 0000000..5805075
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0011.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0011.wavetable
new file mode 100644
index 0000000..3667403
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0012.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0012.wav
new file mode 100644
index 0000000..fc9bfe5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0012.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0012.wavetable
new file mode 100644
index 0000000..831f006
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0013.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0013.wav
new file mode 100644
index 0000000..19a6662
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0013.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0013.wavetable
new file mode 100644
index 0000000..9c8fb26
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0014.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0014.wav
new file mode 100644
index 0000000..29d2033
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0014.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0014.wavetable
new file mode 100644
index 0000000..964cb26
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0015.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0015.wav
new file mode 100644
index 0000000..5e17c85
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0015.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0015.wavetable
new file mode 100644
index 0000000..0066946
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0016.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0016.wav
new file mode 100644
index 0000000..011247b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0016.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0016.wavetable
new file mode 100644
index 0000000..32cf8b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0017.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0017.wav
new file mode 100644
index 0000000..fd874d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0017.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0017.wavetable
new file mode 100644
index 0000000..2ffd1a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0018.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0018.wav
new file mode 100644
index 0000000..95bb358
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0018.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0018.wavetable
new file mode 100644
index 0000000..c07d338
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0019.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0019.wav
new file mode 100644
index 0000000..d7a6c15
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0019.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0019.wavetable
new file mode 100644
index 0000000..d1a4f93
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0020.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0020.wav
new file mode 100644
index 0000000..edee51c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0020.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0020.wavetable
new file mode 100644
index 0000000..0396e28
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0021.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0021.wav
new file mode 100644
index 0000000..c74beea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0021.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0021.wavetable
new file mode 100644
index 0000000..ed0ea2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0022.wav b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0022.wav
new file mode 100644
index 0000000..caeb20f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0022.wavetable b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0022.wavetable
new file mode 100644
index 0000000..93aeec3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eguitar/AKWF_eguitar_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eguitar/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_eguitar/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_eguitar/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0001.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0001.wav
new file mode 100644
index 0000000..1b80e8e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0001.wav.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0001.wav.wavetable
new file mode 100644
index 0000000..7505371
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0001.wav.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0002.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0002.wav
new file mode 100644
index 0000000..f3d2c62
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0002.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0002.wavetable
new file mode 100644
index 0000000..1310d8d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0003.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0003.wav
new file mode 100644
index 0000000..5decaa3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0003.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0003.wavetable
new file mode 100644
index 0000000..9faf2b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0004.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0004.wav
new file mode 100644
index 0000000..edad2e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0004.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0004.wavetable
new file mode 100644
index 0000000..b5cc9f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0005.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0005.wav
new file mode 100644
index 0000000..6085dd2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0005.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0005.wavetable
new file mode 100644
index 0000000..f199fb0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0006.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0006.wav
new file mode 100644
index 0000000..920bbec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0006.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0006.wavetable
new file mode 100644
index 0000000..466b1a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0007.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0007.wav
new file mode 100644
index 0000000..61fc9d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0007.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0007.wavetable
new file mode 100644
index 0000000..defaa55
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0008.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0008.wav
new file mode 100644
index 0000000..9e1240f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0008.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0008.wavetable
new file mode 100644
index 0000000..80e78ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0009.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0009.wav
new file mode 100644
index 0000000..c67b555
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0009.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0009.wavetable
new file mode 100644
index 0000000..7328561
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0010.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0010.wav
new file mode 100644
index 0000000..4346427
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0010.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0010.wavetable
new file mode 100644
index 0000000..f129456
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0011.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0011.wav
new file mode 100644
index 0000000..40bde35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0011.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0011.wavetable
new file mode 100644
index 0000000..b4daab0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0012.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0012.wav
new file mode 100644
index 0000000..dc2d5fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0012.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0012.wavetable
new file mode 100644
index 0000000..3d59864
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0013.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0013.wav
new file mode 100644
index 0000000..a635f50
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0013.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0013.wavetable
new file mode 100644
index 0000000..b8efef1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0014.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0014.wav
new file mode 100644
index 0000000..d614516
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0014.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0014.wavetable
new file mode 100644
index 0000000..dd8d660
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0015.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0015.wav
new file mode 100644
index 0000000..21e5449
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0015.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0015.wavetable
new file mode 100644
index 0000000..3381cb0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0016.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0016.wav
new file mode 100644
index 0000000..5ae572b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0016.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0016.wavetable
new file mode 100644
index 0000000..30f02f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0017.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0017.wav
new file mode 100644
index 0000000..6ba589e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0017.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0017.wavetable
new file mode 100644
index 0000000..645761a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0018.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0018.wav
new file mode 100644
index 0000000..1c1aed6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0018.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0018.wavetable
new file mode 100644
index 0000000..98272ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0019.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0019.wav
new file mode 100644
index 0000000..3060a2c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0019.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0019.wavetable
new file mode 100644
index 0000000..ddcaee0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0020.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0020.wav
new file mode 100644
index 0000000..cf75614
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0020.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0020.wavetable
new file mode 100644
index 0000000..93d50ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0021.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0021.wav
new file mode 100644
index 0000000..62c4da0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0021.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0021.wavetable
new file mode 100644
index 0000000..0ce9ac1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0022.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0022.wav
new file mode 100644
index 0000000..b3da824
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0022.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0022.wavetable
new file mode 100644
index 0000000..8795408
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0023.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0023.wav
new file mode 100644
index 0000000..fe0a99f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0023.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0023.wavetable
new file mode 100644
index 0000000..5fd0e6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0024.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0024.wav
new file mode 100644
index 0000000..3ea5d2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0024.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0024.wavetable
new file mode 100644
index 0000000..30e19c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0025.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0025.wav
new file mode 100644
index 0000000..eebf782
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0025.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0025.wavetable
new file mode 100644
index 0000000..0116cb9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0026.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0026.wav
new file mode 100644
index 0000000..9689314
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0026.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0026.wavetable
new file mode 100644
index 0000000..1dcf05f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0027.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0027.wav
new file mode 100644
index 0000000..bb3680b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0027.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0027.wavetable
new file mode 100644
index 0000000..2dd7e8b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0028.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0028.wav
new file mode 100644
index 0000000..3121099
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0028.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0028.wavetable
new file mode 100644
index 0000000..aec69c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0029.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0029.wav
new file mode 100644
index 0000000..733ac96
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0029.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0029.wavetable
new file mode 100644
index 0000000..296f2ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0030.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0030.wav
new file mode 100644
index 0000000..b7a2516
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0030.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0030.wavetable
new file mode 100644
index 0000000..882401c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0031.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0031.wav
new file mode 100644
index 0000000..57deada
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0031.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0031.wavetable
new file mode 100644
index 0000000..38e63ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0032.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0032.wav
new file mode 100644
index 0000000..f06470e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0032.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0032.wavetable
new file mode 100644
index 0000000..cd804d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0033.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0033.wav
new file mode 100644
index 0000000..4b31033
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0033.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0033.wavetable
new file mode 100644
index 0000000..f8d1a77
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0034.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0034.wav
new file mode 100644
index 0000000..5f9dc07
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0034.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0034.wavetable
new file mode 100644
index 0000000..fe6153d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0035.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0035.wav
new file mode 100644
index 0000000..da997db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0035.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0035.wavetable
new file mode 100644
index 0000000..494f657
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0036.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0036.wav
new file mode 100644
index 0000000..c53fe69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0036.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0036.wavetable
new file mode 100644
index 0000000..ba5a981
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0037.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0037.wav
new file mode 100644
index 0000000..ba2dcdb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0037.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0037.wavetable
new file mode 100644
index 0000000..e9f7e4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0038.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0038.wav
new file mode 100644
index 0000000..564d709
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0038.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0038.wavetable
new file mode 100644
index 0000000..3663354
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0039.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0039.wav
new file mode 100644
index 0000000..0ada75e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0039.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0039.wavetable
new file mode 100644
index 0000000..cc40af7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0040.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0040.wav
new file mode 100644
index 0000000..f84e129
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0040.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0040.wavetable
new file mode 100644
index 0000000..7c2a6ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0041.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0041.wav
new file mode 100644
index 0000000..431fbf7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0041.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0041.wavetable
new file mode 100644
index 0000000..487f364
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0042.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0042.wav
new file mode 100644
index 0000000..d28f8d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0042.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0042.wavetable
new file mode 100644
index 0000000..37ea0d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0043.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0043.wav
new file mode 100644
index 0000000..5187d0f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0043.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0043.wavetable
new file mode 100644
index 0000000..2a83070
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0044.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0044.wav
new file mode 100644
index 0000000..9a5cf93
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0044.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0044.wavetable
new file mode 100644
index 0000000..0862a4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0045.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0045.wav
new file mode 100644
index 0000000..d9b692a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0045.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0045.wavetable
new file mode 100644
index 0000000..a17f72b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0046.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0046.wav
new file mode 100644
index 0000000..944ba79
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0046.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0046.wavetable
new file mode 100644
index 0000000..dd0f866
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0047.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0047.wav
new file mode 100644
index 0000000..b45c81a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0047.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0047.wavetable
new file mode 100644
index 0000000..dd9b906
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0048.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0048.wav
new file mode 100644
index 0000000..e49d0b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0048.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0048.wavetable
new file mode 100644
index 0000000..203c564
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0049.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0049.wav
new file mode 100644
index 0000000..c296304
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0049.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0049.wavetable
new file mode 100644
index 0000000..f7fad77
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0050.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0050.wav
new file mode 100644
index 0000000..47a096a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0050.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0050.wavetable
new file mode 100644
index 0000000..ac31483
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0051.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0051.wav
new file mode 100644
index 0000000..fd30db5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0051.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0051.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0051.wavetable
new file mode 100644
index 0000000..2226e0f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0051.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0052.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0052.wav
new file mode 100644
index 0000000..1e05f92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0052.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0052.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0052.wavetable
new file mode 100644
index 0000000..7d13f72
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0052.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0053.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0053.wav
new file mode 100644
index 0000000..2d579ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0053.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0053.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0053.wavetable
new file mode 100644
index 0000000..f4476f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0053.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0054.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0054.wav
new file mode 100644
index 0000000..b43bea6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0054.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0054.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0054.wavetable
new file mode 100644
index 0000000..ab88006
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0054.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0055.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0055.wav
new file mode 100644
index 0000000..a774514
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0055.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0055.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0055.wavetable
new file mode 100644
index 0000000..2465096
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0055.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0056.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0056.wav
new file mode 100644
index 0000000..2b21218
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0056.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0056.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0056.wavetable
new file mode 100644
index 0000000..e0895e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0056.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0057.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0057.wav
new file mode 100644
index 0000000..619f692
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0057.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0057.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0057.wavetable
new file mode 100644
index 0000000..309eb16
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0057.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0058.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0058.wav
new file mode 100644
index 0000000..be12219
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0058.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0058.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0058.wavetable
new file mode 100644
index 0000000..e53d9b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0058.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0059.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0059.wav
new file mode 100644
index 0000000..4dfec90
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0059.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0059.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0059.wavetable
new file mode 100644
index 0000000..a660ae8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0059.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0060.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0060.wav
new file mode 100644
index 0000000..ae26e95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0060.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0060.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0060.wavetable
new file mode 100644
index 0000000..42775e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0060.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0061.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0061.wav
new file mode 100644
index 0000000..de95719
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0061.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0061.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0061.wavetable
new file mode 100644
index 0000000..032dab8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0061.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0062.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0062.wav
new file mode 100644
index 0000000..91e7375
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0062.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0062.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0062.wavetable
new file mode 100644
index 0000000..80b2048
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0062.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0063.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0063.wav
new file mode 100644
index 0000000..f450cb2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0063.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0063.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0063.wavetable
new file mode 100644
index 0000000..2a7713c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0063.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0064.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0064.wav
new file mode 100644
index 0000000..4584396
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0064.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0064.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0064.wavetable
new file mode 100644
index 0000000..750607a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0064.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0065.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0065.wav
new file mode 100644
index 0000000..43fd138
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0065.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0065.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0065.wavetable
new file mode 100644
index 0000000..0b7da14
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0065.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0066.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0066.wav
new file mode 100644
index 0000000..de3f43e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0066.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0066.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0066.wavetable
new file mode 100644
index 0000000..30af691
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0066.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0067.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0067.wav
new file mode 100644
index 0000000..01736f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0067.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0067.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0067.wavetable
new file mode 100644
index 0000000..2bd54d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0067.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0068.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0068.wav
new file mode 100644
index 0000000..48ad9a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0068.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0068.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0068.wavetable
new file mode 100644
index 0000000..5f1ba98
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0068.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0069.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0069.wav
new file mode 100644
index 0000000..377e8da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0069.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0069.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0069.wavetable
new file mode 100644
index 0000000..e21e323
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0069.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0070.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0070.wav
new file mode 100644
index 0000000..d356838
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0070.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0070.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0070.wavetable
new file mode 100644
index 0000000..b744e96
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0070.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0071.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0071.wav
new file mode 100644
index 0000000..e3cbfa9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0071.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0071.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0071.wavetable
new file mode 100644
index 0000000..94d258e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0071.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0072.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0072.wav
new file mode 100644
index 0000000..2dfec64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0072.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0072.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0072.wavetable
new file mode 100644
index 0000000..2f15a8f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0072.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0073.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0073.wav
new file mode 100644
index 0000000..94c0373
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0073.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0073.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0073.wavetable
new file mode 100644
index 0000000..642566c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0073.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0074.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0074.wav
new file mode 100644
index 0000000..e99bf8e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0074.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0074.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0074.wavetable
new file mode 100644
index 0000000..b63fd7d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0074.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0075.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0075.wav
new file mode 100644
index 0000000..02f1662
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0075.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0075.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0075.wavetable
new file mode 100644
index 0000000..f006aeb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0075.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0076.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0076.wav
new file mode 100644
index 0000000..543eb87
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0076.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0076.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0076.wavetable
new file mode 100644
index 0000000..c57ca2c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0076.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0077.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0077.wav
new file mode 100644
index 0000000..3be6e75
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0077.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0077.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0077.wavetable
new file mode 100644
index 0000000..351ab9f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0077.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0078.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0078.wav
new file mode 100644
index 0000000..cb882cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0078.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0078.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0078.wavetable
new file mode 100644
index 0000000..f618962
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0078.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0079.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0079.wav
new file mode 100644
index 0000000..6b2b982
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0079.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0079.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0079.wavetable
new file mode 100644
index 0000000..79b0d9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0079.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0080.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0080.wav
new file mode 100644
index 0000000..7ec61ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0080.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0080.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0080.wavetable
new file mode 100644
index 0000000..ec5db87
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0080.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0081.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0081.wav
new file mode 100644
index 0000000..0664a97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0081.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0081.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0081.wavetable
new file mode 100644
index 0000000..8cc55fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0081.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0082.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0082.wav
new file mode 100644
index 0000000..fdef22b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0082.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0082.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0082.wavetable
new file mode 100644
index 0000000..aac4c7a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0082.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0083.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0083.wav
new file mode 100644
index 0000000..e9cbaf7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0083.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0083.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0083.wavetable
new file mode 100644
index 0000000..af00603
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0083.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0084.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0084.wav
new file mode 100644
index 0000000..597ba71
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0084.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0084.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0084.wavetable
new file mode 100644
index 0000000..ea2d5ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0084.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0085.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0085.wav
new file mode 100644
index 0000000..13870cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0085.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0085.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0085.wavetable
new file mode 100644
index 0000000..473ecd6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0085.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0086.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0086.wav
new file mode 100644
index 0000000..2bdc83d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0086.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0086.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0086.wavetable
new file mode 100644
index 0000000..6e7f799
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0086.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0087.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0087.wav
new file mode 100644
index 0000000..5b92f4e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0087.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0087.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0087.wavetable
new file mode 100644
index 0000000..bd06d7d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0087.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0088.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0088.wav
new file mode 100644
index 0000000..4d7e768
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0088.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0088.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0088.wavetable
new file mode 100644
index 0000000..d109425
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0088.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0089.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0089.wav
new file mode 100644
index 0000000..ee7997a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0089.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0089.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0089.wavetable
new file mode 100644
index 0000000..6ed5d61
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0089.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0090.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0090.wav
new file mode 100644
index 0000000..0c91f87
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0090.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0090.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0090.wavetable
new file mode 100644
index 0000000..d4a12c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0090.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0091.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0091.wav
new file mode 100644
index 0000000..566d46e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0091.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0091.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0091.wavetable
new file mode 100644
index 0000000..20648fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0091.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0092.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0092.wav
new file mode 100644
index 0000000..cac76f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0092.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0092.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0092.wavetable
new file mode 100644
index 0000000..0c03d8f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0092.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0093.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0093.wav
new file mode 100644
index 0000000..cf9417a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0093.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0093.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0093.wavetable
new file mode 100644
index 0000000..64ba288
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0093.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0094.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0094.wav
new file mode 100644
index 0000000..182915e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0094.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0094.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0094.wavetable
new file mode 100644
index 0000000..68993cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0094.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0095.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0095.wav
new file mode 100644
index 0000000..8301bc5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0095.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0095.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0095.wavetable
new file mode 100644
index 0000000..74e02db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0095.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0096.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0096.wav
new file mode 100644
index 0000000..8f4ae24
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0096.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0096.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0096.wavetable
new file mode 100644
index 0000000..b5c617d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0096.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0097.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0097.wav
new file mode 100644
index 0000000..cf82818
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0097.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0097.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0097.wavetable
new file mode 100644
index 0000000..a5778bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0097.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0098.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0098.wav
new file mode 100644
index 0000000..829041d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0098.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0098.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0098.wavetable
new file mode 100644
index 0000000..50017cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0098.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0099.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0099.wav
new file mode 100644
index 0000000..5c38286
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0099.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0099.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0099.wavetable
new file mode 100644
index 0000000..dff5799
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0099.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0100.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0100.wav
new file mode 100644
index 0000000..c25fabc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0100.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0100.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0100.wavetable
new file mode 100644
index 0000000..4a92fe8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0100.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0101.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0101.wav
new file mode 100644
index 0000000..e7c6548
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0101.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0101.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0101.wavetable
new file mode 100644
index 0000000..3c15bbd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0101.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0102.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0102.wav
new file mode 100644
index 0000000..2a8b340
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0102.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0102.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0102.wavetable
new file mode 100644
index 0000000..25d1c60
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0102.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0103.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0103.wav
new file mode 100644
index 0000000..ffff8b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0103.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0103.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0103.wavetable
new file mode 100644
index 0000000..b940710
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0103.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0104.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0104.wav
new file mode 100644
index 0000000..02d9acd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0104.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0104.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0104.wavetable
new file mode 100644
index 0000000..fe7057c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0104.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0105.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0105.wav
new file mode 100644
index 0000000..a357225
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0105.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0105.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0105.wavetable
new file mode 100644
index 0000000..e2f16ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0105.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0106.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0106.wav
new file mode 100644
index 0000000..551ab16
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0106.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0106.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0106.wavetable
new file mode 100644
index 0000000..e2be554
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0106.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0107.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0107.wav
new file mode 100644
index 0000000..70a6cd4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0107.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0107.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0107.wavetable
new file mode 100644
index 0000000..8f53ecf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0107.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0108.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0108.wav
new file mode 100644
index 0000000..9759842
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0108.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0108.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0108.wavetable
new file mode 100644
index 0000000..5faa482
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0108.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0109.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0109.wav
new file mode 100644
index 0000000..d2e2e29
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0109.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0109.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0109.wavetable
new file mode 100644
index 0000000..4b87696
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0109.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0110.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0110.wav
new file mode 100644
index 0000000..61c8ab8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0110.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0110.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0110.wavetable
new file mode 100644
index 0000000..7c5e792
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0110.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0111.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0111.wav
new file mode 100644
index 0000000..5793f0e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0111.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0111.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0111.wavetable
new file mode 100644
index 0000000..c87d11c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0111.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0112.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0112.wav
new file mode 100644
index 0000000..5a640b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0112.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0112.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0112.wavetable
new file mode 100644
index 0000000..5c0e4a9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0112.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0113.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0113.wav
new file mode 100644
index 0000000..42f32db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0113.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0113.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0113.wavetable
new file mode 100644
index 0000000..fd9cd28
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0113.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0114.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0114.wav
new file mode 100644
index 0000000..f38b233
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0114.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0114.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0114.wavetable
new file mode 100644
index 0000000..b2c7f18
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0114.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0115.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0115.wav
new file mode 100644
index 0000000..d2fe13d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0115.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0115.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0115.wavetable
new file mode 100644
index 0000000..5583077
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0115.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0116.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0116.wav
new file mode 100644
index 0000000..3e9ff7a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0116.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0116.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0116.wavetable
new file mode 100644
index 0000000..fc67ea7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0116.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0117.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0117.wav
new file mode 100644
index 0000000..9027c10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0117.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0117.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0117.wavetable
new file mode 100644
index 0000000..68b446d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0117.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0118.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0118.wav
new file mode 100644
index 0000000..7663768
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0118.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0118.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0118.wavetable
new file mode 100644
index 0000000..c71b9f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0118.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0119.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0119.wav
new file mode 100644
index 0000000..07e135a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0119.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0119.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0119.wavetable
new file mode 100644
index 0000000..acd3f34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0119.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0120.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0120.wav
new file mode 100644
index 0000000..bfcff36
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0120.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0120.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0120.wavetable
new file mode 100644
index 0000000..a706717
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0120.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0121.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0121.wav
new file mode 100644
index 0000000..312900a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0121.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0121.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0121.wavetable
new file mode 100644
index 0000000..c188c4b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0121.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0122.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0122.wav
new file mode 100644
index 0000000..603a7ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0122.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0122.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0122.wavetable
new file mode 100644
index 0000000..5154a32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0122.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0123.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0123.wav
new file mode 100644
index 0000000..5798688
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0123.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0123.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0123.wavetable
new file mode 100644
index 0000000..8b86614
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0123.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0124.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0124.wav
new file mode 100644
index 0000000..bd57bf4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0124.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0124.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0124.wavetable
new file mode 100644
index 0000000..0f69511
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0124.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0125.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0125.wav
new file mode 100644
index 0000000..687c5d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0125.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0125.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0125.wavetable
new file mode 100644
index 0000000..8dfa883
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0125.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0126.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0126.wav
new file mode 100644
index 0000000..cef213d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0126.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0126.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0126.wavetable
new file mode 100644
index 0000000..3786f10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0126.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0127.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0127.wav
new file mode 100644
index 0000000..f935d88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0127.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0127.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0127.wavetable
new file mode 100644
index 0000000..f2a7052
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0127.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0128.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0128.wav
new file mode 100644
index 0000000..348304e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0128.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0128.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0128.wavetable
new file mode 100644
index 0000000..8abaca8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0128.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0129.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0129.wav
new file mode 100644
index 0000000..bbebd11
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0129.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0129.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0129.wavetable
new file mode 100644
index 0000000..ba6afe1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0129.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0130.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0130.wav
new file mode 100644
index 0000000..4cf068d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0130.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0130.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0130.wavetable
new file mode 100644
index 0000000..a64128a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0130.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0131.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0131.wav
new file mode 100644
index 0000000..10559f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0131.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0131.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0131.wavetable
new file mode 100644
index 0000000..816b66d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0131.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0132.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0132.wav
new file mode 100644
index 0000000..3b98bec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0132.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0132.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0132.wavetable
new file mode 100644
index 0000000..d5fb815
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0132.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0133.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0133.wav
new file mode 100644
index 0000000..f818b83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0133.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0133.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0133.wavetable
new file mode 100644
index 0000000..4b3a2bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0133.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0134.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0134.wav
new file mode 100644
index 0000000..af4866d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0134.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0134.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0134.wavetable
new file mode 100644
index 0000000..77e6ffc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0134.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0135.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0135.wav
new file mode 100644
index 0000000..0bf6597
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0135.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0135.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0135.wavetable
new file mode 100644
index 0000000..7ac9bb0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0135.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0136.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0136.wav
new file mode 100644
index 0000000..5fb4968
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0136.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0136.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0136.wavetable
new file mode 100644
index 0000000..f592a0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0136.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0137.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0137.wav
new file mode 100644
index 0000000..78f1f9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0137.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0137.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0137.wavetable
new file mode 100644
index 0000000..2034f78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0137.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0138.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0138.wav
new file mode 100644
index 0000000..d8c948c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0138.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0138.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0138.wavetable
new file mode 100644
index 0000000..9ce4179
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0138.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0139.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0139.wav
new file mode 100644
index 0000000..01bc532
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0139.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0139.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0139.wavetable
new file mode 100644
index 0000000..2aa8486
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0139.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0140.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0140.wav
new file mode 100644
index 0000000..2b1bb4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0140.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0140.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0140.wavetable
new file mode 100644
index 0000000..89fe8cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0140.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0141.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0141.wav
new file mode 100644
index 0000000..3332a66
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0141.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0141.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0141.wavetable
new file mode 100644
index 0000000..835db56
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0141.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0142.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0142.wav
new file mode 100644
index 0000000..0d55f3d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0142.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0142.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0142.wavetable
new file mode 100644
index 0000000..d29c68d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0142.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0143.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0143.wav
new file mode 100644
index 0000000..993fab5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0143.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0143.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0143.wavetable
new file mode 100644
index 0000000..a3fe6ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0143.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0144.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0144.wav
new file mode 100644
index 0000000..5df8ecb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0144.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0144.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0144.wavetable
new file mode 100644
index 0000000..3bc87ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0144.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0145.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0145.wav
new file mode 100644
index 0000000..4a56147
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0145.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0145.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0145.wavetable
new file mode 100644
index 0000000..d5c4fa3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0145.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0146.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0146.wav
new file mode 100644
index 0000000..a8f93c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0146.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0146.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0146.wavetable
new file mode 100644
index 0000000..db1ed48
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0146.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0147.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0147.wav
new file mode 100644
index 0000000..30f108d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0147.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0147.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0147.wavetable
new file mode 100644
index 0000000..e73d65a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0147.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0148.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0148.wav
new file mode 100644
index 0000000..0b769fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0148.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0148.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0148.wavetable
new file mode 100644
index 0000000..07a0745
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0148.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0149.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0149.wav
new file mode 100644
index 0000000..b2a287d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0149.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0149.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0149.wavetable
new file mode 100644
index 0000000..4cd48b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0149.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0150.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0150.wav
new file mode 100644
index 0000000..4206b6e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0150.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0150.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0150.wavetable
new file mode 100644
index 0000000..b4a82c7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0150.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0151.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0151.wav
new file mode 100644
index 0000000..43932ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0151.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0151.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0151.wavetable
new file mode 100644
index 0000000..c16250b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0151.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0152.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0152.wav
new file mode 100644
index 0000000..7697adb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0152.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0152.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0152.wavetable
new file mode 100644
index 0000000..be747f8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0152.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0153.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0153.wav
new file mode 100644
index 0000000..a0fc49b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0153.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0153.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0153.wavetable
new file mode 100644
index 0000000..866adc9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0153.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0154.wav b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0154.wav
new file mode 100644
index 0000000..57b04bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0154.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0154.wavetable b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0154.wavetable
new file mode 100644
index 0000000..0862f77
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_eorgan/AKWF_eorgan_0154.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_eorgan/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_eorgan/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_eorgan/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0001.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0001.wav
new file mode 100644
index 0000000..abf9bf2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0001.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0001.wavetable
new file mode 100644
index 0000000..45170b3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0002.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0002.wav
new file mode 100644
index 0000000..89012d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0002.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0002.wavetable
new file mode 100644
index 0000000..6639230
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0003.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0003.wav
new file mode 100644
index 0000000..2a73fb9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0003.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0003.wavetable
new file mode 100644
index 0000000..ea886d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0004.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0004.wav
new file mode 100644
index 0000000..fac61fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0004.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0004.wavetable
new file mode 100644
index 0000000..61b5a64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0005.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0005.wav
new file mode 100644
index 0000000..7b16b1d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0005.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0005.wavetable
new file mode 100644
index 0000000..55f0fa1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0006.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0006.wav
new file mode 100644
index 0000000..5075002
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0006.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0006.wavetable
new file mode 100644
index 0000000..c869885
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0007.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0007.wav
new file mode 100644
index 0000000..a34ad5c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0007.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0007.wavetable
new file mode 100644
index 0000000..8a7ebf1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0008.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0008.wav
new file mode 100644
index 0000000..c3de8ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0008.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0008.wavetable
new file mode 100644
index 0000000..8c27d04
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0009.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0009.wav
new file mode 100644
index 0000000..dbb77fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0009.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0009.wavetable
new file mode 100644
index 0000000..fdefcca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0010.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0010.wav
new file mode 100644
index 0000000..2389fa4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0010.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0010.wavetable
new file mode 100644
index 0000000..4a3caf2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0011.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0011.wav
new file mode 100644
index 0000000..8ecf160
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0011.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0011.wavetable
new file mode 100644
index 0000000..5de15e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0012.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0012.wav
new file mode 100644
index 0000000..ca5a039
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0012.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0012.wavetable
new file mode 100644
index 0000000..707b8bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0013.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0013.wav
new file mode 100644
index 0000000..68f0c28
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0013.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0013.wavetable
new file mode 100644
index 0000000..2801531
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0014.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0014.wav
new file mode 100644
index 0000000..22dbbc7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0014.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0014.wavetable
new file mode 100644
index 0000000..846b785
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0015.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0015.wav
new file mode 100644
index 0000000..86deb31
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0015.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0015.wavetable
new file mode 100644
index 0000000..ce7c5fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0016.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0016.wav
new file mode 100644
index 0000000..26effd9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0016.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0016.wavetable
new file mode 100644
index 0000000..af5d03a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0017.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0017.wav
new file mode 100644
index 0000000..a1a0b7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0017.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0017.wavetable
new file mode 100644
index 0000000..9af1067
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0018.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0018.wav
new file mode 100644
index 0000000..e1cef43
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0018.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0018.wavetable
new file mode 100644
index 0000000..41cb017
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0019.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0019.wav
new file mode 100644
index 0000000..4f9f9f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0019.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0019.wavetable
new file mode 100644
index 0000000..ec9c63b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0020.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0020.wav
new file mode 100644
index 0000000..fe9c771
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0020.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0020.wavetable
new file mode 100644
index 0000000..4ff30ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0021.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0021.wav
new file mode 100644
index 0000000..f0547dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0021.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0021.wavetable
new file mode 100644
index 0000000..b6a9915
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0022.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0022.wav
new file mode 100644
index 0000000..bd10227
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0022.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0022.wavetable
new file mode 100644
index 0000000..2dfd792
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0023.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0023.wav
new file mode 100644
index 0000000..ff894b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0023.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0023.wavetable
new file mode 100644
index 0000000..d5fc389
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0024.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0024.wav
new file mode 100644
index 0000000..9f1abd4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0024.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0024.wavetable
new file mode 100644
index 0000000..38262bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0025.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0025.wav
new file mode 100644
index 0000000..f42447b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0025.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0025.wavetable
new file mode 100644
index 0000000..3eb7dd9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0026.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0026.wav
new file mode 100644
index 0000000..77fb1c7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0026.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0026.wavetable
new file mode 100644
index 0000000..32546a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0027.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0027.wav
new file mode 100644
index 0000000..a8e8dc1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0027.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0027.wavetable
new file mode 100644
index 0000000..94593d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0028.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0028.wav
new file mode 100644
index 0000000..a46c590
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0028.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0028.wavetable
new file mode 100644
index 0000000..0df91c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0029.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0029.wav
new file mode 100644
index 0000000..28eacfb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0029.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0029.wavetable
new file mode 100644
index 0000000..7150b39
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0030.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0030.wav
new file mode 100644
index 0000000..c3c696d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0030.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0030.wavetable
new file mode 100644
index 0000000..b9547f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0031.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0031.wav
new file mode 100644
index 0000000..9a69b69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0031.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0031.wavetable
new file mode 100644
index 0000000..d592208
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0032.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0032.wav
new file mode 100644
index 0000000..96d4217
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0032.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0032.wavetable
new file mode 100644
index 0000000..f76dcbc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0033.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0033.wav
new file mode 100644
index 0000000..47a703c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0033.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0033.wavetable
new file mode 100644
index 0000000..0199668
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0034.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0034.wav
new file mode 100644
index 0000000..3bb6627
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0034.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0034.wavetable
new file mode 100644
index 0000000..fb9e7d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0035.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0035.wav
new file mode 100644
index 0000000..00e5fcc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0035.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0035.wavetable
new file mode 100644
index 0000000..7f0c058
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0036.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0036.wav
new file mode 100644
index 0000000..6513cd7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0036.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0036.wavetable
new file mode 100644
index 0000000..de74815
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0037.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0037.wav
new file mode 100644
index 0000000..0c4a93c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0037.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0037.wavetable
new file mode 100644
index 0000000..ce15eaa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0038.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0038.wav
new file mode 100644
index 0000000..cba11fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0038.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0038.wavetable
new file mode 100644
index 0000000..dcdc8f8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0039.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0039.wav
new file mode 100644
index 0000000..bceff80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0039.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0039.wavetable
new file mode 100644
index 0000000..b3c56ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0040.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0040.wav
new file mode 100644
index 0000000..bf69c38
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0040.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0040.wavetable
new file mode 100644
index 0000000..8fb3e63
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0041.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0041.wav
new file mode 100644
index 0000000..c050d03
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0041.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0041.wavetable
new file mode 100644
index 0000000..feda198
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0042.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0042.wav
new file mode 100644
index 0000000..f722475
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0042.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0042.wavetable
new file mode 100644
index 0000000..d85d73b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0043.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0043.wav
new file mode 100644
index 0000000..59bff73
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0043.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0043.wavetable
new file mode 100644
index 0000000..25f3982
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0044.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0044.wav
new file mode 100644
index 0000000..2269048
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0044.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0044.wavetable
new file mode 100644
index 0000000..0ae6c33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0045.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0045.wav
new file mode 100644
index 0000000..92a319d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0045.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0045.wavetable
new file mode 100644
index 0000000..a343a58
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0046.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0046.wav
new file mode 100644
index 0000000..3f4f00c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0046.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0046.wavetable
new file mode 100644
index 0000000..d453528
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0047.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0047.wav
new file mode 100644
index 0000000..29e3347
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0047.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0047.wavetable
new file mode 100644
index 0000000..15ddd07
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0048.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0048.wav
new file mode 100644
index 0000000..fc305dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0048.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0048.wavetable
new file mode 100644
index 0000000..6037760
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0049.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0049.wav
new file mode 100644
index 0000000..ebada2c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0049.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0049.wavetable
new file mode 100644
index 0000000..11d094a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0050.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0050.wav
new file mode 100644
index 0000000..8544f4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0050.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0050.wavetable
new file mode 100644
index 0000000..ce4b6f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0051.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0051.wav
new file mode 100644
index 0000000..c32b46d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0051.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0051.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0051.wavetable
new file mode 100644
index 0000000..6b79ae1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0051.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0052.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0052.wav
new file mode 100644
index 0000000..b7665d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0052.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0052.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0052.wavetable
new file mode 100644
index 0000000..0ba188e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0052.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0053.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0053.wav
new file mode 100644
index 0000000..2d772f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0053.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0053.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0053.wavetable
new file mode 100644
index 0000000..6c9e769
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0053.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0054.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0054.wav
new file mode 100644
index 0000000..0efa0ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0054.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0054.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0054.wavetable
new file mode 100644
index 0000000..054b56a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0054.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0055.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0055.wav
new file mode 100644
index 0000000..ad7ccf5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0055.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0055.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0055.wavetable
new file mode 100644
index 0000000..6ace9a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0055.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0056.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0056.wav
new file mode 100644
index 0000000..944e9e2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0056.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0056.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0056.wavetable
new file mode 100644
index 0000000..8c6ffc2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0056.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0057.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0057.wav
new file mode 100644
index 0000000..51387b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0057.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0057.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0057.wavetable
new file mode 100644
index 0000000..4dd7fb9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0057.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0058.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0058.wav
new file mode 100644
index 0000000..e37d355
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0058.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0058.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0058.wavetable
new file mode 100644
index 0000000..395c741
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0058.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0059.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0059.wav
new file mode 100644
index 0000000..b219cb0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0059.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0059.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0059.wavetable
new file mode 100644
index 0000000..98f52a9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0059.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0060.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0060.wav
new file mode 100644
index 0000000..b51330f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0060.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0060.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0060.wavetable
new file mode 100644
index 0000000..a7e930b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0060.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0061.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0061.wav
new file mode 100644
index 0000000..62f49fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0061.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0061.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0061.wavetable
new file mode 100644
index 0000000..a2e82ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0061.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0062.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0062.wav
new file mode 100644
index 0000000..cd83989
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0062.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0062.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0062.wavetable
new file mode 100644
index 0000000..645ef07
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0062.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0063.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0063.wav
new file mode 100644
index 0000000..204180e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0063.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0063.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0063.wavetable
new file mode 100644
index 0000000..98c2302
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0063.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0064.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0064.wav
new file mode 100644
index 0000000..b1e839a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0064.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0064.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0064.wavetable
new file mode 100644
index 0000000..0713f56
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0064.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0065.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0065.wav
new file mode 100644
index 0000000..3822474
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0065.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0065.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0065.wavetable
new file mode 100644
index 0000000..d243cb6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0065.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0066.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0066.wav
new file mode 100644
index 0000000..f3f0aff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0066.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0066.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0066.wavetable
new file mode 100644
index 0000000..8335769
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0066.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0067.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0067.wav
new file mode 100644
index 0000000..f8533f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0067.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0067.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0067.wavetable
new file mode 100644
index 0000000..6e681c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0067.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0068.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0068.wav
new file mode 100644
index 0000000..9d3c1f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0068.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0068.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0068.wavetable
new file mode 100644
index 0000000..174a536
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0068.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0069.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0069.wav
new file mode 100644
index 0000000..4d9d7bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0069.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0069.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0069.wavetable
new file mode 100644
index 0000000..0122f24
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0069.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0070.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0070.wav
new file mode 100644
index 0000000..ed6b76b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0070.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0070.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0070.wavetable
new file mode 100644
index 0000000..3dd1d73
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0070.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0071.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0071.wav
new file mode 100644
index 0000000..0b67e24
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0071.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0071.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0071.wavetable
new file mode 100644
index 0000000..725a55e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0071.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0072.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0072.wav
new file mode 100644
index 0000000..557bbe5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0072.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0072.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0072.wavetable
new file mode 100644
index 0000000..77c8d26
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0072.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0073.wav b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0073.wav
new file mode 100644
index 0000000..4e9cb86
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0073.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0073.wavetable b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0073.wavetable
new file mode 100644
index 0000000..a015b9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_epiano/AKWF_epiano_0073.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_epiano/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_epiano/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_epiano/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0001.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0001.wav
new file mode 100644
index 0000000..d796143
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0001.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0001.wavetable
new file mode 100644
index 0000000..0bdfd35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0002.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0002.wav
new file mode 100644
index 0000000..06ccbdb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0002.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0002.wavetable
new file mode 100644
index 0000000..7476f11
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0003.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0003.wav
new file mode 100644
index 0000000..6102350
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0003.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0003.wavetable
new file mode 100644
index 0000000..e0de2e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0004.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0004.wav
new file mode 100644
index 0000000..f7e02b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0004.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0004.wavetable
new file mode 100644
index 0000000..bd64ecd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0005.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0005.wav
new file mode 100644
index 0000000..d923387
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0005.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0005.wavetable
new file mode 100644
index 0000000..a5cd423
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0006.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0006.wav
new file mode 100644
index 0000000..763ae3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0006.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0006.wavetable
new file mode 100644
index 0000000..49ab066
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0007.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0007.wav
new file mode 100644
index 0000000..9633bf1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0007.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0007.wavetable
new file mode 100644
index 0000000..3ce7fcf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0008.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0008.wav
new file mode 100644
index 0000000..d82cd0e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0008.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0008.wavetable
new file mode 100644
index 0000000..6cb6af7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0009.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0009.wav
new file mode 100644
index 0000000..7947e1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0009.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0009.wavetable
new file mode 100644
index 0000000..c70a2d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0010.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0010.wav
new file mode 100644
index 0000000..b819b84
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0010.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0010.wavetable
new file mode 100644
index 0000000..c7ed377
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0011.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0011.wav
new file mode 100644
index 0000000..90b21fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0011.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0011.wavetable
new file mode 100644
index 0000000..2ec2577
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0012.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0012.wav
new file mode 100644
index 0000000..3c6d3ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0012.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0012.wavetable
new file mode 100644
index 0000000..b962763
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0013.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0013.wav
new file mode 100644
index 0000000..2ec453e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0013.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0013.wavetable
new file mode 100644
index 0000000..c76c344
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0014.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0014.wav
new file mode 100644
index 0000000..13d19f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0014.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0014.wavetable
new file mode 100644
index 0000000..7e79fdd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0015.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0015.wav
new file mode 100644
index 0000000..caefd11
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0015.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0015.wavetable
new file mode 100644
index 0000000..021b173
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0016.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0016.wav
new file mode 100644
index 0000000..351693b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0016.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0016.wavetable
new file mode 100644
index 0000000..fa4fff5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0017.wav b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0017.wav
new file mode 100644
index 0000000..8e077d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0017.wavetable b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0017.wavetable
new file mode 100644
index 0000000..a4c775f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_flute/AKWF_flute_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_flute/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_flute/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_flute/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0001.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0001.wav
new file mode 100644
index 0000000..4d1748b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0001.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0001.wavetable
new file mode 100644
index 0000000..4bbd229
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0002.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0002.wav
new file mode 100644
index 0000000..2e9f1fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0002.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0002.wavetable
new file mode 100644
index 0000000..f3681bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0003.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0003.wav
new file mode 100644
index 0000000..2077994
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0003.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0003.wavetable
new file mode 100644
index 0000000..67ca285
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0004.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0004.wav
new file mode 100644
index 0000000..b134d3d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0004.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0004.wavetable
new file mode 100644
index 0000000..3e12f98
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0005.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0005.wav
new file mode 100644
index 0000000..a69201f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0005.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0005.wavetable
new file mode 100644
index 0000000..0b53b80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0006.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0006.wav
new file mode 100644
index 0000000..9182042
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0006.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0006.wavetable
new file mode 100644
index 0000000..c7c5f90
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0007.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0007.wav
new file mode 100644
index 0000000..577276f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0007.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0007.wavetable
new file mode 100644
index 0000000..475e38f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0008.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0008.wav
new file mode 100644
index 0000000..b0f5a94
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0008.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0008.wavetable
new file mode 100644
index 0000000..81f0333
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0009.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0009.wav
new file mode 100644
index 0000000..ccde8b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0009.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0009.wavetable
new file mode 100644
index 0000000..03b5686
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0010.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0010.wav
new file mode 100644
index 0000000..da9691c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0010.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0010.wavetable
new file mode 100644
index 0000000..98a2b1e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0011.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0011.wav
new file mode 100644
index 0000000..2041043
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0011.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0011.wavetable
new file mode 100644
index 0000000..a8479af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0012.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0012.wav
new file mode 100644
index 0000000..4aab1f8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0012.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0012.wavetable
new file mode 100644
index 0000000..597d009
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0013.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0013.wav
new file mode 100644
index 0000000..18f4812
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0013.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0013.wavetable
new file mode 100644
index 0000000..c88585d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0014.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0014.wav
new file mode 100644
index 0000000..ee76afa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0014.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0014.wavetable
new file mode 100644
index 0000000..f0f28ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0015.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0015.wav
new file mode 100644
index 0000000..d338b18
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0015.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0015.wavetable
new file mode 100644
index 0000000..ba9dc1d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0016.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0016.wav
new file mode 100644
index 0000000..6f98e61
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0016.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0016.wavetable
new file mode 100644
index 0000000..fe23898
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0017.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0017.wav
new file mode 100644
index 0000000..eec668c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0017.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0017.wavetable
new file mode 100644
index 0000000..970b7e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0018.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0018.wav
new file mode 100644
index 0000000..639bbe4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0018.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0018.wavetable
new file mode 100644
index 0000000..a1a2577
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0019.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0019.wav
new file mode 100644
index 0000000..3e04d9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0019.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0019.wavetable
new file mode 100644
index 0000000..0f159d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0020.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0020.wav
new file mode 100644
index 0000000..a692843
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0020.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0020.wavetable
new file mode 100644
index 0000000..6ea8a48
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0021.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0021.wav
new file mode 100644
index 0000000..db386aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0021.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0021.wavetable
new file mode 100644
index 0000000..2880891
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0022.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0022.wav
new file mode 100644
index 0000000..31716c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0022.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0022.wavetable
new file mode 100644
index 0000000..031c266
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0023.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0023.wav
new file mode 100644
index 0000000..65dc267
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0023.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0023.wavetable
new file mode 100644
index 0000000..3e016c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0024.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0024.wav
new file mode 100644
index 0000000..3be5299
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0024.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0024.wavetable
new file mode 100644
index 0000000..56b107b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0025.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0025.wav
new file mode 100644
index 0000000..bbad8f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0025.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0025.wavetable
new file mode 100644
index 0000000..ef15820
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0026.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0026.wav
new file mode 100644
index 0000000..8e87fe3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0026.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0026.wavetable
new file mode 100644
index 0000000..3ad2e07
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0027.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0027.wav
new file mode 100644
index 0000000..1eb5927
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0027.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0027.wavetable
new file mode 100644
index 0000000..c96ae35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0028.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0028.wav
new file mode 100644
index 0000000..aa3a844
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0028.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0028.wavetable
new file mode 100644
index 0000000..d2cd2ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0029.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0029.wav
new file mode 100644
index 0000000..d5a2153
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0029.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0029.wavetable
new file mode 100644
index 0000000..f966701
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0030.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0030.wav
new file mode 100644
index 0000000..db818b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0030.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0030.wavetable
new file mode 100644
index 0000000..34081af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0031.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0031.wav
new file mode 100644
index 0000000..9a6592e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0031.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0031.wavetable
new file mode 100644
index 0000000..7007236
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0032.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0032.wav
new file mode 100644
index 0000000..b899731
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0032.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0032.wavetable
new file mode 100644
index 0000000..04e0182
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0033.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0033.wav
new file mode 100644
index 0000000..2f8f280
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0033.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0033.wavetable
new file mode 100644
index 0000000..48b4b58
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0034.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0034.wav
new file mode 100644
index 0000000..e3f506d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0034.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0034.wavetable
new file mode 100644
index 0000000..951f920
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0035.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0035.wav
new file mode 100644
index 0000000..ef64927
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0035.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0035.wavetable
new file mode 100644
index 0000000..cab9666
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0036.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0036.wav
new file mode 100644
index 0000000..e1a83de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0036.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0036.wavetable
new file mode 100644
index 0000000..6f6da5f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0037.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0037.wav
new file mode 100644
index 0000000..a8f9aac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0037.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0037.wavetable
new file mode 100644
index 0000000..ab88ed5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0038.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0038.wav
new file mode 100644
index 0000000..8da2d9b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0038.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0038.wavetable
new file mode 100644
index 0000000..6ae4dda
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0039.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0039.wav
new file mode 100644
index 0000000..6afb306
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0039.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0039.wavetable
new file mode 100644
index 0000000..970ee76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0040.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0040.wav
new file mode 100644
index 0000000..d4aaaa2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0040.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0040.wavetable
new file mode 100644
index 0000000..c68abd3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0041.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0041.wav
new file mode 100644
index 0000000..9b1564c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0041.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0041.wavetable
new file mode 100644
index 0000000..1eae505
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0042.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0042.wav
new file mode 100644
index 0000000..103dfc3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0042.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0042.wavetable
new file mode 100644
index 0000000..d4c5515
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0043.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0043.wav
new file mode 100644
index 0000000..037cf90
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0043.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0043.wavetable
new file mode 100644
index 0000000..0f126ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0044.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0044.wav
new file mode 100644
index 0000000..da6dbc1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0044.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0044.wavetable
new file mode 100644
index 0000000..996273d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0045.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0045.wav
new file mode 100644
index 0000000..e141685
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0045.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0045.wavetable
new file mode 100644
index 0000000..a105eb8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0046.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0046.wav
new file mode 100644
index 0000000..bc1e00b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0046.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0046.wavetable
new file mode 100644
index 0000000..bc7023d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0047.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0047.wav
new file mode 100644
index 0000000..dcba42b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0047.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0047.wavetable
new file mode 100644
index 0000000..5aa9edf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0048.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0048.wav
new file mode 100644
index 0000000..b325cf3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0048.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0048.wavetable
new file mode 100644
index 0000000..243164f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0049.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0049.wav
new file mode 100644
index 0000000..f141a5f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0049.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0049.wavetable
new file mode 100644
index 0000000..a8ba90b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0050.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0050.wav
new file mode 100644
index 0000000..d69e095
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0050.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0050.wavetable
new file mode 100644
index 0000000..19e77fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0051.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0051.wav
new file mode 100644
index 0000000..6e52a7b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0051.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0051.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0051.wavetable
new file mode 100644
index 0000000..732a31c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0051.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0052.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0052.wav
new file mode 100644
index 0000000..8ff0aa1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0052.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0052.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0052.wavetable
new file mode 100644
index 0000000..c8d49f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0052.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0053.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0053.wav
new file mode 100644
index 0000000..6a2fdd6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0053.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0053.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0053.wavetable
new file mode 100644
index 0000000..6893974
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0053.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0054.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0054.wav
new file mode 100644
index 0000000..ecaa9d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0054.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0054.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0054.wavetable
new file mode 100644
index 0000000..6064867
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0054.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0055.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0055.wav
new file mode 100644
index 0000000..477a0c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0055.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0055.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0055.wavetable
new file mode 100644
index 0000000..5dc2977
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0055.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0056.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0056.wav
new file mode 100644
index 0000000..f662118
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0056.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0056.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0056.wavetable
new file mode 100644
index 0000000..7787ad1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0056.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0057.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0057.wav
new file mode 100644
index 0000000..ad84529
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0057.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0057.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0057.wavetable
new file mode 100644
index 0000000..40ecb07
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0057.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0058.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0058.wav
new file mode 100644
index 0000000..e77a9e3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0058.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0058.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0058.wavetable
new file mode 100644
index 0000000..1b95d93
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0058.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0059.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0059.wav
new file mode 100644
index 0000000..c250ae9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0059.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0059.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0059.wavetable
new file mode 100644
index 0000000..f3dd619
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0059.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0060.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0060.wav
new file mode 100644
index 0000000..063385a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0060.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0060.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0060.wavetable
new file mode 100644
index 0000000..45d9a32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0060.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0061.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0061.wav
new file mode 100644
index 0000000..6ed6bb2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0061.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0061.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0061.wavetable
new file mode 100644
index 0000000..547b9b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0061.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0062.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0062.wav
new file mode 100644
index 0000000..2a4832f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0062.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0062.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0062.wavetable
new file mode 100644
index 0000000..54745e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0062.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0063.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0063.wav
new file mode 100644
index 0000000..347bffc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0063.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0063.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0063.wavetable
new file mode 100644
index 0000000..79a9e2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0063.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0064.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0064.wav
new file mode 100644
index 0000000..0c1f374
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0064.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0064.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0064.wavetable
new file mode 100644
index 0000000..fed4573
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0064.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0065.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0065.wav
new file mode 100644
index 0000000..016011a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0065.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0065.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0065.wavetable
new file mode 100644
index 0000000..264cd6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0065.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0066.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0066.wav
new file mode 100644
index 0000000..46ad76a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0066.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0066.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0066.wavetable
new file mode 100644
index 0000000..48ccc2d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0066.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0067.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0067.wav
new file mode 100644
index 0000000..01a7767
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0067.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0067.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0067.wavetable
new file mode 100644
index 0000000..7273af2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0067.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0068.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0068.wav
new file mode 100644
index 0000000..a72d00a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0068.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0068.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0068.wavetable
new file mode 100644
index 0000000..344c4cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0068.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0069.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0069.wav
new file mode 100644
index 0000000..d6a25b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0069.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0069.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0069.wavetable
new file mode 100644
index 0000000..e13fafa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0069.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0070.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0070.wav
new file mode 100644
index 0000000..a58fcb9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0070.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0070.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0070.wavetable
new file mode 100644
index 0000000..3bea141
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0070.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0071.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0071.wav
new file mode 100644
index 0000000..67fd694
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0071.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0071.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0071.wavetable
new file mode 100644
index 0000000..21f78fc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0071.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0072.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0072.wav
new file mode 100644
index 0000000..6e00b10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0072.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0072.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0072.wavetable
new file mode 100644
index 0000000..9e1cb68
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0072.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0073.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0073.wav
new file mode 100644
index 0000000..9869308
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0073.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0073.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0073.wavetable
new file mode 100644
index 0000000..eb98f6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0073.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0074.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0074.wav
new file mode 100644
index 0000000..9bc2103
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0074.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0074.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0074.wavetable
new file mode 100644
index 0000000..ade91fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0074.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0075.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0075.wav
new file mode 100644
index 0000000..f373506
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0075.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0075.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0075.wavetable
new file mode 100644
index 0000000..051d07a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0075.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0076.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0076.wav
new file mode 100644
index 0000000..5014967
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0076.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0076.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0076.wavetable
new file mode 100644
index 0000000..2b12f2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0076.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0077.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0077.wav
new file mode 100644
index 0000000..7856d6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0077.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0077.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0077.wavetable
new file mode 100644
index 0000000..06f54c8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0077.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0078.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0078.wav
new file mode 100644
index 0000000..45d549a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0078.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0078.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0078.wavetable
new file mode 100644
index 0000000..e962d2a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0078.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0079.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0079.wav
new file mode 100644
index 0000000..d926599
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0079.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0079.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0079.wavetable
new file mode 100644
index 0000000..365260c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0079.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0080.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0080.wav
new file mode 100644
index 0000000..534a1f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0080.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0080.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0080.wavetable
new file mode 100644
index 0000000..e1c2cbc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0080.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0081.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0081.wav
new file mode 100644
index 0000000..412e9d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0081.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0081.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0081.wavetable
new file mode 100644
index 0000000..8ad6ee8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0081.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0082.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0082.wav
new file mode 100644
index 0000000..8724e9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0082.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0082.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0082.wavetable
new file mode 100644
index 0000000..2b17107
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0082.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0083.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0083.wav
new file mode 100644
index 0000000..1ed8b5f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0083.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0083.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0083.wavetable
new file mode 100644
index 0000000..af30370
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0083.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0084.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0084.wav
new file mode 100644
index 0000000..8cefa19
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0084.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0084.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0084.wavetable
new file mode 100644
index 0000000..d1e139e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0084.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0085.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0085.wav
new file mode 100644
index 0000000..8d292a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0085.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0085.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0085.wavetable
new file mode 100644
index 0000000..bf9d412
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0085.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0086.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0086.wav
new file mode 100644
index 0000000..b1d4447
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0086.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0086.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0086.wavetable
new file mode 100644
index 0000000..5d95f83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0086.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0087.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0087.wav
new file mode 100644
index 0000000..5cc00a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0087.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0087.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0087.wavetable
new file mode 100644
index 0000000..fc08b89
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0087.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0088.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0088.wav
new file mode 100644
index 0000000..c2336c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0088.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0088.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0088.wavetable
new file mode 100644
index 0000000..e7a0284
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0088.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0089.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0089.wav
new file mode 100644
index 0000000..654fc6e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0089.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0089.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0089.wavetable
new file mode 100644
index 0000000..20f5f52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0089.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0090.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0090.wav
new file mode 100644
index 0000000..889c5c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0090.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0090.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0090.wavetable
new file mode 100644
index 0000000..a115fc6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0090.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0091.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0091.wav
new file mode 100644
index 0000000..7c27878
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0091.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0091.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0091.wavetable
new file mode 100644
index 0000000..30b807a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0091.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0092.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0092.wav
new file mode 100644
index 0000000..9503b7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0092.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0092.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0092.wavetable
new file mode 100644
index 0000000..1a5707b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0092.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0093.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0093.wav
new file mode 100644
index 0000000..6e11706
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0093.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0093.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0093.wavetable
new file mode 100644
index 0000000..6ff71de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0093.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0094.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0094.wav
new file mode 100644
index 0000000..81c8db6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0094.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0094.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0094.wavetable
new file mode 100644
index 0000000..e52c6e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0094.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0095.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0095.wav
new file mode 100644
index 0000000..b730c9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0095.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0095.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0095.wavetable
new file mode 100644
index 0000000..5dea47b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0095.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0096.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0096.wav
new file mode 100644
index 0000000..f990f22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0096.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0096.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0096.wavetable
new file mode 100644
index 0000000..f27c050
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0096.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0097.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0097.wav
new file mode 100644
index 0000000..7d7804a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0097.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0097.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0097.wavetable
new file mode 100644
index 0000000..0f36e14
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0097.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0098.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0098.wav
new file mode 100644
index 0000000..33c4b7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0098.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0098.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0098.wavetable
new file mode 100644
index 0000000..95837ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0098.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0099.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0099.wav
new file mode 100644
index 0000000..a0ec19d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0099.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0099.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0099.wavetable
new file mode 100644
index 0000000..3317e69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0099.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0100.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0100.wav
new file mode 100644
index 0000000..bb9802c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0100.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0100.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0100.wavetable
new file mode 100644
index 0000000..1dca91c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0100.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0101.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0101.wav
new file mode 100644
index 0000000..e7a0304
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0101.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0101.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0101.wavetable
new file mode 100644
index 0000000..90c78e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0101.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0102.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0102.wav
new file mode 100644
index 0000000..14b05b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0102.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0102.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0102.wavetable
new file mode 100644
index 0000000..71480d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0102.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0103.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0103.wav
new file mode 100644
index 0000000..264ff0a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0103.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0103.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0103.wavetable
new file mode 100644
index 0000000..5f61ac4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0103.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0104.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0104.wav
new file mode 100644
index 0000000..67c2972
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0104.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0104.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0104.wavetable
new file mode 100644
index 0000000..71be2d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0104.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0105.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0105.wav
new file mode 100644
index 0000000..91e0b17
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0105.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0105.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0105.wavetable
new file mode 100644
index 0000000..59fe5c8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0105.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0106.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0106.wav
new file mode 100644
index 0000000..454753a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0106.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0106.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0106.wavetable
new file mode 100644
index 0000000..5139ef0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0106.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0107.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0107.wav
new file mode 100644
index 0000000..2adb15f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0107.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0107.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0107.wavetable
new file mode 100644
index 0000000..0b4c48b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0107.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0108.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0108.wav
new file mode 100644
index 0000000..a98731a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0108.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0108.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0108.wavetable
new file mode 100644
index 0000000..e15b210
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0108.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0109.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0109.wav
new file mode 100644
index 0000000..c55d15c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0109.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0109.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0109.wavetable
new file mode 100644
index 0000000..38c843e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0109.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0110.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0110.wav
new file mode 100644
index 0000000..5e94ba3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0110.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0110.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0110.wavetable
new file mode 100644
index 0000000..7af1ab2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0110.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0111.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0111.wav
new file mode 100644
index 0000000..4651b0e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0111.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0111.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0111.wavetable
new file mode 100644
index 0000000..45ec6ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0111.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0112.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0112.wav
new file mode 100644
index 0000000..e43c54c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0112.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0112.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0112.wavetable
new file mode 100644
index 0000000..c79a80d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0112.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0113.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0113.wav
new file mode 100644
index 0000000..86047c7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0113.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0113.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0113.wavetable
new file mode 100644
index 0000000..2b0a3d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0113.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0114.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0114.wav
new file mode 100644
index 0000000..9c30b19
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0114.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0114.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0114.wavetable
new file mode 100644
index 0000000..8a430e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0114.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0115.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0115.wav
new file mode 100644
index 0000000..520bedd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0115.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0115.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0115.wavetable
new file mode 100644
index 0000000..df44cca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0115.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0116.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0116.wav
new file mode 100644
index 0000000..7d680d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0116.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0116.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0116.wavetable
new file mode 100644
index 0000000..4bb66ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0116.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0117.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0117.wav
new file mode 100644
index 0000000..5ab353f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0117.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0117.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0117.wavetable
new file mode 100644
index 0000000..da28c7b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0117.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0118.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0118.wav
new file mode 100644
index 0000000..5672737
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0118.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0118.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0118.wavetable
new file mode 100644
index 0000000..ea39233
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0118.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0119.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0119.wav
new file mode 100644
index 0000000..e4d8df0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0119.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0119.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0119.wavetable
new file mode 100644
index 0000000..65ba22e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0119.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0120.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0120.wav
new file mode 100644
index 0000000..4dc565f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0120.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0120.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0120.wavetable
new file mode 100644
index 0000000..33d1e9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0120.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0121.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0121.wav
new file mode 100644
index 0000000..fbf7a8a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0121.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0121.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0121.wavetable
new file mode 100644
index 0000000..fb9ccbd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0121.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0122.wav b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0122.wav
new file mode 100644
index 0000000..28ed012
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0122.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0122.wavetable b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0122.wavetable
new file mode 100644
index 0000000..788b69c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_fmsynth/AKWF_fmsynth_0122.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_fmsynth/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_fmsynth/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_fmsynth/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0001.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0001.wav
new file mode 100644
index 0000000..ada08b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0001.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0001.wavetable
new file mode 100644
index 0000000..aa878fc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0002.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0002.wav
new file mode 100644
index 0000000..d8f78eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0002.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0002.wavetable
new file mode 100644
index 0000000..2b136aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0003.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0003.wav
new file mode 100644
index 0000000..ae79475
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0003.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0003.wavetable
new file mode 100644
index 0000000..df0fd00
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0004.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0004.wav
new file mode 100644
index 0000000..01dbeb1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0004.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0004.wavetable
new file mode 100644
index 0000000..7a04b2c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0005.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0005.wav
new file mode 100644
index 0000000..b2c7612
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0005.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0005.wavetable
new file mode 100644
index 0000000..a18921a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0006.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0006.wav
new file mode 100644
index 0000000..eddff1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0006.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0006.wavetable
new file mode 100644
index 0000000..c924938
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0007.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0007.wav
new file mode 100644
index 0000000..ac863c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0007.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0007.wavetable
new file mode 100644
index 0000000..09b3b87
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0008.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0008.wav
new file mode 100644
index 0000000..405b270
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0008.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0008.wavetable
new file mode 100644
index 0000000..6f0276d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0009.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0009.wav
new file mode 100644
index 0000000..895a94c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0009.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0009.wavetable
new file mode 100644
index 0000000..8ed0265
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0010.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0010.wav
new file mode 100644
index 0000000..4c02d47
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0010.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0010.wavetable
new file mode 100644
index 0000000..69cf84f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0011.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0011.wav
new file mode 100644
index 0000000..3d266f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0011.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0011.wavetable
new file mode 100644
index 0000000..2fe431a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0012.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0012.wav
new file mode 100644
index 0000000..c968ed8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0012.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0012.wavetable
new file mode 100644
index 0000000..1dd6539
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0013.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0013.wav
new file mode 100644
index 0000000..90db6aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0013.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0013.wavetable
new file mode 100644
index 0000000..ef8cb1e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0014.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0014.wav
new file mode 100644
index 0000000..9f534d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0014.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0014.wavetable
new file mode 100644
index 0000000..08052a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0015.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0015.wav
new file mode 100644
index 0000000..3767703
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0015.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0015.wavetable
new file mode 100644
index 0000000..6ad3cb0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0016.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0016.wav
new file mode 100644
index 0000000..9ce9d1f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0016.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0016.wavetable
new file mode 100644
index 0000000..afe099b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0017.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0017.wav
new file mode 100644
index 0000000..fab2856
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0017.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0017.wavetable
new file mode 100644
index 0000000..5204c3d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0018.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0018.wav
new file mode 100644
index 0000000..89835f8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0018.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0018.wavetable
new file mode 100644
index 0000000..0b12ff4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0019.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0019.wav
new file mode 100644
index 0000000..8566008
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0019.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0019.wavetable
new file mode 100644
index 0000000..218656e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0020.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0020.wav
new file mode 100644
index 0000000..bd0a24f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0020.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0020.wavetable
new file mode 100644
index 0000000..3264482
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0021.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0021.wav
new file mode 100644
index 0000000..db501ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0021.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0021.wavetable
new file mode 100644
index 0000000..181d24f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0022.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0022.wav
new file mode 100644
index 0000000..217b947
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0022.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0022.wavetable
new file mode 100644
index 0000000..0367d7a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0023.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0023.wav
new file mode 100644
index 0000000..586e4f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0023.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0023.wavetable
new file mode 100644
index 0000000..184b9a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0024.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0024.wav
new file mode 100644
index 0000000..65ece73
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0024.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0024.wavetable
new file mode 100644
index 0000000..24ead99
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0025.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0025.wav
new file mode 100644
index 0000000..4f7ff9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0025.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0025.wavetable
new file mode 100644
index 0000000..a3dffec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0026.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0026.wav
new file mode 100644
index 0000000..df0b206
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0026.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0026.wavetable
new file mode 100644
index 0000000..a9d4b68
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0027.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0027.wav
new file mode 100644
index 0000000..033f10b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0027.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0027.wavetable
new file mode 100644
index 0000000..aa144ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0028.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0028.wav
new file mode 100644
index 0000000..6b997ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0028.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0028.wavetable
new file mode 100644
index 0000000..8c8694a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0029.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0029.wav
new file mode 100644
index 0000000..b19a206
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0029.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0029.wavetable
new file mode 100644
index 0000000..71d5317
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0030.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0030.wav
new file mode 100644
index 0000000..8ddfb86
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0030.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0030.wavetable
new file mode 100644
index 0000000..657b3ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0031.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0031.wav
new file mode 100644
index 0000000..49465db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0031.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0031.wavetable
new file mode 100644
index 0000000..ac41bb7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0032.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0032.wav
new file mode 100644
index 0000000..abe92b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0032.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0032.wavetable
new file mode 100644
index 0000000..70edf80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0033.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0033.wav
new file mode 100644
index 0000000..a3b7804
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0033.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0033.wavetable
new file mode 100644
index 0000000..5471e9c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0034.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0034.wav
new file mode 100644
index 0000000..5468ab3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0034.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0034.wavetable
new file mode 100644
index 0000000..f7d53fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0035.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0035.wav
new file mode 100644
index 0000000..9137dcd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0035.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0035.wavetable
new file mode 100644
index 0000000..9a2160f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0036.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0036.wav
new file mode 100644
index 0000000..499b6ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0036.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0036.wavetable
new file mode 100644
index 0000000..feef6d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0037.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0037.wav
new file mode 100644
index 0000000..a798ce9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0037.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0037.wavetable
new file mode 100644
index 0000000..7547ed3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0038.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0038.wav
new file mode 100644
index 0000000..097d518
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0038.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0038.wavetable
new file mode 100644
index 0000000..5403388
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0039.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0039.wav
new file mode 100644
index 0000000..4176850
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0039.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0039.wavetable
new file mode 100644
index 0000000..1ddfd21
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0040.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0040.wav
new file mode 100644
index 0000000..4276ef4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0040.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0040.wavetable
new file mode 100644
index 0000000..b489e94
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0041.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0041.wav
new file mode 100644
index 0000000..dc983dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0041.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0041.wavetable
new file mode 100644
index 0000000..7b7ea3a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0042.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0042.wav
new file mode 100644
index 0000000..000fab2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0042.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0042.wavetable
new file mode 100644
index 0000000..b2c7e09
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0043.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0043.wav
new file mode 100644
index 0000000..ff49aaa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0043.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0043.wavetable
new file mode 100644
index 0000000..62d6dc4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0044.wav b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0044.wav
new file mode 100644
index 0000000..f27c591
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0044.wavetable b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0044.wavetable
new file mode 100644
index 0000000..4fa5d05
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_granular/AKWF_granular_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_granular/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_granular/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_granular/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0001.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0001.wav
new file mode 100644
index 0000000..58b6323
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0001.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0001.wavetable
new file mode 100644
index 0000000..d34614e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0002.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0002.wav
new file mode 100644
index 0000000..f4a1093
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0002.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0002.wavetable
new file mode 100644
index 0000000..e51071f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0003.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0003.wav
new file mode 100644
index 0000000..791f120
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0003.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0003.wavetable
new file mode 100644
index 0000000..8f5bf7c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0004.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0004.wav
new file mode 100644
index 0000000..ad60d8d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0004.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0004.wavetable
new file mode 100644
index 0000000..995c9f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0005.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0005.wav
new file mode 100644
index 0000000..e817a9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0005.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0005.wavetable
new file mode 100644
index 0000000..01e33b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0006.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0006.wav
new file mode 100644
index 0000000..da2b10e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0006.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0006.wavetable
new file mode 100644
index 0000000..b06a073
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0007.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0007.wav
new file mode 100644
index 0000000..01afa28
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0007.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0007.wavetable
new file mode 100644
index 0000000..1271e86
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0008.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0008.wav
new file mode 100644
index 0000000..6854173
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0008.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0008.wavetable
new file mode 100644
index 0000000..841fb0e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0009.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0009.wav
new file mode 100644
index 0000000..11fe0c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0009.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0009.wavetable
new file mode 100644
index 0000000..b2fb1ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0010.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0010.wav
new file mode 100644
index 0000000..47da2a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0010.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0010.wavetable
new file mode 100644
index 0000000..265c74a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0011.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0011.wav
new file mode 100644
index 0000000..4fd7905
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0011.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0011.wavetable
new file mode 100644
index 0000000..5574122
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0012.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0012.wav
new file mode 100644
index 0000000..56c4e3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0012.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0012.wavetable
new file mode 100644
index 0000000..cefa83c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0013.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0013.wav
new file mode 100644
index 0000000..dc05939
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0013.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0013.wavetable
new file mode 100644
index 0000000..655fe5c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0014.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0014.wav
new file mode 100644
index 0000000..f92addc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0014.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0014.wavetable
new file mode 100644
index 0000000..778c2c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0015.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0015.wav
new file mode 100644
index 0000000..faf7d3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0015.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0015.wavetable
new file mode 100644
index 0000000..c34cc6a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0016.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0016.wav
new file mode 100644
index 0000000..62ce188
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0016.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0016.wavetable
new file mode 100644
index 0000000..9885c9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0017.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0017.wav
new file mode 100644
index 0000000..1b4885a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0017.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0017.wavetable
new file mode 100644
index 0000000..1685f86
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0018.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0018.wav
new file mode 100644
index 0000000..8067584
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0018.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0018.wavetable
new file mode 100644
index 0000000..0519d77
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0019.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0019.wav
new file mode 100644
index 0000000..e61d73f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0019.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0019.wavetable
new file mode 100644
index 0000000..ea0b19c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0020.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0020.wav
new file mode 100644
index 0000000..4477460
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0020.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0020.wavetable
new file mode 100644
index 0000000..722596b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0021.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0021.wav
new file mode 100644
index 0000000..9ec3f88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0021.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0021.wavetable
new file mode 100644
index 0000000..29b56c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0022.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0022.wav
new file mode 100644
index 0000000..a32f2d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0022.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0022.wavetable
new file mode 100644
index 0000000..e064917
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0023.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0023.wav
new file mode 100644
index 0000000..6f3f8f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0023.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0023.wavetable
new file mode 100644
index 0000000..fd21feb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0024.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0024.wav
new file mode 100644
index 0000000..f8c8abd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0024.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0024.wavetable
new file mode 100644
index 0000000..57047f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0025.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0025.wav
new file mode 100644
index 0000000..2e12921
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0025.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0025.wavetable
new file mode 100644
index 0000000..4f991a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0026.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0026.wav
new file mode 100644
index 0000000..da79b70
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0026.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0026.wavetable
new file mode 100644
index 0000000..d21655e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0027.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0027.wav
new file mode 100644
index 0000000..5caf11d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0027.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0027.wavetable
new file mode 100644
index 0000000..29fe0de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0028.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0028.wav
new file mode 100644
index 0000000..0eb3b92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0028.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0028.wavetable
new file mode 100644
index 0000000..3a324f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0029.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0029.wav
new file mode 100644
index 0000000..0a6b92b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0029.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0029.wavetable
new file mode 100644
index 0000000..65791a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0030.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0030.wav
new file mode 100644
index 0000000..f79550e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0030.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0030.wavetable
new file mode 100644
index 0000000..9d218e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0031.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0031.wav
new file mode 100644
index 0000000..8afac92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0031.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0031.wavetable
new file mode 100644
index 0000000..0904a43
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0032.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0032.wav
new file mode 100644
index 0000000..171e471
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0032.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0032.wavetable
new file mode 100644
index 0000000..e5542f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0033.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0033.wav
new file mode 100644
index 0000000..1827d64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0033.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0033.wavetable
new file mode 100644
index 0000000..a9bde91
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0034.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0034.wav
new file mode 100644
index 0000000..2885316
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0034.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0034.wavetable
new file mode 100644
index 0000000..2ca9aa1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0035.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0035.wav
new file mode 100644
index 0000000..9145948
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0035.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0035.wavetable
new file mode 100644
index 0000000..e127b92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0036.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0036.wav
new file mode 100644
index 0000000..24706dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0036.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0036.wavetable
new file mode 100644
index 0000000..114a992
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0037.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0037.wav
new file mode 100644
index 0000000..6355eb2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0037.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0037.wavetable
new file mode 100644
index 0000000..b16200f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0038.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0038.wav
new file mode 100644
index 0000000..66298d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0038.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0038.wavetable
new file mode 100644
index 0000000..1507028
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0039.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0039.wav
new file mode 100644
index 0000000..6b3da6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0039.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0039.wavetable
new file mode 100644
index 0000000..3e1b17e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0040.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0040.wav
new file mode 100644
index 0000000..7e43f38
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0040.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0040.wavetable
new file mode 100644
index 0000000..51970a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0041.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0041.wav
new file mode 100644
index 0000000..72360c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0041.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0041.wavetable
new file mode 100644
index 0000000..31136db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0042.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0042.wav
new file mode 100644
index 0000000..26e16f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0042.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0042.wavetable
new file mode 100644
index 0000000..6400811
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0043.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0043.wav
new file mode 100644
index 0000000..853b876
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0043.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0043.wavetable
new file mode 100644
index 0000000..69efd83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0044.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0044.wav
new file mode 100644
index 0000000..b260071
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0044.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0044.wavetable
new file mode 100644
index 0000000..6ba959b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0045.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0045.wav
new file mode 100644
index 0000000..fc3df34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0045.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0045.wavetable
new file mode 100644
index 0000000..afa8b1a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0046.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0046.wav
new file mode 100644
index 0000000..9bdfd75
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0046.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0046.wavetable
new file mode 100644
index 0000000..2db5a4f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0047.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0047.wav
new file mode 100644
index 0000000..e211533
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0047.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0047.wavetable
new file mode 100644
index 0000000..dbe4a9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0048.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0048.wav
new file mode 100644
index 0000000..289472e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0048.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0048.wavetable
new file mode 100644
index 0000000..07f7415
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0049.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0049.wav
new file mode 100644
index 0000000..ae8d318
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0049.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0049.wavetable
new file mode 100644
index 0000000..8eb248c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0050.wav b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0050.wav
new file mode 100644
index 0000000..9e877e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0050.wavetable b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0050.wavetable
new file mode 100644
index 0000000..6ea5850
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hdrawn/AKWF_hdrawn_0050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hdrawn/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_hdrawn/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_hdrawn/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0001.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0001.wav
new file mode 100644
index 0000000..d5186f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0001.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0001.wavetable
new file mode 100644
index 0000000..091db9f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0002.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0002.wav
new file mode 100644
index 0000000..e280760
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0002.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0002.wavetable
new file mode 100644
index 0000000..ce02cf2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0003.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0003.wav
new file mode 100644
index 0000000..b968f1d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0003.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0003.wavetable
new file mode 100644
index 0000000..3040b49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0004.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0004.wav
new file mode 100644
index 0000000..ba4ca06
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0004.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0004.wavetable
new file mode 100644
index 0000000..a4b00ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0005.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0005.wav
new file mode 100644
index 0000000..0a047e3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0005.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0005.wavetable
new file mode 100644
index 0000000..76d4bd5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0006.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0006.wav
new file mode 100644
index 0000000..30a1c0a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0006.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0006.wavetable
new file mode 100644
index 0000000..ea99316
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0007.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0007.wav
new file mode 100644
index 0000000..786393e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0007.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0007.wavetable
new file mode 100644
index 0000000..6b9599f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0008.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0008.wav
new file mode 100644
index 0000000..74bee9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0008.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0008.wavetable
new file mode 100644
index 0000000..78983c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0009.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0009.wav
new file mode 100644
index 0000000..41e0813
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0009.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0009.wavetable
new file mode 100644
index 0000000..ba408a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0010.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0010.wav
new file mode 100644
index 0000000..b264a30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0010.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0010.wavetable
new file mode 100644
index 0000000..7835368
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0011.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0011.wav
new file mode 100644
index 0000000..6b0824f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0011.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0011.wavetable
new file mode 100644
index 0000000..cc68c0c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0012.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0012.wav
new file mode 100644
index 0000000..d4f4320
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0012.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0012.wavetable
new file mode 100644
index 0000000..968d45f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0013.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0013.wav
new file mode 100644
index 0000000..79774df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0013.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0013.wavetable
new file mode 100644
index 0000000..7f12ec2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0014.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0014.wav
new file mode 100644
index 0000000..acce762
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0014.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0014.wavetable
new file mode 100644
index 0000000..5d4bb09
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0015.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0015.wav
new file mode 100644
index 0000000..2aebb1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0015.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0015.wavetable
new file mode 100644
index 0000000..0a337fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0016.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0016.wav
new file mode 100644
index 0000000..d6e730e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0016.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0016.wavetable
new file mode 100644
index 0000000..fcb5295
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0017.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0017.wav
new file mode 100644
index 0000000..74ee23d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0017.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0017.wavetable
new file mode 100644
index 0000000..c81c126
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0018.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0018.wav
new file mode 100644
index 0000000..a852805
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0018.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0018.wavetable
new file mode 100644
index 0000000..d9a9a78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0019.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0019.wav
new file mode 100644
index 0000000..5a18579
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0019.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0019.wavetable
new file mode 100644
index 0000000..c3720b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0020.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0020.wav
new file mode 100644
index 0000000..e0fce05
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0020.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0020.wavetable
new file mode 100644
index 0000000..4fc930e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0021.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0021.wav
new file mode 100644
index 0000000..385ebf0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0021.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0021.wavetable
new file mode 100644
index 0000000..ff368ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0022.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0022.wav
new file mode 100644
index 0000000..76bb0ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0022.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0022.wavetable
new file mode 100644
index 0000000..0bde2c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0023.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0023.wav
new file mode 100644
index 0000000..b979a7c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0023.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0023.wavetable
new file mode 100644
index 0000000..b65fe68
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0024.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0024.wav
new file mode 100644
index 0000000..2eb0baf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0024.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0024.wavetable
new file mode 100644
index 0000000..b6b1221
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0025.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0025.wav
new file mode 100644
index 0000000..85f29a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0025.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0025.wavetable
new file mode 100644
index 0000000..464e3e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0026.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0026.wav
new file mode 100644
index 0000000..0437c7c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0026.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0026.wavetable
new file mode 100644
index 0000000..7feb507
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0027.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0027.wav
new file mode 100644
index 0000000..fff511b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0027.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0027.wavetable
new file mode 100644
index 0000000..1db7303
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0028.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0028.wav
new file mode 100644
index 0000000..d9f7c15
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0028.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0028.wavetable
new file mode 100644
index 0000000..ada64d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0029.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0029.wav
new file mode 100644
index 0000000..6efb49b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0029.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0029.wavetable
new file mode 100644
index 0000000..95d377c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0030.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0030.wav
new file mode 100644
index 0000000..9379cbd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0030.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0030.wavetable
new file mode 100644
index 0000000..ed836f8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0031.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0031.wav
new file mode 100644
index 0000000..978d652
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0031.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0031.wavetable
new file mode 100644
index 0000000..b68f46d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0032.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0032.wav
new file mode 100644
index 0000000..9c66207
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0032.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0032.wavetable
new file mode 100644
index 0000000..19a74f8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0033.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0033.wav
new file mode 100644
index 0000000..8322a9b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0033.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0033.wavetable
new file mode 100644
index 0000000..6ab3147
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0034.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0034.wav
new file mode 100644
index 0000000..791f5c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0034.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0034.wavetable
new file mode 100644
index 0000000..66c21cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0035.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0035.wav
new file mode 100644
index 0000000..b8a7f2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0035.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0035.wavetable
new file mode 100644
index 0000000..30148a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0036.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0036.wav
new file mode 100644
index 0000000..4c93401
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0036.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0036.wavetable
new file mode 100644
index 0000000..75bd8a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0037.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0037.wav
new file mode 100644
index 0000000..6cc1032
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0037.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0037.wavetable
new file mode 100644
index 0000000..6da6eee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0038.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0038.wav
new file mode 100644
index 0000000..e308023
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0038.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0038.wavetable
new file mode 100644
index 0000000..75d5457
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0039.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0039.wav
new file mode 100644
index 0000000..8f1fdb4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0039.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0039.wavetable
new file mode 100644
index 0000000..4819383
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0040.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0040.wav
new file mode 100644
index 0000000..7de8316
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0040.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0040.wavetable
new file mode 100644
index 0000000..57236e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0041.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0041.wav
new file mode 100644
index 0000000..2614b5d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0041.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0041.wavetable
new file mode 100644
index 0000000..de57733
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0042.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0042.wav
new file mode 100644
index 0000000..1af7af9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0042.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0042.wavetable
new file mode 100644
index 0000000..2de5227
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0043.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0043.wav
new file mode 100644
index 0000000..b97bf9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0043.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0043.wavetable
new file mode 100644
index 0000000..2bada5c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0044.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0044.wav
new file mode 100644
index 0000000..252f46d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0044.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0044.wavetable
new file mode 100644
index 0000000..269fd53
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0045.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0045.wav
new file mode 100644
index 0000000..91deaee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0045.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0045.wavetable
new file mode 100644
index 0000000..05e7acb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0046.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0046.wav
new file mode 100644
index 0000000..1cf15a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0046.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0046.wavetable
new file mode 100644
index 0000000..ef10c97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0047.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0047.wav
new file mode 100644
index 0000000..df11ac5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0047.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0047.wavetable
new file mode 100644
index 0000000..ac16a1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0048.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0048.wav
new file mode 100644
index 0000000..1ba3e68
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0048.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0048.wavetable
new file mode 100644
index 0000000..d59df65
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0049.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0049.wav
new file mode 100644
index 0000000..050ff63
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0049.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0049.wavetable
new file mode 100644
index 0000000..a011a30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0050.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0050.wav
new file mode 100644
index 0000000..8adbf10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0050.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0050.wavetable
new file mode 100644
index 0000000..3abeeda
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0051.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0051.wav
new file mode 100644
index 0000000..a8b1514
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0051.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0051.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0051.wavetable
new file mode 100644
index 0000000..d60b83e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0051.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0052.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0052.wav
new file mode 100644
index 0000000..2ec0bb6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0052.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0052.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0052.wavetable
new file mode 100644
index 0000000..04df240
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0052.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0053.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0053.wav
new file mode 100644
index 0000000..6ed2333
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0053.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0053.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0053.wavetable
new file mode 100644
index 0000000..b15f545
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0053.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0054.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0054.wav
new file mode 100644
index 0000000..28ada3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0054.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0054.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0054.wavetable
new file mode 100644
index 0000000..7c68e76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0054.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0055.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0055.wav
new file mode 100644
index 0000000..fd3ad29
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0055.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0055.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0055.wavetable
new file mode 100644
index 0000000..dd8cc69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0055.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0056.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0056.wav
new file mode 100644
index 0000000..368690a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0056.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0056.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0056.wavetable
new file mode 100644
index 0000000..1104b67
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0056.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0057.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0057.wav
new file mode 100644
index 0000000..267a3f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0057.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0057.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0057.wavetable
new file mode 100644
index 0000000..1af7e5c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0057.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0058.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0058.wav
new file mode 100644
index 0000000..4813d79
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0058.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0058.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0058.wavetable
new file mode 100644
index 0000000..3d866d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0058.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0059.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0059.wav
new file mode 100644
index 0000000..c6ad566
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0059.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0059.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0059.wavetable
new file mode 100644
index 0000000..5ac35f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0059.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0060.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0060.wav
new file mode 100644
index 0000000..afcaf98
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0060.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0060.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0060.wavetable
new file mode 100644
index 0000000..5ca69c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0060.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0061.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0061.wav
new file mode 100644
index 0000000..bf7d3b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0061.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0061.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0061.wavetable
new file mode 100644
index 0000000..d36a3ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0061.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0062.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0062.wav
new file mode 100644
index 0000000..80de80d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0062.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0062.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0062.wavetable
new file mode 100644
index 0000000..85623bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0062.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0063.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0063.wav
new file mode 100644
index 0000000..bcec55e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0063.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0063.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0063.wavetable
new file mode 100644
index 0000000..d653674
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0063.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0064.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0064.wav
new file mode 100644
index 0000000..19757ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0064.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0064.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0064.wavetable
new file mode 100644
index 0000000..3972011
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0064.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0065.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0065.wav
new file mode 100644
index 0000000..c47447f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0065.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0065.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0065.wavetable
new file mode 100644
index 0000000..ca87221
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0065.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0066.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0066.wav
new file mode 100644
index 0000000..74d0a14
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0066.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0066.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0066.wavetable
new file mode 100644
index 0000000..2ade350
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0066.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0067.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0067.wav
new file mode 100644
index 0000000..b1d77d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0067.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0067.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0067.wavetable
new file mode 100644
index 0000000..acfffd3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0067.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0068.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0068.wav
new file mode 100644
index 0000000..1dfbb2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0068.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0068.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0068.wavetable
new file mode 100644
index 0000000..34db719
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0068.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0069.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0069.wav
new file mode 100644
index 0000000..eb66b9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0069.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0069.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0069.wavetable
new file mode 100644
index 0000000..71df75b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0069.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0070.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0070.wav
new file mode 100644
index 0000000..743c7ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0070.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0070.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0070.wavetable
new file mode 100644
index 0000000..5b5b27c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0070.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0071.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0071.wav
new file mode 100644
index 0000000..54af27f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0071.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0071.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0071.wavetable
new file mode 100644
index 0000000..1ba2ef4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0071.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0072.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0072.wav
new file mode 100644
index 0000000..c4018dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0072.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0072.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0072.wavetable
new file mode 100644
index 0000000..64f80a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0072.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0073.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0073.wav
new file mode 100644
index 0000000..b1f3d57
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0073.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0073.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0073.wavetable
new file mode 100644
index 0000000..66a1158
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0073.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0074.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0074.wav
new file mode 100644
index 0000000..ef6fa50
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0074.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0074.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0074.wavetable
new file mode 100644
index 0000000..c21f270
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0074.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0075.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0075.wav
new file mode 100644
index 0000000..58a4248
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0075.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0075.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0075.wavetable
new file mode 100644
index 0000000..31dec8f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0075.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0076.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0076.wav
new file mode 100644
index 0000000..b3a96c8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0076.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0076.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0076.wavetable
new file mode 100644
index 0000000..7a5a154
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0076.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0077.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0077.wav
new file mode 100644
index 0000000..68b75ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0077.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0077.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0077.wavetable
new file mode 100644
index 0000000..e1f6a09
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0077.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0078.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0078.wav
new file mode 100644
index 0000000..816cfc5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0078.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0078.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0078.wavetable
new file mode 100644
index 0000000..c2ae9e2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0078.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0079.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0079.wav
new file mode 100644
index 0000000..cd778f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0079.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0079.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0079.wavetable
new file mode 100644
index 0000000..1a7d457
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0079.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0080.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0080.wav
new file mode 100644
index 0000000..ddf0b42
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0080.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0080.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0080.wavetable
new file mode 100644
index 0000000..a5856fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0080.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0081.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0081.wav
new file mode 100644
index 0000000..9223216
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0081.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0081.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0081.wavetable
new file mode 100644
index 0000000..a0b6f53
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0081.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0082.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0082.wav
new file mode 100644
index 0000000..6d99703
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0082.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0082.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0082.wavetable
new file mode 100644
index 0000000..95fad10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0082.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0083.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0083.wav
new file mode 100644
index 0000000..0ce035c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0083.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0083.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0083.wavetable
new file mode 100644
index 0000000..c574b5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0083.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0084.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0084.wav
new file mode 100644
index 0000000..4db2fdc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0084.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0084.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0084.wavetable
new file mode 100644
index 0000000..736f770
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0084.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0085.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0085.wav
new file mode 100644
index 0000000..c2926de
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0085.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0085.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0085.wavetable
new file mode 100644
index 0000000..26ecd00
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0085.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0086.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0086.wav
new file mode 100644
index 0000000..f916748
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0086.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0086.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0086.wavetable
new file mode 100644
index 0000000..6319337
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0086.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0087.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0087.wav
new file mode 100644
index 0000000..dfa92b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0087.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0087.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0087.wavetable
new file mode 100644
index 0000000..0901110
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0087.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0088.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0088.wav
new file mode 100644
index 0000000..d30c037
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0088.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0088.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0088.wavetable
new file mode 100644
index 0000000..969f91c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0088.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0089.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0089.wav
new file mode 100644
index 0000000..2cc8041
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0089.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0089.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0089.wavetable
new file mode 100644
index 0000000..78751e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0089.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0090.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0090.wav
new file mode 100644
index 0000000..de3ca75
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0090.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0090.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0090.wavetable
new file mode 100644
index 0000000..83906f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0090.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0091.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0091.wav
new file mode 100644
index 0000000..6fe97ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0091.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0091.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0091.wavetable
new file mode 100644
index 0000000..2b85939
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0091.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0092.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0092.wav
new file mode 100644
index 0000000..b22d277
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0092.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0092.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0092.wavetable
new file mode 100644
index 0000000..947b5bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0092.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0093.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0093.wav
new file mode 100644
index 0000000..1a8cb52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0093.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0093.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0093.wavetable
new file mode 100644
index 0000000..f1d7090
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0093.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0094.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0094.wav
new file mode 100644
index 0000000..52d8c16
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0094.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0094.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0094.wavetable
new file mode 100644
index 0000000..1e27802
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0094.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0095.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0095.wav
new file mode 100644
index 0000000..6679073
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0095.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0095.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0095.wavetable
new file mode 100644
index 0000000..a9ea9f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0095.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0096.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0096.wav
new file mode 100644
index 0000000..7069bac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0096.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0096.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0096.wavetable
new file mode 100644
index 0000000..aefc8fc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0096.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0097.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0097.wav
new file mode 100644
index 0000000..bcc0e95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0097.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0097.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0097.wavetable
new file mode 100644
index 0000000..7e79d61
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0097.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0098.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0098.wav
new file mode 100644
index 0000000..cdb05a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0098.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0098.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0098.wavetable
new file mode 100644
index 0000000..ea8b36b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0098.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0099.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0099.wav
new file mode 100644
index 0000000..85b473d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0099.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0099.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0099.wavetable
new file mode 100644
index 0000000..491b264
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0099.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0100.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0100.wav
new file mode 100644
index 0000000..4b616a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0100.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0100.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0100.wavetable
new file mode 100644
index 0000000..fc8e5b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0100.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0101.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0101.wav
new file mode 100644
index 0000000..934f02d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0101.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0101.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0101.wavetable
new file mode 100644
index 0000000..945fc1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0101.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0102.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0102.wav
new file mode 100644
index 0000000..8d3e0fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0102.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0102.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0102.wavetable
new file mode 100644
index 0000000..c49f7d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0102.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0103.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0103.wav
new file mode 100644
index 0000000..205a473
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0103.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0103.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0103.wavetable
new file mode 100644
index 0000000..402720b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0103.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0104.wav b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0104.wav
new file mode 100644
index 0000000..083a4f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0104.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0104.wavetable b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0104.wavetable
new file mode 100644
index 0000000..1cf29a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_hvoice/AKWF_hvoice_0104.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_hvoice/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_hvoice/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_hvoice/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0001.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0001.wav
new file mode 100644
index 0000000..0f2defe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0001.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0001.wavetable
new file mode 100644
index 0000000..675fcd9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0002.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0002.wav
new file mode 100644
index 0000000..d250937
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0002.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0002.wavetable
new file mode 100644
index 0000000..73997e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0003.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0003.wav
new file mode 100644
index 0000000..69163cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0003.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0003.wavetable
new file mode 100644
index 0000000..31ea2c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0004.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0004.wav
new file mode 100644
index 0000000..6d9410f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0004.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0004.wavetable
new file mode 100644
index 0000000..db0f3a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0005.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0005.wav
new file mode 100644
index 0000000..bbcb7db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0005.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0005.wavetable
new file mode 100644
index 0000000..91ec358
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0006.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0006.wav
new file mode 100644
index 0000000..54259a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0006.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0006.wavetable
new file mode 100644
index 0000000..2879636
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0007.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0007.wav
new file mode 100644
index 0000000..cdec105
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0007.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0007.wavetable
new file mode 100644
index 0000000..769a221
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0008.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0008.wav
new file mode 100644
index 0000000..51e8f99
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0008.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0008.wavetable
new file mode 100644
index 0000000..b0376ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0009.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0009.wav
new file mode 100644
index 0000000..03dd627
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0009.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0009.wavetable
new file mode 100644
index 0000000..8d86b8a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0010.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0010.wav
new file mode 100644
index 0000000..23b7f9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0010.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0010.wavetable
new file mode 100644
index 0000000..fc4ff5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0011.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0011.wav
new file mode 100644
index 0000000..2bb8587
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0011.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0011.wavetable
new file mode 100644
index 0000000..b18f809
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0012.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0012.wav
new file mode 100644
index 0000000..f94866e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0012.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0012.wavetable
new file mode 100644
index 0000000..5132b76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0013.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0013.wav
new file mode 100644
index 0000000..ee6d046
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0013.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0013.wavetable
new file mode 100644
index 0000000..a4ffad7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0014.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0014.wav
new file mode 100644
index 0000000..2591653
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0014.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0014.wavetable
new file mode 100644
index 0000000..e72d6a9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0015.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0015.wav
new file mode 100644
index 0000000..47f9080
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0015.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0015.wavetable
new file mode 100644
index 0000000..9b798d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0016.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0016.wav
new file mode 100644
index 0000000..9399106
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0016.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0016.wavetable
new file mode 100644
index 0000000..0fe4c00
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0017.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0017.wav
new file mode 100644
index 0000000..7c14ca2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0017.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0017.wavetable
new file mode 100644
index 0000000..5245cff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0018.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0018.wav
new file mode 100644
index 0000000..a500bd6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0018.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0018.wavetable
new file mode 100644
index 0000000..dc38897
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0019.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0019.wav
new file mode 100644
index 0000000..b1f4235
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0019.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0019.wavetable
new file mode 100644
index 0000000..b98778a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0020.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0020.wav
new file mode 100644
index 0000000..5f51c8b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0020.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0020.wavetable
new file mode 100644
index 0000000..29cecb9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0021.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0021.wav
new file mode 100644
index 0000000..9e0dd9f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0021.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0021.wavetable
new file mode 100644
index 0000000..55e0558
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0022.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0022.wav
new file mode 100644
index 0000000..7044bb9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0022.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0022.wavetable
new file mode 100644
index 0000000..cebceab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0023.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0023.wav
new file mode 100644
index 0000000..7f0d75b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0023.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0023.wavetable
new file mode 100644
index 0000000..18f4426
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0024.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0024.wav
new file mode 100644
index 0000000..f4abc31
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0024.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0024.wavetable
new file mode 100644
index 0000000..49bcbfe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0025.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0025.wav
new file mode 100644
index 0000000..30f415f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0025.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0025.wavetable
new file mode 100644
index 0000000..d96c52b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0026.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0026.wav
new file mode 100644
index 0000000..f52d7ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0026.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0026.wavetable
new file mode 100644
index 0000000..86fcb85
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0027.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0027.wav
new file mode 100644
index 0000000..2f2cf1e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0027.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0027.wavetable
new file mode 100644
index 0000000..570deda
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0028.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0028.wav
new file mode 100644
index 0000000..8f12465
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0028.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0028.wavetable
new file mode 100644
index 0000000..b0eef80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0029.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0029.wav
new file mode 100644
index 0000000..4f4076f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0029.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0029.wavetable
new file mode 100644
index 0000000..d0a0bae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0030.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0030.wav
new file mode 100644
index 0000000..76974d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0030.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0030.wavetable
new file mode 100644
index 0000000..84954f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0031.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0031.wav
new file mode 100644
index 0000000..448b68c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0031.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0031.wavetable
new file mode 100644
index 0000000..0e82292
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0032.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0032.wav
new file mode 100644
index 0000000..028e915
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0032.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0032.wavetable
new file mode 100644
index 0000000..04b43ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0033.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0033.wav
new file mode 100644
index 0000000..fb4a849
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0033.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0033.wavetable
new file mode 100644
index 0000000..5565f73
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0034.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0034.wav
new file mode 100644
index 0000000..a91a20d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0034.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0034.wavetable
new file mode 100644
index 0000000..d67fb43
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0035.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0035.wav
new file mode 100644
index 0000000..5b249bd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0035.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0035.wavetable
new file mode 100644
index 0000000..80ca3df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0036.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0036.wav
new file mode 100644
index 0000000..83cd81b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0036.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0036.wavetable
new file mode 100644
index 0000000..46d2364
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0037.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0037.wav
new file mode 100644
index 0000000..0c2da10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0037.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0037.wavetable
new file mode 100644
index 0000000..24f8781
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0038.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0038.wav
new file mode 100644
index 0000000..45faee7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0038.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0038.wavetable
new file mode 100644
index 0000000..a158b1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0039.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0039.wav
new file mode 100644
index 0000000..dd4818f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0039.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0039.wavetable
new file mode 100644
index 0000000..d6c8cf8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0040.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0040.wav
new file mode 100644
index 0000000..8efb6e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0040.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0040.wavetable
new file mode 100644
index 0000000..b0cb3d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0041.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0041.wav
new file mode 100644
index 0000000..02f584b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0041.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0041.wavetable
new file mode 100644
index 0000000..5b0f1dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0042.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0042.wav
new file mode 100644
index 0000000..cd565a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0042.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0042.wavetable
new file mode 100644
index 0000000..10d1c00
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0043.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0043.wav
new file mode 100644
index 0000000..fc7f8b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0043.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0043.wavetable
new file mode 100644
index 0000000..54d1a5c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0044.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0044.wav
new file mode 100644
index 0000000..70124e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0044.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0044.wavetable
new file mode 100644
index 0000000..1b47fa3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0045.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0045.wav
new file mode 100644
index 0000000..b909453
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0045.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0045.wavetable
new file mode 100644
index 0000000..18f2151
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0046.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0046.wav
new file mode 100644
index 0000000..b24eda1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0046.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0046.wavetable
new file mode 100644
index 0000000..0dba452
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0047.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0047.wav
new file mode 100644
index 0000000..8813d44
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0047.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0047.wavetable
new file mode 100644
index 0000000..910adab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0048.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0048.wav
new file mode 100644
index 0000000..1b58657
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0048.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0048.wavetable
new file mode 100644
index 0000000..a971141
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0049.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0049.wav
new file mode 100644
index 0000000..62b1067
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0049.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0049.wavetable
new file mode 100644
index 0000000..1cd97c7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0050.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0050.wav
new file mode 100644
index 0000000..e8b8d59
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0050.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0050.wavetable
new file mode 100644
index 0000000..80acfb8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0051.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0051.wav
new file mode 100644
index 0000000..eab9ca0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0051.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0051.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0051.wavetable
new file mode 100644
index 0000000..3fb5145
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0051.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0052.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0052.wav
new file mode 100644
index 0000000..dfc3d5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0052.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0052.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0052.wavetable
new file mode 100644
index 0000000..d96b8ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0052.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0053.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0053.wav
new file mode 100644
index 0000000..1b8b56d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0053.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0053.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0053.wavetable
new file mode 100644
index 0000000..d3b81f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0053.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0054.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0054.wav
new file mode 100644
index 0000000..a2c1eca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0054.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0054.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0054.wavetable
new file mode 100644
index 0000000..a3ced32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0054.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0055.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0055.wav
new file mode 100644
index 0000000..a986ef2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0055.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0055.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0055.wavetable
new file mode 100644
index 0000000..532f6cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0055.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0056.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0056.wav
new file mode 100644
index 0000000..018f3ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0056.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0056.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0056.wavetable
new file mode 100644
index 0000000..4fd7a7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0056.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0057.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0057.wav
new file mode 100644
index 0000000..055c9fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0057.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0057.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0057.wavetable
new file mode 100644
index 0000000..a0f9333
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0057.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0058.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0058.wav
new file mode 100644
index 0000000..05f68cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0058.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0058.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0058.wavetable
new file mode 100644
index 0000000..e32994d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0058.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0059.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0059.wav
new file mode 100644
index 0000000..c84619f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0059.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0059.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0059.wavetable
new file mode 100644
index 0000000..4ab9ce2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0059.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0060.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0060.wav
new file mode 100644
index 0000000..be2b15a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0060.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0060.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0060.wavetable
new file mode 100644
index 0000000..fc7109c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0060.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0061.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0061.wav
new file mode 100644
index 0000000..f1aede6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0061.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0061.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0061.wavetable
new file mode 100644
index 0000000..3cb9839
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0061.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0062.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0062.wav
new file mode 100644
index 0000000..1420708
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0062.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0062.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0062.wavetable
new file mode 100644
index 0000000..03258b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0062.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0063.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0063.wav
new file mode 100644
index 0000000..aa50a02
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0063.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0063.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0063.wavetable
new file mode 100644
index 0000000..d0ae177
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0063.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0064.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0064.wav
new file mode 100644
index 0000000..ac50b10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0064.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0064.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0064.wavetable
new file mode 100644
index 0000000..2463405
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0064.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0065.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0065.wav
new file mode 100644
index 0000000..41f3602
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0065.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0065.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0065.wavetable
new file mode 100644
index 0000000..fd4863d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0065.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0066.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0066.wav
new file mode 100644
index 0000000..ebf5c3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0066.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0066.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0066.wavetable
new file mode 100644
index 0000000..ef22827
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0066.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0067.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0067.wav
new file mode 100644
index 0000000..d66515e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0067.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0067.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0067.wavetable
new file mode 100644
index 0000000..0867f1f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0067.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0068.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0068.wav
new file mode 100644
index 0000000..352c423
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0068.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0068.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0068.wavetable
new file mode 100644
index 0000000..fa1073e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0068.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0069.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0069.wav
new file mode 100644
index 0000000..5278b57
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0069.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0069.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0069.wavetable
new file mode 100644
index 0000000..bb49f33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0069.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0070.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0070.wav
new file mode 100644
index 0000000..c33a75a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0070.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0070.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0070.wavetable
new file mode 100644
index 0000000..0d19eb6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0070.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0071.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0071.wav
new file mode 100644
index 0000000..b5f0769
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0071.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0071.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0071.wavetable
new file mode 100644
index 0000000..79fa619
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0071.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0072.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0072.wav
new file mode 100644
index 0000000..cb2a084
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0072.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0072.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0072.wavetable
new file mode 100644
index 0000000..a2253e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0072.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0073.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0073.wav
new file mode 100644
index 0000000..9dc4895
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0073.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0073.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0073.wavetable
new file mode 100644
index 0000000..3e12583
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0073.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0074.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0074.wav
new file mode 100644
index 0000000..db294cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0074.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0074.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0074.wavetable
new file mode 100644
index 0000000..bf09430
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0074.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0075.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0075.wav
new file mode 100644
index 0000000..d0f3873
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0075.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0075.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0075.wavetable
new file mode 100644
index 0000000..7403099
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0075.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0076.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0076.wav
new file mode 100644
index 0000000..f74315f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0076.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0076.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0076.wavetable
new file mode 100644
index 0000000..a48416a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0076.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0077.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0077.wav
new file mode 100644
index 0000000..191ab6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0077.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0077.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0077.wavetable
new file mode 100644
index 0000000..3e3281e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0077.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0078.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0078.wav
new file mode 100644
index 0000000..468132d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0078.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0078.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0078.wavetable
new file mode 100644
index 0000000..c5fb205
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0078.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0079.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0079.wav
new file mode 100644
index 0000000..7d351ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0079.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0079.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0079.wavetable
new file mode 100644
index 0000000..4100120
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0079.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0080.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0080.wav
new file mode 100644
index 0000000..2d20a6a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0080.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0080.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0080.wavetable
new file mode 100644
index 0000000..c029b37
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0080.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0081.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0081.wav
new file mode 100644
index 0000000..c894036
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0081.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0081.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0081.wavetable
new file mode 100644
index 0000000..d3bf7dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0081.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0082.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0082.wav
new file mode 100644
index 0000000..d7532c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0082.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0082.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0082.wavetable
new file mode 100644
index 0000000..98302c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0082.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0083.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0083.wav
new file mode 100644
index 0000000..67b8e41
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0083.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0083.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0083.wavetable
new file mode 100644
index 0000000..31f6bfc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0083.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0084.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0084.wav
new file mode 100644
index 0000000..060384b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0084.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0084.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0084.wavetable
new file mode 100644
index 0000000..4f00960
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0084.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0085.wav b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0085.wav
new file mode 100644
index 0000000..696dc99
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0085.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0085.wavetable b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0085.wavetable
new file mode 100644
index 0000000..fd38aa8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_linear/AKWF_linear_0085.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_linear/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_linear/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_linear/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0001.wav b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0001.wav
new file mode 100644
index 0000000..93d6617
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0001.wavetable b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0001.wavetable
new file mode 100644
index 0000000..df1b8b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0002.wav b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0002.wav
new file mode 100644
index 0000000..3ac06db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0002.wavetable b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0002.wavetable
new file mode 100644
index 0000000..9ff2df8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0003.wav b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0003.wav
new file mode 100644
index 0000000..d8e220e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0003.wavetable b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0003.wavetable
new file mode 100644
index 0000000..c015bd0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0004.wav b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0004.wav
new file mode 100644
index 0000000..1f3308b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0004.wavetable b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0004.wavetable
new file mode 100644
index 0000000..5d5f634
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0005.wav b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0005.wav
new file mode 100644
index 0000000..95dadc8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0005.wavetable b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0005.wavetable
new file mode 100644
index 0000000..a9660b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0006.wav b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0006.wav
new file mode 100644
index 0000000..72f4ebc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0006.wavetable b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0006.wavetable
new file mode 100644
index 0000000..004b9ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0007.wav b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0007.wav
new file mode 100644
index 0000000..13f266c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0007.wavetable b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0007.wavetable
new file mode 100644
index 0000000..e0aec76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0008.wav b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0008.wav
new file mode 100644
index 0000000..0974dd1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0008.wavetable b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0008.wavetable
new file mode 100644
index 0000000..ce46ccd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0009.wav b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0009.wav
new file mode 100644
index 0000000..36ca935
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0009.wavetable b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0009.wavetable
new file mode 100644
index 0000000..40d0364
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0010.wav b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0010.wav
new file mode 100644
index 0000000..1bfa27c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0010.wavetable b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0010.wavetable
new file mode 100644
index 0000000..590906f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0011.wav b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0011.wav
new file mode 100644
index 0000000..a2bf83b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0011.wavetable b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0011.wavetable
new file mode 100644
index 0000000..90dcab0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0012.wav b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0012.wav
new file mode 100644
index 0000000..2a5fa91
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0012.wavetable b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0012.wavetable
new file mode 100644
index 0000000..bf98539
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0013.wav b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0013.wav
new file mode 100644
index 0000000..b1e82fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0013.wavetable b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0013.wavetable
new file mode 100644
index 0000000..f37e79f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oboe/AKWF_oboe_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oboe/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_oboe/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_oboe/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0001.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0001.wav
new file mode 100644
index 0000000..a726fd5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0001.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0001.wavetable
new file mode 100644
index 0000000..2f6b777
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0002.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0002.wav
new file mode 100644
index 0000000..7dea1cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0002.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0002.wavetable
new file mode 100644
index 0000000..588373e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0003.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0003.wav
new file mode 100644
index 0000000..b16cc6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0003.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0003.wavetable
new file mode 100644
index 0000000..2d4ada4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0004.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0004.wav
new file mode 100644
index 0000000..b89bfb9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0004.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0004.wavetable
new file mode 100644
index 0000000..89f85fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0005.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0005.wav
new file mode 100644
index 0000000..cc5f8ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0005.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0005.wavetable
new file mode 100644
index 0000000..b215a7d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0006.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0006.wav
new file mode 100644
index 0000000..937ef76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0006.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0006.wavetable
new file mode 100644
index 0000000..b830943
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0007.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0007.wav
new file mode 100644
index 0000000..6571089
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0007.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0007.wavetable
new file mode 100644
index 0000000..e406fdc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0008.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0008.wav
new file mode 100644
index 0000000..67ffca7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0008.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0008.wavetable
new file mode 100644
index 0000000..a6a4ff8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0009.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0009.wav
new file mode 100644
index 0000000..e72e403
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0009.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0009.wavetable
new file mode 100644
index 0000000..247a934
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0010.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0010.wav
new file mode 100644
index 0000000..b9a4947
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0010.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0010.wavetable
new file mode 100644
index 0000000..569523f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0011.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0011.wav
new file mode 100644
index 0000000..f446487
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0011.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0011.wavetable
new file mode 100644
index 0000000..889a91d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0012.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0012.wav
new file mode 100644
index 0000000..5ec883d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0012.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0012.wavetable
new file mode 100644
index 0000000..f27caf6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0013.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0013.wav
new file mode 100644
index 0000000..1d096a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0013.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0013.wavetable
new file mode 100644
index 0000000..719e860
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0014.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0014.wav
new file mode 100644
index 0000000..bb4a220
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0014.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0014.wavetable
new file mode 100644
index 0000000..3f8f2bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0015.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0015.wav
new file mode 100644
index 0000000..ce74bda
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0015.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0015.wavetable
new file mode 100644
index 0000000..1688bc9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0016.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0016.wav
new file mode 100644
index 0000000..d27d9a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0016.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0016.wavetable
new file mode 100644
index 0000000..3bc54e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0017.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0017.wav
new file mode 100644
index 0000000..e50c195
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0017.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0017.wavetable
new file mode 100644
index 0000000..e7ea320
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0018.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0018.wav
new file mode 100644
index 0000000..6681395
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0018.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0018.wavetable
new file mode 100644
index 0000000..1448de1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0019.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0019.wav
new file mode 100644
index 0000000..8f26939
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0019.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0019.wavetable
new file mode 100644
index 0000000..6065f01
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0020.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0020.wav
new file mode 100644
index 0000000..14909cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0020.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0020.wavetable
new file mode 100644
index 0000000..a32c164
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0021.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0021.wav
new file mode 100644
index 0000000..7b66b8a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0021.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0021.wavetable
new file mode 100644
index 0000000..e3b1610
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0022.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0022.wav
new file mode 100644
index 0000000..e6d6a8d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0022.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0022.wavetable
new file mode 100644
index 0000000..a979b67
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0023.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0023.wav
new file mode 100644
index 0000000..85faaa1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0023.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0023.wavetable
new file mode 100644
index 0000000..b4af5ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0024.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0024.wav
new file mode 100644
index 0000000..fbbfd9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0024.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0024.wavetable
new file mode 100644
index 0000000..30bf97d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0025.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0025.wav
new file mode 100644
index 0000000..272c930
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0025.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0025.wavetable
new file mode 100644
index 0000000..112bcef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0026.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0026.wav
new file mode 100644
index 0000000..99108aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0026.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0026.wavetable
new file mode 100644
index 0000000..e19da0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0027.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0027.wav
new file mode 100644
index 0000000..373a28d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0027.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0027.wavetable
new file mode 100644
index 0000000..fab5e57
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0028.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0028.wav
new file mode 100644
index 0000000..53a33a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0028.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0028.wavetable
new file mode 100644
index 0000000..3111cc1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0029.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0029.wav
new file mode 100644
index 0000000..2b0394d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0029.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0029.wavetable
new file mode 100644
index 0000000..c891938
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0030.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0030.wav
new file mode 100644
index 0000000..c343c91
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0030.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0030.wavetable
new file mode 100644
index 0000000..0e1bc02
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0031.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0031.wav
new file mode 100644
index 0000000..f9c542a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0031.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0031.wavetable
new file mode 100644
index 0000000..11d1033
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0032.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0032.wav
new file mode 100644
index 0000000..5d9f7a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0032.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0032.wavetable
new file mode 100644
index 0000000..3d10a1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0033.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0033.wav
new file mode 100644
index 0000000..b212625
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0033.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0033.wavetable
new file mode 100644
index 0000000..c0fe777
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0034.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0034.wav
new file mode 100644
index 0000000..0649da4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0034.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0034.wavetable
new file mode 100644
index 0000000..86a144e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0035.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0035.wav
new file mode 100644
index 0000000..e02026d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0035.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0035.wavetable
new file mode 100644
index 0000000..db5c108
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0036.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0036.wav
new file mode 100644
index 0000000..ddc0797
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0036.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0036.wavetable
new file mode 100644
index 0000000..d10bb7b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0037.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0037.wav
new file mode 100644
index 0000000..1e00a7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0037.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0037.wavetable
new file mode 100644
index 0000000..6082114
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0038.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0038.wav
new file mode 100644
index 0000000..9a1b4dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0038.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0038.wavetable
new file mode 100644
index 0000000..59e7203
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0039.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0039.wav
new file mode 100644
index 0000000..1eb25f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0039.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0039.wavetable
new file mode 100644
index 0000000..9ffedf2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0040.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0040.wav
new file mode 100644
index 0000000..059084d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0040.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0040.wavetable
new file mode 100644
index 0000000..027c4ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0041.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0041.wav
new file mode 100644
index 0000000..374ecd2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0041.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0041.wavetable
new file mode 100644
index 0000000..45f3da9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0042.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0042.wav
new file mode 100644
index 0000000..1d16487
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0042.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0042.wavetable
new file mode 100644
index 0000000..337ecee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0043.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0043.wav
new file mode 100644
index 0000000..cf464c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0043.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0043.wavetable
new file mode 100644
index 0000000..d7dff9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0044.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0044.wav
new file mode 100644
index 0000000..ffe9dd2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0044.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0044.wavetable
new file mode 100644
index 0000000..291f310
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0045.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0045.wav
new file mode 100644
index 0000000..688f32c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0045.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0045.wavetable
new file mode 100644
index 0000000..b03184c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0046.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0046.wav
new file mode 100644
index 0000000..00cfae4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0046.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0046.wavetable
new file mode 100644
index 0000000..6621e12
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0047.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0047.wav
new file mode 100644
index 0000000..0e4b5c8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0047.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0047.wavetable
new file mode 100644
index 0000000..86096a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0048.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0048.wav
new file mode 100644
index 0000000..fd57186
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0048.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0048.wavetable
new file mode 100644
index 0000000..7c68304
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0049.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0049.wav
new file mode 100644
index 0000000..9d4de52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0049.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0049.wavetable
new file mode 100644
index 0000000..f47f8b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0050.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0050.wav
new file mode 100644
index 0000000..3f29a09
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0050.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0050.wavetable
new file mode 100644
index 0000000..eb386ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0051.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0051.wav
new file mode 100644
index 0000000..4931f0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0051.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0051.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0051.wavetable
new file mode 100644
index 0000000..879ebeb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0051.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0052.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0052.wav
new file mode 100644
index 0000000..8379909
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0052.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0052.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0052.wavetable
new file mode 100644
index 0000000..d686130
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0052.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0053.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0053.wav
new file mode 100644
index 0000000..429cdbd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0053.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0053.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0053.wavetable
new file mode 100644
index 0000000..5bc4562
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0053.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0054.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0054.wav
new file mode 100644
index 0000000..1ea2de4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0054.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0054.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0054.wavetable
new file mode 100644
index 0000000..44a2927
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0054.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0055.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0055.wav
new file mode 100644
index 0000000..03f20ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0055.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0055.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0055.wavetable
new file mode 100644
index 0000000..43f7b93
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0055.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0056.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0056.wav
new file mode 100644
index 0000000..2ac46a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0056.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0056.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0056.wavetable
new file mode 100644
index 0000000..916f741
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0056.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0057.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0057.wav
new file mode 100644
index 0000000..bf482b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0057.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0057.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0057.wavetable
new file mode 100644
index 0000000..08772a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0057.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0058.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0058.wav
new file mode 100644
index 0000000..8cfcdf5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0058.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0058.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0058.wavetable
new file mode 100644
index 0000000..a68c195
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0058.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0059.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0059.wav
new file mode 100644
index 0000000..b807b57
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0059.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0059.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0059.wavetable
new file mode 100644
index 0000000..4a05f45
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0059.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0060.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0060.wav
new file mode 100644
index 0000000..4a15e6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0060.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0060.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0060.wavetable
new file mode 100644
index 0000000..a9ad997
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0060.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0061.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0061.wav
new file mode 100644
index 0000000..2863f79
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0061.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0061.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0061.wavetable
new file mode 100644
index 0000000..7f1dfb0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0061.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0062.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0062.wav
new file mode 100644
index 0000000..1cea733
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0062.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0062.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0062.wavetable
new file mode 100644
index 0000000..2c30559
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0062.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0063.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0063.wav
new file mode 100644
index 0000000..34c25c8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0063.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0063.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0063.wavetable
new file mode 100644
index 0000000..c289530
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0063.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0064.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0064.wav
new file mode 100644
index 0000000..b9831a9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0064.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0064.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0064.wavetable
new file mode 100644
index 0000000..32b489e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0064.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0065.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0065.wav
new file mode 100644
index 0000000..a6835ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0065.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0065.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0065.wavetable
new file mode 100644
index 0000000..cd884c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0065.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0066.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0066.wav
new file mode 100644
index 0000000..8e9b74f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0066.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0066.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0066.wavetable
new file mode 100644
index 0000000..a61c6b8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0066.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0067.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0067.wav
new file mode 100644
index 0000000..eaafa00
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0067.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0067.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0067.wavetable
new file mode 100644
index 0000000..d6bd96e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0067.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0068.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0068.wav
new file mode 100644
index 0000000..fa31be1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0068.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0068.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0068.wavetable
new file mode 100644
index 0000000..3d64d1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0068.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0069.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0069.wav
new file mode 100644
index 0000000..5fb9cba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0069.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0069.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0069.wavetable
new file mode 100644
index 0000000..e62ac49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0069.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0070.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0070.wav
new file mode 100644
index 0000000..e5d50a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0070.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0070.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0070.wavetable
new file mode 100644
index 0000000..3805476
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0070.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0071.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0071.wav
new file mode 100644
index 0000000..94ed795
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0071.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0071.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0071.wavetable
new file mode 100644
index 0000000..a5365a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0071.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0072.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0072.wav
new file mode 100644
index 0000000..e78414d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0072.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0072.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0072.wavetable
new file mode 100644
index 0000000..8a7b9e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0072.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0073.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0073.wav
new file mode 100644
index 0000000..4b26e4a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0073.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0073.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0073.wavetable
new file mode 100644
index 0000000..e486eb5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0073.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0074.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0074.wav
new file mode 100644
index 0000000..0ed9a4b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0074.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0074.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0074.wavetable
new file mode 100644
index 0000000..470361c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0074.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0075.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0075.wav
new file mode 100644
index 0000000..846f953
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0075.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0075.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0075.wavetable
new file mode 100644
index 0000000..1dd8104
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0075.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0076.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0076.wav
new file mode 100644
index 0000000..fe55ef8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0076.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0076.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0076.wavetable
new file mode 100644
index 0000000..db02fca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0076.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0077.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0077.wav
new file mode 100644
index 0000000..5489220
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0077.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0077.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0077.wavetable
new file mode 100644
index 0000000..779125e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0077.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0078.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0078.wav
new file mode 100644
index 0000000..3d8977c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0078.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0078.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0078.wavetable
new file mode 100644
index 0000000..0850565
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0078.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0079.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0079.wav
new file mode 100644
index 0000000..1c3e4e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0079.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0079.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0079.wavetable
new file mode 100644
index 0000000..b455c3f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0079.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0080.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0080.wav
new file mode 100644
index 0000000..6811979
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0080.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0080.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0080.wavetable
new file mode 100644
index 0000000..e5f4fbe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0080.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0081.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0081.wav
new file mode 100644
index 0000000..105454c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0081.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0081.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0081.wavetable
new file mode 100644
index 0000000..a0909a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0081.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0082.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0082.wav
new file mode 100644
index 0000000..0dc40d1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0082.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0082.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0082.wavetable
new file mode 100644
index 0000000..930e829
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0082.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0083.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0083.wav
new file mode 100644
index 0000000..d41f653
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0083.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0083.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0083.wavetable
new file mode 100644
index 0000000..955a796
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0083.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0084.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0084.wav
new file mode 100644
index 0000000..12f14be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0084.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0084.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0084.wavetable
new file mode 100644
index 0000000..ac1e82f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0084.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0085.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0085.wav
new file mode 100644
index 0000000..22955ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0085.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0085.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0085.wavetable
new file mode 100644
index 0000000..01a3827
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0085.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0086.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0086.wav
new file mode 100644
index 0000000..8dc91ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0086.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0086.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0086.wavetable
new file mode 100644
index 0000000..9af454c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0086.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0087.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0087.wav
new file mode 100644
index 0000000..9b63394
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0087.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0087.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0087.wavetable
new file mode 100644
index 0000000..30bb690
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0087.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0088.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0088.wav
new file mode 100644
index 0000000..c3ef33a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0088.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0088.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0088.wavetable
new file mode 100644
index 0000000..334ec7a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0088.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0089.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0089.wav
new file mode 100644
index 0000000..b66e3b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0089.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0089.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0089.wavetable
new file mode 100644
index 0000000..bca6967
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0089.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0090.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0090.wav
new file mode 100644
index 0000000..b6e0ed0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0090.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0090.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0090.wavetable
new file mode 100644
index 0000000..f7d7f92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0090.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0091.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0091.wav
new file mode 100644
index 0000000..06bba34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0091.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0091.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0091.wavetable
new file mode 100644
index 0000000..a441f8f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0091.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0092.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0092.wav
new file mode 100644
index 0000000..618dddd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0092.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0092.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0092.wavetable
new file mode 100644
index 0000000..b8ea81e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0092.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0093.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0093.wav
new file mode 100644
index 0000000..64a7e77
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0093.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0093.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0093.wavetable
new file mode 100644
index 0000000..e90aa9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0093.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0094.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0094.wav
new file mode 100644
index 0000000..e71aaad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0094.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0094.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0094.wavetable
new file mode 100644
index 0000000..1c0f2b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0094.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0095.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0095.wav
new file mode 100644
index 0000000..4282173
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0095.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0095.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0095.wavetable
new file mode 100644
index 0000000..a397efe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0095.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0096.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0096.wav
new file mode 100644
index 0000000..d59b633
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0096.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0096.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0096.wavetable
new file mode 100644
index 0000000..b3f0ec4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0096.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0097.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0097.wav
new file mode 100644
index 0000000..ae15b90
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0097.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0097.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0097.wavetable
new file mode 100644
index 0000000..74fe614
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0097.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0098.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0098.wav
new file mode 100644
index 0000000..ff92847
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0098.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0098.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0098.wavetable
new file mode 100644
index 0000000..5d7d30c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0098.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0099.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0099.wav
new file mode 100644
index 0000000..f4268e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0099.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0099.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0099.wavetable
new file mode 100644
index 0000000..9166489
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0099.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0100.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0100.wav
new file mode 100644
index 0000000..cb9a2ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0100.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0100.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0100.wavetable
new file mode 100644
index 0000000..6206698
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0100.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0101.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0101.wav
new file mode 100644
index 0000000..1bfa774
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0101.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0101.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0101.wavetable
new file mode 100644
index 0000000..db0a677
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0101.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0102.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0102.wav
new file mode 100644
index 0000000..c3b2423
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0102.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0102.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0102.wavetable
new file mode 100644
index 0000000..59ec894
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0102.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0103.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0103.wav
new file mode 100644
index 0000000..020b695
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0103.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0103.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0103.wavetable
new file mode 100644
index 0000000..082cc34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0103.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0104.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0104.wav
new file mode 100644
index 0000000..dbdc20c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0104.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0104.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0104.wavetable
new file mode 100644
index 0000000..35d34b3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0104.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0105.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0105.wav
new file mode 100644
index 0000000..4306f76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0105.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0105.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0105.wavetable
new file mode 100644
index 0000000..e2e33af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0105.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0106.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0106.wav
new file mode 100644
index 0000000..39a4589
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0106.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0106.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0106.wavetable
new file mode 100644
index 0000000..d00a072
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0106.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0107.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0107.wav
new file mode 100644
index 0000000..f771cd4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0107.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0107.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0107.wavetable
new file mode 100644
index 0000000..2cb05eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0107.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0108.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0108.wav
new file mode 100644
index 0000000..35670f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0108.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0108.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0108.wavetable
new file mode 100644
index 0000000..b065642
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0108.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0109.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0109.wav
new file mode 100644
index 0000000..86ef03b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0109.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0109.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0109.wavetable
new file mode 100644
index 0000000..e1fbba0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0109.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0110.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0110.wav
new file mode 100644
index 0000000..f911694
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0110.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0110.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0110.wavetable
new file mode 100644
index 0000000..9ce54e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0110.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0111.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0111.wav
new file mode 100644
index 0000000..8a6ac60
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0111.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0111.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0111.wavetable
new file mode 100644
index 0000000..3facf48
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0111.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0112.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0112.wav
new file mode 100644
index 0000000..b50d4f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0112.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0112.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0112.wavetable
new file mode 100644
index 0000000..bf1c5f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0112.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0113.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0113.wav
new file mode 100644
index 0000000..7971ac8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0113.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0113.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0113.wavetable
new file mode 100644
index 0000000..1da3e97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0113.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0114.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0114.wav
new file mode 100644
index 0000000..140df55
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0114.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0114.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0114.wavetable
new file mode 100644
index 0000000..dc9f8c8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0114.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0115.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0115.wav
new file mode 100644
index 0000000..8583800
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0115.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0115.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0115.wavetable
new file mode 100644
index 0000000..ef21c2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0115.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0116.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0116.wav
new file mode 100644
index 0000000..4962a15
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0116.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0116.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0116.wavetable
new file mode 100644
index 0000000..e064ae1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0116.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0117.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0117.wav
new file mode 100644
index 0000000..9187a97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0117.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0117.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0117.wavetable
new file mode 100644
index 0000000..3cf3552
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0117.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0118.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0118.wav
new file mode 100644
index 0000000..9b1d19a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0118.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0118.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0118.wavetable
new file mode 100644
index 0000000..882df54
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0118.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0119.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0119.wav
new file mode 100644
index 0000000..b406b40
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0119.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0119.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0119.wavetable
new file mode 100644
index 0000000..7718f96
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0119.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0120.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0120.wav
new file mode 100644
index 0000000..373c159
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0120.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0120.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0120.wavetable
new file mode 100644
index 0000000..b075b80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0120.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0121.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0121.wav
new file mode 100644
index 0000000..d54e774
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0121.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0121.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0121.wavetable
new file mode 100644
index 0000000..8c0482a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0121.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0122.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0122.wav
new file mode 100644
index 0000000..e569cd7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0122.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0122.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0122.wavetable
new file mode 100644
index 0000000..6501c6d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0122.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0123.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0123.wav
new file mode 100644
index 0000000..a06eedc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0123.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0123.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0123.wavetable
new file mode 100644
index 0000000..21bce05
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0123.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0124.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0124.wav
new file mode 100644
index 0000000..e674946
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0124.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0124.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0124.wavetable
new file mode 100644
index 0000000..8938e9c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0124.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0125.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0125.wav
new file mode 100644
index 0000000..fd40c78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0125.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0125.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0125.wavetable
new file mode 100644
index 0000000..5f41f13
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0125.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0126.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0126.wav
new file mode 100644
index 0000000..014239a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0126.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0126.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0126.wavetable
new file mode 100644
index 0000000..453076e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0126.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0127.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0127.wav
new file mode 100644
index 0000000..58c353e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0127.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0127.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0127.wavetable
new file mode 100644
index 0000000..2d18a43
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0127.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0128.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0128.wav
new file mode 100644
index 0000000..4bd14fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0128.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0128.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0128.wavetable
new file mode 100644
index 0000000..c06da01
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0128.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0129.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0129.wav
new file mode 100644
index 0000000..a4aee47
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0129.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0129.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0129.wavetable
new file mode 100644
index 0000000..f8b0cee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0129.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0130.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0130.wav
new file mode 100644
index 0000000..be0c8c7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0130.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0130.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0130.wavetable
new file mode 100644
index 0000000..9efb9a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0130.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0131.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0131.wav
new file mode 100644
index 0000000..1825075
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0131.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0131.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0131.wavetable
new file mode 100644
index 0000000..40e79d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0131.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0132.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0132.wav
new file mode 100644
index 0000000..da127bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0132.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0132.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0132.wavetable
new file mode 100644
index 0000000..72aac7c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0132.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0133.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0133.wav
new file mode 100644
index 0000000..5629d95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0133.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0133.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0133.wavetable
new file mode 100644
index 0000000..1e04b36
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0133.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0134.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0134.wav
new file mode 100644
index 0000000..91c1847
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0134.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0134.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0134.wavetable
new file mode 100644
index 0000000..99a9ba3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0134.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0135.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0135.wav
new file mode 100644
index 0000000..b0e0abc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0135.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0135.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0135.wavetable
new file mode 100644
index 0000000..3c98bd8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0135.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0136.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0136.wav
new file mode 100644
index 0000000..b54ae42
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0136.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0136.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0136.wavetable
new file mode 100644
index 0000000..f9463c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0136.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0137.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0137.wav
new file mode 100644
index 0000000..3f46556
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0137.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0137.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0137.wavetable
new file mode 100644
index 0000000..bd9c3e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0137.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0138.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0138.wav
new file mode 100644
index 0000000..b34de1a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0138.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0138.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0138.wavetable
new file mode 100644
index 0000000..9e4c802
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0138.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0139.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0139.wav
new file mode 100644
index 0000000..ddf02b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0139.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0139.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0139.wavetable
new file mode 100644
index 0000000..b19d6b3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0139.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0140.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0140.wav
new file mode 100644
index 0000000..ad693ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0140.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0140.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0140.wavetable
new file mode 100644
index 0000000..9e463ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0140.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0141.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0141.wav
new file mode 100644
index 0000000..d2d93b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0141.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0141.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0141.wavetable
new file mode 100644
index 0000000..a0bfcc4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0141.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0142.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0142.wav
new file mode 100644
index 0000000..8e6c0fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0142.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0142.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0142.wavetable
new file mode 100644
index 0000000..af8cb9c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0142.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0143.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0143.wav
new file mode 100644
index 0000000..df898be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0143.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0143.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0143.wavetable
new file mode 100644
index 0000000..b47b5dc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0143.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0144.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0144.wav
new file mode 100644
index 0000000..d12f973
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0144.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0144.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0144.wavetable
new file mode 100644
index 0000000..f73c53e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0144.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0145.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0145.wav
new file mode 100644
index 0000000..b15b023
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0145.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0145.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0145.wavetable
new file mode 100644
index 0000000..82890d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0145.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0146.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0146.wav
new file mode 100644
index 0000000..b75b4f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0146.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0146.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0146.wavetable
new file mode 100644
index 0000000..0be75a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0146.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0147.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0147.wav
new file mode 100644
index 0000000..0d5b4b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0147.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0147.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0147.wavetable
new file mode 100644
index 0000000..8b6f39a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0147.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0148.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0148.wav
new file mode 100644
index 0000000..b9a8091
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0148.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0148.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0148.wavetable
new file mode 100644
index 0000000..306c86b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0148.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0149.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0149.wav
new file mode 100644
index 0000000..c2bb3df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0149.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0149.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0149.wavetable
new file mode 100644
index 0000000..8bf5569
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0149.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0150.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0150.wav
new file mode 100644
index 0000000..2ff31fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0150.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0150.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0150.wavetable
new file mode 100644
index 0000000..c96a6b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0150.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0151.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0151.wav
new file mode 100644
index 0000000..f52fb75
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0151.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0151.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0151.wavetable
new file mode 100644
index 0000000..454582e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0151.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0152.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0152.wav
new file mode 100644
index 0000000..c9e735c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0152.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0152.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0152.wavetable
new file mode 100644
index 0000000..f374f84
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0152.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0153.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0153.wav
new file mode 100644
index 0000000..3e1e79e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0153.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0153.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0153.wavetable
new file mode 100644
index 0000000..622206d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0153.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0154.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0154.wav
new file mode 100644
index 0000000..b7a213f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0154.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0154.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0154.wavetable
new file mode 100644
index 0000000..da0df51
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0154.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0155.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0155.wav
new file mode 100644
index 0000000..9ed4901
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0155.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0155.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0155.wavetable
new file mode 100644
index 0000000..bcd1fe9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0155.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0156.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0156.wav
new file mode 100644
index 0000000..9adf106
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0156.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0156.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0156.wavetable
new file mode 100644
index 0000000..2c4d24d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0156.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0157.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0157.wav
new file mode 100644
index 0000000..9291ae8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0157.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0157.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0157.wavetable
new file mode 100644
index 0000000..e73f5f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0157.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0158.wav b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0158.wav
new file mode 100644
index 0000000..0d4966c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0158.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0158.wavetable b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0158.wavetable
new file mode 100644
index 0000000..3fa2e1a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_oscchip/AKWF_oscchip_0158.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_oscchip/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_oscchip/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_oscchip/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0001.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0001.wav
new file mode 100644
index 0000000..f776bc9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0001.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0001.wavetable
new file mode 100644
index 0000000..e8ff178
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0002.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0002.wav
new file mode 100644
index 0000000..61bc78c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0002.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0002.wavetable
new file mode 100644
index 0000000..1c5cad2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0003.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0003.wav
new file mode 100644
index 0000000..ba4bf89
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0003.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0003.wavetable
new file mode 100644
index 0000000..52748ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0004.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0004.wav
new file mode 100644
index 0000000..5516c39
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0004.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0004.wavetable
new file mode 100644
index 0000000..eb7d3c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0005.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0005.wav
new file mode 100644
index 0000000..f8ba065
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0005.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0005.wavetable
new file mode 100644
index 0000000..4fa7a92
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0006.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0006.wav
new file mode 100644
index 0000000..0dc0847
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0006.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0006.wavetable
new file mode 100644
index 0000000..57a6da3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0007.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0007.wav
new file mode 100644
index 0000000..e047e19
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0007.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0007.wavetable
new file mode 100644
index 0000000..da37122
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0008.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0008.wav
new file mode 100644
index 0000000..c181587
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0008.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0008.wavetable
new file mode 100644
index 0000000..5c2af10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0009.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0009.wav
new file mode 100644
index 0000000..fc4bf4e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0009.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0009.wavetable
new file mode 100644
index 0000000..aec6ead
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0010.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0010.wav
new file mode 100644
index 0000000..53cebe2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0010.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0010.wavetable
new file mode 100644
index 0000000..ecd8e1a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0011.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0011.wav
new file mode 100644
index 0000000..b0d6bbf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0011.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0011.wavetable
new file mode 100644
index 0000000..c39a087
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0012.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0012.wav
new file mode 100644
index 0000000..3b71d65
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0012.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0012.wavetable
new file mode 100644
index 0000000..8a5205b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0013.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0013.wav
new file mode 100644
index 0000000..b5b731e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0013.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0013.wavetable
new file mode 100644
index 0000000..cdfa65a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0014.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0014.wav
new file mode 100644
index 0000000..2185a6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0014.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0014.wavetable
new file mode 100644
index 0000000..cbfb12a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0015.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0015.wav
new file mode 100644
index 0000000..0e73038
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0015.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0015.wavetable
new file mode 100644
index 0000000..ffc5012
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0016.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0016.wav
new file mode 100644
index 0000000..cbb4133
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0016.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0016.wavetable
new file mode 100644
index 0000000..618d0e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0017.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0017.wav
new file mode 100644
index 0000000..0bbc631
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0017.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0017.wavetable
new file mode 100644
index 0000000..927e6ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0018.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0018.wav
new file mode 100644
index 0000000..c94dab8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0018.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0018.wavetable
new file mode 100644
index 0000000..0774baf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0019.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0019.wav
new file mode 100644
index 0000000..8e10c9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0019.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0019.wavetable
new file mode 100644
index 0000000..aee9cf5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0020.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0020.wav
new file mode 100644
index 0000000..e5819b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0020.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0020.wavetable
new file mode 100644
index 0000000..3cf10a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0021.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0021.wav
new file mode 100644
index 0000000..64f39f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0021.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0021.wavetable
new file mode 100644
index 0000000..23ea0c7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0022.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0022.wav
new file mode 100644
index 0000000..22242aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0022.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0022.wavetable
new file mode 100644
index 0000000..a3b44f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0023.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0023.wav
new file mode 100644
index 0000000..65c1af6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0023.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0023.wavetable
new file mode 100644
index 0000000..bdeebde
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0024.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0024.wav
new file mode 100644
index 0000000..c3ac4c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0024.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0024.wavetable
new file mode 100644
index 0000000..0e264d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0025.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0025.wav
new file mode 100644
index 0000000..1cf5dba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0025.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0025.wavetable
new file mode 100644
index 0000000..ad75566
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0026.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0026.wav
new file mode 100644
index 0000000..fd2c39c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0026.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0026.wavetable
new file mode 100644
index 0000000..13ec0e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0027.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0027.wav
new file mode 100644
index 0000000..1ad999e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0027.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0027.wavetable
new file mode 100644
index 0000000..4900592
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0028.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0028.wav
new file mode 100644
index 0000000..a4f9394
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0028.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0028.wavetable
new file mode 100644
index 0000000..a21746b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0029.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0029.wav
new file mode 100644
index 0000000..877be6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0029.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0029.wavetable
new file mode 100644
index 0000000..a917efa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0030.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0030.wav
new file mode 100644
index 0000000..fb44fa6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0030.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0030.wavetable
new file mode 100644
index 0000000..7a11b29
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0031.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0031.wav
new file mode 100644
index 0000000..1155073
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0031.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0031.wavetable
new file mode 100644
index 0000000..fae04c7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0032.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0032.wav
new file mode 100644
index 0000000..4324fdb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0032.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0032.wavetable
new file mode 100644
index 0000000..bf4c770
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0033.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0033.wav
new file mode 100644
index 0000000..0ca1c55
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0033.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0033.wavetable
new file mode 100644
index 0000000..6be0288
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0034.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0034.wav
new file mode 100644
index 0000000..c4fd3ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0034.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0034.wavetable
new file mode 100644
index 0000000..db64279
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0035.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0035.wav
new file mode 100644
index 0000000..8061de2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0035.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0035.wavetable
new file mode 100644
index 0000000..0ae0a5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0036.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0036.wav
new file mode 100644
index 0000000..6c5bc94
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0036.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0036.wavetable
new file mode 100644
index 0000000..04a8df6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0037.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0037.wav
new file mode 100644
index 0000000..b32b6a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0037.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0037.wavetable
new file mode 100644
index 0000000..d6b26fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0038.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0038.wav
new file mode 100644
index 0000000..07334c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0038.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0038.wavetable
new file mode 100644
index 0000000..e18187e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0039.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0039.wav
new file mode 100644
index 0000000..1239e2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0039.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0039.wavetable
new file mode 100644
index 0000000..feb56c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0040.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0040.wav
new file mode 100644
index 0000000..6b6617f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0040.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0040.wavetable
new file mode 100644
index 0000000..2d279b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0041.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0041.wav
new file mode 100644
index 0000000..51b9903
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0041.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0041.wavetable
new file mode 100644
index 0000000..470883bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0042.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0042.wav
new file mode 100644
index 0000000..42a4b11
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0042.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0042.wavetable
new file mode 100644
index 0000000..9faa515
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0043.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0043.wav
new file mode 100644
index 0000000..6c63881
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0043.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0043.wavetable
new file mode 100644
index 0000000..d32913d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0044.wav b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0044.wav
new file mode 100644
index 0000000..ec860e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0044.wavetable b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0044.wavetable
new file mode 100644
index 0000000..feab6bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_overtone/AKWF_overtone_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_overtone/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_overtone/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_overtone/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0001.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0001.wav
new file mode 100644
index 0000000..908cd25
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0001.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0001.wavetable
new file mode 100644
index 0000000..4919803
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0002.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0002.wav
new file mode 100644
index 0000000..6e70ab3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0002.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0002.wavetable
new file mode 100644
index 0000000..5bba09c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0003.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0003.wav
new file mode 100644
index 0000000..2bf6577
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0003.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0003.wavetable
new file mode 100644
index 0000000..e1ddab6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0004.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0004.wav
new file mode 100644
index 0000000..870130b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0004.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0004.wavetable
new file mode 100644
index 0000000..da993e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0005.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0005.wav
new file mode 100644
index 0000000..ce8bf19
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0005.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0005.wavetable
new file mode 100644
index 0000000..1a14754
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0006.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0006.wav
new file mode 100644
index 0000000..7f2c110
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0006.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0006.wavetable
new file mode 100644
index 0000000..b6aabaf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0007.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0007.wav
new file mode 100644
index 0000000..c4b4c26
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0007.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0007.wavetable
new file mode 100644
index 0000000..b6fb0a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0008.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0008.wav
new file mode 100644
index 0000000..62a72eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0008.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0008.wavetable
new file mode 100644
index 0000000..1aba204
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0009.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0009.wav
new file mode 100644
index 0000000..fffd901
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0009.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0009.wavetable
new file mode 100644
index 0000000..b79b8e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0010.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0010.wav
new file mode 100644
index 0000000..e2a62cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0010.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0010.wavetable
new file mode 100644
index 0000000..860021a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0011.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0011.wav
new file mode 100644
index 0000000..a31438d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0011.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0011.wavetable
new file mode 100644
index 0000000..d11fe49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0012.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0012.wav
new file mode 100644
index 0000000..3c2306d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0012.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0012.wavetable
new file mode 100644
index 0000000..1e6bea1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0013.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0013.wav
new file mode 100644
index 0000000..36ed465
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0013.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0013.wavetable
new file mode 100644
index 0000000..51379ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0014.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0014.wav
new file mode 100644
index 0000000..37148a8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0014.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0014.wavetable
new file mode 100644
index 0000000..48c268e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0015.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0015.wav
new file mode 100644
index 0000000..8a5c79b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0015.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0015.wavetable
new file mode 100644
index 0000000..d35fa54
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0016.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0016.wav
new file mode 100644
index 0000000..863af99
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0016.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0016.wavetable
new file mode 100644
index 0000000..da1480c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0017.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0017.wav
new file mode 100644
index 0000000..ce40584
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0017.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0017.wavetable
new file mode 100644
index 0000000..070e60f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0018.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0018.wav
new file mode 100644
index 0000000..3a5bc3d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0018.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0018.wavetable
new file mode 100644
index 0000000..4c6d37b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0019.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0019.wav
new file mode 100644
index 0000000..daa49bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0019.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0019.wavetable
new file mode 100644
index 0000000..5912e64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0020.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0020.wav
new file mode 100644
index 0000000..cfd8549
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0020.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0020.wavetable
new file mode 100644
index 0000000..116ce58
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0021.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0021.wav
new file mode 100644
index 0000000..8f8dabd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0021.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0021.wavetable
new file mode 100644
index 0000000..a35867a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0022.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0022.wav
new file mode 100644
index 0000000..73c9079
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0022.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0022.wavetable
new file mode 100644
index 0000000..7a9a8ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0023.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0023.wav
new file mode 100644
index 0000000..924113d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0023.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0023.wavetable
new file mode 100644
index 0000000..7499616
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0024.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0024.wav
new file mode 100644
index 0000000..7d5dfde
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0024.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0024.wavetable
new file mode 100644
index 0000000..834c7d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0025.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0025.wav
new file mode 100644
index 0000000..828423b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0025.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0025.wavetable
new file mode 100644
index 0000000..71f4531
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0026.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0026.wav
new file mode 100644
index 0000000..fe63660
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0026.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0026.wavetable
new file mode 100644
index 0000000..3d0b1e0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0027.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0027.wav
new file mode 100644
index 0000000..70a3d06
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0027.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0027.wavetable
new file mode 100644
index 0000000..726b953
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0028.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0028.wav
new file mode 100644
index 0000000..e5a07f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0028.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0028.wavetable
new file mode 100644
index 0000000..f0e7b91
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0029.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0029.wav
new file mode 100644
index 0000000..e44c7cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0029.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0029.wavetable
new file mode 100644
index 0000000..5a5976c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0030.wav b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0030.wav
new file mode 100644
index 0000000..2f2a7d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0030.wavetable b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0030.wavetable
new file mode 100644
index 0000000..4fa96f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_piano/AKWF_piano_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_piano/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_piano/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_piano/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0001.wav b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0001.wav
new file mode 100644
index 0000000..f6d4fd2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0001.wavetable b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0001.wavetable
new file mode 100644
index 0000000..59b8da6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0002.wav b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0002.wav
new file mode 100644
index 0000000..fc78254
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0002.wavetable b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0002.wavetable
new file mode 100644
index 0000000..26bdaff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0003.wav b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0003.wav
new file mode 100644
index 0000000..6d0ffee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0003.wavetable b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0003.wavetable
new file mode 100644
index 0000000..87a5603
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0004.wav b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0004.wav
new file mode 100644
index 0000000..a0d2d89
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0004.wavetable b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0004.wavetable
new file mode 100644
index 0000000..f0e6be0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0005.wav b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0005.wav
new file mode 100644
index 0000000..33ed224
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0005.wavetable b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0005.wavetable
new file mode 100644
index 0000000..3c9acb5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0006.wav b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0006.wav
new file mode 100644
index 0000000..eae6631
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0006.wavetable b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0006.wavetable
new file mode 100644
index 0000000..69187d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0007.wav b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0007.wav
new file mode 100644
index 0000000..a88ad42
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0007.wavetable b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0007.wavetable
new file mode 100644
index 0000000..1bc3af9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0008.wav b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0008.wav
new file mode 100644
index 0000000..86f04a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0008.wavetable b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0008.wavetable
new file mode 100644
index 0000000..10038ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0009.wav b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0009.wav
new file mode 100644
index 0000000..95f127f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0009.wavetable b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0009.wavetable
new file mode 100644
index 0000000..241919a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_pluckalgo/AKWF_pluckalgo_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_pluckalgo/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_pluckalgo/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_pluckalgo/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0001.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0001.wav
new file mode 100644
index 0000000..e9a6a7e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0001.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0001.wavetable
new file mode 100644
index 0000000..d03372c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0002.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0002.wav
new file mode 100644
index 0000000..9de2535
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0002.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0002.wavetable
new file mode 100644
index 0000000..4c2bf45
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0003.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0003.wav
new file mode 100644
index 0000000..85c938e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0003.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0003.wavetable
new file mode 100644
index 0000000..646ad03
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0004.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0004.wav
new file mode 100644
index 0000000..f57ef8a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0004.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0004.wavetable
new file mode 100644
index 0000000..b7d139e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0005.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0005.wav
new file mode 100644
index 0000000..edd4d20
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0005.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0005.wavetable
new file mode 100644
index 0000000..5e33428
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0006.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0006.wav
new file mode 100644
index 0000000..531dea5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0006.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0006.wavetable
new file mode 100644
index 0000000..2181137
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0007.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0007.wav
new file mode 100644
index 0000000..576ce88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0007.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0007.wavetable
new file mode 100644
index 0000000..ef02e9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0008.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0008.wav
new file mode 100644
index 0000000..a146c03
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0008.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0008.wavetable
new file mode 100644
index 0000000..36af3df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0009.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0009.wav
new file mode 100644
index 0000000..bd79d53
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0009.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0009.wavetable
new file mode 100644
index 0000000..8171853
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0010.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0010.wav
new file mode 100644
index 0000000..265d447
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0010.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0010.wavetable
new file mode 100644
index 0000000..afebadb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0011.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0011.wav
new file mode 100644
index 0000000..7eda60c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0011.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0011.wavetable
new file mode 100644
index 0000000..7202574
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0012.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0012.wav
new file mode 100644
index 0000000..cc58e0a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0012.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0012.wavetable
new file mode 100644
index 0000000..ddc9568
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0013.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0013.wav
new file mode 100644
index 0000000..b10803b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0013.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0013.wavetable
new file mode 100644
index 0000000..4b4e967
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0014.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0014.wav
new file mode 100644
index 0000000..e5c7d9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0014.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0014.wavetable
new file mode 100644
index 0000000..315977c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0015.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0015.wav
new file mode 100644
index 0000000..43945d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0015.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0015.wavetable
new file mode 100644
index 0000000..990b2ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0016.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0016.wav
new file mode 100644
index 0000000..1c19335
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0016.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0016.wavetable
new file mode 100644
index 0000000..660c4f8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0017.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0017.wav
new file mode 100644
index 0000000..7c3e8fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0017.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0017.wavetable
new file mode 100644
index 0000000..37b05cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0018.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0018.wav
new file mode 100644
index 0000000..0d5becf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0018.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0018.wavetable
new file mode 100644
index 0000000..7638d24
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0019.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0019.wav
new file mode 100644
index 0000000..ad5fccf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0019.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0019.wavetable
new file mode 100644
index 0000000..a929fbe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0020.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0020.wav
new file mode 100644
index 0000000..eaa2ad9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0020.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0020.wavetable
new file mode 100644
index 0000000..44c6e73
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0021.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0021.wav
new file mode 100644
index 0000000..27415ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0021.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0021.wavetable
new file mode 100644
index 0000000..9135aec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0022.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0022.wav
new file mode 100644
index 0000000..ba63d0a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0022.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0022.wavetable
new file mode 100644
index 0000000..83ed603
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0023.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0023.wav
new file mode 100644
index 0000000..7f10681
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0023.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0023.wavetable
new file mode 100644
index 0000000..8d05353
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0024.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0024.wav
new file mode 100644
index 0000000..0e606ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0024.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0024.wavetable
new file mode 100644
index 0000000..176f118
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0025.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0025.wav
new file mode 100644
index 0000000..3587643
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0025.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0025.wavetable
new file mode 100644
index 0000000..78e5685
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0026.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0026.wav
new file mode 100644
index 0000000..c0736eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0026.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0026.wavetable
new file mode 100644
index 0000000..0b32a16
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0027.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0027.wav
new file mode 100644
index 0000000..81a4963
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0027.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0027.wavetable
new file mode 100644
index 0000000..0cae0dd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0028.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0028.wav
new file mode 100644
index 0000000..a2dbb06
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0028.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0028.wavetable
new file mode 100644
index 0000000..67a83ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0029.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0029.wav
new file mode 100644
index 0000000..c6b61b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0029.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0029.wavetable
new file mode 100644
index 0000000..7520750
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0030.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0030.wav
new file mode 100644
index 0000000..875c4d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0030.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0030.wavetable
new file mode 100644
index 0000000..6af4bca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0031.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0031.wav
new file mode 100644
index 0000000..56b71da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0031.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0031.wavetable
new file mode 100644
index 0000000..21b9bd4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0032.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0032.wav
new file mode 100644
index 0000000..ae1eaf1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0032.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0032.wavetable
new file mode 100644
index 0000000..523dd9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0033.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0033.wav
new file mode 100644
index 0000000..fe39a3e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0033.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0033.wavetable
new file mode 100644
index 0000000..a8f1143
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0034.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0034.wav
new file mode 100644
index 0000000..49705e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0034.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0034.wavetable
new file mode 100644
index 0000000..0930794
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0035.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0035.wav
new file mode 100644
index 0000000..9614e8f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0035.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0035.wavetable
new file mode 100644
index 0000000..d470d2d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0036.wav b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0036.wav
new file mode 100644
index 0000000..ef2e550
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0036.wavetable b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0036.wavetable
new file mode 100644
index 0000000..1e21bee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_raw/AKWF_raw_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_raw/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_raw/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_raw/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0001.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0001.wav
new file mode 100644
index 0000000..10218b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0001.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0001.wavetable
new file mode 100644
index 0000000..14a3127
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0002.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0002.wav
new file mode 100644
index 0000000..ea2323d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0002.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0002.wavetable
new file mode 100644
index 0000000..770a2a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0003.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0003.wav
new file mode 100644
index 0000000..b5ce0b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0003.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0003.wavetable
new file mode 100644
index 0000000..0a9cb32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0004.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0004.wav
new file mode 100644
index 0000000..0c38f21
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0004.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0004.wavetable
new file mode 100644
index 0000000..7c2d1d6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0005.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0005.wav
new file mode 100644
index 0000000..29b4556
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0005.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0005.wavetable
new file mode 100644
index 0000000..0037435
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0006.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0006.wav
new file mode 100644
index 0000000..fd03140
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0006.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0006.wavetable
new file mode 100644
index 0000000..98be815
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0007.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0007.wav
new file mode 100644
index 0000000..66789ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0007.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0007.wavetable
new file mode 100644
index 0000000..4f31c0a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0008.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0008.wav
new file mode 100644
index 0000000..ec14631
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0008.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0008.wavetable
new file mode 100644
index 0000000..8cb1a82
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0009.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0009.wav
new file mode 100644
index 0000000..8abf2b2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0009.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0009.wavetable
new file mode 100644
index 0000000..c6f137a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0010.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0010.wav
new file mode 100644
index 0000000..2799bba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0010.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0010.wavetable
new file mode 100644
index 0000000..a28a76e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0011.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0011.wav
new file mode 100644
index 0000000..bec03db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0011.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0011.wavetable
new file mode 100644
index 0000000..604a3cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0012.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0012.wav
new file mode 100644
index 0000000..bf20fb4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0012.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0012.wavetable
new file mode 100644
index 0000000..f18c03a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0013.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0013.wav
new file mode 100644
index 0000000..9970344
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0013.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0013.wavetable
new file mode 100644
index 0000000..360c215
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0014.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0014.wav
new file mode 100644
index 0000000..1300558
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0014.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0014.wavetable
new file mode 100644
index 0000000..e563c32
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0015.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0015.wav
new file mode 100644
index 0000000..e917a10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0015.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0015.wavetable
new file mode 100644
index 0000000..5be5d5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0016.wav b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0016.wav
new file mode 100644
index 0000000..5b499c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0016.wavetable b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0016.wavetable
new file mode 100644
index 0000000..11f0c2a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_sinharm/AKWF_sinharm_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_sinharm/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_sinharm/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_sinharm/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0001.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0001.wav
new file mode 100644
index 0000000..8c1fd86
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0001.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0001.wavetable
new file mode 100644
index 0000000..740a57d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0002.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0002.wav
new file mode 100644
index 0000000..8d934f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0002.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0002.wavetable
new file mode 100644
index 0000000..cd90571
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0003.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0003.wav
new file mode 100644
index 0000000..a7fba3f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0003.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0003.wavetable
new file mode 100644
index 0000000..88ad123
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0004.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0004.wav
new file mode 100644
index 0000000..43f1f6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0004.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0004.wavetable
new file mode 100644
index 0000000..1a97521
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0005.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0005.wav
new file mode 100644
index 0000000..eea7776
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0005.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0005.wavetable
new file mode 100644
index 0000000..29a16f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0006.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0006.wav
new file mode 100644
index 0000000..df9b41f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0006.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0006.wavetable
new file mode 100644
index 0000000..5752efd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0007.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0007.wav
new file mode 100644
index 0000000..3ceb846
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0007.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0007.wavetable
new file mode 100644
index 0000000..98e7e21
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0008.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0008.wav
new file mode 100644
index 0000000..275589d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0008.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0008.wavetable
new file mode 100644
index 0000000..6ad9b2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0009.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0009.wav
new file mode 100644
index 0000000..3b1eeaa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0009.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0009.wavetable
new file mode 100644
index 0000000..38e50ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0010.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0010.wav
new file mode 100644
index 0000000..a9de803
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0010.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0010.wavetable
new file mode 100644
index 0000000..edbe6d0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0011.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0011.wav
new file mode 100644
index 0000000..49f6385
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0011.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0011.wavetable
new file mode 100644
index 0000000..59e50fd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0012.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0012.wav
new file mode 100644
index 0000000..aaa1ae7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0012.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0012.wavetable
new file mode 100644
index 0000000..480e089
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0013.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0013.wav
new file mode 100644
index 0000000..2e1ebb7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0013.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0013.wavetable
new file mode 100644
index 0000000..77a968b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0014.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0014.wav
new file mode 100644
index 0000000..6ef8dc0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0014.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0014.wavetable
new file mode 100644
index 0000000..9e516ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0015.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0015.wav
new file mode 100644
index 0000000..310b7e7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0015.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0015.wavetable
new file mode 100644
index 0000000..8dc2144
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0016.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0016.wav
new file mode 100644
index 0000000..d898fdc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0016.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0016.wavetable
new file mode 100644
index 0000000..1df0549
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0017.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0017.wav
new file mode 100644
index 0000000..8297d2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0017.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0017.wavetable
new file mode 100644
index 0000000..9005eeb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0018.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0018.wav
new file mode 100644
index 0000000..2532e22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0018.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0018.wavetable
new file mode 100644
index 0000000..989a677
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0019.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0019.wav
new file mode 100644
index 0000000..8287526
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0019.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0019.wavetable
new file mode 100644
index 0000000..6c16807
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0020.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0020.wav
new file mode 100644
index 0000000..ea75ea3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0020.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0020.wavetable
new file mode 100644
index 0000000..9ad8a05
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0021.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0021.wav
new file mode 100644
index 0000000..b46e906
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0021.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0021.wavetable
new file mode 100644
index 0000000..8884f44
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0022.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0022.wav
new file mode 100644
index 0000000..b3b838b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0022.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0022.wavetable
new file mode 100644
index 0000000..f2d0021
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0023.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0023.wav
new file mode 100644
index 0000000..d82937f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0023.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0023.wavetable
new file mode 100644
index 0000000..b2be164
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0024.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0024.wav
new file mode 100644
index 0000000..ecfb46f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0024.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0024.wavetable
new file mode 100644
index 0000000..a4e8df8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0025.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0025.wav
new file mode 100644
index 0000000..87e7320
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0025.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0025.wavetable
new file mode 100644
index 0000000..464d1a6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0026.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0026.wav
new file mode 100644
index 0000000..6a6858e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0026.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0026.wavetable
new file mode 100644
index 0000000..c13a6ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0027.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0027.wav
new file mode 100644
index 0000000..7739a70
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0027.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0027.wavetable
new file mode 100644
index 0000000..e6812ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0028.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0028.wav
new file mode 100644
index 0000000..121a834
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0028.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0028.wavetable
new file mode 100644
index 0000000..8641504
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0029.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0029.wav
new file mode 100644
index 0000000..0ffe21a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0029.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0029.wavetable
new file mode 100644
index 0000000..a9f1c82
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0030.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0030.wav
new file mode 100644
index 0000000..edf86ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0030.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0030.wavetable
new file mode 100644
index 0000000..46b61f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0031.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0031.wav
new file mode 100644
index 0000000..fd9cfdf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0031.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0031.wavetable
new file mode 100644
index 0000000..11b1966
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0032.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0032.wav
new file mode 100644
index 0000000..6db6d88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0032.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0032.wavetable
new file mode 100644
index 0000000..9632aba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0033.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0033.wav
new file mode 100644
index 0000000..c268906
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0033.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0033.wavetable
new file mode 100644
index 0000000..ed3cb77
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0034.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0034.wav
new file mode 100644
index 0000000..e85f1cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0034.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0034.wavetable
new file mode 100644
index 0000000..3e23c18
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0035.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0035.wav
new file mode 100644
index 0000000..e32721e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0035.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0035.wavetable
new file mode 100644
index 0000000..a50c690
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0036.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0036.wav
new file mode 100644
index 0000000..5d9feac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0036.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0036.wavetable
new file mode 100644
index 0000000..350dcb2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0037.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0037.wav
new file mode 100644
index 0000000..199323d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0037.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0037.wavetable
new file mode 100644
index 0000000..f5038b9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0038.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0038.wav
new file mode 100644
index 0000000..ec029c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0038.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0038.wavetable
new file mode 100644
index 0000000..5ea7c66
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0039.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0039.wav
new file mode 100644
index 0000000..1dafe60
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0039.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0039.wavetable
new file mode 100644
index 0000000..8a75c25
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0040.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0040.wav
new file mode 100644
index 0000000..3c59e9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0040.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0040.wavetable
new file mode 100644
index 0000000..42e320a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0041.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0041.wav
new file mode 100644
index 0000000..6ee1c4e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0041.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0041.wavetable
new file mode 100644
index 0000000..f33fe53
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0042.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0042.wav
new file mode 100644
index 0000000..36cb056
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0042.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0042.wavetable
new file mode 100644
index 0000000..09c957e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0043.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0043.wav
new file mode 100644
index 0000000..9a9c4a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0043.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0043.wavetable
new file mode 100644
index 0000000..8410cd4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0044.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0044.wav
new file mode 100644
index 0000000..6bac1db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0044.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0044.wavetable
new file mode 100644
index 0000000..e044237
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0045.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0045.wav
new file mode 100644
index 0000000..31b80ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0045.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0045.wavetable
new file mode 100644
index 0000000..1d10cb4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0046.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0046.wav
new file mode 100644
index 0000000..bb17065
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0046.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0046.wavetable
new file mode 100644
index 0000000..2bc640a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0047.wav b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0047.wav
new file mode 100644
index 0000000..6f97453
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0047.wavetable b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0047.wavetable
new file mode 100644
index 0000000..277983a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_snippets/AKWF_snippet_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_snippets/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_snippets/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_snippets/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0001.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0001.wav
new file mode 100644
index 0000000..242d8ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0001.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0001.wavetable
new file mode 100644
index 0000000..e55ec74
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0002.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0002.wav
new file mode 100644
index 0000000..317c19d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0002.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0002.wavetable
new file mode 100644
index 0000000..47ffaaa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0003.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0003.wav
new file mode 100644
index 0000000..9d227c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0003.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0003.wavetable
new file mode 100644
index 0000000..ad22db4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0004.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0004.wav
new file mode 100644
index 0000000..fbeddeb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0004.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0004.wavetable
new file mode 100644
index 0000000..ccad429
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0005.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0005.wav
new file mode 100644
index 0000000..5dda0d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0005.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0005.wavetable
new file mode 100644
index 0000000..5da6f70
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0006.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0006.wav
new file mode 100644
index 0000000..07122bd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0006.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0006.wavetable
new file mode 100644
index 0000000..a76107f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0007.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0007.wav
new file mode 100644
index 0000000..c6f3394
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0007.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0007.wavetable
new file mode 100644
index 0000000..7bb9b16
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0008.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0008.wav
new file mode 100644
index 0000000..0dca23d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0008.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0008.wavetable
new file mode 100644
index 0000000..498ce8e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0009.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0009.wav
new file mode 100644
index 0000000..e0faf41
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0009.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0009.wavetable
new file mode 100644
index 0000000..6f8b92d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0010.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0010.wav
new file mode 100644
index 0000000..4aaa11a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0010.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0010.wavetable
new file mode 100644
index 0000000..a49095d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0011.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0011.wav
new file mode 100644
index 0000000..3ea50cd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0011.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0011.wavetable
new file mode 100644
index 0000000..5270814
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0012.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0012.wav
new file mode 100644
index 0000000..8b08673
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0012.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0012.wavetable
new file mode 100644
index 0000000..0c151ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0013.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0013.wav
new file mode 100644
index 0000000..20d9007
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0013.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0013.wavetable
new file mode 100644
index 0000000..a41dfe8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0014.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0014.wav
new file mode 100644
index 0000000..a328685
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0014.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0014.wavetable
new file mode 100644
index 0000000..4e0f86c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0015.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0015.wav
new file mode 100644
index 0000000..5482221
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0015.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0015.wavetable
new file mode 100644
index 0000000..78c26f8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0016.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0016.wav
new file mode 100644
index 0000000..01e8e5e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0016.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0016.wavetable
new file mode 100644
index 0000000..87508e2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0017.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0017.wav
new file mode 100644
index 0000000..f99fd03
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0017.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0017.wavetable
new file mode 100644
index 0000000..18c64f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0018.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0018.wav
new file mode 100644
index 0000000..0de5d98
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0018.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0018.wavetable
new file mode 100644
index 0000000..0118891
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0019.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0019.wav
new file mode 100644
index 0000000..4b9efa5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0019.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0019.wavetable
new file mode 100644
index 0000000..744275b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0020.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0020.wav
new file mode 100644
index 0000000..3aced0f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0020.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0020.wavetable
new file mode 100644
index 0000000..c26ce19
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0021.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0021.wav
new file mode 100644
index 0000000..d691c4d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0021.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0021.wavetable
new file mode 100644
index 0000000..d1eda11
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0022.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0022.wav
new file mode 100644
index 0000000..a0dad76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0022.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0022.wavetable
new file mode 100644
index 0000000..d6a2563
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0023.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0023.wav
new file mode 100644
index 0000000..b1f7f1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0023.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0023.wavetable
new file mode 100644
index 0000000..064f250
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0024.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0024.wav
new file mode 100644
index 0000000..ce607b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0024.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0024.wavetable
new file mode 100644
index 0000000..29ad19b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0025.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0025.wav
new file mode 100644
index 0000000..c8d7d55
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0025.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0025.wavetable
new file mode 100644
index 0000000..313127a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0026.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0026.wav
new file mode 100644
index 0000000..12925a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0026.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0026.wavetable
new file mode 100644
index 0000000..40ccf31
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0027.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0027.wav
new file mode 100644
index 0000000..c499f1f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0027.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0027.wavetable
new file mode 100644
index 0000000..a4d6fd2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0028.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0028.wav
new file mode 100644
index 0000000..97e5c33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0028.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0028.wavetable
new file mode 100644
index 0000000..d8e5621
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0029.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0029.wav
new file mode 100644
index 0000000..1d545b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0029.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0029.wavetable
new file mode 100644
index 0000000..9458135
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0030.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0030.wav
new file mode 100644
index 0000000..831af0a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0030.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0030.wavetable
new file mode 100644
index 0000000..922264c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0031.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0031.wav
new file mode 100644
index 0000000..4c8a963
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0031.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0031.wavetable
new file mode 100644
index 0000000..5b08514
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0032.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0032.wav
new file mode 100644
index 0000000..bbbb854
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0032.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0032.wavetable
new file mode 100644
index 0000000..ac0af3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0033.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0033.wav
new file mode 100644
index 0000000..387a59d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0033.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0033.wavetable
new file mode 100644
index 0000000..9537696
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0034.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0034.wav
new file mode 100644
index 0000000..cb9439a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0034.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0034.wavetable
new file mode 100644
index 0000000..484399f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0035.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0035.wav
new file mode 100644
index 0000000..f106e7d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0035.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0035.wavetable
new file mode 100644
index 0000000..1342855
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0036.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0036.wav
new file mode 100644
index 0000000..e41b0ff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0036.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0036.wavetable
new file mode 100644
index 0000000..bf60274
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0037.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0037.wav
new file mode 100644
index 0000000..5fffe1e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0037.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0037.wavetable
new file mode 100644
index 0000000..ee7eed4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0038.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0038.wav
new file mode 100644
index 0000000..4404eae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0038.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0038.wavetable
new file mode 100644
index 0000000..b306482
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0039.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0039.wav
new file mode 100644
index 0000000..d4d3eb4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0039.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0039.wavetable
new file mode 100644
index 0000000..3697b1c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0040.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0040.wav
new file mode 100644
index 0000000..fd7a9ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0040.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0040.wavetable
new file mode 100644
index 0000000..58c5d45
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0041.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0041.wav
new file mode 100644
index 0000000..63d842f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0041.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0041.wavetable
new file mode 100644
index 0000000..6c0a402
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0042.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0042.wav
new file mode 100644
index 0000000..2ec6724
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0042.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0042.wavetable
new file mode 100644
index 0000000..993c187
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0043.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0043.wav
new file mode 100644
index 0000000..755670d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0043.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0043.wavetable
new file mode 100644
index 0000000..8bfcc59
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0044.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0044.wav
new file mode 100644
index 0000000..87de204
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0044.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0044.wavetable
new file mode 100644
index 0000000..c748e3f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0045.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0045.wav
new file mode 100644
index 0000000..677b941
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0045.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0045.wavetable
new file mode 100644
index 0000000..bc93973
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0046.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0046.wav
new file mode 100644
index 0000000..ad04e76
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0046.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0046.wavetable
new file mode 100644
index 0000000..45bf143
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0047.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0047.wav
new file mode 100644
index 0000000..54a7231
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0047.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0047.wavetable
new file mode 100644
index 0000000..6bb21aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0048.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0048.wav
new file mode 100644
index 0000000..1bea3af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0048.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0048.wavetable
new file mode 100644
index 0000000..8f694b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0049.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0049.wav
new file mode 100644
index 0000000..ef5b627
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0049.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0049.wavetable
new file mode 100644
index 0000000..c7fa6a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0050.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0050.wav
new file mode 100644
index 0000000..b5c485d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0050.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0050.wavetable
new file mode 100644
index 0000000..8d1c10b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0051.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0051.wav
new file mode 100644
index 0000000..1aaf148
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0051.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0051.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0051.wavetable
new file mode 100644
index 0000000..8b84015
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0051.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0052.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0052.wav
new file mode 100644
index 0000000..dddf73e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0052.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0052.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0052.wavetable
new file mode 100644
index 0000000..c5f058f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0052.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0053.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0053.wav
new file mode 100644
index 0000000..5a47c10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0053.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0053.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0053.wavetable
new file mode 100644
index 0000000..5d1faa7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0053.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0054.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0054.wav
new file mode 100644
index 0000000..9a5f4e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0054.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0054.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0054.wavetable
new file mode 100644
index 0000000..2e1c999
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0054.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0055.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0055.wav
new file mode 100644
index 0000000..9fb097f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0055.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0055.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0055.wavetable
new file mode 100644
index 0000000..c3a23d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0055.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0056.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0056.wav
new file mode 100644
index 0000000..e3c9ebf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0056.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0056.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0056.wavetable
new file mode 100644
index 0000000..2d17ab2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0056.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0057.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0057.wav
new file mode 100644
index 0000000..bc1157f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0057.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0057.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0057.wavetable
new file mode 100644
index 0000000..9da6fc7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0057.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0058.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0058.wav
new file mode 100644
index 0000000..724daaa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0058.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0058.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0058.wavetable
new file mode 100644
index 0000000..3a4053c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0058.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0059.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0059.wav
new file mode 100644
index 0000000..2a42e70
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0059.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0059.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0059.wavetable
new file mode 100644
index 0000000..10ca2a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0059.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0060.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0060.wav
new file mode 100644
index 0000000..4a4200f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0060.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0060.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0060.wavetable
new file mode 100644
index 0000000..d7fa569
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0060.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0061.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0061.wav
new file mode 100644
index 0000000..716a130
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0061.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0061.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0061.wavetable
new file mode 100644
index 0000000..06814ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0061.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0062.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0062.wav
new file mode 100644
index 0000000..3e56674
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0062.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0062.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0062.wavetable
new file mode 100644
index 0000000..926fe05
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0062.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0063.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0063.wav
new file mode 100644
index 0000000..7efd828
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0063.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0063.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0063.wavetable
new file mode 100644
index 0000000..9aa8c3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0063.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0064.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0064.wav
new file mode 100644
index 0000000..98897ce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0064.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0064.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0064.wavetable
new file mode 100644
index 0000000..ec6f0a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0064.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0065.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0065.wav
new file mode 100644
index 0000000..38c0530
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0065.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0065.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0065.wavetable
new file mode 100644
index 0000000..86de3e2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0065.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0066.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0066.wav
new file mode 100644
index 0000000..f497f7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0066.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0066.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0066.wavetable
new file mode 100644
index 0000000..db96561
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0066.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0067.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0067.wav
new file mode 100644
index 0000000..82399d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0067.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0067.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0067.wavetable
new file mode 100644
index 0000000..8785ea5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0067.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0068.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0068.wav
new file mode 100644
index 0000000..481d79c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0068.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0068.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0068.wavetable
new file mode 100644
index 0000000..7fd7eca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0068.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0069.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0069.wav
new file mode 100644
index 0000000..21640aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0069.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0069.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0069.wavetable
new file mode 100644
index 0000000..fb2f491
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0069.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0070.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0070.wav
new file mode 100644
index 0000000..b87c631
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0070.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0070.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0070.wavetable
new file mode 100644
index 0000000..1d00ea0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0070.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0071.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0071.wav
new file mode 100644
index 0000000..25b1987
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0071.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0071.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0071.wavetable
new file mode 100644
index 0000000..22a2575
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0071.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0072.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0072.wav
new file mode 100644
index 0000000..c5ec828
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0072.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0072.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0072.wavetable
new file mode 100644
index 0000000..d007cef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0072.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0073.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0073.wav
new file mode 100644
index 0000000..c782892
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0073.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0073.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0073.wavetable
new file mode 100644
index 0000000..701f1a7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0073.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0074.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0074.wav
new file mode 100644
index 0000000..6d5242d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0074.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0074.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0074.wavetable
new file mode 100644
index 0000000..3f44141
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0074.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0075.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0075.wav
new file mode 100644
index 0000000..c744b8f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0075.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0075.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0075.wavetable
new file mode 100644
index 0000000..8b1fde0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0075.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0076.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0076.wav
new file mode 100644
index 0000000..965787a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0076.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0076.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0076.wavetable
new file mode 100644
index 0000000..9094275
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0076.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0077.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0077.wav
new file mode 100644
index 0000000..1ca15eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0077.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0077.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0077.wavetable
new file mode 100644
index 0000000..3f75a07
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0077.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0078.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0078.wav
new file mode 100644
index 0000000..6954791
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0078.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0078.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0078.wavetable
new file mode 100644
index 0000000..42c94c4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0078.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0079.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0079.wav
new file mode 100644
index 0000000..0f10ac4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0079.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0079.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0079.wavetable
new file mode 100644
index 0000000..3acac2c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0079.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0080.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0080.wav
new file mode 100644
index 0000000..db37b69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0080.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0080.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0080.wavetable
new file mode 100644
index 0000000..aaae5b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0080.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0081.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0081.wav
new file mode 100644
index 0000000..2735c5c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0081.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0081.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0081.wavetable
new file mode 100644
index 0000000..3b9a456
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0081.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0082.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0082.wav
new file mode 100644
index 0000000..0dfe554
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0082.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0082.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0082.wavetable
new file mode 100644
index 0000000..3348aac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0082.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0083.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0083.wav
new file mode 100644
index 0000000..bcb3dc7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0083.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0083.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0083.wavetable
new file mode 100644
index 0000000..6f1bc23
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0083.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0084.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0084.wav
new file mode 100644
index 0000000..a716053
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0084.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0084.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0084.wavetable
new file mode 100644
index 0000000..daa5dcc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0084.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0085.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0085.wav
new file mode 100644
index 0000000..d7db843
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0085.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0085.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0085.wavetable
new file mode 100644
index 0000000..1d03e2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0085.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0086.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0086.wav
new file mode 100644
index 0000000..25dc94d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0086.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0086.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0086.wavetable
new file mode 100644
index 0000000..c8878e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0086.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0087.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0087.wav
new file mode 100644
index 0000000..9d662b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0087.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0087.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0087.wavetable
new file mode 100644
index 0000000..d94ca72
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0087.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0088.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0088.wav
new file mode 100644
index 0000000..a019c31
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0088.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0088.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0088.wavetable
new file mode 100644
index 0000000..b6dea96
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0088.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0089.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0089.wav
new file mode 100644
index 0000000..626295c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0089.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0089.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0089.wavetable
new file mode 100644
index 0000000..e3e06ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0089.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0090.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0090.wav
new file mode 100644
index 0000000..c35effa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0090.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0090.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0090.wavetable
new file mode 100644
index 0000000..ccb1023
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0090.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0091.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0091.wav
new file mode 100644
index 0000000..afce2ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0091.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0091.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0091.wavetable
new file mode 100644
index 0000000..c210fbe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0091.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0092.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0092.wav
new file mode 100644
index 0000000..7d9ff34
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0092.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0092.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0092.wavetable
new file mode 100644
index 0000000..b77fde2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0092.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0093.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0093.wav
new file mode 100644
index 0000000..872f9c8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0093.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0093.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0093.wavetable
new file mode 100644
index 0000000..e82c426
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0093.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0094.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0094.wav
new file mode 100644
index 0000000..8aef1c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0094.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0094.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0094.wavetable
new file mode 100644
index 0000000..051f848
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0094.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0095.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0095.wav
new file mode 100644
index 0000000..e50e6fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0095.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0095.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0095.wavetable
new file mode 100644
index 0000000..a3a34a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0095.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0096.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0096.wav
new file mode 100644
index 0000000..5a4a3ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0096.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0096.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0096.wavetable
new file mode 100644
index 0000000..b22936f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0096.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0097.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0097.wav
new file mode 100644
index 0000000..d6694c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0097.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0097.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0097.wavetable
new file mode 100644
index 0000000..a7ed467
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0097.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0098.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0098.wav
new file mode 100644
index 0000000..7506e02
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0098.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0098.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0098.wavetable
new file mode 100644
index 0000000..91afbb5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0098.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0099.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0099.wav
new file mode 100644
index 0000000..f14af83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0099.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0099.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0099.wavetable
new file mode 100644
index 0000000..451a71e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0099.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0100.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0100.wav
new file mode 100644
index 0000000..d8f9aca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0100.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0100.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0100.wavetable
new file mode 100644
index 0000000..8969fbc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0100.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0101.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0101.wav
new file mode 100644
index 0000000..5da93ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0101.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0101.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0101.wavetable
new file mode 100644
index 0000000..7e01c97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0101.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0102.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0102.wav
new file mode 100644
index 0000000..7fdf6fc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0102.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0102.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0102.wavetable
new file mode 100644
index 0000000..893c35b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0102.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0103.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0103.wav
new file mode 100644
index 0000000..21af608
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0103.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0103.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0103.wavetable
new file mode 100644
index 0000000..ad03df3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0103.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0104.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0104.wav
new file mode 100644
index 0000000..4433898
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0104.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0104.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0104.wavetable
new file mode 100644
index 0000000..48cd950
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0104.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0105.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0105.wav
new file mode 100644
index 0000000..699250b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0105.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0105.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0105.wavetable
new file mode 100644
index 0000000..4b424f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0105.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0106.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0106.wav
new file mode 100644
index 0000000..2cea971
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0106.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0106.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0106.wavetable
new file mode 100644
index 0000000..1b65ba7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0106.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0107.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0107.wav
new file mode 100644
index 0000000..b4cf569
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0107.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0107.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0107.wavetable
new file mode 100644
index 0000000..e5c9ae8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0107.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0108.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0108.wav
new file mode 100644
index 0000000..ff98a83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0108.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0108.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0108.wavetable
new file mode 100644
index 0000000..e90ffbc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0108.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0109.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0109.wav
new file mode 100644
index 0000000..1eed160
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0109.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0109.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0109.wavetable
new file mode 100644
index 0000000..45d1e81
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0109.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0110.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0110.wav
new file mode 100644
index 0000000..cc24920
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0110.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0110.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0110.wavetable
new file mode 100644
index 0000000..c3d92ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0110.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0111.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0111.wav
new file mode 100644
index 0000000..8441317
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0111.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0111.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0111.wavetable
new file mode 100644
index 0000000..e871547
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0111.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0112.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0112.wav
new file mode 100644
index 0000000..a4d0d0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0112.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0112.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0112.wavetable
new file mode 100644
index 0000000..bd35cf5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0112.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0113.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0113.wav
new file mode 100644
index 0000000..a1a34ec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0113.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0113.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0113.wavetable
new file mode 100644
index 0000000..8919b31
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0113.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0114.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0114.wav
new file mode 100644
index 0000000..194c5b4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0114.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0114.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0114.wavetable
new file mode 100644
index 0000000..0f1f643
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0114.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0115.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0115.wav
new file mode 100644
index 0000000..a8b0b2c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0115.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0115.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0115.wavetable
new file mode 100644
index 0000000..d6cf542
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0115.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0116.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0116.wav
new file mode 100644
index 0000000..9f58a82
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0116.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0116.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0116.wavetable
new file mode 100644
index 0000000..7c0cc80
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0116.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0117.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0117.wav
new file mode 100644
index 0000000..8f1fca6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0117.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0117.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0117.wavetable
new file mode 100644
index 0000000..005088a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0117.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0118.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0118.wav
new file mode 100644
index 0000000..d7b1c2d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0118.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0118.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0118.wavetable
new file mode 100644
index 0000000..4e7bf4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0118.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0119.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0119.wav
new file mode 100644
index 0000000..fc43b27
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0119.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0119.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0119.wavetable
new file mode 100644
index 0000000..ffd9f7b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0119.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0120.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0120.wav
new file mode 100644
index 0000000..8cc4b7b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0120.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0120.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0120.wavetable
new file mode 100644
index 0000000..0b4a9b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0120.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0121.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0121.wav
new file mode 100644
index 0000000..00e5535
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0121.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0121.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0121.wavetable
new file mode 100644
index 0000000..a3e5401
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0121.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0122.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0122.wav
new file mode 100644
index 0000000..014ea6d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0122.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0122.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0122.wavetable
new file mode 100644
index 0000000..bea2b07
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0122.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0123.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0123.wav
new file mode 100644
index 0000000..b408717
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0123.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0123.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0123.wavetable
new file mode 100644
index 0000000..b6dd1ab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0123.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0124.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0124.wav
new file mode 100644
index 0000000..51d19fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0124.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0124.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0124.wavetable
new file mode 100644
index 0000000..2d33b59
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0124.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0125.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0125.wav
new file mode 100644
index 0000000..c75ca4e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0125.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0125.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0125.wavetable
new file mode 100644
index 0000000..bdd901a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0125.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0126.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0126.wav
new file mode 100644
index 0000000..44d5ef8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0126.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0126.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0126.wavetable
new file mode 100644
index 0000000..91f6cdd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0126.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0127.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0127.wav
new file mode 100644
index 0000000..556111e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0127.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0127.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0127.wavetable
new file mode 100644
index 0000000..f226494
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0127.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0128.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0128.wav
new file mode 100644
index 0000000..6bed145
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0128.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0128.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0128.wavetable
new file mode 100644
index 0000000..72fc0e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0128.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0129.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0129.wav
new file mode 100644
index 0000000..568e13b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0129.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0129.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0129.wavetable
new file mode 100644
index 0000000..0a34a10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0129.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0130.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0130.wav
new file mode 100644
index 0000000..19450fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0130.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0130.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0130.wavetable
new file mode 100644
index 0000000..e8f9a0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0130.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0131.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0131.wav
new file mode 100644
index 0000000..621dde4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0131.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0131.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0131.wavetable
new file mode 100644
index 0000000..976a8f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0131.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0132.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0132.wav
new file mode 100644
index 0000000..f805f23
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0132.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0132.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0132.wavetable
new file mode 100644
index 0000000..e4040b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0132.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0133.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0133.wav
new file mode 100644
index 0000000..f9417ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0133.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0133.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0133.wavetable
new file mode 100644
index 0000000..7c30cc3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0133.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0134.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0134.wav
new file mode 100644
index 0000000..e1166f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0134.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0134.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0134.wavetable
new file mode 100644
index 0000000..7d0098d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0134.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0135.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0135.wav
new file mode 100644
index 0000000..135952b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0135.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0135.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0135.wavetable
new file mode 100644
index 0000000..fb3999f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0135.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0136.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0136.wav
new file mode 100644
index 0000000..9e59e78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0136.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0136.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0136.wavetable
new file mode 100644
index 0000000..7e5f81e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0136.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0137.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0137.wav
new file mode 100644
index 0000000..b0c4515
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0137.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0137.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0137.wavetable
new file mode 100644
index 0000000..a8d9bd9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0137.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0138.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0138.wav
new file mode 100644
index 0000000..3221809
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0138.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0138.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0138.wavetable
new file mode 100644
index 0000000..d7f21f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0138.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0139.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0139.wav
new file mode 100644
index 0000000..ab311c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0139.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0139.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0139.wavetable
new file mode 100644
index 0000000..82b0dec
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0139.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0140.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0140.wav
new file mode 100644
index 0000000..74b813b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0140.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0140.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0140.wavetable
new file mode 100644
index 0000000..119f156
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0140.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0141.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0141.wav
new file mode 100644
index 0000000..26e3a1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0141.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0141.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0141.wavetable
new file mode 100644
index 0000000..95ace98
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0141.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0142.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0142.wav
new file mode 100644
index 0000000..a09adb4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0142.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0142.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0142.wavetable
new file mode 100644
index 0000000..232fbf8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0142.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0143.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0143.wav
new file mode 100644
index 0000000..ade8828
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0143.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0143.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0143.wavetable
new file mode 100644
index 0000000..4b3618b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0143.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0144.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0144.wav
new file mode 100644
index 0000000..177ee57
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0144.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0144.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0144.wavetable
new file mode 100644
index 0000000..01d5268
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0144.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0145.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0145.wav
new file mode 100644
index 0000000..37261f1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0145.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0145.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0145.wavetable
new file mode 100644
index 0000000..b28ce97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0145.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0146.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0146.wav
new file mode 100644
index 0000000..ca91c9c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0146.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0146.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0146.wavetable
new file mode 100644
index 0000000..b975a02
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0146.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0147.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0147.wav
new file mode 100644
index 0000000..ceb2f23
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0147.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0147.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0147.wavetable
new file mode 100644
index 0000000..633922f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0147.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0148.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0148.wav
new file mode 100644
index 0000000..e0ef58a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0148.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0148.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0148.wavetable
new file mode 100644
index 0000000..d2592af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0148.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0149.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0149.wav
new file mode 100644
index 0000000..7f09ff7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0149.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0149.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0149.wavetable
new file mode 100644
index 0000000..e3da015
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0149.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0150.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0150.wav
new file mode 100644
index 0000000..469aeea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0150.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0150.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0150.wavetable
new file mode 100644
index 0000000..6320670
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0150.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0151.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0151.wav
new file mode 100644
index 0000000..584630d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0151.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0151.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0151.wavetable
new file mode 100644
index 0000000..449dc29
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0151.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0152.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0152.wav
new file mode 100644
index 0000000..83b5fc3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0152.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0152.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0152.wavetable
new file mode 100644
index 0000000..c1c6d9b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0152.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0153.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0153.wav
new file mode 100644
index 0000000..6591419
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0153.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0153.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0153.wavetable
new file mode 100644
index 0000000..fb048ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0153.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0154.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0154.wav
new file mode 100644
index 0000000..bfb739c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0154.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0154.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0154.wavetable
new file mode 100644
index 0000000..55a8b41
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0154.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0155.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0155.wav
new file mode 100644
index 0000000..8562455
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0155.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0155.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0155.wavetable
new file mode 100644
index 0000000..2dfcbe0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0155.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0156.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0156.wav
new file mode 100644
index 0000000..7d87b6f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0156.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0156.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0156.wavetable
new file mode 100644
index 0000000..32f6bf0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0156.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0157.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0157.wav
new file mode 100644
index 0000000..5b17037
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0157.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0157.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0157.wavetable
new file mode 100644
index 0000000..adec54f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0157.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0158.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0158.wav
new file mode 100644
index 0000000..ba576a3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0158.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0158.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0158.wavetable
new file mode 100644
index 0000000..cc6b23a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0158.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0159.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0159.wav
new file mode 100644
index 0000000..50e85d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0159.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0159.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0159.wavetable
new file mode 100644
index 0000000..e32019e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0159.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0160.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0160.wav
new file mode 100644
index 0000000..c918efa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0160.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0160.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0160.wavetable
new file mode 100644
index 0000000..ed0a035
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0160.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0161.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0161.wav
new file mode 100644
index 0000000..c1370bc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0161.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0161.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0161.wavetable
new file mode 100644
index 0000000..5d9b52b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0161.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0162.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0162.wav
new file mode 100644
index 0000000..ad4c1e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0162.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0162.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0162.wavetable
new file mode 100644
index 0000000..68f5d7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0162.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0163.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0163.wav
new file mode 100644
index 0000000..e75bbb9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0163.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0163.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0163.wavetable
new file mode 100644
index 0000000..bf93859
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0163.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0164.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0164.wav
new file mode 100644
index 0000000..2a987f7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0164.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0164.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0164.wavetable
new file mode 100644
index 0000000..320e041
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0164.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0165.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0165.wav
new file mode 100644
index 0000000..fc339fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0165.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0165.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0165.wavetable
new file mode 100644
index 0000000..2e658a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0165.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0166.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0166.wav
new file mode 100644
index 0000000..9996f6d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0166.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0166.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0166.wavetable
new file mode 100644
index 0000000..d8406cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0166.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0167.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0167.wav
new file mode 100644
index 0000000..03e2e22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0167.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0167.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0167.wavetable
new file mode 100644
index 0000000..4cf2bc9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0167.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0168.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0168.wav
new file mode 100644
index 0000000..a6a9357
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0168.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0168.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0168.wavetable
new file mode 100644
index 0000000..bb33494
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0168.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0169.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0169.wav
new file mode 100644
index 0000000..ec91bc2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0169.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0169.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0169.wavetable
new file mode 100644
index 0000000..5118e8a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0169.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0170.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0170.wav
new file mode 100644
index 0000000..d242f22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0170.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0170.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0170.wavetable
new file mode 100644
index 0000000..4d934cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0170.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0171.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0171.wav
new file mode 100644
index 0000000..2550e73
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0171.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0171.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0171.wavetable
new file mode 100644
index 0000000..df01d3b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0171.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0172.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0172.wav
new file mode 100644
index 0000000..c3712b3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0172.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0172.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0172.wavetable
new file mode 100644
index 0000000..e0daef4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0172.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0173.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0173.wav
new file mode 100644
index 0000000..35989da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0173.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0173.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0173.wavetable
new file mode 100644
index 0000000..c503f44
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0173.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0174.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0174.wav
new file mode 100644
index 0000000..1becd84
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0174.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0174.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0174.wavetable
new file mode 100644
index 0000000..233673c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0174.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0175.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0175.wav
new file mode 100644
index 0000000..47fcf54
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0175.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0175.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0175.wavetable
new file mode 100644
index 0000000..546a84d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0175.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0176.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0176.wav
new file mode 100644
index 0000000..2baf6f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0176.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0176.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0176.wavetable
new file mode 100644
index 0000000..27ffa77
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0176.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0177.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0177.wav
new file mode 100644
index 0000000..4ba7754
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0177.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0177.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0177.wavetable
new file mode 100644
index 0000000..186a85f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0177.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0178.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0178.wav
new file mode 100644
index 0000000..06ee09f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0178.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0178.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0178.wavetable
new file mode 100644
index 0000000..e70a8d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0178.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0179.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0179.wav
new file mode 100644
index 0000000..853822a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0179.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0179.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0179.wavetable
new file mode 100644
index 0000000..7c79ee6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0179.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0180.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0180.wav
new file mode 100644
index 0000000..e2c6d9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0180.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0180.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0180.wavetable
new file mode 100644
index 0000000..793e8b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0180.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0181.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0181.wav
new file mode 100644
index 0000000..33e5616
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0181.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0181.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0181.wavetable
new file mode 100644
index 0000000..59693d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0181.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0182.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0182.wav
new file mode 100644
index 0000000..b80665d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0182.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0182.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0182.wavetable
new file mode 100644
index 0000000..9309fc8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0182.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0183.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0183.wav
new file mode 100644
index 0000000..029d68b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0183.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0183.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0183.wavetable
new file mode 100644
index 0000000..4756231
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0183.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0184.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0184.wav
new file mode 100644
index 0000000..c6a137d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0184.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0184.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0184.wavetable
new file mode 100644
index 0000000..97b5126
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0184.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0185.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0185.wav
new file mode 100644
index 0000000..5d9f01a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0185.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0185.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0185.wavetable
new file mode 100644
index 0000000..32959f2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0185.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0186.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0186.wav
new file mode 100644
index 0000000..d30295f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0186.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0186.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0186.wavetable
new file mode 100644
index 0000000..8f5e83b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0186.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0187.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0187.wav
new file mode 100644
index 0000000..d4b5907
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0187.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0187.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0187.wavetable
new file mode 100644
index 0000000..aed81c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0187.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0188.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0188.wav
new file mode 100644
index 0000000..067f9ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0188.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0188.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0188.wavetable
new file mode 100644
index 0000000..398e511
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0188.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0189.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0189.wav
new file mode 100644
index 0000000..37ec510
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0189.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0189.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0189.wavetable
new file mode 100644
index 0000000..c9c68ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0189.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0190.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0190.wav
new file mode 100644
index 0000000..9fecdd4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0190.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0190.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0190.wavetable
new file mode 100644
index 0000000..6934a85
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0190.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0191.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0191.wav
new file mode 100644
index 0000000..252106a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0191.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0191.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0191.wavetable
new file mode 100644
index 0000000..6fae8c8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0191.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0192.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0192.wav
new file mode 100644
index 0000000..05f1dc6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0192.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0192.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0192.wavetable
new file mode 100644
index 0000000..8cb41e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0192.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0193.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0193.wav
new file mode 100644
index 0000000..6a6d6a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0193.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0193.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0193.wavetable
new file mode 100644
index 0000000..986f4cc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0193.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0194.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0194.wav
new file mode 100644
index 0000000..f7c717e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0194.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0194.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0194.wavetable
new file mode 100644
index 0000000..544af87
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0194.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0195.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0195.wav
new file mode 100644
index 0000000..f484ab1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0195.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0195.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0195.wavetable
new file mode 100644
index 0000000..b966536
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0195.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0196.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0196.wav
new file mode 100644
index 0000000..8d5930a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0196.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0196.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0196.wavetable
new file mode 100644
index 0000000..7a968c1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0196.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0197.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0197.wav
new file mode 100644
index 0000000..c8dad38
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0197.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0197.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0197.wavetable
new file mode 100644
index 0000000..06fd073
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0197.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0198.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0198.wav
new file mode 100644
index 0000000..ce6dd5c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0198.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0198.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0198.wavetable
new file mode 100644
index 0000000..bebbfcb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0198.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0199.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0199.wav
new file mode 100644
index 0000000..028c136
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0199.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0199.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0199.wavetable
new file mode 100644
index 0000000..651e365
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0199.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0200.wav b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0200.wav
new file mode 100644
index 0000000..60f6884
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0200.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0200.wavetable b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0200.wavetable
new file mode 100644
index 0000000..d658090
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stereo/AKWF_stereo_0200.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stereo/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_stereo/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_stereo/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0001.wav b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0001.wav
new file mode 100644
index 0000000..37bad23
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0001.wavetable b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0001.wavetable
new file mode 100644
index 0000000..4710ec6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0002.wav b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0002.wav
new file mode 100644
index 0000000..3033a79
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0002.wavetable b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0002.wavetable
new file mode 100644
index 0000000..c206693
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0003.wav b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0003.wav
new file mode 100644
index 0000000..d6bcdaf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0003.wavetable b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0003.wavetable
new file mode 100644
index 0000000..8ebe3bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0004.wav b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0004.wav
new file mode 100644
index 0000000..9cc238c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0004.wavetable b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0004.wavetable
new file mode 100644
index 0000000..428bbe8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0005.wav b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0005.wav
new file mode 100644
index 0000000..3afa123
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0005.wavetable b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0005.wavetable
new file mode 100644
index 0000000..9197575
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0006.wav b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0006.wav
new file mode 100644
index 0000000..36711b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0006.wavetable b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0006.wavetable
new file mode 100644
index 0000000..0a51258
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_stringbox/AKWF_cheeze_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_stringbox/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_stringbox/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_stringbox/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0001.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0001.wav
new file mode 100644
index 0000000..d3da9a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0001.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0001.wavetable
new file mode 100644
index 0000000..732bc16
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0002.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0002.wav
new file mode 100644
index 0000000..28c615d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0002.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0002.wavetable
new file mode 100644
index 0000000..cdac56d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0003.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0003.wav
new file mode 100644
index 0000000..a02cf15
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0003.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0003.wavetable
new file mode 100644
index 0000000..307d201
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0004.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0004.wav
new file mode 100644
index 0000000..12b41d4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0004.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0004.wavetable
new file mode 100644
index 0000000..0797938
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0005.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0005.wav
new file mode 100644
index 0000000..390140d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0005.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0005.wavetable
new file mode 100644
index 0000000..610a629
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0006.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0006.wav
new file mode 100644
index 0000000..dbb5364
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0006.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0006.wavetable
new file mode 100644
index 0000000..099e6f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0007.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0007.wav
new file mode 100644
index 0000000..16605e6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0007.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0007.wavetable
new file mode 100644
index 0000000..316e4ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0008.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0008.wav
new file mode 100644
index 0000000..c45a868
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0008.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0008.wavetable
new file mode 100644
index 0000000..9ef5a10
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0009.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0009.wav
new file mode 100644
index 0000000..d2555f3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0009.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0009.wavetable
new file mode 100644
index 0000000..cc284f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0010.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0010.wav
new file mode 100644
index 0000000..3086cf3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0010.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0010.wavetable
new file mode 100644
index 0000000..7deb5f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0011.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0011.wav
new file mode 100644
index 0000000..a4a869b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0011.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0011.wavetable
new file mode 100644
index 0000000..d61d9ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0012.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0012.wav
new file mode 100644
index 0000000..1ab473a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0012.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0012.wavetable
new file mode 100644
index 0000000..de67ca0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0013.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0013.wav
new file mode 100644
index 0000000..932c358
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0013.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0013.wavetable
new file mode 100644
index 0000000..9cb6731
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0014.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0014.wav
new file mode 100644
index 0000000..896af6a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0014.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0014.wavetable
new file mode 100644
index 0000000..e88a653
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0015.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0015.wav
new file mode 100644
index 0000000..14047ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0015.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0015.wavetable
new file mode 100644
index 0000000..d2e5662
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0016.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0016.wav
new file mode 100644
index 0000000..068bf67
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0016.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0016.wavetable
new file mode 100644
index 0000000..da387f8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0017.wav b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0017.wav
new file mode 100644
index 0000000..38fab8a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0017.wavetable b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0017.wavetable
new file mode 100644
index 0000000..acde573
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_symetric/AKWF_symetric_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_symetric/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_symetric/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_symetric/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0001.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0001.wav
new file mode 100644
index 0000000..8395ddc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0001.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0001.wavetable
new file mode 100644
index 0000000..38f8655
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0002.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0002.wav
new file mode 100644
index 0000000..0538442
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0002.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0002.wavetable
new file mode 100644
index 0000000..568318e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0003.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0003.wav
new file mode 100644
index 0000000..c6fba95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0003.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0003.wavetable
new file mode 100644
index 0000000..bf0f069
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0004.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0004.wav
new file mode 100644
index 0000000..33a92e3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0004.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0004.wavetable
new file mode 100644
index 0000000..1c09547
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_tannerin_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0001.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0001.wav
new file mode 100644
index 0000000..cb0152f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0001.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0001.wavetable
new file mode 100644
index 0000000..57b5f65
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0002.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0002.wav
new file mode 100644
index 0000000..27a08f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0002.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0002.wavetable
new file mode 100644
index 0000000..6d133ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0003.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0003.wav
new file mode 100644
index 0000000..cdbeff5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0003.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0003.wavetable
new file mode 100644
index 0000000..4c6cbcd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0004.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0004.wav
new file mode 100644
index 0000000..c344bdf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0004.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0004.wavetable
new file mode 100644
index 0000000..0f5d161
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0005.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0005.wav
new file mode 100644
index 0000000..8667484
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0005.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0005.wavetable
new file mode 100644
index 0000000..562d9a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0006.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0006.wav
new file mode 100644
index 0000000..ef85451
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0006.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0006.wavetable
new file mode 100644
index 0000000..74a5435
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0007.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0007.wav
new file mode 100644
index 0000000..07c67e8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0007.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0007.wavetable
new file mode 100644
index 0000000..427ddbf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0008.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0008.wav
new file mode 100644
index 0000000..e416a9d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0008.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0008.wavetable
new file mode 100644
index 0000000..ca550c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0009.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0009.wav
new file mode 100644
index 0000000..b5b981e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0009.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0009.wavetable
new file mode 100644
index 0000000..ea6aea0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0010.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0010.wav
new file mode 100644
index 0000000..14ecadc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0010.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0010.wavetable
new file mode 100644
index 0000000..3ba68cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0011.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0011.wav
new file mode 100644
index 0000000..0243608
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0011.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0011.wavetable
new file mode 100644
index 0000000..e80d9f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0012.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0012.wav
new file mode 100644
index 0000000..ca3aad3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0012.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0012.wavetable
new file mode 100644
index 0000000..5f904a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0013.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0013.wav
new file mode 100644
index 0000000..1acb75b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0013.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0013.wavetable
new file mode 100644
index 0000000..c911c30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0014.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0014.wav
new file mode 100644
index 0000000..968ba74
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0014.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0014.wavetable
new file mode 100644
index 0000000..f6c5367
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0015.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0015.wav
new file mode 100644
index 0000000..57da51f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0015.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0015.wavetable
new file mode 100644
index 0000000..9f0d625
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0016.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0016.wav
new file mode 100644
index 0000000..f99b39e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0016.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0016.wavetable
new file mode 100644
index 0000000..0ede5e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0017.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0017.wav
new file mode 100644
index 0000000..265acaa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0017.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0017.wavetable
new file mode 100644
index 0000000..fc38acc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0018.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0018.wav
new file mode 100644
index 0000000..daef22c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0018.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0018.wavetable
new file mode 100644
index 0000000..2d2cad9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0019.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0019.wav
new file mode 100644
index 0000000..0756761
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0019.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0019.wavetable
new file mode 100644
index 0000000..1913989
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0020.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0020.wav
new file mode 100644
index 0000000..0a021d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0020.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0020.wavetable
new file mode 100644
index 0000000..f6df4e3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0021.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0021.wav
new file mode 100644
index 0000000..d6c4da5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0021.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0021.wavetable
new file mode 100644
index 0000000..a986ad7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0022.wav b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0022.wav
new file mode 100644
index 0000000..919c3cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0022.wavetable b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0022.wavetable
new file mode 100644
index 0000000..d7ae1c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_theremin/AKWF_theremin_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_theremin/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_theremin/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_theremin/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0001.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0001.wav
new file mode 100644
index 0000000..2ce29f5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0001.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0001.wavetable
new file mode 100644
index 0000000..6f91e6c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0002.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0002.wav
new file mode 100644
index 0000000..deb16ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0002.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0002.wavetable
new file mode 100644
index 0000000..5e7f4c2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0003.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0003.wav
new file mode 100644
index 0000000..da7d66b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0003.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0003.wavetable
new file mode 100644
index 0000000..6fae0e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0004.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0004.wav
new file mode 100644
index 0000000..983b9d7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0004.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0004.wavetable
new file mode 100644
index 0000000..ee46eb8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0005.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0005.wav
new file mode 100644
index 0000000..be96818
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0005.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0005.wavetable
new file mode 100644
index 0000000..89a687b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0006.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0006.wav
new file mode 100644
index 0000000..3870f2e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0006.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0006.wavetable
new file mode 100644
index 0000000..25f97d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0007.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0007.wav
new file mode 100644
index 0000000..87c17fb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0007.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0007.wavetable
new file mode 100644
index 0000000..c5fc156
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0008.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0008.wav
new file mode 100644
index 0000000..d1e9752
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0008.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0008.wavetable
new file mode 100644
index 0000000..a37e13e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0009.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0009.wav
new file mode 100644
index 0000000..b9be7da
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0009.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0009.wavetable
new file mode 100644
index 0000000..1853bca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0010.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0010.wav
new file mode 100644
index 0000000..8719695
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0010.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0010.wavetable
new file mode 100644
index 0000000..28a44e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0011.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0011.wav
new file mode 100644
index 0000000..8d1d639
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0011.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0011.wavetable
new file mode 100644
index 0000000..d0cad84
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0012.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0012.wav
new file mode 100644
index 0000000..064a84b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0012.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0012.wavetable
new file mode 100644
index 0000000..8fee118
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0013.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0013.wav
new file mode 100644
index 0000000..61b4cfc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0013.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0013.wavetable
new file mode 100644
index 0000000..1ff7248
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0014.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0014.wav
new file mode 100644
index 0000000..f8dd65b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0014.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0014.wavetable
new file mode 100644
index 0000000..02f573d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0015.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0015.wav
new file mode 100644
index 0000000..208c29d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0015.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0015.wavetable
new file mode 100644
index 0000000..6137bcb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0016.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0016.wav
new file mode 100644
index 0000000..6ef3b0c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0016.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0016.wavetable
new file mode 100644
index 0000000..180f30b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0017.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0017.wav
new file mode 100644
index 0000000..27e97eb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0017.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0017.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0017.wavetable
new file mode 100644
index 0000000..fde6ddc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0017.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0018.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0018.wav
new file mode 100644
index 0000000..11251af
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0018.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0018.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0018.wavetable
new file mode 100644
index 0000000..ff9d3ac
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0018.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0019.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0019.wav
new file mode 100644
index 0000000..b396858
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0019.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0019.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0019.wavetable
new file mode 100644
index 0000000..3054c46
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0019.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0020.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0020.wav
new file mode 100644
index 0000000..01fef2b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0020.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0020.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0020.wavetable
new file mode 100644
index 0000000..849a07c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0020.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0021.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0021.wav
new file mode 100644
index 0000000..b7e3d45
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0021.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0021.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0021.wavetable
new file mode 100644
index 0000000..e0fe80c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0021.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0022.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0022.wav
new file mode 100644
index 0000000..554f83f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0022.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0022.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0022.wavetable
new file mode 100644
index 0000000..ee10d08
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0022.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0023.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0023.wav
new file mode 100644
index 0000000..d9ef401
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0023.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0023.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0023.wavetable
new file mode 100644
index 0000000..caba7a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0023.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0024.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0024.wav
new file mode 100644
index 0000000..9c83aca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0024.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0024.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0024.wavetable
new file mode 100644
index 0000000..4c6baa5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0024.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0025.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0025.wav
new file mode 100644
index 0000000..b8b6bf4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0025.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0025.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0025.wavetable
new file mode 100644
index 0000000..d47a855
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0025.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0026.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0026.wav
new file mode 100644
index 0000000..bd00a93
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0026.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0026.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0026.wavetable
new file mode 100644
index 0000000..bd62345
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0026.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0027.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0027.wav
new file mode 100644
index 0000000..89b480f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0027.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0027.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0027.wavetable
new file mode 100644
index 0000000..d413cbf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0027.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0028.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0028.wav
new file mode 100644
index 0000000..59d1aab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0028.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0028.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0028.wavetable
new file mode 100644
index 0000000..8daa002
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0028.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0029.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0029.wav
new file mode 100644
index 0000000..04e0c78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0029.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0029.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0029.wavetable
new file mode 100644
index 0000000..01ecc30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0029.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0030.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0030.wav
new file mode 100644
index 0000000..6334a5a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0030.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0030.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0030.wavetable
new file mode 100644
index 0000000..7adba9a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0030.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0031.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0031.wav
new file mode 100644
index 0000000..e61b8c8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0031.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0031.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0031.wavetable
new file mode 100644
index 0000000..abc7ff4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0031.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0032.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0032.wav
new file mode 100644
index 0000000..2319ce4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0032.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0032.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0032.wavetable
new file mode 100644
index 0000000..dd74ed3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0032.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0033.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0033.wav
new file mode 100644
index 0000000..78928b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0033.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0033.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0033.wavetable
new file mode 100644
index 0000000..dc641c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0033.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0034.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0034.wav
new file mode 100644
index 0000000..9c5ec77
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0034.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0034.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0034.wavetable
new file mode 100644
index 0000000..149f5ea
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0034.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0035.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0035.wav
new file mode 100644
index 0000000..e7b911d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0035.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0035.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0035.wavetable
new file mode 100644
index 0000000..8b4f8b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0035.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0036.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0036.wav
new file mode 100644
index 0000000..149ee17
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0036.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0036.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0036.wavetable
new file mode 100644
index 0000000..395f755
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0036.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0037.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0037.wav
new file mode 100644
index 0000000..47ae844
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0037.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0037.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0037.wavetable
new file mode 100644
index 0000000..aeccd64
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0037.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0038.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0038.wav
new file mode 100644
index 0000000..032901e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0038.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0038.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0038.wavetable
new file mode 100644
index 0000000..2dd8b7e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0038.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0039.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0039.wav
new file mode 100644
index 0000000..9255d06
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0039.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0039.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0039.wavetable
new file mode 100644
index 0000000..8fbd71b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0039.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0040.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0040.wav
new file mode 100644
index 0000000..2498c74
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0040.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0040.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0040.wavetable
new file mode 100644
index 0000000..ae193f0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0040.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0041.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0041.wav
new file mode 100644
index 0000000..db3dc23
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0041.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0041.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0041.wavetable
new file mode 100644
index 0000000..10523d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0041.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0042.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0042.wav
new file mode 100644
index 0000000..8c407ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0042.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0042.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0042.wavetable
new file mode 100644
index 0000000..77cd141
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0042.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0043.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0043.wav
new file mode 100644
index 0000000..73f0633
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0043.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0043.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0043.wavetable
new file mode 100644
index 0000000..1e2e02d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0043.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0044.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0044.wav
new file mode 100644
index 0000000..4da34ef
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0044.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0044.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0044.wavetable
new file mode 100644
index 0000000..6ebf52c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0044.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0045.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0045.wav
new file mode 100644
index 0000000..a2e6f58
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0045.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0045.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0045.wavetable
new file mode 100644
index 0000000..2b98821
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0045.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0046.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0046.wav
new file mode 100644
index 0000000..ac5f44c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0046.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0046.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0046.wavetable
new file mode 100644
index 0000000..73f1702
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0046.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0047.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0047.wav
new file mode 100644
index 0000000..c8ebc1d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0047.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0047.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0047.wavetable
new file mode 100644
index 0000000..67b7a30
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0047.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0048.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0048.wav
new file mode 100644
index 0000000..56d3546
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0048.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0048.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0048.wavetable
new file mode 100644
index 0000000..8b328ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0048.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0049.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0049.wav
new file mode 100644
index 0000000..395c435
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0049.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0049.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0049.wavetable
new file mode 100644
index 0000000..dd106e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0049.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0050.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0050.wav
new file mode 100644
index 0000000..92a6faf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0050.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0050.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0050.wavetable
new file mode 100644
index 0000000..6661ed7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0050.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0051.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0051.wav
new file mode 100644
index 0000000..2470e43
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0051.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0051.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0051.wavetable
new file mode 100644
index 0000000..929782e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0051.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0052.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0052.wav
new file mode 100644
index 0000000..c3ef45e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0052.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0052.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0052.wavetable
new file mode 100644
index 0000000..1e61cd8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0052.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0053.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0053.wav
new file mode 100644
index 0000000..5586f52
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0053.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0053.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0053.wavetable
new file mode 100644
index 0000000..453defb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0053.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0054.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0054.wav
new file mode 100644
index 0000000..bf841a5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0054.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0054.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0054.wavetable
new file mode 100644
index 0000000..bf7e7ae
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0054.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0055.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0055.wav
new file mode 100644
index 0000000..c327061
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0055.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0055.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0055.wavetable
new file mode 100644
index 0000000..0aa1f01
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0055.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0056.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0056.wav
new file mode 100644
index 0000000..7929c3c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0056.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0056.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0056.wavetable
new file mode 100644
index 0000000..43889e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0056.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0057.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0057.wav
new file mode 100644
index 0000000..0c0f0df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0057.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0057.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0057.wavetable
new file mode 100644
index 0000000..8aa045a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0057.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0058.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0058.wav
new file mode 100644
index 0000000..2a4182b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0058.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0058.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0058.wavetable
new file mode 100644
index 0000000..2f9da68
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0058.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0059.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0059.wav
new file mode 100644
index 0000000..76484e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0059.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0059.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0059.wavetable
new file mode 100644
index 0000000..afa25ee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0059.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0060.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0060.wav
new file mode 100644
index 0000000..e71194b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0060.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0060.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0060.wavetable
new file mode 100644
index 0000000..00d4f22
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0060.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0061.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0061.wav
new file mode 100644
index 0000000..25acd74
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0061.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0061.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0061.wavetable
new file mode 100644
index 0000000..c20de97
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0061.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0062.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0062.wav
new file mode 100644
index 0000000..2595aff
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0062.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0062.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0062.wavetable
new file mode 100644
index 0000000..0034c91
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0062.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0063.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0063.wav
new file mode 100644
index 0000000..ed8fe11
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0063.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0063.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0063.wavetable
new file mode 100644
index 0000000..28c7fe0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0063.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0064.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0064.wav
new file mode 100644
index 0000000..b27ecf5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0064.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0064.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0064.wavetable
new file mode 100644
index 0000000..1732897
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0064.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0065.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0065.wav
new file mode 100644
index 0000000..879118c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0065.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0065.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0065.wavetable
new file mode 100644
index 0000000..614853c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0065.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0066.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0066.wav
new file mode 100644
index 0000000..84171ad
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0066.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0066.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0066.wavetable
new file mode 100644
index 0000000..894bdc5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0066.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0067.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0067.wav
new file mode 100644
index 0000000..f106bd9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0067.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0067.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0067.wavetable
new file mode 100644
index 0000000..bdec5b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0067.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0068.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0068.wav
new file mode 100644
index 0000000..00d2bce
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0068.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0068.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0068.wavetable
new file mode 100644
index 0000000..5197a11
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0068.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0069.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0069.wav
new file mode 100644
index 0000000..ec96d9f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0069.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0069.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0069.wavetable
new file mode 100644
index 0000000..9d9d791
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0069.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0070.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0070.wav
new file mode 100644
index 0000000..53c8d89
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0070.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0070.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0070.wavetable
new file mode 100644
index 0000000..97d1460
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0070.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0071.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0071.wav
new file mode 100644
index 0000000..a038daa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0071.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0071.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0071.wavetable
new file mode 100644
index 0000000..0fcb629
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0071.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0072.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0072.wav
new file mode 100644
index 0000000..cbf1682
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0072.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0072.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0072.wavetable
new file mode 100644
index 0000000..2415cdd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0072.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0073.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0073.wav
new file mode 100644
index 0000000..fc772f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0073.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0073.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0073.wavetable
new file mode 100644
index 0000000..0071d2d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0073.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0074.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0074.wav
new file mode 100644
index 0000000..80d64d2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0074.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0074.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0074.wavetable
new file mode 100644
index 0000000..5f2b13b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0074.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0075.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0075.wav
new file mode 100644
index 0000000..a58a9ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0075.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0075.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0075.wavetable
new file mode 100644
index 0000000..f3b9414
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0075.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0076.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0076.wav
new file mode 100644
index 0000000..10778ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0076.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0076.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0076.wavetable
new file mode 100644
index 0000000..3929047
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0076.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0077.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0077.wav
new file mode 100644
index 0000000..54e78ed
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0077.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0077.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0077.wavetable
new file mode 100644
index 0000000..02aa00a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0077.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0078.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0078.wav
new file mode 100644
index 0000000..b8ca01c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0078.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0078.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0078.wavetable
new file mode 100644
index 0000000..ba8948e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0078.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0079.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0079.wav
new file mode 100644
index 0000000..c53e961
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0079.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0079.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0079.wavetable
new file mode 100644
index 0000000..7a30edf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0079.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0080.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0080.wav
new file mode 100644
index 0000000..738099e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0080.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0080.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0080.wavetable
new file mode 100644
index 0000000..cd25ef8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0080.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0081.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0081.wav
new file mode 100644
index 0000000..2396349
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0081.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0081.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0081.wavetable
new file mode 100644
index 0000000..c1a1877
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0081.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0082.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0082.wav
new file mode 100644
index 0000000..fe370a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0082.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0082.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0082.wavetable
new file mode 100644
index 0000000..3881796
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0082.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0083.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0083.wav
new file mode 100644
index 0000000..a386a7c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0083.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0083.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0083.wavetable
new file mode 100644
index 0000000..264a27d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0083.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0084.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0084.wav
new file mode 100644
index 0000000..9334467
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0084.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0084.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0084.wavetable
new file mode 100644
index 0000000..4548b3a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0084.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0085.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0085.wav
new file mode 100644
index 0000000..a0e168f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0085.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0085.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0085.wavetable
new file mode 100644
index 0000000..090fabd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0085.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0086.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0086.wav
new file mode 100644
index 0000000..f187bb9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0086.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0086.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0086.wavetable
new file mode 100644
index 0000000..041c49e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0086.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0087.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0087.wav
new file mode 100644
index 0000000..c995cd3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0087.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0087.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0087.wavetable
new file mode 100644
index 0000000..f87a1d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0087.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0088.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0088.wav
new file mode 100644
index 0000000..ca499ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0088.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0088.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0088.wavetable
new file mode 100644
index 0000000..91c64f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0088.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0089.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0089.wav
new file mode 100644
index 0000000..a8d2e36
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0089.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0089.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0089.wavetable
new file mode 100644
index 0000000..9e103b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0089.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0090.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0090.wav
new file mode 100644
index 0000000..62f0fc3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0090.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0090.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0090.wavetable
new file mode 100644
index 0000000..8640386
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0090.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0091.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0091.wav
new file mode 100644
index 0000000..78ea319
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0091.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0091.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0091.wavetable
new file mode 100644
index 0000000..f4e0b1b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0091.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0092.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0092.wav
new file mode 100644
index 0000000..b13436e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0092.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0092.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0092.wavetable
new file mode 100644
index 0000000..e27a552
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0092.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0093.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0093.wav
new file mode 100644
index 0000000..0bb8bbd
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0093.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0093.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0093.wavetable
new file mode 100644
index 0000000..f9fc8e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0093.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0094.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0094.wav
new file mode 100644
index 0000000..d3f7e6d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0094.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0094.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0094.wavetable
new file mode 100644
index 0000000..f14316b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0094.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0095.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0095.wav
new file mode 100644
index 0000000..3cb7e35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0095.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0095.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0095.wavetable
new file mode 100644
index 0000000..0be6768
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0095.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0096.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0096.wav
new file mode 100644
index 0000000..b90f8b3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0096.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0096.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0096.wavetable
new file mode 100644
index 0000000..a1c8f81
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0096.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0097.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0097.wav
new file mode 100644
index 0000000..8b3a374
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0097.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0097.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0097.wavetable
new file mode 100644
index 0000000..580a88f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0097.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0098.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0098.wav
new file mode 100644
index 0000000..fd80cba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0098.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0098.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0098.wavetable
new file mode 100644
index 0000000..61aca49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0098.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0099.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0099.wav
new file mode 100644
index 0000000..2581c55
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0099.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0099.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0099.wavetable
new file mode 100644
index 0000000..f483c08
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0099.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0100.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0100.wav
new file mode 100644
index 0000000..b28aa28
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0100.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0100.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0100.wavetable
new file mode 100644
index 0000000..130137a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0100.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0101.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0101.wav
new file mode 100644
index 0000000..587aa42
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0101.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0101.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0101.wavetable
new file mode 100644
index 0000000..715d939
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0101.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0102.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0102.wav
new file mode 100644
index 0000000..ae04d13
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0102.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0102.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0102.wavetable
new file mode 100644
index 0000000..64c0127
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0102.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0103.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0103.wav
new file mode 100644
index 0000000..9847424
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0103.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0103.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0103.wavetable
new file mode 100644
index 0000000..72ea1f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0103.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0104.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0104.wav
new file mode 100644
index 0000000..f5da8f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0104.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0104.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0104.wavetable
new file mode 100644
index 0000000..e1398bb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0104.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0105.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0105.wav
new file mode 100644
index 0000000..010a0b0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0105.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0105.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0105.wavetable
new file mode 100644
index 0000000..f8ff0c9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0105.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0106.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0106.wav
new file mode 100644
index 0000000..4ab3741
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0106.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0106.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0106.wavetable
new file mode 100644
index 0000000..2cb5dfe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0106.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0107.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0107.wav
new file mode 100644
index 0000000..9903f50
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0107.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0107.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0107.wavetable
new file mode 100644
index 0000000..5e9f109
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0107.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0108.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0108.wav
new file mode 100644
index 0000000..4a2f079
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0108.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0108.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0108.wavetable
new file mode 100644
index 0000000..c6ad8a0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0108.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0109.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0109.wav
new file mode 100644
index 0000000..cd4426d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0109.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0109.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0109.wavetable
new file mode 100644
index 0000000..d89809e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0109.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0110.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0110.wav
new file mode 100644
index 0000000..f4f5ff4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0110.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0110.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0110.wavetable
new file mode 100644
index 0000000..3274f9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0110.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0111.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0111.wav
new file mode 100644
index 0000000..b7d30a4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0111.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0111.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0111.wavetable
new file mode 100644
index 0000000..12cb6b6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0111.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0112.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0112.wav
new file mode 100644
index 0000000..862b73c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0112.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0112.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0112.wavetable
new file mode 100644
index 0000000..dc66642
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0112.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0113.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0113.wav
new file mode 100644
index 0000000..cbd58d9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0113.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0113.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0113.wavetable
new file mode 100644
index 0000000..411d8be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0113.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0114.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0114.wav
new file mode 100644
index 0000000..9cd112d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0114.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0114.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0114.wavetable
new file mode 100644
index 0000000..05ec55e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0114.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0115.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0115.wav
new file mode 100644
index 0000000..1d5282f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0115.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0115.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0115.wavetable
new file mode 100644
index 0000000..85d9acf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0115.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0116.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0116.wav
new file mode 100644
index 0000000..62c7374
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0116.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0116.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0116.wavetable
new file mode 100644
index 0000000..499a853
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0116.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0117.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0117.wav
new file mode 100644
index 0000000..6c51be1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0117.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0117.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0117.wavetable
new file mode 100644
index 0000000..4202d21
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0117.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0118.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0118.wav
new file mode 100644
index 0000000..6d60a37
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0118.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0118.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0118.wavetable
new file mode 100644
index 0000000..27c540d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0118.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0119.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0119.wav
new file mode 100644
index 0000000..4c1d7fa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0119.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0119.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0119.wavetable
new file mode 100644
index 0000000..6fda950
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0119.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0120.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0120.wav
new file mode 100644
index 0000000..1d493d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0120.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0120.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0120.wavetable
new file mode 100644
index 0000000..49018b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0120.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0121.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0121.wav
new file mode 100644
index 0000000..5c2cd5f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0121.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0121.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0121.wavetable
new file mode 100644
index 0000000..85a99f9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0121.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0122.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0122.wav
new file mode 100644
index 0000000..de0bb54
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0122.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0122.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0122.wavetable
new file mode 100644
index 0000000..1acf236
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0122.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0123.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0123.wav
new file mode 100644
index 0000000..dbc9bc9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0123.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0123.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0123.wavetable
new file mode 100644
index 0000000..01b8010
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0123.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0124.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0124.wav
new file mode 100644
index 0000000..37b2e49
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0124.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0124.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0124.wavetable
new file mode 100644
index 0000000..5d070cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0124.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0125.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0125.wav
new file mode 100644
index 0000000..85b4a48
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0125.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0125.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0125.wavetable
new file mode 100644
index 0000000..5bde0b7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0125.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0126.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0126.wav
new file mode 100644
index 0000000..3f5cd78
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0126.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0126.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0126.wavetable
new file mode 100644
index 0000000..3a3275a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0126.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0127.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0127.wav
new file mode 100644
index 0000000..ea2a60a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0127.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0127.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0127.wavetable
new file mode 100644
index 0000000..666f28f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0127.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0128.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0128.wav
new file mode 100644
index 0000000..8369c93
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0128.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0128.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0128.wavetable
new file mode 100644
index 0000000..72efb0b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0128.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0129.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0129.wav
new file mode 100644
index 0000000..9aca907
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0129.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0129.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0129.wavetable
new file mode 100644
index 0000000..4c0beb7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0129.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0130.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0130.wav
new file mode 100644
index 0000000..9a85b47
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0130.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0130.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0130.wavetable
new file mode 100644
index 0000000..a7889fe
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0130.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0131.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0131.wav
new file mode 100644
index 0000000..71d0336
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0131.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0131.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0131.wavetable
new file mode 100644
index 0000000..fb185b1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0131.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0132.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0132.wav
new file mode 100644
index 0000000..d397912
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0132.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0132.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0132.wavetable
new file mode 100644
index 0000000..176cd9e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0132.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0133.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0133.wav
new file mode 100644
index 0000000..0f08b5f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0133.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0133.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0133.wavetable
new file mode 100644
index 0000000..9c5bc83
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0133.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0134.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0134.wav
new file mode 100644
index 0000000..b1a3550
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0134.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0134.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0134.wavetable
new file mode 100644
index 0000000..ce6e87f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0134.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0135.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0135.wav
new file mode 100644
index 0000000..1ecb69b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0135.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0135.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0135.wavetable
new file mode 100644
index 0000000..8b29f88
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0135.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0136.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0136.wav
new file mode 100644
index 0000000..e4537bf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0136.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0136.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0136.wavetable
new file mode 100644
index 0000000..fcfdb71
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0136.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0137.wav b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0137.wav
new file mode 100644
index 0000000..574e2cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0137.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0137.wavetable b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0137.wavetable
new file mode 100644
index 0000000..f3aa8ca
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgame/AKWF_vgame_0137.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgame/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_vgame/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_vgame/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0001.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0001.wav
new file mode 100644
index 0000000..2649152
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0001.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0001.wavetable
new file mode 100644
index 0000000..cfd7e56
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0002.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0002.wav
new file mode 100644
index 0000000..7848096
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0002.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0002.wavetable
new file mode 100644
index 0000000..5ebc85b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0003.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0003.wav
new file mode 100644
index 0000000..6d4dc90
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0003.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0003.wavetable
new file mode 100644
index 0000000..e1221aa
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0004.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0004.wav
new file mode 100644
index 0000000..303ae31
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0004.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0004.wavetable
new file mode 100644
index 0000000..5a5bf95
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0005.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0005.wav
new file mode 100644
index 0000000..7664915
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0005.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0005.wavetable
new file mode 100644
index 0000000..e4670c3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0006.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0006.wav
new file mode 100644
index 0000000..898677e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0006.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0006.wavetable
new file mode 100644
index 0000000..d3fff50
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0007.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0007.wav
new file mode 100644
index 0000000..5ffa129
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0007.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0007.wavetable
new file mode 100644
index 0000000..bd55d39
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0008.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0008.wav
new file mode 100644
index 0000000..cbaff7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0008.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0008.wavetable
new file mode 100644
index 0000000..8bdefcb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0009.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0009.wav
new file mode 100644
index 0000000..9d8e00b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0009.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0009.wavetable
new file mode 100644
index 0000000..ad17071
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0010.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0010.wav
new file mode 100644
index 0000000..15ea37c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0010.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0010.wavetable
new file mode 100644
index 0000000..86b3e9f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0011.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0011.wav
new file mode 100644
index 0000000..aac7234
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0011.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0011.wavetable
new file mode 100644
index 0000000..f180cf7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0012.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0012.wav
new file mode 100644
index 0000000..7275998
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0012.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0012.wavetable
new file mode 100644
index 0000000..136eba9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0013.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0013.wav
new file mode 100644
index 0000000..e50f0df
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0013.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0013.wavetable
new file mode 100644
index 0000000..a734583
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0014.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0014.wav
new file mode 100644
index 0000000..1706ee8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0014.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0014.wavetable
new file mode 100644
index 0000000..0f54c44
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0015.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0015.wav
new file mode 100644
index 0000000..eff3b03
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0015.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0015.wavetable
new file mode 100644
index 0000000..97ebe18
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0016.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0016.wav
new file mode 100644
index 0000000..7528855
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0016.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0016.wavetable
new file mode 100644
index 0000000..916a067
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsaw_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0001.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0001.wav
new file mode 100644
index 0000000..33af8b5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0001.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0001.wavetable
new file mode 100644
index 0000000..c1003d3
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0002.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0002.wav
new file mode 100644
index 0000000..fca6a79
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0002.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0002.wavetable
new file mode 100644
index 0000000..39fdde5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0003.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0003.wav
new file mode 100644
index 0000000..a412fe5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0003.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0003.wavetable
new file mode 100644
index 0000000..9b01f7e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0004.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0004.wav
new file mode 100644
index 0000000..2b82e3d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0004.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0004.wavetable
new file mode 100644
index 0000000..34bd32a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0005.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0005.wav
new file mode 100644
index 0000000..9b0c341
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0005.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0005.wavetable
new file mode 100644
index 0000000..0c08aa4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0006.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0006.wav
new file mode 100644
index 0000000..94b19c0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0006.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0006.wavetable
new file mode 100644
index 0000000..7254713
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0007.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0007.wav
new file mode 100644
index 0000000..43a96be
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0007.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0007.wavetable
new file mode 100644
index 0000000..82cbc44
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0008.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0008.wav
new file mode 100644
index 0000000..4701160
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0008.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0008.wavetable
new file mode 100644
index 0000000..25e5965
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0009.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0009.wav
new file mode 100644
index 0000000..71a342a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0009.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0009.wavetable
new file mode 100644
index 0000000..48c68d5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0010.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0010.wav
new file mode 100644
index 0000000..0ee3a8a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0010.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0010.wavetable
new file mode 100644
index 0000000..a3da362
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0011.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0011.wav
new file mode 100644
index 0000000..f626ae2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0011.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0011.wavetable
new file mode 100644
index 0000000..c366c69
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0012.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0012.wav
new file mode 100644
index 0000000..3cd47e5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0012.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0012.wavetable
new file mode 100644
index 0000000..24ec590
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0013.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0013.wav
new file mode 100644
index 0000000..a2b043c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0013.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0013.wavetable
new file mode 100644
index 0000000..64ec3f6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0014.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0014.wav
new file mode 100644
index 0000000..8517dfb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0014.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0014.wavetable
new file mode 100644
index 0000000..086020d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0015.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0015.wav
new file mode 100644
index 0000000..e62133b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0015.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0015.wavetable
new file mode 100644
index 0000000..c89fa4f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0016.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0016.wav
new file mode 100644
index 0000000..a0ee773
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0016.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0016.wavetable
new file mode 100644
index 0000000..046f1d8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsin_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0001.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0001.wav
new file mode 100644
index 0000000..38a5452
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0001.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0001.wavetable
new file mode 100644
index 0000000..5ae0113
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0002.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0002.wav
new file mode 100644
index 0000000..dba5021
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0002.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0002.wavetable
new file mode 100644
index 0000000..3ecf88e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0003.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0003.wav
new file mode 100644
index 0000000..737e101
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0003.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0003.wavetable
new file mode 100644
index 0000000..c0e2302
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0004.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0004.wav
new file mode 100644
index 0000000..04fd5b7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0004.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0004.wavetable
new file mode 100644
index 0000000..64cdc15
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0005.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0005.wav
new file mode 100644
index 0000000..4b59c5c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0005.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0005.wavetable
new file mode 100644
index 0000000..4369c5b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0006.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0006.wav
new file mode 100644
index 0000000..9992576
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0006.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0006.wavetable
new file mode 100644
index 0000000..a4c8acf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0007.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0007.wav
new file mode 100644
index 0000000..7fdbaee
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0007.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0007.wavetable
new file mode 100644
index 0000000..962790f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0008.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0008.wav
new file mode 100644
index 0000000..017e123
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0008.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0008.wavetable
new file mode 100644
index 0000000..433eecf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0009.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0009.wav
new file mode 100644
index 0000000..d057f56
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0009.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0009.wavetable
new file mode 100644
index 0000000..e1ab0a1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0010.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0010.wav
new file mode 100644
index 0000000..40ebad5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0010.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0010.wavetable
new file mode 100644
index 0000000..b1c3d0d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0011.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0011.wav
new file mode 100644
index 0000000..0f93aa9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0011.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0011.wavetable
new file mode 100644
index 0000000..4e274cb
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0012.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0012.wav
new file mode 100644
index 0000000..dcfd549
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0012.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0012.wavetable
new file mode 100644
index 0000000..95f19f8
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0013.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0013.wav
new file mode 100644
index 0000000..749685a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0013.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0013.wavetable
new file mode 100644
index 0000000..a63662d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0014.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0014.wav
new file mode 100644
index 0000000..898d238
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0014.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0014.wavetable
new file mode 100644
index 0000000..dd67c93
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0015.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0015.wav
new file mode 100644
index 0000000..eb685f4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0015.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0015.wavetable
new file mode 100644
index 0000000..39f0939
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0016.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0016.wav
new file mode 100644
index 0000000..3161f6b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0016.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0016.wavetable
new file mode 100644
index 0000000..7e9ccc0
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgsqu_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0001.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0001.wav
new file mode 100644
index 0000000..934a8e4
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0001.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0001.wavetable
new file mode 100644
index 0000000..b1133cf
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0002.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0002.wav
new file mode 100644
index 0000000..d945bc6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0002.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0002.wavetable
new file mode 100644
index 0000000..2937bcc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0003.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0003.wav
new file mode 100644
index 0000000..c2006c7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0003.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0003.wavetable
new file mode 100644
index 0000000..ea0624c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0004.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0004.wav
new file mode 100644
index 0000000..ed22a40
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0004.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0004.wavetable
new file mode 100644
index 0000000..efbec4c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0005.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0005.wav
new file mode 100644
index 0000000..50ba804
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0005.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0005.wavetable
new file mode 100644
index 0000000..026310d
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0006.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0006.wav
new file mode 100644
index 0000000..2a1d394
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0006.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0006.wavetable
new file mode 100644
index 0000000..2767997
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0007.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0007.wav
new file mode 100644
index 0000000..b63ab4f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0007.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0007.wavetable
new file mode 100644
index 0000000..8a6a9db
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0008.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0008.wav
new file mode 100644
index 0000000..d5f2bfc
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0008.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0008.wavetable
new file mode 100644
index 0000000..5576d7f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0009.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0009.wav
new file mode 100644
index 0000000..51714a2
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0009.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0009.wavetable
new file mode 100644
index 0000000..7a9796f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0010.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0010.wav
new file mode 100644
index 0000000..abd1930
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0010.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0010.wavetable
new file mode 100644
index 0000000..928043e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0011.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0011.wav
new file mode 100644
index 0000000..9e4dd02
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0011.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0011.wavetable
new file mode 100644
index 0000000..dea9075
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0012.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0012.wav
new file mode 100644
index 0000000..9c2722b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0012.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0012.wavetable
new file mode 100644
index 0000000..f3e245f
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0013.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0013.wav
new file mode 100644
index 0000000..c934654
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0013.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0013.wavetable
new file mode 100644
index 0000000..118798b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0014.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0014.wav
new file mode 100644
index 0000000..82b4a33
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0014.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0014.wavetable
new file mode 100644
index 0000000..8793a7e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0015.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0015.wav
new file mode 100644
index 0000000..ce0a194
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0015.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0015.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0015.wavetable
new file mode 100644
index 0000000..f5594e9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0015.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0016.wav b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0016.wav
new file mode 100644
index 0000000..f87a1ba
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0016.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0016.wavetable b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0016.wavetable
new file mode 100644
index 0000000..16ee25b
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_vgamebasic/AKWF_vgtri_0016.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_vgamebasic/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_vgamebasic/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_vgamebasic/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0001.wav b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0001.wav
new file mode 100644
index 0000000..935e841
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0001.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0001.wavetable b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0001.wavetable
new file mode 100644
index 0000000..8cd830c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0001.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0002.wav b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0002.wav
new file mode 100644
index 0000000..93b5557
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0002.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0002.wavetable b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0002.wavetable
new file mode 100644
index 0000000..cc18c37
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0002.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0003.wav b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0003.wav
new file mode 100644
index 0000000..5e4efda
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0003.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0003.wavetable b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0003.wavetable
new file mode 100644
index 0000000..3f12b35
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0003.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0004.wav b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0004.wav
new file mode 100644
index 0000000..941bbe7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0004.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0004.wavetable b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0004.wavetable
new file mode 100644
index 0000000..dc42a1e
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0004.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0005.wav b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0005.wav
new file mode 100644
index 0000000..90b56c6
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0005.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0005.wavetable b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0005.wavetable
new file mode 100644
index 0000000..3ae3774
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0005.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0006.wav b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0006.wav
new file mode 100644
index 0000000..686023c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0006.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0006.wavetable b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0006.wavetable
new file mode 100644
index 0000000..258d7e1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0006.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0007.wav b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0007.wav
new file mode 100644
index 0000000..2d3d825
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0007.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0007.wavetable b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0007.wavetable
new file mode 100644
index 0000000..874bb19
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0007.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0008.wav b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0008.wav
new file mode 100644
index 0000000..a6d5ce7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0008.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0008.wavetable b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0008.wavetable
new file mode 100644
index 0000000..39ca020
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0008.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0009.wav b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0009.wav
new file mode 100644
index 0000000..6e11425
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0009.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0009.wavetable b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0009.wavetable
new file mode 100644
index 0000000..25dac02
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0009.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0010.wav b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0010.wav
new file mode 100644
index 0000000..42efbf9
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0010.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0010.wavetable b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0010.wavetable
new file mode 100644
index 0000000..205fdab
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0010.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0011.wav b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0011.wav
new file mode 100644
index 0000000..f390622
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0011.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0011.wavetable b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0011.wavetable
new file mode 100644
index 0000000..bf3506c
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0011.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0012.wav b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0012.wav
new file mode 100644
index 0000000..daefdd7
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0012.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0012.wavetable b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0012.wavetable
new file mode 100644
index 0000000..28f3af1
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0012.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0013.wav b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0013.wav
new file mode 100644
index 0000000..92a2426
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0013.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0013.wavetable b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0013.wavetable
new file mode 100644
index 0000000..cdad583
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0013.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0014.wav b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0014.wav
new file mode 100644
index 0000000..93731c5
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0014.wav differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0014.wavetable b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0014.wavetable
new file mode 100644
index 0000000..736422a
Binary files /dev/null and b/etc/wavetables/AKWF/AKWF_violin/AKWF_violin_0014.wavetable differ
diff --git a/etc/wavetables/AKWF/AKWF_violin/AdventureKidWaveforms.txt b/etc/wavetables/AKWF/AKWF_violin/AdventureKidWaveforms.txt
new file mode 100755
index 0000000..14a4ad2
--- /dev/null
+++ b/etc/wavetables/AKWF/AKWF_violin/AdventureKidWaveforms.txt
@@ -0,0 +1,47 @@
+
+Adventure Kid
+
+http://www.adventurekid.se
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Waveforms (AKWF)
+
+AKWF is a collection of one cycle waveforms sampled
+from various sources intended for use as oscillator
+shapes in samplers and synthesizers.
+
+Length = 600 samples
+Pitch = D1+2
+
+You find them on-line at:
+http://www.adventurekid.se/AKRT
+
+---------------------------------------------------
+
+Adventure Kid Research & Technology (AKRT)
+
+While making music I have always try what happens
+if I miss use something and try to find things
+through experimenting - I love both old technology
+and new. Through the years I have sampled a lot of
+stuff, programmed my own synthesizers and effects 
+and tried a lot of techniques. Adventure Kid
+Research & Technology is my way of both collecting
+and sharing what I make and find.
+
+---------------------------------------------------
+
+Adventure Kid
+
+Adventure Kid is the stage name of Kristoffer
+Ekstrand (born July 22, 1982). Kristoffer who is
+based in Sweden uses obsolete personal computers,
+hand held gaming consoles and video game consoles in
+conjunction with modern synthesizers and sequencers
+to create music and art.
+
+---------------------------------------------------
+
+http://www.adventurekid.se/AKRT
\ No newline at end of file

-- 
sonic-pi packaging



More information about the pkg-multimedia-commits mailing list